diff --git a/.bundle/config b/.bundle/config index 7095f6e9..f9263841 100644 --- a/.bundle/config +++ b/.bundle/config @@ -1,6 +1,6 @@ --- BUNDLE_BIN: "bin" -BUNDLE_PATH: "vendor/gems" +BUNDLE_PATH: "/home/runner/work/hooks/hooks/vendor/bundle" BUNDLE_CACHE_PATH: "vendor/cache" BUNDLE_CACHE_ALL: "true" BUNDLE_SPECIFIC_PLATFORM: "true" diff --git a/spec/unit/lib/hooks/app/auth/auth_spec.rb b/spec/unit/lib/hooks/app/auth/auth_spec.rb new file mode 100644 index 00000000..5f0ff827 --- /dev/null +++ b/spec/unit/lib/hooks/app/auth/auth_spec.rb @@ -0,0 +1,201 @@ +# frozen_string_literal: true + +describe Hooks::App::Auth do + # Create a test class that includes the auth module + let(:test_class) do + Class.new do + include Hooks::App::Auth + + def error!(message, code) + raise StandardError, "#{message} (#{code})" + end + end + end + + let(:auth_instance) { test_class.new } + let(:payload) { "test payload" } + let(:headers) { { "Content-Type" => "application/json" } } + + describe "#validate_auth!" do + context "when auth config has secret_env_key" do + let(:endpoint_config) do + { + auth: { + type: "hmac", + secret_env_key: "TEST_SECRET" + } + } + end + + context "when secret exists in environment" do + before do + ENV["TEST_SECRET"] = "test-secret-value" + end + + after do + ENV.delete("TEST_SECRET") + end + + context "with HMAC auth type" do + it "validates with HMAC plugin when authentication succeeds" do + allow(Hooks::Plugins::Auth::HMAC).to receive(:valid?).and_return(true) + + expect { auth_instance.validate_auth!(payload, headers, endpoint_config) } + .not_to raise_error + + expect(Hooks::Plugins::Auth::HMAC).to have_received(:valid?).with( + payload: payload, + headers: headers, + secret: "test-secret-value", + config: endpoint_config + ) + end + + it "raises authentication failed error when HMAC validation fails" do + allow(Hooks::Plugins::Auth::HMAC).to receive(:valid?).and_return(false) + + expect { auth_instance.validate_auth!(payload, headers, endpoint_config) } + .to raise_error(StandardError, "authentication failed (401)") + end + end + + context "with shared_secret auth type" do + let(:endpoint_config) do + { + auth: { + type: "shared_secret", + secret_env_key: "TEST_SECRET" + } + } + end + + it "validates with SharedSecret plugin when authentication succeeds" do + allow(Hooks::Plugins::Auth::SharedSecret).to receive(:valid?).and_return(true) + + expect { auth_instance.validate_auth!(payload, headers, endpoint_config) } + .not_to raise_error + + expect(Hooks::Plugins::Auth::SharedSecret).to have_received(:valid?).with( + payload: payload, + headers: headers, + secret: "test-secret-value", + config: endpoint_config + ) + end + + it "raises authentication failed error when SharedSecret validation fails" do + allow(Hooks::Plugins::Auth::SharedSecret).to receive(:valid?).and_return(false) + + expect { auth_instance.validate_auth!(payload, headers, endpoint_config) } + .to raise_error(StandardError, "authentication failed (401)") + end + end + + context "with unsupported auth type" do + let(:endpoint_config) do + { + auth: { + type: "custom", + secret_env_key: "TEST_SECRET" + } + } + end + + it "raises custom validators not implemented error" do + expect { auth_instance.validate_auth!(payload, headers, endpoint_config) } + .to raise_error(StandardError, "Custom validators not implemented in POC (500)") + end + end + + context "with case variations in auth type" do + let(:endpoint_config) do + { + auth: { + type: "HMAC", + secret_env_key: "TEST_SECRET" + } + } + end + + it "handles uppercase auth type" do + allow(Hooks::Plugins::Auth::HMAC).to receive(:valid?).and_return(true) + + expect { auth_instance.validate_auth!(payload, headers, endpoint_config) } + .not_to raise_error + end + end + end + + context "when secret does not exist in environment" do + let(:endpoint_config) do + { + auth: { + type: "hmac", + secret_env_key: "NONEXISTENT_SECRET" + } + } + end + + it "raises secret not found error" do + ENV.delete("NONEXISTENT_SECRET") # Ensure it's not set + + expect { auth_instance.validate_auth!(payload, headers, endpoint_config) } + .to raise_error(StandardError, "secret 'NONEXISTENT_SECRET' not found in environment (500)") + end + end + end + + context "when auth config has no secret_env_key" do + let(:endpoint_config) do + { + auth: { + type: "hmac" + } + } + end + + it "returns without validation" do + expect { auth_instance.validate_auth!(payload, headers, endpoint_config) } + .not_to raise_error + + # No auth plugins should be called + expect(Hooks::Plugins::Auth::HMAC).not_to receive(:valid?) + expect(Hooks::Plugins::Auth::SharedSecret).not_to receive(:valid?) + end + end + + context "when auth config has nil secret_env_key" do + let(:endpoint_config) do + { + auth: { + type: "hmac", + secret_env_key: nil + } + } + end + + it "returns without validation" do + expect { auth_instance.validate_auth!(payload, headers, endpoint_config) } + .not_to raise_error + end + end + + context "when auth config has empty secret_env_key" do + let(:endpoint_config) do + { + auth: { + type: "hmac", + secret_env_key: "" + } + } + end + + it "raises secret not found error for empty string" do + ENV.delete("") # Ensure empty string key is not set + + expect { auth_instance.validate_auth!(payload, headers, endpoint_config) } + .to raise_error(StandardError, "secret '' not found in environment (500)") + end + end + end +end \ No newline at end of file diff --git a/spec/unit/lib/hooks/app/endpoints/health_spec.rb b/spec/unit/lib/hooks/app/endpoints/health_spec.rb new file mode 100644 index 00000000..697c7e64 --- /dev/null +++ b/spec/unit/lib/hooks/app/endpoints/health_spec.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +describe Hooks::App::HealthEndpoint do + # Test the endpoint behavior using a mock API instance + let(:api_instance) do + Class.new(Grape::API) do + mount Hooks::App::HealthEndpoint + end + end + + before do + # Mock the API start time + allow(Hooks::App::API).to receive(:start_time).and_return(Time.parse("2025-01-01T00:00:00Z")) + end + + describe "GET /" do + let(:response) { api_instance.new.call(Rack::MockRequest.env_for("/")) } + + it "returns 200 status" do + expect(response[0]).to eq(200) + end + + it "returns JSON content type" do + headers = response[1] + expect(headers["Content-Type"]).to include("application/json") + end + + it "returns health status information" do + body = JSON.parse(response[2].first) + + expect(body["status"]).to eq("healthy") + expect(body["timestamp"]).to eq(TIME_MOCK) + expect(body["version"]).to eq(Hooks::VERSION) + expect(body["uptime_seconds"]).to be_a(Integer) + expect(body["uptime_seconds"]).to eq(0) # Since mocked time is the same as start time + end + + it "calculates uptime correctly" do + # Set different start time to test uptime calculation + start_time = Time.parse("2024-12-31T23:59:30Z") + allow(Hooks::App::API).to receive(:start_time).and_return(start_time) + + body = JSON.parse(response[2].first) + expect(body["uptime_seconds"]).to eq(30) # 30 seconds difference + end + + it "includes all required fields" do + body = JSON.parse(response[2].first) + + expect(body).to have_key("status") + expect(body).to have_key("timestamp") + expect(body).to have_key("version") + expect(body).to have_key("uptime_seconds") + end + + it "returns valid JSON" do + expect { JSON.parse(response[2].first) }.not_to raise_error + end + end + + describe "inheritance" do + it "inherits from Grape::API" do + expect(described_class.superclass).to eq(Grape::API) + end + end +end \ No newline at end of file diff --git a/spec/unit/lib/hooks/app/endpoints/version_spec.rb b/spec/unit/lib/hooks/app/endpoints/version_spec.rb new file mode 100644 index 00000000..b696abc9 --- /dev/null +++ b/spec/unit/lib/hooks/app/endpoints/version_spec.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +describe Hooks::App::VersionEndpoint do + # Test the endpoint behavior using a mock API instance + let(:api_instance) do + Class.new(Grape::API) do + mount Hooks::App::VersionEndpoint + end + end + + describe "GET /" do + let(:response) { api_instance.new.call(Rack::MockRequest.env_for("/")) } + + it "returns 200 status" do + expect(response[0]).to eq(200) + end + + it "returns JSON content type" do + headers = response[1] + expect(headers["Content-Type"]).to include("application/json") + end + + it "returns version information" do + body = JSON.parse(response[2].first) + + expect(body["version"]).to eq(Hooks::VERSION) + expect(body["timestamp"]).to eq(TIME_MOCK) + end + + it "includes all required fields" do + body = JSON.parse(response[2].first) + + expect(body).to have_key("version") + expect(body).to have_key("timestamp") + end + + it "has exactly two fields" do + body = JSON.parse(response[2].first) + expect(body.keys.length).to eq(2) + end + + it "returns valid JSON" do + expect { JSON.parse(response[2].first) }.not_to raise_error + end + + it "returns current version from Hooks::VERSION" do + body = JSON.parse(response[2].first) + expect(body["version"]).to match(/^\d+\.\d+\.\d+$/) + end + + it "returns timestamp in ISO 8601 format" do + body = JSON.parse(response[2].first) + expect(body["timestamp"]).to match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/) + end + end + + describe "inheritance" do + it "inherits from Grape::API" do + expect(described_class.superclass).to eq(Grape::API) + end + end +end \ No newline at end of file diff --git a/spec/unit/lib/hooks/app/helpers_spec.rb b/spec/unit/lib/hooks/app/helpers_spec.rb new file mode 100644 index 00000000..7a6e3453 --- /dev/null +++ b/spec/unit/lib/hooks/app/helpers_spec.rb @@ -0,0 +1,277 @@ +# frozen_string_literal: true + +describe Hooks::App::Helpers do + # Create a test class that includes the helpers module + let(:test_class) do + Class.new do + include Hooks::App::Helpers + + # Mock methods that Grape provides + attr_accessor :headers, :env, :request + + def initialize + @headers = {} + @env = {} + @request = nil + end + + def respond_to?(method_name) + method_name == :request + end + + def error!(message, code) + raise StandardError, "#{message} (#{code})" + end + end + end + + let(:helper_instance) { test_class.new } + + describe "#uuid" do + it "generates a UUID string" do + uuid = helper_instance.uuid + expect(uuid).to be_a(String) + expect(uuid).to match(/\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/i) + end + + it "generates unique UUIDs" do + uuid1 = helper_instance.uuid + uuid2 = helper_instance.uuid + expect(uuid1).not_to eq(uuid2) + end + end + + describe "#enforce_request_limits" do + let(:config) { { request_limit: 1000 } } + + context "when content length is within limits" do + it "does not raise error for header content length" do + helper_instance.headers["Content-Length"] = "500" + expect { helper_instance.enforce_request_limits(config) }.not_to raise_error + end + + it "does not raise error for env content length" do + helper_instance.env["CONTENT_LENGTH"] = "500" + expect { helper_instance.enforce_request_limits(config) }.not_to raise_error + end + + it "does not raise error when no content length is provided" do + expect { helper_instance.enforce_request_limits(config) }.not_to raise_error + end + end + + context "when content length exceeds limits" do + it "raises error for header content length" do + helper_instance.headers["Content-Length"] = "2000" + expect { helper_instance.enforce_request_limits(config) } + .to raise_error(StandardError, "request body too large (413)") + end + + it "raises error for env content length" do + helper_instance.env["CONTENT_LENGTH"] = "2000" + expect { helper_instance.enforce_request_limits(config) } + .to raise_error(StandardError, "request body too large (413)") + end + + it "handles different header name variations" do + helper_instance.headers["CONTENT_LENGTH"] = "2000" + expect { helper_instance.enforce_request_limits(config) } + .to raise_error(StandardError, "request body too large (413)") + + helper_instance.headers.clear + helper_instance.headers["content-length"] = "2000" + expect { helper_instance.enforce_request_limits(config) } + .to raise_error(StandardError, "request body too large (413)") + + helper_instance.headers.clear + helper_instance.headers["HTTP_CONTENT_LENGTH"] = "2000" + expect { helper_instance.enforce_request_limits(config) } + .to raise_error(StandardError, "request body too large (413)") + end + end + end + + describe "#parse_payload" do + context "with JSON content type" do + let(:headers) { { "Content-Type" => "application/json" } } + + it "parses valid JSON with symbolized keys by default" do + raw_body = '{"key": "value", "nested": {"inner": "data"}}' + result = helper_instance.parse_payload(raw_body, headers) + expect(result).to eq({ key: "value", nested: { "inner" => "data" } }) + end + + it "parses valid JSON without symbolizing keys when requested" do + raw_body = '{"key": "value", "nested": {"inner": "data"}}' + result = helper_instance.parse_payload(raw_body, headers, symbolize: false) + expect(result).to eq({ "key" => "value", "nested" => { "inner" => "data" } }) + end + + it "returns raw body when JSON parsing fails" do + raw_body = "invalid json" + result = helper_instance.parse_payload(raw_body, headers) + expect(result).to eq("invalid json") + end + + it "handles JSON arrays" do + raw_body = '[{"key": "value"}]' + result = helper_instance.parse_payload(raw_body, headers) + expect(result).to eq([{ "key" => "value" }]) + end + end + + context "with different content type header variations" do + it "handles CONTENT_TYPE header" do + headers = { "CONTENT_TYPE" => "application/json" } + raw_body = '{"key": "value"}' + result = helper_instance.parse_payload(raw_body, headers) + expect(result).to eq({ key: "value" }) + end + + it "handles content-type header" do + headers = { "content-type" => "application/json" } + raw_body = '{"key": "value"}' + result = helper_instance.parse_payload(raw_body, headers) + expect(result).to eq({ key: "value" }) + end + + it "handles HTTP_CONTENT_TYPE header" do + headers = { "HTTP_CONTENT_TYPE" => "application/json" } + raw_body = '{"key": "value"}' + result = helper_instance.parse_payload(raw_body, headers) + expect(result).to eq({ key: "value" }) + end + end + + context "without JSON content type" do + let(:headers) { { "Content-Type" => "text/plain" } } + + it "returns raw body for non-JSON content type" do + raw_body = "plain text data" + result = helper_instance.parse_payload(raw_body, headers) + expect(result).to eq("plain text data") + end + + it "attempts to parse JSON-like strings even without JSON content type" do + raw_body = '{"key": "value"}' + result = helper_instance.parse_payload(raw_body, headers) + expect(result).to eq({ key: "value" }) + end + + it "attempts to parse array-like strings" do + raw_body = '[{"key": "value"}]' + result = helper_instance.parse_payload(raw_body, headers) + expect(result).to eq([{ "key" => "value" }]) + end + + it "returns raw body for non-JSON-like strings" do + raw_body = "not json at all" + result = helper_instance.parse_payload(raw_body, headers) + expect(result).to eq("not json at all") + end + end + + context "with empty headers" do + it "handles empty headers" do + raw_body = '{"key": "value"}' + result = helper_instance.parse_payload(raw_body, {}) + expect(result).to eq({ key: "value" }) + end + end + end + + describe "#load_handler" do + let(:temp_dir) { "/tmp/test_handlers" } + + before do + FileUtils.mkdir_p(temp_dir) + end + + after do + FileUtils.rm_rf(temp_dir) + end + + context "when handler file exists" do + it "loads simple handler class" do + File.write("#{temp_dir}/test_handler.rb", <<~RUBY) + class TestHandler + def initialize + end + end + RUBY + + expect(helper_instance.load_handler("TestHandler", temp_dir)).to be_a(Object) + expect(Object.const_defined?("TestHandler")).to be true + Object.send(:remove_const, "TestHandler") if Object.const_defined?("TestHandler") + end + + it "converts camelCase to snake_case filename" do + File.write("#{temp_dir}/github_handler.rb", <<~RUBY) + class GithubHandler + def initialize + end + end + RUBY + + expect(helper_instance.load_handler("GithubHandler", temp_dir)).to be_a(Object) + Object.send(:remove_const, "GithubHandler") if Object.const_defined?("GithubHandler") + end + + it "converts PascalCase with acronyms to snake_case filename" do + File.write("#{temp_dir}/git_hub_handler.rb", <<~RUBY) + class GitHubHandler + def initialize + end + end + RUBY + + expect(helper_instance.load_handler("GitHubHandler", temp_dir)).to be_a(Object) + Object.send(:remove_const, "GitHubHandler") if Object.const_defined?("GitHubHandler") + end + end + + context "when handler file does not exist" do + it "raises LoadError with proper message" do + expect { helper_instance.load_handler("NonExistentHandler", temp_dir) } + .to raise_error(LoadError, /Handler NonExistentHandler not found/) + end + end + + context "when handler class cannot be instantiated" do + it "raises error when class has invalid syntax" do + File.write("#{temp_dir}/broken_handler.rb", "class BrokenHandler\n def initialize\n raise 'initialization error'\n end\nend") + + expect { helper_instance.load_handler("BrokenHandler", temp_dir) } + .to raise_error(StandardError, /failed to load handler BrokenHandler/) + Object.send(:remove_const, "BrokenHandler") if Object.const_defined?("BrokenHandler") + end + end + end + + describe "#determine_error_code" do + it "returns 400 for ArgumentError" do + error = ArgumentError.new("test") + expect(helper_instance.determine_error_code(error)).to eq(400) + end + + it "returns 501 for NotImplementedError" do + error = NotImplementedError.new("test") + expect(helper_instance.determine_error_code(error)).to eq(501) + end + + it "returns 500 for StandardError" do + error = StandardError.new("test") + expect(helper_instance.determine_error_code(error)).to eq(500) + end + + it "returns 500 for RuntimeError" do + error = RuntimeError.new("test") + expect(helper_instance.determine_error_code(error)).to eq(500) + end + + it "returns 500 for other exception types" do + error = NoMethodError.new("test") + expect(helper_instance.determine_error_code(error)).to eq(500) + end + end +end \ No newline at end of file diff --git a/spec/unit/lib/hooks/core/log_spec.rb b/spec/unit/lib/hooks/core/log_spec.rb new file mode 100644 index 00000000..2e1e2f44 --- /dev/null +++ b/spec/unit/lib/hooks/core/log_spec.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +describe Hooks::Log do + after do + # Clean up any mock loggers to avoid interference with other tests + described_class.instance = nil + end + + describe ".instance" do + it "has an accessor for the logger instance" do + expect(described_class).to respond_to(:instance) + expect(described_class).to respond_to(:instance=) + end + + it "can set and get the logger instance" do + mock_logger = instance_double(Logger) + described_class.instance = mock_logger + expect(described_class.instance).to eq(mock_logger) + end + + it "starts with nil instance" do + described_class.instance = nil + expect(described_class.instance).to be_nil + end + + it "can handle different logger types" do + # Test with different logger implementations + standard_logger = Logger.new(StringIO.new) + described_class.instance = standard_logger + expect(described_class.instance).to eq(standard_logger) + + # Test with mock logger + mock_logger = double("MockLogger") + described_class.instance = mock_logger + expect(described_class.instance).to eq(mock_logger) + end + end + + describe "module structure" do + it "is a module within Hooks namespace" do + expect(described_class).to be_a(Module) + expect(described_class.name).to eq("Hooks::Log") + end + + it "has a singleton class with instance accessor" do + singleton = described_class.singleton_class + expect(singleton.method_defined?(:instance)).to be true + expect(singleton.method_defined?(:instance=)).to be true + end + end +end \ No newline at end of file diff --git a/spec/unit/lib/hooks/handlers/default_spec.rb b/spec/unit/lib/hooks/handlers/default_spec.rb new file mode 100644 index 00000000..711b8d27 --- /dev/null +++ b/spec/unit/lib/hooks/handlers/default_spec.rb @@ -0,0 +1,96 @@ +# frozen_string_literal: true + +describe DefaultHandler do + let(:handler) { described_class.new } + let(:payload) { { message: "test payload", data: { key: "value" } } } + let(:headers) { { "Content-Type" => "application/json", "User-Agent" => "TestAgent" } } + let(:config) { { endpoint: "test", auth: { type: "hmac" } } } + + before do + # Provide a null logger to avoid nil errors while allowing logging to work + Hooks::Log.instance = Logger.new(StringIO.new) + end + + describe "#call" do + context "with valid payload and headers" do + it "returns successful response hash" do + response = handler.call(payload: payload, headers: headers, config: config) + + expect(response).to be_a(Hash) + expect(response[:message]).to eq("webhook processed successfully") + expect(response[:handler]).to eq("DefaultHandler") + expect(response[:timestamp]).to be_a(String) + expect(response[:timestamp]).to match(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z/) + end + + it "uses the mocked time from spec helper" do + response = handler.call(payload: payload, headers: headers, config: config) + expect(response[:timestamp]).to eq(TIME_MOCK) + end + end + + context "with nil payload" do + it "returns successful response without errors" do + response = handler.call(payload: nil, headers: headers, config: config) + + expect(response).to be_a(Hash) + expect(response[:message]).to eq("webhook processed successfully") + expect(response[:handler]).to eq("DefaultHandler") + expect(response[:timestamp]).to eq(TIME_MOCK) + end + end + + context "with empty payload" do + it "handles empty payload gracefully" do + response = handler.call(payload: {}, headers: headers, config: config) + + expect(response).to be_a(Hash) + expect(response[:message]).to eq("webhook processed successfully") + expect(response[:handler]).to eq("DefaultHandler") + expect(response[:timestamp]).to eq(TIME_MOCK) + end + end + + context "with string payload" do + let(:string_payload) { "plain text payload" } + + it "handles string payload successfully" do + response = handler.call(payload: string_payload, headers: headers, config: config) + + expect(response[:message]).to eq("webhook processed successfully") + expect(response[:handler]).to eq("DefaultHandler") + expect(response[:timestamp]).to eq(TIME_MOCK) + end + end + + context "with different config values" do + let(:custom_config) { { endpoint: "custom", custom_field: "test" } } + + it "accepts any config without affecting response" do + response = handler.call(payload: payload, headers: headers, config: custom_config) + + expect(response[:message]).to eq("webhook processed successfully") + expect(response[:handler]).to eq("DefaultHandler") + expect(response[:timestamp]).to eq(TIME_MOCK) + end + end + + context "with different headers" do + let(:custom_headers) { { "X-GitHub-Event" => "push", "X-GitHub-Delivery" => "12345" } } + + it "accepts any headers without affecting response" do + response = handler.call(payload: payload, headers: custom_headers, config: config) + + expect(response[:message]).to eq("webhook processed successfully") + expect(response[:handler]).to eq("DefaultHandler") + expect(response[:timestamp]).to eq(TIME_MOCK) + end + end + end + + describe "inheritance" do + it "inherits from Hooks::Handlers::Base" do + expect(described_class.superclass).to eq(Hooks::Handlers::Base) + end + end +end \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/bin/erb b/vendor/bundle/ruby/3.4.0/bin/erb new file mode 100755 index 00000000..1bf6e6a9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/bin/erb @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'erb' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('erb', 'erb', version) +else +gem "erb", version +load Gem.bin_path("erb", "erb", version) +end diff --git a/vendor/bundle/ruby/3.4.0/bin/hooks b/vendor/bundle/ruby/3.4.0/bin/hooks new file mode 100755 index 00000000..6b57b5bd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/bin/hooks @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'hooks-ruby' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('hooks-ruby', 'hooks', version) +else +gem "hooks-ruby", version +load Gem.bin_path("hooks-ruby", "hooks", version) +end diff --git a/vendor/bundle/ruby/3.4.0/bin/htmldiff b/vendor/bundle/ruby/3.4.0/bin/htmldiff new file mode 100755 index 00000000..a91f4b64 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/bin/htmldiff @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'diff-lcs' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('diff-lcs', 'htmldiff', version) +else +gem "diff-lcs", version +load Gem.bin_path("diff-lcs", "htmldiff", version) +end diff --git a/vendor/bundle/ruby/3.4.0/bin/irb b/vendor/bundle/ruby/3.4.0/bin/irb new file mode 100755 index 00000000..0bb3f809 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/bin/irb @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'irb' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('irb', 'irb', version) +else +gem "irb", version +load Gem.bin_path("irb", "irb", version) +end diff --git a/vendor/bundle/ruby/3.4.0/bin/ldiff b/vendor/bundle/ruby/3.4.0/bin/ldiff new file mode 100755 index 00000000..b3179208 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/bin/ldiff @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'diff-lcs' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('diff-lcs', 'ldiff', version) +else +gem "diff-lcs", version +load Gem.bin_path("diff-lcs", "ldiff", version) +end diff --git a/vendor/bundle/ruby/3.4.0/bin/puma b/vendor/bundle/ruby/3.4.0/bin/puma new file mode 100755 index 00000000..22557f76 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/bin/puma @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'puma' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('puma', 'puma', version) +else +gem "puma", version +load Gem.bin_path("puma", "puma", version) +end diff --git a/vendor/bundle/ruby/3.4.0/bin/pumactl b/vendor/bundle/ruby/3.4.0/bin/pumactl new file mode 100755 index 00000000..afe38228 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/bin/pumactl @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'puma' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('puma', 'pumactl', version) +else +gem "puma", version +load Gem.bin_path("puma", "pumactl", version) +end diff --git a/vendor/bundle/ruby/3.4.0/bin/racc b/vendor/bundle/ruby/3.4.0/bin/racc new file mode 100755 index 00000000..9041ab6c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/bin/racc @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'racc' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('racc', 'racc', version) +else +gem "racc", version +load Gem.bin_path("racc", "racc", version) +end diff --git a/vendor/bundle/ruby/3.4.0/bin/rdoc b/vendor/bundle/ruby/3.4.0/bin/rdoc new file mode 100755 index 00000000..b8c66ad6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/bin/rdoc @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'rdoc' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('rdoc', 'rdoc', version) +else +gem "rdoc", version +load Gem.bin_path("rdoc", "rdoc", version) +end diff --git a/vendor/bundle/ruby/3.4.0/bin/ri b/vendor/bundle/ruby/3.4.0/bin/ri new file mode 100755 index 00000000..c771c66a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/bin/ri @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'rdoc' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('rdoc', 'ri', version) +else +gem "rdoc", version +load Gem.bin_path("rdoc", "ri", version) +end diff --git a/vendor/bundle/ruby/3.4.0/bin/rspec b/vendor/bundle/ruby/3.4.0/bin/rspec new file mode 100755 index 00000000..d2cafd0e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/bin/rspec @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'rspec-core' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('rspec-core', 'rspec', version) +else +gem "rspec-core", version +load Gem.bin_path("rspec-core", "rspec", version) +end diff --git a/vendor/bundle/ruby/3.4.0/bin/rubocop b/vendor/bundle/ruby/3.4.0/bin/rubocop new file mode 100755 index 00000000..9115ca0b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/bin/rubocop @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'rubocop' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('rubocop', 'rubocop', version) +else +gem "rubocop", version +load Gem.bin_path("rubocop", "rubocop", version) +end diff --git a/vendor/bundle/ruby/3.4.0/bin/ruby-parse b/vendor/bundle/ruby/3.4.0/bin/ruby-parse new file mode 100755 index 00000000..4cbe6e80 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/bin/ruby-parse @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'parser' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('parser', 'ruby-parse', version) +else +gem "parser", version +load Gem.bin_path("parser", "ruby-parse", version) +end diff --git a/vendor/bundle/ruby/3.4.0/bin/ruby-rewrite b/vendor/bundle/ruby/3.4.0/bin/ruby-rewrite new file mode 100755 index 00000000..00c71af8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/bin/ruby-rewrite @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'parser' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +Gem.use_gemdeps + +version = ">= 0.a" + +str = ARGV.first +if str + str = str.b[/\A_(.*)_\z/, 1] + if str and Gem::Version.correct?(str) + version = str + ARGV.shift + end +end + +if Gem.respond_to?(:activate_bin_path) +load Gem.activate_bin_path('parser', 'ruby-rewrite', version) +else +gem "parser", version +load Gem.bin_path("parser", "ruby-rewrite", version) +end diff --git a/vendor/bundle/ruby/3.4.0/cache/activesupport-8.0.2.gem b/vendor/bundle/ruby/3.4.0/cache/activesupport-8.0.2.gem new file mode 100644 index 00000000..24b49354 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/activesupport-8.0.2.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/addressable-2.8.7.gem b/vendor/bundle/ruby/3.4.0/cache/addressable-2.8.7.gem new file mode 100644 index 00000000..c4890680 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/addressable-2.8.7.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/ast-2.4.3.gem b/vendor/bundle/ruby/3.4.0/cache/ast-2.4.3.gem new file mode 100644 index 00000000..1f5e5c25 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/ast-2.4.3.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/base64-0.3.0.gem b/vendor/bundle/ruby/3.4.0/cache/base64-0.3.0.gem new file mode 100644 index 00000000..12f53f14 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/base64-0.3.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/benchmark-0.4.1.gem b/vendor/bundle/ruby/3.4.0/cache/benchmark-0.4.1.gem new file mode 100644 index 00000000..90cd2725 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/benchmark-0.4.1.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/bigdecimal-3.2.2.gem b/vendor/bundle/ruby/3.4.0/cache/bigdecimal-3.2.2.gem new file mode 100644 index 00000000..ed8d2e43 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/bigdecimal-3.2.2.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/concurrent-ruby-1.3.5.gem b/vendor/bundle/ruby/3.4.0/cache/concurrent-ruby-1.3.5.gem new file mode 100644 index 00000000..1cd9f527 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/concurrent-ruby-1.3.5.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/connection_pool-2.5.3.gem b/vendor/bundle/ruby/3.4.0/cache/connection_pool-2.5.3.gem new file mode 100644 index 00000000..23c398fc Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/connection_pool-2.5.3.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/crack-1.0.0.gem b/vendor/bundle/ruby/3.4.0/cache/crack-1.0.0.gem new file mode 100644 index 00000000..e3cbaf45 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/crack-1.0.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/date-3.4.1.gem b/vendor/bundle/ruby/3.4.0/cache/date-3.4.1.gem new file mode 100644 index 00000000..fe7bd0ad Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/date-3.4.1.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/diff-lcs-1.6.2.gem b/vendor/bundle/ruby/3.4.0/cache/diff-lcs-1.6.2.gem new file mode 100644 index 00000000..21c4c77c Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/diff-lcs-1.6.2.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/docile-1.4.1.gem b/vendor/bundle/ruby/3.4.0/cache/docile-1.4.1.gem new file mode 100644 index 00000000..b292f4e5 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/docile-1.4.1.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/drb-2.2.3.gem b/vendor/bundle/ruby/3.4.0/cache/drb-2.2.3.gem new file mode 100644 index 00000000..0c78b283 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/drb-2.2.3.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/dry-configurable-1.3.0.gem b/vendor/bundle/ruby/3.4.0/cache/dry-configurable-1.3.0.gem new file mode 100644 index 00000000..11af638b Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/dry-configurable-1.3.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/dry-core-1.1.0.gem b/vendor/bundle/ruby/3.4.0/cache/dry-core-1.1.0.gem new file mode 100644 index 00000000..33e0c5ba Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/dry-core-1.1.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/dry-inflector-1.2.0.gem b/vendor/bundle/ruby/3.4.0/cache/dry-inflector-1.2.0.gem new file mode 100644 index 00000000..627f7f25 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/dry-inflector-1.2.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/dry-initializer-3.2.0.gem b/vendor/bundle/ruby/3.4.0/cache/dry-initializer-3.2.0.gem new file mode 100644 index 00000000..31d3c6f0 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/dry-initializer-3.2.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/dry-logic-1.6.0.gem b/vendor/bundle/ruby/3.4.0/cache/dry-logic-1.6.0.gem new file mode 100644 index 00000000..83dec7cc Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/dry-logic-1.6.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/dry-schema-1.14.1.gem b/vendor/bundle/ruby/3.4.0/cache/dry-schema-1.14.1.gem new file mode 100644 index 00000000..fe0c923b Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/dry-schema-1.14.1.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/dry-types-1.8.3.gem b/vendor/bundle/ruby/3.4.0/cache/dry-types-1.8.3.gem new file mode 100644 index 00000000..77973654 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/dry-types-1.8.3.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/erb-5.0.1.gem b/vendor/bundle/ruby/3.4.0/cache/erb-5.0.1.gem new file mode 100644 index 00000000..d0902424 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/erb-5.0.1.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/grape-2.3.0.gem b/vendor/bundle/ruby/3.4.0/cache/grape-2.3.0.gem new file mode 100644 index 00000000..c75b33b4 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/grape-2.3.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/grape-swagger-2.1.2.gem b/vendor/bundle/ruby/3.4.0/cache/grape-swagger-2.1.2.gem new file mode 100644 index 00000000..0d39c0fa Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/grape-swagger-2.1.2.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/hashdiff-1.2.0.gem b/vendor/bundle/ruby/3.4.0/cache/hashdiff-1.2.0.gem new file mode 100644 index 00000000..1359998a Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/hashdiff-1.2.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/i18n-1.14.7.gem b/vendor/bundle/ruby/3.4.0/cache/i18n-1.14.7.gem new file mode 100644 index 00000000..9307337f Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/i18n-1.14.7.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/io-console-0.8.0.gem b/vendor/bundle/ruby/3.4.0/cache/io-console-0.8.0.gem new file mode 100644 index 00000000..7a39c003 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/io-console-0.8.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/irb-1.15.2.gem b/vendor/bundle/ruby/3.4.0/cache/irb-1.15.2.gem new file mode 100644 index 00000000..1d053448 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/irb-1.15.2.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/json-2.12.2.gem b/vendor/bundle/ruby/3.4.0/cache/json-2.12.2.gem new file mode 100644 index 00000000..71389d8d Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/json-2.12.2.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/language_server-protocol-3.17.0.5.gem b/vendor/bundle/ruby/3.4.0/cache/language_server-protocol-3.17.0.5.gem new file mode 100644 index 00000000..40a28d80 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/language_server-protocol-3.17.0.5.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/lint_roller-1.1.0.gem b/vendor/bundle/ruby/3.4.0/cache/lint_roller-1.1.0.gem new file mode 100644 index 00000000..0f874b6d Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/lint_roller-1.1.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/logger-1.7.0.gem b/vendor/bundle/ruby/3.4.0/cache/logger-1.7.0.gem new file mode 100644 index 00000000..061f1ccc Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/logger-1.7.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/minitest-5.25.5.gem b/vendor/bundle/ruby/3.4.0/cache/minitest-5.25.5.gem new file mode 100644 index 00000000..2ffec491 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/minitest-5.25.5.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/mustermann-3.0.3.gem b/vendor/bundle/ruby/3.4.0/cache/mustermann-3.0.3.gem new file mode 100644 index 00000000..ec4d1260 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/mustermann-3.0.3.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/mustermann-grape-1.1.0.gem b/vendor/bundle/ruby/3.4.0/cache/mustermann-grape-1.1.0.gem new file mode 100644 index 00000000..480f83bb Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/mustermann-grape-1.1.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/nio4r-2.7.4.gem b/vendor/bundle/ruby/3.4.0/cache/nio4r-2.7.4.gem new file mode 100644 index 00000000..22b7976a Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/nio4r-2.7.4.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/parallel-1.27.0.gem b/vendor/bundle/ruby/3.4.0/cache/parallel-1.27.0.gem new file mode 100644 index 00000000..1b86f818 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/parallel-1.27.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/parser-3.3.8.0.gem b/vendor/bundle/ruby/3.4.0/cache/parser-3.3.8.0.gem new file mode 100644 index 00000000..4571f816 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/parser-3.3.8.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/pp-0.6.2.gem b/vendor/bundle/ruby/3.4.0/cache/pp-0.6.2.gem new file mode 100644 index 00000000..25704968 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/pp-0.6.2.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/prettyprint-0.2.0.gem b/vendor/bundle/ruby/3.4.0/cache/prettyprint-0.2.0.gem new file mode 100644 index 00000000..0944aaba Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/prettyprint-0.2.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/prism-1.4.0.gem b/vendor/bundle/ruby/3.4.0/cache/prism-1.4.0.gem new file mode 100644 index 00000000..005bf8ed Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/prism-1.4.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/psych-5.2.6.gem b/vendor/bundle/ruby/3.4.0/cache/psych-5.2.6.gem new file mode 100644 index 00000000..becbf807 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/psych-5.2.6.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/public_suffix-6.0.2.gem b/vendor/bundle/ruby/3.4.0/cache/public_suffix-6.0.2.gem new file mode 100644 index 00000000..0baf25c6 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/public_suffix-6.0.2.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/puma-6.6.0.gem b/vendor/bundle/ruby/3.4.0/cache/puma-6.6.0.gem new file mode 100644 index 00000000..f28b21e3 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/puma-6.6.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/racc-1.8.1.gem b/vendor/bundle/ruby/3.4.0/cache/racc-1.8.1.gem new file mode 100644 index 00000000..ad9e6bbd Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/racc-1.8.1.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/rack-3.1.16.gem b/vendor/bundle/ruby/3.4.0/cache/rack-3.1.16.gem new file mode 100644 index 00000000..0a48c300 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/rack-3.1.16.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/rack-test-2.2.0.gem b/vendor/bundle/ruby/3.4.0/cache/rack-test-2.2.0.gem new file mode 100644 index 00000000..b0b9c9d8 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/rack-test-2.2.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/rainbow-3.1.1.gem b/vendor/bundle/ruby/3.4.0/cache/rainbow-3.1.1.gem new file mode 100644 index 00000000..863181a2 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/rainbow-3.1.1.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/rdoc-6.14.0.gem b/vendor/bundle/ruby/3.4.0/cache/rdoc-6.14.0.gem new file mode 100644 index 00000000..2dde547a Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/rdoc-6.14.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/redacting-logger-1.5.0.gem b/vendor/bundle/ruby/3.4.0/cache/redacting-logger-1.5.0.gem new file mode 100644 index 00000000..dbd36217 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/redacting-logger-1.5.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/regexp_parser-2.10.0.gem b/vendor/bundle/ruby/3.4.0/cache/regexp_parser-2.10.0.gem new file mode 100644 index 00000000..63358cc5 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/regexp_parser-2.10.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/reline-0.6.1.gem b/vendor/bundle/ruby/3.4.0/cache/reline-0.6.1.gem new file mode 100644 index 00000000..98ae6be5 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/reline-0.6.1.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/retryable-3.0.5.gem b/vendor/bundle/ruby/3.4.0/cache/retryable-3.0.5.gem new file mode 100644 index 00000000..94561620 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/retryable-3.0.5.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/rexml-3.4.1.gem b/vendor/bundle/ruby/3.4.0/cache/rexml-3.4.1.gem new file mode 100644 index 00000000..b0c5c846 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/rexml-3.4.1.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/rspec-3.13.1.gem b/vendor/bundle/ruby/3.4.0/cache/rspec-3.13.1.gem new file mode 100644 index 00000000..74792105 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/rspec-3.13.1.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/rspec-core-3.13.4.gem b/vendor/bundle/ruby/3.4.0/cache/rspec-core-3.13.4.gem new file mode 100644 index 00000000..2a2780f9 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/rspec-core-3.13.4.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/rspec-expectations-3.13.5.gem b/vendor/bundle/ruby/3.4.0/cache/rspec-expectations-3.13.5.gem new file mode 100644 index 00000000..51409fdd Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/rspec-expectations-3.13.5.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/rspec-mocks-3.13.5.gem b/vendor/bundle/ruby/3.4.0/cache/rspec-mocks-3.13.5.gem new file mode 100644 index 00000000..05da2b39 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/rspec-mocks-3.13.5.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/rspec-support-3.13.4.gem b/vendor/bundle/ruby/3.4.0/cache/rspec-support-3.13.4.gem new file mode 100644 index 00000000..0d49eada Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/rspec-support-3.13.4.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/rubocop-1.76.1.gem b/vendor/bundle/ruby/3.4.0/cache/rubocop-1.76.1.gem new file mode 100644 index 00000000..024cb307 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/rubocop-1.76.1.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/rubocop-ast-1.45.1.gem b/vendor/bundle/ruby/3.4.0/cache/rubocop-ast-1.45.1.gem new file mode 100644 index 00000000..9e1a70a9 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/rubocop-ast-1.45.1.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/rubocop-github-0.26.0.gem b/vendor/bundle/ruby/3.4.0/cache/rubocop-github-0.26.0.gem new file mode 100644 index 00000000..dfd9b234 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/rubocop-github-0.26.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/rubocop-performance-1.25.0.gem b/vendor/bundle/ruby/3.4.0/cache/rubocop-performance-1.25.0.gem new file mode 100644 index 00000000..847b3f73 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/rubocop-performance-1.25.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/rubocop-rails-2.32.0.gem b/vendor/bundle/ruby/3.4.0/cache/rubocop-rails-2.32.0.gem new file mode 100644 index 00000000..257d7b7c Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/rubocop-rails-2.32.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/rubocop-rspec-3.6.0.gem b/vendor/bundle/ruby/3.4.0/cache/rubocop-rspec-3.6.0.gem new file mode 100644 index 00000000..18b48e0e Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/rubocop-rspec-3.6.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/ruby-progressbar-1.13.0.gem b/vendor/bundle/ruby/3.4.0/cache/ruby-progressbar-1.13.0.gem new file mode 100644 index 00000000..c50b94b2 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/ruby-progressbar-1.13.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/ruby2_keywords-0.0.5.gem b/vendor/bundle/ruby/3.4.0/cache/ruby2_keywords-0.0.5.gem new file mode 100644 index 00000000..d311c5d0 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/ruby2_keywords-0.0.5.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/securerandom-0.4.1.gem b/vendor/bundle/ruby/3.4.0/cache/securerandom-0.4.1.gem new file mode 100644 index 00000000..05072cab Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/securerandom-0.4.1.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/simplecov-0.22.0.gem b/vendor/bundle/ruby/3.4.0/cache/simplecov-0.22.0.gem new file mode 100644 index 00000000..ce8f9794 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/simplecov-0.22.0.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/simplecov-erb-1.0.1.gem b/vendor/bundle/ruby/3.4.0/cache/simplecov-erb-1.0.1.gem new file mode 100644 index 00000000..4557e73f Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/simplecov-erb-1.0.1.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/simplecov-html-0.13.1.gem b/vendor/bundle/ruby/3.4.0/cache/simplecov-html-0.13.1.gem new file mode 100644 index 00000000..17948593 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/simplecov-html-0.13.1.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/simplecov_json_formatter-0.1.4.gem b/vendor/bundle/ruby/3.4.0/cache/simplecov_json_formatter-0.1.4.gem new file mode 100644 index 00000000..75f6f6e0 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/simplecov_json_formatter-0.1.4.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/stringio-3.1.7.gem b/vendor/bundle/ruby/3.4.0/cache/stringio-3.1.7.gem new file mode 100644 index 00000000..bca0b39f Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/stringio-3.1.7.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/tzinfo-2.0.6.gem b/vendor/bundle/ruby/3.4.0/cache/tzinfo-2.0.6.gem new file mode 100644 index 00000000..2c16da8a Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/tzinfo-2.0.6.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/unicode-display_width-3.1.4.gem b/vendor/bundle/ruby/3.4.0/cache/unicode-display_width-3.1.4.gem new file mode 100644 index 00000000..7c2a1186 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/unicode-display_width-3.1.4.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/unicode-emoji-4.0.4.gem b/vendor/bundle/ruby/3.4.0/cache/unicode-emoji-4.0.4.gem new file mode 100644 index 00000000..bae638f0 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/unicode-emoji-4.0.4.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/uri-1.0.3.gem b/vendor/bundle/ruby/3.4.0/cache/uri-1.0.3.gem new file mode 100644 index 00000000..afd77ba9 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/uri-1.0.3.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/vcr-6.3.1.gem b/vendor/bundle/ruby/3.4.0/cache/vcr-6.3.1.gem new file mode 100644 index 00000000..7ca4c043 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/vcr-6.3.1.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/webmock-3.25.1.gem b/vendor/bundle/ruby/3.4.0/cache/webmock-3.25.1.gem new file mode 100644 index 00000000..9fcca204 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/webmock-3.25.1.gem differ diff --git a/vendor/bundle/ruby/3.4.0/cache/zeitwerk-2.7.3.gem b/vendor/bundle/ruby/3.4.0/cache/zeitwerk-2.7.3.gem new file mode 100644 index 00000000..31cb70ca Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/cache/zeitwerk-2.7.3.gem differ diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/bigdecimal-3.2.2/bigdecimal.so b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/bigdecimal-3.2.2/bigdecimal.so new file mode 100755 index 00000000..02216d0f Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/bigdecimal-3.2.2/bigdecimal.so differ diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/bigdecimal-3.2.2/gem.build_complete b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/bigdecimal-3.2.2/gem.build_complete new file mode 100644 index 00000000..e69de29b diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/bigdecimal-3.2.2/gem_make.out b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/bigdecimal-3.2.2/gem_make.out new file mode 100644 index 00000000..4724b85e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/bigdecimal-3.2.2/gem_make.out @@ -0,0 +1,44 @@ +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal +/opt/hostedtoolcache/Ruby/3.4.4/x64/bin/ruby extconf.rb +checking for __builtin_clz()... yes +checking for __builtin_clzl()... yes +checking for __builtin_clzll()... yes +checking for float.h... yes +checking for math.h... yes +checking for stdbool.h... yes +checking for stdlib.h... yes +checking for x86intrin.h... yes +checking for _lzcnt_u32() in x86intrin.h... no +checking for _lzcnt_u64() in x86intrin.h... no +checking for intrin.h... no +checking for labs() in stdlib.h... yes +checking for llabs() in stdlib.h... yes +checking for finite() in math.h... yes +checking for isfinite() in math.h... no +checking for ruby/atomic.h... yes +checking for ruby/internal/has/builtin.h... yes +checking for ruby/internal/static_assert.h... yes +checking for rb_rational_num() in ruby.h... yes +checking for rb_rational_den() in ruby.h... yes +checking for rb_complex_real() in ruby.h... yes +checking for rb_complex_imag() in ruby.h... yes +checking for rb_opts_exception_p() in ruby.h... yes +checking for rb_category_warn() in ruby.h... yes +checking for RB_WARN_CATEGORY_DEPRECATED in ruby.h... yes +creating Makefile + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-f3g8yl sitelibdir\=./.gem.20250609-2009-f3g8yl clean + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-f3g8yl sitelibdir\=./.gem.20250609-2009-f3g8yl +compiling bigdecimal.c +compiling missing.c +linking shared-object bigdecimal.so + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-f3g8yl sitelibdir\=./.gem.20250609-2009-f3g8yl install +/usr/bin/install -c -m 0755 bigdecimal.so ./.gem.20250609-2009-f3g8yl + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-f3g8yl sitelibdir\=./.gem.20250609-2009-f3g8yl clean diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/bigdecimal-3.2.2/mkmf.log b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/bigdecimal-3.2.2/mkmf.log new file mode 100644 index 00000000..aba96191 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/bigdecimal-3.2.2/mkmf.log @@ -0,0 +1,643 @@ +have_builtin_func: checking for __builtin_clz()... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int main(int argc, char **argv) +4: { +5: return !!argv[argc]; +6: } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +conftest.c: In function ‘main’: +conftest.c:4:5: warning: old-style function definition [-Wold-style-definition] + 4 | int main() { __builtin_clz(0); return 0; } + | ^~~~ +At top level: +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int foo; +4: int main() { __builtin_clz(0); return 0; } +/* end */ + +-------------------- + +have_builtin_func: checking for __builtin_clzl()... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +conftest.c: In function ‘main’: +conftest.c:4:5: warning: old-style function definition [-Wold-style-definition] + 4 | int main() { __builtin_clzl(0); return 0; } + | ^~~~ +At top level: +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int foo; +4: int main() { __builtin_clzl(0); return 0; } +/* end */ + +-------------------- + +have_builtin_func: checking for __builtin_clzll()... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +conftest.c: In function ‘main’: +conftest.c:4:5: warning: old-style function definition [-Wold-style-definition] + 4 | int main() { __builtin_clzll(0); return 0; } + | ^~~~ +At top level: +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int foo; +4: int main() { __builtin_clzll(0); return 0; } +/* end */ + +-------------------- + +have_header: checking for float.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_header: checking for math.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_header: checking for stdbool.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_header: checking for stdlib.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_header: checking for x86intrin.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_func: checking for _lzcnt_u32() in x86intrin.h... -------------------- no + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +/usr/bin/ld: /tmp/ccP8kdYL.o: in function `t': +/home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/conftest.c:16:(.text+0x7): undefined reference to `_lzcnt_u32' +collect2: error: ld returned 1 exit status +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))_lzcnt_u32; return !p; } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +conftest.c:16:13: error: conflicting types for ‘_lzcnt_u32’; have ‘void()’ + 16 | extern void _lzcnt_u32(); + | ^~~~~~~~~~ +In file included from /usr/lib/gcc/x86_64-linux-gnu/13/include/x86gprintrin.h:61, + from /usr/lib/gcc/x86_64-linux-gnu/13/include/x86intrin.h:27, + from conftest.c:3: +/usr/lib/gcc/x86_64-linux-gnu/13/include/lzcntintrin.h:51:1: note: previous definition of ‘_lzcnt_u32’ with type ‘unsigned int(unsigned int)’ + 51 | _lzcnt_u32 (unsigned int __X) + | ^~~~~~~~~~ +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: extern void _lzcnt_u32(); +17: int t(void) { _lzcnt_u32(); return 0; } +/* end */ + +-------------------- + +have_func: checking for _lzcnt_u64() in x86intrin.h... -------------------- no + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +/usr/bin/ld: /tmp/cc8HzwOW.o: in function `t': +/home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/conftest.c:16:(.text+0x7): undefined reference to `_lzcnt_u64' +collect2: error: ld returned 1 exit status +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))_lzcnt_u64; return !p; } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +conftest.c:16:13: error: conflicting types for ‘_lzcnt_u64’; have ‘void()’ + 16 | extern void _lzcnt_u64(); + | ^~~~~~~~~~ +In file included from /usr/lib/gcc/x86_64-linux-gnu/13/include/x86gprintrin.h:61, + from /usr/lib/gcc/x86_64-linux-gnu/13/include/x86intrin.h:27, + from conftest.c:3: +/usr/lib/gcc/x86_64-linux-gnu/13/include/lzcntintrin.h:64:1: note: previous definition of ‘_lzcnt_u64’ with type ‘long long unsigned int(long long unsigned int)’ + 64 | _lzcnt_u64 (unsigned long long __X) + | ^~~~~~~~~~ +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: extern void _lzcnt_u64(); +17: int t(void) { _lzcnt_u64(); return 0; } +/* end */ + +-------------------- + +have_header: checking for intrin.h... -------------------- no + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +conftest.c:3:10: fatal error: intrin.h: No such file or directory + 3 | #include + | ^~~~~~~~~~ +compilation terminated. +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_func: checking for labs() in stdlib.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))labs; return !p; } +/* end */ + +-------------------- + +have_func: checking for llabs() in stdlib.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))llabs; return !p; } +/* end */ + +-------------------- + +have_func: checking for finite() in math.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))finite; return !p; } +/* end */ + +-------------------- + +have_func: checking for isfinite() in math.h... -------------------- no + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +conftest.c: In function ‘t’: +conftest.c:16:57: error: ‘isfinite’ undeclared (first use in this function); did you mean ‘finite’? + 16 | int t(void) { void ((*volatile p)()); p = (void ((*)()))isfinite; return !p; } + | ^~~~~~~~ + | finite +conftest.c:16:57: note: each undeclared identifier is reported only once for each function it appears in +At top level: +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))isfinite; return !p; } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +/usr/bin/ld: /tmp/ccqrkceo.o: in function `t': +/home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/conftest.c:17:(.text+0xb): undefined reference to `__builtin_isfinite' +collect2: error: ld returned 1 exit status +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: extern void isfinite(); +17: int t(void) { isfinite(); return 0; } +/* end */ + +-------------------- + +have_header: checking for ruby/atomic.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_header: checking for ruby/internal/has/builtin.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_header: checking for ruby/internal/static_assert.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_func: checking for rb_rational_num() in ruby.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_rational_num; return !p; } +/* end */ + +-------------------- + +have_func: checking for rb_rational_den() in ruby.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_rational_den; return !p; } +/* end */ + +-------------------- + +have_func: checking for rb_complex_real() in ruby.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_complex_real; return !p; } +/* end */ + +-------------------- + +have_func: checking for rb_complex_imag() in ruby.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_complex_imag; return !p; } +/* end */ + +-------------------- + +have_func: checking for rb_opts_exception_p() in ruby.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +conftest.c: In function ‘t’: +conftest.c:16:57: error: ‘rb_opts_exception_p’ undeclared (first use in this function); did you mean ‘rb_make_exception’? + 16 | int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_opts_exception_p; return !p; } + | ^~~~~~~~~~~~~~~~~~~ + | rb_make_exception +conftest.c:16:57: note: each undeclared identifier is reported only once for each function it appears in +At top level: +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_opts_exception_p; return !p; } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: extern void rb_opts_exception_p(); +17: int t(void) { rb_opts_exception_p(); return 0; } +/* end */ + +-------------------- + +have_func: checking for rb_category_warn() in ruby.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_category_warn; return !p; } +/* end */ + +-------------------- + +have_const: checking for RB_WARN_CATEGORY_DEPRECATED in ruby.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +4: +5: /*top*/ +6: typedef int conftest_type; +7: conftest_type conftestval = (int)RB_WARN_CATEGORY_DEPRECATED; +/* end */ + +-------------------- + diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/date-3.4.1/date_core.so b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/date-3.4.1/date_core.so new file mode 100755 index 00000000..6070a253 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/date-3.4.1/date_core.so differ diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/date-3.4.1/gem.build_complete b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/date-3.4.1/gem.build_complete new file mode 100644 index 00000000..e69de29b diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/date-3.4.1/gem_make.out b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/date-3.4.1/gem_make.out new file mode 100644 index 00000000..080d8529 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/date-3.4.1/gem_make.out @@ -0,0 +1,24 @@ +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date +/opt/hostedtoolcache/Ruby/3.4.4/x64/bin/ruby extconf.rb +checking for rb_category_warn()... yes +checking for timezone in time.h with -Werror... yes +checking for altzone in time.h with -Werror... no +creating Makefile + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-6hkdyv sitelibdir\=./.gem.20250609-2009-6hkdyv clean + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-6hkdyv sitelibdir\=./.gem.20250609-2009-6hkdyv +compiling date_core.c +compiling date_parse.c +compiling date_strftime.c +compiling date_strptime.c +linking shared-object date_core.so + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-6hkdyv sitelibdir\=./.gem.20250609-2009-6hkdyv install +/usr/bin/install -c -m 0755 date_core.so ./.gem.20250609-2009-6hkdyv + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-6hkdyv sitelibdir\=./.gem.20250609-2009-6hkdyv clean diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/date-3.4.1/mkmf.log b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/date-3.4.1/mkmf.log new file mode 100644 index 00000000..ce5937c2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/date-3.4.1/mkmf.log @@ -0,0 +1,93 @@ +have_func: checking for rb_category_warn()... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int main(int argc, char **argv) +4: { +5: return !!argv[argc]; +6: } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_category_warn; return !p; } +/* end */ + +-------------------- + +have_var: checking for timezone in time.h with -Werror... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -Werror -c conftest.c" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { const volatile void *volatile p; p = &(&timezone)[0]; return !p; } +/* end */ + +-------------------- + +have_var: checking for altzone in time.h with -Werror... -------------------- no + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -Werror -c conftest.c" +conftest.c: In function ‘t’: +conftest.c:16:55: error: ‘altzone’ undeclared (first use in this function) + 16 | int t(void) { const volatile void *volatile p; p = &(&altzone)[0]; return !p; } + | ^~~~~~~ +conftest.c:16:55: note: each undeclared identifier is reported only once for each function it appears in +At top level: +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { const volatile void *volatile p; p = &(&altzone)[0]; return !p; } +/* end */ + +-------------------- + diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/erb-5.0.1/erb/escape.so b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/erb-5.0.1/erb/escape.so new file mode 100755 index 00000000..b03bc666 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/erb-5.0.1/erb/escape.so differ diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/erb-5.0.1/gem.build_complete b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/erb-5.0.1/gem.build_complete new file mode 100644 index 00000000..e69de29b diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/erb-5.0.1/gem_make.out b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/erb-5.0.1/gem_make.out new file mode 100644 index 00000000..d284c202 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/erb-5.0.1/gem_make.out @@ -0,0 +1,18 @@ +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/ext/erb/escape +/opt/hostedtoolcache/Ruby/3.4.4/x64/bin/ruby extconf.rb +creating Makefile + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/ext/erb/escape +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-8o21mg sitelibdir\=./.gem.20250609-2009-8o21mg clean + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/ext/erb/escape +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-8o21mg sitelibdir\=./.gem.20250609-2009-8o21mg +compiling escape.c +linking shared-object erb/escape.so + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/ext/erb/escape +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-8o21mg sitelibdir\=./.gem.20250609-2009-8o21mg install +/usr/bin/install -c -m 0755 escape.so ./.gem.20250609-2009-8o21mg/erb + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/ext/erb/escape +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-8o21mg sitelibdir\=./.gem.20250609-2009-8o21mg clean diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/io-console-0.8.0/gem.build_complete b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/io-console-0.8.0/gem.build_complete new file mode 100644 index 00000000..e69de29b diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/io-console-0.8.0/gem_make.out b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/io-console-0.8.0/gem_make.out new file mode 100644 index 00000000..27f9e48e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/io-console-0.8.0/gem_make.out @@ -0,0 +1,31 @@ +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/ext/io/console +/opt/hostedtoolcache/Ruby/3.4.4/x64/bin/ruby extconf.rb +checking for rb_syserr_fail_str(0, Qnil)... yes +checking for rb_interned_str_cstr()... yes +checking for rb_io_path()... yes +checking for rb_io_descriptor()... yes +checking for rb_io_get_write_io()... yes +checking for rb_io_closed_p()... yes +checking for rb_io_open_descriptor()... yes +checking for rb_ractor_local_storage_value_newkey()... yes +checking for termios.h... yes +checking for cfmakeraw() in termios.h... yes +checking for sys/ioctl.h... yes +checking for HAVE_RUBY_FIBER_SCHEDULER_H... yes +checking for ttyname_r()... yes +creating Makefile + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/ext/io/console +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-kaz83k sitelibdir\=./.gem.20250609-2009-kaz83k clean + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/ext/io/console +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-kaz83k sitelibdir\=./.gem.20250609-2009-kaz83k +compiling console.c +linking shared-object io/console.so + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/ext/io/console +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-kaz83k sitelibdir\=./.gem.20250609-2009-kaz83k install +/usr/bin/install -c -m 0755 console.so ./.gem.20250609-2009-kaz83k/io + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/ext/io/console +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-kaz83k sitelibdir\=./.gem.20250609-2009-kaz83k clean diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/io-console-0.8.0/io/console.so b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/io-console-0.8.0/io/console.so new file mode 100755 index 00000000..aa2893c4 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/io-console-0.8.0/io/console.so differ diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/io-console-0.8.0/mkmf.log b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/io-console-0.8.0/mkmf.log new file mode 100644 index 00000000..fa1fcdf0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/io-console-0.8.0/mkmf.log @@ -0,0 +1,489 @@ +have_func: checking for rb_syserr_fail_str(0, Qnil)... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int main(int argc, char **argv) +4: { +5: return !!argv[argc]; +6: } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +conftest.c: In function ‘t’: +conftest.c:15:5: warning: function might be candidate for attribute ‘noreturn’ [-Wsuggest-attribute=noreturn] + 15 | int t(void) { rb_syserr_fail_str(0, Qnil); return 0; } + | ^ +At top level: +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: +15: int t(void) { rb_syserr_fail_str(0, Qnil); return 0; } +/* end */ + +-------------------- + +have_func: checking for rb_interned_str_cstr()... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_interned_str_cstr; return !p; } +/* end */ + +-------------------- + +have_func: checking for rb_io_path()... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +conftest.c: In function ‘t’: +conftest.c:14:57: error: ‘rb_io_path’ undeclared (first use in this function); did you mean ‘rb_io_puts’? + 14 | int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_io_path; return !p; } + | ^~~~~~~~~~ + | rb_io_puts +conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in +At top level: +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_io_path; return !p; } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: extern void rb_io_path(); +15: int t(void) { rb_io_path(); return 0; } +/* end */ + +-------------------- + +have_func: checking for rb_io_descriptor()... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +conftest.c: In function ‘t’: +conftest.c:14:57: error: ‘rb_io_descriptor’ undeclared (first use in this function) + 14 | int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_io_descriptor; return !p; } + | ^~~~~~~~~~~~~~~~ +conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in +At top level: +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_io_descriptor; return !p; } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: extern void rb_io_descriptor(); +15: int t(void) { rb_io_descriptor(); return 0; } +/* end */ + +-------------------- + +have_func: checking for rb_io_get_write_io()... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +conftest.c: In function ‘t’: +conftest.c:14:57: error: ‘rb_io_get_write_io’ undeclared (first use in this function) + 14 | int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_io_get_write_io; return !p; } + | ^~~~~~~~~~~~~~~~~~ +conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in +At top level: +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_io_get_write_io; return !p; } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: extern void rb_io_get_write_io(); +15: int t(void) { rb_io_get_write_io(); return 0; } +/* end */ + +-------------------- + +have_func: checking for rb_io_closed_p()... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +conftest.c: In function ‘t’: +conftest.c:14:57: error: ‘rb_io_closed_p’ undeclared (first use in this function); did you mean ‘rb_io_close’? + 14 | int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_io_closed_p; return !p; } + | ^~~~~~~~~~~~~~ + | rb_io_close +conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in +At top level: +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_io_closed_p; return !p; } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: extern void rb_io_closed_p(); +15: int t(void) { rb_io_closed_p(); return 0; } +/* end */ + +-------------------- + +have_func: checking for rb_io_open_descriptor()... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +conftest.c: In function ‘t’: +conftest.c:14:57: error: ‘rb_io_open_descriptor’ undeclared (first use in this function) + 14 | int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_io_open_descriptor; return !p; } + | ^~~~~~~~~~~~~~~~~~~~~ +conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in +At top level: +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_io_open_descriptor; return !p; } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: extern void rb_io_open_descriptor(); +15: int t(void) { rb_io_open_descriptor(); return 0; } +/* end */ + +-------------------- + +have_func: checking for rb_ractor_local_storage_value_newkey()... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +conftest.c: In function ‘t’: +conftest.c:14:57: error: ‘rb_ractor_local_storage_value_newkey’ undeclared (first use in this function) + 14 | int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_ractor_local_storage_value_newkey; return !p; } + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in +At top level: +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_ractor_local_storage_value_newkey; return !p; } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: extern void rb_ractor_local_storage_value_newkey(); +15: int t(void) { rb_ractor_local_storage_value_newkey(); return 0; } +/* end */ + +-------------------- + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +conftest.c:5:3: error: #error + 5 | # error + | ^~~~~ +conftest.c:6:1: error: expected identifier or ‘(’ before ‘|’ token + 6 | |:/ === _WIN32 undefined === /:| + | ^ +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: /*top*/ +4: #ifndef _WIN32 +5: # error +6: |:/ === _WIN32 undefined === /:| +7: #endif +/* end */ + +have_header: checking for termios.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_func: checking for cfmakeraw() in termios.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))cfmakeraw; return !p; } +/* end */ + +-------------------- + +have_header: checking for sys/ioctl.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_macro: checking for HAVE_RUBY_FIBER_SCHEDULER_H... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: /*top*/ +4: #ifndef HAVE_RUBY_FIBER_SCHEDULER_H +5: # error +6: |:/ === HAVE_RUBY_FIBER_SCHEDULER_H undefined === /:| +7: #endif +/* end */ + +-------------------- + +have_func: checking for ttyname_r()... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: int t(void) { void ((*volatile p)()); p = (void ((*)()))ttyname_r; return !p; } +/* end */ + +-------------------- + diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/json-2.12.2/gem.build_complete b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/json-2.12.2/gem.build_complete new file mode 100644 index 00000000..e69de29b diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/json-2.12.2/gem_make.out b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/json-2.12.2/gem_make.out new file mode 100644 index 00000000..93ee6a6b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/json-2.12.2/gem_make.out @@ -0,0 +1,23 @@ +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/parser +/opt/hostedtoolcache/Ruby/3.4.4/x64/bin/ruby extconf.rb +checking for rb_enc_interned_str() in ruby.h... yes +checking for rb_hash_new_capa() in ruby.h... yes +checking for rb_hash_bulk_insert() in ruby.h... yes +checking for strnlen() in string.h... yes +checking for whether -std=c99 is accepted as CFLAGS... yes +creating Makefile + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/parser +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-qtr9k8 sitelibdir\=./.gem.20250609-2009-qtr9k8 clean + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/parser +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-qtr9k8 sitelibdir\=./.gem.20250609-2009-qtr9k8 +compiling parser.c +linking shared-object json/ext/parser.so + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/parser +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-qtr9k8 sitelibdir\=./.gem.20250609-2009-qtr9k8 install +/usr/bin/install -c -m 0755 parser.so ./.gem.20250609-2009-qtr9k8/json/ext + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/parser +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-qtr9k8 sitelibdir\=./.gem.20250609-2009-qtr9k8 clean diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/json-2.12.2/json/ext/generator.so b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/json-2.12.2/json/ext/generator.so new file mode 100755 index 00000000..bbb87731 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/json-2.12.2/json/ext/generator.so differ diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/json-2.12.2/json/ext/parser.so b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/json-2.12.2/json/ext/parser.so new file mode 100755 index 00000000..008c1296 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/json-2.12.2/json/ext/parser.so differ diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/json-2.12.2/mkmf.log b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/json-2.12.2/mkmf.log new file mode 100644 index 00000000..c53a451c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/json-2.12.2/mkmf.log @@ -0,0 +1,158 @@ +have_func: checking for rb_enc_interned_str() in ruby.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int main(int argc, char **argv) +4: { +5: return !!argv[argc]; +6: } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +conftest.c: In function ‘t’: +conftest.c:16:57: error: ‘rb_enc_interned_str’ undeclared (first use in this function); did you mean ‘rb_interned_str’? + 16 | int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_enc_interned_str; return !p; } + | ^~~~~~~~~~~~~~~~~~~ + | rb_interned_str +conftest.c:16:57: note: each undeclared identifier is reported only once for each function it appears in +At top level: +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_enc_interned_str; return !p; } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: extern void rb_enc_interned_str(); +17: int t(void) { rb_enc_interned_str(); return 0; } +/* end */ + +-------------------- + +have_func: checking for rb_hash_new_capa() in ruby.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_hash_new_capa; return !p; } +/* end */ + +-------------------- + +have_func: checking for rb_hash_bulk_insert() in ruby.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_hash_bulk_insert; return !p; } +/* end */ + +-------------------- + +have_func: checking for strnlen() in string.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))strnlen; return !p; } +/* end */ + +-------------------- + +append_cflags: checking for whether -std=c99 is accepted as CFLAGS... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -std=c99 -Werror -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int main(int argc, char **argv) +4: { +5: return !!argv[argc]; +6: } +/* end */ + +-------------------- + diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/nio4r-2.7.4/gem.build_complete b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/nio4r-2.7.4/gem.build_complete new file mode 100644 index 00000000..e69de29b diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/nio4r-2.7.4/gem_make.out b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/nio4r-2.7.4/gem_make.out new file mode 100644 index 00000000..d7b4bf6a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/nio4r-2.7.4/gem_make.out @@ -0,0 +1,282 @@ +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r +/opt/hostedtoolcache/Ruby/3.4.4/x64/bin/ruby extconf.rb +checking for unistd.h... yes +checking for rb_io_descriptor()... yes +checking for linux/aio_abi.h... yes +checking for linux/io_uring.h... yes +checking for sys/select.h... yes +checking for port_event_t in poll.h... no +checking for sys/epoll.h... yes +checking for sys/event.h... no +checking for port_event_t in port.h... no +checking for sys/resource.h... yes +creating Makefile + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r +make DESTDIR\= sitearchdir\=./.gem.20250609-1995-6c6wv4 sitelibdir\=./.gem.20250609-1995-6c6wv4 clean + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r +make DESTDIR\= sitearchdir\=./.gem.20250609-1995-6c6wv4 sitelibdir\=./.gem.20250609-1995-6c6wv4 +compiling bytebuffer.c +bytebuffer.c: In function ‘Init_NIO_ByteBuffer’: +bytebuffer.c:59:6: warning: old-style function definition [-Wold-style-definition] + 59 | void Init_NIO_ByteBuffer() + | ^~~~~~~~~~~~~~~~~~~ +At top level: +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +compiling monitor.c +monitor.c: In function ‘Init_NIO_Monitor’: +monitor.c:50:6: warning: old-style function definition [-Wold-style-definition] + 50 | void Init_NIO_Monitor() + | ^~~~~~~~~~~~~~~~ +At top level: +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +compiling nio4r_ext.c +In file included from nio4r_ext.c:6: +../libev/ev.c:234:5: warning: "EV_NO_THREADS" is not defined, evaluates to 0 [-Wundef] + 234 | #if EV_NO_THREADS + | ^~~~~~~~~~~~~ +../libev/ev.c:240:5: warning: "EV_NO_SMP" is not defined, evaluates to 0 [-Wundef] + 240 | #if EV_NO_SMP + | ^~~~~~~~~ +../libev/ev.c:573:48: warning: "/*" within comment [-Wcomment] + 573 | /*#define MIN_INTERVAL 0.00000095367431640625 /* 1/2**20, good till 2200 */ + | +../libev/ev.c:691:7: warning: "__OPTIMIZE_SIZE__" is not defined, evaluates to 0 [-Wundef] + 691 | #if __OPTIMIZE_SIZE__ + | ^~~~~~~~~~~~~~~~~ +../libev/ev.c:700:7: warning: "_ILP32" is not defined, evaluates to 0 [-Wundef] + 700 | #if _ILP32 + | ^~~~~~ +../libev/ev.c:722:5: warning: "__clang__" is not defined, evaluates to 0 [-Wundef] + 722 | #if __clang__ && defined __has_builtin + | ^~~~~~~~~ +../libev/ev.c:728:5: warning: "__clang__" is not defined, evaluates to 0 [-Wundef] + 728 | #if __clang__ && defined __has_extension + | ^~~~~~~~~ +../libev/ev.c:734:20: warning: "__cplusplus" is not defined, evaluates to 0 [-Wundef] + 734 | #define ECB_CPP (__cplusplus+0) + | ^~~~~~~~~~~ +../libev/ev.c:739:5: note: in expansion of macro ‘ECB_CPP’ + 739 | #if ECB_CPP + | ^~~~~~~ +../libev/ev.c:734:20: warning: "__cplusplus" is not defined, evaluates to 0 [-Wundef] + 734 | #define ECB_CPP (__cplusplus+0) + | ^~~~~~~~~~~ +../libev/ev.c:751:5: note: in expansion of macro ‘ECB_CPP’ + 751 | #if ECB_CPP + | ^~~~~~~ +../libev/ev.c:766:5: warning: "ECB_NO_THREADS" is not defined, evaluates to 0 [-Wundef] + 766 | #if ECB_NO_THREADS + | ^~~~~~~~~~~~~~ +../libev/ev.c:770:5: warning: "ECB_NO_SMP" is not defined, evaluates to 0 [-Wundef] + 770 | #if ECB_NO_SMP + | ^~~~~~~~~~ +../libev/ev.c:775:5: warning: "__xlC__" is not defined, evaluates to 0 [-Wundef] + 775 | #if __xlC__ && ECB_CPP + | ^~~~~~~ +../libev/ev.c:779:13: warning: "_MSC_VER" is not defined, evaluates to 0 [-Wundef] + 779 | #if 1400 <= _MSC_VER + | ^~~~~~~~ +../libev/ev.c:786:9: warning: "__i386" is not defined, evaluates to 0 [-Wundef] + 786 | #if __i386 || __i386__ + | ^~~~~~ +../libev/ev.c:786:19: warning: "__i386__" is not defined, evaluates to 0 [-Wundef] + 786 | #if __i386 || __i386__ + | ^~~~~~~~ +../libev/ev.c:734:20: warning: "__cplusplus" is not defined, evaluates to 0 [-Wundef] + 734 | #define ECB_CPP (__cplusplus+0) + | ^~~~~~~~~~~ +../libev/ev.c:924:5: note: in expansion of macro ‘ECB_CPP’ + 924 | #if ECB_CPP + | ^~~~~~~ +../libev/ev.c:735:20: warning: "__cplusplus" is not defined, evaluates to 0 [-Wundef] + 735 | #define ECB_CPP11 (__cplusplus >= 201103L) + | ^~~~~~~~~~~ +../libev/ev.c:981:5: note: in expansion of macro ‘ECB_CPP11’ + 981 | #if ECB_CPP11 + | ^~~~~~~~~ +../libev/ev.c:989:5: warning: "_MSC_VER" is not defined, evaluates to 0 [-Wundef] + 989 | #if _MSC_VER >= 1300 + | ^~~~~~~~ +../libev/ev.c:995:5: warning: "_MSC_VER" is not defined, evaluates to 0 [-Wundef] + 995 | #if _MSC_VER >= 1500 + | ^~~~~~~~ +../libev/ev.c:1003:5: warning: "_MSC_VER" is not defined, evaluates to 0 [-Wundef] + 1003 | #if _MSC_VER >= 1400 + | ^~~~~~~~ +../libev/ev.c:734:20: warning: "__cplusplus" is not defined, evaluates to 0 [-Wundef] + 734 | #define ECB_CPP (__cplusplus+0) + | ^~~~~~~~~~~ +../libev/ev.c:1213:5: note: in expansion of macro ‘ECB_CPP’ + 1213 | #if ECB_CPP + | ^~~~~~~ +../libev/ev.c:734:20: warning: "__cplusplus" is not defined, evaluates to 0 [-Wundef] + 734 | #define ECB_CPP (__cplusplus+0) + | ^~~~~~~~~~~ +../libev/ev.c:1374:5: note: in expansion of macro ‘ECB_CPP’ + 1374 | #if ECB_CPP + | ^~~~~~~ +../libev/ev.c:734:20: warning: "__cplusplus" is not defined, evaluates to 0 [-Wundef] + 734 | #define ECB_CPP (__cplusplus+0) + | ^~~~~~~~~~~ +../libev/ev.c:1409:5: note: in expansion of macro ‘ECB_CPP’ + 1409 | #if ECB_CPP + | ^~~~~~~ +../libev/ev.c:1425:5: warning: "ecb_cplusplus_does_not_suck" is not defined, evaluates to 0 [-Wundef] + 1425 | #if ecb_cplusplus_does_not_suck + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +../libev/ev.c: In function ‘ecb_binary32_to_binary16’: +../libev/ev.c:1510:13: warning: comparison of integer expressions of different signedness: ‘unsigned int’ and ‘int’ [-Wsign-compare] + 1510 | if (e < (14 - 24)) /* might not be sharp, but is good enough */ + | ^ +../libev/ev.c: At top level: +../libev/ev.c:1540:8: warning: "__i386" is not defined, evaluates to 0 [-Wundef] + 1540 | || __i386 || __i386__ \ + | ^~~~~~ +../libev/ev.c:1540:18: warning: "__i386__" is not defined, evaluates to 0 [-Wundef] + 1540 | || __i386 || __i386__ \ + | ^~~~~~~~ +../libev/ev.c:1746:5: warning: "ECB_MEMORY_FENCE_NEEDS_PTHREADS" is not defined, evaluates to 0 [-Wundef] + 1746 | #if ECB_MEMORY_FENCE_NEEDS_PTHREADS + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +../libev/ev.c:1976:5: warning: "EV_AVOID_STDIO" is not defined, evaluates to 0 [-Wundef] + 1976 | #if EV_AVOID_STDIO + | ^~~~~~~~~~~~~~ +../libev/ev.c: In function ‘ev_syserr’: +../libev/ev.c:2005:5: warning: "EV_AVOID_STDIO" is not defined, evaluates to 0 [-Wundef] + 2005 | #if EV_AVOID_STDIO + | ^~~~~~~~~~~~~~ +../libev/ev.c: In function ‘ev_realloc’: +../libev/ev.c:2050:5: warning: "EV_AVOID_STDIO" is not defined, evaluates to 0 [-Wundef] + 2050 | #if EV_AVOID_STDIO + | ^~~~~~~~~~~~~~ +../libev/ev.c: At top level: +../libev/ev.c:2080:5: warning: "EV_SELECT_IS_WINSOCKET" is not defined, evaluates to 0 [-Wundef] + 2080 | #if EV_SELECT_IS_WINSOCKET || EV_USE_IOCP + | ^~~~~~~~~~~~~~~~~~~~~~ +../libev/ev.c:2080:31: warning: "EV_USE_IOCP" is not defined, evaluates to 0 [-Wundef] + 2080 | #if EV_SELECT_IS_WINSOCKET || EV_USE_IOCP + | ^~~~~~~~~~~ +../libev/ev.c:2083:5: warning: "EV_USE_IOCP" is not defined, evaluates to 0 [-Wundef] + 2083 | #if EV_USE_IOCP + | ^~~~~~~~~~~ +In file included from ../libev/ev.c:2130: +../libev/ev_vars.h:88:24: warning: "EV_GENWRAP" is not defined, evaluates to 0 [-Wundef] + 88 | #if defined(_WIN32) || EV_GENWRAP + | ^~~~~~~~~~ +../libev/ev_vars.h:150:22: warning: "EV_GENWRAP" is not defined, evaluates to 0 [-Wundef] + 150 | #if EV_USE_KQUEUE || EV_GENWRAP + | ^~~~~~~~~~ +../libev/ev_vars.h:159:20: warning: "EV_GENWRAP" is not defined, evaluates to 0 [-Wundef] + 159 | #if EV_USE_PORT || EV_GENWRAP + | ^~~~~~~~~~ +../libev/ev_vars.h:164:5: warning: "EV_USE_IOCP" is not defined, evaluates to 0 [-Wundef] + 164 | #if EV_USE_IOCP || EV_GENWRAP + | ^~~~~~~~~~~ +../libev/ev_vars.h:164:20: warning: "EV_GENWRAP" is not defined, evaluates to 0 [-Wundef] + 164 | #if EV_USE_IOCP || EV_GENWRAP + | ^~~~~~~~~~ +../libev/ev.c:2136:31: warning: ‘ev_default_loop_ptr’ initialized and declared ‘extern’ + 2136 | EV_API_DECL struct ev_loop *ev_default_loop_ptr = 0; /* needs to be initialised to make it a definition despite extern */ + | ^~~~~~~~~~~~~~~~~~~ +../libev/ev.c: In function ‘array_nextsize’: +../libev/ev.c:2249:19: warning: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’ [-Wsign-compare] + 2249 | if (elem * ncur > MALLOC_ROUND - sizeof (void *) * 4) + | ^ +../libev/ev.c: In function ‘fd_reify’: +../libev/ev.c:2402:5: warning: "EV_SELECT_IS_WINSOCKET" is not defined, evaluates to 0 [-Wundef] + 2402 | #if EV_SELECT_IS_WINSOCKET || EV_USE_IOCP + | ^~~~~~~~~~~~~~~~~~~~~~ +../libev/ev.c:2402:31: warning: "EV_USE_IOCP" is not defined, evaluates to 0 [-Wundef] + 2402 | #if EV_SELECT_IS_WINSOCKET || EV_USE_IOCP + | ^~~~~~~~~~~ +../libev/ev.c: At top level: +../libev/ev.c:3073:5: warning: "EV_USE_IOCP" is not defined, evaluates to 0 [-Wundef] + 3073 | #if EV_USE_IOCP + | ^~~~~~~~~~~ +In file included from ../libev/ev.c:3086: +../libev/ev_linuxaio.c: In function ‘linuxaio_poll’: +../libev/ev_linuxaio.c:467:10: warning: suggest explicit braces to avoid ambiguous ‘else’ [-Wdangling-else] + 467 | if (ecb_expect_false (res < 0)) + | ^ +In file included from ../libev/ev.c:3089: +../libev/ev_iouring.c: In function ‘iouring_sqe_submit’: +../libev/ev_iouring.c:298:31: warning: "/*" within comment [-Wcomment] + 298 | /*ECB_MEMORY_FENCE_RELEASE; /* for the time being we assume this is not needed */ + | +../libev/ev_iouring.c: In function ‘iouring_internal_init’: +../libev/ev_iouring.c:359:5: warning: "TODO" is not defined, evaluates to 0 [-Wundef] + 359 | #if TODO + | ^~~~ +In file included from ../libev/ev.c:3095: +../libev/ev_select.c: At top level: +../libev/ev_select.c:57:5: warning: "EV_SELECT_IS_WINSOCKET" is not defined, evaluates to 0 [-Wundef] + 57 | #if EV_SELECT_IS_WINSOCKET + | ^~~~~~~~~~~~~~~~~~~~~~ +../libev/ev_select.c: In function ‘select_poll’: +../libev/ev_select.c:176:11: warning: "EV_SELECT_IS_WINSOCKET" is not defined, evaluates to 0 [-Wundef] + 176 | #if EV_SELECT_IS_WINSOCKET + | ^~~~~~~~~~~~~~~~~~~~~~ +../libev/ev.c: In function ‘loop_init’: +../libev/ev.c:3318:5: warning: "EV_USE_IOCP" is not defined, evaluates to 0 [-Wundef] + 3318 | #if EV_USE_IOCP + | ^~~~~~~~~~~ +../libev/ev.c: In function ‘ev_loop_destroy’: +../libev/ev.c:3409:5: warning: "EV_USE_IOCP" is not defined, evaluates to 0 [-Wundef] + 3409 | #if EV_USE_IOCP + | ^~~~~~~~~~~ +../libev/ev.c: In function ‘ev_io_start’: +../libev/ev.c:4417:34: warning: suggest parentheses around arithmetic in operand of ‘|’ [-Wparentheses] + 4417 | fd_change (EV_A_ fd, w->events & EV__IOFDSET | EV_ANFD_REIFY); + | ~~~~~~~~~~^~~~~~~~~~~~~ +../libev/ev.c: At top level: +../libev/ev.c:5682:27: warning: "/*" within comment [-Wcomment] + 5682 | /* EV_STAT 0x00001000 /* stat data changed */ + | +../libev/ev.c:5683:27: warning: "/*" within comment [-Wcomment] + 5683 | /* EV_EMBED 0x00010000 /* embedded event loop needs sweep */ + | +nio4r_ext.c: In function ‘Init_nio4r_ext’: +nio4r_ext.c:13:6: warning: old-style function definition [-Wold-style-definition] + 13 | void Init_nio4r_ext() + | ^~~~~~~~~~~~~~ +../libev/ev.c: In function ‘evpipe_write’: +../libev/ev.c:2798:11: warning: ignoring return value of ‘write’ declared with attribute ‘warn_unused_result’ [-Wunused-result] + 2798 | write (evpipe [1], &counter, sizeof (uint64_t)); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +../libev/ev.c:2810:11: warning: ignoring return value of ‘write’ declared with attribute ‘warn_unused_result’ [-Wunused-result] + 2810 | write (evpipe [1], &(evpipe [1]), 1); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +../libev/ev.c: In function ‘pipecb’: +../libev/ev.c:2831:11: warning: ignoring return value of ‘read’ declared with attribute ‘warn_unused_result’ [-Wunused-result] + 2831 | read (evpipe [1], &counter, sizeof (uint64_t)); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +../libev/ev.c:2845:11: warning: ignoring return value of ‘read’ declared with attribute ‘warn_unused_result’ [-Wunused-result] + 2845 | read (evpipe [0], &dummy, sizeof (dummy)); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +At top level: +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +compiling selector.c +selector.c: In function ‘NIO_Selector_wakeup’: +selector.c:525:5: warning: ignoring return value of ‘write’ declared with attribute ‘warn_unused_result’ [-Wunused-result] + 525 | write(selector->wakeup_writer, "\0", 1); + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +At top level: +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +linking shared-object nio4r_ext.so + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r +make DESTDIR\= sitearchdir\=./.gem.20250609-1995-6c6wv4 sitelibdir\=./.gem.20250609-1995-6c6wv4 install +/usr/bin/install -c -m 0755 nio4r_ext.so ./.gem.20250609-1995-6c6wv4 + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r +make DESTDIR\= sitearchdir\=./.gem.20250609-1995-6c6wv4 sitelibdir\=./.gem.20250609-1995-6c6wv4 clean diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/nio4r-2.7.4/mkmf.log b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/nio4r-2.7.4/mkmf.log new file mode 100644 index 00000000..cde9977d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/nio4r-2.7.4/mkmf.log @@ -0,0 +1,193 @@ +have_header: checking for unistd.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int main(int argc, char **argv) +4: { +5: return !!argv[argc]; +6: } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_func: checking for rb_io_descriptor()... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +conftest.c: In function ‘t’: +conftest.c:14:57: error: ‘rb_io_descriptor’ undeclared (first use in this function) + 14 | int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_io_descriptor; return !p; } + | ^~~~~~~~~~~~~~~~ +conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in +At top level: +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: int t(void) { void ((*volatile p)()); p = (void ((*)()))rb_io_descriptor; return !p; } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: extern void rb_io_descriptor(); +15: int t(void) { rb_io_descriptor(); return 0; } +/* end */ + +-------------------- + +have_header: checking for linux/aio_abi.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_header: checking for linux/io_uring.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_header: checking for sys/select.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_type: checking for port_event_t in poll.h... -------------------- no + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +conftest.c:6:9: error: unknown type name ‘port_event_t’ + 6 | typedef port_event_t conftest_type; + | ^~~~~~~~~~~~ +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +4: +5: /*top*/ +6: typedef port_event_t conftest_type; +7: int conftestval[sizeof(conftest_type)?1:-1]; +/* end */ + +-------------------- + +have_header: checking for sys/epoll.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_header: checking for sys/event.h... -------------------- no + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +conftest.c:3:10: fatal error: sys/event.h: No such file or directory + 3 | #include + | ^~~~~~~~~~~~~ +compilation terminated. +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_type: checking for port_event_t in port.h... -------------------- no + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +conftest.c:3:10: fatal error: port.h: No such file or directory + 3 | #include + | ^~~~~~~~ +compilation terminated. +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +4: +5: /*top*/ +6: typedef port_event_t conftest_type; +7: int conftestval[sizeof(conftest_type)?1:-1]; +/* end */ + +-------------------- + +have_header: checking for sys/resource.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/nio4r-2.7.4/nio4r_ext.so b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/nio4r-2.7.4/nio4r_ext.so new file mode 100755 index 00000000..9aa3501f Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/nio4r-2.7.4/nio4r_ext.so differ diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/prism-1.4.0/gem.build_complete b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/prism-1.4.0/gem.build_complete new file mode 100644 index 00000000..e69de29b diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/prism-1.4.0/gem_make.out b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/prism-1.4.0/gem_make.out new file mode 100644 index 00000000..5f879e88 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/prism-1.4.0/gem_make.out @@ -0,0 +1,44 @@ +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext/prism +/opt/hostedtoolcache/Ruby/3.4.4/x64/bin/ruby extconf.rb +checking for prism.h in /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include... yes +checking for prism/extension.h in /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext... yes +checking for whether -fvisibility=hidden is accepted as CFLAGS... yes +creating Makefile + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext/prism +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-z0qi3i sitelibdir\=./.gem.20250609-2009-z0qi3i clean + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext/prism +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-z0qi3i sitelibdir\=./.gem.20250609-2009-z0qi3i +compiling api_node.c +compiling api_pack.c +compiling extension.c +compiling ./../../src/diagnostic.c +compiling ./../../src/encoding.c +compiling ./../../src/node.c +compiling ./../../src/options.c +compiling ./../../src/pack.c +compiling ./../../src/prettyprint.c +compiling ./../../src/prism.c +compiling ./../../src/regexp.c +compiling ./../../src/serialize.c +compiling ./../../src/static_literals.c +compiling ./../../src/token_type.c +compiling ./../../src/util/pm_buffer.c +compiling ./../../src/util/pm_char.c +compiling ./../../src/util/pm_constant_pool.c +compiling ./../../src/util/pm_integer.c +compiling ./../../src/util/pm_list.c +compiling ./../../src/util/pm_memchr.c +compiling ./../../src/util/pm_newline_list.c +compiling ./../../src/util/pm_string.c +compiling ./../../src/util/pm_strncasecmp.c +compiling ./../../src/util/pm_strpbrk.c +linking shared-object prism/prism.so + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext/prism +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-z0qi3i sitelibdir\=./.gem.20250609-2009-z0qi3i install +/usr/bin/install -c -m 0755 prism.so ./.gem.20250609-2009-z0qi3i/prism + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext/prism +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-z0qi3i sitelibdir\=./.gem.20250609-2009-z0qi3i clean diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/prism-1.4.0/mkmf.log b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/prism-1.4.0/mkmf.log new file mode 100644 index 00000000..a4537e25 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/prism-1.4.0/mkmf.log @@ -0,0 +1,74 @@ +find_header: checking for prism.h in /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int main(int argc, char **argv) +4: { +5: return !!argv[argc]; +6: } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +conftest.c:3:10: fatal error: prism.h: No such file or directory + 3 | #include + | ^~~~~~~~~ +compilation terminated. +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -I/home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +find_header: checking for prism/extension.h in /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -I/home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +conftest.c:3:10: fatal error: prism/extension.h: No such file or directory + 3 | #include + | ^~~~~~~~~~~~~~~~~~~ +compilation terminated. +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -I/home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -I/home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +append_cflags: checking for whether -fvisibility=hidden is accepted as CFLAGS... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -I/home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include -I/home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -fvisibility=hidden -Werror -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int main(int argc, char **argv) +4: { +5: return !!argv[argc]; +6: } +/* end */ + +-------------------- + diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/prism-1.4.0/prism/prism.so b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/prism-1.4.0/prism/prism.so new file mode 100755 index 00000000..45b409d9 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/prism-1.4.0/prism/prism.so differ diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/psych-5.2.6/gem.build_complete b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/psych-5.2.6/gem.build_complete new file mode 100644 index 00000000..e69de29b diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/psych-5.2.6/gem_make.out b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/psych-5.2.6/gem_make.out new file mode 100644 index 00000000..86ccda44 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/psych-5.2.6/gem_make.out @@ -0,0 +1,31 @@ +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych +/opt/hostedtoolcache/Ruby/3.4.4/x64/bin/ruby extconf.rb +checking for pkg-config for yaml-0.1... [" ", "", "-lyaml"] +checking for yaml.h... yes +checking for yaml_get_version() in -lyaml... yes +creating Makefile + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-cuerz2 sitelibdir\=./.gem.20250609-2009-cuerz2 clean +cd libyaml && make clean +/bin/sh: 1: cd: can't cd to libyaml +make: [Makefile:287: clean-so] Error 2 (ignored) + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-cuerz2 sitelibdir\=./.gem.20250609-2009-cuerz2 +compiling psych.c +compiling psych_emitter.c +compiling psych_parser.c +compiling psych_to_ruby.c +compiling psych_yaml_tree.c +linking shared-object psych.so + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-cuerz2 sitelibdir\=./.gem.20250609-2009-cuerz2 install +/usr/bin/install -c -m 0755 psych.so ./.gem.20250609-2009-cuerz2 + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-cuerz2 sitelibdir\=./.gem.20250609-2009-cuerz2 clean +cd libyaml && make clean +/bin/sh: 1: cd: can't cd to libyaml +make: [Makefile:287: clean-so] Error 2 (ignored) diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/psych-5.2.6/mkmf.log b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/psych-5.2.6/mkmf.log new file mode 100644 index 00000000..f1134fc5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/psych-5.2.6/mkmf.log @@ -0,0 +1,105 @@ +pkg_config: checking for pkg-config for yaml-0.1... -------------------- [" ", "", "-lyaml"] + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 pkg-config --exists yaml-0.1 +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 pkg-config --libs yaml-0.1 | +=> "-lyaml \n" +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int main(int argc, char **argv) +4: { +5: return !!argv[argc]; +6: } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lyaml -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int main(int argc, char **argv) +4: { +5: return !!argv[argc]; +6: } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 pkg-config --cflags-only-I yaml-0.1 | +=> "\n" +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 pkg-config --cflags-only-other yaml-0.1 | +=> "\n" +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 pkg-config --libs-only-l yaml-0.1 | +=> "-lyaml \n" +package configuration for yaml-0.1 +incflags: +cflags: +ldflags: +libs: -lyaml + +-------------------- + +find_header: checking for yaml.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +find_library: checking for yaml_get_version() in -lyaml... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lyaml -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lyaml -lyaml -lm -lpthread -lc" +conftest.c: In function ‘t’: +conftest.c:14:57: error: ‘yaml_get_version’ undeclared (first use in this function) + 14 | int t(void) { void ((*volatile p)()); p = (void ((*)()))yaml_get_version; return !p; } + | ^~~~~~~~~~~~~~~~ +conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in +At top level: +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: int t(void) { void ((*volatile p)()); p = (void ((*)()))yaml_get_version; return !p; } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lyaml -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lyaml -lyaml -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: extern void yaml_get_version(); +15: int t(void) { yaml_get_version(); return 0; } +/* end */ + +-------------------- + diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/psych-5.2.6/psych.so b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/psych-5.2.6/psych.so new file mode 100755 index 00000000..969437c2 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/psych-5.2.6/psych.so differ diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/puma-6.6.0/gem.build_complete b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/puma-6.6.0/gem.build_complete new file mode 100644 index 00000000..e69de29b diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/puma-6.6.0/gem_make.out b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/puma-6.6.0/gem_make.out new file mode 100644 index 00000000..ee7caa7b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/puma-6.6.0/gem_make.out @@ -0,0 +1,43 @@ +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11 +/opt/hostedtoolcache/Ruby/3.4.4/x64/bin/ruby extconf.rb +checking for BIO_read() in -llibcrypto... no +checking for BIO_read() in -lcrypto... yes +checking for SSL_CTX_new() in -lssl... yes +checking for openssl/bio.h... yes + +──── Below are yes for 1.0.2 & later ──── +checking for DTLS_method() in openssl/ssl.h... yes +checking for SSL_CTX_set_session_cache_mode(NULL, 0) in openssl/ssl.h... yes + +──── Below are yes for 1.1.0 & later ──── +checking for TLS_server_method() in openssl/ssl.h... yes +checking for SSL_CTX_set_min_proto_version(NULL, 0) in openssl/ssl.h... yes + +──── Below is yes for 1.1.0 and later, but isn't documented until 3.0.0 ──── +checking for SSL_CTX_set_dh_auto(NULL, 0) in openssl/ssl.h... yes + +──── Below is yes for 1.1.1 & later ──── +checking for SSL_CTX_set_ciphersuites(NULL, "") in openssl/ssl.h... yes + +──── Below is yes for 3.0.0 & later ──── +checking for SSL_get1_peer_certificate() in openssl/ssl.h... yes + +checking for Random.bytes... yes +creating Makefile + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11 +make DESTDIR\= sitearchdir\=./.gem.20250609-1995-gzebt0 sitelibdir\=./.gem.20250609-1995-gzebt0 clean + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11 +make DESTDIR\= sitearchdir\=./.gem.20250609-1995-gzebt0 sitelibdir\=./.gem.20250609-1995-gzebt0 +compiling http11_parser.c +compiling mini_ssl.c +compiling puma_http11.c +linking shared-object puma/puma_http11.so + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11 +make DESTDIR\= sitearchdir\=./.gem.20250609-1995-gzebt0 sitelibdir\=./.gem.20250609-1995-gzebt0 install +/usr/bin/install -c -m 0755 puma_http11.so ./.gem.20250609-1995-gzebt0/puma + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11 +make DESTDIR\= sitearchdir\=./.gem.20250609-1995-gzebt0 sitelibdir\=./.gem.20250609-1995-gzebt0 clean diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/puma-6.6.0/mkmf.log b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/puma-6.6.0/mkmf.log new file mode 100644 index 00000000..5983ec94 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/puma-6.6.0/mkmf.log @@ -0,0 +1,376 @@ +have_library: checking for BIO_read() in -llibcrypto... -------------------- no + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int main(int argc, char **argv) +4: { +5: return !!argv[argc]; +6: } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -llibcrypto -lm -lpthread -lc" +conftest.c: In function ‘t’: +conftest.c:14:57: error: ‘BIO_read’ undeclared (first use in this function) + 14 | int t(void) { void ((*volatile p)()); p = (void ((*)()))BIO_read; return !p; } + | ^~~~~~~~ +conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in +At top level: +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: int t(void) { void ((*volatile p)()); p = (void ((*)()))BIO_read; return !p; } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -llibcrypto -lm -lpthread -lc" +/usr/bin/ld: cannot find -llibcrypto: No such file or directory +/usr/bin/ld: note to link with /usr/lib/gcc/x86_64-linux-gnu/13/../../../x86_64-linux-gnu/libcrypto.a use -l:libcrypto.a or rename it to liblibcrypto.a +collect2: error: ld returned 1 exit status +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: extern void BIO_read(); +15: int t(void) { BIO_read(); return 0; } +/* end */ + +-------------------- + +have_library: checking for BIO_read() in -lcrypto... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lcrypto -lm -lpthread -lc" +conftest.c: In function ‘t’: +conftest.c:14:57: error: ‘BIO_read’ undeclared (first use in this function) + 14 | int t(void) { void ((*volatile p)()); p = (void ((*)()))BIO_read; return !p; } + | ^~~~~~~~ +conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in +At top level: +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: int t(void) { void ((*volatile p)()); p = (void ((*)()))BIO_read; return !p; } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lcrypto -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: extern void BIO_read(); +15: int t(void) { BIO_read(); return 0; } +/* end */ + +-------------------- + +have_library: checking for SSL_CTX_new() in -lssl... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lcrypto -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lssl -lcrypto -lm -lpthread -lc" +conftest.c: In function ‘t’: +conftest.c:14:57: error: ‘SSL_CTX_new’ undeclared (first use in this function) + 14 | int t(void) { void ((*volatile p)()); p = (void ((*)()))SSL_CTX_new; return !p; } + | ^~~~~~~~~~~ +conftest.c:14:57: note: each undeclared identifier is reported only once for each function it appears in +At top level: +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: int t(void) { void ((*volatile p)()); p = (void ((*)()))SSL_CTX_new; return !p; } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lcrypto -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lssl -lcrypto -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: /*top*/ + 4: extern int t(void); + 5: int main(int argc, char **argv) + 6: { + 7: if (argc > 1000000) { + 8: int (* volatile tp)(void)=(int (*)(void))&t; + 9: printf("%d", (*tp)()); +10: } +11: +12: return !!argv[argc]; +13: } +14: extern void SSL_CTX_new(); +15: int t(void) { SSL_CTX_new(); return 0; } +/* end */ + +-------------------- + +have_header: checking for openssl/bio.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +/* end */ + +-------------------- + +have_func: checking for DTLS_method() in openssl/ssl.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lssl -lcrypto -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lssl -lcrypto -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))DTLS_method; return !p; } +/* end */ + +-------------------- + +have_func: checking for SSL_CTX_set_session_cache_mode(NULL, 0) in openssl/ssl.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lssl -lcrypto -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lssl -lcrypto -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: +17: int t(void) { SSL_CTX_set_session_cache_mode(NULL, 0); return 0; } +/* end */ + +-------------------- + +have_func: checking for TLS_server_method() in openssl/ssl.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lssl -lcrypto -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lssl -lcrypto -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))TLS_server_method; return !p; } +/* end */ + +-------------------- + +have_func: checking for SSL_CTX_set_min_proto_version(NULL, 0) in openssl/ssl.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lssl -lcrypto -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lssl -lcrypto -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: +17: int t(void) { SSL_CTX_set_min_proto_version(NULL, 0); return 0; } +/* end */ + +-------------------- + +have_func: checking for SSL_CTX_set_dh_auto(NULL, 0) in openssl/ssl.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lssl -lcrypto -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lssl -lcrypto -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: +17: int t(void) { SSL_CTX_set_dh_auto(NULL, 0); return 0; } +/* end */ + +-------------------- + +have_func: checking for SSL_CTX_set_ciphersuites(NULL, "") in openssl/ssl.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lssl -lcrypto -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lssl -lcrypto -lm -lpthread -lc" +conftest.c: In function ‘t’: +conftest.c:17:30: warning: ‘s1’ may be used uninitialized [-Wmaybe-uninitialized] + 17 | int t(void) { char s1[1024]; SSL_CTX_set_ciphersuites(NULL, s1); return 0; } + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In file included from conftest.c:3: +/usr/include/openssl/ssl.h:1651:12: note: by argument 2 of type ‘const char *’ to ‘SSL_CTX_set_ciphersuites’ declared here + 1651 | __owur int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str); + | ^~~~~~~~~~~~~~~~~~~~~~~~ +conftest.c:17:20: note: ‘s1’ declared here + 17 | int t(void) { char s1[1024]; SSL_CTX_set_ciphersuites(NULL, s1); return 0; } + | ^~ +At top level: +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: +17: int t(void) { char s1[1024]; SSL_CTX_set_ciphersuites(NULL, s1); return 0; } +/* end */ + +-------------------- + +have_func: checking for SSL_get1_peer_certificate() in openssl/ssl.h... -------------------- yes + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -lssl -lcrypto -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lssl -lcrypto -lm -lpthread -lc" +checked program was: +/* begin */ + 1: #include "ruby.h" + 2: + 3: #include + 4: + 5: /*top*/ + 6: extern int t(void); + 7: int main(int argc, char **argv) + 8: { + 9: if (argc > 1000000) { +10: int (* volatile tp)(void)=(int (*)(void))&t; +11: printf("%d", (*tp)()); +12: } +13: +14: return !!argv[argc]; +15: } +16: int t(void) { void ((*volatile p)()); p = (void ((*)()))SSL_get1_peer_certificate; return !p; } +/* end */ + +-------------------- + diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/puma-6.6.0/puma/puma_http11.so b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/puma-6.6.0/puma/puma_http11.so new file mode 100755 index 00000000..e7b4de5b Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/puma-6.6.0/puma/puma_http11.so differ diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/racc-1.8.1/gem.build_complete b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/racc-1.8.1/gem.build_complete new file mode 100644 index 00000000..e69de29b diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/racc-1.8.1/gem_make.out b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/racc-1.8.1/gem_make.out new file mode 100644 index 00000000..838d9980 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/racc-1.8.1/gem_make.out @@ -0,0 +1,18 @@ +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/ext/racc/cparse +/opt/hostedtoolcache/Ruby/3.4.4/x64/bin/ruby extconf.rb +creating Makefile + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/ext/racc/cparse +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-cgbjoc sitelibdir\=./.gem.20250609-2009-cgbjoc clean + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/ext/racc/cparse +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-cgbjoc sitelibdir\=./.gem.20250609-2009-cgbjoc +compiling cparse.c +linking shared-object racc/cparse.so + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/ext/racc/cparse +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-cgbjoc sitelibdir\=./.gem.20250609-2009-cgbjoc install +/usr/bin/install -c -m 0755 cparse.so ./.gem.20250609-2009-cgbjoc/racc + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/ext/racc/cparse +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-cgbjoc sitelibdir\=./.gem.20250609-2009-cgbjoc clean diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/racc-1.8.1/racc/cparse.so b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/racc-1.8.1/racc/cparse.so new file mode 100755 index 00000000..e8af7b39 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/racc-1.8.1/racc/cparse.so differ diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/stringio-3.1.7/gem.build_complete b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/stringio-3.1.7/gem.build_complete new file mode 100644 index 00000000..e69de29b diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/stringio-3.1.7/gem_make.out b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/stringio-3.1.7/gem_make.out new file mode 100644 index 00000000..4c240725 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/stringio-3.1.7/gem_make.out @@ -0,0 +1,19 @@ +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/stringio-3.1.7/ext/stringio +/opt/hostedtoolcache/Ruby/3.4.4/x64/bin/ruby extconf.rb +checking for rb_io_mode_t in ruby/io.h... no +creating Makefile + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/stringio-3.1.7/ext/stringio +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-ysxtxx sitelibdir\=./.gem.20250609-2009-ysxtxx clean + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/stringio-3.1.7/ext/stringio +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-ysxtxx sitelibdir\=./.gem.20250609-2009-ysxtxx +compiling stringio.c +linking shared-object stringio.so + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/stringio-3.1.7/ext/stringio +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-ysxtxx sitelibdir\=./.gem.20250609-2009-ysxtxx install +/usr/bin/install -c -m 0755 stringio.so ./.gem.20250609-2009-ysxtxx + +current directory: /home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/stringio-3.1.7/ext/stringio +make DESTDIR\= sitearchdir\=./.gem.20250609-2009-ysxtxx sitelibdir\=./.gem.20250609-2009-ysxtxx clean diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/stringio-3.1.7/mkmf.log b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/stringio-3.1.7/mkmf.log new file mode 100644 index 00000000..98eedece --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/stringio-3.1.7/mkmf.log @@ -0,0 +1,33 @@ +have_type: checking for rb_io_mode_t in ruby/io.h... -------------------- no + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -o conftest -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -L/opt/hostedtoolcache/Ruby/3.4.4/x64/lib -lruby -lm -lpthread -lc" +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: int main(int argc, char **argv) +4: { +5: return !!argv[argc]; +6: } +/* end */ + +LD_LIBRARY_PATH=.:/opt/hostedtoolcache/Ruby/3.4.4/x64/lib ASAN_OPTIONS=detect_leaks=0 "gcc -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/ruby/backward -I/opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 -I. -DENABLE_PATH_CHECK=0 -fstack-protector-strong -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC -c conftest.c" +conftest.c:6:9: error: unknown type name ‘rb_io_mode_t’ + 6 | typedef rb_io_mode_t conftest_type; + | ^~~~~~~~~~~~ +cc1: note: unrecognized command-line option ‘-Wno-self-assign’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may have been intended to silence earlier diagnostics +cc1: note: unrecognized command-line option ‘-Wno-constant-logical-operand’ may have been intended to silence earlier diagnostics +checked program was: +/* begin */ +1: #include "ruby.h" +2: +3: #include +4: +5: /*top*/ +6: typedef rb_io_mode_t conftest_type; +7: int conftestval[sizeof(conftest_type)?1:-1]; +/* end */ + +-------------------- + diff --git a/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/stringio-3.1.7/stringio.so b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/stringio-3.1.7/stringio.so new file mode 100755 index 00000000..5fa64bbb Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/extensions/x86_64-linux/3.4.0/stringio-3.1.7/stringio.so differ diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/CHANGELOG.md b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/CHANGELOG.md new file mode 100644 index 00000000..3ba2954f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/CHANGELOG.md @@ -0,0 +1,255 @@ +## Rails 8.0.2 (March 12, 2025) ## + +* No changes. + + +## Rails 8.0.2 (March 12, 2025) ## + +* Fix setting `to_time_preserves_timezone` from `new_framework_defaults_8_0.rb`. + + *fatkodima* + +* Fix Active Support Cache `fetch_multi` when local store is active. + + `fetch_multi` now properly yield to the provided block for missing entries + that have been recorded as such in the local store. + + *Jean Boussier* + +* Fix execution wrapping to report all exceptions, including `Exception`. + + If a more serious error like `SystemStackError` or `NoMemoryError` happens, + the error reporter should be able to report these kinds of exceptions. + + *Gannon McGibbon* + +* Fix `RedisCacheStore` and `MemCacheStore` to also handle connection pool related errors. + + These errors are rescued and reported to `Rails.error`. + + *Jean Boussier* + +* Fix `ActiveSupport::Cache#read_multi` to respect version expiry when using local cache. + + *zzak* + +* Fix `ActiveSupport::MessageVerifier` and `ActiveSupport::MessageEncryptor` configuration of `on_rotation` callback. + + ```ruby + verifier.rotate(old_secret).on_rotation { ... } + ``` + + Now both work as documented. + + *Jean Boussier* + +* Fix `ActiveSupport::MessageVerifier` to always be able to verify both URL-safe and URL-unsafe payloads. + + This is to allow transitioning seemlessly from either configuration without immediately invalidating + all previously generated signed messages. + + *Jean Boussier*, *Florent Beaurain*, *Ali Sepehri* + +* Fix `cache.fetch` to honor the provided expiry when `:race_condition_ttl` is used. + + ```ruby + cache.fetch("key", expires_in: 1.hour, race_condition_ttl: 5.second) do + "something" + end + ``` + + In the above example, the final cache entry would have a 10 seconds TTL instead + of the requested 1 hour. + + *Dhia* + +* Better handle procs with splat arguments in `set_callback`. + + *Radamés Roriz* + +* Fix `String#mb_chars` to not mutate the receiver. + + Previously it would call `force_encoding` on the receiver, + now it dups the receiver first. + + *Jean Boussier* + +* Improve `ErrorSubscriber` to also mark error causes as reported. + + This avoid some cases of errors being reported twice, notably in views because of how + errors are wrapped in `ActionView::Template::Error`. + + *Jean Boussier* + +* Fix `Module#module_parent_name` to return the correct name after the module has been named. + + When called on an anonymous module, the return value wouldn't change after the module was given a name + later by being assigned to a constant. + + ```ruby + mod = Module.new + mod.module_parent_name # => "Object" + MyModule::Something = mod + mod.module_parent_name # => "MyModule" + ``` + + *Jean Boussier* + + +## Rails 8.0.1 (December 13, 2024) ## + +* Fix a bug in `ERB::Util.tokenize` that causes incorrect tokenization when ERB tags are preceeded by multibyte characters. + + *Martin Emde* + +* Restore the ability to decorate methods generated by `class_attribute`. + + It always has been complicated to use Module#prepend or an alias method chain + to decorate methods defined by `class_attribute`, but became even harder in 8.0. + + This capability is now supported for both reader and writer methods. + + *Jean Boussier* + + +## Rails 8.0.0.1 (December 10, 2024) ## + +* No changes. + + +## Rails 8.0.0 (November 07, 2024) ## + +* No changes. + + +## Rails 8.0.0.rc2 (October 30, 2024) ## + +* No changes. + + +## Rails 8.0.0.rc1 (October 19, 2024) ## + +* Remove deprecated support to passing an array of strings to `ActiveSupport::Deprecation#warn`. + + *Rafael Mendonça França* + +* Remove deprecated support to setting `attr_internal_naming_format` with a `@` prefix. + + *Rafael Mendonça França* + +* Remove deprecated `ActiveSupport::ProxyObject`. + + *Rafael Mendonça França* + +* Don't execute i18n watcher on boot. It shouldn't catch any file changes initially, + and unnecessarily slows down boot of applications with lots of translations. + + *Gannon McGibbon*, *David Stosik* + +* Fix `ActiveSupport::HashWithIndifferentAccess#stringify_keys` to stringify all keys not just symbols. + + Previously: + + ```ruby + { 1 => 2 }.with_indifferent_access.stringify_keys[1] # => 2 + ``` + + After this change: + + ```ruby + { 1 => 2 }.with_indifferent_access.stringify_keys["1"] # => 2 + ``` + + This change can be seen as a bug fix, but since it behaved like this for a very long time, we're deciding + to not backport the fix and to make the change in a major release. + + *Jean Boussier* + +## Rails 8.0.0.beta1 (September 26, 2024) ## + +* Include options when instrumenting `ActiveSupport::Cache::Store#delete` and `ActiveSupport::Cache::Store#delete_multi`. + + *Adam Renberg Tamm* + +* Print test names when running `rails test -v` for parallel tests. + + *John Hawthorn*, *Abeid Ahmed* + +* Deprecate `Benchmark.ms` core extension. + + The `benchmark` gem will become bundled in Ruby 3.5 + + *Earlopain* + +* `ActiveSupport::TimeWithZone#inspect` now uses ISO 8601 style time like `Time#inspect` + + *John Hawthorn* + +* `ActiveSupport::ErrorReporter#report` now assigns a backtrace to unraised exceptions. + + Previously reporting an un-raised exception would result in an error report without + a backtrace. Now it automatically generates one. + + *Jean Boussier* + +* Add `escape_html_entities` option to `ActiveSupport::JSON.encode`. + + This allows for overriding the global configuration found at + `ActiveSupport.escape_html_entities_in_json` for specific calls to `to_json`. + + This should be usable from controllers in the following manner: + ```ruby + class MyController < ApplicationController + def index + render json: { hello: "world" }, escape_html_entities: false + end + end + ``` + + *Nigel Baillie* + +* Raise when using key which can't respond to `#to_sym` in `EncryptedConfiguration`. + + As is the case when trying to use an Integer or Float as a key, which is unsupported. + + *zzak* + +* Deprecate addition and since between two `Time` and `ActiveSupport::TimeWithZone`. + + Previously adding time instances together such as `10.days.ago + 10.days.ago` or `10.days.ago.since(10.days.ago)` produced a nonsensical future date. This behavior is deprecated and will be removed in Rails 8.1. + + *Nick Schwaderer* + +* Support rfc2822 format for Time#to_fs & Date#to_fs. + + *Akshay Birajdar* + +* Optimize load time for `Railtie#initialize_i18n`. Filter `I18n.load_path`s passed to the file watcher to only those + under `Rails.root`. Previously the watcher would grab all available locales, including those in gems + which do not require a watcher because they won't change. + + *Nick Schwaderer* + +* Add a `filter` option to `in_order_of` to prioritize certain values in the sorting without filtering the results + by these values. + + *Igor Depolli* + +* Improve error message when using `assert_difference` or `assert_changes` with a + proc by printing the proc's source code (MRI only). + + *Richard Böhme*, *Jean Boussier* + +* Add a new configuration value `:zone` for `ActiveSupport.to_time_preserves_timezone` and rename the previous `true` value to `:offset`. The new default value is `:zone`. + + *Jason Kim*, *John Hawthorn* + +* Align instrumentation `payload[:key]` in ActiveSupport::Cache to follow the same pattern, with namespaced and normalized keys. + + *Frederik Erbs Spang Thomsen* + +* Fix `travel_to` to set usec 0 when `with_usec` is `false` and the given argument String or DateTime. + + *mopp* + +Please check [7-2-stable](https://github.com/rails/rails/blob/7-2-stable/activesupport/CHANGELOG.md) for previous changes. diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/MIT-LICENSE b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/MIT-LICENSE new file mode 100644 index 00000000..f12cfa76 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright (c) David Heinemeier Hansson + +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 AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/README.rdoc b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/README.rdoc new file mode 100644 index 00000000..04e1f778 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/README.rdoc @@ -0,0 +1,40 @@ += Active Support -- Utility classes and Ruby extensions from \Rails + +Active Support is a collection of utility classes and standard library +extensions that were found useful for the \Rails framework. These additions +reside in this package so they can be loaded as needed in Ruby projects +outside of \Rails. + +You can read more about the extensions in the {Active Support Core Extensions}[https://guides.rubyonrails.org/active_support_core_extensions.html] guide. + +== Download and installation + +The latest version of Active Support can be installed with RubyGems: + + $ gem install activesupport + +Source code can be downloaded as part of the \Rails project on GitHub: + +* https://github.com/rails/rails/tree/main/activesupport + + +== License + +Active Support is released under the MIT license: + +* https://opensource.org/licenses/MIT + + +== Support + +API documentation is at: + +* https://api.rubyonrails.org + +Bug reports for the Ruby on \Rails project can be filed here: + +* https://github.com/rails/rails/issues + +Feature requests should be discussed on the rails-core mailing list here: + +* https://discuss.rubyonrails.org/c/rubyonrails-core diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support.rb new file mode 100644 index 00000000..fd729135 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support.rb @@ -0,0 +1,143 @@ +# frozen_string_literal: true + +#-- +# Copyright (c) David Heinemeier Hansson +# +# 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 AUTHORS OR COPYRIGHT HOLDERS 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. +#++ + +require "securerandom" +require "active_support/dependencies/autoload" +require "active_support/version" +require "active_support/deprecator" +require "active_support/logger" +require "active_support/broadcast_logger" +require "active_support/lazy_load_hooks" +require "active_support/core_ext/date_and_time/compatibility" + +# :include: ../README.rdoc +module ActiveSupport + extend ActiveSupport::Autoload + + autoload :Concern + autoload :CodeGenerator + autoload :ActionableError + autoload :ConfigurationFile + autoload :CurrentAttributes + autoload :Dependencies + autoload :DescendantsTracker + autoload :ExecutionWrapper + autoload :Executor + autoload :ErrorReporter + autoload :FileUpdateChecker + autoload :EventedFileUpdateChecker + autoload :ForkTracker + autoload :LogSubscriber + autoload :IsolatedExecutionState + autoload :Notifications + autoload :Reloader + autoload :SecureCompareRotator + + eager_autoload do + autoload :BacktraceCleaner + autoload :Benchmark + autoload :Benchmarkable + autoload :Cache + autoload :Callbacks + autoload :Configurable + autoload :ClassAttribute + autoload :Deprecation + autoload :Delegation + autoload :Digest + autoload :ExecutionContext + autoload :Gzip + autoload :Inflector + autoload :JSON + autoload :KeyGenerator + autoload :MessageEncryptor + autoload :MessageEncryptors + autoload :MessageVerifier + autoload :MessageVerifiers + autoload :Multibyte + autoload :NumberHelper + autoload :OptionMerger + autoload :OrderedHash + autoload :OrderedOptions + autoload :StringInquirer + autoload :EnvironmentInquirer + autoload :TaggedLogging + autoload :XmlMini + autoload :ArrayInquirer + end + + autoload :Rescuable + autoload :SafeBuffer, "active_support/core_ext/string/output_safety" + autoload :TestCase + + def self.eager_load! + super + + NumberHelper.eager_load! + end + + cattr_accessor :test_order # :nodoc: + cattr_accessor :test_parallelization_threshold, default: 50 # :nodoc: + + @error_reporter = ActiveSupport::ErrorReporter.new + singleton_class.attr_accessor :error_reporter # :nodoc: + + def self.cache_format_version + Cache.format_version + end + + def self.cache_format_version=(value) + Cache.format_version = value + end + + def self.to_time_preserves_timezone + DateAndTime::Compatibility.preserve_timezone + end + + def self.to_time_preserves_timezone=(value) + if !value + ActiveSupport.deprecator.warn( + "`to_time` will always preserve the receiver timezone rather than system local time in Rails 8.1. " \ + "To opt in to the new behavior, set `config.active_support.to_time_preserves_timezone = :zone`." + ) + elsif value != :zone + ActiveSupport.deprecator.warn( + "`to_time` will always preserve the full timezone rather than offset of the receiver in Rails 8.1. " \ + "To opt in to the new behavior, set `config.active_support.to_time_preserves_timezone = :zone`." + ) + end + + DateAndTime::Compatibility.preserve_timezone = value + end + + def self.utc_to_local_returns_utc_offset_times + DateAndTime::Compatibility.utc_to_local_returns_utc_offset_times + end + + def self.utc_to_local_returns_utc_offset_times=(value) + DateAndTime::Compatibility.utc_to_local_returns_utc_offset_times = value + end +end + +autoload :I18n, "active_support/i18n" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/actionable_error.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/actionable_error.rb new file mode 100644 index 00000000..8c05e563 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/actionable_error.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +module ActiveSupport + # = Actionable Errors + # + # Actionable errors lets you define actions to resolve an error. + # + # To make an error actionable, include the +ActiveSupport::ActionableError+ + # module and invoke the +action+ class macro to define the action. An action + # needs a name and a block to execute. + module ActionableError + extend Concern + + class NonActionable < StandardError; end + + included do + class_attribute :_actions, default: {} + end + + def self.actions(error) # :nodoc: + case error + when ActionableError, -> it { Class === it && it < ActionableError } + error._actions + else + {} + end + end + + def self.dispatch(error, name) # :nodoc: + actions(error).fetch(name).call + rescue KeyError + raise NonActionable, "Cannot find action \"#{name}\"" + end + + module ClassMethods + # Defines an action that can resolve the error. + # + # class PendingMigrationError < MigrationError + # include ActiveSupport::ActionableError + # + # action "Run pending migrations" do + # ActiveRecord::Tasks::DatabaseTasks.migrate + # end + # end + def action(name, &block) + _actions[name] = block + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/all.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/all.rb new file mode 100644 index 00000000..4adf446a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/all.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +require "active_support" +require "active_support/time" +require "active_support/core_ext" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/array_inquirer.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/array_inquirer.rb new file mode 100644 index 00000000..6fb62085 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/array_inquirer.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +module ActiveSupport + # = \Array Inquirer + # + # Wrapping an array in an +ArrayInquirer+ gives a friendlier way to check + # its string-like contents: + # + # variants = ActiveSupport::ArrayInquirer.new([:phone, :tablet]) + # + # variants.phone? # => true + # variants.tablet? # => true + # variants.desktop? # => false + class ArrayInquirer < Array + # Passes each element of +candidates+ collection to ArrayInquirer collection. + # The method returns true if any element from the ArrayInquirer collection + # is equal to the stringified or symbolized form of any element in the +candidates+ collection. + # + # If +candidates+ collection is not given, method returns true. + # + # variants = ActiveSupport::ArrayInquirer.new([:phone, :tablet]) + # + # variants.any? # => true + # variants.any?(:phone, :tablet) # => true + # variants.any?('phone', 'desktop') # => true + # variants.any?(:desktop, :watch) # => false + def any?(*candidates) + if candidates.none? + super + else + candidates.any? do |candidate| + include?(candidate.to_sym) || include?(candidate.to_s) + end + end + end + + private + def respond_to_missing?(name, include_private = false) + name.end_with?("?") || super + end + + def method_missing(name, ...) + if name.end_with?("?") + any?(name[0..-2]) + else + super + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/backtrace_cleaner.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/backtrace_cleaner.rb new file mode 100644 index 00000000..0b9ec346 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/backtrace_cleaner.rb @@ -0,0 +1,163 @@ +# frozen_string_literal: true + +module ActiveSupport + # = Backtrace Cleaner + # + # Backtraces often include many lines that are not relevant for the context + # under review. This makes it hard to find the signal amongst the backtrace + # noise, and adds debugging time. With a BacktraceCleaner, filters and + # silencers are used to remove the noisy lines, so that only the most relevant + # lines remain. + # + # Filters are used to modify lines of data, while silencers are used to remove + # lines entirely. The typical filter use case is to remove lengthy path + # information from the start of each line, and view file paths relevant to the + # app directory instead of the file system root. The typical silencer use case + # is to exclude the output of a noisy library from the backtrace, so that you + # can focus on the rest. + # + # bc = ActiveSupport::BacktraceCleaner.new + # root = "#{Rails.root}/" + # bc.add_filter { |line| line.delete_prefix(root) } # strip the Rails.root prefix + # bc.add_silencer { |line| /puma|rubygems/.match?(line) } # skip any lines from puma or rubygems + # bc.clean(exception.backtrace) # perform the cleanup + # + # To reconfigure an existing BacktraceCleaner (like the default one in \Rails) + # and show as much data as possible, you can always call + # BacktraceCleaner#remove_silencers!, which will restore the + # backtrace to a pristine state. If you need to reconfigure an existing + # BacktraceCleaner so that it does not filter or modify the paths of any lines + # of the backtrace, you can call BacktraceCleaner#remove_filters! + # These two methods will give you a completely untouched backtrace. + # + # Inspired by the Quiet Backtrace gem by thoughtbot. + class BacktraceCleaner + def initialize + @filters, @silencers = [], [] + add_core_silencer + add_gem_filter + add_gem_silencer + add_stdlib_silencer + end + + # Returns the backtrace after all filters and silencers have been run + # against it. Filters run first, then silencers. + def clean(backtrace, kind = :silent) + filtered = filter_backtrace(backtrace) + + case kind + when :silent + silence(filtered) + when :noise + noise(filtered) + else + filtered + end + end + alias :filter :clean + + # Returns the frame with all filters applied. + # returns +nil+ if the frame was silenced. + def clean_frame(frame, kind = :silent) + frame = frame.to_s + @filters.each do |f| + frame = f.call(frame.to_s) + end + + case kind + when :silent + frame unless @silencers.any? { |s| s.call(frame) } + when :noise + frame if @silencers.any? { |s| s.call(frame) } + else + frame + end + end + + # Adds a filter from the block provided. Each line in the backtrace will be + # mapped against this filter. + # + # # Will turn "/my/rails/root/app/models/person.rb" into "app/models/person.rb" + # root = "#{Rails.root}/" + # backtrace_cleaner.add_filter { |line| line.delete_prefix(root) } + def add_filter(&block) + @filters << block + end + + # Adds a silencer from the block provided. If the silencer returns +true+ + # for a given line, it will be excluded from the clean backtrace. + # + # # Will reject all lines that include the word "puma", like "/gems/puma/server.rb" or "/app/my_puma_server/rb" + # backtrace_cleaner.add_silencer { |line| /puma/.match?(line) } + def add_silencer(&block) + @silencers << block + end + + # Removes all silencers, but leaves in the filters. Useful if your + # context of debugging suddenly expands as you suspect a bug in one of + # the libraries you use. + def remove_silencers! + @silencers = [] + end + + # Removes all filters, but leaves in the silencers. Useful if you suddenly + # need to see entire filepaths in the backtrace that you had already + # filtered out. + def remove_filters! + @filters = [] + end + + private + FORMATTED_GEMS_PATTERN = /\A[^\/]+ \([\w.]+\) / + + def initialize_copy(_other) + @filters = @filters.dup + @silencers = @silencers.dup + end + + def add_gem_filter + gems_paths = (Gem.path | [Gem.default_dir]).map { |p| Regexp.escape(p) } + return if gems_paths.empty? + + gems_regexp = %r{\A(#{gems_paths.join('|')})/(bundler/)?gems/([^/]+)-([\w.]+)/(.*)} + gems_result = '\3 (\4) \5' + add_filter { |line| line.sub(gems_regexp, gems_result) } + end + + def add_core_silencer + add_silencer { |line| line.include?(" 0.10007 + # + # ActiveSupport::Benchmark.realtime(:float_millisecond) { sleep 0.1 } + # # => 100.07 + # + # `unit` can be any of the values accepted by Ruby's `Process.clock_gettime`. + def self.realtime(unit = :float_second, &block) + time_start = Process.clock_gettime(Process::CLOCK_MONOTONIC, unit) + yield + Process.clock_gettime(Process::CLOCK_MONOTONIC, unit) - time_start + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/benchmarkable.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/benchmarkable.rb new file mode 100644 index 00000000..8697e7c4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/benchmarkable.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +require "active_support/core_ext/hash/keys" + +module ActiveSupport + # = \Benchmarkable + module Benchmarkable + # Allows you to measure the execution time of a block in a template and + # records the result to the log. Wrap this block around expensive operations + # or possible bottlenecks to get a time reading for the operation. For + # example, let's say you thought your file processing method was taking too + # long; you could wrap it in a benchmark block. + # + # <% benchmark 'Process data files' do %> + # <%= expensive_files_operation %> + # <% end %> + # + # That would add something like "Process data files (345.2ms)" to the log, + # which you can then use to compare timings when optimizing your code. + # + # You may give an optional logger level (:debug, :info, + # :warn, :error) as the :level option. The + # default logger level value is :info. + # + # <% benchmark 'Low-level files', level: :debug do %> + # <%= lowlevel_files_operation %> + # <% end %> + # + # Finally, you can pass true as the third argument to silence all log + # activity (other than the timing information) from inside the block. This + # is great for boiling down a noisy block to just a single statement that + # produces one log line: + # + # <% benchmark 'Process data files', level: :info, silence: true do %> + # <%= expensive_and_chatty_files_operation %> + # <% end %> + def benchmark(message = "Benchmarking", options = {}, &block) + if logger + options.assert_valid_keys(:level, :silence) + options[:level] ||= :info + + result = nil + ms = ActiveSupport::Benchmark.realtime(:float_millisecond) do + result = options[:silence] ? logger.silence(&block) : yield + end + logger.public_send(options[:level], "%s (%.1fms)" % [ message, ms ]) + result + else + yield + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/broadcast_logger.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/broadcast_logger.rb new file mode 100644 index 00000000..ae3db205 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/broadcast_logger.rb @@ -0,0 +1,251 @@ +# frozen_string_literal: true + +module ActiveSupport + # = Active Support Broadcast Logger + # + # The Broadcast logger is a logger used to write messages to multiple IO. It is commonly used + # in development to display messages on STDOUT and also write them to a file (development.log). + # With the Broadcast logger, you can broadcast your logs to a unlimited number of sinks. + # + # The BroadcastLogger acts as a standard logger and all methods you are used to are available. + # However, all the methods on this logger will propagate and be delegated to the other loggers + # that are part of the broadcast. + # + # Broadcasting your logs. + # + # stdout_logger = Logger.new(STDOUT) + # file_logger = Logger.new("development.log") + # broadcast = BroadcastLogger.new(stdout_logger, file_logger) + # + # broadcast.info("Hello world!") # Writes the log to STDOUT and the development.log file. + # + # Add a logger to the broadcast. + # + # stdout_logger = Logger.new(STDOUT) + # broadcast = BroadcastLogger.new(stdout_logger) + # file_logger = Logger.new("development.log") + # broadcast.broadcast_to(file_logger) + # + # broadcast.info("Hello world!") # Writes the log to STDOUT and the development.log file. + # + # Modifying the log level for all broadcasted loggers. + # + # stdout_logger = Logger.new(STDOUT) + # file_logger = Logger.new("development.log") + # broadcast = BroadcastLogger.new(stdout_logger, file_logger) + # + # broadcast.level = Logger::FATAL # Modify the log level for the whole broadcast. + # + # Stop broadcasting log to a sink. + # + # stdout_logger = Logger.new(STDOUT) + # file_logger = Logger.new("development.log") + # broadcast = BroadcastLogger.new(stdout_logger, file_logger) + # broadcast.info("Hello world!") # Writes the log to STDOUT and the development.log file. + # + # broadcast.stop_broadcasting_to(file_logger) + # broadcast.info("Hello world!") # Writes the log *only* to STDOUT. + # + # At least one sink has to be part of the broadcast. Otherwise, your logs will not + # be written anywhere. For instance: + # + # broadcast = BroadcastLogger.new + # broadcast.info("Hello world") # The log message will appear nowhere. + # + # If you are adding a custom logger with custom methods to the broadcast, + # the `BroadcastLogger` will proxy them and return the raw value, or an array + # of raw values, depending on how many loggers in the broadcasts responded to + # the method: + # + # class MyLogger < ::Logger + # def loggable? + # true + # end + # end + # + # logger = BroadcastLogger.new + # logger.loggable? # => A NoMethodError exception is raised because no loggers in the broadcasts could respond. + # + # logger.broadcast_to(MyLogger.new(STDOUT)) + # logger.loggable? # => true + # logger.broadcast_to(MyLogger.new(STDOUT)) + # puts logger.broadcasts # => [MyLogger, MyLogger] + # logger.loggable? # [true, true] + class BroadcastLogger + include ActiveSupport::LoggerSilence + + # Returns all the logger that are part of this broadcast. + attr_reader :broadcasts + attr_reader :formatter + attr_accessor :progname + + def initialize(*loggers) + @broadcasts = [] + @progname = "Broadcast" + + broadcast_to(*loggers) + end + + # Add logger(s) to the broadcast. + # + # broadcast_logger = ActiveSupport::BroadcastLogger.new + # broadcast_logger.broadcast_to(Logger.new(STDOUT), Logger.new(STDERR)) + def broadcast_to(*loggers) + @broadcasts.concat(loggers) + end + + # Remove a logger from the broadcast. When a logger is removed, messages sent to + # the broadcast will no longer be written to its sink. + # + # sink = Logger.new(STDOUT) + # broadcast_logger = ActiveSupport::BroadcastLogger.new + # + # broadcast_logger.stop_broadcasting_to(sink) + def stop_broadcasting_to(logger) + @broadcasts.delete(logger) + end + + def level + @broadcasts.map(&:level).min + end + + def <<(message) + dispatch { |logger| logger.<<(message) } + end + + def add(...) + dispatch { |logger| logger.add(...) } + end + alias_method :log, :add + + def debug(...) + dispatch { |logger| logger.debug(...) } + end + + def info(...) + dispatch { |logger| logger.info(...) } + end + + def warn(...) + dispatch { |logger| logger.warn(...) } + end + + def error(...) + dispatch { |logger| logger.error(...) } + end + + def fatal(...) + dispatch { |logger| logger.fatal(...) } + end + + def unknown(...) + dispatch { |logger| logger.unknown(...) } + end + + def formatter=(formatter) + dispatch { |logger| logger.formatter = formatter } + + @formatter = formatter + end + + def level=(level) + dispatch { |logger| logger.level = level } + end + alias_method :sev_threshold=, :level= + + def local_level=(level) + dispatch do |logger| + logger.local_level = level if logger.respond_to?(:local_level=) + end + end + + def close + dispatch { |logger| logger.close } + end + + # True if the log level allows entries with severity +Logger::DEBUG+ to be written + # to at least one broadcast. False otherwise. + def debug? + @broadcasts.any? { |logger| logger.debug? } + end + + # Sets the log level to +Logger::DEBUG+ for the whole broadcast. + def debug! + dispatch { |logger| logger.debug! } + end + + # True if the log level allows entries with severity +Logger::INFO+ to be written + # to at least one broadcast. False otherwise. + def info? + @broadcasts.any? { |logger| logger.info? } + end + + # Sets the log level to +Logger::INFO+ for the whole broadcast. + def info! + dispatch { |logger| logger.info! } + end + + # True if the log level allows entries with severity +Logger::WARN+ to be written + # to at least one broadcast. False otherwise. + def warn? + @broadcasts.any? { |logger| logger.warn? } + end + + # Sets the log level to +Logger::WARN+ for the whole broadcast. + def warn! + dispatch { |logger| logger.warn! } + end + + # True if the log level allows entries with severity +Logger::ERROR+ to be written + # to at least one broadcast. False otherwise. + def error? + @broadcasts.any? { |logger| logger.error? } + end + + # Sets the log level to +Logger::ERROR+ for the whole broadcast. + def error! + dispatch { |logger| logger.error! } + end + + # True if the log level allows entries with severity +Logger::FATAL+ to be written + # to at least one broadcast. False otherwise. + def fatal? + @broadcasts.any? { |logger| logger.fatal? } + end + + # Sets the log level to +Logger::FATAL+ for the whole broadcast. + def fatal! + dispatch { |logger| logger.fatal! } + end + + def initialize_copy(other) + @broadcasts = [] + @progname = other.progname.dup + @formatter = other.formatter.dup + + broadcast_to(*other.broadcasts.map(&:dup)) + end + + private + def dispatch(&block) + @broadcasts.each { |logger| block.call(logger) } + true + end + + def method_missing(name, ...) + loggers = @broadcasts.select { |logger| logger.respond_to?(name) } + + if loggers.none? + super + elsif loggers.one? + loggers.first.send(name, ...) + else + loggers.map { |logger| logger.send(name, ...) } + end + end + + def respond_to_missing?(method, include_all) + @broadcasts.any? { |logger| logger.respond_to?(method, include_all) } + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/builder.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/builder.rb new file mode 100644 index 00000000..cd49ec6b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/builder.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +begin + require "builder" +rescue LoadError => e + warn "You don't have builder installed in your application. Please add it to your Gemfile and run bundle install" + raise e +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache.rb new file mode 100644 index 00000000..46b1c448 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache.rb @@ -0,0 +1,1106 @@ +# frozen_string_literal: true + +require "zlib" +require "active_support/core_ext/array/extract_options" +require "active_support/core_ext/enumerable" +require "active_support/core_ext/module/attribute_accessors" +require "active_support/core_ext/numeric/bytes" +require "active_support/core_ext/object/to_param" +require "active_support/core_ext/object/try" +require "active_support/core_ext/string/inflections" +require_relative "cache/coder" +require_relative "cache/entry" +require_relative "cache/serializer_with_fallback" + +module ActiveSupport + # See ActiveSupport::Cache::Store for documentation. + module Cache + autoload :FileStore, "active_support/cache/file_store" + autoload :MemoryStore, "active_support/cache/memory_store" + autoload :MemCacheStore, "active_support/cache/mem_cache_store" + autoload :NullStore, "active_support/cache/null_store" + autoload :RedisCacheStore, "active_support/cache/redis_cache_store" + + # These options mean something to all cache implementations. Individual cache + # implementations may support additional options. + UNIVERSAL_OPTIONS = [ + :coder, + :compress, + :compress_threshold, + :compressor, + :expire_in, + :expired_in, + :expires_in, + :namespace, + :race_condition_ttl, + :serializer, + :skip_nil, + ] + + # Mapping of canonical option names to aliases that a store will recognize. + OPTION_ALIASES = { + expires_in: [:expire_in, :expired_in] + }.freeze + + DEFAULT_COMPRESS_LIMIT = 1.kilobyte + + # Raised by coders when the cache entry can't be deserialized. + # This error is treated as a cache miss. + DeserializationError = Class.new(StandardError) + + module Strategy + autoload :LocalCache, "active_support/cache/strategy/local_cache" + end + + @format_version = 7.0 + + class << self + attr_accessor :format_version + + # Creates a new Store object according to the given options. + # + # If no arguments are passed to this method, then a new + # ActiveSupport::Cache::MemoryStore object will be returned. + # + # If you pass a Symbol as the first argument, then a corresponding cache + # store class under the ActiveSupport::Cache namespace will be created. + # For example: + # + # ActiveSupport::Cache.lookup_store(:memory_store) + # # => returns a new ActiveSupport::Cache::MemoryStore object + # + # ActiveSupport::Cache.lookup_store(:mem_cache_store) + # # => returns a new ActiveSupport::Cache::MemCacheStore object + # + # Any additional arguments will be passed to the corresponding cache store + # class's constructor: + # + # ActiveSupport::Cache.lookup_store(:file_store, '/tmp/cache') + # # => same as: ActiveSupport::Cache::FileStore.new('/tmp/cache') + # + # If the first argument is not a Symbol, then it will simply be returned: + # + # ActiveSupport::Cache.lookup_store(MyOwnCacheStore.new) + # # => returns MyOwnCacheStore.new + def lookup_store(store = nil, *parameters) + case store + when Symbol + options = parameters.extract_options! + retrieve_store_class(store).new(*parameters, **options) + when Array + lookup_store(*store) + when nil + ActiveSupport::Cache::MemoryStore.new + else + store + end + end + + # Expands out the +key+ argument into a key that can be used for the + # cache store. Optionally accepts a namespace, and all keys will be + # scoped within that namespace. + # + # If the +key+ argument provided is an array, or responds to +to_a+, then + # each of elements in the array will be turned into parameters/keys and + # concatenated into a single key. For example: + # + # ActiveSupport::Cache.expand_cache_key([:foo, :bar]) # => "foo/bar" + # ActiveSupport::Cache.expand_cache_key([:foo, :bar], "namespace") # => "namespace/foo/bar" + # + # The +key+ argument can also respond to +cache_key+ or +to_param+. + def expand_cache_key(key, namespace = nil) + expanded_cache_key = namespace ? +"#{namespace}/" : +"" + + if prefix = ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"] + expanded_cache_key << "#{prefix}/" + end + + expanded_cache_key << retrieve_cache_key(key) + expanded_cache_key + end + + private + def retrieve_cache_key(key) + case + when key.respond_to?(:cache_key_with_version) then key.cache_key_with_version + when key.respond_to?(:cache_key) then key.cache_key + when key.is_a?(Array) then key.map { |element| retrieve_cache_key(element) }.to_param + when key.respond_to?(:to_a) then retrieve_cache_key(key.to_a) + else key.to_param + end.to_s + end + + # Obtains the specified cache store class, given the name of the +store+. + # Raises an error when the store class cannot be found. + def retrieve_store_class(store) + # require_relative cannot be used here because the class might be + # provided by another gem, like redis-activesupport for example. + require "active_support/cache/#{store}" + rescue LoadError => e + raise "Could not find cache store adapter for #{store} (#{e})" + else + ActiveSupport::Cache.const_get(store.to_s.camelize) + end + end + + # = Active Support \Cache \Store + # + # An abstract cache store class. There are multiple cache store + # implementations, each having its own additional features. See the classes + # under the ActiveSupport::Cache module, e.g. + # ActiveSupport::Cache::MemCacheStore. MemCacheStore is currently the most + # popular cache store for large production websites. + # + # Some implementations may not support all methods beyond the basic cache + # methods of #fetch, #write, #read, #exist?, and #delete. + # + # +ActiveSupport::Cache::Store+ can store any Ruby object that is supported + # by its +coder+'s +dump+ and +load+ methods. + # + # cache = ActiveSupport::Cache::MemoryStore.new + # + # cache.read('city') # => nil + # cache.write('city', "Duckburgh") # => true + # cache.read('city') # => "Duckburgh" + # + # cache.write('not serializable', Proc.new {}) # => TypeError + # + # Keys are always translated into Strings and are case sensitive. When an + # object is specified as a key and has a +cache_key+ method defined, this + # method will be called to define the key. Otherwise, the +to_param+ + # method will be called. Hashes and Arrays can also be used as keys. The + # elements will be delimited by slashes, and the elements within a Hash + # will be sorted by key so they are consistent. + # + # cache.read('city') == cache.read(:city) # => true + # + # Nil values can be cached. + # + # If your cache is on a shared infrastructure, you can define a namespace + # for your cache entries. If a namespace is defined, it will be prefixed on + # to every key. The namespace can be either a static value or a Proc. If it + # is a Proc, it will be invoked when each key is evaluated so that you can + # use application logic to invalidate keys. + # + # cache.namespace = -> { @last_mod_time } # Set the namespace to a variable + # @last_mod_time = Time.now # Invalidate the entire cache by changing namespace + # + class Store + cattr_accessor :logger, instance_writer: true + cattr_accessor :raise_on_invalid_cache_expiration_time, default: false + + attr_reader :silence, :options + alias :silence? :silence + + class << self + private + DEFAULT_POOL_OPTIONS = { size: 5, timeout: 5 }.freeze + private_constant :DEFAULT_POOL_OPTIONS + + def retrieve_pool_options(options) + if options.key?(:pool) + pool_options = options.delete(:pool) + else + pool_options = true + end + + case pool_options + when false, nil + return false + when true + pool_options = DEFAULT_POOL_OPTIONS + when Hash + pool_options[:size] = Integer(pool_options[:size]) if pool_options.key?(:size) + pool_options[:timeout] = Float(pool_options[:timeout]) if pool_options.key?(:timeout) + pool_options = DEFAULT_POOL_OPTIONS.merge(pool_options) + else + raise TypeError, "Invalid :pool argument, expected Hash, got: #{pool_options.inspect}" + end + + pool_options unless pool_options.empty? + end + end + + # Creates a new cache. + # + # ==== Options + # + # [+:namespace+] + # Sets the namespace for the cache. This option is especially useful if + # your application shares a cache with other applications. + # + # [+:serializer+] + # The serializer for cached values. Must respond to +dump+ and +load+. + # + # The default serializer depends on the cache format version (set via + # +config.active_support.cache_format_version+ when using Rails). The + # default serializer for each format version includes a fallback + # mechanism to deserialize values from any format version. This behavior + # makes it easy to migrate between format versions without invalidating + # the entire cache. + # + # You can also specify serializer: :message_pack to use a + # preconfigured serializer based on ActiveSupport::MessagePack. The + # +:message_pack+ serializer includes the same deserialization fallback + # mechanism, allowing easy migration from (or to) the default + # serializer. The +:message_pack+ serializer may improve performance, + # but it requires the +msgpack+ gem. + # + # [+:compressor+] + # The compressor for serialized cache values. Must respond to +deflate+ + # and +inflate+. + # + # The default compressor is +Zlib+. To define a new custom compressor + # that also decompresses old cache entries, you can check compressed + # values for Zlib's "\x78" signature: + # + # module MyCompressor + # def self.deflate(dumped) + # # compression logic... (make sure result does not start with "\x78"!) + # end + # + # def self.inflate(compressed) + # if compressed.start_with?("\x78") + # Zlib.inflate(compressed) + # else + # # decompression logic... + # end + # end + # end + # + # ActiveSupport::Cache.lookup_store(:redis_cache_store, compressor: MyCompressor) + # + # [+:coder+] + # The coder for serializing and (optionally) compressing cache entries. + # Must respond to +dump+ and +load+. + # + # The default coder composes the serializer and compressor, and includes + # some performance optimizations. If you only need to override the + # serializer or compressor, you should specify the +:serializer+ or + # +:compressor+ options instead. + # + # If the store can handle cache entries directly, you may also specify + # coder: nil to omit the serializer, compressor, and coder. For + # example, if you are using ActiveSupport::Cache::MemoryStore and can + # guarantee that cache values will not be mutated, you can specify + # coder: nil to avoid the overhead of safeguarding against + # mutation. + # + # The +:coder+ option is mutually exclusive with the +:serializer+ and + # +:compressor+ options. Specifying them together will raise an + # +ArgumentError+. + # + # Any other specified options are treated as default options for the + # relevant cache operations, such as #read, #write, and #fetch. + def initialize(options = nil) + @options = options ? validate_options(normalize_options(options)) : {} + + @options[:compress] = true unless @options.key?(:compress) + @options[:compress_threshold] ||= DEFAULT_COMPRESS_LIMIT + + @coder = @options.delete(:coder) do + legacy_serializer = Cache.format_version < 7.1 && !@options[:serializer] + serializer = @options.delete(:serializer) || default_serializer + serializer = Cache::SerializerWithFallback[serializer] if serializer.is_a?(Symbol) + compressor = @options.delete(:compressor) { Zlib } + + Cache::Coder.new(serializer, compressor, legacy_serializer: legacy_serializer) + end + + @coder ||= Cache::SerializerWithFallback[:passthrough] + + @coder_supports_compression = @coder.respond_to?(:dump_compressed) + end + + # Silences the logger. + def silence! + @silence = true + self + end + + # Silences the logger within a block. + def mute + previous_silence, @silence = @silence, true + yield + ensure + @silence = previous_silence + end + + # Fetches data from the cache, using the given key. If there is data in + # the cache with the given key, then that data is returned. + # + # If there is no such data in the cache (a cache miss), then +nil+ will be + # returned. However, if a block has been passed, that block will be passed + # the key and executed in the event of a cache miss. The return value of the + # block will be written to the cache under the given cache key, and that + # return value will be returned. + # + # cache.write('today', 'Monday') + # cache.fetch('today') # => "Monday" + # + # cache.fetch('city') # => nil + # cache.fetch('city') do + # 'Duckburgh' + # end + # cache.fetch('city') # => "Duckburgh" + # + # ==== Options + # + # Internally, +fetch+ calls +read_entry+, and calls +write_entry+ on a + # cache miss. Thus, +fetch+ supports the same options as #read and #write. + # Additionally, +fetch+ supports the following options: + # + # * force: true - Forces a cache "miss," meaning we treat the + # cache value as missing even if it's present. Passing a block is + # required when +force+ is true so this always results in a cache write. + # + # cache.write('today', 'Monday') + # cache.fetch('today', force: true) { 'Tuesday' } # => 'Tuesday' + # cache.fetch('today', force: true) # => ArgumentError + # + # The +:force+ option is useful when you're calling some other method to + # ask whether you should force a cache write. Otherwise, it's clearer to + # just call +write+. + # + # * skip_nil: true - Prevents caching a nil result: + # + # cache.fetch('foo') { nil } + # cache.fetch('bar', skip_nil: true) { nil } + # cache.exist?('foo') # => true + # cache.exist?('bar') # => false + # + # * +:race_condition_ttl+ - Specifies the number of seconds during which + # an expired value can be reused while a new value is being generated. + # This can be used to prevent race conditions when cache entries expire, + # by preventing multiple processes from simultaneously regenerating the + # same entry (also known as the dog pile effect). + # + # When a process encounters a cache entry that has expired less than + # +:race_condition_ttl+ seconds ago, it will bump the expiration time by + # +:race_condition_ttl+ seconds before generating a new value. During + # this extended time window, while the process generates a new value, + # other processes will continue to use the old value. After the first + # process writes the new value, other processes will then use it. + # + # If the first process errors out while generating a new value, another + # process can try to generate a new value after the extended time window + # has elapsed. + # + # # Set all values to expire after one second. + # cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 1) + # + # cache.write("foo", "original value") + # val_1 = nil + # val_2 = nil + # p cache.read("foo") # => "original value" + # + # sleep 1 # wait until the cache expires + # + # t1 = Thread.new do + # # fetch does the following: + # # 1. gets an recent expired entry + # # 2. extends the expiry by 2 seconds (race_condition_ttl) + # # 3. regenerates the new value + # val_1 = cache.fetch("foo", race_condition_ttl: 2) do + # sleep 1 + # "new value 1" + # end + # end + # + # # Wait until t1 extends the expiry of the entry + # # but before generating the new value + # sleep 0.1 + # + # val_2 = cache.fetch("foo", race_condition_ttl: 2) do + # # This block won't be executed because t1 extended the expiry + # "new value 2" + # end + # + # t1.join + # + # p val_1 # => "new value 1" + # p val_2 # => "original value" + # p cache.fetch("foo") # => "new value 1" + # + # # The entry requires 3 seconds to expire (expires_in + race_condition_ttl) + # # We have waited 2 seconds already (sleep(1) + t1.join) thus we need to wait 1 + # # more second to see the entry expire. + # sleep 1 + # + # p cache.fetch("foo") # => nil + # + # ==== Dynamic Options + # + # In some cases it may be necessary to dynamically compute options based + # on the cached value. To support this, an ActiveSupport::Cache::WriteOptions + # instance is passed as the second argument to the block. For example: + # + # cache.fetch("authentication-token:#{user.id}") do |key, options| + # token = authenticate_to_service + # options.expires_at = token.expires_at + # token + # end + # + def fetch(name, options = nil, &block) + if block_given? + options = merged_options(options) + key = normalize_key(name, options) + + entry = nil + unless options[:force] + instrument(:read, key, options) do |payload| + cached_entry = read_entry(key, **options, event: payload) + entry = handle_expired_entry(cached_entry, key, options) + if entry + if entry.mismatched?(normalize_version(name, options)) + entry = nil + else + begin + entry.value + rescue DeserializationError + entry = nil + end + end + end + payload[:super_operation] = :fetch if payload + payload[:hit] = !!entry if payload + end + end + + if entry + get_entry_value(entry, name, options) + else + save_block_result_to_cache(name, key, options, &block) + end + elsif options && options[:force] + raise ArgumentError, "Missing block: Calling `Cache#fetch` with `force: true` requires a block." + else + read(name, options) + end + end + + # Reads data from the cache, using the given key. If there is data in + # the cache with the given key, then that data is returned. Otherwise, + # +nil+ is returned. + # + # Note, if data was written with the :expires_in or + # :version options, both of these conditions are applied before + # the data is returned. + # + # ==== Options + # + # * +:namespace+ - Replace the store namespace for this call. + # * +:version+ - Specifies a version for the cache entry. If the cached + # version does not match the requested version, the read will be treated + # as a cache miss. This feature is used to support recyclable cache keys. + # + # Other options will be handled by the specific cache store implementation. + def read(name, options = nil) + options = merged_options(options) + key = normalize_key(name, options) + version = normalize_version(name, options) + + instrument(:read, key, options) do |payload| + entry = read_entry(key, **options, event: payload) + + if entry + if entry.expired? + delete_entry(key, **options) + payload[:hit] = false if payload + nil + elsif entry.mismatched?(version) + payload[:hit] = false if payload + nil + else + payload[:hit] = true if payload + begin + entry.value + rescue DeserializationError + payload[:hit] = false + nil + end + end + else + payload[:hit] = false if payload + nil + end + end + end + + # Reads multiple values at once from the cache. Options can be passed + # in the last argument. + # + # Some cache implementation may optimize this method. + # + # Returns a hash mapping the names provided to the values found. + def read_multi(*names) + return {} if names.empty? + + options = names.extract_options! + options = merged_options(options) + keys = names.map { |name| normalize_key(name, options) } + + instrument_multi :read_multi, keys, options do |payload| + read_multi_entries(names, **options, event: payload).tap do |results| + payload[:hits] = results.keys.map { |name| normalize_key(name, options) } + end + end + end + + # Cache Storage API to write multiple values at once. + def write_multi(hash, options = nil) + return hash if hash.empty? + + options = merged_options(options) + normalized_hash = hash.transform_keys { |key| normalize_key(key, options) } + + instrument_multi :write_multi, normalized_hash, options do |payload| + entries = hash.each_with_object({}) do |(name, value), memo| + memo[normalize_key(name, options)] = Entry.new(value, **options.merge(version: normalize_version(name, options))) + end + + write_multi_entries entries, **options + end + end + + # Fetches data from the cache, using the given keys. If there is data in + # the cache with the given keys, then that data is returned. Otherwise, + # the supplied block is called for each key for which there was no data, + # and the result will be written to the cache and returned. + # Therefore, you need to pass a block that returns the data to be written + # to the cache. If you do not want to write the cache when the cache is + # not found, use #read_multi. + # + # Returns a hash with the data for each of the names. For example: + # + # cache.write("bim", "bam") + # cache.fetch_multi("bim", "unknown_key") do |key| + # "Fallback value for key: #{key}" + # end + # # => { "bim" => "bam", + # # "unknown_key" => "Fallback value for key: unknown_key" } + # + # You may also specify additional options via the +options+ argument. See #fetch for details. + # Other options are passed to the underlying cache implementation. For example: + # + # cache.fetch_multi("fizz", expires_in: 5.seconds) do |key| + # "buzz" + # end + # # => {"fizz"=>"buzz"} + # cache.read("fizz") + # # => "buzz" + # sleep(6) + # cache.read("fizz") + # # => nil + def fetch_multi(*names) + raise ArgumentError, "Missing block: `Cache#fetch_multi` requires a block." unless block_given? + return {} if names.empty? + + options = names.extract_options! + options = merged_options(options) + keys = names.map { |name| normalize_key(name, options) } + writes = {} + ordered = instrument_multi :read_multi, keys, options do |payload| + if options[:force] + reads = {} + else + reads = read_multi_entries(names, **options) + end + + ordered = names.index_with do |name| + reads.fetch(name) { writes[name] = yield(name) } + end + writes.compact! if options[:skip_nil] + + payload[:hits] = reads.keys.map { |name| normalize_key(name, options) } + payload[:super_operation] = :fetch_multi + + ordered + end + + write_multi(writes, options) + + ordered + end + + # Writes the value to the cache with the key. The value must be supported + # by the +coder+'s +dump+ and +load+ methods. + # + # Returns +true+ if the write succeeded, +nil+ if there was an error talking + # to the cache backend, or +false+ if the write failed for another reason. + # + # By default, cache entries larger than 1kB are compressed. Compression + # allows more data to be stored in the same memory footprint, leading to + # fewer cache evictions and higher hit rates. + # + # ==== Options + # + # * compress: false - Disables compression of the cache entry. + # + # * +:compress_threshold+ - The compression threshold, specified in bytes. + # \Cache entries larger than this threshold will be compressed. Defaults + # to +1.kilobyte+. + # + # * +:expires_in+ - Sets a relative expiration time for the cache entry, + # specified in seconds. +:expire_in+ and +:expired_in+ are aliases for + # +:expires_in+. + # + # cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 5.minutes) + # cache.write(key, value, expires_in: 1.minute) # Set a lower value for one entry + # + # * +:expires_at+ - Sets an absolute expiration time for the cache entry. + # + # cache = ActiveSupport::Cache::MemoryStore.new + # cache.write(key, value, expires_at: Time.now.at_end_of_hour) + # + # * +:version+ - Specifies a version for the cache entry. When reading + # from the cache, if the cached version does not match the requested + # version, the read will be treated as a cache miss. This feature is + # used to support recyclable cache keys. + # + # Other options will be handled by the specific cache store implementation. + def write(name, value, options = nil) + options = merged_options(options) + key = normalize_key(name, options) + + instrument(:write, key, options) do + entry = Entry.new(value, **options.merge(version: normalize_version(name, options))) + write_entry(key, entry, **options) + end + end + + # Deletes an entry in the cache. Returns +true+ if an entry is deleted + # and +false+ otherwise. + # + # Options are passed to the underlying cache implementation. + def delete(name, options = nil) + options = merged_options(options) + key = normalize_key(name, options) + + instrument(:delete, key, options) do + delete_entry(key, **options) + end + end + + # Deletes multiple entries in the cache. Returns the number of deleted + # entries. + # + # Options are passed to the underlying cache implementation. + def delete_multi(names, options = nil) + return 0 if names.empty? + + options = merged_options(options) + names.map! { |key| normalize_key(key, options) } + + instrument_multi(:delete_multi, names, options) do + delete_multi_entries(names, **options) + end + end + + # Returns +true+ if the cache contains an entry for the given key. + # + # Options are passed to the underlying cache implementation. + def exist?(name, options = nil) + options = merged_options(options) + key = normalize_key(name, options) + + instrument(:exist?, key) do |payload| + entry = read_entry(key, **options, event: payload) + (entry && !entry.expired? && !entry.mismatched?(normalize_version(name, options))) || false + end + end + + def new_entry(value, options = nil) # :nodoc: + Entry.new(value, **merged_options(options)) + end + + # Deletes all entries with keys matching the pattern. + # + # Options are passed to the underlying cache implementation. + # + # Some implementations may not support this method. + def delete_matched(matcher, options = nil) + raise NotImplementedError.new("#{self.class.name} does not support delete_matched") + end + + # Increments an integer value in the cache. + # + # Options are passed to the underlying cache implementation. + # + # Some implementations may not support this method. + def increment(name, amount = 1, options = nil) + raise NotImplementedError.new("#{self.class.name} does not support increment") + end + + # Decrements an integer value in the cache. + # + # Options are passed to the underlying cache implementation. + # + # Some implementations may not support this method. + def decrement(name, amount = 1, options = nil) + raise NotImplementedError.new("#{self.class.name} does not support decrement") + end + + # Cleans up the cache by removing expired entries. + # + # Options are passed to the underlying cache implementation. + # + # Some implementations may not support this method. + def cleanup(options = nil) + raise NotImplementedError.new("#{self.class.name} does not support cleanup") + end + + # Clears the entire cache. Be careful with this method since it could + # affect other processes if shared cache is being used. + # + # The options hash is passed to the underlying cache implementation. + # + # Some implementations may not support this method. + def clear(options = nil) + raise NotImplementedError.new("#{self.class.name} does not support clear") + end + + private + def default_serializer + case Cache.format_version + when 7.0 + Cache::SerializerWithFallback[:marshal_7_0] + when 7.1 + Cache::SerializerWithFallback[:marshal_7_1] + else + raise ArgumentError, "Unrecognized ActiveSupport::Cache.format_version: #{Cache.format_version.inspect}" + end + end + + # Adds the namespace defined in the options to a pattern designed to + # match keys. Implementations that support delete_matched should call + # this method to translate a pattern that matches names into one that + # matches namespaced keys. + def key_matcher(pattern, options) # :doc: + prefix = options[:namespace].is_a?(Proc) ? options[:namespace].call : options[:namespace] + if prefix + source = pattern.source + if source.start_with?("^") + source = source[1, source.length] + else + source = ".*#{source[0, source.length]}" + end + Regexp.new("^#{Regexp.escape(prefix)}:#{source}", pattern.options) + else + pattern + end + end + + # Reads an entry from the cache implementation. Subclasses must implement + # this method. + def read_entry(key, **options) + raise NotImplementedError.new + end + + # Writes an entry to the cache implementation. Subclasses must implement + # this method. + def write_entry(key, entry, **options) + raise NotImplementedError.new + end + + def serialize_entry(entry, **options) + options = merged_options(options) + if @coder_supports_compression && options[:compress] + @coder.dump_compressed(entry, options[:compress_threshold]) + else + @coder.dump(entry) + end + end + + def deserialize_entry(payload, **) + payload.nil? ? nil : @coder.load(payload) + rescue DeserializationError + nil + end + + # Reads multiple entries from the cache implementation. Subclasses MAY + # implement this method. + def read_multi_entries(names, **options) + names.each_with_object({}) do |name, results| + key = normalize_key(name, options) + entry = read_entry(key, **options) + + next unless entry + + version = normalize_version(name, options) + + if entry.expired? + delete_entry(key, **options) + elsif !entry.mismatched?(version) + results[name] = entry.value + end + end + end + + # Writes multiple entries to the cache implementation. Subclasses MAY + # implement this method. + def write_multi_entries(hash, **options) + hash.each do |key, entry| + write_entry key, entry, **options + end + end + + # Deletes an entry from the cache implementation. Subclasses must + # implement this method. + def delete_entry(key, **options) + raise NotImplementedError.new + end + + # Deletes multiples entries in the cache implementation. Subclasses MAY + # implement this method. + def delete_multi_entries(entries, **options) + entries.count { |key| delete_entry(key, **options) } + end + + # Merges the default options with ones specific to a method call. + def merged_options(call_options) + if call_options + call_options = normalize_options(call_options) + if call_options.key?(:expires_in) && call_options.key?(:expires_at) + raise ArgumentError, "Either :expires_in or :expires_at can be supplied, but not both" + end + + expires_at = call_options.delete(:expires_at) + call_options[:expires_in] = (expires_at - Time.now) if expires_at + + if call_options[:expires_in].is_a?(Time) + expires_in = call_options[:expires_in] + raise ArgumentError.new("expires_in parameter should not be a Time. Did you mean to use expires_at? Got: #{expires_in}") + end + if call_options[:expires_in]&.negative? + expires_in = call_options.delete(:expires_in) + handle_invalid_expires_in("Cache expiration time is invalid, cannot be negative: #{expires_in}") + end + + if options.empty? + call_options + else + options.merge(call_options) + end + else + options + end + end + + def handle_invalid_expires_in(message) + error = ArgumentError.new(message) + if ActiveSupport::Cache::Store.raise_on_invalid_cache_expiration_time + raise error + else + ActiveSupport.error_reporter&.report(error, handled: true, severity: :warning) + logger.error("#{error.class}: #{error.message}") if logger + end + end + + # Normalize aliased options to their canonical form + def normalize_options(options) + options = options.dup + OPTION_ALIASES.each do |canonical_name, aliases| + alias_key = aliases.detect { |key| options.key?(key) } + options[canonical_name] ||= options[alias_key] if alias_key + options.except!(*aliases) + end + + options + end + + def validate_options(options) + if options.key?(:coder) && options[:serializer] + raise ArgumentError, "Cannot specify :serializer and :coder options together" + end + + if options.key?(:coder) && options[:compressor] + raise ArgumentError, "Cannot specify :compressor and :coder options together" + end + + if Cache.format_version < 7.1 && !options[:serializer] && options[:compressor] + raise ArgumentError, "Cannot specify :compressor option when using" \ + " default serializer and cache format version is < 7.1" + end + + options + end + + # Expands and namespaces the cache key. + # Raises an exception when the key is +nil+ or an empty string. + # May be overridden by cache stores to do additional normalization. + def normalize_key(key, options = nil) + str_key = expanded_key(key) + raise(ArgumentError, "key cannot be blank") if !str_key || str_key.empty? + + namespace_key str_key, options + end + + # Prefix the key with a namespace string: + # + # namespace_key 'foo', namespace: 'cache' + # # => 'cache:foo' + # + # With a namespace block: + # + # namespace_key 'foo', namespace: -> { 'cache' } + # # => 'cache:foo' + def namespace_key(key, call_options = nil) + namespace = if call_options&.key?(:namespace) + call_options[:namespace] + else + options[:namespace] + end + + if namespace.respond_to?(:call) + namespace = namespace.call + end + + if key && key.encoding != Encoding::UTF_8 + key = key.dup.force_encoding(Encoding::UTF_8) + end + + if namespace + "#{namespace}:#{key}" + else + key + end + end + + # Expands key to be a consistent string value. Invokes +cache_key+ if + # object responds to +cache_key+. Otherwise, +to_param+ method will be + # called. If the key is a Hash, then keys will be sorted alphabetically. + def expanded_key(key) + return key.cache_key.to_s if key.respond_to?(:cache_key) + + case key + when Array + if key.size > 1 + key.collect { |element| expanded_key(element) } + else + expanded_key(key.first) + end + when Hash + key.collect { |k, v| "#{k}=#{v}" }.sort! + else + key + end.to_param + end + + def normalize_version(key, options = nil) + (options && options[:version].try(:to_param)) || expanded_version(key) + end + + def expanded_version(key) + case + when key.respond_to?(:cache_version) then key.cache_version.to_param + when key.is_a?(Array) then key.map { |element| expanded_version(element) }.tap(&:compact!).to_param + when key.respond_to?(:to_a) then expanded_version(key.to_a) + end + end + + def instrument(operation, key, options = nil, &block) + _instrument(operation, key: key, options: options, &block) + end + + def instrument_multi(operation, keys, options = nil, &block) + _instrument(operation, multi: true, key: keys, options: options, &block) + end + + def _instrument(operation, multi: false, options: nil, **payload, &block) + if logger && logger.debug? && !silence? + debug_key = + if multi + ": #{payload[:key].size} key(s) specified" + elsif payload[:key] + ": #{payload[:key]}" + end + + debug_options = " (#{options.inspect})" unless options.blank? + + logger.debug "Cache #{operation}#{debug_key}#{debug_options}" + end + + payload[:store] = self.class.name + payload.merge!(options) if options.is_a?(Hash) + ActiveSupport::Notifications.instrument("cache_#{operation}.active_support", payload) do + block&.call(payload) + end + end + + def handle_expired_entry(entry, key, options) + if entry && entry.expired? + race_ttl = options[:race_condition_ttl].to_i + if (race_ttl > 0) && (Time.now.to_f - entry.expires_at <= race_ttl) + # When an entry has a positive :race_condition_ttl defined, put the stale entry back into the cache + # for a brief period while the entry is being recalculated. + entry.expires_at = Time.now.to_f + race_ttl + write_entry(key, entry, **options, expires_in: race_ttl * 2) + else + delete_entry(key, **options) + end + entry = nil + end + entry + end + + def get_entry_value(entry, name, options) + instrument(:fetch_hit, name, options) + entry.value + end + + def save_block_result_to_cache(name, key, options) + options = options.dup + + result = instrument(:generate, key, options) do + yield(name, WriteOptions.new(options)) + end + + write(name, result, options) unless result.nil? && options[:skip_nil] + result + end + end + + # Enables the dynamic configuration of Cache entry options while ensuring + # that conflicting options are not both set. When a block is given to + # ActiveSupport::Cache::Store#fetch, the second argument will be an + # instance of +WriteOptions+. + class WriteOptions + def initialize(options) # :nodoc: + @options = options + end + + def version + @options[:version] + end + + def version=(version) + @options[:version] = version + end + + def expires_in + @options[:expires_in] + end + + # Sets the Cache entry's +expires_in+ value. If an +expires_at+ option was + # previously set, this will unset it since +expires_in+ and +expires_at+ + # cannot both be set. + def expires_in=(expires_in) + @options.delete(:expires_at) + @options[:expires_in] = expires_in + end + + def expires_at + @options[:expires_at] + end + + # Sets the Cache entry's +expires_at+ value. If an +expires_in+ option was + # previously set, this will unset it since +expires_at+ and +expires_in+ + # cannot both be set. + def expires_at=(expires_at) + @options.delete(:expires_in) + @options[:expires_at] = expires_at + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/coder.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/coder.rb new file mode 100644 index 00000000..b21d07dc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/coder.rb @@ -0,0 +1,153 @@ +# frozen_string_literal: true + +require_relative "entry" + +module ActiveSupport + module Cache + class Coder # :nodoc: + def initialize(serializer, compressor, legacy_serializer: false) + @serializer = serializer + @compressor = compressor + @legacy_serializer = legacy_serializer + end + + def dump(entry) + return @serializer.dump(entry) if @legacy_serializer + + dump_compressed(entry, Float::INFINITY) + end + + def dump_compressed(entry, threshold) + return @serializer.dump_compressed(entry, threshold) if @legacy_serializer + + # If value is a string with a supported encoding, use it as the payload + # instead of passing it through the serializer. + if type = type_for_string(entry.value) + payload = entry.value.b + else + type = OBJECT_DUMP_TYPE + payload = @serializer.dump(entry.value) + end + + if compressed = try_compress(payload, threshold) + payload = compressed + type = type | COMPRESSED_FLAG + end + + expires_at = entry.expires_at || -1.0 + + version = dump_version(entry.version) if entry.version + version_length = version&.bytesize || -1 + + packed = SIGNATURE.b + packed << [type, expires_at, version_length].pack(PACKED_TEMPLATE) + packed << version if version + packed << payload + end + + def load(dumped) + return @serializer.load(dumped) if !signature?(dumped) + + type = dumped.unpack1(PACKED_TYPE_TEMPLATE) + expires_at = dumped.unpack1(PACKED_EXPIRES_AT_TEMPLATE) + version_length = dumped.unpack1(PACKED_VERSION_LENGTH_TEMPLATE) + + expires_at = nil if expires_at < 0 + version = load_version(dumped.byteslice(PACKED_VERSION_INDEX, version_length)) if version_length >= 0 + payload = dumped.byteslice((PACKED_VERSION_INDEX + [version_length, 0].max)..) + + compressor = @compressor if type & COMPRESSED_FLAG > 0 + serializer = STRING_DESERIALIZERS[type & ~COMPRESSED_FLAG] || @serializer + + LazyEntry.new(serializer, compressor, payload, version: version, expires_at: expires_at) + end + + private + SIGNATURE = "\x00\x11".b.freeze + + OBJECT_DUMP_TYPE = 0x01 + + STRING_ENCODINGS = { + 0x02 => Encoding::UTF_8, + 0x03 => Encoding::BINARY, + 0x04 => Encoding::US_ASCII, + } + + COMPRESSED_FLAG = 0x80 + + PACKED_TEMPLATE = "CEl<" + PACKED_TYPE_TEMPLATE = "@#{SIGNATURE.bytesize}C" + PACKED_EXPIRES_AT_TEMPLATE = "@#{[0].pack(PACKED_TYPE_TEMPLATE).bytesize}E" + PACKED_VERSION_LENGTH_TEMPLATE = "@#{[0].pack(PACKED_EXPIRES_AT_TEMPLATE).bytesize}l<" + PACKED_VERSION_INDEX = [0].pack(PACKED_VERSION_LENGTH_TEMPLATE).bytesize + + MARSHAL_SIGNATURE = "\x04\x08".b.freeze + + class StringDeserializer + def initialize(encoding) + @encoding = encoding + end + + def load(payload) + payload.force_encoding(@encoding) + end + end + + STRING_DESERIALIZERS = STRING_ENCODINGS.transform_values { |encoding| StringDeserializer.new(encoding) } + + class LazyEntry < Cache::Entry + def initialize(serializer, compressor, payload, **options) + super(payload, **options) + @serializer = serializer + @compressor = compressor + @resolved = false + end + + def value + if !@resolved + @value = @serializer.load(@compressor ? @compressor.inflate(@value) : @value) + @resolved = true + end + @value + end + + def mismatched?(version) + super.tap { |mismatched| value if !mismatched } + rescue Cache::DeserializationError + true + end + end + + def signature?(dumped) + dumped.is_a?(String) && dumped.start_with?(SIGNATURE) + end + + def type_for_string(value) + STRING_ENCODINGS.key(value.encoding) if value.instance_of?(String) + end + + def try_compress(string, threshold) + if @compressor && string.bytesize >= threshold + compressed = @compressor.deflate(string) + compressed if compressed.bytesize < string.bytesize + end + end + + def dump_version(version) + if version.encoding != Encoding::UTF_8 || version.start_with?(MARSHAL_SIGNATURE) + Marshal.dump(version) + else + version.b + end + end + + def load_version(dumped_version) + if dumped_version.start_with?(MARSHAL_SIGNATURE) + Marshal.load(dumped_version) + else + dumped_version.force_encoding(Encoding::UTF_8) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/entry.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/entry.rb new file mode 100644 index 00000000..99318d82 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/entry.rb @@ -0,0 +1,134 @@ +# frozen_string_literal: true + +require "zlib" + +module ActiveSupport + module Cache + # This class is used to represent cache entries. Cache entries have a value, an optional + # expiration time, and an optional version. The expiration time is used to support the :race_condition_ttl option + # on the cache. The version is used to support the :version option on the cache for rejecting + # mismatches. + # + # Since cache entries in most instances will be serialized, the internals of this class are highly optimized + # using short instance variable names that are lazily defined. + class Entry # :nodoc: + class << self + def unpack(members) + new(members[0], expires_at: members[1], version: members[2]) + end + end + + attr_reader :version + + # Creates a new cache entry for the specified value. Options supported are + # +:compressed+, +:version+, +:expires_at+ and +:expires_in+. + def initialize(value, compressed: false, version: nil, expires_in: nil, expires_at: nil, **) + @value = value + @version = version + @created_at = 0.0 + @expires_in = expires_at&.to_f || expires_in && (expires_in.to_f + Time.now.to_f) + @compressed = true if compressed + end + + def value + compressed? ? uncompress(@value) : @value + end + + def mismatched?(version) + @version && version && @version != version + end + + # Checks if the entry is expired. The +expires_in+ parameter can override + # the value set when the entry was created. + def expired? + @expires_in && @created_at + @expires_in <= Time.now.to_f + end + + def expires_at + @expires_in ? @created_at + @expires_in : nil + end + + def expires_at=(value) + if value + @expires_in = value.to_f - @created_at + else + @expires_in = nil + end + end + + # Returns the size of the cached value. This could be less than + # value.bytesize if the data is compressed. + def bytesize + case value + when NilClass + 0 + when String + @value.bytesize + else + @s ||= Marshal.dump(@value).bytesize + end + end + + def compressed? # :nodoc: + defined?(@compressed) + end + + def compressed(compress_threshold) + return self if compressed? + + case @value + when nil, true, false, Numeric + uncompressed_size = 0 + when String + uncompressed_size = @value.bytesize + else + serialized = Marshal.dump(@value) + uncompressed_size = serialized.bytesize + end + + if uncompressed_size >= compress_threshold + serialized ||= Marshal.dump(@value) + compressed = Zlib::Deflate.deflate(serialized) + + if compressed.bytesize < uncompressed_size + return Entry.new(compressed, compressed: true, expires_at: expires_at, version: version) + end + end + self + end + + def local? + false + end + + # Duplicates the value in a class. This is used by cache implementations that don't natively + # serialize entries to protect against accidental cache modifications. + def dup_value! + if @value && !compressed? && !(@value.is_a?(Numeric) || @value == true || @value == false) + if @value.is_a?(String) + @value = @value.dup + else + @value = Marshal.load(Marshal.dump(@value)) + end + end + end + + def pack + members = [value, expires_at, version] + members.pop while !members.empty? && members.last.nil? + members + end + + private + def uncompress(value) + marshal_load(Zlib::Inflate.inflate(value)) + end + + def marshal_load(payload) + Marshal.load(payload) + rescue ArgumentError => error + raise Cache::DeserializationError, error.message + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/file_store.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/file_store.rb new file mode 100644 index 00000000..4c4e737e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/file_store.rb @@ -0,0 +1,244 @@ +# frozen_string_literal: true + +require "active_support/core_ext/file/atomic" +require "active_support/core_ext/string/conversions" +require "uri/common" + +module ActiveSupport + module Cache + # = \File \Cache \Store + # + # A cache store implementation which stores everything on the filesystem. + class FileStore < Store + attr_reader :cache_path + + DIR_FORMATTER = "%03X" + FILENAME_MAX_SIZE = 226 # max filename size on file system is 255, minus room for timestamp, pid, and random characters appended by Tempfile (used by atomic write) + FILEPATH_MAX_SIZE = 900 # max is 1024, plus some room + GITKEEP_FILES = [".gitkeep", ".keep"].freeze + + def initialize(cache_path, **options) + super(options) + @cache_path = cache_path.to_s + end + + # Advertise cache versioning support. + def self.supports_cache_versioning? + true + end + + # Deletes all items from the cache. In this case it deletes all the entries in the specified + # file store directory except for .keep or .gitkeep. Be careful which directory is specified in your + # config file when using +FileStore+ because everything in that directory will be deleted. + def clear(options = nil) + root_dirs = (Dir.children(cache_path) - GITKEEP_FILES) + FileUtils.rm_r(root_dirs.collect { |f| File.join(cache_path, f) }) + rescue Errno::ENOENT, Errno::ENOTEMPTY + end + + # Preemptively iterates through all stored keys and removes the ones which have expired. + def cleanup(options = nil) + options = merged_options(options) + search_dir(cache_path) do |fname| + entry = read_entry(fname, **options) + delete_entry(fname, **options) if entry && entry.expired? + end + end + + # Increment a cached integer value. Returns the updated value. + # + # If the key is unset, it starts from +0+: + # + # cache.increment("foo") # => 1 + # cache.increment("bar", 100) # => 100 + # + # To set a specific value, call #write: + # + # cache.write("baz", 5) + # cache.increment("baz") # => 6 + # + def increment(name, amount = 1, **options) + options = merged_options(options) + key = normalize_key(name, options) + + instrument(:increment, key, amount: amount) do + modify_value(name, amount, options) + end + end + + # Decrement a cached integer value. Returns the updated value. + # + # If the key is unset, it will be set to +-amount+. + # + # cache.decrement("foo") # => -1 + # + # To set a specific value, call #write: + # + # cache.write("baz", 5) + # cache.decrement("baz") # => 4 + # + def decrement(name, amount = 1, **options) + options = merged_options(options) + key = normalize_key(name, options) + + instrument(:decrement, key, amount: amount) do + modify_value(name, -amount, options) + end + end + + def delete_matched(matcher, options = nil) + options = merged_options(options) + matcher = key_matcher(matcher, options) + + instrument(:delete_matched, matcher.inspect) do + search_dir(cache_path) do |path| + key = file_path_key(path) + delete_entry(path, **options) if key.match(matcher) + end + end + end + + def inspect # :nodoc: + "#<#{self.class.name} cache_path=#{@cache_path}, options=#{@options.inspect}>" + end + + private + def read_entry(key, **options) + if payload = read_serialized_entry(key, **options) + entry = deserialize_entry(payload) + entry if entry.is_a?(Cache::Entry) + end + end + + def read_serialized_entry(key, **) + File.binread(key) if File.exist?(key) + rescue => error + logger.error("FileStoreError (#{error}): #{error.message}") if logger + nil + end + + def write_entry(key, entry, **options) + write_serialized_entry(key, serialize_entry(entry, **options), **options) + end + + def write_serialized_entry(key, payload, **options) + return false if options[:unless_exist] && File.exist?(key) + ensure_cache_path(File.dirname(key)) + File.atomic_write(key, cache_path) { |f| f.write(payload) } + true + end + + def delete_entry(key, **options) + if File.exist?(key) + begin + File.delete(key) + delete_empty_directories(File.dirname(key)) + true + rescue + # Just in case the error was caused by another process deleting the file first. + raise if File.exist?(key) + false + end + else + false + end + end + + # Lock a file for a block so only one process can modify it at a time. + def lock_file(file_name, &block) + if File.exist?(file_name) + File.open(file_name, "r+") do |f| + f.flock File::LOCK_EX + yield + ensure + f.flock File::LOCK_UN + end + else + yield + end + end + + # Translate a key into a file path. + def normalize_key(key, options) + key = super + fname = URI.encode_www_form_component(key) + + if fname.size > FILEPATH_MAX_SIZE + fname = ActiveSupport::Digest.hexdigest(key) + end + + hash = Zlib.adler32(fname) + hash, dir_1 = hash.divmod(0x1000) + dir_2 = hash.modulo(0x1000) + + # Make sure file name doesn't exceed file system limits. + if fname.length < FILENAME_MAX_SIZE + fname_paths = fname + else + fname_paths = [] + begin + fname_paths << fname[0, FILENAME_MAX_SIZE] + fname = fname[FILENAME_MAX_SIZE..-1] + end until fname.blank? + end + + File.join(cache_path, DIR_FORMATTER % dir_1, DIR_FORMATTER % dir_2, fname_paths) + end + + # Translate a file path into a key. + def file_path_key(path) + fname = path[cache_path.to_s.size..-1].split(File::SEPARATOR, 4).last.delete(File::SEPARATOR) + URI.decode_www_form_component(fname, Encoding::UTF_8) + end + + # Delete empty directories in the cache. + def delete_empty_directories(dir) + return if File.realpath(dir) == File.realpath(cache_path) + if Dir.children(dir).empty? + Dir.delete(dir) rescue nil + delete_empty_directories(File.dirname(dir)) + end + end + + # Make sure a file path's directories exist. + def ensure_cache_path(path) + FileUtils.makedirs(path) unless File.exist?(path) + end + + def search_dir(dir, &callback) + return if !File.exist?(dir) + Dir.each_child(dir) do |d| + name = File.join(dir, d) + if File.directory?(name) + search_dir(name, &callback) + else + callback.call name + end + end + end + + # Modifies the amount of an integer value that is stored in the cache. + # If the key is not found it is created and set to +amount+. + def modify_value(name, amount, options) + options = merged_options(options) + key = normalize_key(name, options) + version = normalize_version(name, options) + amount = Integer(amount) + + lock_file(key) do + entry = read_entry(key, **options) + + if !entry || entry.expired? || entry.mismatched?(version) + write(name, amount, options) + amount + else + num = entry.value.to_i + amount + entry = Entry.new(num, expires_at: entry.expires_at, version: entry.version) + write_entry(key, entry) + num + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/mem_cache_store.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/mem_cache_store.rb new file mode 100644 index 00000000..723b65bd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/mem_cache_store.rb @@ -0,0 +1,290 @@ +# frozen_string_literal: true + +begin + require "dalli" +rescue LoadError => e + warn "You don't have dalli installed in your application. Please add it to your Gemfile and run bundle install" + raise e +end + +require "connection_pool" +require "delegate" +require "active_support/core_ext/enumerable" +require "active_support/core_ext/array/extract_options" +require "active_support/core_ext/numeric/time" + +module ActiveSupport + module Cache + # = Memcached \Cache \Store + # + # A cache store implementation which stores data in Memcached: + # https://memcached.org + # + # This is currently the most popular cache store for production websites. + # + # Special features: + # - Clustering and load balancing. One can specify multiple memcached servers, + # and +MemCacheStore+ will load balance between all available servers. If a + # server goes down, then +MemCacheStore+ will ignore it until it comes back up. + # + # +MemCacheStore+ implements the Strategy::LocalCache strategy which + # implements an in-memory cache inside of a block. + class MemCacheStore < Store + # These options represent behavior overridden by this implementation and should + # not be allowed to get down to the Dalli client + OVERRIDDEN_OPTIONS = UNIVERSAL_OPTIONS + + # Advertise cache versioning support. + def self.supports_cache_versioning? + true + end + + prepend Strategy::LocalCache + + KEY_MAX_SIZE = 250 + ESCAPE_KEY_CHARS = /[\x00-\x20%\x7F-\xFF]/n + + # Creates a new Dalli::Client instance with specified addresses and options. + # If no addresses are provided, we give nil to Dalli::Client, so it uses its fallbacks: + # - ENV["MEMCACHE_SERVERS"] (if defined) + # - "127.0.0.1:11211" (otherwise) + # + # ActiveSupport::Cache::MemCacheStore.build_mem_cache + # # => # + # ActiveSupport::Cache::MemCacheStore.build_mem_cache('localhost:10290') + # # => # + def self.build_mem_cache(*addresses) # :nodoc: + addresses = addresses.flatten + options = addresses.extract_options! + addresses = nil if addresses.compact.empty? + pool_options = retrieve_pool_options(options) + + if pool_options + ConnectionPool.new(pool_options) { Dalli::Client.new(addresses, options.merge(threadsafe: false)) } + else + Dalli::Client.new(addresses, options) + end + end + + # Creates a new +MemCacheStore+ object, with the given memcached server + # addresses. Each address is either a host name, or a host-with-port string + # in the form of "host_name:port". For example: + # + # ActiveSupport::Cache::MemCacheStore.new("localhost", "server-downstairs.localnetwork:8229") + # + # If no addresses are provided, but ENV['MEMCACHE_SERVERS'] is defined, it will be used instead. Otherwise, + # +MemCacheStore+ will connect to localhost:11211 (the default memcached port). + def initialize(*addresses) + addresses = addresses.flatten + options = addresses.extract_options! + if options.key?(:cache_nils) + options[:skip_nil] = !options.delete(:cache_nils) + end + super(options) + + unless [String, Dalli::Client, NilClass].include?(addresses.first.class) + raise ArgumentError, "First argument must be an empty array, address, or array of addresses." + end + + @mem_cache_options = options.dup + # The value "compress: false" prevents duplicate compression within Dalli. + @mem_cache_options[:compress] = false + (OVERRIDDEN_OPTIONS - %i(compress)).each { |name| @mem_cache_options.delete(name) } + @data = self.class.build_mem_cache(*(addresses + [@mem_cache_options])) + end + + def inspect + instance = @data || @mem_cache_options + "#<#{self.class} options=#{options.inspect} mem_cache=#{instance.inspect}>" + end + + ## + # :method: write + # :call-seq: write(name, value, options = nil) + # + # Behaves the same as ActiveSupport::Cache::Store#write, but supports + # additional options specific to memcached. + # + # ==== Additional Options + # + # * raw: true - Sends the value directly to the server as raw + # bytes. The value must be a string or number. You can use memcached + # direct operations like +increment+ and +decrement+ only on raw values. + # + # * unless_exist: true - Prevents overwriting an existing cache + # entry. + + # Increment a cached integer value using the memcached incr atomic operator. + # Returns the updated value. + # + # If the key is unset or has expired, it will be set to +amount+: + # + # cache.increment("foo") # => 1 + # cache.increment("bar", 100) # => 100 + # + # To set a specific value, call #write passing raw: true: + # + # cache.write("baz", 5, raw: true) + # cache.increment("baz") # => 6 + # + # Incrementing a non-numeric value, or a value written without + # raw: true, will fail and return +nil+. + def increment(name, amount = 1, options = nil) + options = merged_options(options) + key = normalize_key(name, options) + + instrument(:increment, key, amount: amount) do + rescue_error_with nil do + @data.with { |c| c.incr(key, amount, options[:expires_in], amount) } + end + end + end + + # Decrement a cached integer value using the memcached decr atomic operator. + # Returns the updated value. + # + # If the key is unset or has expired, it will be set to 0. Memcached + # does not support negative counters. + # + # cache.decrement("foo") # => 0 + # + # To set a specific value, call #write passing raw: true: + # + # cache.write("baz", 5, raw: true) + # cache.decrement("baz") # => 4 + # + # Decrementing a non-numeric value, or a value written without + # raw: true, will fail and return +nil+. + def decrement(name, amount = 1, options = nil) + options = merged_options(options) + key = normalize_key(name, options) + + instrument(:decrement, key, amount: amount) do + rescue_error_with nil do + @data.with { |c| c.decr(key, amount, options[:expires_in], 0) } + end + end + end + + # Clear the entire cache on all memcached servers. This method should + # be used with care when shared cache is being used. + def clear(options = nil) + rescue_error_with(nil) { @data.with { |c| c.flush_all } } + end + + # Get the statistics from the memcached servers. + def stats + @data.with { |c| c.stats } + end + + private + # Read an entry from the cache. + def read_entry(key, **options) + deserialize_entry(read_serialized_entry(key, **options), **options) + end + + def read_serialized_entry(key, **options) + rescue_error_with(nil) do + @data.with { |c| c.get(key, options) } + end + end + + # Write an entry to the cache. + def write_entry(key, entry, **options) + write_serialized_entry(key, serialize_entry(entry, **options), **options) + end + + def write_serialized_entry(key, payload, **options) + method = options[:unless_exist] ? :add : :set + expires_in = options[:expires_in].to_i + if options[:race_condition_ttl] && expires_in > 0 && !options[:raw] + # Set the memcache expire a few minutes in the future to support race condition ttls on read + expires_in += 5.minutes + end + rescue_error_with nil do + # Don't pass compress option to Dalli since we are already dealing with compression. + options.delete(:compress) + @data.with { |c| !!c.send(method, key, payload, expires_in, **options) } + end + end + + # Reads multiple entries from the cache implementation. + def read_multi_entries(names, **options) + keys_to_names = names.index_by { |name| normalize_key(name, options) } + + raw_values = begin + @data.with { |c| c.get_multi(keys_to_names.keys) } + rescue Dalli::UnmarshalError + {} + end + + values = {} + + raw_values.each do |key, value| + entry = deserialize_entry(value, raw: options[:raw]) + + unless entry.nil? || entry.expired? || entry.mismatched?(normalize_version(keys_to_names[key], options)) + begin + values[keys_to_names[key]] = entry.value + rescue DeserializationError + end + end + end + + values + end + + # Delete an entry from the cache. + def delete_entry(key, **options) + rescue_error_with(false) { @data.with { |c| c.delete(key) } } + end + + def serialize_entry(entry, raw: false, **options) + if raw + entry.value.to_s + else + super(entry, raw: raw, **options) + end + end + + # Memcache keys are binaries. So we need to force their encoding to binary + # before applying the regular expression to ensure we are escaping all + # characters properly. + def normalize_key(key, options) + key = super + if key + key = key.dup.force_encoding(Encoding::ASCII_8BIT) + key = key.gsub(ESCAPE_KEY_CHARS) { |match| "%#{match.getbyte(0).to_s(16).upcase}" } + + if key.size > KEY_MAX_SIZE + key_separator = ":hash:" + key_hash = ActiveSupport::Digest.hexdigest(key) + key_trim_size = KEY_MAX_SIZE - key_separator.size - key_hash.size + key = "#{key[0, key_trim_size]}#{key_separator}#{key_hash}" + end + end + key + end + + def deserialize_entry(payload, raw: false, **) + if payload && raw + Entry.new(payload) + else + super(payload) + end + end + + def rescue_error_with(fallback) + yield + rescue Dalli::DalliError, ConnectionPool::Error, ConnectionPool::TimeoutError => error + logger.error("DalliError (#{error}): #{error.message}") if logger + ActiveSupport.error_reporter&.report( + error, + severity: :warning, + source: "mem_cache_store.active_support", + ) + fallback + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/memory_store.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/memory_store.rb new file mode 100644 index 00000000..3317dcd4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/memory_store.rb @@ -0,0 +1,262 @@ +# frozen_string_literal: true + +require "monitor" + +module ActiveSupport + module Cache + # = Memory \Cache \Store + # + # A cache store implementation which stores everything into memory in the + # same process. If you're running multiple Ruby on \Rails server processes + # (which is the case if you're using Phusion Passenger or puma clustered mode), + # then this means that \Rails server process instances won't be able + # to share cache data with each other and this may not be the most + # appropriate cache in that scenario. + # + # This cache has a bounded size specified by the +:size+ options to the + # initializer (default is 32Mb). When the cache exceeds the allotted size, + # a cleanup will occur which tries to prune the cache down to three quarters + # of the maximum size by removing the least recently used entries. + # + # Unlike other Cache store implementations, +MemoryStore+ does not compress + # values by default. +MemoryStore+ does not benefit from compression as much + # as other Store implementations, as it does not send data over a network. + # However, when compression is enabled, it still pays the full cost of + # compression in terms of cpu use. + # + # +MemoryStore+ is thread-safe. + class MemoryStore < Store + module DupCoder # :nodoc: + extend self + + def dump(entry) + if entry.value && entry.value != true && !entry.value.is_a?(Numeric) + Cache::Entry.new(dump_value(entry.value), expires_at: entry.expires_at, version: entry.version) + else + entry + end + end + + def dump_compressed(entry, threshold) + compressed_entry = entry.compressed(threshold) + compressed_entry.compressed? ? compressed_entry : dump(entry) + end + + def load(entry) + if !entry.compressed? && entry.value.is_a?(String) + Cache::Entry.new(load_value(entry.value), expires_at: entry.expires_at, version: entry.version) + else + entry + end + end + + private + MARSHAL_SIGNATURE = "\x04\x08".b.freeze + + def dump_value(value) + if value.is_a?(String) && !value.start_with?(MARSHAL_SIGNATURE) + value.dup + else + Marshal.dump(value) + end + end + + def load_value(string) + if string.start_with?(MARSHAL_SIGNATURE) + Marshal.load(string) + else + string.dup + end + end + end + + def initialize(options = nil) + options ||= {} + options[:coder] = DupCoder unless options.key?(:coder) || options.key?(:serializer) + # Disable compression by default. + options[:compress] ||= false + super(options) + @data = {} + @max_size = options[:size] || 32.megabytes + @max_prune_time = options[:max_prune_time] || 2 + @cache_size = 0 + @monitor = Monitor.new + @pruning = false + end + + # Advertise cache versioning support. + def self.supports_cache_versioning? + true + end + + # Delete all data stored in a given cache store. + def clear(options = nil) + synchronize do + @data.clear + @cache_size = 0 + end + end + + # Preemptively iterates through all stored keys and removes the ones which have expired. + def cleanup(options = nil) + options = merged_options(options) + _instrument(:cleanup, size: @data.size) do + keys = synchronize { @data.keys } + keys.each do |key| + entry = @data[key] + delete_entry(key, **options) if entry && entry.expired? + end + end + end + + # To ensure entries fit within the specified memory prune the cache by removing the least + # recently accessed entries. + def prune(target_size, max_time = nil) + return if pruning? + @pruning = true + begin + start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) + cleanup + instrument(:prune, target_size, from: @cache_size) do + keys = synchronize { @data.keys } + keys.each do |key| + delete_entry(key, **options) + return if @cache_size <= target_size || (max_time && Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time > max_time) + end + end + ensure + @pruning = false + end + end + + # Returns true if the cache is currently being pruned. + def pruning? + @pruning + end + + # Increment a cached integer value. Returns the updated value. + # + # If the key is unset, it will be set to +amount+: + # + # cache.increment("foo") # => 1 + # cache.increment("bar", 100) # => 100 + # + # To set a specific value, call #write: + # + # cache.write("baz", 5) + # cache.increment("baz") # => 6 + # + def increment(name, amount = 1, **options) + instrument(:increment, name, amount: amount) do + modify_value(name, amount, **options) + end + end + + # Decrement a cached integer value. Returns the updated value. + # + # If the key is unset or has expired, it will be set to +-amount+. + # + # cache.decrement("foo") # => -1 + # + # To set a specific value, call #write: + # + # cache.write("baz", 5) + # cache.decrement("baz") # => 4 + # + def decrement(name, amount = 1, **options) + instrument(:decrement, name, amount: amount) do + modify_value(name, -amount, **options) + end + end + + # Deletes cache entries if the cache key matches a given pattern. + def delete_matched(matcher, options = nil) + options = merged_options(options) + matcher = key_matcher(matcher, options) + + instrument(:delete_matched, matcher.inspect) do + keys = synchronize { @data.keys } + keys.each do |key| + delete_entry(key, **options) if key.match(matcher) + end + end + end + + def inspect # :nodoc: + "#<#{self.class.name} entries=#{@data.size}, size=#{@cache_size}, options=#{@options.inspect}>" + end + + # Synchronize calls to the cache. This should be called wherever the underlying cache implementation + # is not thread safe. + def synchronize(&block) # :nodoc: + @monitor.synchronize(&block) + end + + private + PER_ENTRY_OVERHEAD = 240 + + def cached_size(key, payload) + key.to_s.bytesize + payload.bytesize + PER_ENTRY_OVERHEAD + end + + def read_entry(key, **options) + entry = nil + synchronize do + payload = @data.delete(key) + if payload + @data[key] = payload + entry = deserialize_entry(payload) + end + end + entry + end + + def write_entry(key, entry, **options) + payload = serialize_entry(entry, **options) + synchronize do + return false if options[:unless_exist] && exist?(key, namespace: nil) + + old_payload = @data[key] + if old_payload + @cache_size -= (old_payload.bytesize - payload.bytesize) + else + @cache_size += cached_size(key, payload) + end + @data[key] = payload + prune(@max_size * 0.75, @max_prune_time) if @cache_size > @max_size + true + end + end + + def delete_entry(key, **options) + synchronize do + payload = @data.delete(key) + @cache_size -= cached_size(key, payload) if payload + !!payload + end + end + + # Modifies the amount of an integer value that is stored in the cache. + # If the key is not found it is created and set to +amount+. + def modify_value(name, amount, **options) + options = merged_options(options) + key = normalize_key(name, options) + version = normalize_version(name, options) + + synchronize do + entry = read_entry(key, **options) + + if !entry || entry.expired? || entry.mismatched?(version) + write(name, Integer(amount), options) + amount + else + num = entry.value.to_i + amount + entry = Entry.new(num, expires_at: entry.expires_at, version: entry.version) + write_entry(key, entry) + num + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/null_store.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/null_store.rb new file mode 100644 index 00000000..7479a264 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/null_store.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +module ActiveSupport + module Cache + # = Null \Cache \Store + # + # A cache store implementation which doesn't actually store anything. Useful in + # development and test environments where you don't want caching turned on but + # need to go through the caching interface. + # + # This cache does implement the local cache strategy, so values will actually + # be cached inside blocks that utilize this strategy. See + # ActiveSupport::Cache::Strategy::LocalCache for more details. + class NullStore < Store + prepend Strategy::LocalCache + + # Advertise cache versioning support. + def self.supports_cache_versioning? + true + end + + def clear(options = nil) + end + + def cleanup(options = nil) + end + + def increment(name, amount = 1, **options) + end + + def decrement(name, amount = 1, **options) + end + + def delete_matched(matcher, options = nil) + end + + def inspect # :nodoc: + "#<#{self.class.name} options=#{@options.inspect}>" + end + + private + def read_entry(key, **s) + deserialize_entry(read_serialized_entry(key)) + end + + def read_serialized_entry(_key, **) + end + + def write_entry(key, entry, **) + write_serialized_entry(key, serialize_entry(entry)) + end + + def write_serialized_entry(_key, _payload, **) + true + end + + def delete_entry(key, **options) + false + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/redis_cache_store.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/redis_cache_store.rb new file mode 100644 index 00000000..4192d4ab --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/redis_cache_store.rb @@ -0,0 +1,492 @@ +# frozen_string_literal: true + +begin + gem "redis", ">= 4.0.1" + require "redis" + require "redis/distributed" +rescue LoadError + warn "The Redis cache store requires the redis gem, version 4.0.1 or later. Please add it to your Gemfile: `gem \"redis\", \">= 4.0.1\"`" + raise +end + +require "connection_pool" +require "active_support/core_ext/array/wrap" +require "active_support/core_ext/hash/slice" +require "active_support/core_ext/numeric/time" +require "active_support/digest" + +module ActiveSupport + module Cache + # = Redis \Cache \Store + # + # Deployment note: Take care to use a dedicated Redis cache rather + # than pointing this at a persistent Redis server (for example, one used as + # an Active Job queue). Redis won't cope well with mixed usage patterns and it + # won't expire cache entries by default. + # + # Redis cache server setup guide: https://redis.io/topics/lru-cache + # + # * Supports vanilla Redis, hiredis, and +Redis::Distributed+. + # * Supports Memcached-like sharding across Redises with +Redis::Distributed+. + # * Fault tolerant. If the Redis server is unavailable, no exceptions are + # raised. Cache fetches are all misses and writes are dropped. + # * Local cache. Hot in-memory primary cache within block/middleware scope. + # * +read_multi+ and +write_multi+ support for Redis mget/mset. Use + # +Redis::Distributed+ 4.0.1+ for distributed mget support. + # * +delete_matched+ support for Redis KEYS globs. + class RedisCacheStore < Store + # Keys are truncated with the Active Support digest if they exceed 1kB + MAX_KEY_BYTESIZE = 1024 + + DEFAULT_REDIS_OPTIONS = { + connect_timeout: 1, + read_timeout: 1, + write_timeout: 1, + } + + DEFAULT_ERROR_HANDLER = -> (method:, returning:, exception:) do + if logger + logger.error { "RedisCacheStore: #{method} failed, returned #{returning.inspect}: #{exception.class}: #{exception.message}" } + end + ActiveSupport.error_reporter&.report( + exception, + severity: :warning, + source: "redis_cache_store.active_support", + ) + end + + # The maximum number of entries to receive per SCAN call. + SCAN_BATCH_SIZE = 1000 + private_constant :SCAN_BATCH_SIZE + + # Advertise cache versioning support. + def self.supports_cache_versioning? + true + end + + prepend Strategy::LocalCache + + class << self + # Factory method to create a new Redis instance. + # + # Handles four options: :redis block, :redis instance, single :url + # string, and multiple :url strings. + # + # Option Class Result + # :redis Proc -> options[:redis].call + # :redis Object -> options[:redis] + # :url String -> Redis.new(url: …) + # :url Array -> Redis::Distributed.new([{ url: … }, { url: … }, …]) + # + def build_redis(redis: nil, url: nil, **redis_options) # :nodoc: + urls = Array(url) + + if redis.is_a?(Proc) + redis.call + elsif redis + redis + elsif urls.size > 1 + build_redis_distributed_client(urls: urls, **redis_options) + elsif urls.empty? + build_redis_client(**redis_options) + else + build_redis_client(url: urls.first, **redis_options) + end + end + + private + def build_redis_distributed_client(urls:, **redis_options) + ::Redis::Distributed.new([], DEFAULT_REDIS_OPTIONS.merge(redis_options)).tap do |dist| + urls.each { |u| dist.add_node url: u } + end + end + + def build_redis_client(**redis_options) + ::Redis.new(DEFAULT_REDIS_OPTIONS.merge(redis_options)) + end + end + + attr_reader :max_key_bytesize + attr_reader :redis + + # Creates a new Redis cache store. + # + # There are four ways to provide the Redis client used by the cache: the + # +:redis+ param can be a Redis instance or a block that returns a Redis + # instance, or the +:url+ param can be a string or an array of strings + # which will be used to create a Redis instance or a +Redis::Distributed+ + # instance. + # + # Option Class Result + # :redis Proc -> options[:redis].call + # :redis Object -> options[:redis] + # :url String -> Redis.new(url: …) + # :url Array -> Redis::Distributed.new([{ url: … }, { url: … }, …]) + # + # No namespace is set by default. Provide one if the Redis cache + # server is shared with other apps: namespace: 'myapp-cache'. + # + # Compression is enabled by default with a 1kB threshold, so cached + # values larger than 1kB are automatically compressed. Disable by + # passing compress: false or change the threshold by passing + # compress_threshold: 4.kilobytes. + # + # No expiry is set on cache entries by default. Redis is expected to + # be configured with an eviction policy that automatically deletes + # least-recently or -frequently used keys when it reaches max memory. + # See https://redis.io/topics/lru-cache for cache server setup. + # + # Race condition TTL is not set by default. This can be used to avoid + # "thundering herd" cache writes when hot cache entries are expired. + # See ActiveSupport::Cache::Store#fetch for more. + # + # Setting skip_nil: true will not cache nil results: + # + # cache.fetch('foo') { nil } + # cache.fetch('bar', skip_nil: true) { nil } + # cache.exist?('foo') # => true + # cache.exist?('bar') # => false + def initialize(error_handler: DEFAULT_ERROR_HANDLER, **redis_options) + universal_options = redis_options.extract!(*UNIVERSAL_OPTIONS) + + if pool_options = self.class.send(:retrieve_pool_options, redis_options) + @redis = ::ConnectionPool.new(pool_options) { self.class.build_redis(**redis_options) } + else + @redis = self.class.build_redis(**redis_options) + end + + @max_key_bytesize = MAX_KEY_BYTESIZE + @error_handler = error_handler + + super(universal_options) + end + + def inspect + "#<#{self.class} options=#{options.inspect} redis=#{redis.inspect}>" + end + + # Cache Store API implementation. + # + # Read multiple values at once. Returns a hash of requested keys -> + # fetched values. + def read_multi(*names) + return {} if names.empty? + + options = names.extract_options! + options = merged_options(options) + keys = names.map { |name| normalize_key(name, options) } + + instrument_multi(:read_multi, keys, options) do |payload| + read_multi_entries(names, **options).tap do |results| + payload[:hits] = results.keys.map { |name| normalize_key(name, options) } + end + end + end + + # Cache Store API implementation. + # + # Supports Redis KEYS glob patterns: + # + # h?llo matches hello, hallo and hxllo + # h*llo matches hllo and heeeello + # h[ae]llo matches hello and hallo, but not hillo + # h[^e]llo matches hallo, hbllo, ... but not hello + # h[a-b]llo matches hallo and hbllo + # + # Use \ to escape special characters if you want to match them verbatim. + # + # See https://redis.io/commands/KEYS for more. + # + # Failsafe: Raises errors. + def delete_matched(matcher, options = nil) + unless String === matcher + raise ArgumentError, "Only Redis glob strings are supported: #{matcher.inspect}" + end + pattern = namespace_key(matcher, options) + + instrument :delete_matched, pattern do + redis.then do |c| + cursor = "0" + # Fetch keys in batches using SCAN to avoid blocking the Redis server. + nodes = c.respond_to?(:nodes) ? c.nodes : [c] + + nodes.each do |node| + begin + cursor, keys = node.scan(cursor, match: pattern, count: SCAN_BATCH_SIZE) + node.del(*keys) unless keys.empty? + end until cursor == "0" + end + end + end + end + + # Increment a cached integer value using the Redis incrby atomic operator. + # Returns the updated value. + # + # If the key is unset or has expired, it will be set to +amount+: + # + # cache.increment("foo") # => 1 + # cache.increment("bar", 100) # => 100 + # + # To set a specific value, call #write passing raw: true: + # + # cache.write("baz", 5, raw: true) + # cache.increment("baz") # => 6 + # + # Incrementing a non-numeric value, or a value written without + # raw: true, will fail and return +nil+. + # + # Failsafe: Raises errors. + def increment(name, amount = 1, options = nil) + options = merged_options(options) + key = normalize_key(name, options) + + instrument :increment, key, amount: amount do + failsafe :increment do + change_counter(key, amount, options) + end + end + end + + # Decrement a cached integer value using the Redis decrby atomic operator. + # Returns the updated value. + # + # If the key is unset or has expired, it will be set to +-amount+: + # + # cache.decrement("foo") # => -1 + # + # To set a specific value, call #write passing raw: true: + # + # cache.write("baz", 5, raw: true) + # cache.decrement("baz") # => 4 + # + # Decrementing a non-numeric value, or a value written without + # raw: true, will fail and return +nil+. + # + # Failsafe: Raises errors. + def decrement(name, amount = 1, options = nil) + options = merged_options(options) + key = normalize_key(name, options) + + instrument :decrement, key, amount: amount do + failsafe :decrement do + change_counter(key, -amount, options) + end + end + end + + # Cache Store API implementation. + # + # Removes expired entries. Handled natively by Redis least-recently-/ + # least-frequently-used expiry, so manual cleanup is not supported. + def cleanup(options = nil) + super + end + + # Clear the entire cache on all Redis servers. Safe to use on + # shared servers if the cache is namespaced. + # + # Failsafe: Raises errors. + def clear(options = nil) + failsafe :clear do + if namespace = merged_options(options)[:namespace] + delete_matched "*", namespace: namespace + else + redis.then { |c| c.flushdb } + end + end + end + + # Get info from redis servers. + def stats + redis.then { |c| c.info } + end + + private + def pipeline_entries(entries, &block) + redis.then { |c| + if c.is_a?(Redis::Distributed) + entries.group_by { |k, _v| c.node_for(k) }.each do |node, sub_entries| + node.pipelined { |pipe| yield(pipe, sub_entries) } + end + else + c.pipelined { |pipe| yield(pipe, entries) } + end + } + end + + # Store provider interface: + # Read an entry from the cache. + def read_entry(key, **options) + deserialize_entry(read_serialized_entry(key, **options), **options) + end + + def read_serialized_entry(key, raw: false, **options) + failsafe :read_entry do + redis.then { |c| c.get(key) } + end + end + + def read_multi_entries(names, **options) + options = merged_options(options) + return {} if names == [] + raw = options&.fetch(:raw, false) + + keys = names.map { |name| normalize_key(name, options) } + + values = failsafe(:read_multi_entries, returning: {}) do + redis.then { |c| c.mget(*keys) } + end + + names.zip(values).each_with_object({}) do |(name, value), results| + if value + entry = deserialize_entry(value, raw: raw) + unless entry.nil? || entry.expired? || entry.mismatched?(normalize_version(name, options)) + begin + results[name] = entry.value + rescue DeserializationError + end + end + end + end + end + + # Write an entry to the cache. + # + # Requires Redis 2.6.12+ for extended SET options. + def write_entry(key, entry, raw: false, **options) + write_serialized_entry(key, serialize_entry(entry, raw: raw, **options), raw: raw, **options) + end + + def write_serialized_entry(key, payload, raw: false, unless_exist: false, expires_in: nil, race_condition_ttl: nil, pipeline: nil, **options) + # If race condition TTL is in use, ensure that cache entries + # stick around a bit longer after they would have expired + # so we can purposefully serve stale entries. + if race_condition_ttl && expires_in && expires_in > 0 && !raw + expires_in += 5.minutes + end + + modifiers = {} + if unless_exist || expires_in + modifiers[:nx] = unless_exist + modifiers[:px] = (1000 * expires_in.to_f).ceil if expires_in + end + + if pipeline + pipeline.set(key, payload, **modifiers) + else + failsafe :write_entry, returning: nil do + redis.then { |c| !!c.set(key, payload, **modifiers) } + end + end + end + + # Delete an entry from the cache. + def delete_entry(key, **options) + failsafe :delete_entry, returning: false do + redis.then { |c| c.del(key) == 1 } + end + end + + # Deletes multiple entries in the cache. Returns the number of entries deleted. + def delete_multi_entries(entries, **_options) + failsafe :delete_multi_entries, returning: 0 do + redis.then { |c| c.del(entries) } + end + end + + # Nonstandard store provider API to write multiple values at once. + def write_multi_entries(entries, **options) + return if entries.empty? + + failsafe :write_multi_entries do + pipeline_entries(entries) do |pipeline, sharded_entries| + options = options.dup + options[:pipeline] = pipeline + sharded_entries.each do |key, entry| + write_entry key, entry, **options + end + end + end + end + + # Truncate keys that exceed 1kB. + def normalize_key(key, options) + truncate_key super&.b + end + + def truncate_key(key) + if key && key.bytesize > max_key_bytesize + suffix = ":hash:#{ActiveSupport::Digest.hexdigest(key)}" + truncate_at = max_key_bytesize - suffix.bytesize + "#{key.byteslice(0, truncate_at)}#{suffix}" + else + key + end + end + + def deserialize_entry(payload, raw: false, **) + if raw && !payload.nil? + Entry.new(payload) + else + super(payload) + end + end + + def serialize_entry(entry, raw: false, **options) + if raw + entry.value.to_s + else + super(entry, raw: raw, **options) + end + end + + def serialize_entries(entries, **options) + entries.transform_values do |entry| + serialize_entry(entry, **options) + end + end + + def change_counter(key, amount, options) + redis.then do |c| + c = c.node_for(key) if c.is_a?(Redis::Distributed) + + expires_in = options[:expires_in] + + if expires_in + if supports_expire_nx? + count, _ = c.pipelined do |pipeline| + pipeline.incrby(key, amount) + pipeline.call(:expire, key, expires_in.to_i, "NX") + end + else + count, ttl = c.pipelined do |pipeline| + pipeline.incrby(key, amount) + pipeline.ttl(key) + end + c.expire(key, expires_in.to_i) if ttl < 0 + end + else + count = c.incrby(key, amount) + end + + count + end + end + + def supports_expire_nx? + return @supports_expire_nx if defined?(@supports_expire_nx) + + redis_versions = redis.then { |c| Array.wrap(c.info("server")).pluck("redis_version") } + @supports_expire_nx = redis_versions.all? { |v| Gem::Version.new(v) >= Gem::Version.new("7.0.0") } + end + + def failsafe(method, returning: nil) + yield + rescue ::Redis::BaseError, ConnectionPool::Error, ConnectionPool::TimeoutError => error + @error_handler&.call(method: method, exception: error, returning: returning) + returning + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/serializer_with_fallback.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/serializer_with_fallback.rb new file mode 100644 index 00000000..99358490 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/serializer_with_fallback.rb @@ -0,0 +1,152 @@ +# frozen_string_literal: true + +require "zlib" +require "active_support/core_ext/kernel/reporting" + +module ActiveSupport + module Cache + module SerializerWithFallback # :nodoc: + def self.[](format) + if format.to_s.include?("message_pack") && !defined?(ActiveSupport::MessagePack) + require "active_support/message_pack" + end + + SERIALIZERS.fetch(format) + end + + def load(dumped) + if dumped.is_a?(String) + case + when MessagePackWithFallback.dumped?(dumped) + MessagePackWithFallback._load(dumped) + when Marshal71WithFallback.dumped?(dumped) + Marshal71WithFallback._load(dumped) + when Marshal70WithFallback.dumped?(dumped) + Marshal70WithFallback._load(dumped) + else + Cache::Store.logger&.warn("Unrecognized payload prefix #{dumped.byteslice(0).inspect}; deserializing as nil") + nil + end + elsif PassthroughWithFallback.dumped?(dumped) + PassthroughWithFallback._load(dumped) + else + Cache::Store.logger&.warn("Unrecognized payload class #{dumped.class}; deserializing as nil") + nil + end + end + + private + def marshal_load(payload) + Marshal.load(payload) + rescue ArgumentError => error + raise Cache::DeserializationError, error.message + end + + module PassthroughWithFallback + include SerializerWithFallback + extend self + + def dump(entry) + entry + end + + def dump_compressed(entry, threshold) + entry.compressed(threshold) + end + + def _load(entry) + entry + end + + def dumped?(dumped) + dumped.is_a?(Cache::Entry) + end + end + + module Marshal70WithFallback + include SerializerWithFallback + extend self + + MARK_UNCOMPRESSED = "\x00".b.freeze + MARK_COMPRESSED = "\x01".b.freeze + + def dump(entry) + MARK_UNCOMPRESSED + Marshal.dump(entry.pack) + end + + def dump_compressed(entry, threshold) + dumped = Marshal.dump(entry.pack) + + if dumped.bytesize >= threshold + compressed = Zlib::Deflate.deflate(dumped) + return MARK_COMPRESSED + compressed if compressed.bytesize < dumped.bytesize + end + + MARK_UNCOMPRESSED + dumped + end + + def _load(marked) + dumped = marked.byteslice(1..-1) + dumped = Zlib::Inflate.inflate(dumped) if marked.start_with?(MARK_COMPRESSED) + Cache::Entry.unpack(marshal_load(dumped)) + end + + def dumped?(dumped) + dumped.start_with?(MARK_UNCOMPRESSED, MARK_COMPRESSED) + end + end + + module Marshal71WithFallback + include SerializerWithFallback + extend self + + MARSHAL_SIGNATURE = "\x04\x08".b.freeze + + def dump(value) + Marshal.dump(value) + end + + def _load(dumped) + marshal_load(dumped) + end + + def dumped?(dumped) + dumped.start_with?(MARSHAL_SIGNATURE) + end + end + + module MessagePackWithFallback + include SerializerWithFallback + extend self + + def dump(value) + ActiveSupport::MessagePack::CacheSerializer.dump(value) + end + + def _load(dumped) + ActiveSupport::MessagePack::CacheSerializer.load(dumped) + end + + def dumped?(dumped) + available? && ActiveSupport::MessagePack.signature?(dumped) + end + + private + def available? + return @available if defined?(@available) + silence_warnings { require "active_support/message_pack" } + @available = true + rescue LoadError + @available = false + end + end + + SERIALIZERS = { + passthrough: PassthroughWithFallback, + marshal_7_0: Marshal70WithFallback, + marshal_7_1: Marshal71WithFallback, + message_pack: MessagePackWithFallback, + } + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/strategy/local_cache.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/strategy/local_cache.rb new file mode 100644 index 00000000..d40d5efd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/strategy/local_cache.rb @@ -0,0 +1,237 @@ +# frozen_string_literal: true + +require "active_support/core_ext/string/inflections" + +module ActiveSupport + module Cache + module Strategy + # = Local \Cache \Strategy + # + # Caches that implement LocalCache will be backed by an in-memory cache for the + # duration of a block. Repeated calls to the cache for the same key will hit the + # in-memory cache for faster access. + module LocalCache + autoload :Middleware, "active_support/cache/strategy/local_cache_middleware" + + # Class for storing and registering the local caches. + module LocalCacheRegistry # :nodoc: + extend self + + def cache_for(local_cache_key) + registry = ActiveSupport::IsolatedExecutionState[:active_support_local_cache_registry] ||= {} + registry[local_cache_key] + end + + def set_cache_for(local_cache_key, value) + registry = ActiveSupport::IsolatedExecutionState[:active_support_local_cache_registry] ||= {} + registry[local_cache_key] = value + end + end + + # = Local \Cache \Store + # + # Simple memory backed cache. This cache is not thread safe and is intended only + # for serving as a temporary memory cache for a single thread. + class LocalStore + def initialize + @data = {} + end + + def clear(options = nil) + @data.clear + end + + def read_entry(key) + @data[key] + end + + def read_multi_entries(keys) + @data.slice(*keys) + end + + def write_entry(key, entry) + @data[key] = entry + true + end + + def delete_entry(key) + !!@data.delete(key) + end + + def fetch_entry(key) # :nodoc: + @data.fetch(key) { @data[key] = yield } + end + end + + # Use a local cache for the duration of block. + def with_local_cache(&block) + use_temporary_local_cache(LocalStore.new, &block) + end + + # Middleware class can be inserted as a Rack handler to be local cache for the + # duration of request. + def middleware + @middleware ||= Middleware.new( + "ActiveSupport::Cache::Strategy::LocalCache", + local_cache_key) + end + + def clear(options = nil) # :nodoc: + return super unless cache = local_cache + cache.clear(options) + super + end + + def cleanup(options = nil) # :nodoc: + return super unless cache = local_cache + cache.clear(options) + super + end + + def delete_matched(matcher, options = nil) # :nodoc: + return super unless cache = local_cache + cache.clear(options) + super + end + + def increment(name, amount = 1, **options) # :nodoc: + return super unless local_cache + value = bypass_local_cache { super } + write_cache_value(name, value, raw: true, **options) + value + end + + def decrement(name, amount = 1, **options) # :nodoc: + return super unless local_cache + value = bypass_local_cache { super } + write_cache_value(name, value, raw: true, **options) + value + end + + def fetch_multi(*names, &block) # :nodoc: + return super if local_cache.nil? || names.empty? + + options = names.extract_options! + options = merged_options(options) + + keys_to_names = names.index_by { |name| normalize_key(name, options) } + + local_entries = local_cache.read_multi_entries(keys_to_names.keys) + results = local_entries.each_with_object({}) do |(key, value), result| + # If we recorded a miss in the local cache, `#fetch_multi` will forward + # that key to the real store, and the entry will be replaced + # local_cache.delete_entry(key) + next if value.nil? + + entry = deserialize_entry(value, **options) + + normalized_key = keys_to_names[key] + if entry.nil? + result[normalized_key] = nil + elsif entry.expired? || entry.mismatched?(normalize_version(normalized_key, options)) + local_cache.delete_entry(key) + else + result[normalized_key] = entry.value + end + end + + if results.size < names.size + results.merge!(super(*(names - results.keys), options, &block)) + end + + results + end + + private + def read_serialized_entry(key, raw: false, **options) + if cache = local_cache + hit = true + entry = cache.fetch_entry(key) do + hit = false + super + end + options[:event][:store] = cache.class.name if hit && options[:event] + entry + else + super + end + end + + def read_multi_entries(names, **options) + return super unless local_cache + + keys_to_names = names.index_by { |name| normalize_key(name, options) } + + local_entries = local_cache.read_multi_entries(keys_to_names.keys) + + results = local_entries.each_with_object({}) do |(key, value), result| + next if value.nil? # recorded cache miss + + entry = deserialize_entry(value, **options) + + normalized_key = keys_to_names[key] + if entry.nil? + result[normalized_key] = nil + elsif entry.expired? || entry.mismatched?(normalize_version(normalized_key, options)) + local_cache.delete_entry(key) + else + result[normalized_key] = entry.value + end + end + + if results.size < names.size + results.merge!(super(names - results.keys, **options)) + end + + results + end + + def write_serialized_entry(key, payload, **) + if return_value = super + local_cache.write_entry(key, payload) if local_cache + else + local_cache.delete_entry(key) if local_cache + end + return_value + end + + def delete_entry(key, **) + local_cache.delete_entry(key) if local_cache + super + end + + def write_cache_value(name, value, **options) + name = normalize_key(name, options) + cache = local_cache + if value + cache.write_entry(name, serialize_entry(new_entry(value, **options), **options)) + else + cache.delete_entry(name) + end + end + + def local_cache_key + @local_cache_key ||= "#{self.class.name.underscore}_local_cache_#{object_id}".gsub(/[\/-]/, "_").to_sym + end + + def local_cache + LocalCacheRegistry.cache_for(local_cache_key) + end + + def bypass_local_cache(&block) + use_temporary_local_cache(nil, &block) + end + + def use_temporary_local_cache(temporary_cache) + save_cache = LocalCacheRegistry.cache_for(local_cache_key) + begin + LocalCacheRegistry.set_cache_for(local_cache_key, temporary_cache) + yield + ensure + LocalCacheRegistry.set_cache_for(local_cache_key, save_cache) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/strategy/local_cache_middleware.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/strategy/local_cache_middleware.rb new file mode 100644 index 00000000..62542bdb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/cache/strategy/local_cache_middleware.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require "rack/body_proxy" +require "rack/utils" + +module ActiveSupport + module Cache + module Strategy + module LocalCache + #-- + # This class wraps up local storage for middlewares. Only the middleware method should + # construct them. + class Middleware # :nodoc: + attr_reader :name, :local_cache_key + + def initialize(name, local_cache_key) + @name = name + @local_cache_key = local_cache_key + @app = nil + end + + def new(app) + @app = app + self + end + + def call(env) + LocalCacheRegistry.set_cache_for(local_cache_key, LocalStore.new) + response = @app.call(env) + response[2] = ::Rack::BodyProxy.new(response[2]) do + LocalCacheRegistry.set_cache_for(local_cache_key, nil) + end + cleanup_on_body_close = true + response + rescue Rack::Utils::InvalidParameterError + [400, {}, []] + ensure + LocalCacheRegistry.set_cache_for(local_cache_key, nil) unless + cleanup_on_body_close + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/callbacks.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/callbacks.rb new file mode 100644 index 00000000..ea3c3ccb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/callbacks.rb @@ -0,0 +1,948 @@ +# frozen_string_literal: true + +require "active_support/concern" +require "active_support/descendants_tracker" +require "active_support/core_ext/array/extract_options" +require "active_support/core_ext/class/attribute" +require "active_support/core_ext/string/filters" +require "active_support/core_ext/object/blank" + +module ActiveSupport + # = Active Support \Callbacks + # + # \Callbacks are code hooks that are run at key points in an object's life cycle. + # The typical use case is to have a base class define a set of callbacks + # relevant to the other functionality it supplies, so that subclasses can + # install callbacks that enhance or modify the base functionality without + # needing to override or redefine methods of the base class. + # + # Mixing in this module allows you to define the events in the object's + # life cycle that will support callbacks (via ClassMethods#define_callbacks), + # set the instance methods, procs, or callback objects to be called (via + # ClassMethods#set_callback), and run the installed callbacks at the + # appropriate times (via +run_callbacks+). + # + # By default callbacks are halted by throwing +:abort+. + # See ClassMethods#define_callbacks for details. + # + # Three kinds of callbacks are supported: before callbacks, run before a + # certain event; after callbacks, run after the event; and around callbacks, + # blocks that surround the event, triggering it when they yield. Callback code + # can be contained in instance methods, procs or lambdas, or callback objects + # that respond to certain predetermined methods. See ClassMethods#set_callback + # for details. + # + # class Record + # include ActiveSupport::Callbacks + # define_callbacks :save + # + # def save + # run_callbacks :save do + # puts "- save" + # end + # end + # end + # + # class PersonRecord < Record + # set_callback :save, :before, :saving_message + # def saving_message + # puts "saving..." + # end + # + # set_callback :save, :after do |object| + # puts "saved" + # end + # end + # + # person = PersonRecord.new + # person.save + # + # Output: + # saving... + # - save + # saved + module Callbacks + extend Concern + + included do + extend ActiveSupport::DescendantsTracker + class_attribute :__callbacks, instance_writer: false, instance_predicate: false, default: {} + end + + CALLBACK_FILTER_TYPES = [:before, :after, :around].freeze + + # Runs the callbacks for the given event. + # + # Calls the before and around callbacks in the order they were set, yields + # the block (if given one), and then runs the after callbacks in reverse + # order. + # + # If the callback chain was halted, returns +false+. Otherwise returns the + # result of the block, +nil+ if no callbacks have been set, or +true+ + # if callbacks have been set but no block is given. + # + # run_callbacks :save do + # save + # end + # + #-- + # + # As this method is used in many places, and often wraps large portions of + # user code, it has an additional design goal of minimizing its impact on + # the visible call stack. An exception from inside a :before or :after + # callback can be as noisy as it likes -- but when control has passed + # smoothly through and into the supplied block, we want as little evidence + # as possible that we were here. + def run_callbacks(kind, type = nil) + callbacks = __callbacks[kind.to_sym] + + if callbacks.empty? + yield if block_given? + else + env = Filters::Environment.new(self, false, nil) + + next_sequence = callbacks.compile(type) + + # Common case: no 'around' callbacks defined + if next_sequence.final? + next_sequence.invoke_before(env) + env.value = !env.halted && (!block_given? || yield) + next_sequence.invoke_after(env) + env.value + else + invoke_sequence = Proc.new do + skipped = nil + + while true + current = next_sequence + current.invoke_before(env) + if current.final? + env.value = !env.halted && (!block_given? || yield) + elsif current.skip?(env) + (skipped ||= []) << current + next_sequence = next_sequence.nested + next + else + next_sequence = next_sequence.nested + begin + target, block, method, *arguments = current.expand_call_template(env, invoke_sequence) + target.send(method, *arguments, &block) + ensure + next_sequence = current + end + end + current.invoke_after(env) + skipped.pop.invoke_after(env) while skipped&.first + break env.value + end + end + + invoke_sequence.call + end + end + end + + private + # A hook invoked every time a before callback is halted. + # This can be overridden in ActiveSupport::Callbacks implementors in order + # to provide better debugging/logging. + def halted_callback_hook(filter, name) + end + + module Conditionals # :nodoc: all + class Value + def initialize(&block) + @block = block + end + def call(target, value); @block.call(value); end + end + end + + module Filters # :nodoc: all + Environment = Struct.new(:target, :halted, :value) + + class Before + def initialize(user_callback, user_conditions, chain_config, filter, name) + halted_lambda = chain_config[:terminator] + @user_callback, @user_conditions, @halted_lambda, @filter, @name = user_callback, user_conditions, halted_lambda, filter, name + freeze + end + attr_reader :user_callback, :user_conditions, :halted_lambda, :filter, :name + + def call(env) + target = env.target + value = env.value + halted = env.halted + + if !halted && user_conditions.all? { |c| c.call(target, value) } + result_lambda = -> { user_callback.call target, value } + env.halted = halted_lambda.call(target, result_lambda) + if env.halted + target.send :halted_callback_hook, filter, name + end + end + + env + end + + def apply(callback_sequence) + callback_sequence.before(self) + end + end + + class After + attr_reader :user_callback, :user_conditions, :halting + def initialize(user_callback, user_conditions, chain_config) + halting = chain_config[:skip_after_callbacks_if_terminated] + @user_callback, @user_conditions, @halting = user_callback, user_conditions, halting + freeze + end + + def call(env) + target = env.target + value = env.value + halted = env.halted + + if (!halted || !@halting) && user_conditions.all? { |c| c.call(target, value) } + user_callback.call target, value + end + + env + end + + def apply(callback_sequence) + callback_sequence.after(self) + end + end + + class Around + def initialize(user_callback, user_conditions) + @user_callback, @user_conditions = user_callback, user_conditions + freeze + end + + def apply(callback_sequence) + callback_sequence.around(@user_callback, @user_conditions) + end + end + end + + class Callback # :nodoc: + def self.build(chain, filter, kind, options) + if filter.is_a?(String) + raise ArgumentError, <<-MSG.squish + Passing string to define a callback is not supported. See the `.set_callback` + documentation to see supported values. + MSG + end + + new chain.name, filter, kind, options, chain.config + end + + attr_accessor :kind, :name + attr_reader :chain_config, :filter + + def initialize(name, filter, kind, options, chain_config) + @chain_config = chain_config + @name = name + @kind = kind + @filter = filter + @if = check_conditionals(options[:if]) + @unless = check_conditionals(options[:unless]) + + compiled + end + + def merge_conditional_options(chain, if_option:, unless_option:) + options = { + if: @if.dup, + unless: @unless.dup + } + + options[:if].concat Array(unless_option) + options[:unless].concat Array(if_option) + + self.class.build chain, @filter, @kind, options + end + + def matches?(_kind, _filter) + @kind == _kind && filter == _filter + end + + def duplicates?(other) + case @filter + when Symbol + matches?(other.kind, other.filter) + else + false + end + end + + def compiled + @compiled ||= + begin + user_conditions = conditions_lambdas + user_callback = CallTemplate.build(@filter, self) + + case kind + when :before + Filters::Before.new(user_callback.make_lambda, user_conditions, chain_config, @filter, name) + when :after + Filters::After.new(user_callback.make_lambda, user_conditions, chain_config) + when :around + Filters::Around.new(user_callback, user_conditions) + end + end + end + + # Wraps code with filter + def apply(callback_sequence) + compiled.apply(callback_sequence) + end + + def current_scopes + Array(chain_config[:scope]).map { |s| public_send(s) } + end + + private + EMPTY_ARRAY = [].freeze + private_constant :EMPTY_ARRAY + + def check_conditionals(conditionals) + return EMPTY_ARRAY if conditionals.blank? + + conditionals = Array(conditionals) + if conditionals.any?(String) + raise ArgumentError, <<-MSG.squish + Passing string to be evaluated in :if and :unless conditional + options is not supported. Pass a symbol for an instance method, + or a lambda, proc or block, instead. + MSG + end + + conditionals.freeze + end + + def conditions_lambdas + conditions = + @if.map { |c| CallTemplate.build(c, self).make_lambda } + + @unless.map { |c| CallTemplate.build(c, self).inverted_lambda } + conditions.empty? ? EMPTY_ARRAY : conditions + end + end + + # A future invocation of user-supplied code (either as a callback, + # or a condition filter). + module CallTemplate # :nodoc: all + class MethodCall + def initialize(method) + @method_name = method + end + + # Return the parts needed to make this call, with the given + # input values. + # + # Returns an array of the form: + # + # [target, block, method, *arguments] + # + # This array can be used as such: + # + # target.send(method, *arguments, &block) + # + # The actual invocation is left up to the caller to minimize + # call stack pollution. + def expand(target, value, block) + [target, block, @method_name] + end + + def make_lambda + lambda do |target, value, &block| + target.send(@method_name, &block) + end + end + + def inverted_lambda + lambda do |target, value, &block| + !target.send(@method_name, &block) + end + end + end + + class ObjectCall + def initialize(target, method) + @override_target = target + @method_name = method + end + + def expand(target, value, block) + [@override_target || target, block, @method_name, target] + end + + def make_lambda + lambda do |target, value, &block| + (@override_target || target).send(@method_name, target, &block) + end + end + + def inverted_lambda + lambda do |target, value, &block| + !(@override_target || target).send(@method_name, target, &block) + end + end + end + + class InstanceExec0 + def initialize(block) + @override_block = block + end + + def expand(target, value, block) + [target, @override_block, :instance_exec] + end + + def make_lambda + lambda do |target, value, &block| + target.instance_exec(&@override_block) + end + end + + def inverted_lambda + lambda do |target, value, &block| + !target.instance_exec(&@override_block) + end + end + end + + class InstanceExec1 + def initialize(block) + @override_block = block + end + + def expand(target, value, block) + [target, @override_block, :instance_exec, target] + end + + def make_lambda + lambda do |target, value, &block| + target.instance_exec(target, &@override_block) + end + end + + def inverted_lambda + lambda do |target, value, &block| + !target.instance_exec(target, &@override_block) + end + end + end + + class InstanceExec2 + def initialize(block) + @override_block = block + end + + def expand(target, value, block) + raise ArgumentError unless block + [target, @override_block || block, :instance_exec, target, block] + end + + def make_lambda + lambda do |target, value, &block| + raise ArgumentError unless block + target.instance_exec(target, block, &@override_block) + end + end + + def inverted_lambda + lambda do |target, value, &block| + raise ArgumentError unless block + !target.instance_exec(target, block, &@override_block) + end + end + end + + class ProcCall + def initialize(target) + @override_target = target + end + + def expand(target, value, block) + [@override_target || target, block, :call, target, value] + end + + def make_lambda + lambda do |target, value, &block| + (@override_target || target).call(target, value, &block) + end + end + + def inverted_lambda + lambda do |target, value, &block| + !(@override_target || target).call(target, value, &block) + end + end + end + + # Filters support: + # + # Symbols:: A method to call. + # Procs:: A proc to call with the object. + # Objects:: An object with a before_foo method on it to call. + # + # All of these objects are converted into a CallTemplate and handled + # the same after this point. + def self.build(filter, callback) + case filter + when Symbol + MethodCall.new(filter) + when Conditionals::Value + ProcCall.new(filter) + when ::Proc + case filter.arity + when 2 + InstanceExec2.new(filter) + when 1, -2 + InstanceExec1.new(filter) + else + InstanceExec0.new(filter) + end + else + ObjectCall.new(filter, callback.current_scopes.join("_").to_sym) + end + end + end + + # Execute before and after filters in a sequence instead of + # chaining them with nested lambda calls, see: + # https://github.com/rails/rails/issues/18011 + class CallbackSequence # :nodoc: + def initialize(nested = nil, call_template = nil, user_conditions = nil) + @nested = nested + @call_template = call_template + @user_conditions = user_conditions + + @before = nil + @after = nil + end + + def before(before) + @before ||= [] + @before.unshift(before) + self + end + + def after(after) + @after ||= [] + @after.push(after) + self + end + + def around(call_template, user_conditions) + CallbackSequence.new(self, call_template, user_conditions) + end + + def skip?(arg) + arg.halted || !@user_conditions.all? { |c| c.call(arg.target, arg.value) } + end + + attr_reader :nested + + def final? + !@call_template + end + + def expand_call_template(arg, block) + @call_template.expand(arg.target, arg.value, block) + end + + def invoke_before(arg) + @before&.each { |b| b.call(arg) } + end + + def invoke_after(arg) + @after&.each { |a| a.call(arg) } + end + end + + class CallbackChain # :nodoc: + include Enumerable + + attr_reader :name, :config + + def initialize(name, config) + @name = name + @config = { + scope: [:kind], + terminator: default_terminator + }.merge!(config) + @chain = [] + @all_callbacks = nil + @single_callbacks = {} + @mutex = Mutex.new + end + + def each(&block); @chain.each(&block); end + def index(o); @chain.index(o); end + def empty?; @chain.empty?; end + + def insert(index, o) + @all_callbacks = nil + @single_callbacks.clear + @chain.insert(index, o) + end + + def delete(o) + @all_callbacks = nil + @single_callbacks.clear + @chain.delete(o) + end + + def clear + @all_callbacks = nil + @single_callbacks.clear + @chain.clear + self + end + + def initialize_copy(other) + @all_callbacks = nil + @single_callbacks = {} + @chain = other.chain.dup + @mutex = Mutex.new + end + + def compile(type) + if type.nil? + @all_callbacks || @mutex.synchronize do + final_sequence = CallbackSequence.new + @all_callbacks ||= @chain.reverse.inject(final_sequence) do |callback_sequence, callback| + callback.apply(callback_sequence) + end + end + else + @single_callbacks[type] || @mutex.synchronize do + final_sequence = CallbackSequence.new + @single_callbacks[type] ||= @chain.reverse.inject(final_sequence) do |callback_sequence, callback| + type == callback.kind ? callback.apply(callback_sequence) : callback_sequence + end + end + end + end + + def append(*callbacks) + callbacks.each { |c| append_one(c) } + end + + def prepend(*callbacks) + callbacks.each { |c| prepend_one(c) } + end + + protected + attr_reader :chain + + private + def append_one(callback) + @all_callbacks = nil + @single_callbacks.clear + remove_duplicates(callback) + @chain.push(callback) + end + + def prepend_one(callback) + @all_callbacks = nil + @single_callbacks.clear + remove_duplicates(callback) + @chain.unshift(callback) + end + + def remove_duplicates(callback) + @all_callbacks = nil + @single_callbacks.clear + @chain.delete_if { |c| callback.duplicates?(c) } + end + + def default_terminator + Proc.new do |target, result_lambda| + terminate = true + catch(:abort) do + result_lambda.call + terminate = false + end + terminate + end + end + end + + module ClassMethods + def normalize_callback_params(filters, block) # :nodoc: + type = CALLBACK_FILTER_TYPES.include?(filters.first) ? filters.shift : :before + options = filters.extract_options! + filters.unshift(block) if block + [type, filters, options.dup] + end + + # This is used internally to append, prepend and skip callbacks to the + # CallbackChain. + def __update_callbacks(name) # :nodoc: + self.descendants.prepend(self).reverse_each do |target| + chain = target.get_callbacks name + yield target, chain.dup + end + end + + # Install a callback for the given event. + # + # set_callback :save, :before, :before_method + # set_callback :save, :after, :after_method, if: :condition + # set_callback :save, :around, ->(r, block) { stuff; result = block.call; stuff } + # + # The second argument indicates whether the callback is to be run +:before+, + # +:after+, or +:around+ the event. If omitted, +:before+ is assumed. This + # means the first example above can also be written as: + # + # set_callback :save, :before_method + # + # The callback can be specified as a symbol naming an instance method; as a + # proc, lambda, or block; or as an object that responds to a certain method + # determined by the :scope argument to #define_callbacks. + # + # If a proc, lambda, or block is given, its body is evaluated in the context + # of the current object. It can also optionally accept the current object as + # an argument. + # + # Before and around callbacks are called in the order that they are set; + # after callbacks are called in the reverse order. + # + # Around callbacks can access the return value from the event, if it + # wasn't halted, from the +yield+ call. + # + # ===== Options + # + # * :if - A symbol or an array of symbols, each naming an instance + # method or a proc; the callback will be called only when they all return + # a true value. + # + # If a proc is given, its body is evaluated in the context of the + # current object. It can also optionally accept the current object as + # an argument. + # * :unless - A symbol or an array of symbols, each naming an + # instance method or a proc; the callback will be called only when they + # all return a false value. + # + # If a proc is given, its body is evaluated in the context of the + # current object. It can also optionally accept the current object as + # an argument. + # * :prepend - If +true+, the callback will be prepended to the + # existing chain rather than appended. + def set_callback(name, *filter_list, &block) + type, filters, options = normalize_callback_params(filter_list, block) + + self_chain = get_callbacks name + mapped = filters.map do |filter| + Callback.build(self_chain, filter, type, options) + end + + __update_callbacks(name) do |target, chain| + options[:prepend] ? chain.prepend(*mapped) : chain.append(*mapped) + target.set_callbacks name, chain + end + end + + # Skip a previously set callback. Like #set_callback, :if or + # :unless options may be passed in order to control when the + # callback is skipped. + # + # Note: this example uses +PersonRecord+ and +#saving_message+, which you + # can see defined here[rdoc-ref:ActiveSupport::Callbacks] + # + # class Writer < PersonRecord + # attr_accessor :age + # skip_callback :save, :before, :saving_message, if: -> { age > 18 } + # end + # + # When if option returns true, callback is skipped. + # + # writer = Writer.new + # writer.age = 20 + # writer.save + # + # Output: + # - save + # saved + # + # When if option returns false, callback is NOT skipped. + # + # young_writer = Writer.new + # young_writer.age = 17 + # young_writer.save + # + # Output: + # saving... + # - save + # saved + # + # An ArgumentError will be raised if the callback has not + # already been set (unless the :raise option is set to false). + def skip_callback(name, *filter_list, &block) + type, filters, options = normalize_callback_params(filter_list, block) + + options[:raise] = true unless options.key?(:raise) + + __update_callbacks(name) do |target, chain| + filters.each do |filter| + callback = chain.find { |c| c.matches?(type, filter) } + + if !callback && options[:raise] + raise ArgumentError, "#{type.to_s.capitalize} #{name} callback #{filter.inspect} has not been defined" + end + + if callback && (options.key?(:if) || options.key?(:unless)) + new_callback = callback.merge_conditional_options(chain, if_option: options[:if], unless_option: options[:unless]) + chain.insert(chain.index(callback), new_callback) + end + + chain.delete(callback) + end + target.set_callbacks name, chain + end + end + + # Remove all set callbacks for the given event. + def reset_callbacks(name) + callbacks = get_callbacks name + + self.descendants.each do |target| + chain = target.get_callbacks(name).dup + callbacks.each { |c| chain.delete(c) } + target.set_callbacks name, chain + end + + set_callbacks(name, callbacks.dup.clear) + end + + # Define sets of events in the object life cycle that support callbacks. + # + # define_callbacks :validate + # define_callbacks :initialize, :save, :destroy + # + # ===== Options + # + # * :terminator - Determines when a before filter will halt the + # callback chain, preventing following before and around callbacks from + # being called and the event from being triggered. + # This should be a lambda to be executed. + # The current object and the result lambda of the callback will be provided + # to the terminator lambda. + # + # define_callbacks :validate, terminator: ->(target, result_lambda) { result_lambda.call == false } + # + # In this example, if any before validate callbacks returns +false+, + # any successive before and around callback is not executed. + # + # The default terminator halts the chain when a callback throws +:abort+. + # + # * :skip_after_callbacks_if_terminated - Determines if after + # callbacks should be terminated by the :terminator option. By + # default after callbacks are executed no matter if callback chain was + # terminated or not. This option has no effect if :terminator + # option is set to +nil+. + # + # * :scope - Indicates which methods should be executed when an + # object is used as a callback. + # + # class Audit + # def before(caller) + # puts 'Audit: before is called' + # end + # + # def before_save(caller) + # puts 'Audit: before_save is called' + # end + # end + # + # class Account + # include ActiveSupport::Callbacks + # + # define_callbacks :save + # set_callback :save, :before, Audit.new + # + # def save + # run_callbacks :save do + # puts 'save in main' + # end + # end + # end + # + # In the above case whenever you save an account the method + # Audit#before will be called. On the other hand + # + # define_callbacks :save, scope: [:kind, :name] + # + # would trigger Audit#before_save instead. That's constructed + # by calling #{kind}_#{name} on the given instance. In this + # case "kind" is "before" and "name" is "save". In this context +:kind+ + # and +:name+ have special meanings: +:kind+ refers to the kind of + # callback (before/after/around) and +:name+ refers to the method on + # which callbacks are being defined. + # + # A declaration like + # + # define_callbacks :save, scope: [:name] + # + # would call Audit#save. + # + # ===== Notes + # + # +names+ passed to +define_callbacks+ must not end with + # !, ? or =. + # + # Calling +define_callbacks+ multiple times with the same +names+ will + # overwrite previous callbacks registered with #set_callback. + def define_callbacks(*names) + options = names.extract_options! + + names.each do |name| + name = name.to_sym + + ([self] + self.descendants).each do |target| + target.set_callbacks name, CallbackChain.new(name, options) + end + + module_eval <<-RUBY, __FILE__, __LINE__ + 1 + def _run_#{name}_callbacks(&block) + run_callbacks #{name.inspect}, &block + end + + def self._#{name}_callbacks + get_callbacks(#{name.inspect}) + end + + def self._#{name}_callbacks=(value) + set_callbacks(#{name.inspect}, value) + end + + def _#{name}_callbacks + __callbacks[#{name.inspect}] + end + RUBY + end + end + + protected + def get_callbacks(name) # :nodoc: + __callbacks[name.to_sym] + end + + def set_callbacks(name, callbacks) # :nodoc: + # HACK: We're making assumption on how `class_attribute` is implemented + # to save constantly duping the callback hash. If this desync with class_attribute + # we'll lose the optimization, but won't cause an actual behavior bug. + unless singleton_class.private_method_defined?(:__class_attr__callbacks, false) + self.__callbacks = __callbacks.dup + end + self.__callbacks[name.to_sym] = callbacks + self.__callbacks + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/class_attribute.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/class_attribute.rb new file mode 100644 index 00000000..8aac26e3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/class_attribute.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +module ActiveSupport + module ClassAttribute # :nodoc: + class << self + def redefine(owner, name, namespaced_name, value) + if owner.singleton_class? + if owner.attached_object.is_a?(Module) + redefine_method(owner, namespaced_name, private: true) { value } + else + redefine_method(owner, name) { value } + end + end + + redefine_method(owner.singleton_class, namespaced_name, private: true) { value } + + redefine_method(owner.singleton_class, "#{namespaced_name}=", private: true) do |new_value| + if owner.equal?(self) + value = new_value + else + ::ActiveSupport::ClassAttribute.redefine(self, name, namespaced_name, new_value) + end + end + end + + def redefine_method(owner, name, private: false, &block) + owner.silence_redefinition_of_method(name) + owner.define_method(name, &block) + owner.send(:private, name) if private + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/code_generator.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/code_generator.rb new file mode 100644 index 00000000..26eabb1b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/code_generator.rb @@ -0,0 +1,79 @@ +# frozen_string_literal: true + +module ActiveSupport + class CodeGenerator # :nodoc: + class MethodSet + METHOD_CACHES = Hash.new { |h, k| h[k] = Module.new } + + def initialize(namespace) + @cache = METHOD_CACHES[namespace] + @sources = [] + @methods = {} + @canonical_methods = {} + end + + def define_cached_method(canonical_name, as: nil) + canonical_name = canonical_name.to_sym + as = (as || canonical_name).to_sym + + @methods.fetch(as) do + unless @cache.method_defined?(canonical_name) || @canonical_methods[canonical_name] + yield @sources + end + @canonical_methods[canonical_name] = true + @methods[as] = canonical_name + end + end + + def apply(owner, path, line) + unless @sources.empty? + @cache.module_eval("# frozen_string_literal: true\n" + @sources.join(";"), path, line) + end + @canonical_methods.clear + + @methods.each do |as, canonical_name| + owner.define_method(as, @cache.instance_method(canonical_name)) + end + end + end + + class << self + def batch(owner, path, line) + if owner.is_a?(CodeGenerator) + yield owner + else + instance = new(owner, path, line) + result = yield instance + instance.execute + result + end + end + end + + def initialize(owner, path, line) + @owner = owner + @path = path + @line = line + @namespaces = Hash.new { |h, k| h[k] = MethodSet.new(k) } + @sources = [] + end + + def class_eval + yield @sources + end + + def define_cached_method(canonical_name, namespace:, as: nil, &block) + @namespaces[namespace].define_cached_method(canonical_name, as: as, &block) + end + + def execute + @namespaces.each_value do |method_set| + method_set.apply(@owner, @path, @line - 1) + end + + unless @sources.empty? + @owner.class_eval("# frozen_string_literal: true\n" + @sources.join(";"), @path, @line - 1) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/concern.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/concern.rb new file mode 100644 index 00000000..7af9c75c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/concern.rb @@ -0,0 +1,217 @@ +# frozen_string_literal: true + +module ActiveSupport + # = Active Support \Concern + # + # A typical module looks like this: + # + # module M + # def self.included(base) + # base.extend ClassMethods + # base.class_eval do + # scope :disabled, -> { where(disabled: true) } + # end + # end + # + # module ClassMethods + # ... + # end + # end + # + # By using +ActiveSupport::Concern+ the above module could instead be + # written as: + # + # require "active_support/concern" + # + # module M + # extend ActiveSupport::Concern + # + # included do + # scope :disabled, -> { where(disabled: true) } + # end + # + # class_methods do + # ... + # end + # end + # + # Moreover, it gracefully handles module dependencies. Given a +Foo+ module + # and a +Bar+ module which depends on the former, we would typically write the + # following: + # + # module Foo + # def self.included(base) + # base.class_eval do + # def self.method_injected_by_foo + # ... + # end + # end + # end + # end + # + # module Bar + # def self.included(base) + # base.method_injected_by_foo + # end + # end + # + # class Host + # include Foo # We need to include this dependency for Bar + # include Bar # Bar is the module that Host really needs + # end + # + # But why should +Host+ care about +Bar+'s dependencies, namely +Foo+? We + # could try to hide these from +Host+ directly including +Foo+ in +Bar+: + # + # module Bar + # include Foo + # def self.included(base) + # base.method_injected_by_foo + # end + # end + # + # class Host + # include Bar + # end + # + # Unfortunately this won't work, since when +Foo+ is included, its base + # is the +Bar+ module, not the +Host+ class. With +ActiveSupport::Concern+, + # module dependencies are properly resolved: + # + # require "active_support/concern" + # + # module Foo + # extend ActiveSupport::Concern + # included do + # def self.method_injected_by_foo + # ... + # end + # end + # end + # + # module Bar + # extend ActiveSupport::Concern + # include Foo + # + # included do + # self.method_injected_by_foo + # end + # end + # + # class Host + # include Bar # It works, now Bar takes care of its dependencies + # end + # + # === Prepending concerns + # + # Just like include, concerns also support prepend with a corresponding + # prepended do callback. module ClassMethods or class_methods do are + # prepended as well. + # + # prepend is also used for any dependencies. + module Concern + class MultipleIncludedBlocks < StandardError # :nodoc: + def initialize + super "Cannot define multiple 'included' blocks for a Concern" + end + end + + class MultiplePrependBlocks < StandardError # :nodoc: + def initialize + super "Cannot define multiple 'prepended' blocks for a Concern" + end + end + + def self.extended(base) # :nodoc: + base.instance_variable_set(:@_dependencies, []) + end + + def append_features(base) # :nodoc: + if base.instance_variable_defined?(:@_dependencies) + base.instance_variable_get(:@_dependencies) << self + false + else + return false if base < self + @_dependencies.each { |dep| base.include(dep) } + super + base.extend const_get(:ClassMethods) if const_defined?(:ClassMethods) + base.class_eval(&@_included_block) if instance_variable_defined?(:@_included_block) + end + end + + def prepend_features(base) # :nodoc: + if base.instance_variable_defined?(:@_dependencies) + base.instance_variable_get(:@_dependencies).unshift self + false + else + return false if base < self + @_dependencies.each { |dep| base.prepend(dep) } + super + base.singleton_class.prepend const_get(:ClassMethods) if const_defined?(:ClassMethods) + base.class_eval(&@_prepended_block) if instance_variable_defined?(:@_prepended_block) + end + end + + # Evaluate given block in context of base class, + # so that you can write class macros here. + # When you define more than one +included+ block, it raises an exception. + def included(base = nil, &block) + if base.nil? + if instance_variable_defined?(:@_included_block) + if @_included_block.source_location != block.source_location + raise MultipleIncludedBlocks + end + else + @_included_block = block + end + else + super + end + end + + # Evaluate given block in context of base class, + # so that you can write class macros here. + # When you define more than one +prepended+ block, it raises an exception. + def prepended(base = nil, &block) + if base.nil? + if instance_variable_defined?(:@_prepended_block) + if @_prepended_block.source_location != block.source_location + raise MultiplePrependBlocks + end + else + @_prepended_block = block + end + else + super + end + end + + # Define class methods from given block. + # You can define private class methods as well. + # + # module Example + # extend ActiveSupport::Concern + # + # class_methods do + # def foo; puts 'foo'; end + # + # private + # def bar; puts 'bar'; end + # end + # end + # + # class Buzz + # include Example + # end + # + # Buzz.foo # => "foo" + # Buzz.bar # => private method 'bar' called for Buzz:Class(NoMethodError) + def class_methods(&class_methods_module_definition) + mod = const_defined?(:ClassMethods, false) ? + const_get(:ClassMethods) : + const_set(:ClassMethods, Module.new) + + mod.module_eval(&class_methods_module_definition) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/concurrency/load_interlock_aware_monitor.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/concurrency/load_interlock_aware_monitor.rb new file mode 100644 index 00000000..84729e25 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/concurrency/load_interlock_aware_monitor.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +require "monitor" + +module ActiveSupport + module Concurrency + module LoadInterlockAwareMonitorMixin # :nodoc: + EXCEPTION_NEVER = { Exception => :never }.freeze + EXCEPTION_IMMEDIATE = { Exception => :immediate }.freeze + private_constant :EXCEPTION_NEVER, :EXCEPTION_IMMEDIATE + + # Enters an exclusive section, but allows dependency loading while blocked + def mon_enter + mon_try_enter || + ActiveSupport::Dependencies.interlock.permit_concurrent_loads { super } + end + + def synchronize(&block) + Thread.handle_interrupt(EXCEPTION_NEVER) do + mon_enter + + begin + Thread.handle_interrupt(EXCEPTION_IMMEDIATE, &block) + ensure + mon_exit + end + end + end + end + # A monitor that will permit dependency loading while blocked waiting for + # the lock. + class LoadInterlockAwareMonitor < Monitor + include LoadInterlockAwareMonitorMixin + end + + class ThreadLoadInterlockAwareMonitor # :nodoc: + prepend LoadInterlockAwareMonitorMixin + + def initialize + @owner = nil + @count = 0 + @mutex = Mutex.new + end + + private + def mon_try_enter + if @owner != Thread.current + return false unless @mutex.try_lock + @owner = Thread.current + end + @count += 1 + end + + def mon_enter + @mutex.lock if @owner != Thread.current + @owner = Thread.current + @count += 1 + end + + def mon_exit + unless @owner == Thread.current + raise ThreadError, "current thread not owner" + end + + @count -= 1 + return unless @count == 0 + @owner = nil + @mutex.unlock + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/concurrency/null_lock.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/concurrency/null_lock.rb new file mode 100644 index 00000000..3810158f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/concurrency/null_lock.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module ActiveSupport + module Concurrency + module NullLock # :nodoc: + extend self + + def synchronize + yield + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/concurrency/share_lock.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/concurrency/share_lock.rb new file mode 100644 index 00000000..3bfb1aee --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/concurrency/share_lock.rb @@ -0,0 +1,225 @@ +# frozen_string_literal: true + +require "monitor" + +module ActiveSupport + module Concurrency + # A share/exclusive lock, otherwise known as a read/write lock. + # + # https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock + class ShareLock + include MonitorMixin + + # We track Thread objects, instead of just using counters, because + # we need exclusive locks to be reentrant, and we need to be able + # to upgrade share locks to exclusive. + + def raw_state # :nodoc: + synchronize do + threads = @sleeping.keys | @sharing.keys | @waiting.keys + threads |= [@exclusive_thread] if @exclusive_thread + + data = {} + + threads.each do |thread| + purpose, compatible = @waiting[thread] + + data[thread] = { + thread: thread, + sharing: @sharing[thread], + exclusive: @exclusive_thread == thread, + purpose: purpose, + compatible: compatible, + waiting: !!@waiting[thread], + sleeper: @sleeping[thread], + } + end + + # NB: Yields while holding our *internal* synchronize lock, + # which is supposed to be used only for a few instructions at + # a time. This allows the caller to inspect additional state + # without things changing out from underneath, but would have + # disastrous effects upon normal operation. Fortunately, this + # method is only intended to be called when things have + # already gone wrong. + yield data + end + end + + def initialize + super() + + @cv = new_cond + + @sharing = Hash.new(0) + @waiting = {} + @sleeping = {} + @exclusive_thread = nil + @exclusive_depth = 0 + end + + # Returns false if +no_wait+ is set and the lock is not + # immediately available. Otherwise, returns true after the lock + # has been acquired. + # + # +purpose+ and +compatible+ work together; while this thread is + # waiting for the exclusive lock, it will yield its share (if any) + # to any other attempt whose +purpose+ appears in this attempt's + # +compatible+ list. This allows a "loose" upgrade, which, being + # less strict, prevents some classes of deadlocks. + # + # For many resources, loose upgrades are sufficient: if a thread + # is awaiting a lock, it is not running any other code. With + # +purpose+ matching, it is possible to yield only to other + # threads whose activity will not interfere. + def start_exclusive(purpose: nil, compatible: [], no_wait: false) + synchronize do + unless @exclusive_thread == Thread.current + if busy_for_exclusive?(purpose) + return false if no_wait + + yield_shares(purpose: purpose, compatible: compatible, block_share: true) do + wait_for(:start_exclusive) { busy_for_exclusive?(purpose) } + end + end + @exclusive_thread = Thread.current + end + @exclusive_depth += 1 + + true + end + end + + # Relinquish the exclusive lock. Must only be called by the thread + # that called start_exclusive (and currently holds the lock). + def stop_exclusive(compatible: []) + synchronize do + raise "invalid unlock" if @exclusive_thread != Thread.current + + @exclusive_depth -= 1 + if @exclusive_depth == 0 + @exclusive_thread = nil + + if eligible_waiters?(compatible) + yield_shares(compatible: compatible, block_share: true) do + wait_for(:stop_exclusive) { @exclusive_thread || eligible_waiters?(compatible) } + end + end + @cv.broadcast + end + end + end + + def start_sharing + synchronize do + if @sharing[Thread.current] > 0 || @exclusive_thread == Thread.current + # We already hold a lock; nothing to wait for + elsif @waiting[Thread.current] + # We're nested inside a +yield_shares+ call: we'll resume as + # soon as there isn't an exclusive lock in our way + wait_for(:start_sharing) { @exclusive_thread } + else + # This is an initial / outermost share call: any outstanding + # requests for an exclusive lock get to go first + wait_for(:start_sharing) { busy_for_sharing?(false) } + end + @sharing[Thread.current] += 1 + end + end + + def stop_sharing + synchronize do + if @sharing[Thread.current] > 1 + @sharing[Thread.current] -= 1 + else + @sharing.delete Thread.current + @cv.broadcast + end + end + end + + # Execute the supplied block while holding the Exclusive lock. If + # +no_wait+ is set and the lock is not immediately available, + # returns +nil+ without yielding. Otherwise, returns the result of + # the block. + # + # See +start_exclusive+ for other options. + def exclusive(purpose: nil, compatible: [], after_compatible: [], no_wait: false) + if start_exclusive(purpose: purpose, compatible: compatible, no_wait: no_wait) + begin + yield + ensure + stop_exclusive(compatible: after_compatible) + end + end + end + + # Execute the supplied block while holding the Share lock. + def sharing + start_sharing + begin + yield + ensure + stop_sharing + end + end + + # Temporarily give up all held Share locks while executing the + # supplied block, allowing any +compatible+ exclusive lock request + # to proceed. + def yield_shares(purpose: nil, compatible: [], block_share: false) + loose_shares = previous_wait = nil + synchronize do + if loose_shares = @sharing.delete(Thread.current) + if previous_wait = @waiting[Thread.current] + purpose = nil unless purpose == previous_wait[0] + compatible &= previous_wait[1] + end + compatible |= [false] unless block_share + @waiting[Thread.current] = [purpose, compatible] + end + + @cv.broadcast + end + + begin + yield + ensure + synchronize do + wait_for(:yield_shares) { @exclusive_thread && @exclusive_thread != Thread.current } + + if previous_wait + @waiting[Thread.current] = previous_wait + else + @waiting.delete Thread.current + end + @sharing[Thread.current] = loose_shares if loose_shares + end + end + end + + private + # Must be called within synchronize + def busy_for_exclusive?(purpose) + busy_for_sharing?(purpose) || + @sharing.size > (@sharing[Thread.current] > 0 ? 1 : 0) + end + + def busy_for_sharing?(purpose) + (@exclusive_thread && @exclusive_thread != Thread.current) || + @waiting.any? { |t, (_, c)| t != Thread.current && !c.include?(purpose) } + end + + def eligible_waiters?(compatible) + @waiting.any? { |t, (p, _)| compatible.include?(p) && @waiting.all? { |t2, (_, c2)| t == t2 || c2.include?(p) } } + end + + def wait_for(method, &block) + @sleeping[Thread.current] = method + @cv.wait_while(&block) + ensure + @sleeping.delete Thread.current + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/configurable.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/configurable.rb new file mode 100644 index 00000000..1e9b8028 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/configurable.rb @@ -0,0 +1,159 @@ +# frozen_string_literal: true + +require "active_support/concern" +require "active_support/ordered_options" + +module ActiveSupport + # = Active Support \Configurable + # + # Configurable provides a config method to store and retrieve + # configuration options as an OrderedOptions. + module Configurable + extend ActiveSupport::Concern + + class Configuration < ActiveSupport::InheritableOptions + def compile_methods! + self.class.compile_methods!(keys) + end + + # Compiles reader methods so we don't have to go through method_missing. + def self.compile_methods!(keys) + keys.reject { |m| method_defined?(m) }.each do |key| + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{key}; _get(#{key.inspect}); end + RUBY + end + end + end + + module ClassMethods + def config + @_config ||= if respond_to?(:superclass) && superclass.respond_to?(:config) + superclass.config.inheritable_copy + else + # create a new "anonymous" class that will host the compiled reader methods + Class.new(Configuration).new + end + end + + def configure + yield config + end + + # Allows you to add shortcut so that you don't have to refer to attribute + # through config. Also look at the example for config to contrast. + # + # Defines both class and instance config accessors. + # + # class User + # include ActiveSupport::Configurable + # config_accessor :allowed_access + # end + # + # User.allowed_access # => nil + # User.allowed_access = false + # User.allowed_access # => false + # + # user = User.new + # user.allowed_access # => false + # user.allowed_access = true + # user.allowed_access # => true + # + # User.allowed_access # => false + # + # The attribute name must be a valid method name in Ruby. + # + # class User + # include ActiveSupport::Configurable + # config_accessor :"1_Badname" + # end + # # => NameError: invalid config attribute name + # + # To omit the instance writer method, pass instance_writer: false. + # To omit the instance reader method, pass instance_reader: false. + # + # class User + # include ActiveSupport::Configurable + # config_accessor :allowed_access, instance_reader: false, instance_writer: false + # end + # + # User.allowed_access = false + # User.allowed_access # => false + # + # User.new.allowed_access = true # => NoMethodError + # User.new.allowed_access # => NoMethodError + # + # Or pass instance_accessor: false, to omit both instance methods. + # + # class User + # include ActiveSupport::Configurable + # config_accessor :allowed_access, instance_accessor: false + # end + # + # User.allowed_access = false + # User.allowed_access # => false + # + # User.new.allowed_access = true # => NoMethodError + # User.new.allowed_access # => NoMethodError + # + # Also you can pass default or a block to set up the attribute with a default value. + # + # class User + # include ActiveSupport::Configurable + # config_accessor :allowed_access, default: false + # config_accessor :hair_colors do + # [:brown, :black, :blonde, :red] + # end + # end + # + # User.allowed_access # => false + # User.hair_colors # => [:brown, :black, :blonde, :red] + def config_accessor(*names, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil) # :doc: + names.each do |name| + raise NameError.new("invalid config attribute name") unless /\A[_A-Za-z]\w*\z/.match?(name) + + reader, reader_line = "def #{name}; config.#{name}; end", __LINE__ + writer, writer_line = "def #{name}=(value); config.#{name} = value; end", __LINE__ + + singleton_class.class_eval reader, __FILE__, reader_line + singleton_class.class_eval writer, __FILE__, writer_line + + if instance_accessor + class_eval reader, __FILE__, reader_line if instance_reader + class_eval writer, __FILE__, writer_line if instance_writer + end + + send("#{name}=", block_given? ? yield : default) + end + end + private :config_accessor + + private + def inherited(subclass) + super + subclass.class_eval do + @_config = nil + end + end + end + + # Reads and writes attributes from a configuration OrderedOptions. + # + # require "active_support/configurable" + # + # class User + # include ActiveSupport::Configurable + # end + # + # user = User.new + # + # user.config.allowed_access = true + # user.config.level = 1 + # + # user.config.allowed_access # => true + # user.config.level # => 1 + def config + @_config ||= self.class.config.inheritable_copy + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/configuration_file.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/configuration_file.rb new file mode 100644 index 00000000..78cb1c6d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/configuration_file.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +module ActiveSupport + # Reads a YAML configuration file, evaluating any ERB, then + # parsing the resulting YAML. + # + # Warns in case of YAML confusing characters, like invisible + # non-breaking spaces. + class ConfigurationFile # :nodoc: + class FormatError < StandardError; end + + def initialize(content_path) + @content_path = content_path.to_s + @content = read content_path + end + + def self.parse(content_path, **options) + new(content_path).parse(**options) + end + + def parse(context: nil, **options) + source = @content.include?("<%") ? render(context) : @content + + if source == @content + if YAML.respond_to?(:unsafe_load) + YAML.unsafe_load_file(@content_path, **options) || {} + else + YAML.load_file(@content_path, **options) || {} + end + else + if YAML.respond_to?(:unsafe_load) + YAML.unsafe_load(source, **options) || {} + else + YAML.load(source, **options) || {} + end + end + rescue Psych::SyntaxError => error + raise "YAML syntax error occurred while parsing #{@content_path}. " \ + "Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \ + "Error: #{error.message}" + end + + private + def read(content_path) + require "yaml" unless defined?(YAML) + + File.read(content_path).tap do |content| + if content.include?("\u00A0") + warn "#{content_path} contains invisible non-breaking spaces, you may want to remove those" + end + end + end + + def render(context) + require "erb" unless defined?(ERB) + erb = ERB.new(@content).tap { |e| e.filename = @content_path } + context ? erb.result(context) : erb.result + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext.rb new file mode 100644 index 00000000..3f5d0818 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +Dir.glob(File.expand_path("core_ext/*.rb", __dir__)).sort.each do |path| + require path +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/array.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/array.rb new file mode 100644 index 00000000..88b65677 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/array.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +require "active_support/core_ext/array/wrap" +require "active_support/core_ext/array/access" +require "active_support/core_ext/array/conversions" +require "active_support/core_ext/array/extract" +require "active_support/core_ext/array/extract_options" +require "active_support/core_ext/array/grouping" +require "active_support/core_ext/array/inquiry" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/array/access.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/array/access.rb new file mode 100644 index 00000000..8f36669c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/array/access.rb @@ -0,0 +1,100 @@ +# frozen_string_literal: true + +class Array + # Returns the tail of the array from +position+. + # + # %w( a b c d ).from(0) # => ["a", "b", "c", "d"] + # %w( a b c d ).from(2) # => ["c", "d"] + # %w( a b c d ).from(10) # => [] + # %w().from(0) # => [] + # %w( a b c d ).from(-2) # => ["c", "d"] + # %w( a b c ).from(-10) # => [] + def from(position) + self[position, length] || [] + end + + # Returns the beginning of the array up to +position+. + # + # %w( a b c d ).to(0) # => ["a"] + # %w( a b c d ).to(2) # => ["a", "b", "c"] + # %w( a b c d ).to(10) # => ["a", "b", "c", "d"] + # %w().to(0) # => [] + # %w( a b c d ).to(-2) # => ["a", "b", "c"] + # %w( a b c ).to(-10) # => [] + def to(position) + if position >= 0 + take position + 1 + else + self[0..position] + end + end + + # Returns a new array that includes the passed elements. + # + # [ 1, 2, 3 ].including(4, 5) # => [ 1, 2, 3, 4, 5 ] + # [ [ 0, 1 ] ].including([ [ 1, 0 ] ]) # => [ [ 0, 1 ], [ 1, 0 ] ] + def including(*elements) + self + elements.flatten(1) + end + + # Returns a copy of the Array excluding the specified elements. + # + # ["David", "Rafael", "Aaron", "Todd"].excluding("Aaron", "Todd") # => ["David", "Rafael"] + # [ [ 0, 1 ], [ 1, 0 ] ].excluding([ [ 1, 0 ] ]) # => [ [ 0, 1 ] ] + # + # Note: This is an optimization of Enumerable#excluding that uses Array#- + # instead of Array#reject for performance reasons. + def excluding(*elements) + self - elements.flatten(1) + end + alias :without :excluding + + # Equal to self[1]. + # + # %w( a b c d e ).second # => "b" + def second + self[1] + end + + # Equal to self[2]. + # + # %w( a b c d e ).third # => "c" + def third + self[2] + end + + # Equal to self[3]. + # + # %w( a b c d e ).fourth # => "d" + def fourth + self[3] + end + + # Equal to self[4]. + # + # %w( a b c d e ).fifth # => "e" + def fifth + self[4] + end + + # Equal to self[41]. Also known as accessing "the reddit". + # + # (1..42).to_a.forty_two # => 42 + def forty_two + self[41] + end + + # Equal to self[-3]. + # + # %w( a b c d e ).third_to_last # => "c" + def third_to_last + self[-3] + end + + # Equal to self[-2]. + # + # %w( a b c d e ).second_to_last # => "d" + def second_to_last + self[-2] + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/array/conversions.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/array/conversions.rb new file mode 100644 index 00000000..125a67d7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/array/conversions.rb @@ -0,0 +1,213 @@ +# frozen_string_literal: true + +require "active_support/core_ext/hash/keys" +require "active_support/core_ext/string/inflections" +require "active_support/core_ext/object/to_param" +require "active_support/core_ext/object/to_query" + +class Array + # Converts the array to a comma-separated sentence where the last element is + # joined by the connector word. + # + # You can pass the following options to change the default behavior. If you + # pass an option key that doesn't exist in the list below, it will raise an + # ArgumentError. + # + # ==== Options + # + # * :words_connector - The sign or word used to join all but the last + # element in arrays with three or more elements (default: ", "). + # * :last_word_connector - The sign or word used to join the last element + # in arrays with three or more elements (default: ", and "). + # * :two_words_connector - The sign or word used to join the elements + # in arrays with two elements (default: " and "). + # * :locale - If +i18n+ is available, you can set a locale and use + # the connector options defined on the 'support.array' namespace in the + # corresponding dictionary file. + # + # ==== Examples + # + # [].to_sentence # => "" + # ['one'].to_sentence # => "one" + # ['one', 'two'].to_sentence # => "one and two" + # ['one', 'two', 'three'].to_sentence # => "one, two, and three" + # + # ['one', 'two'].to_sentence(passing: 'invalid option') + # # => ArgumentError: Unknown key: :passing. Valid keys are: :words_connector, :two_words_connector, :last_word_connector, :locale + # + # ['one', 'two'].to_sentence(two_words_connector: '-') + # # => "one-two" + # + # ['one', 'two', 'three'].to_sentence(words_connector: ' or ', last_word_connector: ' or at least ') + # # => "one or two or at least three" + # + # Using :locale option: + # + # # Given this locale dictionary: + # # + # # es: + # # support: + # # array: + # # words_connector: " o " + # # two_words_connector: " y " + # # last_word_connector: " o al menos " + # + # ['uno', 'dos'].to_sentence(locale: :es) + # # => "uno y dos" + # + # ['uno', 'dos', 'tres'].to_sentence(locale: :es) + # # => "uno o dos o al menos tres" + def to_sentence(options = {}) + options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale) + + default_connectors = { + words_connector: ", ", + two_words_connector: " and ", + last_word_connector: ", and " + } + if options[:locale] != false && defined?(I18n) + i18n_connectors = I18n.translate(:'support.array', locale: options[:locale], default: {}) + default_connectors.merge!(i18n_connectors) + end + options = default_connectors.merge!(options) + + case length + when 0 + +"" + when 1 + +"#{self[0]}" + when 2 + +"#{self[0]}#{options[:two_words_connector]}#{self[1]}" + else + +"#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}" + end + end + + # Extends Array#to_s to convert a collection of elements into a + # comma separated id list if :db argument is given as the format. + # + # This method is aliased to to_formatted_s. + # + # Blog.all.to_fs(:db) # => "1,2,3" + # Blog.none.to_fs(:db) # => "null" + # [1,2].to_fs # => "[1, 2]" + def to_fs(format = :default) + case format + when :db + if empty? + "null" + else + collect(&:id).join(",") + end + else + to_s + end + end + alias_method :to_formatted_s, :to_fs + + # Returns a string that represents the array in XML by invoking +to_xml+ + # on each element. Active Record collections delegate their representation + # in XML to this method. + # + # All elements are expected to respond to +to_xml+, if any of them does + # not then an exception is raised. + # + # The root node reflects the class name of the first element in plural + # if all elements belong to the same type and that's not Hash: + # + # customer.projects.to_xml + # + # + # + # + # 20000.0 + # 1567 + # 2008-04-09 + # ... + # + # + # 57230.0 + # 1567 + # 2008-04-15 + # ... + # + # + # + # Otherwise the root element is "objects": + # + # [{ foo: 1, bar: 2}, { baz: 3}].to_xml + # + # + # + # + # 2 + # 1 + # + # + # 3 + # + # + # + # If the collection is empty the root element is "nil-classes" by default: + # + # [].to_xml + # + # + # + # + # To ensure a meaningful root element use the :root option: + # + # customer_with_no_projects.projects.to_xml(root: 'projects') + # + # + # + # + # By default name of the node for the children of root is root.singularize. + # You can change it with the :children option. + # + # The +options+ hash is passed downwards: + # + # Message.all.to_xml(skip_types: true) + # + # + # + # + # 2008-03-07T09:58:18+01:00 + # 1 + # 1 + # 2008-03-07T09:58:18+01:00 + # 1 + # + # + # + def to_xml(options = {}) + require "active_support/builder" unless defined?(Builder::XmlMarkup) + + options = options.dup + options[:indent] ||= 2 + options[:builder] ||= Builder::XmlMarkup.new(indent: options[:indent]) + options[:root] ||= \ + if first.class != Hash && all?(first.class) + underscored = ActiveSupport::Inflector.underscore(first.class.name) + ActiveSupport::Inflector.pluralize(underscored).tr("/", "_") + else + "objects" + end + + builder = options[:builder] + builder.instruct! unless options.delete(:skip_instruct) + + root = ActiveSupport::XmlMini.rename_key(options[:root].to_s, options) + children = options.delete(:children) || root.singularize + attributes = options[:skip_types] ? {} : { type: "array" } + + if empty? + builder.tag!(root, attributes) + else + builder.tag!(root, attributes) do + each { |value| ActiveSupport::XmlMini.to_tag(children, value, options) } + yield builder if block_given? + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/array/extract.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/array/extract.rb new file mode 100644 index 00000000..cc5a8a3f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/array/extract.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class Array + # Removes and returns the elements for which the block returns a true value. + # If no block is given, an Enumerator is returned instead. + # + # numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + # odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9] + # numbers # => [0, 2, 4, 6, 8] + def extract! + return to_enum(:extract!) { size } unless block_given? + + extracted_elements = [] + + reject! do |element| + extracted_elements << element if yield(element) + end + + extracted_elements + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/array/extract_options.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/array/extract_options.rb new file mode 100644 index 00000000..8c7cb2e7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/array/extract_options.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +class Hash + # By default, only instances of Hash itself are extractable. + # Subclasses of Hash may implement this method and return + # true to declare themselves as extractable. If a Hash + # is extractable, Array#extract_options! pops it from + # the Array when it is the last element of the Array. + def extractable_options? + instance_of?(Hash) + end +end + +class Array + # Extracts options from a set of arguments. Removes and returns the last + # element in the array if it's a hash, otherwise returns a blank hash. + # + # def options(*args) + # args.extract_options! + # end + # + # options(1, 2) # => {} + # options(1, 2, a: :b) # => {:a=>:b} + def extract_options! + if last.is_a?(Hash) && last.extractable_options? + pop + else + {} + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/array/grouping.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/array/grouping.rb new file mode 100644 index 00000000..36993e01 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/array/grouping.rb @@ -0,0 +1,109 @@ +# frozen_string_literal: true + +class Array + # Splits or iterates over the array in groups of size +number+, + # padding any remaining slots with +fill_with+ unless it is +false+. + # + # %w(1 2 3 4 5 6 7 8 9 10).in_groups_of(3) {|group| p group} + # ["1", "2", "3"] + # ["4", "5", "6"] + # ["7", "8", "9"] + # ["10", nil, nil] + # + # %w(1 2 3 4 5).in_groups_of(2, ' ') {|group| p group} + # ["1", "2"] + # ["3", "4"] + # ["5", " "] + # + # %w(1 2 3 4 5).in_groups_of(2, false) {|group| p group} + # ["1", "2"] + # ["3", "4"] + # ["5"] + def in_groups_of(number, fill_with = nil, &block) + if number.to_i <= 0 + raise ArgumentError, + "Group size must be a positive integer, was #{number.inspect}" + end + + if fill_with == false + collection = self + else + # size % number gives how many extra we have; + # subtracting from number gives how many to add; + # modulo number ensures we don't add group of just fill. + padding = (number - size % number) % number + collection = dup.concat(Array.new(padding, fill_with)) + end + + if block_given? + collection.each_slice(number, &block) + else + collection.each_slice(number).to_a + end + end + + # Splits or iterates over the array in +number+ of groups, padding any + # remaining slots with +fill_with+ unless it is +false+. + # + # %w(1 2 3 4 5 6 7 8 9 10).in_groups(3) {|group| p group} + # ["1", "2", "3", "4"] + # ["5", "6", "7", nil] + # ["8", "9", "10", nil] + # + # %w(1 2 3 4 5 6 7 8 9 10).in_groups(3, ' ') {|group| p group} + # ["1", "2", "3", "4"] + # ["5", "6", "7", " "] + # ["8", "9", "10", " "] + # + # %w(1 2 3 4 5 6 7).in_groups(3, false) {|group| p group} + # ["1", "2", "3"] + # ["4", "5"] + # ["6", "7"] + def in_groups(number, fill_with = nil, &block) + # size.div number gives minor group size; + # size % number gives how many objects need extra accommodation; + # each group hold either division or division + 1 items. + division = size.div number + modulo = size % number + + # create a new array avoiding dup + groups = [] + start = 0 + + number.times do |index| + length = division + (modulo > 0 && modulo > index ? 1 : 0) + groups << last_group = slice(start, length) + last_group << fill_with if fill_with != false && + modulo > 0 && length == division + start += length + end + + if block_given? + groups.each(&block) + else + groups + end + end + + # Divides the array into one or more subarrays based on a delimiting +value+ + # or the result of an optional block. + # + # [1, 2, 3, 4, 5].split(3) # => [[1, 2], [4, 5]] + # (1..10).to_a.split { |i| i % 3 == 0 } # => [[1, 2], [4, 5], [7, 8], [10]] + def split(value = nil, &block) + arr = dup + result = [] + if block_given? + while (idx = arr.index(&block)) + result << arr.shift(idx) + arr.shift + end + else + while (idx = arr.index(value)) + result << arr.shift(idx) + arr.shift + end + end + result << arr + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/array/inquiry.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/array/inquiry.rb new file mode 100644 index 00000000..650b1067 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/array/inquiry.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require "active_support/array_inquirer" + +class Array + # Wraps the array in an ActiveSupport::ArrayInquirer object, which gives a + # friendlier way to check its string-like contents. + # + # pets = [:cat, :dog].inquiry + # + # pets.cat? # => true + # pets.ferret? # => false + # + # pets.any?(:cat, :ferret) # => true + # pets.any?(:ferret, :alligator) # => false + def inquiry + ActiveSupport::ArrayInquirer.new(self) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/array/wrap.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/array/wrap.rb new file mode 100644 index 00000000..d62f97ed --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/array/wrap.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +class Array + # Wraps its argument in an array unless it is already an array (or array-like). + # + # Specifically: + # + # * If the argument is +nil+ an empty array is returned. + # * Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned. + # * Otherwise, returns an array with the argument as its single element. + # + # Array.wrap(nil) # => [] + # Array.wrap([1, 2, 3]) # => [1, 2, 3] + # Array.wrap(0) # => [0] + # + # This method is similar in purpose to Kernel#Array, but there are some differences: + # + # * If the argument responds to +to_ary+ the method is invoked. Kernel#Array + # moves on to try +to_a+ if the returned value is +nil+, but Array.wrap returns + # an array with the argument as its single element right away. + # * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, Kernel#Array + # raises an exception, while Array.wrap does not, it just returns the value. + # * It does not call +to_a+ on the argument, if the argument does not respond to +to_ary+ + # it returns an array with the argument as its single element. + # + # The last point is easily explained with some enumerables: + # + # Array(foo: :bar) # => [[:foo, :bar]] + # Array.wrap(foo: :bar) # => [{:foo=>:bar}] + # + # There's also a related idiom that uses the splat operator: + # + # [*object] + # + # which returns [] for +nil+, but calls to Array(object) otherwise. + # + # The differences with Kernel#Array explained above + # apply to the rest of objects. + def self.wrap(object) + if object.nil? + [] + elsif object.respond_to?(:to_ary) + object.to_ary || [object] + else + [object] + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/benchmark.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/benchmark.rb new file mode 100644 index 00000000..20675e30 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/benchmark.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require "benchmark" + +class << Benchmark + def ms(&block) # :nodoc + # NOTE: Please also remove the Active Support `benchmark` dependency when removing this + ActiveSupport.deprecator.warn <<~TEXT + `Benchmark.ms` is deprecated and will be removed in Rails 8.1 without replacement. + TEXT + ActiveSupport::Benchmark.realtime(:float_millisecond, &block) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/big_decimal.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/big_decimal.rb new file mode 100644 index 00000000..9e6a9d63 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/big_decimal.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +require "active_support/core_ext/big_decimal/conversions" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/big_decimal/conversions.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/big_decimal/conversions.rb new file mode 100644 index 00000000..76ad5843 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/big_decimal/conversions.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require "bigdecimal" +require "bigdecimal/util" + +module ActiveSupport + module BigDecimalWithDefaultFormat # :nodoc: + def to_s(format = "F") + super(format) + end + end +end + +BigDecimal.prepend(ActiveSupport::BigDecimalWithDefaultFormat) diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/class.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/class.rb new file mode 100644 index 00000000..1c110fd0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/class.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +require "active_support/core_ext/class/attribute" +require "active_support/core_ext/class/subclasses" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/class/attribute.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/class/attribute.rb new file mode 100644 index 00000000..57264dfe --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/class/attribute.rb @@ -0,0 +1,135 @@ +# frozen_string_literal: true + +require "active_support/core_ext/module/redefine_method" +require "active_support/class_attribute" + +class Class + # Declare a class-level attribute whose value is inheritable by subclasses. + # Subclasses can change their own value and it will not impact parent class. + # + # ==== Options + # + # * :instance_reader - Sets the instance reader method (defaults to true). + # * :instance_writer - Sets the instance writer method (defaults to true). + # * :instance_accessor - Sets both instance methods (defaults to true). + # * :instance_predicate - Sets a predicate method (defaults to true). + # * :default - Sets a default value for the attribute (defaults to nil). + # + # ==== Examples + # + # class Base + # class_attribute :setting + # end + # + # class Subclass < Base + # end + # + # Base.setting = true + # Subclass.setting # => true + # Subclass.setting = false + # Subclass.setting # => false + # Base.setting # => true + # + # In the above case as long as Subclass does not assign a value to setting + # by performing Subclass.setting = _something_, Subclass.setting + # would read value assigned to parent class. Once Subclass assigns a value then + # the value assigned by Subclass would be returned. + # + # This matches normal Ruby method inheritance: think of writing an attribute + # on a subclass as overriding the reader method. However, you need to be aware + # when using +class_attribute+ with mutable structures as +Array+ or +Hash+. + # In such cases, you don't want to do changes in place. Instead use setters: + # + # Base.setting = [] + # Base.setting # => [] + # Subclass.setting # => [] + # + # # Appending in child changes both parent and child because it is the same object: + # Subclass.setting << :foo + # Base.setting # => [:foo] + # Subclass.setting # => [:foo] + # + # # Use setters to not propagate changes: + # Base.setting = [] + # Subclass.setting += [:foo] + # Base.setting # => [] + # Subclass.setting # => [:foo] + # + # For convenience, an instance predicate method is defined as well. + # To skip it, pass instance_predicate: false. + # + # Subclass.setting? # => false + # + # Instances may overwrite the class value in the same way: + # + # Base.setting = true + # object = Base.new + # object.setting # => true + # object.setting = false + # object.setting # => false + # Base.setting # => true + # + # To opt out of the instance reader method, pass instance_reader: false. + # + # object.setting # => NoMethodError + # object.setting? # => NoMethodError + # + # To opt out of the instance writer method, pass instance_writer: false. + # + # object.setting = false # => NoMethodError + # + # To opt out of both instance methods, pass instance_accessor: false. + # + # To set a default value for the attribute, pass default:, like so: + # + # class_attribute :settings, default: {} + def class_attribute(*attrs, instance_accessor: true, + instance_reader: instance_accessor, instance_writer: instance_accessor, instance_predicate: true, default: nil + ) + class_methods, methods = [], [] + attrs.each do |name| + unless name.is_a?(Symbol) || name.is_a?(String) + raise TypeError, "#{name.inspect} is not a symbol nor a string" + end + + name = name.to_sym + namespaced_name = :"__class_attr_#{name}" + ::ActiveSupport::ClassAttribute.redefine(self, name, namespaced_name, default) + + delegators = [ + "def #{name}; #{namespaced_name}; end", + "def #{name}=(value); self.#{namespaced_name} = value; end", + ] + + class_methods.concat(delegators) + if singleton_class? + methods.concat(delegators) + else + methods << <<~RUBY if instance_reader + silence_redefinition_of_method def #{name} + if defined?(@#{name}) + @#{name} + else + self.class.#{name} + end + end + RUBY + end + + methods << <<~RUBY if instance_writer + silence_redefinition_of_method(:#{name}=) + attr_writer :#{name} + RUBY + + if instance_predicate + class_methods << "silence_redefinition_of_method def #{name}?; !!self.#{name}; end" + if instance_reader + methods << "silence_redefinition_of_method def #{name}?; !!self.#{name}; end" + end + end + end + + location = caller_locations(1, 1).first + class_eval(["class << self", *class_methods, "end", *methods].join(";").tr("\n", ";"), location.path, location.lineno) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/class/attribute_accessors.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/class/attribute_accessors.rb new file mode 100644 index 00000000..a77354e1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/class/attribute_accessors.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +# cattr_* became mattr_* aliases in 7dfbd91b0780fbd6a1dd9bfbc176e10894871d2d, +# but we keep this around for libraries that directly require it knowing they +# want cattr_*. No need to deprecate. +require "active_support/core_ext/module/attribute_accessors" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/class/subclasses.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/class/subclasses.rb new file mode 100644 index 00000000..dd5b9e33 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/class/subclasses.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require "active_support/descendants_tracker" + +class Class + # Returns an array with all classes that are < than its receiver. + # + # class C; end + # C.descendants # => [] + # + # class B < C; end + # C.descendants # => [B] + # + # class A < B; end + # C.descendants # => [B, A] + # + # class D < C; end + # C.descendants # => [B, A, D] + def descendants + subclasses.concat(subclasses.flat_map(&:descendants)) + end + + prepend ActiveSupport::DescendantsTracker::ReloadedClassesFiltering +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date.rb new file mode 100644 index 00000000..cce73f2d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require "active_support/core_ext/date/acts_like" +require "active_support/core_ext/date/blank" +require "active_support/core_ext/date/calculations" +require "active_support/core_ext/date/conversions" +require "active_support/core_ext/date/zones" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date/acts_like.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date/acts_like.rb new file mode 100644 index 00000000..c8077f37 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date/acts_like.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require "active_support/core_ext/object/acts_like" + +class Date + # Duck-types as a Date-like class. See Object#acts_like?. + def acts_like_date? + true + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date/blank.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date/blank.rb new file mode 100644 index 00000000..4419f86c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date/blank.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require "date" + +class Date # :nodoc: + # No Date is blank: + # + # Date.today.blank? # => false + # + # @return [false] + def blank? + false + end + + def present? + true + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date/calculations.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date/calculations.rb new file mode 100644 index 00000000..7dea4697 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date/calculations.rb @@ -0,0 +1,161 @@ +# frozen_string_literal: true + +require "date" +require "active_support/duration" +require "active_support/core_ext/object/acts_like" +require "active_support/core_ext/date/zones" +require "active_support/core_ext/time/zones" +require "active_support/core_ext/date_and_time/calculations" + +class Date + include DateAndTime::Calculations + + class << self + attr_accessor :beginning_of_week_default + + # Returns the week start (e.g. +:monday+) for the current request, if this has been set (via Date.beginning_of_week=). + # If Date.beginning_of_week has not been set for the current request, returns the week start specified in config.beginning_of_week. + # If no +config.beginning_of_week+ was specified, returns +:monday+. + def beginning_of_week + ::ActiveSupport::IsolatedExecutionState[:beginning_of_week] || beginning_of_week_default || :monday + end + + # Sets Date.beginning_of_week to a week start (e.g. +:monday+) for current request/thread. + # + # This method accepts any of the following day symbols: + # +:monday+, +:tuesday+, +:wednesday+, +:thursday+, +:friday+, +:saturday+, +:sunday+ + def beginning_of_week=(week_start) + ::ActiveSupport::IsolatedExecutionState[:beginning_of_week] = find_beginning_of_week!(week_start) + end + + # Returns week start day symbol (e.g. +:monday+), or raises an +ArgumentError+ for invalid day symbol. + def find_beginning_of_week!(week_start) + raise ArgumentError, "Invalid beginning of week: #{week_start}" unless ::Date::DAYS_INTO_WEEK.key?(week_start) + week_start + end + + # Returns a new Date representing the date 1 day ago (i.e. yesterday's date). + def yesterday + ::Date.current.yesterday + end + + # Returns a new Date representing the date 1 day after today (i.e. tomorrow's date). + def tomorrow + ::Date.current.tomorrow + end + + # Returns Time.zone.today when Time.zone or config.time_zone are set, otherwise just returns Date.today. + def current + ::Time.zone ? ::Time.zone.today : ::Date.today + end + end + + # Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00) + # and then subtracts the specified number of seconds. + def ago(seconds) + in_time_zone.since(-seconds) + end + + # Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00) + # and then adds the specified number of seconds + def since(seconds) + in_time_zone.since(seconds) + end + alias :in :since + + # Converts Date to a Time (or DateTime if necessary) with the time portion set to the beginning of the day (0:00) + def beginning_of_day + in_time_zone + end + alias :midnight :beginning_of_day + alias :at_midnight :beginning_of_day + alias :at_beginning_of_day :beginning_of_day + + # Converts Date to a Time (or DateTime if necessary) with the time portion set to the middle of the day (12:00) + def middle_of_day + in_time_zone.middle_of_day + end + alias :midday :middle_of_day + alias :noon :middle_of_day + alias :at_midday :middle_of_day + alias :at_noon :middle_of_day + alias :at_middle_of_day :middle_of_day + + # Converts Date to a Time (or DateTime if necessary) with the time portion set to the end of the day (23:59:59) + def end_of_day + in_time_zone.end_of_day + end + alias :at_end_of_day :end_of_day + + def plus_with_duration(other) # :nodoc: + if ActiveSupport::Duration === other + other.since(self) + else + plus_without_duration(other) + end + end + alias_method :plus_without_duration, :+ + alias_method :+, :plus_with_duration + + def minus_with_duration(other) # :nodoc: + if ActiveSupport::Duration === other + plus_with_duration(-other) + else + minus_without_duration(other) + end + end + alias_method :minus_without_duration, :- + alias_method :-, :minus_with_duration + + # Provides precise Date calculations for years, months, and days. The +options+ parameter takes a hash with + # any of these keys: :years, :months, :weeks, :days. + # + # The increments are applied in order of time units from largest to smallest. + # In other words, the date is incremented first by +:years+, then by + # +:months+, then by +:weeks+, then by +:days+. This order can affect the + # result around the end of a month. For example, incrementing first by months + # then by days: + # + # Date.new(2004, 9, 30).advance(months: 1, days: 1) + # # => Sun, 31 Oct 2004 + # + # Whereas incrementing first by days then by months yields a different result: + # + # Date.new(2004, 9, 30).advance(days: 1).advance(months: 1) + # # => Mon, 01 Nov 2004 + # + def advance(options) + d = self + + d = d >> options[:years] * 12 if options[:years] + d = d >> options[:months] if options[:months] + d = d + options[:weeks] * 7 if options[:weeks] + d = d + options[:days] if options[:days] + + d + end + + # Returns a new Date where one or more of the elements have been changed according to the +options+ parameter. + # The +options+ parameter is a hash with a combination of these keys: :year, :month, :day. + # + # Date.new(2007, 5, 12).change(day: 1) # => Date.new(2007, 5, 1) + # Date.new(2007, 5, 12).change(year: 2005, month: 1) # => Date.new(2005, 1, 12) + def change(options) + ::Date.new( + options.fetch(:year, year), + options.fetch(:month, month), + options.fetch(:day, day) + ) + end + + # Allow Date to be compared with Time by converting to DateTime and relying on the <=> from there. + def compare_with_coercion(other) + if other.is_a?(Time) + to_datetime <=> other + else + compare_without_coercion(other) + end + end + alias_method :compare_without_coercion, :<=> + alias_method :<=>, :compare_with_coercion +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date/conversions.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date/conversions.rb new file mode 100644 index 00000000..983a3bf3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date/conversions.rb @@ -0,0 +1,98 @@ +# frozen_string_literal: true + +require "date" +require "active_support/inflector/methods" +require "active_support/core_ext/date/zones" +require "active_support/core_ext/module/redefine_method" + +class Date + DATE_FORMATS = { + short: "%d %b", + long: "%B %d, %Y", + db: "%Y-%m-%d", + inspect: "%Y-%m-%d", + number: "%Y%m%d", + long_ordinal: lambda { |date| + day_format = ActiveSupport::Inflector.ordinalize(date.day) + date.strftime("%B #{day_format}, %Y") # => "April 25th, 2007" + }, + rfc822: "%d %b %Y", + rfc2822: "%d %b %Y", + iso8601: lambda { |date| date.iso8601 } + } + + # Convert to a formatted string. See DATE_FORMATS for predefined formats. + # + # This method is aliased to to_formatted_s. + # + # date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007 + # + # date.to_fs(:db) # => "2007-11-10" + # date.to_formatted_s(:db) # => "2007-11-10" + # + # date.to_fs(:short) # => "10 Nov" + # date.to_fs(:number) # => "20071110" + # date.to_fs(:long) # => "November 10, 2007" + # date.to_fs(:long_ordinal) # => "November 10th, 2007" + # date.to_fs(:rfc822) # => "10 Nov 2007" + # date.to_fs(:rfc2822) # => "10 Nov 2007" + # date.to_fs(:iso8601) # => "2007-11-10" + # + # == Adding your own date formats to to_fs + # You can add your own formats to the Date::DATE_FORMATS hash. + # Use the format name as the hash key and either a strftime string + # or Proc instance that takes a date argument as the value. + # + # # config/initializers/date_formats.rb + # Date::DATE_FORMATS[:month_and_year] = '%B %Y' + # Date::DATE_FORMATS[:short_ordinal] = ->(date) { date.strftime("%B #{date.day.ordinalize}") } + def to_fs(format = :default) + if formatter = DATE_FORMATS[format] + if formatter.respond_to?(:call) + formatter.call(self).to_s + else + strftime(formatter) + end + else + to_s + end + end + alias_method :to_formatted_s, :to_fs + + # Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005" + def readable_inspect + strftime("%a, %d %b %Y") + end + alias_method :default_inspect, :inspect + alias_method :inspect, :readable_inspect + + silence_redefinition_of_method :to_time + + # Converts a Date instance to a Time, where the time is set to the beginning of the day. + # The timezone can be either +:local+ or +:utc+ (default +:local+). + # + # date = Date.new(2007, 11, 10) # => Sat, 10 Nov 2007 + # + # date.to_time # => 2007-11-10 00:00:00 0800 + # date.to_time(:local) # => 2007-11-10 00:00:00 0800 + # + # date.to_time(:utc) # => 2007-11-10 00:00:00 UTC + # + # NOTE: The +:local+ timezone is Ruby's *process* timezone, i.e. ENV['TZ']. + # If the application's timezone is needed, then use +in_time_zone+ instead. + def to_time(form = :local) + raise ArgumentError, "Expected :local or :utc, got #{form.inspect}." unless [:local, :utc].include?(form) + ::Time.public_send(form, year, month, day) + end + + silence_redefinition_of_method :xmlschema + + # Returns a string which represents the time in used time zone as DateTime + # defined by XML Schema: + # + # date = Date.new(2015, 05, 23) # => Sat, 23 May 2015 + # date.xmlschema # => "2015-05-23T00:00:00+04:00" + def xmlschema + in_time_zone.xmlschema + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date/zones.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date/zones.rb new file mode 100644 index 00000000..2dcf97cf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date/zones.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +require "date" +require "active_support/core_ext/date_and_time/zones" + +class Date + include DateAndTime::Zones +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_and_time/calculations.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_and_time/calculations.rb new file mode 100644 index 00000000..e713cee1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_and_time/calculations.rb @@ -0,0 +1,374 @@ +# frozen_string_literal: true + +require "active_support/core_ext/object/try" +require "active_support/core_ext/date_time/conversions" + +module DateAndTime + module Calculations + DAYS_INTO_WEEK = { + sunday: 0, + monday: 1, + tuesday: 2, + wednesday: 3, + thursday: 4, + friday: 5, + saturday: 6 + } + WEEKEND_DAYS = [ 6, 0 ] + + # Returns a new date/time representing yesterday. + def yesterday + advance(days: -1) + end + + # Returns a new date/time representing tomorrow. + def tomorrow + advance(days: 1) + end + + # Returns true if the date/time is today. + def today? + to_date == ::Date.current + end + + # Returns true if the date/time is tomorrow. + def tomorrow? + to_date == ::Date.current.tomorrow + end + alias :next_day? :tomorrow? + + # Returns true if the date/time is yesterday. + def yesterday? + to_date == ::Date.current.yesterday + end + alias :prev_day? :yesterday? + + # Returns true if the date/time is in the past. + def past? + self < self.class.current + end + + # Returns true if the date/time is in the future. + def future? + self > self.class.current + end + + # Returns true if the date/time falls on a Saturday or Sunday. + def on_weekend? + WEEKEND_DAYS.include?(wday) + end + + # Returns true if the date/time does not fall on a Saturday or Sunday. + def on_weekday? + !WEEKEND_DAYS.include?(wday) + end + + # Returns true if the date/time falls before date_or_time. + def before?(date_or_time) + self < date_or_time + end + + # Returns true if the date/time falls after date_or_time. + def after?(date_or_time) + self > date_or_time + end + + # Returns a new date/time the specified number of days ago. + def days_ago(days) + advance(days: -days) + end + + # Returns a new date/time the specified number of days in the future. + def days_since(days) + advance(days: days) + end + + # Returns a new date/time the specified number of weeks ago. + def weeks_ago(weeks) + advance(weeks: -weeks) + end + + # Returns a new date/time the specified number of weeks in the future. + def weeks_since(weeks) + advance(weeks: weeks) + end + + # Returns a new date/time the specified number of months ago. + def months_ago(months) + advance(months: -months) + end + + # Returns a new date/time the specified number of months in the future. + def months_since(months) + advance(months: months) + end + + # Returns a new date/time the specified number of years ago. + def years_ago(years) + advance(years: -years) + end + + # Returns a new date/time the specified number of years in the future. + def years_since(years) + advance(years: years) + end + + # Returns a new date/time at the start of the month. + # + # today = Date.today # => Thu, 18 Jun 2015 + # today.beginning_of_month # => Mon, 01 Jun 2015 + # + # +DateTime+ objects will have a time set to 0:00. + # + # now = DateTime.current # => Thu, 18 Jun 2015 15:23:13 +0000 + # now.beginning_of_month # => Mon, 01 Jun 2015 00:00:00 +0000 + def beginning_of_month + first_hour(change(day: 1)) + end + alias :at_beginning_of_month :beginning_of_month + + # Returns a new date/time at the start of the quarter. + # + # today = Date.today # => Fri, 10 Jul 2015 + # today.beginning_of_quarter # => Wed, 01 Jul 2015 + # + # +DateTime+ objects will have a time set to 0:00. + # + # now = DateTime.current # => Fri, 10 Jul 2015 18:41:29 +0000 + # now.beginning_of_quarter # => Wed, 01 Jul 2015 00:00:00 +0000 + def beginning_of_quarter + first_quarter_month = month - (2 + month) % 3 + beginning_of_month.change(month: first_quarter_month) + end + alias :at_beginning_of_quarter :beginning_of_quarter + + # Returns a new date/time at the end of the quarter. + # + # today = Date.today # => Fri, 10 Jul 2015 + # today.end_of_quarter # => Wed, 30 Sep 2015 + # + # +DateTime+ objects will have a time set to 23:59:59. + # + # now = DateTime.current # => Fri, 10 Jul 2015 18:41:29 +0000 + # now.end_of_quarter # => Wed, 30 Sep 2015 23:59:59 +0000 + def end_of_quarter + last_quarter_month = month + (12 - month) % 3 + beginning_of_month.change(month: last_quarter_month).end_of_month + end + alias :at_end_of_quarter :end_of_quarter + + # Returns the quarter for a date/time. + # + # Date.new(2010, 1, 31).quarter # => 1 + # Date.new(2010, 4, 12).quarter # => 2 + # Date.new(2010, 9, 15).quarter # => 3 + # Date.new(2010, 12, 25).quarter # => 4 + def quarter + (month / 3.0).ceil + end + + # Returns a new date/time at the beginning of the year. + # + # today = Date.today # => Fri, 10 Jul 2015 + # today.beginning_of_year # => Thu, 01 Jan 2015 + # + # +DateTime+ objects will have a time set to 0:00. + # + # now = DateTime.current # => Fri, 10 Jul 2015 18:41:29 +0000 + # now.beginning_of_year # => Thu, 01 Jan 2015 00:00:00 +0000 + def beginning_of_year + change(month: 1).beginning_of_month + end + alias :at_beginning_of_year :beginning_of_year + + # Returns a new date/time representing the given day in the next week. + # + # today = Date.today # => Thu, 07 May 2015 + # today.next_week # => Mon, 11 May 2015 + # + # The +given_day_in_next_week+ defaults to the beginning of the week + # which is determined by +Date.beginning_of_week+ or +config.beginning_of_week+ + # when set. + # + # today = Date.today # => Thu, 07 May 2015 + # today.next_week(:friday) # => Fri, 15 May 2015 + # + # +DateTime+ objects have their time set to 0:00 unless +same_time+ is true. + # + # now = DateTime.current # => Thu, 07 May 2015 13:31:16 +0000 + # now.next_week # => Mon, 11 May 2015 00:00:00 +0000 + def next_week(given_day_in_next_week = Date.beginning_of_week, same_time: false) + result = first_hour(weeks_since(1).beginning_of_week.days_since(days_span(given_day_in_next_week))) + same_time ? copy_time_to(result) : result + end + + # Returns a new date/time representing the next weekday. + def next_weekday + if next_day.on_weekend? + next_week(:monday, same_time: true) + else + next_day + end + end + + # Short-hand for months_since(3). + def next_quarter + months_since(3) + end + + # Returns a new date/time representing the given day in the previous week. + # Week is assumed to start on +start_day+, default is + # +Date.beginning_of_week+ or +config.beginning_of_week+ when set. + # DateTime objects have their time set to 0:00 unless +same_time+ is true. + def prev_week(start_day = Date.beginning_of_week, same_time: false) + result = first_hour(weeks_ago(1).beginning_of_week.days_since(days_span(start_day))) + same_time ? copy_time_to(result) : result + end + alias_method :last_week, :prev_week + + # Returns a new date/time representing the previous weekday. + def prev_weekday + if prev_day.on_weekend? + copy_time_to(beginning_of_week(:friday)) + else + prev_day + end + end + alias_method :last_weekday, :prev_weekday + + # Short-hand for months_ago(1). + def last_month + months_ago(1) + end + + # Short-hand for months_ago(3). + def prev_quarter + months_ago(3) + end + alias_method :last_quarter, :prev_quarter + + # Short-hand for years_ago(1). + def last_year + years_ago(1) + end + + # Returns the number of days to the start of the week on the given day. + # Week is assumed to start on +start_day+, default is + # +Date.beginning_of_week+ or +config.beginning_of_week+ when set. + def days_to_week_start(start_day = Date.beginning_of_week) + start_day_number = DAYS_INTO_WEEK.fetch(start_day) + (wday - start_day_number) % 7 + end + + # Returns a new date/time representing the start of this week on the given day. + # Week is assumed to start on +start_day+, default is + # +Date.beginning_of_week+ or +config.beginning_of_week+ when set. + # +DateTime+ objects have their time set to 0:00. + def beginning_of_week(start_day = Date.beginning_of_week) + result = days_ago(days_to_week_start(start_day)) + acts_like?(:time) ? result.midnight : result + end + alias :at_beginning_of_week :beginning_of_week + + # Returns Monday of this week assuming that week starts on Monday. + # +DateTime+ objects have their time set to 0:00. + def monday + beginning_of_week(:monday) + end + + # Returns a new date/time representing the end of this week on the given day. + # Week is assumed to start on +start_day+, default is + # +Date.beginning_of_week+ or +config.beginning_of_week+ when set. + # DateTime objects have their time set to 23:59:59. + def end_of_week(start_day = Date.beginning_of_week) + last_hour(days_since(6 - days_to_week_start(start_day))) + end + alias :at_end_of_week :end_of_week + + # Returns Sunday of this week assuming that week starts on Monday. + # +DateTime+ objects have their time set to 23:59:59. + def sunday + end_of_week(:monday) + end + + # Returns a new date/time representing the end of the month. + # DateTime objects will have a time set to 23:59:59. + def end_of_month + last_day = ::Time.days_in_month(month, year) + last_hour(days_since(last_day - day)) + end + alias :at_end_of_month :end_of_month + + # Returns a new date/time representing the end of the year. + # DateTime objects will have a time set to 23:59:59. + def end_of_year + change(month: 12).end_of_month + end + alias :at_end_of_year :end_of_year + + # Returns a Range representing the whole day of the current date/time. + def all_day + beginning_of_day..end_of_day + end + + # Returns a Range representing the whole week of the current date/time. + # Week starts on start_day, default is Date.beginning_of_week or config.beginning_of_week when set. + def all_week(start_day = Date.beginning_of_week) + beginning_of_week(start_day)..end_of_week(start_day) + end + + # Returns a Range representing the whole month of the current date/time. + def all_month + beginning_of_month..end_of_month + end + + # Returns a Range representing the whole quarter of the current date/time. + def all_quarter + beginning_of_quarter..end_of_quarter + end + + # Returns a Range representing the whole year of the current date/time. + def all_year + beginning_of_year..end_of_year + end + + # Returns a new date/time representing the next occurrence of the specified day of week. + # + # today = Date.today # => Thu, 14 Dec 2017 + # today.next_occurring(:monday) # => Mon, 18 Dec 2017 + # today.next_occurring(:thursday) # => Thu, 21 Dec 2017 + def next_occurring(day_of_week) + from_now = DAYS_INTO_WEEK.fetch(day_of_week) - wday + from_now += 7 unless from_now > 0 + advance(days: from_now) + end + + # Returns a new date/time representing the previous occurrence of the specified day of week. + # + # today = Date.today # => Thu, 14 Dec 2017 + # today.prev_occurring(:monday) # => Mon, 11 Dec 2017 + # today.prev_occurring(:thursday) # => Thu, 07 Dec 2017 + def prev_occurring(day_of_week) + ago = wday - DAYS_INTO_WEEK.fetch(day_of_week) + ago += 7 unless ago > 0 + advance(days: -ago) + end + + private + def first_hour(date_or_time) + date_or_time.acts_like?(:time) ? date_or_time.beginning_of_day : date_or_time + end + + def last_hour(date_or_time) + date_or_time.acts_like?(:time) ? date_or_time.end_of_day : date_or_time + end + + def days_span(day) + (DAYS_INTO_WEEK.fetch(day) - DAYS_INTO_WEEK.fetch(Date.beginning_of_week)) % 7 + end + + def copy_time_to(other) + other.change(hour: hour, min: min, sec: sec, nsec: try(:nsec)) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_and_time/compatibility.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_and_time/compatibility.rb new file mode 100644 index 00000000..68fb42c5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_and_time/compatibility.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require "active_support/core_ext/module/attribute_accessors" +require "active_support/core_ext/module/redefine_method" + +module DateAndTime + module Compatibility + # If true, +to_time+ preserves the timezone offset of receiver. + # + # NOTE: With Ruby 2.4+ the default for +to_time+ changed from + # converting to the local system time, to preserving the offset + # of the receiver. For backwards compatibility we're overriding + # this behavior, but new apps will have an initializer that sets + # this to true, because the new behavior is preferred. + mattr_accessor :preserve_timezone, instance_accessor: false, default: nil + + singleton_class.silence_redefinition_of_method :preserve_timezone + + #-- + # This re-implements the behaviour of the mattr_reader, instead + # of prepending on to it, to avoid overcomplicating a module that + # is in turn included in several places. This will all go away in + # Rails 8.0 anyway. + def self.preserve_timezone # :nodoc: + if @@preserve_timezone.nil? + # Only warn once, the first time the value is used (which should + # be the first time #to_time is called). + ActiveSupport.deprecator.warn( + "`to_time` will always preserve the receiver timezone rather than system local time in Rails 8.1." \ + "To opt in to the new behavior, set `config.active_support.to_time_preserves_timezone = :zone`." + ) + + @@preserve_timezone = false + end + + @@preserve_timezone + end + + def preserve_timezone # :nodoc: + Compatibility.preserve_timezone + end + + # Change the output of ActiveSupport::TimeZone.utc_to_local. + # + # When +true+, it returns local times with a UTC offset, with +false+ local + # times are returned as UTC. + # + # # Given this zone: + # zone = ActiveSupport::TimeZone["Eastern Time (US & Canada)"] + # + # # With `utc_to_local_returns_utc_offset_times = false`, local time is converted to UTC: + # zone.utc_to_local(Time.utc(2000, 1)) # => 1999-12-31 19:00:00 UTC + # + # # With `utc_to_local_returns_utc_offset_times = true`, local time is returned with UTC offset: + # zone.utc_to_local(Time.utc(2000, 1)) # => 1999-12-31 19:00:00 -0500 + mattr_accessor :utc_to_local_returns_utc_offset_times, instance_writer: false, default: false + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_and_time/zones.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_and_time/zones.rb new file mode 100644 index 00000000..fb6a27cb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_and_time/zones.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +module DateAndTime + module Zones + # Returns the simultaneous time in Time.zone if a zone is given or + # if Time.zone_default is set. Otherwise, it returns the current time. + # + # Time.zone = 'Hawaii' # => 'Hawaii' + # Time.utc(2000).in_time_zone # => Fri, 31 Dec 1999 14:00:00 HST -10:00 + # Date.new(2000).in_time_zone # => Sat, 01 Jan 2000 00:00:00 HST -10:00 + # + # This method is similar to Time#localtime, except that it uses Time.zone as the local zone + # instead of the operating system's time zone. + # + # You can also pass in a TimeZone instance or string that identifies a TimeZone as an argument, + # and the conversion will be based on that zone instead of Time.zone. + # + # Time.utc(2000).in_time_zone('Alaska') # => Fri, 31 Dec 1999 15:00:00 AKST -09:00 + # Date.new(2000).in_time_zone('Alaska') # => Sat, 01 Jan 2000 00:00:00 AKST -09:00 + def in_time_zone(zone = ::Time.zone) + time_zone = ::Time.find_zone! zone + time = acts_like?(:time) ? self : nil + + if time_zone + time_with_zone(time, time_zone) + else + time || to_time + end + end + + private + def time_with_zone(time, zone) + if time + ActiveSupport::TimeWithZone.new(time.utc? ? time : time.getutc, zone) + else + ActiveSupport::TimeWithZone.new(nil, zone, to_time(:utc)) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_time.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_time.rb new file mode 100644 index 00000000..790dbeec --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_time.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require "active_support/core_ext/date_time/acts_like" +require "active_support/core_ext/date_time/blank" +require "active_support/core_ext/date_time/calculations" +require "active_support/core_ext/date_time/compatibility" +require "active_support/core_ext/date_time/conversions" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_time/acts_like.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_time/acts_like.rb new file mode 100644 index 00000000..5dccdfe2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_time/acts_like.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require "date" +require "active_support/core_ext/object/acts_like" + +class DateTime + # Duck-types as a Date-like class. See Object#acts_like?. + def acts_like_date? + true + end + + # Duck-types as a Time-like class. See Object#acts_like?. + def acts_like_time? + true + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_time/blank.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_time/blank.rb new file mode 100644 index 00000000..49290bf8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_time/blank.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require "date" + +class DateTime # :nodoc: + # No DateTime is ever blank: + # + # DateTime.now.blank? # => false + # + # @return [false] + def blank? + false + end + + def present? + true + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_time/calculations.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_time/calculations.rb new file mode 100644 index 00000000..a6350680 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_time/calculations.rb @@ -0,0 +1,215 @@ +# frozen_string_literal: true + +require "date" + +class DateTime + class << self + # Returns Time.zone.now.to_datetime when Time.zone or + # config.time_zone are set, otherwise returns + # Time.now.to_datetime. + def current + ::Time.zone ? ::Time.zone.now.to_datetime : ::Time.now.to_datetime + end + end + + # Returns the number of seconds since 00:00:00. + # + # DateTime.new(2012, 8, 29, 0, 0, 0).seconds_since_midnight # => 0 + # DateTime.new(2012, 8, 29, 12, 34, 56).seconds_since_midnight # => 45296 + # DateTime.new(2012, 8, 29, 23, 59, 59).seconds_since_midnight # => 86399 + def seconds_since_midnight + sec + (min * 60) + (hour * 3600) + end + + # Returns the number of seconds until 23:59:59. + # + # DateTime.new(2012, 8, 29, 0, 0, 0).seconds_until_end_of_day # => 86399 + # DateTime.new(2012, 8, 29, 12, 34, 56).seconds_until_end_of_day # => 41103 + # DateTime.new(2012, 8, 29, 23, 59, 59).seconds_until_end_of_day # => 0 + def seconds_until_end_of_day + end_of_day.to_i - to_i + end + + # Returns the fraction of a second as a +Rational+ + # + # DateTime.new(2012, 8, 29, 0, 0, 0.5).subsec # => (1/2) + def subsec + sec_fraction + end + + # Returns a new DateTime where one or more of the elements have been changed + # according to the +options+ parameter. The time options (:hour, + # :min, :sec) reset cascadingly, so if only the hour is + # passed, then minute and sec is set to 0. If the hour and minute is passed, + # then sec is set to 0. The +options+ parameter takes a hash with any of these + # keys: :year, :month, :day, :hour, + # :min, :sec, :offset, :start. + # + # DateTime.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => DateTime.new(2012, 8, 1, 22, 35, 0) + # DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => DateTime.new(1981, 8, 1, 22, 35, 0) + # DateTime.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => DateTime.new(1981, 8, 29, 0, 0, 0) + def change(options) + if new_nsec = options[:nsec] + raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec] + new_fraction = Rational(new_nsec, 1000000000) + else + new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000)) + new_fraction = Rational(new_usec, 1000000) + end + + raise ArgumentError, "argument out of range" if new_fraction >= 1 + + ::DateTime.civil( + options.fetch(:year, year), + options.fetch(:month, month), + options.fetch(:day, day), + options.fetch(:hour, hour), + options.fetch(:min, options[:hour] ? 0 : min), + options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec) + new_fraction, + options.fetch(:offset, offset), + options.fetch(:start, start) + ) + end + + # Uses Date to provide precise Time calculations for years, months, and days. + # The +options+ parameter takes a hash with any of these keys: :years, + # :months, :weeks, :days, :hours, + # :minutes, :seconds. + # + # Just like Date#advance, increments are applied in order of time units from + # largest to smallest. This order can affect the result around the end of a + # month. + def advance(options) + unless options[:weeks].nil? + options[:weeks], partial_weeks = options[:weeks].divmod(1) + options[:days] = options.fetch(:days, 0) + 7 * partial_weeks + end + + unless options[:days].nil? + options[:days], partial_days = options[:days].divmod(1) + options[:hours] = options.fetch(:hours, 0) + 24 * partial_days + end + + d = to_date.advance(options) + datetime_advanced_by_date = change(year: d.year, month: d.month, day: d.day) + seconds_to_advance = \ + options.fetch(:seconds, 0) + + options.fetch(:minutes, 0) * 60 + + options.fetch(:hours, 0) * 3600 + + if seconds_to_advance.zero? + datetime_advanced_by_date + else + datetime_advanced_by_date.since(seconds_to_advance) + end + end + + # Returns a new DateTime representing the time a number of seconds ago. + # Do not use this method in combination with x.months, use months_ago instead! + def ago(seconds) + since(-seconds) + end + + # Returns a new DateTime representing the time a number of seconds since the + # instance time. Do not use this method in combination with x.months, use + # months_since instead! + def since(seconds) + self + Rational(seconds, 86400) + end + alias :in :since + + # Returns a new DateTime representing the start of the day (0:00). + def beginning_of_day + change(hour: 0) + end + alias :midnight :beginning_of_day + alias :at_midnight :beginning_of_day + alias :at_beginning_of_day :beginning_of_day + + # Returns a new DateTime representing the middle of the day (12:00) + def middle_of_day + change(hour: 12) + end + alias :midday :middle_of_day + alias :noon :middle_of_day + alias :at_midday :middle_of_day + alias :at_noon :middle_of_day + alias :at_middle_of_day :middle_of_day + + # Returns a new DateTime representing the end of the day (23:59:59). + def end_of_day + change(hour: 23, min: 59, sec: 59, usec: Rational(999999999, 1000)) + end + alias :at_end_of_day :end_of_day + + # Returns a new DateTime representing the start of the hour (hh:00:00). + def beginning_of_hour + change(min: 0) + end + alias :at_beginning_of_hour :beginning_of_hour + + # Returns a new DateTime representing the end of the hour (hh:59:59). + def end_of_hour + change(min: 59, sec: 59, usec: Rational(999999999, 1000)) + end + alias :at_end_of_hour :end_of_hour + + # Returns a new DateTime representing the start of the minute (hh:mm:00). + def beginning_of_minute + change(sec: 0) + end + alias :at_beginning_of_minute :beginning_of_minute + + # Returns a new DateTime representing the end of the minute (hh:mm:59). + def end_of_minute + change(sec: 59, usec: Rational(999999999, 1000)) + end + alias :at_end_of_minute :end_of_minute + + # Returns a Time instance of the simultaneous time in the system timezone. + def localtime(utc_offset = nil) + utc = new_offset(0) + + Time.utc( + utc.year, utc.month, utc.day, + utc.hour, utc.min, utc.sec + utc.sec_fraction + ).getlocal(utc_offset) + end + alias_method :getlocal, :localtime + + # Returns a Time instance of the simultaneous time in the UTC timezone. + # + # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)) # => Mon, 21 Feb 2005 10:11:12 -0600 + # DateTime.civil(2005, 2, 21, 10, 11, 12, Rational(-6, 24)).utc # => Mon, 21 Feb 2005 16:11:12 UTC + def utc + utc = new_offset(0) + + Time.utc( + utc.year, utc.month, utc.day, + utc.hour, utc.min, utc.sec + utc.sec_fraction + ) + end + alias_method :getgm, :utc + alias_method :getutc, :utc + alias_method :gmtime, :utc + + # Returns +true+ if offset == 0. + def utc? + offset == 0 + end + + # Returns the offset value in seconds. + def utc_offset + (offset * 86400).to_i + end + + # Layers additional behavior on DateTime#<=> so that Time and + # ActiveSupport::TimeWithZone instances can be compared with a DateTime. + def <=>(other) + if other.respond_to? :to_datetime + super other.to_datetime rescue nil + else + super + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_time/compatibility.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_time/compatibility.rb new file mode 100644 index 00000000..7600a067 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_time/compatibility.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require "active_support/core_ext/date_and_time/compatibility" +require "active_support/core_ext/module/redefine_method" + +class DateTime + include DateAndTime::Compatibility + + silence_redefinition_of_method :to_time + + # Either return an instance of +Time+ with the same UTC offset + # as +self+ or an instance of +Time+ representing the same time + # in the local system timezone depending on the setting of + # on the setting of +ActiveSupport.to_time_preserves_timezone+. + def to_time + preserve_timezone ? getlocal(utc_offset) : getlocal + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_time/conversions.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_time/conversions.rb new file mode 100644 index 00000000..57c8d88d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/date_time/conversions.rb @@ -0,0 +1,106 @@ +# frozen_string_literal: true + +require "date" +require "active_support/inflector/methods" +require "active_support/core_ext/time/conversions" +require "active_support/core_ext/date_time/calculations" +require "active_support/values/time_zone" + +class DateTime + # Convert to a formatted string. See Time::DATE_FORMATS for predefined formats. + # + # This method is aliased to to_formatted_s. + # + # === Examples + # datetime = DateTime.civil(2007, 12, 4, 0, 0, 0, 0) # => Tue, 04 Dec 2007 00:00:00 +0000 + # + # datetime.to_fs(:db) # => "2007-12-04 00:00:00" + # datetime.to_formatted_s(:db) # => "2007-12-04 00:00:00" + # datetime.to_fs(:number) # => "20071204000000" + # datetime.to_fs(:short) # => "04 Dec 00:00" + # datetime.to_fs(:long) # => "December 04, 2007 00:00" + # datetime.to_fs(:long_ordinal) # => "December 4th, 2007 00:00" + # datetime.to_fs(:rfc822) # => "Tue, 04 Dec 2007 00:00:00 +0000" + # datetime.to_fs(:iso8601) # => "2007-12-04T00:00:00+00:00" + # + # == Adding your own datetime formats to to_fs + # DateTime formats are shared with Time. You can add your own to the + # Time::DATE_FORMATS hash. Use the format name as the hash key and + # either a strftime string or Proc instance that takes a time or + # datetime argument as the value. + # + # # config/initializers/time_formats.rb + # Time::DATE_FORMATS[:month_and_year] = '%B %Y' + # Time::DATE_FORMATS[:short_ordinal] = lambda { |time| time.strftime("%B #{time.day.ordinalize}") } + def to_fs(format = :default) + if formatter = ::Time::DATE_FORMATS[format] + formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter) + else + to_s + end + end + alias_method :to_formatted_s, :to_fs + + + # Returns a formatted string of the offset from UTC, or an alternative + # string if the time zone is already UTC. + # + # datetime = DateTime.civil(2000, 1, 1, 0, 0, 0, Rational(-6, 24)) + # datetime.formatted_offset # => "-06:00" + # datetime.formatted_offset(false) # => "-0600" + def formatted_offset(colon = true, alternate_utc_string = nil) + utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon) + end + + # Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005 14:30:00 +0000". + def readable_inspect + to_fs(:rfc822) + end + alias_method :default_inspect, :inspect + alias_method :inspect, :readable_inspect + + # Returns DateTime with local offset for given year if format is local else + # offset is zero. + # + # DateTime.civil_from_format :local, 2012 + # # => Sun, 01 Jan 2012 00:00:00 +0300 + # DateTime.civil_from_format :local, 2012, 12, 17 + # # => Mon, 17 Dec 2012 00:00:00 +0000 + def self.civil_from_format(utc_or_local, year, month = 1, day = 1, hour = 0, min = 0, sec = 0) + if utc_or_local.to_sym == :local + offset = ::Time.local(year, month, day).utc_offset.to_r / 86400 + else + offset = 0 + end + civil(year, month, day, hour, min, sec, offset) + end + + # Converts +self+ to a floating-point number of seconds, including fractional microseconds, since the Unix epoch. + def to_f + seconds_since_unix_epoch.to_f + sec_fraction + end + + # Converts +self+ to an integer number of seconds since the Unix epoch. + def to_i + seconds_since_unix_epoch.to_i + end + + # Returns the fraction of a second as microseconds + def usec + (sec_fraction * 1_000_000).to_i + end + + # Returns the fraction of a second as nanoseconds + def nsec + (sec_fraction * 1_000_000_000).to_i + end + + private + def offset_in_seconds + (offset * 86400).to_i + end + + def seconds_since_unix_epoch + (jd - 2440588) * 86400 - offset_in_seconds + seconds_since_midnight + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/digest.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/digest.rb new file mode 100644 index 00000000..ce1427e1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/digest.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +require "active_support/core_ext/digest/uuid" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/digest/uuid.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/digest/uuid.rb new file mode 100644 index 00000000..0f06a979 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/digest/uuid.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true + +require "securerandom" +require "openssl" + +module Digest + module UUID + DNS_NAMESPACE = "k\xA7\xB8\x10\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" # :nodoc: + URL_NAMESPACE = "k\xA7\xB8\x11\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" # :nodoc: + OID_NAMESPACE = "k\xA7\xB8\x12\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" # :nodoc: + X500_NAMESPACE = "k\xA7\xB8\x14\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" # :nodoc: + + # Generates a v5 non-random UUID (Universally Unique IDentifier). + # + # Using OpenSSL::Digest::MD5 generates version 3 UUIDs; OpenSSL::Digest::SHA1 generates version 5 UUIDs. + # uuid_from_hash always generates the same UUID for a given name and namespace combination. + # + # See RFC 4122 for details of UUID at: https://www.ietf.org/rfc/rfc4122.txt + def self.uuid_from_hash(hash_class, namespace, name) + if hash_class == Digest::MD5 || hash_class == OpenSSL::Digest::MD5 + version = 3 + elsif hash_class == Digest::SHA1 || hash_class == OpenSSL::Digest::SHA1 + version = 5 + else + raise ArgumentError, "Expected OpenSSL::Digest::SHA1 or OpenSSL::Digest::MD5, got #{hash_class.name}." + end + + uuid_namespace = pack_uuid_namespace(namespace) + + hash = hash_class.new + hash.update(uuid_namespace) + hash.update(name) + + ary = hash.digest.unpack("NnnnnN") + ary[2] = (ary[2] & 0x0FFF) | (version << 12) + ary[3] = (ary[3] & 0x3FFF) | 0x8000 + + "%08x-%04x-%04x-%04x-%04x%08x" % ary + end + + # Convenience method for uuid_from_hash using OpenSSL::Digest::MD5. + def self.uuid_v3(uuid_namespace, name) + uuid_from_hash(OpenSSL::Digest::MD5, uuid_namespace, name) + end + + # Convenience method for uuid_from_hash using OpenSSL::Digest::SHA1. + def self.uuid_v5(uuid_namespace, name) + uuid_from_hash(OpenSSL::Digest::SHA1, uuid_namespace, name) + end + + # Convenience method for SecureRandom.uuid. + def self.uuid_v4 + SecureRandom.uuid + end + + # Returns the nil UUID. This is a special form of UUID that is specified to + # have all 128 bits set to zero. + def self.nil_uuid + "00000000-0000-0000-0000-000000000000" + end + + def self.pack_uuid_namespace(namespace) + if [DNS_NAMESPACE, OID_NAMESPACE, URL_NAMESPACE, X500_NAMESPACE].include?(namespace) + namespace + else + match_data = namespace.match(/\A(\h{8})-(\h{4})-(\h{4})-(\h{4})-(\h{4})(\h{8})\z/) + + raise ArgumentError, "Only UUIDs are valid namespace identifiers" unless match_data.present? + + match_data.captures.map { |s| s.to_i(16) }.pack("NnnnnN") + end + end + + private_class_method :pack_uuid_namespace + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/enumerable.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/enumerable.rb new file mode 100644 index 00000000..7ae0dc6e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/enumerable.rb @@ -0,0 +1,267 @@ +# frozen_string_literal: true + +module ActiveSupport + module EnumerableCoreExt # :nodoc: + module Constants + private + def const_missing(name) + if name == :SoleItemExpectedError + ::ActiveSupport::EnumerableCoreExt::SoleItemExpectedError + else + super + end + end + end + end +end + +module Enumerable + # Error generated by +sole+ when called on an enumerable that doesn't have + # exactly one item. + class SoleItemExpectedError < StandardError; end + + # HACK: For performance reasons, Enumerable shouldn't have any constants of its own. + # So we move SoleItemExpectedError into ActiveSupport::EnumerableCoreExt. + ActiveSupport::EnumerableCoreExt::SoleItemExpectedError = remove_const(:SoleItemExpectedError) + singleton_class.prepend(ActiveSupport::EnumerableCoreExt::Constants) + + # Calculates the minimum from the extracted elements. + # + # payments = [Payment.new(5), Payment.new(15), Payment.new(10)] + # payments.minimum(:price) # => 5 + def minimum(key) + map(&key).min + end + + # Calculates the maximum from the extracted elements. + # + # payments = [Payment.new(5), Payment.new(15), Payment.new(10)] + # payments.maximum(:price) # => 15 + def maximum(key) + map(&key).max + end + + # Convert an enumerable to a hash, using the block result as the key and the + # element as the value. + # + # people.index_by(&:login) + # # => { "nextangle" => , "chade-" => , ...} + # + # people.index_by { |person| "#{person.first_name} #{person.last_name}" } + # # => { "Chade- Fowlersburg-e" => , "David Heinemeier Hansson" => , ...} + def index_by + if block_given? + result = {} + each { |elem| result[yield(elem)] = elem } + result + else + to_enum(:index_by) { size if respond_to?(:size) } + end + end + + # Convert an enumerable to a hash, using the element as the key and the block + # result as the value. + # + # post = Post.new(title: "hey there", body: "what's up?") + # + # %i( title body ).index_with { |attr_name| post.public_send(attr_name) } + # # => { title: "hey there", body: "what's up?" } + # + # If an argument is passed instead of a block, it will be used as the value + # for all elements: + # + # %i( created_at updated_at ).index_with(Time.now) + # # => { created_at: 2020-03-09 22:31:47, updated_at: 2020-03-09 22:31:47 } + def index_with(default = (no_default = true)) + if block_given? + result = {} + each { |elem| result[elem] = yield(elem) } + result + elsif no_default + to_enum(:index_with) { size if respond_to?(:size) } + else + result = {} + each { |elem| result[elem] = default } + result + end + end + + # Returns +true+ if the enumerable has more than 1 element. Functionally + # equivalent to enum.to_a.size > 1. Can be called with a block too, + # much like any?, so people.many? { |p| p.age > 26 } returns +true+ + # if more than one person is over 26. + def many? + cnt = 0 + if block_given? + any? do |*args| + cnt += 1 if yield(*args) + cnt > 1 + end + else + any? { (cnt += 1) > 1 } + end + end + + # Returns a new array that includes the passed elements. + # + # [ 1, 2, 3 ].including(4, 5) + # # => [ 1, 2, 3, 4, 5 ] + # + # ["David", "Rafael"].including %w[ Aaron Todd ] + # # => ["David", "Rafael", "Aaron", "Todd"] + def including(*elements) + to_a.including(*elements) + end + + # The negative of the Enumerable#include?. Returns +true+ if the + # collection does not include the object. + def exclude?(object) + !include?(object) + end + + # Returns a copy of the enumerable excluding the specified elements. + # + # ["David", "Rafael", "Aaron", "Todd"].excluding "Aaron", "Todd" + # # => ["David", "Rafael"] + # + # ["David", "Rafael", "Aaron", "Todd"].excluding %w[ Aaron Todd ] + # # => ["David", "Rafael"] + # + # {foo: 1, bar: 2, baz: 3}.excluding :bar + # # => {foo: 1, baz: 3} + def excluding(*elements) + elements.flatten!(1) + reject { |element| elements.include?(element) } + end + alias :without :excluding + + # Extract the given key from each element in the enumerable. + # + # [{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pluck(:name) + # # => ["David", "Rafael", "Aaron"] + # + # [{ id: 1, name: "David" }, { id: 2, name: "Rafael" }].pluck(:id, :name) + # # => [[1, "David"], [2, "Rafael"]] + def pluck(*keys) + if keys.many? + map { |element| keys.map { |key| element[key] } } + else + key = keys.first + map { |element| element[key] } + end + end + + # Extract the given key from the first element in the enumerable. + # + # [{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pick(:name) + # # => "David" + # + # [{ id: 1, name: "David" }, { id: 2, name: "Rafael" }].pick(:id, :name) + # # => [1, "David"] + def pick(*keys) + return if none? + + if keys.many? + keys.map { |key| first[key] } + else + first[keys.first] + end + end + + # Returns a new +Array+ without the blank items. + # Uses Object#blank? for determining if an item is blank. + # + # [1, "", nil, 2, " ", [], {}, false, true].compact_blank + # # => [1, 2, true] + # + # Set.new([nil, "", 1, false]).compact_blank + # # => [1] + # + # When called on a +Hash+, returns a new +Hash+ without the blank values. + # + # { a: "", b: 1, c: nil, d: [], e: false, f: true }.compact_blank + # # => { b: 1, f: true } + def compact_blank + reject(&:blank?) + end + + # Returns a new +Array+ where the order has been set to that provided in the +series+, based on the +key+ of the + # objects in the original enumerable. + # + # [ Person.find(5), Person.find(3), Person.find(1) ].in_order_of(:id, [ 1, 5, 3 ]) + # # => [ Person.find(1), Person.find(5), Person.find(3) ] + # + # If the +series+ include keys that have no corresponding element in the Enumerable, these are ignored. + # If the Enumerable has additional elements that aren't named in the +series+, these are not included in the result, unless + # the +filter+ option is set to +false+. + def in_order_of(key, series, filter: true) + if filter + group_by(&key).values_at(*series).flatten(1).compact + else + sort_by { |v| series.index(v.public_send(key)) || series.size }.compact + end + end + + # Returns the sole item in the enumerable. If there are no items, or more + # than one item, raises Enumerable::SoleItemExpectedError. + # + # ["x"].sole # => "x" + # Set.new.sole # => Enumerable::SoleItemExpectedError: no item found + # { a: 1, b: 2 }.sole # => Enumerable::SoleItemExpectedError: multiple items found + def sole + case count + when 1 then return first # rubocop:disable Style/RedundantReturn + when 0 then raise ActiveSupport::EnumerableCoreExt::SoleItemExpectedError, "no item found" + when 2.. then raise ActiveSupport::EnumerableCoreExt::SoleItemExpectedError, "multiple items found" + end + end +end + +class Hash + # Hash#reject has its own definition, so this needs one too. + def compact_blank # :nodoc: + reject { |_k, v| v.blank? } + end + + # Removes all blank values from the +Hash+ in place and returns self. + # Uses Object#blank? for determining if a value is blank. + # + # h = { a: "", b: 1, c: nil, d: [], e: false, f: true } + # h.compact_blank! + # # => { b: 1, f: true } + def compact_blank! + # use delete_if rather than reject! because it always returns self even if nothing changed + delete_if { |_k, v| v.blank? } + end +end + +class Range # :nodoc: + # Optimize range sum to use arithmetic progression if a block is not given and + # we have a range of numeric values. + def sum(initial_value = 0) + if block_given? || !(first.is_a?(Integer) && last.is_a?(Integer)) + super + else + actual_last = exclude_end? ? (last - 1) : last + if actual_last >= first + sum = initial_value || 0 + sum + (actual_last - first + 1) * (actual_last + first) / 2 + else + initial_value || 0 + end + end + end +end + +class Array # :nodoc: + # Removes all blank elements from the +Array+ in place and returns self. + # Uses Object#blank? for determining if an item is blank. + # + # a = [1, "", nil, 2, " ", [], {}, false, true] + # a.compact_blank! + # # => [1, 2, true] + def compact_blank! + # use delete_if rather than reject! because it always returns self even if nothing changed + delete_if(&:blank?) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/erb/util.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/erb/util.rb new file mode 100644 index 00000000..06eed37b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/erb/util.rb @@ -0,0 +1,201 @@ +# frozen_string_literal: true + +require "erb" + +module ActiveSupport + module CoreExt + module ERBUtil + # HTML escapes strings but doesn't wrap them with an ActiveSupport::SafeBuffer. + # This method is not for public consumption! Seriously! + def html_escape(s) # :nodoc: + s = s.to_s + if s.html_safe? + s + else + super(ActiveSupport::Multibyte::Unicode.tidy_bytes(s)) + end + end + alias :unwrapped_html_escape :html_escape # :nodoc: + + # A utility method for escaping HTML tag characters. + # This method is also aliased as h. + # + # puts html_escape('is a > 0 & a < 10?') + # # => is a > 0 & a < 10? + def html_escape(s) # rubocop:disable Lint/DuplicateMethods + unwrapped_html_escape(s).html_safe + end + alias h html_escape + end + + module ERBUtilPrivate + include ERBUtil + private :unwrapped_html_escape, :html_escape, :h + end + end +end + +class ERB + module Util + HTML_ESCAPE = { "&" => "&", ">" => ">", "<" => "<", '"' => """, "'" => "'" } + HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+)|(#[xX][\dA-Fa-f]+));)/ + + # Following XML requirements: https://www.w3.org/TR/REC-xml/#NT-Name + TAG_NAME_START_CODEPOINTS = "@:A-Z_a-z\u{C0}-\u{D6}\u{D8}-\u{F6}\u{F8}-\u{2FF}\u{370}-\u{37D}\u{37F}-\u{1FFF}" \ + "\u{200C}-\u{200D}\u{2070}-\u{218F}\u{2C00}-\u{2FEF}\u{3001}-\u{D7FF}\u{F900}-\u{FDCF}" \ + "\u{FDF0}-\u{FFFD}\u{10000}-\u{EFFFF}" + INVALID_TAG_NAME_START_REGEXP = /[^#{TAG_NAME_START_CODEPOINTS}]/ + TAG_NAME_FOLLOWING_CODEPOINTS = "#{TAG_NAME_START_CODEPOINTS}\\-.0-9\u{B7}\u{0300}-\u{036F}\u{203F}-\u{2040}" + INVALID_TAG_NAME_FOLLOWING_REGEXP = /[^#{TAG_NAME_FOLLOWING_CODEPOINTS}]/ + SAFE_XML_TAG_NAME_REGEXP = /\A[#{TAG_NAME_START_CODEPOINTS}][#{TAG_NAME_FOLLOWING_CODEPOINTS}]*\z/ + TAG_NAME_REPLACEMENT_CHAR = "_" + + prepend ActiveSupport::CoreExt::ERBUtilPrivate + singleton_class.prepend ActiveSupport::CoreExt::ERBUtil + + # A utility method for escaping HTML without affecting existing escaped entities. + # + # html_escape_once('1 < 2 & 3') + # # => "1 < 2 & 3" + # + # html_escape_once('<< Accept & Checkout') + # # => "<< Accept & Checkout" + def html_escape_once(s) + ActiveSupport::Multibyte::Unicode.tidy_bytes(s.to_s).gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE).html_safe + end + + module_function :html_escape_once + + # A utility method for escaping HTML entities in JSON strings. Specifically, the + # &, > and < characters are replaced with their equivalent unicode escaped form - + # \u0026, \u003e, and \u003c. The Unicode sequences \u2028 and \u2029 are also + # escaped as they are treated as newline characters in some JavaScript engines. + # These sequences have identical meaning as the original characters inside the + # context of a JSON string, so assuming the input is a valid and well-formed + # JSON value, the output will have equivalent meaning when parsed: + # + # json = JSON.generate({ name: ""}) + # # => "{\"name\":\"\"}" + # + # json_escape(json) + # # => "{\"name\":\"\\u003C/script\\u003E\\u003Cscript\\u003Ealert('PWNED!!!')\\u003C/script\\u003E\"}" + # + # JSON.parse(json) == JSON.parse(json_escape(json)) + # # => true + # + # The intended use case for this method is to escape JSON strings before including + # them inside a script tag to avoid XSS vulnerability: + # + # + # + # It is necessary to +raw+ the result of +json_escape+, so that quotation marks + # don't get converted to " entities. +json_escape+ doesn't + # automatically flag the result as HTML safe, since the raw value is unsafe to + # use inside HTML attributes. + # + # If your JSON is being used downstream for insertion into the DOM, be aware of + # whether or not it is being inserted via html(). Most jQuery plugins do this. + # If that is the case, be sure to +html_escape+ or +sanitize+ any user-generated + # content returned by your JSON. + # + # If you need to output JSON elsewhere in your HTML, you can just do something + # like this, as any unsafe characters (including quotation marks) will be + # automatically escaped for you: + # + #
...
+ # + # WARNING: this helper only works with valid JSON. Using this on non-JSON values + # will open up serious XSS vulnerabilities. For example, if you replace the + # +current_user.to_json+ in the example above with user input instead, the browser + # will happily eval() that string as JavaScript. + # + # The escaping performed in this method is identical to those performed in the + # Active Support JSON encoder when +ActiveSupport.escape_html_entities_in_json+ is + # set to true. Because this transformation is idempotent, this helper can be + # applied even if +ActiveSupport.escape_html_entities_in_json+ is already true. + # + # Therefore, when you are unsure if +ActiveSupport.escape_html_entities_in_json+ + # is enabled, or if you are unsure where your JSON string originated from, it + # is recommended that you always apply this helper (other libraries, such as the + # JSON gem, do not provide this kind of protection by default; also some gems + # might override +to_json+ to bypass Active Support's encoder). + def json_escape(s) + result = s.to_s.dup + result.gsub!(">", '\u003e') + result.gsub!("<", '\u003c') + result.gsub!("&", '\u0026') + result.gsub!("\u2028", '\u2028') + result.gsub!("\u2029", '\u2029') + s.html_safe? ? result.html_safe : result + end + + module_function :json_escape + + # A utility method for escaping XML names of tags and names of attributes. + # + # xml_name_escape('1 < 2 & 3') + # # => "1___2___3" + # + # It follows the requirements of the specification: https://www.w3.org/TR/REC-xml/#NT-Name + def xml_name_escape(name) + name = name.to_s + return "" if name.blank? + return name if name.match?(SAFE_XML_TAG_NAME_REGEXP) + + starting_char = name[0] + starting_char.gsub!(INVALID_TAG_NAME_START_REGEXP, TAG_NAME_REPLACEMENT_CHAR) + + return starting_char if name.size == 1 + + following_chars = name[1..-1] + following_chars.gsub!(INVALID_TAG_NAME_FOLLOWING_REGEXP, TAG_NAME_REPLACEMENT_CHAR) + + starting_char << following_chars + end + module_function :xml_name_escape + + # Tokenizes a line of ERB. This is really just for error reporting and + # nobody should use it. + def self.tokenize(source) # :nodoc: + require "strscan" + source = StringScanner.new(source.chomp) + tokens = [] + + start_re = /<%(?:={1,2}|-|\#|%)?/m + finish_re = /(?:[-=])?%>/m + + while !source.eos? + pos = source.pos + source.scan_until(/(?:#{start_re}|#{finish_re})/) + raise NotImplementedError if source.matched.nil? + len = source.pos - source.matched.bytesize - pos + + case source.matched + when start_re + tokens << [:TEXT, source.string.byteslice(pos, len)] if len > 0 + tokens << [:OPEN, source.matched] + if source.scan(/(.*?)(?=#{finish_re}|\z)/m) + tokens << [:CODE, source.matched] unless source.matched.empty? + tokens << [:CLOSE, source.scan(finish_re)] unless source.eos? + else + raise NotImplementedError + end + when finish_re + tokens << [:CODE, source.string.byteslice(pos, len)] if len > 0 + tokens << [:CLOSE, source.matched] + else + raise NotImplementedError, source.matched + end + + unless source.eos? || source.exist?(start_re) || source.exist?(finish_re) + tokens << [:TEXT, source.rest] + source.terminate + end + end + + tokens + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/file.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/file.rb new file mode 100644 index 00000000..64553bfa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/file.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +require "active_support/core_ext/file/atomic" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/file/atomic.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/file/atomic.rb new file mode 100644 index 00000000..b442ea31 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/file/atomic.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +require "fileutils" + +class File + # Write to a file atomically. Useful for situations where you don't + # want other processes or threads to see half-written files. + # + # File.atomic_write('important.file') do |file| + # file.write('hello') + # end + # + # This method needs to create a temporary file. By default it will create it + # in the same directory as the destination file. If you don't like this + # behavior you can provide a different directory but it must be on the + # same physical filesystem as the file you're trying to write. + # + # File.atomic_write('/data/something.important', '/data/tmp') do |file| + # file.write('hello') + # end + def self.atomic_write(file_name, temp_dir = dirname(file_name)) + require "tempfile" unless defined?(Tempfile) + + Tempfile.open(".#{basename(file_name)}", temp_dir) do |temp_file| + temp_file.binmode + return_val = yield temp_file + temp_file.close + + old_stat = if exist?(file_name) + # Get original file permissions + stat(file_name) + else + # If not possible, probe which are the default permissions in the + # destination directory. + probe_stat_in(dirname(file_name)) + end + + if old_stat + # Set correct permissions on new file + begin + chown(old_stat.uid, old_stat.gid, temp_file.path) + # This operation will affect filesystem ACL's + chmod(old_stat.mode, temp_file.path) + rescue Errno::EPERM, Errno::EACCES + # Changing file ownership failed, moving on. + end + end + + # Overwrite original file with temp file + rename(temp_file.path, file_name) + return_val + end + end + + # Private utility method. + def self.probe_stat_in(dir) # :nodoc: + basename = [ + ".permissions_check", + Thread.current.object_id, + Process.pid, + rand(1000000) + ].join(".") + + file_name = join(dir, basename) + FileUtils.touch(file_name) + stat(file_name) + rescue Errno::ENOENT + file_name = nil + ensure + FileUtils.rm_f(file_name) if file_name + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash.rb new file mode 100644 index 00000000..2f0901d8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require "active_support/core_ext/hash/conversions" +require "active_support/core_ext/hash/deep_merge" +require "active_support/core_ext/hash/deep_transform_values" +require "active_support/core_ext/hash/except" +require "active_support/core_ext/hash/indifferent_access" +require "active_support/core_ext/hash/keys" +require "active_support/core_ext/hash/reverse_merge" +require "active_support/core_ext/hash/slice" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash/conversions.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash/conversions.rb new file mode 100644 index 00000000..8ab2fd69 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash/conversions.rb @@ -0,0 +1,262 @@ +# frozen_string_literal: true + +require "active_support/core_ext/object/blank" +require "active_support/core_ext/object/to_param" +require "active_support/core_ext/object/to_query" +require "active_support/core_ext/object/try" +require "active_support/core_ext/array/wrap" +require "active_support/core_ext/hash/reverse_merge" +require "active_support/core_ext/string/inflections" + +class Hash + # Returns a string containing an XML representation of its receiver: + # + # { foo: 1, bar: 2 }.to_xml + # # => + # # + # # + # # 1 + # # 2 + # # + # + # To do so, the method loops over the pairs and builds nodes that depend on + # the _values_. Given a pair +key+, +value+: + # + # * If +value+ is a hash there's a recursive call with +key+ as :root. + # + # * If +value+ is an array there's a recursive call with +key+ as :root, + # and +key+ singularized as :children. + # + # * If +value+ is a callable object it must expect one or two arguments. Depending + # on the arity, the callable is invoked with the +options+ hash as first argument + # with +key+ as :root, and +key+ singularized as second argument. The + # callable can add nodes by using options[:builder]. + # + # {foo: lambda { |options, key| options[:builder].b(key) }}.to_xml + # # => "foo" + # + # * If +value+ responds to +to_xml+ the method is invoked with +key+ as :root. + # + # class Foo + # def to_xml(options) + # options[:builder].bar 'fooing!' + # end + # end + # + # { foo: Foo.new }.to_xml(skip_instruct: true) + # # => + # # + # # fooing! + # # + # + # * Otherwise, a node with +key+ as tag is created with a string representation of + # +value+ as text node. If +value+ is +nil+ an attribute "nil" set to "true" is added. + # Unless the option :skip_types exists and is true, an attribute "type" is + # added as well according to the following mapping: + # + # XML_TYPE_NAMES = { + # "Symbol" => "symbol", + # "Integer" => "integer", + # "BigDecimal" => "decimal", + # "Float" => "float", + # "TrueClass" => "boolean", + # "FalseClass" => "boolean", + # "Date" => "date", + # "DateTime" => "dateTime", + # "Time" => "dateTime" + # } + # + # By default the root node is "hash", but that's configurable via the :root option. + # + # The default XML builder is a fresh instance of +Builder::XmlMarkup+. You can + # configure your own builder with the :builder option. The method also accepts + # options like :dasherize and friends, they are forwarded to the builder. + def to_xml(options = {}) + require "active_support/builder" unless defined?(Builder::XmlMarkup) + + options = options.dup + options[:indent] ||= 2 + options[:root] ||= "hash" + options[:builder] ||= Builder::XmlMarkup.new(indent: options[:indent]) + + builder = options[:builder] + builder.instruct! unless options.delete(:skip_instruct) + + root = ActiveSupport::XmlMini.rename_key(options[:root].to_s, options) + + builder.tag!(root) do + each { |key, value| ActiveSupport::XmlMini.to_tag(key, value, options) } + yield builder if block_given? + end + end + + class << self + # Returns a Hash containing a collection of pairs when the key is the node name and the value is + # its content + # + # xml = <<-XML + # + # + # 1 + # 2 + # + # XML + # + # hash = Hash.from_xml(xml) + # # => {"hash"=>{"foo"=>1, "bar"=>2}} + # + # +DisallowedType+ is raised if the XML contains attributes with type="yaml" or + # type="symbol". Use Hash.from_trusted_xml to + # parse this XML. + # + # Custom +disallowed_types+ can also be passed in the form of an + # array. + # + # xml = <<-XML + # + # + # 1 + # "David" + # + # XML + # + # hash = Hash.from_xml(xml, ['integer']) + # # => ActiveSupport::XMLConverter::DisallowedType: Disallowed type attribute: "integer" + # + # Note that passing custom disallowed types will override the default types, + # which are Symbol and YAML. + def from_xml(xml, disallowed_types = nil) + ActiveSupport::XMLConverter.new(xml, disallowed_types).to_h + end + + # Builds a Hash from XML just like Hash.from_xml, but also allows Symbol and YAML. + def from_trusted_xml(xml) + from_xml xml, [] + end + end +end + +module ActiveSupport + class XMLConverter # :nodoc: + # Raised if the XML contains attributes with type="yaml" or + # type="symbol". Read Hash#from_xml for more details. + class DisallowedType < StandardError + def initialize(type) + super "Disallowed type attribute: #{type.inspect}" + end + end + + DISALLOWED_TYPES = %w(symbol yaml) + + def initialize(xml, disallowed_types = nil) + @xml = normalize_keys(XmlMini.parse(xml)) + @disallowed_types = disallowed_types || DISALLOWED_TYPES + end + + def to_h + deep_to_h(@xml) + end + + private + def normalize_keys(params) + case params + when Hash + Hash[params.map { |k, v| [k.to_s.tr("-", "_"), normalize_keys(v)] } ] + when Array + params.map { |v| normalize_keys(v) } + else + params + end + end + + def deep_to_h(value) + case value + when Hash + process_hash(value) + when Array + process_array(value) + when String + value + else + raise "can't typecast #{value.class.name} - #{value.inspect}" + end + end + + def process_hash(value) + if value.include?("type") && !value["type"].is_a?(Hash) && @disallowed_types.include?(value["type"]) + raise DisallowedType, value["type"] + end + + if become_array?(value) + _, entries = Array.wrap(value.detect { |k, v| not v.is_a?(String) }) + if entries.nil? || value["__content__"].try(:empty?) + [] + else + case entries + when Array + entries.collect { |v| deep_to_h(v) } + when Hash + [deep_to_h(entries)] + else + raise "can't typecast #{entries.inspect}" + end + end + elsif become_content?(value) + process_content(value) + + elsif become_empty_string?(value) + "" + elsif become_hash?(value) + xml_value = value.transform_values { |v| deep_to_h(v) } + + # Turn { files: { file: # } } into { files: # } so it is compatible with + # how multipart uploaded files from HTML appear + xml_value["file"].is_a?(StringIO) ? xml_value["file"] : xml_value + end + end + + def become_content?(value) + value["type"] == "file" || (value["__content__"] && (value.keys.size == 1 || value["__content__"].present?)) + end + + def become_array?(value) + value["type"] == "array" + end + + def become_empty_string?(value) + # { "string" => true } + # No tests fail when the second term is removed. + value["type"] == "string" && value["nil"] != "true" + end + + def become_hash?(value) + !nothing?(value) && !garbage?(value) + end + + def nothing?(value) + # blank or nil parsed values are represented by nil + value.blank? || value["nil"] == "true" + end + + def garbage?(value) + # If the type is the only element which makes it then + # this still makes the value nil, except if type is + # an XML node(where type['value'] is a Hash) + value["type"] && !value["type"].is_a?(::Hash) && value.size == 1 + end + + def process_content(value) + content = value["__content__"] + if parser = ActiveSupport::XmlMini::PARSING[value["type"]] + parser.arity == 1 ? parser.call(content) : parser.call(content, value) + else + content + end + end + + def process_array(value) + value.map! { |i| deep_to_h(i) } + value.length > 1 ? value : value.first + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash/deep_merge.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash/deep_merge.rb new file mode 100644 index 00000000..9af3572a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash/deep_merge.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require "active_support/deep_mergeable" + +class Hash + include ActiveSupport::DeepMergeable + + ## + # :method: deep_merge + # :call-seq: deep_merge(other_hash, &block) + # + # Returns a new hash with +self+ and +other_hash+ merged recursively. + # + # h1 = { a: true, b: { c: [1, 2, 3] } } + # h2 = { a: false, b: { x: [3, 4, 5] } } + # + # h1.deep_merge(h2) # => { a: false, b: { c: [1, 2, 3], x: [3, 4, 5] } } + # + # Like with Hash#merge in the standard library, a block can be provided + # to merge values: + # + # h1 = { a: 100, b: 200, c: { c1: 100 } } + # h2 = { b: 250, c: { c1: 200 } } + # h1.deep_merge(h2) { |key, this_val, other_val| this_val + other_val } + # # => { a: 100, b: 450, c: { c1: 300 } } + # + #-- + # Implemented by ActiveSupport::DeepMergeable#deep_merge. + + ## + # :method: deep_merge! + # :call-seq: deep_merge!(other_hash, &block) + # + # Same as #deep_merge, but modifies +self+. + # + #-- + # Implemented by ActiveSupport::DeepMergeable#deep_merge!. + + ## + def deep_merge?(other) # :nodoc: + other.is_a?(Hash) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash/deep_transform_values.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash/deep_transform_values.rb new file mode 100644 index 00000000..f7aeae5b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash/deep_transform_values.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +class Hash + # Returns a new hash with all values converted by the block operation. + # This includes the values from the root hash and from all + # nested hashes and arrays. + # + # hash = { person: { name: 'Rob', age: '28' } } + # + # hash.deep_transform_values{ |value| value.to_s.upcase } + # # => {person: {name: "ROB", age: "28"}} + def deep_transform_values(&block) + _deep_transform_values_in_object(self, &block) + end + + # Destructively converts all values by using the block operation. + # This includes the values from the root hash and from all + # nested hashes and arrays. + def deep_transform_values!(&block) + _deep_transform_values_in_object!(self, &block) + end + + private + # Support methods for deep transforming nested hashes and arrays. + def _deep_transform_values_in_object(object, &block) + case object + when Hash + object.transform_values { |value| _deep_transform_values_in_object(value, &block) } + when Array + object.map { |e| _deep_transform_values_in_object(e, &block) } + else + yield(object) + end + end + + def _deep_transform_values_in_object!(object, &block) + case object + when Hash + object.transform_values! { |value| _deep_transform_values_in_object!(value, &block) } + when Array + object.map! { |e| _deep_transform_values_in_object!(e, &block) } + else + yield(object) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash/except.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash/except.rb new file mode 100644 index 00000000..d94acd74 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash/except.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class Hash + # Removes the given keys from hash and returns it. + # hash = { a: true, b: false, c: nil } + # hash.except!(:c) # => { a: true, b: false } + # hash # => { a: true, b: false } + def except!(*keys) + keys.each { |key| delete(key) } + self + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash/indifferent_access.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash/indifferent_access.rb new file mode 100644 index 00000000..4437363c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash/indifferent_access.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require "active_support/hash_with_indifferent_access" + +class Hash + # Returns an ActiveSupport::HashWithIndifferentAccess out of its receiver: + # + # { a: 1 }.with_indifferent_access['a'] # => 1 + def with_indifferent_access + ActiveSupport::HashWithIndifferentAccess.new(self) + end + + # Called when object is nested under an object that receives + # #with_indifferent_access. This method will be called on the current object + # by the enclosing object and is aliased to #with_indifferent_access by + # default. Subclasses of Hash may override this method to return +self+ if + # converting to an ActiveSupport::HashWithIndifferentAccess would not be + # desirable. + # + # b = { b: 1 } + # { a: b }.with_indifferent_access['a'] # calls b.nested_under_indifferent_access + # # => {"b"=>1} + alias nested_under_indifferent_access with_indifferent_access +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash/keys.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash/keys.rb new file mode 100644 index 00000000..fd74f030 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash/keys.rb @@ -0,0 +1,143 @@ +# frozen_string_literal: true + +class Hash + # Returns a new hash with all keys converted to strings. + # + # hash = { name: 'Rob', age: '28' } + # + # hash.stringify_keys + # # => {"name"=>"Rob", "age"=>"28"} + def stringify_keys + transform_keys { |k| Symbol === k ? k.name : k.to_s } + end + + # Destructively converts all keys to strings. Same as + # +stringify_keys+, but modifies +self+. + def stringify_keys! + transform_keys! { |k| Symbol === k ? k.name : k.to_s } + end + + # Returns a new hash with all keys converted to symbols, as long as + # they respond to +to_sym+. + # + # hash = { 'name' => 'Rob', 'age' => '28' } + # + # hash.symbolize_keys + # # => {:name=>"Rob", :age=>"28"} + def symbolize_keys + transform_keys { |key| key.to_sym rescue key } + end + alias_method :to_options, :symbolize_keys + + # Destructively converts all keys to symbols, as long as they respond + # to +to_sym+. Same as +symbolize_keys+, but modifies +self+. + def symbolize_keys! + transform_keys! { |key| key.to_sym rescue key } + end + alias_method :to_options!, :symbolize_keys! + + # Validates all keys in a hash match *valid_keys, raising + # +ArgumentError+ on a mismatch. + # + # Note that keys are treated differently than HashWithIndifferentAccess, + # meaning that string and symbol keys will not match. + # + # { name: 'Rob', years: '28' }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key: :years. Valid keys are: :name, :age" + # { name: 'Rob', age: '28' }.assert_valid_keys('name', 'age') # => raises "ArgumentError: Unknown key: :name. Valid keys are: 'name', 'age'" + # { name: 'Rob', age: '28' }.assert_valid_keys(:name, :age) # => passes, raises nothing + def assert_valid_keys(*valid_keys) + valid_keys.flatten! + each_key do |k| + unless valid_keys.include?(k) + raise ArgumentError.new("Unknown key: #{k.inspect}. Valid keys are: #{valid_keys.map(&:inspect).join(', ')}") + end + end + end + + # Returns a new hash with all keys converted by the block operation. + # This includes the keys from the root hash and from all + # nested hashes and arrays. + # + # hash = { person: { name: 'Rob', age: '28' } } + # + # hash.deep_transform_keys{ |key| key.to_s.upcase } + # # => {"PERSON"=>{"NAME"=>"Rob", "AGE"=>"28"}} + def deep_transform_keys(&block) + _deep_transform_keys_in_object(self, &block) + end + + # Destructively converts all keys by using the block operation. + # This includes the keys from the root hash and from all + # nested hashes and arrays. + def deep_transform_keys!(&block) + _deep_transform_keys_in_object!(self, &block) + end + + # Returns a new hash with all keys converted to strings. + # This includes the keys from the root hash and from all + # nested hashes and arrays. + # + # hash = { person: { name: 'Rob', age: '28' } } + # + # hash.deep_stringify_keys + # # => {"person"=>{"name"=>"Rob", "age"=>"28"}} + def deep_stringify_keys + deep_transform_keys { |k| Symbol === k ? k.name : k.to_s } + end + + # Destructively converts all keys to strings. + # This includes the keys from the root hash and from all + # nested hashes and arrays. + def deep_stringify_keys! + deep_transform_keys! { |k| Symbol === k ? k.name : k.to_s } + end + + # Returns a new hash with all keys converted to symbols, as long as + # they respond to +to_sym+. This includes the keys from the root hash + # and from all nested hashes and arrays. + # + # hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } } + # + # hash.deep_symbolize_keys + # # => {:person=>{:name=>"Rob", :age=>"28"}} + def deep_symbolize_keys + deep_transform_keys { |key| key.to_sym rescue key } + end + + # Destructively converts all keys to symbols, as long as they respond + # to +to_sym+. This includes the keys from the root hash and from all + # nested hashes and arrays. + def deep_symbolize_keys! + deep_transform_keys! { |key| key.to_sym rescue key } + end + + private + # Support methods for deep transforming nested hashes and arrays. + def _deep_transform_keys_in_object(object, &block) + case object + when Hash + object.each_with_object(self.class.new) do |(key, value), result| + result[yield(key)] = _deep_transform_keys_in_object(value, &block) + end + when Array + object.map { |e| _deep_transform_keys_in_object(e, &block) } + else + object + end + end + + def _deep_transform_keys_in_object!(object, &block) + case object + when Hash + object.keys.each do |key| + value = object.delete(key) + object[yield(key)] = _deep_transform_keys_in_object!(value, &block) + end + object + when Array + object.map! { |e| _deep_transform_keys_in_object!(e, &block) } + else + object + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash/reverse_merge.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash/reverse_merge.rb new file mode 100644 index 00000000..ef8d5928 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash/reverse_merge.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +class Hash + # Merges the caller into +other_hash+. For example, + # + # options = options.reverse_merge(size: 25, velocity: 10) + # + # is equivalent to + # + # options = { size: 25, velocity: 10 }.merge(options) + # + # This is particularly useful for initializing an options hash + # with default values. + def reverse_merge(other_hash) + other_hash.merge(self) + end + alias_method :with_defaults, :reverse_merge + + # Destructive +reverse_merge+. + def reverse_merge!(other_hash) + replace(reverse_merge(other_hash)) + end + alias_method :reverse_update, :reverse_merge! + alias_method :with_defaults!, :reverse_merge! +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash/slice.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash/slice.rb new file mode 100644 index 00000000..56bc5de3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/hash/slice.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +class Hash + # Replaces the hash with only the given keys. + # Returns a hash containing the removed key/value pairs. + # + # hash = { a: 1, b: 2, c: 3, d: 4 } + # hash.slice!(:a, :b) # => {:c=>3, :d=>4} + # hash # => {:a=>1, :b=>2} + def slice!(*keys) + omit = slice(*self.keys - keys) + hash = slice(*keys) + hash.default = default + hash.default_proc = default_proc if default_proc + replace(hash) + omit + end + + # Removes and returns the key/value pairs matching the given keys. + # + # hash = { a: 1, b: 2, c: 3, d: 4 } + # hash.extract!(:a, :b) # => {:a=>1, :b=>2} + # hash # => {:c=>3, :d=>4} + def extract!(*keys) + keys.each_with_object(self.class.new) { |key, result| result[key] = delete(key) if has_key?(key) } + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/integer.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/integer.rb new file mode 100644 index 00000000..d2270130 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/integer.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +require "active_support/core_ext/integer/multiple" +require "active_support/core_ext/integer/inflections" +require "active_support/core_ext/integer/time" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/integer/inflections.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/integer/inflections.rb new file mode 100644 index 00000000..c9879902 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/integer/inflections.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +require "active_support/inflector" + +class Integer + # Ordinalize turns a number into an ordinal string used to denote the + # position in an ordered sequence such as 1st, 2nd, 3rd, 4th. + # + # 1.ordinalize # => "1st" + # 2.ordinalize # => "2nd" + # 1002.ordinalize # => "1002nd" + # 1003.ordinalize # => "1003rd" + # -11.ordinalize # => "-11th" + # -1001.ordinalize # => "-1001st" + def ordinalize + ActiveSupport::Inflector.ordinalize(self) + end + + # Ordinal returns the suffix used to denote the position + # in an ordered sequence such as 1st, 2nd, 3rd, 4th. + # + # 1.ordinal # => "st" + # 2.ordinal # => "nd" + # 1002.ordinal # => "nd" + # 1003.ordinal # => "rd" + # -11.ordinal # => "th" + # -1001.ordinal # => "st" + def ordinal + ActiveSupport::Inflector.ordinal(self) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/integer/multiple.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/integer/multiple.rb new file mode 100644 index 00000000..bd57a909 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/integer/multiple.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class Integer + # Check whether the integer is evenly divisible by the argument. + # + # 0.multiple_of?(0) # => true + # 6.multiple_of?(5) # => false + # 10.multiple_of?(2) # => true + def multiple_of?(number) + number == 0 ? self == 0 : self % number == 0 + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/integer/time.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/integer/time.rb new file mode 100644 index 00000000..5efb89cf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/integer/time.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require "active_support/duration" +require "active_support/core_ext/numeric/time" + +class Integer + # Returns a Duration instance matching the number of months provided. + # + # 2.months # => 2 months + def months + ActiveSupport::Duration.months(self) + end + alias :month :months + + # Returns a Duration instance matching the number of years provided. + # + # 2.years # => 2 years + def years + ActiveSupport::Duration.years(self) + end + alias :year :years +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/kernel.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/kernel.rb new file mode 100644 index 00000000..77080693 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/kernel.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +require "active_support/core_ext/kernel/concern" +require "active_support/core_ext/kernel/reporting" +require "active_support/core_ext/kernel/singleton_class" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/kernel/concern.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/kernel/concern.rb new file mode 100644 index 00000000..0b2baed7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/kernel/concern.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require "active_support/core_ext/module/concerning" + +module Kernel + module_function + + # A shortcut to define a toplevel concern, not within a module. + # + # See Module::Concerning for more. + def concern(topic, &module_definition) + Object.concern topic, &module_definition + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/kernel/reporting.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/kernel/reporting.rb new file mode 100644 index 00000000..1ae1ae8e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/kernel/reporting.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module Kernel + module_function + + # Sets $VERBOSE to +nil+ for the duration of the block and back to its original + # value afterwards. + # + # silence_warnings do + # value = noisy_call # no warning voiced + # end + # + # noisy_call # warning voiced + def silence_warnings(&block) + with_warnings(nil, &block) + end + + # Sets $VERBOSE to +true+ for the duration of the block and back to its + # original value afterwards. + def enable_warnings(&block) + with_warnings(true, &block) + end + + # Sets $VERBOSE for the duration of the block and back to its original + # value afterwards. + def with_warnings(flag) + old_verbose, $VERBOSE = $VERBOSE, flag + yield + ensure + $VERBOSE = old_verbose + end + + # Blocks and ignores any exception passed as argument if raised within the block. + # + # suppress(ZeroDivisionError) do + # 1/0 + # puts 'This code is NOT reached' + # end + # + # puts 'This code gets executed and nothing related to ZeroDivisionError was seen' + def suppress(*exception_classes) + yield + rescue *exception_classes + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/kernel/singleton_class.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/kernel/singleton_class.rb new file mode 100644 index 00000000..31335b68 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/kernel/singleton_class.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +module Kernel + # class_eval on an object acts like +singleton_class.class_eval+. + def class_eval(*args, &block) + singleton_class.class_eval(*args, &block) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/load_error.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/load_error.rb new file mode 100644 index 00000000..03df2dda --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/load_error.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class LoadError + # Returns true if the given path name (except perhaps for the ".rb" + # extension) is the missing file which caused the exception to be raised. + def is_missing?(location) + location.delete_suffix(".rb") == path.to_s.delete_suffix(".rb") + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module.rb new file mode 100644 index 00000000..542af98c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require "active_support/core_ext/module/aliasing" +require "active_support/core_ext/module/introspection" +require "active_support/core_ext/module/anonymous" +require "active_support/core_ext/module/attribute_accessors" +require "active_support/core_ext/module/attribute_accessors_per_thread" +require "active_support/core_ext/module/attr_internal" +require "active_support/core_ext/module/concerning" +require "active_support/core_ext/module/delegation" +require "active_support/core_ext/module/deprecation" +require "active_support/core_ext/module/redefine_method" +require "active_support/core_ext/module/remove_method" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/aliasing.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/aliasing.rb new file mode 100644 index 00000000..6f64d116 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/aliasing.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +class Module + # Allows you to make aliases for attributes, which includes + # getter, setter, and a predicate. + # + # class Content < ActiveRecord::Base + # # has a title attribute + # end + # + # class Email < Content + # alias_attribute :subject, :title + # end + # + # e = Email.find(1) + # e.title # => "Superstars" + # e.subject # => "Superstars" + # e.subject? # => true + # e.subject = "Megastars" + # e.title # => "Megastars" + def alias_attribute(new_name, old_name) + # The following reader methods use an explicit `self` receiver in order to + # support aliases that start with an uppercase letter. Otherwise, they would + # be resolved as constants instead. + module_eval <<-STR, __FILE__, __LINE__ + 1 + def #{new_name}; self.#{old_name}; end # def subject; self.title; end + def #{new_name}?; self.#{old_name}?; end # def subject?; self.title?; end + def #{new_name}=(v); self.#{old_name} = v; end # def subject=(v); self.title = v; end + STR + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/anonymous.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/anonymous.rb new file mode 100644 index 00000000..d1c86b87 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/anonymous.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +class Module + # A module may or may not have a name. + # + # module M; end + # M.name # => "M" + # + # m = Module.new + # m.name # => nil + # + # +anonymous?+ method returns true if module does not have a name, false otherwise: + # + # Module.new.anonymous? # => true + # + # module M; end + # M.anonymous? # => false + # + # A module gets a name when it is first assigned to a constant. Either + # via the +module+ or +class+ keyword or by an explicit assignment: + # + # m = Module.new # creates an anonymous module + # m.anonymous? # => true + # M = m # m gets a name here as a side-effect + # m.name # => "M" + # m.anonymous? # => false + def anonymous? + name.nil? + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/attr_internal.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/attr_internal.rb new file mode 100644 index 00000000..ecf57d8a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/attr_internal.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +class Module + # Declares an attribute reader backed by an internally-named instance variable. + def attr_internal_reader(*attrs) + attrs.each { |attr_name| attr_internal_define(attr_name, :reader) } + end + + # Declares an attribute writer backed by an internally-named instance variable. + def attr_internal_writer(*attrs) + attrs.each { |attr_name| attr_internal_define(attr_name, :writer) } + end + + # Declares an attribute reader and writer backed by an internally-named instance + # variable. + def attr_internal_accessor(*attrs) + attr_internal_reader(*attrs) + attr_internal_writer(*attrs) + end + alias_method :attr_internal, :attr_internal_accessor + + class << self + attr_reader :attr_internal_naming_format + + def attr_internal_naming_format=(format) + if format.start_with?("@") + raise ArgumentError, <<~MESSAGE.squish + Setting `attr_internal_naming_format` with a `@` prefix is not supported. + + You can simply replace #{format.inspect} by #{format.delete_prefix("@").inspect}. + MESSAGE + end + + @attr_internal_naming_format = format + end + end + self.attr_internal_naming_format = "_%s" + + private + def attr_internal_define(attr_name, type) + internal_name = Module.attr_internal_naming_format % attr_name + # use native attr_* methods as they are faster on some Ruby implementations + public_send("attr_#{type}", internal_name) + attr_name, internal_name = "#{attr_name}=", "#{internal_name}=" if type == :writer + alias_method attr_name, internal_name + remove_method internal_name + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/attribute_accessors.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/attribute_accessors.rb new file mode 100644 index 00000000..8511e0f9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/attribute_accessors.rb @@ -0,0 +1,214 @@ +# frozen_string_literal: true + +# == Attribute Accessors +# +# Extends the module object with class/module and instance accessors for +# class/module attributes, just like the native attr* accessors for instance +# attributes. +class Module + # Defines a class attribute and creates a class and instance reader methods. + # The underlying class variable is set to +nil+, if it is not previously + # defined. All class and instance methods created will be public, even if + # this method is called with a private or protected access modifier. + # + # module HairColors + # mattr_reader :hair_colors + # end + # + # HairColors.hair_colors # => nil + # HairColors.class_variable_set("@@hair_colors", [:brown, :black]) + # HairColors.hair_colors # => [:brown, :black] + # + # The attribute name must be a valid method name in Ruby. + # + # module Foo + # mattr_reader :"1_Badname" + # end + # # => NameError: invalid attribute name: 1_Badname + # + # To omit the instance reader method, pass + # instance_reader: false or instance_accessor: false. + # + # module HairColors + # mattr_reader :hair_colors, instance_reader: false + # end + # + # class Person + # include HairColors + # end + # + # Person.new.hair_colors # => NoMethodError + # + # You can set a default value for the attribute. + # + # module HairColors + # mattr_reader :hair_colors, default: [:brown, :black, :blonde, :red] + # mattr_reader(:hair_styles) { [:long, :short] } + # end + # + # class Person + # include HairColors + # end + # + # Person.new.hair_colors # => [:brown, :black, :blonde, :red] + # Person.new.hair_styles # => [:long, :short] + def mattr_reader(*syms, instance_reader: true, instance_accessor: true, default: nil, location: nil) + raise TypeError, "module attributes should be defined directly on class, not singleton" if singleton_class? + location ||= caller_locations(1, 1).first + + definition = [] + syms.each do |sym| + raise NameError.new("invalid attribute name: #{sym}") unless /\A[_A-Za-z]\w*\z/.match?(sym) + + definition << "def self.#{sym}; @@#{sym}; end" + + if instance_reader && instance_accessor + definition << "def #{sym}; @@#{sym}; end" + end + + sym_default_value = (block_given? && default.nil?) ? yield : default + class_variable_set("@@#{sym}", sym_default_value) unless sym_default_value.nil? && class_variable_defined?("@@#{sym}") + end + + module_eval(definition.join(";"), location.path, location.lineno) + end + alias :cattr_reader :mattr_reader + + # Defines a class attribute and creates a class and instance writer methods to + # allow assignment to the attribute. All class and instance methods created + # will be public, even if this method is called with a private or protected + # access modifier. + # + # module HairColors + # mattr_writer :hair_colors + # end + # + # class Person + # include HairColors + # end + # + # HairColors.hair_colors = [:brown, :black] + # Person.class_variable_get("@@hair_colors") # => [:brown, :black] + # Person.new.hair_colors = [:blonde, :red] + # HairColors.class_variable_get("@@hair_colors") # => [:blonde, :red] + # + # To omit the instance writer method, pass + # instance_writer: false or instance_accessor: false. + # + # module HairColors + # mattr_writer :hair_colors, instance_writer: false + # end + # + # class Person + # include HairColors + # end + # + # Person.new.hair_colors = [:blonde, :red] # => NoMethodError + # + # You can set a default value for the attribute. + # + # module HairColors + # mattr_writer :hair_colors, default: [:brown, :black, :blonde, :red] + # mattr_writer(:hair_styles) { [:long, :short] } + # end + # + # class Person + # include HairColors + # end + # + # Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red] + # Person.class_variable_get("@@hair_styles") # => [:long, :short] + def mattr_writer(*syms, instance_writer: true, instance_accessor: true, default: nil, location: nil) + raise TypeError, "module attributes should be defined directly on class, not singleton" if singleton_class? + location ||= caller_locations(1, 1).first + + definition = [] + syms.each do |sym| + raise NameError.new("invalid attribute name: #{sym}") unless /\A[_A-Za-z]\w*\z/.match?(sym) + definition << "def self.#{sym}=(val); @@#{sym} = val; end" + + if instance_writer && instance_accessor + definition << "def #{sym}=(val); @@#{sym} = val; end" + end + + sym_default_value = (block_given? && default.nil?) ? yield : default + class_variable_set("@@#{sym}", sym_default_value) unless sym_default_value.nil? && class_variable_defined?("@@#{sym}") + end + + module_eval(definition.join(";"), location.path, location.lineno) + end + alias :cattr_writer :mattr_writer + + # Defines both class and instance accessors for class attributes. + # All class and instance methods created will be public, even if + # this method is called with a private or protected access modifier. + # + # module HairColors + # mattr_accessor :hair_colors + # end + # + # class Person + # include HairColors + # end + # + # HairColors.hair_colors = [:brown, :black, :blonde, :red] + # HairColors.hair_colors # => [:brown, :black, :blonde, :red] + # Person.new.hair_colors # => [:brown, :black, :blonde, :red] + # + # If a subclass changes the value then that would also change the value for + # parent class. Similarly if parent class changes the value then that would + # change the value of subclasses too. + # + # class Citizen < Person + # end + # + # Citizen.new.hair_colors << :blue + # Person.new.hair_colors # => [:brown, :black, :blonde, :red, :blue] + # + # To omit the instance writer method, pass instance_writer: false. + # To omit the instance reader method, pass instance_reader: false. + # + # module HairColors + # mattr_accessor :hair_colors, instance_writer: false, instance_reader: false + # end + # + # class Person + # include HairColors + # end + # + # Person.new.hair_colors = [:brown] # => NoMethodError + # Person.new.hair_colors # => NoMethodError + # + # Or pass instance_accessor: false, to omit both instance methods. + # + # module HairColors + # mattr_accessor :hair_colors, instance_accessor: false + # end + # + # class Person + # include HairColors + # end + # + # Person.new.hair_colors = [:brown] # => NoMethodError + # Person.new.hair_colors # => NoMethodError + # + # You can set a default value for the attribute. + # + # module HairColors + # mattr_accessor :hair_colors, default: [:brown, :black, :blonde, :red] + # mattr_accessor(:hair_styles) { [:long, :short] } + # end + # + # class Person + # include HairColors + # end + # + # Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red] + # Person.class_variable_get("@@hair_styles") # => [:long, :short] + def mattr_accessor(*syms, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil, &blk) + location = caller_locations(1, 1).first + mattr_reader(*syms, instance_reader: instance_reader, instance_accessor: instance_accessor, default: default, location: location, &blk) + mattr_writer(*syms, instance_writer: instance_writer, instance_accessor: instance_accessor, default: default, location: location) + end + alias :cattr_accessor :mattr_accessor +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb new file mode 100644 index 00000000..628da9c9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb @@ -0,0 +1,175 @@ +# frozen_string_literal: true + +# == Attribute Accessors per Thread +# +# Extends the module object with class/module and instance accessors for +# class/module attributes, just like the native attr* accessors for instance +# attributes, but does so on a per-thread basis. +# +# So the values are scoped within the Thread.current space under the class name +# of the module. +# +# Note that it can also be scoped per-fiber if +Rails.application.config.active_support.isolation_level+ +# is set to +:fiber+. +class Module + # Defines a per-thread class attribute and creates class and instance reader methods. + # The underlying per-thread class variable is set to +nil+, if it is not previously defined. + # + # module Current + # thread_mattr_reader :user + # end + # + # Current.user = "DHH" + # Current.user # => "DHH" + # Thread.new { Current.user }.value # => nil + # + # The attribute name must be a valid method name in Ruby. + # + # module Foo + # thread_mattr_reader :"1_Badname" + # end + # # => NameError: invalid attribute name: 1_Badname + # + # To omit the instance reader method, pass + # instance_reader: false or instance_accessor: false. + # + # class Current + # thread_mattr_reader :user, instance_reader: false + # end + # + # Current.new.user # => NoMethodError + def thread_mattr_reader(*syms, instance_reader: true, instance_accessor: true, default: nil) # :nodoc: + syms.each do |sym| + raise NameError.new("invalid attribute name: #{sym}") unless /^[_A-Za-z]\w*$/.match?(sym) + + # The following generated method concatenates `object_id` because we want + # subclasses to maintain independent values. + if default.nil? + class_eval(<<-EOS, __FILE__, __LINE__ + 1) + def self.#{sym} + @__thread_mattr_#{sym} ||= "attr_#{sym}_\#{object_id}" + ::ActiveSupport::IsolatedExecutionState[@__thread_mattr_#{sym}] + end + EOS + else + default = default.dup.freeze unless default.frozen? + singleton_class.define_method("#{sym}_default_value") { default } + + class_eval(<<-EOS, __FILE__, __LINE__ + 1) + def self.#{sym} + @__thread_mattr_#{sym} ||= "attr_#{sym}_\#{object_id}" + value = ::ActiveSupport::IsolatedExecutionState[@__thread_mattr_#{sym}] + + if value.nil? && !::ActiveSupport::IsolatedExecutionState.key?(@__thread_mattr_#{sym}) + ::ActiveSupport::IsolatedExecutionState[@__thread_mattr_#{sym}] = #{sym}_default_value + else + value + end + end + EOS + end + + if instance_reader && instance_accessor + class_eval(<<-EOS, __FILE__, __LINE__ + 1) + def #{sym} + self.class.#{sym} + end + EOS + end + end + end + alias :thread_cattr_reader :thread_mattr_reader + + # Defines a per-thread class attribute and creates a class and instance writer methods to + # allow assignment to the attribute. + # + # module Current + # thread_mattr_writer :user + # end + # + # Current.user = "DHH" + # Thread.current[:attr_Current_user] # => "DHH" + # + # To omit the instance writer method, pass + # instance_writer: false or instance_accessor: false. + # + # class Current + # thread_mattr_writer :user, instance_writer: false + # end + # + # Current.new.user = "DHH" # => NoMethodError + def thread_mattr_writer(*syms, instance_writer: true, instance_accessor: true) # :nodoc: + syms.each do |sym| + raise NameError.new("invalid attribute name: #{sym}") unless /^[_A-Za-z]\w*$/.match?(sym) + + # The following generated method concatenates `object_id` because we want + # subclasses to maintain independent values. + class_eval(<<-EOS, __FILE__, __LINE__ + 1) + def self.#{sym}=(obj) + @__thread_mattr_#{sym} ||= "attr_#{sym}_\#{object_id}" + ::ActiveSupport::IsolatedExecutionState[@__thread_mattr_#{sym}] = obj + end + EOS + + if instance_writer && instance_accessor + class_eval(<<-EOS, __FILE__, __LINE__ + 1) + def #{sym}=(obj) + self.class.#{sym} = obj + end + EOS + end + end + end + alias :thread_cattr_writer :thread_mattr_writer + + # Defines both class and instance accessors for class attributes. + # + # class Account + # thread_mattr_accessor :user + # end + # + # Account.user = "DHH" + # Account.user # => "DHH" + # Account.new.user # => "DHH" + # + # Unlike +mattr_accessor+, values are *not* shared with subclasses or parent classes. + # If a subclass changes the value, the parent class' value is not changed. + # If the parent class changes the value, the value of subclasses is not changed. + # + # class Customer < Account + # end + # + # Account.user # => "DHH" + # Customer.user # => nil + # Customer.user = "Rafael" + # Customer.user # => "Rafael" + # Account.user # => "DHH" + # + # To omit the instance writer method, pass instance_writer: false. + # To omit the instance reader method, pass instance_reader: false. + # + # class Current + # thread_mattr_accessor :user, instance_writer: false, instance_reader: false + # end + # + # Current.new.user = "DHH" # => NoMethodError + # Current.new.user # => NoMethodError + # + # Or pass instance_accessor: false, to omit both instance methods. + # + # class Current + # thread_mattr_accessor :user, instance_accessor: false + # end + # + # Current.new.user = "DHH" # => NoMethodError + # Current.new.user # => NoMethodError + # + # A default value may be specified using the +:default+ option. Because + # multiple threads can access the default value, non-frozen default values + # will be duped and frozen. + def thread_mattr_accessor(*syms, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil) + thread_mattr_reader(*syms, instance_reader: instance_reader, instance_accessor: instance_accessor, default: default) + thread_mattr_writer(*syms, instance_writer: instance_writer, instance_accessor: instance_accessor) + end + alias :thread_cattr_accessor :thread_mattr_accessor +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/concerning.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/concerning.rb new file mode 100644 index 00000000..c8523201 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/concerning.rb @@ -0,0 +1,140 @@ +# frozen_string_literal: true + +require "active_support/concern" + +class Module + # == Bite-sized separation of concerns + # + # We often find ourselves with a medium-sized chunk of behavior that we'd + # like to extract, but only mix in to a single class. + # + # Extracting a plain old Ruby object to encapsulate it and collaborate or + # delegate to the original object is often a good choice, but when there's + # no additional state to encapsulate or we're making DSL-style declarations + # about the parent class, introducing new collaborators can obfuscate rather + # than simplify. + # + # The typical route is to just dump everything in a monolithic class, perhaps + # with a comment, as a least-bad alternative. Using modules in separate files + # means tedious sifting to get a big-picture view. + # + # == Dissatisfying ways to separate small concerns + # + # === Using comments: + # + # class Todo < ApplicationRecord + # # Other todo implementation + # # ... + # + # ## Event tracking + # has_many :events + # + # before_create :track_creation + # + # private + # def track_creation + # # ... + # end + # end + # + # === With an inline module: + # + # Noisy syntax. + # + # class Todo < ApplicationRecord + # # Other todo implementation + # # ... + # + # module EventTracking + # extend ActiveSupport::Concern + # + # included do + # has_many :events + # before_create :track_creation + # end + # + # private + # def track_creation + # # ... + # end + # end + # include EventTracking + # end + # + # === Mix-in noise exiled to its own file: + # + # Once our chunk of behavior starts pushing the scroll-to-understand-it + # boundary, we give in and move it to a separate file. At this size, the + # increased overhead can be a reasonable tradeoff even if it reduces our + # at-a-glance perception of how things work. + # + # class Todo < ApplicationRecord + # # Other todo implementation + # # ... + # + # include TodoEventTracking + # end + # + # == Introducing Module#concerning + # + # By quieting the mix-in noise, we arrive at a natural, low-ceremony way to + # separate bite-sized concerns. + # + # class Todo < ApplicationRecord + # # Other todo implementation + # # ... + # + # concerning :EventTracking do + # included do + # has_many :events + # before_create :track_creation + # end + # + # private + # def track_creation + # # ... + # end + # end + # end + # + # Todo.ancestors + # # => [Todo, Todo::EventTracking, ApplicationRecord, Object] + # + # This small step has some wonderful ripple effects. We can + # * grok the behavior of our class in one glance, + # * clean up monolithic junk-drawer classes by separating their concerns, and + # * stop leaning on protected/private for crude "this is internal stuff" modularity. + # + # === Prepending concerning + # + # concerning supports a prepend: true argument which will prepend the + # concern instead of using include for it. + module Concerning + # Define a new concern and mix it in. + def concerning(topic, prepend: false, &block) + method = prepend ? :prepend : :include + __send__(method, concern(topic, &block)) + end + + # A low-cruft shortcut to define a concern. + # + # concern :EventTracking do + # ... + # end + # + # is equivalent to + # + # module EventTracking + # extend ActiveSupport::Concern + # + # ... + # end + def concern(topic, &module_definition) + const_set topic, Module.new { + extend ::ActiveSupport::Concern + module_eval(&module_definition) + } + end + end + include Concerning +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/delegation.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/delegation.rb new file mode 100644 index 00000000..f306d55f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/delegation.rb @@ -0,0 +1,225 @@ +# frozen_string_literal: true + +class Module + require "active_support/delegation" + DelegationError = ActiveSupport::DelegationError # :nodoc: + + # Provides a +delegate+ class method to easily expose contained objects' + # public methods as your own. + # + # ==== Options + # * :to - Specifies the target object name as a symbol or string + # * :prefix - Prefixes the new method with the target name or a custom prefix + # * :allow_nil - If set to true, prevents a +ActiveSupport::DelegationError+ + # from being raised + # * :private - If set to true, changes method visibility to private + # + # The macro receives one or more method names (specified as symbols or + # strings) and the name of the target object via the :to option + # (also a symbol or string). + # + # Delegation is particularly useful with Active Record associations: + # + # class Greeter < ActiveRecord::Base + # def hello + # 'hello' + # end + # + # def goodbye + # 'goodbye' + # end + # end + # + # class Foo < ActiveRecord::Base + # belongs_to :greeter + # delegate :hello, to: :greeter + # end + # + # Foo.new.hello # => "hello" + # Foo.new.goodbye # => NoMethodError: undefined method `goodbye' for # + # + # Multiple delegates to the same target are allowed: + # + # class Foo < ActiveRecord::Base + # belongs_to :greeter + # delegate :hello, :goodbye, to: :greeter + # end + # + # Foo.new.goodbye # => "goodbye" + # + # Methods can be delegated to instance variables, class variables, or constants + # by providing them as a symbols: + # + # class Foo + # CONSTANT_ARRAY = [0,1,2,3] + # @@class_array = [4,5,6,7] + # + # def initialize + # @instance_array = [8,9,10,11] + # end + # delegate :sum, to: :CONSTANT_ARRAY + # delegate :min, to: :@@class_array + # delegate :max, to: :@instance_array + # end + # + # Foo.new.sum # => 6 + # Foo.new.min # => 4 + # Foo.new.max # => 11 + # + # It's also possible to delegate a method to the class by using +:class+: + # + # class Foo + # def self.hello + # "world" + # end + # + # delegate :hello, to: :class + # end + # + # Foo.new.hello # => "world" + # + # Delegates can optionally be prefixed using the :prefix option. If the value + # is true, the delegate methods are prefixed with the name of the object being + # delegated to. + # + # Person = Struct.new(:name, :address) + # + # class Invoice < Struct.new(:client) + # delegate :name, :address, to: :client, prefix: true + # end + # + # john_doe = Person.new('John Doe', 'Vimmersvej 13') + # invoice = Invoice.new(john_doe) + # invoice.client_name # => "John Doe" + # invoice.client_address # => "Vimmersvej 13" + # + # It is also possible to supply a custom prefix. + # + # class Invoice < Struct.new(:client) + # delegate :name, :address, to: :client, prefix: :customer + # end + # + # invoice = Invoice.new(john_doe) + # invoice.customer_name # => 'John Doe' + # invoice.customer_address # => 'Vimmersvej 13' + # + # The delegated methods are public by default. + # Pass private: true to change that. + # + # class User < ActiveRecord::Base + # has_one :profile + # delegate :first_name, to: :profile + # delegate :date_of_birth, to: :profile, private: true + # + # def age + # Date.today.year - date_of_birth.year + # end + # end + # + # User.new.first_name # => "Tomas" + # User.new.date_of_birth # => NoMethodError: private method `date_of_birth' called for # + # User.new.age # => 2 + # + # If the target is +nil+ and does not respond to the delegated method a + # +ActiveSupport::DelegationError+ is raised. If you wish to instead return +nil+, + # use the :allow_nil option. + # + # class User < ActiveRecord::Base + # has_one :profile + # delegate :age, to: :profile + # end + # + # User.new.age + # # => ActiveSupport::DelegationError: User#age delegated to profile.age, but profile is nil + # + # But if not having a profile yet is fine and should not be an error + # condition: + # + # class User < ActiveRecord::Base + # has_one :profile + # delegate :age, to: :profile, allow_nil: true + # end + # + # User.new.age # nil + # + # Note that if the target is not +nil+ then the call is attempted regardless of the + # :allow_nil option, and thus an exception is still raised if said object + # does not respond to the method: + # + # class Foo + # def initialize(bar) + # @bar = bar + # end + # + # delegate :name, to: :@bar, allow_nil: true + # end + # + # Foo.new("Bar").name # raises NoMethodError: undefined method `name' + # + # The target method must be public, otherwise it will raise +NoMethodError+. + def delegate(*methods, to: nil, prefix: nil, allow_nil: nil, private: nil) + ::ActiveSupport::Delegation.generate( + self, + methods, + location: caller_locations(1, 1).first, + to: to, + prefix: prefix, + allow_nil: allow_nil, + private: private, + ) + end + + # When building decorators, a common pattern may emerge: + # + # class Partition + # def initialize(event) + # @event = event + # end + # + # def person + # detail.person || creator + # end + # + # private + # def respond_to_missing?(name, include_private = false) + # @event.respond_to?(name, include_private) + # end + # + # def method_missing(method, *args, &block) + # @event.send(method, *args, &block) + # end + # end + # + # With Module#delegate_missing_to, the above is condensed to: + # + # class Partition + # delegate_missing_to :@event + # + # def initialize(event) + # @event = event + # end + # + # def person + # detail.person || creator + # end + # end + # + # The target can be anything callable within the object, e.g. instance + # variables, methods, constants, etc. + # + # The delegated method must be public on the target, otherwise it will + # raise +ActiveSupport::DelegationError+. If you wish to instead return +nil+, + # use the :allow_nil option. + # + # The marshal_dump and _dump methods are exempt from + # delegation due to possible interference when calling + # Marshal.dump(object), should the delegation target method + # of object add or remove instance variables. + def delegate_missing_to(target, allow_nil: nil) + ::ActiveSupport::Delegation.generate_method_missing( + self, + target, + allow_nil: allow_nil, + ) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/deprecation.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/deprecation.rb new file mode 100644 index 00000000..420311b3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/deprecation.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +class Module + # deprecate :foo, deprecator: MyLib.deprecator + # deprecate :foo, bar: "warning!", deprecator: MyLib.deprecator + # + # A deprecator is typically an instance of ActiveSupport::Deprecation, but you can also pass any object that responds + # to deprecation_warning(deprecated_method_name, message, caller_backtrace) where you can implement your + # custom warning behavior. + # + # class MyLib::Deprecator + # def deprecation_warning(deprecated_method_name, message, caller_backtrace = nil) + # message = "#{deprecated_method_name} is deprecated and will be removed from MyLibrary | #{message}" + # Kernel.warn message + # end + # end + def deprecate(*method_names, deprecator:, **options) + if deprecator.is_a?(ActiveSupport::Deprecation) + deprecator.deprecate_methods(self, *method_names, **options) + elsif deprecator + # we just need any instance to call deprecate_methods, but the deprecation will be emitted by deprecator + ActiveSupport.deprecator.deprecate_methods(self, *method_names, **options, deprecator: deprecator) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/introspection.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/introspection.rb new file mode 100644 index 00000000..97ee421c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/introspection.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +require "active_support/inflector" + +class Module + # Returns the name of the module containing this one. + # + # M::N.module_parent_name # => "M" + def module_parent_name + if defined?(@parent_name) + @parent_name + else + name = self.name + return if name.nil? + + parent_name = name =~ /::[^:]+\z/ ? -$` : nil + @parent_name = parent_name unless frozen? + parent_name + end + end + + # Returns the module which contains this one according to its name. + # + # module M + # module N + # end + # end + # X = M::N + # + # M::N.module_parent # => M + # X.module_parent # => M + # + # The parent of top-level and anonymous modules is Object. + # + # M.module_parent # => Object + # Module.new.module_parent # => Object + def module_parent + module_parent_name ? ActiveSupport::Inflector.constantize(module_parent_name) : Object + end + + # Returns all the parents of this module according to its name, ordered from + # nested outwards. The receiver is not contained within the result. + # + # module M + # module N + # end + # end + # X = M::N + # + # M.module_parents # => [Object] + # M::N.module_parents # => [M, Object] + # X.module_parents # => [M, Object] + def module_parents + parents = [] + if module_parent_name + parts = module_parent_name.split("::") + until parts.empty? + parents << ActiveSupport::Inflector.constantize(parts * "::") + parts.pop + end + end + parents << Object unless parents.include? Object + parents + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/redefine_method.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/redefine_method.rb new file mode 100644 index 00000000..5bd8e6e9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/redefine_method.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +class Module + # Marks the named method as intended to be redefined, if it exists. + # Suppresses the Ruby method redefinition warning. Prefer + # #redefine_method where possible. + def silence_redefinition_of_method(method) + if method_defined?(method) || private_method_defined?(method) + # This suppresses the "method redefined" warning; the self-alias + # looks odd, but means we don't need to generate a unique name + alias_method method, method + end + end + + # Replaces the existing method definition, if there is one, with the passed + # block as its body. + def redefine_method(method, &block) + visibility = method_visibility(method) + silence_redefinition_of_method(method) + define_method(method, &block) + send(visibility, method) + end + + # Replaces the existing singleton method definition, if there is one, with + # the passed block as its body. + def redefine_singleton_method(method, &block) + singleton_class.redefine_method(method, &block) + end + + def method_visibility(method) # :nodoc: + case + when private_method_defined?(method) + :private + when protected_method_defined?(method) + :protected + else + :public + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/remove_method.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/remove_method.rb new file mode 100644 index 00000000..97eb5f9e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/module/remove_method.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require "active_support/core_ext/module/redefine_method" + +class Module + # Removes the named method, if it exists. + def remove_possible_method(method) + if method_defined?(method) || private_method_defined?(method) + undef_method(method) + end + end + + # Removes the named singleton method, if it exists. + def remove_possible_singleton_method(method) + singleton_class.remove_possible_method(method) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/name_error.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/name_error.rb new file mode 100644 index 00000000..18ea2754 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/name_error.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +class NameError + # Extract the name of the missing constant from the exception message. + # + # begin + # HelloWorld + # rescue NameError => e + # e.missing_name + # end + # # => "HelloWorld" + def missing_name + # Since ruby v2.3.0 `did_you_mean` gem is loaded by default. + # It extends NameError#message with spell corrections which are SLOW. + # We should use original_message message instead. + message = respond_to?(:original_message) ? original_message : self.message + return unless message.start_with?("uninitialized constant ") + + receiver = begin + self.receiver + rescue ArgumentError + nil + end + + if receiver == Object + name.to_s + elsif receiver + "#{real_mod_name(receiver)}::#{self.name}" + else + if match = message.match(/((::)?([A-Z]\w*)(::[A-Z]\w*)*)$/) + match[1] + end + end + end + + # Was this exception raised because the given name was missing? + # + # begin + # HelloWorld + # rescue NameError => e + # e.missing_name?("HelloWorld") + # end + # # => true + def missing_name?(name) + if name.is_a? Symbol + self.name == name + else + missing_name == name.to_s + end + end + + private + UNBOUND_METHOD_MODULE_NAME = Module.instance_method(:name) + private_constant :UNBOUND_METHOD_MODULE_NAME + + def real_mod_name(mod) + UNBOUND_METHOD_MODULE_NAME.bind_call(mod) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/numeric.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/numeric.rb new file mode 100644 index 00000000..fe778470 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/numeric.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +require "active_support/core_ext/numeric/bytes" +require "active_support/core_ext/numeric/time" +require "active_support/core_ext/numeric/conversions" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/numeric/bytes.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/numeric/bytes.rb new file mode 100644 index 00000000..45b38f2b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/numeric/bytes.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +class Numeric + KILOBYTE = 1024 + MEGABYTE = KILOBYTE * 1024 + GIGABYTE = MEGABYTE * 1024 + TERABYTE = GIGABYTE * 1024 + PETABYTE = TERABYTE * 1024 + EXABYTE = PETABYTE * 1024 + ZETTABYTE = EXABYTE * 1024 + + # Enables the use of byte calculations and declarations, like 45.bytes + 2.6.megabytes + # + # 2.bytes # => 2 + def bytes + self + end + alias :byte :bytes + + # Returns the number of bytes equivalent to the kilobytes provided. + # + # 2.kilobytes # => 2048 + def kilobytes + self * KILOBYTE + end + alias :kilobyte :kilobytes + + # Returns the number of bytes equivalent to the megabytes provided. + # + # 2.megabytes # => 2_097_152 + def megabytes + self * MEGABYTE + end + alias :megabyte :megabytes + + # Returns the number of bytes equivalent to the gigabytes provided. + # + # 2.gigabytes # => 2_147_483_648 + def gigabytes + self * GIGABYTE + end + alias :gigabyte :gigabytes + + # Returns the number of bytes equivalent to the terabytes provided. + # + # 2.terabytes # => 2_199_023_255_552 + def terabytes + self * TERABYTE + end + alias :terabyte :terabytes + + # Returns the number of bytes equivalent to the petabytes provided. + # + # 2.petabytes # => 2_251_799_813_685_248 + def petabytes + self * PETABYTE + end + alias :petabyte :petabytes + + # Returns the number of bytes equivalent to the exabytes provided. + # + # 2.exabytes # => 2_305_843_009_213_693_952 + def exabytes + self * EXABYTE + end + alias :exabyte :exabytes + + # Returns the number of bytes equivalent to the zettabytes provided. + # + # 2.zettabytes # => 2_361_183_241_434_822_606_848 + def zettabytes + self * ZETTABYTE + end + alias :zettabyte :zettabytes +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/numeric/conversions.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/numeric/conversions.rb new file mode 100644 index 00000000..e9839931 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/numeric/conversions.rb @@ -0,0 +1,145 @@ +# frozen_string_literal: true + +require "active_support/core_ext/big_decimal/conversions" +require "active_support/number_helper" + +module ActiveSupport + module NumericWithFormat + # \Numeric With Format + # + # Provides options for converting numbers into formatted strings. + # Options are provided for phone numbers, currency, percentage, + # precision, positional notation, file size, and pretty printing. + # + # This method is aliased to to_formatted_s. + # + # ==== Options + # + # For details on which formats use which options, see ActiveSupport::NumberHelper + # + # ==== Examples + # + # Phone Numbers: + # 5551234.to_fs(:phone) # => "555-1234" + # 1235551234.to_fs(:phone) # => "123-555-1234" + # 1235551234.to_fs(:phone, area_code: true) # => "(123) 555-1234" + # 1235551234.to_fs(:phone, delimiter: ' ') # => "123 555 1234" + # 1235551234.to_fs(:phone, area_code: true, extension: 555) # => "(123) 555-1234 x 555" + # 1235551234.to_fs(:phone, country_code: 1) # => "+1-123-555-1234" + # 1235551234.to_fs(:phone, country_code: 1, extension: 1343, delimiter: '.') + # # => "+1.123.555.1234 x 1343" + # + # Currency: + # 1234567890.50.to_fs(:currency) # => "$1,234,567,890.50" + # 1234567890.506.to_fs(:currency) # => "$1,234,567,890.51" + # 1234567890.506.to_fs(:currency, precision: 3) # => "$1,234,567,890.506" + # 1234567890.506.to_fs(:currency, round_mode: :down) # => "$1,234,567,890.50" + # 1234567890.506.to_fs(:currency, locale: :fr) # => "1 234 567 890,51 €" + # -1234567890.50.to_fs(:currency, negative_format: '(%u%n)') + # # => "($1,234,567,890.50)" + # 1234567890.50.to_fs(:currency, unit: '£', separator: ',', delimiter: '') + # # => "£1234567890,50" + # 1234567890.50.to_fs(:currency, unit: '£', separator: ',', delimiter: '', format: '%n %u') + # # => "1234567890,50 £" + # + # Percentage: + # 100.to_fs(:percentage) # => "100.000%" + # 100.to_fs(:percentage, precision: 0) # => "100%" + # 1000.to_fs(:percentage, delimiter: '.', separator: ',') # => "1.000,000%" + # 302.24398923423.to_fs(:percentage, precision: 5) # => "302.24399%" + # 302.24398923423.to_fs(:percentage, round_mode: :down) # => "302.243%" + # 1000.to_fs(:percentage, locale: :fr) # => "1 000,000%" + # 100.to_fs(:percentage, format: '%n %') # => "100.000 %" + # + # Delimited: + # 12345678.to_fs(:delimited) # => "12,345,678" + # 12345678.05.to_fs(:delimited) # => "12,345,678.05" + # 12345678.to_fs(:delimited, delimiter: '.') # => "12.345.678" + # 12345678.to_fs(:delimited, delimiter: ',') # => "12,345,678" + # 12345678.05.to_fs(:delimited, separator: ' ') # => "12,345,678 05" + # 12345678.05.to_fs(:delimited, locale: :fr) # => "12 345 678,05" + # 98765432.98.to_fs(:delimited, delimiter: ' ', separator: ',') + # # => "98 765 432,98" + # + # Rounded: + # 111.2345.to_fs(:rounded) # => "111.235" + # 111.2345.to_fs(:rounded, precision: 2) # => "111.23" + # 111.2345.to_fs(:rounded, precision: 2, round_mode: :up) # => "111.24" + # 13.to_fs(:rounded, precision: 5) # => "13.00000" + # 389.32314.to_fs(:rounded, precision: 0) # => "389" + # 111.2345.to_fs(:rounded, significant: true) # => "111" + # 111.2345.to_fs(:rounded, precision: 1, significant: true) # => "100" + # 13.to_fs(:rounded, precision: 5, significant: true) # => "13.000" + # 111.234.to_fs(:rounded, locale: :fr) # => "111,234" + # 13.to_fs(:rounded, precision: 5, significant: true, strip_insignificant_zeros: true) + # # => "13" + # 389.32314.to_fs(:rounded, precision: 4, significant: true) # => "389.3" + # 1111.2345.to_fs(:rounded, precision: 2, separator: ',', delimiter: '.') + # # => "1.111,23" + # + # Human-friendly size in Bytes: + # 123.to_fs(:human_size) # => "123 Bytes" + # 1234.to_fs(:human_size) # => "1.21 KB" + # 12345.to_fs(:human_size) # => "12.1 KB" + # 1234567.to_fs(:human_size) # => "1.18 MB" + # 1234567890.to_fs(:human_size) # => "1.15 GB" + # 1234567890123.to_fs(:human_size) # => "1.12 TB" + # 1234567890123456.to_fs(:human_size) # => "1.1 PB" + # 1234567890123456789.to_fs(:human_size) # => "1.07 EB" + # 1234567.to_fs(:human_size, precision: 2) # => "1.2 MB" + # 1234567.to_fs(:human_size, precision: 2, round_mode: :up) # => "1.3 MB" + # 483989.to_fs(:human_size, precision: 2) # => "470 KB" + # 1234567.to_fs(:human_size, precision: 2, separator: ',') # => "1,2 MB" + # 1234567890123.to_fs(:human_size, precision: 5) # => "1.1228 TB" + # 524288000.to_fs(:human_size, precision: 5) # => "500 MB" + # + # Human-friendly format: + # 123.to_fs(:human) # => "123" + # 1234.to_fs(:human) # => "1.23 Thousand" + # 12345.to_fs(:human) # => "12.3 Thousand" + # 1234567.to_fs(:human) # => "1.23 Million" + # 1234567890.to_fs(:human) # => "1.23 Billion" + # 1234567890123.to_fs(:human) # => "1.23 Trillion" + # 1234567890123456.to_fs(:human) # => "1.23 Quadrillion" + # 1234567890123456789.to_fs(:human) # => "1230 Quadrillion" + # 489939.to_fs(:human, precision: 2) # => "490 Thousand" + # 489939.to_fs(:human, precision: 2, round_mode: :down) # => "480 Thousand" + # 489939.to_fs(:human, precision: 4) # => "489.9 Thousand" + # 1234567.to_fs(:human, precision: 4, + # significant: false) # => "1.2346 Million" + # 1234567.to_fs(:human, precision: 1, + # separator: ',', + # significant: false) # => "1,2 Million" + def to_fs(format = nil, options = nil) + return to_s if format.nil? + + case format + when Integer, String + to_s(format) + when :phone + ActiveSupport::NumberHelper.number_to_phone(self, options || {}) + when :currency + ActiveSupport::NumberHelper.number_to_currency(self, options || {}) + when :percentage + ActiveSupport::NumberHelper.number_to_percentage(self, options || {}) + when :delimited + ActiveSupport::NumberHelper.number_to_delimited(self, options || {}) + when :rounded + ActiveSupport::NumberHelper.number_to_rounded(self, options || {}) + when :human + ActiveSupport::NumberHelper.number_to_human(self, options || {}) + when :human_size + ActiveSupport::NumberHelper.number_to_human_size(self, options || {}) + when Symbol + to_s + else + to_s(format) + end + end + alias_method :to_formatted_s, :to_fs + end +end + +Integer.include ActiveSupport::NumericWithFormat +Float.include ActiveSupport::NumericWithFormat +BigDecimal.include ActiveSupport::NumericWithFormat diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/numeric/time.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/numeric/time.rb new file mode 100644 index 00000000..bc4627f7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/numeric/time.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +require "active_support/duration" +require "active_support/core_ext/time/calculations" +require "active_support/core_ext/time/acts_like" +require "active_support/core_ext/date/calculations" +require "active_support/core_ext/date/acts_like" + +class Numeric + # Returns a Duration instance matching the number of seconds provided. + # + # 2.seconds # => 2 seconds + def seconds + ActiveSupport::Duration.seconds(self) + end + alias :second :seconds + + # Returns a Duration instance matching the number of minutes provided. + # + # 2.minutes # => 2 minutes + def minutes + ActiveSupport::Duration.minutes(self) + end + alias :minute :minutes + + # Returns a Duration instance matching the number of hours provided. + # + # 2.hours # => 2 hours + def hours + ActiveSupport::Duration.hours(self) + end + alias :hour :hours + + # Returns a Duration instance matching the number of days provided. + # + # 2.days # => 2 days + def days + ActiveSupport::Duration.days(self) + end + alias :day :days + + # Returns a Duration instance matching the number of weeks provided. + # + # 2.weeks # => 2 weeks + def weeks + ActiveSupport::Duration.weeks(self) + end + alias :week :weeks + + # Returns a Duration instance matching the number of fortnights provided. + # + # 2.fortnights # => 4 weeks + def fortnights + ActiveSupport::Duration.weeks(self * 2) + end + alias :fortnight :fortnights + + # Returns the number of milliseconds equivalent to the seconds provided. + # Used with the standard time durations. + # + # 2.in_milliseconds # => 2000 + # 1.hour.in_milliseconds # => 3600000 + def in_milliseconds + self * 1000 + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object.rb new file mode 100644 index 00000000..7a7f0d99 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require "active_support/core_ext/object/acts_like" +require "active_support/core_ext/object/blank" +require "active_support/core_ext/object/duplicable" +require "active_support/core_ext/object/deep_dup" +require "active_support/core_ext/object/try" +require "active_support/core_ext/object/inclusion" + +require "active_support/core_ext/object/conversions" +require "active_support/core_ext/object/instance_variables" + +require "active_support/core_ext/object/json" +require "active_support/core_ext/object/to_param" +require "active_support/core_ext/object/to_query" +require "active_support/core_ext/object/with" +require "active_support/core_ext/object/with_options" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/acts_like.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/acts_like.rb new file mode 100644 index 00000000..292826c8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/acts_like.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +class Object + # Provides a way to check whether some class acts like some other class based on the existence of + # an appropriately-named marker method. + # + # A class that provides the same interface as SomeClass may define a marker method named + # acts_like_some_class? to signal its compatibility to callers of + # acts_like?(:some_class). + # + # For example, Active Support extends Date to define an acts_like_date? method, + # and extends Time to define acts_like_time?. As a result, developers can call + # x.acts_like?(:time) and x.acts_like?(:date) to test duck-type compatibility, + # and classes that are able to act like Time can also define an acts_like_time? + # method to interoperate. + # + # Note that the marker method is only expected to exist. It isn't called, so its body or return + # value are irrelevant. + # + # ==== Example: A class that provides the same interface as String + # + # This class may define: + # + # class Stringish + # def acts_like_string? + # end + # end + # + # Then client code can query for duck-type-safeness this way: + # + # Stringish.new.acts_like?(:string) # => true + # + def acts_like?(duck) + case duck + when :time + respond_to? :acts_like_time? + when :date + respond_to? :acts_like_date? + when :string + respond_to? :acts_like_string? + else + respond_to? :"acts_like_#{duck}?" + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/blank.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/blank.rb new file mode 100644 index 00000000..967c82ed --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/blank.rb @@ -0,0 +1,199 @@ +# frozen_string_literal: true + +require "concurrent/map" + +class Object + # An object is blank if it's false, empty, or a whitespace string. + # For example, +nil+, '', ' ', [], {}, and +false+ are all blank. + # + # This simplifies + # + # !address || address.empty? + # + # to + # + # address.blank? + # + # @return [true, false] + def blank? + respond_to?(:empty?) ? !!empty? : false + end + + # An object is present if it's not blank. + # + # @return [true, false] + def present? + !blank? + end + + # Returns the receiver if it's present otherwise returns +nil+. + # object.presence is equivalent to + # + # object.present? ? object : nil + # + # For example, something like + # + # state = params[:state] if params[:state].present? + # country = params[:country] if params[:country].present? + # region = state || country || 'US' + # + # becomes + # + # region = params[:state].presence || params[:country].presence || 'US' + # + # @return [Object] + def presence + self if present? + end +end + +class NilClass + # +nil+ is blank: + # + # nil.blank? # => true + # + # @return [true] + def blank? + true + end + + def present? # :nodoc: + false + end +end + +class FalseClass + # +false+ is blank: + # + # false.blank? # => true + # + # @return [true] + def blank? + true + end + + def present? # :nodoc: + false + end +end + +class TrueClass + # +true+ is not blank: + # + # true.blank? # => false + # + # @return [false] + def blank? + false + end + + def present? # :nodoc: + true + end +end + +class Array + # An array is blank if it's empty: + # + # [].blank? # => true + # [1,2,3].blank? # => false + # + # @return [true, false] + alias_method :blank?, :empty? + + def present? # :nodoc: + !empty? + end +end + +class Hash + # A hash is blank if it's empty: + # + # {}.blank? # => true + # { key: 'value' }.blank? # => false + # + # @return [true, false] + alias_method :blank?, :empty? + + def present? # :nodoc: + !empty? + end +end + +class Symbol + # A Symbol is blank if it's empty: + # + # :''.blank? # => true + # :symbol.blank? # => false + alias_method :blank?, :empty? + + def present? # :nodoc: + !empty? + end +end + +class String + BLANK_RE = /\A[[:space:]]*\z/ + ENCODED_BLANKS = Concurrent::Map.new do |h, enc| + h[enc] = Regexp.new(BLANK_RE.source.encode(enc), BLANK_RE.options | Regexp::FIXEDENCODING) + end + + # A string is blank if it's empty or contains whitespaces only: + # + # ''.blank? # => true + # ' '.blank? # => true + # "\t\n\r".blank? # => true + # ' blah '.blank? # => false + # + # Unicode whitespace is supported: + # + # "\u00a0".blank? # => true + # + # @return [true, false] + def blank? + # The regexp that matches blank strings is expensive. For the case of empty + # strings we can speed up this method (~3.5x) with an empty? call. The + # penalty for the rest of strings is marginal. + empty? || + begin + BLANK_RE.match?(self) + rescue Encoding::CompatibilityError + ENCODED_BLANKS[self.encoding].match?(self) + end + end + + def present? # :nodoc: + !blank? + end +end + +class Numeric # :nodoc: + # No number is blank: + # + # 1.blank? # => false + # 0.blank? # => false + # + # @return [false] + def blank? + false + end + + def present? + true + end +end + +class Time # :nodoc: + # No Time is blank: + # + # Time.now.blank? # => false + # + # @return [false] + def blank? + false + end + + def present? + true + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/conversions.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/conversions.rb new file mode 100644 index 00000000..624fb8d7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/conversions.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +require "active_support/core_ext/object/to_param" +require "active_support/core_ext/object/to_query" +require "active_support/core_ext/array/conversions" +require "active_support/core_ext/hash/conversions" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/deep_dup.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/deep_dup.rb new file mode 100644 index 00000000..7d54d0cd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/deep_dup.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +require "active_support/core_ext/object/duplicable" + +class Object + # Returns a deep copy of object if it's duplicable. If it's + # not duplicable, returns +self+. + # + # object = Object.new + # dup = object.deep_dup + # dup.instance_variable_set(:@a, 1) + # + # object.instance_variable_defined?(:@a) # => false + # dup.instance_variable_defined?(:@a) # => true + def deep_dup + duplicable? ? dup : self + end +end + +class Array + # Returns a deep copy of array. + # + # array = [1, [2, 3]] + # dup = array.deep_dup + # dup[1][2] = 4 + # + # array[1][2] # => nil + # dup[1][2] # => 4 + def deep_dup + map(&:deep_dup) + end +end + +class Hash + # Returns a deep copy of hash. + # + # hash = { a: { b: 'b' } } + # dup = hash.deep_dup + # dup[:a][:c] = 'c' + # + # hash[:a][:c] # => nil + # dup[:a][:c] # => "c" + def deep_dup + hash = dup + each_pair do |key, value| + if ::String === key || ::Symbol === key + hash[key] = value.deep_dup + else + hash.delete(key) + hash[key.deep_dup] = value.deep_dup + end + end + hash + end +end + +class Module + # Returns a copy of module or class if it's anonymous. If it's + # named, returns +self+. + # + # Object.deep_dup == Object # => true + # klass = Class.new + # klass.deep_dup == klass # => false + def deep_dup + if name.nil? + super + else + self + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/duplicable.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/duplicable.rb new file mode 100644 index 00000000..505455fe --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/duplicable.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +#-- +# Most objects are cloneable, but not all. For example you can't dup methods: +# +# method(:puts).dup # => TypeError: allocator undefined for Method +# +# Classes may signal their instances are not duplicable removing +dup+/+clone+ +# or raising exceptions from them. So, to dup an arbitrary object you normally +# use an optimistic approach and are ready to catch an exception, say: +# +# arbitrary_object.dup rescue object +# +# Rails dups objects in a few critical spots where they are not that arbitrary. +# That rescue is very expensive (like 40 times slower than a predicate), and it +# is often triggered. +# +# That's why we hardcode the following cases and check duplicable? instead of +# using that rescue idiom. +#++ +class Object + # Can you safely dup this object? + # + # False for method objects; + # true otherwise. + def duplicable? + true + end +end + +methods_are_duplicable = begin + Object.instance_method(:duplicable?).dup + true +rescue TypeError + false +end + +unless methods_are_duplicable + class Method + # Methods are not duplicable: + # + # method(:puts).duplicable? # => false + # method(:puts).dup # => TypeError: allocator undefined for Method + def duplicable? + false + end + end + + class UnboundMethod + # Unbound methods are not duplicable: + # + # method(:puts).unbind.duplicable? # => false + # method(:puts).unbind.dup # => TypeError: allocator undefined for UnboundMethod + def duplicable? + false + end + end +end + +require "singleton" + +module Singleton + # Singleton instances are not duplicable: + # + # Class.new.include(Singleton).instance.dup # TypeError (can't dup instance of singleton + def duplicable? + false + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/inclusion.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/inclusion.rb new file mode 100644 index 00000000..1b3cf2c3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/inclusion.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +class Object + # Returns true if this object is included in the argument. + # + # When argument is a +Range+, +#cover?+ is used to properly handle inclusion + # check within open ranges. Otherwise, argument must be any object which responds + # to +#include?+. Usage: + # + # characters = ["Konata", "Kagami", "Tsukasa"] + # "Konata".in?(characters) # => true + # + # For non +Range+ arguments, this will throw an +ArgumentError+ if the argument + # doesn't respond to +#include?+. + def in?(another_object) + case another_object + when Range + another_object.cover?(self) + else + another_object.include?(self) + end + rescue NoMethodError + raise ArgumentError.new("The parameter passed to #in? must respond to #include?") + end + + # Returns the receiver if it's included in the argument otherwise returns +nil+. + # Argument must be any object which responds to +#include?+. Usage: + # + # params[:bucket_type].presence_in %w( project calendar ) + # + # This will throw an +ArgumentError+ if the argument doesn't respond to +#include?+. + # + # @return [Object] + def presence_in(another_object) + in?(another_object) ? self : nil + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/instance_variables.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/instance_variables.rb new file mode 100644 index 00000000..98b341d3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/instance_variables.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +class Object + # Returns a hash with string keys that maps instance variable names without "@" to their + # corresponding values. + # + # class C + # def initialize(x, y) + # @x, @y = x, y + # end + # end + # + # C.new(0, 1).instance_values # => {"x" => 0, "y" => 1} + def instance_values + instance_variables.to_h do |ivar| + [ivar[1..-1].freeze, instance_variable_get(ivar)] + end + end + + # Returns an array of instance variable names as strings including "@". + # + # class C + # def initialize(x, y) + # @x, @y = x, y + # end + # end + # + # C.new(0, 1).instance_variable_names # => ["@y", "@x"] + def instance_variable_names + instance_variables.map(&:name) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/json.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/json.rb new file mode 100644 index 00000000..3d6e536e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/json.rb @@ -0,0 +1,260 @@ +# frozen_string_literal: true + +# Hack to load JSON gem first so we can override its to_json. +require "json" +require "bigdecimal" +require "ipaddr" +require "uri/generic" +require "pathname" +require "active_support/core_ext/big_decimal/conversions" # for #to_s +require "active_support/core_ext/hash/except" +require "active_support/core_ext/hash/slice" +require "active_support/core_ext/object/instance_variables" +require "time" +require "active_support/core_ext/time/conversions" +require "active_support/core_ext/date_time/conversions" +require "active_support/core_ext/date/conversions" + +#-- +# The JSON gem adds a few modules to Ruby core classes containing :to_json definition, overwriting +# their default behavior. That said, we need to define the basic to_json method in all of them, +# otherwise they will always use to_json gem implementation, which is backwards incompatible in +# several cases (for instance, the JSON implementation for Hash does not work) with inheritance. +# +# On the other hand, we should avoid conflict with ::JSON.{generate,dump}(obj). Unfortunately, the +# JSON gem's encoder relies on its own to_json implementation to encode objects. Since it always +# passes a ::JSON::State object as the only argument to to_json, we can detect that and forward the +# calls to the original to_json method. +# +# It should be noted that when using ::JSON.{generate,dump} directly, ActiveSupport's encoder is +# bypassed completely. This means that as_json won't be invoked and the JSON gem will simply +# ignore any options it does not natively understand. This also means that ::JSON.{generate,dump} +# should give exactly the same results with or without Active Support. + +module ActiveSupport + module ToJsonWithActiveSupportEncoder # :nodoc: + def to_json(options = nil) + if options.is_a?(::JSON::State) + # Called from JSON.{generate,dump}, forward it to JSON gem's to_json + super(options) + else + # to_json is being invoked directly, use ActiveSupport's encoder + ActiveSupport::JSON.encode(self, options) + end + end + end +end + +[Enumerable, Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass].reverse_each do |klass| + klass.include(ActiveSupport::ToJsonWithActiveSupportEncoder) +end + +class Module + def as_json(options = nil) # :nodoc: + name + end +end + +class Object + def as_json(options = nil) # :nodoc: + if respond_to?(:to_hash) + to_hash.as_json(options) + else + instance_values.as_json(options) + end + end +end + +class Data # :nodoc: + def as_json(options = nil) + to_h.as_json(options) + end +end + +class Struct # :nodoc: + def as_json(options = nil) + to_h.as_json(options) + end +end + +class TrueClass + def as_json(options = nil) # :nodoc: + self + end +end + +class FalseClass + def as_json(options = nil) # :nodoc: + self + end +end + +class NilClass + def as_json(options = nil) # :nodoc: + self + end +end + +class String + def as_json(options = nil) # :nodoc: + self + end +end + +class Symbol + def as_json(options = nil) # :nodoc: + name + end +end + +class Numeric + def as_json(options = nil) # :nodoc: + self + end +end + +class Float + # Encoding Infinity or NaN to JSON should return "null". The default returns + # "Infinity" or "NaN" which are not valid JSON. + def as_json(options = nil) # :nodoc: + finite? ? self : nil + end +end + +class BigDecimal + # A BigDecimal would be naturally represented as a JSON number. Most libraries, + # however, parse non-integer JSON numbers directly as floats. Clients using + # those libraries would get in general a wrong number and no way to recover + # other than manually inspecting the string with the JSON code itself. + # + # That's why a JSON string is returned. The JSON literal is not numeric, but + # if the other end knows by contract that the data is supposed to be a + # BigDecimal, it still has the chance to post-process the string and get the + # real value. + def as_json(options = nil) # :nodoc: + finite? ? to_s : nil + end +end + +class Regexp + def as_json(options = nil) # :nodoc: + to_s + end +end + +module Enumerable + def as_json(options = nil) # :nodoc: + to_a.as_json(options) + end +end + +class IO + def as_json(options = nil) # :nodoc: + to_s + end +end + +class Range + def as_json(options = nil) # :nodoc: + to_s + end +end + +class Array + def as_json(options = nil) # :nodoc: + if options + options = options.dup.freeze unless options.frozen? + map { |v| v.as_json(options) } + else + map { |v| v.as_json } + end + end +end + +class Hash + def as_json(options = nil) # :nodoc: + # create a subset of the hash by applying :only or :except + subset = if options + if attrs = options[:only] + slice(*Array(attrs)) + elsif attrs = options[:except] + except(*Array(attrs)) + else + self + end + else + self + end + + result = {} + if options + options = options.dup.freeze unless options.frozen? + subset.each { |k, v| result[k.to_s] = v.as_json(options) } + else + subset.each { |k, v| result[k.to_s] = v.as_json } + end + result + end +end + +class Time + def as_json(options = nil) # :nodoc: + if ActiveSupport::JSON::Encoding.use_standard_json_time_format + xmlschema(ActiveSupport::JSON::Encoding.time_precision) + else + %(#{strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)}) + end + end +end + +class Date + def as_json(options = nil) # :nodoc: + if ActiveSupport::JSON::Encoding.use_standard_json_time_format + strftime("%Y-%m-%d") + else + strftime("%Y/%m/%d") + end + end +end + +class DateTime + def as_json(options = nil) # :nodoc: + if ActiveSupport::JSON::Encoding.use_standard_json_time_format + xmlschema(ActiveSupport::JSON::Encoding.time_precision) + else + strftime("%Y/%m/%d %H:%M:%S %z") + end + end +end + +class URI::Generic # :nodoc: + def as_json(options = nil) + to_s + end +end + +class Pathname # :nodoc: + def as_json(options = nil) + to_s + end +end + +unless IPAddr.method_defined?(:as_json, false) + class IPAddr # :nodoc: + def as_json(options = nil) + to_s + end + end +end + +class Process::Status # :nodoc: + def as_json(options = nil) + { exitstatus: exitstatus, pid: pid } + end +end + +class Exception + def as_json(options = nil) + to_s + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/to_param.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/to_param.rb new file mode 100644 index 00000000..6d2bdd70 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/to_param.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +require "active_support/core_ext/object/to_query" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/to_query.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/to_query.rb new file mode 100644 index 00000000..7cccc03d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/to_query.rb @@ -0,0 +1,87 @@ +# frozen_string_literal: true + +require "cgi" + +class Object + # Alias of to_s. + def to_param + to_s + end + + # Converts an object into a string suitable for use as a URL query string, + # using the given key as the param name. + def to_query(key) + "#{CGI.escape(key.to_param)}=#{CGI.escape(to_param.to_s)}" + end +end + +class NilClass + # Returns +self+. + def to_param + self + end +end + +class TrueClass + # Returns +self+. + def to_param + self + end +end + +class FalseClass + # Returns +self+. + def to_param + self + end +end + +class Array + # Calls to_param on all its elements and joins the result with + # slashes. This is used by url_for in Action Pack. + def to_param + collect(&:to_param).join "/" + end + + # Converts an array into a string suitable for use as a URL query string, + # using the given +key+ as the param name. + # + # ['Rails', 'coding'].to_query('hobbies') # => "hobbies%5B%5D=Rails&hobbies%5B%5D=coding" + def to_query(key) + prefix = "#{key}[]" + + if empty? + nil.to_query(prefix) + else + collect { |value| value.to_query(prefix) }.join "&" + end + end +end + +class Hash + # Returns a string representation of the receiver suitable for use as a URL + # query string: + # + # {name: 'David', nationality: 'Danish'}.to_query + # # => "name=David&nationality=Danish" + # + # An optional namespace can be passed to enclose key names: + # + # {name: 'David', nationality: 'Danish'}.to_query('user') + # # => "user%5Bname%5D=David&user%5Bnationality%5D=Danish" + # + # The string pairs "key=value" that conform the query string + # are sorted lexicographically in ascending order. + def to_query(namespace = nil) + query = filter_map do |key, value| + unless (value.is_a?(Hash) || value.is_a?(Array)) && value.empty? + value.to_query(namespace ? "#{namespace}[#{key}]" : key) + end + end + + query.sort! unless namespace.to_s.include?("[]") + query.join("&") + end + + alias_method :to_param, :to_query +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/try.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/try.rb new file mode 100644 index 00000000..c2c76254 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/try.rb @@ -0,0 +1,158 @@ +# frozen_string_literal: true + +require "delegate" + +module ActiveSupport + module Tryable # :nodoc: + def try(*args, &block) + if args.empty? && block_given? + if block.arity == 0 + instance_eval(&block) + else + yield self + end + elsif respond_to?(args.first) + public_send(*args, &block) + end + end + ruby2_keywords(:try) + + def try!(*args, &block) + if args.empty? && block_given? + if block.arity == 0 + instance_eval(&block) + else + yield self + end + else + public_send(*args, &block) + end + end + ruby2_keywords(:try!) + end +end + +class Object + include ActiveSupport::Tryable + + ## + # :method: try + # + # :call-seq: + # try(*args, &block) + # + # Invokes the public method whose name goes as first argument just like + # +public_send+ does, except that if the receiver does not respond to it the + # call returns +nil+ rather than raising an exception. + # + # This method is defined to be able to write + # + # @person.try(:name) + # + # instead of + # + # @person.name if @person + # + # +try+ calls can be chained: + # + # @person.try(:spouse).try(:name) + # + # instead of + # + # @person.spouse.name if @person && @person.spouse + # + # +try+ will also return +nil+ if the receiver does not respond to the method: + # + # @person.try(:non_existing_method) # => nil + # + # instead of + # + # @person.non_existing_method if @person.respond_to?(:non_existing_method) # => nil + # + # +try+ returns +nil+ when called on +nil+ regardless of whether it responds + # to the method: + # + # nil.try(:to_i) # => nil, rather than 0 + # + # Arguments and blocks are forwarded to the method if invoked: + # + # @posts.try(:each_slice, 2) do |a, b| + # ... + # end + # + # The number of arguments in the signature must match. If the object responds + # to the method the call is attempted and +ArgumentError+ is still raised + # in case of argument mismatch. + # + # If +try+ is called without arguments it yields the receiver to a given + # block unless it is +nil+: + # + # @person.try do |p| + # ... + # end + # + # You can also call try with a block without accepting an argument, and the block + # will be instance_eval'ed instead: + # + # @person.try { upcase.truncate(50) } + # + # Please also note that +try+ is defined on +Object+. Therefore, it won't work + # with instances of classes that do not have +Object+ among their ancestors, + # like direct subclasses of +BasicObject+. + + ## + # :method: try! + # + # :call-seq: + # try!(*args, &block) + # + # Same as #try, but raises a +NoMethodError+ exception if the receiver is + # not +nil+ and does not implement the tried method. + # + # "a".try!(:upcase) # => "A" + # nil.try!(:upcase) # => nil + # 123.try!(:upcase) # => NoMethodError: undefined method `upcase' for 123:Integer +end + +class Delegator + include ActiveSupport::Tryable + + ## + # :method: try + # + # :call-seq: + # try(*args, &block) + # + # See Object#try + + ## + # :method: try! + # + # :call-seq: + # try!(*args, &block) + # + # See Object#try! +end + +class NilClass + # Calling +try+ on +nil+ always returns +nil+. + # It becomes especially helpful when navigating through associations that may return +nil+. + # + # nil.try(:name) # => nil + # + # Without +try+ + # @person && @person.children.any? && @person.children.first.name + # + # With +try+ + # @person.try(:children).try(:first).try(:name) + def try(*) + nil + end + + # Calling +try!+ on +nil+ always returns +nil+. + # + # nil.try!(:name) # => nil + def try!(*) + nil + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/with.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/with.rb new file mode 100644 index 00000000..29f61088 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/with.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +class Object + # Set and restore public attributes around a block. + # + # client.timeout # => 5 + # client.with(timeout: 1) do |c| + # c.timeout # => 1 + # end + # client.timeout # => 5 + # + # The receiver is yielded to the provided block. + # + # This method is a shorthand for the common begin/ensure pattern: + # + # old_value = object.attribute + # begin + # object.attribute = new_value + # # do things + # ensure + # object.attribute = old_value + # end + # + # It can be used on any object as long as both the reader and writer methods + # are public. + def with(**attributes) + old_values = {} + begin + attributes.each do |key, value| + old_values[key] = public_send(key) + public_send("#{key}=", value) + end + yield self + ensure + old_values.each do |key, old_value| + public_send("#{key}=", old_value) + end + end + end +end + +# #with isn't usable on immediates, so we might as well undefine the +# method in common immediate classes to avoid potential confusion. +[NilClass, TrueClass, FalseClass, Integer, Float, Symbol].each do |klass| + klass.undef_method(:with) +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/with_options.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/with_options.rb new file mode 100644 index 00000000..932aec22 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/object/with_options.rb @@ -0,0 +1,101 @@ +# frozen_string_literal: true + +require "active_support/option_merger" + +class Object + # An elegant way to factor duplication out of options passed to a series of + # method calls. Each method called in the block, with the block variable as + # the receiver, will have its options merged with the default +options+ + # Hash or Hash-like object provided. Each method called on + # the block variable must take an options hash as its final argument. + # + # Without with_options, this code contains duplication: + # + # class Account < ActiveRecord::Base + # has_many :customers, dependent: :destroy + # has_many :products, dependent: :destroy + # has_many :invoices, dependent: :destroy + # has_many :expenses, dependent: :destroy + # end + # + # Using with_options, we can remove the duplication: + # + # class Account < ActiveRecord::Base + # with_options dependent: :destroy do |assoc| + # assoc.has_many :customers + # assoc.has_many :products + # assoc.has_many :invoices + # assoc.has_many :expenses + # end + # end + # + # It can also be used with an explicit receiver: + # + # I18n.with_options locale: user.locale, scope: 'newsletter' do |i18n| + # subject i18n.t :subject + # body i18n.t :body, user_name: user.name + # end + # + # When you don't pass an explicit receiver, it executes the whole block + # in merging options context: + # + # class Account < ActiveRecord::Base + # with_options dependent: :destroy do + # has_many :customers + # has_many :products + # has_many :invoices + # has_many :expenses + # end + # end + # + # with_options can also be nested since the call is forwarded to its receiver. + # + # NOTE: Each nesting level will merge inherited defaults in addition to their own. + # + # class Post < ActiveRecord::Base + # with_options if: :persisted?, length: { minimum: 50 } do + # validates :content, if: -> { content.present? } + # end + # end + # + # The code is equivalent to: + # + # validates :content, length: { minimum: 50 }, if: -> { content.present? } + # + # Hence the inherited default for +if+ key is ignored. + # + # NOTE: You cannot call class methods implicitly inside of +with_options+. + # You can access these methods using the class name instead: + # + # class Phone < ActiveRecord::Base + # enum :phone_number_type, { home: 0, office: 1, mobile: 2 } + # + # with_options presence: true do + # validates :phone_number_type, inclusion: { in: Phone.phone_number_types.keys } + # end + # end + # + # When the block argument is omitted, the decorated Object instance is returned: + # + # module MyStyledHelpers + # def styled + # with_options style: "color: red;" + # end + # end + # + # styled.link_to "I'm red", "/" + # # => I'm red + # + # styled.button_tag "I'm red too!" + # # => + # + def with_options(options, &block) + option_merger = ActiveSupport::OptionMerger.new(self, options) + + if block + block.arity.zero? ? option_merger.instance_eval(&block) : block.call(option_merger) + else + option_merger + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/pathname.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/pathname.rb new file mode 100644 index 00000000..10fa1903 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/pathname.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +require "active_support/core_ext/pathname/blank" +require "active_support/core_ext/pathname/existence" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/pathname/blank.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/pathname/blank.rb new file mode 100644 index 00000000..8a9be3ce --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/pathname/blank.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require "pathname" + +class Pathname + # An Pathname is blank if it's empty: + # + # Pathname.new("").blank? # => true + # Pathname.new(" ").blank? # => false + # Pathname.new("test").blank? # => false + # + # @return [true, false] + def blank? + to_s.empty? + end + + def present? # :nodoc: + !to_s.empty? + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/pathname/existence.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/pathname/existence.rb new file mode 100644 index 00000000..848eb4dc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/pathname/existence.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require "pathname" + +class Pathname + # Returns the receiver if the named file exists otherwise returns +nil+. + # pathname.existence is equivalent to + # + # pathname.exist? ? pathname : nil + # + # For example, something like + # + # content = pathname.read if pathname.exist? + # + # becomes + # + # content = pathname.existence&.read + # + # @return [Pathname] + def existence + self if exist? + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/range.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/range.rb new file mode 100644 index 00000000..10fad28d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/range.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +require "active_support/core_ext/range/conversions" +require "active_support/core_ext/range/compare_range" +require "active_support/core_ext/range/overlap" +require "active_support/core_ext/range/each" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/range/compare_range.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/range/compare_range.rb new file mode 100644 index 00000000..affbbebb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/range/compare_range.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +module ActiveSupport + module CompareWithRange + # Extends the default Range#=== to support range comparisons. + # (1..5) === (1..5) # => true + # (1..5) === (2..3) # => true + # (1..5) === (1...6) # => true + # (1..5) === (2..6) # => false + # + # The native Range#=== behavior is untouched. + # ('a'..'f') === ('c') # => true + # (5..9) === (11) # => false + # + # The given range must be fully bounded, with both start and end. + def ===(value) + if value.is_a?(::Range) + is_backwards_op = value.exclude_end? ? :>= : :> + return false if value.begin && value.end && value.begin.public_send(is_backwards_op, value.end) + # 1...10 includes 1..9 but it does not include 1..10. + # 1..10 includes 1...11 but it does not include 1...12. + operator = exclude_end? && !value.exclude_end? ? :< : :<= + value_max = !exclude_end? && value.exclude_end? ? value.max : value.last + super(value.first) && (self.end.nil? || value_max.public_send(operator, last)) + else + super + end + end + + # Extends the default Range#include? to support range comparisons. + # (1..5).include?(1..5) # => true + # (1..5).include?(2..3) # => true + # (1..5).include?(1...6) # => true + # (1..5).include?(2..6) # => false + # + # The native Range#include? behavior is untouched. + # ('a'..'f').include?('c') # => true + # (5..9).include?(11) # => false + # + # The given range must be fully bounded, with both start and end. + def include?(value) + if value.is_a?(::Range) + is_backwards_op = value.exclude_end? ? :>= : :> + return false if value.begin && value.end && value.begin.public_send(is_backwards_op, value.end) + # 1...10 includes 1..9 but it does not include 1..10. + # 1..10 includes 1...11 but it does not include 1...12. + operator = exclude_end? && !value.exclude_end? ? :< : :<= + value_max = !exclude_end? && value.exclude_end? ? value.max : value.last + super(value.first) && (self.end.nil? || value_max.public_send(operator, last)) + else + super + end + end + end +end + +Range.prepend(ActiveSupport::CompareWithRange) diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/range/conversions.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/range/conversions.rb new file mode 100644 index 00000000..b6d81864 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/range/conversions.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +module ActiveSupport + # = \Range With Format + module RangeWithFormat + RANGE_FORMATS = { + db: -> (start, stop) do + if start && stop + case start + when String then "BETWEEN '#{start}' AND '#{stop}'" + else + "BETWEEN '#{start.to_fs(:db)}' AND '#{stop.to_fs(:db)}'" + end + elsif start + case start + when String then ">= '#{start}'" + else + ">= '#{start.to_fs(:db)}'" + end + elsif stop + case stop + when String then "<= '#{stop}'" + else + "<= '#{stop.to_fs(:db)}'" + end + end + end + } + + # Convert range to a formatted string. See RANGE_FORMATS for predefined formats. + # + # This method is aliased to to_formatted_s. + # + # range = (1..100) # => 1..100 + # + # range.to_s # => "1..100" + # range.to_fs(:db) # => "BETWEEN '1' AND '100'" + # + # range = (1..) # => 1.. + # range.to_fs(:db) # => ">= '1'" + # + # range = (..100) # => ..100 + # range.to_fs(:db) # => "<= '100'" + # + # == Adding your own range formats to to_fs + # You can add your own formats to the Range::RANGE_FORMATS hash. + # Use the format name as the hash key and a Proc instance. + # + # # config/initializers/range_formats.rb + # Range::RANGE_FORMATS[:short] = ->(start, stop) { "Between #{start.to_fs(:db)} and #{stop.to_fs(:db)}" } + def to_fs(format = :default) + if formatter = RANGE_FORMATS[format] + formatter.call(self.begin, self.end) + else + to_s + end + end + alias_method :to_formatted_s, :to_fs + end +end + +Range.prepend(ActiveSupport::RangeWithFormat) diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/range/each.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/range/each.rb new file mode 100644 index 00000000..1c44cc84 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/range/each.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require "active_support/time_with_zone" + +module ActiveSupport + module EachTimeWithZone # :nodoc: + def each(&block) + ensure_iteration_allowed + super + end + + def step(n = 1, &block) + ensure_iteration_allowed + super + end + + private + def ensure_iteration_allowed + raise TypeError, "can't iterate from #{first.class}" if first.is_a?(TimeWithZone) + end + end +end + +Range.prepend(ActiveSupport::EachTimeWithZone) diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/range/overlap.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/range/overlap.rb new file mode 100644 index 00000000..b08cdb39 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/range/overlap.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +class Range + # Compare two ranges and see if they overlap each other + # (1..5).overlap?(4..6) # => true + # (1..5).overlap?(7..9) # => false + unless Range.method_defined?(:overlap?) # Ruby 3.3+ + def overlap?(other) + raise TypeError unless other.is_a? Range + + self_begin = self.begin + other_end = other.end + other_excl = other.exclude_end? + + return false if _empty_range?(self_begin, other_end, other_excl) + + other_begin = other.begin + self_end = self.end + self_excl = self.exclude_end? + + return false if _empty_range?(other_begin, self_end, self_excl) + return true if self_begin == other_begin + + return false if _empty_range?(self_begin, self_end, self_excl) + return false if _empty_range?(other_begin, other_end, other_excl) + + true + end + + private + def _empty_range?(b, e, excl) + return false if b.nil? || e.nil? + + comp = b <=> e + comp.nil? || comp > 0 || (comp == 0 && excl) + end + end + + alias :overlaps? :overlap? +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/regexp.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/regexp.rb new file mode 100644 index 00000000..15534ff5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/regexp.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +class Regexp + # Returns +true+ if the regexp has the multiline flag set. + # + # (/./).multiline? # => false + # (/./m).multiline? # => true + # + # Regexp.new(".").multiline? # => false + # Regexp.new(".", Regexp::MULTILINE).multiline? # => true + def multiline? + options & MULTILINE == MULTILINE + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/securerandom.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/securerandom.rb new file mode 100644 index 00000000..aae75290 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/securerandom.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +require "securerandom" + +module SecureRandom + BASE58_ALPHABET = ("0".."9").to_a + ("A".."Z").to_a + ("a".."z").to_a - ["0", "O", "I", "l"] + BASE36_ALPHABET = ("0".."9").to_a + ("a".."z").to_a + + # SecureRandom.base58 generates a random base58 string. + # + # The argument _n_ specifies the length of the random string to be generated. + # + # If _n_ is not specified or is +nil+, 16 is assumed. It may be larger in the future. + # + # The result may contain alphanumeric characters except 0, O, I, and l. + # + # p SecureRandom.base58 # => "4kUgL2pdQMSCQtjE" + # p SecureRandom.base58(24) # => "77TMHrHJFvFDwodq8w7Ev2m7" + if SecureRandom.method(:alphanumeric).parameters.size == 2 # Remove check when Ruby 3.3 is the minimum supported version + def self.base58(n = 16) + alphanumeric(n, chars: BASE58_ALPHABET) + end + else + def self.base58(n = 16) + SecureRandom.random_bytes(n).unpack("C*").map do |byte| + idx = byte % 64 + idx = SecureRandom.random_number(58) if idx >= 58 + BASE58_ALPHABET[idx] + end.join + end + end + + # SecureRandom.base36 generates a random base36 string in lowercase. + # + # The argument _n_ specifies the length of the random string to be generated. + # + # If _n_ is not specified or is +nil+, 16 is assumed. It may be larger in the future. + # This method can be used over +base58+ if a deterministic case key is necessary. + # + # The result will contain alphanumeric characters in lowercase. + # + # p SecureRandom.base36 # => "4kugl2pdqmscqtje" + # p SecureRandom.base36(24) # => "77tmhrhjfvfdwodq8w7ev2m7" + if SecureRandom.method(:alphanumeric).parameters.size == 2 # Remove check when Ruby 3.3 is the minimum supported version + def self.base36(n = 16) + alphanumeric(n, chars: BASE36_ALPHABET) + end + else + def self.base36(n = 16) + SecureRandom.random_bytes(n).unpack("C*").map do |byte| + idx = byte % 64 + idx = SecureRandom.random_number(36) if idx >= 36 + BASE36_ALPHABET[idx] + end.join + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string.rb new file mode 100644 index 00000000..757d15c5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require "active_support/core_ext/string/conversions" +require "active_support/core_ext/string/filters" +require "active_support/core_ext/string/multibyte" +require "active_support/core_ext/string/starts_ends_with" +require "active_support/core_ext/string/inflections" +require "active_support/core_ext/string/access" +require "active_support/core_ext/string/behavior" +require "active_support/core_ext/string/output_safety" +require "active_support/core_ext/string/exclude" +require "active_support/core_ext/string/strip" +require "active_support/core_ext/string/inquiry" +require "active_support/core_ext/string/indent" +require "active_support/core_ext/string/zones" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/access.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/access.rb new file mode 100644 index 00000000..f6a14c08 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/access.rb @@ -0,0 +1,95 @@ +# frozen_string_literal: true + +class String + # If you pass a single integer, returns a substring of one character at that + # position. The first character of the string is at position 0, the next at + # position 1, and so on. If a range is supplied, a substring containing + # characters at offsets given by the range is returned. In both cases, if an + # offset is negative, it is counted from the end of the string. Returns +nil+ + # if the initial offset falls outside the string. Returns an empty string if + # the beginning of the range is greater than the end of the string. + # + # str = "hello" + # str.at(0) # => "h" + # str.at(1..3) # => "ell" + # str.at(-2) # => "l" + # str.at(-2..-1) # => "lo" + # str.at(5) # => nil + # str.at(5..-1) # => "" + # + # If a Regexp is given, the matching portion of the string is returned. + # If a String is given, that given string is returned if it occurs in + # the string. In both cases, +nil+ is returned if there is no match. + # + # str = "hello" + # str.at(/lo/) # => "lo" + # str.at(/ol/) # => nil + # str.at("lo") # => "lo" + # str.at("ol") # => nil + def at(position) + self[position] + end + + # Returns a substring from the given position to the end of the string. + # If the position is negative, it is counted from the end of the string. + # + # str = "hello" + # str.from(0) # => "hello" + # str.from(3) # => "lo" + # str.from(-2) # => "lo" + # + # You can mix it with +to+ method and do fun things like: + # + # str = "hello" + # str.from(0).to(-1) # => "hello" + # str.from(1).to(-2) # => "ell" + def from(position) + self[position, length] + end + + # Returns a substring from the beginning of the string to the given position. + # If the position is negative, it is counted from the end of the string. + # + # str = "hello" + # str.to(0) # => "h" + # str.to(3) # => "hell" + # str.to(-2) # => "hell" + # + # You can mix it with +from+ method and do fun things like: + # + # str = "hello" + # str.from(0).to(-1) # => "hello" + # str.from(1).to(-2) # => "ell" + def to(position) + position += size if position < 0 + self[0, position + 1] || +"" + end + + # Returns the first character. If a limit is supplied, returns a substring + # from the beginning of the string until it reaches the limit value. If the + # given limit is greater than or equal to the string length, returns a copy of self. + # + # str = "hello" + # str.first # => "h" + # str.first(1) # => "h" + # str.first(2) # => "he" + # str.first(0) # => "" + # str.first(6) # => "hello" + def first(limit = 1) + self[0, limit] || raise(ArgumentError, "negative limit") + end + + # Returns the last character of the string. If a limit is supplied, returns a substring + # from the end of the string until it reaches the limit value (counting backwards). If + # the given limit is greater than or equal to the string length, returns a copy of self. + # + # str = "hello" + # str.last # => "o" + # str.last(1) # => "o" + # str.last(2) # => "lo" + # str.last(0) # => "" + # str.last(6) # => "hello" + def last(limit = 1) + self[[length - limit, 0].max, limit] || raise(ArgumentError, "negative limit") + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/behavior.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/behavior.rb new file mode 100644 index 00000000..35a5aa78 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/behavior.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +class String + # Enables more predictable duck-typing on String-like classes. See Object#acts_like?. + def acts_like_string? + true + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/conversions.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/conversions.rb new file mode 100644 index 00000000..107721c6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/conversions.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require "date" +require "active_support/core_ext/time/calculations" + +class String + # Converts a string to a Time value. + # The +form+ can be either +:utc+ or +:local+ (default +:local+). + # + # The time is parsed using Time.parse method. + # If +form+ is +:local+, then the time is in the system timezone. + # If the date part is missing then the current date is used and if + # the time part is missing then it is assumed to be 00:00:00. + # + # "13-12-2012".to_time # => 2012-12-13 00:00:00 +0100 + # "06:12".to_time # => 2012-12-13 06:12:00 +0100 + # "2012-12-13 06:12".to_time # => 2012-12-13 06:12:00 +0100 + # "2012-12-13T06:12".to_time # => 2012-12-13 06:12:00 +0100 + # "2012-12-13T06:12".to_time(:utc) # => 2012-12-13 06:12:00 UTC + # "12/13/2012".to_time # => ArgumentError: argument out of range + # "1604326192".to_time # => ArgumentError: argument out of range + def to_time(form = :local) + parts = Date._parse(self, false) + used_keys = %i(year mon mday hour min sec sec_fraction offset) + return if !parts.keys.intersect?(used_keys) + + now = Time.now + time = Time.new( + parts.fetch(:year, now.year), + parts.fetch(:mon, now.month), + parts.fetch(:mday, now.day), + parts.fetch(:hour, 0), + parts.fetch(:min, 0), + parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0), + parts.fetch(:offset, form == :utc ? 0 : nil) + ) + + form == :utc ? time.utc : time.to_time + end + + # Converts a string to a Date value. + # + # "1-1-2012".to_date # => Sun, 01 Jan 2012 + # "01/01/2012".to_date # => Sun, 01 Jan 2012 + # "2012-12-13".to_date # => Thu, 13 Dec 2012 + # "12/13/2012".to_date # => ArgumentError: invalid date + def to_date + ::Date.parse(self, false) unless blank? + end + + # Converts a string to a DateTime value. + # + # "1-1-2012".to_datetime # => Sun, 01 Jan 2012 00:00:00 +0000 + # "01/01/2012 23:59:59".to_datetime # => Sun, 01 Jan 2012 23:59:59 +0000 + # "2012-12-13 12:50".to_datetime # => Thu, 13 Dec 2012 12:50:00 +0000 + # "12/13/2012".to_datetime # => ArgumentError: invalid date + def to_datetime + ::DateTime.parse(self, false) unless blank? + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/exclude.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/exclude.rb new file mode 100644 index 00000000..8e462689 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/exclude.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class String + # The inverse of String#include?. Returns true if the string + # does not include the other string. + # + # "hello".exclude? "lo" # => false + # "hello".exclude? "ol" # => true + # "hello".exclude? ?h # => false + def exclude?(string) + !include?(string) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/filters.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/filters.rb new file mode 100644 index 00000000..9e7e5511 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/filters.rb @@ -0,0 +1,151 @@ +# frozen_string_literal: true + +class String + # Returns the string, first removing all whitespace on both ends of + # the string, and then changing remaining consecutive whitespace + # groups into one space each. + # + # Note that it handles both ASCII and Unicode whitespace. + # + # %{ Multi-line + # string }.squish # => "Multi-line string" + # " foo bar \n \t boo".squish # => "foo bar boo" + def squish + dup.squish! + end + + # Performs a destructive squish. See String#squish. + # str = " foo bar \n \t boo" + # str.squish! # => "foo bar boo" + # str # => "foo bar boo" + def squish! + gsub!(/[[:space:]]+/, " ") + strip! + self + end + + # Returns a new string with all occurrences of the patterns removed. + # str = "foo bar test" + # str.remove(" test") # => "foo bar" + # str.remove(" test", /bar/) # => "foo " + # str # => "foo bar test" + def remove(*patterns) + dup.remove!(*patterns) + end + + # Alters the string by removing all occurrences of the patterns. + # str = "foo bar test" + # str.remove!(" test", /bar/) # => "foo " + # str # => "foo " + def remove!(*patterns) + patterns.each do |pattern| + gsub! pattern, "" + end + + self + end + + # Truncates a given +text+ to length truncate_to if +text+ is longer than truncate_to: + # + # 'Once upon a time in a world far far away'.truncate(27) + # # => "Once upon a time in a wo..." + # + # Pass a string or regexp :separator to truncate +text+ at a natural break: + # + # 'Once upon a time in a world far far away'.truncate(27, separator: ' ') + # # => "Once upon a time in a..." + # + # 'Once upon a time in a world far far away'.truncate(27, separator: /\s/) + # # => "Once upon a time in a..." + # + # The last characters will be replaced with the :omission string (defaults to "..."). + # The total length will not exceed truncate_to unless both +text+ and :omission + # are longer than truncate_to: + # + # 'And they found that many people were sleeping better.'.truncate(25, omission: '... (continued)') + # # => "And they f... (continued)" + # + # 'And they found that many people were sleeping better.'.truncate(4, omission: '... (continued)') + # # => "... (continued)" + def truncate(truncate_to, options = {}) + return dup unless length > truncate_to + + omission = options[:omission] || "..." + length_with_room_for_omission = truncate_to - omission.length + stop = \ + if options[:separator] + rindex(options[:separator], length_with_room_for_omission) || length_with_room_for_omission + else + length_with_room_for_omission + end + + +"#{self[0, stop]}#{omission}" + end + + # Truncates +text+ to at most truncate_to bytes in length without + # breaking string encoding by splitting multibyte characters or breaking + # grapheme clusters ("perceptual characters") by truncating at combining + # characters. + # + # >> "🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪".size + # => 20 + # >> "🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪".bytesize + # => 80 + # >> "🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪🔪".truncate_bytes(20) + # => "🔪🔪🔪🔪…" + # + # The truncated text ends with the :omission string, defaulting + # to "…", for a total length not exceeding truncate_to. + # + # Raises +ArgumentError+ when the bytesize of :omission exceeds truncate_to. + def truncate_bytes(truncate_to, omission: "…") + omission ||= "" + + case + when bytesize <= truncate_to + dup + when omission.bytesize > truncate_to + raise ArgumentError, "Omission #{omission.inspect} is #{omission.bytesize}, larger than the truncation length of #{truncate_to} bytes" + when omission.bytesize == truncate_to + omission.dup + else + self.class.new.force_encoding(encoding).tap do |cut| + cut_at = truncate_to - omission.bytesize + + each_grapheme_cluster do |grapheme| + if cut.bytesize + grapheme.bytesize <= cut_at + cut << grapheme + else + break + end + end + + cut << omission + end + end + end + + # Truncates a given +text+ after a given number of words (words_count): + # + # 'Once upon a time in a world far far away'.truncate_words(4) + # # => "Once upon a time..." + # + # Pass a string or regexp :separator to specify a different separator of words: + # + # 'Once
upon
a
time
in
a
world'.truncate_words(5, separator: '
') + # # => "Once
upon
a
time
in..." + # + # The last characters will be replaced with the :omission string (defaults to "..."): + # + # 'And they found that many people were sleeping better.'.truncate_words(5, omission: '... (continued)') + # # => "And they found that many... (continued)" + def truncate_words(words_count, options = {}) + sep = options[:separator] || /\s+/ + sep = Regexp.escape(sep.to_s) unless Regexp === sep + if self =~ /\A((?>.+?#{sep}){#{words_count - 1}}.+?)#{sep}.*/m + $1 + (options[:omission] || "...") + else + dup + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/indent.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/indent.rb new file mode 100644 index 00000000..9dcc4302 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/indent.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +class String + # Same as +indent+, except it indents the receiver in-place. + # + # Returns the indented string, or +nil+ if there was nothing to indent. + def indent!(amount, indent_string = nil, indent_empty_lines = false) + indent_string = indent_string || self[/^[ \t]/] || " " + re = indent_empty_lines ? /^/ : /^(?!$)/ + gsub!(re, indent_string * amount) + end + + # Indents the lines in the receiver: + # + # < + # def some_method + # some_code + # end + # + # The second argument, +indent_string+, specifies which indent string to + # use. The default is +nil+, which tells the method to make a guess by + # peeking at the first indented line, and fall back to a space if there is + # none. + # + # " foo".indent(2) # => " foo" + # "foo\n\t\tbar".indent(2) # => "\t\tfoo\n\t\t\t\tbar" + # "foo".indent(2, "\t") # => "\t\tfoo" + # + # While +indent_string+ is typically one space or tab, it may be any string. + # + # The third argument, +indent_empty_lines+, is a flag that says whether + # empty lines should be indented. Default is false. + # + # "foo\n\nbar".indent(2) # => " foo\n\n bar" + # "foo\n\nbar".indent(2, nil, true) # => " foo\n \n bar" + # + def indent(amount, indent_string = nil, indent_empty_lines = false) + dup.tap { |_| _.indent!(amount, indent_string, indent_empty_lines) } + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/inflections.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/inflections.rb new file mode 100644 index 00000000..da127c9a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/inflections.rb @@ -0,0 +1,300 @@ +# frozen_string_literal: true + +require "active_support/inflector/methods" +require "active_support/inflector/transliterate" + +# String inflections define new methods on the String class to transform names for different purposes. +# For instance, you can figure out the name of a table from the name of a class. +# +# 'ScaleScore'.tableize # => "scale_scores" +# +class String + # Returns the plural form of the word in the string. + # + # If the optional parameter +count+ is specified, + # the singular form will be returned if count == 1. + # For any other value of +count+ the plural will be returned. + # + # If the optional parameter +locale+ is specified, + # the word will be pluralized as a word of that language. + # By default, this parameter is set to :en. + # You must define your own inflection rules for languages other than English. + # + # 'post'.pluralize # => "posts" + # 'octopus'.pluralize # => "octopi" + # 'sheep'.pluralize # => "sheep" + # 'words'.pluralize # => "words" + # 'the blue mailman'.pluralize # => "the blue mailmen" + # 'CamelOctopus'.pluralize # => "CamelOctopi" + # 'apple'.pluralize(1) # => "apple" + # 'apple'.pluralize(2) # => "apples" + # 'ley'.pluralize(:es) # => "leyes" + # 'ley'.pluralize(1, :es) # => "ley" + # + # See ActiveSupport::Inflector.pluralize. + def pluralize(count = nil, locale = :en) + locale = count if count.is_a?(Symbol) + if count == 1 + dup + else + ActiveSupport::Inflector.pluralize(self, locale) + end + end + + # The reverse of +pluralize+, returns the singular form of a word in a string. + # + # If the optional parameter +locale+ is specified, + # the word will be singularized as a word of that language. + # By default, this parameter is set to :en. + # You must define your own inflection rules for languages other than English. + # + # 'posts'.singularize # => "post" + # 'octopi'.singularize # => "octopus" + # 'sheep'.singularize # => "sheep" + # 'word'.singularize # => "word" + # 'the blue mailmen'.singularize # => "the blue mailman" + # 'CamelOctopi'.singularize # => "CamelOctopus" + # 'leyes'.singularize(:es) # => "ley" + # + # See ActiveSupport::Inflector.singularize. + def singularize(locale = :en) + ActiveSupport::Inflector.singularize(self, locale) + end + + # +constantize+ tries to find a declared constant with the name specified + # in the string. It raises a NameError when the name is not in CamelCase + # or is not initialized. + # + # 'Module'.constantize # => Module + # 'Class'.constantize # => Class + # 'blargle'.constantize # => NameError: wrong constant name blargle + # + # See ActiveSupport::Inflector.constantize. + def constantize + ActiveSupport::Inflector.constantize(self) + end + + # +safe_constantize+ tries to find a declared constant with the name specified + # in the string. It returns +nil+ when the name is not in CamelCase + # or is not initialized. + # + # 'Module'.safe_constantize # => Module + # 'Class'.safe_constantize # => Class + # 'blargle'.safe_constantize # => nil + # + # See ActiveSupport::Inflector.safe_constantize. + def safe_constantize + ActiveSupport::Inflector.safe_constantize(self) + end + + # By default, +camelize+ converts strings to UpperCamelCase. If the argument to camelize + # is set to :lower then camelize produces lowerCamelCase. + # + # +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces. + # + # 'active_record'.camelize # => "ActiveRecord" + # 'active_record'.camelize(:lower) # => "activeRecord" + # 'active_record/errors'.camelize # => "ActiveRecord::Errors" + # 'active_record/errors'.camelize(:lower) # => "activeRecord::Errors" + # + # See ActiveSupport::Inflector.camelize. + def camelize(first_letter = :upper) + case first_letter + when :upper + ActiveSupport::Inflector.camelize(self, true) + when :lower + ActiveSupport::Inflector.camelize(self, false) + else + raise ArgumentError, "Invalid option, use either :upper or :lower." + end + end + alias_method :camelcase, :camelize + + # Capitalizes all the words and replaces some characters in the string to create + # a nicer looking title. +titleize+ is meant for creating pretty output. It is not + # used in the \Rails internals. + # + # The trailing '_id','Id'.. can be kept and capitalized by setting the + # optional parameter +keep_id_suffix+ to true. + # By default, this parameter is false. + # + # 'man from the boondocks'.titleize # => "Man From The Boondocks" + # 'x-men: the last stand'.titleize # => "X Men: The Last Stand" + # 'string_ending_with_id'.titleize(keep_id_suffix: true) # => "String Ending With Id" + # + # See ActiveSupport::Inflector.titleize. + def titleize(keep_id_suffix: false) + ActiveSupport::Inflector.titleize(self, keep_id_suffix: keep_id_suffix) + end + alias_method :titlecase, :titleize + + # The reverse of +camelize+. Makes an underscored, lowercase form from the expression in the string. + # + # +underscore+ will also change '::' to '/' to convert namespaces to paths. + # + # 'ActiveModel'.underscore # => "active_model" + # 'ActiveModel::Errors'.underscore # => "active_model/errors" + # + # See ActiveSupport::Inflector.underscore. + def underscore + ActiveSupport::Inflector.underscore(self) + end + + # Replaces underscores with dashes in the string. + # + # 'puni_puni'.dasherize # => "puni-puni" + # + # See ActiveSupport::Inflector.dasherize. + def dasherize + ActiveSupport::Inflector.dasherize(self) + end + + # Removes the module part from the constant expression in the string. + # + # 'ActiveSupport::Inflector::Inflections'.demodulize # => "Inflections" + # 'Inflections'.demodulize # => "Inflections" + # '::Inflections'.demodulize # => "Inflections" + # ''.demodulize # => '' + # + # See ActiveSupport::Inflector.demodulize. + # + # See also +deconstantize+. + def demodulize + ActiveSupport::Inflector.demodulize(self) + end + + # Removes the rightmost segment from the constant expression in the string. + # + # 'Net::HTTP'.deconstantize # => "Net" + # '::Net::HTTP'.deconstantize # => "::Net" + # 'String'.deconstantize # => "" + # '::String'.deconstantize # => "" + # ''.deconstantize # => "" + # + # See ActiveSupport::Inflector.deconstantize. + # + # See also +demodulize+. + def deconstantize + ActiveSupport::Inflector.deconstantize(self) + end + + # Replaces special characters in a string so that it may be used as part of a 'pretty' URL. + # + # If the optional parameter +locale+ is specified, + # the word will be parameterized as a word of that language. + # By default, this parameter is set to nil and it will use + # the configured I18n.locale. + # + # class Person + # def to_param + # "#{id}-#{name.parameterize}" + # end + # end + # + # @person = Person.find(1) + # # => # + # + # <%= link_to(@person.name, person_path) %> + # # => Donald E. Knuth + # + # To preserve the case of the characters in a string, use the +preserve_case+ argument. + # + # class Person + # def to_param + # "#{id}-#{name.parameterize(preserve_case: true)}" + # end + # end + # + # @person = Person.find(1) + # # => # + # + # <%= link_to(@person.name, person_path) %> + # # => Donald E. Knuth + # + # See ActiveSupport::Inflector.parameterize. + def parameterize(separator: "-", preserve_case: false, locale: nil) + ActiveSupport::Inflector.parameterize(self, separator: separator, preserve_case: preserve_case, locale: locale) + end + + # Creates the name of a table like \Rails does for models to table names. This method + # uses the +pluralize+ method on the last word in the string. + # + # 'RawScaledScorer'.tableize # => "raw_scaled_scorers" + # 'ham_and_egg'.tableize # => "ham_and_eggs" + # 'fancyCategory'.tableize # => "fancy_categories" + # + # See ActiveSupport::Inflector.tableize. + def tableize + ActiveSupport::Inflector.tableize(self) + end + + # Creates a class name from a plural table name like \Rails does for table names to models. + # Note that this returns a string and not a class. (To convert to an actual class + # follow +classify+ with +constantize+.) + # + # 'ham_and_eggs'.classify # => "HamAndEgg" + # 'posts'.classify # => "Post" + # + # See ActiveSupport::Inflector.classify. + def classify + ActiveSupport::Inflector.classify(self) + end + + # Capitalizes the first word, turns underscores into spaces, and (by default) strips a + # trailing '_id' if present. + # Like +titleize+, this is meant for creating pretty output. + # + # The capitalization of the first word can be turned off by setting the + # optional parameter +capitalize+ to false. + # By default, this parameter is true. + # + # The trailing '_id' can be kept and capitalized by setting the + # optional parameter +keep_id_suffix+ to true. + # By default, this parameter is false. + # + # 'employee_salary'.humanize # => "Employee salary" + # 'author_id'.humanize # => "Author" + # 'author_id'.humanize(capitalize: false) # => "author" + # '_id'.humanize # => "Id" + # 'author_id'.humanize(keep_id_suffix: true) # => "Author id" + # + # See ActiveSupport::Inflector.humanize. + def humanize(capitalize: true, keep_id_suffix: false) + ActiveSupport::Inflector.humanize(self, capitalize: capitalize, keep_id_suffix: keep_id_suffix) + end + + # Converts the first character to uppercase. + # + # 'what a Lovely Day'.upcase_first # => "What a Lovely Day" + # 'w'.upcase_first # => "W" + # ''.upcase_first # => "" + # + # See ActiveSupport::Inflector.upcase_first. + def upcase_first + ActiveSupport::Inflector.upcase_first(self) + end + + # Converts the first character to lowercase. + # + # 'If they enjoyed The Matrix'.downcase_first # => "if they enjoyed The Matrix" + # 'I'.downcase_first # => "i" + # ''.downcase_first # => "" + # + # See ActiveSupport::Inflector.downcase_first. + def downcase_first + ActiveSupport::Inflector.downcase_first(self) + end + + # Creates a foreign key name from a class name. + # +separate_class_name_and_id_with_underscore+ sets whether + # the method should put '_' between the name and 'id'. + # + # 'Message'.foreign_key # => "message_id" + # 'Message'.foreign_key(false) # => "messageid" + # 'Admin::Post'.foreign_key # => "post_id" + # + # See ActiveSupport::Inflector.foreign_key. + def foreign_key(separate_class_name_and_id_with_underscore = true) + ActiveSupport::Inflector.foreign_key(self, separate_class_name_and_id_with_underscore) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/inquiry.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/inquiry.rb new file mode 100644 index 00000000..a3b42dad --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/inquiry.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require "active_support/string_inquirer" +require "active_support/environment_inquirer" + +class String + # Wraps the current string in the ActiveSupport::StringInquirer class, + # which gives you a prettier way to test for equality. + # + # env = 'production'.inquiry + # env.production? # => true + # env.development? # => false + def inquiry + ActiveSupport::StringInquirer.new(self) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/multibyte.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/multibyte.rb new file mode 100644 index 00000000..b74de3f1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/multibyte.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require "active_support/multibyte" + +class String + # == Multibyte proxy + # + # +mb_chars+ is a multibyte safe proxy for string methods. + # + # It creates and returns an instance of the ActiveSupport::Multibyte::Chars class which + # encapsulates the original string. A Unicode safe version of all the String methods are defined on this proxy + # class. If the proxy class doesn't respond to a certain method, it's forwarded to the encapsulated string. + # + # >> "lj".mb_chars.upcase.to_s + # => "LJ" + # + # NOTE: Ruby 2.4 and later support native Unicode case mappings: + # + # >> "lj".upcase + # => "LJ" + # + # == \Method chaining + # + # All the methods on the Chars proxy which normally return a string will return a Chars object. This allows + # method chaining on the result of any of these methods. + # + # name.mb_chars.reverse.length # => 12 + # + # == Interoperability and configuration + # + # The Chars object tries to be as interchangeable with String objects as possible: sorting and comparing between + # String and Char work like expected. The bang! methods change the internal string representation in the Chars + # object. Interoperability problems can be resolved easily with a +to_s+ call. + # + # For more information about the methods defined on the Chars proxy see ActiveSupport::Multibyte::Chars. For + # information about how to change the default Multibyte behavior see ActiveSupport::Multibyte. + def mb_chars + ActiveSupport::Multibyte.proxy_class.new(self) + end + + # Returns +true+ if string has utf_8 encoding. + # + # utf_8_str = "some string".encode "UTF-8" + # iso_str = "some string".encode "ISO-8859-1" + # + # utf_8_str.is_utf8? # => true + # iso_str.is_utf8? # => false + def is_utf8? + case encoding + when Encoding::UTF_8, Encoding::US_ASCII + valid_encoding? + when Encoding::ASCII_8BIT + dup.force_encoding(Encoding::UTF_8).valid_encoding? + else + false + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/output_safety.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/output_safety.rb new file mode 100644 index 00000000..8e44c045 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/output_safety.rb @@ -0,0 +1,228 @@ +# frozen_string_literal: true + +require "active_support/core_ext/erb/util" +require "active_support/multibyte/unicode" + +class Object + def html_safe? + false + end +end + +class Numeric + def html_safe? + true + end +end + +module ActiveSupport # :nodoc: + class SafeBuffer < String + UNSAFE_STRING_METHODS = %w( + capitalize chomp chop delete delete_prefix delete_suffix + downcase lstrip next reverse rstrip scrub squeeze strip + succ swapcase tr tr_s unicode_normalize upcase + ) + + UNSAFE_STRING_METHODS_WITH_BACKREF = %w(gsub sub) + + alias_method :original_concat, :concat + private :original_concat + + # Raised when ActiveSupport::SafeBuffer#safe_concat is called on unsafe buffers. + class SafeConcatError < StandardError + def initialize + super "Could not concatenate to the buffer because it is not HTML safe." + end + end + + def [](*args) + if html_safe? + new_string = super + + return unless new_string + + string_into_safe_buffer(new_string, true) + else + to_str[*args] + end + end + alias_method :slice, :[] + + def slice!(*args) + new_string = super + + return new_string if !html_safe? || new_string.nil? + + string_into_safe_buffer(new_string, true) + end + + def chr + return super unless html_safe? + + string_into_safe_buffer(super, true) + end + + def safe_concat(value) + raise SafeConcatError unless html_safe? + original_concat(value) + end + + def initialize(str = "") + @html_safe = true + super + end + + def initialize_copy(other) + super + @html_safe = other.html_safe? + end + + def concat(value) + unless value.nil? + super(implicit_html_escape_interpolated_argument(value)) + end + self + end + alias << concat + + def bytesplice(*args, value) + super(*args, implicit_html_escape_interpolated_argument(value)) + end + + def insert(index, value) + super(index, implicit_html_escape_interpolated_argument(value)) + end + + def prepend(value) + super(implicit_html_escape_interpolated_argument(value)) + end + + def replace(value) + super(implicit_html_escape_interpolated_argument(value)) + end + + def []=(arg1, arg2, arg3 = nil) + if arg3 + super(arg1, arg2, implicit_html_escape_interpolated_argument(arg3)) + else + super(arg1, implicit_html_escape_interpolated_argument(arg2)) + end + end + + def +(other) + dup.concat(other) + end + + def *(_) + new_string = super + new_safe_buffer = new_string.is_a?(SafeBuffer) ? new_string : SafeBuffer.new(new_string) + new_safe_buffer.instance_variable_set(:@html_safe, @html_safe) + new_safe_buffer + end + + def %(args) + case args + when Hash + escaped_args = args.transform_values { |arg| explicit_html_escape_interpolated_argument(arg) } + else + escaped_args = Array(args).map { |arg| explicit_html_escape_interpolated_argument(arg) } + end + + self.class.new(super(escaped_args)) + end + + attr_reader :html_safe + alias_method :html_safe?, :html_safe + remove_method :html_safe + + def to_s + self + end + + def to_param + to_str + end + + def encode_with(coder) + coder.represent_object nil, to_str + end + + UNSAFE_STRING_METHODS.each do |unsafe_method| + if unsafe_method.respond_to?(unsafe_method) + class_eval <<-EOT, __FILE__, __LINE__ + 1 + def #{unsafe_method}(*args, &block) # def capitalize(*args, &block) + to_str.#{unsafe_method}(*args, &block) # to_str.capitalize(*args, &block) + end # end + + def #{unsafe_method}!(*args) # def capitalize!(*args) + @html_safe = false # @html_safe = false + super # super + end # end + EOT + end + end + + UNSAFE_STRING_METHODS_WITH_BACKREF.each do |unsafe_method| + class_eval <<-EOT, __FILE__, __LINE__ + 1 + def #{unsafe_method}(*args, &block) # def gsub(*args, &block) + if block # if block + to_str.#{unsafe_method}(*args) { |*params| # to_str.gsub(*args) { |*params| + set_block_back_references(block, $~) # set_block_back_references(block, $~) + block.call(*params) # block.call(*params) + } # } + else # else + to_str.#{unsafe_method}(*args) # to_str.gsub(*args) + end # end + end # end + + def #{unsafe_method}!(*args, &block) # def gsub!(*args, &block) + @html_safe = false # @html_safe = false + if block # if block + super(*args) { |*params| # super(*args) { |*params| + set_block_back_references(block, $~) # set_block_back_references(block, $~) + block.call(*params) # block.call(*params) + } # } + else # else + super # super + end # end + end # end + EOT + end + + private + def explicit_html_escape_interpolated_argument(arg) + (!html_safe? || arg.html_safe?) ? arg : CGI.escapeHTML(arg.to_s) + end + + def implicit_html_escape_interpolated_argument(arg) + if !html_safe? || arg.html_safe? + arg + else + CGI.escapeHTML(arg.to_str) + end + end + + def set_block_back_references(block, match_data) + block.binding.eval("proc { |m| $~ = m }").call(match_data) + rescue ArgumentError + # Can't create binding from C level Proc + end + + def string_into_safe_buffer(new_string, is_html_safe) + new_safe_buffer = new_string.is_a?(SafeBuffer) ? new_string : SafeBuffer.new(new_string) + new_safe_buffer.instance_variable_set :@html_safe, is_html_safe + new_safe_buffer + end + end +end + +class String + # Marks a string as trusted safe. It will be inserted into HTML with no + # additional escaping performed. It is your responsibility to ensure that the + # string contains no malicious content. This method is equivalent to the + # +raw+ helper in views. It is recommended that you use +sanitize+ instead of + # this method. It should never be called on user input. + def html_safe + ActiveSupport::SafeBuffer.new(self) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/starts_ends_with.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/starts_ends_with.rb new file mode 100644 index 00000000..1e216370 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/starts_ends_with.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +class String + alias :starts_with? :start_with? + alias :ends_with? :end_with? +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/strip.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/strip.rb new file mode 100644 index 00000000..60e9952e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/strip.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +class String + # Strips indentation in heredocs. + # + # For example in + # + # if options[:usage] + # puts <<-USAGE.strip_heredoc + # This command does such and such. + # + # Supported options are: + # -h This message + # ... + # USAGE + # end + # + # the user would see the usage message aligned against the left margin. + # + # Technically, it looks for the least indented non-empty line + # in the whole string, and removes that amount of leading whitespace. + def strip_heredoc + gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/, "").tap do |stripped| + stripped.freeze if frozen? + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/zones.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/zones.rb new file mode 100644 index 00000000..55dc2314 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/string/zones.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require "active_support/core_ext/string/conversions" +require "active_support/core_ext/time/zones" + +class String + # Converts String to a TimeWithZone in the current zone if Time.zone or Time.zone_default + # is set, otherwise converts String to a Time via String#to_time + def in_time_zone(zone = ::Time.zone) + if zone + ::Time.find_zone!(zone).parse(self) + else + to_time + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/symbol.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/symbol.rb new file mode 100644 index 00000000..709fed20 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/symbol.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +require "active_support/core_ext/symbol/starts_ends_with" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/symbol/starts_ends_with.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/symbol/starts_ends_with.rb new file mode 100644 index 00000000..4f852175 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/symbol/starts_ends_with.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +class Symbol + alias :starts_with? :start_with? + alias :ends_with? :end_with? +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/thread/backtrace/location.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/thread/backtrace/location.rb new file mode 100644 index 00000000..d21acffb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/thread/backtrace/location.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class Thread::Backtrace::Location # :nodoc: + def spot(ex) + ErrorHighlight.spot(ex, backtrace_location: self) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/time.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/time.rb new file mode 100644 index 00000000..c809def0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/time.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require "active_support/core_ext/time/acts_like" +require "active_support/core_ext/time/calculations" +require "active_support/core_ext/time/compatibility" +require "active_support/core_ext/time/conversions" +require "active_support/core_ext/time/zones" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/time/acts_like.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/time/acts_like.rb new file mode 100644 index 00000000..8572b496 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/time/acts_like.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require "active_support/core_ext/object/acts_like" + +class Time + # Duck-types as a Time-like class. See Object#acts_like?. + def acts_like_time? + true + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/time/calculations.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/time/calculations.rb new file mode 100644 index 00000000..471a56c9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/time/calculations.rb @@ -0,0 +1,386 @@ +# frozen_string_literal: true + +require "active_support/duration" +require "active_support/core_ext/time/conversions" +require "active_support/time_with_zone" +require "active_support/core_ext/time/zones" +require "active_support/core_ext/date_and_time/calculations" +require "active_support/core_ext/date/calculations" +require "active_support/core_ext/module/remove_method" + +class Time + include DateAndTime::Calculations + + COMMON_YEAR_DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] + + class << self + # Overriding case equality method so that it returns true for ActiveSupport::TimeWithZone instances + def ===(other) + super || (self == Time && other.is_a?(ActiveSupport::TimeWithZone)) + end + + # Returns the number of days in the given month. + # If no year is specified, it will use the current year. + def days_in_month(month, year = current.year) + if month == 2 && ::Date.gregorian_leap?(year) + 29 + else + COMMON_YEAR_DAYS_IN_MONTH[month] + end + end + + # Returns the number of days in the given year. + # If no year is specified, it will use the current year. + def days_in_year(year = current.year) + days_in_month(2, year) + 337 + end + + # Returns Time.zone.now when Time.zone or config.time_zone are set, otherwise just returns Time.now. + def current + ::Time.zone ? ::Time.zone.now : ::Time.now + end + + # Layers additional behavior on Time.at so that ActiveSupport::TimeWithZone and DateTime + # instances can be used when called with a single argument + def at_with_coercion(time_or_number, *args) + if args.empty? + if time_or_number.is_a?(ActiveSupport::TimeWithZone) + at_without_coercion(time_or_number.to_r).getlocal + elsif time_or_number.is_a?(DateTime) + at_without_coercion(time_or_number.to_f).getlocal + else + at_without_coercion(time_or_number) + end + else + at_without_coercion(time_or_number, *args) + end + end + ruby2_keywords :at_with_coercion + alias_method :at_without_coercion, :at + alias_method :at, :at_with_coercion + + # Creates a +Time+ instance from an RFC 3339 string. + # + # Time.rfc3339('1999-12-31T14:00:00-10:00') # => 2000-01-01 00:00:00 -1000 + # + # If the time or offset components are missing then an +ArgumentError+ will be raised. + # + # Time.rfc3339('1999-12-31') # => ArgumentError: invalid date + def rfc3339(str) + parts = Date._rfc3339(str) + + raise ArgumentError, "invalid date" if parts.empty? + + Time.new( + parts.fetch(:year), + parts.fetch(:mon), + parts.fetch(:mday), + parts.fetch(:hour), + parts.fetch(:min), + parts.fetch(:sec) + parts.fetch(:sec_fraction, 0), + parts.fetch(:offset) + ) + end + end + + # Returns the number of seconds since 00:00:00. + # + # Time.new(2012, 8, 29, 0, 0, 0).seconds_since_midnight # => 0.0 + # Time.new(2012, 8, 29, 12, 34, 56).seconds_since_midnight # => 45296.0 + # Time.new(2012, 8, 29, 23, 59, 59).seconds_since_midnight # => 86399.0 + def seconds_since_midnight + to_i - change(hour: 0).to_i + (usec / 1.0e+6) + end + + # Returns the number of seconds until 23:59:59. + # + # Time.new(2012, 8, 29, 0, 0, 0).seconds_until_end_of_day # => 86399 + # Time.new(2012, 8, 29, 12, 34, 56).seconds_until_end_of_day # => 41103 + # Time.new(2012, 8, 29, 23, 59, 59).seconds_until_end_of_day # => 0 + def seconds_until_end_of_day + end_of_day.to_i - to_i + end + + # Returns the fraction of a second as a +Rational+ + # + # Time.new(2012, 8, 29, 0, 0, 0.5).sec_fraction # => (1/2) + def sec_fraction + subsec + end + + # Returns a new Time where one or more of the elements have been changed according + # to the +options+ parameter. The time options (:hour, :min, + # :sec, :usec, :nsec) reset cascadingly, so if only + # the hour is passed, then minute, sec, usec, and nsec is set to 0. If the hour + # and minute is passed, then sec, usec, and nsec is set to 0. The +options+ parameter + # takes a hash with any of these keys: :year, :month, :day, + # :hour, :min, :sec, :usec, :nsec, + # :offset. Pass either :usec or :nsec, not both. + # + # Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0) + # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0) + # Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0) + def change(options) + new_year = options.fetch(:year, year) + new_month = options.fetch(:month, month) + new_day = options.fetch(:day, day) + new_hour = options.fetch(:hour, hour) + new_min = options.fetch(:min, options[:hour] ? 0 : min) + new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec) + new_offset = options.fetch(:offset, nil) + + if new_nsec = options[:nsec] + raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec] + new_usec = Rational(new_nsec, 1000) + else + new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000)) + end + + raise ArgumentError, "argument out of range" if new_usec >= 1000000 + + new_sec += Rational(new_usec, 1000000) + + if new_offset + ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, new_offset) + elsif utc? + ::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec) + elsif zone.respond_to?(:utc_to_local) + new_time = ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, zone) + + # Some versions of Ruby have a bug where Time.new with a zone object and + # fractional seconds will end up with a broken utc_offset. + # This is fixed in Ruby 3.3.1 and 3.2.4 + unless new_time.utc_offset.integer? + new_time += 0 + end + + # When there are two occurrences of a nominal time due to DST ending, + # `Time.new` chooses the first chronological occurrence (the one with a + # larger UTC offset). However, for `change`, we want to choose the + # occurrence that matches this time's UTC offset. + # + # If the new time's UTC offset is larger than this time's UTC offset, the + # new time might be a first chronological occurrence. So we add the offset + # difference to fast-forward the new time, and check if the result has the + # desired UTC offset (i.e. is the second chronological occurrence). + offset_difference = new_time.utc_offset - utc_offset + if offset_difference > 0 && (new_time_2 = new_time + offset_difference).utc_offset == utc_offset + new_time_2 + else + new_time + end + elsif zone + ::Time.local(new_sec, new_min, new_hour, new_day, new_month, new_year, nil, nil, isdst, nil) + else + ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, utc_offset) + end + end + + # Uses Date to provide precise Time calculations for years, months, and days + # according to the proleptic Gregorian calendar. The +options+ parameter + # takes a hash with any of these keys: :years, :months, + # :weeks, :days, :hours, :minutes, + # :seconds. + # + # Time.new(2015, 8, 1, 14, 35, 0).advance(seconds: 1) # => 2015-08-01 14:35:01 -0700 + # Time.new(2015, 8, 1, 14, 35, 0).advance(minutes: 1) # => 2015-08-01 14:36:00 -0700 + # Time.new(2015, 8, 1, 14, 35, 0).advance(hours: 1) # => 2015-08-01 15:35:00 -0700 + # Time.new(2015, 8, 1, 14, 35, 0).advance(days: 1) # => 2015-08-02 14:35:00 -0700 + # Time.new(2015, 8, 1, 14, 35, 0).advance(weeks: 1) # => 2015-08-08 14:35:00 -0700 + # + # Just like Date#advance, increments are applied in order of time units from + # largest to smallest. This order can affect the result around the end of a + # month. + def advance(options) + unless options[:weeks].nil? + options[:weeks], partial_weeks = options[:weeks].divmod(1) + options[:days] = options.fetch(:days, 0) + 7 * partial_weeks + end + + unless options[:days].nil? + options[:days], partial_days = options[:days].divmod(1) + options[:hours] = options.fetch(:hours, 0) + 24 * partial_days + end + + d = to_date.gregorian.advance(options) + time_advanced_by_date = change(year: d.year, month: d.month, day: d.day) + seconds_to_advance = \ + options.fetch(:seconds, 0) + + options.fetch(:minutes, 0) * 60 + + options.fetch(:hours, 0) * 3600 + + if seconds_to_advance.zero? + time_advanced_by_date + else + time_advanced_by_date.since(seconds_to_advance) + end + end + + # Returns a new Time representing the time a number of seconds ago, this is basically a wrapper around the Numeric extension + def ago(seconds) + since(-seconds) + end + + # Returns a new Time representing the time a number of seconds since the instance time + def since(seconds) + self + seconds + rescue TypeError + result = to_datetime.since(seconds) + ActiveSupport.deprecator.warn( + "Passing an instance of #{seconds.class} to #{self.class}#since is deprecated. This behavior will raise " \ + "a `TypeError` in Rails 8.1." + ) + result + end + alias :in :since + + # Returns a new Time representing the start of the day (0:00) + def beginning_of_day + change(hour: 0) + end + alias :midnight :beginning_of_day + alias :at_midnight :beginning_of_day + alias :at_beginning_of_day :beginning_of_day + + # Returns a new Time representing the middle of the day (12:00) + def middle_of_day + change(hour: 12) + end + alias :midday :middle_of_day + alias :noon :middle_of_day + alias :at_midday :middle_of_day + alias :at_noon :middle_of_day + alias :at_middle_of_day :middle_of_day + + # Returns a new Time representing the end of the day, 23:59:59.999999 + def end_of_day + change( + hour: 23, + min: 59, + sec: 59, + usec: Rational(999999999, 1000) + ) + end + alias :at_end_of_day :end_of_day + + # Returns a new Time representing the start of the hour (x:00) + def beginning_of_hour + change(min: 0) + end + alias :at_beginning_of_hour :beginning_of_hour + + # Returns a new Time representing the end of the hour, x:59:59.999999 + def end_of_hour + change( + min: 59, + sec: 59, + usec: Rational(999999999, 1000) + ) + end + alias :at_end_of_hour :end_of_hour + + # Returns a new Time representing the start of the minute (x:xx:00) + def beginning_of_minute + change(sec: 0) + end + alias :at_beginning_of_minute :beginning_of_minute + + # Returns a new Time representing the end of the minute, x:xx:59.999999 + def end_of_minute + change( + sec: 59, + usec: Rational(999999999, 1000) + ) + end + alias :at_end_of_minute :end_of_minute + + def plus_with_duration(other) # :nodoc: + if ActiveSupport::Duration === other + other.since(self) + else + plus_without_duration(other) + end + end + alias_method :plus_without_duration, :+ + alias_method :+, :plus_with_duration + + def minus_with_duration(other) # :nodoc: + if ActiveSupport::Duration === other + other.until(self) + else + minus_without_duration(other) + end + end + alias_method :minus_without_duration, :- + alias_method :-, :minus_with_duration + + # Time#- can also be used to determine the number of seconds between two Time instances. + # We're layering on additional behavior so that ActiveSupport::TimeWithZone instances + # are coerced into values that Time#- will recognize + def minus_with_coercion(other) + other = other.comparable_time if other.respond_to?(:comparable_time) + other.is_a?(DateTime) ? to_f - other.to_f : minus_without_coercion(other) + end + alias_method :minus_without_coercion, :- + alias_method :-, :minus_with_coercion # rubocop:disable Lint/DuplicateMethods + + # Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances + # can be chronologically compared with a Time + def compare_with_coercion(other) + # we're avoiding Time#to_datetime and Time#to_time because they're expensive + if other.class == Time + compare_without_coercion(other) + elsif other.is_a?(Time) + # also avoid ActiveSupport::TimeWithZone#to_time before Rails 8.0 + if other.respond_to?(:comparable_time) + compare_without_coercion(other.comparable_time) + else + compare_without_coercion(other.to_time) + end + else + to_datetime <=> other + end + end + alias_method :compare_without_coercion, :<=> + alias_method :<=>, :compare_with_coercion + + # Layers additional behavior on Time#eql? so that ActiveSupport::TimeWithZone instances + # can be eql? to an equivalent Time + def eql_with_coercion(other) + # if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do eql? comparison + other = other.comparable_time if other.respond_to?(:comparable_time) + eql_without_coercion(other) + end + alias_method :eql_without_coercion, :eql? + alias_method :eql?, :eql_with_coercion + + # Returns a new time the specified number of days ago. + def prev_day(days = 1) + advance(days: -days) + end + + # Returns a new time the specified number of days in the future. + def next_day(days = 1) + advance(days: days) + end + + # Returns a new time the specified number of months ago. + def prev_month(months = 1) + advance(months: -months) + end + + # Returns a new time the specified number of months in the future. + def next_month(months = 1) + advance(months: months) + end + + # Returns a new time the specified number of years ago. + def prev_year(years = 1) + advance(years: -years) + end + + # Returns a new time the specified number of years in the future. + def next_year(years = 1) + advance(years: years) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/time/compatibility.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/time/compatibility.rb new file mode 100644 index 00000000..4e6c8ca3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/time/compatibility.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require "active_support/core_ext/date_and_time/compatibility" +require "active_support/core_ext/module/redefine_method" + +class Time + include DateAndTime::Compatibility + + silence_redefinition_of_method :to_time + + # Either return +self+ or the time in the local system timezone depending + # on the setting of +ActiveSupport.to_time_preserves_timezone+. + def to_time + preserve_timezone ? self : getlocal + end + + def preserve_timezone # :nodoc: + system_local_time? || super + end + + private + def system_local_time? + if ::Time.equal?(self.class) + zone = self.zone + String === zone && + (zone != "UTC" || active_support_local_zone == "UTC") + end + end + + @@active_support_local_tz = nil + + def active_support_local_zone + @@active_support_local_zone = nil if @@active_support_local_tz != ENV["TZ"] + @@active_support_local_zone ||= + begin + @@active_support_local_tz = ENV["TZ"] + Time.new.zone + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/time/conversions.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/time/conversions.rb new file mode 100644 index 00000000..8913f3f0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/time/conversions.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +require "time" +require "active_support/inflector/methods" +require "active_support/values/time_zone" + +class Time + DATE_FORMATS = { + db: "%Y-%m-%d %H:%M:%S", + inspect: "%Y-%m-%d %H:%M:%S.%9N %z", + number: "%Y%m%d%H%M%S", + nsec: "%Y%m%d%H%M%S%9N", + usec: "%Y%m%d%H%M%S%6N", + time: "%H:%M", + short: "%d %b %H:%M", + long: "%B %d, %Y %H:%M", + long_ordinal: lambda { |time| + day_format = ActiveSupport::Inflector.ordinalize(time.day) + time.strftime("%B #{day_format}, %Y %H:%M") + }, + rfc822: lambda { |time| + offset_format = time.formatted_offset(false) + time.strftime("%a, %d %b %Y %H:%M:%S #{offset_format}") + }, + rfc2822: lambda { |time| time.rfc2822 }, + iso8601: lambda { |time| time.iso8601 } + } + + # Converts to a formatted string. See DATE_FORMATS for built-in formats. + # + # This method is aliased to to_formatted_s. + # + # time = Time.now # => 2007-01-18 06:10:17 -06:00 + # + # time.to_fs(:time) # => "06:10" + # time.to_formatted_s(:time) # => "06:10" + # + # time.to_fs(:db) # => "2007-01-18 06:10:17" + # time.to_fs(:number) # => "20070118061017" + # time.to_fs(:short) # => "18 Jan 06:10" + # time.to_fs(:long) # => "January 18, 2007 06:10" + # time.to_fs(:long_ordinal) # => "January 18th, 2007 06:10" + # time.to_fs(:rfc822) # => "Thu, 18 Jan 2007 06:10:17 -0600" + # time.to_fs(:rfc2822) # => "Thu, 18 Jan 2007 06:10:17 -0600" + # time.to_fs(:iso8601) # => "2007-01-18T06:10:17-06:00" + # + # == Adding your own time formats to +to_fs+ + # You can add your own formats to the Time::DATE_FORMATS hash. + # Use the format name as the hash key and either a strftime string + # or Proc instance that takes a time argument as the value. + # + # # config/initializers/time_formats.rb + # Time::DATE_FORMATS[:month_and_year] = '%B %Y' + # Time::DATE_FORMATS[:short_ordinal] = ->(time) { time.strftime("%B #{time.day.ordinalize}") } + def to_fs(format = :default) + if formatter = DATE_FORMATS[format] + formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter) + else + to_s + end + end + alias_method :to_formatted_s, :to_fs + + # Returns a formatted string of the offset from UTC, or an alternative + # string if the time zone is already UTC. + # + # Time.local(2000).formatted_offset # => "-06:00" + # Time.local(2000).formatted_offset(false) # => "-0600" + def formatted_offset(colon = true, alternate_utc_string = nil) + utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon) + end + + # Aliased to +xmlschema+ for compatibility with +DateTime+ + alias_method :rfc3339, :xmlschema +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/time/zones.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/time/zones.rb new file mode 100644 index 00000000..5f0d3c7f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/core_ext/time/zones.rb @@ -0,0 +1,97 @@ +# frozen_string_literal: true + +require "active_support/time_with_zone" +require "active_support/core_ext/time/acts_like" +require "active_support/core_ext/date_and_time/zones" + +class Time + include DateAndTime::Zones + class << self + attr_accessor :zone_default + + # Returns the TimeZone for the current request, if this has been set (via Time.zone=). + # If Time.zone has not been set for the current request, returns the TimeZone specified in config.time_zone. + def zone + ::ActiveSupport::IsolatedExecutionState[:time_zone] || zone_default + end + + # Sets Time.zone to a TimeZone object for the current request/thread. + # + # This method accepts any of the following: + # + # * A \Rails TimeZone object. + # * An identifier for a \Rails TimeZone object (e.g., "Eastern \Time (US & Canada)", -5.hours). + # * A +TZInfo::Timezone+ object. + # * An identifier for a +TZInfo::Timezone+ object (e.g., "America/New_York"). + # + # Here's an example of how you might set Time.zone on a per request basis and reset it when the request is done. + # current_user.time_zone just needs to return a string identifying the user's preferred time zone: + # + # class ApplicationController < ActionController::Base + # around_action :set_time_zone + # + # def set_time_zone + # if logged_in? + # Time.use_zone(current_user.time_zone) { yield } + # else + # yield + # end + # end + # end + def zone=(time_zone) + ::ActiveSupport::IsolatedExecutionState[:time_zone] = find_zone!(time_zone) + end + + # Allows override of Time.zone locally inside supplied block; + # resets Time.zone to existing value when done. + # + # class ApplicationController < ActionController::Base + # around_action :set_time_zone + # + # private + # def set_time_zone + # Time.use_zone(current_user.timezone) { yield } + # end + # end + # + # NOTE: This won't affect any ActiveSupport::TimeWithZone + # objects that have already been created, e.g. any model timestamp + # attributes that have been read before the block will remain in + # the application's default timezone. + def use_zone(time_zone) + new_zone = find_zone!(time_zone) + begin + old_zone, ::Time.zone = ::Time.zone, new_zone + yield + ensure + ::Time.zone = old_zone + end + end + + # Returns a TimeZone instance matching the time zone provided. + # Accepts the time zone in any format supported by Time.zone=. + # Raises an +ArgumentError+ for invalid time zones. + # + # Time.find_zone! "America/New_York" # => # + # Time.find_zone! "EST" # => # + # Time.find_zone! -5.hours # => # + # Time.find_zone! nil # => nil + # Time.find_zone! false # => false + # Time.find_zone! "NOT-A-TIMEZONE" # => ArgumentError: Invalid Timezone: NOT-A-TIMEZONE + def find_zone!(time_zone) + return time_zone unless time_zone + + ActiveSupport::TimeZone[time_zone] || raise(ArgumentError, "Invalid Timezone: #{time_zone}") + end + + # Returns a TimeZone instance matching the time zone provided. + # Accepts the time zone in any format supported by Time.zone=. + # Returns +nil+ for invalid time zones. + # + # Time.find_zone "America/New_York" # => # + # Time.find_zone "NOT-A-TIMEZONE" # => nil + def find_zone(time_zone) + find_zone!(time_zone) rescue nil + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/current_attributes.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/current_attributes.rb new file mode 100644 index 00000000..43a503ea --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/current_attributes.rb @@ -0,0 +1,233 @@ +# frozen_string_literal: true + +require "active_support/callbacks" +require "active_support/core_ext/object/with" +require "active_support/core_ext/enumerable" +require "active_support/core_ext/module/delegation" + +module ActiveSupport + # = Current Attributes + # + # Abstract super class that provides a thread-isolated attributes singleton, which resets automatically + # before and after each request. This allows you to keep all the per-request attributes easily + # available to the whole system. + # + # The following full app-like example demonstrates how to use a Current class to + # facilitate easy access to the global, per-request attributes without passing them deeply + # around everywhere: + # + # # app/models/current.rb + # class Current < ActiveSupport::CurrentAttributes + # attribute :account, :user + # attribute :request_id, :user_agent, :ip_address + # + # resets { Time.zone = nil } + # + # def user=(user) + # super + # self.account = user.account + # Time.zone = user.time_zone + # end + # end + # + # # app/controllers/concerns/authentication.rb + # module Authentication + # extend ActiveSupport::Concern + # + # included do + # before_action :authenticate + # end + # + # private + # def authenticate + # if authenticated_user = User.find_by(id: cookies.encrypted[:user_id]) + # Current.user = authenticated_user + # else + # redirect_to new_session_url + # end + # end + # end + # + # # app/controllers/concerns/set_current_request_details.rb + # module SetCurrentRequestDetails + # extend ActiveSupport::Concern + # + # included do + # before_action do + # Current.request_id = request.uuid + # Current.user_agent = request.user_agent + # Current.ip_address = request.ip + # end + # end + # end + # + # class ApplicationController < ActionController::Base + # include Authentication + # include SetCurrentRequestDetails + # end + # + # class MessagesController < ApplicationController + # def create + # Current.account.messages.create(message_params) + # end + # end + # + # class Message < ApplicationRecord + # belongs_to :creator, default: -> { Current.user } + # after_create { |message| Event.create(record: message) } + # end + # + # class Event < ApplicationRecord + # before_create do + # self.request_id = Current.request_id + # self.user_agent = Current.user_agent + # self.ip_address = Current.ip_address + # end + # end + # + # A word of caution: It's easy to overdo a global singleton like Current and tangle your model as a result. + # Current should only be used for a few, top-level globals, like account, user, and request details. + # The attributes stuck in Current should be used by more or less all actions on all requests. If you start + # sticking controller-specific attributes in there, you're going to create a mess. + class CurrentAttributes + include ActiveSupport::Callbacks + define_callbacks :reset + + INVALID_ATTRIBUTE_NAMES = [:set, :reset, :resets, :instance, :before_reset, :after_reset, :reset_all, :clear_all] # :nodoc: + + NOT_SET = Object.new.freeze # :nodoc: + + class << self + # Returns singleton instance for this class in this thread. If none exists, one is created. + def instance + current_instances[current_instances_key] ||= new + end + + # Declares one or more attributes that will be given both class and instance accessor methods. + # + # ==== Options + # + # * :default - The default value for the attributes. If the value + # is a proc or lambda, it will be called whenever an instance is + # constructed. Otherwise, the value will be duplicated with +#dup+. + # Default values are re-assigned when the attributes are reset. + def attribute(*names, default: NOT_SET) + invalid_attribute_names = names.map(&:to_sym) & INVALID_ATTRIBUTE_NAMES + if invalid_attribute_names.any? + raise ArgumentError, "Restricted attribute names: #{invalid_attribute_names.join(", ")}" + end + + ActiveSupport::CodeGenerator.batch(generated_attribute_methods, __FILE__, __LINE__) do |owner| + names.each do |name| + owner.define_cached_method(name, namespace: :current_attributes) do |batch| + batch << + "def #{name}" << + "attributes[:#{name}]" << + "end" + end + owner.define_cached_method("#{name}=", namespace: :current_attributes) do |batch| + batch << + "def #{name}=(value)" << + "attributes[:#{name}] = value" << + "end" + end + end + end + + Delegation.generate(singleton_class, names, to: :instance, nilable: false, signature: "") + Delegation.generate(singleton_class, names.map { |n| "#{n}=" }, to: :instance, nilable: false, signature: "value") + + self.defaults = defaults.merge(names.index_with { default }) + end + + # Calls this callback before #reset is called on the instance. Used for resetting external collaborators that depend on current values. + def before_reset(*methods, &block) + set_callback :reset, :before, *methods, &block + end + + # Calls this callback after #reset is called on the instance. Used for resetting external collaborators, like Time.zone. + def resets(*methods, &block) + set_callback :reset, :after, *methods, &block + end + alias_method :after_reset, :resets + + delegate :set, :reset, to: :instance + + def reset_all # :nodoc: + current_instances.each_value(&:reset) + end + + def clear_all # :nodoc: + reset_all + current_instances.clear + end + + private + def generated_attribute_methods + @generated_attribute_methods ||= Module.new.tap { |mod| include mod } + end + + def current_instances + IsolatedExecutionState[:current_attributes_instances] ||= {} + end + + def current_instances_key + @current_instances_key ||= name.to_sym + end + + def method_missing(name, ...) + instance.public_send(name, ...) + end + + def respond_to_missing?(name, _) + instance.respond_to?(name) || super + end + + def method_added(name) + super + return if name == :initialize + return unless public_method_defined?(name) + return if singleton_class.method_defined?(name) || singleton_class.private_method_defined?(name) + Delegation.generate(singleton_class, [name], to: :instance, as: self, nilable: false) + end + end + + class_attribute :defaults, instance_writer: false, default: {}.freeze + + attr_accessor :attributes + + def initialize + @attributes = resolve_defaults + end + + # Expose one or more attributes within a block. Old values are returned after the block concludes. + # Example demonstrating the common use of needing to set Current attributes outside the request-cycle: + # + # class Chat::PublicationJob < ApplicationJob + # def perform(attributes, room_number, creator) + # Current.set(person: creator) do + # Chat::Publisher.publish(attributes: attributes, room_number: room_number) + # end + # end + # end + def set(attributes, &block) + with(**attributes, &block) + end + + # Reset all attributes. Should be called before and after actions, when used as a per-request singleton. + def reset + run_callbacks :reset do + self.attributes = resolve_defaults + end + end + + private + def resolve_defaults + defaults.each_with_object({}) do |(key, value), result| + if value != NOT_SET + result[key] = Proc === value ? value.call : value.dup + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/current_attributes/test_helper.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/current_attributes/test_helper.rb new file mode 100644 index 00000000..2016384a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/current_attributes/test_helper.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module ActiveSupport::CurrentAttributes::TestHelper # :nodoc: + def before_setup + ActiveSupport::CurrentAttributes.reset_all + super + end + + def after_teardown + super + ActiveSupport::CurrentAttributes.reset_all + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deep_mergeable.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deep_mergeable.rb new file mode 100644 index 00000000..c00a240b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deep_mergeable.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +module ActiveSupport + # Provides +deep_merge+ and +deep_merge!+ methods. Expects the including class + # to provide a merge!(other, &block) method. + module DeepMergeable # :nodoc: + # Returns a new instance with the values from +other+ merged recursively. + # + # class Hash + # include ActiveSupport::DeepMergeable + # end + # + # hash_1 = { a: true, b: { c: [1, 2, 3] } } + # hash_2 = { a: false, b: { x: [3, 4, 5] } } + # + # hash_1.deep_merge(hash_2) + # # => { a: false, b: { c: [1, 2, 3], x: [3, 4, 5] } } + # + # A block can be provided to merge non-DeepMergeable values: + # + # hash_1 = { a: 100, b: 200, c: { c1: 100 } } + # hash_2 = { b: 250, c: { c1: 200 } } + # + # hash_1.deep_merge(hash_2) do |key, this_val, other_val| + # this_val + other_val + # end + # # => { a: 100, b: 450, c: { c1: 300 } } + # + def deep_merge(other, &block) + dup.deep_merge!(other, &block) + end + + # Same as #deep_merge, but modifies +self+. + def deep_merge!(other, &block) + merge!(other) do |key, this_val, other_val| + if this_val.is_a?(DeepMergeable) && this_val.deep_merge?(other_val) + this_val.deep_merge(other_val, &block) + elsif block_given? + block.call(key, this_val, other_val) + else + other_val + end + end + end + + # Returns true if +other+ can be deep merged into +self+. Classes may + # override this method to restrict or expand the domain of deep mergeable + # values. Defaults to checking that +other+ is of type +self.class+. + def deep_merge?(other) + other.is_a?(self.class) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/delegation.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/delegation.rb new file mode 100644 index 00000000..261cc0d4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/delegation.rb @@ -0,0 +1,200 @@ +# frozen_string_literal: true + +module ActiveSupport + # Error generated by +delegate+ when a method is called on +nil+ and +allow_nil+ + # option is not used. + class DelegationError < NoMethodError + class << self + def nil_target(method_name, target) # :nodoc: + new("#{method_name} delegated to #{target}, but #{target} is nil") + end + end + end + + module Delegation # :nodoc: + RUBY_RESERVED_KEYWORDS = %w(__ENCODING__ __LINE__ __FILE__ alias and BEGIN begin break + case class def defined? do else elsif END end ensure false for if in module next nil + not or redo rescue retry return self super then true undef unless until when while yield) + RESERVED_METHOD_NAMES = (RUBY_RESERVED_KEYWORDS + %w(_ arg args block)).to_set.freeze + + class << self + def generate(owner, methods, location: nil, to: nil, prefix: nil, allow_nil: nil, nilable: true, private: nil, as: nil, signature: nil) + unless to + raise ArgumentError, "Delegation needs a target. Supply a keyword argument 'to' (e.g. delegate :hello, to: :greeter)." + end + + if prefix == true && /^[^a-z_]/.match?(to) + raise ArgumentError, "Can only automatically set the delegation prefix when delegating to a method." + end + + method_prefix = \ + if prefix + "#{prefix == true ? to : prefix}_" + else + "" + end + + location ||= caller_locations(1, 1).first + file, line = location.path, location.lineno + + receiver = if to.is_a?(Module) + if to.name.nil? + raise ArgumentError, "Can't delegate to anonymous class or module: #{to}" + end + + unless Inflector.safe_constantize(to.name).equal?(to) + raise ArgumentError, "Can't delegate to detached class or module: #{to.name}" + end + + "::#{to.name}" + else + to.to_s + end + receiver = "self.#{receiver}" if RESERVED_METHOD_NAMES.include?(receiver) + + explicit_receiver = false + receiver_class = if as + explicit_receiver = true + as + elsif to.is_a?(Module) + to.singleton_class + elsif receiver == "self.class" + nilable = false # self.class can't possibly be nil + owner.singleton_class + end + + method_def = [] + method_names = [] + + method_def << "self.private" if private + + methods.each do |method| + method_name = prefix ? "#{method_prefix}#{method}" : method + method_names << method_name.to_sym + + # Attribute writer methods only accept one argument. Makes sure []= + # methods still accept two arguments. + definition = \ + if signature + signature + elsif /[^\]]=\z/.match?(method) + "arg" + else + method_object = if receiver_class + begin + receiver_class.public_instance_method(method) + rescue NameError + raise if explicit_receiver + # Do nothing. Fall back to `"..."` + end + end + + if method_object + parameters = method_object.parameters + + if parameters.map(&:first).intersect?([:opt, :rest, :keyreq, :key, :keyrest]) + "..." + else + defn = parameters.filter_map { |type, arg| arg if type == :req } + defn << "&" + defn.join(", ") + end + else + "..." + end + end + + # The following generated method calls the target exactly once, storing + # the returned value in a dummy variable. + # + # Reason is twofold: On one hand doing less calls is in general better. + # On the other hand it could be that the target has side-effects, + # whereas conceptually, from the user point of view, the delegator should + # be doing one call. + if nilable == false + method_def << + "def #{method_name}(#{definition})" << + " (#{receiver}).#{method}(#{definition})" << + "end" + elsif allow_nil + method = method.to_s + + method_def << + "def #{method_name}(#{definition})" << + " _ = #{receiver}" << + " if !_.nil? || nil.respond_to?(:#{method})" << + " _.#{method}(#{definition})" << + " end" << + "end" + else + method = method.to_s + method_name = method_name.to_s + + method_def << + "def #{method_name}(#{definition})" << + " _ = #{receiver}" << + " _.#{method}(#{definition})" << + "rescue NoMethodError => e" << + " if _.nil? && e.name == :#{method}" << + " raise ::ActiveSupport::DelegationError.nil_target(:#{method_name}, :'#{receiver}')" << + " else" << + " raise" << + " end" << + "end" + end + end + owner.module_eval(method_def.join(";"), file, line) + method_names + end + + def generate_method_missing(owner, target, allow_nil: nil) + target = target.to_s + target = "self.#{target}" if RESERVED_METHOD_NAMES.include?(target) || target == "__target" + + if allow_nil + owner.module_eval <<~RUBY, __FILE__, __LINE__ + 1 + def respond_to_missing?(name, include_private = false) + # It may look like an oversight, but we deliberately do not pass + # +include_private+, because they do not get delegated. + + return false if name == :marshal_dump || name == :_dump + #{target}.respond_to?(name) || super + end + + def method_missing(method, ...) + __target = #{target} + if __target.nil? && !nil.respond_to?(method) + nil + elsif __target.respond_to?(method) + __target.public_send(method, ...) + else + super + end + end + RUBY + else + owner.module_eval <<~RUBY, __FILE__, __LINE__ + 1 + def respond_to_missing?(name, include_private = false) + # It may look like an oversight, but we deliberately do not pass + # +include_private+, because they do not get delegated. + + return false if name == :marshal_dump || name == :_dump + #{target}.respond_to?(name) || super + end + + def method_missing(method, ...) + __target = #{target} + if __target.nil? && !nil.respond_to?(method) + raise ::ActiveSupport::DelegationError.nil_target(method, :'#{target}') + elsif __target.respond_to?(method) + __target.public_send(method, ...) + else + super + end + end + RUBY + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/dependencies.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/dependencies.rb new file mode 100644 index 00000000..aed69233 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/dependencies.rb @@ -0,0 +1,97 @@ +# frozen_string_literal: true + +require "active_support/dependencies/interlock" + +module ActiveSupport # :nodoc: + module Dependencies # :nodoc: + require_relative "dependencies/require_dependency" + + singleton_class.attr_accessor :interlock + @interlock = Interlock.new + + # :doc: + + # Execute the supplied block without interference from any + # concurrent loads. + def self.run_interlock(&block) + interlock.running(&block) + end + + # Execute the supplied block while holding an exclusive lock, + # preventing any other thread from being inside a #run_interlock + # block at the same time. + def self.load_interlock(&block) + interlock.loading(&block) + end + + # Execute the supplied block while holding an exclusive lock, + # preventing any other thread from being inside a #run_interlock + # block at the same time. + def self.unload_interlock(&block) + interlock.unloading(&block) + end + + # :nodoc: + + # The array of directories from which we autoload and reload, if reloading + # is enabled. The public interface to push directories to this collection + # from applications or engines is config.autoload_paths. + # + # This collection is allowed to have intersection with autoload_once_paths. + # Common directories are not reloaded. + singleton_class.attr_accessor :autoload_paths + self.autoload_paths = [] + + # The array of directories from which we autoload and never reload, even if + # reloading is enabled. The public interface to push directories to this + # collection from applications or engines is config.autoload_once_paths. + singleton_class.attr_accessor :autoload_once_paths + self.autoload_once_paths = [] + + # This is a private set that collects all eager load paths during bootstrap. + # Useful for Zeitwerk integration. The public interface to push custom + # directories to this collection from applications or engines is + # config.eager_load_paths. + singleton_class.attr_accessor :_eager_load_paths + self._eager_load_paths = Set.new + + # If reloading is enabled, this private set holds autoloaded classes tracked + # by the descendants tracker. It is populated by an on_load callback in the + # main autoloader. Used to clear state. + singleton_class.attr_accessor :_autoloaded_tracked_classes + self._autoloaded_tracked_classes = Set.new + + # If reloading is enabled, this private attribute stores the main autoloader + # of a Rails application. It is `nil` otherwise. + # + # The public interface for this autoloader is `Rails.autoloaders.main`. + singleton_class.attr_accessor :autoloader + + # Private method that reloads constants autoloaded by the main autoloader. + # + # Rails.application.reloader.reload! is the public interface for application + # reload. That involves more things, like deleting unloaded classes from the + # internal state of the descendants tracker, or reloading routes. + def self.clear + unload_interlock do + _autoloaded_tracked_classes.clear + autoloader.reload + end + end + + # Private method used by require_dependency. + def self.search_for_file(relpath) + relpath += ".rb" unless relpath.end_with?(".rb") + autoload_paths.each do |autoload_path| + abspath = File.join(autoload_path, relpath) + return abspath if File.file?(abspath) + end + nil + end + + # Private method that helps configuring the autoloaders. + def self.eager_load?(path) + _eager_load_paths.member?(path) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/dependencies/autoload.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/dependencies/autoload.rb new file mode 100644 index 00000000..747f1fe4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/dependencies/autoload.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +require "active_support/inflector/methods" + +module ActiveSupport + # = Active Support \Autoload + # + # Autoload and eager load conveniences for your library. + # + # This module allows you to define autoloads based on + # \Rails conventions (i.e. no need to define the path + # it is automatically guessed based on the filename) + # and also define a set of constants that needs to be + # eager loaded: + # + # module MyLib + # extend ActiveSupport::Autoload + # + # autoload :Model + # + # eager_autoload do + # autoload :Cache + # end + # end + # + # Then your library can be eager loaded by simply calling: + # + # MyLib.eager_load! + module Autoload + def autoload(const_name, path = @_at_path) + unless path + full = [name, @_under_path, const_name.to_s].compact.join("::") + path = Inflector.underscore(full) + end + + if @_eager_autoload + @_eagerloaded_constants ||= [] + @_eagerloaded_constants << const_name + end + + super const_name, path + end + + def autoload_under(path) + @_under_path, old_path = path, @_under_path + yield + ensure + @_under_path = old_path + end + + def autoload_at(path) + @_at_path, old_path = path, @_at_path + yield + ensure + @_at_path = old_path + end + + def eager_autoload + old_eager, @_eager_autoload = @_eager_autoload, true + yield + ensure + @_eager_autoload = old_eager + end + + def eager_load! + if @_eagerloaded_constants + @_eagerloaded_constants.each { |const_name| const_get(const_name) } + @_eagerloaded_constants = nil + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/dependencies/interlock.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/dependencies/interlock.rb new file mode 100644 index 00000000..e0e32e82 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/dependencies/interlock.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +require "active_support/concurrency/share_lock" + +module ActiveSupport # :nodoc: + module Dependencies # :nodoc: + class Interlock + def initialize # :nodoc: + @lock = ActiveSupport::Concurrency::ShareLock.new + end + + def loading(&block) + @lock.exclusive(purpose: :load, compatible: [:load], after_compatible: [:load], &block) + end + + def unloading(&block) + @lock.exclusive(purpose: :unload, compatible: [:load, :unload], after_compatible: [:load, :unload], &block) + end + + def start_unloading + @lock.start_exclusive(purpose: :unload, compatible: [:load, :unload]) + end + + def done_unloading + @lock.stop_exclusive(compatible: [:load, :unload]) + end + + def start_running + @lock.start_sharing + end + + def done_running + @lock.stop_sharing + end + + def running(&block) + @lock.sharing(&block) + end + + def permit_concurrent_loads(&block) + @lock.yield_shares(compatible: [:load], &block) + end + + def raw_state(&block) # :nodoc: + @lock.raw_state(&block) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/dependencies/require_dependency.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/dependencies/require_dependency.rb new file mode 100644 index 00000000..403f5fa4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/dependencies/require_dependency.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module ActiveSupport::Dependencies::RequireDependency + # Warning: This method is obsolete. The semantics of the autoloader + # match Ruby's and you do not need to be defensive with load order anymore. + # Just refer to classes and modules normally. + # + # Engines that do not control the mode in which their parent application runs + # should call +require_dependency+ where needed in case the runtime mode is + # +:classic+. + def require_dependency(filename) + filename = filename.to_path if filename.respond_to?(:to_path) + + unless filename.is_a?(String) + raise ArgumentError, "the file name must be either a String or implement #to_path -- you passed #{filename.inspect}" + end + + if abspath = ActiveSupport::Dependencies.search_for_file(filename) + require abspath + else + require filename + end + end + + # We could define require_dependency in Object directly, but a module makes + # the extension apparent if you list ancestors. + Object.prepend(self) +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deprecation.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deprecation.rb new file mode 100644 index 00000000..1358d915 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deprecation.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +module ActiveSupport + # = Active Support \Deprecation + # + # \Deprecation specifies the API used by \Rails to deprecate methods, instance variables, objects, and constants. It's + # also available for gems or applications. + # + # For a gem, use Deprecation.new to create a Deprecation object and store it in your module or class (in order for + # users to be able to configure it). + # + # module MyLibrary + # def self.deprecator + # @deprecator ||= ActiveSupport::Deprecation.new("2.0", "MyLibrary") + # end + # end + # + # For a Railtie or Engine, you may also want to add it to the application's deprecators, so that the application's + # configuration can be applied to it. + # + # module MyLibrary + # class Railtie < Rails::Railtie + # initializer "my_library.deprecator" do |app| + # app.deprecators[:my_library] = MyLibrary.deprecator + # end + # end + # end + # + # With the above initializer, configuration settings like the following will affect +MyLibrary.deprecator+: + # + # # in config/environments/test.rb + # config.active_support.deprecation = :raise + class Deprecation + # active_support.rb sets an autoload for ActiveSupport::Deprecation. + # + # If these requires were at the top of the file the constant would not be + # defined by the time their files were loaded. Since some of them reopen + # ActiveSupport::Deprecation its autoload would be triggered, resulting in + # a circular require warning for active_support/deprecation.rb. + # + # So, we define the constant first, and load dependencies later. + require "active_support/deprecation/behaviors" + require "active_support/deprecation/reporting" + require "active_support/deprecation/disallowed" + require "active_support/deprecation/constant_accessor" + require "active_support/deprecation/method_wrappers" + require "active_support/deprecation/proxy_wrappers" + require "active_support/deprecation/deprecators" + require "active_support/core_ext/module/deprecation" + require "concurrent/atomic/thread_local_var" + + include Behavior + include Reporting + include Disallowed + include MethodWrapper + + MUTEX = Mutex.new # :nodoc: + private_constant :MUTEX + + def self._instance # :nodoc: + @_instance ||= MUTEX.synchronize { @_instance ||= new } + end + + # The version number in which the deprecated behavior will be removed, by default. + attr_accessor :deprecation_horizon + + # It accepts two parameters on initialization. The first is a version of library + # and the second is a library name. + # + # ActiveSupport::Deprecation.new('2.0', 'MyLibrary') + def initialize(deprecation_horizon = "8.1", gem_name = "Rails") + self.gem_name = gem_name + self.deprecation_horizon = deprecation_horizon + # By default, warnings are not silenced and debugging is off. + self.silenced = false + self.debug = false + @silence_counter = Concurrent::ThreadLocalVar.new(0) + @explicitly_allowed_warnings = Concurrent::ThreadLocalVar.new(nil) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deprecation/behaviors.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deprecation/behaviors.rb new file mode 100644 index 00000000..2473263f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deprecation/behaviors.rb @@ -0,0 +1,148 @@ +# frozen_string_literal: true + +require "active_support/notifications" + +module ActiveSupport + # Raised when ActiveSupport::Deprecation::Behavior#behavior is set with :raise. + # You would set :raise, as a behavior to raise errors and proactively report exceptions from deprecations. + class DeprecationException < StandardError + end + + class Deprecation + # Default warning behaviors per Rails.env. + DEFAULT_BEHAVIORS = { + raise: ->(message, callstack, deprecator) do + e = DeprecationException.new(message) + e.set_backtrace(callstack.map(&:to_s)) + raise e + end, + + stderr: ->(message, callstack, deprecator) do + $stderr.puts(message) + $stderr.puts callstack.join("\n ") if deprecator.debug + end, + + log: ->(message, callstack, deprecator) do + logger = + if defined?(Rails.logger) && Rails.logger + Rails.logger + else + require "active_support/logger" + ActiveSupport::Logger.new($stderr) + end + logger.warn message + logger.debug callstack.join("\n ") if deprecator.debug + end, + + notify: ->(message, callstack, deprecator) do + ActiveSupport::Notifications.instrument( + "deprecation.#{deprecator.gem_name.underscore.tr("/", "_")}", + message: message, + callstack: callstack, + gem_name: deprecator.gem_name, + deprecation_horizon: deprecator.deprecation_horizon, + ) + end, + + silence: ->(message, callstack, deprecator) { }, + + report: ->(message, callstack, deprecator) do + error = DeprecationException.new(message) + error.set_backtrace(callstack.map(&:to_s)) + ActiveSupport.error_reporter.report(error) + end + } + + # Behavior module allows to determine how to display deprecation messages. + # You can create a custom behavior or set any from the +DEFAULT_BEHAVIORS+ + # constant. Available behaviors are: + # + # [+:raise+] Raise ActiveSupport::DeprecationException. + # [+:stderr+] Log all deprecation warnings to $stderr. + # [+:log+] Log all deprecation warnings to +Rails.logger+. + # [+:notify+] Use ActiveSupport::Notifications to notify +deprecation.rails+. + # [+:report+] Use ActiveSupport::ErrorReporter to report deprecations. + # [+:silence+] Do nothing. On \Rails, set config.active_support.report_deprecations = false to disable all behaviors. + # + # Setting behaviors only affects deprecations that happen after boot time. + # For more information you can read the documentation of the #behavior= method. + module Behavior + # Whether to print a backtrace along with the warning. + attr_accessor :debug + + # Returns the current behavior or if one isn't set, defaults to +:stderr+. + def behavior + @behavior ||= [DEFAULT_BEHAVIORS[:stderr]] + end + + # Returns the current behavior for disallowed deprecations or if one isn't set, defaults to +:raise+. + def disallowed_behavior + @disallowed_behavior ||= [DEFAULT_BEHAVIORS[:raise]] + end + + # Sets the behavior to the specified value. Can be a single value, array, + # or an object that responds to +call+. + # + # Available behaviors: + # + # [+:raise+] Raise ActiveSupport::DeprecationException. + # [+:stderr+] Log all deprecation warnings to $stderr. + # [+:log+] Log all deprecation warnings to +Rails.logger+. + # [+:notify+] Use ActiveSupport::Notifications to notify +deprecation.rails+. + # [+:report+] Use ActiveSupport::ErrorReporter to report deprecations. + # [+:silence+] Do nothing. + # + # Setting behaviors only affects deprecations that happen after boot time. + # Deprecation warnings raised by gems are not affected by this setting + # because they happen before \Rails boots up. + # + # deprecator = ActiveSupport::Deprecation.new + # deprecator.behavior = :stderr + # deprecator.behavior = [:stderr, :log] + # deprecator.behavior = MyCustomHandler + # deprecator.behavior = ->(message, callstack, deprecation_horizon, gem_name) { + # # custom stuff + # } + # + # If you are using \Rails, you can set + # config.active_support.report_deprecations = false to disable + # all deprecation behaviors. This is similar to the +:silence+ option but + # more performant. + def behavior=(behavior) + @behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) } + end + + # Sets the behavior for disallowed deprecations (those configured by + # ActiveSupport::Deprecation#disallowed_warnings=) to the specified + # value. As with #behavior=, this can be a single value, array, or an + # object that responds to +call+. + def disallowed_behavior=(behavior) + @disallowed_behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) } + end + + private + def arity_coerce(behavior) + unless behavior.respond_to?(:call) + raise ArgumentError, "#{behavior.inspect} is not a valid deprecation behavior." + end + + case arity_of_callable(behavior) + when 2 + ->(message, callstack, deprecator) do + behavior.call(message, callstack) + end + when -2..3 + behavior + else + ->(message, callstack, deprecator) do + behavior.call(message, callstack, deprecator.deprecation_horizon, deprecator.gem_name) + end + end + end + + def arity_of_callable(callable) + callable.respond_to?(:arity) ? callable.arity : callable.method(:call).arity + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deprecation/constant_accessor.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deprecation/constant_accessor.rb new file mode 100644 index 00000000..d6ff5b4d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deprecation/constant_accessor.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +module ActiveSupport + class Deprecation + module DeprecatedConstantAccessor + def self.included(base) + require "active_support/inflector/methods" + + extension = Module.new do + def const_missing(missing_const_name) + if class_variable_defined?(:@@_deprecated_constants) + if (replacement = class_variable_get(:@@_deprecated_constants)[missing_const_name.to_s]) + replacement[:deprecator].warn(replacement[:message] || "#{name}::#{missing_const_name} is deprecated! Use #{replacement[:new]} instead.", caller_locations) + return ActiveSupport::Inflector.constantize(replacement[:new].to_s) + end + end + super + end + + # Provides a way to rename constants with a deprecation cycle in which + # both the old and new names work, but using the old one prints a + # deprecation message. + # + # In order to rename A::B to C::D, you need to delete the + # definition of A::B and declare the deprecation in +A+: + # + # require "active_support/deprecation" + # + # module A + # include ActiveSupport::Deprecation::DeprecatedConstantAccessor + # + # deprecate_constant "B", "C::D", deprecator: ActiveSupport::Deprecation.new + # end + # + # The first argument is a constant name (no colons). It is the name of + # the constant you want to deprecate in the enclosing class or module. + # + # The second argument is the constant path of the replacement. That + # has to be a full path even if the replacement is defined in the same + # namespace as the deprecated one was. + # + # In both cases, strings and symbols are supported. + # + # The +deprecator+ keyword argument is the object that will print the + # deprecation message, an instance of ActiveSupport::Deprecation. + # + # With that in place, references to A::B still work, they + # evaluate to C::D now, and trigger a deprecation warning: + # + # DEPRECATION WARNING: A::B is deprecated! Use C::D instead. + # (called from ...) + # + # The message can be customized with the optional +message+ keyword + # argument. + # + # For this to work, a +const_missing+ hook is installed. When client + # code references the deprecated constant, the callback prints the + # message and constantizes the replacement. + # + # Caveat: If the deprecated constant name is reachable in a different + # namespace and Ruby constant lookup finds it, the hook won't be + # called and the deprecation won't work as intended. This may happen, + # for example, if an ancestor of the enclosing namespace has a + # constant with the same name. This is an unsupported edge case. + def deprecate_constant(old_constant_name, new_constant_path, deprecator:, message: nil) + class_variable_set(:@@_deprecated_constants, {}) unless class_variable_defined?(:@@_deprecated_constants) + class_variable_get(:@@_deprecated_constants)[old_constant_name.to_s] = { new: new_constant_path, message: message, deprecator: deprecator } + end + end + base.singleton_class.prepend extension + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deprecation/deprecators.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deprecation/deprecators.rb new file mode 100644 index 00000000..08f3fae3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deprecation/deprecators.rb @@ -0,0 +1,104 @@ +# frozen_string_literal: true + +module ActiveSupport + class Deprecation + # A managed collection of deprecators. Configuration methods, such as + # #behavior=, affect all deprecators in the collection. Additionally, the + # #silence method silences all deprecators in the collection for the + # duration of a given block. + class Deprecators + def initialize + @options = {} + @deprecators = {} + end + + # Returns a deprecator added to this collection via #[]=. + def [](name) + @deprecators[name] + end + + # Adds a given +deprecator+ to this collection. The deprecator will be + # immediately configured with any options previously set on this + # collection. + # + # deprecators = ActiveSupport::Deprecation::Deprecators.new + # deprecators.debug = true + # + # foo_deprecator = ActiveSupport::Deprecation.new("2.0", "Foo") + # foo_deprecator.debug # => false + # + # deprecators[:foo] = foo_deprecator + # deprecators[:foo].debug # => true + # foo_deprecator.debug # => true + # + def []=(name, deprecator) + apply_options(deprecator) + @deprecators[name] = deprecator + end + + # Iterates over all deprecators in this collection. If no block is given, + # returns an +Enumerator+. + def each(&block) + return to_enum(__method__) unless block + @deprecators.each_value(&block) + end + + # Sets the silenced flag for all deprecators in this collection. + def silenced=(silenced) + set_option(:silenced, silenced) + end + + # Sets the debug flag for all deprecators in this collection. + def debug=(debug) + set_option(:debug, debug) + end + + # Sets the deprecation warning behavior for all deprecators in this + # collection. + # + # See ActiveSupport::Deprecation#behavior=. + def behavior=(behavior) + set_option(:behavior, behavior) + end + + # Sets the disallowed deprecation warning behavior for all deprecators in + # this collection. + # + # See ActiveSupport::Deprecation#disallowed_behavior=. + def disallowed_behavior=(disallowed_behavior) + set_option(:disallowed_behavior, disallowed_behavior) + end + + # Sets the disallowed deprecation warnings for all deprecators in this + # collection. + # + # See ActiveSupport::Deprecation#disallowed_warnings=. + def disallowed_warnings=(disallowed_warnings) + set_option(:disallowed_warnings, disallowed_warnings) + end + + # Silences all deprecators in this collection for the duration of the + # given block. + # + # See ActiveSupport::Deprecation#silence. + def silence(&block) + each { |deprecator| deprecator.begin_silence } + block.call + ensure + each { |deprecator| deprecator.end_silence } + end + + private + def set_option(name, value) + @options[name] = value + each { |deprecator| deprecator.public_send("#{name}=", value) } + end + + def apply_options(deprecator) + @options.each do |name, value| + deprecator.public_send("#{name}=", value) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deprecation/disallowed.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deprecation/disallowed.rb new file mode 100644 index 00000000..85fdf5d3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deprecation/disallowed.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +module ActiveSupport + class Deprecation + module Disallowed + # Sets the criteria used to identify deprecation messages which should be + # disallowed. Can be an array containing strings, symbols, or regular + # expressions. (Symbols are treated as strings.) These are compared against + # the text of the generated deprecation warning. + # + # Additionally the scalar symbol +:all+ may be used to treat all + # deprecations as disallowed. + # + # Deprecations matching a substring or regular expression will be handled + # using the configured Behavior#disallowed_behavior rather than + # Behavior#behavior. + attr_writer :disallowed_warnings + + # Returns the configured criteria used to identify deprecation messages + # which should be treated as disallowed. + def disallowed_warnings + @disallowed_warnings ||= [] + end + + private + def deprecation_disallowed?(message) + return false if explicitly_allowed?(message) + return true if disallowed_warnings == :all + message && disallowed_warnings.any? do |rule| + case rule + when String, Symbol + message.include?(rule.to_s) + when Regexp + rule.match?(message) + end + end + end + + def explicitly_allowed?(message) + allowances = @explicitly_allowed_warnings.value + return false unless allowances + return true if allowances == :all + message && Array(allowances).any? do |rule| + case rule + when String, Symbol + message.include?(rule.to_s) + when Regexp + rule.match?(message) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deprecation/method_wrappers.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deprecation/method_wrappers.rb new file mode 100644 index 00000000..921168c9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deprecation/method_wrappers.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +require "active_support/core_ext/array/extract_options" +require "active_support/core_ext/module/redefine_method" + +module ActiveSupport + class Deprecation + module MethodWrapper + # Declare that a method has been deprecated. + # + # class Fred + # def aaa; end + # def bbb; end + # def ccc; end + # def ddd; end + # def eee; end + # end + # + # deprecator = ActiveSupport::Deprecation.new('next-release', 'MyGem') + # + # deprecator.deprecate_methods(Fred, :aaa, bbb: :zzz, ccc: 'use Bar#ccc instead') + # # => Fred + # + # Fred.new.aaa + # # DEPRECATION WARNING: aaa is deprecated and will be removed from MyGem next-release. (called from irb_binding at (irb):10) + # # => nil + # + # Fred.new.bbb + # # DEPRECATION WARNING: bbb is deprecated and will be removed from MyGem next-release (use zzz instead). (called from irb_binding at (irb):11) + # # => nil + # + # Fred.new.ccc + # # DEPRECATION WARNING: ccc is deprecated and will be removed from MyGem next-release (use Bar#ccc instead). (called from irb_binding at (irb):12) + # # => nil + def deprecate_methods(target_module, *method_names) + options = method_names.extract_options! + deprecator = options.delete(:deprecator) || self + method_names += options.keys + mod = nil + + method_names.each do |method_name| + message = options[method_name] + if target_module.method_defined?(method_name) || target_module.private_method_defined?(method_name) + method = target_module.instance_method(method_name) + target_module.module_eval do + redefine_method(method_name) do |*args, &block| + deprecator.deprecation_warning(method_name, message) + method.bind_call(self, *args, &block) + end + ruby2_keywords(method_name) + end + else + mod ||= Module.new + mod.module_eval do + define_method(method_name) do |*args, &block| + deprecator.deprecation_warning(method_name, message) + super(*args, &block) + end + ruby2_keywords(method_name) + end + end + end + + target_module.prepend(mod) if mod + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deprecation/proxy_wrappers.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deprecation/proxy_wrappers.rb new file mode 100644 index 00000000..80e4ab22 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deprecation/proxy_wrappers.rb @@ -0,0 +1,189 @@ +# frozen_string_literal: true + +module ActiveSupport + class Deprecation + class DeprecationProxy # :nodoc: + def self.new(*args, **kwargs, &block) + object = args.first + + return object unless object + super + end + + instance_methods.each { |m| undef_method m unless /^__|^object_id$/.match?(m) } + + # Don't give a deprecation warning on inspect since test/unit and error + # logs rely on it for diagnostics. + def inspect + target.inspect + end + + private + def method_missing(called, *args, &block) + warn caller_locations, called, args + target.__send__(called, *args, &block) + end + end + + # DeprecatedObjectProxy transforms an object into a deprecated one. It takes an object, a deprecation message, and + # a deprecator. + # + # deprecated_object = ActiveSupport::Deprecation::DeprecatedObjectProxy.new(Object.new, "This object is now deprecated", ActiveSupport::Deprecation.new) + # # => # + # + # deprecated_object.to_s + # DEPRECATION WARNING: This object is now deprecated. + # (Backtrace) + # # => "#" + class DeprecatedObjectProxy < DeprecationProxy + def initialize(object, message, deprecator) + @object = object + @message = message + @deprecator = deprecator + end + + private + def target + @object + end + + def warn(callstack, called, args) + @deprecator.warn(@message, callstack) + end + end + + # DeprecatedInstanceVariableProxy transforms an instance variable into a deprecated one. It takes an instance of a + # class, a method on that class, an instance variable, and a deprecator as the last argument. + # + # Trying to use the deprecated instance variable will result in a deprecation warning, pointing to the method as a + # replacement. + # + # class Example + # def initialize + # @request = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(self, :request, :@request, ActiveSupport::Deprecation.new) + # @_request = :special_request + # end + # + # def request + # @_request + # end + # + # def old_request + # @request + # end + # end + # + # example = Example.new + # # => # + # + # example.old_request.to_s + # # => DEPRECATION WARNING: @request is deprecated! Call request.to_s instead of + # @request.to_s + # (Backtrace information…) + # "special_request" + # + # example.request.to_s + # # => "special_request" + class DeprecatedInstanceVariableProxy < DeprecationProxy + def initialize(instance, method, var = "@#{method}", deprecator:) + @instance = instance + @method = method + @var = var + @deprecator = deprecator + end + + private + def target + @instance.__send__(@method) + end + + def warn(callstack, called, args) + @deprecator.warn("#{@var} is deprecated! Call #{@method}.#{called} instead of #{@var}.#{called}. Args: #{args.inspect}", callstack) + end + end + + # DeprecatedConstantProxy transforms a constant into a deprecated one. It takes the full names of an old + # (deprecated) constant and of a new constant (both in string form) and a deprecator. The deprecated constant now + # returns the value of the new one. + # + # PLANETS = %w(mercury venus earth mars jupiter saturn uranus neptune pluto) + # + # # (In a later update, the original implementation of `PLANETS` has been removed.) + # + # PLANETS_POST_2006 = %w(mercury venus earth mars jupiter saturn uranus neptune) + # PLANETS = ActiveSupport::Deprecation::DeprecatedConstantProxy.new("PLANETS", "PLANETS_POST_2006", ActiveSupport::Deprecation.new) + # + # PLANETS.map { |planet| planet.capitalize } + # # => DEPRECATION WARNING: PLANETS is deprecated! Use PLANETS_POST_2006 instead. + # (Backtrace information…) + # ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"] + class DeprecatedConstantProxy < Module + def self.new(*args, **options, &block) + object = args.first + + return object unless object + super + end + + def initialize(old_const, new_const, deprecator, message: "#{old_const} is deprecated! Use #{new_const} instead.") + Kernel.require "active_support/inflector/methods" + + @old_const = old_const + @new_const = new_const + @deprecator = deprecator + @message = message + end + + instance_methods.each { |m| undef_method m unless /^__|^object_id$/.match?(m) } + + # Don't give a deprecation warning on inspect since test/unit and error + # logs rely on it for diagnostics. + def inspect + target.inspect + end + + # Don't give a deprecation warning on methods that IRB may invoke + # during tab-completion. + delegate :hash, :instance_methods, :name, :respond_to?, to: :target + + # Returns the class of the new constant. + # + # PLANETS_POST_2006 = %w(mercury venus earth mars jupiter saturn uranus neptune) + # PLANETS = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('PLANETS', 'PLANETS_POST_2006') + # PLANETS.class # => Array + def class + target.class + end + + def append_features(base) + @deprecator.warn(@message, caller_locations) + base.include(target) + end + + def prepend_features(base) + @deprecator.warn(@message, caller_locations) + base.prepend(target) + end + + def extended(base) + @deprecator.warn(@message, caller_locations) + base.extend(target) + end + + private + def target + ActiveSupport::Inflector.constantize(@new_const.to_s) + end + + def const_missing(name) + @deprecator.warn(@message, caller_locations) + target.const_get(name) + end + + def method_missing(...) + @deprecator.warn(@message, caller_locations) + target.__send__(...) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deprecation/reporting.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deprecation/reporting.rb new file mode 100644 index 00000000..30a95a04 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/deprecation/reporting.rb @@ -0,0 +1,160 @@ +# frozen_string_literal: true + +require "rbconfig" + +module ActiveSupport + class Deprecation + module Reporting + # Whether to print a message (silent mode) + attr_writer :silenced + # Name of gem where method is deprecated + attr_accessor :gem_name + + # Outputs a deprecation warning to the output configured by + # ActiveSupport::Deprecation#behavior. + # + # ActiveSupport::Deprecation.new.warn('something broke!') + # # => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)" + def warn(message = nil, callstack = nil) + return if silenced + + callstack ||= caller_locations(2) + deprecation_message(callstack, message).tap do |full_message| + if deprecation_disallowed?(message) + disallowed_behavior.each { |b| b.call(full_message, callstack, self) } + else + behavior.each { |b| b.call(full_message, callstack, self) } + end + end + end + + # Silence deprecation warnings within the block. + # + # deprecator = ActiveSupport::Deprecation.new + # deprecator.warn('something broke!') + # # => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)" + # + # deprecator.silence do + # deprecator.warn('something broke!') + # end + # # => nil + def silence(&block) + begin_silence + block.call + ensure + end_silence + end + + def begin_silence # :nodoc: + @silence_counter.value += 1 + end + + def end_silence # :nodoc: + @silence_counter.value -= 1 + end + + def silenced + @silenced || @silence_counter.value.nonzero? + end + + # Allow previously disallowed deprecation warnings within the block. + # allowed_warnings can be an array containing strings, symbols, or regular + # expressions. (Symbols are treated as strings). These are compared against + # the text of deprecation warning messages generated within the block. + # Matching warnings will be exempt from the rules set by + # ActiveSupport::Deprecation#disallowed_warnings. + # + # The optional if: argument accepts a truthy/falsy value or an object that + # responds to .call. If truthy, then matching warnings will be allowed. + # If falsey then the method yields to the block without allowing the warning. + # + # deprecator = ActiveSupport::Deprecation.new + # deprecator.disallowed_behavior = :raise + # deprecator.disallowed_warnings = [ + # "something broke" + # ] + # + # deprecator.warn('something broke!') + # # => ActiveSupport::DeprecationException + # + # deprecator.allow ['something broke'] do + # deprecator.warn('something broke!') + # end + # # => nil + # + # deprecator.allow ['something broke'], if: Rails.env.production? do + # deprecator.warn('something broke!') + # end + # # => ActiveSupport::DeprecationException for dev/test, nil for production + def allow(allowed_warnings = :all, if: true, &block) + conditional = binding.local_variable_get(:if) + conditional = conditional.call if conditional.respond_to?(:call) + if conditional + @explicitly_allowed_warnings.bind(allowed_warnings, &block) + else + yield + end + end + + def deprecation_warning(deprecated_method_name, message = nil, caller_backtrace = nil) + caller_backtrace ||= caller_locations(2) + deprecated_method_warning(deprecated_method_name, message).tap do |msg| + warn(msg, caller_backtrace) + end + end + + private + # Outputs a deprecation warning message + # + # deprecated_method_warning(:method_name) + # # => "method_name is deprecated and will be removed from Rails #{deprecation_horizon}" + # deprecated_method_warning(:method_name, :another_method) + # # => "method_name is deprecated and will be removed from Rails #{deprecation_horizon} (use another_method instead)" + # deprecated_method_warning(:method_name, "Optional message") + # # => "method_name is deprecated and will be removed from Rails #{deprecation_horizon} (Optional message)" + def deprecated_method_warning(method_name, message = nil) + warning = "#{method_name} is deprecated and will be removed from #{gem_name} #{deprecation_horizon}" + case message + when Symbol then "#{warning} (use #{message} instead)" + when String then "#{warning} (#{message})" + else warning + end + end + + def deprecation_message(callstack, message = nil) + message ||= "You are using deprecated behavior which will be removed from the next major or minor release." + "DEPRECATION WARNING: #{message} #{deprecation_caller_message(callstack)}" + end + + def deprecation_caller_message(callstack) + file, line, method = extract_callstack(callstack) + if file + if line && method + "(called from #{method} at #{file}:#{line})" + else + "(called from #{file}:#{line})" + end + end + end + + def extract_callstack(callstack) + return [] if callstack.empty? + + offending_line = callstack.find { |frame| + # Code generated with `eval` doesn't have an `absolute_path`, e.g. templates. + path = frame.absolute_path || frame.path + path && !ignored_callstack?(path) + } || callstack.first + + [offending_line.path, offending_line.lineno, offending_line.label] + end + + RAILS_GEM_ROOT = File.expand_path("../../../..", __dir__) + "/" # :nodoc: + LIB_DIR = RbConfig::CONFIG["libdir"] # :nodoc: + + def ignored_callstack?(path) + path.start_with?(RAILS_GEM_ROOT, LIB_DIR) || path.include?("(other) + if Scalar === other || Duration === other + value <=> other.value + elsif Numeric === other + value <=> other + else + nil + end + end + + def +(other) + if Duration === other + seconds = value + other._parts.fetch(:seconds, 0) + new_parts = other._parts.merge(seconds: seconds) + new_value = value + other.value + + Duration.new(new_value, new_parts, other.variable?) + else + calculate(:+, other) + end + end + + def -(other) + if Duration === other + seconds = value - other._parts.fetch(:seconds, 0) + new_parts = other._parts.transform_values(&:-@) + new_parts = new_parts.merge(seconds: seconds) + new_value = value - other.value + + Duration.new(new_value, new_parts, other.variable?) + else + calculate(:-, other) + end + end + + def *(other) + if Duration === other + new_parts = other._parts.transform_values { |other_value| value * other_value } + new_value = value * other.value + + Duration.new(new_value, new_parts, other.variable?) + else + calculate(:*, other) + end + end + + def /(other) + if Duration === other + value / other.value + else + calculate(:/, other) + end + end + + def %(other) + if Duration === other + Duration.build(value % other.value) + else + calculate(:%, other) + end + end + + def variable? # :nodoc: + false + end + + private + def calculate(op, other) + if Scalar === other + Scalar.new(value.public_send(op, other.value)) + elsif Numeric === other + Scalar.new(value.public_send(op, other)) + else + raise_type_error(other) + end + end + + def raise_type_error(other) + raise TypeError, "no implicit conversion of #{other.class} into #{self.class}" + end + end + + SECONDS_PER_MINUTE = 60 + SECONDS_PER_HOUR = 3600 + SECONDS_PER_DAY = 86400 + SECONDS_PER_WEEK = 604800 + SECONDS_PER_MONTH = 2629746 # 1/12 of a gregorian year + SECONDS_PER_YEAR = 31556952 # length of a gregorian year (365.2425 days) + + PARTS_IN_SECONDS = { + seconds: 1, + minutes: SECONDS_PER_MINUTE, + hours: SECONDS_PER_HOUR, + days: SECONDS_PER_DAY, + weeks: SECONDS_PER_WEEK, + months: SECONDS_PER_MONTH, + years: SECONDS_PER_YEAR + }.freeze + + PARTS = [:years, :months, :weeks, :days, :hours, :minutes, :seconds].freeze + VARIABLE_PARTS = [:years, :months, :weeks, :days].freeze + + attr_reader :value + + autoload :ISO8601Parser, "active_support/duration/iso8601_parser" + autoload :ISO8601Serializer, "active_support/duration/iso8601_serializer" + + class << self + # Creates a new Duration from string formatted according to ISO 8601 Duration. + # + # See {ISO 8601}[https://en.wikipedia.org/wiki/ISO_8601#Durations] for more information. + # This method allows negative parts to be present in pattern. + # If invalid string is provided, it will raise +ActiveSupport::Duration::ISO8601Parser::ParsingError+. + def parse(iso8601duration) + parts = ISO8601Parser.new(iso8601duration).parse! + new(calculate_total_seconds(parts), parts) + end + + def ===(other) # :nodoc: + other.is_a?(Duration) + rescue ::NoMethodError + false + end + + def seconds(value) # :nodoc: + new(value, { seconds: value }, false) + end + + def minutes(value) # :nodoc: + new(value * SECONDS_PER_MINUTE, { minutes: value }, false) + end + + def hours(value) # :nodoc: + new(value * SECONDS_PER_HOUR, { hours: value }, false) + end + + def days(value) # :nodoc: + new(value * SECONDS_PER_DAY, { days: value }, true) + end + + def weeks(value) # :nodoc: + new(value * SECONDS_PER_WEEK, { weeks: value }, true) + end + + def months(value) # :nodoc: + new(value * SECONDS_PER_MONTH, { months: value }, true) + end + + def years(value) # :nodoc: + new(value * SECONDS_PER_YEAR, { years: value }, true) + end + + # Creates a new Duration from a seconds value that is converted + # to the individual parts: + # + # ActiveSupport::Duration.build(31556952).parts # => {:years=>1} + # ActiveSupport::Duration.build(2716146).parts # => {:months=>1, :days=>1} + # + def build(value) + unless value.is_a?(::Numeric) + raise TypeError, "can't build an #{self.name} from a #{value.class.name}" + end + + parts = {} + remainder_sign = value <=> 0 + remainder = value.round(9).abs + variable = false + + PARTS.each do |part| + unless part == :seconds + part_in_seconds = PARTS_IN_SECONDS[part] + parts[part] = remainder.div(part_in_seconds) * remainder_sign + remainder %= part_in_seconds + + unless parts[part].zero? + variable ||= VARIABLE_PARTS.include?(part) + end + end + end unless value == 0 + + parts[:seconds] = remainder * remainder_sign + + new(value, parts, variable) + end + + private + def calculate_total_seconds(parts) + parts.inject(0) do |total, (part, value)| + total + value * PARTS_IN_SECONDS[part] + end + end + end + + Delegation.generate(self, [:to_f, :positive?, :negative?, :zero?, :abs], to: :@value, as: Integer, nilable: false) + + def initialize(value, parts, variable = nil) # :nodoc: + @value, @parts = value, parts + @parts.reject! { |k, v| v.zero? } unless value == 0 + @parts.freeze + @variable = variable + + if @variable.nil? + @variable = @parts.any? { |part, _| VARIABLE_PARTS.include?(part) } + end + end + + # Returns a copy of the parts hash that defines the duration. + # + # 5.minutes.parts # => {:minutes=>5} + # 3.years.parts # => {:years=>3} + def parts + @parts.dup + end + + def coerce(other) # :nodoc: + case other + when Scalar + [other, self] + when Duration + [Scalar.new(other.value), self] + else + [Scalar.new(other), self] + end + end + + # Compares one Duration with another or a Numeric to this Duration. + # Numeric values are treated as seconds. + def <=>(other) + if Duration === other + value <=> other.value + elsif Numeric === other + value <=> other + end + end + + # Adds another Duration or a Numeric to this Duration. Numeric values + # are treated as seconds. + def +(other) + if Duration === other + parts = @parts.merge(other._parts) do |_key, value, other_value| + value + other_value + end + Duration.new(value + other.value, parts, @variable || other.variable?) + else + seconds = @parts.fetch(:seconds, 0) + other + Duration.new(value + other, @parts.merge(seconds: seconds), @variable) + end + end + + # Subtracts another Duration or a Numeric from this Duration. Numeric + # values are treated as seconds. + def -(other) + self + (-other) + end + + # Multiplies this Duration by a Numeric and returns a new Duration. + def *(other) + if Scalar === other || Duration === other + Duration.new(value * other.value, @parts.transform_values { |number| number * other.value }, @variable || other.variable?) + elsif Numeric === other + Duration.new(value * other, @parts.transform_values { |number| number * other }, @variable) + else + raise_type_error(other) + end + end + + # Divides this Duration by a Numeric and returns a new Duration. + def /(other) + if Scalar === other + Duration.new(value / other.value, @parts.transform_values { |number| number / other.value }, @variable) + elsif Duration === other + value / other.value + elsif Numeric === other + Duration.new(value / other, @parts.transform_values { |number| number / other }, @variable) + else + raise_type_error(other) + end + end + + # Returns the modulo of this Duration by another Duration or Numeric. + # Numeric values are treated as seconds. + def %(other) + if Duration === other || Scalar === other + Duration.build(value % other.value) + elsif Numeric === other + Duration.build(value % other) + else + raise_type_error(other) + end + end + + def -@ # :nodoc: + Duration.new(-value, @parts.transform_values(&:-@), @variable) + end + + def +@ # :nodoc: + self + end + + def is_a?(klass) # :nodoc: + Duration == klass || value.is_a?(klass) + end + alias :kind_of? :is_a? + + def instance_of?(klass) # :nodoc: + Duration == klass || value.instance_of?(klass) + end + + # Returns +true+ if +other+ is also a Duration instance with the + # same +value+, or if other == value. + def ==(other) + if Duration === other + other.value == value + else + other == value + end + end + + # Returns the amount of seconds a duration covers as a string. + # For more information check to_i method. + # + # 1.day.to_s # => "86400" + def to_s + @value.to_s + end + + # Returns the number of seconds that this Duration represents. + # + # 1.minute.to_i # => 60 + # 1.hour.to_i # => 3600 + # 1.day.to_i # => 86400 + # + # Note that this conversion makes some assumptions about the + # duration of some periods, e.g. months are always 1/12 of year + # and years are 365.2425 days: + # + # # equivalent to (1.year / 12).to_i + # 1.month.to_i # => 2629746 + # + # # equivalent to 365.2425.days.to_i + # 1.year.to_i # => 31556952 + # + # In such cases, Ruby's core + # Date[https://docs.ruby-lang.org/en/master/Date.html] and + # Time[https://docs.ruby-lang.org/en/master/Time.html] should be used for precision + # date and time arithmetic. + def to_i + @value.to_i + end + alias :in_seconds :to_i + + # Returns the amount of minutes a duration covers as a float + # + # 1.day.in_minutes # => 1440.0 + def in_minutes + in_seconds / SECONDS_PER_MINUTE.to_f + end + + # Returns the amount of hours a duration covers as a float + # + # 1.day.in_hours # => 24.0 + def in_hours + in_seconds / SECONDS_PER_HOUR.to_f + end + + # Returns the amount of days a duration covers as a float + # + # 12.hours.in_days # => 0.5 + def in_days + in_seconds / SECONDS_PER_DAY.to_f + end + + # Returns the amount of weeks a duration covers as a float + # + # 2.months.in_weeks # => 8.696 + def in_weeks + in_seconds / SECONDS_PER_WEEK.to_f + end + + # Returns the amount of months a duration covers as a float + # + # 9.weeks.in_months # => 2.07 + def in_months + in_seconds / SECONDS_PER_MONTH.to_f + end + + # Returns the amount of years a duration covers as a float + # + # 30.days.in_years # => 0.082 + def in_years + in_seconds / SECONDS_PER_YEAR.to_f + end + + # Returns +true+ if +other+ is also a Duration instance, which has the + # same parts as this one. + def eql?(other) + Duration === other && other.value.eql?(value) + end + + def hash + @value.hash + end + + # Calculates a new Time or Date that is as far in the future + # as this Duration represents. + def since(time = ::Time.current) + sum(1, time) + end + alias :from_now :since + alias :after :since + + # Calculates a new Time or Date that is as far in the past + # as this Duration represents. + def ago(time = ::Time.current) + sum(-1, time) + end + alias :until :ago + alias :before :ago + + def inspect # :nodoc: + return "#{value} seconds" if @parts.empty? + + @parts. + sort_by { |unit, _ | PARTS.index(unit) }. + map { |unit, val| "#{val} #{val == 1 ? unit.to_s.chop : unit.to_s}" }. + to_sentence(locale: false) + end + + def as_json(options = nil) # :nodoc: + to_i + end + + def init_with(coder) # :nodoc: + initialize(coder["value"], coder["parts"]) + end + + def encode_with(coder) # :nodoc: + coder.map = { "value" => @value, "parts" => @parts } + end + + # Build ISO 8601 Duration string for this duration. + # The +precision+ parameter can be used to limit seconds' precision of duration. + def iso8601(precision: nil) + ISO8601Serializer.new(self, precision: precision).serialize + end + + def variable? # :nodoc: + @variable + end + + def _parts # :nodoc: + @parts + end + + private + def sum(sign, time = ::Time.current) + unless time.acts_like?(:time) || time.acts_like?(:date) + raise ::ArgumentError, "expected a time or date, got #{time.inspect}" + end + + if @parts.empty? + time.since(sign * value) + else + @parts.each do |type, number| + t = time + time = + if type == :seconds + t.since(sign * number) + elsif type == :minutes + t.since(sign * number * 60) + elsif type == :hours + t.since(sign * number * 3600) + else + t.advance(type => sign * number) + end + end + + time + end + end + + def respond_to_missing?(method, _) + value.respond_to?(method) + end + + def method_missing(...) + value.public_send(...) + end + + def raise_type_error(other) + raise TypeError, "no implicit conversion of #{other.class} into #{self.class}" + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/duration/iso8601_parser.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/duration/iso8601_parser.rb new file mode 100644 index 00000000..8ccd0cf4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/duration/iso8601_parser.rb @@ -0,0 +1,123 @@ +# frozen_string_literal: true + +require "strscan" + +module ActiveSupport + class Duration + # Parses a string formatted according to ISO 8601 Duration into the hash. + # + # See {ISO 8601}[https://en.wikipedia.org/wiki/ISO_8601#Durations] for more information. + # + # This parser allows negative parts to be present in pattern. + class ISO8601Parser # :nodoc: + class ParsingError < ::ArgumentError; end + + PERIOD_OR_COMMA = /\.|,/ + PERIOD = "." + COMMA = "," + + SIGN_MARKER = /\A-|\+|/ + DATE_MARKER = /P/ + TIME_MARKER = /T/ + DATE_COMPONENT = /(-?\d+(?:[.,]\d+)?)(Y|M|D|W)/ + TIME_COMPONENT = /(-?\d+(?:[.,]\d+)?)(H|M|S)/ + + DATE_TO_PART = { "Y" => :years, "M" => :months, "W" => :weeks, "D" => :days } + TIME_TO_PART = { "H" => :hours, "M" => :minutes, "S" => :seconds } + + DATE_COMPONENTS = [:years, :months, :days] + TIME_COMPONENTS = [:hours, :minutes, :seconds] + + attr_reader :parts, :scanner + attr_accessor :mode, :sign + + def initialize(string) + @scanner = StringScanner.new(string) + @parts = {} + @mode = :start + @sign = 1 + end + + def parse! + while !finished? + case mode + when :start + if scan(SIGN_MARKER) + self.sign = (scanner.matched == "-") ? -1 : 1 + self.mode = :sign + else + raise_parsing_error + end + + when :sign + if scan(DATE_MARKER) + self.mode = :date + else + raise_parsing_error + end + + when :date + if scan(TIME_MARKER) + self.mode = :time + elsif scan(DATE_COMPONENT) + parts[DATE_TO_PART[scanner[2]]] = number * sign + else + raise_parsing_error + end + + when :time + if scan(TIME_COMPONENT) + parts[TIME_TO_PART[scanner[2]]] = number * sign + else + raise_parsing_error + end + + end + end + + validate! + parts + end + + private + def finished? + scanner.eos? + end + + # Parses number which can be a float with either comma or period. + def number + PERIOD_OR_COMMA.match?(scanner[1]) ? scanner[1].tr(COMMA, PERIOD).to_f : scanner[1].to_i + end + + def scan(pattern) + scanner.scan(pattern) + end + + def raise_parsing_error(reason = nil) + raise ParsingError, "Invalid ISO 8601 duration: #{scanner.string.inspect} #{reason}".strip + end + + # Checks for various semantic errors as stated in ISO 8601 standard. + def validate! + raise_parsing_error("is empty duration") if parts.empty? + + # Mixing any of Y, M, D with W is invalid. + if parts.key?(:weeks) && parts.keys.intersect?(DATE_COMPONENTS) + raise_parsing_error("mixing weeks with other date parts not allowed") + end + + # Specifying an empty T part is invalid. + if mode == :time && !parts.keys.intersect?(TIME_COMPONENTS) + raise_parsing_error("time part marker is present but time part is empty") + end + + fractions = parts.values.reject(&:zero?).select { |a| (a % 1) != 0 } + unless fractions.empty? || (fractions.size == 1 && fractions.last == @parts.values.reject(&:zero?).last) + raise_parsing_error "(only last part can be fractional)" + end + + true + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/duration/iso8601_serializer.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/duration/iso8601_serializer.rb new file mode 100644 index 00000000..ca9c9129 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/duration/iso8601_serializer.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +module ActiveSupport + class Duration + # Serializes duration to string according to ISO 8601 Duration format. + class ISO8601Serializer # :nodoc: + DATE_COMPONENTS = %i(years months days) + + def initialize(duration, precision: nil) + @duration = duration + @precision = precision + end + + # Builds and returns output string. + def serialize + parts = normalize + return "PT0S" if parts.empty? + + output = +"P" + output << "#{parts[:years]}Y" if parts.key?(:years) + output << "#{parts[:months]}M" if parts.key?(:months) + output << "#{parts[:days]}D" if parts.key?(:days) + output << "#{parts[:weeks]}W" if parts.key?(:weeks) + time = +"" + time << "#{parts[:hours]}H" if parts.key?(:hours) + time << "#{parts[:minutes]}M" if parts.key?(:minutes) + if parts.key?(:seconds) + time << "#{format_seconds(parts[:seconds])}S" + end + output << "T#{time}" unless time.empty? + output + end + + private + # Return pair of duration's parts and whole duration sign. + # Parts are summarized (as they can become repetitive due to addition, etc). + # Zero parts are removed as not significant. + def normalize + parts = @duration.parts.each_with_object(Hash.new(0)) do |(k, v), p| + p[k] += v unless v.zero? + end + + # Convert weeks to days and remove weeks if mixed with date parts + if week_mixed_with_date?(parts) + parts[:days] += parts.delete(:weeks) * SECONDS_PER_WEEK / SECONDS_PER_DAY + end + + parts + end + + def week_mixed_with_date?(parts) + parts.key?(:weeks) && parts.keys.intersect?(DATE_COMPONENTS) + end + + def format_seconds(seconds) + if @precision + sprintf("%0.0#{@precision}f", seconds) + else + seconds.to_s + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/encrypted_configuration.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/encrypted_configuration.rb new file mode 100644 index 00000000..39c7636d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/encrypted_configuration.rb @@ -0,0 +1,126 @@ +# frozen_string_literal: true + +require "yaml" +require "active_support/encrypted_file" +require "active_support/ordered_options" +require "active_support/core_ext/object/inclusion" +require "active_support/core_ext/hash/keys" +require "active_support/core_ext/module/delegation" + +module ActiveSupport + # = Encrypted Configuration + # + # Provides convenience methods on top of EncryptedFile to access values stored + # as encrypted YAML. + # + # Values can be accessed via +Hash+ methods, such as +fetch+ and +dig+, or via + # dynamic accessor methods, similar to OrderedOptions. + # + # my_config = ActiveSupport::EncryptedConfiguration.new(...) + # my_config.read # => "some_secret: 123\nsome_namespace:\n another_secret: 456" + # + # my_config[:some_secret] + # # => 123 + # my_config.some_secret + # # => 123 + # my_config.dig(:some_namespace, :another_secret) + # # => 456 + # my_config.some_namespace.another_secret + # # => 456 + # my_config.fetch(:foo) + # # => KeyError + # my_config.foo! + # # => KeyError + # + class EncryptedConfiguration < EncryptedFile + class InvalidContentError < RuntimeError + def initialize(content_path) + super "Invalid YAML in '#{content_path}'." + end + + def message + cause.is_a?(Psych::SyntaxError) ? "#{super}\n\n #{cause.message}" : super + end + end + + class InvalidKeyError < RuntimeError + def initialize(content_path, key) + super "Key '#{key}' is invalid, it must respond to '#to_sym' from configuration in '#{content_path}'." + end + end + + delegate_missing_to :options + + def initialize(config_path:, key_path:, env_key:, raise_if_missing_key:) + super content_path: config_path, key_path: key_path, + env_key: env_key, raise_if_missing_key: raise_if_missing_key + @config = nil + @options = nil + end + + # Reads the file and returns the decrypted content. See EncryptedFile#read. + def read + super + rescue ActiveSupport::EncryptedFile::MissingContentError + # Allow a config to be started without a file present + "" + end + + def validate! # :nodoc: + deserialize(read).each_key do |key| + key.to_sym + rescue NoMethodError + raise InvalidKeyError.new(content_path, key) + end + end + + # Returns the decrypted content as a Hash with symbolized keys. + # + # my_config = ActiveSupport::EncryptedConfiguration.new(...) + # my_config.read # => "some_secret: 123\nsome_namespace:\n another_secret: 456" + # + # my_config.config + # # => { some_secret: 123, some_namespace: { another_secret: 789 } } + # + def config + @config ||= deep_symbolize_keys(deserialize(read)) + end + + def inspect # :nodoc: + "#<#{self.class.name}:#{'%#016x' % (object_id << 1)}>" + end + + private + def deep_symbolize_keys(hash) + hash.deep_transform_keys do |key| + key.to_sym + rescue NoMethodError + raise InvalidKeyError.new(content_path, key) + end + end + + def deep_transform(hash) + return hash unless hash.is_a?(Hash) + + h = ActiveSupport::OrderedOptions.new + hash.each do |k, v| + h[k] = deep_transform(v) + end + h + end + + def options + @options ||= deep_transform(config) + end + + def deserialize(content) + config = YAML.respond_to?(:unsafe_load) ? + YAML.unsafe_load(content, filename: content_path) : + YAML.load(content, filename: content_path) + + config.presence || {} + rescue Psych::SyntaxError + raise InvalidContentError.new(content_path) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/encrypted_file.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/encrypted_file.rb new file mode 100644 index 00000000..6522e00e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/encrypted_file.rb @@ -0,0 +1,133 @@ +# frozen_string_literal: true + +require "pathname" +require "tempfile" +require "active_support/message_encryptor" + +module ActiveSupport + class EncryptedFile + class MissingContentError < RuntimeError + def initialize(content_path) + super "Missing encrypted content file in #{content_path}." + end + end + + class MissingKeyError < RuntimeError + def initialize(key_path:, env_key:) + super \ + "Missing encryption key to decrypt file with. " + + "Ask your team for your master key and write it to #{key_path} or put it in the ENV['#{env_key}']." + end + end + + class InvalidKeyLengthError < RuntimeError + def initialize + super "Encryption key must be exactly #{EncryptedFile.expected_key_length} characters." + end + end + + CIPHER = "aes-128-gcm" + + def self.generate_key + SecureRandom.hex(ActiveSupport::MessageEncryptor.key_len(CIPHER)) + end + + def self.expected_key_length # :nodoc: + @expected_key_length ||= generate_key.length + end + + + attr_reader :content_path, :key_path, :env_key, :raise_if_missing_key + + def initialize(content_path:, key_path:, env_key:, raise_if_missing_key:) + @content_path = Pathname.new(content_path).yield_self { |path| path.symlink? ? path.realpath : path } + @key_path = Pathname.new(key_path) + @env_key, @raise_if_missing_key = env_key, raise_if_missing_key + end + + # Returns the encryption key, first trying the environment variable + # specified by +env_key+, then trying the key file specified by +key_path+. + # If +raise_if_missing_key+ is true, raises MissingKeyError if the + # environment variable is not set and the key file does not exist. + def key + read_env_key || read_key_file || handle_missing_key + end + + # Returns truthy if #key is truthy. Returns falsy otherwise. Unlike #key, + # does not raise MissingKeyError when +raise_if_missing_key+ is true. + def key? + read_env_key || read_key_file + end + + # Reads the file and returns the decrypted content. + # + # Raises: + # - MissingKeyError if the key is missing and +raise_if_missing_key+ is true. + # - MissingContentError if the encrypted file does not exist or otherwise + # if the key is missing. + # - ActiveSupport::MessageEncryptor::InvalidMessage if the content cannot be + # decrypted or verified. + def read + if !key.nil? && content_path.exist? + decrypt content_path.binread.strip + else + raise MissingContentError, content_path + end + end + + def write(contents) + IO.binwrite "#{content_path}.tmp", encrypt(contents) + FileUtils.mv "#{content_path}.tmp", content_path + end + + def change(&block) + writing read, &block + end + + + private + def writing(contents) + Tempfile.create(["", "-" + content_path.basename.to_s.chomp(".enc")]) do |tmp_file| + tmp_path = Pathname.new(tmp_file) + tmp_path.binwrite contents + + yield tmp_path + + updated_contents = tmp_path.binread + + write(updated_contents) if updated_contents != contents + end + end + + + def encrypt(contents) + check_key_length + encryptor.encrypt_and_sign contents + end + + def decrypt(contents) + encryptor.decrypt_and_verify contents + end + + def encryptor + @encryptor ||= ActiveSupport::MessageEncryptor.new([ key ].pack("H*"), cipher: CIPHER, serializer: Marshal) + end + + + def read_env_key + ENV[env_key].presence + end + + def read_key_file + @key_file_contents ||= (key_path.binread.strip if key_path.exist?) + end + + def handle_missing_key + raise MissingKeyError.new(key_path: key_path, env_key: env_key) if raise_if_missing_key + end + + def check_key_length + raise InvalidKeyLengthError if key&.length != self.class.expected_key_length + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/environment_inquirer.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/environment_inquirer.rb new file mode 100644 index 00000000..6fa4fa1d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/environment_inquirer.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require "active_support/string_inquirer" +require "active_support/core_ext/object/inclusion" + +module ActiveSupport + class EnvironmentInquirer < StringInquirer # :nodoc: + # Optimization for the three default environments, so this inquirer doesn't need to rely on + # the slower delegation through method_missing that StringInquirer would normally entail. + DEFAULT_ENVIRONMENTS = %w[ development test production ] + + # Environments that'll respond true for #local? + LOCAL_ENVIRONMENTS = %w[ development test ] + + def initialize(env) + raise(ArgumentError, "'local' is a reserved environment name") if env == "local" + + super(env) + + DEFAULT_ENVIRONMENTS.each do |default| + instance_variable_set :"@#{default}", env == default + end + + @local = in? LOCAL_ENVIRONMENTS + end + + DEFAULT_ENVIRONMENTS.each do |env| + class_eval <<~RUBY, __FILE__, __LINE__ + 1 + def #{env}? + @#{env} + end + RUBY + end + + # Returns true if we're in the development or test environment. + def local? + @local + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/error_reporter.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/error_reporter.rb new file mode 100644 index 00000000..12ef41c8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/error_reporter.rb @@ -0,0 +1,274 @@ +# frozen_string_literal: true + +module ActiveSupport + # = Active Support \Error Reporter + # + # +ActiveSupport::ErrorReporter+ is a common interface for error reporting services. + # + # To rescue and report any unhandled error, you can use the #handle method: + # + # Rails.error.handle do + # do_something! + # end + # + # If an error is raised, it will be reported and swallowed. + # + # Alternatively, if you want to report the error but not swallow it, you can use #record: + # + # Rails.error.record do + # do_something! + # end + # + # Both methods can be restricted to handle only a specific error class: + # + # maybe_tags = Rails.error.handle(Redis::BaseError) { redis.get("tags") } + # + class ErrorReporter + SEVERITIES = %i(error warning info) + DEFAULT_SOURCE = "application" + DEFAULT_RESCUE = [StandardError].freeze + + attr_accessor :logger, :debug_mode + + UnexpectedError = Class.new(Exception) + + def initialize(*subscribers, logger: nil) + @subscribers = subscribers.flatten + @logger = logger + @debug_mode = false + end + + # Evaluates the given block, reporting and swallowing any unhandled error. + # If no error is raised, returns the return value of the block. Otherwise, + # returns the result of +fallback.call+, or +nil+ if +fallback+ is not + # specified. + # + # # Will report a TypeError to all subscribers and return nil. + # Rails.error.handle do + # 1 + '1' + # end + # + # Can be restricted to handle only specific error classes: + # + # maybe_tags = Rails.error.handle(Redis::BaseError) { redis.get("tags") } + # + # ==== Options + # + # * +:severity+ - This value is passed along to subscribers to indicate how + # important the error report is. Can be +:error+, +:warning+, or +:info+. + # Defaults to +:warning+. + # + # * +:context+ - Extra information that is passed along to subscribers. For + # example: + # + # Rails.error.handle(context: { section: "admin" }) do + # # ... + # end + # + # * +:fallback+ - A callable that provides +handle+'s return value when an + # unhandled error is raised. For example: + # + # user = Rails.error.handle(fallback: -> { User.anonymous }) do + # User.find_by(params) + # end + # + # * +:source+ - This value is passed along to subscribers to indicate the + # source of the error. Subscribers can use this value to ignore certain + # errors. Defaults to "application". + def handle(*error_classes, severity: :warning, context: {}, fallback: nil, source: DEFAULT_SOURCE) + error_classes = DEFAULT_RESCUE if error_classes.empty? + yield + rescue *error_classes => error + report(error, handled: true, severity: severity, context: context, source: source) + fallback.call if fallback + end + + # Evaluates the given block, reporting and re-raising any unhandled error. + # If no error is raised, returns the return value of the block. + # + # # Will report a TypeError to all subscribers and re-raise it. + # Rails.error.record do + # 1 + '1' + # end + # + # Can be restricted to handle only specific error classes: + # + # tags = Rails.error.record(Redis::BaseError) { redis.get("tags") } + # + # ==== Options + # + # * +:severity+ - This value is passed along to subscribers to indicate how + # important the error report is. Can be +:error+, +:warning+, or +:info+. + # Defaults to +:error+. + # + # * +:context+ - Extra information that is passed along to subscribers. For + # example: + # + # Rails.error.record(context: { section: "admin" }) do + # # ... + # end + # + # * +:source+ - This value is passed along to subscribers to indicate the + # source of the error. Subscribers can use this value to ignore certain + # errors. Defaults to "application". + def record(*error_classes, severity: :error, context: {}, source: DEFAULT_SOURCE) + error_classes = DEFAULT_RESCUE if error_classes.empty? + yield + rescue *error_classes => error + report(error, handled: false, severity: severity, context: context, source: source) + raise + end + + # Either report the given error when in production, or raise it when in development or test. + # + # When called in production, after the error is reported, this method will return + # nil and execution will continue. + # + # When called in development, the original error is wrapped in a different error class to ensure + # it's not being rescued higher in the stack and will be surfaced to the developer. + # + # This method is intended for reporting violated assertions about preconditions, or similar + # cases that can and should be gracefully handled in production, but that aren't supposed to happen. + # + # The error can be either an exception instance or a String. + # + # example: + # + # def edit + # if published? + # Rails.error.unexpected("[BUG] Attempting to edit a published article, that shouldn't be possible") + # return false + # end + # # ... + # end + # + def unexpected(error, severity: :warning, context: {}, source: DEFAULT_SOURCE) + error = RuntimeError.new(error) if error.is_a?(String) + + if @debug_mode + ensure_backtrace(error) + raise UnexpectedError, "#{error.class.name}: #{error.message}", error.backtrace, cause: error + else + report(error, handled: true, severity: severity, context: context, source: source) + end + end + + # Register a new error subscriber. The subscriber must respond to + # + # report(Exception, handled: Boolean, severity: (:error OR :warning OR :info), context: Hash, source: String) + # + # The +report+ method should never raise an error. + def subscribe(subscriber) + unless subscriber.respond_to?(:report) + raise ArgumentError, "Error subscribers must respond to #report" + end + @subscribers << subscriber + end + + # Unregister an error subscriber. Accepts either a subscriber or a class. + # + # subscriber = MyErrorSubscriber.new + # Rails.error.subscribe(subscriber) + # + # Rails.error.unsubscribe(subscriber) + # # or + # Rails.error.unsubscribe(MyErrorSubscriber) + def unsubscribe(subscriber) + @subscribers.delete_if { |s| subscriber === s } + end + + # Prevent a subscriber from being notified of errors for the + # duration of the block. You may pass in the subscriber itself, or its class. + # + # This can be helpful for error reporting service integrations, when they wish + # to handle any errors higher in the stack. + def disable(subscriber) + disabled_subscribers = (ActiveSupport::IsolatedExecutionState[self] ||= []) + disabled_subscribers << subscriber + begin + yield + ensure + disabled_subscribers.delete(subscriber) + end + end + + # Update the execution context that is accessible to error subscribers. Any + # context passed to #handle, #record, or #report will be merged with the + # context set here. + # + # Rails.error.set_context(section: "checkout", user_id: @user.id) + # + def set_context(...) + ActiveSupport::ExecutionContext.set(...) + end + + # Report an error directly to subscribers. You can use this method when the + # block-based #handle and #record methods are not suitable. + # + # Rails.error.report(error) + # + # The +error+ argument must be an instance of Exception. + # + # Rails.error.report(Exception.new("Something went wrong")) + # + # Otherwise you can use #unexpected to report an error which does accept a + # string argument. + def report(error, handled: true, severity: handled ? :warning : :error, context: {}, source: DEFAULT_SOURCE) + return if error.instance_variable_defined?(:@__rails_error_reported) + ensure_backtrace(error) + + unless SEVERITIES.include?(severity) + raise ArgumentError, "severity must be one of #{SEVERITIES.map(&:inspect).join(", ")}, got: #{severity.inspect}" + end + + full_context = ActiveSupport::ExecutionContext.to_h.merge(context) + disabled_subscribers = ActiveSupport::IsolatedExecutionState[self] + @subscribers.each do |subscriber| + unless disabled_subscribers&.any? { |s| s === subscriber } + subscriber.report(error, handled: handled, severity: severity, context: full_context, source: source) + end + rescue => subscriber_error + if logger + logger.fatal( + "Error subscriber raised an error: #{subscriber_error.message} (#{subscriber_error.class})\n" + + subscriber_error.backtrace.join("\n") + ) + else + raise + end + end + + while error + unless error.frozen? + error.instance_variable_set(:@__rails_error_reported, true) + end + error = error.cause + end + + nil + end + + private + def ensure_backtrace(error) + return if error.frozen? # re-raising won't add a backtrace + return unless error.backtrace.nil? + + begin + # We could use Exception#set_backtrace, but until Ruby 3.4 + # it only support setting `Exception#backtrace` and not + # `Exception#backtrace_locations`. So raising the exception + # is a good way to build a real backtrace. + raise error + rescue error.class => error + end + + count = 0 + while error.backtrace_locations.first&.path == __FILE__ + count += 1 + error.backtrace_locations.shift + end + + error.backtrace.shift(count) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/error_reporter/test_helper.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/error_reporter/test_helper.rb new file mode 100644 index 00000000..bc67efa2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/error_reporter/test_helper.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module ActiveSupport::ErrorReporter::TestHelper # :nodoc: + class ErrorSubscriber + attr_reader :events + + def initialize + @events = [] + end + + def report(error, handled:, severity:, source:, context:) + @events << [error, handled, severity, source, context] + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/evented_file_update_checker.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/evented_file_update_checker.rb new file mode 100644 index 00000000..4bfc42d4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/evented_file_update_checker.rb @@ -0,0 +1,181 @@ +# frozen_string_literal: true + +gem "listen", "~> 3.5" +require "listen" + +require "pathname" +require "concurrent/atomic/atomic_boolean" + +module ActiveSupport + # Allows you to "listen" to changes in a file system. + # The evented file updater does not hit disk when checking for updates. + # Instead, it uses platform-specific file system events to trigger a change + # in state. + # + # The file checker takes an array of files to watch or a hash specifying directories + # and file extensions to watch. It also takes a block that is called when + # EventedFileUpdateChecker#execute is run or when EventedFileUpdateChecker#execute_if_updated + # is run and there have been changes to the file system. + # + # Example: + # + # checker = ActiveSupport::EventedFileUpdateChecker.new(["/tmp/foo"]) { puts "changed" } + # checker.updated? + # # => false + # checker.execute_if_updated + # # => nil + # + # FileUtils.touch("/tmp/foo") + # + # checker.updated? + # # => true + # checker.execute_if_updated + # # => "changed" + # + class EventedFileUpdateChecker # :nodoc: all + def initialize(files, dirs = {}, &block) + unless block + raise ArgumentError, "A block is required to initialize an EventedFileUpdateChecker" + end + + @block = block + @core = Core.new(files, dirs) + ObjectSpace.define_finalizer(self, @core.finalizer) + end + + def inspect + "# error + error_reporter&.report(error, handled: false, source: source) + raise + ensure + instance.complete! + end + end + + def self.perform # :nodoc: + instance = new + instance.run + begin + yield + ensure + instance.complete + end + end + + def self.error_reporter # :nodoc: + ActiveSupport.error_reporter + end + + def self.active_key # :nodoc: + @active_key ||= :"active_execution_wrapper_#{object_id}" + end + + def self.active? # :nodoc: + IsolatedExecutionState.key?(active_key) + end + + def run! # :nodoc: + IsolatedExecutionState[self.class.active_key] = self + run + end + + def run # :nodoc: + run_callbacks(:run) + end + + # Complete this in-flight execution. This method *must* be called + # exactly once on the result of any call to +run!+. + # + # Where possible, prefer +wrap+. + def complete! + complete + ensure + IsolatedExecutionState.delete(self.class.active_key) + end + + def complete # :nodoc: + run_callbacks(:complete) + end + + private + def hook_state + @_hook_state ||= {} + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/executor.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/executor.rb new file mode 100644 index 00000000..ce391b07 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/executor.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +require "active_support/execution_wrapper" + +module ActiveSupport + class Executor < ExecutionWrapper + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/executor/test_helper.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/executor/test_helper.rb new file mode 100644 index 00000000..97f489dc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/executor/test_helper.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module ActiveSupport::Executor::TestHelper # :nodoc: + def run(...) + Rails.application.executor.perform { super } + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/file_update_checker.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/file_update_checker.rb new file mode 100644 index 00000000..608755d0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/file_update_checker.rb @@ -0,0 +1,164 @@ +# frozen_string_literal: true + +require "active_support/core_ext/time/calculations" + +module ActiveSupport + # = \File Update Checker + # + # FileUpdateChecker specifies the API used by \Rails to watch files + # and control reloading. The API depends on four methods: + # + # * +initialize+ which expects two parameters and one block as + # described below. + # + # * +updated?+ which returns a boolean if there were updates in + # the filesystem or not. + # + # * +execute+ which executes the given block on initialization + # and updates the latest watched files and timestamp. + # + # * +execute_if_updated+ which just executes the block if it was updated. + # + # After initialization, a call to +execute_if_updated+ must execute + # the block only if there was really a change in the filesystem. + # + # This class is used by \Rails to reload the I18n framework whenever + # they are changed upon a new request. + # + # i18n_reloader = ActiveSupport::FileUpdateChecker.new(paths) do + # I18n.reload! + # end + # + # ActiveSupport::Reloader.to_prepare do + # i18n_reloader.execute_if_updated + # end + class FileUpdateChecker + # It accepts two parameters on initialization. The first is an array + # of files and the second is an optional hash of directories. The hash must + # have directories as keys and the value is an array of extensions to be + # watched under that directory. + # + # This method must also receive a block that will be called once a path + # changes. The array of files and list of directories cannot be changed + # after FileUpdateChecker has been initialized. + def initialize(files, dirs = {}, &block) + unless block + raise ArgumentError, "A block is required to initialize a FileUpdateChecker" + end + + @files = files.freeze + @glob = compile_glob(dirs) + @block = block + + @watched = nil + @updated_at = nil + + @last_watched = watched + @last_update_at = updated_at(@last_watched) + end + + # Check if any of the entries were updated. If so, the watched and/or + # updated_at values are cached until the block is executed via +execute+ + # or +execute_if_updated+. + def updated? + current_watched = watched + if @last_watched.size != current_watched.size + @watched = current_watched + true + else + current_updated_at = updated_at(current_watched) + if @last_update_at < current_updated_at + @watched = current_watched + @updated_at = current_updated_at + true + else + false + end + end + end + + # Executes the given block and updates the latest watched files and + # timestamp. + def execute + @last_watched = watched + @last_update_at = updated_at(@last_watched) + @block.call + ensure + @watched = nil + @updated_at = nil + end + + # Execute the block given if updated. + def execute_if_updated + if updated? + yield if block_given? + execute + true + else + false + end + end + + private + def watched + @watched || begin + all = @files.select { |f| File.exist?(f) } + all.concat(Dir[@glob]) if @glob + all.tap(&:uniq!) + end + end + + def updated_at(paths) + @updated_at || max_mtime(paths) || Time.at(0) + end + + # This method returns the maximum mtime of the files in +paths+, or +nil+ + # if the array is empty. + # + # Files with a mtime in the future are ignored. Such abnormal situation + # can happen for example if the user changes the clock by hand. It is + # healthy to consider this edge case because with mtimes in the future + # reloading is not triggered. + def max_mtime(paths) + time_now = Time.now + max_mtime = nil + + # Time comparisons are performed with #compare_without_coercion because + # AS redefines these operators in a way that is much slower and does not + # bring any benefit in this particular code. + # + # Read t1.compare_without_coercion(t2) < 0 as t1 < t2. + paths.each do |path| + mtime = File.mtime(path) + + next if time_now.compare_without_coercion(mtime) < 0 + + if max_mtime.nil? || max_mtime.compare_without_coercion(mtime) < 0 + max_mtime = mtime + end + end + + max_mtime + end + + def compile_glob(hash) + hash.freeze # Freeze so changes aren't accidentally pushed + return if hash.empty? + + globs = hash.map do |key, value| + "#{escape(key)}/**/*#{compile_ext(value)}" + end + "{#{globs.join(",")}}" + end + + def escape(key) + key.gsub(",", '\,') + end + + def compile_ext(array) + array = Array(array) + return if array.empty? + ".{#{array.join(",")}}" + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/fork_tracker.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/fork_tracker.rb new file mode 100644 index 00000000..2ff8fc5b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/fork_tracker.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +module ActiveSupport + module ForkTracker # :nodoc: + module CoreExt + def _fork + pid = super + if pid == 0 + ForkTracker.after_fork_callback + end + pid + end + end + + @pid = Process.pid + @callbacks = [] + + class << self + def after_fork_callback + new_pid = Process.pid + if @pid != new_pid + @callbacks.each(&:call) + @pid = new_pid + end + end + + def hook! + ::Process.singleton_class.prepend(CoreExt) + end + + def after_fork(&block) + @callbacks << block + block + end + + def unregister(callback) + @callbacks.delete(callback) + end + end + end +end + +ActiveSupport::ForkTracker.hook! diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/gem_version.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/gem_version.rb new file mode 100644 index 00000000..0386e59a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/gem_version.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module ActiveSupport + # Returns the currently loaded version of Active Support as a +Gem::Version+. + def self.gem_version + Gem::Version.new VERSION::STRING + end + + module VERSION + MAJOR = 8 + MINOR = 0 + TINY = 2 + PRE = nil + + STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/gzip.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/gzip.rb new file mode 100644 index 00000000..f6ecc29c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/gzip.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require "zlib" +require "stringio" + +module ActiveSupport + # = Active Support \Gzip + # + # A convenient wrapper for the zlib standard library that allows + # compression/decompression of strings with gzip. + # + # gzip = ActiveSupport::Gzip.compress('compress me!') + # # => "\x1F\x8B\b\x00o\x8D\xCDO\x00\x03K\xCE\xCF-(J-.V\xC8MU\x04\x00R>n\x83\f\x00\x00\x00" + # + # ActiveSupport::Gzip.decompress(gzip) + # # => "compress me!" + module Gzip + class Stream < StringIO + def initialize(*) + super + set_encoding "BINARY" + end + def close; rewind; end + end + + # Decompresses a gzipped string. + def self.decompress(source) + Zlib::GzipReader.wrap(StringIO.new(source), &:read) + end + + # Compresses a string using gzip. + def self.compress(source, level = Zlib::DEFAULT_COMPRESSION, strategy = Zlib::DEFAULT_STRATEGY) + output = Stream.new + gz = Zlib::GzipWriter.new(output, level, strategy) + gz.write(source) + gz.close + output.string + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/hash_with_indifferent_access.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/hash_with_indifferent_access.rb new file mode 100644 index 00000000..4fa4e3b0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/hash_with_indifferent_access.rb @@ -0,0 +1,441 @@ +# frozen_string_literal: true + +require "active_support/core_ext/hash/keys" +require "active_support/core_ext/hash/reverse_merge" +require "active_support/core_ext/hash/except" +require "active_support/core_ext/hash/slice" + +module ActiveSupport + # = \Hash With Indifferent Access + # + # Implements a hash where keys :foo and "foo" are considered + # to be the same. + # + # rgb = ActiveSupport::HashWithIndifferentAccess.new + # + # rgb[:black] = '#000000' + # rgb[:black] # => '#000000' + # rgb['black'] # => '#000000' + # + # rgb['white'] = '#FFFFFF' + # rgb[:white] # => '#FFFFFF' + # rgb['white'] # => '#FFFFFF' + # + # Internally symbols are mapped to strings when used as keys in the entire + # writing interface (calling []=, merge, etc). This + # mapping belongs to the public interface. For example, given: + # + # hash = ActiveSupport::HashWithIndifferentAccess.new(a: 1) + # + # You are guaranteed that the key is returned as a string: + # + # hash.keys # => ["a"] + # + # Technically other types of keys are accepted: + # + # hash = ActiveSupport::HashWithIndifferentAccess.new(a: 1) + # hash[0] = 0 + # hash # => {"a"=>1, 0=>0} + # + # but this class is intended for use cases where strings or symbols are the + # expected keys and it is convenient to understand both as the same. For + # example the +params+ hash in Ruby on \Rails. + # + # Note that core extensions define Hash#with_indifferent_access: + # + # rgb = { black: '#000000', white: '#FFFFFF' }.with_indifferent_access + # + # which may be handy. + # + # To access this class outside of \Rails, require the core extension with: + # + # require "active_support/core_ext/hash/indifferent_access" + # + # which will, in turn, require this file. + class HashWithIndifferentAccess < Hash + # Returns +true+ so that Array#extract_options! finds members of + # this class. + def extractable_options? + true + end + + def with_indifferent_access + dup + end + + def nested_under_indifferent_access + self + end + + def initialize(constructor = nil) + if constructor.respond_to?(:to_hash) + super() + update(constructor) + + hash = constructor.is_a?(Hash) ? constructor : constructor.to_hash + self.default = hash.default if hash.default + self.default_proc = hash.default_proc if hash.default_proc + elsif constructor.nil? + super() + else + super(constructor) + end + end + + def self.[](*args) + new.merge!(Hash[*args]) + end + + alias_method :regular_writer, :[]= unless method_defined?(:regular_writer) + alias_method :regular_update, :update unless method_defined?(:regular_update) + + # Assigns a new value to the hash: + # + # hash = ActiveSupport::HashWithIndifferentAccess.new + # hash[:key] = 'value' + # + # This value can be later fetched using either +:key+ or 'key'. + def []=(key, value) + regular_writer(convert_key(key), convert_value(value, conversion: :assignment)) + end + + alias_method :store, :[]= + + # Updates the receiver in-place, merging in the hashes passed as arguments: + # + # hash_1 = ActiveSupport::HashWithIndifferentAccess.new + # hash_1[:key] = 'value' + # + # hash_2 = ActiveSupport::HashWithIndifferentAccess.new + # hash_2[:key] = 'New Value!' + # + # hash_1.update(hash_2) # => {"key"=>"New Value!"} + # + # hash = ActiveSupport::HashWithIndifferentAccess.new + # hash.update({ "a" => 1 }, { "b" => 2 }) # => { "a" => 1, "b" => 2 } + # + # The arguments can be either an + # +ActiveSupport::HashWithIndifferentAccess+ or a regular +Hash+. + # In either case the merge respects the semantics of indifferent access. + # + # If the argument is a regular hash with keys +:key+ and "key" only one + # of the values end up in the receiver, but which one is unspecified. + # + # When given a block, the value for duplicated keys will be determined + # by the result of invoking the block with the duplicated key, the value + # in the receiver, and the value in +other_hash+. The rules for duplicated + # keys follow the semantics of indifferent access: + # + # hash_1[:key] = 10 + # hash_2['key'] = 12 + # hash_1.update(hash_2) { |key, old, new| old + new } # => {"key"=>22} + def update(*other_hashes, &block) + if other_hashes.size == 1 + update_with_single_argument(other_hashes.first, block) + else + other_hashes.each do |other_hash| + update_with_single_argument(other_hash, block) + end + end + self + end + + alias_method :merge!, :update + + # Checks the hash for a key matching the argument passed in: + # + # hash = ActiveSupport::HashWithIndifferentAccess.new + # hash['key'] = 'value' + # hash.key?(:key) # => true + # hash.key?('key') # => true + def key?(key) + super(convert_key(key)) + end + + alias_method :include?, :key? + alias_method :has_key?, :key? + alias_method :member?, :key? + + # Same as Hash#[] where the key passed as argument can be + # either a string or a symbol: + # + # counters = ActiveSupport::HashWithIndifferentAccess.new + # counters[:foo] = 1 + # + # counters['foo'] # => 1 + # counters[:foo] # => 1 + # counters[:zoo] # => nil + def [](key) + super(convert_key(key)) + end + + # Same as Hash#assoc where the key passed as argument can be + # either a string or a symbol: + # + # counters = ActiveSupport::HashWithIndifferentAccess.new + # counters[:foo] = 1 + # + # counters.assoc('foo') # => ["foo", 1] + # counters.assoc(:foo) # => ["foo", 1] + # counters.assoc(:zoo) # => nil + def assoc(key) + super(convert_key(key)) + end + + # Same as Hash#fetch where the key passed as argument can be + # either a string or a symbol: + # + # counters = ActiveSupport::HashWithIndifferentAccess.new + # counters[:foo] = 1 + # + # counters.fetch('foo') # => 1 + # counters.fetch(:bar, 0) # => 0 + # counters.fetch(:bar) { |key| 0 } # => 0 + # counters.fetch(:zoo) # => KeyError: key not found: "zoo" + def fetch(key, *extras) + super(convert_key(key), *extras) + end + + # Same as Hash#dig where the key passed as argument can be + # either a string or a symbol: + # + # counters = ActiveSupport::HashWithIndifferentAccess.new + # counters[:foo] = { bar: 1 } + # + # counters.dig('foo', 'bar') # => 1 + # counters.dig(:foo, :bar) # => 1 + # counters.dig(:zoo) # => nil + def dig(*args) + args[0] = convert_key(args[0]) if args.size > 0 + super(*args) + end + + # Same as Hash#default where the key passed as argument can be + # either a string or a symbol: + # + # hash = ActiveSupport::HashWithIndifferentAccess.new(1) + # hash.default # => 1 + # + # hash = ActiveSupport::HashWithIndifferentAccess.new { |hash, key| key } + # hash.default # => nil + # hash.default('foo') # => 'foo' + # hash.default(:foo) # => 'foo' + def default(key = (no_key = true)) + if no_key + super() + else + super(convert_key(key)) + end + end + + # Returns an array of the values at the specified indices: + # + # hash = ActiveSupport::HashWithIndifferentAccess.new + # hash[:a] = 'x' + # hash[:b] = 'y' + # hash.values_at('a', 'b') # => ["x", "y"] + def values_at(*keys) + keys.map! { |key| convert_key(key) } + super + end + + # Returns an array of the values at the specified indices, but also + # raises an exception when one of the keys can't be found. + # + # hash = ActiveSupport::HashWithIndifferentAccess.new + # hash[:a] = 'x' + # hash[:b] = 'y' + # hash.fetch_values('a', 'b') # => ["x", "y"] + # hash.fetch_values('a', 'c') { |key| 'z' } # => ["x", "z"] + # hash.fetch_values('a', 'c') # => KeyError: key not found: "c" + def fetch_values(*indices, &block) + indices.map! { |key| convert_key(key) } + super + end + + # Returns a shallow copy of the hash. + # + # hash = ActiveSupport::HashWithIndifferentAccess.new({ a: { b: 'b' } }) + # dup = hash.dup + # dup[:a][:c] = 'c' + # + # hash[:a][:c] # => "c" + # dup[:a][:c] # => "c" + def dup + self.class.new(self).tap do |new_hash| + set_defaults(new_hash) + end + end + + # This method has the same semantics of +update+, except it does not + # modify the receiver but rather returns a new hash with indifferent + # access with the result of the merge. + def merge(*hashes, &block) + dup.update(*hashes, &block) + end + + # Like +merge+ but the other way around: Merges the receiver into the + # argument and returns a new hash with indifferent access as result: + # + # hash = ActiveSupport::HashWithIndifferentAccess.new + # hash['a'] = nil + # hash.reverse_merge(a: 0, b: 1) # => {"a"=>nil, "b"=>1} + def reverse_merge(other_hash) + super(self.class.new(other_hash)) + end + alias_method :with_defaults, :reverse_merge + + # Same semantics as +reverse_merge+ but modifies the receiver in-place. + def reverse_merge!(other_hash) + super(self.class.new(other_hash)) + end + alias_method :with_defaults!, :reverse_merge! + + # Replaces the contents of this hash with other_hash. + # + # h = { "a" => 100, "b" => 200 } + # h.replace({ "c" => 300, "d" => 400 }) # => {"c"=>300, "d"=>400} + def replace(other_hash) + super(self.class.new(other_hash)) + end + + # Removes the specified key from the hash. + def delete(key) + super(convert_key(key)) + end + + # Returns a hash with indifferent access that includes everything except given keys. + # hash = { a: "x", b: "y", c: 10 }.with_indifferent_access + # hash.except(:a, "b") # => {c: 10}.with_indifferent_access + # hash # => { a: "x", b: "y", c: 10 }.with_indifferent_access + def except(*keys) + dup.except!(*keys) + end + alias_method :without, :except + + undef :symbolize_keys! + undef :deep_symbolize_keys! + def symbolize_keys; to_hash.symbolize_keys! end + alias_method :to_options, :symbolize_keys + def deep_symbolize_keys; to_hash.deep_symbolize_keys! end + def to_options!; self end + + def select(*args, &block) + return to_enum(:select) unless block_given? + dup.tap { |hash| hash.select!(*args, &block) } + end + + def reject(*args, &block) + return to_enum(:reject) unless block_given? + dup.tap { |hash| hash.reject!(*args, &block) } + end + + def transform_values(&block) + return to_enum(:transform_values) unless block_given? + dup.tap { |hash| hash.transform_values!(&block) } + end + + NOT_GIVEN = Object.new # :nodoc: + + def transform_keys(hash = NOT_GIVEN, &block) + return to_enum(:transform_keys) if NOT_GIVEN.equal?(hash) && !block_given? + dup.tap { |h| h.transform_keys!(hash, &block) } + end + + def transform_keys!(hash = NOT_GIVEN, &block) + return to_enum(:transform_keys!) if NOT_GIVEN.equal?(hash) && !block_given? + + if hash.nil? + super + elsif NOT_GIVEN.equal?(hash) + keys.each { |key| self[yield(key)] = delete(key) } + elsif block_given? + keys.each { |key| self[hash[key] || yield(key)] = delete(key) } + else + keys.each { |key| self[hash[key] || key] = delete(key) } + end + + self + end + + def slice(*keys) + keys.map! { |key| convert_key(key) } + self.class.new(super) + end + + def slice!(*keys) + keys.map! { |key| convert_key(key) } + super + end + + def compact + dup.tap(&:compact!) + end + + # Convert to a regular hash with string keys. + def to_hash + copy = Hash[self] + copy.transform_values! { |v| convert_value_to_hash(v) } + set_defaults(copy) + copy + end + + def to_proc + proc { |key| self[key] } + end + + private + def convert_key(key) + Symbol === key ? key.name : key + end + + def convert_value(value, conversion: nil) + if value.is_a? Hash + value.nested_under_indifferent_access + elsif value.is_a?(Array) + if conversion != :assignment || value.frozen? + value = value.dup + end + value.map! { |e| convert_value(e, conversion: conversion) } + else + value + end + end + + def convert_value_to_hash(value) + if value.is_a? Hash + value.to_hash + elsif value.is_a?(Array) + value.map { |e| convert_value_to_hash(e) } + else + value + end + end + + + def set_defaults(target) + if default_proc + target.default_proc = default_proc.dup + else + target.default = default + end + end + + def update_with_single_argument(other_hash, block) + if other_hash.is_a? HashWithIndifferentAccess + regular_update(other_hash, &block) + else + other_hash.to_hash.each_pair do |key, value| + if block && key?(key) + value = block.call(convert_key(key), self[key], value) + end + regular_writer(convert_key(key), convert_value(value)) + end + end + end + end +end + +# :stopdoc: + +HashWithIndifferentAccess = ActiveSupport::HashWithIndifferentAccess diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/html_safe_translation.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/html_safe_translation.rb new file mode 100644 index 00000000..69ff23dd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/html_safe_translation.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +module ActiveSupport + module HtmlSafeTranslation # :nodoc: + extend self + + def translate(key, **options) + if html_safe_translation_key?(key) + html_safe_options = html_escape_translation_options(options) + + exception = false + + exception_handler = ->(*args) do + exception = true + I18n.exception_handler.call(*args) + end + + translation = I18n.translate(key, **html_safe_options, exception_handler: exception_handler) + + if exception + translation + else + html_safe_translation(translation) + end + else + I18n.translate(key, **options) + end + end + + def html_safe_translation_key?(key) + /(?:_|\b)html\z/.match?(key) + end + + private + def html_escape_translation_options(options) + options.each do |name, value| + unless i18n_option?(name) || (name == :count && value.is_a?(Numeric)) + options[name] = ERB::Util.html_escape(value.to_s) + end + end + end + + def i18n_option?(name) + (@i18n_option_names ||= I18n::RESERVED_KEYS.to_set).include?(name) + end + + + def html_safe_translation(translation) + if translation.respond_to?(:map) + translation.map { |element| element.respond_to?(:html_safe) ? element.html_safe : element } + else + translation.respond_to?(:html_safe) ? translation.html_safe : translation + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/i18n.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/i18n.rb new file mode 100644 index 00000000..f4f06d43 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/i18n.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require "active_support/core_ext/hash/deep_merge" +require "active_support/core_ext/hash/except" +require "active_support/core_ext/hash/slice" +begin + require "i18n" + require "i18n/backend/fallbacks" +rescue LoadError => e + warn "The i18n gem is not available. Please add it to your Gemfile and run bundle install" + raise e +end +require "active_support/lazy_load_hooks" + +ActiveSupport.run_load_hooks(:i18n) +I18n.load_path << File.expand_path("locale/en.yml", __dir__) +I18n.load_path << File.expand_path("locale/en.rb", __dir__) diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/i18n_railtie.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/i18n_railtie.rb new file mode 100644 index 00000000..de2ac078 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/i18n_railtie.rb @@ -0,0 +1,140 @@ +# frozen_string_literal: true + +require "active_support" +require "active_support/core_ext/array/wrap" + +# :enddoc: + +module I18n + class Railtie < Rails::Railtie + config.i18n = ActiveSupport::OrderedOptions.new + config.i18n.railties_load_path = [] + config.i18n.load_path = [] + config.i18n.fallbacks = ActiveSupport::OrderedOptions.new + + config.eager_load_namespaces << I18n + + # Make sure i18n is ready before eager loading, in case any eager loaded + # code needs it. + config.before_eager_load do |app| + I18n::Railtie.initialize_i18n(app) + end + + # i18n initialization needs to run after application initialization, since + # initializers may configure i18n. + # + # If the application eager loaded, this was done on before_eager_load. The + # hook is still OK, though, because initialize_i18n is idempotent. + config.after_initialize do |app| + I18n::Railtie.initialize_i18n(app) + end + + @i18n_inited = false + + # Setup i18n configuration. + def self.initialize_i18n(app) + return if @i18n_inited + + fallbacks = app.config.i18n.delete(:fallbacks) + + # Avoid issues with setting the default_locale by disabling available locales + # check while configuring. + enforce_available_locales = app.config.i18n.delete(:enforce_available_locales) + enforce_available_locales = I18n.enforce_available_locales if enforce_available_locales.nil? + I18n.enforce_available_locales = false + + reloadable_paths = [] + app.config.i18n.each do |setting, value| + case setting + when :railties_load_path + reloadable_paths = value + app.config.i18n.load_path.unshift(*value.flat_map(&:existent)) + when :load_path + I18n.load_path += value + when :raise_on_missing_translations + strict = value == :strict + setup_raise_on_missing_translations_config(app, strict) + else + I18n.public_send("#{setting}=", value) + end + end + + init_fallbacks(fallbacks) if fallbacks && validate_fallbacks(fallbacks) + + # Restore available locales check so it will take place from now on. + I18n.enforce_available_locales = enforce_available_locales + + if app.config.reloading_enabled? + directories = watched_dirs_with_extensions(reloadable_paths) + root_load_paths = I18n.load_path.select { |path| path.to_s.start_with?(Rails.root.to_s) } + reloader = app.config.file_watcher.new(root_load_paths, directories) do + I18n.load_path.delete_if { |path| path.to_s.start_with?(Rails.root.to_s) && !File.exist?(path) } + I18n.load_path |= reloadable_paths.flat_map(&:existent) + end + + app.reloaders << reloader + app.reloader.to_run do + reloader.execute_if_updated { require_unload_lock! } + end + end + + @i18n_inited = true + end + + def self.setup_raise_on_missing_translations_config(app, strict) + ActiveSupport.on_load(:action_view) do + ActionView::Helpers::TranslationHelper.raise_on_missing_translations = app.config.i18n.raise_on_missing_translations + end + + ActiveSupport.on_load(:active_model_translation) do + ActiveModel::Translation.raise_on_missing_translations = app.config.i18n.raise_on_missing_translations if strict + end + + if app.config.i18n.raise_on_missing_translations && + I18n.exception_handler.is_a?(I18n::ExceptionHandler) # Only override the i18n gem's default exception handler. + + I18n.exception_handler = ->(exception, *) { + exception = exception.to_exception if exception.is_a?(I18n::MissingTranslation) + raise exception + } + end + end + + def self.include_fallbacks_module + I18n.backend.class.include(I18n::Backend::Fallbacks) + end + + def self.init_fallbacks(fallbacks) + include_fallbacks_module + + args = \ + case fallbacks + when ActiveSupport::OrderedOptions + [*(fallbacks[:defaults] || []) << fallbacks[:map]].compact + when Hash, Array + Array.wrap(fallbacks) + else # TrueClass + [I18n.default_locale] + end + + I18n.fallbacks = I18n::Locale::Fallbacks.new(*args) + end + + def self.validate_fallbacks(fallbacks) + case fallbacks + when ActiveSupport::OrderedOptions + !fallbacks.empty? + when TrueClass, Array, Hash + true + else + raise "Unexpected fallback type #{fallbacks.inspect}" + end + end + + def self.watched_dirs_with_extensions(paths) + paths.each_with_object({}) do |path, result| + result[path.absolute_current] = path.extensions + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/inflections.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/inflections.rb new file mode 100644 index 00000000..baf1cb30 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/inflections.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +require "active_support/inflector/inflections" + +#-- +# Defines the standard inflection rules. These are the starting point for +# new projects and are not considered complete. The current set of inflection +# rules is frozen. This means, we do not change them to become more complete. +# This is a safety measure to keep existing applications from breaking. +#++ +module ActiveSupport + Inflector.inflections(:en) do |inflect| + inflect.plural(/$/, "s") + inflect.plural(/s$/i, "s") + inflect.plural(/^(ax|test)is$/i, '\1es') + inflect.plural(/(octop|vir)us$/i, '\1i') + inflect.plural(/(octop|vir)i$/i, '\1i') + inflect.plural(/(alias|status)$/i, '\1es') + inflect.plural(/(bu)s$/i, '\1ses') + inflect.plural(/(buffal|tomat)o$/i, '\1oes') + inflect.plural(/([ti])um$/i, '\1a') + inflect.plural(/([ti])a$/i, '\1a') + inflect.plural(/sis$/i, "ses") + inflect.plural(/(?:([^f])fe|([lr])f)$/i, '\1\2ves') + inflect.plural(/(hive)$/i, '\1s') + inflect.plural(/([^aeiouy]|qu)y$/i, '\1ies') + inflect.plural(/(x|ch|ss|sh)$/i, '\1es') + inflect.plural(/(matr|vert|ind)(?:ix|ex)$/i, '\1ices') + inflect.plural(/^(m|l)ouse$/i, '\1ice') + inflect.plural(/^(m|l)ice$/i, '\1ice') + inflect.plural(/^(ox)$/i, '\1en') + inflect.plural(/^(oxen)$/i, '\1') + inflect.plural(/(quiz)$/i, '\1zes') + + inflect.singular(/s$/i, "") + inflect.singular(/(ss)$/i, '\1') + inflect.singular(/(n)ews$/i, '\1ews') + inflect.singular(/([ti])a$/i, '\1um') + inflect.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$/i, '\1sis') + inflect.singular(/(^analy)(sis|ses)$/i, '\1sis') + inflect.singular(/([^f])ves$/i, '\1fe') + inflect.singular(/(hive)s$/i, '\1') + inflect.singular(/(tive)s$/i, '\1') + inflect.singular(/([lr])ves$/i, '\1f') + inflect.singular(/([^aeiouy]|qu)ies$/i, '\1y') + inflect.singular(/(s)eries$/i, '\1eries') + inflect.singular(/(m)ovies$/i, '\1ovie') + inflect.singular(/(x|ch|ss|sh)es$/i, '\1') + inflect.singular(/^(m|l)ice$/i, '\1ouse') + inflect.singular(/(bus)(es)?$/i, '\1') + inflect.singular(/(o)es$/i, '\1') + inflect.singular(/(shoe)s$/i, '\1') + inflect.singular(/(cris|test)(is|es)$/i, '\1is') + inflect.singular(/^(a)x[ie]s$/i, '\1xis') + inflect.singular(/(octop|vir)(us|i)$/i, '\1us') + inflect.singular(/(alias|status)(es)?$/i, '\1') + inflect.singular(/^(ox)en/i, '\1') + inflect.singular(/(vert|ind)ices$/i, '\1ex') + inflect.singular(/(matr)ices$/i, '\1ix') + inflect.singular(/(quiz)zes$/i, '\1') + inflect.singular(/(database)s$/i, '\1') + + inflect.irregular("person", "people") + inflect.irregular("man", "men") + inflect.irregular("child", "children") + inflect.irregular("sex", "sexes") + inflect.irregular("move", "moves") + inflect.irregular("zombie", "zombies") + + inflect.uncountable(%w(equipment information rice money species series fish sheep jeans police)) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/inflector.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/inflector.rb new file mode 100644 index 00000000..d77f04c9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/inflector.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +# in case active_support/inflector is required without the rest of active_support +require "active_support/inflector/inflections" +require "active_support/inflector/transliterate" +require "active_support/inflector/methods" + +require "active_support/inflections" +require "active_support/core_ext/string/inflections" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/inflector/inflections.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/inflector/inflections.rb new file mode 100644 index 00000000..5a1b64a5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/inflector/inflections.rb @@ -0,0 +1,273 @@ +# frozen_string_literal: true + +require "concurrent/map" +require "active_support/i18n" + +module ActiveSupport + module Inflector + extend self + + # = Active Support \Inflections + # + # A singleton instance of this class is yielded by Inflector.inflections, + # which can then be used to specify additional inflection rules. If passed + # an optional locale, rules for other languages can be specified. The + # default locale is :en. Only rules for English are provided. + # + # ActiveSupport::Inflector.inflections(:en) do |inflect| + # inflect.plural /^(ox)$/i, '\1\2en' + # inflect.singular /^(ox)en/i, '\1' + # + # inflect.irregular 'cactus', 'cacti' + # + # inflect.uncountable 'equipment' + # end + # + # New rules are added at the top. So in the example above, the irregular + # rule for cactus will now be the first of the pluralization and + # singularization rules that is runs. This guarantees that your rules run + # before any of the rules that may already have been loaded. + class Inflections + @__instance__ = Concurrent::Map.new + + class Uncountables < Array + def initialize + @regex_array = [] + super + end + + def delete(entry) + super entry + @regex_array.delete(to_regex(entry)) + end + + def <<(*word) + add(word) + end + + def add(words) + words = words.flatten.map(&:downcase) + concat(words) + @regex_array += words.map { |word| to_regex(word) } + self + end + + def uncountable?(str) + @regex_array.any? { |regex| regex.match? str } + end + + private + def to_regex(string) + /\b#{::Regexp.escape(string)}\Z/i + end + end + + def self.instance(locale = :en) + @__instance__[locale] ||= new + end + + def self.instance_or_fallback(locale) + I18n.fallbacks[locale].each do |k| + return @__instance__[k] if @__instance__.key?(k) + end + instance(locale) + end + + attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms + + attr_reader :acronyms_camelize_regex, :acronyms_underscore_regex # :nodoc: + + def initialize + @plurals, @singulars, @uncountables, @humans, @acronyms = [], [], Uncountables.new, [], {} + define_acronym_regex_patterns + end + + # Private, for the test suite. + def initialize_dup(orig) # :nodoc: + %w(plurals singulars uncountables humans acronyms).each do |scope| + instance_variable_set("@#{scope}", orig.public_send(scope).dup) + end + define_acronym_regex_patterns + end + + # Specifies a new acronym. An acronym must be specified as it will appear + # in a camelized string. An underscore string that contains the acronym + # will retain the acronym when passed to +camelize+, +humanize+, or + # +titleize+. A camelized string that contains the acronym will maintain + # the acronym when titleized or humanized, and will convert the acronym + # into a non-delimited single lowercase word when passed to +underscore+. + # + # acronym 'HTML' + # titleize 'html' # => 'HTML' + # camelize 'html' # => 'HTML' + # underscore 'MyHTML' # => 'my_html' + # + # The acronym, however, must occur as a delimited unit and not be part of + # another word for conversions to recognize it: + # + # acronym 'HTTP' + # camelize 'my_http_delimited' # => 'MyHTTPDelimited' + # camelize 'https' # => 'Https', not 'HTTPs' + # underscore 'HTTPS' # => 'http_s', not 'https' + # + # acronym 'HTTPS' + # camelize 'https' # => 'HTTPS' + # underscore 'HTTPS' # => 'https' + # + # Note: Acronyms that are passed to +pluralize+ will no longer be + # recognized, since the acronym will not occur as a delimited unit in the + # pluralized result. To work around this, you must specify the pluralized + # form as an acronym as well: + # + # acronym 'API' + # camelize(pluralize('api')) # => 'Apis' + # + # acronym 'APIs' + # camelize(pluralize('api')) # => 'APIs' + # + # +acronym+ may be used to specify any word that contains an acronym or + # otherwise needs to maintain a non-standard capitalization. The only + # restriction is that the word must begin with a capital letter. + # + # acronym 'RESTful' + # underscore 'RESTful' # => 'restful' + # underscore 'RESTfulController' # => 'restful_controller' + # titleize 'RESTfulController' # => 'RESTful Controller' + # camelize 'restful' # => 'RESTful' + # camelize 'restful_controller' # => 'RESTfulController' + # + # acronym 'McDonald' + # underscore 'McDonald' # => 'mcdonald' + # camelize 'mcdonald' # => 'McDonald' + def acronym(word) + @acronyms[word.downcase] = word + define_acronym_regex_patterns + end + + # Specifies a new pluralization rule and its replacement. The rule can + # either be a string or a regular expression. The replacement should + # always be a string that may include references to the matched data from + # the rule. + def plural(rule, replacement) + @uncountables.delete(rule) if rule.is_a?(String) + @uncountables.delete(replacement) + @plurals.prepend([rule, replacement]) + end + + # Specifies a new singularization rule and its replacement. The rule can + # either be a string or a regular expression. The replacement should + # always be a string that may include references to the matched data from + # the rule. + def singular(rule, replacement) + @uncountables.delete(rule) if rule.is_a?(String) + @uncountables.delete(replacement) + @singulars.prepend([rule, replacement]) + end + + # Specifies a new irregular that applies to both pluralization and + # singularization at the same time. This can only be used for strings, not + # regular expressions. You simply pass the irregular in singular and + # plural form. + # + # irregular 'cactus', 'cacti' + # irregular 'person', 'people' + def irregular(singular, plural) + @uncountables.delete(singular) + @uncountables.delete(plural) + + s0 = singular[0] + srest = singular[1..-1] + + p0 = plural[0] + prest = plural[1..-1] + + if s0.upcase == p0.upcase + plural(/(#{s0})#{srest}$/i, '\1' + prest) + plural(/(#{p0})#{prest}$/i, '\1' + prest) + + singular(/(#{s0})#{srest}$/i, '\1' + srest) + singular(/(#{p0})#{prest}$/i, '\1' + srest) + else + plural(/#{s0.upcase}(?i)#{srest}$/, p0.upcase + prest) + plural(/#{s0.downcase}(?i)#{srest}$/, p0.downcase + prest) + plural(/#{p0.upcase}(?i)#{prest}$/, p0.upcase + prest) + plural(/#{p0.downcase}(?i)#{prest}$/, p0.downcase + prest) + + singular(/#{s0.upcase}(?i)#{srest}$/, s0.upcase + srest) + singular(/#{s0.downcase}(?i)#{srest}$/, s0.downcase + srest) + singular(/#{p0.upcase}(?i)#{prest}$/, s0.upcase + srest) + singular(/#{p0.downcase}(?i)#{prest}$/, s0.downcase + srest) + end + end + + # Specifies words that are uncountable and should not be inflected. + # + # uncountable 'money' + # uncountable 'money', 'information' + # uncountable %w( money information rice ) + def uncountable(*words) + @uncountables.add(words) + end + + # Specifies a humanized form of a string by a regular expression rule or + # by a string mapping. When using a regular expression based replacement, + # the normal humanize formatting is called after the replacement. When a + # string is used, the human form should be specified as desired (example: + # 'The name', not 'the_name'). + # + # human /_cnt$/i, '\1_count' + # human 'legacy_col_person_name', 'Name' + def human(rule, replacement) + @humans.prepend([rule, replacement]) + end + + # Clears the loaded inflections within a given scope (default is + # :all). Give the scope as a symbol of the inflection type, the + # options are: :plurals, :singulars, :uncountables, + # :humans, :acronyms. + # + # clear :all + # clear :plurals + def clear(scope = :all) + case scope + when :all + clear(:acronyms) + clear(:plurals) + clear(:singulars) + clear(:uncountables) + clear(:humans) + when :acronyms + @acronyms = {} + define_acronym_regex_patterns + when :uncountables + @uncountables = Uncountables.new + when :plurals, :singulars, :humans + instance_variable_set "@#{scope}", [] + end + end + + private + def define_acronym_regex_patterns + @acronym_regex = @acronyms.empty? ? /(?=a)b/ : /#{@acronyms.values.join("|")}/ + @acronyms_camelize_regex = /^(?:#{@acronym_regex}(?=\b|[A-Z_])|\w)/ + @acronyms_underscore_regex = /(?:(?<=([A-Za-z\d]))|\b)(#{@acronym_regex})(?=\b|[^a-z])/ + end + end + + # Yields a singleton instance of Inflector::Inflections so you can specify + # additional inflector rules. If passed an optional locale, rules for other + # languages can be specified. If not specified, defaults to :en. + # Only rules for English are provided. + # + # ActiveSupport::Inflector.inflections(:en) do |inflect| + # inflect.uncountable 'rails' + # end + def inflections(locale = :en) + if block_given? + yield Inflections.instance(locale) + else + Inflections.instance_or_fallback(locale) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/inflector/methods.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/inflector/methods.rb new file mode 100644 index 00000000..e61afcf5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/inflector/methods.rb @@ -0,0 +1,387 @@ +# frozen_string_literal: true + +require "active_support/inflections" + +module ActiveSupport + # = Active Support \Inflector + # + # The Inflector transforms words from singular to plural, class names to table + # names, modularized class names to ones without, and class names to foreign + # keys. The default inflections for pluralization, singularization, and + # uncountable words are kept in inflections.rb. + # + # The \Rails core team has stated patches for the inflections library will not + # be accepted in order to avoid breaking legacy applications which may be + # relying on errant inflections. If you discover an incorrect inflection and + # require it for your application or wish to define rules for languages other + # than English, please correct or add them yourself (explained below). + module Inflector + extend self + + # Returns the plural form of the word in the string. + # + # If passed an optional +locale+ parameter, the word will be + # pluralized using rules defined for that language. By default, + # this parameter is set to :en. + # + # pluralize('post') # => "posts" + # pluralize('octopus') # => "octopi" + # pluralize('sheep') # => "sheep" + # pluralize('words') # => "words" + # pluralize('CamelOctopus') # => "CamelOctopi" + # pluralize('ley', :es) # => "leyes" + def pluralize(word, locale = :en) + apply_inflections(word, inflections(locale).plurals, locale) + end + + # The reverse of #pluralize, returns the singular form of a word in a + # string. + # + # If passed an optional +locale+ parameter, the word will be + # singularized using rules defined for that language. By default, + # this parameter is set to :en. + # + # singularize('posts') # => "post" + # singularize('octopi') # => "octopus" + # singularize('sheep') # => "sheep" + # singularize('word') # => "word" + # singularize('CamelOctopi') # => "CamelOctopus" + # singularize('leyes', :es) # => "ley" + def singularize(word, locale = :en) + apply_inflections(word, inflections(locale).singulars, locale) + end + + # Converts strings to UpperCamelCase. + # If the +uppercase_first_letter+ parameter is set to false, then produces + # lowerCamelCase. + # + # Also converts '/' to '::' which is useful for converting + # paths to namespaces. + # + # camelize('active_model') # => "ActiveModel" + # camelize('active_model', false) # => "activeModel" + # camelize('active_model/errors') # => "ActiveModel::Errors" + # camelize('active_model/errors', false) # => "activeModel::Errors" + # + # As a rule of thumb you can think of +camelize+ as the inverse of + # #underscore, though there are cases where that does not hold: + # + # camelize(underscore('SSLError')) # => "SslError" + def camelize(term, uppercase_first_letter = true) + string = term.to_s + # String#camelize takes a symbol (:upper or :lower), so here we also support :lower to keep the methods consistent. + if !uppercase_first_letter || uppercase_first_letter == :lower + string = string.sub(inflections.acronyms_camelize_regex) { |match| match.downcase! || match } + elsif string.match?(/\A[a-z\d]*\z/) + return inflections.acronyms[string]&.dup || string.capitalize + else + string = string.sub(/^[a-z\d]*/) { |match| inflections.acronyms[match] || match.capitalize! || match } + end + string.gsub!(/(?:_|(\/))([a-z\d]*)/i) do + word = $2 + substituted = inflections.acronyms[word] || word.capitalize! || word + $1 ? "::#{substituted}" : substituted + end + string + end + + # Makes an underscored, lowercase form from the expression in the string. + # + # Changes '::' to '/' to convert namespaces to paths. + # + # underscore('ActiveModel') # => "active_model" + # underscore('ActiveModel::Errors') # => "active_model/errors" + # + # As a rule of thumb you can think of +underscore+ as the inverse of + # #camelize, though there are cases where that does not hold: + # + # camelize(underscore('SSLError')) # => "SslError" + def underscore(camel_cased_word) + return camel_cased_word.to_s.dup unless /[A-Z-]|::/.match?(camel_cased_word) + word = camel_cased_word.to_s.gsub("::", "/") + word.gsub!(inflections.acronyms_underscore_regex) { "#{$1 && '_' }#{$2.downcase}" } + word.gsub!(/(?<=[A-Z])(?=[A-Z][a-z])|(?<=[a-z\d])(?=[A-Z])/, "_") + word.tr!("-", "_") + word.downcase! + word + end + + # Tweaks an attribute name for display to end users. + # + # Specifically, performs these transformations: + # + # * Applies human inflection rules to the argument. + # * Deletes leading underscores, if any. + # * Removes an "_id" suffix if present. + # * Replaces underscores with spaces, if any. + # * Downcases all words except acronyms. + # * Capitalizes the first word. + # The capitalization of the first word can be turned off by setting the + # +:capitalize+ option to false (default is true). + # + # The trailing '_id' can be kept and capitalized by setting the + # optional parameter +keep_id_suffix+ to true (default is false). + # + # humanize('employee_salary') # => "Employee salary" + # humanize('author_id') # => "Author" + # humanize('author_id', capitalize: false) # => "author" + # humanize('_id') # => "Id" + # humanize('author_id', keep_id_suffix: true) # => "Author id" + # + # If "SSL" was defined to be an acronym: + # + # humanize('ssl_error') # => "SSL error" + # + def humanize(lower_case_and_underscored_word, capitalize: true, keep_id_suffix: false) + result = lower_case_and_underscored_word.to_s.dup + + inflections.humans.each { |(rule, replacement)| break if result.sub!(rule, replacement) } + + result.tr!("_", " ") + result.lstrip! + if !keep_id_suffix && lower_case_and_underscored_word&.end_with?("_id") + result.delete_suffix!(" id") + end + + result.gsub!(/([a-z\d]+)/i) do |match| + match.downcase! + inflections.acronyms[match] || match + end + + if capitalize + result.sub!(/\A\w/) do |match| + match.upcase! + match + end + end + + result + end + + # Converts the first character in the string to uppercase. + # + # upcase_first('what a Lovely Day') # => "What a Lovely Day" + # upcase_first('w') # => "W" + # upcase_first('') # => "" + def upcase_first(string) + string.length > 0 ? string[0].upcase.concat(string[1..-1]) : +"" + end + + # Converts the first character in the string to lowercase. + # + # downcase_first('If they enjoyed The Matrix') # => "if they enjoyed The Matrix" + # downcase_first('I') # => "i" + # downcase_first('') # => "" + def downcase_first(string) + string.length > 0 ? string[0].downcase.concat(string[1..-1]) : +"" + end + + # Capitalizes all the words and replaces some characters in the string to + # create a nicer looking title. +titleize+ is meant for creating pretty + # output. It is not used in the \Rails internals. + # + # The trailing '_id','Id'.. can be kept and capitalized by setting the + # optional parameter +keep_id_suffix+ to true. + # By default, this parameter is false. + # + # titleize('man from the boondocks') # => "Man From The Boondocks" + # titleize('x-men: the last stand') # => "X Men: The Last Stand" + # titleize('TheManWithoutAPast') # => "The Man Without A Past" + # titleize('raiders_of_the_lost_ark') # => "Raiders Of The Lost Ark" + # titleize('string_ending_with_id', keep_id_suffix: true) # => "String Ending With Id" + def titleize(word, keep_id_suffix: false) + humanize(underscore(word), keep_id_suffix: keep_id_suffix).gsub(/\b(? "raw_scaled_scorers" + # tableize('ham_and_egg') # => "ham_and_eggs" + # tableize('fancyCategory') # => "fancy_categories" + def tableize(class_name) + pluralize(underscore(class_name)) + end + + # Creates a class name from a plural table name like \Rails does for table + # names to models. Note that this returns a string and not a Class. (To + # convert to an actual class follow +classify+ with #constantize.) + # + # classify('ham_and_eggs') # => "HamAndEgg" + # classify('posts') # => "Post" + # + # Singular names are not handled correctly: + # + # classify('calculus') # => "Calculu" + def classify(table_name) + # strip out any leading schema name + camelize(singularize(table_name.to_s.sub(/.*\./, ""))) + end + + # Replaces underscores with dashes in the string. + # + # dasherize('puni_puni') # => "puni-puni" + def dasherize(underscored_word) + underscored_word.tr("_", "-") + end + + # Removes the module part from the expression in the string. + # + # demodulize('ActiveSupport::Inflector::Inflections') # => "Inflections" + # demodulize('Inflections') # => "Inflections" + # demodulize('::Inflections') # => "Inflections" + # demodulize('') # => "" + # + # See also #deconstantize. + def demodulize(path) + path = path.to_s + if i = path.rindex("::") + path[(i + 2), path.length] + else + path + end + end + + # Removes the rightmost segment from the constant expression in the string. + # + # deconstantize('Net::HTTP') # => "Net" + # deconstantize('::Net::HTTP') # => "::Net" + # deconstantize('String') # => "" + # deconstantize('::String') # => "" + # deconstantize('') # => "" + # + # See also #demodulize. + def deconstantize(path) + path.to_s[0, path.rindex("::") || 0] # implementation based on the one in facets' Module#spacename + end + + # Creates a foreign key name from a class name. + # +separate_class_name_and_id_with_underscore+ sets whether + # the method should put '_' between the name and 'id'. + # + # foreign_key('Message') # => "message_id" + # foreign_key('Message', false) # => "messageid" + # foreign_key('Admin::Post') # => "post_id" + def foreign_key(class_name, separate_class_name_and_id_with_underscore = true) + underscore(demodulize(class_name)) + (separate_class_name_and_id_with_underscore ? "_id" : "id") + end + + # Tries to find a constant with the name specified in the argument string. + # + # constantize('Module') # => Module + # constantize('Foo::Bar') # => Foo::Bar + # + # The name is assumed to be the one of a top-level constant, no matter + # whether it starts with "::" or not. No lexical context is taken into + # account: + # + # C = 'outside' + # module M + # C = 'inside' + # C # => 'inside' + # constantize('C') # => 'outside', same as ::C + # end + # + # NameError is raised when the name is not in CamelCase or the constant is + # unknown. + def constantize(camel_cased_word) + Object.const_get(camel_cased_word) + end + + # Tries to find a constant with the name specified in the argument string. + # + # safe_constantize('Module') # => Module + # safe_constantize('Foo::Bar') # => Foo::Bar + # + # The name is assumed to be the one of a top-level constant, no matter + # whether it starts with "::" or not. No lexical context is taken into + # account: + # + # C = 'outside' + # module M + # C = 'inside' + # C # => 'inside' + # safe_constantize('C') # => 'outside', same as ::C + # end + # + # +nil+ is returned when the name is not in CamelCase or the constant (or + # part of it) is unknown. + # + # safe_constantize('blargle') # => nil + # safe_constantize('UnknownModule') # => nil + # safe_constantize('UnknownModule::Foo::Bar') # => nil + def safe_constantize(camel_cased_word) + constantize(camel_cased_word) + rescue NameError => e + raise if e.name && !(camel_cased_word.to_s.split("::").include?(e.name.to_s) || + e.name.to_s == camel_cased_word.to_s) + rescue LoadError => e + message = e.respond_to?(:original_message) ? e.original_message : e.message + raise unless /Unable to autoload constant #{const_regexp(camel_cased_word)}/.match?(message) + end + + # Returns the suffix that should be added to a number to denote the position + # in an ordered sequence such as 1st, 2nd, 3rd, 4th. + # + # ordinal(1) # => "st" + # ordinal(2) # => "nd" + # ordinal(1002) # => "nd" + # ordinal(1003) # => "rd" + # ordinal(-11) # => "th" + # ordinal(-1021) # => "st" + def ordinal(number) + I18n.translate("number.nth.ordinals", number: number) + end + + # Turns a number into an ordinal string used to denote the position in an + # ordered sequence such as 1st, 2nd, 3rd, 4th. + # + # ordinalize(1) # => "1st" + # ordinalize(2) # => "2nd" + # ordinalize(1002) # => "1002nd" + # ordinalize(1003) # => "1003rd" + # ordinalize(-11) # => "-11th" + # ordinalize(-1021) # => "-1021st" + def ordinalize(number) + I18n.translate("number.nth.ordinalized", number: number) + end + + private + # Mounts a regular expression, returned as a string to ease interpolation, + # that will match part by part the given constant. + # + # const_regexp("Foo::Bar::Baz") # => "Foo(::Bar(::Baz)?)?" + # const_regexp("::") # => "::" + def const_regexp(camel_cased_word) + parts = camel_cased_word.split("::") + + return Regexp.escape(camel_cased_word) if parts.empty? + + last = parts.pop + + parts.reverse!.inject(last) do |acc, part| + part.empty? ? acc : "#{part}(::#{acc})?" + end + end + + # Applies inflection rules for +singularize+ and +pluralize+. + # + # If passed an optional +locale+ parameter, the uncountables will be + # found for that locale. + # + # apply_inflections('post', inflections.plurals, :en) # => "posts" + # apply_inflections('posts', inflections.singulars, :en) # => "post" + def apply_inflections(word, rules, locale = :en) + result = word.to_s.dup + + if word.empty? || inflections(locale).uncountables.uncountable?(result) + result + else + rules.each { |(rule, replacement)| break if result.sub!(rule, replacement) } + result + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/inflector/transliterate.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/inflector/transliterate.rb new file mode 100644 index 00000000..926d32ee --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/inflector/transliterate.rb @@ -0,0 +1,149 @@ +# frozen_string_literal: true + +require "active_support/core_ext/string/multibyte" +require "active_support/i18n" + +module ActiveSupport + module Inflector + ALLOWED_ENCODINGS_FOR_TRANSLITERATE = [Encoding::UTF_8, Encoding::US_ASCII, Encoding::GB18030].freeze + + # Replaces non-ASCII characters with an ASCII approximation, or if none + # exists, a replacement character which defaults to "?". + # + # transliterate('Ærøskøbing') + # # => "AEroskobing" + # + # Default approximations are provided for Western/Latin characters, + # e.g, "ø", "ñ", "é", "ß", etc. + # + # This method is I18n aware, so you can set up custom approximations for a + # locale. This can be useful, for example, to transliterate German's "ü" + # and "ö" to "ue" and "oe", or to add support for transliterating Russian + # to ASCII. + # + # In order to make your custom transliterations available, you must set + # them as the i18n.transliterate.rule i18n key: + # + # # Store the transliterations in locales/de.yml + # i18n: + # transliterate: + # rule: + # ü: "ue" + # ö: "oe" + # + # # Or set them using Ruby + # I18n.backend.store_translations(:de, i18n: { + # transliterate: { + # rule: { + # 'ü' => 'ue', + # 'ö' => 'oe' + # } + # } + # }) + # + # The value for i18n.transliterate.rule can be a simple Hash that + # maps characters to ASCII approximations as shown above, or, for more + # complex requirements, a Proc: + # + # I18n.backend.store_translations(:de, i18n: { + # transliterate: { + # rule: ->(string) { MyTransliterator.transliterate(string) } + # } + # }) + # + # Now you can have different transliterations for each locale: + # + # transliterate('Jürgen', locale: :en) + # # => "Jurgen" + # + # transliterate('Jürgen', locale: :de) + # # => "Juergen" + # + # Transliteration is restricted to UTF-8, US-ASCII, and GB18030 strings. + # Other encodings will raise an ArgumentError. + def transliterate(string, replacement = "?", locale: nil) + raise ArgumentError, "Can only transliterate strings. Received #{string.class.name}" unless string.is_a?(String) + raise ArgumentError, "Cannot transliterate strings with #{string.encoding} encoding" unless ALLOWED_ENCODINGS_FOR_TRANSLITERATE.include?(string.encoding) + + return string.dup if string.ascii_only? + string = string.dup if string.frozen? + + input_encoding = string.encoding + + # US-ASCII is a subset of UTF-8 so we'll force encoding as UTF-8 if + # US-ASCII is given. This way we can let tidy_bytes handle the string + # in the same way as we do for UTF-8 + string.force_encoding(Encoding::UTF_8) if string.encoding == Encoding::US_ASCII + + # GB18030 is Unicode compatible but is not a direct mapping so needs to be + # transcoded. Using invalid/undef :replace will result in loss of data in + # the event of invalid characters, but since tidy_bytes will replace + # invalid/undef with a "?" we're safe to do the same beforehand + string.encode!(Encoding::UTF_8, invalid: :replace, undef: :replace) if string.encoding == Encoding::GB18030 + + transliterated = I18n.transliterate( + ActiveSupport::Multibyte::Unicode.tidy_bytes(string).unicode_normalize(:nfc), + replacement: replacement, + locale: locale + ) + + # Restore the string encoding of the input if it was not UTF-8. + # Apply invalid/undef :replace as tidy_bytes does + transliterated.encode!(input_encoding, invalid: :replace, undef: :replace) if input_encoding != transliterated.encoding + + transliterated + end + + # Replaces special characters in a string so that it may be used as part of + # a 'pretty' URL. + # + # parameterize("Donald E. Knuth") # => "donald-e-knuth" + # parameterize("^très|Jolie-- ") # => "tres-jolie" + # + # To use a custom separator, override the +separator+ argument. + # + # parameterize("Donald E. Knuth", separator: '_') # => "donald_e_knuth" + # parameterize("^très|Jolie__ ", separator: '_') # => "tres_jolie" + # + # To preserve the case of the characters in a string, use the +preserve_case+ argument. + # + # parameterize("Donald E. Knuth", preserve_case: true) # => "Donald-E-Knuth" + # parameterize("^très|Jolie-- ", preserve_case: true) # => "tres-Jolie" + # + # It preserves dashes and underscores unless they are used as separators: + # + # parameterize("^très|Jolie__ ") # => "tres-jolie__" + # parameterize("^très|Jolie-- ", separator: "_") # => "tres_jolie--" + # parameterize("^très_Jolie-- ", separator: ".") # => "tres_jolie--" + # + # If the optional parameter +locale+ is specified, + # the word will be parameterized as a word of that language. + # By default, this parameter is set to nil and it will use + # the configured I18n.locale. + def parameterize(string, separator: "-", preserve_case: false, locale: nil) + # Replace accented chars with their ASCII equivalents. + parameterized_string = transliterate(string, locale: locale) + + # Turn unwanted chars into the separator. + parameterized_string.gsub!(/[^a-z0-9\-_]+/i, separator) + + unless separator.nil? || separator.empty? + if separator == "-" + re_duplicate_separator = /-{2,}/ + re_leading_trailing_separator = /^-|-$/i + else + re_sep = Regexp.escape(separator) + re_duplicate_separator = /#{re_sep}{2,}/ + re_leading_trailing_separator = /^#{re_sep}|#{re_sep}$/i + end + # No more than one of the separator in a row. + parameterized_string.gsub!(re_duplicate_separator, separator) + # Remove leading/trailing separator. + parameterized_string.gsub!(re_leading_trailing_separator, "") + end + + parameterized_string.downcase! unless preserve_case + parameterized_string + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/isolated_execution_state.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/isolated_execution_state.rb new file mode 100644 index 00000000..082bdb83 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/isolated_execution_state.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +module ActiveSupport + module IsolatedExecutionState # :nodoc: + @isolation_level = nil + + Thread.attr_accessor :active_support_execution_state + Fiber.attr_accessor :active_support_execution_state + + class << self + attr_reader :isolation_level, :scope + + def isolation_level=(level) + return if level == @isolation_level + + unless %i(thread fiber).include?(level) + raise ArgumentError, "isolation_level must be `:thread` or `:fiber`, got: `#{level.inspect}`" + end + + clear if @isolation_level + + @scope = + case level + when :thread; Thread + when :fiber; Fiber + end + + @isolation_level = level + end + + def unique_id + self[:__id__] ||= Object.new + end + + def [](key) + state[key] + end + + def []=(key, value) + state[key] = value + end + + def key?(key) + state.key?(key) + end + + def delete(key) + state.delete(key) + end + + def clear + state.clear + end + + def context + scope.current + end + + def share_with(other) + # Action Controller streaming spawns a new thread and copy thread locals. + # We do the same here for backward compatibility, but this is very much a hack + # and streaming should be rethought. + context.active_support_execution_state = other.active_support_execution_state.dup + end + + private + def state + context.active_support_execution_state ||= {} + end + end + + self.isolation_level = :thread + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/json.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/json.rb new file mode 100644 index 00000000..d7887175 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/json.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +require "active_support/json/decoding" +require "active_support/json/encoding" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/json/decoding.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/json/decoding.rb new file mode 100644 index 00000000..78016bdd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/json/decoding.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true + +require "active_support/core_ext/module/attribute_accessors" +require "active_support/core_ext/module/delegation" +require "json" + +module ActiveSupport + # Look for and parse JSON strings that look like ISO 8601 times. + mattr_accessor :parse_json_times + + module JSON + # matches YAML-formatted dates + DATE_REGEX = /\A\d{4}-\d{2}-\d{2}\z/ + DATETIME_REGEX = /\A(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[T \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?)?)\z/ + + class << self + # Parses a JSON string (JavaScript Object Notation) into a hash. + # See http://www.json.org for more info. + # + # ActiveSupport::JSON.decode("{\"team\":\"rails\",\"players\":\"36\"}") + # => {"team" => "rails", "players" => "36"} + def decode(json) + data = ::JSON.parse(json, quirks_mode: true) + + if ActiveSupport.parse_json_times + convert_dates_from(data) + else + data + end + end + alias_method :load, :decode + + # Returns the class of the error that will be raised when there is an + # error in decoding JSON. Using this method means you won't directly + # depend on the ActiveSupport's JSON implementation, in case it changes + # in the future. + # + # begin + # obj = ActiveSupport::JSON.decode(some_string) + # rescue ActiveSupport::JSON.parse_error + # Rails.logger.warn("Attempted to decode invalid JSON: #{some_string}") + # end + def parse_error + ::JSON::ParserError + end + + private + def convert_dates_from(data) + case data + when nil + nil + when DATE_REGEX + begin + Date.parse(data) + rescue ArgumentError + data + end + when DATETIME_REGEX + begin + Time.zone.parse(data) + rescue ArgumentError + data + end + when Array + data.map! { |d| convert_dates_from(d) } + when Hash + data.transform_values! do |value| + convert_dates_from(value) + end + else + data + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/json/encoding.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/json/encoding.rb new file mode 100644 index 00000000..832be756 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/json/encoding.rb @@ -0,0 +1,138 @@ +# frozen_string_literal: true + +require "active_support/core_ext/object/json" +require "active_support/core_ext/module/delegation" + +module ActiveSupport + class << self + delegate :use_standard_json_time_format, :use_standard_json_time_format=, + :time_precision, :time_precision=, + :escape_html_entities_in_json, :escape_html_entities_in_json=, + :json_encoder, :json_encoder=, + to: :'ActiveSupport::JSON::Encoding' + end + + module JSON + class << self + # Dumps objects in JSON (JavaScript Object Notation). + # See http://www.json.org for more info. + # + # ActiveSupport::JSON.encode({ team: 'rails', players: '36' }) + # # => "{\"team\":\"rails\",\"players\":\"36\"}" + # + # Generates JSON that is safe to include in JavaScript as it escapes + # U+2028 (Line Separator) and U+2029 (Paragraph Separator): + # + # ActiveSupport::JSON.encode({ key: "\u2028" }) + # # => "{\"key\":\"\\u2028\"}" + # + # By default, it also generates JSON that is safe to include in HTML, as + # it escapes <, >, and &: + # + # ActiveSupport::JSON.encode({ key: "<>&" }) + # # => "{\"key\":\"\\u003c\\u003e\\u0026\"}" + # + # This can be changed with the +escape_html_entities+ option, or the + # global escape_html_entities_in_json configuration option. + # + # ActiveSupport::JSON.encode({ key: "<>&" }, escape_html_entities: false) + # # => "{\"key\":\"<>&\"}" + def encode(value, options = nil) + Encoding.json_encoder.new(options).encode(value) + end + alias_method :dump, :encode + end + + module Encoding # :nodoc: + class JSONGemEncoder # :nodoc: + attr_reader :options + + def initialize(options = nil) + @options = options || {} + end + + # Encode the given object into a JSON string + def encode(value) + unless options.empty? + value = value.as_json(options.dup.freeze) + end + json = stringify(jsonify(value)) + + # Rails does more escaping than the JSON gem natively does (we + # escape \u2028 and \u2029 and optionally >, <, & to work around + # certain browser problems). + if @options.fetch(:escape_html_entities, Encoding.escape_html_entities_in_json) + json.gsub!(">", '\u003e') + json.gsub!("<", '\u003c') + json.gsub!("&", '\u0026') + end + json.gsub!("\u2028", '\u2028') + json.gsub!("\u2029", '\u2029') + json + end + + private + # Convert an object into a "JSON-ready" representation composed of + # primitives like Hash, Array, String, Symbol, Numeric, + # and +true+/+false+/+nil+. + # Recursively calls #as_json to the object to recursively build a + # fully JSON-ready object. + # + # This allows developers to implement #as_json without having to + # worry about what base types of objects they are allowed to return + # or having to remember to call #as_json recursively. + # + # Note: the +options+ hash passed to +object.to_json+ is only passed + # to +object.as_json+, not any of this method's recursive +#as_json+ + # calls. + def jsonify(value) + case value + when String, Integer, Symbol, nil, true, false + value + when Numeric + value.as_json + when Hash + result = {} + value.each do |k, v| + k = k.to_s unless Symbol === k || String === k + result[k] = jsonify(v) + end + result + when Array + value.map { |v| jsonify(v) } + else + jsonify value.as_json + end + end + + # Encode a "jsonified" Ruby data structure using the JSON gem + def stringify(jsonified) + ::JSON.generate(jsonified, quirks_mode: true, max_nesting: false) + end + end + + class << self + # If true, use ISO 8601 format for dates and times. Otherwise, fall back + # to the Active Support legacy format. + attr_accessor :use_standard_json_time_format + + # If true, encode >, <, & as escaped unicode sequences (e.g. > as \u003e) + # as a safety measure. + attr_accessor :escape_html_entities_in_json + + # Sets the precision of encoded time values. + # Defaults to 3 (equivalent to millisecond precision) + attr_accessor :time_precision + + # Sets the encoder used by \Rails to encode Ruby objects into JSON strings + # in +Object#to_json+ and +ActiveSupport::JSON.encode+. + attr_accessor :json_encoder + end + + self.use_standard_json_time_format = true + self.escape_html_entities_in_json = true + self.json_encoder = JSONGemEncoder + self.time_precision = 3 + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/key_generator.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/key_generator.rb new file mode 100644 index 00000000..8e75fba2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/key_generator.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +require "concurrent/map" +require "openssl" + +module ActiveSupport + # = Key Generator + # + # KeyGenerator is a simple wrapper around OpenSSL's implementation of PBKDF2. + # It can be used to derive a number of keys for various purposes from a given secret. + # This lets \Rails applications have a single secure secret, but avoid reusing that + # key in multiple incompatible contexts. + class KeyGenerator + class << self + def hash_digest_class=(klass) + if klass.kind_of?(Class) && klass < OpenSSL::Digest + @hash_digest_class = klass + else + raise ArgumentError, "#{klass} is expected to be an OpenSSL::Digest subclass" + end + end + + def hash_digest_class + @hash_digest_class ||= OpenSSL::Digest::SHA1 + end + end + + def initialize(secret, options = {}) + @secret = secret + # The default iterations are higher than required for our key derivation uses + # on the off chance someone uses this for password storage + @iterations = options[:iterations] || 2**16 + # Also allow configuration here so people can use this to build a rotation + # scheme when switching the digest class. + @hash_digest_class = options[:hash_digest_class] || self.class.hash_digest_class + end + + # Returns a derived key suitable for use. The default +key_size+ is chosen + # to be compatible with the default settings of ActiveSupport::MessageVerifier. + # i.e. OpenSSL::Digest::SHA1#block_length + def generate_key(salt, key_size = 64) + OpenSSL::PKCS5.pbkdf2_hmac(@secret, salt, @iterations, key_size, @hash_digest_class.new) + end + + def inspect # :nodoc: + "#<#{self.class.name}:#{'%#016x' % (object_id << 1)}>" + end + end + + # = Caching Key Generator + # + # CachingKeyGenerator is a wrapper around KeyGenerator which allows users to avoid + # re-executing the key generation process when it's called using the same +salt+ and + # +key_size+. + class CachingKeyGenerator + def initialize(key_generator) + @key_generator = key_generator + @cache_keys = Concurrent::Map.new + end + + # Returns a derived key suitable for use. + def generate_key(*args) + @cache_keys[args.join("|")] ||= @key_generator.generate_key(*args) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/lazy_load_hooks.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/lazy_load_hooks.rb new file mode 100644 index 00000000..39907156 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/lazy_load_hooks.rb @@ -0,0 +1,107 @@ +# frozen_string_literal: true + +module ActiveSupport + # = Lazy Load Hooks + # + # LazyLoadHooks allows \Rails to lazily load a lot of components and thus + # making the app boot faster. Because of this feature now there is no need to + # require +ActiveRecord::Base+ at boot time purely to apply + # configuration. Instead a hook is registered that applies configuration once + # +ActiveRecord::Base+ is loaded. Here +ActiveRecord::Base+ is + # used as example but this feature can be applied elsewhere too. + # + # Here is an example where on_load method is called to register a hook. + # + # initializer 'active_record.initialize_timezone' do + # ActiveSupport.on_load(:active_record) do + # self.time_zone_aware_attributes = true + # self.default_timezone = :utc + # end + # end + # + # When the entirety of +ActiveRecord::Base+ has been + # evaluated then run_load_hooks is invoked. The very last line of + # +ActiveRecord::Base+ is: + # + # ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base) + # + # run_load_hooks will then execute all the hooks that were registered + # with the on_load method. In the case of the above example, it will + # execute the block of code that is in the +initializer+. + # + # Registering a hook that has already run results in that hook executing + # immediately. This allows hooks to be nested for code that relies on + # multiple lazily loaded components: + # + # initializer "action_text.renderer" do + # ActiveSupport.on_load(:action_controller_base) do + # ActiveSupport.on_load(:action_text_content) do + # self.default_renderer = Class.new(ActionController::Base).renderer + # end + # end + # end + module LazyLoadHooks + def self.extended(base) # :nodoc: + base.class_eval do + @load_hooks = Hash.new { |h, k| h[k] = [] } + @loaded = Hash.new { |h, k| h[k] = [] } + @run_once = Hash.new { |h, k| h[k] = [] } + end + end + + # Declares a block that will be executed when a \Rails component is fully + # loaded. If the component has already loaded, the block is executed + # immediately. + # + # Options: + # + # * :yield - Yields the object that run_load_hooks to +block+. + # * :run_once - Given +block+ will run only once. + def on_load(name, options = {}, &block) + @loaded[name].each do |base| + execute_hook(name, base, options, block) + end + + @load_hooks[name] << [block, options] + end + + # Executes all blocks registered to +name+ via on_load, using +base+ as the + # evaluation context. + # + # ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base) + # + # In the case of the above example, it will execute all hooks registered + # for +:active_record+ within the class +ActiveRecord::Base+. + def run_load_hooks(name, base = Object) + @loaded[name] << base + @load_hooks[name].each do |hook, options| + execute_hook(name, base, options, hook) + end + end + + private + def with_execution_control(name, block, once) + unless @run_once[name].include?(block) + @run_once[name] << block if once + + yield + end + end + + def execute_hook(name, base, options, block) + with_execution_control(name, block, options[:run_once]) do + if options[:yield] + block.call(base) + else + if base.is_a?(Module) + base.class_eval(&block) + else + base.instance_eval(&block) + end + end + end + end + end + + extend LazyLoadHooks +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/locale/en.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/locale/en.rb new file mode 100644 index 00000000..29eb9dec --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/locale/en.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +{ + en: { + number: { + nth: { + ordinals: lambda do |_key, options| + number = options[:number] + case number + when 1; "st" + when 2; "nd" + when 3; "rd" + when 4, 5, 6, 7, 8, 9, 10, 11, 12, 13; "th" + else + num_modulo = number.to_i.abs % 100 + num_modulo %= 10 if num_modulo > 13 + case num_modulo + when 1; "st" + when 2; "nd" + when 3; "rd" + else "th" + end + end + end, + + ordinalized: lambda do |_key, options| + number = options[:number] + "#{number}#{ActiveSupport::Inflector.ordinal(number)}" + end + } + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/locale/en.yml b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/locale/en.yml new file mode 100644 index 00000000..52134208 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/locale/en.yml @@ -0,0 +1,141 @@ +en: + date: + formats: + # Use the strftime parameters for formats. + # When no format has been given, it uses default. + # You can provide other formats here if you like! + default: "%Y-%m-%d" + short: "%b %d" + long: "%B %d, %Y" + + day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday] + abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat] + + # Don't forget the nil at the beginning; there's no such thing as a 0th month + month_names: [~, January, February, March, April, May, June, July, August, September, October, November, December] + abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec] + # Used in date_select and datetime_select. + order: + - year + - month + - day + + time: + formats: + default: "%a, %d %b %Y %H:%M:%S %z" + short: "%d %b %H:%M" + long: "%B %d, %Y %H:%M" + am: "am" + pm: "pm" + +# Used in array.to_sentence. + support: + array: + words_connector: ", " + two_words_connector: " and " + last_word_connector: ", and " + number: + # Used in NumberHelper.number_to_delimited() + # These are also the defaults for 'currency', 'percentage', 'precision', and 'human' + format: + # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5) + separator: "." + # Delimits thousands (e.g. 1,000,000 is a million) (always in groups of three) + delimiter: "," + # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00) + precision: 3 + # Determine how rounding is performed (see BigDecimal::mode) + round_mode: default + # If set to true, precision will mean the number of significant digits instead + # of the number of decimal digits (1234 with precision 2 becomes 1200, 1.23543 becomes 1.2) + significant: false + # If set, the zeros after the decimal separator will always be stripped (e.g.: 1.200 will be 1.2) + strip_insignificant_zeros: false + + # Used in NumberHelper.number_to_currency() + currency: + format: + # Where is the currency sign? %u is the currency unit, %n is the number (default: $5.00) + format: "%u%n" + negative_format: "-%u%n" + unit: "$" + # These six are to override number.format and are optional + separator: "." + delimiter: "," + precision: 2 + # round_mode: + significant: false + strip_insignificant_zeros: false + + # Used in NumberHelper.number_to_percentage() + percentage: + format: + # These five are to override number.format and are optional + # separator: + delimiter: "" + # precision: + # significant: false + # strip_insignificant_zeros: false + format: "%n%" + + # Used in NumberHelper.number_to_rounded() + precision: + format: + # These five are to override number.format and are optional + # separator: + delimiter: "" + # precision: + # significant: false + # strip_insignificant_zeros: false + + # Used in NumberHelper.number_to_human_size() and NumberHelper.number_to_human() + human: + format: + # These six are to override number.format and are optional + # separator: + delimiter: "" + precision: 3 + # round_mode: + significant: true + strip_insignificant_zeros: true + # Used in number_to_human_size() + storage_units: + # Storage units output formatting. + # %u is the storage unit, %n is the number (default: 2 MB) + format: "%n %u" + units: + byte: + one: "Byte" + other: "Bytes" + kb: "KB" + mb: "MB" + gb: "GB" + tb: "TB" + pb: "PB" + eb: "EB" + zb: "ZB" + # Used in NumberHelper.number_to_human() + decimal_units: + format: "%n %u" + # Decimal units output formatting + # By default we will only quantify some of the exponents + # but the commented ones might be defined or overridden + # by the user. + units: + # femto: Quadrillionth + # pico: Trillionth + # nano: Billionth + # micro: Millionth + # mili: Thousandth + # centi: Hundredth + # deci: Tenth + unit: "" + # ten: + # one: Ten + # other: Tens + # hundred: Hundred + thousand: Thousand + million: Million + billion: Billion + trillion: Trillion + quadrillion: Quadrillion diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/log_subscriber.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/log_subscriber.rb new file mode 100644 index 00000000..42df2a2f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/log_subscriber.rb @@ -0,0 +1,192 @@ +# frozen_string_literal: true + +require "active_support/core_ext/module/attribute_accessors" +require "active_support/core_ext/class/attribute" +require "active_support/core_ext/enumerable" +require "active_support/subscriber" +require "active_support/deprecation/proxy_wrappers" + +module ActiveSupport + # = Active Support Log \Subscriber + # + # +ActiveSupport::LogSubscriber+ is an object set to consume + # ActiveSupport::Notifications with the sole purpose of logging them. + # The log subscriber dispatches notifications to a registered object based + # on its given namespace. + # + # An example would be Active Record log subscriber responsible for logging + # queries: + # + # module ActiveRecord + # class LogSubscriber < ActiveSupport::LogSubscriber + # attach_to :active_record + # + # def sql(event) + # info "#{event.payload[:name]} (#{event.duration}) #{event.payload[:sql]}" + # end + # end + # end + # + # ActiveRecord::LogSubscriber.logger must be set as well, but it is assigned + # automatically in a \Rails environment. + # + # After configured, whenever a "sql.active_record" notification is + # published, it will properly dispatch the event + # (ActiveSupport::Notifications::Event) to the +sql+ method. + # + # Being an ActiveSupport::Notifications consumer, + # +ActiveSupport::LogSubscriber+ exposes a simple interface to check if + # instrumented code raises an exception. It is common to log a different + # message in case of an error, and this can be achieved by extending + # the previous example: + # + # module ActiveRecord + # class LogSubscriber < ActiveSupport::LogSubscriber + # def sql(event) + # exception = event.payload[:exception] + # + # if exception + # exception_object = event.payload[:exception_object] + # + # error "[ERROR] #{event.payload[:name]}: #{exception.join(', ')} " \ + # "(#{exception_object.backtrace.first})" + # else + # # standard logger code + # end + # end + # end + # end + # + # +ActiveSupport::LogSubscriber+ also has some helpers to deal with + # logging. For example, ActiveSupport::LogSubscriber.flush_all! will ensure + # that all logs are flushed, and it is called in Rails::Rack::Logger after a + # request finishes. + class LogSubscriber < Subscriber + # ANSI sequence modes + MODES = { + clear: 0, + bold: 1, + italic: 3, + underline: 4, + } + + # ANSI sequence colors + BLACK = "\e[30m" + RED = "\e[31m" + GREEN = "\e[32m" + YELLOW = "\e[33m" + BLUE = "\e[34m" + MAGENTA = "\e[35m" + CYAN = "\e[36m" + WHITE = "\e[37m" + + mattr_accessor :colorize_logging, default: true + class_attribute :log_levels, instance_accessor: false, default: {} # :nodoc: + + LEVEL_CHECKS = { + debug: -> (logger) { !logger.debug? }, + info: -> (logger) { !logger.info? }, + error: -> (logger) { !logger.error? }, + } + + class << self + def logger + @logger ||= if defined?(Rails) && Rails.respond_to?(:logger) + Rails.logger + end + end + + def attach_to(...) # :nodoc: + result = super + set_event_levels + result + end + + attr_writer :logger + + def log_subscribers + subscribers + end + + # Flush all log_subscribers' logger. + def flush_all! + logger.flush if logger.respond_to?(:flush) + end + + private + def fetch_public_methods(subscriber, inherit_all) + subscriber.public_methods(inherit_all) - LogSubscriber.public_instance_methods(true) + end + + def set_event_levels + if subscriber + subscriber.event_levels = log_levels.transform_keys { |k| "#{k}.#{namespace}" } + end + end + + def subscribe_log_level(method, level) + self.log_levels = log_levels.merge(method => LEVEL_CHECKS.fetch(level)) + set_event_levels + end + end + + def initialize + super + @event_levels = {} + end + + def logger + LogSubscriber.logger + end + + def silenced?(event) + logger.nil? || @event_levels[event]&.call(logger) + end + + def call(event) + super if logger + rescue => e + log_exception(event.name, e) + end + + def publish_event(event) + super if logger + rescue => e + log_exception(event.name, e) + end + + attr_writer :event_levels # :nodoc: + + private + %w(info debug warn error fatal unknown).each do |level| + class_eval <<-METHOD, __FILE__, __LINE__ + 1 + def #{level}(progname = nil, &block) + logger.#{level}(progname, &block) if logger + end + METHOD + end + + # Set color by using a symbol or one of the defined constants. Set modes + # by specifying bold, italic, or underline options. Inspired by Highline, + # this method will automatically clear formatting at the end of the returned String. + def color(text, color, mode_options = {}) # :doc: + return text unless colorize_logging + color = self.class.const_get(color.upcase) if color.is_a?(Symbol) + mode = mode_from(mode_options) + clear = "\e[#{MODES[:clear]}m" + "#{mode}#{color}#{text}#{clear}" + end + + def mode_from(options) + modes = MODES.values_at(*options.compact_blank.keys) + + "\e[#{modes.join(";")}m" if modes.any? + end + + def log_exception(name, e) + if logger + logger.error "Could not log #{name.inspect} event. #{e.class}: #{e.message} #{e.backtrace}" + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/log_subscriber/test_helper.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/log_subscriber/test_helper.rb new file mode 100644 index 00000000..b528a7fc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/log_subscriber/test_helper.rb @@ -0,0 +1,106 @@ +# frozen_string_literal: true + +require "active_support/log_subscriber" +require "active_support/logger" +require "active_support/notifications" + +module ActiveSupport + class LogSubscriber + # Provides some helpers to deal with testing log subscribers by setting up + # notifications. Take for instance Active Record subscriber tests: + # + # class SyncLogSubscriberTest < ActiveSupport::TestCase + # include ActiveSupport::LogSubscriber::TestHelper + # + # setup do + # ActiveRecord::LogSubscriber.attach_to(:active_record) + # end + # + # def test_basic_query_logging + # Developer.all.to_a + # wait + # assert_equal 1, @logger.logged(:debug).size + # assert_match(/Developer Load/, @logger.logged(:debug).last) + # assert_match(/SELECT \* FROM "developers"/, @logger.logged(:debug).last) + # end + # end + # + # All you need to do is to ensure that your log subscriber is added to + # Rails::Subscriber, as in the second line of the code above. The test + # helpers are responsible for setting up the queue and subscriptions, and + # turning colors in logs off. + # + # The messages are available in the @logger instance, which is a logger with + # limited powers (it actually does not send anything to your output), and + # you can collect them doing @logger.logged(level), where level is the level + # used in logging, like info, debug, warn, and so on. + module TestHelper + def setup # :nodoc: + @logger = MockLogger.new + @notifier = ActiveSupport::Notifications::Fanout.new + + ActiveSupport::LogSubscriber.colorize_logging = false + + @old_notifier = ActiveSupport::Notifications.notifier + set_logger(@logger) + ActiveSupport::Notifications.notifier = @notifier + end + + def teardown # :nodoc: + set_logger(nil) + ActiveSupport::Notifications.notifier = @old_notifier + end + + class MockLogger + include ActiveSupport::Logger::Severity + + attr_reader :flush_count + attr_accessor :level + + def initialize(level = DEBUG) + @flush_count = 0 + @level = level + @logged = Hash.new { |h, k| h[k] = [] } + end + + def method_missing(level, message = nil) + if block_given? + @logged[level] << yield + else + @logged[level] << message + end + end + + def logged(level) + @logged[level].compact.map { |l| l.to_s.strip } + end + + def flush + @flush_count += 1 + end + + ActiveSupport::Logger::Severity.constants.each do |severity| + class_eval <<-EOT, __FILE__, __LINE__ + 1 + def #{severity.downcase}? + #{severity} >= @level + end + EOT + end + end + + # Wait notifications to be published. + def wait + @notifier.wait + end + + # Overwrite if you use another logger in your log subscriber. + # + # def logger + # ActiveRecord::Base.logger = @logger + # end + def set_logger(logger) + ActiveSupport::LogSubscriber.logger = logger + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/logger.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/logger.rb new file mode 100644 index 00000000..09ea81f5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/logger.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +require "active_support/logger_silence" +require "active_support/logger_thread_safe_level" +require "logger" + +module ActiveSupport + class Logger < ::Logger + include LoggerSilence + + # Returns true if the logger destination matches one of the sources + # + # logger = Logger.new(STDOUT) + # ActiveSupport::Logger.logger_outputs_to?(logger, STDOUT) + # # => true + # + # logger = Logger.new('/var/log/rails.log') + # ActiveSupport::Logger.logger_outputs_to?(logger, '/var/log/rails.log') + # # => true + def self.logger_outputs_to?(logger, *sources) + loggers = if logger.is_a?(BroadcastLogger) + logger.broadcasts + else + [logger] + end + + logdevs = loggers.map { |logger| logger.instance_variable_get(:@logdev) } + logger_sources = logdevs.filter_map { |logdev| logdev.try(:filename) || logdev.try(:dev) } + + normalize_sources(sources).intersect?(normalize_sources(logger_sources)) + end + + def initialize(*args, **kwargs) + super + @formatter ||= SimpleFormatter.new + end + + # Simple formatter which only displays the message. + class SimpleFormatter < ::Logger::Formatter + # This method is invoked when a log event occurs + def call(severity, timestamp, progname, msg) + "#{String === msg ? msg : msg.inspect}\n" + end + end + + private + def self.normalize_sources(sources) + sources.map do |source| + source = source.path if source.respond_to?(:path) + source = File.realpath(source) if source.is_a?(String) && File.exist?(source) + source + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/logger_silence.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/logger_silence.rb new file mode 100644 index 00000000..8567eff4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/logger_silence.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require "active_support/concern" +require "active_support/core_ext/module/attribute_accessors" +require "active_support/logger_thread_safe_level" + +module ActiveSupport + module LoggerSilence + extend ActiveSupport::Concern + + included do + cattr_accessor :silencer, default: true + include ActiveSupport::LoggerThreadSafeLevel + end + + # Silences the logger for the duration of the block. + def silence(severity = Logger::ERROR) + silencer ? log_at(severity) { yield self } : yield(self) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/logger_thread_safe_level.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/logger_thread_safe_level.rb new file mode 100644 index 00000000..39d6fe9d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/logger_thread_safe_level.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require "active_support/concern" +require "logger" + +module ActiveSupport + module LoggerThreadSafeLevel # :nodoc: + extend ActiveSupport::Concern + + def local_level + IsolatedExecutionState[local_level_key] + end + + def local_level=(level) + case level + when Integer + when Symbol + level = Logger::Severity.const_get(level.to_s.upcase) + when nil + else + raise ArgumentError, "Invalid log level: #{level.inspect}" + end + if level.nil? + IsolatedExecutionState.delete(local_level_key) + else + IsolatedExecutionState[local_level_key] = level + end + end + + def level + local_level || super + end + + # Change the thread-local level for the duration of the given block. + def log_at(level) + old_local_level, self.local_level = local_level, level + yield + ensure + self.local_level = old_local_level + end + + private + def local_level_key + @local_level_key ||= :"logger_thread_safe_level_#{object_id}" + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/message_encryptor.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/message_encryptor.rb new file mode 100644 index 00000000..af0b20e1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/message_encryptor.rb @@ -0,0 +1,374 @@ +# frozen_string_literal: true + +require "openssl" +require "base64" +require "active_support/core_ext/module/attribute_accessors" +require "active_support/messages/codec" +require "active_support/messages/rotator" +require "active_support/message_verifier" + +module ActiveSupport + # = Active Support Message Encryptor + # + # MessageEncryptor is a simple way to encrypt values which get stored + # somewhere you don't trust. + # + # The cipher text and initialization vector are base64 encoded and returned + # to you. + # + # This can be used in situations similar to the MessageVerifier, but + # where you don't want users to be able to determine the value of the payload. + # + # len = ActiveSupport::MessageEncryptor.key_len + # salt = SecureRandom.random_bytes(len) + # key = ActiveSupport::KeyGenerator.new('password').generate_key(salt, len) # => "\x89\xE0\x156\xAC..." + # crypt = ActiveSupport::MessageEncryptor.new(key) # => # + # encrypted_data = crypt.encrypt_and_sign('my secret data') # => "NlFBTTMwOUV5UlA1QlNEN2xkY2d6eThYWWh..." + # crypt.decrypt_and_verify(encrypted_data) # => "my secret data" + # + # The +decrypt_and_verify+ method will raise an + # +ActiveSupport::MessageEncryptor::InvalidMessage+ exception if the data + # provided cannot be decrypted or verified. + # + # crypt.decrypt_and_verify('not encrypted data') # => ActiveSupport::MessageEncryptor::InvalidMessage + # + # === Confining messages to a specific purpose + # + # By default any message can be used throughout your app. But they can also be + # confined to a specific +:purpose+. + # + # token = crypt.encrypt_and_sign("this is the chair", purpose: :login) + # + # Then that same purpose must be passed when verifying to get the data back out: + # + # crypt.decrypt_and_verify(token, purpose: :login) # => "this is the chair" + # crypt.decrypt_and_verify(token, purpose: :shipping) # => nil + # crypt.decrypt_and_verify(token) # => nil + # + # Likewise, if a message has no purpose it won't be returned when verifying with + # a specific purpose. + # + # token = crypt.encrypt_and_sign("the conversation is lively") + # crypt.decrypt_and_verify(token, purpose: :scare_tactics) # => nil + # crypt.decrypt_and_verify(token) # => "the conversation is lively" + # + # === Making messages expire + # + # By default messages last forever and verifying one year from now will still + # return the original value. But messages can be set to expire at a given + # time with +:expires_in+ or +:expires_at+. + # + # crypt.encrypt_and_sign(parcel, expires_in: 1.month) + # crypt.encrypt_and_sign(doowad, expires_at: Time.now.end_of_year) + # + # Then the messages can be verified and returned up to the expire time. + # Thereafter, verifying returns +nil+. + # + # === Rotating keys + # + # MessageEncryptor also supports rotating out old configurations by falling + # back to a stack of encryptors. Call +rotate+ to build and add an encryptor + # so +decrypt_and_verify+ will also try the fallback. + # + # By default any rotated encryptors use the values of the primary + # encryptor unless specified otherwise. + # + # You'd give your encryptor the new defaults: + # + # crypt = ActiveSupport::MessageEncryptor.new(@secret, cipher: "aes-256-gcm") + # + # Then gradually rotate the old values out by adding them as fallbacks. Any message + # generated with the old values will then work until the rotation is removed. + # + # crypt.rotate old_secret # Fallback to an old secret instead of @secret. + # crypt.rotate cipher: "aes-256-cbc" # Fallback to an old cipher instead of aes-256-gcm. + # + # Though if both the secret and the cipher was changed at the same time, + # the above should be combined into: + # + # crypt.rotate old_secret, cipher: "aes-256-cbc" + class MessageEncryptor < Messages::Codec + prepend Messages::Rotator + + cattr_accessor :use_authenticated_message_encryption, instance_accessor: false, default: false + + class << self + def default_cipher # :nodoc: + if use_authenticated_message_encryption + "aes-256-gcm" + else + "aes-256-cbc" + end + end + end + + module NullSerializer # :nodoc: + def self.load(value) + value + end + + def self.dump(value) + value + end + end + + class InvalidMessage < StandardError; end + OpenSSLCipherError = OpenSSL::Cipher::CipherError + + AUTH_TAG_LENGTH = 16 # :nodoc: + SEPARATOR = "--" # :nodoc: + + # Initialize a new MessageEncryptor. +secret+ must be at least as long as + # the cipher key size. For the default 'aes-256-gcm' cipher, this is 256 + # bits. If you are using a user-entered secret, you can generate a suitable + # key by using ActiveSupport::KeyGenerator or a similar key + # derivation function. + # + # The first additional parameter is used as the signature key for + # MessageVerifier. This allows you to specify keys to encrypt and sign + # data. Ignored when using an AEAD cipher like 'aes-256-gcm'. + # + # ActiveSupport::MessageEncryptor.new('secret', 'signature_secret') + # + # ==== Options + # + # [+:cipher+] + # Cipher to use. Can be any cipher returned by +OpenSSL::Cipher.ciphers+. + # Default is 'aes-256-gcm'. + # + # [+:digest+] + # Digest used for signing. Ignored when using an AEAD cipher like + # 'aes-256-gcm'. + # + # [+:serializer+] + # The serializer used to serialize message data. You can specify any + # object that responds to +dump+ and +load+, or you can choose from + # several preconfigured serializers: +:marshal+, +:json_allow_marshal+, + # +:json+, +:message_pack_allow_marshal+, +:message_pack+. + # + # The preconfigured serializers include a fallback mechanism to support + # multiple deserialization formats. For example, the +:marshal+ serializer + # will serialize using +Marshal+, but can deserialize using +Marshal+, + # ActiveSupport::JSON, or ActiveSupport::MessagePack. This makes it easy + # to migrate between serializers. + # + # The +:marshal+, +:json_allow_marshal+, and +:message_pack_allow_marshal+ + # serializers support deserializing using +Marshal+, but the others do + # not. Beware that +Marshal+ is a potential vector for deserialization + # attacks in cases where a message signing secret has been leaked. If + # possible, choose a serializer that does not support +Marshal+. + # + # The +:message_pack+ and +:message_pack_allow_marshal+ serializers use + # ActiveSupport::MessagePack, which can roundtrip some Ruby types that are + # not supported by JSON, and may provide improved performance. However, + # these require the +msgpack+ gem. + # + # When using \Rails, the default depends on +config.active_support.message_serializer+. + # Otherwise, the default is +:marshal+. + # + # [+:url_safe+] + # By default, MessageEncryptor generates RFC 4648 compliant strings + # which are not URL-safe. In other words, they can contain "+" and "/". + # If you want to generate URL-safe strings (in compliance with "Base 64 + # Encoding with URL and Filename Safe Alphabet" in RFC 4648), you can + # pass +true+. + # + # [+:force_legacy_metadata_serializer+] + # Whether to use the legacy metadata serializer, which serializes the + # message first, then wraps it in an envelope which is also serialized. This + # was the default in \Rails 7.0 and below. + # + # If you don't pass a truthy value, the default is set using + # +config.active_support.use_message_serializer_for_metadata+. + def initialize(secret, sign_secret = nil, **options) + super(**options) + @secret = secret + @cipher = options[:cipher] || self.class.default_cipher + @aead_mode = new_cipher.authenticated? + @verifier = if !@aead_mode + MessageVerifier.new(sign_secret || secret, **options, serializer: NullSerializer) + end + end + + # Encrypt and sign a message. We need to sign the message in order to avoid + # padding attacks. Reference: https://www.limited-entropy.com/padding-oracle-attacks/. + # + # ==== Options + # + # [+:expires_at+] + # The datetime at which the message expires. After this datetime, + # verification of the message will fail. + # + # message = encryptor.encrypt_and_sign("hello", expires_at: Time.now.tomorrow) + # encryptor.decrypt_and_verify(message) # => "hello" + # # 24 hours later... + # encryptor.decrypt_and_verify(message) # => nil + # + # [+:expires_in+] + # The duration for which the message is valid. After this duration has + # elapsed, verification of the message will fail. + # + # message = encryptor.encrypt_and_sign("hello", expires_in: 24.hours) + # encryptor.decrypt_and_verify(message) # => "hello" + # # 24 hours later... + # encryptor.decrypt_and_verify(message) # => nil + # + # [+:purpose+] + # The purpose of the message. If specified, the same purpose must be + # specified when verifying the message; otherwise, verification will fail. + # (See #decrypt_and_verify.) + def encrypt_and_sign(value, **options) + create_message(value, **options) + end + + # Decrypt and verify a message. We need to verify the message in order to + # avoid padding attacks. Reference: https://www.limited-entropy.com/padding-oracle-attacks/. + # + # ==== Options + # + # [+:purpose+] + # The purpose that the message was generated with. If the purpose does not + # match, +decrypt_and_verify+ will return +nil+. + # + # message = encryptor.encrypt_and_sign("hello", purpose: "greeting") + # encryptor.decrypt_and_verify(message, purpose: "greeting") # => "hello" + # encryptor.decrypt_and_verify(message) # => nil + # + # message = encryptor.encrypt_and_sign("bye") + # encryptor.decrypt_and_verify(message) # => "bye" + # encryptor.decrypt_and_verify(message, purpose: "greeting") # => nil + # + def decrypt_and_verify(message, **options) + catch_and_raise :invalid_message_format, as: InvalidMessage do + catch_and_raise :invalid_message_serialization, as: InvalidMessage do + catch_and_ignore :invalid_message_content do + read_message(message, **options) + end + end + end + end + + # Given a cipher, returns the key length of the cipher to help generate the key of desired size + def self.key_len(cipher = default_cipher) + OpenSSL::Cipher.new(cipher).key_len + end + + def create_message(value, **options) # :nodoc: + sign(encrypt(serialize_with_metadata(value, **options))) + end + + def read_message(message, **options) # :nodoc: + deserialize_with_metadata(decrypt(verify(message)), **options) + end + + def inspect # :nodoc: + "#<#{self.class.name}:#{'%#016x' % (object_id << 1)}>" + end + + private + def sign(data) + @verifier ? @verifier.create_message(data) : data + end + + def verify(data) + @verifier ? @verifier.read_message(data) : data + end + + def encrypt(data) + cipher = new_cipher + cipher.encrypt + cipher.key = @secret + + # Rely on OpenSSL for the initialization vector + iv = cipher.random_iv + cipher.auth_data = "" if aead_mode? + + encrypted_data = cipher.update(data) + encrypted_data << cipher.final + + parts = [encrypted_data, iv] + parts << cipher.auth_tag(AUTH_TAG_LENGTH) if aead_mode? + + join_parts(parts) + end + + def decrypt(encrypted_message) + cipher = new_cipher + encrypted_data, iv, auth_tag = extract_parts(encrypted_message) + + # Currently the OpenSSL bindings do not raise an error if auth_tag is + # truncated, which would allow an attacker to easily forge it. See + # https://github.com/ruby/openssl/issues/63 + if aead_mode? && auth_tag.bytesize != AUTH_TAG_LENGTH + throw :invalid_message_format, "truncated auth_tag" + end + + cipher.decrypt + cipher.key = @secret + cipher.iv = iv + if aead_mode? + cipher.auth_tag = auth_tag + cipher.auth_data = "" + end + + decrypted_data = cipher.update(encrypted_data) + decrypted_data << cipher.final + rescue OpenSSLCipherError => error + throw :invalid_message_format, error + end + + def length_after_encode(length_before_encode) + if @url_safe + (4 * length_before_encode / 3.0).ceil # length without padding + else + 4 * (length_before_encode / 3.0).ceil # length with padding + end + end + + def length_of_encoded_iv + @length_of_encoded_iv ||= length_after_encode(new_cipher.iv_len) + end + + def length_of_encoded_auth_tag + @length_of_encoded_auth_tag ||= length_after_encode(AUTH_TAG_LENGTH) + end + + def join_parts(parts) + parts.map! { |part| encode(part) }.join(SEPARATOR) + end + + def extract_part(encrypted_message, rindex, length) + index = rindex - length + + if encrypted_message[index - SEPARATOR.length, SEPARATOR.length] == SEPARATOR + encrypted_message[index, length] + else + throw :invalid_message_format, "missing separator" + end + end + + def extract_parts(encrypted_message) + parts = [] + rindex = encrypted_message.length + + if aead_mode? + parts << extract_part(encrypted_message, rindex, length_of_encoded_auth_tag) + rindex -= SEPARATOR.length + length_of_encoded_auth_tag + end + + parts << extract_part(encrypted_message, rindex, length_of_encoded_iv) + rindex -= SEPARATOR.length + length_of_encoded_iv + + parts << encrypted_message[0, rindex] + + parts.reverse!.map! { |part| decode(part) } + end + + def new_cipher + OpenSSL::Cipher.new(@cipher) + end + + attr_reader :aead_mode + alias :aead_mode? :aead_mode + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/message_encryptors.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/message_encryptors.rb new file mode 100644 index 00000000..aa327404 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/message_encryptors.rb @@ -0,0 +1,141 @@ +# frozen_string_literal: true + +require "active_support/messages/rotation_coordinator" + +module ActiveSupport + class MessageEncryptors < Messages::RotationCoordinator + ## + # :attr_accessor: transitional + # + # If true, the first two rotation option sets are swapped when building + # message encryptors. For example, with the following configuration, message + # encryptors will encrypt messages using serializer: Marshal, url_safe: true, + # and will able to decrypt messages that were encrypted using any of the + # three option sets: + # + # encryptors = ActiveSupport::MessageEncryptors.new { ... } + # encryptors.rotate(serializer: JSON, url_safe: true) + # encryptors.rotate(serializer: Marshal, url_safe: true) + # encryptors.rotate(serializer: Marshal, url_safe: false) + # encryptors.transitional = true + # + # This can be useful when performing a rolling deploy of an application, + # wherein servers that have not yet been updated must still be able to + # decrypt messages from updated servers. In such a scenario, first perform a + # rolling deploy with the new rotation (e.g. serializer: JSON, url_safe: true) + # as the first rotation and transitional = true. Then, after all + # servers have been updated, perform a second rolling deploy with + # transitional = false. + + ## + # :singleton-method: new + # :call-seq: new(&secret_generator) + # + # Initializes a new instance. +secret_generator+ must accept a salt and a + # +secret_length+ kwarg, and return a suitable secret (string) or secrets + # (array of strings). +secret_generator+ may also accept other arbitrary + # kwargs. If #rotate is called with any options matching those kwargs, those + # options will be passed to +secret_generator+ instead of to the message + # encryptor. + # + # encryptors = ActiveSupport::MessageEncryptors.new do |salt, secret_length:, base:| + # MySecretGenerator.new(base).generate(salt, secret_length) + # end + # + # encryptors.rotate(base: "...") + + ## + # :method: [] + # :call-seq: [](salt) + # + # Returns a MessageEncryptor configured with a secret derived from the + # given +salt+, and options from #rotate. MessageEncryptor instances will + # be memoized, so the same +salt+ will return the same instance. + + ## + # :method: []= + # :call-seq: []=(salt, encryptor) + # + # Overrides a MessageEncryptor instance associated with a given +salt+. + + ## + # :method: rotate + # :call-seq: + # rotate(**options) + # rotate(&block) + # + # Adds +options+ to the list of option sets. Messages will be encrypted + # using the first set in the list. When decrypting, however, each set will + # be tried, in order, until one succeeds. + # + # Notably, the +:secret_generator+ option can specify a different secret + # generator than the one initially specified. The secret generator must + # respond to +call+, accept a salt and a +secret_length+ kwarg, and return + # a suitable secret (string) or secrets (array of strings). The secret + # generator may also accept other arbitrary kwargs. + # + # If any options match the kwargs of the operative secret generator, those + # options will be passed to the secret generator instead of to the message + # encryptor. + # + # For fine-grained per-salt rotations, a block form is supported. The block + # will receive the salt, and should return an appropriate options Hash. The + # block may also return +nil+ to indicate that the rotation does not apply + # to the given salt. For example: + # + # encryptors = ActiveSupport::MessageEncryptors.new { ... } + # + # encryptors.rotate do |salt| + # case salt + # when :foo + # { serializer: JSON, url_safe: true } + # when :bar + # { serializer: Marshal, url_safe: true } + # end + # end + # + # encryptors.rotate(serializer: Marshal, url_safe: false) + # + # # Uses `serializer: JSON, url_safe: true`. + # # Falls back to `serializer: Marshal, url_safe: false`. + # encryptors[:foo] + # + # # Uses `serializer: Marshal, url_safe: true`. + # # Falls back to `serializer: Marshal, url_safe: false`. + # encryptors[:bar] + # + # # Uses `serializer: Marshal, url_safe: false`. + # encryptors[:baz] + + ## + # :method: rotate_defaults + # :call-seq: rotate_defaults + # + # Invokes #rotate with the default options. + + ## + # :method: clear_rotations + # :call-seq: clear_rotations + # + # Clears the list of option sets. + + ## + # :method: on_rotation + # :call-seq: on_rotation(&callback) + # + # Sets a callback to invoke when a message is decrypted using an option set + # other than the first. + # + # For example, this callback could log each time it is called, and thus + # indicate whether old option sets are still in use or can be removed from + # rotation. + + ## + private + def build(salt, secret_generator:, secret_generator_options:, **options) + secret_length = MessageEncryptor.key_len(*options[:cipher]) + secret = secret_generator.call(salt, secret_length: secret_length, **secret_generator_options) + MessageEncryptor.new(*Array(secret), **options) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/message_pack.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/message_pack.rb new file mode 100644 index 00000000..3ce2c07b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/message_pack.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +begin + gem "msgpack", ">= 1.7.0" + require "msgpack" +rescue LoadError => error + warn "ActiveSupport::MessagePack requires the msgpack gem, version 1.7.0 or later. " \ + "Please add it to your Gemfile: `gem \"msgpack\", \">= 1.7.0\"`" + raise error +end + +require_relative "message_pack/cache_serializer" +require_relative "message_pack/serializer" + +module ActiveSupport + module MessagePack + extend Serializer + + ## + # :singleton-method: dump + # :call-seq: dump(object) + # + # Dumps an object. Raises ActiveSupport::MessagePack::UnserializableObjectError + # if the object type is not supported. + # + #-- + # Implemented by Serializer#dump. + + ## + # :singleton-method: load + # :call-seq: load(dumped) + # + # Loads an object dump created by ::dump. + # + #-- + # Implemented by Serializer#load. + + ## + # :singleton-method: signature? + # :call-seq: signature?(dumped) + # + # Returns true if the given dump begins with an +ActiveSupport::MessagePack+ + # signature. + # + #-- + # Implemented by Serializer#signature?. + + ActiveSupport.run_load_hooks(:message_pack, self) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/message_pack/cache_serializer.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/message_pack/cache_serializer.rb new file mode 100644 index 00000000..a7f4958e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/message_pack/cache_serializer.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require_relative "serializer" + +module ActiveSupport + module MessagePack + module CacheSerializer + include Serializer + extend self + + def load(dumped) + super + rescue ActiveSupport::MessagePack::MissingClassError + # Treat missing class as cache miss => return nil + end + + private + def install_unregistered_type_handler + Extensions.install_unregistered_type_fallback(message_pack_factory) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/message_pack/extensions.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/message_pack/extensions.rb new file mode 100644 index 00000000..3e3ba64c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/message_pack/extensions.rb @@ -0,0 +1,305 @@ +# frozen_string_literal: true + +require "bigdecimal" +require "date" +require "ipaddr" +require "pathname" +require "uri/generic" +require "msgpack/bigint" +require "active_support/hash_with_indifferent_access" +require "active_support/time" + +module ActiveSupport + module MessagePack + class UnserializableObjectError < StandardError; end + class MissingClassError < StandardError; end # :nodoc: + + module Extensions # :nodoc: + extend self + + def install(registry) + registry.register_type 0, Symbol, + packer: :to_msgpack_ext, + unpacker: :from_msgpack_ext, + optimized_symbols_parsing: true + + registry.register_type 1, Integer, + packer: ::MessagePack::Bigint.method(:to_msgpack_ext), + unpacker: ::MessagePack::Bigint.method(:from_msgpack_ext), + oversized_integer_extension: true + + registry.register_type 2, BigDecimal, + packer: :_dump, + unpacker: :_load + + registry.register_type 3, Rational, + packer: method(:write_rational), + unpacker: method(:read_rational), + recursive: true + + registry.register_type 4, Complex, + packer: method(:write_complex), + unpacker: method(:read_complex), + recursive: true + + registry.register_type 5, DateTime, + packer: method(:write_datetime), + unpacker: method(:read_datetime), + recursive: true + + registry.register_type 6, Date, + packer: method(:write_date), + unpacker: method(:read_date), + recursive: true + + registry.register_type 7, Time, + packer: method(:write_time), + unpacker: method(:read_time), + recursive: true + + registry.register_type 8, ActiveSupport::TimeWithZone, + packer: method(:write_time_with_zone), + unpacker: method(:read_time_with_zone), + recursive: true + + registry.register_type 9, ActiveSupport::TimeZone, + packer: method(:dump_time_zone), + unpacker: method(:load_time_zone) + + registry.register_type 10, ActiveSupport::Duration, + packer: method(:write_duration), + unpacker: method(:read_duration), + recursive: true + + registry.register_type 11, Range, + packer: method(:write_range), + unpacker: method(:read_range), + recursive: true + + registry.register_type 12, Set, + packer: method(:write_set), + unpacker: method(:read_set), + recursive: true + + registry.register_type 13, URI::Generic, + packer: :to_s, + unpacker: URI.method(:parse) + + registry.register_type 14, IPAddr, + packer: method(:write_ipaddr), + unpacker: method(:read_ipaddr), + recursive: true + + registry.register_type 15, Pathname, + packer: :to_s, + unpacker: :new + + registry.register_type 16, Regexp, + packer: :to_s, + unpacker: :new + + registry.register_type 17, ActiveSupport::HashWithIndifferentAccess, + packer: method(:write_hash_with_indifferent_access), + unpacker: method(:read_hash_with_indifferent_access), + recursive: true + end + + def install_unregistered_type_error(registry) + registry.register_type 127, Object, + packer: method(:raise_unserializable), + unpacker: method(:raise_invalid_format) + end + + def install_unregistered_type_fallback(registry) + registry.register_type 127, Object, + packer: method(:write_object), + unpacker: method(:read_object), + recursive: true + end + + def write_rational(rational, packer) + packer.write(rational.numerator) + packer.write(rational.denominator) unless rational.numerator.zero? + end + + def read_rational(unpacker) + numerator = unpacker.read + Rational(numerator, numerator.zero? ? 1 : unpacker.read) + end + + def write_complex(complex, packer) + packer.write(complex.real) + packer.write(complex.imaginary) + end + + def read_complex(unpacker) + Complex(unpacker.read, unpacker.read) + end + + def write_datetime(datetime, packer) + packer.write(datetime.jd) + packer.write(datetime.hour) + packer.write(datetime.min) + packer.write(datetime.sec) + write_rational(datetime.sec_fraction, packer) + write_rational(datetime.offset, packer) + end + + def read_datetime(unpacker) + DateTime.jd(unpacker.read, unpacker.read, unpacker.read, unpacker.read + read_rational(unpacker), read_rational(unpacker)) + end + + def write_date(date, packer) + packer.write(date.jd) + end + + def read_date(unpacker) + Date.jd(unpacker.read) + end + + def write_time(time, packer) + packer.write(time.tv_sec) + packer.write(time.tv_nsec) + packer.write(time.utc_offset) + end + + def read_time(unpacker) + Time.at_without_coercion(unpacker.read, unpacker.read, :nanosecond, in: unpacker.read) + end + + def write_time_with_zone(twz, packer) + write_time(twz.utc, packer) + write_time_zone(twz.time_zone, packer) + end + + def read_time_with_zone(unpacker) + ActiveSupport::TimeWithZone.new(read_time(unpacker), read_time_zone(unpacker)) + end + + def dump_time_zone(time_zone) + time_zone.name + end + + def load_time_zone(name) + ActiveSupport::TimeZone[name] + end + + def write_time_zone(time_zone, packer) + packer.write(dump_time_zone(time_zone)) + end + + def read_time_zone(unpacker) + load_time_zone(unpacker.read) + end + + def write_duration(duration, packer) + packer.write(duration.value) + packer.write(duration._parts.values_at(*ActiveSupport::Duration::PARTS)) + end + + def read_duration(unpacker) + value = unpacker.read + parts = ActiveSupport::Duration::PARTS.zip(unpacker.read).to_h + parts.compact! + ActiveSupport::Duration.new(value, parts) + end + + def write_range(range, packer) + packer.write(range.begin) + packer.write(range.end) + packer.write(range.exclude_end?) + end + + def read_range(unpacker) + Range.new(unpacker.read, unpacker.read, unpacker.read) + end + + def write_set(set, packer) + packer.write(set.to_a) + end + + def read_set(unpacker) + Set.new(unpacker.read) + end + + def write_ipaddr(ipaddr, packer) + if ipaddr.prefix < 32 || (ipaddr.ipv6? && ipaddr.prefix < 128) + packer.write("#{ipaddr}/#{ipaddr.prefix}") + else + packer.write(ipaddr.to_s) + end + end + + def read_ipaddr(unpacker) + IPAddr.new(unpacker.read) + end + + def write_hash_with_indifferent_access(hwia, packer) + packer.write(hwia.to_h) + end + + def read_hash_with_indifferent_access(unpacker) + ActiveSupport::HashWithIndifferentAccess.new(unpacker.read) + end + + def raise_unserializable(object, *) + raise UnserializableObjectError, "Unsupported type #{object.class} for object #{object.inspect}" + end + + def raise_invalid_format(*) + raise "Invalid format" + end + + def dump_class(klass) + raise UnserializableObjectError, "Cannot serialize anonymous class" unless klass.name + klass.name + end + + def load_class(name) + Object.const_get(name) + rescue NameError => error + if error.name.to_s == name + raise MissingClassError, "Missing class: #{name}" + else + raise + end + end + + def write_class(klass, packer) + packer.write(dump_class(klass)) + end + + def read_class(unpacker) + load_class(unpacker.read) + end + + LOAD_WITH_MSGPACK_EXT = 0 + LOAD_WITH_JSON_CREATE = 1 + + def write_object(object, packer) + if object.class.respond_to?(:from_msgpack_ext) + packer.write(LOAD_WITH_MSGPACK_EXT) + write_class(object.class, packer) + packer.write(object.to_msgpack_ext) + elsif object.class.respond_to?(:json_create) + packer.write(LOAD_WITH_JSON_CREATE) + write_class(object.class, packer) + packer.write(object.as_json) + else + raise_unserializable(object) + end + end + + def read_object(unpacker) + case unpacker.read + when LOAD_WITH_MSGPACK_EXT + read_class(unpacker).from_msgpack_ext(unpacker.read) + when LOAD_WITH_JSON_CREATE + read_class(unpacker).json_create(unpacker.read) + else + raise_invalid_format + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/message_pack/serializer.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/message_pack/serializer.rb new file mode 100644 index 00000000..c5ce8e18 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/message_pack/serializer.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require_relative "extensions" + +module ActiveSupport + module MessagePack + module Serializer # :nodoc: + SIGNATURE = "\xCC\x80".b.freeze # == 128.to_msgpack + SIGNATURE_INT = 128 + + def dump(object) + message_pack_pool.packer do |packer| + packer.write(SIGNATURE_INT) + packer.write(object) + packer.full_pack + end + end + + def load(dumped) + message_pack_pool.unpacker do |unpacker| + unpacker.feed_reference(dumped) + raise "Invalid serialization format" unless unpacker.read == SIGNATURE_INT + unpacker.full_unpack + end + end + + def signature?(dumped) + dumped.getbyte(0) == SIGNATURE.getbyte(0) && dumped.getbyte(1) == SIGNATURE.getbyte(1) + end + + def message_pack_factory + @message_pack_factory ||= ::MessagePack::Factory.new + end + + def message_pack_factory=(factory) + @message_pack_pool = nil + @message_pack_factory = factory + end + + delegate :register_type, to: :message_pack_factory + + def warmup + message_pack_pool # eagerly compute + end + + private + def message_pack_pool + @message_pack_pool ||= begin + unless message_pack_factory.frozen? + Extensions.install(message_pack_factory) + install_unregistered_type_handler + message_pack_factory.freeze + end + message_pack_factory.pool(ENV.fetch("RAILS_MAX_THREADS", 5).to_i) + end + end + + def install_unregistered_type_handler + Extensions.install_unregistered_type_error(message_pack_factory) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/message_verifier.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/message_verifier.rb new file mode 100644 index 00000000..b89ed55f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/message_verifier.rb @@ -0,0 +1,377 @@ +# frozen_string_literal: true + +require "openssl" +require "base64" +require "active_support/core_ext/object/blank" +require "active_support/security_utils" +require "active_support/messages/codec" +require "active_support/messages/rotator" + +module ActiveSupport + # = Active Support Message Verifier + # + # +MessageVerifier+ makes it easy to generate and verify messages which are + # signed to prevent tampering. + # + # In a \Rails application, you can use +Rails.application.message_verifier+ + # to manage unique instances of verifiers for each use case. + # {Learn more}[link:classes/Rails/Application.html#method-i-message_verifier]. + # + # This is useful for cases like remember-me tokens and auto-unsubscribe links + # where the session store isn't suitable or available. + # + # First, generate a signed message: + # cookies[:remember_me] = Rails.application.message_verifier(:remember_me).generate([@user.id, 2.weeks.from_now]) + # + # Later verify that message: + # + # id, time = Rails.application.message_verifier(:remember_me).verify(cookies[:remember_me]) + # if time.future? + # self.current_user = User.find(id) + # end + # + # === Signing is not encryption + # + # The signed messages are not encrypted. The payload is merely encoded (Base64 by default) and can be decoded by + # anyone. The signature is just assuring that the message wasn't tampered with. For example: + # + # message = Rails.application.message_verifier('my_purpose').generate('never put secrets here') + # # => "BAhJIhtuZXZlciBwdXQgc2VjcmV0cyBoZXJlBjoGRVQ=--a0c1c0827919da5e949e989c971249355735e140" + # Base64.decode64(message.split("--").first) # no key needed + # # => 'never put secrets here' + # + # If you also need to encrypt the contents, you must use ActiveSupport::MessageEncryptor instead. + # + # === Confine messages to a specific purpose + # + # It's not recommended to use the same verifier for different purposes in your application. + # Doing so could allow a malicious actor to re-use a signed message to perform an unauthorized + # action. + # You can reduce this risk by confining signed messages to a specific +:purpose+. + # + # token = @verifier.generate("signed message", purpose: :login) + # + # Then that same purpose must be passed when verifying to get the data back out: + # + # @verifier.verified(token, purpose: :login) # => "signed message" + # @verifier.verified(token, purpose: :shipping) # => nil + # @verifier.verified(token) # => nil + # + # @verifier.verify(token, purpose: :login) # => "signed message" + # @verifier.verify(token, purpose: :shipping) # => raises ActiveSupport::MessageVerifier::InvalidSignature + # @verifier.verify(token) # => raises ActiveSupport::MessageVerifier::InvalidSignature + # + # Likewise, if a message has no purpose it won't be returned when verifying with + # a specific purpose. + # + # token = @verifier.generate("signed message") + # @verifier.verified(token, purpose: :redirect) # => nil + # @verifier.verified(token) # => "signed message" + # + # @verifier.verify(token, purpose: :redirect) # => raises ActiveSupport::MessageVerifier::InvalidSignature + # @verifier.verify(token) # => "signed message" + # + # === Expiring messages + # + # By default messages last forever and verifying one year from now will still + # return the original value. But messages can be set to expire at a given + # time with +:expires_in+ or +:expires_at+. + # + # @verifier.generate("signed message", expires_in: 1.month) + # @verifier.generate("signed message", expires_at: Time.now.end_of_year) + # + # Messages can then be verified and returned until expiry. + # Thereafter, the +verified+ method returns +nil+ while +verify+ raises + # +ActiveSupport::MessageVerifier::InvalidSignature+. + # + # === Rotating keys + # + # MessageVerifier also supports rotating out old configurations by falling + # back to a stack of verifiers. Call +rotate+ to build and add a verifier so + # either +verified+ or +verify+ will also try verifying with the fallback. + # + # By default any rotated verifiers use the values of the primary + # verifier unless specified otherwise. + # + # You'd give your verifier the new defaults: + # + # verifier = ActiveSupport::MessageVerifier.new(@secret, digest: "SHA512", serializer: JSON) + # + # Then gradually rotate the old values out by adding them as fallbacks. Any message + # generated with the old values will then work until the rotation is removed. + # + # verifier.rotate(old_secret) # Fallback to an old secret instead of @secret. + # verifier.rotate(digest: "SHA256") # Fallback to an old digest instead of SHA512. + # verifier.rotate(serializer: Marshal) # Fallback to an old serializer instead of JSON. + # + # Though the above would most likely be combined into one rotation: + # + # verifier.rotate(old_secret, digest: "SHA256", serializer: Marshal) + class MessageVerifier < Messages::Codec + prepend Messages::Rotator + + class InvalidSignature < StandardError; end + + SEPARATOR = "--" # :nodoc: + SEPARATOR_LENGTH = SEPARATOR.length # :nodoc: + + # Initialize a new MessageVerifier with a secret for the signature. + # + # ==== Options + # + # [+:digest+] + # Digest used for signing. The default is "SHA1". See + # +OpenSSL::Digest+ for alternatives. + # + # [+:serializer+] + # The serializer used to serialize message data. You can specify any + # object that responds to +dump+ and +load+, or you can choose from + # several preconfigured serializers: +:marshal+, +:json_allow_marshal+, + # +:json+, +:message_pack_allow_marshal+, +:message_pack+. + # + # The preconfigured serializers include a fallback mechanism to support + # multiple deserialization formats. For example, the +:marshal+ serializer + # will serialize using +Marshal+, but can deserialize using +Marshal+, + # ActiveSupport::JSON, or ActiveSupport::MessagePack. This makes it easy + # to migrate between serializers. + # + # The +:marshal+, +:json_allow_marshal+, and +:message_pack_allow_marshal+ + # serializers support deserializing using +Marshal+, but the others do + # not. Beware that +Marshal+ is a potential vector for deserialization + # attacks in cases where a message signing secret has been leaked. If + # possible, choose a serializer that does not support +Marshal+. + # + # The +:message_pack+ and +:message_pack_allow_marshal+ serializers use + # ActiveSupport::MessagePack, which can roundtrip some Ruby types that are + # not supported by JSON, and may provide improved performance. However, + # these require the +msgpack+ gem. + # + # When using \Rails, the default depends on +config.active_support.message_serializer+. + # Otherwise, the default is +:marshal+. + # + # [+:url_safe+] + # By default, MessageVerifier generates RFC 4648 compliant strings which are + # not URL-safe. In other words, they can contain "+" and "/". If you want to + # generate URL-safe strings (in compliance with "Base 64 Encoding with URL + # and Filename Safe Alphabet" in RFC 4648), you can pass +true+. + # Note that MessageVerifier will always accept both URL-safe and URL-unsafe + # encoded messages, to allow a smooth transition between the two settings. + # + # [+:force_legacy_metadata_serializer+] + # Whether to use the legacy metadata serializer, which serializes the + # message first, then wraps it in an envelope which is also serialized. This + # was the default in \Rails 7.0 and below. + # + # If you don't pass a truthy value, the default is set using + # +config.active_support.use_message_serializer_for_metadata+. + def initialize(secret, **options) + raise ArgumentError, "Secret should not be nil." unless secret + super(**options) + @secret = secret + @digest = options[:digest]&.to_s || "SHA1" + end + + # Checks if a signed message could have been generated by signing an object + # with the +MessageVerifier+'s secret. + # + # verifier = ActiveSupport::MessageVerifier.new("secret") + # signed_message = verifier.generate("signed message") + # verifier.valid_message?(signed_message) # => true + # + # tampered_message = signed_message.chop # editing the message invalidates the signature + # verifier.valid_message?(tampered_message) # => false + def valid_message?(message) + !!catch_and_ignore(:invalid_message_format) { extract_encoded(message) } + end + + # Decodes the signed message using the +MessageVerifier+'s secret. + # + # verifier = ActiveSupport::MessageVerifier.new("secret") + # + # signed_message = verifier.generate("signed message") + # verifier.verified(signed_message) # => "signed message" + # + # Returns +nil+ if the message was not signed with the same secret. + # + # other_verifier = ActiveSupport::MessageVerifier.new("different_secret") + # other_verifier.verified(signed_message) # => nil + # + # Returns +nil+ if the message is not Base64-encoded. + # + # invalid_message = "f--46a0120593880c733a53b6dad75b42ddc1c8996d" + # verifier.verified(invalid_message) # => nil + # + # Raises any error raised while decoding the signed message. + # + # incompatible_message = "test--dad7b06c94abba8d46a15fafaef56c327665d5ff" + # verifier.verified(incompatible_message) # => TypeError: incompatible marshal file format + # + # ==== Options + # + # [+:purpose+] + # The purpose that the message was generated with. If the purpose does not + # match, +verified+ will return +nil+. + # + # message = verifier.generate("hello", purpose: "greeting") + # verifier.verified(message, purpose: "greeting") # => "hello" + # verifier.verified(message, purpose: "chatting") # => nil + # verifier.verified(message) # => nil + # + # message = verifier.generate("bye") + # verifier.verified(message) # => "bye" + # verifier.verified(message, purpose: "greeting") # => nil + # + def verified(message, **options) + catch_and_ignore :invalid_message_format do + catch_and_raise :invalid_message_serialization do + catch_and_ignore :invalid_message_content do + read_message(message, **options) + end + end + end + end + + # Decodes the signed message using the +MessageVerifier+'s secret. + # + # verifier = ActiveSupport::MessageVerifier.new("secret") + # signed_message = verifier.generate("signed message") + # + # verifier.verify(signed_message) # => "signed message" + # + # Raises +InvalidSignature+ if the message was not signed with the same + # secret or was not Base64-encoded. + # + # other_verifier = ActiveSupport::MessageVerifier.new("different_secret") + # other_verifier.verify(signed_message) # => ActiveSupport::MessageVerifier::InvalidSignature + # + # ==== Options + # + # [+:purpose+] + # The purpose that the message was generated with. If the purpose does not + # match, +verify+ will raise ActiveSupport::MessageVerifier::InvalidSignature. + # + # message = verifier.generate("hello", purpose: "greeting") + # verifier.verify(message, purpose: "greeting") # => "hello" + # verifier.verify(message, purpose: "chatting") # => raises InvalidSignature + # verifier.verify(message) # => raises InvalidSignature + # + # message = verifier.generate("bye") + # verifier.verify(message) # => "bye" + # verifier.verify(message, purpose: "greeting") # => raises InvalidSignature + # + def verify(message, **options) + catch_and_raise :invalid_message_format, as: InvalidSignature do + catch_and_raise :invalid_message_serialization do + catch_and_raise :invalid_message_content, as: InvalidSignature do + read_message(message, **options) + end + end + end + end + + # Generates a signed message for the provided value. + # + # The message is signed with the +MessageVerifier+'s secret. + # Returns Base64-encoded message joined with the generated signature. + # + # verifier = ActiveSupport::MessageVerifier.new("secret") + # verifier.generate("signed message") # => "BAhJIhNzaWduZWQgbWVzc2FnZQY6BkVU--f67d5f27c3ee0b8483cebf2103757455e947493b" + # + # ==== Options + # + # [+:expires_at+] + # The datetime at which the message expires. After this datetime, + # verification of the message will fail. + # + # message = verifier.generate("hello", expires_at: Time.now.tomorrow) + # verifier.verified(message) # => "hello" + # # 24 hours later... + # verifier.verified(message) # => nil + # verifier.verify(message) # => raises ActiveSupport::MessageVerifier::InvalidSignature + # + # [+:expires_in+] + # The duration for which the message is valid. After this duration has + # elapsed, verification of the message will fail. + # + # message = verifier.generate("hello", expires_in: 24.hours) + # verifier.verified(message) # => "hello" + # # 24 hours later... + # verifier.verified(message) # => nil + # verifier.verify(message) # => raises ActiveSupport::MessageVerifier::InvalidSignature + # + # [+:purpose+] + # The purpose of the message. If specified, the same purpose must be + # specified when verifying the message; otherwise, verification will fail. + # (See #verified and #verify.) + def generate(value, **options) + create_message(value, **options) + end + + def create_message(value, **options) # :nodoc: + sign_encoded(encode(serialize_with_metadata(value, **options))) + end + + def read_message(message, **options) # :nodoc: + deserialize_with_metadata(decode(extract_encoded(message)), **options) + end + + def inspect # :nodoc: + "#<#{self.class.name}:#{'%#016x' % (object_id << 1)}>" + end + + private + def decode(encoded, url_safe: @url_safe) + catch :invalid_message_format do + return super + end + super(encoded, url_safe: !url_safe) + end + + def sign_encoded(encoded) + digest = generate_digest(encoded) + encoded << SEPARATOR << digest + end + + def extract_encoded(signed) + if signed.nil? || !signed.valid_encoding? + throw :invalid_message_format, "invalid message string" + end + + if separator_index = separator_index_for(signed) + encoded = signed[0, separator_index] + digest = signed[separator_index + SEPARATOR_LENGTH, digest_length_in_hex] + end + + unless digest_matches_data?(digest, encoded) + throw :invalid_message_format, "mismatched digest" + end + + encoded + end + + def generate_digest(data) + OpenSSL::HMAC.hexdigest(@digest, @secret, data) + end + + def digest_length_in_hex + # In hexadecimal (AKA base16) it takes 4 bits to represent a character, + # hence we multiply the digest's length (in bytes) by 8 to get it in + # bits and divide by 4 to get its number of characters it hex. Well, 8 + # divided by 4 is 2. + @digest_length_in_hex ||= OpenSSL::Digest.new(@digest).digest_length * 2 + end + + def separator_at?(signed_message, index) + signed_message[index, SEPARATOR_LENGTH] == SEPARATOR + end + + def separator_index_for(signed_message) + index = signed_message.length - digest_length_in_hex - SEPARATOR_LENGTH + index unless index.negative? || !separator_at?(signed_message, index) + end + + def digest_matches_data?(digest, data) + data.present? && digest.present? && ActiveSupport::SecurityUtils.secure_compare(digest, generate_digest(data)) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/message_verifiers.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/message_verifiers.rb new file mode 100644 index 00000000..bbbd5b41 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/message_verifiers.rb @@ -0,0 +1,137 @@ +# frozen_string_literal: true + +require "active_support/messages/rotation_coordinator" + +module ActiveSupport + class MessageVerifiers < Messages::RotationCoordinator + ## + # :attr_accessor: transitional + # + # If true, the first two rotation option sets are swapped when building + # message verifiers. For example, with the following configuration, message + # verifiers will generate messages using serializer: Marshal, url_safe: true, + # and will able to verify messages that were generated using any of the + # three option sets: + # + # verifiers = ActiveSupport::MessageVerifiers.new { ... } + # verifiers.rotate(serializer: JSON, url_safe: true) + # verifiers.rotate(serializer: Marshal, url_safe: true) + # verifiers.rotate(serializer: Marshal, url_safe: false) + # verifiers.transitional = true + # + # This can be useful when performing a rolling deploy of an application, + # wherein servers that have not yet been updated must still be able to + # verify messages from updated servers. In such a scenario, first perform a + # rolling deploy with the new rotation (e.g. serializer: JSON, url_safe: true) + # as the first rotation and transitional = true. Then, after all + # servers have been updated, perform a second rolling deploy with + # transitional = false. + + ## + # :singleton-method: new + # :call-seq: new(&secret_generator) + # + # Initializes a new instance. +secret_generator+ must accept a salt, and + # return a suitable secret (string). +secret_generator+ may also accept + # arbitrary kwargs. If #rotate is called with any options matching those + # kwargs, those options will be passed to +secret_generator+ instead of to + # the message verifier. + # + # verifiers = ActiveSupport::MessageVerifiers.new do |salt, base:| + # MySecretGenerator.new(base).generate(salt) + # end + # + # verifiers.rotate(base: "...") + + ## + # :method: [] + # :call-seq: [](salt) + # + # Returns a MessageVerifier configured with a secret derived from the + # given +salt+, and options from #rotate. MessageVerifier instances will + # be memoized, so the same +salt+ will return the same instance. + + ## + # :method: []= + # :call-seq: []=(salt, verifier) + # + # Overrides a MessageVerifier instance associated with a given +salt+. + + ## + # :method: rotate + # :call-seq: + # rotate(**options) + # rotate(&block) + # + # Adds +options+ to the list of option sets. Messages will be signed using + # the first set in the list. When verifying, however, each set will be + # tried, in order, until one succeeds. + # + # Notably, the +:secret_generator+ option can specify a different secret + # generator than the one initially specified. The secret generator must + # respond to +call+, accept a salt, and return a suitable secret (string). + # The secret generator may also accept arbitrary kwargs. + # + # If any options match the kwargs of the operative secret generator, those + # options will be passed to the secret generator instead of to the message + # verifier. + # + # For fine-grained per-salt rotations, a block form is supported. The block + # will receive the salt, and should return an appropriate options Hash. The + # block may also return +nil+ to indicate that the rotation does not apply + # to the given salt. For example: + # + # verifiers = ActiveSupport::MessageVerifiers.new { ... } + # + # verifiers.rotate do |salt| + # case salt + # when :foo + # { serializer: JSON, url_safe: true } + # when :bar + # { serializer: Marshal, url_safe: true } + # end + # end + # + # verifiers.rotate(serializer: Marshal, url_safe: false) + # + # # Uses `serializer: JSON, url_safe: true`. + # # Falls back to `serializer: Marshal, url_safe: false`. + # verifiers[:foo] + # + # # Uses `serializer: Marshal, url_safe: true`. + # # Falls back to `serializer: Marshal, url_safe: false`. + # verifiers[:bar] + # + # # Uses `serializer: Marshal, url_safe: false`. + # verifiers[:baz] + + ## + # :method: rotate_defaults + # :call-seq: rotate_defaults + # + # Invokes #rotate with the default options. + + ## + # :method: clear_rotations + # :call-seq: clear_rotations + # + # Clears the list of option sets. + + ## + # :method: on_rotation + # :call-seq: on_rotation(&callback) + # + # Sets a callback to invoke when a message is verified using an option set + # other than the first. + # + # For example, this callback could log each time it is called, and thus + # indicate whether old option sets are still in use or can be removed from + # rotation. + + ## + private + def build(salt, secret_generator:, secret_generator_options:, **options) + MessageVerifier.new(secret_generator.call(salt, **secret_generator_options), **options) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/messages/codec.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/messages/codec.rb new file mode 100644 index 00000000..5d2c755e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/messages/codec.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +require "active_support/core_ext/class/attribute" +require_relative "metadata" +require_relative "serializer_with_fallback" + +module ActiveSupport + module Messages # :nodoc: + class Codec # :nodoc: + include Metadata + + class_attribute :default_serializer, default: :marshal, + instance_accessor: false, instance_predicate: false + + def initialize(**options) + @serializer = options[:serializer] || self.class.default_serializer + @serializer = SerializerWithFallback[@serializer] if @serializer.is_a?(Symbol) + @url_safe = options[:url_safe] + @force_legacy_metadata_serializer = options[:force_legacy_metadata_serializer] + end + + private + attr_reader :serializer + + def encode(data, url_safe: @url_safe) + url_safe ? ::Base64.urlsafe_encode64(data, padding: false) : ::Base64.strict_encode64(data) + end + + def decode(encoded, url_safe: @url_safe) + url_safe ? ::Base64.urlsafe_decode64(encoded) : ::Base64.strict_decode64(encoded) + rescue StandardError => error + throw :invalid_message_format, error + end + + def serialize(data) + serializer.dump(data) + end + + def deserialize(serialized) + serializer.load(serialized) + rescue StandardError => error + throw :invalid_message_serialization, error + end + + def catch_and_ignore(throwable, &block) + catch throwable do + return block.call + end + nil + end + + def catch_and_raise(throwable, as: nil, &block) + error = catch throwable do + return block.call + end + error = as.new(error.to_s) if as + raise error + end + + def use_message_serializer_for_metadata? + !@force_legacy_metadata_serializer && super + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/messages/metadata.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/messages/metadata.rb new file mode 100644 index 00000000..33b81aa9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/messages/metadata.rb @@ -0,0 +1,146 @@ +# frozen_string_literal: true + +require "time" +require "active_support/json" +require_relative "serializer_with_fallback" + +module ActiveSupport + module Messages # :nodoc: + module Metadata # :nodoc: + singleton_class.attr_accessor :use_message_serializer_for_metadata + + ENVELOPE_SERIALIZERS = [ + *SerializerWithFallback::SERIALIZERS.values, + ActiveSupport::JSON, + ::JSON, + Marshal, + ] + + TIMESTAMP_SERIALIZERS = [ + SerializerWithFallback::SERIALIZERS.fetch(:message_pack), + SerializerWithFallback::SERIALIZERS.fetch(:message_pack_allow_marshal), + ] + + ActiveSupport.on_load(:message_pack) do + ENVELOPE_SERIALIZERS << ActiveSupport::MessagePack + TIMESTAMP_SERIALIZERS << ActiveSupport::MessagePack + end + + private + def serialize_with_metadata(data, **metadata) + has_metadata = metadata.any? { |k, v| v } + + if has_metadata && !use_message_serializer_for_metadata? + data_string = serialize_to_json_safe_string(data) + envelope = wrap_in_metadata_legacy_envelope({ "message" => data_string }, **metadata) + serialize_to_json(envelope) + else + data = wrap_in_metadata_envelope({ "data" => data }, **metadata) if has_metadata + serialize(data) + end + end + + def deserialize_with_metadata(message, **expected_metadata) + if dual_serialized_metadata_envelope_json?(message) + envelope = deserialize_from_json(message) + extracted = extract_from_metadata_envelope(envelope, **expected_metadata) + deserialize_from_json_safe_string(extracted["message"]) + else + deserialized = deserialize(message) + if metadata_envelope?(deserialized) + extract_from_metadata_envelope(deserialized, **expected_metadata)["data"] + elsif expected_metadata.none? { |k, v| v } + deserialized + else + throw :invalid_message_content, "missing metadata" + end + end + end + + def use_message_serializer_for_metadata? + Metadata.use_message_serializer_for_metadata && Metadata::ENVELOPE_SERIALIZERS.include?(serializer) + end + + def wrap_in_metadata_envelope(hash, expires_at: nil, expires_in: nil, purpose: nil) + expiry = pick_expiry(expires_at, expires_in) + hash["exp"] = expiry if expiry + hash["pur"] = purpose.to_s if purpose + { "_rails" => hash } + end + + def wrap_in_metadata_legacy_envelope(hash, expires_at: nil, expires_in: nil, purpose: nil) + expiry = pick_expiry(expires_at, expires_in) + hash["exp"] = expiry + hash["pur"] = purpose + { "_rails" => hash } + end + + def extract_from_metadata_envelope(envelope, purpose: nil) + hash = envelope["_rails"] + + if hash["exp"] && Time.now.utc >= parse_expiry(hash["exp"]) + throw :invalid_message_content, "expired" + end + + if hash["pur"].to_s != purpose.to_s + throw :invalid_message_content, "mismatched purpose" + end + + hash + end + + def metadata_envelope?(object) + object.is_a?(Hash) && object.key?("_rails") + end + + def dual_serialized_metadata_envelope_json?(string) + string.start_with?('{"_rails":{"message":') + end + + def pick_expiry(expires_at, expires_in) + expiry = if expires_at + expires_at.utc + elsif expires_in + Time.now.utc.advance(seconds: expires_in) + end + + unless Metadata::TIMESTAMP_SERIALIZERS.include?(serializer) + expiry = expiry&.iso8601(3) + end + + expiry + end + + def parse_expiry(expires_at) + if !expires_at.is_a?(String) + expires_at + elsif ActiveSupport.use_standard_json_time_format + Time.iso8601(expires_at) + else + Time.parse(expires_at) + end + end + + def serialize_to_json(data) + ActiveSupport::JSON.encode(data) + end + + def deserialize_from_json(serialized) + ActiveSupport::JSON.decode(serialized) + rescue ::JSON::ParserError => error + # Throw :invalid_message_format instead of :invalid_message_serialization + # because here a parse error is due to a bad message rather than an + # incompatible `self.serializer`. + throw :invalid_message_format, error + end + + def serialize_to_json_safe_string(data) + encode(serialize(data), url_safe: false) + end + + def deserialize_from_json_safe_string(string) + deserialize(decode(string, url_safe: false)) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/messages/rotation_configuration.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/messages/rotation_configuration.rb new file mode 100644 index 00000000..eef05fe3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/messages/rotation_configuration.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module ActiveSupport + module Messages + class RotationConfiguration # :nodoc: + attr_reader :signed, :encrypted + + def initialize + @signed, @encrypted = [], [] + end + + def rotate(kind, *args, **options) + args << options unless options.empty? + case kind + when :signed + @signed << args + when :encrypted + @encrypted << args + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/messages/rotation_coordinator.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/messages/rotation_coordinator.rb new file mode 100644 index 00000000..131b479e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/messages/rotation_coordinator.rb @@ -0,0 +1,93 @@ +# frozen_string_literal: true + +require "active_support/core_ext/hash/slice" + +module ActiveSupport + module Messages + class RotationCoordinator # :nodoc: + attr_accessor :transitional + + def initialize(&secret_generator) + raise ArgumentError, "A secret generator block is required" unless secret_generator + @secret_generator = secret_generator + @rotate_options = [] + @on_rotation = nil + @codecs = {} + end + + def [](salt) + @codecs[salt] ||= build_with_rotations(salt) + end + + def []=(salt, codec) + @codecs[salt] = codec + end + + def rotate(**options, &block) + raise ArgumentError, "Options cannot be specified when using a block" if block && !options.empty? + changing_configuration! + + @rotate_options << (block || options) + + self + end + + def rotate_defaults + rotate() + end + + def clear_rotations + changing_configuration! + @rotate_options.clear + self + end + + def on_rotation(&callback) + changing_configuration! + @on_rotation = callback + end + + private + def changing_configuration! + if @codecs.any? + raise <<~MESSAGE + Cannot change #{self.class} configuration after it has already been applied. + + The configuration has been applied with the following salts: + #{@codecs.keys.map { |salt| "- #{salt.inspect}" }.join("\n")} + MESSAGE + end + end + + def normalize_options(options) + options = options.dup + + options[:secret_generator] ||= @secret_generator + + secret_generator_kwargs = options[:secret_generator].parameters. + filter_map { |type, name| name if type == :key || type == :keyreq } + options[:secret_generator_options] = options.extract!(*secret_generator_kwargs) + + options[:on_rotation] = @on_rotation + + options + end + + def build_with_rotations(salt) + rotate_options = @rotate_options.map { |options| options.is_a?(Proc) ? options.(salt) : options } + transitional = self.transitional && rotate_options.first + rotate_options.compact! + rotate_options[0..1] = rotate_options[0..1].reverse if transitional + rotate_options = rotate_options.map { |options| normalize_options(options) }.uniq + + raise "No options have been configured for #{salt}" if rotate_options.empty? + + rotate_options.map { |options| build(salt.to_s, **options) }.reduce(&:fall_back_to) + end + + def build(salt, secret_generator:, secret_generator_options:, **options) + raise NotImplementedError + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/messages/rotator.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/messages/rotator.rb new file mode 100644 index 00000000..d54a11e4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/messages/rotator.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +module ActiveSupport + module Messages + module Rotator # :nodoc: + def initialize(*args, on_rotation: nil, **options) + super(*args, **options) + @args = args + @options = options + @rotations = [] + @on_rotation = on_rotation + end + + def rotate(*args, **options) + fall_back_to build_rotation(*args, **options) + end + + def on_rotation(&on_rotation) + @on_rotation = on_rotation + self + end + + def fall_back_to(fallback) + @rotations << fallback + self + end + + def read_message(message, on_rotation: @on_rotation, **options) + if @rotations.empty? + super(message, **options) + else + thrown, error = catch_rotation_error do + return super(message, **options) + end + + @rotations.each do |rotation| + catch_rotation_error do + value = rotation.read_message(message, **options) + on_rotation&.call + return value + end + end + + throw thrown, error + end + end + + private + def build_rotation(*args, **options) + self.class.new(*args, *@args.drop(args.length), **@options, **options) + end + + def catch_rotation_error(&block) + error = catch :invalid_message_format do + error = catch :invalid_message_serialization do + return [nil, block.call] + end + return [:invalid_message_serialization, error] + end + [:invalid_message_format, error] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/messages/serializer_with_fallback.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/messages/serializer_with_fallback.rb new file mode 100644 index 00000000..dd96c6d7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/messages/serializer_with_fallback.rb @@ -0,0 +1,158 @@ +# frozen_string_literal: true + +require "active_support/core_ext/kernel/reporting" +require "active_support/notifications" + +module ActiveSupport + module Messages # :nodoc: + module SerializerWithFallback # :nodoc: + def self.[](format) + if format.to_s.include?("message_pack") && !defined?(ActiveSupport::MessagePack) + require "active_support/message_pack" + end + + SERIALIZERS.fetch(format) + end + + def load(dumped) + format = detect_format(dumped) + + if format == self.format + _load(dumped) + elsif format && fallback?(format) + payload = { serializer: SERIALIZERS.key(self), fallback: format, serialized: dumped } + ActiveSupport::Notifications.instrument("message_serializer_fallback.active_support", payload) do + payload[:deserialized] = SERIALIZERS[format]._load(dumped) + end + else + raise "Unsupported serialization format" + end + end + + private + def detect_format(dumped) + case + when MessagePackWithFallback.dumped?(dumped) + :message_pack + when MarshalWithFallback.dumped?(dumped) + :marshal + when JsonWithFallback.dumped?(dumped) + :json + end + end + + def fallback?(format) + format != :marshal + end + + module AllowMarshal + private + def fallback?(format) + super || format == :marshal + end + end + + module MarshalWithFallback + include SerializerWithFallback + extend self + + def format + :marshal + end + + def dump(object) + Marshal.dump(object) + end + + def _load(dumped) + Marshal.load(dumped) + end + + MARSHAL_SIGNATURE = "\x04\x08" + + def dumped?(dumped) + dumped.start_with?(MARSHAL_SIGNATURE) + end + end + + module JsonWithFallback + include SerializerWithFallback + extend self + + def format + :json + end + + def dump(object) + ActiveSupport::JSON.encode(object) + end + + def _load(dumped) + ActiveSupport::JSON.decode(dumped) + end + + JSON_START_WITH = /\A(?:[{\["]|-?\d|true|false|null)/ + + def dumped?(dumped) + JSON_START_WITH.match?(dumped) + end + + private + def detect_format(dumped) + # Assume JSON format if format could not be determined. + super || :json + end + end + + module JsonWithFallbackAllowMarshal + include JsonWithFallback + include AllowMarshal + extend self + end + + module MessagePackWithFallback + include SerializerWithFallback + extend self + + def format + :message_pack + end + + def dump(object) + ActiveSupport::MessagePack.dump(object) + end + + def _load(dumped) + ActiveSupport::MessagePack.load(dumped) + end + + def dumped?(dumped) + available? && ActiveSupport::MessagePack.signature?(dumped) + end + + private + def available? + return @available if defined?(@available) + silence_warnings { require "active_support/message_pack" } + @available = true + rescue LoadError + @available = false + end + end + + module MessagePackWithFallbackAllowMarshal + include MessagePackWithFallback + include AllowMarshal + extend self + end + + SERIALIZERS = { + marshal: MarshalWithFallback, + json: JsonWithFallback, + json_allow_marshal: JsonWithFallbackAllowMarshal, + message_pack: MessagePackWithFallback, + message_pack_allow_marshal: MessagePackWithFallbackAllowMarshal, + } + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/multibyte.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/multibyte.rb new file mode 100644 index 00000000..03663506 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/multibyte.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module ActiveSupport # :nodoc: + module Multibyte + autoload :Chars, "active_support/multibyte/chars" + autoload :Unicode, "active_support/multibyte/unicode" + + # The proxy class returned when calling mb_chars. You can use this accessor + # to configure your own proxy class so you can support other encodings. See + # the ActiveSupport::Multibyte::Chars implementation for an example how to + # do this. + # + # ActiveSupport::Multibyte.proxy_class = CharsForUTF32 + def self.proxy_class=(klass) + @proxy_class = klass + end + + # Returns the current proxy class. + def self.proxy_class + @proxy_class ||= ActiveSupport::Multibyte::Chars + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/multibyte/chars.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/multibyte/chars.rb new file mode 100644 index 00000000..05ced5dd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/multibyte/chars.rb @@ -0,0 +1,181 @@ +# frozen_string_literal: true + +require "active_support/json" +require "active_support/core_ext/string/access" +require "active_support/core_ext/string/behavior" +require "active_support/core_ext/module/delegation" + +module ActiveSupport # :nodoc: + module Multibyte # :nodoc: + # = Active Support \Multibyte \Chars + # + # Chars enables you to work transparently with UTF-8 encoding in the Ruby + # String class without having extensive knowledge about the encoding. A + # Chars object accepts a string upon initialization and proxies String + # methods in an encoding safe manner. All the normal String methods are also + # implemented on the proxy. + # + # String methods are proxied through the Chars object, and can be accessed + # through the +mb_chars+ method. Methods which would normally return a + # String object now return a Chars object so methods can be chained. + # + # 'The Perfect String '.mb_chars.downcase.strip + # # => # + # + # Chars objects are perfectly interchangeable with String objects as long as + # no explicit class checks are made. If certain methods do explicitly check + # the class, call +to_s+ before you pass chars objects to them. + # + # bad.explicit_checking_method 'T'.mb_chars.downcase.to_s + # + # The default Chars implementation assumes that the encoding of the string + # is UTF-8, if you want to handle different encodings you can write your own + # multibyte string handler and configure it through + # ActiveSupport::Multibyte.proxy_class. + # + # class CharsForUTF32 + # def size + # @wrapped_string.size / 4 + # end + # + # def self.accepts?(string) + # string.length % 4 == 0 + # end + # end + # + # ActiveSupport::Multibyte.proxy_class = CharsForUTF32 + class Chars + include Comparable + attr_reader :wrapped_string + alias to_s wrapped_string + alias to_str wrapped_string + + delegate :<=>, :=~, :match?, :acts_like_string?, to: :wrapped_string + + # Creates a new Chars instance by wrapping _string_. + def initialize(string) + @wrapped_string = string + if string.encoding != Encoding::UTF_8 + @wrapped_string = @wrapped_string.dup + @wrapped_string.force_encoding(Encoding::UTF_8) + end + end + + # Forward all undefined methods to the wrapped string. + def method_missing(method, ...) + result = @wrapped_string.__send__(method, ...) + if method.end_with?("!") + self if result + else + result.kind_of?(String) ? chars(result) : result + end + end + + # Returns +true+ if _obj_ responds to the given method. Private methods + # are included in the search only if the optional second parameter + # evaluates to +true+. + def respond_to_missing?(method, include_private) + @wrapped_string.respond_to?(method, include_private) + end + + # Works just like String#split, with the exception that the items + # in the resulting list are Chars instances instead of String. This makes + # chaining methods easier. + # + # 'Café périferôl'.mb_chars.split(/é/).map { |part| part.upcase.to_s } # => ["CAF", " P", "RIFERÔL"] + def split(*args) + @wrapped_string.split(*args).map { |i| self.class.new(i) } + end + + # Works like String#slice!, but returns an instance of + # Chars, or +nil+ if the string was not modified. The string will not be + # modified if the range given is out of bounds + # + # string = 'Welcome' + # string.mb_chars.slice!(3) # => # + # string # => 'Welome' + # string.mb_chars.slice!(0..3) # => # + # string # => 'me' + def slice!(*args) + string_sliced = @wrapped_string.slice!(*args) + if string_sliced + chars(string_sliced) + end + end + + # Reverses all characters in the string. + # + # 'Café'.mb_chars.reverse.to_s # => 'éfaC' + def reverse + chars(@wrapped_string.grapheme_clusters.reverse.join) + end + + # Limits the byte size of the string to a number of bytes without breaking + # characters. Usable when the storage for a string is limited for some + # reason. + # + # 'こんにちは'.mb_chars.limit(7).to_s # => "こん" + def limit(limit) + chars(@wrapped_string.truncate_bytes(limit, omission: nil)) + end + + # Capitalizes the first letter of every word, when possible. + # + # "ÉL QUE SE ENTERÓ".mb_chars.titleize.to_s # => "Él Que Se Enteró" + # "日本語".mb_chars.titleize.to_s # => "日本語" + def titleize + chars(downcase.to_s.gsub(/\b('?\S)/u) { $1.upcase }) + end + alias_method :titlecase, :titleize + + # Performs canonical decomposition on all the characters. + # + # 'é'.length # => 1 + # 'é'.mb_chars.decompose.to_s.length # => 2 + def decompose + chars(Unicode.decompose(:canonical, @wrapped_string.codepoints.to_a).pack("U*")) + end + + # Performs composition on all the characters. + # + # 'é'.length # => 1 + # 'é'.mb_chars.compose.to_s.length # => 1 + def compose + chars(Unicode.compose(@wrapped_string.codepoints.to_a).pack("U*")) + end + + # Returns the number of grapheme clusters in the string. + # + # 'क्षि'.mb_chars.length # => 4 + # 'क्षि'.mb_chars.grapheme_length # => 2 + def grapheme_length + @wrapped_string.grapheme_clusters.length + end + + # Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent + # resulting in a valid UTF-8 string. + # + # Passing +true+ will forcibly tidy all bytes, assuming that the string's + # encoding is entirely CP1252 or ISO-8859-1. + def tidy_bytes(force = false) + chars(Unicode.tidy_bytes(@wrapped_string, force)) + end + + def as_json(options = nil) # :nodoc: + to_s.as_json(options) + end + + %w(reverse tidy_bytes).each do |method| + define_method("#{method}!") do |*args| + @wrapped_string = public_send(method, *args).to_s + self + end + end + + private + def chars(string) + self.class.new(string) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/multibyte/unicode.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/multibyte/unicode.rb new file mode 100644 index 00000000..c4cb642b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/multibyte/unicode.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +module ActiveSupport + module Multibyte + module Unicode + extend self + + # The Unicode version that is supported by the implementation + UNICODE_VERSION = RbConfig::CONFIG["UNICODE_VERSION"] + + # Decompose composed characters to the decomposed form. + def decompose(type, codepoints) + if type == :compatibility + codepoints.pack("U*").unicode_normalize(:nfkd).codepoints + else + codepoints.pack("U*").unicode_normalize(:nfd).codepoints + end + end + + # Compose decomposed characters to the composed form. + def compose(codepoints) + codepoints.pack("U*").unicode_normalize(:nfc).codepoints + end + + # Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent + # resulting in a valid UTF-8 string. + # + # Passing +true+ will forcibly tidy all bytes, assuming that the string's + # encoding is entirely CP1252 or ISO-8859-1. + def tidy_bytes(string, force = false) + return string if string.empty? || string.ascii_only? + return recode_windows1252_chars(string) if force + string.scrub { |bad| recode_windows1252_chars(bad) } + end + + private + def recode_windows1252_chars(string) + string.encode(Encoding::UTF_8, Encoding::Windows_1252, invalid: :replace, undef: :replace) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/notifications.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/notifications.rb new file mode 100644 index 00000000..1a54dc24 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/notifications.rb @@ -0,0 +1,281 @@ +# frozen_string_literal: true + +require "active_support/notifications/instrumenter" +require "active_support/notifications/fanout" + +module ActiveSupport + # = \Notifications + # + # +ActiveSupport::Notifications+ provides an instrumentation API for + # Ruby. + # + # == Instrumenters + # + # To instrument an event you just need to do: + # + # ActiveSupport::Notifications.instrument('render', extra: :information) do + # render plain: 'Foo' + # end + # + # That first executes the block and then notifies all subscribers once done. + # + # In the example above +render+ is the name of the event, and the rest is called + # the _payload_. The payload is a mechanism that allows instrumenters to pass + # extra information to subscribers. Payloads consist of a hash whose contents + # are arbitrary and generally depend on the event. + # + # == Subscribers + # + # You can consume those events and the information they provide by registering + # a subscriber. + # + # ActiveSupport::Notifications.subscribe('render') do |event| + # event.name # => "render" + # event.duration # => 10 (in milliseconds) + # event.payload # => { extra: :information } + # event.allocations # => 1826 (objects) + # end + # + # +Event+ objects record CPU time and allocations. If you don't need this + # it's also possible to pass a block that accepts five arguments: + # + # ActiveSupport::Notifications.subscribe('render') do |name, start, finish, id, payload| + # name # => String, name of the event (such as 'render' from above) + # start # => Time, when the instrumented block started execution + # finish # => Time, when the instrumented block ended execution + # id # => String, unique ID for the instrumenter that fired the event + # payload # => Hash, the payload + # end + # + # Here, the +start+ and +finish+ values represent wall-clock time. If you are + # concerned about accuracy, you can register a monotonic subscriber. + # + # ActiveSupport::Notifications.monotonic_subscribe('render') do |name, start, finish, id, payload| + # name # => String, name of the event (such as 'render' from above) + # start # => Float, monotonic time when the instrumented block started execution + # finish # => Float, monotonic time when the instrumented block ended execution + # id # => String, unique ID for the instrumenter that fired the event + # payload # => Hash, the payload + # end + # + # For instance, let's store all "render" events in an array: + # + # events = [] + # + # ActiveSupport::Notifications.subscribe('render') do |event| + # events << event + # end + # + # That code returns right away, you are just subscribing to "render" events. + # The block is saved and will be called whenever someone instruments "render": + # + # ActiveSupport::Notifications.instrument('render', extra: :information) do + # render plain: 'Foo' + # end + # + # event = events.first + # event.name # => "render" + # event.duration # => 10 (in milliseconds) + # event.payload # => { extra: :information } + # event.allocations # => 1826 (objects) + # + # If an exception happens during that particular instrumentation the payload will + # have a key :exception with an array of two elements as value: a string with + # the name of the exception class, and the exception message. + # The :exception_object key of the payload will have the exception + # itself as the value: + # + # event.payload[:exception] # => ["ArgumentError", "Invalid value"] + # event.payload[:exception_object] # => # + # + # As the earlier example depicts, the class ActiveSupport::Notifications::Event + # is able to take the arguments as they come and provide an object-oriented + # interface to that data. + # + # It is also possible to pass an object which responds to call method + # as the second parameter to the subscribe method instead of a block: + # + # module ActionController + # class PageRequest + # def call(name, started, finished, unique_id, payload) + # Rails.logger.debug ['notification:', name, started, finished, unique_id, payload].join(' ') + # end + # end + # end + # + # ActiveSupport::Notifications.subscribe('process_action.action_controller', ActionController::PageRequest.new) + # + # resulting in the following output within the logs including a hash with the payload: + # + # notification: process_action.action_controller 2012-04-13 01:08:35 +0300 2012-04-13 01:08:35 +0300 af358ed7fab884532ec7 { + # controller: "Devise::SessionsController", + # action: "new", + # params: {"action"=>"new", "controller"=>"devise/sessions"}, + # format: :html, + # method: "GET", + # path: "/login/sign_in", + # status: 200, + # view_runtime: 279.3080806732178, + # db_runtime: 40.053 + # } + # + # You can also subscribe to all events whose name matches a certain regexp: + # + # ActiveSupport::Notifications.subscribe(/render/) do |*args| + # ... + # end + # + # and even pass no argument to subscribe, in which case you are subscribing + # to all events. + # + # == Temporary Subscriptions + # + # Sometimes you do not want to subscribe to an event for the entire life of + # the application. There are two ways to unsubscribe. + # + # WARNING: The instrumentation framework is designed for long-running subscribers, + # use this feature sparingly because it wipes some internal caches and that has + # a negative impact on performance. + # + # === Subscribe While a Block Runs + # + # You can subscribe to some event temporarily while some block runs. For + # example, in + # + # callback = lambda {|event| ... } + # ActiveSupport::Notifications.subscribed(callback, "sql.active_record") do + # ... + # end + # + # the callback will be called for all "sql.active_record" events instrumented + # during the execution of the block. The callback is unsubscribed automatically + # after that. + # + # To record +started+ and +finished+ values with monotonic time, + # specify the optional :monotonic option to the + # subscribed method. The :monotonic option is set + # to +false+ by default. + # + # callback = lambda {|name, started, finished, unique_id, payload| ... } + # ActiveSupport::Notifications.subscribed(callback, "sql.active_record", monotonic: true) do + # ... + # end + # + # === Manual Unsubscription + # + # The +subscribe+ method returns a subscriber object: + # + # subscriber = ActiveSupport::Notifications.subscribe("render") do |event| + # ... + # end + # + # To prevent that block from being called anymore, just unsubscribe passing + # that reference: + # + # ActiveSupport::Notifications.unsubscribe(subscriber) + # + # You can also unsubscribe by passing the name of the subscriber object. Note + # that this will unsubscribe all subscriptions with the given name: + # + # ActiveSupport::Notifications.unsubscribe("render") + # + # Subscribers using a regexp or other pattern-matching object will remain subscribed + # to all events that match their original pattern, unless those events match a string + # passed to +unsubscribe+: + # + # subscriber = ActiveSupport::Notifications.subscribe(/render/) { } + # ActiveSupport::Notifications.unsubscribe('render_template.action_view') + # subscriber.matches?('render_template.action_view') # => false + # subscriber.matches?('render_partial.action_view') # => true + # + # == Default Queue + # + # Notifications ships with a queue implementation that consumes and publishes events + # to all log subscribers. You can use any queue implementation you want. + # + module Notifications + class << self + attr_accessor :notifier + + def publish(name, *args) + notifier.publish(name, *args) + end + + def publish_event(event) # :nodoc: + notifier.publish_event(event) + end + + def instrument(name, payload = {}) + if notifier.listening?(name) + instrumenter.instrument(name, payload) { yield payload if block_given? } + else + yield payload if block_given? + end + end + + # Subscribe to a given event name with the passed +block+. + # + # You can subscribe to events by passing a String to match exact event + # names, or by passing a Regexp to match all events that match a pattern. + # + # If the block passed to the method only takes one argument, + # it will yield an +Event+ object to the block: + # + # ActiveSupport::Notifications.subscribe(/render/) do |event| + # @event = event + # end + # + # Otherwise the +block+ will receive five arguments with information + # about the event: + # + # ActiveSupport::Notifications.subscribe('render') do |name, start, finish, id, payload| + # name # => String, name of the event (such as 'render' from above) + # start # => Time, when the instrumented block started execution + # finish # => Time, when the instrumented block ended execution + # id # => String, unique ID for the instrumenter that fired the event + # payload # => Hash, the payload + # end + # + # Raises an error if invalid event name type is passed: + # + # ActiveSupport::Notifications.subscribe(:render) {|event| ...} + # #=> ArgumentError (pattern must be specified as a String, Regexp or empty) + # + def subscribe(pattern = nil, callback = nil, &block) + notifier.subscribe(pattern, callback, monotonic: false, &block) + end + + # Performs the same functionality as #subscribe, but the +start+ and + # +finish+ block arguments are in monotonic time instead of wall-clock + # time. Monotonic time will not jump forward or backward (due to NTP or + # Daylights Savings). Use +monotonic_subscribe+ when accuracy of time + # duration is important. For example, computing elapsed time between + # two events. + def monotonic_subscribe(pattern = nil, callback = nil, &block) + notifier.subscribe(pattern, callback, monotonic: true, &block) + end + + def subscribed(callback, pattern = nil, monotonic: false, &block) + subscriber = notifier.subscribe(pattern, callback, monotonic: monotonic) + yield + ensure + unsubscribe(subscriber) + end + + def unsubscribe(subscriber_or_name) + notifier.unsubscribe(subscriber_or_name) + end + + def instrumenter + registry[notifier] ||= Instrumenter.new(notifier) + end + + private + def registry + ActiveSupport::IsolatedExecutionState[:active_support_notifications_registry] ||= {} + end + end + + self.notifier = Fanout.new + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/notifications/fanout.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/notifications/fanout.rb new file mode 100644 index 00000000..ecf4b7c9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/notifications/fanout.rb @@ -0,0 +1,445 @@ +# frozen_string_literal: true + +require "concurrent/map" +require "active_support/core_ext/object/try" + +module ActiveSupport + module Notifications + class InstrumentationSubscriberError < RuntimeError + attr_reader :exceptions + + def initialize(exceptions) + @exceptions = exceptions + exception_class_names = exceptions.map { |e| e.class.name } + super "Exception(s) occurred within instrumentation subscribers: #{exception_class_names.join(', ')}" + end + end + + module FanoutIteration # :nodoc: + private + def iterate_guarding_exceptions(collection) + exceptions = nil + + collection.each do |s| + yield s + rescue Exception => e + exceptions ||= [] + exceptions << e + end + + if exceptions + exceptions = exceptions.flat_map do |exception| + exception.is_a?(InstrumentationSubscriberError) ? exception.exceptions : [exception] + end + if exceptions.size == 1 + raise exceptions.first + else + raise InstrumentationSubscriberError.new(exceptions), cause: exceptions.first + end + end + + collection + end + end + + # This is a default queue implementation that ships with Notifications. + # It just pushes events to all registered log subscribers. + # + # This class is thread safe. All methods are reentrant. + class Fanout + def initialize + @mutex = Mutex.new + @string_subscribers = Concurrent::Map.new { |h, k| h.compute_if_absent(k) { [] } } + @other_subscribers = [] + @all_listeners_for = Concurrent::Map.new + @groups_for = Concurrent::Map.new + @silenceable_groups_for = Concurrent::Map.new + end + + def inspect # :nodoc: + total_patterns = @string_subscribers.size + @other_subscribers.size + "#<#{self.class} (#{total_patterns} patterns)>" + end + + def subscribe(pattern = nil, callable = nil, monotonic: false, &block) + subscriber = Subscribers.new(pattern, callable || block, monotonic) + @mutex.synchronize do + case pattern + when String + @string_subscribers[pattern] << subscriber + clear_cache(pattern) + when NilClass, Regexp + @other_subscribers << subscriber + clear_cache + else + raise ArgumentError, "pattern must be specified as a String, Regexp or empty" + end + end + subscriber + end + + def unsubscribe(subscriber_or_name) + @mutex.synchronize do + case subscriber_or_name + when String + @string_subscribers[subscriber_or_name].clear + clear_cache(subscriber_or_name) + @other_subscribers.each { |sub| sub.unsubscribe!(subscriber_or_name) } + else + pattern = subscriber_or_name.try(:pattern) + if String === pattern + @string_subscribers[pattern].delete(subscriber_or_name) + clear_cache(pattern) + else + @other_subscribers.delete(subscriber_or_name) + clear_cache + end + end + end + end + + def clear_cache(key = nil) # :nodoc: + if key + @all_listeners_for.delete(key) + @groups_for.delete(key) + @silenceable_groups_for.delete(key) + else + @all_listeners_for.clear + @groups_for.clear + @silenceable_groups_for.clear + end + end + + class BaseGroup # :nodoc: + include FanoutIteration + + def initialize(listeners, name, id, payload) + @listeners = listeners + end + + def each(&block) + iterate_guarding_exceptions(@listeners, &block) + end + end + + class BaseTimeGroup < BaseGroup # :nodoc: + def start(name, id, payload) + @start_time = now + end + + def finish(name, id, payload) + stop_time = now + each do |listener| + listener.call(name, @start_time, stop_time, id, payload) + end + end + end + + class MonotonicTimedGroup < BaseTimeGroup # :nodoc: + private + def now + Process.clock_gettime(Process::CLOCK_MONOTONIC) + end + end + + class TimedGroup < BaseTimeGroup # :nodoc: + private + def now + Time.now + end + end + + class EventedGroup < BaseGroup # :nodoc: + def start(name, id, payload) + each do |s| + s.start(name, id, payload) + end + end + + def finish(name, id, payload) + each do |s| + s.finish(name, id, payload) + end + end + end + + class EventObjectGroup < BaseGroup # :nodoc: + def start(name, id, payload) + @event = build_event(name, id, payload) + @event.start! + end + + def finish(name, id, payload) + @event.payload = payload + @event.finish! + + each do |s| + s.call(@event) + end + end + + private + def build_event(name, id, payload) + ActiveSupport::Notifications::Event.new name, nil, nil, id, payload + end + end + + def groups_for(name) # :nodoc: + groups = @groups_for.compute_if_absent(name) do + all_listeners_for(name).reject(&:silenceable).group_by(&:group_class).transform_values do |s| + s.map(&:delegate) + end + end + + silenceable_groups = @silenceable_groups_for.compute_if_absent(name) do + all_listeners_for(name).select(&:silenceable).group_by(&:group_class).transform_values do |s| + s.map(&:delegate) + end + end + + unless silenceable_groups.empty? + groups = groups.dup + silenceable_groups.each do |group_class, subscriptions| + active_subscriptions = subscriptions.reject { |s| s.silenced?(name) } + unless active_subscriptions.empty? + groups[group_class] = (groups[group_class] || []) + active_subscriptions + end + end + end + + groups + end + + # A +Handle+ is used to record the start and finish time of event. + # + # Both #start and #finish must each be called exactly once. + # + # Where possible, it's best to use the block form: ActiveSupport::Notifications.instrument. + # +Handle+ is a low-level API intended for cases where the block form can't be used. + # + # handle = ActiveSupport::Notifications.instrumenter.build_handle("my.event", {}) + # begin + # handle.start + # # work to be instrumented + # ensure + # handle.finish + # end + class Handle + include FanoutIteration + + def initialize(notifier, name, id, payload) # :nodoc: + @name = name + @id = id + @payload = payload + @groups = notifier.groups_for(name).map do |group_klass, grouped_listeners| + group_klass.new(grouped_listeners, name, id, payload) + end + @state = :initialized + end + + def start + ensure_state! :initialized + @state = :started + + iterate_guarding_exceptions(@groups) do |group| + group.start(@name, @id, @payload) + end + end + + def finish + finish_with_values(@name, @id, @payload) + end + + def finish_with_values(name, id, payload) # :nodoc: + ensure_state! :started + @state = :finished + + iterate_guarding_exceptions(@groups) do |group| + group.finish(name, id, payload) + end + end + + private + def ensure_state!(expected) + if @state != expected + raise ArgumentError, "expected state to be #{expected.inspect} but was #{@state.inspect}" + end + end + end + + include FanoutIteration + + def build_handle(name, id, payload) + Handle.new(self, name, id, payload) + end + + def start(name, id, payload) + handle_stack = (IsolatedExecutionState[:_fanout_handle_stack] ||= []) + handle = build_handle(name, id, payload) + handle_stack << handle + handle.start + end + + def finish(name, id, payload, listeners = nil) + handle_stack = IsolatedExecutionState[:_fanout_handle_stack] + handle = handle_stack.pop + handle.finish_with_values(name, id, payload) + end + + def publish(name, *args) + iterate_guarding_exceptions(listeners_for(name)) { |s| s.publish(name, *args) } + end + + def publish_event(event) + iterate_guarding_exceptions(listeners_for(event.name)) { |s| s.publish_event(event) } + end + + def all_listeners_for(name) + # this is correctly done double-checked locking (Concurrent::Map's lookups have volatile semantics) + @all_listeners_for[name] || @mutex.synchronize do + # use synchronisation when accessing @subscribers + @all_listeners_for[name] ||= + @string_subscribers[name] + @other_subscribers.select { |s| s.subscribed_to?(name) } + end + end + + def listeners_for(name) + all_listeners_for(name).reject { |s| s.silenced?(name) } + end + + def listening?(name) + all_listeners_for(name).any? { |s| !s.silenced?(name) } + end + + # This is a sync queue, so there is no waiting. + def wait + end + + module Subscribers # :nodoc: + def self.new(pattern, listener, monotonic) + subscriber_class = monotonic ? MonotonicTimed : Timed + + if listener.respond_to?(:start) && listener.respond_to?(:finish) + subscriber_class = Evented + else + # Doing this to detect a single argument block or callable + # like `proc { |x| }` vs `proc { |*x| }`, `proc { |**x| }`, + # or `proc { |x, **y| }` + procish = listener.respond_to?(:parameters) ? listener : listener.method(:call) + + if procish.arity == 1 && procish.parameters.length == 1 + subscriber_class = EventObject + end + end + + subscriber_class.new(pattern, listener) + end + + class Matcher # :nodoc: + attr_reader :pattern, :exclusions + + def self.wrap(pattern) + if String === pattern + pattern + elsif pattern.nil? + AllMessages.new + else + new(pattern) + end + end + + def initialize(pattern) + @pattern = pattern + @exclusions = Set.new + end + + def unsubscribe!(name) + exclusions << -name if pattern === name + end + + def ===(name) + pattern === name && !exclusions.include?(name) + end + + class AllMessages + def ===(name) + true + end + + def unsubscribe!(*) + false + end + end + end + + class Evented # :nodoc: + attr_reader :pattern, :delegate, :silenceable + + def initialize(pattern, delegate) + @pattern = Matcher.wrap(pattern) + @delegate = delegate + @silenceable = delegate.respond_to?(:silenced?) + @can_publish = delegate.respond_to?(:publish) + @can_publish_event = delegate.respond_to?(:publish_event) + end + + def group_class + EventedGroup + end + + def publish(name, *args) + if @can_publish + @delegate.publish name, *args + end + end + + def publish_event(event) + if @can_publish_event + @delegate.publish_event event + else + publish(event.name, event.time, event.end, event.transaction_id, event.payload) + end + end + + def silenced?(name) + @silenceable && @delegate.silenced?(name) + end + + def subscribed_to?(name) + pattern === name + end + + def unsubscribe!(name) + pattern.unsubscribe!(name) + end + end + + class Timed < Evented # :nodoc: + def group_class + TimedGroup + end + + def publish(name, *args) + @delegate.call name, *args + end + end + + class MonotonicTimed < Timed # :nodoc: + def group_class + MonotonicTimedGroup + end + end + + class EventObject < Evented + def group_class + EventObjectGroup + end + + def publish_event(event) + @delegate.call event + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/notifications/instrumenter.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/notifications/instrumenter.rb new file mode 100644 index 00000000..6143d1b8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/notifications/instrumenter.rb @@ -0,0 +1,240 @@ +# frozen_string_literal: true + +require "active_support/core_ext/module/delegation" +require "securerandom" + +module ActiveSupport + module Notifications + # Instrumenters are stored in a thread local. + class Instrumenter + attr_reader :id + + def initialize(notifier) + unless notifier.respond_to?(:build_handle) + notifier = LegacyHandle::Wrapper.new(notifier) + end + + @id = unique_id + @notifier = notifier + end + + class LegacyHandle # :nodoc: + class Wrapper # :nodoc: + def initialize(notifier) + @notifier = notifier + end + + def build_handle(name, id, payload) + LegacyHandle.new(@notifier, name, id, payload) + end + + delegate :start, :finish, to: :@notifier + end + + def initialize(notifier, name, id, payload) + @notifier = notifier + @name = name + @id = id + @payload = payload + end + + def start + @listener_state = @notifier.start @name, @id, @payload + end + + def finish + @notifier.finish(@name, @id, @payload, @listener_state) + end + end + + # Given a block, instrument it by measuring the time taken to execute + # and publish it. Without a block, simply send a message via the + # notifier. Notice that events get sent even if an error occurs in the + # passed-in block. + def instrument(name, payload = {}) + handle = build_handle(name, payload) + handle.start + begin + yield payload if block_given? + rescue Exception => e + payload[:exception] = [e.class.name, e.message] + payload[:exception_object] = e + raise e + ensure + handle.finish + end + end + + # Returns a "handle" for an event with the given +name+ and +payload+. + # + # #start and #finish must each be called exactly once on the returned object. + # + # Where possible, it's best to use #instrument, which will record the + # start and finish of the event and correctly handle any exceptions. + # +build_handle+ is a low-level API intended for cases where using + # +instrument+ isn't possible. + # + # See ActiveSupport::Notifications::Fanout::Handle. + def build_handle(name, payload) + @notifier.build_handle(name, @id, payload) + end + + def new_event(name, payload = {}) # :nodoc: + Event.new(name, nil, nil, @id, payload) + end + + # Send a start notification with +name+ and +payload+. + def start(name, payload) + @notifier.start name, @id, payload + end + + # Send a finish notification with +name+ and +payload+. + def finish(name, payload) + @notifier.finish name, @id, payload + end + + def finish_with_state(listeners_state, name, payload) + @notifier.finish name, @id, payload, listeners_state + end + + private + def unique_id + SecureRandom.hex(10) + end + end + + class Event + attr_reader :name, :transaction_id + attr_accessor :payload + + def initialize(name, start, ending, transaction_id, payload) + @name = name + @payload = payload.dup + @time = start ? start.to_f * 1_000.0 : start + @transaction_id = transaction_id + @end = ending ? ending.to_f * 1_000.0 : ending + @cpu_time_start = 0.0 + @cpu_time_finish = 0.0 + @allocation_count_start = 0 + @allocation_count_finish = 0 + @gc_time_start = 0 + @gc_time_finish = 0 + end + + def time + @time / 1000.0 if @time + end + + def end + @end / 1000.0 if @end + end + + def record # :nodoc: + start! + begin + yield payload if block_given? + rescue Exception => e + payload[:exception] = [e.class.name, e.message] + payload[:exception_object] = e + raise e + ensure + finish! + end + end + + # Record information at the time this event starts + def start! + @time = now + @cpu_time_start = now_cpu + @gc_time_start = now_gc + @allocation_count_start = now_allocations + end + + # Record information at the time this event finishes + def finish! + @cpu_time_finish = now_cpu + @gc_time_finish = now_gc + @end = now + @allocation_count_finish = now_allocations + end + + # Returns the CPU time (in milliseconds) passed between the call to + # #start! and the call to #finish!. + def cpu_time + @cpu_time_finish - @cpu_time_start + end + + # Returns the idle time time (in milliseconds) passed between the call to + # #start! and the call to #finish!. + def idle_time + diff = duration - cpu_time + diff > 0.0 ? diff : 0.0 + end + + # Returns the number of allocations made between the call to #start! and + # the call to #finish!. + def allocations + @allocation_count_finish - @allocation_count_start + end + + # Returns the time spent in GC (in milliseconds) between the call to #start! + # and the call to #finish! + def gc_time + (@gc_time_finish - @gc_time_start) / 1_000_000.0 + end + + # Returns the difference in milliseconds between when the execution of the + # event started and when it ended. + # + # ActiveSupport::Notifications.subscribe('wait') do |event| + # @event = event + # end + # + # ActiveSupport::Notifications.instrument('wait') do + # sleep 1 + # end + # + # @event.duration # => 1000.138 + def duration + @end - @time + end + + private + def now + Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond) + end + + begin + Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :float_millisecond) + + def now_cpu + Process.clock_gettime(Process::CLOCK_THREAD_CPUTIME_ID, :float_millisecond) + end + rescue + def now_cpu + 0.0 + end + end + + if GC.respond_to?(:total_time) + def now_gc + GC.total_time + end + else + def now_gc + 0 + end + end + + if GC.stat.key?(:total_allocated_objects) + def now_allocations + GC.stat(:total_allocated_objects) + end + else # Likely on JRuby, TruffleRuby + def now_allocations + 0 + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper.rb new file mode 100644 index 00000000..0c51306b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper.rb @@ -0,0 +1,479 @@ +# frozen_string_literal: true + +module ActiveSupport + # = Number Helper + # + # Provides methods for formatting numbers into currencies, percentages, + # phone numbers, and more. + # + # Example usage in a class: + # class Topic + # include ActiveSupport::NumberHelper + # + # def price + # number_to_currency(@price) + # end + # end + # + # Example usage in a module: + # require "active_support/number_helper" + # + # module NumberFormatting + # def format_price(price) + # ActiveSupport::NumberHelper.number_to_currency(price) + # end + # end + module NumberHelper + extend ActiveSupport::Autoload + + eager_autoload do + autoload :NumberConverter + autoload :RoundingHelper + autoload :NumberToRoundedConverter + autoload :NumberToDelimitedConverter + autoload :NumberToHumanConverter + autoload :NumberToHumanSizeConverter + autoload :NumberToPhoneConverter + autoload :NumberToCurrencyConverter + autoload :NumberToPercentageConverter + end + + extend self + + # Formats +number+ into a phone number. + # + # number_to_phone(5551234) # => "555-1234" + # number_to_phone("5551234") # => "555-1234" + # number_to_phone(1235551234) # => "123-555-1234" + # number_to_phone("12x34") # => "12x34" + # + # number_to_phone(1235551234, delimiter: ".", country_code: 1, extension: 1343) + # # => "+1.123.555.1234 x 1343" + # + # ==== Options + # + # [+:area_code+] + # Whether to use parentheses for the area code. Defaults to false. + # + # number_to_phone(1235551234, area_code: true) + # # => "(123) 555-1234" + # + # [+:delimiter+] + # The digit group delimiter to use. Defaults to "-". + # + # number_to_phone(1235551234, delimiter: " ") + # # => "123 555 1234" + # + # [+:country_code+] + # A country code to prepend. + # + # number_to_phone(1235551234, country_code: 1) + # # => "+1-123-555-1234" + # + # [+:extension+] + # An extension to append. + # + # number_to_phone(1235551234, extension: 555) + # # => "123-555-1234 x 555" + # + # [+:pattern+] + # A regexp that specifies how the digits should be grouped. The first + # three captures from the regexp are treated as digit groups. + # + # number_to_phone(13312345678, pattern: /(\d{3})(\d{4})(\d{4})$/) + # # => "133-1234-5678" + # number_to_phone(75561234567, pattern: /(\d{1,4})(\d{4})(\d{4})$/, area_code: true) + # # => "(755) 6123-4567" + # + def number_to_phone(number, options = {}) + NumberToPhoneConverter.convert(number, options) + end + + # Formats a +number+ into a currency string. + # + # number_to_currency(1234567890.50) # => "$1,234,567,890.50" + # number_to_currency(1234567890.506) # => "$1,234,567,890.51" + # number_to_currency("12x34") # => "$12x34" + # + # number_to_currency(1234567890.50, unit: "£", separator: ",", delimiter: "") + # # => "£1234567890,50" + # + # The currency unit and number formatting of the current locale will be used + # unless otherwise specified via options. No currency conversion is + # performed. If the user is given a way to change their locale, they will + # also be able to change the relative value of the currency displayed with + # this helper. If your application will ever support multiple locales, you + # may want to specify a constant +:locale+ option or consider using a + # library capable of currency conversion. + # + # ==== Options + # + # [+:locale+] + # The locale to use for formatting. Defaults to the current locale. + # + # number_to_currency(1234567890.506, locale: :fr) + # # => "1 234 567 890,51 €" + # + # [+:precision+] + # The level of precision. Defaults to 2. + # + # number_to_currency(1234567890.123, precision: 3) # => "$1,234,567,890.123" + # number_to_currency(0.456789, precision: 0) # => "$0" + # + # [+:round_mode+] + # Specifies how rounding is performed. See +BigDecimal.mode+. Defaults to + # +:default+. + # + # number_to_currency(1234567890.01, precision: 0, round_mode: :up) + # # => "$1,234,567,891" + # + # [+:unit+] + # The denomination of the currency. Defaults to "$". + # + # [+:separator+] + # The decimal separator. Defaults to ".". + # + # [+:delimiter+] + # The thousands delimiter. Defaults to ",". + # + # [+:format+] + # The format for non-negative numbers. %u represents the currency, + # and %n represents the number. Defaults to "%u%n". + # + # number_to_currency(1234567890.50, format: "%n %u") + # # => "1,234,567,890.50 $" + # + # [+:negative_format+] + # The format for negative numbers. %u and %n behave the + # same as in +:format+, but %n represents the absolute value of + # the number. Defaults to the value of +:format+ prepended with -. + # + # number_to_currency(-1234567890.50, negative_format: "(%u%n)") + # # => "($1,234,567,890.50)" + # + # [+:strip_insignificant_zeros+] + # Whether to remove insignificant zeros after the decimal separator. + # Defaults to false. + # + # number_to_currency(1234567890.50, strip_insignificant_zeros: true) + # # => "$1,234,567,890.5" + # + def number_to_currency(number, options = {}) + NumberToCurrencyConverter.convert(number, options) + end + + # Formats +number+ as a percentage string. + # + # number_to_percentage(100) # => "100.000%" + # number_to_percentage("99") # => "99.000%" + # number_to_percentage("99x") # => "99x%" + # + # number_to_percentage(12345.6789, delimiter: ".", separator: ",", precision: 2) + # # => "12.345,68%" + # + # ==== Options + # + # [+:locale+] + # The locale to use for formatting. Defaults to the current locale. + # + # number_to_percentage(1000, locale: :fr) + # # => "1000,000%" + # + # [+:precision+] + # The level of precision, or +nil+ to preserve +number+'s precision. + # Defaults to 2. + # + # number_to_percentage(12.3456789, precision: 4) # => "12.3457%" + # number_to_percentage(99.999, precision: 0) # => "100%" + # number_to_percentage(99.999, precision: nil) # => "99.999%" + # + # [+:round_mode+] + # Specifies how rounding is performed. See +BigDecimal.mode+. Defaults to + # +:default+. + # + # number_to_percentage(12.3456789, precision: 4, round_mode: :down) + # # => "12.3456%" + # + # [+:significant+] + # Whether +:precision+ should be applied to significant digits instead of + # fractional digits. Defaults to false. + # + # number_to_percentage(12345.6789) # => "12345.679%" + # number_to_percentage(12345.6789, significant: true) # => "12300%" + # number_to_percentage(12345.6789, precision: 2) # => "12345.68%" + # number_to_percentage(12345.6789, precision: 2, significant: true) # => "12000%" + # + # [+:separator+] + # The decimal separator. Defaults to ".". + # + # [+:delimiter+] + # The thousands delimiter. Defaults to ",". + # + # [+:strip_insignificant_zeros+] + # Whether to remove insignificant zeros after the decimal separator. + # Defaults to false. + # + # [+:format+] + # The format of the output. %n represents the number. Defaults to + # "%n%". + # + # number_to_percentage(100, format: "%n %") + # # => "100.000 %" + # + def number_to_percentage(number, options = {}) + NumberToPercentageConverter.convert(number, options) + end + + # Formats +number+ by grouping thousands with a delimiter. + # + # number_to_delimited(12345678) # => "12,345,678" + # number_to_delimited("123456") # => "123,456" + # number_to_delimited(12345678.9876) # => "12,345,678.9876" + # number_to_delimited("12x34") # => "12x34" + # + # number_to_delimited(12345678.9876, delimiter: ".", separator: ",") + # # => "12.345.678,9876" + # + # ==== Options + # + # [+:locale+] + # The locale to use for formatting. Defaults to the current locale. + # + # number_to_delimited(12345678.05, locale: :fr) + # # => "12 345 678,05" + # + # [+:delimiter+] + # The thousands delimiter. Defaults to ",". + # + # number_to_delimited(12345678, delimiter: ".") + # # => "12.345.678" + # + # [+:separator+] + # The decimal separator. Defaults to ".". + # + # number_to_delimited(12345678.05, separator: " ") + # # => "12,345,678 05" + # + # [+:delimiter_pattern+] + # A regexp to determine the placement of delimiters. Helpful when using + # currency formats like INR. + # + # number_to_delimited("123456.78", delimiter_pattern: /(\d+?)(?=(\d\d)+(\d)(?!\d))/) + # # => "1,23,456.78" + # + def number_to_delimited(number, options = {}) + NumberToDelimitedConverter.convert(number, options) + end + + # Formats +number+ to a specific level of precision. + # + # number_to_rounded(12345.6789) # => "12345.679" + # number_to_rounded(12345.6789, precision: 2) # => "12345.68" + # number_to_rounded(12345.6789, precision: 0) # => "12345" + # number_to_rounded(12345, precision: 5) # => "12345.00000" + # + # ==== Options + # + # [+:locale+] + # The locale to use for formatting. Defaults to the current locale. + # + # number_to_rounded(111.234, locale: :fr) + # # => "111,234" + # + # [+:precision+] + # The level of precision, or +nil+ to preserve +number+'s precision. + # Defaults to 3. + # + # number_to_rounded(12345.6789, precision: nil) + # # => "12345.6789" + # + # [+:round_mode+] + # Specifies how rounding is performed. See +BigDecimal.mode+. Defaults to + # +:default+. + # + # number_to_rounded(12.34, precision: 0, round_mode: :up) + # # => "13" + # + # [+:significant+] + # Whether +:precision+ should be applied to significant digits instead of + # fractional digits. Defaults to false. + # + # number_to_rounded(12345.6789) # => "12345.679" + # number_to_rounded(12345.6789, significant: true) # => "12300" + # number_to_rounded(12345.6789, precision: 2) # => "12345.68" + # number_to_rounded(12345.6789, precision: 2, significant: true) # => "12000" + # + # [+:separator+] + # The decimal separator. Defaults to ".". + # + # [+:delimiter+] + # The thousands delimiter. Defaults to ",". + # + # [+:strip_insignificant_zeros+] + # Whether to remove insignificant zeros after the decimal separator. + # Defaults to false. + # + # number_to_rounded(12.34, strip_insignificant_zeros: false) # => "12.340" + # number_to_rounded(12.34, strip_insignificant_zeros: true) # => "12.34" + # number_to_rounded(12.3456, strip_insignificant_zeros: true) # => "12.346" + # + def number_to_rounded(number, options = {}) + NumberToRoundedConverter.convert(number, options) + end + + # Formats +number+ as bytes into a more human-friendly representation. + # Useful for reporting file sizes to users. + # + # number_to_human_size(123) # => "123 Bytes" + # number_to_human_size(1234) # => "1.21 KB" + # number_to_human_size(12345) # => "12.1 KB" + # number_to_human_size(1234567) # => "1.18 MB" + # number_to_human_size(1234567890) # => "1.15 GB" + # number_to_human_size(1234567890123) # => "1.12 TB" + # number_to_human_size(1234567890123456) # => "1.1 PB" + # number_to_human_size(1234567890123456789) # => "1.07 EB" + # + # See #number_to_human if you want to pretty-print a generic number. + # + # ==== Options + # + # [+:locale+] + # The locale to use for formatting. Defaults to the current locale. + # + # [+:precision+] + # The level of precision. Defaults to 3. + # + # number_to_human_size(123456, precision: 2) # => "120 KB" + # number_to_human_size(1234567, precision: 2) # => "1.2 MB" + # + # [+:round_mode+] + # Specifies how rounding is performed. See +BigDecimal.mode+. Defaults to + # +:default+. + # + # number_to_human_size(123456, precision: 2, round_mode: :up) + # # => "130 KB" + # + # [+:significant+] + # Whether +:precision+ should be applied to significant digits instead of + # fractional digits. Defaults to true. + # + # [+:separator+] + # The decimal separator. Defaults to ".". + # + # number_to_human_size(1234567, separator: ",") + # # => "1,18 MB" + # + # [+:delimiter+] + # The thousands delimiter. Defaults to ",". + # + # [+:strip_insignificant_zeros+] + # Whether to remove insignificant zeros after the decimal separator. + # Defaults to true. + # + def number_to_human_size(number, options = {}) + NumberToHumanSizeConverter.convert(number, options) + end + + # Formats +number+ into a more human-friendly representation. Useful for + # numbers that can become very large and too hard to read. + # + # number_to_human(123) # => "123" + # number_to_human(1234) # => "1.23 Thousand" + # number_to_human(12345) # => "12.3 Thousand" + # number_to_human(1234567) # => "1.23 Million" + # number_to_human(1234567890) # => "1.23 Billion" + # number_to_human(1234567890123) # => "1.23 Trillion" + # number_to_human(1234567890123456) # => "1.23 Quadrillion" + # number_to_human(1234567890123456789) # => "1230 Quadrillion" + # + # See #number_to_human_size if you want to pretty-print a file size. + # + # ==== Options + # + # [+:locale+] + # The locale to use for formatting. Defaults to the current locale. + # + # [+:precision+] + # The level of precision. Defaults to 3. + # + # number_to_human(123456, precision: 2) # => "120 Thousand" + # number_to_human(123456, precision: 4) # => "123.5 Thousand" + # + # [+:round_mode+] + # Specifies how rounding is performed. See +BigDecimal.mode+. Defaults to + # +:default+. + # + # number_to_human(123456, precision: 2, round_mode: :up) + # # => "130 Thousand" + # + # [+:significant+] + # Whether +:precision+ should be applied to significant digits instead of + # fractional digits. Defaults to true. + # + # [+:separator+] + # The decimal separator. Defaults to ".". + # + # number_to_human(123456, precision: 4, separator: ",") + # # => "123,5 Thousand" + # + # [+:delimiter+] + # The thousands delimiter. Defaults to ",". + # + # [+:strip_insignificant_zeros+] + # Whether to remove insignificant zeros after the decimal separator. + # Defaults to true. + # + # number_to_human(1000000) # => "1 Million" + # number_to_human(1000000, strip_insignificant_zeros: false) # => "1.00 Million" + # number_to_human(10.01) # => "10" + # number_to_human(10.01, strip_insignificant_zeros: false) # => "10.0" + # + # [+:format+] + # The format of the output. %n represents the number, and + # %u represents the quantifier (e.g., "Thousand"). Defaults to + # "%n %u". + # + # [+:units+] + # A Hash of custom unit quantifier names. + # + # number_to_human(1, units: { unit: "m", thousand: "km" }) # => "1 m" + # number_to_human(100, units: { unit: "m", thousand: "km" }) # => "100 m" + # number_to_human(1000, units: { unit: "m", thousand: "km" }) # => "1 km" + # number_to_human(100000, units: { unit: "m", thousand: "km" }) # => "100 km" + # number_to_human(10000000, units: { unit: "m", thousand: "km" }) # => "10000 km" + # + # The following keys are supported for integer units: +:unit+, +:ten+, + # +:hundred+, +:thousand+, +:million+, +:billion+, +:trillion+, + # +:quadrillion+. Additionally, the following keys are supported for + # fractional units: +:deci+, +:centi+, +:mili+, +:micro+, +:nano+, + # +:pico+, +:femto+. + # + # The Hash can also be defined as a scope in an I18n locale. For example: + # + # en: + # distance: + # centi: + # one: "centimeter" + # other: "centimeters" + # unit: + # one: "meter" + # other: "meters" + # thousand: + # one: "kilometer" + # other: "kilometers" + # + # Then it can be specified by name: + # + # number_to_human(1, units: :distance) # => "1 meter" + # number_to_human(100, units: :distance) # => "100 meters" + # number_to_human(1000, units: :distance) # => "1 kilometer" + # number_to_human(100000, units: :distance) # => "100 kilometers" + # number_to_human(10000000, units: :distance) # => "10000 kilometers" + # number_to_human(0.1, units: :distance) # => "10 centimeters" + # number_to_human(0.01, units: :distance) # => "1 centimeter" + # + def number_to_human(number, options = {}) + NumberToHumanConverter.convert(number, options) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/number_converter.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/number_converter.rb new file mode 100644 index 00000000..a68838c0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/number_converter.rb @@ -0,0 +1,190 @@ +# frozen_string_literal: true + +require "bigdecimal" +require "bigdecimal/util" +require "active_support/core_ext/big_decimal/conversions" +require "active_support/core_ext/hash/keys" +require "active_support/i18n" +require "active_support/core_ext/class/attribute" + +module ActiveSupport + module NumberHelper + class NumberConverter # :nodoc: + # Default and i18n option namespace per class + class_attribute :namespace + + # Does the object need a number that is a valid float? + class_attribute :validate_float + + attr_reader :number, :opts + + DEFAULTS = { + # Used in number_to_delimited + # These are also the defaults for 'currency', 'percentage', 'precision', and 'human' + format: { + # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5) + separator: ".", + # Delimits thousands (e.g. 1,000,000 is a million) (always in groups of three) + delimiter: ",", + # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00) + precision: 3, + # If set to true, precision will mean the number of significant digits instead + # of the number of decimal digits (1234 with precision 2 becomes 1200, 1.23543 becomes 1.2) + significant: false, + # If set, the zeros after the decimal separator will always be stripped (e.g.: 1.200 will be 1.2) + strip_insignificant_zeros: false + }, + + # Used in number_to_currency + currency: { + format: { + format: "%u%n", + negative_format: "-%u%n", + unit: "$", + # These five are to override number.format and are optional + separator: ".", + delimiter: ",", + precision: 2, + significant: false, + strip_insignificant_zeros: false + } + }, + + # Used in number_to_percentage + percentage: { + format: { + delimiter: "", + format: "%n%" + } + }, + + # Used in number_to_rounded + precision: { + format: { + delimiter: "" + } + }, + + # Used in number_to_human_size and number_to_human + human: { + format: { + # These five are to override number.format and are optional + delimiter: "", + precision: 3, + significant: true, + strip_insignificant_zeros: true + }, + # Used in number_to_human_size + storage_units: { + # Storage units output formatting. + # %u is the storage unit, %n is the number (default: 2 MB) + format: "%n %u", + units: { + byte: "Bytes", + kb: "KB", + mb: "MB", + gb: "GB", + tb: "TB" + } + }, + # Used in number_to_human + decimal_units: { + format: "%n %u", + # Decimal units output formatting + # By default we will only quantify some of the exponents + # but the commented ones might be defined or overridden + # by the user. + units: { + # femto: Quadrillionth + # pico: Trillionth + # nano: Billionth + # micro: Millionth + # mili: Thousandth + # centi: Hundredth + # deci: Tenth + unit: "", + # ten: + # one: Ten + # other: Tens + # hundred: Hundred + thousand: "Thousand", + million: "Million", + billion: "Billion", + trillion: "Trillion", + quadrillion: "Quadrillion" + } + } + } + } + + def self.convert(number, options) + new(number, options).execute + end + + def initialize(number, options) + @number = number + @opts = options.symbolize_keys + @options = nil + end + + def execute + if !number + nil + elsif validate_float? && !valid_bigdecimal + number + else + convert + end + end + + private + def options + @options ||= format_options.merge(opts) + end + + def format_options + default_format_options.merge!(i18n_format_options) + end + + def default_format_options + options = DEFAULTS[:format].dup + options.merge!(DEFAULTS[namespace][:format]) if namespace + options + end + + def i18n_format_options + locale = opts[:locale] + options = I18n.translate(:'number.format', locale: locale, default: {}).dup + + if namespace + options.merge!(I18n.translate(:"number.#{namespace}.format", locale: locale, default: {})) + end + + options + end + + def translate_number_value_with_default(key, **i18n_options) + I18n.translate(key, default: default_value(key), scope: :number, **i18n_options) + end + + def translate_in_locale(key, **i18n_options) + translate_number_value_with_default(key, locale: options[:locale], **i18n_options) + end + + def default_value(key) + key.split(".").reduce(DEFAULTS) { |defaults, k| defaults[k.to_sym] } + end + + def valid_bigdecimal + case number + when Float, Rational + number.to_d(0) + when String + BigDecimal(number, exception: false) + else + number.to_d rescue nil + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/number_to_currency_converter.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/number_to_currency_converter.rb new file mode 100644 index 00000000..543c7b4f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/number_to_currency_converter.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require "active_support/number_helper/number_converter" + +module ActiveSupport + module NumberHelper + class NumberToCurrencyConverter < NumberConverter # :nodoc: + self.namespace = :currency + + def convert + format = options[:format] + + number_d = valid_bigdecimal + if number_d + if number_d.negative? + number_d = number_d.abs + format = options[:negative_format] if (number_d * 10**options[:precision]) >= 0.5 + end + number_s = NumberToRoundedConverter.convert(number_d, options) + else + number_s = number.to_s.strip + format = options[:negative_format] if number_s.sub!(/^-/, "") + end + + format.gsub("%n", number_s).gsub("%u", options[:unit]) + end + + private + def options + @options ||= begin + defaults = default_format_options.merge(i18n_opts) + # Override negative format if format options are given + defaults[:negative_format] = "-#{opts[:format]}" if opts[:format] + defaults.merge!(opts) + end + end + + def i18n_opts + # Set International negative format if it does not exist + i18n = i18n_format_options + i18n[:negative_format] ||= "-#{i18n[:format]}" if i18n[:format] + i18n + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/number_to_delimited_converter.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/number_to_delimited_converter.rb new file mode 100644 index 00000000..4fb2fb71 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/number_to_delimited_converter.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require "active_support/number_helper/number_converter" + +module ActiveSupport + module NumberHelper + class NumberToDelimitedConverter < NumberConverter # :nodoc: + self.validate_float = true + + DEFAULT_DELIMITER_REGEX = /(\d)(?=(\d\d\d)+(?!\d))/ + + def convert + parts.join(options[:separator]) + end + + private + def parts + left, right = number.to_s.split(".") + left.gsub!(delimiter_pattern) do |digit_to_delimit| + "#{digit_to_delimit}#{options[:delimiter]}" + end + [left, right].compact + end + + def delimiter_pattern + options.fetch(:delimiter_pattern, DEFAULT_DELIMITER_REGEX) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/number_to_human_converter.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/number_to_human_converter.rb new file mode 100644 index 00000000..3f926285 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/number_to_human_converter.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +require "active_support/number_helper/number_converter" + +module ActiveSupport + module NumberHelper + class NumberToHumanConverter < NumberConverter # :nodoc: + DECIMAL_UNITS = { 0 => :unit, 1 => :ten, 2 => :hundred, 3 => :thousand, 6 => :million, 9 => :billion, 12 => :trillion, 15 => :quadrillion, + -1 => :deci, -2 => :centi, -3 => :mili, -6 => :micro, -9 => :nano, -12 => :pico, -15 => :femto } + INVERTED_DECIMAL_UNITS = DECIMAL_UNITS.invert + + self.namespace = :human + self.validate_float = true + + def convert # :nodoc: + @number = RoundingHelper.new(options).round(number) + @number = Float(number) + + # For backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files. + unless options.key?(:strip_insignificant_zeros) + options[:strip_insignificant_zeros] = true + end + + units = opts[:units] + exponent = calculate_exponent(units) + @number = number / (10**exponent) + + rounded_number = NumberToRoundedConverter.convert(number, options) + unit = determine_unit(units, exponent) + format.gsub("%n", rounded_number).gsub("%u", unit).strip + end + + private + def format + options[:format] || translate_in_locale("human.decimal_units.format") + end + + def determine_unit(units, exponent) + exp = DECIMAL_UNITS[exponent] + case units + when Hash + units[exp] || "" + when String, Symbol + I18n.translate("#{units}.#{exp}", locale: options[:locale], count: number.to_i) + else + translate_in_locale("human.decimal_units.units.#{exp}", count: number.to_i) + end + end + + def calculate_exponent(units) + exponent = number != 0 ? Math.log10(number.abs).floor : 0 + unit_exponents(units).find { |e| exponent >= e } || 0 + end + + def unit_exponents(units) + case units + when Hash + units + when String, Symbol + I18n.translate(units.to_s, locale: options[:locale], raise: true) + when nil + translate_in_locale("human.decimal_units.units", raise: true) + else + raise ArgumentError, ":units must be a Hash or String translation scope." + end.keys.map { |e_name| INVERTED_DECIMAL_UNITS[e_name] }.sort_by(&:-@) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/number_to_human_size_converter.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/number_to_human_size_converter.rb new file mode 100644 index 00000000..66688a42 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/number_to_human_size_converter.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require "active_support/number_helper/number_converter" + +module ActiveSupport + module NumberHelper + class NumberToHumanSizeConverter < NumberConverter # :nodoc: + STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb, :pb, :eb, :zb] + + self.namespace = :human + self.validate_float = true + + def convert + @number = Float(number) + + # For backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files. + unless options.key?(:strip_insignificant_zeros) + options[:strip_insignificant_zeros] = true + end + + if smaller_than_base? + number_to_format = number.to_i.to_s + else + human_size = number / (base**exponent) + number_to_format = NumberToRoundedConverter.convert(human_size, options) + end + conversion_format.gsub("%n", number_to_format).gsub("%u", unit) + end + + private + def conversion_format + translate_number_value_with_default("human.storage_units.format", locale: options[:locale], raise: true) + end + + def unit + translate_number_value_with_default(storage_unit_key, locale: options[:locale], count: number.to_i, raise: true) + end + + def storage_unit_key + key_end = smaller_than_base? ? "byte" : STORAGE_UNITS[exponent] + "human.storage_units.units.#{key_end}" + end + + def exponent + max = STORAGE_UNITS.size - 1 + exp = (Math.log(number.abs) / Math.log(base)).to_i + exp = max if exp > max # avoid overflow for the highest unit + exp + end + + def smaller_than_base? + number.to_i.abs < base + end + + def base + 1024 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/number_to_percentage_converter.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/number_to_percentage_converter.rb new file mode 100644 index 00000000..0c2e190f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/number_to_percentage_converter.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require "active_support/number_helper/number_converter" + +module ActiveSupport + module NumberHelper + class NumberToPercentageConverter < NumberConverter # :nodoc: + self.namespace = :percentage + + def convert + rounded_number = NumberToRoundedConverter.convert(number, options) + options[:format].gsub("%n", rounded_number) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/number_to_phone_converter.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/number_to_phone_converter.rb new file mode 100644 index 00000000..d104449a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/number_to_phone_converter.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require "active_support/core_ext/object/blank" +require "active_support/number_helper/number_converter" + +module ActiveSupport + module NumberHelper + class NumberToPhoneConverter < NumberConverter # :nodoc: + def convert + str = country_code(opts[:country_code]).dup + str << convert_to_phone_number(number.to_s.strip) + str << phone_ext(opts[:extension]) + end + + private + def convert_to_phone_number(number) + if opts[:area_code] + convert_with_area_code(number) + else + convert_without_area_code(number) + end + end + + def convert_with_area_code(number) + default_pattern = /(\d{1,3})(\d{3})(\d{4}$)/ + number.gsub!(regexp_pattern(default_pattern), + "(\\1) \\2#{delimiter}\\3") + number + end + + def convert_without_area_code(number) + default_pattern = /(\d{0,3})(\d{3})(\d{4})$/ + number.gsub!(regexp_pattern(default_pattern), + "\\1#{delimiter}\\2#{delimiter}\\3") + number.slice!(0, 1) if start_with_delimiter?(number) + number + end + + def start_with_delimiter?(number) + delimiter.present? && number.start_with?(delimiter) + end + + def delimiter + opts[:delimiter] || "-" + end + + def country_code(code) + code.blank? ? "" : "+#{code}#{delimiter}" + end + + def phone_ext(ext) + ext.blank? ? "" : " x #{ext}" + end + + def regexp_pattern(default_pattern) + opts.fetch :pattern, default_pattern + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/number_to_rounded_converter.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/number_to_rounded_converter.rb new file mode 100644 index 00000000..f48a5158 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/number_to_rounded_converter.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +require "active_support/number_helper/number_converter" + +module ActiveSupport + module NumberHelper + class NumberToRoundedConverter < NumberConverter # :nodoc: + self.namespace = :precision + self.validate_float = true + + def convert + helper = RoundingHelper.new(options) + rounded_number = helper.round(number) + + if precision = options[:precision] + if options[:significant] && precision > 0 + digits = helper.digit_count(rounded_number) + precision -= digits + precision = 0 if precision < 0 # don't let it be negative + end + + formatted_string = + if rounded_number.finite? + s = rounded_number.to_s("F") + a, b = s.split(".", 2) + if precision != 0 + b << "0" * precision + a << "." + a << b[0, precision] + end + a + else + # Infinity/NaN + "%f" % rounded_number + end + else + formatted_string = rounded_number + end + + delimited_number = NumberToDelimitedConverter.convert(formatted_string, options) + format_number(delimited_number) + end + + private + def strip_insignificant_zeros + options[:strip_insignificant_zeros] + end + + def format_number(number) + if strip_insignificant_zeros + escaped_separator = Regexp.escape(options[:separator]) + number.sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, "") + else + number + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/rounding_helper.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/rounding_helper.rb new file mode 100644 index 00000000..14deca13 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/number_helper/rounding_helper.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +module ActiveSupport + module NumberHelper + class RoundingHelper # :nodoc: + attr_reader :options + + def initialize(options) + @options = options + end + + def round(number) + precision = absolute_precision(number) + return number unless precision + + rounded_number = convert_to_decimal(number).round(precision, options.fetch(:round_mode, :default).to_sym) + rounded_number.zero? ? rounded_number.abs : rounded_number # prevent showing negative zeros + end + + def digit_count(number) + return 1 if number.zero? + (Math.log10(number.abs) + 1).floor + end + + private + def convert_to_decimal(number) + case number + when Float, String + BigDecimal(number.to_s) + when Rational + BigDecimal(number, digit_count(number.to_i) + options[:precision]) + else + number.to_d + end + end + + def absolute_precision(number) + if options[:significant] && options[:precision] > 0 + options[:precision] - digit_count(convert_to_decimal(number)) + else + options[:precision] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/option_merger.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/option_merger.rb new file mode 100644 index 00000000..36d99a6e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/option_merger.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require "active_support/core_ext/hash/deep_merge" + +module ActiveSupport + class OptionMerger # :nodoc: + instance_methods.each do |method| + undef_method(method) unless method.start_with?("__", "instance_eval", "class", "object_id") + end + + def initialize(context, options) + @context, @options = context, options + end + + private + def method_missing(method, *arguments, &block) + options = nil + if arguments.size == 1 && arguments.first.is_a?(Proc) + proc = arguments.shift + arguments << lambda { |*args| @options.deep_merge(proc.call(*args)) } + elsif arguments.last.respond_to?(:to_hash) + options = @options.deep_merge(arguments.pop) + else + options = @options + end + + if options + @context.__send__(method, *arguments, **options, &block) + else + @context.__send__(method, *arguments, &block) + end + end + + def respond_to_missing?(...) + @context.respond_to?(...) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/ordered_hash.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/ordered_hash.rb new file mode 100644 index 00000000..07cde368 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/ordered_hash.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +require "yaml" + +YAML.add_builtin_type("omap") do |type, val| + ActiveSupport::OrderedHash[val.map { |v| v.to_a.first }] +end + +module ActiveSupport + # DEPRECATED: +ActiveSupport::OrderedHash+ implements a hash that preserves + # insertion order. + # + # oh = ActiveSupport::OrderedHash.new + # oh[:a] = 1 + # oh[:b] = 2 + # oh.keys # => [:a, :b], this order is guaranteed + # + # Also, maps the +omap+ feature for YAML files + # (See https://yaml.org/type/omap.html) to support ordered items + # when loading from YAML. + # + # +ActiveSupport::OrderedHash+ is namespaced to prevent conflicts + # with other implementations. + class OrderedHash < ::Hash # :nodoc: + def to_yaml_type + "!tag:yaml.org,2002:omap" + end + + def encode_with(coder) + coder.represent_seq "!omap", map { |k, v| { k => v } } + end + + def select(*args, &block) + dup.tap { |hash| hash.select!(*args, &block) } + end + + def reject(*args, &block) + dup.tap { |hash| hash.reject!(*args, &block) } + end + + def nested_under_indifferent_access + self + end + + # Returns true to make sure that this hash is extractable via Array#extract_options! + def extractable_options? + true + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/ordered_options.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/ordered_options.rb new file mode 100644 index 00000000..00048325 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/ordered_options.rb @@ -0,0 +1,147 @@ +# frozen_string_literal: true + +require "active_support/core_ext/object/blank" + +module ActiveSupport + # = Ordered Options + # + # +OrderedOptions+ inherits from +Hash+ and provides dynamic accessor methods. + # + # With a +Hash+, key-value pairs are typically managed like this: + # + # h = {} + # h[:boy] = 'John' + # h[:girl] = 'Mary' + # h[:boy] # => 'John' + # h[:girl] # => 'Mary' + # h[:dog] # => nil + # + # Using +OrderedOptions+, the above code can be written as: + # + # h = ActiveSupport::OrderedOptions.new + # h.boy = 'John' + # h.girl = 'Mary' + # h.boy # => 'John' + # h.girl # => 'Mary' + # h.dog # => nil + # + # To raise an exception when the value is blank, append a + # bang to the key name, like: + # + # h.dog! # => raises KeyError: :dog is blank + # + class OrderedOptions < Hash + alias_method :_get, :[] # preserve the original #[] method + protected :_get # make it protected + + def []=(key, value) + super(key.to_sym, value) + end + + def [](key) + super(key.to_sym) + end + + def dig(key, *identifiers) + super(key.to_sym, *identifiers) + end + + def method_missing(method, *args) + if method.end_with?("=") + self[method.name.chomp("=")] = args.first + elsif method.end_with?("!") + name_string = method.name.chomp("!") + self[name_string].presence || raise(KeyError.new(":#{name_string} is blank")) + else + self[method.name] + end + end + + def respond_to_missing?(name, include_private) + true + end + + def extractable_options? + true + end + + def inspect + "#<#{self.class.name} #{super}>" + end + end + + # = Inheritable Options + # + # +InheritableOptions+ provides a constructor to build an OrderedOptions + # hash inherited from another hash. + # + # Use this if you already have some hash and you want to create a new one based on it. + # + # h = ActiveSupport::InheritableOptions.new({ girl: 'Mary', boy: 'John' }) + # h.girl # => 'Mary' + # h.boy # => 'John' + # + # If the existing hash has string keys, call Hash#symbolize_keys on it. + # + # h = ActiveSupport::InheritableOptions.new({ 'girl' => 'Mary', 'boy' => 'John' }.symbolize_keys) + # h.girl # => 'Mary' + # h.boy # => 'John' + class InheritableOptions < OrderedOptions + def initialize(parent = nil) + @parent = parent + if @parent.kind_of?(OrderedOptions) + # use the faster _get when dealing with OrderedOptions + super() { |h, k| @parent._get(k) } + elsif @parent + super() { |h, k| @parent[k] } + else + super() + @parent = {} + end + end + + def to_h + @parent.merge(self) + end + + def ==(other) + to_h == other.to_h + end + + def inspect + "#<#{self.class.name} #{to_h.inspect}>" + end + + def to_s + to_h.to_s + end + + def pretty_print(pp) + pp.pp_hash(to_h) + end + + alias_method :own_key?, :key? + private :own_key? + + def key?(key) + super || @parent.key?(key) + end + + def overridden?(key) + !!(@parent && @parent.key?(key) && own_key?(key.to_sym)) + end + + def inheritable_copy + self.class.new(self) + end + + def to_a + entries + end + + def each(&block) + to_h.each(&block) + self + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/parameter_filter.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/parameter_filter.rb new file mode 100644 index 00000000..7eeae6b2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/parameter_filter.rb @@ -0,0 +1,157 @@ +# frozen_string_literal: true + +require "active_support/core_ext/object/duplicable" +require "active_support/core_ext/array/extract" + +module ActiveSupport + # = Active Support Parameter Filter + # + # +ParameterFilter+ replaces values in a Hash-like object if their + # keys match one of the specified filters. + # + # Matching based on nested keys is possible by using dot notation, e.g. + # "credit_card.number". + # + # If a proc is given as a filter, each key and value of the Hash-like + # and of any nested Hashes will be passed to it. The value or key can + # then be mutated as desired using methods such as String#replace. + # + # # Replaces values with "[FILTERED]" for keys that match /password/i. + # ActiveSupport::ParameterFilter.new([:password]) + # + # # Replaces values with "[FILTERED]" for keys that match /foo|bar/i. + # ActiveSupport::ParameterFilter.new([:foo, "bar"]) + # + # # Replaces values for the exact key "pin" and for keys that begin with + # # "pin_". Does not match keys that otherwise include "pin" as a + # # substring, such as "shipping_id". + # ActiveSupport::ParameterFilter.new([/\Apin\z/, /\Apin_/]) + # + # # Replaces the value for :code in `{ credit_card: { code: "xxxx" } }`. + # # Does not change `{ file: { code: "xxxx" } }`. + # ActiveSupport::ParameterFilter.new(["credit_card.code"]) + # + # # Reverses values for keys that match /secret/i. + # ActiveSupport::ParameterFilter.new([-> (k, v) do + # v.reverse! if /secret/i.match?(k) + # end]) + # + class ParameterFilter + FILTERED = "[FILTERED]" # :nodoc: + + # Precompiles an array of filters that otherwise would be passed directly to + # #initialize. Depending on the quantity and types of filters, + # precompilation can improve filtering performance, especially in the case + # where the ParameterFilter instance itself cannot be retained (but the + # precompiled filters can be retained). + # + # filters = [/foo/, :bar, "nested.baz", /nested\.qux/] + # + # precompiled = ActiveSupport::ParameterFilter.precompile_filters(filters) + # # => [/(?-mix:foo)|(?i:bar)/, /(?i:nested\.baz)|(?-mix:nested\.qux)/] + # + # ActiveSupport::ParameterFilter.new(precompiled) + # + def self.precompile_filters(filters) + filters, patterns = filters.partition { |filter| filter.is_a?(Proc) } + + patterns.map! do |pattern| + pattern.is_a?(Regexp) ? pattern : "(?i:#{Regexp.escape pattern.to_s})" + end + + deep_patterns = patterns.extract! { |pattern| pattern.to_s.include?("\\.") } + + filters << Regexp.new(patterns.join("|")) if patterns.any? + filters << Regexp.new(deep_patterns.join("|")) if deep_patterns.any? + + filters + end + + # Create instance with given filters. Supported type of filters are +String+, +Regexp+, and +Proc+. + # Other types of filters are treated as +String+ using +to_s+. + # For +Proc+ filters, key, value, and optional original hash is passed to block arguments. + # + # ==== Options + # + # * :mask - A replaced object when filtered. Defaults to "[FILTERED]". + def initialize(filters = [], mask: FILTERED) + @mask = mask + compile_filters!(filters) + end + + # Mask value of +params+ if key matches one of filters. + def filter(params) + @no_filters ? params.dup : call(params) + end + + # Returns filtered value for given key. For +Proc+ filters, third block argument is not populated. + def filter_param(key, value) + @no_filters ? value : value_for_key(key, value) + end + + private + def compile_filters!(filters) + @no_filters = filters.empty? + return if @no_filters + + @regexps, strings = [], [] + @deep_regexps, deep_strings = nil, nil + @blocks = nil + + filters.each do |item| + case item + when Proc + (@blocks ||= []) << item + when Regexp + if item.to_s.include?("\\.") + (@deep_regexps ||= []) << item + else + @regexps << item + end + else + s = Regexp.escape(item.to_s) + if s.include?("\\.") + (deep_strings ||= []) << s + else + strings << s + end + end + end + + @regexps << Regexp.new(strings.join("|"), true) unless strings.empty? + (@deep_regexps ||= []) << Regexp.new(deep_strings.join("|"), true) if deep_strings + end + + def call(params, full_parent_key = nil, original_params = params) + filtered_params = params.class.new + + params.each do |key, value| + filtered_params[key] = value_for_key(key, value, full_parent_key, original_params) + end + + filtered_params + end + + def value_for_key(key, value, full_parent_key = nil, original_params = nil) + if @deep_regexps + full_key = full_parent_key ? "#{full_parent_key}.#{key}" : key.to_s + end + + if @regexps.any? { |r| r.match?(key.to_s) } + value = @mask + elsif @deep_regexps&.any? { |r| r.match?(full_key) } + value = @mask + elsif value.is_a?(Hash) + value = call(value, full_key, original_params) + elsif value.is_a?(Array) + value = value.map { |v| value_for_key(key, v, full_parent_key, original_params) } + elsif @blocks + key = key.dup if key.duplicable? + value = value.dup if value.duplicable? + @blocks.each { |b| b.arity == 2 ? b.call(key, value) : b.call(key, value, original_params) } + end + + value + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/rails.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/rails.rb new file mode 100644 index 00000000..75676a2e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/rails.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +# This is a private interface. +# +# Rails components cherry pick from Active Support as needed, but there are a +# few features that are used for sure in some way or another and it is not worth +# putting individual requires absolutely everywhere. Think blank? for example. +# +# This file is loaded by every Rails component except Active Support itself, +# but it does not belong to the Rails public interface. It is internal to +# Rails and can change anytime. + +# Defines Object#blank? and Object#present?. +require "active_support/core_ext/object/blank" + +# Support for ClassMethods and the included macro. +require "active_support/concern" + +# Defines Class#class_attribute. +require "active_support/core_ext/class/attribute" + +# Defines Module#delegate. +require "active_support/core_ext/module/delegation" + +# Defines ActiveSupport::Deprecation. +require "active_support/deprecation" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/railtie.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/railtie.rb new file mode 100644 index 00000000..eec12b37 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/railtie.rb @@ -0,0 +1,163 @@ +# frozen_string_literal: true + +require "active_support" +require "active_support/i18n_railtie" + +module ActiveSupport + class Railtie < Rails::Railtie # :nodoc: + config.active_support = ActiveSupport::OrderedOptions.new + + config.eager_load_namespaces << ActiveSupport + + initializer "active_support.deprecator", before: :load_environment_config do |app| + app.deprecators[:active_support] = ActiveSupport.deprecator + end + + initializer "active_support.isolation_level" do |app| + config.after_initialize do + if level = app.config.active_support.delete(:isolation_level) + ActiveSupport::IsolatedExecutionState.isolation_level = level + end + end + end + + initializer "active_support.raise_on_invalid_cache_expiration_time" do |app| + config.after_initialize do + if app.config.active_support.raise_on_invalid_cache_expiration_time + ActiveSupport::Cache::Store.raise_on_invalid_cache_expiration_time = true + end + end + end + + initializer "active_support.set_authenticated_message_encryption" do |app| + config.after_initialize do + unless app.config.active_support.use_authenticated_message_encryption.nil? + ActiveSupport::MessageEncryptor.use_authenticated_message_encryption = + app.config.active_support.use_authenticated_message_encryption + end + end + end + + initializer "active_support.reset_execution_context" do |app| + app.reloader.before_class_unload { ActiveSupport::ExecutionContext.clear } + app.executor.to_run { ActiveSupport::ExecutionContext.clear } + app.executor.to_complete { ActiveSupport::ExecutionContext.clear } + end + + initializer "active_support.reset_all_current_attributes_instances" do |app| + app.reloader.before_class_unload { ActiveSupport::CurrentAttributes.clear_all } + app.executor.to_run { ActiveSupport::CurrentAttributes.reset_all } + app.executor.to_complete { ActiveSupport::CurrentAttributes.reset_all } + + ActiveSupport.on_load(:active_support_test_case) do + if app.config.active_support.executor_around_test_case + require "active_support/executor/test_helper" + include ActiveSupport::Executor::TestHelper + else + require "active_support/current_attributes/test_helper" + include ActiveSupport::CurrentAttributes::TestHelper + + require "active_support/execution_context/test_helper" + include ActiveSupport::ExecutionContext::TestHelper + end + end + end + + initializer "active_support.deprecation_behavior" do |app| + if app.config.active_support.report_deprecations == false + app.deprecators.silenced = true + app.deprecators.behavior = :silence + app.deprecators.disallowed_behavior = :silence + else + if deprecation = app.config.active_support.deprecation + app.deprecators.behavior = deprecation + end + + if disallowed_deprecation = app.config.active_support.disallowed_deprecation + app.deprecators.disallowed_behavior = disallowed_deprecation + end + + if disallowed_warnings = app.config.active_support.disallowed_deprecation_warnings + app.deprecators.disallowed_warnings = disallowed_warnings + end + end + end + + # Sets the default value for Time.zone + # If assigned value cannot be matched to a TimeZone, an exception will be raised. + initializer "active_support.initialize_time_zone" do |app| + begin + TZInfo::DataSource.get + rescue TZInfo::DataSourceNotFound => e + raise e.exception('tzinfo-data is not present. Please add gem "tzinfo-data" to your Gemfile and run bundle install') + end + require "active_support/core_ext/time/zones" + Time.zone_default = Time.find_zone!(app.config.time_zone) + config.eager_load_namespaces << TZInfo + end + + initializer "active_support.to_time_preserves_timezone" do |app| + config.after_initialize do + ActiveSupport.to_time_preserves_timezone = app.config.active_support.to_time_preserves_timezone + end + end + + # Sets the default week start + # If assigned value is not a valid day symbol (e.g. :sunday, :monday, ...), an exception will be raised. + initializer "active_support.initialize_beginning_of_week" do |app| + require "active_support/core_ext/date/calculations" + beginning_of_week_default = Date.find_beginning_of_week!(app.config.beginning_of_week) + + Date.beginning_of_week_default = beginning_of_week_default + end + + initializer "active_support.require_master_key" do |app| + if app.config.respond_to?(:require_master_key) && app.config.require_master_key + begin + app.credentials.key + rescue ActiveSupport::EncryptedFile::MissingKeyError => error + $stderr.puts error.message + exit 1 + end + end + end + + initializer "active_support.set_configs" do |app| + app.config.active_support.each do |k, v| + k = "#{k}=" + ActiveSupport.public_send(k, v) if ActiveSupport.respond_to? k + end + end + + initializer "active_support.set_hash_digest_class" do |app| + config.after_initialize do + if klass = app.config.active_support.hash_digest_class + ActiveSupport::Digest.hash_digest_class = klass + end + end + end + + initializer "active_support.set_key_generator_hash_digest_class" do |app| + config.after_initialize do + if klass = app.config.active_support.key_generator_hash_digest_class + ActiveSupport::KeyGenerator.hash_digest_class = klass + end + end + end + + initializer "active_support.set_default_message_serializer" do |app| + config.after_initialize do + if message_serializer = app.config.active_support.message_serializer + ActiveSupport::Messages::Codec.default_serializer = message_serializer + end + end + end + + initializer "active_support.set_use_message_serializer_for_metadata" do |app| + config.after_initialize do + ActiveSupport::Messages::Metadata.use_message_serializer_for_metadata = + app.config.active_support.use_message_serializer_for_metadata + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/reloader.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/reloader.rb new file mode 100644 index 00000000..33257ed7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/reloader.rb @@ -0,0 +1,138 @@ +# frozen_string_literal: true + +require "active_support/execution_wrapper" +require "active_support/executor" + +module ActiveSupport + # = Active Support \Reloader + # + # This class defines several callbacks: + # + # to_prepare -- Run once at application startup, and also from + # +to_run+. + # + # to_run -- Run before a work run that is reloading. If + # +reload_classes_only_on_change+ is true (the default), the class + # unload will have already occurred. + # + # to_complete -- Run after a work run that has reloaded. If + # +reload_classes_only_on_change+ is false, the class unload will + # have occurred after the work run, but before this callback. + # + # before_class_unload -- Run immediately before the classes are + # unloaded. + # + # after_class_unload -- Run immediately after the classes are + # unloaded. + # + class Reloader < ExecutionWrapper + define_callbacks :prepare + + define_callbacks :class_unload + + # Registers a callback that will run once at application startup and every time the code is reloaded. + def self.to_prepare(*args, &block) + set_callback(:prepare, *args, &block) + end + + # Registers a callback that will run immediately before the classes are unloaded. + def self.before_class_unload(*args, &block) + set_callback(:class_unload, *args, &block) + end + + # Registers a callback that will run immediately after the classes are unloaded. + def self.after_class_unload(*args, &block) + set_callback(:class_unload, :after, *args, &block) + end + + to_run(:after) { self.class.prepare! } + + # Initiate a manual reload + def self.reload! + executor.wrap do + new.tap do |instance| + instance.run! + ensure + instance.complete! + end + end + prepare! + end + + def self.run!(reset: false) # :nodoc: + if check! + super + else + Null + end + end + + # Run the supplied block as a work unit, reloading code as needed + def self.wrap(**kwargs) + return yield if active? + + executor.wrap(**kwargs) do + instance = run! + begin + yield + ensure + instance.complete! + end + end + end + + class_attribute :executor, default: Executor + class_attribute :check, default: lambda { false } + + def self.check! # :nodoc: + @should_reload ||= check.call + end + + def self.reloaded! # :nodoc: + @should_reload = false + end + + def self.prepare! # :nodoc: + new.run_callbacks(:prepare) + end + + def initialize + super + @locked = false + end + + # Acquire the ActiveSupport::Dependencies::Interlock unload lock, + # ensuring it will be released automatically + def require_unload_lock! + unless @locked + ActiveSupport::Dependencies.interlock.start_unloading + @locked = true + end + end + + # Release the unload lock if it has been previously obtained + def release_unload_lock! + if @locked + @locked = false + ActiveSupport::Dependencies.interlock.done_unloading + end + end + + def run! # :nodoc: + super + release_unload_lock! + end + + def class_unload!(&block) # :nodoc: + require_unload_lock! + run_callbacks(:class_unload, &block) + end + + def complete! # :nodoc: + super + self.class.reloaded! + ensure + release_unload_lock! + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/rescuable.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/rescuable.rb new file mode 100644 index 00000000..470f01d9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/rescuable.rb @@ -0,0 +1,176 @@ +# frozen_string_literal: true + +require "active_support/concern" +require "active_support/core_ext/class/attribute" +require "active_support/core_ext/string/inflections" + +module ActiveSupport + # = Active Support \Rescuable + # + # Rescuable module adds support for easier exception handling. + module Rescuable + extend Concern + + included do + class_attribute :rescue_handlers, default: [] + end + + module ClassMethods + # Registers exception classes with a handler to be called by rescue_with_handler. + # + # rescue_from receives a series of exception classes or class + # names, and an exception handler specified by a trailing :with + # option containing the name of a method or a Proc object. Alternatively, a block + # can be given as the handler. + # + # Handlers that take one argument will be called with the exception, so + # that the exception can be inspected when dealing with it. + # + # Handlers are inherited. They are searched from right to left, from + # bottom to top, and up the hierarchy. The handler of the first class for + # which exception.is_a?(klass) holds true is the one invoked, if + # any. + # + # class ApplicationController < ActionController::Base + # rescue_from User::NotAuthorized, with: :deny_access + # rescue_from ActiveRecord::RecordInvalid, with: :show_record_errors + # + # rescue_from "MyApp::BaseError" do |exception| + # redirect_to root_url, alert: exception.message + # end + # + # private + # def deny_access + # head :forbidden + # end + # + # def show_record_errors(exception) + # redirect_back_or_to root_url, alert: exception.record.errors.full_messages.to_sentence + # end + # end + # + # Exceptions raised inside exception handlers are not propagated up. + def rescue_from(*klasses, with: nil, &block) + unless with + if block_given? + with = block + else + raise ArgumentError, "Need a handler. Pass the with: keyword argument or provide a block." + end + end + + klasses.each do |klass| + key = if klass.is_a?(Module) && klass.respond_to?(:===) + klass.name + elsif klass.is_a?(String) + klass + else + raise ArgumentError, "#{klass.inspect} must be an Exception class or a String referencing an Exception class" + end + + # Put the new handler at the end because the list is read in reverse. + self.rescue_handlers += [[key, with]] + end + end + + # Matches an exception to a handler based on the exception class. + # + # If no handler matches the exception, check for a handler matching the + # (optional) +exception.cause+. If no handler matches the exception or its + # cause, this returns +nil+, so you can deal with unhandled exceptions. + # Be sure to re-raise unhandled exceptions if this is what you expect. + # + # begin + # # ... + # rescue => exception + # rescue_with_handler(exception) || raise + # end + # + # Returns the exception if it was handled and +nil+ if it was not. + def rescue_with_handler(exception, object: self, visited_exceptions: []) + visited_exceptions << exception + + if handler = handler_for_rescue(exception, object: object) + handler.call exception + exception + elsif exception + if visited_exceptions.include?(exception.cause) + nil + else + rescue_with_handler(exception.cause, object: object, visited_exceptions: visited_exceptions) + end + end + end + + def handler_for_rescue(exception, object: self) # :nodoc: + case rescuer = find_rescue_handler(exception) + when Symbol + method = object.method(rescuer) + if method.arity == 0 + -> e { method.call } + else + method + end + when Proc + if rescuer.arity == 0 + -> e { object.instance_exec(&rescuer) } + else + -> e { object.instance_exec(e, &rescuer) } + end + end + end + + private + def find_rescue_handler(exception) + if exception + # Handlers are in order of declaration but the most recently declared + # is the highest priority match, so we search for matching handlers + # in reverse. + _, handler = rescue_handlers.reverse_each.detect do |class_or_name, _| + if klass = constantize_rescue_handler_class(class_or_name) + klass === exception + end + end + + handler + end + end + + def constantize_rescue_handler_class(class_or_name) + case class_or_name + when String, Symbol + begin + # Try a lexical lookup first since we support + # + # class Super + # rescue_from 'Error', with: … + # end + # + # class Sub + # class Error < StandardError; end + # end + # + # so an Error raised in Sub will hit the 'Error' handler. + const_get class_or_name + rescue NameError + class_or_name.safe_constantize + end + else + class_or_name + end + end + end + + # Delegates to the class method, but uses the instance as the subject for + # rescue_from handlers (method calls, +instance_exec+ blocks). + def rescue_with_handler(exception) + self.class.rescue_with_handler exception, object: self + end + + # Internal handler lookup. Delegates to class method. Some libraries call + # this directly, so keeping it around for compatibility. + def handler_for_rescue(exception) # :nodoc: + self.class.handler_for_rescue exception, object: self + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/secure_compare_rotator.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/secure_compare_rotator.rb new file mode 100644 index 00000000..1c203898 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/secure_compare_rotator.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require "active_support/security_utils" +require "active_support/messages/rotator" + +module ActiveSupport + # = Secure Compare Rotator + # + # The ActiveSupport::SecureCompareRotator is a wrapper around ActiveSupport::SecurityUtils.secure_compare + # and allows you to rotate a previously defined value to a new one. + # + # It can be used as follow: + # + # rotator = ActiveSupport::SecureCompareRotator.new('new_production_value') + # rotator.rotate('previous_production_value') + # rotator.secure_compare!('previous_production_value') + # + # One real use case example would be to rotate a basic auth credentials: + # + # class MyController < ApplicationController + # def authenticate_request + # rotator = ActiveSupport::SecureCompareRotator.new('new_password') + # rotator.rotate('old_password') + # + # authenticate_or_request_with_http_basic do |username, password| + # rotator.secure_compare!(password) + # rescue ActiveSupport::SecureCompareRotator::InvalidMatch + # false + # end + # end + # end + class SecureCompareRotator + include SecurityUtils + + InvalidMatch = Class.new(StandardError) + + def initialize(value, on_rotation: nil) + @value = value + @rotate_values = [] + @on_rotation = on_rotation + end + + def rotate(previous_value) + @rotate_values << previous_value + end + + def secure_compare!(other_value, on_rotation: @on_rotation) + if secure_compare(@value, other_value) + true + elsif @rotate_values.any? { |value| secure_compare(value, other_value) } + on_rotation&.call + true + else + raise InvalidMatch + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/security_utils.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/security_utils.rb new file mode 100644 index 00000000..aa004744 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/security_utils.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +module ActiveSupport + module SecurityUtils + # Constant time string comparison, for fixed length strings. + # + # The values compared should be of fixed length, such as strings + # that have already been processed by HMAC. Raises in case of length mismatch. + + if defined?(OpenSSL.fixed_length_secure_compare) + def fixed_length_secure_compare(a, b) + OpenSSL.fixed_length_secure_compare(a, b) + end + else + def fixed_length_secure_compare(a, b) + raise ArgumentError, "string length mismatch." unless a.bytesize == b.bytesize + + l = a.unpack "C#{a.bytesize}" + + res = 0 + b.each_byte { |byte| res |= byte ^ l.shift } + res == 0 + end + end + module_function :fixed_length_secure_compare + + # Secure string comparison for strings of variable length. + # + # While a timing attack would not be able to discern the content of + # a secret compared via secure_compare, it is possible to determine + # the secret length. This should be considered when using secure_compare + # to compare weak, short secrets to user input. + def secure_compare(a, b) + a.bytesize == b.bytesize && fixed_length_secure_compare(a, b) + end + module_function :secure_compare + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/string_inquirer.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/string_inquirer.rb new file mode 100644 index 00000000..9b82df19 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/string_inquirer.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module ActiveSupport + # = \String Inquirer + # + # Wrapping a string in this class gives you a prettier way to test + # for equality. The value returned by Rails.env is wrapped + # in a StringInquirer object, so instead of calling this: + # + # Rails.env == 'production' + # + # you can call this: + # + # Rails.env.production? + # + # == Instantiating a new \StringInquirer + # + # vehicle = ActiveSupport::StringInquirer.new('car') + # vehicle.car? # => true + # vehicle.bike? # => false + class StringInquirer < String + private + def respond_to_missing?(method_name, include_private = false) + method_name.end_with?("?") || super + end + + def method_missing(method_name, ...) + if method_name.end_with?("?") + self == method_name[0..-2] + else + super + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/subscriber.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/subscriber.rb new file mode 100644 index 00000000..19c28906 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/subscriber.rb @@ -0,0 +1,146 @@ +# frozen_string_literal: true + +require "active_support/notifications" + +module ActiveSupport + # = Active Support \Subscriber + # + # +ActiveSupport::Subscriber+ is an object set to consume + # ActiveSupport::Notifications. The subscriber dispatches notifications to + # a registered object based on its given namespace. + # + # An example would be an Active Record subscriber responsible for collecting + # statistics about queries: + # + # module ActiveRecord + # class StatsSubscriber < ActiveSupport::Subscriber + # attach_to :active_record + # + # def sql(event) + # Statsd.timing("sql.#{event.payload[:name]}", event.duration) + # end + # end + # end + # + # After configured, whenever a "sql.active_record" notification is + # published, it will properly dispatch the event + # (ActiveSupport::Notifications::Event) to the +sql+ method. + # + # We can detach a subscriber as well: + # + # ActiveRecord::StatsSubscriber.detach_from(:active_record) + class Subscriber + class << self + # Attach the subscriber to a namespace. + def attach_to(namespace, subscriber = new, notifier = ActiveSupport::Notifications, inherit_all: false) + @namespace = namespace + @subscriber = subscriber + @notifier = notifier + @inherit_all = inherit_all + + subscribers << subscriber + + # Add event subscribers for all existing methods on the class. + fetch_public_methods(subscriber, inherit_all).each do |event| + add_event_subscriber(event) + end + end + + # Detach the subscriber from a namespace. + def detach_from(namespace, notifier = ActiveSupport::Notifications) + @namespace = namespace + @subscriber = find_attached_subscriber + @notifier = notifier + + return unless subscriber + + subscribers.delete(subscriber) + + # Remove event subscribers of all existing methods on the class. + fetch_public_methods(subscriber, true).each do |event| + remove_event_subscriber(event) + end + + # Reset notifier so that event subscribers will not add for new methods added to the class. + @notifier = nil + end + + # Adds event subscribers for all new methods added to the class. + def method_added(event) + super + # Only public methods are added as subscribers, and only if a notifier + # has been set up. This means that subscribers will only be set up for + # classes that call #attach_to. + if public_method_defined?(event) && notifier + add_event_subscriber(event) + end + end + + def subscribers + @@subscribers ||= [] + end + + private + attr_reader :subscriber, :notifier, :namespace + + def add_event_subscriber(event) # :doc: + return if invalid_event?(event) + + pattern = prepare_pattern(event) + + # Don't add multiple subscribers (e.g. if methods are redefined). + return if pattern_subscribed?(pattern) + + subscriber.patterns[pattern] = notifier.subscribe(pattern, subscriber) + end + + def remove_event_subscriber(event) # :doc: + return if invalid_event?(event) + + pattern = prepare_pattern(event) + + return unless pattern_subscribed?(pattern) + + notifier.unsubscribe(subscriber.patterns[pattern]) + subscriber.patterns.delete(pattern) + end + + def find_attached_subscriber + subscribers.find { |attached_subscriber| attached_subscriber.instance_of?(self) } + end + + def invalid_event?(event) + %i{ start finish }.include?(event.to_sym) + end + + def prepare_pattern(event) + "#{event}.#{namespace}" + end + + def pattern_subscribed?(pattern) + subscriber.patterns.key?(pattern) + end + + def fetch_public_methods(subscriber, inherit_all) + subscriber.public_methods(inherit_all) - Subscriber.public_instance_methods(true) + end + end + + attr_reader :patterns # :nodoc: + + def initialize + @patterns = {} + super + end + + def call(event) + method = event.name[0, event.name.index(".")] + send(method, event) + end + + def publish_event(event) # :nodoc: + method = event.name[0, event.name.index(".")] + send(method, event) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/syntax_error_proxy.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/syntax_error_proxy.rb new file mode 100644 index 00000000..f778013f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/syntax_error_proxy.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require "delegate" + +module ActiveSupport + # This is a class for wrapping syntax errors. The purpose of this class + # is to enhance the backtraces on SyntaxError exceptions to include the + # source location of the syntax error. That way we can display the error + # source on error pages in development. + class SyntaxErrorProxy < DelegateClass(SyntaxError) # :nodoc: + def backtrace + parse_message_for_trace + super + end + + class BacktraceLocation < Struct.new(:path, :lineno, :to_s) # :nodoc: + def spot(_) + end + + def label + end + end + + class BacktraceLocationProxy < DelegateClass(Thread::Backtrace::Location) # :nodoc: + def initialize(loc, ex) + super(loc) + @ex = ex + end + + def spot(_) + super(@ex.__getobj__) + end + end + + def backtrace_locations + return nil if super.nil? + + parse_message_for_trace.map { |trace| + file, line = trace.match(/^(.+?):(\d+).*$/, &:captures) || trace + BacktraceLocation.new(file, line.to_i, trace) + # We have to wrap these backtrace locations because we need the + # spot information to come from the originating exception, not the + # proxy object that's generating these + } + super.map { |loc| BacktraceLocationProxy.new(loc, self) } + end + + private + def parse_message_for_trace + if __getobj__.to_s.start_with?("(eval") + # If the exception is coming from a call to eval, we need to keep + # the path of the file in which eval was called to ensure we can + # return the right source fragment to show the location of the + # error + location = __getobj__.backtrace_locations[0] + ["#{location.path}:#{location.lineno}: #{__getobj__}"] + else + __getobj__.to_s.split("\n") + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/tagged_logging.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/tagged_logging.rb new file mode 100644 index 00000000..594ea30e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/tagged_logging.rb @@ -0,0 +1,157 @@ +# frozen_string_literal: true + +require "active_support/core_ext/module/delegation" +require "active_support/core_ext/object/blank" +require "active_support/logger" + +module ActiveSupport + # = Active Support Tagged Logging + # + # Wraps any standard Logger object to provide tagging capabilities. + # + # May be called with a block: + # + # logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT)) + # logger.tagged('BCX') { logger.info 'Stuff' } # Logs "[BCX] Stuff" + # logger.tagged('BCX', "Jason") { |tagged_logger| tagged_logger.info 'Stuff' } # Logs "[BCX] [Jason] Stuff" + # logger.tagged('BCX') { logger.tagged('Jason') { logger.info 'Stuff' } } # Logs "[BCX] [Jason] Stuff" + # + # If called without a block, a new logger will be returned with applied tags: + # + # logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT)) + # logger.tagged("BCX").info "Stuff" # Logs "[BCX] Stuff" + # logger.tagged("BCX", "Jason").info "Stuff" # Logs "[BCX] [Jason] Stuff" + # logger.tagged("BCX").tagged("Jason").info "Stuff" # Logs "[BCX] [Jason] Stuff" + # + # This is used by the default Rails.logger as configured by Railties to make + # it easy to stamp log lines with subdomains, request ids, and anything else + # to aid debugging of multi-user production applications. + module TaggedLogging + module Formatter # :nodoc: + # This method is invoked when a log event occurs. + def call(severity, timestamp, progname, msg) + super(severity, timestamp, progname, tag_stack.format_message(msg)) + end + + def tagged(*tags) + pushed_count = tag_stack.push_tags(tags).size + yield self + ensure + pop_tags(pushed_count) + end + + def push_tags(*tags) + tag_stack.push_tags(tags) + end + + def pop_tags(count = 1) + tag_stack.pop_tags(count) + end + + def clear_tags! + tag_stack.clear + end + + def tag_stack + # We use our object ID here to avoid conflicting with other instances + @thread_key ||= "activesupport_tagged_logging_tags:#{object_id}" + IsolatedExecutionState[@thread_key] ||= TagStack.new + end + + def current_tags + tag_stack.tags + end + + def tags_text + tag_stack.format_message("") + end + end + + class TagStack # :nodoc: + attr_reader :tags + + def initialize + @tags = [] + @tags_string = nil + end + + def push_tags(tags) + @tags_string = nil + tags.flatten! + tags.reject!(&:blank?) + @tags.concat(tags) + tags + end + + def pop_tags(count) + @tags_string = nil + @tags.pop(count) + end + + def clear + @tags_string = nil + @tags.clear + end + + def format_message(message) + if @tags.empty? + message + elsif @tags.size == 1 + "[#{@tags[0]}] #{message}" + else + @tags_string ||= "[#{@tags.join("] [")}] " + "#{@tags_string}#{message}" + end + end + end + + module LocalTagStorage # :nodoc: + attr_accessor :tag_stack + + def self.extended(base) + base.tag_stack = TagStack.new + end + end + + # Returns an `ActiveSupport::Logger` that has already been wrapped with tagged logging concern. + def self.logger(*args, **kwargs) + new ActiveSupport::Logger.new(*args, **kwargs) + end + + def self.new(logger) + logger = logger.clone + + if logger.formatter + logger.formatter = logger.formatter.clone + + # Workaround for https://bugs.ruby-lang.org/issues/20250 + # Can be removed when Ruby 3.4 is the least supported version. + logger.formatter.object_id if logger.formatter.is_a?(Proc) + else + # Ensure we set a default formatter so we aren't extending nil! + logger.formatter = ActiveSupport::Logger::SimpleFormatter.new + end + + logger.formatter.extend Formatter + logger.extend(self) + end + + delegate :push_tags, :pop_tags, :clear_tags!, to: :formatter + + def tagged(*tags) + if block_given? + formatter.tagged(*tags) { yield self } + else + logger = ActiveSupport::TaggedLogging.new(self) + logger.formatter.extend LocalTagStorage + logger.push_tags(*formatter.current_tags, *tags) + logger + end + end + + def flush + clear_tags! + super if defined?(super) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/test_case.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/test_case.rb new file mode 100644 index 00000000..bd2847fc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/test_case.rb @@ -0,0 +1,304 @@ +# frozen_string_literal: true + +require "minitest" +require "active_support/testing/tagged_logging" +require "active_support/testing/setup_and_teardown" +require "active_support/testing/tests_without_assertions" +require "active_support/testing/assertions" +require "active_support/testing/error_reporter_assertions" +require "active_support/testing/deprecation" +require "active_support/testing/declarative" +require "active_support/testing/isolation" +require "active_support/testing/constant_lookup" +require "active_support/testing/time_helpers" +require "active_support/testing/constant_stubbing" +require "active_support/testing/file_fixtures" +require "active_support/testing/parallelization" +require "active_support/testing/parallelize_executor" +require "concurrent/utility/processor_counter" + +module ActiveSupport + class TestCase < ::Minitest::Test + Assertion = Minitest::Assertion + + class << self + # Sets the order in which test cases are run. + # + # ActiveSupport::TestCase.test_order = :random # => :random + # + # Valid values are: + # * +:random+ (to run tests in random order) + # * +:parallel+ (to run tests in parallel) + # * +:sorted+ (to run tests alphabetically by method name) + # * +:alpha+ (equivalent to +:sorted+) + def test_order=(new_order) + ActiveSupport.test_order = new_order + end + + # Returns the order in which test cases are run. + # + # ActiveSupport::TestCase.test_order # => :random + # + # Possible values are +:random+, +:parallel+, +:alpha+, +:sorted+. + # Defaults to +:random+. + def test_order + ActiveSupport.test_order ||= :random + end + + # Parallelizes the test suite. + # + # Takes a +workers+ argument that controls how many times the process + # is forked. For each process a new database will be created suffixed + # with the worker number. + # + # test-database-0 + # test-database-1 + # + # If ENV["PARALLEL_WORKERS"] is set the workers argument will be ignored + # and the environment variable will be used instead. This is useful for CI + # environments, or other environments where you may need more workers than + # you do for local testing. + # + # If the number of workers is set to +1+ or fewer, the tests will not be + # parallelized. + # + # If +workers+ is set to +:number_of_processors+, the number of workers will be + # set to the actual core count on the machine you are on. + # + # The default parallelization method is to fork processes. If you'd like to + # use threads instead you can pass with: :threads to the +parallelize+ + # method. Note the threaded parallelization does not create multiple + # databases and will not work with system tests. + # + # parallelize(workers: :number_of_processors, with: :threads) + # + # The threaded parallelization uses minitest's parallel executor directly. + # The processes parallelization uses a Ruby DRb server. + # + # Because parallelization presents an overhead, it is only enabled when the + # number of tests to run is above the +threshold+ param. The default value is + # 50, and it's configurable via +config.active_support.test_parallelization_threshold+. + def parallelize(workers: :number_of_processors, with: :processes, threshold: ActiveSupport.test_parallelization_threshold) + workers = Concurrent.processor_count if workers == :number_of_processors + workers = ENV["PARALLEL_WORKERS"].to_i if ENV["PARALLEL_WORKERS"] + + Minitest.parallel_executor = ActiveSupport::Testing::ParallelizeExecutor.new(size: workers, with: with, threshold: threshold) + end + + # Set up hook for parallel testing. This can be used if you have multiple + # databases or any behavior that needs to be run after the process is forked + # but before the tests run. + # + # Note: this feature is not available with the threaded parallelization. + # + # In your +test_helper.rb+ add the following: + # + # class ActiveSupport::TestCase + # parallelize_setup do + # # create databases + # end + # end + def parallelize_setup(&block) + ActiveSupport::Testing::Parallelization.after_fork_hook(&block) + end + + # Clean up hook for parallel testing. This can be used to drop databases + # if your app uses multiple write/read databases or other clean up before + # the tests finish. This runs before the forked process is closed. + # + # Note: this feature is not available with the threaded parallelization. + # + # In your +test_helper.rb+ add the following: + # + # class ActiveSupport::TestCase + # parallelize_teardown do + # # drop databases + # end + # end + def parallelize_teardown(&block) + ActiveSupport::Testing::Parallelization.run_cleanup_hook(&block) + end + + # :singleton-method: fixture_paths + # + # Returns the ActiveRecord::FixtureSet collection. + # + # In your +test_helper.rb+ you must have require "rails/test_help". + + # :singleton-method: fixture_paths= + # + # :call-seq: + # fixture_paths=(fixture_paths) + # + # Sets the given path to the fixture set. + # + # Can also append multiple paths. + # + # ActiveSupport::TestCase.fixture_paths << "component1/test/fixtures" + # + # In your +test_helper.rb+ you must have require "rails/test_help". + end + + alias_method :method_name, :name + + include ActiveSupport::Testing::TaggedLogging + prepend ActiveSupport::Testing::SetupAndTeardown + prepend ActiveSupport::Testing::TestsWithoutAssertions + include ActiveSupport::Testing::Assertions + include ActiveSupport::Testing::ErrorReporterAssertions + include ActiveSupport::Testing::Deprecation + include ActiveSupport::Testing::ConstantStubbing + include ActiveSupport::Testing::TimeHelpers + include ActiveSupport::Testing::FileFixtures + extend ActiveSupport::Testing::Declarative + + ## + # :method: assert_not_empty + # + # :call-seq: + # assert_not_empty(obj, msg = nil) + # + # Alias for: refute_empty[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_empty] + + # + alias :assert_not_empty :refute_empty + + ## + # :method: assert_not_equal + # + # :call-seq: + # assert_not_equal(exp, act, msg = nil) + # + # Alias for: refute_equal[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_equal] + + # + alias :assert_not_equal :refute_equal + + ## + # :method: assert_not_in_delta + # + # :call-seq: + # assert_not_in_delta(exp, act, delta = 0.001, msg = nil) + # + # Alias for: refute_in_delta[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_in_delta] + + # + alias :assert_not_in_delta :refute_in_delta + + ## + # :method: assert_not_in_epsilon + # + # :call-seq: + # assert_not_in_epsilon(a, b, epsilon = 0.001, msg = nil) + # + # Alias for: refute_in_epsilon[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_in_epsilon] + + # + alias :assert_not_in_epsilon :refute_in_epsilon + + ## + # :method: assert_not_includes + # + # :call-seq: + # assert_not_includes(collection, obj, msg = nil) + # + # Alias for: refute_includes[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_includes] + + # + alias :assert_not_includes :refute_includes + + ## + # :method: assert_not_instance_of + # + # :call-seq: + # assert_not_instance_of(cls, obj, msg = nil) + # + # Alias for: refute_instance_of[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_instance_of] + + # + alias :assert_not_instance_of :refute_instance_of + + ## + # :method: assert_not_kind_of + # + # :call-seq: + # assert_not_kind_of(cls, obj, msg = nil) + # + # Alias for: refute_kind_of[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_kind_of] + + # + alias :assert_not_kind_of :refute_kind_of + + ## + # :method: assert_no_match + # + # :call-seq: + # assert_no_match(matcher, obj, msg = nil) + # + # Alias for: refute_match[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_match] + + # + alias :assert_no_match :refute_match + + ## + # :method: assert_not_nil + # + # :call-seq: + # assert_not_nil(obj, msg = nil) + # + # Alias for: refute_nil[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_nil] + + # + alias :assert_not_nil :refute_nil + + ## + # :method: assert_not_operator + # + # :call-seq: + # assert_not_operator(o1, op, o2 = UNDEFINED, msg = nil) + # + # Alias for: refute_operator[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_operator] + + # + alias :assert_not_operator :refute_operator + + ## + # :method: assert_not_predicate + # + # :call-seq: + # assert_not_predicate(o1, op, msg = nil) + # + # Alias for: refute_predicate[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_predicate] + + # + alias :assert_not_predicate :refute_predicate + + ## + # :method: assert_not_respond_to + # + # :call-seq: + # assert_not_respond_to(obj, meth, msg = nil) + # + # Alias for: refute_respond_to[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_respond_to] + + # + alias :assert_not_respond_to :refute_respond_to + + ## + # :method: assert_not_same + # + # :call-seq: + # assert_not_same(exp, act, msg = nil) + # + # Alias for: refute_same[https://docs.seattlerb.org/minitest/Minitest/Assertions.html#method-i-refute_same] + + # + alias :assert_not_same :refute_same + + ActiveSupport.run_load_hooks(:active_support_test_case, self) + + def inspect # :nodoc: + Object.instance_method(:to_s).bind_call(self) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/assertions.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/assertions.rb new file mode 100644 index 00000000..38a9215d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/assertions.rb @@ -0,0 +1,339 @@ +# frozen_string_literal: true + +require "active_support/core_ext/enumerable" + +module ActiveSupport + module Testing + module Assertions + UNTRACKED = Object.new # :nodoc: + + # Asserts that an expression is not truthy. Passes if +object+ is +nil+ or + # +false+. "Truthy" means "considered true in a conditional" like if + # foo. + # + # assert_not nil # => true + # assert_not false # => true + # assert_not 'foo' # => Expected "foo" to be nil or false + # + # An error message can be specified. + # + # assert_not foo, 'foo should be false' + def assert_not(object, message = nil) + message ||= -> { "Expected #{mu_pp(object)} to be nil or false" } + assert !object, message + end + + # Asserts that a block raises one of +exp+. This is an enhancement of the + # standard Minitest assertion method with the ability to test error + # messages. + # + # assert_raises(ArgumentError, match: /incorrect param/i) do + # perform_service(param: 'exception') + # end + # + def assert_raises(*exp, match: nil, &block) + error = super(*exp, &block) + assert_match(match, error.message) if match + error + end + alias :assert_raise :assert_raises + + # Assertion that the block should not raise an exception. + # + # Passes if evaluated code in the yielded block raises no exception. + # + # assert_nothing_raised do + # perform_service(param: 'no_exception') + # end + def assert_nothing_raised + yield.tap { assert(true) } + rescue => error + raise Minitest::UnexpectedError.new(error) + end + + # Test numeric difference between the return value of an expression as a + # result of what is evaluated in the yielded block. + # + # assert_difference 'Article.count' do + # post :create, params: { article: {...} } + # end + # + # An arbitrary expression is passed in and evaluated. + # + # assert_difference 'Article.last.comments(:reload).size' do + # post :create, params: { comment: {...} } + # end + # + # An arbitrary positive or negative difference can be specified. + # The default is +1+. + # + # assert_difference 'Article.count', -1 do + # post :delete, params: { id: ... } + # end + # + # An array of expressions can also be passed in and evaluated. + # + # assert_difference [ 'Article.count', 'Post.count' ], 2 do + # post :create, params: { article: {...} } + # end + # + # A hash of expressions/numeric differences can also be passed in and evaluated. + # + # assert_difference ->{ Article.count } => 1, ->{ Notification.count } => 2 do + # post :create, params: { article: {...} } + # end + # + # A lambda or a list of lambdas can be passed in and evaluated: + # + # assert_difference ->{ Article.count }, 2 do + # post :create, params: { article: {...} } + # end + # + # assert_difference [->{ Article.count }, ->{ Post.count }], 2 do + # post :create, params: { article: {...} } + # end + # + # An error message can be specified. + # + # assert_difference 'Article.count', -1, 'An Article should be destroyed' do + # post :delete, params: { id: ... } + # end + def assert_difference(expression, *args, &block) + expressions = + if expression.is_a?(Hash) + message = args[0] + expression + else + difference = args[0] || 1 + message = args[1] + Array(expression).index_with(difference) + end + + exps = expressions.keys.map { |e| + e.respond_to?(:call) ? e : lambda { eval(e, block.binding) } + } + before = exps.map(&:call) + + retval = _assert_nothing_raised_or_warn("assert_difference", &block) + + expressions.zip(exps, before) do |(code, diff), exp, before_value| + actual = exp.call + rich_message = -> do + code_string = code.respond_to?(:call) ? _callable_to_source_string(code) : code + error = "`#{code_string}` didn't change by #{diff}, but by #{actual - before_value}" + error = "#{message}.\n#{error}" if message + error + end + assert_equal(before_value + diff, actual, rich_message) + end + + retval + end + + # Assertion that the numeric result of evaluating an expression is not + # changed before and after invoking the passed in block. + # + # assert_no_difference 'Article.count' do + # post :create, params: { article: invalid_attributes } + # end + # + # A lambda can be passed in and evaluated. + # + # assert_no_difference -> { Article.count } do + # post :create, params: { article: invalid_attributes } + # end + # + # An error message can be specified. + # + # assert_no_difference 'Article.count', 'An Article should not be created' do + # post :create, params: { article: invalid_attributes } + # end + # + # An array of expressions can also be passed in and evaluated. + # + # assert_no_difference [ 'Article.count', -> { Post.count } ] do + # post :create, params: { article: invalid_attributes } + # end + def assert_no_difference(expression, message = nil, &block) + assert_difference expression, 0, message, &block + end + + # Assertion that the result of evaluating an expression is changed before + # and after invoking the passed in block. + # + # assert_changes 'Status.all_good?' do + # post :create, params: { status: { ok: false } } + # end + # + # You can pass the block as a string to be evaluated in the context of + # the block. A lambda can be passed for the block as well. + # + # assert_changes -> { Status.all_good? } do + # post :create, params: { status: { ok: false } } + # end + # + # The assertion is useful to test side effects. The passed block can be + # anything that can be converted to string with #to_s. + # + # assert_changes :@object do + # @object = 42 + # end + # + # The keyword arguments +:from+ and +:to+ can be given to specify the + # expected initial value and the expected value after the block was + # executed. + # + # assert_changes :@object, from: nil, to: :foo do + # @object = :foo + # end + # + # An error message can be specified. + # + # assert_changes -> { Status.all_good? }, 'Expected the status to be bad' do + # post :create, params: { status: { incident: true } } + # end + def assert_changes(expression, message = nil, from: UNTRACKED, to: UNTRACKED, &block) + exp = expression.respond_to?(:call) ? expression : -> { eval(expression.to_s, block.binding) } + + before = exp.call + retval = _assert_nothing_raised_or_warn("assert_changes", &block) + + unless from == UNTRACKED + rich_message = -> do + error = "Expected change from #{from.inspect}, got #{before.inspect}" + error = "#{message}.\n#{error}" if message + error + end + assert from === before, rich_message + end + + after = exp.call + + rich_message = -> do + code_string = expression.respond_to?(:call) ? _callable_to_source_string(expression) : expression + error = "`#{code_string}` didn't change" + error = "#{error}. It was already #{to.inspect}" if before == to + error = "#{message}.\n#{error}" if message + error + end + refute_equal before, after, rich_message + + unless to == UNTRACKED + rich_message = -> do + error = "Expected change to #{to.inspect}, got #{after.inspect}\n" + error = "#{message}.\n#{error}" if message + error + end + assert to === after, rich_message + end + + retval + end + + # Assertion that the result of evaluating an expression is not changed before + # and after invoking the passed in block. + # + # assert_no_changes 'Status.all_good?' do + # post :create, params: { status: { ok: true } } + # end + # + # Provide the optional keyword argument +:from+ to specify the expected + # initial value. + # + # assert_no_changes -> { Status.all_good? }, from: true do + # post :create, params: { status: { ok: true } } + # end + # + # An error message can be specified. + # + # assert_no_changes -> { Status.all_good? }, 'Expected the status to be good' do + # post :create, params: { status: { ok: false } } + # end + def assert_no_changes(expression, message = nil, from: UNTRACKED, &block) + exp = expression.respond_to?(:call) ? expression : -> { eval(expression.to_s, block.binding) } + + before = exp.call + retval = _assert_nothing_raised_or_warn("assert_no_changes", &block) + + unless from == UNTRACKED + rich_message = -> do + error = "Expected initial value of #{from.inspect}, got #{before.inspect}" + error = "#{message}.\n#{error}" if message + error + end + assert from === before, rich_message + end + + after = exp.call + + rich_message = -> do + code_string = expression.respond_to?(:call) ? _callable_to_source_string(expression) : expression + error = "`#{code_string}` changed" + error = "#{message}.\n#{error}" if message + error + end + + if before.nil? + assert_nil after, rich_message + else + assert_equal before, after, rich_message + end + + retval + end + + private + def _assert_nothing_raised_or_warn(assertion, &block) + assert_nothing_raised(&block) + rescue Minitest::UnexpectedError => e + if tagged_logger && tagged_logger.warn? + warning = <<~MSG + #{self.class} - #{name}: #{e.error.class} raised. + If you expected this exception, use `assert_raises` as near to the code that raises as possible. + Other block based assertions (e.g. `#{assertion}`) can be used, as long as `assert_raises` is inside their block. + MSG + tagged_logger.warn warning + end + + raise + end + + def _callable_to_source_string(callable) + if defined?(RubyVM::InstructionSequence) && callable.is_a?(Proc) + iseq = RubyVM::InstructionSequence.of(callable) + source = + if iseq.script_lines + iseq.script_lines.join("\n") + elsif File.readable?(iseq.absolute_path) + File.read(iseq.absolute_path) + end + + return callable unless source + + location = iseq.to_a[4][:code_location] + return callable unless location + + lines = source.lines[(location[0] - 1)..(location[2] - 1)] + lines[-1] = lines[-1].byteslice(...location[3]) + lines[0] = lines[0].byteslice(location[1]...) + source = lines.join.strip + + # We ignore procs defined with do/end as they are likely multi-line anyway. + if source.start_with?("{") + source.delete_suffix!("}") + source.delete_prefix!("{") + source.strip! + # It won't read nice if the callable contains multiple + # lines, and it should be a rare occurrence anyway. + # Same if it takes arguments. + if !source.include?("\n") && !source.start_with?("|") + return source + end + end + end + + callable + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/autorun.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/autorun.rb new file mode 100644 index 00000000..d5d5fc7a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/autorun.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +require "minitest" + +Minitest.autorun diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/constant_lookup.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/constant_lookup.rb new file mode 100644 index 00000000..51167e92 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/constant_lookup.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require "active_support/concern" +require "active_support/inflector" + +module ActiveSupport + module Testing + # Resolves a constant from a minitest spec name. + # + # Given the following spec-style test: + # + # describe WidgetsController, :index do + # describe "authenticated user" do + # describe "returns widgets" do + # it "has a controller that exists" do + # assert_kind_of WidgetsController, @controller + # end + # end + # end + # end + # + # The test will have the following name: + # + # "WidgetsController::index::authenticated user::returns widgets" + # + # The constant WidgetsController can be resolved from the name. + # The following code will resolve the constant: + # + # controller = determine_constant_from_test_name(name) do |constant| + # Class === constant && constant < ::ActionController::Metal + # end + module ConstantLookup + extend ::ActiveSupport::Concern + + module ClassMethods # :nodoc: + def determine_constant_from_test_name(test_name) + names = test_name.split "::" + while names.size > 0 do + names.last.sub!(/Test$/, "") + begin + constant = names.join("::").safe_constantize + break(constant) if yield(constant) + ensure + names.pop + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/constant_stubbing.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/constant_stubbing.rb new file mode 100644 index 00000000..e0bc6dcd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/constant_stubbing.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +module ActiveSupport + module Testing + module ConstantStubbing + # Changes the value of a constant for the duration of a block. Example: + # + # # World::List::Import::LARGE_IMPORT_THRESHOLD = 5000 + # stub_const(World::List::Import, :LARGE_IMPORT_THRESHOLD, 1) do + # assert_equal 1, World::List::Import::LARGE_IMPORT_THRESHOLD + # end + # + # assert_equal 5000, World::List::Import::LARGE_IMPORT_THRESHOLD + # + # Using this method rather than forcing World::List::Import::LARGE_IMPORT_THRESHOLD = 5000 prevents + # warnings from being thrown, and ensures that the old value is returned after the test has completed. + # + # If the constant doesn't already exists, but you need it set for the duration of the block + # you can do so by passing `exists: false`. + # + # stub_const(object, :SOME_CONST, 1, exists: false) do + # assert_equal 1, SOME_CONST + # end + # + # Note: Stubbing a const will stub it across all threads. So if you have concurrent threads + # (like separate test suites running in parallel) that all depend on the same constant, it's possible + # divergent stubbing will trample on each other. + def stub_const(mod, constant, new_value, exists: true) + if exists + begin + old_value = mod.const_get(constant, false) + mod.send(:remove_const, constant) + mod.const_set(constant, new_value) + yield + ensure + mod.send(:remove_const, constant) + mod.const_set(constant, old_value) + end + else + if mod.const_defined?(constant) + raise NameError, "already defined constant #{constant} in #{mod.name}" + end + + begin + mod.const_set(constant, new_value) + yield + ensure + mod.send(:remove_const, constant) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/declarative.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/declarative.rb new file mode 100644 index 00000000..7c340368 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/declarative.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module ActiveSupport + module Testing + module Declarative + unless defined?(Spec) + # Helper to define a test method using a String. Under the hood, it replaces + # spaces with underscores and defines the test method. + # + # test "verify something" do + # ... + # end + def test(name, &block) + test_name = "test_#{name.gsub(/\s+/, '_')}".to_sym + defined = method_defined? test_name + raise "#{test_name} is already defined in #{self}" if defined + if block_given? + define_method(test_name, &block) + else + define_method(test_name) do + flunk "No implementation provided for #{name}" + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/deprecation.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/deprecation.rb new file mode 100644 index 00000000..ea307a0b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/deprecation.rb @@ -0,0 +1,82 @@ +# frozen_string_literal: true + +require "active_support/deprecation" + +module ActiveSupport + module Testing + module Deprecation + ## + # :call-seq: + # assert_deprecated(deprecator, &block) + # assert_deprecated(match, deprecator, &block) + # + # Asserts that a matching deprecation warning was emitted by the given deprecator during the execution of the yielded block. + # + # assert_deprecated(/foo/, CustomDeprecator) do + # CustomDeprecator.warn "foo should no longer be used" + # end + # + # The +match+ object may be a +Regexp+, or +String+ appearing in the message. + # + # assert_deprecated('foo', CustomDeprecator) do + # CustomDeprecator.warn "foo should no longer be used" + # end + # + # If the +match+ is omitted (or explicitly +nil+), any deprecation warning will match. + # + # assert_deprecated(CustomDeprecator) do + # CustomDeprecator.warn "foo should no longer be used" + # end + def assert_deprecated(match = nil, deprecator = nil, &block) + match, deprecator = nil, match if match.is_a?(ActiveSupport::Deprecation) + + unless deprecator + raise ArgumentError, "No deprecator given" + end + + result, warnings = collect_deprecations(deprecator, &block) + assert !warnings.empty?, "Expected a deprecation warning within the block but received none" + if match + match = Regexp.new(Regexp.escape(match)) unless match.is_a?(Regexp) + assert warnings.any? { |w| match.match?(w) }, "No deprecation warning matched #{match}: #{warnings.join(', ')}" + end + result + end + + # Asserts that no deprecation warnings are emitted by the given deprecator during the execution of the yielded block. + # + # assert_not_deprecated(CustomDeprecator) do + # CustomDeprecator.warn "message" # fails assertion + # end + # + # assert_not_deprecated(ActiveSupport::Deprecation.new) do + # CustomDeprecator.warn "message" # passes assertion, different deprecator + # end + def assert_not_deprecated(deprecator, &block) + result, deprecations = collect_deprecations(deprecator, &block) + assert deprecations.empty?, "Expected no deprecation warning within the block but received #{deprecations.size}: \n #{deprecations * "\n "}" + result + end + + # Returns the return value of the block and an array of all the deprecation warnings emitted by the given + # +deprecator+ during the execution of the yielded block. + # + # collect_deprecations(CustomDeprecator) do + # CustomDeprecator.warn "message" + # ActiveSupport::Deprecation.new.warn "other message" + # :result + # end # => [:result, ["message"]] + def collect_deprecations(deprecator) + old_behavior = deprecator.behavior + deprecations = [] + deprecator.behavior = Proc.new do |message, callstack| + deprecations << message + end + result = yield + [result, deprecations] + ensure + deprecator.behavior = old_behavior + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/error_reporter_assertions.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/error_reporter_assertions.rb new file mode 100644 index 00000000..3b7ad7cd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/error_reporter_assertions.rb @@ -0,0 +1,107 @@ +# frozen_string_literal: true + +module ActiveSupport + module Testing + module ErrorReporterAssertions + module ErrorCollector # :nodoc: + @subscribed = false + @mutex = Mutex.new + + Report = Struct.new(:error, :handled, :severity, :context, :source, keyword_init: true) + class Report + alias_method :handled?, :handled + end + + class << self + def record + subscribe + recorders = ActiveSupport::IsolatedExecutionState[:active_support_error_reporter_assertions] ||= [] + reports = [] + recorders << reports + begin + yield + reports + ensure + recorders.delete_if { |r| reports.equal?(r) } + end + end + + def report(error, **kwargs) + report = Report.new(error: error, **kwargs) + ActiveSupport::IsolatedExecutionState[:active_support_error_reporter_assertions]&.each do |reports| + reports << report + end + true + end + + private + def subscribe + return if @subscribed + @mutex.synchronize do + return if @subscribed + + if ActiveSupport.error_reporter + ActiveSupport.error_reporter.subscribe(self) + @subscribed = true + else + raise Minitest::Assertion, "No error reporter is configured" + end + end + end + end + end + + # Assertion that the block should not cause an exception to be reported + # to +Rails.error+. + # + # Passes if evaluated code in the yielded block reports no exception. + # + # assert_no_error_reported do + # perform_service(param: 'no_exception') + # end + def assert_no_error_reported(&block) + reports = ErrorCollector.record do + _assert_nothing_raised_or_warn("assert_no_error_reported", &block) + end + assert_predicate(reports, :empty?) + end + + # Assertion that the block should cause at least one exception to be reported + # to +Rails.error+. + # + # Passes if the evaluated code in the yielded block reports a matching exception. + # + # assert_error_reported(IOError) do + # Rails.error.report(IOError.new("Oops")) + # end + # + # To test further details about the reported exception, you can use the return + # value. + # + # report = assert_error_reported(IOError) do + # # ... + # end + # assert_equal "Oops", report.error.message + # assert_equal "admin", report.context[:section] + # assert_equal :warning, report.severity + # assert_predicate report, :handled? + def assert_error_reported(error_class = StandardError, &block) + reports = ErrorCollector.record do + _assert_nothing_raised_or_warn("assert_error_reported", &block) + end + + if reports.empty? + assert(false, "Expected a #{error_class.name} to be reported, but there were no errors reported.") + elsif (report = reports.find { |r| error_class === r.error }) + self.assertions += 1 + report + else + message = "Expected a #{error_class.name} to be reported, but none of the " \ + "#{reports.size} reported errors matched: \n" \ + "#{reports.map { |r| r.error.class.name }.join("\n ")}" + assert(false, message) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/file_fixtures.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/file_fixtures.rb new file mode 100644 index 00000000..4eb7a885 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/file_fixtures.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require "active_support/concern" + +module ActiveSupport + module Testing + # Adds simple access to sample files called file fixtures. + # File fixtures are normal files stored in + # ActiveSupport::TestCase.file_fixture_path. + # + # File fixtures are represented as +Pathname+ objects. + # This makes it easy to extract specific information: + # + # file_fixture("example.txt").read # get the file's content + # file_fixture("example.mp3").size # get the file size + module FileFixtures + extend ActiveSupport::Concern + + included do + class_attribute :file_fixture_path, instance_writer: false + end + + # Returns a +Pathname+ to the fixture file named +fixture_name+. + # + # Raises +ArgumentError+ if +fixture_name+ can't be found. + def file_fixture(fixture_name) + path = Pathname.new(File.join(file_fixture_path, fixture_name)) + + if path.exist? + path + else + msg = "the directory '%s' does not contain a file named '%s'" + raise ArgumentError, msg % [file_fixture_path, fixture_name] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/isolation.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/isolation.rb new file mode 100644 index 00000000..ccba6ebb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/isolation.rb @@ -0,0 +1,121 @@ +# frozen_string_literal: true + +require "active_support/testing/parallelize_executor" + +module ActiveSupport + module Testing + module Isolation + SubprocessCrashed = Class.new(StandardError) + + def self.included(klass) # :nodoc: + klass.class_eval do + parallelize_me! unless Minitest.parallel_executor.is_a?(ActiveSupport::Testing::ParallelizeExecutor) + end + end + + def self.forking_env? + !ENV["NO_FORK"] && Process.respond_to?(:fork) + end + + def run + status, serialized = run_in_isolation do + super + end + + unless status&.success? + error = SubprocessCrashed.new("Subprocess exited with an error: #{status.inspect}\noutput: #{serialized.inspect}") + error.set_backtrace(caller) + self.failures << Minitest::UnexpectedError.new(error) + return defined?(Minitest::Result) ? Minitest::Result.from(self) : dup + end + + Marshal.load(serialized) + end + + module Forking + def run_in_isolation(&blk) + IO.pipe do |read, write| + read.binmode + write.binmode + + pid = fork do + read.close + yield + begin + if error? + failures.map! { |e| + begin + Marshal.dump e + e + rescue TypeError + ex = Exception.new e.message + ex.set_backtrace e.backtrace + Minitest::UnexpectedError.new ex + end + } + end + test_result = defined?(Minitest::Result) ? Minitest::Result.from(self) : dup + result = Marshal.dump(test_result) + end + + write.puts [result].pack("m") + exit!(0) + end + + write.close + result = read.read + _, status = Process.wait2(pid) + return status, result.unpack1("m") + end + end + end + + module Subprocess + ORIG_ARGV = ARGV.dup unless defined?(ORIG_ARGV) + + # Complicated H4X to get this working in Windows / JRuby with + # no forking. + def run_in_isolation(&blk) + require "tempfile" + + if ENV["ISOLATION_TEST"] + yield + test_result = defined?(Minitest::Result) ? Minitest::Result.from(self) : dup + File.open(ENV["ISOLATION_OUTPUT"], "w") do |file| + file.puts [Marshal.dump(test_result)].pack("m") + end + exit!(0) + else + Tempfile.open("isolation") do |tmpfile| + env = { + "ISOLATION_TEST" => self.class.name, + "ISOLATION_OUTPUT" => tmpfile.path + } + + test_opts = "-n#{self.class.name}##{name}" + + load_path_args = [] + $-I.each do |p| + load_path_args << "-I" + load_path_args << File.expand_path(p) + end + + child = IO.popen([env, Gem.ruby, *load_path_args, $0, *ORIG_ARGV, test_opts]) + + status = nil + begin + _, status = Process.wait2(child.pid) + rescue Errno::ECHILD # The child process may exit before we wait + nil + end + + return status, tmpfile.read.unpack1("m") + end + end + end + end + + include forking_env? ? Forking : Subprocess + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/method_call_assertions.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/method_call_assertions.rb new file mode 100644 index 00000000..2992164a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/method_call_assertions.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +require "minitest/mock" + +module ActiveSupport + module Testing + module MethodCallAssertions # :nodoc: + private + def assert_called(object, method_name, message = nil, times: 1, returns: nil, &block) + times_called = 0 + + object.stub(method_name, proc { times_called += 1; returns }, &block) + + error = "Expected #{method_name} to be called #{times} times, " \ + "but was called #{times_called} times" + error = "#{message}.\n#{error}" if message + assert_equal times, times_called, error + end + + def assert_called_with(object, method_name, args, returns: false, **kwargs, &block) + mock = Minitest::Mock.new + expect_called_with(mock, args, returns: returns, **kwargs) + + object.stub(method_name, mock, &block) + + assert_mock(mock) + end + + def assert_not_called(object, method_name, message = nil, &block) + assert_called(object, method_name, message, times: 0, &block) + end + + def expect_called_with(mock, args, returns: false, **kwargs) + mock.expect(:call, returns, args, **kwargs) + end + + def assert_called_on_instance_of(klass, method_name, message = nil, times: 1, returns: nil) + times_called = 0 + klass.define_method("stubbed_#{method_name}") do |*| + times_called += 1 + + returns + end + + klass.alias_method "original_#{method_name}", method_name + klass.alias_method method_name, "stubbed_#{method_name}" + + yield + + error = "Expected #{method_name} to be called #{times} times, but was called #{times_called} times" + error = "#{message}.\n#{error}" if message + + assert_equal times, times_called, error + ensure + klass.alias_method method_name, "original_#{method_name}" + klass.undef_method "original_#{method_name}" + klass.undef_method "stubbed_#{method_name}" + end + + def assert_not_called_on_instance_of(klass, method_name, message = nil, &block) + assert_called_on_instance_of(klass, method_name, message, times: 0, &block) + end + + def stub_any_instance(klass, instance: klass.new) + klass.stub(:new, instance) { yield instance } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/parallelization.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/parallelization.rb new file mode 100644 index 00000000..d1b2734c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/parallelization.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +require "drb" +require "drb/unix" unless Gem.win_platform? +require "active_support/core_ext/module/attribute_accessors" +require "active_support/testing/parallelization/server" +require "active_support/testing/parallelization/worker" + +module ActiveSupport + module Testing + class Parallelization # :nodoc: + @@after_fork_hooks = [] + + def self.after_fork_hook(&blk) + @@after_fork_hooks << blk + end + + cattr_reader :after_fork_hooks + + @@run_cleanup_hooks = [] + + def self.run_cleanup_hook(&blk) + @@run_cleanup_hooks << blk + end + + cattr_reader :run_cleanup_hooks + + def initialize(worker_count) + @worker_count = worker_count + @queue_server = Server.new + @worker_pool = [] + @url = DRb.start_service("drbunix:", @queue_server).uri + end + + def start + @worker_pool = @worker_count.times.map do |worker| + Worker.new(worker, @url).start + end + end + + def <<(work) + @queue_server << work + end + + def size + @worker_count + end + + def shutdown + @queue_server.shutdown + @worker_pool.each { |pid| Process.waitpid pid } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/parallelization/server.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/parallelization/server.rb new file mode 100644 index 00000000..dc70c961 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/parallelization/server.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +require "drb" +require "drb/unix" unless Gem.win_platform? + +module ActiveSupport + module Testing + class Parallelization # :nodoc: + PrerecordResultClass = Struct.new(:name) + + class Server + include DRb::DRbUndumped + + def initialize + @queue = Queue.new + @active_workers = Concurrent::Map.new + @in_flight = Concurrent::Map.new + end + + def record(reporter, result) + raise DRb::DRbConnError if result.is_a?(DRb::DRbUnknown) + + @in_flight.delete([result.klass, result.name]) + + reporter.synchronize do + reporter.prerecord(PrerecordResultClass.new(result.klass), result.name) + reporter.record(result) + end + end + + def <<(o) + o[2] = DRbObject.new(o[2]) if o + @queue << o + end + + def pop + if test = @queue.pop + @in_flight[[test[0].to_s, test[1]]] = test + test + end + end + + def start_worker(worker_id) + @active_workers[worker_id] = true + end + + def stop_worker(worker_id) + @active_workers.delete(worker_id) + end + + def active_workers? + @active_workers.size > 0 + end + + def interrupt + @queue.clear + end + + def shutdown + # Wait for initial queue to drain + while @queue.length != 0 + sleep 0.1 + end + + @queue.close + + # Wait until all workers have finished + while active_workers? + sleep 0.1 + end + + @in_flight.values.each do |(klass, name, reporter)| + result = Minitest::Result.from(klass.new(name)) + error = RuntimeError.new("result not reported") + error.set_backtrace([""]) + result.failures << Minitest::UnexpectedError.new(error) + reporter.synchronize do + reporter.record(result) + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/parallelization/worker.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/parallelization/worker.rb new file mode 100644 index 00000000..393355a2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/parallelization/worker.rb @@ -0,0 +1,103 @@ +# frozen_string_literal: true + +module ActiveSupport + module Testing + class Parallelization # :nodoc: + class Worker + def initialize(number, url) + @id = SecureRandom.uuid + @number = number + @url = url + @setup_exception = nil + end + + def start + fork do + set_process_title("(starting)") + + DRb.stop_service + + @queue = DRbObject.new_with_uri(@url) + @queue.start_worker(@id) + + begin + after_fork + rescue => @setup_exception; end + + work_from_queue + ensure + set_process_title("(stopping)") + + run_cleanup + @queue.stop_worker(@id) + end + end + + def work_from_queue + while job = @queue.pop + perform_job(job) + end + end + + def perform_job(job) + klass = job[0] + method = job[1] + reporter = job[2] + + set_process_title("#{klass}##{method}") + + result = klass.with_info_handler reporter do + Minitest.run_one_method(klass, method) + end + + safe_record(reporter, result) + end + + def safe_record(reporter, result) + add_setup_exception(result) if @setup_exception + + begin + @queue.record(reporter, result) + rescue DRb::DRbConnError + result.failures.map! do |failure| + if failure.respond_to?(:error) + # minitest >5.14.0 + error = DRb::DRbRemoteError.new(failure.error) + else + error = DRb::DRbRemoteError.new(failure.exception) + end + Minitest::UnexpectedError.new(error) + end + @queue.record(reporter, result) + rescue Interrupt + @queue.interrupt + raise + end + + set_process_title("(idle)") + end + + def after_fork + Parallelization.after_fork_hooks.each do |cb| + cb.call(@number) + end + end + + def run_cleanup + Parallelization.run_cleanup_hooks.each do |cb| + cb.call(@number) + end + end + + private + def add_setup_exception(result) + result.failures.prepend Minitest::UnexpectedError.new(@setup_exception) + end + + def set_process_title(status) + Process.setproctitle("Rails test worker #{@number} - #{status}") + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/parallelize_executor.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/parallelize_executor.rb new file mode 100644 index 00000000..127f26f9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/parallelize_executor.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +module ActiveSupport + module Testing + class ParallelizeExecutor # :nodoc: + attr_reader :size, :parallelize_with, :threshold + + def initialize(size:, with:, threshold: ActiveSupport.test_parallelization_threshold) + @size = size + @parallelize_with = with + @threshold = threshold + @parallelized = false + end + + def start + parallelize if should_parallelize? + show_execution_info + + parallel_executor.start if parallelized? + end + + def <<(work) + parallel_executor << work if parallelized? + end + + def shutdown + parallel_executor.shutdown if parallelized? + end + + private + def parallel_executor + @parallel_executor ||= build_parallel_executor + end + + def build_parallel_executor + case parallelize_with + when :processes + Testing::Parallelization.new(size) + when :threads + ActiveSupport::TestCase.lock_threads = false if defined?(ActiveSupport::TestCase.lock_threads) + Minitest::Parallel::Executor.new(size) + else + raise ArgumentError, "#{parallelize_with} is not a supported parallelization executor." + end + end + + def parallelize + @parallelized = true + Minitest::Test.parallelize_me! + end + + def parallelized? + @parallelized + end + + def should_parallelize? + (ENV["PARALLEL_WORKERS"] || tests_count > threshold) && many_workers? + end + + def many_workers? + size > 1 + end + + def tests_count + @tests_count ||= Minitest::Runnable.runnables.sum { |runnable| runnable.runnable_methods.size } + end + + def show_execution_info + puts execution_info + end + + def execution_info + if parallelized? + "Running #{tests_count} tests in parallel using #{parallel_executor.size} #{parallelize_with}" + elsif many_workers? + "Running #{tests_count} tests in a single process (parallelization threshold is #{threshold})" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/setup_and_teardown.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/setup_and_teardown.rb new file mode 100644 index 00000000..9c12dc2e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/setup_and_teardown.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +require "active_support/callbacks" + +module ActiveSupport + module Testing + # Adds support for +setup+ and +teardown+ callbacks. + # These callbacks serve as a replacement to overwriting the + # #setup and #teardown methods of your TestCase. + # + # class ExampleTest < ActiveSupport::TestCase + # setup do + # # ... + # end + # + # teardown do + # # ... + # end + # end + module SetupAndTeardown + def self.prepended(klass) + klass.include ActiveSupport::Callbacks + klass.define_callbacks :setup, :teardown + klass.extend ClassMethods + end + + module ClassMethods + # Add a callback, which runs before TestCase#setup. + def setup(*args, &block) + set_callback(:setup, :before, *args, &block) + end + + # Add a callback, which runs after TestCase#teardown. + def teardown(*args, &block) + set_callback(:teardown, :after, *args, &block) + end + end + + def before_setup # :nodoc: + super + run_callbacks :setup + end + + def after_teardown # :nodoc: + begin + run_callbacks :teardown + rescue => e + self.failures << Minitest::UnexpectedError.new(e) + rescue Minitest::Assertion => e + self.failures << e + end + + super + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/stream.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/stream.rb new file mode 100644 index 00000000..0b8e0298 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/stream.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module ActiveSupport + module Testing + module Stream # :nodoc: + private + def silence_stream(stream) + old_stream = stream.dup + stream.reopen(IO::NULL) + stream.sync = true + yield + ensure + stream.reopen(old_stream) + old_stream.close + end + + def quietly(&block) + silence_stream(STDOUT) do + silence_stream(STDERR, &block) + end + end + + def capture(stream) + stream = stream.to_s + captured_stream = Tempfile.new(stream) + stream_io = eval("$#{stream}", binding, __FILE__, __LINE__) + origin_stream = stream_io.dup + stream_io.reopen(captured_stream) + + yield + + stream_io.rewind + captured_stream.read + ensure + captured_stream.close + captured_stream.unlink + stream_io.reopen(origin_stream) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/tagged_logging.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/tagged_logging.rb new file mode 100644 index 00000000..7d38268b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/tagged_logging.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module ActiveSupport + module Testing + # Logs a "PostsControllerTest: test name" heading before each test to + # make test.log easier to search and follow along with. + module TaggedLogging # :nodoc: + attr_writer :tagged_logger + + def before_setup + if tagged_logger && tagged_logger.info? + heading = "#{self.class}: #{name}" + divider = "-" * heading.size + tagged_logger.info divider + tagged_logger.info heading + tagged_logger.info divider + end + super + end + + private + def tagged_logger + @tagged_logger ||= (defined?(Rails.logger) && Rails.logger) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/tests_without_assertions.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/tests_without_assertions.rb new file mode 100644 index 00000000..adfe7d86 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/tests_without_assertions.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module ActiveSupport + module Testing + # Warns when a test case does not perform any assertions. + # + # This is helpful in detecting broken tests that do not perform intended assertions. + module TestsWithoutAssertions # :nodoc: + def after_teardown + super + + if assertions.zero? && !skipped? && !error? + file, line = method(name).source_location + warn "Test is missing assertions: `#{name}` #{file}:#{line}" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/time_helpers.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/time_helpers.rb new file mode 100644 index 00000000..578184c5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/testing/time_helpers.rb @@ -0,0 +1,269 @@ +# frozen_string_literal: true + +require "active_support/core_ext/module/redefine_method" +require "active_support/core_ext/time/calculations" + +module ActiveSupport + module Testing + # Manages stubs for TimeHelpers + class SimpleStubs # :nodoc: + Stub = Struct.new(:object, :method_name, :original_method) + + def initialize + @stubs = Hash.new { |h, k| h[k] = {} } + end + + # Stubs object.method_name with the given block + # If the method is already stubbed, remove that stub + # so that removing this stub will restore the original implementation. + # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00 + # target = Time.zone.local(2004, 11, 24, 1, 4, 44) + # simple_stubs.stub_object(Time, :now) { at(target.to_i) } + # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00 + def stub_object(object, method_name, &block) + if stub = stubbing(object, method_name) + unstub_object(stub) + end + + new_name = "__simple_stub__#{method_name}__#{object_id}" + + @stubs[object.object_id][method_name] = Stub.new(object, method_name, new_name) + + object.singleton_class.alias_method new_name, method_name + object.define_singleton_method(method_name, &block) + end + + # Remove all object-method stubs held by this instance + def unstub_all! + @stubs.each_value do |object_stubs| + object_stubs.each_value do |stub| + unstub_object(stub) + end + end + @stubs.clear + end + + # Returns the Stub for object#method_name + # (nil if it is not stubbed) + def stubbing(object, method_name) + @stubs[object.object_id][method_name] + end + + # Returns true if any stubs are set, false if there are none + def stubbed? + !@stubs.empty? + end + + private + # Restores the original object.method described by the Stub + def unstub_object(stub) + singleton_class = stub.object.singleton_class + singleton_class.silence_redefinition_of_method stub.method_name + singleton_class.alias_method stub.method_name, stub.original_method + singleton_class.undef_method stub.original_method + end + end + + # Contains helpers that help you test passage of time. + module TimeHelpers + def after_teardown + travel_back + super + end + + # Changes current time to the time in the future or in the past by a given time difference by + # stubbing +Time.now+, +Date.today+, and +DateTime.now+. The stubs are automatically removed + # at the end of the test. + # + # Note that the usec for the resulting time will be set to 0 to prevent rounding + # errors with external services, like MySQL (which will round instead of floor, + # leading to off-by-one-second errors), unless the with_usec argument + # is set to true. + # + # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00 + # travel 1.day + # Time.current # => Sun, 10 Nov 2013 15:34:49 EST -05:00 + # Date.current # => Sun, 10 Nov 2013 + # DateTime.current # => Sun, 10 Nov 2013 15:34:49 -0500 + # + # This method also accepts a block, which will return the current time back to its original + # state at the end of the block: + # + # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00 + # travel 1.day do + # User.create.created_at # => Sun, 10 Nov 2013 15:34:49 EST -05:00 + # end + # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00 + def travel(duration, with_usec: false, &block) + travel_to Time.now + duration, with_usec: with_usec, &block + end + + # Changes current time to the given time by stubbing +Time.now+, +Time.new+, + # +Date.today+, and +DateTime.now+ to return the time or date passed into this method. + # The stubs are automatically removed at the end of the test. + # + # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00 + # travel_to Time.zone.local(2004, 11, 24, 1, 4, 44) + # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00 + # Date.current # => Wed, 24 Nov 2004 + # DateTime.current # => Wed, 24 Nov 2004 01:04:44 -0500 + # + # Dates are taken as their timestamp at the beginning of the day in the + # application time zone. Time.current returns said timestamp, + # and Time.now its equivalent in the system time zone. Similarly, + # Date.current returns a date equal to the argument, and + # Date.today the date according to Time.now, which may + # be different. (Note that you rarely want to deal with Time.now, + # or Date.today, in order to honor the application time zone + # please always use Time.current and Date.current.) + # + # Note that the usec for the time passed will be set to 0 to prevent rounding + # errors with external services, like MySQL (which will round instead of floor, + # leading to off-by-one-second errors), unless the with_usec argument + # is set to true. + # + # This method also accepts a block, which will return the current time back to its original + # state at the end of the block: + # + # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00 + # travel_to Time.zone.local(2004, 11, 24, 1, 4, 44) do + # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00 + # end + # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00 + def travel_to(date_or_time, with_usec: false) + if block_given? && in_block + travel_to_nested_block_call = <<~MSG + + Calling `travel_to` with a block, when we have previously already made a call to `travel_to`, can lead to confusing time stubbing. + + Instead of: + + travel_to 2.days.from_now do + # 2 days from today + travel_to 3.days.from_now do + # 5 days from today + end + end + + preferred way to achieve above is: + + travel 2.days do + # 2 days from today + end + + travel 5.days do + # 5 days from today + end + + MSG + raise travel_to_nested_block_call + end + + if date_or_time.is_a?(Date) && !date_or_time.is_a?(DateTime) + now = date_or_time.midnight.to_time + elsif date_or_time.is_a?(String) + now = Time.zone.parse(date_or_time) + else + now = date_or_time + now = now.to_time unless now.is_a?(Time) + end + + now = now.change(usec: 0) unless with_usec + + # +now+ must be in local system timezone, because +Time.at(now)+ + # and +now.to_date+ (see stubs below) will use +now+'s timezone too! + now = now.getlocal + + stubs = simple_stubs + stubbed_time = Time.now if stubs.stubbing(Time, :now) + stubs.stub_object(Time, :now) { at(now) } + + stubs.stub_object(Time, :new) do |*args, **options| + if args.empty? && options.empty? + at(now) + else + stub = stubs.stubbing(Time, :new) + Time.send(stub.original_method, *args, **options) + end + end + + stubs.stub_object(Date, :today) { jd(now.to_date.jd) } + stubs.stub_object(DateTime, :now) { jd(now.to_date.jd, now.hour, now.min, now.sec, Rational(now.utc_offset, 86400)) } + + if block_given? + begin + self.in_block = true + yield + ensure + if stubbed_time + travel_to stubbed_time + else + travel_back + end + self.in_block = false + end + end + end + + # Returns the current time back to its original state, by removing the stubs added by + # +travel+, +travel_to+, and +freeze_time+. + # + # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00 + # + # travel_to Time.zone.local(2004, 11, 24, 1, 4, 44) + # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00 + # + # travel_back + # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00 + # + # This method also accepts a block, which brings the stubs back at the end of the block: + # + # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00 + # + # travel_to Time.zone.local(2004, 11, 24, 1, 4, 44) + # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00 + # + # travel_back do + # Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00 + # end + # + # Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00 + def travel_back + stubbed_time = Time.current if block_given? && simple_stubs.stubbed? + + simple_stubs.unstub_all! + yield if block_given? + ensure + travel_to stubbed_time if stubbed_time + end + alias_method :unfreeze_time, :travel_back + + # Calls +travel_to+ with +Time.now+. Forwards optional with_usec argument. + # + # Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00 + # freeze_time + # sleep(1) + # Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00 + # + # This method also accepts a block, which will return the current time back to its original + # state at the end of the block: + # + # Time.current # => Sun, 09 Jul 2017 15:34:49 EST -05:00 + # freeze_time do + # sleep(1) + # User.create.created_at # => Sun, 09 Jul 2017 15:34:49 EST -05:00 + # end + # Time.current # => Sun, 09 Jul 2017 15:34:50 EST -05:00 + def freeze_time(with_usec: false, &block) + travel_to Time.now, with_usec: with_usec, &block + end + + private + def simple_stubs + @simple_stubs ||= SimpleStubs.new + end + + attr_accessor :in_block + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/time.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/time.rb new file mode 100644 index 00000000..51854675 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/time.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module ActiveSupport + autoload :Duration, "active_support/duration" + autoload :TimeWithZone, "active_support/time_with_zone" + autoload :TimeZone, "active_support/values/time_zone" +end + +require "date" +require "time" + +require "active_support/core_ext/time" +require "active_support/core_ext/date" +require "active_support/core_ext/date_time" + +require "active_support/core_ext/integer/time" +require "active_support/core_ext/numeric/time" + +require "active_support/core_ext/string/conversions" +require "active_support/core_ext/string/zones" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/time_with_zone.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/time_with_zone.rb new file mode 100644 index 00000000..eb25fd46 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/time_with_zone.rb @@ -0,0 +1,609 @@ +# frozen_string_literal: true + +require "yaml" + +require "active_support/duration" +require "active_support/values/time_zone" +require "active_support/core_ext/object/acts_like" +require "active_support/core_ext/date_and_time/compatibility" + +module ActiveSupport + # = Active Support \Time With Zone + # + # A Time-like class that can represent a time in any time zone. Necessary + # because standard Ruby Time instances are limited to UTC and the + # system's ENV['TZ'] zone. + # + # You shouldn't ever need to create a TimeWithZone instance directly via +new+. + # Instead use methods +local+, +parse+, +at+, and +now+ on TimeZone instances, + # and +in_time_zone+ on Time and DateTime instances. + # + # Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)' + # Time.zone.local(2007, 2, 10, 15, 30, 45) # => Sat, 10 Feb 2007 15:30:45.000000000 EST -05:00 + # Time.zone.parse('2007-02-10 15:30:45') # => Sat, 10 Feb 2007 15:30:45.000000000 EST -05:00 + # Time.zone.at(1171139445) # => Sat, 10 Feb 2007 15:30:45.000000000 EST -05:00 + # Time.zone.now # => Sun, 18 May 2008 13:07:55.754107581 EDT -04:00 + # Time.utc(2007, 2, 10, 20, 30, 45).in_time_zone # => Sat, 10 Feb 2007 15:30:45.000000000 EST -05:00 + # + # See Time and TimeZone for further documentation of these methods. + # + # TimeWithZone instances implement the same API as Ruby Time instances, so + # that Time and TimeWithZone instances are interchangeable. + # + # t = Time.zone.now # => Sun, 18 May 2008 13:27:25.031505668 EDT -04:00 + # t.hour # => 13 + # t.dst? # => true + # t.utc_offset # => -14400 + # t.zone # => "EDT" + # t.to_fs(:rfc822) # => "Sun, 18 May 2008 13:27:25 -0400" + # t + 1.day # => Mon, 19 May 2008 13:27:25.031505668 EDT -04:00 + # t.beginning_of_year # => Tue, 01 Jan 2008 00:00:00.000000000 EST -05:00 + # t > Time.utc(1999) # => true + # t.is_a?(Time) # => true + # t.is_a?(ActiveSupport::TimeWithZone) # => true + class TimeWithZone + PRECISIONS = Hash.new { |h, n| h[n] = "%FT%T.%#{n}N" } + PRECISIONS[0] = "%FT%T" + + include Comparable, DateAndTime::Compatibility + attr_reader :time_zone + + def initialize(utc_time, time_zone, local_time = nil, period = nil) + @utc = utc_time ? transfer_time_values_to_utc_constructor(utc_time) : nil + @time_zone, @time = time_zone, local_time + @period = @utc ? period : get_period_and_ensure_valid_local_time(period) + end + + # Returns a Time instance that represents the time in +time_zone+. + def time + @time ||= incorporate_utc_offset(@utc, utc_offset) + end + + # Returns a Time instance of the simultaneous time in the UTC timezone. + def utc + @utc ||= incorporate_utc_offset(@time, -utc_offset) + end + alias_method :comparable_time, :utc + alias_method :getgm, :utc + alias_method :getutc, :utc + alias_method :gmtime, :utc + + # Returns the underlying +TZInfo::TimezonePeriod+. + def period + @period ||= time_zone.period_for_utc(@utc) + end + + # Returns the simultaneous time in Time.zone, or the specified zone. + def in_time_zone(new_zone = ::Time.zone) + return self if time_zone == new_zone + utc.in_time_zone(new_zone) + end + + # Returns a Time instance of the simultaneous time in the system timezone. + def localtime(utc_offset = nil) + utc.getlocal(utc_offset) + end + alias_method :getlocal, :localtime + + # Returns true if the current time is within Daylight Savings \Time for the + # specified time zone. + # + # Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)' + # Time.zone.parse("2012-5-30").dst? # => true + # Time.zone.parse("2012-11-30").dst? # => false + def dst? + period.dst? + end + alias_method :isdst, :dst? + + # Returns true if the current time zone is set to UTC. + # + # Time.zone = 'UTC' # => 'UTC' + # Time.zone.now.utc? # => true + # Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)' + # Time.zone.now.utc? # => false + def utc? + zone == "UTC" || zone == "UCT" + end + alias_method :gmt?, :utc? + + # Returns the offset from current time to UTC time in seconds. + def utc_offset + period.observed_utc_offset + end + alias_method :gmt_offset, :utc_offset + alias_method :gmtoff, :utc_offset + + # Returns a formatted string of the offset from UTC, or an alternative + # string if the time zone is already UTC. + # + # Time.zone = 'Eastern Time (US & Canada)' # => "Eastern Time (US & Canada)" + # Time.zone.now.formatted_offset(true) # => "-05:00" + # Time.zone.now.formatted_offset(false) # => "-0500" + # Time.zone = 'UTC' # => "UTC" + # Time.zone.now.formatted_offset(true, "0") # => "0" + def formatted_offset(colon = true, alternate_utc_string = nil) + utc? && alternate_utc_string || TimeZone.seconds_to_utc_offset(utc_offset, colon) + end + + # Returns the time zone abbreviation. + # + # Time.zone = 'Eastern Time (US & Canada)' # => "Eastern Time (US & Canada)" + # Time.zone.now.zone # => "EST" + def zone + period.abbreviation + end + + # Returns a string of the object's date, time, zone, and offset from UTC. + # + # Time.zone.now.inspect # => "2024-11-13 07:00:10.528054960 UTC +00:00" + def inspect + "#{time.strftime('%F %H:%M:%S.%9N')} #{zone} #{formatted_offset}" + end + + # Returns a string of the object's date and time in the ISO 8601 standard + # format. + # + # Time.zone.now.xmlschema # => "2014-12-04T11:02:37-05:00" + def xmlschema(fraction_digits = 0) + "#{time.strftime(PRECISIONS[fraction_digits.to_i])}#{formatted_offset(true, 'Z')}" + end + alias_method :iso8601, :xmlschema + alias_method :rfc3339, :xmlschema + + # Coerces time to a string for JSON encoding. The default format is ISO 8601. + # You can get %Y/%m/%d %H:%M:%S +offset style by setting + # ActiveSupport::JSON::Encoding.use_standard_json_time_format + # to +false+. + # + # # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = true + # Time.utc(2005,2,1,15,15,10).in_time_zone("Hawaii").as_json + # # => "2005-02-01T05:15:10.000-10:00" + # + # # With ActiveSupport::JSON::Encoding.use_standard_json_time_format = false + # Time.utc(2005,2,1,15,15,10).in_time_zone("Hawaii").as_json + # # => "2005/02/01 05:15:10 -1000" + def as_json(options = nil) + if ActiveSupport::JSON::Encoding.use_standard_json_time_format + xmlschema(ActiveSupport::JSON::Encoding.time_precision) + else + %(#{time.strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)}) + end + end + + def init_with(coder) # :nodoc: + initialize(coder["utc"], coder["zone"], coder["time"]) + end + + def encode_with(coder) # :nodoc: + coder.map = { "utc" => utc, "zone" => time_zone, "time" => time } + end + + # Returns a string of the object's date and time in the format used by + # HTTP requests. + # + # Time.zone.now.httpdate # => "Tue, 01 Jan 2013 04:39:43 GMT" + def httpdate + utc.httpdate + end + + # Returns a string of the object's date and time in the RFC 2822 standard + # format. + # + # Time.zone.now.rfc2822 # => "Tue, 01 Jan 2013 04:51:39 +0000" + def rfc2822 + to_fs(:rfc822) + end + alias_method :rfc822, :rfc2822 + + # Returns a string of the object's date and time. + def to_s + "#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby Time#to_s format + end + + # Returns a string of the object's date and time. + # + # This method is aliased to to_formatted_s. + # + # Accepts an optional format: + # * :default - default value, mimics Ruby Time#to_s format. + # * :db - format outputs time in UTC :db time. See Time#to_fs(:db). + # * Any key in +Time::DATE_FORMATS+ can be used. See active_support/core_ext/time/conversions.rb. + def to_fs(format = :default) + if format == :db + utc.to_fs(format) + elsif formatter = ::Time::DATE_FORMATS[format] + formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter) + else + to_s + end + end + alias_method :to_formatted_s, :to_fs + + # Replaces %Z directive with +zone before passing to Time#strftime, + # so that zone information is correct. + def strftime(format) + format = format.gsub(/((?:\A|[^%])(?:%%)*)%Z/, "\\1#{zone}") + getlocal(utc_offset).strftime(format) + end + + # Use the time in UTC for comparisons. + def <=>(other) + utc <=> other + end + alias_method :before?, :< + alias_method :after?, :> + + # Returns true if the current object's time is within the specified + # +min+ and +max+ time. + def between?(min, max) + utc.between?(min, max) + end + + # Returns true if the current object's time is in the past. + def past? + utc.past? + end + + # Returns true if the current object's time falls within + # the current day. + def today? + time.today? + end + + # Returns true if the current object's time falls within + # the next day (tomorrow). + def tomorrow? + time.tomorrow? + end + alias :next_day? :tomorrow? + + # Returns true if the current object's time falls within + # the previous day (yesterday). + def yesterday? + time.yesterday? + end + alias :prev_day? :yesterday? + + # Returns true if the current object's time is in the future. + def future? + utc.future? + end + + # Returns +true+ if +other+ is equal to current object. + def eql?(other) + other.eql?(utc) + end + + def hash + utc.hash + end + + # Adds an interval of time to the current object's time and returns that + # value as a new TimeWithZone object. + # + # Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)' + # now = Time.zone.now # => Sun, 02 Nov 2014 01:26:28.725182881 EDT -04:00 + # now + 1000 # => Sun, 02 Nov 2014 01:43:08.725182881 EDT -04:00 + # + # If we're adding a Duration of variable length (i.e., years, months, days), + # move forward from #time, otherwise move forward from #utc, for accuracy + # when moving across DST boundaries. + # + # For instance, a time + 24.hours will advance exactly 24 hours, while a + # time + 1.day will advance 23-25 hours, depending on the day. + # + # now + 24.hours # => Mon, 03 Nov 2014 00:26:28.725182881 EST -05:00 + # now + 1.day # => Mon, 03 Nov 2014 01:26:28.725182881 EST -05:00 + def +(other) + if duration_of_variable_length?(other) + method_missing(:+, other) + else + begin + result = utc + other + rescue TypeError + result = utc.to_datetime.since(other) + ActiveSupport.deprecator.warn( + "Adding an instance of #{other.class} to an instance of #{self.class} is deprecated. This behavior will raise " \ + "a `TypeError` in Rails 8.1." + ) + result.in_time_zone(time_zone) + end + result.in_time_zone(time_zone) + end + end + alias_method :since, :+ + alias_method :in, :+ + + # Subtracts an interval of time and returns a new TimeWithZone object unless + # the other value +acts_like?+ time. In which case, it will subtract the + # other time and return the difference in seconds as a Float. + # + # Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)' + # now = Time.zone.now # => Mon, 03 Nov 2014 00:26:28.725182881 EST -05:00 + # now - 1000 # => Mon, 03 Nov 2014 00:09:48.725182881 EST -05:00 + # + # If subtracting a Duration of variable length (i.e., years, months, days), + # move backward from #time, otherwise move backward from #utc, for accuracy + # when moving across DST boundaries. + # + # For instance, a time - 24.hours will go subtract exactly 24 hours, while a + # time - 1.day will subtract 23-25 hours, depending on the day. + # + # now - 24.hours # => Sun, 02 Nov 2014 01:26:28.725182881 EDT -04:00 + # now - 1.day # => Sun, 02 Nov 2014 00:26:28.725182881 EDT -04:00 + # + # If both the TimeWithZone object and the other value act like Time, a Float + # will be returned. + # + # Time.zone.now - 1.day.ago # => 86399.999967 + # + def -(other) + if other.acts_like?(:time) + getutc - other.getutc + elsif duration_of_variable_length?(other) + method_missing(:-, other) + else + result = utc - other + result.in_time_zone(time_zone) + end + end + + # Subtracts an interval of time from the current object's time and returns + # the result as a new TimeWithZone object. + # + # Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)' + # now = Time.zone.now # => Mon, 03 Nov 2014 00:26:28.725182881 EST -05:00 + # now.ago(1000) # => Mon, 03 Nov 2014 00:09:48.725182881 EST -05:00 + # + # If we're subtracting a Duration of variable length (i.e., years, months, + # days), move backward from #time, otherwise move backward from #utc, for + # accuracy when moving across DST boundaries. + # + # For instance, time.ago(24.hours) will move back exactly 24 hours, + # while time.ago(1.day) will move back 23-25 hours, depending on + # the day. + # + # now.ago(24.hours) # => Sun, 02 Nov 2014 01:26:28.725182881 EDT -04:00 + # now.ago(1.day) # => Sun, 02 Nov 2014 00:26:28.725182881 EDT -04:00 + def ago(other) + since(-other) + end + + # Returns a new +ActiveSupport::TimeWithZone+ where one or more of the elements have + # been changed according to the +options+ parameter. The time options (:hour, + # :min, :sec, :usec, :nsec) reset cascadingly, + # so if only the hour is passed, then minute, sec, usec, and nsec is set to 0. If the + # hour and minute is passed, then sec, usec, and nsec is set to 0. The +options+ + # parameter takes a hash with any of these keys: :year, :month, + # :day, :hour, :min, :sec, :usec, + # :nsec, :offset, :zone. Pass either :usec + # or :nsec, not both. Similarly, pass either :zone or + # :offset, not both. + # + # t = Time.zone.now # => Fri, 14 Apr 2017 11:45:15.116992711 EST -05:00 + # t.change(year: 2020) # => Tue, 14 Apr 2020 11:45:15.116992711 EST -05:00 + # t.change(hour: 12) # => Fri, 14 Apr 2017 12:00:00.000000000 EST -05:00 + # t.change(min: 30) # => Fri, 14 Apr 2017 11:30:00.000000000 EST -05:00 + # t.change(offset: "-10:00") # => Fri, 14 Apr 2017 11:45:15.116992711 HST -10:00 + # t.change(zone: "Hawaii") # => Fri, 14 Apr 2017 11:45:15.116992711 HST -10:00 + def change(options) + if options[:zone] && options[:offset] + raise ArgumentError, "Can't change both :offset and :zone at the same time: #{options.inspect}" + end + + new_time = time.change(options) + + if options[:zone] + new_zone = ::Time.find_zone(options[:zone]) + elsif options[:offset] + new_zone = ::Time.find_zone(new_time.utc_offset) + end + + new_zone ||= time_zone + periods = new_zone.periods_for_local(new_time) + + self.class.new(nil, new_zone, new_time, periods.include?(period) ? period : nil) + end + + # Uses Date to provide precise Time calculations for years, months, and days + # according to the proleptic Gregorian calendar. The result is returned as a + # new TimeWithZone object. + # + # The +options+ parameter takes a hash with any of these keys: + # :years, :months, :weeks, :days, + # :hours, :minutes, :seconds. + # + # If advancing by a value of variable length (i.e., years, weeks, months, + # days), move forward from #time, otherwise move forward from #utc, for + # accuracy when moving across DST boundaries. + # + # Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)' + # now = Time.zone.now # => Sun, 02 Nov 2014 01:26:28.558049687 EDT -04:00 + # now.advance(seconds: 1) # => Sun, 02 Nov 2014 01:26:29.558049687 EDT -04:00 + # now.advance(minutes: 1) # => Sun, 02 Nov 2014 01:27:28.558049687 EDT -04:00 + # now.advance(hours: 1) # => Sun, 02 Nov 2014 01:26:28.558049687 EST -05:00 + # now.advance(days: 1) # => Mon, 03 Nov 2014 01:26:28.558049687 EST -05:00 + # now.advance(weeks: 1) # => Sun, 09 Nov 2014 01:26:28.558049687 EST -05:00 + # now.advance(months: 1) # => Tue, 02 Dec 2014 01:26:28.558049687 EST -05:00 + # now.advance(years: 1) # => Mon, 02 Nov 2015 01:26:28.558049687 EST -05:00 + def advance(options) + # If we're advancing a value of variable length (i.e., years, weeks, months, days), advance from #time, + # otherwise advance from #utc, for accuracy when moving across DST boundaries + if options.values_at(:years, :weeks, :months, :days).any? + method_missing(:advance, options) + else + utc.advance(options).in_time_zone(time_zone) + end + end + + %w(year mon month day mday wday yday hour min sec usec nsec to_date).each do |method_name| + class_eval <<-EOV, __FILE__, __LINE__ + 1 + def #{method_name} # def month + time.#{method_name} # time.month + end # end + EOV + end + + # Returns Array of parts of Time in sequence of + # [seconds, minutes, hours, day, month, year, weekday, yearday, dst?, zone]. + # + # now = Time.zone.now # => Tue, 18 Aug 2015 02:29:27.485278555 UTC +00:00 + # now.to_a # => [27, 29, 2, 18, 8, 2015, 2, 230, false, "UTC"] + def to_a + [time.sec, time.min, time.hour, time.day, time.mon, time.year, time.wday, time.yday, dst?, zone] + end + + # Returns the object's date and time as a floating-point number of seconds + # since the Epoch (January 1, 1970 00:00 UTC). + # + # Time.zone.now.to_f # => 1417709320.285418 + def to_f + utc.to_f + end + + # Returns the object's date and time as an integer number of seconds + # since the Epoch (January 1, 1970 00:00 UTC). + # + # Time.zone.now.to_i # => 1417709320 + def to_i + utc.to_i + end + alias_method :tv_sec, :to_i + + # Returns the object's date and time as a rational number of seconds + # since the Epoch (January 1, 1970 00:00 UTC). + # + # Time.zone.now.to_r # => (708854548642709/500000) + def to_r + utc.to_r + end + + # Returns an instance of DateTime with the timezone's UTC offset + # + # Time.zone.now.to_datetime # => Tue, 18 Aug 2015 02:32:20 +0000 + # Time.current.in_time_zone('Hawaii').to_datetime # => Mon, 17 Aug 2015 16:32:20 -1000 + def to_datetime + @to_datetime ||= utc.to_datetime.new_offset(Rational(utc_offset, 86_400)) + end + + # Returns an instance of +Time+, either with the same timezone as +self+, + # with the same UTC offset as +self+ or in the local system timezone + # depending on the setting of +ActiveSupport.to_time_preserves_timezone+. + def to_time + if preserve_timezone == :zone + @to_time_with_timezone ||= getlocal(time_zone) + elsif preserve_timezone + @to_time_with_instance_offset ||= getlocal(utc_offset) + else + @to_time_with_system_offset ||= getlocal + end + end + + # So that +self+ acts_like?(:time). + def acts_like_time? + true + end + + # Say we're a Time to thwart type checking. + def is_a?(klass) + klass == ::Time || super + end + alias_method :kind_of?, :is_a? + + # An instance of ActiveSupport::TimeWithZone is never blank + def blank? + false + end + + def present? # :nodoc: + true + end + + def freeze + # preload instance variables before freezing + period; utc; time; to_datetime; to_time + super + end + + def marshal_dump + [utc, time_zone.name, time] + end + + def marshal_load(variables) + initialize(variables[0].utc, ::Time.find_zone(variables[1]), variables[2].utc) + end + + # respond_to_missing? is not called in some cases, such as when type conversion is + # performed with Kernel#String + def respond_to?(sym, include_priv = false) + # ensure that we're not going to throw and rescue from NoMethodError in method_missing which is slow + return false if sym.to_sym == :to_str + super + end + + # Ensure proxy class responds to all methods that underlying time instance + # responds to. + def respond_to_missing?(sym, include_priv) + time.respond_to?(sym, include_priv) + end + + # Send the missing method to +time+ instance, and wrap result in a new + # TimeWithZone with the existing +time_zone+. + def method_missing(...) + wrap_with_time_zone time.__send__(...) + rescue NoMethodError => e + raise e, e.message.sub(time.inspect, inspect).sub("Time", "ActiveSupport::TimeWithZone"), e.backtrace + end + + private + SECONDS_PER_DAY = 86400 + + def incorporate_utc_offset(time, offset) + if time.kind_of?(Date) + time + Rational(offset, SECONDS_PER_DAY) + else + time + offset + end + end + + def get_period_and_ensure_valid_local_time(period) + # we don't want a Time.local instance enforcing its own DST rules as well, + # so transfer time values to a utc constructor if necessary + @time = transfer_time_values_to_utc_constructor(@time) unless @time.utc? + begin + period || @time_zone.period_for_local(@time) + rescue ::TZInfo::PeriodNotFound + # time is in the "spring forward" hour gap, so we're moving the time forward one hour and trying again + @time += 1.hour + retry + end + end + + def transfer_time_values_to_utc_constructor(time) + # avoid creating another Time object if possible + return time if time.instance_of?(::Time) && time.utc? + ::Time.utc(time.year, time.month, time.day, time.hour, time.min, time.sec + time.subsec) + end + + def duration_of_variable_length?(obj) + ActiveSupport::Duration === obj && obj.variable? + end + + def wrap_with_time_zone(time) + if time.acts_like?(:time) + periods = time_zone.periods_for_local(time) + self.class.new(nil, time_zone, time, periods.include?(period) ? period : nil) + elsif time.is_a?(Range) + wrap_with_time_zone(time.begin)..wrap_with_time_zone(time.end) + else + time + end + end + end +end + +# These prevent Psych from calling `ActiveSupport::TimeWithZone.name` +# and triggering the deprecation warning about the change in Rails 7.1. +YAML.load_tags["!ruby/object:ActiveSupport::TimeWithZone"] = "ActiveSupport::TimeWithZone" +YAML.dump_tags[ActiveSupport::TimeWithZone] = "!ruby/object:ActiveSupport::TimeWithZone" diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/values/time_zone.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/values/time_zone.rb new file mode 100644 index 00000000..db98f37c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/values/time_zone.rb @@ -0,0 +1,614 @@ +# frozen_string_literal: true + +require "tzinfo" +require "concurrent/map" + +module ActiveSupport + # = Active Support \Time Zone + # + # The TimeZone class serves as a wrapper around +TZInfo::Timezone+ instances. + # It allows us to do the following: + # + # * Limit the set of zones provided by TZInfo to a meaningful subset of 134 + # zones. + # * Retrieve and display zones with a friendlier name + # (e.g., "Eastern \Time (US & Canada)" instead of "America/New_York"). + # * Lazily load +TZInfo::Timezone+ instances only when they're needed. + # * Create ActiveSupport::TimeWithZone instances via TimeZone's +local+, + # +parse+, +at+, and +now+ methods. + # + # If you set config.time_zone in the \Rails Application, you can + # access this TimeZone object via Time.zone: + # + # # application.rb: + # class Application < Rails::Application + # config.time_zone = 'Eastern Time (US & Canada)' + # end + # + # Time.zone # => # + # Time.zone.name # => "Eastern Time (US & Canada)" + # Time.zone.now # => Sun, 18 May 2008 14:30:44 EDT -04:00 + class TimeZone + # Keys are \Rails TimeZone names, values are TZInfo identifiers. + MAPPING = { + "International Date Line West" => "Etc/GMT+12", + "Midway Island" => "Pacific/Midway", + "American Samoa" => "Pacific/Pago_Pago", + "Hawaii" => "Pacific/Honolulu", + "Alaska" => "America/Juneau", + "Pacific Time (US & Canada)" => "America/Los_Angeles", + "Tijuana" => "America/Tijuana", + "Mountain Time (US & Canada)" => "America/Denver", + "Arizona" => "America/Phoenix", + "Chihuahua" => "America/Chihuahua", + "Mazatlan" => "America/Mazatlan", + "Central Time (US & Canada)" => "America/Chicago", + "Saskatchewan" => "America/Regina", + "Guadalajara" => "America/Mexico_City", + "Mexico City" => "America/Mexico_City", + "Monterrey" => "America/Monterrey", + "Central America" => "America/Guatemala", + "Eastern Time (US & Canada)" => "America/New_York", + "Indiana (East)" => "America/Indiana/Indianapolis", + "Bogota" => "America/Bogota", + "Lima" => "America/Lima", + "Quito" => "America/Lima", + "Atlantic Time (Canada)" => "America/Halifax", + "Caracas" => "America/Caracas", + "La Paz" => "America/La_Paz", + "Santiago" => "America/Santiago", + "Newfoundland" => "America/St_Johns", + "Brasilia" => "America/Sao_Paulo", + "Buenos Aires" => "America/Argentina/Buenos_Aires", + "Montevideo" => "America/Montevideo", + "Georgetown" => "America/Guyana", + "Puerto Rico" => "America/Puerto_Rico", + "Greenland" => "America/Godthab", + "Mid-Atlantic" => "Atlantic/South_Georgia", + "Azores" => "Atlantic/Azores", + "Cape Verde Is." => "Atlantic/Cape_Verde", + "Dublin" => "Europe/Dublin", + "Edinburgh" => "Europe/London", + "Lisbon" => "Europe/Lisbon", + "London" => "Europe/London", + "Casablanca" => "Africa/Casablanca", + "Monrovia" => "Africa/Monrovia", + "UTC" => "Etc/UTC", + "Belgrade" => "Europe/Belgrade", + "Bratislava" => "Europe/Bratislava", + "Budapest" => "Europe/Budapest", + "Ljubljana" => "Europe/Ljubljana", + "Prague" => "Europe/Prague", + "Sarajevo" => "Europe/Sarajevo", + "Skopje" => "Europe/Skopje", + "Warsaw" => "Europe/Warsaw", + "Zagreb" => "Europe/Zagreb", + "Brussels" => "Europe/Brussels", + "Copenhagen" => "Europe/Copenhagen", + "Madrid" => "Europe/Madrid", + "Paris" => "Europe/Paris", + "Amsterdam" => "Europe/Amsterdam", + "Berlin" => "Europe/Berlin", + "Bern" => "Europe/Zurich", + "Zurich" => "Europe/Zurich", + "Rome" => "Europe/Rome", + "Stockholm" => "Europe/Stockholm", + "Vienna" => "Europe/Vienna", + "West Central Africa" => "Africa/Algiers", + "Bucharest" => "Europe/Bucharest", + "Cairo" => "Africa/Cairo", + "Helsinki" => "Europe/Helsinki", + "Kyiv" => "Europe/Kiev", + "Riga" => "Europe/Riga", + "Sofia" => "Europe/Sofia", + "Tallinn" => "Europe/Tallinn", + "Vilnius" => "Europe/Vilnius", + "Athens" => "Europe/Athens", + "Istanbul" => "Europe/Istanbul", + "Minsk" => "Europe/Minsk", + "Jerusalem" => "Asia/Jerusalem", + "Harare" => "Africa/Harare", + "Pretoria" => "Africa/Johannesburg", + "Kaliningrad" => "Europe/Kaliningrad", + "Moscow" => "Europe/Moscow", + "St. Petersburg" => "Europe/Moscow", + "Volgograd" => "Europe/Volgograd", + "Samara" => "Europe/Samara", + "Kuwait" => "Asia/Kuwait", + "Riyadh" => "Asia/Riyadh", + "Nairobi" => "Africa/Nairobi", + "Baghdad" => "Asia/Baghdad", + "Tehran" => "Asia/Tehran", + "Abu Dhabi" => "Asia/Muscat", + "Muscat" => "Asia/Muscat", + "Baku" => "Asia/Baku", + "Tbilisi" => "Asia/Tbilisi", + "Yerevan" => "Asia/Yerevan", + "Kabul" => "Asia/Kabul", + "Ekaterinburg" => "Asia/Yekaterinburg", + "Islamabad" => "Asia/Karachi", + "Karachi" => "Asia/Karachi", + "Tashkent" => "Asia/Tashkent", + "Chennai" => "Asia/Kolkata", + "Kolkata" => "Asia/Kolkata", + "Mumbai" => "Asia/Kolkata", + "New Delhi" => "Asia/Kolkata", + "Kathmandu" => "Asia/Kathmandu", + "Dhaka" => "Asia/Dhaka", + "Sri Jayawardenepura" => "Asia/Colombo", + "Almaty" => "Asia/Almaty", + "Astana" => "Asia/Almaty", + "Novosibirsk" => "Asia/Novosibirsk", + "Rangoon" => "Asia/Rangoon", + "Bangkok" => "Asia/Bangkok", + "Hanoi" => "Asia/Bangkok", + "Jakarta" => "Asia/Jakarta", + "Krasnoyarsk" => "Asia/Krasnoyarsk", + "Beijing" => "Asia/Shanghai", + "Chongqing" => "Asia/Chongqing", + "Hong Kong" => "Asia/Hong_Kong", + "Urumqi" => "Asia/Urumqi", + "Kuala Lumpur" => "Asia/Kuala_Lumpur", + "Singapore" => "Asia/Singapore", + "Taipei" => "Asia/Taipei", + "Perth" => "Australia/Perth", + "Irkutsk" => "Asia/Irkutsk", + "Ulaanbaatar" => "Asia/Ulaanbaatar", + "Seoul" => "Asia/Seoul", + "Osaka" => "Asia/Tokyo", + "Sapporo" => "Asia/Tokyo", + "Tokyo" => "Asia/Tokyo", + "Yakutsk" => "Asia/Yakutsk", + "Darwin" => "Australia/Darwin", + "Adelaide" => "Australia/Adelaide", + "Canberra" => "Australia/Canberra", + "Melbourne" => "Australia/Melbourne", + "Sydney" => "Australia/Sydney", + "Brisbane" => "Australia/Brisbane", + "Hobart" => "Australia/Hobart", + "Vladivostok" => "Asia/Vladivostok", + "Guam" => "Pacific/Guam", + "Port Moresby" => "Pacific/Port_Moresby", + "Magadan" => "Asia/Magadan", + "Srednekolymsk" => "Asia/Srednekolymsk", + "Solomon Is." => "Pacific/Guadalcanal", + "New Caledonia" => "Pacific/Noumea", + "Fiji" => "Pacific/Fiji", + "Kamchatka" => "Asia/Kamchatka", + "Marshall Is." => "Pacific/Majuro", + "Auckland" => "Pacific/Auckland", + "Wellington" => "Pacific/Auckland", + "Nuku'alofa" => "Pacific/Tongatapu", + "Tokelau Is." => "Pacific/Fakaofo", + "Chatham Is." => "Pacific/Chatham", + "Samoa" => "Pacific/Apia" + } + + UTC_OFFSET_WITH_COLON = "%s%02d:%02d" # :nodoc: + UTC_OFFSET_WITHOUT_COLON = UTC_OFFSET_WITH_COLON.tr(":", "") # :nodoc: + private_constant :UTC_OFFSET_WITH_COLON, :UTC_OFFSET_WITHOUT_COLON + + @lazy_zones_map = Concurrent::Map.new + @country_zones = Concurrent::Map.new + + class << self + # Assumes self represents an offset from UTC in seconds (as returned from + # Time#utc_offset) and turns this into an +HH:MM formatted string. + # + # ActiveSupport::TimeZone.seconds_to_utc_offset(-21_600) # => "-06:00" + def seconds_to_utc_offset(seconds, colon = true) + format = colon ? UTC_OFFSET_WITH_COLON : UTC_OFFSET_WITHOUT_COLON + sign = (seconds < 0 ? "-" : "+") + hours = seconds.abs / 3600 + minutes = (seconds.abs % 3600) / 60 + format % [sign, hours, minutes] + end + + def find_tzinfo(name) + TZInfo::Timezone.get(MAPPING[name] || name) + end + + alias_method :create, :new # :nodoc: + + # Returns a TimeZone instance with the given name, or +nil+ if no + # such TimeZone instance exists. (This exists to support the use of + # this class with the +composed_of+ macro.) + def new(name) + self[name] + end + + # Returns an array of all TimeZone objects. There are multiple + # TimeZone objects per time zone, in many cases, to make it easier + # for users to find their own time zone. + def all + @zones ||= zones_map.values.sort + end + + # Locate a specific time zone object. If the argument is a string, it + # is interpreted to mean the name of the timezone to locate. If it is a + # numeric value it is either the hour offset, or the second offset, of the + # timezone to find. (The first one with that offset will be returned.) + # Returns +nil+ if no such time zone is known to the system. + def [](arg) + case arg + when self + arg + when String + begin + @lazy_zones_map[arg] ||= create(arg) + rescue TZInfo::InvalidTimezoneIdentifier + nil + end + when TZInfo::Timezone + @lazy_zones_map[arg.name] ||= create(arg.name, nil, arg) + when Numeric, ActiveSupport::Duration + arg *= 3600 if arg.abs <= 13 + all.find { |z| z.utc_offset == arg.to_i } + else + raise ArgumentError, "invalid argument to TimeZone[]: #{arg.inspect}" + end + end + + # A convenience method for returning a collection of TimeZone objects + # for time zones in the USA. + def us_zones + country_zones(:us) + end + + # A convenience method for returning a collection of TimeZone objects + # for time zones in the country specified by its ISO 3166-1 Alpha2 code. + def country_zones(country_code) + code = country_code.to_s.upcase + @country_zones[code] ||= load_country_zones(code) + end + + def clear # :nodoc: + @lazy_zones_map = Concurrent::Map.new + @country_zones = Concurrent::Map.new + @zones = nil + @zones_map = nil + end + + private + def load_country_zones(code) + country = TZInfo::Country.get(code) + country.zone_identifiers.flat_map do |tz_id| + if MAPPING.value?(tz_id) + MAPPING.inject([]) do |memo, (key, value)| + memo << self[key] if value == tz_id + memo + end + else + create(tz_id, nil, TZInfo::Timezone.get(tz_id)) + end + end.sort! + end + + def zones_map + @zones_map ||= MAPPING.each_with_object({}) do |(name, _), zones| + timezone = self[name] + zones[name] = timezone if timezone + end + end + end + + include Comparable + attr_reader :name + attr_reader :tzinfo + + ## + # :singleton-method: create + # :call-seq: create(name, utc_offset = nil, tzinfo = nil) + # + # Create a new TimeZone object with the given name and offset. The + # offset is the number of seconds that this time zone is offset from UTC + # (GMT). Seconds were chosen as the offset unit because that is the unit + # that Ruby uses to represent time zone offsets (see Time#utc_offset). + + # :stopdoc: + def initialize(name, utc_offset = nil, tzinfo = nil) + @name = name + @utc_offset = utc_offset + @tzinfo = tzinfo || TimeZone.find_tzinfo(name) + end + # :startdoc: + + # Returns the offset of this time zone from UTC in seconds. + def utc_offset + @utc_offset || tzinfo&.current_period&.base_utc_offset + end + + # Returns a formatted string of the offset from UTC, or an alternative + # string if the time zone is already UTC. + # + # zone = ActiveSupport::TimeZone['Central Time (US & Canada)'] + # zone.formatted_offset # => "-06:00" + # zone.formatted_offset(false) # => "-0600" + def formatted_offset(colon = true, alternate_utc_string = nil) + utc_offset == 0 && alternate_utc_string || self.class.seconds_to_utc_offset(utc_offset, colon) + end + + # Compare this time zone to the parameter. The two are compared first on + # their offsets, and then by name. + def <=>(zone) + return unless zone.respond_to? :utc_offset + result = (utc_offset <=> zone.utc_offset) + result = (name <=> zone.name) if result == 0 + result + end + + # Compare #name and TZInfo identifier to a supplied regexp, returning +true+ + # if a match is found. + def =~(re) + re === name || re === MAPPING[name] + end + + # Compare #name and TZInfo identifier to a supplied regexp, returning +true+ + # if a match is found. + def match?(re) + (re == name) || (re == MAPPING[name]) || + ((Regexp === re) && (re.match?(name) || re.match?(MAPPING[name]))) + end + + # Returns a textual representation of this time zone. + def to_s + "(GMT#{formatted_offset}) #{name}" + end + + # \Method for creating new ActiveSupport::TimeWithZone instance in time zone + # of +self+ from given values. + # + # Time.zone = 'Hawaii' # => "Hawaii" + # Time.zone.local(2007, 2, 1, 15, 30, 45) # => Thu, 01 Feb 2007 15:30:45 HST -10:00 + def local(*args) + time = Time.utc(*args) + ActiveSupport::TimeWithZone.new(nil, self, time) + end + + # \Method for creating new ActiveSupport::TimeWithZone instance in time zone + # of +self+ from number of seconds since the Unix epoch. + # + # Time.zone = 'Hawaii' # => "Hawaii" + # Time.utc(2000).to_f # => 946684800.0 + # Time.zone.at(946684800.0) # => Fri, 31 Dec 1999 14:00:00 HST -10:00 + # + # A second argument can be supplied to specify sub-second precision. + # + # Time.zone = 'Hawaii' # => "Hawaii" + # Time.at(946684800, 123456.789).nsec # => 123456789 + def at(*args) + Time.at(*args).utc.in_time_zone(self) + end + + # \Method for creating new ActiveSupport::TimeWithZone instance in time zone + # of +self+ from an ISO 8601 string. + # + # Time.zone = 'Hawaii' # => "Hawaii" + # Time.zone.iso8601('1999-12-31T14:00:00') # => Fri, 31 Dec 1999 14:00:00 HST -10:00 + # + # If the time components are missing then they will be set to zero. + # + # Time.zone = 'Hawaii' # => "Hawaii" + # Time.zone.iso8601('1999-12-31') # => Fri, 31 Dec 1999 00:00:00 HST -10:00 + # + # If the string is invalid then an +ArgumentError+ will be raised unlike +parse+ + # which usually returns +nil+ when given an invalid date string. + def iso8601(str) + # Historically `Date._iso8601(nil)` returns `{}`, but in the `date` gem versions `3.2.1`, `3.1.2`, `3.0.2`, + # and `2.0.1`, `Date._iso8601(nil)` raises `TypeError` https://github.com/ruby/date/issues/39 + # Future `date` releases are expected to revert back to the original behavior. + raise ArgumentError, "invalid date" if str.nil? + + parts = Date._iso8601(str) + + year = parts.fetch(:year) + + if parts.key?(:yday) + ordinal_date = Date.ordinal(year, parts.fetch(:yday)) + month = ordinal_date.month + day = ordinal_date.day + else + month = parts.fetch(:mon) + day = parts.fetch(:mday) + end + + time = Time.new( + year, + month, + day, + parts.fetch(:hour, 0), + parts.fetch(:min, 0), + parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0), + parts.fetch(:offset, 0) + ) + + if parts[:offset] + TimeWithZone.new(time.utc, self) + else + TimeWithZone.new(nil, self, time) + end + + rescue Date::Error, KeyError + raise ArgumentError, "invalid date" + end + + # \Method for creating new ActiveSupport::TimeWithZone instance in time zone + # of +self+ from parsed string. + # + # Time.zone = 'Hawaii' # => "Hawaii" + # Time.zone.parse('1999-12-31 14:00:00') # => Fri, 31 Dec 1999 14:00:00 HST -10:00 + # + # If upper components are missing from the string, they are supplied from + # TimeZone#now: + # + # Time.zone.now # => Fri, 31 Dec 1999 14:00:00 HST -10:00 + # Time.zone.parse('22:30:00') # => Fri, 31 Dec 1999 22:30:00 HST -10:00 + # + # However, if the date component is not provided, but any other upper + # components are supplied, then the day of the month defaults to 1: + # + # Time.zone.parse('Mar 2000') # => Wed, 01 Mar 2000 00:00:00 HST -10:00 + # + # If the string is invalid then an +ArgumentError+ could be raised. + def parse(str, now = now()) + parts_to_time(Date._parse(str, false), now) + end + + # \Method for creating new ActiveSupport::TimeWithZone instance in time zone + # of +self+ from an RFC 3339 string. + # + # Time.zone = 'Hawaii' # => "Hawaii" + # Time.zone.rfc3339('2000-01-01T00:00:00Z') # => Fri, 31 Dec 1999 14:00:00 HST -10:00 + # + # If the time or zone components are missing then an +ArgumentError+ will + # be raised. This is much stricter than either +parse+ or +iso8601+ which + # allow for missing components. + # + # Time.zone = 'Hawaii' # => "Hawaii" + # Time.zone.rfc3339('1999-12-31') # => ArgumentError: invalid date + def rfc3339(str) + parts = Date._rfc3339(str) + + raise ArgumentError, "invalid date" if parts.empty? + + time = Time.new( + parts.fetch(:year), + parts.fetch(:mon), + parts.fetch(:mday), + parts.fetch(:hour), + parts.fetch(:min), + parts.fetch(:sec) + parts.fetch(:sec_fraction, 0), + parts.fetch(:offset) + ) + + TimeWithZone.new(time.utc, self) + end + + # Parses +str+ according to +format+ and returns an ActiveSupport::TimeWithZone. + # + # Assumes that +str+ is a time in the time zone +self+, + # unless +format+ includes an explicit time zone. + # (This is the same behavior as +parse+.) + # In either case, the returned TimeWithZone has the timezone of +self+. + # + # Time.zone = 'Hawaii' # => "Hawaii" + # Time.zone.strptime('1999-12-31 14:00:00', '%Y-%m-%d %H:%M:%S') # => Fri, 31 Dec 1999 14:00:00 HST -10:00 + # + # If upper components are missing from the string, they are supplied from + # TimeZone#now: + # + # Time.zone.now # => Fri, 31 Dec 1999 14:00:00 HST -10:00 + # Time.zone.strptime('22:30:00', '%H:%M:%S') # => Fri, 31 Dec 1999 22:30:00 HST -10:00 + # + # However, if the date component is not provided, but any other upper + # components are supplied, then the day of the month defaults to 1: + # + # Time.zone.strptime('Mar 2000', '%b %Y') # => Wed, 01 Mar 2000 00:00:00 HST -10:00 + def strptime(str, format, now = now()) + parts_to_time(DateTime._strptime(str, format), now) + end + + # Returns an ActiveSupport::TimeWithZone instance representing the current + # time in the time zone represented by +self+. + # + # Time.zone = 'Hawaii' # => "Hawaii" + # Time.zone.now # => Wed, 23 Jan 2008 20:24:27 HST -10:00 + def now + time_now.utc.in_time_zone(self) + end + + # Returns the current date in this time zone. + def today + tzinfo.now.to_date + end + + # Returns the next date in this time zone. + def tomorrow + today + 1 + end + + # Returns the previous date in this time zone. + def yesterday + today - 1 + end + + # Adjust the given time to the simultaneous time in the time zone + # represented by +self+. Returns a local time with the appropriate offset + # -- if you want an ActiveSupport::TimeWithZone instance, use + # Time#in_time_zone() instead. + # + # As of tzinfo 2, utc_to_local returns a Time with a non-zero utc_offset. + # See the +utc_to_local_returns_utc_offset_times+ config for more info. + def utc_to_local(time) + tzinfo.utc_to_local(time).yield_self do |t| + ActiveSupport.utc_to_local_returns_utc_offset_times ? + t : Time.utc(t.year, t.month, t.day, t.hour, t.min, t.sec, t.sec_fraction * 1_000_000) + end + end + + # Adjust the given time to the simultaneous time in UTC. Returns a + # Time.utc() instance. + def local_to_utc(time, dst = true) + tzinfo.local_to_utc(time, dst) + end + + def period_for_utc(time) # :nodoc: + tzinfo.period_for_utc(time) + end + + def period_for_local(time, dst = true) # :nodoc: + tzinfo.period_for_local(time, dst) { |periods| periods.last } + end + + def periods_for_local(time) # :nodoc: + tzinfo.periods_for_local(time) + end + + def abbr(time) # :nodoc: + tzinfo.abbr(time) + end + + def dst?(time) # :nodoc: + tzinfo.dst?(time) + end + + def init_with(coder) # :nodoc: + initialize(coder["name"]) + end + + def encode_with(coder) # :nodoc: + coder.tag = "!ruby/object:#{self.class}" + coder.map = { "name" => tzinfo.name } + end + + private + def parts_to_time(parts, now) + raise ArgumentError, "invalid date" if parts.nil? + return if parts.empty? + + if parts[:seconds] + time = Time.at(parts[:seconds]) + else + time = Time.new( + parts.fetch(:year, now.year), + parts.fetch(:mon, now.month), + parts.fetch(:mday, parts[:year] || parts[:mon] ? 1 : now.day), + parts.fetch(:hour, 0), + parts.fetch(:min, 0), + parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0), + parts.fetch(:offset, 0) + ) + end + + if parts[:offset] || parts[:seconds] + TimeWithZone.new(time.utc, self) + else + TimeWithZone.new(nil, self, time) + end + end + + def time_now + Time.now + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/version.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/version.rb new file mode 100644 index 00000000..12f83379 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/version.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require_relative "gem_version" + +module ActiveSupport + # Returns the currently loaded version of Active Support as a +Gem::Version+. + def self.version + gem_version + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/xml_mini.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/xml_mini.rb new file mode 100644 index 00000000..380d0156 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/xml_mini.rb @@ -0,0 +1,211 @@ +# frozen_string_literal: true + +require "time" +require "base64" +require "bigdecimal" +require "bigdecimal/util" +require "active_support/core_ext/module/delegation" +require "active_support/core_ext/string/inflections" +require "active_support/core_ext/date_time/calculations" + +module ActiveSupport + # = \XmlMini + # + # To use the much faster libxml parser: + # gem "libxml-ruby" + # XmlMini.backend = 'LibXML' + module XmlMini + extend self + + # This module decorates files deserialized using Hash.from_xml with + # the original_filename and content_type methods. + module FileLike # :nodoc: + attr_writer :original_filename, :content_type + + def original_filename + @original_filename || "untitled" + end + + def content_type + @content_type || "application/octet-stream" + end + end + + DEFAULT_ENCODINGS = { + "binary" => "base64" + } unless defined?(DEFAULT_ENCODINGS) + + unless defined?(TYPE_NAMES) + TYPE_NAMES = { + "Symbol" => "symbol", + "Integer" => "integer", + "BigDecimal" => "decimal", + "Float" => "float", + "TrueClass" => "boolean", + "FalseClass" => "boolean", + "Date" => "date", + "DateTime" => "dateTime", + "Time" => "dateTime", + "ActiveSupport::Duration" => "duration", + "Array" => "array", + "Hash" => "hash" + } + end + TYPE_NAMES["ActiveSupport::TimeWithZone"] = TYPE_NAMES["Time"] + + FORMATTING = { + "symbol" => Proc.new { |symbol| symbol.to_s }, + "date" => Proc.new { |date| date.to_fs(:db) }, + "dateTime" => Proc.new { |time| time.xmlschema }, + "duration" => Proc.new { |duration| duration.iso8601 }, + "binary" => Proc.new { |binary| ::Base64.encode64(binary) }, + "yaml" => Proc.new { |yaml| yaml.to_yaml } + } unless defined?(FORMATTING) + + # TODO use regexp instead of Date.parse + unless defined?(PARSING) + PARSING = { + "symbol" => Proc.new { |symbol| symbol.to_s.to_sym }, + "date" => Proc.new { |date| ::Date.parse(date) }, + "datetime" => Proc.new { |time| Time.xmlschema(time).utc rescue ::DateTime.parse(time).utc }, + "duration" => Proc.new { |duration| Duration.parse(duration) }, + "integer" => Proc.new { |integer| integer.to_i }, + "float" => Proc.new { |float| float.to_f }, + "decimal" => Proc.new do |number| + if String === number + number.to_d + else + BigDecimal(number) + end + end, + "boolean" => Proc.new { |boolean| %w(1 true).include?(boolean.to_s.strip) }, + "string" => Proc.new { |string| string.to_s }, + "yaml" => Proc.new { |yaml| YAML.load(yaml) rescue yaml }, + "base64Binary" => Proc.new { |bin| ::Base64.decode64(bin) }, + "hexBinary" => Proc.new { |bin| _parse_hex_binary(bin) }, + "binary" => Proc.new { |bin, entity| _parse_binary(bin, entity) }, + "file" => Proc.new { |file, entity| _parse_file(file, entity) } + } + + PARSING.update( + "double" => PARSING["float"], + "dateTime" => PARSING["datetime"] + ) + end + + attr_accessor :depth + self.depth = 100 + + delegate :parse, to: :backend + + def backend + current_thread_backend || @backend + end + + def backend=(name) + backend = name && cast_backend_name_to_module(name) + self.current_thread_backend = backend if current_thread_backend + @backend = backend + end + + def with_backend(name) + old_backend = current_thread_backend + self.current_thread_backend = name && cast_backend_name_to_module(name) + yield + ensure + self.current_thread_backend = old_backend + end + + def to_tag(key, value, options) + type_name = options.delete(:type) + merged_options = options.merge(root: key, skip_instruct: true) + + if value.is_a?(::Method) || value.is_a?(::Proc) + if value.arity == 1 + value.call(merged_options) + else + value.call(merged_options, key.to_s.singularize) + end + elsif value.respond_to?(:to_xml) + value.to_xml(merged_options) + else + type_name ||= TYPE_NAMES[value.class.name] + type_name ||= value.class.name if value && !value.respond_to?(:to_str) + type_name = type_name.to_s if type_name + type_name = "dateTime" if type_name == "datetime" + + key = rename_key(key.to_s, options) + + attributes = options[:skip_types] || type_name.nil? ? {} : { type: type_name } + attributes[:nil] = true if value.nil? + + encoding = options[:encoding] || DEFAULT_ENCODINGS[type_name] + attributes[:encoding] = encoding if encoding + + formatted_value = FORMATTING[type_name] && !value.nil? ? + FORMATTING[type_name].call(value) : value + + options[:builder].tag!(key, formatted_value, attributes) + end + end + + def rename_key(key, options = {}) + camelize = options[:camelize] + dasherize = !options.has_key?(:dasherize) || options[:dasherize] + if camelize + key = true == camelize ? key.camelize : key.camelize(camelize) + end + key = _dasherize(key) if dasherize + key + end + + private + def _dasherize(key) + # $2 must be a non-greedy regex for this to work + left, middle, right = /\A(_*)(.*?)(_*)\Z/.match(key.strip)[1, 3] + "#{left}#{middle.tr('_ ', '--')}#{right}" + end + + def _parse_binary(bin, entity) + case entity["encoding"] + when "base64" + ::Base64.decode64(bin) + when "hex", "hexBinary" + _parse_hex_binary(bin) + else + bin + end + end + + def _parse_file(file, entity) + f = StringIO.new(::Base64.decode64(file)) + f.extend(FileLike) + f.original_filename = entity["name"] + f.content_type = entity["content_type"] + f + end + + def _parse_hex_binary(bin) + [bin].pack("H*") + end + + def current_thread_backend + IsolatedExecutionState[:xml_mini_backend] + end + + def current_thread_backend=(name) + IsolatedExecutionState[:xml_mini_backend] = name && cast_backend_name_to_module(name) + end + + def cast_backend_name_to_module(name) + if name.is_a?(Module) + name + else + require "active_support/xml_mini/#{name.downcase}" + ActiveSupport.const_get("XmlMini_#{name}") + end + end + end + + XmlMini.backend = "REXML" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/xml_mini/jdom.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/xml_mini/jdom.rb new file mode 100644 index 00000000..f1bc0fe7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/xml_mini/jdom.rb @@ -0,0 +1,175 @@ +# frozen_string_literal: true + +raise "JRuby is required to use the JDOM backend for XmlMini" unless RUBY_PLATFORM.include?("java") + +require "jruby" +include Java + +require "active_support/core_ext/object/blank" + +java_import javax.xml.parsers.DocumentBuilder unless defined? DocumentBuilder +java_import javax.xml.parsers.DocumentBuilderFactory unless defined? DocumentBuilderFactory +java_import java.io.StringReader unless defined? StringReader +java_import org.xml.sax.InputSource unless defined? InputSource +java_import org.xml.sax.Attributes unless defined? Attributes +java_import org.w3c.dom.Node unless defined? Node + +module ActiveSupport + module XmlMini_JDOM # :nodoc: + extend self + + CONTENT_KEY = "__content__" + + # Parse an XML Document string or IO into a simple hash using Java's jdom. + # data:: + # XML Document string or IO to parse + def parse(data) + if data.respond_to?(:read) + data = data.read + end + + if data.blank? + {} + else + @dbf = DocumentBuilderFactory.new_instance + # secure processing of java xml + # https://archive.is/9xcQQ + @dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false) + @dbf.setFeature("http://xml.org/sax/features/external-general-entities", false) + @dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false) + @dbf.setFeature(javax.xml.XMLConstants::FEATURE_SECURE_PROCESSING, true) + xml_string_reader = StringReader.new(data) + xml_input_source = InputSource.new(xml_string_reader) + doc = @dbf.new_document_builder.parse(xml_input_source) + merge_element!({ CONTENT_KEY => "" }, doc.document_element, XmlMini.depth) + end + end + + private + # Convert an XML element and merge into the hash + # + # hash:: + # Hash to merge the converted element into. + # element:: + # XML element to merge into hash + def merge_element!(hash, element, depth) + raise "Document too deep!" if depth == 0 + delete_empty(hash) + merge!(hash, element.tag_name, collapse(element, depth)) + end + + def delete_empty(hash) + hash.delete(CONTENT_KEY) if hash[CONTENT_KEY] == "" + end + + # Actually converts an XML document element into a data structure. + # + # element:: + # The document element to be collapsed. + def collapse(element, depth) + hash = get_attributes(element) + + child_nodes = element.child_nodes + if child_nodes.length > 0 + (0...child_nodes.length).each do |i| + child = child_nodes.item(i) + merge_element!(hash, child, depth - 1) unless child.node_type == Node::TEXT_NODE + end + merge_texts!(hash, element) unless empty_content?(element) + hash + else + merge_texts!(hash, element) + end + end + + # Merge all the texts of an element into the hash + # + # hash:: + # Hash to add the converted element to. + # element:: + # XML element whose texts are to me merged into the hash + def merge_texts!(hash, element) + delete_empty(hash) + text_children = texts(element) + if text_children.join.empty? + hash + else + # must use value to prevent double-escaping + merge!(hash, CONTENT_KEY, text_children.join) + end + end + + # Adds a new key/value pair to an existing Hash. If the key to be added + # already exists and the existing value associated with key is not + # an Array, it will be wrapped in an Array. Then the new value is + # appended to that Array. + # + # hash:: + # Hash to add key/value pair to. + # key:: + # Key to be added. + # value:: + # Value to be associated with key. + def merge!(hash, key, value) + if hash.has_key?(key) + if hash[key].instance_of?(Array) + hash[key] << value + else + hash[key] = [hash[key], value] + end + elsif value.instance_of?(Array) + hash[key] = [value] + else + hash[key] = value + end + hash + end + + # Converts the attributes array of an XML element into a hash. + # Returns an empty Hash if node has no attributes. + # + # element:: + # XML element to extract attributes from. + def get_attributes(element) + attribute_hash = {} + attributes = element.attributes + (0...attributes.length).each do |i| + attribute_hash[CONTENT_KEY] ||= "" + attribute_hash[attributes.item(i).name] = attributes.item(i).value + end + attribute_hash + end + + # Determines if a document element has text content + # + # element:: + # XML element to be checked. + def texts(element) + texts = [] + child_nodes = element.child_nodes + (0...child_nodes.length).each do |i| + item = child_nodes.item(i) + if item.node_type == Node::TEXT_NODE + texts << item.get_data + end + end + texts + end + + # Determines if a document element has text content + # + # element:: + # XML element to be checked. + def empty_content?(element) + text = +"" + child_nodes = element.child_nodes + (0...child_nodes.length).each do |i| + item = child_nodes.item(i) + if item.node_type == Node::TEXT_NODE + text << item.get_data.strip + end + end + text.strip.length == 0 + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/xml_mini/libxml.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/xml_mini/libxml.rb new file mode 100644 index 00000000..65976a2b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/xml_mini/libxml.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: true + +require "libxml" +require "active_support/core_ext/object/blank" +require "stringio" + +module ActiveSupport + module XmlMini_LibXML # :nodoc: + extend self + + # Parse an XML Document string or IO into a simple hash using libxml. + # data:: + # XML Document string or IO to parse + def parse(data) + if !data.respond_to?(:read) + data = StringIO.new(data || "") + end + + if data.eof? + {} + else + LibXML::XML::Parser.io(data).parse.to_hash + end + end + end +end + +module LibXML # :nodoc: + module Conversions # :nodoc: + module Document # :nodoc: + def to_hash + root.to_hash + end + end + + module Node # :nodoc: + CONTENT_ROOT = "__content__" + + # Convert XML document to hash. + # + # hash:: + # Hash to merge the converted element into. + def to_hash(hash = {}) + node_hash = {} + + # Insert node hash into parent hash correctly. + case hash[name] + when Array then hash[name] << node_hash + when Hash then hash[name] = [hash[name], node_hash] + when nil then hash[name] = node_hash + end + + # Handle child elements + each_child do |c| + if c.element? + c.to_hash(node_hash) + elsif c.text? || c.cdata? + node_hash[CONTENT_ROOT] ||= +"" + node_hash[CONTENT_ROOT] << c.content + end + end + + # Remove content node if it is blank + if node_hash.length > 1 && node_hash[CONTENT_ROOT].blank? + node_hash.delete(CONTENT_ROOT) + end + + # Handle attributes + each_attr { |a| node_hash[a.name] = a.value } + + hash + end + end + end +end + +# :enddoc: + +LibXML::XML::Document.include(LibXML::Conversions::Document) +LibXML::XML::Node.include(LibXML::Conversions::Node) diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/xml_mini/libxmlsax.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/xml_mini/libxmlsax.rb new file mode 100644 index 00000000..33d594c4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/xml_mini/libxmlsax.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +require "libxml" +require "active_support/core_ext/object/blank" +require "stringio" + +module ActiveSupport + module XmlMini_LibXMLSAX # :nodoc: + extend self + + # Class that will build the hash while the XML document + # is being parsed using SAX events. + class HashBuilder + include LibXML::XML::SaxParser::Callbacks + + CONTENT_KEY = "__content__" + HASH_SIZE_KEY = "__hash_size__" + + attr_reader :hash + + def current_hash + @hash_stack.last + end + + def on_start_document + @hash = { CONTENT_KEY => +"" } + @hash_stack = [@hash] + end + + def on_end_document + @hash = @hash_stack.pop + @hash.delete(CONTENT_KEY) + end + + def on_start_element(name, attrs = {}) + new_hash = { CONTENT_KEY => +"" }.merge!(attrs) + new_hash[HASH_SIZE_KEY] = new_hash.size + 1 + + case current_hash[name] + when Array then current_hash[name] << new_hash + when Hash then current_hash[name] = [current_hash[name], new_hash] + when nil then current_hash[name] = new_hash + end + + @hash_stack.push(new_hash) + end + + def on_end_element(name) + if current_hash.length > current_hash.delete(HASH_SIZE_KEY) && current_hash[CONTENT_KEY].blank? || current_hash[CONTENT_KEY] == "" + current_hash.delete(CONTENT_KEY) + end + @hash_stack.pop + end + + def on_characters(string) + current_hash[CONTENT_KEY] << string + end + + alias_method :on_cdata_block, :on_characters + end + + attr_accessor :document_class + self.document_class = HashBuilder + + def parse(data) + if !data.respond_to?(:read) + data = StringIO.new(data || "") + end + + if data.eof? + {} + else + LibXML::XML::Error.set_handler(&LibXML::XML::Error::QUIET_HANDLER) + parser = LibXML::XML::SaxParser.io(data) + document = document_class.new + + parser.callbacks = document + parser.parse + document.hash + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/xml_mini/nokogiri.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/xml_mini/nokogiri.rb new file mode 100644 index 00000000..3d9cf342 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/xml_mini/nokogiri.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +begin + require "nokogiri" +rescue LoadError => e + warn "You don't have nokogiri installed in your application. Please add it to your Gemfile and run bundle install" + raise e +end +require "active_support/core_ext/object/blank" +require "stringio" + +module ActiveSupport + module XmlMini_Nokogiri # :nodoc: + extend self + + # Parse an XML Document string or IO into a simple hash using libxml / nokogiri. + # data:: + # XML Document string or IO to parse + def parse(data) + if !data.respond_to?(:read) + data = StringIO.new(data || "") + end + + if data.eof? + {} + else + doc = Nokogiri::XML(data) + raise doc.errors.first if doc.errors.length > 0 + doc.to_hash + end + end + + module Conversions # :nodoc: + module Document # :nodoc: + def to_hash + root.to_hash + end + end + + module Node # :nodoc: + CONTENT_ROOT = "__content__" + + # Convert XML document to hash. + # + # hash:: + # Hash to merge the converted element into. + def to_hash(hash = {}) + node_hash = {} + + # Insert node hash into parent hash correctly. + case hash[name] + when Array then hash[name] << node_hash + when Hash then hash[name] = [hash[name], node_hash] + when nil then hash[name] = node_hash + end + + # Handle child elements + children.each do |c| + if c.element? + c.to_hash(node_hash) + elsif c.text? || c.cdata? + node_hash[CONTENT_ROOT] ||= +"" + node_hash[CONTENT_ROOT] << c.content + end + end + + # Remove content node if it is blank and there are child tags + if node_hash.length > 1 && node_hash[CONTENT_ROOT].blank? + node_hash.delete(CONTENT_ROOT) + end + + # Handle attributes + attribute_nodes.each { |a| node_hash[a.node_name] = a.value } + + hash + end + end + end + + Nokogiri::XML::Document.include(Conversions::Document) + Nokogiri::XML::Node.include(Conversions::Node) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/xml_mini/nokogirisax.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/xml_mini/nokogirisax.rb new file mode 100644 index 00000000..9316f92b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/xml_mini/nokogirisax.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true + +begin + require "nokogiri" +rescue LoadError => e + warn "You don't have nokogiri installed in your application. Please add it to your Gemfile and run bundle install" + raise e +end +require "active_support/core_ext/object/blank" +require "stringio" + +module ActiveSupport + module XmlMini_NokogiriSAX # :nodoc: + extend self + + # Class that will build the hash while the XML document + # is being parsed using SAX events. + class HashBuilder < Nokogiri::XML::SAX::Document + CONTENT_KEY = "__content__" + HASH_SIZE_KEY = "__hash_size__" + + attr_reader :hash + + def current_hash + @hash_stack.last + end + + def start_document + @hash = {} + @hash_stack = [@hash] + end + + def end_document + raise "Parse stack not empty!" if @hash_stack.size > 1 + end + + def error(error_message) + raise error_message + end + + def start_element(name, attrs = []) + new_hash = { CONTENT_KEY => +"" }.merge!(Hash[attrs]) + new_hash[HASH_SIZE_KEY] = new_hash.size + 1 + + case current_hash[name] + when Array then current_hash[name] << new_hash + when Hash then current_hash[name] = [current_hash[name], new_hash] + when nil then current_hash[name] = new_hash + end + + @hash_stack.push(new_hash) + end + + def end_element(name) + if current_hash.length > current_hash.delete(HASH_SIZE_KEY) && current_hash[CONTENT_KEY].blank? || current_hash[CONTENT_KEY] == "" + current_hash.delete(CONTENT_KEY) + end + @hash_stack.pop + end + + def characters(string) + current_hash[CONTENT_KEY] << string + end + + alias_method :cdata_block, :characters + end + + attr_accessor :document_class + self.document_class = HashBuilder + + def parse(data) + if !data.respond_to?(:read) + data = StringIO.new(data || "") + end + + if data.eof? + {} + else + document = document_class.new + parser = Nokogiri::XML::SAX::Parser.new(document) + parser.parse(data) + document.hash + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/xml_mini/rexml.rb b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/xml_mini/rexml.rb new file mode 100644 index 00000000..393749ab --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/activesupport-8.0.2/lib/active_support/xml_mini/rexml.rb @@ -0,0 +1,137 @@ +# frozen_string_literal: true + +require "active_support/core_ext/kernel/reporting" +require "active_support/core_ext/object/blank" +require "stringio" + +module ActiveSupport + module XmlMini_REXML # :nodoc: + extend self + + CONTENT_KEY = "__content__" + + # Parse an XML Document string or IO into a simple hash. + # + # Same as XmlSimple::xml_in but doesn't shoot itself in the foot, + # and uses the defaults from Active Support. + # + # data:: + # XML Document string or IO to parse + def parse(data) + if !data.respond_to?(:read) + data = StringIO.new(data || "") + end + + if data.eof? + {} + else + require_rexml unless defined?(REXML::Document) + doc = REXML::Document.new(data) + + if doc.root + merge_element!({}, doc.root, XmlMini.depth) + else + raise REXML::ParseException, + "The document #{doc.to_s.inspect} does not have a valid root" + end + end + end + + private + def require_rexml + silence_warnings { require "rexml/document" } + rescue LoadError => e + warn "You don't have rexml installed in your application. Please add it to your Gemfile and run bundle install" + raise e + end + + # Convert an XML element and merge into the hash + # + # hash:: + # Hash to merge the converted element into. + # element:: + # XML element to merge into hash + def merge_element!(hash, element, depth) + raise REXML::ParseException, "The document is too deep" if depth == 0 + merge!(hash, element.name, collapse(element, depth)) + end + + # Actually converts an XML document element into a data structure. + # + # element:: + # The document element to be collapsed. + def collapse(element, depth) + hash = get_attributes(element) + + if element.has_elements? + element.each_element { |child| merge_element!(hash, child, depth - 1) } + merge_texts!(hash, element) unless empty_content?(element) + hash + else + merge_texts!(hash, element) + end + end + + # Merge all the texts of an element into the hash + # + # hash:: + # Hash to add the converted element to. + # element:: + # XML element whose texts are to me merged into the hash + def merge_texts!(hash, element) + unless element.has_text? + hash + else + # must use value to prevent double-escaping + texts = +"" + element.texts.each { |t| texts << t.value } + merge!(hash, CONTENT_KEY, texts) + end + end + + # Adds a new key/value pair to an existing Hash. If the key to be added + # already exists and the existing value associated with key is not + # an Array, it will be wrapped in an Array. Then the new value is + # appended to that Array. + # + # hash:: + # Hash to add key/value pair to. + # key:: + # Key to be added. + # value:: + # Value to be associated with key. + def merge!(hash, key, value) + if hash.has_key?(key) + if hash[key].instance_of?(Array) + hash[key] << value + else + hash[key] = [hash[key], value] + end + elsif value.instance_of?(Array) + hash[key] = [value] + else + hash[key] = value + end + hash + end + + # Converts the attributes array of an XML element into a hash. + # Returns an empty Hash if node has no attributes. + # + # element:: + # XML element to extract attributes from. + def get_attributes(element) + attributes = {} + element.attributes.each { |n, v| attributes[n] = v } + attributes + end + + # Determines if a document element has text content + # + # element:: + # XML element to be checked. + def empty_content?(element) + element.texts.join.blank? + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/CHANGELOG.md b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/CHANGELOG.md new file mode 100644 index 00000000..bf21002e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/CHANGELOG.md @@ -0,0 +1,301 @@ +# Addressable 2.8.7 +- Allow `public_suffix` 6 ([#535]) + +[#535]: https://github.com/sporkmonger/addressable/pull/535 + +# Addressable 2.8.6 +- Memoize regexps for common character classes ([#524]) + +[#524]: https://github.com/sporkmonger/addressable/pull/524 + +# Addressable 2.8.5 +- Fix thread safety issue with encoding tables ([#515]) +- Define URI::NONE as a module to avoid serialization issues ([#509]) +- Fix YAML serialization ([#508]) + +[#508]: https://github.com/sporkmonger/addressable/pull/508 +[#509]: https://github.com/sporkmonger/addressable/pull/509 +[#515]: https://github.com/sporkmonger/addressable/pull/515 + +# Addressable 2.8.4 +- Restore `Addressable::IDNA.unicode_normalize_kc` as a deprecated method ([#504]) + +[#504]: https://github.com/sporkmonger/addressable/pull/504 + +# Addressable 2.8.3 +- Fix template expand level 2 hash support for non-string objects ([#499], [#498]) + +[#499]: https://github.com/sporkmonger/addressable/pull/499 +[#498]: https://github.com/sporkmonger/addressable/pull/498 + +# Addressable 2.8.2 +- Improve cache hits and JIT friendliness ([#486](https://github.com/sporkmonger/addressable/pull/486)) +- Improve code style and test coverage ([#482](https://github.com/sporkmonger/addressable/pull/482)) +- Ensure reset of deferred validation ([#481](https://github.com/sporkmonger/addressable/pull/481)) +- Resolve normalization differences between `IDNA::Native` and `IDNA::Pure` ([#408](https://github.com/sporkmonger/addressable/issues/408), [#492]) +- Remove redundant colon in `Addressable::URI::CharacterClasses::AUTHORITY` regex ([#438](https://github.com/sporkmonger/addressable/pull/438)) (accidentally reverted by [#449] merge but [added back](https://github.com/sporkmonger/addressable/pull/492#discussion_r1105125280) in [#492]) + +[#492]: https://github.com/sporkmonger/addressable/pull/492 + +# Addressable 2.8.1 +- refactor `Addressable::URI.normalize_path` to address linter offenses ([#430](https://github.com/sporkmonger/addressable/pull/430)) +- update gemspec to reflect supported Ruby versions ([#466], [#464], [#463]) +- compatibility w/ public_suffix 5.x ([#466], [#465], [#460]) +- fixes "invalid byte sequence in UTF-8" exception when unencoding URLs containing non UTF-8 characters ([#459](https://github.com/sporkmonger/addressable/pull/459)) +- `Ractor` compatibility ([#449]) +- use the whole string instead of a single line for template match ([#431](https://github.com/sporkmonger/addressable/pull/431)) +- force UTF-8 encoding only if needed ([#341](https://github.com/sporkmonger/addressable/pull/341)) + +[#449]: https://github.com/sporkmonger/addressable/pull/449 +[#460]: https://github.com/sporkmonger/addressable/pull/460 +[#463]: https://github.com/sporkmonger/addressable/pull/463 +[#464]: https://github.com/sporkmonger/addressable/pull/464 +[#465]: https://github.com/sporkmonger/addressable/pull/465 +[#466]: https://github.com/sporkmonger/addressable/pull/466 + +# Addressable 2.8.0 +- fixes ReDoS vulnerability in Addressable::Template#match +- no longer replaces `+` with spaces in queries for non-http(s) schemes +- fixed encoding ipv6 literals +- the `:compacted` flag for `normalized_query` now dedupes parameters +- fix broken `escape_component` alias +- dropping support for Ruby 2.0 and 2.1 +- adding Ruby 3.0 compatibility for development tasks +- drop support for `rack-mount` and remove Addressable::Template#generate +- performance improvements +- switch CI/CD to GitHub Actions + +# Addressable 2.7.0 +- added `:compacted` flag to `normalized_query` +- `heuristic_parse` handles `mailto:` more intuitively +- dropped explicit support for JRuby 9.0.5.0 +- compatibility w/ public_suffix 4.x +- performance improvements + +# Addressable 2.6.0 +- added `tld=` method to allow assignment to the public suffix +- most `heuristic_parse` patterns are now case-insensitive +- `heuristic_parse` handles more `file://` URI variations +- fixes bug in `heuristic_parse` when uri starts with digit +- fixes bug in `request_uri=` with query strings +- fixes template issues with `nil` and `?` operator +- `frozen_string_literal` pragmas added +- minor performance improvements in regexps +- fixes to eliminate warnings + +# Addressable 2.5.2 +- better support for frozen string literals +- fixed bug w/ uppercase characters in scheme +- IDNA errors w/ emoji URLs +- compatibility w/ public_suffix 3.x + +# Addressable 2.5.1 +- allow unicode normalization to be disabled for URI Template expansion +- removed duplicate test + +# Addressable 2.5.0 +- dropping support for Ruby 1.9 +- adding support for Ruby 2.4 preview +- add support for public suffixes and tld; first runtime dependency +- hostname escaping should match RFC; underscores in hostnames no longer escaped +- paths beginning with // and missing an authority are now considered invalid +- validation now also takes place after setting a path +- handle backslashes in authority more like a browser for `heuristic_parse` +- unescaped backslashes in host now raise an `InvalidURIError` +- `merge!`, `join!`, `omit!` and `normalize!` don't disable deferred validation +- `heuristic_parse` now trims whitespace before parsing +- host parts longer than 63 bytes will be ignored and not passed to libidn +- normalized values always encoded as UTF-8 + +# Addressable 2.4.0 +- support for 1.8.x dropped +- double quotes in a host now raises an error +- newlines in host will no longer get unescaped during normalization +- stricter handling of bogus scheme values +- stricter handling of encoded port values +- calling `require 'addressable'` will now load both the URI and Template files +- assigning to the `hostname` component with an `IPAddr` object is now supported +- assigning to the `origin` component is now supported +- fixed minor bug where an exception would be thrown for a missing ACE suffix +- better partial expansion of URI templates + +# Addressable 2.3.8 +- fix warnings +- update dependency gems +- support for 1.8.x officially deprecated + +# Addressable 2.3.7 +- fix scenario in which invalid URIs don't get an exception until inspected +- handle hostnames with two adjacent periods correctly +- upgrade of RSpec + +# Addressable 2.3.6 +- normalization drops empty query string +- better handling in template extract for missing values +- template modifier for `'?'` now treated as optional +- fixed issue where character class parameters were modified +- templates can now be tested for equality +- added `:sorted` option to normalization of query strings +- fixed issue with normalization of hosts given in `'example.com.'` form + +# Addressable 2.3.5 +- added Addressable::URI#empty? method +- Addressable::URI#hostname methods now strip square brackets from IPv6 hosts +- compatibility with Net::HTTP in Ruby 2.0.0 +- Addressable::URI#route_from should always give relative URIs + +# Addressable 2.3.4 +- fixed issue with encoding altering its inputs +- query string normalization now leaves ';' characters alone +- FakeFS is detected before attempting to load unicode tables +- additional testing to ensure frozen objects don't cause problems + +# Addressable 2.3.3 +- fixed issue with converting common primitives during template expansion +- fixed port encoding issue +- removed a few warnings +- normalize should now ignore %2B in query strings +- the IDNA logic should now be handled by libidn in Ruby 1.9 +- no template match should now result in nil instead of an empty MatchData +- added license information to gemspec + +# Addressable 2.3.2 +- added Addressable::URI#default_port method +- fixed issue with Marshalling Unicode data on Windows +- improved heuristic parsing to better handle IPv4 addresses + +# Addressable 2.3.1 +- fixed missing unicode data file + +# Addressable 2.3.0 +- updated Addressable::Template to use RFC 6570, level 4 +- fixed compatibility problems with some versions of Ruby +- moved unicode tables into a data file for performance reasons +- removing support for multiple query value notations + +# Addressable 2.2.8 +- fixed issues with dot segment removal code +- form encoding can now handle multiple values per key +- updated development environment + +# Addressable 2.2.7 +- fixed issues related to Addressable::URI#query_values= +- the Addressable::URI.parse method is now polymorphic + +# Addressable 2.2.6 +- changed the way ambiguous paths are handled +- fixed bug with frozen URIs +- https supported in heuristic parsing + +# Addressable 2.2.5 +- 'parsing' a pre-parsed URI object is now a dup operation +- introduced conditional support for libidn +- fixed normalization issue on ampersands in query strings +- added additional tests around handling of query strings + +# Addressable 2.2.4 +- added origin support from draft-ietf-websec-origin-00 +- resolved issue with attempting to navigate below root +- fixed bug with string splitting in query strings + +# Addressable 2.2.3 +- added :flat_array notation for query strings + +# Addressable 2.2.2 +- fixed issue with percent escaping of '+' character in query strings + +# Addressable 2.2.1 +- added support for application/x-www-form-urlencoded. + +# Addressable 2.2.0 +- added site methods +- improved documentation + +# Addressable 2.1.2 +- added HTTP request URI methods +- better handling of Windows file paths +- validation_deferred boolean replaced with defer_validation block +- normalization of percent-encoded paths should now be correct +- fixed issue with constructing URIs with relative paths +- fixed warnings + +# Addressable 2.1.1 +- more type checking changes +- fixed issue with unicode normalization +- added method to find template defaults +- symbolic keys are now allowed in template mappings +- numeric values and symbolic values are now allowed in template mappings + +# Addressable 2.1.0 +- refactored URI template support out into its own class +- removed extract method due to being useless and unreliable +- removed Addressable::URI.expand_template +- removed Addressable::URI#extract_mapping +- added partial template expansion +- fixed minor bugs in the parse and heuristic_parse methods +- fixed incompatibility with Ruby 1.9.1 +- fixed bottleneck in Addressable::URI#hash and Addressable::URI#to_s +- fixed unicode normalization exception +- updated query_values methods to better handle subscript notation +- worked around issue with freezing URIs +- improved specs + +# Addressable 2.0.2 +- fixed issue with URI template expansion +- fixed issue with percent escaping characters 0-15 + +# Addressable 2.0.1 +- fixed issue with query string assignment +- fixed issue with improperly encoded components + +# Addressable 2.0.0 +- the initialize method now takes an options hash as its only parameter +- added query_values method to URI class +- completely replaced IDNA implementation with pure Ruby +- renamed Addressable::ADDRESSABLE_VERSION to Addressable::VERSION +- completely reworked the Rakefile +- changed the behavior of the port method significantly +- Addressable::URI.encode_segment, Addressable::URI.unencode_segment renamed +- documentation is now in YARD format +- more rigorous type checking +- to_str method implemented, implicit conversion to Strings now allowed +- Addressable::URI#omit method added, Addressable::URI#merge method replaced +- updated URI Template code to match v 03 of the draft spec +- added a bunch of new specifications + +# Addressable 1.0.4 +- switched to using RSpec's pending system for specs that rely on IDN +- fixed issue with creating URIs with paths that are not prefixed with '/' + +# Addressable 1.0.3 +- implemented a hash method + +# Addressable 1.0.2 +- fixed minor bug with the extract_mapping method + +# Addressable 1.0.1 +- fixed minor bug with the extract_mapping method + +# Addressable 1.0.0 +- heuristic parse method added +- parsing is slightly more strict +- replaced to_h with to_hash +- fixed routing methods +- improved specifications +- improved heckle rake task +- no surviving heckle mutations + +# Addressable 0.1.2 +- improved normalization +- fixed bug in joining algorithm +- updated specifications + +# Addressable 0.1.1 +- updated documentation +- added URI Template variable extraction + +# Addressable 0.1.0 +- initial release +- implementation based on RFC 3986, 3987 +- support for IRIs via libidn +- support for the URI Template draft spec diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/Gemfile b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/Gemfile new file mode 100644 index 00000000..87cf7719 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/Gemfile @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +source 'https://rubygems.org' + +gemspec + +group :test do + gem 'bigdecimal' if RUBY_VERSION > '2.4' + gem 'rspec', '~> 3.8' + gem 'rspec-its', '~> 1.3' +end + +group :coverage do + gem "coveralls", "> 0.7", require: false, platforms: :mri + gem "simplecov", require: false +end + +group :development do + gem 'launchy', '~> 2.4', '>= 2.4.3' + gem 'redcarpet', :platform => :mri_19 + gem 'yard' +end + +group :test, :development do + gem 'memory_profiler' + gem "rake", ">= 12.3.3" +end + +unless ENV["IDNA_MODE"] == "pure" + gem "idn-ruby", platform: :mri +end diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/LICENSE.txt b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/LICENSE.txt new file mode 100644 index 00000000..ef51da2b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/README.md b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/README.md new file mode 100644 index 00000000..9892f615 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/README.md @@ -0,0 +1,121 @@ +# Addressable + +
+
Homepage
github.com/sporkmonger/addressable
+
Author
Bob Aman
+
Copyright
Copyright © Bob Aman
+
License
Apache 2.0
+
+ +[![Gem Version](https://img.shields.io/gem/dt/addressable.svg)][gem] +[![Build Status](https://github.com/sporkmonger/addressable/workflows/CI/badge.svg)][actions] +[![Test Coverage Status](https://img.shields.io/coveralls/sporkmonger/addressable.svg)][coveralls] +[![Documentation Coverage Status](https://inch-ci.org/github/sporkmonger/addressable.svg?branch=master)][inch] + +[gem]: https://rubygems.org/gems/addressable +[actions]: https://github.com/sporkmonger/addressable/actions +[coveralls]: https://coveralls.io/r/sporkmonger/addressable +[inch]: https://inch-ci.org/github/sporkmonger/addressable + +# Description + +Addressable is an alternative implementation to the URI implementation +that is part of Ruby's standard library. It is flexible, offers heuristic +parsing, and additionally provides extensive support for IRIs and URI templates. + +Addressable closely conforms to RFC 3986, RFC 3987, and RFC 6570 (level 4). + +# Reference + +- {Addressable::URI} +- {Addressable::Template} + +# Example usage + +```ruby +require "addressable/uri" + +uri = Addressable::URI.parse("http://example.com/path/to/resource/") +uri.scheme +#=> "http" +uri.host +#=> "example.com" +uri.path +#=> "/path/to/resource/" + +uri = Addressable::URI.parse("http://www.詹姆斯.com/") +uri.normalize +#=> # +``` + + +# URI Templates + +For more details, see [RFC 6570](https://www.rfc-editor.org/rfc/rfc6570.txt). + + +```ruby + +require "addressable/template" + +template = Addressable::Template.new("http://example.com/{?query*}") +template.expand({ + "query" => { + 'foo' => 'bar', + 'color' => 'red' + } +}) +#=> # + +template = Addressable::Template.new("http://example.com/{?one,two,three}") +template.partial_expand({"one" => "1", "three" => 3}).pattern +#=> "http://example.com/?one=1{&two}&three=3" + +template = Addressable::Template.new( + "http://{host}{/segments*}/{?one,two,bogus}{#fragment}" +) +uri = Addressable::URI.parse( + "http://example.com/a/b/c/?one=1&two=2#foo" +) +template.extract(uri) +#=> +# { +# "host" => "example.com", +# "segments" => ["a", "b", "c"], +# "one" => "1", +# "two" => "2", +# "fragment" => "foo" +# } +``` + +# Install + +```console +$ gem install addressable +``` + +You may optionally turn on native IDN support by installing libidn and the +idn gem: + +```console +$ sudo apt-get install libidn11-dev # Debian/Ubuntu +$ brew install libidn # OS X +$ gem install idn-ruby +``` + +# Semantic Versioning + +This project uses [Semantic Versioning](https://semver.org/). You can (and should) specify your +dependency using a pessimistic version constraint covering the major and minor +values: + +```ruby +spec.add_dependency 'addressable', '~> 2.7' +``` + +If you need a specific bug fix, you can also specify minimum tiny versions +without preventing updates to the latest minor release: + +```ruby +spec.add_dependency 'addressable', '~> 2.3', '>= 2.3.7' +``` diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/Rakefile b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/Rakefile new file mode 100644 index 00000000..46fbbd0a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/Rakefile @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'rubygems' +require 'rake' + +require File.join(File.dirname(__FILE__), 'lib', 'addressable', 'version') + +PKG_DISPLAY_NAME = 'Addressable' +PKG_NAME = PKG_DISPLAY_NAME.downcase +PKG_VERSION = Addressable::VERSION::STRING +PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}" + +RELEASE_NAME = "REL #{PKG_VERSION}" + +PKG_SUMMARY = "URI Implementation" +PKG_DESCRIPTION = <<-TEXT +Addressable is an alternative implementation to the URI implementation that is +part of Ruby's standard library. It is flexible, offers heuristic parsing, and +additionally provides extensive support for IRIs and URI templates. +TEXT + +PKG_FILES = FileList[ + "data/**/*", + "lib/**/*.rb", + "spec/**/*.rb", + "tasks/**/*.rake", + "addressable.gemspec", + "CHANGELOG.md", + "Gemfile", + "LICENSE.txt", + "README.md", + "Rakefile", +] + +task :default => "spec" + +Dir['tasks/**/*.rake'].each { |rake| load rake } diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/addressable.gemspec b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/addressable.gemspec new file mode 100644 index 00000000..bb1f2fa7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/addressable.gemspec @@ -0,0 +1,28 @@ +# -*- encoding: utf-8 -*- +# stub: addressable 2.8.7 ruby lib + +Gem::Specification.new do |s| + s.name = "addressable".freeze + s.version = "2.8.7".freeze + + s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= + s.metadata = { "changelog_uri" => "https://github.com/sporkmonger/addressable/blob/main/CHANGELOG.md#v2.8.7" } if s.respond_to? :metadata= + s.require_paths = ["lib".freeze] + s.authors = ["Bob Aman".freeze] + s.date = "2024-06-21" + s.description = "Addressable is an alternative implementation to the URI implementation that is\npart of Ruby's standard library. It is flexible, offers heuristic parsing, and\nadditionally provides extensive support for IRIs and URI templates.\n".freeze + s.email = "bob@sporkmonger.com".freeze + s.extra_rdoc_files = ["README.md".freeze] + s.files = ["CHANGELOG.md".freeze, "Gemfile".freeze, "LICENSE.txt".freeze, "README.md".freeze, "Rakefile".freeze, "addressable.gemspec".freeze, "data/unicode.data".freeze, "lib/addressable.rb".freeze, "lib/addressable/idna.rb".freeze, "lib/addressable/idna/native.rb".freeze, "lib/addressable/idna/pure.rb".freeze, "lib/addressable/template.rb".freeze, "lib/addressable/uri.rb".freeze, "lib/addressable/version.rb".freeze, "spec/addressable/idna_spec.rb".freeze, "spec/addressable/net_http_compat_spec.rb".freeze, "spec/addressable/security_spec.rb".freeze, "spec/addressable/template_spec.rb".freeze, "spec/addressable/uri_spec.rb".freeze, "spec/spec_helper.rb".freeze, "tasks/clobber.rake".freeze, "tasks/gem.rake".freeze, "tasks/git.rake".freeze, "tasks/metrics.rake".freeze, "tasks/profile.rake".freeze, "tasks/rspec.rake".freeze, "tasks/yard.rake".freeze] + s.homepage = "https://github.com/sporkmonger/addressable".freeze + s.licenses = ["Apache-2.0".freeze] + s.rdoc_options = ["--main".freeze, "README.md".freeze] + s.required_ruby_version = Gem::Requirement.new(">= 2.2".freeze) + s.rubygems_version = "3.5.11".freeze + s.summary = "URI Implementation".freeze + + s.specification_version = 4 + + s.add_runtime_dependency(%q.freeze, [">= 2.0.2".freeze, "< 7.0".freeze]) + s.add_development_dependency(%q.freeze, [">= 1.0".freeze, "< 3.0".freeze]) +end diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/data/unicode.data b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/data/unicode.data new file mode 100644 index 00000000..cdfc2241 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/data/unicode.data differ diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/lib/addressable.rb b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/lib/addressable.rb new file mode 100644 index 00000000..b4e98b69 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/lib/addressable.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +require 'addressable/uri' +require 'addressable/template' diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/lib/addressable/idna.rb b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/lib/addressable/idna.rb new file mode 100644 index 00000000..2dbd3934 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/lib/addressable/idna.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +#-- +# Copyright (C) Bob Aman +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#++ + + +begin + require "addressable/idna/native" +rescue LoadError + # libidn or the idn gem was not available, fall back on a pure-Ruby + # implementation... + require "addressable/idna/pure" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/lib/addressable/idna/native.rb b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/lib/addressable/idna/native.rb new file mode 100644 index 00000000..a718364f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/lib/addressable/idna/native.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +#-- +# Copyright (C) Bob Aman +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#++ + + +require "idn" + +module Addressable + module IDNA + def self.punycode_encode(value) + IDN::Punycode.encode(value.to_s) + end + + def self.punycode_decode(value) + IDN::Punycode.decode(value.to_s) + end + + class << self + # @deprecated Use {String#unicode_normalize(:nfkc)} instead + def unicode_normalize_kc(value) + value.to_s.unicode_normalize(:nfkc) + end + + extend Gem::Deprecate + deprecate :unicode_normalize_kc, "String#unicode_normalize(:nfkc)", 2023, 4 + end + + def self.to_ascii(value) + value.to_s.split('.', -1).map do |segment| + if segment.size > 0 && segment.size < 64 + IDN::Idna.toASCII(segment, IDN::Idna::ALLOW_UNASSIGNED) + elsif segment.size >= 64 + segment + else + '' + end + end.join('.') + end + + def self.to_unicode(value) + value.to_s.split('.', -1).map do |segment| + if segment.size > 0 && segment.size < 64 + IDN::Idna.toUnicode(segment, IDN::Idna::ALLOW_UNASSIGNED) + elsif segment.size >= 64 + segment + else + '' + end + end.join('.') + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/lib/addressable/idna/pure.rb b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/lib/addressable/idna/pure.rb new file mode 100644 index 00000000..3d6ffbad --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/lib/addressable/idna/pure.rb @@ -0,0 +1,505 @@ +# frozen_string_literal: true + +#-- +# Copyright (C) Bob Aman +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#++ + + +module Addressable + module IDNA + # This module is loosely based on idn_actionmailer by Mick Staugaard, + # the unicode library by Yoshida Masato, and the punycode implementation + # by Kazuhiro Nishiyama. Most of the code was copied verbatim, but + # some reformatting was done, and some translation from C was done. + # + # Without their code to work from as a base, we'd all still be relying + # on the presence of libidn. Which nobody ever seems to have installed. + # + # Original sources: + # http://github.com/staugaard/idn_actionmailer + # http://www.yoshidam.net/Ruby.html#unicode + # http://rubyforge.org/frs/?group_id=2550 + + + UNICODE_TABLE = File.expand_path( + File.join(File.dirname(__FILE__), '../../..', 'data/unicode.data') + ) + + ACE_PREFIX = "xn--" + + UTF8_REGEX = /\A(?: + [\x09\x0A\x0D\x20-\x7E] # ASCII + | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte + | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs + | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte + | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates + | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 + | [\xF1-\xF3][\x80-\xBF]{3} # planes 4nil5 + | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 + )*\z/mnx + + UTF8_REGEX_MULTIBYTE = /(?: + [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte + | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs + | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte + | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates + | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 + | [\xF1-\xF3][\x80-\xBF]{3} # planes 4nil5 + | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 + )/mnx + + # :startdoc: + + # Converts from a Unicode internationalized domain name to an ASCII + # domain name as described in RFC 3490. + def self.to_ascii(input) + input = input.to_s unless input.is_a?(String) + input = input.dup.force_encoding(Encoding::UTF_8).unicode_normalize(:nfkc) + if input.respond_to?(:force_encoding) + input.force_encoding(Encoding::ASCII_8BIT) + end + if input =~ UTF8_REGEX && input =~ UTF8_REGEX_MULTIBYTE + parts = unicode_downcase(input).split('.') + parts.map! do |part| + if part.respond_to?(:force_encoding) + part.force_encoding(Encoding::ASCII_8BIT) + end + if part =~ UTF8_REGEX && part =~ UTF8_REGEX_MULTIBYTE + ACE_PREFIX + punycode_encode(part) + else + part + end + end + parts.join('.') + else + input + end + end + + # Converts from an ASCII domain name to a Unicode internationalized + # domain name as described in RFC 3490. + def self.to_unicode(input) + input = input.to_s unless input.is_a?(String) + parts = input.split('.') + parts.map! do |part| + if part =~ /^#{ACE_PREFIX}(.+)/ + begin + punycode_decode(part[/^#{ACE_PREFIX}(.+)/, 1]) + rescue Addressable::IDNA::PunycodeBadInput + # toUnicode is explicitly defined as never-fails by the spec + part + end + else + part + end + end + output = parts.join('.') + if output.respond_to?(:force_encoding) + output.force_encoding(Encoding::UTF_8) + end + output + end + + class << self + # @deprecated Use {String#unicode_normalize(:nfkc)} instead + def unicode_normalize_kc(value) + value.to_s.unicode_normalize(:nfkc) + end + + extend Gem::Deprecate + deprecate :unicode_normalize_kc, "String#unicode_normalize(:nfkc)", 2023, 4 + end + + ## + # Unicode aware downcase method. + # + # @api private + # @param [String] input + # The input string. + # @return [String] The downcased result. + def self.unicode_downcase(input) + input = input.to_s unless input.is_a?(String) + unpacked = input.unpack("U*") + unpacked.map! { |codepoint| lookup_unicode_lowercase(codepoint) } + return unpacked.pack("U*") + end + private_class_method :unicode_downcase + + def self.lookup_unicode_lowercase(codepoint) + codepoint_data = UNICODE_DATA[codepoint] + (codepoint_data ? + (codepoint_data[UNICODE_DATA_LOWERCASE] || codepoint) : + codepoint) + end + private_class_method :lookup_unicode_lowercase + + UNICODE_DATA_COMBINING_CLASS = 0 + UNICODE_DATA_EXCLUSION = 1 + UNICODE_DATA_CANONICAL = 2 + UNICODE_DATA_COMPATIBILITY = 3 + UNICODE_DATA_UPPERCASE = 4 + UNICODE_DATA_LOWERCASE = 5 + UNICODE_DATA_TITLECASE = 6 + + begin + if defined?(FakeFS) + fakefs_state = FakeFS.activated? + FakeFS.deactivate! + end + # This is a sparse Unicode table. Codepoints without entries are + # assumed to have the value: [0, 0, nil, nil, nil, nil, nil] + UNICODE_DATA = File.open(UNICODE_TABLE, "rb") do |file| + Marshal.load(file.read) + end + ensure + if defined?(FakeFS) + FakeFS.activate! if fakefs_state + end + end + + COMPOSITION_TABLE = {} + UNICODE_DATA.each do |codepoint, data| + canonical = data[UNICODE_DATA_CANONICAL] + exclusion = data[UNICODE_DATA_EXCLUSION] + + if canonical && exclusion == 0 + COMPOSITION_TABLE[canonical.unpack("C*")] = codepoint + end + end + + UNICODE_MAX_LENGTH = 256 + ACE_MAX_LENGTH = 256 + + PUNYCODE_BASE = 36 + PUNYCODE_TMIN = 1 + PUNYCODE_TMAX = 26 + PUNYCODE_SKEW = 38 + PUNYCODE_DAMP = 700 + PUNYCODE_INITIAL_BIAS = 72 + PUNYCODE_INITIAL_N = 0x80 + PUNYCODE_DELIMITER = 0x2D + + PUNYCODE_MAXINT = 1 << 64 + + PUNYCODE_PRINT_ASCII = + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + + "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + + " !\"\#$%&'()*+,-./" + + "0123456789:;<=>?" + + "@ABCDEFGHIJKLMNO" + + "PQRSTUVWXYZ[\\]^_" + + "`abcdefghijklmno" + + "pqrstuvwxyz{|}~\n" + + # Input is invalid. + class PunycodeBadInput < StandardError; end + # Output would exceed the space provided. + class PunycodeBigOutput < StandardError; end + # Input needs wider integers to process. + class PunycodeOverflow < StandardError; end + + def self.punycode_encode(unicode) + unicode = unicode.to_s unless unicode.is_a?(String) + input = unicode.unpack("U*") + output = [0] * (ACE_MAX_LENGTH + 1) + input_length = input.size + output_length = [ACE_MAX_LENGTH] + + # Initialize the state + n = PUNYCODE_INITIAL_N + delta = out = 0 + max_out = output_length[0] + bias = PUNYCODE_INITIAL_BIAS + + # Handle the basic code points: + input_length.times do |j| + if punycode_basic?(input[j]) + if max_out - out < 2 + raise PunycodeBigOutput, + "Output would exceed the space provided." + end + output[out] = input[j] + out += 1 + end + end + + h = b = out + + # h is the number of code points that have been handled, b is the + # number of basic code points, and out is the number of characters + # that have been output. + + if b > 0 + output[out] = PUNYCODE_DELIMITER + out += 1 + end + + # Main encoding loop: + + while h < input_length + # All non-basic code points < n have been + # handled already. Find the next larger one: + + m = PUNYCODE_MAXINT + input_length.times do |j| + m = input[j] if (n...m) === input[j] + end + + # Increase delta enough to advance the decoder's + # state to , but guard against overflow: + + if m - n > (PUNYCODE_MAXINT - delta) / (h + 1) + raise PunycodeOverflow, "Input needs wider integers to process." + end + delta += (m - n) * (h + 1) + n = m + + input_length.times do |j| + # Punycode does not need to check whether input[j] is basic: + if input[j] < n + delta += 1 + if delta == 0 + raise PunycodeOverflow, + "Input needs wider integers to process." + end + end + + if input[j] == n + # Represent delta as a generalized variable-length integer: + + q = delta; k = PUNYCODE_BASE + while true + if out >= max_out + raise PunycodeBigOutput, + "Output would exceed the space provided." + end + t = ( + if k <= bias + PUNYCODE_TMIN + elsif k >= bias + PUNYCODE_TMAX + PUNYCODE_TMAX + else + k - bias + end + ) + break if q < t + output[out] = + punycode_encode_digit(t + (q - t) % (PUNYCODE_BASE - t)) + out += 1 + q = (q - t) / (PUNYCODE_BASE - t) + k += PUNYCODE_BASE + end + + output[out] = punycode_encode_digit(q) + out += 1 + bias = punycode_adapt(delta, h + 1, h == b) + delta = 0 + h += 1 + end + end + + delta += 1 + n += 1 + end + + output_length[0] = out + + outlen = out + outlen.times do |j| + c = output[j] + unless c >= 0 && c <= 127 + raise StandardError, "Invalid output char." + end + unless PUNYCODE_PRINT_ASCII[c] + raise PunycodeBadInput, "Input is invalid." + end + end + + output[0..outlen].map { |x| x.chr }.join("").sub(/\0+\z/, "") + end + private_class_method :punycode_encode + + def self.punycode_decode(punycode) + input = [] + output = [] + + if ACE_MAX_LENGTH * 2 < punycode.size + raise PunycodeBigOutput, "Output would exceed the space provided." + end + punycode.each_byte do |c| + unless c >= 0 && c <= 127 + raise PunycodeBadInput, "Input is invalid." + end + input.push(c) + end + + input_length = input.length + output_length = [UNICODE_MAX_LENGTH] + + # Initialize the state + n = PUNYCODE_INITIAL_N + + out = i = 0 + max_out = output_length[0] + bias = PUNYCODE_INITIAL_BIAS + + # Handle the basic code points: Let b be the number of input code + # points before the last delimiter, or 0 if there is none, then + # copy the first b code points to the output. + + b = 0 + input_length.times do |j| + b = j if punycode_delimiter?(input[j]) + end + if b > max_out + raise PunycodeBigOutput, "Output would exceed the space provided." + end + + b.times do |j| + unless punycode_basic?(input[j]) + raise PunycodeBadInput, "Input is invalid." + end + output[out] = input[j] + out+=1 + end + + # Main decoding loop: Start just after the last delimiter if any + # basic code points were copied; start at the beginning otherwise. + + in_ = b > 0 ? b + 1 : 0 + while in_ < input_length + + # in_ is the index of the next character to be consumed, and + # out is the number of code points in the output array. + + # Decode a generalized variable-length integer into delta, + # which gets added to i. The overflow checking is easier + # if we increase i as we go, then subtract off its starting + # value at the end to obtain delta. + + oldi = i; w = 1; k = PUNYCODE_BASE + while true + if in_ >= input_length + raise PunycodeBadInput, "Input is invalid." + end + digit = punycode_decode_digit(input[in_]) + in_+=1 + if digit >= PUNYCODE_BASE + raise PunycodeBadInput, "Input is invalid." + end + if digit > (PUNYCODE_MAXINT - i) / w + raise PunycodeOverflow, "Input needs wider integers to process." + end + i += digit * w + t = ( + if k <= bias + PUNYCODE_TMIN + elsif k >= bias + PUNYCODE_TMAX + PUNYCODE_TMAX + else + k - bias + end + ) + break if digit < t + if w > PUNYCODE_MAXINT / (PUNYCODE_BASE - t) + raise PunycodeOverflow, "Input needs wider integers to process." + end + w *= PUNYCODE_BASE - t + k += PUNYCODE_BASE + end + + bias = punycode_adapt(i - oldi, out + 1, oldi == 0) + + # I was supposed to wrap around from out + 1 to 0, + # incrementing n each time, so we'll fix that now: + + if i / (out + 1) > PUNYCODE_MAXINT - n + raise PunycodeOverflow, "Input needs wider integers to process." + end + n += i / (out + 1) + i %= out + 1 + + # Insert n at position i of the output: + + # not needed for Punycode: + # raise PUNYCODE_INVALID_INPUT if decode_digit(n) <= base + if out >= max_out + raise PunycodeBigOutput, "Output would exceed the space provided." + end + + #memmove(output + i + 1, output + i, (out - i) * sizeof *output) + output[i + 1, out - i] = output[i, out - i] + output[i] = n + i += 1 + + out += 1 + end + + output_length[0] = out + + output.pack("U*") + end + private_class_method :punycode_decode + + def self.punycode_basic?(codepoint) + codepoint < 0x80 + end + private_class_method :punycode_basic? + + def self.punycode_delimiter?(codepoint) + codepoint == PUNYCODE_DELIMITER + end + private_class_method :punycode_delimiter? + + def self.punycode_encode_digit(d) + d + 22 + 75 * ((d < 26) ? 1 : 0) + end + private_class_method :punycode_encode_digit + + # Returns the numeric value of a basic codepoint + # (for use in representing integers) in the range 0 to + # base - 1, or PUNYCODE_BASE if codepoint does not represent a value. + def self.punycode_decode_digit(codepoint) + if codepoint - 48 < 10 + codepoint - 22 + elsif codepoint - 65 < 26 + codepoint - 65 + elsif codepoint - 97 < 26 + codepoint - 97 + else + PUNYCODE_BASE + end + end + private_class_method :punycode_decode_digit + + # Bias adaptation method + def self.punycode_adapt(delta, numpoints, firsttime) + delta = firsttime ? delta / PUNYCODE_DAMP : delta >> 1 + # delta >> 1 is a faster way of doing delta / 2 + delta += delta / numpoints + difference = PUNYCODE_BASE - PUNYCODE_TMIN + + k = 0 + while delta > (difference * PUNYCODE_TMAX) / 2 + delta /= difference + k += PUNYCODE_BASE + end + + k + (difference + 1) * delta / (delta + PUNYCODE_SKEW) + end + private_class_method :punycode_adapt + end + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/lib/addressable/template.rb b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/lib/addressable/template.rb new file mode 100644 index 00000000..08556d9e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/lib/addressable/template.rb @@ -0,0 +1,1029 @@ +# frozen_string_literal: true + +#-- +# Copyright (C) Bob Aman +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#++ + + +require "addressable/version" +require "addressable/uri" + +module Addressable + ## + # This is an implementation of a URI template based on + # RFC 6570 (http://tools.ietf.org/html/rfc6570). + class Template + # Constants used throughout the template code. + anything = + Addressable::URI::CharacterClasses::RESERVED + + Addressable::URI::CharacterClasses::UNRESERVED + + + variable_char_class = + Addressable::URI::CharacterClasses::ALPHA + + Addressable::URI::CharacterClasses::DIGIT + '_' + + var_char = + "(?>(?:[#{variable_char_class}]|%[a-fA-F0-9][a-fA-F0-9])+)" + RESERVED = + "(?:[#{anything}]|%[a-fA-F0-9][a-fA-F0-9])" + UNRESERVED = + "(?:[#{ + Addressable::URI::CharacterClasses::UNRESERVED + }]|%[a-fA-F0-9][a-fA-F0-9])" + variable = + "(?:#{var_char}(?:\\.?#{var_char})*)" + varspec = + "(?:(#{variable})(\\*|:\\d+)?)" + VARNAME = + /^#{variable}$/ + VARSPEC = + /^#{varspec}$/ + VARIABLE_LIST = + /^#{varspec}(?:,#{varspec})*$/ + operator = + "+#./;?&=,!@|" + EXPRESSION = + /\{([#{operator}])?(#{varspec}(?:,#{varspec})*)\}/ + + + LEADERS = { + '?' => '?', + '/' => '/', + '#' => '#', + '.' => '.', + ';' => ';', + '&' => '&' + } + JOINERS = { + '?' => '&', + '.' => '.', + ';' => ';', + '&' => '&', + '/' => '/' + } + + ## + # Raised if an invalid template value is supplied. + class InvalidTemplateValueError < StandardError + end + + ## + # Raised if an invalid template operator is used in a pattern. + class InvalidTemplateOperatorError < StandardError + end + + ## + # Raised if an invalid template operator is used in a pattern. + class TemplateOperatorAbortedError < StandardError + end + + ## + # This class represents the data that is extracted when a Template + # is matched against a URI. + class MatchData + ## + # Creates a new MatchData object. + # MatchData objects should never be instantiated directly. + # + # @param [Addressable::URI] uri + # The URI that the template was matched against. + def initialize(uri, template, mapping) + @uri = uri.dup.freeze + @template = template + @mapping = mapping.dup.freeze + end + + ## + # @return [Addressable::URI] + # The URI that the Template was matched against. + attr_reader :uri + + ## + # @return [Addressable::Template] + # The Template used for the match. + attr_reader :template + + ## + # @return [Hash] + # The mapping that resulted from the match. + # Note that this mapping does not include keys or values for + # variables that appear in the Template, but are not present + # in the URI. + attr_reader :mapping + + ## + # @return [Array] + # The list of variables that were present in the Template. + # Note that this list will include variables which do not appear + # in the mapping because they were not present in URI. + def variables + self.template.variables + end + alias_method :keys, :variables + alias_method :names, :variables + + ## + # @return [Array] + # The list of values that were captured by the Template. + # Note that this list will include nils for any variables which + # were in the Template, but did not appear in the URI. + def values + @values ||= self.variables.inject([]) do |accu, key| + accu << self.mapping[key] + accu + end + end + alias_method :captures, :values + + ## + # Accesses captured values by name or by index. + # + # @param [String, Symbol, Fixnum] key + # Capture index or name. Note that when accessing by with index + # of 0, the full URI will be returned. The intention is to mimic + # the ::MatchData#[] behavior. + # + # @param [#to_int, nil] len + # If provided, an array of values will be returned with the given + # parameter used as length. + # + # @return [Array, String, nil] + # The captured value corresponding to the index or name. If the + # value was not provided or the key is unknown, nil will be + # returned. + # + # If the second parameter is provided, an array of that length will + # be returned instead. + def [](key, len = nil) + if len + to_a[key, len] + elsif String === key or Symbol === key + mapping[key.to_s] + else + to_a[key] + end + end + + ## + # @return [Array] + # Array with the matched URI as first element followed by the captured + # values. + def to_a + [to_s, *values] + end + + ## + # @return [String] + # The matched URI as String. + def to_s + uri.to_s + end + alias_method :string, :to_s + + # Returns multiple captured values at once. + # + # @param [String, Symbol, Fixnum] *indexes + # Indices of the captures to be returned + # + # @return [Array] + # Values corresponding to given indices. + # + # @see Addressable::Template::MatchData#[] + def values_at(*indexes) + indexes.map { |i| self[i] } + end + + ## + # Returns a String representation of the MatchData's state. + # + # @return [String] The MatchData's state, as a String. + def inspect + sprintf("#<%s:%#0x RESULT:%s>", + self.class.to_s, self.object_id, self.mapping.inspect) + end + + ## + # Dummy method for code expecting a ::MatchData instance + # + # @return [String] An empty string. + def pre_match + "" + end + alias_method :post_match, :pre_match + end + + ## + # Creates a new Addressable::Template object. + # + # @param [#to_str] pattern The URI Template pattern. + # + # @return [Addressable::Template] The initialized Template object. + def initialize(pattern) + if !pattern.respond_to?(:to_str) + raise TypeError, "Can't convert #{pattern.class} into String." + end + @pattern = pattern.to_str.dup.freeze + end + + ## + # Freeze URI, initializing instance variables. + # + # @return [Addressable::URI] The frozen URI object. + def freeze + self.variables + self.variable_defaults + self.named_captures + super + end + + ## + # @return [String] The Template object's pattern. + attr_reader :pattern + + ## + # Returns a String representation of the Template object's state. + # + # @return [String] The Template object's state, as a String. + def inspect + sprintf("#<%s:%#0x PATTERN:%s>", + self.class.to_s, self.object_id, self.pattern) + end + + ## + # Returns true if the Template objects are equal. This method + # does NOT normalize either Template before doing the comparison. + # + # @param [Object] template The Template to compare. + # + # @return [TrueClass, FalseClass] + # true if the Templates are equivalent, false + # otherwise. + def ==(template) + return false unless template.kind_of?(Template) + return self.pattern == template.pattern + end + + ## + # Addressable::Template makes no distinction between `==` and `eql?`. + # + # @see #== + alias_method :eql?, :== + + ## + # Extracts a mapping from the URI using a URI Template pattern. + # + # @param [Addressable::URI, #to_str] uri + # The URI to extract from. + # + # @param [#restore, #match] processor + # A template processor object may optionally be supplied. + # + # The object should respond to either the restore or + # match messages or both. The restore method should + # take two parameters: `[String] name` and `[String] value`. + # The restore method should reverse any transformations that + # have been performed on the value to ensure a valid URI. + # The match method should take a single + # parameter: `[String] name`. The match method should return + # a String containing a regular expression capture group for + # matching on that particular variable. The default value is `".*?"`. + # The match method has no effect on multivariate operator + # expansions. + # + # @return [Hash, NilClass] + # The Hash mapping that was extracted from the URI, or + # nil if the URI didn't match the template. + # + # @example + # class ExampleProcessor + # def self.restore(name, value) + # return value.gsub(/\+/, " ") if name == "query" + # return value + # end + # + # def self.match(name) + # return ".*?" if name == "first" + # return ".*" + # end + # end + # + # uri = Addressable::URI.parse( + # "http://example.com/search/an+example+search+query/" + # ) + # Addressable::Template.new( + # "http://example.com/search/{query}/" + # ).extract(uri, ExampleProcessor) + # #=> {"query" => "an example search query"} + # + # uri = Addressable::URI.parse("http://example.com/a/b/c/") + # Addressable::Template.new( + # "http://example.com/{first}/{second}/" + # ).extract(uri, ExampleProcessor) + # #=> {"first" => "a", "second" => "b/c"} + # + # uri = Addressable::URI.parse("http://example.com/a/b/c/") + # Addressable::Template.new( + # "http://example.com/{first}/{-list|/|second}/" + # ).extract(uri) + # #=> {"first" => "a", "second" => ["b", "c"]} + def extract(uri, processor=nil) + match_data = self.match(uri, processor) + return (match_data ? match_data.mapping : nil) + end + + ## + # Extracts match data from the URI using a URI Template pattern. + # + # @param [Addressable::URI, #to_str] uri + # The URI to extract from. + # + # @param [#restore, #match] processor + # A template processor object may optionally be supplied. + # + # The object should respond to either the restore or + # match messages or both. The restore method should + # take two parameters: `[String] name` and `[String] value`. + # The restore method should reverse any transformations that + # have been performed on the value to ensure a valid URI. + # The match method should take a single + # parameter: `[String] name`. The match method should return + # a String containing a regular expression capture group for + # matching on that particular variable. The default value is `".*?"`. + # The match method has no effect on multivariate operator + # expansions. + # + # @return [Hash, NilClass] + # The Hash mapping that was extracted from the URI, or + # nil if the URI didn't match the template. + # + # @example + # class ExampleProcessor + # def self.restore(name, value) + # return value.gsub(/\+/, " ") if name == "query" + # return value + # end + # + # def self.match(name) + # return ".*?" if name == "first" + # return ".*" + # end + # end + # + # uri = Addressable::URI.parse( + # "http://example.com/search/an+example+search+query/" + # ) + # match = Addressable::Template.new( + # "http://example.com/search/{query}/" + # ).match(uri, ExampleProcessor) + # match.variables + # #=> ["query"] + # match.captures + # #=> ["an example search query"] + # + # uri = Addressable::URI.parse("http://example.com/a/b/c/") + # match = Addressable::Template.new( + # "http://example.com/{first}/{+second}/" + # ).match(uri, ExampleProcessor) + # match.variables + # #=> ["first", "second"] + # match.captures + # #=> ["a", "b/c"] + # + # uri = Addressable::URI.parse("http://example.com/a/b/c/") + # match = Addressable::Template.new( + # "http://example.com/{first}{/second*}/" + # ).match(uri) + # match.variables + # #=> ["first", "second"] + # match.captures + # #=> ["a", ["b", "c"]] + def match(uri, processor=nil) + uri = Addressable::URI.parse(uri) unless uri.is_a?(Addressable::URI) + mapping = {} + + # First, we need to process the pattern, and extract the values. + expansions, expansion_regexp = + parse_template_pattern(pattern, processor) + + return nil unless uri.to_str.match(expansion_regexp) + unparsed_values = uri.to_str.scan(expansion_regexp).flatten + + if uri.to_str == pattern + return Addressable::Template::MatchData.new(uri, self, mapping) + elsif expansions.size > 0 + index = 0 + expansions.each do |expansion| + _, operator, varlist = *expansion.match(EXPRESSION) + varlist.split(',').each do |varspec| + _, name, modifier = *varspec.match(VARSPEC) + mapping[name] ||= nil + case operator + when nil, '+', '#', '/', '.' + unparsed_value = unparsed_values[index] + name = varspec[VARSPEC, 1] + value = unparsed_value + value = value.split(JOINERS[operator]) if value && modifier == '*' + when ';', '?', '&' + if modifier == '*' + if unparsed_values[index] + value = unparsed_values[index].split(JOINERS[operator]) + value = value.inject({}) do |acc, v| + key, val = v.split('=') + val = "" if val.nil? + acc[key] = val + acc + end + end + else + if (unparsed_values[index]) + name, value = unparsed_values[index].split('=') + value = "" if value.nil? + end + end + end + if processor != nil && processor.respond_to?(:restore) + value = processor.restore(name, value) + end + if processor == nil + if value.is_a?(Hash) + value = value.inject({}){|acc, (k, v)| + acc[Addressable::URI.unencode_component(k)] = + Addressable::URI.unencode_component(v) + acc + } + elsif value.is_a?(Array) + value = value.map{|v| Addressable::URI.unencode_component(v) } + else + value = Addressable::URI.unencode_component(value) + end + end + if !mapping.has_key?(name) || mapping[name].nil? + # Doesn't exist, set to value (even if value is nil) + mapping[name] = value + end + index = index + 1 + end + end + return Addressable::Template::MatchData.new(uri, self, mapping) + else + return nil + end + end + + ## + # Expands a URI template into another URI template. + # + # @param [Hash] mapping The mapping that corresponds to the pattern. + # @param [#validate, #transform] processor + # An optional processor object may be supplied. + # @param [Boolean] normalize_values + # Optional flag to enable/disable unicode normalization. Default: true + # + # The object should respond to either the validate or + # transform messages or both. Both the validate and + # transform methods should take two parameters: name and + # value. The validate method should return true + # or false; true if the value of the variable is valid, + # false otherwise. An InvalidTemplateValueError + # exception will be raised if the value is invalid. The transform + # method should return the transformed variable value as a String. + # If a transform method is used, the value will not be percent + # encoded automatically. Unicode normalization will be performed both + # before and after sending the value to the transform method. + # + # @return [Addressable::Template] The partially expanded URI template. + # + # @example + # Addressable::Template.new( + # "http://example.com/{one}/{two}/" + # ).partial_expand({"one" => "1"}).pattern + # #=> "http://example.com/1/{two}/" + # + # Addressable::Template.new( + # "http://example.com/{?one,two}/" + # ).partial_expand({"one" => "1"}).pattern + # #=> "http://example.com/?one=1{&two}/" + # + # Addressable::Template.new( + # "http://example.com/{?one,two,three}/" + # ).partial_expand({"one" => "1", "three" => 3}).pattern + # #=> "http://example.com/?one=1{&two}&three=3" + def partial_expand(mapping, processor=nil, normalize_values=true) + result = self.pattern.dup + mapping = normalize_keys(mapping) + result.gsub!( EXPRESSION ) do |capture| + transform_partial_capture(mapping, capture, processor, normalize_values) + end + return Addressable::Template.new(result) + end + + ## + # Expands a URI template into a full URI. + # + # @param [Hash] mapping The mapping that corresponds to the pattern. + # @param [#validate, #transform] processor + # An optional processor object may be supplied. + # @param [Boolean] normalize_values + # Optional flag to enable/disable unicode normalization. Default: true + # + # The object should respond to either the validate or + # transform messages or both. Both the validate and + # transform methods should take two parameters: name and + # value. The validate method should return true + # or false; true if the value of the variable is valid, + # false otherwise. An InvalidTemplateValueError + # exception will be raised if the value is invalid. The transform + # method should return the transformed variable value as a String. + # If a transform method is used, the value will not be percent + # encoded automatically. Unicode normalization will be performed both + # before and after sending the value to the transform method. + # + # @return [Addressable::URI] The expanded URI template. + # + # @example + # class ExampleProcessor + # def self.validate(name, value) + # return !!(value =~ /^[\w ]+$/) if name == "query" + # return true + # end + # + # def self.transform(name, value) + # return value.gsub(/ /, "+") if name == "query" + # return value + # end + # end + # + # Addressable::Template.new( + # "http://example.com/search/{query}/" + # ).expand( + # {"query" => "an example search query"}, + # ExampleProcessor + # ).to_str + # #=> "http://example.com/search/an+example+search+query/" + # + # Addressable::Template.new( + # "http://example.com/search/{query}/" + # ).expand( + # {"query" => "an example search query"} + # ).to_str + # #=> "http://example.com/search/an%20example%20search%20query/" + # + # Addressable::Template.new( + # "http://example.com/search/{query}/" + # ).expand( + # {"query" => "bogus!"}, + # ExampleProcessor + # ).to_str + # #=> Addressable::Template::InvalidTemplateValueError + def expand(mapping, processor=nil, normalize_values=true) + result = self.pattern.dup + mapping = normalize_keys(mapping) + result.gsub!( EXPRESSION ) do |capture| + transform_capture(mapping, capture, processor, normalize_values) + end + return Addressable::URI.parse(result) + end + + ## + # Returns an Array of variables used within the template pattern. + # The variables are listed in the Array in the order they appear within + # the pattern. Multiple occurrences of a variable within a pattern are + # not represented in this Array. + # + # @return [Array] The variables present in the template's pattern. + def variables + @variables ||= ordered_variable_defaults.map { |var, val| var }.uniq + end + alias_method :keys, :variables + alias_method :names, :variables + + ## + # Returns a mapping of variables to their default values specified + # in the template. Variables without defaults are not returned. + # + # @return [Hash] Mapping of template variables to their defaults + def variable_defaults + @variable_defaults ||= + Hash[*ordered_variable_defaults.reject { |k, v| v.nil? }.flatten] + end + + ## + # Coerces a template into a `Regexp` object. This regular expression will + # behave very similarly to the actual template, and should match the same + # URI values, but it cannot fully handle, for example, values that would + # extract to an `Array`. + # + # @return [Regexp] A regular expression which should match the template. + def to_regexp + _, source = parse_template_pattern(pattern) + Regexp.new(source) + end + + ## + # Returns the source of the coerced `Regexp`. + # + # @return [String] The source of the `Regexp` given by {#to_regexp}. + # + # @api private + def source + self.to_regexp.source + end + + ## + # Returns the named captures of the coerced `Regexp`. + # + # @return [Hash] The named captures of the `Regexp` given by {#to_regexp}. + # + # @api private + def named_captures + self.to_regexp.named_captures + end + + private + def ordered_variable_defaults + @ordered_variable_defaults ||= begin + expansions, _ = parse_template_pattern(pattern) + expansions.flat_map do |capture| + _, _, varlist = *capture.match(EXPRESSION) + varlist.split(',').map do |varspec| + varspec[VARSPEC, 1] + end + end + end + end + + + ## + # Loops through each capture and expands any values available in mapping + # + # @param [Hash] mapping + # Set of keys to expand + # @param [String] capture + # The expression to expand + # @param [#validate, #transform] processor + # An optional processor object may be supplied. + # @param [Boolean] normalize_values + # Optional flag to enable/disable unicode normalization. Default: true + # + # The object should respond to either the validate or + # transform messages or both. Both the validate and + # transform methods should take two parameters: name and + # value. The validate method should return true + # or false; true if the value of the variable is valid, + # false otherwise. An InvalidTemplateValueError exception + # will be raised if the value is invalid. The transform method + # should return the transformed variable value as a String. If a + # transform method is used, the value will not be percent encoded + # automatically. Unicode normalization will be performed both before and + # after sending the value to the transform method. + # + # @return [String] The expanded expression + def transform_partial_capture(mapping, capture, processor = nil, + normalize_values = true) + _, operator, varlist = *capture.match(EXPRESSION) + + vars = varlist.split(",") + + if operator == "?" + # partial expansion of form style query variables sometimes requires a + # slight reordering of the variables to produce a valid url. + first_to_expand = vars.find { |varspec| + _, name, _ = *varspec.match(VARSPEC) + mapping.key?(name) && !mapping[name].nil? + } + + vars = [first_to_expand] + vars.reject {|varspec| varspec == first_to_expand} if first_to_expand + end + + vars. + inject("".dup) do |acc, varspec| + _, name, _ = *varspec.match(VARSPEC) + next_val = if mapping.key? name + transform_capture(mapping, "{#{operator}#{varspec}}", + processor, normalize_values) + else + "{#{operator}#{varspec}}" + end + # If we've already expanded at least one '?' operator with non-empty + # value, change to '&' + operator = "&" if (operator == "?") && (next_val != "") + acc << next_val + end + end + + ## + # Transforms a mapped value so that values can be substituted into the + # template. + # + # @param [Hash] mapping The mapping to replace captures + # @param [String] capture + # The expression to replace + # @param [#validate, #transform] processor + # An optional processor object may be supplied. + # @param [Boolean] normalize_values + # Optional flag to enable/disable unicode normalization. Default: true + # + # + # The object should respond to either the validate or + # transform messages or both. Both the validate and + # transform methods should take two parameters: name and + # value. The validate method should return true + # or false; true if the value of the variable is valid, + # false otherwise. An InvalidTemplateValueError exception + # will be raised if the value is invalid. The transform method + # should return the transformed variable value as a String. If a + # transform method is used, the value will not be percent encoded + # automatically. Unicode normalization will be performed both before and + # after sending the value to the transform method. + # + # @return [String] The expanded expression + def transform_capture(mapping, capture, processor=nil, + normalize_values=true) + _, operator, varlist = *capture.match(EXPRESSION) + return_value = varlist.split(',').inject([]) do |acc, varspec| + _, name, modifier = *varspec.match(VARSPEC) + value = mapping[name] + unless value == nil || value == {} + allow_reserved = %w(+ #).include?(operator) + # Common primitives where the .to_s output is well-defined + if Numeric === value || Symbol === value || + value == true || value == false + value = value.to_s + end + length = modifier.gsub(':', '').to_i if modifier =~ /^:\d+/ + + unless (Hash === value) || + value.respond_to?(:to_ary) || value.respond_to?(:to_str) + raise TypeError, + "Can't convert #{value.class} into String or Array." + end + + value = normalize_value(value) if normalize_values + + if processor == nil || !processor.respond_to?(:transform) + # Handle percent escaping + if allow_reserved + encode_map = + Addressable::URI::CharacterClasses::RESERVED + + Addressable::URI::CharacterClasses::UNRESERVED + else + encode_map = Addressable::URI::CharacterClasses::UNRESERVED + end + if value.kind_of?(Array) + transformed_value = value.map do |val| + if length + Addressable::URI.encode_component(val[0...length], encode_map) + else + Addressable::URI.encode_component(val, encode_map) + end + end + unless modifier == "*" + transformed_value = transformed_value.join(',') + end + elsif value.kind_of?(Hash) + transformed_value = value.map do |key, val| + if modifier == "*" + "#{ + Addressable::URI.encode_component( key, encode_map) + }=#{ + Addressable::URI.encode_component( val, encode_map) + }" + else + "#{ + Addressable::URI.encode_component( key, encode_map) + },#{ + Addressable::URI.encode_component( val, encode_map) + }" + end + end + unless modifier == "*" + transformed_value = transformed_value.join(',') + end + else + if length + transformed_value = Addressable::URI.encode_component( + value[0...length], encode_map) + else + transformed_value = Addressable::URI.encode_component( + value, encode_map) + end + end + end + + # Process, if we've got a processor + if processor != nil + if processor.respond_to?(:validate) + if !processor.validate(name, value) + display_value = value.kind_of?(Array) ? value.inspect : value + raise InvalidTemplateValueError, + "#{name}=#{display_value} is an invalid template value." + end + end + if processor.respond_to?(:transform) + transformed_value = processor.transform(name, value) + if normalize_values + transformed_value = normalize_value(transformed_value) + end + end + end + acc << [name, transformed_value] + end + acc + end + return "" if return_value.empty? + join_values(operator, return_value) + end + + ## + # Takes a set of values, and joins them together based on the + # operator. + # + # @param [String, Nil] operator One of the operators from the set + # (?,&,+,#,;,/,.), or nil if there wasn't one. + # @param [Array] return_value + # The set of return values (as [variable_name, value] tuples) that will + # be joined together. + # + # @return [String] The transformed mapped value + def join_values(operator, return_value) + leader = LEADERS.fetch(operator, '') + joiner = JOINERS.fetch(operator, ',') + case operator + when '&', '?' + leader + return_value.map{|k,v| + if v.is_a?(Array) && v.first =~ /=/ + v.join(joiner) + elsif v.is_a?(Array) + v.map{|inner_value| "#{k}=#{inner_value}"}.join(joiner) + else + "#{k}=#{v}" + end + }.join(joiner) + when ';' + return_value.map{|k,v| + if v.is_a?(Array) && v.first =~ /=/ + ';' + v.join(";") + elsif v.is_a?(Array) + ';' + v.map{|inner_value| "#{k}=#{inner_value}"}.join(";") + else + v && v != '' ? ";#{k}=#{v}" : ";#{k}" + end + }.join + else + leader + return_value.map{|k,v| v}.join(joiner) + end + end + + ## + # Takes a set of values, and joins them together based on the + # operator. + # + # @param [Hash, Array, String] value + # Normalizes unicode keys and values with String#unicode_normalize (NFC) + # + # @return [Hash, Array, String] The normalized values + def normalize_value(value) + # Handle unicode normalization + if value.respond_to?(:to_ary) + value.to_ary.map! { |val| normalize_value(val) } + elsif value.kind_of?(Hash) + value = value.inject({}) { |acc, (k, v)| + acc[normalize_value(k)] = normalize_value(v) + acc + } + else + value = value.to_s if !value.kind_of?(String) + if value.encoding != Encoding::UTF_8 + value = value.dup.force_encoding(Encoding::UTF_8) + end + value = value.unicode_normalize(:nfc) + end + value + end + + ## + # Generates a hash with string keys + # + # @param [Hash] mapping A mapping hash to normalize + # + # @return [Hash] + # A hash with stringified keys + def normalize_keys(mapping) + return mapping.inject({}) do |accu, pair| + name, value = pair + if Symbol === name + name = name.to_s + elsif name.respond_to?(:to_str) + name = name.to_str + else + raise TypeError, + "Can't convert #{name.class} into String." + end + accu[name] = value + accu + end + end + + ## + # Generates the Regexp that parses a template pattern. Memoizes the + # value if template processor not set (processors may not be deterministic) + # + # @param [String] pattern The URI template pattern. + # @param [#match] processor The template processor to use. + # + # @return [Array, Regexp] + # An array of expansion variables nad a regular expression which may be + # used to parse a template pattern + def parse_template_pattern(pattern, processor = nil) + if processor.nil? && pattern == @pattern + @cached_template_parse ||= + parse_new_template_pattern(pattern, processor) + else + parse_new_template_pattern(pattern, processor) + end + end + + ## + # Generates the Regexp that parses a template pattern. + # + # @param [String] pattern The URI template pattern. + # @param [#match] processor The template processor to use. + # + # @return [Array, Regexp] + # An array of expansion variables nad a regular expression which may be + # used to parse a template pattern + def parse_new_template_pattern(pattern, processor = nil) + # Escape the pattern. The two gsubs restore the escaped curly braces + # back to their original form. Basically, escape everything that isn't + # within an expansion. + escaped_pattern = Regexp.escape( + pattern + ).gsub(/\\\{(.*?)\\\}/) do |escaped| + escaped.gsub(/\\(.)/, "\\1") + end + + expansions = [] + + # Create a regular expression that captures the values of the + # variables in the URI. + regexp_string = escaped_pattern.gsub( EXPRESSION ) do |expansion| + + expansions << expansion + _, operator, varlist = *expansion.match(EXPRESSION) + leader = Regexp.escape(LEADERS.fetch(operator, '')) + joiner = Regexp.escape(JOINERS.fetch(operator, ',')) + combined = varlist.split(',').map do |varspec| + _, name, modifier = *varspec.match(VARSPEC) + + result = processor && processor.respond_to?(:match) ? processor.match(name) : nil + if result + "(?<#{name}>#{ result })" + else + group = case operator + when '+' + "#{ RESERVED }*?" + when '#' + "#{ RESERVED }*?" + when '/' + "#{ UNRESERVED }*?" + when '.' + "#{ UNRESERVED.gsub('\.', '') }*?" + when ';' + "#{ UNRESERVED }*=?#{ UNRESERVED }*?" + when '?' + "#{ UNRESERVED }*=#{ UNRESERVED }*?" + when '&' + "#{ UNRESERVED }*=#{ UNRESERVED }*?" + else + "#{ UNRESERVED }*?" + end + if modifier == '*' + "(?<#{name}>#{group}(?:#{joiner}?#{group})*)?" + else + "(?<#{name}>#{group})?" + end + end + end.join("#{joiner}?") + "(?:|#{leader}#{combined})" + end + + # Ensure that the regular expression matches the whole URI. + regexp_string = "\\A#{regexp_string}\\z" + return expansions, Regexp.new(regexp_string) + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/lib/addressable/uri.rb b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/lib/addressable/uri.rb new file mode 100644 index 00000000..40b80cf0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/lib/addressable/uri.rb @@ -0,0 +1,2602 @@ +# frozen_string_literal: true + +#-- +# Copyright (C) Bob Aman +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#++ + + +require "addressable/version" +require "addressable/idna" +require "public_suffix" + +## +# Addressable is a library for processing links and URIs. +module Addressable + ## + # This is an implementation of a URI parser based on + # RFC 3986, + # RFC 3987. + class URI + ## + # Raised if something other than a uri is supplied. + class InvalidURIError < StandardError + end + + ## + # Container for the character classes specified in + # RFC 3986. + # + # Note: Concatenated and interpolated `String`s are not affected by the + # `frozen_string_literal` directive and must be frozen explicitly. + # + # Interpolated `String`s *were* frozen this way before Ruby 3.0: + # https://bugs.ruby-lang.org/issues/17104 + module CharacterClasses + ALPHA = "a-zA-Z" + DIGIT = "0-9" + GEN_DELIMS = "\\:\\/\\?\\#\\[\\]\\@" + SUB_DELIMS = "\\!\\$\\&\\'\\(\\)\\*\\+\\,\\;\\=" + RESERVED = (GEN_DELIMS + SUB_DELIMS).freeze + UNRESERVED = (ALPHA + DIGIT + "\\-\\.\\_\\~").freeze + RESERVED_AND_UNRESERVED = RESERVED + UNRESERVED + PCHAR = (UNRESERVED + SUB_DELIMS + "\\:\\@").freeze + SCHEME = (ALPHA + DIGIT + "\\-\\+\\.").freeze + HOST = (UNRESERVED + SUB_DELIMS + "\\[\\:\\]").freeze + AUTHORITY = (PCHAR + "\\[\\]").freeze + PATH = (PCHAR + "\\/").freeze + QUERY = (PCHAR + "\\/\\?").freeze + FRAGMENT = (PCHAR + "\\/\\?").freeze + end + + module NormalizeCharacterClasses + HOST = /[^#{CharacterClasses::HOST}]/ + UNRESERVED = /[^#{CharacterClasses::UNRESERVED}]/ + PCHAR = /[^#{CharacterClasses::PCHAR}]/ + SCHEME = /[^#{CharacterClasses::SCHEME}]/ + FRAGMENT = /[^#{CharacterClasses::FRAGMENT}]/ + QUERY = %r{[^a-zA-Z0-9\-\.\_\~\!\$\'\(\)\*\+\,\=\:\@\/\?%]|%(?!2B|2b)} + end + + module CharacterClassesRegexps + AUTHORITY = /[^#{CharacterClasses::AUTHORITY}]/ + FRAGMENT = /[^#{CharacterClasses::FRAGMENT}]/ + HOST = /[^#{CharacterClasses::HOST}]/ + PATH = /[^#{CharacterClasses::PATH}]/ + QUERY = /[^#{CharacterClasses::QUERY}]/ + RESERVED = /[^#{CharacterClasses::RESERVED}]/ + RESERVED_AND_UNRESERVED = /[^#{CharacterClasses::RESERVED_AND_UNRESERVED}]/ + SCHEME = /[^#{CharacterClasses::SCHEME}]/ + UNRESERVED = /[^#{CharacterClasses::UNRESERVED}]/ + end + + SLASH = '/' + EMPTY_STR = '' + + URIREGEX = /^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/ + + PORT_MAPPING = { + "http" => 80, + "https" => 443, + "ftp" => 21, + "tftp" => 69, + "sftp" => 22, + "ssh" => 22, + "svn+ssh" => 22, + "telnet" => 23, + "nntp" => 119, + "gopher" => 70, + "wais" => 210, + "ldap" => 389, + "prospero" => 1525 + }.freeze + + ## + # Returns a URI object based on the parsed string. + # + # @param [String, Addressable::URI, #to_str] uri + # The URI string to parse. + # No parsing is performed if the object is already an + # Addressable::URI. + # + # @return [Addressable::URI] The parsed URI. + def self.parse(uri) + # If we were given nil, return nil. + return nil unless uri + # If a URI object is passed, just return itself. + return uri.dup if uri.kind_of?(self) + + # If a URI object of the Ruby standard library variety is passed, + # convert it to a string, then parse the string. + # We do the check this way because we don't want to accidentally + # cause a missing constant exception to be thrown. + if uri.class.name =~ /^URI\b/ + uri = uri.to_s + end + + # Otherwise, convert to a String + begin + uri = uri.to_str + rescue TypeError, NoMethodError + raise TypeError, "Can't convert #{uri.class} into String." + end unless uri.is_a?(String) + + # This Regexp supplied as an example in RFC 3986, and it works great. + scan = uri.scan(URIREGEX) + fragments = scan[0] + scheme = fragments[1] + authority = fragments[3] + path = fragments[4] + query = fragments[6] + fragment = fragments[8] + user = nil + password = nil + host = nil + port = nil + if authority != nil + # The Regexp above doesn't split apart the authority. + userinfo = authority[/^([^\[\]]*)@/, 1] + if userinfo != nil + user = userinfo.strip[/^([^:]*):?/, 1] + password = userinfo.strip[/:(.*)$/, 1] + end + + host = authority.sub( + /^([^\[\]]*)@/, EMPTY_STR + ).sub( + /:([^:@\[\]]*?)$/, EMPTY_STR + ) + + port = authority[/:([^:@\[\]]*?)$/, 1] + port = nil if port == EMPTY_STR + end + + return new( + :scheme => scheme, + :user => user, + :password => password, + :host => host, + :port => port, + :path => path, + :query => query, + :fragment => fragment + ) + end + + ## + # Converts an input to a URI. The input does not have to be a valid + # URI — the method will use heuristics to guess what URI was intended. + # This is not standards-compliant, merely user-friendly. + # + # @param [String, Addressable::URI, #to_str] uri + # The URI string to parse. + # No parsing is performed if the object is already an + # Addressable::URI. + # @param [Hash] hints + # A Hash of hints to the heuristic parser. + # Defaults to {:scheme => "http"}. + # + # @return [Addressable::URI] The parsed URI. + def self.heuristic_parse(uri, hints={}) + # If we were given nil, return nil. + return nil unless uri + # If a URI object is passed, just return itself. + return uri.dup if uri.kind_of?(self) + + # If a URI object of the Ruby standard library variety is passed, + # convert it to a string, then parse the string. + # We do the check this way because we don't want to accidentally + # cause a missing constant exception to be thrown. + if uri.class.name =~ /^URI\b/ + uri = uri.to_s + end + + unless uri.respond_to?(:to_str) + raise TypeError, "Can't convert #{uri.class} into String." + end + # Otherwise, convert to a String + uri = uri.to_str.dup.strip + hints = { + :scheme => "http" + }.merge(hints) + case uri + when /^http:\//i + uri.sub!(/^http:\/+/i, "http://") + when /^https:\//i + uri.sub!(/^https:\/+/i, "https://") + when /^feed:\/+http:\//i + uri.sub!(/^feed:\/+http:\/+/i, "feed:http://") + when /^feed:\//i + uri.sub!(/^feed:\/+/i, "feed://") + when %r[^file:/{4}]i + uri.sub!(%r[^file:/+]i, "file:////") + when %r[^file://localhost/]i + uri.sub!(%r[^file://localhost/+]i, "file:///") + when %r[^file:/+]i + uri.sub!(%r[^file:/+]i, "file:///") + when /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/ + uri.sub!(/^/, hints[:scheme] + "://") + when /\A\d+\..*:\d+\z/ + uri = "#{hints[:scheme]}://#{uri}" + end + match = uri.match(URIREGEX) + fragments = match.captures + authority = fragments[3] + if authority && authority.length > 0 + new_authority = authority.tr("\\", "/").gsub(" ", "%20") + # NOTE: We want offset 4, not 3! + offset = match.offset(4) + uri = uri.dup + uri[offset[0]...offset[1]] = new_authority + end + parsed = self.parse(uri) + if parsed.scheme =~ /^[^\/?#\.]+\.[^\/?#]+$/ + parsed = self.parse(hints[:scheme] + "://" + uri) + end + if parsed.path.include?(".") + if parsed.path[/\b@\b/] + parsed.scheme = "mailto" unless parsed.scheme + elsif new_host = parsed.path[/^([^\/]+\.[^\/]*)/, 1] + parsed.defer_validation do + new_path = parsed.path.sub( + Regexp.new("^" + Regexp.escape(new_host)), EMPTY_STR) + parsed.host = new_host + parsed.path = new_path + parsed.scheme = hints[:scheme] unless parsed.scheme + end + end + end + return parsed + end + + ## + # Converts a path to a file scheme URI. If the path supplied is + # relative, it will be returned as a relative URI. If the path supplied + # is actually a non-file URI, it will parse the URI as if it had been + # parsed with Addressable::URI.parse. Handles all of the + # various Microsoft-specific formats for specifying paths. + # + # @param [String, Addressable::URI, #to_str] path + # Typically a String path to a file or directory, but + # will return a sensible return value if an absolute URI is supplied + # instead. + # + # @return [Addressable::URI] + # The parsed file scheme URI or the original URI if some other URI + # scheme was provided. + # + # @example + # base = Addressable::URI.convert_path("/absolute/path/") + # uri = Addressable::URI.convert_path("relative/path") + # (base + uri).to_s + # #=> "file:///absolute/path/relative/path" + # + # Addressable::URI.convert_path( + # "c:\\windows\\My Documents 100%20\\foo.txt" + # ).to_s + # #=> "file:///c:/windows/My%20Documents%20100%20/foo.txt" + # + # Addressable::URI.convert_path("http://example.com/").to_s + # #=> "http://example.com/" + def self.convert_path(path) + # If we were given nil, return nil. + return nil unless path + # If a URI object is passed, just return itself. + return path if path.kind_of?(self) + unless path.respond_to?(:to_str) + raise TypeError, "Can't convert #{path.class} into String." + end + # Otherwise, convert to a String + path = path.to_str.strip + + path.sub!(/^file:\/?\/?/, EMPTY_STR) if path =~ /^file:\/?\/?/ + path = SLASH + path if path =~ /^([a-zA-Z])[\|:]/ + uri = self.parse(path) + + if uri.scheme == nil + # Adjust windows-style uris + uri.path.sub!(/^\/?([a-zA-Z])[\|:][\\\/]/) do + "/#{$1.downcase}:/" + end + uri.path.tr!("\\", SLASH) + if File.exist?(uri.path) && + File.stat(uri.path).directory? + uri.path.chomp!(SLASH) + uri.path = uri.path + '/' + end + + # If the path is absolute, set the scheme and host. + if uri.path.start_with?(SLASH) + uri.scheme = "file" + uri.host = EMPTY_STR + end + uri.normalize! + end + + return uri + end + + ## + # Joins several URIs together. + # + # @param [String, Addressable::URI, #to_str] *uris + # The URIs to join. + # + # @return [Addressable::URI] The joined URI. + # + # @example + # base = "http://example.com/" + # uri = Addressable::URI.parse("relative/path") + # Addressable::URI.join(base, uri) + # #=> # + def self.join(*uris) + uri_objects = uris.collect do |uri| + unless uri.respond_to?(:to_str) + raise TypeError, "Can't convert #{uri.class} into String." + end + uri.kind_of?(self) ? uri : self.parse(uri.to_str) + end + result = uri_objects.shift.dup + uri_objects.each do |uri| + result.join!(uri) + end + return result + end + + ## + # Tables used to optimize encoding operations in `self.encode_component` + # and `self.normalize_component` + SEQUENCE_ENCODING_TABLE = (0..255).map do |byte| + format("%02x", byte).freeze + end.freeze + + SEQUENCE_UPCASED_PERCENT_ENCODING_TABLE = (0..255).map do |byte| + format("%%%02X", byte).freeze + end.freeze + + ## + # Percent encodes a URI component. + # + # @param [String, #to_str] component The URI component to encode. + # + # @param [String, Regexp] character_class + # The characters which are not percent encoded. If a String + # is passed, the String must be formatted as a regular + # expression character class. (Do not include the surrounding square + # brackets.) For example, "b-zB-Z0-9" would cause + # everything but the letters 'b' through 'z' and the numbers '0' through + # '9' to be percent encoded. If a Regexp is passed, the + # value /[^b-zB-Z0-9]/ would have the same effect. A set of + # useful String values may be found in the + # Addressable::URI::CharacterClasses module. The default + # value is the reserved plus unreserved character classes specified in + # RFC 3986. + # + # @param [Regexp] upcase_encoded + # A string of characters that may already be percent encoded, and whose + # encodings should be upcased. This allows normalization of percent + # encodings for characters not included in the + # character_class. + # + # @return [String] The encoded component. + # + # @example + # Addressable::URI.encode_component("simple/example", "b-zB-Z0-9") + # => "simple%2Fex%61mple" + # Addressable::URI.encode_component("simple/example", /[^b-zB-Z0-9]/) + # => "simple%2Fex%61mple" + # Addressable::URI.encode_component( + # "simple/example", Addressable::URI::CharacterClasses::UNRESERVED + # ) + # => "simple%2Fexample" + def self.encode_component(component, character_class=CharacterClassesRegexps::RESERVED_AND_UNRESERVED, upcase_encoded='') + return nil if component.nil? + + begin + if component.kind_of?(Symbol) || + component.kind_of?(Numeric) || + component.kind_of?(TrueClass) || + component.kind_of?(FalseClass) + component = component.to_s + else + component = component.to_str + end + rescue TypeError, NoMethodError + raise TypeError, "Can't convert #{component.class} into String." + end if !component.is_a? String + + if ![String, Regexp].include?(character_class.class) + raise TypeError, + "Expected String or Regexp, got #{character_class.inspect}" + end + if character_class.kind_of?(String) + character_class = /[^#{character_class}]/ + end + # We can't perform regexps on invalid UTF sequences, but + # here we need to, so switch to ASCII. + component = component.dup + component.force_encoding(Encoding::ASCII_8BIT) + # Avoiding gsub! because there are edge cases with frozen strings + component = component.gsub(character_class) do |char| + SEQUENCE_UPCASED_PERCENT_ENCODING_TABLE[char.ord] + end + if upcase_encoded.length > 0 + upcase_encoded_chars = upcase_encoded.bytes.map do |byte| + SEQUENCE_ENCODING_TABLE[byte] + end + component = component.gsub(/%(#{upcase_encoded_chars.join('|')})/, + &:upcase) + end + + return component + end + + class << self + alias_method :escape_component, :encode_component + end + + ## + # Unencodes any percent encoded characters within a URI component. + # This method may be used for unencoding either components or full URIs, + # however, it is recommended to use the unencode_component + # alias when unencoding components. + # + # @param [String, Addressable::URI, #to_str] uri + # The URI or component to unencode. + # + # @param [Class] return_type + # The type of object to return. + # This value may only be set to String or + # Addressable::URI. All other values are invalid. Defaults + # to String. + # + # @param [String] leave_encoded + # A string of characters to leave encoded. If a percent encoded character + # in this list is encountered then it will remain percent encoded. + # + # @return [String, Addressable::URI] + # The unencoded component or URI. + # The return type is determined by the return_type + # parameter. + def self.unencode(uri, return_type=String, leave_encoded='') + return nil if uri.nil? + + begin + uri = uri.to_str + rescue NoMethodError, TypeError + raise TypeError, "Can't convert #{uri.class} into String." + end if !uri.is_a? String + if ![String, ::Addressable::URI].include?(return_type) + raise TypeError, + "Expected Class (String or Addressable::URI), " + + "got #{return_type.inspect}" + end + + result = uri.gsub(/%[0-9a-f]{2}/i) do |sequence| + c = sequence[1..3].to_i(16).chr + c.force_encoding(sequence.encoding) + leave_encoded.include?(c) ? sequence : c + end + + result.force_encoding(Encoding::UTF_8) + if return_type == String + return result + elsif return_type == ::Addressable::URI + return ::Addressable::URI.parse(result) + end + end + + class << self + alias_method :unescape, :unencode + alias_method :unencode_component, :unencode + alias_method :unescape_component, :unencode + end + + + ## + # Normalizes the encoding of a URI component. + # + # @param [String, #to_str] component The URI component to encode. + # + # @param [String, Regexp] character_class + # The characters which are not percent encoded. If a String + # is passed, the String must be formatted as a regular + # expression character class. (Do not include the surrounding square + # brackets.) For example, "b-zB-Z0-9" would cause + # everything but the letters 'b' through 'z' and the numbers '0' + # through '9' to be percent encoded. If a Regexp is passed, + # the value /[^b-zB-Z0-9]/ would have the same effect. A + # set of useful String values may be found in the + # Addressable::URI::CharacterClasses module. The default + # value is the reserved plus unreserved character classes specified in + # RFC 3986. + # + # @param [String] leave_encoded + # When character_class is a String then + # leave_encoded is a string of characters that should remain + # percent encoded while normalizing the component; if they appear percent + # encoded in the original component, then they will be upcased ("%2f" + # normalized to "%2F") but otherwise left alone. + # + # @return [String] The normalized component. + # + # @example + # Addressable::URI.normalize_component("simpl%65/%65xampl%65", "b-zB-Z") + # => "simple%2Fex%61mple" + # Addressable::URI.normalize_component( + # "simpl%65/%65xampl%65", /[^b-zB-Z]/ + # ) + # => "simple%2Fex%61mple" + # Addressable::URI.normalize_component( + # "simpl%65/%65xampl%65", + # Addressable::URI::CharacterClasses::UNRESERVED + # ) + # => "simple%2Fexample" + # Addressable::URI.normalize_component( + # "one%20two%2fthree%26four", + # "0-9a-zA-Z &/", + # "/" + # ) + # => "one two%2Fthree&four" + def self.normalize_component(component, character_class= + CharacterClassesRegexps::RESERVED_AND_UNRESERVED, + leave_encoded='') + return nil if component.nil? + + begin + component = component.to_str + rescue NoMethodError, TypeError + raise TypeError, "Can't convert #{component.class} into String." + end if !component.is_a? String + + if ![String, Regexp].include?(character_class.class) + raise TypeError, + "Expected String or Regexp, got #{character_class.inspect}" + end + if character_class.kind_of?(String) + leave_re = if leave_encoded.length > 0 + character_class = "#{character_class}%" unless character_class.include?('%') + + bytes = leave_encoded.bytes + leave_encoded_pattern = bytes.map { |b| SEQUENCE_ENCODING_TABLE[b] }.join('|') + "|%(?!#{leave_encoded_pattern}|#{leave_encoded_pattern.upcase})" + end + + character_class = if leave_re + /[^#{character_class}]#{leave_re}/ + else + /[^#{character_class}]/ + end + end + # We can't perform regexps on invalid UTF sequences, but + # here we need to, so switch to ASCII. + component = component.dup + component.force_encoding(Encoding::ASCII_8BIT) + unencoded = self.unencode_component(component, String, leave_encoded) + begin + encoded = self.encode_component( + unencoded.unicode_normalize(:nfc), + character_class, + leave_encoded + ) + rescue ArgumentError + encoded = self.encode_component(unencoded) + end + encoded.force_encoding(Encoding::UTF_8) + return encoded + end + + ## + # Percent encodes any special characters in the URI. + # + # @param [String, Addressable::URI, #to_str] uri + # The URI to encode. + # + # @param [Class] return_type + # The type of object to return. + # This value may only be set to String or + # Addressable::URI. All other values are invalid. Defaults + # to String. + # + # @return [String, Addressable::URI] + # The encoded URI. + # The return type is determined by the return_type + # parameter. + def self.encode(uri, return_type=String) + return nil if uri.nil? + + begin + uri = uri.to_str + rescue NoMethodError, TypeError + raise TypeError, "Can't convert #{uri.class} into String." + end if !uri.is_a? String + + if ![String, ::Addressable::URI].include?(return_type) + raise TypeError, + "Expected Class (String or Addressable::URI), " + + "got #{return_type.inspect}" + end + uri_object = uri.kind_of?(self) ? uri : self.parse(uri) + encoded_uri = Addressable::URI.new( + :scheme => self.encode_component(uri_object.scheme, + Addressable::URI::CharacterClassesRegexps::SCHEME), + :authority => self.encode_component(uri_object.authority, + Addressable::URI::CharacterClassesRegexps::AUTHORITY), + :path => self.encode_component(uri_object.path, + Addressable::URI::CharacterClassesRegexps::PATH), + :query => self.encode_component(uri_object.query, + Addressable::URI::CharacterClassesRegexps::QUERY), + :fragment => self.encode_component(uri_object.fragment, + Addressable::URI::CharacterClassesRegexps::FRAGMENT) + ) + if return_type == String + return encoded_uri.to_s + elsif return_type == ::Addressable::URI + return encoded_uri + end + end + + class << self + alias_method :escape, :encode + end + + ## + # Normalizes the encoding of a URI. Characters within a hostname are + # not percent encoded to allow for internationalized domain names. + # + # @param [String, Addressable::URI, #to_str] uri + # The URI to encode. + # + # @param [Class] return_type + # The type of object to return. + # This value may only be set to String or + # Addressable::URI. All other values are invalid. Defaults + # to String. + # + # @return [String, Addressable::URI] + # The encoded URI. + # The return type is determined by the return_type + # parameter. + def self.normalized_encode(uri, return_type=String) + begin + uri = uri.to_str + rescue NoMethodError, TypeError + raise TypeError, "Can't convert #{uri.class} into String." + end if !uri.is_a? String + + if ![String, ::Addressable::URI].include?(return_type) + raise TypeError, + "Expected Class (String or Addressable::URI), " + + "got #{return_type.inspect}" + end + uri_object = uri.kind_of?(self) ? uri : self.parse(uri) + components = { + :scheme => self.unencode_component(uri_object.scheme), + :user => self.unencode_component(uri_object.user), + :password => self.unencode_component(uri_object.password), + :host => self.unencode_component(uri_object.host), + :port => (uri_object.port.nil? ? nil : uri_object.port.to_s), + :path => self.unencode_component(uri_object.path), + :query => self.unencode_component(uri_object.query), + :fragment => self.unencode_component(uri_object.fragment) + } + components.each do |key, value| + if value != nil + begin + components[key] = value.to_str.unicode_normalize(:nfc) + rescue ArgumentError + # Likely a malformed UTF-8 character, skip unicode normalization + components[key] = value.to_str + end + end + end + encoded_uri = Addressable::URI.new( + :scheme => self.encode_component(components[:scheme], + Addressable::URI::CharacterClassesRegexps::SCHEME), + :user => self.encode_component(components[:user], + Addressable::URI::CharacterClassesRegexps::UNRESERVED), + :password => self.encode_component(components[:password], + Addressable::URI::CharacterClassesRegexps::UNRESERVED), + :host => components[:host], + :port => components[:port], + :path => self.encode_component(components[:path], + Addressable::URI::CharacterClassesRegexps::PATH), + :query => self.encode_component(components[:query], + Addressable::URI::CharacterClassesRegexps::QUERY), + :fragment => self.encode_component(components[:fragment], + Addressable::URI::CharacterClassesRegexps::FRAGMENT) + ) + if return_type == String + return encoded_uri.to_s + elsif return_type == ::Addressable::URI + return encoded_uri + end + end + + ## + # Encodes a set of key/value pairs according to the rules for the + # application/x-www-form-urlencoded MIME type. + # + # @param [#to_hash, #to_ary] form_values + # The form values to encode. + # + # @param [TrueClass, FalseClass] sort + # Sort the key/value pairs prior to encoding. + # Defaults to false. + # + # @return [String] + # The encoded value. + def self.form_encode(form_values, sort=false) + if form_values.respond_to?(:to_hash) + form_values = form_values.to_hash.to_a + elsif form_values.respond_to?(:to_ary) + form_values = form_values.to_ary + else + raise TypeError, "Can't convert #{form_values.class} into Array." + end + + form_values = form_values.inject([]) do |accu, (key, value)| + if value.kind_of?(Array) + value.each do |v| + accu << [key.to_s, v.to_s] + end + else + accu << [key.to_s, value.to_s] + end + accu + end + + if sort + # Useful for OAuth and optimizing caching systems + form_values = form_values.sort + end + escaped_form_values = form_values.map do |(key, value)| + # Line breaks are CRLF pairs + [ + self.encode_component( + key.gsub(/(\r\n|\n|\r)/, "\r\n"), + CharacterClassesRegexps::UNRESERVED + ).gsub("%20", "+"), + self.encode_component( + value.gsub(/(\r\n|\n|\r)/, "\r\n"), + CharacterClassesRegexps::UNRESERVED + ).gsub("%20", "+") + ] + end + return escaped_form_values.map do |(key, value)| + "#{key}=#{value}" + end.join("&") + end + + ## + # Decodes a String according to the rules for the + # application/x-www-form-urlencoded MIME type. + # + # @param [String, #to_str] encoded_value + # The form values to decode. + # + # @return [Array] + # The decoded values. + # This is not a Hash because of the possibility for + # duplicate keys. + def self.form_unencode(encoded_value) + if !encoded_value.respond_to?(:to_str) + raise TypeError, "Can't convert #{encoded_value.class} into String." + end + encoded_value = encoded_value.to_str + split_values = encoded_value.split("&").map do |pair| + pair.split("=", 2) + end + return split_values.map do |(key, value)| + [ + key ? self.unencode_component( + key.gsub("+", "%20")).gsub(/(\r\n|\n|\r)/, "\n") : nil, + value ? (self.unencode_component( + value.gsub("+", "%20")).gsub(/(\r\n|\n|\r)/, "\n")) : nil + ] + end + end + + ## + # Creates a new uri object from component parts. + # + # @option [String, #to_str] scheme The scheme component. + # @option [String, #to_str] user The user component. + # @option [String, #to_str] password The password component. + # @option [String, #to_str] userinfo + # The userinfo component. If this is supplied, the user and password + # components must be omitted. + # @option [String, #to_str] host The host component. + # @option [String, #to_str] port The port component. + # @option [String, #to_str] authority + # The authority component. If this is supplied, the user, password, + # userinfo, host, and port components must be omitted. + # @option [String, #to_str] path The path component. + # @option [String, #to_str] query The query component. + # @option [String, #to_str] fragment The fragment component. + # + # @return [Addressable::URI] The constructed URI object. + def initialize(options={}) + if options.has_key?(:authority) + if (options.keys & [:userinfo, :user, :password, :host, :port]).any? + raise ArgumentError, + "Cannot specify both an authority and any of the components " + + "within the authority." + end + end + if options.has_key?(:userinfo) + if (options.keys & [:user, :password]).any? + raise ArgumentError, + "Cannot specify both a userinfo and either the user or password." + end + end + + reset_ivs + + defer_validation do + # Bunch of crazy logic required because of the composite components + # like userinfo and authority. + self.scheme = options[:scheme] if options[:scheme] + self.user = options[:user] if options[:user] + self.password = options[:password] if options[:password] + self.userinfo = options[:userinfo] if options[:userinfo] + self.host = options[:host] if options[:host] + self.port = options[:port] if options[:port] + self.authority = options[:authority] if options[:authority] + self.path = options[:path] if options[:path] + self.query = options[:query] if options[:query] + self.query_values = options[:query_values] if options[:query_values] + self.fragment = options[:fragment] if options[:fragment] + end + + to_s # force path validation + end + + ## + # Freeze URI, initializing instance variables. + # + # @return [Addressable::URI] The frozen URI object. + def freeze + self.normalized_scheme + self.normalized_user + self.normalized_password + self.normalized_userinfo + self.normalized_host + self.normalized_port + self.normalized_authority + self.normalized_site + self.normalized_path + self.normalized_query + self.normalized_fragment + self.hash + super + end + + ## + # The scheme component for this URI. + # + # @return [String] The scheme component. + attr_reader :scheme + + ## + # The scheme component for this URI, normalized. + # + # @return [String] The scheme component, normalized. + def normalized_scheme + return nil unless self.scheme + if @normalized_scheme == NONE + @normalized_scheme = if self.scheme =~ /^\s*ssh\+svn\s*$/i + "svn+ssh".dup + else + Addressable::URI.normalize_component( + self.scheme.strip.downcase, + Addressable::URI::NormalizeCharacterClasses::SCHEME + ) + end + end + # All normalized values should be UTF-8 + force_utf8_encoding_if_needed(@normalized_scheme) + @normalized_scheme + end + + ## + # Sets the scheme component for this URI. + # + # @param [String, #to_str] new_scheme The new scheme component. + def scheme=(new_scheme) + if new_scheme && !new_scheme.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_scheme.class} into String." + elsif new_scheme + new_scheme = new_scheme.to_str + end + if new_scheme && new_scheme !~ /\A[a-z][a-z0-9\.\+\-]*\z/i + raise InvalidURIError, "Invalid scheme format: '#{new_scheme}'" + end + @scheme = new_scheme + @scheme = nil if @scheme.to_s.strip.empty? + + # Reset dependent values + @normalized_scheme = NONE + remove_composite_values + + # Ensure we haven't created an invalid URI + validate() + end + + ## + # The user component for this URI. + # + # @return [String] The user component. + attr_reader :user + + ## + # The user component for this URI, normalized. + # + # @return [String] The user component, normalized. + def normalized_user + return nil unless self.user + return @normalized_user unless @normalized_user == NONE + @normalized_user = begin + if normalized_scheme =~ /https?/ && self.user.strip.empty? && + (!self.password || self.password.strip.empty?) + nil + else + Addressable::URI.normalize_component( + self.user.strip, + Addressable::URI::NormalizeCharacterClasses::UNRESERVED + ) + end + end + # All normalized values should be UTF-8 + force_utf8_encoding_if_needed(@normalized_user) + @normalized_user + end + + ## + # Sets the user component for this URI. + # + # @param [String, #to_str] new_user The new user component. + def user=(new_user) + if new_user && !new_user.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_user.class} into String." + end + @user = new_user ? new_user.to_str : nil + + # You can't have a nil user with a non-nil password + if password != nil + @user = EMPTY_STR unless user + end + + # Reset dependent values + @userinfo = nil + @normalized_userinfo = NONE + @authority = nil + @normalized_user = NONE + remove_composite_values + + # Ensure we haven't created an invalid URI + validate() + end + + ## + # The password component for this URI. + # + # @return [String] The password component. + attr_reader :password + + ## + # The password component for this URI, normalized. + # + # @return [String] The password component, normalized. + def normalized_password + return nil unless self.password + return @normalized_password unless @normalized_password == NONE + @normalized_password = begin + if self.normalized_scheme =~ /https?/ && self.password.strip.empty? && + (!self.user || self.user.strip.empty?) + nil + else + Addressable::URI.normalize_component( + self.password.strip, + Addressable::URI::NormalizeCharacterClasses::UNRESERVED + ) + end + end + # All normalized values should be UTF-8 + force_utf8_encoding_if_needed(@normalized_password) + @normalized_password + end + + ## + # Sets the password component for this URI. + # + # @param [String, #to_str] new_password The new password component. + def password=(new_password) + if new_password && !new_password.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_password.class} into String." + end + @password = new_password ? new_password.to_str : nil + + # You can't have a nil user with a non-nil password + if @password != nil + self.user = EMPTY_STR if user.nil? + end + + # Reset dependent values + @userinfo = nil + @normalized_userinfo = NONE + @authority = nil + @normalized_password = NONE + remove_composite_values + + # Ensure we haven't created an invalid URI + validate() + end + + ## + # The userinfo component for this URI. + # Combines the user and password components. + # + # @return [String] The userinfo component. + def userinfo + current_user = self.user + current_password = self.password + (current_user || current_password) && @userinfo ||= begin + if current_user && current_password + "#{current_user}:#{current_password}" + elsif current_user && !current_password + "#{current_user}" + end + end + end + + ## + # The userinfo component for this URI, normalized. + # + # @return [String] The userinfo component, normalized. + def normalized_userinfo + return nil unless self.userinfo + return @normalized_userinfo unless @normalized_userinfo == NONE + @normalized_userinfo = begin + current_user = self.normalized_user + current_password = self.normalized_password + if !current_user && !current_password + nil + elsif current_user && current_password + "#{current_user}:#{current_password}".dup + elsif current_user && !current_password + "#{current_user}".dup + end + end + # All normalized values should be UTF-8 + force_utf8_encoding_if_needed(@normalized_userinfo) + @normalized_userinfo + end + + ## + # Sets the userinfo component for this URI. + # + # @param [String, #to_str] new_userinfo The new userinfo component. + def userinfo=(new_userinfo) + if new_userinfo && !new_userinfo.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_userinfo.class} into String." + end + new_user, new_password = if new_userinfo + [ + new_userinfo.to_str.strip[/^(.*):/, 1], + new_userinfo.to_str.strip[/:(.*)$/, 1] + ] + else + [nil, nil] + end + + # Password assigned first to ensure validity in case of nil + self.password = new_password + self.user = new_user + + # Reset dependent values + @authority = nil + remove_composite_values + + # Ensure we haven't created an invalid URI + validate() + end + + ## + # The host component for this URI. + # + # @return [String] The host component. + attr_reader :host + + ## + # The host component for this URI, normalized. + # + # @return [String] The host component, normalized. + def normalized_host + return nil unless self.host + + @normalized_host ||= begin + if !self.host.strip.empty? + result = ::Addressable::IDNA.to_ascii( + URI.unencode_component(self.host.strip.downcase) + ) + if result =~ /[^\.]\.$/ + # Single trailing dots are unnecessary. + result = result[0...-1] + end + result = Addressable::URI.normalize_component( + result, + NormalizeCharacterClasses::HOST + ) + result + else + EMPTY_STR.dup + end + end + # All normalized values should be UTF-8 + force_utf8_encoding_if_needed(@normalized_host) + @normalized_host + end + + ## + # Sets the host component for this URI. + # + # @param [String, #to_str] new_host The new host component. + def host=(new_host) + if new_host && !new_host.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_host.class} into String." + end + @host = new_host ? new_host.to_str : nil + + # Reset dependent values + @authority = nil + @normalized_host = nil + remove_composite_values + + # Ensure we haven't created an invalid URI + validate() + end + + ## + # This method is same as URI::Generic#host except + # brackets for IPv6 (and 'IPvFuture') addresses are removed. + # + # @see Addressable::URI#host + # + # @return [String] The hostname for this URI. + def hostname + v = self.host + /\A\[(.*)\]\z/ =~ v ? $1 : v + end + + ## + # This method is same as URI::Generic#host= except + # the argument can be a bare IPv6 address (or 'IPvFuture'). + # + # @see Addressable::URI#host= + # + # @param [String, #to_str] new_hostname The new hostname for this URI. + def hostname=(new_hostname) + if new_hostname && + (new_hostname.respond_to?(:ipv4?) || new_hostname.respond_to?(:ipv6?)) + new_hostname = new_hostname.to_s + elsif new_hostname && !new_hostname.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_hostname.class} into String." + end + v = new_hostname ? new_hostname.to_str : nil + v = "[#{v}]" if /\A\[.*\]\z/ !~ v && /:/ =~ v + self.host = v + end + + ## + # Returns the top-level domain for this host. + # + # @example + # Addressable::URI.parse("http://www.example.co.uk").tld # => "co.uk" + def tld + PublicSuffix.parse(self.host, ignore_private: true).tld + end + + ## + # Sets the top-level domain for this URI. + # + # @param [String, #to_str] new_tld The new top-level domain. + def tld=(new_tld) + replaced_tld = host.sub(/#{tld}\z/, new_tld) + self.host = PublicSuffix::Domain.new(replaced_tld).to_s + end + + ## + # Returns the public suffix domain for this host. + # + # @example + # Addressable::URI.parse("http://www.example.co.uk").domain # => "example.co.uk" + def domain + PublicSuffix.domain(self.host, ignore_private: true) + end + + ## + # The authority component for this URI. + # Combines the user, password, host, and port components. + # + # @return [String] The authority component. + def authority + self.host && @authority ||= begin + authority = String.new + if self.userinfo != nil + authority << "#{self.userinfo}@" + end + authority << self.host + if self.port != nil + authority << ":#{self.port}" + end + authority + end + end + + ## + # The authority component for this URI, normalized. + # + # @return [String] The authority component, normalized. + def normalized_authority + return nil unless self.authority + @normalized_authority ||= begin + authority = String.new + if self.normalized_userinfo != nil + authority << "#{self.normalized_userinfo}@" + end + authority << self.normalized_host + if self.normalized_port != nil + authority << ":#{self.normalized_port}" + end + authority + end + # All normalized values should be UTF-8 + force_utf8_encoding_if_needed(@normalized_authority) + @normalized_authority + end + + ## + # Sets the authority component for this URI. + # + # @param [String, #to_str] new_authority The new authority component. + def authority=(new_authority) + if new_authority + if !new_authority.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_authority.class} into String." + end + new_authority = new_authority.to_str + new_userinfo = new_authority[/^([^\[\]]*)@/, 1] + if new_userinfo + new_user = new_userinfo.strip[/^([^:]*):?/, 1] + new_password = new_userinfo.strip[/:(.*)$/, 1] + end + new_host = new_authority.sub( + /^([^\[\]]*)@/, EMPTY_STR + ).sub( + /:([^:@\[\]]*?)$/, EMPTY_STR + ) + new_port = + new_authority[/:([^:@\[\]]*?)$/, 1] + end + + # Password assigned first to ensure validity in case of nil + self.password = new_password + self.user = new_user + self.host = new_host + self.port = new_port + + # Reset dependent values + @userinfo = nil + @normalized_userinfo = NONE + remove_composite_values + + # Ensure we haven't created an invalid URI + validate() + end + + ## + # The origin for this URI, serialized to ASCII, as per + # RFC 6454, section 6.2. + # + # @return [String] The serialized origin. + def origin + if self.scheme && self.authority + if self.normalized_port + "#{self.normalized_scheme}://#{self.normalized_host}" + + ":#{self.normalized_port}" + else + "#{self.normalized_scheme}://#{self.normalized_host}" + end + else + "null" + end + end + + ## + # Sets the origin for this URI, serialized to ASCII, as per + # RFC 6454, section 6.2. This assignment will reset the `userinfo` + # component. + # + # @param [String, #to_str] new_origin The new origin component. + def origin=(new_origin) + if new_origin + if !new_origin.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_origin.class} into String." + end + new_origin = new_origin.to_str + new_scheme = new_origin[/^([^:\/?#]+):\/\//, 1] + unless new_scheme + raise InvalidURIError, 'An origin cannot omit the scheme.' + end + new_host = new_origin[/:\/\/([^\/?#:]+)/, 1] + unless new_host + raise InvalidURIError, 'An origin cannot omit the host.' + end + new_port = new_origin[/:([^:@\[\]\/]*?)$/, 1] + end + + self.scheme = new_scheme + self.host = new_host + self.port = new_port + self.userinfo = nil + + # Reset dependent values + @userinfo = nil + @normalized_userinfo = NONE + @authority = nil + @normalized_authority = nil + remove_composite_values + + # Ensure we haven't created an invalid URI + validate() + end + + # Returns an array of known ip-based schemes. These schemes typically + # use a similar URI form: + # //:@:/ + def self.ip_based_schemes + return self.port_mapping.keys + end + + # Returns a hash of common IP-based schemes and their default port + # numbers. Adding new schemes to this hash, as necessary, will allow + # for better URI normalization. + def self.port_mapping + PORT_MAPPING + end + + ## + # The port component for this URI. + # This is the port number actually given in the URI. This does not + # infer port numbers from default values. + # + # @return [Integer] The port component. + attr_reader :port + + ## + # The port component for this URI, normalized. + # + # @return [Integer] The port component, normalized. + def normalized_port + return nil unless self.port + return @normalized_port unless @normalized_port == NONE + @normalized_port = begin + if URI.port_mapping[self.normalized_scheme] == self.port + nil + else + self.port + end + end + end + + ## + # Sets the port component for this URI. + # + # @param [String, Integer, #to_s] new_port The new port component. + def port=(new_port) + if new_port != nil && new_port.respond_to?(:to_str) + new_port = Addressable::URI.unencode_component(new_port.to_str) + end + + if new_port.respond_to?(:valid_encoding?) && !new_port.valid_encoding? + raise InvalidURIError, "Invalid encoding in port" + end + + if new_port != nil && !(new_port.to_s =~ /^\d+$/) + raise InvalidURIError, + "Invalid port number: #{new_port.inspect}" + end + + @port = new_port.to_s.to_i + @port = nil if @port == 0 + + # Reset dependent values + @authority = nil + @normalized_port = NONE + remove_composite_values + + # Ensure we haven't created an invalid URI + validate() + end + + ## + # The inferred port component for this URI. + # This method will normalize to the default port for the URI's scheme if + # the port isn't explicitly specified in the URI. + # + # @return [Integer] The inferred port component. + def inferred_port + if self.port.to_i == 0 + self.default_port + else + self.port.to_i + end + end + + ## + # The default port for this URI's scheme. + # This method will always returns the default port for the URI's scheme + # regardless of the presence of an explicit port in the URI. + # + # @return [Integer] The default port. + def default_port + URI.port_mapping[self.scheme.strip.downcase] if self.scheme + end + + ## + # The combination of components that represent a site. + # Combines the scheme, user, password, host, and port components. + # Primarily useful for HTTP and HTTPS. + # + # For example, "http://example.com/path?query" would have a + # site value of "http://example.com". + # + # @return [String] The components that identify a site. + def site + (self.scheme || self.authority) && @site ||= begin + site_string = "".dup + site_string << "#{self.scheme}:" if self.scheme != nil + site_string << "//#{self.authority}" if self.authority != nil + site_string + end + end + + ## + # The normalized combination of components that represent a site. + # Combines the scheme, user, password, host, and port components. + # Primarily useful for HTTP and HTTPS. + # + # For example, "http://example.com/path?query" would have a + # site value of "http://example.com". + # + # @return [String] The normalized components that identify a site. + def normalized_site + return nil unless self.site + @normalized_site ||= begin + site_string = "".dup + if self.normalized_scheme != nil + site_string << "#{self.normalized_scheme}:" + end + if self.normalized_authority != nil + site_string << "//#{self.normalized_authority}" + end + site_string + end + # All normalized values should be UTF-8 + force_utf8_encoding_if_needed(@normalized_site) + @normalized_site + end + + ## + # Sets the site value for this URI. + # + # @param [String, #to_str] new_site The new site value. + def site=(new_site) + if new_site + if !new_site.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_site.class} into String." + end + new_site = new_site.to_str + # These two regular expressions derived from the primary parsing + # expression + self.scheme = new_site[/^(?:([^:\/?#]+):)?(?:\/\/(?:[^\/?#]*))?$/, 1] + self.authority = new_site[ + /^(?:(?:[^:\/?#]+):)?(?:\/\/([^\/?#]*))?$/, 1 + ] + else + self.scheme = nil + self.authority = nil + end + end + + ## + # The path component for this URI. + # + # @return [String] The path component. + attr_reader :path + + NORMPATH = /^(?!\/)[^\/:]*:.*$/ + ## + # The path component for this URI, normalized. + # + # @return [String] The path component, normalized. + def normalized_path + @normalized_path ||= begin + path = self.path.to_s + if self.scheme == nil && path =~ NORMPATH + # Relative paths with colons in the first segment are ambiguous. + path = path.sub(":", "%2F") + end + # String#split(delimiter, -1) uses the more strict splitting behavior + # found by default in Python. + result = path.strip.split(SLASH, -1).map do |segment| + Addressable::URI.normalize_component( + segment, + Addressable::URI::NormalizeCharacterClasses::PCHAR + ) + end.join(SLASH) + + result = URI.normalize_path(result) + if result.empty? && + ["http", "https", "ftp", "tftp"].include?(self.normalized_scheme) + result = SLASH.dup + end + result + end + # All normalized values should be UTF-8 + force_utf8_encoding_if_needed(@normalized_path) + @normalized_path + end + + ## + # Sets the path component for this URI. + # + # @param [String, #to_str] new_path The new path component. + def path=(new_path) + if new_path && !new_path.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_path.class} into String." + end + @path = (new_path || EMPTY_STR).to_str + if !@path.empty? && @path[0..0] != SLASH && host != nil + @path = "/#{@path}" + end + + # Reset dependent values + @normalized_path = nil + remove_composite_values + + # Ensure we haven't created an invalid URI + validate() + end + + ## + # The basename, if any, of the file in the path component. + # + # @return [String] The path's basename. + def basename + # Path cannot be nil + return File.basename(self.path).sub(/;[^\/]*$/, EMPTY_STR) + end + + ## + # The extname, if any, of the file in the path component. + # Empty string if there is no extension. + # + # @return [String] The path's extname. + def extname + return nil unless self.path + return File.extname(self.basename) + end + + ## + # The query component for this URI. + # + # @return [String] The query component. + attr_reader :query + + ## + # The query component for this URI, normalized. + # + # @return [String] The query component, normalized. + def normalized_query(*flags) + return nil unless self.query + return @normalized_query unless @normalized_query == NONE + @normalized_query = begin + modified_query_class = Addressable::URI::CharacterClasses::QUERY.dup + # Make sure possible key-value pair delimiters are escaped. + modified_query_class.sub!("\\&", "").sub!("\\;", "") + pairs = (query || "").split("&", -1) + pairs.delete_if(&:empty?).uniq! if flags.include?(:compacted) + pairs.sort! if flags.include?(:sorted) + component = pairs.map do |pair| + Addressable::URI.normalize_component( + pair, + Addressable::URI::NormalizeCharacterClasses::QUERY, + "+" + ) + end.join("&") + component == "" ? nil : component + end + # All normalized values should be UTF-8 + force_utf8_encoding_if_needed(@normalized_query) + @normalized_query + end + + ## + # Sets the query component for this URI. + # + # @param [String, #to_str] new_query The new query component. + def query=(new_query) + if new_query && !new_query.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_query.class} into String." + end + @query = new_query ? new_query.to_str : nil + + # Reset dependent values + @normalized_query = NONE + remove_composite_values + end + + ## + # Converts the query component to a Hash value. + # + # @param [Class] return_type The return type desired. Value must be either + # `Hash` or `Array`. + # + # @return [Hash, Array, nil] The query string parsed as a Hash or Array + # or nil if the query string is blank. + # + # @example + # Addressable::URI.parse("?one=1&two=2&three=3").query_values + # #=> {"one" => "1", "two" => "2", "three" => "3"} + # Addressable::URI.parse("?one=two&one=three").query_values(Array) + # #=> [["one", "two"], ["one", "three"]] + # Addressable::URI.parse("?one=two&one=three").query_values(Hash) + # #=> {"one" => "three"} + # Addressable::URI.parse("?").query_values + # #=> {} + # Addressable::URI.parse("").query_values + # #=> nil + def query_values(return_type=Hash) + empty_accumulator = Array == return_type ? [] : {} + if return_type != Hash && return_type != Array + raise ArgumentError, "Invalid return type. Must be Hash or Array." + end + return nil if self.query == nil + split_query = self.query.split("&").map do |pair| + pair.split("=", 2) if pair && !pair.empty? + end.compact + return split_query.inject(empty_accumulator.dup) do |accu, pair| + # I'd rather use key/value identifiers instead of array lookups, + # but in this case I really want to maintain the exact pair structure, + # so it's best to make all changes in-place. + pair[0] = URI.unencode_component(pair[0]) + if pair[1].respond_to?(:to_str) + value = pair[1].to_str + # I loathe the fact that I have to do this. Stupid HTML 4.01. + # Treating '+' as a space was just an unbelievably bad idea. + # There was nothing wrong with '%20'! + # If it ain't broke, don't fix it! + value = value.tr("+", " ") if ["http", "https", nil].include?(scheme) + pair[1] = URI.unencode_component(value) + end + if return_type == Hash + accu[pair[0]] = pair[1] + else + accu << pair + end + accu + end + end + + ## + # Sets the query component for this URI from a Hash object. + # An empty Hash or Array will result in an empty query string. + # + # @param [Hash, #to_hash, Array] new_query_values The new query values. + # + # @example + # uri.query_values = {:a => "a", :b => ["c", "d", "e"]} + # uri.query + # # => "a=a&b=c&b=d&b=e" + # uri.query_values = [['a', 'a'], ['b', 'c'], ['b', 'd'], ['b', 'e']] + # uri.query + # # => "a=a&b=c&b=d&b=e" + # uri.query_values = [['a', 'a'], ['b', ['c', 'd', 'e']]] + # uri.query + # # => "a=a&b=c&b=d&b=e" + # uri.query_values = [['flag'], ['key', 'value']] + # uri.query + # # => "flag&key=value" + def query_values=(new_query_values) + if new_query_values == nil + self.query = nil + return nil + end + + if !new_query_values.is_a?(Array) + if !new_query_values.respond_to?(:to_hash) + raise TypeError, + "Can't convert #{new_query_values.class} into Hash." + end + new_query_values = new_query_values.to_hash + new_query_values = new_query_values.map do |key, value| + key = key.to_s if key.kind_of?(Symbol) + [key, value] + end + # Useful default for OAuth and caching. + # Only to be used for non-Array inputs. Arrays should preserve order. + new_query_values.sort! + end + + # new_query_values have form [['key1', 'value1'], ['key2', 'value2']] + buffer = "".dup + new_query_values.each do |key, value| + encoded_key = URI.encode_component( + key, CharacterClassesRegexps::UNRESERVED + ) + if value == nil + buffer << "#{encoded_key}&" + elsif value.kind_of?(Array) + value.each do |sub_value| + encoded_value = URI.encode_component( + sub_value, CharacterClassesRegexps::UNRESERVED + ) + buffer << "#{encoded_key}=#{encoded_value}&" + end + else + encoded_value = URI.encode_component( + value, CharacterClassesRegexps::UNRESERVED + ) + buffer << "#{encoded_key}=#{encoded_value}&" + end + end + self.query = buffer.chop + end + + ## + # The HTTP request URI for this URI. This is the path and the + # query string. + # + # @return [String] The request URI required for an HTTP request. + def request_uri + return nil if self.absolute? && self.scheme !~ /^https?$/i + return ( + (!self.path.empty? ? self.path : SLASH) + + (self.query ? "?#{self.query}" : EMPTY_STR) + ) + end + + ## + # Sets the HTTP request URI for this URI. + # + # @param [String, #to_str] new_request_uri The new HTTP request URI. + def request_uri=(new_request_uri) + if !new_request_uri.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_request_uri.class} into String." + end + if self.absolute? && self.scheme !~ /^https?$/i + raise InvalidURIError, + "Cannot set an HTTP request URI for a non-HTTP URI." + end + new_request_uri = new_request_uri.to_str + path_component = new_request_uri[/^([^\?]*)\??(?:.*)$/, 1] + query_component = new_request_uri[/^(?:[^\?]*)\?(.*)$/, 1] + path_component = path_component.to_s + path_component = (!path_component.empty? ? path_component : SLASH) + self.path = path_component + self.query = query_component + + # Reset dependent values + remove_composite_values + end + + ## + # The fragment component for this URI. + # + # @return [String] The fragment component. + attr_reader :fragment + + ## + # The fragment component for this URI, normalized. + # + # @return [String] The fragment component, normalized. + def normalized_fragment + return nil unless self.fragment + return @normalized_fragment unless @normalized_fragment == NONE + @normalized_fragment = begin + component = Addressable::URI.normalize_component( + self.fragment, + Addressable::URI::NormalizeCharacterClasses::FRAGMENT + ) + component == "" ? nil : component + end + # All normalized values should be UTF-8 + force_utf8_encoding_if_needed(@normalized_fragment) + @normalized_fragment + end + + ## + # Sets the fragment component for this URI. + # + # @param [String, #to_str] new_fragment The new fragment component. + def fragment=(new_fragment) + if new_fragment && !new_fragment.respond_to?(:to_str) + raise TypeError, "Can't convert #{new_fragment.class} into String." + end + @fragment = new_fragment ? new_fragment.to_str : nil + + # Reset dependent values + @normalized_fragment = NONE + remove_composite_values + + # Ensure we haven't created an invalid URI + validate() + end + + ## + # Determines if the scheme indicates an IP-based protocol. + # + # @return [TrueClass, FalseClass] + # true if the scheme indicates an IP-based protocol. + # false otherwise. + def ip_based? + if self.scheme + return URI.ip_based_schemes.include?( + self.scheme.strip.downcase) + end + return false + end + + ## + # Determines if the URI is relative. + # + # @return [TrueClass, FalseClass] + # true if the URI is relative. false + # otherwise. + def relative? + return self.scheme.nil? + end + + ## + # Determines if the URI is absolute. + # + # @return [TrueClass, FalseClass] + # true if the URI is absolute. false + # otherwise. + def absolute? + return !relative? + end + + ## + # Joins two URIs together. + # + # @param [String, Addressable::URI, #to_str] The URI to join with. + # + # @return [Addressable::URI] The joined URI. + def join(uri) + if !uri.respond_to?(:to_str) + raise TypeError, "Can't convert #{uri.class} into String." + end + if !uri.kind_of?(URI) + # Otherwise, convert to a String, then parse. + uri = URI.parse(uri.to_str) + end + if uri.to_s.empty? + return self.dup + end + + joined_scheme = nil + joined_user = nil + joined_password = nil + joined_host = nil + joined_port = nil + joined_path = nil + joined_query = nil + joined_fragment = nil + + # Section 5.2.2 of RFC 3986 + if uri.scheme != nil + joined_scheme = uri.scheme + joined_user = uri.user + joined_password = uri.password + joined_host = uri.host + joined_port = uri.port + joined_path = URI.normalize_path(uri.path) + joined_query = uri.query + else + if uri.authority != nil + joined_user = uri.user + joined_password = uri.password + joined_host = uri.host + joined_port = uri.port + joined_path = URI.normalize_path(uri.path) + joined_query = uri.query + else + if uri.path == nil || uri.path.empty? + joined_path = self.path + if uri.query != nil + joined_query = uri.query + else + joined_query = self.query + end + else + if uri.path[0..0] == SLASH + joined_path = URI.normalize_path(uri.path) + else + base_path = self.path.dup + base_path = EMPTY_STR if base_path == nil + base_path = URI.normalize_path(base_path) + + # Section 5.2.3 of RFC 3986 + # + # Removes the right-most path segment from the base path. + if base_path.include?(SLASH) + base_path.sub!(/\/[^\/]+$/, SLASH) + else + base_path = EMPTY_STR + end + + # If the base path is empty and an authority segment has been + # defined, use a base path of SLASH + if base_path.empty? && self.authority != nil + base_path = SLASH + end + + joined_path = URI.normalize_path(base_path + uri.path) + end + joined_query = uri.query + end + joined_user = self.user + joined_password = self.password + joined_host = self.host + joined_port = self.port + end + joined_scheme = self.scheme + end + joined_fragment = uri.fragment + + return self.class.new( + :scheme => joined_scheme, + :user => joined_user, + :password => joined_password, + :host => joined_host, + :port => joined_port, + :path => joined_path, + :query => joined_query, + :fragment => joined_fragment + ) + end + alias_method :+, :join + + ## + # Destructive form of join. + # + # @param [String, Addressable::URI, #to_str] The URI to join with. + # + # @return [Addressable::URI] The joined URI. + # + # @see Addressable::URI#join + def join!(uri) + replace_self(self.join(uri)) + end + + ## + # Merges a URI with a Hash of components. + # This method has different behavior from join. Any + # components present in the hash parameter will override the + # original components. The path component is not treated specially. + # + # @param [Hash, Addressable::URI, #to_hash] The components to merge with. + # + # @return [Addressable::URI] The merged URI. + # + # @see Hash#merge + def merge(hash) + unless hash.respond_to?(:to_hash) + raise TypeError, "Can't convert #{hash.class} into Hash." + end + hash = hash.to_hash + + if hash.has_key?(:authority) + if (hash.keys & [:userinfo, :user, :password, :host, :port]).any? + raise ArgumentError, + "Cannot specify both an authority and any of the components " + + "within the authority." + end + end + if hash.has_key?(:userinfo) + if (hash.keys & [:user, :password]).any? + raise ArgumentError, + "Cannot specify both a userinfo and either the user or password." + end + end + + uri = self.class.new + uri.defer_validation do + # Bunch of crazy logic required because of the composite components + # like userinfo and authority. + uri.scheme = + hash.has_key?(:scheme) ? hash[:scheme] : self.scheme + if hash.has_key?(:authority) + uri.authority = + hash.has_key?(:authority) ? hash[:authority] : self.authority + end + if hash.has_key?(:userinfo) + uri.userinfo = + hash.has_key?(:userinfo) ? hash[:userinfo] : self.userinfo + end + if !hash.has_key?(:userinfo) && !hash.has_key?(:authority) + uri.user = + hash.has_key?(:user) ? hash[:user] : self.user + uri.password = + hash.has_key?(:password) ? hash[:password] : self.password + end + if !hash.has_key?(:authority) + uri.host = + hash.has_key?(:host) ? hash[:host] : self.host + uri.port = + hash.has_key?(:port) ? hash[:port] : self.port + end + uri.path = + hash.has_key?(:path) ? hash[:path] : self.path + uri.query = + hash.has_key?(:query) ? hash[:query] : self.query + uri.fragment = + hash.has_key?(:fragment) ? hash[:fragment] : self.fragment + end + + return uri + end + + ## + # Destructive form of merge. + # + # @param [Hash, Addressable::URI, #to_hash] The components to merge with. + # + # @return [Addressable::URI] The merged URI. + # + # @see Addressable::URI#merge + def merge!(uri) + replace_self(self.merge(uri)) + end + + ## + # Returns the shortest normalized relative form of this URI that uses the + # supplied URI as a base for resolution. Returns an absolute URI if + # necessary. This is effectively the opposite of route_to. + # + # @param [String, Addressable::URI, #to_str] uri The URI to route from. + # + # @return [Addressable::URI] + # The normalized relative URI that is equivalent to the original URI. + def route_from(uri) + uri = URI.parse(uri).normalize + normalized_self = self.normalize + if normalized_self.relative? + raise ArgumentError, "Expected absolute URI, got: #{self.to_s}" + end + if uri.relative? + raise ArgumentError, "Expected absolute URI, got: #{uri.to_s}" + end + if normalized_self == uri + return Addressable::URI.parse("##{normalized_self.fragment}") + end + components = normalized_self.to_hash + if normalized_self.scheme == uri.scheme + components[:scheme] = nil + if normalized_self.authority == uri.authority + components[:user] = nil + components[:password] = nil + components[:host] = nil + components[:port] = nil + if normalized_self.path == uri.path + components[:path] = nil + if normalized_self.query == uri.query + components[:query] = nil + end + else + if uri.path != SLASH and components[:path] + self_splitted_path = split_path(components[:path]) + uri_splitted_path = split_path(uri.path) + self_dir = self_splitted_path.shift + uri_dir = uri_splitted_path.shift + while !self_splitted_path.empty? && !uri_splitted_path.empty? and self_dir == uri_dir + self_dir = self_splitted_path.shift + uri_dir = uri_splitted_path.shift + end + components[:path] = (uri_splitted_path.fill('..') + [self_dir] + self_splitted_path).join(SLASH) + end + end + end + end + # Avoid network-path references. + if components[:host] != nil + components[:scheme] = normalized_self.scheme + end + return Addressable::URI.new( + :scheme => components[:scheme], + :user => components[:user], + :password => components[:password], + :host => components[:host], + :port => components[:port], + :path => components[:path], + :query => components[:query], + :fragment => components[:fragment] + ) + end + + ## + # Returns the shortest normalized relative form of the supplied URI that + # uses this URI as a base for resolution. Returns an absolute URI if + # necessary. This is effectively the opposite of route_from. + # + # @param [String, Addressable::URI, #to_str] uri The URI to route to. + # + # @return [Addressable::URI] + # The normalized relative URI that is equivalent to the supplied URI. + def route_to(uri) + return URI.parse(uri).route_from(self) + end + + ## + # Returns a normalized URI object. + # + # NOTE: This method does not attempt to fully conform to specifications. + # It exists largely to correct other people's failures to read the + # specifications, and also to deal with caching issues since several + # different URIs may represent the same resource and should not be + # cached multiple times. + # + # @return [Addressable::URI] The normalized URI. + def normalize + # This is a special exception for the frequently misused feed + # URI scheme. + if normalized_scheme == "feed" + if self.to_s =~ /^feed:\/*http:\/*/ + return URI.parse( + self.to_s[/^feed:\/*(http:\/*.*)/, 1] + ).normalize + end + end + + return self.class.new( + :scheme => normalized_scheme, + :authority => normalized_authority, + :path => normalized_path, + :query => normalized_query, + :fragment => normalized_fragment + ) + end + + ## + # Destructively normalizes this URI object. + # + # @return [Addressable::URI] The normalized URI. + # + # @see Addressable::URI#normalize + def normalize! + replace_self(self.normalize) + end + + ## + # Creates a URI suitable for display to users. If semantic attacks are + # likely, the application should try to detect these and warn the user. + # See RFC 3986, + # section 7.6 for more information. + # + # @return [Addressable::URI] A URI suitable for display purposes. + def display_uri + display_uri = self.normalize + display_uri.host = ::Addressable::IDNA.to_unicode(display_uri.host) + return display_uri + end + + ## + # Returns true if the URI objects are equal. This method + # normalizes both URIs before doing the comparison, and allows comparison + # against Strings. + # + # @param [Object] uri The URI to compare. + # + # @return [TrueClass, FalseClass] + # true if the URIs are equivalent, false + # otherwise. + def ===(uri) + if uri.respond_to?(:normalize) + uri_string = uri.normalize.to_s + else + begin + uri_string = ::Addressable::URI.parse(uri).normalize.to_s + rescue InvalidURIError, TypeError + return false + end + end + return self.normalize.to_s == uri_string + end + + ## + # Returns true if the URI objects are equal. This method + # normalizes both URIs before doing the comparison. + # + # @param [Object] uri The URI to compare. + # + # @return [TrueClass, FalseClass] + # true if the URIs are equivalent, false + # otherwise. + def ==(uri) + return false unless uri.kind_of?(URI) + return self.normalize.to_s == uri.normalize.to_s + end + + ## + # Returns true if the URI objects are equal. This method + # does NOT normalize either URI before doing the comparison. + # + # @param [Object] uri The URI to compare. + # + # @return [TrueClass, FalseClass] + # true if the URIs are equivalent, false + # otherwise. + def eql?(uri) + return false unless uri.kind_of?(URI) + return self.to_s == uri.to_s + end + + ## + # A hash value that will make a URI equivalent to its normalized + # form. + # + # @return [Integer] A hash of the URI. + def hash + @hash ||= self.to_s.hash * -1 + end + + ## + # Clones the URI object. + # + # @return [Addressable::URI] The cloned URI. + def dup + duplicated_uri = self.class.new( + :scheme => self.scheme ? self.scheme.dup : nil, + :user => self.user ? self.user.dup : nil, + :password => self.password ? self.password.dup : nil, + :host => self.host ? self.host.dup : nil, + :port => self.port, + :path => self.path ? self.path.dup : nil, + :query => self.query ? self.query.dup : nil, + :fragment => self.fragment ? self.fragment.dup : nil + ) + return duplicated_uri + end + + ## + # Omits components from a URI. + # + # @param [Symbol] *components The components to be omitted. + # + # @return [Addressable::URI] The URI with components omitted. + # + # @example + # uri = Addressable::URI.parse("http://example.com/path?query") + # #=> # + # uri.omit(:scheme, :authority) + # #=> # + def omit(*components) + invalid_components = components - [ + :scheme, :user, :password, :userinfo, :host, :port, :authority, + :path, :query, :fragment + ] + unless invalid_components.empty? + raise ArgumentError, + "Invalid component names: #{invalid_components.inspect}." + end + duplicated_uri = self.dup + duplicated_uri.defer_validation do + components.each do |component| + duplicated_uri.send((component.to_s + "=").to_sym, nil) + end + duplicated_uri.user = duplicated_uri.normalized_user + end + duplicated_uri + end + + ## + # Destructive form of omit. + # + # @param [Symbol] *components The components to be omitted. + # + # @return [Addressable::URI] The URI with components omitted. + # + # @see Addressable::URI#omit + def omit!(*components) + replace_self(self.omit(*components)) + end + + ## + # Determines if the URI is an empty string. + # + # @return [TrueClass, FalseClass] + # Returns true if empty, false otherwise. + def empty? + return self.to_s.empty? + end + + ## + # Converts the URI to a String. + # + # @return [String] The URI's String representation. + def to_s + if self.scheme == nil && self.path != nil && !self.path.empty? && + self.path =~ NORMPATH + raise InvalidURIError, + "Cannot assemble URI string with ambiguous path: '#{self.path}'" + end + @uri_string ||= begin + uri_string = String.new + uri_string << "#{self.scheme}:" if self.scheme != nil + uri_string << "//#{self.authority}" if self.authority != nil + uri_string << self.path.to_s + uri_string << "?#{self.query}" if self.query != nil + uri_string << "##{self.fragment}" if self.fragment != nil + uri_string.force_encoding(Encoding::UTF_8) + uri_string + end + end + + ## + # URI's are glorified Strings. Allow implicit conversion. + alias_method :to_str, :to_s + + ## + # Returns a Hash of the URI components. + # + # @return [Hash] The URI as a Hash of components. + def to_hash + return { + :scheme => self.scheme, + :user => self.user, + :password => self.password, + :host => self.host, + :port => self.port, + :path => self.path, + :query => self.query, + :fragment => self.fragment + } + end + + ## + # Returns a String representation of the URI object's state. + # + # @return [String] The URI object's state, as a String. + def inspect + sprintf("#<%s:%#0x URI:%s>", URI.to_s, self.object_id, self.to_s) + end + + ## + # This method allows you to make several changes to a URI simultaneously, + # which separately would cause validation errors, but in conjunction, + # are valid. The URI will be revalidated as soon as the entire block has + # been executed. + # + # @param [Proc] block + # A set of operations to perform on a given URI. + def defer_validation + raise LocalJumpError, "No block given." unless block_given? + @validation_deferred = true + yield + @validation_deferred = false + validate + ensure + @validation_deferred = false + end + + def encode_with(coder) + instance_variables.each do |ivar| + value = instance_variable_get(ivar) + if value != NONE + key = ivar.to_s.slice(1..-1) + coder[key] = value + end + end + nil + end + + def init_with(coder) + reset_ivs + coder.map.each do |key, value| + instance_variable_set("@#{key}", value) + end + nil + end + + protected + SELF_REF = '.' + PARENT = '..' + + RULE_2A = /\/\.\/|\/\.$/ + RULE_2B_2C = /\/([^\/]*)\/\.\.\/|\/([^\/]*)\/\.\.$/ + RULE_2D = /^\.\.?\/?/ + RULE_PREFIXED_PARENT = /^\/\.\.?\/|^(\/\.\.?)+\/?$/ + + ## + # Resolves paths to their simplest form. + # + # @param [String] path The path to normalize. + # + # @return [String] The normalized path. + def self.normalize_path(path) + # Section 5.2.4 of RFC 3986 + + return if path.nil? + normalized_path = path.dup + loop do + mod ||= normalized_path.gsub!(RULE_2A, SLASH) + + pair = normalized_path.match(RULE_2B_2C) + if pair + parent = pair[1] + current = pair[2] + else + parent = nil + current = nil + end + + regexp = "/#{Regexp.escape(parent.to_s)}/\\.\\./|" + regexp += "(/#{Regexp.escape(current.to_s)}/\\.\\.$)" + + if pair && ((parent != SELF_REF && parent != PARENT) || + (current != SELF_REF && current != PARENT)) + mod ||= normalized_path.gsub!(Regexp.new(regexp), SLASH) + end + + mod ||= normalized_path.gsub!(RULE_2D, EMPTY_STR) + # Non-standard, removes prefixed dotted segments from path. + mod ||= normalized_path.gsub!(RULE_PREFIXED_PARENT, SLASH) + break if mod.nil? + end + + normalized_path + end + + ## + # Ensures that the URI is valid. + def validate + return if !!@validation_deferred + if self.scheme != nil && self.ip_based? && + (self.host == nil || self.host.empty?) && + (self.path == nil || self.path.empty?) + raise InvalidURIError, + "Absolute URI missing hierarchical segment: '#{self.to_s}'" + end + if self.host == nil + if self.port != nil || + self.user != nil || + self.password != nil + raise InvalidURIError, "Hostname not supplied: '#{self.to_s}'" + end + end + if self.path != nil && !self.path.empty? && self.path[0..0] != SLASH && + self.authority != nil + raise InvalidURIError, + "Cannot have a relative path with an authority set: '#{self.to_s}'" + end + if self.path != nil && !self.path.empty? && + self.path[0..1] == SLASH + SLASH && self.authority == nil + raise InvalidURIError, + "Cannot have a path with two leading slashes " + + "without an authority set: '#{self.to_s}'" + end + unreserved = CharacterClasses::UNRESERVED + sub_delims = CharacterClasses::SUB_DELIMS + if !self.host.nil? && (self.host =~ /[<>{}\/\\\?\#\@"[[:space:]]]/ || + (self.host[/^\[(.*)\]$/, 1] != nil && self.host[/^\[(.*)\]$/, 1] !~ + Regexp.new("^[#{unreserved}#{sub_delims}:]*$"))) + raise InvalidURIError, "Invalid character in host: '#{self.host.to_s}'" + end + return nil + end + + ## + # Replaces the internal state of self with the specified URI's state. + # Used in destructive operations to avoid massive code repetition. + # + # @param [Addressable::URI] uri The URI to replace self with. + # + # @return [Addressable::URI] self. + def replace_self(uri) + # Reset dependent values + reset_ivs + + @scheme = uri.scheme + @user = uri.user + @password = uri.password + @host = uri.host + @port = uri.port + @path = uri.path + @query = uri.query + @fragment = uri.fragment + return self + end + + ## + # Splits path string with "/" (slash). + # It is considered that there is empty string after last slash when + # path ends with slash. + # + # @param [String] path The path to split. + # + # @return [Array] An array of parts of path. + def split_path(path) + splitted = path.split(SLASH) + splitted << EMPTY_STR if path.end_with? SLASH + splitted + end + + ## + # Resets composite values for the entire URI + # + # @api private + def remove_composite_values + @uri_string = nil + @hash = nil + end + + ## + # Converts the string to be UTF-8 if it is not already UTF-8 + # + # @api private + def force_utf8_encoding_if_needed(str) + if str && str.encoding != Encoding::UTF_8 + str.force_encoding(Encoding::UTF_8) + end + end + + private + + ## + # Resets instance variables + # + # @api private + def reset_ivs + @scheme = nil + @user = nil + @normalized_scheme = NONE + @normalized_user = NONE + @uri_string = nil + @hash = nil + @userinfo = nil + @normalized_userinfo = NONE + @authority = nil + @password = nil + @normalized_authority = nil + @port = nil + @normalized_password = NONE + @host = nil + @normalized_host = nil + @normalized_port = NONE + @path = EMPTY_STR + @normalized_path = nil + @normalized_query = NONE + @fragment = nil + @normalized_fragment = NONE + @query = nil + end + + NONE = Module.new.freeze + + private_constant :NONE + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/lib/addressable/version.rb b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/lib/addressable/version.rb new file mode 100644 index 00000000..2eec3e65 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/lib/addressable/version.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +#-- +# Copyright (C) Bob Aman +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#++ + + +# Used to prevent the class/module from being loaded more than once +if !defined?(Addressable::VERSION) + module Addressable + module VERSION + MAJOR = 2 + MINOR = 8 + TINY = 7 + + STRING = [MAJOR, MINOR, TINY].join('.') + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/spec/addressable/idna_spec.rb b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/spec/addressable/idna_spec.rb new file mode 100644 index 00000000..428c9ec8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/spec/addressable/idna_spec.rb @@ -0,0 +1,302 @@ +# frozen_string_literal: true + +# Copyright (C) Bob Aman +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +require "spec_helper" + +# Have to use RubyGems to load the idn gem. +require "rubygems" + +require "addressable/idna" + +shared_examples_for "converting from unicode to ASCII" do + it "should convert 'www.google.com' correctly" do + expect(Addressable::IDNA.to_ascii("www.google.com")).to eq("www.google.com") + end + + long = 'AcinusFallumTrompetumNullunCreditumVisumEstAtCuadLongumEtCefallum.com' + it "should convert '#{long}' correctly" do + expect(Addressable::IDNA.to_ascii(long)).to eq(long) + end + + it "should convert 'www.詹姆斯.com' correctly" do + expect(Addressable::IDNA.to_ascii( + "www.詹姆斯.com" + )).to eq("www.xn--8ws00zhy3a.com") + end + + it "also accepts unicode strings encoded as ascii-8bit" do + expect(Addressable::IDNA.to_ascii( + "www.詹姆斯.com".b + )).to eq("www.xn--8ws00zhy3a.com") + end + + it "should convert 'www.Iñtërnâtiônàlizætiøn.com' correctly" do + "www.Iñtërnâtiônàlizætiøn.com" + expect(Addressable::IDNA.to_ascii( + "www.I\xC3\xB1t\xC3\xABrn\xC3\xA2ti\xC3\xB4" + + "n\xC3\xA0liz\xC3\xA6ti\xC3\xB8n.com" + )).to eq("www.xn--itrntinliztin-vdb0a5exd8ewcye.com") + end + + it "should convert 'www.Iñtërnâtiônàlizætiøn.com' correctly" do + expect(Addressable::IDNA.to_ascii( + "www.In\xCC\x83te\xCC\x88rna\xCC\x82tio\xCC\x82n" + + "a\xCC\x80liz\xC3\xA6ti\xC3\xB8n.com" + )).to eq("www.xn--itrntinliztin-vdb0a5exd8ewcye.com") + end + + it "should convert " + + "'www.ほんとうにながいわけのわからないどめいんめいのらべるまだながくしないとたりない.w3.mag.keio.ac.jp' " + + "correctly" do + expect(Addressable::IDNA.to_ascii( + "www.\343\201\273\343\202\223\343\201\250\343\201\206\343\201\253\343" + + "\201\252\343\201\214\343\201\204\343\202\217\343\201\221\343\201\256" + + "\343\202\217\343\201\213\343\202\211\343\201\252\343\201\204\343\201" + + "\251\343\202\201\343\201\204\343\202\223\343\202\201\343\201\204\343" + + "\201\256\343\202\211\343\201\271\343\202\213\343\201\276\343\201\240" + + "\343\201\252\343\201\214\343\201\217\343\201\227\343\201\252\343\201" + + "\204\343\201\250\343\201\237\343\202\212\343\201\252\343\201\204." + + "w3.mag.keio.ac.jp" + )).to eq( + "www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3" + + "fg11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp" + ) + end + + it "should convert " + + "'www.ほんとうにながいわけのわからないどめいんめいのらべるまだながくしないとたりない.w3.mag.keio.ac.jp' " + + "correctly" do + expect(Addressable::IDNA.to_ascii( + "www.\343\201\273\343\202\223\343\201\250\343\201\206\343\201\253\343" + + "\201\252\343\201\213\343\202\231\343\201\204\343\202\217\343\201\221" + + "\343\201\256\343\202\217\343\201\213\343\202\211\343\201\252\343\201" + + "\204\343\201\250\343\202\231\343\202\201\343\201\204\343\202\223\343" + + "\202\201\343\201\204\343\201\256\343\202\211\343\201\270\343\202\231" + + "\343\202\213\343\201\276\343\201\237\343\202\231\343\201\252\343\201" + + "\213\343\202\231\343\201\217\343\201\227\343\201\252\343\201\204\343" + + "\201\250\343\201\237\343\202\212\343\201\252\343\201\204." + + "w3.mag.keio.ac.jp" + )).to eq( + "www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3" + + "fg11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp" + ) + end + + it "should convert '点心和烤鸭.w3.mag.keio.ac.jp' correctly" do + expect(Addressable::IDNA.to_ascii( + "点心和烤鸭.w3.mag.keio.ac.jp" + )).to eq("xn--0trv4xfvn8el34t.w3.mag.keio.ac.jp") + end + + it "should convert '가각갂갃간갅갆갇갈갉힢힣.com' correctly" do + expect(Addressable::IDNA.to_ascii( + "가각갂갃간갅갆갇갈갉힢힣.com" + )).to eq("xn--o39acdefghijk5883jma.com") + end + + it "should convert " + + "'\347\242\274\346\250\231\346\272\226\350" + + "\220\254\345\234\213\347\242\274.com' correctly" do + expect(Addressable::IDNA.to_ascii( + "\347\242\274\346\250\231\346\272\226\350" + + "\220\254\345\234\213\347\242\274.com" + )).to eq("xn--9cs565brid46mda086o.com") + end + + it "should convert 'リ宠퐱〹.com' correctly" do + expect(Addressable::IDNA.to_ascii( + "\357\276\230\345\256\240\355\220\261\343\200\271.com" + )).to eq("xn--eek174hoxfpr4k.com") + end + + it "should convert 'リ宠퐱卄.com' correctly" do + expect(Addressable::IDNA.to_ascii( + "\343\203\252\345\256\240\355\220\261\345\215\204.com" + )).to eq("xn--eek174hoxfpr4k.com") + end + + it "should convert 'ᆵ' correctly" do + expect(Addressable::IDNA.to_ascii( + "\341\206\265" + )).to eq("xn--4ud") + end + + it "should convert 'ᆵ' correctly" do + expect(Addressable::IDNA.to_ascii( + "\357\276\257" + )).to eq("xn--4ud") + end + + it "should convert '🌹🌹🌹.ws' correctly" do + expect(Addressable::IDNA.to_ascii( + "\360\237\214\271\360\237\214\271\360\237\214\271.ws" + )).to eq("xn--2h8haa.ws") + end + + it "should handle two adjacent '.'s correctly" do + expect(Addressable::IDNA.to_ascii( + "example..host" + )).to eq("example..host") + end +end + +shared_examples_for "converting from ASCII to unicode" do + long = 'AcinusFallumTrompetumNullunCreditumVisumEstAtCuadLongumEtCefallum.com' + it "should convert '#{long}' correctly" do + expect(Addressable::IDNA.to_unicode(long)).to eq(long) + end + + it "should return the identity conversion when punycode decode fails" do + expect(Addressable::IDNA.to_unicode("xn--zckp1cyg1.sblo.jp")).to eq( + "xn--zckp1cyg1.sblo.jp") + end + + it "should return the identity conversion when the ACE prefix has no suffix" do + expect(Addressable::IDNA.to_unicode("xn--...-")).to eq("xn--...-") + end + + it "should convert 'www.google.com' correctly" do + expect(Addressable::IDNA.to_unicode("www.google.com")).to eq( + "www.google.com") + end + + it "should convert 'www.詹姆斯.com' correctly" do + expect(Addressable::IDNA.to_unicode( + "www.xn--8ws00zhy3a.com" + )).to eq("www.詹姆斯.com") + end + + it "should convert '詹姆斯.com' correctly" do + expect(Addressable::IDNA.to_unicode( + "xn--8ws00zhy3a.com" + )).to eq("詹姆斯.com") + end + + it "should convert 'www.iñtërnâtiônàlizætiøn.com' correctly" do + expect(Addressable::IDNA.to_unicode( + "www.xn--itrntinliztin-vdb0a5exd8ewcye.com" + )).to eq("www.iñtërnâtiônàlizætiøn.com") + end + + it "should convert 'iñtërnâtiônàlizætiøn.com' correctly" do + expect(Addressable::IDNA.to_unicode( + "xn--itrntinliztin-vdb0a5exd8ewcye.com" + )).to eq("iñtërnâtiônàlizætiøn.com") + end + + it "should convert " + + "'www.ほんとうにながいわけのわからないどめいんめいのらべるまだながくしないとたりない.w3.mag.keio.ac.jp' " + + "correctly" do + expect(Addressable::IDNA.to_unicode( + "www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3" + + "fg11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp" + )).to eq( + "www.ほんとうにながいわけのわからないどめいんめいのらべるまだながくしないとたりない.w3.mag.keio.ac.jp" + ) + end + + it "should convert '点心和烤鸭.w3.mag.keio.ac.jp' correctly" do + expect(Addressable::IDNA.to_unicode( + "xn--0trv4xfvn8el34t.w3.mag.keio.ac.jp" + )).to eq("点心和烤鸭.w3.mag.keio.ac.jp") + end + + it "should convert '가각갂갃간갅갆갇갈갉힢힣.com' correctly" do + expect(Addressable::IDNA.to_unicode( + "xn--o39acdefghijk5883jma.com" + )).to eq("가각갂갃간갅갆갇갈갉힢힣.com") + end + + it "should convert " + + "'\347\242\274\346\250\231\346\272\226\350" + + "\220\254\345\234\213\347\242\274.com' correctly" do + expect(Addressable::IDNA.to_unicode( + "xn--9cs565brid46mda086o.com" + )).to eq( + "\347\242\274\346\250\231\346\272\226\350" + + "\220\254\345\234\213\347\242\274.com" + ) + end + + it "should convert 'リ宠퐱卄.com' correctly" do + expect(Addressable::IDNA.to_unicode( + "xn--eek174hoxfpr4k.com" + )).to eq("\343\203\252\345\256\240\355\220\261\345\215\204.com") + end + + it "should convert 'ᆵ' correctly" do + expect(Addressable::IDNA.to_unicode( + "xn--4ud" + )).to eq("\341\206\265") + end + + it "should convert '🌹🌹🌹.ws' correctly" do + expect(Addressable::IDNA.to_unicode( + "xn--2h8haa.ws" + )).to eq("\360\237\214\271\360\237\214\271\360\237\214\271.ws") + end + + it "should handle two adjacent '.'s correctly" do + expect(Addressable::IDNA.to_unicode( + "example..host" + )).to eq("example..host") + end +end + +describe Addressable::IDNA, "when using the pure-Ruby implementation" do + before do + Addressable.send(:remove_const, :IDNA) + load "addressable/idna/pure.rb" + end + + it_should_behave_like "converting from unicode to ASCII" + it_should_behave_like "converting from ASCII to unicode" + + begin + require "fiber" + + it "should not blow up inside fibers" do + f = Fiber.new do + Addressable.send(:remove_const, :IDNA) + load "addressable/idna/pure.rb" + end + f.resume + end + rescue LoadError + # Fibers aren't supported in this version of Ruby, skip this test. + warn('Fibers unsupported.') + end +end + +begin + require "idn" + + describe Addressable::IDNA, "when using the native-code implementation" do + before do + Addressable.send(:remove_const, :IDNA) + load "addressable/idna/native.rb" + end + + it_should_behave_like "converting from unicode to ASCII" + it_should_behave_like "converting from ASCII to unicode" + end +rescue LoadError => error + raise error if ENV["CI"] && TestHelper.native_supported? + + # Cannot test the native implementation without libidn support. + warn('Could not load native IDN implementation.') +end diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/spec/addressable/net_http_compat_spec.rb b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/spec/addressable/net_http_compat_spec.rb new file mode 100644 index 00000000..d07a43e5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/spec/addressable/net_http_compat_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +# Copyright (C) Bob Aman +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +require "spec_helper" + +require "addressable/uri" +require "net/http" + +describe Net::HTTP do + it "should be compatible with Addressable" do + response_body = + Net::HTTP.get(Addressable::URI.parse('http://www.google.com/')) + expect(response_body).not_to be_nil + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/spec/addressable/security_spec.rb b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/spec/addressable/security_spec.rb new file mode 100644 index 00000000..3bf90a20 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/spec/addressable/security_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +# Copyright (C) Bob Aman +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +require "spec_helper" + +require "addressable/uri" + +describe Addressable::URI, "when created with a URI known to cause crashes " + + "in certain browsers" do + it "should parse correctly" do + uri = Addressable::URI.parse('%%30%30') + expect(uri.path).to eq('%%30%30') + expect(uri.normalize.path).to eq('%2500') + end + + it "should parse correctly as a full URI" do + uri = Addressable::URI.parse('http://www.example.com/%%30%30') + expect(uri.path).to eq('/%%30%30') + expect(uri.normalize.path).to eq('/%2500') + end +end + +describe Addressable::URI, "when created with a URI known to cause crashes " + + "in certain browsers" do + it "should parse correctly" do + uri = Addressable::URI.parse('لُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ 冗') + expect(uri.path).to eq('لُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ 冗') + expect(uri.normalize.path).to eq( + '%D9%84%D9%8F%D8%B5%D9%91%D8%A8%D9%8F%D9%84%D9%8F%D9%84%D8%B5%D9%91' + + '%D8%A8%D9%8F%D8%B1%D8%B1%D9%8B%20%E0%A5%A3%20%E0%A5%A3h%20%E0%A5' + + '%A3%20%E0%A5%A3%20%E5%86%97' + ) + end + + it "should parse correctly as a full URI" do + uri = Addressable::URI.parse('http://www.example.com/لُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ 冗') + expect(uri.path).to eq('/لُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ 冗') + expect(uri.normalize.path).to eq( + '/%D9%84%D9%8F%D8%B5%D9%91%D8%A8%D9%8F%D9%84%D9%8F%D9%84%D8%B5%D9%91' + + '%D8%A8%D9%8F%D8%B1%D8%B1%D9%8B%20%E0%A5%A3%20%E0%A5%A3h%20%E0%A5' + + '%A3%20%E0%A5%A3%20%E5%86%97' + ) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/spec/addressable/template_spec.rb b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/spec/addressable/template_spec.rb new file mode 100644 index 00000000..24616c23 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/spec/addressable/template_spec.rb @@ -0,0 +1,1264 @@ +# frozen_string_literal: true + +# Copyright (C) Bob Aman +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +require "spec_helper" + +require "bigdecimal" +require "timeout" +require "addressable/template" + +shared_examples_for 'expands' do |tests| + tests.each do |template, expansion| + exp = expansion.is_a?(Array) ? expansion.first : expansion + it "#{template} to #{exp}" do + tmpl = Addressable::Template.new(template).expand(subject) + expect(tmpl.to_str).to eq(expansion) + end + end +end + +describe "eql?" do + let(:template) { Addressable::Template.new('https://www.example.com/{foo}') } + it 'is equal when the pattern matches' do + other_template = Addressable::Template.new('https://www.example.com/{foo}') + expect(template).to be_eql(other_template) + expect(other_template).to be_eql(template) + end + it 'is not equal when the pattern differs' do + other_template = Addressable::Template.new('https://www.example.com/{bar}') + expect(template).to_not be_eql(other_template) + expect(other_template).to_not be_eql(template) + end + it 'is not equal to non-templates' do + uri = 'https://www.example.com/foo/bar' + addressable_template = Addressable::Template.new uri + addressable_uri = Addressable::URI.parse uri + expect(addressable_template).to_not be_eql(addressable_uri) + expect(addressable_uri).to_not be_eql(addressable_template) + end +end + +describe "==" do + let(:template) { Addressable::Template.new('https://www.example.com/{foo}') } + it 'is equal when the pattern matches' do + other_template = Addressable::Template.new('https://www.example.com/{foo}') + expect(template).to eq other_template + expect(other_template).to eq template + end + it 'is not equal when the pattern differs' do + other_template = Addressable::Template.new('https://www.example.com/{bar}') + expect(template).not_to eq other_template + expect(other_template).not_to eq template + end + it 'is not equal to non-templates' do + uri = 'https://www.example.com/foo/bar' + addressable_template = Addressable::Template.new uri + addressable_uri = Addressable::URI.parse uri + expect(addressable_template).not_to eq addressable_uri + expect(addressable_uri).not_to eq addressable_template + end +end + +describe "#to_regexp" do + it "does not match the first line of multiline strings" do + uri = "https://www.example.com/bar" + template = Addressable::Template.new(uri) + expect(template.match(uri)).not_to be_nil + expect(template.match("#{uri}\ngarbage")).to be_nil + end +end + +describe "Type conversion" do + subject { + { + :var => true, + :hello => 1234, + :nothing => nil, + :sym => :symbolic, + :decimal => BigDecimal('1') + } + } + + it_behaves_like 'expands', { + '{var}' => 'true', + '{hello}' => '1234', + '{nothing}' => '', + '{sym}' => 'symbolic', + '{decimal}' => RUBY_VERSION < '2.4.0' ? '0.1E1' : '0.1e1' + } +end + +describe "Level 1:" do + subject { + {:var => "value", :hello => "Hello World!"} + } + it_behaves_like 'expands', { + '{var}' => 'value', + '{hello}' => 'Hello%20World%21' + } +end + +describe "Level 2" do + subject { + { + :var => "value", + :hello => "Hello World!", + :path => "/foo/bar" + } + } + context "Operator +:" do + it_behaves_like 'expands', { + '{+var}' => 'value', + '{+hello}' => 'Hello%20World!', + '{+path}/here' => '/foo/bar/here', + 'here?ref={+path}' => 'here?ref=/foo/bar' + } + end + context "Operator #:" do + it_behaves_like 'expands', { + 'X{#var}' => 'X#value', + 'X{#hello}' => 'X#Hello%20World!' + } + end +end + +describe "Level 3" do + subject { + { + :var => "value", + :hello => "Hello World!", + :empty => "", + :path => "/foo/bar", + :x => "1024", + :y => "768" + } + } + context "Operator nil (multiple vars):" do + it_behaves_like 'expands', { + 'map?{x,y}' => 'map?1024,768', + '{x,hello,y}' => '1024,Hello%20World%21,768' + } + end + context "Operator + (multiple vars):" do + it_behaves_like 'expands', { + '{+x,hello,y}' => '1024,Hello%20World!,768', + '{+path,x}/here' => '/foo/bar,1024/here' + } + end + context "Operator # (multiple vars):" do + it_behaves_like 'expands', { + '{#x,hello,y}' => '#1024,Hello%20World!,768', + '{#path,x}/here' => '#/foo/bar,1024/here' + } + end + context "Operator ." do + it_behaves_like 'expands', { + 'X{.var}' => 'X.value', + 'X{.x,y}' => 'X.1024.768' + } + end + context "Operator /" do + it_behaves_like 'expands', { + '{/var}' => '/value', + '{/var,x}/here' => '/value/1024/here' + } + end + context "Operator ;" do + it_behaves_like 'expands', { + '{;x,y}' => ';x=1024;y=768', + '{;x,y,empty}' => ';x=1024;y=768;empty' + } + end + context "Operator ?" do + it_behaves_like 'expands', { + '{?x,y}' => '?x=1024&y=768', + '{?x,y,empty}' => '?x=1024&y=768&empty=' + } + end + context "Operator &" do + it_behaves_like 'expands', { + '?fixed=yes{&x}' => '?fixed=yes&x=1024', + '{&x,y,empty}' => '&x=1024&y=768&empty=' + } + end +end + +describe "Level 4" do + subject { + { + :var => "value", + :hello => "Hello World!", + :path => "/foo/bar", + :semi => ";", + :list => %w(red green blue), + :keys => {"semi" => ';', "dot" => '.', :comma => ','} + } + } + context "Expansion with value modifiers" do + it_behaves_like 'expands', { + '{var:3}' => 'val', + '{var:30}' => 'value', + '{list}' => 'red,green,blue', + '{list*}' => 'red,green,blue', + '{keys}' => 'semi,%3B,dot,.,comma,%2C', + '{keys*}' => 'semi=%3B,dot=.,comma=%2C', + } + end + context "Operator + with value modifiers" do + it_behaves_like 'expands', { + '{+path:6}/here' => '/foo/b/here', + '{+list}' => 'red,green,blue', + '{+list*}' => 'red,green,blue', + '{+keys}' => 'semi,;,dot,.,comma,,', + '{+keys*}' => 'semi=;,dot=.,comma=,', + } + end + context "Operator # with value modifiers" do + it_behaves_like 'expands', { + '{#path:6}/here' => '#/foo/b/here', + '{#list}' => '#red,green,blue', + '{#list*}' => '#red,green,blue', + '{#keys}' => '#semi,;,dot,.,comma,,', + '{#keys*}' => '#semi=;,dot=.,comma=,', + } + end + context "Operator . with value modifiers" do + it_behaves_like 'expands', { + 'X{.var:3}' => 'X.val', + 'X{.list}' => 'X.red,green,blue', + 'X{.list*}' => 'X.red.green.blue', + 'X{.keys}' => 'X.semi,%3B,dot,.,comma,%2C', + 'X{.keys*}' => 'X.semi=%3B.dot=..comma=%2C', + } + end + context "Operator / with value modifiers" do + it_behaves_like 'expands', { + '{/var:1,var}' => '/v/value', + '{/list}' => '/red,green,blue', + '{/list*}' => '/red/green/blue', + '{/list*,path:4}' => '/red/green/blue/%2Ffoo', + '{/keys}' => '/semi,%3B,dot,.,comma,%2C', + '{/keys*}' => '/semi=%3B/dot=./comma=%2C', + } + end + context "Operator ; with value modifiers" do + it_behaves_like 'expands', { + '{;hello:5}' => ';hello=Hello', + '{;list}' => ';list=red,green,blue', + '{;list*}' => ';list=red;list=green;list=blue', + '{;keys}' => ';keys=semi,%3B,dot,.,comma,%2C', + '{;keys*}' => ';semi=%3B;dot=.;comma=%2C', + } + end + context "Operator ? with value modifiers" do + it_behaves_like 'expands', { + '{?var:3}' => '?var=val', + '{?list}' => '?list=red,green,blue', + '{?list*}' => '?list=red&list=green&list=blue', + '{?keys}' => '?keys=semi,%3B,dot,.,comma,%2C', + '{?keys*}' => '?semi=%3B&dot=.&comma=%2C', + } + end + context "Operator & with value modifiers" do + it_behaves_like 'expands', { + '{&var:3}' => '&var=val', + '{&list}' => '&list=red,green,blue', + '{&list*}' => '&list=red&list=green&list=blue', + '{&keys}' => '&keys=semi,%3B,dot,.,comma,%2C', + '{&keys*}' => '&semi=%3B&dot=.&comma=%2C', + } + end +end +describe "Modifiers" do + subject { + { + :var => "value", + :semi => ";", + :year => [1965, 2000, 2012], + :dom => %w(example com) + } + } + context "length" do + it_behaves_like 'expands', { + '{var:3}' => 'val', + '{var:30}' => 'value', + '{var}' => 'value', + '{semi}' => '%3B', + '{semi:2}' => '%3B' + } + end + context "explode" do + it_behaves_like 'expands', { + 'find{?year*}' => 'find?year=1965&year=2000&year=2012', + 'www{.dom*}' => 'www.example.com', + } + end +end +describe "Expansion" do + subject { + { + :count => ["one", "two", "three"], + :dom => ["example", "com"], + :dub => "me/too", + :hello => "Hello World!", + :half => "50%", + :var => "value", + :who => "fred", + :base => "http://example.com/home/", + :path => "/foo/bar", + :list => ["red", "green", "blue"], + :keys => {"semi" => ";","dot" => ".",:comma => ","}, + :v => "6", + :x => "1024", + :y => "768", + :empty => "", + :empty_keys => {}, + :undef => nil + } + } + context "concatenation" do + it_behaves_like 'expands', { + '{count}' => 'one,two,three', + '{count*}' => 'one,two,three', + '{/count}' => '/one,two,three', + '{/count*}' => '/one/two/three', + '{;count}' => ';count=one,two,three', + '{;count*}' => ';count=one;count=two;count=three', + '{?count}' => '?count=one,two,three', + '{?count*}' => '?count=one&count=two&count=three', + '{&count*}' => '&count=one&count=two&count=three' + } + end + context "simple expansion" do + it_behaves_like 'expands', { + '{var}' => 'value', + '{hello}' => 'Hello%20World%21', + '{half}' => '50%25', + 'O{empty}X' => 'OX', + 'O{undef}X' => 'OX', + '{x,y}' => '1024,768', + '{x,hello,y}' => '1024,Hello%20World%21,768', + '?{x,empty}' => '?1024,', + '?{x,undef}' => '?1024', + '?{undef,y}' => '?768', + '{var:3}' => 'val', + '{var:30}' => 'value', + '{list}' => 'red,green,blue', + '{list*}' => 'red,green,blue', + '{keys}' => 'semi,%3B,dot,.,comma,%2C', + '{keys*}' => 'semi=%3B,dot=.,comma=%2C', + } + end + context "reserved expansion (+)" do + it_behaves_like 'expands', { + '{+var}' => 'value', + '{+hello}' => 'Hello%20World!', + '{+half}' => '50%25', + '{base}index' => 'http%3A%2F%2Fexample.com%2Fhome%2Findex', + '{+base}index' => 'http://example.com/home/index', + 'O{+empty}X' => 'OX', + 'O{+undef}X' => 'OX', + '{+path}/here' => '/foo/bar/here', + 'here?ref={+path}' => 'here?ref=/foo/bar', + 'up{+path}{var}/here' => 'up/foo/barvalue/here', + '{+x,hello,y}' => '1024,Hello%20World!,768', + '{+path,x}/here' => '/foo/bar,1024/here', + '{+path:6}/here' => '/foo/b/here', + '{+list}' => 'red,green,blue', + '{+list*}' => 'red,green,blue', + '{+keys}' => 'semi,;,dot,.,comma,,', + '{+keys*}' => 'semi=;,dot=.,comma=,', + } + end + context "fragment expansion (#)" do + it_behaves_like 'expands', { + '{#var}' => '#value', + '{#hello}' => '#Hello%20World!', + '{#half}' => '#50%25', + 'foo{#empty}' => 'foo#', + 'foo{#undef}' => 'foo', + '{#x,hello,y}' => '#1024,Hello%20World!,768', + '{#path,x}/here' => '#/foo/bar,1024/here', + '{#path:6}/here' => '#/foo/b/here', + '{#list}' => '#red,green,blue', + '{#list*}' => '#red,green,blue', + '{#keys}' => '#semi,;,dot,.,comma,,', + '{#keys*}' => '#semi=;,dot=.,comma=,', + } + end + context "label expansion (.)" do + it_behaves_like 'expands', { + '{.who}' => '.fred', + '{.who,who}' => '.fred.fred', + '{.half,who}' => '.50%25.fred', + 'www{.dom*}' => 'www.example.com', + 'X{.var}' => 'X.value', + 'X{.empty}' => 'X.', + 'X{.undef}' => 'X', + 'X{.var:3}' => 'X.val', + 'X{.list}' => 'X.red,green,blue', + 'X{.list*}' => 'X.red.green.blue', + 'X{.keys}' => 'X.semi,%3B,dot,.,comma,%2C', + 'X{.keys*}' => 'X.semi=%3B.dot=..comma=%2C', + 'X{.empty_keys}' => 'X', + 'X{.empty_keys*}' => 'X' + } + end + context "path expansion (/)" do + it_behaves_like 'expands', { + '{/who}' => '/fred', + '{/who,who}' => '/fred/fred', + '{/half,who}' => '/50%25/fred', + '{/who,dub}' => '/fred/me%2Ftoo', + '{/var}' => '/value', + '{/var,empty}' => '/value/', + '{/var,undef}' => '/value', + '{/var,x}/here' => '/value/1024/here', + '{/var:1,var}' => '/v/value', + '{/list}' => '/red,green,blue', + '{/list*}' => '/red/green/blue', + '{/list*,path:4}' => '/red/green/blue/%2Ffoo', + '{/keys}' => '/semi,%3B,dot,.,comma,%2C', + '{/keys*}' => '/semi=%3B/dot=./comma=%2C', + } + end + context "path-style expansion (;)" do + it_behaves_like 'expands', { + '{;who}' => ';who=fred', + '{;half}' => ';half=50%25', + '{;empty}' => ';empty', + '{;v,empty,who}' => ';v=6;empty;who=fred', + '{;v,bar,who}' => ';v=6;who=fred', + '{;x,y}' => ';x=1024;y=768', + '{;x,y,empty}' => ';x=1024;y=768;empty', + '{;x,y,undef}' => ';x=1024;y=768', + '{;hello:5}' => ';hello=Hello', + '{;list}' => ';list=red,green,blue', + '{;list*}' => ';list=red;list=green;list=blue', + '{;keys}' => ';keys=semi,%3B,dot,.,comma,%2C', + '{;keys*}' => ';semi=%3B;dot=.;comma=%2C', + } + end + context "form query expansion (?)" do + it_behaves_like 'expands', { + '{?who}' => '?who=fred', + '{?half}' => '?half=50%25', + '{?x,y}' => '?x=1024&y=768', + '{?x,y,empty}' => '?x=1024&y=768&empty=', + '{?x,y,undef}' => '?x=1024&y=768', + '{?var:3}' => '?var=val', + '{?list}' => '?list=red,green,blue', + '{?list*}' => '?list=red&list=green&list=blue', + '{?keys}' => '?keys=semi,%3B,dot,.,comma,%2C', + '{?keys*}' => '?semi=%3B&dot=.&comma=%2C', + } + end + context "form query expansion (&)" do + it_behaves_like 'expands', { + '{&who}' => '&who=fred', + '{&half}' => '&half=50%25', + '?fixed=yes{&x}' => '?fixed=yes&x=1024', + '{&x,y,empty}' => '&x=1024&y=768&empty=', + '{&x,y,undef}' => '&x=1024&y=768', + '{&var:3}' => '&var=val', + '{&list}' => '&list=red,green,blue', + '{&list*}' => '&list=red&list=green&list=blue', + '{&keys}' => '&keys=semi,%3B,dot,.,comma,%2C', + '{&keys*}' => '&semi=%3B&dot=.&comma=%2C', + } + end + context "non-string key in match data" do + subject {Addressable::Template.new("http://example.com/{one}")} + + it "raises TypeError" do + expect { subject.expand(Object.new => "1") }.to raise_error TypeError + end + end +end + +class ExampleTwoProcessor + def self.restore(name, value) + return value.gsub(/-/, " ") if name == "query" + return value + end + + def self.match(name) + return ".*?" if name == "first" + return ".*" + end + def self.validate(name, value) + return !!(value =~ /^[\w ]+$/) if name == "query" + return true + end + + def self.transform(name, value) + return value.gsub(/ /, "+") if name == "query" + return value + end +end + +class DumbProcessor + def self.match(name) + return ".*?" if name == "first" + end +end + +describe Addressable::Template do + describe 'initialize' do + context 'with a non-string' do + it 'raises a TypeError' do + expect { Addressable::Template.new(nil) }.to raise_error(TypeError) + end + end + end + + describe 'freeze' do + subject { Addressable::Template.new("http://example.com/{first}/{+second}/") } + it 'freezes the template' do + expect(subject.freeze).to be_frozen + end + end + + describe "Matching" do + let(:uri){ + Addressable::URI.parse( + "http://example.com/search/an-example-search-query/" + ) + } + let(:uri2){ + Addressable::URI.parse("http://example.com/a/b/c/") + } + let(:uri3){ + Addressable::URI.parse("http://example.com/;a=1;b=2;c=3;first=foo") + } + let(:uri4){ + Addressable::URI.parse("http://example.com/?a=1&b=2&c=3&first=foo") + } + let(:uri5){ + "http://example.com/foo" + } + context "first uri with ExampleTwoProcessor" do + subject { + Addressable::Template.new( + "http://example.com/search/{query}/" + ).match(uri, ExampleTwoProcessor) + } + its(:variables){ should == ["query"] } + its(:captures){ should == ["an example search query"] } + end + + context "second uri with ExampleTwoProcessor" do + subject { + Addressable::Template.new( + "http://example.com/{first}/{+second}/" + ).match(uri2, ExampleTwoProcessor) + } + its(:variables){ should == ["first", "second"] } + its(:captures){ should == ["a", "b/c"] } + end + + context "second uri with DumbProcessor" do + subject { + Addressable::Template.new( + "http://example.com/{first}/{+second}/" + ).match(uri2, DumbProcessor) + } + its(:variables){ should == ["first", "second"] } + its(:captures){ should == ["a", "b/c"] } + end + + context "second uri" do + subject { + Addressable::Template.new( + "http://example.com/{first}{/second*}/" + ).match(uri2) + } + its(:variables){ should == ["first", "second"] } + its(:captures){ should == ["a", ["b","c"]] } + end + context "third uri" do + subject { + Addressable::Template.new( + "http://example.com/{;hash*,first}" + ).match(uri3) + } + its(:variables){ should == ["hash", "first"] } + its(:captures){ should == [ + {"a" => "1", "b" => "2", "c" => "3", "first" => "foo"}, nil] } + end + # Note that this expansion is impossible to revert deterministically - the + # * operator means first could have been a key of hash or a separate key. + # Semantically, a separate key is more likely, but both are possible. + context "fourth uri" do + subject { + Addressable::Template.new( + "http://example.com/{?hash*,first}" + ).match(uri4) + } + its(:variables){ should == ["hash", "first"] } + its(:captures){ should == [ + {"a" => "1", "b" => "2", "c" => "3", "first"=> "foo"}, nil] } + end + context "fifth uri" do + subject { + Addressable::Template.new( + "http://example.com/{path}{?hash*,first}" + ).match(uri5) + } + its(:variables){ should == ["path", "hash", "first"] } + its(:captures){ should == ["foo", nil, nil] } + end + end + + describe 'match' do + subject { Addressable::Template.new('http://example.com/first/second/') } + context 'when the URI is the same as the template' do + it 'returns the match data itself with an empty mapping' do + uri = Addressable::URI.parse('http://example.com/first/second/') + match_data = subject.match(uri) + expect(match_data).to be_an Addressable::Template::MatchData + expect(match_data.uri).to eq(uri) + expect(match_data.template).to eq(subject) + expect(match_data.mapping).to be_empty + expect(match_data.inspect).to be_an String + end + end + end + + describe "extract" do + let(:template) { + Addressable::Template.new( + "http://{host}{/segments*}/{?one,two,bogus}{#fragment}" + ) + } + let(:uri){ "http://example.com/a/b/c/?one=1&two=2#foo" } + let(:uri2){ "http://example.com/a/b/c/#foo" } + it "should be able to extract with queries" do + expect(template.extract(uri)).to eq({ + "host" => "example.com", + "segments" => %w(a b c), + "one" => "1", + "bogus" => nil, + "two" => "2", + "fragment" => "foo" + }) + end + it "should be able to extract without queries" do + expect(template.extract(uri2)).to eq({ + "host" => "example.com", + "segments" => %w(a b c), + "one" => nil, + "bogus" => nil, + "two" => nil, + "fragment" => "foo" + }) + end + + context "issue #137" do + subject { Addressable::Template.new('/path{?page,per_page}') } + + it "can match empty" do + data = subject.extract("/path") + expect(data["page"]).to eq(nil) + expect(data["per_page"]).to eq(nil) + expect(data.keys.sort).to eq(['page', 'per_page']) + end + + it "can match first var" do + data = subject.extract("/path?page=1") + expect(data["page"]).to eq("1") + expect(data["per_page"]).to eq(nil) + expect(data.keys.sort).to eq(['page', 'per_page']) + end + + it "can match second var" do + data = subject.extract("/path?per_page=1") + expect(data["page"]).to eq(nil) + expect(data["per_page"]).to eq("1") + expect(data.keys.sort).to eq(['page', 'per_page']) + end + + it "can match both vars" do + data = subject.extract("/path?page=2&per_page=1") + expect(data["page"]).to eq("2") + expect(data["per_page"]).to eq("1") + expect(data.keys.sort).to eq(['page', 'per_page']) + end + end + end + + describe "Partial expand with symbols" do + context "partial_expand with two simple values" do + subject { + Addressable::Template.new("http://example.com/{one}/{two}/") + } + it "builds a new pattern" do + expect(subject.partial_expand(:one => "1").pattern).to eq( + "http://example.com/1/{two}/" + ) + end + end + context "partial_expand query with missing param in middle" do + subject { + Addressable::Template.new("http://example.com/{?one,two,three}/") + } + it "builds a new pattern" do + expect(subject.partial_expand(:one => "1", :three => "3").pattern).to eq( + "http://example.com/?one=1{&two}&three=3/" + ) + end + end + context "partial_expand form style query with missing param at beginning" do + subject { + Addressable::Template.new("http://example.com/{?one,two}/") + } + it "builds a new pattern" do + expect(subject.partial_expand(:two => "2").pattern).to eq( + "http://example.com/?two=2{&one}/" + ) + end + end + context "issue #307 - partial_expand form query with nil params" do + subject do + Addressable::Template.new("http://example.com/{?one,two,three}/") + end + it "builds a new pattern with two=nil" do + expect(subject.partial_expand(two: nil).pattern).to eq( + "http://example.com/{?one}{&three}/" + ) + end + it "builds a new pattern with one=nil and two=nil" do + expect(subject.partial_expand(one: nil, two: nil).pattern).to eq( + "http://example.com/{?three}/" + ) + end + it "builds a new pattern with one=1 and two=nil" do + expect(subject.partial_expand(one: 1, two: nil).pattern).to eq( + "http://example.com/?one=1{&three}/" + ) + end + it "builds a new pattern with one=nil and two=2" do + expect(subject.partial_expand(one: nil, two: 2).pattern).to eq( + "http://example.com/?two=2{&three}/" + ) + end + it "builds a new pattern with one=nil" do + expect(subject.partial_expand(one: nil).pattern).to eq( + "http://example.com/{?two}{&three}/" + ) + end + end + context "partial_expand with query string" do + subject { + Addressable::Template.new("http://example.com/{?two,one}/") + } + it "builds a new pattern" do + expect(subject.partial_expand(:one => "1").pattern).to eq( + "http://example.com/?one=1{&two}/" + ) + end + end + context "partial_expand with path operator" do + subject { + Addressable::Template.new("http://example.com{/one,two}/") + } + it "builds a new pattern" do + expect(subject.partial_expand(:one => "1").pattern).to eq( + "http://example.com/1{/two}/" + ) + end + end + context "partial expand with unicode values" do + subject do + Addressable::Template.new("http://example.com/{resource}/{query}/") + end + it "normalizes unicode by default" do + template = subject.partial_expand("query" => "Cafe\u0301") + expect(template.pattern).to eq( + "http://example.com/{resource}/Caf%C3%A9/" + ) + end + + it "normalizes as unicode even with wrong encoding specified" do + template = subject.partial_expand("query" => "Cafe\u0301".b) + expect(template.pattern).to eq( + "http://example.com/{resource}/Caf%C3%A9/" + ) + end + + it "raises on invalid unicode input" do + expect { + subject.partial_expand("query" => "M\xE9thode".b) + }.to raise_error(ArgumentError, "invalid byte sequence in UTF-8") + end + + it "does not normalize unicode when byte semantics requested" do + template = subject.partial_expand({"query" => "Cafe\u0301"}, nil, false) + expect(template.pattern).to eq( + "http://example.com/{resource}/Cafe%CC%81/" + ) + end + end + end + describe "Partial expand with strings" do + context "partial_expand with two simple values" do + subject { + Addressable::Template.new("http://example.com/{one}/{two}/") + } + it "builds a new pattern" do + expect(subject.partial_expand("one" => "1").pattern).to eq( + "http://example.com/1/{two}/" + ) + end + end + context "partial_expand query with missing param in middle" do + subject { + Addressable::Template.new("http://example.com/{?one,two,three}/") + } + it "builds a new pattern" do + expect(subject.partial_expand("one" => "1", "three" => "3").pattern).to eq( + "http://example.com/?one=1{&two}&three=3/" + ) + end + end + context "partial_expand with query string" do + subject { + Addressable::Template.new("http://example.com/{?two,one}/") + } + it "builds a new pattern" do + expect(subject.partial_expand("one" => "1").pattern).to eq( + "http://example.com/?one=1{&two}/" + ) + end + end + context "partial_expand with path operator" do + subject { + Addressable::Template.new("http://example.com{/one,two}/") + } + it "builds a new pattern" do + expect(subject.partial_expand("one" => "1").pattern).to eq( + "http://example.com/1{/two}/" + ) + end + end + end + describe "Expand" do + context "expand with unicode values" do + subject do + Addressable::Template.new("http://example.com/search/{query}/") + end + it "normalizes unicode by default" do + uri = subject.expand("query" => "Cafe\u0301").to_str + expect(uri).to eq("http://example.com/search/Caf%C3%A9/") + end + + it "normalizes as unicode even with wrong encoding specified" do + uri = subject.expand("query" => "Cafe\u0301".b).to_str + expect(uri).to eq("http://example.com/search/Caf%C3%A9/") + end + + it "raises on invalid unicode input" do + expect { + subject.expand("query" => "M\xE9thode".b).to_str + }.to raise_error(ArgumentError, "invalid byte sequence in UTF-8") + end + + it "does not normalize unicode when byte semantics requested" do + uri = subject.expand({ "query" => "Cafe\u0301" }, nil, false).to_str + expect(uri).to eq("http://example.com/search/Cafe%CC%81/") + end + end + context "expand with a processor" do + subject { + Addressable::Template.new("http://example.com/search/{query}/") + } + it "processes spaces" do + expect(subject.expand({"query" => "an example search query"}, + ExampleTwoProcessor).to_str).to eq( + "http://example.com/search/an+example+search+query/" + ) + end + it "validates" do + expect{ + subject.expand({"query" => "Bogus!"}, + ExampleTwoProcessor).to_str + }.to raise_error(Addressable::Template::InvalidTemplateValueError) + end + end + context "partial_expand query with missing param in middle" do + subject { + Addressable::Template.new("http://example.com/{?one,two,three}/") + } + it "builds a new pattern" do + expect(subject.partial_expand("one" => "1", "three" => "3").pattern).to eq( + "http://example.com/?one=1{&two}&three=3/" + ) + end + end + context "partial_expand with query string" do + subject { + Addressable::Template.new("http://example.com/{?two,one}/") + } + it "builds a new pattern" do + expect(subject.partial_expand("one" => "1").pattern).to eq( + "http://example.com/?one=1{&two}/" + ) + end + end + context "partial_expand with path operator" do + subject { + Addressable::Template.new("http://example.com{/one,two}/") + } + it "builds a new pattern" do + expect(subject.partial_expand("one" => "1").pattern).to eq( + "http://example.com/1{/two}/" + ) + end + end + end + context "Matching with operators" do + describe "Level 1:" do + subject { Addressable::Template.new("foo{foo}/{bar}baz") } + it "can match" do + data = subject.match("foofoo/bananabaz") + expect(data.mapping["foo"]).to eq("foo") + expect(data.mapping["bar"]).to eq("banana") + end + it "can fail" do + expect(subject.match("bar/foo")).to be_nil + expect(subject.match("foobaz")).to be_nil + end + it "can match empty" do + data = subject.match("foo/baz") + expect(data.mapping["foo"]).to eq(nil) + expect(data.mapping["bar"]).to eq(nil) + end + it "lists vars" do + expect(subject.variables).to eq(["foo", "bar"]) + end + end + + describe "Level 2:" do + subject { Addressable::Template.new("foo{+foo}{#bar}baz") } + it "can match" do + data = subject.match("foo/test/banana#bazbaz") + expect(data.mapping["foo"]).to eq("/test/banana") + expect(data.mapping["bar"]).to eq("baz") + end + it "can match empty level 2 #" do + data = subject.match("foo/test/bananabaz") + expect(data.mapping["foo"]).to eq("/test/banana") + expect(data.mapping["bar"]).to eq(nil) + data = subject.match("foo/test/banana#baz") + expect(data.mapping["foo"]).to eq("/test/banana") + expect(data.mapping["bar"]).to eq("") + end + it "can match empty level 2 +" do + data = subject.match("foobaz") + expect(data.mapping["foo"]).to eq(nil) + expect(data.mapping["bar"]).to eq(nil) + data = subject.match("foo#barbaz") + expect(data.mapping["foo"]).to eq(nil) + expect(data.mapping["bar"]).to eq("bar") + end + it "lists vars" do + expect(subject.variables).to eq(["foo", "bar"]) + end + end + + describe "Level 3:" do + context "no operator" do + subject { Addressable::Template.new("foo{foo,bar}baz") } + it "can match" do + data = subject.match("foofoo,barbaz") + expect(data.mapping["foo"]).to eq("foo") + expect(data.mapping["bar"]).to eq("bar") + end + it "lists vars" do + expect(subject.variables).to eq(["foo", "bar"]) + end + end + context "+ operator" do + subject { Addressable::Template.new("foo{+foo,bar}baz") } + it "can match" do + data = subject.match("foofoo/bar,barbaz") + expect(data.mapping["bar"]).to eq("foo/bar,bar") + expect(data.mapping["foo"]).to eq("") + end + it "lists vars" do + expect(subject.variables).to eq(["foo", "bar"]) + end + end + context ". operator" do + subject { Addressable::Template.new("foo{.foo,bar}baz") } + it "can match" do + data = subject.match("foo.foo.barbaz") + expect(data.mapping["foo"]).to eq("foo") + expect(data.mapping["bar"]).to eq("bar") + end + it "lists vars" do + expect(subject.variables).to eq(["foo", "bar"]) + end + end + context "/ operator" do + subject { Addressable::Template.new("foo{/foo,bar}baz") } + it "can match" do + data = subject.match("foo/foo/barbaz") + expect(data.mapping["foo"]).to eq("foo") + expect(data.mapping["bar"]).to eq("bar") + end + it "lists vars" do + expect(subject.variables).to eq(["foo", "bar"]) + end + end + context "; operator" do + subject { Addressable::Template.new("foo{;foo,bar,baz}baz") } + it "can match" do + data = subject.match("foo;foo=bar%20baz;bar=foo;bazbaz") + expect(data.mapping["foo"]).to eq("bar baz") + expect(data.mapping["bar"]).to eq("foo") + expect(data.mapping["baz"]).to eq("") + end + it "lists vars" do + expect(subject.variables).to eq(%w(foo bar baz)) + end + end + context "? operator" do + context "test" do + subject { Addressable::Template.new("foo{?foo,bar}baz") } + it "can match" do + data = subject.match("foo?foo=bar%20baz&bar=foobaz") + expect(data.mapping["foo"]).to eq("bar baz") + expect(data.mapping["bar"]).to eq("foo") + end + it "lists vars" do + expect(subject.variables).to eq(%w(foo bar)) + end + end + + context "issue #137" do + subject { Addressable::Template.new('/path{?page,per_page}') } + + it "can match empty" do + data = subject.match("/path") + expect(data.mapping["page"]).to eq(nil) + expect(data.mapping["per_page"]).to eq(nil) + expect(data.mapping.keys.sort).to eq(['page', 'per_page']) + end + + it "can match first var" do + data = subject.match("/path?page=1") + expect(data.mapping["page"]).to eq("1") + expect(data.mapping["per_page"]).to eq(nil) + expect(data.mapping.keys.sort).to eq(['page', 'per_page']) + end + + it "can match second var" do + data = subject.match("/path?per_page=1") + expect(data.mapping["page"]).to eq(nil) + expect(data.mapping["per_page"]).to eq("1") + expect(data.mapping.keys.sort).to eq(['page', 'per_page']) + end + + it "can match both vars" do + data = subject.match("/path?page=2&per_page=1") + expect(data.mapping["page"]).to eq("2") + expect(data.mapping["per_page"]).to eq("1") + expect(data.mapping.keys.sort).to eq(['page', 'per_page']) + end + end + + context "issue #71" do + subject { Addressable::Template.new("http://cyberscore.dev/api/users{?username}") } + it "can match" do + data = subject.match("http://cyberscore.dev/api/users?username=foobaz") + expect(data.mapping["username"]).to eq("foobaz") + end + it "lists vars" do + expect(subject.variables).to eq(%w(username)) + expect(subject.keys).to eq(%w(username)) + end + end + end + context "& operator" do + subject { Addressable::Template.new("foo{&foo,bar}baz") } + it "can match" do + data = subject.match("foo&foo=bar%20baz&bar=foobaz") + expect(data.mapping["foo"]).to eq("bar baz") + expect(data.mapping["bar"]).to eq("foo") + end + it "lists vars" do + expect(subject.variables).to eq(%w(foo bar)) + end + end + end + end + + context "support regexes:" do + context "EXPRESSION" do + subject { Addressable::Template::EXPRESSION } + it "should be able to match an expression" do + expect(subject).to match("{foo}") + expect(subject).to match("{foo,9}") + expect(subject).to match("{foo.bar,baz}") + expect(subject).to match("{+foo.bar,baz}") + expect(subject).to match("{foo,foo%20bar}") + expect(subject).to match("{#foo:20,baz*}") + expect(subject).to match("stuff{#foo:20,baz*}things") + end + it "should fail on non vars" do + expect(subject).not_to match("!{foo") + expect(subject).not_to match("{foo.bar.}") + expect(subject).not_to match("!{}") + end + end + context "VARNAME" do + subject { Addressable::Template::VARNAME } + it "should be able to match a variable" do + expect(subject).to match("foo") + expect(subject).to match("9") + expect(subject).to match("foo.bar") + expect(subject).to match("foo_bar") + expect(subject).to match("foo_bar.baz") + expect(subject).to match("foo%20bar") + expect(subject).to match("foo%20bar.baz") + end + it "should fail on non vars" do + expect(subject).not_to match("!foo") + expect(subject).not_to match("foo.bar.") + expect(subject).not_to match("foo%2%00bar") + expect(subject).not_to match("foo_ba%r") + expect(subject).not_to match("foo_bar*") + expect(subject).not_to match("foo_bar:20") + end + + it 'should parse in a reasonable time' do + expect do + Timeout.timeout(0.1) do + expect(subject).not_to match("0"*25 + "!") + end + end.not_to raise_error + end + end + context "VARIABLE_LIST" do + subject { Addressable::Template::VARIABLE_LIST } + it "should be able to match a variable list" do + expect(subject).to match("foo,bar") + expect(subject).to match("foo") + expect(subject).to match("foo,bar*,baz") + expect(subject).to match("foo.bar,bar_baz*,baz:12") + end + it "should fail on non vars" do + expect(subject).not_to match(",foo,bar*,baz") + expect(subject).not_to match("foo,*bar,baz") + expect(subject).not_to match("foo,,bar*,baz") + end + end + context "VARSPEC" do + subject { Addressable::Template::VARSPEC } + it "should be able to match a variable with modifier" do + expect(subject).to match("9:8") + expect(subject).to match("foo.bar*") + expect(subject).to match("foo_bar:12") + expect(subject).to match("foo_bar.baz*") + expect(subject).to match("foo%20bar:12") + expect(subject).to match("foo%20bar.baz*") + end + it "should fail on non vars" do + expect(subject).not_to match("!foo") + expect(subject).not_to match("*foo") + expect(subject).not_to match("fo*o") + expect(subject).not_to match("fo:o") + expect(subject).not_to match("foo:") + end + end + end +end + +describe Addressable::Template::MatchData do + let(:template) { Addressable::Template.new('{foo}/{bar}') } + subject(:its) { template.match('ab/cd') } + its(:uri) { should == Addressable::URI.parse('ab/cd') } + its(:template) { should == template } + its(:mapping) { should == { 'foo' => 'ab', 'bar' => 'cd' } } + its(:variables) { should == ['foo', 'bar'] } + its(:keys) { should == ['foo', 'bar'] } + its(:names) { should == ['foo', 'bar'] } + its(:values) { should == ['ab', 'cd'] } + its(:captures) { should == ['ab', 'cd'] } + its(:to_a) { should == ['ab/cd', 'ab', 'cd'] } + its(:to_s) { should == 'ab/cd' } + its(:string) { should == its.to_s } + its(:pre_match) { should == "" } + its(:post_match) { should == "" } + + describe 'values_at' do + it 'returns an array with the values' do + expect(its.values_at(0, 2)).to eq(['ab/cd', 'cd']) + end + it 'allows mixing integer an string keys' do + expect(its.values_at('foo', 1)).to eq(['ab', 'ab']) + end + it 'accepts unknown keys' do + expect(its.values_at('baz', 'foo')).to eq([nil, 'ab']) + end + end + + describe '[]' do + context 'string key' do + it 'returns the corresponding capture' do + expect(its['foo']).to eq('ab') + expect(its['bar']).to eq('cd') + end + it 'returns nil for unknown keys' do + expect(its['baz']).to be_nil + end + end + context 'symbol key' do + it 'returns the corresponding capture' do + expect(its[:foo]).to eq('ab') + expect(its[:bar]).to eq('cd') + end + it 'returns nil for unknown keys' do + expect(its[:baz]).to be_nil + end + end + context 'integer key' do + it 'returns the full URI for index 0' do + expect(its[0]).to eq('ab/cd') + end + it 'returns the corresponding capture' do + expect(its[1]).to eq('ab') + expect(its[2]).to eq('cd') + end + it 'returns nil for unknown keys' do + expect(its[3]).to be_nil + end + end + context 'other key' do + it 'raises an exception' do + expect { its[Object.new] }.to raise_error(TypeError) + end + end + context 'with length' do + it 'returns an array starting at index with given length' do + expect(its[0, 2]).to eq(['ab/cd', 'ab']) + expect(its[2, 1]).to eq(['cd']) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/spec/addressable/uri_spec.rb b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/spec/addressable/uri_spec.rb new file mode 100644 index 00000000..26ee923d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/spec/addressable/uri_spec.rb @@ -0,0 +1,6840 @@ +# frozen_string_literal: true + +# Copyright (C) Bob Aman +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +require "spec_helper" + +require "addressable/uri" +require "uri" +require "ipaddr" +require "yaml" + +if !"".respond_to?("force_encoding") + class String + def force_encoding(encoding) + @encoding = encoding + end + + def encoding + @encoding ||= Encoding::ASCII_8BIT + end + end + + class Encoding + def initialize(name) + @name = name + end + + def to_s + return @name + end + + UTF_8 = Encoding.new("UTF-8") + ASCII_8BIT = Encoding.new("US-ASCII") + end +end + +module Fake + module URI + class HTTP + def initialize(uri) + @uri = uri + end + + def to_s + return @uri.to_s + end + + alias :to_str :to_s + end + end +end + +describe Addressable::URI, "when created with a non-numeric port number" do + it "should raise an error" do + expect do + Addressable::URI.new(:port => "bogus") + end.to raise_error(Addressable::URI::InvalidURIError) + end +end + +describe Addressable::URI, "when created with a invalid encoded port number" do + it "should raise an error" do + expect do + Addressable::URI.new(:port => "%eb") + end.to raise_error(Addressable::URI::InvalidURIError) + end +end + +describe Addressable::URI, "when created with a non-string scheme" do + it "should raise an error" do + expect do + Addressable::URI.new(:scheme => :bogus) + end.to raise_error(TypeError) + end +end + +describe Addressable::URI, "when created with a non-string user" do + it "should raise an error" do + expect do + Addressable::URI.new(:user => :bogus) + end.to raise_error(TypeError) + end +end + +describe Addressable::URI, "when created with a non-string password" do + it "should raise an error" do + expect do + Addressable::URI.new(:password => :bogus) + end.to raise_error(TypeError) + end +end + +describe Addressable::URI, "when created with a non-string userinfo" do + it "should raise an error" do + expect do + Addressable::URI.new(:userinfo => :bogus) + end.to raise_error(TypeError) + end +end + +describe Addressable::URI, "when created with a non-string host" do + it "should raise an error" do + expect do + Addressable::URI.new(:host => :bogus) + end.to raise_error(TypeError) + end +end + +describe Addressable::URI, "when created with a non-string authority" do + it "should raise an error" do + expect do + Addressable::URI.new(:authority => :bogus) + end.to raise_error(TypeError) + end +end + +describe Addressable::URI, "when created with a non-string path" do + it "should raise an error" do + expect do + Addressable::URI.new(:path => :bogus) + end.to raise_error(TypeError) + end +end + +describe Addressable::URI, "when created with a non-string query" do + it "should raise an error" do + expect do + Addressable::URI.new(:query => :bogus) + end.to raise_error(TypeError) + end +end + +describe Addressable::URI, "when created with a non-string fragment" do + it "should raise an error" do + expect do + Addressable::URI.new(:fragment => :bogus) + end.to raise_error(TypeError) + end +end + +describe Addressable::URI, "when created with a scheme but no hierarchical " + + "segment" do + it "should raise an error" do + expect do + Addressable::URI.parse("http:") + end.to raise_error(Addressable::URI::InvalidURIError) + end +end + +describe Addressable::URI, "quote handling" do + describe 'in host name' do + it "should raise an error for single quote" do + expect do + Addressable::URI.parse("http://local\"host/") + end.to raise_error(Addressable::URI::InvalidURIError) + end + end +end + +describe Addressable::URI, "newline normalization" do + it "should not accept newlines in scheme" do + expect do + Addressable::URI.parse("ht%0atp://localhost/") + end.to raise_error(Addressable::URI::InvalidURIError) + end + + it "should not unescape newline in path" do + uri = Addressable::URI.parse("http://localhost/%0a").normalize + expect(uri.to_s).to eq("http://localhost/%0A") + end + + it "should not unescape newline in hostname" do + uri = Addressable::URI.parse("http://local%0ahost/").normalize + expect(uri.to_s).to eq("http://local%0Ahost/") + end + + it "should not unescape newline in username" do + uri = Addressable::URI.parse("http://foo%0abar@localhost/").normalize + expect(uri.to_s).to eq("http://foo%0Abar@localhost/") + end + + it "should not unescape newline in username" do + uri = Addressable::URI.parse("http://example:foo%0abar@example/").normalize + expect(uri.to_s).to eq("http://example:foo%0Abar@example/") + end + + it "should not accept newline in hostname" do + uri = Addressable::URI.parse("http://localhost/") + expect do + uri.host = "local\nhost" + end.to raise_error(Addressable::URI::InvalidURIError) + end +end + +describe Addressable::URI, "when created with ambiguous path" do + it "should raise an error" do + expect do + Addressable::URI.parse("::http") + end.to raise_error(Addressable::URI::InvalidURIError) + end +end + +describe Addressable::URI, "when created with an invalid host" do + it "should raise an error" do + expect do + Addressable::URI.new(:host => "") + end.to raise_error(Addressable::URI::InvalidURIError) + end +end + +describe Addressable::URI, "when created with a host consisting of " + + "sub-delims characters" do + it "should not raise an error" do + expect do + Addressable::URI.new( + :host => Addressable::URI::CharacterClasses::SUB_DELIMS.gsub(/\\/, '') + ) + end.not_to raise_error + end +end + +describe Addressable::URI, "when created with a host consisting of " + + "unreserved characters" do + it "should not raise an error" do + expect do + Addressable::URI.new( + :host => Addressable::URI::CharacterClasses::UNRESERVED.gsub(/\\/, '') + ) + end.not_to raise_error + end +end + +describe Addressable::URI, "when created from nil components" do + before do + @uri = Addressable::URI.new + end + + it "should have a nil site value" do + expect(@uri.site).to eq(nil) + end + + it "should have an empty path" do + expect(@uri.path).to eq("") + end + + it "should be an empty uri" do + expect(@uri.to_s).to eq("") + end + + it "should have a nil default port" do + expect(@uri.default_port).to eq(nil) + end + + it "should be empty" do + expect(@uri).to be_empty + end + + it "should raise an error if the scheme is set to whitespace" do + expect do + @uri.scheme = "\t \n" + end.to raise_error(Addressable::URI::InvalidURIError, /'\t \n'/) + end + + it "should raise an error if the scheme is set to all digits" do + expect do + @uri.scheme = "123" + end.to raise_error(Addressable::URI::InvalidURIError, /'123'/) + end + + it "should raise an error if the scheme begins with a digit" do + expect do + @uri.scheme = "1scheme" + end.to raise_error(Addressable::URI::InvalidURIError, /'1scheme'/) + end + + it "should raise an error if the scheme begins with a plus" do + expect do + @uri.scheme = "+scheme" + end.to raise_error(Addressable::URI::InvalidURIError, /'\+scheme'/) + end + + it "should raise an error if the scheme begins with a dot" do + expect do + @uri.scheme = ".scheme" + end.to raise_error(Addressable::URI::InvalidURIError, /'\.scheme'/) + end + + it "should raise an error if the scheme begins with a dash" do + expect do + @uri.scheme = "-scheme" + end.to raise_error(Addressable::URI::InvalidURIError, /'-scheme'/) + end + + it "should raise an error if the scheme contains an illegal character" do + expect do + @uri.scheme = "scheme!" + end.to raise_error(Addressable::URI::InvalidURIError, /'scheme!'/) + end + + it "should raise an error if the scheme contains whitespace" do + expect do + @uri.scheme = "sch eme" + end.to raise_error(Addressable::URI::InvalidURIError, /'sch eme'/) + end + + it "should raise an error if the scheme contains a newline" do + expect do + @uri.scheme = "sch\neme" + end.to raise_error(Addressable::URI::InvalidURIError) + end + + it "should raise an error if set into an invalid state" do + expect do + @uri.user = "user" + end.to raise_error(Addressable::URI::InvalidURIError) + end + + it "should raise an error if set into an invalid state" do + expect do + @uri.password = "pass" + end.to raise_error(Addressable::URI::InvalidURIError) + end + + it "should raise an error if set into an invalid state" do + expect do + @uri.scheme = "http" + @uri.fragment = "fragment" + end.to raise_error(Addressable::URI::InvalidURIError) + end + + it "should raise an error if set into an invalid state" do + expect do + @uri.fragment = "fragment" + @uri.scheme = "http" + end.to raise_error(Addressable::URI::InvalidURIError) + end +end + +describe Addressable::URI, "when initialized from individual components" do + before do + @uri = Addressable::URI.new( + :scheme => "http", + :user => "user", + :password => "password", + :host => "example.com", + :port => 8080, + :path => "/path", + :query => "query=value", + :fragment => "fragment" + ) + end + + it "returns 'http' for #scheme" do + expect(@uri.scheme).to eq("http") + end + + it "returns 'http' for #normalized_scheme" do + expect(@uri.normalized_scheme).to eq("http") + end + + it "returns 'user' for #user" do + expect(@uri.user).to eq("user") + end + + it "returns 'user' for #normalized_user" do + expect(@uri.normalized_user).to eq("user") + end + + it "returns 'password' for #password" do + expect(@uri.password).to eq("password") + end + + it "returns 'password' for #normalized_password" do + expect(@uri.normalized_password).to eq("password") + end + + it "returns 'user:password' for #userinfo" do + expect(@uri.userinfo).to eq("user:password") + end + + it "returns 'user:password' for #normalized_userinfo" do + expect(@uri.normalized_userinfo).to eq("user:password") + end + + it "returns 'example.com' for #host" do + expect(@uri.host).to eq("example.com") + end + + it "returns 'example.com' for #normalized_host" do + expect(@uri.normalized_host).to eq("example.com") + end + + it "returns 'com' for #tld" do + expect(@uri.tld).to eq("com") + end + + it "returns 'user:password@example.com:8080' for #authority" do + expect(@uri.authority).to eq("user:password@example.com:8080") + end + + it "returns 'user:password@example.com:8080' for #normalized_authority" do + expect(@uri.normalized_authority).to eq("user:password@example.com:8080") + end + + it "returns 8080 for #port" do + expect(@uri.port).to eq(8080) + end + + it "returns 8080 for #normalized_port" do + expect(@uri.normalized_port).to eq(8080) + end + + it "returns 80 for #default_port" do + expect(@uri.default_port).to eq(80) + end + + it "returns 'http://user:password@example.com:8080' for #site" do + expect(@uri.site).to eq("http://user:password@example.com:8080") + end + + it "returns 'http://user:password@example.com:8080' for #normalized_site" do + expect(@uri.normalized_site).to eq("http://user:password@example.com:8080") + end + + it "returns '/path' for #path" do + expect(@uri.path).to eq("/path") + end + + it "returns '/path' for #normalized_path" do + expect(@uri.normalized_path).to eq("/path") + end + + it "returns 'query=value' for #query" do + expect(@uri.query).to eq("query=value") + end + + it "returns 'query=value' for #normalized_query" do + expect(@uri.normalized_query).to eq("query=value") + end + + it "returns 'fragment' for #fragment" do + expect(@uri.fragment).to eq("fragment") + end + + it "returns 'fragment' for #normalized_fragment" do + expect(@uri.normalized_fragment).to eq("fragment") + end + + it "returns #hash" do + expect(@uri.hash).not_to be nil + end + + it "returns #to_s" do + expect(@uri.to_s).to eq( + "http://user:password@example.com:8080/path?query=value#fragment" + ) + end + + it "should not be empty" do + expect(@uri).not_to be_empty + end + + it "should not be frozen" do + expect(@uri).not_to be_frozen + end + + it "should allow destructive operations" do + expect { @uri.normalize! }.not_to raise_error + end +end + +describe Addressable::URI, "when initialized from " + + "frozen individual components" do + before do + @uri = Addressable::URI.new( + :scheme => "http".freeze, + :user => "user".freeze, + :password => "password".freeze, + :host => "example.com".freeze, + :port => "8080".freeze, + :path => "/path".freeze, + :query => "query=value".freeze, + :fragment => "fragment".freeze + ) + end + + it "returns 'http' for #scheme" do + expect(@uri.scheme).to eq("http") + end + + it "returns 'http' for #normalized_scheme" do + expect(@uri.normalized_scheme).to eq("http") + end + + it "returns 'user' for #user" do + expect(@uri.user).to eq("user") + end + + it "returns 'user' for #normalized_user" do + expect(@uri.normalized_user).to eq("user") + end + + it "returns 'password' for #password" do + expect(@uri.password).to eq("password") + end + + it "returns 'password' for #normalized_password" do + expect(@uri.normalized_password).to eq("password") + end + + it "returns 'user:password' for #userinfo" do + expect(@uri.userinfo).to eq("user:password") + end + + it "returns 'user:password' for #normalized_userinfo" do + expect(@uri.normalized_userinfo).to eq("user:password") + end + + it "returns 'example.com' for #host" do + expect(@uri.host).to eq("example.com") + end + + it "returns 'example.com' for #normalized_host" do + expect(@uri.normalized_host).to eq("example.com") + end + + it "returns 'user:password@example.com:8080' for #authority" do + expect(@uri.authority).to eq("user:password@example.com:8080") + end + + it "returns 'user:password@example.com:8080' for #normalized_authority" do + expect(@uri.normalized_authority).to eq("user:password@example.com:8080") + end + + it "returns 8080 for #port" do + expect(@uri.port).to eq(8080) + end + + it "returns 8080 for #normalized_port" do + expect(@uri.normalized_port).to eq(8080) + end + + it "returns 80 for #default_port" do + expect(@uri.default_port).to eq(80) + end + + it "returns 'http://user:password@example.com:8080' for #site" do + expect(@uri.site).to eq("http://user:password@example.com:8080") + end + + it "returns 'http://user:password@example.com:8080' for #normalized_site" do + expect(@uri.normalized_site).to eq("http://user:password@example.com:8080") + end + + it "returns '/path' for #path" do + expect(@uri.path).to eq("/path") + end + + it "returns '/path' for #normalized_path" do + expect(@uri.normalized_path).to eq("/path") + end + + it "returns 'query=value' for #query" do + expect(@uri.query).to eq("query=value") + end + + it "returns 'query=value' for #normalized_query" do + expect(@uri.normalized_query).to eq("query=value") + end + + it "returns 'fragment' for #fragment" do + expect(@uri.fragment).to eq("fragment") + end + + it "returns 'fragment' for #normalized_fragment" do + expect(@uri.normalized_fragment).to eq("fragment") + end + + it "returns #hash" do + expect(@uri.hash).not_to be nil + end + + it "returns #to_s" do + expect(@uri.to_s).to eq( + "http://user:password@example.com:8080/path?query=value#fragment" + ) + end + + it "should not be empty" do + expect(@uri).not_to be_empty + end + + it "should not be frozen" do + expect(@uri).not_to be_frozen + end + + it "should allow destructive operations" do + expect { @uri.normalize! }.not_to raise_error + end +end + +describe Addressable::URI, "when parsed from a frozen string" do + before do + @uri = Addressable::URI.parse( + "http://user:password@example.com:8080/path?query=value#fragment".freeze + ) + end + + it "returns 'http' for #scheme" do + expect(@uri.scheme).to eq("http") + end + + it "returns 'http' for #normalized_scheme" do + expect(@uri.normalized_scheme).to eq("http") + end + + it "returns 'user' for #user" do + expect(@uri.user).to eq("user") + end + + it "returns 'user' for #normalized_user" do + expect(@uri.normalized_user).to eq("user") + end + + it "returns 'password' for #password" do + expect(@uri.password).to eq("password") + end + + it "returns 'password' for #normalized_password" do + expect(@uri.normalized_password).to eq("password") + end + + it "returns 'user:password' for #userinfo" do + expect(@uri.userinfo).to eq("user:password") + end + + it "returns 'user:password' for #normalized_userinfo" do + expect(@uri.normalized_userinfo).to eq("user:password") + end + + it "returns 'example.com' for #host" do + expect(@uri.host).to eq("example.com") + end + + it "returns 'example.com' for #normalized_host" do + expect(@uri.normalized_host).to eq("example.com") + end + + it "returns 'user:password@example.com:8080' for #authority" do + expect(@uri.authority).to eq("user:password@example.com:8080") + end + + it "returns 'user:password@example.com:8080' for #normalized_authority" do + expect(@uri.normalized_authority).to eq("user:password@example.com:8080") + end + + it "returns 8080 for #port" do + expect(@uri.port).to eq(8080) + end + + it "returns 8080 for #normalized_port" do + expect(@uri.normalized_port).to eq(8080) + end + + it "returns 80 for #default_port" do + expect(@uri.default_port).to eq(80) + end + + it "returns 'http://user:password@example.com:8080' for #site" do + expect(@uri.site).to eq("http://user:password@example.com:8080") + end + + it "returns 'http://user:password@example.com:8080' for #normalized_site" do + expect(@uri.normalized_site).to eq("http://user:password@example.com:8080") + end + + it "returns '/path' for #path" do + expect(@uri.path).to eq("/path") + end + + it "returns '/path' for #normalized_path" do + expect(@uri.normalized_path).to eq("/path") + end + + it "returns 'query=value' for #query" do + expect(@uri.query).to eq("query=value") + end + + it "returns 'query=value' for #normalized_query" do + expect(@uri.normalized_query).to eq("query=value") + end + + it "returns 'fragment' for #fragment" do + expect(@uri.fragment).to eq("fragment") + end + + it "returns 'fragment' for #normalized_fragment" do + expect(@uri.normalized_fragment).to eq("fragment") + end + + it "returns #hash" do + expect(@uri.hash).not_to be nil + end + + it "returns #to_s" do + expect(@uri.to_s).to eq( + "http://user:password@example.com:8080/path?query=value#fragment" + ) + end + + it "should not be empty" do + expect(@uri).not_to be_empty + end + + it "should not be frozen" do + expect(@uri).not_to be_frozen + end + + it "should allow destructive operations" do + expect { @uri.normalize! }.not_to raise_error + end +end + +describe Addressable::URI, "when frozen" do + before do + @uri = Addressable::URI.new.freeze + end + + it "returns nil for #scheme" do + expect(@uri.scheme).to eq(nil) + end + + it "returns nil for #normalized_scheme" do + expect(@uri.normalized_scheme).to eq(nil) + end + + it "returns nil for #user" do + expect(@uri.user).to eq(nil) + end + + it "returns nil for #normalized_user" do + expect(@uri.normalized_user).to eq(nil) + end + + it "returns nil for #password" do + expect(@uri.password).to eq(nil) + end + + it "returns nil for #normalized_password" do + expect(@uri.normalized_password).to eq(nil) + end + + it "returns nil for #userinfo" do + expect(@uri.userinfo).to eq(nil) + end + + it "returns nil for #normalized_userinfo" do + expect(@uri.normalized_userinfo).to eq(nil) + end + + it "returns nil for #host" do + expect(@uri.host).to eq(nil) + end + + it "returns nil for #normalized_host" do + expect(@uri.normalized_host).to eq(nil) + end + + it "returns nil for #authority" do + expect(@uri.authority).to eq(nil) + end + + it "returns nil for #normalized_authority" do + expect(@uri.normalized_authority).to eq(nil) + end + + it "returns nil for #port" do + expect(@uri.port).to eq(nil) + end + + it "returns nil for #normalized_port" do + expect(@uri.normalized_port).to eq(nil) + end + + it "returns nil for #default_port" do + expect(@uri.default_port).to eq(nil) + end + + it "returns nil for #site" do + expect(@uri.site).to eq(nil) + end + + it "returns nil for #normalized_site" do + expect(@uri.normalized_site).to eq(nil) + end + + it "returns '' for #path" do + expect(@uri.path).to eq('') + end + + it "returns '' for #normalized_path" do + expect(@uri.normalized_path).to eq('') + end + + it "returns nil for #query" do + expect(@uri.query).to eq(nil) + end + + it "returns nil for #normalized_query" do + expect(@uri.normalized_query).to eq(nil) + end + + it "returns nil for #fragment" do + expect(@uri.fragment).to eq(nil) + end + + it "returns nil for #normalized_fragment" do + expect(@uri.normalized_fragment).to eq(nil) + end + + it "returns #hash" do + expect(@uri.hash).not_to be nil + end + + it "returns #to_s" do + expect(@uri.to_s).to eq('') + end + + it "should be empty" do + expect(@uri).to be_empty + end + + it "should be frozen" do + expect(@uri).to be_frozen + end + + it "should not be frozen after duping" do + expect(@uri.dup).not_to be_frozen + end + + it "should not allow destructive operations" do + expect { @uri.normalize! }.to raise_error { |error| + expect(error.message).to match(/can't modify frozen/) + expect(error).to satisfy { |e| RuntimeError === e || TypeError === e } + } + end +end + +describe Addressable::URI, "when frozen" do + before do + @uri = Addressable::URI.parse( + "HTTP://example.com.:%38%30/%70a%74%68?a=%31#1%323" + ).freeze + end + + it "returns 'HTTP' for #scheme" do + expect(@uri.scheme).to eq("HTTP") + end + + it "returns 'http' for #normalized_scheme" do + expect(@uri.normalized_scheme).to eq("http") + expect(@uri.normalize.scheme).to eq("http") + end + + it "returns nil for #user" do + expect(@uri.user).to eq(nil) + end + + it "returns nil for #normalized_user" do + expect(@uri.normalized_user).to eq(nil) + end + + it "returns nil for #password" do + expect(@uri.password).to eq(nil) + end + + it "returns nil for #normalized_password" do + expect(@uri.normalized_password).to eq(nil) + end + + it "returns nil for #userinfo" do + expect(@uri.userinfo).to eq(nil) + end + + it "returns nil for #normalized_userinfo" do + expect(@uri.normalized_userinfo).to eq(nil) + end + + it "returns 'example.com.' for #host" do + expect(@uri.host).to eq("example.com.") + end + + it "returns nil for #normalized_host" do + expect(@uri.normalized_host).to eq("example.com") + expect(@uri.normalize.host).to eq("example.com") + end + + it "returns 'example.com.:80' for #authority" do + expect(@uri.authority).to eq("example.com.:80") + end + + it "returns 'example.com:80' for #normalized_authority" do + expect(@uri.normalized_authority).to eq("example.com") + expect(@uri.normalize.authority).to eq("example.com") + end + + it "returns 80 for #port" do + expect(@uri.port).to eq(80) + end + + it "returns nil for #normalized_port" do + expect(@uri.normalized_port).to eq(nil) + expect(@uri.normalize.port).to eq(nil) + end + + it "returns 80 for #default_port" do + expect(@uri.default_port).to eq(80) + end + + it "returns 'HTTP://example.com.:80' for #site" do + expect(@uri.site).to eq("HTTP://example.com.:80") + end + + it "returns 'http://example.com' for #normalized_site" do + expect(@uri.normalized_site).to eq("http://example.com") + expect(@uri.normalize.site).to eq("http://example.com") + end + + it "returns '/%70a%74%68' for #path" do + expect(@uri.path).to eq("/%70a%74%68") + end + + it "returns '/path' for #normalized_path" do + expect(@uri.normalized_path).to eq("/path") + expect(@uri.normalize.path).to eq("/path") + end + + it "returns 'a=%31' for #query" do + expect(@uri.query).to eq("a=%31") + end + + it "returns 'a=1' for #normalized_query" do + expect(@uri.normalized_query).to eq("a=1") + expect(@uri.normalize.query).to eq("a=1") + end + + it "returns '/%70a%74%68?a=%31' for #request_uri" do + expect(@uri.request_uri).to eq("/%70a%74%68?a=%31") + end + + it "returns '1%323' for #fragment" do + expect(@uri.fragment).to eq("1%323") + end + + it "returns '123' for #normalized_fragment" do + expect(@uri.normalized_fragment).to eq("123") + expect(@uri.normalize.fragment).to eq("123") + end + + it "returns #hash" do + expect(@uri.hash).not_to be nil + end + + it "returns #to_s" do + expect(@uri.to_s).to eq('HTTP://example.com.:80/%70a%74%68?a=%31#1%323') + expect(@uri.normalize.to_s).to eq('http://example.com/path?a=1#123') + end + + it "should not be empty" do + expect(@uri).not_to be_empty + end + + it "should be frozen" do + expect(@uri).to be_frozen + end + + it "should not be frozen after duping" do + expect(@uri.dup).not_to be_frozen + end + + it "should not allow destructive operations" do + expect { @uri.normalize! }.to raise_error { |error| + expect(error.message).to match(/can't modify frozen/) + expect(error).to satisfy { |e| RuntimeError === e || TypeError === e } + } + end +end + +describe Addressable::URI, "when normalized and then deeply frozen" do + before do + @uri = Addressable::URI.parse( + "http://user:password@example.com:8080/path?query=value#fragment" + ).normalize! + + @uri.instance_variables.each do |var| + @uri.instance_variable_set(var, @uri.instance_variable_get(var).freeze) + end + + @uri.freeze + end + + it "#normalized_scheme should not error" do + expect { @uri.normalized_scheme }.not_to raise_error + end + + it "#normalized_user should not error" do + expect { @uri.normalized_user }.not_to raise_error + end + + it "#normalized_password should not error" do + expect { @uri.normalized_password }.not_to raise_error + end + + it "#normalized_userinfo should not error" do + expect { @uri.normalized_userinfo }.not_to raise_error + end + + it "#normalized_host should not error" do + expect { @uri.normalized_host }.not_to raise_error + end + + it "#normalized_authority should not error" do + expect { @uri.normalized_authority }.not_to raise_error + end + + it "#normalized_port should not error" do + expect { @uri.normalized_port }.not_to raise_error + end + + it "#normalized_site should not error" do + expect { @uri.normalized_site }.not_to raise_error + end + + it "#normalized_path should not error" do + expect { @uri.normalized_path }.not_to raise_error + end + + it "#normalized_query should not error" do + expect { @uri.normalized_query }.not_to raise_error + end + + it "#normalized_fragment should not error" do + expect { @uri.normalized_fragment }.not_to raise_error + end + + it "should be frozen" do + expect(@uri).to be_frozen + end + + it "should not allow destructive operations" do + expect { @uri.normalize! }.to raise_error(RuntimeError) + end +end + +describe Addressable::URI, "when created from string components" do + before do + @uri = Addressable::URI.new( + :scheme => "http", :host => "example.com" + ) + end + + it "should have a site value of 'http://example.com'" do + expect(@uri.site).to eq("http://example.com") + end + + it "should be equal to the equivalent parsed URI" do + expect(@uri).to eq(Addressable::URI.parse("http://example.com")) + end + + it "should raise an error if invalid components omitted" do + expect do + @uri.omit(:bogus) + end.to raise_error(ArgumentError) + expect do + @uri.omit(:scheme, :bogus, :path) + end.to raise_error(ArgumentError) + end +end + +describe Addressable::URI, "when created with a nil host but " + + "non-nil authority components" do + it "should raise an error" do + expect do + Addressable::URI.new(:user => "user", :password => "pass", :port => 80) + end.to raise_error(Addressable::URI::InvalidURIError) + end +end + +describe Addressable::URI, "when created with both an authority and a user" do + it "should raise an error" do + expect do + Addressable::URI.new( + :user => "user", :authority => "user@example.com:80" + ) + end.to raise_error(ArgumentError) + end +end + +describe Addressable::URI, "when created with an authority and no port" do + before do + @uri = Addressable::URI.new(:authority => "user@example.com") + end + + it "should not infer a port" do + expect(@uri.port).to eq(nil) + expect(@uri.default_port).to eq(nil) + expect(@uri.inferred_port).to eq(nil) + end + + it "should have a site value of '//user@example.com'" do + expect(@uri.site).to eq("//user@example.com") + end + + it "should have a 'null' origin" do + expect(@uri.origin).to eq('null') + end +end + +describe Addressable::URI, "when created with a host with trailing dots" do + before do + @uri = Addressable::URI.new(:authority => "example...") + end + + it "should have a stable normalized form" do + expect(@uri.normalize.normalize.normalize.host).to eq( + @uri.normalize.host + ) + end +end + +describe Addressable::URI, "when created with a host with a backslash" do + it "should raise an error" do + expect do + Addressable::URI.new(:authority => "example\\example") + end.to raise_error(Addressable::URI::InvalidURIError) + end +end + +describe Addressable::URI, "when created with a host with a slash" do + it "should raise an error" do + expect do + Addressable::URI.new(:authority => "example/example") + end.to raise_error(Addressable::URI::InvalidURIError) + end +end + +describe Addressable::URI, "when created with a host with a space" do + it "should raise an error" do + expect do + Addressable::URI.new(:authority => "example example") + end.to raise_error(Addressable::URI::InvalidURIError) + end +end + +describe Addressable::URI, "when created with both a userinfo and a user" do + it "should raise an error" do + expect do + Addressable::URI.new(:user => "user", :userinfo => "user:pass") + end.to raise_error(ArgumentError) + end +end + +describe Addressable::URI, "when created with a path that hasn't been " + + "prefixed with a '/' but a host specified" do + before do + @uri = Addressable::URI.new( + :scheme => "http", :host => "example.com", :path => "path" + ) + end + + it "should prefix a '/' to the path" do + expect(@uri).to eq(Addressable::URI.parse("http://example.com/path")) + end + + it "should have a site value of 'http://example.com'" do + expect(@uri.site).to eq("http://example.com") + end + + it "should have an origin of 'http://example.com" do + expect(@uri.origin).to eq('http://example.com') + end +end + +describe Addressable::URI, "when created with a path that hasn't been " + + "prefixed with a '/' but no host specified" do + before do + @uri = Addressable::URI.new( + :scheme => "http", :path => "path" + ) + end + + it "should not prefix a '/' to the path" do + expect(@uri).to eq(Addressable::URI.parse("http:path")) + end + + it "should have a site value of 'http:'" do + expect(@uri.site).to eq("http:") + end + + it "should have a 'null' origin" do + expect(@uri.origin).to eq('null') + end +end + +describe Addressable::URI, "when parsed from an Addressable::URI object" do + it "should not have unexpected side-effects" do + original_uri = Addressable::URI.parse("http://example.com/") + new_uri = Addressable::URI.parse(original_uri) + new_uri.host = 'www.example.com' + expect(new_uri.host).to eq('www.example.com') + expect(new_uri.to_s).to eq('http://www.example.com/') + expect(original_uri.host).to eq('example.com') + expect(original_uri.to_s).to eq('http://example.com/') + end + + it "should not have unexpected side-effects" do + original_uri = Addressable::URI.parse("http://example.com/") + new_uri = Addressable::URI.heuristic_parse(original_uri) + new_uri.host = 'www.example.com' + expect(new_uri.host).to eq('www.example.com') + expect(new_uri.to_s).to eq('http://www.example.com/') + expect(original_uri.host).to eq('example.com') + expect(original_uri.to_s).to eq('http://example.com/') + end + + it "should not have unexpected side-effects" do + original_uri = Addressable::URI.parse("http://example.com/") + new_uri = Addressable::URI.parse(original_uri) + new_uri.origin = 'https://www.example.com:8080' + expect(new_uri.host).to eq('www.example.com') + expect(new_uri.to_s).to eq('https://www.example.com:8080/') + expect(original_uri.host).to eq('example.com') + expect(original_uri.to_s).to eq('http://example.com/') + end + + it "should not have unexpected side-effects" do + original_uri = Addressable::URI.parse("http://example.com/") + new_uri = Addressable::URI.heuristic_parse(original_uri) + new_uri.origin = 'https://www.example.com:8080' + expect(new_uri.host).to eq('www.example.com') + expect(new_uri.to_s).to eq('https://www.example.com:8080/') + expect(original_uri.host).to eq('example.com') + expect(original_uri.to_s).to eq('http://example.com/') + end +end + +describe Addressable::URI, "when parsed from something that looks " + + "like a URI object" do + it "should parse without error" do + uri = Addressable::URI.parse(Fake::URI::HTTP.new("http://example.com/")) + expect do + Addressable::URI.parse(uri) + end.not_to raise_error + end +end + +describe Addressable::URI, "when parsed from a standard library URI object" do + it "should parse without error" do + uri = Addressable::URI.parse(URI.parse("http://example.com/")) + expect do + Addressable::URI.parse(uri) + end.not_to raise_error + end +end + +describe Addressable::URI, "when parsed from ''" do + before do + @uri = Addressable::URI.parse("") + end + + it "should have no scheme" do + expect(@uri.scheme).to eq(nil) + end + + it "should not be considered to be ip-based" do + expect(@uri).not_to be_ip_based + end + + it "should have a path of ''" do + expect(@uri.path).to eq("") + end + + it "should have a request URI of '/'" do + expect(@uri.request_uri).to eq("/") + end + + it "should be considered relative" do + expect(@uri).to be_relative + end + + it "should be considered to be in normal form" do + expect(@uri.normalize).to be_eql(@uri) + end + + it "should have a 'null' origin" do + expect(@uri.origin).to eq('null') + end +end + +# Section 1.1.2 of RFC 3986 +describe Addressable::URI, "when parsed from " + + "'ftp://ftp.is.co.za/rfc/rfc1808.txt'" do + before do + @uri = Addressable::URI.parse("ftp://ftp.is.co.za/rfc/rfc1808.txt") + end + + it "should use the 'ftp' scheme" do + expect(@uri.scheme).to eq("ftp") + end + + it "should be considered to be ip-based" do + expect(@uri).to be_ip_based + end + + it "should have a host of 'ftp.is.co.za'" do + expect(@uri.host).to eq("ftp.is.co.za") + end + + it "should have inferred_port of 21" do + expect(@uri.inferred_port).to eq(21) + end + + it "should have a path of '/rfc/rfc1808.txt'" do + expect(@uri.path).to eq("/rfc/rfc1808.txt") + end + + it "should not have a request URI" do + expect(@uri.request_uri).to eq(nil) + end + + it "should be considered to be in normal form" do + expect(@uri.normalize).to be_eql(@uri) + end + + it "should have an origin of 'ftp://ftp.is.co.za'" do + expect(@uri.origin).to eq('ftp://ftp.is.co.za') + end +end + +# Section 1.1.2 of RFC 3986 +describe Addressable::URI, "when parsed from " + + "'http://www.ietf.org/rfc/rfc2396.txt'" do + before do + @uri = Addressable::URI.parse("http://www.ietf.org/rfc/rfc2396.txt") + end + + it "should use the 'http' scheme" do + expect(@uri.scheme).to eq("http") + end + + it "should be considered to be ip-based" do + expect(@uri).to be_ip_based + end + + it "should have a host of 'www.ietf.org'" do + expect(@uri.host).to eq("www.ietf.org") + end + + it "should have inferred_port of 80" do + expect(@uri.inferred_port).to eq(80) + end + + it "should have a path of '/rfc/rfc2396.txt'" do + expect(@uri.path).to eq("/rfc/rfc2396.txt") + end + + it "should have a request URI of '/rfc/rfc2396.txt'" do + expect(@uri.request_uri).to eq("/rfc/rfc2396.txt") + end + + it "should be considered to be in normal form" do + expect(@uri.normalize).to be_eql(@uri) + end + + it "should correctly omit components" do + expect(@uri.omit(:scheme).to_s).to eq("//www.ietf.org/rfc/rfc2396.txt") + expect(@uri.omit(:path).to_s).to eq("http://www.ietf.org") + end + + it "should correctly omit components destructively" do + @uri.omit!(:scheme) + expect(@uri.to_s).to eq("//www.ietf.org/rfc/rfc2396.txt") + end + + it "should have an origin of 'http://www.ietf.org'" do + expect(@uri.origin).to eq('http://www.ietf.org') + end +end + +# Section 1.1.2 of RFC 3986 +describe Addressable::URI, "when parsed from " + + "'ldap://[2001:db8::7]/c=GB?objectClass?one'" do + before do + @uri = Addressable::URI.parse("ldap://[2001:db8::7]/c=GB?objectClass?one") + end + + it "should use the 'ldap' scheme" do + expect(@uri.scheme).to eq("ldap") + end + + it "should be considered to be ip-based" do + expect(@uri).to be_ip_based + end + + it "should have a host of '[2001:db8::7]'" do + expect(@uri.host).to eq("[2001:db8::7]") + end + + it "should have inferred_port of 389" do + expect(@uri.inferred_port).to eq(389) + end + + it "should have a path of '/c=GB'" do + expect(@uri.path).to eq("/c=GB") + end + + it "should not have a request URI" do + expect(@uri.request_uri).to eq(nil) + end + + it "should not allow request URI assignment" do + expect do + @uri.request_uri = "/" + end.to raise_error(Addressable::URI::InvalidURIError) + end + + it "should have a query of 'objectClass?one'" do + expect(@uri.query).to eq("objectClass?one") + end + + it "should be considered to be in normal form" do + expect(@uri.normalize).to be_eql(@uri) + end + + it "should correctly omit components" do + expect(@uri.omit(:scheme, :authority).to_s).to eq("/c=GB?objectClass?one") + expect(@uri.omit(:path).to_s).to eq("ldap://[2001:db8::7]?objectClass?one") + end + + it "should correctly omit components destructively" do + @uri.omit!(:scheme, :authority) + expect(@uri.to_s).to eq("/c=GB?objectClass?one") + end + + it "should raise an error if omission would create an invalid URI" do + expect do + @uri.omit(:authority, :path) + end.to raise_error(Addressable::URI::InvalidURIError) + end + + it "should have an origin of 'ldap://[2001:db8::7]'" do + expect(@uri.origin).to eq('ldap://[2001:db8::7]') + end +end + +# Section 1.1.2 of RFC 3986 +describe Addressable::URI, "when parsed from " + + "'mailto:John.Doe@example.com'" do + before do + @uri = Addressable::URI.parse("mailto:John.Doe@example.com") + end + + it "should use the 'mailto' scheme" do + expect(@uri.scheme).to eq("mailto") + end + + it "should not be considered to be ip-based" do + expect(@uri).not_to be_ip_based + end + + it "should not have an inferred_port" do + expect(@uri.inferred_port).to eq(nil) + end + + it "should have a path of 'John.Doe@example.com'" do + expect(@uri.path).to eq("John.Doe@example.com") + end + + it "should not have a request URI" do + expect(@uri.request_uri).to eq(nil) + end + + it "should be considered to be in normal form" do + expect(@uri.normalize).to be_eql(@uri) + end + + it "should have a 'null' origin" do + expect(@uri.origin).to eq('null') + end +end + +# Section 2 of RFC 6068 +describe Addressable::URI, "when parsed from " + + "'mailto:?to=addr1@an.example,addr2@an.example'" do + before do + @uri = Addressable::URI.parse( + "mailto:?to=addr1@an.example,addr2@an.example" + ) + end + + it "should use the 'mailto' scheme" do + expect(@uri.scheme).to eq("mailto") + end + + it "should not be considered to be ip-based" do + expect(@uri).not_to be_ip_based + end + + it "should not have an inferred_port" do + expect(@uri.inferred_port).to eq(nil) + end + + it "should have a path of ''" do + expect(@uri.path).to eq("") + end + + it "should not have a request URI" do + expect(@uri.request_uri).to eq(nil) + end + + it "should have the To: field value parameterized" do + expect(@uri.query_values(Hash)["to"]).to eq( + "addr1@an.example,addr2@an.example" + ) + end + + it "should be considered to be in normal form" do + expect(@uri.normalize).to be_eql(@uri) + end + + it "should have a 'null' origin" do + expect(@uri.origin).to eq('null') + end +end + +# Section 1.1.2 of RFC 3986 +describe Addressable::URI, "when parsed from " + + "'news:comp.infosystems.www.servers.unix'" do + before do + @uri = Addressable::URI.parse("news:comp.infosystems.www.servers.unix") + end + + it "should use the 'news' scheme" do + expect(@uri.scheme).to eq("news") + end + + it "should not have an inferred_port" do + expect(@uri.inferred_port).to eq(nil) + end + + it "should not be considered to be ip-based" do + expect(@uri).not_to be_ip_based + end + + it "should have a path of 'comp.infosystems.www.servers.unix'" do + expect(@uri.path).to eq("comp.infosystems.www.servers.unix") + end + + it "should not have a request URI" do + expect(@uri.request_uri).to eq(nil) + end + + it "should be considered to be in normal form" do + expect(@uri.normalize).to be_eql(@uri) + end + + it "should have a 'null' origin" do + expect(@uri.origin).to eq('null') + end +end + +# Section 1.1.2 of RFC 3986 +describe Addressable::URI, "when parsed from " + + "'tel:+1-816-555-1212'" do + before do + @uri = Addressable::URI.parse("tel:+1-816-555-1212") + end + + it "should use the 'tel' scheme" do + expect(@uri.scheme).to eq("tel") + end + + it "should not be considered to be ip-based" do + expect(@uri).not_to be_ip_based + end + + it "should not have an inferred_port" do + expect(@uri.inferred_port).to eq(nil) + end + + it "should have a path of '+1-816-555-1212'" do + expect(@uri.path).to eq("+1-816-555-1212") + end + + it "should not have a request URI" do + expect(@uri.request_uri).to eq(nil) + end + + it "should be considered to be in normal form" do + expect(@uri.normalize).to be_eql(@uri) + end + + it "should have a 'null' origin" do + expect(@uri.origin).to eq('null') + end +end + +# Section 1.1.2 of RFC 3986 +describe Addressable::URI, "when parsed from " + + "'telnet://192.0.2.16:80/'" do + before do + @uri = Addressable::URI.parse("telnet://192.0.2.16:80/") + end + + it "should use the 'telnet' scheme" do + expect(@uri.scheme).to eq("telnet") + end + + it "should have a host of '192.0.2.16'" do + expect(@uri.host).to eq("192.0.2.16") + end + + it "should have a port of 80" do + expect(@uri.port).to eq(80) + end + + it "should have a inferred_port of 80" do + expect(@uri.inferred_port).to eq(80) + end + + it "should have a default_port of 23" do + expect(@uri.default_port).to eq(23) + end + + it "should be considered to be ip-based" do + expect(@uri).to be_ip_based + end + + it "should have a path of '/'" do + expect(@uri.path).to eq("/") + end + + it "should not have a request URI" do + expect(@uri.request_uri).to eq(nil) + end + + it "should be considered to be in normal form" do + expect(@uri.normalize).to be_eql(@uri) + end + + it "should have an origin of 'telnet://192.0.2.16:80'" do + expect(@uri.origin).to eq('telnet://192.0.2.16:80') + end +end + +# Section 1.1.2 of RFC 3986 +describe Addressable::URI, "when parsed from " + + "'urn:oasis:names:specification:docbook:dtd:xml:4.1.2'" do + before do + @uri = Addressable::URI.parse( + "urn:oasis:names:specification:docbook:dtd:xml:4.1.2") + end + + it "should use the 'urn' scheme" do + expect(@uri.scheme).to eq("urn") + end + + it "should not have an inferred_port" do + expect(@uri.inferred_port).to eq(nil) + end + + it "should not be considered to be ip-based" do + expect(@uri).not_to be_ip_based + end + + it "should have a path of " + + "'oasis:names:specification:docbook:dtd:xml:4.1.2'" do + expect(@uri.path).to eq("oasis:names:specification:docbook:dtd:xml:4.1.2") + end + + it "should not have a request URI" do + expect(@uri.request_uri).to eq(nil) + end + + it "should be considered to be in normal form" do + expect(@uri.normalize).to be_eql(@uri) + end + + it "should have a 'null' origin" do + expect(@uri.origin).to eq('null') + end +end + +describe Addressable::URI, "when heuristically parsed from " + + "'192.0.2.16:8000/path'" do + before do + @uri = Addressable::URI.heuristic_parse("192.0.2.16:8000/path") + end + + it "should use the 'http' scheme" do + expect(@uri.scheme).to eq("http") + end + + it "should have a host of '192.0.2.16'" do + expect(@uri.host).to eq("192.0.2.16") + end + + it "should have a port of '8000'" do + expect(@uri.port).to eq(8000) + end + + it "should be considered to be ip-based" do + expect(@uri).to be_ip_based + end + + it "should have a path of '/path'" do + expect(@uri.path).to eq("/path") + end + + it "should be considered to be in normal form" do + expect(@uri.normalize).to be_eql(@uri) + end + + it "should have an origin of 'http://192.0.2.16:8000'" do + expect(@uri.origin).to eq('http://192.0.2.16:8000') + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com'" do + before do + @uri = Addressable::URI.parse("http://example.com") + end + + it "when inspected, should have the correct URI" do + expect(@uri.inspect).to include("http://example.com") + end + + it "when inspected, should have the correct class name" do + expect(@uri.inspect).to include("Addressable::URI") + end + + it "when inspected, should have the correct object id" do + expect(@uri.inspect).to include("%#0x" % @uri.object_id) + end + + it "should use the 'http' scheme" do + expect(@uri.scheme).to eq("http") + end + + it "should be considered to be ip-based" do + expect(@uri).to be_ip_based + end + + it "should have an authority segment of 'example.com'" do + expect(@uri.authority).to eq("example.com") + end + + it "should have a host of 'example.com'" do + expect(@uri.host).to eq("example.com") + end + + it "should be considered ip-based" do + expect(@uri).to be_ip_based + end + + it "should have no username" do + expect(@uri.user).to eq(nil) + end + + it "should have no password" do + expect(@uri.password).to eq(nil) + end + + it "should use port 80" do + expect(@uri.inferred_port).to eq(80) + end + + it "should not have a specified port" do + expect(@uri.port).to eq(nil) + end + + it "should have an empty path" do + expect(@uri.path).to eq("") + end + + it "should have no query string" do + expect(@uri.query).to eq(nil) + expect(@uri.query_values).to eq(nil) + end + + it "should have a request URI of '/'" do + expect(@uri.request_uri).to eq("/") + end + + it "should have no fragment" do + expect(@uri.fragment).to eq(nil) + end + + it "should be considered absolute" do + expect(@uri).to be_absolute + end + + it "should not be considered relative" do + expect(@uri).not_to be_relative + end + + it "should not be exactly equal to 42" do + expect(@uri.eql?(42)).to eq(false) + end + + it "should not be equal to 42" do + expect(@uri == 42).to eq(false) + end + + it "should not be roughly equal to 42" do + expect(@uri === 42).to eq(false) + end + + it "should be exactly equal to http://example.com" do + expect(@uri.eql?(Addressable::URI.parse("http://example.com"))).to eq(true) + end + + it "should be roughly equal to http://example.com/" do + expect(@uri === Addressable::URI.parse("http://example.com/")).to eq(true) + end + + it "should be roughly equal to the string 'http://example.com/'" do + expect(@uri === "http://example.com/").to eq(true) + end + + it "should not be roughly equal to the string " + + "'http://example.com:bogus/'" do + expect do + expect(@uri === "http://example.com:bogus/").to eq(false) + end.not_to raise_error + end + + it "should result in itself when joined with itself" do + expect(@uri.join(@uri).to_s).to eq("http://example.com") + expect(@uri.join!(@uri).to_s).to eq("http://example.com") + end + + it "should be equivalent to http://EXAMPLE.com" do + expect(@uri).to eq(Addressable::URI.parse("http://EXAMPLE.com")) + end + + it "should be equivalent to http://EXAMPLE.com:80/" do + expect(@uri).to eq(Addressable::URI.parse("http://EXAMPLE.com:80/")) + end + + it "should have the same hash as http://example.com" do + expect(@uri.hash).to eq(Addressable::URI.parse("http://example.com").hash) + end + + it "should have the same hash as http://EXAMPLE.com after assignment" do + @uri.origin = "http://EXAMPLE.com" + expect(@uri.hash).to eq(Addressable::URI.parse("http://EXAMPLE.com").hash) + end + + it "should have a different hash from http://EXAMPLE.com" do + expect(@uri.hash).not_to eq(Addressable::URI.parse("http://EXAMPLE.com").hash) + end + + it "should not allow origin assignment without scheme" do + expect do + @uri.origin = "example.com" + end.to raise_error(Addressable::URI::InvalidURIError) + end + + it "should not allow origin assignment without host" do + expect do + @uri.origin = "http://" + end.to raise_error(Addressable::URI::InvalidURIError) + end + + it "should not allow origin assignment with bogus type" do + expect do + @uri.origin = :bogus + end.to raise_error(TypeError) + end + + # Section 6.2.3 of RFC 3986 + it "should be equivalent to http://example.com/" do + expect(@uri).to eq(Addressable::URI.parse("http://example.com/")) + end + + # Section 6.2.3 of RFC 3986 + it "should be equivalent to http://example.com:/" do + expect(@uri).to eq(Addressable::URI.parse("http://example.com:/")) + end + + # Section 6.2.3 of RFC 3986 + it "should be equivalent to http://example.com:80/" do + expect(@uri).to eq(Addressable::URI.parse("http://example.com:80/")) + end + + # Section 6.2.2.1 of RFC 3986 + it "should be equivalent to http://EXAMPLE.COM/" do + expect(@uri).to eq(Addressable::URI.parse("http://EXAMPLE.COM/")) + end + + it "should have a route of '/path/' to 'http://example.com/path/'" do + expect(@uri.route_to("http://example.com/path/")).to eq( + Addressable::URI.parse("/path/") + ) + end + + it "should have a route of '..' from 'http://example.com/path/'" do + expect(@uri.route_from("http://example.com/path/")).to eq( + Addressable::URI.parse("..") + ) + end + + it "should have a route of '#' to 'http://example.com/'" do + expect(@uri.route_to("http://example.com/")).to eq( + Addressable::URI.parse("#") + ) + end + + it "should have a route of 'http://elsewhere.com/' to " + + "'http://elsewhere.com/'" do + expect(@uri.route_to("http://elsewhere.com/")).to eq( + Addressable::URI.parse("http://elsewhere.com/") + ) + end + + it "when joined with 'relative/path' should be " + + "'http://example.com/relative/path'" do + expect(@uri.join('relative/path')).to eq( + Addressable::URI.parse("http://example.com/relative/path") + ) + end + + it "when joined with a bogus object a TypeError should be raised" do + expect do + @uri.join(42) + end.to raise_error(TypeError) + end + + it "should have the correct username after assignment" do + @uri.user = "newuser" + expect(@uri.user).to eq("newuser") + expect(@uri.password).to eq(nil) + expect(@uri.to_s).to eq("http://newuser@example.com") + end + + it "should have the correct username after assignment" do + @uri.user = "user@123!" + expect(@uri.user).to eq("user@123!") + expect(@uri.normalized_user).to eq("user%40123%21") + expect(@uri.password).to eq(nil) + expect(@uri.normalize.to_s).to eq("http://user%40123%21@example.com/") + end + + it "should have the correct password after assignment" do + @uri.password = "newpass" + expect(@uri.password).to eq("newpass") + expect(@uri.user).to eq("") + expect(@uri.to_s).to eq("http://:newpass@example.com") + end + + it "should have the correct password after assignment" do + @uri.password = "#secret@123!" + expect(@uri.password).to eq("#secret@123!") + expect(@uri.normalized_password).to eq("%23secret%40123%21") + expect(@uri.user).to eq("") + expect(@uri.normalize.to_s).to eq("http://:%23secret%40123%21@example.com/") + expect(@uri.omit(:password).to_s).to eq("http://example.com") + end + + it "should have the correct user/pass after repeated assignment" do + @uri.user = nil + expect(@uri.user).to eq(nil) + @uri.password = "newpass" + expect(@uri.password).to eq("newpass") + # Username cannot be nil if the password is set + expect(@uri.user).to eq("") + expect(@uri.to_s).to eq("http://:newpass@example.com") + @uri.user = "newuser" + expect(@uri.user).to eq("newuser") + @uri.password = nil + expect(@uri.password).to eq(nil) + expect(@uri.to_s).to eq("http://newuser@example.com") + @uri.user = "newuser" + expect(@uri.user).to eq("newuser") + @uri.password = "" + expect(@uri.password).to eq("") + expect(@uri.to_s).to eq("http://newuser:@example.com") + @uri.password = "newpass" + expect(@uri.password).to eq("newpass") + @uri.user = nil + # Username cannot be nil if the password is set + expect(@uri.user).to eq("") + expect(@uri.to_s).to eq("http://:newpass@example.com") + end + + it "should have the correct user/pass after userinfo assignment" do + @uri.user = "newuser" + expect(@uri.user).to eq("newuser") + @uri.password = "newpass" + expect(@uri.password).to eq("newpass") + @uri.userinfo = nil + expect(@uri.userinfo).to eq(nil) + expect(@uri.user).to eq(nil) + expect(@uri.password).to eq(nil) + end + + it "should correctly convert to a hash" do + expect(@uri.to_hash).to eq({ + :scheme => "http", + :user => nil, + :password => nil, + :host => "example.com", + :port => nil, + :path => "", + :query => nil, + :fragment => nil + }) + end + + it "should be identical to its duplicate" do + expect(@uri).to eq(@uri.dup) + end + + it "should have an origin of 'http://example.com'" do + expect(@uri.origin).to eq('http://example.com') + end +end + +# Section 5.1.2 of RFC 2616 +describe Addressable::URI, "when parsed from " + + "'HTTP://www.w3.org/pub/WWW/TheProject.html'" do + before do + @uri = Addressable::URI.parse("HTTP://www.w3.org/pub/WWW/TheProject.html") + end + + it "should have the correct request URI" do + expect(@uri.request_uri).to eq("/pub/WWW/TheProject.html") + end + + it "should have the correct request URI after assignment" do + @uri.request_uri = "/pub/WWW/TheProject.html?" + expect(@uri.request_uri).to eq("/pub/WWW/TheProject.html?") + expect(@uri.path).to eq("/pub/WWW/TheProject.html") + expect(@uri.query).to eq("") + end + + it "should have the correct request URI after assignment" do + @uri.request_uri = "/some/where/else.html" + expect(@uri.request_uri).to eq("/some/where/else.html") + expect(@uri.path).to eq("/some/where/else.html") + expect(@uri.query).to eq(nil) + end + + it "should have the correct request URI after assignment" do + @uri.request_uri = "/some/where/else.html?query?string" + expect(@uri.request_uri).to eq("/some/where/else.html?query?string") + expect(@uri.path).to eq("/some/where/else.html") + expect(@uri.query).to eq("query?string") + end + + it "should have the correct request URI after assignment" do + @uri.request_uri = "?x=y" + expect(@uri.request_uri).to eq("/?x=y") + expect(@uri.path).to eq("/") + expect(@uri.query).to eq("x=y") + end + + it "should raise an error if the site value is set to something bogus" do + expect do + @uri.site = 42 + end.to raise_error(TypeError) + end + + it "should raise an error if the request URI is set to something bogus" do + expect do + @uri.request_uri = 42 + end.to raise_error(TypeError) + end + + it "should correctly convert to a hash" do + expect(@uri.to_hash).to eq({ + :scheme => "HTTP", + :user => nil, + :password => nil, + :host => "www.w3.org", + :port => nil, + :path => "/pub/WWW/TheProject.html", + :query => nil, + :fragment => nil + }) + end + + it "should have an origin of 'http://www.w3.org'" do + expect(@uri.origin).to eq('http://www.w3.org') + end +end + +describe Addressable::URI, "when parsing IPv6 addresses" do + it "should not raise an error for " + + "'http://[3ffe:1900:4545:3:200:f8ff:fe21:67cf]/'" do + Addressable::URI.parse("http://[3ffe:1900:4545:3:200:f8ff:fe21:67cf]/") + end + + it "should not raise an error for " + + "'http://[fe80:0:0:0:200:f8ff:fe21:67cf]/'" do + Addressable::URI.parse("http://[fe80:0:0:0:200:f8ff:fe21:67cf]/") + end + + it "should not raise an error for " + + "'http://[fe80::200:f8ff:fe21:67cf]/'" do + Addressable::URI.parse("http://[fe80::200:f8ff:fe21:67cf]/") + end + + it "should not raise an error for " + + "'http://[::1]/'" do + Addressable::URI.parse("http://[::1]/") + end + + it "should not raise an error for " + + "'http://[fe80::1]/'" do + Addressable::URI.parse("http://[fe80::1]/") + end + + it "should raise an error for " + + "'http://[]/'" do + expect do + Addressable::URI.parse("http://[]/") + end.to raise_error(Addressable::URI::InvalidURIError) + end +end + +describe Addressable::URI, "when parsing IPv6 address" do + subject { Addressable::URI.parse("http://[3ffe:1900:4545:3:200:f8ff:fe21:67cf]/") } + its(:host) { should == '[3ffe:1900:4545:3:200:f8ff:fe21:67cf]' } + its(:hostname) { should == '3ffe:1900:4545:3:200:f8ff:fe21:67cf' } +end + +describe Addressable::URI, "when assigning IPv6 address" do + it "should allow to set bare IPv6 address as hostname" do + uri = Addressable::URI.parse("http://[::1]/") + uri.hostname = '3ffe:1900:4545:3:200:f8ff:fe21:67cf' + expect(uri.to_s).to eq('http://[3ffe:1900:4545:3:200:f8ff:fe21:67cf]/') + end + + it "should allow to set bare IPv6 address as hostname with IPAddr object" do + uri = Addressable::URI.parse("http://[::1]/") + uri.hostname = IPAddr.new('3ffe:1900:4545:3:200:f8ff:fe21:67cf') + expect(uri.to_s).to eq('http://[3ffe:1900:4545:3:200:f8ff:fe21:67cf]/') + end + + it "should not allow to set bare IPv6 address as host" do + uri = Addressable::URI.parse("http://[::1]/") + skip "not checked" + expect do + uri.host = '3ffe:1900:4545:3:200:f8ff:fe21:67cf' + end.to raise_error(Addressable::URI::InvalidURIError) + end +end + +describe Addressable::URI, "when parsing IPvFuture addresses" do + it "should not raise an error for " + + "'http://[v9.3ffe:1900:4545:3:200:f8ff:fe21:67cf]/'" do + Addressable::URI.parse("http://[v9.3ffe:1900:4545:3:200:f8ff:fe21:67cf]/") + end + + it "should not raise an error for " + + "'http://[vff.fe80:0:0:0:200:f8ff:fe21:67cf]/'" do + Addressable::URI.parse("http://[vff.fe80:0:0:0:200:f8ff:fe21:67cf]/") + end + + it "should not raise an error for " + + "'http://[v12.fe80::200:f8ff:fe21:67cf]/'" do + Addressable::URI.parse("http://[v12.fe80::200:f8ff:fe21:67cf]/") + end + + it "should not raise an error for " + + "'http://[va0.::1]/'" do + Addressable::URI.parse("http://[va0.::1]/") + end + + it "should not raise an error for " + + "'http://[v255.fe80::1]/'" do + Addressable::URI.parse("http://[v255.fe80::1]/") + end + + it "should raise an error for " + + "'http://[v0.]/'" do + expect do + Addressable::URI.parse("http://[v0.]/") + end.to raise_error(Addressable::URI::InvalidURIError) + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/'" do + before do + @uri = Addressable::URI.parse("http://example.com/") + end + + # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence + it "should be equivalent to http://example.com" do + expect(@uri).to eq(Addressable::URI.parse("http://example.com")) + end + + # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence + it "should be equivalent to HTTP://example.com/" do + expect(@uri).to eq(Addressable::URI.parse("HTTP://example.com/")) + end + + # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence + it "should be equivalent to http://example.com:/" do + expect(@uri).to eq(Addressable::URI.parse("http://example.com:/")) + end + + # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence + it "should be equivalent to http://example.com:80/" do + expect(@uri).to eq(Addressable::URI.parse("http://example.com:80/")) + end + + # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence + it "should be equivalent to http://Example.com/" do + expect(@uri).to eq(Addressable::URI.parse("http://Example.com/")) + end + + it "should have the correct username after assignment" do + @uri.user = nil + expect(@uri.user).to eq(nil) + expect(@uri.password).to eq(nil) + expect(@uri.to_s).to eq("http://example.com/") + end + + it "should have the correct password after assignment" do + @uri.password = nil + expect(@uri.password).to eq(nil) + expect(@uri.user).to eq(nil) + expect(@uri.to_s).to eq("http://example.com/") + end + + it "should have a request URI of '/'" do + expect(@uri.request_uri).to eq("/") + end + + it "should correctly convert to a hash" do + expect(@uri.to_hash).to eq({ + :scheme => "http", + :user => nil, + :password => nil, + :host => "example.com", + :port => nil, + :path => "/", + :query => nil, + :fragment => nil + }) + end + + it "should be identical to its duplicate" do + expect(@uri).to eq(@uri.dup) + end + + it "should have the same hash as its duplicate" do + expect(@uri.hash).to eq(@uri.dup.hash) + end + + it "should have a different hash from its equivalent String value" do + expect(@uri.hash).not_to eq(@uri.to_s.hash) + end + + it "should have the same hash as an equal URI" do + expect(@uri.hash).to eq(Addressable::URI.parse("http://example.com/").hash) + end + + it "should be equivalent to http://EXAMPLE.com" do + expect(@uri).to eq(Addressable::URI.parse("http://EXAMPLE.com")) + end + + it "should be equivalent to http://EXAMPLE.com:80/" do + expect(@uri).to eq(Addressable::URI.parse("http://EXAMPLE.com:80/")) + end + + it "should have the same hash as http://example.com/" do + expect(@uri.hash).to eq(Addressable::URI.parse("http://example.com/").hash) + end + + it "should have the same hash as http://example.com after assignment" do + @uri.path = "" + expect(@uri.hash).to eq(Addressable::URI.parse("http://example.com").hash) + end + + it "should have the same hash as http://example.com/? after assignment" do + @uri.query = "" + expect(@uri.hash).to eq(Addressable::URI.parse("http://example.com/?").hash) + end + + it "should have the same hash as http://example.com/? after assignment" do + @uri.query_values = {} + expect(@uri.hash).to eq(Addressable::URI.parse("http://example.com/?").hash) + end + + it "should have the same hash as http://example.com/# after assignment" do + @uri.fragment = "" + expect(@uri.hash).to eq(Addressable::URI.parse("http://example.com/#").hash) + end + + it "should have a different hash from http://example.com" do + expect(@uri.hash).not_to eq(Addressable::URI.parse("http://example.com").hash) + end + + it "should have an origin of 'http://example.com'" do + expect(@uri.origin).to eq('http://example.com') + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com?#'" do + before do + @uri = Addressable::URI.parse("http://example.com?#") + end + + it "should correctly convert to a hash" do + expect(@uri.to_hash).to eq({ + :scheme => "http", + :user => nil, + :password => nil, + :host => "example.com", + :port => nil, + :path => "", + :query => "", + :fragment => "" + }) + end + + it "should have a request URI of '/?'" do + expect(@uri.request_uri).to eq("/?") + end + + it "should normalize to 'http://example.com/'" do + expect(@uri.normalize.to_s).to eq("http://example.com/") + end + + it "should have an origin of 'http://example.com'" do + expect(@uri.origin).to eq("http://example.com") + end +end + +describe Addressable::URI, "when parsed from " + + "'http://@example.com/'" do + before do + @uri = Addressable::URI.parse("http://@example.com/") + end + + it "should be equivalent to http://example.com" do + expect(@uri).to eq(Addressable::URI.parse("http://example.com")) + end + + it "should correctly convert to a hash" do + expect(@uri.to_hash).to eq({ + :scheme => "http", + :user => "", + :password => nil, + :host => "example.com", + :port => nil, + :path => "/", + :query => nil, + :fragment => nil + }) + end + + it "should be identical to its duplicate" do + expect(@uri).to eq(@uri.dup) + end + + it "should have an origin of 'http://example.com'" do + expect(@uri.origin).to eq('http://example.com') + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com./'" do + before do + @uri = Addressable::URI.parse("http://example.com./") + end + + it "should be equivalent to http://example.com" do + expect(@uri).to eq(Addressable::URI.parse("http://example.com")) + end + + it "should not be considered to be in normal form" do + expect(@uri.normalize).not_to be_eql(@uri) + end + + it "should be identical to its duplicate" do + expect(@uri).to eq(@uri.dup) + end + + it "should have an origin of 'http://example.com'" do + expect(@uri.origin).to eq('http://example.com') + end +end + +describe Addressable::URI, "when parsed from " + + "'http://:@example.com/'" do + before do + @uri = Addressable::URI.parse("http://:@example.com/") + end + + it "should be equivalent to http://example.com" do + expect(@uri).to eq(Addressable::URI.parse("http://example.com")) + end + + it "should correctly convert to a hash" do + expect(@uri.to_hash).to eq({ + :scheme => "http", + :user => "", + :password => "", + :host => "example.com", + :port => nil, + :path => "/", + :query => nil, + :fragment => nil + }) + end + + it "should be identical to its duplicate" do + expect(@uri).to eq(@uri.dup) + end + + it "should have an origin of 'http://example.com'" do + expect(@uri.origin).to eq('http://example.com') + end +end + +describe Addressable::URI, "when parsed from " + + "'HTTP://EXAMPLE.COM/'" do + before do + @uri = Addressable::URI.parse("HTTP://EXAMPLE.COM/") + end + + it "should be equivalent to http://example.com" do + expect(@uri).to eq(Addressable::URI.parse("http://example.com")) + end + + it "should correctly convert to a hash" do + expect(@uri.to_hash).to eq({ + :scheme => "HTTP", + :user => nil, + :password => nil, + :host => "EXAMPLE.COM", + :port => nil, + :path => "/", + :query => nil, + :fragment => nil + }) + end + + it "should be identical to its duplicate" do + expect(@uri).to eq(@uri.dup) + end + + it "should have an origin of 'http://example.com'" do + expect(@uri.origin).to eq('http://example.com') + end + + it "should have a tld of 'com'" do + expect(@uri.tld).to eq('com') + end +end + +describe Addressable::URI, "when parsed from " + + "'http://www.example.co.uk/'" do + before do + @uri = Addressable::URI.parse("http://www.example.co.uk/") + end + + it "should have an origin of 'http://www.example.co.uk'" do + expect(@uri.origin).to eq('http://www.example.co.uk') + end + + it "should have a tld of 'co.uk'" do + expect(@uri.tld).to eq('co.uk') + end + + it "should have a domain of 'example.co.uk'" do + expect(@uri.domain).to eq('example.co.uk') + end +end + +describe Addressable::URI, "when parsed from " + + "'http://sub_domain.blogspot.com/'" do + before do + @uri = Addressable::URI.parse("http://sub_domain.blogspot.com/") + end + + it "should have an origin of 'http://sub_domain.blogspot.com'" do + expect(@uri.origin).to eq('http://sub_domain.blogspot.com') + end + + it "should have a tld of 'com'" do + expect(@uri.tld).to eq('com') + end + + it "should have a domain of 'blogspot.com'" do + expect(@uri.domain).to eq('blogspot.com') + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/~smith/'" do + before do + @uri = Addressable::URI.parse("http://example.com/~smith/") + end + + # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence + it "should be equivalent to http://example.com/%7Esmith/" do + expect(@uri).to eq(Addressable::URI.parse("http://example.com/%7Esmith/")) + end + + # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence + it "should be equivalent to http://example.com/%7esmith/" do + expect(@uri).to eq(Addressable::URI.parse("http://example.com/%7esmith/")) + end + + it "should be identical to its duplicate" do + expect(@uri).to eq(@uri.dup) + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/%E8'" do + before do + @uri = Addressable::URI.parse("http://example.com/%E8") + end + + it "should not raise an exception when normalized" do + expect do + @uri.normalize + end.not_to raise_error + end + + it "should be considered to be in normal form" do + expect(@uri.normalize).to be_eql(@uri) + end + + it "should not change if encoded with the normalizing algorithm" do + expect(Addressable::URI.normalized_encode(@uri).to_s).to eq( + "http://example.com/%E8" + ) + expect(Addressable::URI.normalized_encode(@uri, Addressable::URI).to_s).to be === + "http://example.com/%E8" + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/path%2Fsegment/'" do + before do + @uri = Addressable::URI.parse("http://example.com/path%2Fsegment/") + end + + it "should be considered to be in normal form" do + expect(@uri.normalize).to be_eql(@uri) + end + + it "should be equal to 'http://example.com/path%2Fsegment/'" do + expect(@uri.normalize).to be_eql( + Addressable::URI.parse("http://example.com/path%2Fsegment/") + ) + end + + it "should not be equal to 'http://example.com/path/segment/'" do + expect(@uri).not_to eq( + Addressable::URI.parse("http://example.com/path/segment/") + ) + end + + it "should not be equal to 'http://example.com/path/segment/'" do + expect(@uri.normalize).not_to be_eql( + Addressable::URI.parse("http://example.com/path/segment/") + ) + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/?%F6'" do + before do + @uri = Addressable::URI.parse("http://example.com/?%F6") + end + + it "should not raise an exception when normalized" do + expect do + @uri.normalize + end.not_to raise_error + end + + it "should be considered to be in normal form" do + expect(@uri.normalize).to be_eql(@uri) + end + + it "should not change if encoded with the normalizing algorithm" do + expect(Addressable::URI.normalized_encode(@uri).to_s).to eq( + "http://example.com/?%F6" + ) + expect(Addressable::URI.normalized_encode(@uri, Addressable::URI).to_s).to be === + "http://example.com/?%F6" + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/#%F6'" do + before do + @uri = Addressable::URI.parse("http://example.com/#%F6") + end + + it "should not raise an exception when normalized" do + expect do + @uri.normalize + end.not_to raise_error + end + + it "should be considered to be in normal form" do + expect(@uri.normalize).to be_eql(@uri) + end + + it "should not change if encoded with the normalizing algorithm" do + expect(Addressable::URI.normalized_encode(@uri).to_s).to eq( + "http://example.com/#%F6" + ) + expect(Addressable::URI.normalized_encode(@uri, Addressable::URI).to_s).to be === + "http://example.com/#%F6" + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/%C3%87'" do + before do + @uri = Addressable::URI.parse("http://example.com/%C3%87") + end + + # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence + it "should be equivalent to 'http://example.com/C%CC%A7'" do + expect(@uri).to eq(Addressable::URI.parse("http://example.com/C%CC%A7")) + end + + it "should not change if encoded with the normalizing algorithm" do + expect(Addressable::URI.normalized_encode(@uri).to_s).to eq( + "http://example.com/%C3%87" + ) + expect(Addressable::URI.normalized_encode(@uri, Addressable::URI).to_s).to be === + "http://example.com/%C3%87" + end + + it "should raise an error if encoding with an unexpected return type" do + expect do + Addressable::URI.normalized_encode(@uri, Integer) + end.to raise_error(TypeError) + end + + it "if percent encoded should be 'http://example.com/C%25CC%25A7'" do + expect(Addressable::URI.encode(@uri).to_s).to eq( + "http://example.com/%25C3%2587" + ) + end + + it "if percent encoded should be 'http://example.com/C%25CC%25A7'" do + expect(Addressable::URI.encode(@uri, Addressable::URI)).to eq( + Addressable::URI.parse("http://example.com/%25C3%2587") + ) + end + + it "should raise an error if encoding with an unexpected return type" do + expect do + Addressable::URI.encode(@uri, Integer) + end.to raise_error(TypeError) + end + + it "should be identical to its duplicate" do + expect(@uri).to eq(@uri.dup) + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/?q=string'" do + before do + @uri = Addressable::URI.parse("http://example.com/?q=string") + end + + it "should use the 'http' scheme" do + expect(@uri.scheme).to eq("http") + end + + it "should have an authority segment of 'example.com'" do + expect(@uri.authority).to eq("example.com") + end + + it "should have a host of 'example.com'" do + expect(@uri.host).to eq("example.com") + end + + it "should have no username" do + expect(@uri.user).to eq(nil) + end + + it "should have no password" do + expect(@uri.password).to eq(nil) + end + + it "should use port 80" do + expect(@uri.inferred_port).to eq(80) + end + + it "should have a path of '/'" do + expect(@uri.path).to eq("/") + end + + it "should have a query string of 'q=string'" do + expect(@uri.query).to eq("q=string") + end + + it "should have no fragment" do + expect(@uri.fragment).to eq(nil) + end + + it "should be considered absolute" do + expect(@uri).to be_absolute + end + + it "should not be considered relative" do + expect(@uri).not_to be_relative + end + + it "should be considered to be in normal form" do + expect(@uri.normalize).to be_eql(@uri) + end + + it "should be identical to its duplicate" do + expect(@uri).to eq(@uri.dup) + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com:80/'" do + before do + @uri = Addressable::URI.parse("http://example.com:80/") + end + + it "should use the 'http' scheme" do + expect(@uri.scheme).to eq("http") + end + + it "should have an authority segment of 'example.com:80'" do + expect(@uri.authority).to eq("example.com:80") + end + + it "should have a host of 'example.com'" do + expect(@uri.host).to eq("example.com") + end + + it "should have no username" do + expect(@uri.user).to eq(nil) + end + + it "should have no password" do + expect(@uri.password).to eq(nil) + end + + it "should use port 80" do + expect(@uri.inferred_port).to eq(80) + end + + it "should have explicit port 80" do + expect(@uri.port).to eq(80) + end + + it "should have a path of '/'" do + expect(@uri.path).to eq("/") + end + + it "should have no query string" do + expect(@uri.query).to eq(nil) + end + + it "should have no fragment" do + expect(@uri.fragment).to eq(nil) + end + + it "should be considered absolute" do + expect(@uri).to be_absolute + end + + it "should not be considered relative" do + expect(@uri).not_to be_relative + end + + it "should be exactly equal to http://example.com:80/" do + expect(@uri.eql?(Addressable::URI.parse("http://example.com:80/"))).to eq(true) + end + + it "should be roughly equal to http://example.com/" do + expect(@uri === Addressable::URI.parse("http://example.com/")).to eq(true) + end + + it "should be roughly equal to the string 'http://example.com/'" do + expect(@uri === "http://example.com/").to eq(true) + end + + it "should not be roughly equal to the string " + + "'http://example.com:bogus/'" do + expect do + expect(@uri === "http://example.com:bogus/").to eq(false) + end.not_to raise_error + end + + it "should result in itself when joined with itself" do + expect(@uri.join(@uri).to_s).to eq("http://example.com:80/") + expect(@uri.join!(@uri).to_s).to eq("http://example.com:80/") + end + + # Section 6.2.3 of RFC 3986 + it "should be equal to http://example.com/" do + expect(@uri).to eq(Addressable::URI.parse("http://example.com/")) + end + + # Section 6.2.3 of RFC 3986 + it "should be equal to http://example.com:/" do + expect(@uri).to eq(Addressable::URI.parse("http://example.com:/")) + end + + # Section 6.2.3 of RFC 3986 + it "should be equal to http://example.com:80/" do + expect(@uri).to eq(Addressable::URI.parse("http://example.com:80/")) + end + + # Section 6.2.2.1 of RFC 3986 + it "should be equal to http://EXAMPLE.COM/" do + expect(@uri).to eq(Addressable::URI.parse("http://EXAMPLE.COM/")) + end + + it "should correctly convert to a hash" do + expect(@uri.to_hash).to eq({ + :scheme => "http", + :user => nil, + :password => nil, + :host => "example.com", + :port => 80, + :path => "/", + :query => nil, + :fragment => nil + }) + end + + it "should be identical to its duplicate" do + expect(@uri).to eq(@uri.dup) + end + + it "should have an origin of 'http://example.com'" do + expect(@uri.origin).to eq('http://example.com') + end + + it "should not change if encoded with the normalizing algorithm" do + expect(Addressable::URI.normalized_encode(@uri).to_s).to eq( + "http://example.com:80/" + ) + expect(Addressable::URI.normalized_encode(@uri, Addressable::URI).to_s).to be === + "http://example.com:80/" + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com:8080/'" do + before do + @uri = Addressable::URI.parse("http://example.com:8080/") + end + + it "should use the 'http' scheme" do + expect(@uri.scheme).to eq("http") + end + + it "should have an authority segment of 'example.com:8080'" do + expect(@uri.authority).to eq("example.com:8080") + end + + it "should have a host of 'example.com'" do + expect(@uri.host).to eq("example.com") + end + + it "should have no username" do + expect(@uri.user).to eq(nil) + end + + it "should have no password" do + expect(@uri.password).to eq(nil) + end + + it "should use port 8080" do + expect(@uri.inferred_port).to eq(8080) + end + + it "should have explicit port 8080" do + expect(@uri.port).to eq(8080) + end + + it "should have default port 80" do + expect(@uri.default_port).to eq(80) + end + + it "should have a path of '/'" do + expect(@uri.path).to eq("/") + end + + it "should have no query string" do + expect(@uri.query).to eq(nil) + end + + it "should have no fragment" do + expect(@uri.fragment).to eq(nil) + end + + it "should be considered absolute" do + expect(@uri).to be_absolute + end + + it "should not be considered relative" do + expect(@uri).not_to be_relative + end + + it "should be exactly equal to http://example.com:8080/" do + expect(@uri.eql?(Addressable::URI.parse( + "http://example.com:8080/"))).to eq(true) + end + + it "should have a route of 'http://example.com:8080/' from " + + "'http://example.com/path/to/'" do + expect(@uri.route_from("http://example.com/path/to/")).to eq( + Addressable::URI.parse("http://example.com:8080/") + ) + end + + it "should have a route of 'http://example.com:8080/' from " + + "'http://example.com:80/path/to/'" do + expect(@uri.route_from("http://example.com:80/path/to/")).to eq( + Addressable::URI.parse("http://example.com:8080/") + ) + end + + it "should have a route of '../../' from " + + "'http://example.com:8080/path/to/'" do + expect(@uri.route_from("http://example.com:8080/path/to/")).to eq( + Addressable::URI.parse("../../") + ) + end + + it "should have a route of 'http://example.com:8080/' from " + + "'http://user:pass@example.com/path/to/'" do + expect(@uri.route_from("http://user:pass@example.com/path/to/")).to eq( + Addressable::URI.parse("http://example.com:8080/") + ) + end + + it "should correctly convert to a hash" do + expect(@uri.to_hash).to eq({ + :scheme => "http", + :user => nil, + :password => nil, + :host => "example.com", + :port => 8080, + :path => "/", + :query => nil, + :fragment => nil + }) + end + + it "should be identical to its duplicate" do + expect(@uri).to eq(@uri.dup) + end + + it "should have an origin of 'http://example.com:8080'" do + expect(@uri.origin).to eq('http://example.com:8080') + end + + it "should not change if encoded with the normalizing algorithm" do + expect(Addressable::URI.normalized_encode(@uri).to_s).to eq( + "http://example.com:8080/" + ) + expect(Addressable::URI.normalized_encode(@uri, Addressable::URI).to_s).to be === + "http://example.com:8080/" + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com:%38%30/'" do + before do + @uri = Addressable::URI.parse("http://example.com:%38%30/") + end + + it "should have the correct port" do + expect(@uri.port).to eq(80) + end + + it "should not be considered to be in normal form" do + expect(@uri.normalize).not_to be_eql(@uri) + end + + it "should normalize to 'http://example.com/'" do + expect(@uri.normalize.to_s).to eq("http://example.com/") + end + + it "should have an origin of 'http://example.com'" do + expect(@uri.origin).to eq('http://example.com') + end +end + +describe Addressable::URI, "when parsed with empty port" do + subject(:uri) do + Addressable::URI.parse("//example.com:") + end + + it "should not infer a port" do + expect(uri.port).to be(nil) + end + + it "should have a site value of '//example.com'" do + expect(uri.site).to eq("//example.com") + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/%2E/'" do + before do + @uri = Addressable::URI.parse("http://example.com/%2E/") + end + + it "should be considered to be in normal form" do + skip( + 'path segment normalization should happen before ' + + 'percent escaping normalization' + ) + @uri.normalize.should be_eql(@uri) + end + + it "should normalize to 'http://example.com/%2E/'" do + skip( + 'path segment normalization should happen before ' + + 'percent escaping normalization' + ) + expect(@uri.normalize).to eq("http://example.com/%2E/") + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/..'" do + before do + @uri = Addressable::URI.parse("http://example.com/..") + end + + it "should have the correct port" do + expect(@uri.inferred_port).to eq(80) + end + + it "should not be considered to be in normal form" do + expect(@uri.normalize).not_to be_eql(@uri) + end + + it "should normalize to 'http://example.com/'" do + expect(@uri.normalize.to_s).to eq("http://example.com/") + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/../..'" do + before do + @uri = Addressable::URI.parse("http://example.com/../..") + end + + it "should have the correct port" do + expect(@uri.inferred_port).to eq(80) + end + + it "should not be considered to be in normal form" do + expect(@uri.normalize).not_to be_eql(@uri) + end + + it "should normalize to 'http://example.com/'" do + expect(@uri.normalize.to_s).to eq("http://example.com/") + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/path(/..'" do + before do + @uri = Addressable::URI.parse("http://example.com/path(/..") + end + + it "should have the correct port" do + expect(@uri.inferred_port).to eq(80) + end + + it "should not be considered to be in normal form" do + expect(@uri.normalize).not_to be_eql(@uri) + end + + it "should normalize to 'http://example.com/'" do + expect(@uri.normalize.to_s).to eq("http://example.com/") + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/(path)/..'" do + before do + @uri = Addressable::URI.parse("http://example.com/(path)/..") + end + + it "should have the correct port" do + expect(@uri.inferred_port).to eq(80) + end + + it "should not be considered to be in normal form" do + expect(@uri.normalize).not_to be_eql(@uri) + end + + it "should normalize to 'http://example.com/'" do + expect(@uri.normalize.to_s).to eq("http://example.com/") + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/path(/../'" do + before do + @uri = Addressable::URI.parse("http://example.com/path(/../") + end + + it "should have the correct port" do + expect(@uri.inferred_port).to eq(80) + end + + it "should not be considered to be in normal form" do + expect(@uri.normalize).not_to be_eql(@uri) + end + + it "should normalize to 'http://example.com/'" do + expect(@uri.normalize.to_s).to eq("http://example.com/") + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/(path)/../'" do + before do + @uri = Addressable::URI.parse("http://example.com/(path)/../") + end + + it "should have the correct port" do + expect(@uri.inferred_port).to eq(80) + end + + it "should not be considered to be in normal form" do + expect(@uri.normalize).not_to be_eql(@uri) + end + + it "should normalize to 'http://example.com/'" do + expect(@uri.normalize.to_s).to eq("http://example.com/") + end +end + +describe Addressable::URI, "when parsed from " + + "'/..//example.com'" do + before do + @uri = Addressable::URI.parse("/..//example.com") + end + + it "should become invalid when normalized" do + expect do + @uri.normalize + end.to raise_error(Addressable::URI::InvalidURIError, /authority/) + end + + it "should have a path of '/..//example.com'" do + expect(@uri.path).to eq("/..//example.com") + end +end + +describe Addressable::URI, "when parsed from '/a/b/c/./../../g'" do + before do + @uri = Addressable::URI.parse("/a/b/c/./../../g") + end + + it "should not be considered to be in normal form" do + expect(@uri.normalize).not_to be_eql(@uri) + end + + # Section 5.2.4 of RFC 3986 + it "should normalize to '/a/g'" do + expect(@uri.normalize.to_s).to eq("/a/g") + end +end + +describe Addressable::URI, "when parsed from 'mid/content=5/../6'" do + before do + @uri = Addressable::URI.parse("mid/content=5/../6") + end + + it "should not be considered to be in normal form" do + expect(@uri.normalize).not_to be_eql(@uri) + end + + # Section 5.2.4 of RFC 3986 + it "should normalize to 'mid/6'" do + expect(@uri.normalize.to_s).to eq("mid/6") + end +end + +describe Addressable::URI, "when parsed from " + + "'http://www.example.com///../'" do + before do + @uri = Addressable::URI.parse('http://www.example.com///../') + end + + it "should not be considered to be in normal form" do + expect(@uri.normalize).not_to be_eql(@uri) + end + + it "should normalize to 'http://www.example.com//'" do + expect(@uri.normalize.to_s).to eq("http://www.example.com//") + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/path/to/resource/'" do + before do + @uri = Addressable::URI.parse("http://example.com/path/to/resource/") + end + + it "should use the 'http' scheme" do + expect(@uri.scheme).to eq("http") + end + + it "should have an authority segment of 'example.com'" do + expect(@uri.authority).to eq("example.com") + end + + it "should have a host of 'example.com'" do + expect(@uri.host).to eq("example.com") + end + + it "should have no username" do + expect(@uri.user).to eq(nil) + end + + it "should have no password" do + expect(@uri.password).to eq(nil) + end + + it "should use port 80" do + expect(@uri.inferred_port).to eq(80) + end + + it "should have a path of '/path/to/resource/'" do + expect(@uri.path).to eq("/path/to/resource/") + end + + it "should have no query string" do + expect(@uri.query).to eq(nil) + end + + it "should have no fragment" do + expect(@uri.fragment).to eq(nil) + end + + it "should be considered absolute" do + expect(@uri).to be_absolute + end + + it "should not be considered relative" do + expect(@uri).not_to be_relative + end + + it "should be exactly equal to http://example.com:8080/" do + expect(@uri.eql?(Addressable::URI.parse( + "http://example.com/path/to/resource/"))).to eq(true) + end + + it "should have a route of 'resource/' from " + + "'http://example.com/path/to/'" do + expect(@uri.route_from("http://example.com/path/to/")).to eq( + Addressable::URI.parse("resource/") + ) + end + + it "should have a route of '../' from " + + "'http://example.com/path/to/resource/sub'" do + expect(@uri.route_from("http://example.com/path/to/resource/sub")).to eq( + Addressable::URI.parse("../") + ) + end + + + it "should have a route of 'resource/' from " + + "'http://example.com/path/to/another'" do + expect(@uri.route_from("http://example.com/path/to/another")).to eq( + Addressable::URI.parse("resource/") + ) + end + + it "should have a route of 'resource/' from " + + "'http://example.com/path/to/res'" do + expect(@uri.route_from("http://example.com/path/to/res")).to eq( + Addressable::URI.parse("resource/") + ) + end + + it "should have a route of 'resource/' from " + + "'http://example.com:80/path/to/'" do + expect(@uri.route_from("http://example.com:80/path/to/")).to eq( + Addressable::URI.parse("resource/") + ) + end + + it "should have a route of 'http://example.com/path/to/' from " + + "'http://example.com:8080/path/to/'" do + expect(@uri.route_from("http://example.com:8080/path/to/")).to eq( + Addressable::URI.parse("http://example.com/path/to/resource/") + ) + end + + it "should have a route of 'http://example.com/path/to/' from " + + "'http://user:pass@example.com/path/to/'" do + expect(@uri.route_from("http://user:pass@example.com/path/to/")).to eq( + Addressable::URI.parse("http://example.com/path/to/resource/") + ) + end + + it "should have a route of '../../path/to/resource/' from " + + "'http://example.com/to/resource/'" do + expect(@uri.route_from("http://example.com/to/resource/")).to eq( + Addressable::URI.parse("../../path/to/resource/") + ) + end + + it "should correctly convert to a hash" do + expect(@uri.to_hash).to eq({ + :scheme => "http", + :user => nil, + :password => nil, + :host => "example.com", + :port => nil, + :path => "/path/to/resource/", + :query => nil, + :fragment => nil + }) + end + + it "should be identical to its duplicate" do + expect(@uri).to eq(@uri.dup) + end +end + +describe Addressable::URI, "when parsed from " + + "'relative/path/to/resource'" do + before do + @uri = Addressable::URI.parse("relative/path/to/resource") + end + + it "should not have a scheme" do + expect(@uri.scheme).to eq(nil) + end + + it "should not be considered ip-based" do + expect(@uri).not_to be_ip_based + end + + it "should not have an authority segment" do + expect(@uri.authority).to eq(nil) + end + + it "should not have a host" do + expect(@uri.host).to eq(nil) + end + + it "should have no username" do + expect(@uri.user).to eq(nil) + end + + it "should have no password" do + expect(@uri.password).to eq(nil) + end + + it "should not have a port" do + expect(@uri.port).to eq(nil) + end + + it "should have a path of 'relative/path/to/resource'" do + expect(@uri.path).to eq("relative/path/to/resource") + end + + it "should have no query string" do + expect(@uri.query).to eq(nil) + end + + it "should have no fragment" do + expect(@uri.fragment).to eq(nil) + end + + it "should not be considered absolute" do + expect(@uri).not_to be_absolute + end + + it "should be considered relative" do + expect(@uri).to be_relative + end + + it "should raise an error if routing is attempted" do + expect do + @uri.route_to("http://example.com/") + end.to raise_error(ArgumentError, /relative\/path\/to\/resource/) + expect do + @uri.route_from("http://example.com/") + end.to raise_error(ArgumentError, /relative\/path\/to\/resource/) + end + + it "when joined with 'another/relative/path' should be " + + "'relative/path/to/another/relative/path'" do + expect(@uri.join('another/relative/path')).to eq( + Addressable::URI.parse("relative/path/to/another/relative/path") + ) + end + + it "should be identical to its duplicate" do + expect(@uri).to eq(@uri.dup) + end +end + +describe Addressable::URI, "when parsed from " + + "'relative_path_with_no_slashes'" do + before do + @uri = Addressable::URI.parse("relative_path_with_no_slashes") + end + + it "should not have a scheme" do + expect(@uri.scheme).to eq(nil) + end + + it "should not be considered ip-based" do + expect(@uri).not_to be_ip_based + end + + it "should not have an authority segment" do + expect(@uri.authority).to eq(nil) + end + + it "should not have a host" do + expect(@uri.host).to eq(nil) + end + + it "should have no username" do + expect(@uri.user).to eq(nil) + end + + it "should have no password" do + expect(@uri.password).to eq(nil) + end + + it "should not have a port" do + expect(@uri.port).to eq(nil) + end + + it "should have a path of 'relative_path_with_no_slashes'" do + expect(@uri.path).to eq("relative_path_with_no_slashes") + end + + it "should have no query string" do + expect(@uri.query).to eq(nil) + end + + it "should have no fragment" do + expect(@uri.fragment).to eq(nil) + end + + it "should not be considered absolute" do + expect(@uri).not_to be_absolute + end + + it "should be considered relative" do + expect(@uri).to be_relative + end + + it "when joined with 'another_relative_path' should be " + + "'another_relative_path'" do + expect(@uri.join('another_relative_path')).to eq( + Addressable::URI.parse("another_relative_path") + ) + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/file.txt'" do + before do + @uri = Addressable::URI.parse("http://example.com/file.txt") + end + + it "should have a scheme of 'http'" do + expect(@uri.scheme).to eq("http") + end + + it "should have an authority segment of 'example.com'" do + expect(@uri.authority).to eq("example.com") + end + + it "should have a host of 'example.com'" do + expect(@uri.host).to eq("example.com") + end + + it "should have no username" do + expect(@uri.user).to eq(nil) + end + + it "should have no password" do + expect(@uri.password).to eq(nil) + end + + it "should use port 80" do + expect(@uri.inferred_port).to eq(80) + end + + it "should have a path of '/file.txt'" do + expect(@uri.path).to eq("/file.txt") + end + + it "should have a basename of 'file.txt'" do + expect(@uri.basename).to eq("file.txt") + end + + it "should have an extname of '.txt'" do + expect(@uri.extname).to eq(".txt") + end + + it "should have no query string" do + expect(@uri.query).to eq(nil) + end + + it "should have no fragment" do + expect(@uri.fragment).to eq(nil) + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/file.txt;parameter'" do + before do + @uri = Addressable::URI.parse("http://example.com/file.txt;parameter") + end + + it "should have a scheme of 'http'" do + expect(@uri.scheme).to eq("http") + end + + it "should have an authority segment of 'example.com'" do + expect(@uri.authority).to eq("example.com") + end + + it "should have a host of 'example.com'" do + expect(@uri.host).to eq("example.com") + end + + it "should have no username" do + expect(@uri.user).to eq(nil) + end + + it "should have no password" do + expect(@uri.password).to eq(nil) + end + + it "should use port 80" do + expect(@uri.inferred_port).to eq(80) + end + + it "should have a path of '/file.txt;parameter'" do + expect(@uri.path).to eq("/file.txt;parameter") + end + + it "should have a basename of 'file.txt'" do + expect(@uri.basename).to eq("file.txt") + end + + it "should have an extname of '.txt'" do + expect(@uri.extname).to eq(".txt") + end + + it "should have no query string" do + expect(@uri.query).to eq(nil) + end + + it "should have no fragment" do + expect(@uri.fragment).to eq(nil) + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/file.txt;x=y'" do + before do + @uri = Addressable::URI.parse("http://example.com/file.txt;x=y") + end + + it "should have a scheme of 'http'" do + expect(@uri.scheme).to eq("http") + end + + it "should have a scheme of 'http'" do + expect(@uri.scheme).to eq("http") + end + + it "should have an authority segment of 'example.com'" do + expect(@uri.authority).to eq("example.com") + end + + it "should have a host of 'example.com'" do + expect(@uri.host).to eq("example.com") + end + + it "should have no username" do + expect(@uri.user).to eq(nil) + end + + it "should have no password" do + expect(@uri.password).to eq(nil) + end + + it "should use port 80" do + expect(@uri.inferred_port).to eq(80) + end + + it "should have a path of '/file.txt;x=y'" do + expect(@uri.path).to eq("/file.txt;x=y") + end + + it "should have an extname of '.txt'" do + expect(@uri.extname).to eq(".txt") + end + + it "should have no query string" do + expect(@uri.query).to eq(nil) + end + + it "should have no fragment" do + expect(@uri.fragment).to eq(nil) + end + + it "should be considered to be in normal form" do + expect(@uri.normalize).to be_eql(@uri) + end +end + +describe Addressable::URI, "when parsed from " + + "'svn+ssh://developername@rubyforge.org/var/svn/project'" do + before do + @uri = Addressable::URI.parse( + "svn+ssh://developername@rubyforge.org/var/svn/project" + ) + end + + it "should have a scheme of 'svn+ssh'" do + expect(@uri.scheme).to eq("svn+ssh") + end + + it "should be considered to be ip-based" do + expect(@uri).to be_ip_based + end + + it "should have a path of '/var/svn/project'" do + expect(@uri.path).to eq("/var/svn/project") + end + + it "should have a username of 'developername'" do + expect(@uri.user).to eq("developername") + end + + it "should have no password" do + expect(@uri.password).to eq(nil) + end + + it "should be considered to be in normal form" do + expect(@uri.normalize).to be_eql(@uri) + end +end + +describe Addressable::URI, "when parsed from " + + "'ssh+svn://developername@RUBYFORGE.ORG/var/svn/project'" do + before do + @uri = Addressable::URI.parse( + "ssh+svn://developername@RUBYFORGE.ORG/var/svn/project" + ) + end + + it "should have a scheme of 'ssh+svn'" do + expect(@uri.scheme).to eq("ssh+svn") + end + + it "should have a normalized scheme of 'svn+ssh'" do + expect(@uri.normalized_scheme).to eq("svn+ssh") + end + + it "should have a normalized site of 'svn+ssh'" do + expect(@uri.normalized_site).to eq("svn+ssh://developername@rubyforge.org") + end + + it "should not be considered to be ip-based" do + expect(@uri).not_to be_ip_based + end + + it "should have a path of '/var/svn/project'" do + expect(@uri.path).to eq("/var/svn/project") + end + + it "should have a username of 'developername'" do + expect(@uri.user).to eq("developername") + end + + it "should have no password" do + expect(@uri.password).to eq(nil) + end + + it "should not be considered to be in normal form" do + expect(@uri.normalize).not_to be_eql(@uri) + end +end + +describe Addressable::URI, "when parsed from " + + "'mailto:user@example.com'" do + before do + @uri = Addressable::URI.parse("mailto:user@example.com") + end + + it "should have a scheme of 'mailto'" do + expect(@uri.scheme).to eq("mailto") + end + + it "should not be considered to be ip-based" do + expect(@uri).not_to be_ip_based + end + + it "should have a path of 'user@example.com'" do + expect(@uri.path).to eq("user@example.com") + end + + it "should have no user" do + expect(@uri.user).to eq(nil) + end + + it "should be considered to be in normal form" do + expect(@uri.normalize).to be_eql(@uri) + end +end + +describe Addressable::URI, "when parsed from " + + "'tag:example.com,2006-08-18:/path/to/something'" do + before do + @uri = Addressable::URI.parse( + "tag:example.com,2006-08-18:/path/to/something") + end + + it "should have a scheme of 'tag'" do + expect(@uri.scheme).to eq("tag") + end + + it "should be considered to be ip-based" do + expect(@uri).not_to be_ip_based + end + + it "should have a path of " + + "'example.com,2006-08-18:/path/to/something'" do + expect(@uri.path).to eq("example.com,2006-08-18:/path/to/something") + end + + it "should have no user" do + expect(@uri.user).to eq(nil) + end + + it "should be considered to be in normal form" do + expect(@uri.normalize).to be_eql(@uri) + end + + it "should have a 'null' origin" do + expect(@uri.origin).to eq('null') + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/x;y/'" do + before do + @uri = Addressable::URI.parse("http://example.com/x;y/") + end + + it "should be considered to be in normal form" do + expect(@uri.normalize).to be_eql(@uri) + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/?x=1&y=2'" do + before do + @uri = Addressable::URI.parse("http://example.com/?x=1&y=2") + end + + it "should be considered to be in normal form" do + expect(@uri.normalize).to be_eql(@uri) + end +end + +describe Addressable::URI, "when parsed from " + + "'view-source:http://example.com/'" do + before do + @uri = Addressable::URI.parse("view-source:http://example.com/") + end + + it "should have a scheme of 'view-source'" do + expect(@uri.scheme).to eq("view-source") + end + + it "should have a path of 'http://example.com/'" do + expect(@uri.path).to eq("http://example.com/") + end + + it "should be considered to be in normal form" do + expect(@uri.normalize).to be_eql(@uri) + end + + it "should have a 'null' origin" do + expect(@uri.origin).to eq('null') + end +end + +describe Addressable::URI, "when parsed from " + + "'http://user:pass@example.com/path/to/resource?query=x#fragment'" do + before do + @uri = Addressable::URI.parse( + "http://user:pass@example.com/path/to/resource?query=x#fragment") + end + + it "should use the 'http' scheme" do + expect(@uri.scheme).to eq("http") + end + + it "should have an authority segment of 'user:pass@example.com'" do + expect(@uri.authority).to eq("user:pass@example.com") + end + + it "should have a username of 'user'" do + expect(@uri.user).to eq("user") + end + + it "should have a password of 'pass'" do + expect(@uri.password).to eq("pass") + end + + it "should have a host of 'example.com'" do + expect(@uri.host).to eq("example.com") + end + + it "should use port 80" do + expect(@uri.inferred_port).to eq(80) + end + + it "should have a path of '/path/to/resource'" do + expect(@uri.path).to eq("/path/to/resource") + end + + it "should have a query string of 'query=x'" do + expect(@uri.query).to eq("query=x") + end + + it "should have a fragment of 'fragment'" do + expect(@uri.fragment).to eq("fragment") + end + + it "should be considered to be in normal form" do + expect(@uri.normalize).to be_eql(@uri) + end + + it "should have a route of '../../' to " + + "'http://user:pass@example.com/path/'" do + expect(@uri.route_to("http://user:pass@example.com/path/")).to eq( + Addressable::URI.parse("../../") + ) + end + + it "should have a route of 'to/resource?query=x#fragment' " + + "from 'http://user:pass@example.com/path/'" do + expect(@uri.route_from("http://user:pass@example.com/path/")).to eq( + Addressable::URI.parse("to/resource?query=x#fragment") + ) + end + + it "should have a route of '?query=x#fragment' " + + "from 'http://user:pass@example.com/path/to/resource'" do + expect(@uri.route_from("http://user:pass@example.com/path/to/resource")).to eq( + Addressable::URI.parse("?query=x#fragment") + ) + end + + it "should have a route of '#fragment' " + + "from 'http://user:pass@example.com/path/to/resource?query=x'" do + expect(@uri.route_from( + "http://user:pass@example.com/path/to/resource?query=x")).to eq( + Addressable::URI.parse("#fragment") + ) + end + + it "should have a route of '#fragment' from " + + "'http://user:pass@example.com/path/to/resource?query=x#fragment'" do + expect(@uri.route_from( + "http://user:pass@example.com/path/to/resource?query=x#fragment" + )).to eq(Addressable::URI.parse("#fragment")) + end + + it "should have a route of 'http://elsewhere.com/' to " + + "'http://elsewhere.com/'" do + expect(@uri.route_to("http://elsewhere.com/")).to eq( + Addressable::URI.parse("http://elsewhere.com/") + ) + end + + it "should have a route of " + + "'http://user:pass@example.com/path/to/resource?query=x#fragment' " + + "from 'http://example.com/path/to/'" do + expect(@uri.route_from("http://elsewhere.com/path/to/")).to eq( + Addressable::URI.parse( + "http://user:pass@example.com/path/to/resource?query=x#fragment") + ) + end + + it "should have the correct scheme after assignment" do + @uri.scheme = "ftp" + expect(@uri.scheme).to eq("ftp") + expect(@uri.to_s).to eq( + "ftp://user:pass@example.com/path/to/resource?query=x#fragment" + ) + expect(@uri.to_str).to eq( + "ftp://user:pass@example.com/path/to/resource?query=x#fragment" + ) + end + + it "should have the correct site segment after assignment" do + @uri.site = "https://newuser:newpass@example.com:443" + expect(@uri.scheme).to eq("https") + expect(@uri.authority).to eq("newuser:newpass@example.com:443") + expect(@uri.user).to eq("newuser") + expect(@uri.password).to eq("newpass") + expect(@uri.userinfo).to eq("newuser:newpass") + expect(@uri.normalized_userinfo).to eq("newuser:newpass") + expect(@uri.host).to eq("example.com") + expect(@uri.port).to eq(443) + expect(@uri.inferred_port).to eq(443) + expect(@uri.to_s).to eq( + "https://newuser:newpass@example.com:443" + + "/path/to/resource?query=x#fragment" + ) + end + + it "should have the correct authority segment after assignment" do + @uri.authority = "newuser:newpass@example.com:80" + expect(@uri.authority).to eq("newuser:newpass@example.com:80") + expect(@uri.user).to eq("newuser") + expect(@uri.password).to eq("newpass") + expect(@uri.userinfo).to eq("newuser:newpass") + expect(@uri.normalized_userinfo).to eq("newuser:newpass") + expect(@uri.host).to eq("example.com") + expect(@uri.port).to eq(80) + expect(@uri.inferred_port).to eq(80) + expect(@uri.to_s).to eq( + "http://newuser:newpass@example.com:80" + + "/path/to/resource?query=x#fragment" + ) + end + + it "should have the correct userinfo segment after assignment" do + @uri.userinfo = "newuser:newpass" + expect(@uri.userinfo).to eq("newuser:newpass") + expect(@uri.authority).to eq("newuser:newpass@example.com") + expect(@uri.user).to eq("newuser") + expect(@uri.password).to eq("newpass") + expect(@uri.host).to eq("example.com") + expect(@uri.port).to eq(nil) + expect(@uri.inferred_port).to eq(80) + expect(@uri.to_s).to eq( + "http://newuser:newpass@example.com" + + "/path/to/resource?query=x#fragment" + ) + end + + it "should have the correct username after assignment" do + @uri.user = "newuser" + expect(@uri.user).to eq("newuser") + expect(@uri.authority).to eq("newuser:pass@example.com") + end + + it "should have the correct password after assignment" do + @uri.password = "newpass" + expect(@uri.password).to eq("newpass") + expect(@uri.authority).to eq("user:newpass@example.com") + end + + it "should have the correct host after assignment" do + @uri.host = "newexample.com" + expect(@uri.host).to eq("newexample.com") + expect(@uri.authority).to eq("user:pass@newexample.com") + end + + it "should have the correct host after assignment" do + @uri.hostname = "newexample.com" + expect(@uri.host).to eq("newexample.com") + expect(@uri.hostname).to eq("newexample.com") + expect(@uri.authority).to eq("user:pass@newexample.com") + end + + it "should raise an error if assigning a bogus object to the hostname" do + expect do + @uri.hostname = Object.new + end.to raise_error(TypeError) + end + + it "should have the correct port after assignment" do + @uri.port = 8080 + expect(@uri.port).to eq(8080) + expect(@uri.authority).to eq("user:pass@example.com:8080") + end + + it "should have the correct origin after assignment" do + @uri.origin = "http://newexample.com" + expect(@uri.host).to eq("newexample.com") + expect(@uri.authority).to eq("newexample.com") + end + + it "should have the correct path after assignment" do + @uri.path = "/newpath/to/resource" + expect(@uri.path).to eq("/newpath/to/resource") + expect(@uri.to_s).to eq( + "http://user:pass@example.com/newpath/to/resource?query=x#fragment" + ) + end + + it "should have the correct scheme and authority after nil assignment" do + @uri.site = nil + expect(@uri.scheme).to eq(nil) + expect(@uri.authority).to eq(nil) + expect(@uri.to_s).to eq("/path/to/resource?query=x#fragment") + end + + it "should have the correct scheme and authority after assignment" do + @uri.site = "file://" + expect(@uri.scheme).to eq("file") + expect(@uri.authority).to eq("") + expect(@uri.to_s).to eq("file:///path/to/resource?query=x#fragment") + end + + it "should have the correct path after nil assignment" do + @uri.path = nil + expect(@uri.path).to eq("") + expect(@uri.to_s).to eq( + "http://user:pass@example.com?query=x#fragment" + ) + end + + it "should have the correct query string after assignment" do + @uri.query = "newquery=x" + expect(@uri.query).to eq("newquery=x") + expect(@uri.to_s).to eq( + "http://user:pass@example.com/path/to/resource?newquery=x#fragment" + ) + @uri.query = nil + expect(@uri.query).to eq(nil) + expect(@uri.to_s).to eq( + "http://user:pass@example.com/path/to/resource#fragment" + ) + end + + it "should have the correct query string after hash assignment" do + @uri.query_values = {"?uestion mark" => "=sign", "hello" => "g\xC3\xBCnther"} + expect(@uri.query.split("&")).to include("%3Fuestion%20mark=%3Dsign") + expect(@uri.query.split("&")).to include("hello=g%C3%BCnther") + expect(@uri.query_values).to eq({ + "?uestion mark" => "=sign", "hello" => "g\xC3\xBCnther" + }) + end + + it "should have the correct query string after flag hash assignment" do + @uri.query_values = {'flag?1' => nil, 'fl=ag2' => nil, 'flag3' => nil} + expect(@uri.query.split("&")).to include("flag%3F1") + expect(@uri.query.split("&")).to include("fl%3Dag2") + expect(@uri.query.split("&")).to include("flag3") + expect(@uri.query_values(Array).sort).to eq([["fl=ag2"], ["flag3"], ["flag?1"]]) + expect(@uri.query_values(Hash)).to eq({ + 'flag?1' => nil, 'fl=ag2' => nil, 'flag3' => nil + }) + end + + it "should raise an error if query values are set to a bogus type" do + expect do + @uri.query_values = "bogus" + end.to raise_error(TypeError) + end + + it "should have the correct fragment after assignment" do + @uri.fragment = "newfragment" + expect(@uri.fragment).to eq("newfragment") + expect(@uri.to_s).to eq( + "http://user:pass@example.com/path/to/resource?query=x#newfragment" + ) + + @uri.fragment = nil + expect(@uri.fragment).to eq(nil) + expect(@uri.to_s).to eq( + "http://user:pass@example.com/path/to/resource?query=x" + ) + end + + it "should have the correct values after a merge" do + expect(@uri.merge(:fragment => "newfragment").to_s).to eq( + "http://user:pass@example.com/path/to/resource?query=x#newfragment" + ) + end + + it "should have the correct values after a merge" do + expect(@uri.merge(:fragment => nil).to_s).to eq( + "http://user:pass@example.com/path/to/resource?query=x" + ) + end + + it "should have the correct values after a merge" do + expect(@uri.merge(:userinfo => "newuser:newpass").to_s).to eq( + "http://newuser:newpass@example.com/path/to/resource?query=x#fragment" + ) + end + + it "should have the correct values after a merge" do + expect(@uri.merge(:userinfo => nil).to_s).to eq( + "http://example.com/path/to/resource?query=x#fragment" + ) + end + + it "should have the correct values after a merge" do + expect(@uri.merge(:path => "newpath").to_s).to eq( + "http://user:pass@example.com/newpath?query=x#fragment" + ) + end + + it "should have the correct values after a merge" do + expect(@uri.merge(:port => "42", :path => "newpath", :query => "").to_s).to eq( + "http://user:pass@example.com:42/newpath?#fragment" + ) + end + + it "should have the correct values after a merge" do + expect(@uri.merge(:authority => "foo:bar@baz:42").to_s).to eq( + "http://foo:bar@baz:42/path/to/resource?query=x#fragment" + ) + # Ensure the operation was not destructive + expect(@uri.to_s).to eq( + "http://user:pass@example.com/path/to/resource?query=x#fragment" + ) + end + + it "should have the correct values after a destructive merge" do + @uri.merge!(:authority => "foo:bar@baz:42") + # Ensure the operation was destructive + expect(@uri.to_s).to eq( + "http://foo:bar@baz:42/path/to/resource?query=x#fragment" + ) + end + + it "should fail to merge with bogus values" do + expect do + @uri.merge(:port => "bogus") + end.to raise_error(Addressable::URI::InvalidURIError) + end + + it "should fail to merge with bogus values" do + expect do + @uri.merge(:authority => "bar@baz:bogus") + end.to raise_error(Addressable::URI::InvalidURIError) + end + + it "should fail to merge with bogus parameters" do + expect do + @uri.merge(42) + end.to raise_error(TypeError) + end + + it "should fail to merge with bogus parameters" do + expect do + @uri.merge("http://example.com/") + end.to raise_error(TypeError) + end + + it "should fail to merge with both authority and subcomponents" do + expect do + @uri.merge(:authority => "foo:bar@baz:42", :port => "42") + end.to raise_error(ArgumentError) + end + + it "should fail to merge with both userinfo and subcomponents" do + expect do + @uri.merge(:userinfo => "foo:bar", :user => "foo") + end.to raise_error(ArgumentError) + end + + it "should be identical to its duplicate" do + expect(@uri).to eq(@uri.dup) + end + + it "should have an origin of 'http://example.com'" do + expect(@uri.origin).to eq('http://example.com') + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/search?q=Q%26A'" do + + before do + @uri = Addressable::URI.parse("http://example.com/search?q=Q%26A") + end + + it "should have a query of 'q=Q%26A'" do + expect(@uri.query).to eq("q=Q%26A") + end + + it "should have query_values of {'q' => 'Q&A'}" do + expect(@uri.query_values).to eq({ 'q' => 'Q&A' }) + end + + it "should normalize to the original uri " + + "(with the ampersand properly percent-encoded)" do + expect(@uri.normalize.to_s).to eq("http://example.com/search?q=Q%26A") + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/?&x=b'" do + before do + @uri = Addressable::URI.parse("http://example.com/?&x=b") + end + + it "should have a query of '&x=b'" do + expect(@uri.query).to eq("&x=b") + end + + it "should have query_values of {'x' => 'b'}" do + expect(@uri.query_values).to eq({'x' => 'b'}) + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/?q='one;two'&x=1'" do + before do + @uri = Addressable::URI.parse("http://example.com/?q='one;two'&x=1") + end + + it "should have a query of 'q='one;two'&x=1'" do + expect(@uri.query).to eq("q='one;two'&x=1") + end + + it "should have query_values of {\"q\" => \"'one;two'\", \"x\" => \"1\"}" do + expect(@uri.query_values).to eq({"q" => "'one;two'", "x" => "1"}) + end + + it "should escape the ';' character when normalizing to avoid ambiguity " + + "with the W3C HTML 4.01 specification" do + # HTML 4.01 Section B.2.2 + expect(@uri.normalize.query).to eq("q='one%3Btwo'&x=1") + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/?&&x=b'" do + before do + @uri = Addressable::URI.parse("http://example.com/?&&x=b") + end + + it "should have a query of '&&x=b'" do + expect(@uri.query).to eq("&&x=b") + end + + it "should have query_values of {'x' => 'b'}" do + expect(@uri.query_values).to eq({'x' => 'b'}) + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/?q=a&&x=b'" do + before do + @uri = Addressable::URI.parse("http://example.com/?q=a&&x=b") + end + + it "should have a query of 'q=a&&x=b'" do + expect(@uri.query).to eq("q=a&&x=b") + end + + it "should have query_values of {'q' => 'a, 'x' => 'b'}" do + expect(@uri.query_values).to eq({'q' => 'a', 'x' => 'b'}) + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/?q&&x=b'" do + before do + @uri = Addressable::URI.parse("http://example.com/?q&&x=b") + end + + it "should have a query of 'q&&x=b'" do + expect(@uri.query).to eq("q&&x=b") + end + + it "should have query_values of {'q' => true, 'x' => 'b'}" do + expect(@uri.query_values).to eq({'q' => nil, 'x' => 'b'}) + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/?q=a+b'" do + before do + @uri = Addressable::URI.parse("http://example.com/?q=a+b") + end + + it "should have a query of 'q=a+b'" do + expect(@uri.query).to eq("q=a+b") + end + + it "should have query_values of {'q' => 'a b'}" do + expect(@uri.query_values).to eq({'q' => 'a b'}) + end + + it "should have a normalized query of 'q=a+b'" do + expect(@uri.normalized_query).to eq("q=a+b") + end +end + +describe Addressable::URI, "when parsed from 'https://example.com/?q=a+b'" do + before do + @uri = Addressable::URI.parse("https://example.com/?q=a+b") + end + + it "should have query_values of {'q' => 'a b'}" do + expect(@uri.query_values).to eq("q" => "a b") + end +end + +describe Addressable::URI, "when parsed from 'example.com?q=a+b'" do + before do + @uri = Addressable::URI.parse("example.com?q=a+b") + end + + it "should have query_values of {'q' => 'a b'}" do + expect(@uri.query_values).to eq("q" => "a b") + end +end + +describe Addressable::URI, "when parsed from 'mailto:?q=a+b'" do + before do + @uri = Addressable::URI.parse("mailto:?q=a+b") + end + + it "should have query_values of {'q' => 'a+b'}" do + expect(@uri.query_values).to eq("q" => "a+b") + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/?q=a%2bb'" do + before do + @uri = Addressable::URI.parse("http://example.com/?q=a%2bb") + end + + it "should have a query of 'q=a+b'" do + expect(@uri.query).to eq("q=a%2bb") + end + + it "should have query_values of {'q' => 'a+b'}" do + expect(@uri.query_values).to eq({'q' => 'a+b'}) + end + + it "should have a normalized query of 'q=a%2Bb'" do + expect(@uri.normalized_query).to eq("q=a%2Bb") + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/?v=%7E&w=%&x=%25&y=%2B&z=C%CC%A7'" do + before do + @uri = Addressable::URI.parse("http://example.com/?v=%7E&w=%&x=%25&y=%2B&z=C%CC%A7") + end + + it "should have a normalized query of 'v=~&w=%25&x=%25&y=%2B&z=%C3%87'" do + expect(@uri.normalized_query).to eq("v=~&w=%25&x=%25&y=%2B&z=%C3%87") + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/?v=%7E&w=%&x=%25&y=+&z=C%CC%A7'" do + before do + @uri = Addressable::URI.parse("http://example.com/?v=%7E&w=%&x=%25&y=+&z=C%CC%A7") + end + + it "should have a normalized query of 'v=~&w=%25&x=%25&y=+&z=%C3%87'" do + expect(@uri.normalized_query).to eq("v=~&w=%25&x=%25&y=+&z=%C3%87") + end +end + +describe Addressable::URI, "when parsed from 'http://example/?b=1&a=2&c=3'" do + before do + @uri = Addressable::URI.parse("http://example/?b=1&a=2&c=3") + end + + it "should have a sorted normalized query of 'a=2&b=1&c=3'" do + expect(@uri.normalized_query(:sorted)).to eq("a=2&b=1&c=3") + end +end + +describe Addressable::URI, "when parsed from 'http://example/?&a&&c&'" do + before do + @uri = Addressable::URI.parse("http://example/?&a&&c&") + end + + it "should have a compacted normalized query of 'a&c'" do + expect(@uri.normalized_query(:compacted)).to eq("a&c") + end +end + +describe Addressable::URI, "when parsed from 'http://example.com/?a=1&a=1'" do + before do + @uri = Addressable::URI.parse("http://example.com/?a=1&a=1") + end + + it "should have a compacted normalized query of 'a=1'" do + expect(@uri.normalized_query(:compacted)).to eq("a=1") + end +end + +describe Addressable::URI, "when parsed from 'http://example.com/?a=1&a=2'" do + before do + @uri = Addressable::URI.parse("http://example.com/?a=1&a=2") + end + + it "should have a compacted normalized query of 'a=1&a=2'" do + expect(@uri.normalized_query(:compacted)).to eq("a=1&a=2") + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/sound%2bvision'" do + before do + @uri = Addressable::URI.parse("http://example.com/sound%2bvision") + end + + it "should have a normalized path of '/sound+vision'" do + expect(@uri.normalized_path).to eq('/sound+vision') + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/?q='" do + before do + @uri = Addressable::URI.parse("http://example.com/?q=") + end + + it "should have a query of 'q='" do + expect(@uri.query).to eq("q=") + end + + it "should have query_values of {'q' => ''}" do + expect(@uri.query_values).to eq({'q' => ''}) + end +end + +describe Addressable::URI, "when parsed from " + + "'http://user@example.com'" do + before do + @uri = Addressable::URI.parse("http://user@example.com") + end + + it "should use the 'http' scheme" do + expect(@uri.scheme).to eq("http") + end + + it "should have a username of 'user'" do + expect(@uri.user).to eq("user") + end + + it "should have no password" do + expect(@uri.password).to eq(nil) + end + + it "should have a userinfo of 'user'" do + expect(@uri.userinfo).to eq("user") + end + + it "should have a normalized userinfo of 'user'" do + expect(@uri.normalized_userinfo).to eq("user") + end + + it "should have a host of 'example.com'" do + expect(@uri.host).to eq("example.com") + end + + it "should have default_port 80" do + expect(@uri.default_port).to eq(80) + end + + it "should use port 80" do + expect(@uri.inferred_port).to eq(80) + end + + it "should have the correct username after assignment" do + @uri.user = "newuser" + expect(@uri.user).to eq("newuser") + expect(@uri.password).to eq(nil) + expect(@uri.to_s).to eq("http://newuser@example.com") + end + + it "should have the correct password after assignment" do + @uri.password = "newpass" + expect(@uri.password).to eq("newpass") + expect(@uri.to_s).to eq("http://user:newpass@example.com") + end + + it "should have the correct userinfo segment after assignment" do + @uri.userinfo = "newuser:newpass" + expect(@uri.userinfo).to eq("newuser:newpass") + expect(@uri.user).to eq("newuser") + expect(@uri.password).to eq("newpass") + expect(@uri.host).to eq("example.com") + expect(@uri.port).to eq(nil) + expect(@uri.inferred_port).to eq(80) + expect(@uri.to_s).to eq("http://newuser:newpass@example.com") + end + + it "should have the correct userinfo segment after nil assignment" do + @uri.userinfo = nil + expect(@uri.userinfo).to eq(nil) + expect(@uri.user).to eq(nil) + expect(@uri.password).to eq(nil) + expect(@uri.host).to eq("example.com") + expect(@uri.port).to eq(nil) + expect(@uri.inferred_port).to eq(80) + expect(@uri.to_s).to eq("http://example.com") + end + + it "should have the correct authority segment after assignment" do + @uri.authority = "newuser@example.com" + expect(@uri.authority).to eq("newuser@example.com") + expect(@uri.user).to eq("newuser") + expect(@uri.password).to eq(nil) + expect(@uri.host).to eq("example.com") + expect(@uri.port).to eq(nil) + expect(@uri.inferred_port).to eq(80) + expect(@uri.to_s).to eq("http://newuser@example.com") + end + + it "should raise an error after nil assignment of authority segment" do + expect do + # This would create an invalid URI + @uri.authority = nil + end.to raise_error(Addressable::URI::InvalidURIError) + end +end + +describe Addressable::URI, "when parsed from " + + "'http://user:@example.com'" do + before do + @uri = Addressable::URI.parse("http://user:@example.com") + end + + it "should use the 'http' scheme" do + expect(@uri.scheme).to eq("http") + end + + it "should have a username of 'user'" do + expect(@uri.user).to eq("user") + end + + it "should have a password of ''" do + expect(@uri.password).to eq("") + end + + it "should have a normalized userinfo of 'user:'" do + expect(@uri.normalized_userinfo).to eq("user:") + end + + it "should have a host of 'example.com'" do + expect(@uri.host).to eq("example.com") + end + + it "should use port 80" do + expect(@uri.inferred_port).to eq(80) + end + + it "should have the correct username after assignment" do + @uri.user = "newuser" + expect(@uri.user).to eq("newuser") + expect(@uri.password).to eq("") + expect(@uri.to_s).to eq("http://newuser:@example.com") + end + + it "should have the correct password after assignment" do + @uri.password = "newpass" + expect(@uri.password).to eq("newpass") + expect(@uri.to_s).to eq("http://user:newpass@example.com") + end + + it "should have the correct authority segment after assignment" do + @uri.authority = "newuser:@example.com" + expect(@uri.authority).to eq("newuser:@example.com") + expect(@uri.user).to eq("newuser") + expect(@uri.password).to eq("") + expect(@uri.host).to eq("example.com") + expect(@uri.port).to eq(nil) + expect(@uri.inferred_port).to eq(80) + expect(@uri.to_s).to eq("http://newuser:@example.com") + end +end + +describe Addressable::URI, "when parsed from " + + "'http://:pass@example.com'" do + before do + @uri = Addressable::URI.parse("http://:pass@example.com") + end + + it "should use the 'http' scheme" do + expect(@uri.scheme).to eq("http") + end + + it "should have a username of ''" do + expect(@uri.user).to eq("") + end + + it "should have a password of 'pass'" do + expect(@uri.password).to eq("pass") + end + + it "should have a userinfo of ':pass'" do + expect(@uri.userinfo).to eq(":pass") + end + + it "should have a normalized userinfo of ':pass'" do + expect(@uri.normalized_userinfo).to eq(":pass") + end + + it "should have a host of 'example.com'" do + expect(@uri.host).to eq("example.com") + end + + it "should use port 80" do + expect(@uri.inferred_port).to eq(80) + end + + it "should have the correct username after assignment" do + @uri.user = "newuser" + expect(@uri.user).to eq("newuser") + expect(@uri.password).to eq("pass") + expect(@uri.to_s).to eq("http://newuser:pass@example.com") + end + + it "should have the correct password after assignment" do + @uri.password = "newpass" + expect(@uri.password).to eq("newpass") + expect(@uri.user).to eq("") + expect(@uri.to_s).to eq("http://:newpass@example.com") + end + + it "should have the correct authority segment after assignment" do + @uri.authority = ":newpass@example.com" + expect(@uri.authority).to eq(":newpass@example.com") + expect(@uri.user).to eq("") + expect(@uri.password).to eq("newpass") + expect(@uri.host).to eq("example.com") + expect(@uri.port).to eq(nil) + expect(@uri.inferred_port).to eq(80) + expect(@uri.to_s).to eq("http://:newpass@example.com") + end +end + +describe Addressable::URI, "when parsed from " + + "'http://:@example.com'" do + before do + @uri = Addressable::URI.parse("http://:@example.com") + end + + it "should use the 'http' scheme" do + expect(@uri.scheme).to eq("http") + end + + it "should have a username of ''" do + expect(@uri.user).to eq("") + end + + it "should have a password of ''" do + expect(@uri.password).to eq("") + end + + it "should have a normalized userinfo of nil" do + expect(@uri.normalized_userinfo).to eq(nil) + end + + it "should have a host of 'example.com'" do + expect(@uri.host).to eq("example.com") + end + + it "should use port 80" do + expect(@uri.inferred_port).to eq(80) + end + + it "should have the correct username after assignment" do + @uri.user = "newuser" + expect(@uri.user).to eq("newuser") + expect(@uri.password).to eq("") + expect(@uri.to_s).to eq("http://newuser:@example.com") + end + + it "should have the correct password after assignment" do + @uri.password = "newpass" + expect(@uri.password).to eq("newpass") + expect(@uri.user).to eq("") + expect(@uri.to_s).to eq("http://:newpass@example.com") + end + + it "should have the correct authority segment after assignment" do + @uri.authority = ":@newexample.com" + expect(@uri.authority).to eq(":@newexample.com") + expect(@uri.user).to eq("") + expect(@uri.password).to eq("") + expect(@uri.host).to eq("newexample.com") + expect(@uri.port).to eq(nil) + expect(@uri.inferred_port).to eq(80) + expect(@uri.to_s).to eq("http://:@newexample.com") + end +end + +describe Addressable::URI, "when parsed from " + + "'#example'" do + before do + @uri = Addressable::URI.parse("#example") + end + + it "should be considered relative" do + expect(@uri).to be_relative + end + + it "should have a host of nil" do + expect(@uri.host).to eq(nil) + end + + it "should have a site of nil" do + expect(@uri.site).to eq(nil) + end + + it "should have a normalized_site of nil" do + expect(@uri.normalized_site).to eq(nil) + end + + it "should have a path of ''" do + expect(@uri.path).to eq("") + end + + it "should have a query string of nil" do + expect(@uri.query).to eq(nil) + end + + it "should have a fragment of 'example'" do + expect(@uri.fragment).to eq("example") + end +end + +describe Addressable::URI, "when parsed from " + + "the network-path reference '//example.com/'" do + before do + @uri = Addressable::URI.parse("//example.com/") + end + + it "should be considered relative" do + expect(@uri).to be_relative + end + + it "should have a host of 'example.com'" do + expect(@uri.host).to eq("example.com") + end + + it "should have a path of '/'" do + expect(@uri.path).to eq("/") + end + + it "should raise an error if routing is attempted" do + expect do + @uri.route_to("http://example.com/") + end.to raise_error(ArgumentError, /\/\/example.com\//) + expect do + @uri.route_from("http://example.com/") + end.to raise_error(ArgumentError, /\/\/example.com\//) + end + + it "should have a 'null' origin" do + expect(@uri.origin).to eq('null') + end +end + +describe Addressable::URI, "when parsed from " + + "'feed://http://example.com/'" do + before do + @uri = Addressable::URI.parse("feed://http://example.com/") + end + + it "should have a host of 'http'" do + expect(@uri.host).to eq("http") + end + + it "should have a path of '//example.com/'" do + expect(@uri.path).to eq("//example.com/") + end +end + +describe Addressable::URI, "when parsed from " + + "'feed:http://example.com/'" do + before do + @uri = Addressable::URI.parse("feed:http://example.com/") + end + + it "should have a path of 'http://example.com/'" do + expect(@uri.path).to eq("http://example.com/") + end + + it "should normalize to 'http://example.com/'" do + expect(@uri.normalize.to_s).to eq("http://example.com/") + expect(@uri.normalize!.to_s).to eq("http://example.com/") + end + + it "should have a 'null' origin" do + expect(@uri.origin).to eq('null') + end +end + +describe Addressable::URI, "when parsed from " + + "'example://a/b/c/%7Bfoo%7D'" do + before do + @uri = Addressable::URI.parse("example://a/b/c/%7Bfoo%7D") + end + + # Section 6.2.2 of RFC 3986 + it "should be equivalent to eXAMPLE://a/./b/../b/%63/%7bfoo%7d" do + expect(@uri).to eq( + Addressable::URI.parse("eXAMPLE://a/./b/../b/%63/%7bfoo%7d") + ) + end + + it "should have an origin of 'example://a'" do + expect(@uri.origin).to eq('example://a') + end +end + +describe Addressable::URI, "when parsed from " + + "'http://example.com/indirect/path/./to/../resource/'" do + before do + @uri = Addressable::URI.parse( + "http://example.com/indirect/path/./to/../resource/") + end + + it "should use the 'http' scheme" do + expect(@uri.scheme).to eq("http") + end + + it "should have a host of 'example.com'" do + expect(@uri.host).to eq("example.com") + end + + it "should use port 80" do + expect(@uri.inferred_port).to eq(80) + end + + it "should have a path of '/indirect/path/./to/../resource/'" do + expect(@uri.path).to eq("/indirect/path/./to/../resource/") + end + + # Section 6.2.2.3 of RFC 3986 + it "should have a normalized path of '/indirect/path/resource/'" do + expect(@uri.normalize.path).to eq("/indirect/path/resource/") + expect(@uri.normalize!.path).to eq("/indirect/path/resource/") + end +end + +describe Addressable::URI, "when parsed from " + + "'http://under_score.example.com/'" do + it "should not cause an error" do + expect do + Addressable::URI.parse("http://under_score.example.com/") + end.not_to raise_error + end +end + +describe Addressable::URI, "when parsed from " + + "'./this:that'" do + before do + @uri = Addressable::URI.parse("./this:that") + end + + it "should be considered relative" do + expect(@uri).to be_relative + end + + it "should have no scheme" do + expect(@uri.scheme).to eq(nil) + end + + it "should have a 'null' origin" do + expect(@uri.origin).to eq('null') + end +end + +describe Addressable::URI, "when parsed from " + + "'this:that'" do + before do + @uri = Addressable::URI.parse("this:that") + end + + it "should be considered absolute" do + expect(@uri).to be_absolute + end + + it "should have a scheme of 'this'" do + expect(@uri.scheme).to eq("this") + end + + it "should have a 'null' origin" do + expect(@uri.origin).to eq('null') + end +end + +describe Addressable::URI, "when parsed from '?'" do + before do + @uri = Addressable::URI.parse("?") + end + + it "should normalize to ''" do + expect(@uri.normalize.to_s).to eq("") + end + + it "should have the correct return type" do + expect(@uri.query_values).to eq({}) + expect(@uri.query_values(Hash)).to eq({}) + expect(@uri.query_values(Array)).to eq([]) + end + + it "should have a 'null' origin" do + expect(@uri.origin).to eq('null') + end +end + +describe Addressable::URI, "when parsed from '?one=1&two=2&three=3'" do + before do + @uri = Addressable::URI.parse("?one=1&two=2&three=3") + end + + it "should have the correct query values" do + expect(@uri.query_values).to eq({"one" => "1", "two" => "2", "three" => "3"}) + end + + it "should raise an error for invalid return type values" do + expect do + @uri.query_values(Integer) + end.to raise_error(ArgumentError) + end + + it "should have the correct array query values" do + expect(@uri.query_values(Array)).to eq([ + ["one", "1"], ["two", "2"], ["three", "3"] + ]) + end + + it "should have a 'null' origin" do + expect(@uri.origin).to eq('null') + end +end + +describe Addressable::URI, "when parsed from '?one=1=uno&two=2=dos'" do + before do + @uri = Addressable::URI.parse("?one=1=uno&two=2=dos") + end + + it "should have the correct query values" do + expect(@uri.query_values).to eq({"one" => "1=uno", "two" => "2=dos"}) + end + + it "should have the correct array query values" do + expect(@uri.query_values(Array)).to eq([ + ["one", "1=uno"], ["two", "2=dos"] + ]) + end +end + +describe Addressable::URI, "when parsed from '?one[two][three]=four'" do + before do + @uri = Addressable::URI.parse("?one[two][three]=four") + end + + it "should have the correct query values" do + expect(@uri.query_values).to eq({"one[two][three]" => "four"}) + end + + it "should have the correct array query values" do + expect(@uri.query_values(Array)).to eq([ + ["one[two][three]", "four"] + ]) + end +end + +describe Addressable::URI, "when parsed from '?one.two.three=four'" do + before do + @uri = Addressable::URI.parse("?one.two.three=four") + end + + it "should have the correct query values" do + expect(@uri.query_values).to eq({ + "one.two.three" => "four" + }) + end + + it "should have the correct array query values" do + expect(@uri.query_values(Array)).to eq([ + ["one.two.three", "four"] + ]) + end +end + +describe Addressable::URI, "when parsed from " + + "'?one[two][three]=four&one[two][five]=six'" do + before do + @uri = Addressable::URI.parse("?one[two][three]=four&one[two][five]=six") + end + + it "should have the correct query values" do + expect(@uri.query_values).to eq({ + "one[two][three]" => "four", "one[two][five]" => "six" + }) + end + + it "should have the correct array query values" do + expect(@uri.query_values(Array)).to eq([ + ["one[two][three]", "four"], ["one[two][five]", "six"] + ]) + end +end + +describe Addressable::URI, "when parsed from " + + "'?one.two.three=four&one.two.five=six'" do + before do + @uri = Addressable::URI.parse("?one.two.three=four&one.two.five=six") + end + + it "should have the correct query values" do + expect(@uri.query_values).to eq({ + "one.two.three" => "four", "one.two.five" => "six" + }) + end + + it "should have the correct array query values" do + expect(@uri.query_values(Array)).to eq([ + ["one.two.three", "four"], ["one.two.five", "six"] + ]) + end +end + +describe Addressable::URI, "when parsed from " + + "'?one=two&one=three'" do + before do + @uri = Addressable::URI.parse( + "?one=two&one=three&one=four" + ) + end + + it "should have correct array query values" do + expect(@uri.query_values(Array)).to eq( + [['one', 'two'], ['one', 'three'], ['one', 'four']] + ) + end + + it "should have correct hash query values" do + skip("This is probably more desirable behavior.") + expect(@uri.query_values(Hash)).to eq( + {'one' => ['two', 'three', 'four']} + ) + end + + it "should handle assignment with keys of mixed type" do + @uri.query_values = @uri.query_values(Hash).merge({:one => 'three'}) + expect(@uri.query_values(Hash)).to eq({'one' => 'three'}) + end +end + +describe Addressable::URI, "when parsed from " + + "'?one[two][three][]=four&one[two][three][]=five'" do + before do + @uri = Addressable::URI.parse( + "?one[two][three][]=four&one[two][three][]=five" + ) + end + + it "should have correct query values" do + expect(@uri.query_values(Hash)).to eq({"one[two][three][]" => "five"}) + end + + it "should have correct array query values" do + expect(@uri.query_values(Array)).to eq([ + ["one[two][three][]", "four"], ["one[two][three][]", "five"] + ]) + end +end + +describe Addressable::URI, "when parsed from " + + "'?one[two][three][0]=four&one[two][three][1]=five'" do + before do + @uri = Addressable::URI.parse( + "?one[two][three][0]=four&one[two][three][1]=five" + ) + end + + it "should have the correct query values" do + expect(@uri.query_values).to eq({ + "one[two][three][0]" => "four", "one[two][three][1]" => "five" + }) + end +end + +describe Addressable::URI, "when parsed from " + + "'?one[two][three][1]=four&one[two][three][0]=five'" do + before do + @uri = Addressable::URI.parse( + "?one[two][three][1]=four&one[two][three][0]=five" + ) + end + + it "should have the correct query values" do + expect(@uri.query_values).to eq({ + "one[two][three][1]" => "four", "one[two][three][0]" => "five" + }) + end +end + +describe Addressable::URI, "when parsed from " + + "'?one[two][three][2]=four&one[two][three][1]=five'" do + before do + @uri = Addressable::URI.parse( + "?one[two][three][2]=four&one[two][three][1]=five" + ) + end + + it "should have the correct query values" do + expect(@uri.query_values).to eq({ + "one[two][three][2]" => "four", "one[two][three][1]" => "five" + }) + end +end + +describe Addressable::URI, "when parsed from " + + "'http://www.詹姆斯.com/'" do + before do + @uri = Addressable::URI.parse("http://www.詹姆斯.com/") + end + + it "should be equivalent to 'http://www.xn--8ws00zhy3a.com/'" do + expect(@uri).to eq( + Addressable::URI.parse("http://www.xn--8ws00zhy3a.com/") + ) + end + + it "should not have domain name encoded during normalization" do + expect(Addressable::URI.normalized_encode(@uri.to_s)).to eq( + "http://www.詹姆斯.com/" + ) + end + + it "should have an origin of 'http://www.xn--8ws00zhy3a.com'" do + expect(@uri.origin).to eq('http://www.xn--8ws00zhy3a.com') + end +end + +describe Addressable::URI, "when parsed from " + + "'http://www.詹姆斯.com/ some spaces /'" do + before do + @uri = Addressable::URI.parse("http://www.詹姆斯.com/ some spaces /") + end + + it "should be equivalent to " + + "'http://www.xn--8ws00zhy3a.com/%20some%20spaces%20/'" do + expect(@uri).to eq( + Addressable::URI.parse( + "http://www.xn--8ws00zhy3a.com/%20some%20spaces%20/") + ) + end + + it "should not have domain name encoded during normalization" do + expect(Addressable::URI.normalized_encode(@uri.to_s)).to eq( + "http://www.詹姆斯.com/%20some%20spaces%20/" + ) + end + + it "should have an origin of 'http://www.xn--8ws00zhy3a.com'" do + expect(@uri.origin).to eq('http://www.xn--8ws00zhy3a.com') + end +end + +describe Addressable::URI, "when parsed from " + + "'http://www.xn--8ws00zhy3a.com/'" do + before do + @uri = Addressable::URI.parse("http://www.xn--8ws00zhy3a.com/") + end + + it "should be displayed as http://www.詹姆斯.com/" do + expect(@uri.display_uri.to_s).to eq("http://www.詹姆斯.com/") + end + + it "should properly force the encoding" do + display_string = @uri.display_uri.to_str + expect(display_string).to eq("http://www.詹姆斯.com/") + if display_string.respond_to?(:encoding) + expect(display_string.encoding.to_s).to eq(Encoding::UTF_8.to_s) + end + end + + it "should have an origin of 'http://www.xn--8ws00zhy3a.com'" do + expect(@uri.origin).to eq('http://www.xn--8ws00zhy3a.com') + end +end + +describe Addressable::URI, "when parsed from " + + "'http://www.詹姆斯.com/atomtests/iri/詹.html'" do + before do + @uri = Addressable::URI.parse("http://www.詹姆斯.com/atomtests/iri/詹.html") + end + + it "should normalize to " + + "http://www.xn--8ws00zhy3a.com/atomtests/iri/%E8%A9%B9.html" do + expect(@uri.normalize.to_s).to eq( + "http://www.xn--8ws00zhy3a.com/atomtests/iri/%E8%A9%B9.html" + ) + expect(@uri.normalize!.to_s).to eq( + "http://www.xn--8ws00zhy3a.com/atomtests/iri/%E8%A9%B9.html" + ) + end +end + +describe Addressable::URI, "when parsed from a percent-encoded IRI" do + before do + @uri = Addressable::URI.parse( + "http://www.%E3%81%BB%E3%82%93%E3%81%A8%E3%81%86%E3%81%AB%E3%81%AA" + + "%E3%81%8C%E3%81%84%E3%82%8F%E3%81%91%E3%81%AE%E3%82%8F%E3%81%8B%E3" + + "%82%89%E3%81%AA%E3%81%84%E3%81%A9%E3%82%81%E3%81%84%E3%82%93%E3%82" + + "%81%E3%81%84%E3%81%AE%E3%82%89%E3%81%B9%E3%82%8B%E3%81%BE%E3%81%A0" + + "%E3%81%AA%E3%81%8C%E3%81%8F%E3%81%97%E3%81%AA%E3%81%84%E3%81%A8%E3" + + "%81%9F%E3%82%8A%E3%81%AA%E3%81%84.w3.mag.keio.ac.jp" + ) + end + + it "should normalize to something sane" do + expect(@uri.normalize.to_s).to eq( + "http://www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3f" + + "g11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp/" + ) + expect(@uri.normalize!.to_s).to eq( + "http://www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3f" + + "g11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp/" + ) + end + + it "should have the correct origin" do + expect(@uri.origin).to eq( + "http://www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3f" + + "g11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp" + ) + end +end + +describe Addressable::URI, "with a base uri of 'http://a/b/c/d;p?q'" do + before do + @uri = Addressable::URI.parse("http://a/b/c/d;p?q") + end + + # Section 5.4.1 of RFC 3986 + it "when joined with 'g:h' should resolve to g:h" do + expect((@uri + "g:h").to_s).to eq("g:h") + expect(Addressable::URI.join(@uri, "g:h").to_s).to eq("g:h") + end + + # Section 5.4.1 of RFC 3986 + it "when joined with 'g' should resolve to http://a/b/c/g" do + expect((@uri + "g").to_s).to eq("http://a/b/c/g") + expect(Addressable::URI.join(@uri.to_s, "g").to_s).to eq("http://a/b/c/g") + end + + # Section 5.4.1 of RFC 3986 + it "when joined with './g' should resolve to http://a/b/c/g" do + expect((@uri + "./g").to_s).to eq("http://a/b/c/g") + expect(Addressable::URI.join(@uri.to_s, "./g").to_s).to eq("http://a/b/c/g") + end + + # Section 5.4.1 of RFC 3986 + it "when joined with 'g/' should resolve to http://a/b/c/g/" do + expect((@uri + "g/").to_s).to eq("http://a/b/c/g/") + expect(Addressable::URI.join(@uri.to_s, "g/").to_s).to eq("http://a/b/c/g/") + end + + # Section 5.4.1 of RFC 3986 + it "when joined with '/g' should resolve to http://a/g" do + expect((@uri + "/g").to_s).to eq("http://a/g") + expect(Addressable::URI.join(@uri.to_s, "/g").to_s).to eq("http://a/g") + end + + # Section 5.4.1 of RFC 3986 + it "when joined with '//g' should resolve to http://g" do + expect((@uri + "//g").to_s).to eq("http://g") + expect(Addressable::URI.join(@uri.to_s, "//g").to_s).to eq("http://g") + end + + # Section 5.4.1 of RFC 3986 + it "when joined with '?y' should resolve to http://a/b/c/d;p?y" do + expect((@uri + "?y").to_s).to eq("http://a/b/c/d;p?y") + expect(Addressable::URI.join(@uri.to_s, "?y").to_s).to eq("http://a/b/c/d;p?y") + end + + # Section 5.4.1 of RFC 3986 + it "when joined with 'g?y' should resolve to http://a/b/c/g?y" do + expect((@uri + "g?y").to_s).to eq("http://a/b/c/g?y") + expect(Addressable::URI.join(@uri.to_s, "g?y").to_s).to eq("http://a/b/c/g?y") + end + + # Section 5.4.1 of RFC 3986 + it "when joined with '#s' should resolve to http://a/b/c/d;p?q#s" do + expect((@uri + "#s").to_s).to eq("http://a/b/c/d;p?q#s") + expect(Addressable::URI.join(@uri.to_s, "#s").to_s).to eq( + "http://a/b/c/d;p?q#s" + ) + end + + # Section 5.4.1 of RFC 3986 + it "when joined with 'g#s' should resolve to http://a/b/c/g#s" do + expect((@uri + "g#s").to_s).to eq("http://a/b/c/g#s") + expect(Addressable::URI.join(@uri.to_s, "g#s").to_s).to eq("http://a/b/c/g#s") + end + + # Section 5.4.1 of RFC 3986 + it "when joined with 'g?y#s' should resolve to http://a/b/c/g?y#s" do + expect((@uri + "g?y#s").to_s).to eq("http://a/b/c/g?y#s") + expect(Addressable::URI.join( + @uri.to_s, "g?y#s").to_s).to eq("http://a/b/c/g?y#s") + end + + # Section 5.4.1 of RFC 3986 + it "when joined with ';x' should resolve to http://a/b/c/;x" do + expect((@uri + ";x").to_s).to eq("http://a/b/c/;x") + expect(Addressable::URI.join(@uri.to_s, ";x").to_s).to eq("http://a/b/c/;x") + end + + # Section 5.4.1 of RFC 3986 + it "when joined with 'g;x' should resolve to http://a/b/c/g;x" do + expect((@uri + "g;x").to_s).to eq("http://a/b/c/g;x") + expect(Addressable::URI.join(@uri.to_s, "g;x").to_s).to eq("http://a/b/c/g;x") + end + + # Section 5.4.1 of RFC 3986 + it "when joined with 'g;x?y#s' should resolve to http://a/b/c/g;x?y#s" do + expect((@uri + "g;x?y#s").to_s).to eq("http://a/b/c/g;x?y#s") + expect(Addressable::URI.join( + @uri.to_s, "g;x?y#s").to_s).to eq("http://a/b/c/g;x?y#s") + end + + # Section 5.4.1 of RFC 3986 + it "when joined with '' should resolve to http://a/b/c/d;p?q" do + expect((@uri + "").to_s).to eq("http://a/b/c/d;p?q") + expect(Addressable::URI.join(@uri.to_s, "").to_s).to eq("http://a/b/c/d;p?q") + end + + # Section 5.4.1 of RFC 3986 + it "when joined with '.' should resolve to http://a/b/c/" do + expect((@uri + ".").to_s).to eq("http://a/b/c/") + expect(Addressable::URI.join(@uri.to_s, ".").to_s).to eq("http://a/b/c/") + end + + # Section 5.4.1 of RFC 3986 + it "when joined with './' should resolve to http://a/b/c/" do + expect((@uri + "./").to_s).to eq("http://a/b/c/") + expect(Addressable::URI.join(@uri.to_s, "./").to_s).to eq("http://a/b/c/") + end + + # Section 5.4.1 of RFC 3986 + it "when joined with '..' should resolve to http://a/b/" do + expect((@uri + "..").to_s).to eq("http://a/b/") + expect(Addressable::URI.join(@uri.to_s, "..").to_s).to eq("http://a/b/") + end + + # Section 5.4.1 of RFC 3986 + it "when joined with '../' should resolve to http://a/b/" do + expect((@uri + "../").to_s).to eq("http://a/b/") + expect(Addressable::URI.join(@uri.to_s, "../").to_s).to eq("http://a/b/") + end + + # Section 5.4.1 of RFC 3986 + it "when joined with '../g' should resolve to http://a/b/g" do + expect((@uri + "../g").to_s).to eq("http://a/b/g") + expect(Addressable::URI.join(@uri.to_s, "../g").to_s).to eq("http://a/b/g") + end + + # Section 5.4.1 of RFC 3986 + it "when joined with '../..' should resolve to http://a/" do + expect((@uri + "../..").to_s).to eq("http://a/") + expect(Addressable::URI.join(@uri.to_s, "../..").to_s).to eq("http://a/") + end + + # Section 5.4.1 of RFC 3986 + it "when joined with '../../' should resolve to http://a/" do + expect((@uri + "../../").to_s).to eq("http://a/") + expect(Addressable::URI.join(@uri.to_s, "../../").to_s).to eq("http://a/") + end + + # Section 5.4.1 of RFC 3986 + it "when joined with '../../g' should resolve to http://a/g" do + expect((@uri + "../../g").to_s).to eq("http://a/g") + expect(Addressable::URI.join(@uri.to_s, "../../g").to_s).to eq("http://a/g") + end + + # Section 5.4.2 of RFC 3986 + it "when joined with '../../../g' should resolve to http://a/g" do + expect((@uri + "../../../g").to_s).to eq("http://a/g") + expect(Addressable::URI.join(@uri.to_s, "../../../g").to_s).to eq("http://a/g") + end + + it "when joined with '../.././../g' should resolve to http://a/g" do + expect((@uri + "../.././../g").to_s).to eq("http://a/g") + expect(Addressable::URI.join(@uri.to_s, "../.././../g").to_s).to eq( + "http://a/g" + ) + end + + # Section 5.4.2 of RFC 3986 + it "when joined with '../../../../g' should resolve to http://a/g" do + expect((@uri + "../../../../g").to_s).to eq("http://a/g") + expect(Addressable::URI.join( + @uri.to_s, "../../../../g").to_s).to eq("http://a/g") + end + + # Section 5.4.2 of RFC 3986 + it "when joined with '/./g' should resolve to http://a/g" do + expect((@uri + "/./g").to_s).to eq("http://a/g") + expect(Addressable::URI.join(@uri.to_s, "/./g").to_s).to eq("http://a/g") + end + + # Section 5.4.2 of RFC 3986 + it "when joined with '/../g' should resolve to http://a/g" do + expect((@uri + "/../g").to_s).to eq("http://a/g") + expect(Addressable::URI.join(@uri.to_s, "/../g").to_s).to eq("http://a/g") + end + + # Section 5.4.2 of RFC 3986 + it "when joined with 'g.' should resolve to http://a/b/c/g." do + expect((@uri + "g.").to_s).to eq("http://a/b/c/g.") + expect(Addressable::URI.join(@uri.to_s, "g.").to_s).to eq("http://a/b/c/g.") + end + + # Section 5.4.2 of RFC 3986 + it "when joined with '.g' should resolve to http://a/b/c/.g" do + expect((@uri + ".g").to_s).to eq("http://a/b/c/.g") + expect(Addressable::URI.join(@uri.to_s, ".g").to_s).to eq("http://a/b/c/.g") + end + + # Section 5.4.2 of RFC 3986 + it "when joined with 'g..' should resolve to http://a/b/c/g.." do + expect((@uri + "g..").to_s).to eq("http://a/b/c/g..") + expect(Addressable::URI.join(@uri.to_s, "g..").to_s).to eq("http://a/b/c/g..") + end + + # Section 5.4.2 of RFC 3986 + it "when joined with '..g' should resolve to http://a/b/c/..g" do + expect((@uri + "..g").to_s).to eq("http://a/b/c/..g") + expect(Addressable::URI.join(@uri.to_s, "..g").to_s).to eq("http://a/b/c/..g") + end + + # Section 5.4.2 of RFC 3986 + it "when joined with './../g' should resolve to http://a/b/g" do + expect((@uri + "./../g").to_s).to eq("http://a/b/g") + expect(Addressable::URI.join(@uri.to_s, "./../g").to_s).to eq("http://a/b/g") + end + + # Section 5.4.2 of RFC 3986 + it "when joined with './g/.' should resolve to http://a/b/c/g/" do + expect((@uri + "./g/.").to_s).to eq("http://a/b/c/g/") + expect(Addressable::URI.join(@uri.to_s, "./g/.").to_s).to eq("http://a/b/c/g/") + end + + # Section 5.4.2 of RFC 3986 + it "when joined with 'g/./h' should resolve to http://a/b/c/g/h" do + expect((@uri + "g/./h").to_s).to eq("http://a/b/c/g/h") + expect(Addressable::URI.join(@uri.to_s, "g/./h").to_s).to eq("http://a/b/c/g/h") + end + + # Section 5.4.2 of RFC 3986 + it "when joined with 'g/../h' should resolve to http://a/b/c/h" do + expect((@uri + "g/../h").to_s).to eq("http://a/b/c/h") + expect(Addressable::URI.join(@uri.to_s, "g/../h").to_s).to eq("http://a/b/c/h") + end + + # Section 5.4.2 of RFC 3986 + it "when joined with 'g;x=1/./y' " + + "should resolve to http://a/b/c/g;x=1/y" do + expect((@uri + "g;x=1/./y").to_s).to eq("http://a/b/c/g;x=1/y") + expect(Addressable::URI.join( + @uri.to_s, "g;x=1/./y").to_s).to eq("http://a/b/c/g;x=1/y") + end + + # Section 5.4.2 of RFC 3986 + it "when joined with 'g;x=1/../y' should resolve to http://a/b/c/y" do + expect((@uri + "g;x=1/../y").to_s).to eq("http://a/b/c/y") + expect(Addressable::URI.join( + @uri.to_s, "g;x=1/../y").to_s).to eq("http://a/b/c/y") + end + + # Section 5.4.2 of RFC 3986 + it "when joined with 'g?y/./x' " + + "should resolve to http://a/b/c/g?y/./x" do + expect((@uri + "g?y/./x").to_s).to eq("http://a/b/c/g?y/./x") + expect(Addressable::URI.join( + @uri.to_s, "g?y/./x").to_s).to eq("http://a/b/c/g?y/./x") + end + + # Section 5.4.2 of RFC 3986 + it "when joined with 'g?y/../x' " + + "should resolve to http://a/b/c/g?y/../x" do + expect((@uri + "g?y/../x").to_s).to eq("http://a/b/c/g?y/../x") + expect(Addressable::URI.join( + @uri.to_s, "g?y/../x").to_s).to eq("http://a/b/c/g?y/../x") + end + + # Section 5.4.2 of RFC 3986 + it "when joined with 'g#s/./x' " + + "should resolve to http://a/b/c/g#s/./x" do + expect((@uri + "g#s/./x").to_s).to eq("http://a/b/c/g#s/./x") + expect(Addressable::URI.join( + @uri.to_s, "g#s/./x").to_s).to eq("http://a/b/c/g#s/./x") + end + + # Section 5.4.2 of RFC 3986 + it "when joined with 'g#s/../x' " + + "should resolve to http://a/b/c/g#s/../x" do + expect((@uri + "g#s/../x").to_s).to eq("http://a/b/c/g#s/../x") + expect(Addressable::URI.join( + @uri.to_s, "g#s/../x").to_s).to eq("http://a/b/c/g#s/../x") + end + + # Section 5.4.2 of RFC 3986 + it "when joined with 'http:g' should resolve to http:g" do + expect((@uri + "http:g").to_s).to eq("http:g") + expect(Addressable::URI.join(@uri.to_s, "http:g").to_s).to eq("http:g") + end + + # Edge case to be sure + it "when joined with '//example.com/' should " + + "resolve to http://example.com/" do + expect((@uri + "//example.com/").to_s).to eq("http://example.com/") + expect(Addressable::URI.join( + @uri.to_s, "//example.com/").to_s).to eq("http://example.com/") + end + + it "when joined with a bogus object a TypeError should be raised" do + expect do + Addressable::URI.join(@uri, 42) + end.to raise_error(TypeError) + end +end + +describe Addressable::URI, "when converting the path " + + "'relative/path/to/something'" do + before do + @path = 'relative/path/to/something' + end + + it "should convert to " + + "\'relative/path/to/something\'" do + @uri = Addressable::URI.convert_path(@path) + expect(@uri.to_str).to eq("relative/path/to/something") + end + + it "should join with an absolute file path correctly" do + @base = Addressable::URI.convert_path("/absolute/path/") + @uri = Addressable::URI.convert_path(@path) + expect((@base + @uri).to_str).to eq( + "file:///absolute/path/relative/path/to/something" + ) + end +end + +describe Addressable::URI, "when converting a bogus path" do + it "should raise a TypeError" do + expect do + Addressable::URI.convert_path(42) + end.to raise_error(TypeError) + end +end + +describe Addressable::URI, "when given a UNIX root directory" do + before do + @path = "/" + end + + it "should convert to \'file:///\'" do + @uri = Addressable::URI.convert_path(@path) + expect(@uri.to_str).to eq("file:///") + end + + it "should have an origin of 'file://'" do + @uri = Addressable::URI.convert_path(@path) + expect(@uri.origin).to eq('file://') + end +end + +describe Addressable::URI, "when given a Windows root directory" do + before do + @path = "C:\\" + end + + it "should convert to \'file:///c:/\'" do + @uri = Addressable::URI.convert_path(@path) + expect(@uri.to_str).to eq("file:///c:/") + end + + it "should have an origin of 'file://'" do + @uri = Addressable::URI.convert_path(@path) + expect(@uri.origin).to eq('file://') + end +end + +describe Addressable::URI, "when given the path '/one/two/'" do + before do + @path = '/one/two/' + end + + it "should convert to " + + "\'file:///one/two/\'" do + @uri = Addressable::URI.convert_path(@path) + expect(@uri.to_str).to eq("file:///one/two/") + end + + it "should have an origin of 'file://'" do + @uri = Addressable::URI.convert_path(@path) + expect(@uri.origin).to eq('file://') + end +end + +describe Addressable::URI, "when given the tld " do + it "'uk' should have a tld of 'uk'" do + uri = Addressable::URI.parse("http://example.com") + uri.tld = "uk" + + expect(uri.tld).to eq("uk") + end + + context "which " do + let (:uri) { Addressable::URI.parse("http://www.comrade.net/path/to/source/") } + + it "contains a subdomain" do + uri.tld = "co.uk" + + expect(uri.to_s).to eq("http://www.comrade.co.uk/path/to/source/") + end + + it "is part of the domain" do + uri.tld = "com" + + expect(uri.to_s).to eq("http://www.comrade.com/path/to/source/") + end + end +end + +describe Addressable::URI, "when given the path " + + "'c:\\windows\\My Documents 100%20\\foo.txt'" do + before do + @path = "c:\\windows\\My Documents 100%20\\foo.txt" + end + + it "should convert to " + + "\'file:///c:/windows/My%20Documents%20100%20/foo.txt\'" do + @uri = Addressable::URI.convert_path(@path) + expect(@uri.to_str).to eq("file:///c:/windows/My%20Documents%20100%20/foo.txt") + end + + it "should have an origin of 'file://'" do + @uri = Addressable::URI.convert_path(@path) + expect(@uri.origin).to eq('file://') + end +end + +describe Addressable::URI, "when given the path " + + "'file://c:\\windows\\My Documents 100%20\\foo.txt'" do + before do + @path = "file://c:\\windows\\My Documents 100%20\\foo.txt" + end + + it "should convert to " + + "\'file:///c:/windows/My%20Documents%20100%20/foo.txt\'" do + @uri = Addressable::URI.convert_path(@path) + expect(@uri.to_str).to eq("file:///c:/windows/My%20Documents%20100%20/foo.txt") + end + + it "should have an origin of 'file://'" do + @uri = Addressable::URI.convert_path(@path) + expect(@uri.origin).to eq('file://') + end +end + +describe Addressable::URI, "when given the path " + + "'file:c:\\windows\\My Documents 100%20\\foo.txt'" do + before do + @path = "file:c:\\windows\\My Documents 100%20\\foo.txt" + end + + it "should convert to " + + "\'file:///c:/windows/My%20Documents%20100%20/foo.txt\'" do + @uri = Addressable::URI.convert_path(@path) + expect(@uri.to_str).to eq("file:///c:/windows/My%20Documents%20100%20/foo.txt") + end + + it "should have an origin of 'file://'" do + @uri = Addressable::URI.convert_path(@path) + expect(@uri.origin).to eq('file://') + end +end + +describe Addressable::URI, "when given the path " + + "'file:/c:\\windows\\My Documents 100%20\\foo.txt'" do + before do + @path = "file:/c:\\windows\\My Documents 100%20\\foo.txt" + end + + it "should convert to " + + "\'file:///c:/windows/My%20Documents%20100%20/foo.txt\'" do + @uri = Addressable::URI.convert_path(@path) + expect(@uri.to_str).to eq("file:///c:/windows/My%20Documents%20100%20/foo.txt") + end + + it "should have an origin of 'file://'" do + @uri = Addressable::URI.convert_path(@path) + expect(@uri.origin).to eq('file://') + end +end + +describe Addressable::URI, "when given the path " + + "'file:///c|/windows/My%20Documents%20100%20/foo.txt'" do + before do + @path = "file:///c|/windows/My%20Documents%20100%20/foo.txt" + end + + it "should convert to " + + "\'file:///c:/windows/My%20Documents%20100%20/foo.txt\'" do + @uri = Addressable::URI.convert_path(@path) + expect(@uri.to_str).to eq("file:///c:/windows/My%20Documents%20100%20/foo.txt") + end + + it "should have an origin of 'file://'" do + @uri = Addressable::URI.convert_path(@path) + expect(@uri.origin).to eq('file://') + end +end + +describe Addressable::URI, "when given an http protocol URI" do + before do + @path = "http://example.com/" + end + + it "should not do any conversion at all" do + @uri = Addressable::URI.convert_path(@path) + expect(@uri.to_str).to eq("http://example.com/") + end +end + +class SuperString + def initialize(string) + @string = string.to_s + end + + def to_str + return @string + end +end + +describe Addressable::URI, "when parsing a non-String object" do + it "should correctly parse anything with a 'to_str' method" do + Addressable::URI.parse(SuperString.new(42)) + end + + it "should raise a TypeError for objects than cannot be converted" do + expect do + Addressable::URI.parse(42) + end.to raise_error(TypeError) + end + + it "should correctly parse heuristically anything with a 'to_str' method" do + Addressable::URI.heuristic_parse(SuperString.new(42)) + end + + it "should raise a TypeError for objects than cannot be converted" do + expect do + Addressable::URI.heuristic_parse(42) + end.to raise_error(TypeError) + end +end + +describe Addressable::URI, "when form encoding a hash" do + it "should result in correct percent encoded sequence" do + expect(Addressable::URI.form_encode( + [["&one", "/1"], ["=two", "?2"], [":three", "#3"]] + )).to eq("%26one=%2F1&%3Dtwo=%3F2&%3Athree=%233") + end + + it "should result in correct percent encoded sequence" do + expect(Addressable::URI.form_encode( + {"q" => "one two three"} + )).to eq("q=one+two+three") + end + + it "should result in correct percent encoded sequence" do + expect(Addressable::URI.form_encode( + {"key" => nil} + )).to eq("key=") + end + + it "should result in correct percent encoded sequence" do + expect(Addressable::URI.form_encode( + {"q" => ["one", "two", "three"]} + )).to eq("q=one&q=two&q=three") + end + + it "should result in correctly encoded newlines" do + expect(Addressable::URI.form_encode( + {"text" => "one\ntwo\rthree\r\nfour\n\r"} + )).to eq("text=one%0D%0Atwo%0D%0Athree%0D%0Afour%0D%0A%0D%0A") + end + + it "should result in a sorted percent encoded sequence" do + expect(Addressable::URI.form_encode( + [["a", "1"], ["dup", "3"], ["dup", "2"]], true + )).to eq("a=1&dup=2&dup=3") + end +end + +describe Addressable::URI, "when form encoding a non-Array object" do + it "should raise a TypeError for objects than cannot be converted" do + expect do + Addressable::URI.form_encode(42) + end.to raise_error(TypeError) + end +end + +# See https://tools.ietf.org/html/rfc6749#appendix-B +describe Addressable::URI, "when form encoding the example value from OAuth 2" do + it "should result in correct values" do + expect(Addressable::URI.form_encode( + {"value" => " %&+£€"} + )).to eq("value=+%25%26%2B%C2%A3%E2%82%AC") + end +end + +# See https://tools.ietf.org/html/rfc6749#appendix-B +describe Addressable::URI, "when form unencoding the example value from OAuth 2" do + it "should result in correct values" do + expect(Addressable::URI.form_unencode( + "value=+%25%26%2B%C2%A3%E2%82%AC" + )).to eq([["value", " %&+£€"]]) + end +end + +describe Addressable::URI, "when form unencoding a string" do + it "should result in correct values" do + expect(Addressable::URI.form_unencode( + "%26one=%2F1&%3Dtwo=%3F2&%3Athree=%233" + )).to eq([["&one", "/1"], ["=two", "?2"], [":three", "#3"]]) + end + + it "should result in correct values" do + expect(Addressable::URI.form_unencode( + "q=one+two+three" + )).to eq([["q", "one two three"]]) + end + + it "should result in correct values" do + expect(Addressable::URI.form_unencode( + "text=one%0D%0Atwo%0D%0Athree%0D%0Afour%0D%0A%0D%0A" + )).to eq([["text", "one\ntwo\nthree\nfour\n\n"]]) + end + + it "should result in correct values" do + expect(Addressable::URI.form_unencode( + "a=1&dup=2&dup=3" + )).to eq([["a", "1"], ["dup", "2"], ["dup", "3"]]) + end + + it "should result in correct values" do + expect(Addressable::URI.form_unencode( + "key" + )).to eq([["key", nil]]) + end + + it "should result in correct values" do + expect(Addressable::URI.form_unencode("GivenName=Ren%C3%A9")).to eq( + [["GivenName", "René"]] + ) + end +end + +describe Addressable::URI, "when form unencoding a non-String object" do + it "should correctly parse anything with a 'to_str' method" do + Addressable::URI.form_unencode(SuperString.new(42)) + end + + it "should raise a TypeError for objects than cannot be converted" do + expect do + Addressable::URI.form_unencode(42) + end.to raise_error(TypeError) + end +end + +describe Addressable::URI, "when normalizing a non-String object" do + it "should correctly parse anything with a 'to_str' method" do + Addressable::URI.normalize_component(SuperString.new(42)) + end + + it "should raise a TypeError for objects than cannot be converted" do + expect do + Addressable::URI.normalize_component(42) + end.to raise_error(TypeError) + end + + it "should raise a TypeError for objects than cannot be converted" do + expect do + Addressable::URI.normalize_component("component", 42) + end.to raise_error(TypeError) + end +end + +describe Addressable::URI, "when normalizing a path with an encoded slash" do + it "should result in correct percent encoded sequence" do + expect(Addressable::URI.parse("/path%2Fsegment/").normalize.path).to eq( + "/path%2Fsegment/" + ) + end +end + +describe Addressable::URI, "when normalizing a path with special unicode" do + it "does not stop at or ignore null bytes" do + expect(Addressable::URI.parse("/path%00segment/").normalize.path).to eq( + "/path%00segment/" + ) + end + + it "does apply NFC unicode normalization" do + expect(Addressable::URI.parse("/%E2%84%A6").normalize.path).to eq( + "/%CE%A9" + ) + end + + it "does not apply NFKC unicode normalization" do + expect(Addressable::URI.parse("/%C2%AF%C2%A0").normalize.path).to eq( + "/%C2%AF%C2%A0" + ) + end +end + +describe Addressable::URI, "when normalizing a partially encoded string" do + it "should result in correct percent encoded sequence" do + expect(Addressable::URI.normalize_component( + "partially % encoded%21" + )).to eq("partially%20%25%20encoded!") + end + + it "should result in correct percent encoded sequence" do + expect(Addressable::URI.normalize_component( + "partially %25 encoded!" + )).to eq("partially%20%25%20encoded!") + end +end + +describe Addressable::URI, "when normalizing a unicode sequence" do + it "should result in correct percent encoded sequence" do + expect(Addressable::URI.normalize_component( + "/C%CC%A7" + )).to eq("/%C3%87") + end + + it "should result in correct percent encoded sequence" do + expect(Addressable::URI.normalize_component( + "/%C3%87" + )).to eq("/%C3%87") + end +end + +describe Addressable::URI, "when normalizing a multibyte string" do + it "should result in correct percent encoded sequence" do + expect(Addressable::URI.normalize_component("günther")).to eq( + "g%C3%BCnther" + ) + end + + it "should result in correct percent encoded sequence" do + expect(Addressable::URI.normalize_component("g%C3%BCnther")).to eq( + "g%C3%BCnther" + ) + end +end + +describe Addressable::URI, "when normalizing a string but leaving some characters encoded" do + it "should result in correct percent encoded sequence" do + expect(Addressable::URI.normalize_component("%58X%59Y%5AZ", "0-9a-zXY", "Y")).to eq( + "XX%59Y%5A%5A" + ) + end + + it "should not modify the character class" do + character_class = "0-9a-zXY" + + character_class_copy = character_class.dup + + Addressable::URI.normalize_component("%58X%59Y%5AZ", character_class, "Y") + + expect(character_class).to eq(character_class_copy) + end +end + +describe Addressable::URI, "when encoding IP literals" do + it "should work for IPv4" do + input = "http://127.0.0.1/" + expect(Addressable::URI.encode(input)).to eq(input) + end + + it "should work for IPv6" do + input = "http://[fe80::200:f8ff:fe21:67cf]/" + expect(Addressable::URI.encode(input)).to eq(input) + end +end + +describe Addressable::URI, "when encoding a string with existing encodings to upcase" do + it "should result in correct percent encoded sequence" do + expect(Addressable::URI.encode_component("JK%4c", "0-9A-IKM-Za-z%", "L")).to eq("%4AK%4C") + end +end + +describe Addressable::URI, "when encoding a multibyte string" do + it "should result in correct percent encoded sequence" do + expect(Addressable::URI.encode_component("günther")).to eq("g%C3%BCnther") + end + + it "should result in correct percent encoded sequence" do + expect(Addressable::URI.encode_component( + "günther", /[^a-zA-Z0-9\:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=\-\.\_\~]/ + )).to eq("g%C3%BCnther") + end +end + +describe Addressable::URI, "when form encoding a multibyte string" do + it "should result in correct percent encoded sequence" do + expect(Addressable::URI.form_encode({"GivenName" => "René"})).to eq( + "GivenName=Ren%C3%A9" + ) + end +end + +describe Addressable::URI, "when encoding a string with ASCII chars 0-15" do + it "should result in correct percent encoded sequence" do + expect(Addressable::URI.encode_component("one\ntwo")).to eq("one%0Atwo") + end + + it "should result in correct percent encoded sequence" do + expect(Addressable::URI.encode_component( + "one\ntwo", /[^a-zA-Z0-9\:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=\-\.\_\~]/ + )).to eq("one%0Atwo") + end +end + +describe Addressable::URI, "when unencoding a multibyte string" do + it "should result in correct percent encoded sequence" do + expect(Addressable::URI.unencode_component("g%C3%BCnther")).to eq("günther") + end + + it "should consistently use UTF-8 internally" do + expect(Addressable::URI.unencode_component("ski=%BA%DAɫ")).to eq("ski=\xBA\xDAɫ") + end + + it "should not fail with UTF-8 incompatible string" do + url = "/M%E9/\xE9?p=\xFC".b + expect(Addressable::URI.unencode_component(url)).to eq("/M\xE9/\xE9?p=\xFC") + end + + it "should result in correct percent encoded sequence as a URI" do + expect(Addressable::URI.unencode( + "/path?g%C3%BCnther", ::Addressable::URI + )).to eq(Addressable::URI.new( + :path => "/path", :query => "günther" + )) + end +end + +describe Addressable::URI, "when partially unencoding a string" do + it "should unencode all characters by default" do + expect(Addressable::URI.unencode('%%25~%7e+%2b', String)).to eq('%%~~++') + end + + it "should unencode characters not in leave_encoded" do + expect(Addressable::URI.unencode('%%25~%7e+%2b', String, '~')).to eq('%%~%7e++') + end + + it "should leave characters in leave_encoded alone" do + expect(Addressable::URI.unencode('%%25~%7e+%2b', String, '%~+')).to eq('%%25~%7e+%2b') + end +end + +describe Addressable::URI, "when unencoding a bogus object" do + it "should raise a TypeError" do + expect do + Addressable::URI.unencode_component(42) + end.to raise_error(TypeError) + end + + it "should raise a TypeError" do + expect do + Addressable::URI.unencode("/path?g%C3%BCnther", Integer) + end.to raise_error(TypeError) + end +end + +describe Addressable::URI, "when encoding a bogus object" do + it "should raise a TypeError" do + expect do + Addressable::URI.encode(Object.new) + end.to raise_error(TypeError) + end + + it "should raise a TypeError" do + expect do + Addressable::URI.normalized_encode(Object.new) + end.to raise_error(TypeError) + end + + it "should raise a TypeError" do + expect do + Addressable::URI.encode_component("günther", Object.new) + end.to raise_error(TypeError) + end + + it "should raise a TypeError" do + expect do + Addressable::URI.encode_component(Object.new) + end.to raise_error(TypeError) + end +end + +describe Addressable::URI, "when given the input " + + "'http://example.com/'" do + before do + @input = "http://example.com/" + end + + it "should heuristically parse to 'http://example.com/'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.to_s).to eq("http://example.com/") + end + + it "should not raise error when frozen" do + expect do + Addressable::URI.heuristic_parse(@input).freeze.to_s + end.not_to raise_error + end +end + +describe Addressable::URI, "when given the input " + + "'https://example.com/'" do + before do + @input = "https://example.com/" + end + + it "should heuristically parse to 'https://example.com/'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.to_s).to eq("https://example.com/") + end +end + +describe Addressable::URI, "when given the input " + + "'http:example.com/'" do + before do + @input = "http:example.com/" + end + + it "should heuristically parse to 'http://example.com/'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.to_s).to eq("http://example.com/") + end + + it "should heuristically parse to 'http://example.com/' " + + "even with a scheme hint of 'ftp'" do + @uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'}) + expect(@uri.to_s).to eq("http://example.com/") + end +end + +describe Addressable::URI, "when given the input " + + "'https:example.com/'" do + before do + @input = "https:example.com/" + end + + it "should heuristically parse to 'https://example.com/'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.to_s).to eq("https://example.com/") + end + + it "should heuristically parse to 'https://example.com/' " + + "even with a scheme hint of 'ftp'" do + @uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'}) + expect(@uri.to_s).to eq("https://example.com/") + end +end + +describe Addressable::URI, "when given the input " + + "'http://example.com/example.com/'" do + before do + @input = "http://example.com/example.com/" + end + + it "should heuristically parse to 'http://example.com/example.com/'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.to_s).to eq("http://example.com/example.com/") + end +end + +describe Addressable::URI, "when given the input " + + "'http://prefix\\.example.com/'" do + before do + @input = "http://prefix\\.example.com/" + end + + it "should heuristically parse to 'http://prefix/.example.com/'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.authority).to eq("prefix") + expect(@uri.to_s).to eq("http://prefix/.example.com/") + end + + it "should heuristically parse to 'http://prefix/.example.com/' " + + "even with a scheme hint of 'ftp'" do + @uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'}) + expect(@uri.to_s).to eq("http://prefix/.example.com/") + end +end + +describe Addressable::URI, "when given the input " + + "'http://p:\\/'" do + before do + @input = "http://p:\\/" + end + + it "should heuristically parse to 'http://p//'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.authority).to eq("p") + expect(@uri.to_s).to eq("http://p//") + end + + it "should heuristically parse to 'http://p//' " + + "even with a scheme hint of 'ftp'" do + @uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'}) + expect(@uri.to_s).to eq("http://p//") + end +end + +describe Addressable::URI, "when given the input " + + "'http://p://'" do + before do + @input = "http://p://" + end + + it "should heuristically parse to 'http://p//'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.authority).to eq("p") + expect(@uri.to_s).to eq("http://p//") + end + + it "should heuristically parse to 'http://p//' " + + "even with a scheme hint of 'ftp'" do + @uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'}) + expect(@uri.to_s).to eq("http://p//") + end +end + +describe Addressable::URI, "when given the input " + + "'http://p://p'" do + before do + @input = "http://p://p" + end + + it "should heuristically parse to 'http://p//p'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.authority).to eq("p") + expect(@uri.to_s).to eq("http://p//p") + end + + it "should heuristically parse to 'http://p//p' " + + "even with a scheme hint of 'ftp'" do + @uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'}) + expect(@uri.to_s).to eq("http://p//p") + end +end + +describe Addressable::URI, "when given the input " + + "'http://prefix .example.com/'" do + before do + @input = "http://prefix .example.com/" + end + + # Justification here being that no browser actually tries to resolve this. + # They all treat this as a web search. + it "should heuristically parse to 'http://prefix%20.example.com/'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.authority).to eq("prefix%20.example.com") + expect(@uri.to_s).to eq("http://prefix%20.example.com/") + end + + it "should heuristically parse to 'http://prefix%20.example.com/' " + + "even with a scheme hint of 'ftp'" do + @uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'}) + expect(@uri.to_s).to eq("http://prefix%20.example.com/") + end +end + +describe Addressable::URI, "when given the input " + + "' http://www.example.com/ '" do + before do + @input = " http://www.example.com/ " + end + + it "should heuristically parse to 'http://prefix%20.example.com/'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.scheme).to eq("http") + expect(@uri.path).to eq("/") + expect(@uri.to_s).to eq("http://www.example.com/") + end +end + +describe Addressable::URI, "when given the input " + + "'http://prefix%2F.example.com/'" do + before do + @input = "http://prefix%2F.example.com/" + end + + it "should heuristically parse to 'http://prefix%2F.example.com/'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.authority).to eq("prefix%2F.example.com") + expect(@uri.to_s).to eq("http://prefix%2F.example.com/") + end + + it "should heuristically parse to 'http://prefix%2F.example.com/' " + + "even with a scheme hint of 'ftp'" do + @uri = Addressable::URI.heuristic_parse(@input, {:scheme => 'ftp'}) + expect(@uri.to_s).to eq("http://prefix%2F.example.com/") + end +end + +describe Addressable::URI, "when given the input " + + "'/path/to/resource'" do + before do + @input = "/path/to/resource" + end + + it "should heuristically parse to '/path/to/resource'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.to_s).to eq("/path/to/resource") + end +end + +describe Addressable::URI, "when given the input " + + "'relative/path/to/resource'" do + before do + @input = "relative/path/to/resource" + end + + it "should heuristically parse to 'relative/path/to/resource'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.to_s).to eq("relative/path/to/resource") + end +end + +describe Addressable::URI, "when given the input " + + "'example.com'" do + before do + @input = "example.com" + end + + it "should heuristically parse to 'http://example.com'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.to_s).to eq("http://example.com") + end +end + +describe Addressable::URI, "when given the input " + + "'example.com' and a scheme hint of 'ftp'" do + before do + @input = "example.com" + @hints = {:scheme => 'ftp'} + end + + it "should heuristically parse to 'http://example.com'" do + @uri = Addressable::URI.heuristic_parse(@input, @hints) + expect(@uri.to_s).to eq("ftp://example.com") + end +end + +describe Addressable::URI, "when given the input " + + "'example.com:21' and a scheme hint of 'ftp'" do + before do + @input = "example.com:21" + @hints = {:scheme => 'ftp'} + end + + it "should heuristically parse to 'http://example.com:21'" do + @uri = Addressable::URI.heuristic_parse(@input, @hints) + expect(@uri.to_s).to eq("ftp://example.com:21") + end +end + +describe Addressable::URI, "when given the input " + + "'example.com/path/to/resource'" do + before do + @input = "example.com/path/to/resource" + end + + it "should heuristically parse to 'http://example.com/path/to/resource'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.to_s).to eq("http://example.com/path/to/resource") + end +end + +describe Addressable::URI, "when given the input " + + "'http:///example.com'" do + before do + @input = "http:///example.com" + end + + it "should heuristically parse to 'http://example.com'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.to_s).to eq("http://example.com") + end +end + +describe Addressable::URI, "when given the input which "\ + "start with digits and has specified port" do + before do + @input = "7777.example.org:8089" + end + + it "should heuristically parse to 'http://7777.example.org:8089'" do + uri = Addressable::URI.heuristic_parse(@input) + expect(uri.to_s).to eq("http://7777.example.org:8089") + end +end + +describe Addressable::URI, "when given the input " + + "'feed:///example.com'" do + before do + @input = "feed:///example.com" + end + + it "should heuristically parse to 'feed://example.com'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.to_s).to eq("feed://example.com") + end +end + +describe Addressable::URI, "when given the input " + + "'file://localhost/path/to/resource/'" do + before do + @input = "file://localhost/path/to/resource/" + end + + it "should heuristically parse to 'file:///path/to/resource/'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.to_s).to eq("file:///path/to/resource/") + end +end + +describe Addressable::URI, "when given the input " + + "'file://path/to/resource/'" do + before do + @input = "file://path/to/resource/" + end + + it "should heuristically parse to 'file:///path/to/resource/'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.to_s).to eq("file:///path/to/resource/") + end +end + +describe Addressable::URI, "when given the input " + + "'file://///path/to/resource/'" do + before do + @input = "file:///////path/to/resource/" + end + + it "should heuristically parse to 'file:////path/to/resource/'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.to_s).to eq("file:////path/to/resource/") + end +end + +describe Addressable::URI, "when given the input " + + "'feed://http://example.com'" do + before do + @input = "feed://http://example.com" + end + + it "should heuristically parse to 'feed:http://example.com'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.to_s).to eq("feed:http://example.com") + end +end + +describe Addressable::URI, "when given the input " + + "::URI.parse('http://example.com')" do + before do + @input = ::URI.parse('http://example.com') + end + + it "should heuristically parse to 'http://example.com'" do + @uri = Addressable::URI.heuristic_parse(@input) + expect(@uri.to_s).to eq("http://example.com") + end +end + +describe Addressable::URI, "when given the input: 'user@domain.com'" do + before do + @input = "user@domain.com" + end + + context "for heuristic parse" do + it "should remain 'mailto:user@domain.com'" do + uri = Addressable::URI.heuristic_parse("mailto:#{@input}") + expect(uri.to_s).to eq("mailto:user@domain.com") + end + + it "should have a scheme of 'mailto'" do + uri = Addressable::URI.heuristic_parse(@input) + expect(uri.to_s).to eq("mailto:user@domain.com") + expect(uri.scheme).to eq("mailto") + end + + it "should remain 'acct:user@domain.com'" do + uri = Addressable::URI.heuristic_parse("acct:#{@input}") + expect(uri.to_s).to eq("acct:user@domain.com") + end + + context "HTTP" do + before do + @uri = Addressable::URI.heuristic_parse("http://#{@input}/") + end + + it "should remain 'http://user@domain.com/'" do + expect(@uri.to_s).to eq("http://user@domain.com/") + end + + it "should have the username 'user' for HTTP basic authentication" do + expect(@uri.user).to eq("user") + end + end + end +end + +describe Addressable::URI, "when assigning query values" do + before do + @uri = Addressable::URI.new + end + + it "should correctly assign {:a => 'a', :b => ['c', 'd', 'e']}" do + @uri.query_values = {:a => "a", :b => ["c", "d", "e"]} + expect(@uri.query).to eq("a=a&b=c&b=d&b=e") + end + + it "should raise an error attempting to assign {'a' => {'b' => ['c']}}" do + expect do + @uri.query_values = { 'a' => {'b' => ['c'] } } + end.to raise_error(TypeError) + end + + it "should raise an error attempting to assign " + + "{:b => '2', :a => {:c => '1'}}" do + expect do + @uri.query_values = {:b => '2', :a => {:c => '1'}} + end.to raise_error(TypeError) + end + + it "should raise an error attempting to assign " + + "{:a => 'a', :b => [{:c => 'c', :d => 'd'}, " + + "{:e => 'e', :f => 'f'}]}" do + expect do + @uri.query_values = { + :a => "a", :b => [{:c => "c", :d => "d"}, {:e => "e", :f => "f"}] + } + end.to raise_error(TypeError) + end + + it "should raise an error attempting to assign " + + "{:a => 'a', :b => [{:c => true, :d => 'd'}, " + + "{:e => 'e', :f => 'f'}]}" do + expect do + @uri.query_values = { + :a => 'a', :b => [{:c => true, :d => 'd'}, {:e => 'e', :f => 'f'}] + } + end.to raise_error(TypeError) + end + + it "should raise an error attempting to assign " + + "{:a => 'a', :b => {:c => true, :d => 'd'}}" do + expect do + @uri.query_values = { + :a => 'a', :b => {:c => true, :d => 'd'} + } + end.to raise_error(TypeError) + end + + it "should raise an error attempting to assign " + + "{:a => 'a', :b => {:c => true, :d => 'd'}}" do + expect do + @uri.query_values = { + :a => 'a', :b => {:c => true, :d => 'd'} + } + end.to raise_error(TypeError) + end + + it "should correctly assign {:a => 1, :b => 1.5}" do + @uri.query_values = { :a => 1, :b => 1.5 } + expect(@uri.query).to eq("a=1&b=1.5") + end + + it "should raise an error attempting to assign " + + "{:z => 1, :f => [2, {999.1 => [3,'4']}, ['h', 'i']], " + + ":a => {:b => ['c', 'd'], :e => true, :y => 0.5}}" do + expect do + @uri.query_values = { + :z => 1, + :f => [ 2, {999.1 => [3,'4']}, ['h', 'i'] ], + :a => { :b => ['c', 'd'], :e => true, :y => 0.5 } + } + end.to raise_error(TypeError) + end + + it "should correctly assign {}" do + @uri.query_values = {} + expect(@uri.query).to eq('') + end + + it "should correctly assign nil" do + @uri.query_values = nil + expect(@uri.query).to eq(nil) + end + + it "should correctly sort {'ab' => 'c', :ab => 'a', :a => 'x'}" do + @uri.query_values = {'ab' => 'c', :ab => 'a', :a => 'x'} + expect(@uri.query).to eq("a=x&ab=a&ab=c") + end + + it "should correctly assign " + + "[['b', 'c'], ['b', 'a'], ['a', 'a']]" do + # Order can be guaranteed in this format, so preserve it. + @uri.query_values = [['b', 'c'], ['b', 'a'], ['a', 'a']] + expect(@uri.query).to eq("b=c&b=a&a=a") + end + + it "should preserve query string order" do + query_string = (('a'..'z').to_a.reverse.map { |e| "#{e}=#{e}" }).join("&") + @uri.query = query_string + original_uri = @uri.to_s + @uri.query_values = @uri.query_values(Array) + expect(@uri.to_s).to eq(original_uri) + end + + describe 'when a hash with mixed types is assigned to query_values' do + it 'should not raise an error' do + skip 'Issue #94' + expect { subject.query_values = { "page" => "1", :page => 2 } }.to_not raise_error + end + end +end + +describe Addressable::URI, "when assigning path values" do + before do + @uri = Addressable::URI.new + end + + it "should correctly assign paths containing colons" do + @uri.path = "acct:bob@sporkmonger.com" + expect(@uri.path).to eq("acct:bob@sporkmonger.com") + expect(@uri.normalize.to_str).to eq("acct%2Fbob@sporkmonger.com") + expect { @uri.to_s }.to raise_error( + Addressable::URI::InvalidURIError + ) + end + + it "should correctly assign paths containing colons" do + @uri.path = "/acct:bob@sporkmonger.com" + @uri.authority = "example.com" + expect(@uri.normalize.to_str).to eq("//example.com/acct:bob@sporkmonger.com") + end + + it "should correctly assign paths containing colons" do + @uri.path = "acct:bob@sporkmonger.com" + @uri.scheme = "something" + expect(@uri.normalize.to_str).to eq("something:acct:bob@sporkmonger.com") + end + + it "should not allow relative paths to be assigned on absolute URIs" do + expect do + @uri.scheme = "http" + @uri.host = "example.com" + @uri.path = "acct:bob@sporkmonger.com" + end.to raise_error(Addressable::URI::InvalidURIError) + end + + it "should not allow relative paths to be assigned on absolute URIs" do + expect do + @uri.path = "acct:bob@sporkmonger.com" + @uri.scheme = "http" + @uri.host = "example.com" + end.to raise_error(Addressable::URI::InvalidURIError) + end + + it "should not allow relative paths to be assigned on absolute URIs" do + expect do + @uri.path = "uuid:0b3ecf60-3f93-11df-a9c3-001f5bfffe12" + @uri.scheme = "urn" + end.not_to raise_error + end +end + +describe Addressable::URI, "when initializing a subclass of Addressable::URI" do + before do + @uri = Class.new(Addressable::URI).new + end + + it "should have the same class after being parsed" do + expect(@uri.class).to eq(Addressable::URI.parse(@uri).class) + end + + it "should have the same class as its duplicate" do + expect(@uri.class).to eq(@uri.dup.class) + end + + it "should have the same class after being normalized" do + expect(@uri.class).to eq(@uri.normalize.class) + end + + it "should have the same class after being merged" do + expect(@uri.class).to eq(@uri.merge(:path => 'path').class) + end + + it "should have the same class after being joined" do + expect(@uri.class).to eq(@uri.join('path').class) + end +end + +describe Addressable::URI, "support serialization roundtrip" do + before do + @uri = Addressable::URI.new( + :scheme => "http", + :user => "user", + :password => "password", + :host => "example.com", + :port => 80, + :path => "/path", + :query => "query=value", + :fragment => "fragment" + ) + end + + it "is in a working state after being serialized with Marshal" do + @uri = Addressable::URI.parse("http://example.com") + cloned_uri = Marshal.load(Marshal.dump(@uri)) + expect(cloned_uri.normalized_scheme).to be == @uri.normalized_scheme + end + + it "is in a working state after being serialized with YAML" do + @uri = Addressable::URI.parse("http://example.com") + cloned_uri = if YAML.respond_to?(:unsafe_load) + YAML.unsafe_load(YAML.dump(@uri)) + else + YAML.load(YAML.dump(@uri)) + end + expect(cloned_uri.normalized_scheme).to be == @uri.normalized_scheme + end +end + +describe Addressable::URI, "when initialized in a non-main `Ractor`" do + it "should have the same value as if used in the main `Ractor`" do + pending("Ruby 3.0+ for `Ractor` support") unless defined?(Ractor) + main = Addressable::URI.parse("http://example.com") + expect( + Ractor.new { Addressable::URI.parse("http://example.com") }.take + ).to eq(main) + end +end + +describe Addressable::URI, "when deferring validation" do + subject(:deferred) { uri.instance_variable_get(:@validation_deferred) } + + let(:uri) { Addressable::URI.parse("http://example.com") } + + it "defers validation within the block" do + uri.defer_validation do + expect(deferred).to be true + end + end + + it "always resets deferral afterward" do + expect { uri.defer_validation { raise "boom" } }.to raise_error("boom") + expect(deferred).to be false + end + + it "returns nil" do + res = uri.defer_validation {} + expect(res).to be nil + end +end + +describe Addressable::URI, "YAML safe loading" do + it "doesn't serialize anonymous objects" do + url = Addressable::URI.parse("http://example.com/") + expect(YAML.dump(url)).to_not include("!ruby/object {}") + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/spec/spec_helper.rb b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/spec/spec_helper.rb new file mode 100644 index 00000000..bd8e3958 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/spec/spec_helper.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require 'bundler/setup' +require 'rspec/its' + +begin + require 'coveralls' + Coveralls.wear! do + add_filter "spec/" + add_filter "vendor/" + end +rescue LoadError + warn "warning: coveralls gem not found; skipping Coveralls" + require 'simplecov' + SimpleCov.start do + add_filter "spec/" + add_filter "vendor/" + end +end if Gem.loaded_specs.key?("simplecov") + +class TestHelper + def self.native_supported? + mri = RUBY_ENGINE == "ruby" + windows = RUBY_PLATFORM.include?("mingw") + + mri && !windows + end +end + +RSpec.configure do |config| + config.warnings = true + config.filter_run_when_matching :focus +end diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/tasks/clobber.rake b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/tasks/clobber.rake new file mode 100644 index 00000000..a9e32b34 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/tasks/clobber.rake @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +desc "Remove all build products" +task "clobber" diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/tasks/gem.rake b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/tasks/gem.rake new file mode 100644 index 00000000..70b1f97d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/tasks/gem.rake @@ -0,0 +1,95 @@ +# frozen_string_literal: true + +require "rubygems/package_task" + +namespace :gem do + GEM_SPEC = Gem::Specification.new do |s| + s.name = PKG_NAME + s.version = PKG_VERSION + s.summary = PKG_SUMMARY + s.description = PKG_DESCRIPTION + + s.files = PKG_FILES.to_a + + s.extra_rdoc_files = %w( README.md ) + s.rdoc_options.concat ["--main", "README.md"] + + if !s.respond_to?(:add_development_dependency) + puts "Cannot build Gem with this version of RubyGems." + exit(1) + end + + s.required_ruby_version = ">= 2.2" + + s.add_runtime_dependency "public_suffix", ">= 2.0.2", "< 7.0" + s.add_development_dependency "bundler", ">= 1.0", "< 3.0" + + s.require_path = "lib" + + s.author = "Bob Aman" + s.email = "bob@sporkmonger.com" + s.homepage = "https://github.com/sporkmonger/addressable" + s.license = "Apache-2.0" + s.metadata = { + "changelog_uri" => "https://github.com/sporkmonger/addressable/blob/main/CHANGELOG.md#v#{PKG_VERSION}" + } + end + + Gem::PackageTask.new(GEM_SPEC) do |p| + p.gem_spec = GEM_SPEC + p.need_tar = true + p.need_zip = true + end + + desc "Generates .gemspec file" + task :gemspec do + spec_string = GEM_SPEC.to_ruby + File.open("#{GEM_SPEC.name}.gemspec", "w") do |file| + file.write spec_string + end + end + + desc "Show information about the gem" + task :debug do + puts GEM_SPEC.to_ruby + end + + desc "Install the gem" + task :install => ["clobber", "gem:package"] do + sh "gem install --local ./pkg/#{GEM_SPEC.full_name}.gem" + end + + desc "Uninstall the gem" + task :uninstall do + installed_list = Gem.source_index.find_name(PKG_NAME) + if installed_list && + (installed_list.collect { |s| s.version.to_s}.include?(PKG_VERSION)) + sh( + "gem uninstall --version '#{PKG_VERSION}' " + + "--ignore-dependencies --executables #{PKG_NAME}" + ) + end + end + + desc "Reinstall the gem" + task :reinstall => [:uninstall, :install] + + desc "Package for release" + task :release => ["gem:package", "gem:gemspec"] do |t| + v = ENV["VERSION"] or abort "Must supply VERSION=x.y.z" + abort "Versions don't match #{v} vs #{PROJ.version}" if v != PKG_VERSION + pkg = "pkg/#{GEM_SPEC.full_name}" + + changelog = File.open("CHANGELOG.md") { |file| file.read } + + puts "Releasing #{PKG_NAME} v. #{PKG_VERSION}" + Rake::Task["git:tag:create"].invoke + end +end + +desc "Alias to gem:package" +task "gem" => "gem:package" + +task "gem:release" => "gem:gemspec" + +task "clobber" => ["gem:clobber_package"] diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/tasks/git.rake b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/tasks/git.rake new file mode 100644 index 00000000..1238c8d2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/tasks/git.rake @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +namespace :git do + namespace :tag do + desc "List tags from the Git repository" + task :list do + tags = `git tag -l` + tags.gsub!("\r", "") + tags = tags.split("\n").sort {|a, b| b <=> a } + puts tags.join("\n") + end + + desc "Create a new tag in the Git repository" + task :create do + changelog = File.open("CHANGELOG.md", "r") { |file| file.read } + puts "-" * 80 + puts changelog + puts "-" * 80 + puts + + v = ENV["VERSION"] or abort "Must supply VERSION=x.y.z" + abort "Versions don't match #{v} vs #{PKG_VERSION}" if v != PKG_VERSION + + git_status = `git status` + if git_status !~ /^nothing to commit/ + abort "Working directory isn't clean." + end + + tag = "#{PKG_NAME}-#{PKG_VERSION}" + msg = "Release #{PKG_NAME}-#{PKG_VERSION}" + + existing_tags = `git tag -l #{PKG_NAME}-*`.split('\n') + if existing_tags.include?(tag) + warn("Tag already exists, deleting...") + unless system "git tag -d #{tag}" + abort "Tag deletion failed." + end + end + puts "Creating git tag '#{tag}'..." + unless system "git tag -a -m \"#{msg}\" #{tag}" + abort "Tag creation failed." + end + end + end +end + +task "gem:release" => "git:tag:create" diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/tasks/metrics.rake b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/tasks/metrics.rake new file mode 100644 index 00000000..107cc244 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/tasks/metrics.rake @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +namespace :metrics do + task :lines do + lines, codelines, total_lines, total_codelines = 0, 0, 0, 0 + for file_name in FileList["lib/**/*.rb"] + f = File.open(file_name) + while line = f.gets + lines += 1 + next if line =~ /^\s*$/ + next if line =~ /^\s*#/ + codelines += 1 + end + puts "L: #{sprintf("%4d", lines)}, " + + "LOC #{sprintf("%4d", codelines)} | #{file_name}" + total_lines += lines + total_codelines += codelines + + lines, codelines = 0, 0 + end + + puts "Total: Lines #{total_lines}, LOC #{total_codelines}" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/tasks/profile.rake b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/tasks/profile.rake new file mode 100644 index 00000000..b697d489 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/tasks/profile.rake @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +namespace :profile do + desc "Profile Template match memory allocations" + task :template_match_memory do + require "memory_profiler" + require "addressable/template" + + start_at = Time.now.to_f + template = Addressable::Template.new("http://example.com/{?one,two,three}") + report = MemoryProfiler.report do + 30_000.times do + template.match( + "http://example.com/?one=one&two=floo&three=me" + ) + end + end + end_at = Time.now.to_f + print_options = { scale_bytes: true, normalize_paths: true } + puts "\n\n" + + if ENV["CI"] + report.pretty_print(print_options) + else + t_allocated = report.scale_bytes(report.total_allocated_memsize) + t_retained = report.scale_bytes(report.total_retained_memsize) + + puts "Total allocated: #{t_allocated} (#{report.total_allocated} objects)" + puts "Total retained: #{t_retained} (#{report.total_retained} objects)" + puts "Took #{end_at - start_at} seconds" + + FileUtils.mkdir_p("tmp") + report.pretty_print(to_file: "tmp/memprof.txt", **print_options) + end + end + + desc "Profile URI parse memory allocations" + task :memory do + require "memory_profiler" + require "addressable/uri" + if ENV["IDNA_MODE"] == "pure" + Addressable.send(:remove_const, :IDNA) + load "addressable/idna/pure.rb" + end + + start_at = Time.now.to_f + report = MemoryProfiler.report do + 30_000.times do + Addressable::URI.parse( + "http://google.com/stuff/../?with_lots=of¶ms=asdff#!stuff" + ).normalize + end + end + end_at = Time.now.to_f + print_options = { scale_bytes: true, normalize_paths: true } + puts "\n\n" + + if ENV["CI"] + report.pretty_print(**print_options) + else + t_allocated = report.scale_bytes(report.total_allocated_memsize) + t_retained = report.scale_bytes(report.total_retained_memsize) + + puts "Total allocated: #{t_allocated} (#{report.total_allocated} objects)" + puts "Total retained: #{t_retained} (#{report.total_retained} objects)" + puts "Took #{end_at - start_at} seconds" + + FileUtils.mkdir_p("tmp") + report.pretty_print(to_file: "tmp/memprof.txt", **print_options) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/tasks/rspec.rake b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/tasks/rspec.rake new file mode 100644 index 00000000..e3d9f014 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/tasks/rspec.rake @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require "rspec/core/rake_task" + +namespace :spec do + RSpec::Core::RakeTask.new(:simplecov) do |t| + t.pattern = FileList['spec/**/*_spec.rb'] + t.rspec_opts = %w[--color --format documentation] unless ENV["CI"] + end + + namespace :simplecov do + desc "Browse the code coverage report." + task :browse => "spec:simplecov" do + require "launchy" + Launchy.open("coverage/index.html") + end + end +end + +desc "Alias to spec:simplecov" +task "spec" => "spec:simplecov" + +task "clobber" => ["spec:clobber_simplecov"] diff --git a/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/tasks/yard.rake b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/tasks/yard.rake new file mode 100644 index 00000000..515f9603 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/addressable-2.8.7/tasks/yard.rake @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require "rake" + +begin + require "yard" + require "yard/rake/yardoc_task" + + namespace :doc do + desc "Generate Yardoc documentation" + YARD::Rake::YardocTask.new do |yardoc| + yardoc.name = "yard" + yardoc.options = ["--verbose", "--markup", "markdown"] + yardoc.files = FileList[ + "lib/**/*.rb", "ext/**/*.c", + "README.md", "CHANGELOG.md", "LICENSE.txt" + ].exclude(/idna/) + end + end + + task "clobber" => ["doc:clobber_yard"] + + desc "Alias to doc:yard" + task "doc" => "doc:yard" +rescue LoadError + # If yard isn't available, it's not the end of the world + desc "Alias to doc:rdoc" + task "doc" => "doc:rdoc" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ast-2.4.3/LICENSE.MIT b/vendor/bundle/ruby/3.4.0/gems/ast-2.4.3/LICENSE.MIT new file mode 100644 index 00000000..7c483cf2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ast-2.4.3/LICENSE.MIT @@ -0,0 +1,20 @@ +Copyright (c) 2011-2013 Peter Zotov + +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 AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/ast-2.4.3/README.YARD.md b/vendor/bundle/ruby/3.4.0/gems/ast-2.4.3/README.YARD.md new file mode 100644 index 00000000..d2616c3d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ast-2.4.3/README.YARD.md @@ -0,0 +1,12 @@ +{AST} is a library for manipulating abstract syntax trees. + +It embraces immutability; each AST node is inherently frozen at +creation, and updating a child node requires recreating that node +and its every parent, recursively. + +This is a design choice. It does create some pressure on +garbage collector, but completely eliminates all concurrency +and aliasing problems. + +See also {AST::Node}, {AST::Processor::Mixin} and {AST::Sexp} for +additional recommendations and design patterns. diff --git a/vendor/bundle/ruby/3.4.0/gems/ast-2.4.3/lib/ast.rb b/vendor/bundle/ruby/3.4.0/gems/ast-2.4.3/lib/ast.rb new file mode 100644 index 00000000..4af060f3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ast-2.4.3/lib/ast.rb @@ -0,0 +1,17 @@ +# {AST} is a library for manipulating abstract syntax trees. +# +# It embraces immutability; each AST node is inherently frozen at +# creation, and updating a child node requires recreating that node +# and its every parent, recursively. +# This is a design choice. It does create some pressure on +# garbage collector, but completely eliminates all concurrency +# and aliasing problems. +# +# See also {AST::Node}, {AST::Processor::Mixin} and {AST::Sexp} for +# additional recommendations and design patterns. +# +module AST + require_relative 'ast/node' + require_relative 'ast/processor' + require_relative 'ast/sexp' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ast-2.4.3/lib/ast/node.rb b/vendor/bundle/ruby/3.4.0/gems/ast-2.4.3/lib/ast/node.rb new file mode 100644 index 00000000..9e9341f5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ast-2.4.3/lib/ast/node.rb @@ -0,0 +1,268 @@ +# frozen_string_literal: true + +module AST + # Node is an immutable class, instances of which represent abstract + # syntax tree nodes. It combines semantic information (i.e. anything + # that affects the algorithmic properties of a program) with + # meta-information (line numbers or compiler intermediates). + # + # Notes on inheritance + # ==================== + # + # The distinction between semantics and metadata is important. Complete + # semantic information should be contained within just the {#type} and + # {#children} of a Node instance; in other words, if an AST was to be + # stripped of all meta-information, it should remain a valid AST which + # could be successfully processed to yield a result with the same + # algorithmic properties. + # + # Thus, Node should never be inherited in order to define methods which + # affect or return semantic information, such as getters for `class_name`, + # `superclass` and `body` in the case of a hypothetical `ClassNode`. The + # correct solution is to use a generic Node with a {#type} of `:class` + # and three children. See also {Processor} for tips on working with such + # ASTs. + # + # On the other hand, Node can and should be inherited to define + # application-specific metadata (see also {#initialize}) or customize the + # printing format. It is expected that an application would have one or two + # such classes and use them across the entire codebase. + # + # The rationale for this pattern is extensibility and maintainability. + # Unlike static ones, dynamic languages do not require the presence of a + # predefined, rigid structure, nor does it improve dispatch efficiency, + # and while such a structure can certainly be defined, it does not add + # any value but incurs a maintaining cost. + # For example, extending the AST even with a transformation-local + # temporary node type requires making globally visible changes to + # the codebase. + # + class Node + # Returns the type of this node. + # @return [Symbol] + attr_reader :type + + # Returns the children of this node. + # The returned value is frozen. + # The to_a alias is useful for decomposing nodes concisely. + # For example: + # + # node = s(:gasgn, :$foo, s(:integer, 1)) + # var_name, value = *node + # p var_name # => :$foo + # p value # => (integer 1) + # + # @return [Array] + attr_reader :children + alias to_a children + + # Returns the precomputed hash value for this node + # @return [Integer] + attr_reader :hash + + # Constructs a new instance of Node. + # + # The arguments `type` and `children` are converted with `to_sym` and + # `to_a` respectively. Additionally, the result of converting `children` + # is frozen. While mutating the arguments is generally considered harmful, + # the most common case is to pass an array literal to the constructor. If + # your code does not expect the argument to be frozen, use `#dup`. + # + # The `properties` hash is passed to {#assign_properties}. + def initialize(type, children=[], properties={}) + @type, @children = type.to_sym, children.to_a.freeze + + assign_properties(properties) + + @hash = [@type, @children, self.class].hash + + freeze + end + + # Test if other object is equal to + # @param [Object] other + # @return [Boolean] + def eql?(other) + self.class.eql?(other.class) && + @type.eql?(other.type) && + @children.eql?(other.children) + end + + # By default, each entry in the `properties` hash is assigned to + # an instance variable in this instance of Node. A subclass should define + # attribute readers for such variables. The values passed in the hash + # are not frozen or whitelisted; such behavior can also be implemented + # by subclassing Node and overriding this method. + # + # @return [nil] + def assign_properties(properties) + properties.each do |name, value| + instance_variable_set :"@#{name}", value + end + + nil + end + protected :assign_properties + + alias :original_dup :dup + private :original_dup + + # Nodes are already frozen, so there is no harm in returning the + # current node as opposed to initializing from scratch and freezing + # another one. + # + # @return self + def dup + self + end + alias :clone :dup + + # Returns a new instance of Node where non-nil arguments replace the + # corresponding fields of `self`. + # + # For example, `Node.new(:foo, [ 1, 2 ]).updated(:bar)` would yield + # `(bar 1 2)`, and `Node.new(:foo, [ 1, 2 ]).updated(nil, [])` would + # yield `(foo)`. + # + # If the resulting node would be identical to `self`, does nothing. + # + # @param [Symbol, nil] type + # @param [Array, nil] children + # @param [Hash, nil] properties + # @return [AST::Node] + def updated(type=nil, children=nil, properties=nil) + new_type = type || @type + new_children = children || @children + new_properties = properties || {} + + if @type == new_type && + @children == new_children && + properties.nil? + self + else + copy = original_dup + copy.send :initialize, new_type, new_children, new_properties + copy + end + end + + # Compares `self` to `other`, possibly converting with `to_ast`. Only + # `type` and `children` are compared; metadata is deliberately ignored. + # + # @return [Boolean] + def ==(other) + if equal?(other) + true + elsif other.respond_to? :to_ast + other = other.to_ast + other.type == self.type && + other.children == self.children + else + false + end + end + + # Concatenates `array` with `children` and returns the resulting node. + # + # @return [AST::Node] + def concat(array) + updated(nil, @children + array.to_a) + end + + alias + concat + + # Appends `element` to `children` and returns the resulting node. + # + # @return [AST::Node] + def append(element) + updated(nil, @children + [element]) + end + + alias << append + + # Converts `self` to a pretty-printed s-expression. + # + # @param [Integer] indent Base indentation level. + # @return [String] + def to_sexp(indent=0) + indented = " " * indent + sexp = "#{indented}(#{fancy_type}" + + children.each do |child| + if child.is_a?(Node) + sexp += "\n#{child.to_sexp(indent + 1)}" + else + sexp += " #{child.inspect}" + end + end + + sexp += ")" + + sexp + end + + alias to_s to_sexp + + # Converts `self` to a s-expression ruby string. + # The code return will recreate the node, using the sexp module s() + # + # @param [Integer] indent Base indentation level. + # @return [String] + def inspect(indent=0) + indented = " " * indent + sexp = "#{indented}s(:#{@type}" + + children.each do |child| + if child.is_a?(Node) + sexp += ",\n#{child.inspect(indent + 1)}" + else + sexp += ", #{child.inspect}" + end + end + + sexp += ")" + + sexp + end + + # @return [AST::Node] self + def to_ast + self + end + + # Converts `self` to an Array where the first element is the type as a Symbol, + # and subsequent elements are the same representation of its children. + # + # @return [Array] + def to_sexp_array + children_sexp_arrs = children.map do |child| + if child.is_a?(Node) + child.to_sexp_array + else + child + end + end + + [type, *children_sexp_arrs] + end + + # Enables matching for Node, where type is the first element + # and the children are remaining items. + # + # @return [Array] + def deconstruct + [type, *children] + end + + protected + + # Returns `@type` with all underscores replaced by dashes. This allows + # to write symbol literals without quotes in Ruby sources and yet have + # nicely looking s-expressions. + # + # @return [String] + def fancy_type + @type.to_s.gsub('_', '-') + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ast-2.4.3/lib/ast/processor.rb b/vendor/bundle/ruby/3.4.0/gems/ast-2.4.3/lib/ast/processor.rb new file mode 100644 index 00000000..622e779d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ast-2.4.3/lib/ast/processor.rb @@ -0,0 +1,12 @@ +module AST + # This class includes {AST::Processor::Mixin}; however, it is + # deprecated, since the module defines all of the behaviors that + # the processor includes. Any new libraries should use + # {AST::Processor::Mixin} instead of subclassing this. + # + # @deprecated Use {AST::Processor::Mixin} instead. + class Processor + require_relative 'processor/mixin' + include Mixin + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ast-2.4.3/lib/ast/processor/mixin.rb b/vendor/bundle/ruby/3.4.0/gems/ast-2.4.3/lib/ast/processor/mixin.rb new file mode 100644 index 00000000..6febec87 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ast-2.4.3/lib/ast/processor/mixin.rb @@ -0,0 +1,288 @@ +module AST + class Processor + # The processor module is a module which helps transforming one + # AST into another. In a nutshell, the {#process} method accepts + # a {Node} and dispatches it to a handler corresponding to its + # type, and returns a (possibly) updated variant of the node. + # + # The processor module has a set of associated design patterns. + # They are best explained with a concrete example. Let's define a + # simple arithmetic language and an AST format for it: + # + # Terminals (AST nodes which do not have other AST nodes inside): + # + # * `(integer )`, + # + # Nonterminals (AST nodes with other nodes as children): + # + # * `(add )`, + # * `(multiply )`, + # * `(divide )`, + # * `(negate )`, + # * `(store )`: stores value of `` + # into a variable named ``, + # * `(load )`: loads value of a variable named + # ``, + # * `(each ...)`: computes each of the ``s and + # prints the result. + # + # All AST nodes have the same Ruby class, and therefore they don't + # know how to traverse themselves. (A solution which dynamically + # checks the type of children is possible, but is slow and + # error-prone.) So, a class including the module which knows how + # to traverse the entire tree should be defined. Such classes + # have a handler for each nonterminal node which recursively + # processes children nodes: + # + # require 'ast' + # + # class ArithmeticsProcessor + # include AST::Processor::Mixin + # # This method traverses any binary operators such as (add) + # # or (multiply). + # def process_binary_op(node) + # # Children aren't decomposed automatically; it is + # # suggested to use Ruby multiple assignment expansion, + # # as it is very convenient here. + # left_expr, right_expr = *node + # + # # AST::Node#updated won't change node type if nil is + # # passed as a first argument, which allows to reuse the + # # same handler for multiple node types using `alias' + # # (below). + # node.updated(nil, [ + # process(left_expr), + # process(right_expr) + # ]) + # end + # alias_method :on_add, :process_binary_op + # alias_method :on_multiply, :process_binary_op + # alias_method :on_divide, :process_binary_op + # + # def on_negate(node) + # # It is also possible to use #process_all for more + # # compact code if every child is a Node. + # node.updated(nil, process_all(node)) + # end + # + # def on_store(node) + # expr, variable_name = *node + # + # # Note that variable_name is not a Node and thus isn't + # # passed to #process. + # node.updated(nil, [ + # process(expr), + # variable_name + # ]) + # end + # + # # (load) is effectively a terminal node, and so it does + # # not need an explicit handler, as the following is the + # # default behavior. Essentially, for any nodes that don't + # # have a defined handler, the node remains unchanged. + # def on_load(node) + # nil + # end + # + # def on_each(node) + # node.updated(nil, process_all(node)) + # end + # end + # + # Let's test our ArithmeticsProcessor: + # + # include AST::Sexp + # expr = s(:add, s(:integer, 2), s(:integer, 2)) + # + # p ArithmeticsProcessor.new.process(expr) == expr # => true + # + # As expected, it does not change anything at all. This isn't + # actually very useful, so let's now define a Calculator, which + # will compute the expression values: + # + # # This Processor folds nonterminal nodes and returns an + # # (integer) terminal node. + # class ArithmeticsCalculator < ArithmeticsProcessor + # def compute_op(node) + # # First, node children are processed and then unpacked + # # to local variables. + # nodes = process_all(node) + # + # if nodes.all? { |node| node.type == :integer } + # # If each of those nodes represents a literal, we can + # # fold this node! + # values = nodes.map { |node| node.children.first } + # AST::Node.new(:integer, [ + # yield(values) + # ]) + # else + # # Otherwise, we can just leave the current node in the + # # tree and only update it with processed children + # # nodes, which can be partially folded. + # node.updated(nil, nodes) + # end + # end + # + # def on_add(node) + # compute_op(node) { |left, right| left + right } + # end + # + # def on_multiply(node) + # compute_op(node) { |left, right| left * right } + # end + # end + # + # Let's check: + # + # p ArithmeticsCalculator.new.process(expr) # => (integer 4) + # + # Excellent, the calculator works! Now, a careful reader could + # notice that the ArithmeticsCalculator does not know how to + # divide numbers. What if we pass an expression with division to + # it? + # + # expr_with_division = \ + # s(:add, + # s(:integer, 1), + # s(:divide, + # s(:add, s(:integer, 8), s(:integer, 4)), + # s(:integer, 3))) # 1 + (8 + 4) / 3 + # + # folded_expr_with_division = ArithmeticsCalculator.new.process(expr_with_division) + # p folded_expr_with_division + # # => (add + # # (integer 1) + # # (divide + # # (integer 12) + # # (integer 3))) + # + # As you can see, the expression was folded _partially_: the inner + # `(add)` node which could be computed was folded to + # `(integer 12)`, the `(divide)` node is left as-is because there + # is no computing handler for it, and the root `(add)` node was + # also left as it is because some of its children were not + # literals. + # + # Note that this partial folding is only possible because the + # _data_ format, i.e. the format in which the computed values of + # the nodes are represented, is the same as the AST itself. + # + # Let's extend our ArithmeticsCalculator class further. + # + # class ArithmeticsCalculator + # def on_divide(node) + # compute_op(node) { |left, right| left / right } + # end + # + # def on_negate(node) + # # Note how #compute_op works regardless of the operator + # # arity. + # compute_op(node) { |value| -value } + # end + # end + # + # Now, let's apply our renewed ArithmeticsCalculator to a partial + # result of previous evaluation: + # + # p ArithmeticsCalculator.new.process(expr_with_division) # => (integer 5) + # + # Five! Excellent. This is also pretty much how CRuby 1.8 executed + # its programs. + # + # Now, let's do some automated bug searching. Division by zero is + # an error, right? So if we could detect that someone has divided + # by zero before the program is even run, that could save some + # debugging time. + # + # class DivisionByZeroVerifier < ArithmeticsProcessor + # class VerificationFailure < Exception; end + # + # def on_divide(node) + # # You need to process the children to handle nested divisions + # # such as: + # # (divide + # # (integer 1) + # # (divide (integer 1) (integer 0)) + # left, right = process_all(node) + # + # if right.type == :integer && + # right.children.first == 0 + # raise VerificationFailure, "Ouch! This code divides by zero." + # end + # end + # + # def divides_by_zero?(ast) + # process(ast) + # false + # rescue VerificationFailure + # true + # end + # end + # + # nice_expr = \ + # s(:divide, + # s(:add, s(:integer, 10), s(:integer, 2)), + # s(:integer, 4)) + # + # p DivisionByZeroVerifier.new.divides_by_zero?(nice_expr) + # # => false. Good. + # + # bad_expr = \ + # s(:add, s(:integer, 10), + # s(:divide, s(:integer, 1), s(:integer, 0))) + # + # p DivisionByZeroVerifier.new.divides_by_zero?(bad_expr) + # # => true. WHOOPS. DO NOT RUN THIS. + # + # Of course, this won't detect more complex cases... unless you + # use some partial evaluation before! The possibilites are + # endless. Have fun. + module Mixin + # Dispatches `node`. If a node has type `:foo`, then a handler + # named `on_foo` is invoked with one argument, the `node`; if + # there isn't such a handler, {#handler_missing} is invoked + # with the same argument. + # + # If the handler returns `nil`, `node` is returned; otherwise, + # the return value of the handler is passed along. + # + # @param [AST::Node, nil] node + # @return [AST::Node, nil] + def process(node) + return if node.nil? + + node = node.to_ast + + # Invoke a specific handler + on_handler = :"on_#{node.type}" + if respond_to? on_handler + new_node = send on_handler, node + else + new_node = handler_missing(node) + end + + node = new_node if new_node + + node + end + + # {#process}es each node from `nodes` and returns an array of + # results. + # + # @param [Array] nodes + # @return [Array] + def process_all(nodes) + nodes.to_a.map do |node| + process node + end + end + + # Default handler. Does nothing. + # + # @param [AST::Node] node + # @return [AST::Node, nil] + def handler_missing(node) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/ast-2.4.3/lib/ast/sexp.rb b/vendor/bundle/ruby/3.4.0/gems/ast-2.4.3/lib/ast/sexp.rb new file mode 100644 index 00000000..fa8a63d4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/ast-2.4.3/lib/ast/sexp.rb @@ -0,0 +1,30 @@ +module AST + # This simple module is very useful in the cases where one needs + # to define deeply nested ASTs from Ruby code, for example, in + # tests. It should be used like this: + # + # describe YourLanguage do + # include ::AST::Sexp + # + # it "should correctly parse expressions" do + # YourLanguage.parse("1 + 2 * 3").should == + # s(:add, + # s(:integer, 1), + # s(:multiply, + # s(:integer, 2), + # s(:integer, 3))) + # end + # end + # + # This way the amount of boilerplate code is greatly reduced. + module Sexp + # Creates a {Node} with type `type` and children `children`. + # Note that the resulting node is of the type AST::Node and not a + # subclass. + # This would not pose a problem with comparisons, as {Node#==} + # ignores metadata. + def s(type, *children) + Node.new(type, children) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/base64-0.3.0/BSDL b/vendor/bundle/ruby/3.4.0/gems/base64-0.3.0/BSDL new file mode 100644 index 00000000..66d93598 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/base64-0.3.0/BSDL @@ -0,0 +1,22 @@ +Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/vendor/bundle/ruby/3.4.0/gems/base64-0.3.0/COPYING b/vendor/bundle/ruby/3.4.0/gems/base64-0.3.0/COPYING new file mode 100644 index 00000000..48e5a96d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/base64-0.3.0/COPYING @@ -0,0 +1,56 @@ +Ruby is copyrighted free software by Yukihiro Matsumoto . +You can redistribute it and/or modify it under either the terms of the +2-clause BSDL (see the file BSDL), or the conditions below: + +1. You may make and give away verbatim copies of the source form of the + software without restriction, provided that you duplicate all of the + original copyright notices and associated disclaimers. + +2. You may modify your copy of the software in any way, provided that + you do at least ONE of the following: + + a. place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said + modifications to Usenet or an equivalent medium, or by allowing + the author to include your modifications in the software. + + b. use the modified software only within your corporation or + organization. + + c. give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d. make other distribution arrangements with the author. + +3. You may distribute the software in object code or binary form, + provided that you do at least ONE of the following: + + a. distribute the binaries and library files of the software, + together with instructions (in the manual page or equivalent) + on where to get the original distribution. + + b. accompany the distribution with the machine-readable source of + the software. + + c. give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d. make other distribution arrangements with the author. + +4. You may modify and include the part of the software into any other + software (possibly commercial). But some files in the distribution + are not written by the author, so that they are not under these terms. + + For the list of those files and their copying conditions, see the + file LEGAL. + +5. The scripts and library files supplied as input to or produced as + output from the software do not automatically fall under the + copyright of the software, but belong to whomever generated them, + and may be sold commercially, and may be aggregated with this + software. + +6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. diff --git a/vendor/bundle/ruby/3.4.0/gems/base64-0.3.0/LEGAL b/vendor/bundle/ruby/3.4.0/gems/base64-0.3.0/LEGAL new file mode 100644 index 00000000..f2d80147 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/base64-0.3.0/LEGAL @@ -0,0 +1,60 @@ +# -*- rdoc -*- + += LEGAL NOTICE INFORMATION +-------------------------- + +All the files in this distribution are covered under either the Ruby's +license (see the file COPYING) or public-domain except some files +mentioned below. + +== MIT License +>>> + 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 AUTHORS OR COPYRIGHT HOLDERS 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. + +== Old-style BSD license +>>> + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + IMPORTANT NOTE:: + + From ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change + paragraph 3 above is now null and void. diff --git a/vendor/bundle/ruby/3.4.0/gems/base64-0.3.0/README.md b/vendor/bundle/ruby/3.4.0/gems/base64-0.3.0/README.md new file mode 100644 index 00000000..a29c58e7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/base64-0.3.0/README.md @@ -0,0 +1,48 @@ +# Base64 + +The Base64 module provides for the encoding (`#encode64`, `#strict_encode64`, +`#urlsafe_encode64`) and decoding (`#decode64`, `#strict_decode64`, +`#urlsafe_decode64`) of binary data using a Base64 representation. + +## Installation + +Add this line to your application's Gemfile: + +```ruby +gem 'base64' +``` + +And then execute: + + $ bundle install + +Or install it yourself as: + + $ gem install base64 + +## Usage + +A simple encoding and decoding. + +```ruby +require "base64" + +enc = Base64.encode64('Send reinforcements') + # -> "U2VuZCByZWluZm9yY2VtZW50cw==\n" +plain = Base64.decode64(enc) + # -> "Send reinforcements" +``` + +The purpose of using base64 to encode data is that it translates any +binary data into purely printable characters. + +## Development + +After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. + +To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). + +## Contributing + +Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/base64. + diff --git a/vendor/bundle/ruby/3.4.0/gems/base64-0.3.0/lib/base64.rb b/vendor/bundle/ruby/3.4.0/gems/base64-0.3.0/lib/base64.rb new file mode 100644 index 00000000..8c0145d2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/base64-0.3.0/lib/base64.rb @@ -0,0 +1,381 @@ +# frozen_string_literal: true +# +# \Module \Base64 provides methods for: +# +# - \Encoding a binary string (containing non-ASCII characters) +# as a string of printable ASCII characters. +# - Decoding such an encoded string. +# +# \Base64 is commonly used in contexts where binary data +# is not allowed or supported: +# +# - Images in HTML or CSS files, or in URLs. +# - Email attachments. +# +# A \Base64-encoded string is about one-third larger that its source. +# See the {Wikipedia article}[https://en.wikipedia.org/wiki/Base64] +# for more information. +# +# This module provides three pairs of encode/decode methods. +# Your choices among these methods should depend on: +# +# - Which character set is to be used for encoding and decoding. +# - Whether "padding" is to be used. +# - Whether encoded strings are to contain newlines. +# +# Note: Examples on this page assume that the including program has executed: +# +# require 'base64' +# +# == \Encoding Character Sets +# +# A \Base64-encoded string consists only of characters from a 64-character set: +# +# - ('A'..'Z'). +# - ('a'..'z'). +# - ('0'..'9'). +# - =, the 'padding' character. +# - Either: +# - %w[+ /]: +# {RFC-2045-compliant}[https://datatracker.ietf.org/doc/html/rfc2045]; +# _not_ safe for URLs. +# - %w[- _]: +# {RFC-4648-compliant}[https://datatracker.ietf.org/doc/html/rfc4648]; +# safe for URLs. +# +# If you are working with \Base64-encoded strings that will come from +# or be put into URLs, you should choose this encoder-decoder pair +# of RFC-4648-compliant methods: +# +# - Base64.urlsafe_encode64 and Base64.urlsafe_decode64. +# +# Otherwise, you may choose any of the pairs in this module, +# including the pair above, or the RFC-2045-compliant pairs: +# +# - Base64.encode64 and Base64.decode64. +# - Base64.strict_encode64 and Base64.strict_decode64. +# +# == Padding +# +# \Base64-encoding changes a triplet of input bytes +# into a quartet of output characters. +# +# Padding in Encode Methods +# +# Padding -- extending an encoded string with zero, one, or two trailing +# = characters -- is performed by methods Base64.encode64, +# Base64.strict_encode64, and, by default, Base64.urlsafe_encode64: +# +# Base64.encode64('s') # => "cw==\n" +# Base64.strict_encode64('s') # => "cw==" +# Base64.urlsafe_encode64('s') # => "cw==" +# Base64.urlsafe_encode64('s', padding: false) # => "cw" +# +# When padding is performed, the encoded string is always of length 4n, +# where +n+ is a non-negative integer: +# +# - Input bytes of length 3n generate unpadded output characters +# of length 4n: +# +# # n = 1: 3 bytes => 4 characters. +# Base64.strict_encode64('123') # => "MDEy" +# # n = 2: 6 bytes => 8 characters. +# Base64.strict_encode64('123456') # => "MDEyMzQ1" +# +# - Input bytes of length 3n+1 generate padded output characters +# of length 4(n+1), with two padding characters at the end: +# +# # n = 1: 4 bytes => 8 characters. +# Base64.strict_encode64('1234') # => "MDEyMw==" +# # n = 2: 7 bytes => 12 characters. +# Base64.strict_encode64('1234567') # => "MDEyMzQ1Ng==" +# +# - Input bytes of length 3n+2 generate padded output characters +# of length 4(n+1), with one padding character at the end: +# +# # n = 1: 5 bytes => 8 characters. +# Base64.strict_encode64('12345') # => "MDEyMzQ=" +# # n = 2: 8 bytes => 12 characters. +# Base64.strict_encode64('12345678') # => "MDEyMzQ1Njc=" +# +# When padding is suppressed, for a positive integer n: +# +# - Input bytes of length 3n generate unpadded output characters +# of length 4n: +# +# # n = 1: 3 bytes => 4 characters. +# Base64.urlsafe_encode64('123', padding: false) # => "MDEy" +# # n = 2: 6 bytes => 8 characters. +# Base64.urlsafe_encode64('123456', padding: false) # => "MDEyMzQ1" +# +# - Input bytes of length 3n+1 generate unpadded output characters +# of length 4n+2, with two padding characters at the end: +# +# # n = 1: 4 bytes => 6 characters. +# Base64.urlsafe_encode64('1234', padding: false) # => "MDEyMw" +# # n = 2: 7 bytes => 10 characters. +# Base64.urlsafe_encode64('1234567', padding: false) # => "MDEyMzQ1Ng" +# +# - Input bytes of length 3n+2 generate unpadded output characters +# of length 4n+3, with one padding character at the end: +# +# # n = 1: 5 bytes => 7 characters. +# Base64.urlsafe_encode64('12345', padding: false) # => "MDEyMzQ" +# # m = 2: 8 bytes => 11 characters. +# Base64.urlsafe_encode64('12345678', padding: false) # => "MDEyMzQ1Njc" +# +# Padding in Decode Methods +# +# All of the \Base64 decode methods support (but do not require) padding. +# +# \Method Base64.decode64 does not check the size of the padding: +# +# Base64.decode64("MDEyMzQ1Njc") # => "01234567" +# Base64.decode64("MDEyMzQ1Njc=") # => "01234567" +# Base64.decode64("MDEyMzQ1Njc==") # => "01234567" +# +# \Method Base64.strict_decode64 strictly enforces padding size: +# +# Base64.strict_decode64("MDEyMzQ1Njc") # Raises ArgumentError +# Base64.strict_decode64("MDEyMzQ1Njc=") # => "01234567" +# Base64.strict_decode64("MDEyMzQ1Njc==") # Raises ArgumentError +# +# \Method Base64.urlsafe_decode64 allows padding in the encoded string, +# which if present, must be correct: +# see {Padding}[Base64.html#module-Base64-label-Padding], above: +# +# Base64.urlsafe_decode64("MDEyMzQ1Njc") # => "01234567" +# Base64.urlsafe_decode64("MDEyMzQ1Njc=") # => "01234567" +# Base64.urlsafe_decode64("MDEyMzQ1Njc==") # Raises ArgumentError. +# +# == Newlines +# +# An encoded string returned by Base64.encode64 or Base64.urlsafe_encode64 +# has an embedded newline character +# after each 60-character sequence, and, if non-empty, at the end: +# +# # No newline if empty. +# encoded = Base64.encode64("\x00" * 0) +# encoded.index("\n") # => nil +# +# # Newline at end of short output. +# encoded = Base64.encode64("\x00" * 1) +# encoded.size # => 4 +# encoded.index("\n") # => 4 +# +# # Newline at end of longer output. +# encoded = Base64.encode64("\x00" * 45) +# encoded.size # => 60 +# encoded.index("\n") # => 60 +# +# # Newlines embedded and at end of still longer output. +# encoded = Base64.encode64("\x00" * 46) +# encoded.size # => 65 +# encoded.rindex("\n") # => 65 +# encoded.split("\n").map {|s| s.size } # => [60, 4] +# +# The string to be encoded may itself contain newlines, +# which are encoded as \Base64: +# +# # Base64.encode64("\n\n\n") # => "CgoK\n" +# s = "This is line 1\nThis is line 2\n" +# Base64.encode64(s) # => "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK\n" +# +module Base64 + + VERSION = "0.3.0" + + module_function + + # :call-seq: + # Base64.encode64(string) -> encoded_string + # + # Returns a string containing the RFC-2045-compliant \Base64-encoding of +string+. + # + # Per RFC 2045, the returned string may contain the URL-unsafe characters + # + or /; + # see {Encoding Character Set}[Base64.html#module-Base64-label-Encoding+Character+Sets] above: + # + # Base64.encode64("\xFB\xEF\xBE") # => "++++\n" + # Base64.encode64("\xFF\xFF\xFF") # => "////\n" + # + # The returned string may include padding; + # see {Padding}[Base64.html#module-Base64-label-Padding] above. + # + # Base64.encode64('*') # => "Kg==\n" + # + # The returned string ends with a newline character, and if sufficiently long + # will have one or more embedded newline characters; + # see {Newlines}[Base64.html#module-Base64-label-Newlines] above: + # + # Base64.encode64('*') # => "Kg==\n" + # Base64.encode64('*' * 46) + # # => "KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq\nKg==\n" + # + # The string to be encoded may itself contain newlines, + # which will be encoded as ordinary \Base64: + # + # Base64.encode64("\n\n\n") # => "CgoK\n" + # s = "This is line 1\nThis is line 2\n" + # Base64.encode64(s) # => "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK\n" + # + def encode64(bin) + [bin].pack("m") + end + + # :call-seq: + # Base64.decode(encoded_string) -> decoded_string + # + # Returns a string containing the decoding of an RFC-2045-compliant + # \Base64-encoded string +encoded_string+: + # + # s = "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK\n" + # Base64.decode64(s) # => "This is line 1\nThis is line 2\n" + # + # Non-\Base64 characters in +encoded_string+ are ignored; + # see {Encoding Character Set}[Base64.html#module-Base64-label-Encoding+Character+Sets] above: + # these include newline characters and characters - and /: + # + # Base64.decode64("\x00\n-_") # => "" + # + # Padding in +encoded_string+ (even if incorrect) is ignored: + # + # Base64.decode64("MDEyMzQ1Njc") # => "01234567" + # Base64.decode64("MDEyMzQ1Njc=") # => "01234567" + # Base64.decode64("MDEyMzQ1Njc==") # => "01234567" + # + def decode64(str) + str.unpack1("m") + end + + # :call-seq: + # Base64.strict_encode64(string) -> encoded_string + # + # Returns a string containing the RFC-2045-compliant \Base64-encoding of +string+. + # + # Per RFC 2045, the returned string may contain the URL-unsafe characters + # + or /; + # see {Encoding Character Set}[Base64.html#module-Base64-label-Encoding+Character+Sets] above: + # + # Base64.strict_encode64("\xFB\xEF\xBE") # => "++++\n" + # Base64.strict_encode64("\xFF\xFF\xFF") # => "////\n" + # + # The returned string may include padding; + # see {Padding}[Base64.html#module-Base64-label-Padding] above. + # + # Base64.strict_encode64('*') # => "Kg==\n" + # + # The returned string will have no newline characters, regardless of its length; + # see {Newlines}[Base64.html#module-Base64-label-Newlines] above: + # + # Base64.strict_encode64('*') # => "Kg==" + # Base64.strict_encode64('*' * 46) + # # => "KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKg==" + # + # The string to be encoded may itself contain newlines, + # which will be encoded as ordinary \Base64: + # + # Base64.strict_encode64("\n\n\n") # => "CgoK" + # s = "This is line 1\nThis is line 2\n" + # Base64.strict_encode64(s) # => "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK" + # + def strict_encode64(bin) + [bin].pack("m0") + end + + # :call-seq: + # Base64.strict_decode64(encoded_string) -> decoded_string + # + # Returns a string containing the decoding of an RFC-2045-compliant + # \Base64-encoded string +encoded_string+: + # + # s = "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK" + # Base64.strict_decode64(s) # => "This is line 1\nThis is line 2\n" + # + # Non-\Base64 characters in +encoded_string+ are not allowed; + # see {Encoding Character Set}[Base64.html#module-Base64-label-Encoding+Character+Sets] above: + # these include newline characters and characters - and /: + # + # Base64.strict_decode64("\n") # Raises ArgumentError + # Base64.strict_decode64('-') # Raises ArgumentError + # Base64.strict_decode64('_') # Raises ArgumentError + # + # Padding in +encoded_string+, if present, must be correct: + # + # Base64.strict_decode64("MDEyMzQ1Njc") # Raises ArgumentError + # Base64.strict_decode64("MDEyMzQ1Njc=") # => "01234567" + # Base64.strict_decode64("MDEyMzQ1Njc==") # Raises ArgumentError + # + def strict_decode64(str) + str.unpack1("m0") + end + + # :call-seq: + # Base64.urlsafe_encode64(string) -> encoded_string + # + # Returns the RFC-4648-compliant \Base64-encoding of +string+. + # + # Per RFC 4648, the returned string will not contain the URL-unsafe characters + # + or /, + # but instead may contain the URL-safe characters + # - and _; + # see {Encoding Character Set}[Base64.html#module-Base64-label-Encoding+Character+Sets] above: + # + # Base64.urlsafe_encode64("\xFB\xEF\xBE") # => "----" + # Base64.urlsafe_encode64("\xFF\xFF\xFF") # => "____" + # + # By default, the returned string may have padding; + # see {Padding}[Base64.html#module-Base64-label-Padding], above: + # + # Base64.urlsafe_encode64('*') # => "Kg==" + # + # Optionally, you can suppress padding: + # + # Base64.urlsafe_encode64('*', padding: false) # => "Kg" + # + # The returned string will have no newline characters, regardless of its length; + # see {Newlines}[Base64.html#module-Base64-label-Newlines] above: + # + # Base64.urlsafe_encode64('*') # => "Kg==" + # Base64.urlsafe_encode64('*' * 46) + # # => "KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKg==" + # + def urlsafe_encode64(bin, padding: true) + str = strict_encode64(bin) + str.chomp!("==") or str.chomp!("=") unless padding + str.tr!("+/", "-_") + str + end + + # :call-seq: + # Base64.urlsafe_decode64(encoded_string) -> decoded_string + # + # Returns the decoding of an RFC-4648-compliant \Base64-encoded string +encoded_string+: + # + # +encoded_string+ may not contain non-Base64 characters; + # see {Encoding Character Set}[Base64.html#module-Base64-label-Encoding+Character+Sets] above: + # + # Base64.urlsafe_decode64('+') # Raises ArgumentError. + # Base64.urlsafe_decode64('/') # Raises ArgumentError. + # Base64.urlsafe_decode64("\n") # Raises ArgumentError. + # + # Padding in +encoded_string+, if present, must be correct: + # see {Padding}[Base64.html#module-Base64-label-Padding], above: + # + # Base64.urlsafe_decode64("MDEyMzQ1Njc") # => "01234567" + # Base64.urlsafe_decode64("MDEyMzQ1Njc=") # => "01234567" + # Base64.urlsafe_decode64("MDEyMzQ1Njc==") # Raises ArgumentError. + # + def urlsafe_decode64(str) + # NOTE: RFC 4648 does say nothing about unpadded input, but says that + # "the excess pad characters MAY also be ignored", so it is inferred that + # unpadded input is also acceptable. + if !str.end_with?("=") && str.length % 4 != 0 + str = str.ljust((str.length + 3) & ~3, "=") + str.tr!("-_", "+/") + else + str = str.tr("-_", "+/") + end + strict_decode64(str) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/base64-0.3.0/sig/base64.rbs b/vendor/bundle/ruby/3.4.0/gems/base64-0.3.0/sig/base64.rbs new file mode 100644 index 00000000..147e874c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/base64-0.3.0/sig/base64.rbs @@ -0,0 +1,355 @@ +# +# Module Base64 provides methods for: +# +# * Encoding a binary string (containing non-ASCII characters) as a string of +# printable ASCII characters. +# * Decoding such an encoded string. +# +# Base64 is commonly used in contexts where binary data is not allowed or +# supported: +# +# * Images in HTML or CSS files, or in URLs. +# * Email attachments. +# +# A Base64-encoded string is about one-third larger that its source. See the +# [Wikipedia article](https://en.wikipedia.org/wiki/Base64) for more +# information. +# +# This module provides three pairs of encode/decode methods. Your choices among +# these methods should depend on: +# +# * Which character set is to be used for encoding and decoding. +# * Whether "padding" is to be used. +# * Whether encoded strings are to contain newlines. +# +# Note: Examples on this page assume that the including program has executed: +# +# require 'base64' +# +# ## Encoding Character Sets +# +# A Base64-encoded string consists only of characters from a 64-character set: +# +# * `('A'..'Z')`. +# * `('a'..'z')`. +# * `('0'..'9')`. +# * `=`, the 'padding' character. +# * Either: +# * `%w[+ /]`: +# [RFC-2045-compliant](https://datatracker.ietf.org/doc/html/rfc2045); +# *not* safe for URLs. +# * `%w[- _]`: +# [RFC-4648-compliant](https://datatracker.ietf.org/doc/html/rfc4648); +# safe for URLs. +# +# If you are working with Base64-encoded strings that will come from or be put +# into URLs, you should choose this encoder-decoder pair of RFC-4648-compliant +# methods: +# +# * Base64.urlsafe_encode64 and Base64.urlsafe_decode64. +# +# Otherwise, you may choose any of the pairs in this module, including the pair +# above, or the RFC-2045-compliant pairs: +# +# * Base64.encode64 and Base64.decode64. +# * Base64.strict_encode64 and Base64.strict_decode64. +# +# ## Padding +# +# Base64-encoding changes a triplet of input bytes into a quartet of output +# characters. +# +# **Padding in Encode Methods** +# +# Padding -- extending an encoded string with zero, one, or two trailing `=` +# characters -- is performed by methods Base64.encode64, Base64.strict_encode64, +# and, by default, Base64.urlsafe_encode64: +# +# Base64.encode64('s') # => "cw==\n" +# Base64.strict_encode64('s') # => "cw==" +# Base64.urlsafe_encode64('s') # => "cw==" +# Base64.urlsafe_encode64('s', padding: false) # => "cw" +# +# When padding is performed, the encoded string is always of length *4n*, where +# `n` is a non-negative integer: +# +# * Input bytes of length *3n* generate unpadded output characters of length +# *4n*: +# +# # n = 1: 3 bytes => 4 characters. +# Base64.strict_encode64('123') # => "MDEy" +# # n = 2: 6 bytes => 8 characters. +# Base64.strict_encode64('123456') # => "MDEyMzQ1" +# +# * Input bytes of length *3n+1* generate padded output characters of length +# *4(n+1)*, with two padding characters at the end: +# +# # n = 1: 4 bytes => 8 characters. +# Base64.strict_encode64('1234') # => "MDEyMw==" +# # n = 2: 7 bytes => 12 characters. +# Base64.strict_encode64('1234567') # => "MDEyMzQ1Ng==" +# +# * Input bytes of length *3n+2* generate padded output characters of length +# *4(n+1)*, with one padding character at the end: +# +# # n = 1: 5 bytes => 8 characters. +# Base64.strict_encode64('12345') # => "MDEyMzQ=" +# # n = 2: 8 bytes => 12 characters. +# Base64.strict_encode64('12345678') # => "MDEyMzQ1Njc=" +# +# When padding is suppressed, for a positive integer *n*: +# +# * Input bytes of length *3n* generate unpadded output characters of length +# *4n*: +# +# # n = 1: 3 bytes => 4 characters. +# Base64.urlsafe_encode64('123', padding: false) # => "MDEy" +# # n = 2: 6 bytes => 8 characters. +# Base64.urlsafe_encode64('123456', padding: false) # => "MDEyMzQ1" +# +# * Input bytes of length *3n+1* generate unpadded output characters of length +# *4n+2*, with two padding characters at the end: +# +# # n = 1: 4 bytes => 6 characters. +# Base64.urlsafe_encode64('1234', padding: false) # => "MDEyMw" +# # n = 2: 7 bytes => 10 characters. +# Base64.urlsafe_encode64('1234567', padding: false) # => "MDEyMzQ1Ng" +# +# * Input bytes of length *3n+2* generate unpadded output characters of length +# *4n+3*, with one padding character at the end: +# +# # n = 1: 5 bytes => 7 characters. +# Base64.urlsafe_encode64('12345', padding: false) # => "MDEyMzQ" +# # m = 2: 8 bytes => 11 characters. +# Base64.urlsafe_encode64('12345678', padding: false) # => "MDEyMzQ1Njc" +# +# **Padding in Decode Methods** +# +# All of the Base64 decode methods support (but do not require) padding. +# +# Method Base64.decode64 does not check the size of the padding: +# +# Base64.decode64("MDEyMzQ1Njc") # => "01234567" +# Base64.decode64("MDEyMzQ1Njc=") # => "01234567" +# Base64.decode64("MDEyMzQ1Njc==") # => "01234567" +# +# Method Base64.strict_decode64 strictly enforces padding size: +# +# Base64.strict_decode64("MDEyMzQ1Njc") # Raises ArgumentError +# Base64.strict_decode64("MDEyMzQ1Njc=") # => "01234567" +# Base64.strict_decode64("MDEyMzQ1Njc==") # Raises ArgumentError +# +# Method Base64.urlsafe_decode64 allows padding in `str`, which if present, must +# be correct: see [Padding](Base64.html#module-Base64-label-Padding), above: +# +# Base64.urlsafe_decode64("MDEyMzQ1Njc") # => "01234567" +# Base64.urlsafe_decode64("MDEyMzQ1Njc=") # => "01234567" +# Base64.urlsafe_decode64("MDEyMzQ1Njc==") # Raises ArgumentError. +# +# ## Newlines +# +# An encoded string returned by Base64.encode64 or Base64.urlsafe_encode64 has +# an embedded newline character after each 60-character sequence, and, if +# non-empty, at the end: +# +# # No newline if empty. +# encoded = Base64.encode64("\x00" * 0) +# encoded.index("\n") # => nil +# +# # Newline at end of short output. +# encoded = Base64.encode64("\x00" * 1) +# encoded.size # => 4 +# encoded.index("\n") # => 4 +# +# # Newline at end of longer output. +# encoded = Base64.encode64("\x00" * 45) +# encoded.size # => 60 +# encoded.index("\n") # => 60 +# +# # Newlines embedded and at end of still longer output. +# encoded = Base64.encode64("\x00" * 46) +# encoded.size # => 65 +# encoded.rindex("\n") # => 65 +# encoded.split("\n").map {|s| s.size } # => [60, 4] +# +# The string to be encoded may itself contain newlines, which are encoded as +# Base64: +# +# # Base64.encode64("\n\n\n") # => "CgoK\n" +# s = "This is line 1\nThis is line 2\n" +# Base64.encode64(s) # => "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK\n" +# +module Base64 + # + # Returns a string containing the decoding of an RFC-2045-compliant + # Base64-encoded string `str`: + # + # s = "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK\n" + # Base64.decode64(s) # => "This is line 1\nThis is line 2\n" + # + # Non-Base64 characters in `str` are ignored; see [Encoding Character + # Set](Base64.html#module-Base64-label-Encoding+Character+Sets) above: these + # include newline characters and characters `-` and `/`: + # + # Base64.decode64("\x00\n-_") # => "" + # + # Padding in `str` (even if incorrect) is ignored: + # + # Base64.decode64("MDEyMzQ1Njc") # => "01234567" + # Base64.decode64("MDEyMzQ1Njc=") # => "01234567" + # Base64.decode64("MDEyMzQ1Njc==") # => "01234567" + # + def self?.decode64: (String str) -> String + + # + # Returns a string containing the RFC-2045-compliant Base64-encoding of `bin`. + # + # Per RFC 2045, the returned string may contain the URL-unsafe characters `+` or + # `/`; see [Encoding Character + # Set](Base64.html#module-Base64-label-Encoding+Character+Sets) above: + # + # Base64.encode64("\xFB\xEF\xBE") # => "++++\n" + # Base64.encode64("\xFF\xFF\xFF") # => "////\n" + # + # The returned string may include padding; see + # [Padding](Base64.html#module-Base64-label-Padding) above. + # + # Base64.encode64('*') # => "Kg==\n" + # + # The returned string ends with a newline character, and if sufficiently long + # will have one or more embedded newline characters; see + # [Newlines](Base64.html#module-Base64-label-Newlines) above: + # + # Base64.encode64('*') # => "Kg==\n" + # Base64.encode64('*' * 46) + # # => "KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq\nKg==\n" + # + # The string to be encoded may itself contain newlines, which will be encoded as + # ordinary Base64: + # + # Base64.encode64("\n\n\n") # => "CgoK\n" + # s = "This is line 1\nThis is line 2\n" + # Base64.encode64(s) # => "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK\n" + # + def self?.encode64: (String bin) -> String + + # + # Returns a string containing the decoding of an RFC-2045-compliant + # Base64-encoded string `str`: + # + # s = "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK" + # Base64.strict_decode64(s) # => "This is line 1\nThis is line 2\n" + # + # Non-Base64 characters in `str` not allowed; see [Encoding Character + # Set](Base64.html#module-Base64-label-Encoding+Character+Sets) above: these + # include newline characters and characters `-` and `/`: + # + # Base64.strict_decode64("\n") # Raises ArgumentError + # Base64.strict_decode64('-') # Raises ArgumentError + # Base64.strict_decode64('_') # Raises ArgumentError + # + # Padding in `str`, if present, must be correct: + # + # Base64.strict_decode64("MDEyMzQ1Njc") # Raises ArgumentError + # Base64.strict_decode64("MDEyMzQ1Njc=") # => "01234567" + # Base64.strict_decode64("MDEyMzQ1Njc==") # Raises ArgumentError + # + def self?.strict_decode64: (String str) -> String + + # + # Returns a string containing the RFC-2045-compliant Base64-encoding of `bin`. + # + # Per RFC 2045, the returned string may contain the URL-unsafe characters `+` or + # `/`; see [Encoding Character + # Set](Base64.html#module-Base64-label-Encoding+Character+Sets) above: + # + # Base64.strict_encode64("\xFB\xEF\xBE") # => "++++\n" + # Base64.strict_encode64("\xFF\xFF\xFF") # => "////\n" + # + # The returned string may include padding; see + # [Padding](Base64.html#module-Base64-label-Padding) above. + # + # Base64.strict_encode64('*') # => "Kg==\n" + # + # The returned string will have no newline characters, regardless of its length; + # see [Newlines](Base64.html#module-Base64-label-Newlines) above: + # + # Base64.strict_encode64('*') # => "Kg==" + # Base64.strict_encode64('*' * 46) + # # => "KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKg==" + # + # The string to be encoded may itself contain newlines, which will be encoded as + # ordinary Base64: + # + # Base64.strict_encode64("\n\n\n") # => "CgoK" + # s = "This is line 1\nThis is line 2\n" + # Base64.strict_encode64(s) # => "VGhpcyBpcyBsaW5lIDEKVGhpcyBpcyBsaW5lIDIK" + # + def self?.strict_encode64: (String bin) -> String + + # + # Returns the decoding of an RFC-4648-compliant Base64-encoded string `str`: + # + # `str` may not contain non-Base64 characters; see [Encoding Character + # Set](Base64.html#module-Base64-label-Encoding+Character+Sets) above: + # + # Base64.urlsafe_decode64('+') # Raises ArgumentError. + # Base64.urlsafe_decode64('/') # Raises ArgumentError. + # Base64.urlsafe_decode64("\n") # Raises ArgumentError. + # + # Padding in `str`, if present, must be correct: see + # [Padding](Base64.html#module-Base64-label-Padding), above: + # + # Base64.urlsafe_decode64("MDEyMzQ1Njc") # => "01234567" + # Base64.urlsafe_decode64("MDEyMzQ1Njc=") # => "01234567" + # Base64.urlsafe_decode64("MDEyMzQ1Njc==") # Raises ArgumentError. + # + def self?.urlsafe_decode64: (String str) -> String + + # + # Returns the RFC-4648-compliant Base64-encoding of `bin`. + # + # Per RFC 4648, the returned string will not contain the URL-unsafe characters + # `+` or `/`, but instead may contain the URL-safe characters `-` and `_`; see + # [Encoding Character + # Set](Base64.html#module-Base64-label-Encoding+Character+Sets) above: + # + # Base64.urlsafe_encode64("\xFB\xEF\xBE") # => "----" + # Base64.urlsafe_encode64("\xFF\xFF\xFF") # => "____" + # + # By default, the returned string may have padding; see + # [Padding](Base64.html#module-Base64-label-Padding), above: + # + # Base64.urlsafe_encode64('*') # => "Kg==" + # + # Optionally, you can suppress padding: + # + # Base64.urlsafe_encode64('*', padding: false) # => "Kg" + # + # The returned string will have no newline characters, regardless of its length; + # see [Newlines](Base64.html#module-Base64-label-Newlines) above: + # + # Base64.urlsafe_encode64('*') # => "Kg==" + # Base64.urlsafe_encode64('*' * 46) + # # => "KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKg==" + # + def self?.urlsafe_encode64: (String bin, ?padding: boolish) -> String +end diff --git a/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/.github/dependabot.yml b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/.github/dependabot.yml new file mode 100644 index 00000000..b18fd293 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: 'github-actions' + directory: '/' + schedule: + interval: 'weekly' diff --git a/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/.github/workflows/push_gem.yml b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/.github/workflows/push_gem.yml new file mode 100644 index 00000000..5019826c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/.github/workflows/push_gem.yml @@ -0,0 +1,46 @@ +name: Publish gem to rubygems.org + +on: + push: + tags: + - 'v*' + +permissions: + contents: read + +jobs: + push: + if: github.repository == 'ruby/benchmark' + runs-on: ubuntu-latest + + environment: + name: rubygems.org + url: https://rubygems.org/gems/benchmark + + permissions: + contents: write + id-token: write + + steps: + - name: Harden Runner + uses: step-security/harden-runner@0634a2670c59f64b4a01f0f96f84700a4088b9f0 # v2.12.0 + with: + egress-policy: audit + + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 + + - name: Set up Ruby + uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0 + with: + bundler-cache: true + ruby-version: ruby + + - name: Publish to RubyGems + uses: rubygems/release-gem@a25424ba2ba8b387abc8ef40807c2c85b96cbe32 # v1.1.1 + + - name: Create GitHub release + run: | + tag_name="$(git describe --tags --abbrev=0)" + gh release create "${tag_name}" --verify-tag --generate-notes + env: + GITHUB_TOKEN: ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }} diff --git a/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/.github/workflows/test.yml b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/.github/workflows/test.yml new file mode 100644 index 00000000..74a4e7e0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/.github/workflows/test.yml @@ -0,0 +1,32 @@ +name: test + +on: [push, pull_request] + +jobs: + ruby-versions: + uses: ruby/actions/.github/workflows/ruby_versions.yml@master + with: + min_version: 2.5 + + test: + needs: ruby-versions + name: build (${{ matrix.ruby }} / ${{ matrix.os }}) + strategy: + matrix: + ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }} + os: [ ubuntu-latest, macos-latest, windows-latest ] + exclude: + - { os: macos-latest, ruby: 2.5 } + - { os: windows-latest, ruby: truffleruby-head } + - { os: windows-latest, ruby: truffleruby } + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + - name: Install dependencies + run: bundle install + - name: Run test + run: rake test diff --git a/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/.gitignore b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/.gitignore new file mode 100644 index 00000000..4ea57987 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/.gitignore @@ -0,0 +1,9 @@ +/.bundle/ +/.yardoc +/_yardoc/ +/coverage/ +/doc/ +/pkg/ +/spec/reports/ +/tmp/ +Gemfile.lock diff --git a/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/BSDL b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/BSDL new file mode 100644 index 00000000..66d93598 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/BSDL @@ -0,0 +1,22 @@ +Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/COPYING b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/COPYING new file mode 100644 index 00000000..48e5a96d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/COPYING @@ -0,0 +1,56 @@ +Ruby is copyrighted free software by Yukihiro Matsumoto . +You can redistribute it and/or modify it under either the terms of the +2-clause BSDL (see the file BSDL), or the conditions below: + +1. You may make and give away verbatim copies of the source form of the + software without restriction, provided that you duplicate all of the + original copyright notices and associated disclaimers. + +2. You may modify your copy of the software in any way, provided that + you do at least ONE of the following: + + a. place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said + modifications to Usenet or an equivalent medium, or by allowing + the author to include your modifications in the software. + + b. use the modified software only within your corporation or + organization. + + c. give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d. make other distribution arrangements with the author. + +3. You may distribute the software in object code or binary form, + provided that you do at least ONE of the following: + + a. distribute the binaries and library files of the software, + together with instructions (in the manual page or equivalent) + on where to get the original distribution. + + b. accompany the distribution with the machine-readable source of + the software. + + c. give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d. make other distribution arrangements with the author. + +4. You may modify and include the part of the software into any other + software (possibly commercial). But some files in the distribution + are not written by the author, so that they are not under these terms. + + For the list of those files and their copying conditions, see the + file LEGAL. + +5. The scripts and library files supplied as input to or produced as + output from the software do not automatically fall under the + copyright of the software, but belong to whomever generated them, + and may be sold commercially, and may be aggregated with this + software. + +6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. diff --git a/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/Gemfile b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/Gemfile new file mode 100644 index 00000000..3dc28835 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/Gemfile @@ -0,0 +1,9 @@ +source "https://rubygems.org" + +gemspec + +group :development do + gem "bundler" + gem "rake" + gem "test-unit" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/README.md b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/README.md new file mode 100644 index 00000000..c5705939 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/README.md @@ -0,0 +1,138 @@ +# Benchmark + +The Benchmark module provides methods for benchmarking Ruby code, giving detailed reports on the time taken for each task. + +## Installation + +Add this line to your application's Gemfile: + +```ruby +gem 'benchmark' +``` + +And then execute: + + $ bundle + +Or install it yourself as: + + $ gem install benchmark + +## Usage + +The Benchmark module provides methods to measure and report the time used to execute Ruby code. + +Measure the time to construct the string given by the expression "a"*1_000_000_000: + +```ruby +require 'benchmark' +puts Benchmark.measure { "a"*1_000_000_000 } +``` + +On my machine (OSX 10.8.3 on i5 1.7 GHz) this generates: + +``` +0.350000 0.400000 0.750000 ( 0.835234) +``` + +This report shows the user CPU time, system CPU time, the total time (sum of user CPU time, system CPU time, children's user CPU time, and children's system CPU time), and the elapsed real time. The unit of time is seconds. + +Do some experiments sequentially using the #bm method: + +```ruby +require 'benchmark' +n = 5000000 +Benchmark.bm do |x| + x.report { for i in 1..n; a = "1"; end } + x.report { n.times do ; a = "1"; end } + x.report { 1.upto(n) do ; a = "1"; end } +end +``` + +The result: + +``` + user system total real +1.010000 0.000000 1.010000 ( 1.014479) +1.000000 0.000000 1.000000 ( 0.998261) +0.980000 0.000000 0.980000 ( 0.981335) +``` + +Continuing the previous example, put a label in each report: + +```ruby +require 'benchmark' +n = 5000000 +Benchmark.bm(7) do |x| + x.report("for:") { for i in 1..n; a = "1"; end } + x.report("times:") { n.times do ; a = "1"; end } + x.report("upto:") { 1.upto(n) do ; a = "1"; end } +end +``` + +The result: + +``` + user system total real +for: 1.010000 0.000000 1.010000 ( 1.015688) +times: 1.000000 0.000000 1.000000 ( 1.003611) +upto: 1.030000 0.000000 1.030000 ( 1.028098) +``` + +The times for some benchmarks depend on the order in which items are run. These differences are due to the cost of memory allocation and garbage collection. To avoid these discrepancies, the #bmbm method is provided. For example, to compare ways to sort an array of floats: + +```ruby +require 'benchmark' +array = (1..1000000).map { rand } +Benchmark.bmbm do |x| + x.report("sort!") { array.dup.sort! } + x.report("sort") { array.dup.sort } +end +``` + +The result: + +``` +Rehearsal ----------------------------------------- +sort! 1.490000 0.010000 1.500000 ( 1.490520) +sort 1.460000 0.000000 1.460000 ( 1.463025) +-------------------------------- total: 2.960000sec + user system total real +sort! 1.460000 0.000000 1.460000 ( 1.460465) +sort 1.450000 0.010000 1.460000 ( 1.448327) +``` + +Report statistics of sequential experiments with unique labels, using the #benchmark method: + +```ruby +require 'benchmark' +include Benchmark # we need the CAPTION and FORMAT constants +n = 5000000 +Benchmark.benchmark(CAPTION, 7, FORMAT, ">total:", ">avg:") do |x| + tf = x.report("for:") { for i in 1..n; a = "1"; end } + tt = x.report("times:") { n.times do ; a = "1"; end } + tu = x.report("upto:") { 1.upto(n) do ; a = "1"; end } + [tf+tt+tu, (tf+tt+tu)/3] +end +``` + +The result: + +``` + user system total real +for: 0.950000 0.000000 0.950000 ( 0.952039) +times: 0.980000 0.000000 0.980000 ( 0.984938) +upto: 0.950000 0.000000 0.950000 ( 0.946787) +>total: 2.880000 0.000000 2.880000 ( 2.883764) +>avg: 0.960000 0.000000 0.960000 ( 0.961255) +``` + +## Development + +After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. + +To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). + +## Contributing + +Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/benchmark. diff --git a/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/Rakefile b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/Rakefile new file mode 100644 index 00000000..8830e057 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/Rakefile @@ -0,0 +1,8 @@ +require "bundler/gem_tasks" +require "rake/testtask" + +Rake::TestTask.new(:test) do |t| + t.test_files = FileList["test/**/test_*.rb"] +end + +task :default => :test diff --git a/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/benchmark.gemspec b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/benchmark.gemspec new file mode 100644 index 00000000..35deff8d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/benchmark.gemspec @@ -0,0 +1,32 @@ +name = File.basename(__FILE__, ".gemspec") +version = ["lib", Array.new(name.count("-")+1, ".").join("/")].find do |dir| + break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line| + /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1 + end rescue nil +end + +Gem::Specification.new do |spec| + spec.name = name + spec.version = version + spec.authors = ["Yukihiro Matsumoto"] + spec.email = ["matz@ruby-lang.org"] + + spec.summary = %q{a performance benchmarking library} + spec.description = spec.summary + spec.homepage = "https://github.com/ruby/benchmark" + spec.licenses = ["Ruby", "BSD-2-Clause"] + + spec.required_ruby_version = ">= 2.1.0" + + spec.metadata["homepage_uri"] = spec.homepage + spec.metadata["source_code_uri"] = spec.homepage + + # Specify which files should be added to the gem when it is released. + # The `git ls-files -z` loads the files in the RubyGem that have been added into git. + spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do + `git ls-files -z 2>#{IO::NULL}`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } + end + spec.bindir = "exe" + spec.executables = [] + spec.require_paths = ["lib"] +end diff --git a/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/bin/console b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/bin/console new file mode 100755 index 00000000..87e7b95e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/bin/console @@ -0,0 +1,14 @@ +#!/usr/bin/env ruby + +require "bundler/setup" +require "benchmark" + +# You can add fixtures and/or initialization code here to make experimenting +# with your gem easier. You can also use a different console, if you like. + +# (If you use this, don't forget to add pry to your Gemfile!) +# require "pry" +# Pry.start + +require "irb" +IRB.start(__FILE__) diff --git a/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/bin/setup b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/bin/setup new file mode 100755 index 00000000..dce67d86 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/bin/setup @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -euo pipefail +IFS=$'\n\t' +set -vx + +bundle install + +# Do any other automated setup that you need to do here diff --git a/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/lib/benchmark.rb b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/lib/benchmark.rb new file mode 100644 index 00000000..0d1b8df6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/benchmark-0.4.1/lib/benchmark.rb @@ -0,0 +1,595 @@ +# frozen_string_literal: true +#-- +# benchmark.rb - a performance benchmarking library +# +# $Id$ +# +# Created by Gotoken (gotoken@notwork.org). +# +# Documentation by Gotoken (original RD), Lyle Johnson (RDoc conversion), and +# Gavin Sinclair (editing). +#++ +# +# == Overview +# +# The Benchmark module provides methods for benchmarking Ruby code, giving +# detailed reports on the time taken for each task. +# + +# The Benchmark module provides methods to measure and report the time +# used to execute Ruby code. +# +# * Measure the time to construct the string given by the expression +# "a"*1_000_000_000: +# +# require 'benchmark' +# +# puts Benchmark.measure { "a"*1_000_000_000 } +# +# On my machine (OSX 10.8.3 on i5 1.7 GHz) this generates: +# +# 0.350000 0.400000 0.750000 ( 0.835234) +# +# This report shows the user CPU time, system CPU time, the total time +# (sum of user CPU time, system CPU time, children's user CPU time, +# and children's system CPU time), and the elapsed real time. The unit +# of time is seconds. +# +# * Do some experiments sequentially using the #bm method: +# +# require 'benchmark' +# +# n = 5000000 +# Benchmark.bm do |x| +# x.report { for i in 1..n; a = "1"; end } +# x.report { n.times do ; a = "1"; end } +# x.report { 1.upto(n) do ; a = "1"; end } +# end +# +# The result: +# +# user system total real +# 1.010000 0.000000 1.010000 ( 1.014479) +# 1.000000 0.000000 1.000000 ( 0.998261) +# 0.980000 0.000000 0.980000 ( 0.981335) +# +# * Continuing the previous example, put a label in each report: +# +# require 'benchmark' +# +# n = 5000000 +# Benchmark.bm(7) do |x| +# x.report("for:") { for i in 1..n; a = "1"; end } +# x.report("times:") { n.times do ; a = "1"; end } +# x.report("upto:") { 1.upto(n) do ; a = "1"; end } +# end +# +# The result: +# +# user system total real +# for: 1.010000 0.000000 1.010000 ( 1.015688) +# times: 1.000000 0.000000 1.000000 ( 1.003611) +# upto: 1.030000 0.000000 1.030000 ( 1.028098) +# +# * The times for some benchmarks depend on the order in which items +# are run. These differences are due to the cost of memory +# allocation and garbage collection. To avoid these discrepancies, +# the #bmbm method is provided. For example, to compare ways to +# sort an array of floats: +# +# require 'benchmark' +# +# array = (1..1000000).map { rand } +# +# Benchmark.bmbm do |x| +# x.report("sort!") { array.dup.sort! } +# x.report("sort") { array.dup.sort } +# end +# +# The result: +# +# Rehearsal ----------------------------------------- +# sort! 1.490000 0.010000 1.500000 ( 1.490520) +# sort 1.460000 0.000000 1.460000 ( 1.463025) +# -------------------------------- total: 2.960000sec +# +# user system total real +# sort! 1.460000 0.000000 1.460000 ( 1.460465) +# sort 1.450000 0.010000 1.460000 ( 1.448327) +# +# * Report statistics of sequential experiments with unique labels, +# using the #benchmark method: +# +# require 'benchmark' +# include Benchmark # we need the CAPTION and FORMAT constants +# +# n = 5000000 +# Benchmark.benchmark(CAPTION, 7, FORMAT, ">total:", ">avg:") do |x| +# tf = x.report("for:") { for i in 1..n; a = "1"; end } +# tt = x.report("times:") { n.times do ; a = "1"; end } +# tu = x.report("upto:") { 1.upto(n) do ; a = "1"; end } +# [tf+tt+tu, (tf+tt+tu)/3] +# end +# +# The result: +# +# user system total real +# for: 0.950000 0.000000 0.950000 ( 0.952039) +# times: 0.980000 0.000000 0.980000 ( 0.984938) +# upto: 0.950000 0.000000 0.950000 ( 0.946787) +# >total: 2.880000 0.000000 2.880000 ( 2.883764) +# >avg: 0.960000 0.000000 0.960000 ( 0.961255) + +module Benchmark + + VERSION = "0.4.1" + + BENCHMARK_VERSION = "2002-04-25" # :nodoc: + + # Invokes the block with a Benchmark::Report object, which + # may be used to collect and report on the results of individual + # benchmark tests. Reserves +label_width+ leading spaces for + # labels on each line. Prints +caption+ at the top of the + # report, and uses +format+ to format each line. + # (Note: +caption+ must contain a terminating newline character, + # see the default Benchmark::Tms::CAPTION for an example.) + # + # Returns an array of Benchmark::Tms objects. + # + # If the block returns an array of + # Benchmark::Tms objects, these will be used to format + # additional lines of output. If +labels+ parameter are + # given, these are used to label these extra lines. + # + # _Note_: Other methods provide a simpler interface to this one, and are + # suitable for nearly all benchmarking requirements. See the examples in + # Benchmark, and the #bm and #bmbm methods. + # + # Example: + # + # require 'benchmark' + # include Benchmark # we need the CAPTION and FORMAT constants + # + # n = 5000000 + # Benchmark.benchmark(CAPTION, 7, FORMAT, ">total:", ">avg:") do |x| + # tf = x.report("for:") { for i in 1..n; a = "1"; end } + # tt = x.report("times:") { n.times do ; a = "1"; end } + # tu = x.report("upto:") { 1.upto(n) do ; a = "1"; end } + # [tf+tt+tu, (tf+tt+tu)/3] + # end + # + # Generates: + # + # user system total real + # for: 0.970000 0.000000 0.970000 ( 0.970493) + # times: 0.990000 0.000000 0.990000 ( 0.989542) + # upto: 0.970000 0.000000 0.970000 ( 0.972854) + # >total: 2.930000 0.000000 2.930000 ( 2.932889) + # >avg: 0.976667 0.000000 0.976667 ( 0.977630) + # + + def benchmark(caption = "", label_width = nil, format = nil, *labels) # :yield: report + sync = $stdout.sync + $stdout.sync = true + label_width ||= 0 + label_width += 1 + format ||= FORMAT + report = Report.new(label_width, format) + results = yield(report) + + print " " * report.width + caption unless caption.empty? + report.list.each { |i| + print i.label.to_s.ljust(report.width) + print i.format(report.format, *format) + } + + Array === results and results.grep(Tms).each {|t| + print((labels.shift || t.label || "").ljust(label_width), t.format(format)) + } + report.list + ensure + $stdout.sync = sync unless sync.nil? + end + + + # A simple interface to the #benchmark method, #bm generates sequential + # reports with labels. +label_width+ and +labels+ parameters have the same + # meaning as for #benchmark. + # + # require 'benchmark' + # + # n = 5000000 + # Benchmark.bm(7) do |x| + # x.report("for:") { for i in 1..n; a = "1"; end } + # x.report("times:") { n.times do ; a = "1"; end } + # x.report("upto:") { 1.upto(n) do ; a = "1"; end } + # end + # + # Generates: + # + # user system total real + # for: 0.960000 0.000000 0.960000 ( 0.957966) + # times: 0.960000 0.000000 0.960000 ( 0.960423) + # upto: 0.950000 0.000000 0.950000 ( 0.954864) + # + + def bm(label_width = 0, *labels, &blk) # :yield: report + benchmark(CAPTION, label_width, FORMAT, *labels, &blk) + end + + + # Sometimes benchmark results are skewed because code executed + # earlier encounters different garbage collection overheads than + # that run later. #bmbm attempts to minimize this effect by running + # the tests twice, the first time as a rehearsal in order to get the + # runtime environment stable, the second time for + # real. GC.start is executed before the start of each of + # the real timings; the cost of this is not included in the + # timings. In reality, though, there's only so much that #bmbm can + # do, and the results are not guaranteed to be isolated from garbage + # collection and other effects. + # + # Because #bmbm takes two passes through the tests, it can + # calculate the required label width. + # + # require 'benchmark' + # + # array = (1..1000000).map { rand } + # + # Benchmark.bmbm do |x| + # x.report("sort!") { array.dup.sort! } + # x.report("sort") { array.dup.sort } + # end + # + # Generates: + # + # Rehearsal ----------------------------------------- + # sort! 1.440000 0.010000 1.450000 ( 1.446833) + # sort 1.440000 0.000000 1.440000 ( 1.448257) + # -------------------------------- total: 2.890000sec + # + # user system total real + # sort! 1.460000 0.000000 1.460000 ( 1.458065) + # sort 1.450000 0.000000 1.450000 ( 1.455963) + # + # #bmbm yields a Benchmark::Job object and returns an array of + # Benchmark::Tms objects. + # + def bmbm(width = 0) # :yield: job + job = Job.new(width) + yield(job) + width = job.width + 1 + sync = $stdout.sync + $stdout.sync = true + + # rehearsal + puts 'Rehearsal '.ljust(width+CAPTION.length,'-') + ets = job.list.inject(Tms.new) { |sum,(label,item)| + print label.ljust(width) + res = Benchmark.measure(&item) + print res.format + sum + res + }.format("total: %tsec") + print " #{ets}\n\n".rjust(width+CAPTION.length+2,'-') + + # take + print ' '*width + CAPTION + job.list.map { |label,item| + GC.start + print label.ljust(width) + Benchmark.measure(label, &item).tap { |res| print res } + } + ensure + $stdout.sync = sync unless sync.nil? + end + + # + # Returns the time used to execute the given block as a + # Benchmark::Tms object. Takes +label+ option. + # + # require 'benchmark' + # + # n = 1000000 + # + # time = Benchmark.measure do + # n.times { a = "1" } + # end + # puts time + # + # Generates: + # + # 0.220000 0.000000 0.220000 ( 0.227313) + # + def measure(label = "") # :yield: + t0, r0 = Process.times, Process.clock_gettime(Process::CLOCK_MONOTONIC) + yield + t1, r1 = Process.times, Process.clock_gettime(Process::CLOCK_MONOTONIC) + Benchmark::Tms.new(t1.utime - t0.utime, + t1.stime - t0.stime, + t1.cutime - t0.cutime, + t1.cstime - t0.cstime, + r1 - r0, + label) + end + + # + # Returns the elapsed real time used to execute the given block. + # The unit of time is seconds. + # + # Benchmark.realtime { "a" * 1_000_000_000 } + # #=> 0.5098029999935534 + # + def realtime # :yield: + r0 = Process.clock_gettime(Process::CLOCK_MONOTONIC) + yield + Process.clock_gettime(Process::CLOCK_MONOTONIC) - r0 + end + + module_function :benchmark, :measure, :realtime, :bm, :bmbm + + # + # A Job is a sequence of labelled blocks to be processed by the + # Benchmark.bmbm method. It is of little direct interest to the user. + # + class Job # :nodoc: + # + # Returns an initialized Job instance. + # Usually, one doesn't call this method directly, as new + # Job objects are created by the #bmbm method. + # +width+ is a initial value for the label offset used in formatting; + # the #bmbm method passes its +width+ argument to this constructor. + # + def initialize(width) + @width = width + @list = [] + end + + # + # Registers the given label and block pair in the job list. + # + def item(label = "", &blk) # :yield: + raise ArgumentError, "no block" unless block_given? + label = label.to_s + w = label.length + @width = w if @width < w + @list << [label, blk] + self + end + + alias report item + + # An array of 2-element arrays, consisting of label and block pairs. + attr_reader :list + + # Length of the widest label in the #list. + attr_reader :width + end + + # + # This class is used by the Benchmark.benchmark and Benchmark.bm methods. + # It is of little direct interest to the user. + # + class Report # :nodoc: + # + # Returns an initialized Report instance. + # Usually, one doesn't call this method directly, as new + # Report objects are created by the #benchmark and #bm methods. + # +width+ and +format+ are the label offset and + # format string used by Tms#format. + # + def initialize(width = 0, format = nil) + @width, @format, @list = width, format, [] + end + + # + # Prints the +label+ and measured time for the block, + # formatted by +format+. See Tms#format for the + # formatting rules. + # + def item(label = "", *format, &blk) # :yield: + w = label.to_s.length + @width = w if @width < w + @list << res = Benchmark.measure(label, &blk) + res + end + + alias report item + + # An array of Benchmark::Tms objects representing each item. + attr_reader :width, :format, :list + end + + + + # + # A data object, representing the times associated with a benchmark + # measurement. + # + class Tms + + # Default caption, see also Benchmark::CAPTION + CAPTION = " user system total real\n" + + # Default format string, see also Benchmark::FORMAT + FORMAT = "%10.6u %10.6y %10.6t %10.6r\n" + + # User CPU time + attr_reader :utime + + # System CPU time + attr_reader :stime + + # User CPU time of children + attr_reader :cutime + + # System CPU time of children + attr_reader :cstime + + # Elapsed real time + attr_reader :real + + # Total time, that is +utime+ + +stime+ + +cutime+ + +cstime+ + attr_reader :total + + # Label + attr_reader :label + + # + # Returns an initialized Tms object which has + # +utime+ as the user CPU time, +stime+ as the system CPU time, + # +cutime+ as the children's user CPU time, +cstime+ as the children's + # system CPU time, +real+ as the elapsed real time and +label+ as the label. + # + def initialize(utime = 0.0, stime = 0.0, cutime = 0.0, cstime = 0.0, real = 0.0, label = nil) + @utime, @stime, @cutime, @cstime, @real, @label = utime, stime, cutime, cstime, real, label.to_s + @total = @utime + @stime + @cutime + @cstime + end + + # + # Returns a new Tms object whose times are the sum of the times for this + # Tms object, plus the time required to execute the code block (+blk+). + # + def add(&blk) # :yield: + self + Benchmark.measure(&blk) + end + + # + # An in-place version of #add. + # Changes the times of this Tms object by making it the sum of the times + # for this Tms object, plus the time required to execute + # the code block (+blk+). + # + def add!(&blk) + t = Benchmark.measure(&blk) + @utime = utime + t.utime + @stime = stime + t.stime + @cutime = cutime + t.cutime + @cstime = cstime + t.cstime + @real = real + t.real + self + end + + # + # Returns a new Tms object obtained by memberwise summation + # of the individual times for this Tms object with those of the +other+ + # Tms object. + # This method and #/() are useful for taking statistics. + # + def +(other); memberwise(:+, other) end + + # + # Returns a new Tms object obtained by memberwise subtraction + # of the individual times for the +other+ Tms object from those of this + # Tms object. + # + def -(other); memberwise(:-, other) end + + # + # Returns a new Tms object obtained by memberwise multiplication + # of the individual times for this Tms object by +x+. + # + def *(x); memberwise(:*, x) end + + # + # Returns a new Tms object obtained by memberwise division + # of the individual times for this Tms object by +x+. + # This method and #+() are useful for taking statistics. + # + def /(x); memberwise(:/, x) end + + # + # Returns the contents of this Tms object as + # a formatted string, according to a +format+ string + # like that passed to Kernel.format. In addition, #format + # accepts the following extensions: + # + # %u:: Replaced by the user CPU time, as reported by Tms#utime. + # %y:: Replaced by the system CPU time, as reported by Tms#stime (Mnemonic: y of "s*y*stem") + # %U:: Replaced by the children's user CPU time, as reported by Tms#cutime + # %Y:: Replaced by the children's system CPU time, as reported by Tms#cstime + # %t:: Replaced by the total CPU time, as reported by Tms#total + # %r:: Replaced by the elapsed real time, as reported by Tms#real + # %n:: Replaced by the label string, as reported by Tms#label (Mnemonic: n of "*n*ame") + # + # If +format+ is not given, FORMAT is used as default value, detailing the + # user, system, total and real elapsed time. + # + def format(format = nil, *args) + str = (format || FORMAT).dup + str.gsub!(/(%[-+.\d]*)n/) { "#{$1}s" % label } + str.gsub!(/(%[-+.\d]*)u/) { "#{$1}f" % utime } + str.gsub!(/(%[-+.\d]*)y/) { "#{$1}f" % stime } + str.gsub!(/(%[-+.\d]*)U/) { "#{$1}f" % cutime } + str.gsub!(/(%[-+.\d]*)Y/) { "#{$1}f" % cstime } + str.gsub!(/(%[-+.\d]*)t/) { "#{$1}f" % total } + str.gsub!(/(%[-+.\d]*)r/) { "(#{$1}f)" % real } + format ? str % args : str + end + + # + # Same as #format. + # + def to_s + format + end + + # + # Returns a new 6-element array, consisting of the + # label, user CPU time, system CPU time, children's + # user CPU time, children's system CPU time and elapsed + # real time. + # + def to_a + [@label, @utime, @stime, @cutime, @cstime, @real] + end + + # + # Returns a hash containing the same data as `to_a`. + # + def to_h + { + label: @label, + utime: @utime, + stime: @stime, + cutime: @cutime, + cstime: @cstime, + real: @real + } + end + + protected + + # + # Returns a new Tms object obtained by memberwise operation +op+ + # of the individual times for this Tms object with those of the other + # Tms object (+x+). + # + # +op+ can be a mathematical operation such as +, -, + # *, / + # + def memberwise(op, x) + case x + when Benchmark::Tms + Benchmark::Tms.new(utime.__send__(op, x.utime), + stime.__send__(op, x.stime), + cutime.__send__(op, x.cutime), + cstime.__send__(op, x.cstime), + real.__send__(op, x.real) + ) + else + Benchmark::Tms.new(utime.__send__(op, x), + stime.__send__(op, x), + cutime.__send__(op, x), + cstime.__send__(op, x), + real.__send__(op, x) + ) + end + end + end + + # The default caption string (heading above the output times). + CAPTION = Benchmark::Tms::CAPTION + + # The default format string used to display times. See also Benchmark::Tms#format. + FORMAT = Benchmark::Tms::FORMAT +end diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/LICENSE b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/LICENSE new file mode 100644 index 00000000..a1f19ff9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/LICENSE @@ -0,0 +1,56 @@ +Ruby is copyrighted free software by Yukihiro Matsumoto . +You can redistribute it and/or modify it under either the terms of the +2-clause BSDL (see the file BSDL), or the conditions below: + + 1. You may make and give away verbatim copies of the source form of the + software without restriction, provided that you duplicate all of the + original copyright notices and associated disclaimers. + + 2. You may modify your copy of the software in any way, provided that + you do at least ONE of the following: + + a) place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said + modifications to Usenet or an equivalent medium, or by allowing + the author to include your modifications in the software. + + b) use the modified software only within your corporation or + organization. + + c) give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d) make other distribution arrangements with the author. + + 3. You may distribute the software in object code or binary form, + provided that you do at least ONE of the following: + + a) distribute the binaries and library files of the software, + together with instructions (in the manual page or equivalent) + on where to get the original distribution. + + b) accompany the distribution with the machine-readable source of + the software. + + c) give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d) make other distribution arrangements with the author. + + 4. You may modify and include the part of the software into any other + software (possibly commercial). But some files in the distribution + are not written by the author, so that they are not under these terms. + + For the list of those files and their copying conditions, see the + file LEGAL. + + 5. The scripts and library files supplied as input to or produced as + output from the software do not automatically fall under the + copyright of the software, but belong to whomever generated them, + and may be sold commercially, and may be aggregated with this + software. + + 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/bigdecimal.gemspec b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/bigdecimal.gemspec new file mode 100644 index 00000000..b6ef8fd9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/bigdecimal.gemspec @@ -0,0 +1,57 @@ +# coding: utf-8 + +name = File.basename(__FILE__, '.*') +source_version = ["", "ext/#{name}/"].find do |dir| + begin + break File.foreach(File.join(__dir__, "#{dir}#{name}.c")) {|line| + break $1.sub("-", ".") if /^#define\s+#{name.upcase}_VERSION\s+"(.+)"/o =~ line + } + rescue Errno::ENOENT + end +end or raise "can't find #{name.upcase}_VERSION" + +Gem::Specification.new do |s| + s.name = name + s.version = source_version + s.authors = ["Kenta Murata", "Zachary Scott", "Shigeo Kobayashi"] + s.email = ["mrkn@mrkn.jp"] + + s.summary = "Arbitrary-precision decimal floating-point number library." + s.description = "This library provides arbitrary-precision decimal floating-point number class." + s.homepage = "https://github.com/ruby/bigdecimal" + s.licenses = ["Ruby", "BSD-2-Clause"] + + s.require_paths = %w[lib] + s.files = %w[ + LICENSE + bigdecimal.gemspec + lib/bigdecimal.rb + lib/bigdecimal/jacobian.rb + lib/bigdecimal/ludcmp.rb + lib/bigdecimal/math.rb + lib/bigdecimal/newton.rb + lib/bigdecimal/util.rb + sample/linear.rb + sample/nlsolve.rb + sample/pi.rb + ] + if Gem::Platform === s.platform and s.platform =~ 'java' or RUBY_ENGINE == 'jruby' + s.platform = 'java' + else + s.extensions = %w[ext/bigdecimal/extconf.rb] + s.files += %w[ + ext/bigdecimal/bigdecimal.c + ext/bigdecimal/bigdecimal.h + ext/bigdecimal/bits.h + ext/bigdecimal/feature.h + ext/bigdecimal/missing.c + ext/bigdecimal/missing.h + ext/bigdecimal/missing/dtoa.c + ext/bigdecimal/static_assert.h + ] + end + + s.required_ruby_version = Gem::Requirement.new(">= 2.5.0") + + s.metadata["changelog_uri"] = s.homepage + "/blob/master/CHANGES.md" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/Makefile b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/Makefile new file mode 100644 index 00000000..7e524013 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/Makefile @@ -0,0 +1,274 @@ + +SHELL = /bin/sh + +# V=0 quiet, V=1 verbose. other values don't work. +V = 0 +V0 = $(V:0=) +Q1 = $(V:1=) +Q = $(Q1:0=@) +ECHO1 = $(V:1=@ :) +ECHO = $(ECHO1:0=@ echo) +NULLCMD = : + +#### Start of system configuration section. #### + +srcdir = . +topdir = /opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 +hdrdir = $(topdir) +arch_hdrdir = /opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux +PATH_SEPARATOR = : +VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby +prefix = $(DESTDIR)/opt/hostedtoolcache/Ruby/3.4.4/x64 +rubysitearchprefix = $(rubylibprefix)/$(sitearch) +rubyarchprefix = $(rubylibprefix)/$(arch) +rubylibprefix = $(libdir)/$(RUBY_BASE_NAME) +exec_prefix = $(prefix) +vendorarchhdrdir = $(vendorhdrdir)/$(sitearch) +sitearchhdrdir = $(sitehdrdir)/$(sitearch) +rubyarchhdrdir = $(rubyhdrdir)/$(arch) +vendorhdrdir = $(rubyhdrdir)/vendor_ruby +sitehdrdir = $(rubyhdrdir)/site_ruby +rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME) +vendorarchdir = $(vendorlibdir)/$(sitearch) +vendorlibdir = $(vendordir)/$(ruby_version) +vendordir = $(rubylibprefix)/vendor_ruby +sitearchdir = $(sitelibdir)/$(sitearch) +sitelibdir = $(sitedir)/$(ruby_version) +sitedir = $(rubylibprefix)/site_ruby +rubyarchdir = $(rubylibdir)/$(arch) +rubylibdir = $(rubylibprefix)/$(ruby_version) +sitearchincludedir = $(includedir)/$(sitearch) +archincludedir = $(includedir)/$(arch) +sitearchlibdir = $(libdir)/$(sitearch) +archlibdir = $(libdir)/$(arch) +ridir = $(datarootdir)/$(RI_BASE_NAME) +modular_gc_dir = $(DESTDIR) +mandir = $(datarootdir)/man +localedir = $(datarootdir)/locale +libdir = $(exec_prefix)/lib +psdir = $(docdir) +pdfdir = $(docdir) +dvidir = $(docdir) +htmldir = $(docdir) +infodir = $(datarootdir)/info +docdir = $(datarootdir)/doc/$(PACKAGE) +oldincludedir = $(DESTDIR)/usr/include +includedir = $(prefix)/include +runstatedir = $(localstatedir)/run +localstatedir = $(prefix)/var +sharedstatedir = $(prefix)/com +sysconfdir = $(prefix)/etc +datadir = $(datarootdir) +datarootdir = $(prefix)/share +libexecdir = $(exec_prefix)/libexec +sbindir = $(exec_prefix)/sbin +bindir = $(exec_prefix)/bin +archdir = $(rubyarchdir) + + +CC_WRAPPER = +CC = gcc +CXX = g++ +LIBRUBY = $(LIBRUBY_SO) +LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a +LIBRUBYARG_SHARED = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME) +LIBRUBYARG_STATIC = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)-static $(MAINLIBS) +empty = +OUTFLAG = -o $(empty) +COUTFLAG = -o $(empty) +CSRCFLAG = $(empty) + +RUBY_EXTCONF_H = +cflags = $(hardenflags) $(optflags) $(debugflags) $(warnflags) +cxxflags = +optflags = -O3 -fno-fast-math +debugflags = -ggdb3 +warnflags = -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef +cppflags = +CCDLFLAGS = -fPIC +CFLAGS = $(CCDLFLAGS) $(cflags) -fPIC $(ARCH_FLAG) +INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) +DEFS = +CPPFLAGS = -DHAVE_BUILTIN___BUILTIN_CLZ -DHAVE_BUILTIN___BUILTIN_CLZL -DHAVE_BUILTIN___BUILTIN_CLZLL -DHAVE_FLOAT_H -DHAVE_MATH_H -DHAVE_STDBOOL_H -DHAVE_STDLIB_H -DHAVE_X86INTRIN_H -DHAVE_LABS -DHAVE_LLABS -DHAVE_FINITE -DHAVE_RUBY_ATOMIC_H -DHAVE_RUBY_INTERNAL_HAS_BUILTIN_H -DHAVE_RUBY_INTERNAL_STATIC_ASSERT_H -DHAVE_RB_RATIONAL_NUM -DHAVE_RB_RATIONAL_DEN -DHAVE_RB_COMPLEX_REAL -DHAVE_RB_COMPLEX_IMAG -DHAVE_RB_OPTS_EXCEPTION_P -DHAVE_RB_CATEGORY_WARN -DHAVE_CONST_RB_WARN_CATEGORY_DEPRECATED -DENABLE_PATH_CHECK=0 $(DEFS) $(cppflags) +CXXFLAGS = $(CCDLFLAGS) $(ARCH_FLAG) +ldflags = -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed +dldflags = -Wl,--compress-debug-sections=zlib +ARCH_FLAG = +DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG) +LDSHARED = $(CC) -shared +LDSHAREDXX = $(CXX) -shared +POSTLINK = : +AR = gcc-ar +LD = ld +EXEEXT = + +RUBY_INSTALL_NAME = $(RUBY_BASE_NAME) +RUBY_SO_NAME = ruby +RUBYW_INSTALL_NAME = +RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version) +RUBYW_BASE_NAME = rubyw +RUBY_BASE_NAME = ruby + +arch = x86_64-linux +sitearch = $(arch) +ruby_version = 3.4.0 +ruby = $(bindir)/$(RUBY_BASE_NAME) +RUBY = $(ruby) +BUILTRUBY = $(bindir)/$(RUBY_BASE_NAME) +ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/backward.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h + +RM = rm -f +RM_RF = rm -fr +RMDIRS = rmdir --ignore-fail-on-non-empty -p +MAKEDIRS = /usr/bin/mkdir -p +INSTALL = /usr/bin/install -c +INSTALL_PROG = $(INSTALL) -m 0755 +INSTALL_DATA = $(INSTALL) -m 644 +COPY = cp +TOUCH = exit > + +#### End of system configuration section. #### + +preload = +libpath = . $(libdir) +LIBPATH = -L. -L$(libdir) -Wl,-rpath,$(libdir) +DEFFILE = + +CLEANFILES = mkmf.log +DISTCLEANFILES = +DISTCLEANDIRS = + +extout = +extout_prefix = +target_prefix = +LOCAL_LIBS = +LIBS = $(LIBRUBYARG_SHARED) -lm -lpthread -lc +ORIG_SRCS = bigdecimal.c missing.c +SRCS = $(ORIG_SRCS) +OBJS = bigdecimal.o missing.o +HDRS = $(srcdir)/bigdecimal.h $(srcdir)/bits.h $(srcdir)/feature.h $(srcdir)/missing.h $(srcdir)/static_assert.h +LOCAL_HDRS = +TARGET = bigdecimal +TARGET_NAME = bigdecimal +TARGET_ENTRY = Init_$(TARGET_NAME) +DLLIB = $(TARGET).so +EXTSTATIC = +STATIC_LIB = + +TIMESTAMP_DIR = . +BINDIR = $(bindir) +RUBYCOMMONDIR = $(sitedir)$(target_prefix) +RUBYLIBDIR = $(sitelibdir)$(target_prefix) +RUBYARCHDIR = $(sitearchdir)$(target_prefix) +HDRDIR = $(sitehdrdir)$(target_prefix) +ARCHHDRDIR = $(sitearchhdrdir)$(target_prefix) +TARGET_SO_DIR = +TARGET_SO = $(TARGET_SO_DIR)$(DLLIB) +CLEANLIBS = $(TARGET_SO) false +CLEANOBJS = $(OBJS) *.bak +TARGET_SO_DIR_TIMESTAMP = $(TIMESTAMP_DIR)/.sitearchdir.time +BIGDECIMAL_RB = $(srcdir)/../../lib/bigdecimal.rb + +all: $(DLLIB) +static: $(STATIC_LIB) +.PHONY: all install static install-so install-rb +.PHONY: clean clean-so clean-static clean-rb + +clean-static:: +clean-rb-default:: +clean-rb:: +clean-so:: +clean: clean-so clean-static clean-rb-default clean-rb + -$(Q)$(RM_RF) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time + +distclean-rb-default:: +distclean-rb:: +distclean-so:: +distclean-static:: +distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb + -$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + -$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + -$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true + +realclean: distclean +install: install-so install-rb + +install-so: $(DLLIB) $(TARGET_SO_DIR_TIMESTAMP) + $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) +clean-static:: + -$(Q)$(RM) $(STATIC_LIB) +install-rb: pre-install-rb do-install-rb install-rb-default +install-rb-default: pre-install-rb-default do-install-rb-default +pre-install-rb: Makefile +pre-install-rb-default: Makefile +do-install-rb: +do-install-rb-default: +pre-install-rb-default: + @$(NULLCMD) +$(TARGET_SO_DIR_TIMESTAMP): + $(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR) + $(Q) $(TOUCH) $@ + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + +.SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S + +.cc.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cc.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.mm.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.mm.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cxx.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cxx.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cpp.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cpp.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.c.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.c.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.m.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.m.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +$(TARGET_SO): $(OBJS) Makefile + $(ECHO) linking shared-object $(DLLIB) + -$(Q)$(RM) $(@) + $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) + $(Q) $(POSTLINK) + + + +$(OBJS): $(HDRS) $(ruby_headers) diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/bigdecimal.c b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/bigdecimal.c new file mode 100644 index 00000000..486aee86 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/bigdecimal.c @@ -0,0 +1,7761 @@ +/* + * + * Ruby BigDecimal(Variable decimal precision) extension library. + * + * Copyright(C) 2002 by Shigeo Kobayashi(shigeo@tinyforest.gr.jp) + * + */ + +/* #define BIGDECIMAL_DEBUG 1 */ + +#include "bigdecimal.h" +#include "ruby/util.h" + +#ifndef BIGDECIMAL_DEBUG +# undef NDEBUG +# define NDEBUG +#endif +#include + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_IEEEFP_H +#include +#endif + +#include "bits.h" +#include "static_assert.h" + +#define BIGDECIMAL_VERSION "3.2.2" + +/* #define ENABLE_NUMERIC_STRING */ + +#define SIGNED_VALUE_MAX INTPTR_MAX +#define SIGNED_VALUE_MIN INTPTR_MIN +#define MUL_OVERFLOW_SIGNED_VALUE_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, SIGNED_VALUE_MIN, SIGNED_VALUE_MAX) + +VALUE rb_cBigDecimal; +VALUE rb_mBigMath; + +static ID id_BigDecimal_exception_mode; +static ID id_BigDecimal_rounding_mode; +static ID id_BigDecimal_precision_limit; + +static ID id_up; +static ID id_down; +static ID id_truncate; +static ID id_half_up; +static ID id_default; +static ID id_half_down; +static ID id_half_even; +static ID id_banker; +static ID id_ceiling; +static ID id_ceil; +static ID id_floor; +static ID id_to_r; +static ID id_eq; +static ID id_half; + +#define RBD_NUM_ROUNDING_MODES 11 + +static struct { + ID id; + uint8_t mode; +} rbd_rounding_modes[RBD_NUM_ROUNDING_MODES]; + +/* MACRO's to guard objects from GC by keeping them in stack */ +#ifdef RBIMPL_ATTR_MAYBE_UNUSED +#define ENTER(n) RBIMPL_ATTR_MAYBE_UNUSED() volatile VALUE vStack[n];int iStack=0 +#else +#define ENTER(n) volatile VALUE RB_UNUSED_VAR(vStack[n]);int iStack=0 +#endif +#define PUSH(x) (vStack[iStack++] = (VALUE)(x)) +#define SAVE(p) PUSH((p)->obj) +#define GUARD_OBJ(p,y) ((p)=(y), SAVE(p)) + +#define BASE_FIG BIGDECIMAL_COMPONENT_FIGURES +#define BASE BIGDECIMAL_BASE + +#define HALF_BASE (BASE/2) +#define BASE1 (BASE/10) + +#define LOG10_2 0.3010299956639812 + +#ifndef RRATIONAL_ZERO_P +# define RRATIONAL_ZERO_P(x) (FIXNUM_P(rb_rational_num(x)) && \ + FIX2LONG(rb_rational_num(x)) == 0) +#endif + +#ifndef RRATIONAL_NEGATIVE_P +# define RRATIONAL_NEGATIVE_P(x) RTEST(rb_funcall((x), '<', 1, INT2FIX(0))) +#endif + +#ifndef DECIMAL_SIZE_OF_BITS +#define DECIMAL_SIZE_OF_BITS(n) (((n) * 3010 + 9998) / 9999) +/* an approximation of ceil(n * log10(2)), upto 65536 at least */ +#endif + +#ifdef PRIsVALUE +# define RB_OBJ_CLASSNAME(obj) rb_obj_class(obj) +# define RB_OBJ_STRING(obj) (obj) +#else +# define PRIsVALUE "s" +# define RB_OBJ_CLASSNAME(obj) rb_obj_classname(obj) +# define RB_OBJ_STRING(obj) StringValueCStr(obj) +#endif + +#ifndef MAYBE_UNUSED +# define MAYBE_UNUSED(x) x +#endif + +#define BIGDECIMAL_POSITIVE_P(bd) ((bd)->sign > 0) +#define BIGDECIMAL_NEGATIVE_P(bd) ((bd)->sign < 0) + +/* + * ================== Memory allocation ============================ + */ + +#ifdef BIGDECIMAL_DEBUG +static size_t rbd_allocation_count = 0; /* Memory allocation counter */ +static inline void +atomic_allocation_count_inc(void) +{ + RUBY_ATOMIC_SIZE_INC(rbd_allocation_count); +} +static inline void +atomic_allocation_count_dec_nounderflow(void) +{ + if (rbd_allocation_count == 0) return; + RUBY_ATOMIC_SIZE_DEC(rbd_allocation_count); +} +static void +check_allocation_count_nonzero(void) +{ + if (rbd_allocation_count != 0) return; + rb_bug("[bigdecimal][rbd_free_struct] Too many memory free calls"); +} +#else +# define atomic_allocation_count_inc() /* nothing */ +# define atomic_allocation_count_dec_nounderflow() /* nothing */ +# define check_allocation_count_nonzero() /* nothing */ +#endif /* BIGDECIMAL_DEBUG */ + +PUREFUNC(static inline size_t rbd_struct_size(size_t const)); + +static inline size_t +rbd_struct_size(size_t const internal_digits) +{ + size_t const frac_len = (internal_digits == 0) ? 1 : internal_digits; + return offsetof(Real, frac) + frac_len * sizeof(DECDIG); +} + +static inline Real * +rbd_allocate_struct(size_t const internal_digits) +{ + size_t const size = rbd_struct_size(internal_digits); + Real *real = ruby_xcalloc(1, size); + atomic_allocation_count_inc(); + real->MaxPrec = internal_digits; + return real; +} + +static size_t +rbd_calculate_internal_digits(size_t const digits, bool limit_precision) +{ + size_t const len = roomof(digits, BASE_FIG); + if (limit_precision) { + size_t const prec_limit = VpGetPrecLimit(); + if (prec_limit > 0) { + /* NOTE: 2 more digits for rounding and division */ + size_t const max_len = roomof(prec_limit, BASE_FIG) + 2; + if (len > max_len) + return max_len; + } + } + + return len; +} + +static inline Real * +rbd_allocate_struct_decimal_digits(size_t const decimal_digits, bool limit_precision) +{ + size_t const internal_digits = rbd_calculate_internal_digits(decimal_digits, limit_precision); + return rbd_allocate_struct(internal_digits); +} + +static VALUE BigDecimal_wrap_struct(VALUE obj, Real *vp); + +static Real * +rbd_reallocate_struct(Real *real, size_t const internal_digits) +{ + size_t const size = rbd_struct_size(internal_digits); + VALUE obj = real ? real->obj : 0; + Real *new_real = (Real *)ruby_xrealloc(real, size); + new_real->MaxPrec = internal_digits; + if (obj) { + new_real->obj = 0; + BigDecimal_wrap_struct(obj, new_real); + } + return new_real; +} + +static void +rbd_free_struct(Real *real) +{ + if (real != NULL) { + check_allocation_count_nonzero(); + ruby_xfree(real); + atomic_allocation_count_dec_nounderflow(); + } +} + +#define NewZero rbd_allocate_struct_zero +static Real * +rbd_allocate_struct_zero(int sign, size_t const digits, bool limit_precision) +{ + Real *real = rbd_allocate_struct_decimal_digits(digits, limit_precision); + VpSetZero(real, sign); + return real; +} + +MAYBE_UNUSED(static inline Real * rbd_allocate_struct_zero_limited(int sign, size_t const digits)); +#define NewZeroLimited rbd_allocate_struct_zero_limited +static inline Real * +rbd_allocate_struct_zero_limited(int sign, size_t const digits) +{ + return rbd_allocate_struct_zero(sign, digits, true); +} + +MAYBE_UNUSED(static inline Real * rbd_allocate_struct_zero_nolimit(int sign, size_t const digits)); +#define NewZeroNolimit rbd_allocate_struct_zero_nolimit +static inline Real * +rbd_allocate_struct_zero_nolimit(int sign, size_t const digits) +{ + return rbd_allocate_struct_zero(sign, digits, false); +} + +#define NewOne rbd_allocate_struct_one +static Real * +rbd_allocate_struct_one(int sign, size_t const digits, bool limit_precision) +{ + Real *real = rbd_allocate_struct_decimal_digits(digits, limit_precision); + VpSetOne(real); + if (sign < 0) + VpSetSign(real, VP_SIGN_NEGATIVE_FINITE); + return real; +} + +MAYBE_UNUSED(static inline Real * rbd_allocate_struct_one_limited(int sign, size_t const digits)); +#define NewOneLimited rbd_allocate_struct_one_limited +static inline Real * +rbd_allocate_struct_one_limited(int sign, size_t const digits) +{ + return rbd_allocate_struct_one(sign, digits, true); +} + +MAYBE_UNUSED(static inline Real * rbd_allocate_struct_one_nolimit(int sign, size_t const digits)); +#define NewOneNolimit rbd_allocate_struct_one_nolimit +static inline Real * +rbd_allocate_struct_one_nolimit(int sign, size_t const digits) +{ + return rbd_allocate_struct_one(sign, digits, false); +} + +/* + * ================== Ruby Interface part ========================== + */ +#define DoSomeOne(x,y,f) rb_num_coerce_bin(x,y,f) + +/* + * VP routines used in BigDecimal part + */ +static unsigned short VpGetException(void); +static void VpSetException(unsigned short f); +static void VpCheckException(Real *p, bool always); +static VALUE VpCheckGetValue(Real *p); +static void VpInternalRound(Real *c, size_t ixDigit, DECDIG vPrev, DECDIG v); +static int VpLimitRound(Real *c, size_t ixDigit); +static Real *VpCopy(Real *pv, Real const* const x); +static int VPrint(FILE *fp,const char *cntl_chr,Real *a); + +/* + * **** BigDecimal part **** + */ + +static VALUE BigDecimal_nan(void); +static VALUE BigDecimal_positive_infinity(void); +static VALUE BigDecimal_negative_infinity(void); +static VALUE BigDecimal_positive_zero(void); +static VALUE BigDecimal_negative_zero(void); + +static void +BigDecimal_delete(void *pv) +{ + rbd_free_struct(pv); +} + +static size_t +BigDecimal_memsize(const void *ptr) +{ + const Real *pv = ptr; + return (sizeof(*pv) + pv->MaxPrec * sizeof(DECDIG)); +} + +#ifndef HAVE_RB_EXT_RACTOR_SAFE +# undef RUBY_TYPED_FROZEN_SHAREABLE +# define RUBY_TYPED_FROZEN_SHAREABLE 0 +#endif + +static const rb_data_type_t BigDecimal_data_type = { + "BigDecimal", + { 0, BigDecimal_delete, BigDecimal_memsize, }, +#ifdef RUBY_TYPED_FREE_IMMEDIATELY + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE | RUBY_TYPED_WB_PROTECTED +#endif +}; + +static Real * +rbd_allocate_struct_zero_wrap_klass(VALUE klass, int sign, size_t const digits, bool limit_precision) +{ + Real *real = rbd_allocate_struct_zero(sign, digits, limit_precision); + if (real != NULL) { + VALUE obj = TypedData_Wrap_Struct(klass, &BigDecimal_data_type, 0); + BigDecimal_wrap_struct(obj, real); + } + return real; +} + +MAYBE_UNUSED(static inline Real * rbd_allocate_struct_zero_limited_wrap(int sign, size_t const digits)); +#define NewZeroWrapLimited rbd_allocate_struct_zero_limited_wrap +static inline Real * +rbd_allocate_struct_zero_limited_wrap(int sign, size_t const digits) +{ + return rbd_allocate_struct_zero_wrap_klass(rb_cBigDecimal, sign, digits, true); +} + +MAYBE_UNUSED(static inline Real * rbd_allocate_struct_zero_nolimit_wrap(int sign, size_t const digits)); +#define NewZeroWrapNolimit rbd_allocate_struct_zero_nolimit_wrap +static inline Real * +rbd_allocate_struct_zero_nolimit_wrap(int sign, size_t const digits) +{ + return rbd_allocate_struct_zero_wrap_klass(rb_cBigDecimal, sign, digits, false); +} + +static Real * +rbd_allocate_struct_one_wrap_klass(VALUE klass, int sign, size_t const digits, bool limit_precision) +{ + Real *real = rbd_allocate_struct_one(sign, digits, limit_precision); + if (real != NULL) { + VALUE obj = TypedData_Wrap_Struct(klass, &BigDecimal_data_type, 0); + BigDecimal_wrap_struct(obj, real); + } + return real; +} + +MAYBE_UNUSED(static inline Real * rbd_allocate_struct_one_limited_wrap(int sign, size_t const digits)); +#define NewOneWrapLimited rbd_allocate_struct_one_limited_wrap +static inline Real * +rbd_allocate_struct_one_limited_wrap(int sign, size_t const digits) +{ + return rbd_allocate_struct_one_wrap_klass(rb_cBigDecimal, sign, digits, true); +} + +MAYBE_UNUSED(static inline Real * rbd_allocate_struct_one_nolimit_wrap(int sign, size_t const digits)); +#define NewOneWrapNolimit rbd_allocate_struct_one_nolimit_wrap +static inline Real * +rbd_allocate_struct_one_nolimit_wrap(int sign, size_t const digits) +{ + return rbd_allocate_struct_one_wrap_klass(rb_cBigDecimal, sign, digits, false); +} + +static inline int +is_kind_of_BigDecimal(VALUE const v) +{ + return rb_typeddata_is_kind_of(v, &BigDecimal_data_type); +} + +NORETURN(static void cannot_be_coerced_into_BigDecimal(VALUE, VALUE)); + +static void +cannot_be_coerced_into_BigDecimal(VALUE exc_class, VALUE v) +{ + VALUE str; + + if (rb_special_const_p(v)) { + str = rb_inspect(v); + } + else { + str = rb_class_name(rb_obj_class(v)); + } + + str = rb_str_cat2(rb_str_dup(str), " can't be coerced into BigDecimal"); + rb_exc_raise(rb_exc_new3(exc_class, str)); +} + +static inline VALUE BigDecimal_div2(VALUE, VALUE, VALUE); +static VALUE rb_inum_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception); +static VALUE rb_float_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception); +static VALUE rb_rational_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception); +static VALUE rb_cstr_convert_to_BigDecimal(const char *c_str, size_t digs, int raise_exception); +static VALUE rb_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception); + +static Real* +GetVpValueWithPrec(VALUE v, long prec, int must) +{ + const size_t digs = prec < 0 ? SIZE_MAX : (size_t)prec; + + switch(TYPE(v)) { + case T_FLOAT: + v = rb_float_convert_to_BigDecimal(v, digs, must); + break; + + case T_RATIONAL: + v = rb_rational_convert_to_BigDecimal(v, digs, must); + break; + + case T_DATA: + if (!is_kind_of_BigDecimal(v)) { + goto SomeOneMayDoIt; + } + break; + + case T_FIXNUM: { + char szD[128]; + snprintf(szD, 128, "%ld", FIX2LONG(v)); + v = rb_cstr_convert_to_BigDecimal(szD, VpBaseFig() * 2 + 1, must); + break; + } + +#ifdef ENABLE_NUMERIC_STRING + case T_STRING: { + const char *c_str = StringValueCStr(v); + v = rb_cstr_convert_to_BigDecimal(c_str, RSTRING_LEN(v) + VpBaseFig() + 1, must); + break; + } +#endif /* ENABLE_NUMERIC_STRING */ + + case T_BIGNUM: { + VALUE bg = rb_big2str(v, 10); + v = rb_cstr_convert_to_BigDecimal(RSTRING_PTR(bg), RSTRING_LEN(bg) + VpBaseFig() + 1, must); + RB_GC_GUARD(bg); + break; + } + + default: + goto SomeOneMayDoIt; + } + + Real *vp; + TypedData_Get_Struct(v, Real, &BigDecimal_data_type, vp); + return vp; + +SomeOneMayDoIt: + if (must) { + cannot_be_coerced_into_BigDecimal(rb_eTypeError, v); + } + return NULL; /* NULL means to coerce */ +} + +static inline Real* +GetVpValue(VALUE v, int must) +{ + return GetVpValueWithPrec(v, -1, must); +} + +/* call-seq: + * BigDecimal.double_fig -> integer + * + * Returns the number of digits a Float object is allowed to have; + * the result is system-dependent: + * + * BigDecimal.double_fig # => 16 + * + */ +static inline VALUE +BigDecimal_double_fig(VALUE self) +{ + return INT2FIX(VpDblFig()); +} + +/* call-seq: + * precs -> array + * + * Returns an Array of two Integer values that represent platform-dependent + * internal storage properties. + * + * This method is deprecated and will be removed in the future. + * Instead, use BigDecimal#n_significant_digits for obtaining the number of + * significant digits in scientific notation, and BigDecimal#precision for + * obtaining the number of digits in decimal notation. + * + */ + +static VALUE +BigDecimal_prec(VALUE self) +{ + ENTER(1); + Real *p; + VALUE obj; + + rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, + "BigDecimal#precs is deprecated and will be removed in the future; " + "use BigDecimal#precision instead."); + + GUARD_OBJ(p, GetVpValue(self, 1)); + obj = rb_assoc_new(SIZET2NUM(p->Prec*VpBaseFig()), + SIZET2NUM(p->MaxPrec*VpBaseFig())); + return obj; +} + +static void +VpCountPrecisionAndScale(Real *p, ssize_t *out_precision, ssize_t *out_scale) +{ + if (out_precision == NULL && out_scale == NULL) + return; + if (VpIsZero(p) || !VpIsDef(p)) { + zero: + if (out_precision) *out_precision = 0; + if (out_scale) *out_scale = 0; + return; + } + + DECDIG x; + + ssize_t n = p->Prec; /* The length of frac without zeros. */ + while (n > 0 && p->frac[n-1] == 0) --n; + if (n == 0) goto zero; + + int nlz = BASE_FIG; + for (x = p->frac[0]; x > 0; x /= 10) --nlz; + + int ntz = 0; + for (x = p->frac[n-1]; x > 0 && x % 10 == 0; x /= 10) ++ntz; + + /* + * Calculate the precision and the scale + * ------------------------------------- + * + * The most significant digit is frac[0], and the least significant digit + * is frac[Prec-1]. When the exponent is zero, the decimal point is + * located just before frac[0]. + * + * When the exponent is negative, the decimal point moves to leftward. + * In this case, the precision can be calculated by + * + * precision = BASE_FIG * (-exponent + n) - ntz, + * + * and the scale is the same as precision. + * + * 0 . 0000 0000 | frac[0] ... frac[n-1] | + * |<----------| exponent == -2 | + * |---------------------------------->| precision + * |---------------------------------->| scale + * + * + * Conversely, when the exponent is positive, the decimal point moves to + * rightward. In this case, the scale equals to + * + * BASE_FIG * (n - exponent) - ntz. + * + * the precision equals to + * + * scale + BASE_FIG * exponent - nlz. + * + * | frac[0] frac[1] . frac[2] ... frac[n-1] | + * |---------------->| exponent == 2 | + * | |---------------------->| scale + * |---------------------------------------->| precision + */ + + ssize_t ex = p->exponent; + + /* Count the number of decimal digits before frac[1]. */ + ssize_t n_digits_head = BASE_FIG; + if (ex < 0) { + n_digits_head += (-ex) * BASE_FIG; /* The number of leading zeros before frac[0]. */ + ex = 0; + } + else if (ex > 0) { + /* Count the number of decimal digits without the leading zeros in + * the most significant digit in the integral part. + */ + n_digits_head -= nlz; /* Make the number of digits */ + } + + if (out_precision) { + ssize_t precision = n_digits_head; + + /* Count the number of decimal digits after frac[0]. */ + if (ex > (ssize_t)n) { + /* In this case the number is an integer with some trailing zeros. */ + precision += (ex - 1) * BASE_FIG; + } + else if (n > 0) { + precision += (n - 1) * BASE_FIG; + + if (ex < (ssize_t)n) { + precision -= ntz; + } + } + + *out_precision = precision; + } + + if (out_scale) { + ssize_t scale = 0; + + if (p->exponent < 0) { + scale = n_digits_head + (n - 1) * BASE_FIG - ntz; + } + else if (n > p->exponent) { + scale = (n - p->exponent) * BASE_FIG - ntz; + } + + *out_scale = scale; + } +} + +static void +BigDecimal_count_precision_and_scale(VALUE self, ssize_t *out_precision, ssize_t *out_scale) +{ + ENTER(1); + Real *p; + GUARD_OBJ(p, GetVpValue(self, 1)); + VpCountPrecisionAndScale(p, out_precision, out_scale); +} + +/* + * call-seq: + * precision -> integer + * + * Returns the number of decimal digits in +self+: + * + * BigDecimal("0").precision # => 0 + * BigDecimal("1").precision # => 1 + * BigDecimal("1.1").precision # => 2 + * BigDecimal("3.1415").precision # => 5 + * BigDecimal("-1e20").precision # => 21 + * BigDecimal("1e-20").precision # => 20 + * BigDecimal("Infinity").precision # => 0 + * BigDecimal("-Infinity").precision # => 0 + * BigDecimal("NaN").precision # => 0 + * + */ +static VALUE +BigDecimal_precision(VALUE self) +{ + ssize_t precision; + BigDecimal_count_precision_and_scale(self, &precision, NULL); + return SSIZET2NUM(precision); +} + +/* + * call-seq: + * scale -> integer + * + * Returns the number of decimal digits following the decimal digits in +self+. + * + * BigDecimal("0").scale # => 0 + * BigDecimal("1").scale # => 0 + * BigDecimal("1.1").scale # => 1 + * BigDecimal("3.1415").scale # => 4 + * BigDecimal("-1e20").precision # => 0 + * BigDecimal("1e-20").precision # => 20 + * BigDecimal("Infinity").scale # => 0 + * BigDecimal("-Infinity").scale # => 0 + * BigDecimal("NaN").scale # => 0 + */ +static VALUE +BigDecimal_scale(VALUE self) +{ + ssize_t scale; + BigDecimal_count_precision_and_scale(self, NULL, &scale); + return SSIZET2NUM(scale); +} + +/* + * call-seq: + * precision_scale -> [integer, integer] + * + * Returns a 2-length array; the first item is the result of + * BigDecimal#precision and the second one is of BigDecimal#scale. + * + * See BigDecimal#precision. + * See BigDecimal#scale. + */ +static VALUE +BigDecimal_precision_scale(VALUE self) +{ + ssize_t precision, scale; + BigDecimal_count_precision_and_scale(self, &precision, &scale); + return rb_assoc_new(SSIZET2NUM(precision), SSIZET2NUM(scale)); +} + +/* + * call-seq: + * n_significant_digits -> integer + * + * Returns the number of decimal significant digits in +self+. + * + * BigDecimal("0").n_significant_digits # => 0 + * BigDecimal("1").n_significant_digits # => 1 + * BigDecimal("1.1").n_significant_digits # => 2 + * BigDecimal("3.1415").n_significant_digits # => 5 + * BigDecimal("-1e20").n_significant_digits # => 1 + * BigDecimal("1e-20").n_significant_digits # => 1 + * BigDecimal("Infinity").n_significant_digits # => 0 + * BigDecimal("-Infinity").n_significant_digits # => 0 + * BigDecimal("NaN").n_significant_digits # => 0 + */ +static VALUE +BigDecimal_n_significant_digits(VALUE self) +{ + ENTER(1); + + Real *p; + GUARD_OBJ(p, GetVpValue(self, 1)); + if (VpIsZero(p) || !VpIsDef(p)) { + return INT2FIX(0); + } + + ssize_t n = p->Prec; /* The length of frac without trailing zeros. */ + for (n = p->Prec; n > 0 && p->frac[n-1] == 0; --n); + if (n == 0) return INT2FIX(0); + + DECDIG x; + int nlz = BASE_FIG; + for (x = p->frac[0]; x > 0; x /= 10) --nlz; + + int ntz = 0; + for (x = p->frac[n-1]; x > 0 && x % 10 == 0; x /= 10) ++ntz; + + ssize_t n_significant_digits = BASE_FIG*n - nlz - ntz; + return SSIZET2NUM(n_significant_digits); +} + +/* + * call-seq: + * hash -> integer + * + * Returns the integer hash value for +self+. + * + * Two instances of \BigDecimal have the same hash value if and only if + * they have equal: + * + * - Sign. + * - Fractional part. + * - Exponent. + * + */ +static VALUE +BigDecimal_hash(VALUE self) +{ + ENTER(1); + Real *p; + st_index_t hash; + + GUARD_OBJ(p, GetVpValue(self, 1)); + hash = (st_index_t)p->sign; + /* hash!=2: the case for 0(1),NaN(0) or +-Infinity(3) is sign itself */ + if(hash == 2 || hash == (st_index_t)-2) { + hash ^= rb_memhash(p->frac, sizeof(DECDIG)*p->Prec); + hash += p->exponent; + } + return ST2FIX(hash); +} + +/* + * call-seq: + * _dump -> string + * + * Returns a string representing the marshalling of +self+. + * See module Marshal. + * + * inf = BigDecimal('Infinity') # => Infinity + * dumped = inf._dump # => "9:Infinity" + * BigDecimal._load(dumped) # => Infinity + * + */ +static VALUE +BigDecimal_dump(int argc, VALUE *argv, VALUE self) +{ + ENTER(5); + Real *vp; + char *psz; + VALUE dummy; + volatile VALUE dump; + size_t len; + + rb_scan_args(argc, argv, "01", &dummy); + GUARD_OBJ(vp,GetVpValue(self, 1)); + dump = rb_str_new(0, VpNumOfChars(vp, "E")+50); + psz = RSTRING_PTR(dump); + snprintf(psz, RSTRING_LEN(dump), "%"PRIuSIZE":", VpMaxPrec(vp)*VpBaseFig()); + len = strlen(psz); + VpToString(vp, psz+len, RSTRING_LEN(dump)-len, 0, 0); + rb_str_resize(dump, strlen(psz)); + return dump; +} + +/* + * Internal method used to provide marshalling support. See the Marshal module. + */ +static VALUE +BigDecimal_load(VALUE self, VALUE str) +{ + ENTER(2); + Real *pv; + unsigned char *pch; + unsigned char ch; + unsigned long m=0; + + pch = (unsigned char *)StringValueCStr(str); + /* First get max prec */ + while((*pch) != (unsigned char)'\0' && (ch = *pch++) != (unsigned char)':') { + if(!ISDIGIT(ch)) { + rb_raise(rb_eTypeError, "load failed: invalid character in the marshaled string"); + } + m = m*10 + (unsigned long)(ch-'0'); + } + if (m > VpBaseFig()) m -= VpBaseFig(); + GUARD_OBJ(pv, VpNewRbClass(m, (char *)pch, self, true, true)); + m /= VpBaseFig(); + if (m && pv->MaxPrec > m) { + pv->MaxPrec = m+1; + } + return VpCheckGetValue(pv); +} + +static unsigned short +check_rounding_mode_option(VALUE const opts) +{ + VALUE mode; + char const *s; + long l; + + assert(RB_TYPE_P(opts, T_HASH)); + + if (NIL_P(opts)) + goto no_opt; + + mode = rb_hash_lookup2(opts, ID2SYM(id_half), Qundef); + if (mode == Qundef || NIL_P(mode)) + goto no_opt; + + if (SYMBOL_P(mode)) + mode = rb_sym2str(mode); + else if (!RB_TYPE_P(mode, T_STRING)) { + VALUE str_mode = rb_check_string_type(mode); + if (NIL_P(str_mode)) + goto invalid; + mode = str_mode; + } + s = RSTRING_PTR(mode); + l = RSTRING_LEN(mode); + switch (l) { + case 2: + if (strncasecmp(s, "up", 2) == 0) + return VP_ROUND_HALF_UP; + break; + case 4: + if (strncasecmp(s, "even", 4) == 0) + return VP_ROUND_HALF_EVEN; + else if (strncasecmp(s, "down", 4) == 0) + return VP_ROUND_HALF_DOWN; + break; + default: + break; + } + + invalid: + rb_raise(rb_eArgError, "invalid rounding mode (%"PRIsVALUE")", mode); + + no_opt: + return VpGetRoundMode(); +} + +static unsigned short +check_rounding_mode(VALUE const v) +{ + unsigned short sw; + ID id; + if (RB_TYPE_P(v, T_SYMBOL)) { + int i; + id = SYM2ID(v); + for (i = 0; i < RBD_NUM_ROUNDING_MODES; ++i) { + if (rbd_rounding_modes[i].id == id) { + return rbd_rounding_modes[i].mode; + } + } + rb_raise(rb_eArgError, "invalid rounding mode (%"PRIsVALUE")", v); + } + else { + sw = NUM2USHORT(v); + if (!VpIsRoundMode(sw)) { + rb_raise(rb_eArgError, "invalid rounding mode (%"PRIsVALUE")", v); + } + return sw; + } +} + +/* call-seq: + * BigDecimal.mode(mode, setting = nil) -> integer + * + * Returns an integer representing the mode settings + * for exception handling and rounding. + * + * These modes control exception handling: + * + * - \BigDecimal::EXCEPTION_NaN. + * - \BigDecimal::EXCEPTION_INFINITY. + * - \BigDecimal::EXCEPTION_UNDERFLOW. + * - \BigDecimal::EXCEPTION_OVERFLOW. + * - \BigDecimal::EXCEPTION_ZERODIVIDE. + * - \BigDecimal::EXCEPTION_ALL. + * + * Values for +setting+ for exception handling: + * + * - +true+: sets the given +mode+ to +true+. + * - +false+: sets the given +mode+ to +false+. + * - +nil+: does not modify the mode settings. + * + * You can use method BigDecimal.save_exception_mode + * to temporarily change, and then automatically restore, exception modes. + * + * For clarity, some examples below begin by setting all + * exception modes to +false+. + * + * This mode controls the way rounding is to be performed: + * + * - \BigDecimal::ROUND_MODE + * + * You can use method BigDecimal.save_rounding_mode + * to temporarily change, and then automatically restore, the rounding mode. + * + * NaNs + * + * Mode \BigDecimal::EXCEPTION_NaN controls behavior + * when a \BigDecimal NaN is created. + * + * Settings: + * + * - +false+ (default): Returns BigDecimal('NaN'). + * - +true+: Raises FloatDomainError. + * + * Examples: + * + * BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0 + * BigDecimal('NaN') # => NaN + * BigDecimal.mode(BigDecimal::EXCEPTION_NaN, true) # => 2 + * BigDecimal('NaN') # Raises FloatDomainError + * + * Infinities + * + * Mode \BigDecimal::EXCEPTION_INFINITY controls behavior + * when a \BigDecimal Infinity or -Infinity is created. + * Settings: + * + * - +false+ (default): Returns BigDecimal('Infinity') + * or BigDecimal('-Infinity'). + * - +true+: Raises FloatDomainError. + * + * Examples: + * + * BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0 + * BigDecimal('Infinity') # => Infinity + * BigDecimal('-Infinity') # => -Infinity + * BigDecimal.mode(BigDecimal::EXCEPTION_INFINITY, true) # => 1 + * BigDecimal('Infinity') # Raises FloatDomainError + * BigDecimal('-Infinity') # Raises FloatDomainError + * + * Underflow + * + * Mode \BigDecimal::EXCEPTION_UNDERFLOW controls behavior + * when a \BigDecimal underflow occurs. + * Settings: + * + * - +false+ (default): Returns BigDecimal('0') + * or BigDecimal('-Infinity'). + * - +true+: Raises FloatDomainError. + * + * Examples: + * + * BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0 + * def flow_under + * x = BigDecimal('0.1') + * 100.times { x *= x } + * end + * flow_under # => 100 + * BigDecimal.mode(BigDecimal::EXCEPTION_UNDERFLOW, true) # => 4 + * flow_under # Raises FloatDomainError + * + * Overflow + * + * Mode \BigDecimal::EXCEPTION_OVERFLOW controls behavior + * when a \BigDecimal overflow occurs. + * Settings: + * + * - +false+ (default): Returns BigDecimal('Infinity') + * or BigDecimal('-Infinity'). + * - +true+: Raises FloatDomainError. + * + * Examples: + * + * BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0 + * def flow_over + * x = BigDecimal('10') + * 100.times { x *= x } + * end + * flow_over # => 100 + * BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, true) # => 1 + * flow_over # Raises FloatDomainError + * + * Zero Division + * + * Mode \BigDecimal::EXCEPTION_ZERODIVIDE controls behavior + * when a zero-division occurs. + * Settings: + * + * - +false+ (default): Returns BigDecimal('Infinity') + * or BigDecimal('-Infinity'). + * - +true+: Raises FloatDomainError. + * + * Examples: + * + * BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0 + * one = BigDecimal('1') + * zero = BigDecimal('0') + * one / zero # => Infinity + * BigDecimal.mode(BigDecimal::EXCEPTION_ZERODIVIDE, true) # => 16 + * one / zero # Raises FloatDomainError + * + * All Exceptions + * + * Mode \BigDecimal::EXCEPTION_ALL controls all of the above: + * + * BigDecimal.mode(BigDecimal::EXCEPTION_ALL, false) # => 0 + * BigDecimal.mode(BigDecimal::EXCEPTION_ALL, true) # => 23 + * + * Rounding + * + * Mode \BigDecimal::ROUND_MODE controls the way rounding is to be performed; + * its +setting+ values are: + * + * - +ROUND_UP+: Round away from zero. + * Aliased as +:up+. + * - +ROUND_DOWN+: Round toward zero. + * Aliased as +:down+ and +:truncate+. + * - +ROUND_HALF_UP+: Round toward the nearest neighbor; + * if the neighbors are equidistant, round away from zero. + * Aliased as +:half_up+ and +:default+. + * - +ROUND_HALF_DOWN+: Round toward the nearest neighbor; + * if the neighbors are equidistant, round toward zero. + * Aliased as +:half_down+. + * - +ROUND_HALF_EVEN+ (Banker's rounding): Round toward the nearest neighbor; + * if the neighbors are equidistant, round toward the even neighbor. + * Aliased as +:half_even+ and +:banker+. + * - +ROUND_CEILING+: Round toward positive infinity. + * Aliased as +:ceiling+ and +:ceil+. + * - +ROUND_FLOOR+: Round toward negative infinity. + * Aliased as +:floor:+. + * + */ +static VALUE +BigDecimal_mode(int argc, VALUE *argv, VALUE self) +{ + VALUE which; + VALUE val; + unsigned long f,fo; + + rb_scan_args(argc, argv, "11", &which, &val); + f = (unsigned long)NUM2INT(which); + + if (f & VP_EXCEPTION_ALL) { + /* Exception mode setting */ + fo = VpGetException(); + if (val == Qnil) return INT2FIX(fo); + if (val != Qfalse && val!=Qtrue) { + rb_raise(rb_eArgError, "second argument must be true or false"); + return Qnil; /* Not reached */ + } + if (f & VP_EXCEPTION_INFINITY) { + VpSetException((unsigned short)((val == Qtrue) ? (fo | VP_EXCEPTION_INFINITY) : + (fo & (~VP_EXCEPTION_INFINITY)))); + } + fo = VpGetException(); + if (f & VP_EXCEPTION_NaN) { + VpSetException((unsigned short)((val == Qtrue) ? (fo | VP_EXCEPTION_NaN) : + (fo & (~VP_EXCEPTION_NaN)))); + } + fo = VpGetException(); + if (f & VP_EXCEPTION_UNDERFLOW) { + VpSetException((unsigned short)((val == Qtrue) ? (fo | VP_EXCEPTION_UNDERFLOW) : + (fo & (~VP_EXCEPTION_UNDERFLOW)))); + } + fo = VpGetException(); + if(f & VP_EXCEPTION_ZERODIVIDE) { + VpSetException((unsigned short)((val == Qtrue) ? (fo | VP_EXCEPTION_ZERODIVIDE) : + (fo & (~VP_EXCEPTION_ZERODIVIDE)))); + } + fo = VpGetException(); + return INT2FIX(fo); + } + if (VP_ROUND_MODE == f) { + /* Rounding mode setting */ + unsigned short sw; + fo = VpGetRoundMode(); + if (NIL_P(val)) return INT2FIX(fo); + sw = check_rounding_mode(val); + fo = VpSetRoundMode(sw); + return INT2FIX(fo); + } + rb_raise(rb_eTypeError, "first argument for BigDecimal.mode invalid"); + return Qnil; +} + +static size_t +GetAddSubPrec(Real *a, Real *b) +{ + size_t mxs; + size_t mx = a->Prec; + SIGNED_VALUE d; + + if (!VpIsDef(a) || !VpIsDef(b)) return (size_t)-1L; + if (mx < b->Prec) mx = b->Prec; + if (a->exponent != b->exponent) { + mxs = mx; + d = a->exponent - b->exponent; + if (d < 0) d = -d; + mx = mx + (size_t)d; + if (mx < mxs) { + return VpException(VP_EXCEPTION_INFINITY, "Exponent overflow", 0); + } + } + return mx; +} + +static inline SIGNED_VALUE +check_int_precision(VALUE v) +{ + SIGNED_VALUE n; +#if SIZEOF_VALUE <= SIZEOF_LONG + n = (SIGNED_VALUE)NUM2LONG(v); +#elif SIZEOF_VALUE <= SIZEOF_LONG_LONG + n = (SIGNED_VALUE)NUM2LL(v); +#else +# error SIZEOF_VALUE is too large +#endif + if (n < 0) { + rb_raise(rb_eArgError, "negative precision"); + } + return n; +} + +static VALUE +BigDecimal_wrap_struct(VALUE obj, Real *vp) +{ + assert(is_kind_of_BigDecimal(obj)); + assert(vp != NULL); + + if (vp->obj == obj && RTYPEDDATA_DATA(obj) == vp) + return obj; + + assert(RTYPEDDATA_DATA(obj) == NULL); + assert(vp->obj == 0); + + RTYPEDDATA_DATA(obj) = vp; + vp->obj = obj; + RB_OBJ_FREEZE(obj); + return obj; +} + +VP_EXPORT Real * +VpNewRbClass(size_t mx, const char *str, VALUE klass, bool strict_p, bool raise_exception) +{ + VALUE obj = TypedData_Wrap_Struct(klass, &BigDecimal_data_type, 0); + Real *pv = VpAlloc(mx, str, strict_p, raise_exception); + if (!pv) + return NULL; + BigDecimal_wrap_struct(obj, pv); + return pv; +} + +VP_EXPORT Real * +VpCreateRbObject(size_t mx, const char *str, bool raise_exception) +{ + return VpNewRbClass(mx, str, rb_cBigDecimal, true, raise_exception); +} + +static Real * +VpCopy(Real *pv, Real const* const x) +{ + assert(x != NULL); + + pv = rbd_reallocate_struct(pv, x->MaxPrec); + pv->MaxPrec = x->MaxPrec; + pv->Prec = x->Prec; + pv->exponent = x->exponent; + pv->sign = x->sign; + pv->flag = x->flag; + MEMCPY(pv->frac, x->frac, DECDIG, pv->MaxPrec); + + return pv; +} + +/* Returns True if the value is Not a Number. */ +static VALUE +BigDecimal_IsNaN(VALUE self) +{ + Real *p = GetVpValue(self, 1); + if (VpIsNaN(p)) return Qtrue; + return Qfalse; +} + +/* Returns nil, -1, or +1 depending on whether the value is finite, + * -Infinity, or +Infinity. + */ +static VALUE +BigDecimal_IsInfinite(VALUE self) +{ + Real *p = GetVpValue(self, 1); + if (VpIsPosInf(p)) return INT2FIX(1); + if (VpIsNegInf(p)) return INT2FIX(-1); + return Qnil; +} + +/* Returns True if the value is finite (not NaN or infinite). */ +static VALUE +BigDecimal_IsFinite(VALUE self) +{ + Real *p = GetVpValue(self, 1); + if (VpIsNaN(p)) return Qfalse; + if (VpIsInf(p)) return Qfalse; + return Qtrue; +} + +static void +BigDecimal_check_num(Real *p) +{ + VpCheckException(p, true); +} + +static VALUE BigDecimal_split(VALUE self); + +/* Returns the value as an Integer. + * + * If the BigDecimal is infinity or NaN, raises FloatDomainError. + */ +static VALUE +BigDecimal_to_i(VALUE self) +{ + ENTER(5); + ssize_t e, nf; + Real *p; + + GUARD_OBJ(p, GetVpValue(self, 1)); + BigDecimal_check_num(p); + + e = VpExponent10(p); + if (e <= 0) return INT2FIX(0); + nf = VpBaseFig(); + if (e <= nf) { + return LONG2NUM((long)(VpGetSign(p) * (DECDIG_DBL_SIGNED)p->frac[0])); + } + else { + VALUE a = BigDecimal_split(self); + VALUE digits = RARRAY_AREF(a, 1); + VALUE numerator = rb_funcall(digits, rb_intern("to_i"), 0); + VALUE ret; + ssize_t dpower = e - (ssize_t)RSTRING_LEN(digits); + + if (BIGDECIMAL_NEGATIVE_P(p)) { + numerator = rb_funcall(numerator, '*', 1, INT2FIX(-1)); + } + if (dpower < 0) { + ret = rb_funcall(numerator, rb_intern("div"), 1, + rb_funcall(INT2FIX(10), rb_intern("**"), 1, + INT2FIX(-dpower))); + } + else { + ret = rb_funcall(numerator, '*', 1, + rb_funcall(INT2FIX(10), rb_intern("**"), 1, + INT2FIX(dpower))); + } + if (RB_TYPE_P(ret, T_FLOAT)) { + rb_raise(rb_eFloatDomainError, "Infinity"); + } + return ret; + } +} + +/* Returns a new Float object having approximately the same value as the + * BigDecimal number. Normal accuracy limits and built-in errors of binary + * Float arithmetic apply. + */ +static VALUE +BigDecimal_to_f(VALUE self) +{ + ENTER(1); + Real *p; + double d; + SIGNED_VALUE e; + char *buf; + volatile VALUE str; + + GUARD_OBJ(p, GetVpValue(self, 1)); + if (VpVtoD(&d, &e, p) != 1) + return rb_float_new(d); + if (e > (SIGNED_VALUE)(DBL_MAX_10_EXP+BASE_FIG)) + goto overflow; + if (e < (SIGNED_VALUE)(DBL_MIN_10_EXP-BASE_FIG)) + goto underflow; + + str = rb_str_new(0, VpNumOfChars(p, "E")); + buf = RSTRING_PTR(str); + VpToString(p, buf, RSTRING_LEN(str), 0, 0); + errno = 0; + d = strtod(buf, 0); + if (errno == ERANGE) { + if (d == 0.0) goto underflow; + if (fabs(d) >= HUGE_VAL) goto overflow; + } + return rb_float_new(d); + +overflow: + VpException(VP_EXCEPTION_OVERFLOW, "BigDecimal to Float conversion", 0); + if (BIGDECIMAL_NEGATIVE_P(p)) + return rb_float_new(VpGetDoubleNegInf()); + else + return rb_float_new(VpGetDoublePosInf()); + +underflow: + VpException(VP_EXCEPTION_UNDERFLOW, "BigDecimal to Float conversion", 0); + if (BIGDECIMAL_NEGATIVE_P(p)) + return rb_float_new(-0.0); + else + return rb_float_new(0.0); +} + + +/* Converts a BigDecimal to a Rational. + */ +static VALUE +BigDecimal_to_r(VALUE self) +{ + Real *p; + ssize_t sign, power, denomi_power; + VALUE a, digits, numerator; + + p = GetVpValue(self, 1); + BigDecimal_check_num(p); + + sign = VpGetSign(p); + power = VpExponent10(p); + a = BigDecimal_split(self); + digits = RARRAY_AREF(a, 1); + denomi_power = power - RSTRING_LEN(digits); + numerator = rb_funcall(digits, rb_intern("to_i"), 0); + + if (sign < 0) { + numerator = rb_funcall(numerator, '*', 1, INT2FIX(-1)); + } + if (denomi_power < 0) { + return rb_Rational(numerator, + rb_funcall(INT2FIX(10), rb_intern("**"), 1, + INT2FIX(-denomi_power))); + } + else { + return rb_Rational1(rb_funcall(numerator, '*', 1, + rb_funcall(INT2FIX(10), rb_intern("**"), 1, + INT2FIX(denomi_power)))); + } +} + +/* The coerce method provides support for Ruby type coercion. It is not + * enabled by default. + * + * This means that binary operations like + * / or - can often be performed + * on a BigDecimal and an object of another type, if the other object can + * be coerced into a BigDecimal value. + * + * e.g. + * a = BigDecimal("1.0") + * b = a / 2.0 #=> 0.5 + * + * Note that coercing a String to a BigDecimal is not supported by default; + * it requires a special compile-time option when building Ruby. + */ +static VALUE +BigDecimal_coerce(VALUE self, VALUE other) +{ + ENTER(2); + VALUE obj; + Real *b; + + if (RB_TYPE_P(other, T_FLOAT)) { + GUARD_OBJ(b, GetVpValueWithPrec(other, 0, 1)); + obj = rb_assoc_new(VpCheckGetValue(b), self); + } + else { + if (RB_TYPE_P(other, T_RATIONAL)) { + Real* pv = DATA_PTR(self); + GUARD_OBJ(b, GetVpValueWithPrec(other, pv->Prec*VpBaseFig(), 1)); + } + else { + GUARD_OBJ(b, GetVpValue(other, 1)); + } + obj = rb_assoc_new(b->obj, self); + } + + return obj; +} + +/* + * call-seq: + * +big_decimal -> self + * + * Returns +self+: + * + * +BigDecimal(5) # => 0.5e1 + * +BigDecimal(-5) # => -0.5e1 + * + */ + +static VALUE +BigDecimal_uplus(VALUE self) +{ + return self; +} + + /* + * call-seq: + * self + value -> bigdecimal + * + * Returns the \BigDecimal sum of +self+ and +value+: + * + * b = BigDecimal('111111.111') # => 0.111111111e6 + * b + 2 # => 0.111113111e6 + * b + 2.0 # => 0.111113111e6 + * b + Rational(2, 1) # => 0.111113111e6 + * b + Complex(2, 0) # => (0.111113111e6+0i) + * + * See the {Note About Precision}[BigDecimal.html#class-BigDecimal-label-A+Note+About+Precision]. + * + */ + +static VALUE +BigDecimal_add(VALUE self, VALUE r) +{ + ENTER(5); + Real *c, *a, *b; + size_t mx; + + GUARD_OBJ(a, GetVpValue(self, 1)); + if (RB_TYPE_P(r, T_FLOAT)) { + b = GetVpValueWithPrec(r, 0, 1); + } + else if (RB_TYPE_P(r, T_RATIONAL)) { + b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1); + } + else { + b = GetVpValue(r, 0); + } + + if (!b) return DoSomeOne(self,r,'+'); + SAVE(b); + + if (VpIsNaN(b)) return b->obj; + if (VpIsNaN(a)) return a->obj; + + mx = GetAddSubPrec(a, b); + if (mx == (size_t)-1L) { + GUARD_OBJ(c, NewZeroWrapLimited(1, VpBaseFig() + 1)); + VpAddSub(c, a, b, 1); + } + else { + GUARD_OBJ(c, NewZeroWrapLimited(1, mx * (VpBaseFig() + 1))); + if (!mx) { + VpSetInf(c, VpGetSign(a)); + } + else { + VpAddSub(c, a, b, 1); + } + } + return VpCheckGetValue(c); +} + + /* + * call-seq: + * self - value -> bigdecimal + * + * Returns the \BigDecimal difference of +self+ and +value+: + * + * b = BigDecimal('333333.333') # => 0.333333333e6 + * b - 2 # => 0.333331333e6 + * b - 2.0 # => 0.333331333e6 + * b - Rational(2, 1) # => 0.333331333e6 + * b - Complex(2, 0) # => (0.333331333e6+0i) + * + * See the {Note About Precision}[BigDecimal.html#class-BigDecimal-label-A+Note+About+Precision]. + * + */ +static VALUE +BigDecimal_sub(VALUE self, VALUE r) +{ + ENTER(5); + Real *c, *a, *b; + size_t mx; + + GUARD_OBJ(a, GetVpValue(self,1)); + if (RB_TYPE_P(r, T_FLOAT)) { + b = GetVpValueWithPrec(r, 0, 1); + } + else if (RB_TYPE_P(r, T_RATIONAL)) { + b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1); + } + else { + b = GetVpValue(r,0); + } + + if (!b) return DoSomeOne(self,r,'-'); + SAVE(b); + + if (VpIsNaN(b)) return b->obj; + if (VpIsNaN(a)) return a->obj; + + mx = GetAddSubPrec(a,b); + if (mx == (size_t)-1L) { + GUARD_OBJ(c, NewZeroWrapLimited(1, VpBaseFig() + 1)); + VpAddSub(c, a, b, -1); + } + else { + GUARD_OBJ(c, NewZeroWrapLimited(1, mx *(VpBaseFig() + 1))); + if (!mx) { + VpSetInf(c,VpGetSign(a)); + } + else { + VpAddSub(c, a, b, -1); + } + } + return VpCheckGetValue(c); +} + +static VALUE +BigDecimalCmp(VALUE self, VALUE r,char op) +{ + ENTER(5); + SIGNED_VALUE e; + Real *a, *b=0; + GUARD_OBJ(a, GetVpValue(self, 1)); + switch (TYPE(r)) { + case T_DATA: + if (!is_kind_of_BigDecimal(r)) break; + /* fall through */ + case T_FIXNUM: + /* fall through */ + case T_BIGNUM: + GUARD_OBJ(b, GetVpValue(r, 0)); + break; + + case T_FLOAT: + GUARD_OBJ(b, GetVpValueWithPrec(r, 0, 0)); + break; + + case T_RATIONAL: + GUARD_OBJ(b, GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 0)); + break; + + default: + break; + } + if (b == NULL) { + ID f = 0; + + switch (op) { + case '*': + return rb_num_coerce_cmp(self, r, rb_intern("<=>")); + + case '=': + return RTEST(rb_num_coerce_cmp(self, r, rb_intern("=="))) ? Qtrue : Qfalse; + + case 'G': + f = rb_intern(">="); + break; + + case 'L': + f = rb_intern("<="); + break; + + case '>': + /* fall through */ + case '<': + f = (ID)op; + break; + + default: + break; + } + return rb_num_coerce_relop(self, r, f); + } + SAVE(b); + e = VpComp(a, b); + if (e == 999) + return (op == '*') ? Qnil : Qfalse; + switch (op) { + case '*': + return INT2FIX(e); /* any op */ + + case '=': + if (e == 0) return Qtrue; + return Qfalse; + + case 'G': + if (e >= 0) return Qtrue; + return Qfalse; + + case '>': + if (e > 0) return Qtrue; + return Qfalse; + + case 'L': + if (e <= 0) return Qtrue; + return Qfalse; + + case '<': + if (e < 0) return Qtrue; + return Qfalse; + + default: + break; + } + + rb_bug("Undefined operation in BigDecimalCmp()"); + + UNREACHABLE; +} + +/* Returns True if the value is zero. */ +static VALUE +BigDecimal_zero(VALUE self) +{ + Real *a = GetVpValue(self, 1); + return VpIsZero(a) ? Qtrue : Qfalse; +} + +/* Returns self if the value is non-zero, nil otherwise. */ +static VALUE +BigDecimal_nonzero(VALUE self) +{ + Real *a = GetVpValue(self, 1); + return VpIsZero(a) ? Qnil : self; +} + +/* The comparison operator. + * a <=> b is 0 if a == b, 1 if a > b, -1 if a < b. + */ +static VALUE +BigDecimal_comp(VALUE self, VALUE r) +{ + return BigDecimalCmp(self, r, '*'); +} + +/* + * Tests for value equality; returns true if the values are equal. + * + * The == and === operators and the eql? method have the same implementation + * for BigDecimal. + * + * Values may be coerced to perform the comparison: + * + * BigDecimal('1.0') == 1.0 #=> true + */ +static VALUE +BigDecimal_eq(VALUE self, VALUE r) +{ + return BigDecimalCmp(self, r, '='); +} + +/* call-seq: + * self < other -> true or false + * + * Returns +true+ if +self+ is less than +other+, +false+ otherwise: + * + * b = BigDecimal('1.5') # => 0.15e1 + * b < 2 # => true + * b < 2.0 # => true + * b < Rational(2, 1) # => true + * b < 1.5 # => false + * + * Raises an exception if the comparison cannot be made. + * + */ +static VALUE +BigDecimal_lt(VALUE self, VALUE r) +{ + return BigDecimalCmp(self, r, '<'); +} + +/* call-seq: + * self <= other -> true or false + * + * Returns +true+ if +self+ is less or equal to than +other+, +false+ otherwise: + * + * b = BigDecimal('1.5') # => 0.15e1 + * b <= 2 # => true + * b <= 2.0 # => true + * b <= Rational(2, 1) # => true + * b <= 1.5 # => true + * b < 1 # => false + * + * Raises an exception if the comparison cannot be made. + * + */ +static VALUE +BigDecimal_le(VALUE self, VALUE r) +{ + return BigDecimalCmp(self, r, 'L'); +} + +/* call-seq: + * self > other -> true or false + * + * Returns +true+ if +self+ is greater than +other+, +false+ otherwise: + * + * b = BigDecimal('1.5') + * b > 1 # => true + * b > 1.0 # => true + * b > Rational(1, 1) # => true + * b > 2 # => false + * + * Raises an exception if the comparison cannot be made. + * + */ +static VALUE +BigDecimal_gt(VALUE self, VALUE r) +{ + return BigDecimalCmp(self, r, '>'); +} + +/* call-seq: + * self >= other -> true or false + * + * Returns +true+ if +self+ is greater than or equal to +other+, +false+ otherwise: + * + * b = BigDecimal('1.5') + * b >= 1 # => true + * b >= 1.0 # => true + * b >= Rational(1, 1) # => true + * b >= 1.5 # => true + * b > 2 # => false + * + * Raises an exception if the comparison cannot be made. + * + */ +static VALUE +BigDecimal_ge(VALUE self, VALUE r) +{ + return BigDecimalCmp(self, r, 'G'); +} + +/* + * call-seq: + * -self -> bigdecimal + * + * Returns the \BigDecimal negation of self: + * + * b0 = BigDecimal('1.5') + * b1 = -b0 # => -0.15e1 + * b2 = -b1 # => 0.15e1 + * + */ + +static VALUE +BigDecimal_neg(VALUE self) +{ + ENTER(5); + Real *c, *a; + GUARD_OBJ(a, GetVpValue(self, 1)); + GUARD_OBJ(c, NewZeroWrapLimited(1, a->Prec *(VpBaseFig() + 1))); + VpAsgn(c, a, -1); + return VpCheckGetValue(c); +} + +/* + * call-seq: + * a * b -> bigdecimal + * + * Multiply by the specified value. + * + * The result precision will be the precision of the sum of each precision. + * + * See BigDecimal#mult. + */ + +static VALUE +BigDecimal_mult(VALUE self, VALUE r) +{ + ENTER(5); + Real *c, *a, *b; + size_t mx; + + GUARD_OBJ(a, GetVpValue(self, 1)); + if (RB_TYPE_P(r, T_FLOAT)) { + b = GetVpValueWithPrec(r, 0, 1); + } + else if (RB_TYPE_P(r, T_RATIONAL)) { + b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1); + } + else { + b = GetVpValue(r,0); + } + + if (!b) return DoSomeOne(self, r, '*'); + SAVE(b); + + mx = a->Prec + b->Prec; + GUARD_OBJ(c, NewZeroWrapLimited(1, mx * (VpBaseFig() + 1))); + VpMult(c, a, b); + return VpCheckGetValue(c); +} + +static VALUE BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod); + +/* call-seq: + * a / b -> bigdecimal + * + * Divide by the specified value. + * + * The result precision will be the precision of the larger operand, + * but its minimum is 2*Float::DIG. + * + * See BigDecimal#div. + * See BigDecimal#quo. + */ +static VALUE +BigDecimal_div(VALUE self, VALUE r) +/* For c = self/r: with round operation */ +{ + if ( + !is_kind_of_BigDecimal(r) && + !RB_INTEGER_TYPE_P(r) && + !RB_TYPE_P(r, T_FLOAT) && + !RB_TYPE_P(r, T_RATIONAL) + ) { + return DoSomeOne(self, r, '/'); + } + return BigDecimal_div2(self, r, INT2FIX(0)); +} + +static VALUE BigDecimal_round(int argc, VALUE *argv, VALUE self); + +/* call-seq: + * quo(value) -> bigdecimal + * quo(value, digits) -> bigdecimal + * + * Divide by the specified value. + * + * digits:: If specified and less than the number of significant digits of + * the result, the result is rounded to the given number of digits, + * according to the rounding mode indicated by BigDecimal.mode. + * + * If digits is 0 or omitted, the result is the same as for the + * / operator. + * + * See BigDecimal#/. + * See BigDecimal#div. + */ +static VALUE +BigDecimal_quo(int argc, VALUE *argv, VALUE self) +{ + VALUE value, digits, result; + SIGNED_VALUE n = -1; + + argc = rb_scan_args(argc, argv, "11", &value, &digits); + if (argc > 1) { + n = check_int_precision(digits); + } + + if (n > 0) { + result = BigDecimal_div2(self, value, digits); + } + else { + result = BigDecimal_div(self, value); + } + + return result; +} + +/* + * %: mod = a%b = a - (a.to_f/b).floor * b + * div = (a.to_f/b).floor + */ +static VALUE +BigDecimal_DoDivmod(VALUE self, VALUE r, Real **div, Real **mod) +{ + ENTER(8); + Real *c=NULL, *d=NULL, *res=NULL; + Real *a, *b; + ssize_t a_prec, b_prec; + size_t mx; + + TypedData_Get_Struct(self, Real, &BigDecimal_data_type, a); + SAVE(a); + + VALUE rr = r; + if (is_kind_of_BigDecimal(rr)) { + /* do nothing */ + } + else if (RB_INTEGER_TYPE_P(r)) { + rr = rb_inum_convert_to_BigDecimal(r, 0, true); + } + else if (RB_TYPE_P(r, T_FLOAT)) { + rr = rb_float_convert_to_BigDecimal(r, 0, true); + } + else if (RB_TYPE_P(r, T_RATIONAL)) { + rr = rb_rational_convert_to_BigDecimal(r, a->Prec*BASE_FIG, true); + } + + if (!is_kind_of_BigDecimal(rr)) { + return Qfalse; + } + + TypedData_Get_Struct(rr, Real, &BigDecimal_data_type, b); + SAVE(b); + + if (VpIsNaN(a) || VpIsNaN(b)) goto NaN; + if (VpIsInf(a) && VpIsInf(b)) goto NaN; + if (VpIsZero(b)) { + rb_raise(rb_eZeroDivError, "divided by 0"); + } + if (VpIsInf(a)) { + if (VpGetSign(a) == VpGetSign(b)) { + VALUE inf = BigDecimal_positive_infinity(); + TypedData_Get_Struct(inf, Real, &BigDecimal_data_type, *div); + } + else { + VALUE inf = BigDecimal_negative_infinity(); + TypedData_Get_Struct(inf, Real, &BigDecimal_data_type, *div); + } + VALUE nan = BigDecimal_nan(); + TypedData_Get_Struct(nan, Real, &BigDecimal_data_type, *mod); + return Qtrue; + } + if (VpIsInf(b)) { + VALUE zero = BigDecimal_positive_zero(); + TypedData_Get_Struct(zero, Real, &BigDecimal_data_type, *div); + *mod = a; + return Qtrue; + } + if (VpIsZero(a)) { + VALUE zero = BigDecimal_positive_zero(); + TypedData_Get_Struct(zero, Real, &BigDecimal_data_type, *div); + TypedData_Get_Struct(zero, Real, &BigDecimal_data_type, *mod); + return Qtrue; + } + + BigDecimal_count_precision_and_scale(self, &a_prec, NULL); + BigDecimal_count_precision_and_scale(rr, &b_prec, NULL); + + mx = (a_prec > b_prec) ? a_prec : b_prec; + mx *= 2; + + if (2*BIGDECIMAL_DOUBLE_FIGURES > mx) + mx = 2*BIGDECIMAL_DOUBLE_FIGURES; + + GUARD_OBJ(c, NewZeroWrapLimited(1, mx + 2*BASE_FIG)); + GUARD_OBJ(res, NewZeroWrapNolimit(1, mx*2 + 2*BASE_FIG)); + VpDivd(c, res, a, b); + + mx = c->Prec * BASE_FIG; + GUARD_OBJ(d, NewZeroWrapLimited(1, mx)); + VpActiveRound(d, c, VP_ROUND_DOWN, 0); + + VpMult(res, d, b); + VpAddSub(c, a, res, -1); + + if (!VpIsZero(c) && (VpGetSign(a) * VpGetSign(b) < 0)) { + /* result adjustment for negative case */ + res = rbd_reallocate_struct(res, d->MaxPrec); + res->MaxPrec = d->MaxPrec; + VpAddSub(res, d, VpOne(), -1); + GUARD_OBJ(d, NewZeroWrapLimited(1, GetAddSubPrec(c, b) * 2*BASE_FIG)); + VpAddSub(d, c, b, 1); + *div = res; + *mod = d; + } + else { + *div = d; + *mod = c; + } + return Qtrue; + + NaN: + { + VALUE nan = BigDecimal_nan(); + TypedData_Get_Struct(nan, Real, &BigDecimal_data_type, *div); + TypedData_Get_Struct(nan, Real, &BigDecimal_data_type, *mod); + } + return Qtrue; +} + +/* call-seq: + * a % b + * a.modulo(b) + * + * Returns the modulus from dividing by b. + * + * See BigDecimal#divmod. + */ +static VALUE +BigDecimal_mod(VALUE self, VALUE r) /* %: a%b = a - (a.to_f/b).floor * b */ +{ + ENTER(3); + Real *div = NULL, *mod = NULL; + + if (BigDecimal_DoDivmod(self, r, &div, &mod)) { + SAVE(div); SAVE(mod); + return VpCheckGetValue(mod); + } + return DoSomeOne(self, r, '%'); +} + +static VALUE +BigDecimal_divremain(VALUE self, VALUE r, Real **dv, Real **rv) +{ + ENTER(10); + size_t mx; + Real *a = NULL, *b = NULL, *c = NULL, *res = NULL, *d = NULL, *rr = NULL, *ff = NULL; + Real *f = NULL; + + GUARD_OBJ(a, GetVpValue(self, 1)); + if (RB_TYPE_P(r, T_FLOAT)) { + b = GetVpValueWithPrec(r, 0, 1); + } + else if (RB_TYPE_P(r, T_RATIONAL)) { + b = GetVpValueWithPrec(r, a->Prec*VpBaseFig(), 1); + } + else { + b = GetVpValue(r, 0); + } + + if (!b) return DoSomeOne(self, r, rb_intern("remainder")); + SAVE(b); + + if (VpIsPosInf(b) || VpIsNegInf(b)) { + GUARD_OBJ(*dv, NewZeroWrapLimited(1, 1)); + VpSetZero(*dv, 1); + *rv = a; + return Qnil; + } + + mx = (a->MaxPrec + b->MaxPrec) *VpBaseFig(); + GUARD_OBJ(c, NewZeroWrapLimited(1, mx)); + GUARD_OBJ(res, NewZeroWrapNolimit(1, (mx+1) * 2 + (VpBaseFig() + 1))); + GUARD_OBJ(rr, NewZeroWrapNolimit(1, (mx+1) * 2 + (VpBaseFig() + 1))); + GUARD_OBJ(ff, NewZeroWrapNolimit(1, (mx+1) * 2 + (VpBaseFig() + 1))); + + VpDivd(c, res, a, b); + + mx = c->Prec *(VpBaseFig() + 1); + + GUARD_OBJ(d, NewZeroWrapLimited(1, mx)); + GUARD_OBJ(f, NewZeroWrapLimited(1, mx)); + + VpActiveRound(d, c, VP_ROUND_DOWN, 0); /* 0: round off */ + + VpFrac(f, c); + VpMult(rr, f, b); + VpAddSub(ff, res, rr, 1); + + *dv = d; + *rv = ff; + return Qnil; +} + +/* call-seq: + * remainder(value) + * + * Returns the remainder from dividing by the value. + * + * x.remainder(y) means x-y*(x/y).truncate + */ +static VALUE +BigDecimal_remainder(VALUE self, VALUE r) /* remainder */ +{ + VALUE f; + Real *d, *rv = 0; + f = BigDecimal_divremain(self, r, &d, &rv); + if (!NIL_P(f)) return f; + return VpCheckGetValue(rv); +} + +/* call-seq: + * divmod(value) + * + * Divides by the specified value, and returns the quotient and modulus + * as BigDecimal numbers. The quotient is rounded towards negative infinity. + * + * For example: + * + * require 'bigdecimal' + * + * a = BigDecimal("42") + * b = BigDecimal("9") + * + * q, m = a.divmod(b) + * + * c = q * b + m + * + * a == c #=> true + * + * The quotient q is (a/b).floor, and the modulus is the amount that must be + * added to q * b to get a. + */ +static VALUE +BigDecimal_divmod(VALUE self, VALUE r) +{ + ENTER(5); + Real *div = NULL, *mod = NULL; + + if (BigDecimal_DoDivmod(self, r, &div, &mod)) { + SAVE(div); SAVE(mod); + return rb_assoc_new(VpCheckGetValue(div), VpCheckGetValue(mod)); + } + return DoSomeOne(self,r,rb_intern("divmod")); +} + +/* + * Do the same manner as Float#div when n is nil. + * Do the same manner as BigDecimal#quo when n is 0. + */ +static inline VALUE +BigDecimal_div2(VALUE self, VALUE b, VALUE n) +{ + ENTER(5); + SIGNED_VALUE ix; + Real *res = NULL; + Real *av = NULL, *bv = NULL, *cv = NULL; + size_t mx, pl; + + if (NIL_P(n)) { /* div in Float sense */ + Real *div = NULL; + Real *mod; + if (BigDecimal_DoDivmod(self, b, &div, &mod)) { + return BigDecimal_to_i(VpCheckGetValue(div)); + } + return DoSomeOne(self, b, rb_intern("div")); + } + + /* div in BigDecimal sense */ + ix = check_int_precision(n); + + pl = VpSetPrecLimit(0); + if (ix == 0) ix = pl; + + GUARD_OBJ(av, GetVpValue(self, 1)); + if (RB_FLOAT_TYPE_P(b) && ix > BIGDECIMAL_DOUBLE_FIGURES) { + /* TODO: I want to refactor this precision control for a float value later + * by introducing an implicit conversion function instead of + * GetVpValueWithPrec. */ + GUARD_OBJ(bv, GetVpValueWithPrec(b, BIGDECIMAL_DOUBLE_FIGURES, 1)); + } + else { + GUARD_OBJ(bv, GetVpValueWithPrec(b, ix, 1)); + } + + if (ix == 0) { + ssize_t a_prec, b_prec; + VpCountPrecisionAndScale(av, &a_prec, NULL); + VpCountPrecisionAndScale(bv, &b_prec, NULL); + ix = ((a_prec > b_prec) ? a_prec : b_prec) + BIGDECIMAL_DOUBLE_FIGURES; + if (2 * BIGDECIMAL_DOUBLE_FIGURES > ix) + ix = 2 * BIGDECIMAL_DOUBLE_FIGURES; + } + + // VpDivd needs 2 extra DECDIGs. One more is needed for rounding. + GUARD_OBJ(cv, NewZeroWrapLimited(1, ix + 3 * VpBaseFig())); + + mx = bv->Prec + cv->MaxPrec - 1; + if (mx <= av->Prec) mx = av->Prec + 1; + GUARD_OBJ(res, NewZeroWrapNolimit(1, mx * VpBaseFig())); + VpDivd(cv, res, av, bv); + VpSetPrecLimit(pl); + if (!VpIsZero(res)) { + // Remainder value affects rounding result. + // ROUND_UP cv = 0.1e0 with ix=10 will be: + // 0.1e0 if remainder == 0 + // 0.1000000001e0 if remainder != 0 + size_t idx = roomof(ix, BASE_FIG); + while (cv->Prec <= idx) cv->frac[cv->Prec++] = 0; + if (cv->frac[idx] == 0 || cv->frac[idx] == HALF_BASE) cv->frac[idx]++; + } + VpLeftRound(cv, VpGetRoundMode(), ix); + return VpCheckGetValue(cv); +} + + /* + * Document-method: BigDecimal#div + * + * call-seq: + * div(value) -> integer + * div(value, digits) -> bigdecimal or integer + * + * Divide by the specified value. + * + * digits:: If specified and less than the number of significant digits of the + * result, the result is rounded to that number of digits, according + * to BigDecimal.mode. + * + * If digits is 0, the result is the same as for the / operator + * or #quo. + * + * If digits is not specified, the result is an integer, + * by analogy with Float#div; see also BigDecimal#divmod. + * + * See BigDecimal#/. + * See BigDecimal#quo. + * + * Examples: + * + * a = BigDecimal("4") + * b = BigDecimal("3") + * + * a.div(b, 3) # => 0.133e1 + * + * a.div(b, 0) # => 0.1333333333333333333e1 + * a / b # => 0.1333333333333333333e1 + * a.quo(b) # => 0.1333333333333333333e1 + * + * a.div(b) # => 1 + */ +static VALUE +BigDecimal_div3(int argc, VALUE *argv, VALUE self) +{ + VALUE b,n; + + rb_scan_args(argc, argv, "11", &b, &n); + + return BigDecimal_div2(self, b, n); +} + + /* + * call-seq: + * add(value, ndigits) -> new_bigdecimal + * + * Returns the \BigDecimal sum of +self+ and +value+ + * with a precision of +ndigits+ decimal digits. + * + * When +ndigits+ is less than the number of significant digits + * in the sum, the sum is rounded to that number of digits, + * according to the current rounding mode; see BigDecimal.mode. + * + * Examples: + * + * # Set the rounding mode. + * BigDecimal.mode(BigDecimal::ROUND_MODE, :half_up) + * b = BigDecimal('111111.111') + * b.add(1, 0) # => 0.111112111e6 + * b.add(1, 3) # => 0.111e6 + * b.add(1, 6) # => 0.111112e6 + * b.add(1, 15) # => 0.111112111e6 + * b.add(1.0, 15) # => 0.111112111e6 + * b.add(Rational(1, 1), 15) # => 0.111112111e6 + * + */ + +static VALUE +BigDecimal_add2(VALUE self, VALUE b, VALUE n) +{ + ENTER(2); + Real *cv; + SIGNED_VALUE mx = check_int_precision(n); + if (mx == 0) return BigDecimal_add(self, b); + else { + size_t pl = VpSetPrecLimit(0); + VALUE c = BigDecimal_add(self, b); + VpSetPrecLimit(pl); + GUARD_OBJ(cv, GetVpValue(c, 1)); + VpLeftRound(cv, VpGetRoundMode(), mx); + return VpCheckGetValue(cv); + } +} + +/* call-seq: + * sub(value, digits) -> bigdecimal + * + * Subtract the specified value. + * + * e.g. + * c = a.sub(b,n) + * + * digits:: If specified and less than the number of significant digits of the + * result, the result is rounded to that number of digits, according + * to BigDecimal.mode. + * + */ +static VALUE +BigDecimal_sub2(VALUE self, VALUE b, VALUE n) +{ + ENTER(2); + Real *cv; + SIGNED_VALUE mx = check_int_precision(n); + if (mx == 0) return BigDecimal_sub(self, b); + else { + size_t pl = VpSetPrecLimit(0); + VALUE c = BigDecimal_sub(self, b); + VpSetPrecLimit(pl); + GUARD_OBJ(cv, GetVpValue(c, 1)); + VpLeftRound(cv, VpGetRoundMode(), mx); + return VpCheckGetValue(cv); + } +} + + /* + * call-seq: + * mult(other, ndigits) -> bigdecimal + * + * Returns the \BigDecimal product of +self+ and +value+ + * with a precision of +ndigits+ decimal digits. + * + * When +ndigits+ is less than the number of significant digits + * in the sum, the sum is rounded to that number of digits, + * according to the current rounding mode; see BigDecimal.mode. + * + * Examples: + * + * # Set the rounding mode. + * BigDecimal.mode(BigDecimal::ROUND_MODE, :half_up) + * b = BigDecimal('555555.555') + * b.mult(3, 0) # => 0.1666666665e7 + * b.mult(3, 3) # => 0.167e7 + * b.mult(3, 6) # => 0.166667e7 + * b.mult(3, 15) # => 0.1666666665e7 + * b.mult(3.0, 0) # => 0.1666666665e7 + * b.mult(Rational(3, 1), 0) # => 0.1666666665e7 + * b.mult(Complex(3, 0), 0) # => (0.1666666665e7+0.0i) + * + */ + +static VALUE +BigDecimal_mult2(VALUE self, VALUE b, VALUE n) +{ + ENTER(2); + Real *cv; + SIGNED_VALUE mx = check_int_precision(n); + if (mx == 0) return BigDecimal_mult(self, b); + else { + size_t pl = VpSetPrecLimit(0); + VALUE c = BigDecimal_mult(self, b); + VpSetPrecLimit(pl); + GUARD_OBJ(cv, GetVpValue(c, 1)); + VpLeftRound(cv, VpGetRoundMode(), mx); + return VpCheckGetValue(cv); + } +} + +/* + * call-seq: + * abs -> bigdecimal + * + * Returns the \BigDecimal absolute value of +self+: + * + * BigDecimal('5').abs # => 0.5e1 + * BigDecimal('-3').abs # => 0.3e1 + * + */ + +static VALUE +BigDecimal_abs(VALUE self) +{ + ENTER(5); + Real *c, *a; + size_t mx; + + GUARD_OBJ(a, GetVpValue(self, 1)); + mx = a->Prec *(VpBaseFig() + 1); + GUARD_OBJ(c, NewZeroWrapLimited(1, mx)); + VpAsgn(c, a, 1); + VpChangeSign(c, 1); + return VpCheckGetValue(c); +} + +/* call-seq: + * sqrt(n) + * + * Returns the square root of the value. + * + * Result has at least n significant digits. + */ +static VALUE +BigDecimal_sqrt(VALUE self, VALUE nFig) +{ + ENTER(5); + Real *c, *a; + size_t mx, n; + + GUARD_OBJ(a, GetVpValue(self, 1)); + mx = a->Prec * (VpBaseFig() + 1); + + n = check_int_precision(nFig); + n += VpDblFig() + VpBaseFig(); + if (mx <= n) mx = n; + GUARD_OBJ(c, NewZeroWrapLimited(1, mx)); + VpSqrt(c, a); + return VpCheckGetValue(c); +} + +/* Return the integer part of the number, as a BigDecimal. + */ +static VALUE +BigDecimal_fix(VALUE self) +{ + ENTER(5); + Real *c, *a; + size_t mx; + + GUARD_OBJ(a, GetVpValue(self, 1)); + mx = a->Prec *(VpBaseFig() + 1); + GUARD_OBJ(c, NewZeroWrapLimited(1, mx)); + VpActiveRound(c, a, VP_ROUND_DOWN, 0); /* 0: round off */ + return VpCheckGetValue(c); +} + +/* call-seq: + * round(n, mode) + * + * Round to the nearest integer (by default), returning the result as a + * BigDecimal if n is specified and positive, or as an Integer if it isn't. + * + * BigDecimal('3.14159').round #=> 3 + * BigDecimal('8.7').round #=> 9 + * BigDecimal('-9.9').round #=> -10 + * + * BigDecimal('3.14159').round(2).class.name #=> "BigDecimal" + * BigDecimal('3.14159').round.class.name #=> "Integer" + * BigDecimal('3.14159').round(0).class.name #=> "Integer" + * + * If n is specified and positive, the fractional part of the result has no + * more than that many digits. + * + * If n is specified and negative, at least that many digits to the left of the + * decimal point will be 0 in the result, and return value will be an Integer. + * + * BigDecimal('3.14159').round(3) #=> 3.142 + * BigDecimal('13345.234').round(-2) #=> 13300 + * + * The value of the optional mode argument can be used to determine how + * rounding is performed; see BigDecimal.mode. + */ +static VALUE +BigDecimal_round(int argc, VALUE *argv, VALUE self) +{ + ENTER(5); + Real *c, *a; + int iLoc = 0; + VALUE vLoc; + VALUE vRound; + int round_to_int = 0; + size_t mx, pl; + + unsigned short sw = VpGetRoundMode(); + + switch (rb_scan_args(argc, argv, "02", &vLoc, &vRound)) { + case 0: + iLoc = 0; + round_to_int = 1; + break; + case 1: + if (RB_TYPE_P(vLoc, T_HASH)) { + sw = check_rounding_mode_option(vLoc); + } + else { + iLoc = NUM2INT(vLoc); + if (iLoc < 1) round_to_int = 1; + } + break; + case 2: + iLoc = NUM2INT(vLoc); + if (RB_TYPE_P(vRound, T_HASH)) { + sw = check_rounding_mode_option(vRound); + } + else { + sw = check_rounding_mode(vRound); + } + break; + default: + break; + } + + pl = VpSetPrecLimit(0); + GUARD_OBJ(a, GetVpValue(self, 1)); + mx = a->Prec * (VpBaseFig() + 1); + GUARD_OBJ(c, NewZeroWrapLimited(1, mx)); + VpSetPrecLimit(pl); + VpActiveRound(c, a, sw, iLoc); + if (round_to_int) { + return BigDecimal_to_i(VpCheckGetValue(c)); + } + return VpCheckGetValue(c); +} + +/* call-seq: + * truncate(n) + * + * Truncate to the nearest integer (by default), returning the result as a + * BigDecimal. + * + * BigDecimal('3.14159').truncate #=> 3 + * BigDecimal('8.7').truncate #=> 8 + * BigDecimal('-9.9').truncate #=> -9 + * + * If n is specified and positive, the fractional part of the result has no + * more than that many digits. + * + * If n is specified and negative, at least that many digits to the left of the + * decimal point will be 0 in the result. + * + * BigDecimal('3.14159').truncate(3) #=> 3.141 + * BigDecimal('13345.234').truncate(-2) #=> 13300.0 + */ +static VALUE +BigDecimal_truncate(int argc, VALUE *argv, VALUE self) +{ + ENTER(5); + Real *c, *a; + int iLoc; + VALUE vLoc; + size_t mx, pl = VpSetPrecLimit(0); + + if (rb_scan_args(argc, argv, "01", &vLoc) == 0) { + iLoc = 0; + } + else { + iLoc = NUM2INT(vLoc); + } + + GUARD_OBJ(a, GetVpValue(self, 1)); + mx = a->Prec * (VpBaseFig() + 1); + GUARD_OBJ(c, NewZeroWrapLimited(1, mx)); + VpSetPrecLimit(pl); + VpActiveRound(c, a, VP_ROUND_DOWN, iLoc); /* 0: truncate */ + if (argc == 0) { + return BigDecimal_to_i(VpCheckGetValue(c)); + } + return VpCheckGetValue(c); +} + +/* Return the fractional part of the number, as a BigDecimal. + */ +static VALUE +BigDecimal_frac(VALUE self) +{ + ENTER(5); + Real *c, *a; + size_t mx; + + GUARD_OBJ(a, GetVpValue(self, 1)); + mx = a->Prec * (VpBaseFig() + 1); + GUARD_OBJ(c, NewZeroWrapLimited(1, mx)); + VpFrac(c, a); + return VpCheckGetValue(c); +} + +/* call-seq: + * floor(n) + * + * Return the largest integer less than or equal to the value, as a BigDecimal. + * + * BigDecimal('3.14159').floor #=> 3 + * BigDecimal('-9.1').floor #=> -10 + * + * If n is specified and positive, the fractional part of the result has no + * more than that many digits. + * + * If n is specified and negative, at least that + * many digits to the left of the decimal point will be 0 in the result. + * + * BigDecimal('3.14159').floor(3) #=> 3.141 + * BigDecimal('13345.234').floor(-2) #=> 13300.0 + */ +static VALUE +BigDecimal_floor(int argc, VALUE *argv, VALUE self) +{ + ENTER(5); + Real *c, *a; + int iLoc; + VALUE vLoc; + size_t mx, pl = VpSetPrecLimit(0); + + if (rb_scan_args(argc, argv, "01", &vLoc)==0) { + iLoc = 0; + } + else { + iLoc = NUM2INT(vLoc); + } + + GUARD_OBJ(a, GetVpValue(self, 1)); + mx = a->Prec * (VpBaseFig() + 1); + GUARD_OBJ(c, NewZeroWrapLimited(1, mx)); + VpSetPrecLimit(pl); + VpActiveRound(c, a, VP_ROUND_FLOOR, iLoc); +#ifdef BIGDECIMAL_DEBUG + VPrint(stderr, "floor: c=%\n", c); +#endif + if (argc == 0) { + return BigDecimal_to_i(VpCheckGetValue(c)); + } + return VpCheckGetValue(c); +} + +/* call-seq: + * ceil(n) + * + * Return the smallest integer greater than or equal to the value, as a BigDecimal. + * + * BigDecimal('3.14159').ceil #=> 4 + * BigDecimal('-9.1').ceil #=> -9 + * + * If n is specified and positive, the fractional part of the result has no + * more than that many digits. + * + * If n is specified and negative, at least that + * many digits to the left of the decimal point will be 0 in the result. + * + * BigDecimal('3.14159').ceil(3) #=> 3.142 + * BigDecimal('13345.234').ceil(-2) #=> 13400.0 + */ +static VALUE +BigDecimal_ceil(int argc, VALUE *argv, VALUE self) +{ + ENTER(5); + Real *c, *a; + int iLoc; + VALUE vLoc; + size_t mx, pl = VpSetPrecLimit(0); + + if (rb_scan_args(argc, argv, "01", &vLoc) == 0) { + iLoc = 0; + } else { + iLoc = NUM2INT(vLoc); + } + + GUARD_OBJ(a, GetVpValue(self, 1)); + mx = a->Prec * (VpBaseFig() + 1); + GUARD_OBJ(c, NewZeroWrapLimited(1, mx)); + VpSetPrecLimit(pl); + VpActiveRound(c, a, VP_ROUND_CEIL, iLoc); + if (argc == 0) { + return BigDecimal_to_i(VpCheckGetValue(c)); + } + return VpCheckGetValue(c); +} + +/* call-seq: + * to_s(s) + * + * Converts the value to a string. + * + * The default format looks like 0.xxxxEnn. + * + * The optional parameter s consists of either an integer; or an optional '+' + * or ' ', followed by an optional number, followed by an optional 'E' or 'F'. + * + * If there is a '+' at the start of s, positive values are returned with + * a leading '+'. + * + * A space at the start of s returns positive values with a leading space. + * + * If s contains a number, a space is inserted after each group of that many + * digits, starting from '.' and counting outwards. + * + * If s ends with an 'E', engineering notation (0.xxxxEnn) is used. + * + * If s ends with an 'F', conventional floating point notation is used. + * + * Examples: + * + * BigDecimal('-1234567890123.45678901234567890').to_s('5F') + * #=> '-123 45678 90123.45678 90123 45678 9' + * + * BigDecimal('1234567890123.45678901234567890').to_s('+8F') + * #=> '+12345 67890123.45678901 23456789' + * + * BigDecimal('1234567890123.45678901234567890').to_s(' F') + * #=> ' 1234567890123.4567890123456789' + */ +static VALUE +BigDecimal_to_s(int argc, VALUE *argv, VALUE self) +{ + ENTER(5); + int fmt = 0; /* 0: E format, 1: F format */ + int fPlus = 0; /* 0: default, 1: set ' ' before digits, 2: set '+' before digits. */ + Real *vp; + volatile VALUE str; + char *psz; + char ch; + size_t nc, mc = 0; + SIGNED_VALUE m; + VALUE f; + + GUARD_OBJ(vp, GetVpValue(self, 1)); + + if (rb_scan_args(argc, argv, "01", &f) == 1) { + if (RB_TYPE_P(f, T_STRING)) { + psz = StringValueCStr(f); + if (*psz == ' ') { + fPlus = 1; + psz++; + } + else if (*psz == '+') { + fPlus = 2; + psz++; + } + while ((ch = *psz++) != 0) { + if (ISSPACE(ch)) { + continue; + } + if (!ISDIGIT(ch)) { + if (ch == 'F' || ch == 'f') { + fmt = 1; /* F format */ + } + break; + } + mc = mc*10 + ch - '0'; + } + } + else { + m = NUM2INT(f); + if (m <= 0) { + rb_raise(rb_eArgError, "argument must be positive"); + } + mc = (size_t)m; + } + } + if (fmt) { + nc = VpNumOfChars(vp, "F"); + } + else { + nc = VpNumOfChars(vp, "E"); + } + if (mc > 0) { + nc += (nc + mc - 1) / mc + 1; + } + + str = rb_usascii_str_new(0, nc); + psz = RSTRING_PTR(str); + + if (fmt) { + VpToFString(vp, psz, RSTRING_LEN(str), mc, fPlus); + } + else { + VpToString (vp, psz, RSTRING_LEN(str), mc, fPlus); + } + rb_str_resize(str, strlen(psz)); + return str; +} + +/* Splits a BigDecimal number into four parts, returned as an array of values. + * + * The first value represents the sign of the BigDecimal, and is -1 or 1, or 0 + * if the BigDecimal is Not a Number. + * + * The second value is a string representing the significant digits of the + * BigDecimal, with no leading zeros. + * + * The third value is the base used for arithmetic (currently always 10) as an + * Integer. + * + * The fourth value is an Integer exponent. + * + * If the BigDecimal can be represented as 0.xxxxxx*10**n, then xxxxxx is the + * string of significant digits with no leading zeros, and n is the exponent. + * + * From these values, you can translate a BigDecimal to a float as follows: + * + * sign, significant_digits, base, exponent = a.split + * f = sign * "0.#{significant_digits}".to_f * (base ** exponent) + * + * (Note that the to_f method is provided as a more convenient way to translate + * a BigDecimal to a Float.) + */ +static VALUE +BigDecimal_split(VALUE self) +{ + ENTER(5); + Real *vp; + VALUE obj,str; + ssize_t e, s; + char *psz1; + + GUARD_OBJ(vp, GetVpValue(self, 1)); + str = rb_str_new(0, VpNumOfChars(vp, "E")); + psz1 = RSTRING_PTR(str); + VpSzMantissa(vp, psz1, RSTRING_LEN(str)); + s = 1; + if(psz1[0] == '-') { + size_t len = strlen(psz1 + 1); + + memmove(psz1, psz1 + 1, len); + psz1[len] = '\0'; + s = -1; + } + if (psz1[0] == 'N') s = 0; /* NaN */ + e = VpExponent10(vp); + obj = rb_ary_new2(4); + rb_ary_push(obj, INT2FIX(s)); + rb_ary_push(obj, str); + rb_str_resize(str, strlen(psz1)); + rb_ary_push(obj, INT2FIX(10)); + rb_ary_push(obj, SSIZET2NUM(e)); + return obj; +} + +/* Returns the exponent of the BigDecimal number, as an Integer. + * + * If the number can be represented as 0.xxxxxx*10**n where xxxxxx is a string + * of digits with no leading zeros, then n is the exponent. + */ +static VALUE +BigDecimal_exponent(VALUE self) +{ + ssize_t e = VpExponent10(GetVpValue(self, 1)); + return SSIZET2NUM(e); +} + +/* Returns a string representation of self. + * + * BigDecimal("1234.5678").inspect + * #=> "0.12345678e4" + */ +static VALUE +BigDecimal_inspect(VALUE self) +{ + ENTER(5); + Real *vp; + volatile VALUE str; + size_t nc; + + GUARD_OBJ(vp, GetVpValue(self, 1)); + nc = VpNumOfChars(vp, "E"); + + str = rb_str_new(0, nc); + VpToString(vp, RSTRING_PTR(str), RSTRING_LEN(str), 0, 0); + rb_str_resize(str, strlen(RSTRING_PTR(str))); + return str; +} + +static VALUE BigMath_s_exp(VALUE, VALUE, VALUE); +static VALUE BigMath_s_log(VALUE, VALUE, VALUE); + +#define BigMath_exp(x, n) BigMath_s_exp(rb_mBigMath, (x), (n)) +#define BigMath_log(x, n) BigMath_s_log(rb_mBigMath, (x), (n)) + +inline static int +is_integer(VALUE x) +{ + return (RB_TYPE_P(x, T_FIXNUM) || RB_TYPE_P(x, T_BIGNUM)); +} + +inline static int +is_negative(VALUE x) +{ + if (FIXNUM_P(x)) { + return FIX2LONG(x) < 0; + } + else if (RB_TYPE_P(x, T_BIGNUM)) { + return FIX2INT(rb_big_cmp(x, INT2FIX(0))) < 0; + } + else if (RB_TYPE_P(x, T_FLOAT)) { + return RFLOAT_VALUE(x) < 0.0; + } + return RTEST(rb_funcall(x, '<', 1, INT2FIX(0))); +} + +#define is_positive(x) (!is_negative(x)) + +inline static int +is_zero(VALUE x) +{ + VALUE num; + + switch (TYPE(x)) { + case T_FIXNUM: + return FIX2LONG(x) == 0; + + case T_BIGNUM: + return Qfalse; + + case T_RATIONAL: + num = rb_rational_num(x); + return FIXNUM_P(num) && FIX2LONG(num) == 0; + + default: + break; + } + + return RTEST(rb_funcall(x, id_eq, 1, INT2FIX(0))); +} + +inline static int +is_one(VALUE x) +{ + VALUE num, den; + + switch (TYPE(x)) { + case T_FIXNUM: + return FIX2LONG(x) == 1; + + case T_BIGNUM: + return Qfalse; + + case T_RATIONAL: + num = rb_rational_num(x); + den = rb_rational_den(x); + return FIXNUM_P(den) && FIX2LONG(den) == 1 && + FIXNUM_P(num) && FIX2LONG(num) == 1; + + default: + break; + } + + return RTEST(rb_funcall(x, id_eq, 1, INT2FIX(1))); +} + +inline static int +is_even(VALUE x) +{ + switch (TYPE(x)) { + case T_FIXNUM: + return (FIX2LONG(x) % 2) == 0; + + case T_BIGNUM: + { + unsigned long l; + rb_big_pack(x, &l, 1); + return l % 2 == 0; + } + + default: + break; + } + + return 0; +} + +static VALUE +bigdecimal_power_by_bigdecimal(Real const* x, Real const* exp, ssize_t const n) +{ + VALUE log_x, multiplied, y; + volatile VALUE obj = exp->obj; + + if (VpIsZero(exp)) { + return VpCheckGetValue(NewOneWrapLimited(1, n)); + } + + log_x = BigMath_log(x->obj, SSIZET2NUM(n+1)); + multiplied = BigDecimal_mult2(exp->obj, log_x, SSIZET2NUM(n+1)); + y = BigMath_exp(multiplied, SSIZET2NUM(n)); + RB_GC_GUARD(obj); + + return y; +} + +/* call-seq: + * power(n) + * power(n, prec) + * + * Returns the value raised to the power of n. + * + * Note that n must be an Integer. + * + * Also available as the operator **. + */ +static VALUE +BigDecimal_power(int argc, VALUE*argv, VALUE self) +{ + ENTER(5); + VALUE vexp, prec; + Real* exp = NULL; + Real *x, *y; + ssize_t mp, ma, n; + SIGNED_VALUE int_exp; + double d; + + rb_scan_args(argc, argv, "11", &vexp, &prec); + + GUARD_OBJ(x, GetVpValue(self, 1)); + n = NIL_P(prec) ? (ssize_t)(x->Prec*VpBaseFig()) : NUM2SSIZET(prec); + + if (VpIsNaN(x)) { + y = NewZeroWrapLimited(1, n); + VpSetNaN(y); + RB_GC_GUARD(y->obj); + return VpCheckGetValue(y); + } + + retry: + switch (TYPE(vexp)) { + case T_FIXNUM: + break; + + case T_BIGNUM: + break; + + case T_FLOAT: + d = RFLOAT_VALUE(vexp); + if (d == round(d)) { + if (FIXABLE(d)) { + vexp = LONG2FIX((long)d); + } + else { + vexp = rb_dbl2big(d); + } + goto retry; + } + if (NIL_P(prec)) { + n += BIGDECIMAL_DOUBLE_FIGURES; + } + exp = GetVpValueWithPrec(vexp, 0, 1); + break; + + case T_RATIONAL: + if (is_zero(rb_rational_num(vexp))) { + if (is_positive(vexp)) { + vexp = INT2FIX(0); + goto retry; + } + } + else if (is_one(rb_rational_den(vexp))) { + vexp = rb_rational_num(vexp); + goto retry; + } + exp = GetVpValueWithPrec(vexp, n, 1); + if (NIL_P(prec)) { + n += n; + } + break; + + case T_DATA: + if (is_kind_of_BigDecimal(vexp)) { + VALUE zero = INT2FIX(0); + VALUE rounded = BigDecimal_round(1, &zero, vexp); + if (RTEST(BigDecimal_eq(vexp, rounded))) { + vexp = BigDecimal_to_i(vexp); + goto retry; + } + if (NIL_P(prec)) { + GUARD_OBJ(y, GetVpValue(vexp, 1)); + n += y->Prec*VpBaseFig(); + } + exp = DATA_PTR(vexp); + break; + } + /* fall through */ + default: + rb_raise(rb_eTypeError, + "wrong argument type %"PRIsVALUE" (expected scalar Numeric)", + RB_OBJ_CLASSNAME(vexp)); + } + + if (VpIsZero(x)) { + if (is_negative(vexp)) { + y = NewZeroWrapNolimit(1, n); + if (BIGDECIMAL_NEGATIVE_P(x)) { + if (is_integer(vexp)) { + if (is_even(vexp)) { + /* (-0) ** (-even_integer) -> Infinity */ + VpSetPosInf(y); + } + else { + /* (-0) ** (-odd_integer) -> -Infinity */ + VpSetNegInf(y); + } + } + else { + /* (-0) ** (-non_integer) -> Infinity */ + VpSetPosInf(y); + } + } + else { + /* (+0) ** (-num) -> Infinity */ + VpSetPosInf(y); + } + RB_GC_GUARD(y->obj); + return VpCheckGetValue(y); + } + else if (is_zero(vexp)) { + return VpCheckGetValue(NewOneWrapLimited(1, n)); + } + else { + return VpCheckGetValue(NewZeroWrapLimited(1, n)); + } + } + + if (is_zero(vexp)) { + return VpCheckGetValue(NewOneWrapLimited(1, n)); + } + else if (is_one(vexp)) { + return self; + } + + if (VpIsInf(x)) { + if (is_negative(vexp)) { + if (BIGDECIMAL_NEGATIVE_P(x)) { + if (is_integer(vexp)) { + if (is_even(vexp)) { + /* (-Infinity) ** (-even_integer) -> +0 */ + return VpCheckGetValue(NewZeroWrapLimited(1, n)); + } + else { + /* (-Infinity) ** (-odd_integer) -> -0 */ + return VpCheckGetValue(NewZeroWrapLimited(-1, n)); + } + } + else { + /* (-Infinity) ** (-non_integer) -> -0 */ + return VpCheckGetValue(NewZeroWrapLimited(-1, n)); + } + } + else { + return VpCheckGetValue(NewZeroWrapLimited(1, n)); + } + } + else { + y = NewZeroWrapLimited(1, n); + if (BIGDECIMAL_NEGATIVE_P(x)) { + if (is_integer(vexp)) { + if (is_even(vexp)) { + VpSetPosInf(y); + } + else { + VpSetNegInf(y); + } + } + else { + /* TODO: support complex */ + rb_raise(rb_eMathDomainError, + "a non-integral exponent for a negative base"); + } + } + else { + VpSetPosInf(y); + } + return VpCheckGetValue(y); + } + } + + if (exp != NULL) { + return bigdecimal_power_by_bigdecimal(x, exp, n); + } + else if (RB_TYPE_P(vexp, T_BIGNUM)) { + VALUE abs_value = BigDecimal_abs(self); + if (is_one(abs_value)) { + return VpCheckGetValue(NewOneWrapLimited(1, n)); + } + else if (RTEST(rb_funcall(abs_value, '<', 1, INT2FIX(1)))) { + if (is_negative(vexp)) { + y = NewZeroWrapLimited(1, n); + VpSetInf(y, (is_even(vexp) ? 1 : -1) * VpGetSign(x)); + return VpCheckGetValue(y); + } + else if (BIGDECIMAL_NEGATIVE_P(x) && is_even(vexp)) { + return VpCheckGetValue(NewZeroWrapLimited(-1, n)); + } + else { + return VpCheckGetValue(NewZeroWrapLimited(1, n)); + } + } + else { + if (is_positive(vexp)) { + y = NewZeroWrapLimited(1, n); + VpSetInf(y, (is_even(vexp) ? 1 : -1) * VpGetSign(x)); + return VpCheckGetValue(y); + } + else if (BIGDECIMAL_NEGATIVE_P(x) && is_even(vexp)) { + return VpCheckGetValue(NewZeroWrapLimited(-1, n)); + } + else { + return VpCheckGetValue(NewZeroWrapLimited(1, n)); + } + } + } + + int_exp = FIX2LONG(vexp); + ma = int_exp; + if (ma < 0) ma = -ma; + if (ma == 0) ma = 1; + + if (VpIsDef(x)) { + mp = x->Prec * (VpBaseFig() + 1); + GUARD_OBJ(y, NewZeroWrapLimited(1, mp * (ma + 1))); + } + else { + GUARD_OBJ(y, NewZeroWrapLimited(1, 1)); + } + VpPowerByInt(y, x, int_exp); + if (!NIL_P(prec) && VpIsDef(y)) { + VpMidRound(y, VpGetRoundMode(), n); + } + return VpCheckGetValue(y); +} + +/* call-seq: + * self ** other -> bigdecimal + * + * Returns the \BigDecimal value of +self+ raised to power +other+: + * + * b = BigDecimal('3.14') + * b ** 2 # => 0.98596e1 + * b ** 2.0 # => 0.98596e1 + * b ** Rational(2, 1) # => 0.98596e1 + * + * Related: BigDecimal#power. + * + */ +static VALUE +BigDecimal_power_op(VALUE self, VALUE exp) +{ + return BigDecimal_power(1, &exp, self); +} + +/* :nodoc: + * + * private method for dup and clone the provided BigDecimal +other+ + */ +static VALUE +BigDecimal_initialize_copy(VALUE self, VALUE other) +{ + Real *pv = rb_check_typeddata(self, &BigDecimal_data_type); + Real *x = rb_check_typeddata(other, &BigDecimal_data_type); + + if (self != other) { + DATA_PTR(self) = VpCopy(pv, x); + } + return self; +} + +/* :nodoc: */ +static VALUE +BigDecimal_clone(VALUE self) +{ + return self; +} + +#ifdef HAVE_RB_OPTS_EXCEPTION_P +int rb_opts_exception_p(VALUE opts, int default_value); +#define opts_exception_p(opts) rb_opts_exception_p((opts), 1) +#else +static int +opts_exception_p(VALUE opts) +{ + static ID kwds[1]; + VALUE exception; + if (!kwds[0]) { + kwds[0] = rb_intern_const("exception"); + } + if (!rb_get_kwargs(opts, kwds, 0, 1, &exception)) return 1; + switch (exception) { + case Qtrue: case Qfalse: + break; + default: + rb_raise(rb_eArgError, "true or false is expected as exception: %+"PRIsVALUE, + exception); + } + return exception != Qfalse; +} +#endif + +static VALUE +check_exception(VALUE bd) +{ + assert(is_kind_of_BigDecimal(bd)); + + Real *vp; + TypedData_Get_Struct(bd, Real, &BigDecimal_data_type, vp); + VpCheckGetValue(vp); /* VpCheckGetValue performs exception check */ + + return bd; +} + +static VALUE +rb_uint64_convert_to_BigDecimal(uint64_t uval, RB_UNUSED_VAR(size_t digs), int raise_exception) +{ + VALUE obj = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, 0); + + Real *vp; + if (uval == 0) { + vp = rbd_allocate_struct(1); + vp->MaxPrec = 1; + vp->Prec = 1; + vp->exponent = 1; + VpSetZero(vp, 1); + vp->frac[0] = 0; + } + else if (uval < BASE) { + vp = rbd_allocate_struct(1); + vp->MaxPrec = 1; + vp->Prec = 1; + vp->exponent = 1; + VpSetSign(vp, 1); + vp->frac[0] = (DECDIG)uval; + } + else { + DECDIG buf[BIGDECIMAL_INT64_MAX_LENGTH] = {0,}; + DECDIG r = uval % BASE; + size_t len = 0, ntz = 0; + if (r == 0) { + // Count and skip trailing zeros + for (; r == 0 && uval > 0; ++ntz) { + uval /= BASE; + r = uval % BASE; + } + } + for (; uval > 0; ++len) { + // Store digits + buf[BIGDECIMAL_INT64_MAX_LENGTH - len - 1] = r; + uval /= BASE; + r = uval % BASE; + } + + const size_t exp = len + ntz; + vp = rbd_allocate_struct(len); + vp->MaxPrec = len; + vp->Prec = len; + vp->exponent = exp; + VpSetSign(vp, 1); + MEMCPY(vp->frac, buf + BIGDECIMAL_INT64_MAX_LENGTH - len, DECDIG, len); + } + + return BigDecimal_wrap_struct(obj, vp); +} + +static VALUE +rb_int64_convert_to_BigDecimal(int64_t ival, size_t digs, int raise_exception) +{ + const uint64_t uval = (ival < 0) ? (((uint64_t)-(ival+1))+1) : (uint64_t)ival; + VALUE bd = rb_uint64_convert_to_BigDecimal(uval, digs, raise_exception); + if (ival < 0) { + Real *vp; + TypedData_Get_Struct(bd, Real, &BigDecimal_data_type, vp); + VpSetSign(vp, -1); + } + return bd; +} + +static VALUE +rb_big_convert_to_BigDecimal(VALUE val, RB_UNUSED_VAR(size_t digs), int raise_exception) +{ + assert(RB_TYPE_P(val, T_BIGNUM)); + + int leading_zeros; + size_t size = rb_absint_size(val, &leading_zeros); + int sign = FIX2INT(rb_big_cmp(val, INT2FIX(0))); + if (sign < 0 && leading_zeros == 0) { + size += 1; + } + if (size <= sizeof(long)) { + if (sign < 0) { + return rb_int64_convert_to_BigDecimal(NUM2LONG(val), digs, raise_exception); + } + else { + return rb_uint64_convert_to_BigDecimal(NUM2ULONG(val), digs, raise_exception); + } + } +#if defined(SIZEOF_LONG_LONG) && SIZEOF_LONG < SIZEOF_LONG_LONG + else if (size <= sizeof(LONG_LONG)) { + if (sign < 0) { + return rb_int64_convert_to_BigDecimal(NUM2LL(val), digs, raise_exception); + } + else { + return rb_uint64_convert_to_BigDecimal(NUM2ULL(val), digs, raise_exception); + } + } +#endif + else { + VALUE str = rb_big2str(val, 10); + Real *vp = VpCreateRbObject(RSTRING_LEN(str) + BASE_FIG + 1, + RSTRING_PTR(str), true); + RB_GC_GUARD(str); + return check_exception(vp->obj); + } +} + +static VALUE +rb_inum_convert_to_BigDecimal(VALUE val, RB_UNUSED_VAR(size_t digs), int raise_exception) +{ + assert(RB_INTEGER_TYPE_P(val)); + if (FIXNUM_P(val)) { + return rb_int64_convert_to_BigDecimal(FIX2LONG(val), digs, raise_exception); + } + else { + return rb_big_convert_to_BigDecimal(val, digs, raise_exception); + } +} + +static VALUE +rb_float_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception) +{ + assert(RB_FLOAT_TYPE_P(val)); + + double d = RFLOAT_VALUE(val); + + if (isnan(d)) { + VALUE obj = BigDecimal_nan(); + return check_exception(obj); + } + else if (isinf(d)) { + VALUE obj; + if (d > 0) { + obj = BigDecimal_positive_infinity(); + } + else { + obj = BigDecimal_negative_infinity(); + } + return check_exception(obj); + } + else if (d == 0.0) { + if (1/d < 0.0) { + return BigDecimal_negative_zero(); + } + else { + return BigDecimal_positive_zero(); + } + } + + if (digs == SIZE_MAX) { + if (!raise_exception) + return Qnil; + rb_raise(rb_eArgError, + "can't omit precision for a %"PRIsVALUE".", + CLASS_OF(val)); + } + else if (digs > BIGDECIMAL_DOUBLE_FIGURES) { + if (!raise_exception) + return Qnil; + rb_raise(rb_eArgError, "precision too large."); + } + + /* Use the same logic in flo_to_s to convert a float to a decimal string */ + char buf[BIGDECIMAL_DOUBLE_FIGURES + BASE_FIG + 2 + 1]; /* sizeof(buf) == 28 in the typical case */ + int decpt, negative_p; + char *e; + const int mode = digs == 0 ? 0 : 2; + char *p = BigDecimal_dtoa(d, mode, (int)digs, &decpt, &negative_p, &e); + int len10 = (int)(e - p); + if (len10 > BIGDECIMAL_DOUBLE_FIGURES) { + /* TODO: Presumably, rounding should be done here. */ + len10 = BIGDECIMAL_DOUBLE_FIGURES; + } + memcpy(buf, p, len10); + xfree(p); + + VALUE inum; + size_t RB_UNUSED_VAR(prec) = 0; + SIGNED_VALUE exp = 0; + if (decpt > 0) { + if (decpt < len10) { + /* + * len10 |---------------| + * : |-------| frac_len10 = len10 - decpt + * decpt |-------| |--| ntz10 = BASE_FIG - frac_len10 % BASE_FIG + * : : : + * 00 dd dddd.dddd dd 00 + * prec |-----.----.----.-----| prec = exp + roomof(frac_len, BASE_FIG) + * exp |-----.----| exp = roomof(decpt, BASE_FIG) + */ + const size_t frac_len10 = len10 - decpt; + const size_t ntz10 = BASE_FIG - frac_len10 % BASE_FIG; + memset(buf + len10, '0', ntz10); + buf[len10 + ntz10] = '\0'; + inum = rb_cstr_to_inum(buf, 10, false); + + exp = roomof(decpt, BASE_FIG); + prec = exp + roomof(frac_len10, BASE_FIG); + } + else { + /* + * decpt |-----------------------| + * len10 |----------| : + * : |------------| exp10 + * : : : + * 00 dd dddd dd 00 0000 0000.0 + * : : : : + * : |--| ntz10 = exp10 % BASE_FIG + * prec |-----.----.-----| : + * : |----.----| exp10 / BASE_FIG + * exp |-----.----.-----.----.----| + */ + const size_t exp10 = decpt - len10; + const size_t ntz10 = exp10 % BASE_FIG; + + memset(buf + len10, '0', ntz10); + buf[len10 + ntz10] = '\0'; + inum = rb_cstr_to_inum(buf, 10, false); + + prec = roomof(len10 + ntz10, BASE_FIG); + exp = prec + exp10 / BASE_FIG; + } + } + else if (decpt == 0) { + /* + * len10 |------------| + * : : + * 0.dddd dddd dd 00 + * : : : + * : |--| ntz10 = prec * BASE_FIG - len10 + * prec |----.----.-----| roomof(len10, BASE_FIG) + */ + prec = roomof(len10, BASE_FIG); + const size_t ntz10 = prec * BASE_FIG - len10; + + memset(buf + len10, '0', ntz10); + buf[len10 + ntz10] = '\0'; + inum = rb_cstr_to_inum(buf, 10, false); + } + else { + /* + * len10 |---------------| + * : : + * decpt |-------| |--| ntz10 = prec * BASE_FIG - nlz10 - len10 + * : : : + * 0.0000 00 dd dddd dddd dd 00 + * : : : + * nlz10 |--| : decpt % BASE_FIG + * prec |-----.----.----.-----| roomof(decpt + len10, BASE_FIG) - exp + * exp |----| decpt / BASE_FIG + */ + decpt = -decpt; + + const size_t nlz10 = decpt % BASE_FIG; + exp = decpt / BASE_FIG; + prec = roomof(decpt + len10, BASE_FIG) - exp; + const size_t ntz10 = prec * BASE_FIG - nlz10 - len10; + + if (nlz10 > 0) { + memmove(buf + nlz10, buf, len10); + memset(buf, '0', nlz10); + } + memset(buf + nlz10 + len10, '0', ntz10); + buf[nlz10 + len10 + ntz10] = '\0'; + inum = rb_cstr_to_inum(buf, 10, false); + + exp = -exp; + } + + VALUE bd = rb_inum_convert_to_BigDecimal(inum, SIZE_MAX, raise_exception); + Real *vp; + TypedData_Get_Struct(bd, Real, &BigDecimal_data_type, vp); + assert(vp->Prec == prec); + vp->exponent = exp; + + if (negative_p) VpSetSign(vp, -1); + return bd; +} + +static VALUE +rb_rational_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception) +{ + assert(RB_TYPE_P(val, T_RATIONAL)); + + if (digs == SIZE_MAX) { + if (!raise_exception) + return Qnil; + rb_raise(rb_eArgError, + "can't omit precision for a %"PRIsVALUE".", + CLASS_OF(val)); + } + + VALUE num = rb_inum_convert_to_BigDecimal(rb_rational_num(val), 0, raise_exception); + VALUE d = BigDecimal_div2(num, rb_rational_den(val), SIZET2NUM(digs)); + return d; +} + +static VALUE +rb_cstr_convert_to_BigDecimal(const char *c_str, size_t digs, int raise_exception) +{ + if (digs == SIZE_MAX) + digs = 0; + + Real *vp = VpCreateRbObject(digs, c_str, raise_exception); + if (!vp) + return Qnil; + return VpCheckGetValue(vp); +} + +static inline VALUE +rb_str_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception) +{ + const char *c_str = StringValueCStr(val); + return rb_cstr_convert_to_BigDecimal(c_str, digs, raise_exception); +} + +static VALUE +rb_convert_to_BigDecimal(VALUE val, size_t digs, int raise_exception) +{ + switch (val) { + case Qnil: + case Qtrue: + case Qfalse: + if (raise_exception) { + const char *cname = NIL_P(val) ? "nil" : + val == Qtrue ? "true" : + val == Qfalse ? "false" : + NULL; + rb_raise(rb_eTypeError, + "can't convert %s into BigDecimal", cname); + } + return Qnil; + + default: + break; + } + + if (is_kind_of_BigDecimal(val)) { + if (digs == SIZE_MAX) + return check_exception(val); + + Real *vp; + TypedData_Get_Struct(val, Real, &BigDecimal_data_type, vp); + + VALUE copy = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, 0); + vp = VpCopy(NULL, vp); + /* TODO: rounding */ + BigDecimal_wrap_struct(copy, vp); + return VpCheckGetValue(vp); + } + else if (RB_INTEGER_TYPE_P(val)) { + return rb_inum_convert_to_BigDecimal(val, digs, raise_exception); + } + else if (RB_FLOAT_TYPE_P(val)) { + return rb_float_convert_to_BigDecimal(val, digs, raise_exception); + } + else if (RB_TYPE_P(val, T_RATIONAL)) { + return rb_rational_convert_to_BigDecimal(val, digs, raise_exception); + } + else if (RB_TYPE_P(val, T_COMPLEX)) { + VALUE im = rb_complex_imag(val); + if (!is_zero(im)) { + /* TODO: handle raise_exception */ + rb_raise(rb_eArgError, + "Unable to make a BigDecimal from non-zero imaginary number"); + } + return rb_convert_to_BigDecimal(rb_complex_real(val), digs, raise_exception); + } + else if (RB_TYPE_P(val, T_STRING)) { + return rb_str_convert_to_BigDecimal(val, digs, raise_exception); + } + + /* TODO: chheck to_d */ + /* TODO: chheck to_int */ + + VALUE str = rb_check_convert_type(val, T_STRING, "String", "to_str"); + if (!RB_TYPE_P(str, T_STRING)) { + if (raise_exception) { + rb_raise(rb_eTypeError, + "can't convert %"PRIsVALUE" into BigDecimal", rb_obj_class(val)); + } + return Qnil; + } + return rb_str_convert_to_BigDecimal(str, digs, raise_exception); +} + +/* call-seq: + * BigDecimal(value, exception: true) -> bigdecimal + * BigDecimal(value, ndigits, exception: true) -> bigdecimal + * + * Returns the \BigDecimal converted from +value+ + * with a precision of +ndigits+ decimal digits. + * + * When +ndigits+ is less than the number of significant digits + * in the value, the result is rounded to that number of digits, + * according to the current rounding mode; see BigDecimal.mode. + * + * When +ndigits+ is 0, the number of digits to correctly represent a float number + * is determined automatically. + * + * Returns +value+ converted to a \BigDecimal, depending on the type of +value+: + * + * - Integer, Float, Rational, Complex, or BigDecimal: converted directly: + * + * # Integer, Complex, or BigDecimal value does not require ndigits; ignored if given. + * BigDecimal(2) # => 0.2e1 + * BigDecimal(Complex(2, 0)) # => 0.2e1 + * BigDecimal(BigDecimal(2)) # => 0.2e1 + * # Float or Rational value requires ndigits. + * BigDecimal(2.0, 0) # => 0.2e1 + * BigDecimal(Rational(2, 1), 0) # => 0.2e1 + * + * - String: converted by parsing if it contains an integer or floating-point literal; + * leading and trailing whitespace is ignored: + * + * # String does not require ndigits; ignored if given. + * BigDecimal('2') # => 0.2e1 + * BigDecimal('2.0') # => 0.2e1 + * BigDecimal('0.2e1') # => 0.2e1 + * BigDecimal(' 2.0 ') # => 0.2e1 + * + * - Other type that responds to method :to_str: + * first converted to a string, then converted to a \BigDecimal, as above. + * + * - Other type: + * + * - Raises an exception if keyword argument +exception+ is +true+. + * - Returns +nil+ if keyword argument +exception+ is +false+. + * + * Raises an exception if +value+ evaluates to a Float + * and +digits+ is larger than Float::DIG + 1. + * + */ +static VALUE +f_BigDecimal(int argc, VALUE *argv, VALUE self) +{ + VALUE val, digs_v, opts = Qnil; + argc = rb_scan_args(argc, argv, "11:", &val, &digs_v, &opts); + int exception = opts_exception_p(opts); + + size_t digs = SIZE_MAX; /* this means digs is omitted */ + if (argc > 1) { + digs_v = rb_to_int(digs_v); + if (FIXNUM_P(digs_v)) { + long n = FIX2LONG(digs_v); + if (n < 0) + goto negative_digs; + digs = (size_t)n; + } + else { + if (RBIGNUM_NEGATIVE_P(digs_v)) { + negative_digs: + if (!exception) + return Qnil; + rb_raise(rb_eArgError, "negative precision"); + } + digs = NUM2SIZET(digs_v); + } + } + + return rb_convert_to_BigDecimal(val, digs, exception); +} + +/* call-seq: + * BigDecimal.interpret_loosely(string) -> bigdecimal + * + * Returns the +BigDecimal+ converted loosely from +string+. + */ + +static VALUE +BigDecimal_s_interpret_loosely(VALUE klass, VALUE str) +{ + char const *c_str = StringValueCStr(str); + Real *vp = VpNewRbClass(0, c_str, klass, false, true); + if (!vp) + return Qnil; + else + return VpCheckGetValue(vp); +} + + /* + * call-seq: + * BigDecimal.limit(digits) + * + * Limit the number of significant digits in newly created BigDecimal + * numbers to the specified value. Rounding is performed as necessary, + * as specified by BigDecimal.mode. + * + * A limit of 0, the default, means no upper limit. + * + * The limit specified by this method takes less priority over any limit + * specified to instance methods such as ceil, floor, truncate, or round. + */ +static VALUE +BigDecimal_limit(int argc, VALUE *argv, VALUE self) +{ + VALUE nFig; + VALUE nCur = SIZET2NUM(VpGetPrecLimit()); + + if (rb_scan_args(argc, argv, "01", &nFig) == 1) { + int nf; + if (NIL_P(nFig)) return nCur; + nf = NUM2INT(nFig); + if (nf < 0) { + rb_raise(rb_eArgError, "argument must be positive"); + } + VpSetPrecLimit(nf); + } + return nCur; +} + +/* Returns the sign of the value. + * + * Returns a positive value if > 0, a negative value if < 0. + * It behaves the same with zeros - + * it returns a positive value for a positive zero (BigDecimal('0')) and + * a negative value for a negative zero (BigDecimal('-0')). + * + * The specific value returned indicates the type and sign of the BigDecimal, + * as follows: + * + * BigDecimal::SIGN_NaN:: value is Not a Number + * BigDecimal::SIGN_POSITIVE_ZERO:: value is +0 + * BigDecimal::SIGN_NEGATIVE_ZERO:: value is -0 + * BigDecimal::SIGN_POSITIVE_INFINITE:: value is +Infinity + * BigDecimal::SIGN_NEGATIVE_INFINITE:: value is -Infinity + * BigDecimal::SIGN_POSITIVE_FINITE:: value is positive + * BigDecimal::SIGN_NEGATIVE_FINITE:: value is negative + */ +static VALUE +BigDecimal_sign(VALUE self) +{ /* sign */ + int s = GetVpValue(self, 1)->sign; + return INT2FIX(s); +} + +/* + * call-seq: BigDecimal.save_exception_mode { ... } + * + * Execute the provided block, but preserve the exception mode + * + * BigDecimal.save_exception_mode do + * BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false) + * BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false) + * + * BigDecimal(BigDecimal('Infinity')) + * BigDecimal(BigDecimal('-Infinity')) + * BigDecimal(BigDecimal('NaN')) + * end + * + * For use with the BigDecimal::EXCEPTION_* + * + * See BigDecimal.mode + */ +static VALUE +BigDecimal_save_exception_mode(VALUE self) +{ + unsigned short const exception_mode = VpGetException(); + int state; + VALUE ret = rb_protect(rb_yield, Qnil, &state); + VpSetException(exception_mode); + if (state) rb_jump_tag(state); + return ret; +} + +/* + * call-seq: BigDecimal.save_rounding_mode { ... } + * + * Execute the provided block, but preserve the rounding mode + * + * BigDecimal.save_rounding_mode do + * BigDecimal.mode(BigDecimal::ROUND_MODE, :up) + * puts BigDecimal.mode(BigDecimal::ROUND_MODE) + * end + * + * For use with the BigDecimal::ROUND_* + * + * See BigDecimal.mode + */ +static VALUE +BigDecimal_save_rounding_mode(VALUE self) +{ + unsigned short const round_mode = VpGetRoundMode(); + int state; + VALUE ret = rb_protect(rb_yield, Qnil, &state); + VpSetRoundMode(round_mode); + if (state) rb_jump_tag(state); + return ret; +} + +/* + * call-seq: BigDecimal.save_limit { ... } + * + * Execute the provided block, but preserve the precision limit + * + * BigDecimal.limit(100) + * puts BigDecimal.limit + * BigDecimal.save_limit do + * BigDecimal.limit(200) + * puts BigDecimal.limit + * end + * puts BigDecimal.limit + * + */ +static VALUE +BigDecimal_save_limit(VALUE self) +{ + size_t const limit = VpGetPrecLimit(); + int state; + VALUE ret = rb_protect(rb_yield, Qnil, &state); + VpSetPrecLimit(limit); + if (state) rb_jump_tag(state); + return ret; +} + +/* call-seq: + * BigMath.exp(decimal, numeric) -> BigDecimal + * + * Computes the value of e (the base of natural logarithms) raised to the + * power of +decimal+, to the specified number of digits of precision. + * + * If +decimal+ is infinity, returns Infinity. + * + * If +decimal+ is NaN, returns NaN. + */ +static VALUE +BigMath_s_exp(VALUE klass, VALUE x, VALUE vprec) +{ + ssize_t prec, n, i; + Real* vx = NULL; + VALUE one, d, y; + int negative = 0; + int infinite = 0; + int nan = 0; + double flo; + + prec = NUM2SSIZET(vprec); + if (prec <= 0) { + rb_raise(rb_eArgError, "Zero or negative precision for exp"); + } + + /* TODO: the following switch statement is almost same as one in the + * BigDecimalCmp function. */ + switch (TYPE(x)) { + case T_DATA: + if (!is_kind_of_BigDecimal(x)) break; + vx = DATA_PTR(x); + negative = BIGDECIMAL_NEGATIVE_P(vx); + infinite = VpIsPosInf(vx) || VpIsNegInf(vx); + nan = VpIsNaN(vx); + break; + + case T_FIXNUM: + /* fall through */ + case T_BIGNUM: + vx = GetVpValue(x, 0); + break; + + case T_FLOAT: + flo = RFLOAT_VALUE(x); + negative = flo < 0; + infinite = isinf(flo); + nan = isnan(flo); + if (!infinite && !nan) { + vx = GetVpValueWithPrec(x, 0, 0); + } + break; + + case T_RATIONAL: + vx = GetVpValueWithPrec(x, prec, 0); + break; + + default: + break; + } + if (infinite) { + if (negative) { + return VpCheckGetValue(GetVpValueWithPrec(INT2FIX(0), prec, 1)); + } + else { + Real* vy = NewZeroWrapNolimit(1, prec); + VpSetInf(vy, VP_SIGN_POSITIVE_INFINITE); + RB_GC_GUARD(vy->obj); + return VpCheckGetValue(vy); + } + } + else if (nan) { + Real* vy = NewZeroWrapNolimit(1, prec); + VpSetNaN(vy); + RB_GC_GUARD(vy->obj); + return VpCheckGetValue(vy); + } + else if (vx == NULL) { + cannot_be_coerced_into_BigDecimal(rb_eArgError, x); + } + x = vx->obj; + + n = prec + BIGDECIMAL_DOUBLE_FIGURES; + negative = BIGDECIMAL_NEGATIVE_P(vx); + if (negative) { + VALUE x_zero = INT2NUM(1); + VALUE x_copy = f_BigDecimal(1, &x_zero, klass); + x = BigDecimal_initialize_copy(x_copy, x); + vx = DATA_PTR(x); + VpSetSign(vx, 1); + } + + one = VpCheckGetValue(NewOneWrapLimited(1, 1)); + y = one; + d = y; + i = 1; + + while (!VpIsZero((Real*)DATA_PTR(d))) { + SIGNED_VALUE const ey = VpExponent10(DATA_PTR(y)); + SIGNED_VALUE const ed = VpExponent10(DATA_PTR(d)); + ssize_t m = n - vabs(ey - ed); + + rb_thread_check_ints(); + + if (m <= 0) { + break; + } + else if ((size_t)m < BIGDECIMAL_DOUBLE_FIGURES) { + m = BIGDECIMAL_DOUBLE_FIGURES; + } + + d = BigDecimal_mult(d, x); /* d <- d * x */ + d = BigDecimal_div2(d, SSIZET2NUM(i), SSIZET2NUM(m)); /* d <- d / i */ + y = BigDecimal_add(y, d); /* y <- y + d */ + ++i; /* i <- i + 1 */ + } + + if (negative) { + return BigDecimal_div2(one, y, vprec); + } + else { + vprec = SSIZET2NUM(prec - VpExponent10(DATA_PTR(y))); + return BigDecimal_round(1, &vprec, y); + } + + RB_GC_GUARD(one); + RB_GC_GUARD(x); + RB_GC_GUARD(y); + RB_GC_GUARD(d); +} + +/* call-seq: + * BigMath.log(decimal, numeric) -> BigDecimal + * + * Computes the natural logarithm of +decimal+ to the specified number of + * digits of precision, +numeric+. + * + * If +decimal+ is zero or negative, raises Math::DomainError. + * + * If +decimal+ is positive infinity, returns Infinity. + * + * If +decimal+ is NaN, returns NaN. + */ +static VALUE +BigMath_s_log(VALUE klass, VALUE x, VALUE vprec) +{ + ssize_t prec, n, i; + SIGNED_VALUE expo; + Real* vx = NULL; + VALUE vn, one, two, w, x2, y, d; + int zero = 0; + int negative = 0; + int infinite = 0; + int nan = 0; + double flo; + long fix; + + if (!is_integer(vprec)) { + rb_raise(rb_eArgError, "precision must be an Integer"); + } + + prec = NUM2SSIZET(vprec); + if (prec <= 0) { + rb_raise(rb_eArgError, "Zero or negative precision for exp"); + } + + /* TODO: the following switch statement is almost same as one in the + * BigDecimalCmp function. */ + switch (TYPE(x)) { + case T_DATA: + if (!is_kind_of_BigDecimal(x)) break; + vx = DATA_PTR(x); + zero = VpIsZero(vx); + negative = BIGDECIMAL_NEGATIVE_P(vx); + infinite = VpIsPosInf(vx) || VpIsNegInf(vx); + nan = VpIsNaN(vx); + break; + + case T_FIXNUM: + fix = FIX2LONG(x); + zero = fix == 0; + negative = fix < 0; + goto get_vp_value; + + case T_BIGNUM: + i = FIX2INT(rb_big_cmp(x, INT2FIX(0))); + zero = i == 0; + negative = i < 0; +get_vp_value: + if (zero || negative) break; + vx = GetVpValue(x, 0); + break; + + case T_FLOAT: + flo = RFLOAT_VALUE(x); + zero = flo == 0; + negative = flo < 0; + infinite = isinf(flo); + nan = isnan(flo); + if (!zero && !negative && !infinite && !nan) { + vx = GetVpValueWithPrec(x, 0, 1); + } + break; + + case T_RATIONAL: + zero = RRATIONAL_ZERO_P(x); + negative = RRATIONAL_NEGATIVE_P(x); + if (zero || negative) break; + vx = GetVpValueWithPrec(x, prec, 1); + break; + + case T_COMPLEX: + rb_raise(rb_eMathDomainError, + "Complex argument for BigMath.log"); + + default: + break; + } + if (infinite && !negative) { + Real *vy = NewZeroWrapNolimit(1, prec); + RB_GC_GUARD(vy->obj); + VpSetInf(vy, VP_SIGN_POSITIVE_INFINITE); + return VpCheckGetValue(vy); + } + else if (nan) { + Real* vy = NewZeroWrapNolimit(1, prec); + RB_GC_GUARD(vy->obj); + VpSetNaN(vy); + return VpCheckGetValue(vy); + } + else if (zero || negative) { + rb_raise(rb_eMathDomainError, + "Zero or negative argument for log"); + } + else if (vx == NULL) { + cannot_be_coerced_into_BigDecimal(rb_eArgError, x); + } + x = VpCheckGetValue(vx); + + one = VpCheckGetValue(NewOneWrapLimited(1, 1)); + two = VpCheckGetValue(VpCreateRbObject(1, "2", true)); + + n = prec + BIGDECIMAL_DOUBLE_FIGURES; + vn = SSIZET2NUM(n); + expo = VpExponent10(vx); + if (expo < 0 || expo >= 3) { + char buf[DECIMAL_SIZE_OF_BITS(SIZEOF_VALUE * CHAR_BIT) + 4]; + snprintf(buf, sizeof(buf), "1E%"PRIdVALUE, -expo); + x = BigDecimal_mult2(x, VpCheckGetValue(VpCreateRbObject(1, buf, true)), vn); + } + else { + expo = 0; + } + w = BigDecimal_sub(x, one); + x = BigDecimal_div2(w, BigDecimal_add(x, one), vn); + x2 = BigDecimal_mult2(x, x, vn); + y = x; + d = y; + i = 1; + while (!VpIsZero((Real*)DATA_PTR(d))) { + SIGNED_VALUE const ey = VpExponent10(DATA_PTR(y)); + SIGNED_VALUE const ed = VpExponent10(DATA_PTR(d)); + ssize_t m = n - vabs(ey - ed); + if (m <= 0) { + break; + } + else if ((size_t)m < BIGDECIMAL_DOUBLE_FIGURES) { + m = BIGDECIMAL_DOUBLE_FIGURES; + } + + x = BigDecimal_mult2(x2, x, vn); + i += 2; + d = BigDecimal_div2(x, SSIZET2NUM(i), SSIZET2NUM(m)); + y = BigDecimal_add(y, d); + } + + y = BigDecimal_mult(y, two); + if (expo != 0) { + VALUE log10, vexpo, dy; + log10 = BigMath_s_log(klass, INT2FIX(10), vprec); + vexpo = VpCheckGetValue(GetVpValue(SSIZET2NUM(expo), 1)); + dy = BigDecimal_mult(log10, vexpo); + y = BigDecimal_add(y, dy); + } + + RB_GC_GUARD(one); + RB_GC_GUARD(two); + RB_GC_GUARD(vn); + RB_GC_GUARD(x2); + RB_GC_GUARD(y); + RB_GC_GUARD(d); + + return y; +} + +static VALUE BIGDECIMAL_NAN = Qnil; + +static VALUE +BigDecimal_nan(void) +{ + return BIGDECIMAL_NAN; +} + +static VALUE BIGDECIMAL_POSITIVE_INFINITY = Qnil; + +static VALUE +BigDecimal_positive_infinity(void) +{ + return BIGDECIMAL_POSITIVE_INFINITY; +} + +static VALUE BIGDECIMAL_NEGATIVE_INFINITY = Qnil; + +static VALUE +BigDecimal_negative_infinity(void) +{ + return BIGDECIMAL_NEGATIVE_INFINITY; +} + +static VALUE BIGDECIMAL_POSITIVE_ZERO = Qnil; + +static VALUE +BigDecimal_positive_zero(void) +{ + return BIGDECIMAL_POSITIVE_ZERO; +} + +static VALUE BIGDECIMAL_NEGATIVE_ZERO = Qnil; + +static VALUE +BigDecimal_negative_zero(void) +{ + return BIGDECIMAL_NEGATIVE_ZERO; +} + +static inline VALUE +BigDecimal_literal(const char *str) +{ + VALUE arg = rb_str_new_cstr(str); + VALUE val = f_BigDecimal(1, &arg, rb_cBigDecimal); + rb_gc_register_mark_object(val); + return val; +} + +#define BIGDECIMAL_LITERAL(var, val) (BIGDECIMAL_ ## var = BigDecimal_literal(#val)) + +/* Document-class: BigDecimal + * BigDecimal provides arbitrary-precision floating point decimal arithmetic. + * + * == Introduction + * + * Ruby provides built-in support for arbitrary precision integer arithmetic. + * + * For example: + * + * 42**13 #=> 1265437718438866624512 + * + * BigDecimal provides similar support for very large or very accurate floating + * point numbers. + * + * Decimal arithmetic is also useful for general calculation, because it + * provides the correct answers people expect--whereas normal binary floating + * point arithmetic often introduces subtle errors because of the conversion + * between base 10 and base 2. + * + * For example, try: + * + * sum = 0 + * 10_000.times do + * sum = sum + 0.0001 + * end + * print sum #=> 0.9999999999999062 + * + * and contrast with the output from: + * + * require 'bigdecimal' + * + * sum = BigDecimal("0") + * 10_000.times do + * sum = sum + BigDecimal("0.0001") + * end + * print sum #=> 0.1E1 + * + * Similarly: + * + * (BigDecimal("1.2") - BigDecimal("1.0")) == BigDecimal("0.2") #=> true + * + * (1.2 - 1.0) == 0.2 #=> false + * + * == A Note About Precision + * + * For a calculation using a \BigDecimal and another +value+, + * the precision of the result depends on the type of +value+: + * + * - If +value+ is a \Float, + * the precision is Float::DIG + 1. + * - If +value+ is a \Rational, the precision is larger than Float::DIG + 1. + * - If +value+ is a \BigDecimal, the precision is +value+'s precision in the + * internal representation, which is platform-dependent. + * - If +value+ is other object, the precision is determined by the result of +BigDecimal(value)+. + * + * == Special features of accurate decimal arithmetic + * + * Because BigDecimal is more accurate than normal binary floating point + * arithmetic, it requires some special values. + * + * === Infinity + * + * BigDecimal sometimes needs to return infinity, for example if you divide + * a value by zero. + * + * BigDecimal("1.0") / BigDecimal("0.0") #=> Infinity + * BigDecimal("-1.0") / BigDecimal("0.0") #=> -Infinity + * + * You can represent infinite numbers to BigDecimal using the strings + * 'Infinity', '+Infinity' and + * '-Infinity' (case-sensitive) + * + * === Not a Number + * + * When a computation results in an undefined value, the special value +NaN+ + * (for 'not a number') is returned. + * + * Example: + * + * BigDecimal("0.0") / BigDecimal("0.0") #=> NaN + * + * You can also create undefined values. + * + * NaN is never considered to be the same as any other value, even NaN itself: + * + * n = BigDecimal('NaN') + * n == 0.0 #=> false + * n == n #=> false + * + * === Positive and negative zero + * + * If a computation results in a value which is too small to be represented as + * a BigDecimal within the currently specified limits of precision, zero must + * be returned. + * + * If the value which is too small to be represented is negative, a BigDecimal + * value of negative zero is returned. + * + * BigDecimal("1.0") / BigDecimal("-Infinity") #=> -0.0 + * + * If the value is positive, a value of positive zero is returned. + * + * BigDecimal("1.0") / BigDecimal("Infinity") #=> 0.0 + * + * (See BigDecimal.mode for how to specify limits of precision.) + * + * Note that +-0.0+ and +0.0+ are considered to be the same for the purposes of + * comparison. + * + * Note also that in mathematics, there is no particular concept of negative + * or positive zero; true mathematical zero has no sign. + * + * == bigdecimal/util + * + * When you require +bigdecimal/util+, the #to_d method will be + * available on BigDecimal and the native Integer, Float, Rational, + * and String classes: + * + * require 'bigdecimal/util' + * + * 42.to_d # => 0.42e2 + * 0.5.to_d # => 0.5e0 + * (2/3r).to_d(3) # => 0.667e0 + * "0.5".to_d # => 0.5e0 + * + * == Methods for Working with \JSON + * + * - {::json_create}[https://docs.ruby-lang.org/en/master/BigDecimal.html#method-c-json_create]: + * Returns a new \BigDecimal object constructed from the given object. + * - {#as_json}[https://docs.ruby-lang.org/en/master/BigDecimal.html#method-i-as_json]: + * Returns a 2-element hash representing +self+. + * - {#to_json}[https://docs.ruby-lang.org/en/master/BigDecimal.html#method-i-to_json]: + * Returns a \JSON string representing +self+. + * + * These methods are provided by the {JSON gem}[https://github.com/flori/json]. To make these methods available: + * + * require 'json/add/bigdecimal' + * + * * == License + * + * Copyright (C) 2002 by Shigeo Kobayashi . + * + * BigDecimal is released under the Ruby and 2-clause BSD licenses. + * See LICENSE.txt for details. + * + * Maintained by mrkn and ruby-core members. + * + * Documented by zzak , mathew , and + * many other contributors. + */ +void +Init_bigdecimal(void) +{ +#ifdef HAVE_RB_EXT_RACTOR_SAFE + rb_ext_ractor_safe(true); +#endif + + id_BigDecimal_exception_mode = rb_intern_const("BigDecimal.exception_mode"); + id_BigDecimal_rounding_mode = rb_intern_const("BigDecimal.rounding_mode"); + id_BigDecimal_precision_limit = rb_intern_const("BigDecimal.precision_limit"); + + /* Initialize VP routines */ + VpInit(0UL); + + /* Class and method registration */ + rb_cBigDecimal = rb_define_class("BigDecimal", rb_cNumeric); + + /* Global function */ + rb_define_global_function("BigDecimal", f_BigDecimal, -1); + + /* Class methods */ + rb_undef_alloc_func(rb_cBigDecimal); + rb_undef_method(CLASS_OF(rb_cBigDecimal), "new"); + rb_define_singleton_method(rb_cBigDecimal, "interpret_loosely", BigDecimal_s_interpret_loosely, 1); + rb_define_singleton_method(rb_cBigDecimal, "mode", BigDecimal_mode, -1); + rb_define_singleton_method(rb_cBigDecimal, "limit", BigDecimal_limit, -1); + rb_define_singleton_method(rb_cBigDecimal, "double_fig", BigDecimal_double_fig, 0); + rb_define_singleton_method(rb_cBigDecimal, "_load", BigDecimal_load, 1); + + rb_define_singleton_method(rb_cBigDecimal, "save_exception_mode", BigDecimal_save_exception_mode, 0); + rb_define_singleton_method(rb_cBigDecimal, "save_rounding_mode", BigDecimal_save_rounding_mode, 0); + rb_define_singleton_method(rb_cBigDecimal, "save_limit", BigDecimal_save_limit, 0); + + /* Constants definition */ + + /* + * The version of bigdecimal library + */ + rb_define_const(rb_cBigDecimal, "VERSION", rb_str_new2(BIGDECIMAL_VERSION)); + + /* + * Base value used in internal calculations. On a 32 bit system, BASE + * is 10000, indicating that calculation is done in groups of 4 digits. + * (If it were larger, BASE**2 wouldn't fit in 32 bits, so you couldn't + * guarantee that two groups could always be multiplied together without + * overflow.) + */ + rb_define_const(rb_cBigDecimal, "BASE", INT2FIX((SIGNED_VALUE)VpBaseVal())); + + /* Exceptions */ + + /* + * 0xff: Determines whether overflow, underflow or zero divide result in + * an exception being thrown. See BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "EXCEPTION_ALL", INT2FIX(VP_EXCEPTION_ALL)); + + /* + * 0x02: Determines what happens when the result of a computation is not a + * number (NaN). See BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "EXCEPTION_NaN", INT2FIX(VP_EXCEPTION_NaN)); + + /* + * 0x01: Determines what happens when the result of a computation is + * infinity. See BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "EXCEPTION_INFINITY", INT2FIX(VP_EXCEPTION_INFINITY)); + + /* + * 0x04: Determines what happens when the result of a computation is an + * underflow (a result too small to be represented). See BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "EXCEPTION_UNDERFLOW", INT2FIX(VP_EXCEPTION_UNDERFLOW)); + + /* + * 0x01: Determines what happens when the result of a computation is an + * overflow (a result too large to be represented). See BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "EXCEPTION_OVERFLOW", INT2FIX(VP_EXCEPTION_OVERFLOW)); + + /* + * 0x10: Determines what happens when a division by zero is performed. + * See BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "EXCEPTION_ZERODIVIDE", INT2FIX(VP_EXCEPTION_ZERODIVIDE)); + + /* + * 0x100: Determines what happens when a result must be rounded in order to + * fit in the appropriate number of significant digits. See + * BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "ROUND_MODE", INT2FIX(VP_ROUND_MODE)); + + /* 1: Indicates that values should be rounded away from zero. See + * BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "ROUND_UP", INT2FIX(VP_ROUND_UP)); + + /* 2: Indicates that values should be rounded towards zero. See + * BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "ROUND_DOWN", INT2FIX(VP_ROUND_DOWN)); + + /* 3: Indicates that digits >= 5 should be rounded up, others rounded down. + * See BigDecimal.mode. */ + rb_define_const(rb_cBigDecimal, "ROUND_HALF_UP", INT2FIX(VP_ROUND_HALF_UP)); + + /* 4: Indicates that digits >= 6 should be rounded up, others rounded down. + * See BigDecimal.mode. + */ + rb_define_const(rb_cBigDecimal, "ROUND_HALF_DOWN", INT2FIX(VP_ROUND_HALF_DOWN)); + /* 5: Round towards +Infinity. See BigDecimal.mode. */ + rb_define_const(rb_cBigDecimal, "ROUND_CEILING", INT2FIX(VP_ROUND_CEIL)); + + /* 6: Round towards -Infinity. See BigDecimal.mode. */ + rb_define_const(rb_cBigDecimal, "ROUND_FLOOR", INT2FIX(VP_ROUND_FLOOR)); + + /* 7: Round towards the even neighbor. See BigDecimal.mode. */ + rb_define_const(rb_cBigDecimal, "ROUND_HALF_EVEN", INT2FIX(VP_ROUND_HALF_EVEN)); + + /* 0: Indicates that a value is not a number. See BigDecimal.sign. */ + rb_define_const(rb_cBigDecimal, "SIGN_NaN", INT2FIX(VP_SIGN_NaN)); + + /* 1: Indicates that a value is +0. See BigDecimal.sign. */ + rb_define_const(rb_cBigDecimal, "SIGN_POSITIVE_ZERO", INT2FIX(VP_SIGN_POSITIVE_ZERO)); + + /* -1: Indicates that a value is -0. See BigDecimal.sign. */ + rb_define_const(rb_cBigDecimal, "SIGN_NEGATIVE_ZERO", INT2FIX(VP_SIGN_NEGATIVE_ZERO)); + + /* 2: Indicates that a value is positive and finite. See BigDecimal.sign. */ + rb_define_const(rb_cBigDecimal, "SIGN_POSITIVE_FINITE", INT2FIX(VP_SIGN_POSITIVE_FINITE)); + + /* -2: Indicates that a value is negative and finite. See BigDecimal.sign. */ + rb_define_const(rb_cBigDecimal, "SIGN_NEGATIVE_FINITE", INT2FIX(VP_SIGN_NEGATIVE_FINITE)); + + /* 3: Indicates that a value is positive and infinite. See BigDecimal.sign. */ + rb_define_const(rb_cBigDecimal, "SIGN_POSITIVE_INFINITE", INT2FIX(VP_SIGN_POSITIVE_INFINITE)); + + /* -3: Indicates that a value is negative and infinite. See BigDecimal.sign. */ + rb_define_const(rb_cBigDecimal, "SIGN_NEGATIVE_INFINITE", INT2FIX(VP_SIGN_NEGATIVE_INFINITE)); + + /* Positive zero value. */ + BIGDECIMAL_LITERAL(POSITIVE_ZERO, +0); + + /* Negative zero value. */ + BIGDECIMAL_LITERAL(NEGATIVE_ZERO, -0); + + /* Positive infinity[rdoc-ref:BigDecimal@Infinity] value. */ + rb_define_const(rb_cBigDecimal, "INFINITY", BIGDECIMAL_LITERAL(POSITIVE_INFINITY, +Infinity)); + + /* Negative infinity value. */ + BIGDECIMAL_LITERAL(NEGATIVE_INFINITY, -Infinity); + + /* '{Not a Number}[rdoc-ref:BigDecimal@Not+a+Number]' value. */ + rb_define_const(rb_cBigDecimal, "NAN", BIGDECIMAL_LITERAL(NAN, NaN)); + + /* instance methods */ + rb_define_method(rb_cBigDecimal, "precs", BigDecimal_prec, 0); + rb_define_method(rb_cBigDecimal, "precision", BigDecimal_precision, 0); + rb_define_method(rb_cBigDecimal, "scale", BigDecimal_scale, 0); + rb_define_method(rb_cBigDecimal, "precision_scale", BigDecimal_precision_scale, 0); + rb_define_method(rb_cBigDecimal, "n_significant_digits", BigDecimal_n_significant_digits, 0); + + rb_define_method(rb_cBigDecimal, "add", BigDecimal_add2, 2); + rb_define_method(rb_cBigDecimal, "sub", BigDecimal_sub2, 2); + rb_define_method(rb_cBigDecimal, "mult", BigDecimal_mult2, 2); + rb_define_method(rb_cBigDecimal, "div", BigDecimal_div3, -1); + rb_define_method(rb_cBigDecimal, "hash", BigDecimal_hash, 0); + rb_define_method(rb_cBigDecimal, "to_s", BigDecimal_to_s, -1); + rb_define_method(rb_cBigDecimal, "to_i", BigDecimal_to_i, 0); + rb_define_method(rb_cBigDecimal, "to_int", BigDecimal_to_i, 0); + rb_define_method(rb_cBigDecimal, "to_r", BigDecimal_to_r, 0); + rb_define_method(rb_cBigDecimal, "split", BigDecimal_split, 0); + rb_define_method(rb_cBigDecimal, "+", BigDecimal_add, 1); + rb_define_method(rb_cBigDecimal, "-", BigDecimal_sub, 1); + rb_define_method(rb_cBigDecimal, "+@", BigDecimal_uplus, 0); + rb_define_method(rb_cBigDecimal, "-@", BigDecimal_neg, 0); + rb_define_method(rb_cBigDecimal, "*", BigDecimal_mult, 1); + rb_define_method(rb_cBigDecimal, "/", BigDecimal_div, 1); + rb_define_method(rb_cBigDecimal, "quo", BigDecimal_quo, -1); + rb_define_method(rb_cBigDecimal, "%", BigDecimal_mod, 1); + rb_define_method(rb_cBigDecimal, "modulo", BigDecimal_mod, 1); + rb_define_method(rb_cBigDecimal, "remainder", BigDecimal_remainder, 1); + rb_define_method(rb_cBigDecimal, "divmod", BigDecimal_divmod, 1); + rb_define_method(rb_cBigDecimal, "clone", BigDecimal_clone, 0); + rb_define_method(rb_cBigDecimal, "dup", BigDecimal_clone, 0); + rb_define_method(rb_cBigDecimal, "to_f", BigDecimal_to_f, 0); + rb_define_method(rb_cBigDecimal, "abs", BigDecimal_abs, 0); + rb_define_method(rb_cBigDecimal, "sqrt", BigDecimal_sqrt, 1); + rb_define_method(rb_cBigDecimal, "fix", BigDecimal_fix, 0); + rb_define_method(rb_cBigDecimal, "round", BigDecimal_round, -1); + rb_define_method(rb_cBigDecimal, "frac", BigDecimal_frac, 0); + rb_define_method(rb_cBigDecimal, "floor", BigDecimal_floor, -1); + rb_define_method(rb_cBigDecimal, "ceil", BigDecimal_ceil, -1); + rb_define_method(rb_cBigDecimal, "power", BigDecimal_power, -1); + rb_define_method(rb_cBigDecimal, "**", BigDecimal_power_op, 1); + rb_define_method(rb_cBigDecimal, "<=>", BigDecimal_comp, 1); + rb_define_method(rb_cBigDecimal, "==", BigDecimal_eq, 1); + rb_define_method(rb_cBigDecimal, "===", BigDecimal_eq, 1); + rb_define_method(rb_cBigDecimal, "eql?", BigDecimal_eq, 1); + rb_define_method(rb_cBigDecimal, "<", BigDecimal_lt, 1); + rb_define_method(rb_cBigDecimal, "<=", BigDecimal_le, 1); + rb_define_method(rb_cBigDecimal, ">", BigDecimal_gt, 1); + rb_define_method(rb_cBigDecimal, ">=", BigDecimal_ge, 1); + rb_define_method(rb_cBigDecimal, "zero?", BigDecimal_zero, 0); + rb_define_method(rb_cBigDecimal, "nonzero?", BigDecimal_nonzero, 0); + rb_define_method(rb_cBigDecimal, "coerce", BigDecimal_coerce, 1); + rb_define_method(rb_cBigDecimal, "inspect", BigDecimal_inspect, 0); + rb_define_method(rb_cBigDecimal, "exponent", BigDecimal_exponent, 0); + rb_define_method(rb_cBigDecimal, "sign", BigDecimal_sign, 0); + rb_define_method(rb_cBigDecimal, "nan?", BigDecimal_IsNaN, 0); + rb_define_method(rb_cBigDecimal, "infinite?", BigDecimal_IsInfinite, 0); + rb_define_method(rb_cBigDecimal, "finite?", BigDecimal_IsFinite, 0); + rb_define_method(rb_cBigDecimal, "truncate", BigDecimal_truncate, -1); + rb_define_method(rb_cBigDecimal, "_dump", BigDecimal_dump, -1); + + rb_mBigMath = rb_define_module("BigMath"); + rb_define_singleton_method(rb_mBigMath, "exp", BigMath_s_exp, 2); + rb_define_singleton_method(rb_mBigMath, "log", BigMath_s_log, 2); + +#define ROUNDING_MODE(i, name, value) \ + id_##name = rb_intern_const(#name); \ + rbd_rounding_modes[i].id = id_##name; \ + rbd_rounding_modes[i].mode = value; + + ROUNDING_MODE(0, up, RBD_ROUND_UP); + ROUNDING_MODE(1, down, RBD_ROUND_DOWN); + ROUNDING_MODE(2, half_up, RBD_ROUND_HALF_UP); + ROUNDING_MODE(3, half_down, RBD_ROUND_HALF_DOWN); + ROUNDING_MODE(4, ceil, RBD_ROUND_CEIL); + ROUNDING_MODE(5, floor, RBD_ROUND_FLOOR); + ROUNDING_MODE(6, half_even, RBD_ROUND_HALF_EVEN); + + ROUNDING_MODE(7, default, RBD_ROUND_DEFAULT); + ROUNDING_MODE(8, truncate, RBD_ROUND_TRUNCATE); + ROUNDING_MODE(9, banker, RBD_ROUND_BANKER); + ROUNDING_MODE(10, ceiling, RBD_ROUND_CEILING); + +#undef ROUNDING_MODE + + id_to_r = rb_intern_const("to_r"); + id_eq = rb_intern_const("=="); + id_half = rb_intern_const("half"); + + (void)VPrint; /* suppress unused warning */ +} + +/* + * + * ============================================================================ + * + * vp_ routines begin from here. + * + * ============================================================================ + * + */ +#ifdef BIGDECIMAL_DEBUG +static int gfDebug = 1; /* Debug switch */ +#if 0 +static int gfCheckVal = 1; /* Value checking flag in VpNmlz() */ +#endif +#endif /* BIGDECIMAL_DEBUG */ + +static Real *VpConstOne; /* constant 1.0 */ +static Real *VpConstPt5; /* constant 0.5 */ +#define maxnr 100UL /* Maximum iterations for calculating sqrt. */ + /* used in VpSqrt() */ + +/* ETC */ +#define MemCmp(x,y,z) memcmp(x,y,z) +#define StrCmp(x,y) strcmp(x,y) + +enum op_sw { + OP_SW_ADD = 1, /* + */ + OP_SW_SUB, /* - */ + OP_SW_MULT, /* * */ + OP_SW_DIV /* / */ +}; + +static int VpIsDefOP(Real *c, Real *a, Real *b, enum op_sw sw); +static int AddExponent(Real *a, SIGNED_VALUE n); +static DECDIG VpAddAbs(Real *a,Real *b,Real *c); +static DECDIG VpSubAbs(Real *a,Real *b,Real *c); +static size_t VpSetPTR(Real *a, Real *b, Real *c, size_t *a_pos, size_t *b_pos, size_t *c_pos, DECDIG *av, DECDIG *bv); +static int VpNmlz(Real *a); +static void VpFormatSt(char *psz, size_t fFmt); +static int VpRdup(Real *m, size_t ind_m); + +#ifdef BIGDECIMAL_DEBUG +# ifdef HAVE_RB_EXT_RACTOR_SAFE +# error Need to make rewiting gnAlloc atomic +# endif +static int gnAlloc = 0; /* Memory allocation counter */ +#endif /* BIGDECIMAL_DEBUG */ + +/* + * EXCEPTION Handling. + */ + +#define bigdecimal_set_thread_local_exception_mode(mode) \ + rb_thread_local_aset( \ + rb_thread_current(), \ + id_BigDecimal_exception_mode, \ + INT2FIX((int)(mode)) \ + ) + +static unsigned short +VpGetException (void) +{ + VALUE const vmode = rb_thread_local_aref( + rb_thread_current(), + id_BigDecimal_exception_mode + ); + + if (NIL_P(vmode)) { + bigdecimal_set_thread_local_exception_mode(BIGDECIMAL_EXCEPTION_MODE_DEFAULT); + return BIGDECIMAL_EXCEPTION_MODE_DEFAULT; + } + + return NUM2USHORT(vmode); +} + +static void +VpSetException(unsigned short f) +{ + bigdecimal_set_thread_local_exception_mode(f); +} + +static void +VpCheckException(Real *p, bool always) +{ + if (VpIsNaN(p)) { + VpException(VP_EXCEPTION_NaN, "Computation results in 'NaN' (Not a Number)", always); + } + else if (VpIsPosInf(p)) { + VpException(VP_EXCEPTION_INFINITY, "Computation results in 'Infinity'", always); + } + else if (VpIsNegInf(p)) { + VpException(VP_EXCEPTION_INFINITY, "Computation results in '-Infinity'", always); + } +} + +static VALUE +VpCheckGetValue(Real *p) +{ + VpCheckException(p, false); + return p->obj; +} + +/* + * Precision limit. + */ + +#define bigdecimal_set_thread_local_precision_limit(limit) \ + rb_thread_local_aset( \ + rb_thread_current(), \ + id_BigDecimal_precision_limit, \ + SIZET2NUM(limit) \ + ) +#define BIGDECIMAL_PRECISION_LIMIT_DEFAULT ((size_t)0) + +/* These 2 functions added at v1.1.7 */ +VP_EXPORT size_t +VpGetPrecLimit(void) +{ + VALUE const vlimit = rb_thread_local_aref( + rb_thread_current(), + id_BigDecimal_precision_limit + ); + + if (NIL_P(vlimit)) { + bigdecimal_set_thread_local_precision_limit(BIGDECIMAL_PRECISION_LIMIT_DEFAULT); + return BIGDECIMAL_PRECISION_LIMIT_DEFAULT; + } + + return NUM2SIZET(vlimit); +} + +VP_EXPORT size_t +VpSetPrecLimit(size_t n) +{ + size_t const s = VpGetPrecLimit(); + bigdecimal_set_thread_local_precision_limit(n); + return s; +} + +/* + * Rounding mode. + */ + +#define bigdecimal_set_thread_local_rounding_mode(mode) \ + rb_thread_local_aset( \ + rb_thread_current(), \ + id_BigDecimal_rounding_mode, \ + INT2FIX((int)(mode)) \ + ) + +VP_EXPORT unsigned short +VpGetRoundMode(void) +{ + VALUE const vmode = rb_thread_local_aref( + rb_thread_current(), + id_BigDecimal_rounding_mode + ); + + if (NIL_P(vmode)) { + bigdecimal_set_thread_local_rounding_mode(BIGDECIMAL_ROUNDING_MODE_DEFAULT); + return BIGDECIMAL_ROUNDING_MODE_DEFAULT; + } + + return NUM2USHORT(vmode); +} + +VP_EXPORT int +VpIsRoundMode(unsigned short n) +{ + switch (n) { + case VP_ROUND_UP: + case VP_ROUND_DOWN: + case VP_ROUND_HALF_UP: + case VP_ROUND_HALF_DOWN: + case VP_ROUND_CEIL: + case VP_ROUND_FLOOR: + case VP_ROUND_HALF_EVEN: + return 1; + + default: + return 0; + } +} + +VP_EXPORT unsigned short +VpSetRoundMode(unsigned short n) +{ + if (VpIsRoundMode(n)) { + bigdecimal_set_thread_local_rounding_mode(n); + return n; + } + + return VpGetRoundMode(); +} + +/* + * 0.0 & 1.0 generator + * These gZero_..... and gOne_..... can be any name + * referenced from nowhere except Zero() and One(). + * gZero_..... and gOne_..... must have global scope + * (to let the compiler know they may be changed in outside + * (... but not actually..)). + */ +volatile const double gOne_ABCED9B4_CE73__00400511F31D = 1.0; + +static double +One(void) +{ + return gOne_ABCED9B4_CE73__00400511F31D; +} + +/* + ---------------------------------------------------------------- + Value of sign in Real structure is reserved for future use. + short sign; + ==0 : NaN + 1 : Positive zero + -1 : Negative zero + 2 : Positive number + -2 : Negative number + 3 : Positive infinite number + -3 : Negative infinite number + ---------------------------------------------------------------- +*/ + +VP_EXPORT double +VpGetDoubleNaN(void) /* Returns the value of NaN */ +{ + return nan(""); +} + +VP_EXPORT double +VpGetDoublePosInf(void) /* Returns the value of +Infinity */ +{ + return HUGE_VAL; +} + +VP_EXPORT double +VpGetDoubleNegInf(void) /* Returns the value of -Infinity */ +{ + return -HUGE_VAL; +} + +VP_EXPORT double +VpGetDoubleNegZero(void) /* Returns the value of -0 */ +{ + static double nzero = 1000.0; + if (nzero != 0.0) nzero = (One()/VpGetDoubleNegInf()); + return nzero; +} + +#if 0 /* unused */ +VP_EXPORT int +VpIsNegDoubleZero(double v) +{ + double z = VpGetDoubleNegZero(); + return MemCmp(&v,&z,sizeof(v))==0; +} +#endif + +VP_EXPORT int +VpException(unsigned short f, const char *str,int always) +{ + unsigned short const exception_mode = VpGetException(); + + if (f == VP_EXCEPTION_OP) always = 1; + + if (always || (exception_mode & f)) { + switch(f) { + /* case VP_EXCEPTION_OVERFLOW: */ + case VP_EXCEPTION_ZERODIVIDE: + case VP_EXCEPTION_INFINITY: + case VP_EXCEPTION_NaN: + case VP_EXCEPTION_UNDERFLOW: + case VP_EXCEPTION_OP: + rb_raise(rb_eFloatDomainError, "%s", str); + break; + default: + rb_fatal("%s", str); + } + } + return 0; /* 0 Means VpException() raised no exception */ +} + +/* Throw exception or returns 0,when resulting c is Inf or NaN */ +/* sw=1:+ 2:- 3:* 4:/ */ +static int +VpIsDefOP(Real *c, Real *a, Real *b, enum op_sw sw) +{ + if (VpIsNaN(a) || VpIsNaN(b)) { + /* at least a or b is NaN */ + VpSetNaN(c); + goto NaN; + } + + if (VpIsInf(a)) { + if (VpIsInf(b)) { + switch(sw) { + case OP_SW_ADD: /* + */ + if (VpGetSign(a) == VpGetSign(b)) { + VpSetInf(c, VpGetSign(a)); + goto Inf; + } + else { + VpSetNaN(c); + goto NaN; + } + case OP_SW_SUB: /* - */ + if (VpGetSign(a) != VpGetSign(b)) { + VpSetInf(c, VpGetSign(a)); + goto Inf; + } + else { + VpSetNaN(c); + goto NaN; + } + case OP_SW_MULT: /* * */ + VpSetInf(c, VpGetSign(a)*VpGetSign(b)); + goto Inf; + case OP_SW_DIV: /* / */ + VpSetNaN(c); + goto NaN; + } + VpSetNaN(c); + goto NaN; + } + /* Inf op Finite */ + switch(sw) { + case OP_SW_ADD: /* + */ + case OP_SW_SUB: /* - */ + VpSetInf(c, VpGetSign(a)); + break; + case OP_SW_MULT: /* * */ + if (VpIsZero(b)) { + VpSetNaN(c); + goto NaN; + } + VpSetInf(c, VpGetSign(a)*VpGetSign(b)); + break; + case OP_SW_DIV: /* / */ + VpSetInf(c, VpGetSign(a)*VpGetSign(b)); + } + goto Inf; + } + + if (VpIsInf(b)) { + switch(sw) { + case OP_SW_ADD: /* + */ + VpSetInf(c, VpGetSign(b)); + break; + case OP_SW_SUB: /* - */ + VpSetInf(c, -VpGetSign(b)); + break; + case OP_SW_MULT: /* * */ + if (VpIsZero(a)) { + VpSetNaN(c); + goto NaN; + } + VpSetInf(c, VpGetSign(a)*VpGetSign(b)); + break; + case OP_SW_DIV: /* / */ + VpSetZero(c, VpGetSign(a)*VpGetSign(b)); + } + goto Inf; + } + return 1; /* Results OK */ + +Inf: + if (VpIsPosInf(c)) { + return VpException(VP_EXCEPTION_INFINITY, "Computation results to 'Infinity'", 0); + } + else { + return VpException(VP_EXCEPTION_INFINITY, "Computation results to '-Infinity'", 0); + } + +NaN: + return VpException(VP_EXCEPTION_NaN, "Computation results to 'NaN'", 0); +} + +/* + ---------------------------------------------------------------- +*/ + +/* + * returns number of chars needed to represent vp in specified format. + */ +VP_EXPORT size_t +VpNumOfChars(Real *vp,const char *pszFmt) +{ + SIGNED_VALUE ex; + size_t nc; + + if (vp == NULL) return BASE_FIG*2+6; + if (!VpIsDef(vp)) return 32; /* not sure,may be OK */ + + switch(*pszFmt) { + case 'F': + nc = BASE_FIG*(vp->Prec + 1)+2; + ex = vp->exponent; + if (ex < 0) { + nc += BASE_FIG*(size_t)(-ex); + } + else { + if ((size_t)ex > vp->Prec) { + nc += BASE_FIG*((size_t)ex - vp->Prec); + } + } + break; + case 'E': + /* fall through */ + default: + nc = BASE_FIG*(vp->Prec + 2)+6; /* 3: sign + exponent chars */ + } + return nc; +} + +/* + * Initializer for Vp routines and constants used. + * [Input] + * BaseVal: Base value(assigned to BASE) for Vp calculation. + * It must be the form BaseVal=10**n.(n=1,2,3,...) + * If Base <= 0L,then the BASE will be calculated so + * that BASE is as large as possible satisfying the + * relation MaxVal <= BASE*(BASE+1). Where the value + * MaxVal is the largest value which can be represented + * by one DECDIG word in the computer used. + * + * [Returns] + * BIGDECIMAL_DOUBLE_FIGURES ... OK + */ +VP_EXPORT size_t +VpInit(DECDIG BaseVal) +{ + /* Setup +/- Inf NaN -0 */ + VpGetDoubleNegZero(); + + /* Const 1.0 */ + VpConstOne = NewOneNolimit(1, 1); + + /* Const 0.5 */ + VpConstPt5 = NewOneNolimit(1, 1); + VpConstPt5->exponent = 0; + VpConstPt5->frac[0] = 5*BASE1; + +#ifdef BIGDECIMAL_DEBUG + gnAlloc = 0; +#endif /* BIGDECIMAL_DEBUG */ + +#ifdef BIGDECIMAL_DEBUG + if (gfDebug) { + printf("VpInit: BaseVal = %"PRIuDECDIG"\n", BaseVal); + printf("\tBASE = %"PRIuDECDIG"\n", BASE); + printf("\tHALF_BASE = %"PRIuDECDIG"\n", HALF_BASE); + printf("\tBASE1 = %"PRIuDECDIG"\n", BASE1); + printf("\tBASE_FIG = %u\n", BASE_FIG); + printf("\tBIGDECIMAL_DOUBLE_FIGURES = %d\n", BIGDECIMAL_DOUBLE_FIGURES); + } +#endif /* BIGDECIMAL_DEBUG */ + + return BIGDECIMAL_DOUBLE_FIGURES; +} + +VP_EXPORT Real * +VpOne(void) +{ + return VpConstOne; +} + +/* If exponent overflows,then raise exception or returns 0 */ +static int +AddExponent(Real *a, SIGNED_VALUE n) +{ + SIGNED_VALUE e = a->exponent; + SIGNED_VALUE m = e+n; + SIGNED_VALUE eb, mb; + if (e > 0) { + if (n > 0) { + if (MUL_OVERFLOW_SIGNED_VALUE_P(m, (SIGNED_VALUE)BASE_FIG) || + MUL_OVERFLOW_SIGNED_VALUE_P(e, (SIGNED_VALUE)BASE_FIG)) + goto overflow; + mb = m*(SIGNED_VALUE)BASE_FIG; + eb = e*(SIGNED_VALUE)BASE_FIG; + if (eb - mb > 0) goto overflow; + } + } + else if (n < 0) { + if (MUL_OVERFLOW_SIGNED_VALUE_P(m, (SIGNED_VALUE)BASE_FIG) || + MUL_OVERFLOW_SIGNED_VALUE_P(e, (SIGNED_VALUE)BASE_FIG)) + goto underflow; + mb = m*(SIGNED_VALUE)BASE_FIG; + eb = e*(SIGNED_VALUE)BASE_FIG; + if (mb - eb > 0) goto underflow; + } + a->exponent = m; + return 1; + +/* Overflow/Underflow ==> Raise exception or returns 0 */ +underflow: + VpSetZero(a, VpGetSign(a)); + return VpException(VP_EXCEPTION_UNDERFLOW, "Exponent underflow", 0); + +overflow: + VpSetInf(a, VpGetSign(a)); + return VpException(VP_EXCEPTION_OVERFLOW, "Exponent overflow", 0); +} + +Real * +bigdecimal_parse_special_string(const char *str) +{ + static const struct { + const char *str; + size_t len; + int sign; + } table[] = { + { SZ_INF, sizeof(SZ_INF) - 1, VP_SIGN_POSITIVE_INFINITE }, + { SZ_PINF, sizeof(SZ_PINF) - 1, VP_SIGN_POSITIVE_INFINITE }, + { SZ_NINF, sizeof(SZ_NINF) - 1, VP_SIGN_NEGATIVE_INFINITE }, + { SZ_NaN, sizeof(SZ_NaN) - 1, VP_SIGN_NaN } + }; + static const size_t table_length = sizeof(table) / sizeof(table[0]); + size_t i; + + for (i = 0; i < table_length; ++i) { + const char *p; + if (strncmp(str, table[i].str, table[i].len) != 0) { + continue; + } + + p = str + table[i].len; + while (*p && ISSPACE(*p)) ++p; + if (*p == '\0') { + Real *vp = rbd_allocate_struct(1); + vp->MaxPrec = 1; + switch (table[i].sign) { + default: + UNREACHABLE; break; + case VP_SIGN_POSITIVE_INFINITE: + VpSetPosInf(vp); + return vp; + case VP_SIGN_NEGATIVE_INFINITE: + VpSetNegInf(vp); + return vp; + case VP_SIGN_NaN: + VpSetNaN(vp); + return vp; + } + } + } + + return NULL; +} + +struct VpCtoV_args { + Real *a; + const char *int_chr; + size_t ni; + const char *frac; + size_t nf; + const char *exp_chr; + size_t ne; +}; + +static VALUE +call_VpCtoV(VALUE arg) +{ + struct VpCtoV_args *x = (struct VpCtoV_args *)arg; + return (VALUE)VpCtoV(x->a, x->int_chr, x->ni, x->frac, x->nf, x->exp_chr, x->ne); +} + +static int +protected_VpCtoV(Real *a, const char *int_chr, size_t ni, const char *frac, size_t nf, const char *exp_chr, size_t ne, int free_on_error) +{ + struct VpCtoV_args args; + int state = 0; + + args.a = a; + args.int_chr = int_chr; + args.ni = ni; + args.frac = frac; + args.nf = nf; + args.exp_chr = exp_chr; + args.ne = ne; + + VALUE result = rb_protect(call_VpCtoV, (VALUE)&args, &state); + if (state) { + if (free_on_error) { + rbd_free_struct(a); + } + rb_jump_tag(state); + } + + return (int)result; +} + +/* + * Allocates variable. + * [Input] + * mx ... The number of decimal digits to be allocated, if zero then mx is determined by szVal. + * The mx will be the number of significant digits can to be stored. + * szVal ... The value assigned(char). If szVal==NULL, then zero is assumed. + * If szVal[0]=='#' then MaxPrec is not affected by the precision limit + * so that the full precision specified by szVal is allocated. + * + * [Returns] + * Pointer to the newly allocated variable, or + * NULL be returned if memory allocation is failed,or any error. + */ +VP_EXPORT Real * +VpAlloc(size_t mx, const char *szVal, int strict_p, int exc) +{ + const char *orig_szVal = szVal; + size_t i, j, ni, ipf, nf, ipe, ne, exp_seen, nalloc; + size_t len; + char v, *psz; + int sign=1; + Real *vp = NULL; + VALUE buf; + + if (szVal == NULL) { + return_zero: + /* necessary to be able to store */ + /* at least mx digits. */ + /* szVal==NULL ==> allocate zero value. */ + vp = rbd_allocate_struct(mx); + vp->MaxPrec = rbd_calculate_internal_digits(mx, false); /* Must false */ + VpSetZero(vp, 1); /* initialize vp to zero. */ + return vp; + } + + /* Skipping leading spaces */ + while (ISSPACE(*szVal)) szVal++; + + /* Check on Inf & NaN */ + if ((vp = bigdecimal_parse_special_string(szVal)) != NULL) { + return vp; + } + + /* Processing the leading one `#` */ + if (*szVal != '#') { + len = rbd_calculate_internal_digits(mx, true); + } + else { + len = rbd_calculate_internal_digits(mx, false); + ++szVal; + } + + /* Scanning digits */ + + /* A buffer for keeping scanned digits */ + buf = rb_str_tmp_new(strlen(szVal) + 1); + psz = RSTRING_PTR(buf); + + /* cursor: i for psz, and j for szVal */ + i = j = 0; + + /* Scanning: sign part */ + v = psz[i] = szVal[j]; + if ((v == '-') || (v == '+')) { + sign = -(v == '-'); + ++i; + ++j; + } + + /* Scanning: integer part */ + ni = 0; /* number of digits in the integer part */ + while ((v = psz[i] = szVal[j]) != '\0') { + if (!strict_p && ISSPACE(v)) { + v = psz[i] = '\0'; + break; + } + if (v == '_') { + if (ni > 0) { + v = szVal[j+1]; + if (v == '\0' || ISSPACE(v) || ISDIGIT(v)) { + ++j; + continue; + } + if (!strict_p) { + v = psz[i] = '\0'; + break; + } + } + goto invalid_value; + } + if (!ISDIGIT(v)) { + break; + } + ++ni; + ++i; + ++j; + } + + /* Scanning: fractional part */ + nf = 0; /* number of digits in the fractional part */ + ne = 0; /* number of digits in the exponential part */ + ipf = 0; /* index of the beginning of the fractional part */ + ipe = 0; /* index of the beginning of the exponential part */ + exp_seen = 0; + + if (v != '\0') { + /* Scanning fractional part */ + if ((psz[i] = szVal[j]) == '.') { + ++i; + ++j; + ipf = i; + while ((v = psz[i] = szVal[j]) != '\0') { + if (!strict_p && ISSPACE(v)) { + v = psz[i] = '\0'; + break; + } + if (v == '_') { + if (nf > 0 && ISDIGIT(szVal[j+1])) { + ++j; + continue; + } + if (!strict_p) { + v = psz[i] = '\0'; + break; + } + goto invalid_value; + } + if (!ISDIGIT(v)) break; + ++i; + ++j; + ++nf; + } + } + + /* Scanning exponential part */ + if (v != '\0') { + switch ((psz[i] = szVal[j])) { + case '\0': + break; + case 'e': case 'E': + case 'd': case 'D': + exp_seen = 1; + ++i; + ++j; + ipe = i; + v = psz[i] = szVal[j]; + if ((v == '-') || (v == '+')) { + ++i; + ++j; + } + while ((v = psz[i] = szVal[j]) != '\0') { + if (!strict_p && ISSPACE(v)) { + v = psz[i] = '\0'; + break; + } + if (v == '_') { + if (ne > 0 && ISDIGIT(szVal[j+1])) { + ++j; + continue; + } + if (!strict_p) { + v = psz[i] = '\0'; + if (ne == 0) { + exp_seen = 0; + } + break; + } + goto invalid_value; + } + if (!ISDIGIT(v)) break; + ++i; + ++j; + ++ne; + } + break; + default: + break; + } + } + + if (v != '\0') { + /* Scanning trailing spaces */ + while (ISSPACE(szVal[j])) ++j; + + /* Invalid character */ + if (szVal[j] && strict_p) { + goto invalid_value; + } + } + } + + psz[i] = '\0'; + + if (strict_p && ((ni == 0 && nf == 0) || (exp_seen && ne == 0))) { + VALUE str; + invalid_value: + if (!strict_p) { + goto return_zero; + } + if (!exc) { + return NULL; + } + str = rb_str_new2(orig_szVal); + rb_raise(rb_eArgError, "invalid value for BigDecimal(): \"%"PRIsVALUE"\"", str); + } + + nalloc = (ni + nf + BASE_FIG - 1) / BASE_FIG + 1; /* set effective allocation */ + /* units for szVal[] */ + if (len == 0) len = 1; + nalloc = Max(nalloc, len); + len = nalloc; + vp = rbd_allocate_struct(len); + vp->MaxPrec = len; /* set max precision */ + VpSetZero(vp, sign); + protected_VpCtoV(vp, psz, ni, psz + ipf, nf, psz + ipe, ne, true); + rb_str_resize(buf, 0); + return vp; +} + +/* + * Assignment(c=a). + * [Input] + * a ... RHSV + * isw ... switch for assignment. + * c = a when isw > 0 + * c = -a when isw < 0 + * if c->MaxPrec < a->Prec,then round operation + * will be performed. + * [Output] + * c ... LHSV + */ +VP_EXPORT size_t +VpAsgn(Real *c, Real *a, int isw) +{ + size_t n; + if (VpIsNaN(a)) { + VpSetNaN(c); + return 0; + } + if (VpIsInf(a)) { + VpSetInf(c, isw * VpGetSign(a)); + return 0; + } + + /* check if the RHS is zero */ + if (!VpIsZero(a)) { + c->exponent = a->exponent; /* store exponent */ + VpSetSign(c, isw * VpGetSign(a)); /* set sign */ + n = (a->Prec < c->MaxPrec) ? (a->Prec) : (c->MaxPrec); + c->Prec = n; + memcpy(c->frac, a->frac, n * sizeof(DECDIG)); + /* Needs round ? */ + if (isw != 10) { + /* Not in ActiveRound */ + if(c->Prec < a->Prec) { + VpInternalRound(c, n, (n>0) ? a->frac[n-1] : 0, a->frac[n]); + } + else { + VpLimitRound(c,0); + } + } + } + else { + /* The value of 'a' is zero. */ + VpSetZero(c, isw * VpGetSign(a)); + return 1; + } + return c->Prec * BASE_FIG; +} + +/* + * c = a + b when operation = 1 or 2 + * c = a - b when operation = -1 or -2. + * Returns number of significant digits of c + */ +VP_EXPORT size_t +VpAddSub(Real *c, Real *a, Real *b, int operation) +{ + short sw, isw; + Real *a_ptr, *b_ptr; + size_t n, na, nb, i; + DECDIG mrv; + +#ifdef BIGDECIMAL_DEBUG + if (gfDebug) { + VPrint(stdout, "VpAddSub(enter) a=% \n", a); + VPrint(stdout, " b=% \n", b); + printf(" operation=%d\n", operation); + } +#endif /* BIGDECIMAL_DEBUG */ + + if (!VpIsDefOP(c, a, b, (operation > 0) ? OP_SW_ADD : OP_SW_SUB)) return 0; /* No significant digits */ + + /* check if a or b is zero */ + if (VpIsZero(a)) { + /* a is zero,then assign b to c */ + if (!VpIsZero(b)) { + VpAsgn(c, b, operation); + } + else { + /* Both a and b are zero. */ + if (VpGetSign(a) < 0 && operation * VpGetSign(b) < 0) { + /* -0 -0 */ + VpSetZero(c, -1); + } + else { + VpSetZero(c, 1); + } + return 1; /* 0: 1 significant digits */ + } + return c->Prec * BASE_FIG; + } + if (VpIsZero(b)) { + /* b is zero,then assign a to c. */ + VpAsgn(c, a, 1); + return c->Prec*BASE_FIG; + } + + if (operation < 0) sw = -1; + else sw = 1; + + /* compare absolute value. As a result,|a_ptr|>=|b_ptr| */ + if (a->exponent > b->exponent) { + a_ptr = a; + b_ptr = b; + } /* |a|>|b| */ + else if (a->exponent < b->exponent) { + a_ptr = b; + b_ptr = a; + } /* |a|<|b| */ + else { + /* Exponent part of a and b is the same,then compare fraction */ + /* part */ + na = a->Prec; + nb = b->Prec; + n = Min(na, nb); + for (i=0; i < n; ++i) { + if (a->frac[i] > b->frac[i]) { + a_ptr = a; + b_ptr = b; + goto end_if; + } + else if (a->frac[i] < b->frac[i]) { + a_ptr = b; + b_ptr = a; + goto end_if; + } + } + if (na > nb) { + a_ptr = a; + b_ptr = b; + goto end_if; + } + else if (na < nb) { + a_ptr = b; + b_ptr = a; + goto end_if; + } + /* |a| == |b| */ + if (VpGetSign(a) + sw *VpGetSign(b) == 0) { + VpSetZero(c, 1); /* abs(a)=abs(b) and operation = '-' */ + return c->Prec * BASE_FIG; + } + a_ptr = a; + b_ptr = b; + } + +end_if: + isw = VpGetSign(a) + sw *VpGetSign(b); + /* + * isw = 0 ...( 1)+(-1),( 1)-( 1),(-1)+(1),(-1)-(-1) + * = 2 ...( 1)+( 1),( 1)-(-1) + * =-2 ...(-1)+(-1),(-1)-( 1) + * If isw==0, then c =(Sign a_ptr)(|a_ptr|-|b_ptr|) + * else c =(Sign ofisw)(|a_ptr|+|b_ptr|) + */ + if (isw) { /* addition */ + VpSetSign(c, 1); + mrv = VpAddAbs(a_ptr, b_ptr, c); + VpSetSign(c, isw / 2); + } + else { /* subtraction */ + VpSetSign(c, 1); + mrv = VpSubAbs(a_ptr, b_ptr, c); + if (a_ptr == a) { + VpSetSign(c,VpGetSign(a)); + } + else { + VpSetSign(c, VpGetSign(a_ptr) * sw); + } + } + VpInternalRound(c, 0, (c->Prec > 0) ? c->frac[c->Prec-1] : 0, mrv); + +#ifdef BIGDECIMAL_DEBUG + if (gfDebug) { + VPrint(stdout, "VpAddSub(result) c=% \n", c); + VPrint(stdout, " a=% \n", a); + VPrint(stdout, " b=% \n", b); + printf(" operation=%d\n", operation); + } +#endif /* BIGDECIMAL_DEBUG */ + return c->Prec * BASE_FIG; +} + +/* + * Addition of two values with variable precision + * a and b assuming abs(a)>abs(b). + * c = abs(a) + abs(b) ; where |a|>=|b| + */ +static DECDIG +VpAddAbs(Real *a, Real *b, Real *c) +{ + size_t word_shift; + size_t ap; + size_t bp; + size_t cp; + size_t a_pos; + size_t b_pos, b_pos_with_word_shift; + size_t c_pos; + DECDIG av, bv, carry, mrv; + +#ifdef BIGDECIMAL_DEBUG + if (gfDebug) { + VPrint(stdout, "VpAddAbs called: a = %\n", a); + VPrint(stdout, " b = %\n", b); + } +#endif /* BIGDECIMAL_DEBUG */ + + word_shift = VpSetPTR(a, b, c, &ap, &bp, &cp, &av, &bv); + a_pos = ap; + b_pos = bp; + c_pos = cp; + + if (word_shift == (size_t)-1L) return 0; /* Overflow */ + if (b_pos == (size_t)-1L) goto Assign_a; + + mrv = av + bv; /* Most right val. Used for round. */ + + /* Just assign the last few digits of b to c because a has no */ + /* corresponding digits to be added. */ + if (b_pos > 0) { + while (b_pos > 0 && b_pos + word_shift > a_pos) { + c->frac[--c_pos] = b->frac[--b_pos]; + } + } + if (b_pos == 0 && word_shift > a_pos) { + while (word_shift-- > a_pos) { + c->frac[--c_pos] = 0; + } + } + + /* Just assign the last few digits of a to c because b has no */ + /* corresponding digits to be added. */ + b_pos_with_word_shift = b_pos + word_shift; + while (a_pos > b_pos_with_word_shift) { + c->frac[--c_pos] = a->frac[--a_pos]; + } + carry = 0; /* set first carry be zero */ + + /* Now perform addition until every digits of b will be */ + /* exhausted. */ + while (b_pos > 0) { + c->frac[--c_pos] = a->frac[--a_pos] + b->frac[--b_pos] + carry; + if (c->frac[c_pos] >= BASE) { + c->frac[c_pos] -= BASE; + carry = 1; + } + else { + carry = 0; + } + } + + /* Just assign the first few digits of a with considering */ + /* the carry obtained so far because b has been exhausted. */ + while (a_pos > 0) { + c->frac[--c_pos] = a->frac[--a_pos] + carry; + if (c->frac[c_pos] >= BASE) { + c->frac[c_pos] -= BASE; + carry = 1; + } + else { + carry = 0; + } + } + if (c_pos) c->frac[c_pos - 1] += carry; + goto Exit; + +Assign_a: + VpAsgn(c, a, 1); + mrv = 0; + +Exit: + +#ifdef BIGDECIMAL_DEBUG + if (gfDebug) { + VPrint(stdout, "VpAddAbs exit: c=% \n", c); + } +#endif /* BIGDECIMAL_DEBUG */ + return mrv; +} + +/* + * c = abs(a) - abs(b) + */ +static DECDIG +VpSubAbs(Real *a, Real *b, Real *c) +{ + size_t word_shift; + size_t ap; + size_t bp; + size_t cp; + size_t a_pos; + size_t b_pos, b_pos_with_word_shift; + size_t c_pos; + DECDIG av, bv, borrow, mrv; + +#ifdef BIGDECIMAL_DEBUG + if (gfDebug) { + VPrint(stdout, "VpSubAbs called: a = %\n", a); + VPrint(stdout, " b = %\n", b); + } +#endif /* BIGDECIMAL_DEBUG */ + + word_shift = VpSetPTR(a, b, c, &ap, &bp, &cp, &av, &bv); + a_pos = ap; + b_pos = bp; + c_pos = cp; + if (word_shift == (size_t)-1L) return 0; /* Overflow */ + if (b_pos == (size_t)-1L) goto Assign_a; + + if (av >= bv) { + mrv = av - bv; + borrow = 0; + } + else { + mrv = 0; + borrow = 1; + } + + /* Just assign the values which are the BASE subtracted by */ + /* each of the last few digits of the b because the a has no */ + /* corresponding digits to be subtracted. */ + if (b_pos + word_shift > a_pos) { + while (b_pos > 0 && b_pos + word_shift > a_pos) { + c->frac[--c_pos] = BASE - b->frac[--b_pos] - borrow; + borrow = 1; + } + if (b_pos == 0) { + while (word_shift > a_pos) { + --word_shift; + c->frac[--c_pos] = BASE - borrow; + borrow = 1; + } + } + } + /* Just assign the last few digits of a to c because b has no */ + /* corresponding digits to subtract. */ + + b_pos_with_word_shift = b_pos + word_shift; + while (a_pos > b_pos_with_word_shift) { + c->frac[--c_pos] = a->frac[--a_pos]; + } + + /* Now perform subtraction until every digits of b will be */ + /* exhausted. */ + while (b_pos > 0) { + --c_pos; + if (a->frac[--a_pos] < b->frac[--b_pos] + borrow) { + c->frac[c_pos] = BASE + a->frac[a_pos] - b->frac[b_pos] - borrow; + borrow = 1; + } + else { + c->frac[c_pos] = a->frac[a_pos] - b->frac[b_pos] - borrow; + borrow = 0; + } + } + + /* Just assign the first few digits of a with considering */ + /* the borrow obtained so far because b has been exhausted. */ + while (a_pos > 0) { + --c_pos; + if (a->frac[--a_pos] < borrow) { + c->frac[c_pos] = BASE + a->frac[a_pos] - borrow; + borrow = 1; + } + else { + c->frac[c_pos] = a->frac[a_pos] - borrow; + borrow = 0; + } + } + if (c_pos) c->frac[c_pos - 1] -= borrow; + goto Exit; + +Assign_a: + VpAsgn(c, a, 1); + mrv = 0; + +Exit: +#ifdef BIGDECIMAL_DEBUG + if (gfDebug) { + VPrint(stdout, "VpSubAbs exit: c=% \n", c); + } +#endif /* BIGDECIMAL_DEBUG */ + return mrv; +} + +/* + * Note: If(av+bv)>= HALF_BASE,then 1 will be added to the least significant + * digit of c(In case of addition). + * ------------------------- figure of output ----------------------------------- + * a = xxxxxxxxxxx + * b = xxxxxxxxxx + * c =xxxxxxxxxxxxxxx + * word_shift = | | + * right_word = | | (Total digits in RHSV) + * left_word = | | (Total digits in LHSV) + * a_pos = | + * b_pos = | + * c_pos = | + */ +static size_t +VpSetPTR(Real *a, Real *b, Real *c, size_t *a_pos, size_t *b_pos, size_t *c_pos, DECDIG *av, DECDIG *bv) +{ + size_t left_word, right_word, word_shift; + + size_t const round_limit = (VpGetPrecLimit() + BASE_FIG - 1) / BASE_FIG; + + assert(a->exponent >= b->exponent); + + c->frac[0] = 0; + *av = *bv = 0; + + word_shift = (a->exponent - b->exponent); + left_word = b->Prec + word_shift; + right_word = Max(a->Prec, left_word); + left_word = c->MaxPrec - 1; /* -1 ... prepare for round up */ + + /* + * check if 'round' is needed. + */ + if (right_word > left_word) { /* round ? */ + /*--------------------------------- + * Actual size of a = xxxxxxAxx + * Actual size of b = xxxBxxxxx + * Max. size of c = xxxxxx + * Round off = |-----| + * c_pos = | + * right_word = | + * a_pos = | + */ + *c_pos = right_word = left_word + 1; /* Set resulting precision */ + /* be equal to that of c */ + if (a->Prec >= c->MaxPrec) { + /* + * a = xxxxxxAxxx + * c = xxxxxx + * a_pos = | + */ + *a_pos = left_word; + if (*a_pos <= round_limit) { + *av = a->frac[*a_pos]; /* av is 'A' shown in above. */ + } + } + else { + /* + * a = xxxxxxx + * c = xxxxxxxxxx + * a_pos = | + */ + *a_pos = a->Prec; + } + if (b->Prec + word_shift >= c->MaxPrec) { + /* + * a = xxxxxxxxx + * b = xxxxxxxBxxx + * c = xxxxxxxxxxx + * b_pos = | + */ + if (c->MaxPrec >= word_shift + 1) { + *b_pos = c->MaxPrec - word_shift - 1; + if (*b_pos + word_shift <= round_limit) { + *bv = b->frac[*b_pos]; + } + } + else { + *b_pos = -1L; + } + } + else { + /* + * a = xxxxxxxxxxxxxxxx + * b = xxxxxx + * c = xxxxxxxxxxxxx + * b_pos = | + */ + *b_pos = b->Prec; + } + } + else { /* The MaxPrec of c - 1 > The Prec of a + b */ + /* + * a = xxxxxxx + * b = xxxxxx + * c = xxxxxxxxxxx + * c_pos = | + */ + *b_pos = b->Prec; + *a_pos = a->Prec; + *c_pos = right_word + 1; + } + c->Prec = *c_pos; + c->exponent = a->exponent; + if (!AddExponent(c, 1)) return (size_t)-1L; + return word_shift; +} + +/* + * Return number of significant digits + * c = a * b , Where a = a0a1a2 ... an + * b = b0b1b2 ... bm + * c = c0c1c2 ... cl + * a0 a1 ... an * bm + * a0 a1 ... an * bm-1 + * . . . + * . . . + * a0 a1 .... an * b0 + * +_____________________________ + * c0 c1 c2 ...... cl + * nc <---| + * MaxAB |--------------------| + */ +VP_EXPORT size_t +VpMult(Real *c, Real *a, Real *b) +{ + size_t MxIndA, MxIndB, MxIndAB, MxIndC; + size_t ind_c, i, ii, nc; + size_t ind_as, ind_ae, ind_bs; + DECDIG carry; + DECDIG_DBL s; + Real *w; + +#ifdef BIGDECIMAL_DEBUG + if (gfDebug) { + VPrint(stdout, "VpMult(Enter): a=% \n", a); + VPrint(stdout, " b=% \n", b); + } +#endif /* BIGDECIMAL_DEBUG */ + + if (!VpIsDefOP(c, a, b, OP_SW_MULT)) return 0; /* No significant digit */ + + if (VpIsZero(a) || VpIsZero(b)) { + /* at least a or b is zero */ + VpSetZero(c, VpGetSign(a) * VpGetSign(b)); + return 1; /* 0: 1 significant digit */ + } + + if (VpIsOne(a)) { + VpAsgn(c, b, VpGetSign(a)); + goto Exit; + } + if (VpIsOne(b)) { + VpAsgn(c, a, VpGetSign(b)); + goto Exit; + } + if (b->Prec > a->Prec) { + /* Adjust so that digits(a)>digits(b) */ + w = a; + a = b; + b = w; + } + w = NULL; + MxIndA = a->Prec - 1; + MxIndB = b->Prec - 1; + MxIndC = c->MaxPrec - 1; + MxIndAB = a->Prec + b->Prec - 1; + + if (MxIndC < MxIndAB) { /* The Max. prec. of c < Prec(a)+Prec(b) */ + w = c; + c = NewZeroNolimit(1, (size_t)((MxIndAB + 1) * BASE_FIG)); + MxIndC = MxIndAB; + } + + /* set LHSV c info */ + + c->exponent = a->exponent; /* set exponent */ + if (!AddExponent(c, b->exponent)) { + if (w) rbd_free_struct(c); + return 0; + } + VpSetSign(c, VpGetSign(a) * VpGetSign(b)); /* set sign */ + carry = 0; + nc = ind_c = MxIndAB; + memset(c->frac, 0, (nc + 1) * sizeof(DECDIG)); /* Initialize c */ + c->Prec = nc + 1; /* set precision */ + for (nc = 0; nc < MxIndAB; ++nc, --ind_c) { + if (nc < MxIndB) { /* The left triangle of the Fig. */ + ind_as = MxIndA - nc; + ind_ae = MxIndA; + ind_bs = MxIndB; + } + else if (nc <= MxIndA) { /* The middle rectangular of the Fig. */ + ind_as = MxIndA - nc; + ind_ae = MxIndA - (nc - MxIndB); + ind_bs = MxIndB; + } + else /* if (nc > MxIndA) */ { /* The right triangle of the Fig. */ + ind_as = 0; + ind_ae = MxIndAB - nc - 1; + ind_bs = MxIndB - (nc - MxIndA); + } + + for (i = ind_as; i <= ind_ae; ++i) { + s = (DECDIG_DBL)a->frac[i] * b->frac[ind_bs--]; + carry = (DECDIG)(s / BASE); + s -= (DECDIG_DBL)carry * BASE; + c->frac[ind_c] += (DECDIG)s; + if (c->frac[ind_c] >= BASE) { + s = c->frac[ind_c] / BASE; + carry += (DECDIG)s; + c->frac[ind_c] -= (DECDIG)(s * BASE); + } + if (carry) { + ii = ind_c; + while (ii-- > 0) { + c->frac[ii] += carry; + if (c->frac[ii] >= BASE) { + carry = c->frac[ii] / BASE; + c->frac[ii] -= (carry * BASE); + } + else { + break; + } + } + } + } + } + if (w != NULL) { /* free work variable */ + VpNmlz(c); + VpAsgn(w, c, 1); + rbd_free_struct(c); + c = w; + } + else { + VpLimitRound(c,0); + } + +Exit: +#ifdef BIGDECIMAL_DEBUG + if (gfDebug) { + VPrint(stdout, "VpMult(c=a*b): c=% \n", c); + VPrint(stdout, " a=% \n", a); + VPrint(stdout, " b=% \n", b); + } +#endif /*BIGDECIMAL_DEBUG */ + return c->Prec*BASE_FIG; +} + +/* + * c = a / b, remainder = r + */ +VP_EXPORT size_t +VpDivd(Real *c, Real *r, Real *a, Real *b) +{ + size_t word_a, word_b, word_c, word_r; + size_t i, n, ind_a, ind_b, ind_c, ind_r; + size_t nLoop; + DECDIG_DBL q, b1, b1p1, b1b2, b1b2p1, r1r2; + DECDIG borrow, borrow1, borrow2; + DECDIG_DBL qb; + +#ifdef BIGDECIMAL_DEBUG + if (gfDebug) { + VPrint(stdout, " VpDivd(c=a/b) a=% \n", a); + VPrint(stdout, " b=% \n", b); + } +#endif /*BIGDECIMAL_DEBUG */ + + VpSetNaN(r); + if (!VpIsDefOP(c, a, b, OP_SW_DIV)) goto Exit; + if (VpIsZero(a) && VpIsZero(b)) { + VpSetNaN(c); + return VpException(VP_EXCEPTION_NaN, "Computation results to 'NaN'", 0); + } + if (VpIsZero(b)) { + VpSetInf(c, VpGetSign(a) * VpGetSign(b)); + return VpException(VP_EXCEPTION_ZERODIVIDE, "Divide by zero", 0); + } + if (VpIsZero(a)) { + /* numerator a is zero */ + VpSetZero(c, VpGetSign(a) * VpGetSign(b)); + VpSetZero(r, VpGetSign(a) * VpGetSign(b)); + goto Exit; + } + if (VpIsOne(b)) { + /* divide by one */ + VpAsgn(c, a, VpGetSign(b)); + VpSetZero(r, VpGetSign(a)); + goto Exit; + } + + word_a = a->Prec; + word_b = b->Prec; + word_c = c->MaxPrec; + word_r = r->MaxPrec; + + if (word_a >= word_r || word_b + word_c - 2 >= word_r) goto space_error; + + ind_r = 1; + r->frac[0] = 0; + while (ind_r <= word_a) { + r->frac[ind_r] = a->frac[ind_r - 1]; + ++ind_r; + } + while (ind_r < word_r) r->frac[ind_r++] = 0; + + ind_c = 0; + while (ind_c < word_c) c->frac[ind_c++] = 0; + + /* initial procedure */ + b1 = b1p1 = b->frac[0]; + if (b->Prec <= 1) { + b1b2p1 = b1b2 = b1p1 * BASE; + } + else { + b1p1 = b1 + 1; + b1b2p1 = b1b2 = b1 * BASE + b->frac[1]; + if (b->Prec > 2) ++b1b2p1; + } + + /* */ + /* loop start */ + ind_c = word_r - 1; + nLoop = Min(word_c,ind_c); + ind_c = 1; + while (ind_c < nLoop) { + if (r->frac[ind_c] == 0) { + ++ind_c; + continue; + } + r1r2 = (DECDIG_DBL)r->frac[ind_c] * BASE + r->frac[ind_c + 1]; + if (r1r2 == b1b2) { + /* The first two word digits is the same */ + ind_b = 2; + ind_a = ind_c + 2; + while (ind_b < word_b) { + if (r->frac[ind_a] < b->frac[ind_b]) goto div_b1p1; + if (r->frac[ind_a] > b->frac[ind_b]) break; + ++ind_a; + ++ind_b; + } + /* The first few word digits of r and b is the same and */ + /* the first different word digit of w is greater than that */ + /* of b, so quotient is 1 and just subtract b from r. */ + borrow = 0; /* quotient=1, then just r-b */ + ind_b = b->Prec - 1; + ind_r = ind_c + ind_b; + if (ind_r >= word_r) goto space_error; + n = ind_b; + for (i = 0; i <= n; ++i) { + if (r->frac[ind_r] < b->frac[ind_b] + borrow) { + r->frac[ind_r] += (BASE - (b->frac[ind_b] + borrow)); + borrow = 1; + } + else { + r->frac[ind_r] = r->frac[ind_r] - b->frac[ind_b] - borrow; + borrow = 0; + } + --ind_r; + --ind_b; + } + ++c->frac[ind_c]; + goto carry; + } + /* The first two word digits is not the same, */ + /* then compare magnitude, and divide actually. */ + if (r1r2 >= b1b2p1) { + q = r1r2 / b1b2p1; /* q == (DECDIG)q */ + c->frac[ind_c] += (DECDIG)q; + ind_r = b->Prec + ind_c - 1; + goto sub_mult; + } + +div_b1p1: + if (ind_c + 1 >= word_c) goto out_side; + q = r1r2 / b1p1; /* q == (DECDIG)q */ + c->frac[ind_c + 1] += (DECDIG)q; + ind_r = b->Prec + ind_c; + +sub_mult: + borrow1 = borrow2 = 0; + ind_b = word_b - 1; + if (ind_r >= word_r) goto space_error; + n = ind_b; + for (i = 0; i <= n; ++i) { + /* now, perform r = r - q * b */ + qb = q * b->frac[ind_b]; + if (qb < BASE) borrow1 = 0; + else { + borrow1 = (DECDIG)(qb / BASE); + qb -= (DECDIG_DBL)borrow1 * BASE; /* get qb < BASE */ + } + if(r->frac[ind_r] < qb) { + r->frac[ind_r] += (DECDIG)(BASE - qb); + borrow2 = borrow2 + borrow1 + 1; + } + else { + r->frac[ind_r] -= (DECDIG)qb; + borrow2 += borrow1; + } + if (borrow2) { + if(r->frac[ind_r - 1] < borrow2) { + r->frac[ind_r - 1] += (BASE - borrow2); + borrow2 = 1; + } + else { + r->frac[ind_r - 1] -= borrow2; + borrow2 = 0; + } + } + --ind_r; + --ind_b; + } + + r->frac[ind_r] -= borrow2; +carry: + ind_r = ind_c; + while (c->frac[ind_r] >= BASE) { + c->frac[ind_r] -= BASE; + --ind_r; + ++c->frac[ind_r]; + } + } + /* End of operation, now final arrangement */ +out_side: + c->Prec = word_c; + c->exponent = a->exponent; + if (!AddExponent(c, 2)) return 0; + if (!AddExponent(c, -(b->exponent))) return 0; + + VpSetSign(c, VpGetSign(a) * VpGetSign(b)); + VpNmlz(c); /* normalize c */ + r->Prec = word_r; + r->exponent = a->exponent; + if (!AddExponent(r, 1)) return 0; + VpSetSign(r, VpGetSign(a)); + VpNmlz(r); /* normalize r(remainder) */ + goto Exit; + +space_error: +#ifdef BIGDECIMAL_DEBUG + if (gfDebug) { + printf(" word_a=%"PRIuSIZE"\n", word_a); + printf(" word_b=%"PRIuSIZE"\n", word_b); + printf(" word_c=%"PRIuSIZE"\n", word_c); + printf(" word_r=%"PRIuSIZE"\n", word_r); + printf(" ind_r =%"PRIuSIZE"\n", ind_r); + } +#endif /* BIGDECIMAL_DEBUG */ + rb_bug("ERROR(VpDivd): space for remainder too small."); + +Exit: +#ifdef BIGDECIMAL_DEBUG + if (gfDebug) { + VPrint(stdout, " VpDivd(c=a/b), c=% \n", c); + VPrint(stdout, " r=% \n", r); + } +#endif /* BIGDECIMAL_DEBUG */ + return c->Prec * BASE_FIG; +} + +/* + * Input a = 00000xxxxxxxx En(5 preceding zeros) + * Output a = xxxxxxxx En-5 + */ +static int +VpNmlz(Real *a) +{ + size_t ind_a, i; + + if (!VpIsDef(a)) goto NoVal; + if (VpIsZero(a)) goto NoVal; + + ind_a = a->Prec; + while (ind_a--) { + if (a->frac[ind_a]) { + a->Prec = ind_a + 1; + i = 0; + while (a->frac[i] == 0) ++i; /* skip the first few zeros */ + if (i) { + a->Prec -= i; + if (!AddExponent(a, -(SIGNED_VALUE)i)) return 0; + memmove(&a->frac[0], &a->frac[i], a->Prec*sizeof(DECDIG)); + } + return 1; + } + } + /* a is zero(no non-zero digit) */ + VpSetZero(a, VpGetSign(a)); + return 0; + +NoVal: + a->frac[0] = 0; + a->Prec = 1; + return 0; +} + +/* + * VpComp = 0 ... if a=b, + * Pos ... a>b, + * Neg ... asign - b->sign; + else e = a->sign; + + if (e > 0) return 1; + else if (e < 0) return -1; + else return 0; + } + if (!VpIsDef(b)) { + e = -b->sign; + if (e > 0) return 1; + else return -1; + } + /* Zero check */ + if (VpIsZero(a)) { + if (VpIsZero(b)) return 0; /* both zero */ + val = -VpGetSign(b); + goto Exit; + } + if (VpIsZero(b)) { + val = VpGetSign(a); + goto Exit; + } + + /* compare sign */ + if (VpGetSign(a) > VpGetSign(b)) { + val = 1; /* a>b */ + goto Exit; + } + if (VpGetSign(a) < VpGetSign(b)) { + val = -1; /* aexponent > b->exponent) { + val = VpGetSign(a); + goto Exit; + } + if (a->exponent < b->exponent) { + val = -VpGetSign(b); + goto Exit; + } + + /* a and b have same exponent, then compare their significand. */ + mx = (a->Prec < b->Prec) ? a->Prec : b->Prec; + ind = 0; + while (ind < mx) { + if (a->frac[ind] > b->frac[ind]) { + val = VpGetSign(a); + goto Exit; + } + if (a->frac[ind] < b->frac[ind]) { + val = -VpGetSign(b); + goto Exit; + } + ++ind; + } + if (a->Prec > b->Prec) { + val = VpGetSign(a); + } + else if (a->Prec < b->Prec) { + val = -VpGetSign(b); + } + +Exit: + if (val > 1) val = 1; + else if (val < -1) val = -1; + +#ifdef BIGDECIMAL_DEBUG + if (gfDebug) { + VPrint(stdout, " VpComp a=%\n", a); + VPrint(stdout, " b=%\n", b); + printf(" ans=%d\n", val); + } +#endif /* BIGDECIMAL_DEBUG */ + return (int)val; +} + +/* + * cntl_chr ... ASCIIZ Character, print control characters + * Available control codes: + * % ... VP variable. To print '%', use '%%'. + * \n ... new line + * \b ... backspace + * \t ... tab + * Note: % must not appear more than once + * a ... VP variable to be printed + */ +static int +VPrint(FILE *fp, const char *cntl_chr, Real *a) +{ + size_t i, j, nc, nd, ZeroSup, sep = 10; + DECDIG m, e, nn; + + j = 0; + nd = nc = 0; /* nd : number of digits in fraction part(every 10 digits, */ + /* nd<=10). */ + /* nc : number of characters printed */ + ZeroSup = 1; /* Flag not to print the leading zeros as 0.00xxxxEnn */ + while (*(cntl_chr + j)) { + if (*(cntl_chr + j) == '%' && *(cntl_chr + j + 1) != '%') { + nc = 0; + if (VpIsNaN(a)) { + fprintf(fp, SZ_NaN); + nc += 8; + } + else if (VpIsPosInf(a)) { + fprintf(fp, SZ_INF); + nc += 8; + } + else if (VpIsNegInf(a)) { + fprintf(fp, SZ_NINF); + nc += 9; + } + else if (!VpIsZero(a)) { + if (BIGDECIMAL_NEGATIVE_P(a)) { + fprintf(fp, "-"); + ++nc; + } + nc += fprintf(fp, "0."); + switch (*(cntl_chr + j + 1)) { + default: + break; + + case '0': case 'z': + ZeroSup = 0; + ++j; + sep = cntl_chr[j] == 'z' ? BIGDECIMAL_COMPONENT_FIGURES : 10; + break; + } + for (i = 0; i < a->Prec; ++i) { + m = BASE1; + e = a->frac[i]; + while (m) { + nn = e / m; + if (!ZeroSup || nn) { + nc += fprintf(fp, "%lu", (unsigned long)nn); /* The leading zero(s) */ + /* as 0.00xx will not */ + /* be printed. */ + ++nd; + ZeroSup = 0; /* Set to print succeeding zeros */ + } + if (nd >= sep) { /* print ' ' after every 10 digits */ + nd = 0; + nc += fprintf(fp, " "); + } + e = e - nn * m; + m /= 10; + } + } + nc += fprintf(fp, "E%"PRIdSIZE, VpExponent10(a)); + nc += fprintf(fp, " (%"PRIdVALUE", %"PRIuSIZE", %"PRIuSIZE")", a->exponent, a->Prec, a->MaxPrec); + } + else { + nc += fprintf(fp, "0.0"); + } + } + else { + ++nc; + if (*(cntl_chr + j) == '\\') { + switch (*(cntl_chr + j + 1)) { + case 'n': + fprintf(fp, "\n"); + ++j; + break; + case 't': + fprintf(fp, "\t"); + ++j; + break; + case 'b': + fprintf(fp, "\n"); + ++j; + break; + default: + fprintf(fp, "%c", *(cntl_chr + j)); + break; + } + } + else { + fprintf(fp, "%c", *(cntl_chr + j)); + if (*(cntl_chr + j) == '%') ++j; + } + } + j++; + } + + return (int)nc; +} + +static void +VpFormatSt(char *psz, size_t fFmt) +{ + size_t ie, i, nf = 0; + char ch; + + if (fFmt == 0) return; + + ie = strlen(psz); + for (i = 0; i < ie; ++i) { + ch = psz[i]; + if (!ch) break; + if (ISSPACE(ch) || ch=='-' || ch=='+') continue; + if (ch == '.') { nf = 0; continue; } + if (ch == 'E' || ch == 'e') break; + + if (++nf > fFmt) { + memmove(psz + i + 1, psz + i, ie - i + 1); + ++ie; + nf = 0; + psz[i] = ' '; + } + } +} + +VP_EXPORT ssize_t +VpExponent10(Real *a) +{ + ssize_t ex; + size_t n; + + if (!VpHasVal(a)) return 0; + + ex = a->exponent * (ssize_t)BASE_FIG; + n = BASE1; + while ((a->frac[0] / n) == 0) { + --ex; + n /= 10; + } + return ex; +} + +VP_EXPORT void +VpSzMantissa(Real *a, char *buf, size_t buflen) +{ + size_t i, n, ZeroSup; + DECDIG_DBL m, e, nn; + + if (VpIsNaN(a)) { + snprintf(buf, buflen, SZ_NaN); + return; + } + if (VpIsPosInf(a)) { + snprintf(buf, buflen, SZ_INF); + return; + } + if (VpIsNegInf(a)) { + snprintf(buf, buflen, SZ_NINF); + return; + } + + ZeroSup = 1; /* Flag not to print the leading zeros as 0.00xxxxEnn */ + if (!VpIsZero(a)) { + if (BIGDECIMAL_NEGATIVE_P(a)) *buf++ = '-'; + n = a->Prec; + for (i = 0; i < n; ++i) { + m = BASE1; + e = a->frac[i]; + while (m) { + nn = e / m; + if (!ZeroSup || nn) { + snprintf(buf, buflen, "%lu", (unsigned long)nn); /* The leading zero(s) */ + buf += strlen(buf); + /* as 0.00xx will be ignored. */ + ZeroSup = 0; /* Set to print succeeding zeros */ + } + e = e - nn * m; + m /= 10; + } + } + *buf = 0; + while (buf[-1] == '0') *(--buf) = 0; + } + else { + if (VpIsPosZero(a)) snprintf(buf, buflen, "0"); + else snprintf(buf, buflen, "-0"); + } +} + +VP_EXPORT int +VpToSpecialString(Real *a, char *buf, size_t buflen, int fPlus) +/* fPlus = 0: default, 1: set ' ' before digits, 2: set '+' before digits. */ +{ + if (VpIsNaN(a)) { + snprintf(buf, buflen, SZ_NaN); + return 1; + } + + if (VpIsPosInf(a)) { + if (fPlus == 1) { + *buf++ = ' '; + } + else if (fPlus == 2) { + *buf++ = '+'; + } + snprintf(buf, buflen, SZ_INF); + return 1; + } + if (VpIsNegInf(a)) { + snprintf(buf, buflen, SZ_NINF); + return 1; + } + if (VpIsZero(a)) { + if (VpIsPosZero(a)) { + if (fPlus == 1) snprintf(buf, buflen, " 0.0"); + else if (fPlus == 2) snprintf(buf, buflen, "+0.0"); + else snprintf(buf, buflen, "0.0"); + } + else snprintf(buf, buflen, "-0.0"); + return 1; + } + return 0; +} + +VP_EXPORT void +VpToString(Real *a, char *buf, size_t buflen, size_t fFmt, int fPlus) +/* fPlus = 0: default, 1: set ' ' before digits, 2: set '+' before digits. */ +{ + size_t i, n, ZeroSup; + DECDIG shift, m, e, nn; + char *p = buf; + size_t plen = buflen; + ssize_t ex; + + if (VpToSpecialString(a, buf, buflen, fPlus)) return; + + ZeroSup = 1; /* Flag not to print the leading zeros as 0.00xxxxEnn */ + +#define ADVANCE(n) do { \ + if (plen < n) goto overflow; \ + p += n; \ + plen -= n; \ +} while (0) + + if (BIGDECIMAL_NEGATIVE_P(a)) { + *p = '-'; + ADVANCE(1); + } + else if (fPlus == 1) { + *p = ' '; + ADVANCE(1); + } + else if (fPlus == 2) { + *p = '+'; + ADVANCE(1); + } + + *p = '0'; ADVANCE(1); + *p = '.'; ADVANCE(1); + + n = a->Prec; + for (i = 0; i < n; ++i) { + m = BASE1; + e = a->frac[i]; + while (m) { + nn = e / m; + if (!ZeroSup || nn) { + /* The reading zero(s) */ + size_t n = (size_t)snprintf(p, plen, "%lu", (unsigned long)nn); + if (n > plen) goto overflow; + ADVANCE(n); + /* as 0.00xx will be ignored. */ + ZeroSup = 0; /* Set to print succeeding zeros */ + } + e = e - nn * m; + m /= 10; + } + } + + ex = a->exponent * (ssize_t)BASE_FIG; + shift = BASE1; + while (a->frac[0] / shift == 0) { + --ex; + shift /= 10; + } + while (p - 1 > buf && p[-1] == '0') { + *(--p) = '\0'; + ++plen; + } + snprintf(p, plen, "e%"PRIdSIZE, ex); + if (fFmt) VpFormatSt(buf, fFmt); + + overflow: + return; +#undef ADVANCE +} + +VP_EXPORT void +VpToFString(Real *a, char *buf, size_t buflen, size_t fFmt, int fPlus) +/* fPlus = 0: default, 1: set ' ' before digits, 2: set '+' before digits. */ +{ + size_t i, n; + DECDIG m, e; + char *p = buf; + size_t plen = buflen, delim = fFmt; + ssize_t ex; + + if (VpToSpecialString(a, buf, buflen, fPlus)) return; + +#define APPEND(c, group) do { \ + if (plen < 1) goto overflow; \ + if (group && delim == 0) { \ + *p = ' '; \ + p += 1; \ + plen -= 1; \ + } \ + if (plen < 1) goto overflow; \ + *p = c; \ + p += 1; \ + plen -= 1; \ + if (group) delim = (delim + 1) % fFmt; \ +} while (0) + + + if (BIGDECIMAL_NEGATIVE_P(a)) { + APPEND('-', false); + } + else if (fPlus == 1) { + APPEND(' ', false); + } + else if (fPlus == 2) { + APPEND('+', false); + } + + n = a->Prec; + ex = a->exponent; + if (ex <= 0) { + APPEND('0', false); + APPEND('.', false); + } + while (ex < 0) { + for (i=0; i < BASE_FIG; ++i) { + APPEND('0', fFmt > 0); + } + ++ex; + } + + for (i = 0; i < n; ++i) { + m = BASE1; + e = a->frac[i]; + if (i == 0 && ex > 0) { + for (delim = 0; e / m == 0; delim++) { + m /= 10; + } + if (fFmt > 0) { + delim = 2*fFmt - (ex * BASE_FIG - delim) % fFmt; + } + } + while (m && (e || (i < n - 1) || ex > 0)) { + APPEND((char)(e / m + '0'), fFmt > 0); + e %= m; + m /= 10; + } + if (--ex == 0) { + APPEND('.', false); + delim = fFmt; + } + } + + while (ex > 0) { + for (i=0; i < BASE_FIG; ++i) { + APPEND('0', fFmt > 0); + } + if (--ex == 0) { + APPEND('.', false); + } + } + + *p = '\0'; + if (p - 1 > buf && p[-1] == '.') { + snprintf(p, plen, "0"); + } + + overflow: + return; +#undef APPEND +} + +/* + * [Output] + * a[] ... variable to be assigned the value. + * [Input] + * int_chr[] ... integer part(may include '+/-'). + * ni ... number of characters in int_chr[],not including '+/-'. + * frac[] ... fraction part. + * nf ... number of characters in frac[]. + * exp_chr[] ... exponent part(including '+/-'). + * ne ... number of characters in exp_chr[],not including '+/-'. + */ +VP_EXPORT int +VpCtoV(Real *a, const char *int_chr, size_t ni, const char *frac, size_t nf, const char *exp_chr, size_t ne) +{ + size_t i, j, ind_a, ma, mi, me; + SIGNED_VALUE e, es, eb, ef; + int sign, signe, exponent_overflow; + + /* get exponent part */ + e = 0; + ma = a->MaxPrec; + mi = ni; + me = ne; + signe = 1; + exponent_overflow = 0; + memset(a->frac, 0, ma * sizeof(DECDIG)); + if (ne > 0) { + i = 0; + if (exp_chr[0] == '-') { + signe = -1; + ++i; + ++me; + } + else if (exp_chr[0] == '+') { + ++i; + ++me; + } + while (i < me) { + if (MUL_OVERFLOW_SIGNED_VALUE_P(e, (SIGNED_VALUE)BASE_FIG)) { + es = e; + goto exp_overflow; + } + es = e * (SIGNED_VALUE)BASE_FIG; + if (MUL_OVERFLOW_SIGNED_VALUE_P(e, 10) || + SIGNED_VALUE_MAX - (exp_chr[i] - '0') < e * 10) + goto exp_overflow; + e = e * 10 + exp_chr[i] - '0'; + if (MUL_OVERFLOW_SIGNED_VALUE_P(e, (SIGNED_VALUE)BASE_FIG)) + goto exp_overflow; + if (es > (SIGNED_VALUE)(e * BASE_FIG)) { + exp_overflow: + exponent_overflow = 1; + e = es; /* keep sign */ + break; + } + ++i; + } + } + + /* get integer part */ + i = 0; + sign = 1; + if (1 /*ni >= 0*/) { + if (int_chr[0] == '-') { + sign = -1; + ++i; + ++mi; + } + else if (int_chr[0] == '+') { + ++i; + ++mi; + } + } + + e = signe * e; /* e: The value of exponent part. */ + e = e + ni; /* set actual exponent size. */ + + if (e > 0) signe = 1; + else signe = -1; + + /* Adjust the exponent so that it is the multiple of BASE_FIG. */ + j = 0; + ef = 1; + while (ef) { + if (e >= 0) eb = e; + else eb = -e; + ef = eb / (SIGNED_VALUE)BASE_FIG; + ef = eb - ef * (SIGNED_VALUE)BASE_FIG; + if (ef) { + ++j; /* Means to add one more preceding zero */ + ++e; + } + } + + eb = e / (SIGNED_VALUE)BASE_FIG; + + if (exponent_overflow) { + int zero = 1; + for ( ; i < mi && zero; i++) zero = int_chr[i] == '0'; + for (i = 0; i < nf && zero; i++) zero = frac[i] == '0'; + if (!zero && signe > 0) { + VpSetInf(a, sign); + VpException(VP_EXCEPTION_INFINITY, "exponent overflow",0); + } + else VpSetZero(a, sign); + return 1; + } + + ind_a = 0; + while (i < mi) { + a->frac[ind_a] = 0; + while (j < BASE_FIG && i < mi) { + a->frac[ind_a] = a->frac[ind_a] * 10 + int_chr[i] - '0'; + ++j; + ++i; + } + if (i < mi) { + ++ind_a; + if (ind_a >= ma) goto over_flow; + j = 0; + } + } + + /* get fraction part */ + + i = 0; + while (i < nf) { + while (j < BASE_FIG && i < nf) { + a->frac[ind_a] = a->frac[ind_a] * 10 + frac[i] - '0'; + ++j; + ++i; + } + if (i < nf) { + ++ind_a; + if (ind_a >= ma) goto over_flow; + j = 0; + } + } + goto Final; + +over_flow: + rb_warn("Conversion from String to BigDecimal overflow (last few digits discarded)."); + +Final: + if (ind_a >= ma) ind_a = ma - 1; + while (j < BASE_FIG) { + a->frac[ind_a] = a->frac[ind_a] * 10; + ++j; + } + a->Prec = ind_a + 1; + a->exponent = eb; + VpSetSign(a, sign); + VpNmlz(a); + return 1; +} + +/* + * [Input] + * *m ... Real + * [Output] + * *d ... fraction part of m(d = 0.xxxxxxx). where # of 'x's is fig. + * *e ... exponent of m. + * BIGDECIMAL_DOUBLE_FIGURES ... Number of digits in a double variable. + * + * m -> d*10**e, 0Prec); + *d = 0.0; + div = 1.; + while (ind_m < mm) { + div /= (double)BASE; + *d = *d + (double)m->frac[ind_m++] * div; + } + *e = m->exponent * (SIGNED_VALUE)BASE_FIG; + *d *= VpGetSign(m); + +Exit: +#ifdef BIGDECIMAL_DEBUG + if (gfDebug) { + VPrint(stdout, " VpVtoD: m=%\n", m); + printf(" d=%e * 10 **%ld\n", *d, *e); + printf(" BIGDECIMAL_DOUBLE_FIGURES = %d\n", BIGDECIMAL_DOUBLE_FIGURES); + } +#endif /*BIGDECIMAL_DEBUG */ + return f; +} + +/* + * m <- d + */ +VP_EXPORT void +VpDtoV(Real *m, double d) +{ + size_t ind_m, mm; + SIGNED_VALUE ne; + DECDIG i; + double val, val2; + + if (isnan(d)) { + VpSetNaN(m); + goto Exit; + } + if (isinf(d)) { + if (d > 0.0) VpSetPosInf(m); + else VpSetNegInf(m); + goto Exit; + } + + if (d == 0.0) { + VpSetZero(m, 1); + goto Exit; + } + val = (d > 0.) ? d : -d; + ne = 0; + if (val >= 1.0) { + while (val >= 1.0) { + val /= (double)BASE; + ++ne; + } + } + else { + val2 = 1.0 / (double)BASE; + while (val < val2) { + val *= (double)BASE; + --ne; + } + } + /* Now val = 0.xxxxx*BASE**ne */ + + mm = m->MaxPrec; + memset(m->frac, 0, mm * sizeof(DECDIG)); + for (ind_m = 0; val > 0.0 && ind_m < mm; ind_m++) { + val *= (double)BASE; + i = (DECDIG)val; + val -= (double)i; + m->frac[ind_m] = i; + } + if (ind_m >= mm) ind_m = mm - 1; + VpSetSign(m, (d > 0.0) ? 1 : -1); + m->Prec = ind_m + 1; + m->exponent = ne; + + VpInternalRound(m, 0, (m->Prec > 0) ? m->frac[m->Prec-1] : 0, + (DECDIG)(val*(double)BASE)); + +Exit: +#ifdef BIGDECIMAL_DEBUG + if (gfDebug) { + printf("VpDtoV d=%30.30e\n", d); + VPrint(stdout, " m=%\n", m); + } +#endif /* BIGDECIMAL_DEBUG */ + return; +} + +/* + * m <- ival + */ +#if 0 /* unused */ +VP_EXPORT void +VpItoV(Real *m, SIGNED_VALUE ival) +{ + size_t mm, ind_m; + size_t val, v1, v2, v; + int isign; + SIGNED_VALUE ne; + + if (ival == 0) { + VpSetZero(m, 1); + goto Exit; + } + isign = 1; + val = ival; + if (ival < 0) { + isign = -1; + val =(size_t)(-ival); + } + ne = 0; + ind_m = 0; + mm = m->MaxPrec; + while (ind_m < mm) { + m->frac[ind_m] = 0; + ++ind_m; + } + ind_m = 0; + while (val > 0) { + if (val) { + v1 = val; + v2 = 1; + while (v1 >= BASE) { + v1 /= BASE; + v2 *= BASE; + } + val = val - v2 * v1; + v = v1; + } + else { + v = 0; + } + m->frac[ind_m] = v; + ++ind_m; + ++ne; + } + m->Prec = ind_m - 1; + m->exponent = ne; + VpSetSign(m, isign); + VpNmlz(m); + +Exit: +#ifdef BIGDECIMAL_DEBUG + if (gfDebug) { + printf(" VpItoV i=%d\n", ival); + VPrint(stdout, " m=%\n", m); + } +#endif /* BIGDECIMAL_DEBUG */ + return; +} +#endif + +/* + * y = SQRT(x), y*y - x =>0 + */ +VP_EXPORT int +VpSqrt(Real *y, Real *x) +{ + Real *f = NULL; + Real *r = NULL; + size_t y_prec; + SIGNED_VALUE n, e; + ssize_t nr; + double val; + + /* Zero or +Infinity ? */ + if (VpIsZero(x) || VpIsPosInf(x)) { + VpAsgn(y,x,1); + goto Exit; + } + + /* Negative ? */ + if (BIGDECIMAL_NEGATIVE_P(x)) { + VpSetNaN(y); + return VpException(VP_EXCEPTION_OP, "sqrt of negative value", 0); + } + + /* NaN ? */ + if (VpIsNaN(x)) { + VpSetNaN(y); + return VpException(VP_EXCEPTION_OP, "sqrt of 'NaN'(Not a Number)", 0); + } + + /* One ? */ + if (VpIsOne(x)) { + VpSetOne(y); + goto Exit; + } + + n = (SIGNED_VALUE)y->MaxPrec; + if (x->MaxPrec > (size_t)n) n = (ssize_t)x->MaxPrec; + + /* allocate temporally variables */ + /* TODO: reconsider MaxPrec of f and r */ + f = NewOneNolimit(1, y->MaxPrec * (BASE_FIG + 2)); + r = NewOneNolimit(1, (n + n) * (BASE_FIG + 2)); + + nr = 0; + y_prec = y->MaxPrec; + + VpVtoD(&val, &e, x); /* val <- x */ + e /= (SIGNED_VALUE)BASE_FIG; + n = e / 2; + if (e - n * 2 != 0) { + val /= BASE; + n = (e + 1) / 2; + } + VpDtoV(y, sqrt(val)); /* y <- sqrt(val) */ + y->exponent += n; + n = (SIGNED_VALUE)roomof(BIGDECIMAL_DOUBLE_FIGURES, BASE_FIG); + y->MaxPrec = Min((size_t)n , y_prec); + f->MaxPrec = y->MaxPrec + 1; + n = (SIGNED_VALUE)(y_prec * BASE_FIG); + if (n > (SIGNED_VALUE)maxnr) n = (SIGNED_VALUE)maxnr; + + /* + * Perform: y_{n+1} = (y_n - x/y_n) / 2 + */ + do { + y->MaxPrec *= 2; + if (y->MaxPrec > y_prec) y->MaxPrec = y_prec; + f->MaxPrec = y->MaxPrec; + VpDivd(f, r, x, y); /* f = x/y */ + VpAddSub(r, f, y, -1); /* r = f - y */ + VpMult(f, VpConstPt5, r); /* f = 0.5*r */ + if (VpIsZero(f)) + goto converge; + VpAddSub(r, f, y, 1); /* r = y + f */ + VpAsgn(y, r, 1); /* y = r */ + } while (++nr < n); + +#ifdef BIGDECIMAL_DEBUG + if (gfDebug) { + printf("ERROR(VpSqrt): did not converge within %ld iterations.\n", nr); + } +#endif /* BIGDECIMAL_DEBUG */ + y->MaxPrec = y_prec; + +converge: + VpChangeSign(y, 1); +#ifdef BIGDECIMAL_DEBUG + if (gfDebug) { + VpMult(r, y, y); + VpAddSub(f, x, r, -1); + printf("VpSqrt: iterations = %"PRIdSIZE"\n", nr); + VPrint(stdout, " y =% \n", y); + VPrint(stdout, " x =% \n", x); + VPrint(stdout, " x-y*y = % \n", f); + } +#endif /* BIGDECIMAL_DEBUG */ + y->MaxPrec = y_prec; + +Exit: + rbd_free_struct(f); + rbd_free_struct(r); + return 1; +} + +/* + * Round relatively from the decimal point. + * f: rounding mode + * nf: digit location to round from the decimal point. + */ +VP_EXPORT int +VpMidRound(Real *y, unsigned short f, ssize_t nf) +{ + /* fracf: any positive digit under rounding position? */ + /* fracf_1further: any positive digits under one further than the rounding position? */ + /* exptoadd: number of digits needed to compensate negative nf */ + int fracf, fracf_1further; + ssize_t n,i,ix,ioffset, exptoadd; + DECDIG v, shifter; + DECDIG div; + + nf += y->exponent * (ssize_t)BASE_FIG; + exptoadd=0; + if (nf < 0) { + /* rounding position too left(large). */ + if (f != VP_ROUND_CEIL && f != VP_ROUND_FLOOR) { + VpSetZero(y, VpGetSign(y)); /* truncate everything */ + return 0; + } + exptoadd = -nf; + nf = 0; + } + + ix = nf / (ssize_t)BASE_FIG; + if ((size_t)ix >= y->Prec) return 0; /* rounding position too right(small). */ + v = y->frac[ix]; + + ioffset = nf - ix*(ssize_t)BASE_FIG; + n = (ssize_t)BASE_FIG - ioffset - 1; + for (shifter = 1, i = 0; i < n; ++i) shifter *= 10; + + /* so the representation used (in y->frac) is an array of DECDIG, where + each DECDIG contains a value between 0 and BASE-1, consisting of BASE_FIG + decimal places. + + (that numbers of decimal places are typed as ssize_t is somewhat confusing) + + nf is now position (in decimal places) of the digit from the start of + the array. + + ix is the position (in DECDIGs) of the DECDIG containing the decimal digit, + from the start of the array. + + v is the value of this DECDIG + + ioffset is the number of extra decimal places along of this decimal digit + within v. + + n is the number of decimal digits remaining within v after this decimal digit + shifter is 10**n, + + v % shifter are the remaining digits within v + v % (shifter * 10) are the digit together with the remaining digits within v + v / shifter are the digit's predecessors together with the digit + div = v / shifter / 10 is just the digit's precessors + (v / shifter) - div*10 is just the digit, which is what v ends up being reassigned to. + */ + + fracf = (v % (shifter * 10) > 0); + fracf_1further = ((v % shifter) > 0); + + v /= shifter; + div = v / 10; + v = v - div*10; + /* now v is just the digit required. + now fracf is whether the digit or any of the remaining digits within v are non-zero + now fracf_1further is whether any of the remaining digits within v are non-zero + */ + + /* now check all the remaining DECDIGs for zero-ness a whole DECDIG at a time. + if we spot any non-zeroness, that means that we found a positive digit under + rounding position, and we also found a positive digit under one further than + the rounding position, so both searches (to see if any such non-zero digit exists) + can stop */ + + for (i = ix + 1; (size_t)i < y->Prec; i++) { + if (y->frac[i] % BASE) { + fracf = fracf_1further = 1; + break; + } + } + + /* now fracf = does any positive digit exist under the rounding position? + now fracf_1further = does any positive digit exist under one further than the + rounding position? + now v = the first digit under the rounding position */ + + /* drop digits after pointed digit */ + memset(y->frac + ix + 1, 0, (y->Prec - (ix + 1)) * sizeof(DECDIG)); + + switch (f) { + case VP_ROUND_DOWN: /* Truncate */ + break; + case VP_ROUND_UP: /* Roundup */ + if (fracf) ++div; + break; + case VP_ROUND_HALF_UP: + if (v>=5) ++div; + break; + case VP_ROUND_HALF_DOWN: + if (v > 5 || (v == 5 && fracf_1further)) ++div; + break; + case VP_ROUND_CEIL: + if (fracf && BIGDECIMAL_POSITIVE_P(y)) ++div; + break; + case VP_ROUND_FLOOR: + if (fracf && BIGDECIMAL_NEGATIVE_P(y)) ++div; + break; + case VP_ROUND_HALF_EVEN: /* Banker's rounding */ + if (v > 5) ++div; + else if (v == 5) { + if (fracf_1further) { + ++div; + } + else { + if (ioffset == 0) { + /* v is the first decimal digit of its DECDIG; + need to grab the previous DECDIG if present + to check for evenness of the previous decimal + digit (which is same as that of the DECDIG since + base 10 has a factor of 2) */ + if (ix && (y->frac[ix-1] % 2)) ++div; + } + else { + if (div % 2) ++div; + } + } + } + break; + } + for (i = 0; i <= n; ++i) div *= 10; + if (div >= BASE) { + if (ix) { + y->frac[ix] = 0; + VpRdup(y, ix); + } + else { + short s = VpGetSign(y); + SIGNED_VALUE e = y->exponent; + VpSetOne(y); + VpSetSign(y, s); + y->exponent = e + 1; + } + } + else { + y->frac[ix] = div; + VpNmlz(y); + } + if (exptoadd > 0) { + y->exponent += (SIGNED_VALUE)(exptoadd / BASE_FIG); + exptoadd %= (ssize_t)BASE_FIG; + for (i = 0; i < exptoadd; i++) { + y->frac[0] *= 10; + if (y->frac[0] >= BASE) { + y->frac[0] /= BASE; + y->exponent++; + } + } + } + return 1; +} + +VP_EXPORT int +VpLeftRound(Real *y, unsigned short f, ssize_t nf) +/* + * Round from the left hand side of the digits. + */ +{ + DECDIG v; + if (!VpHasVal(y)) return 0; /* Unable to round */ + v = y->frac[0]; + nf -= VpExponent(y) * (ssize_t)BASE_FIG; + while ((v /= 10) != 0) nf--; + nf += (ssize_t)BASE_FIG-1; + return VpMidRound(y, f, nf); +} + +VP_EXPORT int +VpActiveRound(Real *y, Real *x, unsigned short f, ssize_t nf) +{ + /* First,assign whole value in truncation mode */ + if (VpAsgn(y, x, 10) <= 1) return 0; /* Zero,NaN,or Infinity */ + return VpMidRound(y, f, nf); +} + +static int +VpLimitRound(Real *c, size_t ixDigit) +{ + size_t ix = VpGetPrecLimit(); + if (!VpNmlz(c)) return -1; + if (!ix) return 0; + if (!ixDigit) ixDigit = c->Prec-1; + if ((ix + BASE_FIG - 1) / BASE_FIG > ixDigit + 1) return 0; + return VpLeftRound(c, VpGetRoundMode(), (ssize_t)ix); +} + +/* If I understand correctly, this is only ever used to round off the final decimal + digit of precision */ +static void +VpInternalRound(Real *c, size_t ixDigit, DECDIG vPrev, DECDIG v) +{ + int f = 0; + + unsigned short const rounding_mode = VpGetRoundMode(); + + if (VpLimitRound(c, ixDigit)) return; + if (!v) return; + + v /= BASE1; + switch (rounding_mode) { + case VP_ROUND_DOWN: + break; + case VP_ROUND_UP: + if (v) f = 1; + break; + case VP_ROUND_HALF_UP: + if (v >= 5) f = 1; + break; + case VP_ROUND_HALF_DOWN: + /* this is ok - because this is the last digit of precision, + the case where v == 5 and some further digits are nonzero + will never occur */ + if (v >= 6) f = 1; + break; + case VP_ROUND_CEIL: + if (v && BIGDECIMAL_POSITIVE_P(c)) f = 1; + break; + case VP_ROUND_FLOOR: + if (v && BIGDECIMAL_NEGATIVE_P(c)) f = 1; + break; + case VP_ROUND_HALF_EVEN: /* Banker's rounding */ + /* as per VP_ROUND_HALF_DOWN, because this is the last digit of precision, + there is no case to worry about where v == 5 and some further digits are nonzero */ + if (v > 5) f = 1; + else if (v == 5 && vPrev % 2) f = 1; + break; + } + if (f) { + VpRdup(c, ixDigit); + VpNmlz(c); + } +} + +/* + * Rounds up m(plus one to final digit of m). + */ +static int +VpRdup(Real *m, size_t ind_m) +{ + DECDIG carry; + + if (!ind_m) ind_m = m->Prec; + + carry = 1; + while (carry > 0 && ind_m--) { + m->frac[ind_m] += carry; + if (m->frac[ind_m] >= BASE) m->frac[ind_m] -= BASE; + else carry = 0; + } + if (carry > 0) { /* Overflow,count exponent and set fraction part be 1 */ + if (!AddExponent(m, 1)) return 0; + m->Prec = m->frac[0] = 1; + } + else { + VpNmlz(m); + } + return 1; +} + +/* + * y = x - fix(x) + */ +VP_EXPORT void +VpFrac(Real *y, Real *x) +{ + size_t my, ind_y, ind_x; + + if (!VpHasVal(x)) { + VpAsgn(y, x, 1); + goto Exit; + } + + if (x->exponent > 0 && (size_t)x->exponent >= x->Prec) { + VpSetZero(y, VpGetSign(x)); + goto Exit; + } + else if (x->exponent <= 0) { + VpAsgn(y, x, 1); + goto Exit; + } + + /* satisfy: x->exponent > 0 */ + + y->Prec = x->Prec - (size_t)x->exponent; + y->Prec = Min(y->Prec, y->MaxPrec); + y->exponent = 0; + VpSetSign(y, VpGetSign(x)); + ind_y = 0; + my = y->Prec; + ind_x = x->exponent; + while (ind_y < my) { + y->frac[ind_y] = x->frac[ind_x]; + ++ind_y; + ++ind_x; + } + VpNmlz(y); + +Exit: +#ifdef BIGDECIMAL_DEBUG + if (gfDebug) { + VPrint(stdout, "VpFrac y=%\n", y); + VPrint(stdout, " x=%\n", x); + } +#endif /* BIGDECIMAL_DEBUG */ + return; +} + +/* + * y = x ** n + */ +VP_EXPORT int +VpPowerByInt(Real *y, Real *x, SIGNED_VALUE n) +{ + size_t s, ss; + ssize_t sign; + Real *w1 = NULL; + Real *w2 = NULL; + + if (VpIsZero(x)) { + if (n == 0) { + VpSetOne(y); + goto Exit; + } + sign = VpGetSign(x); + if (n < 0) { + n = -n; + if (sign < 0) sign = (n % 2) ? -1 : 1; + VpSetInf(y, sign); + } + else { + if (sign < 0) sign = (n % 2) ? -1 : 1; + VpSetZero(y,sign); + } + goto Exit; + } + if (VpIsNaN(x)) { + VpSetNaN(y); + goto Exit; + } + if (VpIsInf(x)) { + if (n == 0) { + VpSetOne(y); + goto Exit; + } + if (n > 0) { + VpSetInf(y, (n % 2 == 0 || VpIsPosInf(x)) ? 1 : -1); + goto Exit; + } + VpSetZero(y, (n % 2 == 0 || VpIsPosInf(x)) ? 1 : -1); + goto Exit; + } + + if (x->exponent == 1 && x->Prec == 1 && x->frac[0] == 1) { + /* abs(x) = 1 */ + VpSetOne(y); + if (BIGDECIMAL_POSITIVE_P(x)) goto Exit; + if ((n % 2) == 0) goto Exit; + VpSetSign(y, -1); + goto Exit; + } + + if (n > 0) sign = 1; + else if (n < 0) { + sign = -1; + n = -n; + } + else { + VpSetOne(y); + goto Exit; + } + + /* Allocate working variables */ + /* TODO: reconsider MaxPrec of w1 and w2 */ + w1 = NewZeroNolimit(1, (y->MaxPrec + 2) * BASE_FIG); + w2 = NewZeroNolimit(1, (w1->MaxPrec * 2 + 1) * BASE_FIG); + + /* calculation start */ + + VpAsgn(y, x, 1); + --n; + while (n > 0) { + VpAsgn(w1, x, 1); + s = 1; + while (ss = s, (s += s) <= (size_t)n) { + VpMult(w2, w1, w1); + VpAsgn(w1, w2, 1); + } + n -= (SIGNED_VALUE)ss; + VpMult(w2, y, w1); + VpAsgn(y, w2, 1); + } + if (sign < 0) { + VpDivd(w1, w2, VpConstOne, y); + VpAsgn(y, w1, 1); + } + +Exit: +#ifdef BIGDECIMAL_DEBUG + if (gfDebug) { + VPrint(stdout, "VpPowerByInt y=%\n", y); + VPrint(stdout, "VpPowerByInt x=%\n", x); + printf(" n=%"PRIdVALUE"\n", n); + } +#endif /* BIGDECIMAL_DEBUG */ + rbd_free_struct(w2); + rbd_free_struct(w1); + return 1; +} + +#ifdef BIGDECIMAL_DEBUG +int +VpVarCheck(Real * v) +/* + * Checks the validity of the Real variable v. + * [Input] + * v ... Real *, variable to be checked. + * [Returns] + * 0 ... correct v. + * other ... error + */ +{ + size_t i; + + if (v->MaxPrec == 0) { + printf("ERROR(VpVarCheck): Illegal Max. Precision(=%"PRIuSIZE")\n", + v->MaxPrec); + return 1; + } + if (v->Prec == 0 || v->Prec > v->MaxPrec) { + printf("ERROR(VpVarCheck): Illegal Precision(=%"PRIuSIZE")\n", v->Prec); + printf(" Max. Prec.=%"PRIuSIZE"\n", v->MaxPrec); + return 2; + } + for (i = 0; i < v->Prec; ++i) { + if (v->frac[i] >= BASE) { + printf("ERROR(VpVarCheck): Illegal fraction\n"); + printf(" Frac[%"PRIuSIZE"]=%"PRIuDECDIG"\n", i, v->frac[i]); + printf(" Prec. =%"PRIuSIZE"\n", v->Prec); + printf(" Exp. =%"PRIdVALUE"\n", v->exponent); + printf(" BASE =%"PRIuDECDIG"\n", BASE); + return 3; + } + } + return 0; +} +#endif /* BIGDECIMAL_DEBUG */ diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/bigdecimal.h b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/bigdecimal.h new file mode 100644 index 00000000..54fed811 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/bigdecimal.h @@ -0,0 +1,313 @@ +/* + * + * Ruby BigDecimal(Variable decimal precision) extension library. + * + * Copyright(C) 2002 by Shigeo Kobayashi(shigeo@tinyforest.gr.jp) + * + */ + +#ifndef RUBY_BIG_DECIMAL_H +#define RUBY_BIG_DECIMAL_H 1 + +#define RUBY_NO_OLD_COMPATIBILITY +#include "ruby/ruby.h" +#include "missing.h" + +#ifdef HAVE_FLOAT_H +# include +#endif + +#ifdef HAVE_INT64_T +# define DECDIG uint32_t +# define DECDIG_DBL uint64_t +# define DECDIG_DBL_SIGNED int64_t +# define SIZEOF_DECDIG 4 +# define PRI_DECDIG_PREFIX "" +# ifdef PRI_LL_PREFIX +# define PRI_DECDIG_DBL_PREFIX PRI_LL_PREFIX +# else +# define PRI_DECDIG_DBL_PREFIX "l" +# endif +#else +# define DECDIG uint16_t +# define DECDIG_DBL uint32_t +# define DECDIG_DBL_SIGNED int32_t +# define SIZEOF_DECDIG 2 +# define PRI_DECDIG_PREFIX "h" +# define PRI_DECDIG_DBL_PREFIX "" +#endif + +#define PRIdDECDIG PRI_DECDIG_PREFIX"d" +#define PRIiDECDIG PRI_DECDIG_PREFIX"i" +#define PRIoDECDIG PRI_DECDIG_PREFIX"o" +#define PRIuDECDIG PRI_DECDIG_PREFIX"u" +#define PRIxDECDIG PRI_DECDIG_PREFIX"x" +#define PRIXDECDIG PRI_DECDIG_PREFIX"X" + +#define PRIdDECDIG_DBL PRI_DECDIG_DBL_PREFIX"d" +#define PRIiDECDIG_DBL PRI_DECDIG_DBL_PREFIX"i" +#define PRIoDECDIG_DBL PRI_DECDIG_DBL_PREFIX"o" +#define PRIuDECDIG_DBL PRI_DECDIG_DBL_PREFIX"u" +#define PRIxDECDIG_DBL PRI_DECDIG_DBL_PREFIX"x" +#define PRIXDECDIG_DBL PRI_DECDIG_DBL_PREFIX"X" + +#if SIZEOF_DECDIG == 4 +# define BIGDECIMAL_BASE ((DECDIG)1000000000U) +# define BIGDECIMAL_COMPONENT_FIGURES 9 +/* + * The number of components required for a 64-bit integer. + * + * INT64_MAX: 9_223372036_854775807 + * UINT64_MAX: 18_446744073_709551615 + */ +# define BIGDECIMAL_INT64_MAX_LENGTH 3 + +#elif SIZEOF_DECDIG == 2 +# define BIGDECIMAL_BASE ((DECDIG)10000U) +# define BIGDECIMAL_COMPONENT_FIGURES 4 +/* + * The number of components required for a 64-bit integer. + * + * INT64_MAX: 922_3372_0368_5477_5807 + * UINT64_MAX: 1844_6744_0737_0955_1615 + */ +# define BIGDECIMAL_INT64_MAX_LENGTH 5 + +#else +# error Unknown size of DECDIG +#endif + +#define BIGDECIMAL_DOUBLE_FIGURES (1+DBL_DIG) + +#if defined(__cplusplus) +extern "C" { +#if 0 +} /* satisfy cc-mode */ +#endif +#endif + +extern VALUE rb_cBigDecimal; + +/* + * NaN & Infinity + */ +#define SZ_NaN "NaN" +#define SZ_INF "Infinity" +#define SZ_PINF "+Infinity" +#define SZ_NINF "-Infinity" + +/* + * #define VP_EXPORT other than static to let VP_ routines + * be called from outside of this module. + */ +#define VP_EXPORT static + +/* Exception mode */ +#define VP_EXCEPTION_ALL ((unsigned short)0x00FF) +#define VP_EXCEPTION_INFINITY ((unsigned short)0x0001) +#define VP_EXCEPTION_NaN ((unsigned short)0x0002) +#define VP_EXCEPTION_UNDERFLOW ((unsigned short)0x0004) +#define VP_EXCEPTION_OVERFLOW ((unsigned short)0x0001) /* 0x0008) */ +#define VP_EXCEPTION_ZERODIVIDE ((unsigned short)0x0010) + +/* Following 2 exceptions can't controlled by user */ +#define VP_EXCEPTION_OP ((unsigned short)0x0020) + +#define BIGDECIMAL_EXCEPTION_MODE_DEFAULT 0U + +/* This is used in BigDecimal#mode */ +#define VP_ROUND_MODE ((unsigned short)0x0100) + +/* Rounding mode */ +#define VP_ROUND_UP RBD_ROUND_UP +#define VP_ROUND_DOWN RBD_ROUND_DOWN +#define VP_ROUND_HALF_UP RBD_ROUND_HALF_UP +#define VP_ROUND_HALF_DOWN RBD_ROUND_HALF_DOWN +#define VP_ROUND_CEIL RBD_ROUND_CEIL +#define VP_ROUND_FLOOR RBD_ROUND_FLOOR +#define VP_ROUND_HALF_EVEN RBD_ROUND_HALF_EVEN + +enum rbd_rounding_mode { + RBD_ROUND_UP = 1, + RBD_ROUND_DOWN = 2, + RBD_ROUND_HALF_UP = 3, + RBD_ROUND_HALF_DOWN = 4, + RBD_ROUND_CEIL = 5, + RBD_ROUND_FLOOR = 6, + RBD_ROUND_HALF_EVEN = 7, + + RBD_ROUND_DEFAULT = RBD_ROUND_HALF_UP, + RBD_ROUND_TRUNCATE = RBD_ROUND_DOWN, + RBD_ROUND_BANKER = RBD_ROUND_HALF_EVEN, + RBD_ROUND_CEILING = RBD_ROUND_CEIL +}; + +#define BIGDECIMAL_ROUNDING_MODE_DEFAULT VP_ROUND_HALF_UP + +/* Sign flag */ +#define VP_SIGN_NaN 0 /* NaN */ +#define VP_SIGN_POSITIVE_ZERO 1 /* Positive zero */ +#define VP_SIGN_NEGATIVE_ZERO -1 /* Negative zero */ +#define VP_SIGN_POSITIVE_FINITE 2 /* Positive finite number */ +#define VP_SIGN_NEGATIVE_FINITE -2 /* Negative finite number */ +#define VP_SIGN_POSITIVE_INFINITE 3 /* Positive infinite number */ +#define VP_SIGN_NEGATIVE_INFINITE -3 /* Negative infinite number */ + +/* The size of fraction part array */ +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +#define FLEXIBLE_ARRAY_SIZE /* */ +#elif defined(__GNUC__) && !defined(__STRICT_ANSI__) +#define FLEXIBLE_ARRAY_SIZE 0 +#else +#define FLEXIBLE_ARRAY_SIZE 1 +#endif + +/* + * VP representation + * r = 0.xxxxxxxxx *BASE**exponent + */ +typedef struct { + VALUE obj; /* Back pointer(VALUE) for Ruby object. */ + size_t MaxPrec; /* Maximum precision size */ + /* This is the actual size of frac[] */ + /*(frac[0] to frac[MaxPrec] are available). */ + size_t Prec; /* Current precision size. */ + /* This indicates how much the */ + /* array frac[] is actually used. */ + SIGNED_VALUE exponent; /* Exponent part. */ + short sign; /* Attributes of the value. */ + /* + * ==0 : NaN + * 1 : Positive zero + * -1 : Negative zero + * 2 : Positive number + * -2 : Negative number + * 3 : Positive infinite number + * -3 : Negative infinite number + */ + short flag; /* Not used in vp_routines,space for user. */ + DECDIG frac[FLEXIBLE_ARRAY_SIZE]; /* Array of fraction part. */ +} Real; + +/* + * ------------------ + * EXPORTables. + * ------------------ + */ + +VP_EXPORT Real *VpNewRbClass(size_t mx, char const *str, VALUE klass, bool strict_p, bool raise_exception); + +VP_EXPORT Real *VpCreateRbObject(size_t mx, const char *str, bool raise_exception); + +#define VpBaseFig() BIGDECIMAL_COMPONENT_FIGURES +#define VpDblFig() BIGDECIMAL_DOUBLE_FIGURES +#define VpBaseVal() BIGDECIMAL_BASE + +/* Zero,Inf,NaN (isinf(),isnan() used to check) */ +VP_EXPORT double VpGetDoubleNaN(void); +VP_EXPORT double VpGetDoublePosInf(void); +VP_EXPORT double VpGetDoubleNegInf(void); +VP_EXPORT double VpGetDoubleNegZero(void); + +/* These 2 functions added at v1.1.7 */ +VP_EXPORT size_t VpGetPrecLimit(void); +VP_EXPORT size_t VpSetPrecLimit(size_t n); + +/* Round mode */ +VP_EXPORT int VpIsRoundMode(unsigned short n); +VP_EXPORT unsigned short VpGetRoundMode(void); +VP_EXPORT unsigned short VpSetRoundMode(unsigned short n); + +VP_EXPORT int VpException(unsigned short f,const char *str,int always); +#if 0 /* unused */ +VP_EXPORT int VpIsNegDoubleZero(double v); +#endif +VP_EXPORT size_t VpNumOfChars(Real *vp,const char *pszFmt); +VP_EXPORT size_t VpInit(DECDIG BaseVal); +VP_EXPORT Real *VpAlloc(size_t mx, const char *szVal, int strict_p, int exc); +VP_EXPORT size_t VpAsgn(Real *c, Real *a, int isw); +VP_EXPORT size_t VpAddSub(Real *c,Real *a,Real *b,int operation); +VP_EXPORT size_t VpMult(Real *c,Real *a,Real *b); +VP_EXPORT size_t VpDivd(Real *c,Real *r,Real *a,Real *b); +VP_EXPORT int VpComp(Real *a,Real *b); +VP_EXPORT ssize_t VpExponent10(Real *a); +VP_EXPORT void VpSzMantissa(Real *a, char *buf, size_t bufsize); +VP_EXPORT int VpToSpecialString(Real *a, char *buf, size_t bufsize, int fPlus); +VP_EXPORT void VpToString(Real *a, char *buf, size_t bufsize, size_t fFmt, int fPlus); +VP_EXPORT void VpToFString(Real *a, char *buf, size_t bufsize, size_t fFmt, int fPlus); +VP_EXPORT int VpCtoV(Real *a, const char *int_chr, size_t ni, const char *frac, size_t nf, const char *exp_chr, size_t ne); +VP_EXPORT int VpVtoD(double *d, SIGNED_VALUE *e, Real *m); +VP_EXPORT void VpDtoV(Real *m,double d); +#if 0 /* unused */ +VP_EXPORT void VpItoV(Real *m,S_INT ival); +#endif +VP_EXPORT int VpSqrt(Real *y,Real *x); +VP_EXPORT int VpActiveRound(Real *y, Real *x, unsigned short f, ssize_t il); +VP_EXPORT int VpMidRound(Real *y, unsigned short f, ssize_t nf); +VP_EXPORT int VpLeftRound(Real *y, unsigned short f, ssize_t nf); +VP_EXPORT void VpFrac(Real *y, Real *x); +VP_EXPORT int VpPowerByInt(Real *y, Real *x, SIGNED_VALUE n); +#define VpPower VpPowerByInt + +/* VP constants */ +VP_EXPORT Real *VpOne(void); + +/* + * ------------------ + * MACRO definitions. + * ------------------ + */ +#define Abs(a) (((a)>= 0)?(a):(-(a))) +#define Max(a, b) (((a)>(b))?(a):(b)) +#define Min(a, b) (((a)>(b))?(b):(a)) + +#define VpMaxPrec(a) ((a)->MaxPrec) +#define VpPrec(a) ((a)->Prec) +#define VpGetFlag(a) ((a)->flag) + +/* Sign */ + +/* VpGetSign(a) returns 1,-1 if a>0,a<0 respectively */ +#define VpGetSign(a) (((a)->sign>0)?1:(-1)) +/* Change sign of a to a>0,a<0 if s = 1,-1 respectively */ +#define VpChangeSign(a,s) {if((s)>0) (a)->sign=(short)Abs((ssize_t)(a)->sign);else (a)->sign=-(short)Abs((ssize_t)(a)->sign);} +/* Sets sign of a to a>0,a<0 if s = 1,-1 respectively */ +#define VpSetSign(a,s) {if((s)>0) (a)->sign=(short)VP_SIGN_POSITIVE_FINITE;else (a)->sign=(short)VP_SIGN_NEGATIVE_FINITE;} + +/* 1 */ +#define VpSetOne(a) {(a)->Prec=(a)->exponent=(a)->frac[0]=1;(a)->sign=VP_SIGN_POSITIVE_FINITE;} + +/* ZEROs */ +#define VpIsPosZero(a) ((a)->sign==VP_SIGN_POSITIVE_ZERO) +#define VpIsNegZero(a) ((a)->sign==VP_SIGN_NEGATIVE_ZERO) +#define VpIsZero(a) (VpIsPosZero(a) || VpIsNegZero(a)) +#define VpSetPosZero(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_POSITIVE_ZERO) +#define VpSetNegZero(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NEGATIVE_ZERO) +#define VpSetZero(a,s) (void)(((s)>0)?VpSetPosZero(a):VpSetNegZero(a)) + +/* NaN */ +#define VpIsNaN(a) ((a)->sign==VP_SIGN_NaN) +#define VpSetNaN(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NaN) + +/* Infinity */ +#define VpIsPosInf(a) ((a)->sign==VP_SIGN_POSITIVE_INFINITE) +#define VpIsNegInf(a) ((a)->sign==VP_SIGN_NEGATIVE_INFINITE) +#define VpIsInf(a) (VpIsPosInf(a) || VpIsNegInf(a)) +#define VpIsDef(a) ( !(VpIsNaN(a)||VpIsInf(a)) ) +#define VpSetPosInf(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_POSITIVE_INFINITE) +#define VpSetNegInf(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NEGATIVE_INFINITE) +#define VpSetInf(a,s) (void)(((s)>0)?VpSetPosInf(a):VpSetNegInf(a)) +#define VpHasVal(a) (a->frac[0]) +#define VpIsOne(a) ((a->Prec==1)&&(a->frac[0]==1)&&(a->exponent==1)) +#define VpExponent(a) (a->exponent) +#ifdef BIGDECIMAL_DEBUG +int VpVarCheck(Real * v); +#endif /* BIGDECIMAL_DEBUG */ + +#if defined(__cplusplus) +#if 0 +{ /* satisfy cc-mode */ +#endif +} /* extern "C" { */ +#endif +#endif /* RUBY_BIG_DECIMAL_H */ diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/bits.h b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/bits.h new file mode 100644 index 00000000..6e1e4776 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/bits.h @@ -0,0 +1,141 @@ +#ifndef BIGDECIMAL_BITS_H +#define BIGDECIMAL_BITS_H + +#include "feature.h" +#include "static_assert.h" + +#if defined(__x86_64__) && defined(HAVE_X86INTRIN_H) +# include /* for _lzcnt_u64, etc. */ +#elif defined(_MSC_VER) && defined(HAVE_INTRIN_H) +# include /* for the following intrinsics */ +#endif + +#if defined(_MSC_VER) && defined(__AVX2__) +# pragma intrinsic(__lzcnt) +# pragma intrinsic(__lzcnt64) +#endif + +#define numberof(array) ((int)(sizeof(array) / sizeof((array)[0]))) +#define roomof(x, y) (((x) + (y) - 1) / (y)) +#define type_roomof(x, y) roomof(sizeof(x), sizeof(y)) + +#define MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, min, max) ( \ + (a) == 0 ? 0 : \ + (a) == -1 ? (b) < -(max) : \ + (a) > 0 ? \ + ((b) > 0 ? (max) / (a) < (b) : (min) / (a) > (b)) : \ + ((b) > 0 ? (min) / (a) < (b) : (max) / (a) > (b))) + +#ifdef HAVE_UINT128_T +# define bit_length(x) \ + (unsigned int) \ + (sizeof(x) <= sizeof(int32_t) ? 32 - nlz_int32((uint32_t)(x)) : \ + sizeof(x) <= sizeof(int64_t) ? 64 - nlz_int64((uint64_t)(x)) : \ + 128 - nlz_int128((uint128_t)(x))) +#else +# define bit_length(x) \ + (unsigned int) \ + (sizeof(x) <= sizeof(int32_t) ? 32 - nlz_int32((uint32_t)(x)) : \ + 64 - nlz_int64((uint64_t)(x))) +#endif + +static inline unsigned nlz_int32(uint32_t x); +static inline unsigned nlz_int64(uint64_t x); +#ifdef HAVE_UINT128_T +static inline unsigned nlz_int128(uint128_t x); +#endif + +static inline unsigned int +nlz_int32(uint32_t x) +{ +#if defined(_MSC_VER) && defined(__AVX2__) && defined(HAVE___LZCNT) + /* Note: It seems there is no such thing like __LZCNT__ predefined in MSVC. + * AMD CPUs have had this instruction for decades (since K10) but for + * Intel, Haswell is the oldest one. We need to use __AVX2__ for maximum + * safety. */ + return (unsigned int)__lzcnt(x); + +#elif defined(__x86_64__) && defined(__LZCNT__) && defined(HAVE__LZCNT_U32) + return (unsigned int)_lzcnt_u32(x); + +#elif defined(_MSC_VER) && defined(HAVE__BITSCANREVERSE) + unsigned long r; + return _BitScanReverse(&r, x) ? (31 - (int)r) : 32; + +#elif __has_builtin(__builtin_clz) + STATIC_ASSERT(sizeof_int, sizeof(int) * CHAR_BIT == 32); + return x ? (unsigned int)__builtin_clz(x) : 32; + +#else + uint32_t y; + unsigned n = 32; + y = x >> 16; if (y) {n -= 16; x = y;} + y = x >> 8; if (y) {n -= 8; x = y;} + y = x >> 4; if (y) {n -= 4; x = y;} + y = x >> 2; if (y) {n -= 2; x = y;} + y = x >> 1; if (y) {return n - 2;} + return (unsigned int)(n - x); +#endif +} + +static inline unsigned int +nlz_int64(uint64_t x) +{ +#if defined(_MSC_VER) && defined(__AVX2__) && defined(HAVE___LZCNT64) + return (unsigned int)__lzcnt64(x); + +#elif defined(__x86_64__) && defined(__LZCNT__) && defined(HAVE__LZCNT_U64) + return (unsigned int)_lzcnt_u64(x); + +#elif defined(_WIN64) && defined(_MSC_VER) && defined(HAVE__BITSCANREVERSE64) + unsigned long r; + return _BitScanReverse64(&r, x) ? (63u - (unsigned int)r) : 64; + +#elif __has_builtin(__builtin_clzl) && __has_builtin(__builtin_clzll) && !(defined(__sun) && defined(__sparc)) + if (x == 0) { + return 64; + } + else if (sizeof(long) * CHAR_BIT == 64) { + return (unsigned int)__builtin_clzl((unsigned long)x); + } + else if (sizeof(long long) * CHAR_BIT == 64) { + return (unsigned int)__builtin_clzll((unsigned long long)x); + } + else { + /* :FIXME: Is there a way to make this branch a compile-time error? */ + __builtin_unreachable(); + } + +#else + uint64_t y; + unsigned int n = 64; + y = x >> 32; if (y) {n -= 32; x = y;} + y = x >> 16; if (y) {n -= 16; x = y;} + y = x >> 8; if (y) {n -= 8; x = y;} + y = x >> 4; if (y) {n -= 4; x = y;} + y = x >> 2; if (y) {n -= 2; x = y;} + y = x >> 1; if (y) {return n - 2;} + return (unsigned int)(n - x); + +#endif +} + +#ifdef HAVE_UINT128_T +static inline unsigned int +nlz_int128(uint128_t x) +{ + uint64_t y = (uint64_t)(x >> 64); + + if (x == 0) { + return 128; + } + else if (y == 0) { + return (unsigned int)nlz_int64(x) + 64; + } + else { + return (unsigned int)nlz_int64(y); + } +} +#endif + +#endif /* BIGDECIMAL_BITS_H */ diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/extconf.rb b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/extconf.rb new file mode 100644 index 00000000..cf4290f5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/extconf.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: false +require 'mkmf' + +def have_builtin_func(name, check_expr, opt = "", &b) + checking_for checking_message(name.funcall_style, nil, opt) do + if try_compile(< +#endif + +#ifdef RBIMPL_HAS_BUILTIN +# define BIGDECIMAL_HAS_BUILTIN(...) RBIMPL_HAS_BUILTIN(__VA_ARGS__) + +#else +# /* The following section is copied from CRuby's builtin.h */ +# +# ifdef __has_builtin +# if defined(__INTEL_COMPILER) +# /* :TODO: Intel C Compiler has __has_builtin (since 19.1 maybe?), and is +# * reportedly broken. We have to skip them. However the situation can +# * change. They might improve someday. We need to revisit here later. */ +# elif defined(__GNUC__) && ! __has_builtin(__builtin_alloca) +# /* FreeBSD's defines its own *broken* version of +# * __has_builtin. Cygwin copied that content to be a victim of the +# * broken-ness. We don't take them into account. */ +# else +# define HAVE___HAS_BUILTIN 1 +# endif +# endif +# +# if defined(HAVE___HAS_BUILTIN) +# define BIGDECIMAL_HAS_BUILTIN(_) __has_builtin(_) +# +# elif defined(__GNUC__) +# define BIGDECIMAL_HAS_BUILTIN(_) BIGDECIMAL_HAS_BUILTIN_ ## _ +# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 6)) +# define BIGDECIMAL_HAS_BUILTIN___builtin_clz 1 +# define BIGDECIMAL_HAS_BUILTIN___builtin_clzl 1 +# else +# define BIGDECIMAL_HAS_BUILTIN___builtin_clz 0 +# define BIGDECIMAL_HAS_BUILTIN___builtin_clzl 0 +# endif +# elif defined(_MSC_VER) +# define BIGDECIMAL_HAS_BUILTIN(_) 0 +# +# else +# define BIGDECIMAL_HAS_BUILTIN(_) BIGDECIMAL_HAS_BUILTIN_ ## _ +# define BIGDECIMAL_HAS_BUILTIN___builtin_clz HAVE_BUILTIN___BUILTIN_CLZ +# define BIGDECIMAL_HAS_BUILTIN___builtin_clzl HAVE_BUILTIN___BUILTIN_CLZL +# endif +#endif /* RBIMPL_HAS_BUILTIN */ + +#ifndef __has_builtin +# define __has_builtin(...) BIGDECIMAL_HAS_BUILTIN(__VA_ARGS__) +#endif + +#endif /* BIGDECIMAL_HAS_FEATURE_H */ diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/missing.c b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/missing.c new file mode 100644 index 00000000..1454c281 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/missing.c @@ -0,0 +1,28 @@ +#include + +#ifdef HAVE_RUBY_ATOMIC_H +# include +#endif + +#ifdef RUBY_ATOMIC_PTR_CAS +# define ATOMIC_PTR_CAS(var, old, new) RUBY_ATOMIC_PTR_CAS(var, old, new) +#endif + +#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +/* GCC warns about unknown sanitizer, which is annoying. */ +# undef NO_SANITIZE +# define NO_SANITIZE(x, y) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wattributes\"") \ + __attribute__((__no_sanitize__(x))) y; \ + _Pragma("GCC diagnostic pop") \ + y +#endif + +#undef strtod +#define strtod BigDecimal_strtod +#undef dtoa +#define dtoa BigDecimal_dtoa +#undef hdtoa +#define hdtoa BigDecimal_hdtoa +#include "missing/dtoa.c" diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/missing.h b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/missing.h new file mode 100644 index 00000000..325554b5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/missing.h @@ -0,0 +1,196 @@ +#ifndef MISSING_H +#define MISSING_H 1 + +#if defined(__cplusplus) +extern "C" { +#if 0 +} /* satisfy cc-mode */ +#endif +#endif + +#ifdef HAVE_STDLIB_H +# include +#endif + +#ifdef HAVE_MATH_H +# include +#endif + +#ifndef RB_UNUSED_VAR +# if defined(_MSC_VER) && _MSC_VER >= 1911 +# define RB_UNUSED_VAR(x) x [[maybe_unused]] + +# elif defined(__has_cpp_attribute) && __has_cpp_attribute(maybe_unused) +# define RB_UNUSED_VAR(x) x [[maybe_unused]] + +# elif defined(__has_c_attribute) && __has_c_attribute(maybe_unused) +# define RB_UNUSED_VAR(x) x [[maybe_unused]] + +# elif defined(__GNUC__) +# define RB_UNUSED_VAR(x) x __attribute__ ((unused)) + +# else +# define RB_UNUSED_VAR(x) x +# endif +#endif /* RB_UNUSED_VAR */ + +#if defined(_MSC_VER) && _MSC_VER >= 1310 +# define HAVE___ASSUME 1 + +#elif defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1300 +# define HAVE___ASSUME 1 +#endif + +#ifndef UNREACHABLE +# if __has_builtin(__builtin_unreachable) +# define UNREACHABLE __builtin_unreachable() + +# elif defined(HAVE___ASSUME) +# define UNREACHABLE __assume(0) + +# else +# define UNREACHABLE /* unreachable */ +# endif +#endif /* UNREACHABLE */ + +/* bool */ + +#if defined(__bool_true_false_are_defined) +# /* Take that. */ + +#elif defined(HAVE_STDBOOL_H) +# include + +#else +typedef unsigned char _Bool; +# define bool _Bool +# define true ((_Bool)+1) +# define false ((_Bool)-1) +# define __bool_true_false_are_defined +#endif + +/* abs */ + +#ifndef HAVE_LABS +static inline long +labs(long const x) +{ + if (x < 0) return -x; + return x; +} +#endif + +#ifndef HAVE_LLABS +static inline LONG_LONG +llabs(LONG_LONG const x) +{ + if (x < 0) return -x; + return x; +} +#endif + +#ifdef vabs +# undef vabs +#endif +#if SIZEOF_VALUE <= SIZEOF_INT +# define vabs abs +#elif SIZEOF_VALUE <= SIZEOF_LONG +# define vabs labs +#elif SIZEOF_VALUE <= SIZEOF_LONG_LONG +# define vabs llabs +#endif + +/* finite */ + +#ifndef HAVE_FINITE +static int +finite(double) +{ + return !isnan(n) && !isinf(n); +} +#endif + +#ifndef isfinite +# ifndef HAVE_ISFINITE +# define HAVE_ISFINITE 1 +# define isfinite(x) finite(x) +# endif +#endif + +/* dtoa */ +char *BigDecimal_dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve); + +/* rational */ + +#ifndef HAVE_RB_RATIONAL_NUM +static inline VALUE +rb_rational_num(VALUE rat) +{ +#ifdef RRATIONAL + return RRATIONAL(rat)->num; +#else + return rb_funcall(rat, rb_intern("numerator"), 0); +#endif +} +#endif + +#ifndef HAVE_RB_RATIONAL_DEN +static inline VALUE +rb_rational_den(VALUE rat) +{ +#ifdef RRATIONAL + return RRATIONAL(rat)->den; +#else + return rb_funcall(rat, rb_intern("denominator"), 0); +#endif +} +#endif + +/* complex */ + +#ifndef HAVE_RB_COMPLEX_REAL +static inline VALUE +rb_complex_real(VALUE cmp) +{ +#ifdef RCOMPLEX + return RCOMPLEX(cmp)->real; +#else + return rb_funcall(cmp, rb_intern("real"), 0); +#endif +} +#endif + +#ifndef HAVE_RB_COMPLEX_IMAG +static inline VALUE +rb_complex_imag(VALUE cmp) +{ +# ifdef RCOMPLEX + return RCOMPLEX(cmp)->imag; +# else + return rb_funcall(cmp, rb_intern("imag"), 0); +# endif +} +#endif + +/* st */ + +#ifndef ST2FIX +# undef RB_ST2FIX +# define RB_ST2FIX(h) LONG2FIX((long)(h)) +# define ST2FIX(h) RB_ST2FIX(h) +#endif + +/* warning */ + +#if !defined(HAVE_RB_CATEGORY_WARN) || !defined(HAVE_CONST_RB_WARN_CATEGORY_DEPRECATED) +# define rb_category_warn(category, ...) rb_warn(__VA_ARGS__) +#endif + +#if defined(__cplusplus) +#if 0 +{ /* satisfy cc-mode */ +#endif +} /* extern "C" { */ +#endif + +#endif /* MISSING_H */ diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/missing/dtoa.c b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/missing/dtoa.c new file mode 100644 index 00000000..41b0a221 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/missing/dtoa.c @@ -0,0 +1,3462 @@ +/**************************************************************** + * + * The author of this software is David M. Gay. + * + * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + * + ***************************************************************/ + +/* Please send bug reports to David M. Gay (dmg at acm dot org, + * with " at " changed at "@" and " dot " changed to "."). */ + +/* On a machine with IEEE extended-precision registers, it is + * necessary to specify double-precision (53-bit) rounding precision + * before invoking strtod or dtoa. If the machine uses (the equivalent + * of) Intel 80x87 arithmetic, the call + * _control87(PC_53, MCW_PC); + * does this with many compilers. Whether this or another call is + * appropriate depends on the compiler; for this to work, it may be + * necessary to #include "float.h" or another system-dependent header + * file. + */ + +/* strtod for IEEE-, VAX-, and IBM-arithmetic machines. + * + * This strtod returns a nearest machine number to the input decimal + * string (or sets errno to ERANGE). With IEEE arithmetic, ties are + * broken by the IEEE round-even rule. Otherwise ties are broken by + * biased rounding (add half and chop). + * + * Inspired loosely by William D. Clinger's paper "How to Read Floating + * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. + * + * Modifications: + * + * 1. We only require IEEE, IBM, or VAX double-precision + * arithmetic (not IEEE double-extended). + * 2. We get by with floating-point arithmetic in a case that + * Clinger missed -- when we're computing d * 10^n + * for a small integer d and the integer n is not too + * much larger than 22 (the maximum integer k for which + * we can represent 10^k exactly), we may be able to + * compute (d*10^k) * 10^(e-k) with just one roundoff. + * 3. Rather than a bit-at-a-time adjustment of the binary + * result in the hard case, we use floating-point + * arithmetic to determine the adjustment to within + * one bit; only in really hard cases do we need to + * compute a second residual. + * 4. Because of 3., we don't need a large table of powers of 10 + * for ten-to-e (just some small tables, e.g. of 10^k + * for 0 <= k <= 22). + */ + +/* + * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least + * significant byte has the lowest address. + * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most + * significant byte has the lowest address. + * #define Long int on machines with 32-bit ints and 64-bit longs. + * #define IBM for IBM mainframe-style floating-point arithmetic. + * #define VAX for VAX-style floating-point arithmetic (D_floating). + * #define No_leftright to omit left-right logic in fast floating-point + * computation of dtoa. + * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 + * and strtod and dtoa should round accordingly. + * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 + * and Honor_FLT_ROUNDS is not #defined. + * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines + * that use extended-precision instructions to compute rounded + * products and quotients) with IBM. + * #define ROUND_BIASED for IEEE-format with biased rounding. + * #define Inaccurate_Divide for IEEE-format with correctly rounded + * products but inaccurate quotients, e.g., for Intel i860. + * #define NO_LONG_LONG on machines that do not have a "long long" + * integer type (of >= 64 bits). On such machines, you can + * #define Just_16 to store 16 bits per 32-bit Long when doing + * high-precision integer arithmetic. Whether this speeds things + * up or slows things down depends on the machine and the number + * being converted. If long long is available and the name is + * something other than "long long", #define Llong to be the name, + * and if "unsigned Llong" does not work as an unsigned version of + * Llong, #define #ULLong to be the corresponding unsigned type. + * #define KR_headers for old-style C function headers. + * #define Bad_float_h if your system lacks a float.h or if it does not + * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, + * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. + * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) + * if memory is available and otherwise does something you deem + * appropriate. If MALLOC is undefined, malloc will be invoked + * directly -- and assumed always to succeed. + * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making + * memory allocations from a private pool of memory when possible. + * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, + * unless #defined to be a different length. This default length + * suffices to get rid of MALLOC calls except for unusual cases, + * such as decimal-to-binary conversion of a very long string of + * digits. The longest string dtoa can return is about 751 bytes + * long. For conversions by strtod of strings of 800 digits and + * all dtoa conversions in single-threaded executions with 8-byte + * pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte + * pointers, PRIVATE_MEM >= 7112 appears adequate. + * #define INFNAN_CHECK on IEEE systems to cause strtod to check for + * Infinity and NaN (case insensitively). On some systems (e.g., + * some HP systems), it may be necessary to #define NAN_WORD0 + * appropriately -- to the most significant word of a quiet NaN. + * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) + * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, + * strtod also accepts (case insensitively) strings of the form + * NaN(x), where x is a string of hexadecimal digits and spaces; + * if there is only one string of hexadecimal digits, it is taken + * for the 52 fraction bits of the resulting NaN; if there are two + * or more strings of hex digits, the first is for the high 20 bits, + * the second and subsequent for the low 32 bits, with intervening + * white space ignored; but if this results in none of the 52 + * fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0 + * and NAN_WORD1 are used instead. + * #define MULTIPLE_THREADS if the system offers preemptively scheduled + * multiple threads. In this case, you must provide (or suitably + * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed + * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed + * in pow5mult, ensures lazy evaluation of only one copy of high + * powers of 5; omitting this lock would introduce a small + * probability of wasting memory, but would otherwise be harmless.) + * You must also invoke freedtoa(s) to free the value s returned by + * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. + * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that + * avoids underflows on inputs whose result does not underflow. + * If you #define NO_IEEE_Scale on a machine that uses IEEE-format + * floating-point numbers and flushes underflows to zero rather + * than implementing gradual underflow, then you must also #define + * Sudden_Underflow. + * #define YES_ALIAS to permit aliasing certain double values with + * arrays of ULongs. This leads to slightly better code with + * some compilers and was always used prior to 19990916, but it + * is not strictly legal and can cause trouble with aggressively + * optimizing compilers (e.g., gcc 2.95.1 under -O2). + * #define USE_LOCALE to use the current locale's decimal_point value. + * #define SET_INEXACT if IEEE arithmetic is being used and extra + * computation should be done to set the inexact flag when the + * result is inexact and avoid setting inexact when the result + * is exact. In this case, dtoa.c must be compiled in + * an environment, perhaps provided by #include "dtoa.c" in a + * suitable wrapper, that defines two functions, + * int get_inexact(void); + * void clear_inexact(void); + * such that get_inexact() returns a nonzero value if the + * inexact bit is already set, and clear_inexact() sets the + * inexact bit to 0. When SET_INEXACT is #defined, strtod + * also does extra computations to set the underflow and overflow + * flags when appropriate (i.e., when the result is tiny and + * inexact or when it is a numeric value rounded to +-infinity). + * #define NO_ERRNO if strtod should not assign errno = ERANGE when + * the result overflows to +-Infinity or underflows to 0. + */ + +#ifdef WORDS_BIGENDIAN +#define IEEE_BIG_ENDIAN +#else +#define IEEE_LITTLE_ENDIAN +#endif + +#ifdef __vax__ +#define VAX +#undef IEEE_BIG_ENDIAN +#undef IEEE_LITTLE_ENDIAN +#endif + +#if defined(__arm__) && !defined(__VFP_FP__) +#define IEEE_BIG_ENDIAN +#undef IEEE_LITTLE_ENDIAN +#endif + +#undef Long +#undef ULong + +#include + +#if (INT_MAX >> 30) && !(INT_MAX >> 31) +#define Long int +#define ULong unsigned int +#elif (LONG_MAX >> 30) && !(LONG_MAX >> 31) +#define Long long int +#define ULong unsigned long int +#else +#error No 32bit integer +#endif + +#if HAVE_LONG_LONG +#define Llong LONG_LONG +#else +#define NO_LONG_LONG +#endif + +#ifdef DEBUG +#include +#define Bug(x) {fprintf(stderr, "%s\n", (x)); exit(EXIT_FAILURE);} +#endif + +#ifndef ISDIGIT +#include +#define ISDIGIT(c) isdigit(c) +#endif +#include +#include +#include + +#ifdef USE_LOCALE +#include +#endif + +#ifdef MALLOC +extern void *MALLOC(size_t); +#else +#define MALLOC xmalloc +#endif +#ifdef FREE +extern void FREE(void*); +#else +#define FREE xfree +#endif +#ifndef NO_SANITIZE +#define NO_SANITIZE(x, y) y +#endif + +#ifndef Omit_Private_Memory +#ifndef PRIVATE_MEM +#define PRIVATE_MEM 2304 +#endif +#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) +static double private_mem[PRIVATE_mem], *pmem_next = private_mem; +#endif + +#undef IEEE_Arith +#undef Avoid_Underflow +#ifdef IEEE_BIG_ENDIAN +#define IEEE_Arith +#endif +#ifdef IEEE_LITTLE_ENDIAN +#define IEEE_Arith +#endif + +#ifdef Bad_float_h + +#ifdef IEEE_Arith +#define DBL_DIG 15 +#define DBL_MAX_10_EXP 308 +#define DBL_MAX_EXP 1024 +#define FLT_RADIX 2 +#endif /*IEEE_Arith*/ + +#ifdef IBM +#define DBL_DIG 16 +#define DBL_MAX_10_EXP 75 +#define DBL_MAX_EXP 63 +#define FLT_RADIX 16 +#define DBL_MAX 7.2370055773322621e+75 +#endif + +#ifdef VAX +#define DBL_DIG 16 +#define DBL_MAX_10_EXP 38 +#define DBL_MAX_EXP 127 +#define FLT_RADIX 2 +#define DBL_MAX 1.7014118346046923e+38 +#endif + +#ifndef LONG_MAX +#define LONG_MAX 2147483647 +#endif + +#else /* ifndef Bad_float_h */ +#include +#endif /* Bad_float_h */ + +#include + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* satisfy cc-mode */ +#endif +#endif + +#ifndef hexdigit +static const char hexdigit[] = "0123456789abcdef0123456789ABCDEF"; +#endif + +#if defined(IEEE_LITTLE_ENDIAN) + defined(IEEE_BIG_ENDIAN) + defined(VAX) + defined(IBM) != 1 +Exactly one of IEEE_LITTLE_ENDIAN, IEEE_BIG_ENDIAN, VAX, or IBM should be defined. +#endif + +typedef union { double d; ULong L[2]; } U; + +#ifdef YES_ALIAS +typedef double double_u; +# define dval(x) (x) +# ifdef IEEE_LITTLE_ENDIAN +# define word0(x) (((ULong *)&(x))[1]) +# define word1(x) (((ULong *)&(x))[0]) +# else +# define word0(x) (((ULong *)&(x))[0]) +# define word1(x) (((ULong *)&(x))[1]) +# endif +#else +typedef U double_u; +# ifdef IEEE_LITTLE_ENDIAN +# define word0(x) ((x).L[1]) +# define word1(x) ((x).L[0]) +# else +# define word0(x) ((x).L[0]) +# define word1(x) ((x).L[1]) +# endif +# define dval(x) ((x).d) +#endif + +/* The following definition of Storeinc is appropriate for MIPS processors. + * An alternative that might be better on some machines is + * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff) + */ +#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm__) +#define Storeinc(a,b,c) (((unsigned short *)(a))[1] = (unsigned short)(b), \ +((unsigned short *)(a))[0] = (unsigned short)(c), (a)++) +#else +#define Storeinc(a,b,c) (((unsigned short *)(a))[0] = (unsigned short)(b), \ +((unsigned short *)(a))[1] = (unsigned short)(c), (a)++) +#endif + +/* #define P DBL_MANT_DIG */ +/* Ten_pmax = floor(P*log(2)/log(5)) */ +/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ +/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ +/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ + +#ifdef IEEE_Arith +#define Exp_shift 20 +#define Exp_shift1 20 +#define Exp_msk1 0x100000 +#define Exp_msk11 0x100000 +#define Exp_mask 0x7ff00000 +#define P 53 +#define Bias 1023 +#define Emin (-1022) +#define Exp_1 0x3ff00000 +#define Exp_11 0x3ff00000 +#define Ebits 11 +#define Frac_mask 0xfffff +#define Frac_mask1 0xfffff +#define Ten_pmax 22 +#define Bletch 0x10 +#define Bndry_mask 0xfffff +#define Bndry_mask1 0xfffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 1 +#define Tiny0 0 +#define Tiny1 1 +#define Quick_max 14 +#define Int_max 14 +#ifndef NO_IEEE_Scale +#define Avoid_Underflow +#ifdef Flush_Denorm /* debugging option */ +#undef Sudden_Underflow +#endif +#endif + +#ifndef Flt_Rounds +#ifdef FLT_ROUNDS +#define Flt_Rounds FLT_ROUNDS +#else +#define Flt_Rounds 1 +#endif +#endif /*Flt_Rounds*/ + +#ifdef Honor_FLT_ROUNDS +#define Rounding rounding +#undef Check_FLT_ROUNDS +#define Check_FLT_ROUNDS +#else +#define Rounding Flt_Rounds +#endif + +#else /* ifndef IEEE_Arith */ +#undef Check_FLT_ROUNDS +#undef Honor_FLT_ROUNDS +#undef SET_INEXACT +#undef Sudden_Underflow +#define Sudden_Underflow +#ifdef IBM +#undef Flt_Rounds +#define Flt_Rounds 0 +#define Exp_shift 24 +#define Exp_shift1 24 +#define Exp_msk1 0x1000000 +#define Exp_msk11 0x1000000 +#define Exp_mask 0x7f000000 +#define P 14 +#define Bias 65 +#define Exp_1 0x41000000 +#define Exp_11 0x41000000 +#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ +#define Frac_mask 0xffffff +#define Frac_mask1 0xffffff +#define Bletch 4 +#define Ten_pmax 22 +#define Bndry_mask 0xefffff +#define Bndry_mask1 0xffffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 4 +#define Tiny0 0x100000 +#define Tiny1 0 +#define Quick_max 14 +#define Int_max 15 +#else /* VAX */ +#undef Flt_Rounds +#define Flt_Rounds 1 +#define Exp_shift 23 +#define Exp_shift1 7 +#define Exp_msk1 0x80 +#define Exp_msk11 0x800000 +#define Exp_mask 0x7f80 +#define P 56 +#define Bias 129 +#define Exp_1 0x40800000 +#define Exp_11 0x4080 +#define Ebits 8 +#define Frac_mask 0x7fffff +#define Frac_mask1 0xffff007f +#define Ten_pmax 24 +#define Bletch 2 +#define Bndry_mask 0xffff007f +#define Bndry_mask1 0xffff007f +#define LSB 0x10000 +#define Sign_bit 0x8000 +#define Log2P 1 +#define Tiny0 0x80 +#define Tiny1 0 +#define Quick_max 15 +#define Int_max 15 +#endif /* IBM, VAX */ +#endif /* IEEE_Arith */ + +#ifndef IEEE_Arith +#define ROUND_BIASED +#endif + +#ifdef RND_PRODQUOT +#define rounded_product(a,b) ((a) = rnd_prod((a), (b))) +#define rounded_quotient(a,b) ((a) = rnd_quot((a), (b))) +extern double rnd_prod(double, double), rnd_quot(double, double); +#else +#define rounded_product(a,b) ((a) *= (b)) +#define rounded_quotient(a,b) ((a) /= (b)) +#endif + +#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) +#define Big1 0xffffffff + +#ifndef Pack_32 +#define Pack_32 +#endif + +#define FFFFFFFF 0xffffffffUL + +#ifdef NO_LONG_LONG +#undef ULLong +#ifdef Just_16 +#undef Pack_32 +/* When Pack_32 is not defined, we store 16 bits per 32-bit Long. + * This makes some inner loops simpler and sometimes saves work + * during multiplications, but it often seems to make things slightly + * slower. Hence the default is now to store 32 bits per Long. + */ +#endif +#else /* long long available */ +#ifndef Llong +#define Llong long long +#endif +#ifndef ULLong +#define ULLong unsigned Llong +#endif +#endif /* NO_LONG_LONG */ + +#define MULTIPLE_THREADS 1 + +#ifndef MULTIPLE_THREADS +#define ACQUIRE_DTOA_LOCK(n) /*nothing*/ +#define FREE_DTOA_LOCK(n) /*nothing*/ +#else +#define ACQUIRE_DTOA_LOCK(n) /*unused right now*/ +#define FREE_DTOA_LOCK(n) /*unused right now*/ +#endif + +#ifndef ATOMIC_PTR_CAS +#define ATOMIC_PTR_CAS(var, old, new) ((var) = (new), (old)) +#endif +#ifndef LIKELY +#define LIKELY(x) (x) +#endif +#ifndef UNLIKELY +#define UNLIKELY(x) (x) +#endif +#ifndef ASSUME +#define ASSUME(x) (void)(x) +#endif + +#define Kmax 15 + +struct Bigint { + struct Bigint *next; + int k, maxwds, sign, wds; + ULong x[1]; +}; + +typedef struct Bigint Bigint; + +static Bigint *freelist[Kmax+1]; + +static Bigint * +Balloc(int k) +{ + int x; + Bigint *rv; +#ifndef Omit_Private_Memory + size_t len; +#endif + + rv = 0; + ACQUIRE_DTOA_LOCK(0); + if (k <= Kmax) { + rv = freelist[k]; + while (rv) { + Bigint *rvn = rv; + rv = ATOMIC_PTR_CAS(freelist[k], rv, rv->next); + if (LIKELY(rvn == rv)) { + ASSUME(rv); + break; + } + } + } + if (!rv) { + x = 1 << k; +#ifdef Omit_Private_Memory + rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); +#else + len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) + /sizeof(double); + if (k <= Kmax) { + double *pnext = pmem_next; + while (pnext - private_mem + len <= PRIVATE_mem) { + double *p = pnext; + pnext = ATOMIC_PTR_CAS(pmem_next, pnext, pnext + len); + if (LIKELY(p == pnext)) { + rv = (Bigint*)pnext; + ASSUME(rv); + break; + } + } + } + if (!rv) + rv = (Bigint*)MALLOC(len*sizeof(double)); +#endif + rv->k = k; + rv->maxwds = x; + } + FREE_DTOA_LOCK(0); + rv->sign = rv->wds = 0; + return rv; +} + +static void +Bfree(Bigint *v) +{ + Bigint *vn; + if (v) { + if (v->k > Kmax) { + FREE(v); + return; + } + ACQUIRE_DTOA_LOCK(0); + do { + vn = v->next = freelist[v->k]; + } while (UNLIKELY(ATOMIC_PTR_CAS(freelist[v->k], vn, v) != vn)); + FREE_DTOA_LOCK(0); + } +} + +#define Bcopy(x,y) memcpy((char *)&(x)->sign, (char *)&(y)->sign, \ +(y)->wds*sizeof(Long) + 2*sizeof(int)) + +static Bigint * +multadd(Bigint *b, int m, int a) /* multiply by m and add a */ +{ + int i, wds; + ULong *x; +#ifdef ULLong + ULLong carry, y; +#else + ULong carry, y; +#ifdef Pack_32 + ULong xi, z; +#endif +#endif + Bigint *b1; + + wds = b->wds; + x = b->x; + i = 0; + carry = a; + do { +#ifdef ULLong + y = *x * (ULLong)m + carry; + carry = y >> 32; + *x++ = (ULong)(y & FFFFFFFF); +#else +#ifdef Pack_32 + xi = *x; + y = (xi & 0xffff) * m + carry; + z = (xi >> 16) * m + (y >> 16); + carry = z >> 16; + *x++ = (z << 16) + (y & 0xffff); +#else + y = *x * m + carry; + carry = y >> 16; + *x++ = y & 0xffff; +#endif +#endif + } while (++i < wds); + if (carry) { + if (wds >= b->maxwds) { + b1 = Balloc(b->k+1); + Bcopy(b1, b); + Bfree(b); + b = b1; + } + b->x[wds++] = (ULong)carry; + b->wds = wds; + } + return b; +} + +static Bigint * +s2b(const char *s, int nd0, int nd, ULong y9) +{ + Bigint *b; + int i, k; + Long x, y; + + x = (nd + 8) / 9; + for (k = 0, y = 1; x > y; y <<= 1, k++) ; +#ifdef Pack_32 + b = Balloc(k); + b->x[0] = y9; + b->wds = 1; +#else + b = Balloc(k+1); + b->x[0] = y9 & 0xffff; + b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; +#endif + + i = 9; + if (9 < nd0) { + s += 9; + do { + b = multadd(b, 10, *s++ - '0'); + } while (++i < nd0); + s++; + } + else + s += 10; + for (; i < nd; i++) + b = multadd(b, 10, *s++ - '0'); + return b; +} + +static int +hi0bits(register ULong x) +{ + register int k = 0; + + if (!(x & 0xffff0000)) { + k = 16; + x <<= 16; + } + if (!(x & 0xff000000)) { + k += 8; + x <<= 8; + } + if (!(x & 0xf0000000)) { + k += 4; + x <<= 4; + } + if (!(x & 0xc0000000)) { + k += 2; + x <<= 2; + } + if (!(x & 0x80000000)) { + k++; + if (!(x & 0x40000000)) + return 32; + } + return k; +} + +static int +lo0bits(ULong *y) +{ + register int k; + register ULong x = *y; + + if (x & 7) { + if (x & 1) + return 0; + if (x & 2) { + *y = x >> 1; + return 1; + } + *y = x >> 2; + return 2; + } + k = 0; + if (!(x & 0xffff)) { + k = 16; + x >>= 16; + } + if (!(x & 0xff)) { + k += 8; + x >>= 8; + } + if (!(x & 0xf)) { + k += 4; + x >>= 4; + } + if (!(x & 0x3)) { + k += 2; + x >>= 2; + } + if (!(x & 1)) { + k++; + x >>= 1; + if (!x) + return 32; + } + *y = x; + return k; +} + +static Bigint * +i2b(int i) +{ + Bigint *b; + + b = Balloc(1); + b->x[0] = i; + b->wds = 1; + return b; +} + +static Bigint * +mult(Bigint *a, Bigint *b) +{ + Bigint *c; + int k, wa, wb, wc; + ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; + ULong y; +#ifdef ULLong + ULLong carry, z; +#else + ULong carry, z; +#ifdef Pack_32 + ULong z2; +#endif +#endif + + if (a->wds < b->wds) { + c = a; + a = b; + b = c; + } + k = a->k; + wa = a->wds; + wb = b->wds; + wc = wa + wb; + if (wc > a->maxwds) + k++; + c = Balloc(k); + for (x = c->x, xa = x + wc; x < xa; x++) + *x = 0; + xa = a->x; + xae = xa + wa; + xb = b->x; + xbe = xb + wb; + xc0 = c->x; +#ifdef ULLong + for (; xb < xbe; xc0++) { + if ((y = *xb++) != 0) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * (ULLong)y + *xc + carry; + carry = z >> 32; + *xc++ = (ULong)(z & FFFFFFFF); + } while (x < xae); + *xc = (ULong)carry; + } + } +#else +#ifdef Pack_32 + for (; xb < xbe; xb++, xc0++) { + if ((y = *xb & 0xffff) != 0) { + x = xa; + xc = xc0; + carry = 0; + do { + z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; + carry = z >> 16; + z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; + carry = z2 >> 16; + Storeinc(xc, z2, z); + } while (x < xae); + *xc = (ULong)carry; + } + if ((y = *xb >> 16) != 0) { + x = xa; + xc = xc0; + carry = 0; + z2 = *xc; + do { + z = (*x & 0xffff) * y + (*xc >> 16) + carry; + carry = z >> 16; + Storeinc(xc, z, z2); + z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; + carry = z2 >> 16; + } while (x < xae); + *xc = z2; + } + } +#else + for (; xb < xbe; xc0++) { + if (y = *xb++) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * y + *xc + carry; + carry = z >> 16; + *xc++ = z & 0xffff; + } while (x < xae); + *xc = (ULong)carry; + } + } +#endif +#endif + for (xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; + c->wds = wc; + return c; +} + +static Bigint *p5s; + +static Bigint * +pow5mult(Bigint *b, int k) +{ + Bigint *b1, *p5, *p51; + Bigint *p5tmp; + int i; + static const int p05[3] = { 5, 25, 125 }; + + if ((i = k & 3) != 0) + b = multadd(b, p05[i-1], 0); + + if (!(k >>= 2)) + return b; + if (!(p5 = p5s)) { + /* first time */ + ACQUIRE_DTOA_LOCK(1); + if (!(p5 = p5s)) { + p5 = i2b(625); + p5->next = 0; + p5tmp = ATOMIC_PTR_CAS(p5s, NULL, p5); + if (UNLIKELY(p5tmp)) { + Bfree(p5); + p5 = p5tmp; + } + } + FREE_DTOA_LOCK(1); + } + for (;;) { + if (k & 1) { + b1 = mult(b, p5); + Bfree(b); + b = b1; + } + if (!(k >>= 1)) + break; + if (!(p51 = p5->next)) { + ACQUIRE_DTOA_LOCK(1); + if (!(p51 = p5->next)) { + p51 = mult(p5,p5); + p51->next = 0; + p5tmp = ATOMIC_PTR_CAS(p5->next, NULL, p51); + if (UNLIKELY(p5tmp)) { + Bfree(p51); + p51 = p5tmp; + } + } + FREE_DTOA_LOCK(1); + } + p5 = p51; + } + return b; +} + +static Bigint * +lshift(Bigint *b, int k) +{ + int i, k1, n, n1; + Bigint *b1; + ULong *x, *x1, *xe, z; + +#ifdef Pack_32 + n = k >> 5; +#else + n = k >> 4; +#endif + k1 = b->k; + n1 = n + b->wds + 1; + for (i = b->maxwds; n1 > i; i <<= 1) + k1++; + b1 = Balloc(k1); + x1 = b1->x; + for (i = 0; i < n; i++) + *x1++ = 0; + x = b->x; + xe = x + b->wds; +#ifdef Pack_32 + if (k &= 0x1f) { + k1 = 32 - k; + z = 0; + do { + *x1++ = *x << k | z; + z = *x++ >> k1; + } while (x < xe); + if ((*x1 = z) != 0) + ++n1; + } +#else + if (k &= 0xf) { + k1 = 16 - k; + z = 0; + do { + *x1++ = *x << k & 0xffff | z; + z = *x++ >> k1; + } while (x < xe); + if (*x1 = z) + ++n1; + } +#endif + else + do { + *x1++ = *x++; + } while (x < xe); + b1->wds = n1 - 1; + Bfree(b); + return b1; +} + +static int +cmp(Bigint *a, Bigint *b) +{ + ULong *xa, *xa0, *xb, *xb0; + int i, j; + + i = a->wds; + j = b->wds; +#ifdef DEBUG + if (i > 1 && !a->x[i-1]) + Bug("cmp called with a->x[a->wds-1] == 0"); + if (j > 1 && !b->x[j-1]) + Bug("cmp called with b->x[b->wds-1] == 0"); +#endif + if (i -= j) + return i; + xa0 = a->x; + xa = xa0 + j; + xb0 = b->x; + xb = xb0 + j; + for (;;) { + if (*--xa != *--xb) + return *xa < *xb ? -1 : 1; + if (xa <= xa0) + break; + } + return 0; +} + +NO_SANITIZE("unsigned-integer-overflow", static Bigint * diff(Bigint *a, Bigint *b)); +static Bigint * +diff(Bigint *a, Bigint *b) +{ + Bigint *c; + int i, wa, wb; + ULong *xa, *xae, *xb, *xbe, *xc; +#ifdef ULLong + ULLong borrow, y; +#else + ULong borrow, y; +#ifdef Pack_32 + ULong z; +#endif +#endif + + i = cmp(a,b); + if (!i) { + c = Balloc(0); + c->wds = 1; + c->x[0] = 0; + return c; + } + if (i < 0) { + c = a; + a = b; + b = c; + i = 1; + } + else + i = 0; + c = Balloc(a->k); + c->sign = i; + wa = a->wds; + xa = a->x; + xae = xa + wa; + wb = b->wds; + xb = b->x; + xbe = xb + wb; + xc = c->x; + borrow = 0; +#ifdef ULLong + do { + y = (ULLong)*xa++ - *xb++ - borrow; + borrow = y >> 32 & (ULong)1; + *xc++ = (ULong)(y & FFFFFFFF); + } while (xb < xbe); + while (xa < xae) { + y = *xa++ - borrow; + borrow = y >> 32 & (ULong)1; + *xc++ = (ULong)(y & FFFFFFFF); + } +#else +#ifdef Pack_32 + do { + y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } while (xb < xbe); + while (xa < xae) { + y = (*xa & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } +#else + do { + y = *xa++ - *xb++ - borrow; + borrow = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } while (xb < xbe); + while (xa < xae) { + y = *xa++ - borrow; + borrow = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } +#endif +#endif + while (!*--xc) + wa--; + c->wds = wa; + return c; +} + +static double +ulp(double x_) +{ + register Long L; + double_u x, a; + dval(x) = x_; + + L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; +#ifndef Avoid_Underflow +#ifndef Sudden_Underflow + if (L > 0) { +#endif +#endif +#ifdef IBM + L |= Exp_msk1 >> 4; +#endif + word0(a) = L; + word1(a) = 0; +#ifndef Avoid_Underflow +#ifndef Sudden_Underflow + } + else { + L = -L >> Exp_shift; + if (L < Exp_shift) { + word0(a) = 0x80000 >> L; + word1(a) = 0; + } + else { + word0(a) = 0; + L -= Exp_shift; + word1(a) = L >= 31 ? 1 : 1 << 31 - L; + } + } +#endif +#endif + return dval(a); +} + +static double +b2d(Bigint *a, int *e) +{ + ULong *xa, *xa0, w, y, z; + int k; + double_u d; +#ifdef VAX + ULong d0, d1; +#else +#define d0 word0(d) +#define d1 word1(d) +#endif + + xa0 = a->x; + xa = xa0 + a->wds; + y = *--xa; +#ifdef DEBUG + if (!y) Bug("zero y in b2d"); +#endif + k = hi0bits(y); + *e = 32 - k; +#ifdef Pack_32 + if (k < Ebits) { + d0 = Exp_1 | y >> (Ebits - k); + w = xa > xa0 ? *--xa : 0; + d1 = y << ((32-Ebits) + k) | w >> (Ebits - k); + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + if (k -= Ebits) { + d0 = Exp_1 | y << k | z >> (32 - k); + y = xa > xa0 ? *--xa : 0; + d1 = z << k | y >> (32 - k); + } + else { + d0 = Exp_1 | y; + d1 = z; + } +#else + if (k < Ebits + 16) { + z = xa > xa0 ? *--xa : 0; + d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; + w = xa > xa0 ? *--xa : 0; + y = xa > xa0 ? *--xa : 0; + d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + w = xa > xa0 ? *--xa : 0; + k -= Ebits + 16; + d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; + y = xa > xa0 ? *--xa : 0; + d1 = w << k + 16 | y << k; +#endif +ret_d: +#ifdef VAX + word0(d) = d0 >> 16 | d0 << 16; + word1(d) = d1 >> 16 | d1 << 16; +#else +#undef d0 +#undef d1 +#endif + return dval(d); +} + +static Bigint * +d2b(double d_, int *e, int *bits) +{ + double_u d; + Bigint *b; + int de, k; + ULong *x, y, z; +#ifndef Sudden_Underflow + int i; +#endif +#ifdef VAX + ULong d0, d1; +#endif + dval(d) = d_; +#ifdef VAX + d0 = word0(d) >> 16 | word0(d) << 16; + d1 = word1(d) >> 16 | word1(d) << 16; +#else +#define d0 word0(d) +#define d1 word1(d) +#endif + +#ifdef Pack_32 + b = Balloc(1); +#else + b = Balloc(2); +#endif + x = b->x; + + z = d0 & Frac_mask; + d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ +#ifdef Sudden_Underflow + de = (int)(d0 >> Exp_shift); +#ifndef IBM + z |= Exp_msk11; +#endif +#else + if ((de = (int)(d0 >> Exp_shift)) != 0) + z |= Exp_msk1; +#endif +#ifdef Pack_32 + if ((y = d1) != 0) { + if ((k = lo0bits(&y)) != 0) { + x[0] = y | z << (32 - k); + z >>= k; + } + else + x[0] = y; +#ifndef Sudden_Underflow + i = +#endif + b->wds = (x[1] = z) ? 2 : 1; + } + else { +#ifdef DEBUG + if (!z) + Bug("Zero passed to d2b"); +#endif + k = lo0bits(&z); + x[0] = z; +#ifndef Sudden_Underflow + i = +#endif + b->wds = 1; + k += 32; + } +#else + if (y = d1) { + if (k = lo0bits(&y)) + if (k >= 16) { + x[0] = y | z << 32 - k & 0xffff; + x[1] = z >> k - 16 & 0xffff; + x[2] = z >> k; + i = 2; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16 | z << 16 - k & 0xffff; + x[2] = z >> k & 0xffff; + x[3] = z >> k+16; + i = 3; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16; + x[2] = z & 0xffff; + x[3] = z >> 16; + i = 3; + } + } + else { +#ifdef DEBUG + if (!z) + Bug("Zero passed to d2b"); +#endif + k = lo0bits(&z); + if (k >= 16) { + x[0] = z; + i = 0; + } + else { + x[0] = z & 0xffff; + x[1] = z >> 16; + i = 1; + } + k += 32; + } + while (!x[i]) + --i; + b->wds = i + 1; +#endif +#ifndef Sudden_Underflow + if (de) { +#endif +#ifdef IBM + *e = (de - Bias - (P-1) << 2) + k; + *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); +#else + *e = de - Bias - (P-1) + k; + *bits = P - k; +#endif +#ifndef Sudden_Underflow + } + else { + *e = de - Bias - (P-1) + 1 + k; +#ifdef Pack_32 + *bits = 32*i - hi0bits(x[i-1]); +#else + *bits = (i+2)*16 - hi0bits(x[i]); +#endif + } +#endif + return b; +} +#undef d0 +#undef d1 + +static double +ratio(Bigint *a, Bigint *b) +{ + double_u da, db; + int k, ka, kb; + + dval(da) = b2d(a, &ka); + dval(db) = b2d(b, &kb); +#ifdef Pack_32 + k = ka - kb + 32*(a->wds - b->wds); +#else + k = ka - kb + 16*(a->wds - b->wds); +#endif +#ifdef IBM + if (k > 0) { + word0(da) += (k >> 2)*Exp_msk1; + if (k &= 3) + dval(da) *= 1 << k; + } + else { + k = -k; + word0(db) += (k >> 2)*Exp_msk1; + if (k &= 3) + dval(db) *= 1 << k; + } +#else + if (k > 0) + word0(da) += k*Exp_msk1; + else { + k = -k; + word0(db) += k*Exp_msk1; + } +#endif + return dval(da) / dval(db); +} + +static const double +tens[] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22 +#ifdef VAX + , 1e23, 1e24 +#endif +}; + +static const double +#ifdef IEEE_Arith +bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; +static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, +#ifdef Avoid_Underflow + 9007199254740992.*9007199254740992.e-256 + /* = 2^106 * 1e-53 */ +#else + 1e-256 +#endif +}; +/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ +/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ +#define Scale_Bit 0x10 +#define n_bigtens 5 +#else +#ifdef IBM +bigtens[] = { 1e16, 1e32, 1e64 }; +static const double tinytens[] = { 1e-16, 1e-32, 1e-64 }; +#define n_bigtens 3 +#else +bigtens[] = { 1e16, 1e32 }; +static const double tinytens[] = { 1e-16, 1e-32 }; +#define n_bigtens 2 +#endif +#endif + +#ifndef IEEE_Arith +#undef INFNAN_CHECK +#endif + +#ifdef INFNAN_CHECK + +#ifndef NAN_WORD0 +#define NAN_WORD0 0x7ff80000 +#endif + +#ifndef NAN_WORD1 +#define NAN_WORD1 0 +#endif + +static int +match(const char **sp, char *t) +{ + int c, d; + const char *s = *sp; + + while (d = *t++) { + if ((c = *++s) >= 'A' && c <= 'Z') + c += 'a' - 'A'; + if (c != d) + return 0; + } + *sp = s + 1; + return 1; +} + +#ifndef No_Hex_NaN +static void +hexnan(double *rvp, const char **sp) +{ + ULong c, x[2]; + const char *s; + int havedig, udx0, xshift; + + x[0] = x[1] = 0; + havedig = xshift = 0; + udx0 = 1; + s = *sp; + while (c = *(const unsigned char*)++s) { + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'a' && c <= 'f') + c += 10 - 'a'; + else if (c >= 'A' && c <= 'F') + c += 10 - 'A'; + else if (c <= ' ') { + if (udx0 && havedig) { + udx0 = 0; + xshift = 1; + } + continue; + } + else if (/*(*/ c == ')' && havedig) { + *sp = s + 1; + break; + } + else + return; /* invalid form: don't change *sp */ + havedig = 1; + if (xshift) { + xshift = 0; + x[0] = x[1]; + x[1] = 0; + } + if (udx0) + x[0] = (x[0] << 4) | (x[1] >> 28); + x[1] = (x[1] << 4) | c; + } + if ((x[0] &= 0xfffff) || x[1]) { + word0(*rvp) = Exp_mask | x[0]; + word1(*rvp) = x[1]; + } +} +#endif /*No_Hex_NaN*/ +#endif /* INFNAN_CHECK */ + +NO_SANITIZE("unsigned-integer-overflow", double strtod(const char *s00, char **se)); +double +strtod(const char *s00, char **se) +{ +#ifdef Avoid_Underflow + int scale; +#endif + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, + e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; + const char *s, *s0, *s1; + double aadj, adj; + double_u aadj1, rv, rv0; + Long L; + ULong y, z; + Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; +#ifdef SET_INEXACT + int inexact, oldinexact; +#endif +#ifdef Honor_FLT_ROUNDS + int rounding; +#endif +#ifdef USE_LOCALE + const char *s2; +#endif + + errno = 0; + sign = nz0 = nz = 0; + dval(rv) = 0.; + for (s = s00;;s++) + switch (*s) { + case '-': + sign = 1; + /* no break */ + case '+': + if (*++s) + goto break2; + /* no break */ + case 0: + goto ret0; + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + case ' ': + continue; + default: + goto break2; + } +break2: + if (*s == '0') { + if (s[1] == 'x' || s[1] == 'X') { + s0 = ++s; + adj = 0; + aadj = 1.0; + nd0 = -4; + + if (!*++s || !(s1 = strchr(hexdigit, *s))) goto ret0; + if (*s == '0') { + while (*++s == '0'); + s1 = strchr(hexdigit, *s); + } + if (s1 != NULL) { + do { + adj += aadj * ((s1 - hexdigit) & 15); + nd0 += 4; + aadj /= 16; + } while (*++s && (s1 = strchr(hexdigit, *s))); + } + + if (*s == '.') { + dsign = 1; + if (!*++s || !(s1 = strchr(hexdigit, *s))) goto ret0; + if (nd0 < 0) { + while (*s == '0') { + s++; + nd0 -= 4; + } + } + for (; *s && (s1 = strchr(hexdigit, *s)); ++s) { + adj += aadj * ((s1 - hexdigit) & 15); + if ((aadj /= 16) == 0.0) { + while (strchr(hexdigit, *++s)); + break; + } + } + } + else { + dsign = 0; + } + + if (*s == 'P' || *s == 'p') { + dsign = 0x2C - *++s; /* +: 2B, -: 2D */ + if (abs(dsign) == 1) s++; + else dsign = 1; + + nd = 0; + c = *s; + if (c < '0' || '9' < c) goto ret0; + do { + nd *= 10; + nd += c; + nd -= '0'; + c = *++s; + /* Float("0x0."+("0"*267)+"1fp2095") */ + if (nd + dsign * nd0 > 2095) { + while ('0' <= c && c <= '9') c = *++s; + break; + } + } while ('0' <= c && c <= '9'); + nd0 += nd * dsign; + } + else { + if (dsign) goto ret0; + } + dval(rv) = ldexp(adj, nd0); + goto ret; + } + nz0 = 1; + while (*++s == '0') ; + if (!*s) + goto ret; + } + s0 = s; + y = z = 0; + for (nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) + if (nd < 9) + y = 10*y + c - '0'; + else if (nd < DBL_DIG + 2) + z = 10*z + c - '0'; + nd0 = nd; +#ifdef USE_LOCALE + s1 = localeconv()->decimal_point; + if (c == *s1) { + c = '.'; + if (*++s1) { + s2 = s; + for (;;) { + if (*++s2 != *s1) { + c = 0; + break; + } + if (!*++s1) { + s = s2; + break; + } + } + } + } +#endif + if (c == '.') { + if (!ISDIGIT(s[1])) + goto dig_done; + c = *++s; + if (!nd) { + for (; c == '0'; c = *++s) + nz++; + if (c > '0' && c <= '9') { + s0 = s; + nf += nz; + nz = 0; + goto have_dig; + } + goto dig_done; + } + for (; c >= '0' && c <= '9'; c = *++s) { +have_dig: + nz++; + if (nd > DBL_DIG * 4) { + continue; + } + if (c -= '0') { + nf += nz; + for (i = 1; i < nz; i++) + if (nd++ < 9) + y *= 10; + else if (nd <= DBL_DIG + 2) + z *= 10; + if (nd++ < 9) + y = 10*y + c; + else if (nd <= DBL_DIG + 2) + z = 10*z + c; + nz = 0; + } + } + } +dig_done: + e = 0; + if (c == 'e' || c == 'E') { + if (!nd && !nz && !nz0) { + goto ret0; + } + s00 = s; + esign = 0; + switch (c = *++s) { + case '-': + esign = 1; + case '+': + c = *++s; + } + if (c >= '0' && c <= '9') { + while (c == '0') + c = *++s; + if (c > '0' && c <= '9') { + L = c - '0'; + s1 = s; + while ((c = *++s) >= '0' && c <= '9') + L = 10*L + c - '0'; + if (s - s1 > 8 || L > 19999) + /* Avoid confusion from exponents + * so large that e might overflow. + */ + e = 19999; /* safe for 16 bit ints */ + else + e = (int)L; + if (esign) + e = -e; + } + else + e = 0; + } + else + s = s00; + } + if (!nd) { + if (!nz && !nz0) { +#ifdef INFNAN_CHECK + /* Check for Nan and Infinity */ + switch (c) { + case 'i': + case 'I': + if (match(&s,"nf")) { + --s; + if (!match(&s,"inity")) + ++s; + word0(rv) = 0x7ff00000; + word1(rv) = 0; + goto ret; + } + break; + case 'n': + case 'N': + if (match(&s, "an")) { + word0(rv) = NAN_WORD0; + word1(rv) = NAN_WORD1; +#ifndef No_Hex_NaN + if (*s == '(') /*)*/ + hexnan(&rv, &s); +#endif + goto ret; + } + } +#endif /* INFNAN_CHECK */ +ret0: + s = s00; + sign = 0; + } + goto ret; + } + e1 = e -= nf; + + /* Now we have nd0 digits, starting at s0, followed by a + * decimal point, followed by nd-nd0 digits. The number we're + * after is the integer represented by those digits times + * 10**e */ + + if (!nd0) + nd0 = nd; + k = nd < DBL_DIG + 2 ? nd : DBL_DIG + 2; + dval(rv) = y; + if (k > 9) { +#ifdef SET_INEXACT + if (k > DBL_DIG) + oldinexact = get_inexact(); +#endif + dval(rv) = tens[k - 9] * dval(rv) + z; + } + bd0 = bb = bd = bs = delta = 0; + if (nd <= DBL_DIG +#ifndef RND_PRODQUOT +#ifndef Honor_FLT_ROUNDS + && Flt_Rounds == 1 +#endif +#endif + ) { + if (!e) + goto ret; + if (e > 0) { + if (e <= Ten_pmax) { +#ifdef VAX + goto vax_ovfl_check; +#else +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + dval(rv) = -dval(rv); + sign = 0; + } +#endif + /* rv = */ rounded_product(dval(rv), tens[e]); + goto ret; +#endif + } + i = DBL_DIG - nd; + if (e <= Ten_pmax + i) { + /* A fancier test would sometimes let us do + * this for larger i values. + */ +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + dval(rv) = -dval(rv); + sign = 0; + } +#endif + e -= i; + dval(rv) *= tens[i]; +#ifdef VAX + /* VAX exponent range is so narrow we must + * worry about overflow here... + */ +vax_ovfl_check: + word0(rv) -= P*Exp_msk1; + /* rv = */ rounded_product(dval(rv), tens[e]); + if ((word0(rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) + goto ovfl; + word0(rv) += P*Exp_msk1; +#else + /* rv = */ rounded_product(dval(rv), tens[e]); +#endif + goto ret; + } + } +#ifndef Inaccurate_Divide + else if (e >= -Ten_pmax) { +#ifdef Honor_FLT_ROUNDS + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + dval(rv) = -dval(rv); + sign = 0; + } +#endif + /* rv = */ rounded_quotient(dval(rv), tens[-e]); + goto ret; + } +#endif + } + e1 += nd - k; + +#ifdef IEEE_Arith +#ifdef SET_INEXACT + inexact = 1; + if (k <= DBL_DIG) + oldinexact = get_inexact(); +#endif +#ifdef Avoid_Underflow + scale = 0; +#endif +#ifdef Honor_FLT_ROUNDS + if ((rounding = Flt_Rounds) >= 2) { + if (sign) + rounding = rounding == 2 ? 0 : 2; + else + if (rounding != 2) + rounding = 0; + } +#endif +#endif /*IEEE_Arith*/ + + /* Get starting approximation = rv * 10**e1 */ + + if (e1 > 0) { + if ((i = e1 & 15) != 0) + dval(rv) *= tens[i]; + if (e1 &= ~15) { + if (e1 > DBL_MAX_10_EXP) { +ovfl: +#ifndef NO_ERRNO + errno = ERANGE; +#endif + /* Can't trust HUGE_VAL */ +#ifdef IEEE_Arith +#ifdef Honor_FLT_ROUNDS + switch (rounding) { + case 0: /* toward 0 */ + case 3: /* toward -infinity */ + word0(rv) = Big0; + word1(rv) = Big1; + break; + default: + word0(rv) = Exp_mask; + word1(rv) = 0; + } +#else /*Honor_FLT_ROUNDS*/ + word0(rv) = Exp_mask; + word1(rv) = 0; +#endif /*Honor_FLT_ROUNDS*/ +#ifdef SET_INEXACT + /* set overflow bit */ + dval(rv0) = 1e300; + dval(rv0) *= dval(rv0); +#endif +#else /*IEEE_Arith*/ + word0(rv) = Big0; + word1(rv) = Big1; +#endif /*IEEE_Arith*/ + if (bd0) + goto retfree; + goto ret; + } + e1 >>= 4; + for (j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= bigtens[j]; + /* The last multiplication could overflow. */ + word0(rv) -= P*Exp_msk1; + dval(rv) *= bigtens[j]; + if ((z = word0(rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-P)) + goto ovfl; + if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { + /* set to largest number */ + /* (Can't trust DBL_MAX) */ + word0(rv) = Big0; + word1(rv) = Big1; + } + else + word0(rv) += P*Exp_msk1; + } + } + else if (e1 < 0) { + e1 = -e1; + if ((i = e1 & 15) != 0) + dval(rv) /= tens[i]; + if (e1 >>= 4) { + if (e1 >= 1 << n_bigtens) + goto undfl; +#ifdef Avoid_Underflow + if (e1 & Scale_Bit) + scale = 2*P; + for (j = 0; e1 > 0; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= tinytens[j]; + if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask) + >> Exp_shift)) > 0) { + /* scaled rv is denormal; zap j low bits */ + if (j >= 32) { + word1(rv) = 0; + if (j >= 53) + word0(rv) = (P+2)*Exp_msk1; + else + word0(rv) &= 0xffffffff << (j-32); + } + else + word1(rv) &= 0xffffffff << j; + } +#else + for (j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + dval(rv) *= tinytens[j]; + /* The last multiplication could underflow. */ + dval(rv0) = dval(rv); + dval(rv) *= tinytens[j]; + if (!dval(rv)) { + dval(rv) = 2.*dval(rv0); + dval(rv) *= tinytens[j]; +#endif + if (!dval(rv)) { +undfl: + dval(rv) = 0.; +#ifndef NO_ERRNO + errno = ERANGE; +#endif + if (bd0) + goto retfree; + goto ret; + } +#ifndef Avoid_Underflow + word0(rv) = Tiny0; + word1(rv) = Tiny1; + /* The refinement below will clean + * this approximation up. + */ + } +#endif + } + } + + /* Now the hard part -- adjusting rv to the correct value.*/ + + /* Put digits into bd: true value = bd * 10^e */ + + bd0 = s2b(s0, nd0, nd, y); + + for (;;) { + bd = Balloc(bd0->k); + Bcopy(bd, bd0); + bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ + bs = i2b(1); + + if (e >= 0) { + bb2 = bb5 = 0; + bd2 = bd5 = e; + } + else { + bb2 = bb5 = -e; + bd2 = bd5 = 0; + } + if (bbe >= 0) + bb2 += bbe; + else + bd2 -= bbe; + bs2 = bb2; +#ifdef Honor_FLT_ROUNDS + if (rounding != 1) + bs2++; +#endif +#ifdef Avoid_Underflow + j = bbe - scale; + i = j + bbbits - 1; /* logb(rv) */ + if (i < Emin) /* denormal */ + j += P - Emin; + else + j = P + 1 - bbbits; +#else /*Avoid_Underflow*/ +#ifdef Sudden_Underflow +#ifdef IBM + j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); +#else + j = P + 1 - bbbits; +#endif +#else /*Sudden_Underflow*/ + j = bbe; + i = j + bbbits - 1; /* logb(rv) */ + if (i < Emin) /* denormal */ + j += P - Emin; + else + j = P + 1 - bbbits; +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + bb2 += j; + bd2 += j; +#ifdef Avoid_Underflow + bd2 += scale; +#endif + i = bb2 < bd2 ? bb2 : bd2; + if (i > bs2) + i = bs2; + if (i > 0) { + bb2 -= i; + bd2 -= i; + bs2 -= i; + } + if (bb5 > 0) { + bs = pow5mult(bs, bb5); + bb1 = mult(bs, bb); + Bfree(bb); + bb = bb1; + } + if (bb2 > 0) + bb = lshift(bb, bb2); + if (bd5 > 0) + bd = pow5mult(bd, bd5); + if (bd2 > 0) + bd = lshift(bd, bd2); + if (bs2 > 0) + bs = lshift(bs, bs2); + delta = diff(bb, bd); + dsign = delta->sign; + delta->sign = 0; + i = cmp(delta, bs); +#ifdef Honor_FLT_ROUNDS + if (rounding != 1) { + if (i < 0) { + /* Error is less than an ulp */ + if (!delta->x[0] && delta->wds <= 1) { + /* exact */ +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + if (rounding) { + if (dsign) { + adj = 1.; + goto apply_adj; + } + } + else if (!dsign) { + adj = -1.; + if (!word1(rv) + && !(word0(rv) & Frac_mask)) { + y = word0(rv) & Exp_mask; +#ifdef Avoid_Underflow + if (!scale || y > 2*P*Exp_msk1) +#else + if (y) +#endif + { + delta = lshift(delta,Log2P); + if (cmp(delta, bs) <= 0) + adj = -0.5; + } + } +apply_adj: +#ifdef Avoid_Underflow + if (scale && (y = word0(rv) & Exp_mask) + <= 2*P*Exp_msk1) + word0(adj) += (2*P+1)*Exp_msk1 - y; +#else +#ifdef Sudden_Underflow + if ((word0(rv) & Exp_mask) <= + P*Exp_msk1) { + word0(rv) += P*Exp_msk1; + dval(rv) += adj*ulp(dval(rv)); + word0(rv) -= P*Exp_msk1; + } + else +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + dval(rv) += adj*ulp(dval(rv)); + } + break; + } + adj = ratio(delta, bs); + if (adj < 1.) + adj = 1.; + if (adj <= 0x7ffffffe) { + /* adj = rounding ? ceil(adj) : floor(adj); */ + y = adj; + if (y != adj) { + if (!((rounding>>1) ^ dsign)) + y++; + adj = y; + } + } +#ifdef Avoid_Underflow + if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) + word0(adj) += (2*P+1)*Exp_msk1 - y; +#else +#ifdef Sudden_Underflow + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { + word0(rv) += P*Exp_msk1; + adj *= ulp(dval(rv)); + if (dsign) + dval(rv) += adj; + else + dval(rv) -= adj; + word0(rv) -= P*Exp_msk1; + goto cont; + } +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + adj *= ulp(dval(rv)); + if (dsign) + dval(rv) += adj; + else + dval(rv) -= adj; + goto cont; + } +#endif /*Honor_FLT_ROUNDS*/ + + if (i < 0) { + /* Error is less than half an ulp -- check for + * special case of mantissa a power of two. + */ + if (dsign || word1(rv) || word0(rv) & Bndry_mask +#ifdef IEEE_Arith +#ifdef Avoid_Underflow + || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1 +#else + || (word0(rv) & Exp_mask) <= Exp_msk1 +#endif +#endif + ) { +#ifdef SET_INEXACT + if (!delta->x[0] && delta->wds <= 1) + inexact = 0; +#endif + break; + } + if (!delta->x[0] && delta->wds <= 1) { + /* exact result */ +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + delta = lshift(delta,Log2P); + if (cmp(delta, bs) > 0) + goto drop_down; + break; + } + if (i == 0) { + /* exactly half-way between */ + if (dsign) { + if ((word0(rv) & Bndry_mask1) == Bndry_mask1 + && word1(rv) == ( +#ifdef Avoid_Underflow + (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) + ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : +#endif + 0xffffffff)) { + /*boundary case -- increment exponent*/ + word0(rv) = (word0(rv) & Exp_mask) + + Exp_msk1 +#ifdef IBM + | Exp_msk1 >> 4 +#endif + ; + word1(rv) = 0; +#ifdef Avoid_Underflow + dsign = 0; +#endif + break; + } + } + else if (!(word0(rv) & Bndry_mask) && !word1(rv)) { +drop_down: + /* boundary case -- decrement exponent */ +#ifdef Sudden_Underflow /*{{*/ + L = word0(rv) & Exp_mask; +#ifdef IBM + if (L < Exp_msk1) +#else +#ifdef Avoid_Underflow + if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) +#else + if (L <= Exp_msk1) +#endif /*Avoid_Underflow*/ +#endif /*IBM*/ + goto undfl; + L -= Exp_msk1; +#else /*Sudden_Underflow}{*/ +#ifdef Avoid_Underflow + if (scale) { + L = word0(rv) & Exp_mask; + if (L <= (2*P+1)*Exp_msk1) { + if (L > (P+2)*Exp_msk1) + /* round even ==> */ + /* accept rv */ + break; + /* rv = smallest denormal */ + goto undfl; + } + } +#endif /*Avoid_Underflow*/ + L = (word0(rv) & Exp_mask) - Exp_msk1; +#endif /*Sudden_Underflow}}*/ + word0(rv) = L | Bndry_mask1; + word1(rv) = 0xffffffff; +#ifdef IBM + goto cont; +#else + break; +#endif + } +#ifndef ROUND_BIASED + if (!(word1(rv) & LSB)) + break; +#endif + if (dsign) + dval(rv) += ulp(dval(rv)); +#ifndef ROUND_BIASED + else { + dval(rv) -= ulp(dval(rv)); +#ifndef Sudden_Underflow + if (!dval(rv)) + goto undfl; +#endif + } +#ifdef Avoid_Underflow + dsign = 1 - dsign; +#endif +#endif + break; + } + if ((aadj = ratio(delta, bs)) <= 2.) { + if (dsign) + aadj = dval(aadj1) = 1.; + else if (word1(rv) || word0(rv) & Bndry_mask) { +#ifndef Sudden_Underflow + if (word1(rv) == Tiny1 && !word0(rv)) + goto undfl; +#endif + aadj = 1.; + dval(aadj1) = -1.; + } + else { + /* special case -- power of FLT_RADIX to be */ + /* rounded down... */ + + if (aadj < 2./FLT_RADIX) + aadj = 1./FLT_RADIX; + else + aadj *= 0.5; + dval(aadj1) = -aadj; + } + } + else { + aadj *= 0.5; + dval(aadj1) = dsign ? aadj : -aadj; +#ifdef Check_FLT_ROUNDS + switch (Rounding) { + case 2: /* towards +infinity */ + dval(aadj1) -= 0.5; + break; + case 0: /* towards 0 */ + case 3: /* towards -infinity */ + dval(aadj1) += 0.5; + } +#else + if (Flt_Rounds == 0) + dval(aadj1) += 0.5; +#endif /*Check_FLT_ROUNDS*/ + } + y = word0(rv) & Exp_mask; + + /* Check for overflow */ + + if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { + dval(rv0) = dval(rv); + word0(rv) -= P*Exp_msk1; + adj = dval(aadj1) * ulp(dval(rv)); + dval(rv) += adj; + if ((word0(rv) & Exp_mask) >= + Exp_msk1*(DBL_MAX_EXP+Bias-P)) { + if (word0(rv0) == Big0 && word1(rv0) == Big1) + goto ovfl; + word0(rv) = Big0; + word1(rv) = Big1; + goto cont; + } + else + word0(rv) += P*Exp_msk1; + } + else { +#ifdef Avoid_Underflow + if (scale && y <= 2*P*Exp_msk1) { + if (aadj <= 0x7fffffff) { + if ((z = (int)aadj) <= 0) + z = 1; + aadj = z; + dval(aadj1) = dsign ? aadj : -aadj; + } + word0(aadj1) += (2*P+1)*Exp_msk1 - y; + } + adj = dval(aadj1) * ulp(dval(rv)); + dval(rv) += adj; +#else +#ifdef Sudden_Underflow + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { + dval(rv0) = dval(rv); + word0(rv) += P*Exp_msk1; + adj = dval(aadj1) * ulp(dval(rv)); + dval(rv) += adj; +#ifdef IBM + if ((word0(rv) & Exp_mask) < P*Exp_msk1) +#else + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) +#endif + { + if (word0(rv0) == Tiny0 && word1(rv0) == Tiny1) + goto undfl; + word0(rv) = Tiny0; + word1(rv) = Tiny1; + goto cont; + } + else + word0(rv) -= P*Exp_msk1; + } + else { + adj = dval(aadj1) * ulp(dval(rv)); + dval(rv) += adj; + } +#else /*Sudden_Underflow*/ + /* Compute adj so that the IEEE rounding rules will + * correctly round rv + adj in some half-way cases. + * If rv * ulp(rv) is denormalized (i.e., + * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid + * trouble from bits lost to denormalization; + * example: 1.2e-307 . + */ + if (y <= (P-1)*Exp_msk1 && aadj > 1.) { + dval(aadj1) = (double)(int)(aadj + 0.5); + if (!dsign) + dval(aadj1) = -dval(aadj1); + } + adj = dval(aadj1) * ulp(dval(rv)); + dval(rv) += adj; +#endif /*Sudden_Underflow*/ +#endif /*Avoid_Underflow*/ + } + z = word0(rv) & Exp_mask; +#ifndef SET_INEXACT +#ifdef Avoid_Underflow + if (!scale) +#endif + if (y == z) { + /* Can we stop now? */ + L = (Long)aadj; + aadj -= L; + /* The tolerances below are conservative. */ + if (dsign || word1(rv) || word0(rv) & Bndry_mask) { + if (aadj < .4999999 || aadj > .5000001) + break; + } + else if (aadj < .4999999/FLT_RADIX) + break; + } +#endif +cont: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(delta); + } +#ifdef SET_INEXACT + if (inexact) { + if (!oldinexact) { + word0(rv0) = Exp_1 + (70 << Exp_shift); + word1(rv0) = 0; + dval(rv0) += 1.; + } + } + else if (!oldinexact) + clear_inexact(); +#endif +#ifdef Avoid_Underflow + if (scale) { + word0(rv0) = Exp_1 - 2*P*Exp_msk1; + word1(rv0) = 0; + dval(rv) *= dval(rv0); +#ifndef NO_ERRNO + /* try to avoid the bug of testing an 8087 register value */ + if (word0(rv) == 0 && word1(rv) == 0) + errno = ERANGE; +#endif + } +#endif /* Avoid_Underflow */ +#ifdef SET_INEXACT + if (inexact && !(word0(rv) & Exp_mask)) { + /* set underflow bit */ + dval(rv0) = 1e-300; + dval(rv0) *= dval(rv0); + } +#endif +retfree: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); +ret: + if (se) + *se = (char *)s; + return sign ? -dval(rv) : dval(rv); +} + +NO_SANITIZE("unsigned-integer-overflow", static int quorem(Bigint *b, Bigint *S)); +static int +quorem(Bigint *b, Bigint *S) +{ + int n; + ULong *bx, *bxe, q, *sx, *sxe; +#ifdef ULLong + ULLong borrow, carry, y, ys; +#else + ULong borrow, carry, y, ys; +#ifdef Pack_32 + ULong si, z, zs; +#endif +#endif + + n = S->wds; +#ifdef DEBUG + /*debug*/ if (b->wds > n) + /*debug*/ Bug("oversize b in quorem"); +#endif + if (b->wds < n) + return 0; + sx = S->x; + sxe = sx + --n; + bx = b->x; + bxe = bx + n; + q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ +#ifdef DEBUG + /*debug*/ if (q > 9) + /*debug*/ Bug("oversized quotient in quorem"); +#endif + if (q) { + borrow = 0; + carry = 0; + do { +#ifdef ULLong + ys = *sx++ * (ULLong)q + carry; + carry = ys >> 32; + y = *bx - (ys & FFFFFFFF) - borrow; + borrow = y >> 32 & (ULong)1; + *bx++ = (ULong)(y & FFFFFFFF); +#else +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) * q + carry; + zs = (si >> 16) * q + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#else + ys = *sx++ * q + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } while (sx <= sxe); + if (!*bxe) { + bx = b->x; + while (--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + if (cmp(b, S) >= 0) { + q++; + borrow = 0; + carry = 0; + bx = b->x; + sx = S->x; + do { +#ifdef ULLong + ys = *sx++ + carry; + carry = ys >> 32; + y = *bx - (ys & FFFFFFFF) - borrow; + borrow = y >> 32 & (ULong)1; + *bx++ = (ULong)(y & FFFFFFFF); +#else +#ifdef Pack_32 + si = *sx++; + ys = (si & 0xffff) + carry; + zs = (si >> 16) + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#else + ys = *sx++ + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } while (sx <= sxe); + bx = b->x; + bxe = bx + n; + if (!*bxe) { + while (--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + return q; +} + +#ifndef MULTIPLE_THREADS +static char *dtoa_result; +#endif + +#ifndef MULTIPLE_THREADS +static char * +rv_alloc(int i) +{ + return dtoa_result = MALLOC(i); +} +#else +#define rv_alloc(i) MALLOC(i) +#endif + +static char * +nrv_alloc(const char *s, char **rve, size_t n) +{ + char *rv, *t; + + t = rv = rv_alloc(n); + while ((*t = *s++) != 0) t++; + if (rve) + *rve = t; + return rv; +} + +#define rv_strdup(s, rve) nrv_alloc((s), (rve), strlen(s)+1) + +#ifndef MULTIPLE_THREADS +/* freedtoa(s) must be used to free values s returned by dtoa + * when MULTIPLE_THREADS is #defined. It should be used in all cases, + * but for consistency with earlier versions of dtoa, it is optional + * when MULTIPLE_THREADS is not defined. + */ + +static void +freedtoa(char *s) +{ + FREE(s); +} +#endif + +static const char INFSTR[] = "Infinity"; +static const char NANSTR[] = "NaN"; +static const char ZEROSTR[] = "0"; + +/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. + * + * Inspired by "How to Print Floating-Point Numbers Accurately" by + * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. + * + * Modifications: + * 1. Rather than iterating, we use a simple numeric overestimate + * to determine k = floor(log10(d)). We scale relevant + * quantities using O(log2(k)) rather than O(k) multiplications. + * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't + * try to generate digits strictly left to right. Instead, we + * compute with fewer bits and propagate the carry if necessary + * when rounding the final digit up. This is often faster. + * 3. Under the assumption that input will be rounded nearest, + * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. + * That is, we allow equality in stopping tests when the + * round-nearest rule will give the same floating-point value + * as would satisfaction of the stopping test with strict + * inequality. + * 4. We remove common factors of powers of 2 from relevant + * quantities. + * 5. When converting floating-point integers less than 1e16, + * we use floating-point arithmetic rather than resorting + * to multiple-precision integers. + * 6. When asked to produce fewer than 15 digits, we first try + * to get by with floating-point arithmetic; we resort to + * multiple-precision integer arithmetic only if we cannot + * guarantee that the floating-point calculation has given + * the correctly rounded result. For k requested digits and + * "uniformly" distributed input, the probability is + * something like 10^(k-15) that we must resort to the Long + * calculation. + */ + +char * +dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve) +{ + /* Arguments ndigits, decpt, sign are similar to those + of ecvt and fcvt; trailing zeros are suppressed from + the returned string. If not null, *rve is set to point + to the end of the return value. If d is +-Infinity or NaN, + then *decpt is set to 9999. + + mode: + 0 ==> shortest string that yields d when read in + and rounded to nearest. + 1 ==> like 0, but with Steele & White stopping rule; + e.g. with IEEE P754 arithmetic , mode 0 gives + 1e23 whereas mode 1 gives 9.999999999999999e22. + 2 ==> max(1,ndigits) significant digits. This gives a + return value similar to that of ecvt, except + that trailing zeros are suppressed. + 3 ==> through ndigits past the decimal point. This + gives a return value similar to that from fcvt, + except that trailing zeros are suppressed, and + ndigits can be negative. + 4,5 ==> similar to 2 and 3, respectively, but (in + round-nearest mode) with the tests of mode 0 to + possibly return a shorter string that rounds to d. + With IEEE arithmetic and compilation with + -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same + as modes 2 and 3 when FLT_ROUNDS != 1. + 6-9 ==> Debugging modes similar to mode - 4: don't try + fast floating-point estimate (if applicable). + + Values of mode other than 0-9 are treated as mode 0. + + Sufficient space is allocated to the return value + to hold the suppressed trailing zeros. + */ + + int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, + j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, + spec_case, try_quick, half = 0; + Long L; +#ifndef Sudden_Underflow + int denorm; + ULong x; +#endif + Bigint *b, *b1, *delta, *mlo = 0, *mhi = 0, *S; + double ds; + double_u d, d2, eps; + char *s, *s0; +#ifdef Honor_FLT_ROUNDS + int rounding; +#endif +#ifdef SET_INEXACT + int inexact, oldinexact; +#endif + + dval(d) = d_; + +#ifndef MULTIPLE_THREADS + if (dtoa_result) { + freedtoa(dtoa_result); + dtoa_result = 0; + } +#endif + + if (word0(d) & Sign_bit) { + /* set sign for everything, including 0's and NaNs */ + *sign = 1; + word0(d) &= ~Sign_bit; /* clear sign bit */ + } + else + *sign = 0; + +#if defined(IEEE_Arith) + defined(VAX) +#ifdef IEEE_Arith + if ((word0(d) & Exp_mask) == Exp_mask) +#else + if (word0(d) == 0x8000) +#endif + { + /* Infinity or NaN */ + *decpt = 9999; +#ifdef IEEE_Arith + if (!word1(d) && !(word0(d) & 0xfffff)) + return rv_strdup(INFSTR, rve); +#endif + return rv_strdup(NANSTR, rve); + } +#endif +#ifdef IBM + dval(d) += 0; /* normalize */ +#endif + if (!dval(d)) { + *decpt = 1; + return rv_strdup(ZEROSTR, rve); + } + +#ifdef SET_INEXACT + try_quick = oldinexact = get_inexact(); + inexact = 1; +#endif +#ifdef Honor_FLT_ROUNDS + if ((rounding = Flt_Rounds) >= 2) { + if (*sign) + rounding = rounding == 2 ? 0 : 2; + else + if (rounding != 2) + rounding = 0; + } +#endif + + b = d2b(dval(d), &be, &bbits); +#ifdef Sudden_Underflow + i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); +#else + if ((i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) { +#endif + dval(d2) = dval(d); + word0(d2) &= Frac_mask1; + word0(d2) |= Exp_11; +#ifdef IBM + if (j = 11 - hi0bits(word0(d2) & Frac_mask)) + dval(d2) /= 1 << j; +#endif + + /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 + * log10(x) = log(x) / log(10) + * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) + * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * + * This suggests computing an approximation k to log10(d) by + * + * k = (i - Bias)*0.301029995663981 + * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); + * + * We want k to be too large rather than too small. + * The error in the first-order Taylor series approximation + * is in our favor, so we just round up the constant enough + * to compensate for any error in the multiplication of + * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, + * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, + * adding 1e-13 to the constant term more than suffices. + * Hence we adjust the constant term to 0.1760912590558. + * (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ + + i -= Bias; +#ifdef IBM + i <<= 2; + i += j; +#endif +#ifndef Sudden_Underflow + denorm = 0; + } + else { + /* d is denormalized */ + + i = bbits + be + (Bias + (P-1) - 1); + x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32) + : word1(d) << (32 - i); + dval(d2) = x; + word0(d2) -= 31*Exp_msk1; /* adjust exponent */ + i -= (Bias + (P-1) - 1) + 1; + denorm = 1; + } +#endif + ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + k = (int)ds; + if (ds < 0. && ds != k) + k--; /* want k = floor(ds) */ + k_check = 1; + if (k >= 0 && k <= Ten_pmax) { + if (dval(d) < tens[k]) + k--; + k_check = 0; + } + j = bbits - i - 1; + if (j >= 0) { + b2 = 0; + s2 = j; + } + else { + b2 = -j; + s2 = 0; + } + if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; + } + else { + b2 -= k; + b5 = -k; + s5 = 0; + } + if (mode < 0 || mode > 9) + mode = 0; + +#ifndef SET_INEXACT +#ifdef Check_FLT_ROUNDS + try_quick = Rounding == 1; +#else + try_quick = 1; +#endif +#endif /*SET_INEXACT*/ + + if (mode > 5) { + mode -= 4; + try_quick = 0; + } + leftright = 1; + ilim = ilim1 = -1; + switch (mode) { + case 0: + case 1: + i = 18; + ndigits = 0; + break; + case 2: + leftright = 0; + /* no break */ + case 4: + if (ndigits <= 0) + ndigits = 1; + ilim = ilim1 = i = ndigits; + break; + case 3: + leftright = 0; + /* no break */ + case 5: + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) + i = 1; + } + s = s0 = rv_alloc(i+1); + +#ifdef Honor_FLT_ROUNDS + if (mode > 1 && rounding != 1) + leftright = 0; +#endif + + if (ilim >= 0 && ilim <= Quick_max && try_quick) { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + dval(d2) = dval(d); + k0 = k; + ilim0 = ilim; + ieps = 2; /* conservative */ + if (k > 0) { + ds = tens[k&0xf]; + j = k >> 4; + if (j & Bletch) { + /* prevent overflows */ + j &= Bletch - 1; + dval(d) /= bigtens[n_bigtens-1]; + ieps++; + } + for (; j; j >>= 1, i++) + if (j & 1) { + ieps++; + ds *= bigtens[i]; + } + dval(d) /= ds; + } + else if ((j1 = -k) != 0) { + dval(d) *= tens[j1 & 0xf]; + for (j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { + ieps++; + dval(d) *= bigtens[i]; + } + } + if (k_check && dval(d) < 1. && ilim > 0) { + if (ilim1 <= 0) + goto fast_failed; + ilim = ilim1; + k--; + dval(d) *= 10.; + ieps++; + } + dval(eps) = ieps*dval(d) + 7.; + word0(eps) -= (P-1)*Exp_msk1; + if (ilim == 0) { + S = mhi = 0; + dval(d) -= 5.; + if (dval(d) > dval(eps)) + goto one_digit; + if (dval(d) < -dval(eps)) + goto no_digits; + goto fast_failed; + } +#ifndef No_leftright + if (leftright) { + /* Use Steele & White method of only + * generating digits needed. + */ + dval(eps) = 0.5/tens[ilim-1] - dval(eps); + for (i = 0;;) { + L = (int)dval(d); + dval(d) -= L; + *s++ = '0' + (int)L; + if (dval(d) < dval(eps)) + goto ret1; + if (1. - dval(d) < dval(eps)) + goto bump_up; + if (++i >= ilim) + break; + dval(eps) *= 10.; + dval(d) *= 10.; + } + } + else { +#endif + /* Generate ilim digits, then fix them up. */ + dval(eps) *= tens[ilim-1]; + for (i = 1;; i++, dval(d) *= 10.) { + L = (Long)(dval(d)); + if (!(dval(d) -= L)) + ilim = i; + *s++ = '0' + (int)L; + if (i == ilim) { + if (dval(d) > 0.5 + dval(eps)) + goto bump_up; + else if (dval(d) < 0.5 - dval(eps)) { + while (*--s == '0') ; + s++; + goto ret1; + } + half = 1; + if ((*(s-1) - '0') & 1) { + goto bump_up; + } + break; + } + } +#ifndef No_leftright + } +#endif +fast_failed: + s = s0; + dval(d) = dval(d2); + k = k0; + ilim = ilim0; + } + + /* Do we have a "small" integer? */ + + if (be >= 0 && k <= Int_max) { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) { + S = mhi = 0; + if (ilim < 0 || dval(d) <= 5*ds) + goto no_digits; + goto one_digit; + } + for (i = 1;; i++, dval(d) *= 10.) { + L = (Long)(dval(d) / ds); + dval(d) -= L*ds; +#ifdef Check_FLT_ROUNDS + /* If FLT_ROUNDS == 2, L will usually be high by 1 */ + if (dval(d) < 0) { + L--; + dval(d) += ds; + } +#endif + *s++ = '0' + (int)L; + if (!dval(d)) { +#ifdef SET_INEXACT + inexact = 0; +#endif + break; + } + if (i == ilim) { +#ifdef Honor_FLT_ROUNDS + if (mode > 1) + switch (rounding) { + case 0: goto ret1; + case 2: goto bump_up; + } +#endif + dval(d) += dval(d); + if (dval(d) > ds || (dval(d) == ds && (L & 1))) { +bump_up: + while (*--s == '9') + if (s == s0) { + k++; + *s = '0'; + break; + } + ++*s++; + } + break; + } + } + goto ret1; + } + + m2 = b2; + m5 = b5; + if (leftright) { + i = +#ifndef Sudden_Underflow + denorm ? be + (Bias + (P-1) - 1 + 1) : +#endif +#ifdef IBM + 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); +#else + 1 + P - bbits; +#endif + b2 += i; + s2 += i; + mhi = i2b(1); + } + if (m2 > 0 && s2 > 0) { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; + } + if (b5 > 0) { + if (leftright) { + if (m5 > 0) { + mhi = pow5mult(mhi, m5); + b1 = mult(mhi, b); + Bfree(b); + b = b1; + } + if ((j = b5 - m5) != 0) + b = pow5mult(b, j); + } + else + b = pow5mult(b, b5); + } + S = i2b(1); + if (s5 > 0) + S = pow5mult(S, s5); + + /* Check for special case that d is a normalized power of 2. */ + + spec_case = 0; + if ((mode < 2 || leftright) +#ifdef Honor_FLT_ROUNDS + && rounding == 1 +#endif + ) { + if (!word1(d) && !(word0(d) & Bndry_mask) +#ifndef Sudden_Underflow + && word0(d) & (Exp_mask & ~Exp_msk1) +#endif + ) { + /* The special case */ + b2 += Log2P; + s2 += Log2P; + spec_case = 1; + } + } + + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once + * and for all and pass them and a shift to quorem, so it + * can do shifts and ors to compute the numerator for q. + */ +#ifdef Pack_32 + if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0) + i = 32 - i; +#else + if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) != 0) + i = 16 - i; +#endif + if (i > 4) { + i -= 4; + b2 += i; + m2 += i; + s2 += i; + } + else if (i < 4) { + i += 28; + b2 += i; + m2 += i; + s2 += i; + } + if (b2 > 0) + b = lshift(b, b2); + if (s2 > 0) + S = lshift(S, s2); + if (k_check) { + if (cmp(b,S) < 0) { + k--; + b = multadd(b, 10, 0); /* we botched the k estimate */ + if (leftright) + mhi = multadd(mhi, 10, 0); + ilim = ilim1; + } + } + if (ilim <= 0 && (mode == 3 || mode == 5)) { + if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { + /* no digits, fcvt style */ +no_digits: + k = -1 - ndigits; + goto ret; + } +one_digit: + *s++ = '1'; + k++; + goto ret; + } + if (leftright) { + if (m2 > 0) + mhi = lshift(mhi, m2); + + /* Compute mlo -- check for special case + * that d is a normalized power of 2. + */ + + mlo = mhi; + if (spec_case) { + mhi = Balloc(mhi->k); + Bcopy(mhi, mlo); + mhi = lshift(mhi, Log2P); + } + + for (i = 1;;i++) { + dig = quorem(b,S) + '0'; + /* Do we yet have the shortest decimal string + * that will round to d? + */ + j = cmp(b, mlo); + delta = diff(S, mhi); + j1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta); +#ifndef ROUND_BIASED + if (j1 == 0 && mode != 1 && !(word1(d) & 1) +#ifdef Honor_FLT_ROUNDS + && rounding >= 1 +#endif + ) { + if (dig == '9') + goto round_9_up; + if (j > 0) + dig++; +#ifdef SET_INEXACT + else if (!b->x[0] && b->wds <= 1) + inexact = 0; +#endif + *s++ = dig; + goto ret; + } +#endif + if (j < 0 || (j == 0 && mode != 1 +#ifndef ROUND_BIASED + && !(word1(d) & 1) +#endif + )) { + if (!b->x[0] && b->wds <= 1) { +#ifdef SET_INEXACT + inexact = 0; +#endif + goto accept_dig; + } +#ifdef Honor_FLT_ROUNDS + if (mode > 1) + switch (rounding) { + case 0: goto accept_dig; + case 2: goto keep_dig; + } +#endif /*Honor_FLT_ROUNDS*/ + if (j1 > 0) { + b = lshift(b, 1); + j1 = cmp(b, S); + if ((j1 > 0 || (j1 == 0 && (dig & 1))) && dig++ == '9') + goto round_9_up; + } +accept_dig: + *s++ = dig; + goto ret; + } + if (j1 > 0) { +#ifdef Honor_FLT_ROUNDS + if (!rounding) + goto accept_dig; +#endif + if (dig == '9') { /* possible if i == 1 */ +round_9_up: + *s++ = '9'; + goto roundoff; + } + *s++ = dig + 1; + goto ret; + } +#ifdef Honor_FLT_ROUNDS +keep_dig: +#endif + *s++ = dig; + if (i == ilim) + break; + b = multadd(b, 10, 0); + if (mlo == mhi) + mlo = mhi = multadd(mhi, 10, 0); + else { + mlo = multadd(mlo, 10, 0); + mhi = multadd(mhi, 10, 0); + } + } + } + else + for (i = 1;; i++) { + *s++ = dig = quorem(b,S) + '0'; + if (!b->x[0] && b->wds <= 1) { +#ifdef SET_INEXACT + inexact = 0; +#endif + goto ret; + } + if (i >= ilim) + break; + b = multadd(b, 10, 0); + } + + /* Round off last digit */ + +#ifdef Honor_FLT_ROUNDS + switch (rounding) { + case 0: goto trimzeros; + case 2: goto roundoff; + } +#endif + b = lshift(b, 1); + j = cmp(b, S); + if (j > 0 || (j == 0 && (dig & 1))) { + roundoff: + while (*--s == '9') + if (s == s0) { + k++; + *s++ = '1'; + goto ret; + } + if (!half || (*s - '0') & 1) + ++*s; + } + else { + while (*--s == '0') ; + } + s++; +ret: + Bfree(S); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } +ret1: +#ifdef SET_INEXACT + if (inexact) { + if (!oldinexact) { + word0(d) = Exp_1 + (70 << Exp_shift); + word1(d) = 0; + dval(d) += 1.; + } + } + else if (!oldinexact) + clear_inexact(); +#endif + Bfree(b); + *s = 0; + *decpt = k + 1; + if (rve) + *rve = s; + return s0; +} + +/*- + * Copyright (c) 2004-2008 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#define DBL_MANH_SIZE 20 +#define DBL_MANL_SIZE 32 +#define DBL_ADJ (DBL_MAX_EXP - 2) +#define SIGFIGS ((DBL_MANT_DIG + 3) / 4 + 1) +#define dexp_get(u) ((int)(word0(u) >> Exp_shift) & ~Exp_msk1) +#define dexp_set(u,v) (word0(u) = (((int)(word0(u)) & ~Exp_mask) | ((v) << Exp_shift))) +#define dmanh_get(u) ((uint32_t)(word0(u) & Frac_mask)) +#define dmanl_get(u) ((uint32_t)word1(u)) + + +/* + * This procedure converts a double-precision number in IEEE format + * into a string of hexadecimal digits and an exponent of 2. Its + * behavior is bug-for-bug compatible with dtoa() in mode 2, with the + * following exceptions: + * + * - An ndigits < 0 causes it to use as many digits as necessary to + * represent the number exactly. + * - The additional xdigs argument should point to either the string + * "0123456789ABCDEF" or the string "0123456789abcdef", depending on + * which case is desired. + * - This routine does not repeat dtoa's mistake of setting decpt + * to 9999 in the case of an infinity or NaN. INT_MAX is used + * for this purpose instead. + * + * Note that the C99 standard does not specify what the leading digit + * should be for non-zero numbers. For instance, 0x1.3p3 is the same + * as 0x2.6p2 is the same as 0x4.cp3. This implementation always makes + * the leading digit a 1. This ensures that the exponent printed is the + * actual base-2 exponent, i.e., ilogb(d). + * + * Inputs: d, xdigs, ndigits + * Outputs: decpt, sign, rve + */ +char * +hdtoa(double d, const char *xdigs, int ndigits, int *decpt, int *sign, char **rve) +{ + U u; + char *s, *s0; + int bufsize; + uint32_t manh, manl; + + u.d = d; + if (word0(u) & Sign_bit) { + /* set sign for everything, including 0's and NaNs */ + *sign = 1; + word0(u) &= ~Sign_bit; /* clear sign bit */ + } + else + *sign = 0; + + if (isinf(d)) { /* FP_INFINITE */ + *decpt = INT_MAX; + return rv_strdup(INFSTR, rve); + } + else if (isnan(d)) { /* FP_NAN */ + *decpt = INT_MAX; + return rv_strdup(NANSTR, rve); + } + else if (d == 0.0) { /* FP_ZERO */ + *decpt = 1; + return rv_strdup(ZEROSTR, rve); + } + else if (dexp_get(u)) { /* FP_NORMAL */ + *decpt = dexp_get(u) - DBL_ADJ; + } + else { /* FP_SUBNORMAL */ + u.d *= 5.363123171977039e+154 /* 0x1p514 */; + *decpt = dexp_get(u) - (514 + DBL_ADJ); + } + + if (ndigits == 0) /* dtoa() compatibility */ + ndigits = 1; + + /* + * If ndigits < 0, we are expected to auto-size, so we allocate + * enough space for all the digits. + */ + bufsize = (ndigits > 0) ? ndigits : SIGFIGS; + s0 = rv_alloc(bufsize+1); + + /* Round to the desired number of digits. */ + if (SIGFIGS > ndigits && ndigits > 0) { + float redux = 1.0f; + int offset = 4 * ndigits + DBL_MAX_EXP - 4 - DBL_MANT_DIG; + dexp_set(u, offset); + u.d += redux; + u.d -= redux; + *decpt += dexp_get(u) - offset; + } + + manh = dmanh_get(u); + manl = dmanl_get(u); + *s0 = '1'; + for (s = s0 + 1; s < s0 + bufsize; s++) { + *s = xdigs[(manh >> (DBL_MANH_SIZE - 4)) & 0xf]; + manh = (manh << 4) | (manl >> (DBL_MANL_SIZE - 4)); + manl <<= 4; + } + + /* If ndigits < 0, we are expected to auto-size the precision. */ + if (ndigits < 0) { + for (ndigits = SIGFIGS; s0[ndigits - 1] == '0'; ndigits--) + ; + } + + s = s0 + ndigits; + *s = '\0'; + if (rve != NULL) + *rve = s; + return (s0); +} + +#ifdef __cplusplus +#if 0 +{ /* satisfy cc-mode */ +#endif +} +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/static_assert.h b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/static_assert.h new file mode 100644 index 00000000..9295729b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/ext/bigdecimal/static_assert.h @@ -0,0 +1,54 @@ +#ifndef BIGDECIMAL_STATIC_ASSERT_H +#define BIGDECIMAL_STATIC_ASSERT_H + +#include "feature.h" + +#ifdef HAVE_RUBY_INTERNAL_STATIC_ASSERT_H +# include +#endif + +#ifdef RBIMPL_STATIC_ASSERT +# define STATIC_ASSERT RBIMPL_STATIC_ASSERT +#endif + +#ifndef STATIC_ASSERT +# /* The following section is copied from CRuby's static_assert.h */ + +# if defined(__cplusplus) && defined(__cpp_static_assert) +# /* https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations */ +# define BIGDECIMAL_STATIC_ASSERT0 static_assert + +# elif defined(__cplusplus) && defined(_MSC_VER) && _MSC_VER >= 1600 +# define BIGDECIMAL_STATIC_ASSERT0 static_assert + +# elif defined(__INTEL_CXX11_MODE__) +# define BIGDECIMAL_STATIC_ASSERT0 static_assert + +# elif defined(__cplusplus) && __cplusplus >= 201103L +# define BIGDECIMAL_STATIC_ASSERT0 static_assert + +# elif defined(__cplusplus) && __has_extension(cxx_static_assert) +# define BIGDECIMAL_STATIC_ASSERT0 __extension__ static_assert + +# elif defined(__STDC_VERSION__) && __has_extension(c_static_assert) +# define BIGDECIMAL_STATIC_ASSERT0 __extension__ _Static_assert + +# elif defined(__STDC_VERSION__) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +# define BIGDECIMAL_STATIC_ASSERT0 __extension__ _Static_assert +#endif + +# if defined(__DOXYGEN__) +# define STATIC_ASSERT static_assert + +# elif defined(BIGDECIMAL_STATIC_ASSERT0) +# define STATIC_ASSERT(name, expr) \ + BIGDECIMAL_STATIC_ASSERT0(expr, #name ": " #expr) + +# else +# define STATIC_ASSERT(name, expr) \ + typedef int static_assert_ ## name ## _check[1 - 2 * !(expr)] +# endif +#endif /* STATIC_ASSERT */ + + +#endif /* BIGDECIMAL_STATIC_ASSERT_H */ diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/lib/bigdecimal.rb b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/lib/bigdecimal.rb new file mode 100644 index 00000000..82b3e1b7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/lib/bigdecimal.rb @@ -0,0 +1,5 @@ +if RUBY_ENGINE == 'jruby' + JRuby::Util.load_ext("org.jruby.ext.bigdecimal.BigDecimalLibrary") +else + require 'bigdecimal.so' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/lib/bigdecimal.so b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/lib/bigdecimal.so new file mode 100755 index 00000000..02216d0f Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/lib/bigdecimal.so differ diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/lib/bigdecimal/jacobian.rb b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/lib/bigdecimal/jacobian.rb new file mode 100644 index 00000000..4448024c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/lib/bigdecimal/jacobian.rb @@ -0,0 +1,90 @@ +# frozen_string_literal: false + +require 'bigdecimal' + +# require 'bigdecimal/jacobian' +# +# Provides methods to compute the Jacobian matrix of a set of equations at a +# point x. In the methods below: +# +# f is an Object which is used to compute the Jacobian matrix of the equations. +# It must provide the following methods: +# +# f.values(x):: returns the values of all functions at x +# +# f.zero:: returns 0.0 +# f.one:: returns 1.0 +# f.two:: returns 2.0 +# f.ten:: returns 10.0 +# +# f.eps:: returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal. +# +# x is the point at which to compute the Jacobian. +# +# fx is f.values(x). +# +module Jacobian + module_function + + # Determines the equality of two numbers by comparing to zero, or using the epsilon value + def isEqual(a,b,zero=0.0,e=1.0e-8) + aa = a.abs + bb = b.abs + if aa == zero && bb == zero then + true + else + if ((a-b)/(aa+bb)).abs < e then + true + else + false + end + end + end + + + # Computes the derivative of +f[i]+ at +x[i]+. + # +fx+ is the value of +f+ at +x+. + def dfdxi(f,fx,x,i) + nRetry = 0 + n = x.size + xSave = x[i] + ok = 0 + ratio = f.ten*f.ten*f.ten + dx = x[i].abs/ratio + dx = fx[i].abs/ratio if isEqual(dx,f.zero,f.zero,f.eps) + dx = f.one/f.ten if isEqual(dx,f.zero,f.zero,f.eps) + until ok>0 do + deriv = [] + nRetry += 1 + if nRetry > 100 + raise "Singular Jacobian matrix. No change at x[" + i.to_s + "]" + end + dx = dx*f.two + x[i] += dx + fxNew = f.values(x) + for j in 0...n do + if !isEqual(fxNew[j],fx[j],f.zero,f.eps) then + ok += 1 + deriv <<= (fxNew[j]-fx[j])/dx + else + deriv <<= f.zero + end + end + x[i] = xSave + end + deriv + end + + # Computes the Jacobian of +f+ at +x+. +fx+ is the value of +f+ at +x+. + def jacobian(f,fx,x) + n = x.size + dfdx = Array.new(n*n) + for i in 0...n do + df = dfdxi(f,fx,x,i) + for j in 0...n do + dfdx[j*n+i] = df[j] + end + end + dfdx + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/lib/bigdecimal/ludcmp.rb b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/lib/bigdecimal/ludcmp.rb new file mode 100644 index 00000000..dd265e48 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/lib/bigdecimal/ludcmp.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: false +require 'bigdecimal' + +# +# Solves a*x = b for x, using LU decomposition. +# +module LUSolve + module_function + + # Performs LU decomposition of the n by n matrix a. + def ludecomp(a,n,zero=0,one=1) + prec = BigDecimal.limit(nil) + ps = [] + scales = [] + for i in 0...n do # pick up largest(abs. val.) element in each row. + ps <<= i + nrmrow = zero + ixn = i*n + for j in 0...n do + biggst = a[ixn+j].abs + nrmrow = biggst if biggst>nrmrow + end + if nrmrow>zero then + scales <<= one.div(nrmrow,prec) + else + raise "Singular matrix" + end + end + n1 = n - 1 + for k in 0...n1 do # Gaussian elimination with partial pivoting. + biggst = zero; + for i in k...n do + size = a[ps[i]*n+k].abs*scales[ps[i]] + if size>biggst then + biggst = size + pividx = i + end + end + raise "Singular matrix" if biggst<=zero + if pividx!=k then + j = ps[k] + ps[k] = ps[pividx] + ps[pividx] = j + end + pivot = a[ps[k]*n+k] + for i in (k+1)...n do + psin = ps[i]*n + a[psin+k] = mult = a[psin+k].div(pivot,prec) + if mult!=zero then + pskn = ps[k]*n + for j in (k+1)...n do + a[psin+j] -= mult.mult(a[pskn+j],prec) + end + end + end + end + raise "Singular matrix" if a[ps[n1]*n+n1] == zero + ps + end + + # Solves a*x = b for x, using LU decomposition. + # + # a is a matrix, b is a constant vector, x is the solution vector. + # + # ps is the pivot, a vector which indicates the permutation of rows performed + # during LU decomposition. + def lusolve(a,b,ps,zero=0.0) + prec = BigDecimal.limit(nil) + n = ps.size + x = [] + for i in 0...n do + dot = zero + psin = ps[i]*n + for j in 0...i do + dot = a[psin+j].mult(x[j],prec) + dot + end + x <<= b[ps[i]] - dot + end + (n-1).downto(0) do |i| + dot = zero + psin = ps[i]*n + for j in (i+1)...n do + dot = a[psin+j].mult(x[j],prec) + dot + end + x[i] = (x[i]-dot).div(a[psin+i],prec) + end + x + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/lib/bigdecimal/math.rb b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/lib/bigdecimal/math.rb new file mode 100644 index 00000000..3ab84d84 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/lib/bigdecimal/math.rb @@ -0,0 +1,231 @@ +# frozen_string_literal: false +require 'bigdecimal' + +# +#-- +# Contents: +# sqrt(x, prec) +# sin (x, prec) +# cos (x, prec) +# atan(x, prec) +# PI (prec) +# E (prec) == exp(1.0,prec) +# +# where: +# x ... BigDecimal number to be computed. +# prec ... Number of digits to be obtained. +#++ +# +# Provides mathematical functions. +# +# Example: +# +# require "bigdecimal/math" +# +# include BigMath +# +# a = BigDecimal((PI(100)/2).to_s) +# puts sin(a,100) # => 0.99999999999999999999......e0 +# +module BigMath + module_function + + # call-seq: + # sqrt(decimal, numeric) -> BigDecimal + # + # Computes the square root of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # BigMath.sqrt(BigDecimal('2'), 16).to_s + # #=> "0.1414213562373095048801688724e1" + # + def sqrt(x, prec) + x.sqrt(prec) + end + + # call-seq: + # sin(decimal, numeric) -> BigDecimal + # + # Computes the sine of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # If +decimal+ is Infinity or NaN, returns NaN. + # + # BigMath.sin(BigMath.PI(5)/4, 5).to_s + # #=> "0.70710678118654752440082036563292800375e0" + # + def sin(x, prec) + raise ArgumentError, "Zero or negative precision for sin" if prec <= 0 + return BigDecimal("NaN") if x.infinite? || x.nan? + n = prec + BigDecimal.double_fig + one = BigDecimal("1") + two = BigDecimal("2") + x = -x if neg = x < 0 + if x > (twopi = two * BigMath.PI(prec)) + if x > 30 + x %= twopi + else + x -= twopi while x > twopi + end + end + x1 = x + x2 = x.mult(x,n) + sign = 1 + y = x + d = y + i = one + z = one + while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0) + m = BigDecimal.double_fig if m < BigDecimal.double_fig + sign = -sign + x1 = x2.mult(x1,n) + i += two + z *= (i-one) * i + d = sign * x1.div(z,m) + y += d + end + neg ? -y : y + end + + # call-seq: + # cos(decimal, numeric) -> BigDecimal + # + # Computes the cosine of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # If +decimal+ is Infinity or NaN, returns NaN. + # + # BigMath.cos(BigMath.PI(4), 16).to_s + # #=> "-0.999999999999999999999999999999856613163740061349e0" + # + def cos(x, prec) + raise ArgumentError, "Zero or negative precision for cos" if prec <= 0 + return BigDecimal("NaN") if x.infinite? || x.nan? + n = prec + BigDecimal.double_fig + one = BigDecimal("1") + two = BigDecimal("2") + x = -x if x < 0 + if x > (twopi = two * BigMath.PI(prec)) + if x > 30 + x %= twopi + else + x -= twopi while x > twopi + end + end + x1 = one + x2 = x.mult(x,n) + sign = 1 + y = one + d = y + i = BigDecimal("0") + z = one + while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0) + m = BigDecimal.double_fig if m < BigDecimal.double_fig + sign = -sign + x1 = x2.mult(x1,n) + i += two + z *= (i-one) * i + d = sign * x1.div(z,m) + y += d + end + y + end + + # call-seq: + # atan(decimal, numeric) -> BigDecimal + # + # Computes the arctangent of +decimal+ to the specified number of digits of + # precision, +numeric+. + # + # If +decimal+ is NaN, returns NaN. + # + # BigMath.atan(BigDecimal('-1'), 16).to_s + # #=> "-0.785398163397448309615660845819878471907514682065e0" + # + def atan(x, prec) + raise ArgumentError, "Zero or negative precision for atan" if prec <= 0 + return BigDecimal("NaN") if x.nan? + pi = PI(prec) + x = -x if neg = x < 0 + return pi.div(neg ? -2 : 2, prec) if x.infinite? + return pi / (neg ? -4 : 4) if x.round(prec) == 1 + x = BigDecimal("1").div(x, prec) if inv = x > 1 + x = (-1 + sqrt(1 + x**2, prec))/x if dbl = x > 0.5 + n = prec + BigDecimal.double_fig + y = x + d = y + t = x + r = BigDecimal("3") + x2 = x.mult(x,n) + while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0) + m = BigDecimal.double_fig if m < BigDecimal.double_fig + t = -t.mult(x2,n) + d = t.div(r,m) + y += d + r += 2 + end + y *= 2 if dbl + y = pi / 2 - y if inv + y = -y if neg + y + end + + # call-seq: + # PI(numeric) -> BigDecimal + # + # Computes the value of pi to the specified number of digits of precision, + # +numeric+. + # + # BigMath.PI(10).to_s + # #=> "0.3141592653589793238462643388813853786957412e1" + # + def PI(prec) + raise ArgumentError, "Zero or negative precision for PI" if prec <= 0 + n = prec + BigDecimal.double_fig + zero = BigDecimal("0") + one = BigDecimal("1") + two = BigDecimal("2") + + m25 = BigDecimal("-0.04") + m57121 = BigDecimal("-57121") + + pi = zero + + d = one + k = one + t = BigDecimal("-80") + while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0) + m = BigDecimal.double_fig if m < BigDecimal.double_fig + t = t*m25 + d = t.div(k,m) + k = k+two + pi = pi + d + end + + d = one + k = one + t = BigDecimal("956") + while d.nonzero? && ((m = n - (pi.exponent - d.exponent).abs) > 0) + m = BigDecimal.double_fig if m < BigDecimal.double_fig + t = t.div(m57121,n) + d = t.div(k,m) + pi = pi + d + k = k+two + end + pi + end + + # call-seq: + # E(numeric) -> BigDecimal + # + # Computes e (the base of natural logarithms) to the specified number of + # digits of precision, +numeric+. + # + # BigMath.E(10).to_s + # #=> "0.271828182845904523536028752390026306410273e1" + # + def E(prec) + raise ArgumentError, "Zero or negative precision for E" if prec <= 0 + BigMath.exp(1, prec) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/lib/bigdecimal/newton.rb b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/lib/bigdecimal/newton.rb new file mode 100644 index 00000000..85bacb7f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/lib/bigdecimal/newton.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: false +require "bigdecimal/ludcmp" +require "bigdecimal/jacobian" + +# +# newton.rb +# +# Solves the nonlinear algebraic equation system f = 0 by Newton's method. +# This program is not dependent on BigDecimal. +# +# To call: +# n = nlsolve(f,x) +# where n is the number of iterations required, +# x is the initial value vector +# f is an Object which is used to compute the values of the equations to be solved. +# It must provide the following methods: +# +# f.values(x):: returns the values of all functions at x +# +# f.zero:: returns 0.0 +# f.one:: returns 1.0 +# f.two:: returns 2.0 +# f.ten:: returns 10.0 +# +# f.eps:: returns the convergence criterion (epsilon value) used to determine whether two values are considered equal. If |a-b| < epsilon, the two values are considered equal. +# +# On exit, x is the solution vector. +# +module Newton + include LUSolve + include Jacobian + module_function + + def norm(fv,zero=0.0) # :nodoc: + s = zero + n = fv.size + for i in 0...n do + s += fv[i]*fv[i] + end + s + end + + # See also Newton + def nlsolve(f,x) + nRetry = 0 + n = x.size + + f0 = f.values(x) + zero = f.zero + one = f.one + two = f.two + p5 = one/two + d = norm(f0,zero) + minfact = f.ten*f.ten*f.ten + minfact = one/minfact + e = f.eps + while d >= e do + nRetry += 1 + # Not yet converged. => Compute Jacobian matrix + dfdx = jacobian(f,f0,x) + # Solve dfdx*dx = -f0 to estimate dx + dx = lusolve(dfdx,f0,ludecomp(dfdx,n,zero,one),zero) + fact = two + xs = x.dup + begin + fact *= p5 + if fact < minfact then + raise "Failed to reduce function values." + end + for i in 0...n do + x[i] = xs[i] - dx[i]*fact + end + f0 = f.values(x) + dn = norm(f0,zero) + end while(dn>=d) + d = dn + end + nRetry + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/lib/bigdecimal/util.rb b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/lib/bigdecimal/util.rb new file mode 100644 index 00000000..cb514435 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/lib/bigdecimal/util.rb @@ -0,0 +1,185 @@ +# frozen_string_literal: false +# +#-- +# bigdecimal/util extends various native classes to provide the #to_d method, +# and provides BigDecimal#to_d and BigDecimal#to_digits. +#++ + +require 'bigdecimal' + +class Integer < Numeric + # call-seq: + # int.to_d -> bigdecimal + # + # Returns the value of +int+ as a BigDecimal. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # 42.to_d # => 0.42e2 + # + # See also Kernel.BigDecimal. + # + def to_d + BigDecimal(self) + end +end + + +class Float < Numeric + # call-seq: + # float.to_d -> bigdecimal + # float.to_d(precision) -> bigdecimal + # + # Returns the value of +float+ as a BigDecimal. + # The +precision+ parameter is used to determine the number of + # significant digits for the result. When +precision+ is set to +0+, + # the number of digits to represent the float being converted is determined + # automatically. + # The default +precision+ is +0+. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # 0.5.to_d # => 0.5e0 + # 1.234.to_d # => 0.1234e1 + # 1.234.to_d(2) # => 0.12e1 + # + # See also Kernel.BigDecimal. + # + def to_d(precision=0) + BigDecimal(self, precision) + end +end + + +class String + # call-seq: + # str.to_d -> bigdecimal + # + # Returns the result of interpreting leading characters in +str+ + # as a BigDecimal. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # "0.5".to_d # => 0.5e0 + # "123.45e1".to_d # => 0.12345e4 + # "45.67 degrees".to_d # => 0.4567e2 + # + # See also Kernel.BigDecimal. + # + def to_d + BigDecimal.interpret_loosely(self) + end +end + + +class BigDecimal < Numeric + # call-seq: + # a.to_digits -> string + # + # Converts a BigDecimal to a String of the form "nnnnnn.mmm". + # This method is deprecated; use BigDecimal#to_s("F") instead. + # + # require 'bigdecimal/util' + # + # d = BigDecimal("3.14") + # d.to_digits # => "3.14" + # + def to_digits + if self.nan? || self.infinite? || self.zero? + self.to_s + else + i = self.to_i.to_s + _,f,_,z = self.frac.split + i + "." + ("0"*(-z)) + f + end + end + + # call-seq: + # a.to_d -> bigdecimal + # + # Returns self. + # + # require 'bigdecimal/util' + # + # d = BigDecimal("3.14") + # d.to_d # => 0.314e1 + # + def to_d + self + end +end + + +class Rational < Numeric + # call-seq: + # rat.to_d(precision) -> bigdecimal + # + # Returns the value as a BigDecimal. + # + # The required +precision+ parameter is used to determine the number of + # significant digits for the result. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # Rational(22, 7).to_d(3) # => 0.314e1 + # + # See also Kernel.BigDecimal. + # + def to_d(precision) + BigDecimal(self, precision) + end +end + + +class Complex < Numeric + # call-seq: + # cmp.to_d -> bigdecimal + # cmp.to_d(precision) -> bigdecimal + # + # Returns the value as a BigDecimal. + # + # The +precision+ parameter is required for a rational complex number. + # This parameter is used to determine the number of significant digits + # for the result. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # Complex(0.1234567, 0).to_d(4) # => 0.1235e0 + # Complex(Rational(22, 7), 0).to_d(3) # => 0.314e1 + # + # See also Kernel.BigDecimal. + # + def to_d(*args) + BigDecimal(self) unless self.imag.zero? # to raise error + + if args.length == 0 + case self.real + when Rational + BigDecimal(self.real) # to raise error + end + end + self.real.to_d(*args) + end +end + + +class NilClass + # call-seq: + # nil.to_d -> bigdecimal + # + # Returns nil represented as a BigDecimal. + # + # require 'bigdecimal' + # require 'bigdecimal/util' + # + # nil.to_d # => 0.0 + # + def to_d + BigDecimal(0) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/sample/linear.rb b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/sample/linear.rb new file mode 100644 index 00000000..516c2473 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/sample/linear.rb @@ -0,0 +1,74 @@ +#!/usr/local/bin/ruby +# frozen_string_literal: false + +# +# linear.rb +# +# Solves linear equation system(A*x = b) by LU decomposition method. +# where A is a coefficient matrix,x is an answer vector,b is a constant vector. +# +# USAGE: +# ruby linear.rb [input file solved] +# + +# :stopdoc: +require "bigdecimal" +require "bigdecimal/ludcmp" + +# +# NOTE: +# Change following BigDecimal.limit() if needed. +BigDecimal.limit(100) +# + +include LUSolve +def rd_order(na) + printf("Number of equations ?") if(na <= 0) + n = ARGF.gets().to_i +end + +na = ARGV.size +zero = BigDecimal("0.0") +one = BigDecimal("1.0") + +while (n=rd_order(na))>0 + a = [] + as= [] + b = [] + if na <= 0 + # Read data from console. + printf("\nEnter coefficient matrix element A[i,j]\n") + for i in 0...n do + for j in 0...n do + printf("A[%d,%d]? ",i,j); s = ARGF.gets + a << BigDecimal(s) + as << BigDecimal(s) + end + printf("Contatant vector element b[%d] ? ",i) + b << BigDecimal(ARGF.gets) + end + else + # Read data from specified file. + printf("Coefficient matrix and constant vector.\n") + for i in 0...n do + s = ARGF.gets + printf("%d) %s",i,s) + s = s.split + for j in 0...n do + a << BigDecimal(s[j]) + as << BigDecimal(s[j]) + end + b << BigDecimal(s[n]) + end + end + x = lusolve(a,b,ludecomp(a,n,zero,one),zero) + printf("Answer(x[i] & (A*x-b)[i]) follows\n") + for i in 0...n do + printf("x[%d]=%s ",i,x[i].to_s) + s = zero + for j in 0...n do + s = s + as[i*n+j]*x[j] + end + printf(" & %s\n",(s-b[i]).to_s) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/sample/nlsolve.rb b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/sample/nlsolve.rb new file mode 100644 index 00000000..c2227dac --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/sample/nlsolve.rb @@ -0,0 +1,40 @@ +#!/usr/local/bin/ruby +# frozen_string_literal: false + +# +# nlsolve.rb +# An example for solving nonlinear algebraic equation system. +# + +require "bigdecimal" +require "bigdecimal/newton" +include Newton + +class Function # :nodoc: all + def initialize() + @zero = BigDecimal("0.0") + @one = BigDecimal("1.0") + @two = BigDecimal("2.0") + @ten = BigDecimal("10.0") + @eps = BigDecimal("1.0e-16") + end + def zero;@zero;end + def one ;@one ;end + def two ;@two ;end + def ten ;@ten ;end + def eps ;@eps ;end + def values(x) # <= defines functions solved + f = [] + f1 = x[0]*x[0] + x[1]*x[1] - @two # f1 = x**2 + y**2 - 2 => 0 + f2 = x[0] - x[1] # f2 = x - y => 0 + f <<= f1 + f <<= f2 + f + end +end + +f = BigDecimal.limit(100) +f = Function.new +x = [f.zero,f.zero] # Initial values +n = nlsolve(f,x) +p x diff --git a/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/sample/pi.rb b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/sample/pi.rb new file mode 100644 index 00000000..ea966389 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/bigdecimal-3.2.2/sample/pi.rb @@ -0,0 +1,21 @@ +#!/usr/local/bin/ruby +# frozen_string_literal: false + +# +# pi.rb +# +# Calculates 3.1415.... (the number of times that a circle's diameter +# will fit around the circle) using J. Machin's formula. +# + +require "bigdecimal" +require "bigdecimal/math.rb" + +include BigMath + +if ARGV.size == 1 + print "PI("+ARGV[0]+"):\n" + p PI(ARGV[0].to_i) +else + print "TRY: ruby pi.rb 1000 \n" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/CHANGELOG.md b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/CHANGELOG.md new file mode 100644 index 00000000..30810b72 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/CHANGELOG.md @@ -0,0 +1,603 @@ +## Current + +## Release v1.3.5, edge v0.7.2 (15 January 2025) + +concurrent-ruby: + +* (#1062) Remove dependency on logger. + +concurrent-ruby-edge: + +* (#1062) Remove dependency on logger. + +## Release v1.3.4 (10 August 2024) + +* (#1060) Fix bug with return value of `Concurrent.available_processor_count` when `cpu.cfs_quota_us` is -1. +* (#1058) Add `Concurrent.cpu_shares` that is cgroups aware. + +## Release v1.3.3 (9 June 2024) + +* (#1053) Improve the speed of `Concurrent.physical_processor_count` on Windows. + +## Release v1.3.2, edge v0.7.1 (7 June 2024) + +concurrent-ruby: + +* (#1051) Remove dependency on `win32ole`. + +concurrent-ruby-edge: + +* (#1052) Fix dependency on `concurrent-ruby` to allow the latest release. + +## Release v1.3.1 (29 May 2024) + +* Release 1.3.0 was broken when pushed to RubyGems. 1.3.1 is a packaging fix. + +## Release v1.3.0 (28 May 2024) + +* (#1042) Align Java Executor Service behavior for `shuttingdown?`, `shutdown?` +* (#1038) Add `Concurrent.available_processor_count` that is cgroups aware. + +## Release v1.2.3 (16 Jan 2024) + +* See [the GitHub release](https://github.com/ruby-concurrency/concurrent-ruby/releases/tag/v1.2.3) for details. + +## Release v1.2.2 (24 Feb 2023) + +* (#993) Fix arguments passed to `Concurrent::Map`'s `default_proc`. + +## Release v1.2.1 (24 Feb 2023) + +* (#990) Add missing `require 'fiber'` for `FiberLocalVar`. +* (#989) Optimize `Concurrent::Map#[]` on CRuby by letting the backing Hash handle the `default_proc`. + +## Release v1.2.0 (23 Jan 2023) + +* (#962) Fix ReentrantReadWriteLock to use the same granularity for locals as for Mutex it uses. +* (#983) Add FiberLocalVar +* (#934) concurrent-ruby now supports requiring individual classes (public classes listed in the docs), e.g., `require 'concurrent/map'` +* (#976) Let `Promises.any_fulfilled_future` take an `Event` +* Improve documentation of various classes +* (#975) Set the Ruby compatibility version at 2.3 +* (#972) Remove Rubinius-related code + +## Release v1.1.10 (22 Mar 2022) + +concurrent-ruby: + +* (#951) Set the Ruby compatibility version at 2.2 +* (#939, #933) The `caller_runs` fallback policy no longer blocks reads from the job queue by worker threads +* (#938, #761, #652) You can now explicitly `prune_pool` a thread pool (Sylvain Joyeux) +* (#937, #757, #670) We switched the Yahoo stock API for demos to Alpha Vantage (Gustavo Caso) +* (#932, #931) We changed how `SafeTaskExecutor` handles local jump errors (Aaron Jensen) +* (#927) You can use keyword arguments in your initialize when using `Async` (Matt Larraz) +* (#926, #639) We removed timeout from `TimerTask` because it wasn't sound, and now it's a no-op with a warning (Jacob Atzen) +* (#919) If you double-lock a re-entrant read-write lock, we promote to locked for writing (zp yuan) +* (#915) `monotonic_time` now accepts an optional unit parameter, as Ruby's `clock_gettime` (Jean Boussier) + +## Release v1.1.9 (5 Jun 2021) + +concurrent-ruby: + +* (#866) Child promise state not set to :pending immediately after #execute when parent has completed +* (#905, #872) Fix RubyNonConcurrentPriorityQueue#delete method +* (2df0337d) Make sure locks are not shared on shared when objects are dup/cloned +* (#900, #906, #796, #847, #911) Fix Concurrent::Set tread-safety issues on CRuby +* (#907) Add new ConcurrentMap backend for TruffleRuby + +## Release v1.1.8 (20 January 2021) + +concurrent-ruby: + +* (#885) Fix race condition in TVar for stale reads +* (#884) RubyThreadLocalVar: Do not iterate over hash which might conflict with new pair addition + +## Release v1.1.7 (6 August 2020) + +concurrent-ruby: + +* (#879) Consider falsy value on `Concurrent::Map#compute_if_absent` for fast non-blocking path +* (#876) Reset Async queue on forking, makes Async fork-safe +* (#856) Avoid running problematic code in RubyThreadLocalVar on MRI that occasionally results in segfault +* (#853) Introduce ThreadPoolExecutor without a Queue + +## Release v1.1.6, edge v0.6.0 (10 Feb 2020) + +concurrent-ruby: + +* (#841) Concurrent.disable_at_exit_handlers! is no longer needed and was deprecated. +* (#841) AbstractExecutorService#auto_terminate= was deprecated and has no effect. + Set :auto_terminate option instead when executor is initialized. + +## Release v1.1.6.pre1, edge v0.6.0.pre1 (26 Jan 2020) + +concurrent-ruby: + +* (#828) Allow to name executors, the name is also used to name their threads +* (#838) Implement #dup and #clone for structs +* (#821) Safer finalizers for thread local variables +* Documentation fixes +* (#814) Use Ruby's Etc.nprocessors if available +* (#812) Fix directory structure not to mess with packaging tools +* (#840) Fix termination of pools on JRuby + +concurrent-ruby-edge: + +* Add WrappingExecutor (#830) + +## Release v1.1.5, edge v0.5.0 (10 Mar 2019) + +concurrent-ruby: + +* fix potential leak of context on JRuby and Java 7 + +concurrent-ruby-edge: + +* Add finalized Concurrent::Cancellation +* Add finalized Concurrent::Throttle +* Add finalized Concurrent::Promises::Channel +* Add new Concurrent::ErlangActor + +## Release v1.1.4 (14 Dec 2018) + +* (#780) Remove java_alias of 'submit' method of Runnable to let executor service work on java 11 +* (#776) Fix NameError on defining a struct with a name which is already taken in an ancestor + +## Release v1.1.3 (7 Nov 2018) + +* (#775) fix partial require of the gem (although not officially supported) + +## Release v1.1.2 (6 Nov 2018) + +* (#773) more defensive 1.9.3 support + +## Release v1.1.1, edge v0.4.1 (1 Nov 2018) + +* (#768) add support for 1.9.3 back + +## Release v1.1.0, edge v0.4.0 (31 OCt 2018) (yanked) + +* (#768) yanked because of issues with removed 1.9.3 support + +## Release v1.1.0.pre2, edge v0.4.0.pre2 (18 Sep 2018) + +concurrent-ruby: + +* fixed documentation and README links +* fix Set for TruffleRuby and Rubinius +* use properly supported TruffleRuby APIs + +concurrent-ruby-edge: + +* add Promises.zip_futures_over_on + +## Release v1.1.0.pre1, edge v0.4.0.pre1 (15 Aug 2018) + +concurrent-ruby: + +* requires at least Ruby 2.0 +* [Promises](http://ruby-concurrency.github.io/concurrent-ruby/1.1.0/Concurrent/Promises.html) + are moved from `concurrent-ruby-edge` to `concurrent-ruby` +* Add support for TruffleRuby + * (#734) Fix Array/Hash/Set construction broken on TruffleRuby + * AtomicReference fixed +* CI stabilization +* remove sharp dependency edge -> core +* remove warnings +* documentation updates +* Exchanger is no longer documented as edge since it was already available in + `concurrent-ruby` +* (#644) Fix Map#each and #each_pair not returning enumerator outside of MRI +* (#659) Edge promises fail during error handling +* (#741) Raise on recursive Delay#value call +* (#727) #717 fix global IO executor on JRuby +* (#740) Drop support for CRuby 1.9, JRuby 1.7, Rubinius. +* (#737) Move AtomicMarkableReference out of Edge +* (#708) Prefer platform specific memory barriers +* (#735) Fix wrong expected exception in channel spec assertion +* (#729) Allow executor option in `Promise#then` +* (#725) fix timeout check to use timeout_interval +* (#719) update engine detection +* (#660) Add specs for Promise#zip/Promise.zip ordering +* (#654) Promise.zip execution changes +* (#666) Add thread safe set implementation +* (#651) #699 #to_s, #inspect should not output negative object IDs. +* (#685) Avoid RSpec warnings about raise_error +* (#680) Avoid RSpec monkey patching, persist spec results locally, use RSpec + v3.7.0 +* (#665) Initialize the monitor for new subarrays on Rubinius +* (#661) Fix error handling in edge promises + +concurrent-ruby-edge: + +* (#659) Edge promises fail during error handling +* Edge files clearly separated in `lib-edge` +* added ReInclude + +## Release v1.0.5, edge v0.3.1 (26 Feb 2017) + +concurrent-ruby: + +* Documentation for Event and Semaphore +* Use Unsafe#fullFence and #loadFence directly since the shortcuts were removed in JRuby +* Do not depend on org.jruby.util.unsafe.UnsafeHolder + +concurrent-ruby-edge: + +* (#620) Actors on Pool raise an error +* (#624) Delayed promises did not interact correctly with flatting + * Fix arguments yielded by callback methods +* Overridable default executor in promises factory methods +* Asking actor to terminate will always resolve to `true` + +## Release v1.0.4, edge v0.3.0 (27 Dec 2016) + +concurrent-ruby: + +* Nothing + +concurrent-ruby-edge: + +* New promises' API renamed, lots of improvements, edge bumped to 0.3.0 + * **Incompatible** with previous 0.2.3 version + * see https://github.com/ruby-concurrency/concurrent-ruby/pull/522 + +## Release v1.0.3 (17 Dec 2016) + +* Trigger execution of flattened delayed futures +* Avoid forking for processor_count if possible +* Semaphore Mutex and JRuby parity +* Adds Map#each as alias to Map#each_pair +* Fix uninitialized instance variables +* Make Fixnum, Bignum merger ready +* Allows Promise#then to receive an executor +* TimerSet now survives a fork +* Reject promise on any exception +* Allow ThreadLocalVar to be initialized with a block +* Support Alpha with `Concurrent::processor_count` +* Fixes format-security error when compiling ruby_193_compatible.h +* Concurrent::Atom#swap fixed: reraise the exceptions from block + +## Release v1.0.2 (2 May 2016) + +* Fix bug with `Concurrent::Map` MRI backend `#inspect` method +* Fix bug with `Concurrent::Map` MRI backend using `Hash#value?` +* Improved documentation and examples +* Minor updates to Edge + +## Release v1.0.1 (27 February 2016) + +* Fix "uninitialized constant Concurrent::ReentrantReadWriteLock" error. +* Better handling of `autoload` vs. `require`. +* Improved API for Edge `Future` zipping. +* Fix reference leak in Edge `Future` constructor . +* Fix bug which prevented thread pools from surviving a `fork`. +* Fix bug in which `TimerTask` did not correctly specify all its dependencies. +* Improved support for JRuby+Truffle +* Improved error messages. +* Improved documentation. +* Updated README and CONTRIBUTING. + +## Release v1.0.0 (13 November 2015) + +* Rename `attr_volatile_with_cas` to `attr_atomic` +* Add `clear_each` to `LockFreeStack` +* Update `AtomicReference` documentation +* Further updates and improvements to the synchronization layer. +* Performance and memory usage performance with `Actor` logging. +* Fixed `ThreadPoolExecutor` task count methods. +* Improved `Async` performance for both short and long-lived objects. +* Fixed bug in `LockFreeLinkedSet`. +* Fixed bug in which `Agent#await` triggered a validation failure. +* Further `Channel` updates. +* Adopted a project Code of Conduct +* Cleared interpreter warnings +* Fixed bug in `ThreadPoolExecutor` task count methods +* Fixed bug in 'LockFreeLinkedSet' +* Improved Java extension loading +* Handle Exception children in Edge::Future +* Continued improvements to channel +* Removed interpreter warnings. +* Shared constants now in `lib/concurrent/constants.rb` +* Refactored many tests. +* Improved synchronization layer/memory model documentation. +* Bug fix in Edge `Future#flat` +* Brand new `Channel` implementation in Edge gem. +* Simplification of `RubySingleThreadExecutor` +* `Async` improvements + - Each object uses its own `SingleThreadExecutor` instead of the global thread pool. + - No longer supports executor injection + - Much better documentation +* `Atom` updates + - No longer `Dereferenceable` + - Now `Observable` + - Added a `#reset` method +* Brand new `Agent` API and implementation. Now functionally equivalent to Clojure. +* Continued improvements to the synchronization layer +* Merged in the `thread_safe` gem + - `Concurrent::Array` + - `Concurrent::Hash` + - `Concurrent::Map` (formerly ThreadSafe::Cache) + - `Concurrent::Tuple` +* Minor improvements to Concurrent::Map +* Complete rewrite of `Exchanger` +* Removed all deprecated code (classes, methods, constants, etc.) +* Updated Agent, MutexAtomic, and BufferedChannel to inherit from Synchronization::Object. +* Many improved tests +* Some internal reorganization + +## Release v0.9.1 (09 August 2015) + +* Fixed a Rubiniux bug in synchronization object +* Fixed all interpreter warnings (except circular references) +* Fixed require statements when requiring `Atom` alone +* Significantly improved `ThreadLocalVar` on non-JRuby platforms +* Fixed error handling in Edge `Concurrent.zip` +* `AtomicFixnum` methods `#increment` and `#decrement` now support optional delta +* New `AtomicFixnum#update` method +* Minor optimizations in `ReadWriteLock` +* New `ReentrantReadWriteLock` class +* `ThreadLocalVar#bind` method is now public +* Refactored many tests + +## Release v0.9.0 (10 July 2015) + +* Updated `AtomicReference` + - `AtomicReference#try_update` now simply returns instead of raising exception + - `AtomicReference#try_update!` was added to raise exceptions if an update + fails. Note: this is the same behavior as the old `try_update` +* Pure Java implementations of + - `AtomicBoolean` + - `AtomicFixnum` + - `Semaphore` +* Fixed bug when pruning Ruby thread pools +* Fixed bug in time calculations within `ScheduledTask` +* Default `count` in `CountDownLatch` to 1 +* Use monotonic clock for all timers via `Concurrent.monotonic_time` + - Use `Process.clock_gettime(Process::CLOCK_MONOTONIC)` when available + - Fallback to `java.lang.System.nanoTime()` on unsupported JRuby versions + - Pure Ruby implementation for everything else + - Effects `Concurrent.timer`, `Concurrent.timeout`, `TimerSet`, `TimerTask`, and `ScheduledTask` +* Deprecated all clock-time based timer scheduling + - Only support scheduling by delay + - Effects `Concurrent.timer`, `TimerSet`, and `ScheduledTask` +* Added new `ReadWriteLock` class +* Consistent `at_exit` behavior for Java and Ruby thread pools. +* Added `at_exit` handler to Ruby thread pools (already in Java thread pools) + - Ruby handler stores the object id and retrieves from `ObjectSpace` + - JRuby disables `ObjectSpace` by default so that handler stores the object reference +* Added a `:stop_on_exit` option to thread pools to enable/disable `at_exit` handler +* Updated thread pool docs to better explain shutting down thread pools +* Simpler `:executor` option syntax for all abstractions which support this option +* Added `Executor#auto_terminate?` predicate method (for thread pools) +* Added `at_exit` handler to `TimerSet` +* Simplified auto-termination of the global executors + - Can now disable auto-termination of global executors + - Added shutdown/kill/wait_for_termination variants for global executors +* Can now disable auto-termination for *all* executors (the nuclear option) +* Simplified auto-termination of the global executors +* Deprecated terms "task pool" and "operation pool" + - New terms are "io executor" and "fast executor" + - New functions added with new names + - Deprecation warnings added to functions referencing old names +* Moved all thread pool related functions from `Concurrent::Configuration` to `Concurrent` + - Old functions still exist with deprecation warnings + - New functions have updated names as appropriate +* All high-level abstractions default to the "io executor" +* Fixed bug in `Actor` causing it to prematurely warm global thread pools on gem load + - This also fixed a `RejectedExecutionError` bug when running with minitest/autorun via JRuby +* Moved global logger up to the `Concurrent` namespace and refactored the code +* Optimized the performance of `Delay` + - Fixed a bug in which no executor option on construction caused block execution on a global thread pool +* Numerous improvements and bug fixes to `TimerSet` +* Fixed deadlock of `Future` when the handler raises Exception +* Added shared specs for more classes +* New concurrency abstractions including: + - `Atom` + - `Maybe` + - `ImmutableStruct` + - `MutableStruct` + - `SettableStruct` +* Created an Edge gem for unstable abstractions including + - `Actor` + - `Agent` + - `Channel` + - `Exchanger` + - `LazyRegister` + - **new Future Framework** - unified + implementation of Futures and Promises which combines Features of previous `Future`, + `Promise`, `IVar`, `Event`, `Probe`, `dataflow`, `Delay`, `TimerTask` into single framework. It uses extensively + new synchronization layer to make all the paths **lock-free** with exception of blocking threads on `#wait`. + It offers better performance and does not block threads when not required. +* Actor framework changes: + - fixed reset loop in Pool + - Pool can use any actor as a worker, abstract worker class is no longer needed. + - Actor events not have format `[:event_name, *payload]` instead of just the Symbol. + - Actor now uses new Future/Promise Framework instead of `IVar` for better interoperability + - Behaviour definition array was simplified to `[BehaviourClass1, [BehaviourClass2, *initialization_args]]` + - Linking behavior responds to :linked message by returning array of linked actors + - Supervised behavior is removed in favour of just Linking + - RestartingContext is supervised by default now, `supervise: true` is not required any more + - Events can be private and public, so far only difference is that Linking will + pass to linked actors only public messages. Adding private :restarting and + :resetting events which are send before the actor restarts or resets allowing + to add callbacks to cleanup current child actors. + - Print also object_id in Reference to_s + - Add AbstractContext#default_executor to be able to override executor class wide + - Add basic IO example + - Documentation somewhat improved + - All messages should have same priority. It's now possible to send `actor << job1 << job2 << :terminate!` and + be sure that both jobs are processed first. +* Refactored `Channel` to use newer synchronization objects +* Added `#reset` and `#cancel` methods to `TimerSet` +* Added `#cancel` method to `Future` and `ScheduledTask` +* Refactored `TimerSet` to use `ScheduledTask` +* Updated `Async` with a factory that initializes the object +* Deprecated `Concurrent.timer` and `Concurrent.timeout` +* Reduced max threads on pure-Ruby thread pools (abends around 14751 threads) +* Moved many private/internal classes/modules into "namespace" modules +* Removed brute-force killing of threads in tests +* Fixed a thread pool bug when the operating system cannot allocate more threads + +## Release v0.8.0 (25 January 2015) + +* C extension for MRI have been extracted into the `concurrent-ruby-ext` companion gem. + Please see the README for more detail. +* Better variable isolation in `Promise` and `Future` via an `:args` option +* Continued to update intermittently failing tests + +## Release v0.7.2 (24 January 2015) + +* New `Semaphore` class based on [java.util.concurrent.Semaphore](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Semaphore.html) +* New `Promise.all?` and `Promise.any?` class methods +* Renamed `:overflow_policy` on thread pools to `:fallback_policy` +* Thread pools still accept the `:overflow_policy` option but display a warning +* Thread pools now implement `fallback_policy` behavior when not running (rather than universally rejecting tasks) +* Fixed minor `set_deref_options` constructor bug in `Promise` class +* Fixed minor `require` bug in `ThreadLocalVar` class +* Fixed race condition bug in `TimerSet` class +* Fixed race condition bug in `TimerSet` class +* Fixed signal bug in `TimerSet#post` method +* Numerous non-functional updates to clear warning when running in debug mode +* Fixed more intermittently failing tests +* Tests now run on new Travis build environment +* Multiple documentation updates + +## Release v0.7.1 (4 December 2014) + +Please see the [roadmap](https://github.com/ruby-concurrency/concurrent-ruby/issues/142) for more information on the next planned release. + +* Added `flat_map` method to `Promise` +* Added `zip` method to `Promise` +* Fixed bug with logging in `Actor` +* Improvements to `Promise` tests +* Removed actor-experimental warning +* Added an `IndirectImmediateExecutor` class +* Allow disabling auto termination of global executors +* Fix thread leaking in `ThreadLocalVar` (uses `Ref` gem on non-JRuby systems) +* Fix thread leaking when pruning pure-Ruby thread pools +* Prevent `Actor` from using an `ImmediateExecutor` (causes deadlock) +* Added missing synchronizations to `TimerSet` +* Fixed bug with return value of `Concurrent::Actor::Utils::Pool#ask` +* Fixed timing bug in `TimerTask` +* Fixed bug when creating a `JavaThreadPoolExecutor` with minimum pool size of zero +* Removed confusing warning when not using native extensions +* Improved documentation + +## Release v0.7.0 (13 August 2014) + +* Merge the [atomic](https://github.com/ruby-concurrency/atomic) gem + - Pure Ruby `MutexAtomic` atomic reference class + - Platform native atomic reference classes `CAtomic`, `JavaAtomic`, and `RbxAtomic` + - Automated [build process](https://github.com/ruby-concurrency/rake-compiler-dev-box) + - Fat binary releases for [multiple platforms](https://rubygems.org/gems/concurrent-ruby/versions) including Windows (32/64), Linux (32/64), OS X (64-bit), Solaris (64-bit), and JRuby +* C native `CAtomicBoolean` +* C native `CAtomicFixnum` +* Refactored intermittently failing tests +* Added `dataflow!` and `dataflow_with!` methods to match `Future#value!` method +* Better handling of timeout in `Agent` +* Actor Improvements + - Fine-grained implementation using chain of behaviors. Each behavior is responsible for single aspect like: `Termination`, `Pausing`, `Linking`, `Supervising`, etc. Users can create custom Actors easily based on their needs. + - Supervision was added. `RestartingContext` will pause on error waiting on its supervisor to decide what to do next ( options are `:terminate!`, `:resume!`, `:reset!`, `:restart!`). Supervising behavior also supports strategies `:one_for_one` and `:one_for_all`. + - Linking was added to be able to monitor actor's events like: `:terminated`, `:paused`, `:restarted`, etc. + - Dead letter routing added. Rejected envelopes are collected in a configurable actor (default: `Concurrent::Actor.root.ask!(:dead_letter_routing)`) + - Old `Actor` class removed and replaced by new implementation previously called `Actress`. `Actress` was kept as an alias for `Actor` to keep compatibility. + - `Utils::Broadcast` actor which allows Publish–subscribe pattern. +* More executors for managing serialized operations + - `SerializedExecution` mixin module + - `SerializedExecutionDelegator` for serializing *any* executor +* Updated `Async` with serialized execution +* Updated `ImmediateExecutor` and `PerThreadExecutor` with full executor service lifecycle +* Added a `Delay` to root `Actress` initialization +* Minor bug fixes to thread pools +* Refactored many intermittently failing specs +* Removed Java interop warning `executor.rb:148 warning: ambiguous Java methods found, using submit(java.lang.Runnable)` +* Fixed minor bug in `RubyCachedThreadPool` overflow policy +* Updated tests to use [RSpec 3.0](http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3) +* Removed deprecated `Actor` class +* Better support for Rubinius + +## Release v0.6.1 (14 June 2014) + +* Many improvements to `Concurrent::Actress` +* Bug fixes to `Concurrent::RubyThreadPoolExecutor` +* Fixed several brittle tests +* Moved documentation to http://ruby-concurrency.github.io/concurrent-ruby/frames.html + +## Release v0.6.0 (25 May 2014) + +* Added `Concurrent::Observable` to encapsulate our thread safe observer sets +* Improvements to new `Channel` +* Major improvements to `CachedThreadPool` and `FixedThreadPool` +* Added `SingleThreadExecutor` +* Added `Current::timer` function +* Added `TimerSet` executor +* Added `AtomicBoolean` +* `ScheduledTask` refactoring +* Pure Ruby and JRuby-optimized `PriorityQueue` classes +* Updated `Agent` behavior to more closely match Clojure +* Observer sets support block callbacks to the `add_observer` method +* New algorithm for thread creation in `RubyThreadPoolExecutor` +* Minor API updates to `Event` +* Rewritten `TimerTask` now an `Executor` instead of a `Runnable` +* Fixed many brittle specs +* Renamed `FixedThreadPool` and `CachedThreadPool` to `RubyFixedThreadPool` and `RubyCachedThreadPool` +* Created JRuby optimized `JavaFixedThreadPool` and `JavaCachedThreadPool` +* Consolidated fixed thread pool tests into `spec/concurrent/fixed_thread_pool_shared.rb` and `spec/concurrent/cached_thread_pool_shared.rb` +* `FixedThreadPool` now subclasses `RubyFixedThreadPool` or `JavaFixedThreadPool` as appropriate +* `CachedThreadPool` now subclasses `RubyCachedThreadPool` or `JavaCachedThreadPool` as appropriate +* New `Delay` class +* `Concurrent::processor_count` helper function +* New `Async` module +* Renamed `NullThreadPool` to `PerThreadExecutor` +* Deprecated `Channel` (we are planning a new implementation based on [Go](http://golangtutorials.blogspot.com/2011/06/channels-in-go.html)) +* Added gem-level [configuration](http://robots.thoughtbot.com/mygem-configure-block) +* Deprecated `$GLOBAL_THREAD_POOL` in lieu of gem-level configuration +* Removed support for Ruby [1.9.2](https://www.ruby-lang.org/en/news/2013/12/17/maintenance-of-1-8-7-and-1-9-2/) +* New `RubyThreadPoolExecutor` and `JavaThreadPoolExecutor` classes +* All thread pools now extend the appropriate thread pool executor classes +* All thread pools now support `:overflow_policy` (based on Java's [reject policies](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html)) +* Deprecated `UsesGlobalThreadPool` in lieu of explicit `:executor` option (dependency injection) on `Future`, `Promise`, and `Agent` +* Added `Concurrent::dataflow_with(executor, *inputs)` method to support executor dependency injection for dataflow +* Software transactional memory with `TVar` and `Concurrent::atomically` +* First implementation of [new, high-performance](https://github.com/ruby-concurrency/concurrent-ruby/pull/49) `Channel` +* `Actor` is deprecated in favor of new experimental actor implementation [#73](https://github.com/ruby-concurrency/concurrent-ruby/pull/73). To avoid namespace collision it is living in `Actress` namespace until `Actor` is removed in next release. + +## Release v0.5.0 + +This is the most significant release of this gem since its inception. This release includes many improvements and optimizations. It also includes several bug fixes. The major areas of focus for this release were: + +* Stability improvements on Ruby versions with thread-level parallelism ([JRuby](http://jruby.org/) and [Rubinius](http://rubini.us/)) +* Creation of new low-level concurrency abstractions +* Internal refactoring to use the new low-level abstractions + +Most of these updates had no effect on the gem API. There are a few notable exceptions which were unavoidable. Please read the [release notes](API-Updates-in-v0.5.0) for more information. + +Specific changes include: + +* New class `IVar` +* New class `MVar` +* New class `ThreadLocalVar` +* New class `AtomicFixnum` +* New class method `dataflow` +* New class `Condition` +* New class `CountDownLatch` +* New class `DependencyCounter` +* New class `SafeTaskExecutor` +* New class `CopyOnNotifyObserverSet` +* New class `CopyOnWriteObserverSet` +* `Future` updated with `execute` API +* `ScheduledTask` updated with `execute` API +* New `Promise` API +* `Future` now extends `IVar` +* `Postable#post?` now returns an `IVar` +* Thread safety fixes to `Dereferenceable` +* Thread safety fixes to `Obligation` +* Thread safety fixes to `Supervisor` +* Thread safety fixes to `Event` +* Various other thread safety (race condition) fixes +* Refactored brittle tests +* Implemented pending tests +* Added JRuby and Rubinius as Travis CI build targets +* Added [CodeClimate](https://codeclimate.com/) code review +* Improved YARD documentation diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/Gemfile b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/Gemfile new file mode 100644 index 00000000..1786c8b2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/Gemfile @@ -0,0 +1,36 @@ +source 'https://rubygems.org' + +version = File.read("#{__dir__}/lib/concurrent-ruby/concurrent/version.rb")[/'(.+)'/, 1] or raise +edge_version = File.read("#{__dir__}/lib/concurrent-ruby-edge/concurrent/edge/version.rb")[/'(.+)'/, 1] or raise + +no_path = ENV['NO_PATH'] +options = no_path ? {} : { path: '.' } + +gem 'concurrent-ruby', version, options +gem 'concurrent-ruby-edge', edge_version, options +gem 'concurrent-ruby-ext', version, options.merge(platform: :mri) + +group :development do + gem 'rake', '~> 13.0' + gem 'rake-compiler', '~> 1.0', '>= 1.0.7', '!= 1.2.4' + gem 'rake-compiler-dock', '~> 1.0' + gem 'pry', '~> 0.11', platforms: :mri +end + +group :documentation, optional: true do + gem 'yard', '~> 0.9.0', require: false + gem 'redcarpet', '~> 3.0', platforms: :mri # understands github markdown + gem 'md-ruby-eval', '~> 0.6' +end + +group :testing do + gem 'rspec', '~> 3.7' + gem 'timecop', '~> 0.9' + gem 'sigdump', require: false +end + +# made opt-in since it will not install on jruby 1.7 +group :coverage, optional: !ENV['COVERAGE'] do + gem 'simplecov', '~> 0.16.0', require: false + gem 'coveralls', '~> 0.8.2', require: false +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/LICENSE.txt b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/LICENSE.txt new file mode 100644 index 00000000..1026f28d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/LICENSE.txt @@ -0,0 +1,21 @@ +Copyright (c) Jerry D'Antonio -- released under the MIT license. + +http://www.opensource.org/licenses/mit-license.php + +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 +AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/README.md b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/README.md new file mode 100644 index 00000000..63ee743c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/README.md @@ -0,0 +1,407 @@ +# Concurrent Ruby + +[![Gem Version](https://badge.fury.io/rb/concurrent-ruby.svg)](http://badge.fury.io/rb/concurrent-ruby) +[![License](https://img.shields.io/badge/license-MIT-green.svg)](http://opensource.org/licenses/MIT) +[![Gitter chat](https://img.shields.io/badge/IRC%20(gitter)-devs%20%26%20users-brightgreen.svg)](https://gitter.im/ruby-concurrency/concurrent-ruby) + +Modern concurrency tools for Ruby. Inspired by +[Erlang](http://www.erlang.org/doc/reference_manual/processes.html), +[Clojure](http://clojure.org/concurrent_programming), +[Scala](http://akka.io/), +[Haskell](http://www.haskell.org/haskellwiki/Applications_and_libraries/Concurrency_and_parallelism#Concurrent_Haskell), +[F#](http://blogs.msdn.com/b/dsyme/archive/2010/02/15/async-and-parallel-design-patterns-in-f-part-3-agents.aspx), +[C#](http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx), +[Java](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html), +and classic concurrency patterns. + + + +The design goals of this gem are: + +* Be an 'unopinionated' toolbox that provides useful utilities without debating which is better + or why +* Remain free of external gem dependencies +* Stay true to the spirit of the languages providing inspiration +* But implement in a way that makes sense for Ruby +* Keep the semantics as idiomatic Ruby as possible +* Support features that make sense in Ruby +* Exclude features that don't make sense in Ruby +* Be small, lean, and loosely coupled +* Thread-safety +* Backward compatibility + +## Contributing + +**This gem depends on +[contributions](https://github.com/ruby-concurrency/concurrent-ruby/graphs/contributors) and we +appreciate your help. Would you like to contribute? Great! Have a look at +[issues with `looking-for-contributor` label](https://github.com/ruby-concurrency/concurrent-ruby/issues?q=is%3Aissue+is%3Aopen+label%3Alooking-for-contributor).** And if you pick something up let us know on the issue. + +You can also get started by triaging issues which may include reproducing bug reports or asking for vital information, such as version numbers or reproduction instructions. If you would like to start triaging issues, one easy way to get started is to [subscribe to concurrent-ruby on CodeTriage](https://www.codetriage.com/ruby-concurrency/concurrent-ruby). [![Open Source Helpers](https://www.codetriage.com/ruby-concurrency/concurrent-ruby/badges/users.svg)](https://www.codetriage.com/ruby-concurrency/concurrent-ruby) + +## Thread Safety + +*Concurrent Ruby makes one of the strongest thread safety guarantees of any Ruby concurrency +library, providing consistent behavior and guarantees on all three main Ruby interpreters +(MRI/CRuby, JRuby, TruffleRuby).* + +Every abstraction in this library is thread safe. Specific thread safety guarantees are documented +with each abstraction. + +It is critical to remember, however, that Ruby is a language of mutable references. *No* +concurrency library for Ruby can ever prevent the user from making thread safety mistakes (such as +sharing a mutable object between threads and modifying it on both threads) or from creating +deadlocks through incorrect use of locks. All the library can do is provide safe abstractions which +encourage safe practices. Concurrent Ruby provides more safe concurrency abstractions than any +other Ruby library, many of which support the mantra of +["Do not communicate by sharing memory; instead, share memory by communicating"](https://blog.golang.org/share-memory-by-communicating). +Concurrent Ruby is also the only Ruby library which provides a full suite of thread safe and +immutable variable types and data structures. + +We've also initiated discussion to document the [memory model](docs-source/synchronization.md) of Ruby which +would provide consistent behaviour and guarantees on all three main Ruby interpreters +(MRI/CRuby, JRuby, TruffleRuby). + +## Features & Documentation + +**The primary site for documentation is the automatically generated +[API documentation](http://ruby-concurrency.github.io/concurrent-ruby/index.html) which is up to +date with latest release.** This readme matches the master so may contain new stuff not yet +released. + +We also have a [IRC (gitter)](https://gitter.im/ruby-concurrency/concurrent-ruby). + +### Versioning + +* `concurrent-ruby` uses [Semantic Versioning](http://semver.org/) +* `concurrent-ruby-ext` has always same version as `concurrent-ruby` +* `concurrent-ruby-edge` will always be 0.y.z therefore following + [point 4](http://semver.org/#spec-item-4) applies *"Major version zero + (0.y.z) is for initial development. Anything may change at any time. The + public API should not be considered stable."* However we additionally use + following rules: + * Minor version increment means incompatible changes were made + * Patch version increment means only compatible changes were made + + +#### General-purpose Concurrency Abstractions + +* [Async](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Async.html): + A mixin module that provides simple asynchronous behavior to a class. Loosely based on Erlang's + [gen_server](http://www.erlang.org/doc/man/gen_server.html). +* [ScheduledTask](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ScheduledTask.html): + Like a Future scheduled for a specific future time. +* [TimerTask](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/TimerTask.html): + A Thread that periodically wakes up to perform work at regular intervals. +* [Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html): + Unified implementation of futures and promises which combines features of previous `Future`, + `Promise`, `IVar`, `Event`, `dataflow`, `Delay`, and (partially) `TimerTask` into a single + framework. It extensively uses the new synchronization layer to make all the features + **non-blocking** and **lock-free**, with the exception of obviously blocking operations like + `#wait`, `#value`. It also offers better performance. + +#### Thread-safe Value Objects, Structures, and Collections + +Collection classes that were originally part of the (deprecated) `thread_safe` gem: + +* [Array](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Array.html) A thread-safe + subclass of Ruby's standard [Array](http://ruby-doc.org/core/Array.html). +* [Hash](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Hash.html) A thread-safe + subclass of Ruby's standard [Hash](http://ruby-doc.org/core/Hash.html). +* [Set](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Set.html) A thread-safe + subclass of Ruby's standard [Set](http://ruby-doc.org/stdlib-2.4.0/libdoc/set/rdoc/Set.html). +* [Map](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Map.html) A hash-like object + that should have much better performance characteristics, especially under high concurrency, + than `Concurrent::Hash`. +* [Tuple](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Tuple.html) A fixed size + array with volatile (synchronized, thread safe) getters/setters. + +Value objects inspired by other languages: + +* [Maybe](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Maybe.html) A thread-safe, + immutable object representing an optional value, based on + [Haskell Data.Maybe](https://hackage.haskell.org/package/base-4.2.0.1/docs/Data-Maybe.html). + +Structure classes derived from Ruby's [Struct](http://ruby-doc.org/core/Struct.html): + +* [ImmutableStruct](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ImmutableStruct.html) + Immutable struct where values are set at construction and cannot be changed later. +* [MutableStruct](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/MutableStruct.html) + Synchronized, mutable struct where values can be safely changed at any time. +* [SettableStruct](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/SettableStruct.html) + Synchronized, write-once struct where values can be set at most once, either at construction + or any time thereafter. + +Thread-safe variables: + +* [Agent](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Agent.html): A way to + manage shared, mutable, *asynchronous*, independent state. Based on Clojure's + [Agent](http://clojure.org/agents). +* [Atom](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Atom.html): A way to manage + shared, mutable, *synchronous*, independent state. Based on Clojure's + [Atom](http://clojure.org/atoms). +* [AtomicBoolean](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/AtomicBoolean.html) + A boolean value that can be updated atomically. +* [AtomicFixnum](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/AtomicFixnum.html) + A numeric value that can be updated atomically. +* [AtomicReference](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/AtomicReference.html) + An object reference that may be updated atomically. +* [Exchanger](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Exchanger.html) + A synchronization point at which threads can pair and swap elements within pairs. Based on + Java's [Exchanger](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Exchanger.html). +* [MVar](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/MVar.html) A synchronized + single element container. Based on Haskell's + [MVar](https://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Concurrent-MVar.html) and + Scala's [MVar](http://docs.typelevel.org/api/scalaz/nightly/index.html#scalaz.concurrent.MVar$). +* [ThreadLocalVar](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ThreadLocalVar.html) + A variable where the value is different for each thread. +* [TVar](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/TVar.html) A transactional + variable implementing software transactional memory (STM). Based on Clojure's + [Ref](http://clojure.org/refs). + +#### Java-inspired ThreadPools and Other Executors + +* See the [thread pool](http://ruby-concurrency.github.io/concurrent-ruby/master/file.thread_pools.html) + overview, which also contains a list of other Executors available. + +#### Thread Synchronization Classes and Algorithms + +* [CountDownLatch](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/CountDownLatch.html) + A synchronization object that allows one thread to wait on multiple other threads. +* [CyclicBarrier](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/CyclicBarrier.html) + A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. +* [Event](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Event.html) Old school + kernel-style event. +* [ReadWriteLock](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ReadWriteLock.html) + A lock that supports multiple readers but only one writer. +* [ReentrantReadWriteLock](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ReentrantReadWriteLock.html) + A read/write lock with reentrant and upgrade features. +* [Semaphore](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Semaphore.html) + A counting-based locking mechanism that uses permits. +* [AtomicMarkableReference](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/AtomicMarkableReference.html) + +#### Deprecated + +Deprecated features are still available and bugs are being fixed, but new features will not be added. + +* ~~[Future](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Future.html): + An asynchronous operation that produces a value.~~ Replaced by + [Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html). + * ~~[.dataflow](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent.html#dataflow-class_method): + Built on Futures, Dataflow allows you to create a task that will be scheduled when all of + its data dependencies are available.~~ Replaced by + [Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html). +* ~~[Promise](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promise.html): Similar + to Futures, with more features.~~ Replaced by + [Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html). +* ~~[Delay](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Delay.html) Lazy evaluation + of a block yielding an immutable result. Based on Clojure's + [delay](https://clojuredocs.org/clojure.core/delay).~~ Replaced by + [Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html). +* ~~[IVar](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/IVar.html) Similar to a + "future" but can be manually assigned once, after which it becomes immutable.~~ Replaced by + [Promises](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises.html). + +### Edge Features + +These are available in the `concurrent-ruby-edge` companion gem. + +These features are under active development and may change frequently. They are expected not to +keep backward compatibility (there may also lack tests and documentation). Semantic versions will +be obeyed though. Features developed in `concurrent-ruby-edge` are expected to move to +`concurrent-ruby` when final. + +* [Actor](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Actor.html): Implements + the Actor Model, where concurrent actors exchange messages. + *Status: Partial documentation and tests; depends on new future/promise framework; stability is good.* +* [Channel](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Channel.html): + Communicating Sequential Processes ([CSP](https://en.wikipedia.org/wiki/Communicating_sequential_processes)). + Functionally equivalent to Go [channels](https://tour.golang.org/concurrency/2) with additional + inspiration from Clojure [core.async](https://clojure.github.io/core.async/). + *Status: Partial documentation and tests.* +* [LazyRegister](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/LazyRegister.html) +* [LockFreeLinkedSet](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Edge/LockFreeLinkedSet.html) + *Status: will be moved to core soon.* +* [LockFreeStack](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/LockFreeStack.html) + *Status: missing documentation and tests.* +* [Promises::Channel](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Promises/Channel.html) + A first in first out channel that accepts messages with push family of methods and returns + messages with pop family of methods. + Pop and push operations can be represented as futures, see `#pop_op` and `#push_op`. + The capacity of the channel can be limited to support back pressure, use capacity option in `#initialize`. + `#pop` method blocks ans `#pop_op` returns pending future if there is no message in the channel. + If the capacity is limited the `#push` method blocks and `#push_op` returns pending future. +* [Cancellation](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Cancellation.html) + The Cancellation abstraction provides cooperative cancellation. + + The standard methods `Thread#raise` of `Thread#kill` available in Ruby + are very dangerous (see linked the blog posts bellow). + Therefore concurrent-ruby provides an alternative. + + * + * + * + + It provides an object which represents a task which can be executed, + the task has to get the reference to the object and periodically cooperatively check that it is not cancelled. + Good practices to make tasks cancellable: + * check cancellation every cycle of a loop which does significant work, + * do all blocking actions in a loop with a timeout then on timeout check cancellation + and if ok block again with the timeout +* [Throttle](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/Throttle.html) + A tool managing concurrency level of tasks. +* [ErlangActor](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/ErlangActor.html) + Actor implementation which precisely matches Erlang actor behaviour. + Requires at least Ruby 2.1 otherwise it's not loaded. +* [WrappingExecutor](http://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent/WrappingExecutor.html) + A delegating executor which modifies each task before the task is given to + the target executor it delegates to. + +## Supported Ruby versions + +* MRI 2.3 and above +* Latest JRuby 9000 +* Latest TruffleRuby + +## Usage + +Everything within this gem can be loaded simply by requiring it: + +```ruby +require 'concurrent' +``` + +You can also require a specific abstraction [part of the public documentation](https://ruby-concurrency.github.io/concurrent-ruby/master/index.html) since concurrent-ruby 1.2.0, for example: +```ruby +require 'concurrent/map' +require 'concurrent/atomic/atomic_reference' +require 'concurrent/executor/fixed_thread_pool' +``` + +To use the tools in the Edge gem it must be required separately: + +```ruby +require 'concurrent-edge' +``` + +If the library does not behave as expected, `Concurrent.use_simple_logger(:DEBUG)` could +help to reveal the problem. + +## Installation + +```shell +gem install concurrent-ruby +``` + +or add the following line to Gemfile: + +```ruby +gem 'concurrent-ruby', require: 'concurrent' +``` + +and run `bundle install` from your shell. + +### Edge Gem Installation + +The Edge gem must be installed separately from the core gem: + +```shell +gem install concurrent-ruby-edge +``` + +or add the following line to Gemfile: + +```ruby +gem 'concurrent-ruby-edge', require: 'concurrent-edge' +``` + +and run `bundle install` from your shell. + + +### C Extensions for MRI + +Potential performance improvements may be achieved under MRI by installing optional C extensions. +To minimise installation errors the C extensions are available in the `concurrent-ruby-ext` +extension gem. `concurrent-ruby` and `concurrent-ruby-ext` are always released together with same +version. Simply install the extension gem too: + +```ruby +gem install concurrent-ruby-ext +``` + +or add the following line to Gemfile: + +```ruby +gem 'concurrent-ruby-ext' +``` + +and run `bundle install` from your shell. + +In code it is only necessary to + +```ruby +require 'concurrent' +``` + +The `concurrent-ruby` gem will automatically detect the presence of the `concurrent-ruby-ext` gem +and load the appropriate C extensions. + +#### Note For gem developers + +No gems should depend on `concurrent-ruby-ext`. Doing so will force C extensions on your users. The +best practice is to depend on `concurrent-ruby` and let users to decide if they want C extensions. + +## Building the gem + +### Requirements + +* Recent CRuby +* JRuby, `rbenv install jruby-9.2.17.0` +* Set env variable `CONCURRENT_JRUBY_HOME` to point to it, e.g. `/usr/local/opt/rbenv/versions/jruby-9.2.17.0` +* Install Docker, required for Windows builds + +### Publishing the Gem + +* Update `version.rb` +* Update the CHANGELOG +* Add the new version to `docs-source/signpost.md`. Needs to be done only if there are visible changes in the documentation. +* Commit (and push) the changes. +* Use `bundle exec rake release` to release the gem. + It consists of `['release:checks', 'release:build', 'release:test', 'release:publish']` steps. + It will ask at the end before publishing anything. Steps can also be executed individually. + +## Maintainers + +* [Benoit Daloze](https://github.com/eregon) +* [Matthew Draper](https://github.com/matthewd) +* [Rafael França](https://github.com/rafaelfranca) +* [Charles Oliver Nutter](https://github.com/headius) +* [Ben Sheldon](https://github.com/bensheldon) +* [Samuel Williams](https://github.com/ioquatix) + +### Special Thanks to + +* [Jerry D'Antonio](https://github.com/jdantonio) for creating the gem +* [Brian Durand](https://github.com/bdurand) for the `ref` gem +* [Charles Oliver Nutter](https://github.com/headius) for the `atomic` and `thread_safe` gems +* [thedarkone](https://github.com/thedarkone) for the `thread_safe` gem + +to the past maintainers + +* [Chris Seaton](https://github.com/chrisseaton) +* [Petr Chalupa](https://github.com/pitr-ch) +* [Michele Della Torre](https://github.com/mighe) +* [Paweł Obrok](https://github.com/obrok) +* [Lucas Allan](https://github.com/lucasallan) + +and to [Ruby Association](https://www.ruby.or.jp/en/) for sponsoring a project +["Enhancing Ruby’s concurrency tooling"](https://www.ruby.or.jp/en/news/20181106) in 2018. + +## License and Copyright + +*Concurrent Ruby* is free software released under the +[MIT License](http://www.opensource.org/licenses/MIT). + +The *Concurrent Ruby* [logo](https://raw.githubusercontent.com/ruby-concurrency/concurrent-ruby/master/docs-source/logo/concurrent-ruby-logo-300x300.png) was +designed by [David Jones](https://twitter.com/zombyboy). It is Copyright © 2014 +[Jerry D'Antonio](https://twitter.com/jerrydantonio). All Rights Reserved. diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/Rakefile b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/Rakefile new file mode 100644 index 00000000..3d157d47 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/Rakefile @@ -0,0 +1,344 @@ +version = File.read("#{__dir__}/lib/concurrent-ruby/concurrent/version.rb")[/'(.+)'/, 1] or raise +edge_version = File.read("#{__dir__}/lib/concurrent-ruby-edge/concurrent/edge/version.rb")[/'(.+)'/, 1] or raise + +core_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby.gemspec') +ext_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby-ext.gemspec') +edge_gemspec = Gem::Specification.load File.join(__dir__, 'concurrent-ruby-edge.gemspec') + +require 'rake/javaextensiontask' + +ENV['JRUBY_HOME'] = ENV['CONCURRENT_JRUBY_HOME'] if ENV['CONCURRENT_JRUBY_HOME'] && RUBY_ENGINE != 'jruby' + +Rake::JavaExtensionTask.new('concurrent_ruby', core_gemspec) do |ext| + ext.ext_dir = 'ext/concurrent-ruby' + ext.lib_dir = 'lib/concurrent-ruby/concurrent' + ext.source_version = '8' + ext.target_version = '8' +end + +if RUBY_ENGINE == 'ruby' + require 'rake/extensiontask' + + Rake::ExtensionTask.new('concurrent_ruby_ext', ext_gemspec) do |ext| + ext.ext_dir = 'ext/concurrent-ruby-ext' + ext.lib_dir = 'lib/concurrent-ruby/concurrent' + ext.source_pattern = '*.{c,h}' + + ext.cross_compile = true + ext.cross_platform = ['x86-mingw32', 'x64-mingw32'] + end +end + +def which?(executable) + !`which #{executable} 2>/dev/null`.empty? +end + +require 'rake_compiler_dock' +namespace :repackage do + desc '* with Windows fat distributions' + task :all do + Dir.chdir(__dir__) do + # store gems in vendor cache for docker + Bundler.with_original_env do + sh 'bundle package' + end + + # build only the jar file not the whole gem for java platform, the jar is part the concurrent-ruby-x.y.z.gem + Rake::Task['lib/concurrent-ruby/concurrent/concurrent_ruby.jar'].invoke + + # build all gem files + rack_compiler_dock_kwargs = {} + if which?('podman') and (!which?('docker') || `docker --version`.include?('podman')) + # podman and only podman available, so RakeCompilerDock will use podman, otherwise it uses docker + rack_compiler_dock_kwargs = { + options: ['--privileged'], # otherwise the directory in the image is empty + runas: false + } + end + %w[x86-mingw32 x64-mingw32].each do |plat| + RakeCompilerDock.sh( + "bundle install --local && bundle exec rake native:#{plat} gem --trace", + platform: plat, + **rack_compiler_dock_kwargs) + end + end + end +end + +require 'rubygems' +require 'rubygems/package_task' + +Gem::PackageTask.new(core_gemspec) {} if core_gemspec +Gem::PackageTask.new(ext_gemspec) {} if ext_gemspec && RUBY_ENGINE != 'jruby' +Gem::PackageTask.new(edge_gemspec) {} if edge_gemspec + +CLEAN.include( + 'lib/concurrent-ruby/concurrent/concurrent_ruby_ext.*', + 'lib/concurrent-ruby/concurrent/2.*', + 'lib/concurrent-ruby/concurrent/*.jar') + +begin + require 'rspec' + require 'rspec/core/rake_task' + + RSpec::Core::RakeTask.new(:spec) + + namespace :spec do + desc '* Configured for ci' + RSpec::Core::RakeTask.new(:ci) do |t| + options = %w[ --color + --backtrace + --order defined + --format documentation ] + t.rspec_opts = [*options].join(' ') + end + + desc '* test packaged and installed gems instead of local files' + task :installed do + Bundler.with_original_env do + Dir.chdir(__dir__) do + sh "gem install pkg/concurrent-ruby-#{version}.gem" + sh "gem install pkg/concurrent-ruby-ext-#{version}.gem" if RUBY_ENGINE == 'ruby' + sh "gem install pkg/concurrent-ruby-edge-#{edge_version}.gem" + ENV['NO_PATH'] = 'true' + sh 'bundle update' + sh 'bundle exec rake spec:ci' + end + end + end + end + + desc 'executed in CI' + task :ci => [:compile, 'spec:ci'] + + desc 'run each spec file in a separate process to help find missing requires' + task 'spec:isolated' do + glob = "#{ENV['DIR'] || 'spec'}/**/*_spec.rb" + from = ENV['FROM'] + env = { 'ISOLATED' => 'true' } + Dir[glob].each do |spec| + next if from and from != spec + from = nil if from == spec + + sh env, 'rspec', spec + end + end + + task :default => [:clobber, :compile, :spec] +rescue LoadError => e + puts 'RSpec is not installed, skipping test task definitions: ' + e.message +end + +current_yard_version_name = version + +begin + require 'yard' + require 'md_ruby_eval' + require_relative 'support/yard_full_types' + + common_yard_options = ['--no-yardopts', + '--no-document', + '--no-private', + '--embed-mixins', + '--markup', 'markdown', + '--title', 'Concurrent Ruby', + '--template', 'default', + '--template-path', 'yard-template', + '--default-return', 'undocumented'] + + desc 'Generate YARD Documentation (signpost, master)' + task :yard => ['yard:signpost', 'yard:master'] + + namespace :yard do + + desc '* eval markdown files' + task :eval_md do + Dir.chdir File.join(__dir__, 'docs-source') do + sh 'bundle exec md-ruby-eval --auto' + end + end + + task :update_readme do + Dir.chdir __dir__ do + content = File.read(File.join('README.md')). + gsub(/\[([\w ]+)\]\(http:\/\/ruby-concurrency\.github\.io\/concurrent-ruby\/master\/.*\)/) do |_| + case $1 + when 'LockFreeLinkedSet' + "{Concurrent::Edge::#{$1} #{$1}}" + when '.dataflow' + '{Concurrent.dataflow Concurrent.dataflow}' + when 'thread pool' + '{file:thread_pools.md thread pool}' + else + "{Concurrent::#{$1} #{$1}}" + end + end + FileUtils.mkpath 'tmp' + File.write 'tmp/README.md', content + end + end + + define_yard_task = -> name do + output_dir = "docs/#{name}" + + removal_name = "remove.#{name}" + task removal_name do + Dir.chdir __dir__ do + FileUtils.rm_rf output_dir + end + end + + desc "* of #{name} into subdir #{name}" + YARD::Rake::YardocTask.new(name) do |yard| + yard.options.push( + '--output-dir', output_dir, + '--main', 'tmp/README.md', + *common_yard_options) + yard.files = ['./lib/concurrent-ruby/**/*.rb', + './lib/concurrent-ruby-edge/**/*.rb', + './ext/concurrent_ruby_ext/**/*.c', + '-', + 'docs-source/thread_pools.md', + 'docs-source/promises.out.md', + 'docs-source/medium-example.out.rb', + 'LICENSE.txt', + 'CHANGELOG.md'] + end + Rake::Task[name].prerequisites.push removal_name, + # 'yard:eval_md', + 'yard:update_readme' + end + + define_yard_task.call current_yard_version_name + define_yard_task.call 'master' + + desc "* signpost for versions" + YARD::Rake::YardocTask.new(:signpost) do |yard| + yard.options.push( + '--output-dir', 'docs', + '--main', 'docs-source/signpost.md', + *common_yard_options) + yard.files = ['no-lib'] + end + end + +rescue LoadError => e + puts 'YARD is not installed, skipping documentation task definitions: ' + e.message +end + +desc 'build, test, and publish the gem' +task :release => ['release:checks', 'release:build', 'release:test', 'release:publish'] + +namespace :release do + # Depends on environment of @pitr-ch + + task :checks do + raise '$CONCURRENT_JRUBY_HOME must be set' unless ENV['CONCURRENT_JRUBY_HOME'] + + Dir.chdir(__dir__) do + sh 'test -z "$(git status --porcelain)"' do |ok, res| + unless ok + begin + status = `git status --porcelain` + STDOUT.puts 'There are local changes that you might want to commit.', status, 'Continue? (y/n)' + input = STDIN.gets.strip.downcase + end until %w(y n).include?(input) + exit 1 if input == 'n' + end + end + sh 'git fetch' + sh 'test $(git show-ref --verify --hash refs/heads/master) = ' + + '$(git show-ref --verify --hash refs/remotes/origin/master)' do |ok, res| + unless ok + begin + STDOUT.puts 'Local master branch is not pushed to origin.', 'Continue? (y/n)' + input = STDIN.gets.strip.downcase + end until %w(y n).include?(input) + exit 1 if input == 'n' + end + end + end + end + + desc '* build all *.gem files necessary for release' + task :build => [:clobber, 'repackage:all'] + + desc '* test actual installed gems instead of cloned repository on MRI and JRuby' + task :test do + raise '$CONCURRENT_JRUBY_HOME must be set' unless ENV['CONCURRENT_JRUBY_HOME'] + + Dir.chdir(__dir__) do + puts "Testing with the installed gem" + + Bundler.with_original_env do + sh 'ruby -v' + sh 'bundle install' + sh 'bundle exec rake spec:installed' + + env = { "PATH" => "#{ENV.fetch('CONCURRENT_JRUBY_HOME')}/bin:#{ENV['PATH']}" } + sh env, 'ruby -v' + sh env, 'bundle install' + sh env, 'bundle exec rake spec:installed' + end + + puts 'Windows build is untested' + end + end + + desc '* do all nested steps' + task :publish => ['publish:ask', 'publish:tag', 'publish:rubygems', 'publish:post_steps'] + + namespace :publish do + publish_base = nil + publish_edge = nil + + task :ask do + begin + STDOUT.puts 'Do you want to publish anything now? (y/n)' + input = STDIN.gets.strip.downcase + end until %w(y n).include?(input) + exit 1 if input == 'n' + + begin + STDOUT.puts 'Do you want to publish `concurrent-ruby`? (y/n)' + input = STDIN.gets.strip.downcase + end until %w(y n).include?(input) + publish_base = input == 'y' + + begin + STDOUT.puts 'Do you want to publish `concurrent-ruby-edge`? (y/n)' + input = STDIN.gets.strip.downcase + end until %w(y n).include?(input) + publish_edge = input == 'y' + end + + desc '** tag HEAD with current version and push to github' + task :tag => :ask do + Dir.chdir(__dir__) do + sh "git tag v#{version}" if publish_base + sh "git push origin v#{version}" if publish_base + sh "git tag edge-v#{edge_version}" if publish_edge + sh "git push origin edge-v#{edge_version}" if publish_edge + end + end + + desc '** push all *.gem files to rubygems' + task :rubygems => :ask do + Dir.chdir(__dir__) do + sh "gem push pkg/concurrent-ruby-#{version}.gem" if publish_base + sh "gem push pkg/concurrent-ruby-edge-#{edge_version}.gem" if publish_edge + sh "gem push pkg/concurrent-ruby-ext-#{version}.gem" if publish_base + sh "gem push pkg/concurrent-ruby-ext-#{version}-x64-mingw32.gem" if publish_base + sh "gem push pkg/concurrent-ruby-ext-#{version}-x86-mingw32.gem" if publish_base + end + end + + desc '** print post release steps' + task :post_steps do + # TODO: (petr 05-Jun-2021) automate and renew the process + puts 'Manually: create a release on GitHub with relevant changelog part' + puts 'Manually: send email same as release with relevant changelog part' + puts 'Manually: tweet' + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/ConcurrentRubyService.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/ConcurrentRubyService.java new file mode 100644 index 00000000..fb6be96d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/ConcurrentRubyService.java @@ -0,0 +1,17 @@ +import org.jruby.Ruby; +import org.jruby.runtime.load.BasicLibraryService; + +import java.io.IOException; + +public class ConcurrentRubyService implements BasicLibraryService { + + public boolean basicLoad(final Ruby runtime) throws IOException { + new com.concurrent_ruby.ext.AtomicReferenceLibrary().load(runtime, false); + new com.concurrent_ruby.ext.JavaAtomicBooleanLibrary().load(runtime, false); + new com.concurrent_ruby.ext.JavaAtomicFixnumLibrary().load(runtime, false); + new com.concurrent_ruby.ext.JavaSemaphoreLibrary().load(runtime, false); + new com.concurrent_ruby.ext.SynchronizationLibrary().load(runtime, false); + new com.concurrent_ruby.ext.JRubyMapBackendLibrary().load(runtime, false); + return true; + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java new file mode 100644 index 00000000..dfa9e770 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/AtomicReferenceLibrary.java @@ -0,0 +1,175 @@ +package com.concurrent_ruby.ext; + +import java.lang.reflect.Field; +import java.io.IOException; +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; +import org.jruby.Ruby; +import org.jruby.RubyClass; +import org.jruby.RubyModule; +import org.jruby.RubyNumeric; +import org.jruby.RubyObject; +import org.jruby.anno.JRubyClass; +import org.jruby.anno.JRubyMethod; +import org.jruby.runtime.ObjectAllocator; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.builtin.IRubyObject; +import org.jruby.runtime.load.Library; + +/** + * This library adds an atomic reference type to JRuby for use in the atomic + * library. We do a native version to avoid the implicit value coercion that + * normally happens through JI. + * + * @author headius + */ +public class AtomicReferenceLibrary implements Library { + public void load(Ruby runtime, boolean wrap) throws IOException { + RubyModule concurrentMod = runtime.defineModule("Concurrent"); + RubyClass atomicCls = concurrentMod.defineClassUnder("JavaAtomicReference", runtime.getObject(), JRUBYREFERENCE_ALLOCATOR); + try { + sun.misc.Unsafe.class.getMethod("getAndSetObject", Object.class); + atomicCls.setAllocator(JRUBYREFERENCE8_ALLOCATOR); + } catch (Exception e) { + // leave it as Java 6/7 version + } + atomicCls.defineAnnotatedMethods(JRubyReference.class); + } + + private static final ObjectAllocator JRUBYREFERENCE_ALLOCATOR = new ObjectAllocator() { + public IRubyObject allocate(Ruby runtime, RubyClass klazz) { + return new JRubyReference(runtime, klazz); + } + }; + + private static final ObjectAllocator JRUBYREFERENCE8_ALLOCATOR = new ObjectAllocator() { + public IRubyObject allocate(Ruby runtime, RubyClass klazz) { + return new JRubyReference8(runtime, klazz); + } + }; + + @JRubyClass(name="JRubyReference", parent="Object") + public static class JRubyReference extends RubyObject { + volatile IRubyObject reference; + + static final sun.misc.Unsafe UNSAFE; + static final long referenceOffset; + + static { + try { + UNSAFE = UnsafeHolder.U; + Class k = JRubyReference.class; + referenceOffset = UNSAFE.objectFieldOffset(k.getDeclaredField("reference")); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public JRubyReference(Ruby runtime, RubyClass klass) { + super(runtime, klass); + } + + @JRubyMethod + public IRubyObject initialize(ThreadContext context) { + UNSAFE.putObject(this, referenceOffset, context.nil); + return context.nil; + } + + @JRubyMethod + public IRubyObject initialize(ThreadContext context, IRubyObject value) { + UNSAFE.putObject(this, referenceOffset, value); + return context.nil; + } + + @JRubyMethod(name = {"get", "value"}) + public IRubyObject get() { + return reference; + } + + @JRubyMethod(name = {"set", "value="}) + public IRubyObject set(IRubyObject newValue) { + UNSAFE.putObjectVolatile(this, referenceOffset, newValue); + return newValue; + } + + @JRubyMethod(name = {"compare_and_set", "compare_and_swap"}) + public IRubyObject compare_and_set(ThreadContext context, IRubyObject expectedValue, IRubyObject newValue) { + Ruby runtime = context.runtime; + + if (expectedValue instanceof RubyNumeric) { + // numerics are not always idempotent in Ruby, so we need to do slower logic + return compareAndSetNumeric(context, expectedValue, newValue); + } + + return runtime.newBoolean(UNSAFE.compareAndSwapObject(this, referenceOffset, expectedValue, newValue)); + } + + @JRubyMethod(name = {"get_and_set", "swap"}) + public IRubyObject get_and_set(ThreadContext context, IRubyObject newValue) { + // less-efficient version for Java 6 and 7 + while (true) { + IRubyObject oldValue = get(); + if (UNSAFE.compareAndSwapObject(this, referenceOffset, oldValue, newValue)) { + return oldValue; + } + } + } + + private IRubyObject compareAndSetNumeric(ThreadContext context, IRubyObject expectedValue, IRubyObject newValue) { + Ruby runtime = context.runtime; + + // loop until: + // * reference CAS would succeed for same-valued objects + // * current and expected have different values as determined by #equals + while (true) { + IRubyObject current = reference; + + if (!(current instanceof RubyNumeric)) { + // old value is not numeric, CAS fails + return runtime.getFalse(); + } + + RubyNumeric currentNumber = (RubyNumeric)current; + if (!currentNumber.equals(expectedValue)) { + // current number does not equal expected, fail CAS + return runtime.getFalse(); + } + + // check that current has not changed, or else allow loop to repeat + boolean success = UNSAFE.compareAndSwapObject(this, referenceOffset, current, newValue); + if (success) { + // value is same and did not change in interim...success + return runtime.getTrue(); + } + } + } + } + + private static final class UnsafeHolder { + private UnsafeHolder(){} + + public static final sun.misc.Unsafe U = loadUnsafe(); + + private static sun.misc.Unsafe loadUnsafe() { + try { + Class unsafeClass = Class.forName("sun.misc.Unsafe"); + Field f = unsafeClass.getDeclaredField("theUnsafe"); + f.setAccessible(true); + return (sun.misc.Unsafe) f.get(null); + } catch (Exception e) { + return null; + } + } + } + + public static class JRubyReference8 extends JRubyReference { + public JRubyReference8(Ruby runtime, RubyClass klass) { + super(runtime, klass); + } + + @Override + public IRubyObject get_and_set(ThreadContext context, IRubyObject newValue) { + // efficient version for Java 8 + return (IRubyObject)UNSAFE.getAndSetObject(this, referenceOffset, newValue); + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/JRubyMapBackendLibrary.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/JRubyMapBackendLibrary.java new file mode 100644 index 00000000..a09f9162 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/JRubyMapBackendLibrary.java @@ -0,0 +1,248 @@ +package com.concurrent_ruby.ext; + +import org.jruby.*; +import org.jruby.anno.JRubyClass; +import org.jruby.anno.JRubyMethod; +import com.concurrent_ruby.ext.jsr166e.ConcurrentHashMap; +import com.concurrent_ruby.ext.jsr166e.ConcurrentHashMapV8; +import com.concurrent_ruby.ext.jsr166e.nounsafe.*; +import org.jruby.runtime.Block; +import org.jruby.runtime.ObjectAllocator; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.builtin.IRubyObject; +import org.jruby.runtime.load.Library; + +import java.io.IOException; +import java.util.Map; + +import static org.jruby.runtime.Visibility.PRIVATE; + +/** + * Native Java implementation to avoid the JI overhead. + * + * @author thedarkone + */ +public class JRubyMapBackendLibrary implements Library { + public void load(Ruby runtime, boolean wrap) throws IOException { + + RubyModule concurrentMod = runtime.defineModule("Concurrent"); + RubyModule thread_safeMod = concurrentMod.defineModuleUnder("Collection"); + RubyClass jrubyRefClass = thread_safeMod.defineClassUnder("JRubyMapBackend", runtime.getObject(), BACKEND_ALLOCATOR); + jrubyRefClass.setAllocator(BACKEND_ALLOCATOR); + jrubyRefClass.defineAnnotatedMethods(JRubyMapBackend.class); + } + + private static final ObjectAllocator BACKEND_ALLOCATOR = new ObjectAllocator() { + public IRubyObject allocate(Ruby runtime, RubyClass klazz) { + return new JRubyMapBackend(runtime, klazz); + } + }; + + @JRubyClass(name="JRubyMapBackend", parent="Object") + public static class JRubyMapBackend extends RubyObject { + // Defaults used by the CHM + static final int DEFAULT_INITIAL_CAPACITY = 16; + static final float DEFAULT_LOAD_FACTOR = 0.75f; + + public static final boolean CAN_USE_UNSAFE_CHM = canUseUnsafeCHM(); + + private ConcurrentHashMap map; + + private static ConcurrentHashMap newCHM(int initialCapacity, float loadFactor) { + if (CAN_USE_UNSAFE_CHM) { + return new ConcurrentHashMapV8(initialCapacity, loadFactor); + } else { + return new com.concurrent_ruby.ext.jsr166e.nounsafe.ConcurrentHashMapV8(initialCapacity, loadFactor); + } + } + + private static ConcurrentHashMap newCHM() { + return newCHM(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR); + } + + private static boolean canUseUnsafeCHM() { + try { + new com.concurrent_ruby.ext.jsr166e.ConcurrentHashMapV8(); // force class load and initialization + return true; + } catch (Throwable t) { // ensuring we really do catch everything + // Doug's Unsafe setup errors always have this "Could not ini.." message + if (isCausedBySecurityException(t)) { + return false; + } + throw (t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t)); + } + } + + private static boolean isCausedBySecurityException(Throwable t) { + while (t != null) { + if ((t.getMessage() != null && t.getMessage().contains("Could not initialize intrinsics")) || t instanceof SecurityException) { + return true; + } + t = t.getCause(); + } + return false; + } + + public JRubyMapBackend(Ruby runtime, RubyClass klass) { + super(runtime, klass); + } + + @JRubyMethod + public IRubyObject initialize(ThreadContext context) { + map = newCHM(); + return context.getRuntime().getNil(); + } + + @JRubyMethod + public IRubyObject initialize(ThreadContext context, IRubyObject options) { + map = toCHM(context, options); + return context.getRuntime().getNil(); + } + + private ConcurrentHashMap toCHM(ThreadContext context, IRubyObject options) { + Ruby runtime = context.getRuntime(); + if (!options.isNil() && options.respondsTo("[]")) { + IRubyObject rInitialCapacity = options.callMethod(context, "[]", runtime.newSymbol("initial_capacity")); + IRubyObject rLoadFactor = options.callMethod(context, "[]", runtime.newSymbol("load_factor")); + int initialCapacity = !rInitialCapacity.isNil() ? RubyNumeric.num2int(rInitialCapacity.convertToInteger()) : DEFAULT_INITIAL_CAPACITY; + float loadFactor = !rLoadFactor.isNil() ? (float)RubyNumeric.num2dbl(rLoadFactor.convertToFloat()) : DEFAULT_LOAD_FACTOR; + return newCHM(initialCapacity, loadFactor); + } else { + return newCHM(); + } + } + + @JRubyMethod(name = "[]", required = 1) + public IRubyObject op_aref(ThreadContext context, IRubyObject key) { + IRubyObject value; + return ((value = map.get(key)) == null) ? context.getRuntime().getNil() : value; + } + + @JRubyMethod(name = {"[]="}, required = 2) + public IRubyObject op_aset(IRubyObject key, IRubyObject value) { + map.put(key, value); + return value; + } + + @JRubyMethod + public IRubyObject put_if_absent(IRubyObject key, IRubyObject value) { + IRubyObject result = map.putIfAbsent(key, value); + return result == null ? getRuntime().getNil() : result; + } + + @JRubyMethod + public IRubyObject compute_if_absent(final ThreadContext context, final IRubyObject key, final Block block) { + return map.computeIfAbsent(key, new ConcurrentHashMap.Fun() { + @Override + public IRubyObject apply(IRubyObject key) { + return block.yieldSpecific(context); + } + }); + } + + @JRubyMethod + public IRubyObject compute_if_present(final ThreadContext context, final IRubyObject key, final Block block) { + IRubyObject result = map.computeIfPresent(key, new ConcurrentHashMap.BiFun() { + @Override + public IRubyObject apply(IRubyObject key, IRubyObject oldValue) { + IRubyObject result = block.yieldSpecific(context, oldValue == null ? context.getRuntime().getNil() : oldValue); + return result.isNil() ? null : result; + } + }); + return result == null ? context.getRuntime().getNil() : result; + } + + @JRubyMethod + public IRubyObject compute(final ThreadContext context, final IRubyObject key, final Block block) { + IRubyObject result = map.compute(key, new ConcurrentHashMap.BiFun() { + @Override + public IRubyObject apply(IRubyObject key, IRubyObject oldValue) { + IRubyObject result = block.yieldSpecific(context, oldValue == null ? context.getRuntime().getNil() : oldValue); + return result.isNil() ? null : result; + } + }); + return result == null ? context.getRuntime().getNil() : result; + } + + @JRubyMethod + public IRubyObject merge_pair(final ThreadContext context, final IRubyObject key, final IRubyObject value, final Block block) { + IRubyObject result = map.merge(key, value, new ConcurrentHashMap.BiFun() { + @Override + public IRubyObject apply(IRubyObject oldValue, IRubyObject newValue) { + IRubyObject result = block.yieldSpecific(context, oldValue == null ? context.getRuntime().getNil() : oldValue); + return result.isNil() ? null : result; + } + }); + return result == null ? context.getRuntime().getNil() : result; + } + + @JRubyMethod + public RubyBoolean replace_pair(IRubyObject key, IRubyObject oldValue, IRubyObject newValue) { + return getRuntime().newBoolean(map.replace(key, oldValue, newValue)); + } + + @JRubyMethod(name = "key?", required = 1) + public RubyBoolean has_key_p(IRubyObject key) { + return map.containsKey(key) ? getRuntime().getTrue() : getRuntime().getFalse(); + } + + @JRubyMethod + public IRubyObject key(IRubyObject value) { + final IRubyObject key = map.findKey(value); + return key == null ? getRuntime().getNil() : key; + } + + @JRubyMethod + public IRubyObject replace_if_exists(IRubyObject key, IRubyObject value) { + IRubyObject result = map.replace(key, value); + return result == null ? getRuntime().getNil() : result; + } + + @JRubyMethod + public IRubyObject get_and_set(IRubyObject key, IRubyObject value) { + IRubyObject result = map.put(key, value); + return result == null ? getRuntime().getNil() : result; + } + + @JRubyMethod + public IRubyObject delete(IRubyObject key) { + IRubyObject result = map.remove(key); + return result == null ? getRuntime().getNil() : result; + } + + @JRubyMethod + public RubyBoolean delete_pair(IRubyObject key, IRubyObject value) { + return getRuntime().newBoolean(map.remove(key, value)); + } + + @JRubyMethod + public IRubyObject clear() { + map.clear(); + return this; + } + + @JRubyMethod + public IRubyObject each_pair(ThreadContext context, Block block) { + for (Map.Entry entry : map.entrySet()) { + block.yieldSpecific(context, entry.getKey(), entry.getValue()); + } + return this; + } + + @JRubyMethod + public RubyFixnum size(ThreadContext context) { + return context.getRuntime().newFixnum(map.size()); + } + + @JRubyMethod + public IRubyObject get_or_default(IRubyObject key, IRubyObject defaultValue) { + return map.getValueOrDefault(key, defaultValue); + } + + @JRubyMethod(visibility = PRIVATE) + public JRubyMapBackend initialize_copy(ThreadContext context, IRubyObject other) { + map = newCHM(); + return this; + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicBooleanLibrary.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicBooleanLibrary.java new file mode 100644 index 00000000..b5660762 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicBooleanLibrary.java @@ -0,0 +1,93 @@ +package com.concurrent_ruby.ext; + +import org.jruby.Ruby; +import org.jruby.RubyBoolean; +import org.jruby.RubyClass; +import org.jruby.RubyModule; +import org.jruby.RubyNil; +import org.jruby.RubyObject; +import org.jruby.anno.JRubyClass; +import org.jruby.anno.JRubyMethod; +import org.jruby.runtime.ObjectAllocator; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.builtin.IRubyObject; +import org.jruby.runtime.load.Library; + +import java.io.IOException; +import java.util.concurrent.atomic.AtomicBoolean; + +public class JavaAtomicBooleanLibrary implements Library { + + public void load(Ruby runtime, boolean wrap) throws IOException { + RubyModule concurrentMod = runtime.defineModule("Concurrent"); + RubyClass atomicCls = concurrentMod.defineClassUnder("JavaAtomicBoolean", runtime.getObject(), JRUBYREFERENCE_ALLOCATOR); + atomicCls.defineAnnotatedMethods(JavaAtomicBoolean.class); + } + + private static final ObjectAllocator JRUBYREFERENCE_ALLOCATOR = new ObjectAllocator() { + public IRubyObject allocate(Ruby runtime, RubyClass klazz) { + return new JavaAtomicBoolean(runtime, klazz); + } + }; + + @JRubyClass(name = "JavaAtomicBoolean", parent = "Object") + public static class JavaAtomicBoolean extends RubyObject { + + private AtomicBoolean atomicBoolean; + + public JavaAtomicBoolean(Ruby runtime, RubyClass metaClass) { + super(runtime, metaClass); + } + + @JRubyMethod + public IRubyObject initialize(ThreadContext context, IRubyObject value) { + atomicBoolean = new AtomicBoolean(convertRubyBooleanToJavaBoolean(value)); + return context.nil; + } + + @JRubyMethod + public IRubyObject initialize(ThreadContext context) { + atomicBoolean = new AtomicBoolean(); + return context.nil; + } + + @JRubyMethod(name = "value") + public IRubyObject value() { + return getRuntime().newBoolean(atomicBoolean.get()); + } + + @JRubyMethod(name = "true?") + public IRubyObject isAtomicTrue() { + return getRuntime().newBoolean(atomicBoolean.get()); + } + + @JRubyMethod(name = "false?") + public IRubyObject isAtomicFalse() { + return getRuntime().newBoolean((atomicBoolean.get() == false)); + } + + @JRubyMethod(name = "value=") + public IRubyObject setAtomic(ThreadContext context, IRubyObject newValue) { + atomicBoolean.set(convertRubyBooleanToJavaBoolean(newValue)); + return context.nil; + } + + @JRubyMethod(name = "make_true") + public IRubyObject makeTrue() { + return getRuntime().newBoolean(atomicBoolean.compareAndSet(false, true)); + } + + @JRubyMethod(name = "make_false") + public IRubyObject makeFalse() { + return getRuntime().newBoolean(atomicBoolean.compareAndSet(true, false)); + } + + private boolean convertRubyBooleanToJavaBoolean(IRubyObject newValue) { + if (newValue instanceof RubyBoolean.False || newValue instanceof RubyNil) { + return false; + } else { + return true; + } + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicFixnumLibrary.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicFixnumLibrary.java new file mode 100644 index 00000000..672bfc04 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaAtomicFixnumLibrary.java @@ -0,0 +1,113 @@ +package com.concurrent_ruby.ext; + +import java.io.IOException; +import java.util.concurrent.atomic.AtomicLong; +import org.jruby.Ruby; +import org.jruby.RubyClass; +import org.jruby.RubyFixnum; +import org.jruby.RubyModule; +import org.jruby.RubyObject; +import org.jruby.anno.JRubyClass; +import org.jruby.anno.JRubyMethod; +import org.jruby.runtime.ObjectAllocator; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.builtin.IRubyObject; +import org.jruby.runtime.load.Library; +import org.jruby.runtime.Block; + +public class JavaAtomicFixnumLibrary implements Library { + + public void load(Ruby runtime, boolean wrap) throws IOException { + RubyModule concurrentMod = runtime.defineModule("Concurrent"); + RubyClass atomicCls = concurrentMod.defineClassUnder("JavaAtomicFixnum", runtime.getObject(), JRUBYREFERENCE_ALLOCATOR); + + atomicCls.defineAnnotatedMethods(JavaAtomicFixnum.class); + } + + private static final ObjectAllocator JRUBYREFERENCE_ALLOCATOR = new ObjectAllocator() { + public IRubyObject allocate(Ruby runtime, RubyClass klazz) { + return new JavaAtomicFixnum(runtime, klazz); + } + }; + + @JRubyClass(name = "JavaAtomicFixnum", parent = "Object") + public static class JavaAtomicFixnum extends RubyObject { + + private AtomicLong atomicLong; + + public JavaAtomicFixnum(Ruby runtime, RubyClass metaClass) { + super(runtime, metaClass); + } + + @JRubyMethod + public IRubyObject initialize(ThreadContext context) { + this.atomicLong = new AtomicLong(0); + return context.nil; + } + + @JRubyMethod + public IRubyObject initialize(ThreadContext context, IRubyObject value) { + this.atomicLong = new AtomicLong(rubyFixnumToLong(value)); + return context.nil; + } + + @JRubyMethod(name = "value") + public IRubyObject getValue() { + return getRuntime().newFixnum(atomicLong.get()); + } + + @JRubyMethod(name = "value=") + public IRubyObject setValue(ThreadContext context, IRubyObject newValue) { + atomicLong.set(rubyFixnumToLong(newValue)); + return context.nil; + } + + @JRubyMethod(name = {"increment", "up"}) + public IRubyObject increment() { + return getRuntime().newFixnum(atomicLong.incrementAndGet()); + } + + @JRubyMethod(name = {"increment", "up"}) + public IRubyObject increment(IRubyObject value) { + long delta = rubyFixnumToLong(value); + return getRuntime().newFixnum(atomicLong.addAndGet(delta)); + } + + @JRubyMethod(name = {"decrement", "down"}) + public IRubyObject decrement() { + return getRuntime().newFixnum(atomicLong.decrementAndGet()); + } + + @JRubyMethod(name = {"decrement", "down"}) + public IRubyObject decrement(IRubyObject value) { + long delta = rubyFixnumToLong(value); + return getRuntime().newFixnum(atomicLong.addAndGet(-delta)); + } + + @JRubyMethod(name = "compare_and_set") + public IRubyObject compareAndSet(ThreadContext context, IRubyObject expect, IRubyObject update) { + return getRuntime().newBoolean(atomicLong.compareAndSet(rubyFixnumToLong(expect), rubyFixnumToLong(update))); + } + + @JRubyMethod + public IRubyObject update(ThreadContext context, Block block) { + for (;;) { + long _oldValue = atomicLong.get(); + IRubyObject oldValue = getRuntime().newFixnum(_oldValue); + IRubyObject newValue = block.yield(context, oldValue); + if (atomicLong.compareAndSet(_oldValue, rubyFixnumToLong(newValue))) { + return newValue; + } + } + } + + private long rubyFixnumToLong(IRubyObject value) { + if (value instanceof RubyFixnum) { + RubyFixnum fixNum = (RubyFixnum) value; + return fixNum.getLongValue(); + } else { + throw getRuntime().newArgumentError("value must be a Fixnum"); + } + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaSemaphoreLibrary.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaSemaphoreLibrary.java new file mode 100644 index 00000000..d887f250 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/JavaSemaphoreLibrary.java @@ -0,0 +1,189 @@ +package com.concurrent_ruby.ext; + +import java.io.IOException; +import java.util.concurrent.Semaphore; +import org.jruby.Ruby; +import org.jruby.RubyClass; +import org.jruby.RubyFixnum; +import org.jruby.RubyModule; +import org.jruby.RubyNumeric; +import org.jruby.RubyObject; +import org.jruby.anno.JRubyClass; +import org.jruby.anno.JRubyMethod; +import org.jruby.runtime.Block; +import org.jruby.runtime.ObjectAllocator; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.builtin.IRubyObject; + +public class JavaSemaphoreLibrary { + + public void load(Ruby runtime, boolean wrap) throws IOException { + RubyModule concurrentMod = runtime.defineModule("Concurrent"); + RubyClass atomicCls = concurrentMod.defineClassUnder("JavaSemaphore", runtime.getObject(), JRUBYREFERENCE_ALLOCATOR); + + atomicCls.defineAnnotatedMethods(JavaSemaphore.class); + } + + private static final ObjectAllocator JRUBYREFERENCE_ALLOCATOR = new ObjectAllocator() { + public IRubyObject allocate(Ruby runtime, RubyClass klazz) { + return new JavaSemaphore(runtime, klazz); + } + }; + + @JRubyClass(name = "JavaSemaphore", parent = "Object") + public static class JavaSemaphore extends RubyObject { + + private JRubySemaphore semaphore; + + public JavaSemaphore(Ruby runtime, RubyClass metaClass) { + super(runtime, metaClass); + } + + @JRubyMethod + public IRubyObject initialize(ThreadContext context, IRubyObject value) { + this.semaphore = new JRubySemaphore(rubyFixnumInt(value, "count")); + return context.nil; + } + + @JRubyMethod + public IRubyObject acquire(ThreadContext context, final Block block) throws InterruptedException { + return this.acquire(context, 1, block); + } + + @JRubyMethod + public IRubyObject acquire(ThreadContext context, IRubyObject permits, final Block block) throws InterruptedException { + return this.acquire(context, rubyFixnumToPositiveInt(permits, "permits"), block); + } + + @JRubyMethod(name = "available_permits") + public IRubyObject availablePermits(ThreadContext context) { + return getRuntime().newFixnum(this.semaphore.availablePermits()); + } + + @JRubyMethod(name = "drain_permits") + public IRubyObject drainPermits(ThreadContext context) { + return getRuntime().newFixnum(this.semaphore.drainPermits()); + } + + @JRubyMethod(name = "try_acquire") + public IRubyObject tryAcquire(ThreadContext context, final Block block) throws InterruptedException { + int permitsInt = 1; + boolean acquired = semaphore.tryAcquire(permitsInt); + + return triedAcquire(context, permitsInt, acquired, block); + } + + @JRubyMethod(name = "try_acquire") + public IRubyObject tryAcquire(ThreadContext context, IRubyObject permits, final Block block) throws InterruptedException { + int permitsInt = rubyFixnumToPositiveInt(permits, "permits"); + boolean acquired = semaphore.tryAcquire(permitsInt); + + return triedAcquire(context, permitsInt, acquired, block); + } + + @JRubyMethod(name = "try_acquire") + public IRubyObject tryAcquire(ThreadContext context, IRubyObject permits, IRubyObject timeout, final Block block) throws InterruptedException { + int permitsInt = rubyFixnumToPositiveInt(permits, "permits"); + boolean acquired = semaphore.tryAcquire( + permitsInt, + rubyNumericToLong(timeout, "timeout"), + java.util.concurrent.TimeUnit.SECONDS + ); + + return triedAcquire(context, permitsInt, acquired, block); + } + + @JRubyMethod + public IRubyObject release(ThreadContext context) { + this.semaphore.release(1); + return getRuntime().newBoolean(true); + } + + @JRubyMethod + public IRubyObject release(ThreadContext context, IRubyObject permits) { + this.semaphore.release(rubyFixnumToPositiveInt(permits, "permits")); + return getRuntime().newBoolean(true); + } + + @JRubyMethod(name = "reduce_permits") + public IRubyObject reducePermits(ThreadContext context, IRubyObject reduction) throws InterruptedException { + this.semaphore.publicReducePermits(rubyFixnumToNonNegativeInt(reduction, "reduction")); + return context.nil; + } + + private IRubyObject acquire(ThreadContext context, int permits, final Block block) throws InterruptedException { + this.semaphore.acquire(permits); + + if (!block.isGiven()) return context.nil; + + try { + return block.yieldSpecific(context); + } finally { + this.semaphore.release(permits); + } + } + + private IRubyObject triedAcquire(ThreadContext context, int permits, boolean acquired, final Block block) { + if (!block.isGiven()) return getRuntime().newBoolean(acquired); + if (!acquired) return context.nil; + + try { + return block.yieldSpecific(context); + } finally { + this.semaphore.release(permits); + } + } + + private int rubyFixnumInt(IRubyObject value, String paramName) { + if (value instanceof RubyFixnum) { + RubyFixnum fixNum = (RubyFixnum) value; + return (int) fixNum.getLongValue(); + } else { + throw getRuntime().newArgumentError(paramName + " must be integer"); + } + } + + private int rubyFixnumToNonNegativeInt(IRubyObject value, String paramName) { + if (value instanceof RubyFixnum && ((RubyFixnum) value).getLongValue() >= 0) { + RubyFixnum fixNum = (RubyFixnum) value; + return (int) fixNum.getLongValue(); + } else { + throw getRuntime().newArgumentError(paramName + " must be a non-negative integer"); + } + } + + private int rubyFixnumToPositiveInt(IRubyObject value, String paramName) { + if (value instanceof RubyFixnum && ((RubyFixnum) value).getLongValue() > 0) { + RubyFixnum fixNum = (RubyFixnum) value; + return (int) fixNum.getLongValue(); + } else { + throw getRuntime().newArgumentError(paramName + " must be an integer greater than zero"); + } + } + + private long rubyNumericToLong(IRubyObject value, String paramName) { + if (value instanceof RubyNumeric && ((RubyNumeric) value).getDoubleValue() > 0) { + RubyNumeric fixNum = (RubyNumeric) value; + return fixNum.getLongValue(); + } else { + throw getRuntime().newArgumentError(paramName + " must be a float greater than zero"); + } + } + + class JRubySemaphore extends Semaphore { + + public JRubySemaphore(int permits) { + super(permits); + } + + public JRubySemaphore(int permits, boolean value) { + super(permits, value); + } + + public void publicReducePermits(int i) { + reducePermits(i); + } + + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java new file mode 100644 index 00000000..f0c75ee4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/SynchronizationLibrary.java @@ -0,0 +1,292 @@ +package com.concurrent_ruby.ext; + +import org.jruby.Ruby; +import org.jruby.RubyBasicObject; +import org.jruby.RubyClass; +import org.jruby.RubyModule; +import org.jruby.RubyObject; +import org.jruby.RubyThread; +import org.jruby.anno.JRubyClass; +import org.jruby.anno.JRubyMethod; +import org.jruby.runtime.Block; +import org.jruby.runtime.ObjectAllocator; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.Visibility; +import org.jruby.runtime.builtin.IRubyObject; +import org.jruby.runtime.load.Library; +import sun.misc.Unsafe; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +public class SynchronizationLibrary implements Library { + + private static final Unsafe UNSAFE = loadUnsafe(); + private static final boolean FULL_FENCE = supportsFences(); + + private static Unsafe loadUnsafe() { + try { + Class ncdfe = Class.forName("sun.misc.Unsafe"); + Field f = ncdfe.getDeclaredField("theUnsafe"); + f.setAccessible(true); + return (Unsafe) f.get((java.lang.Object) null); + } catch (Exception var2) { + return null; + } catch (NoClassDefFoundError var3) { + return null; + } + } + + private static boolean supportsFences() { + if (UNSAFE == null) { + return false; + } else { + try { + Method m = UNSAFE.getClass().getDeclaredMethod("fullFence", new Class[0]); + if (m != null) { + return true; + } + } catch (Exception var1) { + // nothing + } + + return false; + } + } + + private static final ObjectAllocator OBJECT_ALLOCATOR = new ObjectAllocator() { + public IRubyObject allocate(Ruby runtime, RubyClass klazz) { + return new Object(runtime, klazz); + } + }; + + private static final ObjectAllocator ABSTRACT_LOCKABLE_OBJECT_ALLOCATOR = new ObjectAllocator() { + public IRubyObject allocate(Ruby runtime, RubyClass klazz) { + return new AbstractLockableObject(runtime, klazz); + } + }; + + private static final ObjectAllocator JRUBY_LOCKABLE_OBJECT_ALLOCATOR = new ObjectAllocator() { + public IRubyObject allocate(Ruby runtime, RubyClass klazz) { + return new JRubyLockableObject(runtime, klazz); + } + }; + + public void load(Ruby runtime, boolean wrap) throws IOException { + RubyModule synchronizationModule = runtime. + defineModule("Concurrent"). + defineModuleUnder("Synchronization"); + + RubyModule jrubyAttrVolatileModule = synchronizationModule.defineModuleUnder("JRubyAttrVolatile"); + jrubyAttrVolatileModule.defineAnnotatedMethods(JRubyAttrVolatile.class); + + defineClass(runtime, synchronizationModule, "AbstractObject", "Object", + Object.class, OBJECT_ALLOCATOR); + + defineClass(runtime, synchronizationModule, "Object", "AbstractLockableObject", + AbstractLockableObject.class, ABSTRACT_LOCKABLE_OBJECT_ALLOCATOR); + + defineClass(runtime, synchronizationModule, "AbstractLockableObject", "JRubyLockableObject", + JRubyLockableObject.class, JRUBY_LOCKABLE_OBJECT_ALLOCATOR); + + defineClass(runtime, synchronizationModule, "Object", "JRuby", + JRuby.class, new ObjectAllocator() { + @Override + public IRubyObject allocate(Ruby runtime, RubyClass klazz) { + return new JRuby(runtime, klazz); + } + }); + } + + private RubyClass defineClass( + Ruby runtime, + RubyModule namespace, + String parentName, + String name, + Class javaImplementation, + ObjectAllocator allocator) { + final RubyClass parentClass = namespace.getClass(parentName); + + if (parentClass == null) { + System.out.println("not found " + parentName); + throw runtime.newRuntimeError(namespace.toString() + "::" + parentName + " is missing"); + } + + final RubyClass newClass = namespace.defineClassUnder(name, parentClass, allocator); + newClass.defineAnnotatedMethods(javaImplementation); + return newClass; + } + + // Facts: + // - all ivar reads are without any synchronisation of fences see + // https://github.com/jruby/jruby/blob/master/core/src/main/java/org/jruby/runtime/ivars/VariableAccessor.java#L110-110 + // - writes depend on UnsafeHolder.U, null -> SynchronizedVariableAccessor, !null -> StampedVariableAccessor + // SynchronizedVariableAccessor wraps with synchronized block, StampedVariableAccessor uses fullFence or + // volatilePut + // TODO (pitr 16-Sep-2015): what do we do in Java 9 ? + + // module JRubyAttrVolatile + public static class JRubyAttrVolatile { + + // volatile threadContext is used as a memory barrier per the JVM memory model happens-before semantic + // on volatile fields. any volatile field could have been used but using the thread context is an + // attempt to avoid code elimination. + private static volatile int volatileField; + + @JRubyMethod(name = "full_memory_barrier", visibility = Visibility.PUBLIC, module = true) + public static IRubyObject fullMemoryBarrier(ThreadContext context, IRubyObject module) { + // Prevent reordering of ivar writes with publication of this instance + if (!FULL_FENCE) { + // Assuming that following volatile read and write is not eliminated it simulates fullFence. + // If it's eliminated it'll cause problems only on non-x86 platforms. + // http://shipilev.net/blog/2014/jmm-pragmatics/#_happens_before_test_your_understanding + final int volatileRead = volatileField; + volatileField = context.getLine(); + } else { + UNSAFE.fullFence(); + } + return context.nil; + } + + @JRubyMethod(name = "instance_variable_get_volatile", visibility = Visibility.PUBLIC, module = true) + public static IRubyObject instanceVariableGetVolatile( + ThreadContext context, + IRubyObject module, + IRubyObject self, + IRubyObject name) { + // Ensure we ses latest value with loadFence + if (!FULL_FENCE) { + // piggybacking on volatile read, simulating loadFence + final int volatileRead = volatileField; + return ((RubyBasicObject) self).instance_variable_get(context, name); + } else { + UNSAFE.loadFence(); + return ((RubyBasicObject) self).instance_variable_get(context, name); + } + } + + @JRubyMethod(name = "instance_variable_set_volatile", visibility = Visibility.PUBLIC, module = true) + public static IRubyObject InstanceVariableSetVolatile( + ThreadContext context, + IRubyObject module, + IRubyObject self, + IRubyObject name, + IRubyObject value) { + // Ensure we make last update visible + if (!FULL_FENCE) { + // piggybacking on volatile write, simulating storeFence + final IRubyObject result = ((RubyBasicObject) self).instance_variable_set(name, value); + volatileField = context.getLine(); + return result; + } else { + // JRuby uses StampedVariableAccessor which calls fullFence + // so no additional steps needed. + // See https://github.com/jruby/jruby/blob/master/core/src/main/java/org/jruby/runtime/ivars/StampedVariableAccessor.java#L151-L159 + return ((RubyBasicObject) self).instance_variable_set(name, value); + } + } + } + + @JRubyClass(name = "Object", parent = "AbstractObject") + public static class Object extends RubyObject { + + public Object(Ruby runtime, RubyClass metaClass) { + super(runtime, metaClass); + } + } + + @JRubyClass(name = "AbstractLockableObject", parent = "Object") + public static class AbstractLockableObject extends Object { + + public AbstractLockableObject(Ruby runtime, RubyClass metaClass) { + super(runtime, metaClass); + } + } + + @JRubyClass(name = "JRubyLockableObject", parent = "AbstractLockableObject") + public static class JRubyLockableObject extends AbstractLockableObject { + + public JRubyLockableObject(Ruby runtime, RubyClass metaClass) { + super(runtime, metaClass); + } + + @JRubyMethod(name = "synchronize", visibility = Visibility.PROTECTED) + public IRubyObject rubySynchronize(ThreadContext context, Block block) { + synchronized (this) { + return block.yield(context, null); + } + } + + @JRubyMethod(name = "ns_wait", optional = 1, visibility = Visibility.PROTECTED) + public IRubyObject nsWait(ThreadContext context, IRubyObject[] args) { + Ruby runtime = context.runtime; + if (args.length > 1) { + throw runtime.newArgumentError(args.length, 1); + } + Double timeout = null; + if (args.length > 0 && !args[0].isNil()) { + timeout = args[0].convertToFloat().getDoubleValue(); + if (timeout < 0) { + throw runtime.newArgumentError("time interval must be positive"); + } + } + if (Thread.interrupted()) { + throw runtime.newConcurrencyError("thread interrupted"); + } + boolean success = false; + try { + success = context.getThread().wait_timeout(this, timeout); + } catch (InterruptedException ie) { + throw runtime.newConcurrencyError(ie.getLocalizedMessage()); + } finally { + // An interrupt or timeout may have caused us to miss + // a notify that we consumed, so do another notify in + // case someone else is available to pick it up. + if (!success) { + this.notify(); + } + } + return this; + } + + @JRubyMethod(name = "ns_signal", visibility = Visibility.PROTECTED) + public IRubyObject nsSignal(ThreadContext context) { + notify(); + return this; + } + + @JRubyMethod(name = "ns_broadcast", visibility = Visibility.PROTECTED) + public IRubyObject nsBroadcast(ThreadContext context) { + notifyAll(); + return this; + } + } + + @JRubyClass(name = "JRuby") + public static class JRuby extends RubyObject { + public JRuby(Ruby runtime, RubyClass metaClass) { + super(runtime, metaClass); + } + + @JRubyMethod(name = "sleep_interruptibly", visibility = Visibility.PUBLIC, module = true) + public static IRubyObject sleepInterruptibly(final ThreadContext context, IRubyObject receiver, final Block block) { + try { + context.getThread().executeBlockingTask(new RubyThread.BlockingTask() { + @Override + public void run() throws InterruptedException { + block.call(context); + } + + @Override + public void wakeup() { + context.getThread().getNativeThread().interrupt(); + } + }); + } catch (InterruptedException e) { + throw context.runtime.newThreadError("interrupted in Concurrent::Synchronization::JRuby.sleep_interruptibly"); + } + return context.nil; + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMap.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMap.java new file mode 100644 index 00000000..e11e15aa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMap.java @@ -0,0 +1,31 @@ +package com.concurrent_ruby.ext.jsr166e; + +import java.util.Map; +import java.util.Set; + +public interface ConcurrentHashMap { + /** Interface describing a function of one argument */ + public interface Fun { T apply(A a); } + /** Interface describing a function of two arguments */ + public interface BiFun { T apply(A a, B b); } + + public V get(K key); + public V put(K key, V value); + public V putIfAbsent(K key, V value); + public V computeIfAbsent(K key, Fun mf); + public V computeIfPresent(K key, BiFun mf); + public V compute(K key, BiFun mf); + public V merge(K key, V value, BiFun mf); + public boolean replace(K key, V oldVal, V newVal); + public V replace(K key, V value); + public boolean containsKey(K key); + public boolean remove(Object key, Object value); + public V remove(K key); + public void clear(); + public Set> entrySet(); + public int size(); + public V getValueOrDefault(Object key, V defaultValue); + + public boolean containsValue(V value); + public K findKey(V value); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMapV8.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMapV8.java new file mode 100644 index 00000000..dc9901fb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/ConcurrentHashMapV8.java @@ -0,0 +1,3863 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// This is based on the 1.79 version. + +package com.concurrent_ruby.ext.jsr166e; + +import org.jruby.RubyClass; +import org.jruby.RubyNumeric; +import org.jruby.RubyObject; +import org.jruby.exceptions.RaiseException; +import com.concurrent_ruby.ext.jsr166y.ThreadLocalRandom; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.builtin.IRubyObject; + +import java.util.Arrays; +import java.util.Map; +import java.util.Set; +import java.util.Collection; +import java.util.Hashtable; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Enumeration; +import java.util.ConcurrentModificationException; +import java.util.NoSuchElementException; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.locks.AbstractQueuedSynchronizer; + +import java.io.Serializable; + +/** + * A hash table supporting full concurrency of retrievals and + * high expected concurrency for updates. This class obeys the + * same functional specification as {@link java.util.Hashtable}, and + * includes versions of methods corresponding to each method of + * {@code Hashtable}. However, even though all operations are + * thread-safe, retrieval operations do not entail locking, + * and there is not any support for locking the entire table + * in a way that prevents all access. This class is fully + * interoperable with {@code Hashtable} in programs that rely on its + * thread safety but not on its synchronization details. + * + *

Retrieval operations (including {@code get}) generally do not + * block, so may overlap with update operations (including {@code put} + * and {@code remove}). Retrievals reflect the results of the most + * recently completed update operations holding upon their + * onset. (More formally, an update operation for a given key bears a + * happens-before relation with any (non-null) retrieval for + * that key reporting the updated value.) For aggregate operations + * such as {@code putAll} and {@code clear}, concurrent retrievals may + * reflect insertion or removal of only some entries. Similarly, + * Iterators and Enumerations return elements reflecting the state of + * the hash table at some point at or since the creation of the + * iterator/enumeration. They do not throw {@link + * ConcurrentModificationException}. However, iterators are designed + * to be used by only one thread at a time. Bear in mind that the + * results of aggregate status methods including {@code size}, {@code + * isEmpty}, and {@code containsValue} are typically useful only when + * a map is not undergoing concurrent updates in other threads. + * Otherwise the results of these methods reflect transient states + * that may be adequate for monitoring or estimation purposes, but not + * for program control. + * + *

The table is dynamically expanded when there are too many + * collisions (i.e., keys that have distinct hash codes but fall into + * the same slot modulo the table size), with the expected average + * effect of maintaining roughly two bins per mapping (corresponding + * to a 0.75 load factor threshold for resizing). There may be much + * variance around this average as mappings are added and removed, but + * overall, this maintains a commonly accepted time/space tradeoff for + * hash tables. However, resizing this or any other kind of hash + * table may be a relatively slow operation. When possible, it is a + * good idea to provide a size estimate as an optional {@code + * initialCapacity} constructor argument. An additional optional + * {@code loadFactor} constructor argument provides a further means of + * customizing initial table capacity by specifying the table density + * to be used in calculating the amount of space to allocate for the + * given number of elements. Also, for compatibility with previous + * versions of this class, constructors may optionally specify an + * expected {@code concurrencyLevel} as an additional hint for + * internal sizing. Note that using many keys with exactly the same + * {@code hashCode()} is a sure way to slow down performance of any + * hash table. + * + *

A {@link Set} projection of a ConcurrentHashMapV8 may be created + * (using {@link #newKeySet()} or {@link #newKeySet(int)}), or viewed + * (using {@link #keySet(Object)} when only keys are of interest, and the + * mapped values are (perhaps transiently) not used or all take the + * same mapping value. + * + *

A ConcurrentHashMapV8 can be used as scalable frequency map (a + * form of histogram or multiset) by using {@link LongAdder} values + * and initializing via {@link #computeIfAbsent}. For example, to add + * a count to a {@code ConcurrentHashMapV8 freqs}, you + * can use {@code freqs.computeIfAbsent(k -> new + * LongAdder()).increment();} + * + *

This class and its views and iterators implement all of the + * optional methods of the {@link Map} and {@link Iterator} + * interfaces. + * + *

Like {@link Hashtable} but unlike {@link HashMap}, this class + * does not allow {@code null} to be used as a key or value. + * + *

ConcurrentHashMapV8s support parallel operations using the {@link + * ForkJoinPool#commonPool}. (Tasks that may be used in other contexts + * are available in class {@link ForkJoinTasks}). These operations are + * designed to be safely, and often sensibly, applied even with maps + * that are being concurrently updated by other threads; for example, + * when computing a snapshot summary of the values in a shared + * registry. There are three kinds of operation, each with four + * forms, accepting functions with Keys, Values, Entries, and (Key, + * Value) arguments and/or return values. (The first three forms are + * also available via the {@link #keySet()}, {@link #values()} and + * {@link #entrySet()} views). Because the elements of a + * ConcurrentHashMapV8 are not ordered in any particular way, and may be + * processed in different orders in different parallel executions, the + * correctness of supplied functions should not depend on any + * ordering, or on any other objects or values that may transiently + * change while computation is in progress; and except for forEach + * actions, should ideally be side-effect-free. + * + *

    + *
  • forEach: Perform a given action on each element. + * A variant form applies a given transformation on each element + * before performing the action.
  • + * + *
  • search: Return the first available non-null result of + * applying a given function on each element; skipping further + * search when a result is found.
  • + * + *
  • reduce: Accumulate each element. The supplied reduction + * function cannot rely on ordering (more formally, it should be + * both associative and commutative). There are five variants: + * + *
      + * + *
    • Plain reductions. (There is not a form of this method for + * (key, value) function arguments since there is no corresponding + * return type.)
    • + * + *
    • Mapped reductions that accumulate the results of a given + * function applied to each element.
    • + * + *
    • Reductions to scalar doubles, longs, and ints, using a + * given basis value.
    • + * + * + *
    + *
+ * + *

The concurrency properties of bulk operations follow + * from those of ConcurrentHashMapV8: Any non-null result returned + * from {@code get(key)} and related access methods bears a + * happens-before relation with the associated insertion or + * update. The result of any bulk operation reflects the + * composition of these per-element relations (but is not + * necessarily atomic with respect to the map as a whole unless it + * is somehow known to be quiescent). Conversely, because keys + * and values in the map are never null, null serves as a reliable + * atomic indicator of the current lack of any result. To + * maintain this property, null serves as an implicit basis for + * all non-scalar reduction operations. For the double, long, and + * int versions, the basis should be one that, when combined with + * any other value, returns that other value (more formally, it + * should be the identity element for the reduction). Most common + * reductions have these properties; for example, computing a sum + * with basis 0 or a minimum with basis MAX_VALUE. + * + *

Search and transformation functions provided as arguments + * should similarly return null to indicate the lack of any result + * (in which case it is not used). In the case of mapped + * reductions, this also enables transformations to serve as + * filters, returning null (or, in the case of primitive + * specializations, the identity basis) if the element should not + * be combined. You can create compound transformations and + * filterings by composing them yourself under this "null means + * there is nothing there now" rule before using them in search or + * reduce operations. + * + *

Methods accepting and/or returning Entry arguments maintain + * key-value associations. They may be useful for example when + * finding the key for the greatest value. Note that "plain" Entry + * arguments can be supplied using {@code new + * AbstractMap.SimpleEntry(k,v)}. + * + *

Bulk operations may complete abruptly, throwing an + * exception encountered in the application of a supplied + * function. Bear in mind when handling such exceptions that other + * concurrently executing functions could also have thrown + * exceptions, or would have done so if the first exception had + * not occurred. + * + *

Parallel speedups for bulk operations compared to sequential + * processing are common but not guaranteed. Operations involving + * brief functions on small maps may execute more slowly than + * sequential loops if the underlying work to parallelize the + * computation is more expensive than the computation itself. + * Similarly, parallelization may not lead to much actual parallelism + * if all processors are busy performing unrelated tasks. + * + *

All arguments to all task methods must be non-null. + * + *

jsr166e note: During transition, this class + * uses nested functional interfaces with different names but the + * same forms as those expected for JDK8. + * + *

This class is a member of the + * + * Java Collections Framework. + * + * @since 1.5 + * @author Doug Lea + * @param the type of keys maintained by this map + * @param the type of mapped values + */ +public class ConcurrentHashMapV8 + implements ConcurrentMap, Serializable, ConcurrentHashMap { + private static final long serialVersionUID = 7249069246763182397L; + + /** + * A partitionable iterator. A Spliterator can be traversed + * directly, but can also be partitioned (before traversal) by + * creating another Spliterator that covers a non-overlapping + * portion of the elements, and so may be amenable to parallel + * execution. + * + *

This interface exports a subset of expected JDK8 + * functionality. + * + *

Sample usage: Here is one (of the several) ways to compute + * the sum of the values held in a map using the ForkJoin + * framework. As illustrated here, Spliterators are well suited to + * designs in which a task repeatedly splits off half its work + * into forked subtasks until small enough to process directly, + * and then joins these subtasks. Variants of this style can also + * be used in completion-based designs. + * + *

+     * {@code ConcurrentHashMapV8 m = ...
+     * // split as if have 8 * parallelism, for load balance
+     * int n = m.size();
+     * int p = aForkJoinPool.getParallelism() * 8;
+     * int split = (n < p)? n : p;
+     * long sum = aForkJoinPool.invoke(new SumValues(m.valueSpliterator(), split, null));
+     * // ...
+     * static class SumValues extends RecursiveTask {
+     *   final Spliterator s;
+     *   final int split;             // split while > 1
+     *   final SumValues nextJoin;    // records forked subtasks to join
+     *   SumValues(Spliterator s, int depth, SumValues nextJoin) {
+     *     this.s = s; this.depth = depth; this.nextJoin = nextJoin;
+     *   }
+     *   public Long compute() {
+     *     long sum = 0;
+     *     SumValues subtasks = null; // fork subtasks
+     *     for (int s = split >>> 1; s > 0; s >>>= 1)
+     *       (subtasks = new SumValues(s.split(), s, subtasks)).fork();
+     *     while (s.hasNext())        // directly process remaining elements
+     *       sum += s.next();
+     *     for (SumValues t = subtasks; t != null; t = t.nextJoin)
+     *       sum += t.join();         // collect subtask results
+     *     return sum;
+     *   }
+     * }
+     * }
+ */ + public static interface Spliterator extends Iterator { + /** + * Returns a Spliterator covering approximately half of the + * elements, guaranteed not to overlap with those subsequently + * returned by this Spliterator. After invoking this method, + * the current Spliterator will not produce any of + * the elements of the returned Spliterator, but the two + * Spliterators together will produce all of the elements that + * would have been produced by this Spliterator had this + * method not been called. The exact number of elements + * produced by the returned Spliterator is not guaranteed, and + * may be zero (i.e., with {@code hasNext()} reporting {@code + * false}) if this Spliterator cannot be further split. + * + * @return a Spliterator covering approximately half of the + * elements + * @throws IllegalStateException if this Spliterator has + * already commenced traversing elements + */ + Spliterator split(); + } + + + /* + * Overview: + * + * The primary design goal of this hash table is to maintain + * concurrent readability (typically method get(), but also + * iterators and related methods) while minimizing update + * contention. Secondary goals are to keep space consumption about + * the same or better than java.util.HashMap, and to support high + * initial insertion rates on an empty table by many threads. + * + * Each key-value mapping is held in a Node. Because Node fields + * can contain special values, they are defined using plain Object + * types. Similarly in turn, all internal methods that use them + * work off Object types. And similarly, so do the internal + * methods of auxiliary iterator and view classes. All public + * generic typed methods relay in/out of these internal methods, + * supplying null-checks and casts as needed. This also allows + * many of the public methods to be factored into a smaller number + * of internal methods (although sadly not so for the five + * variants of put-related operations). The validation-based + * approach explained below leads to a lot of code sprawl because + * retry-control precludes factoring into smaller methods. + * + * The table is lazily initialized to a power-of-two size upon the + * first insertion. Each bin in the table normally contains a + * list of Nodes (most often, the list has only zero or one Node). + * Table accesses require volatile/atomic reads, writes, and + * CASes. Because there is no other way to arrange this without + * adding further indirections, we use intrinsics + * (sun.misc.Unsafe) operations. The lists of nodes within bins + * are always accurately traversable under volatile reads, so long + * as lookups check hash code and non-nullness of value before + * checking key equality. + * + * We use the top two bits of Node hash fields for control + * purposes -- they are available anyway because of addressing + * constraints. As explained further below, these top bits are + * used as follows: + * 00 - Normal + * 01 - Locked + * 11 - Locked and may have a thread waiting for lock + * 10 - Node is a forwarding node + * + * The lower 30 bits of each Node's hash field contain a + * transformation of the key's hash code, except for forwarding + * nodes, for which the lower bits are zero (and so always have + * hash field == MOVED). + * + * Insertion (via put or its variants) of the first node in an + * empty bin is performed by just CASing it to the bin. This is + * by far the most common case for put operations under most + * key/hash distributions. Other update operations (insert, + * delete, and replace) require locks. We do not want to waste + * the space required to associate a distinct lock object with + * each bin, so instead use the first node of a bin list itself as + * a lock. Blocking support for these locks relies on the builtin + * "synchronized" monitors. However, we also need a tryLock + * construction, so we overlay these by using bits of the Node + * hash field for lock control (see above), and so normally use + * builtin monitors only for blocking and signalling using + * wait/notifyAll constructions. See Node.tryAwaitLock. + * + * Using the first node of a list as a lock does not by itself + * suffice though: When a node is locked, any update must first + * validate that it is still the first node after locking it, and + * retry if not. Because new nodes are always appended to lists, + * once a node is first in a bin, it remains first until deleted + * or the bin becomes invalidated (upon resizing). However, + * operations that only conditionally update may inspect nodes + * until the point of update. This is a converse of sorts to the + * lazy locking technique described by Herlihy & Shavit. + * + * The main disadvantage of per-bin locks is that other update + * operations on other nodes in a bin list protected by the same + * lock can stall, for example when user equals() or mapping + * functions take a long time. However, statistically, under + * random hash codes, this is not a common problem. Ideally, the + * frequency of nodes in bins follows a Poisson distribution + * (http://en.wikipedia.org/wiki/Poisson_distribution) with a + * parameter of about 0.5 on average, given the resizing threshold + * of 0.75, although with a large variance because of resizing + * granularity. Ignoring variance, the expected occurrences of + * list size k are (exp(-0.5) * pow(0.5, k) / factorial(k)). The + * first values are: + * + * 0: 0.60653066 + * 1: 0.30326533 + * 2: 0.07581633 + * 3: 0.01263606 + * 4: 0.00157952 + * 5: 0.00015795 + * 6: 0.00001316 + * 7: 0.00000094 + * 8: 0.00000006 + * more: less than 1 in ten million + * + * Lock contention probability for two threads accessing distinct + * elements is roughly 1 / (8 * #elements) under random hashes. + * + * Actual hash code distributions encountered in practice + * sometimes deviate significantly from uniform randomness. This + * includes the case when N > (1<<30), so some keys MUST collide. + * Similarly for dumb or hostile usages in which multiple keys are + * designed to have identical hash codes. Also, although we guard + * against the worst effects of this (see method spread), sets of + * hashes may differ only in bits that do not impact their bin + * index for a given power-of-two mask. So we use a secondary + * strategy that applies when the number of nodes in a bin exceeds + * a threshold, and at least one of the keys implements + * Comparable. These TreeBins use a balanced tree to hold nodes + * (a specialized form of red-black trees), bounding search time + * to O(log N). Each search step in a TreeBin is around twice as + * slow as in a regular list, but given that N cannot exceed + * (1<<64) (before running out of addresses) this bounds search + * steps, lock hold times, etc, to reasonable constants (roughly + * 100 nodes inspected per operation worst case) so long as keys + * are Comparable (which is very common -- String, Long, etc). + * TreeBin nodes (TreeNodes) also maintain the same "next" + * traversal pointers as regular nodes, so can be traversed in + * iterators in the same way. + * + * The table is resized when occupancy exceeds a percentage + * threshold (nominally, 0.75, but see below). Only a single + * thread performs the resize (using field "sizeCtl", to arrange + * exclusion), but the table otherwise remains usable for reads + * and updates. Resizing proceeds by transferring bins, one by + * one, from the table to the next table. Because we are using + * power-of-two expansion, the elements from each bin must either + * stay at same index, or move with a power of two offset. We + * eliminate unnecessary node creation by catching cases where old + * nodes can be reused because their next fields won't change. On + * average, only about one-sixth of them need cloning when a table + * doubles. The nodes they replace will be garbage collectable as + * soon as they are no longer referenced by any reader thread that + * may be in the midst of concurrently traversing table. Upon + * transfer, the old table bin contains only a special forwarding + * node (with hash field "MOVED") that contains the next table as + * its key. On encountering a forwarding node, access and update + * operations restart, using the new table. + * + * Each bin transfer requires its bin lock. However, unlike other + * cases, a transfer can skip a bin if it fails to acquire its + * lock, and revisit it later (unless it is a TreeBin). Method + * rebuild maintains a buffer of TRANSFER_BUFFER_SIZE bins that + * have been skipped because of failure to acquire a lock, and + * blocks only if none are available (i.e., only very rarely). + * The transfer operation must also ensure that all accessible + * bins in both the old and new table are usable by any traversal. + * When there are no lock acquisition failures, this is arranged + * simply by proceeding from the last bin (table.length - 1) up + * towards the first. Upon seeing a forwarding node, traversals + * (see class Iter) arrange to move to the new table + * without revisiting nodes. However, when any node is skipped + * during a transfer, all earlier table bins may have become + * visible, so are initialized with a reverse-forwarding node back + * to the old table until the new ones are established. (This + * sometimes requires transiently locking a forwarding node, which + * is possible under the above encoding.) These more expensive + * mechanics trigger only when necessary. + * + * The traversal scheme also applies to partial traversals of + * ranges of bins (via an alternate Traverser constructor) + * to support partitioned aggregate operations. Also, read-only + * operations give up if ever forwarded to a null table, which + * provides support for shutdown-style clearing, which is also not + * currently implemented. + * + * Lazy table initialization minimizes footprint until first use, + * and also avoids resizings when the first operation is from a + * putAll, constructor with map argument, or deserialization. + * These cases attempt to override the initial capacity settings, + * but harmlessly fail to take effect in cases of races. + * + * The element count is maintained using a LongAdder, which avoids + * contention on updates but can encounter cache thrashing if read + * too frequently during concurrent access. To avoid reading so + * often, resizing is attempted either when a bin lock is + * contended, or upon adding to a bin already holding two or more + * nodes (checked before adding in the xIfAbsent methods, after + * adding in others). Under uniform hash distributions, the + * probability of this occurring at threshold is around 13%, + * meaning that only about 1 in 8 puts check threshold (and after + * resizing, many fewer do so). But this approximation has high + * variance for small table sizes, so we check on any collision + * for sizes <= 64. The bulk putAll operation further reduces + * contention by only committing count updates upon these size + * checks. + * + * Maintaining API and serialization compatibility with previous + * versions of this class introduces several oddities. Mainly: We + * leave untouched but unused constructor arguments referring to + * concurrencyLevel. We accept a loadFactor constructor argument, + * but apply it only to initial table capacity (which is the only + * time that we can guarantee to honor it.) We also declare an + * unused "Segment" class that is instantiated in minimal form + * only when serializing. + */ + + /* ---------------- Constants -------------- */ + + /** + * The largest possible table capacity. This value must be + * exactly 1<<30 to stay within Java array allocation and indexing + * bounds for power of two table sizes, and is further required + * because the top two bits of 32bit hash fields are used for + * control purposes. + */ + private static final int MAXIMUM_CAPACITY = 1 << 30; + + /** + * The default initial table capacity. Must be a power of 2 + * (i.e., at least 1) and at most MAXIMUM_CAPACITY. + */ + private static final int DEFAULT_CAPACITY = 16; + + /** + * The largest possible (non-power of two) array size. + * Needed by toArray and related methods. + */ + static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; + + /** + * The default concurrency level for this table. Unused but + * defined for compatibility with previous versions of this class. + */ + private static final int DEFAULT_CONCURRENCY_LEVEL = 16; + + /** + * The load factor for this table. Overrides of this value in + * constructors affect only the initial table capacity. The + * actual floating point value isn't normally used -- it is + * simpler to use expressions such as {@code n - (n >>> 2)} for + * the associated resizing threshold. + */ + private static final float LOAD_FACTOR = 0.75f; + + /** + * The buffer size for skipped bins during transfers. The + * value is arbitrary but should be large enough to avoid + * most locking stalls during resizes. + */ + private static final int TRANSFER_BUFFER_SIZE = 32; + + /** + * The bin count threshold for using a tree rather than list for a + * bin. The value reflects the approximate break-even point for + * using tree-based operations. + * Note that Doug's version defaults to 8, but when dealing with + * Ruby objects it is actually beneficial to avoid TreeNodes + * as long as possible as it usually means going into Ruby land. + */ + private static final int TREE_THRESHOLD = 16; + + /* + * Encodings for special uses of Node hash fields. See above for + * explanation. + */ + static final int MOVED = 0x80000000; // hash field for forwarding nodes + static final int LOCKED = 0x40000000; // set/tested only as a bit + static final int WAITING = 0xc0000000; // both bits set/tested together + static final int HASH_BITS = 0x3fffffff; // usable bits of normal node hash + + /* ---------------- Fields -------------- */ + + /** + * The array of bins. Lazily initialized upon first insertion. + * Size is always a power of two. Accessed directly by iterators. + */ + transient volatile Node[] table; + + /** + * The counter maintaining number of elements. + */ + private transient final LongAdder counter; + + /** + * Table initialization and resizing control. When negative, the + * table is being initialized or resized. Otherwise, when table is + * null, holds the initial table size to use upon creation, or 0 + * for default. After initialization, holds the next element count + * value upon which to resize the table. + */ + private transient volatile int sizeCtl; + + // views + private transient KeySetView keySet; + private transient ValuesView values; + private transient EntrySetView entrySet; + + /** For serialization compatibility. Null unless serialized; see below */ + private Segment[] segments; + + /* ---------------- Table element access -------------- */ + + /* + * Volatile access methods are used for table elements as well as + * elements of in-progress next table while resizing. Uses are + * null checked by callers, and implicitly bounds-checked, relying + * on the invariants that tab arrays have non-zero size, and all + * indices are masked with (tab.length - 1) which is never + * negative and always less than length. Note that, to be correct + * wrt arbitrary concurrency errors by users, bounds checks must + * operate on local variables, which accounts for some odd-looking + * inline assignments below. + */ + + static final Node tabAt(Node[] tab, int i) { // used by Iter + return (Node)UNSAFE.getObjectVolatile(tab, ((long)i< 1 ? 64 : 1; + + /** + * Spins a while if LOCKED bit set and this node is the first + * of its bin, and then sets WAITING bits on hash field and + * blocks (once) if they are still set. It is OK for this + * method to return even if lock is not available upon exit, + * which enables these simple single-wait mechanics. + * + * The corresponding signalling operation is performed within + * callers: Upon detecting that WAITING has been set when + * unlocking lock (via a failed CAS from non-waiting LOCKED + * state), unlockers acquire the sync lock and perform a + * notifyAll. + * + * The initial sanity check on tab and bounds is not currently + * necessary in the only usages of this method, but enables + * use in other future contexts. + */ + final void tryAwaitLock(Node[] tab, int i) { + if (tab != null && i >= 0 && i < tab.length) { // sanity check + int r = ThreadLocalRandom.current().nextInt(); // randomize spins + int spins = MAX_SPINS, h; + while (tabAt(tab, i) == this && ((h = hash) & LOCKED) != 0) { + if (spins >= 0) { + r ^= r << 1; r ^= r >>> 3; r ^= r << 10; // xorshift + if (r >= 0 && --spins == 0) + Thread.yield(); // yield before block + } + else if (casHash(h, h | WAITING)) { + synchronized (this) { + if (tabAt(tab, i) == this && + (hash & WAITING) == WAITING) { + try { + wait(); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + } + } + else + notifyAll(); // possibly won race vs signaller + } + break; + } + } + } + } + + // Unsafe mechanics for casHash + private static final sun.misc.Unsafe UNSAFE; + private static final long hashOffset; + + static { + try { + UNSAFE = getUnsafe(); + Class k = Node.class; + hashOffset = UNSAFE.objectFieldOffset + (k.getDeclaredField("hash")); + } catch (Exception e) { + throw new Error(e); + } + } + } + + /* ---------------- TreeBins -------------- */ + + /** + * Nodes for use in TreeBins + */ + static final class TreeNode extends Node { + TreeNode parent; // red-black tree links + TreeNode left; + TreeNode right; + TreeNode prev; // needed to unlink next upon deletion + boolean red; + + TreeNode(int hash, Object key, Object val, Node next, TreeNode parent) { + super(hash, key, val, next); + this.parent = parent; + } + } + + /** + * A specialized form of red-black tree for use in bins + * whose size exceeds a threshold. + * + * TreeBins use a special form of comparison for search and + * related operations (which is the main reason we cannot use + * existing collections such as TreeMaps). TreeBins contain + * Comparable elements, but may contain others, as well as + * elements that are Comparable but not necessarily Comparable + * for the same T, so we cannot invoke compareTo among them. To + * handle this, the tree is ordered primarily by hash value, then + * by getClass().getName() order, and then by Comparator order + * among elements of the same class. On lookup at a node, if + * elements are not comparable or compare as 0, both left and + * right children may need to be searched in the case of tied hash + * values. (This corresponds to the full list search that would be + * necessary if all elements were non-Comparable and had tied + * hashes.) The red-black balancing code is updated from + * pre-jdk-collections + * (http://gee.cs.oswego.edu/dl/classes/collections/RBCell.java) + * based in turn on Cormen, Leiserson, and Rivest "Introduction to + * Algorithms" (CLR). + * + * TreeBins also maintain a separate locking discipline than + * regular bins. Because they are forwarded via special MOVED + * nodes at bin heads (which can never change once established), + * we cannot use those nodes as locks. Instead, TreeBin + * extends AbstractQueuedSynchronizer to support a simple form of + * read-write lock. For update operations and table validation, + * the exclusive form of lock behaves in the same way as bin-head + * locks. However, lookups use shared read-lock mechanics to allow + * multiple readers in the absence of writers. Additionally, + * these lookups do not ever block: While the lock is not + * available, they proceed along the slow traversal path (via + * next-pointers) until the lock becomes available or the list is + * exhausted, whichever comes first. (These cases are not fast, + * but maximize aggregate expected throughput.) The AQS mechanics + * for doing this are straightforward. The lock state is held as + * AQS getState(). Read counts are negative; the write count (1) + * is positive. There are no signalling preferences among readers + * and writers. Since we don't need to export full Lock API, we + * just override the minimal AQS methods and use them directly. + */ + static final class TreeBin extends AbstractQueuedSynchronizer { + private static final long serialVersionUID = 2249069246763182397L; + transient TreeNode root; // root of tree + transient TreeNode first; // head of next-pointer list + + /* AQS overrides */ + public final boolean isHeldExclusively() { return getState() > 0; } + public final boolean tryAcquire(int ignore) { + if (compareAndSetState(0, 1)) { + setExclusiveOwnerThread(Thread.currentThread()); + return true; + } + return false; + } + public final boolean tryRelease(int ignore) { + setExclusiveOwnerThread(null); + setState(0); + return true; + } + public final int tryAcquireShared(int ignore) { + for (int c;;) { + if ((c = getState()) > 0) + return -1; + if (compareAndSetState(c, c -1)) + return 1; + } + } + public final boolean tryReleaseShared(int ignore) { + int c; + do {} while (!compareAndSetState(c = getState(), c + 1)); + return c == -1; + } + + /** From CLR */ + private void rotateLeft(TreeNode p) { + if (p != null) { + TreeNode r = p.right, pp, rl; + if ((rl = p.right = r.left) != null) + rl.parent = p; + if ((pp = r.parent = p.parent) == null) + root = r; + else if (pp.left == p) + pp.left = r; + else + pp.right = r; + r.left = p; + p.parent = r; + } + } + + /** From CLR */ + private void rotateRight(TreeNode p) { + if (p != null) { + TreeNode l = p.left, pp, lr; + if ((lr = p.left = l.right) != null) + lr.parent = p; + if ((pp = l.parent = p.parent) == null) + root = l; + else if (pp.right == p) + pp.right = l; + else + pp.left = l; + l.right = p; + p.parent = l; + } + } + + @SuppressWarnings("unchecked") final TreeNode getTreeNode + (int h, Object k, TreeNode p) { + return getTreeNode(h, (RubyObject)k, p); + } + + /** + * Returns the TreeNode (or null if not found) for the given key + * starting at given root. + */ + @SuppressWarnings("unchecked") final TreeNode getTreeNode + (int h, RubyObject k, TreeNode p) { + RubyClass c = k.getMetaClass(); boolean kNotComparable = !k.respondsTo("<=>"); + while (p != null) { + int dir, ph; RubyObject pk; RubyClass pc; + if ((ph = p.hash) == h) { + if ((pk = (RubyObject)p.key) == k || k.equals(pk)) + return p; + if (c != (pc = (RubyClass)pk.getMetaClass()) || + kNotComparable || + (dir = rubyCompare(k, pk)) == 0) { + dir = (c == pc) ? 0 : c.getName().compareTo(pc.getName()); + if (dir == 0) { // if still stuck, need to check both sides + TreeNode r = null, pl, pr; + // try to recurse on the right + if ((pr = p.right) != null && h >= pr.hash && (r = getTreeNode(h, k, pr)) != null) + return r; + // try to continue iterating on the left side + else if ((pl = p.left) != null && h <= pl.hash) + dir = -1; + else // no matching node found + return null; + } + } + } + else + dir = (h < ph) ? -1 : 1; + p = (dir > 0) ? p.right : p.left; + } + return null; + } + + int rubyCompare(RubyObject l, RubyObject r) { + ThreadContext context = l.getMetaClass().getRuntime().getCurrentContext(); + IRubyObject result; + try { + result = l.callMethod(context, "<=>", r); + } catch (RaiseException e) { + // handle objects "lying" about responding to <=>, ie: an Array containing non-comparable keys + if (context.runtime.getNoMethodError().isInstance(e.getException())) { + return 0; + } + throw e; + } + + return result.isNil() ? 0 : RubyNumeric.num2int(result.convertToInteger()); + } + + /** + * Wrapper for getTreeNode used by CHM.get. Tries to obtain + * read-lock to call getTreeNode, but during failure to get + * lock, searches along next links. + */ + final Object getValue(int h, Object k) { + Node r = null; + int c = getState(); // Must read lock state first + for (Node e = first; e != null; e = e.next) { + if (c <= 0 && compareAndSetState(c, c - 1)) { + try { + r = getTreeNode(h, k, root); + } finally { + releaseShared(0); + } + break; + } + else if ((e.hash & HASH_BITS) == h && k.equals(e.key)) { + r = e; + break; + } + else + c = getState(); + } + return r == null ? null : r.val; + } + + @SuppressWarnings("unchecked") final TreeNode putTreeNode + (int h, Object k, Object v) { + return putTreeNode(h, (RubyObject)k, v); + } + + /** + * Finds or adds a node. + * @return null if added + */ + @SuppressWarnings("unchecked") final TreeNode putTreeNode + (int h, RubyObject k, Object v) { + RubyClass c = k.getMetaClass(); + boolean kNotComparable = !k.respondsTo("<=>"); + TreeNode pp = root, p = null; + int dir = 0; + while (pp != null) { // find existing node or leaf to insert at + int ph; RubyObject pk; RubyClass pc; + p = pp; + if ((ph = p.hash) == h) { + if ((pk = (RubyObject)p.key) == k || k.equals(pk)) + return p; + if (c != (pc = pk.getMetaClass()) || + kNotComparable || + (dir = rubyCompare(k, pk)) == 0) { + dir = (c == pc) ? 0 : c.getName().compareTo(pc.getName()); + if (dir == 0) { // if still stuck, need to check both sides + TreeNode r = null, pr; + // try to recurse on the right + if ((pr = p.right) != null && h >= pr.hash && (r = getTreeNode(h, k, pr)) != null) + return r; + else // continue descending down the left subtree + dir = -1; + } + } + } + else + dir = (h < ph) ? -1 : 1; + pp = (dir > 0) ? p.right : p.left; + } + + TreeNode f = first; + TreeNode x = first = new TreeNode(h, (Object)k, v, f, p); + if (p == null) + root = x; + else { // attach and rebalance; adapted from CLR + TreeNode xp, xpp; + if (f != null) + f.prev = x; + if (dir <= 0) + p.left = x; + else + p.right = x; + x.red = true; + while (x != null && (xp = x.parent) != null && xp.red && + (xpp = xp.parent) != null) { + TreeNode xppl = xpp.left; + if (xp == xppl) { + TreeNode y = xpp.right; + if (y != null && y.red) { + y.red = false; + xp.red = false; + xpp.red = true; + x = xpp; + } + else { + if (x == xp.right) { + rotateLeft(x = xp); + xpp = (xp = x.parent) == null ? null : xp.parent; + } + if (xp != null) { + xp.red = false; + if (xpp != null) { + xpp.red = true; + rotateRight(xpp); + } + } + } + } + else { + TreeNode y = xppl; + if (y != null && y.red) { + y.red = false; + xp.red = false; + xpp.red = true; + x = xpp; + } + else { + if (x == xp.left) { + rotateRight(x = xp); + xpp = (xp = x.parent) == null ? null : xp.parent; + } + if (xp != null) { + xp.red = false; + if (xpp != null) { + xpp.red = true; + rotateLeft(xpp); + } + } + } + } + } + TreeNode r = root; + if (r != null && r.red) + r.red = false; + } + return null; + } + + /** + * Removes the given node, that must be present before this + * call. This is messier than typical red-black deletion code + * because we cannot swap the contents of an interior node + * with a leaf successor that is pinned by "next" pointers + * that are accessible independently of lock. So instead we + * swap the tree linkages. + */ + final void deleteTreeNode(TreeNode p) { + TreeNode next = (TreeNode)p.next; // unlink traversal pointers + TreeNode pred = p.prev; + if (pred == null) + first = next; + else + pred.next = next; + if (next != null) + next.prev = pred; + TreeNode replacement; + TreeNode pl = p.left; + TreeNode pr = p.right; + if (pl != null && pr != null) { + TreeNode s = pr, sl; + while ((sl = s.left) != null) // find successor + s = sl; + boolean c = s.red; s.red = p.red; p.red = c; // swap colors + TreeNode sr = s.right; + TreeNode pp = p.parent; + if (s == pr) { // p was s's direct parent + p.parent = s; + s.right = p; + } + else { + TreeNode sp = s.parent; + if ((p.parent = sp) != null) { + if (s == sp.left) + sp.left = p; + else + sp.right = p; + } + if ((s.right = pr) != null) + pr.parent = s; + } + p.left = null; + if ((p.right = sr) != null) + sr.parent = p; + if ((s.left = pl) != null) + pl.parent = s; + if ((s.parent = pp) == null) + root = s; + else if (p == pp.left) + pp.left = s; + else + pp.right = s; + replacement = sr; + } + else + replacement = (pl != null) ? pl : pr; + TreeNode pp = p.parent; + if (replacement == null) { + if (pp == null) { + root = null; + return; + } + replacement = p; + } + else { + replacement.parent = pp; + if (pp == null) + root = replacement; + else if (p == pp.left) + pp.left = replacement; + else + pp.right = replacement; + p.left = p.right = p.parent = null; + } + if (!p.red) { // rebalance, from CLR + TreeNode x = replacement; + while (x != null) { + TreeNode xp, xpl; + if (x.red || (xp = x.parent) == null) { + x.red = false; + break; + } + if (x == (xpl = xp.left)) { + TreeNode sib = xp.right; + if (sib != null && sib.red) { + sib.red = false; + xp.red = true; + rotateLeft(xp); + sib = (xp = x.parent) == null ? null : xp.right; + } + if (sib == null) + x = xp; + else { + TreeNode sl = sib.left, sr = sib.right; + if ((sr == null || !sr.red) && + (sl == null || !sl.red)) { + sib.red = true; + x = xp; + } + else { + if (sr == null || !sr.red) { + if (sl != null) + sl.red = false; + sib.red = true; + rotateRight(sib); + sib = (xp = x.parent) == null ? null : xp.right; + } + if (sib != null) { + sib.red = (xp == null) ? false : xp.red; + if ((sr = sib.right) != null) + sr.red = false; + } + if (xp != null) { + xp.red = false; + rotateLeft(xp); + } + x = root; + } + } + } + else { // symmetric + TreeNode sib = xpl; + if (sib != null && sib.red) { + sib.red = false; + xp.red = true; + rotateRight(xp); + sib = (xp = x.parent) == null ? null : xp.left; + } + if (sib == null) + x = xp; + else { + TreeNode sl = sib.left, sr = sib.right; + if ((sl == null || !sl.red) && + (sr == null || !sr.red)) { + sib.red = true; + x = xp; + } + else { + if (sl == null || !sl.red) { + if (sr != null) + sr.red = false; + sib.red = true; + rotateLeft(sib); + sib = (xp = x.parent) == null ? null : xp.left; + } + if (sib != null) { + sib.red = (xp == null) ? false : xp.red; + if ((sl = sib.left) != null) + sl.red = false; + } + if (xp != null) { + xp.red = false; + rotateRight(xp); + } + x = root; + } + } + } + } + } + if (p == replacement && (pp = p.parent) != null) { + if (p == pp.left) // detach pointers + pp.left = null; + else if (p == pp.right) + pp.right = null; + p.parent = null; + } + } + } + + /* ---------------- Collision reduction methods -------------- */ + + /** + * Spreads higher bits to lower, and also forces top 2 bits to 0. + * Because the table uses power-of-two masking, sets of hashes + * that vary only in bits above the current mask will always + * collide. (Among known examples are sets of Float keys holding + * consecutive whole numbers in small tables.) To counter this, + * we apply a transform that spreads the impact of higher bits + * downward. There is a tradeoff between speed, utility, and + * quality of bit-spreading. Because many common sets of hashes + * are already reasonably distributed across bits (so don't benefit + * from spreading), and because we use trees to handle large sets + * of collisions in bins, we don't need excessively high quality. + */ + private static final int spread(int h) { + h ^= (h >>> 18) ^ (h >>> 12); + return (h ^ (h >>> 10)) & HASH_BITS; + } + + /** + * Replaces a list bin with a tree bin. Call only when locked. + * Fails to replace if the given key is non-comparable or table + * is, or needs, resizing. + */ + private final void replaceWithTreeBin(Node[] tab, int index, Object key) { + if ((key instanceof Comparable) && + (tab.length >= MAXIMUM_CAPACITY || counter.sum() < (long)sizeCtl)) { + TreeBin t = new TreeBin(); + for (Node e = tabAt(tab, index); e != null; e = e.next) + t.putTreeNode(e.hash & HASH_BITS, e.key, e.val); + setTabAt(tab, index, new Node(MOVED, t, null, null)); + } + } + + /* ---------------- Internal access and update methods -------------- */ + + /** Implementation for get and containsKey */ + private final Object internalGet(Object k) { + int h = spread(k.hashCode()); + retry: for (Node[] tab = table; tab != null;) { + Node e, p; Object ek, ev; int eh; // locals to read fields once + for (e = tabAt(tab, (tab.length - 1) & h); e != null; e = e.next) { + if ((eh = e.hash) == MOVED) { + if ((ek = e.key) instanceof TreeBin) // search TreeBin + return ((TreeBin)ek).getValue(h, k); + else { // restart with new table + tab = (Node[])ek; + continue retry; + } + } + else if ((eh & HASH_BITS) == h && (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) + return ev; + } + break; + } + return null; + } + + /** + * Implementation for the four public remove/replace methods: + * Replaces node value with v, conditional upon match of cv if + * non-null. If resulting value is null, delete. + */ + private final Object internalReplace(Object k, Object v, Object cv) { + int h = spread(k.hashCode()); + Object oldVal = null; + for (Node[] tab = table;;) { + Node f; int i, fh; Object fk; + if (tab == null || + (f = tabAt(tab, i = (tab.length - 1) & h)) == null) + break; + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + boolean validated = false; + boolean deleted = false; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + validated = true; + TreeNode p = t.getTreeNode(h, k, t.root); + if (p != null) { + Object pv = p.val; + if (cv == null || cv == pv || cv.equals(pv)) { + oldVal = pv; + if ((p.val = v) == null) { + deleted = true; + t.deleteTreeNode(p); + } + } + } + } + } finally { + t.release(0); + } + if (validated) { + if (deleted) + counter.add(-1L); + break; + } + } + else + tab = (Node[])fk; + } + else if ((fh & HASH_BITS) != h && f.next == null) // precheck + break; // rules out possible existence + else if ((fh & LOCKED) != 0) { + checkForResize(); // try resizing if can't get lock + f.tryAwaitLock(tab, i); + } + else if (f.casHash(fh, fh | LOCKED)) { + boolean validated = false; + boolean deleted = false; + try { + if (tabAt(tab, i) == f) { + validated = true; + for (Node e = f, pred = null;;) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + ((ev = e.val) != null) && + ((ek = e.key) == k || k.equals(ek))) { + if (cv == null || cv == ev || cv.equals(ev)) { + oldVal = ev; + if ((e.val = v) == null) { + deleted = true; + Node en = e.next; + if (pred != null) + pred.next = en; + else + setTabAt(tab, i, en); + } + } + break; + } + pred = e; + if ((e = e.next) == null) + break; + } + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (validated) { + if (deleted) + counter.add(-1L); + break; + } + } + } + return oldVal; + } + + /* + * Internal versions of the six insertion methods, each a + * little more complicated than the last. All have + * the same basic structure as the first (internalPut): + * 1. If table uninitialized, create + * 2. If bin empty, try to CAS new node + * 3. If bin stale, use new table + * 4. if bin converted to TreeBin, validate and relay to TreeBin methods + * 5. Lock and validate; if valid, scan and add or update + * + * The others interweave other checks and/or alternative actions: + * * Plain put checks for and performs resize after insertion. + * * putIfAbsent prescans for mapping without lock (and fails to add + * if present), which also makes pre-emptive resize checks worthwhile. + * * computeIfAbsent extends form used in putIfAbsent with additional + * mechanics to deal with, calls, potential exceptions and null + * returns from function call. + * * compute uses the same function-call mechanics, but without + * the prescans + * * merge acts as putIfAbsent in the absent case, but invokes the + * update function if present + * * putAll attempts to pre-allocate enough table space + * and more lazily performs count updates and checks. + * + * Someday when details settle down a bit more, it might be worth + * some factoring to reduce sprawl. + */ + + /** Implementation for put */ + private final Object internalPut(Object k, Object v) { + int h = spread(k.hashCode()); + int count = 0; + for (Node[] tab = table;;) { + int i; Node f; int fh; Object fk; + if (tab == null) + tab = initTable(); + else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) { + if (casTabAt(tab, i, null, new Node(h, k, v, null))) + break; // no lock when adding to empty bin + } + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + Object oldVal = null; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + count = 2; + TreeNode p = t.putTreeNode(h, k, v); + if (p != null) { + oldVal = p.val; + p.val = v; + } + } + } finally { + t.release(0); + } + if (count != 0) { + if (oldVal != null) + return oldVal; + break; + } + } + else + tab = (Node[])fk; + } + else if ((fh & LOCKED) != 0) { + checkForResize(); + f.tryAwaitLock(tab, i); + } + else if (f.casHash(fh, fh | LOCKED)) { + Object oldVal = null; + try { // needed in case equals() throws + if (tabAt(tab, i) == f) { + count = 1; + for (Node e = f;; ++count) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) { + oldVal = ev; + e.val = v; + break; + } + Node last = e; + if ((e = e.next) == null) { + last.next = new Node(h, k, v, null); + if (count >= TREE_THRESHOLD) + replaceWithTreeBin(tab, i, k); + break; + } + } + } + } finally { // unlock and signal if needed + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (count != 0) { + if (oldVal != null) + return oldVal; + if (tab.length <= 64) + count = 2; + break; + } + } + } + counter.add(1L); + if (count > 1) + checkForResize(); + return null; + } + + /** Implementation for putIfAbsent */ + private final Object internalPutIfAbsent(Object k, Object v) { + int h = spread(k.hashCode()); + int count = 0; + for (Node[] tab = table;;) { + int i; Node f; int fh; Object fk, fv; + if (tab == null) + tab = initTable(); + else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) { + if (casTabAt(tab, i, null, new Node(h, k, v, null))) + break; + } + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + Object oldVal = null; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + count = 2; + TreeNode p = t.putTreeNode(h, k, v); + if (p != null) + oldVal = p.val; + } + } finally { + t.release(0); + } + if (count != 0) { + if (oldVal != null) + return oldVal; + break; + } + } + else + tab = (Node[])fk; + } + else if ((fh & HASH_BITS) == h && (fv = f.val) != null && + ((fk = f.key) == k || k.equals(fk))) + return fv; + else { + Node g = f.next; + if (g != null) { // at least 2 nodes -- search and maybe resize + for (Node e = g;;) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) + return ev; + if ((e = e.next) == null) { + checkForResize(); + break; + } + } + } + if (((fh = f.hash) & LOCKED) != 0) { + checkForResize(); + f.tryAwaitLock(tab, i); + } + else if (tabAt(tab, i) == f && f.casHash(fh, fh | LOCKED)) { + Object oldVal = null; + try { + if (tabAt(tab, i) == f) { + count = 1; + for (Node e = f;; ++count) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) { + oldVal = ev; + break; + } + Node last = e; + if ((e = e.next) == null) { + last.next = new Node(h, k, v, null); + if (count >= TREE_THRESHOLD) + replaceWithTreeBin(tab, i, k); + break; + } + } + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (count != 0) { + if (oldVal != null) + return oldVal; + if (tab.length <= 64) + count = 2; + break; + } + } + } + } + counter.add(1L); + if (count > 1) + checkForResize(); + return null; + } + + /** Implementation for computeIfAbsent */ + private final Object internalComputeIfAbsent(K k, + Fun mf) { + int h = spread(k.hashCode()); + Object val = null; + int count = 0; + for (Node[] tab = table;;) { + Node f; int i, fh; Object fk, fv; + if (tab == null) + tab = initTable(); + else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) { + Node node = new Node(fh = h | LOCKED, k, null, null); + if (casTabAt(tab, i, null, node)) { + count = 1; + try { + if ((val = mf.apply(k)) != null) + node.val = val; + } finally { + if (val == null) + setTabAt(tab, i, null); + if (!node.casHash(fh, h)) { + node.hash = h; + synchronized (node) { node.notifyAll(); }; + } + } + } + if (count != 0) + break; + } + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + boolean added = false; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + count = 1; + TreeNode p = t.getTreeNode(h, k, t.root); + if (p != null) + val = p.val; + else if ((val = mf.apply(k)) != null) { + added = true; + count = 2; + t.putTreeNode(h, k, val); + } + } + } finally { + t.release(0); + } + if (count != 0) { + if (!added) + return val; + break; + } + } + else + tab = (Node[])fk; + } + else if ((fh & HASH_BITS) == h && (fv = f.val) != null && + ((fk = f.key) == k || k.equals(fk))) + return fv; + else { + Node g = f.next; + if (g != null) { + for (Node e = g;;) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) + return ev; + if ((e = e.next) == null) { + checkForResize(); + break; + } + } + } + if (((fh = f.hash) & LOCKED) != 0) { + checkForResize(); + f.tryAwaitLock(tab, i); + } + else if (tabAt(tab, i) == f && f.casHash(fh, fh | LOCKED)) { + boolean added = false; + try { + if (tabAt(tab, i) == f) { + count = 1; + for (Node e = f;; ++count) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) { + val = ev; + break; + } + Node last = e; + if ((e = e.next) == null) { + if ((val = mf.apply(k)) != null) { + added = true; + last.next = new Node(h, k, val, null); + if (count >= TREE_THRESHOLD) + replaceWithTreeBin(tab, i, k); + } + break; + } + } + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (count != 0) { + if (!added) + return val; + if (tab.length <= 64) + count = 2; + break; + } + } + } + } + if (val != null) { + counter.add(1L); + if (count > 1) + checkForResize(); + } + return val; + } + + /** Implementation for compute */ + @SuppressWarnings("unchecked") private final Object internalCompute + (K k, boolean onlyIfPresent, BiFun mf) { + int h = spread(k.hashCode()); + Object val = null; + int delta = 0; + int count = 0; + for (Node[] tab = table;;) { + Node f; int i, fh; Object fk; + if (tab == null) + tab = initTable(); + else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) { + if (onlyIfPresent) + break; + Node node = new Node(fh = h | LOCKED, k, null, null); + if (casTabAt(tab, i, null, node)) { + try { + count = 1; + if ((val = mf.apply(k, null)) != null) { + node.val = val; + delta = 1; + } + } finally { + if (delta == 0) + setTabAt(tab, i, null); + if (!node.casHash(fh, h)) { + node.hash = h; + synchronized (node) { node.notifyAll(); }; + } + } + } + if (count != 0) + break; + } + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + count = 1; + TreeNode p = t.getTreeNode(h, k, t.root); + Object pv; + if (p == null) { + if (onlyIfPresent) + break; + pv = null; + } else + pv = p.val; + if ((val = mf.apply(k, (V)pv)) != null) { + if (p != null) + p.val = val; + else { + count = 2; + delta = 1; + t.putTreeNode(h, k, val); + } + } + else if (p != null) { + delta = -1; + t.deleteTreeNode(p); + } + } + } finally { + t.release(0); + } + if (count != 0) + break; + } + else + tab = (Node[])fk; + } + else if ((fh & LOCKED) != 0) { + checkForResize(); + f.tryAwaitLock(tab, i); + } + else if (f.casHash(fh, fh | LOCKED)) { + try { + if (tabAt(tab, i) == f) { + count = 1; + for (Node e = f, pred = null;; ++count) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) { + val = mf.apply(k, (V)ev); + if (val != null) + e.val = val; + else { + delta = -1; + Node en = e.next; + if (pred != null) + pred.next = en; + else + setTabAt(tab, i, en); + } + break; + } + pred = e; + if ((e = e.next) == null) { + if (!onlyIfPresent && (val = mf.apply(k, null)) != null) { + pred.next = new Node(h, k, val, null); + delta = 1; + if (count >= TREE_THRESHOLD) + replaceWithTreeBin(tab, i, k); + } + break; + } + } + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (count != 0) { + if (tab.length <= 64) + count = 2; + break; + } + } + } + if (delta != 0) { + counter.add((long)delta); + if (count > 1) + checkForResize(); + } + return val; + } + + /** Implementation for merge */ + @SuppressWarnings("unchecked") private final Object internalMerge + (K k, V v, BiFun mf) { + int h = spread(k.hashCode()); + Object val = null; + int delta = 0; + int count = 0; + for (Node[] tab = table;;) { + int i; Node f; int fh; Object fk, fv; + if (tab == null) + tab = initTable(); + else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null) { + if (casTabAt(tab, i, null, new Node(h, k, v, null))) { + delta = 1; + val = v; + break; + } + } + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + count = 1; + TreeNode p = t.getTreeNode(h, k, t.root); + val = (p == null) ? v : mf.apply((V)p.val, v); + if (val != null) { + if (p != null) + p.val = val; + else { + count = 2; + delta = 1; + t.putTreeNode(h, k, val); + } + } + else if (p != null) { + delta = -1; + t.deleteTreeNode(p); + } + } + } finally { + t.release(0); + } + if (count != 0) + break; + } + else + tab = (Node[])fk; + } + else if ((fh & LOCKED) != 0) { + checkForResize(); + f.tryAwaitLock(tab, i); + } + else if (f.casHash(fh, fh | LOCKED)) { + try { + if (tabAt(tab, i) == f) { + count = 1; + for (Node e = f, pred = null;; ++count) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) { + val = mf.apply((V)ev, v); + if (val != null) + e.val = val; + else { + delta = -1; + Node en = e.next; + if (pred != null) + pred.next = en; + else + setTabAt(tab, i, en); + } + break; + } + pred = e; + if ((e = e.next) == null) { + val = v; + pred.next = new Node(h, k, val, null); + delta = 1; + if (count >= TREE_THRESHOLD) + replaceWithTreeBin(tab, i, k); + break; + } + } + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (count != 0) { + if (tab.length <= 64) + count = 2; + break; + } + } + } + if (delta != 0) { + counter.add((long)delta); + if (count > 1) + checkForResize(); + } + return val; + } + + /** Implementation for putAll */ + private final void internalPutAll(Map m) { + tryPresize(m.size()); + long delta = 0L; // number of uncommitted additions + boolean npe = false; // to throw exception on exit for nulls + try { // to clean up counts on other exceptions + for (Map.Entry entry : m.entrySet()) { + Object k, v; + if (entry == null || (k = entry.getKey()) == null || + (v = entry.getValue()) == null) { + npe = true; + break; + } + int h = spread(k.hashCode()); + for (Node[] tab = table;;) { + int i; Node f; int fh; Object fk; + if (tab == null) + tab = initTable(); + else if ((f = tabAt(tab, i = (tab.length - 1) & h)) == null){ + if (casTabAt(tab, i, null, new Node(h, k, v, null))) { + ++delta; + break; + } + } + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + boolean validated = false; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + validated = true; + TreeNode p = t.getTreeNode(h, k, t.root); + if (p != null) + p.val = v; + else { + t.putTreeNode(h, k, v); + ++delta; + } + } + } finally { + t.release(0); + } + if (validated) + break; + } + else + tab = (Node[])fk; + } + else if ((fh & LOCKED) != 0) { + counter.add(delta); + delta = 0L; + checkForResize(); + f.tryAwaitLock(tab, i); + } + else if (f.casHash(fh, fh | LOCKED)) { + int count = 0; + try { + if (tabAt(tab, i) == f) { + count = 1; + for (Node e = f;; ++count) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) { + e.val = v; + break; + } + Node last = e; + if ((e = e.next) == null) { + ++delta; + last.next = new Node(h, k, v, null); + if (count >= TREE_THRESHOLD) + replaceWithTreeBin(tab, i, k); + break; + } + } + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (count != 0) { + if (count > 1) { + counter.add(delta); + delta = 0L; + checkForResize(); + } + break; + } + } + } + } + } finally { + if (delta != 0) + counter.add(delta); + } + if (npe) + throw new NullPointerException(); + } + + /* ---------------- Table Initialization and Resizing -------------- */ + + /** + * Returns a power of two table size for the given desired capacity. + * See Hackers Delight, sec 3.2 + */ + private static final int tableSizeFor(int c) { + int n = c - 1; + n |= n >>> 1; + n |= n >>> 2; + n |= n >>> 4; + n |= n >>> 8; + n |= n >>> 16; + return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; + } + + /** + * Initializes table, using the size recorded in sizeCtl. + */ + private final Node[] initTable() { + Node[] tab; int sc; + while ((tab = table) == null) { + if ((sc = sizeCtl) < 0) + Thread.yield(); // lost initialization race; just spin + else if (UNSAFE.compareAndSwapInt(this, sizeCtlOffset, sc, -1)) { + try { + if ((tab = table) == null) { + int n = (sc > 0) ? sc : DEFAULT_CAPACITY; + tab = table = new Node[n]; + sc = n - (n >>> 2); + } + } finally { + sizeCtl = sc; + } + break; + } + } + return tab; + } + + /** + * If table is too small and not already resizing, creates next + * table and transfers bins. Rechecks occupancy after a transfer + * to see if another resize is already needed because resizings + * are lagging additions. + */ + private final void checkForResize() { + Node[] tab; int n, sc; + while ((tab = table) != null && + (n = tab.length) < MAXIMUM_CAPACITY && + (sc = sizeCtl) >= 0 && counter.sum() >= (long)sc && + UNSAFE.compareAndSwapInt(this, sizeCtlOffset, sc, -1)) { + try { + if (tab == table) { + table = rebuild(tab); + sc = (n << 1) - (n >>> 1); + } + } finally { + sizeCtl = sc; + } + } + } + + /** + * Tries to presize table to accommodate the given number of elements. + * + * @param size number of elements (doesn't need to be perfectly accurate) + */ + private final void tryPresize(int size) { + int c = (size >= (MAXIMUM_CAPACITY >>> 1)) ? MAXIMUM_CAPACITY : + tableSizeFor(size + (size >>> 1) + 1); + int sc; + while ((sc = sizeCtl) >= 0) { + Node[] tab = table; int n; + if (tab == null || (n = tab.length) == 0) { + n = (sc > c) ? sc : c; + if (UNSAFE.compareAndSwapInt(this, sizeCtlOffset, sc, -1)) { + try { + if (table == tab) { + table = new Node[n]; + sc = n - (n >>> 2); + } + } finally { + sizeCtl = sc; + } + } + } + else if (c <= sc || n >= MAXIMUM_CAPACITY) + break; + else if (UNSAFE.compareAndSwapInt(this, sizeCtlOffset, sc, -1)) { + try { + if (table == tab) { + table = rebuild(tab); + sc = (n << 1) - (n >>> 1); + } + } finally { + sizeCtl = sc; + } + } + } + } + + /* + * Moves and/or copies the nodes in each bin to new table. See + * above for explanation. + * + * @return the new table + */ + private static final Node[] rebuild(Node[] tab) { + int n = tab.length; + Node[] nextTab = new Node[n << 1]; + Node fwd = new Node(MOVED, nextTab, null, null); + int[] buffer = null; // holds bins to revisit; null until needed + Node rev = null; // reverse forwarder; null until needed + int nbuffered = 0; // the number of bins in buffer list + int bufferIndex = 0; // buffer index of current buffered bin + int bin = n - 1; // current non-buffered bin or -1 if none + + for (int i = bin;;) { // start upwards sweep + int fh; Node f; + if ((f = tabAt(tab, i)) == null) { + if (bin >= 0) { // Unbuffered; no lock needed (or available) + if (!casTabAt(tab, i, f, fwd)) + continue; + } + else { // transiently use a locked forwarding node + Node g = new Node(MOVED|LOCKED, nextTab, null, null); + if (!casTabAt(tab, i, f, g)) + continue; + setTabAt(nextTab, i, null); + setTabAt(nextTab, i + n, null); + setTabAt(tab, i, fwd); + if (!g.casHash(MOVED|LOCKED, MOVED)) { + g.hash = MOVED; + synchronized (g) { g.notifyAll(); } + } + } + } + else if ((fh = f.hash) == MOVED) { + Object fk = f.key; + if (fk instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + boolean validated = false; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + validated = true; + splitTreeBin(nextTab, i, t); + setTabAt(tab, i, fwd); + } + } finally { + t.release(0); + } + if (!validated) + continue; + } + } + else if ((fh & LOCKED) == 0 && f.casHash(fh, fh|LOCKED)) { + boolean validated = false; + try { // split to lo and hi lists; copying as needed + if (tabAt(tab, i) == f) { + validated = true; + splitBin(nextTab, i, f); + setTabAt(tab, i, fwd); + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (!validated) + continue; + } + else { + if (buffer == null) // initialize buffer for revisits + buffer = new int[TRANSFER_BUFFER_SIZE]; + if (bin < 0 && bufferIndex > 0) { + int j = buffer[--bufferIndex]; + buffer[bufferIndex] = i; + i = j; // swap with another bin + continue; + } + if (bin < 0 || nbuffered >= TRANSFER_BUFFER_SIZE) { + f.tryAwaitLock(tab, i); + continue; // no other options -- block + } + if (rev == null) // initialize reverse-forwarder + rev = new Node(MOVED, tab, null, null); + if (tabAt(tab, i) != f || (f.hash & LOCKED) == 0) + continue; // recheck before adding to list + buffer[nbuffered++] = i; + setTabAt(nextTab, i, rev); // install place-holders + setTabAt(nextTab, i + n, rev); + } + + if (bin > 0) + i = --bin; + else if (buffer != null && nbuffered > 0) { + bin = -1; + i = buffer[bufferIndex = --nbuffered]; + } + else + return nextTab; + } + } + + /** + * Splits a normal bin with list headed by e into lo and hi parts; + * installs in given table. + */ + private static void splitBin(Node[] nextTab, int i, Node e) { + int bit = nextTab.length >>> 1; // bit to split on + int runBit = e.hash & bit; + Node lastRun = e, lo = null, hi = null; + for (Node p = e.next; p != null; p = p.next) { + int b = p.hash & bit; + if (b != runBit) { + runBit = b; + lastRun = p; + } + } + if (runBit == 0) + lo = lastRun; + else + hi = lastRun; + for (Node p = e; p != lastRun; p = p.next) { + int ph = p.hash & HASH_BITS; + Object pk = p.key, pv = p.val; + if ((ph & bit) == 0) + lo = new Node(ph, pk, pv, lo); + else + hi = new Node(ph, pk, pv, hi); + } + setTabAt(nextTab, i, lo); + setTabAt(nextTab, i + bit, hi); + } + + /** + * Splits a tree bin into lo and hi parts; installs in given table. + */ + private static void splitTreeBin(Node[] nextTab, int i, TreeBin t) { + int bit = nextTab.length >>> 1; + TreeBin lt = new TreeBin(); + TreeBin ht = new TreeBin(); + int lc = 0, hc = 0; + for (Node e = t.first; e != null; e = e.next) { + int h = e.hash & HASH_BITS; + Object k = e.key, v = e.val; + if ((h & bit) == 0) { + ++lc; + lt.putTreeNode(h, k, v); + } + else { + ++hc; + ht.putTreeNode(h, k, v); + } + } + Node ln, hn; // throw away trees if too small + if (lc <= (TREE_THRESHOLD >>> 1)) { + ln = null; + for (Node p = lt.first; p != null; p = p.next) + ln = new Node(p.hash, p.key, p.val, ln); + } + else + ln = new Node(MOVED, lt, null, null); + setTabAt(nextTab, i, ln); + if (hc <= (TREE_THRESHOLD >>> 1)) { + hn = null; + for (Node p = ht.first; p != null; p = p.next) + hn = new Node(p.hash, p.key, p.val, hn); + } + else + hn = new Node(MOVED, ht, null, null); + setTabAt(nextTab, i + bit, hn); + } + + /** + * Implementation for clear. Steps through each bin, removing all + * nodes. + */ + private final void internalClear() { + long delta = 0L; // negative number of deletions + int i = 0; + Node[] tab = table; + while (tab != null && i < tab.length) { + int fh; Object fk; + Node f = tabAt(tab, i); + if (f == null) + ++i; + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + for (Node p = t.first; p != null; p = p.next) { + if (p.val != null) { // (currently always true) + p.val = null; + --delta; + } + } + t.first = null; + t.root = null; + ++i; + } + } finally { + t.release(0); + } + } + else + tab = (Node[])fk; + } + else if ((fh & LOCKED) != 0) { + counter.add(delta); // opportunistically update count + delta = 0L; + f.tryAwaitLock(tab, i); + } + else if (f.casHash(fh, fh | LOCKED)) { + try { + if (tabAt(tab, i) == f) { + for (Node e = f; e != null; e = e.next) { + if (e.val != null) { // (currently always true) + e.val = null; + --delta; + } + } + setTabAt(tab, i, null); + ++i; + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + } + } + if (delta != 0) + counter.add(delta); + } + + /* ----------------Table Traversal -------------- */ + + /** + * Encapsulates traversal for methods such as containsValue; also + * serves as a base class for other iterators and bulk tasks. + * + * At each step, the iterator snapshots the key ("nextKey") and + * value ("nextVal") of a valid node (i.e., one that, at point of + * snapshot, has a non-null user value). Because val fields can + * change (including to null, indicating deletion), field nextVal + * might not be accurate at point of use, but still maintains the + * weak consistency property of holding a value that was once + * valid. To support iterator.remove, the nextKey field is not + * updated (nulled out) when the iterator cannot advance. + * + * Internal traversals directly access these fields, as in: + * {@code while (it.advance() != null) { process(it.nextKey); }} + * + * Exported iterators must track whether the iterator has advanced + * (in hasNext vs next) (by setting/checking/nulling field + * nextVal), and then extract key, value, or key-value pairs as + * return values of next(). + * + * The iterator visits once each still-valid node that was + * reachable upon iterator construction. It might miss some that + * were added to a bin after the bin was visited, which is OK wrt + * consistency guarantees. Maintaining this property in the face + * of possible ongoing resizes requires a fair amount of + * bookkeeping state that is difficult to optimize away amidst + * volatile accesses. Even so, traversal maintains reasonable + * throughput. + * + * Normally, iteration proceeds bin-by-bin traversing lists. + * However, if the table has been resized, then all future steps + * must traverse both the bin at the current index as well as at + * (index + baseSize); and so on for further resizings. To + * paranoically cope with potential sharing by users of iterators + * across threads, iteration terminates if a bounds checks fails + * for a table read. + * + * This class extends ForkJoinTask to streamline parallel + * iteration in bulk operations (see BulkTask). This adds only an + * int of space overhead, which is close enough to negligible in + * cases where it is not needed to not worry about it. Because + * ForkJoinTask is Serializable, but iterators need not be, we + * need to add warning suppressions. + */ + @SuppressWarnings("serial") static class Traverser { + final ConcurrentHashMapV8 map; + Node next; // the next entry to use + K nextKey; // cached key field of next + V nextVal; // cached val field of next + Node[] tab; // current table; updated if resized + int index; // index of bin to use next + int baseIndex; // current index of initial table + int baseLimit; // index bound for initial table + int baseSize; // initial table size + + /** Creates iterator for all entries in the table. */ + Traverser(ConcurrentHashMapV8 map) { + this.map = map; + } + + /** Creates iterator for split() methods */ + Traverser(Traverser it) { + ConcurrentHashMapV8 m; Node[] t; + if ((m = this.map = it.map) == null) + t = null; + else if ((t = it.tab) == null && // force parent tab initialization + (t = it.tab = m.table) != null) + it.baseLimit = it.baseSize = t.length; + this.tab = t; + this.baseSize = it.baseSize; + it.baseLimit = this.index = this.baseIndex = + ((this.baseLimit = it.baseLimit) + it.baseIndex + 1) >>> 1; + } + + /** + * Advances next; returns nextVal or null if terminated. + * See above for explanation. + */ + final V advance() { + Node e = next; + V ev = null; + outer: do { + if (e != null) // advance past used/skipped node + e = e.next; + while (e == null) { // get to next non-null bin + ConcurrentHashMapV8 m; + Node[] t; int b, i, n; Object ek; // checks must use locals + if ((t = tab) != null) + n = t.length; + else if ((m = map) != null && (t = tab = m.table) != null) + n = baseLimit = baseSize = t.length; + else + break outer; + if ((b = baseIndex) >= baseLimit || + (i = index) < 0 || i >= n) + break outer; + if ((e = tabAt(t, i)) != null && e.hash == MOVED) { + if ((ek = e.key) instanceof TreeBin) + e = ((TreeBin)ek).first; + else { + tab = (Node[])ek; + continue; // restarts due to null val + } + } // visit upper slots if present + index = (i += baseSize) < n ? i : (baseIndex = b + 1); + } + nextKey = (K) e.key; + } while ((ev = (V) e.val) == null); // skip deleted or special nodes + next = e; + return nextVal = ev; + } + + public final void remove() { + Object k = nextKey; + if (k == null && (advance() == null || (k = nextKey) == null)) + throw new IllegalStateException(); + map.internalReplace(k, null, null); + } + + public final boolean hasNext() { + return nextVal != null || advance() != null; + } + + public final boolean hasMoreElements() { return hasNext(); } + public final void setRawResult(Object x) { } + public R getRawResult() { return null; } + public boolean exec() { return true; } + } + + /* ---------------- Public operations -------------- */ + + /** + * Creates a new, empty map with the default initial table size (16). + */ + public ConcurrentHashMapV8() { + this.counter = new LongAdder(); + } + + /** + * Creates a new, empty map with an initial table size + * accommodating the specified number of elements without the need + * to dynamically resize. + * + * @param initialCapacity The implementation performs internal + * sizing to accommodate this many elements. + * @throws IllegalArgumentException if the initial capacity of + * elements is negative + */ + public ConcurrentHashMapV8(int initialCapacity) { + if (initialCapacity < 0) + throw new IllegalArgumentException(); + int cap = ((initialCapacity >= (MAXIMUM_CAPACITY >>> 1)) ? + MAXIMUM_CAPACITY : + tableSizeFor(initialCapacity + (initialCapacity >>> 1) + 1)); + this.counter = new LongAdder(); + this.sizeCtl = cap; + } + + /** + * Creates a new map with the same mappings as the given map. + * + * @param m the map + */ + public ConcurrentHashMapV8(Map m) { + this.counter = new LongAdder(); + this.sizeCtl = DEFAULT_CAPACITY; + internalPutAll(m); + } + + /** + * Creates a new, empty map with an initial table size based on + * the given number of elements ({@code initialCapacity}) and + * initial table density ({@code loadFactor}). + * + * @param initialCapacity the initial capacity. The implementation + * performs internal sizing to accommodate this many elements, + * given the specified load factor. + * @param loadFactor the load factor (table density) for + * establishing the initial table size + * @throws IllegalArgumentException if the initial capacity of + * elements is negative or the load factor is nonpositive + * + * @since 1.6 + */ + public ConcurrentHashMapV8(int initialCapacity, float loadFactor) { + this(initialCapacity, loadFactor, 1); + } + + /** + * Creates a new, empty map with an initial table size based on + * the given number of elements ({@code initialCapacity}), table + * density ({@code loadFactor}), and number of concurrently + * updating threads ({@code concurrencyLevel}). + * + * @param initialCapacity the initial capacity. The implementation + * performs internal sizing to accommodate this many elements, + * given the specified load factor. + * @param loadFactor the load factor (table density) for + * establishing the initial table size + * @param concurrencyLevel the estimated number of concurrently + * updating threads. The implementation may use this value as + * a sizing hint. + * @throws IllegalArgumentException if the initial capacity is + * negative or the load factor or concurrencyLevel are + * nonpositive + */ + public ConcurrentHashMapV8(int initialCapacity, + float loadFactor, int concurrencyLevel) { + if (!(loadFactor > 0.0f) || initialCapacity < 0 || concurrencyLevel <= 0) + throw new IllegalArgumentException(); + if (initialCapacity < concurrencyLevel) // Use at least as many bins + initialCapacity = concurrencyLevel; // as estimated threads + long size = (long)(1.0 + (long)initialCapacity / loadFactor); + int cap = (size >= (long)MAXIMUM_CAPACITY) ? + MAXIMUM_CAPACITY : tableSizeFor((int)size); + this.counter = new LongAdder(); + this.sizeCtl = cap; + } + + /** + * Creates a new {@link Set} backed by a ConcurrentHashMapV8 + * from the given type to {@code Boolean.TRUE}. + * + * @return the new set + */ + public static KeySetView newKeySet() { + return new KeySetView(new ConcurrentHashMapV8(), + Boolean.TRUE); + } + + /** + * Creates a new {@link Set} backed by a ConcurrentHashMapV8 + * from the given type to {@code Boolean.TRUE}. + * + * @param initialCapacity The implementation performs internal + * sizing to accommodate this many elements. + * @throws IllegalArgumentException if the initial capacity of + * elements is negative + * @return the new set + */ + public static KeySetView newKeySet(int initialCapacity) { + return new KeySetView(new ConcurrentHashMapV8(initialCapacity), + Boolean.TRUE); + } + + /** + * {@inheritDoc} + */ + public boolean isEmpty() { + return counter.sum() <= 0L; // ignore transient negative values + } + + /** + * {@inheritDoc} + */ + public int size() { + long n = counter.sum(); + return ((n < 0L) ? 0 : + (n > (long)Integer.MAX_VALUE) ? Integer.MAX_VALUE : + (int)n); + } + + /** + * Returns the number of mappings. This method should be used + * instead of {@link #size} because a ConcurrentHashMapV8 may + * contain more mappings than can be represented as an int. The + * value returned is a snapshot; the actual count may differ if + * there are ongoing concurrent insertions or removals. + * + * @return the number of mappings + */ + public long mappingCount() { + long n = counter.sum(); + return (n < 0L) ? 0L : n; // ignore transient negative values + } + + /** + * Returns the value to which the specified key is mapped, + * or {@code null} if this map contains no mapping for the key. + * + *

More formally, if this map contains a mapping from a key + * {@code k} to a value {@code v} such that {@code key.equals(k)}, + * then this method returns {@code v}; otherwise it returns + * {@code null}. (There can be at most one such mapping.) + * + * @throws NullPointerException if the specified key is null + */ + @SuppressWarnings("unchecked") public V get(Object key) { + if (key == null) + throw new NullPointerException(); + return (V)internalGet(key); + } + + /** + * Returns the value to which the specified key is mapped, + * or the given defaultValue if this map contains no mapping for the key. + * + * @param key the key + * @param defaultValue the value to return if this map contains + * no mapping for the given key + * @return the mapping for the key, if present; else the defaultValue + * @throws NullPointerException if the specified key is null + */ + @SuppressWarnings("unchecked") public V getValueOrDefault(Object key, V defaultValue) { + if (key == null) + throw new NullPointerException(); + V v = (V) internalGet(key); + return v == null ? defaultValue : v; + } + + /** + * Tests if the specified object is a key in this table. + * + * @param key possible key + * @return {@code true} if and only if the specified object + * is a key in this table, as determined by the + * {@code equals} method; {@code false} otherwise + * @throws NullPointerException if the specified key is null + */ + public boolean containsKey(Object key) { + if (key == null) + throw new NullPointerException(); + return internalGet(key) != null; + } + + /** + * Returns {@code true} if this map maps one or more keys to the + * specified value. Note: This method may require a full traversal + * of the map, and is much slower than method {@code containsKey}. + * + * @param value value whose presence in this map is to be tested + * @return {@code true} if this map maps one or more keys to the + * specified value + * @throws NullPointerException if the specified value is null + */ + public boolean containsValue(Object value) { + if (value == null) + throw new NullPointerException(); + Object v; + Traverser it = new Traverser(this); + while ((v = it.advance()) != null) { + if (v == value || value.equals(v)) + return true; + } + return false; + } + + public K findKey(Object value) { + if (value == null) + throw new NullPointerException(); + Object v; + Traverser it = new Traverser(this); + while ((v = it.advance()) != null) { + if (v == value || value.equals(v)) + return it.nextKey; + } + return null; + } + + /** + * Legacy method testing if some key maps into the specified value + * in this table. This method is identical in functionality to + * {@link #containsValue}, and exists solely to ensure + * full compatibility with class {@link java.util.Hashtable}, + * which supported this method prior to introduction of the + * Java Collections framework. + * + * @param value a value to search for + * @return {@code true} if and only if some key maps to the + * {@code value} argument in this table as + * determined by the {@code equals} method; + * {@code false} otherwise + * @throws NullPointerException if the specified value is null + */ + public boolean contains(Object value) { + return containsValue(value); + } + + /** + * Maps the specified key to the specified value in this table. + * Neither the key nor the value can be null. + * + *

The value can be retrieved by calling the {@code get} method + * with a key that is equal to the original key. + * + * @param key key with which the specified value is to be associated + * @param value value to be associated with the specified key + * @return the previous value associated with {@code key}, or + * {@code null} if there was no mapping for {@code key} + * @throws NullPointerException if the specified key or value is null + */ + @SuppressWarnings("unchecked") public V put(K key, V value) { + if (key == null || value == null) + throw new NullPointerException(); + return (V)internalPut(key, value); + } + + /** + * {@inheritDoc} + * + * @return the previous value associated with the specified key, + * or {@code null} if there was no mapping for the key + * @throws NullPointerException if the specified key or value is null + */ + @SuppressWarnings("unchecked") public V putIfAbsent(K key, V value) { + if (key == null || value == null) + throw new NullPointerException(); + return (V)internalPutIfAbsent(key, value); + } + + /** + * Copies all of the mappings from the specified map to this one. + * These mappings replace any mappings that this map had for any of the + * keys currently in the specified map. + * + * @param m mappings to be stored in this map + */ + public void putAll(Map m) { + internalPutAll(m); + } + + /** + * If the specified key is not already associated with a value, + * computes its value using the given mappingFunction and enters + * it into the map unless null. This is equivalent to + *

 {@code
+     * if (map.containsKey(key))
+     *   return map.get(key);
+     * value = mappingFunction.apply(key);
+     * if (value != null)
+     *   map.put(key, value);
+     * return value;}
+ * + * except that the action is performed atomically. If the + * function returns {@code null} no mapping is recorded. If the + * function itself throws an (unchecked) exception, the exception + * is rethrown to its caller, and no mapping is recorded. Some + * attempted update operations on this map by other threads may be + * blocked while computation is in progress, so the computation + * should be short and simple, and must not attempt to update any + * other mappings of this Map. The most appropriate usage is to + * construct a new object serving as an initial mapped value, or + * memoized result, as in: + * + *
 {@code
+     * map.computeIfAbsent(key, new Fun() {
+     *   public V map(K k) { return new Value(f(k)); }});}
+ * + * @param key key with which the specified value is to be associated + * @param mappingFunction the function to compute a value + * @return the current (existing or computed) value associated with + * the specified key, or null if the computed value is null + * @throws NullPointerException if the specified key or mappingFunction + * is null + * @throws IllegalStateException if the computation detectably + * attempts a recursive update to this map that would + * otherwise never complete + * @throws RuntimeException or Error if the mappingFunction does so, + * in which case the mapping is left unestablished + */ + @SuppressWarnings("unchecked") public V computeIfAbsent + (K key, Fun mappingFunction) { + if (key == null || mappingFunction == null) + throw new NullPointerException(); + return (V)internalComputeIfAbsent(key, mappingFunction); + } + + /** + * If the given key is present, computes a new mapping value given a key and + * its current mapped value. This is equivalent to + *
 {@code
+     *   if (map.containsKey(key)) {
+     *     value = remappingFunction.apply(key, map.get(key));
+     *     if (value != null)
+     *       map.put(key, value);
+     *     else
+     *       map.remove(key);
+     *   }
+     * }
+ * + * except that the action is performed atomically. If the + * function returns {@code null}, the mapping is removed. If the + * function itself throws an (unchecked) exception, the exception + * is rethrown to its caller, and the current mapping is left + * unchanged. Some attempted update operations on this map by + * other threads may be blocked while computation is in progress, + * so the computation should be short and simple, and must not + * attempt to update any other mappings of this Map. For example, + * to either create or append new messages to a value mapping: + * + * @param key key with which the specified value is to be associated + * @param remappingFunction the function to compute a value + * @return the new value associated with the specified key, or null if none + * @throws NullPointerException if the specified key or remappingFunction + * is null + * @throws IllegalStateException if the computation detectably + * attempts a recursive update to this map that would + * otherwise never complete + * @throws RuntimeException or Error if the remappingFunction does so, + * in which case the mapping is unchanged + */ + @SuppressWarnings("unchecked") public V computeIfPresent + (K key, BiFun remappingFunction) { + if (key == null || remappingFunction == null) + throw new NullPointerException(); + return (V)internalCompute(key, true, remappingFunction); + } + + /** + * Computes a new mapping value given a key and + * its current mapped value (or {@code null} if there is no current + * mapping). This is equivalent to + *
 {@code
+     *   value = remappingFunction.apply(key, map.get(key));
+     *   if (value != null)
+     *     map.put(key, value);
+     *   else
+     *     map.remove(key);
+     * }
+ * + * except that the action is performed atomically. If the + * function returns {@code null}, the mapping is removed. If the + * function itself throws an (unchecked) exception, the exception + * is rethrown to its caller, and the current mapping is left + * unchanged. Some attempted update operations on this map by + * other threads may be blocked while computation is in progress, + * so the computation should be short and simple, and must not + * attempt to update any other mappings of this Map. For example, + * to either create or append new messages to a value mapping: + * + *
 {@code
+     * Map map = ...;
+     * final String msg = ...;
+     * map.compute(key, new BiFun() {
+     *   public String apply(Key k, String v) {
+     *    return (v == null) ? msg : v + msg;});}}
+ * + * @param key key with which the specified value is to be associated + * @param remappingFunction the function to compute a value + * @return the new value associated with the specified key, or null if none + * @throws NullPointerException if the specified key or remappingFunction + * is null + * @throws IllegalStateException if the computation detectably + * attempts a recursive update to this map that would + * otherwise never complete + * @throws RuntimeException or Error if the remappingFunction does so, + * in which case the mapping is unchanged + */ + @SuppressWarnings("unchecked") public V compute + (K key, BiFun remappingFunction) { + if (key == null || remappingFunction == null) + throw new NullPointerException(); + return (V)internalCompute(key, false, remappingFunction); + } + + /** + * If the specified key is not already associated + * with a value, associate it with the given value. + * Otherwise, replace the value with the results of + * the given remapping function. This is equivalent to: + *
 {@code
+     *   if (!map.containsKey(key))
+     *     map.put(value);
+     *   else {
+     *     newValue = remappingFunction.apply(map.get(key), value);
+     *     if (value != null)
+     *       map.put(key, value);
+     *     else
+     *       map.remove(key);
+     *   }
+     * }
+ * except that the action is performed atomically. If the + * function returns {@code null}, the mapping is removed. If the + * function itself throws an (unchecked) exception, the exception + * is rethrown to its caller, and the current mapping is left + * unchanged. Some attempted update operations on this map by + * other threads may be blocked while computation is in progress, + * so the computation should be short and simple, and must not + * attempt to update any other mappings of this Map. + */ + @SuppressWarnings("unchecked") public V merge + (K key, V value, BiFun remappingFunction) { + if (key == null || value == null || remappingFunction == null) + throw new NullPointerException(); + return (V)internalMerge(key, value, remappingFunction); + } + + /** + * Removes the key (and its corresponding value) from this map. + * This method does nothing if the key is not in the map. + * + * @param key the key that needs to be removed + * @return the previous value associated with {@code key}, or + * {@code null} if there was no mapping for {@code key} + * @throws NullPointerException if the specified key is null + */ + @SuppressWarnings("unchecked") public V remove(Object key) { + if (key == null) + throw new NullPointerException(); + return (V)internalReplace(key, null, null); + } + + /** + * {@inheritDoc} + * + * @throws NullPointerException if the specified key is null + */ + public boolean remove(Object key, Object value) { + if (key == null) + throw new NullPointerException(); + if (value == null) + return false; + return internalReplace(key, null, value) != null; + } + + /** + * {@inheritDoc} + * + * @throws NullPointerException if any of the arguments are null + */ + public boolean replace(K key, V oldValue, V newValue) { + if (key == null || oldValue == null || newValue == null) + throw new NullPointerException(); + return internalReplace(key, newValue, oldValue) != null; + } + + /** + * {@inheritDoc} + * + * @return the previous value associated with the specified key, + * or {@code null} if there was no mapping for the key + * @throws NullPointerException if the specified key or value is null + */ + @SuppressWarnings("unchecked") public V replace(K key, V value) { + if (key == null || value == null) + throw new NullPointerException(); + return (V)internalReplace(key, value, null); + } + + /** + * Removes all of the mappings from this map. + */ + public void clear() { + internalClear(); + } + + /** + * Returns a {@link Set} view of the keys contained in this map. + * The set is backed by the map, so changes to the map are + * reflected in the set, and vice-versa. + * + * @return the set view + */ + public KeySetView keySet() { + KeySetView ks = keySet; + return (ks != null) ? ks : (keySet = new KeySetView(this, null)); + } + + /** + * Returns a {@link Set} view of the keys in this map, using the + * given common mapped value for any additions (i.e., {@link + * Collection#add} and {@link Collection#addAll}). This is of + * course only appropriate if it is acceptable to use the same + * value for all additions from this view. + * + * @param mappedValue the mapped value to use for any + * additions. + * @return the set view + * @throws NullPointerException if the mappedValue is null + */ + public KeySetView keySet(V mappedValue) { + if (mappedValue == null) + throw new NullPointerException(); + return new KeySetView(this, mappedValue); + } + + /** + * Returns a {@link Collection} view of the values contained in this map. + * The collection is backed by the map, so changes to the map are + * reflected in the collection, and vice-versa. + */ + public ValuesView values() { + ValuesView vs = values; + return (vs != null) ? vs : (values = new ValuesView(this)); + } + + /** + * Returns a {@link Set} view of the mappings contained in this map. + * The set is backed by the map, so changes to the map are + * reflected in the set, and vice-versa. The set supports element + * removal, which removes the corresponding mapping from the map, + * via the {@code Iterator.remove}, {@code Set.remove}, + * {@code removeAll}, {@code retainAll}, and {@code clear} + * operations. It does not support the {@code add} or + * {@code addAll} operations. + * + *

The view's {@code iterator} is a "weakly consistent" iterator + * that will never throw {@link ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + */ + public Set> entrySet() { + EntrySetView es = entrySet; + return (es != null) ? es : (entrySet = new EntrySetView(this)); + } + + /** + * Returns an enumeration of the keys in this table. + * + * @return an enumeration of the keys in this table + * @see #keySet() + */ + public Enumeration keys() { + return new KeyIterator(this); + } + + /** + * Returns an enumeration of the values in this table. + * + * @return an enumeration of the values in this table + * @see #values() + */ + public Enumeration elements() { + return new ValueIterator(this); + } + + /** + * Returns a partitionable iterator of the keys in this map. + * + * @return a partitionable iterator of the keys in this map + */ + public Spliterator keySpliterator() { + return new KeyIterator(this); + } + + /** + * Returns a partitionable iterator of the values in this map. + * + * @return a partitionable iterator of the values in this map + */ + public Spliterator valueSpliterator() { + return new ValueIterator(this); + } + + /** + * Returns a partitionable iterator of the entries in this map. + * + * @return a partitionable iterator of the entries in this map + */ + public Spliterator> entrySpliterator() { + return new EntryIterator(this); + } + + /** + * Returns the hash code value for this {@link Map}, i.e., + * the sum of, for each key-value pair in the map, + * {@code key.hashCode() ^ value.hashCode()}. + * + * @return the hash code value for this map + */ + public int hashCode() { + int h = 0; + Traverser it = new Traverser(this); + Object v; + while ((v = it.advance()) != null) { + h += it.nextKey.hashCode() ^ v.hashCode(); + } + return h; + } + + /** + * Returns a string representation of this map. The string + * representation consists of a list of key-value mappings (in no + * particular order) enclosed in braces ("{@code {}}"). Adjacent + * mappings are separated by the characters {@code ", "} (comma + * and space). Each key-value mapping is rendered as the key + * followed by an equals sign ("{@code =}") followed by the + * associated value. + * + * @return a string representation of this map + */ + public String toString() { + Traverser it = new Traverser(this); + StringBuilder sb = new StringBuilder(); + sb.append('{'); + Object v; + if ((v = it.advance()) != null) { + for (;;) { + Object k = it.nextKey; + sb.append(k == this ? "(this Map)" : k); + sb.append('='); + sb.append(v == this ? "(this Map)" : v); + if ((v = it.advance()) == null) + break; + sb.append(',').append(' '); + } + } + return sb.append('}').toString(); + } + + /** + * Compares the specified object with this map for equality. + * Returns {@code true} if the given object is a map with the same + * mappings as this map. This operation may return misleading + * results if either map is concurrently modified during execution + * of this method. + * + * @param o object to be compared for equality with this map + * @return {@code true} if the specified object is equal to this map + */ + public boolean equals(Object o) { + if (o != this) { + if (!(o instanceof Map)) + return false; + Map m = (Map) o; + Traverser it = new Traverser(this); + Object val; + while ((val = it.advance()) != null) { + Object v = m.get(it.nextKey); + if (v == null || (v != val && !v.equals(val))) + return false; + } + for (Map.Entry e : m.entrySet()) { + Object mk, mv, v; + if ((mk = e.getKey()) == null || + (mv = e.getValue()) == null || + (v = internalGet(mk)) == null || + (mv != v && !mv.equals(v))) + return false; + } + } + return true; + } + + /* ----------------Iterators -------------- */ + + @SuppressWarnings("serial") static final class KeyIterator extends Traverser + implements Spliterator, Enumeration { + KeyIterator(ConcurrentHashMapV8 map) { super(map); } + KeyIterator(Traverser it) { + super(it); + } + public KeyIterator split() { + if (nextKey != null) + throw new IllegalStateException(); + return new KeyIterator(this); + } + @SuppressWarnings("unchecked") public final K next() { + if (nextVal == null && advance() == null) + throw new NoSuchElementException(); + Object k = nextKey; + nextVal = null; + return (K) k; + } + + public final K nextElement() { return next(); } + } + + @SuppressWarnings("serial") static final class ValueIterator extends Traverser + implements Spliterator, Enumeration { + ValueIterator(ConcurrentHashMapV8 map) { super(map); } + ValueIterator(Traverser it) { + super(it); + } + public ValueIterator split() { + if (nextKey != null) + throw new IllegalStateException(); + return new ValueIterator(this); + } + + @SuppressWarnings("unchecked") public final V next() { + Object v; + if ((v = nextVal) == null && (v = advance()) == null) + throw new NoSuchElementException(); + nextVal = null; + return (V) v; + } + + public final V nextElement() { return next(); } + } + + @SuppressWarnings("serial") static final class EntryIterator extends Traverser + implements Spliterator> { + EntryIterator(ConcurrentHashMapV8 map) { super(map); } + EntryIterator(Traverser it) { + super(it); + } + public EntryIterator split() { + if (nextKey != null) + throw new IllegalStateException(); + return new EntryIterator(this); + } + + @SuppressWarnings("unchecked") public final Map.Entry next() { + Object v; + if ((v = nextVal) == null && (v = advance()) == null) + throw new NoSuchElementException(); + Object k = nextKey; + nextVal = null; + return new MapEntry((K)k, (V)v, map); + } + } + + /** + * Exported Entry for iterators + */ + static final class MapEntry implements Map.Entry { + final K key; // non-null + V val; // non-null + final ConcurrentHashMapV8 map; + MapEntry(K key, V val, ConcurrentHashMapV8 map) { + this.key = key; + this.val = val; + this.map = map; + } + public final K getKey() { return key; } + public final V getValue() { return val; } + public final int hashCode() { return key.hashCode() ^ val.hashCode(); } + public final String toString(){ return key + "=" + val; } + + public final boolean equals(Object o) { + Object k, v; Map.Entry e; + return ((o instanceof Map.Entry) && + (k = (e = (Map.Entry)o).getKey()) != null && + (v = e.getValue()) != null && + (k == key || k.equals(key)) && + (v == val || v.equals(val))); + } + + /** + * Sets our entry's value and writes through to the map. The + * value to return is somewhat arbitrary here. Since we do not + * necessarily track asynchronous changes, the most recent + * "previous" value could be different from what we return (or + * could even have been removed in which case the put will + * re-establish). We do not and cannot guarantee more. + */ + public final V setValue(V value) { + if (value == null) throw new NullPointerException(); + V v = val; + val = value; + map.put(key, value); + return v; + } + } + + /* ---------------- Serialization Support -------------- */ + + /** + * Stripped-down version of helper class used in previous version, + * declared for the sake of serialization compatibility + */ + static class Segment implements Serializable { + private static final long serialVersionUID = 2249069246763182397L; + final float loadFactor; + Segment(float lf) { this.loadFactor = lf; } + } + + /** + * Saves the state of the {@code ConcurrentHashMapV8} instance to a + * stream (i.e., serializes it). + * @param s the stream + * @serialData + * the key (Object) and value (Object) + * for each key-value mapping, followed by a null pair. + * The key-value mappings are emitted in no particular order. + */ + @SuppressWarnings("unchecked") private void writeObject(java.io.ObjectOutputStream s) + throws java.io.IOException { + if (segments == null) { // for serialization compatibility + segments = (Segment[]) + new Segment[DEFAULT_CONCURRENCY_LEVEL]; + for (int i = 0; i < segments.length; ++i) + segments[i] = new Segment(LOAD_FACTOR); + } + s.defaultWriteObject(); + Traverser it = new Traverser(this); + Object v; + while ((v = it.advance()) != null) { + s.writeObject(it.nextKey); + s.writeObject(v); + } + s.writeObject(null); + s.writeObject(null); + segments = null; // throw away + } + + /** + * Reconstitutes the instance from a stream (that is, deserializes it). + * @param s the stream + */ + @SuppressWarnings("unchecked") private void readObject(java.io.ObjectInputStream s) + throws java.io.IOException, ClassNotFoundException { + s.defaultReadObject(); + this.segments = null; // unneeded + // initialize transient final field + UNSAFE.putObjectVolatile(this, counterOffset, new LongAdder()); + + // Create all nodes, then place in table once size is known + long size = 0L; + Node p = null; + for (;;) { + K k = (K) s.readObject(); + V v = (V) s.readObject(); + if (k != null && v != null) { + int h = spread(k.hashCode()); + p = new Node(h, k, v, p); + ++size; + } + else + break; + } + if (p != null) { + boolean init = false; + int n; + if (size >= (long)(MAXIMUM_CAPACITY >>> 1)) + n = MAXIMUM_CAPACITY; + else { + int sz = (int)size; + n = tableSizeFor(sz + (sz >>> 1) + 1); + } + int sc = sizeCtl; + boolean collide = false; + if (n > sc && + UNSAFE.compareAndSwapInt(this, sizeCtlOffset, sc, -1)) { + try { + if (table == null) { + init = true; + Node[] tab = new Node[n]; + int mask = n - 1; + while (p != null) { + int j = p.hash & mask; + Node next = p.next; + Node q = p.next = tabAt(tab, j); + setTabAt(tab, j, p); + if (!collide && q != null && q.hash == p.hash) + collide = true; + p = next; + } + table = tab; + counter.add(size); + sc = n - (n >>> 2); + } + } finally { + sizeCtl = sc; + } + if (collide) { // rescan and convert to TreeBins + Node[] tab = table; + for (int i = 0; i < tab.length; ++i) { + int c = 0; + for (Node e = tabAt(tab, i); e != null; e = e.next) { + if (++c > TREE_THRESHOLD && + (e.key instanceof Comparable)) { + replaceWithTreeBin(tab, i, e.key); + break; + } + } + } + } + } + if (!init) { // Can only happen if unsafely published. + while (p != null) { + internalPut(p.key, p.val); + p = p.next; + } + } + } + } + + + // ------------------------------------------------------- + + // Sams + /** Interface describing a void action of one argument */ + public interface Action { void apply(A a); } + /** Interface describing a void action of two arguments */ + public interface BiAction { void apply(A a, B b); } + /** Interface describing a function of one argument */ + public interface Generator { T apply(); } + /** Interface describing a function mapping its argument to a double */ + public interface ObjectToDouble { double apply(A a); } + /** Interface describing a function mapping its argument to a long */ + public interface ObjectToLong { long apply(A a); } + /** Interface describing a function mapping its argument to an int */ + public interface ObjectToInt {int apply(A a); } + /** Interface describing a function mapping two arguments to a double */ + public interface ObjectByObjectToDouble { double apply(A a, B b); } + /** Interface describing a function mapping two arguments to a long */ + public interface ObjectByObjectToLong { long apply(A a, B b); } + /** Interface describing a function mapping two arguments to an int */ + public interface ObjectByObjectToInt {int apply(A a, B b); } + /** Interface describing a function mapping a double to a double */ + public interface DoubleToDouble { double apply(double a); } + /** Interface describing a function mapping a long to a long */ + public interface LongToLong { long apply(long a); } + /** Interface describing a function mapping an int to an int */ + public interface IntToInt { int apply(int a); } + /** Interface describing a function mapping two doubles to a double */ + public interface DoubleByDoubleToDouble { double apply(double a, double b); } + /** Interface describing a function mapping two longs to a long */ + public interface LongByLongToLong { long apply(long a, long b); } + /** Interface describing a function mapping two ints to an int */ + public interface IntByIntToInt { int apply(int a, int b); } + + + /* ----------------Views -------------- */ + + /** + * Base class for views. + */ + static abstract class CHMView { + final ConcurrentHashMapV8 map; + CHMView(ConcurrentHashMapV8 map) { this.map = map; } + + /** + * Returns the map backing this view. + * + * @return the map backing this view + */ + public ConcurrentHashMapV8 getMap() { return map; } + + public final int size() { return map.size(); } + public final boolean isEmpty() { return map.isEmpty(); } + public final void clear() { map.clear(); } + + // implementations below rely on concrete classes supplying these + abstract public Iterator iterator(); + abstract public boolean contains(Object o); + abstract public boolean remove(Object o); + + private static final String oomeMsg = "Required array size too large"; + + public final Object[] toArray() { + long sz = map.mappingCount(); + if (sz > (long)(MAX_ARRAY_SIZE)) + throw new OutOfMemoryError(oomeMsg); + int n = (int)sz; + Object[] r = new Object[n]; + int i = 0; + Iterator it = iterator(); + while (it.hasNext()) { + if (i == n) { + if (n >= MAX_ARRAY_SIZE) + throw new OutOfMemoryError(oomeMsg); + if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1) + n = MAX_ARRAY_SIZE; + else + n += (n >>> 1) + 1; + r = Arrays.copyOf(r, n); + } + r[i++] = it.next(); + } + return (i == n) ? r : Arrays.copyOf(r, i); + } + + @SuppressWarnings("unchecked") public final T[] toArray(T[] a) { + long sz = map.mappingCount(); + if (sz > (long)(MAX_ARRAY_SIZE)) + throw new OutOfMemoryError(oomeMsg); + int m = (int)sz; + T[] r = (a.length >= m) ? a : + (T[])java.lang.reflect.Array + .newInstance(a.getClass().getComponentType(), m); + int n = r.length; + int i = 0; + Iterator it = iterator(); + while (it.hasNext()) { + if (i == n) { + if (n >= MAX_ARRAY_SIZE) + throw new OutOfMemoryError(oomeMsg); + if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1) + n = MAX_ARRAY_SIZE; + else + n += (n >>> 1) + 1; + r = Arrays.copyOf(r, n); + } + r[i++] = (T)it.next(); + } + if (a == r && i < n) { + r[i] = null; // null-terminate + return r; + } + return (i == n) ? r : Arrays.copyOf(r, i); + } + + public final int hashCode() { + int h = 0; + for (Iterator it = iterator(); it.hasNext();) + h += it.next().hashCode(); + return h; + } + + public final String toString() { + StringBuilder sb = new StringBuilder(); + sb.append('['); + Iterator it = iterator(); + if (it.hasNext()) { + for (;;) { + Object e = it.next(); + sb.append(e == this ? "(this Collection)" : e); + if (!it.hasNext()) + break; + sb.append(',').append(' '); + } + } + return sb.append(']').toString(); + } + + public final boolean containsAll(Collection c) { + if (c != this) { + for (Iterator it = c.iterator(); it.hasNext();) { + Object e = it.next(); + if (e == null || !contains(e)) + return false; + } + } + return true; + } + + public final boolean removeAll(Collection c) { + boolean modified = false; + for (Iterator it = iterator(); it.hasNext();) { + if (c.contains(it.next())) { + it.remove(); + modified = true; + } + } + return modified; + } + + public final boolean retainAll(Collection c) { + boolean modified = false; + for (Iterator it = iterator(); it.hasNext();) { + if (!c.contains(it.next())) { + it.remove(); + modified = true; + } + } + return modified; + } + + } + + /** + * A view of a ConcurrentHashMapV8 as a {@link Set} of keys, in + * which additions may optionally be enabled by mapping to a + * common value. This class cannot be directly instantiated. See + * {@link #keySet}, {@link #keySet(Object)}, {@link #newKeySet()}, + * {@link #newKeySet(int)}. + */ + public static class KeySetView extends CHMView implements Set, java.io.Serializable { + private static final long serialVersionUID = 7249069246763182397L; + private final V value; + KeySetView(ConcurrentHashMapV8 map, V value) { // non-public + super(map); + this.value = value; + } + + /** + * Returns the default mapped value for additions, + * or {@code null} if additions are not supported. + * + * @return the default mapped value for additions, or {@code null} + * if not supported. + */ + public V getMappedValue() { return value; } + + // implement Set API + + public boolean contains(Object o) { return map.containsKey(o); } + public boolean remove(Object o) { return map.remove(o) != null; } + + /** + * Returns a "weakly consistent" iterator that will never + * throw {@link ConcurrentModificationException}, and + * guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not + * guaranteed to) reflect any modifications subsequent to + * construction. + * + * @return an iterator over the keys of this map + */ + public Iterator iterator() { return new KeyIterator(map); } + public boolean add(K e) { + V v; + if ((v = value) == null) + throw new UnsupportedOperationException(); + if (e == null) + throw new NullPointerException(); + return map.internalPutIfAbsent(e, v) == null; + } + public boolean addAll(Collection c) { + boolean added = false; + V v; + if ((v = value) == null) + throw new UnsupportedOperationException(); + for (K e : c) { + if (e == null) + throw new NullPointerException(); + if (map.internalPutIfAbsent(e, v) == null) + added = true; + } + return added; + } + public boolean equals(Object o) { + Set c; + return ((o instanceof Set) && + ((c = (Set)o) == this || + (containsAll(c) && c.containsAll(this)))); + } + } + + /** + * A view of a ConcurrentHashMapV8 as a {@link Collection} of + * values, in which additions are disabled. This class cannot be + * directly instantiated. See {@link #values}, + * + *

The view's {@code iterator} is a "weakly consistent" iterator + * that will never throw {@link ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + */ + public static final class ValuesView extends CHMView + implements Collection { + ValuesView(ConcurrentHashMapV8 map) { super(map); } + public final boolean contains(Object o) { return map.containsValue(o); } + public final boolean remove(Object o) { + if (o != null) { + Iterator it = new ValueIterator(map); + while (it.hasNext()) { + if (o.equals(it.next())) { + it.remove(); + return true; + } + } + } + return false; + } + + /** + * Returns a "weakly consistent" iterator that will never + * throw {@link ConcurrentModificationException}, and + * guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not + * guaranteed to) reflect any modifications subsequent to + * construction. + * + * @return an iterator over the values of this map + */ + public final Iterator iterator() { + return new ValueIterator(map); + } + public final boolean add(V e) { + throw new UnsupportedOperationException(); + } + public final boolean addAll(Collection c) { + throw new UnsupportedOperationException(); + } + } + + /** + * A view of a ConcurrentHashMapV8 as a {@link Set} of (key, value) + * entries. This class cannot be directly instantiated. See + * {@link #entrySet}. + */ + public static final class EntrySetView extends CHMView + implements Set> { + EntrySetView(ConcurrentHashMapV8 map) { super(map); } + public final boolean contains(Object o) { + Object k, v, r; Map.Entry e; + return ((o instanceof Map.Entry) && + (k = (e = (Map.Entry)o).getKey()) != null && + (r = map.get(k)) != null && + (v = e.getValue()) != null && + (v == r || v.equals(r))); + } + public final boolean remove(Object o) { + Object k, v; Map.Entry e; + return ((o instanceof Map.Entry) && + (k = (e = (Map.Entry)o).getKey()) != null && + (v = e.getValue()) != null && + map.remove(k, v)); + } + + /** + * Returns a "weakly consistent" iterator that will never + * throw {@link ConcurrentModificationException}, and + * guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not + * guaranteed to) reflect any modifications subsequent to + * construction. + * + * @return an iterator over the entries of this map + */ + public final Iterator> iterator() { + return new EntryIterator(map); + } + + public final boolean add(Entry e) { + K key = e.getKey(); + V value = e.getValue(); + if (key == null || value == null) + throw new NullPointerException(); + return map.internalPut(key, value) == null; + } + public final boolean addAll(Collection> c) { + boolean added = false; + for (Entry e : c) { + if (add(e)) + added = true; + } + return added; + } + public boolean equals(Object o) { + Set c; + return ((o instanceof Set) && + ((c = (Set)o) == this || + (containsAll(c) && c.containsAll(this)))); + } + } + + // Unsafe mechanics + private static final sun.misc.Unsafe UNSAFE; + private static final long counterOffset; + private static final long sizeCtlOffset; + private static final long ABASE; + private static final int ASHIFT; + + static { + int ss; + try { + UNSAFE = getUnsafe(); + Class k = ConcurrentHashMapV8.class; + counterOffset = UNSAFE.objectFieldOffset + (k.getDeclaredField("counter")); + sizeCtlOffset = UNSAFE.objectFieldOffset + (k.getDeclaredField("sizeCtl")); + Class sc = Node[].class; + ABASE = UNSAFE.arrayBaseOffset(sc); + ss = UNSAFE.arrayIndexScale(sc); + } catch (Exception e) { + throw new Error(e); + } + if ((ss & (ss-1)) != 0) + throw new Error("data type scale not a power of two"); + ASHIFT = 31 - Integer.numberOfLeadingZeros(ss); + } + + /** + * Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package. + * Replace with a simple call to Unsafe.getUnsafe when integrating + * into a jdk. + * + * @return a sun.misc.Unsafe + */ + private static sun.misc.Unsafe getUnsafe() { + try { + return sun.misc.Unsafe.getUnsafe(); + } catch (SecurityException se) { + try { + return java.security.AccessController.doPrivileged + (new java.security + .PrivilegedExceptionAction() { + public sun.misc.Unsafe run() throws Exception { + java.lang.reflect.Field f = sun.misc + .Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + return (sun.misc.Unsafe) f.get(null); + }}); + } catch (java.security.PrivilegedActionException e) { + throw new RuntimeException("Could not initialize intrinsics", + e.getCause()); + } + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/LongAdder.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/LongAdder.java new file mode 100644 index 00000000..47a923c8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/LongAdder.java @@ -0,0 +1,203 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// This is based on 1.9 version. + +package com.concurrent_ruby.ext.jsr166e; +import java.util.concurrent.atomic.AtomicLong; +import java.io.IOException; +import java.io.Serializable; +import java.io.ObjectInputStream; + +/** + * One or more variables that together maintain an initially zero + * {@code long} sum. When updates (method {@link #add}) are contended + * across threads, the set of variables may grow dynamically to reduce + * contention. Method {@link #sum} (or, equivalently, {@link + * #longValue}) returns the current total combined across the + * variables maintaining the sum. + * + *

This class is usually preferable to {@link AtomicLong} when + * multiple threads update a common sum that is used for purposes such + * as collecting statistics, not for fine-grained synchronization + * control. Under low update contention, the two classes have similar + * characteristics. But under high contention, expected throughput of + * this class is significantly higher, at the expense of higher space + * consumption. + * + *

This class extends {@link Number}, but does not define + * methods such as {@code hashCode} and {@code compareTo} because + * instances are expected to be mutated, and so are not useful as + * collection keys. + * + *

jsr166e note: This class is targeted to be placed in + * java.util.concurrent.atomic. + * + * @since 1.8 + * @author Doug Lea + */ +public class LongAdder extends Striped64 implements Serializable { + private static final long serialVersionUID = 7249069246863182397L; + + /** + * Version of plus for use in retryUpdate + */ + final long fn(long v, long x) { return v + x; } + + /** + * Creates a new adder with initial sum of zero. + */ + public LongAdder() { + } + + /** + * Adds the given value. + * + * @param x the value to add + */ + public void add(long x) { + Cell[] as; long b, v; HashCode hc; Cell a; int n; + if ((as = cells) != null || !casBase(b = base, b + x)) { + boolean uncontended = true; + int h = (hc = threadHashCode.get()).code; + if (as == null || (n = as.length) < 1 || + (a = as[(n - 1) & h]) == null || + !(uncontended = a.cas(v = a.value, v + x))) + retryUpdate(x, hc, uncontended); + } + } + + /** + * Equivalent to {@code add(1)}. + */ + public void increment() { + add(1L); + } + + /** + * Equivalent to {@code add(-1)}. + */ + public void decrement() { + add(-1L); + } + + /** + * Returns the current sum. The returned value is NOT an + * atomic snapshot: Invocation in the absence of concurrent + * updates returns an accurate result, but concurrent updates that + * occur while the sum is being calculated might not be + * incorporated. + * + * @return the sum + */ + public long sum() { + long sum = base; + Cell[] as = cells; + if (as != null) { + int n = as.length; + for (int i = 0; i < n; ++i) { + Cell a = as[i]; + if (a != null) + sum += a.value; + } + } + return sum; + } + + /** + * Resets variables maintaining the sum to zero. This method may + * be a useful alternative to creating a new adder, but is only + * effective if there are no concurrent updates. Because this + * method is intrinsically racy, it should only be used when it is + * known that no threads are concurrently updating. + */ + public void reset() { + internalReset(0L); + } + + /** + * Equivalent in effect to {@link #sum} followed by {@link + * #reset}. This method may apply for example during quiescent + * points between multithreaded computations. If there are + * updates concurrent with this method, the returned value is + * not guaranteed to be the final value occurring before + * the reset. + * + * @return the sum + */ + public long sumThenReset() { + long sum = base; + Cell[] as = cells; + base = 0L; + if (as != null) { + int n = as.length; + for (int i = 0; i < n; ++i) { + Cell a = as[i]; + if (a != null) { + sum += a.value; + a.value = 0L; + } + } + } + return sum; + } + + /** + * Returns the String representation of the {@link #sum}. + * @return the String representation of the {@link #sum} + */ + public String toString() { + return Long.toString(sum()); + } + + /** + * Equivalent to {@link #sum}. + * + * @return the sum + */ + public long longValue() { + return sum(); + } + + /** + * Returns the {@link #sum} as an {@code int} after a narrowing + * primitive conversion. + */ + public int intValue() { + return (int)sum(); + } + + /** + * Returns the {@link #sum} as a {@code float} + * after a widening primitive conversion. + */ + public float floatValue() { + return (float)sum(); + } + + /** + * Returns the {@link #sum} as a {@code double} after a widening + * primitive conversion. + */ + public double doubleValue() { + return (double)sum(); + } + + private void writeObject(java.io.ObjectOutputStream s) + throws java.io.IOException { + s.defaultWriteObject(); + s.writeLong(sum()); + } + + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException { + s.defaultReadObject(); + busy = 0; + cells = null; + base = s.readLong(); + } + +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/Striped64.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/Striped64.java new file mode 100644 index 00000000..93a277fb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/Striped64.java @@ -0,0 +1,342 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// This is based on 1.5 version. + +package com.concurrent_ruby.ext.jsr166e; +import java.util.Random; + +/** + * A package-local class holding common representation and mechanics + * for classes supporting dynamic striping on 64bit values. The class + * extends Number so that concrete subclasses must publicly do so. + */ +abstract class Striped64 extends Number { + /* + * This class maintains a lazily-initialized table of atomically + * updated variables, plus an extra "base" field. The table size + * is a power of two. Indexing uses masked per-thread hash codes. + * Nearly all declarations in this class are package-private, + * accessed directly by subclasses. + * + * Table entries are of class Cell; a variant of AtomicLong padded + * to reduce cache contention on most processors. Padding is + * overkill for most Atomics because they are usually irregularly + * scattered in memory and thus don't interfere much with each + * other. But Atomic objects residing in arrays will tend to be + * placed adjacent to each other, and so will most often share + * cache lines (with a huge negative performance impact) without + * this precaution. + * + * In part because Cells are relatively large, we avoid creating + * them until they are needed. When there is no contention, all + * updates are made to the base field. Upon first contention (a + * failed CAS on base update), the table is initialized to size 2. + * The table size is doubled upon further contention until + * reaching the nearest power of two greater than or equal to the + * number of CPUS. Table slots remain empty (null) until they are + * needed. + * + * A single spinlock ("busy") is used for initializing and + * resizing the table, as well as populating slots with new Cells. + * There is no need for a blocking lock: When the lock is not + * available, threads try other slots (or the base). During these + * retries, there is increased contention and reduced locality, + * which is still better than alternatives. + * + * Per-thread hash codes are initialized to random values. + * Contention and/or table collisions are indicated by failed + * CASes when performing an update operation (see method + * retryUpdate). Upon a collision, if the table size is less than + * the capacity, it is doubled in size unless some other thread + * holds the lock. If a hashed slot is empty, and lock is + * available, a new Cell is created. Otherwise, if the slot + * exists, a CAS is tried. Retries proceed by "double hashing", + * using a secondary hash (Marsaglia XorShift) to try to find a + * free slot. + * + * The table size is capped because, when there are more threads + * than CPUs, supposing that each thread were bound to a CPU, + * there would exist a perfect hash function mapping threads to + * slots that eliminates collisions. When we reach capacity, we + * search for this mapping by randomly varying the hash codes of + * colliding threads. Because search is random, and collisions + * only become known via CAS failures, convergence can be slow, + * and because threads are typically not bound to CPUS forever, + * may not occur at all. However, despite these limitations, + * observed contention rates are typically low in these cases. + * + * It is possible for a Cell to become unused when threads that + * once hashed to it terminate, as well as in the case where + * doubling the table causes no thread to hash to it under + * expanded mask. We do not try to detect or remove such cells, + * under the assumption that for long-running instances, observed + * contention levels will recur, so the cells will eventually be + * needed again; and for short-lived ones, it does not matter. + */ + + /** + * Padded variant of AtomicLong supporting only raw accesses plus CAS. + * The value field is placed between pads, hoping that the JVM doesn't + * reorder them. + * + * JVM intrinsics note: It would be possible to use a release-only + * form of CAS here, if it were provided. + */ + static final class Cell { + volatile long p0, p1, p2, p3, p4, p5, p6; + volatile long value; + volatile long q0, q1, q2, q3, q4, q5, q6; + Cell(long x) { value = x; } + + final boolean cas(long cmp, long val) { + return UNSAFE.compareAndSwapLong(this, valueOffset, cmp, val); + } + + // Unsafe mechanics + private static final sun.misc.Unsafe UNSAFE; + private static final long valueOffset; + static { + try { + UNSAFE = getUnsafe(); + Class ak = Cell.class; + valueOffset = UNSAFE.objectFieldOffset + (ak.getDeclaredField("value")); + } catch (Exception e) { + throw new Error(e); + } + } + + } + + /** + * Holder for the thread-local hash code. The code is initially + * random, but may be set to a different value upon collisions. + */ + static final class HashCode { + static final Random rng = new Random(); + int code; + HashCode() { + int h = rng.nextInt(); // Avoid zero to allow xorShift rehash + code = (h == 0) ? 1 : h; + } + } + + /** + * The corresponding ThreadLocal class + */ + static final class ThreadHashCode extends ThreadLocal { + public HashCode initialValue() { return new HashCode(); } + } + + /** + * Static per-thread hash codes. Shared across all instances to + * reduce ThreadLocal pollution and because adjustments due to + * collisions in one table are likely to be appropriate for + * others. + */ + static final ThreadHashCode threadHashCode = new ThreadHashCode(); + + /** Number of CPUS, to place bound on table size */ + static final int NCPU = Runtime.getRuntime().availableProcessors(); + + /** + * Table of cells. When non-null, size is a power of 2. + */ + transient volatile Cell[] cells; + + /** + * Base value, used mainly when there is no contention, but also as + * a fallback during table initialization races. Updated via CAS. + */ + transient volatile long base; + + /** + * Spinlock (locked via CAS) used when resizing and/or creating Cells. + */ + transient volatile int busy; + + /** + * Package-private default constructor + */ + Striped64() { + } + + /** + * CASes the base field. + */ + final boolean casBase(long cmp, long val) { + return UNSAFE.compareAndSwapLong(this, baseOffset, cmp, val); + } + + /** + * CASes the busy field from 0 to 1 to acquire lock. + */ + final boolean casBusy() { + return UNSAFE.compareAndSwapInt(this, busyOffset, 0, 1); + } + + /** + * Computes the function of current and new value. Subclasses + * should open-code this update function for most uses, but the + * virtualized form is needed within retryUpdate. + * + * @param currentValue the current value (of either base or a cell) + * @param newValue the argument from a user update call + * @return result of the update function + */ + abstract long fn(long currentValue, long newValue); + + /** + * Handles cases of updates involving initialization, resizing, + * creating new Cells, and/or contention. See above for + * explanation. This method suffers the usual non-modularity + * problems of optimistic retry code, relying on rechecked sets of + * reads. + * + * @param x the value + * @param hc the hash code holder + * @param wasUncontended false if CAS failed before call + */ + final void retryUpdate(long x, HashCode hc, boolean wasUncontended) { + int h = hc.code; + boolean collide = false; // True if last slot nonempty + for (;;) { + Cell[] as; Cell a; int n; long v; + if ((as = cells) != null && (n = as.length) > 0) { + if ((a = as[(n - 1) & h]) == null) { + if (busy == 0) { // Try to attach new Cell + Cell r = new Cell(x); // Optimistically create + if (busy == 0 && casBusy()) { + boolean created = false; + try { // Recheck under lock + Cell[] rs; int m, j; + if ((rs = cells) != null && + (m = rs.length) > 0 && + rs[j = (m - 1) & h] == null) { + rs[j] = r; + created = true; + } + } finally { + busy = 0; + } + if (created) + break; + continue; // Slot is now non-empty + } + } + collide = false; + } + else if (!wasUncontended) // CAS already known to fail + wasUncontended = true; // Continue after rehash + else if (a.cas(v = a.value, fn(v, x))) + break; + else if (n >= NCPU || cells != as) + collide = false; // At max size or stale + else if (!collide) + collide = true; + else if (busy == 0 && casBusy()) { + try { + if (cells == as) { // Expand table unless stale + Cell[] rs = new Cell[n << 1]; + for (int i = 0; i < n; ++i) + rs[i] = as[i]; + cells = rs; + } + } finally { + busy = 0; + } + collide = false; + continue; // Retry with expanded table + } + h ^= h << 13; // Rehash + h ^= h >>> 17; + h ^= h << 5; + } + else if (busy == 0 && cells == as && casBusy()) { + boolean init = false; + try { // Initialize table + if (cells == as) { + Cell[] rs = new Cell[2]; + rs[h & 1] = new Cell(x); + cells = rs; + init = true; + } + } finally { + busy = 0; + } + if (init) + break; + } + else if (casBase(v = base, fn(v, x))) + break; // Fall back on using base + } + hc.code = h; // Record index for next time + } + + + /** + * Sets base and all cells to the given value. + */ + final void internalReset(long initialValue) { + Cell[] as = cells; + base = initialValue; + if (as != null) { + int n = as.length; + for (int i = 0; i < n; ++i) { + Cell a = as[i]; + if (a != null) + a.value = initialValue; + } + } + } + + // Unsafe mechanics + private static final sun.misc.Unsafe UNSAFE; + private static final long baseOffset; + private static final long busyOffset; + static { + try { + UNSAFE = getUnsafe(); + Class sk = Striped64.class; + baseOffset = UNSAFE.objectFieldOffset + (sk.getDeclaredField("base")); + busyOffset = UNSAFE.objectFieldOffset + (sk.getDeclaredField("busy")); + } catch (Exception e) { + throw new Error(e); + } + } + + /** + * Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package. + * Replace with a simple call to Unsafe.getUnsafe when integrating + * into a jdk. + * + * @return a sun.misc.Unsafe + */ + private static sun.misc.Unsafe getUnsafe() { + try { + return sun.misc.Unsafe.getUnsafe(); + } catch (SecurityException se) { + try { + return java.security.AccessController.doPrivileged + (new java.security + .PrivilegedExceptionAction() { + public sun.misc.Unsafe run() throws Exception { + java.lang.reflect.Field f = sun.misc + .Unsafe.class.getDeclaredField("theUnsafe"); + f.setAccessible(true); + return (sun.misc.Unsafe) f.get(null); + }}); + } catch (java.security.PrivilegedActionException e) { + throw new RuntimeException("Could not initialize intrinsics", + e.getCause()); + } + } + } + +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/ConcurrentHashMapV8.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/ConcurrentHashMapV8.java new file mode 100644 index 00000000..a4e73ea1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/ConcurrentHashMapV8.java @@ -0,0 +1,3800 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// This is based on the 1.79 version. + +package com.concurrent_ruby.ext.jsr166e.nounsafe; + +import org.jruby.RubyClass; +import org.jruby.RubyNumeric; +import org.jruby.RubyObject; +import org.jruby.exceptions.RaiseException; +import com.concurrent_ruby.ext.jsr166e.ConcurrentHashMap; +import com.concurrent_ruby.ext.jsr166y.ThreadLocalRandom; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.builtin.IRubyObject; + +import java.util.Arrays; +import java.util.Map; +import java.util.Set; +import java.util.Collection; +import java.util.Hashtable; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Enumeration; +import java.util.ConcurrentModificationException; +import java.util.NoSuchElementException; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +import java.util.concurrent.atomic.AtomicReferenceArray; +import java.util.concurrent.locks.AbstractQueuedSynchronizer; + +import java.io.Serializable; + +/** + * A hash table supporting full concurrency of retrievals and + * high expected concurrency for updates. This class obeys the + * same functional specification as {@link java.util.Hashtable}, and + * includes versions of methods corresponding to each method of + * {@code Hashtable}. However, even though all operations are + * thread-safe, retrieval operations do not entail locking, + * and there is not any support for locking the entire table + * in a way that prevents all access. This class is fully + * interoperable with {@code Hashtable} in programs that rely on its + * thread safety but not on its synchronization details. + * + *

Retrieval operations (including {@code get}) generally do not + * block, so may overlap with update operations (including {@code put} + * and {@code remove}). Retrievals reflect the results of the most + * recently completed update operations holding upon their + * onset. (More formally, an update operation for a given key bears a + * happens-before relation with any (non-null) retrieval for + * that key reporting the updated value.) For aggregate operations + * such as {@code putAll} and {@code clear}, concurrent retrievals may + * reflect insertion or removal of only some entries. Similarly, + * Iterators and Enumerations return elements reflecting the state of + * the hash table at some point at or since the creation of the + * iterator/enumeration. They do not throw {@link + * ConcurrentModificationException}. However, iterators are designed + * to be used by only one thread at a time. Bear in mind that the + * results of aggregate status methods including {@code size}, {@code + * isEmpty}, and {@code containsValue} are typically useful only when + * a map is not undergoing concurrent updates in other threads. + * Otherwise the results of these methods reflect transient states + * that may be adequate for monitoring or estimation purposes, but not + * for program control. + * + *

The table is dynamically expanded when there are too many + * collisions (i.e., keys that have distinct hash codes but fall into + * the same slot modulo the table size), with the expected average + * effect of maintaining roughly two bins per mapping (corresponding + * to a 0.75 load factor threshold for resizing). There may be much + * variance around this average as mappings are added and removed, but + * overall, this maintains a commonly accepted time/space tradeoff for + * hash tables. However, resizing this or any other kind of hash + * table may be a relatively slow operation. When possible, it is a + * good idea to provide a size estimate as an optional {@code + * initialCapacity} constructor argument. An additional optional + * {@code loadFactor} constructor argument provides a further means of + * customizing initial table capacity by specifying the table density + * to be used in calculating the amount of space to allocate for the + * given number of elements. Also, for compatibility with previous + * versions of this class, constructors may optionally specify an + * expected {@code concurrencyLevel} as an additional hint for + * internal sizing. Note that using many keys with exactly the same + * {@code hashCode()} is a sure way to slow down performance of any + * hash table. + * + *

A {@link Set} projection of a ConcurrentHashMapV8 may be created + * (using {@link #newKeySet()} or {@link #newKeySet(int)}), or viewed + * (using {@link #keySet(Object)} when only keys are of interest, and the + * mapped values are (perhaps transiently) not used or all take the + * same mapping value. + * + *

A ConcurrentHashMapV8 can be used as scalable frequency map (a + * form of histogram or multiset) by using {@link LongAdder} values + * and initializing via {@link #computeIfAbsent}. For example, to add + * a count to a {@code ConcurrentHashMapV8 freqs}, you + * can use {@code freqs.computeIfAbsent(k -> new + * LongAdder()).increment();} + * + *

This class and its views and iterators implement all of the + * optional methods of the {@link Map} and {@link Iterator} + * interfaces. + * + *

Like {@link Hashtable} but unlike {@link HashMap}, this class + * does not allow {@code null} to be used as a key or value. + * + *

ConcurrentHashMapV8s support parallel operations using the {@link + * ForkJoinPool#commonPool}. (Tasks that may be used in other contexts + * are available in class {@link ForkJoinTasks}). These operations are + * designed to be safely, and often sensibly, applied even with maps + * that are being concurrently updated by other threads; for example, + * when computing a snapshot summary of the values in a shared + * registry. There are three kinds of operation, each with four + * forms, accepting functions with Keys, Values, Entries, and (Key, + * Value) arguments and/or return values. (The first three forms are + * also available via the {@link #keySet()}, {@link #values()} and + * {@link #entrySet()} views). Because the elements of a + * ConcurrentHashMapV8 are not ordered in any particular way, and may be + * processed in different orders in different parallel executions, the + * correctness of supplied functions should not depend on any + * ordering, or on any other objects or values that may transiently + * change while computation is in progress; and except for forEach + * actions, should ideally be side-effect-free. + * + *

+ * + *

The concurrency properties of bulk operations follow + * from those of ConcurrentHashMapV8: Any non-null result returned + * from {@code get(key)} and related access methods bears a + * happens-before relation with the associated insertion or + * update. The result of any bulk operation reflects the + * composition of these per-element relations (but is not + * necessarily atomic with respect to the map as a whole unless it + * is somehow known to be quiescent). Conversely, because keys + * and values in the map are never null, null serves as a reliable + * atomic indicator of the current lack of any result. To + * maintain this property, null serves as an implicit basis for + * all non-scalar reduction operations. For the double, long, and + * int versions, the basis should be one that, when combined with + * any other value, returns that other value (more formally, it + * should be the identity element for the reduction). Most common + * reductions have these properties; for example, computing a sum + * with basis 0 or a minimum with basis MAX_VALUE. + * + *

Search and transformation functions provided as arguments + * should similarly return null to indicate the lack of any result + * (in which case it is not used). In the case of mapped + * reductions, this also enables transformations to serve as + * filters, returning null (or, in the case of primitive + * specializations, the identity basis) if the element should not + * be combined. You can create compound transformations and + * filterings by composing them yourself under this "null means + * there is nothing there now" rule before using them in search or + * reduce operations. + * + *

Methods accepting and/or returning Entry arguments maintain + * key-value associations. They may be useful for example when + * finding the key for the greatest value. Note that "plain" Entry + * arguments can be supplied using {@code new + * AbstractMap.SimpleEntry(k,v)}. + * + *

Bulk operations may complete abruptly, throwing an + * exception encountered in the application of a supplied + * function. Bear in mind when handling such exceptions that other + * concurrently executing functions could also have thrown + * exceptions, or would have done so if the first exception had + * not occurred. + * + *

Parallel speedups for bulk operations compared to sequential + * processing are common but not guaranteed. Operations involving + * brief functions on small maps may execute more slowly than + * sequential loops if the underlying work to parallelize the + * computation is more expensive than the computation itself. + * Similarly, parallelization may not lead to much actual parallelism + * if all processors are busy performing unrelated tasks. + * + *

All arguments to all task methods must be non-null. + * + *

jsr166e note: During transition, this class + * uses nested functional interfaces with different names but the + * same forms as those expected for JDK8. + * + *

This class is a member of the + * + * Java Collections Framework. + * + * @since 1.5 + * @author Doug Lea + * @param the type of keys maintained by this map + * @param the type of mapped values + */ +public class ConcurrentHashMapV8 + implements ConcurrentMap, Serializable, ConcurrentHashMap { + private static final long serialVersionUID = 7249069246763182397L; + + /** + * A partitionable iterator. A Spliterator can be traversed + * directly, but can also be partitioned (before traversal) by + * creating another Spliterator that covers a non-overlapping + * portion of the elements, and so may be amenable to parallel + * execution. + * + *

This interface exports a subset of expected JDK8 + * functionality. + * + *

Sample usage: Here is one (of the several) ways to compute + * the sum of the values held in a map using the ForkJoin + * framework. As illustrated here, Spliterators are well suited to + * designs in which a task repeatedly splits off half its work + * into forked subtasks until small enough to process directly, + * and then joins these subtasks. Variants of this style can also + * be used in completion-based designs. + * + *

+     * {@code ConcurrentHashMapV8 m = ...
+     * // split as if have 8 * parallelism, for load balance
+     * int n = m.size();
+     * int p = aForkJoinPool.getParallelism() * 8;
+     * int split = (n < p)? n : p;
+     * long sum = aForkJoinPool.invoke(new SumValues(m.valueSpliterator(), split, null));
+     * // ...
+     * static class SumValues extends RecursiveTask {
+     *   final Spliterator s;
+     *   final int split;             // split while > 1
+     *   final SumValues nextJoin;    // records forked subtasks to join
+     *   SumValues(Spliterator s, int depth, SumValues nextJoin) {
+     *     this.s = s; this.depth = depth; this.nextJoin = nextJoin;
+     *   }
+     *   public Long compute() {
+     *     long sum = 0;
+     *     SumValues subtasks = null; // fork subtasks
+     *     for (int s = split >>> 1; s > 0; s >>>= 1)
+     *       (subtasks = new SumValues(s.split(), s, subtasks)).fork();
+     *     while (s.hasNext())        // directly process remaining elements
+     *       sum += s.next();
+     *     for (SumValues t = subtasks; t != null; t = t.nextJoin)
+     *       sum += t.join();         // collect subtask results
+     *     return sum;
+     *   }
+     * }
+     * }
+ */ + public static interface Spliterator extends Iterator { + /** + * Returns a Spliterator covering approximately half of the + * elements, guaranteed not to overlap with those subsequently + * returned by this Spliterator. After invoking this method, + * the current Spliterator will not produce any of + * the elements of the returned Spliterator, but the two + * Spliterators together will produce all of the elements that + * would have been produced by this Spliterator had this + * method not been called. The exact number of elements + * produced by the returned Spliterator is not guaranteed, and + * may be zero (i.e., with {@code hasNext()} reporting {@code + * false}) if this Spliterator cannot be further split. + * + * @return a Spliterator covering approximately half of the + * elements + * @throws IllegalStateException if this Spliterator has + * already commenced traversing elements + */ + Spliterator split(); + } + + + /* + * Overview: + * + * The primary design goal of this hash table is to maintain + * concurrent readability (typically method get(), but also + * iterators and related methods) while minimizing update + * contention. Secondary goals are to keep space consumption about + * the same or better than java.util.HashMap, and to support high + * initial insertion rates on an empty table by many threads. + * + * Each key-value mapping is held in a Node. Because Node fields + * can contain special values, they are defined using plain Object + * types. Similarly in turn, all internal methods that use them + * work off Object types. And similarly, so do the internal + * methods of auxiliary iterator and view classes. All public + * generic typed methods relay in/out of these internal methods, + * supplying null-checks and casts as needed. This also allows + * many of the public methods to be factored into a smaller number + * of internal methods (although sadly not so for the five + * variants of put-related operations). The validation-based + * approach explained below leads to a lot of code sprawl because + * retry-control precludes factoring into smaller methods. + * + * The table is lazily initialized to a power-of-two size upon the + * first insertion. Each bin in the table normally contains a + * list of Nodes (most often, the list has only zero or one Node). + * Table accesses require volatile/atomic reads, writes, and + * CASes. Because there is no other way to arrange this without + * adding further indirections, we use intrinsics + * (sun.misc.Unsafe) operations. The lists of nodes within bins + * are always accurately traversable under volatile reads, so long + * as lookups check hash code and non-nullness of value before + * checking key equality. + * + * We use the top two bits of Node hash fields for control + * purposes -- they are available anyway because of addressing + * constraints. As explained further below, these top bits are + * used as follows: + * 00 - Normal + * 01 - Locked + * 11 - Locked and may have a thread waiting for lock + * 10 - Node is a forwarding node + * + * The lower 30 bits of each Node's hash field contain a + * transformation of the key's hash code, except for forwarding + * nodes, for which the lower bits are zero (and so always have + * hash field == MOVED). + * + * Insertion (via put or its variants) of the first node in an + * empty bin is performed by just CASing it to the bin. This is + * by far the most common case for put operations under most + * key/hash distributions. Other update operations (insert, + * delete, and replace) require locks. We do not want to waste + * the space required to associate a distinct lock object with + * each bin, so instead use the first node of a bin list itself as + * a lock. Blocking support for these locks relies on the builtin + * "synchronized" monitors. However, we also need a tryLock + * construction, so we overlay these by using bits of the Node + * hash field for lock control (see above), and so normally use + * builtin monitors only for blocking and signalling using + * wait/notifyAll constructions. See Node.tryAwaitLock. + * + * Using the first node of a list as a lock does not by itself + * suffice though: When a node is locked, any update must first + * validate that it is still the first node after locking it, and + * retry if not. Because new nodes are always appended to lists, + * once a node is first in a bin, it remains first until deleted + * or the bin becomes invalidated (upon resizing). However, + * operations that only conditionally update may inspect nodes + * until the point of update. This is a converse of sorts to the + * lazy locking technique described by Herlihy & Shavit. + * + * The main disadvantage of per-bin locks is that other update + * operations on other nodes in a bin list protected by the same + * lock can stall, for example when user equals() or mapping + * functions take a long time. However, statistically, under + * random hash codes, this is not a common problem. Ideally, the + * frequency of nodes in bins follows a Poisson distribution + * (http://en.wikipedia.org/wiki/Poisson_distribution) with a + * parameter of about 0.5 on average, given the resizing threshold + * of 0.75, although with a large variance because of resizing + * granularity. Ignoring variance, the expected occurrences of + * list size k are (exp(-0.5) * pow(0.5, k) / factorial(k)). The + * first values are: + * + * 0: 0.60653066 + * 1: 0.30326533 + * 2: 0.07581633 + * 3: 0.01263606 + * 4: 0.00157952 + * 5: 0.00015795 + * 6: 0.00001316 + * 7: 0.00000094 + * 8: 0.00000006 + * more: less than 1 in ten million + * + * Lock contention probability for two threads accessing distinct + * elements is roughly 1 / (8 * #elements) under random hashes. + * + * Actual hash code distributions encountered in practice + * sometimes deviate significantly from uniform randomness. This + * includes the case when N > (1<<30), so some keys MUST collide. + * Similarly for dumb or hostile usages in which multiple keys are + * designed to have identical hash codes. Also, although we guard + * against the worst effects of this (see method spread), sets of + * hashes may differ only in bits that do not impact their bin + * index for a given power-of-two mask. So we use a secondary + * strategy that applies when the number of nodes in a bin exceeds + * a threshold, and at least one of the keys implements + * Comparable. These TreeBins use a balanced tree to hold nodes + * (a specialized form of red-black trees), bounding search time + * to O(log N). Each search step in a TreeBin is around twice as + * slow as in a regular list, but given that N cannot exceed + * (1<<64) (before running out of addresses) this bounds search + * steps, lock hold times, etc, to reasonable constants (roughly + * 100 nodes inspected per operation worst case) so long as keys + * are Comparable (which is very common -- String, Long, etc). + * TreeBin nodes (TreeNodes) also maintain the same "next" + * traversal pointers as regular nodes, so can be traversed in + * iterators in the same way. + * + * The table is resized when occupancy exceeds a percentage + * threshold (nominally, 0.75, but see below). Only a single + * thread performs the resize (using field "sizeCtl", to arrange + * exclusion), but the table otherwise remains usable for reads + * and updates. Resizing proceeds by transferring bins, one by + * one, from the table to the next table. Because we are using + * power-of-two expansion, the elements from each bin must either + * stay at same index, or move with a power of two offset. We + * eliminate unnecessary node creation by catching cases where old + * nodes can be reused because their next fields won't change. On + * average, only about one-sixth of them need cloning when a table + * doubles. The nodes they replace will be garbage collectable as + * soon as they are no longer referenced by any reader thread that + * may be in the midst of concurrently traversing table. Upon + * transfer, the old table bin contains only a special forwarding + * node (with hash field "MOVED") that contains the next table as + * its key. On encountering a forwarding node, access and update + * operations restart, using the new table. + * + * Each bin transfer requires its bin lock. However, unlike other + * cases, a transfer can skip a bin if it fails to acquire its + * lock, and revisit it later (unless it is a TreeBin). Method + * rebuild maintains a buffer of TRANSFER_BUFFER_SIZE bins that + * have been skipped because of failure to acquire a lock, and + * blocks only if none are available (i.e., only very rarely). + * The transfer operation must also ensure that all accessible + * bins in both the old and new table are usable by any traversal. + * When there are no lock acquisition failures, this is arranged + * simply by proceeding from the last bin (table.length - 1) up + * towards the first. Upon seeing a forwarding node, traversals + * (see class Iter) arrange to move to the new table + * without revisiting nodes. However, when any node is skipped + * during a transfer, all earlier table bins may have become + * visible, so are initialized with a reverse-forwarding node back + * to the old table until the new ones are established. (This + * sometimes requires transiently locking a forwarding node, which + * is possible under the above encoding.) These more expensive + * mechanics trigger only when necessary. + * + * The traversal scheme also applies to partial traversals of + * ranges of bins (via an alternate Traverser constructor) + * to support partitioned aggregate operations. Also, read-only + * operations give up if ever forwarded to a null table, which + * provides support for shutdown-style clearing, which is also not + * currently implemented. + * + * Lazy table initialization minimizes footprint until first use, + * and also avoids resizings when the first operation is from a + * putAll, constructor with map argument, or deserialization. + * These cases attempt to override the initial capacity settings, + * but harmlessly fail to take effect in cases of races. + * + * The element count is maintained using a LongAdder, which avoids + * contention on updates but can encounter cache thrashing if read + * too frequently during concurrent access. To avoid reading so + * often, resizing is attempted either when a bin lock is + * contended, or upon adding to a bin already holding two or more + * nodes (checked before adding in the xIfAbsent methods, after + * adding in others). Under uniform hash distributions, the + * probability of this occurring at threshold is around 13%, + * meaning that only about 1 in 8 puts check threshold (and after + * resizing, many fewer do so). But this approximation has high + * variance for small table sizes, so we check on any collision + * for sizes <= 64. The bulk putAll operation further reduces + * contention by only committing count updates upon these size + * checks. + * + * Maintaining API and serialization compatibility with previous + * versions of this class introduces several oddities. Mainly: We + * leave untouched but unused constructor arguments referring to + * concurrencyLevel. We accept a loadFactor constructor argument, + * but apply it only to initial table capacity (which is the only + * time that we can guarantee to honor it.) We also declare an + * unused "Segment" class that is instantiated in minimal form + * only when serializing. + */ + + /* ---------------- Constants -------------- */ + + /** + * The largest possible table capacity. This value must be + * exactly 1<<30 to stay within Java array allocation and indexing + * bounds for power of two table sizes, and is further required + * because the top two bits of 32bit hash fields are used for + * control purposes. + */ + private static final int MAXIMUM_CAPACITY = 1 << 30; + + /** + * The default initial table capacity. Must be a power of 2 + * (i.e., at least 1) and at most MAXIMUM_CAPACITY. + */ + private static final int DEFAULT_CAPACITY = 16; + + /** + * The largest possible (non-power of two) array size. + * Needed by toArray and related methods. + */ + static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; + + /** + * The default concurrency level for this table. Unused but + * defined for compatibility with previous versions of this class. + */ + private static final int DEFAULT_CONCURRENCY_LEVEL = 16; + + /** + * The load factor for this table. Overrides of this value in + * constructors affect only the initial table capacity. The + * actual floating point value isn't normally used -- it is + * simpler to use expressions such as {@code n - (n >>> 2)} for + * the associated resizing threshold. + */ + private static final float LOAD_FACTOR = 0.75f; + + /** + * The buffer size for skipped bins during transfers. The + * value is arbitrary but should be large enough to avoid + * most locking stalls during resizes. + */ + private static final int TRANSFER_BUFFER_SIZE = 32; + + /** + * The bin count threshold for using a tree rather than list for a + * bin. The value reflects the approximate break-even point for + * using tree-based operations. + * Note that Doug's version defaults to 8, but when dealing with + * Ruby objects it is actually beneficial to avoid TreeNodes + * as long as possible as it usually means going into Ruby land. + */ + private static final int TREE_THRESHOLD = 16; + + /* + * Encodings for special uses of Node hash fields. See above for + * explanation. + */ + static final int MOVED = 0x80000000; // hash field for forwarding nodes + static final int LOCKED = 0x40000000; // set/tested only as a bit + static final int WAITING = 0xc0000000; // both bits set/tested together + static final int HASH_BITS = 0x3fffffff; // usable bits of normal node hash + + /* ---------------- Fields -------------- */ + + /** + * The array of bins. Lazily initialized upon first insertion. + * Size is always a power of two. Accessed directly by iterators. + */ + transient volatile AtomicReferenceArray table; + + /** + * The counter maintaining number of elements. + */ + private transient LongAdder counter; + + /** + * Table initialization and resizing control. When negative, the + * table is being initialized or resized. Otherwise, when table is + * null, holds the initial table size to use upon creation, or 0 + * for default. After initialization, holds the next element count + * value upon which to resize the table. + */ + private transient volatile int sizeCtl; + + // views + private transient KeySetView keySet; + private transient ValuesView values; + private transient EntrySetView entrySet; + + /** For serialization compatibility. Null unless serialized; see below */ + private Segment[] segments; + + static AtomicIntegerFieldUpdater SIZE_CTRL_UPDATER = AtomicIntegerFieldUpdater.newUpdater(ConcurrentHashMapV8.class, "sizeCtl"); + + /* ---------------- Table element access -------------- */ + + /* + * Volatile access methods are used for table elements as well as + * elements of in-progress next table while resizing. Uses are + * null checked by callers, and implicitly bounds-checked, relying + * on the invariants that tab arrays have non-zero size, and all + * indices are masked with (tab.length - 1) which is never + * negative and always less than length. Note that, to be correct + * wrt arbitrary concurrency errors by users, bounds checks must + * operate on local variables, which accounts for some odd-looking + * inline assignments below. + */ + + static final Node tabAt(AtomicReferenceArray tab, int i) { // used by Iter + return tab.get(i); + } + + private static final boolean casTabAt(AtomicReferenceArray tab, int i, Node c, Node v) { + return tab.compareAndSet(i, c, v); + } + + private static final void setTabAt(AtomicReferenceArray tab, int i, Node v) { + tab.set(i, v); + } + + /* ---------------- Nodes -------------- */ + + /** + * Key-value entry. Note that this is never exported out as a + * user-visible Map.Entry (see MapEntry below). Nodes with a hash + * field of MOVED are special, and do not contain user keys or + * values. Otherwise, keys are never null, and null val fields + * indicate that a node is in the process of being deleted or + * created. For purposes of read-only access, a key may be read + * before a val, but can only be used after checking val to be + * non-null. + */ + static class Node { + volatile int hash; + final Object key; + volatile Object val; + volatile Node next; + + static AtomicIntegerFieldUpdater HASH_UPDATER = AtomicIntegerFieldUpdater.newUpdater(Node.class, "hash"); + + Node(int hash, Object key, Object val, Node next) { + this.hash = hash; + this.key = key; + this.val = val; + this.next = next; + } + + /** CompareAndSet the hash field */ + final boolean casHash(int cmp, int val) { + return HASH_UPDATER.compareAndSet(this, cmp, val); + } + + /** The number of spins before blocking for a lock */ + static final int MAX_SPINS = + Runtime.getRuntime().availableProcessors() > 1 ? 64 : 1; + + /** + * Spins a while if LOCKED bit set and this node is the first + * of its bin, and then sets WAITING bits on hash field and + * blocks (once) if they are still set. It is OK for this + * method to return even if lock is not available upon exit, + * which enables these simple single-wait mechanics. + * + * The corresponding signalling operation is performed within + * callers: Upon detecting that WAITING has been set when + * unlocking lock (via a failed CAS from non-waiting LOCKED + * state), unlockers acquire the sync lock and perform a + * notifyAll. + * + * The initial sanity check on tab and bounds is not currently + * necessary in the only usages of this method, but enables + * use in other future contexts. + */ + final void tryAwaitLock(AtomicReferenceArray tab, int i) { + if (tab != null && i >= 0 && i < tab.length()) { // sanity check + int r = ThreadLocalRandom.current().nextInt(); // randomize spins + int spins = MAX_SPINS, h; + while (tabAt(tab, i) == this && ((h = hash) & LOCKED) != 0) { + if (spins >= 0) { + r ^= r << 1; r ^= r >>> 3; r ^= r << 10; // xorshift + if (r >= 0 && --spins == 0) + Thread.yield(); // yield before block + } + else if (casHash(h, h | WAITING)) { + synchronized (this) { + if (tabAt(tab, i) == this && + (hash & WAITING) == WAITING) { + try { + wait(); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + } + } + else + notifyAll(); // possibly won race vs signaller + } + break; + } + } + } + } + } + + /* ---------------- TreeBins -------------- */ + + /** + * Nodes for use in TreeBins + */ + static final class TreeNode extends Node { + TreeNode parent; // red-black tree links + TreeNode left; + TreeNode right; + TreeNode prev; // needed to unlink next upon deletion + boolean red; + + TreeNode(int hash, Object key, Object val, Node next, TreeNode parent) { + super(hash, key, val, next); + this.parent = parent; + } + } + + /** + * A specialized form of red-black tree for use in bins + * whose size exceeds a threshold. + * + * TreeBins use a special form of comparison for search and + * related operations (which is the main reason we cannot use + * existing collections such as TreeMaps). TreeBins contain + * Comparable elements, but may contain others, as well as + * elements that are Comparable but not necessarily Comparable + * for the same T, so we cannot invoke compareTo among them. To + * handle this, the tree is ordered primarily by hash value, then + * by getClass().getName() order, and then by Comparator order + * among elements of the same class. On lookup at a node, if + * elements are not comparable or compare as 0, both left and + * right children may need to be searched in the case of tied hash + * values. (This corresponds to the full list search that would be + * necessary if all elements were non-Comparable and had tied + * hashes.) The red-black balancing code is updated from + * pre-jdk-collections + * (http://gee.cs.oswego.edu/dl/classes/collections/RBCell.java) + * based in turn on Cormen, Leiserson, and Rivest "Introduction to + * Algorithms" (CLR). + * + * TreeBins also maintain a separate locking discipline than + * regular bins. Because they are forwarded via special MOVED + * nodes at bin heads (which can never change once established), + * we cannot use those nodes as locks. Instead, TreeBin + * extends AbstractQueuedSynchronizer to support a simple form of + * read-write lock. For update operations and table validation, + * the exclusive form of lock behaves in the same way as bin-head + * locks. However, lookups use shared read-lock mechanics to allow + * multiple readers in the absence of writers. Additionally, + * these lookups do not ever block: While the lock is not + * available, they proceed along the slow traversal path (via + * next-pointers) until the lock becomes available or the list is + * exhausted, whichever comes first. (These cases are not fast, + * but maximize aggregate expected throughput.) The AQS mechanics + * for doing this are straightforward. The lock state is held as + * AQS getState(). Read counts are negative; the write count (1) + * is positive. There are no signalling preferences among readers + * and writers. Since we don't need to export full Lock API, we + * just override the minimal AQS methods and use them directly. + */ + static final class TreeBin extends AbstractQueuedSynchronizer { + private static final long serialVersionUID = 2249069246763182397L; + transient TreeNode root; // root of tree + transient TreeNode first; // head of next-pointer list + + /* AQS overrides */ + public final boolean isHeldExclusively() { return getState() > 0; } + public final boolean tryAcquire(int ignore) { + if (compareAndSetState(0, 1)) { + setExclusiveOwnerThread(Thread.currentThread()); + return true; + } + return false; + } + public final boolean tryRelease(int ignore) { + setExclusiveOwnerThread(null); + setState(0); + return true; + } + public final int tryAcquireShared(int ignore) { + for (int c;;) { + if ((c = getState()) > 0) + return -1; + if (compareAndSetState(c, c -1)) + return 1; + } + } + public final boolean tryReleaseShared(int ignore) { + int c; + do {} while (!compareAndSetState(c = getState(), c + 1)); + return c == -1; + } + + /** From CLR */ + private void rotateLeft(TreeNode p) { + if (p != null) { + TreeNode r = p.right, pp, rl; + if ((rl = p.right = r.left) != null) + rl.parent = p; + if ((pp = r.parent = p.parent) == null) + root = r; + else if (pp.left == p) + pp.left = r; + else + pp.right = r; + r.left = p; + p.parent = r; + } + } + + /** From CLR */ + private void rotateRight(TreeNode p) { + if (p != null) { + TreeNode l = p.left, pp, lr; + if ((lr = p.left = l.right) != null) + lr.parent = p; + if ((pp = l.parent = p.parent) == null) + root = l; + else if (pp.right == p) + pp.right = l; + else + pp.left = l; + l.right = p; + p.parent = l; + } + } + + @SuppressWarnings("unchecked") final TreeNode getTreeNode + (int h, Object k, TreeNode p) { + return getTreeNode(h, (RubyObject)k, p); + } + + /** + * Returns the TreeNode (or null if not found) for the given key + * starting at given root. + */ + @SuppressWarnings("unchecked") final TreeNode getTreeNode + (int h, RubyObject k, TreeNode p) { + RubyClass c = k.getMetaClass(); boolean kNotComparable = !k.respondsTo("<=>"); + while (p != null) { + int dir, ph; RubyObject pk; RubyClass pc; + if ((ph = p.hash) == h) { + if ((pk = (RubyObject)p.key) == k || k.equals(pk)) + return p; + if (c != (pc = (RubyClass)pk.getMetaClass()) || + kNotComparable || + (dir = rubyCompare(k, pk)) == 0) { + dir = (c == pc) ? 0 : c.getName().compareTo(pc.getName()); + if (dir == 0) { // if still stuck, need to check both sides + TreeNode r = null, pl, pr; + // try to recurse on the right + if ((pr = p.right) != null && h >= pr.hash && (r = getTreeNode(h, k, pr)) != null) + return r; + // try to continue iterating on the left side + else if ((pl = p.left) != null && h <= pl.hash) + dir = -1; + else // no matching node found + return null; + } + } + } + else + dir = (h < ph) ? -1 : 1; + p = (dir > 0) ? p.right : p.left; + } + return null; + } + + int rubyCompare(RubyObject l, RubyObject r) { + ThreadContext context = l.getMetaClass().getRuntime().getCurrentContext(); + IRubyObject result; + try { + result = l.callMethod(context, "<=>", r); + } catch (RaiseException e) { + // handle objects "lying" about responding to <=>, ie: an Array containing non-comparable keys + if (context.runtime.getNoMethodError().isInstance(e.getException())) { + return 0; + } + throw e; + } + + return result.isNil() ? 0 : RubyNumeric.num2int(result.convertToInteger()); + } + + /** + * Wrapper for getTreeNode used by CHM.get. Tries to obtain + * read-lock to call getTreeNode, but during failure to get + * lock, searches along next links. + */ + final Object getValue(int h, Object k) { + Node r = null; + int c = getState(); // Must read lock state first + for (Node e = first; e != null; e = e.next) { + if (c <= 0 && compareAndSetState(c, c - 1)) { + try { + r = getTreeNode(h, k, root); + } finally { + releaseShared(0); + } + break; + } + else if ((e.hash & HASH_BITS) == h && k.equals(e.key)) { + r = e; + break; + } + else + c = getState(); + } + return r == null ? null : r.val; + } + + @SuppressWarnings("unchecked") final TreeNode putTreeNode + (int h, Object k, Object v) { + return putTreeNode(h, (RubyObject)k, v); + } + + /** + * Finds or adds a node. + * @return null if added + */ + @SuppressWarnings("unchecked") final TreeNode putTreeNode + (int h, RubyObject k, Object v) { + RubyClass c = k.getMetaClass(); + boolean kNotComparable = !k.respondsTo("<=>"); + TreeNode pp = root, p = null; + int dir = 0; + while (pp != null) { // find existing node or leaf to insert at + int ph; RubyObject pk; RubyClass pc; + p = pp; + if ((ph = p.hash) == h) { + if ((pk = (RubyObject)p.key) == k || k.equals(pk)) + return p; + if (c != (pc = pk.getMetaClass()) || + kNotComparable || + (dir = rubyCompare(k, pk)) == 0) { + dir = (c == pc) ? 0 : c.getName().compareTo(pc.getName()); + if (dir == 0) { // if still stuck, need to check both sides + TreeNode r = null, pr; + // try to recurse on the right + if ((pr = p.right) != null && h >= pr.hash && (r = getTreeNode(h, k, pr)) != null) + return r; + else // continue descending down the left subtree + dir = -1; + } + } + } + else + dir = (h < ph) ? -1 : 1; + pp = (dir > 0) ? p.right : p.left; + } + + TreeNode f = first; + TreeNode x = first = new TreeNode(h, (Object)k, v, f, p); + if (p == null) + root = x; + else { // attach and rebalance; adapted from CLR + TreeNode xp, xpp; + if (f != null) + f.prev = x; + if (dir <= 0) + p.left = x; + else + p.right = x; + x.red = true; + while (x != null && (xp = x.parent) != null && xp.red && + (xpp = xp.parent) != null) { + TreeNode xppl = xpp.left; + if (xp == xppl) { + TreeNode y = xpp.right; + if (y != null && y.red) { + y.red = false; + xp.red = false; + xpp.red = true; + x = xpp; + } + else { + if (x == xp.right) { + rotateLeft(x = xp); + xpp = (xp = x.parent) == null ? null : xp.parent; + } + if (xp != null) { + xp.red = false; + if (xpp != null) { + xpp.red = true; + rotateRight(xpp); + } + } + } + } + else { + TreeNode y = xppl; + if (y != null && y.red) { + y.red = false; + xp.red = false; + xpp.red = true; + x = xpp; + } + else { + if (x == xp.left) { + rotateRight(x = xp); + xpp = (xp = x.parent) == null ? null : xp.parent; + } + if (xp != null) { + xp.red = false; + if (xpp != null) { + xpp.red = true; + rotateLeft(xpp); + } + } + } + } + } + TreeNode r = root; + if (r != null && r.red) + r.red = false; + } + return null; + } + + /** + * Removes the given node, that must be present before this + * call. This is messier than typical red-black deletion code + * because we cannot swap the contents of an interior node + * with a leaf successor that is pinned by "next" pointers + * that are accessible independently of lock. So instead we + * swap the tree linkages. + */ + final void deleteTreeNode(TreeNode p) { + TreeNode next = (TreeNode)p.next; // unlink traversal pointers + TreeNode pred = p.prev; + if (pred == null) + first = next; + else + pred.next = next; + if (next != null) + next.prev = pred; + TreeNode replacement; + TreeNode pl = p.left; + TreeNode pr = p.right; + if (pl != null && pr != null) { + TreeNode s = pr, sl; + while ((sl = s.left) != null) // find successor + s = sl; + boolean c = s.red; s.red = p.red; p.red = c; // swap colors + TreeNode sr = s.right; + TreeNode pp = p.parent; + if (s == pr) { // p was s's direct parent + p.parent = s; + s.right = p; + } + else { + TreeNode sp = s.parent; + if ((p.parent = sp) != null) { + if (s == sp.left) + sp.left = p; + else + sp.right = p; + } + if ((s.right = pr) != null) + pr.parent = s; + } + p.left = null; + if ((p.right = sr) != null) + sr.parent = p; + if ((s.left = pl) != null) + pl.parent = s; + if ((s.parent = pp) == null) + root = s; + else if (p == pp.left) + pp.left = s; + else + pp.right = s; + replacement = sr; + } + else + replacement = (pl != null) ? pl : pr; + TreeNode pp = p.parent; + if (replacement == null) { + if (pp == null) { + root = null; + return; + } + replacement = p; + } + else { + replacement.parent = pp; + if (pp == null) + root = replacement; + else if (p == pp.left) + pp.left = replacement; + else + pp.right = replacement; + p.left = p.right = p.parent = null; + } + if (!p.red) { // rebalance, from CLR + TreeNode x = replacement; + while (x != null) { + TreeNode xp, xpl; + if (x.red || (xp = x.parent) == null) { + x.red = false; + break; + } + if (x == (xpl = xp.left)) { + TreeNode sib = xp.right; + if (sib != null && sib.red) { + sib.red = false; + xp.red = true; + rotateLeft(xp); + sib = (xp = x.parent) == null ? null : xp.right; + } + if (sib == null) + x = xp; + else { + TreeNode sl = sib.left, sr = sib.right; + if ((sr == null || !sr.red) && + (sl == null || !sl.red)) { + sib.red = true; + x = xp; + } + else { + if (sr == null || !sr.red) { + if (sl != null) + sl.red = false; + sib.red = true; + rotateRight(sib); + sib = (xp = x.parent) == null ? null : xp.right; + } + if (sib != null) { + sib.red = (xp == null) ? false : xp.red; + if ((sr = sib.right) != null) + sr.red = false; + } + if (xp != null) { + xp.red = false; + rotateLeft(xp); + } + x = root; + } + } + } + else { // symmetric + TreeNode sib = xpl; + if (sib != null && sib.red) { + sib.red = false; + xp.red = true; + rotateRight(xp); + sib = (xp = x.parent) == null ? null : xp.left; + } + if (sib == null) + x = xp; + else { + TreeNode sl = sib.left, sr = sib.right; + if ((sl == null || !sl.red) && + (sr == null || !sr.red)) { + sib.red = true; + x = xp; + } + else { + if (sl == null || !sl.red) { + if (sr != null) + sr.red = false; + sib.red = true; + rotateLeft(sib); + sib = (xp = x.parent) == null ? null : xp.left; + } + if (sib != null) { + sib.red = (xp == null) ? false : xp.red; + if ((sl = sib.left) != null) + sl.red = false; + } + if (xp != null) { + xp.red = false; + rotateRight(xp); + } + x = root; + } + } + } + } + } + if (p == replacement && (pp = p.parent) != null) { + if (p == pp.left) // detach pointers + pp.left = null; + else if (p == pp.right) + pp.right = null; + p.parent = null; + } + } + } + + /* ---------------- Collision reduction methods -------------- */ + + /** + * Spreads higher bits to lower, and also forces top 2 bits to 0. + * Because the table uses power-of-two masking, sets of hashes + * that vary only in bits above the current mask will always + * collide. (Among known examples are sets of Float keys holding + * consecutive whole numbers in small tables.) To counter this, + * we apply a transform that spreads the impact of higher bits + * downward. There is a tradeoff between speed, utility, and + * quality of bit-spreading. Because many common sets of hashes + * are already reasonably distributed across bits (so don't benefit + * from spreading), and because we use trees to handle large sets + * of collisions in bins, we don't need excessively high quality. + */ + private static final int spread(int h) { + h ^= (h >>> 18) ^ (h >>> 12); + return (h ^ (h >>> 10)) & HASH_BITS; + } + + /** + * Replaces a list bin with a tree bin. Call only when locked. + * Fails to replace if the given key is non-comparable or table + * is, or needs, resizing. + */ + private final void replaceWithTreeBin(AtomicReferenceArray tab, int index, Object key) { + if ((key instanceof Comparable) && + (tab.length() >= MAXIMUM_CAPACITY || counter.sum() < (long)sizeCtl)) { + TreeBin t = new TreeBin(); + for (Node e = tabAt(tab, index); e != null; e = e.next) + t.putTreeNode(e.hash & HASH_BITS, e.key, e.val); + setTabAt(tab, index, new Node(MOVED, t, null, null)); + } + } + + /* ---------------- Internal access and update methods -------------- */ + + /** Implementation for get and containsKey */ + private final Object internalGet(Object k) { + int h = spread(k.hashCode()); + retry: for (AtomicReferenceArray tab = table; tab != null;) { + Node e, p; Object ek, ev; int eh; // locals to read fields once + for (e = tabAt(tab, (tab.length() - 1) & h); e != null; e = e.next) { + if ((eh = e.hash) == MOVED) { + if ((ek = e.key) instanceof TreeBin) // search TreeBin + return ((TreeBin)ek).getValue(h, k); + else { // restart with new table + tab = (AtomicReferenceArray)ek; + continue retry; + } + } + else if ((eh & HASH_BITS) == h && (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) + return ev; + } + break; + } + return null; + } + + /** + * Implementation for the four public remove/replace methods: + * Replaces node value with v, conditional upon match of cv if + * non-null. If resulting value is null, delete. + */ + private final Object internalReplace(Object k, Object v, Object cv) { + int h = spread(k.hashCode()); + Object oldVal = null; + for (AtomicReferenceArray tab = table;;) { + Node f; int i, fh; Object fk; + if (tab == null || + (f = tabAt(tab, i = (tab.length() - 1) & h)) == null) + break; + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + boolean validated = false; + boolean deleted = false; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + validated = true; + TreeNode p = t.getTreeNode(h, k, t.root); + if (p != null) { + Object pv = p.val; + if (cv == null || cv == pv || cv.equals(pv)) { + oldVal = pv; + if ((p.val = v) == null) { + deleted = true; + t.deleteTreeNode(p); + } + } + } + } + } finally { + t.release(0); + } + if (validated) { + if (deleted) + counter.add(-1L); + break; + } + } + else + tab = (AtomicReferenceArray)fk; + } + else if ((fh & HASH_BITS) != h && f.next == null) // precheck + break; // rules out possible existence + else if ((fh & LOCKED) != 0) { + checkForResize(); // try resizing if can't get lock + f.tryAwaitLock(tab, i); + } + else if (f.casHash(fh, fh | LOCKED)) { + boolean validated = false; + boolean deleted = false; + try { + if (tabAt(tab, i) == f) { + validated = true; + for (Node e = f, pred = null;;) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + ((ev = e.val) != null) && + ((ek = e.key) == k || k.equals(ek))) { + if (cv == null || cv == ev || cv.equals(ev)) { + oldVal = ev; + if ((e.val = v) == null) { + deleted = true; + Node en = e.next; + if (pred != null) + pred.next = en; + else + setTabAt(tab, i, en); + } + } + break; + } + pred = e; + if ((e = e.next) == null) + break; + } + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (validated) { + if (deleted) + counter.add(-1L); + break; + } + } + } + return oldVal; + } + + /* + * Internal versions of the six insertion methods, each a + * little more complicated than the last. All have + * the same basic structure as the first (internalPut): + * 1. If table uninitialized, create + * 2. If bin empty, try to CAS new node + * 3. If bin stale, use new table + * 4. if bin converted to TreeBin, validate and relay to TreeBin methods + * 5. Lock and validate; if valid, scan and add or update + * + * The others interweave other checks and/or alternative actions: + * * Plain put checks for and performs resize after insertion. + * * putIfAbsent prescans for mapping without lock (and fails to add + * if present), which also makes pre-emptive resize checks worthwhile. + * * computeIfAbsent extends form used in putIfAbsent with additional + * mechanics to deal with, calls, potential exceptions and null + * returns from function call. + * * compute uses the same function-call mechanics, but without + * the prescans + * * merge acts as putIfAbsent in the absent case, but invokes the + * update function if present + * * putAll attempts to pre-allocate enough table space + * and more lazily performs count updates and checks. + * + * Someday when details settle down a bit more, it might be worth + * some factoring to reduce sprawl. + */ + + /** Implementation for put */ + private final Object internalPut(Object k, Object v) { + int h = spread(k.hashCode()); + int count = 0; + for (AtomicReferenceArray tab = table;;) { + int i; Node f; int fh; Object fk; + if (tab == null) + tab = initTable(); + else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null) { + if (casTabAt(tab, i, null, new Node(h, k, v, null))) + break; // no lock when adding to empty bin + } + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + Object oldVal = null; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + count = 2; + TreeNode p = t.putTreeNode(h, k, v); + if (p != null) { + oldVal = p.val; + p.val = v; + } + } + } finally { + t.release(0); + } + if (count != 0) { + if (oldVal != null) + return oldVal; + break; + } + } + else + tab = (AtomicReferenceArray)fk; + } + else if ((fh & LOCKED) != 0) { + checkForResize(); + f.tryAwaitLock(tab, i); + } + else if (f.casHash(fh, fh | LOCKED)) { + Object oldVal = null; + try { // needed in case equals() throws + if (tabAt(tab, i) == f) { + count = 1; + for (Node e = f;; ++count) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) { + oldVal = ev; + e.val = v; + break; + } + Node last = e; + if ((e = e.next) == null) { + last.next = new Node(h, k, v, null); + if (count >= TREE_THRESHOLD) + replaceWithTreeBin(tab, i, k); + break; + } + } + } + } finally { // unlock and signal if needed + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (count != 0) { + if (oldVal != null) + return oldVal; + if (tab.length() <= 64) + count = 2; + break; + } + } + } + counter.add(1L); + if (count > 1) + checkForResize(); + return null; + } + + /** Implementation for putIfAbsent */ + private final Object internalPutIfAbsent(Object k, Object v) { + int h = spread(k.hashCode()); + int count = 0; + for (AtomicReferenceArray tab = table;;) { + int i; Node f; int fh; Object fk, fv; + if (tab == null) + tab = initTable(); + else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null) { + if (casTabAt(tab, i, null, new Node(h, k, v, null))) + break; + } + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + Object oldVal = null; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + count = 2; + TreeNode p = t.putTreeNode(h, k, v); + if (p != null) + oldVal = p.val; + } + } finally { + t.release(0); + } + if (count != 0) { + if (oldVal != null) + return oldVal; + break; + } + } + else + tab = (AtomicReferenceArray)fk; + } + else if ((fh & HASH_BITS) == h && (fv = f.val) != null && + ((fk = f.key) == k || k.equals(fk))) + return fv; + else { + Node g = f.next; + if (g != null) { // at least 2 nodes -- search and maybe resize + for (Node e = g;;) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) + return ev; + if ((e = e.next) == null) { + checkForResize(); + break; + } + } + } + if (((fh = f.hash) & LOCKED) != 0) { + checkForResize(); + f.tryAwaitLock(tab, i); + } + else if (tabAt(tab, i) == f && f.casHash(fh, fh | LOCKED)) { + Object oldVal = null; + try { + if (tabAt(tab, i) == f) { + count = 1; + for (Node e = f;; ++count) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) { + oldVal = ev; + break; + } + Node last = e; + if ((e = e.next) == null) { + last.next = new Node(h, k, v, null); + if (count >= TREE_THRESHOLD) + replaceWithTreeBin(tab, i, k); + break; + } + } + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (count != 0) { + if (oldVal != null) + return oldVal; + if (tab.length() <= 64) + count = 2; + break; + } + } + } + } + counter.add(1L); + if (count > 1) + checkForResize(); + return null; + } + + /** Implementation for computeIfAbsent */ + private final Object internalComputeIfAbsent(K k, + Fun mf) { + int h = spread(k.hashCode()); + Object val = null; + int count = 0; + for (AtomicReferenceArray tab = table;;) { + Node f; int i, fh; Object fk, fv; + if (tab == null) + tab = initTable(); + else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null) { + Node node = new Node(fh = h | LOCKED, k, null, null); + if (casTabAt(tab, i, null, node)) { + count = 1; + try { + if ((val = mf.apply(k)) != null) + node.val = val; + } finally { + if (val == null) + setTabAt(tab, i, null); + if (!node.casHash(fh, h)) { + node.hash = h; + synchronized (node) { node.notifyAll(); }; + } + } + } + if (count != 0) + break; + } + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + boolean added = false; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + count = 1; + TreeNode p = t.getTreeNode(h, k, t.root); + if (p != null) + val = p.val; + else if ((val = mf.apply(k)) != null) { + added = true; + count = 2; + t.putTreeNode(h, k, val); + } + } + } finally { + t.release(0); + } + if (count != 0) { + if (!added) + return val; + break; + } + } + else + tab = (AtomicReferenceArray)fk; + } + else if ((fh & HASH_BITS) == h && (fv = f.val) != null && + ((fk = f.key) == k || k.equals(fk))) + return fv; + else { + Node g = f.next; + if (g != null) { + for (Node e = g;;) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) + return ev; + if ((e = e.next) == null) { + checkForResize(); + break; + } + } + } + if (((fh = f.hash) & LOCKED) != 0) { + checkForResize(); + f.tryAwaitLock(tab, i); + } + else if (tabAt(tab, i) == f && f.casHash(fh, fh | LOCKED)) { + boolean added = false; + try { + if (tabAt(tab, i) == f) { + count = 1; + for (Node e = f;; ++count) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) { + val = ev; + break; + } + Node last = e; + if ((e = e.next) == null) { + if ((val = mf.apply(k)) != null) { + added = true; + last.next = new Node(h, k, val, null); + if (count >= TREE_THRESHOLD) + replaceWithTreeBin(tab, i, k); + } + break; + } + } + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (count != 0) { + if (!added) + return val; + if (tab.length() <= 64) + count = 2; + break; + } + } + } + } + if (val != null) { + counter.add(1L); + if (count > 1) + checkForResize(); + } + return val; + } + + /** Implementation for compute */ + @SuppressWarnings("unchecked") private final Object internalCompute + (K k, boolean onlyIfPresent, BiFun mf) { + int h = spread(k.hashCode()); + Object val = null; + int delta = 0; + int count = 0; + for (AtomicReferenceArray tab = table;;) { + Node f; int i, fh; Object fk; + if (tab == null) + tab = initTable(); + else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null) { + if (onlyIfPresent) + break; + Node node = new Node(fh = h | LOCKED, k, null, null); + if (casTabAt(tab, i, null, node)) { + try { + count = 1; + if ((val = mf.apply(k, null)) != null) { + node.val = val; + delta = 1; + } + } finally { + if (delta == 0) + setTabAt(tab, i, null); + if (!node.casHash(fh, h)) { + node.hash = h; + synchronized (node) { node.notifyAll(); }; + } + } + } + if (count != 0) + break; + } + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + count = 1; + TreeNode p = t.getTreeNode(h, k, t.root); + Object pv; + if (p == null) { + if (onlyIfPresent) + break; + pv = null; + } else + pv = p.val; + if ((val = mf.apply(k, (V)pv)) != null) { + if (p != null) + p.val = val; + else { + count = 2; + delta = 1; + t.putTreeNode(h, k, val); + } + } + else if (p != null) { + delta = -1; + t.deleteTreeNode(p); + } + } + } finally { + t.release(0); + } + if (count != 0) + break; + } + else + tab = (AtomicReferenceArray)fk; + } + else if ((fh & LOCKED) != 0) { + checkForResize(); + f.tryAwaitLock(tab, i); + } + else if (f.casHash(fh, fh | LOCKED)) { + try { + if (tabAt(tab, i) == f) { + count = 1; + for (Node e = f, pred = null;; ++count) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) { + val = mf.apply(k, (V)ev); + if (val != null) + e.val = val; + else { + delta = -1; + Node en = e.next; + if (pred != null) + pred.next = en; + else + setTabAt(tab, i, en); + } + break; + } + pred = e; + if ((e = e.next) == null) { + if (!onlyIfPresent && (val = mf.apply(k, null)) != null) { + pred.next = new Node(h, k, val, null); + delta = 1; + if (count >= TREE_THRESHOLD) + replaceWithTreeBin(tab, i, k); + } + break; + } + } + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (count != 0) { + if (tab.length() <= 64) + count = 2; + break; + } + } + } + if (delta != 0) { + counter.add((long)delta); + if (count > 1) + checkForResize(); + } + return val; + } + + /** Implementation for merge */ + @SuppressWarnings("unchecked") private final Object internalMerge + (K k, V v, BiFun mf) { + int h = spread(k.hashCode()); + Object val = null; + int delta = 0; + int count = 0; + for (AtomicReferenceArray tab = table;;) { + int i; Node f; int fh; Object fk, fv; + if (tab == null) + tab = initTable(); + else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null) { + if (casTabAt(tab, i, null, new Node(h, k, v, null))) { + delta = 1; + val = v; + break; + } + } + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + count = 1; + TreeNode p = t.getTreeNode(h, k, t.root); + val = (p == null) ? v : mf.apply((V)p.val, v); + if (val != null) { + if (p != null) + p.val = val; + else { + count = 2; + delta = 1; + t.putTreeNode(h, k, val); + } + } + else if (p != null) { + delta = -1; + t.deleteTreeNode(p); + } + } + } finally { + t.release(0); + } + if (count != 0) + break; + } + else + tab = (AtomicReferenceArray)fk; + } + else if ((fh & LOCKED) != 0) { + checkForResize(); + f.tryAwaitLock(tab, i); + } + else if (f.casHash(fh, fh | LOCKED)) { + try { + if (tabAt(tab, i) == f) { + count = 1; + for (Node e = f, pred = null;; ++count) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) { + val = mf.apply((V)ev, v); + if (val != null) + e.val = val; + else { + delta = -1; + Node en = e.next; + if (pred != null) + pred.next = en; + else + setTabAt(tab, i, en); + } + break; + } + pred = e; + if ((e = e.next) == null) { + val = v; + pred.next = new Node(h, k, val, null); + delta = 1; + if (count >= TREE_THRESHOLD) + replaceWithTreeBin(tab, i, k); + break; + } + } + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (count != 0) { + if (tab.length() <= 64) + count = 2; + break; + } + } + } + if (delta != 0) { + counter.add((long)delta); + if (count > 1) + checkForResize(); + } + return val; + } + + /** Implementation for putAll */ + private final void internalPutAll(Map m) { + tryPresize(m.size()); + long delta = 0L; // number of uncommitted additions + boolean npe = false; // to throw exception on exit for nulls + try { // to clean up counts on other exceptions + for (Map.Entry entry : m.entrySet()) { + Object k, v; + if (entry == null || (k = entry.getKey()) == null || + (v = entry.getValue()) == null) { + npe = true; + break; + } + int h = spread(k.hashCode()); + for (AtomicReferenceArray tab = table;;) { + int i; Node f; int fh; Object fk; + if (tab == null) + tab = initTable(); + else if ((f = tabAt(tab, i = (tab.length() - 1) & h)) == null){ + if (casTabAt(tab, i, null, new Node(h, k, v, null))) { + ++delta; + break; + } + } + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + boolean validated = false; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + validated = true; + TreeNode p = t.getTreeNode(h, k, t.root); + if (p != null) + p.val = v; + else { + t.putTreeNode(h, k, v); + ++delta; + } + } + } finally { + t.release(0); + } + if (validated) + break; + } + else + tab = (AtomicReferenceArray)fk; + } + else if ((fh & LOCKED) != 0) { + counter.add(delta); + delta = 0L; + checkForResize(); + f.tryAwaitLock(tab, i); + } + else if (f.casHash(fh, fh | LOCKED)) { + int count = 0; + try { + if (tabAt(tab, i) == f) { + count = 1; + for (Node e = f;; ++count) { + Object ek, ev; + if ((e.hash & HASH_BITS) == h && + (ev = e.val) != null && + ((ek = e.key) == k || k.equals(ek))) { + e.val = v; + break; + } + Node last = e; + if ((e = e.next) == null) { + ++delta; + last.next = new Node(h, k, v, null); + if (count >= TREE_THRESHOLD) + replaceWithTreeBin(tab, i, k); + break; + } + } + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (count != 0) { + if (count > 1) { + counter.add(delta); + delta = 0L; + checkForResize(); + } + break; + } + } + } + } + } finally { + if (delta != 0) + counter.add(delta); + } + if (npe) + throw new NullPointerException(); + } + + /* ---------------- Table Initialization and Resizing -------------- */ + + /** + * Returns a power of two table size for the given desired capacity. + * See Hackers Delight, sec 3.2 + */ + private static final int tableSizeFor(int c) { + int n = c - 1; + n |= n >>> 1; + n |= n >>> 2; + n |= n >>> 4; + n |= n >>> 8; + n |= n >>> 16; + return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; + } + + /** + * Initializes table, using the size recorded in sizeCtl. + */ + private final AtomicReferenceArray initTable() { + AtomicReferenceArray tab; int sc; + while ((tab = table) == null) { + if ((sc = sizeCtl) < 0) + Thread.yield(); // lost initialization race; just spin + else if (SIZE_CTRL_UPDATER.compareAndSet(this, sc, -1)) { + try { + if ((tab = table) == null) { + int n = (sc > 0) ? sc : DEFAULT_CAPACITY; + tab = table = new AtomicReferenceArray(n); + sc = n - (n >>> 2); + } + } finally { + sizeCtl = sc; + } + break; + } + } + return tab; + } + + /** + * If table is too small and not already resizing, creates next + * table and transfers bins. Rechecks occupancy after a transfer + * to see if another resize is already needed because resizings + * are lagging additions. + */ + private final void checkForResize() { + AtomicReferenceArray tab; int n, sc; + while ((tab = table) != null && + (n = tab.length()) < MAXIMUM_CAPACITY && + (sc = sizeCtl) >= 0 && counter.sum() >= (long)sc && + SIZE_CTRL_UPDATER.compareAndSet(this, sc, -1)) { + try { + if (tab == table) { + table = rebuild(tab); + sc = (n << 1) - (n >>> 1); + } + } finally { + sizeCtl = sc; + } + } + } + + /** + * Tries to presize table to accommodate the given number of elements. + * + * @param size number of elements (doesn't need to be perfectly accurate) + */ + private final void tryPresize(int size) { + int c = (size >= (MAXIMUM_CAPACITY >>> 1)) ? MAXIMUM_CAPACITY : + tableSizeFor(size + (size >>> 1) + 1); + int sc; + while ((sc = sizeCtl) >= 0) { + AtomicReferenceArray tab = table; int n; + if (tab == null || (n = tab.length()) == 0) { + n = (sc > c) ? sc : c; + if (SIZE_CTRL_UPDATER.compareAndSet(this, sc, -1)) { + try { + if (table == tab) { + table = new AtomicReferenceArray(n); + sc = n - (n >>> 2); + } + } finally { + sizeCtl = sc; + } + } + } + else if (c <= sc || n >= MAXIMUM_CAPACITY) + break; + else if (SIZE_CTRL_UPDATER.compareAndSet(this, sc, -1)) { + try { + if (table == tab) { + table = rebuild(tab); + sc = (n << 1) - (n >>> 1); + } + } finally { + sizeCtl = sc; + } + } + } + } + + /* + * Moves and/or copies the nodes in each bin to new table. See + * above for explanation. + * + * @return the new table + */ + private static final AtomicReferenceArray rebuild(AtomicReferenceArray tab) { + int n = tab.length(); + AtomicReferenceArray nextTab = new AtomicReferenceArray(n << 1); + Node fwd = new Node(MOVED, nextTab, null, null); + int[] buffer = null; // holds bins to revisit; null until needed + Node rev = null; // reverse forwarder; null until needed + int nbuffered = 0; // the number of bins in buffer list + int bufferIndex = 0; // buffer index of current buffered bin + int bin = n - 1; // current non-buffered bin or -1 if none + + for (int i = bin;;) { // start upwards sweep + int fh; Node f; + if ((f = tabAt(tab, i)) == null) { + if (bin >= 0) { // Unbuffered; no lock needed (or available) + if (!casTabAt(tab, i, f, fwd)) + continue; + } + else { // transiently use a locked forwarding node + Node g = new Node(MOVED|LOCKED, nextTab, null, null); + if (!casTabAt(tab, i, f, g)) + continue; + setTabAt(nextTab, i, null); + setTabAt(nextTab, i + n, null); + setTabAt(tab, i, fwd); + if (!g.casHash(MOVED|LOCKED, MOVED)) { + g.hash = MOVED; + synchronized (g) { g.notifyAll(); } + } + } + } + else if ((fh = f.hash) == MOVED) { + Object fk = f.key; + if (fk instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + boolean validated = false; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + validated = true; + splitTreeBin(nextTab, i, t); + setTabAt(tab, i, fwd); + } + } finally { + t.release(0); + } + if (!validated) + continue; + } + } + else if ((fh & LOCKED) == 0 && f.casHash(fh, fh|LOCKED)) { + boolean validated = false; + try { // split to lo and hi lists; copying as needed + if (tabAt(tab, i) == f) { + validated = true; + splitBin(nextTab, i, f); + setTabAt(tab, i, fwd); + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + if (!validated) + continue; + } + else { + if (buffer == null) // initialize buffer for revisits + buffer = new int[TRANSFER_BUFFER_SIZE]; + if (bin < 0 && bufferIndex > 0) { + int j = buffer[--bufferIndex]; + buffer[bufferIndex] = i; + i = j; // swap with another bin + continue; + } + if (bin < 0 || nbuffered >= TRANSFER_BUFFER_SIZE) { + f.tryAwaitLock(tab, i); + continue; // no other options -- block + } + if (rev == null) // initialize reverse-forwarder + rev = new Node(MOVED, tab, null, null); + if (tabAt(tab, i) != f || (f.hash & LOCKED) == 0) + continue; // recheck before adding to list + buffer[nbuffered++] = i; + setTabAt(nextTab, i, rev); // install place-holders + setTabAt(nextTab, i + n, rev); + } + + if (bin > 0) + i = --bin; + else if (buffer != null && nbuffered > 0) { + bin = -1; + i = buffer[bufferIndex = --nbuffered]; + } + else + return nextTab; + } + } + + /** + * Splits a normal bin with list headed by e into lo and hi parts; + * installs in given table. + */ + private static void splitBin(AtomicReferenceArray nextTab, int i, Node e) { + int bit = nextTab.length() >>> 1; // bit to split on + int runBit = e.hash & bit; + Node lastRun = e, lo = null, hi = null; + for (Node p = e.next; p != null; p = p.next) { + int b = p.hash & bit; + if (b != runBit) { + runBit = b; + lastRun = p; + } + } + if (runBit == 0) + lo = lastRun; + else + hi = lastRun; + for (Node p = e; p != lastRun; p = p.next) { + int ph = p.hash & HASH_BITS; + Object pk = p.key, pv = p.val; + if ((ph & bit) == 0) + lo = new Node(ph, pk, pv, lo); + else + hi = new Node(ph, pk, pv, hi); + } + setTabAt(nextTab, i, lo); + setTabAt(nextTab, i + bit, hi); + } + + /** + * Splits a tree bin into lo and hi parts; installs in given table. + */ + private static void splitTreeBin(AtomicReferenceArray nextTab, int i, TreeBin t) { + int bit = nextTab.length() >>> 1; + TreeBin lt = new TreeBin(); + TreeBin ht = new TreeBin(); + int lc = 0, hc = 0; + for (Node e = t.first; e != null; e = e.next) { + int h = e.hash & HASH_BITS; + Object k = e.key, v = e.val; + if ((h & bit) == 0) { + ++lc; + lt.putTreeNode(h, k, v); + } + else { + ++hc; + ht.putTreeNode(h, k, v); + } + } + Node ln, hn; // throw away trees if too small + if (lc <= (TREE_THRESHOLD >>> 1)) { + ln = null; + for (Node p = lt.first; p != null; p = p.next) + ln = new Node(p.hash, p.key, p.val, ln); + } + else + ln = new Node(MOVED, lt, null, null); + setTabAt(nextTab, i, ln); + if (hc <= (TREE_THRESHOLD >>> 1)) { + hn = null; + for (Node p = ht.first; p != null; p = p.next) + hn = new Node(p.hash, p.key, p.val, hn); + } + else + hn = new Node(MOVED, ht, null, null); + setTabAt(nextTab, i + bit, hn); + } + + /** + * Implementation for clear. Steps through each bin, removing all + * nodes. + */ + private final void internalClear() { + long delta = 0L; // negative number of deletions + int i = 0; + AtomicReferenceArray tab = table; + while (tab != null && i < tab.length()) { + int fh; Object fk; + Node f = tabAt(tab, i); + if (f == null) + ++i; + else if ((fh = f.hash) == MOVED) { + if ((fk = f.key) instanceof TreeBin) { + TreeBin t = (TreeBin)fk; + t.acquire(0); + try { + if (tabAt(tab, i) == f) { + for (Node p = t.first; p != null; p = p.next) { + if (p.val != null) { // (currently always true) + p.val = null; + --delta; + } + } + t.first = null; + t.root = null; + ++i; + } + } finally { + t.release(0); + } + } + else + tab = (AtomicReferenceArray)fk; + } + else if ((fh & LOCKED) != 0) { + counter.add(delta); // opportunistically update count + delta = 0L; + f.tryAwaitLock(tab, i); + } + else if (f.casHash(fh, fh | LOCKED)) { + try { + if (tabAt(tab, i) == f) { + for (Node e = f; e != null; e = e.next) { + if (e.val != null) { // (currently always true) + e.val = null; + --delta; + } + } + setTabAt(tab, i, null); + ++i; + } + } finally { + if (!f.casHash(fh | LOCKED, fh)) { + f.hash = fh; + synchronized (f) { f.notifyAll(); }; + } + } + } + } + if (delta != 0) + counter.add(delta); + } + + /* ----------------Table Traversal -------------- */ + + /** + * Encapsulates traversal for methods such as containsValue; also + * serves as a base class for other iterators and bulk tasks. + * + * At each step, the iterator snapshots the key ("nextKey") and + * value ("nextVal") of a valid node (i.e., one that, at point of + * snapshot, has a non-null user value). Because val fields can + * change (including to null, indicating deletion), field nextVal + * might not be accurate at point of use, but still maintains the + * weak consistency property of holding a value that was once + * valid. To support iterator.remove, the nextKey field is not + * updated (nulled out) when the iterator cannot advance. + * + * Internal traversals directly access these fields, as in: + * {@code while (it.advance() != null) { process(it.nextKey); }} + * + * Exported iterators must track whether the iterator has advanced + * (in hasNext vs next) (by setting/checking/nulling field + * nextVal), and then extract key, value, or key-value pairs as + * return values of next(). + * + * The iterator visits once each still-valid node that was + * reachable upon iterator construction. It might miss some that + * were added to a bin after the bin was visited, which is OK wrt + * consistency guarantees. Maintaining this property in the face + * of possible ongoing resizes requires a fair amount of + * bookkeeping state that is difficult to optimize away amidst + * volatile accesses. Even so, traversal maintains reasonable + * throughput. + * + * Normally, iteration proceeds bin-by-bin traversing lists. + * However, if the table has been resized, then all future steps + * must traverse both the bin at the current index as well as at + * (index + baseSize); and so on for further resizings. To + * paranoically cope with potential sharing by users of iterators + * across threads, iteration terminates if a bounds checks fails + * for a table read. + * + * This class extends ForkJoinTask to streamline parallel + * iteration in bulk operations (see BulkTask). This adds only an + * int of space overhead, which is close enough to negligible in + * cases where it is not needed to not worry about it. Because + * ForkJoinTask is Serializable, but iterators need not be, we + * need to add warning suppressions. + */ + @SuppressWarnings("serial") static class Traverser { + final ConcurrentHashMapV8 map; + Node next; // the next entry to use + K nextKey; // cached key field of next + V nextVal; // cached val field of next + AtomicReferenceArray tab; // current table; updated if resized + int index; // index of bin to use next + int baseIndex; // current index of initial table + int baseLimit; // index bound for initial table + int baseSize; // initial table size + + /** Creates iterator for all entries in the table. */ + Traverser(ConcurrentHashMapV8 map) { + this.map = map; + } + + /** Creates iterator for split() methods */ + Traverser(Traverser it) { + ConcurrentHashMapV8 m; AtomicReferenceArray t; + if ((m = this.map = it.map) == null) + t = null; + else if ((t = it.tab) == null && // force parent tab initialization + (t = it.tab = m.table) != null) + it.baseLimit = it.baseSize = t.length(); + this.tab = t; + this.baseSize = it.baseSize; + it.baseLimit = this.index = this.baseIndex = + ((this.baseLimit = it.baseLimit) + it.baseIndex + 1) >>> 1; + } + + /** + * Advances next; returns nextVal or null if terminated. + * See above for explanation. + */ + final V advance() { + Node e = next; + V ev = null; + outer: do { + if (e != null) // advance past used/skipped node + e = e.next; + while (e == null) { // get to next non-null bin + ConcurrentHashMapV8 m; + AtomicReferenceArray t; int b, i, n; Object ek; // checks must use locals + if ((t = tab) != null) + n = t.length(); + else if ((m = map) != null && (t = tab = m.table) != null) + n = baseLimit = baseSize = t.length(); + else + break outer; + if ((b = baseIndex) >= baseLimit || + (i = index) < 0 || i >= n) + break outer; + if ((e = tabAt(t, i)) != null && e.hash == MOVED) { + if ((ek = e.key) instanceof TreeBin) + e = ((TreeBin)ek).first; + else { + tab = (AtomicReferenceArray)ek; + continue; // restarts due to null val + } + } // visit upper slots if present + index = (i += baseSize) < n ? i : (baseIndex = b + 1); + } + nextKey = (K) e.key; + } while ((ev = (V) e.val) == null); // skip deleted or special nodes + next = e; + return nextVal = ev; + } + + public final void remove() { + Object k = nextKey; + if (k == null && (advance() == null || (k = nextKey) == null)) + throw new IllegalStateException(); + map.internalReplace(k, null, null); + } + + public final boolean hasNext() { + return nextVal != null || advance() != null; + } + + public final boolean hasMoreElements() { return hasNext(); } + public final void setRawResult(Object x) { } + public R getRawResult() { return null; } + public boolean exec() { return true; } + } + + /* ---------------- Public operations -------------- */ + + /** + * Creates a new, empty map with the default initial table size (16). + */ + public ConcurrentHashMapV8() { + this.counter = new LongAdder(); + } + + /** + * Creates a new, empty map with an initial table size + * accommodating the specified number of elements without the need + * to dynamically resize. + * + * @param initialCapacity The implementation performs internal + * sizing to accommodate this many elements. + * @throws IllegalArgumentException if the initial capacity of + * elements is negative + */ + public ConcurrentHashMapV8(int initialCapacity) { + if (initialCapacity < 0) + throw new IllegalArgumentException(); + int cap = ((initialCapacity >= (MAXIMUM_CAPACITY >>> 1)) ? + MAXIMUM_CAPACITY : + tableSizeFor(initialCapacity + (initialCapacity >>> 1) + 1)); + this.counter = new LongAdder(); + this.sizeCtl = cap; + } + + /** + * Creates a new map with the same mappings as the given map. + * + * @param m the map + */ + public ConcurrentHashMapV8(Map m) { + this.counter = new LongAdder(); + this.sizeCtl = DEFAULT_CAPACITY; + internalPutAll(m); + } + + /** + * Creates a new, empty map with an initial table size based on + * the given number of elements ({@code initialCapacity}) and + * initial table density ({@code loadFactor}). + * + * @param initialCapacity the initial capacity. The implementation + * performs internal sizing to accommodate this many elements, + * given the specified load factor. + * @param loadFactor the load factor (table density) for + * establishing the initial table size + * @throws IllegalArgumentException if the initial capacity of + * elements is negative or the load factor is nonpositive + * + * @since 1.6 + */ + public ConcurrentHashMapV8(int initialCapacity, float loadFactor) { + this(initialCapacity, loadFactor, 1); + } + + /** + * Creates a new, empty map with an initial table size based on + * the given number of elements ({@code initialCapacity}), table + * density ({@code loadFactor}), and number of concurrently + * updating threads ({@code concurrencyLevel}). + * + * @param initialCapacity the initial capacity. The implementation + * performs internal sizing to accommodate this many elements, + * given the specified load factor. + * @param loadFactor the load factor (table density) for + * establishing the initial table size + * @param concurrencyLevel the estimated number of concurrently + * updating threads. The implementation may use this value as + * a sizing hint. + * @throws IllegalArgumentException if the initial capacity is + * negative or the load factor or concurrencyLevel are + * nonpositive + */ + public ConcurrentHashMapV8(int initialCapacity, + float loadFactor, int concurrencyLevel) { + if (!(loadFactor > 0.0f) || initialCapacity < 0 || concurrencyLevel <= 0) + throw new IllegalArgumentException(); + if (initialCapacity < concurrencyLevel) // Use at least as many bins + initialCapacity = concurrencyLevel; // as estimated threads + long size = (long)(1.0 + (long)initialCapacity / loadFactor); + int cap = (size >= (long)MAXIMUM_CAPACITY) ? + MAXIMUM_CAPACITY : tableSizeFor((int)size); + this.counter = new LongAdder(); + this.sizeCtl = cap; + } + + /** + * Creates a new {@link Set} backed by a ConcurrentHashMapV8 + * from the given type to {@code Boolean.TRUE}. + * + * @return the new set + */ + public static KeySetView newKeySet() { + return new KeySetView(new ConcurrentHashMapV8(), + Boolean.TRUE); + } + + /** + * Creates a new {@link Set} backed by a ConcurrentHashMapV8 + * from the given type to {@code Boolean.TRUE}. + * + * @param initialCapacity The implementation performs internal + * sizing to accommodate this many elements. + * @throws IllegalArgumentException if the initial capacity of + * elements is negative + * @return the new set + */ + public static KeySetView newKeySet(int initialCapacity) { + return new KeySetView(new ConcurrentHashMapV8(initialCapacity), + Boolean.TRUE); + } + + /** + * {@inheritDoc} + */ + public boolean isEmpty() { + return counter.sum() <= 0L; // ignore transient negative values + } + + /** + * {@inheritDoc} + */ + public int size() { + long n = counter.sum(); + return ((n < 0L) ? 0 : + (n > (long)Integer.MAX_VALUE) ? Integer.MAX_VALUE : + (int)n); + } + + /** + * Returns the number of mappings. This method should be used + * instead of {@link #size} because a ConcurrentHashMapV8 may + * contain more mappings than can be represented as an int. The + * value returned is a snapshot; the actual count may differ if + * there are ongoing concurrent insertions or removals. + * + * @return the number of mappings + */ + public long mappingCount() { + long n = counter.sum(); + return (n < 0L) ? 0L : n; // ignore transient negative values + } + + /** + * Returns the value to which the specified key is mapped, + * or {@code null} if this map contains no mapping for the key. + * + *

More formally, if this map contains a mapping from a key + * {@code k} to a value {@code v} such that {@code key.equals(k)}, + * then this method returns {@code v}; otherwise it returns + * {@code null}. (There can be at most one such mapping.) + * + * @throws NullPointerException if the specified key is null + */ + @SuppressWarnings("unchecked") public V get(Object key) { + if (key == null) + throw new NullPointerException(); + return (V)internalGet(key); + } + + /** + * Returns the value to which the specified key is mapped, + * or the given defaultValue if this map contains no mapping for the key. + * + * @param key the key + * @param defaultValue the value to return if this map contains + * no mapping for the given key + * @return the mapping for the key, if present; else the defaultValue + * @throws NullPointerException if the specified key is null + */ + @SuppressWarnings("unchecked") public V getValueOrDefault(Object key, V defaultValue) { + if (key == null) + throw new NullPointerException(); + V v = (V) internalGet(key); + return v == null ? defaultValue : v; + } + + /** + * Tests if the specified object is a key in this table. + * + * @param key possible key + * @return {@code true} if and only if the specified object + * is a key in this table, as determined by the + * {@code equals} method; {@code false} otherwise + * @throws NullPointerException if the specified key is null + */ + public boolean containsKey(Object key) { + if (key == null) + throw new NullPointerException(); + return internalGet(key) != null; + } + + /** + * Returns {@code true} if this map maps one or more keys to the + * specified value. Note: This method may require a full traversal + * of the map, and is much slower than method {@code containsKey}. + * + * @param value value whose presence in this map is to be tested + * @return {@code true} if this map maps one or more keys to the + * specified value + * @throws NullPointerException if the specified value is null + */ + public boolean containsValue(Object value) { + if (value == null) + throw new NullPointerException(); + Object v; + Traverser it = new Traverser(this); + while ((v = it.advance()) != null) { + if (v == value || value.equals(v)) + return true; + } + return false; + } + + public K findKey(Object value) { + if (value == null) + throw new NullPointerException(); + Object v; + Traverser it = new Traverser(this); + while ((v = it.advance()) != null) { + if (v == value || value.equals(v)) + return it.nextKey; + } + return null; + } + + /** + * Legacy method testing if some key maps into the specified value + * in this table. This method is identical in functionality to + * {@link #containsValue}, and exists solely to ensure + * full compatibility with class {@link java.util.Hashtable}, + * which supported this method prior to introduction of the + * Java Collections framework. + * + * @param value a value to search for + * @return {@code true} if and only if some key maps to the + * {@code value} argument in this table as + * determined by the {@code equals} method; + * {@code false} otherwise + * @throws NullPointerException if the specified value is null + */ + public boolean contains(Object value) { + return containsValue(value); + } + + /** + * Maps the specified key to the specified value in this table. + * Neither the key nor the value can be null. + * + *

The value can be retrieved by calling the {@code get} method + * with a key that is equal to the original key. + * + * @param key key with which the specified value is to be associated + * @param value value to be associated with the specified key + * @return the previous value associated with {@code key}, or + * {@code null} if there was no mapping for {@code key} + * @throws NullPointerException if the specified key or value is null + */ + @SuppressWarnings("unchecked") public V put(K key, V value) { + if (key == null || value == null) + throw new NullPointerException(); + return (V)internalPut(key, value); + } + + /** + * {@inheritDoc} + * + * @return the previous value associated with the specified key, + * or {@code null} if there was no mapping for the key + * @throws NullPointerException if the specified key or value is null + */ + @SuppressWarnings("unchecked") public V putIfAbsent(K key, V value) { + if (key == null || value == null) + throw new NullPointerException(); + return (V)internalPutIfAbsent(key, value); + } + + /** + * Copies all of the mappings from the specified map to this one. + * These mappings replace any mappings that this map had for any of the + * keys currently in the specified map. + * + * @param m mappings to be stored in this map + */ + public void putAll(Map m) { + internalPutAll(m); + } + + /** + * If the specified key is not already associated with a value, + * computes its value using the given mappingFunction and enters + * it into the map unless null. This is equivalent to + *

 {@code
+     * if (map.containsKey(key))
+     *   return map.get(key);
+     * value = mappingFunction.apply(key);
+     * if (value != null)
+     *   map.put(key, value);
+     * return value;}
+ * + * except that the action is performed atomically. If the + * function returns {@code null} no mapping is recorded. If the + * function itself throws an (unchecked) exception, the exception + * is rethrown to its caller, and no mapping is recorded. Some + * attempted update operations on this map by other threads may be + * blocked while computation is in progress, so the computation + * should be short and simple, and must not attempt to update any + * other mappings of this Map. The most appropriate usage is to + * construct a new object serving as an initial mapped value, or + * memoized result, as in: + * + *
 {@code
+     * map.computeIfAbsent(key, new Fun() {
+     *   public V map(K k) { return new Value(f(k)); }});}
+ * + * @param key key with which the specified value is to be associated + * @param mappingFunction the function to compute a value + * @return the current (existing or computed) value associated with + * the specified key, or null if the computed value is null + * @throws NullPointerException if the specified key or mappingFunction + * is null + * @throws IllegalStateException if the computation detectably + * attempts a recursive update to this map that would + * otherwise never complete + * @throws RuntimeException or Error if the mappingFunction does so, + * in which case the mapping is left unestablished + */ + @SuppressWarnings("unchecked") public V computeIfAbsent + (K key, Fun mappingFunction) { + if (key == null || mappingFunction == null) + throw new NullPointerException(); + return (V)internalComputeIfAbsent(key, mappingFunction); + } + + /** + * If the given key is present, computes a new mapping value given a key and + * its current mapped value. This is equivalent to + *
 {@code
+     *   if (map.containsKey(key)) {
+     *     value = remappingFunction.apply(key, map.get(key));
+     *     if (value != null)
+     *       map.put(key, value);
+     *     else
+     *       map.remove(key);
+     *   }
+     * }
+ * + * except that the action is performed atomically. If the + * function returns {@code null}, the mapping is removed. If the + * function itself throws an (unchecked) exception, the exception + * is rethrown to its caller, and the current mapping is left + * unchanged. Some attempted update operations on this map by + * other threads may be blocked while computation is in progress, + * so the computation should be short and simple, and must not + * attempt to update any other mappings of this Map. For example, + * to either create or append new messages to a value mapping: + * + * @param key key with which the specified value is to be associated + * @param remappingFunction the function to compute a value + * @return the new value associated with the specified key, or null if none + * @throws NullPointerException if the specified key or remappingFunction + * is null + * @throws IllegalStateException if the computation detectably + * attempts a recursive update to this map that would + * otherwise never complete + * @throws RuntimeException or Error if the remappingFunction does so, + * in which case the mapping is unchanged + */ + @SuppressWarnings("unchecked") public V computeIfPresent + (K key, BiFun remappingFunction) { + if (key == null || remappingFunction == null) + throw new NullPointerException(); + return (V)internalCompute(key, true, remappingFunction); + } + + /** + * Computes a new mapping value given a key and + * its current mapped value (or {@code null} if there is no current + * mapping). This is equivalent to + *
 {@code
+     *   value = remappingFunction.apply(key, map.get(key));
+     *   if (value != null)
+     *     map.put(key, value);
+     *   else
+     *     map.remove(key);
+     * }
+ * + * except that the action is performed atomically. If the + * function returns {@code null}, the mapping is removed. If the + * function itself throws an (unchecked) exception, the exception + * is rethrown to its caller, and the current mapping is left + * unchanged. Some attempted update operations on this map by + * other threads may be blocked while computation is in progress, + * so the computation should be short and simple, and must not + * attempt to update any other mappings of this Map. For example, + * to either create or append new messages to a value mapping: + * + *
 {@code
+     * Map map = ...;
+     * final String msg = ...;
+     * map.compute(key, new BiFun() {
+     *   public String apply(Key k, String v) {
+     *    return (v == null) ? msg : v + msg;});}}
+ * + * @param key key with which the specified value is to be associated + * @param remappingFunction the function to compute a value + * @return the new value associated with the specified key, or null if none + * @throws NullPointerException if the specified key or remappingFunction + * is null + * @throws IllegalStateException if the computation detectably + * attempts a recursive update to this map that would + * otherwise never complete + * @throws RuntimeException or Error if the remappingFunction does so, + * in which case the mapping is unchanged + */ + @SuppressWarnings("unchecked") public V compute + (K key, BiFun remappingFunction) { + if (key == null || remappingFunction == null) + throw new NullPointerException(); + return (V)internalCompute(key, false, remappingFunction); + } + + /** + * If the specified key is not already associated + * with a value, associate it with the given value. + * Otherwise, replace the value with the results of + * the given remapping function. This is equivalent to: + *
 {@code
+     *   if (!map.containsKey(key))
+     *     map.put(value);
+     *   else {
+     *     newValue = remappingFunction.apply(map.get(key), value);
+     *     if (value != null)
+     *       map.put(key, value);
+     *     else
+     *       map.remove(key);
+     *   }
+     * }
+ * except that the action is performed atomically. If the + * function returns {@code null}, the mapping is removed. If the + * function itself throws an (unchecked) exception, the exception + * is rethrown to its caller, and the current mapping is left + * unchanged. Some attempted update operations on this map by + * other threads may be blocked while computation is in progress, + * so the computation should be short and simple, and must not + * attempt to update any other mappings of this Map. + */ + @SuppressWarnings("unchecked") public V merge + (K key, V value, BiFun remappingFunction) { + if (key == null || value == null || remappingFunction == null) + throw new NullPointerException(); + return (V)internalMerge(key, value, remappingFunction); + } + + /** + * Removes the key (and its corresponding value) from this map. + * This method does nothing if the key is not in the map. + * + * @param key the key that needs to be removed + * @return the previous value associated with {@code key}, or + * {@code null} if there was no mapping for {@code key} + * @throws NullPointerException if the specified key is null + */ + @SuppressWarnings("unchecked") public V remove(Object key) { + if (key == null) + throw new NullPointerException(); + return (V)internalReplace(key, null, null); + } + + /** + * {@inheritDoc} + * + * @throws NullPointerException if the specified key is null + */ + public boolean remove(Object key, Object value) { + if (key == null) + throw new NullPointerException(); + if (value == null) + return false; + return internalReplace(key, null, value) != null; + } + + /** + * {@inheritDoc} + * + * @throws NullPointerException if any of the arguments are null + */ + public boolean replace(K key, V oldValue, V newValue) { + if (key == null || oldValue == null || newValue == null) + throw new NullPointerException(); + return internalReplace(key, newValue, oldValue) != null; + } + + /** + * {@inheritDoc} + * + * @return the previous value associated with the specified key, + * or {@code null} if there was no mapping for the key + * @throws NullPointerException if the specified key or value is null + */ + @SuppressWarnings("unchecked") public V replace(K key, V value) { + if (key == null || value == null) + throw new NullPointerException(); + return (V)internalReplace(key, value, null); + } + + /** + * Removes all of the mappings from this map. + */ + public void clear() { + internalClear(); + } + + /** + * Returns a {@link Set} view of the keys contained in this map. + * The set is backed by the map, so changes to the map are + * reflected in the set, and vice-versa. + * + * @return the set view + */ + public KeySetView keySet() { + KeySetView ks = keySet; + return (ks != null) ? ks : (keySet = new KeySetView(this, null)); + } + + /** + * Returns a {@link Set} view of the keys in this map, using the + * given common mapped value for any additions (i.e., {@link + * Collection#add} and {@link Collection#addAll}). This is of + * course only appropriate if it is acceptable to use the same + * value for all additions from this view. + * + * @param mappedValue the mapped value to use for any + * additions. + * @return the set view + * @throws NullPointerException if the mappedValue is null + */ + public KeySetView keySet(V mappedValue) { + if (mappedValue == null) + throw new NullPointerException(); + return new KeySetView(this, mappedValue); + } + + /** + * Returns a {@link Collection} view of the values contained in this map. + * The collection is backed by the map, so changes to the map are + * reflected in the collection, and vice-versa. + */ + public ValuesView values() { + ValuesView vs = values; + return (vs != null) ? vs : (values = new ValuesView(this)); + } + + /** + * Returns a {@link Set} view of the mappings contained in this map. + * The set is backed by the map, so changes to the map are + * reflected in the set, and vice-versa. The set supports element + * removal, which removes the corresponding mapping from the map, + * via the {@code Iterator.remove}, {@code Set.remove}, + * {@code removeAll}, {@code retainAll}, and {@code clear} + * operations. It does not support the {@code add} or + * {@code addAll} operations. + * + *

The view's {@code iterator} is a "weakly consistent" iterator + * that will never throw {@link ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + */ + public Set> entrySet() { + EntrySetView es = entrySet; + return (es != null) ? es : (entrySet = new EntrySetView(this)); + } + + /** + * Returns an enumeration of the keys in this table. + * + * @return an enumeration of the keys in this table + * @see #keySet() + */ + public Enumeration keys() { + return new KeyIterator(this); + } + + /** + * Returns an enumeration of the values in this table. + * + * @return an enumeration of the values in this table + * @see #values() + */ + public Enumeration elements() { + return new ValueIterator(this); + } + + /** + * Returns a partitionable iterator of the keys in this map. + * + * @return a partitionable iterator of the keys in this map + */ + public Spliterator keySpliterator() { + return new KeyIterator(this); + } + + /** + * Returns a partitionable iterator of the values in this map. + * + * @return a partitionable iterator of the values in this map + */ + public Spliterator valueSpliterator() { + return new ValueIterator(this); + } + + /** + * Returns a partitionable iterator of the entries in this map. + * + * @return a partitionable iterator of the entries in this map + */ + public Spliterator> entrySpliterator() { + return new EntryIterator(this); + } + + /** + * Returns the hash code value for this {@link Map}, i.e., + * the sum of, for each key-value pair in the map, + * {@code key.hashCode() ^ value.hashCode()}. + * + * @return the hash code value for this map + */ + public int hashCode() { + int h = 0; + Traverser it = new Traverser(this); + Object v; + while ((v = it.advance()) != null) { + h += it.nextKey.hashCode() ^ v.hashCode(); + } + return h; + } + + /** + * Returns a string representation of this map. The string + * representation consists of a list of key-value mappings (in no + * particular order) enclosed in braces ("{@code {}}"). Adjacent + * mappings are separated by the characters {@code ", "} (comma + * and space). Each key-value mapping is rendered as the key + * followed by an equals sign ("{@code =}") followed by the + * associated value. + * + * @return a string representation of this map + */ + public String toString() { + Traverser it = new Traverser(this); + StringBuilder sb = new StringBuilder(); + sb.append('{'); + Object v; + if ((v = it.advance()) != null) { + for (;;) { + Object k = it.nextKey; + sb.append(k == this ? "(this Map)" : k); + sb.append('='); + sb.append(v == this ? "(this Map)" : v); + if ((v = it.advance()) == null) + break; + sb.append(',').append(' '); + } + } + return sb.append('}').toString(); + } + + /** + * Compares the specified object with this map for equality. + * Returns {@code true} if the given object is a map with the same + * mappings as this map. This operation may return misleading + * results if either map is concurrently modified during execution + * of this method. + * + * @param o object to be compared for equality with this map + * @return {@code true} if the specified object is equal to this map + */ + public boolean equals(Object o) { + if (o != this) { + if (!(o instanceof Map)) + return false; + Map m = (Map) o; + Traverser it = new Traverser(this); + Object val; + while ((val = it.advance()) != null) { + Object v = m.get(it.nextKey); + if (v == null || (v != val && !v.equals(val))) + return false; + } + for (Map.Entry e : m.entrySet()) { + Object mk, mv, v; + if ((mk = e.getKey()) == null || + (mv = e.getValue()) == null || + (v = internalGet(mk)) == null || + (mv != v && !mv.equals(v))) + return false; + } + } + return true; + } + + /* ----------------Iterators -------------- */ + + @SuppressWarnings("serial") static final class KeyIterator extends Traverser + implements Spliterator, Enumeration { + KeyIterator(ConcurrentHashMapV8 map) { super(map); } + KeyIterator(Traverser it) { + super(it); + } + public KeyIterator split() { + if (nextKey != null) + throw new IllegalStateException(); + return new KeyIterator(this); + } + @SuppressWarnings("unchecked") public final K next() { + if (nextVal == null && advance() == null) + throw new NoSuchElementException(); + Object k = nextKey; + nextVal = null; + return (K) k; + } + + public final K nextElement() { return next(); } + } + + @SuppressWarnings("serial") static final class ValueIterator extends Traverser + implements Spliterator, Enumeration { + ValueIterator(ConcurrentHashMapV8 map) { super(map); } + ValueIterator(Traverser it) { + super(it); + } + public ValueIterator split() { + if (nextKey != null) + throw new IllegalStateException(); + return new ValueIterator(this); + } + + @SuppressWarnings("unchecked") public final V next() { + Object v; + if ((v = nextVal) == null && (v = advance()) == null) + throw new NoSuchElementException(); + nextVal = null; + return (V) v; + } + + public final V nextElement() { return next(); } + } + + @SuppressWarnings("serial") static final class EntryIterator extends Traverser + implements Spliterator> { + EntryIterator(ConcurrentHashMapV8 map) { super(map); } + EntryIterator(Traverser it) { + super(it); + } + public EntryIterator split() { + if (nextKey != null) + throw new IllegalStateException(); + return new EntryIterator(this); + } + + @SuppressWarnings("unchecked") public final Map.Entry next() { + Object v; + if ((v = nextVal) == null && (v = advance()) == null) + throw new NoSuchElementException(); + Object k = nextKey; + nextVal = null; + return new MapEntry((K)k, (V)v, map); + } + } + + /** + * Exported Entry for iterators + */ + static final class MapEntry implements Map.Entry { + final K key; // non-null + V val; // non-null + final ConcurrentHashMapV8 map; + MapEntry(K key, V val, ConcurrentHashMapV8 map) { + this.key = key; + this.val = val; + this.map = map; + } + public final K getKey() { return key; } + public final V getValue() { return val; } + public final int hashCode() { return key.hashCode() ^ val.hashCode(); } + public final String toString(){ return key + "=" + val; } + + public final boolean equals(Object o) { + Object k, v; Map.Entry e; + return ((o instanceof Map.Entry) && + (k = (e = (Map.Entry)o).getKey()) != null && + (v = e.getValue()) != null && + (k == key || k.equals(key)) && + (v == val || v.equals(val))); + } + + /** + * Sets our entry's value and writes through to the map. The + * value to return is somewhat arbitrary here. Since we do not + * necessarily track asynchronous changes, the most recent + * "previous" value could be different from what we return (or + * could even have been removed in which case the put will + * re-establish). We do not and cannot guarantee more. + */ + public final V setValue(V value) { + if (value == null) throw new NullPointerException(); + V v = val; + val = value; + map.put(key, value); + return v; + } + } + + /* ---------------- Serialization Support -------------- */ + + /** + * Stripped-down version of helper class used in previous version, + * declared for the sake of serialization compatibility + */ + static class Segment implements Serializable { + private static final long serialVersionUID = 2249069246763182397L; + final float loadFactor; + Segment(float lf) { this.loadFactor = lf; } + } + + /** + * Saves the state of the {@code ConcurrentHashMapV8} instance to a + * stream (i.e., serializes it). + * @param s the stream + * @serialData + * the key (Object) and value (Object) + * for each key-value mapping, followed by a null pair. + * The key-value mappings are emitted in no particular order. + */ + @SuppressWarnings("unchecked") private void writeObject(java.io.ObjectOutputStream s) + throws java.io.IOException { + if (segments == null) { // for serialization compatibility + segments = (Segment[]) + new Segment[DEFAULT_CONCURRENCY_LEVEL]; + for (int i = 0; i < segments.length; ++i) + segments[i] = new Segment(LOAD_FACTOR); + } + s.defaultWriteObject(); + Traverser it = new Traverser(this); + Object v; + while ((v = it.advance()) != null) { + s.writeObject(it.nextKey); + s.writeObject(v); + } + s.writeObject(null); + s.writeObject(null); + segments = null; // throw away + } + + /** + * Reconstitutes the instance from a stream (that is, deserializes it). + * @param s the stream + */ + @SuppressWarnings("unchecked") private void readObject(java.io.ObjectInputStream s) + throws java.io.IOException, ClassNotFoundException { + s.defaultReadObject(); + this.segments = null; // unneeded + // initialize transient final field + this.counter = new LongAdder(); + + // Create all nodes, then place in table once size is known + long size = 0L; + Node p = null; + for (;;) { + K k = (K) s.readObject(); + V v = (V) s.readObject(); + if (k != null && v != null) { + int h = spread(k.hashCode()); + p = new Node(h, k, v, p); + ++size; + } + else + break; + } + if (p != null) { + boolean init = false; + int n; + if (size >= (long)(MAXIMUM_CAPACITY >>> 1)) + n = MAXIMUM_CAPACITY; + else { + int sz = (int)size; + n = tableSizeFor(sz + (sz >>> 1) + 1); + } + int sc = sizeCtl; + boolean collide = false; + if (n > sc && + SIZE_CTRL_UPDATER.compareAndSet(this, sc, -1)) { + try { + if (table == null) { + init = true; + AtomicReferenceArray tab = new AtomicReferenceArray(n); + int mask = n - 1; + while (p != null) { + int j = p.hash & mask; + Node next = p.next; + Node q = p.next = tabAt(tab, j); + setTabAt(tab, j, p); + if (!collide && q != null && q.hash == p.hash) + collide = true; + p = next; + } + table = tab; + counter.add(size); + sc = n - (n >>> 2); + } + } finally { + sizeCtl = sc; + } + if (collide) { // rescan and convert to TreeBins + AtomicReferenceArray tab = table; + for (int i = 0; i < tab.length(); ++i) { + int c = 0; + for (Node e = tabAt(tab, i); e != null; e = e.next) { + if (++c > TREE_THRESHOLD && + (e.key instanceof Comparable)) { + replaceWithTreeBin(tab, i, e.key); + break; + } + } + } + } + } + if (!init) { // Can only happen if unsafely published. + while (p != null) { + internalPut(p.key, p.val); + p = p.next; + } + } + } + } + + + // ------------------------------------------------------- + + // Sams + /** Interface describing a void action of one argument */ + public interface Action { void apply(A a); } + /** Interface describing a void action of two arguments */ + public interface BiAction { void apply(A a, B b); } + /** Interface describing a function of one argument */ + public interface Generator { T apply(); } + /** Interface describing a function mapping its argument to a double */ + public interface ObjectToDouble { double apply(A a); } + /** Interface describing a function mapping its argument to a long */ + public interface ObjectToLong { long apply(A a); } + /** Interface describing a function mapping its argument to an int */ + public interface ObjectToInt {int apply(A a); } + /** Interface describing a function mapping two arguments to a double */ + public interface ObjectByObjectToDouble { double apply(A a, B b); } + /** Interface describing a function mapping two arguments to a long */ + public interface ObjectByObjectToLong { long apply(A a, B b); } + /** Interface describing a function mapping two arguments to an int */ + public interface ObjectByObjectToInt {int apply(A a, B b); } + /** Interface describing a function mapping a double to a double */ + public interface DoubleToDouble { double apply(double a); } + /** Interface describing a function mapping a long to a long */ + public interface LongToLong { long apply(long a); } + /** Interface describing a function mapping an int to an int */ + public interface IntToInt { int apply(int a); } + /** Interface describing a function mapping two doubles to a double */ + public interface DoubleByDoubleToDouble { double apply(double a, double b); } + /** Interface describing a function mapping two longs to a long */ + public interface LongByLongToLong { long apply(long a, long b); } + /** Interface describing a function mapping two ints to an int */ + public interface IntByIntToInt { int apply(int a, int b); } + + + /* ----------------Views -------------- */ + + /** + * Base class for views. + */ + static abstract class CHMView { + final ConcurrentHashMapV8 map; + CHMView(ConcurrentHashMapV8 map) { this.map = map; } + + /** + * Returns the map backing this view. + * + * @return the map backing this view + */ + public ConcurrentHashMapV8 getMap() { return map; } + + public final int size() { return map.size(); } + public final boolean isEmpty() { return map.isEmpty(); } + public final void clear() { map.clear(); } + + // implementations below rely on concrete classes supplying these + abstract public Iterator iterator(); + abstract public boolean contains(Object o); + abstract public boolean remove(Object o); + + private static final String oomeMsg = "Required array size too large"; + + public final Object[] toArray() { + long sz = map.mappingCount(); + if (sz > (long)(MAX_ARRAY_SIZE)) + throw new OutOfMemoryError(oomeMsg); + int n = (int)sz; + Object[] r = new Object[n]; + int i = 0; + Iterator it = iterator(); + while (it.hasNext()) { + if (i == n) { + if (n >= MAX_ARRAY_SIZE) + throw new OutOfMemoryError(oomeMsg); + if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1) + n = MAX_ARRAY_SIZE; + else + n += (n >>> 1) + 1; + r = Arrays.copyOf(r, n); + } + r[i++] = it.next(); + } + return (i == n) ? r : Arrays.copyOf(r, i); + } + + @SuppressWarnings("unchecked") public final T[] toArray(T[] a) { + long sz = map.mappingCount(); + if (sz > (long)(MAX_ARRAY_SIZE)) + throw new OutOfMemoryError(oomeMsg); + int m = (int)sz; + T[] r = (a.length >= m) ? a : + (T[])java.lang.reflect.Array + .newInstance(a.getClass().getComponentType(), m); + int n = r.length; + int i = 0; + Iterator it = iterator(); + while (it.hasNext()) { + if (i == n) { + if (n >= MAX_ARRAY_SIZE) + throw new OutOfMemoryError(oomeMsg); + if (n >= MAX_ARRAY_SIZE - (MAX_ARRAY_SIZE >>> 1) - 1) + n = MAX_ARRAY_SIZE; + else + n += (n >>> 1) + 1; + r = Arrays.copyOf(r, n); + } + r[i++] = (T)it.next(); + } + if (a == r && i < n) { + r[i] = null; // null-terminate + return r; + } + return (i == n) ? r : Arrays.copyOf(r, i); + } + + public final int hashCode() { + int h = 0; + for (Iterator it = iterator(); it.hasNext();) + h += it.next().hashCode(); + return h; + } + + public final String toString() { + StringBuilder sb = new StringBuilder(); + sb.append('['); + Iterator it = iterator(); + if (it.hasNext()) { + for (;;) { + Object e = it.next(); + sb.append(e == this ? "(this Collection)" : e); + if (!it.hasNext()) + break; + sb.append(',').append(' '); + } + } + return sb.append(']').toString(); + } + + public final boolean containsAll(Collection c) { + if (c != this) { + for (Iterator it = c.iterator(); it.hasNext();) { + Object e = it.next(); + if (e == null || !contains(e)) + return false; + } + } + return true; + } + + public final boolean removeAll(Collection c) { + boolean modified = false; + for (Iterator it = iterator(); it.hasNext();) { + if (c.contains(it.next())) { + it.remove(); + modified = true; + } + } + return modified; + } + + public final boolean retainAll(Collection c) { + boolean modified = false; + for (Iterator it = iterator(); it.hasNext();) { + if (!c.contains(it.next())) { + it.remove(); + modified = true; + } + } + return modified; + } + + } + + /** + * A view of a ConcurrentHashMapV8 as a {@link Set} of keys, in + * which additions may optionally be enabled by mapping to a + * common value. This class cannot be directly instantiated. See + * {@link #keySet}, {@link #keySet(Object)}, {@link #newKeySet()}, + * {@link #newKeySet(int)}. + */ + public static class KeySetView extends CHMView implements Set, java.io.Serializable { + private static final long serialVersionUID = 7249069246763182397L; + private final V value; + KeySetView(ConcurrentHashMapV8 map, V value) { // non-public + super(map); + this.value = value; + } + + /** + * Returns the default mapped value for additions, + * or {@code null} if additions are not supported. + * + * @return the default mapped value for additions, or {@code null} + * if not supported. + */ + public V getMappedValue() { return value; } + + // implement Set API + + public boolean contains(Object o) { return map.containsKey(o); } + public boolean remove(Object o) { return map.remove(o) != null; } + + /** + * Returns a "weakly consistent" iterator that will never + * throw {@link ConcurrentModificationException}, and + * guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not + * guaranteed to) reflect any modifications subsequent to + * construction. + * + * @return an iterator over the keys of this map + */ + public Iterator iterator() { return new KeyIterator(map); } + public boolean add(K e) { + V v; + if ((v = value) == null) + throw new UnsupportedOperationException(); + if (e == null) + throw new NullPointerException(); + return map.internalPutIfAbsent(e, v) == null; + } + public boolean addAll(Collection c) { + boolean added = false; + V v; + if ((v = value) == null) + throw new UnsupportedOperationException(); + for (K e : c) { + if (e == null) + throw new NullPointerException(); + if (map.internalPutIfAbsent(e, v) == null) + added = true; + } + return added; + } + public boolean equals(Object o) { + Set c; + return ((o instanceof Set) && + ((c = (Set)o) == this || + (containsAll(c) && c.containsAll(this)))); + } + } + + /** + * A view of a ConcurrentHashMapV8 as a {@link Collection} of + * values, in which additions are disabled. This class cannot be + * directly instantiated. See {@link #values}, + * + *

The view's {@code iterator} is a "weakly consistent" iterator + * that will never throw {@link ConcurrentModificationException}, + * and guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not guaranteed to) + * reflect any modifications subsequent to construction. + */ + public static final class ValuesView extends CHMView + implements Collection { + ValuesView(ConcurrentHashMapV8 map) { super(map); } + public final boolean contains(Object o) { return map.containsValue(o); } + public final boolean remove(Object o) { + if (o != null) { + Iterator it = new ValueIterator(map); + while (it.hasNext()) { + if (o.equals(it.next())) { + it.remove(); + return true; + } + } + } + return false; + } + + /** + * Returns a "weakly consistent" iterator that will never + * throw {@link ConcurrentModificationException}, and + * guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not + * guaranteed to) reflect any modifications subsequent to + * construction. + * + * @return an iterator over the values of this map + */ + public final Iterator iterator() { + return new ValueIterator(map); + } + public final boolean add(V e) { + throw new UnsupportedOperationException(); + } + public final boolean addAll(Collection c) { + throw new UnsupportedOperationException(); + } + } + + /** + * A view of a ConcurrentHashMapV8 as a {@link Set} of (key, value) + * entries. This class cannot be directly instantiated. See + * {@link #entrySet}. + */ + public static final class EntrySetView extends CHMView + implements Set> { + EntrySetView(ConcurrentHashMapV8 map) { super(map); } + public final boolean contains(Object o) { + Object k, v, r; Map.Entry e; + return ((o instanceof Map.Entry) && + (k = (e = (Map.Entry)o).getKey()) != null && + (r = map.get(k)) != null && + (v = e.getValue()) != null && + (v == r || v.equals(r))); + } + public final boolean remove(Object o) { + Object k, v; Map.Entry e; + return ((o instanceof Map.Entry) && + (k = (e = (Map.Entry)o).getKey()) != null && + (v = e.getValue()) != null && + map.remove(k, v)); + } + + /** + * Returns a "weakly consistent" iterator that will never + * throw {@link ConcurrentModificationException}, and + * guarantees to traverse elements as they existed upon + * construction of the iterator, and may (but is not + * guaranteed to) reflect any modifications subsequent to + * construction. + * + * @return an iterator over the entries of this map + */ + public final Iterator> iterator() { + return new EntryIterator(map); + } + + public final boolean add(Entry e) { + K key = e.getKey(); + V value = e.getValue(); + if (key == null || value == null) + throw new NullPointerException(); + return map.internalPut(key, value) == null; + } + public final boolean addAll(Collection> c) { + boolean added = false; + for (Entry e : c) { + if (add(e)) + added = true; + } + return added; + } + public boolean equals(Object o) { + Set c; + return ((o instanceof Set) && + ((c = (Set)o) == this || + (containsAll(c) && c.containsAll(this)))); + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/LongAdder.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/LongAdder.java new file mode 100644 index 00000000..ecf552a2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/LongAdder.java @@ -0,0 +1,204 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// This is based on 1.9 version. + +package com.concurrent_ruby.ext.jsr166e.nounsafe; + +import java.util.concurrent.atomic.AtomicLong; +import java.io.IOException; +import java.io.Serializable; +import java.io.ObjectInputStream; + +/** + * One or more variables that together maintain an initially zero + * {@code long} sum. When updates (method {@link #add}) are contended + * across threads, the set of variables may grow dynamically to reduce + * contention. Method {@link #sum} (or, equivalently, {@link + * #longValue}) returns the current total combined across the + * variables maintaining the sum. + * + *

This class is usually preferable to {@link AtomicLong} when + * multiple threads update a common sum that is used for purposes such + * as collecting statistics, not for fine-grained synchronization + * control. Under low update contention, the two classes have similar + * characteristics. But under high contention, expected throughput of + * this class is significantly higher, at the expense of higher space + * consumption. + * + *

This class extends {@link Number}, but does not define + * methods such as {@code hashCode} and {@code compareTo} because + * instances are expected to be mutated, and so are not useful as + * collection keys. + * + *

jsr166e note: This class is targeted to be placed in + * java.util.concurrent.atomic. + * + * @since 1.8 + * @author Doug Lea + */ +public class LongAdder extends Striped64 implements Serializable { + private static final long serialVersionUID = 7249069246863182397L; + + /** + * Version of plus for use in retryUpdate + */ + final long fn(long v, long x) { return v + x; } + + /** + * Creates a new adder with initial sum of zero. + */ + public LongAdder() { + } + + /** + * Adds the given value. + * + * @param x the value to add + */ + public void add(long x) { + Cell[] as; long b, v; HashCode hc; Cell a; int n; + if ((as = cells) != null || !casBase(b = base, b + x)) { + boolean uncontended = true; + int h = (hc = threadHashCode.get()).code; + if (as == null || (n = as.length) < 1 || + (a = as[(n - 1) & h]) == null || + !(uncontended = a.cas(v = a.value, v + x))) + retryUpdate(x, hc, uncontended); + } + } + + /** + * Equivalent to {@code add(1)}. + */ + public void increment() { + add(1L); + } + + /** + * Equivalent to {@code add(-1)}. + */ + public void decrement() { + add(-1L); + } + + /** + * Returns the current sum. The returned value is NOT an + * atomic snapshot: Invocation in the absence of concurrent + * updates returns an accurate result, but concurrent updates that + * occur while the sum is being calculated might not be + * incorporated. + * + * @return the sum + */ + public long sum() { + long sum = base; + Cell[] as = cells; + if (as != null) { + int n = as.length; + for (int i = 0; i < n; ++i) { + Cell a = as[i]; + if (a != null) + sum += a.value; + } + } + return sum; + } + + /** + * Resets variables maintaining the sum to zero. This method may + * be a useful alternative to creating a new adder, but is only + * effective if there are no concurrent updates. Because this + * method is intrinsically racy, it should only be used when it is + * known that no threads are concurrently updating. + */ + public void reset() { + internalReset(0L); + } + + /** + * Equivalent in effect to {@link #sum} followed by {@link + * #reset}. This method may apply for example during quiescent + * points between multithreaded computations. If there are + * updates concurrent with this method, the returned value is + * not guaranteed to be the final value occurring before + * the reset. + * + * @return the sum + */ + public long sumThenReset() { + long sum = base; + Cell[] as = cells; + base = 0L; + if (as != null) { + int n = as.length; + for (int i = 0; i < n; ++i) { + Cell a = as[i]; + if (a != null) { + sum += a.value; + a.value = 0L; + } + } + } + return sum; + } + + /** + * Returns the String representation of the {@link #sum}. + * @return the String representation of the {@link #sum} + */ + public String toString() { + return Long.toString(sum()); + } + + /** + * Equivalent to {@link #sum}. + * + * @return the sum + */ + public long longValue() { + return sum(); + } + + /** + * Returns the {@link #sum} as an {@code int} after a narrowing + * primitive conversion. + */ + public int intValue() { + return (int)sum(); + } + + /** + * Returns the {@link #sum} as a {@code float} + * after a widening primitive conversion. + */ + public float floatValue() { + return (float)sum(); + } + + /** + * Returns the {@link #sum} as a {@code double} after a widening + * primitive conversion. + */ + public double doubleValue() { + return (double)sum(); + } + + private void writeObject(java.io.ObjectOutputStream s) + throws java.io.IOException { + s.defaultWriteObject(); + s.writeLong(sum()); + } + + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException { + s.defaultReadObject(); + busy = 0; + cells = null; + base = s.readLong(); + } + +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/Striped64.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/Striped64.java new file mode 100644 index 00000000..f5216424 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166e/nounsafe/Striped64.java @@ -0,0 +1,291 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// This is based on 1.5 version. + +package com.concurrent_ruby.ext.jsr166e.nounsafe; + +import java.util.Random; +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; +import java.util.concurrent.atomic.AtomicLongFieldUpdater; + +/** + * A package-local class holding common representation and mechanics + * for classes supporting dynamic striping on 64bit values. The class + * extends Number so that concrete subclasses must publicly do so. + */ +abstract class Striped64 extends Number { + /* + * This class maintains a lazily-initialized table of atomically + * updated variables, plus an extra "base" field. The table size + * is a power of two. Indexing uses masked per-thread hash codes. + * Nearly all declarations in this class are package-private, + * accessed directly by subclasses. + * + * Table entries are of class Cell; a variant of AtomicLong padded + * to reduce cache contention on most processors. Padding is + * overkill for most Atomics because they are usually irregularly + * scattered in memory and thus don't interfere much with each + * other. But Atomic objects residing in arrays will tend to be + * placed adjacent to each other, and so will most often share + * cache lines (with a huge negative performance impact) without + * this precaution. + * + * In part because Cells are relatively large, we avoid creating + * them until they are needed. When there is no contention, all + * updates are made to the base field. Upon first contention (a + * failed CAS on base update), the table is initialized to size 2. + * The table size is doubled upon further contention until + * reaching the nearest power of two greater than or equal to the + * number of CPUS. Table slots remain empty (null) until they are + * needed. + * + * A single spinlock ("busy") is used for initializing and + * resizing the table, as well as populating slots with new Cells. + * There is no need for a blocking lock: When the lock is not + * available, threads try other slots (or the base). During these + * retries, there is increased contention and reduced locality, + * which is still better than alternatives. + * + * Per-thread hash codes are initialized to random values. + * Contention and/or table collisions are indicated by failed + * CASes when performing an update operation (see method + * retryUpdate). Upon a collision, if the table size is less than + * the capacity, it is doubled in size unless some other thread + * holds the lock. If a hashed slot is empty, and lock is + * available, a new Cell is created. Otherwise, if the slot + * exists, a CAS is tried. Retries proceed by "double hashing", + * using a secondary hash (Marsaglia XorShift) to try to find a + * free slot. + * + * The table size is capped because, when there are more threads + * than CPUs, supposing that each thread were bound to a CPU, + * there would exist a perfect hash function mapping threads to + * slots that eliminates collisions. When we reach capacity, we + * search for this mapping by randomly varying the hash codes of + * colliding threads. Because search is random, and collisions + * only become known via CAS failures, convergence can be slow, + * and because threads are typically not bound to CPUS forever, + * may not occur at all. However, despite these limitations, + * observed contention rates are typically low in these cases. + * + * It is possible for a Cell to become unused when threads that + * once hashed to it terminate, as well as in the case where + * doubling the table causes no thread to hash to it under + * expanded mask. We do not try to detect or remove such cells, + * under the assumption that for long-running instances, observed + * contention levels will recur, so the cells will eventually be + * needed again; and for short-lived ones, it does not matter. + */ + + /** + * Padded variant of AtomicLong supporting only raw accesses plus CAS. + * The value field is placed between pads, hoping that the JVM doesn't + * reorder them. + * + * JVM intrinsics note: It would be possible to use a release-only + * form of CAS here, if it were provided. + */ + static final class Cell { + volatile long p0, p1, p2, p3, p4, p5, p6; + volatile long value; + volatile long q0, q1, q2, q3, q4, q5, q6; + + static AtomicLongFieldUpdater VALUE_UPDATER = AtomicLongFieldUpdater.newUpdater(Cell.class, "value"); + + Cell(long x) { value = x; } + + final boolean cas(long cmp, long val) { + return VALUE_UPDATER.compareAndSet(this, cmp, val); + } + + } + + /** + * Holder for the thread-local hash code. The code is initially + * random, but may be set to a different value upon collisions. + */ + static final class HashCode { + static final Random rng = new Random(); + int code; + HashCode() { + int h = rng.nextInt(); // Avoid zero to allow xorShift rehash + code = (h == 0) ? 1 : h; + } + } + + /** + * The corresponding ThreadLocal class + */ + static final class ThreadHashCode extends ThreadLocal { + public HashCode initialValue() { return new HashCode(); } + } + + /** + * Static per-thread hash codes. Shared across all instances to + * reduce ThreadLocal pollution and because adjustments due to + * collisions in one table are likely to be appropriate for + * others. + */ + static final ThreadHashCode threadHashCode = new ThreadHashCode(); + + /** Number of CPUS, to place bound on table size */ + static final int NCPU = Runtime.getRuntime().availableProcessors(); + + /** + * Table of cells. When non-null, size is a power of 2. + */ + transient volatile Cell[] cells; + + /** + * Base value, used mainly when there is no contention, but also as + * a fallback during table initialization races. Updated via CAS. + */ + transient volatile long base; + + /** + * Spinlock (locked via CAS) used when resizing and/or creating Cells. + */ + transient volatile int busy; + + AtomicLongFieldUpdater BASE_UPDATER = AtomicLongFieldUpdater.newUpdater(Striped64.class, "base"); + AtomicIntegerFieldUpdater BUSY_UPDATER = AtomicIntegerFieldUpdater.newUpdater(Striped64.class, "busy"); + + /** + * Package-private default constructor + */ + Striped64() { + } + + /** + * CASes the base field. + */ + final boolean casBase(long cmp, long val) { + return BASE_UPDATER.compareAndSet(this, cmp, val); + } + + /** + * CASes the busy field from 0 to 1 to acquire lock. + */ + final boolean casBusy() { + return BUSY_UPDATER.compareAndSet(this, 0, 1); + } + + /** + * Computes the function of current and new value. Subclasses + * should open-code this update function for most uses, but the + * virtualized form is needed within retryUpdate. + * + * @param currentValue the current value (of either base or a cell) + * @param newValue the argument from a user update call + * @return result of the update function + */ + abstract long fn(long currentValue, long newValue); + + /** + * Handles cases of updates involving initialization, resizing, + * creating new Cells, and/or contention. See above for + * explanation. This method suffers the usual non-modularity + * problems of optimistic retry code, relying on rechecked sets of + * reads. + * + * @param x the value + * @param hc the hash code holder + * @param wasUncontended false if CAS failed before call + */ + final void retryUpdate(long x, HashCode hc, boolean wasUncontended) { + int h = hc.code; + boolean collide = false; // True if last slot nonempty + for (;;) { + Cell[] as; Cell a; int n; long v; + if ((as = cells) != null && (n = as.length) > 0) { + if ((a = as[(n - 1) & h]) == null) { + if (busy == 0) { // Try to attach new Cell + Cell r = new Cell(x); // Optimistically create + if (busy == 0 && casBusy()) { + boolean created = false; + try { // Recheck under lock + Cell[] rs; int m, j; + if ((rs = cells) != null && + (m = rs.length) > 0 && + rs[j = (m - 1) & h] == null) { + rs[j] = r; + created = true; + } + } finally { + busy = 0; + } + if (created) + break; + continue; // Slot is now non-empty + } + } + collide = false; + } + else if (!wasUncontended) // CAS already known to fail + wasUncontended = true; // Continue after rehash + else if (a.cas(v = a.value, fn(v, x))) + break; + else if (n >= NCPU || cells != as) + collide = false; // At max size or stale + else if (!collide) + collide = true; + else if (busy == 0 && casBusy()) { + try { + if (cells == as) { // Expand table unless stale + Cell[] rs = new Cell[n << 1]; + for (int i = 0; i < n; ++i) + rs[i] = as[i]; + cells = rs; + } + } finally { + busy = 0; + } + collide = false; + continue; // Retry with expanded table + } + h ^= h << 13; // Rehash + h ^= h >>> 17; + h ^= h << 5; + } + else if (busy == 0 && cells == as && casBusy()) { + boolean init = false; + try { // Initialize table + if (cells == as) { + Cell[] rs = new Cell[2]; + rs[h & 1] = new Cell(x); + cells = rs; + init = true; + } + } finally { + busy = 0; + } + if (init) + break; + } + else if (casBase(v = base, fn(v, x))) + break; // Fall back on using base + } + hc.code = h; // Record index for next time + } + + + /** + * Sets base and all cells to the given value. + */ + final void internalReset(long initialValue) { + Cell[] as = cells; + base = initialValue; + if (as != null) { + int n = as.length; + for (int i = 0; i < n; ++i) { + Cell a = as[i]; + if (a != null) + a.value = initialValue; + } + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166y/ThreadLocalRandom.java b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166y/ThreadLocalRandom.java new file mode 100644 index 00000000..3ea409ff --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/ext/concurrent-ruby/com/concurrent_ruby/ext/jsr166y/ThreadLocalRandom.java @@ -0,0 +1,199 @@ +/* + * Written by Doug Lea with assistance from members of JCP JSR-166 + * Expert Group and released to the public domain, as explained at + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +// This is based on 1.16 version + +package com.concurrent_ruby.ext.jsr166y; + +import java.util.Random; + +/** + * A random number generator isolated to the current thread. Like the + * global {@link java.util.Random} generator used by the {@link + * java.lang.Math} class, a {@code ThreadLocalRandom} is initialized + * with an internally generated seed that may not otherwise be + * modified. When applicable, use of {@code ThreadLocalRandom} rather + * than shared {@code Random} objects in concurrent programs will + * typically encounter much less overhead and contention. Use of + * {@code ThreadLocalRandom} is particularly appropriate when multiple + * tasks (for example, each a {@link ForkJoinTask}) use random numbers + * in parallel in thread pools. + * + *

Usages of this class should typically be of the form: + * {@code ThreadLocalRandom.current().nextX(...)} (where + * {@code X} is {@code Int}, {@code Long}, etc). + * When all usages are of this form, it is never possible to + * accidently share a {@code ThreadLocalRandom} across multiple threads. + * + *

This class also provides additional commonly used bounded random + * generation methods. + * + * @since 1.7 + * @author Doug Lea + */ +public class ThreadLocalRandom extends Random { + // same constants as Random, but must be redeclared because private + private static final long multiplier = 0x5DEECE66DL; + private static final long addend = 0xBL; + private static final long mask = (1L << 48) - 1; + + /** + * The random seed. We can't use super.seed. + */ + private long rnd; + + /** + * Initialization flag to permit calls to setSeed to succeed only + * while executing the Random constructor. We can't allow others + * since it would cause setting seed in one part of a program to + * unintentionally impact other usages by the thread. + */ + boolean initialized; + + // Padding to help avoid memory contention among seed updates in + // different TLRs in the common case that they are located near + // each other. + private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7; + + /** + * The actual ThreadLocal + */ + private static final ThreadLocal localRandom = + new ThreadLocal() { + protected ThreadLocalRandom initialValue() { + return new ThreadLocalRandom(); + } + }; + + + /** + * Constructor called only by localRandom.initialValue. + */ + ThreadLocalRandom() { + super(); + initialized = true; + } + + /** + * Returns the current thread's {@code ThreadLocalRandom}. + * + * @return the current thread's {@code ThreadLocalRandom} + */ + public static ThreadLocalRandom current() { + return localRandom.get(); + } + + /** + * Throws {@code UnsupportedOperationException}. Setting seeds in + * this generator is not supported. + * + * @throws UnsupportedOperationException always + */ + public void setSeed(long seed) { + if (initialized) + throw new UnsupportedOperationException(); + rnd = (seed ^ multiplier) & mask; + } + + protected int next(int bits) { + rnd = (rnd * multiplier + addend) & mask; + return (int) (rnd >>> (48-bits)); + } + + /** + * Returns a pseudorandom, uniformly distributed value between the + * given least value (inclusive) and bound (exclusive). + * + * @param least the least value returned + * @param bound the upper bound (exclusive) + * @throws IllegalArgumentException if least greater than or equal + * to bound + * @return the next value + */ + public int nextInt(int least, int bound) { + if (least >= bound) + throw new IllegalArgumentException(); + return nextInt(bound - least) + least; + } + + /** + * Returns a pseudorandom, uniformly distributed value + * between 0 (inclusive) and the specified value (exclusive). + * + * @param n the bound on the random number to be returned. Must be + * positive. + * @return the next value + * @throws IllegalArgumentException if n is not positive + */ + public long nextLong(long n) { + if (n <= 0) + throw new IllegalArgumentException("n must be positive"); + // Divide n by two until small enough for nextInt. On each + // iteration (at most 31 of them but usually much less), + // randomly choose both whether to include high bit in result + // (offset) and whether to continue with the lower vs upper + // half (which makes a difference only if odd). + long offset = 0; + while (n >= Integer.MAX_VALUE) { + int bits = next(2); + long half = n >>> 1; + long nextn = ((bits & 2) == 0) ? half : n - half; + if ((bits & 1) == 0) + offset += n - nextn; + n = nextn; + } + return offset + nextInt((int) n); + } + + /** + * Returns a pseudorandom, uniformly distributed value between the + * given least value (inclusive) and bound (exclusive). + * + * @param least the least value returned + * @param bound the upper bound (exclusive) + * @return the next value + * @throws IllegalArgumentException if least greater than or equal + * to bound + */ + public long nextLong(long least, long bound) { + if (least >= bound) + throw new IllegalArgumentException(); + return nextLong(bound - least) + least; + } + + /** + * Returns a pseudorandom, uniformly distributed {@code double} value + * between 0 (inclusive) and the specified value (exclusive). + * + * @param n the bound on the random number to be returned. Must be + * positive. + * @return the next value + * @throws IllegalArgumentException if n is not positive + */ + public double nextDouble(double n) { + if (n <= 0) + throw new IllegalArgumentException("n must be positive"); + return nextDouble() * n; + } + + /** + * Returns a pseudorandom, uniformly distributed value between the + * given least value (inclusive) and bound (exclusive). + * + * @param least the least value returned + * @param bound the upper bound (exclusive) + * @return the next value + * @throws IllegalArgumentException if least greater than or equal + * to bound + */ + public double nextDouble(double least, double bound) { + if (least >= bound) + throw new IllegalArgumentException(); + return nextDouble() * (bound - least) + least; + } + + private static final long serialVersionUID = -5851777807851030925L; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent-ruby.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent-ruby.rb new file mode 100644 index 00000000..e9a3dea4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent-ruby.rb @@ -0,0 +1,5 @@ +# This file is here so that there is a file with the same name as the gem that +# can be required by Bundler.require. Applications should normally +# require 'concurrent'. + +require_relative "concurrent" diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent.rb new file mode 100644 index 00000000..87de46f1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent.rb @@ -0,0 +1,134 @@ +require 'concurrent/version' +require 'concurrent/constants' +require 'concurrent/errors' +require 'concurrent/configuration' + +require 'concurrent/atomics' +require 'concurrent/executors' +require 'concurrent/synchronization' + +require 'concurrent/atomic/atomic_markable_reference' +require 'concurrent/atomic/atomic_reference' +require 'concurrent/agent' +require 'concurrent/atom' +require 'concurrent/array' +require 'concurrent/hash' +require 'concurrent/set' +require 'concurrent/map' +require 'concurrent/tuple' +require 'concurrent/async' +require 'concurrent/dataflow' +require 'concurrent/delay' +require 'concurrent/exchanger' +require 'concurrent/future' +require 'concurrent/immutable_struct' +require 'concurrent/ivar' +require 'concurrent/maybe' +require 'concurrent/mutable_struct' +require 'concurrent/mvar' +require 'concurrent/promise' +require 'concurrent/scheduled_task' +require 'concurrent/settable_struct' +require 'concurrent/timer_task' +require 'concurrent/tvar' +require 'concurrent/promises' + +require 'concurrent/thread_safe/synchronized_delegator' +require 'concurrent/thread_safe/util' + +require 'concurrent/options' + +# @!macro internal_implementation_note +# +# @note **Private Implementation:** This abstraction is a private, internal +# implementation detail. It should never be used directly. + +# @!macro monotonic_clock_warning +# +# @note Time calculations on all platforms and languages are sensitive to +# changes to the system clock. To alleviate the potential problems +# associated with changing the system clock while an application is running, +# most modern operating systems provide a monotonic clock that operates +# independently of the system clock. A monotonic clock cannot be used to +# determine human-friendly clock times. A monotonic clock is used exclusively +# for calculating time intervals. Not all Ruby platforms provide access to an +# operating system monotonic clock. On these platforms a pure-Ruby monotonic +# clock will be used as a fallback. An operating system monotonic clock is both +# faster and more reliable than the pure-Ruby implementation. The pure-Ruby +# implementation should be fast and reliable enough for most non-realtime +# operations. At this time the common Ruby platforms that provide access to an +# operating system monotonic clock are MRI 2.1 and above and JRuby (all versions). +# +# @see http://linux.die.net/man/3/clock_gettime Linux clock_gettime(3) + +# @!macro copy_options +# +# ## Copy Options +# +# Object references in Ruby are mutable. This can lead to serious +# problems when the {#value} of an object is a mutable reference. Which +# is always the case unless the value is a `Fixnum`, `Symbol`, or similar +# "primitive" data type. Each instance can be configured with a few +# options that can help protect the program from potentially dangerous +# operations. Each of these options can be optionally set when the object +# instance is created: +# +# * `:dup_on_deref` When true the object will call the `#dup` method on +# the `value` object every time the `#value` method is called +# (default: false) +# * `:freeze_on_deref` When true the object will call the `#freeze` +# method on the `value` object every time the `#value` method is called +# (default: false) +# * `:copy_on_deref` When given a `Proc` object the `Proc` will be run +# every time the `#value` method is called. The `Proc` will be given +# the current `value` as its only argument and the result returned by +# the block will be the return value of the `#value` call. When `nil` +# this option will be ignored (default: nil) +# +# When multiple deref options are set the order of operations is strictly defined. +# The order of deref operations is: +# * `:copy_on_deref` +# * `:dup_on_deref` +# * `:freeze_on_deref` +# +# Because of this ordering there is no need to `#freeze` an object created by a +# provided `:copy_on_deref` block. Simply set `:freeze_on_deref` to `true`. +# Setting both `:dup_on_deref` to `true` and `:freeze_on_deref` to `true` is +# as close to the behavior of a "pure" functional language (like Erlang, Clojure, +# or Haskell) as we are likely to get in Ruby. + +# @!macro deref_options +# +# @option opts [Boolean] :dup_on_deref (false) Call `#dup` before +# returning the data from {#value} +# @option opts [Boolean] :freeze_on_deref (false) Call `#freeze` before +# returning the data from {#value} +# @option opts [Proc] :copy_on_deref (nil) When calling the {#value} +# method, call the given proc passing the internal value as the sole +# argument then return the new value returned from the proc. + +# @!macro executor_and_deref_options +# +# @param [Hash] opts the options used to define the behavior at update and deref +# and to specify the executor on which to perform actions +# @option opts [Executor] :executor when set use the given `Executor` instance. +# Three special values are also supported: `:io` returns the global pool for +# long, blocking (IO) tasks, `:fast` returns the global pool for short, fast +# operations, and `:immediate` returns the global `ImmediateExecutor` object. +# @!macro deref_options + +# @!macro warn.edge +# @api Edge +# @note **Edge Features** are under active development and may change frequently. +# +# - Deprecations are not added before incompatible changes. +# - Edge version: _major_ is always 0, _minor_ bump means incompatible change, +# _patch_ bump means compatible change. +# - Edge features may also lack tests and documentation. +# - Features developed in `concurrent-ruby-edge` are expected to move +# to `concurrent-ruby` when finalised. + + +# {include:file:README.md} +module Concurrent +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/agent.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/agent.rb new file mode 100644 index 00000000..dc8a2600 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/agent.rb @@ -0,0 +1,588 @@ +require 'concurrent/configuration' +require 'concurrent/atomic/atomic_reference' +require 'concurrent/atomic/count_down_latch' +require 'concurrent/atomic/thread_local_var' +require 'concurrent/collection/copy_on_write_observer_set' +require 'concurrent/concern/observable' +require 'concurrent/synchronization/lockable_object' + +module Concurrent + + # `Agent` is inspired by Clojure's [agent](http://clojure.org/agents) + # function. An agent is a shared, mutable variable providing independent, + # uncoordinated, *asynchronous* change of individual values. Best used when + # the value will undergo frequent, complex updates. Suitable when the result + # of an update does not need to be known immediately. `Agent` is (mostly) + # functionally equivalent to Clojure's agent, except where the runtime + # prevents parity. + # + # Agents are reactive, not autonomous - there is no imperative message loop + # and no blocking receive. The state of an Agent should be itself immutable + # and the `#value` of an Agent is always immediately available for reading by + # any thread without any messages, i.e. observation does not require + # cooperation or coordination. + # + # Agent action dispatches are made using the various `#send` methods. These + # methods always return immediately. At some point later, in another thread, + # the following will happen: + # + # 1. The given `action` will be applied to the state of the Agent and the + # `args`, if any were supplied. + # 2. The return value of `action` will be passed to the validator lambda, + # if one has been set on the Agent. + # 3. If the validator succeeds or if no validator was given, the return value + # of the given `action` will become the new `#value` of the Agent. See + # `#initialize` for details. + # 4. If any observers were added to the Agent, they will be notified. See + # `#add_observer` for details. + # 5. If during the `action` execution any other dispatches are made (directly + # or indirectly), they will be held until after the `#value` of the Agent + # has been changed. + # + # If any exceptions are thrown by an action function, no nested dispatches + # will occur, and the exception will be cached in the Agent itself. When an + # Agent has errors cached, any subsequent interactions will immediately throw + # an exception, until the agent's errors are cleared. Agent errors can be + # examined with `#error` and the agent restarted with `#restart`. + # + # The actions of all Agents get interleaved amongst threads in a thread pool. + # At any point in time, at most one action for each Agent is being executed. + # Actions dispatched to an agent from another single agent or thread will + # occur in the order they were sent, potentially interleaved with actions + # dispatched to the same agent from other sources. The `#send` method should + # be used for actions that are CPU limited, while the `#send_off` method is + # appropriate for actions that may block on IO. + # + # Unlike in Clojure, `Agent` cannot participate in `Concurrent::TVar` transactions. + # + # ## Example + # + # ``` + # def next_fibonacci(set = nil) + # return [0, 1] if set.nil? + # set + [set[-2..-1].reduce{|sum,x| sum + x }] + # end + # + # # create an agent with an initial value + # agent = Concurrent::Agent.new(next_fibonacci) + # + # # send a few update requests + # 5.times do + # agent.send{|set| next_fibonacci(set) } + # end + # + # # wait for them to complete + # agent.await + # + # # get the current value + # agent.value #=> [0, 1, 1, 2, 3, 5, 8] + # ``` + # + # ## Observation + # + # Agents support observers through the {Concurrent::Observable} mixin module. + # Notification of observers occurs every time an action dispatch returns and + # the new value is successfully validated. Observation will *not* occur if the + # action raises an exception, if validation fails, or when a {#restart} occurs. + # + # When notified the observer will receive three arguments: `time`, `old_value`, + # and `new_value`. The `time` argument is the time at which the value change + # occurred. The `old_value` is the value of the Agent when the action began + # processing. The `new_value` is the value to which the Agent was set when the + # action completed. Note that `old_value` and `new_value` may be the same. + # This is not an error. It simply means that the action returned the same + # value. + # + # ## Nested Actions + # + # It is possible for an Agent action to post further actions back to itself. + # The nested actions will be enqueued normally then processed *after* the + # outer action completes, in the order they were sent, possibly interleaved + # with action dispatches from other threads. Nested actions never deadlock + # with one another and a failure in a nested action will never affect the + # outer action. + # + # Nested actions can be called using the Agent reference from the enclosing + # scope or by passing the reference in as a "send" argument. Nested actions + # cannot be post using `self` from within the action block/proc/lambda; `self` + # in this context will not reference the Agent. The preferred method for + # dispatching nested actions is to pass the Agent as an argument. This allows + # Ruby to more effectively manage the closing scope. + # + # Prefer this: + # + # ``` + # agent = Concurrent::Agent.new(0) + # agent.send(agent) do |value, this| + # this.send {|v| v + 42 } + # 3.14 + # end + # agent.value #=> 45.14 + # ``` + # + # Over this: + # + # ``` + # agent = Concurrent::Agent.new(0) + # agent.send do |value| + # agent.send {|v| v + 42 } + # 3.14 + # end + # ``` + # + # @!macro agent_await_warning + # + # **NOTE** Never, *under any circumstances*, call any of the "await" methods + # ({#await}, {#await_for}, {#await_for!}, and {#wait}) from within an action + # block/proc/lambda. The call will block the Agent and will always fail. + # Calling either {#await} or {#wait} (with a timeout of `nil`) will + # hopelessly deadlock the Agent with no possibility of recovery. + # + # @!macro thread_safe_variable_comparison + # + # @see http://clojure.org/Agents Clojure Agents + # @see http://clojure.org/state Values and Change - Clojure's approach to Identity and State + class Agent < Synchronization::LockableObject + include Concern::Observable + + ERROR_MODES = [:continue, :fail].freeze + private_constant :ERROR_MODES + + AWAIT_FLAG = ::Object.new + private_constant :AWAIT_FLAG + + AWAIT_ACTION = ->(value, latch) { latch.count_down; AWAIT_FLAG } + private_constant :AWAIT_ACTION + + DEFAULT_ERROR_HANDLER = ->(agent, error) { nil } + private_constant :DEFAULT_ERROR_HANDLER + + DEFAULT_VALIDATOR = ->(value) { true } + private_constant :DEFAULT_VALIDATOR + + Job = Struct.new(:action, :args, :executor, :caller) + private_constant :Job + + # Raised during action processing or any other time in an Agent's lifecycle. + class Error < StandardError + def initialize(message = nil) + message ||= 'agent must be restarted before jobs can post' + super(message) + end + end + + # Raised when a new value obtained during action processing or at `#restart` + # fails validation. + class ValidationError < Error + def initialize(message = nil) + message ||= 'invalid value' + super(message) + end + end + + # The error mode this Agent is operating in. See {#initialize} for details. + attr_reader :error_mode + + # Create a new `Agent` with the given initial value and options. + # + # The `:validator` option must be `nil` or a side-effect free proc/lambda + # which takes one argument. On any intended value change the validator, if + # provided, will be called. If the new value is invalid the validator should + # return `false` or raise an error. + # + # The `:error_handler` option must be `nil` or a proc/lambda which takes two + # arguments. When an action raises an error or validation fails, either by + # returning false or raising an error, the error handler will be called. The + # arguments to the error handler will be a reference to the agent itself and + # the error object which was raised. + # + # The `:error_mode` may be either `:continue` (the default if an error + # handler is given) or `:fail` (the default if error handler nil or not + # given). + # + # If an action being run by the agent throws an error or doesn't pass + # validation the error handler, if present, will be called. After the + # handler executes if the error mode is `:continue` the Agent will continue + # as if neither the action that caused the error nor the error itself ever + # happened. + # + # If the mode is `:fail` the Agent will become {#failed?} and will stop + # accepting new action dispatches. Any previously queued actions will be + # held until {#restart} is called. The {#value} method will still work, + # returning the value of the Agent before the error. + # + # @param [Object] initial the initial value + # @param [Hash] opts the configuration options + # + # @option opts [Symbol] :error_mode either `:continue` or `:fail` + # @option opts [nil, Proc] :error_handler the (optional) error handler + # @option opts [nil, Proc] :validator the (optional) validation procedure + def initialize(initial, opts = {}) + super() + synchronize { ns_initialize(initial, opts) } + end + + # The current value (state) of the Agent, irrespective of any pending or + # in-progress actions. The value is always available and is non-blocking. + # + # @return [Object] the current value + def value + @current.value # TODO (pitr 12-Sep-2015): broken unsafe read? + end + + alias_method :deref, :value + + # When {#failed?} and {#error_mode} is `:fail`, returns the error object + # which caused the failure, else `nil`. When {#error_mode} is `:continue` + # will *always* return `nil`. + # + # @return [nil, Error] the error which caused the failure when {#failed?} + def error + @error.value + end + + alias_method :reason, :error + + # @!macro agent_send + # + # Dispatches an action to the Agent and returns immediately. Subsequently, + # in a thread from a thread pool, the {#value} will be set to the return + # value of the action. Action dispatches are only allowed when the Agent + # is not {#failed?}. + # + # The action must be a block/proc/lambda which takes 1 or more arguments. + # The first argument is the current {#value} of the Agent. Any arguments + # passed to the send method via the `args` parameter will be passed to the + # action as the remaining arguments. The action must return the new value + # of the Agent. + # + # * {#send} and {#send!} should be used for actions that are CPU limited + # * {#send_off}, {#send_off!}, and {#<<} are appropriate for actions that + # may block on IO + # * {#send_via} and {#send_via!} are used when a specific executor is to + # be used for the action + # + # @param [Array] args zero or more arguments to be passed to + # the action + # @param [Proc] action the action dispatch to be enqueued + # + # @yield [agent, value, *args] process the old value and return the new + # @yieldparam [Object] value the current {#value} of the Agent + # @yieldparam [Array] args zero or more arguments to pass to the + # action + # @yieldreturn [Object] the new value of the Agent + # + # @!macro send_return + # @return [Boolean] true if the action is successfully enqueued, false if + # the Agent is {#failed?} + def send(*args, &action) + enqueue_action_job(action, args, Concurrent.global_fast_executor) + end + + # @!macro agent_send + # + # @!macro send_bang_return_and_raise + # @return [Boolean] true if the action is successfully enqueued + # @raise [Concurrent::Agent::Error] if the Agent is {#failed?} + def send!(*args, &action) + raise Error.new unless send(*args, &action) + true + end + + # @!macro agent_send + # @!macro send_return + def send_off(*args, &action) + enqueue_action_job(action, args, Concurrent.global_io_executor) + end + + alias_method :post, :send_off + + # @!macro agent_send + # @!macro send_bang_return_and_raise + def send_off!(*args, &action) + raise Error.new unless send_off(*args, &action) + true + end + + # @!macro agent_send + # @!macro send_return + # @param [Concurrent::ExecutorService] executor the executor on which the + # action is to be dispatched + def send_via(executor, *args, &action) + enqueue_action_job(action, args, executor) + end + + # @!macro agent_send + # @!macro send_bang_return_and_raise + # @param [Concurrent::ExecutorService] executor the executor on which the + # action is to be dispatched + def send_via!(executor, *args, &action) + raise Error.new unless send_via(executor, *args, &action) + true + end + + # Dispatches an action to the Agent and returns immediately. Subsequently, + # in a thread from a thread pool, the {#value} will be set to the return + # value of the action. Appropriate for actions that may block on IO. + # + # @param [Proc] action the action dispatch to be enqueued + # @return [Concurrent::Agent] self + # @see #send_off + def <<(action) + send_off(&action) + self + end + + # Blocks the current thread (indefinitely!) until all actions dispatched + # thus far, from this thread or nested by the Agent, have occurred. Will + # block when {#failed?}. Will never return if a failed Agent is {#restart} + # with `:clear_actions` true. + # + # Returns a reference to `self` to support method chaining: + # + # ``` + # current_value = agent.await.value + # ``` + # + # @return [Boolean] self + # + # @!macro agent_await_warning + def await + wait(nil) + self + end + + # Blocks the current thread until all actions dispatched thus far, from this + # thread or nested by the Agent, have occurred, or the timeout (in seconds) + # has elapsed. + # + # @param [Float] timeout the maximum number of seconds to wait + # @return [Boolean] true if all actions complete before timeout else false + # + # @!macro agent_await_warning + def await_for(timeout) + wait(timeout.to_f) + end + + # Blocks the current thread until all actions dispatched thus far, from this + # thread or nested by the Agent, have occurred, or the timeout (in seconds) + # has elapsed. + # + # @param [Float] timeout the maximum number of seconds to wait + # @return [Boolean] true if all actions complete before timeout + # + # @raise [Concurrent::TimeoutError] when timeout is reached + # + # @!macro agent_await_warning + def await_for!(timeout) + raise Concurrent::TimeoutError unless wait(timeout.to_f) + true + end + + # Blocks the current thread until all actions dispatched thus far, from this + # thread or nested by the Agent, have occurred, or the timeout (in seconds) + # has elapsed. Will block indefinitely when timeout is nil or not given. + # + # Provided mainly for consistency with other classes in this library. Prefer + # the various `await` methods instead. + # + # @param [Float] timeout the maximum number of seconds to wait + # @return [Boolean] true if all actions complete before timeout else false + # + # @!macro agent_await_warning + def wait(timeout = nil) + latch = Concurrent::CountDownLatch.new(1) + enqueue_await_job(latch) + latch.wait(timeout) + end + + # Is the Agent in a failed state? + # + # @see #restart + def failed? + !@error.value.nil? + end + + alias_method :stopped?, :failed? + + # When an Agent is {#failed?}, changes the Agent {#value} to `new_value` + # then un-fails the Agent so that action dispatches are allowed again. If + # the `:clear_actions` option is give and true, any actions queued on the + # Agent that were being held while it was failed will be discarded, + # otherwise those held actions will proceed. The `new_value` must pass the + # validator if any, or `restart` will raise an exception and the Agent will + # remain failed with its old {#value} and {#error}. Observers, if any, will + # not be notified of the new state. + # + # @param [Object] new_value the new value for the Agent once restarted + # @param [Hash] opts the configuration options + # @option opts [Symbol] :clear_actions true if all enqueued but unprocessed + # actions should be discarded on restart, else false (default: false) + # @return [Boolean] true + # + # @raise [Concurrent:AgentError] when not failed + def restart(new_value, opts = {}) + clear_actions = opts.fetch(:clear_actions, false) + synchronize do + raise Error.new('agent is not failed') unless failed? + raise ValidationError unless ns_validate(new_value) + @current.value = new_value + @error.value = nil + @queue.clear if clear_actions + ns_post_next_job unless @queue.empty? + end + true + end + + class << self + + # Blocks the current thread (indefinitely!) until all actions dispatched + # thus far to all the given Agents, from this thread or nested by the + # given Agents, have occurred. Will block when any of the agents are + # failed. Will never return if a failed Agent is restart with + # `:clear_actions` true. + # + # @param [Array] agents the Agents on which to wait + # @return [Boolean] true + # + # @!macro agent_await_warning + def await(*agents) + agents.each { |agent| agent.await } + true + end + + # Blocks the current thread until all actions dispatched thus far to all + # the given Agents, from this thread or nested by the given Agents, have + # occurred, or the timeout (in seconds) has elapsed. + # + # @param [Float] timeout the maximum number of seconds to wait + # @param [Array] agents the Agents on which to wait + # @return [Boolean] true if all actions complete before timeout else false + # + # @!macro agent_await_warning + def await_for(timeout, *agents) + end_at = Concurrent.monotonic_time + timeout.to_f + ok = agents.length.times do |i| + break false if (delay = end_at - Concurrent.monotonic_time) < 0 + break false unless agents[i].await_for(delay) + end + !!ok + end + + # Blocks the current thread until all actions dispatched thus far to all + # the given Agents, from this thread or nested by the given Agents, have + # occurred, or the timeout (in seconds) has elapsed. + # + # @param [Float] timeout the maximum number of seconds to wait + # @param [Array] agents the Agents on which to wait + # @return [Boolean] true if all actions complete before timeout + # + # @raise [Concurrent::TimeoutError] when timeout is reached + # @!macro agent_await_warning + def await_for!(timeout, *agents) + raise Concurrent::TimeoutError unless await_for(timeout, *agents) + true + end + end + + private + + def ns_initialize(initial, opts) + @error_mode = opts[:error_mode] + @error_handler = opts[:error_handler] + + if @error_mode && !ERROR_MODES.include?(@error_mode) + raise ArgumentError.new('unrecognized error mode') + elsif @error_mode.nil? + @error_mode = @error_handler ? :continue : :fail + end + + @error_handler ||= DEFAULT_ERROR_HANDLER + @validator = opts.fetch(:validator, DEFAULT_VALIDATOR) + @current = Concurrent::AtomicReference.new(initial) + @error = Concurrent::AtomicReference.new(nil) + @caller = Concurrent::ThreadLocalVar.new(nil) + @queue = [] + + self.observers = Collection::CopyOnNotifyObserverSet.new + end + + def enqueue_action_job(action, args, executor) + raise ArgumentError.new('no action given') unless action + job = Job.new(action, args, executor, @caller.value || Thread.current.object_id) + synchronize { ns_enqueue_job(job) } + end + + def enqueue_await_job(latch) + synchronize do + if (index = ns_find_last_job_for_thread) + job = Job.new(AWAIT_ACTION, [latch], Concurrent.global_immediate_executor, + Thread.current.object_id) + ns_enqueue_job(job, index+1) + else + latch.count_down + true + end + end + end + + def ns_enqueue_job(job, index = nil) + # a non-nil index means this is an await job + return false if index.nil? && failed? + index ||= @queue.length + @queue.insert(index, job) + # if this is the only job, post to executor + ns_post_next_job if @queue.length == 1 + true + end + + def ns_post_next_job + @queue.first.executor.post { execute_next_job } + end + + def execute_next_job + job = synchronize { @queue.first } + old_value = @current.value + + @caller.value = job.caller # for nested actions + new_value = job.action.call(old_value, *job.args) + @caller.value = nil + + return if new_value == AWAIT_FLAG + + if ns_validate(new_value) + @current.value = new_value + observers.notify_observers(Time.now, old_value, new_value) + else + handle_error(ValidationError.new) + end + rescue => error + handle_error(error) + ensure + synchronize do + @queue.shift + unless failed? || @queue.empty? + ns_post_next_job + end + end + end + + def ns_validate(value) + @validator.call(value) + rescue + false + end + + def handle_error(error) + # stop new jobs from posting + @error.value = error if @error_mode == :fail + @error_handler.call(self, error) + rescue + # do nothing + end + + def ns_find_last_job_for_thread + @queue.rindex { |job| job.caller == Thread.current.object_id } + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/array.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/array.rb new file mode 100644 index 00000000..c8761af8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/array.rb @@ -0,0 +1,56 @@ +require 'concurrent/utility/engine' +require 'concurrent/thread_safe/util' + +module Concurrent + + # @!macro concurrent_array + # + # A thread-safe subclass of Array. This version locks against the object + # itself for every method call, ensuring only one thread can be reading + # or writing at a time. This includes iteration methods like `#each`. + # + # @note `a += b` is **not** a **thread-safe** operation on + # `Concurrent::Array`. It reads array `a`, then it creates new `Concurrent::Array` + # which is concatenation of `a` and `b`, then it writes the concatenation to `a`. + # The read and write are independent operations they do not form a single atomic + # operation therefore when two `+=` operations are executed concurrently updates + # may be lost. Use `#concat` instead. + # + # @see http://ruby-doc.org/core/Array.html Ruby standard library `Array` + + # @!macro internal_implementation_note + ArrayImplementation = case + when Concurrent.on_cruby? + # Array is not fully thread-safe on CRuby, see + # https://github.com/ruby-concurrency/concurrent-ruby/issues/929 + # So we will need to add synchronization here + ::Array + + when Concurrent.on_jruby? + require 'jruby/synchronized' + + class JRubyArray < ::Array + include JRuby::Synchronized + end + JRubyArray + + when Concurrent.on_truffleruby? + require 'concurrent/thread_safe/util/data_structures' + + class TruffleRubyArray < ::Array + end + + ThreadSafe::Util.make_synchronized_on_truffleruby TruffleRubyArray + TruffleRubyArray + + else + warn 'Possibly unsupported Ruby implementation' + ::Array + end + private_constant :ArrayImplementation + + # @!macro concurrent_array + class Array < ArrayImplementation + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/async.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/async.rb new file mode 100644 index 00000000..97c5a6b2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/async.rb @@ -0,0 +1,449 @@ +require 'concurrent/configuration' +require 'concurrent/ivar' +require 'concurrent/synchronization/lockable_object' + +module Concurrent + + # A mixin module that provides simple asynchronous behavior to a class, + # turning it into a simple actor. Loosely based on Erlang's + # [gen_server](http://www.erlang.org/doc/man/gen_server.html), but without + # supervision or linking. + # + # A more feature-rich {Concurrent::Actor} is also available when the + # capabilities of `Async` are too limited. + # + # ```cucumber + # Feature: + # As a stateful, plain old Ruby class + # I want safe, asynchronous behavior + # So my long-running methods don't block the main thread + # ``` + # + # The `Async` module is a way to mix simple yet powerful asynchronous + # capabilities into any plain old Ruby object or class, turning each object + # into a simple Actor. Method calls are processed on a background thread. The + # caller is free to perform other actions while processing occurs in the + # background. + # + # Method calls to the asynchronous object are made via two proxy methods: + # `async` (alias `cast`) and `await` (alias `call`). These proxy methods post + # the method call to the object's background thread and return a "future" + # which will eventually contain the result of the method call. + # + # This behavior is loosely patterned after Erlang's `gen_server` behavior. + # When an Erlang module implements the `gen_server` behavior it becomes + # inherently asynchronous. The `start` or `start_link` function spawns a + # process (similar to a thread but much more lightweight and efficient) and + # returns the ID of the process. Using the process ID, other processes can + # send messages to the `gen_server` via the `cast` and `call` methods. Unlike + # Erlang's `gen_server`, however, `Async` classes do not support linking or + # supervision trees. + # + # ## Basic Usage + # + # When this module is mixed into a class, objects of the class become inherently + # asynchronous. Each object gets its own background thread on which to post + # asynchronous method calls. Asynchronous method calls are executed in the + # background one at a time in the order they are received. + # + # To create an asynchronous class, simply mix in the `Concurrent::Async` module: + # + # ``` + # class Hello + # include Concurrent::Async + # + # def hello(name) + # "Hello, #{name}!" + # end + # end + # ``` + # + # Mixing this module into a class provides each object two proxy methods: + # `async` and `await`. These methods are thread safe with respect to the + # enclosing object. The former proxy allows methods to be called + # asynchronously by posting to the object's internal thread. The latter proxy + # allows a method to be called synchronously but does so safely with respect + # to any pending asynchronous method calls and ensures proper ordering. Both + # methods return a {Concurrent::IVar} which can be inspected for the result + # of the proxied method call. Calling a method with `async` will return a + # `:pending` `IVar` whereas `await` will return a `:complete` `IVar`. + # + # ``` + # class Echo + # include Concurrent::Async + # + # def echo(msg) + # print "#{msg}\n" + # end + # end + # + # horn = Echo.new + # horn.echo('zero') # synchronous, not thread-safe + # # returns the actual return value of the method + # + # horn.async.echo('one') # asynchronous, non-blocking, thread-safe + # # returns an IVar in the :pending state + # + # horn.await.echo('two') # synchronous, blocking, thread-safe + # # returns an IVar in the :complete state + # ``` + # + # ## Let It Fail + # + # The `async` and `await` proxy methods have built-in error protection based + # on Erlang's famous "let it fail" philosophy. Instance methods should not be + # programmed defensively. When an exception is raised by a delegated method + # the proxy will rescue the exception, expose it to the caller as the `reason` + # attribute of the returned future, then process the next method call. + # + # ## Calling Methods Internally + # + # External method calls should *always* use the `async` and `await` proxy + # methods. When one method calls another method, the `async` proxy should + # rarely be used and the `await` proxy should *never* be used. + # + # When an object calls one of its own methods using the `await` proxy the + # second call will be enqueued *behind* the currently running method call. + # Any attempt to wait on the result will fail as the second call will never + # run until after the current call completes. + # + # Calling a method using the `await` proxy from within a method that was + # itself called using `async` or `await` will irreversibly deadlock the + # object. Do *not* do this, ever. + # + # ## Instance Variables and Attribute Accessors + # + # Instance variables do not need to be thread-safe so long as they are private. + # Asynchronous method calls are processed in the order they are received and + # are processed one at a time. Therefore private instance variables can only + # be accessed by one thread at a time. This is inherently thread-safe. + # + # When using private instance variables within asynchronous methods, the best + # practice is to read the instance variable into a local variable at the start + # of the method then update the instance variable at the *end* of the method. + # This way, should an exception be raised during method execution the internal + # state of the object will not have been changed. + # + # ### Reader Attributes + # + # The use of `attr_reader` is discouraged. Internal state exposed externally, + # when necessary, should be done through accessor methods. The instance + # variables exposed by these methods *must* be thread-safe, or they must be + # called using the `async` and `await` proxy methods. These two approaches are + # subtly different. + # + # When internal state is accessed via the `async` and `await` proxy methods, + # the returned value represents the object's state *at the time the call is + # processed*, which may *not* be the state of the object at the time the call + # is made. + # + # To get the state *at the current* time, irrespective of an enqueued method + # calls, a reader method must be called directly. This is inherently unsafe + # unless the instance variable is itself thread-safe, preferably using one + # of the thread-safe classes within this library. Because the thread-safe + # classes within this library are internally-locking or non-locking, they can + # be safely used from within asynchronous methods without causing deadlocks. + # + # Generally speaking, the best practice is to *not* expose internal state via + # reader methods. The best practice is to simply use the method's return value. + # + # ### Writer Attributes + # + # Writer attributes should never be used with asynchronous classes. Changing + # the state externally, even when done in the thread-safe way, is not logically + # consistent. Changes to state need to be timed with respect to all asynchronous + # method calls which my be in-process or enqueued. The only safe practice is to + # pass all necessary data to each method as arguments and let the method update + # the internal state as necessary. + # + # ## Class Constants, Variables, and Methods + # + # ### Class Constants + # + # Class constants do not need to be thread-safe. Since they are read-only and + # immutable they may be safely read both externally and from within + # asynchronous methods. + # + # ### Class Variables + # + # Class variables should be avoided. Class variables represent shared state. + # Shared state is anathema to concurrency. Should there be a need to share + # state using class variables they *must* be thread-safe, preferably + # using the thread-safe classes within this library. When updating class + # variables, never assign a new value/object to the variable itself. Assignment + # is not thread-safe in Ruby. Instead, use the thread-safe update functions + # of the variable itself to change the value. + # + # The best practice is to *never* use class variables with `Async` classes. + # + # ### Class Methods + # + # Class methods which are pure functions are safe. Class methods which modify + # class variables should be avoided, for all the reasons listed above. + # + # ## An Important Note About Thread Safe Guarantees + # + # > Thread safe guarantees can only be made when asynchronous method calls + # > are not mixed with direct method calls. Use only direct method calls + # > when the object is used exclusively on a single thread. Use only + # > `async` and `await` when the object is shared between threads. Once you + # > call a method using `async` or `await`, you should no longer call methods + # > directly on the object. Use `async` and `await` exclusively from then on. + # + # @example + # + # class Echo + # include Concurrent::Async + # + # def echo(msg) + # print "#{msg}\n" + # end + # end + # + # horn = Echo.new + # horn.echo('zero') # synchronous, not thread-safe + # # returns the actual return value of the method + # + # horn.async.echo('one') # asynchronous, non-blocking, thread-safe + # # returns an IVar in the :pending state + # + # horn.await.echo('two') # synchronous, blocking, thread-safe + # # returns an IVar in the :complete state + # + # @see Concurrent::Actor + # @see https://en.wikipedia.org/wiki/Actor_model "Actor Model" at Wikipedia + # @see http://www.erlang.org/doc/man/gen_server.html Erlang gen_server + # @see http://c2.com/cgi/wiki?LetItCrash "Let It Crash" at http://c2.com/ + module Async + + # @!method self.new(*args, &block) + # + # Instantiate a new object and ensure proper initialization of the + # synchronization mechanisms. + # + # @param [Array] args Zero or more arguments to be passed to the + # object's initializer. + # @param [Proc] block Optional block to pass to the object's initializer. + # @return [Object] A properly initialized object of the asynchronous class. + + # Check for the presence of a method on an object and determine if a given + # set of arguments matches the required arity. + # + # @param [Object] obj the object to check against + # @param [Symbol] method the method to check the object for + # @param [Array] args zero or more arguments for the arity check + # + # @raise [NameError] the object does not respond to `method` method + # @raise [ArgumentError] the given `args` do not match the arity of `method` + # + # @note This check is imperfect because of the way Ruby reports the arity of + # methods with a variable number of arguments. It is possible to determine + # if too few arguments are given but impossible to determine if too many + # arguments are given. This check may also fail to recognize dynamic behavior + # of the object, such as methods simulated with `method_missing`. + # + # @see http://www.ruby-doc.org/core-2.1.1/Method.html#method-i-arity Method#arity + # @see http://ruby-doc.org/core-2.1.0/Object.html#method-i-respond_to-3F Object#respond_to? + # @see http://www.ruby-doc.org/core-2.1.0/BasicObject.html#method-i-method_missing BasicObject#method_missing + # + # @!visibility private + def self.validate_argc(obj, method, *args) + argc = args.length + arity = obj.method(method).arity + + if arity >= 0 && argc != arity + raise ArgumentError.new("wrong number of arguments (#{argc} for #{arity})") + elsif arity < 0 && (arity = (arity + 1).abs) > argc + raise ArgumentError.new("wrong number of arguments (#{argc} for #{arity}..*)") + end + end + + # @!visibility private + def self.included(base) + base.singleton_class.send(:alias_method, :original_new, :new) + base.extend(ClassMethods) + super(base) + end + + # @!visibility private + module ClassMethods + def new(*args, &block) + obj = original_new(*args, &block) + obj.send(:init_synchronization) + obj + end + ruby2_keywords :new if respond_to?(:ruby2_keywords, true) + end + private_constant :ClassMethods + + # Delegates asynchronous, thread-safe method calls to the wrapped object. + # + # @!visibility private + class AsyncDelegator < Synchronization::LockableObject + safe_initialization! + + # Create a new delegator object wrapping the given delegate. + # + # @param [Object] delegate the object to wrap and delegate method calls to + def initialize(delegate) + super() + @delegate = delegate + @queue = [] + @executor = Concurrent.global_io_executor + @ruby_pid = $$ + end + + # Delegates method calls to the wrapped object. + # + # @param [Symbol] method the method being called + # @param [Array] args zero or more arguments to the method + # + # @return [IVar] the result of the method call + # + # @raise [NameError] the object does not respond to `method` method + # @raise [ArgumentError] the given `args` do not match the arity of `method` + def method_missing(method, *args, &block) + super unless @delegate.respond_to?(method) + Async::validate_argc(@delegate, method, *args) + + ivar = Concurrent::IVar.new + synchronize do + reset_if_forked + @queue.push [ivar, method, args, block] + @executor.post { perform } if @queue.length == 1 + end + + ivar + end + + # Check whether the method is responsive + # + # @param [Symbol] method the method being called + def respond_to_missing?(method, include_private = false) + @delegate.respond_to?(method) || super + end + + # Perform all enqueued tasks. + # + # This method must be called from within the executor. It must not be + # called while already running. It will loop until the queue is empty. + def perform + loop do + ivar, method, args, block = synchronize { @queue.first } + break unless ivar # queue is empty + + begin + ivar.set(@delegate.send(method, *args, &block)) + rescue => error + ivar.fail(error) + end + + synchronize do + @queue.shift + return if @queue.empty? + end + end + end + + def reset_if_forked + if $$ != @ruby_pid + @queue.clear + @ruby_pid = $$ + end + end + end + private_constant :AsyncDelegator + + # Delegates synchronous, thread-safe method calls to the wrapped object. + # + # @!visibility private + class AwaitDelegator + + # Create a new delegator object wrapping the given delegate. + # + # @param [AsyncDelegator] delegate the object to wrap and delegate method calls to + def initialize(delegate) + @delegate = delegate + end + + # Delegates method calls to the wrapped object. + # + # @param [Symbol] method the method being called + # @param [Array] args zero or more arguments to the method + # + # @return [IVar] the result of the method call + # + # @raise [NameError] the object does not respond to `method` method + # @raise [ArgumentError] the given `args` do not match the arity of `method` + def method_missing(method, *args, &block) + ivar = @delegate.send(method, *args, &block) + ivar.wait + ivar + end + + # Check whether the method is responsive + # + # @param [Symbol] method the method being called + def respond_to_missing?(method, include_private = false) + @delegate.respond_to?(method) || super + end + end + private_constant :AwaitDelegator + + # Causes the chained method call to be performed asynchronously on the + # object's thread. The delegated method will return a future in the + # `:pending` state and the method call will have been scheduled on the + # object's thread. The final disposition of the method call can be obtained + # by inspecting the returned future. + # + # @!macro async_thread_safety_warning + # @note The method call is guaranteed to be thread safe with respect to + # all other method calls against the same object that are called with + # either `async` or `await`. The mutable nature of Ruby references + # (and object orientation in general) prevent any other thread safety + # guarantees. Do NOT mix direct method calls with delegated method calls. + # Use *only* delegated method calls when sharing the object between threads. + # + # @return [Concurrent::IVar] the pending result of the asynchronous operation + # + # @raise [NameError] the object does not respond to the requested method + # @raise [ArgumentError] the given `args` do not match the arity of + # the requested method + def async + @__async_delegator__ + end + alias_method :cast, :async + + # Causes the chained method call to be performed synchronously on the + # current thread. The delegated will return a future in either the + # `:fulfilled` or `:rejected` state and the delegated method will have + # completed. The final disposition of the delegated method can be obtained + # by inspecting the returned future. + # + # @!macro async_thread_safety_warning + # + # @return [Concurrent::IVar] the completed result of the synchronous operation + # + # @raise [NameError] the object does not respond to the requested method + # @raise [ArgumentError] the given `args` do not match the arity of the + # requested method + def await + @__await_delegator__ + end + alias_method :call, :await + + # Initialize the internal serializer and other stnchronization mechanisms. + # + # @note This method *must* be called immediately upon object construction. + # This is the only way thread-safe initialization can be guaranteed. + # + # @!visibility private + def init_synchronization + return self if defined?(@__async_initialized__) && @__async_initialized__ + @__async_initialized__ = true + @__async_delegator__ = AsyncDelegator.new(self) + @__await_delegator__ = AwaitDelegator.new(@__async_delegator__) + self + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atom.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atom.rb new file mode 100644 index 00000000..f590a23d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atom.rb @@ -0,0 +1,222 @@ +require 'concurrent/atomic/atomic_reference' +require 'concurrent/collection/copy_on_notify_observer_set' +require 'concurrent/concern/observable' +require 'concurrent/synchronization/object' + +# @!macro thread_safe_variable_comparison +# +# ## Thread-safe Variable Classes +# +# Each of the thread-safe variable classes is designed to solve a different +# problem. In general: +# +# * *{Concurrent::Agent}:* Shared, mutable variable providing independent, +# uncoordinated, *asynchronous* change of individual values. Best used when +# the value will undergo frequent, complex updates. Suitable when the result +# of an update does not need to be known immediately. +# * *{Concurrent::Atom}:* Shared, mutable variable providing independent, +# uncoordinated, *synchronous* change of individual values. Best used when +# the value will undergo frequent reads but only occasional, though complex, +# updates. Suitable when the result of an update must be known immediately. +# * *{Concurrent::AtomicReference}:* A simple object reference that can be updated +# atomically. Updates are synchronous but fast. Best used when updates a +# simple set operations. Not suitable when updates are complex. +# {Concurrent::AtomicBoolean} and {Concurrent::AtomicFixnum} are similar +# but optimized for the given data type. +# * *{Concurrent::Exchanger}:* Shared, stateless synchronization point. Used +# when two or more threads need to exchange data. The threads will pair then +# block on each other until the exchange is complete. +# * *{Concurrent::MVar}:* Shared synchronization point. Used when one thread +# must give a value to another, which must take the value. The threads will +# block on each other until the exchange is complete. +# * *{Concurrent::ThreadLocalVar}:* Shared, mutable, isolated variable which +# holds a different value for each thread which has access. Often used as +# an instance variable in objects which must maintain different state +# for different threads. +# * *{Concurrent::TVar}:* Shared, mutable variables which provide +# *coordinated*, *synchronous*, change of *many* stated. Used when multiple +# value must change together, in an all-or-nothing transaction. + + +module Concurrent + + # Atoms provide a way to manage shared, synchronous, independent state. + # + # An atom is initialized with an initial value and an optional validation + # proc. At any time the value of the atom can be synchronously and safely + # changed. If a validator is given at construction then any new value + # will be checked against the validator and will be rejected if the + # validator returns false or raises an exception. + # + # There are two ways to change the value of an atom: {#compare_and_set} and + # {#swap}. The former will set the new value if and only if it validates and + # the current value matches the new value. The latter will atomically set the + # new value to the result of running the given block if and only if that + # value validates. + # + # ## Example + # + # ``` + # def next_fibonacci(set = nil) + # return [0, 1] if set.nil? + # set + [set[-2..-1].reduce{|sum,x| sum + x }] + # end + # + # # create an atom with an initial value + # atom = Concurrent::Atom.new(next_fibonacci) + # + # # send a few update requests + # 5.times do + # atom.swap{|set| next_fibonacci(set) } + # end + # + # # get the current value + # atom.value #=> [0, 1, 1, 2, 3, 5, 8] + # ``` + # + # ## Observation + # + # Atoms support observers through the {Concurrent::Observable} mixin module. + # Notification of observers occurs every time the value of the Atom changes. + # When notified the observer will receive three arguments: `time`, `old_value`, + # and `new_value`. The `time` argument is the time at which the value change + # occurred. The `old_value` is the value of the Atom when the change began + # The `new_value` is the value to which the Atom was set when the change + # completed. Note that `old_value` and `new_value` may be the same. This is + # not an error. It simply means that the change operation returned the same + # value. + # + # Unlike in Clojure, `Atom` cannot participate in {Concurrent::TVar} transactions. + # + # @!macro thread_safe_variable_comparison + # + # @see http://clojure.org/atoms Clojure Atoms + # @see http://clojure.org/state Values and Change - Clojure's approach to Identity and State + class Atom < Synchronization::Object + include Concern::Observable + + safe_initialization! + attr_atomic(:value) + private :value=, :swap_value, :compare_and_set_value, :update_value + public :value + alias_method :deref, :value + + # @!method value + # The current value of the atom. + # + # @return [Object] The current value. + + # Create a new atom with the given initial value. + # + # @param [Object] value The initial value + # @param [Hash] opts The options used to configure the atom + # @option opts [Proc] :validator (nil) Optional proc used to validate new + # values. It must accept one and only one argument which will be the + # intended new value. The validator will return true if the new value + # is acceptable else return false (preferably) or raise an exception. + # + # @!macro deref_options + # + # @raise [ArgumentError] if the validator is not a `Proc` (when given) + def initialize(value, opts = {}) + super() + @Validator = opts.fetch(:validator, -> v { true }) + self.observers = Collection::CopyOnNotifyObserverSet.new + self.value = value + end + + # Atomically swaps the value of atom using the given block. The current + # value will be passed to the block, as will any arguments passed as + # arguments to the function. The new value will be validated against the + # (optional) validator proc given at construction. If validation fails the + # value will not be changed. + # + # Internally, {#swap} reads the current value, applies the block to it, and + # attempts to compare-and-set it in. Since another thread may have changed + # the value in the intervening time, it may have to retry, and does so in a + # spin loop. The net effect is that the value will always be the result of + # the application of the supplied block to a current value, atomically. + # However, because the block might be called multiple times, it must be free + # of side effects. + # + # @note The given block may be called multiple times, and thus should be free + # of side effects. + # + # @param [Object] args Zero or more arguments passed to the block. + # + # @yield [value, args] Calculates a new value for the atom based on the + # current value and any supplied arguments. + # @yieldparam value [Object] The current value of the atom. + # @yieldparam args [Object] All arguments passed to the function, in order. + # @yieldreturn [Object] The intended new value of the atom. + # + # @return [Object] The final value of the atom after all operations and + # validations are complete. + # + # @raise [ArgumentError] When no block is given. + def swap(*args) + raise ArgumentError.new('no block given') unless block_given? + + loop do + old_value = value + new_value = yield(old_value, *args) + begin + break old_value unless valid?(new_value) + break new_value if compare_and_set(old_value, new_value) + rescue + break old_value + end + end + end + + # Atomically sets the value of atom to the new value if and only if the + # current value of the atom is identical to the old value and the new + # value successfully validates against the (optional) validator given + # at construction. + # + # @param [Object] old_value The expected current value. + # @param [Object] new_value The intended new value. + # + # @return [Boolean] True if the value is changed else false. + def compare_and_set(old_value, new_value) + if valid?(new_value) && compare_and_set_value(old_value, new_value) + observers.notify_observers(Time.now, old_value, new_value) + true + else + false + end + end + + # Atomically sets the value of atom to the new value without regard for the + # current value so long as the new value successfully validates against the + # (optional) validator given at construction. + # + # @param [Object] new_value The intended new value. + # + # @return [Object] The final value of the atom after all operations and + # validations are complete. + def reset(new_value) + old_value = value + if valid?(new_value) + self.value = new_value + observers.notify_observers(Time.now, old_value, new_value) + new_value + else + old_value + end + end + + private + + # Is the new value valid? + # + # @param [Object] new_value The intended new value. + # @return [Boolean] false if the validator function returns false or raises + # an exception else true + def valid?(new_value) + @Validator.call(new_value) + rescue + false + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb new file mode 100644 index 00000000..f775691a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/atomic_boolean.rb @@ -0,0 +1,127 @@ +require 'concurrent/utility/native_extension_loader' # load native parts first + +require 'concurrent/atomic/mutex_atomic_boolean' + +module Concurrent + + ################################################################### + + # @!macro atomic_boolean_method_initialize + # + # Creates a new `AtomicBoolean` with the given initial value. + # + # @param [Boolean] initial the initial value + + # @!macro atomic_boolean_method_value_get + # + # Retrieves the current `Boolean` value. + # + # @return [Boolean] the current value + + # @!macro atomic_boolean_method_value_set + # + # Explicitly sets the value. + # + # @param [Boolean] value the new value to be set + # + # @return [Boolean] the current value + + # @!macro atomic_boolean_method_true_question + # + # Is the current value `true` + # + # @return [Boolean] true if the current value is `true`, else false + + # @!macro atomic_boolean_method_false_question + # + # Is the current value `false` + # + # @return [Boolean] true if the current value is `false`, else false + + # @!macro atomic_boolean_method_make_true + # + # Explicitly sets the value to true. + # + # @return [Boolean] true if value has changed, otherwise false + + # @!macro atomic_boolean_method_make_false + # + # Explicitly sets the value to false. + # + # @return [Boolean] true if value has changed, otherwise false + + ################################################################### + + # @!macro atomic_boolean_public_api + # + # @!method initialize(initial = false) + # @!macro atomic_boolean_method_initialize + # + # @!method value + # @!macro atomic_boolean_method_value_get + # + # @!method value=(value) + # @!macro atomic_boolean_method_value_set + # + # @!method true? + # @!macro atomic_boolean_method_true_question + # + # @!method false? + # @!macro atomic_boolean_method_false_question + # + # @!method make_true + # @!macro atomic_boolean_method_make_true + # + # @!method make_false + # @!macro atomic_boolean_method_make_false + + ################################################################### + + # @!visibility private + # @!macro internal_implementation_note + AtomicBooleanImplementation = case + when Concurrent.on_cruby? && Concurrent.c_extensions_loaded? + CAtomicBoolean + when Concurrent.on_jruby? + JavaAtomicBoolean + else + MutexAtomicBoolean + end + private_constant :AtomicBooleanImplementation + + # @!macro atomic_boolean + # + # A boolean value that can be updated atomically. Reads and writes to an atomic + # boolean and thread-safe and guaranteed to succeed. Reads and writes may block + # briefly but no explicit locking is required. + # + # @!macro thread_safe_variable_comparison + # + # Performance: + # + # ``` + # Testing with ruby 2.1.2 + # Testing with Concurrent::MutexAtomicBoolean... + # 2.790000 0.000000 2.790000 ( 2.791454) + # Testing with Concurrent::CAtomicBoolean... + # 0.740000 0.000000 0.740000 ( 0.740206) + # + # Testing with jruby 1.9.3 + # Testing with Concurrent::MutexAtomicBoolean... + # 5.240000 2.520000 7.760000 ( 3.683000) + # Testing with Concurrent::JavaAtomicBoolean... + # 3.340000 0.010000 3.350000 ( 0.855000) + # ``` + # + # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicBoolean.html java.util.concurrent.atomic.AtomicBoolean + # + # @!macro atomic_boolean_public_api + class AtomicBoolean < AtomicBooleanImplementation + # @return [String] Short string representation. + def to_s + format '%s value:%s>', super[0..-2], value + end + + alias_method :inspect, :to_s + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb new file mode 100644 index 00000000..26cd05d8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/atomic_fixnum.rb @@ -0,0 +1,144 @@ +require 'concurrent/utility/native_extension_loader' # load native parts first + +require 'concurrent/atomic/mutex_atomic_fixnum' + +module Concurrent + + ################################################################### + + # @!macro atomic_fixnum_method_initialize + # + # Creates a new `AtomicFixnum` with the given initial value. + # + # @param [Fixnum] initial the initial value + # @raise [ArgumentError] if the initial value is not a `Fixnum` + + # @!macro atomic_fixnum_method_value_get + # + # Retrieves the current `Fixnum` value. + # + # @return [Fixnum] the current value + + # @!macro atomic_fixnum_method_value_set + # + # Explicitly sets the value. + # + # @param [Fixnum] value the new value to be set + # + # @return [Fixnum] the current value + # + # @raise [ArgumentError] if the new value is not a `Fixnum` + + # @!macro atomic_fixnum_method_increment + # + # Increases the current value by the given amount (defaults to 1). + # + # @param [Fixnum] delta the amount by which to increase the current value + # + # @return [Fixnum] the current value after incrementation + + # @!macro atomic_fixnum_method_decrement + # + # Decreases the current value by the given amount (defaults to 1). + # + # @param [Fixnum] delta the amount by which to decrease the current value + # + # @return [Fixnum] the current value after decrementation + + # @!macro atomic_fixnum_method_compare_and_set + # + # Atomically sets the value to the given updated value if the current + # value == the expected value. + # + # @param [Fixnum] expect the expected value + # @param [Fixnum] update the new value + # + # @return [Boolean] true if the value was updated else false + + # @!macro atomic_fixnum_method_update + # + # Pass the current value to the given block, replacing it + # with the block's result. May retry if the value changes + # during the block's execution. + # + # @yield [Object] Calculate a new value for the atomic reference using + # given (old) value + # @yieldparam [Object] old_value the starting value of the atomic reference + # + # @return [Object] the new value + + ################################################################### + + # @!macro atomic_fixnum_public_api + # + # @!method initialize(initial = 0) + # @!macro atomic_fixnum_method_initialize + # + # @!method value + # @!macro atomic_fixnum_method_value_get + # + # @!method value=(value) + # @!macro atomic_fixnum_method_value_set + # + # @!method increment(delta = 1) + # @!macro atomic_fixnum_method_increment + # + # @!method decrement(delta = 1) + # @!macro atomic_fixnum_method_decrement + # + # @!method compare_and_set(expect, update) + # @!macro atomic_fixnum_method_compare_and_set + # + # @!method update + # @!macro atomic_fixnum_method_update + + ################################################################### + + # @!visibility private + # @!macro internal_implementation_note + AtomicFixnumImplementation = case + when Concurrent.on_cruby? && Concurrent.c_extensions_loaded? + CAtomicFixnum + when Concurrent.on_jruby? + JavaAtomicFixnum + else + MutexAtomicFixnum + end + private_constant :AtomicFixnumImplementation + + # @!macro atomic_fixnum + # + # A numeric value that can be updated atomically. Reads and writes to an atomic + # fixnum and thread-safe and guaranteed to succeed. Reads and writes may block + # briefly but no explicit locking is required. + # + # @!macro thread_safe_variable_comparison + # + # Performance: + # + # ``` + # Testing with ruby 2.1.2 + # Testing with Concurrent::MutexAtomicFixnum... + # 3.130000 0.000000 3.130000 ( 3.136505) + # Testing with Concurrent::CAtomicFixnum... + # 0.790000 0.000000 0.790000 ( 0.785550) + # + # Testing with jruby 1.9.3 + # Testing with Concurrent::MutexAtomicFixnum... + # 5.460000 2.460000 7.920000 ( 3.715000) + # Testing with Concurrent::JavaAtomicFixnum... + # 4.520000 0.030000 4.550000 ( 1.187000) + # ``` + # + # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicLong.html java.util.concurrent.atomic.AtomicLong + # + # @!macro atomic_fixnum_public_api + class AtomicFixnum < AtomicFixnumImplementation + # @return [String] Short string representation. + def to_s + format '%s value:%s>', super[0..-2], value + end + + alias_method :inspect, :to_s + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb new file mode 100644 index 00000000..e16be657 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/atomic_markable_reference.rb @@ -0,0 +1,167 @@ +require 'concurrent/errors' +require 'concurrent/synchronization/object' + +module Concurrent + # An atomic reference which maintains an object reference along with a mark bit + # that can be updated atomically. + # + # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicMarkableReference.html + # java.util.concurrent.atomic.AtomicMarkableReference + class AtomicMarkableReference < ::Concurrent::Synchronization::Object + + attr_atomic(:reference) + private :reference, :reference=, :swap_reference, :compare_and_set_reference, :update_reference + + def initialize(value = nil, mark = false) + super() + self.reference = immutable_array(value, mark) + end + + # Atomically sets the value and mark to the given updated value and + # mark given both: + # - the current value == the expected value && + # - the current mark == the expected mark + # + # @param [Object] expected_val the expected value + # @param [Object] new_val the new value + # @param [Boolean] expected_mark the expected mark + # @param [Boolean] new_mark the new mark + # + # @return [Boolean] `true` if successful. A `false` return indicates + # that the actual value was not equal to the expected value or the + # actual mark was not equal to the expected mark + def compare_and_set(expected_val, new_val, expected_mark, new_mark) + # Memoize a valid reference to the current AtomicReference for + # later comparison. + current = reference + curr_val, curr_mark = current + + # Ensure that that the expected marks match. + return false unless expected_mark == curr_mark + + if expected_val.is_a? Numeric + # If the object is a numeric, we need to ensure we are comparing + # the numerical values + return false unless expected_val == curr_val + else + # Otherwise, we need to ensure we are comparing the object identity. + # Theoretically, this could be incorrect if a user monkey-patched + # `Object#equal?`, but they should know that they are playing with + # fire at that point. + return false unless expected_val.equal? curr_val + end + + prospect = immutable_array(new_val, new_mark) + + compare_and_set_reference current, prospect + end + + alias_method :compare_and_swap, :compare_and_set + + # Gets the current reference and marked values. + # + # @return [Array] the current reference and marked values + def get + reference + end + + # Gets the current value of the reference + # + # @return [Object] the current value of the reference + def value + reference[0] + end + + # Gets the current marked value + # + # @return [Boolean] the current marked value + def mark + reference[1] + end + + alias_method :marked?, :mark + + # _Unconditionally_ sets to the given value of both the reference and + # the mark. + # + # @param [Object] new_val the new value + # @param [Boolean] new_mark the new mark + # + # @return [Array] both the new value and the new mark + def set(new_val, new_mark) + self.reference = immutable_array(new_val, new_mark) + end + + # Pass the current value and marked state to the given block, replacing it + # with the block's results. May retry if the value changes during the + # block's execution. + # + # @yield [Object] Calculate a new value and marked state for the atomic + # reference using given (old) value and (old) marked + # @yieldparam [Object] old_val the starting value of the atomic reference + # @yieldparam [Boolean] old_mark the starting state of marked + # + # @return [Array] the new value and new mark + def update + loop do + old_val, old_mark = reference + new_val, new_mark = yield old_val, old_mark + + if compare_and_set old_val, new_val, old_mark, new_mark + return immutable_array(new_val, new_mark) + end + end + end + + # Pass the current value to the given block, replacing it + # with the block's result. Raise an exception if the update + # fails. + # + # @yield [Object] Calculate a new value and marked state for the atomic + # reference using given (old) value and (old) marked + # @yieldparam [Object] old_val the starting value of the atomic reference + # @yieldparam [Boolean] old_mark the starting state of marked + # + # @return [Array] the new value and marked state + # + # @raise [Concurrent::ConcurrentUpdateError] if the update fails + def try_update! + old_val, old_mark = reference + new_val, new_mark = yield old_val, old_mark + + unless compare_and_set old_val, new_val, old_mark, new_mark + fail ::Concurrent::ConcurrentUpdateError, + 'AtomicMarkableReference: Update failed due to race condition.', + 'Note: If you would like to guarantee an update, please use ' + + 'the `AtomicMarkableReference#update` method.' + end + + immutable_array(new_val, new_mark) + end + + # Pass the current value to the given block, replacing it with the + # block's result. Simply return nil if update fails. + # + # @yield [Object] Calculate a new value and marked state for the atomic + # reference using given (old) value and (old) marked + # @yieldparam [Object] old_val the starting value of the atomic reference + # @yieldparam [Boolean] old_mark the starting state of marked + # + # @return [Array] the new value and marked state, or nil if + # the update failed + def try_update + old_val, old_mark = reference + new_val, new_mark = yield old_val, old_mark + + return unless compare_and_set old_val, new_val, old_mark, new_mark + + immutable_array(new_val, new_mark) + end + + private + + def immutable_array(*args) + args.freeze + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb new file mode 100644 index 00000000..bb5fb774 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/atomic_reference.rb @@ -0,0 +1,135 @@ +require 'concurrent/utility/native_extension_loader' # load native parts first + +require 'concurrent/atomic_reference/atomic_direct_update' +require 'concurrent/atomic_reference/numeric_cas_wrapper' +require 'concurrent/atomic_reference/mutex_atomic' + +# Shim for TruffleRuby::AtomicReference +if Concurrent.on_truffleruby? && !defined?(TruffleRuby::AtomicReference) + # @!visibility private + module TruffleRuby + AtomicReference = Truffle::AtomicReference + end +end + +module Concurrent + + # @!macro internal_implementation_note + AtomicReferenceImplementation = case + when Concurrent.on_cruby? && Concurrent.c_extensions_loaded? + # @!visibility private + # @!macro internal_implementation_note + class CAtomicReference + include AtomicDirectUpdate + include AtomicNumericCompareAndSetWrapper + alias_method :compare_and_swap, :compare_and_set + end + CAtomicReference + when Concurrent.on_jruby? + # @!visibility private + # @!macro internal_implementation_note + class JavaAtomicReference + include AtomicDirectUpdate + end + JavaAtomicReference + when Concurrent.on_truffleruby? + class TruffleRubyAtomicReference < TruffleRuby::AtomicReference + include AtomicDirectUpdate + alias_method :value, :get + alias_method :value=, :set + alias_method :compare_and_swap, :compare_and_set + alias_method :swap, :get_and_set + end + TruffleRubyAtomicReference + else + MutexAtomicReference + end + private_constant :AtomicReferenceImplementation + + # An object reference that may be updated atomically. All read and write + # operations have java volatile semantic. + # + # @!macro thread_safe_variable_comparison + # + # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicReference.html + # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/package-summary.html + # + # @!method initialize(value = nil) + # @!macro atomic_reference_method_initialize + # @param [Object] value The initial value. + # + # @!method get + # @!macro atomic_reference_method_get + # Gets the current value. + # @return [Object] the current value + # + # @!method set(new_value) + # @!macro atomic_reference_method_set + # Sets to the given value. + # @param [Object] new_value the new value + # @return [Object] the new value + # + # @!method get_and_set(new_value) + # @!macro atomic_reference_method_get_and_set + # Atomically sets to the given value and returns the old value. + # @param [Object] new_value the new value + # @return [Object] the old value + # + # @!method compare_and_set(old_value, new_value) + # @!macro atomic_reference_method_compare_and_set + # + # Atomically sets the value to the given updated value if + # the current value == the expected value. + # + # @param [Object] old_value the expected value + # @param [Object] new_value the new value + # + # @return [Boolean] `true` if successful. A `false` return indicates + # that the actual value was not equal to the expected value. + # + # @!method update + # Pass the current value to the given block, replacing it + # with the block's result. May retry if the value changes + # during the block's execution. + # + # @yield [Object] Calculate a new value for the atomic reference using + # given (old) value + # @yieldparam [Object] old_value the starting value of the atomic reference + # @return [Object] the new value + # + # @!method try_update + # Pass the current value to the given block, replacing it + # with the block's result. Return nil if the update fails. + # + # @yield [Object] Calculate a new value for the atomic reference using + # given (old) value + # @yieldparam [Object] old_value the starting value of the atomic reference + # @note This method was altered to avoid raising an exception by default. + # Instead, this method now returns `nil` in case of failure. For more info, + # please see: https://github.com/ruby-concurrency/concurrent-ruby/pull/336 + # @return [Object] the new value, or nil if update failed + # + # @!method try_update! + # Pass the current value to the given block, replacing it + # with the block's result. Raise an exception if the update + # fails. + # + # @yield [Object] Calculate a new value for the atomic reference using + # given (old) value + # @yieldparam [Object] old_value the starting value of the atomic reference + # @note This behavior mimics the behavior of the original + # `AtomicReference#try_update` API. The reason this was changed was to + # avoid raising exceptions (which are inherently slow) by default. For more + # info: https://github.com/ruby-concurrency/concurrent-ruby/pull/336 + # @return [Object] the new value + # @raise [Concurrent::ConcurrentUpdateError] if the update fails + class AtomicReference < AtomicReferenceImplementation + + # @return [String] Short string representation. + def to_s + format '%s value:%s>', super[0..-2], get + end + + alias_method :inspect, :to_s + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/count_down_latch.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/count_down_latch.rb new file mode 100644 index 00000000..d883aed6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/count_down_latch.rb @@ -0,0 +1,100 @@ +require 'concurrent/utility/engine' +require 'concurrent/atomic/mutex_count_down_latch' +require 'concurrent/atomic/java_count_down_latch' + +module Concurrent + + ################################################################### + + # @!macro count_down_latch_method_initialize + # + # Create a new `CountDownLatch` with the initial `count`. + # + # @param [new] count the initial count + # + # @raise [ArgumentError] if `count` is not an integer or is less than zero + + # @!macro count_down_latch_method_wait + # + # Block on the latch until the counter reaches zero or until `timeout` is reached. + # + # @param [Fixnum] timeout the number of seconds to wait for the counter or `nil` + # to block indefinitely + # @return [Boolean] `true` if the `count` reaches zero else false on `timeout` + + # @!macro count_down_latch_method_count_down + # + # Signal the latch to decrement the counter. Will signal all blocked threads when + # the `count` reaches zero. + + # @!macro count_down_latch_method_count + # + # The current value of the counter. + # + # @return [Fixnum] the current value of the counter + + ################################################################### + + # @!macro count_down_latch_public_api + # + # @!method initialize(count = 1) + # @!macro count_down_latch_method_initialize + # + # @!method wait(timeout = nil) + # @!macro count_down_latch_method_wait + # + # @!method count_down + # @!macro count_down_latch_method_count_down + # + # @!method count + # @!macro count_down_latch_method_count + + ################################################################### + + # @!visibility private + # @!macro internal_implementation_note + CountDownLatchImplementation = case + when Concurrent.on_jruby? + JavaCountDownLatch + else + MutexCountDownLatch + end + private_constant :CountDownLatchImplementation + + # @!macro count_down_latch + # + # A synchronization object that allows one thread to wait on multiple other threads. + # The thread that will wait creates a `CountDownLatch` and sets the initial value + # (normally equal to the number of other threads). The initiating thread passes the + # latch to the other threads then waits for the other threads by calling the `#wait` + # method. Each of the other threads calls `#count_down` when done with its work. + # When the latch counter reaches zero the waiting thread is unblocked and continues + # with its work. A `CountDownLatch` can be used only once. Its value cannot be reset. + # + # @!macro count_down_latch_public_api + # @example Waiter and Decrementer + # latch = Concurrent::CountDownLatch.new(3) + # + # waiter = Thread.new do + # latch.wait() + # puts ("Waiter released") + # end + # + # decrementer = Thread.new do + # sleep(1) + # latch.count_down + # puts latch.count + # + # sleep(1) + # latch.count_down + # puts latch.count + # + # sleep(1) + # latch.count_down + # puts latch.count + # end + # + # [waiter, decrementer].each(&:join) + class CountDownLatch < CountDownLatchImplementation + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb new file mode 100644 index 00000000..9ebe29dd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/cyclic_barrier.rb @@ -0,0 +1,128 @@ +require 'concurrent/synchronization/lockable_object' +require 'concurrent/utility/native_integer' + +module Concurrent + + # A synchronization aid that allows a set of threads to all wait for each + # other to reach a common barrier point. + # @example + # barrier = Concurrent::CyclicBarrier.new(3) + # jobs = Array.new(3) { |i| -> { sleep i; p done: i } } + # process = -> (i) do + # # waiting to start at the same time + # barrier.wait + # # execute job + # jobs[i].call + # # wait for others to finish + # barrier.wait + # end + # threads = 2.times.map do |i| + # Thread.new(i, &process) + # end + # + # # use main as well + # process.call 2 + # + # # here we can be sure that all jobs are processed + class CyclicBarrier < Synchronization::LockableObject + + # @!visibility private + Generation = Struct.new(:status) + private_constant :Generation + + # Create a new `CyclicBarrier` that waits for `parties` threads + # + # @param [Fixnum] parties the number of parties + # @yield an optional block that will be executed that will be executed after + # the last thread arrives and before the others are released + # + # @raise [ArgumentError] if `parties` is not an integer or is less than zero + def initialize(parties, &block) + Utility::NativeInteger.ensure_integer_and_bounds parties + Utility::NativeInteger.ensure_positive_and_no_zero parties + + super(&nil) + synchronize { ns_initialize parties, &block } + end + + # @return [Fixnum] the number of threads needed to pass the barrier + def parties + synchronize { @parties } + end + + # @return [Fixnum] the number of threads currently waiting on the barrier + def number_waiting + synchronize { @number_waiting } + end + + # Blocks on the barrier until the number of waiting threads is equal to + # `parties` or until `timeout` is reached or `reset` is called + # If a block has been passed to the constructor, it will be executed once by + # the last arrived thread before releasing the others + # @param [Fixnum] timeout the number of seconds to wait for the counter or + # `nil` to block indefinitely + # @return [Boolean] `true` if the `count` reaches zero else false on + # `timeout` or on `reset` or if the barrier is broken + def wait(timeout = nil) + synchronize do + + return false unless @generation.status == :waiting + + @number_waiting += 1 + + if @number_waiting == @parties + @action.call if @action + ns_generation_done @generation, :fulfilled + true + else + generation = @generation + if ns_wait_until(timeout) { generation.status != :waiting } + generation.status == :fulfilled + else + ns_generation_done generation, :broken, false + false + end + end + end + end + + # resets the barrier to its initial state + # If there is at least one waiting thread, it will be woken up, the `wait` + # method will return false and the barrier will be broken + # If the barrier is broken, this method restores it to the original state + # + # @return [nil] + def reset + synchronize { ns_generation_done @generation, :reset } + end + + # A barrier can be broken when: + # - a thread called the `reset` method while at least one other thread was waiting + # - at least one thread timed out on `wait` method + # + # A broken barrier can be restored using `reset` it's safer to create a new one + # @return [Boolean] true if the barrier is broken otherwise false + def broken? + synchronize { @generation.status != :waiting } + end + + protected + + def ns_generation_done(generation, status, continue = true) + generation.status = status + ns_next_generation if continue + ns_broadcast + end + + def ns_next_generation + @generation = Generation.new(:waiting) + @number_waiting = 0 + end + + def ns_initialize(parties, &block) + @parties = parties + @action = block + ns_next_generation + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/event.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/event.rb new file mode 100644 index 00000000..ccf84c9d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/event.rb @@ -0,0 +1,109 @@ +require 'thread' +require 'concurrent/synchronization/lockable_object' + +module Concurrent + + # Old school kernel-style event reminiscent of Win32 programming in C++. + # + # When an `Event` is created it is in the `unset` state. Threads can choose to + # `#wait` on the event, blocking until released by another thread. When one + # thread wants to alert all blocking threads it calls the `#set` method which + # will then wake up all listeners. Once an `Event` has been set it remains set. + # New threads calling `#wait` will return immediately. An `Event` may be + # `#reset` at any time once it has been set. + # + # @see http://msdn.microsoft.com/en-us/library/windows/desktop/ms682655.aspx + # @example + # event = Concurrent::Event.new + # + # t1 = Thread.new do + # puts "t1 is waiting" + # event.wait(1) + # puts "event occurred" + # end + # + # t2 = Thread.new do + # puts "t2 calling set" + # event.set + # end + # + # [t1, t2].each(&:join) + # + # # prints: + # # t1 is waiting + # # t2 calling set + # # event occurred + class Event < Synchronization::LockableObject + + # Creates a new `Event` in the unset state. Threads calling `#wait` on the + # `Event` will block. + def initialize + super + synchronize { ns_initialize } + end + + # Is the object in the set state? + # + # @return [Boolean] indicating whether or not the `Event` has been set + def set? + synchronize { @set } + end + + # Trigger the event, setting the state to `set` and releasing all threads + # waiting on the event. Has no effect if the `Event` has already been set. + # + # @return [Boolean] should always return `true` + def set + synchronize { ns_set } + end + + def try? + synchronize { @set ? false : ns_set } + end + + # Reset a previously set event back to the `unset` state. + # Has no effect if the `Event` has not yet been set. + # + # @return [Boolean] should always return `true` + def reset + synchronize do + if @set + @set = false + @iteration +=1 + end + true + end + end + + # Wait a given number of seconds for the `Event` to be set by another + # thread. Will wait forever when no `timeout` value is given. Returns + # immediately if the `Event` has already been set. + # + # @return [Boolean] true if the `Event` was set before timeout else false + def wait(timeout = nil) + synchronize do + unless @set + iteration = @iteration + ns_wait_until(timeout) { iteration < @iteration || @set } + else + true + end + end + end + + protected + + def ns_set + unless @set + @set = true + ns_broadcast + end + true + end + + def ns_initialize + @set = false + @iteration = 0 + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/fiber_local_var.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/fiber_local_var.rb new file mode 100644 index 00000000..e90fc24f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/fiber_local_var.rb @@ -0,0 +1,109 @@ +require 'concurrent/constants' +require_relative 'locals' + +module Concurrent + + # A `FiberLocalVar` is a variable where the value is different for each fiber. + # Each variable may have a default value, but when you modify the variable only + # the current fiber will ever see that change. + # + # This is similar to Ruby's built-in fiber-local variables (`Thread.current[:name]`), + # but with these major advantages: + # * `FiberLocalVar` has its own identity, it doesn't need a Symbol. + # * Each Ruby's built-in fiber-local variable leaks some memory forever (it's a Symbol held forever on the fiber), + # so it's only OK to create a small amount of them. + # `FiberLocalVar` has no such issue and it is fine to create many of them. + # * Ruby's built-in fiber-local variables leak forever the value set on each fiber (unless set to nil explicitly). + # `FiberLocalVar` automatically removes the mapping for each fiber once the `FiberLocalVar` instance is GC'd. + # + # @example + # v = FiberLocalVar.new(14) + # v.value #=> 14 + # v.value = 2 + # v.value #=> 2 + # + # @example + # v = FiberLocalVar.new(14) + # + # Fiber.new do + # v.value #=> 14 + # v.value = 1 + # v.value #=> 1 + # end.resume + # + # Fiber.new do + # v.value #=> 14 + # v.value = 2 + # v.value #=> 2 + # end.resume + # + # v.value #=> 14 + class FiberLocalVar + LOCALS = FiberLocals.new + + # Creates a fiber local variable. + # + # @param [Object] default the default value when otherwise unset + # @param [Proc] default_block Optional block that gets called to obtain the + # default value for each fiber + def initialize(default = nil, &default_block) + if default && block_given? + raise ArgumentError, "Cannot use both value and block as default value" + end + + if block_given? + @default_block = default_block + @default = nil + else + @default_block = nil + @default = default + end + + @index = LOCALS.next_index(self) + end + + # Returns the value in the current fiber's copy of this fiber-local variable. + # + # @return [Object] the current value + def value + LOCALS.fetch(@index) { default } + end + + # Sets the current fiber's copy of this fiber-local variable to the specified value. + # + # @param [Object] value the value to set + # @return [Object] the new value + def value=(value) + LOCALS.set(@index, value) + end + + # Bind the given value to fiber local storage during + # execution of the given block. + # + # @param [Object] value the value to bind + # @yield the operation to be performed with the bound variable + # @return [Object] the value + def bind(value) + if block_given? + old_value = self.value + self.value = value + begin + yield + ensure + self.value = old_value + end + end + end + + protected + + # @!visibility private + def default + if @default_block + self.value = @default_block.call + else + @default + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/java_count_down_latch.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/java_count_down_latch.rb new file mode 100644 index 00000000..3c119bc3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/java_count_down_latch.rb @@ -0,0 +1,43 @@ +if Concurrent.on_jruby? + require 'concurrent/utility/native_extension_loader' + + module Concurrent + + # @!macro count_down_latch + # @!visibility private + # @!macro internal_implementation_note + class JavaCountDownLatch + + # @!macro count_down_latch_method_initialize + def initialize(count = 1) + Utility::NativeInteger.ensure_integer_and_bounds(count) + Utility::NativeInteger.ensure_positive(count) + @latch = java.util.concurrent.CountDownLatch.new(count) + end + + # @!macro count_down_latch_method_wait + def wait(timeout = nil) + result = nil + if timeout.nil? + Synchronization::JRuby.sleep_interruptibly { @latch.await } + result = true + else + Synchronization::JRuby.sleep_interruptibly do + result = @latch.await(1000 * timeout, java.util.concurrent.TimeUnit::MILLISECONDS) + end + end + result + end + + # @!macro count_down_latch_method_count_down + def count_down + @latch.countDown + end + + # @!macro count_down_latch_method_count + def count + @latch.getCount + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/locals.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/locals.rb new file mode 100644 index 00000000..0a276aed --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/locals.rb @@ -0,0 +1,189 @@ +require 'fiber' +require 'concurrent/utility/engine' +require 'concurrent/constants' + +module Concurrent + # @!visibility private + # @!macro internal_implementation_note + # + # An abstract implementation of local storage, with sub-classes for + # per-thread and per-fiber locals. + # + # Each execution context (EC, thread or fiber) has a lazily initialized array + # of local variable values. Each time a new local variable is created, we + # allocate an "index" for it. + # + # For example, if the allocated index is 1, that means slot #1 in EVERY EC's + # locals array will be used for the value of that variable. + # + # The good thing about using a per-EC structure to hold values, rather than + # a global, is that no synchronization is needed when reading and writing + # those values (since the structure is only ever accessed by a single + # thread). + # + # Of course, when a local variable is GC'd, 1) we need to recover its index + # for use by other new local variables (otherwise the locals arrays could + # get bigger and bigger with time), and 2) we need to null out all the + # references held in the now-unused slots (both to avoid blocking GC of those + # objects, and also to prevent "stale" values from being passed on to a new + # local when the index is reused). + # + # Because we need to null out freed slots, we need to keep references to + # ALL the locals arrays, so we can null out the appropriate slots in all of + # them. This is why we need to use a finalizer to clean up the locals array + # when the EC goes out of scope. + class AbstractLocals + def initialize + @free = [] + @lock = Mutex.new + @all_arrays = {} + @next = 0 + end + + def synchronize + @lock.synchronize { yield } + end + + if Concurrent.on_cruby? + def weak_synchronize + yield + end + else + alias_method :weak_synchronize, :synchronize + end + + def next_index(local) + index = synchronize do + if @free.empty? + @next += 1 + else + @free.pop + end + end + + # When the local goes out of scope, we should free the associated index + # and all values stored into it. + ObjectSpace.define_finalizer(local, local_finalizer(index)) + + index + end + + def free_index(index) + weak_synchronize do + # The cost of GC'ing a TLV is linear in the number of ECs using local + # variables. But that is natural! More ECs means more storage is used + # per local variable. So naturally more CPU time is required to free + # more storage. + # + # DO NOT use each_value which might conflict with new pair assignment + # into the hash in #set method. + @all_arrays.values.each do |locals| + locals[index] = nil + end + + # free index has to be published after the arrays are cleared: + @free << index + end + end + + def fetch(index) + locals = self.locals + value = locals ? locals[index] : nil + + if nil == value + yield + elsif NULL.equal?(value) + nil + else + value + end + end + + def set(index, value) + locals = self.locals! + locals[index] = (nil == value ? NULL : value) + + value + end + + private + + # When the local goes out of scope, clean up that slot across all locals currently assigned. + def local_finalizer(index) + proc do + free_index(index) + end + end + + # When a thread/fiber goes out of scope, remove the array from @all_arrays. + def thread_fiber_finalizer(array_object_id) + proc do + weak_synchronize do + @all_arrays.delete(array_object_id) + end + end + end + + # Returns the locals for the current scope, or nil if none exist. + def locals + raise NotImplementedError + end + + # Returns the locals for the current scope, creating them if necessary. + def locals! + raise NotImplementedError + end + end + + # @!visibility private + # @!macro internal_implementation_note + # An array-backed storage of indexed variables per thread. + class ThreadLocals < AbstractLocals + def locals + Thread.current.thread_variable_get(:concurrent_thread_locals) + end + + def locals! + thread = Thread.current + locals = thread.thread_variable_get(:concurrent_thread_locals) + + unless locals + locals = thread.thread_variable_set(:concurrent_thread_locals, []) + weak_synchronize do + @all_arrays[locals.object_id] = locals + end + # When the thread goes out of scope, we should delete the associated locals: + ObjectSpace.define_finalizer(thread, thread_fiber_finalizer(locals.object_id)) + end + + locals + end + end + + # @!visibility private + # @!macro internal_implementation_note + # An array-backed storage of indexed variables per fiber. + class FiberLocals < AbstractLocals + def locals + Thread.current[:concurrent_fiber_locals] + end + + def locals! + thread = Thread.current + locals = thread[:concurrent_fiber_locals] + + unless locals + locals = thread[:concurrent_fiber_locals] = [] + weak_synchronize do + @all_arrays[locals.object_id] = locals + end + # When the fiber goes out of scope, we should delete the associated locals: + ObjectSpace.define_finalizer(Fiber.current, thread_fiber_finalizer(locals.object_id)) + end + + locals + end + end + + private_constant :AbstractLocals, :ThreadLocals, :FiberLocals +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/lock_local_var.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/lock_local_var.rb new file mode 100644 index 00000000..ebf23a24 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/lock_local_var.rb @@ -0,0 +1,28 @@ +require 'concurrent/utility/engine' +require_relative 'fiber_local_var' +require_relative 'thread_local_var' + +module Concurrent + # @!visibility private + def self.mutex_owned_per_thread? + return false if Concurrent.on_jruby? || Concurrent.on_truffleruby? + + mutex = Mutex.new + # Lock the mutex: + mutex.synchronize do + # Check if the mutex is still owned in a child fiber: + Fiber.new { mutex.owned? }.resume + end + end + + if mutex_owned_per_thread? + LockLocalVar = ThreadLocalVar + else + LockLocalVar = FiberLocalVar + end + + # Either {FiberLocalVar} or {ThreadLocalVar} depending on whether Mutex (and Monitor) + # are held, respectively, per Fiber or per Thread. + class LockLocalVar + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_boolean.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_boolean.rb new file mode 100644 index 00000000..015996b0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_boolean.rb @@ -0,0 +1,68 @@ +require 'concurrent/synchronization/safe_initialization' + +module Concurrent + + # @!macro atomic_boolean + # @!visibility private + # @!macro internal_implementation_note + class MutexAtomicBoolean + extend Concurrent::Synchronization::SafeInitialization + + # @!macro atomic_boolean_method_initialize + def initialize(initial = false) + super() + @Lock = ::Mutex.new + @value = !!initial + end + + # @!macro atomic_boolean_method_value_get + def value + synchronize { @value } + end + + # @!macro atomic_boolean_method_value_set + def value=(value) + synchronize { @value = !!value } + end + + # @!macro atomic_boolean_method_true_question + def true? + synchronize { @value } + end + + # @!macro atomic_boolean_method_false_question + def false? + synchronize { !@value } + end + + # @!macro atomic_boolean_method_make_true + def make_true + synchronize { ns_make_value(true) } + end + + # @!macro atomic_boolean_method_make_false + def make_false + synchronize { ns_make_value(false) } + end + + protected + + # @!visibility private + def synchronize + if @Lock.owned? + yield + else + @Lock.synchronize { yield } + end + end + + private + + # @!visibility private + def ns_make_value(value) + old = @value + @value = value + old != @value + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_fixnum.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_fixnum.rb new file mode 100644 index 00000000..0ca39557 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/mutex_atomic_fixnum.rb @@ -0,0 +1,81 @@ +require 'concurrent/synchronization/safe_initialization' +require 'concurrent/utility/native_integer' + +module Concurrent + + # @!macro atomic_fixnum + # @!visibility private + # @!macro internal_implementation_note + class MutexAtomicFixnum + extend Concurrent::Synchronization::SafeInitialization + + # @!macro atomic_fixnum_method_initialize + def initialize(initial = 0) + super() + @Lock = ::Mutex.new + ns_set(initial) + end + + # @!macro atomic_fixnum_method_value_get + def value + synchronize { @value } + end + + # @!macro atomic_fixnum_method_value_set + def value=(value) + synchronize { ns_set(value) } + end + + # @!macro atomic_fixnum_method_increment + def increment(delta = 1) + synchronize { ns_set(@value + delta.to_i) } + end + + alias_method :up, :increment + + # @!macro atomic_fixnum_method_decrement + def decrement(delta = 1) + synchronize { ns_set(@value - delta.to_i) } + end + + alias_method :down, :decrement + + # @!macro atomic_fixnum_method_compare_and_set + def compare_and_set(expect, update) + synchronize do + if @value == expect.to_i + @value = update.to_i + true + else + false + end + end + end + + # @!macro atomic_fixnum_method_update + def update + synchronize do + @value = yield @value + end + end + + protected + + # @!visibility private + def synchronize + if @Lock.owned? + yield + else + @Lock.synchronize { yield } + end + end + + private + + # @!visibility private + def ns_set(value) + Utility::NativeInteger.ensure_integer_and_bounds value + @value = value + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/mutex_count_down_latch.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/mutex_count_down_latch.rb new file mode 100644 index 00000000..29aa1caa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/mutex_count_down_latch.rb @@ -0,0 +1,44 @@ +require 'concurrent/synchronization/lockable_object' +require 'concurrent/utility/native_integer' + +module Concurrent + + # @!macro count_down_latch + # @!visibility private + # @!macro internal_implementation_note + class MutexCountDownLatch < Synchronization::LockableObject + + # @!macro count_down_latch_method_initialize + def initialize(count = 1) + Utility::NativeInteger.ensure_integer_and_bounds count + Utility::NativeInteger.ensure_positive count + + super() + synchronize { ns_initialize count } + end + + # @!macro count_down_latch_method_wait + def wait(timeout = nil) + synchronize { ns_wait_until(timeout) { @count == 0 } } + end + + # @!macro count_down_latch_method_count_down + def count_down + synchronize do + @count -= 1 if @count > 0 + ns_broadcast if @count == 0 + end + end + + # @!macro count_down_latch_method_count + def count + synchronize { @count } + end + + protected + + def ns_initialize(count) + @count = count + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/mutex_semaphore.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/mutex_semaphore.rb new file mode 100644 index 00000000..4347289f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/mutex_semaphore.rb @@ -0,0 +1,131 @@ +require 'concurrent/synchronization/lockable_object' +require 'concurrent/utility/native_integer' + +module Concurrent + + # @!macro semaphore + # @!visibility private + # @!macro internal_implementation_note + class MutexSemaphore < Synchronization::LockableObject + + # @!macro semaphore_method_initialize + def initialize(count) + Utility::NativeInteger.ensure_integer_and_bounds count + + super() + synchronize { ns_initialize count } + end + + # @!macro semaphore_method_acquire + def acquire(permits = 1) + Utility::NativeInteger.ensure_integer_and_bounds permits + Utility::NativeInteger.ensure_positive permits + + synchronize do + try_acquire_timed(permits, nil) + end + + return unless block_given? + + begin + yield + ensure + release(permits) + end + end + + # @!macro semaphore_method_available_permits + def available_permits + synchronize { @free } + end + + # @!macro semaphore_method_drain_permits + # + # Acquires and returns all permits that are immediately available. + # + # @return [Integer] + def drain_permits + synchronize do + @free.tap { |_| @free = 0 } + end + end + + # @!macro semaphore_method_try_acquire + def try_acquire(permits = 1, timeout = nil) + Utility::NativeInteger.ensure_integer_and_bounds permits + Utility::NativeInteger.ensure_positive permits + + acquired = synchronize do + if timeout.nil? + try_acquire_now(permits) + else + try_acquire_timed(permits, timeout) + end + end + + return acquired unless block_given? + return unless acquired + + begin + yield + ensure + release(permits) + end + end + + # @!macro semaphore_method_release + def release(permits = 1) + Utility::NativeInteger.ensure_integer_and_bounds permits + Utility::NativeInteger.ensure_positive permits + + synchronize do + @free += permits + permits.times { ns_signal } + end + nil + end + + # Shrinks the number of available permits by the indicated reduction. + # + # @param [Fixnum] reduction Number of permits to remove. + # + # @raise [ArgumentError] if `reduction` is not an integer or is negative + # + # @raise [ArgumentError] if `@free` - `@reduction` is less than zero + # + # @return [nil] + # + # @!visibility private + def reduce_permits(reduction) + Utility::NativeInteger.ensure_integer_and_bounds reduction + Utility::NativeInteger.ensure_positive reduction + + synchronize { @free -= reduction } + nil + end + + protected + + # @!visibility private + def ns_initialize(count) + @free = count + end + + private + + # @!visibility private + def try_acquire_now(permits) + if @free >= permits + @free -= permits + true + else + false + end + end + + # @!visibility private + def try_acquire_timed(permits, timeout) + ns_wait_until(timeout) { try_acquire_now(permits) } + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb new file mode 100644 index 00000000..b26bd17a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/read_write_lock.rb @@ -0,0 +1,255 @@ +require 'thread' +require 'concurrent/atomic/atomic_fixnum' +require 'concurrent/errors' +require 'concurrent/synchronization/object' +require 'concurrent/synchronization/lock' + +module Concurrent + + # Ruby read-write lock implementation + # + # Allows any number of concurrent readers, but only one concurrent writer + # (And if the "write" lock is taken, any readers who come along will have to wait) + # + # If readers are already active when a writer comes along, the writer will wait for + # all the readers to finish before going ahead. + # Any additional readers that come when the writer is already waiting, will also + # wait (so writers are not starved). + # + # This implementation is based on `java.util.concurrent.ReentrantReadWriteLock`. + # + # @example + # lock = Concurrent::ReadWriteLock.new + # lock.with_read_lock { data.retrieve } + # lock.with_write_lock { data.modify! } + # + # @note Do **not** try to acquire the write lock while already holding a read lock + # **or** try to acquire the write lock while you already have it. + # This will lead to deadlock + # + # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html java.util.concurrent.ReentrantReadWriteLock + class ReadWriteLock < Synchronization::Object + + # @!visibility private + WAITING_WRITER = 1 << 15 + + # @!visibility private + RUNNING_WRITER = 1 << 29 + + # @!visibility private + MAX_READERS = WAITING_WRITER - 1 + + # @!visibility private + MAX_WRITERS = RUNNING_WRITER - MAX_READERS - 1 + + safe_initialization! + + # Implementation notes: + # A goal is to make the uncontended path for both readers/writers lock-free + # Only if there is reader-writer or writer-writer contention, should locks be used + # Internal state is represented by a single integer ("counter"), and updated + # using atomic compare-and-swap operations + # When the counter is 0, the lock is free + # Each reader increments the counter by 1 when acquiring a read lock + # (and decrements by 1 when releasing the read lock) + # The counter is increased by (1 << 15) for each writer waiting to acquire the + # write lock, and by (1 << 29) if the write lock is taken + + # Create a new `ReadWriteLock` in the unlocked state. + def initialize + super() + @Counter = AtomicFixnum.new(0) # single integer which represents lock state + @ReadLock = Synchronization::Lock.new + @WriteLock = Synchronization::Lock.new + end + + # Execute a block operation within a read lock. + # + # @yield the task to be performed within the lock. + # + # @return [Object] the result of the block operation. + # + # @raise [ArgumentError] when no block is given. + # @raise [Concurrent::ResourceLimitError] if the maximum number of readers + # is exceeded. + def with_read_lock + raise ArgumentError.new('no block given') unless block_given? + acquire_read_lock + begin + yield + ensure + release_read_lock + end + end + + # Execute a block operation within a write lock. + # + # @yield the task to be performed within the lock. + # + # @return [Object] the result of the block operation. + # + # @raise [ArgumentError] when no block is given. + # @raise [Concurrent::ResourceLimitError] if the maximum number of readers + # is exceeded. + def with_write_lock + raise ArgumentError.new('no block given') unless block_given? + acquire_write_lock + begin + yield + ensure + release_write_lock + end + end + + # Acquire a read lock. If a write lock has been acquired will block until + # it is released. Will not block if other read locks have been acquired. + # + # @return [Boolean] true if the lock is successfully acquired + # + # @raise [Concurrent::ResourceLimitError] if the maximum number of readers + # is exceeded. + def acquire_read_lock + while true + c = @Counter.value + raise ResourceLimitError.new('Too many reader threads') if max_readers?(c) + + # If a writer is waiting when we first queue up, we need to wait + if waiting_writer?(c) + @ReadLock.wait_until { !waiting_writer? } + + # after a reader has waited once, they are allowed to "barge" ahead of waiting writers + # but if a writer is *running*, the reader still needs to wait (naturally) + while true + c = @Counter.value + if running_writer?(c) + @ReadLock.wait_until { !running_writer? } + else + return if @Counter.compare_and_set(c, c+1) + end + end + else + break if @Counter.compare_and_set(c, c+1) + end + end + true + end + + # Release a previously acquired read lock. + # + # @return [Boolean] true if the lock is successfully released + def release_read_lock + while true + c = @Counter.value + if @Counter.compare_and_set(c, c-1) + # If one or more writers were waiting, and we were the last reader, wake a writer up + if waiting_writer?(c) && running_readers(c) == 1 + @WriteLock.signal + end + break + end + end + true + end + + # Acquire a write lock. Will block and wait for all active readers and writers. + # + # @return [Boolean] true if the lock is successfully acquired + # + # @raise [Concurrent::ResourceLimitError] if the maximum number of writers + # is exceeded. + def acquire_write_lock + while true + c = @Counter.value + raise ResourceLimitError.new('Too many writer threads') if max_writers?(c) + + if c == 0 # no readers OR writers running + # if we successfully swap the RUNNING_WRITER bit on, then we can go ahead + break if @Counter.compare_and_set(0, RUNNING_WRITER) + elsif @Counter.compare_and_set(c, c+WAITING_WRITER) + while true + # Now we have successfully incremented, so no more readers will be able to increment + # (they will wait instead) + # However, readers OR writers could decrement right here, OR another writer could increment + @WriteLock.wait_until do + # So we have to do another check inside the synchronized section + # If a writer OR reader is running, then go to sleep + c = @Counter.value + !running_writer?(c) && !running_readers?(c) + end + + # We just came out of a wait + # If we successfully turn the RUNNING_WRITER bit on with an atomic swap, + # Then we are OK to stop waiting and go ahead + # Otherwise go back and wait again + c = @Counter.value + break if !running_writer?(c) && !running_readers?(c) && @Counter.compare_and_set(c, c+RUNNING_WRITER-WAITING_WRITER) + end + break + end + end + true + end + + # Release a previously acquired write lock. + # + # @return [Boolean] true if the lock is successfully released + def release_write_lock + return true unless running_writer? + c = @Counter.update { |counter| counter - RUNNING_WRITER } + @ReadLock.broadcast + @WriteLock.signal if waiting_writers(c) > 0 + true + end + + # Queries if the write lock is held by any thread. + # + # @return [Boolean] true if the write lock is held else false` + def write_locked? + @Counter.value >= RUNNING_WRITER + end + + # Queries whether any threads are waiting to acquire the read or write lock. + # + # @return [Boolean] true if any threads are waiting for a lock else false + def has_waiters? + waiting_writer?(@Counter.value) + end + + private + + # @!visibility private + def running_readers(c = @Counter.value) + c & MAX_READERS + end + + # @!visibility private + def running_readers?(c = @Counter.value) + (c & MAX_READERS) > 0 + end + + # @!visibility private + def running_writer?(c = @Counter.value) + c >= RUNNING_WRITER + end + + # @!visibility private + def waiting_writers(c = @Counter.value) + (c & MAX_WRITERS) / WAITING_WRITER + end + + # @!visibility private + def waiting_writer?(c = @Counter.value) + c >= WAITING_WRITER + end + + # @!visibility private + def max_readers?(c = @Counter.value) + (c & MAX_READERS) == MAX_READERS + end + + # @!visibility private + def max_writers?(c = @Counter.value) + (c & MAX_WRITERS) == MAX_WRITERS + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb new file mode 100644 index 00000000..6d72a3a0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb @@ -0,0 +1,379 @@ +require 'thread' +require 'concurrent/atomic/atomic_reference' +require 'concurrent/atomic/atomic_fixnum' +require 'concurrent/errors' +require 'concurrent/synchronization/object' +require 'concurrent/synchronization/lock' +require 'concurrent/atomic/lock_local_var' + +module Concurrent + + # Re-entrant read-write lock implementation + # + # Allows any number of concurrent readers, but only one concurrent writer + # (And while the "write" lock is taken, no read locks can be obtained either. + # Hence, the write lock can also be called an "exclusive" lock.) + # + # If another thread has taken a read lock, any thread which wants a write lock + # will block until all the readers release their locks. However, once a thread + # starts waiting to obtain a write lock, any additional readers that come along + # will also wait (so writers are not starved). + # + # A thread can acquire both a read and write lock at the same time. A thread can + # also acquire a read lock OR a write lock more than once. Only when the read (or + # write) lock is released as many times as it was acquired, will the thread + # actually let it go, allowing other threads which might have been waiting + # to proceed. Therefore the lock can be upgraded by first acquiring + # read lock and then write lock and that the lock can be downgraded by first + # having both read and write lock a releasing just the write lock. + # + # If both read and write locks are acquired by the same thread, it is not strictly + # necessary to release them in the same order they were acquired. In other words, + # the following code is legal: + # + # @example + # lock = Concurrent::ReentrantReadWriteLock.new + # lock.acquire_write_lock + # lock.acquire_read_lock + # lock.release_write_lock + # # At this point, the current thread is holding only a read lock, not a write + # # lock. So other threads can take read locks, but not a write lock. + # lock.release_read_lock + # # Now the current thread is not holding either a read or write lock, so + # # another thread could potentially acquire a write lock. + # + # This implementation was inspired by `java.util.concurrent.ReentrantReadWriteLock`. + # + # @example + # lock = Concurrent::ReentrantReadWriteLock.new + # lock.with_read_lock { data.retrieve } + # lock.with_write_lock { data.modify! } + # + # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html java.util.concurrent.ReentrantReadWriteLock + class ReentrantReadWriteLock < Synchronization::Object + + # Implementation notes: + # + # A goal is to make the uncontended path for both readers/writers mutex-free + # Only if there is reader-writer or writer-writer contention, should mutexes be used + # Otherwise, a single CAS operation is all we need to acquire/release a lock + # + # Internal state is represented by a single integer ("counter"), and updated + # using atomic compare-and-swap operations + # When the counter is 0, the lock is free + # Each thread which has one OR MORE read locks increments the counter by 1 + # (and decrements by 1 when releasing the read lock) + # The counter is increased by (1 << 15) for each writer waiting to acquire the + # write lock, and by (1 << 29) if the write lock is taken + # + # Additionally, each thread uses a thread-local variable to count how many times + # it has acquired a read lock, AND how many times it has acquired a write lock. + # It uses a similar trick; an increment of 1 means a read lock was taken, and + # an increment of (1 << 15) means a write lock was taken + # This is what makes re-entrancy possible + # + # 2 rules are followed to ensure good liveness properties: + # 1) Once a writer has queued up and is waiting for a write lock, no other thread + # can take a lock without waiting + # 2) When a write lock is released, readers are given the "first chance" to wake + # up and acquire a read lock + # Following these rules means readers and writers tend to "take turns", so neither + # can starve the other, even under heavy contention + + # @!visibility private + READER_BITS = 15 + # @!visibility private + WRITER_BITS = 14 + + # Used with @Counter: + # @!visibility private + WAITING_WRITER = 1 << READER_BITS + # @!visibility private + RUNNING_WRITER = 1 << (READER_BITS + WRITER_BITS) + # @!visibility private + MAX_READERS = WAITING_WRITER - 1 + # @!visibility private + MAX_WRITERS = RUNNING_WRITER - MAX_READERS - 1 + + # Used with @HeldCount: + # @!visibility private + WRITE_LOCK_HELD = 1 << READER_BITS + # @!visibility private + READ_LOCK_MASK = WRITE_LOCK_HELD - 1 + # @!visibility private + WRITE_LOCK_MASK = MAX_WRITERS + + safe_initialization! + + # Create a new `ReentrantReadWriteLock` in the unlocked state. + def initialize + super() + @Counter = AtomicFixnum.new(0) # single integer which represents lock state + @ReadQueue = Synchronization::Lock.new # used to queue waiting readers + @WriteQueue = Synchronization::Lock.new # used to queue waiting writers + @HeldCount = LockLocalVar.new(0) # indicates # of R & W locks held by this thread + end + + # Execute a block operation within a read lock. + # + # @yield the task to be performed within the lock. + # + # @return [Object] the result of the block operation. + # + # @raise [ArgumentError] when no block is given. + # @raise [Concurrent::ResourceLimitError] if the maximum number of readers + # is exceeded. + def with_read_lock + raise ArgumentError.new('no block given') unless block_given? + acquire_read_lock + begin + yield + ensure + release_read_lock + end + end + + # Execute a block operation within a write lock. + # + # @yield the task to be performed within the lock. + # + # @return [Object] the result of the block operation. + # + # @raise [ArgumentError] when no block is given. + # @raise [Concurrent::ResourceLimitError] if the maximum number of readers + # is exceeded. + def with_write_lock + raise ArgumentError.new('no block given') unless block_given? + acquire_write_lock + begin + yield + ensure + release_write_lock + end + end + + # Acquire a read lock. If a write lock is held by another thread, will block + # until it is released. + # + # @return [Boolean] true if the lock is successfully acquired + # + # @raise [Concurrent::ResourceLimitError] if the maximum number of readers + # is exceeded. + def acquire_read_lock + if (held = @HeldCount.value) > 0 + # If we already have a lock, there's no need to wait + if held & READ_LOCK_MASK == 0 + # But we do need to update the counter, if we were holding a write + # lock but not a read lock + @Counter.update { |c| c + 1 } + end + @HeldCount.value = held + 1 + return true + end + + while true + c = @Counter.value + raise ResourceLimitError.new('Too many reader threads') if max_readers?(c) + + # If a writer is waiting OR running when we first queue up, we need to wait + if waiting_or_running_writer?(c) + # Before going to sleep, check again with the ReadQueue mutex held + @ReadQueue.synchronize do + @ReadQueue.ns_wait if waiting_or_running_writer? + end + # Note: the above 'synchronize' block could have used #wait_until, + # but that waits repeatedly in a loop, checking the wait condition + # each time it wakes up (to protect against spurious wakeups) + # But we are already in a loop, which is only broken when we successfully + # acquire the lock! So we don't care about spurious wakeups, and would + # rather not pay the extra overhead of using #wait_until + + # After a reader has waited once, they are allowed to "barge" ahead of waiting writers + # But if a writer is *running*, the reader still needs to wait (naturally) + while true + c = @Counter.value + if running_writer?(c) + @ReadQueue.synchronize do + @ReadQueue.ns_wait if running_writer? + end + elsif @Counter.compare_and_set(c, c+1) + @HeldCount.value = held + 1 + return true + end + end + elsif @Counter.compare_and_set(c, c+1) + @HeldCount.value = held + 1 + return true + end + end + end + + # Try to acquire a read lock and return true if we succeed. If it cannot be + # acquired immediately, return false. + # + # @return [Boolean] true if the lock is successfully acquired + def try_read_lock + if (held = @HeldCount.value) > 0 + if held & READ_LOCK_MASK == 0 + # If we hold a write lock, but not a read lock... + @Counter.update { |c| c + 1 } + end + @HeldCount.value = held + 1 + return true + else + c = @Counter.value + if !waiting_or_running_writer?(c) && @Counter.compare_and_set(c, c+1) + @HeldCount.value = held + 1 + return true + end + end + false + end + + # Release a previously acquired read lock. + # + # @return [Boolean] true if the lock is successfully released + def release_read_lock + held = @HeldCount.value = @HeldCount.value - 1 + rlocks_held = held & READ_LOCK_MASK + if rlocks_held == 0 + c = @Counter.update { |counter| counter - 1 } + # If one or more writers were waiting, and we were the last reader, wake a writer up + if waiting_or_running_writer?(c) && running_readers(c) == 0 + @WriteQueue.signal + end + elsif rlocks_held == READ_LOCK_MASK + raise IllegalOperationError, "Cannot release a read lock which is not held" + end + true + end + + # Acquire a write lock. Will block and wait for all active readers and writers. + # + # @return [Boolean] true if the lock is successfully acquired + # + # @raise [Concurrent::ResourceLimitError] if the maximum number of writers + # is exceeded. + def acquire_write_lock + if (held = @HeldCount.value) >= WRITE_LOCK_HELD + # if we already have a write (exclusive) lock, there's no need to wait + @HeldCount.value = held + WRITE_LOCK_HELD + return true + end + + while true + c = @Counter.value + raise ResourceLimitError.new('Too many writer threads') if max_writers?(c) + + # To go ahead and take the lock without waiting, there must be no writer + # running right now, AND no writers who came before us still waiting to + # acquire the lock + # Additionally, if any read locks have been taken, we must hold all of them + if held > 0 && @Counter.compare_and_set(1, c+RUNNING_WRITER) + # If we are the only one reader and successfully swap the RUNNING_WRITER bit on, then we can go ahead + @HeldCount.value = held + WRITE_LOCK_HELD + return true + elsif @Counter.compare_and_set(c, c+WAITING_WRITER) + while true + # Now we have successfully incremented, so no more readers will be able to increment + # (they will wait instead) + # However, readers OR writers could decrement right here + @WriteQueue.synchronize do + # So we have to do another check inside the synchronized section + # If a writer OR another reader is running, then go to sleep + c = @Counter.value + @WriteQueue.ns_wait if running_writer?(c) || running_readers(c) != held + end + # Note: if you are thinking of replacing the above 'synchronize' block + # with #wait_until, read the comment in #acquire_read_lock first! + + # We just came out of a wait + # If we successfully turn the RUNNING_WRITER bit on with an atomic swap, + # then we are OK to stop waiting and go ahead + # Otherwise go back and wait again + c = @Counter.value + if !running_writer?(c) && + running_readers(c) == held && + @Counter.compare_and_set(c, c+RUNNING_WRITER-WAITING_WRITER) + @HeldCount.value = held + WRITE_LOCK_HELD + return true + end + end + end + end + end + + # Try to acquire a write lock and return true if we succeed. If it cannot be + # acquired immediately, return false. + # + # @return [Boolean] true if the lock is successfully acquired + def try_write_lock + if (held = @HeldCount.value) >= WRITE_LOCK_HELD + @HeldCount.value = held + WRITE_LOCK_HELD + return true + else + c = @Counter.value + if !waiting_or_running_writer?(c) && + running_readers(c) == held && + @Counter.compare_and_set(c, c+RUNNING_WRITER) + @HeldCount.value = held + WRITE_LOCK_HELD + return true + end + end + false + end + + # Release a previously acquired write lock. + # + # @return [Boolean] true if the lock is successfully released + def release_write_lock + held = @HeldCount.value = @HeldCount.value - WRITE_LOCK_HELD + wlocks_held = held & WRITE_LOCK_MASK + if wlocks_held == 0 + c = @Counter.update { |counter| counter - RUNNING_WRITER } + @ReadQueue.broadcast + @WriteQueue.signal if waiting_writers(c) > 0 + elsif wlocks_held == WRITE_LOCK_MASK + raise IllegalOperationError, "Cannot release a write lock which is not held" + end + true + end + + private + + # @!visibility private + def running_readers(c = @Counter.value) + c & MAX_READERS + end + + # @!visibility private + def running_readers?(c = @Counter.value) + (c & MAX_READERS) > 0 + end + + # @!visibility private + def running_writer?(c = @Counter.value) + c >= RUNNING_WRITER + end + + # @!visibility private + def waiting_writers(c = @Counter.value) + (c & MAX_WRITERS) >> READER_BITS + end + + # @!visibility private + def waiting_or_running_writer?(c = @Counter.value) + c >= WAITING_WRITER + end + + # @!visibility private + def max_readers?(c = @Counter.value) + (c & MAX_READERS) == MAX_READERS + end + + # @!visibility private + def max_writers?(c = @Counter.value) + (c & MAX_WRITERS) == MAX_WRITERS + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/semaphore.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/semaphore.rb new file mode 100644 index 00000000..f0799f0f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/semaphore.rb @@ -0,0 +1,163 @@ +require 'concurrent/atomic/mutex_semaphore' + +module Concurrent + + ################################################################### + + # @!macro semaphore_method_initialize + # + # Create a new `Semaphore` with the initial `count`. + # + # @param [Fixnum] count the initial count + # + # @raise [ArgumentError] if `count` is not an integer + + # @!macro semaphore_method_acquire + # + # Acquires the given number of permits from this semaphore, + # blocking until all are available. If a block is given, + # yields to it and releases the permits afterwards. + # + # @param [Fixnum] permits Number of permits to acquire + # + # @raise [ArgumentError] if `permits` is not an integer or is less than zero + # + # @return [nil, BasicObject] Without a block, `nil` is returned. If a block + # is given, its return value is returned. + + # @!macro semaphore_method_available_permits + # + # Returns the current number of permits available in this semaphore. + # + # @return [Integer] + + # @!macro semaphore_method_drain_permits + # + # Acquires and returns all permits that are immediately available. + # + # @return [Integer] + + # @!macro semaphore_method_try_acquire + # + # Acquires the given number of permits from this semaphore, + # only if all are available at the time of invocation or within + # `timeout` interval. If a block is given, yields to it if the permits + # were successfully acquired, and releases them afterward, returning the + # block's return value. + # + # @param [Fixnum] permits the number of permits to acquire + # + # @param [Fixnum] timeout the number of seconds to wait for the counter + # or `nil` to return immediately + # + # @raise [ArgumentError] if `permits` is not an integer or is less than zero + # + # @return [true, false, nil, BasicObject] `false` if no permits are + # available, `true` when acquired a permit. If a block is given, the + # block's return value is returned if the permits were acquired; if not, + # `nil` is returned. + + # @!macro semaphore_method_release + # + # Releases the given number of permits, returning them to the semaphore. + # + # @param [Fixnum] permits Number of permits to return to the semaphore. + # + # @raise [ArgumentError] if `permits` is not a number or is less than zero + # + # @return [nil] + + ################################################################### + + # @!macro semaphore_public_api + # + # @!method initialize(count) + # @!macro semaphore_method_initialize + # + # @!method acquire(permits = 1) + # @!macro semaphore_method_acquire + # + # @!method available_permits + # @!macro semaphore_method_available_permits + # + # @!method drain_permits + # @!macro semaphore_method_drain_permits + # + # @!method try_acquire(permits = 1, timeout = nil) + # @!macro semaphore_method_try_acquire + # + # @!method release(permits = 1) + # @!macro semaphore_method_release + + ################################################################### + + # @!visibility private + # @!macro internal_implementation_note + SemaphoreImplementation = if Concurrent.on_jruby? + require 'concurrent/utility/native_extension_loader' + JavaSemaphore + else + MutexSemaphore + end + private_constant :SemaphoreImplementation + + # @!macro semaphore + # + # A counting semaphore. Conceptually, a semaphore maintains a set of + # permits. Each {#acquire} blocks if necessary until a permit is + # available, and then takes it. Each {#release} adds a permit, potentially + # releasing a blocking acquirer. + # However, no actual permit objects are used; the Semaphore just keeps a + # count of the number available and acts accordingly. + # Alternatively, permits may be acquired within a block, and automatically + # released after the block finishes executing. + # + # @!macro semaphore_public_api + # @example + # semaphore = Concurrent::Semaphore.new(2) + # + # t1 = Thread.new do + # semaphore.acquire + # puts "Thread 1 acquired semaphore" + # end + # + # t2 = Thread.new do + # semaphore.acquire + # puts "Thread 2 acquired semaphore" + # end + # + # t3 = Thread.new do + # semaphore.acquire + # puts "Thread 3 acquired semaphore" + # end + # + # t4 = Thread.new do + # sleep(2) + # puts "Thread 4 releasing semaphore" + # semaphore.release + # end + # + # [t1, t2, t3, t4].each(&:join) + # + # # prints: + # # Thread 3 acquired semaphore + # # Thread 2 acquired semaphore + # # Thread 4 releasing semaphore + # # Thread 1 acquired semaphore + # + # @example + # semaphore = Concurrent::Semaphore.new(1) + # + # puts semaphore.available_permits + # semaphore.acquire do + # puts semaphore.available_permits + # end + # puts semaphore.available_permits + # + # # prints: + # # 1 + # # 0 + # # 1 + class Semaphore < SemaphoreImplementation + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb new file mode 100644 index 00000000..3b7e12b5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic/thread_local_var.rb @@ -0,0 +1,111 @@ +require 'concurrent/constants' +require_relative 'locals' + +module Concurrent + + # A `ThreadLocalVar` is a variable where the value is different for each thread. + # Each variable may have a default value, but when you modify the variable only + # the current thread will ever see that change. + # + # This is similar to Ruby's built-in thread-local variables (`Thread#thread_variable_get`), + # but with these major advantages: + # * `ThreadLocalVar` has its own identity, it doesn't need a Symbol. + # * Each Ruby's built-in thread-local variable leaks some memory forever (it's a Symbol held forever on the thread), + # so it's only OK to create a small amount of them. + # `ThreadLocalVar` has no such issue and it is fine to create many of them. + # * Ruby's built-in thread-local variables leak forever the value set on each thread (unless set to nil explicitly). + # `ThreadLocalVar` automatically removes the mapping for each thread once the `ThreadLocalVar` instance is GC'd. + # + # @!macro thread_safe_variable_comparison + # + # @example + # v = ThreadLocalVar.new(14) + # v.value #=> 14 + # v.value = 2 + # v.value #=> 2 + # + # @example + # v = ThreadLocalVar.new(14) + # + # t1 = Thread.new do + # v.value #=> 14 + # v.value = 1 + # v.value #=> 1 + # end + # + # t2 = Thread.new do + # v.value #=> 14 + # v.value = 2 + # v.value #=> 2 + # end + # + # v.value #=> 14 + class ThreadLocalVar + LOCALS = ThreadLocals.new + + # Creates a thread local variable. + # + # @param [Object] default the default value when otherwise unset + # @param [Proc] default_block Optional block that gets called to obtain the + # default value for each thread + def initialize(default = nil, &default_block) + if default && block_given? + raise ArgumentError, "Cannot use both value and block as default value" + end + + if block_given? + @default_block = default_block + @default = nil + else + @default_block = nil + @default = default + end + + @index = LOCALS.next_index(self) + end + + # Returns the value in the current thread's copy of this thread-local variable. + # + # @return [Object] the current value + def value + LOCALS.fetch(@index) { default } + end + + # Sets the current thread's copy of this thread-local variable to the specified value. + # + # @param [Object] value the value to set + # @return [Object] the new value + def value=(value) + LOCALS.set(@index, value) + end + + # Bind the given value to thread local storage during + # execution of the given block. + # + # @param [Object] value the value to bind + # @yield the operation to be performed with the bound variable + # @return [Object] the value + def bind(value) + if block_given? + old_value = self.value + self.value = value + begin + yield + ensure + self.value = old_value + end + end + end + + protected + + # @!visibility private + def default + if @default_block + self.value = @default_block.call + else + @default + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic_reference/atomic_direct_update.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic_reference/atomic_direct_update.rb new file mode 100644 index 00000000..5d2d7edd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic_reference/atomic_direct_update.rb @@ -0,0 +1,37 @@ +require 'concurrent/errors' + +module Concurrent + + # Define update methods that use direct paths + # + # @!visibility private + # @!macro internal_implementation_note + module AtomicDirectUpdate + def update + true until compare_and_set(old_value = get, new_value = yield(old_value)) + new_value + end + + def try_update + old_value = get + new_value = yield old_value + + return unless compare_and_set old_value, new_value + + new_value + end + + def try_update! + old_value = get + new_value = yield old_value + unless compare_and_set(old_value, new_value) + if $VERBOSE + raise ConcurrentUpdateError, "Update failed" + else + raise ConcurrentUpdateError, "Update failed", ConcurrentUpdateError::CONC_UP_ERR_BACKTRACE + end + end + new_value + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb new file mode 100644 index 00000000..e5e2a637 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic_reference/mutex_atomic.rb @@ -0,0 +1,67 @@ +require 'concurrent/atomic_reference/atomic_direct_update' +require 'concurrent/atomic_reference/numeric_cas_wrapper' +require 'concurrent/synchronization/safe_initialization' + +module Concurrent + + # @!visibility private + # @!macro internal_implementation_note + class MutexAtomicReference + extend Concurrent::Synchronization::SafeInitialization + include AtomicDirectUpdate + include AtomicNumericCompareAndSetWrapper + alias_method :compare_and_swap, :compare_and_set + + # @!macro atomic_reference_method_initialize + def initialize(value = nil) + super() + @Lock = ::Mutex.new + @value = value + end + + # @!macro atomic_reference_method_get + def get + synchronize { @value } + end + alias_method :value, :get + + # @!macro atomic_reference_method_set + def set(new_value) + synchronize { @value = new_value } + end + alias_method :value=, :set + + # @!macro atomic_reference_method_get_and_set + def get_and_set(new_value) + synchronize do + old_value = @value + @value = new_value + old_value + end + end + alias_method :swap, :get_and_set + + # @!macro atomic_reference_method_compare_and_set + def _compare_and_set(old_value, new_value) + synchronize do + if @value.equal? old_value + @value = new_value + true + else + false + end + end + end + + protected + + # @!visibility private + def synchronize + if @Lock.owned? + yield + else + @Lock.synchronize { yield } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb new file mode 100644 index 00000000..709a3822 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomic_reference/numeric_cas_wrapper.rb @@ -0,0 +1,28 @@ +module Concurrent + + # Special "compare and set" handling of numeric values. + # + # @!visibility private + # @!macro internal_implementation_note + module AtomicNumericCompareAndSetWrapper + + # @!macro atomic_reference_method_compare_and_set + def compare_and_set(old_value, new_value) + if old_value.kind_of? Numeric + while true + old = get + + return false unless old.kind_of? Numeric + + return false unless old == old_value + + result = _compare_and_set(old, new_value) + return result if result + end + else + _compare_and_set(old_value, new_value) + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomics.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomics.rb new file mode 100644 index 00000000..16cbe661 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/atomics.rb @@ -0,0 +1,10 @@ +require 'concurrent/atomic/atomic_reference' +require 'concurrent/atomic/atomic_boolean' +require 'concurrent/atomic/atomic_fixnum' +require 'concurrent/atomic/cyclic_barrier' +require 'concurrent/atomic/count_down_latch' +require 'concurrent/atomic/event' +require 'concurrent/atomic/read_write_lock' +require 'concurrent/atomic/reentrant_read_write_lock' +require 'concurrent/atomic/semaphore' +require 'concurrent/atomic/thread_local_var' diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb new file mode 100644 index 00000000..7c700bd7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/copy_on_notify_observer_set.rb @@ -0,0 +1,107 @@ +require 'concurrent/synchronization/lockable_object' + +module Concurrent + module Collection + + # A thread safe observer set implemented using copy-on-read approach: + # observers are added and removed from a thread safe collection; every time + # a notification is required the internal data structure is copied to + # prevent concurrency issues + # + # @api private + class CopyOnNotifyObserverSet < Synchronization::LockableObject + + def initialize + super() + synchronize { ns_initialize } + end + + # @!macro observable_add_observer + def add_observer(observer = nil, func = :update, &block) + if observer.nil? && block.nil? + raise ArgumentError, 'should pass observer as a first argument or block' + elsif observer && block + raise ArgumentError.new('cannot provide both an observer and a block') + end + + if block + observer = block + func = :call + end + + synchronize do + @observers[observer] = func + observer + end + end + + # @!macro observable_delete_observer + def delete_observer(observer) + synchronize do + @observers.delete(observer) + observer + end + end + + # @!macro observable_delete_observers + def delete_observers + synchronize do + @observers.clear + self + end + end + + # @!macro observable_count_observers + def count_observers + synchronize { @observers.count } + end + + # Notifies all registered observers with optional args + # @param [Object] args arguments to be passed to each observer + # @return [CopyOnWriteObserverSet] self + def notify_observers(*args, &block) + observers = duplicate_observers + notify_to(observers, *args, &block) + self + end + + # Notifies all registered observers with optional args and deletes them. + # + # @param [Object] args arguments to be passed to each observer + # @return [CopyOnWriteObserverSet] self + def notify_and_delete_observers(*args, &block) + observers = duplicate_and_clear_observers + notify_to(observers, *args, &block) + self + end + + protected + + def ns_initialize + @observers = {} + end + + private + + def duplicate_and_clear_observers + synchronize do + observers = @observers.dup + @observers.clear + observers + end + end + + def duplicate_observers + synchronize { @observers.dup } + end + + def notify_to(observers, *args) + raise ArgumentError.new('cannot give arguments and a block') if block_given? && !args.empty? + observers.each do |observer, function| + args = yield if block_given? + observer.send(function, *args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb new file mode 100644 index 00000000..bcb6750d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/copy_on_write_observer_set.rb @@ -0,0 +1,111 @@ +require 'concurrent/synchronization/lockable_object' + +module Concurrent + module Collection + + # A thread safe observer set implemented using copy-on-write approach: + # every time an observer is added or removed the whole internal data structure is + # duplicated and replaced with a new one. + # + # @api private + class CopyOnWriteObserverSet < Synchronization::LockableObject + + def initialize + super() + synchronize { ns_initialize } + end + + # @!macro observable_add_observer + def add_observer(observer = nil, func = :update, &block) + if observer.nil? && block.nil? + raise ArgumentError, 'should pass observer as a first argument or block' + elsif observer && block + raise ArgumentError.new('cannot provide both an observer and a block') + end + + if block + observer = block + func = :call + end + + synchronize do + new_observers = @observers.dup + new_observers[observer] = func + @observers = new_observers + observer + end + end + + # @!macro observable_delete_observer + def delete_observer(observer) + synchronize do + new_observers = @observers.dup + new_observers.delete(observer) + @observers = new_observers + observer + end + end + + # @!macro observable_delete_observers + def delete_observers + self.observers = {} + self + end + + # @!macro observable_count_observers + def count_observers + observers.count + end + + # Notifies all registered observers with optional args + # @param [Object] args arguments to be passed to each observer + # @return [CopyOnWriteObserverSet] self + def notify_observers(*args, &block) + notify_to(observers, *args, &block) + self + end + + # Notifies all registered observers with optional args and deletes them. + # + # @param [Object] args arguments to be passed to each observer + # @return [CopyOnWriteObserverSet] self + def notify_and_delete_observers(*args, &block) + old = clear_observers_and_return_old + notify_to(old, *args, &block) + self + end + + protected + + def ns_initialize + @observers = {} + end + + private + + def notify_to(observers, *args) + raise ArgumentError.new('cannot give arguments and a block') if block_given? && !args.empty? + observers.each do |observer, function| + args = yield if block_given? + observer.send(function, *args) + end + end + + def observers + synchronize { @observers } + end + + def observers=(new_set) + synchronize { @observers = new_set } + end + + def clear_observers_and_return_old + synchronize do + old_observers = @observers + @observers = {} + old_observers + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/java_non_concurrent_priority_queue.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/java_non_concurrent_priority_queue.rb new file mode 100644 index 00000000..2be9e437 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/java_non_concurrent_priority_queue.rb @@ -0,0 +1,84 @@ +if Concurrent.on_jruby? + + module Concurrent + module Collection + + + # @!macro priority_queue + # + # @!visibility private + # @!macro internal_implementation_note + class JavaNonConcurrentPriorityQueue + + # @!macro priority_queue_method_initialize + def initialize(opts = {}) + order = opts.fetch(:order, :max) + if [:min, :low].include?(order) + @queue = java.util.PriorityQueue.new(11) # 11 is the default initial capacity + else + @queue = java.util.PriorityQueue.new(11, java.util.Collections.reverseOrder()) + end + end + + # @!macro priority_queue_method_clear + def clear + @queue.clear + true + end + + # @!macro priority_queue_method_delete + def delete(item) + found = false + while @queue.remove(item) do + found = true + end + found + end + + # @!macro priority_queue_method_empty + def empty? + @queue.size == 0 + end + + # @!macro priority_queue_method_include + def include?(item) + @queue.contains(item) + end + alias_method :has_priority?, :include? + + # @!macro priority_queue_method_length + def length + @queue.size + end + alias_method :size, :length + + # @!macro priority_queue_method_peek + def peek + @queue.peek + end + + # @!macro priority_queue_method_pop + def pop + @queue.poll + end + alias_method :deq, :pop + alias_method :shift, :pop + + # @!macro priority_queue_method_push + def push(item) + raise ArgumentError.new('cannot enqueue nil') if item.nil? + @queue.add(item) + end + alias_method :<<, :push + alias_method :enq, :push + + # @!macro priority_queue_method_from_list + def self.from_list(list, opts = {}) + queue = new(opts) + list.each{|item| queue << item } + queue + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb new file mode 100644 index 00000000..3704410b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/lock_free_stack.rb @@ -0,0 +1,160 @@ +require 'concurrent/synchronization/object' + +module Concurrent + + # @!macro warn.edge + class LockFreeStack < Synchronization::Object + + safe_initialization! + + class Node + # TODO (pitr-ch 20-Dec-2016): Could be unified with Stack class? + + # @return [Node] + attr_reader :next_node + + # @return [Object] + attr_reader :value + + # @!visibility private + # allow to nil-ify to free GC when the entry is no longer relevant, not synchronised + attr_writer :value + + def initialize(value, next_node) + @value = value + @next_node = next_node + end + + singleton_class.send :alias_method, :[], :new + end + + # The singleton for empty node + EMPTY = Node[nil, nil] + def EMPTY.next_node + self + end + + attr_atomic(:head) + private :head, :head=, :swap_head, :compare_and_set_head, :update_head + + # @!visibility private + def self.of1(value) + new Node[value, EMPTY] + end + + # @!visibility private + def self.of2(value1, value2) + new Node[value1, Node[value2, EMPTY]] + end + + # @param [Node] head + def initialize(head = EMPTY) + super() + self.head = head + end + + # @param [Node] head + # @return [true, false] + def empty?(head = head()) + head.equal? EMPTY + end + + # @param [Node] head + # @param [Object] value + # @return [true, false] + def compare_and_push(head, value) + compare_and_set_head head, Node[value, head] + end + + # @param [Object] value + # @return [self] + def push(value) + while true + current_head = head + return self if compare_and_set_head current_head, Node[value, current_head] + end + end + + # @return [Node] + def peek + head + end + + # @param [Node] head + # @return [true, false] + def compare_and_pop(head) + compare_and_set_head head, head.next_node + end + + # @return [Object] + def pop + while true + current_head = head + return current_head.value if compare_and_set_head current_head, current_head.next_node + end + end + + # @param [Node] head + # @return [true, false] + def compare_and_clear(head) + compare_and_set_head head, EMPTY + end + + include Enumerable + + # @param [Node] head + # @return [self] + def each(head = nil) + return to_enum(:each, head) unless block_given? + it = head || peek + until it.equal?(EMPTY) + yield it.value + it = it.next_node + end + self + end + + # @return [true, false] + def clear + while true + current_head = head + return false if current_head == EMPTY + return true if compare_and_set_head current_head, EMPTY + end + end + + # @param [Node] head + # @return [true, false] + def clear_if(head) + compare_and_set_head head, EMPTY + end + + # @param [Node] head + # @param [Node] new_head + # @return [true, false] + def replace_if(head, new_head) + compare_and_set_head head, new_head + end + + # @return [self] + # @yield over the cleared stack + # @yieldparam [Object] value + def clear_each(&block) + while true + current_head = head + return self if current_head == EMPTY + if compare_and_set_head current_head, EMPTY + each current_head, &block + return self + end + end + end + + # @return [String] Short string representation. + def to_s + format '%s %s>', super[0..-2], to_a.to_s + end + + alias_method :inspect, :to_s + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/map/mri_map_backend.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/map/mri_map_backend.rb new file mode 100644 index 00000000..e0cf9990 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/map/mri_map_backend.rb @@ -0,0 +1,66 @@ +require 'thread' +require 'concurrent/collection/map/non_concurrent_map_backend' + +module Concurrent + + # @!visibility private + module Collection + + # @!visibility private + class MriMapBackend < NonConcurrentMapBackend + + def initialize(options = nil, &default_proc) + super(options, &default_proc) + @write_lock = Mutex.new + end + + def []=(key, value) + @write_lock.synchronize { super } + end + + def compute_if_absent(key) + if NULL != (stored_value = @backend.fetch(key, NULL)) # fast non-blocking path for the most likely case + stored_value + else + @write_lock.synchronize { super } + end + end + + def compute_if_present(key) + @write_lock.synchronize { super } + end + + def compute(key) + @write_lock.synchronize { super } + end + + def merge_pair(key, value) + @write_lock.synchronize { super } + end + + def replace_pair(key, old_value, new_value) + @write_lock.synchronize { super } + end + + def replace_if_exists(key, new_value) + @write_lock.synchronize { super } + end + + def get_and_set(key, value) + @write_lock.synchronize { super } + end + + def delete(key) + @write_lock.synchronize { super } + end + + def delete_pair(key, value) + @write_lock.synchronize { super } + end + + def clear + @write_lock.synchronize { super } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb new file mode 100644 index 00000000..ca5fd9b4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/map/non_concurrent_map_backend.rb @@ -0,0 +1,148 @@ +require 'concurrent/constants' + +module Concurrent + + # @!visibility private + module Collection + + # @!visibility private + class NonConcurrentMapBackend + + # WARNING: all public methods of the class must operate on the @backend + # directly without calling each other. This is important because of the + # SynchronizedMapBackend which uses a non-reentrant mutex for performance + # reasons. + def initialize(options = nil, &default_proc) + validate_options_hash!(options) if options.kind_of?(::Hash) + set_backend(default_proc) + @default_proc = default_proc + end + + def [](key) + @backend[key] + end + + def []=(key, value) + @backend[key] = value + end + + def compute_if_absent(key) + if NULL != (stored_value = @backend.fetch(key, NULL)) + stored_value + else + @backend[key] = yield + end + end + + def replace_pair(key, old_value, new_value) + if pair?(key, old_value) + @backend[key] = new_value + true + else + false + end + end + + def replace_if_exists(key, new_value) + if NULL != (stored_value = @backend.fetch(key, NULL)) + @backend[key] = new_value + stored_value + end + end + + def compute_if_present(key) + if NULL != (stored_value = @backend.fetch(key, NULL)) + store_computed_value(key, yield(stored_value)) + end + end + + def compute(key) + store_computed_value(key, yield(get_or_default(key, nil))) + end + + def merge_pair(key, value) + if NULL == (stored_value = @backend.fetch(key, NULL)) + @backend[key] = value + else + store_computed_value(key, yield(stored_value)) + end + end + + def get_and_set(key, value) + stored_value = get_or_default(key, nil) + @backend[key] = value + stored_value + end + + def key?(key) + @backend.key?(key) + end + + def delete(key) + @backend.delete(key) + end + + def delete_pair(key, value) + if pair?(key, value) + @backend.delete(key) + true + else + false + end + end + + def clear + @backend.clear + self + end + + def each_pair + dupped_backend.each_pair do |k, v| + yield k, v + end + self + end + + def size + @backend.size + end + + def get_or_default(key, default_value) + @backend.fetch(key, default_value) + end + + private + + def set_backend(default_proc) + if default_proc + @backend = ::Hash.new { |_h, key| default_proc.call(self, key) } + else + @backend = {} + end + end + + def initialize_copy(other) + super + set_backend(@default_proc) + self + end + + def dupped_backend + @backend.dup + end + + def pair?(key, expected_value) + NULL != (stored_value = @backend.fetch(key, NULL)) && expected_value.equal?(stored_value) + end + + def store_computed_value(key, new_value) + if new_value.nil? + @backend.delete(key) + nil + else + @backend[key] = new_value + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/map/synchronized_map_backend.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/map/synchronized_map_backend.rb new file mode 100644 index 00000000..efa161ed --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/map/synchronized_map_backend.rb @@ -0,0 +1,85 @@ +require 'concurrent/collection/map/non_concurrent_map_backend' + +module Concurrent + + # @!visibility private + module Collection + + # @!visibility private + class SynchronizedMapBackend < NonConcurrentMapBackend + + def initialize(*args, &block) + super + + # WARNING: Mutex is a non-reentrant lock, so the synchronized methods are + # not allowed to call each other. + @mutex = Mutex.new + end + + def [](key) + @mutex.synchronize { super } + end + + def []=(key, value) + @mutex.synchronize { super } + end + + def compute_if_absent(key) + @mutex.synchronize { super } + end + + def compute_if_present(key) + @mutex.synchronize { super } + end + + def compute(key) + @mutex.synchronize { super } + end + + def merge_pair(key, value) + @mutex.synchronize { super } + end + + def replace_pair(key, old_value, new_value) + @mutex.synchronize { super } + end + + def replace_if_exists(key, new_value) + @mutex.synchronize { super } + end + + def get_and_set(key, value) + @mutex.synchronize { super } + end + + def key?(key) + @mutex.synchronize { super } + end + + def delete(key) + @mutex.synchronize { super } + end + + def delete_pair(key, value) + @mutex.synchronize { super } + end + + def clear + @mutex.synchronize { super } + end + + def size + @mutex.synchronize { super } + end + + def get_or_default(key, default_value) + @mutex.synchronize { super } + end + + private + def dupped_backend + @mutex.synchronize { super } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/map/truffleruby_map_backend.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/map/truffleruby_map_backend.rb new file mode 100644 index 00000000..68a1b388 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/map/truffleruby_map_backend.rb @@ -0,0 +1,14 @@ +module Concurrent + + # @!visibility private + module Collection + + # @!visibility private + class TruffleRubyMapBackend < TruffleRuby::ConcurrentMap + def initialize(options = nil) + options ||= {} + super(initial_capacity: options[:initial_capacity], load_factor: options[:load_factor]) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/non_concurrent_priority_queue.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/non_concurrent_priority_queue.rb new file mode 100644 index 00000000..694cd7ac --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/non_concurrent_priority_queue.rb @@ -0,0 +1,143 @@ +require 'concurrent/utility/engine' +require 'concurrent/collection/java_non_concurrent_priority_queue' +require 'concurrent/collection/ruby_non_concurrent_priority_queue' + +module Concurrent + module Collection + + # @!visibility private + # @!macro internal_implementation_note + NonConcurrentPriorityQueueImplementation = case + when Concurrent.on_jruby? + JavaNonConcurrentPriorityQueue + else + RubyNonConcurrentPriorityQueue + end + private_constant :NonConcurrentPriorityQueueImplementation + + # @!macro priority_queue + # + # A queue collection in which the elements are sorted based on their + # comparison (spaceship) operator `<=>`. Items are added to the queue + # at a position relative to their priority. On removal the element + # with the "highest" priority is removed. By default the sort order is + # from highest to lowest, but a lowest-to-highest sort order can be + # set on construction. + # + # The API is based on the `Queue` class from the Ruby standard library. + # + # The pure Ruby implementation, `RubyNonConcurrentPriorityQueue` uses a heap algorithm + # stored in an array. The algorithm is based on the work of Robert Sedgewick + # and Kevin Wayne. + # + # The JRuby native implementation is a thin wrapper around the standard + # library `java.util.NonConcurrentPriorityQueue`. + # + # When running under JRuby the class `NonConcurrentPriorityQueue` extends `JavaNonConcurrentPriorityQueue`. + # When running under all other interpreters it extends `RubyNonConcurrentPriorityQueue`. + # + # @note This implementation is *not* thread safe. + # + # @see http://en.wikipedia.org/wiki/Priority_queue + # @see http://ruby-doc.org/stdlib-2.0.0/libdoc/thread/rdoc/Queue.html + # + # @see http://algs4.cs.princeton.edu/24pq/index.php#2.6 + # @see http://algs4.cs.princeton.edu/24pq/MaxPQ.java.html + # + # @see http://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html + # + # @!visibility private + class NonConcurrentPriorityQueue < NonConcurrentPriorityQueueImplementation + + alias_method :has_priority?, :include? + + alias_method :size, :length + + alias_method :deq, :pop + alias_method :shift, :pop + + alias_method :<<, :push + alias_method :enq, :push + + # @!method initialize(opts = {}) + # @!macro priority_queue_method_initialize + # + # Create a new priority queue with no items. + # + # @param [Hash] opts the options for creating the queue + # @option opts [Symbol] :order (:max) dictates the order in which items are + # stored: from highest to lowest when `:max` or `:high`; from lowest to + # highest when `:min` or `:low` + + # @!method clear + # @!macro priority_queue_method_clear + # + # Removes all of the elements from this priority queue. + + # @!method delete(item) + # @!macro priority_queue_method_delete + # + # Deletes all items from `self` that are equal to `item`. + # + # @param [Object] item the item to be removed from the queue + # @return [Object] true if the item is found else false + + # @!method empty? + # @!macro priority_queue_method_empty + # + # Returns `true` if `self` contains no elements. + # + # @return [Boolean] true if there are no items in the queue else false + + # @!method include?(item) + # @!macro priority_queue_method_include + # + # Returns `true` if the given item is present in `self` (that is, if any + # element == `item`), otherwise returns false. + # + # @param [Object] item the item to search for + # + # @return [Boolean] true if the item is found else false + + # @!method length + # @!macro priority_queue_method_length + # + # The current length of the queue. + # + # @return [Fixnum] the number of items in the queue + + # @!method peek + # @!macro priority_queue_method_peek + # + # Retrieves, but does not remove, the head of this queue, or returns `nil` + # if this queue is empty. + # + # @return [Object] the head of the queue or `nil` when empty + + # @!method pop + # @!macro priority_queue_method_pop + # + # Retrieves and removes the head of this queue, or returns `nil` if this + # queue is empty. + # + # @return [Object] the head of the queue or `nil` when empty + + # @!method push(item) + # @!macro priority_queue_method_push + # + # Inserts the specified element into this priority queue. + # + # @param [Object] item the item to insert onto the queue + + # @!method self.from_list(list, opts = {}) + # @!macro priority_queue_method_from_list + # + # Create a new priority queue from the given list. + # + # @param [Enumerable] list the list to build the queue from + # @param [Hash] opts the options for creating the queue + # + # @return [NonConcurrentPriorityQueue] the newly created and populated queue + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/ruby_non_concurrent_priority_queue.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/ruby_non_concurrent_priority_queue.rb new file mode 100644 index 00000000..322b4ac2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/collection/ruby_non_concurrent_priority_queue.rb @@ -0,0 +1,160 @@ +module Concurrent + module Collection + + # @!macro priority_queue + # + # @!visibility private + # @!macro internal_implementation_note + class RubyNonConcurrentPriorityQueue + + # @!macro priority_queue_method_initialize + def initialize(opts = {}) + order = opts.fetch(:order, :max) + @comparator = [:min, :low].include?(order) ? -1 : 1 + clear + end + + # @!macro priority_queue_method_clear + def clear + @queue = [nil] + @length = 0 + true + end + + # @!macro priority_queue_method_delete + def delete(item) + return false if empty? + original_length = @length + k = 1 + while k <= @length + if @queue[k] == item + swap(k, @length) + @length -= 1 + sink(k) || swim(k) + @queue.pop + else + k += 1 + end + end + @length != original_length + end + + # @!macro priority_queue_method_empty + def empty? + size == 0 + end + + # @!macro priority_queue_method_include + def include?(item) + @queue.include?(item) + end + alias_method :has_priority?, :include? + + # @!macro priority_queue_method_length + def length + @length + end + alias_method :size, :length + + # @!macro priority_queue_method_peek + def peek + empty? ? nil : @queue[1] + end + + # @!macro priority_queue_method_pop + def pop + return nil if empty? + max = @queue[1] + swap(1, @length) + @length -= 1 + sink(1) + @queue.pop + max + end + alias_method :deq, :pop + alias_method :shift, :pop + + # @!macro priority_queue_method_push + def push(item) + raise ArgumentError.new('cannot enqueue nil') if item.nil? + @length += 1 + @queue << item + swim(@length) + true + end + alias_method :<<, :push + alias_method :enq, :push + + # @!macro priority_queue_method_from_list + def self.from_list(list, opts = {}) + queue = new(opts) + list.each{|item| queue << item } + queue + end + + private + + # Exchange the values at the given indexes within the internal array. + # + # @param [Integer] x the first index to swap + # @param [Integer] y the second index to swap + # + # @!visibility private + def swap(x, y) + temp = @queue[x] + @queue[x] = @queue[y] + @queue[y] = temp + end + + # Are the items at the given indexes ordered based on the priority + # order specified at construction? + # + # @param [Integer] x the first index from which to retrieve a comparable value + # @param [Integer] y the second index from which to retrieve a comparable value + # + # @return [Boolean] true if the two elements are in the correct priority order + # else false + # + # @!visibility private + def ordered?(x, y) + (@queue[x] <=> @queue[y]) == @comparator + end + + # Percolate down to maintain heap invariant. + # + # @param [Integer] k the index at which to start the percolation + # + # @!visibility private + def sink(k) + success = false + + while (j = (2 * k)) <= @length do + j += 1 if j < @length && ! ordered?(j, j+1) + break if ordered?(k, j) + swap(k, j) + success = true + k = j + end + + success + end + + # Percolate up to maintain heap invariant. + # + # @param [Integer] k the index at which to start the percolation + # + # @!visibility private + def swim(k) + success = false + + while k > 1 && ! ordered?(k/2, k) do + swap(k, k/2) + k = k/2 + success = true + end + + success + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/concern/deprecation.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/concern/deprecation.rb new file mode 100644 index 00000000..35ae4b2c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/concern/deprecation.rb @@ -0,0 +1,34 @@ +require 'concurrent/concern/logging' + +module Concurrent + module Concern + + # @!visibility private + # @!macro internal_implementation_note + module Deprecation + # TODO require additional parameter: a version. Display when it'll be removed based on that. Error if not removed. + include Concern::Logging + + def deprecated(message, strip = 2) + caller_line = caller(strip).first if strip > 0 + klass = if Module === self + self + else + self.class + end + message = if strip > 0 + format("[DEPRECATED] %s\ncalled on: %s", message, caller_line) + else + format('[DEPRECATED] %s', message) + end + log WARN, klass.to_s, message + end + + def deprecated_method(old_name, new_name) + deprecated "`#{old_name}` is deprecated and it'll removed in next release, use `#{new_name}` instead", 3 + end + + extend self + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/concern/dereferenceable.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/concern/dereferenceable.rb new file mode 100644 index 00000000..dc172ba7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/concern/dereferenceable.rb @@ -0,0 +1,73 @@ +module Concurrent + module Concern + + # Object references in Ruby are mutable. This can lead to serious problems when + # the `#value` of a concurrent object is a mutable reference. Which is always the + # case unless the value is a `Fixnum`, `Symbol`, or similar "primitive" data type. + # Most classes in this library that expose a `#value` getter method do so using the + # `Dereferenceable` mixin module. + # + # @!macro copy_options + module Dereferenceable + # NOTE: This module is going away in 2.0. In the mean time we need it to + # play nicely with the synchronization layer. This means that the + # including class SHOULD be synchronized and it MUST implement a + # `#synchronize` method. Not doing so will lead to runtime errors. + + # Return the value this object represents after applying the options specified + # by the `#set_deref_options` method. + # + # @return [Object] the current value of the object + def value + synchronize { apply_deref_options(@value) } + end + alias_method :deref, :value + + protected + + # Set the internal value of this object + # + # @param [Object] value the new value + def value=(value) + synchronize{ @value = value } + end + + # @!macro dereferenceable_set_deref_options + # Set the options which define the operations #value performs before + # returning data to the caller (dereferencing). + # + # @note Most classes that include this module will call `#set_deref_options` + # from within the constructor, thus allowing these options to be set at + # object creation. + # + # @param [Hash] opts the options defining dereference behavior. + # @option opts [String] :dup_on_deref (false) call `#dup` before returning the data + # @option opts [String] :freeze_on_deref (false) call `#freeze` before returning the data + # @option opts [String] :copy_on_deref (nil) call the given `Proc` passing + # the internal value and returning the value returned from the proc + def set_deref_options(opts = {}) + synchronize{ ns_set_deref_options(opts) } + end + + # @!macro dereferenceable_set_deref_options + # @!visibility private + def ns_set_deref_options(opts) + @dup_on_deref = opts[:dup_on_deref] || opts[:dup] + @freeze_on_deref = opts[:freeze_on_deref] || opts[:freeze] + @copy_on_deref = opts[:copy_on_deref] || opts[:copy] + @do_nothing_on_deref = !(@dup_on_deref || @freeze_on_deref || @copy_on_deref) + nil + end + + # @!visibility private + def apply_deref_options(value) + return nil if value.nil? + return value if @do_nothing_on_deref + value = @copy_on_deref.call(value) if @copy_on_deref + value = value.dup if @dup_on_deref + value = value.freeze if @freeze_on_deref + value + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/concern/logging.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/concern/logging.rb new file mode 100644 index 00000000..d1aae81a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/concern/logging.rb @@ -0,0 +1,121 @@ +require 'concurrent/atomic/atomic_reference' + +module Concurrent + module Concern + + # Include where logging is needed + # + # @!visibility private + module Logging + # The same as Logger::Severity but we copy it here to avoid a dependency on the logger gem just for these 7 constants + DEBUG, INFO, WARN, ERROR, FATAL, UNKNOWN = 0, 1, 2, 3, 4, 5 + SEV_LABEL = %w[DEBUG INFO WARN ERROR FATAL ANY].freeze + + # Logs through {Concurrent.global_logger}, it can be overridden by setting @logger + # @param [Integer] level one of Concurrent::Concern::Logging constants + # @param [String] progname e.g. a path of an Actor + # @param [String, nil] message when nil block is used to generate the message + # @yieldreturn [String] a message + def log(level, progname, message = nil, &block) + logger = if defined?(@logger) && @logger + @logger + else + Concurrent.global_logger + end + logger.call level, progname, message, &block + rescue => error + $stderr.puts "`Concurrent.global_logger` failed to log #{[level, progname, message, block]}\n" + + "#{error.message} (#{error.class})\n#{error.backtrace.join "\n"}" + end + end + end +end + +module Concurrent + extend Concern::Logging + + # Create a simple logger with provided level and output. + def self.create_simple_logger(level = :FATAL, output = $stderr) + level = Concern::Logging.const_get(level) unless level.is_a?(Integer) + + # TODO (pitr-ch 24-Dec-2016): figure out why it had to be replaced, stdlogger was deadlocking + lambda do |severity, progname, message = nil, &block| + return false if severity < level + + message = block ? block.call : message + formatted_message = case message + when String + message + when Exception + format "%s (%s)\n%s", + message.message, message.class, (message.backtrace || []).join("\n") + else + message.inspect + end + + output.print format "[%s] %5s -- %s: %s\n", + Time.now.strftime('%Y-%m-%d %H:%M:%S.%L'), + Concern::Logging::SEV_LABEL[severity], + progname, + formatted_message + true + end + end + + # Use logger created by #create_simple_logger to log concurrent-ruby messages. + def self.use_simple_logger(level = :FATAL, output = $stderr) + Concurrent.global_logger = create_simple_logger level, output + end + + # Create a stdlib logger with provided level and output. + # If you use this deprecated method you might need to add logger to your Gemfile to avoid warnings from Ruby 3.3.5+. + # @deprecated + def self.create_stdlib_logger(level = :FATAL, output = $stderr) + require 'logger' + logger = Logger.new(output) + logger.level = level + logger.formatter = lambda do |severity, datetime, progname, msg| + formatted_message = case msg + when String + msg + when Exception + format "%s (%s)\n%s", + msg.message, msg.class, (msg.backtrace || []).join("\n") + else + msg.inspect + end + format "[%s] %5s -- %s: %s\n", + datetime.strftime('%Y-%m-%d %H:%M:%S.%L'), + severity, + progname, + formatted_message + end + + lambda do |loglevel, progname, message = nil, &block| + logger.add loglevel, message, progname, &block + end + end + + # Use logger created by #create_stdlib_logger to log concurrent-ruby messages. + # @deprecated + def self.use_stdlib_logger(level = :FATAL, output = $stderr) + Concurrent.global_logger = create_stdlib_logger level, output + end + + # TODO (pitr-ch 27-Dec-2016): remove deadlocking stdlib_logger methods + + # Suppresses all output when used for logging. + NULL_LOGGER = lambda { |level, progname, message = nil, &block| } + + # @!visibility private + GLOBAL_LOGGER = AtomicReference.new(create_simple_logger(:WARN)) + private_constant :GLOBAL_LOGGER + + def self.global_logger + GLOBAL_LOGGER.value + end + + def self.global_logger=(value) + GLOBAL_LOGGER.value = value + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/concern/obligation.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/concern/obligation.rb new file mode 100644 index 00000000..2c9ac120 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/concern/obligation.rb @@ -0,0 +1,220 @@ +require 'thread' +require 'timeout' + +require 'concurrent/atomic/event' +require 'concurrent/concern/dereferenceable' + +module Concurrent + module Concern + + module Obligation + include Concern::Dereferenceable + # NOTE: The Dereferenceable module is going away in 2.0. In the mean time + # we need it to place nicely with the synchronization layer. This means + # that the including class SHOULD be synchronized and it MUST implement a + # `#synchronize` method. Not doing so will lead to runtime errors. + + # Has the obligation been fulfilled? + # + # @return [Boolean] + def fulfilled? + state == :fulfilled + end + alias_method :realized?, :fulfilled? + + # Has the obligation been rejected? + # + # @return [Boolean] + def rejected? + state == :rejected + end + + # Is obligation completion still pending? + # + # @return [Boolean] + def pending? + state == :pending + end + + # Is the obligation still unscheduled? + # + # @return [Boolean] + def unscheduled? + state == :unscheduled + end + + # Has the obligation completed processing? + # + # @return [Boolean] + def complete? + [:fulfilled, :rejected].include? state + end + + # Is the obligation still awaiting completion of processing? + # + # @return [Boolean] + def incomplete? + ! complete? + end + + # The current value of the obligation. Will be `nil` while the state is + # pending or the operation has been rejected. + # + # @param [Numeric] timeout the maximum time in seconds to wait. + # @return [Object] see Dereferenceable#deref + def value(timeout = nil) + wait timeout + deref + end + + # Wait until obligation is complete or the timeout has been reached. + # + # @param [Numeric] timeout the maximum time in seconds to wait. + # @return [Obligation] self + def wait(timeout = nil) + event.wait(timeout) if timeout != 0 && incomplete? + self + end + + # Wait until obligation is complete or the timeout is reached. Will re-raise + # any exceptions raised during processing (but will not raise an exception + # on timeout). + # + # @param [Numeric] timeout the maximum time in seconds to wait. + # @return [Obligation] self + # @raise [Exception] raises the reason when rejected + def wait!(timeout = nil) + wait(timeout).tap { raise self if rejected? } + end + alias_method :no_error!, :wait! + + # The current value of the obligation. Will be `nil` while the state is + # pending or the operation has been rejected. Will re-raise any exceptions + # raised during processing (but will not raise an exception on timeout). + # + # @param [Numeric] timeout the maximum time in seconds to wait. + # @return [Object] see Dereferenceable#deref + # @raise [Exception] raises the reason when rejected + def value!(timeout = nil) + wait(timeout) + if rejected? + raise self + else + deref + end + end + + # The current state of the obligation. + # + # @return [Symbol] the current state + def state + synchronize { @state } + end + + # If an exception was raised during processing this will return the + # exception object. Will return `nil` when the state is pending or if + # the obligation has been successfully fulfilled. + # + # @return [Exception] the exception raised during processing or `nil` + def reason + synchronize { @reason } + end + + # @example allows Obligation to be risen + # rejected_ivar = Ivar.new.fail + # raise rejected_ivar + def exception(*args) + raise 'obligation is not rejected' unless rejected? + reason.exception(*args) + end + + protected + + # @!visibility private + def get_arguments_from(opts = {}) + [*opts.fetch(:args, [])] + end + + # @!visibility private + def init_obligation + @event = Event.new + @value = @reason = nil + end + + # @!visibility private + def event + @event + end + + # @!visibility private + def set_state(success, value, reason) + if success + @value = value + @state = :fulfilled + else + @reason = reason + @state = :rejected + end + end + + # @!visibility private + def state=(value) + synchronize { ns_set_state(value) } + end + + # Atomic compare and set operation + # State is set to `next_state` only if `current state == expected_current`. + # + # @param [Symbol] next_state + # @param [Symbol] expected_current + # + # @return [Boolean] true is state is changed, false otherwise + # + # @!visibility private + def compare_and_set_state(next_state, *expected_current) + synchronize do + if expected_current.include? @state + @state = next_state + true + else + false + end + end + end + + # Executes the block within mutex if current state is included in expected_states + # + # @return block value if executed, false otherwise + # + # @!visibility private + def if_state(*expected_states) + synchronize do + raise ArgumentError.new('no block given') unless block_given? + + if expected_states.include? @state + yield + else + false + end + end + end + + protected + + # Am I in the current state? + # + # @param [Symbol] expected The state to check against + # @return [Boolean] true if in the expected state else false + # + # @!visibility private + def ns_check_state?(expected) + @state == expected + end + + # @!visibility private + def ns_set_state(value) + @state = value + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/concern/observable.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/concern/observable.rb new file mode 100644 index 00000000..b5132714 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/concern/observable.rb @@ -0,0 +1,110 @@ +require 'concurrent/collection/copy_on_notify_observer_set' +require 'concurrent/collection/copy_on_write_observer_set' + +module Concurrent + module Concern + + # The [observer pattern](http://en.wikipedia.org/wiki/Observer_pattern) is one + # of the most useful design patterns. + # + # The workflow is very simple: + # - an `observer` can register itself to a `subject` via a callback + # - many `observers` can be registered to the same `subject` + # - the `subject` notifies all registered observers when its status changes + # - an `observer` can deregister itself when is no more interested to receive + # event notifications + # + # In a single threaded environment the whole pattern is very easy: the + # `subject` can use a simple data structure to manage all its subscribed + # `observer`s and every `observer` can react directly to every event without + # caring about synchronization. + # + # In a multi threaded environment things are more complex. The `subject` must + # synchronize the access to its data structure and to do so currently we're + # using two specialized ObserverSet: {Concurrent::Concern::CopyOnWriteObserverSet} + # and {Concurrent::Concern::CopyOnNotifyObserverSet}. + # + # When implementing and `observer` there's a very important rule to remember: + # **there are no guarantees about the thread that will execute the callback** + # + # Let's take this example + # ``` + # class Observer + # def initialize + # @count = 0 + # end + # + # def update + # @count += 1 + # end + # end + # + # obs = Observer.new + # [obj1, obj2, obj3, obj4].each { |o| o.add_observer(obs) } + # # execute [obj1, obj2, obj3, obj4] + # ``` + # + # `obs` is wrong because the variable `@count` can be accessed by different + # threads at the same time, so it should be synchronized (using either a Mutex + # or an AtomicFixum) + module Observable + + # @!macro observable_add_observer + # + # Adds an observer to this set. If a block is passed, the observer will be + # created by this method and no other params should be passed. + # + # @param [Object] observer the observer to add + # @param [Symbol] func the function to call on the observer during notification. + # Default is :update + # @return [Object] the added observer + def add_observer(observer = nil, func = :update, &block) + observers.add_observer(observer, func, &block) + end + + # As `#add_observer` but can be used for chaining. + # + # @param [Object] observer the observer to add + # @param [Symbol] func the function to call on the observer during notification. + # @return [Observable] self + def with_observer(observer = nil, func = :update, &block) + add_observer(observer, func, &block) + self + end + + # @!macro observable_delete_observer + # + # Remove `observer` as an observer on this object so that it will no + # longer receive notifications. + # + # @param [Object] observer the observer to remove + # @return [Object] the deleted observer + def delete_observer(observer) + observers.delete_observer(observer) + end + + # @!macro observable_delete_observers + # + # Remove all observers associated with this object. + # + # @return [Observable] self + def delete_observers + observers.delete_observers + self + end + + # @!macro observable_count_observers + # + # Return the number of observers associated with this object. + # + # @return [Integer] the observers count + def count_observers + observers.count_observers + end + + protected + + attr_accessor :observers + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/concurrent_ruby.jar b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/concurrent_ruby.jar new file mode 100644 index 00000000..d5b8d275 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/concurrent_ruby.jar differ diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/configuration.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/configuration.rb new file mode 100644 index 00000000..5571d39b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/configuration.rb @@ -0,0 +1,105 @@ +require 'thread' +require 'concurrent/delay' +require 'concurrent/errors' +require 'concurrent/concern/deprecation' +require 'concurrent/executor/immediate_executor' +require 'concurrent/executor/fixed_thread_pool' +require 'concurrent/executor/cached_thread_pool' +require 'concurrent/utility/processor_counter' + +module Concurrent + extend Concern::Deprecation + + autoload :Options, 'concurrent/options' + autoload :TimerSet, 'concurrent/executor/timer_set' + autoload :ThreadPoolExecutor, 'concurrent/executor/thread_pool_executor' + + # @!visibility private + GLOBAL_FAST_EXECUTOR = Delay.new { Concurrent.new_fast_executor } + private_constant :GLOBAL_FAST_EXECUTOR + + # @!visibility private + GLOBAL_IO_EXECUTOR = Delay.new { Concurrent.new_io_executor } + private_constant :GLOBAL_IO_EXECUTOR + + # @!visibility private + GLOBAL_TIMER_SET = Delay.new { TimerSet.new } + private_constant :GLOBAL_TIMER_SET + + # @!visibility private + GLOBAL_IMMEDIATE_EXECUTOR = ImmediateExecutor.new + private_constant :GLOBAL_IMMEDIATE_EXECUTOR + + # Disables AtExit handlers including pool auto-termination handlers. + # When disabled it will be the application programmer's responsibility + # to ensure that the handlers are shutdown properly prior to application + # exit by calling `AtExit.run` method. + # + # @note this option should be needed only because of `at_exit` ordering + # issues which may arise when running some of the testing frameworks. + # E.g. Minitest's test-suite runs itself in `at_exit` callback which + # executes after the pools are already terminated. Then auto termination + # needs to be disabled and called manually after test-suite ends. + # @note This method should *never* be called + # from within a gem. It should *only* be used from within the main + # application and even then it should be used only when necessary. + # @deprecated Has no effect since it is no longer needed, see https://github.com/ruby-concurrency/concurrent-ruby/pull/841. + # + def self.disable_at_exit_handlers! + deprecated "Method #disable_at_exit_handlers! has no effect since it is no longer needed, see https://github.com/ruby-concurrency/concurrent-ruby/pull/841." + end + + # Global thread pool optimized for short, fast *operations*. + # + # @return [ThreadPoolExecutor] the thread pool + def self.global_fast_executor + GLOBAL_FAST_EXECUTOR.value! + end + + # Global thread pool optimized for long, blocking (IO) *tasks*. + # + # @return [ThreadPoolExecutor] the thread pool + def self.global_io_executor + GLOBAL_IO_EXECUTOR.value! + end + + def self.global_immediate_executor + GLOBAL_IMMEDIATE_EXECUTOR + end + + # Global thread pool user for global *timers*. + # + # @return [Concurrent::TimerSet] the thread pool + def self.global_timer_set + GLOBAL_TIMER_SET.value! + end + + # General access point to global executors. + # @param [Symbol, Executor] executor_identifier symbols: + # - :fast - {Concurrent.global_fast_executor} + # - :io - {Concurrent.global_io_executor} + # - :immediate - {Concurrent.global_immediate_executor} + # @return [Executor] + def self.executor(executor_identifier) + Options.executor(executor_identifier) + end + + def self.new_fast_executor(opts = {}) + FixedThreadPool.new( + [2, Concurrent.processor_count].max, + auto_terminate: opts.fetch(:auto_terminate, true), + idletime: 60, # 1 minute + max_queue: 0, # unlimited + fallback_policy: :abort, # shouldn't matter -- 0 max queue + name: "fast" + ) + end + + def self.new_io_executor(opts = {}) + CachedThreadPool.new( + auto_terminate: opts.fetch(:auto_terminate, true), + fallback_policy: :abort, # shouldn't matter -- 0 max queue + name: "io" + ) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/constants.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/constants.rb new file mode 100644 index 00000000..676c2afb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/constants.rb @@ -0,0 +1,8 @@ +module Concurrent + + # Various classes within allows for +nil+ values to be stored, + # so a special +NULL+ token is required to indicate the "nil-ness". + # @!visibility private + NULL = ::Object.new + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/dataflow.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/dataflow.rb new file mode 100644 index 00000000..d55f19d8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/dataflow.rb @@ -0,0 +1,81 @@ +require 'concurrent/future' +require 'concurrent/atomic/atomic_fixnum' + +module Concurrent + + # @!visibility private + class DependencyCounter # :nodoc: + + def initialize(count, &block) + @counter = AtomicFixnum.new(count) + @block = block + end + + def update(time, value, reason) + if @counter.decrement == 0 + @block.call + end + end + end + + # Dataflow allows you to create a task that will be scheduled when all of its data dependencies are available. + # {include:file:docs-source/dataflow.md} + # + # @param [Future] inputs zero or more `Future` operations that this dataflow depends upon + # + # @yield The operation to perform once all the dependencies are met + # @yieldparam [Future] inputs each of the `Future` inputs to the dataflow + # @yieldreturn [Object] the result of the block operation + # + # @return [Object] the result of all the operations + # + # @raise [ArgumentError] if no block is given + # @raise [ArgumentError] if any of the inputs are not `IVar`s + def dataflow(*inputs, &block) + dataflow_with(Concurrent.global_io_executor, *inputs, &block) + end + module_function :dataflow + + def dataflow_with(executor, *inputs, &block) + call_dataflow(:value, executor, *inputs, &block) + end + module_function :dataflow_with + + def dataflow!(*inputs, &block) + dataflow_with!(Concurrent.global_io_executor, *inputs, &block) + end + module_function :dataflow! + + def dataflow_with!(executor, *inputs, &block) + call_dataflow(:value!, executor, *inputs, &block) + end + module_function :dataflow_with! + + private + + def call_dataflow(method, executor, *inputs, &block) + raise ArgumentError.new('an executor must be provided') if executor.nil? + raise ArgumentError.new('no block given') unless block_given? + unless inputs.all? { |input| input.is_a? IVar } + raise ArgumentError.new("Not all dependencies are IVars.\nDependencies: #{ inputs.inspect }") + end + + result = Future.new(executor: executor) do + values = inputs.map { |input| input.send(method) } + block.call(*values) + end + + if inputs.empty? + result.execute + else + counter = DependencyCounter.new(inputs.size) { result.execute } + + inputs.each do |input| + input.add_observer counter + end + end + + result + end + module_function :call_dataflow +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/delay.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/delay.rb new file mode 100644 index 00000000..0d6d91a5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/delay.rb @@ -0,0 +1,199 @@ +require 'thread' +require 'concurrent/concern/obligation' +require 'concurrent/executor/immediate_executor' +require 'concurrent/synchronization/lockable_object' + +module Concurrent + + # This file has circular require issues. It must be autoloaded here. + autoload :Options, 'concurrent/options' + + # Lazy evaluation of a block yielding an immutable result. Useful for + # expensive operations that may never be needed. It may be non-blocking, + # supports the `Concern::Obligation` interface, and accepts the injection of + # custom executor upon which to execute the block. Processing of + # block will be deferred until the first time `#value` is called. + # At that time the caller can choose to return immediately and let + # the block execute asynchronously, block indefinitely, or block + # with a timeout. + # + # When a `Delay` is created its state is set to `pending`. The value and + # reason are both `nil`. The first time the `#value` method is called the + # enclosed operation will be run and the calling thread will block. Other + # threads attempting to call `#value` will block as well. Once the operation + # is complete the *value* will be set to the result of the operation or the + # *reason* will be set to the raised exception, as appropriate. All threads + # blocked on `#value` will return. Subsequent calls to `#value` will immediately + # return the cached value. The operation will only be run once. This means that + # any side effects created by the operation will only happen once as well. + # + # `Delay` includes the `Concurrent::Concern::Dereferenceable` mixin to support thread + # safety of the reference returned by `#value`. + # + # @!macro copy_options + # + # @!macro delay_note_regarding_blocking + # @note The default behavior of `Delay` is to block indefinitely when + # calling either `value` or `wait`, executing the delayed operation on + # the current thread. This makes the `timeout` value completely + # irrelevant. To enable non-blocking behavior, use the `executor` + # constructor option. This will cause the delayed operation to be + # execute on the given executor, allowing the call to timeout. + # + # @see Concurrent::Concern::Dereferenceable + class Delay < Synchronization::LockableObject + include Concern::Obligation + + # NOTE: Because the global thread pools are lazy-loaded with these objects + # there is a performance hit every time we post a new task to one of these + # thread pools. Subsequently it is critical that `Delay` perform as fast + # as possible post-completion. This class has been highly optimized using + # the benchmark script `examples/lazy_and_delay.rb`. Do NOT attempt to + # DRY-up this class or perform other refactoring with running the + # benchmarks and ensuring that performance is not negatively impacted. + + # Create a new `Delay` in the `:pending` state. + # + # @!macro executor_and_deref_options + # + # @yield the delayed operation to perform + # + # @raise [ArgumentError] if no block is given + def initialize(opts = {}, &block) + raise ArgumentError.new('no block given') unless block_given? + super(&nil) + synchronize { ns_initialize(opts, &block) } + end + + # Return the value this object represents after applying the options + # specified by the `#set_deref_options` method. If the delayed operation + # raised an exception this method will return nil. The exception object + # can be accessed via the `#reason` method. + # + # @param [Numeric] timeout the maximum number of seconds to wait + # @return [Object] the current value of the object + # + # @!macro delay_note_regarding_blocking + def value(timeout = nil) + if @executor # TODO (pitr 12-Sep-2015): broken unsafe read? + super + else + # this function has been optimized for performance and + # should not be modified without running new benchmarks + synchronize do + execute = @evaluation_started = true unless @evaluation_started + if execute + begin + set_state(true, @task.call, nil) + rescue => ex + set_state(false, nil, ex) + end + elsif incomplete? + raise IllegalOperationError, 'Recursive call to #value during evaluation of the Delay' + end + end + if @do_nothing_on_deref + @value + else + apply_deref_options(@value) + end + end + end + + # Return the value this object represents after applying the options + # specified by the `#set_deref_options` method. If the delayed operation + # raised an exception, this method will raise that exception (even when) + # the operation has already been executed). + # + # @param [Numeric] timeout the maximum number of seconds to wait + # @return [Object] the current value of the object + # @raise [Exception] when `#rejected?` raises `#reason` + # + # @!macro delay_note_regarding_blocking + def value!(timeout = nil) + if @executor + super + else + result = value + raise @reason if @reason + result + end + end + + # Return the value this object represents after applying the options + # specified by the `#set_deref_options` method. + # + # @param [Integer] timeout (nil) the maximum number of seconds to wait for + # the value to be computed. When `nil` the caller will block indefinitely. + # + # @return [Object] self + # + # @!macro delay_note_regarding_blocking + def wait(timeout = nil) + if @executor + execute_task_once + super(timeout) + else + value + end + self + end + + # Reconfigures the block returning the value if still `#incomplete?` + # + # @yield the delayed operation to perform + # @return [true, false] if success + def reconfigure(&block) + synchronize do + raise ArgumentError.new('no block given') unless block_given? + unless @evaluation_started + @task = block + true + else + false + end + end + end + + protected + + def ns_initialize(opts, &block) + init_obligation + set_deref_options(opts) + @executor = opts[:executor] + + @task = block + @state = :pending + @evaluation_started = false + end + + private + + # @!visibility private + def execute_task_once # :nodoc: + # this function has been optimized for performance and + # should not be modified without running new benchmarks + execute = task = nil + synchronize do + execute = @evaluation_started = true unless @evaluation_started + task = @task + end + + if execute + executor = Options.executor_from_options(executor: @executor) + executor.post do + begin + result = task.call + success = true + rescue => ex + reason = ex + end + synchronize do + set_state(success, result, reason) + event.set + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/errors.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/errors.rb new file mode 100644 index 00000000..74f1fc3d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/errors.rb @@ -0,0 +1,74 @@ +module Concurrent + + Error = Class.new(StandardError) + + # Raised when errors occur during configuration. + ConfigurationError = Class.new(Error) + + # Raised when an asynchronous operation is cancelled before execution. + CancelledOperationError = Class.new(Error) + + # Raised when a lifecycle method (such as `stop`) is called in an improper + # sequence or when the object is in an inappropriate state. + LifecycleError = Class.new(Error) + + # Raised when an attempt is made to violate an immutability guarantee. + ImmutabilityError = Class.new(Error) + + # Raised when an operation is attempted which is not legal given the + # receiver's current state + IllegalOperationError = Class.new(Error) + + # Raised when an object's methods are called when it has not been + # properly initialized. + InitializationError = Class.new(Error) + + # Raised when an object with a start/stop lifecycle has been started an + # excessive number of times. Often used in conjunction with a restart + # policy or strategy. + MaxRestartFrequencyError = Class.new(Error) + + # Raised when an attempt is made to modify an immutable object + # (such as an `IVar`) after its final state has been set. + class MultipleAssignmentError < Error + attr_reader :inspection_data + + def initialize(message = nil, inspection_data = nil) + @inspection_data = inspection_data + super message + end + + def inspect + format '%s %s>', super[0..-2], @inspection_data.inspect + end + end + + # Raised by an `Executor` when it is unable to process a given task, + # possibly because of a reject policy or other internal error. + RejectedExecutionError = Class.new(Error) + + # Raised when any finite resource, such as a lock counter, exceeds its + # maximum limit/threshold. + ResourceLimitError = Class.new(Error) + + # Raised when an operation times out. + TimeoutError = Class.new(Error) + + # Aggregates multiple exceptions. + class MultipleErrors < Error + attr_reader :errors + + def initialize(errors, message = "#{errors.size} errors") + @errors = errors + super [*message, + *errors.map { |e| [format('%s (%s)', e.message, e.class), *e.backtrace] }.flatten(1) + ].join("\n") + end + end + + # @!macro internal_implementation_note + class ConcurrentUpdateError < ThreadError + # frozen pre-allocated backtrace to speed ConcurrentUpdateError + CONC_UP_ERR_BACKTRACE = ['backtrace elided; set verbose to enable'].freeze + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/exchanger.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/exchanger.rb new file mode 100644 index 00000000..a5405d25 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/exchanger.rb @@ -0,0 +1,353 @@ +require 'concurrent/constants' +require 'concurrent/errors' +require 'concurrent/maybe' +require 'concurrent/atomic/atomic_reference' +require 'concurrent/atomic/count_down_latch' +require 'concurrent/utility/engine' +require 'concurrent/utility/monotonic_time' + +module Concurrent + + # @!macro exchanger + # + # A synchronization point at which threads can pair and swap elements within + # pairs. Each thread presents some object on entry to the exchange method, + # matches with a partner thread, and receives its partner's object on return. + # + # @!macro thread_safe_variable_comparison + # + # This implementation is very simple, using only a single slot for each + # exchanger (unlike more advanced implementations which use an "arena"). + # This approach will work perfectly fine when there are only a few threads + # accessing a single `Exchanger`. Beyond a handful of threads the performance + # will degrade rapidly due to contention on the single slot, but the algorithm + # will remain correct. + # + # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Exchanger.html java.util.concurrent.Exchanger + # @example + # + # exchanger = Concurrent::Exchanger.new + # + # threads = [ + # Thread.new { puts "first: " << exchanger.exchange('foo', 1) }, #=> "first: bar" + # Thread.new { puts "second: " << exchanger.exchange('bar', 1) } #=> "second: foo" + # ] + # threads.each {|t| t.join(2) } + + # @!visibility private + class AbstractExchanger < Synchronization::Object + + # @!visibility private + CANCEL = ::Object.new + private_constant :CANCEL + + def initialize + super + end + + # @!macro exchanger_method_do_exchange + # + # Waits for another thread to arrive at this exchange point (unless the + # current thread is interrupted), and then transfers the given object to + # it, receiving its object in return. The timeout value indicates the + # approximate number of seconds the method should block while waiting + # for the exchange. When the timeout value is `nil` the method will + # block indefinitely. + # + # @param [Object] value the value to exchange with another thread + # @param [Numeric, nil] timeout in seconds, `nil` blocks indefinitely + # + # @!macro exchanger_method_exchange + # + # In some edge cases when a `timeout` is given a return value of `nil` may be + # ambiguous. Specifically, if `nil` is a valid value in the exchange it will + # be impossible to tell whether `nil` is the actual return value or if it + # signifies timeout. When `nil` is a valid value in the exchange consider + # using {#exchange!} or {#try_exchange} instead. + # + # @return [Object] the value exchanged by the other thread or `nil` on timeout + def exchange(value, timeout = nil) + (value = do_exchange(value, timeout)) == CANCEL ? nil : value + end + + # @!macro exchanger_method_do_exchange + # @!macro exchanger_method_exchange_bang + # + # On timeout a {Concurrent::TimeoutError} exception will be raised. + # + # @return [Object] the value exchanged by the other thread + # @raise [Concurrent::TimeoutError] on timeout + def exchange!(value, timeout = nil) + if (value = do_exchange(value, timeout)) == CANCEL + raise Concurrent::TimeoutError + else + value + end + end + + # @!macro exchanger_method_do_exchange + # @!macro exchanger_method_try_exchange + # + # The return value will be a {Concurrent::Maybe} set to `Just` on success or + # `Nothing` on timeout. + # + # @return [Concurrent::Maybe] on success a `Just` maybe will be returned with + # the item exchanged by the other thread as `#value`; on timeout a + # `Nothing` maybe will be returned with {Concurrent::TimeoutError} as `#reason` + # + # @example + # + # exchanger = Concurrent::Exchanger.new + # + # result = exchanger.exchange(:foo, 0.5) + # + # if result.just? + # puts result.value #=> :bar + # else + # puts 'timeout' + # end + def try_exchange(value, timeout = nil) + if (value = do_exchange(value, timeout)) == CANCEL + Concurrent::Maybe.nothing(Concurrent::TimeoutError) + else + Concurrent::Maybe.just(value) + end + end + + private + + # @!macro exchanger_method_do_exchange + # + # @return [Object, CANCEL] the value exchanged by the other thread; {CANCEL} on timeout + def do_exchange(value, timeout) + raise NotImplementedError + end + end + + # @!macro internal_implementation_note + # @!visibility private + class RubyExchanger < AbstractExchanger + # A simplified version of java.util.concurrent.Exchanger written by + # Doug Lea, Bill Scherer, and Michael Scott with assistance from members + # of JCP JSR-166 Expert Group and released to the public domain. It does + # not include the arena or the multi-processor spin loops. + # http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/concurrent/Exchanger.java + + safe_initialization! + + class Node < Concurrent::Synchronization::Object + attr_atomic :value + safe_initialization! + + def initialize(item) + super() + @Item = item + @Latch = Concurrent::CountDownLatch.new + self.value = nil + end + + def latch + @Latch + end + + def item + @Item + end + end + private_constant :Node + + def initialize + super + end + + private + + attr_atomic(:slot) + + # @!macro exchanger_method_do_exchange + # + # @return [Object, CANCEL] the value exchanged by the other thread; {CANCEL} on timeout + def do_exchange(value, timeout) + + # ALGORITHM + # + # From the original Java version: + # + # > The basic idea is to maintain a "slot", which is a reference to + # > a Node containing both an Item to offer and a "hole" waiting to + # > get filled in. If an incoming "occupying" thread sees that the + # > slot is null, it CAS'es (compareAndSets) a Node there and waits + # > for another to invoke exchange. That second "fulfilling" thread + # > sees that the slot is non-null, and so CASes it back to null, + # > also exchanging items by CASing the hole, plus waking up the + # > occupying thread if it is blocked. In each case CAS'es may + # > fail because a slot at first appears non-null but is null upon + # > CAS, or vice-versa. So threads may need to retry these + # > actions. + # + # This version: + # + # An exchange occurs between an "occupier" thread and a "fulfiller" thread. + # The "slot" is used to setup this interaction. The first thread in the + # exchange puts itself into the slot (occupies) and waits for a fulfiller. + # The second thread removes the occupier from the slot and attempts to + # perform the exchange. Removing the occupier also frees the slot for + # another occupier/fulfiller pair. + # + # Because the occupier and the fulfiller are operating independently and + # because there may be contention with other threads, any failed operation + # indicates contention. Both the occupier and the fulfiller operate within + # spin loops. Any failed actions along the happy path will cause the thread + # to repeat the loop and try again. + # + # When a timeout value is given the thread must be cognizant of time spent + # in the spin loop. The remaining time is checked every loop. When the time + # runs out the thread will exit. + # + # A "node" is the data structure used to perform the exchange. Only the + # occupier's node is necessary. It's the node used for the exchange. + # Each node has an "item," a "hole" (self), and a "latch." The item is the + # node's initial value. It never changes. It's what the fulfiller returns on + # success. The occupier's hole is where the fulfiller put its item. It's the + # item that the occupier returns on success. The latch is used for synchronization. + # Because a thread may act as either an occupier or fulfiller (or possibly + # both in periods of high contention) every thread creates a node when + # the exchange method is first called. + # + # The following steps occur within the spin loop. If any actions fail + # the thread will loop and try again, so long as there is time remaining. + # If time runs out the thread will return CANCEL. + # + # Check the slot for an occupier: + # + # * If the slot is empty try to occupy + # * If the slot is full try to fulfill + # + # Attempt to occupy: + # + # * Attempt to CAS myself into the slot + # * Go to sleep and wait to be woken by a fulfiller + # * If the sleep is successful then the fulfiller completed its happy path + # - Return the value from my hole (the value given by the fulfiller) + # * When the sleep fails (time ran out) attempt to cancel the operation + # - Attempt to CAS myself out of the hole + # - If successful there is no contention + # - Return CANCEL + # - On failure, I am competing with a fulfiller + # - Attempt to CAS my hole to CANCEL + # - On success + # - Let the fulfiller deal with my cancel + # - Return CANCEL + # - On failure the fulfiller has completed its happy path + # - Return th value from my hole (the fulfiller's value) + # + # Attempt to fulfill: + # + # * Attempt to CAS the occupier out of the slot + # - On failure loop again + # * Attempt to CAS my item into the occupier's hole + # - On failure the occupier is trying to cancel + # - Loop again + # - On success we are on the happy path + # - Wake the sleeping occupier + # - Return the occupier's item + + value = NULL if value.nil? # The sentinel allows nil to be a valid value + me = Node.new(value) # create my node in case I need to occupy + end_at = Concurrent.monotonic_time + timeout.to_f # The time to give up + + result = loop do + other = slot + if other && compare_and_set_slot(other, nil) + # try to fulfill + if other.compare_and_set_value(nil, value) + # happy path + other.latch.count_down + break other.item + end + elsif other.nil? && compare_and_set_slot(nil, me) + # try to occupy + timeout = end_at - Concurrent.monotonic_time if timeout + if me.latch.wait(timeout) + # happy path + break me.value + else + # attempt to remove myself from the slot + if compare_and_set_slot(me, nil) + break CANCEL + elsif !me.compare_and_set_value(nil, CANCEL) + # I've failed to block the fulfiller + break me.value + end + end + end + break CANCEL if timeout && Concurrent.monotonic_time >= end_at + end + + result == NULL ? nil : result + end + end + + if Concurrent.on_jruby? + require 'concurrent/utility/native_extension_loader' + + # @!macro internal_implementation_note + # @!visibility private + class JavaExchanger < AbstractExchanger + + def initialize + @exchanger = java.util.concurrent.Exchanger.new + end + + private + + # @!macro exchanger_method_do_exchange + # + # @return [Object, CANCEL] the value exchanged by the other thread; {CANCEL} on timeout + def do_exchange(value, timeout) + result = nil + if timeout.nil? + Synchronization::JRuby.sleep_interruptibly do + result = @exchanger.exchange(value) + end + else + Synchronization::JRuby.sleep_interruptibly do + result = @exchanger.exchange(value, 1000 * timeout, java.util.concurrent.TimeUnit::MILLISECONDS) + end + end + result + rescue java.util.concurrent.TimeoutException + CANCEL + end + end + end + + # @!visibility private + # @!macro internal_implementation_note + ExchangerImplementation = case + when Concurrent.on_jruby? + JavaExchanger + else + RubyExchanger + end + private_constant :ExchangerImplementation + + # @!macro exchanger + class Exchanger < ExchangerImplementation + + # @!method initialize + # Creates exchanger instance + + # @!method exchange(value, timeout = nil) + # @!macro exchanger_method_do_exchange + # @!macro exchanger_method_exchange + + # @!method exchange!(value, timeout = nil) + # @!macro exchanger_method_do_exchange + # @!macro exchanger_method_exchange_bang + + # @!method try_exchange(value, timeout = nil) + # @!macro exchanger_method_do_exchange + # @!macro exchanger_method_try_exchange + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/abstract_executor_service.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/abstract_executor_service.rb new file mode 100644 index 00000000..ac429531 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/abstract_executor_service.rb @@ -0,0 +1,131 @@ +require 'concurrent/errors' +require 'concurrent/concern/deprecation' +require 'concurrent/executor/executor_service' +require 'concurrent/synchronization/lockable_object' + +module Concurrent + + # @!macro abstract_executor_service_public_api + # @!visibility private + class AbstractExecutorService < Synchronization::LockableObject + include ExecutorService + include Concern::Deprecation + + # The set of possible fallback policies that may be set at thread pool creation. + FALLBACK_POLICIES = [:abort, :discard, :caller_runs].freeze + + # @!macro executor_service_attr_reader_fallback_policy + attr_reader :fallback_policy + + attr_reader :name + + # Create a new thread pool. + def initialize(opts = {}, &block) + super(&nil) + synchronize do + @auto_terminate = opts.fetch(:auto_terminate, true) + @name = opts.fetch(:name) if opts.key?(:name) + ns_initialize(opts, &block) + end + end + + def to_s + name ? "#{super[0..-2]} name: #{name}>" : super + end + + # @!macro executor_service_method_shutdown + def shutdown + raise NotImplementedError + end + + # @!macro executor_service_method_kill + def kill + raise NotImplementedError + end + + # @!macro executor_service_method_wait_for_termination + def wait_for_termination(timeout = nil) + raise NotImplementedError + end + + # @!macro executor_service_method_running_question + def running? + synchronize { ns_running? } + end + + # @!macro executor_service_method_shuttingdown_question + def shuttingdown? + synchronize { ns_shuttingdown? } + end + + # @!macro executor_service_method_shutdown_question + def shutdown? + synchronize { ns_shutdown? } + end + + # @!macro executor_service_method_auto_terminate_question + def auto_terminate? + synchronize { @auto_terminate } + end + + # @!macro executor_service_method_auto_terminate_setter + def auto_terminate=(value) + deprecated "Method #auto_terminate= has no effect. Set :auto_terminate option when executor is initialized." + end + + private + + # Returns an action which executes the `fallback_policy` once the queue + # size reaches `max_queue`. The reason for the indirection of an action + # is so that the work can be deferred outside of synchronization. + # + # @param [Array] args the arguments to the task which is being handled. + # + # @!visibility private + def fallback_action(*args) + case fallback_policy + when :abort + lambda { raise RejectedExecutionError } + when :discard + lambda { false } + when :caller_runs + lambda { + begin + yield(*args) + rescue => ex + # let it fail + log DEBUG, ex + end + true + } + else + lambda { fail "Unknown fallback policy #{fallback_policy}" } + end + end + + def ns_execute(*args, &task) + raise NotImplementedError + end + + # @!macro executor_service_method_ns_shutdown_execution + # + # Callback method called when an orderly shutdown has completed. + # The default behavior is to signal all waiting threads. + def ns_shutdown_execution + # do nothing + end + + # @!macro executor_service_method_ns_kill_execution + # + # Callback method called when the executor has been killed. + # The default behavior is to do nothing. + def ns_kill_execution + # do nothing + end + + def ns_auto_terminate? + @auto_terminate + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/cached_thread_pool.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/cached_thread_pool.rb new file mode 100644 index 00000000..de50ed17 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/cached_thread_pool.rb @@ -0,0 +1,62 @@ +require 'concurrent/utility/engine' +require 'concurrent/executor/thread_pool_executor' + +module Concurrent + + # A thread pool that dynamically grows and shrinks to fit the current workload. + # New threads are created as needed, existing threads are reused, and threads + # that remain idle for too long are killed and removed from the pool. These + # pools are particularly suited to applications that perform a high volume of + # short-lived tasks. + # + # On creation a `CachedThreadPool` has zero running threads. New threads are + # created on the pool as new operations are `#post`. The size of the pool + # will grow until `#max_length` threads are in the pool or until the number + # of threads exceeds the number of running and pending operations. When a new + # operation is post to the pool the first available idle thread will be tasked + # with the new operation. + # + # Should a thread crash for any reason the thread will immediately be removed + # from the pool. Similarly, threads which remain idle for an extended period + # of time will be killed and reclaimed. Thus these thread pools are very + # efficient at reclaiming unused resources. + # + # The API and behavior of this class are based on Java's `CachedThreadPool` + # + # @!macro thread_pool_options + class CachedThreadPool < ThreadPoolExecutor + + # @!macro cached_thread_pool_method_initialize + # + # Create a new thread pool. + # + # @param [Hash] opts the options defining pool behavior. + # @option opts [Symbol] :fallback_policy (`:abort`) the fallback policy + # + # @raise [ArgumentError] if `fallback_policy` is not a known policy + # + # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newCachedThreadPool-- + def initialize(opts = {}) + defaults = { idletime: DEFAULT_THREAD_IDLETIMEOUT } + overrides = { min_threads: 0, + max_threads: DEFAULT_MAX_POOL_SIZE, + max_queue: DEFAULT_MAX_QUEUE_SIZE } + super(defaults.merge(opts).merge(overrides)) + end + + private + + # @!macro cached_thread_pool_method_initialize + # @!visibility private + def ns_initialize(opts) + super(opts) + if Concurrent.on_jruby? + @max_queue = 0 + @executor = java.util.concurrent.Executors.newCachedThreadPool( + DaemonThreadFactory.new(ns_auto_terminate?)) + @executor.setRejectedExecutionHandler(FALLBACK_POLICY_CLASSES[@fallback_policy].new) + @executor.setKeepAliveTime(opts.fetch(:idletime, DEFAULT_THREAD_IDLETIMEOUT), java.util.concurrent.TimeUnit::SECONDS) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/executor_service.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/executor_service.rb new file mode 100644 index 00000000..7e344919 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/executor_service.rb @@ -0,0 +1,185 @@ +require 'concurrent/concern/logging' + +module Concurrent + + ################################################################### + + # @!macro executor_service_method_post + # + # Submit a task to the executor for asynchronous processing. + # + # @param [Array] args zero or more arguments to be passed to the task + # + # @yield the asynchronous task to perform + # + # @return [Boolean] `true` if the task is queued, `false` if the executor + # is not running + # + # @raise [ArgumentError] if no task is given + + # @!macro executor_service_method_left_shift + # + # Submit a task to the executor for asynchronous processing. + # + # @param [Proc] task the asynchronous task to perform + # + # @return [self] returns itself + + # @!macro executor_service_method_can_overflow_question + # + # Does the task queue have a maximum size? + # + # @return [Boolean] True if the task queue has a maximum size else false. + + # @!macro executor_service_method_serialized_question + # + # Does this executor guarantee serialization of its operations? + # + # @return [Boolean] True if the executor guarantees that all operations + # will be post in the order they are received and no two operations may + # occur simultaneously. Else false. + + ################################################################### + + # @!macro executor_service_public_api + # + # @!method post(*args, &task) + # @!macro executor_service_method_post + # + # @!method <<(task) + # @!macro executor_service_method_left_shift + # + # @!method can_overflow? + # @!macro executor_service_method_can_overflow_question + # + # @!method serialized? + # @!macro executor_service_method_serialized_question + + ################################################################### + + # @!macro executor_service_attr_reader_fallback_policy + # @return [Symbol] The fallback policy in effect. Either `:abort`, `:discard`, or `:caller_runs`. + + # @!macro executor_service_method_shutdown + # + # Begin an orderly shutdown. Tasks already in the queue will be executed, + # but no new tasks will be accepted. Has no additional effect if the + # thread pool is not running. + + # @!macro executor_service_method_kill + # + # Begin an immediate shutdown. In-progress tasks will be allowed to + # complete but enqueued tasks will be dismissed and no new tasks + # will be accepted. Has no additional effect if the thread pool is + # not running. + + # @!macro executor_service_method_wait_for_termination + # + # Block until executor shutdown is complete or until `timeout` seconds have + # passed. + # + # @note Does not initiate shutdown or termination. Either `shutdown` or `kill` + # must be called before this method (or on another thread). + # + # @param [Integer] timeout the maximum number of seconds to wait for shutdown to complete + # + # @return [Boolean] `true` if shutdown complete or false on `timeout` + + # @!macro executor_service_method_running_question + # + # Is the executor running? + # + # @return [Boolean] `true` when running, `false` when shutting down or shutdown + + # @!macro executor_service_method_shuttingdown_question + # + # Is the executor shuttingdown? + # + # @return [Boolean] `true` when not running and not shutdown, else `false` + + # @!macro executor_service_method_shutdown_question + # + # Is the executor shutdown? + # + # @return [Boolean] `true` when shutdown, `false` when shutting down or running + + # @!macro executor_service_method_auto_terminate_question + # + # Is the executor auto-terminate when the application exits? + # + # @return [Boolean] `true` when auto-termination is enabled else `false`. + + # @!macro executor_service_method_auto_terminate_setter + # + # + # Set the auto-terminate behavior for this executor. + # @deprecated Has no effect + # @param [Boolean] value The new auto-terminate value to set for this executor. + # @return [Boolean] `true` when auto-termination is enabled else `false`. + + ################################################################### + + # @!macro abstract_executor_service_public_api + # + # @!macro executor_service_public_api + # + # @!attribute [r] fallback_policy + # @!macro executor_service_attr_reader_fallback_policy + # + # @!method shutdown + # @!macro executor_service_method_shutdown + # + # @!method kill + # @!macro executor_service_method_kill + # + # @!method wait_for_termination(timeout = nil) + # @!macro executor_service_method_wait_for_termination + # + # @!method running? + # @!macro executor_service_method_running_question + # + # @!method shuttingdown? + # @!macro executor_service_method_shuttingdown_question + # + # @!method shutdown? + # @!macro executor_service_method_shutdown_question + # + # @!method auto_terminate? + # @!macro executor_service_method_auto_terminate_question + # + # @!method auto_terminate=(value) + # @!macro executor_service_method_auto_terminate_setter + + ################################################################### + + # @!macro executor_service_public_api + # @!visibility private + module ExecutorService + include Concern::Logging + + # @!macro executor_service_method_post + def post(*args, &task) + raise NotImplementedError + end + + # @!macro executor_service_method_left_shift + def <<(task) + post(&task) + self + end + + # @!macro executor_service_method_can_overflow_question + # + # @note Always returns `false` + def can_overflow? + false + end + + # @!macro executor_service_method_serialized_question + # + # @note Always returns `false` + def serialized? + false + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/fixed_thread_pool.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/fixed_thread_pool.rb new file mode 100644 index 00000000..8324c067 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/fixed_thread_pool.rb @@ -0,0 +1,224 @@ +require 'concurrent/utility/engine' +require 'concurrent/executor/thread_pool_executor' + +module Concurrent + + # @!macro thread_pool_executor_constant_default_max_pool_size + # Default maximum number of threads that will be created in the pool. + + # @!macro thread_pool_executor_constant_default_min_pool_size + # Default minimum number of threads that will be retained in the pool. + + # @!macro thread_pool_executor_constant_default_max_queue_size + # Default maximum number of tasks that may be added to the task queue. + + # @!macro thread_pool_executor_constant_default_thread_timeout + # Default maximum number of seconds a thread in the pool may remain idle + # before being reclaimed. + + # @!macro thread_pool_executor_constant_default_synchronous + # Default value of the :synchronous option. + + # @!macro thread_pool_executor_attr_reader_max_length + # The maximum number of threads that may be created in the pool. + # @return [Integer] The maximum number of threads that may be created in the pool. + + # @!macro thread_pool_executor_attr_reader_min_length + # The minimum number of threads that may be retained in the pool. + # @return [Integer] The minimum number of threads that may be retained in the pool. + + # @!macro thread_pool_executor_attr_reader_largest_length + # The largest number of threads that have been created in the pool since construction. + # @return [Integer] The largest number of threads that have been created in the pool since construction. + + # @!macro thread_pool_executor_attr_reader_scheduled_task_count + # The number of tasks that have been scheduled for execution on the pool since construction. + # @return [Integer] The number of tasks that have been scheduled for execution on the pool since construction. + + # @!macro thread_pool_executor_attr_reader_completed_task_count + # The number of tasks that have been completed by the pool since construction. + # @return [Integer] The number of tasks that have been completed by the pool since construction. + + # @!macro thread_pool_executor_method_active_count + # The number of threads that are actively executing tasks. + # @return [Integer] The number of threads that are actively executing tasks. + + # @!macro thread_pool_executor_attr_reader_idletime + # The number of seconds that a thread may be idle before being reclaimed. + # @return [Integer] The number of seconds that a thread may be idle before being reclaimed. + + # @!macro thread_pool_executor_attr_reader_synchronous + # Whether or not a value of 0 for :max_queue option means the queue must perform direct hand-off or rather unbounded queue. + # @return [true, false] + + # @!macro thread_pool_executor_attr_reader_max_queue + # The maximum number of tasks that may be waiting in the work queue at any one time. + # When the queue size reaches `max_queue` subsequent tasks will be rejected in + # accordance with the configured `fallback_policy`. + # + # @return [Integer] The maximum number of tasks that may be waiting in the work queue at any one time. + # When the queue size reaches `max_queue` subsequent tasks will be rejected in + # accordance with the configured `fallback_policy`. + + # @!macro thread_pool_executor_attr_reader_length + # The number of threads currently in the pool. + # @return [Integer] The number of threads currently in the pool. + + # @!macro thread_pool_executor_attr_reader_queue_length + # The number of tasks in the queue awaiting execution. + # @return [Integer] The number of tasks in the queue awaiting execution. + + # @!macro thread_pool_executor_attr_reader_remaining_capacity + # Number of tasks that may be enqueued before reaching `max_queue` and rejecting + # new tasks. A value of -1 indicates that the queue may grow without bound. + # + # @return [Integer] Number of tasks that may be enqueued before reaching `max_queue` and rejecting + # new tasks. A value of -1 indicates that the queue may grow without bound. + + # @!macro thread_pool_executor_method_prune_pool + # Prune the thread pool of unneeded threads + # + # What is being pruned is controlled by the min_threads and idletime + # parameters passed at pool creation time + # + # This is a no-op on some pool implementation (e.g. the Java one). The Ruby + # pool will auto-prune each time a new job is posted. You will need to call + # this method explicitly in case your application post jobs in bursts (a + # lot of jobs and then nothing for long periods) + + # @!macro thread_pool_executor_public_api + # + # @!macro abstract_executor_service_public_api + # + # @!attribute [r] max_length + # @!macro thread_pool_executor_attr_reader_max_length + # + # @!attribute [r] min_length + # @!macro thread_pool_executor_attr_reader_min_length + # + # @!attribute [r] largest_length + # @!macro thread_pool_executor_attr_reader_largest_length + # + # @!attribute [r] scheduled_task_count + # @!macro thread_pool_executor_attr_reader_scheduled_task_count + # + # @!attribute [r] completed_task_count + # @!macro thread_pool_executor_attr_reader_completed_task_count + # + # @!attribute [r] idletime + # @!macro thread_pool_executor_attr_reader_idletime + # + # @!attribute [r] max_queue + # @!macro thread_pool_executor_attr_reader_max_queue + # + # @!attribute [r] length + # @!macro thread_pool_executor_attr_reader_length + # + # @!attribute [r] queue_length + # @!macro thread_pool_executor_attr_reader_queue_length + # + # @!attribute [r] remaining_capacity + # @!macro thread_pool_executor_attr_reader_remaining_capacity + # + # @!method can_overflow? + # @!macro executor_service_method_can_overflow_question + # + # @!method prune_pool + # @!macro thread_pool_executor_method_prune_pool + + + + + # @!macro thread_pool_options + # + # **Thread Pool Options** + # + # Thread pools support several configuration options: + # + # * `idletime`: The number of seconds that a thread may be idle before being reclaimed. + # * `name`: The name of the executor (optional). Printed in the executor's `#to_s` output and + # a `-worker-` name is given to its threads if supported by used Ruby + # implementation. `` is uniq for each thread. + # * `max_queue`: The maximum number of tasks that may be waiting in the work queue at + # any one time. When the queue size reaches `max_queue` and no new threads can be created, + # subsequent tasks will be rejected in accordance with the configured `fallback_policy`. + # * `auto_terminate`: When true (default), the threads started will be marked as daemon. + # * `fallback_policy`: The policy defining how rejected tasks are handled. + # + # Three fallback policies are supported: + # + # * `:abort`: Raise a `RejectedExecutionError` exception and discard the task. + # * `:discard`: Discard the task and return false. + # * `:caller_runs`: Execute the task on the calling thread. + # + # **Shutting Down Thread Pools** + # + # Killing a thread pool while tasks are still being processed, either by calling + # the `#kill` method or at application exit, will have unpredictable results. There + # is no way for the thread pool to know what resources are being used by the + # in-progress tasks. When those tasks are killed the impact on those resources + # cannot be predicted. The *best* practice is to explicitly shutdown all thread + # pools using the provided methods: + # + # * Call `#shutdown` to initiate an orderly termination of all in-progress tasks + # * Call `#wait_for_termination` with an appropriate timeout interval an allow + # the orderly shutdown to complete + # * Call `#kill` *only when* the thread pool fails to shutdown in the allotted time + # + # On some runtime platforms (most notably the JVM) the application will not + # exit until all thread pools have been shutdown. To prevent applications from + # "hanging" on exit, all threads can be marked as daemon according to the + # `:auto_terminate` option. + # + # ```ruby + # pool1 = Concurrent::FixedThreadPool.new(5) # threads will be marked as daemon + # pool2 = Concurrent::FixedThreadPool.new(5, auto_terminate: false) # mark threads as non-daemon + # ``` + # + # @note Failure to properly shutdown a thread pool can lead to unpredictable results. + # Please read *Shutting Down Thread Pools* for more information. + # + # @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html Java Tutorials: Thread Pools + # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html Java Executors class + # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html Java ExecutorService interface + # @see https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#setDaemon-boolean- + + + + + + # @!macro fixed_thread_pool + # + # A thread pool that reuses a fixed number of threads operating off an unbounded queue. + # At any point, at most `num_threads` will be active processing tasks. When all threads are busy new + # tasks `#post` to the thread pool are enqueued until a thread becomes available. + # Should a thread crash for any reason the thread will immediately be removed + # from the pool and replaced. + # + # The API and behavior of this class are based on Java's `FixedThreadPool` + # + # @!macro thread_pool_options + class FixedThreadPool < ThreadPoolExecutor + + # @!macro fixed_thread_pool_method_initialize + # + # Create a new thread pool. + # + # @param [Integer] num_threads the number of threads to allocate + # @param [Hash] opts the options defining pool behavior. + # @option opts [Symbol] :fallback_policy (`:abort`) the fallback policy + # + # @raise [ArgumentError] if `num_threads` is less than or equal to zero + # @raise [ArgumentError] if `fallback_policy` is not a known policy + # + # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool-int- + def initialize(num_threads, opts = {}) + raise ArgumentError.new('number of threads must be greater than zero') if num_threads.to_i < 1 + defaults = { max_queue: DEFAULT_MAX_QUEUE_SIZE, + idletime: DEFAULT_THREAD_IDLETIMEOUT } + overrides = { min_threads: num_threads, + max_threads: num_threads } + super(defaults.merge(opts).merge(overrides)) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/immediate_executor.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/immediate_executor.rb new file mode 100644 index 00000000..282df7a0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/immediate_executor.rb @@ -0,0 +1,66 @@ +require 'concurrent/atomic/event' +require 'concurrent/executor/abstract_executor_service' +require 'concurrent/executor/serial_executor_service' + +module Concurrent + + # An executor service which runs all operations on the current thread, + # blocking as necessary. Operations are performed in the order they are + # received and no two operations can be performed simultaneously. + # + # This executor service exists mainly for testing an debugging. When used + # it immediately runs every `#post` operation on the current thread, blocking + # that thread until the operation is complete. This can be very beneficial + # during testing because it makes all operations deterministic. + # + # @note Intended for use primarily in testing and debugging. + class ImmediateExecutor < AbstractExecutorService + include SerialExecutorService + + # Creates a new executor + def initialize + @stopped = Concurrent::Event.new + end + + # @!macro executor_service_method_post + def post(*args, &task) + raise ArgumentError.new('no block given') unless block_given? + return false unless running? + task.call(*args) + true + end + + # @!macro executor_service_method_left_shift + def <<(task) + post(&task) + self + end + + # @!macro executor_service_method_running_question + def running? + ! shutdown? + end + + # @!macro executor_service_method_shuttingdown_question + def shuttingdown? + false + end + + # @!macro executor_service_method_shutdown_question + def shutdown? + @stopped.set? + end + + # @!macro executor_service_method_shutdown + def shutdown + @stopped.set + true + end + alias_method :kill, :shutdown + + # @!macro executor_service_method_wait_for_termination + def wait_for_termination(timeout = nil) + @stopped.wait(timeout) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/indirect_immediate_executor.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/indirect_immediate_executor.rb new file mode 100644 index 00000000..4f9769fa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/indirect_immediate_executor.rb @@ -0,0 +1,44 @@ +require 'concurrent/executor/immediate_executor' +require 'concurrent/executor/simple_executor_service' + +module Concurrent + # An executor service which runs all operations on a new thread, blocking + # until it completes. Operations are performed in the order they are received + # and no two operations can be performed simultaneously. + # + # This executor service exists mainly for testing an debugging. When used it + # immediately runs every `#post` operation on a new thread, blocking the + # current thread until the operation is complete. This is similar to how the + # ImmediateExecutor works, but the operation has the full stack of the new + # thread at its disposal. This can be helpful when the operations will spawn + # more operations on the same executor and so on - such a situation might + # overflow the single stack in case of an ImmediateExecutor, which is + # inconsistent with how it would behave for a threaded executor. + # + # @note Intended for use primarily in testing and debugging. + class IndirectImmediateExecutor < ImmediateExecutor + # Creates a new executor + def initialize + super + @internal_executor = SimpleExecutorService.new + end + + # @!macro executor_service_method_post + def post(*args, &task) + raise ArgumentError.new("no block given") unless block_given? + return false unless running? + + event = Concurrent::Event.new + @internal_executor.post do + begin + task.call(*args) + ensure + event.set + end + end + event.wait + + true + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/java_executor_service.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/java_executor_service.rb new file mode 100644 index 00000000..b2bc69a6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/java_executor_service.rb @@ -0,0 +1,100 @@ +require 'concurrent/utility/engine' + +if Concurrent.on_jruby? + require 'concurrent/errors' + require 'concurrent/executor/abstract_executor_service' + + module Concurrent + + # @!macro abstract_executor_service_public_api + # @!visibility private + class JavaExecutorService < AbstractExecutorService + java_import 'java.lang.Runnable' + + FALLBACK_POLICY_CLASSES = { + abort: java.util.concurrent.ThreadPoolExecutor::AbortPolicy, + discard: java.util.concurrent.ThreadPoolExecutor::DiscardPolicy, + caller_runs: java.util.concurrent.ThreadPoolExecutor::CallerRunsPolicy + }.freeze + private_constant :FALLBACK_POLICY_CLASSES + + def post(*args, &task) + raise ArgumentError.new('no block given') unless block_given? + return fallback_action(*args, &task).call unless running? + @executor.submit Job.new(args, task) + true + rescue Java::JavaUtilConcurrent::RejectedExecutionException + raise RejectedExecutionError + end + + def wait_for_termination(timeout = nil) + if timeout.nil? + ok = @executor.awaitTermination(60, java.util.concurrent.TimeUnit::SECONDS) until ok + true + else + @executor.awaitTermination(1000 * timeout, java.util.concurrent.TimeUnit::MILLISECONDS) + end + end + + def shutdown + synchronize do + @executor.shutdown + nil + end + end + + def kill + synchronize do + @executor.shutdownNow + nil + end + end + + private + + def ns_running? + !(ns_shuttingdown? || ns_shutdown?) + end + + def ns_shuttingdown? + @executor.isShutdown && !@executor.isTerminated + end + + def ns_shutdown? + @executor.isTerminated + end + + class Job + include Runnable + def initialize(args, block) + @args = args + @block = block + end + + def run + @block.call(*@args) + end + end + private_constant :Job + end + + class DaemonThreadFactory + # hide include from YARD + send :include, java.util.concurrent.ThreadFactory + + def initialize(daemonize = true) + @daemonize = daemonize + @java_thread_factory = java.util.concurrent.Executors.defaultThreadFactory + end + + def newThread(runnable) + thread = @java_thread_factory.newThread(runnable) + thread.setDaemon(@daemonize) + return thread + end + end + + private_constant :DaemonThreadFactory + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/java_single_thread_executor.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/java_single_thread_executor.rb new file mode 100644 index 00000000..7aa24f2d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/java_single_thread_executor.rb @@ -0,0 +1,30 @@ +if Concurrent.on_jruby? + + require 'concurrent/executor/java_executor_service' + require 'concurrent/executor/serial_executor_service' + + module Concurrent + + # @!macro single_thread_executor + # @!macro abstract_executor_service_public_api + # @!visibility private + class JavaSingleThreadExecutor < JavaExecutorService + include SerialExecutorService + + # @!macro single_thread_executor_method_initialize + def initialize(opts = {}) + super(opts) + end + + private + + def ns_initialize(opts) + @executor = java.util.concurrent.Executors.newSingleThreadExecutor( + DaemonThreadFactory.new(ns_auto_terminate?) + ) + @fallback_policy = opts.fetch(:fallback_policy, :discard) + raise ArgumentError.new("#{@fallback_policy} is not a valid fallback policy") unless FALLBACK_POLICY_CLASSES.keys.include?(@fallback_policy) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb new file mode 100644 index 00000000..598a5f91 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb @@ -0,0 +1,145 @@ +if Concurrent.on_jruby? + + require 'concurrent/executor/java_executor_service' + + module Concurrent + + # @!macro thread_pool_executor + # @!macro thread_pool_options + # @!visibility private + class JavaThreadPoolExecutor < JavaExecutorService + + # @!macro thread_pool_executor_constant_default_max_pool_size + DEFAULT_MAX_POOL_SIZE = java.lang.Integer::MAX_VALUE # 2147483647 + + # @!macro thread_pool_executor_constant_default_min_pool_size + DEFAULT_MIN_POOL_SIZE = 0 + + # @!macro thread_pool_executor_constant_default_max_queue_size + DEFAULT_MAX_QUEUE_SIZE = 0 + + # @!macro thread_pool_executor_constant_default_thread_timeout + DEFAULT_THREAD_IDLETIMEOUT = 60 + + # @!macro thread_pool_executor_constant_default_synchronous + DEFAULT_SYNCHRONOUS = false + + # @!macro thread_pool_executor_attr_reader_max_length + attr_reader :max_length + + # @!macro thread_pool_executor_attr_reader_max_queue + attr_reader :max_queue + + # @!macro thread_pool_executor_attr_reader_synchronous + attr_reader :synchronous + + # @!macro thread_pool_executor_method_initialize + def initialize(opts = {}) + super(opts) + end + + # @!macro executor_service_method_can_overflow_question + def can_overflow? + @max_queue != 0 + end + + # @!macro thread_pool_executor_attr_reader_min_length + def min_length + @executor.getCorePoolSize + end + + # @!macro thread_pool_executor_attr_reader_max_length + def max_length + @executor.getMaximumPoolSize + end + + # @!macro thread_pool_executor_attr_reader_length + def length + @executor.getPoolSize + end + + # @!macro thread_pool_executor_attr_reader_largest_length + def largest_length + @executor.getLargestPoolSize + end + + # @!macro thread_pool_executor_attr_reader_scheduled_task_count + def scheduled_task_count + @executor.getTaskCount + end + + # @!macro thread_pool_executor_attr_reader_completed_task_count + def completed_task_count + @executor.getCompletedTaskCount + end + + # @!macro thread_pool_executor_method_active_count + def active_count + @executor.getActiveCount + end + + # @!macro thread_pool_executor_attr_reader_idletime + def idletime + @executor.getKeepAliveTime(java.util.concurrent.TimeUnit::SECONDS) + end + + # @!macro thread_pool_executor_attr_reader_queue_length + def queue_length + @executor.getQueue.size + end + + # @!macro thread_pool_executor_attr_reader_remaining_capacity + def remaining_capacity + @max_queue == 0 ? -1 : @executor.getQueue.remainingCapacity + end + + # @!macro executor_service_method_running_question + def running? + super && !@executor.isTerminating + end + + # @!macro thread_pool_executor_method_prune_pool + def prune_pool + end + + private + + def ns_initialize(opts) + min_length = opts.fetch(:min_threads, DEFAULT_MIN_POOL_SIZE).to_i + max_length = opts.fetch(:max_threads, DEFAULT_MAX_POOL_SIZE).to_i + idletime = opts.fetch(:idletime, DEFAULT_THREAD_IDLETIMEOUT).to_i + @max_queue = opts.fetch(:max_queue, DEFAULT_MAX_QUEUE_SIZE).to_i + @synchronous = opts.fetch(:synchronous, DEFAULT_SYNCHRONOUS) + @fallback_policy = opts.fetch(:fallback_policy, :abort) + + raise ArgumentError.new("`synchronous` cannot be set unless `max_queue` is 0") if @synchronous && @max_queue > 0 + raise ArgumentError.new("`max_threads` cannot be less than #{DEFAULT_MIN_POOL_SIZE}") if max_length < DEFAULT_MIN_POOL_SIZE + raise ArgumentError.new("`max_threads` cannot be greater than #{DEFAULT_MAX_POOL_SIZE}") if max_length > DEFAULT_MAX_POOL_SIZE + raise ArgumentError.new("`min_threads` cannot be less than #{DEFAULT_MIN_POOL_SIZE}") if min_length < DEFAULT_MIN_POOL_SIZE + raise ArgumentError.new("`min_threads` cannot be more than `max_threads`") if min_length > max_length + raise ArgumentError.new("#{fallback_policy} is not a valid fallback policy") unless FALLBACK_POLICY_CLASSES.include?(@fallback_policy) + + if @max_queue == 0 + if @synchronous + queue = java.util.concurrent.SynchronousQueue.new + else + queue = java.util.concurrent.LinkedBlockingQueue.new + end + else + queue = java.util.concurrent.LinkedBlockingQueue.new(@max_queue) + end + + @executor = java.util.concurrent.ThreadPoolExecutor.new( + min_length, + max_length, + idletime, + java.util.concurrent.TimeUnit::SECONDS, + queue, + DaemonThreadFactory.new(ns_auto_terminate?), + FALLBACK_POLICY_CLASSES[@fallback_policy].new) + + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/ruby_executor_service.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/ruby_executor_service.rb new file mode 100644 index 00000000..1f7301b9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/ruby_executor_service.rb @@ -0,0 +1,82 @@ +require 'concurrent/executor/abstract_executor_service' +require 'concurrent/atomic/event' + +module Concurrent + + # @!macro abstract_executor_service_public_api + # @!visibility private + class RubyExecutorService < AbstractExecutorService + safe_initialization! + + def initialize(*args, &block) + super + @StopEvent = Event.new + @StoppedEvent = Event.new + end + + def post(*args, &task) + raise ArgumentError.new('no block given') unless block_given? + deferred_action = synchronize { + if running? + ns_execute(*args, &task) + else + fallback_action(*args, &task) + end + } + if deferred_action + deferred_action.call + else + true + end + end + + def shutdown + synchronize do + break unless running? + stop_event.set + ns_shutdown_execution + end + true + end + + def kill + synchronize do + break if shutdown? + stop_event.set + ns_kill_execution + stopped_event.set + end + true + end + + def wait_for_termination(timeout = nil) + stopped_event.wait(timeout) + end + + private + + def stop_event + @StopEvent + end + + def stopped_event + @StoppedEvent + end + + def ns_shutdown_execution + stopped_event.set + end + + def ns_running? + !stop_event.set? + end + + def ns_shuttingdown? + !(ns_running? || ns_shutdown?) + end + + def ns_shutdown? + stopped_event.set? + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/ruby_single_thread_executor.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/ruby_single_thread_executor.rb new file mode 100644 index 00000000..916337d4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/ruby_single_thread_executor.rb @@ -0,0 +1,21 @@ +require 'concurrent/executor/ruby_thread_pool_executor' + +module Concurrent + + # @!macro single_thread_executor + # @!macro abstract_executor_service_public_api + # @!visibility private + class RubySingleThreadExecutor < RubyThreadPoolExecutor + + # @!macro single_thread_executor_method_initialize + def initialize(opts = {}) + super( + min_threads: 1, + max_threads: 1, + max_queue: 0, + idletime: DEFAULT_THREAD_IDLETIMEOUT, + fallback_policy: opts.fetch(:fallback_policy, :discard), + ) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb new file mode 100644 index 00000000..9375acf3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb @@ -0,0 +1,373 @@ +require 'thread' +require 'concurrent/atomic/event' +require 'concurrent/concern/logging' +require 'concurrent/executor/ruby_executor_service' +require 'concurrent/utility/monotonic_time' + +module Concurrent + + # @!macro thread_pool_executor + # @!macro thread_pool_options + # @!visibility private + class RubyThreadPoolExecutor < RubyExecutorService + + # @!macro thread_pool_executor_constant_default_max_pool_size + DEFAULT_MAX_POOL_SIZE = 2_147_483_647 # java.lang.Integer::MAX_VALUE + + # @!macro thread_pool_executor_constant_default_min_pool_size + DEFAULT_MIN_POOL_SIZE = 0 + + # @!macro thread_pool_executor_constant_default_max_queue_size + DEFAULT_MAX_QUEUE_SIZE = 0 + + # @!macro thread_pool_executor_constant_default_thread_timeout + DEFAULT_THREAD_IDLETIMEOUT = 60 + + # @!macro thread_pool_executor_constant_default_synchronous + DEFAULT_SYNCHRONOUS = false + + # @!macro thread_pool_executor_attr_reader_max_length + attr_reader :max_length + + # @!macro thread_pool_executor_attr_reader_min_length + attr_reader :min_length + + # @!macro thread_pool_executor_attr_reader_idletime + attr_reader :idletime + + # @!macro thread_pool_executor_attr_reader_max_queue + attr_reader :max_queue + + # @!macro thread_pool_executor_attr_reader_synchronous + attr_reader :synchronous + + # @!macro thread_pool_executor_method_initialize + def initialize(opts = {}) + super(opts) + end + + # @!macro thread_pool_executor_attr_reader_largest_length + def largest_length + synchronize { @largest_length } + end + + # @!macro thread_pool_executor_attr_reader_scheduled_task_count + def scheduled_task_count + synchronize { @scheduled_task_count } + end + + # @!macro thread_pool_executor_attr_reader_completed_task_count + def completed_task_count + synchronize { @completed_task_count } + end + + # @!macro thread_pool_executor_method_active_count + def active_count + synchronize do + @pool.length - @ready.length + end + end + + # @!macro executor_service_method_can_overflow_question + def can_overflow? + synchronize { ns_limited_queue? } + end + + # @!macro thread_pool_executor_attr_reader_length + def length + synchronize { @pool.length } + end + + # @!macro thread_pool_executor_attr_reader_queue_length + def queue_length + synchronize { @queue.length } + end + + # @!macro thread_pool_executor_attr_reader_remaining_capacity + def remaining_capacity + synchronize do + if ns_limited_queue? + @max_queue - @queue.length + else + -1 + end + end + end + + # @!visibility private + def remove_busy_worker(worker) + synchronize { ns_remove_busy_worker worker } + end + + # @!visibility private + def ready_worker(worker, last_message) + synchronize { ns_ready_worker worker, last_message } + end + + # @!visibility private + def worker_died(worker) + synchronize { ns_worker_died worker } + end + + # @!visibility private + def worker_task_completed + synchronize { @completed_task_count += 1 } + end + + # @!macro thread_pool_executor_method_prune_pool + def prune_pool + synchronize { ns_prune_pool } + end + + private + + # @!visibility private + def ns_initialize(opts) + @min_length = opts.fetch(:min_threads, DEFAULT_MIN_POOL_SIZE).to_i + @max_length = opts.fetch(:max_threads, DEFAULT_MAX_POOL_SIZE).to_i + @idletime = opts.fetch(:idletime, DEFAULT_THREAD_IDLETIMEOUT).to_i + @max_queue = opts.fetch(:max_queue, DEFAULT_MAX_QUEUE_SIZE).to_i + @synchronous = opts.fetch(:synchronous, DEFAULT_SYNCHRONOUS) + @fallback_policy = opts.fetch(:fallback_policy, :abort) + + raise ArgumentError.new("`synchronous` cannot be set unless `max_queue` is 0") if @synchronous && @max_queue > 0 + raise ArgumentError.new("#{@fallback_policy} is not a valid fallback policy") unless FALLBACK_POLICIES.include?(@fallback_policy) + raise ArgumentError.new("`max_threads` cannot be less than #{DEFAULT_MIN_POOL_SIZE}") if @max_length < DEFAULT_MIN_POOL_SIZE + raise ArgumentError.new("`max_threads` cannot be greater than #{DEFAULT_MAX_POOL_SIZE}") if @max_length > DEFAULT_MAX_POOL_SIZE + raise ArgumentError.new("`min_threads` cannot be less than #{DEFAULT_MIN_POOL_SIZE}") if @min_length < DEFAULT_MIN_POOL_SIZE + raise ArgumentError.new("`min_threads` cannot be more than `max_threads`") if min_length > max_length + + @pool = [] # all workers + @ready = [] # used as a stash (most idle worker is at the start) + @queue = [] # used as queue + # @ready or @queue is empty at all times + @scheduled_task_count = 0 + @completed_task_count = 0 + @largest_length = 0 + @workers_counter = 0 + @ruby_pid = $$ # detects if Ruby has forked + + @gc_interval = opts.fetch(:gc_interval, @idletime / 2.0).to_i # undocumented + @next_gc_time = Concurrent.monotonic_time + @gc_interval + end + + # @!visibility private + def ns_limited_queue? + @max_queue != 0 + end + + # @!visibility private + def ns_execute(*args, &task) + ns_reset_if_forked + + if ns_assign_worker(*args, &task) || ns_enqueue(*args, &task) + @scheduled_task_count += 1 + else + return fallback_action(*args, &task) + end + + ns_prune_pool if @next_gc_time < Concurrent.monotonic_time + nil + end + + # @!visibility private + def ns_shutdown_execution + ns_reset_if_forked + + if @pool.empty? + # nothing to do + stopped_event.set + end + + if @queue.empty? + # no more tasks will be accepted, just stop all workers + @pool.each(&:stop) + end + end + + # @!visibility private + def ns_kill_execution + # TODO log out unprocessed tasks in queue + # TODO try to shutdown first? + @pool.each(&:kill) + @pool.clear + @ready.clear + end + + # tries to assign task to a worker, tries to get one from @ready or to create new one + # @return [true, false] if task is assigned to a worker + # + # @!visibility private + def ns_assign_worker(*args, &task) + # keep growing if the pool is not at the minimum yet + worker, _ = (@ready.pop if @pool.size >= @min_length) || ns_add_busy_worker + if worker + worker << [task, args] + true + else + false + end + rescue ThreadError + # Raised when the operating system refuses to create the new thread + return false + end + + # tries to enqueue task + # @return [true, false] if enqueued + # + # @!visibility private + def ns_enqueue(*args, &task) + return false if @synchronous + + if !ns_limited_queue? || @queue.size < @max_queue + @queue << [task, args] + true + else + false + end + end + + # @!visibility private + def ns_worker_died(worker) + ns_remove_busy_worker worker + replacement_worker = ns_add_busy_worker + ns_ready_worker replacement_worker, Concurrent.monotonic_time, false if replacement_worker + end + + # creates new worker which has to receive work to do after it's added + # @return [nil, Worker] nil of max capacity is reached + # + # @!visibility private + def ns_add_busy_worker + return if @pool.size >= @max_length + + @workers_counter += 1 + @pool << (worker = Worker.new(self, @workers_counter)) + @largest_length = @pool.length if @pool.length > @largest_length + worker + end + + # handle ready worker, giving it new job or assigning back to @ready + # + # @!visibility private + def ns_ready_worker(worker, last_message, success = true) + task_and_args = @queue.shift + if task_and_args + worker << task_and_args + else + # stop workers when !running?, do not return them to @ready + if running? + raise unless last_message + @ready.push([worker, last_message]) + else + worker.stop + end + end + end + + # removes a worker which is not in not tracked in @ready + # + # @!visibility private + def ns_remove_busy_worker(worker) + @pool.delete(worker) + stopped_event.set if @pool.empty? && !running? + true + end + + # try oldest worker if it is idle for enough time, it's returned back at the start + # + # @!visibility private + def ns_prune_pool + now = Concurrent.monotonic_time + stopped_workers = 0 + while !@ready.empty? && (@pool.size - stopped_workers > @min_length) + worker, last_message = @ready.first + if now - last_message > self.idletime + stopped_workers += 1 + @ready.shift + worker << :stop + else break + end + end + + @next_gc_time = Concurrent.monotonic_time + @gc_interval + end + + def ns_reset_if_forked + if $$ != @ruby_pid + @queue.clear + @ready.clear + @pool.clear + @scheduled_task_count = 0 + @completed_task_count = 0 + @largest_length = 0 + @workers_counter = 0 + @ruby_pid = $$ + end + end + + # @!visibility private + class Worker + include Concern::Logging + + def initialize(pool, id) + # instance variables accessed only under pool's lock so no need to sync here again + @queue = Queue.new + @pool = pool + @thread = create_worker @queue, pool, pool.idletime + + if @thread.respond_to?(:name=) + @thread.name = [pool.name, 'worker', id].compact.join('-') + end + end + + def <<(message) + @queue << message + end + + def stop + @queue << :stop + end + + def kill + @thread.kill + end + + private + + def create_worker(queue, pool, idletime) + Thread.new(queue, pool, idletime) do |my_queue, my_pool, my_idletime| + catch(:stop) do + loop do + + case message = my_queue.pop + when :stop + my_pool.remove_busy_worker(self) + throw :stop + + else + task, args = message + run_task my_pool, task, args + my_pool.ready_worker(self, Concurrent.monotonic_time) + end + end + end + end + end + + def run_task(pool, task, args) + task.call(*args) + pool.worker_task_completed + rescue => ex + # let it fail + log DEBUG, ex + rescue Exception => ex + log ERROR, ex + pool.worker_died(self) + throw :stop + end + end + + private_constant :Worker + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb new file mode 100644 index 00000000..f796b857 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/safe_task_executor.rb @@ -0,0 +1,35 @@ +require 'concurrent/synchronization/lockable_object' + +module Concurrent + + # A simple utility class that executes a callable and returns and array of three elements: + # success - indicating if the callable has been executed without errors + # value - filled by the callable result if it has been executed without errors, nil otherwise + # reason - the error risen by the callable if it has been executed with errors, nil otherwise + class SafeTaskExecutor < Synchronization::LockableObject + + def initialize(task, opts = {}) + @task = task + @exception_class = opts.fetch(:rescue_exception, false) ? Exception : StandardError + super() # ensures visibility + end + + # @return [Array] + def execute(*args) + success = true + value = reason = nil + + synchronize do + begin + value = @task.call(*args) + success = true + rescue @exception_class => ex + reason = ex + success = false + end + end + + [success, value, reason] + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/serial_executor_service.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/serial_executor_service.rb new file mode 100644 index 00000000..f1c38ecf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/serial_executor_service.rb @@ -0,0 +1,34 @@ +require 'concurrent/executor/executor_service' + +module Concurrent + + # Indicates that the including `ExecutorService` guarantees + # that all operations will occur in the order they are post and that no + # two operations may occur simultaneously. This module provides no + # functionality and provides no guarantees. That is the responsibility + # of the including class. This module exists solely to allow the including + # object to be interrogated for its serialization status. + # + # @example + # class Foo + # include Concurrent::SerialExecutor + # end + # + # foo = Foo.new + # + # foo.is_a? Concurrent::ExecutorService #=> true + # foo.is_a? Concurrent::SerialExecutor #=> true + # foo.serialized? #=> true + # + # @!visibility private + module SerialExecutorService + include ExecutorService + + # @!macro executor_service_method_serialized_question + # + # @note Always returns `true` + def serialized? + true + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/serialized_execution.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/serialized_execution.rb new file mode 100644 index 00000000..4db7c7f0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/serialized_execution.rb @@ -0,0 +1,107 @@ +require 'concurrent/errors' +require 'concurrent/concern/logging' +require 'concurrent/synchronization/lockable_object' + +module Concurrent + + # Ensures passed jobs in a serialized order never running at the same time. + class SerializedExecution < Synchronization::LockableObject + include Concern::Logging + + def initialize() + super() + synchronize { ns_initialize } + end + + Job = Struct.new(:executor, :args, :block) do + def call + block.call(*args) + end + end + + # Submit a task to the executor for asynchronous processing. + # + # @param [Executor] executor to be used for this job + # + # @param [Array] args zero or more arguments to be passed to the task + # + # @yield the asynchronous task to perform + # + # @return [Boolean] `true` if the task is queued, `false` if the executor + # is not running + # + # @raise [ArgumentError] if no task is given + def post(executor, *args, &task) + posts [[executor, args, task]] + true + end + + # As {#post} but allows to submit multiple tasks at once, it's guaranteed that they will not + # be interleaved by other tasks. + # + # @param [Array, Proc)>] posts array of triplets where + # first is a {ExecutorService}, second is array of args for task, third is a task (Proc) + def posts(posts) + # if can_overflow? + # raise ArgumentError, 'SerializedExecution does not support thread-pools which can overflow' + # end + + return nil if posts.empty? + + jobs = posts.map { |executor, args, task| Job.new executor, args, task } + + job_to_post = synchronize do + if @being_executed + @stash.push(*jobs) + nil + else + @being_executed = true + @stash.push(*jobs[1..-1]) + jobs.first + end + end + + call_job job_to_post if job_to_post + true + end + + private + + def ns_initialize + @being_executed = false + @stash = [] + end + + def call_job(job) + did_it_run = begin + job.executor.post { work(job) } + true + rescue RejectedExecutionError => ex + false + end + + # TODO not the best idea to run it myself + unless did_it_run + begin + work job + rescue => ex + # let it fail + log DEBUG, ex + end + end + end + + # ensures next job is executed if any is stashed + def work(job) + job.call + ensure + synchronize do + job = @stash.shift || (@being_executed = false) + end + + # TODO maybe be able to tell caching pool to just enqueue this job, because the current one end at the end + # of this block + call_job job if job + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/serialized_execution_delegator.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/serialized_execution_delegator.rb new file mode 100644 index 00000000..8197781b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/serialized_execution_delegator.rb @@ -0,0 +1,28 @@ +require 'delegate' +require 'concurrent/executor/serial_executor_service' +require 'concurrent/executor/serialized_execution' + +module Concurrent + + # A wrapper/delegator for any `ExecutorService` that + # guarantees serialized execution of tasks. + # + # @see [SimpleDelegator](http://www.ruby-doc.org/stdlib-2.1.2/libdoc/delegate/rdoc/SimpleDelegator.html) + # @see Concurrent::SerializedExecution + class SerializedExecutionDelegator < SimpleDelegator + include SerialExecutorService + + def initialize(executor) + @executor = executor + @serializer = SerializedExecution.new + super(executor) + end + + # @!macro executor_service_method_post + def post(*args, &task) + raise ArgumentError.new('no block given') unless block_given? + return false unless running? + @serializer.post(@executor, *args, &task) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb new file mode 100644 index 00000000..0bc62afd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/simple_executor_service.rb @@ -0,0 +1,103 @@ +require 'concurrent/atomic/atomic_boolean' +require 'concurrent/atomic/atomic_fixnum' +require 'concurrent/atomic/event' +require 'concurrent/executor/executor_service' +require 'concurrent/executor/ruby_executor_service' + +module Concurrent + + # An executor service in which every operation spawns a new, + # independently operating thread. + # + # This is perhaps the most inefficient executor service in this + # library. It exists mainly for testing an debugging. Thread creation + # and management is expensive in Ruby and this executor performs no + # resource pooling. This can be very beneficial during testing and + # debugging because it decouples the using code from the underlying + # executor implementation. In production this executor will likely + # lead to suboptimal performance. + # + # @note Intended for use primarily in testing and debugging. + class SimpleExecutorService < RubyExecutorService + + # @!macro executor_service_method_post + def self.post(*args) + raise ArgumentError.new('no block given') unless block_given? + Thread.new(*args) do + Thread.current.abort_on_exception = false + yield(*args) + end + true + end + + # @!macro executor_service_method_left_shift + def self.<<(task) + post(&task) + self + end + + # @!macro executor_service_method_post + def post(*args, &task) + raise ArgumentError.new('no block given') unless block_given? + return false unless running? + @count.increment + Thread.new(*args) do + Thread.current.abort_on_exception = false + begin + yield(*args) + ensure + @count.decrement + @stopped.set if @running.false? && @count.value == 0 + end + end + end + + # @!macro executor_service_method_left_shift + def <<(task) + post(&task) + self + end + + # @!macro executor_service_method_running_question + def running? + @running.true? + end + + # @!macro executor_service_method_shuttingdown_question + def shuttingdown? + @running.false? && ! @stopped.set? + end + + # @!macro executor_service_method_shutdown_question + def shutdown? + @stopped.set? + end + + # @!macro executor_service_method_shutdown + def shutdown + @running.make_false + @stopped.set if @count.value == 0 + true + end + + # @!macro executor_service_method_kill + def kill + @running.make_false + @stopped.set + true + end + + # @!macro executor_service_method_wait_for_termination + def wait_for_termination(timeout = nil) + @stopped.wait(timeout) + end + + private + + def ns_initialize(*args) + @running = Concurrent::AtomicBoolean.new(true) + @stopped = Concurrent::Event.new + @count = Concurrent::AtomicFixnum.new(0) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb new file mode 100644 index 00000000..220eb0ff --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/single_thread_executor.rb @@ -0,0 +1,57 @@ +require 'concurrent/utility/engine' +require 'concurrent/executor/ruby_single_thread_executor' + +module Concurrent + + if Concurrent.on_jruby? + require 'concurrent/executor/java_single_thread_executor' + end + + SingleThreadExecutorImplementation = case + when Concurrent.on_jruby? + JavaSingleThreadExecutor + else + RubySingleThreadExecutor + end + private_constant :SingleThreadExecutorImplementation + + # @!macro single_thread_executor + # + # A thread pool with a single thread an unlimited queue. Should the thread + # die for any reason it will be removed and replaced, thus ensuring that + # the executor will always remain viable and available to process jobs. + # + # A common pattern for background processing is to create a single thread + # on which an infinite loop is run. The thread's loop blocks on an input + # source (perhaps blocking I/O or a queue) and processes each input as it + # is received. This pattern has several issues. The thread itself is highly + # susceptible to errors during processing. Also, the thread itself must be + # constantly monitored and restarted should it die. `SingleThreadExecutor` + # encapsulates all these behaviors. The task processor is highly resilient + # to errors from within tasks. Also, should the thread die it will + # automatically be restarted. + # + # The API and behavior of this class are based on Java's `SingleThreadExecutor`. + # + # @!macro abstract_executor_service_public_api + class SingleThreadExecutor < SingleThreadExecutorImplementation + + # @!macro single_thread_executor_method_initialize + # + # Create a new thread pool. + # + # @option opts [Symbol] :fallback_policy (:discard) the policy for handling new + # tasks that are received when the queue size has reached + # `max_queue` or the executor has shut down + # + # @raise [ArgumentError] if `:fallback_policy` is not one of the values specified + # in `FALLBACK_POLICIES` + # + # @see http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html + # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html + # @see http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html + + # @!method initialize(opts = {}) + # @!macro single_thread_executor_method_initialize + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb new file mode 100644 index 00000000..253d46a9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/thread_pool_executor.rb @@ -0,0 +1,88 @@ +require 'concurrent/utility/engine' +require 'concurrent/executor/ruby_thread_pool_executor' + +module Concurrent + + if Concurrent.on_jruby? + require 'concurrent/executor/java_thread_pool_executor' + end + + ThreadPoolExecutorImplementation = case + when Concurrent.on_jruby? + JavaThreadPoolExecutor + else + RubyThreadPoolExecutor + end + private_constant :ThreadPoolExecutorImplementation + + # @!macro thread_pool_executor + # + # An abstraction composed of one or more threads and a task queue. Tasks + # (blocks or `proc` objects) are submitted to the pool and added to the queue. + # The threads in the pool remove the tasks and execute them in the order + # they were received. + # + # A `ThreadPoolExecutor` will automatically adjust the pool size according + # to the bounds set by `min-threads` and `max-threads`. When a new task is + # submitted and fewer than `min-threads` threads are running, a new thread + # is created to handle the request, even if other worker threads are idle. + # If there are more than `min-threads` but less than `max-threads` threads + # running, a new thread will be created only if the queue is full. + # + # Threads that are idle for too long will be garbage collected, down to the + # configured minimum options. Should a thread crash it, too, will be garbage collected. + # + # `ThreadPoolExecutor` is based on the Java class of the same name. From + # the official Java documentation; + # + # > Thread pools address two different problems: they usually provide + # > improved performance when executing large numbers of asynchronous tasks, + # > due to reduced per-task invocation overhead, and they provide a means + # > of bounding and managing the resources, including threads, consumed + # > when executing a collection of tasks. Each ThreadPoolExecutor also + # > maintains some basic statistics, such as the number of completed tasks. + # > + # > To be useful across a wide range of contexts, this class provides many + # > adjustable parameters and extensibility hooks. However, programmers are + # > urged to use the more convenient Executors factory methods + # > [CachedThreadPool] (unbounded thread pool, with automatic thread reclamation), + # > [FixedThreadPool] (fixed size thread pool) and [SingleThreadExecutor] (single + # > background thread), that preconfigure settings for the most common usage + # > scenarios. + # + # @!macro thread_pool_options + # + # @!macro thread_pool_executor_public_api + class ThreadPoolExecutor < ThreadPoolExecutorImplementation + + # @!macro thread_pool_executor_method_initialize + # + # Create a new thread pool. + # + # @param [Hash] opts the options which configure the thread pool. + # + # @option opts [Integer] :max_threads (DEFAULT_MAX_POOL_SIZE) the maximum + # number of threads to be created + # @option opts [Integer] :min_threads (DEFAULT_MIN_POOL_SIZE) When a new task is submitted + # and fewer than `min_threads` are running, a new thread is created + # @option opts [Integer] :idletime (DEFAULT_THREAD_IDLETIMEOUT) the maximum + # number of seconds a thread may be idle before being reclaimed + # @option opts [Integer] :max_queue (DEFAULT_MAX_QUEUE_SIZE) the maximum + # number of tasks allowed in the work queue at any one time; a value of + # zero means the queue may grow without bound + # @option opts [Symbol] :fallback_policy (:abort) the policy for handling new + # tasks that are received when the queue size has reached + # `max_queue` or the executor has shut down + # @option opts [Boolean] :synchronous (DEFAULT_SYNCHRONOUS) whether or not a value of 0 + # for :max_queue means the queue must perform direct hand-off rather than unbounded. + # @raise [ArgumentError] if `:max_threads` is less than one + # @raise [ArgumentError] if `:min_threads` is less than zero + # @raise [ArgumentError] if `:fallback_policy` is not one of the values specified + # in `FALLBACK_POLICIES` + # + # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html + + # @!method initialize(opts = {}) + # @!macro thread_pool_executor_method_initialize + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/timer_set.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/timer_set.rb new file mode 100644 index 00000000..759dce09 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executor/timer_set.rb @@ -0,0 +1,176 @@ +require 'concurrent/scheduled_task' +require 'concurrent/atomic/event' +require 'concurrent/collection/non_concurrent_priority_queue' +require 'concurrent/executor/executor_service' +require 'concurrent/executor/single_thread_executor' +require 'concurrent/errors' +require 'concurrent/options' + +module Concurrent + + # Executes a collection of tasks, each after a given delay. A master task + # monitors the set and schedules each task for execution at the appropriate + # time. Tasks are run on the global thread pool or on the supplied executor. + # Each task is represented as a `ScheduledTask`. + # + # @see Concurrent::ScheduledTask + # + # @!macro monotonic_clock_warning + class TimerSet < RubyExecutorService + + # Create a new set of timed tasks. + # + # @!macro executor_options + # + # @param [Hash] opts the options used to specify the executor on which to perform actions + # @option opts [Executor] :executor when set use the given `Executor` instance. + # Three special values are also supported: `:task` returns the global task pool, + # `:operation` returns the global operation pool, and `:immediate` returns a new + # `ImmediateExecutor` object. + def initialize(opts = {}) + super(opts) + end + + # Post a task to be execute run after a given delay (in seconds). If the + # delay is less than 1/100th of a second the task will be immediately post + # to the executor. + # + # @param [Float] delay the number of seconds to wait for before executing the task. + # @param [Array] args the arguments passed to the task on execution. + # + # @yield the task to be performed. + # + # @return [Concurrent::ScheduledTask, false] IVar representing the task if the post + # is successful; false after shutdown. + # + # @raise [ArgumentError] if the intended execution time is not in the future. + # @raise [ArgumentError] if no block is given. + def post(delay, *args, &task) + raise ArgumentError.new('no block given') unless block_given? + return false unless running? + opts = { executor: @task_executor, + args: args, + timer_set: self } + task = ScheduledTask.execute(delay, opts, &task) # may raise exception + task.unscheduled? ? false : task + end + + # Begin an immediate shutdown. In-progress tasks will be allowed to + # complete but enqueued tasks will be dismissed and no new tasks + # will be accepted. Has no additional effect if the thread pool is + # not running. + def kill + shutdown + end + + private :<< + + private + + # Initialize the object. + # + # @param [Hash] opts the options to create the object with. + # @!visibility private + def ns_initialize(opts) + @queue = Collection::NonConcurrentPriorityQueue.new(order: :min) + @task_executor = Options.executor_from_options(opts) || Concurrent.global_io_executor + @timer_executor = SingleThreadExecutor.new + @condition = Event.new + @ruby_pid = $$ # detects if Ruby has forked + end + + # Post the task to the internal queue. + # + # @note This is intended as a callback method from ScheduledTask + # only. It is not intended to be used directly. Post a task + # by using the `SchedulesTask#execute` method. + # + # @!visibility private + def post_task(task) + synchronize { ns_post_task(task) } + end + + # @!visibility private + def ns_post_task(task) + return false unless ns_running? + ns_reset_if_forked + if (task.initial_delay) <= 0.01 + task.executor.post { task.process_task } + else + @queue.push(task) + # only post the process method when the queue is empty + @timer_executor.post(&method(:process_tasks)) if @queue.length == 1 + @condition.set + end + true + end + + # Remove the given task from the queue. + # + # @note This is intended as a callback method from `ScheduledTask` + # only. It is not intended to be used directly. Cancel a task + # by using the `ScheduledTask#cancel` method. + # + # @!visibility private + def remove_task(task) + synchronize { @queue.delete(task) } + end + + # `ExecutorService` callback called during shutdown. + # + # @!visibility private + def ns_shutdown_execution + ns_reset_if_forked + @queue.clear + @timer_executor.kill + stopped_event.set + end + + def ns_reset_if_forked + if $$ != @ruby_pid + @queue.clear + @condition.reset + @ruby_pid = $$ + end + end + + # Run a loop and execute tasks in the scheduled order and at the approximate + # scheduled time. If no tasks remain the thread will exit gracefully so that + # garbage collection can occur. If there are no ready tasks it will sleep + # for up to 60 seconds waiting for the next scheduled task. + # + # @!visibility private + def process_tasks + loop do + task = synchronize { @condition.reset; @queue.peek } + break unless task + + now = Concurrent.monotonic_time + diff = task.schedule_time - now + + if diff <= 0 + # We need to remove the task from the queue before passing + # it to the executor, to avoid race conditions where we pass + # the peek'ed task to the executor and then pop a different + # one that's been added in the meantime. + # + # Note that there's no race condition between the peek and + # this pop - this pop could retrieve a different task from + # the peek, but that task would be due to fire now anyway + # (because @queue is a priority queue, and this thread is + # the only reader, so whatever timer is at the head of the + # queue now must have the same pop time, or a closer one, as + # when we peeked). + task = synchronize { @queue.pop } + begin + task.executor.post { task.process_task } + rescue RejectedExecutionError + # ignore and continue + end + else + @condition.wait([diff, 60].min) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executors.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executors.rb new file mode 100644 index 00000000..eb1972ce --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/executors.rb @@ -0,0 +1,20 @@ +require 'concurrent/executor/abstract_executor_service' +require 'concurrent/executor/cached_thread_pool' +require 'concurrent/executor/executor_service' +require 'concurrent/executor/fixed_thread_pool' +require 'concurrent/executor/immediate_executor' +require 'concurrent/executor/indirect_immediate_executor' +require 'concurrent/executor/java_executor_service' +require 'concurrent/executor/java_single_thread_executor' +require 'concurrent/executor/java_thread_pool_executor' +require 'concurrent/executor/ruby_executor_service' +require 'concurrent/executor/ruby_single_thread_executor' +require 'concurrent/executor/ruby_thread_pool_executor' +require 'concurrent/executor/cached_thread_pool' +require 'concurrent/executor/safe_task_executor' +require 'concurrent/executor/serial_executor_service' +require 'concurrent/executor/serialized_execution' +require 'concurrent/executor/serialized_execution_delegator' +require 'concurrent/executor/single_thread_executor' +require 'concurrent/executor/thread_pool_executor' +require 'concurrent/executor/timer_set' diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/future.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/future.rb new file mode 100644 index 00000000..1af182ec --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/future.rb @@ -0,0 +1,141 @@ +require 'thread' +require 'concurrent/constants' +require 'concurrent/errors' +require 'concurrent/ivar' +require 'concurrent/executor/safe_task_executor' + +require 'concurrent/options' + +# TODO (pitr-ch 14-Mar-2017): deprecate, Future, Promise, etc. + + +module Concurrent + + # {include:file:docs-source/future.md} + # + # @!macro copy_options + # + # @see http://ruby-doc.org/stdlib-2.1.1/libdoc/observer/rdoc/Observable.html Ruby Observable module + # @see http://clojuredocs.org/clojure_core/clojure.core/future Clojure's future function + # @see http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html java.util.concurrent.Future + class Future < IVar + + # Create a new `Future` in the `:unscheduled` state. + # + # @yield the asynchronous operation to perform + # + # @!macro executor_and_deref_options + # + # @option opts [object, Array] :args zero or more arguments to be passed the task + # block on execution + # + # @raise [ArgumentError] if no block is given + def initialize(opts = {}, &block) + raise ArgumentError.new('no block given') unless block_given? + super(NULL, opts.merge(__task_from_block__: block), &nil) + end + + # Execute an `:unscheduled` `Future`. Immediately sets the state to `:pending` and + # passes the block to a new thread/thread pool for eventual execution. + # Does nothing if the `Future` is in any state other than `:unscheduled`. + # + # @return [Future] a reference to `self` + # + # @example Instance and execute in separate steps + # future = Concurrent::Future.new{ sleep(1); 42 } + # future.state #=> :unscheduled + # future.execute + # future.state #=> :pending + # + # @example Instance and execute in one line + # future = Concurrent::Future.new{ sleep(1); 42 }.execute + # future.state #=> :pending + def execute + if compare_and_set_state(:pending, :unscheduled) + @executor.post{ safe_execute(@task, @args) } + self + end + end + + # Create a new `Future` object with the given block, execute it, and return the + # `:pending` object. + # + # @yield the asynchronous operation to perform + # + # @!macro executor_and_deref_options + # + # @option opts [object, Array] :args zero or more arguments to be passed the task + # block on execution + # + # @raise [ArgumentError] if no block is given + # + # @return [Future] the newly created `Future` in the `:pending` state + # + # @example + # future = Concurrent::Future.execute{ sleep(1); 42 } + # future.state #=> :pending + def self.execute(opts = {}, &block) + Future.new(opts, &block).execute + end + + # @!macro ivar_set_method + def set(value = NULL, &block) + check_for_block_or_value!(block_given?, value) + synchronize do + if @state != :unscheduled + raise MultipleAssignmentError + else + @task = block || Proc.new { value } + end + end + execute + end + + # Attempt to cancel the operation if it has not already processed. + # The operation can only be cancelled while still `pending`. It cannot + # be cancelled once it has begun processing or has completed. + # + # @return [Boolean] was the operation successfully cancelled. + def cancel + if compare_and_set_state(:cancelled, :pending) + complete(false, nil, CancelledOperationError.new) + true + else + false + end + end + + # Has the operation been successfully cancelled? + # + # @return [Boolean] + def cancelled? + state == :cancelled + end + + # Wait the given number of seconds for the operation to complete. + # On timeout attempt to cancel the operation. + # + # @param [Numeric] timeout the maximum time in seconds to wait. + # @return [Boolean] true if the operation completed before the timeout + # else false + def wait_or_cancel(timeout) + wait(timeout) + if complete? + true + else + cancel + false + end + end + + protected + + def ns_initialize(value, opts) + super + @state = :unscheduled + @task = opts[:__task_from_block__] + @executor = Options.executor_from_options(opts) || Concurrent.global_io_executor + @args = get_arguments_from(opts) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/hash.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/hash.rb new file mode 100644 index 00000000..db0208e0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/hash.rb @@ -0,0 +1,52 @@ +require 'concurrent/utility/engine' +require 'concurrent/thread_safe/util' + +module Concurrent + + # @!macro concurrent_hash + # + # A thread-safe subclass of Hash. This version locks against the object + # itself for every method call, ensuring only one thread can be reading + # or writing at a time. This includes iteration methods like `#each`, + # which takes the lock repeatedly when reading an item. + # + # @see http://ruby-doc.org/core/Hash.html Ruby standard library `Hash` + + # @!macro internal_implementation_note + HashImplementation = case + when Concurrent.on_cruby? + # Hash is not fully thread-safe on CRuby, see + # https://bugs.ruby-lang.org/issues/19237 + # https://github.com/ruby/ruby/commit/ffd52412ab + # https://github.com/ruby-concurrency/concurrent-ruby/issues/929 + # So we will need to add synchronization here (similar to Concurrent::Map). + ::Hash + + when Concurrent.on_jruby? + require 'jruby/synchronized' + + class JRubyHash < ::Hash + include JRuby::Synchronized + end + JRubyHash + + when Concurrent.on_truffleruby? + require 'concurrent/thread_safe/util/data_structures' + + class TruffleRubyHash < ::Hash + end + + ThreadSafe::Util.make_synchronized_on_truffleruby TruffleRubyHash + TruffleRubyHash + + else + warn 'Possibly unsupported Ruby implementation' + ::Hash + end + private_constant :HashImplementation + + # @!macro concurrent_hash + class Hash < HashImplementation + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/immutable_struct.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/immutable_struct.rb new file mode 100644 index 00000000..48462e83 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/immutable_struct.rb @@ -0,0 +1,101 @@ +require 'concurrent/synchronization/abstract_struct' +require 'concurrent/synchronization/lockable_object' + +module Concurrent + + # A thread-safe, immutable variation of Ruby's standard `Struct`. + # + # @see http://ruby-doc.org/core/Struct.html Ruby standard library `Struct` + module ImmutableStruct + include Synchronization::AbstractStruct + + def self.included(base) + base.safe_initialization! + end + + # @!macro struct_values + def values + ns_values + end + + alias_method :to_a, :values + + # @!macro struct_values_at + def values_at(*indexes) + ns_values_at(indexes) + end + + # @!macro struct_inspect + def inspect + ns_inspect + end + + alias_method :to_s, :inspect + + # @!macro struct_merge + def merge(other, &block) + ns_merge(other, &block) + end + + # @!macro struct_to_h + def to_h + ns_to_h + end + + # @!macro struct_get + def [](member) + ns_get(member) + end + + # @!macro struct_equality + def ==(other) + ns_equality(other) + end + + # @!macro struct_each + def each(&block) + return enum_for(:each) unless block_given? + ns_each(&block) + end + + # @!macro struct_each_pair + def each_pair(&block) + return enum_for(:each_pair) unless block_given? + ns_each_pair(&block) + end + + # @!macro struct_select + def select(&block) + return enum_for(:select) unless block_given? + ns_select(&block) + end + + private + + # @!visibility private + def initialize_copy(original) + super(original) + ns_initialize_copy + end + + # @!macro struct_new + def self.new(*args, &block) + clazz_name = nil + if args.length == 0 + raise ArgumentError.new('wrong number of arguments (0 for 1+)') + elsif args.length > 0 && args.first.is_a?(String) + clazz_name = args.shift + end + FACTORY.define_struct(clazz_name, args, &block) + end + + FACTORY = Class.new(Synchronization::LockableObject) do + def define_struct(name, members, &block) + synchronize do + Synchronization::AbstractStruct.define_struct_class(ImmutableStruct, Synchronization::Object, name, members, &block) + end + end + end.new + private_constant :FACTORY + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/ivar.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/ivar.rb new file mode 100644 index 00000000..4165038f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/ivar.rb @@ -0,0 +1,208 @@ +require 'concurrent/constants' +require 'concurrent/errors' +require 'concurrent/collection/copy_on_write_observer_set' +require 'concurrent/concern/obligation' +require 'concurrent/concern/observable' +require 'concurrent/executor/safe_task_executor' +require 'concurrent/synchronization/lockable_object' + +module Concurrent + + # An `IVar` is like a future that you can assign. As a future is a value that + # is being computed that you can wait on, an `IVar` is a value that is waiting + # to be assigned, that you can wait on. `IVars` are single assignment and + # deterministic. + # + # Then, express futures as an asynchronous computation that assigns an `IVar`. + # The `IVar` becomes the primitive on which [futures](Future) and + # [dataflow](Dataflow) are built. + # + # An `IVar` is a single-element container that is normally created empty, and + # can only be set once. The I in `IVar` stands for immutable. Reading an + # `IVar` normally blocks until it is set. It is safe to set and read an `IVar` + # from different threads. + # + # If you want to have some parallel task set the value in an `IVar`, you want + # a `Future`. If you want to create a graph of parallel tasks all executed + # when the values they depend on are ready you want `dataflow`. `IVar` is + # generally a low-level primitive. + # + # ## Examples + # + # Create, set and get an `IVar` + # + # ```ruby + # ivar = Concurrent::IVar.new + # ivar.set 14 + # ivar.value #=> 14 + # ivar.set 2 # would now be an error + # ``` + # + # ## See Also + # + # 1. For the theory: Arvind, R. Nikhil, and K. Pingali. + # [I-Structures: Data structures for parallel computing](http://dl.acm.org/citation.cfm?id=69562). + # In Proceedings of Workshop on Graph Reduction, 1986. + # 2. For recent application: + # [DataDrivenFuture in Habanero Java from Rice](http://www.cs.rice.edu/~vs3/hjlib/doc/edu/rice/hj/api/HjDataDrivenFuture.html). + class IVar < Synchronization::LockableObject + include Concern::Obligation + include Concern::Observable + + # Create a new `IVar` in the `:pending` state with the (optional) initial value. + # + # @param [Object] value the initial value + # @param [Hash] opts the options to create a message with + # @option opts [String] :dup_on_deref (false) call `#dup` before returning + # the data + # @option opts [String] :freeze_on_deref (false) call `#freeze` before + # returning the data + # @option opts [String] :copy_on_deref (nil) call the given `Proc` passing + # the internal value and returning the value returned from the proc + def initialize(value = NULL, opts = {}, &block) + if value != NULL && block_given? + raise ArgumentError.new('provide only a value or a block') + end + super(&nil) + synchronize { ns_initialize(value, opts, &block) } + end + + # Add an observer on this object that will receive notification on update. + # + # Upon completion the `IVar` will notify all observers in a thread-safe way. + # The `func` method of the observer will be called with three arguments: the + # `Time` at which the `Future` completed the asynchronous operation, the + # final `value` (or `nil` on rejection), and the final `reason` (or `nil` on + # fulfillment). + # + # @param [Object] observer the object that will be notified of changes + # @param [Symbol] func symbol naming the method to call when this + # `Observable` has changes` + def add_observer(observer = nil, func = :update, &block) + raise ArgumentError.new('cannot provide both an observer and a block') if observer && block + direct_notification = false + + if block + observer = block + func = :call + end + + synchronize do + if event.set? + direct_notification = true + else + observers.add_observer(observer, func) + end + end + + observer.send(func, Time.now, self.value, reason) if direct_notification + observer + end + + # @!macro ivar_set_method + # Set the `IVar` to a value and wake or notify all threads waiting on it. + # + # @!macro ivar_set_parameters_and_exceptions + # @param [Object] value the value to store in the `IVar` + # @yield A block operation to use for setting the value + # @raise [ArgumentError] if both a value and a block are given + # @raise [Concurrent::MultipleAssignmentError] if the `IVar` has already + # been set or otherwise completed + # + # @return [IVar] self + def set(value = NULL) + check_for_block_or_value!(block_given?, value) + raise MultipleAssignmentError unless compare_and_set_state(:processing, :pending) + + begin + value = yield if block_given? + complete_without_notification(true, value, nil) + rescue => ex + complete_without_notification(false, nil, ex) + end + + notify_observers(self.value, reason) + self + end + + # @!macro ivar_fail_method + # Set the `IVar` to failed due to some error and wake or notify all threads waiting on it. + # + # @param [Object] reason for the failure + # @raise [Concurrent::MultipleAssignmentError] if the `IVar` has already + # been set or otherwise completed + # @return [IVar] self + def fail(reason = StandardError.new) + complete(false, nil, reason) + end + + # Attempt to set the `IVar` with the given value or block. Return a + # boolean indicating the success or failure of the set operation. + # + # @!macro ivar_set_parameters_and_exceptions + # + # @return [Boolean] true if the value was set else false + def try_set(value = NULL, &block) + set(value, &block) + true + rescue MultipleAssignmentError + false + end + + protected + + # @!visibility private + def ns_initialize(value, opts) + value = yield if block_given? + init_obligation + self.observers = Collection::CopyOnWriteObserverSet.new + set_deref_options(opts) + + @state = :pending + if value != NULL + ns_complete_without_notification(true, value, nil) + end + end + + # @!visibility private + def safe_execute(task, args = []) + if compare_and_set_state(:processing, :pending) + success, val, reason = SafeTaskExecutor.new(task, rescue_exception: true).execute(*@args) + complete(success, val, reason) + yield(success, val, reason) if block_given? + end + end + + # @!visibility private + def complete(success, value, reason) + complete_without_notification(success, value, reason) + notify_observers(self.value, reason) + self + end + + # @!visibility private + def complete_without_notification(success, value, reason) + synchronize { ns_complete_without_notification(success, value, reason) } + self + end + + # @!visibility private + def notify_observers(value, reason) + observers.notify_and_delete_observers{ [Time.now, value, reason] } + end + + # @!visibility private + def ns_complete_without_notification(success, value, reason) + raise MultipleAssignmentError if [:fulfilled, :rejected].include? @state + set_state(success, value, reason) + event.set + end + + # @!visibility private + def check_for_block_or_value!(block_given, value) # :nodoc: + if (block_given && value != NULL) || (! block_given && value == NULL) + raise ArgumentError.new('must set with either a value or a block') + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/map.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/map.rb new file mode 100644 index 00000000..b263f83d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/map.rb @@ -0,0 +1,350 @@ +require 'thread' +require 'concurrent/constants' +require 'concurrent/utility/engine' + +module Concurrent + # @!visibility private + module Collection + + # @!visibility private + MapImplementation = case + when Concurrent.on_jruby? + require 'concurrent/utility/native_extension_loader' + # noinspection RubyResolve + JRubyMapBackend + when Concurrent.on_cruby? + require 'concurrent/collection/map/mri_map_backend' + MriMapBackend + when Concurrent.on_truffleruby? + if defined?(::TruffleRuby::ConcurrentMap) + require 'concurrent/collection/map/truffleruby_map_backend' + TruffleRubyMapBackend + else + require 'concurrent/collection/map/synchronized_map_backend' + SynchronizedMapBackend + end + else + warn 'Concurrent::Map: unsupported Ruby engine, using a fully synchronized Concurrent::Map implementation' + require 'concurrent/collection/map/synchronized_map_backend' + SynchronizedMapBackend + end + end + + # `Concurrent::Map` is a hash-like object and should have much better performance + # characteristics, especially under high concurrency, than `Concurrent::Hash`. + # However, `Concurrent::Map `is not strictly semantically equivalent to a ruby `Hash` + # -- for instance, it does not necessarily retain ordering by insertion time as `Hash` + # does. For most uses it should do fine though, and we recommend you consider + # `Concurrent::Map` instead of `Concurrent::Hash` for your concurrency-safe hash needs. + class Map < Collection::MapImplementation + + # @!macro map.atomic_method + # This method is atomic. + + # @!macro map.atomic_method_with_block + # This method is atomic. + # @note Atomic methods taking a block do not allow the `self` instance + # to be used within the block. Doing so will cause a deadlock. + + # @!method []=(key, value) + # Set a value with key + # @param [Object] key + # @param [Object] value + # @return [Object] the new value + + # @!method compute_if_absent(key) + # Compute and store new value for key if the key is absent. + # @param [Object] key + # @yield new value + # @yieldreturn [Object] new value + # @return [Object] new value or current value + # @!macro map.atomic_method_with_block + + # @!method compute_if_present(key) + # Compute and store new value for key if the key is present. + # @param [Object] key + # @yield new value + # @yieldparam old_value [Object] + # @yieldreturn [Object, nil] new value, when nil the key is removed + # @return [Object, nil] new value or nil + # @!macro map.atomic_method_with_block + + # @!method compute(key) + # Compute and store new value for key. + # @param [Object] key + # @yield compute new value from old one + # @yieldparam old_value [Object, nil] old_value, or nil when key is absent + # @yieldreturn [Object, nil] new value, when nil the key is removed + # @return [Object, nil] new value or nil + # @!macro map.atomic_method_with_block + + # @!method merge_pair(key, value) + # If the key is absent, the value is stored, otherwise new value is + # computed with a block. + # @param [Object] key + # @param [Object] value + # @yield compute new value from old one + # @yieldparam old_value [Object] old value + # @yieldreturn [Object, nil] new value, when nil the key is removed + # @return [Object, nil] new value or nil + # @!macro map.atomic_method_with_block + + # @!method replace_pair(key, old_value, new_value) + # Replaces old_value with new_value if key exists and current value + # matches old_value + # @param [Object] key + # @param [Object] old_value + # @param [Object] new_value + # @return [true, false] true if replaced + # @!macro map.atomic_method + + # @!method replace_if_exists(key, new_value) + # Replaces current value with new_value if key exists + # @param [Object] key + # @param [Object] new_value + # @return [Object, nil] old value or nil + # @!macro map.atomic_method + + # @!method get_and_set(key, value) + # Get the current value under key and set new value. + # @param [Object] key + # @param [Object] value + # @return [Object, nil] old value or nil when the key was absent + # @!macro map.atomic_method + + # @!method delete(key) + # Delete key and its value. + # @param [Object] key + # @return [Object, nil] old value or nil when the key was absent + # @!macro map.atomic_method + + # @!method delete_pair(key, value) + # Delete pair and its value if current value equals the provided value. + # @param [Object] key + # @param [Object] value + # @return [true, false] true if deleted + # @!macro map.atomic_method + + # NonConcurrentMapBackend handles default_proc natively + unless defined?(Collection::NonConcurrentMapBackend) and self < Collection::NonConcurrentMapBackend + + # @param [Hash, nil] options options to set the :initial_capacity or :load_factor. Ignored on some Rubies. + # @param [Proc] default_proc Optional block to compute the default value if the key is not set, like `Hash#default_proc` + def initialize(options = nil, &default_proc) + if options.kind_of?(::Hash) + validate_options_hash!(options) + else + options = nil + end + + super(options) + @default_proc = default_proc + end + + # Get a value with key + # @param [Object] key + # @return [Object] the value + def [](key) + if value = super # non-falsy value is an existing mapping, return it right away + value + # re-check is done with get_or_default(key, NULL) instead of a simple !key?(key) in order to avoid a race condition, whereby by the time the current thread gets to the key?(key) call + # a key => value mapping might have already been created by a different thread (key?(key) would then return true, this elsif branch wouldn't be taken and an incorrect +nil+ value + # would be returned) + # note: nil == value check is not technically necessary + elsif @default_proc && nil == value && NULL == (value = get_or_default(key, NULL)) + @default_proc.call(self, key) + else + value + end + end + end + + alias_method :get, :[] + alias_method :put, :[]= + + # Get a value with key, or default_value when key is absent, + # or fail when no default_value is given. + # @param [Object] key + # @param [Object] default_value + # @yield default value for a key + # @yieldparam key [Object] + # @yieldreturn [Object] default value + # @return [Object] the value or default value + # @raise [KeyError] when key is missing and no default_value is provided + # @!macro map_method_not_atomic + # @note The "fetch-then-act" methods of `Map` are not atomic. `Map` is intended + # to be use as a concurrency primitive with strong happens-before + # guarantees. It is not intended to be used as a high-level abstraction + # supporting complex operations. All read and write operations are + # thread safe, but no guarantees are made regarding race conditions + # between the fetch operation and yielding to the block. Additionally, + # this method does not support recursion. This is due to internal + # constraints that are very unlikely to change in the near future. + def fetch(key, default_value = NULL) + if NULL != (value = get_or_default(key, NULL)) + value + elsif block_given? + yield key + elsif NULL != default_value + default_value + else + raise_fetch_no_key + end + end + + # Fetch value with key, or store default value when key is absent, + # or fail when no default_value is given. This is a two step operation, + # therefore not atomic. The store can overwrite other concurrently + # stored value. + # @param [Object] key + # @param [Object] default_value + # @yield default value for a key + # @yieldparam key [Object] + # @yieldreturn [Object] default value + # @return [Object] the value or default value + def fetch_or_store(key, default_value = NULL) + fetch(key) do + put(key, block_given? ? yield(key) : (NULL == default_value ? raise_fetch_no_key : default_value)) + end + end + + # Insert value into map with key if key is absent in one atomic step. + # @param [Object] key + # @param [Object] value + # @return [Object, nil] the previous value when key was present or nil when there was no key + def put_if_absent(key, value) + computed = false + result = compute_if_absent(key) do + computed = true + value + end + computed ? nil : result + end unless method_defined?(:put_if_absent) + + # Is the value stored in the map. Iterates over all values. + # @param [Object] value + # @return [true, false] + def value?(value) + each_value do |v| + return true if value.equal?(v) + end + false + end + + # All keys + # @return [::Array] keys + def keys + arr = [] + each_pair { |k, v| arr << k } + arr + end unless method_defined?(:keys) + + # All values + # @return [::Array] values + def values + arr = [] + each_pair { |k, v| arr << v } + arr + end unless method_defined?(:values) + + # Iterates over each key. + # @yield for each key in the map + # @yieldparam key [Object] + # @return [self] + # @!macro map.atomic_method_with_block + def each_key + each_pair { |k, v| yield k } + end unless method_defined?(:each_key) + + # Iterates over each value. + # @yield for each value in the map + # @yieldparam value [Object] + # @return [self] + # @!macro map.atomic_method_with_block + def each_value + each_pair { |k, v| yield v } + end unless method_defined?(:each_value) + + # Iterates over each key value pair. + # @yield for each key value pair in the map + # @yieldparam key [Object] + # @yieldparam value [Object] + # @return [self] + # @!macro map.atomic_method_with_block + def each_pair + return enum_for :each_pair unless block_given? + super + end + + alias_method :each, :each_pair unless method_defined?(:each) + + # Find key of a value. + # @param [Object] value + # @return [Object, nil] key or nil when not found + def key(value) + each_pair { |k, v| return k if v == value } + nil + end unless method_defined?(:key) + + # Is map empty? + # @return [true, false] + def empty? + each_pair { |k, v| return false } + true + end unless method_defined?(:empty?) + + # The size of map. + # @return [Integer] size + def size + count = 0 + each_pair { |k, v| count += 1 } + count + end unless method_defined?(:size) + + # @!visibility private + def marshal_dump + raise TypeError, "can't dump hash with default proc" if @default_proc + h = {} + each_pair { |k, v| h[k] = v } + h + end + + # @!visibility private + def marshal_load(hash) + initialize + populate_from(hash) + end + + undef :freeze + + # @!visibility private + def inspect + format '%s entries=%d default_proc=%s>', to_s[0..-2], size.to_s, @default_proc.inspect + end + + private + + def raise_fetch_no_key + raise KeyError, 'key not found' + end + + def initialize_copy(other) + super + populate_from(other) + end + + def populate_from(hash) + hash.each_pair { |k, v| self[k] = v } + self + end + + def validate_options_hash!(options) + if (initial_capacity = options[:initial_capacity]) && (!initial_capacity.kind_of?(Integer) || initial_capacity < 0) + raise ArgumentError, ":initial_capacity must be a positive Integer" + end + if (load_factor = options[:load_factor]) && (!load_factor.kind_of?(Numeric) || load_factor <= 0 || load_factor > 1) + raise ArgumentError, ":load_factor must be a number between 0 and 1" + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/maybe.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/maybe.rb new file mode 100644 index 00000000..317c82b8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/maybe.rb @@ -0,0 +1,229 @@ +require 'concurrent/synchronization/object' + +module Concurrent + + # A `Maybe` encapsulates an optional value. A `Maybe` either contains a value + # of (represented as `Just`), or it is empty (represented as `Nothing`). Using + # `Maybe` is a good way to deal with errors or exceptional cases without + # resorting to drastic measures such as exceptions. + # + # `Maybe` is a replacement for the use of `nil` with better type checking. + # + # For compatibility with {Concurrent::Concern::Obligation} the predicate and + # accessor methods are aliased as `fulfilled?`, `rejected?`, `value`, and + # `reason`. + # + # ## Motivation + # + # A common pattern in languages with pattern matching, such as Erlang and + # Haskell, is to return *either* a value *or* an error from a function + # Consider this Erlang code: + # + # ```erlang + # case file:consult("data.dat") of + # {ok, Terms} -> do_something_useful(Terms); + # {error, Reason} -> lager:error(Reason) + # end. + # ``` + # + # In this example the standard library function `file:consult` returns a + # [tuple](http://erlang.org/doc/reference_manual/data_types.html#id69044) + # with two elements: an [atom](http://erlang.org/doc/reference_manual/data_types.html#id64134) + # (similar to a ruby symbol) and a variable containing ancillary data. On + # success it returns the atom `ok` and the data from the file. On failure it + # returns `error` and a string with an explanation of the problem. With this + # pattern there is no ambiguity regarding success or failure. If the file is + # empty the return value cannot be misinterpreted as an error. And when an + # error occurs the return value provides useful information. + # + # In Ruby we tend to return `nil` when an error occurs or else we raise an + # exception. Both of these idioms are problematic. Returning `nil` is + # ambiguous because `nil` may also be a valid value. It also lacks + # information pertaining to the nature of the error. Raising an exception + # is both expensive and usurps the normal flow of control. All of these + # problems can be solved with the use of a `Maybe`. + # + # A `Maybe` is unambiguous with regard to whether or not it contains a value. + # When `Just` it contains a value, when `Nothing` it does not. When `Just` + # the value it contains may be `nil`, which is perfectly valid. When + # `Nothing` the reason for the lack of a value is contained as well. The + # previous Erlang example can be duplicated in Ruby in a principled way by + # having functions return `Maybe` objects: + # + # ```ruby + # result = MyFileUtils.consult("data.dat") # returns a Maybe + # if result.just? + # do_something_useful(result.value) # or result.just + # else + # logger.error(result.reason) # or result.nothing + # end + # ``` + # + # @example Returning a Maybe from a Function + # module MyFileUtils + # def self.consult(path) + # file = File.open(path, 'r') + # Concurrent::Maybe.just(file.read) + # rescue => ex + # return Concurrent::Maybe.nothing(ex) + # ensure + # file.close if file + # end + # end + # + # maybe = MyFileUtils.consult('bogus.file') + # maybe.just? #=> false + # maybe.nothing? #=> true + # maybe.reason #=> # + # + # maybe = MyFileUtils.consult('README.md') + # maybe.just? #=> true + # maybe.nothing? #=> false + # maybe.value #=> "# Concurrent Ruby\n[![Gem Version..." + # + # @example Using Maybe with a Block + # result = Concurrent::Maybe.from do + # Client.find(10) # Client is an ActiveRecord model + # end + # + # # -- if the record was found + # result.just? #=> true + # result.value #=> # + # + # # -- if the record was not found + # result.just? #=> false + # result.reason #=> ActiveRecord::RecordNotFound + # + # @example Using Maybe with the Null Object Pattern + # # In a Rails controller... + # result = ClientService.new(10).find # returns a Maybe + # render json: result.or(NullClient.new) + # + # @see https://hackage.haskell.org/package/base-4.2.0.1/docs/Data-Maybe.html Haskell Data.Maybe + # @see https://github.com/purescript/purescript-maybe/blob/master/docs/Data.Maybe.md PureScript Data.Maybe + class Maybe < Synchronization::Object + include Comparable + safe_initialization! + + # Indicates that the given attribute has not been set. + # When `Just` the {#nothing} getter will return `NONE`. + # When `Nothing` the {#just} getter will return `NONE`. + NONE = ::Object.new.freeze + + # The value of a `Maybe` when `Just`. Will be `NONE` when `Nothing`. + attr_reader :just + + # The reason for the `Maybe` when `Nothing`. Will be `NONE` when `Just`. + attr_reader :nothing + + private_class_method :new + + # Create a new `Maybe` using the given block. + # + # Runs the given block passing all function arguments to the block as block + # arguments. If the block runs to completion without raising an exception + # a new `Just` is created with the value set to the return value of the + # block. If the block raises an exception a new `Nothing` is created with + # the reason being set to the raised exception. + # + # @param [Array] args Zero or more arguments to pass to the block. + # @yield The block from which to create a new `Maybe`. + # @yieldparam [Array] args Zero or more block arguments passed as + # arguments to the function. + # + # @return [Maybe] The newly created object. + # + # @raise [ArgumentError] when no block given. + def self.from(*args) + raise ArgumentError.new('no block given') unless block_given? + begin + value = yield(*args) + return new(value, NONE) + rescue => ex + return new(NONE, ex) + end + end + + # Create a new `Just` with the given value. + # + # @param [Object] value The value to set for the new `Maybe` object. + # + # @return [Maybe] The newly created object. + def self.just(value) + return new(value, NONE) + end + + # Create a new `Nothing` with the given (optional) reason. + # + # @param [Exception] error The reason to set for the new `Maybe` object. + # When given a string a new `StandardError` will be created with the + # argument as the message. When no argument is given a new + # `StandardError` with an empty message will be created. + # + # @return [Maybe] The newly created object. + def self.nothing(error = '') + if error.is_a?(Exception) + nothing = error + else + nothing = StandardError.new(error.to_s) + end + return new(NONE, nothing) + end + + # Is this `Maybe` a `Just` (successfully fulfilled with a value)? + # + # @return [Boolean] True if `Just` or false if `Nothing`. + def just? + ! nothing? + end + alias :fulfilled? :just? + + # Is this `Maybe` a `nothing` (rejected with an exception upon fulfillment)? + # + # @return [Boolean] True if `Nothing` or false if `Just`. + def nothing? + @nothing != NONE + end + alias :rejected? :nothing? + + alias :value :just + + alias :reason :nothing + + # Comparison operator. + # + # @return [Integer] 0 if self and other are both `Nothing`; + # -1 if self is `Nothing` and other is `Just`; + # 1 if self is `Just` and other is nothing; + # `self.just <=> other.just` if both self and other are `Just`. + def <=>(other) + if nothing? + other.nothing? ? 0 : -1 + else + other.nothing? ? 1 : just <=> other.just + end + end + + # Return either the value of self or the given default value. + # + # @return [Object] The value of self when `Just`; else the given default. + def or(other) + just? ? just : other + end + + private + + # Create a new `Maybe` with the given attributes. + # + # @param [Object] just The value when `Just` else `NONE`. + # @param [Exception, Object] nothing The exception when `Nothing` else `NONE`. + # + # @return [Maybe] The new `Maybe`. + # + # @!visibility private + def initialize(just, nothing) + @just = just + @nothing = nothing + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/mutable_struct.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/mutable_struct.rb new file mode 100644 index 00000000..5d0e9b9a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/mutable_struct.rb @@ -0,0 +1,239 @@ +require 'concurrent/synchronization/abstract_struct' +require 'concurrent/synchronization/lockable_object' + +module Concurrent + + # An thread-safe variation of Ruby's standard `Struct`. Values can be set at + # construction or safely changed at any time during the object's lifecycle. + # + # @see http://ruby-doc.org/core/Struct.html Ruby standard library `Struct` + module MutableStruct + include Synchronization::AbstractStruct + + # @!macro struct_new + # + # Factory for creating new struct classes. + # + # ``` + # new([class_name] [, member_name]+>) -> StructClass click to toggle source + # new([class_name] [, member_name]+>) {|StructClass| block } -> StructClass + # new(value, ...) -> obj + # StructClass[value, ...] -> obj + # ``` + # + # The first two forms are used to create a new struct subclass `class_name` + # that can contain a value for each member_name . This subclass can be + # used to create instances of the structure like any other Class . + # + # If the `class_name` is omitted an anonymous struct class will be created. + # Otherwise, the name of this struct will appear as a constant in the struct class, + # so it must be unique for all structs under this base class and must start with a + # capital letter. Assigning a struct class to a constant also gives the class + # the name of the constant. + # + # If a block is given it will be evaluated in the context of `StructClass`, passing + # the created class as a parameter. This is the recommended way to customize a struct. + # Subclassing an anonymous struct creates an extra anonymous class that will never be used. + # + # The last two forms create a new instance of a struct subclass. The number of value + # parameters must be less than or equal to the number of attributes defined for the + # struct. Unset parameters default to nil. Passing more parameters than number of attributes + # will raise an `ArgumentError`. + # + # @see http://ruby-doc.org/core/Struct.html#method-c-new Ruby standard library `Struct#new` + + # @!macro struct_values + # + # Returns the values for this struct as an Array. + # + # @return [Array] the values for this struct + # + def values + synchronize { ns_values } + end + alias_method :to_a, :values + + # @!macro struct_values_at + # + # Returns the struct member values for each selector as an Array. + # + # A selector may be either an Integer offset or a Range of offsets (as in `Array#values_at`). + # + # @param [Fixnum, Range] indexes the index(es) from which to obatin the values (in order) + def values_at(*indexes) + synchronize { ns_values_at(indexes) } + end + + # @!macro struct_inspect + # + # Describe the contents of this struct in a string. + # + # @return [String] the contents of this struct in a string + def inspect + synchronize { ns_inspect } + end + alias_method :to_s, :inspect + + # @!macro struct_merge + # + # Returns a new struct containing the contents of `other` and the contents + # of `self`. If no block is specified, the value for entries with duplicate + # keys will be that of `other`. Otherwise the value for each duplicate key + # is determined by calling the block with the key, its value in `self` and + # its value in `other`. + # + # @param [Hash] other the hash from which to set the new values + # @yield an options block for resolving duplicate keys + # @yieldparam [String, Symbol] member the name of the member which is duplicated + # @yieldparam [Object] selfvalue the value of the member in `self` + # @yieldparam [Object] othervalue the value of the member in `other` + # + # @return [Synchronization::AbstractStruct] a new struct with the new values + # + # @raise [ArgumentError] of given a member that is not defined in the struct + def merge(other, &block) + synchronize { ns_merge(other, &block) } + end + + # @!macro struct_to_h + # + # Returns a hash containing the names and values for the struct’s members. + # + # @return [Hash] the names and values for the struct’s members + def to_h + synchronize { ns_to_h } + end + + # @!macro struct_get + # + # Attribute Reference + # + # @param [Symbol, String, Integer] member the string or symbol name of the member + # for which to obtain the value or the member's index + # + # @return [Object] the value of the given struct member or the member at the given index. + # + # @raise [NameError] if the member does not exist + # @raise [IndexError] if the index is out of range. + def [](member) + synchronize { ns_get(member) } + end + + # @!macro struct_equality + # + # Equality + # + # @return [Boolean] true if other has the same struct subclass and has + # equal member values (according to `Object#==`) + def ==(other) + synchronize { ns_equality(other) } + end + + # @!macro struct_each + # + # Yields the value of each struct member in order. If no block is given + # an enumerator is returned. + # + # @yield the operation to be performed on each struct member + # @yieldparam [Object] value each struct value (in order) + def each(&block) + return enum_for(:each) unless block_given? + synchronize { ns_each(&block) } + end + + # @!macro struct_each_pair + # + # Yields the name and value of each struct member in order. If no block is + # given an enumerator is returned. + # + # @yield the operation to be performed on each struct member/value pair + # @yieldparam [Object] member each struct member (in order) + # @yieldparam [Object] value each struct value (in order) + def each_pair(&block) + return enum_for(:each_pair) unless block_given? + synchronize { ns_each_pair(&block) } + end + + # @!macro struct_select + # + # Yields each member value from the struct to the block and returns an Array + # containing the member values from the struct for which the given block + # returns a true value (equivalent to `Enumerable#select`). + # + # @yield the operation to be performed on each struct member + # @yieldparam [Object] value each struct value (in order) + # + # @return [Array] an array containing each value for which the block returns true + def select(&block) + return enum_for(:select) unless block_given? + synchronize { ns_select(&block) } + end + + # @!macro struct_set + # + # Attribute Assignment + # + # Sets the value of the given struct member or the member at the given index. + # + # @param [Symbol, String, Integer] member the string or symbol name of the member + # for which to obtain the value or the member's index + # + # @return [Object] the value of the given struct member or the member at the given index. + # + # @raise [NameError] if the name does not exist + # @raise [IndexError] if the index is out of range. + def []=(member, value) + if member.is_a? Integer + length = synchronize { @values.length } + if member >= length + raise IndexError.new("offset #{member} too large for struct(size:#{length})") + end + synchronize { @values[member] = value } + else + send("#{member}=", value) + end + rescue NoMethodError + raise NameError.new("no member '#{member}' in struct") + end + + private + + # @!visibility private + def initialize_copy(original) + synchronize do + super(original) + ns_initialize_copy + end + end + + # @!macro struct_new + def self.new(*args, &block) + clazz_name = nil + if args.length == 0 + raise ArgumentError.new('wrong number of arguments (0 for 1+)') + elsif args.length > 0 && args.first.is_a?(String) + clazz_name = args.shift + end + FACTORY.define_struct(clazz_name, args, &block) + end + + FACTORY = Class.new(Synchronization::LockableObject) do + def define_struct(name, members, &block) + synchronize do + clazz = Synchronization::AbstractStruct.define_struct_class(MutableStruct, Synchronization::LockableObject, name, members, &block) + members.each_with_index do |member, index| + clazz.send :remove_method, member + clazz.send(:define_method, member) do + synchronize { @values[index] } + end + clazz.send(:define_method, "#{member}=") do |value| + synchronize { @values[index] = value } + end + end + clazz + end + end + end.new + private_constant :FACTORY + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/mvar.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/mvar.rb new file mode 100644 index 00000000..dfc41950 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/mvar.rb @@ -0,0 +1,242 @@ +require 'concurrent/concern/dereferenceable' +require 'concurrent/synchronization/object' + +module Concurrent + + # An `MVar` is a synchronized single element container. They are empty or + # contain one item. Taking a value from an empty `MVar` blocks, as does + # putting a value into a full one. You can either think of them as blocking + # queue of length one, or a special kind of mutable variable. + # + # On top of the fundamental `#put` and `#take` operations, we also provide a + # `#mutate` that is atomic with respect to operations on the same instance. + # These operations all support timeouts. + # + # We also support non-blocking operations `#try_put!` and `#try_take!`, a + # `#set!` that ignores existing values, a `#value` that returns the value + # without removing it or returns `MVar::EMPTY`, and a `#modify!` that yields + # `MVar::EMPTY` if the `MVar` is empty and can be used to set `MVar::EMPTY`. + # You shouldn't use these operations in the first instance. + # + # `MVar` is a [Dereferenceable](Dereferenceable). + # + # `MVar` is related to M-structures in Id, `MVar` in Haskell and `SyncVar` in Scala. + # + # Note that unlike the original Haskell paper, our `#take` is blocking. This is how + # Haskell and Scala do it today. + # + # @!macro copy_options + # + # ## See Also + # + # 1. P. Barth, R. Nikhil, and Arvind. [M-Structures: Extending a parallel, non- strict, functional language with state](http://dl.acm.org/citation.cfm?id=652538). In Proceedings of the 5th + # ACM Conference on Functional Programming Languages and Computer Architecture (FPCA), 1991. + # + # 2. S. Peyton Jones, A. Gordon, and S. Finne. [Concurrent Haskell](http://dl.acm.org/citation.cfm?id=237794). + # In Proceedings of the 23rd Symposium on Principles of Programming Languages + # (PoPL), 1996. + class MVar < Synchronization::Object + include Concern::Dereferenceable + safe_initialization! + + # Unique value that represents that an `MVar` was empty + EMPTY = ::Object.new + + # Unique value that represents that an `MVar` timed out before it was able + # to produce a value. + TIMEOUT = ::Object.new + + # Create a new `MVar`, either empty or with an initial value. + # + # @param [Hash] opts the options controlling how the future will be processed + # + # @!macro deref_options + def initialize(value = EMPTY, opts = {}) + @value = value + @mutex = Mutex.new + @empty_condition = ConditionVariable.new + @full_condition = ConditionVariable.new + set_deref_options(opts) + end + + # Remove the value from an `MVar`, leaving it empty, and blocking if there + # isn't a value. A timeout can be set to limit the time spent blocked, in + # which case it returns `TIMEOUT` if the time is exceeded. + # @return [Object] the value that was taken, or `TIMEOUT` + def take(timeout = nil) + @mutex.synchronize do + wait_for_full(timeout) + + # If we timed out we'll still be empty + if unlocked_full? + value = @value + @value = EMPTY + @empty_condition.signal + apply_deref_options(value) + else + TIMEOUT + end + end + end + + # acquires lock on the from an `MVAR`, yields the value to provided block, + # and release lock. A timeout can be set to limit the time spent blocked, + # in which case it returns `TIMEOUT` if the time is exceeded. + # @return [Object] the value returned by the block, or `TIMEOUT` + def borrow(timeout = nil) + @mutex.synchronize do + wait_for_full(timeout) + + # if we timeoud out we'll still be empty + if unlocked_full? + yield @value + else + TIMEOUT + end + end + end + + # Put a value into an `MVar`, blocking if there is already a value until + # it is empty. A timeout can be set to limit the time spent blocked, in + # which case it returns `TIMEOUT` if the time is exceeded. + # @return [Object] the value that was put, or `TIMEOUT` + def put(value, timeout = nil) + @mutex.synchronize do + wait_for_empty(timeout) + + # If we timed out we won't be empty + if unlocked_empty? + @value = value + @full_condition.signal + apply_deref_options(value) + else + TIMEOUT + end + end + end + + # Atomically `take`, yield the value to a block for transformation, and then + # `put` the transformed value. Returns the transformed value. A timeout can + # be set to limit the time spent blocked, in which case it returns `TIMEOUT` + # if the time is exceeded. + # @return [Object] the transformed value, or `TIMEOUT` + def modify(timeout = nil) + raise ArgumentError.new('no block given') unless block_given? + + @mutex.synchronize do + wait_for_full(timeout) + + # If we timed out we'll still be empty + if unlocked_full? + value = @value + @value = yield value + @full_condition.signal + apply_deref_options(value) + else + TIMEOUT + end + end + end + + # Non-blocking version of `take`, that returns `EMPTY` instead of blocking. + def try_take! + @mutex.synchronize do + if unlocked_full? + value = @value + @value = EMPTY + @empty_condition.signal + apply_deref_options(value) + else + EMPTY + end + end + end + + # Non-blocking version of `put`, that returns whether or not it was successful. + def try_put!(value) + @mutex.synchronize do + if unlocked_empty? + @value = value + @full_condition.signal + true + else + false + end + end + end + + # Non-blocking version of `put` that will overwrite an existing value. + def set!(value) + @mutex.synchronize do + old_value = @value + @value = value + @full_condition.signal + apply_deref_options(old_value) + end + end + + # Non-blocking version of `modify` that will yield with `EMPTY` if there is no value yet. + def modify! + raise ArgumentError.new('no block given') unless block_given? + + @mutex.synchronize do + value = @value + @value = yield value + if unlocked_empty? + @empty_condition.signal + else + @full_condition.signal + end + apply_deref_options(value) + end + end + + # Returns if the `MVar` is currently empty. + def empty? + @mutex.synchronize { @value == EMPTY } + end + + # Returns if the `MVar` currently contains a value. + def full? + !empty? + end + + protected + + def synchronize(&block) + @mutex.synchronize(&block) + end + + private + + def unlocked_empty? + @value == EMPTY + end + + def unlocked_full? + ! unlocked_empty? + end + + def wait_for_full(timeout) + wait_while(@full_condition, timeout) { unlocked_empty? } + end + + def wait_for_empty(timeout) + wait_while(@empty_condition, timeout) { unlocked_full? } + end + + def wait_while(condition, timeout) + if timeout.nil? + while yield + condition.wait(@mutex) + end + else + stop = Concurrent.monotonic_time + timeout + while yield && timeout > 0.0 + condition.wait(@mutex, timeout) + timeout = stop - Concurrent.monotonic_time + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/options.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/options.rb new file mode 100644 index 00000000..bdd22a9d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/options.rb @@ -0,0 +1,42 @@ +require 'concurrent/configuration' + +module Concurrent + + # @!visibility private + module Options + + # Get the requested `Executor` based on the values set in the options hash. + # + # @param [Hash] opts the options defining the requested executor + # @option opts [Executor] :executor when set use the given `Executor` instance. + # Three special values are also supported: `:fast` returns the global fast executor, + # `:io` returns the global io executor, and `:immediate` returns a new + # `ImmediateExecutor` object. + # + # @return [Executor, nil] the requested thread pool, or nil when no option specified + # + # @!visibility private + def self.executor_from_options(opts = {}) # :nodoc: + if identifier = opts.fetch(:executor, nil) + executor(identifier) + else + nil + end + end + + def self.executor(executor_identifier) + case executor_identifier + when :fast + Concurrent.global_fast_executor + when :io + Concurrent.global_io_executor + when :immediate + Concurrent.global_immediate_executor + when Concurrent::ExecutorService + executor_identifier + else + raise ArgumentError, "executor not recognized by '#{executor_identifier}'" + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/promise.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/promise.rb new file mode 100644 index 00000000..c717f9b0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/promise.rb @@ -0,0 +1,580 @@ +require 'thread' +require 'concurrent/constants' +require 'concurrent/errors' +require 'concurrent/ivar' +require 'concurrent/executor/safe_task_executor' + +require 'concurrent/options' + +module Concurrent + + PromiseExecutionError = Class.new(StandardError) + + # Promises are inspired by the JavaScript [Promises/A](http://wiki.commonjs.org/wiki/Promises/A) + # and [Promises/A+](http://promises-aplus.github.io/promises-spec/) specifications. + # + # > A promise represents the eventual value returned from the single + # > completion of an operation. + # + # Promises are similar to futures and share many of the same behaviours. + # Promises are far more robust, however. Promises can be chained in a tree + # structure where each promise may have zero or more children. Promises are + # chained using the `then` method. The result of a call to `then` is always + # another promise. Promises are resolved asynchronously (with respect to the + # main thread) but in a strict order: parents are guaranteed to be resolved + # before their children, children before their younger siblings. The `then` + # method takes two parameters: an optional block to be executed upon parent + # resolution and an optional callable to be executed upon parent failure. The + # result of each promise is passed to each of its children upon resolution. + # When a promise is rejected all its children will be summarily rejected and + # will receive the reason. + # + # Promises have several possible states: *:unscheduled*, *:pending*, + # *:processing*, *:rejected*, or *:fulfilled*. These are also aggregated as + # `#incomplete?` and `#complete?`. When a Promise is created it is set to + # *:unscheduled*. Once the `#execute` method is called the state becomes + # *:pending*. Once a job is pulled from the thread pool's queue and is given + # to a thread for processing (often immediately upon `#post`) the state + # becomes *:processing*. The future will remain in this state until processing + # is complete. A future that is in the *:unscheduled*, *:pending*, or + # *:processing* is considered `#incomplete?`. A `#complete?` Promise is either + # *:rejected*, indicating that an exception was thrown during processing, or + # *:fulfilled*, indicating success. If a Promise is *:fulfilled* its `#value` + # will be updated to reflect the result of the operation. If *:rejected* the + # `reason` will be updated with a reference to the thrown exception. The + # predicate methods `#unscheduled?`, `#pending?`, `#rejected?`, and + # `#fulfilled?` can be called at any time to obtain the state of the Promise, + # as can the `#state` method, which returns a symbol. + # + # Retrieving the value of a promise is done through the `value` (alias: + # `deref`) method. Obtaining the value of a promise is a potentially blocking + # operation. When a promise is *rejected* a call to `value` will return `nil` + # immediately. When a promise is *fulfilled* a call to `value` will + # immediately return the current value. When a promise is *pending* a call to + # `value` will block until the promise is either *rejected* or *fulfilled*. A + # *timeout* value can be passed to `value` to limit how long the call will + # block. If `nil` the call will block indefinitely. If `0` the call will not + # block. Any other integer or float value will indicate the maximum number of + # seconds to block. + # + # Promises run on the global thread pool. + # + # @!macro copy_options + # + # ### Examples + # + # Start by requiring promises + # + # ```ruby + # require 'concurrent/promise' + # ``` + # + # Then create one + # + # ```ruby + # p = Concurrent::Promise.execute do + # # do something + # 42 + # end + # ``` + # + # Promises can be chained using the `then` method. The `then` method accepts a + # block and an executor, to be executed on fulfillment, and a callable argument to be executed + # on rejection. The result of the each promise is passed as the block argument + # to chained promises. + # + # ```ruby + # p = Concurrent::Promise.new{10}.then{|x| x * 2}.then{|result| result - 10 }.execute + # ``` + # + # And so on, and so on, and so on... + # + # ```ruby + # p = Concurrent::Promise.fulfill(20). + # then{|result| result - 10 }. + # then{|result| result * 3 }. + # then(executor: different_executor){|result| result % 5 }.execute + # ``` + # + # The initial state of a newly created Promise depends on the state of its parent: + # - if parent is *unscheduled* the child will be *unscheduled* + # - if parent is *pending* the child will be *pending* + # - if parent is *fulfilled* the child will be *pending* + # - if parent is *rejected* the child will be *pending* (but will ultimately be *rejected*) + # + # Promises are executed asynchronously from the main thread. By the time a + # child Promise finishes initialization it may be in a different state than its + # parent (by the time a child is created its parent may have completed + # execution and changed state). Despite being asynchronous, however, the order + # of execution of Promise objects in a chain (or tree) is strictly defined. + # + # There are multiple ways to create and execute a new `Promise`. Both ways + # provide identical behavior: + # + # ```ruby + # # create, operate, then execute + # p1 = Concurrent::Promise.new{ "Hello World!" } + # p1.state #=> :unscheduled + # p1.execute + # + # # create and immediately execute + # p2 = Concurrent::Promise.new{ "Hello World!" }.execute + # + # # execute during creation + # p3 = Concurrent::Promise.execute{ "Hello World!" } + # ``` + # + # Once the `execute` method is called a `Promise` becomes `pending`: + # + # ```ruby + # p = Concurrent::Promise.execute{ "Hello, world!" } + # p.state #=> :pending + # p.pending? #=> true + # ``` + # + # Wait a little bit, and the promise will resolve and provide a value: + # + # ```ruby + # p = Concurrent::Promise.execute{ "Hello, world!" } + # sleep(0.1) + # + # p.state #=> :fulfilled + # p.fulfilled? #=> true + # p.value #=> "Hello, world!" + # ``` + # + # If an exception occurs, the promise will be rejected and will provide + # a reason for the rejection: + # + # ```ruby + # p = Concurrent::Promise.execute{ raise StandardError.new("Here comes the Boom!") } + # sleep(0.1) + # + # p.state #=> :rejected + # p.rejected? #=> true + # p.reason #=> "#" + # ``` + # + # #### Rejection + # + # When a promise is rejected all its children will be rejected and will + # receive the rejection `reason` as the rejection callable parameter: + # + # ```ruby + # p = Concurrent::Promise.execute { Thread.pass; raise StandardError } + # + # c1 = p.then(-> reason { 42 }) + # c2 = p.then(-> reason { raise 'Boom!' }) + # + # c1.wait.state #=> :fulfilled + # c1.value #=> 45 + # c2.wait.state #=> :rejected + # c2.reason #=> # + # ``` + # + # Once a promise is rejected it will continue to accept children that will + # receive immediately rejection (they will be executed asynchronously). + # + # #### Aliases + # + # The `then` method is the most generic alias: it accepts a block to be + # executed upon parent fulfillment and a callable to be executed upon parent + # rejection. At least one of them should be passed. The default block is `{ + # |result| result }` that fulfills the child with the parent value. The + # default callable is `{ |reason| raise reason }` that rejects the child with + # the parent reason. + # + # - `on_success { |result| ... }` is the same as `then {|result| ... }` + # - `rescue { |reason| ... }` is the same as `then(Proc.new { |reason| ... } )` + # - `rescue` is aliased by `catch` and `on_error` + class Promise < IVar + + # Initialize a new Promise with the provided options. + # + # @!macro executor_and_deref_options + # + # @!macro promise_init_options + # + # @option opts [Promise] :parent the parent `Promise` when building a chain/tree + # @option opts [Proc] :on_fulfill fulfillment handler + # @option opts [Proc] :on_reject rejection handler + # @option opts [object, Array] :args zero or more arguments to be passed + # the task block on execution + # + # @yield The block operation to be performed asynchronously. + # + # @raise [ArgumentError] if no block is given + # + # @see http://wiki.commonjs.org/wiki/Promises/A + # @see http://promises-aplus.github.io/promises-spec/ + def initialize(opts = {}, &block) + opts.delete_if { |k, v| v.nil? } + super(NULL, opts.merge(__promise_body_from_block__: block), &nil) + end + + # Create a new `Promise` and fulfill it immediately. + # + # @!macro executor_and_deref_options + # + # @!macro promise_init_options + # + # @raise [ArgumentError] if no block is given + # + # @return [Promise] the newly created `Promise` + def self.fulfill(value, opts = {}) + Promise.new(opts).tap { |p| p.send(:synchronized_set_state!, true, value, nil) } + end + + # Create a new `Promise` and reject it immediately. + # + # @!macro executor_and_deref_options + # + # @!macro promise_init_options + # + # @raise [ArgumentError] if no block is given + # + # @return [Promise] the newly created `Promise` + def self.reject(reason, opts = {}) + Promise.new(opts).tap { |p| p.send(:synchronized_set_state!, false, nil, reason) } + end + + # Execute an `:unscheduled` `Promise`. Immediately sets the state to `:pending` and + # passes the block to a new thread/thread pool for eventual execution. + # Does nothing if the `Promise` is in any state other than `:unscheduled`. + # + # @return [Promise] a reference to `self` + def execute + if root? + if compare_and_set_state(:pending, :unscheduled) + set_pending + realize(@promise_body) + end + else + compare_and_set_state(:pending, :unscheduled) + @parent.execute + end + self + end + + # @!macro ivar_set_method + # + # @raise [Concurrent::PromiseExecutionError] if not the root promise + def set(value = NULL, &block) + raise PromiseExecutionError.new('supported only on root promise') unless root? + check_for_block_or_value!(block_given?, value) + synchronize do + if @state != :unscheduled + raise MultipleAssignmentError + else + @promise_body = block || Proc.new { |result| value } + end + end + execute + end + + # @!macro ivar_fail_method + # + # @raise [Concurrent::PromiseExecutionError] if not the root promise + def fail(reason = StandardError.new) + set { raise reason } + end + + # Create a new `Promise` object with the given block, execute it, and return the + # `:pending` object. + # + # @!macro executor_and_deref_options + # + # @!macro promise_init_options + # + # @return [Promise] the newly created `Promise` in the `:pending` state + # + # @raise [ArgumentError] if no block is given + # + # @example + # promise = Concurrent::Promise.execute{ sleep(1); 42 } + # promise.state #=> :pending + def self.execute(opts = {}, &block) + new(opts, &block).execute + end + + # Chain a new promise off the current promise. + # + # @return [Promise] the new promise + # @yield The block operation to be performed asynchronously. + # @overload then(rescuer, executor, &block) + # @param [Proc] rescuer An optional rescue block to be executed if the + # promise is rejected. + # @param [ThreadPool] executor An optional thread pool executor to be used + # in the new Promise + # @overload then(rescuer, executor: executor, &block) + # @param [Proc] rescuer An optional rescue block to be executed if the + # promise is rejected. + # @param [ThreadPool] executor An optional thread pool executor to be used + # in the new Promise + def then(*args, &block) + if args.last.is_a?(::Hash) + executor = args.pop[:executor] + rescuer = args.first + else + rescuer, executor = args + end + + executor ||= @executor + + raise ArgumentError.new('rescuers and block are both missing') if rescuer.nil? && !block_given? + block = Proc.new { |result| result } unless block_given? + child = Promise.new( + parent: self, + executor: executor, + on_fulfill: block, + on_reject: rescuer + ) + + synchronize do + child.state = :pending if @state == :pending + child.on_fulfill(apply_deref_options(@value)) if @state == :fulfilled + child.on_reject(@reason) if @state == :rejected + @children << child + end + + child + end + + # Chain onto this promise an action to be undertaken on success + # (fulfillment). + # + # @yield The block to execute + # + # @return [Promise] self + def on_success(&block) + raise ArgumentError.new('no block given') unless block_given? + self.then(&block) + end + + # Chain onto this promise an action to be undertaken on failure + # (rejection). + # + # @yield The block to execute + # + # @return [Promise] self + def rescue(&block) + self.then(block) + end + + alias_method :catch, :rescue + alias_method :on_error, :rescue + + # Yield the successful result to the block that returns a promise. If that + # promise is also successful the result is the result of the yielded promise. + # If either part fails the whole also fails. + # + # @example + # Promise.execute { 1 }.flat_map { |v| Promise.execute { v + 2 } }.value! #=> 3 + # + # @return [Promise] + def flat_map(&block) + child = Promise.new( + parent: self, + executor: ImmediateExecutor.new, + ) + + on_error { |e| child.on_reject(e) } + on_success do |result1| + begin + inner = block.call(result1) + inner.execute + inner.on_success { |result2| child.on_fulfill(result2) } + inner.on_error { |e| child.on_reject(e) } + rescue => e + child.on_reject(e) + end + end + + child + end + + # Builds a promise that produces the result of promises in an Array + # and fails if any of them fails. + # + # @overload zip(*promises) + # @param [Array] promises + # + # @overload zip(*promises, opts) + # @param [Array] promises + # @param [Hash] opts the configuration options + # @option opts [Executor] :executor (ImmediateExecutor.new) when set use the given `Executor` instance. + # @option opts [Boolean] :execute (true) execute promise before returning + # + # @return [Promise] + def self.zip(*promises) + opts = promises.last.is_a?(::Hash) ? promises.pop.dup : {} + opts[:executor] ||= ImmediateExecutor.new + zero = if !opts.key?(:execute) || opts.delete(:execute) + fulfill([], opts) + else + Promise.new(opts) { [] } + end + + promises.reduce(zero) do |p1, p2| + p1.flat_map do |results| + p2.then do |next_result| + results << next_result + end + end + end + end + + # Builds a promise that produces the result of self and others in an Array + # and fails if any of them fails. + # + # @overload zip(*promises) + # @param [Array] others + # + # @overload zip(*promises, opts) + # @param [Array] others + # @param [Hash] opts the configuration options + # @option opts [Executor] :executor (ImmediateExecutor.new) when set use the given `Executor` instance. + # @option opts [Boolean] :execute (true) execute promise before returning + # + # @return [Promise] + def zip(*others) + self.class.zip(self, *others) + end + + # Aggregates a collection of promises and executes the `then` condition + # if all aggregated promises succeed. Executes the `rescue` handler with + # a `Concurrent::PromiseExecutionError` if any of the aggregated promises + # fail. Upon execution will execute any of the aggregate promises that + # were not already executed. + # + # @!macro promise_self_aggregate + # + # The returned promise will not yet have been executed. Additional `#then` + # and `#rescue` handlers may still be provided. Once the returned promise + # is execute the aggregate promises will be also be executed (if they have + # not been executed already). The results of the aggregate promises will + # be checked upon completion. The necessary `#then` and `#rescue` blocks + # on the aggregating promise will then be executed as appropriate. If the + # `#rescue` handlers are executed the raises exception will be + # `Concurrent::PromiseExecutionError`. + # + # @param [Array] promises Zero or more promises to aggregate + # @return [Promise] an unscheduled (not executed) promise that aggregates + # the promises given as arguments + def self.all?(*promises) + aggregate(:all?, *promises) + end + + # Aggregates a collection of promises and executes the `then` condition + # if any aggregated promises succeed. Executes the `rescue` handler with + # a `Concurrent::PromiseExecutionError` if any of the aggregated promises + # fail. Upon execution will execute any of the aggregate promises that + # were not already executed. + # + # @!macro promise_self_aggregate + def self.any?(*promises) + aggregate(:any?, *promises) + end + + protected + + def ns_initialize(value, opts) + super + + @executor = Options.executor_from_options(opts) || Concurrent.global_io_executor + @args = get_arguments_from(opts) + + @parent = opts.fetch(:parent) { nil } + @on_fulfill = opts.fetch(:on_fulfill) { Proc.new { |result| result } } + @on_reject = opts.fetch(:on_reject) { Proc.new { |reason| raise reason } } + + @promise_body = opts[:__promise_body_from_block__] || Proc.new { |result| result } + @state = :unscheduled + @children = [] + end + + # Aggregate a collection of zero or more promises under a composite promise, + # execute the aggregated promises and collect them into a standard Ruby array, + # call the given Ruby `Ennnumerable` predicate (such as `any?`, `all?`, `none?`, + # or `one?`) on the collection checking for the success or failure of each, + # then executing the composite's `#then` handlers if the predicate returns + # `true` or executing the composite's `#rescue` handlers if the predicate + # returns false. + # + # @!macro promise_self_aggregate + def self.aggregate(method, *promises) + composite = Promise.new do + completed = promises.collect do |promise| + promise.execute if promise.unscheduled? + promise.wait + promise + end + unless completed.empty? || completed.send(method){|promise| promise.fulfilled? } + raise PromiseExecutionError + end + end + composite + end + + # @!visibility private + def set_pending + synchronize do + @state = :pending + @children.each { |c| c.set_pending } + end + end + + # @!visibility private + def root? # :nodoc: + @parent.nil? + end + + # @!visibility private + def on_fulfill(result) + realize Proc.new { @on_fulfill.call(result) } + nil + end + + # @!visibility private + def on_reject(reason) + realize Proc.new { @on_reject.call(reason) } + nil + end + + # @!visibility private + def notify_child(child) + if_state(:fulfilled) { child.on_fulfill(apply_deref_options(@value)) } + if_state(:rejected) { child.on_reject(@reason) } + end + + # @!visibility private + def complete(success, value, reason) + children_to_notify = synchronize do + set_state!(success, value, reason) + @children.dup + end + + children_to_notify.each { |child| notify_child(child) } + observers.notify_and_delete_observers{ [Time.now, self.value, reason] } + end + + # @!visibility private + def realize(task) + @executor.post do + success, value, reason = SafeTaskExecutor.new(task, rescue_exception: true).execute(*@args) + complete(success, value, reason) + end + end + + # @!visibility private + def set_state!(success, value, reason) + set_state(success, value, reason) + event.set + end + + # @!visibility private + def synchronized_set_state!(success, value, reason) + synchronize { set_state!(success, value, reason) } + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/promises.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/promises.rb new file mode 100644 index 00000000..c5df8fe9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/promises.rb @@ -0,0 +1,2178 @@ +require 'concurrent/synchronization/object' +require 'concurrent/atomic/atomic_boolean' +require 'concurrent/atomic/atomic_fixnum' +require 'concurrent/collection/lock_free_stack' +require 'concurrent/configuration' +require 'concurrent/errors' +require 'concurrent/re_include' +require 'concurrent/utility/monotonic_time' + +module Concurrent + + # {include:file:docs-source/promises-main.md} + module Promises + + # @!macro promises.param.default_executor + # @param [Executor, :io, :fast] default_executor Instance of an executor or a name of the + # global executor. Default executor propagates to chained futures unless overridden with + # executor parameter or changed with {AbstractEventFuture#with_default_executor}. + # + # @!macro promises.param.executor + # @param [Executor, :io, :fast] executor Instance of an executor or a name of the + # global executor. The task is executed on it, default executor remains unchanged. + # + # @!macro promises.param.args + # @param [Object] args arguments which are passed to the task when it's executed. + # (It might be prepended with other arguments, see the @yield section). + # + # @!macro promises.shortcut.on + # Shortcut of {#$0_on} with default `:io` executor supplied. + # @see #$0_on + # + # @!macro promises.shortcut.using + # Shortcut of {#$0_using} with default `:io` executor supplied. + # @see #$0_using + # + # @!macro promise.param.task-future + # @yieldreturn will become result of the returned Future. + # Its returned value becomes {Future#value} fulfilling it, + # raised exception becomes {Future#reason} rejecting it. + # + # @!macro promise.param.callback + # @yieldreturn is forgotten. + + # Container of all {Future}, {Event} factory methods. They are never constructed directly with + # new. + module FactoryMethods + extend ReInclude + extend self + + module Configuration + # @return [Executor, :io, :fast] the executor which is used when none is supplied + # to a factory method. The method can be overridden in the receivers of + # `include FactoryMethod` + def default_executor + :io + end + end + + include Configuration + + # @!macro promises.shortcut.on + # @return [ResolvableEvent] + def resolvable_event + resolvable_event_on default_executor + end + + # Creates a resolvable event, user is responsible for resolving the event once + # by calling {Promises::ResolvableEvent#resolve}. + # + # @!macro promises.param.default_executor + # @return [ResolvableEvent] + def resolvable_event_on(default_executor = self.default_executor) + ResolvableEventPromise.new(default_executor).future + end + + # @!macro promises.shortcut.on + # @return [ResolvableFuture] + def resolvable_future + resolvable_future_on default_executor + end + + # Creates resolvable future, user is responsible for resolving the future once by + # {Promises::ResolvableFuture#resolve}, {Promises::ResolvableFuture#fulfill}, + # or {Promises::ResolvableFuture#reject} + # + # @!macro promises.param.default_executor + # @return [ResolvableFuture] + def resolvable_future_on(default_executor = self.default_executor) + ResolvableFuturePromise.new(default_executor).future + end + + # @!macro promises.shortcut.on + # @return [Future] + def future(*args, &task) + future_on(default_executor, *args, &task) + end + + # Constructs a new Future which will be resolved after block is evaluated on default executor. + # Evaluation begins immediately. + # + # @!macro promises.param.default_executor + # @!macro promises.param.args + # @yield [*args] to the task. + # @!macro promise.param.task-future + # @return [Future] + def future_on(default_executor, *args, &task) + ImmediateEventPromise.new(default_executor).future.then(*args, &task) + end + + # Creates a resolved future with will be either fulfilled with the given value or rejected with + # the given reason. + # + # @param [true, false] fulfilled + # @param [Object] value + # @param [Object] reason + # @!macro promises.param.default_executor + # @return [Future] + def resolved_future(fulfilled, value, reason, default_executor = self.default_executor) + ImmediateFuturePromise.new(default_executor, fulfilled, value, reason).future + end + + # Creates a resolved future which will be fulfilled with the given value. + # + # @!macro promises.param.default_executor + # @param [Object] value + # @return [Future] + def fulfilled_future(value, default_executor = self.default_executor) + resolved_future true, value, nil, default_executor + end + + # Creates a resolved future which will be rejected with the given reason. + # + # @!macro promises.param.default_executor + # @param [Object] reason + # @return [Future] + def rejected_future(reason, default_executor = self.default_executor) + resolved_future false, nil, reason, default_executor + end + + # Creates resolved event. + # + # @!macro promises.param.default_executor + # @return [Event] + def resolved_event(default_executor = self.default_executor) + ImmediateEventPromise.new(default_executor).event + end + + # General constructor. Behaves differently based on the argument's type. It's provided for convenience + # but it's better to be explicit. + # + # @see rejected_future, resolved_event, fulfilled_future + # @!macro promises.param.default_executor + # @return [Event, Future] + # + # @overload make_future(nil, default_executor = self.default_executor) + # @param [nil] nil + # @return [Event] resolved event. + # + # @overload make_future(a_future, default_executor = self.default_executor) + # @param [Future] a_future + # @return [Future] a future which will be resolved when a_future is. + # + # @overload make_future(an_event, default_executor = self.default_executor) + # @param [Event] an_event + # @return [Event] an event which will be resolved when an_event is. + # + # @overload make_future(exception, default_executor = self.default_executor) + # @param [Exception] exception + # @return [Future] a rejected future with the exception as its reason. + # + # @overload make_future(value, default_executor = self.default_executor) + # @param [Object] value when none of the above overloads fits + # @return [Future] a fulfilled future with the value. + def make_future(argument = nil, default_executor = self.default_executor) + case argument + when AbstractEventFuture + # returning wrapper would change nothing + argument + when Exception + rejected_future argument, default_executor + when nil + resolved_event default_executor + else + fulfilled_future argument, default_executor + end + end + + # @!macro promises.shortcut.on + # @return [Future, Event] + def delay(*args, &task) + delay_on default_executor, *args, &task + end + + # Creates a new event or future which is resolved only after it is touched, + # see {Concurrent::AbstractEventFuture#touch}. + # + # @!macro promises.param.default_executor + # @overload delay_on(default_executor, *args, &task) + # If task is provided it returns a {Future} representing the result of the task. + # @!macro promises.param.args + # @yield [*args] to the task. + # @!macro promise.param.task-future + # @return [Future] + # @overload delay_on(default_executor) + # If no task is provided, it returns an {Event} + # @return [Event] + def delay_on(default_executor, *args, &task) + event = DelayPromise.new(default_executor).event + task ? event.chain(*args, &task) : event + end + + # @!macro promises.shortcut.on + # @return [Future, Event] + def schedule(intended_time, *args, &task) + schedule_on default_executor, intended_time, *args, &task + end + + # Creates a new event or future which is resolved in intended_time. + # + # @!macro promises.param.default_executor + # @!macro promises.param.intended_time + # @param [Numeric, Time] intended_time `Numeric` means to run in `intended_time` seconds. + # `Time` means to run on `intended_time`. + # @overload schedule_on(default_executor, intended_time, *args, &task) + # If task is provided it returns a {Future} representing the result of the task. + # @!macro promises.param.args + # @yield [*args] to the task. + # @!macro promise.param.task-future + # @return [Future] + # @overload schedule_on(default_executor, intended_time) + # If no task is provided, it returns an {Event} + # @return [Event] + def schedule_on(default_executor, intended_time, *args, &task) + event = ScheduledPromise.new(default_executor, intended_time).event + task ? event.chain(*args, &task) : event + end + + # @!macro promises.shortcut.on + # @return [Future] + def zip_futures(*futures_and_or_events) + zip_futures_on default_executor, *futures_and_or_events + end + + # Creates a new future which is resolved after all futures_and_or_events are resolved. + # Its value is an array of zipped future values. Its reason is an array of reasons for rejection. + # If there is an error it rejects. + # @!macro promises.event-conversion + # If event is supplied, which does not have value and can be only resolved, it's + # represented as `:fulfilled` with value `nil`. + # + # @!macro promises.param.default_executor + # @param [AbstractEventFuture] futures_and_or_events + # @return [Future] + def zip_futures_on(default_executor, *futures_and_or_events) + ZipFuturesPromise.new_blocked_by(futures_and_or_events, default_executor).future + end + + alias_method :zip, :zip_futures + + # @!macro promises.shortcut.on + # @return [Event] + def zip_events(*futures_and_or_events) + zip_events_on default_executor, *futures_and_or_events + end + + # Creates a new event which is resolved after all futures_and_or_events are resolved. + # (Future is resolved when fulfilled or rejected.) + # + # @!macro promises.param.default_executor + # @param [AbstractEventFuture] futures_and_or_events + # @return [Event] + def zip_events_on(default_executor, *futures_and_or_events) + ZipEventsPromise.new_blocked_by(futures_and_or_events, default_executor).event + end + + # @!macro promises.shortcut.on + # @return [Future] + def any_resolved_future(*futures_and_or_events) + any_resolved_future_on default_executor, *futures_and_or_events + end + + alias_method :any, :any_resolved_future + + # Creates a new future which is resolved after the first futures_and_or_events is resolved. + # Its result equals the result of the first resolved future. + # @!macro promises.any-touch + # If resolved it does not propagate {Concurrent::AbstractEventFuture#touch}, leaving delayed + # futures un-executed if they are not required any more. + # @!macro promises.event-conversion + # + # @!macro promises.param.default_executor + # @param [AbstractEventFuture] futures_and_or_events + # @return [Future] + def any_resolved_future_on(default_executor, *futures_and_or_events) + AnyResolvedFuturePromise.new_blocked_by(futures_and_or_events, default_executor).future + end + + # @!macro promises.shortcut.on + # @return [Future] + def any_fulfilled_future(*futures_and_or_events) + any_fulfilled_future_on default_executor, *futures_and_or_events + end + + # Creates a new future which is resolved after the first futures_and_or_events is fulfilled. + # Its result equals the result of the first resolved future or if all futures_and_or_events reject, + # it has reason of the last rejected future. + # @!macro promises.any-touch + # @!macro promises.event-conversion + # + # @!macro promises.param.default_executor + # @param [AbstractEventFuture] futures_and_or_events + # @return [Future] + def any_fulfilled_future_on(default_executor, *futures_and_or_events) + AnyFulfilledFuturePromise.new_blocked_by(futures_and_or_events, default_executor).future + end + + # @!macro promises.shortcut.on + # @return [Event] + def any_event(*futures_and_or_events) + any_event_on default_executor, *futures_and_or_events + end + + # Creates a new event which becomes resolved after the first futures_and_or_events resolves. + # @!macro promises.any-touch + # + # @!macro promises.param.default_executor + # @param [AbstractEventFuture] futures_and_or_events + # @return [Event] + def any_event_on(default_executor, *futures_and_or_events) + AnyResolvedEventPromise.new_blocked_by(futures_and_or_events, default_executor).event + end + + # TODO consider adding first(count, *futures) + # TODO consider adding zip_by(slice, *futures) processing futures in slices + # TODO or rather a generic aggregator taking a function + end + + module InternalStates + # @!visibility private + class State + def resolved? + raise NotImplementedError + end + + def to_sym + raise NotImplementedError + end + end + + # @!visibility private + class Pending < State + def resolved? + false + end + + def to_sym + :pending + end + end + + # @!visibility private + class Reserved < Pending + end + + # @!visibility private + class ResolvedWithResult < State + def resolved? + true + end + + def to_sym + :resolved + end + + def result + [fulfilled?, value, reason] + end + + def fulfilled? + raise NotImplementedError + end + + def value + raise NotImplementedError + end + + def reason + raise NotImplementedError + end + + def apply + raise NotImplementedError + end + end + + # @!visibility private + class Fulfilled < ResolvedWithResult + + def initialize(value) + @Value = value + end + + def fulfilled? + true + end + + def apply(args, block) + block.call value, *args + end + + def value + @Value + end + + def reason + nil + end + + def to_sym + :fulfilled + end + end + + # @!visibility private + class FulfilledArray < Fulfilled + def apply(args, block) + block.call(*value, *args) + end + end + + # @!visibility private + class Rejected < ResolvedWithResult + def initialize(reason) + @Reason = reason + end + + def fulfilled? + false + end + + def value + nil + end + + def reason + @Reason + end + + def to_sym + :rejected + end + + def apply(args, block) + block.call reason, *args + end + end + + # @!visibility private + class PartiallyRejected < ResolvedWithResult + def initialize(value, reason) + super() + @Value = value + @Reason = reason + end + + def fulfilled? + false + end + + def to_sym + :rejected + end + + def value + @Value + end + + def reason + @Reason + end + + def apply(args, block) + block.call(*reason, *args) + end + end + + # @!visibility private + PENDING = Pending.new + # @!visibility private + RESERVED = Reserved.new + # @!visibility private + RESOLVED = Fulfilled.new(nil) + + def RESOLVED.to_sym + :resolved + end + end + + private_constant :InternalStates + + # @!macro promises.shortcut.event-future + # @see Event#$0 + # @see Future#$0 + + # @!macro promises.param.timeout + # @param [Numeric] timeout the maximum time in second to wait. + + # @!macro promises.warn.blocks + # @note This function potentially blocks current thread until the Future is resolved. + # Be careful it can deadlock. Try to chain instead. + + # Common ancestor of {Event} and {Future} classes, many shared methods are defined here. + class AbstractEventFuture < Synchronization::Object + safe_initialization! + attr_atomic(:internal_state) + private :internal_state=, :swap_internal_state, :compare_and_set_internal_state, :update_internal_state + # @!method internal_state + # @!visibility private + + include InternalStates + + def initialize(promise, default_executor) + super() + @Lock = Mutex.new + @Condition = ConditionVariable.new + @Promise = promise + @DefaultExecutor = default_executor + @Callbacks = LockFreeStack.new + @Waiters = AtomicFixnum.new 0 + self.internal_state = PENDING + end + + private :initialize + + # Returns its state. + # @return [Symbol] + # + # @overload an_event.state + # @return [:pending, :resolved] + # @overload a_future.state + # Both :fulfilled, :rejected implies :resolved. + # @return [:pending, :fulfilled, :rejected] + def state + internal_state.to_sym + end + + # Is it in pending state? + # @return [Boolean] + def pending? + !internal_state.resolved? + end + + # Is it in resolved state? + # @return [Boolean] + def resolved? + internal_state.resolved? + end + + # Propagates touch. Requests all the delayed futures, which it depends on, to be + # executed. This method is called by any other method requiring resolved state, like {#wait}. + # @return [self] + def touch + @Promise.touch + self + end + + # @!macro promises.touches + # Calls {Concurrent::AbstractEventFuture#touch}. + + # @!macro promises.method.wait + # Wait (block the Thread) until receiver is {#resolved?}. + # @!macro promises.touches + # + # @!macro promises.warn.blocks + # @!macro promises.param.timeout + # @return [self, true, false] self implies timeout was not used, true implies timeout was used + # and it was resolved, false implies it was not resolved within timeout. + def wait(timeout = nil) + result = wait_until_resolved(timeout) + timeout ? result : self + end + + # Returns default executor. + # @return [Executor] default executor + # @see #with_default_executor + # @see FactoryMethods#future_on + # @see FactoryMethods#resolvable_future + # @see FactoryMethods#any_fulfilled_future_on + # @see similar + def default_executor + @DefaultExecutor + end + + # @!macro promises.shortcut.on + # @return [Future] + def chain(*args, &task) + chain_on @DefaultExecutor, *args, &task + end + + # Chains the task to be executed asynchronously on executor after it is resolved. + # + # @!macro promises.param.executor + # @!macro promises.param.args + # @return [Future] + # @!macro promise.param.task-future + # + # @overload an_event.chain_on(executor, *args, &task) + # @yield [*args] to the task. + # @overload a_future.chain_on(executor, *args, &task) + # @yield [fulfilled, value, reason, *args] to the task. + # @yieldparam [true, false] fulfilled + # @yieldparam [Object] value + # @yieldparam [Object] reason + def chain_on(executor, *args, &task) + ChainPromise.new_blocked_by1(self, executor, executor, args, &task).future + end + + # @return [String] Short string representation. + def to_s + format '%s %s>', super[0..-2], state + end + + alias_method :inspect, :to_s + + # Resolves the resolvable when receiver is resolved. + # + # @param [Resolvable] resolvable + # @return [self] + def chain_resolvable(resolvable) + on_resolution! { resolvable.resolve_with internal_state } + end + + alias_method :tangle, :chain_resolvable + + # @!macro promises.shortcut.using + # @return [self] + def on_resolution(*args, &callback) + on_resolution_using @DefaultExecutor, *args, &callback + end + + # Stores the callback to be executed synchronously on resolving thread after it is + # resolved. + # + # @!macro promises.param.args + # @!macro promise.param.callback + # @return [self] + # + # @overload an_event.on_resolution!(*args, &callback) + # @yield [*args] to the callback. + # @overload a_future.on_resolution!(*args, &callback) + # @yield [fulfilled, value, reason, *args] to the callback. + # @yieldparam [true, false] fulfilled + # @yieldparam [Object] value + # @yieldparam [Object] reason + def on_resolution!(*args, &callback) + add_callback :callback_on_resolution, args, callback + end + + # Stores the callback to be executed asynchronously on executor after it is resolved. + # + # @!macro promises.param.executor + # @!macro promises.param.args + # @!macro promise.param.callback + # @return [self] + # + # @overload an_event.on_resolution_using(executor, *args, &callback) + # @yield [*args] to the callback. + # @overload a_future.on_resolution_using(executor, *args, &callback) + # @yield [fulfilled, value, reason, *args] to the callback. + # @yieldparam [true, false] fulfilled + # @yieldparam [Object] value + # @yieldparam [Object] reason + def on_resolution_using(executor, *args, &callback) + add_callback :async_callback_on_resolution, executor, args, callback + end + + # @!macro promises.method.with_default_executor + # Crates new object with same class with the executor set as its new default executor. + # Any futures depending on it will use the new default executor. + # @!macro promises.shortcut.event-future + # @abstract + # @return [AbstractEventFuture] + def with_default_executor(executor) + raise NotImplementedError + end + + # @!visibility private + def resolve_with(state, raise_on_reassign = true, reserved = false) + if compare_and_set_internal_state(reserved ? RESERVED : PENDING, state) + # go to synchronized block only if there were waiting threads + @Lock.synchronize { @Condition.broadcast } unless @Waiters.value == 0 + call_callbacks state + else + return rejected_resolution(raise_on_reassign, state) + end + self + end + + # For inspection. + # @!visibility private + # @return [Array] + def blocks + @Callbacks.each_with_object([]) do |(method, args), promises| + promises.push(args[0]) if method == :callback_notify_blocked + end + end + + # For inspection. + # @!visibility private + def callbacks + @Callbacks.each.to_a + end + + # For inspection. + # @!visibility private + def promise + @Promise + end + + # For inspection. + # @!visibility private + def touched? + promise.touched? + end + + # For inspection. + # @!visibility private + def waiting_threads + @Waiters.each.to_a + end + + # @!visibility private + def add_callback_notify_blocked(promise, index) + add_callback :callback_notify_blocked, promise, index + end + + # @!visibility private + def add_callback_clear_delayed_node(node) + add_callback(:callback_clear_delayed_node, node) + end + + # @!visibility private + def with_hidden_resolvable + # TODO (pitr-ch 10-Dec-2018): documentation, better name if in edge + self + end + + private + + def add_callback(method, *args) + state = internal_state + if state.resolved? + call_callback method, state, args + else + @Callbacks.push [method, args] + state = internal_state + # take back if it was resolved in the meanwhile + call_callbacks state if state.resolved? + end + self + end + + def callback_clear_delayed_node(state, node) + node.value = nil + end + + # @return [Boolean] + def wait_until_resolved(timeout) + return true if resolved? + + touch + + @Lock.synchronize do + @Waiters.increment + begin + if timeout + start = Concurrent.monotonic_time + until resolved? + break if @Condition.wait(@Lock, timeout) == nil # nil means timeout + timeout -= (Concurrent.monotonic_time - start) + break if timeout <= 0 + end + else + until resolved? + @Condition.wait(@Lock, timeout) + end + end + ensure + # JRuby may raise ConcurrencyError + @Waiters.decrement + end + end + resolved? + end + + def call_callback(method, state, args) + self.send method, state, *args + end + + def call_callbacks(state) + method, args = @Callbacks.pop + while method + call_callback method, state, args + method, args = @Callbacks.pop + end + end + + def with_async(executor, *args, &block) + Concurrent.executor(executor).post(*args, &block) + end + + def async_callback_on_resolution(state, executor, args, callback) + with_async(executor, state, args, callback) do |st, ar, cb| + callback_on_resolution st, ar, cb + end + end + + def callback_notify_blocked(state, promise, index) + promise.on_blocker_resolution self, index + end + end + + # Represents an event which will happen in future (will be resolved). The event is either + # pending or resolved. It should be always resolved. Use {Future} to communicate rejections and + # cancellation. + class Event < AbstractEventFuture + + alias_method :then, :chain + + + # @!macro promises.method.zip + # Creates a new event or a future which will be resolved when receiver and other are. + # Returns an event if receiver and other are events, otherwise returns a future. + # If just one of the parties is Future then the result + # of the returned future is equal to the result of the supplied future. If both are futures + # then the result is as described in {FactoryMethods#zip_futures_on}. + # + # @return [Future, Event] + def zip(other) + if other.is_a?(Future) + ZipFutureEventPromise.new_blocked_by2(other, self, @DefaultExecutor).future + else + ZipEventEventPromise.new_blocked_by2(self, other, @DefaultExecutor).event + end + end + + alias_method :&, :zip + + # Creates a new event which will be resolved when the first of receiver, `event_or_future` + # resolves. + # + # @return [Event] + def any(event_or_future) + AnyResolvedEventPromise.new_blocked_by2(self, event_or_future, @DefaultExecutor).event + end + + alias_method :|, :any + + # Creates new event dependent on receiver which will not evaluate until touched, see {#touch}. + # In other words, it inserts delay into the chain of Futures making rest of it lazy evaluated. + # + # @return [Event] + def delay + event = DelayPromise.new(@DefaultExecutor).event + ZipEventEventPromise.new_blocked_by2(self, event, @DefaultExecutor).event + end + + # @!macro promise.method.schedule + # Creates new event dependent on receiver scheduled to execute on/in intended_time. + # In time is interpreted from the moment the receiver is resolved, therefore it inserts + # delay into the chain. + # + # @!macro promises.param.intended_time + # @return [Event] + def schedule(intended_time) + chain do + event = ScheduledPromise.new(@DefaultExecutor, intended_time).event + ZipEventEventPromise.new_blocked_by2(self, event, @DefaultExecutor).event + end.flat_event + end + + # Converts event to a future. The future is fulfilled when the event is resolved, the future may never fail. + # + # @return [Future] + def to_future + future = Promises.resolvable_future + ensure + chain_resolvable(future) + end + + # Returns self, since this is event + # @return [Event] + def to_event + self + end + + # @!macro promises.method.with_default_executor + # @return [Event] + def with_default_executor(executor) + EventWrapperPromise.new_blocked_by1(self, executor).event + end + + private + + def rejected_resolution(raise_on_reassign, state) + raise Concurrent::MultipleAssignmentError.new('Event can be resolved only once') if raise_on_reassign + return false + end + + def callback_on_resolution(state, args, callback) + callback.call(*args) + end + end + + # Represents a value which will become available in future. May reject with a reason instead, + # e.g. when the tasks raises an exception. + class Future < AbstractEventFuture + + # Is it in fulfilled state? + # @return [Boolean] + def fulfilled? + state = internal_state + state.resolved? && state.fulfilled? + end + + # Is it in rejected state? + # @return [Boolean] + def rejected? + state = internal_state + state.resolved? && !state.fulfilled? + end + + # @!macro promises.warn.nil + # @note Make sure returned `nil` is not confused with timeout, no value when rejected, + # no reason when fulfilled, etc. + # Use more exact methods if needed, like {#wait}, {#value!}, {#result}, etc. + + # @!macro promises.method.value + # Return value of the future. + # @!macro promises.touches + # + # @!macro promises.warn.blocks + # @!macro promises.warn.nil + # @!macro promises.param.timeout + # @!macro promises.param.timeout_value + # @param [Object] timeout_value a value returned by the method when it times out + # @return [Object, nil, timeout_value] the value of the Future when fulfilled, + # timeout_value on timeout, + # nil on rejection. + def value(timeout = nil, timeout_value = nil) + if wait_until_resolved timeout + internal_state.value + else + timeout_value + end + end + + # Returns reason of future's rejection. + # @!macro promises.touches + # + # @!macro promises.warn.blocks + # @!macro promises.warn.nil + # @!macro promises.param.timeout + # @!macro promises.param.timeout_value + # @return [Object, timeout_value] the reason, or timeout_value on timeout, or nil on fulfillment. + def reason(timeout = nil, timeout_value = nil) + if wait_until_resolved timeout + internal_state.reason + else + timeout_value + end + end + + # Returns triplet fulfilled?, value, reason. + # @!macro promises.touches + # + # @!macro promises.warn.blocks + # @!macro promises.param.timeout + # @return [Array(Boolean, Object, Object), nil] triplet of fulfilled?, value, reason, or nil + # on timeout. + def result(timeout = nil) + internal_state.result if wait_until_resolved timeout + end + + # @!macro promises.method.wait + # @raise [Exception] {#reason} on rejection + def wait!(timeout = nil) + result = wait_until_resolved!(timeout) + timeout ? result : self + end + + # @!macro promises.method.value + # @return [Object, nil, timeout_value] the value of the Future when fulfilled, + # or nil on rejection, + # or timeout_value on timeout. + # @raise [Exception] {#reason} on rejection + def value!(timeout = nil, timeout_value = nil) + if wait_until_resolved! timeout + internal_state.value + else + timeout_value + end + end + + # Allows rejected Future to be risen with `raise` method. + # If the reason is not an exception `Runtime.new(reason)` is returned. + # + # @example + # raise Promises.rejected_future(StandardError.new("boom")) + # raise Promises.rejected_future("or just boom") + # @raise [Concurrent::Error] when raising not rejected future + # @return [Exception] + def exception(*args) + raise Concurrent::Error, 'it is not rejected' unless rejected? + raise ArgumentError unless args.size <= 1 + reason = Array(internal_state.reason).flatten.compact + if reason.size > 1 + ex = Concurrent::MultipleErrors.new reason + ex.set_backtrace(caller) + ex + else + ex = if reason[0].respond_to? :exception + reason[0].exception(*args) + else + RuntimeError.new(reason[0]).exception(*args) + end + ex.set_backtrace Array(ex.backtrace) + caller + ex + end + end + + # @!macro promises.shortcut.on + # @return [Future] + def then(*args, &task) + then_on @DefaultExecutor, *args, &task + end + + # Chains the task to be executed asynchronously on executor after it fulfills. Does not run + # the task if it rejects. It will resolve though, triggering any dependent futures. + # + # @!macro promises.param.executor + # @!macro promises.param.args + # @!macro promise.param.task-future + # @return [Future] + # @yield [value, *args] to the task. + def then_on(executor, *args, &task) + ThenPromise.new_blocked_by1(self, executor, executor, args, &task).future + end + + # @!macro promises.shortcut.on + # @return [Future] + def rescue(*args, &task) + rescue_on @DefaultExecutor, *args, &task + end + + # Chains the task to be executed asynchronously on executor after it rejects. Does not run + # the task if it fulfills. It will resolve though, triggering any dependent futures. + # + # @!macro promises.param.executor + # @!macro promises.param.args + # @!macro promise.param.task-future + # @return [Future] + # @yield [reason, *args] to the task. + def rescue_on(executor, *args, &task) + RescuePromise.new_blocked_by1(self, executor, executor, args, &task).future + end + + # @!macro promises.method.zip + # @return [Future] + def zip(other) + if other.is_a?(Future) + ZipFuturesPromise.new_blocked_by2(self, other, @DefaultExecutor).future + else + ZipFutureEventPromise.new_blocked_by2(self, other, @DefaultExecutor).future + end + end + + alias_method :&, :zip + + # Creates a new event which will be resolved when the first of receiver, `event_or_future` + # resolves. Returning future will have value nil if event_or_future is event and resolves + # first. + # + # @return [Future] + def any(event_or_future) + AnyResolvedFuturePromise.new_blocked_by2(self, event_or_future, @DefaultExecutor).future + end + + alias_method :|, :any + + # Creates new future dependent on receiver which will not evaluate until touched, see {#touch}. + # In other words, it inserts delay into the chain of Futures making rest of it lazy evaluated. + # + # @return [Future] + def delay + event = DelayPromise.new(@DefaultExecutor).event + ZipFutureEventPromise.new_blocked_by2(self, event, @DefaultExecutor).future + end + + # @!macro promise.method.schedule + # @return [Future] + def schedule(intended_time) + chain do + event = ScheduledPromise.new(@DefaultExecutor, intended_time).event + ZipFutureEventPromise.new_blocked_by2(self, event, @DefaultExecutor).future + end.flat + end + + # @!macro promises.method.with_default_executor + # @return [Future] + def with_default_executor(executor) + FutureWrapperPromise.new_blocked_by1(self, executor).future + end + + # Creates new future which will have result of the future returned by receiver. If receiver + # rejects it will have its rejection. + # + # @param [Integer] level how many levels of futures should flatten + # @return [Future] + def flat_future(level = 1) + FlatFuturePromise.new_blocked_by1(self, level, @DefaultExecutor).future + end + + alias_method :flat, :flat_future + + # Creates new event which will be resolved when the returned event by receiver is. + # Be careful if the receiver rejects it will just resolve since Event does not hold reason. + # + # @return [Event] + def flat_event + FlatEventPromise.new_blocked_by1(self, @DefaultExecutor).event + end + + # @!macro promises.shortcut.using + # @return [self] + def on_fulfillment(*args, &callback) + on_fulfillment_using @DefaultExecutor, *args, &callback + end + + # Stores the callback to be executed synchronously on resolving thread after it is + # fulfilled. Does nothing on rejection. + # + # @!macro promises.param.args + # @!macro promise.param.callback + # @return [self] + # @yield [value, *args] to the callback. + def on_fulfillment!(*args, &callback) + add_callback :callback_on_fulfillment, args, callback + end + + # Stores the callback to be executed asynchronously on executor after it is + # fulfilled. Does nothing on rejection. + # + # @!macro promises.param.executor + # @!macro promises.param.args + # @!macro promise.param.callback + # @return [self] + # @yield [value, *args] to the callback. + def on_fulfillment_using(executor, *args, &callback) + add_callback :async_callback_on_fulfillment, executor, args, callback + end + + # @!macro promises.shortcut.using + # @return [self] + def on_rejection(*args, &callback) + on_rejection_using @DefaultExecutor, *args, &callback + end + + # Stores the callback to be executed synchronously on resolving thread after it is + # rejected. Does nothing on fulfillment. + # + # @!macro promises.param.args + # @!macro promise.param.callback + # @return [self] + # @yield [reason, *args] to the callback. + def on_rejection!(*args, &callback) + add_callback :callback_on_rejection, args, callback + end + + # Stores the callback to be executed asynchronously on executor after it is + # rejected. Does nothing on fulfillment. + # + # @!macro promises.param.executor + # @!macro promises.param.args + # @!macro promise.param.callback + # @return [self] + # @yield [reason, *args] to the callback. + def on_rejection_using(executor, *args, &callback) + add_callback :async_callback_on_rejection, executor, args, callback + end + + # Allows to use futures as green threads. The receiver has to evaluate to a future which + # represents what should be done next. It basically flattens indefinitely until non Future + # values is returned which becomes result of the returned future. Any encountered exception + # will become reason of the returned future. + # + # @return [Future] + # @param [#call(value)] run_test + # an object which when called returns either Future to keep running with + # or nil, then the run completes with the value. + # The run_test can be used to extract the Future from deeper structure, + # or to distinguish Future which is a resulting value from a future + # which is suppose to continue running. + # @example + # body = lambda do |v| + # v += 1 + # v < 5 ? Promises.future(v, &body) : v + # end + # Promises.future(0, &body).run.value! # => 5 + def run(run_test = method(:run_test)) + RunFuturePromise.new_blocked_by1(self, @DefaultExecutor, run_test).future + end + + # @!visibility private + def apply(args, block) + internal_state.apply args, block + end + + # Converts future to event which is resolved when future is resolved by fulfillment or rejection. + # + # @return [Event] + def to_event + event = Promises.resolvable_event + ensure + chain_resolvable(event) + end + + # Returns self, since this is a future + # @return [Future] + def to_future + self + end + + # @return [String] Short string representation. + def to_s + if resolved? + format '%s with %s>', super[0..-2], (fulfilled? ? value : reason).inspect + else + super + end + end + + alias_method :inspect, :to_s + + private + + def run_test(v) + v if v.is_a?(Future) + end + + def rejected_resolution(raise_on_reassign, state) + if raise_on_reassign + if internal_state == RESERVED + raise Concurrent::MultipleAssignmentError.new( + "Future can be resolved only once. It is already reserved.") + else + raise Concurrent::MultipleAssignmentError.new( + "Future can be resolved only once. It's #{result}, trying to set #{state.result}.", + current_result: result, + new_result: state.result) + end + end + return false + end + + def wait_until_resolved!(timeout = nil) + result = wait_until_resolved(timeout) + raise self if rejected? + result + end + + def async_callback_on_fulfillment(state, executor, args, callback) + with_async(executor, state, args, callback) do |st, ar, cb| + callback_on_fulfillment st, ar, cb + end + end + + def async_callback_on_rejection(state, executor, args, callback) + with_async(executor, state, args, callback) do |st, ar, cb| + callback_on_rejection st, ar, cb + end + end + + def callback_on_fulfillment(state, args, callback) + state.apply args, callback if state.fulfilled? + end + + def callback_on_rejection(state, args, callback) + state.apply args, callback unless state.fulfilled? + end + + def callback_on_resolution(state, args, callback) + callback.call(*state.result, *args) + end + + end + + # Marker module of Future, Event resolved manually. + module Resolvable + include InternalStates + end + + # A Event which can be resolved by user. + class ResolvableEvent < Event + include Resolvable + + # @!macro raise_on_reassign + # @raise [MultipleAssignmentError] when already resolved and raise_on_reassign is true. + + # @!macro promise.param.raise_on_reassign + # @param [Boolean] raise_on_reassign should method raise exception if already resolved + # @return [self, false] false is returned when raise_on_reassign is false and the receiver + # is already resolved. + # + + # Makes the event resolved, which triggers all dependent futures. + # + # @!macro promise.param.raise_on_reassign + # @!macro promise.param.reserved + # @param [true, false] reserved + # Set to true if the resolvable is {#reserve}d by you, + # marks resolution of reserved resolvable events and futures explicitly. + # Advanced feature, ignore unless you use {Resolvable#reserve} from edge. + def resolve(raise_on_reassign = true, reserved = false) + resolve_with RESOLVED, raise_on_reassign, reserved + end + + # Creates new event wrapping receiver, effectively hiding the resolve method. + # + # @return [Event] + def with_hidden_resolvable + @with_hidden_resolvable ||= EventWrapperPromise.new_blocked_by1(self, @DefaultExecutor).event + end + + # Behaves as {AbstractEventFuture#wait} but has one additional optional argument + # resolve_on_timeout. + # + # @param [true, false] resolve_on_timeout + # If it times out and the argument is true it will also resolve the event. + # @return [self, true, false] + # @see AbstractEventFuture#wait + def wait(timeout = nil, resolve_on_timeout = false) + super(timeout) or if resolve_on_timeout + # if it fails to resolve it was resolved in the meantime + # so return true as if there was no timeout + !resolve(false) + else + false + end + end + end + + # A Future which can be resolved by user. + class ResolvableFuture < Future + include Resolvable + + # Makes the future resolved with result of triplet `fulfilled?`, `value`, `reason`, + # which triggers all dependent futures. + # + # @param [true, false] fulfilled + # @param [Object] value + # @param [Object] reason + # @!macro promise.param.raise_on_reassign + # @!macro promise.param.reserved + def resolve(fulfilled = true, value = nil, reason = nil, raise_on_reassign = true, reserved = false) + resolve_with(fulfilled ? Fulfilled.new(value) : Rejected.new(reason), raise_on_reassign, reserved) + end + + # Makes the future fulfilled with `value`, + # which triggers all dependent futures. + # + # @param [Object] value + # @!macro promise.param.raise_on_reassign + # @!macro promise.param.reserved + def fulfill(value, raise_on_reassign = true, reserved = false) + resolve_with Fulfilled.new(value), raise_on_reassign, reserved + end + + # Makes the future rejected with `reason`, + # which triggers all dependent futures. + # + # @param [Object] reason + # @!macro promise.param.raise_on_reassign + # @!macro promise.param.reserved + def reject(reason, raise_on_reassign = true, reserved = false) + resolve_with Rejected.new(reason), raise_on_reassign, reserved + end + + # Evaluates the block and sets its result as future's value fulfilling, if the block raises + # an exception the future rejects with it. + # + # @yield [*args] to the block. + # @yieldreturn [Object] value + # @return [self] + def evaluate_to(*args, &block) + promise.evaluate_to(*args, block) + end + + # Evaluates the block and sets its result as future's value fulfilling, if the block raises + # an exception the future rejects with it. + # + # @yield [*args] to the block. + # @yieldreturn [Object] value + # @return [self] + # @raise [Exception] also raise reason on rejection. + def evaluate_to!(*args, &block) + promise.evaluate_to(*args, block).wait! + end + + # @!macro promises.resolvable.resolve_on_timeout + # @param [::Array(true, Object, nil), ::Array(false, nil, Exception), nil] resolve_on_timeout + # If it times out and the argument is not nil it will also resolve the future + # to the provided resolution. + + # Behaves as {AbstractEventFuture#wait} but has one additional optional argument + # resolve_on_timeout. + # + # @!macro promises.resolvable.resolve_on_timeout + # @return [self, true, false] + # @see AbstractEventFuture#wait + def wait(timeout = nil, resolve_on_timeout = nil) + super(timeout) or if resolve_on_timeout + # if it fails to resolve it was resolved in the meantime + # so return true as if there was no timeout + !resolve(*resolve_on_timeout, false) + else + false + end + end + + # Behaves as {Future#wait!} but has one additional optional argument + # resolve_on_timeout. + # + # @!macro promises.resolvable.resolve_on_timeout + # @return [self, true, false] + # @raise [Exception] {#reason} on rejection + # @see Future#wait! + def wait!(timeout = nil, resolve_on_timeout = nil) + super(timeout) or if resolve_on_timeout + if resolve(*resolve_on_timeout, false) + false + else + # if it fails to resolve it was resolved in the meantime + # so return true as if there was no timeout + raise self if rejected? + true + end + else + false + end + end + + # Behaves as {Future#value} but has one additional optional argument + # resolve_on_timeout. + # + # @!macro promises.resolvable.resolve_on_timeout + # @return [Object, timeout_value, nil] + # @see Future#value + def value(timeout = nil, timeout_value = nil, resolve_on_timeout = nil) + if wait_until_resolved timeout + internal_state.value + else + if resolve_on_timeout + unless resolve(*resolve_on_timeout, false) + # if it fails to resolve it was resolved in the meantime + # so return value as if there was no timeout + return internal_state.value + end + end + timeout_value + end + end + + # Behaves as {Future#value!} but has one additional optional argument + # resolve_on_timeout. + # + # @!macro promises.resolvable.resolve_on_timeout + # @return [Object, timeout_value, nil] + # @raise [Exception] {#reason} on rejection + # @see Future#value! + def value!(timeout = nil, timeout_value = nil, resolve_on_timeout = nil) + if wait_until_resolved! timeout + internal_state.value + else + if resolve_on_timeout + unless resolve(*resolve_on_timeout, false) + # if it fails to resolve it was resolved in the meantime + # so return value as if there was no timeout + raise self if rejected? + return internal_state.value + end + end + timeout_value + end + end + + # Behaves as {Future#reason} but has one additional optional argument + # resolve_on_timeout. + # + # @!macro promises.resolvable.resolve_on_timeout + # @return [Exception, timeout_value, nil] + # @see Future#reason + def reason(timeout = nil, timeout_value = nil, resolve_on_timeout = nil) + if wait_until_resolved timeout + internal_state.reason + else + if resolve_on_timeout + unless resolve(*resolve_on_timeout, false) + # if it fails to resolve it was resolved in the meantime + # so return value as if there was no timeout + return internal_state.reason + end + end + timeout_value + end + end + + # Behaves as {Future#result} but has one additional optional argument + # resolve_on_timeout. + # + # @!macro promises.resolvable.resolve_on_timeout + # @return [::Array(Boolean, Object, Exception), nil] + # @see Future#result + def result(timeout = nil, resolve_on_timeout = nil) + if wait_until_resolved timeout + internal_state.result + else + if resolve_on_timeout + unless resolve(*resolve_on_timeout, false) + # if it fails to resolve it was resolved in the meantime + # so return value as if there was no timeout + internal_state.result + end + end + # otherwise returns nil + end + end + + # Creates new future wrapping receiver, effectively hiding the resolve method and similar. + # + # @return [Future] + def with_hidden_resolvable + @with_hidden_resolvable ||= FutureWrapperPromise.new_blocked_by1(self, @DefaultExecutor).future + end + end + + # @abstract + # @private + class AbstractPromise < Synchronization::Object + safe_initialization! + include InternalStates + + def initialize(future) + super() + @Future = future + end + + def future + @Future + end + + alias_method :event, :future + + def default_executor + future.default_executor + end + + def state + future.state + end + + def touch + end + + def to_s + format '%s %s>', super[0..-2], @Future + end + + alias_method :inspect, :to_s + + def delayed_because + nil + end + + private + + def resolve_with(new_state, raise_on_reassign = true) + @Future.resolve_with(new_state, raise_on_reassign) + end + + # @return [Future] + def evaluate_to(*args, block) + resolve_with Fulfilled.new(block.call(*args)) + rescue Exception => error + resolve_with Rejected.new(error) + raise error unless error.is_a?(StandardError) + end + end + + class ResolvableEventPromise < AbstractPromise + def initialize(default_executor) + super ResolvableEvent.new(self, default_executor) + end + end + + class ResolvableFuturePromise < AbstractPromise + def initialize(default_executor) + super ResolvableFuture.new(self, default_executor) + end + + public :evaluate_to + end + + # @abstract + class InnerPromise < AbstractPromise + end + + # @abstract + class BlockedPromise < InnerPromise + + private_class_method :new + + def self.new_blocked_by1(blocker, *args, &block) + blocker_delayed = blocker.promise.delayed_because + promise = new(blocker_delayed, 1, *args, &block) + blocker.add_callback_notify_blocked promise, 0 + promise + end + + def self.new_blocked_by2(blocker1, blocker2, *args, &block) + blocker_delayed1 = blocker1.promise.delayed_because + blocker_delayed2 = blocker2.promise.delayed_because + delayed = if blocker_delayed1 && blocker_delayed2 + # TODO (pitr-ch 23-Dec-2016): use arrays when we know it will not grow (only flat adds delay) + LockFreeStack.of2(blocker_delayed1, blocker_delayed2) + else + blocker_delayed1 || blocker_delayed2 + end + promise = new(delayed, 2, *args, &block) + blocker1.add_callback_notify_blocked promise, 0 + blocker2.add_callback_notify_blocked promise, 1 + promise + end + + def self.new_blocked_by(blockers, *args, &block) + delayed = blockers.reduce(nil) { |d, f| add_delayed d, f.promise.delayed_because } + promise = new(delayed, blockers.size, *args, &block) + blockers.each_with_index { |f, i| f.add_callback_notify_blocked promise, i } + promise + end + + def self.add_delayed(delayed1, delayed2) + if delayed1 && delayed2 + delayed1.push delayed2 + delayed1 + else + delayed1 || delayed2 + end + end + + def initialize(delayed, blockers_count, future) + super(future) + @Delayed = delayed + @Countdown = AtomicFixnum.new blockers_count + end + + def on_blocker_resolution(future, index) + countdown = process_on_blocker_resolution(future, index) + resolvable = resolvable?(countdown, future, index) + + on_resolvable(future, index) if resolvable + end + + def delayed_because + @Delayed + end + + def touch + clear_and_propagate_touch + end + + # for inspection only + def blocked_by + blocked_by = [] + ObjectSpace.each_object(AbstractEventFuture) { |o| blocked_by.push o if o.blocks.include? self } + blocked_by + end + + private + + def clear_and_propagate_touch(stack_or_element = @Delayed) + return if stack_or_element.nil? + + if stack_or_element.is_a? LockFreeStack + stack_or_element.clear_each { |element| clear_and_propagate_touch element } + else + stack_or_element.touch unless stack_or_element.nil? # if still present + end + end + + # @return [true,false] if resolvable + def resolvable?(countdown, future, index) + countdown.zero? + end + + def process_on_blocker_resolution(future, index) + @Countdown.decrement + end + + def on_resolvable(resolved_future, index) + raise NotImplementedError + end + end + + # @abstract + class BlockedTaskPromise < BlockedPromise + def initialize(delayed, blockers_count, default_executor, executor, args, &task) + raise ArgumentError, 'no block given' unless block_given? + super delayed, 1, Future.new(self, default_executor) + @Executor = executor + @Task = task + @Args = args + end + + def executor + @Executor + end + end + + class ThenPromise < BlockedTaskPromise + private + + def initialize(delayed, blockers_count, default_executor, executor, args, &task) + super delayed, blockers_count, default_executor, executor, args, &task + end + + def on_resolvable(resolved_future, index) + if resolved_future.fulfilled? + Concurrent.executor(@Executor).post(resolved_future, @Args, @Task) do |future, args, task| + evaluate_to lambda { future.apply args, task } + end + else + resolve_with resolved_future.internal_state + end + end + end + + class RescuePromise < BlockedTaskPromise + private + + def initialize(delayed, blockers_count, default_executor, executor, args, &task) + super delayed, blockers_count, default_executor, executor, args, &task + end + + def on_resolvable(resolved_future, index) + if resolved_future.rejected? + Concurrent.executor(@Executor).post(resolved_future, @Args, @Task) do |future, args, task| + evaluate_to lambda { future.apply args, task } + end + else + resolve_with resolved_future.internal_state + end + end + end + + class ChainPromise < BlockedTaskPromise + private + + def on_resolvable(resolved_future, index) + if Future === resolved_future + Concurrent.executor(@Executor).post(resolved_future, @Args, @Task) do |future, args, task| + evaluate_to(*future.result, *args, task) + end + else + Concurrent.executor(@Executor).post(@Args, @Task) do |args, task| + evaluate_to(*args, task) + end + end + end + end + + # will be immediately resolved + class ImmediateEventPromise < InnerPromise + def initialize(default_executor) + super Event.new(self, default_executor).resolve_with(RESOLVED) + end + end + + class ImmediateFuturePromise < InnerPromise + def initialize(default_executor, fulfilled, value, reason) + super Future.new(self, default_executor). + resolve_with(fulfilled ? Fulfilled.new(value) : Rejected.new(reason)) + end + end + + class AbstractFlatPromise < BlockedPromise + + def initialize(delayed_because, blockers_count, event_or_future) + delayed = LockFreeStack.of1(self) + super(delayed, blockers_count, event_or_future) + # noinspection RubyArgCount + @Touched = AtomicBoolean.new false + @DelayedBecause = delayed_because || LockFreeStack.new + + event_or_future.add_callback_clear_delayed_node delayed.peek + end + + def touch + if @Touched.make_true + clear_and_propagate_touch @DelayedBecause + end + end + + private + + def touched? + @Touched.value + end + + def on_resolvable(resolved_future, index) + resolve_with resolved_future.internal_state + end + + def resolvable?(countdown, future, index) + !@Future.internal_state.resolved? && super(countdown, future, index) + end + + def add_delayed_of(future) + delayed = future.promise.delayed_because + if touched? + clear_and_propagate_touch delayed + else + BlockedPromise.add_delayed @DelayedBecause, delayed + clear_and_propagate_touch @DelayedBecause if touched? + end + end + + end + + class FlatEventPromise < AbstractFlatPromise + + private + + def initialize(delayed, blockers_count, default_executor) + super delayed, 2, Event.new(self, default_executor) + end + + def process_on_blocker_resolution(future, index) + countdown = super(future, index) + if countdown.nonzero? + internal_state = future.internal_state + + unless internal_state.fulfilled? + resolve_with RESOLVED + return countdown + end + + value = internal_state.value + case value + when AbstractEventFuture + add_delayed_of value + value.add_callback_notify_blocked self, nil + countdown + else + resolve_with RESOLVED + end + end + countdown + end + + end + + class FlatFuturePromise < AbstractFlatPromise + + private + + def initialize(delayed, blockers_count, levels, default_executor) + raise ArgumentError, 'levels has to be higher than 0' if levels < 1 + # flat promise may result to a future having delayed futures, therefore we have to have empty stack + # to be able to add new delayed futures + super delayed || LockFreeStack.new, 1 + levels, Future.new(self, default_executor) + end + + def process_on_blocker_resolution(future, index) + countdown = super(future, index) + if countdown.nonzero? + internal_state = future.internal_state + + unless internal_state.fulfilled? + resolve_with internal_state + return countdown + end + + value = internal_state.value + case value + when AbstractEventFuture + add_delayed_of value + value.add_callback_notify_blocked self, nil + countdown + else + evaluate_to(lambda { raise TypeError, "returned value #{value.inspect} is not a Future" }) + end + end + countdown + end + + end + + class RunFuturePromise < AbstractFlatPromise + + private + + def initialize(delayed, blockers_count, default_executor, run_test) + super delayed, 1, Future.new(self, default_executor) + @RunTest = run_test + end + + def process_on_blocker_resolution(future, index) + internal_state = future.internal_state + + unless internal_state.fulfilled? + resolve_with internal_state + return 0 + end + + value = internal_state.value + continuation_future = @RunTest.call value + + if continuation_future + add_delayed_of continuation_future + continuation_future.add_callback_notify_blocked self, nil + else + resolve_with internal_state + end + + 1 + end + end + + class ZipEventEventPromise < BlockedPromise + def initialize(delayed, blockers_count, default_executor) + super delayed, 2, Event.new(self, default_executor) + end + + private + + def on_resolvable(resolved_future, index) + resolve_with RESOLVED + end + end + + class ZipFutureEventPromise < BlockedPromise + def initialize(delayed, blockers_count, default_executor) + super delayed, 2, Future.new(self, default_executor) + @result = nil + end + + private + + def process_on_blocker_resolution(future, index) + # first blocking is future, take its result + @result = future.internal_state if index == 0 + # super has to be called after above to piggyback on volatile @Countdown + super future, index + end + + def on_resolvable(resolved_future, index) + resolve_with @result + end + end + + class EventWrapperPromise < BlockedPromise + def initialize(delayed, blockers_count, default_executor) + super delayed, 1, Event.new(self, default_executor) + end + + private + + def on_resolvable(resolved_future, index) + resolve_with RESOLVED + end + end + + class FutureWrapperPromise < BlockedPromise + def initialize(delayed, blockers_count, default_executor) + super delayed, 1, Future.new(self, default_executor) + end + + private + + def on_resolvable(resolved_future, index) + resolve_with resolved_future.internal_state + end + end + + class ZipFuturesPromise < BlockedPromise + + private + + def initialize(delayed, blockers_count, default_executor) + super(delayed, blockers_count, Future.new(self, default_executor)) + @Resolutions = ::Array.new(blockers_count, nil) + + on_resolvable nil, nil if blockers_count == 0 + end + + def process_on_blocker_resolution(future, index) + # TODO (pitr-ch 18-Dec-2016): Can we assume that array will never break under parallel access when never re-sized? + @Resolutions[index] = future.internal_state # has to be set before countdown in super + super future, index + end + + def on_resolvable(resolved_future, index) + all_fulfilled = true + values = ::Array.new(@Resolutions.size) + reasons = ::Array.new(@Resolutions.size) + + @Resolutions.each_with_index do |internal_state, i| + fulfilled, values[i], reasons[i] = internal_state.result + all_fulfilled &&= fulfilled + end + + if all_fulfilled + resolve_with FulfilledArray.new(values) + else + resolve_with PartiallyRejected.new(values, reasons) + end + end + end + + class ZipEventsPromise < BlockedPromise + + private + + def initialize(delayed, blockers_count, default_executor) + super delayed, blockers_count, Event.new(self, default_executor) + + on_resolvable nil, nil if blockers_count == 0 + end + + def on_resolvable(resolved_future, index) + resolve_with RESOLVED + end + end + + # @abstract + class AbstractAnyPromise < BlockedPromise + end + + class AnyResolvedEventPromise < AbstractAnyPromise + + private + + def initialize(delayed, blockers_count, default_executor) + super delayed, blockers_count, Event.new(self, default_executor) + end + + def resolvable?(countdown, future, index) + true + end + + def on_resolvable(resolved_future, index) + resolve_with RESOLVED, false + end + end + + class AnyResolvedFuturePromise < AbstractAnyPromise + + private + + def initialize(delayed, blockers_count, default_executor) + super delayed, blockers_count, Future.new(self, default_executor) + end + + def resolvable?(countdown, future, index) + true + end + + def on_resolvable(resolved_future, index) + resolve_with resolved_future.internal_state, false + end + end + + class AnyFulfilledFuturePromise < AnyResolvedFuturePromise + + private + + def resolvable?(countdown, event_or_future, index) + (event_or_future.is_a?(Event) ? event_or_future.resolved? : event_or_future.fulfilled?) || + # inlined super from BlockedPromise + countdown.zero? + end + end + + class DelayPromise < InnerPromise + + def initialize(default_executor) + event = Event.new(self, default_executor) + @Delayed = LockFreeStack.of1(self) + super event + event.add_callback_clear_delayed_node @Delayed.peek + end + + def touch + @Future.resolve_with RESOLVED + end + + def delayed_because + @Delayed + end + + end + + class ScheduledPromise < InnerPromise + def intended_time + @IntendedTime + end + + def inspect + "#{to_s[0..-2]} intended_time: #{@IntendedTime}>" + end + + private + + def initialize(default_executor, intended_time) + super Event.new(self, default_executor) + + @IntendedTime = intended_time + + in_seconds = begin + now = Time.now + schedule_time = if @IntendedTime.is_a? Time + @IntendedTime + else + now + @IntendedTime + end + [0, schedule_time.to_f - now.to_f].max + end + + Concurrent.global_timer_set.post(in_seconds) do + @Future.resolve_with RESOLVED + end + end + end + + extend FactoryMethods + + private_constant :AbstractPromise, + :ResolvableEventPromise, + :ResolvableFuturePromise, + :InnerPromise, + :BlockedPromise, + :BlockedTaskPromise, + :ThenPromise, + :RescuePromise, + :ChainPromise, + :ImmediateEventPromise, + :ImmediateFuturePromise, + :AbstractFlatPromise, + :FlatFuturePromise, + :FlatEventPromise, + :RunFuturePromise, + :ZipEventEventPromise, + :ZipFutureEventPromise, + :EventWrapperPromise, + :FutureWrapperPromise, + :ZipFuturesPromise, + :ZipEventsPromise, + :AbstractAnyPromise, + :AnyResolvedFuturePromise, + :AnyFulfilledFuturePromise, + :AnyResolvedEventPromise, + :DelayPromise, + :ScheduledPromise + + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/re_include.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/re_include.rb new file mode 100644 index 00000000..600bc6a5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/re_include.rb @@ -0,0 +1,60 @@ +module Concurrent + + # Methods form module A included to a module B, which is already included into class C, + # will not be visible in the C class. If this module is extended to B then A's methods + # are correctly made visible to C. + # + # @example + # module A + # def a + # :a + # end + # end + # + # module B1 + # end + # + # class C1 + # include B1 + # end + # + # module B2 + # extend Concurrent::ReInclude + # end + # + # class C2 + # include B2 + # end + # + # B1.send :include, A + # B2.send :include, A + # + # C1.new.respond_to? :a # => false + # C2.new.respond_to? :a # => true + # + # @!visibility private + module ReInclude + # @!visibility private + def included(base) + (@re_include_to_bases ||= []) << [:include, base] + super(base) + end + + # @!visibility private + def extended(base) + (@re_include_to_bases ||= []) << [:extend, base] + super(base) + end + + # @!visibility private + def include(*modules) + result = super(*modules) + modules.reverse.each do |module_being_included| + (@re_include_to_bases ||= []).each do |method, mod| + mod.send method, module_being_included + end + end + result + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/scheduled_task.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/scheduled_task.rb new file mode 100644 index 00000000..efe9e193 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/scheduled_task.rb @@ -0,0 +1,331 @@ +require 'concurrent/constants' +require 'concurrent/errors' +require 'concurrent/configuration' +require 'concurrent/ivar' +require 'concurrent/collection/copy_on_notify_observer_set' +require 'concurrent/utility/monotonic_time' + +require 'concurrent/options' + +module Concurrent + + # `ScheduledTask` is a close relative of `Concurrent::Future` but with one + # important difference: A `Future` is set to execute as soon as possible + # whereas a `ScheduledTask` is set to execute after a specified delay. This + # implementation is loosely based on Java's + # [ScheduledExecutorService](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html). + # It is a more feature-rich variant of {Concurrent.timer}. + # + # The *intended* schedule time of task execution is set on object construction + # with the `delay` argument. The delay is a numeric (floating point or integer) + # representing a number of seconds in the future. Any other value or a numeric + # equal to or less than zero will result in an exception. The *actual* schedule + # time of task execution is set when the `execute` method is called. + # + # The constructor can also be given zero or more processing options. Currently + # the only supported options are those recognized by the + # [Dereferenceable](Dereferenceable) module. + # + # The final constructor argument is a block representing the task to be performed. + # If no block is given an `ArgumentError` will be raised. + # + # **States** + # + # `ScheduledTask` mixes in the [Obligation](Obligation) module thus giving it + # "future" behavior. This includes the expected lifecycle states. `ScheduledTask` + # has one additional state, however. While the task (block) is being executed the + # state of the object will be `:processing`. This additional state is necessary + # because it has implications for task cancellation. + # + # **Cancellation** + # + # A `:pending` task can be cancelled using the `#cancel` method. A task in any + # other state, including `:processing`, cannot be cancelled. The `#cancel` + # method returns a boolean indicating the success of the cancellation attempt. + # A cancelled `ScheduledTask` cannot be restarted. It is immutable. + # + # **Obligation and Observation** + # + # The result of a `ScheduledTask` can be obtained either synchronously or + # asynchronously. `ScheduledTask` mixes in both the [Obligation](Obligation) + # module and the + # [Observable](http://ruby-doc.org/stdlib-2.0/libdoc/observer/rdoc/Observable.html) + # module from the Ruby standard library. With one exception `ScheduledTask` + # behaves identically to [Future](Observable) with regard to these modules. + # + # @!macro copy_options + # + # @example Basic usage + # + # require 'concurrent/scheduled_task' + # require 'csv' + # require 'open-uri' + # + # class Ticker + # def get_year_end_closing(symbol, year, api_key) + # uri = "https://www.alphavantage.co/query?function=TIME_SERIES_MONTHLY&symbol=#{symbol}&apikey=#{api_key}&datatype=csv" + # data = [] + # csv = URI.parse(uri).read + # if csv.include?('call frequency') + # return :rate_limit_exceeded + # end + # CSV.parse(csv, headers: true) do |row| + # data << row['close'].to_f if row['timestamp'].include?(year.to_s) + # end + # year_end = data.first + # year_end + # rescue => e + # p e + # end + # end + # + # api_key = ENV['ALPHAVANTAGE_KEY'] + # abort(error_message) unless api_key + # + # # Future + # price = Concurrent::Future.execute{ Ticker.new.get_year_end_closing('TWTR', 2013, api_key) } + # price.state #=> :pending + # price.pending? #=> true + # price.value(0) #=> nil (does not block) + # + # sleep(1) # do other stuff + # + # price.value #=> 63.65 (after blocking if necessary) + # price.state #=> :fulfilled + # price.fulfilled? #=> true + # price.value #=> 63.65 + # + # @example Successful task execution + # + # task = Concurrent::ScheduledTask.new(2){ 'What does the fox say?' } + # task.state #=> :unscheduled + # task.execute + # task.state #=> pending + # + # # wait for it... + # sleep(3) + # + # task.unscheduled? #=> false + # task.pending? #=> false + # task.fulfilled? #=> true + # task.rejected? #=> false + # task.value #=> 'What does the fox say?' + # + # @example One line creation and execution + # + # task = Concurrent::ScheduledTask.new(2){ 'What does the fox say?' }.execute + # task.state #=> pending + # + # task = Concurrent::ScheduledTask.execute(2){ 'What do you get when you multiply 6 by 9?' } + # task.state #=> pending + # + # @example Failed task execution + # + # task = Concurrent::ScheduledTask.execute(2){ raise StandardError.new('Call me maybe?') } + # task.pending? #=> true + # + # # wait for it... + # sleep(3) + # + # task.unscheduled? #=> false + # task.pending? #=> false + # task.fulfilled? #=> false + # task.rejected? #=> true + # task.value #=> nil + # task.reason #=> # + # + # @example Task execution with observation + # + # observer = Class.new{ + # def update(time, value, reason) + # puts "The task completed at #{time} with value '#{value}'" + # end + # }.new + # + # task = Concurrent::ScheduledTask.new(2){ 'What does the fox say?' } + # task.add_observer(observer) + # task.execute + # task.pending? #=> true + # + # # wait for it... + # sleep(3) + # + # #>> The task completed at 2013-11-07 12:26:09 -0500 with value 'What does the fox say?' + # + # @!macro monotonic_clock_warning + # + # @see Concurrent.timer + class ScheduledTask < IVar + include Comparable + + # The executor on which to execute the task. + # @!visibility private + attr_reader :executor + + # Schedule a task for execution at a specified future time. + # + # @param [Float] delay the number of seconds to wait for before executing the task + # + # @yield the task to be performed + # + # @!macro executor_and_deref_options + # + # @option opts [object, Array] :args zero or more arguments to be passed the task + # block on execution + # + # @raise [ArgumentError] When no block is given + # @raise [ArgumentError] When given a time that is in the past + def initialize(delay, opts = {}, &task) + raise ArgumentError.new('no block given') unless block_given? + raise ArgumentError.new('seconds must be greater than zero') if delay.to_f < 0.0 + + super(NULL, opts, &nil) + + synchronize do + ns_set_state(:unscheduled) + @parent = opts.fetch(:timer_set, Concurrent.global_timer_set) + @args = get_arguments_from(opts) + @delay = delay.to_f + @task = task + @time = nil + @executor = Options.executor_from_options(opts) || Concurrent.global_io_executor + self.observers = Collection::CopyOnNotifyObserverSet.new + end + end + + # The `delay` value given at instantiation. + # + # @return [Float] the initial delay. + def initial_delay + synchronize { @delay } + end + + # The monotonic time at which the the task is scheduled to be executed. + # + # @return [Float] the schedule time or nil if `unscheduled` + def schedule_time + synchronize { @time } + end + + # Comparator which orders by schedule time. + # + # @!visibility private + def <=>(other) + schedule_time <=> other.schedule_time + end + + # Has the task been cancelled? + # + # @return [Boolean] true if the task is in the given state else false + def cancelled? + synchronize { ns_check_state?(:cancelled) } + end + + # In the task execution in progress? + # + # @return [Boolean] true if the task is in the given state else false + def processing? + synchronize { ns_check_state?(:processing) } + end + + # Cancel this task and prevent it from executing. A task can only be + # cancelled if it is pending or unscheduled. + # + # @return [Boolean] true if successfully cancelled else false + def cancel + if compare_and_set_state(:cancelled, :pending, :unscheduled) + complete(false, nil, CancelledOperationError.new) + # To avoid deadlocks this call must occur outside of #synchronize + # Changing the state above should prevent redundant calls + @parent.send(:remove_task, self) + else + false + end + end + + # Reschedule the task using the original delay and the current time. + # A task can only be reset while it is `:pending`. + # + # @return [Boolean] true if successfully rescheduled else false + def reset + synchronize{ ns_reschedule(@delay) } + end + + # Reschedule the task using the given delay and the current time. + # A task can only be reset while it is `:pending`. + # + # @param [Float] delay the number of seconds to wait for before executing the task + # + # @return [Boolean] true if successfully rescheduled else false + # + # @raise [ArgumentError] When given a time that is in the past + def reschedule(delay) + delay = delay.to_f + raise ArgumentError.new('seconds must be greater than zero') if delay < 0.0 + synchronize{ ns_reschedule(delay) } + end + + # Execute an `:unscheduled` `ScheduledTask`. Immediately sets the state to `:pending` + # and starts counting down toward execution. Does nothing if the `ScheduledTask` is + # in any state other than `:unscheduled`. + # + # @return [ScheduledTask] a reference to `self` + def execute + if compare_and_set_state(:pending, :unscheduled) + synchronize{ ns_schedule(@delay) } + end + self + end + + # Create a new `ScheduledTask` object with the given block, execute it, and return the + # `:pending` object. + # + # @param [Float] delay the number of seconds to wait for before executing the task + # + # @!macro executor_and_deref_options + # + # @return [ScheduledTask] the newly created `ScheduledTask` in the `:pending` state + # + # @raise [ArgumentError] if no block is given + def self.execute(delay, opts = {}, &task) + new(delay, opts, &task).execute + end + + # Execute the task. + # + # @!visibility private + def process_task + safe_execute(@task, @args) + end + + protected :set, :try_set, :fail, :complete + + protected + + # Schedule the task using the given delay and the current time. + # + # @param [Float] delay the number of seconds to wait for before executing the task + # + # @return [Boolean] true if successfully rescheduled else false + # + # @!visibility private + def ns_schedule(delay) + @delay = delay + @time = Concurrent.monotonic_time + @delay + @parent.send(:post_task, self) + end + + # Reschedule the task using the given delay and the current time. + # A task can only be reset while it is `:pending`. + # + # @param [Float] delay the number of seconds to wait for before executing the task + # + # @return [Boolean] true if successfully rescheduled else false + # + # @!visibility private + def ns_reschedule(delay) + return false unless ns_check_state?(:pending) + @parent.send(:remove_task, self) && ns_schedule(delay) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/set.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/set.rb new file mode 100644 index 00000000..eee4effd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/set.rb @@ -0,0 +1,64 @@ +require 'concurrent/utility/engine' +require 'concurrent/thread_safe/util' +require 'set' + +module Concurrent + + # @!macro concurrent_set + # + # A thread-safe subclass of Set. This version locks against the object + # itself for every method call, ensuring only one thread can be reading + # or writing at a time. This includes iteration methods like `#each`. + # + # @note `a += b` is **not** a **thread-safe** operation on + # `Concurrent::Set`. It reads Set `a`, then it creates new `Concurrent::Set` + # which is union of `a` and `b`, then it writes the union to `a`. + # The read and write are independent operations they do not form a single atomic + # operation therefore when two `+=` operations are executed concurrently updates + # may be lost. Use `#merge` instead. + # + # @see http://ruby-doc.org/stdlib-2.4.0/libdoc/set/rdoc/Set.html Ruby standard library `Set` + + # @!macro internal_implementation_note + SetImplementation = case + when Concurrent.on_cruby? + # The CRuby implementation of Set is written in Ruby itself and is + # not thread safe for certain methods. + require 'monitor' + require 'concurrent/thread_safe/util/data_structures' + + class CRubySet < ::Set + end + + ThreadSafe::Util.make_synchronized_on_cruby CRubySet + CRubySet + + when Concurrent.on_jruby? + require 'jruby/synchronized' + + class JRubySet < ::Set + include JRuby::Synchronized + end + + JRubySet + + when Concurrent.on_truffleruby? + require 'concurrent/thread_safe/util/data_structures' + + class TruffleRubySet < ::Set + end + + ThreadSafe::Util.make_synchronized_on_truffleruby TruffleRubySet + TruffleRubySet + + else + warn 'Possibly unsupported Ruby implementation' + ::Set + end + private_constant :SetImplementation + + # @!macro concurrent_set + class Set < SetImplementation + end +end + diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/settable_struct.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/settable_struct.rb new file mode 100644 index 00000000..99b85619 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/settable_struct.rb @@ -0,0 +1,139 @@ +require 'concurrent/errors' +require 'concurrent/synchronization/abstract_struct' +require 'concurrent/synchronization/lockable_object' + +module Concurrent + + # An thread-safe, write-once variation of Ruby's standard `Struct`. + # Each member can have its value set at most once, either at construction + # or any time thereafter. Attempting to assign a value to a member + # that has already been set will result in a `Concurrent::ImmutabilityError`. + # + # @see http://ruby-doc.org/core/Struct.html Ruby standard library `Struct` + # @see http://en.wikipedia.org/wiki/Final_(Java) Java `final` keyword + module SettableStruct + include Synchronization::AbstractStruct + + # @!macro struct_values + def values + synchronize { ns_values } + end + alias_method :to_a, :values + + # @!macro struct_values_at + def values_at(*indexes) + synchronize { ns_values_at(indexes) } + end + + # @!macro struct_inspect + def inspect + synchronize { ns_inspect } + end + alias_method :to_s, :inspect + + # @!macro struct_merge + def merge(other, &block) + synchronize { ns_merge(other, &block) } + end + + # @!macro struct_to_h + def to_h + synchronize { ns_to_h } + end + + # @!macro struct_get + def [](member) + synchronize { ns_get(member) } + end + + # @!macro struct_equality + def ==(other) + synchronize { ns_equality(other) } + end + + # @!macro struct_each + def each(&block) + return enum_for(:each) unless block_given? + synchronize { ns_each(&block) } + end + + # @!macro struct_each_pair + def each_pair(&block) + return enum_for(:each_pair) unless block_given? + synchronize { ns_each_pair(&block) } + end + + # @!macro struct_select + def select(&block) + return enum_for(:select) unless block_given? + synchronize { ns_select(&block) } + end + + # @!macro struct_set + # + # @raise [Concurrent::ImmutabilityError] if the given member has already been set + def []=(member, value) + if member.is_a? Integer + length = synchronize { @values.length } + if member >= length + raise IndexError.new("offset #{member} too large for struct(size:#{length})") + end + synchronize do + unless @values[member].nil? + raise Concurrent::ImmutabilityError.new('struct member has already been set') + end + @values[member] = value + end + else + send("#{member}=", value) + end + rescue NoMethodError + raise NameError.new("no member '#{member}' in struct") + end + + private + + # @!visibility private + def initialize_copy(original) + synchronize do + super(original) + ns_initialize_copy + end + end + + # @!macro struct_new + def self.new(*args, &block) + clazz_name = nil + if args.length == 0 + raise ArgumentError.new('wrong number of arguments (0 for 1+)') + elsif args.length > 0 && args.first.is_a?(String) + clazz_name = args.shift + end + FACTORY.define_struct(clazz_name, args, &block) + end + + FACTORY = Class.new(Synchronization::LockableObject) do + def define_struct(name, members, &block) + synchronize do + clazz = Synchronization::AbstractStruct.define_struct_class(SettableStruct, Synchronization::LockableObject, name, members, &block) + members.each_with_index do |member, index| + clazz.send :remove_method, member if clazz.instance_methods.include? member + clazz.send(:define_method, member) do + synchronize { @values[index] } + end + clazz.send(:define_method, "#{member}=") do |value| + synchronize do + unless @values[index].nil? + raise Concurrent::ImmutabilityError.new('struct member has already been set') + end + @values[index] = value + end + end + end + clazz + end + end + end.new + private_constant :FACTORY + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization.rb new file mode 100644 index 00000000..6d8cf4bd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization.rb @@ -0,0 +1,13 @@ +require 'concurrent/utility/native_extension_loader' # load native parts first + +require 'concurrent/synchronization/object' +require 'concurrent/synchronization/lockable_object' +require 'concurrent/synchronization/condition' +require 'concurrent/synchronization/lock' + +module Concurrent + # @!visibility private + module Synchronization + end +end + diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/abstract_lockable_object.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/abstract_lockable_object.rb new file mode 100644 index 00000000..d9050b31 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/abstract_lockable_object.rb @@ -0,0 +1,102 @@ +require 'concurrent/utility/native_extension_loader' # load native parts first +require 'concurrent/utility/monotonic_time' +require 'concurrent/synchronization/object' + +module Concurrent + module Synchronization + + # @!visibility private + class AbstractLockableObject < Synchronization::Object + + protected + + # @!macro synchronization_object_method_synchronize + # + # @yield runs the block synchronized against this object, + # equivalent of java's `synchronize(this) {}` + # @note can by made public in descendants if required by `public :synchronize` + def synchronize + raise NotImplementedError + end + + # @!macro synchronization_object_method_ns_wait_until + # + # Wait until condition is met or timeout passes, + # protects against spurious wake-ups. + # @param [Numeric, nil] timeout in seconds, `nil` means no timeout + # @yield condition to be met + # @yieldreturn [true, false] + # @return [true, false] if condition met + # @note only to be used inside synchronized block + # @note to provide direct access to this method in a descendant add method + # ``` + # def wait_until(timeout = nil, &condition) + # synchronize { ns_wait_until(timeout, &condition) } + # end + # ``` + def ns_wait_until(timeout = nil, &condition) + if timeout + wait_until = Concurrent.monotonic_time + timeout + loop do + now = Concurrent.monotonic_time + condition_result = condition.call + return condition_result if now >= wait_until || condition_result + ns_wait wait_until - now + end + else + ns_wait timeout until condition.call + true + end + end + + # @!macro synchronization_object_method_ns_wait + # + # Wait until another thread calls #signal or #broadcast, + # spurious wake-ups can happen. + # + # @param [Numeric, nil] timeout in seconds, `nil` means no timeout + # @return [self] + # @note only to be used inside synchronized block + # @note to provide direct access to this method in a descendant add method + # ``` + # def wait(timeout = nil) + # synchronize { ns_wait(timeout) } + # end + # ``` + def ns_wait(timeout = nil) + raise NotImplementedError + end + + # @!macro synchronization_object_method_ns_signal + # + # Signal one waiting thread. + # @return [self] + # @note only to be used inside synchronized block + # @note to provide direct access to this method in a descendant add method + # ``` + # def signal + # synchronize { ns_signal } + # end + # ``` + def ns_signal + raise NotImplementedError + end + + # @!macro synchronization_object_method_ns_broadcast + # + # Broadcast to all waiting threads. + # @return [self] + # @note only to be used inside synchronized block + # @note to provide direct access to this method in a descendant add method + # ``` + # def broadcast + # synchronize { ns_broadcast } + # end + # ``` + def ns_broadcast + raise NotImplementedError + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/abstract_object.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/abstract_object.rb new file mode 100644 index 00000000..7cd2decf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/abstract_object.rb @@ -0,0 +1,22 @@ +module Concurrent + module Synchronization + + # @!visibility private + # @!macro internal_implementation_note + class AbstractObject + def initialize + # nothing to do + end + + # @!visibility private + # @abstract + def full_memory_barrier + raise NotImplementedError + end + + def self.attr_volatile(*names) + raise NotImplementedError + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/abstract_struct.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/abstract_struct.rb new file mode 100644 index 00000000..28816c51 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/abstract_struct.rb @@ -0,0 +1,171 @@ +module Concurrent + module Synchronization + + # @!visibility private + # @!macro internal_implementation_note + module AbstractStruct + + # @!visibility private + def initialize(*values) + super() + ns_initialize(*values) + end + + # @!macro struct_length + # + # Returns the number of struct members. + # + # @return [Fixnum] the number of struct members + def length + self.class::MEMBERS.length + end + alias_method :size, :length + + # @!macro struct_members + # + # Returns the struct members as an array of symbols. + # + # @return [Array] the struct members as an array of symbols + def members + self.class::MEMBERS.dup + end + + protected + + # @!macro struct_values + # + # @!visibility private + def ns_values + @values.dup + end + + # @!macro struct_values_at + # + # @!visibility private + def ns_values_at(indexes) + @values.values_at(*indexes) + end + + # @!macro struct_to_h + # + # @!visibility private + def ns_to_h + length.times.reduce({}){|memo, i| memo[self.class::MEMBERS[i]] = @values[i]; memo} + end + + # @!macro struct_get + # + # @!visibility private + def ns_get(member) + if member.is_a? Integer + if member >= @values.length + raise IndexError.new("offset #{member} too large for struct(size:#{@values.length})") + end + @values[member] + else + send(member) + end + rescue NoMethodError + raise NameError.new("no member '#{member}' in struct") + end + + # @!macro struct_equality + # + # @!visibility private + def ns_equality(other) + self.class == other.class && self.values == other.values + end + + # @!macro struct_each + # + # @!visibility private + def ns_each + values.each{|value| yield value } + end + + # @!macro struct_each_pair + # + # @!visibility private + def ns_each_pair + @values.length.times do |index| + yield self.class::MEMBERS[index], @values[index] + end + end + + # @!macro struct_select + # + # @!visibility private + def ns_select + values.select{|value| yield value } + end + + # @!macro struct_inspect + # + # @!visibility private + def ns_inspect + struct = pr_underscore(self.class.ancestors[1]) + clazz = ((self.class.to_s =~ /^#" + end + + # @!macro struct_merge + # + # @!visibility private + def ns_merge(other, &block) + self.class.new(*self.to_h.merge(other, &block).values) + end + + # @!visibility private + def ns_initialize_copy + @values = @values.map do |val| + begin + val.clone + rescue TypeError + val + end + end + end + + # @!visibility private + def pr_underscore(clazz) + word = clazz.to_s.dup # dup string to workaround JRuby 9.2.0.0 bug https://github.com/jruby/jruby/issues/5229 + 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 + + # @!visibility private + def self.define_struct_class(parent, base, name, members, &block) + clazz = Class.new(base || Object) do + include parent + self.const_set(:MEMBERS, members.collect{|member| member.to_s.to_sym}.freeze) + def ns_initialize(*values) + raise ArgumentError.new('struct size differs') if values.length > length + @values = values.fill(nil, values.length..length-1) + end + end + unless name.nil? + begin + parent.send :remove_const, name if parent.const_defined?(name, false) + parent.const_set(name, clazz) + clazz + rescue NameError + raise NameError.new("identifier #{name} needs to be constant") + end + end + members.each_with_index do |member, index| + clazz.send :remove_method, member if clazz.instance_methods(false).include? member + clazz.send(:define_method, member) do + @values[index] + end + end + clazz.class_exec(&block) unless block.nil? + clazz.singleton_class.send :alias_method, :[], :new + clazz + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/condition.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/condition.rb new file mode 100644 index 00000000..5daa68be --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/condition.rb @@ -0,0 +1,62 @@ +require 'concurrent/synchronization/lockable_object' + +module Concurrent + module Synchronization + + # @!visibility private + # TODO (pitr-ch 04-Dec-2016): should be in edge + class Condition < LockableObject + safe_initialization! + + # TODO (pitr 12-Sep-2015): locks two objects, improve + # TODO (pitr 26-Sep-2015): study + # http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/util/concurrent/locks/AbstractQueuedSynchronizer.java#AbstractQueuedSynchronizer.Node + + singleton_class.send :alias_method, :private_new, :new + private_class_method :new + + def initialize(lock) + super() + @Lock = lock + end + + def wait(timeout = nil) + @Lock.synchronize { ns_wait(timeout) } + end + + def ns_wait(timeout = nil) + synchronize { super(timeout) } + end + + def wait_until(timeout = nil, &condition) + @Lock.synchronize { ns_wait_until(timeout, &condition) } + end + + def ns_wait_until(timeout = nil, &condition) + synchronize { super(timeout, &condition) } + end + + def signal + @Lock.synchronize { ns_signal } + end + + def ns_signal + synchronize { super } + end + + def broadcast + @Lock.synchronize { ns_broadcast } + end + + def ns_broadcast + synchronize { super } + end + end + + class LockableObject < LockableObjectImplementation + def new_condition + Condition.private_new(self) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/full_memory_barrier.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/full_memory_barrier.rb new file mode 100644 index 00000000..139e08d8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/full_memory_barrier.rb @@ -0,0 +1,29 @@ +require 'concurrent/utility/native_extension_loader' # load native parts first + +module Concurrent + module Synchronization + case + when Concurrent.on_cruby? + def self.full_memory_barrier + # relying on undocumented behavior of CRuby, GVL acquire has lock which ensures visibility of ivars + # https://github.com/ruby/ruby/blob/ruby_2_2/thread_pthread.c#L204-L211 + end + + when Concurrent.on_jruby? + require 'concurrent/utility/native_extension_loader' + def self.full_memory_barrier + JRubyAttrVolatile.full_memory_barrier + end + + when Concurrent.on_truffleruby? + def self.full_memory_barrier + TruffleRuby.full_memory_barrier + end + + else + warn 'Possibly unsupported Ruby implementation' + def self.full_memory_barrier + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/jruby_lockable_object.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/jruby_lockable_object.rb new file mode 100644 index 00000000..76930461 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/jruby_lockable_object.rb @@ -0,0 +1,15 @@ +require 'concurrent/utility/native_extension_loader' # load native parts first + +module Concurrent + module Synchronization + + if Concurrent.on_jruby? + + # @!visibility private + # @!macro internal_implementation_note + class JRubyLockableObject < AbstractLockableObject + + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/lock.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/lock.rb new file mode 100644 index 00000000..f90e0b5f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/lock.rb @@ -0,0 +1,38 @@ +require 'concurrent/synchronization/lockable_object' + +module Concurrent + module Synchronization + + # @!visibility private + # TODO (pitr-ch 04-Dec-2016): should be in edge + class Lock < LockableObject + # TODO use JavaReentrantLock on JRuby + + public :synchronize + + def wait(timeout = nil) + synchronize { ns_wait(timeout) } + end + + public :ns_wait + + def wait_until(timeout = nil, &condition) + synchronize { ns_wait_until(timeout, &condition) } + end + + public :ns_wait_until + + def signal + synchronize { ns_signal } + end + + public :ns_signal + + def broadcast + synchronize { ns_broadcast } + end + + public :ns_broadcast + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb new file mode 100644 index 00000000..08d2ff66 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/lockable_object.rb @@ -0,0 +1,75 @@ +require 'concurrent/utility/engine' +require 'concurrent/synchronization/abstract_lockable_object' +require 'concurrent/synchronization/mutex_lockable_object' +require 'concurrent/synchronization/jruby_lockable_object' + +module Concurrent + module Synchronization + + # @!visibility private + # @!macro internal_implementation_note + LockableObjectImplementation = case + when Concurrent.on_cruby? + MutexLockableObject + when Concurrent.on_jruby? + JRubyLockableObject + when Concurrent.on_truffleruby? + MutexLockableObject + else + warn 'Possibly unsupported Ruby implementation' + MonitorLockableObject + end + private_constant :LockableObjectImplementation + + # Safe synchronization under any Ruby implementation. + # It provides methods like {#synchronize}, {#wait}, {#signal} and {#broadcast}. + # Provides a single layer which can improve its implementation over time without changes needed to + # the classes using it. Use {Synchronization::Object} not this abstract class. + # + # @note this object does not support usage together with + # [`Thread#wakeup`](http://ruby-doc.org/core/Thread.html#method-i-wakeup) + # and [`Thread#raise`](http://ruby-doc.org/core/Thread.html#method-i-raise). + # `Thread#sleep` and `Thread#wakeup` will work as expected but mixing `Synchronization::Object#wait` and + # `Thread#wakeup` will not work on all platforms. + # + # @see Event implementation as an example of this class use + # + # @example simple + # class AnClass < Synchronization::Object + # def initialize + # super + # synchronize { @value = 'asd' } + # end + # + # def value + # synchronize { @value } + # end + # end + # + # @!visibility private + class LockableObject < LockableObjectImplementation + + # TODO (pitr 12-Sep-2015): make private for c-r, prohibit subclassing + # TODO (pitr 12-Sep-2015): we inherit too much ourselves :/ + + # @!method initialize(*args, &block) + # @!macro synchronization_object_method_initialize + + # @!method synchronize + # @!macro synchronization_object_method_synchronize + + # @!method wait_until(timeout = nil, &condition) + # @!macro synchronization_object_method_ns_wait_until + + # @!method wait(timeout = nil) + # @!macro synchronization_object_method_ns_wait + + # @!method signal + # @!macro synchronization_object_method_ns_signal + + # @!method broadcast + # @!macro synchronization_object_method_ns_broadcast + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb new file mode 100644 index 00000000..acc9745a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/mutex_lockable_object.rb @@ -0,0 +1,89 @@ +require 'concurrent/synchronization/abstract_lockable_object' + +module Concurrent + module Synchronization + + # @!visibility private + # @!macro internal_implementation_note + module ConditionSignalling + protected + + def ns_signal + @__Condition__.signal + self + end + + def ns_broadcast + @__Condition__.broadcast + self + end + end + + + # @!visibility private + # @!macro internal_implementation_note + class MutexLockableObject < AbstractLockableObject + include ConditionSignalling + + safe_initialization! + + def initialize + super() + @__Lock__ = ::Mutex.new + @__Condition__ = ::ConditionVariable.new + end + + def initialize_copy(other) + super + @__Lock__ = ::Mutex.new + @__Condition__ = ::ConditionVariable.new + end + + protected + + def synchronize + if @__Lock__.owned? + yield + else + @__Lock__.synchronize { yield } + end + end + + def ns_wait(timeout = nil) + @__Condition__.wait @__Lock__, timeout + self + end + end + + # @!visibility private + # @!macro internal_implementation_note + class MonitorLockableObject < AbstractLockableObject + include ConditionSignalling + + safe_initialization! + + def initialize + super() + @__Lock__ = ::Monitor.new + @__Condition__ = @__Lock__.new_cond + end + + def initialize_copy(other) + super + @__Lock__ = ::Monitor.new + @__Condition__ = @__Lock__.new_cond + end + + protected + + def synchronize # TODO may be a problem with lock.synchronize { lock.wait } + @__Lock__.synchronize { yield } + end + + def ns_wait(timeout = nil) + @__Condition__.wait timeout + self + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/object.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/object.rb new file mode 100644 index 00000000..59219070 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/object.rb @@ -0,0 +1,151 @@ +require 'concurrent/utility/native_extension_loader' # load native parts first + +require 'concurrent/synchronization/safe_initialization' +require 'concurrent/synchronization/volatile' +require 'concurrent/atomic/atomic_reference' + +module Concurrent + module Synchronization + + # Abstract object providing final, volatile, ans CAS extensions to build other concurrent abstractions. + # - final instance variables see {Object.safe_initialization!} + # - volatile instance variables see {Object.attr_volatile} + # - volatile instance variables see {Object.attr_atomic} + # @!visibility private + class Object < AbstractObject + include Volatile + + # TODO make it a module if possible + + # @!method self.attr_volatile(*names) + # Creates methods for reading and writing (as `attr_accessor` does) to a instance variable with + # volatile (Java) semantic. The instance variable should be accessed only through generated methods. + # + # @param [::Array] names of the instance variables to be volatile + # @return [::Array] names of defined method names + + # Has to be called by children. + def initialize + super + __initialize_atomic_fields__ + end + + def self.safe_initialization! + extend SafeInitialization unless safe_initialization? + end + + def self.safe_initialization? + self.singleton_class < SafeInitialization + end + + # For testing purposes, quite slow. Injects assert code to new method which will raise if class instance contains + # any instance variables with CamelCase names and isn't {.safe_initialization?}. + # @raise when offend found + # @return [true] + def self.ensure_safe_initialization_when_final_fields_are_present + Object.class_eval do + def self.new(*args, &block) + object = super(*args, &block) + ensure + has_final_field = object.instance_variables.any? { |v| v.to_s =~ /^@[A-Z]/ } + if has_final_field && !safe_initialization? + raise "there was an instance of #{object.class} with final field but not marked with safe_initialization!" + end + end + end + true + end + + # Creates methods for reading and writing to a instance variable with + # volatile (Java) semantic as {.attr_volatile} does. + # The instance variable should be accessed only through generated methods. + # This method generates following methods: `value`, `value=(new_value) #=> new_value`, + # `swap_value(new_value) #=> old_value`, + # `compare_and_set_value(expected, value) #=> true || false`, `update_value(&block)`. + # @param [::Array] names of the instance variables to be volatile with CAS. + # @return [::Array] names of defined method names. + # @!macro attr_atomic + # @!method $1 + # @return [Object] The $1. + # @!method $1=(new_$1) + # Set the $1. + # @return [Object] new_$1. + # @!method swap_$1(new_$1) + # Set the $1 to new_$1 and return the old $1. + # @return [Object] old $1 + # @!method compare_and_set_$1(expected_$1, new_$1) + # Sets the $1 to new_$1 if the current $1 is expected_$1 + # @return [true, false] + # @!method update_$1(&block) + # Updates the $1 using the block. + # @yield [Object] Calculate a new $1 using given (old) $1 + # @yieldparam [Object] old $1 + # @return [Object] new $1 + def self.attr_atomic(*names) + @__atomic_fields__ ||= [] + @__atomic_fields__ += names + safe_initialization! + define_initialize_atomic_fields + + names.each do |name| + ivar = :"@Atomic#{name.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }}" + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{name} + #{ivar}.get + end + + def #{name}=(value) + #{ivar}.set value + end + + def swap_#{name}(value) + #{ivar}.swap value + end + + def compare_and_set_#{name}(expected, value) + #{ivar}.compare_and_set expected, value + end + + def update_#{name}(&block) + #{ivar}.update(&block) + end + RUBY + end + names.flat_map { |n| [n, :"#{n}=", :"swap_#{n}", :"compare_and_set_#{n}", :"update_#{n}"] } + end + + # @param [true, false] inherited should inherited volatile with CAS fields be returned? + # @return [::Array] Returns defined volatile with CAS fields on this class. + def self.atomic_attributes(inherited = true) + @__atomic_fields__ ||= [] + ((superclass.atomic_attributes if superclass.respond_to?(:atomic_attributes) && inherited) || []) + @__atomic_fields__ + end + + # @return [true, false] is the attribute with name atomic? + def self.atomic_attribute?(name) + atomic_attributes.include? name + end + + private + + def self.define_initialize_atomic_fields + assignments = @__atomic_fields__.map do |name| + "@Atomic#{name.to_s.gsub(/(?:^|_)(.)/) { $1.upcase }} = Concurrent::AtomicReference.new(nil)" + end.join("\n") + + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def __initialize_atomic_fields__ + super + #{assignments} + end + RUBY + end + + private_class_method :define_initialize_atomic_fields + + def __initialize_atomic_fields__ + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/safe_initialization.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/safe_initialization.rb new file mode 100644 index 00000000..f785e352 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/safe_initialization.rb @@ -0,0 +1,36 @@ +require 'concurrent/synchronization/full_memory_barrier' + +module Concurrent + module Synchronization + + # @!visibility private + # @!macro internal_implementation_note + # + # By extending this module, a class and all its children are marked to be constructed safely. Meaning that + # all writes (ivar initializations) are made visible to all readers of newly constructed object. It ensures + # same behaviour as Java's final fields. + # + # Due to using Kernel#extend, the module is not included again if already present in the ancestors, + # which avoids extra overhead. + # + # @example + # class AClass < Concurrent::Synchronization::Object + # extend Concurrent::Synchronization::SafeInitialization + # + # def initialize + # @AFinalValue = 'value' # published safely, #foo will never return nil + # end + # + # def foo + # @AFinalValue + # end + # end + module SafeInitialization + def new(*args, &block) + super(*args, &block) + ensure + Concurrent::Synchronization.full_memory_barrier + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/volatile.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/volatile.rb new file mode 100644 index 00000000..46e8ba6a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/synchronization/volatile.rb @@ -0,0 +1,101 @@ +require 'concurrent/utility/native_extension_loader' # load native parts first +require 'concurrent/utility/engine' +require 'concurrent/synchronization/full_memory_barrier' + +module Concurrent + module Synchronization + + # Volatile adds the attr_volatile class method when included. + # + # @example + # class Foo + # include Concurrent::Synchronization::Volatile + # + # attr_volatile :bar + # + # def initialize + # self.bar = 1 + # end + # end + # + # foo = Foo.new + # foo.bar + # => 1 + # foo.bar = 2 + # => 2 + # + # @!visibility private + module Volatile + def self.included(base) + base.extend(ClassMethods) + end + + def full_memory_barrier + Synchronization.full_memory_barrier + end + + module ClassMethods + if Concurrent.on_cruby? + def attr_volatile(*names) + names.each do |name| + ivar = :"@volatile_#{name}" + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{name} + #{ivar} + end + + def #{name}=(value) + #{ivar} = value + end + RUBY + end + names.map { |n| [n, :"#{n}="] }.flatten + end + + elsif Concurrent.on_jruby? + def attr_volatile(*names) + names.each do |name| + ivar = :"@volatile_#{name}" + + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{name} + ::Concurrent::Synchronization::JRubyAttrVolatile.instance_variable_get_volatile(self, :#{ivar}) + end + + def #{name}=(value) + ::Concurrent::Synchronization::JRubyAttrVolatile.instance_variable_set_volatile(self, :#{ivar}, value) + end + RUBY + + end + names.map { |n| [n, :"#{n}="] }.flatten + end + + else + warn 'Possibly unsupported Ruby implementation' unless Concurrent.on_truffleruby? + + def attr_volatile(*names) + names.each do |name| + ivar = :"@volatile_#{name}" + + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{name} + ::Concurrent::Synchronization.full_memory_barrier + #{ivar} + end + + def #{name}=(value) + #{ivar} = value + ::Concurrent::Synchronization.full_memory_barrier + end + RUBY + end + + names.map { |n| [n, :"#{n}="] }.flatten + end + end + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/thread_safe/synchronized_delegator.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/thread_safe/synchronized_delegator.rb new file mode 100644 index 00000000..019d8438 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/thread_safe/synchronized_delegator.rb @@ -0,0 +1,47 @@ +require 'delegate' +require 'monitor' + +module Concurrent + # This class provides a trivial way to synchronize all calls to a given object + # by wrapping it with a `Delegator` that performs `Monitor#enter/exit` calls + # around the delegated `#send`. Example: + # + # array = [] # not thread-safe on many impls + # array = SynchronizedDelegator.new([]) # thread-safe + # + # A simple `Monitor` provides a very coarse-grained way to synchronize a given + # object, in that it will cause synchronization for methods that have no need + # for it, but this is a trivial way to get thread-safety where none may exist + # currently on some implementations. + # + # This class is currently being considered for inclusion into stdlib, via + # https://bugs.ruby-lang.org/issues/8556 + # + # @!visibility private + class SynchronizedDelegator < SimpleDelegator + def setup + @old_abort = Thread.abort_on_exception + Thread.abort_on_exception = true + end + + def teardown + Thread.abort_on_exception = @old_abort + end + + def initialize(obj) + __setobj__(obj) + @monitor = Monitor.new + end + + def method_missing(method, *args, &block) + monitor = @monitor + begin + monitor.enter + super + ensure + monitor.exit + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/thread_safe/util.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/thread_safe/util.rb new file mode 100644 index 00000000..c67084a2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/thread_safe/util.rb @@ -0,0 +1,16 @@ +module Concurrent + + # @!visibility private + module ThreadSafe + + # @!visibility private + module Util + + # TODO (pitr-ch 15-Oct-2016): migrate to Utility::NativeInteger + FIXNUM_BIT_SIZE = (0.size * 8) - 2 + MAX_INT = (2 ** FIXNUM_BIT_SIZE) - 1 + # TODO (pitr-ch 15-Oct-2016): migrate to Utility::ProcessorCounter + CPU_COUNT = 16 # is there a way to determine this? + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/thread_safe/util/adder.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/thread_safe/util/adder.rb new file mode 100644 index 00000000..852b403b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/thread_safe/util/adder.rb @@ -0,0 +1,74 @@ +require 'concurrent/thread_safe/util' +require 'concurrent/thread_safe/util/striped64' + +module Concurrent + + # @!visibility private + module ThreadSafe + + # @!visibility private + module Util + + # A Ruby port of the Doug Lea's jsr166e.LongAdder class version 1.8 + # available in public domain. + # + # Original source code available here: + # http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/LongAdder.java?revision=1.8 + # + # One or more variables that together maintain an initially zero + # sum. When updates (method +add+) are contended across threads, + # the set of variables may grow dynamically to reduce contention. + # Method +sum+ returns the current total combined across the + # variables maintaining the sum. + # + # This class is usually preferable to single +Atomic+ reference when + # multiple threads update a common sum that is used for purposes such + # as collecting statistics, not for fine-grained synchronization + # control. Under low update contention, the two classes have similar + # characteristics. But under high contention, expected throughput of + # this class is significantly higher, at the expense of higher space + # consumption. + # + # @!visibility private + class Adder < Striped64 + # Adds the given value. + def add(x) + if (current_cells = cells) || !cas_base_computed {|current_base| current_base + x} + was_uncontended = true + hash = hash_code + unless current_cells && (cell = current_cells.volatile_get_by_hash(hash)) && (was_uncontended = cell.cas_computed {|current_value| current_value + x}) + retry_update(x, hash, was_uncontended) {|current_value| current_value + x} + end + end + end + + def increment + add(1) + end + + def decrement + add(-1) + end + + # Returns the current sum. The returned value is _NOT_ an + # atomic snapshot: Invocation in the absence of concurrent + # updates returns an accurate result, but concurrent updates that + # occur while the sum is being calculated might not be + # incorporated. + def sum + x = base + if current_cells = cells + current_cells.each do |cell| + x += cell.value if cell + end + end + x + end + + def reset + internal_reset(0) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/thread_safe/util/data_structures.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/thread_safe/util/data_structures.rb new file mode 100644 index 00000000..01eb98f4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/thread_safe/util/data_structures.rb @@ -0,0 +1,52 @@ +require 'concurrent/thread_safe/util' +require 'concurrent/utility/engine' + +# Shim for TruffleRuby.synchronized +if Concurrent.on_truffleruby? && !TruffleRuby.respond_to?(:synchronized) + module TruffleRuby + def self.synchronized(object, &block) + Truffle::System.synchronized(object, &block) + end + end +end + +module Concurrent + module ThreadSafe + module Util + def self.make_synchronized_on_cruby(klass) + klass.class_eval do + def initialize(*args, &block) + @_monitor = Monitor.new + super + end + + def initialize_copy(other) + # make sure a copy is not sharing a monitor with the original object! + @_monitor = Monitor.new + super + end + end + + klass.superclass.instance_methods(false).each do |method| + klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{method}(*args) + monitor = @_monitor + monitor or raise("BUG: Internal monitor was not properly initialized. Please report this to the concurrent-ruby developers.") + monitor.synchronize { super } + end + RUBY + end + end + + def self.make_synchronized_on_truffleruby(klass) + klass.superclass.instance_methods(false).each do |method| + klass.class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{method}(*args, &block) + TruffleRuby.synchronized(self) { super(*args, &block) } + end + RUBY + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/thread_safe/util/power_of_two_tuple.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/thread_safe/util/power_of_two_tuple.rb new file mode 100644 index 00000000..b54be39c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/thread_safe/util/power_of_two_tuple.rb @@ -0,0 +1,38 @@ +require 'concurrent/thread_safe/util' +require 'concurrent/tuple' + +module Concurrent + + # @!visibility private + module ThreadSafe + + # @!visibility private + module Util + + # @!visibility private + class PowerOfTwoTuple < Concurrent::Tuple + + def initialize(size) + raise ArgumentError, "size must be a power of 2 (#{size.inspect} provided)" unless size > 0 && size & (size - 1) == 0 + super(size) + end + + def hash_to_index(hash) + (size - 1) & hash + end + + def volatile_get_by_hash(hash) + volatile_get(hash_to_index(hash)) + end + + def volatile_set_by_hash(hash, value) + volatile_set(hash_to_index(hash), value) + end + + def next_in_size_table + self.class.new(size << 1) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/thread_safe/util/striped64.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/thread_safe/util/striped64.rb new file mode 100644 index 00000000..4169c3d3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/thread_safe/util/striped64.rb @@ -0,0 +1,246 @@ +require 'concurrent/thread_safe/util' +require 'concurrent/thread_safe/util/power_of_two_tuple' +require 'concurrent/thread_safe/util/volatile' +require 'concurrent/thread_safe/util/xor_shift_random' + +module Concurrent + + # @!visibility private + module ThreadSafe + + # @!visibility private + module Util + + # A Ruby port of the Doug Lea's jsr166e.Striped64 class version 1.6 + # available in public domain. + # + # Original source code available here: + # http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/Striped64.java?revision=1.6 + # + # Class holding common representation and mechanics for classes supporting + # dynamic striping on 64bit values. + # + # This class maintains a lazily-initialized table of atomically updated + # variables, plus an extra +base+ field. The table size is a power of two. + # Indexing uses masked per-thread hash codes. Nearly all methods on this + # class are private, accessed directly by subclasses. + # + # Table entries are of class +Cell+; a variant of AtomicLong padded to + # reduce cache contention on most processors. Padding is overkill for most + # Atomics because they are usually irregularly scattered in memory and thus + # don't interfere much with each other. But Atomic objects residing in + # arrays will tend to be placed adjacent to each other, and so will most + # often share cache lines (with a huge negative performance impact) without + # this precaution. + # + # In part because +Cell+s are relatively large, we avoid creating them until + # they are needed. When there is no contention, all updates are made to the + # +base+ field. Upon first contention (a failed CAS on +base+ update), the + # table is initialized to size 2. The table size is doubled upon further + # contention until reaching the nearest power of two greater than or equal + # to the number of CPUS. Table slots remain empty (+nil+) until they are + # needed. + # + # A single spinlock (+busy+) is used for initializing and resizing the + # table, as well as populating slots with new +Cell+s. There is no need for + # a blocking lock: When the lock is not available, threads try other slots + # (or the base). During these retries, there is increased contention and + # reduced locality, which is still better than alternatives. + # + # Per-thread hash codes are initialized to random values. Contention and/or + # table collisions are indicated by failed CASes when performing an update + # operation (see method +retry_update+). Upon a collision, if the table size + # is less than the capacity, it is doubled in size unless some other thread + # holds the lock. If a hashed slot is empty, and lock is available, a new + # +Cell+ is created. Otherwise, if the slot exists, a CAS is tried. Retries + # proceed by "double hashing", using a secondary hash (XorShift) to try to + # find a free slot. + # + # The table size is capped because, when there are more threads than CPUs, + # supposing that each thread were bound to a CPU, there would exist a + # perfect hash function mapping threads to slots that eliminates collisions. + # When we reach capacity, we search for this mapping by randomly varying the + # hash codes of colliding threads. Because search is random, and collisions + # only become known via CAS failures, convergence can be slow, and because + # threads are typically not bound to CPUS forever, may not occur at all. + # However, despite these limitations, observed contention rates are + # typically low in these cases. + # + # It is possible for a +Cell+ to become unused when threads that once hashed + # to it terminate, as well as in the case where doubling the table causes no + # thread to hash to it under expanded mask. We do not try to detect or + # remove such cells, under the assumption that for long-running instances, + # observed contention levels will recur, so the cells will eventually be + # needed again; and for short-lived ones, it does not matter. + # + # @!visibility private + class Striped64 + + # Padded variant of AtomicLong supporting only raw accesses plus CAS. + # The +value+ field is placed between pads, hoping that the JVM doesn't + # reorder them. + # + # Optimisation note: It would be possible to use a release-only + # form of CAS here, if it were provided. + # + # @!visibility private + class Cell < Concurrent::AtomicReference + + alias_method :cas, :compare_and_set + + def cas_computed + cas(current_value = value, yield(current_value)) + end + + # @!visibility private + def self.padding + # TODO: this only adds padding after the :value slot, need to find a way to add padding before the slot + # TODO (pitr-ch 28-Jul-2018): the padding instance vars may not be created + # hide from yardoc in a method + attr_reader :padding_0, :padding_1, :padding_2, :padding_3, :padding_4, :padding_5, :padding_6, :padding_7, :padding_8, :padding_9, :padding_10, :padding_11 + end + padding + end + + extend Volatile + attr_volatile :cells, # Table of cells. When non-null, size is a power of 2. + :base, # Base value, used mainly when there is no contention, but also as a fallback during table initialization races. Updated via CAS. + :busy # Spinlock (locked via CAS) used when resizing and/or creating Cells. + + alias_method :busy?, :busy + + def initialize + super() + self.busy = false + self.base = 0 + end + + # Handles cases of updates involving initialization, resizing, + # creating new Cells, and/or contention. See above for + # explanation. This method suffers the usual non-modularity + # problems of optimistic retry code, relying on rechecked sets of + # reads. + # + # Arguments: + # [+x+] + # the value + # [+hash_code+] + # hash code used + # [+x+] + # false if CAS failed before call + def retry_update(x, hash_code, was_uncontended) # :yields: current_value + hash = hash_code + collided = false # True if last slot nonempty + while true + if current_cells = cells + if !(cell = current_cells.volatile_get_by_hash(hash)) + if busy? + collided = false + else # Try to attach new Cell + if try_to_install_new_cell(Cell.new(x), hash) # Optimistically create and try to insert new cell + break + else + redo # Slot is now non-empty + end + end + elsif !was_uncontended # CAS already known to fail + was_uncontended = true # Continue after rehash + elsif cell.cas_computed {|current_value| yield current_value} + break + elsif current_cells.size >= CPU_COUNT || cells != current_cells # At max size or stale + collided = false + elsif collided && expand_table_unless_stale(current_cells) + collided = false + redo # Retry with expanded table + else + collided = true + end + hash = XorShiftRandom.xorshift(hash) + + elsif try_initialize_cells(x, hash) || cas_base_computed {|current_base| yield current_base} + break + end + end + self.hash_code = hash + end + + private + # Static per-thread hash code key. Shared across all instances to + # reduce Thread locals pollution and because adjustments due to + # collisions in one table are likely to be appropriate for + # others. + THREAD_LOCAL_KEY = "#{name}.hash_code".to_sym + + # A thread-local hash code accessor. The code is initially + # random, but may be set to a different value upon collisions. + def hash_code + Thread.current[THREAD_LOCAL_KEY] ||= XorShiftRandom.get + end + + def hash_code=(hash) + Thread.current[THREAD_LOCAL_KEY] = hash + end + + # Sets base and all +cells+ to the given value. + def internal_reset(initial_value) + current_cells = cells + self.base = initial_value + if current_cells + current_cells.each do |cell| + cell.value = initial_value if cell + end + end + end + + def cas_base_computed + cas_base(current_base = base, yield(current_base)) + end + + def free? + !busy? + end + + def try_initialize_cells(x, hash) + if free? && !cells + try_in_busy do + unless cells # Recheck under lock + new_cells = PowerOfTwoTuple.new(2) + new_cells.volatile_set_by_hash(hash, Cell.new(x)) + self.cells = new_cells + end + end + end + end + + def expand_table_unless_stale(current_cells) + try_in_busy do + if current_cells == cells # Recheck under lock + new_cells = current_cells.next_in_size_table + current_cells.each_with_index {|x, i| new_cells.volatile_set(i, x)} + self.cells = new_cells + end + end + end + + def try_to_install_new_cell(new_cell, hash) + try_in_busy do + # Recheck under lock + if (current_cells = cells) && !current_cells.volatile_get(i = current_cells.hash_to_index(hash)) + current_cells.volatile_set(i, new_cell) + end + end + end + + def try_in_busy + if cas_busy(false, true) + begin + yield + ensure + self.busy = false + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/thread_safe/util/volatile.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/thread_safe/util/volatile.rb new file mode 100644 index 00000000..cdac2a39 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/thread_safe/util/volatile.rb @@ -0,0 +1,75 @@ +require 'concurrent/thread_safe/util' + +module Concurrent + + # @!visibility private + module ThreadSafe + + # @!visibility private + module Util + + # @!visibility private + module Volatile + + # Provides +volatile+ (in the JVM's sense) attribute accessors implemented + # atop of +Concurrent::AtomicReference+. + # + # Usage: + # class Foo + # extend Concurrent::ThreadSafe::Util::Volatile + # attr_volatile :foo, :bar + # + # def initialize(bar) + # super() # must super() into parent initializers before using the volatile attribute accessors + # self.bar = bar + # end + # + # def hello + # my_foo = foo # volatile read + # self.foo = 1 # volatile write + # cas_foo(1, 2) # => true | a strong CAS + # end + # end + def attr_volatile(*attr_names) + return if attr_names.empty? + include(Module.new do + atomic_ref_setup = attr_names.map {|attr_name| "@__#{attr_name} = Concurrent::AtomicReference.new"} + initialize_copy_setup = attr_names.zip(atomic_ref_setup).map do |attr_name, ref_setup| + "#{ref_setup}(other.instance_variable_get(:@__#{attr_name}).get)" + end + class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 + def initialize(*) + super + #{atomic_ref_setup.join('; ')} + end + + def initialize_copy(other) + super + #{initialize_copy_setup.join('; ')} + end + RUBY_EVAL + + attr_names.each do |attr_name| + class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 + def #{attr_name} + @__#{attr_name}.get + end + + def #{attr_name}=(value) + @__#{attr_name}.set(value) + end + + def compare_and_set_#{attr_name}(old_value, new_value) + @__#{attr_name}.compare_and_set(old_value, new_value) + end + RUBY_EVAL + + alias_method :"cas_#{attr_name}", :"compare_and_set_#{attr_name}" + alias_method :"lazy_set_#{attr_name}", :"#{attr_name}=" + end + end) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/thread_safe/util/xor_shift_random.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/thread_safe/util/xor_shift_random.rb new file mode 100644 index 00000000..c231d182 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/thread_safe/util/xor_shift_random.rb @@ -0,0 +1,50 @@ +require 'concurrent/thread_safe/util' + +module Concurrent + + # @!visibility private + module ThreadSafe + + # @!visibility private + module Util + + # A xorshift random number (positive +Fixnum+s) generator, provides + # reasonably cheap way to generate thread local random numbers without + # contending for the global +Kernel.rand+. + # + # Usage: + # x = XorShiftRandom.get # uses Kernel.rand to generate an initial seed + # while true + # if (x = XorShiftRandom.xorshift).odd? # thread-locally generate a next random number + # do_something_at_random + # end + # end + module XorShiftRandom + extend self + MAX_XOR_SHIFTABLE_INT = MAX_INT - 1 + + # Generates an initial non-zero positive +Fixnum+ via +Kernel.rand+. + def get + Kernel.rand(MAX_XOR_SHIFTABLE_INT) + 1 # 0 can't be xorshifted + end + + # xorshift based on: http://www.jstatsoft.org/v08/i14/paper + if 0.size == 4 + # using the "yˆ=y>>a; yˆ=y<>c;" transform with the (a,b,c) tuple with values (3,1,14) to minimise Bignum overflows + def xorshift(x) + x ^= x >> 3 + x ^= (x << 1) & MAX_INT # cut-off Bignum overflow + x ^= x >> 14 + end + else + # using the "yˆ=y>>a; yˆ=y<>c;" transform with the (a,b,c) tuple with values (1,1,54) to minimise Bignum overflows + def xorshift(x) + x ^= x >> 1 + x ^= (x << 1) & MAX_INT # cut-off Bignum overflow + x ^= x >> 54 + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/timer_task.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/timer_task.rb new file mode 100644 index 00000000..dd2037f6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/timer_task.rb @@ -0,0 +1,361 @@ +require 'concurrent/collection/copy_on_notify_observer_set' +require 'concurrent/concern/dereferenceable' +require 'concurrent/concern/observable' +require 'concurrent/atomic/atomic_boolean' +require 'concurrent/executor/executor_service' +require 'concurrent/executor/ruby_executor_service' +require 'concurrent/executor/safe_task_executor' +require 'concurrent/scheduled_task' + +module Concurrent + + # A very common concurrency pattern is to run a thread that performs a task at + # regular intervals. The thread that performs the task sleeps for the given + # interval then wakes up and performs the task. Lather, rinse, repeat... This + # pattern causes two problems. First, it is difficult to test the business + # logic of the task because the task itself is tightly coupled with the + # concurrency logic. Second, an exception raised while performing the task can + # cause the entire thread to abend. In a long-running application where the + # task thread is intended to run for days/weeks/years a crashed task thread + # can pose a significant problem. `TimerTask` alleviates both problems. + # + # When a `TimerTask` is launched it starts a thread for monitoring the + # execution interval. The `TimerTask` thread does not perform the task, + # however. Instead, the TimerTask launches the task on a separate thread. + # Should the task experience an unrecoverable crash only the task thread will + # crash. This makes the `TimerTask` very fault tolerant. Additionally, the + # `TimerTask` thread can respond to the success or failure of the task, + # performing logging or ancillary operations. + # + # One other advantage of `TimerTask` is that it forces the business logic to + # be completely decoupled from the concurrency logic. The business logic can + # be tested separately then passed to the `TimerTask` for scheduling and + # running. + # + # A `TimerTask` supports two different types of interval calculations. + # A fixed delay will always wait the same amount of time between the + # completion of one task and the start of the next. A fixed rate will + # attempt to maintain a constant rate of execution regardless of the + # duration of the task. For example, if a fixed rate task is scheduled + # to run every 60 seconds but the task itself takes 10 seconds to + # complete, the next task will be scheduled to run 50 seconds after + # the start of the previous task. If the task takes 70 seconds to + # complete, the next task will be start immediately after the previous + # task completes. Tasks will not be executed concurrently. + # + # In some cases it may be necessary for a `TimerTask` to affect its own + # execution cycle. To facilitate this, a reference to the TimerTask instance + # is passed as an argument to the provided block every time the task is + # executed. + # + # The `TimerTask` class includes the `Dereferenceable` mixin module so the + # result of the last execution is always available via the `#value` method. + # Dereferencing options can be passed to the `TimerTask` during construction or + # at any later time using the `#set_deref_options` method. + # + # `TimerTask` supports notification through the Ruby standard library + # {http://ruby-doc.org/stdlib-2.0/libdoc/observer/rdoc/Observable.html + # Observable} module. On execution the `TimerTask` will notify the observers + # with three arguments: time of execution, the result of the block (or nil on + # failure), and any raised exceptions (or nil on success). + # + # @!macro copy_options + # + # @example Basic usage + # task = Concurrent::TimerTask.new{ puts 'Boom!' } + # task.execute + # + # task.execution_interval #=> 60 (default) + # + # # wait 60 seconds... + # #=> 'Boom!' + # + # task.shutdown #=> true + # + # @example Configuring `:execution_interval` + # task = Concurrent::TimerTask.new(execution_interval: 5) do + # puts 'Boom!' + # end + # + # task.execution_interval #=> 5 + # + # @example Immediate execution with `:run_now` + # task = Concurrent::TimerTask.new(run_now: true){ puts 'Boom!' } + # task.execute + # + # #=> 'Boom!' + # + # @example Configuring `:interval_type` with either :fixed_delay or :fixed_rate, default is :fixed_delay + # task = Concurrent::TimerTask.new(execution_interval: 5, interval_type: :fixed_rate) do + # puts 'Boom!' + # end + # task.interval_type #=> :fixed_rate + # + # @example Last `#value` and `Dereferenceable` mixin + # task = Concurrent::TimerTask.new( + # dup_on_deref: true, + # execution_interval: 5 + # ){ Time.now } + # + # task.execute + # Time.now #=> 2013-11-07 18:06:50 -0500 + # sleep(10) + # task.value #=> 2013-11-07 18:06:55 -0500 + # + # @example Controlling execution from within the block + # timer_task = Concurrent::TimerTask.new(execution_interval: 1) do |task| + # task.execution_interval.to_i.times{ print 'Boom! ' } + # print "\n" + # task.execution_interval += 1 + # if task.execution_interval > 5 + # puts 'Stopping...' + # task.shutdown + # end + # end + # + # timer_task.execute + # #=> Boom! + # #=> Boom! Boom! + # #=> Boom! Boom! Boom! + # #=> Boom! Boom! Boom! Boom! + # #=> Boom! Boom! Boom! Boom! Boom! + # #=> Stopping... + # + # @example Observation + # class TaskObserver + # def update(time, result, ex) + # if result + # print "(#{time}) Execution successfully returned #{result}\n" + # else + # print "(#{time}) Execution failed with error #{ex}\n" + # end + # end + # end + # + # task = Concurrent::TimerTask.new(execution_interval: 1){ 42 } + # task.add_observer(TaskObserver.new) + # task.execute + # sleep 4 + # + # #=> (2013-10-13 19:08:58 -0400) Execution successfully returned 42 + # #=> (2013-10-13 19:08:59 -0400) Execution successfully returned 42 + # #=> (2013-10-13 19:09:00 -0400) Execution successfully returned 42 + # task.shutdown + # + # task = Concurrent::TimerTask.new(execution_interval: 1){ sleep } + # task.add_observer(TaskObserver.new) + # task.execute + # + # #=> (2013-10-13 19:07:25 -0400) Execution timed out + # #=> (2013-10-13 19:07:27 -0400) Execution timed out + # #=> (2013-10-13 19:07:29 -0400) Execution timed out + # task.shutdown + # + # task = Concurrent::TimerTask.new(execution_interval: 1){ raise StandardError } + # task.add_observer(TaskObserver.new) + # task.execute + # + # #=> (2013-10-13 19:09:37 -0400) Execution failed with error StandardError + # #=> (2013-10-13 19:09:38 -0400) Execution failed with error StandardError + # #=> (2013-10-13 19:09:39 -0400) Execution failed with error StandardError + # task.shutdown + # + # @see http://ruby-doc.org/stdlib-2.0/libdoc/observer/rdoc/Observable.html + # @see http://docs.oracle.com/javase/7/docs/api/java/util/TimerTask.html + class TimerTask < RubyExecutorService + include Concern::Dereferenceable + include Concern::Observable + + # Default `:execution_interval` in seconds. + EXECUTION_INTERVAL = 60 + + # Maintain the interval between the end of one execution and the start of the next execution. + FIXED_DELAY = :fixed_delay + + # Maintain the interval between the start of one execution and the start of the next. + # If execution time exceeds the interval, the next execution will start immediately + # after the previous execution finishes. Executions will not run concurrently. + FIXED_RATE = :fixed_rate + + # Default `:interval_type` + DEFAULT_INTERVAL_TYPE = FIXED_DELAY + + # Create a new TimerTask with the given task and configuration. + # + # @!macro timer_task_initialize + # @param [Hash] opts the options defining task execution. + # @option opts [Float] :execution_interval number of seconds between + # task executions (default: EXECUTION_INTERVAL) + # @option opts [Boolean] :run_now Whether to run the task immediately + # upon instantiation or to wait until the first # execution_interval + # has passed (default: false) + # @options opts [Symbol] :interval_type method to calculate the interval + # between executions, can be either :fixed_rate or :fixed_delay. + # (default: :fixed_delay) + # @option opts [Executor] executor, default is `global_io_executor` + # + # @!macro deref_options + # + # @raise ArgumentError when no block is given. + # + # @yield to the block after :execution_interval seconds have passed since + # the last yield + # @yieldparam task a reference to the `TimerTask` instance so that the + # block can control its own lifecycle. Necessary since `self` will + # refer to the execution context of the block rather than the running + # `TimerTask`. + # + # @return [TimerTask] the new `TimerTask` + def initialize(opts = {}, &task) + raise ArgumentError.new('no block given') unless block_given? + super + set_deref_options opts + end + + # Is the executor running? + # + # @return [Boolean] `true` when running, `false` when shutting down or shutdown + def running? + @running.true? + end + + # Execute a previously created `TimerTask`. + # + # @return [TimerTask] a reference to `self` + # + # @example Instance and execute in separate steps + # task = Concurrent::TimerTask.new(execution_interval: 10){ print "Hello World\n" } + # task.running? #=> false + # task.execute + # task.running? #=> true + # + # @example Instance and execute in one line + # task = Concurrent::TimerTask.new(execution_interval: 10){ print "Hello World\n" }.execute + # task.running? #=> true + def execute + synchronize do + if @running.false? + @running.make_true + schedule_next_task(@run_now ? 0 : @execution_interval) + end + end + self + end + + # Create and execute a new `TimerTask`. + # + # @!macro timer_task_initialize + # + # @example + # task = Concurrent::TimerTask.execute(execution_interval: 10){ print "Hello World\n" } + # task.running? #=> true + def self.execute(opts = {}, &task) + TimerTask.new(opts, &task).execute + end + + # @!attribute [rw] execution_interval + # @return [Fixnum] Number of seconds after the task completes before the + # task is performed again. + def execution_interval + synchronize { @execution_interval } + end + + # @!attribute [rw] execution_interval + # @return [Fixnum] Number of seconds after the task completes before the + # task is performed again. + def execution_interval=(value) + if (value = value.to_f) <= 0.0 + raise ArgumentError.new('must be greater than zero') + else + synchronize { @execution_interval = value } + end + end + + # @!attribute [r] interval_type + # @return [Symbol] method to calculate the interval between executions + attr_reader :interval_type + + # @!attribute [rw] timeout_interval + # @return [Fixnum] Number of seconds the task can run before it is + # considered to have failed. + def timeout_interval + warn 'TimerTask timeouts are now ignored as these were not able to be implemented correctly' + end + + # @!attribute [rw] timeout_interval + # @return [Fixnum] Number of seconds the task can run before it is + # considered to have failed. + def timeout_interval=(value) + warn 'TimerTask timeouts are now ignored as these were not able to be implemented correctly' + end + + private :post, :<< + + private + + def ns_initialize(opts, &task) + set_deref_options(opts) + + self.execution_interval = opts[:execution] || opts[:execution_interval] || EXECUTION_INTERVAL + if opts[:interval_type] && ![FIXED_DELAY, FIXED_RATE].include?(opts[:interval_type]) + raise ArgumentError.new('interval_type must be either :fixed_delay or :fixed_rate') + end + if opts[:timeout] || opts[:timeout_interval] + warn 'TimeTask timeouts are now ignored as these were not able to be implemented correctly' + end + + @run_now = opts[:now] || opts[:run_now] + @interval_type = opts[:interval_type] || DEFAULT_INTERVAL_TYPE + @task = Concurrent::SafeTaskExecutor.new(task) + @executor = opts[:executor] || Concurrent.global_io_executor + @running = Concurrent::AtomicBoolean.new(false) + @value = nil + + self.observers = Collection::CopyOnNotifyObserverSet.new + end + + # @!visibility private + def ns_shutdown_execution + @running.make_false + super + end + + # @!visibility private + def ns_kill_execution + @running.make_false + super + end + + # @!visibility private + def schedule_next_task(interval = execution_interval) + ScheduledTask.execute(interval, executor: @executor, args: [Concurrent::Event.new], &method(:execute_task)) + nil + end + + # @!visibility private + def execute_task(completion) + return nil unless @running.true? + start_time = Concurrent.monotonic_time + _success, value, reason = @task.execute(self) + if completion.try? + self.value = value + schedule_next_task(calculate_next_interval(start_time)) + time = Time.now + observers.notify_observers do + [time, self.value, reason] + end + end + nil + end + + # @!visibility private + def calculate_next_interval(start_time) + if @interval_type == FIXED_RATE + run_time = Concurrent.monotonic_time - start_time + [execution_interval - run_time, 0].max + else # FIXED_DELAY + execution_interval + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/tuple.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/tuple.rb new file mode 100644 index 00000000..56212cfd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/tuple.rb @@ -0,0 +1,82 @@ +require 'concurrent/atomic/atomic_reference' + +module Concurrent + + # A fixed size array with volatile (synchronized, thread safe) getters/setters. + # Mixes in Ruby's `Enumerable` module for enhanced search, sort, and traversal. + # + # @example + # tuple = Concurrent::Tuple.new(16) + # + # tuple.set(0, :foo) #=> :foo | volatile write + # tuple.get(0) #=> :foo | volatile read + # tuple.compare_and_set(0, :foo, :bar) #=> true | strong CAS + # tuple.cas(0, :foo, :baz) #=> false | strong CAS + # tuple.get(0) #=> :bar | volatile read + # + # @see https://en.wikipedia.org/wiki/Tuple Tuple entry at Wikipedia + # @see http://www.erlang.org/doc/reference_manual/data_types.html#id70396 Erlang Tuple + # @see http://ruby-doc.org/core-2.2.2/Enumerable.html Enumerable + class Tuple + include Enumerable + + # The (fixed) size of the tuple. + attr_reader :size + + # Create a new tuple of the given size. + # + # @param [Integer] size the number of elements in the tuple + def initialize(size) + @size = size + @tuple = tuple = ::Array.new(size) + i = 0 + while i < size + tuple[i] = Concurrent::AtomicReference.new + i += 1 + end + end + + # Get the value of the element at the given index. + # + # @param [Integer] i the index from which to retrieve the value + # @return [Object] the value at the given index or nil if the index is out of bounds + def get(i) + return nil if i >= @size || i < 0 + @tuple[i].get + end + alias_method :volatile_get, :get + + # Set the element at the given index to the given value + # + # @param [Integer] i the index for the element to set + # @param [Object] value the value to set at the given index + # + # @return [Object] the new value of the element at the given index or nil if the index is out of bounds + def set(i, value) + return nil if i >= @size || i < 0 + @tuple[i].set(value) + end + alias_method :volatile_set, :set + + # Set the value at the given index to the new value if and only if the current + # value matches the given old value. + # + # @param [Integer] i the index for the element to set + # @param [Object] old_value the value to compare against the current value + # @param [Object] new_value the value to set at the given index + # + # @return [Boolean] true if the value at the given element was set else false + def compare_and_set(i, old_value, new_value) + return false if i >= @size || i < 0 + @tuple[i].compare_and_set(old_value, new_value) + end + alias_method :cas, :compare_and_set + + # Calls the given block once for each element in self, passing that element as a parameter. + # + # @yieldparam [Object] ref the `Concurrent::AtomicReference` object at the current index + def each + @tuple.each {|ref| yield ref.get} + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/tvar.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/tvar.rb new file mode 100644 index 00000000..5d02ef09 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/tvar.rb @@ -0,0 +1,222 @@ +require 'set' +require 'concurrent/synchronization/object' + +module Concurrent + + # A `TVar` is a transactional variable - a single-element container that + # is used as part of a transaction - see `Concurrent::atomically`. + # + # @!macro thread_safe_variable_comparison + # + # {include:file:docs-source/tvar.md} + class TVar < Synchronization::Object + safe_initialization! + + # Create a new `TVar` with an initial value. + def initialize(value) + @value = value + @lock = Mutex.new + end + + # Get the value of a `TVar`. + def value + Concurrent::atomically do + Transaction::current.read(self) + end + end + + # Set the value of a `TVar`. + def value=(value) + Concurrent::atomically do + Transaction::current.write(self, value) + end + end + + # @!visibility private + def unsafe_value # :nodoc: + @value + end + + # @!visibility private + def unsafe_value=(value) # :nodoc: + @value = value + end + + # @!visibility private + def unsafe_lock # :nodoc: + @lock + end + + end + + # Run a block that reads and writes `TVar`s as a single atomic transaction. + # With respect to the value of `TVar` objects, the transaction is atomic, in + # that it either happens or it does not, consistent, in that the `TVar` + # objects involved will never enter an illegal state, and isolated, in that + # transactions never interfere with each other. You may recognise these + # properties from database transactions. + # + # There are some very important and unusual semantics that you must be aware of: + # + # * Most importantly, the block that you pass to atomically may be executed + # more than once. In most cases your code should be free of + # side-effects, except for via TVar. + # + # * If an exception escapes an atomically block it will abort the transaction. + # + # * It is undefined behaviour to use callcc or Fiber with atomically. + # + # * If you create a new thread within an atomically, it will not be part of + # the transaction. Creating a thread counts as a side-effect. + # + # Transactions within transactions are flattened to a single transaction. + # + # @example + # a = new TVar(100_000) + # b = new TVar(100) + # + # Concurrent::atomically do + # a.value -= 10 + # b.value += 10 + # end + def atomically + raise ArgumentError.new('no block given') unless block_given? + + # Get the current transaction + + transaction = Transaction::current + + # Are we not already in a transaction (not nested)? + + if transaction.nil? + # New transaction + + begin + # Retry loop + + loop do + + # Create a new transaction + + transaction = Transaction.new + Transaction::current = transaction + + # Run the block, aborting on exceptions + + begin + result = yield + rescue Transaction::AbortError => e + transaction.abort + result = Transaction::ABORTED + rescue Transaction::LeaveError => e + transaction.abort + break result + rescue => e + transaction.abort + raise e + end + # If we can commit, break out of the loop + + if result != Transaction::ABORTED + if transaction.commit + break result + end + end + end + ensure + # Clear the current transaction + + Transaction::current = nil + end + else + # Nested transaction - flatten it and just run the block + + yield + end + end + + # Abort a currently running transaction - see `Concurrent::atomically`. + def abort_transaction + raise Transaction::AbortError.new + end + + # Leave a transaction without committing or aborting - see `Concurrent::atomically`. + def leave_transaction + raise Transaction::LeaveError.new + end + + module_function :atomically, :abort_transaction, :leave_transaction + + private + + # @!visibility private + class Transaction + + ABORTED = ::Object.new + + OpenEntry = Struct.new(:value, :modified) + + AbortError = Class.new(StandardError) + LeaveError = Class.new(StandardError) + + def initialize + @open_tvars = {} + end + + def read(tvar) + entry = open(tvar) + entry.value + end + + def write(tvar, value) + entry = open(tvar) + entry.modified = true + entry.value = value + end + + def open(tvar) + entry = @open_tvars[tvar] + + unless entry + unless tvar.unsafe_lock.try_lock + Concurrent::abort_transaction + end + + entry = OpenEntry.new(tvar.unsafe_value, false) + @open_tvars[tvar] = entry + end + + entry + end + + def abort + unlock + end + + def commit + @open_tvars.each do |tvar, entry| + if entry.modified + tvar.unsafe_value = entry.value + end + end + + unlock + end + + def unlock + @open_tvars.each_key do |tvar| + tvar.unsafe_lock.unlock + end + end + + def self.current + Thread.current[:current_tvar_transaction] + end + + def self.current=(transaction) + Thread.current[:current_tvar_transaction] = transaction + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/utility/engine.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/utility/engine.rb new file mode 100644 index 00000000..0c574b2a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/utility/engine.rb @@ -0,0 +1,45 @@ +module Concurrent + # @!visibility private + module Utility + + # @!visibility private + module EngineDetector + def on_cruby? + RUBY_ENGINE == 'ruby' + end + + def on_jruby? + RUBY_ENGINE == 'jruby' + end + + def on_truffleruby? + RUBY_ENGINE == 'truffleruby' + end + + def on_windows? + !(RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/).nil? + end + + def on_osx? + !(RbConfig::CONFIG['host_os'] =~ /darwin|mac os/).nil? + end + + def on_linux? + !(RbConfig::CONFIG['host_os'] =~ /linux/).nil? + end + + def ruby_version(version = RUBY_VERSION, comparison, major, minor, patch) + result = (version.split('.').map(&:to_i) <=> [major, minor, patch]) + comparisons = { :== => [0], + :>= => [1, 0], + :<= => [-1, 0], + :> => [1], + :< => [-1] } + comparisons.fetch(comparison).include? result + end + end + end + + # @!visibility private + extend Utility::EngineDetector +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/utility/monotonic_time.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/utility/monotonic_time.rb new file mode 100644 index 00000000..1c987d8a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/utility/monotonic_time.rb @@ -0,0 +1,19 @@ +module Concurrent + + # @!macro monotonic_get_time + # + # Returns the current time as tracked by the application monotonic clock. + # + # @param [Symbol] unit the time unit to be returned, can be either + # :float_second, :float_millisecond, :float_microsecond, :second, + # :millisecond, :microsecond, or :nanosecond default to :float_second. + # + # @return [Float] The current monotonic time since some unspecified + # starting point + # + # @!macro monotonic_clock_warning + def monotonic_time(unit = :float_second) + Process.clock_gettime(Process::CLOCK_MONOTONIC, unit) + end + module_function :monotonic_time +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb new file mode 100644 index 00000000..bf7bab35 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/utility/native_extension_loader.rb @@ -0,0 +1,77 @@ +require 'concurrent/utility/engine' +# Synchronization::AbstractObject must be defined before loading the extension +require 'concurrent/synchronization/abstract_object' + +module Concurrent + # @!visibility private + module Utility + # @!visibility private + module NativeExtensionLoader + + def allow_c_extensions? + Concurrent.on_cruby? + end + + def c_extensions_loaded? + defined?(@c_extensions_loaded) && @c_extensions_loaded + end + + def load_native_extensions + if Concurrent.on_cruby? && !c_extensions_loaded? + ['concurrent/concurrent_ruby_ext', + "concurrent/#{RUBY_VERSION[0..2]}/concurrent_ruby_ext" + ].each { |p| try_load_c_extension p } + end + + if Concurrent.on_jruby? && !java_extensions_loaded? + begin + require 'concurrent/concurrent_ruby.jar' + set_java_extensions_loaded + rescue LoadError => e + raise e, "Java extensions are required for JRuby.\n" + e.message, e.backtrace + end + end + end + + private + + def load_error_path(error) + if error.respond_to? :path + error.path + else + error.message.split(' -- ').last + end + end + + def set_c_extensions_loaded + @c_extensions_loaded = true + end + + def java_extensions_loaded? + defined?(@java_extensions_loaded) && @java_extensions_loaded + end + + def set_java_extensions_loaded + @java_extensions_loaded = true + end + + def try_load_c_extension(path) + require path + set_c_extensions_loaded + rescue LoadError => e + if load_error_path(e) == path + # move on with pure-Ruby implementations + # TODO (pitr-ch 12-Jul-2018): warning on verbose? + else + raise e + end + end + + end + end + + # @!visibility private + extend Utility::NativeExtensionLoader +end + +Concurrent.load_native_extensions diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/utility/native_integer.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/utility/native_integer.rb new file mode 100644 index 00000000..de1cdc30 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/utility/native_integer.rb @@ -0,0 +1,54 @@ +module Concurrent + # @!visibility private + module Utility + # @private + module NativeInteger + # http://stackoverflow.com/questions/535721/ruby-max-integer + MIN_VALUE = -(2**(0.size * 8 - 2)) + MAX_VALUE = (2**(0.size * 8 - 2) - 1) + + def ensure_upper_bound(value) + if value > MAX_VALUE + raise RangeError.new("#{value} is greater than the maximum value of #{MAX_VALUE}") + end + value + end + + def ensure_lower_bound(value) + if value < MIN_VALUE + raise RangeError.new("#{value} is less than the maximum value of #{MIN_VALUE}") + end + value + end + + def ensure_integer(value) + unless value.is_a?(Integer) + raise ArgumentError.new("#{value} is not an Integer") + end + value + end + + def ensure_integer_and_bounds(value) + ensure_integer value + ensure_upper_bound value + ensure_lower_bound value + end + + def ensure_positive(value) + if value < 0 + raise ArgumentError.new("#{value} cannot be negative") + end + value + end + + def ensure_positive_and_no_zero(value) + if value < 1 + raise ArgumentError.new("#{value} cannot be negative or zero") + end + value + end + + extend self + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/utility/processor_counter.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/utility/processor_counter.rb new file mode 100644 index 00000000..2489cbd7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/utility/processor_counter.rb @@ -0,0 +1,220 @@ +require 'etc' +require 'rbconfig' +require 'concurrent/delay' + +module Concurrent + # @!visibility private + module Utility + + # @!visibility private + class ProcessorCounter + def initialize + @processor_count = Delay.new { compute_processor_count } + @physical_processor_count = Delay.new { compute_physical_processor_count } + @cpu_quota = Delay.new { compute_cpu_quota } + @cpu_shares = Delay.new { compute_cpu_shares } + end + + def processor_count + @processor_count.value + end + + def physical_processor_count + @physical_processor_count.value + end + + def available_processor_count + cpu_count = processor_count.to_f + quota = cpu_quota + + return cpu_count if quota.nil? + + # cgroup cpus quotas have no limits, so they can be set to higher than the + # real count of cores. + if quota > cpu_count + cpu_count + else + quota + end + end + + def cpu_quota + @cpu_quota.value + end + + def cpu_shares + @cpu_shares.value + end + + private + + def compute_processor_count + if Concurrent.on_jruby? + java.lang.Runtime.getRuntime.availableProcessors + else + Etc.nprocessors + end + end + + def compute_physical_processor_count + ppc = case RbConfig::CONFIG["target_os"] + when /darwin\d\d/ + IO.popen("/usr/sbin/sysctl -n hw.physicalcpu", &:read).to_i + when /linux/ + cores = {} # unique physical ID / core ID combinations + phy = 0 + IO.read("/proc/cpuinfo").scan(/^physical id.*|^core id.*/) do |ln| + if ln.start_with?("physical") + phy = ln[/\d+/] + elsif ln.start_with?("core") + cid = phy + ":" + ln[/\d+/] + cores[cid] = true if not cores[cid] + end + end + cores.count + when /mswin|mingw/ + # Get-CimInstance introduced in PowerShell 3 or earlier: https://learn.microsoft.com/en-us/previous-versions/powershell/module/cimcmdlets/get-ciminstance?view=powershell-3.0 + result = run('powershell -command "Get-CimInstance -ClassName Win32_Processor -Property NumberOfCores | Select-Object -Property NumberOfCores"') + if !result || $?.exitstatus != 0 + # fallback to deprecated wmic for older systems + result = run("wmic cpu get NumberOfCores") + end + if !result || $?.exitstatus != 0 + # Bail out if both commands returned something unexpected + processor_count + else + # powershell: "\nNumberOfCores\n-------------\n 4\n\n\n" + # wmic: "NumberOfCores \n\n4 \n\n\n\n" + result.scan(/\d+/).map(&:to_i).reduce(:+) + end + else + processor_count + end + # fall back to logical count if physical info is invalid + ppc > 0 ? ppc : processor_count + rescue + return 1 + end + + def run(command) + IO.popen(command, &:read) + rescue Errno::ENOENT + end + + def compute_cpu_quota + if RbConfig::CONFIG["target_os"].include?("linux") + if File.exist?("/sys/fs/cgroup/cpu.max") + # cgroups v2: https://docs.kernel.org/admin-guide/cgroup-v2.html#cpu-interface-files + cpu_max = File.read("/sys/fs/cgroup/cpu.max") + return nil if cpu_max.start_with?("max ") # no limit + max, period = cpu_max.split.map(&:to_f) + max / period + elsif File.exist?("/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us") + # cgroups v1: https://kernel.googlesource.com/pub/scm/linux/kernel/git/glommer/memcg/+/cpu_stat/Documentation/cgroups/cpu.txt + max = File.read("/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us").to_i + # If the cpu.cfs_quota_us is -1, cgroup does not adhere to any CPU time restrictions + # https://docs.kernel.org/scheduler/sched-bwc.html#management + return nil if max <= 0 + period = File.read("/sys/fs/cgroup/cpu,cpuacct/cpu.cfs_period_us").to_f + max / period + end + end + end + + def compute_cpu_shares + if RbConfig::CONFIG["target_os"].include?("linux") + if File.exist?("/sys/fs/cgroup/cpu.weight") + # cgroups v2: https://docs.kernel.org/admin-guide/cgroup-v2.html#cpu-interface-files + # Ref: https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2254-cgroup-v2#phase-1-convert-from-cgroups-v1-settings-to-v2 + weight = File.read("/sys/fs/cgroup/cpu.weight").to_f + ((((weight - 1) * 262142) / 9999) + 2) / 1024 + elsif File.exist?("/sys/fs/cgroup/cpu/cpu.shares") + # cgroups v1: https://kernel.googlesource.com/pub/scm/linux/kernel/git/glommer/memcg/+/cpu_stat/Documentation/cgroups/cpu.txt + File.read("/sys/fs/cgroup/cpu/cpu.shares").to_f / 1024 + end + end + end + end + end + + # create the default ProcessorCounter on load + @processor_counter = Utility::ProcessorCounter.new + singleton_class.send :attr_reader, :processor_counter + + # Number of processors seen by the OS and used for process scheduling. For + # performance reasons the calculated value will be memoized on the first + # call. + # + # When running under JRuby the Java runtime call + # `java.lang.Runtime.getRuntime.availableProcessors` will be used. According + # to the Java documentation this "value may change during a particular + # invocation of the virtual machine... [applications] should therefore + # occasionally poll this property." We still memoize this value once under + # JRuby. + # + # Otherwise Ruby's Etc.nprocessors will be used. + # + # @return [Integer] number of processors seen by the OS or Java runtime + # + # @see http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html#availableProcessors() + def self.processor_count + processor_counter.processor_count + end + + # Number of physical processor cores on the current system. For performance + # reasons the calculated value will be memoized on the first call. + # + # On Windows the Win32 API will be queried for the `NumberOfCores from + # Win32_Processor`. This will return the total number "of cores for the + # current instance of the processor." On Unix-like operating systems either + # the `hwprefs` or `sysctl` utility will be called in a subshell and the + # returned value will be used. In the rare case where none of these methods + # work or an exception is raised the function will simply return 1. + # + # @return [Integer] number physical processor cores on the current system + # + # @see https://github.com/grosser/parallel/blob/4fc8b89d08c7091fe0419ca8fba1ec3ce5a8d185/lib/parallel.rb + # + # @see http://msdn.microsoft.com/en-us/library/aa394373(v=vs.85).aspx + # @see http://www.unix.com/man-page/osx/1/HWPREFS/ + # @see http://linux.die.net/man/8/sysctl + def self.physical_processor_count + processor_counter.physical_processor_count + end + + # Number of processors cores available for process scheduling. + # This method takes in account the CPU quota if the process is inside a cgroup with a + # dedicated CPU quota (typically Docker). + # Otherwise it returns the same value as #processor_count but as a Float. + # + # For performance reasons the calculated value will be memoized on the first + # call. + # + # @return [Float] number of available processors + def self.available_processor_count + processor_counter.available_processor_count + end + + # The maximum number of processors cores available for process scheduling. + # Returns `nil` if there is no enforced limit, or a `Float` if the + # process is inside a cgroup with a dedicated CPU quota (typically Docker). + # + # Note that nothing prevents setting a CPU quota higher than the actual number of + # cores on the system. + # + # For performance reasons the calculated value will be memoized on the first + # call. + # + # @return [nil, Float] Maximum number of available processors as set by a cgroup CPU quota, or nil if none set + def self.cpu_quota + processor_counter.cpu_quota + end + + # The CPU shares requested by the process. For performance reasons the calculated + # value will be memoized on the first call. + # + # @return [Float, nil] CPU shares requested by the process, or nil if not set + def self.cpu_shares + processor_counter.cpu_shares + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/version.rb b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/version.rb new file mode 100644 index 00000000..f773e44f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/concurrent-ruby-1.3.5/lib/concurrent-ruby/concurrent/version.rb @@ -0,0 +1,3 @@ +module Concurrent + VERSION = '1.3.5' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/Changes.md b/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/Changes.md new file mode 100644 index 00000000..8f077fc6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/Changes.md @@ -0,0 +1,185 @@ +# connection_pool Changelog + +2.5.3 +------ + +- Fix TruffleRuby/JRuby crash [#201] + +2.5.2 +------ + +- Rollback inadvertant change to `auto_reload_after_fork` default. [#200] + +2.5.1 +------ + +- Pass options to TimedStack in `checkout` [#195] +- Optimize connection lookup [#196] +- Fixes for use with Ractors + +2.5.0 +------ + +- Reap idle connections [#187] +```ruby +idle_timeout = 60 +pool = ConnectionPool.new ... +pool.reap(idle_timeout, &:close) +``` +- `ConnectionPool#idle` returns the count of connections not in use [#187] + +2.4.1 +------ + +- New `auto_reload_after_fork` config option to disable auto-drop [#177, shayonj] + +2.4.0 +------ + +- Automatically drop all connections after fork [#166] + +2.3.0 +------ + +- Minimum Ruby version is now 2.5.0 +- Add pool size to TimeoutError message + +2.2.5 +------ + +- Fix argument forwarding on Ruby 2.7 [#149] + +2.2.4 +------ + +- Add `reload` to close all connections, recreating them afterwards [Andrew Marshall, #140] +- Add `then` as a way to use a pool or a bare connection with the same code path [#138] + +2.2.3 +------ + +- Pool now throws `ConnectionPool::TimeoutError` on timeout. [#130] +- Use monotonic clock present in all modern Rubies [Tero Tasanen, #109] +- Remove code hacks necessary for JRuby 1.7 +- Expose wrapped pool from ConnectionPool::Wrapper [Thomas Lecavelier, #113] + +2.2.2 +------ + +- Add pool `size` and `available` accessors for metrics and monitoring + purposes [#97, robholland] + +2.2.1 +------ + +- Allow CP::Wrapper to use an existing pool [#87, etiennebarrie] +- Use monotonic time for more accurate timeouts [#84, jdantonio] + +2.2.0 +------ + +- Rollback `Timeout` handling introduced in 2.1.1 and 2.1.2. It seems + impossible to safely work around the issue. Please never, ever use + `Timeout.timeout` in your code or you will see rare but mysterious bugs. [#75] + +2.1.3 +------ + +- Don't increment created count until connection is successfully + created. [mylesmegyesi, #73] + +2.1.2 +------ + +- The connection\_pool will now close any connections which respond to + `close` (Dalli) or `disconnect!` (Redis). This ensures discarded connections + from the fix in 2.1.1 are torn down ASAP and don't linger open. + + +2.1.1 +------ + +- Work around a subtle race condition with code which uses `Timeout.timeout` and + checks out a connection within the timeout block. This might cause + connections to get into a bad state and raise very odd errors. [tamird, #67] + + +2.1.0 +------ + +- Refactoring to better support connection pool subclasses [drbrain, + #55] +- `with` should return value of the last expression [#59] + + +2.0.0 +----- + +- The connection pool is now lazy. Connections are created as needed + and retained until the pool is shut down. [drbrain, #52] + +1.2.0 +----- + +- Add `with(options)` and `checkout(options)`. [mattcamuto] + Allows the caller to override the pool timeout. +```ruby +@pool.with(:timeout => 2) do |conn| +end +``` + +1.1.0 +----- + +- New `#shutdown` method (simao) + + This method accepts a block and calls the block for each + connection in the pool. After calling this method, trying to get a + connection from the pool raises `PoolShuttingDownError`. + +1.0.0 +----- + +- `#with_connection` is now gone in favor of `#with`. + +- We no longer pollute the top level namespace with our internal +`TimedStack` class. + +0.9.3 +-------- + +- `#with_connection` is now deprecated in favor of `#with`. + + A warning will be issued in the 0.9 series and the method will be + removed in 1.0. + +- We now reuse objects when possible. + + This means that under no contention, the same object will be checked + out from the pool after subsequent calls to `ConnectionPool#with`. + + This change should have no impact on end user performance. If + anything, it should be an improvement, depending on what objects you + are pooling. + +0.9.2 +-------- + +- Fix reentrant checkout leading to early checkin. + +0.9.1 +-------- + +- Fix invalid superclass in version.rb + +0.9.0 +-------- + +- Move method\_missing magic into ConnectionPool::Wrapper (djanowski) +- Remove BasicObject superclass (djanowski) + +0.1.0 +-------- + +- More precise timeouts and better error message +- ConnectionPool now subclasses BasicObject so `method_missing` is more effective. diff --git a/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/LICENSE b/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/LICENSE new file mode 100644 index 00000000..7673cbfb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2011 Mike Perham + +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 AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/README.md b/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/README.md new file mode 100644 index 00000000..804929c9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/README.md @@ -0,0 +1,167 @@ +connection\_pool +================= +[![Build Status](https://github.com/mperham/connection_pool/actions/workflows/ci.yml/badge.svg)](https://github.com/mperham/connection_pool/actions/workflows/ci.yml) + +Generic connection pooling for Ruby. + +MongoDB has its own connection pool. +ActiveRecord has its own connection pool. +This is a generic connection pool that can be used with anything, e.g. Redis, Dalli and other Ruby network clients. + +Usage +----- + +Create a pool of objects to share amongst the fibers or threads in your Ruby application: + +``` ruby +$memcached = ConnectionPool.new(size: 5, timeout: 5) { Dalli::Client.new } +``` + +Then use the pool in your application: + +``` ruby +$memcached.with do |conn| + conn.get('some-count') +end +``` + +If all the objects in the connection pool are in use, `with` will block +until one becomes available. +If no object is available within `:timeout` seconds, +`with` will raise a `ConnectionPool::TimeoutError` (a subclass of `Timeout::Error`). + +You can also use `ConnectionPool#then` to support _both_ a +connection pool and a raw client. + +```ruby +# Compatible with a raw Redis::Client, and ConnectionPool Redis +$redis.then { |r| r.set 'foo' 'bar' } +``` + +Optionally, you can specify a timeout override using the with-block semantics: + +``` ruby +$memcached.with(timeout: 2.0) do |conn| + conn.get('some-count') +end +``` + +This will only modify the resource-get timeout for this particular +invocation. +This is useful if you want to fail-fast on certain non-critical +sections when a resource is not available, or conversely if you are comfortable blocking longer on a particular resource. +This is not implemented in the `ConnectionPool::Wrapper` class. + +## Migrating to a Connection Pool + +You can use `ConnectionPool::Wrapper` to wrap a single global connection, making it easier to migrate existing connection code over time: + +``` ruby +$redis = ConnectionPool::Wrapper.new(size: 5, timeout: 3) { Redis.new } +$redis.sadd('foo', 1) +$redis.smembers('foo') +``` + +The wrapper uses `method_missing` to checkout a connection, run the requested method and then immediately check the connection back into the pool. +It's **not** high-performance so you'll want to port your performance sensitive code to use `with` as soon as possible. + +``` ruby +$redis.with do |conn| + conn.sadd('foo', 1) + conn.smembers('foo') +end +``` + +Once you've ported your entire system to use `with`, you can simply remove `Wrapper` and use the simpler and faster `ConnectionPool`. + + +## Shutdown + +You can shut down a ConnectionPool instance once it should no longer be used. +Further checkout attempts will immediately raise an error but existing checkouts will work. + +```ruby +cp = ConnectionPool.new { Redis.new } +cp.shutdown { |c| c.close } +``` + +Shutting down a connection pool will block until all connections are checked in and closed. +**Note that shutting down is completely optional**; Ruby's garbage collector will reclaim unreferenced pools under normal circumstances. + +## Reload + +You can reload a ConnectionPool instance in the case it is desired to close all connections to the pool and, unlike `shutdown`, afterwards recreate connections so the pool may continue to be used. +Reloading may be useful after forking the process. + +```ruby +cp = ConnectionPool.new { Redis.new } +cp.reload { |conn| conn.quit } +cp.with { |conn| conn.get('some-count') } +``` + +Like `shutdown`, this will block until all connections are checked in and closed. + +## Reap + +You can reap idle connections in the ConnectionPool instance to close connections that were created but have not been used for a certain amount of time. This can be useful to run periodically in a separate thread especially if keeping the connection open is resource intensive. + +You can specify how many seconds the connections have to be idle for them to be reaped. +Defaults to 60 seconds. + +```ruby +cp = ConnectionPool.new { Redis.new } +cp.reap(300) { |conn| conn.close } # Reaps connections that have been idle for 300 seconds (5 minutes). +``` + +### Reaper Thread + +You can start your own reaper thread to reap idle connections in the ConnectionPool instance on a regular interval. + +```ruby +cp = ConnectionPool.new { Redis.new } + +# Start a reaper thread to reap connections that have been idle for 300 seconds (5 minutes). +Thread.new do + loop do + cp.reap(300) { |conn| conn.close } + sleep 300 + end +end +``` + +## Current State + +There are several methods that return information about a pool. + +```ruby +cp = ConnectionPool.new(size: 10) { Redis.new } +cp.size # => 10 +cp.available # => 10 +cp.idle # => 0 + +cp.with do |conn| + cp.size # => 10 + cp.available # => 9 + cp.idle # => 0 +end + +cp.idle # => 1 +``` + +Notes +----- + +- Connections are lazily created as needed. +- There is no provision for repairing or checking the health of a connection; + connections should be self-repairing. This is true of the Dalli and Redis + clients. +- **WARNING**: Don't ever use `Timeout.timeout` in your Ruby code or you will see + occasional silent corruption and mysterious errors. The Timeout API is unsafe + and cannot be used correctly, ever. Use proper socket timeout options as + exposed by Net::HTTP, Redis, Dalli, etc. + + +Author +------ + +Mike Perham, [@getajobmike](https://twitter.com/getajobmike), diff --git a/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/connection_pool.gemspec b/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/connection_pool.gemspec new file mode 100644 index 00000000..32289f25 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/connection_pool.gemspec @@ -0,0 +1,24 @@ +require "./lib/connection_pool/version" + +Gem::Specification.new do |s| + s.name = "connection_pool" + s.version = ConnectionPool::VERSION + s.platform = Gem::Platform::RUBY + s.authors = ["Mike Perham", "Damian Janowski"] + s.email = ["mperham@gmail.com", "damian@educabilia.com"] + s.homepage = "https://github.com/mperham/connection_pool" + s.description = s.summary = "Generic connection pool for Ruby" + + s.files = ["Changes.md", "LICENSE", "README.md", "connection_pool.gemspec", + "lib/connection_pool.rb", "lib/connection_pool/timed_stack.rb", + "lib/connection_pool/version.rb", "lib/connection_pool/wrapper.rb"] + s.executables = [] + s.require_paths = ["lib"] + s.license = "MIT" + s.add_development_dependency "bundler" + s.add_development_dependency "minitest", ">= 5.0.0" + s.add_development_dependency "rake" + s.required_ruby_version = ">= 2.5.0" + + s.metadata = {"changelog_uri" => "https://github.com/mperham/connection_pool/blob/main/Changes.md", "rubygems_mfa_required" => "true"} +end diff --git a/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/lib/connection_pool.rb b/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/lib/connection_pool.rb new file mode 100644 index 00000000..081d8bdf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/lib/connection_pool.rb @@ -0,0 +1,184 @@ +require "timeout" +require_relative "connection_pool/version" + +class ConnectionPool + class Error < ::RuntimeError; end + + class PoolShuttingDownError < ::ConnectionPool::Error; end + + class TimeoutError < ::Timeout::Error; end +end + +# Generic connection pool class for sharing a limited number of objects or network connections +# among many threads. Note: pool elements are lazily created. +# +# Example usage with block (faster): +# +# @pool = ConnectionPool.new { Redis.new } +# @pool.with do |redis| +# redis.lpop('my-list') if redis.llen('my-list') > 0 +# end +# +# Using optional timeout override (for that single invocation) +# +# @pool.with(timeout: 2.0) do |redis| +# redis.lpop('my-list') if redis.llen('my-list') > 0 +# end +# +# Example usage replacing an existing connection (slower): +# +# $redis = ConnectionPool.wrap { Redis.new } +# +# def do_work +# $redis.lpop('my-list') if $redis.llen('my-list') > 0 +# end +# +# Accepts the following options: +# - :size - number of connections to pool, defaults to 5 +# - :timeout - amount of time to wait for a connection if none currently available, defaults to 5 seconds +# - :auto_reload_after_fork - automatically drop all connections after fork, defaults to true +# +class ConnectionPool + DEFAULTS = {size: 5, timeout: 5, auto_reload_after_fork: true}.freeze + + def self.wrap(options, &block) + Wrapper.new(options, &block) + end + + if Process.respond_to?(:fork) + INSTANCES = ObjectSpace::WeakMap.new + private_constant :INSTANCES + + def self.after_fork + INSTANCES.values.each do |pool| + next unless pool.auto_reload_after_fork + + # We're on after fork, so we know all other threads are dead. + # All we need to do is to ensure the main thread doesn't have a + # checked out connection + pool.checkin(force: true) + pool.reload do |connection| + # Unfortunately we don't know what method to call to close the connection, + # so we try the most common one. + connection.close if connection.respond_to?(:close) + end + end + nil + end + + if ::Process.respond_to?(:_fork) # MRI 3.1+ + module ForkTracker + def _fork + pid = super + if pid == 0 + ConnectionPool.after_fork + end + pid + end + end + Process.singleton_class.prepend(ForkTracker) + end + else + INSTANCES = nil + private_constant :INSTANCES + + def self.after_fork + # noop + end + end + + def initialize(options = {}, &block) + raise ArgumentError, "Connection pool requires a block" unless block + + options = DEFAULTS.merge(options) + + @size = Integer(options.fetch(:size)) + @timeout = options.fetch(:timeout) + @auto_reload_after_fork = options.fetch(:auto_reload_after_fork) + + @available = TimedStack.new(@size, &block) + @key = :"pool-#{@available.object_id}" + @key_count = :"pool-#{@available.object_id}-count" + INSTANCES[self] = self if @auto_reload_after_fork && INSTANCES + end + + def with(options = {}) + Thread.handle_interrupt(Exception => :never) do + conn = checkout(options) + begin + Thread.handle_interrupt(Exception => :immediate) do + yield conn + end + ensure + checkin + end + end + end + alias_method :then, :with + + def checkout(options = {}) + if ::Thread.current[@key] + ::Thread.current[@key_count] += 1 + ::Thread.current[@key] + else + ::Thread.current[@key_count] = 1 + ::Thread.current[@key] = @available.pop(options[:timeout] || @timeout, options) + end + end + + def checkin(force: false) + if ::Thread.current[@key] + if ::Thread.current[@key_count] == 1 || force + @available.push(::Thread.current[@key]) + ::Thread.current[@key] = nil + ::Thread.current[@key_count] = nil + else + ::Thread.current[@key_count] -= 1 + end + elsif !force + raise ConnectionPool::Error, "no connections are checked out" + end + + nil + end + + ## + # Shuts down the ConnectionPool by passing each connection to +block+ and + # then removing it from the pool. Attempting to checkout a connection after + # shutdown will raise +ConnectionPool::PoolShuttingDownError+. + def shutdown(&block) + @available.shutdown(&block) + end + + ## + # Reloads the ConnectionPool by passing each connection to +block+ and then + # removing it the pool. Subsequent checkouts will create new connections as + # needed. + def reload(&block) + @available.shutdown(reload: true, &block) + end + + ## Reaps idle connections that have been idle for over +idle_seconds+. + # +idle_seconds+ defaults to 60. + def reap(idle_seconds = 60, &block) + @available.reap(idle_seconds, &block) + end + + # Size of this connection pool + attr_reader :size + # Automatically drop all connections after fork + attr_reader :auto_reload_after_fork + + # Number of pool entries available for checkout at this instant. + def available + @available.length + end + + # Number of pool entries created and idle in the pool. + def idle + @available.idle + end +end + +require_relative "connection_pool/timed_stack" +require_relative "connection_pool/wrapper" diff --git a/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/lib/connection_pool/timed_stack.rb b/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/lib/connection_pool/timed_stack.rb new file mode 100644 index 00000000..189431ee --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/lib/connection_pool/timed_stack.rb @@ -0,0 +1,221 @@ +## +# The TimedStack manages a pool of homogeneous connections (or any resource +# you wish to manage). Connections are created lazily up to a given maximum +# number. +# +# Examples: +# +# ts = TimedStack.new(1) { MyConnection.new } +# +# # fetch a connection +# conn = ts.pop +# +# # return a connection +# ts.push conn +# +# conn = ts.pop +# ts.pop timeout: 5 +# #=> raises ConnectionPool::TimeoutError after 5 seconds +class ConnectionPool::TimedStack + attr_reader :max + + ## + # Creates a new pool with +size+ connections that are created from the given + # +block+. + def initialize(size = 0, &block) + @create_block = block + @created = 0 + @que = [] + @max = size + @mutex = Thread::Mutex.new + @resource = Thread::ConditionVariable.new + @shutdown_block = nil + end + + ## + # Returns +obj+ to the stack. +options+ is ignored in TimedStack but may be + # used by subclasses that extend TimedStack. + def push(obj, options = {}) + @mutex.synchronize do + if @shutdown_block + @created -= 1 unless @created == 0 + @shutdown_block.call(obj) + else + store_connection obj, options + end + + @resource.broadcast + end + end + alias_method :<<, :push + + ## + # Retrieves a connection from the stack. If a connection is available it is + # immediately returned. If no connection is available within the given + # timeout a ConnectionPool::TimeoutError is raised. + # + # +:timeout+ is the only checked entry in +options+ and is preferred over + # the +timeout+ argument (which will be removed in a future release). Other + # options may be used by subclasses that extend TimedStack. + def pop(timeout = 0.5, options = {}) + options, timeout = timeout, 0.5 if Hash === timeout + timeout = options.fetch :timeout, timeout + + deadline = current_time + timeout + @mutex.synchronize do + loop do + raise ConnectionPool::PoolShuttingDownError if @shutdown_block + if (conn = try_fetch_connection(options)) + return conn + end + + connection = try_create(options) + return connection if connection + + to_wait = deadline - current_time + raise ConnectionPool::TimeoutError, "Waited #{timeout} sec, #{length}/#{@max} available" if to_wait <= 0 + @resource.wait(@mutex, to_wait) + end + end + end + + ## + # Shuts down the TimedStack by passing each connection to +block+ and then + # removing it from the pool. Attempting to checkout a connection after + # shutdown will raise +ConnectionPool::PoolShuttingDownError+ unless + # +:reload+ is +true+. + def shutdown(reload: false, &block) + raise ArgumentError, "shutdown must receive a block" unless block + + @mutex.synchronize do + @shutdown_block = block + @resource.broadcast + + shutdown_connections + @shutdown_block = nil if reload + end + end + + ## + # Reaps connections that were checked in more than +idle_seconds+ ago. + def reap(idle_seconds, &block) + raise ArgumentError, "reap must receive a block" unless block + raise ArgumentError, "idle_seconds must be a number" unless idle_seconds.is_a?(Numeric) + raise ConnectionPool::PoolShuttingDownError if @shutdown_block + + idle.times do + conn = + @mutex.synchronize do + raise ConnectionPool::PoolShuttingDownError if @shutdown_block + + reserve_idle_connection(idle_seconds) + end + break unless conn + + block.call(conn) + end + end + + ## + # Returns +true+ if there are no available connections. + def empty? + (@created - @que.length) >= @max + end + + ## + # The number of connections available on the stack. + def length + @max - @created + @que.length + end + + ## + # The number of connections created and available on the stack. + def idle + @que.length + end + + private + + def current_time + Process.clock_gettime(Process::CLOCK_MONOTONIC) + end + + ## + # This is an extension point for TimedStack and is called with a mutex. + # + # This method must returns a connection from the stack if one exists. Allows + # subclasses with expensive match/search algorithms to avoid double-handling + # their stack. + def try_fetch_connection(options = nil) + connection_stored?(options) && fetch_connection(options) + end + + ## + # This is an extension point for TimedStack and is called with a mutex. + # + # This method must returns true if a connection is available on the stack. + def connection_stored?(options = nil) + !@que.empty? + end + + ## + # This is an extension point for TimedStack and is called with a mutex. + # + # This method must return a connection from the stack. + def fetch_connection(options = nil) + @que.pop&.first + end + + ## + # This is an extension point for TimedStack and is called with a mutex. + # + # This method must shut down all connections on the stack. + def shutdown_connections(options = nil) + while (conn = try_fetch_connection(options)) + @created -= 1 unless @created == 0 + @shutdown_block.call(conn) + end + end + + ## + # This is an extension point for TimedStack and is called with a mutex. + # + # This method returns the oldest idle connection if it has been idle for more than idle_seconds. + # This requires that the stack is kept in order of checked in time (oldest first). + def reserve_idle_connection(idle_seconds) + return unless idle_connections?(idle_seconds) + + @created -= 1 unless @created == 0 + + @que.shift.first + end + + ## + # This is an extension point for TimedStack and is called with a mutex. + # + # Returns true if the first connection in the stack has been idle for more than idle_seconds + def idle_connections?(idle_seconds) + connection_stored? && (current_time - @que.first.last > idle_seconds) + end + + ## + # This is an extension point for TimedStack and is called with a mutex. + # + # This method must return +obj+ to the stack. + def store_connection(obj, options = nil) + @que.push [obj, current_time] + end + + ## + # This is an extension point for TimedStack and is called with a mutex. + # + # This method must create a connection if and only if the total number of + # connections allowed has not been met. + def try_create(options = nil) + unless @created == @max + object = @create_block.call + @created += 1 + object + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/lib/connection_pool/version.rb b/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/lib/connection_pool/version.rb new file mode 100644 index 00000000..02620939 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/lib/connection_pool/version.rb @@ -0,0 +1,3 @@ +class ConnectionPool + VERSION = "2.5.3" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/lib/connection_pool/wrapper.rb b/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/lib/connection_pool/wrapper.rb new file mode 100644 index 00000000..8630bee3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/connection_pool-2.5.3/lib/connection_pool/wrapper.rb @@ -0,0 +1,56 @@ +class ConnectionPool + class Wrapper < ::BasicObject + METHODS = [:with, :pool_shutdown, :wrapped_pool] + + def initialize(options = {}, &block) + @pool = options.fetch(:pool) { ::ConnectionPool.new(options, &block) } + end + + def wrapped_pool + @pool + end + + def with(&block) + @pool.with(&block) + end + + def pool_shutdown(&block) + @pool.shutdown(&block) + end + + def pool_size + @pool.size + end + + def pool_available + @pool.available + end + + def respond_to?(id, *args) + METHODS.include?(id) || with { |c| c.respond_to?(id, *args) } + end + + # rubocop:disable Style/MissingRespondToMissing + if ::RUBY_VERSION >= "3.0.0" + def method_missing(name, *args, **kwargs, &block) + with do |connection| + connection.send(name, *args, **kwargs, &block) + end + end + elsif ::RUBY_VERSION >= "2.7.0" + ruby2_keywords def method_missing(name, *args, &block) + with do |connection| + connection.send(name, *args, &block) + end + end + else + def method_missing(name, *args, &block) + with do |connection| + connection.send(name, *args, &block) + end + end + end + # rubocop:enable Style/MethodMissingSuper + # rubocop:enable Style/MissingRespondToMissing + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/crack-1.0.0/History b/vendor/bundle/ruby/3.4.0/gems/crack-1.0.0/History new file mode 100644 index 00000000..1d5f1087 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/crack-1.0.0/History @@ -0,0 +1,52 @@ +== 1.0.0 2024-02-09 + +This version is identical with the previous one, there's no code changes. + +Releasing v1.0.0 indicates that the gem has a stable API and it's going to follow semantic versioning. + +== 0.4.6 2024-01-29 + +* minor patches + * Ruby 3.1, 3.2, 3.3 support + * Ship LICENSE file + * Add BigDecimal to gem dependency + * Move CI to Github Actions + * Fix parse issue with consecutive dates + +== 0.4.5 2020-12-26 + +* 1 minor patch + * Add REXML as gem runtime dependency + +== 0.4.4 2020-09-17 + +* 1 minor patch + * Remove safe_yaml + +== 0.1.7 2010-02-19 +* 1 minor patch + * Added patch from @purp for ISO 8601 date/time format + +== 0.1.6 2010-01-31 +* 1 minor patch + * Added Crack::VERSION constant - http://weblog.rubyonrails.org/2009/9/1/gem-packaging-best-practices + +== 0.1.5 2010-01-27 +* 1 minor patch + * Strings that begin with dates shouldn't be parsed as such (sandro) + +== 0.1.3 2009-06-22 +* 1 minor patch + * Parsing a text node with attributes stores them in the attributes method (tamalw) + +== 0.1.2 2009-04-21 +* 2 minor patches + * Correct unnormalization of attribute values (der-flo) + * Fix error in parsing YAML in the case where a hash value ends with backslashes, and there are subsequent values in the hash (deadprogrammer) + +== 0.1.1 2009-03-31 +* 1 minor patch + * Parsing empty or blank xml now returns empty hash instead of raising error. + +== 0.1.0 2009-03-28 +* Initial release. diff --git a/vendor/bundle/ruby/3.4.0/gems/crack-1.0.0/LICENSE b/vendor/bundle/ruby/3.4.0/gems/crack-1.0.0/LICENSE new file mode 100644 index 00000000..fbbebe14 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/crack-1.0.0/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2009 John Nunemaker + +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 AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/crack-1.0.0/README.md b/vendor/bundle/ruby/3.4.0/gems/crack-1.0.0/README.md new file mode 100644 index 00000000..78bba7f7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/crack-1.0.0/README.md @@ -0,0 +1,43 @@ +# crack + +[![Test](https://github.com/jnunemaker/crack/actions/workflows/test.yml/badge.svg)](https://github.com/jnunemaker/crack/actions/workflows/test.yml) +[![Gem Version](https://badge.fury.io/rb/crack.svg)](https://badge.fury.io/rb/crack) +![downloads](https://img.shields.io/gem/dt/crack?label=downloads) + +Really simple JSON and XML parsing, ripped from Merb and Rails. The XML parser is ripped from Merb and the JSON parser is ripped from Rails. I take no credit, just packaged them for all to enjoy and easily use. + +## compatibility + +* Ruby 2.x +* Ruby 3.x + +## note on patches/pull requests + +* Fork the project. +* Make your feature addition or bug fix. +* Add tests for it. This is important so I don't break it in a future version unintentionally. +* Run the tests with `rake test` +* Open a Pull Request with the changes + +## usage + +```ruby +gem 'crack' # in Gemfile +require 'crack' # for xml and json +require 'crack/json' # for just json +require 'crack/xml' # for just xml +``` + +## examples + +```ruby +Crack::XML.parse("This is the contents") +# => {'tag' => 'This is the contents'} + +Crack::JSON.parse('{"tag":"This is the contents"}') +# => {'tag' => 'This is the contents'} +``` + +## Copyright + +Copyright (c) 2009 John Nunemaker. See LICENSE for details. diff --git a/vendor/bundle/ruby/3.4.0/gems/crack-1.0.0/lib/crack.rb b/vendor/bundle/ruby/3.4.0/gems/crack-1.0.0/lib/crack.rb new file mode 100644 index 00000000..d6af02d6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/crack-1.0.0/lib/crack.rb @@ -0,0 +1,8 @@ +module Crack + class ParseError < StandardError; end +end + +require 'crack/version' +require 'crack/util' +require 'crack/json' +require 'crack/xml' diff --git a/vendor/bundle/ruby/3.4.0/gems/crack-1.0.0/lib/crack/json.rb b/vendor/bundle/ruby/3.4.0/gems/crack-1.0.0/lib/crack/json.rb new file mode 100644 index 00000000..42f39e1a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/crack-1.0.0/lib/crack/json.rb @@ -0,0 +1,113 @@ +# Copyright (c) 2004-2008 David Heinemeier Hansson +# 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 AUTHORS OR COPYRIGHT HOLDERS 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. + +require 'strscan' +require 'psych' + +module Crack + class JSON + def self.parser_exceptions + @parser_exceptions ||= [ArgumentError, Psych::SyntaxError] + end + + if Gem::Version.new(Psych::VERSION) >= Gem::Version.new('3.1.0') + def self.parse(json) + yaml = unescape(convert_json_to_yaml(json)) + YAML.safe_load(yaml, permitted_classes: [Regexp, Date, Time]) + rescue *parser_exceptions + raise ParseError, "Invalid JSON string" + rescue Psych::DisallowedClass + yaml + end + else # Ruby < 2.6 + def self.parse(json) + yaml = unescape(convert_json_to_yaml(json)) + YAML.safe_load(yaml, [Regexp, Date, Time]) + rescue *parser_exceptions + raise ParseError, "Invalid JSON string" + rescue Psych::DisallowedClass + yaml + end + end + + protected + def self.unescape(str) + # Force the encoding to be UTF-8 so we can perform regular expressions + # on 1.9.2 without blowing up. + # see http://stackoverflow.com/questions/1224204/ruby-mechanize-getting-force-encoding-exception for a similar issue + str.force_encoding('UTF-8') if defined?(Encoding) && str.respond_to?(:force_encoding) + str.gsub(/\\u0000/, "").gsub(/\\[u|U]([0-9a-fA-F]{4})/) { [$1.hex].pack("U") } + end + + # matches YAML-formatted dates + DATE_REGEX = /^\d{4}-\d{2}-\d{2}$|^\d{4}-\d{1,2}-\d{1,2}[T \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?)$/ + + # Ensure that ":" and "," are always followed by a space + def self.convert_json_to_yaml(json) #:nodoc: + json = String.new(json) #can't modify a frozen string + scanner, quoting, marks, pos, date_starts, date_ends = StringScanner.new(json), false, [], nil, [], [] + while scanner.scan_until(/(\\['"]|['":,\/\\]|\\.)/) + case char = scanner[1] + when '"', "'" + if !quoting + quoting = char + pos = scanner.pos + elsif quoting == char + if json[pos..scanner.pos-2] =~ DATE_REGEX + # found a date, track the exact positions of the quotes so we can remove them later. + # oh, and increment them for each current mark, each one is an extra padded space that bumps + # the position in the final YAML output + total_marks = marks.size + date_starts << pos+total_marks + date_ends << scanner.pos+total_marks + end + quoting = false + end + when "/" + if !quoting + json[scanner.pos - 1] = "!ruby/regexp /" + scanner.pos += 13 + scanner.scan_until(/\/[mix]*/) + end + when ":","," + marks << scanner.pos - 1 unless quoting + when "\\" + scanner.skip(/\\/) + end + end + + if marks.empty? + json.gsub(/\\\//, '/') + else + left_pos = marks.clone.unshift(-1) + right_pos = marks << json.length + output = [] + left_pos.each_with_index do |left, i| + output << json[left.succ..right_pos[i]] + end + output = output * " " + + format_dates(output, date_starts, date_ends) + output.gsub!(/\\\//, '/') + output + end + end + + def self.format_dates(output, date_starts, date_ends) + if YAML.constants.include?('Syck') + (date_starts + date_ends).each { |i| output[i-1] = ' ' } + else + extra_chars_to_be_added = 0 + timestamp_marker = '!!timestamp ' + timestamp_marker_size = timestamp_marker.size + + date_starts.each do |i| + output[i-2+extra_chars_to_be_added] = timestamp_marker + extra_chars_to_be_added += timestamp_marker_size - 1 + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/crack-1.0.0/lib/crack/util.rb b/vendor/bundle/ruby/3.4.0/gems/crack-1.0.0/lib/crack/util.rb new file mode 100644 index 00000000..60c94428 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/crack-1.0.0/lib/crack/util.rb @@ -0,0 +1,17 @@ +module Crack + module Util + def snake_case(str) + return str.downcase if str =~ /^[A-Z]+$/ + str.gsub(/([A-Z]+)(?=[A-Z][a-z]?)|\B[A-Z]/, '_\&') =~ /_*(.*)/ + return $+.downcase + end + + def to_xml_attributes(hash) + hash.map do |k,v| + %{#{Crack::Util.snake_case(k.to_s).sub(/^(.{1,1})/) { |m| m.downcase }}="#{v.to_s.gsub('"', '"')}"} + end.join(' ') + end + + extend self + end +end \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/crack-1.0.0/lib/crack/version.rb b/vendor/bundle/ruby/3.4.0/gems/crack-1.0.0/lib/crack/version.rb new file mode 100644 index 00000000..a6c37990 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/crack-1.0.0/lib/crack/version.rb @@ -0,0 +1,3 @@ +module Crack + VERSION = "1.0.0" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/crack-1.0.0/lib/crack/xml.rb b/vendor/bundle/ruby/3.4.0/gems/crack-1.0.0/lib/crack/xml.rb new file mode 100644 index 00000000..69856891 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/crack-1.0.0/lib/crack/xml.rb @@ -0,0 +1,238 @@ +require 'rexml/parsers/streamparser' +require 'rexml/parsers/baseparser' +require 'rexml/light/node' +require 'rexml/text' +require "rexml/document" +require 'date' +require 'time' +require 'yaml' +require 'bigdecimal' + +# The Reason behind redefining the String Class for this specific plugin is to +# avoid the dynamic insertion of stuff on it (see version previous to this commit). +# Doing that disables the possibility of efectuating a dump on the structure. This way it goes. +class REXMLUtiliyNodeString < String + attr_accessor :attributes +end + +# This is a slighly modified version of the XMLUtilityNode from +# http://merb.devjavu.com/projects/merb/ticket/95 (has.sox@gmail.com) +# It's mainly just adding vowels, as I ht cd wth n vwls :) +# This represents the hard part of the work, all I did was change the +# underlying parser. +class REXMLUtilityNode #:nodoc: + attr_accessor :name, :attributes, :children, :type + + def self.typecasts + @@typecasts + end + + def self.typecasts=(obj) + @@typecasts = obj + end + + def self.available_typecasts + @@available_typecasts + end + + def self.available_typecasts=(obj) + @@available_typecasts = obj + end + + self.typecasts = {} + self.typecasts["integer"] = lambda{|v| v.nil? ? nil : v.to_i} + self.typecasts["boolean"] = lambda{|v| v.nil? ? nil : (v.strip != "false")} + self.typecasts["datetime"] = lambda{|v| v.nil? ? nil : Time.parse(v).utc} + self.typecasts["date"] = lambda{|v| v.nil? ? nil : Date.parse(v)} + self.typecasts["dateTime"] = lambda{|v| v.nil? ? nil : Time.parse(v).utc} + self.typecasts["decimal"] = lambda{|v| v.nil? ? nil : BigDecimal(v.to_s)} + self.typecasts["double"] = lambda{|v| v.nil? ? nil : v.to_f} + self.typecasts["float"] = lambda{|v| v.nil? ? nil : v.to_f} + self.typecasts["string"] = lambda{|v| v.to_s} + self.typecasts["base64Binary"] = lambda{|v| v.unpack('m').first } + + self.available_typecasts = self.typecasts.keys + + def initialize(name, normalized_attributes = {}) + + # unnormalize attribute values + attributes = Hash[* normalized_attributes.map { |key, value| + [ key, unnormalize_xml_entities(value) ] + }.flatten] + + @name = name.tr("-", "_") + # leave the type alone if we don't know what it is + @type = self.class.available_typecasts.include?(attributes["type"]) ? attributes.delete("type") : attributes["type"] + + @nil_element = attributes.delete("nil") == "true" + @attributes = undasherize_keys(attributes) + @children = [] + @text = false + end + + def add_node(node) + @text = true if node.is_a? String + @children << node + end + + def to_hash + # ACG: Added a check here to prevent an exception a type == "file" tag has nodes within it + if @type == "file" and (@children.first.nil? or @children.first.is_a?(String)) + f = StringIO.new((@children.first || '').unpack('m').first) + class << f + attr_accessor :original_filename, :content_type + end + f.original_filename = attributes['name'] || 'untitled' + f.content_type = attributes['content_type'] || 'application/octet-stream' + return {name => f} + end + + if @text + t = typecast_value( unnormalize_xml_entities( inner_html ) ) + if t.is_a?(String) + t = REXMLUtiliyNodeString.new(t) + t.attributes = attributes + end + return { name => t } + else + #change repeating groups into an array + groups = @children.inject({}) { |s,e| (s[e.name] ||= []) << e; s } + + out = nil + if @type == "array" + out = [] + groups.each do |k, v| + if v.size == 1 + out << v.first.to_hash.entries.first.last + else + out << v.map{|e| e.to_hash[k]} + end + end + out = out.flatten + + else # If Hash + out = {} + groups.each do |k,v| + if v.size == 1 + out.merge!(v.first) + else + out.merge!( k => v.map{|e| e.to_hash[k]}) + end + end + out.merge! attributes unless attributes.empty? + out = out.empty? ? nil : out + end + + if @type && out.nil? + { name => typecast_value(out) } + else + { name => out } + end + end + end + + # Typecasts a value based upon its type. For instance, if + # +node+ has #type == "integer", + # {{[node.typecast_value("12") #=> 12]}} + # + # @param value The value that is being typecast. + # + # @details [:type options] + # "integer":: + # converts +value+ to an integer with #to_i + # "boolean":: + # checks whether +value+, after removing spaces, is the literal + # "true" + # "datetime":: + # Parses +value+ using Time.parse, and returns a UTC Time + # "date":: + # Parses +value+ using Date.parse + # + # @return + # The result of typecasting +value+. + # + # @note + # If +self+ does not have a "type" key, or if it's not one of the + # options specified above, the raw +value+ will be returned. + def typecast_value(value) + return value unless @type + proc = self.class.typecasts[@type] + proc.nil? ? value : proc.call(value) + end + + # Take keys of the form foo-bar and convert them to foo_bar + def undasherize_keys(params) + params.keys.each do |key, value| + params[key.tr("-", "_")] = params.delete(key) + end + params + end + + # Get the inner_html of the REXML node. + def inner_html + @children.join + end + + # Converts the node into a readable HTML node. + # + # @return The HTML node in text form. + def to_html + attributes.merge!(:type => @type ) if @type + "<#{name}#{Crack::Util.to_xml_attributes(attributes)}>#{@nil_element ? '' : inner_html}" + end + + # @alias #to_html #to_s + def to_s + to_html + end + + private + + def unnormalize_xml_entities value + REXML::Text.unnormalize(value) + end +end + +module Crack + class REXMLParser + def self.parse(xml) + stack = [] + parser = REXML::Parsers::BaseParser.new(xml) + + while true + event = parser.pull + case event[0] + when :end_document + break + when :end_doctype, :start_doctype + # do nothing + when :start_element + stack.push REXMLUtilityNode.new(event[1], event[2]) + when :end_element + if stack.size > 1 + temp = stack.pop + stack.last.add_node(temp) + end + when :text, :cdata + stack.last.add_node(event[1]) unless event[1].strip.length == 0 || stack.empty? + end + end + + stack.length > 0 ? stack.pop.to_hash : {} + end + end + + class XML + def self.parser + @@parser ||= REXMLParser + end + + def self.parser=(parser) + @@parser = parser + end + + def self.parse(xml) + parser.parse(xml) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/README.md b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/README.md new file mode 100644 index 00000000..0a1c39f1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/README.md @@ -0,0 +1,102 @@ +# `Date` + +A subclass of `Object` that includes the `Comparable` module and easily handles date. + +## Installation + +Add this line to your application's Gemfile: + +```ruby +gem 'date' +``` + +And then execute: + + $ bundle + +Or install it yourself as: + + $ gem install date + +## Usage + +```ruby +require 'date' +``` + +A `Date` object is created with `Date::new`, `Date::jd`, `Date::ordinal`, `Date::commercial`, `Date::parse`, `Date::strptime`, `Date::today`, `Time#to_date`, etc. + +```ruby +require 'date' + +Date.new(2001,2,3) + #=> # +Date.jd(2451944) + #=> # +Date.ordinal(2001,34) + #=> # +Date.commercial(2001,5,6) + #=> # +Date.parse('2001-02-03') + #=> # +Date.strptime('03-02-2001', '%d-%m-%Y') + #=> # +Time.new(2001,2,3).to_date + #=> # +``` + +All `Date` objects are immutable; hence cannot modify themselves. + +The concept of a date object can be represented as a tuple of the day count, the offset and the day of calendar reform. + +The day count denotes the absolute position of a temporal dimension. The offset is relative adjustment, which determines decoded local time with the day count. The day of calendar reform denotes the start day of the new style. The old style of the West is the Julian calendar which was adopted by Caesar. The new style is the Gregorian calendar, which is the current civil calendar of many countries. + +The day count is virtually the astronomical Julian day number. The offset in this class is usually zero, and cannot be specified directly. + +A `Date` object can be created with an optional argument, the day of calendar reform as a Julian day number, which should be 2298874 to 2426355 or negative/positive infinity. The default value is `Date::ITALY` (2299161=1582-10-15). See also sample/cal.rb. + +``` +$ ruby sample/cal.rb -c it 10 1582 +October 1582 +S M Tu W Th F S +1 2 3 4 15 16 +17 18 19 20 21 22 23 +24 25 26 27 28 29 30 +31 +``` + +``` +$ ruby sample/cal.rb -c gb 9 1752 +September 1752 +S M Tu W Th F S +1 2 14 15 16 +17 18 19 20 21 22 23 +24 25 26 27 28 29 30 +``` + +A `Date` object has various methods. See each reference. + +```ruby +d = Date.parse('3rd Feb 2001') + #=> # +d.year #=> 2001 +d.mon #=> 2 +d.mday #=> 3 +d.wday #=> 6 +d += 1 #=> # +d.strftime('%a %d %b %Y') #=> "Sun 04 Feb 2001" +``` + +## Development + +After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. + +To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). + +## Contributing + +Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/date. + +## License + +The gem is available as open source under the terms of the [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause). diff --git a/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/Makefile b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/Makefile new file mode 100644 index 00000000..7a94ee00 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/Makefile @@ -0,0 +1,273 @@ + +SHELL = /bin/sh + +# V=0 quiet, V=1 verbose. other values don't work. +V = 0 +V0 = $(V:0=) +Q1 = $(V:1=) +Q = $(Q1:0=@) +ECHO1 = $(V:1=@ :) +ECHO = $(ECHO1:0=@ echo) +NULLCMD = : + +#### Start of system configuration section. #### + +srcdir = . +topdir = /opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 +hdrdir = $(topdir) +arch_hdrdir = /opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux +PATH_SEPARATOR = : +VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby +prefix = $(DESTDIR)/opt/hostedtoolcache/Ruby/3.4.4/x64 +rubysitearchprefix = $(rubylibprefix)/$(sitearch) +rubyarchprefix = $(rubylibprefix)/$(arch) +rubylibprefix = $(libdir)/$(RUBY_BASE_NAME) +exec_prefix = $(prefix) +vendorarchhdrdir = $(vendorhdrdir)/$(sitearch) +sitearchhdrdir = $(sitehdrdir)/$(sitearch) +rubyarchhdrdir = $(rubyhdrdir)/$(arch) +vendorhdrdir = $(rubyhdrdir)/vendor_ruby +sitehdrdir = $(rubyhdrdir)/site_ruby +rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME) +vendorarchdir = $(vendorlibdir)/$(sitearch) +vendorlibdir = $(vendordir)/$(ruby_version) +vendordir = $(rubylibprefix)/vendor_ruby +sitearchdir = $(sitelibdir)/$(sitearch) +sitelibdir = $(sitedir)/$(ruby_version) +sitedir = $(rubylibprefix)/site_ruby +rubyarchdir = $(rubylibdir)/$(arch) +rubylibdir = $(rubylibprefix)/$(ruby_version) +sitearchincludedir = $(includedir)/$(sitearch) +archincludedir = $(includedir)/$(arch) +sitearchlibdir = $(libdir)/$(sitearch) +archlibdir = $(libdir)/$(arch) +ridir = $(datarootdir)/$(RI_BASE_NAME) +modular_gc_dir = $(DESTDIR) +mandir = $(datarootdir)/man +localedir = $(datarootdir)/locale +libdir = $(exec_prefix)/lib +psdir = $(docdir) +pdfdir = $(docdir) +dvidir = $(docdir) +htmldir = $(docdir) +infodir = $(datarootdir)/info +docdir = $(datarootdir)/doc/$(PACKAGE) +oldincludedir = $(DESTDIR)/usr/include +includedir = $(prefix)/include +runstatedir = $(localstatedir)/run +localstatedir = $(prefix)/var +sharedstatedir = $(prefix)/com +sysconfdir = $(prefix)/etc +datadir = $(datarootdir) +datarootdir = $(prefix)/share +libexecdir = $(exec_prefix)/libexec +sbindir = $(exec_prefix)/sbin +bindir = $(exec_prefix)/bin +archdir = $(rubyarchdir) + + +CC_WRAPPER = +CC = gcc +CXX = g++ +LIBRUBY = $(LIBRUBY_SO) +LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a +LIBRUBYARG_SHARED = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME) +LIBRUBYARG_STATIC = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)-static $(MAINLIBS) +empty = +OUTFLAG = -o $(empty) +COUTFLAG = -o $(empty) +CSRCFLAG = $(empty) + +RUBY_EXTCONF_H = +cflags = $(hardenflags) $(optflags) $(debugflags) $(warnflags) +cxxflags = +optflags = -O3 -fno-fast-math +debugflags = -ggdb3 +warnflags = -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef +cppflags = +CCDLFLAGS = -fPIC +CFLAGS = $(CCDLFLAGS) $(cflags) -fPIC $(ARCH_FLAG) +INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) +DEFS = +CPPFLAGS = -DHAVE_RB_CATEGORY_WARN -DHAVE_TIMEZONE -DENABLE_PATH_CHECK=0 $(DEFS) $(cppflags) +CXXFLAGS = $(CCDLFLAGS) $(ARCH_FLAG) +ldflags = -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed +dldflags = -Wl,--compress-debug-sections=zlib +ARCH_FLAG = +DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG) +LDSHARED = $(CC) -shared +LDSHAREDXX = $(CXX) -shared +POSTLINK = : +AR = gcc-ar +LD = ld +EXEEXT = + +RUBY_INSTALL_NAME = $(RUBY_BASE_NAME) +RUBY_SO_NAME = ruby +RUBYW_INSTALL_NAME = +RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version) +RUBYW_BASE_NAME = rubyw +RUBY_BASE_NAME = ruby + +arch = x86_64-linux +sitearch = $(arch) +ruby_version = 3.4.0 +ruby = $(bindir)/$(RUBY_BASE_NAME) +RUBY = $(ruby) +BUILTRUBY = $(bindir)/$(RUBY_BASE_NAME) +ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/backward.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h + +RM = rm -f +RM_RF = rm -fr +RMDIRS = rmdir --ignore-fail-on-non-empty -p +MAKEDIRS = /usr/bin/mkdir -p +INSTALL = /usr/bin/install -c +INSTALL_PROG = $(INSTALL) -m 0755 +INSTALL_DATA = $(INSTALL) -m 644 +COPY = cp +TOUCH = exit > + +#### End of system configuration section. #### + +preload = +libpath = . $(libdir) +LIBPATH = -L. -L$(libdir) -Wl,-rpath,$(libdir) +DEFFILE = + +CLEANFILES = mkmf.log +DISTCLEANFILES = +DISTCLEANDIRS = + +extout = +extout_prefix = +target_prefix = +LOCAL_LIBS = +LIBS = $(LIBRUBYARG_SHARED) -lm -lpthread -lc +ORIG_SRCS = date_core.c date_parse.c date_strftime.c date_strptime.c +SRCS = $(ORIG_SRCS) +OBJS = date_core.o date_parse.o date_strftime.o date_strptime.o +HDRS = $(srcdir)/date_tmx.h $(srcdir)/zonetab.h +LOCAL_HDRS = +TARGET = date_core +TARGET_NAME = date_core +TARGET_ENTRY = Init_$(TARGET_NAME) +DLLIB = $(TARGET).so +EXTSTATIC = +STATIC_LIB = + +TIMESTAMP_DIR = . +BINDIR = $(bindir) +RUBYCOMMONDIR = $(sitedir)$(target_prefix) +RUBYLIBDIR = $(sitelibdir)$(target_prefix) +RUBYARCHDIR = $(sitearchdir)$(target_prefix) +HDRDIR = $(sitehdrdir)$(target_prefix) +ARCHHDRDIR = $(sitearchhdrdir)$(target_prefix) +TARGET_SO_DIR = +TARGET_SO = $(TARGET_SO_DIR)$(DLLIB) +CLEANLIBS = $(TARGET_SO) false +CLEANOBJS = $(OBJS) *.bak +TARGET_SO_DIR_TIMESTAMP = $(TIMESTAMP_DIR)/.sitearchdir.time + +all: $(DLLIB) +static: $(STATIC_LIB) +.PHONY: all install static install-so install-rb +.PHONY: clean clean-so clean-static clean-rb + +clean-static:: +clean-rb-default:: +clean-rb:: +clean-so:: +clean: clean-so clean-static clean-rb-default clean-rb + -$(Q)$(RM_RF) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time + +distclean-rb-default:: +distclean-rb:: +distclean-so:: +distclean-static:: +distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb + -$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + -$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + -$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true + +realclean: distclean +install: install-so install-rb + +install-so: $(DLLIB) $(TARGET_SO_DIR_TIMESTAMP) + $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) +clean-static:: + -$(Q)$(RM) $(STATIC_LIB) +install-rb: pre-install-rb do-install-rb install-rb-default +install-rb-default: pre-install-rb-default do-install-rb-default +pre-install-rb: Makefile +pre-install-rb-default: Makefile +do-install-rb: +do-install-rb-default: +pre-install-rb-default: + @$(NULLCMD) +$(TARGET_SO_DIR_TIMESTAMP): + $(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR) + $(Q) $(TOUCH) $@ + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + +.SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S + +.cc.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cc.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.mm.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.mm.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cxx.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cxx.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cpp.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cpp.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.c.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.c.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.m.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.m.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +$(TARGET_SO): $(OBJS) Makefile + $(ECHO) linking shared-object $(DLLIB) + -$(Q)$(RM) $(@) + $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) + $(Q) $(POSTLINK) + + + +$(OBJS): $(HDRS) $(ruby_headers) diff --git a/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/date_core.c b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/date_core.c new file mode 100644 index 00000000..2e92539b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/date_core.c @@ -0,0 +1,10064 @@ +/* + date_core.c: Coded by Tadayoshi Funaba 2010-2014 +*/ + +#include "ruby.h" +#include "ruby/encoding.h" +#include "ruby/util.h" +#include +#include +#if defined(HAVE_SYS_TIME_H) +#include +#endif + +#undef NDEBUG +#define NDEBUG +#include + +#ifdef RUBY_EXTCONF_H +#include RUBY_EXTCONF_H +#endif + +#define USE_PACK + +static ID id_cmp, id_le_p, id_ge_p, id_eqeq_p; +static VALUE cDate, cDateTime; +static VALUE eDateError; +static VALUE half_days_in_day, day_in_nanoseconds; +static double positive_inf, negative_inf; + +// used by deconstruct_keys +static VALUE sym_year, sym_month, sym_day, sym_yday, sym_wday; +static VALUE sym_hour, sym_min, sym_sec, sym_sec_fraction, sym_zone; + +#define f_boolcast(x) ((x) ? Qtrue : Qfalse) + +#define f_abs(x) rb_funcall(x, rb_intern("abs"), 0) +#define f_negate(x) rb_funcall(x, rb_intern("-@"), 0) +#define f_add(x,y) rb_funcall(x, '+', 1, y) +#define f_sub(x,y) rb_funcall(x, '-', 1, y) +#define f_mul(x,y) rb_funcall(x, '*', 1, y) +#define f_div(x,y) rb_funcall(x, '/', 1, y) +#define f_quo(x,y) rb_funcall(x, rb_intern("quo"), 1, y) +#define f_idiv(x,y) rb_funcall(x, rb_intern("div"), 1, y) +#define f_mod(x,y) rb_funcall(x, '%', 1, y) +#define f_remainder(x,y) rb_funcall(x, rb_intern("remainder"), 1, y) +#define f_expt(x,y) rb_funcall(x, rb_intern("**"), 1, y) +#define f_floor(x) rb_funcall(x, rb_intern("floor"), 0) +#define f_ceil(x) rb_funcall(x, rb_intern("ceil"), 0) +#define f_truncate(x) rb_funcall(x, rb_intern("truncate"), 0) +#define f_round(x) rb_funcall(x, rb_intern("round"), 0) + +#define f_to_i(x) rb_funcall(x, rb_intern("to_i"), 0) +#define f_to_r(x) rb_funcall(x, rb_intern("to_r"), 0) +#define f_to_s(x) rb_funcall(x, rb_intern("to_s"), 0) +#define f_inspect(x) rb_funcall(x, rb_intern("inspect"), 0) + +#define f_add3(x,y,z) f_add(f_add(x, y), z) +#define f_sub3(x,y,z) f_sub(f_sub(x, y), z) + +#define f_frozen_ary(...) rb_ary_freeze(rb_ary_new3(__VA_ARGS__)) + +static VALUE date_initialize(int argc, VALUE *argv, VALUE self); +static VALUE datetime_initialize(int argc, VALUE *argv, VALUE self); + +#define RETURN_FALSE_UNLESS_NUMERIC(obj) if(!RTEST(rb_obj_is_kind_of((obj), rb_cNumeric))) return Qfalse +inline static void +check_numeric(VALUE obj, const char* field) +{ + if(!RTEST(rb_obj_is_kind_of(obj, rb_cNumeric))) { + rb_raise(rb_eTypeError, "invalid %s (not numeric)", field); + } +} + +inline static int +f_cmp(VALUE x, VALUE y) +{ + if (FIXNUM_P(x) && FIXNUM_P(y)) { + long c = FIX2LONG(x) - FIX2LONG(y); + if (c > 0) + return 1; + else if (c < 0) + return -1; + return 0; + } + return rb_cmpint(rb_funcallv(x, id_cmp, 1, &y), x, y); +} + +inline static VALUE +f_lt_p(VALUE x, VALUE y) +{ + if (FIXNUM_P(x) && FIXNUM_P(y)) + return f_boolcast(FIX2LONG(x) < FIX2LONG(y)); + return rb_funcall(x, '<', 1, y); +} + +inline static VALUE +f_gt_p(VALUE x, VALUE y) +{ + if (FIXNUM_P(x) && FIXNUM_P(y)) + return f_boolcast(FIX2LONG(x) > FIX2LONG(y)); + return rb_funcall(x, '>', 1, y); +} + +inline static VALUE +f_le_p(VALUE x, VALUE y) +{ + if (FIXNUM_P(x) && FIXNUM_P(y)) + return f_boolcast(FIX2LONG(x) <= FIX2LONG(y)); + return rb_funcall(x, id_le_p, 1, y); +} + +inline static VALUE +f_ge_p(VALUE x, VALUE y) +{ + if (FIXNUM_P(x) && FIXNUM_P(y)) + return f_boolcast(FIX2LONG(x) >= FIX2LONG(y)); + return rb_funcall(x, id_ge_p, 1, y); +} + +inline static VALUE +f_eqeq_p(VALUE x, VALUE y) +{ + if (FIXNUM_P(x) && FIXNUM_P(y)) + return f_boolcast(FIX2LONG(x) == FIX2LONG(y)); + return rb_funcall(x, id_eqeq_p, 1, y); +} + +inline static VALUE +f_zero_p(VALUE x) +{ + switch (TYPE(x)) { + case T_FIXNUM: + return f_boolcast(FIX2LONG(x) == 0); + case T_BIGNUM: + return Qfalse; + case T_RATIONAL: + { + VALUE num = rb_rational_num(x); + return f_boolcast(FIXNUM_P(num) && FIX2LONG(num) == 0); + } + } + return rb_funcall(x, id_eqeq_p, 1, INT2FIX(0)); +} + +#define f_nonzero_p(x) (!f_zero_p(x)) + +inline static VALUE +f_negative_p(VALUE x) +{ + if (FIXNUM_P(x)) + return f_boolcast(FIX2LONG(x) < 0); + return rb_funcall(x, '<', 1, INT2FIX(0)); +} + +#define f_positive_p(x) (!f_negative_p(x)) + +#define f_ajd(x) rb_funcall(x, rb_intern("ajd"), 0) +#define f_jd(x) rb_funcall(x, rb_intern("jd"), 0) +#define f_year(x) rb_funcall(x, rb_intern("year"), 0) +#define f_mon(x) rb_funcall(x, rb_intern("mon"), 0) +#define f_mday(x) rb_funcall(x, rb_intern("mday"), 0) +#define f_wday(x) rb_funcall(x, rb_intern("wday"), 0) +#define f_hour(x) rb_funcall(x, rb_intern("hour"), 0) +#define f_min(x) rb_funcall(x, rb_intern("min"), 0) +#define f_sec(x) rb_funcall(x, rb_intern("sec"), 0) + +/* copied from time.c */ +#define NDIV(x,y) (-(-((x)+1)/(y))-1) +#define NMOD(x,y) ((y)-(-((x)+1)%(y))-1) +#define DIV(n,d) ((n)<0 ? NDIV((n),(d)) : (n)/(d)) +#define MOD(n,d) ((n)<0 ? NMOD((n),(d)) : (n)%(d)) + +#define HAVE_JD (1 << 0) +#define HAVE_DF (1 << 1) +#define HAVE_CIVIL (1 << 2) +#define HAVE_TIME (1 << 3) +#define COMPLEX_DAT (1 << 7) + +#define have_jd_p(x) ((x)->flags & HAVE_JD) +#define have_df_p(x) ((x)->flags & HAVE_DF) +#define have_civil_p(x) ((x)->flags & HAVE_CIVIL) +#define have_time_p(x) ((x)->flags & HAVE_TIME) +#define complex_dat_p(x) ((x)->flags & COMPLEX_DAT) +#define simple_dat_p(x) (!complex_dat_p(x)) + +#define ITALY 2299161 /* 1582-10-15 */ +#define ENGLAND 2361222 /* 1752-09-14 */ +#define JULIAN positive_inf +#define GREGORIAN negative_inf +#define DEFAULT_SG ITALY + +#define UNIX_EPOCH_IN_CJD INT2FIX(2440588) /* 1970-01-01 */ + +#define MINUTE_IN_SECONDS 60 +#define HOUR_IN_SECONDS 3600 +#define DAY_IN_SECONDS 86400 +#define SECOND_IN_MILLISECONDS 1000 +#define SECOND_IN_NANOSECONDS 1000000000 + +#define JC_PERIOD0 1461 /* 365.25 * 4 */ +#define GC_PERIOD0 146097 /* 365.2425 * 400 */ +#define CM_PERIOD0 71149239 /* (lcm 7 1461 146097) */ +#define CM_PERIOD (0xfffffff / CM_PERIOD0 * CM_PERIOD0) +#define CM_PERIOD_JCY (CM_PERIOD / JC_PERIOD0 * 4) +#define CM_PERIOD_GCY (CM_PERIOD / GC_PERIOD0 * 400) + +#define REFORM_BEGIN_YEAR 1582 +#define REFORM_END_YEAR 1930 +#define REFORM_BEGIN_JD 2298874 /* ns 1582-01-01 */ +#define REFORM_END_JD 2426355 /* os 1930-12-31 */ + +#ifdef USE_PACK +#define SEC_WIDTH 6 +#define MIN_WIDTH 6 +#define HOUR_WIDTH 5 +#define MDAY_WIDTH 5 +#define MON_WIDTH 4 + +#define SEC_SHIFT 0 +#define MIN_SHIFT SEC_WIDTH +#define HOUR_SHIFT (MIN_WIDTH + SEC_WIDTH) +#define MDAY_SHIFT (HOUR_WIDTH + MIN_WIDTH + SEC_WIDTH) +#define MON_SHIFT (MDAY_WIDTH + HOUR_WIDTH + MIN_WIDTH + SEC_WIDTH) + +#define PK_MASK(x) ((1 << (x)) - 1) + +#define EX_SEC(x) (((x) >> SEC_SHIFT) & PK_MASK(SEC_WIDTH)) +#define EX_MIN(x) (((x) >> MIN_SHIFT) & PK_MASK(MIN_WIDTH)) +#define EX_HOUR(x) (((x) >> HOUR_SHIFT) & PK_MASK(HOUR_WIDTH)) +#define EX_MDAY(x) (((x) >> MDAY_SHIFT) & PK_MASK(MDAY_WIDTH)) +#define EX_MON(x) (((x) >> MON_SHIFT) & PK_MASK(MON_WIDTH)) + +#define PACK5(m,d,h,min,s) \ + (((m) << MON_SHIFT) | ((d) << MDAY_SHIFT) |\ + ((h) << HOUR_SHIFT) | ((min) << MIN_SHIFT) | ((s) << SEC_SHIFT)) + +#define PACK2(m,d) \ + (((m) << MON_SHIFT) | ((d) << MDAY_SHIFT)) +#endif + +#ifdef HAVE_FLOAT_H +#include +#endif + +#if defined(FLT_RADIX) && defined(FLT_MANT_DIG) && FLT_RADIX == 2 && FLT_MANT_DIG > 22 +#define date_sg_t float +#else +#define date_sg_t double +#endif + +#define JULIAN_EPOCH_DATE "-4712-01-01" +#define JULIAN_EPOCH_DATETIME JULIAN_EPOCH_DATE "T00:00:00+00:00" +#define JULIAN_EPOCH_DATETIME_RFC3339 "Mon, 1 Jan -4712 00:00:00 +0000" +#define JULIAN_EPOCH_DATETIME_HTTPDATE "Mon, 01 Jan -4712 00:00:00 GMT" + +/* A set of nth, jd, df and sf denote ajd + 1/2. Each ajd begin at + * noon of GMT (assume equal to UTC). However, this begins at + * midnight. + */ + +struct SimpleDateData +{ + unsigned flags; + int jd; /* as utc */ + VALUE nth; /* not always canonicalized */ + date_sg_t sg; /* 2298874..2426355 or -/+oo -- at most 22 bits */ + /* decoded as utc=local */ + int year; /* truncated */ +#ifndef USE_PACK + int mon; + int mday; + /* hour is zero */ + /* min is zero */ + /* sec is zero */ +#else + /* packed civil */ + unsigned pc; +#endif +}; + +struct ComplexDateData +{ + unsigned flags; + int jd; /* as utc */ + VALUE nth; /* not always canonicalized */ + date_sg_t sg; /* 2298874..2426355 or -/+oo -- at most 22 bits */ + /* decoded as local */ + int year; /* truncated */ +#ifndef USE_PACK + int mon; + int mday; + int hour; + int min; + int sec; +#else + /* packed civil */ + unsigned pc; +#endif + int df; /* as utc, in secs */ + int of; /* in secs */ + VALUE sf; /* in nano secs */ +}; + +union DateData { + unsigned flags; + struct SimpleDateData s; + struct ComplexDateData c; +}; + +#define get_d1(x)\ + union DateData *dat;\ + TypedData_Get_Struct(x, union DateData, &d_lite_type, dat); + +#define get_d1a(x)\ + union DateData *adat;\ + TypedData_Get_Struct(x, union DateData, &d_lite_type, adat); + +#define get_d1b(x)\ + union DateData *bdat;\ + TypedData_Get_Struct(x, union DateData, &d_lite_type, bdat); + +#define get_d2(x,y)\ + union DateData *adat, *bdat;\ + TypedData_Get_Struct(x, union DateData, &d_lite_type, adat);\ + TypedData_Get_Struct(y, union DateData, &d_lite_type, bdat); + +inline static VALUE +canon(VALUE x) +{ + if (RB_TYPE_P(x, T_RATIONAL)) { + VALUE den = rb_rational_den(x); + if (FIXNUM_P(den) && FIX2LONG(den) == 1) + return rb_rational_num(x); + } + return x; +} + +#ifndef USE_PACK +#define set_to_simple(obj, x, _nth, _jd ,_sg, _year, _mon, _mday, _flags) \ +do {\ + RB_OBJ_WRITE((obj), &(x)->nth, canon(_nth)); \ + (x)->jd = _jd;\ + (x)->sg = (date_sg_t)(_sg);\ + (x)->year = _year;\ + (x)->mon = _mon;\ + (x)->mday = _mday;\ + (x)->flags = (_flags) & ~COMPLEX_DAT;\ +} while (0) +#else +#define set_to_simple(obj, x, _nth, _jd ,_sg, _year, _mon, _mday, _flags) \ +do {\ + RB_OBJ_WRITE((obj), &(x)->nth, canon(_nth)); \ + (x)->jd = _jd;\ + (x)->sg = (date_sg_t)(_sg);\ + (x)->year = _year;\ + (x)->pc = PACK2(_mon, _mday);\ + (x)->flags = (_flags) & ~COMPLEX_DAT;\ +} while (0) +#endif + +#ifndef USE_PACK +#define set_to_complex(obj, x, _nth, _jd ,_df, _sf, _of, _sg,\ +_year, _mon, _mday, _hour, _min, _sec, _flags) \ +do {\ + RB_OBJ_WRITE((obj), &(x)->nth, canon(_nth));\ + (x)->jd = _jd;\ + (x)->df = _df;\ + RB_OBJ_WRITE((obj), &(x)->sf, canon(_sf));\ + (x)->of = _of;\ + (x)->sg = (date_sg_t)(_sg);\ + (x)->year = _year;\ + (x)->mon = _mon;\ + (x)->mday = _mday;\ + (x)->hour = _hour;\ + (x)->min = _min;\ + (x)->sec = _sec;\ + (x)->flags = (_flags) | COMPLEX_DAT;\ +} while (0) +#else +#define set_to_complex(obj, x, _nth, _jd ,_df, _sf, _of, _sg,\ +_year, _mon, _mday, _hour, _min, _sec, _flags) \ +do {\ + RB_OBJ_WRITE((obj), &(x)->nth, canon(_nth));\ + (x)->jd = _jd;\ + (x)->df = _df;\ + RB_OBJ_WRITE((obj), &(x)->sf, canon(_sf));\ + (x)->of = _of;\ + (x)->sg = (date_sg_t)(_sg);\ + (x)->year = _year;\ + (x)->pc = PACK5(_mon, _mday, _hour, _min, _sec);\ + (x)->flags = (_flags) | COMPLEX_DAT;\ +} while (0) +#endif + +#ifndef USE_PACK +#define copy_simple_to_complex(obj, x, y) \ +do {\ + RB_OBJ_WRITE((obj), &(x)->nth, (y)->nth);\ + (x)->jd = (y)->jd;\ + (x)->df = 0;\ + (x)->sf = INT2FIX(0);\ + (x)->of = 0;\ + (x)->sg = (date_sg_t)((y)->sg);\ + (x)->year = (y)->year;\ + (x)->mon = (y)->mon;\ + (x)->mday = (y)->mday;\ + (x)->hour = 0;\ + (x)->min = 0;\ + (x)->sec = 0;\ + (x)->flags = (y)->flags;\ +} while (0) +#else +#define copy_simple_to_complex(obj, x, y) \ +do {\ + RB_OBJ_WRITE((obj), &(x)->nth, (y)->nth);\ + (x)->jd = (y)->jd;\ + (x)->df = 0;\ + RB_OBJ_WRITE((obj), &(x)->sf, INT2FIX(0));\ + (x)->of = 0;\ + (x)->sg = (date_sg_t)((y)->sg);\ + (x)->year = (y)->year;\ + (x)->pc = PACK5(EX_MON((y)->pc), EX_MDAY((y)->pc), 0, 0, 0);\ + (x)->flags = (y)->flags;\ +} while (0) +#endif + +#ifndef USE_PACK +#define copy_complex_to_simple(obj, x, y) \ +do {\ + RB_OBJ_WRITE((obj), &(x)->nth, (y)->nth);\ + (x)->jd = (y)->jd;\ + (x)->sg = (date_sg_t)((y)->sg);\ + (x)->year = (y)->year;\ + (x)->mon = (y)->mon;\ + (x)->mday = (y)->mday;\ + (x)->flags = (y)->flags;\ +} while (0) +#else +#define copy_complex_to_simple(obj, x, y) \ +do {\ + RB_OBJ_WRITE((obj), &(x)->nth, (y)->nth);\ + (x)->jd = (y)->jd;\ + (x)->sg = (date_sg_t)((y)->sg);\ + (x)->year = (y)->year;\ + (x)->pc = PACK2(EX_MON((y)->pc), EX_MDAY((y)->pc));\ + (x)->flags = (y)->flags;\ +} while (0) +#endif + +/* base */ + +static int c_valid_civil_p(int, int, int, double, + int *, int *, int *, int *); + +static int +c_find_fdoy(int y, double sg, int *rjd, int *ns) +{ + int d, rm, rd; + + for (d = 1; d < 31; d++) + if (c_valid_civil_p(y, 1, d, sg, &rm, &rd, rjd, ns)) + return 1; + return 0; +} + +static int +c_find_ldoy(int y, double sg, int *rjd, int *ns) +{ + int i, rm, rd; + + for (i = 0; i < 30; i++) + if (c_valid_civil_p(y, 12, 31 - i, sg, &rm, &rd, rjd, ns)) + return 1; + return 0; +} + +#ifndef NDEBUG +/* :nodoc: */ +static int +c_find_fdom(int y, int m, double sg, int *rjd, int *ns) +{ + int d, rm, rd; + + for (d = 1; d < 31; d++) + if (c_valid_civil_p(y, m, d, sg, &rm, &rd, rjd, ns)) + return 1; + return 0; +} +#endif + +static int +c_find_ldom(int y, int m, double sg, int *rjd, int *ns) +{ + int i, rm, rd; + + for (i = 0; i < 30; i++) + if (c_valid_civil_p(y, m, 31 - i, sg, &rm, &rd, rjd, ns)) + return 1; + return 0; +} + +static void +c_civil_to_jd(int y, int m, int d, double sg, int *rjd, int *ns) +{ + double a, b, jd; + + if (m <= 2) { + y -= 1; + m += 12; + } + a = floor(y / 100.0); + b = 2 - a + floor(a / 4.0); + jd = floor(365.25 * (y + 4716)) + + floor(30.6001 * (m + 1)) + + d + b - 1524; + if (jd < sg) { + jd -= b; + *ns = 0; + } + else + *ns = 1; + + *rjd = (int)jd; +} + +static void +c_jd_to_civil(int jd, double sg, int *ry, int *rm, int *rdom) +{ + double x, a, b, c, d, e, y, m, dom; + + if (jd < sg) + a = jd; + else { + x = floor((jd - 1867216.25) / 36524.25); + a = jd + 1 + x - floor(x / 4.0); + } + b = a + 1524; + c = floor((b - 122.1) / 365.25); + d = floor(365.25 * c); + e = floor((b - d) / 30.6001); + dom = b - d - floor(30.6001 * e); + if (e <= 13) { + m = e - 1; + y = c - 4716; + } + else { + m = e - 13; + y = c - 4715; + } + + *ry = (int)y; + *rm = (int)m; + *rdom = (int)dom; +} + +static void +c_ordinal_to_jd(int y, int d, double sg, int *rjd, int *ns) +{ + int ns2; + + c_find_fdoy(y, sg, rjd, &ns2); + *rjd += d - 1; + *ns = (*rjd < sg) ? 0 : 1; +} + +static void +c_jd_to_ordinal(int jd, double sg, int *ry, int *rd) +{ + int rm2, rd2, rjd, ns; + + c_jd_to_civil(jd, sg, ry, &rm2, &rd2); + c_find_fdoy(*ry, sg, &rjd, &ns); + *rd = (jd - rjd) + 1; +} + +static void +c_commercial_to_jd(int y, int w, int d, double sg, int *rjd, int *ns) +{ + int rjd2, ns2; + + c_find_fdoy(y, sg, &rjd2, &ns2); + rjd2 += 3; + *rjd = + (rjd2 - MOD((rjd2 - 1) + 1, 7)) + + 7 * (w - 1) + + (d - 1); + *ns = (*rjd < sg) ? 0 : 1; +} + +static void +c_jd_to_commercial(int jd, double sg, int *ry, int *rw, int *rd) +{ + int ry2, rm2, rd2, a, rjd2, ns2; + + c_jd_to_civil(jd - 3, sg, &ry2, &rm2, &rd2); + a = ry2; + c_commercial_to_jd(a + 1, 1, 1, sg, &rjd2, &ns2); + if (jd >= rjd2) + *ry = a + 1; + else { + c_commercial_to_jd(a, 1, 1, sg, &rjd2, &ns2); + *ry = a; + } + *rw = 1 + DIV(jd - rjd2, 7); + *rd = MOD(jd + 1, 7); + if (*rd == 0) + *rd = 7; +} + +static void +c_weeknum_to_jd(int y, int w, int d, int f, double sg, int *rjd, int *ns) +{ + int rjd2, ns2; + + c_find_fdoy(y, sg, &rjd2, &ns2); + rjd2 += 6; + *rjd = (rjd2 - MOD(((rjd2 - f) + 1), 7) - 7) + 7 * w + d; + *ns = (*rjd < sg) ? 0 : 1; +} + +static void +c_jd_to_weeknum(int jd, int f, double sg, int *ry, int *rw, int *rd) +{ + int rm, rd2, rjd, ns, j; + + c_jd_to_civil(jd, sg, ry, &rm, &rd2); + c_find_fdoy(*ry, sg, &rjd, &ns); + rjd += 6; + j = jd - (rjd - MOD((rjd - f) + 1, 7)) + 7; + *rw = (int)DIV(j, 7); + *rd = (int)MOD(j, 7); +} + +#ifndef NDEBUG +/* :nodoc: */ +static void +c_nth_kday_to_jd(int y, int m, int n, int k, double sg, int *rjd, int *ns) +{ + int rjd2, ns2; + + if (n > 0) { + c_find_fdom(y, m, sg, &rjd2, &ns2); + rjd2 -= 1; + } + else { + c_find_ldom(y, m, sg, &rjd2, &ns2); + rjd2 += 7; + } + *rjd = (rjd2 - MOD((rjd2 - k) + 1, 7)) + 7 * n; + *ns = (*rjd < sg) ? 0 : 1; +} +#endif + +inline static int +c_jd_to_wday(int jd) +{ + return MOD(jd + 1, 7); +} + +#ifndef NDEBUG +/* :nodoc: */ +static void +c_jd_to_nth_kday(int jd, double sg, int *ry, int *rm, int *rn, int *rk) +{ + int rd, rjd, ns2; + + c_jd_to_civil(jd, sg, ry, rm, &rd); + c_find_fdom(*ry, *rm, sg, &rjd, &ns2); + *rn = DIV(jd - rjd, 7) + 1; + *rk = c_jd_to_wday(jd); +} +#endif + +static int +c_valid_ordinal_p(int y, int d, double sg, + int *rd, int *rjd, int *ns) +{ + int ry2, rd2; + + if (d < 0) { + int rjd2, ns2; + + if (!c_find_ldoy(y, sg, &rjd2, &ns2)) + return 0; + c_jd_to_ordinal(rjd2 + d + 1, sg, &ry2, &rd2); + if (ry2 != y) + return 0; + d = rd2; + } + c_ordinal_to_jd(y, d, sg, rjd, ns); + c_jd_to_ordinal(*rjd, sg, &ry2, &rd2); + if (ry2 != y || rd2 != d) + return 0; + return 1; +} + +static const int monthtab[2][13] = { + { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +}; + +inline static int +c_julian_leap_p(int y) +{ + return MOD(y, 4) == 0; +} + +inline static int +c_gregorian_leap_p(int y) +{ + return (MOD(y, 4) == 0 && y % 100 != 0) || MOD(y, 400) == 0; +} + +static int +c_julian_last_day_of_month(int y, int m) +{ + assert(m >= 1 && m <= 12); + return monthtab[c_julian_leap_p(y) ? 1 : 0][m]; +} + +static int +c_gregorian_last_day_of_month(int y, int m) +{ + assert(m >= 1 && m <= 12); + return monthtab[c_gregorian_leap_p(y) ? 1 : 0][m]; +} + +static int +c_valid_julian_p(int y, int m, int d, int *rm, int *rd) +{ + int last; + + if (m < 0) + m += 13; + if (m < 1 || m > 12) + return 0; + last = c_julian_last_day_of_month(y, m); + if (d < 0) + d = last + d + 1; + if (d < 1 || d > last) + return 0; + *rm = m; + *rd = d; + return 1; +} + +static int +c_valid_gregorian_p(int y, int m, int d, int *rm, int *rd) +{ + int last; + + if (m < 0) + m += 13; + if (m < 1 || m > 12) + return 0; + last = c_gregorian_last_day_of_month(y, m); + if (d < 0) + d = last + d + 1; + if (d < 1 || d > last) + return 0; + *rm = m; + *rd = d; + return 1; +} + +static int +c_valid_civil_p(int y, int m, int d, double sg, + int *rm, int *rd, int *rjd, int *ns) +{ + int ry; + + if (m < 0) + m += 13; + if (m < 1 || m > 12) + return 0; + if (d < 0) { + if (!c_find_ldom(y, m, sg, rjd, ns)) + return 0; + c_jd_to_civil(*rjd + d + 1, sg, &ry, rm, rd); + if (ry != y || *rm != m) + return 0; + d = *rd; + } + c_civil_to_jd(y, m, d, sg, rjd, ns); + c_jd_to_civil(*rjd, sg, &ry, rm, rd); + if (ry != y || *rm != m || *rd != d) + return 0; + return 1; +} + +static int +c_valid_commercial_p(int y, int w, int d, double sg, + int *rw, int *rd, int *rjd, int *ns) +{ + int ns2, ry2, rw2, rd2; + + if (d < 0) + d += 8; + if (w < 0) { + int rjd2; + + c_commercial_to_jd(y + 1, 1, 1, sg, &rjd2, &ns2); + c_jd_to_commercial(rjd2 + w * 7, sg, &ry2, &rw2, &rd2); + if (ry2 != y) + return 0; + w = rw2; + } + c_commercial_to_jd(y, w, d, sg, rjd, ns); + c_jd_to_commercial(*rjd, sg, &ry2, rw, rd); + if (y != ry2 || w != *rw || d != *rd) + return 0; + return 1; +} + +static int +c_valid_weeknum_p(int y, int w, int d, int f, double sg, + int *rw, int *rd, int *rjd, int *ns) +{ + int ns2, ry2, rw2, rd2; + + if (d < 0) + d += 7; + if (w < 0) { + int rjd2; + + c_weeknum_to_jd(y + 1, 1, f, f, sg, &rjd2, &ns2); + c_jd_to_weeknum(rjd2 + w * 7, f, sg, &ry2, &rw2, &rd2); + if (ry2 != y) + return 0; + w = rw2; + } + c_weeknum_to_jd(y, w, d, f, sg, rjd, ns); + c_jd_to_weeknum(*rjd, f, sg, &ry2, rw, rd); + if (y != ry2 || w != *rw || d != *rd) + return 0; + return 1; +} + +#ifndef NDEBUG +/* :nodoc: */ +static int +c_valid_nth_kday_p(int y, int m, int n, int k, double sg, + int *rm, int *rn, int *rk, int *rjd, int *ns) +{ + int ns2, ry2, rm2, rn2, rk2; + + if (k < 0) + k += 7; + if (n < 0) { + int t, ny, nm, rjd2; + + t = y * 12 + m; + ny = DIV(t, 12); + nm = MOD(t, 12) + 1; + + c_nth_kday_to_jd(ny, nm, 1, k, sg, &rjd2, &ns2); + c_jd_to_nth_kday(rjd2 + n * 7, sg, &ry2, &rm2, &rn2, &rk2); + if (ry2 != y || rm2 != m) + return 0; + n = rn2; + } + c_nth_kday_to_jd(y, m, n, k, sg, rjd, ns); + c_jd_to_nth_kday(*rjd, sg, &ry2, rm, rn, rk); + if (y != ry2 || m != *rm || n != *rn || k != *rk) + return 0; + return 1; +} +#endif + +static int +c_valid_time_p(int h, int min, int s, int *rh, int *rmin, int *rs) +{ + if (h < 0) + h += 24; + if (min < 0) + min += 60; + if (s < 0) + s += 60; + *rh = h; + *rmin = min; + *rs = s; + return !(h < 0 || h > 24 || + min < 0 || min > 59 || + s < 0 || s > 59 || + (h == 24 && (min > 0 || s > 0))); +} + +inline static int +c_valid_start_p(double sg) +{ + if (isnan(sg)) + return 0; + if (isinf(sg)) + return 1; + if (sg < REFORM_BEGIN_JD || sg > REFORM_END_JD) + return 0; + return 1; +} + +inline static int +df_local_to_utc(int df, int of) +{ + df -= of; + if (df < 0) + df += DAY_IN_SECONDS; + else if (df >= DAY_IN_SECONDS) + df -= DAY_IN_SECONDS; + return df; +} + +inline static int +df_utc_to_local(int df, int of) +{ + df += of; + if (df < 0) + df += DAY_IN_SECONDS; + else if (df >= DAY_IN_SECONDS) + df -= DAY_IN_SECONDS; + return df; +} + +inline static int +jd_local_to_utc(int jd, int df, int of) +{ + df -= of; + if (df < 0) + jd -= 1; + else if (df >= DAY_IN_SECONDS) + jd += 1; + return jd; +} + +inline static int +jd_utc_to_local(int jd, int df, int of) +{ + df += of; + if (df < 0) + jd -= 1; + else if (df >= DAY_IN_SECONDS) + jd += 1; + return jd; +} + +inline static int +time_to_df(int h, int min, int s) +{ + return h * HOUR_IN_SECONDS + min * MINUTE_IN_SECONDS + s; +} + +inline static void +df_to_time(int df, int *h, int *min, int *s) +{ + *h = df / HOUR_IN_SECONDS; + df %= HOUR_IN_SECONDS; + *min = df / MINUTE_IN_SECONDS; + *s = df % MINUTE_IN_SECONDS; +} + +static VALUE +sec_to_day(VALUE s) +{ + if (FIXNUM_P(s)) + return rb_rational_new2(s, INT2FIX(DAY_IN_SECONDS)); + return f_quo(s, INT2FIX(DAY_IN_SECONDS)); +} + +inline static VALUE +isec_to_day(int s) +{ + return sec_to_day(INT2FIX(s)); +} + +static VALUE +ns_to_day(VALUE n) +{ + if (FIXNUM_P(n)) + return rb_rational_new2(n, day_in_nanoseconds); + return f_quo(n, day_in_nanoseconds); +} + +#ifndef NDEBUG +/* :nodoc: */ +static VALUE +ms_to_sec(VALUE m) +{ + if (FIXNUM_P(m)) + return rb_rational_new2(m, INT2FIX(SECOND_IN_MILLISECONDS)); + return f_quo(m, INT2FIX(SECOND_IN_MILLISECONDS)); +} +#endif + +static VALUE +ns_to_sec(VALUE n) +{ + if (FIXNUM_P(n)) + return rb_rational_new2(n, INT2FIX(SECOND_IN_NANOSECONDS)); + return f_quo(n, INT2FIX(SECOND_IN_NANOSECONDS)); +} + +#ifndef NDEBUG +/* :nodoc: */ +inline static VALUE +ins_to_day(int n) +{ + return ns_to_day(INT2FIX(n)); +} +#endif + +static int +safe_mul_p(VALUE x, long m) +{ + long ix; + + if (!FIXNUM_P(x)) + return 0; + ix = FIX2LONG(x); + if (ix < 0) { + if (ix <= (FIXNUM_MIN / m)) + return 0; + } + else { + if (ix >= (FIXNUM_MAX / m)) + return 0; + } + return 1; +} + +static VALUE +day_to_sec(VALUE d) +{ + if (safe_mul_p(d, DAY_IN_SECONDS)) + return LONG2FIX(FIX2LONG(d) * DAY_IN_SECONDS); + return f_mul(d, INT2FIX(DAY_IN_SECONDS)); +} + +#ifndef NDEBUG +/* :nodoc: */ +static VALUE +day_to_ns(VALUE d) +{ + return f_mul(d, day_in_nanoseconds); +} +#endif + +static VALUE +sec_to_ms(VALUE s) +{ + if (safe_mul_p(s, SECOND_IN_MILLISECONDS)) + return LONG2FIX(FIX2LONG(s) * SECOND_IN_MILLISECONDS); + return f_mul(s, INT2FIX(SECOND_IN_MILLISECONDS)); +} + +static VALUE +sec_to_ns(VALUE s) +{ + if (safe_mul_p(s, SECOND_IN_NANOSECONDS)) + return LONG2FIX(FIX2LONG(s) * SECOND_IN_NANOSECONDS); + return f_mul(s, INT2FIX(SECOND_IN_NANOSECONDS)); +} + +#ifndef NDEBUG +/* :nodoc: */ +static VALUE +isec_to_ns(int s) +{ + return sec_to_ns(INT2FIX(s)); +} +#endif + +static VALUE +div_day(VALUE d, VALUE *f) +{ + if (f) + *f = f_mod(d, INT2FIX(1)); + return f_floor(d); +} + +static VALUE +div_df(VALUE d, VALUE *f) +{ + VALUE s = day_to_sec(d); + + if (f) + *f = f_mod(s, INT2FIX(1)); + return f_floor(s); +} + +#ifndef NDEBUG +/* :nodoc: */ +static VALUE +div_sf(VALUE s, VALUE *f) +{ + VALUE n = sec_to_ns(s); + + if (f) + *f = f_mod(n, INT2FIX(1)); + return f_floor(n); +} +#endif + +static void +decode_day(VALUE d, VALUE *jd, VALUE *df, VALUE *sf) +{ + VALUE f; + + *jd = div_day(d, &f); + *df = div_df(f, &f); + *sf = sec_to_ns(f); +} + +inline static double +s_virtual_sg(union DateData *x) +{ + if (isinf(x->s.sg)) + return x->s.sg; + if (f_zero_p(x->s.nth)) + return x->s.sg; + else if (f_negative_p(x->s.nth)) + return positive_inf; + return negative_inf; +} + +inline static double +c_virtual_sg(union DateData *x) +{ + if (isinf(x->c.sg)) + return x->c.sg; + if (f_zero_p(x->c.nth)) + return x->c.sg; + else if (f_negative_p(x->c.nth)) + return positive_inf; + return negative_inf; +} + +inline static double +m_virtual_sg(union DateData *x) +{ + if (simple_dat_p(x)) + return s_virtual_sg(x); + else + return c_virtual_sg(x); +} + +#define canonicalize_jd(_nth, _jd) \ +do {\ + if (_jd < 0) {\ + _nth = f_sub(_nth, INT2FIX(1));\ + _jd += CM_PERIOD;\ + }\ + if (_jd >= CM_PERIOD) {\ + _nth = f_add(_nth, INT2FIX(1));\ + _jd -= CM_PERIOD;\ + }\ +} while (0) + +inline static void +canonicalize_s_jd(VALUE obj, union DateData *x) +{ + int j = x->s.jd; + VALUE nth = x->s.nth; + assert(have_jd_p(x)); + canonicalize_jd(nth, x->s.jd); + RB_OBJ_WRITE(obj, &x->s.nth, nth); + if (x->s.jd != j) + x->flags &= ~HAVE_CIVIL; +} + +inline static void +get_s_jd(union DateData *x) +{ + assert(simple_dat_p(x)); + if (!have_jd_p(x)) { + int jd, ns; + + assert(have_civil_p(x)); +#ifndef USE_PACK + c_civil_to_jd(x->s.year, x->s.mon, x->s.mday, + s_virtual_sg(x), &jd, &ns); +#else + c_civil_to_jd(x->s.year, EX_MON(x->s.pc), EX_MDAY(x->s.pc), + s_virtual_sg(x), &jd, &ns); +#endif + x->s.jd = jd; + x->s.flags |= HAVE_JD; + } +} + +inline static void +get_s_civil(union DateData *x) +{ + assert(simple_dat_p(x)); + if (!have_civil_p(x)) { + int y, m, d; + + assert(have_jd_p(x)); + c_jd_to_civil(x->s.jd, s_virtual_sg(x), &y, &m, &d); + x->s.year = y; +#ifndef USE_PACK + x->s.mon = m; + x->s.mday = d; +#else + x->s.pc = PACK2(m, d); +#endif + x->s.flags |= HAVE_CIVIL; + } +} + +inline static void +get_c_df(union DateData *x) +{ + assert(complex_dat_p(x)); + if (!have_df_p(x)) { + assert(have_time_p(x)); +#ifndef USE_PACK + x->c.df = df_local_to_utc(time_to_df(x->c.hour, x->c.min, x->c.sec), + x->c.of); +#else + x->c.df = df_local_to_utc(time_to_df(EX_HOUR(x->c.pc), + EX_MIN(x->c.pc), + EX_SEC(x->c.pc)), + x->c.of); +#endif + x->c.flags |= HAVE_DF; + } +} + +inline static void +get_c_time(union DateData *x) +{ + assert(complex_dat_p(x)); + if (!have_time_p(x)) { +#ifndef USE_PACK + int r; + assert(have_df_p(x)); + r = df_utc_to_local(x->c.df, x->c.of); + df_to_time(r, &x->c.hour, &x->c.min, &x->c.sec); + x->c.flags |= HAVE_TIME; +#else + int r, m, d, h, min, s; + + assert(have_df_p(x)); + m = EX_MON(x->c.pc); + d = EX_MDAY(x->c.pc); + r = df_utc_to_local(x->c.df, x->c.of); + df_to_time(r, &h, &min, &s); + x->c.pc = PACK5(m, d, h, min, s); + x->c.flags |= HAVE_TIME; +#endif + } +} + +inline static void +canonicalize_c_jd(VALUE obj, union DateData *x) +{ + int j = x->c.jd; + VALUE nth = x->c.nth; + assert(have_jd_p(x)); + canonicalize_jd(nth, x->c.jd); + RB_OBJ_WRITE(obj, &x->c.nth, nth); + if (x->c.jd != j) + x->flags &= ~HAVE_CIVIL; +} + +inline static void +get_c_jd(union DateData *x) +{ + assert(complex_dat_p(x)); + if (!have_jd_p(x)) { + int jd, ns; + + assert(have_civil_p(x)); +#ifndef USE_PACK + c_civil_to_jd(x->c.year, x->c.mon, x->c.mday, + c_virtual_sg(x), &jd, &ns); +#else + c_civil_to_jd(x->c.year, EX_MON(x->c.pc), EX_MDAY(x->c.pc), + c_virtual_sg(x), &jd, &ns); +#endif + + get_c_time(x); +#ifndef USE_PACK + x->c.jd = jd_local_to_utc(jd, + time_to_df(x->c.hour, x->c.min, x->c.sec), + x->c.of); +#else + x->c.jd = jd_local_to_utc(jd, + time_to_df(EX_HOUR(x->c.pc), + EX_MIN(x->c.pc), + EX_SEC(x->c.pc)), + x->c.of); +#endif + x->c.flags |= HAVE_JD; + } +} + +inline static void +get_c_civil(union DateData *x) +{ + assert(complex_dat_p(x)); + if (!have_civil_p(x)) { +#ifndef USE_PACK + int jd, y, m, d; +#else + int jd, y, m, d, h, min, s; +#endif + + assert(have_jd_p(x)); + get_c_df(x); + jd = jd_utc_to_local(x->c.jd, x->c.df, x->c.of); + c_jd_to_civil(jd, c_virtual_sg(x), &y, &m, &d); + x->c.year = y; +#ifndef USE_PACK + x->c.mon = m; + x->c.mday = d; +#else + h = EX_HOUR(x->c.pc); + min = EX_MIN(x->c.pc); + s = EX_SEC(x->c.pc); + x->c.pc = PACK5(m, d, h, min, s); +#endif + x->c.flags |= HAVE_CIVIL; + } +} + +inline static int +local_jd(union DateData *x) +{ + assert(complex_dat_p(x)); + assert(have_jd_p(x)); + assert(have_df_p(x)); + return jd_utc_to_local(x->c.jd, x->c.df, x->c.of); +} + +inline static int +local_df(union DateData *x) +{ + assert(complex_dat_p(x)); + assert(have_df_p(x)); + return df_utc_to_local(x->c.df, x->c.of); +} + +static void +decode_year(VALUE y, double style, + VALUE *nth, int *ry) +{ + int period; + VALUE t; + + period = (style < 0) ? + CM_PERIOD_GCY : + CM_PERIOD_JCY; + if (FIXNUM_P(y)) { + long iy, it, inth; + + iy = FIX2LONG(y); + if (iy >= (FIXNUM_MAX - 4712)) + goto big; + it = iy + 4712; /* shift */ + inth = DIV(it, ((long)period)); + *nth = LONG2FIX(inth); + if (inth) + it = MOD(it, ((long)period)); + *ry = (int)it - 4712; /* unshift */ + return; + } + big: + t = f_add(y, INT2FIX(4712)); /* shift */ + *nth = f_idiv(t, INT2FIX(period)); + if (f_nonzero_p(*nth)) + t = f_mod(t, INT2FIX(period)); + *ry = FIX2INT(t) - 4712; /* unshift */ +} + +static void +encode_year(VALUE nth, int y, double style, + VALUE *ry) +{ + int period; + VALUE t; + + period = (style < 0) ? + CM_PERIOD_GCY : + CM_PERIOD_JCY; + if (f_zero_p(nth)) + *ry = INT2FIX(y); + else { + t = f_mul(INT2FIX(period), nth); + t = f_add(t, INT2FIX(y)); + *ry = t; + } +} + +static void +decode_jd(VALUE jd, VALUE *nth, int *rjd) +{ + *nth = f_idiv(jd, INT2FIX(CM_PERIOD)); + if (f_zero_p(*nth)) { + *rjd = FIX2INT(jd); + return; + } + *rjd = FIX2INT(f_mod(jd, INT2FIX(CM_PERIOD))); +} + +static void +encode_jd(VALUE nth, int jd, VALUE *rjd) +{ + if (f_zero_p(nth)) { + *rjd = INT2FIX(jd); + return; + } + *rjd = f_add(f_mul(INT2FIX(CM_PERIOD), nth), INT2FIX(jd)); +} + +inline static double +guess_style(VALUE y, double sg) /* -/+oo or zero */ +{ + double style = 0; + + if (isinf(sg)) + style = sg; + else if (!FIXNUM_P(y)) + style = f_positive_p(y) ? negative_inf : positive_inf; + else { + long iy = FIX2LONG(y); + + assert(FIXNUM_P(y)); + if (iy < REFORM_BEGIN_YEAR) + style = positive_inf; + else if (iy > REFORM_END_YEAR) + style = negative_inf; + } + return style; +} + +inline static void +m_canonicalize_jd(VALUE obj, union DateData *x) +{ + if (simple_dat_p(x)) { + get_s_jd(x); + canonicalize_s_jd(obj, x); + } + else { + get_c_jd(x); + canonicalize_c_jd(obj, x); + } +} + +inline static VALUE +m_nth(union DateData *x) +{ + if (simple_dat_p(x)) + return x->s.nth; + else { + get_c_civil(x); + return x->c.nth; + } +} + +inline static int +m_jd(union DateData *x) +{ + if (simple_dat_p(x)) { + get_s_jd(x); + return x->s.jd; + } + else { + get_c_jd(x); + return x->c.jd; + } +} + +static VALUE +m_real_jd(union DateData *x) +{ + VALUE nth, rjd; + int jd; + + nth = m_nth(x); + jd = m_jd(x); + + encode_jd(nth, jd, &rjd); + return rjd; +} + +static int +m_local_jd(union DateData *x) +{ + if (simple_dat_p(x)) { + get_s_jd(x); + return x->s.jd; + } + else { + get_c_jd(x); + get_c_df(x); + return local_jd(x); + } +} + +static VALUE +m_real_local_jd(union DateData *x) +{ + VALUE nth, rjd; + int jd; + + nth = m_nth(x); + jd = m_local_jd(x); + + encode_jd(nth, jd, &rjd); + return rjd; +} + +inline static int +m_df(union DateData *x) +{ + if (simple_dat_p(x)) + return 0; + else { + get_c_df(x); + return x->c.df; + } +} + +#ifndef NDEBUG +/* :nodoc: */ +static VALUE +m_df_in_day(union DateData *x) +{ + return isec_to_day(m_df(x)); +} +#endif + +static int +m_local_df(union DateData *x) +{ + if (simple_dat_p(x)) + return 0; + else { + get_c_df(x); + return local_df(x); + } +} + +#ifndef NDEBUG +static VALUE +m_local_df_in_day(union DateData *x) +{ + return isec_to_day(m_local_df(x)); +} +#endif + +inline static VALUE +m_sf(union DateData *x) +{ + if (simple_dat_p(x)) + return INT2FIX(0); + else + return x->c.sf; +} + +#ifndef NDEBUG +static VALUE +m_sf_in_day(union DateData *x) +{ + return ns_to_day(m_sf(x)); +} +#endif + +static VALUE +m_sf_in_sec(union DateData *x) +{ + return ns_to_sec(m_sf(x)); +} + +static VALUE +m_fr(union DateData *x) +{ + if (simple_dat_p(x)) + return INT2FIX(0); + else { + int df; + VALUE sf, fr; + + df = m_local_df(x); + sf = m_sf(x); + fr = isec_to_day(df); + if (f_nonzero_p(sf)) + fr = f_add(fr, ns_to_day(sf)); + return fr; + } +} + +#define HALF_DAYS_IN_SECONDS (DAY_IN_SECONDS / 2) + +static VALUE +m_ajd(union DateData *x) +{ + VALUE r, sf; + int df; + + if (simple_dat_p(x)) { + r = m_real_jd(x); + if (FIXNUM_P(r) && FIX2LONG(r) <= (FIXNUM_MAX / 2)) { + long ir = FIX2LONG(r); + ir = ir * 2 - 1; + return rb_rational_new2(LONG2FIX(ir), INT2FIX(2)); + } + else + return rb_rational_new2(f_sub(f_mul(r, + INT2FIX(2)), + INT2FIX(1)), + INT2FIX(2)); + } + + r = m_real_jd(x); + df = m_df(x); + df -= HALF_DAYS_IN_SECONDS; + if (df) + r = f_add(r, isec_to_day(df)); + sf = m_sf(x); + if (f_nonzero_p(sf)) + r = f_add(r, ns_to_day(sf)); + + return r; +} + +static VALUE +m_amjd(union DateData *x) +{ + VALUE r, sf; + int df; + + r = m_real_jd(x); + if (FIXNUM_P(r) && FIX2LONG(r) >= (FIXNUM_MIN + 2400001)) { + long ir = FIX2LONG(r); + ir -= 2400001; + r = rb_rational_new1(LONG2FIX(ir)); + } + else + r = rb_rational_new1(f_sub(m_real_jd(x), + INT2FIX(2400001))); + + if (simple_dat_p(x)) + return r; + + df = m_df(x); + if (df) + r = f_add(r, isec_to_day(df)); + sf = m_sf(x); + if (f_nonzero_p(sf)) + r = f_add(r, ns_to_day(sf)); + + return r; +} + +inline static int +m_of(union DateData *x) +{ + if (simple_dat_p(x)) + return 0; + else { + get_c_jd(x); + return x->c.of; + } +} + +static VALUE +m_of_in_day(union DateData *x) +{ + return isec_to_day(m_of(x)); +} + +inline static double +m_sg(union DateData *x) +{ + if (simple_dat_p(x)) + return x->s.sg; + else { + get_c_jd(x); + return x->c.sg; + } +} + +static int +m_julian_p(union DateData *x) +{ + int jd; + double sg; + + if (simple_dat_p(x)) { + get_s_jd(x); + jd = x->s.jd; + sg = s_virtual_sg(x); + } + else { + get_c_jd(x); + jd = x->c.jd; + sg = c_virtual_sg(x); + } + if (isinf(sg)) + return sg == positive_inf; + return jd < sg; +} + +inline static int +m_gregorian_p(union DateData *x) +{ + return !m_julian_p(x); +} + +inline static int +m_proleptic_julian_p(union DateData *x) +{ + double sg; + + sg = m_sg(x); + if (isinf(sg) && sg > 0) + return 1; + return 0; +} + +inline static int +m_proleptic_gregorian_p(union DateData *x) +{ + double sg; + + sg = m_sg(x); + if (isinf(sg) && sg < 0) + return 1; + return 0; +} + +inline static int +m_year(union DateData *x) +{ + if (simple_dat_p(x)) { + get_s_civil(x); + return x->s.year; + } + else { + get_c_civil(x); + return x->c.year; + } +} + +static VALUE +m_real_year(union DateData *x) +{ + VALUE nth, ry; + int year; + + nth = m_nth(x); + year = m_year(x); + + if (f_zero_p(nth)) + return INT2FIX(year); + + encode_year(nth, year, + m_gregorian_p(x) ? -1 : +1, + &ry); + return ry; +} + +inline static int +m_mon(union DateData *x) +{ + if (simple_dat_p(x)) { + get_s_civil(x); +#ifndef USE_PACK + return x->s.mon; +#else + return EX_MON(x->s.pc); +#endif + } + else { + get_c_civil(x); +#ifndef USE_PACK + return x->c.mon; +#else + return EX_MON(x->c.pc); +#endif + } +} + +inline static int +m_mday(union DateData *x) +{ + if (simple_dat_p(x)) { + get_s_civil(x); +#ifndef USE_PACK + return x->s.mday; +#else + return EX_MDAY(x->s.pc); +#endif + } + else { + get_c_civil(x); +#ifndef USE_PACK + return x->c.mday; +#else + return EX_MDAY(x->c.pc); +#endif + } +} + +static const int yeartab[2][13] = { + { 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }, + { 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 } +}; + +static int +c_julian_to_yday(int y, int m, int d) +{ + assert(m >= 1 && m <= 12); + return yeartab[c_julian_leap_p(y) ? 1 : 0][m] + d; +} + +static int +c_gregorian_to_yday(int y, int m, int d) +{ + assert(m >= 1 && m <= 12); + return yeartab[c_gregorian_leap_p(y) ? 1 : 0][m] + d; +} + +static int +m_yday(union DateData *x) +{ + int jd, ry, rd; + double sg; + + jd = m_local_jd(x); + sg = m_virtual_sg(x); /* !=m_sg() */ + + if (m_proleptic_gregorian_p(x) || + (jd - sg) > 366) + return c_gregorian_to_yday(m_year(x), m_mon(x), m_mday(x)); + if (m_proleptic_julian_p(x)) + return c_julian_to_yday(m_year(x), m_mon(x), m_mday(x)); + c_jd_to_ordinal(jd, sg, &ry, &rd); + return rd; +} + +static int +m_wday(union DateData *x) +{ + return c_jd_to_wday(m_local_jd(x)); +} + +static int +m_cwyear(union DateData *x) +{ + int ry, rw, rd; + + c_jd_to_commercial(m_local_jd(x), m_virtual_sg(x), /* !=m_sg() */ + &ry, &rw, &rd); + return ry; +} + +static VALUE +m_real_cwyear(union DateData *x) +{ + VALUE nth, ry; + int year; + + nth = m_nth(x); + year = m_cwyear(x); + + if (f_zero_p(nth)) + return INT2FIX(year); + + encode_year(nth, year, + m_gregorian_p(x) ? -1 : +1, + &ry); + return ry; +} + +static int +m_cweek(union DateData *x) +{ + int ry, rw, rd; + + c_jd_to_commercial(m_local_jd(x), m_virtual_sg(x), /* !=m_sg() */ + &ry, &rw, &rd); + return rw; +} + +static int +m_cwday(union DateData *x) +{ + int w; + + w = m_wday(x); + if (w == 0) + w = 7; + return w; +} + +static int +m_wnumx(union DateData *x, int f) +{ + int ry, rw, rd; + + c_jd_to_weeknum(m_local_jd(x), f, m_virtual_sg(x), /* !=m_sg() */ + &ry, &rw, &rd); + return rw; +} + +static int +m_wnum0(union DateData *x) +{ + return m_wnumx(x, 0); +} + +static int +m_wnum1(union DateData *x) +{ + return m_wnumx(x, 1); +} + +inline static int +m_hour(union DateData *x) +{ + if (simple_dat_p(x)) + return 0; + else { + get_c_time(x); +#ifndef USE_PACK + return x->c.hour; +#else + return EX_HOUR(x->c.pc); +#endif + } +} + +inline static int +m_min(union DateData *x) +{ + if (simple_dat_p(x)) + return 0; + else { + get_c_time(x); +#ifndef USE_PACK + return x->c.min; +#else + return EX_MIN(x->c.pc); +#endif + } +} + +inline static int +m_sec(union DateData *x) +{ + if (simple_dat_p(x)) + return 0; + else { + get_c_time(x); +#ifndef USE_PACK + return x->c.sec; +#else + return EX_SEC(x->c.pc); +#endif + } +} + +#define decode_offset(of,s,h,m)\ +do {\ + int a;\ + s = (of < 0) ? '-' : '+';\ + a = (of < 0) ? -of : of;\ + h = a / HOUR_IN_SECONDS;\ + m = a % HOUR_IN_SECONDS / MINUTE_IN_SECONDS;\ +} while (0) + +static VALUE +of2str(int of) +{ + int s, h, m; + + decode_offset(of, s, h, m); + return rb_enc_sprintf(rb_usascii_encoding(), "%c%02d:%02d", s, h, m); +} + +static VALUE +m_zone(union DateData *x) +{ + if (simple_dat_p(x)) + return rb_usascii_str_new2("+00:00"); + return of2str(m_of(x)); +} + +inline static VALUE +f_kind_of_p(VALUE x, VALUE c) +{ + return rb_obj_is_kind_of(x, c); +} + +inline static VALUE +k_date_p(VALUE x) +{ + return f_kind_of_p(x, cDate); +} + +inline static VALUE +k_numeric_p(VALUE x) +{ + return f_kind_of_p(x, rb_cNumeric); +} + +inline static VALUE +k_rational_p(VALUE x) +{ + return f_kind_of_p(x, rb_cRational); +} + +static inline void +expect_numeric(VALUE x) +{ + if (!k_numeric_p(x)) + rb_raise(rb_eTypeError, "expected numeric"); +} + +#ifndef NDEBUG +/* :nodoc: */ +static void +civil_to_jd(VALUE y, int m, int d, double sg, + VALUE *nth, int *ry, + int *rjd, + int *ns) +{ + double style = guess_style(y, sg); + + if (style == 0) { + int jd; + + c_civil_to_jd(FIX2INT(y), m, d, sg, &jd, ns); + decode_jd(INT2FIX(jd), nth, rjd); + if (f_zero_p(*nth)) + *ry = FIX2INT(y); + else { + VALUE nth2; + decode_year(y, *ns ? -1 : +1, &nth2, ry); + } + } + else { + decode_year(y, style, nth, ry); + c_civil_to_jd(*ry, m, d, style, rjd, ns); + } +} + +static void +jd_to_civil(VALUE jd, double sg, + VALUE *nth, int *rjd, + int *ry, int *rm, int *rd) +{ + decode_jd(jd, nth, rjd); + c_jd_to_civil(*rjd, sg, ry, rm, rd); +} + +static void +ordinal_to_jd(VALUE y, int d, double sg, + VALUE *nth, int *ry, + int *rjd, + int *ns) +{ + double style = guess_style(y, sg); + + if (style == 0) { + int jd; + + c_ordinal_to_jd(FIX2INT(y), d, sg, &jd, ns); + decode_jd(INT2FIX(jd), nth, rjd); + if (f_zero_p(*nth)) + *ry = FIX2INT(y); + else { + VALUE nth2; + decode_year(y, *ns ? -1 : +1, &nth2, ry); + } + } + else { + decode_year(y, style, nth, ry); + c_ordinal_to_jd(*ry, d, style, rjd, ns); + } +} + +static void +jd_to_ordinal(VALUE jd, double sg, + VALUE *nth, int *rjd, + int *ry, int *rd) +{ + decode_jd(jd, nth, rjd); + c_jd_to_ordinal(*rjd, sg, ry, rd); +} + +static void +commercial_to_jd(VALUE y, int w, int d, double sg, + VALUE *nth, int *ry, + int *rjd, + int *ns) +{ + double style = guess_style(y, sg); + + if (style == 0) { + int jd; + + c_commercial_to_jd(FIX2INT(y), w, d, sg, &jd, ns); + decode_jd(INT2FIX(jd), nth, rjd); + if (f_zero_p(*nth)) + *ry = FIX2INT(y); + else { + VALUE nth2; + decode_year(y, *ns ? -1 : +1, &nth2, ry); + } + } + else { + decode_year(y, style, nth, ry); + c_commercial_to_jd(*ry, w, d, style, rjd, ns); + } +} + +static void +jd_to_commercial(VALUE jd, double sg, + VALUE *nth, int *rjd, + int *ry, int *rw, int *rd) +{ + decode_jd(jd, nth, rjd); + c_jd_to_commercial(*rjd, sg, ry, rw, rd); +} + +static void +weeknum_to_jd(VALUE y, int w, int d, int f, double sg, + VALUE *nth, int *ry, + int *rjd, + int *ns) +{ + double style = guess_style(y, sg); + + if (style == 0) { + int jd; + + c_weeknum_to_jd(FIX2INT(y), w, d, f, sg, &jd, ns); + decode_jd(INT2FIX(jd), nth, rjd); + if (f_zero_p(*nth)) + *ry = FIX2INT(y); + else { + VALUE nth2; + decode_year(y, *ns ? -1 : +1, &nth2, ry); + } + } + else { + decode_year(y, style, nth, ry); + c_weeknum_to_jd(*ry, w, d, f, style, rjd, ns); + } +} + +static void +jd_to_weeknum(VALUE jd, int f, double sg, + VALUE *nth, int *rjd, + int *ry, int *rw, int *rd) +{ + decode_jd(jd, nth, rjd); + c_jd_to_weeknum(*rjd, f, sg, ry, rw, rd); +} + +static void +nth_kday_to_jd(VALUE y, int m, int n, int k, double sg, + VALUE *nth, int *ry, + int *rjd, + int *ns) +{ + double style = guess_style(y, sg); + + if (style == 0) { + int jd; + + c_nth_kday_to_jd(FIX2INT(y), m, n, k, sg, &jd, ns); + decode_jd(INT2FIX(jd), nth, rjd); + if (f_zero_p(*nth)) + *ry = FIX2INT(y); + else { + VALUE nth2; + decode_year(y, *ns ? -1 : +1, &nth2, ry); + } + } + else { + decode_year(y, style, nth, ry); + c_nth_kday_to_jd(*ry, m, n, k, style, rjd, ns); + } +} + +static void +jd_to_nth_kday(VALUE jd, double sg, + VALUE *nth, int *rjd, + int *ry, int *rm, int *rn, int *rk) +{ + decode_jd(jd, nth, rjd); + c_jd_to_nth_kday(*rjd, sg, ry, rm, rn, rk); +} +#endif + +static int +valid_ordinal_p(VALUE y, int d, double sg, + VALUE *nth, int *ry, + int *rd, int *rjd, + int *ns) +{ + double style = guess_style(y, sg); + int r; + + if (style == 0) { + int jd; + + r = c_valid_ordinal_p(FIX2INT(y), d, sg, rd, &jd, ns); + if (!r) + return 0; + decode_jd(INT2FIX(jd), nth, rjd); + if (f_zero_p(*nth)) + *ry = FIX2INT(y); + else { + VALUE nth2; + decode_year(y, *ns ? -1 : +1, &nth2, ry); + } + } + else { + decode_year(y, style, nth, ry); + r = c_valid_ordinal_p(*ry, d, style, rd, rjd, ns); + } + return r; +} + +static int +valid_gregorian_p(VALUE y, int m, int d, + VALUE *nth, int *ry, + int *rm, int *rd) +{ + decode_year(y, -1, nth, ry); + return c_valid_gregorian_p(*ry, m, d, rm, rd); +} + +static int +valid_civil_p(VALUE y, int m, int d, double sg, + VALUE *nth, int *ry, + int *rm, int *rd, int *rjd, + int *ns) +{ + double style = guess_style(y, sg); + int r; + + if (style == 0) { + int jd; + + r = c_valid_civil_p(FIX2INT(y), m, d, sg, rm, rd, &jd, ns); + if (!r) + return 0; + decode_jd(INT2FIX(jd), nth, rjd); + if (f_zero_p(*nth)) + *ry = FIX2INT(y); + else { + VALUE nth2; + decode_year(y, *ns ? -1 : +1, &nth2, ry); + } + } + else { + decode_year(y, style, nth, ry); + if (style < 0) + r = c_valid_gregorian_p(*ry, m, d, rm, rd); + else + r = c_valid_julian_p(*ry, m, d, rm, rd); + if (!r) + return 0; + c_civil_to_jd(*ry, *rm, *rd, style, rjd, ns); + } + return r; +} + +static int +valid_commercial_p(VALUE y, int w, int d, double sg, + VALUE *nth, int *ry, + int *rw, int *rd, int *rjd, + int *ns) +{ + double style = guess_style(y, sg); + int r; + + if (style == 0) { + int jd; + + r = c_valid_commercial_p(FIX2INT(y), w, d, sg, rw, rd, &jd, ns); + if (!r) + return 0; + decode_jd(INT2FIX(jd), nth, rjd); + if (f_zero_p(*nth)) + *ry = FIX2INT(y); + else { + VALUE nth2; + decode_year(y, *ns ? -1 : +1, &nth2, ry); + } + } + else { + decode_year(y, style, nth, ry); + r = c_valid_commercial_p(*ry, w, d, style, rw, rd, rjd, ns); + } + return r; +} + +static int +valid_weeknum_p(VALUE y, int w, int d, int f, double sg, + VALUE *nth, int *ry, + int *rw, int *rd, int *rjd, + int *ns) +{ + double style = guess_style(y, sg); + int r; + + if (style == 0) { + int jd; + + r = c_valid_weeknum_p(FIX2INT(y), w, d, f, sg, rw, rd, &jd, ns); + if (!r) + return 0; + decode_jd(INT2FIX(jd), nth, rjd); + if (f_zero_p(*nth)) + *ry = FIX2INT(y); + else { + VALUE nth2; + decode_year(y, *ns ? -1 : +1, &nth2, ry); + } + } + else { + decode_year(y, style, nth, ry); + r = c_valid_weeknum_p(*ry, w, d, f, style, rw, rd, rjd, ns); + } + return r; +} + +#ifndef NDEBUG +/* :nodoc: */ +static int +valid_nth_kday_p(VALUE y, int m, int n, int k, double sg, + VALUE *nth, int *ry, + int *rm, int *rn, int *rk, int *rjd, + int *ns) +{ + double style = guess_style(y, sg); + int r; + + if (style == 0) { + int jd; + + r = c_valid_nth_kday_p(FIX2INT(y), m, n, k, sg, rm, rn, rk, &jd, ns); + if (!r) + return 0; + decode_jd(INT2FIX(jd), nth, rjd); + if (f_zero_p(*nth)) + *ry = FIX2INT(y); + else { + VALUE nth2; + decode_year(y, *ns ? -1 : +1, &nth2, ry); + } + } + else { + decode_year(y, style, nth, ry); + r = c_valid_nth_kday_p(*ry, m, n, k, style, rm, rn, rk, rjd, ns); + } + return r; +} +#endif + +VALUE date_zone_to_diff(VALUE); + +static int +offset_to_sec(VALUE vof, int *rof) +{ + int try_rational = 1; + + again: + switch (TYPE(vof)) { + case T_FIXNUM: + { + long n; + + n = FIX2LONG(vof); + if (n != -1 && n != 0 && n != 1) + return 0; + *rof = (int)n * DAY_IN_SECONDS; + return 1; + } + case T_FLOAT: + { + double n; + + n = RFLOAT_VALUE(vof) * DAY_IN_SECONDS; + if (n < -DAY_IN_SECONDS || n > DAY_IN_SECONDS) + return 0; + *rof = (int)round(n); + if (*rof != n) + rb_warning("fraction of offset is ignored"); + return 1; + } + default: + expect_numeric(vof); + vof = f_to_r(vof); + if (!k_rational_p(vof)) { + if (!try_rational) Check_Type(vof, T_RATIONAL); + try_rational = 0; + goto again; + } + /* fall through */ + case T_RATIONAL: + { + VALUE vs, vn, vd; + long n; + + vs = day_to_sec(vof); + + if (!k_rational_p(vs)) { + vn = vs; + goto rounded; + } + vn = rb_rational_num(vs); + vd = rb_rational_den(vs); + + if (FIXNUM_P(vn) && FIXNUM_P(vd) && (FIX2LONG(vd) == 1)) + n = FIX2LONG(vn); + else { + vn = f_round(vs); + if (!f_eqeq_p(vn, vs)) + rb_warning("fraction of offset is ignored"); + rounded: + if (!FIXNUM_P(vn)) + return 0; + n = FIX2LONG(vn); + if (n < -DAY_IN_SECONDS || n > DAY_IN_SECONDS) + return 0; + } + *rof = (int)n; + return 1; + } + case T_STRING: + { + VALUE vs = date_zone_to_diff(vof); + long n; + + if (!FIXNUM_P(vs)) + return 0; + n = FIX2LONG(vs); + if (n < -DAY_IN_SECONDS || n > DAY_IN_SECONDS) + return 0; + *rof = (int)n; + return 1; + } + } + return 0; +} + +/* date */ + +#define valid_sg(sg) \ +do {\ + if (!c_valid_start_p(sg)) {\ + sg = 0;\ + rb_warning("invalid start is ignored");\ + }\ +} while (0) + +static VALUE +valid_jd_sub(int argc, VALUE *argv, VALUE klass, int need_jd) +{ + double sg = NUM2DBL(argv[1]); + valid_sg(sg); + return argv[0]; +} + +#ifndef NDEBUG +/* :nodoc: */ +static VALUE +date_s__valid_jd_p(int argc, VALUE *argv, VALUE klass) +{ + VALUE vjd, vsg; + VALUE argv2[2]; + + rb_scan_args(argc, argv, "11", &vjd, &vsg); + + argv2[0] = vjd; + if (argc < 2) + argv2[1] = DBL2NUM(GREGORIAN); + else + argv2[1] = vsg; + + return valid_jd_sub(2, argv2, klass, 1); +} +#endif + +/* + * call-seq: + * Date.valid_jd?(jd, start = Date::ITALY) -> true + * + * Implemented for compatibility; + * returns +true+ unless +jd+ is invalid (i.e., not a Numeric). + * + * Date.valid_jd?(2451944) # => true + * + * See argument {start}[rdoc-ref:calendars.rdoc@Argument+start]. + * + * Related: Date.jd. + */ +static VALUE +date_s_valid_jd_p(int argc, VALUE *argv, VALUE klass) +{ + VALUE vjd, vsg; + VALUE argv2[2]; + + rb_scan_args(argc, argv, "11", &vjd, &vsg); + + RETURN_FALSE_UNLESS_NUMERIC(vjd); + argv2[0] = vjd; + if (argc < 2) + argv2[1] = INT2FIX(DEFAULT_SG); + else + argv2[1] = vsg; + + if (NIL_P(valid_jd_sub(2, argv2, klass, 0))) + return Qfalse; + return Qtrue; +} + +static VALUE +valid_civil_sub(int argc, VALUE *argv, VALUE klass, int need_jd) +{ + VALUE nth, y; + int m, d, ry, rm, rd; + double sg; + + y = argv[0]; + m = NUM2INT(argv[1]); + d = NUM2INT(argv[2]); + sg = NUM2DBL(argv[3]); + + valid_sg(sg); + + if (!need_jd && (guess_style(y, sg) < 0)) { + if (!valid_gregorian_p(y, m, d, + &nth, &ry, + &rm, &rd)) + return Qnil; + return INT2FIX(0); /* dummy */ + } + else { + int rjd, ns; + VALUE rjd2; + + if (!valid_civil_p(y, m, d, sg, + &nth, &ry, + &rm, &rd, &rjd, + &ns)) + return Qnil; + if (!need_jd) + return INT2FIX(0); /* dummy */ + encode_jd(nth, rjd, &rjd2); + return rjd2; + } +} + +#ifndef NDEBUG +/* :nodoc: */ +static VALUE +date_s__valid_civil_p(int argc, VALUE *argv, VALUE klass) +{ + VALUE vy, vm, vd, vsg; + VALUE argv2[4]; + + rb_scan_args(argc, argv, "31", &vy, &vm, &vd, &vsg); + + argv2[0] = vy; + argv2[1] = vm; + argv2[2] = vd; + if (argc < 4) + argv2[3] = DBL2NUM(GREGORIAN); + else + argv2[3] = vsg; + + return valid_civil_sub(4, argv2, klass, 1); +} +#endif + +/* + * call-seq: + * Date.valid_civil?(year, month, mday, start = Date::ITALY) -> true or false + * + * Returns +true+ if the arguments define a valid ordinal date, + * +false+ otherwise: + * + * Date.valid_date?(2001, 2, 3) # => true + * Date.valid_date?(2001, 2, 29) # => false + * Date.valid_date?(2001, 2, -1) # => true + * + * See argument {start}[rdoc-ref:calendars.rdoc@Argument+start]. + * + * Related: Date.jd, Date.new. + */ +static VALUE +date_s_valid_civil_p(int argc, VALUE *argv, VALUE klass) +{ + VALUE vy, vm, vd, vsg; + VALUE argv2[4]; + + rb_scan_args(argc, argv, "31", &vy, &vm, &vd, &vsg); + + RETURN_FALSE_UNLESS_NUMERIC(vy); + RETURN_FALSE_UNLESS_NUMERIC(vm); + RETURN_FALSE_UNLESS_NUMERIC(vd); + argv2[0] = vy; + argv2[1] = vm; + argv2[2] = vd; + if (argc < 4) + argv2[3] = INT2FIX(DEFAULT_SG); + else + argv2[3] = vsg; + + if (NIL_P(valid_civil_sub(4, argv2, klass, 0))) + return Qfalse; + return Qtrue; +} + +static VALUE +valid_ordinal_sub(int argc, VALUE *argv, VALUE klass, int need_jd) +{ + VALUE nth, y; + int d, ry, rd; + double sg; + + y = argv[0]; + d = NUM2INT(argv[1]); + sg = NUM2DBL(argv[2]); + + valid_sg(sg); + + { + int rjd, ns; + VALUE rjd2; + + if (!valid_ordinal_p(y, d, sg, + &nth, &ry, + &rd, &rjd, + &ns)) + return Qnil; + if (!need_jd) + return INT2FIX(0); /* dummy */ + encode_jd(nth, rjd, &rjd2); + return rjd2; + } +} + +#ifndef NDEBUG +/* :nodoc: */ +static VALUE +date_s__valid_ordinal_p(int argc, VALUE *argv, VALUE klass) +{ + VALUE vy, vd, vsg; + VALUE argv2[3]; + + rb_scan_args(argc, argv, "21", &vy, &vd, &vsg); + + argv2[0] = vy; + argv2[1] = vd; + if (argc < 3) + argv2[2] = DBL2NUM(GREGORIAN); + else + argv2[2] = vsg; + + return valid_ordinal_sub(3, argv2, klass, 1); +} +#endif + +/* + * call-seq: + * Date.valid_ordinal?(year, yday, start = Date::ITALY) -> true or false + * + * Returns +true+ if the arguments define a valid ordinal date, + * +false+ otherwise: + * + * Date.valid_ordinal?(2001, 34) # => true + * Date.valid_ordinal?(2001, 366) # => false + * + * See argument {start}[rdoc-ref:calendars.rdoc@Argument+start]. + * + * Related: Date.jd, Date.ordinal. + */ +static VALUE +date_s_valid_ordinal_p(int argc, VALUE *argv, VALUE klass) +{ + VALUE vy, vd, vsg; + VALUE argv2[3]; + + rb_scan_args(argc, argv, "21", &vy, &vd, &vsg); + + RETURN_FALSE_UNLESS_NUMERIC(vy); + RETURN_FALSE_UNLESS_NUMERIC(vd); + argv2[0] = vy; + argv2[1] = vd; + if (argc < 3) + argv2[2] = INT2FIX(DEFAULT_SG); + else + argv2[2] = vsg; + + if (NIL_P(valid_ordinal_sub(3, argv2, klass, 0))) + return Qfalse; + return Qtrue; +} + +static VALUE +valid_commercial_sub(int argc, VALUE *argv, VALUE klass, int need_jd) +{ + VALUE nth, y; + int w, d, ry, rw, rd; + double sg; + + y = argv[0]; + w = NUM2INT(argv[1]); + d = NUM2INT(argv[2]); + sg = NUM2DBL(argv[3]); + + valid_sg(sg); + + { + int rjd, ns; + VALUE rjd2; + + if (!valid_commercial_p(y, w, d, sg, + &nth, &ry, + &rw, &rd, &rjd, + &ns)) + return Qnil; + if (!need_jd) + return INT2FIX(0); /* dummy */ + encode_jd(nth, rjd, &rjd2); + return rjd2; + } +} + +#ifndef NDEBUG +/* :nodoc: */ +static VALUE +date_s__valid_commercial_p(int argc, VALUE *argv, VALUE klass) +{ + VALUE vy, vw, vd, vsg; + VALUE argv2[4]; + + rb_scan_args(argc, argv, "31", &vy, &vw, &vd, &vsg); + + argv2[0] = vy; + argv2[1] = vw; + argv2[2] = vd; + if (argc < 4) + argv2[3] = DBL2NUM(GREGORIAN); + else + argv2[3] = vsg; + + return valid_commercial_sub(4, argv2, klass, 1); +} +#endif + +/* + * call-seq: + * Date.valid_commercial?(cwyear, cweek, cwday, start = Date::ITALY) -> true or false + * + * Returns +true+ if the arguments define a valid commercial date, + * +false+ otherwise: + * + * Date.valid_commercial?(2001, 5, 6) # => true + * Date.valid_commercial?(2001, 5, 8) # => false + * + * See Date.commercial. + * + * See argument {start}[rdoc-ref:calendars.rdoc@Argument+start]. + * + * Related: Date.jd, Date.commercial. + */ +static VALUE +date_s_valid_commercial_p(int argc, VALUE *argv, VALUE klass) +{ + VALUE vy, vw, vd, vsg; + VALUE argv2[4]; + + rb_scan_args(argc, argv, "31", &vy, &vw, &vd, &vsg); + + RETURN_FALSE_UNLESS_NUMERIC(vy); + RETURN_FALSE_UNLESS_NUMERIC(vw); + RETURN_FALSE_UNLESS_NUMERIC(vd); + argv2[0] = vy; + argv2[1] = vw; + argv2[2] = vd; + if (argc < 4) + argv2[3] = INT2FIX(DEFAULT_SG); + else + argv2[3] = vsg; + + if (NIL_P(valid_commercial_sub(4, argv2, klass, 0))) + return Qfalse; + return Qtrue; +} + +#ifndef NDEBUG +/* :nodoc: */ +static VALUE +valid_weeknum_sub(int argc, VALUE *argv, VALUE klass, int need_jd) +{ + VALUE nth, y; + int w, d, f, ry, rw, rd; + double sg; + + y = argv[0]; + w = NUM2INT(argv[1]); + d = NUM2INT(argv[2]); + f = NUM2INT(argv[3]); + sg = NUM2DBL(argv[4]); + + valid_sg(sg); + + { + int rjd, ns; + VALUE rjd2; + + if (!valid_weeknum_p(y, w, d, f, sg, + &nth, &ry, + &rw, &rd, &rjd, + &ns)) + return Qnil; + if (!need_jd) + return INT2FIX(0); /* dummy */ + encode_jd(nth, rjd, &rjd2); + return rjd2; + } +} + +/* :nodoc: */ +static VALUE +date_s__valid_weeknum_p(int argc, VALUE *argv, VALUE klass) +{ + VALUE vy, vw, vd, vf, vsg; + VALUE argv2[5]; + + rb_scan_args(argc, argv, "41", &vy, &vw, &vd, &vf, &vsg); + + argv2[0] = vy; + argv2[1] = vw; + argv2[2] = vd; + argv2[3] = vf; + if (argc < 5) + argv2[4] = DBL2NUM(GREGORIAN); + else + argv2[4] = vsg; + + return valid_weeknum_sub(5, argv2, klass, 1); +} + +/* :nodoc: */ +static VALUE +date_s_valid_weeknum_p(int argc, VALUE *argv, VALUE klass) +{ + VALUE vy, vw, vd, vf, vsg; + VALUE argv2[5]; + + rb_scan_args(argc, argv, "41", &vy, &vw, &vd, &vf, &vsg); + + argv2[0] = vy; + argv2[1] = vw; + argv2[2] = vd; + argv2[3] = vf; + if (argc < 5) + argv2[4] = INT2FIX(DEFAULT_SG); + else + argv2[4] = vsg; + + if (NIL_P(valid_weeknum_sub(5, argv2, klass, 0))) + return Qfalse; + return Qtrue; +} + +static VALUE +valid_nth_kday_sub(int argc, VALUE *argv, VALUE klass, int need_jd) +{ + VALUE nth, y; + int m, n, k, ry, rm, rn, rk; + double sg; + + y = argv[0]; + m = NUM2INT(argv[1]); + n = NUM2INT(argv[2]); + k = NUM2INT(argv[3]); + sg = NUM2DBL(argv[4]); + + { + int rjd, ns; + VALUE rjd2; + + if (!valid_nth_kday_p(y, m, n, k, sg, + &nth, &ry, + &rm, &rn, &rk, &rjd, + &ns)) + return Qnil; + if (!need_jd) + return INT2FIX(0); /* dummy */ + encode_jd(nth, rjd, &rjd2); + return rjd2; + } +} + +/* :nodoc: */ +static VALUE +date_s__valid_nth_kday_p(int argc, VALUE *argv, VALUE klass) +{ + VALUE vy, vm, vn, vk, vsg; + VALUE argv2[5]; + + rb_scan_args(argc, argv, "41", &vy, &vm, &vn, &vk, &vsg); + + argv2[0] = vy; + argv2[1] = vm; + argv2[2] = vn; + argv2[3] = vk; + if (argc < 5) + argv2[4] = DBL2NUM(GREGORIAN); + else + argv2[4] = vsg; + + return valid_nth_kday_sub(5, argv2, klass, 1); +} + +/* :nodoc: */ +static VALUE +date_s_valid_nth_kday_p(int argc, VALUE *argv, VALUE klass) +{ + VALUE vy, vm, vn, vk, vsg; + VALUE argv2[5]; + + rb_scan_args(argc, argv, "41", &vy, &vm, &vn, &vk, &vsg); + + argv2[0] = vy; + argv2[1] = vm; + argv2[2] = vn; + argv2[3] = vk; + if (argc < 5) + argv2[4] = INT2FIX(DEFAULT_SG); + else + argv2[4] = vsg; + + if (NIL_P(valid_nth_kday_sub(5, argv2, klass, 0))) + return Qfalse; + return Qtrue; +} + +/* :nodoc: */ +static VALUE +date_s_zone_to_diff(VALUE klass, VALUE str) +{ + return date_zone_to_diff(str); +} +#endif + +/* + * call-seq: + * Date.julian_leap?(year) -> true or false + * + * Returns +true+ if the given year is a leap year + * in the {proleptic Julian calendar}[https://en.wikipedia.org/wiki/Proleptic_Julian_calendar], +false+ otherwise: + * + * Date.julian_leap?(1900) # => true + * Date.julian_leap?(1901) # => false + * + * Related: Date.gregorian_leap?. + */ +static VALUE +date_s_julian_leap_p(VALUE klass, VALUE y) +{ + VALUE nth; + int ry; + + check_numeric(y, "year"); + decode_year(y, +1, &nth, &ry); + return f_boolcast(c_julian_leap_p(ry)); +} + +/* + * call-seq: + * Date.gregorian_leap?(year) -> true or false + * + * Returns +true+ if the given year is a leap year + * in the {proleptic Gregorian calendar}[https://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar], +false+ otherwise: + * + * Date.gregorian_leap?(2000) # => true + * Date.gregorian_leap?(2001) # => false + * + * Related: Date.julian_leap?. + */ +static VALUE +date_s_gregorian_leap_p(VALUE klass, VALUE y) +{ + VALUE nth; + int ry; + + check_numeric(y, "year"); + decode_year(y, -1, &nth, &ry); + return f_boolcast(c_gregorian_leap_p(ry)); +} + +static void +d_lite_gc_mark(void *ptr) +{ + union DateData *dat = ptr; + if (simple_dat_p(dat)) + rb_gc_mark(dat->s.nth); + else { + rb_gc_mark(dat->c.nth); + rb_gc_mark(dat->c.sf); + } +} + +static size_t +d_lite_memsize(const void *ptr) +{ + const union DateData *dat = ptr; + return complex_dat_p(dat) ? sizeof(struct ComplexDateData) : sizeof(struct SimpleDateData); +} + +#ifndef HAVE_RB_EXT_RACTOR_SAFE +# define RUBY_TYPED_FROZEN_SHAREABLE 0 +#endif + +static const rb_data_type_t d_lite_type = { + "Date", + {d_lite_gc_mark, RUBY_TYPED_DEFAULT_FREE, d_lite_memsize,}, + 0, 0, + RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED|RUBY_TYPED_FROZEN_SHAREABLE, +}; + +inline static VALUE +d_simple_new_internal(VALUE klass, + VALUE nth, int jd, + double sg, + int y, int m, int d, + unsigned flags) +{ + struct SimpleDateData *dat; + VALUE obj; + + obj = TypedData_Make_Struct(klass, struct SimpleDateData, + &d_lite_type, dat); + set_to_simple(obj, dat, nth, jd, sg, y, m, d, flags); + + assert(have_jd_p(dat) || have_civil_p(dat)); + + return obj; +} + +inline static VALUE +d_complex_new_internal(VALUE klass, + VALUE nth, int jd, + int df, VALUE sf, + int of, double sg, + int y, int m, int d, + int h, int min, int s, + unsigned flags) +{ + struct ComplexDateData *dat; + VALUE obj; + + obj = TypedData_Make_Struct(klass, struct ComplexDateData, + &d_lite_type, dat); + set_to_complex(obj, dat, nth, jd, df, sf, of, sg, + y, m, d, h, min, s, flags); + + assert(have_jd_p(dat) || have_civil_p(dat)); + assert(have_df_p(dat) || have_time_p(dat)); + + return obj; +} + +static VALUE +d_lite_s_alloc_simple(VALUE klass) +{ + return d_simple_new_internal(klass, + INT2FIX(0), 0, + DEFAULT_SG, + 0, 0, 0, + HAVE_JD); +} + +static VALUE +d_lite_s_alloc_complex(VALUE klass) +{ + return d_complex_new_internal(klass, + INT2FIX(0), 0, + 0, INT2FIX(0), + 0, DEFAULT_SG, + 0, 0, 0, + 0, 0, 0, + HAVE_JD | HAVE_DF); +} + +static VALUE +d_lite_s_alloc(VALUE klass) +{ + return d_lite_s_alloc_complex(klass); +} + +static void +old_to_new(VALUE ajd, VALUE of, VALUE sg, + VALUE *rnth, int *rjd, int *rdf, VALUE *rsf, + int *rof, double *rsg) +{ + VALUE jd, df, sf, of2, t; + + decode_day(f_add(ajd, half_days_in_day), + &jd, &df, &sf); + t = day_to_sec(of); + of2 = f_round(t); + + if (!f_eqeq_p(of2, t)) + rb_warning("fraction of offset is ignored"); + + decode_jd(jd, rnth, rjd); + + *rdf = NUM2INT(df); + *rsf = sf; + *rof = NUM2INT(of2); + *rsg = NUM2DBL(sg); + + if (*rdf < 0 || *rdf >= DAY_IN_SECONDS) + rb_raise(eDateError, "invalid day fraction"); + + if (f_lt_p(*rsf, INT2FIX(0)) || + f_ge_p(*rsf, INT2FIX(SECOND_IN_NANOSECONDS))) + + if (*rof < -DAY_IN_SECONDS || *rof > DAY_IN_SECONDS) { + *rof = 0; + rb_warning("invalid offset is ignored"); + } + + if (!c_valid_start_p(*rsg)) { + *rsg = DEFAULT_SG; + rb_warning("invalid start is ignored"); + } +} + +#ifndef NDEBUG +/* :nodoc: */ +static VALUE +date_s_new_bang(int argc, VALUE *argv, VALUE klass) +{ + VALUE ajd, of, sg, nth, sf; + int jd, df, rof; + double rsg; + + rb_scan_args(argc, argv, "03", &ajd, &of, &sg); + + switch (argc) { + case 0: + ajd = INT2FIX(0); + case 1: + of = INT2FIX(0); + case 2: + sg = INT2FIX(DEFAULT_SG); + } + + old_to_new(ajd, of, sg, + &nth, &jd, &df, &sf, &rof, &rsg); + + if (!df && f_zero_p(sf) && !rof) + return d_simple_new_internal(klass, + nth, jd, + rsg, + 0, 0, 0, + HAVE_JD); + else + return d_complex_new_internal(klass, + nth, jd, + df, sf, + rof, rsg, + 0, 0, 0, + 0, 0, 0, + HAVE_JD | HAVE_DF); +} +#endif + +inline static int +wholenum_p(VALUE x) +{ + if (FIXNUM_P(x)) + return 1; + switch (TYPE(x)) { + case T_BIGNUM: + return 1; + case T_FLOAT: + { + double d = RFLOAT_VALUE(x); + return round(d) == d; + } + break; + case T_RATIONAL: + { + VALUE den = rb_rational_den(x); + return FIXNUM_P(den) && FIX2LONG(den) == 1; + } + break; + } + return 0; +} + +inline static VALUE +to_integer(VALUE x) +{ + if (RB_INTEGER_TYPE_P(x)) + return x; + return f_to_i(x); +} + +inline static VALUE +d_trunc(VALUE d, VALUE *fr) +{ + VALUE rd; + + if (wholenum_p(d)) { + rd = to_integer(d); + *fr = INT2FIX(0); + } + else { + rd = f_idiv(d, INT2FIX(1)); + *fr = f_mod(d, INT2FIX(1)); + } + return rd; +} + +#define jd_trunc d_trunc +#define k_trunc d_trunc + +inline static VALUE +h_trunc(VALUE h, VALUE *fr) +{ + VALUE rh; + + if (wholenum_p(h)) { + rh = to_integer(h); + *fr = INT2FIX(0); + } + else { + rh = f_idiv(h, INT2FIX(1)); + *fr = f_mod(h, INT2FIX(1)); + *fr = f_quo(*fr, INT2FIX(24)); + } + return rh; +} + +inline static VALUE +min_trunc(VALUE min, VALUE *fr) +{ + VALUE rmin; + + if (wholenum_p(min)) { + rmin = to_integer(min); + *fr = INT2FIX(0); + } + else { + rmin = f_idiv(min, INT2FIX(1)); + *fr = f_mod(min, INT2FIX(1)); + *fr = f_quo(*fr, INT2FIX(1440)); + } + return rmin; +} + +inline static VALUE +s_trunc(VALUE s, VALUE *fr) +{ + VALUE rs; + + if (wholenum_p(s)) { + rs = to_integer(s); + *fr = INT2FIX(0); + } + else { + rs = f_idiv(s, INT2FIX(1)); + *fr = f_mod(s, INT2FIX(1)); + *fr = f_quo(*fr, INT2FIX(86400)); + } + return rs; +} + +#define num2num_with_frac(s,n) \ +do {\ + s = s##_trunc(v##s, &fr);\ + if (f_nonzero_p(fr)) {\ + if (argc > n)\ + rb_raise(eDateError, "invalid fraction");\ + fr2 = fr;\ + }\ +} while (0) + +#define num2int_with_frac(s,n) \ +do {\ + s = NUM2INT(s##_trunc(v##s, &fr));\ + if (f_nonzero_p(fr)) {\ + if (argc > n)\ + rb_raise(eDateError, "invalid fraction");\ + fr2 = fr;\ + }\ +} while (0) + +#define canon24oc() \ +do {\ + if (rh == 24) {\ + rh = 0;\ + fr2 = f_add(fr2, INT2FIX(1));\ + }\ +} while (0) + +#define add_frac() \ +do {\ + if (f_nonzero_p(fr2))\ + ret = d_lite_plus(ret, fr2);\ +} while (0) + +#define val2sg(vsg,dsg) \ +do {\ + dsg = NUM2DBL(vsg);\ + if (!c_valid_start_p(dsg)) {\ + dsg = DEFAULT_SG;\ + rb_warning("invalid start is ignored");\ + }\ +} while (0) + +static VALUE d_lite_plus(VALUE, VALUE); + +/* + * call-seq: + * Date.jd(jd = 0, start = Date::ITALY) -> date + * + * Returns a new \Date object formed from the arguments: + * + * Date.jd(2451944).to_s # => "2001-02-03" + * Date.jd(2451945).to_s # => "2001-02-04" + * Date.jd(0).to_s # => "-4712-01-01" + * + * The returned date is: + * + * - Gregorian, if the argument is greater than or equal to +start+: + * + * Date::ITALY # => 2299161 + * Date.jd(Date::ITALY).gregorian? # => true + * Date.jd(Date::ITALY + 1).gregorian? # => true + * + * - Julian, otherwise + * + * Date.jd(Date::ITALY - 1).julian? # => true + * + * See argument {start}[rdoc-ref:calendars.rdoc@Argument+start]. + * + * Related: Date.new. + */ +static VALUE +date_s_jd(int argc, VALUE *argv, VALUE klass) +{ + VALUE vjd, vsg, jd, fr, fr2, ret; + double sg; + + rb_scan_args(argc, argv, "02", &vjd, &vsg); + + jd = INT2FIX(0); + fr2 = INT2FIX(0); + sg = DEFAULT_SG; + + switch (argc) { + case 2: + val2sg(vsg, sg); + case 1: + check_numeric(vjd, "jd"); + num2num_with_frac(jd, positive_inf); + } + + { + VALUE nth; + int rjd; + + decode_jd(jd, &nth, &rjd); + ret = d_simple_new_internal(klass, + nth, rjd, + sg, + 0, 0, 0, + HAVE_JD); + } + add_frac(); + return ret; +} + +/* + * call-seq: + * Date.ordinal(year = -4712, yday = 1, start = Date::ITALY) -> date + * + * Returns a new \Date object formed fom the arguments. + * + * With no arguments, returns the date for January 1, -4712: + * + * Date.ordinal.to_s # => "-4712-01-01" + * + * With argument +year+, returns the date for January 1 of that year: + * + * Date.ordinal(2001).to_s # => "2001-01-01" + * Date.ordinal(-2001).to_s # => "-2001-01-01" + * + * With positive argument +yday+ == +n+, + * returns the date for the +nth+ day of the given year: + * + * Date.ordinal(2001, 14).to_s # => "2001-01-14" + * + * With negative argument +yday+, counts backward from the end of the year: + * + * Date.ordinal(2001, -14).to_s # => "2001-12-18" + * + * Raises an exception if +yday+ is zero or out of range. + * + * See argument {start}[rdoc-ref:calendars.rdoc@Argument+start]. + * + * Related: Date.jd, Date.new. + */ +static VALUE +date_s_ordinal(int argc, VALUE *argv, VALUE klass) +{ + VALUE vy, vd, vsg, y, fr, fr2, ret; + int d; + double sg; + + rb_scan_args(argc, argv, "03", &vy, &vd, &vsg); + + y = INT2FIX(-4712); + d = 1; + fr2 = INT2FIX(0); + sg = DEFAULT_SG; + + switch (argc) { + case 3: + val2sg(vsg, sg); + case 2: + check_numeric(vd, "yday"); + num2int_with_frac(d, positive_inf); + case 1: + check_numeric(vy, "year"); + y = vy; + } + + { + VALUE nth; + int ry, rd, rjd, ns; + + if (!valid_ordinal_p(y, d, sg, + &nth, &ry, + &rd, &rjd, + &ns)) + rb_raise(eDateError, "invalid date"); + + ret = d_simple_new_internal(klass, + nth, rjd, + sg, + 0, 0, 0, + HAVE_JD); + } + add_frac(); + return ret; +} + +/* + * Same as Date.new. + */ +static VALUE +date_s_civil(int argc, VALUE *argv, VALUE klass) +{ + return date_initialize(argc, argv, d_lite_s_alloc_simple(klass)); +} + +/* + * call-seq: + * Date.new(year = -4712, month = 1, mday = 1, start = Date::ITALY) -> date + * + * Returns a new \Date object constructed from the given arguments: + * + * Date.new(2022).to_s # => "2022-01-01" + * Date.new(2022, 2).to_s # => "2022-02-01" + * Date.new(2022, 2, 4).to_s # => "2022-02-04" + * + * Argument +month+ should be in range (1..12) or range (-12..-1); + * when the argument is negative, counts backward from the end of the year: + * + * Date.new(2022, -11, 4).to_s # => "2022-02-04" + * + * Argument +mday+ should be in range (1..n) or range (-n..-1) + * where +n+ is the number of days in the month; + * when the argument is negative, counts backward from the end of the month. + * + * See argument {start}[rdoc-ref:calendars.rdoc@Argument+start]. + * + * Related: Date.jd. + */ +static VALUE +date_initialize(int argc, VALUE *argv, VALUE self) +{ + VALUE vy, vm, vd, vsg, y, fr, fr2, ret; + int m, d; + double sg; + struct SimpleDateData *dat = rb_check_typeddata(self, &d_lite_type); + + if (!simple_dat_p(dat)) { + rb_raise(rb_eTypeError, "Date expected"); + } + + rb_scan_args(argc, argv, "04", &vy, &vm, &vd, &vsg); + + y = INT2FIX(-4712); + m = 1; + d = 1; + fr2 = INT2FIX(0); + sg = DEFAULT_SG; + + switch (argc) { + case 4: + val2sg(vsg, sg); + case 3: + check_numeric(vd, "day"); + num2int_with_frac(d, positive_inf); + case 2: + check_numeric(vm, "month"); + m = NUM2INT(vm); + case 1: + check_numeric(vy, "year"); + y = vy; + } + + if (guess_style(y, sg) < 0) { + VALUE nth; + int ry, rm, rd; + + if (!valid_gregorian_p(y, m, d, + &nth, &ry, + &rm, &rd)) + rb_raise(eDateError, "invalid date"); + + set_to_simple(self, dat, nth, 0, sg, ry, rm, rd, HAVE_CIVIL); + } + else { + VALUE nth; + int ry, rm, rd, rjd, ns; + + if (!valid_civil_p(y, m, d, sg, + &nth, &ry, + &rm, &rd, &rjd, + &ns)) + rb_raise(eDateError, "invalid date"); + + set_to_simple(self, dat, nth, rjd, sg, ry, rm, rd, HAVE_JD | HAVE_CIVIL); + } + ret = self; + add_frac(); + return ret; +} + +/* + * call-seq: + * Date.commercial(cwyear = -4712, cweek = 1, cwday = 1, start = Date::ITALY) -> date + * + * Returns a new \Date object constructed from the arguments. + * + * Argument +cwyear+ gives the year, and should be an integer. + * + * Argument +cweek+ gives the index of the week within the year, + * and should be in range (1..53) or (-53..-1); + * in some years, 53 or -53 will be out-of-range; + * if negative, counts backward from the end of the year: + * + * Date.commercial(2022, 1, 1).to_s # => "2022-01-03" + * Date.commercial(2022, 52, 1).to_s # => "2022-12-26" + * + * Argument +cwday+ gives the indes of the weekday within the week, + * and should be in range (1..7) or (-7..-1); + * 1 or -7 is Monday; + * if negative, counts backward from the end of the week: + * + * Date.commercial(2022, 1, 1).to_s # => "2022-01-03" + * Date.commercial(2022, 1, -7).to_s # => "2022-01-03" + * + * When +cweek+ is 1: + * + * - If January 1 is a Friday, Saturday, or Sunday, + * the first week begins in the week after: + * + * Date::ABBR_DAYNAMES[Date.new(2023, 1, 1).wday] # => "Sun" + * Date.commercial(2023, 1, 1).to_s # => "2023-01-02" + Date.commercial(2023, 1, 7).to_s # => "2023-01-08" + * + * - Otherwise, the first week is the week of January 1, + * which may mean some of the days fall on the year before: + * + * Date::ABBR_DAYNAMES[Date.new(2020, 1, 1).wday] # => "Wed" + * Date.commercial(2020, 1, 1).to_s # => "2019-12-30" + Date.commercial(2020, 1, 7).to_s # => "2020-01-05" + * + * See argument {start}[rdoc-ref:calendars.rdoc@Argument+start]. + * + * Related: Date.jd, Date.new, Date.ordinal. + */ +static VALUE +date_s_commercial(int argc, VALUE *argv, VALUE klass) +{ + VALUE vy, vw, vd, vsg, y, fr, fr2, ret; + int w, d; + double sg; + + rb_scan_args(argc, argv, "04", &vy, &vw, &vd, &vsg); + + y = INT2FIX(-4712); + w = 1; + d = 1; + fr2 = INT2FIX(0); + sg = DEFAULT_SG; + + switch (argc) { + case 4: + val2sg(vsg, sg); + case 3: + check_numeric(vd, "cwday"); + num2int_with_frac(d, positive_inf); + case 2: + check_numeric(vw, "cweek"); + w = NUM2INT(vw); + case 1: + check_numeric(vy, "year"); + y = vy; + } + + { + VALUE nth; + int ry, rw, rd, rjd, ns; + + if (!valid_commercial_p(y, w, d, sg, + &nth, &ry, + &rw, &rd, &rjd, + &ns)) + rb_raise(eDateError, "invalid date"); + + ret = d_simple_new_internal(klass, + nth, rjd, + sg, + 0, 0, 0, + HAVE_JD); + } + add_frac(); + return ret; +} + +#ifndef NDEBUG +/* :nodoc: */ +static VALUE +date_s_weeknum(int argc, VALUE *argv, VALUE klass) +{ + VALUE vy, vw, vd, vf, vsg, y, fr, fr2, ret; + int w, d, f; + double sg; + + rb_scan_args(argc, argv, "05", &vy, &vw, &vd, &vf, &vsg); + + y = INT2FIX(-4712); + w = 0; + d = 1; + f = 0; + fr2 = INT2FIX(0); + sg = DEFAULT_SG; + + switch (argc) { + case 5: + val2sg(vsg, sg); + case 4: + f = NUM2INT(vf); + case 3: + num2int_with_frac(d, positive_inf); + case 2: + w = NUM2INT(vw); + case 1: + y = vy; + } + + { + VALUE nth; + int ry, rw, rd, rjd, ns; + + if (!valid_weeknum_p(y, w, d, f, sg, + &nth, &ry, + &rw, &rd, &rjd, + &ns)) + rb_raise(eDateError, "invalid date"); + + ret = d_simple_new_internal(klass, + nth, rjd, + sg, + 0, 0, 0, + HAVE_JD); + } + add_frac(); + return ret; +} + +/* :nodoc: */ +static VALUE +date_s_nth_kday(int argc, VALUE *argv, VALUE klass) +{ + VALUE vy, vm, vn, vk, vsg, y, fr, fr2, ret; + int m, n, k; + double sg; + + rb_scan_args(argc, argv, "05", &vy, &vm, &vn, &vk, &vsg); + + y = INT2FIX(-4712); + m = 1; + n = 1; + k = 1; + fr2 = INT2FIX(0); + sg = DEFAULT_SG; + + switch (argc) { + case 5: + val2sg(vsg, sg); + case 4: + num2int_with_frac(k, positive_inf); + case 3: + n = NUM2INT(vn); + case 2: + m = NUM2INT(vm); + case 1: + y = vy; + } + + { + VALUE nth; + int ry, rm, rn, rk, rjd, ns; + + if (!valid_nth_kday_p(y, m, n, k, sg, + &nth, &ry, + &rm, &rn, &rk, &rjd, + &ns)) + rb_raise(eDateError, "invalid date"); + + ret = d_simple_new_internal(klass, + nth, rjd, + sg, + 0, 0, 0, + HAVE_JD); + } + add_frac(); + return ret; +} +#endif + +#if !defined(HAVE_GMTIME_R) +static struct tm* +gmtime_r(const time_t *t, struct tm *tm) +{ + auto struct tm *tmp = gmtime(t); + if (tmp) + *tm = *tmp; + return tmp; +} + +static struct tm* +localtime_r(const time_t *t, struct tm *tm) +{ + auto struct tm *tmp = localtime(t); + if (tmp) + *tm = *tmp; + return tmp; +} +#endif + +static void set_sg(union DateData *, double); + +/* + * call-seq: + * Date.today(start = Date::ITALY) -> date + * + * Returns a new \Date object constructed from the present date: + * + * Date.today.to_s # => "2022-07-06" + * + * See argument {start}[rdoc-ref:calendars.rdoc@Argument+start]. + * + */ +static VALUE +date_s_today(int argc, VALUE *argv, VALUE klass) +{ + VALUE vsg, nth, ret; + double sg; + time_t t; + struct tm tm; + int y, ry, m, d; + + rb_scan_args(argc, argv, "01", &vsg); + + if (argc < 1) + sg = DEFAULT_SG; + else + val2sg(vsg, sg); + + if (time(&t) == -1) + rb_sys_fail("time"); + tzset(); + if (!localtime_r(&t, &tm)) + rb_sys_fail("localtime"); + + y = tm.tm_year + 1900; + m = tm.tm_mon + 1; + d = tm.tm_mday; + + decode_year(INT2FIX(y), -1, &nth, &ry); + + ret = d_simple_new_internal(klass, + nth, 0, + GREGORIAN, + ry, m, d, + HAVE_CIVIL); + { + get_d1(ret); + set_sg(dat, sg); + } + return ret; +} + +#define set_hash0(k,v) rb_hash_aset(hash, k, v) +#define ref_hash0(k) rb_hash_aref(hash, k) +#define del_hash0(k) rb_hash_delete(hash, k) + +#define sym(x) ID2SYM(rb_intern(x"")) + +#define set_hash(k,v) set_hash0(sym(k), v) +#define ref_hash(k) ref_hash0(sym(k)) +#define del_hash(k) del_hash0(sym(k)) + +static VALUE +rt_rewrite_frags(VALUE hash) +{ + VALUE seconds; + + seconds = del_hash("seconds"); + if (!NIL_P(seconds)) { + VALUE offset, d, h, min, s, fr; + + offset = ref_hash("offset"); + if (!NIL_P(offset)) + seconds = f_add(seconds, offset); + + d = f_idiv(seconds, INT2FIX(DAY_IN_SECONDS)); + fr = f_mod(seconds, INT2FIX(DAY_IN_SECONDS)); + + h = f_idiv(fr, INT2FIX(HOUR_IN_SECONDS)); + fr = f_mod(fr, INT2FIX(HOUR_IN_SECONDS)); + + min = f_idiv(fr, INT2FIX(MINUTE_IN_SECONDS)); + fr = f_mod(fr, INT2FIX(MINUTE_IN_SECONDS)); + + s = f_idiv(fr, INT2FIX(1)); + fr = f_mod(fr, INT2FIX(1)); + + set_hash("jd", f_add(UNIX_EPOCH_IN_CJD, d)); + set_hash("hour", h); + set_hash("min", min); + set_hash("sec", s); + set_hash("sec_fraction", fr); + } + return hash; +} + +static VALUE d_lite_year(VALUE); +static VALUE d_lite_wday(VALUE); +static VALUE d_lite_jd(VALUE); + +static VALUE +rt_complete_frags(VALUE klass, VALUE hash) +{ + static VALUE tab = Qnil; + int g; + long e; + VALUE k, a, d; + + if (NIL_P(tab)) { + tab = f_frozen_ary(11, + f_frozen_ary(2, + sym("time"), + f_frozen_ary(3, + sym("hour"), + sym("min"), + sym("sec"))), + f_frozen_ary(2, + Qnil, + f_frozen_ary(1, + sym("jd"))), + f_frozen_ary(2, + sym("ordinal"), + f_frozen_ary(5, + sym("year"), + sym("yday"), + sym("hour"), + sym("min"), + sym("sec"))), + f_frozen_ary(2, + sym("civil"), + f_frozen_ary(6, + sym("year"), + sym("mon"), + sym("mday"), + sym("hour"), + sym("min"), + sym("sec"))), + f_frozen_ary(2, + sym("commercial"), + f_frozen_ary(6, + sym("cwyear"), + sym("cweek"), + sym("cwday"), + sym("hour"), + sym("min"), + sym("sec"))), + f_frozen_ary(2, + sym("wday"), + f_frozen_ary(4, + sym("wday"), + sym("hour"), + sym("min"), + sym("sec"))), + f_frozen_ary(2, + sym("wnum0"), + f_frozen_ary(6, + sym("year"), + sym("wnum0"), + sym("wday"), + sym("hour"), + sym("min"), + sym("sec"))), + f_frozen_ary(2, + sym("wnum1"), + f_frozen_ary(6, + sym("year"), + sym("wnum1"), + sym("wday"), + sym("hour"), + sym("min"), + sym("sec"))), + f_frozen_ary(2, + Qnil, + f_frozen_ary(6, + sym("cwyear"), + sym("cweek"), + sym("wday"), + sym("hour"), + sym("min"), + sym("sec"))), + f_frozen_ary(2, + Qnil, + f_frozen_ary(6, + sym("year"), + sym("wnum0"), + sym("cwday"), + sym("hour"), + sym("min"), + sym("sec"))), + f_frozen_ary(2, + Qnil, + f_frozen_ary(6, + sym("year"), + sym("wnum1"), + sym("cwday"), + sym("hour"), + sym("min"), + sym("sec")))); + rb_gc_register_mark_object(tab); + } + + { + long i, eno = 0, idx = 0; + + for (i = 0; i < RARRAY_LEN(tab); i++) { + VALUE x, a; + + x = RARRAY_AREF(tab, i); + a = RARRAY_AREF(x, 1); + + { + long j, n = 0; + + for (j = 0; j < RARRAY_LEN(a); j++) + if (!NIL_P(ref_hash0(RARRAY_AREF(a, j)))) + n++; + if (n > eno) { + eno = n; + idx = i; + } + } + } + if (eno == 0) + g = 0; + else { + g = 1; + k = RARRAY_AREF(RARRAY_AREF(tab, idx), 0); + a = RARRAY_AREF(RARRAY_AREF(tab, idx), 1); + e = eno; + } + } + + d = Qnil; + + if (g && !NIL_P(k) && (RARRAY_LEN(a) - e)) { + if (k == sym("ordinal")) { + if (NIL_P(ref_hash("year"))) { + if (NIL_P(d)) + d = date_s_today(0, (VALUE *)0, cDate); + set_hash("year", d_lite_year(d)); + } + if (NIL_P(ref_hash("yday"))) + set_hash("yday", INT2FIX(1)); + } + else if (k == sym("civil")) { + long i; + + for (i = 0; i < RARRAY_LEN(a); i++) { + VALUE e = RARRAY_AREF(a, i); + + if (!NIL_P(ref_hash0(e))) + break; + if (NIL_P(d)) + d = date_s_today(0, (VALUE *)0, cDate); + set_hash0(e, rb_funcall(d, SYM2ID(e), 0)); + } + if (NIL_P(ref_hash("mon"))) + set_hash("mon", INT2FIX(1)); + if (NIL_P(ref_hash("mday"))) + set_hash("mday", INT2FIX(1)); + } + else if (k == sym("commercial")) { + long i; + + for (i = 0; i < RARRAY_LEN(a); i++) { + VALUE e = RARRAY_AREF(a, i); + + if (!NIL_P(ref_hash0(e))) + break; + if (NIL_P(d)) + d = date_s_today(0, (VALUE *)0, cDate); + set_hash0(e, rb_funcall(d, SYM2ID(e), 0)); + } + if (NIL_P(ref_hash("cweek"))) + set_hash("cweek", INT2FIX(1)); + if (NIL_P(ref_hash("cwday"))) + set_hash("cwday", INT2FIX(1)); + } + else if (k == sym("wday")) { + if (NIL_P(d)) + d = date_s_today(0, (VALUE *)0, cDate); + set_hash("jd", d_lite_jd(f_add(f_sub(d, + d_lite_wday(d)), + ref_hash("wday")))); + } + else if (k == sym("wnum0")) { + long i; + + for (i = 0; i < RARRAY_LEN(a); i++) { + VALUE e = RARRAY_AREF(a, i); + + if (!NIL_P(ref_hash0(e))) + break; + if (NIL_P(d)) + d = date_s_today(0, (VALUE *)0, cDate); + set_hash0(e, rb_funcall(d, SYM2ID(e), 0)); + } + if (NIL_P(ref_hash("wnum0"))) + set_hash("wnum0", INT2FIX(0)); + if (NIL_P(ref_hash("wday"))) + set_hash("wday", INT2FIX(0)); + } + else if (k == sym("wnum1")) { + long i; + + for (i = 0; i < RARRAY_LEN(a); i++) { + VALUE e = RARRAY_AREF(a, i); + + if (!NIL_P(ref_hash0(e))) + break; + if (NIL_P(d)) + d = date_s_today(0, (VALUE *)0, cDate); + set_hash0(e, rb_funcall(d, SYM2ID(e), 0)); + } + if (NIL_P(ref_hash("wnum1"))) + set_hash("wnum1", INT2FIX(0)); + if (NIL_P(ref_hash("wday"))) + set_hash("wday", INT2FIX(1)); + } + } + + if (g && k == sym("time")) { + if (f_le_p(klass, cDateTime)) { + if (NIL_P(d)) + d = date_s_today(0, (VALUE *)0, cDate); + if (NIL_P(ref_hash("jd"))) + set_hash("jd", d_lite_jd(d)); + } + } + + if (NIL_P(ref_hash("hour"))) + set_hash("hour", INT2FIX(0)); + if (NIL_P(ref_hash("min"))) + set_hash("min", INT2FIX(0)); + if (NIL_P(ref_hash("sec"))) + set_hash("sec", INT2FIX(0)); + else if (f_gt_p(ref_hash("sec"), INT2FIX(59))) + set_hash("sec", INT2FIX(59)); + + return hash; +} + +static VALUE +rt__valid_jd_p(VALUE jd, VALUE sg) +{ + return jd; +} + +static VALUE +rt__valid_ordinal_p(VALUE y, VALUE d, VALUE sg) +{ + VALUE nth, rjd2; + int ry, rd, rjd, ns; + + if (!valid_ordinal_p(y, NUM2INT(d), NUM2DBL(sg), + &nth, &ry, + &rd, &rjd, + &ns)) + return Qnil; + encode_jd(nth, rjd, &rjd2); + return rjd2; +} + +static VALUE +rt__valid_civil_p(VALUE y, VALUE m, VALUE d, VALUE sg) +{ + VALUE nth, rjd2; + int ry, rm, rd, rjd, ns; + + if (!valid_civil_p(y, NUM2INT(m), NUM2INT(d), NUM2DBL(sg), + &nth, &ry, + &rm, &rd, &rjd, + &ns)) + return Qnil; + encode_jd(nth, rjd, &rjd2); + return rjd2; +} + +static VALUE +rt__valid_commercial_p(VALUE y, VALUE w, VALUE d, VALUE sg) +{ + VALUE nth, rjd2; + int ry, rw, rd, rjd, ns; + + if (!valid_commercial_p(y, NUM2INT(w), NUM2INT(d), NUM2DBL(sg), + &nth, &ry, + &rw, &rd, &rjd, + &ns)) + return Qnil; + encode_jd(nth, rjd, &rjd2); + return rjd2; +} + +static VALUE +rt__valid_weeknum_p(VALUE y, VALUE w, VALUE d, VALUE f, VALUE sg) +{ + VALUE nth, rjd2; + int ry, rw, rd, rjd, ns; + + if (!valid_weeknum_p(y, NUM2INT(w), NUM2INT(d), NUM2INT(f), NUM2DBL(sg), + &nth, &ry, + &rw, &rd, &rjd, + &ns)) + return Qnil; + encode_jd(nth, rjd, &rjd2); + return rjd2; +} + +static VALUE +rt__valid_date_frags_p(VALUE hash, VALUE sg) +{ + { + VALUE vjd; + + if (!NIL_P(vjd = ref_hash("jd"))) { + VALUE jd = rt__valid_jd_p(vjd, sg); + if (!NIL_P(jd)) + return jd; + } + } + + { + VALUE year, yday; + + if (!NIL_P(yday = ref_hash("yday")) && + !NIL_P(year = ref_hash("year"))) { + VALUE jd = rt__valid_ordinal_p(year, yday, sg); + if (!NIL_P(jd)) + return jd; + } + } + + { + VALUE year, mon, mday; + + if (!NIL_P(mday = ref_hash("mday")) && + !NIL_P(mon = ref_hash("mon")) && + !NIL_P(year = ref_hash("year"))) { + VALUE jd = rt__valid_civil_p(year, mon, mday, sg); + if (!NIL_P(jd)) + return jd; + } + } + + { + VALUE year, week, wday; + + wday = ref_hash("cwday"); + if (NIL_P(wday)) { + wday = ref_hash("wday"); + if (!NIL_P(wday)) + if (f_zero_p(wday)) + wday = INT2FIX(7); + } + + if (!NIL_P(wday) && + !NIL_P(week = ref_hash("cweek")) && + !NIL_P(year = ref_hash("cwyear"))) { + VALUE jd = rt__valid_commercial_p(year, week, wday, sg); + if (!NIL_P(jd)) + return jd; + } + } + + { + VALUE year, week, wday; + + wday = ref_hash("wday"); + if (NIL_P(wday)) { + wday = ref_hash("cwday"); + if (!NIL_P(wday)) + if (f_eqeq_p(wday, INT2FIX(7))) + wday = INT2FIX(0); + } + + if (!NIL_P(wday) && + !NIL_P(week = ref_hash("wnum0")) && + !NIL_P(year = ref_hash("year"))) { + VALUE jd = rt__valid_weeknum_p(year, week, wday, INT2FIX(0), sg); + if (!NIL_P(jd)) + return jd; + } + } + + { + VALUE year, week, wday; + + wday = ref_hash("wday"); + if (NIL_P(wday)) + wday = ref_hash("cwday"); + if (!NIL_P(wday)) + wday = f_mod(f_sub(wday, INT2FIX(1)), + INT2FIX(7)); + + if (!NIL_P(wday) && + !NIL_P(week = ref_hash("wnum1")) && + !NIL_P(year = ref_hash("year"))) { + VALUE jd = rt__valid_weeknum_p(year, week, wday, INT2FIX(1), sg); + if (!NIL_P(jd)) + return jd; + } + } + return Qnil; +} + +static VALUE +d_new_by_frags(VALUE klass, VALUE hash, VALUE sg) +{ + VALUE jd; + + if (!c_valid_start_p(NUM2DBL(sg))) { + sg = INT2FIX(DEFAULT_SG); + rb_warning("invalid start is ignored"); + } + + if (NIL_P(hash)) + rb_raise(eDateError, "invalid date"); + + if (NIL_P(ref_hash("jd")) && + NIL_P(ref_hash("yday")) && + !NIL_P(ref_hash("year")) && + !NIL_P(ref_hash("mon")) && + !NIL_P(ref_hash("mday"))) + jd = rt__valid_civil_p(ref_hash("year"), + ref_hash("mon"), + ref_hash("mday"), sg); + else { + hash = rt_rewrite_frags(hash); + hash = rt_complete_frags(klass, hash); + jd = rt__valid_date_frags_p(hash, sg); + } + + if (NIL_P(jd)) + rb_raise(eDateError, "invalid date"); + { + VALUE nth; + int rjd; + + decode_jd(jd, &nth, &rjd); + return d_simple_new_internal(klass, + nth, rjd, + NUM2DBL(sg), + 0, 0, 0, + HAVE_JD); + } +} + +VALUE date__strptime(const char *str, size_t slen, + const char *fmt, size_t flen, VALUE hash); + +static VALUE +date_s__strptime_internal(int argc, VALUE *argv, VALUE klass, + const char *default_fmt) +{ + VALUE vstr, vfmt, hash; + const char *str, *fmt; + size_t slen, flen; + + rb_scan_args(argc, argv, "11", &vstr, &vfmt); + + StringValue(vstr); + if (!rb_enc_str_asciicompat_p(vstr)) + rb_raise(rb_eArgError, + "string should have ASCII compatible encoding"); + str = RSTRING_PTR(vstr); + slen = RSTRING_LEN(vstr); + if (argc < 2) { + fmt = default_fmt; + flen = strlen(default_fmt); + } + else { + StringValue(vfmt); + if (!rb_enc_str_asciicompat_p(vfmt)) + rb_raise(rb_eArgError, + "format should have ASCII compatible encoding"); + fmt = RSTRING_PTR(vfmt); + flen = RSTRING_LEN(vfmt); + } + hash = rb_hash_new(); + if (NIL_P(date__strptime(str, slen, fmt, flen, hash))) + return Qnil; + + { + VALUE zone = ref_hash("zone"); + VALUE left = ref_hash("leftover"); + + if (!NIL_P(zone)) { + rb_enc_copy(zone, vstr); + set_hash("zone", zone); + } + if (!NIL_P(left)) { + rb_enc_copy(left, vstr); + set_hash("leftover", left); + } + } + + return hash; +} + +/* + * call-seq: + * Date._strptime(string, format = '%F') -> hash + * + * Returns a hash of values parsed from +string+ + * according to the given +format+: + * + * Date._strptime('2001-02-03', '%Y-%m-%d') # => {:year=>2001, :mon=>2, :mday=>3} + * + * For other formats, see + * {Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html]. + * (Unlike Date.strftime, does not support flags and width.) + * + * See also {strptime(3)}[https://man7.org/linux/man-pages/man3/strptime.3.html]. + * + * Related: Date.strptime (returns a \Date object). + */ +static VALUE +date_s__strptime(int argc, VALUE *argv, VALUE klass) +{ + return date_s__strptime_internal(argc, argv, klass, "%F"); +} + +/* + * call-seq: + * Date.strptime(string = '-4712-01-01', format = '%F', start = Date::ITALY) -> date + * + * Returns a new \Date object with values parsed from +string+, + * according to the given +format+: + * + * Date.strptime('2001-02-03', '%Y-%m-%d') # => # + * Date.strptime('03-02-2001', '%d-%m-%Y') # => # + * Date.strptime('2001-034', '%Y-%j') # => # + * Date.strptime('2001-W05-6', '%G-W%V-%u') # => # + * Date.strptime('2001 04 6', '%Y %U %w') # => # + * Date.strptime('2001 05 6', '%Y %W %u') # => # + * Date.strptime('sat3feb01', '%a%d%b%y') # => # + * + * For other formats, see + * {Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html]. + * (Unlike Date.strftime, does not support flags and width.) + * + * See argument {start}[rdoc-ref:calendars.rdoc@Argument+start]. + * + * See also {strptime(3)}[https://man7.org/linux/man-pages/man3/strptime.3.html]. + * + * Related: Date._strptime (returns a hash). + */ +static VALUE +date_s_strptime(int argc, VALUE *argv, VALUE klass) +{ + VALUE str, fmt, sg; + + rb_scan_args(argc, argv, "03", &str, &fmt, &sg); + + switch (argc) { + case 0: + str = rb_str_new2(JULIAN_EPOCH_DATE); + case 1: + fmt = rb_str_new2("%F"); + case 2: + sg = INT2FIX(DEFAULT_SG); + } + + { + VALUE argv2[2], hash; + + argv2[0] = str; + argv2[1] = fmt; + hash = date_s__strptime(2, argv2, klass); + return d_new_by_frags(klass, hash, sg); + } +} + +VALUE date__parse(VALUE str, VALUE comp); + +static size_t +get_limit(VALUE opt) +{ + if (!NIL_P(opt)) { + VALUE limit = rb_hash_aref(opt, ID2SYM(rb_intern("limit"))); + if (NIL_P(limit)) return SIZE_MAX; + return NUM2SIZET(limit); + } + return 128; +} + +#ifndef HAVE_RB_CATEGORY_WARN +#define rb_category_warn(category, fmt) rb_warn(fmt) +#endif + +static void +check_limit(VALUE str, VALUE opt) +{ + size_t slen, limit; + if (NIL_P(str)) return; + StringValue(str); + slen = RSTRING_LEN(str); + limit = get_limit(opt); + if (slen > limit) { + rb_raise(rb_eArgError, + "string length (%"PRI_SIZE_PREFIX"u) exceeds the limit %"PRI_SIZE_PREFIX"u", slen, limit); + } +} + +static VALUE +date_s__parse_internal(int argc, VALUE *argv, VALUE klass) +{ + VALUE vstr, vcomp, hash, opt; + + argc = rb_scan_args(argc, argv, "11:", &vstr, &vcomp, &opt); + check_limit(vstr, opt); + StringValue(vstr); + if (!rb_enc_str_asciicompat_p(vstr)) + rb_raise(rb_eArgError, + "string should have ASCII compatible encoding"); + if (argc < 2) + vcomp = Qtrue; + + hash = date__parse(vstr, vcomp); + + return hash; +} + +/* + * call-seq: + * Date._parse(string, comp = true, limit: 128) -> hash + * + * Note: + * This method recognizes many forms in +string+, + * but it is not a validator. + * For formats, see + * {"Specialized Format Strings" in Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-Specialized+Format+Strings] + * + * If +string+ does not specify a valid date, + * the result is unpredictable; + * consider using Date._strptime instead. + * + * Returns a hash of values parsed from +string+: + * + * Date._parse('2001-02-03') # => {:year=>2001, :mon=>2, :mday=>3} + * + * If +comp+ is +true+ and the given year is in the range (0..99), + * the current century is supplied; + * otherwise, the year is taken as given: + * + * Date._parse('01-02-03', true) # => {:year=>2001, :mon=>2, :mday=>3} + * Date._parse('01-02-03', false) # => {:year=>1, :mon=>2, :mday=>3} + * + * See argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date.parse(returns a \Date object). + */ +static VALUE +date_s__parse(int argc, VALUE *argv, VALUE klass) +{ + return date_s__parse_internal(argc, argv, klass); +} + +/* + * call-seq: + * Date.parse(string = '-4712-01-01', comp = true, start = Date::ITALY, limit: 128) -> date + * + * Note: + * This method recognizes many forms in +string+, + * but it is not a validator. + * For formats, see + * {"Specialized Format Strings" in Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-Specialized+Format+Strings] + * If +string+ does not specify a valid date, + * the result is unpredictable; + * consider using Date._strptime instead. + * + * Returns a new \Date object with values parsed from +string+: + * + * Date.parse('2001-02-03') # => # + * Date.parse('20010203') # => # + * Date.parse('3rd Feb 2001') # => # + * + * If +comp+ is +true+ and the given year is in the range (0..99), + * the current century is supplied; + * otherwise, the year is taken as given: + * + * Date.parse('01-02-03', true) # => # + * Date.parse('01-02-03', false) # => # + * + * See: + * + * - Argument {start}[rdoc-ref:calendars.rdoc@Argument+start]. + * - Argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date._parse (returns a hash). + */ +static VALUE +date_s_parse(int argc, VALUE *argv, VALUE klass) +{ + VALUE str, comp, sg, opt; + + argc = rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt); + + switch (argc) { + case 0: + str = rb_str_new2(JULIAN_EPOCH_DATE); + case 1: + comp = Qtrue; + case 2: + sg = INT2FIX(DEFAULT_SG); + } + + { + int argc2 = 2; + VALUE argv2[3], hash; + argv2[0] = str; + argv2[1] = comp; + if (!NIL_P(opt)) argv2[argc2++] = opt; + hash = date_s__parse(argc2, argv2, klass); + return d_new_by_frags(klass, hash, sg); + } +} + +VALUE date__iso8601(VALUE); +VALUE date__rfc3339(VALUE); +VALUE date__xmlschema(VALUE); +VALUE date__rfc2822(VALUE); +VALUE date__httpdate(VALUE); +VALUE date__jisx0301(VALUE); + +/* + * call-seq: + * Date._iso8601(string, limit: 128) -> hash + * + * Returns a hash of values parsed from +string+, which should contain + * an {ISO 8601 formatted date}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-ISO+8601+Format+Specifications]: + * + * d = Date.new(2001, 2, 3) + * s = d.iso8601 # => "2001-02-03" + * Date._iso8601(s) # => {:mday=>3, :year=>2001, :mon=>2} + * + * See argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date.iso8601 (returns a \Date object). + */ +static VALUE +date_s__iso8601(int argc, VALUE *argv, VALUE klass) +{ + VALUE str, opt; + + rb_scan_args(argc, argv, "1:", &str, &opt); + check_limit(str, opt); + + return date__iso8601(str); +} + +/* + * call-seq: + * Date.iso8601(string = '-4712-01-01', start = Date::ITALY, limit: 128) -> date + * + * Returns a new \Date object with values parsed from +string+, + * which should contain + * an {ISO 8601 formatted date}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-ISO+8601+Format+Specifications]: + * + * d = Date.new(2001, 2, 3) + * s = d.iso8601 # => "2001-02-03" + * Date.iso8601(s) # => # + * + * See: + * + * - Argument {start}[rdoc-ref:calendars.rdoc@Argument+start]. + * - Argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date._iso8601 (returns a hash). + */ +static VALUE +date_s_iso8601(int argc, VALUE *argv, VALUE klass) +{ + VALUE str, sg, opt; + + argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt); + + switch (argc) { + case 0: + str = rb_str_new2(JULIAN_EPOCH_DATE); + case 1: + sg = INT2FIX(DEFAULT_SG); + } + + { + int argc2 = 1; + VALUE argv2[2], hash; + argv2[0] = str; + if (!NIL_P(opt)) argv2[argc2++] = opt; + hash = date_s__iso8601(argc2, argv2, klass); + return d_new_by_frags(klass, hash, sg); + } +} + +/* + * call-seq: + * Date._rfc3339(string, limit: 128) -> hash + * + * Returns a hash of values parsed from +string+, which should be a valid + * {RFC 3339 format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-RFC+3339+Format]: + * + * d = Date.new(2001, 2, 3) + * s = d.rfc3339 # => "2001-02-03T00:00:00+00:00" + * Date._rfc3339(s) + * # => {:year=>2001, :mon=>2, :mday=>3, :hour=>0, :min=>0, :sec=>0, :zone=>"+00:00", :offset=>0} + * + * See argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date.rfc3339 (returns a \Date object). + */ +static VALUE +date_s__rfc3339(int argc, VALUE *argv, VALUE klass) +{ + VALUE str, opt; + + rb_scan_args(argc, argv, "1:", &str, &opt); + check_limit(str, opt); + + return date__rfc3339(str); +} + +/* + * call-seq: + * Date.rfc3339(string = '-4712-01-01T00:00:00+00:00', start = Date::ITALY, limit: 128) -> date + * + * Returns a new \Date object with values parsed from +string+, + * which should be a valid + * {RFC 3339 format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-RFC+3339+Format]: + * + * d = Date.new(2001, 2, 3) + * s = d.rfc3339 # => "2001-02-03T00:00:00+00:00" + * Date.rfc3339(s) # => # + * + * See: + * + * - Argument {start}[rdoc-ref:calendars.rdoc@Argument+start]. + * - Argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date._rfc3339 (returns a hash). + */ +static VALUE +date_s_rfc3339(int argc, VALUE *argv, VALUE klass) +{ + VALUE str, sg, opt; + + argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt); + + switch (argc) { + case 0: + str = rb_str_new2(JULIAN_EPOCH_DATETIME); + case 1: + sg = INT2FIX(DEFAULT_SG); + } + + { + int argc2 = 1; + VALUE argv2[2], hash; + argv2[0] = str; + if (!NIL_P(opt)) argv2[argc2++] = opt; + hash = date_s__rfc3339(argc2, argv2, klass); + return d_new_by_frags(klass, hash, sg); + } +} + +/* + * call-seq: + * Date._xmlschema(string, limit: 128) -> hash + * + * Returns a hash of values parsed from +string+, which should be a valid + * XML date format: + * + * d = Date.new(2001, 2, 3) + * s = d.xmlschema # => "2001-02-03" + * Date._xmlschema(s) # => {:year=>2001, :mon=>2, :mday=>3} + * + * See argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date.xmlschema (returns a \Date object). + */ +static VALUE +date_s__xmlschema(int argc, VALUE *argv, VALUE klass) +{ + VALUE str, opt; + + rb_scan_args(argc, argv, "1:", &str, &opt); + check_limit(str, opt); + + return date__xmlschema(str); +} + +/* + * call-seq: + * Date.xmlschema(string = '-4712-01-01', start = Date::ITALY, limit: 128) -> date + * + * Returns a new \Date object with values parsed from +string+, + * which should be a valid XML date format: + * + * d = Date.new(2001, 2, 3) + * s = d.xmlschema # => "2001-02-03" + * Date.xmlschema(s) # => # + * + * See: + * + * - Argument {start}[rdoc-ref:calendars.rdoc@Argument+start]. + * - Argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date._xmlschema (returns a hash). + */ +static VALUE +date_s_xmlschema(int argc, VALUE *argv, VALUE klass) +{ + VALUE str, sg, opt; + + argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt); + + switch (argc) { + case 0: + str = rb_str_new2(JULIAN_EPOCH_DATE); + case 1: + sg = INT2FIX(DEFAULT_SG); + } + + { + int argc2 = 1; + VALUE argv2[2], hash; + argv2[0] = str; + if (!NIL_P(opt)) argv2[argc2++] = opt; + hash = date_s__xmlschema(argc2, argv2, klass); + return d_new_by_frags(klass, hash, sg); + } +} + +/* + * call-seq: + * Date._rfc2822(string, limit: 128) -> hash + * + * Returns a hash of values parsed from +string+, which should be a valid + * {RFC 2822 date format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-RFC+2822+Format]: + * + * d = Date.new(2001, 2, 3) + * s = d.rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000" + * Date._rfc2822(s) + * # => {:wday=>6, :mday=>3, :mon=>2, :year=>2001, :hour=>0, :min=>0, :sec=>0, :zone=>"+0000", :offset=>0} + * + * See argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date.rfc2822 (returns a \Date object). + */ +static VALUE +date_s__rfc2822(int argc, VALUE *argv, VALUE klass) +{ + VALUE str, opt; + + rb_scan_args(argc, argv, "1:", &str, &opt); + check_limit(str, opt); + + return date__rfc2822(str); +} + +/* + * call-seq: + * Date.rfc2822(string = 'Mon, 1 Jan -4712 00:00:00 +0000', start = Date::ITALY, limit: 128) -> date + * + * Returns a new \Date object with values parsed from +string+, + * which should be a valid + * {RFC 2822 date format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-RFC+2822+Format]: + * + * d = Date.new(2001, 2, 3) + * s = d.rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000" + * Date.rfc2822(s) # => # + * + * See: + * + * - Argument {start}[rdoc-ref:calendars.rdoc@Argument+start]. + * - Argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date._rfc2822 (returns a hash). + */ +static VALUE +date_s_rfc2822(int argc, VALUE *argv, VALUE klass) +{ + VALUE str, sg, opt; + + argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt); + + switch (argc) { + case 0: + str = rb_str_new2(JULIAN_EPOCH_DATETIME_RFC3339); + case 1: + sg = INT2FIX(DEFAULT_SG); + } + + { + int argc2 = 1; + VALUE argv2[2], hash; + argv2[0] = str; + if (!NIL_P(opt)) argv2[argc2++] = opt; + hash = date_s__rfc2822(argc2, argv2, klass); + return d_new_by_frags(klass, hash, sg); + } +} + +/* + * call-seq: + * Date._httpdate(string, limit: 128) -> hash + * + * Returns a hash of values parsed from +string+, which should be a valid + * {HTTP date format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-HTTP+Format]: + * + * d = Date.new(2001, 2, 3) + * s = d.httpdate # => "Sat, 03 Feb 2001 00:00:00 GMT" + * Date._httpdate(s) + * # => {:wday=>6, :mday=>3, :mon=>2, :year=>2001, :hour=>0, :min=>0, :sec=>0, :zone=>"GMT", :offset=>0} + * + * Related: Date.httpdate (returns a \Date object). + */ +static VALUE +date_s__httpdate(int argc, VALUE *argv, VALUE klass) +{ + VALUE str, opt; + + rb_scan_args(argc, argv, "1:", &str, &opt); + check_limit(str, opt); + + return date__httpdate(str); +} + +/* + * call-seq: + * Date.httpdate(string = 'Mon, 01 Jan -4712 00:00:00 GMT', start = Date::ITALY, limit: 128) -> date + * + * Returns a new \Date object with values parsed from +string+, + * which should be a valid + * {HTTP date format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-HTTP+Format]: + * + * d = Date.new(2001, 2, 3) + s = d.httpdate # => "Sat, 03 Feb 2001 00:00:00 GMT" + Date.httpdate(s) # => # + * + * See: + * + * - Argument {start}[rdoc-ref:calendars.rdoc@Argument+start]. + * - Argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date._httpdate (returns a hash). + */ +static VALUE +date_s_httpdate(int argc, VALUE *argv, VALUE klass) +{ + VALUE str, sg, opt; + + argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt); + + switch (argc) { + case 0: + str = rb_str_new2(JULIAN_EPOCH_DATETIME_HTTPDATE); + case 1: + sg = INT2FIX(DEFAULT_SG); + } + + { + int argc2 = 1; + VALUE argv2[2], hash; + argv2[0] = str; + if (!NIL_P(opt)) argv2[argc2++] = opt; + hash = date_s__httpdate(argc2, argv2, klass); + return d_new_by_frags(klass, hash, sg); + } +} + +/* + * call-seq: + * Date._jisx0301(string, limit: 128) -> hash + * + * Returns a hash of values parsed from +string+, which should be a valid + * {JIS X 0301 date format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-JIS+X+0301+Format]: + * + * d = Date.new(2001, 2, 3) + * s = d.jisx0301 # => "H13.02.03" + * Date._jisx0301(s) # => {:year=>2001, :mon=>2, :mday=>3} + * + * See argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date.jisx0301 (returns a \Date object). + */ +static VALUE +date_s__jisx0301(int argc, VALUE *argv, VALUE klass) +{ + VALUE str, opt; + + rb_scan_args(argc, argv, "1:", &str, &opt); + check_limit(str, opt); + + return date__jisx0301(str); +} + +/* + * call-seq: + * Date.jisx0301(string = '-4712-01-01', start = Date::ITALY, limit: 128) -> date + * + * Returns a new \Date object with values parsed from +string+, + * which should be a valid {JIS X 0301 format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-JIS+X+0301+Format]: + * + * d = Date.new(2001, 2, 3) + * s = d.jisx0301 # => "H13.02.03" + * Date.jisx0301(s) # => # + * + * For no-era year, legacy format, Heisei is assumed. + * + * Date.jisx0301('13.02.03') # => # + * + * See: + * + * - Argument {start}[rdoc-ref:calendars.rdoc@Argument+start]. + * - Argument {limit}[rdoc-ref:Date@Argument+limit]. + * + * Related: Date._jisx0301 (returns a hash). + */ +static VALUE +date_s_jisx0301(int argc, VALUE *argv, VALUE klass) +{ + VALUE str, sg, opt; + + argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt); + + switch (argc) { + case 0: + str = rb_str_new2(JULIAN_EPOCH_DATE); + case 1: + sg = INT2FIX(DEFAULT_SG); + } + + { + int argc2 = 1; + VALUE argv2[2], hash; + argv2[0] = str; + if (!NIL_P(opt)) argv2[argc2++] = opt; + hash = date_s__jisx0301(argc2, argv2, klass); + return d_new_by_frags(klass, hash, sg); + } +} + +static VALUE +dup_obj(VALUE self) +{ + get_d1a(self); + + if (simple_dat_p(adat)) { + VALUE new = d_lite_s_alloc_simple(rb_obj_class(self)); + { + get_d1b(new); + bdat->s = adat->s; + RB_OBJ_WRITTEN(new, Qundef, bdat->s.nth); + return new; + } + } + else { + VALUE new = d_lite_s_alloc_complex(rb_obj_class(self)); + { + get_d1b(new); + bdat->c = adat->c; + RB_OBJ_WRITTEN(new, Qundef, bdat->c.nth); + RB_OBJ_WRITTEN(new, Qundef, bdat->c.sf); + return new; + } + } +} + +static VALUE +dup_obj_as_complex(VALUE self) +{ + get_d1a(self); + + if (simple_dat_p(adat)) { + VALUE new = d_lite_s_alloc_complex(rb_obj_class(self)); + { + get_d1b(new); + copy_simple_to_complex(new, &bdat->c, &adat->s); + bdat->c.flags |= HAVE_DF | COMPLEX_DAT; + return new; + } + } + else { + VALUE new = d_lite_s_alloc_complex(rb_obj_class(self)); + { + get_d1b(new); + bdat->c = adat->c; + RB_OBJ_WRITTEN(new, Qundef, bdat->c.nth); + RB_OBJ_WRITTEN(new, Qundef, bdat->c.sf); + return new; + } + } +} + +#define val2off(vof,iof) \ +do {\ + if (!offset_to_sec(vof, &iof)) {\ + iof = 0;\ + rb_warning("invalid offset is ignored");\ + }\ +} while (0) + +#if 0 +static VALUE +d_lite_initialize(int argc, VALUE *argv, VALUE self) +{ + VALUE jd, vjd, vdf, sf, vsf, vof, vsg; + int df, of; + double sg; + + rb_check_frozen(self); + + rb_scan_args(argc, argv, "05", &vjd, &vdf, &vsf, &vof, &vsg); + + jd = INT2FIX(0); + df = 0; + sf = INT2FIX(0); + of = 0; + sg = DEFAULT_SG; + + switch (argc) { + case 5: + val2sg(vsg, sg); + case 4: + val2off(vof, of); + case 3: + sf = vsf; + if (f_lt_p(sf, INT2FIX(0)) || + f_ge_p(sf, INT2FIX(SECOND_IN_NANOSECONDS))) + rb_raise(eDateError, "invalid second fraction"); + case 2: + df = NUM2INT(vdf); + if (df < 0 || df >= DAY_IN_SECONDS) + rb_raise(eDateError, "invalid day fraction"); + case 1: + jd = vjd; + } + + { + VALUE nth; + int rjd; + + get_d1(self); + + decode_jd(jd, &nth, &rjd); + if (!df && f_zero_p(sf) && !of) { + set_to_simple(self, &dat->s, nth, rjd, sg, 0, 0, 0, HAVE_JD); + } + else { + if (!complex_dat_p(dat)) + rb_raise(rb_eArgError, + "cannot load complex into simple"); + + set_to_complex(self, &dat->c, nth, rjd, df, sf, of, sg, + 0, 0, 0, 0, 0, 0, HAVE_JD | HAVE_DF); + } + } + return self; +} +#endif + +/* :nodoc: */ +static VALUE +d_lite_initialize_copy(VALUE copy, VALUE date) +{ + rb_check_frozen(copy); + + if (copy == date) + return copy; + { + get_d2(copy, date); + if (simple_dat_p(bdat)) { + if (simple_dat_p(adat)) { + adat->s = bdat->s; + } + else { + adat->c.flags = bdat->s.flags | COMPLEX_DAT; + adat->c.nth = bdat->s.nth; + adat->c.jd = bdat->s.jd; + adat->c.df = 0; + adat->c.sf = INT2FIX(0); + adat->c.of = 0; + adat->c.sg = bdat->s.sg; + adat->c.year = bdat->s.year; +#ifndef USE_PACK + adat->c.mon = bdat->s.mon; + adat->c.mday = bdat->s.mday; + adat->c.hour = bdat->s.hour; + adat->c.min = bdat->s.min; + adat->c.sec = bdat->s.sec; +#else + adat->c.pc = bdat->s.pc; +#endif + } + } + else { + if (!complex_dat_p(adat)) + rb_raise(rb_eArgError, + "cannot load complex into simple"); + + adat->c = bdat->c; + } + } + return copy; +} + +#ifndef NDEBUG +/* :nodoc: */ +static VALUE +d_lite_fill(VALUE self) +{ + get_d1(self); + + if (simple_dat_p(dat)) { + get_s_jd(dat); + get_s_civil(dat); + } + else { + get_c_jd(dat); + get_c_civil(dat); + get_c_df(dat); + get_c_time(dat); + } + return self; +} +#endif + +/* + * call-seq: + * d.ajd -> rational + * + * Returns the astronomical Julian day number. This is a fractional + * number, which is not adjusted by the offset. + * + * DateTime.new(2001,2,3,4,5,6,'+7').ajd #=> (11769328217/4800) + * DateTime.new(2001,2,2,14,5,6,'-7').ajd #=> (11769328217/4800) + */ +static VALUE +d_lite_ajd(VALUE self) +{ + get_d1(self); + return m_ajd(dat); +} + +/* + * call-seq: + * d.amjd -> rational + * + * Returns the astronomical modified Julian day number. This is + * a fractional number, which is not adjusted by the offset. + * + * DateTime.new(2001,2,3,4,5,6,'+7').amjd #=> (249325817/4800) + * DateTime.new(2001,2,2,14,5,6,'-7').amjd #=> (249325817/4800) + */ +static VALUE +d_lite_amjd(VALUE self) +{ + get_d1(self); + return m_amjd(dat); +} + +/* + * call-seq: + * d.jd -> integer + * + * Returns the Julian day number. This is a whole number, which is + * adjusted by the offset as the local time. + * + * DateTime.new(2001,2,3,4,5,6,'+7').jd #=> 2451944 + * DateTime.new(2001,2,3,4,5,6,'-7').jd #=> 2451944 + */ +static VALUE +d_lite_jd(VALUE self) +{ + get_d1(self); + return m_real_local_jd(dat); +} + +/* + * call-seq: + * d.mjd -> integer + * + * Returns the modified Julian day number. This is a whole number, + * which is adjusted by the offset as the local time. + * + * DateTime.new(2001,2,3,4,5,6,'+7').mjd #=> 51943 + * DateTime.new(2001,2,3,4,5,6,'-7').mjd #=> 51943 + */ +static VALUE +d_lite_mjd(VALUE self) +{ + get_d1(self); + return f_sub(m_real_local_jd(dat), INT2FIX(2400001)); +} + +/* + * call-seq: + * ld -> integer + * + * Returns the + * {Lilian day number}[https://en.wikipedia.org/wiki/Lilian_date], + * which is the number of days since the beginning of the Gregorian + * calendar, October 15, 1582. + * + * Date.new(2001, 2, 3).ld # => 152784 + * + */ +static VALUE +d_lite_ld(VALUE self) +{ + get_d1(self); + return f_sub(m_real_local_jd(dat), INT2FIX(2299160)); +} + +/* + * call-seq: + * year -> integer + * + * Returns the year: + * + * Date.new(2001, 2, 3).year # => 2001 + * (Date.new(1, 1, 1) - 1).year # => 0 + * + */ +static VALUE +d_lite_year(VALUE self) +{ + get_d1(self); + return m_real_year(dat); +} + +/* + * call-seq: + * yday -> integer + * + * Returns the day of the year, in range (1..366): + * + * Date.new(2001, 2, 3).yday # => 34 + * + */ +static VALUE +d_lite_yday(VALUE self) +{ + get_d1(self); + return INT2FIX(m_yday(dat)); +} + +/* + * call-seq: + * mon -> integer + * + * Returns the month in range (1..12): + * + * Date.new(2001, 2, 3).mon # => 2 + * + */ +static VALUE +d_lite_mon(VALUE self) +{ + get_d1(self); + return INT2FIX(m_mon(dat)); +} + +/* + * call-seq: + * mday -> integer + * + * Returns the day of the month in range (1..31): + * + * Date.new(2001, 2, 3).mday # => 3 + * + */ +static VALUE +d_lite_mday(VALUE self) +{ + get_d1(self); + return INT2FIX(m_mday(dat)); +} + +/* + * call-seq: + * day_fraction -> rational + * + * Returns the fractional part of the day in range (Rational(0, 1)...Rational(1, 1)): + * + * DateTime.new(2001,2,3,12).day_fraction # => (1/2) + * + */ +static VALUE +d_lite_day_fraction(VALUE self) +{ + get_d1(self); + if (simple_dat_p(dat)) + return INT2FIX(0); + return m_fr(dat); +} + +/* + * call-seq: + * cwyear -> integer + * + * Returns commercial-date year for +self+ + * (see Date.commercial): + * + * Date.new(2001, 2, 3).cwyear # => 2001 + * Date.new(2000, 1, 1).cwyear # => 1999 + * + */ +static VALUE +d_lite_cwyear(VALUE self) +{ + get_d1(self); + return m_real_cwyear(dat); +} + +/* + * call-seq: + * cweek -> integer + * + * Returns commercial-date week index for +self+ + * (see Date.commercial): + * + * Date.new(2001, 2, 3).cweek # => 5 + * + */ +static VALUE +d_lite_cweek(VALUE self) +{ + get_d1(self); + return INT2FIX(m_cweek(dat)); +} + +/* + * call-seq: + * cwday -> integer + * + * Returns the commercial-date weekday index for +self+ + * (see Date.commercial); + * 1 is Monday: + * + * Date.new(2001, 2, 3).cwday # => 6 + * + */ +static VALUE +d_lite_cwday(VALUE self) +{ + get_d1(self); + return INT2FIX(m_cwday(dat)); +} + +#ifndef NDEBUG +/* :nodoc: */ +static VALUE +d_lite_wnum0(VALUE self) +{ + get_d1(self); + return INT2FIX(m_wnum0(dat)); +} + +/* :nodoc: */ +static VALUE +d_lite_wnum1(VALUE self) +{ + get_d1(self); + return INT2FIX(m_wnum1(dat)); +} +#endif + +/* + * call-seq: + * wday -> integer + * + * Returns the day of week in range (0..6); Sunday is 0: + * + * Date.new(2001, 2, 3).wday # => 6 + * + */ +static VALUE +d_lite_wday(VALUE self) +{ + get_d1(self); + return INT2FIX(m_wday(dat)); +} + +/* + * call-seq: + * sunday? -> true or false + * + * Returns +true+ if +self+ is a Sunday, +false+ otherwise. + */ +static VALUE +d_lite_sunday_p(VALUE self) +{ + get_d1(self); + return f_boolcast(m_wday(dat) == 0); +} + +/* + * call-seq: + * monday? -> true or false + * + * Returns +true+ if +self+ is a Monday, +false+ otherwise. + */ +static VALUE +d_lite_monday_p(VALUE self) +{ + get_d1(self); + return f_boolcast(m_wday(dat) == 1); +} + +/* + * call-seq: + * tuesday? -> true or false + * + * Returns +true+ if +self+ is a Tuesday, +false+ otherwise. + */ +static VALUE +d_lite_tuesday_p(VALUE self) +{ + get_d1(self); + return f_boolcast(m_wday(dat) == 2); +} + +/* + * call-seq: + * wednesday? -> true or false + * + * Returns +true+ if +self+ is a Wednesday, +false+ otherwise. + */ +static VALUE +d_lite_wednesday_p(VALUE self) +{ + get_d1(self); + return f_boolcast(m_wday(dat) == 3); +} + +/* + * call-seq: + * thursday? -> true or false + * + * Returns +true+ if +self+ is a Thursday, +false+ otherwise. + */ +static VALUE +d_lite_thursday_p(VALUE self) +{ + get_d1(self); + return f_boolcast(m_wday(dat) == 4); +} + +/* + * call-seq: + * friday? -> true or false + * + * Returns +true+ if +self+ is a Friday, +false+ otherwise. + */ +static VALUE +d_lite_friday_p(VALUE self) +{ + get_d1(self); + return f_boolcast(m_wday(dat) == 5); +} + +/* + * call-seq: + * saturday? -> true or false + * + * Returns +true+ if +self+ is a Saturday, +false+ otherwise. + */ +static VALUE +d_lite_saturday_p(VALUE self) +{ + get_d1(self); + return f_boolcast(m_wday(dat) == 6); +} + +#ifndef NDEBUG +/* :nodoc: */ +static VALUE +d_lite_nth_kday_p(VALUE self, VALUE n, VALUE k) +{ + int rjd, ns; + + get_d1(self); + + if (NUM2INT(k) != m_wday(dat)) + return Qfalse; + + c_nth_kday_to_jd(m_year(dat), m_mon(dat), + NUM2INT(n), NUM2INT(k), m_virtual_sg(dat), /* !=m_sg() */ + &rjd, &ns); + if (m_local_jd(dat) != rjd) + return Qfalse; + return Qtrue; +} +#endif + +/* + * call-seq: + * hour -> integer + * + * Returns the hour in range (0..23): + * + * DateTime.new(2001, 2, 3, 4, 5, 6).hour # => 4 + * + */ +static VALUE +d_lite_hour(VALUE self) +{ + get_d1(self); + return INT2FIX(m_hour(dat)); +} + +/* + * call-seq: + * min -> integer + * + * Returns the minute in range (0..59): + * + * DateTime.new(2001, 2, 3, 4, 5, 6).min # => 5 + * + */ +static VALUE +d_lite_min(VALUE self) +{ + get_d1(self); + return INT2FIX(m_min(dat)); +} + +/* + * call-seq: + * sec -> integer + * + * Returns the second in range (0..59): + * + * DateTime.new(2001, 2, 3, 4, 5, 6).sec # => 6 + * + */ +static VALUE +d_lite_sec(VALUE self) +{ + get_d1(self); + return INT2FIX(m_sec(dat)); +} + +/* + * call-seq: + * sec_fraction -> rational + * + * Returns the fractional part of the second in range + * (Rational(0, 1)...Rational(1, 1)): + * + * DateTime.new(2001, 2, 3, 4, 5, 6.5).sec_fraction # => (1/2) + * + */ +static VALUE +d_lite_sec_fraction(VALUE self) +{ + get_d1(self); + return m_sf_in_sec(dat); +} + +/* + * call-seq: + * d.offset -> rational + * + * Returns the offset. + * + * DateTime.parse('04pm+0730').offset #=> (5/16) + */ +static VALUE +d_lite_offset(VALUE self) +{ + get_d1(self); + return m_of_in_day(dat); +} + +/* + * call-seq: + * d.zone -> string + * + * Returns the timezone. + * + * DateTime.parse('04pm+0730').zone #=> "+07:30" + */ +static VALUE +d_lite_zone(VALUE self) +{ + get_d1(self); + return m_zone(dat); +} + +/* + * call-seq: + * d.julian? -> true or false + * + * Returns +true+ if the date is before the date of calendar reform, + * +false+ otherwise: + * + * (Date.new(1582, 10, 15) - 1).julian? # => true + * Date.new(1582, 10, 15).julian? # => false + * + */ +static VALUE +d_lite_julian_p(VALUE self) +{ + get_d1(self); + return f_boolcast(m_julian_p(dat)); +} + +/* + * call-seq: + * gregorian? -> true or false + * + * Returns +true+ if the date is on or after + * the date of calendar reform, +false+ otherwise: + * + * Date.new(1582, 10, 15).gregorian? # => true + * (Date.new(1582, 10, 15) - 1).gregorian? # => false + * + */ +static VALUE +d_lite_gregorian_p(VALUE self) +{ + get_d1(self); + return f_boolcast(m_gregorian_p(dat)); +} + +/* + * call-seq: + * leap? -> true or false + * + * Returns +true+ if the year is a leap year, +false+ otherwise: + * + * Date.new(2000).leap? # => true + * Date.new(2001).leap? # => false + * + */ +static VALUE +d_lite_leap_p(VALUE self) +{ + int rjd, ns, ry, rm, rd; + + get_d1(self); + if (m_gregorian_p(dat)) + return f_boolcast(c_gregorian_leap_p(m_year(dat))); + + c_civil_to_jd(m_year(dat), 3, 1, m_virtual_sg(dat), + &rjd, &ns); + c_jd_to_civil(rjd - 1, m_virtual_sg(dat), &ry, &rm, &rd); + return f_boolcast(rd == 29); +} + +/* + * call-seq: + * start -> float + * + * Returns the Julian start date for calendar reform; + * if not an infinity, the returned value is suitable + * for passing to Date#jd: + * + * d = Date.new(2001, 2, 3, Date::ITALY) + * s = d.start # => 2299161.0 + * Date.jd(s).to_s # => "1582-10-15" + * + * d = Date.new(2001, 2, 3, Date::ENGLAND) + * s = d.start # => 2361222.0 + * Date.jd(s).to_s # => "1752-09-14" + * + * Date.new(2001, 2, 3, Date::GREGORIAN).start # => -Infinity + * Date.new(2001, 2, 3, Date::JULIAN).start # => Infinity + * + * See argument {start}[rdoc-ref:calendars.rdoc@Argument+start]. + * + */ +static VALUE +d_lite_start(VALUE self) +{ + get_d1(self); + return DBL2NUM(m_sg(dat)); +} + +static void +clear_civil(union DateData *x) +{ + if (simple_dat_p(x)) { + x->s.year = 0; +#ifndef USE_PACK + x->s.mon = 0; + x->s.mday = 0; +#else + x->s.pc = 0; +#endif + x->s.flags &= ~HAVE_CIVIL; + } + else { + x->c.year = 0; +#ifndef USE_PACK + x->c.mon = 0; + x->c.mday = 0; + x->c.hour = 0; + x->c.min = 0; + x->c.sec = 0; +#else + x->c.pc = 0; +#endif + x->c.flags &= ~(HAVE_CIVIL | HAVE_TIME); + } +} + +static void +set_sg(union DateData *x, double sg) +{ + if (simple_dat_p(x)) { + get_s_jd(x); + clear_civil(x); + x->s.sg = (date_sg_t)sg; + } else { + get_c_jd(x); + get_c_df(x); + clear_civil(x); + x->c.sg = (date_sg_t)sg; + } +} + +static VALUE +dup_obj_with_new_start(VALUE obj, double sg) +{ + volatile VALUE dup = dup_obj(obj); + { + get_d1(dup); + set_sg(dat, sg); + } + return dup; +} + +/* + * call-seq: + * new_start(start = Date::ITALY]) -> new_date + * + * Returns a copy of +self+ with the given +start+ value: + * + * d0 = Date.new(2000, 2, 3) + * d0.julian? # => false + * d1 = d0.new_start(Date::JULIAN) + * d1.julian? # => true + * + * See argument {start}[rdoc-ref:calendars.rdoc@Argument+start]. + * + */ +static VALUE +d_lite_new_start(int argc, VALUE *argv, VALUE self) +{ + VALUE vsg; + double sg; + + rb_scan_args(argc, argv, "01", &vsg); + + sg = DEFAULT_SG; + if (argc >= 1) + val2sg(vsg, sg); + + return dup_obj_with_new_start(self, sg); +} + +/* + * call-seq: + * italy -> new_date + * + * Equivalent to Date#new_start with argument Date::ITALY. + * + */ +static VALUE +d_lite_italy(VALUE self) +{ + return dup_obj_with_new_start(self, ITALY); +} + +/* + * call-seq: + * england -> new_date + * + * Equivalent to Date#new_start with argument Date::ENGLAND. + */ +static VALUE +d_lite_england(VALUE self) +{ + return dup_obj_with_new_start(self, ENGLAND); +} + +/* + * call-seq: + * julian -> new_date + * + * Equivalent to Date#new_start with argument Date::JULIAN. + */ +static VALUE +d_lite_julian(VALUE self) +{ + return dup_obj_with_new_start(self, JULIAN); +} + +/* + * call-seq: + * gregorian -> new_date + * + * Equivalent to Date#new_start with argument Date::GREGORIAN. + */ +static VALUE +d_lite_gregorian(VALUE self) +{ + return dup_obj_with_new_start(self, GREGORIAN); +} + +static void +set_of(union DateData *x, int of) +{ + assert(complex_dat_p(x)); + get_c_jd(x); + get_c_df(x); + clear_civil(x); + x->c.of = of; +} + +static VALUE +dup_obj_with_new_offset(VALUE obj, int of) +{ + volatile VALUE dup = dup_obj_as_complex(obj); + { + get_d1(dup); + set_of(dat, of); + } + return dup; +} + +/* + * call-seq: + * d.new_offset([offset=0]) -> date + * + * Duplicates self and resets its offset. + * + * d = DateTime.new(2001,2,3,4,5,6,'-02:00') + * #=> # + * d.new_offset('+09:00') #=> # + */ +static VALUE +d_lite_new_offset(int argc, VALUE *argv, VALUE self) +{ + VALUE vof; + int rof; + + rb_scan_args(argc, argv, "01", &vof); + + rof = 0; + if (argc >= 1) + val2off(vof, rof); + + return dup_obj_with_new_offset(self, rof); +} + +/* + * call-seq: + * d + other -> date + * + * Returns a date object pointing +other+ days after self. The other + * should be a numeric value. If the other is a fractional number, + * assumes its precision is at most nanosecond. + * + * Date.new(2001,2,3) + 1 #=> # + * DateTime.new(2001,2,3) + Rational(1,2) + * #=> # + * DateTime.new(2001,2,3) + Rational(-1,2) + * #=> # + * DateTime.jd(0,12) + DateTime.new(2001,2,3).ajd + * #=> # + */ +static VALUE +d_lite_plus(VALUE self, VALUE other) +{ + int try_rational = 1; + get_d1(self); + + again: + switch (TYPE(other)) { + case T_FIXNUM: + { + VALUE nth; + long t; + int jd; + + nth = m_nth(dat); + t = FIX2LONG(other); + if (DIV(t, CM_PERIOD)) { + nth = f_add(nth, INT2FIX(DIV(t, CM_PERIOD))); + t = MOD(t, CM_PERIOD); + } + + if (!t) + jd = m_jd(dat); + else { + jd = m_jd(dat) + (int)t; + canonicalize_jd(nth, jd); + } + + if (simple_dat_p(dat)) + return d_simple_new_internal(rb_obj_class(self), + nth, jd, + dat->s.sg, + 0, 0, 0, + (dat->s.flags | HAVE_JD) & + ~HAVE_CIVIL); + else + return d_complex_new_internal(rb_obj_class(self), + nth, jd, + dat->c.df, dat->c.sf, + dat->c.of, dat->c.sg, + 0, 0, 0, +#ifndef USE_PACK + dat->c.hour, + dat->c.min, + dat->c.sec, +#else + EX_HOUR(dat->c.pc), + EX_MIN(dat->c.pc), + EX_SEC(dat->c.pc), +#endif + (dat->c.flags | HAVE_JD) & + ~HAVE_CIVIL); + } + break; + case T_BIGNUM: + { + VALUE nth; + int jd, s; + + if (f_positive_p(other)) + s = +1; + else { + s = -1; + other = f_negate(other); + } + + nth = f_idiv(other, INT2FIX(CM_PERIOD)); + jd = FIX2INT(f_mod(other, INT2FIX(CM_PERIOD))); + + if (s < 0) { + nth = f_negate(nth); + jd = -jd; + } + + if (!jd) + jd = m_jd(dat); + else { + jd = m_jd(dat) + jd; + canonicalize_jd(nth, jd); + } + + if (f_zero_p(nth)) + nth = m_nth(dat); + else + nth = f_add(m_nth(dat), nth); + + if (simple_dat_p(dat)) + return d_simple_new_internal(rb_obj_class(self), + nth, jd, + dat->s.sg, + 0, 0, 0, + (dat->s.flags | HAVE_JD) & + ~HAVE_CIVIL); + else + return d_complex_new_internal(rb_obj_class(self), + nth, jd, + dat->c.df, dat->c.sf, + dat->c.of, dat->c.sg, + 0, 0, 0, +#ifndef USE_PACK + dat->c.hour, + dat->c.min, + dat->c.sec, +#else + EX_HOUR(dat->c.pc), + EX_MIN(dat->c.pc), + EX_SEC(dat->c.pc), +#endif + (dat->c.flags | HAVE_JD) & + ~HAVE_CIVIL); + } + break; + case T_FLOAT: + { + double jd, o, tmp; + int s, df; + VALUE nth, sf; + + o = RFLOAT_VALUE(other); + + if (o > 0) + s = +1; + else { + s = -1; + o = -o; + } + + o = modf(o, &tmp); + + if (!floor(tmp / CM_PERIOD)) { + nth = INT2FIX(0); + jd = (int)tmp; + } + else { + double i, f; + + f = modf(tmp / CM_PERIOD, &i); + nth = f_floor(DBL2NUM(i)); + jd = (int)(f * CM_PERIOD); + } + + o *= DAY_IN_SECONDS; + o = modf(o, &tmp); + df = (int)tmp; + o *= SECOND_IN_NANOSECONDS; + sf = INT2FIX((int)round(o)); + + if (s < 0) { + jd = -jd; + df = -df; + sf = f_negate(sf); + } + + if (f_zero_p(sf)) + sf = m_sf(dat); + else { + sf = f_add(m_sf(dat), sf); + if (f_lt_p(sf, INT2FIX(0))) { + df -= 1; + sf = f_add(sf, INT2FIX(SECOND_IN_NANOSECONDS)); + } + else if (f_ge_p(sf, INT2FIX(SECOND_IN_NANOSECONDS))) { + df += 1; + sf = f_sub(sf, INT2FIX(SECOND_IN_NANOSECONDS)); + } + } + + if (!df) + df = m_df(dat); + else { + df = m_df(dat) + df; + if (df < 0) { + jd -= 1; + df += DAY_IN_SECONDS; + } + else if (df >= DAY_IN_SECONDS) { + jd += 1; + df -= DAY_IN_SECONDS; + } + } + + if (!jd) + jd = m_jd(dat); + else { + jd = m_jd(dat) + jd; + canonicalize_jd(nth, jd); + } + + if (f_zero_p(nth)) + nth = m_nth(dat); + else + nth = f_add(m_nth(dat), nth); + + if (!df && f_zero_p(sf) && !m_of(dat)) + return d_simple_new_internal(rb_obj_class(self), + nth, (int)jd, + m_sg(dat), + 0, 0, 0, + (dat->s.flags | HAVE_JD) & + ~(HAVE_CIVIL | HAVE_TIME | + COMPLEX_DAT)); + else + return d_complex_new_internal(rb_obj_class(self), + nth, (int)jd, + df, sf, + m_of(dat), m_sg(dat), + 0, 0, 0, + 0, 0, 0, + (dat->c.flags | + HAVE_JD | HAVE_DF) & + ~(HAVE_CIVIL | HAVE_TIME)); + } + break; + default: + expect_numeric(other); + other = f_to_r(other); + if (!k_rational_p(other)) { + if (!try_rational) Check_Type(other, T_RATIONAL); + try_rational = 0; + goto again; + } + /* fall through */ + case T_RATIONAL: + { + VALUE nth, sf, t; + int jd, df, s; + + if (wholenum_p(other)) { + other = rb_rational_num(other); + goto again; + } + + if (f_positive_p(other)) + s = +1; + else { + s = -1; + other = f_negate(other); + } + + nth = f_idiv(other, INT2FIX(CM_PERIOD)); + t = f_mod(other, INT2FIX(CM_PERIOD)); + + jd = FIX2INT(f_idiv(t, INT2FIX(1))); + t = f_mod(t, INT2FIX(1)); + + t = f_mul(t, INT2FIX(DAY_IN_SECONDS)); + df = FIX2INT(f_idiv(t, INT2FIX(1))); + t = f_mod(t, INT2FIX(1)); + + sf = f_mul(t, INT2FIX(SECOND_IN_NANOSECONDS)); + + if (s < 0) { + nth = f_negate(nth); + jd = -jd; + df = -df; + sf = f_negate(sf); + } + + if (f_zero_p(sf)) + sf = m_sf(dat); + else { + sf = f_add(m_sf(dat), sf); + if (f_lt_p(sf, INT2FIX(0))) { + df -= 1; + sf = f_add(sf, INT2FIX(SECOND_IN_NANOSECONDS)); + } + else if (f_ge_p(sf, INT2FIX(SECOND_IN_NANOSECONDS))) { + df += 1; + sf = f_sub(sf, INT2FIX(SECOND_IN_NANOSECONDS)); + } + } + + if (!df) + df = m_df(dat); + else { + df = m_df(dat) + df; + if (df < 0) { + jd -= 1; + df += DAY_IN_SECONDS; + } + else if (df >= DAY_IN_SECONDS) { + jd += 1; + df -= DAY_IN_SECONDS; + } + } + + if (!jd) + jd = m_jd(dat); + else { + jd = m_jd(dat) + jd; + canonicalize_jd(nth, jd); + } + + if (f_zero_p(nth)) + nth = m_nth(dat); + else + nth = f_add(m_nth(dat), nth); + + if (!df && f_zero_p(sf) && !m_of(dat)) + return d_simple_new_internal(rb_obj_class(self), + nth, jd, + m_sg(dat), + 0, 0, 0, + (dat->s.flags | HAVE_JD) & + ~(HAVE_CIVIL | HAVE_TIME | + COMPLEX_DAT)); + else + return d_complex_new_internal(rb_obj_class(self), + nth, jd, + df, sf, + m_of(dat), m_sg(dat), + 0, 0, 0, + 0, 0, 0, + (dat->c.flags | + HAVE_JD | HAVE_DF) & + ~(HAVE_CIVIL | HAVE_TIME)); + } + break; + } +} + +static VALUE +minus_dd(VALUE self, VALUE other) +{ + get_d2(self, other); + + { + int d, df; + VALUE n, sf, r; + + n = f_sub(m_nth(adat), m_nth(bdat)); + d = m_jd(adat) - m_jd(bdat); + df = m_df(adat) - m_df(bdat); + sf = f_sub(m_sf(adat), m_sf(bdat)); + canonicalize_jd(n, d); + + if (df < 0) { + d -= 1; + df += DAY_IN_SECONDS; + } + else if (df >= DAY_IN_SECONDS) { + d += 1; + df -= DAY_IN_SECONDS; + } + + if (f_lt_p(sf, INT2FIX(0))) { + df -= 1; + sf = f_add(sf, INT2FIX(SECOND_IN_NANOSECONDS)); + } + else if (f_ge_p(sf, INT2FIX(SECOND_IN_NANOSECONDS))) { + df += 1; + sf = f_sub(sf, INT2FIX(SECOND_IN_NANOSECONDS)); + } + + if (f_zero_p(n)) + r = INT2FIX(0); + else + r = f_mul(n, INT2FIX(CM_PERIOD)); + + if (d) + r = f_add(r, rb_rational_new1(INT2FIX(d))); + if (df) + r = f_add(r, isec_to_day(df)); + if (f_nonzero_p(sf)) + r = f_add(r, ns_to_day(sf)); + + if (RB_TYPE_P(r, T_RATIONAL)) + return r; + return rb_rational_new1(r); + } +} + +/* + * call-seq: + * d - other -> date or rational + * + * If the other is a date object, returns a Rational + * whose value is the difference between the two dates in days. + * If the other is a numeric value, returns a date object + * pointing +other+ days before self. + * If the other is a fractional number, + * assumes its precision is at most nanosecond. + * + * Date.new(2001,2,3) - 1 #=> # + * DateTime.new(2001,2,3) - Rational(1,2) + * #=> # + * Date.new(2001,2,3) - Date.new(2001) + * #=> (33/1) + * DateTime.new(2001,2,3) - DateTime.new(2001,2,2,12) + * #=> (1/2) + */ +static VALUE +d_lite_minus(VALUE self, VALUE other) +{ + if (k_date_p(other)) + return minus_dd(self, other); + + switch (TYPE(other)) { + case T_FIXNUM: + return d_lite_plus(self, LONG2NUM(-FIX2LONG(other))); + case T_FLOAT: + return d_lite_plus(self, DBL2NUM(-RFLOAT_VALUE(other))); + default: + expect_numeric(other); + /* fall through */ + case T_BIGNUM: + case T_RATIONAL: + return d_lite_plus(self, f_negate(other)); + } +} + +/* + * call-seq: + * next_day(n = 1) -> new_date + * + * Equivalent to Date#+ with argument +n+. + */ +static VALUE +d_lite_next_day(int argc, VALUE *argv, VALUE self) +{ + VALUE n; + + rb_scan_args(argc, argv, "01", &n); + if (argc < 1) + n = INT2FIX(1); + return d_lite_plus(self, n); +} + +/* + * call-seq: + * prev_day(n = 1) -> new_date + * + * Equivalent to Date#- with argument +n+. + */ +static VALUE +d_lite_prev_day(int argc, VALUE *argv, VALUE self) +{ + VALUE n; + + rb_scan_args(argc, argv, "01", &n); + if (argc < 1) + n = INT2FIX(1); + return d_lite_minus(self, n); +} + +/* + * call-seq: + * d.next -> new_date + * + * Returns a new \Date object representing the following day: + * + * d = Date.new(2001, 2, 3) + * d.to_s # => "2001-02-03" + * d.next.to_s # => "2001-02-04" + * + */ +static VALUE +d_lite_next(VALUE self) +{ + return d_lite_next_day(0, (VALUE *)NULL, self); +} + +/* + * call-seq: + * d >> n -> new_date + * + * Returns a new \Date object representing the date + * +n+ months later; +n+ should be a numeric: + * + * (Date.new(2001, 2, 3) >> 1).to_s # => "2001-03-03" + * (Date.new(2001, 2, 3) >> -2).to_s # => "2000-12-03" + * + * When the same day does not exist for the new month, + * the last day of that month is used instead: + * + * (Date.new(2001, 1, 31) >> 1).to_s # => "2001-02-28" + * (Date.new(2001, 1, 31) >> -4).to_s # => "2000-09-30" + * + * This results in the following, possibly unexpected, behaviors: + * + * d0 = Date.new(2001, 1, 31) + * d1 = d0 >> 1 # => # + * d2 = d1 >> 1 # => # + * + * d0 = Date.new(2001, 1, 31) + * d1 = d0 >> 1 # => # + * d2 = d1 >> -1 # => # + * + */ +static VALUE +d_lite_rshift(VALUE self, VALUE other) +{ + VALUE t, y, nth, rjd2; + int m, d, rjd; + double sg; + + get_d1(self); + t = f_add3(f_mul(m_real_year(dat), INT2FIX(12)), + INT2FIX(m_mon(dat) - 1), + other); + if (FIXNUM_P(t)) { + long it = FIX2LONG(t); + y = LONG2NUM(DIV(it, 12)); + it = MOD(it, 12); + m = (int)it + 1; + } + else { + y = f_idiv(t, INT2FIX(12)); + t = f_mod(t, INT2FIX(12)); + m = FIX2INT(t) + 1; + } + d = m_mday(dat); + sg = m_sg(dat); + + while (1) { + int ry, rm, rd, ns; + + if (valid_civil_p(y, m, d, sg, + &nth, &ry, + &rm, &rd, &rjd, &ns)) + break; + if (--d < 1) + rb_raise(eDateError, "invalid date"); + } + encode_jd(nth, rjd, &rjd2); + return d_lite_plus(self, f_sub(rjd2, m_real_local_jd(dat))); +} + +/* + * call-seq: + * d << n -> date + * + * Returns a new \Date object representing the date + * +n+ months earlier; +n+ should be a numeric: + * + * (Date.new(2001, 2, 3) << 1).to_s # => "2001-01-03" + * (Date.new(2001, 2, 3) << -2).to_s # => "2001-04-03" + * + * When the same day does not exist for the new month, + * the last day of that month is used instead: + * + * (Date.new(2001, 3, 31) << 1).to_s # => "2001-02-28" + * (Date.new(2001, 3, 31) << -6).to_s # => "2001-09-30" + * + * This results in the following, possibly unexpected, behaviors: + * + * d0 = Date.new(2001, 3, 31) + * d0 << 2 # => # + * d0 << 1 << 1 # => # + * + * d0 = Date.new(2001, 3, 31) + * d1 = d0 << 1 # => # + * d2 = d1 << -1 # => # + * + */ +static VALUE +d_lite_lshift(VALUE self, VALUE other) +{ + expect_numeric(other); + return d_lite_rshift(self, f_negate(other)); +} + +/* + * call-seq: + * next_month(n = 1) -> new_date + * + * Equivalent to #>> with argument +n+. + */ +static VALUE +d_lite_next_month(int argc, VALUE *argv, VALUE self) +{ + VALUE n; + + rb_scan_args(argc, argv, "01", &n); + if (argc < 1) + n = INT2FIX(1); + return d_lite_rshift(self, n); +} + +/* + * call-seq: + * prev_month(n = 1) -> new_date + * + * Equivalent to #<< with argument +n+. + */ +static VALUE +d_lite_prev_month(int argc, VALUE *argv, VALUE self) +{ + VALUE n; + + rb_scan_args(argc, argv, "01", &n); + if (argc < 1) + n = INT2FIX(1); + return d_lite_lshift(self, n); +} + +/* + * call-seq: + * next_year(n = 1) -> new_date + * + * Equivalent to #>> with argument n * 12. + */ +static VALUE +d_lite_next_year(int argc, VALUE *argv, VALUE self) +{ + VALUE n; + + rb_scan_args(argc, argv, "01", &n); + if (argc < 1) + n = INT2FIX(1); + return d_lite_rshift(self, f_mul(n, INT2FIX(12))); +} + +/* + * call-seq: + * prev_year(n = 1) -> new_date + * + * Equivalent to #<< with argument n * 12. + */ +static VALUE +d_lite_prev_year(int argc, VALUE *argv, VALUE self) +{ + VALUE n; + + rb_scan_args(argc, argv, "01", &n); + if (argc < 1) + n = INT2FIX(1); + return d_lite_lshift(self, f_mul(n, INT2FIX(12))); +} + +static VALUE d_lite_cmp(VALUE, VALUE); + +/* + * call-seq: + * step(limit, step = 1){|date| ... } -> self + * + * Calls the block with specified dates; + * returns +self+. + * + * - The first +date+ is +self+. + * - Each successive +date+ is date + step, + * where +step+ is the numeric step size in days. + * - The last date is the last one that is before or equal to +limit+, + * which should be a \Date object. + * + * Example: + * + * limit = Date.new(2001, 12, 31) + * Date.new(2001).step(limit){|date| p date.to_s if date.mday == 31 } + * + * Output: + * + * "2001-01-31" + * "2001-03-31" + * "2001-05-31" + * "2001-07-31" + * "2001-08-31" + * "2001-10-31" + * "2001-12-31" + * + * Returns an Enumerator if no block is given. + */ +static VALUE +d_lite_step(int argc, VALUE *argv, VALUE self) +{ + VALUE limit, step, date; + int c; + + rb_scan_args(argc, argv, "11", &limit, &step); + + if (argc < 2) + step = INT2FIX(1); + +#if 0 + if (f_zero_p(step)) + rb_raise(rb_eArgError, "step can't be 0"); +#endif + + RETURN_ENUMERATOR(self, argc, argv); + + date = self; + c = f_cmp(step, INT2FIX(0)); + if (c < 0) { + while (FIX2INT(d_lite_cmp(date, limit)) >= 0) { + rb_yield(date); + date = d_lite_plus(date, step); + } + } + else if (c == 0) { + while (1) + rb_yield(date); + } + else /* if (c > 0) */ { + while (FIX2INT(d_lite_cmp(date, limit)) <= 0) { + rb_yield(date); + date = d_lite_plus(date, step); + } + } + return self; +} + +/* + * call-seq: + * upto(max){|date| ... } -> self + * + * Equivalent to #step with arguments +max+ and +1+. + */ +static VALUE +d_lite_upto(VALUE self, VALUE max) +{ + VALUE date; + + RETURN_ENUMERATOR(self, 1, &max); + + date = self; + while (FIX2INT(d_lite_cmp(date, max)) <= 0) { + rb_yield(date); + date = d_lite_plus(date, INT2FIX(1)); + } + return self; +} + +/* + * call-seq: + * downto(min){|date| ... } -> self + * + * Equivalent to #step with arguments +min+ and -1. + */ +static VALUE +d_lite_downto(VALUE self, VALUE min) +{ + VALUE date; + + RETURN_ENUMERATOR(self, 1, &min); + + date = self; + while (FIX2INT(d_lite_cmp(date, min)) >= 0) { + rb_yield(date); + date = d_lite_plus(date, INT2FIX(-1)); + } + return self; +} + +static VALUE +cmp_gen(VALUE self, VALUE other) +{ + get_d1(self); + + if (k_numeric_p(other)) + return INT2FIX(f_cmp(m_ajd(dat), other)); + else if (k_date_p(other)) + return INT2FIX(f_cmp(m_ajd(dat), f_ajd(other))); + return rb_num_coerce_cmp(self, other, id_cmp); +} + +static VALUE +cmp_dd(VALUE self, VALUE other) +{ + get_d2(self, other); + + { + VALUE a_nth, b_nth, + a_sf, b_sf; + int a_jd, b_jd, + a_df, b_df; + + m_canonicalize_jd(self, adat); + m_canonicalize_jd(other, bdat); + a_nth = m_nth(adat); + b_nth = m_nth(bdat); + if (f_eqeq_p(a_nth, b_nth)) { + a_jd = m_jd(adat); + b_jd = m_jd(bdat); + if (a_jd == b_jd) { + a_df = m_df(adat); + b_df = m_df(bdat); + if (a_df == b_df) { + a_sf = m_sf(adat); + b_sf = m_sf(bdat); + if (f_eqeq_p(a_sf, b_sf)) { + return INT2FIX(0); + } + else if (f_lt_p(a_sf, b_sf)) { + return INT2FIX(-1); + } + else { + return INT2FIX(1); + } + } + else if (a_df < b_df) { + return INT2FIX(-1); + } + else { + return INT2FIX(1); + } + } + else if (a_jd < b_jd) { + return INT2FIX(-1); + } + else { + return INT2FIX(1); + } + } + else if (f_lt_p(a_nth, b_nth)) { + return INT2FIX(-1); + } + else { + return INT2FIX(1); + } + } +} + +/* + * call-seq: + * self <=> other -> -1, 0, 1 or nil + * + * Compares +self+ and +other+, returning: + * + * - -1 if +other+ is larger. + * - 0 if the two are equal. + * - 1 if +other+ is smaller. + * - +nil+ if the two are incomparable. + * + * Argument +other+ may be: + * + * - Another \Date object: + * + * d = Date.new(2022, 7, 27) # => # + * prev_date = d.prev_day # => # + * next_date = d.next_day # => # + * d <=> next_date # => -1 + * d <=> d # => 0 + * d <=> prev_date # => 1 + * + * - A DateTime object: + * + * d <=> DateTime.new(2022, 7, 26) # => 1 + * d <=> DateTime.new(2022, 7, 27) # => 0 + * d <=> DateTime.new(2022, 7, 28) # => -1 + * + * - A numeric (compares self.ajd to +other+): + * + * d <=> 2459788 # => -1 + * d <=> 2459787 # => 1 + * d <=> 2459786 # => 1 + * d <=> d.ajd # => 0 + * + * - Any other object: + * + * d <=> Object.new # => nil + * + */ +static VALUE +d_lite_cmp(VALUE self, VALUE other) +{ + if (!k_date_p(other)) + return cmp_gen(self, other); + + { + get_d2(self, other); + + if (!(simple_dat_p(adat) && simple_dat_p(bdat) && + m_gregorian_p(adat) == m_gregorian_p(bdat))) + return cmp_dd(self, other); + + { + VALUE a_nth, b_nth; + int a_jd, b_jd; + + m_canonicalize_jd(self, adat); + m_canonicalize_jd(other, bdat); + a_nth = m_nth(adat); + b_nth = m_nth(bdat); + if (f_eqeq_p(a_nth, b_nth)) { + a_jd = m_jd(adat); + b_jd = m_jd(bdat); + if (a_jd == b_jd) { + return INT2FIX(0); + } + else if (a_jd < b_jd) { + return INT2FIX(-1); + } + else { + return INT2FIX(1); + } + } + else if (f_lt_p(a_nth, b_nth)) { + return INT2FIX(-1); + } + else { + return INT2FIX(1); + } + } + } +} + +static VALUE +equal_gen(VALUE self, VALUE other) +{ + get_d1(self); + + if (k_numeric_p(other)) + return f_eqeq_p(m_real_local_jd(dat), other); + else if (k_date_p(other)) + return f_eqeq_p(m_real_local_jd(dat), f_jd(other)); + return rb_num_coerce_cmp(self, other, id_eqeq_p); +} + +/* + * call-seq: + * self === other -> true, false, or nil. + * + * Returns +true+ if +self+ and +other+ represent the same date, + * +false+ if not, +nil+ if the two are not comparable. + * + * Argument +other+ may be: + * + * - Another \Date object: + * + * d = Date.new(2022, 7, 27) # => # + * prev_date = d.prev_day # => # + * next_date = d.next_day # => # + * d === prev_date # => false + * d === d # => true + * d === next_date # => false + * + * - A DateTime object: + * + * d === DateTime.new(2022, 7, 26) # => false + * d === DateTime.new(2022, 7, 27) # => true + * d === DateTime.new(2022, 7, 28) # => false + * + * - A numeric (compares self.jd to +other+): + * + * d === 2459788 # => true + * d === 2459787 # => false + * d === 2459786 # => false + * d === d.jd # => true + * + * - An object not comparable: + * + * d === Object.new # => nil + * + */ +static VALUE +d_lite_equal(VALUE self, VALUE other) +{ + if (!k_date_p(other)) + return equal_gen(self, other); + + { + get_d2(self, other); + + if (!(m_gregorian_p(adat) == m_gregorian_p(bdat))) + return equal_gen(self, other); + + { + VALUE a_nth, b_nth; + int a_jd, b_jd; + + m_canonicalize_jd(self, adat); + m_canonicalize_jd(other, bdat); + a_nth = m_nth(adat); + b_nth = m_nth(bdat); + a_jd = m_local_jd(adat); + b_jd = m_local_jd(bdat); + if (f_eqeq_p(a_nth, b_nth) && + a_jd == b_jd) + return Qtrue; + return Qfalse; + } + } +} + +/* :nodoc: */ +static VALUE +d_lite_eql_p(VALUE self, VALUE other) +{ + if (!k_date_p(other)) + return Qfalse; + return f_zero_p(d_lite_cmp(self, other)); +} + +/* :nodoc: */ +static VALUE +d_lite_hash(VALUE self) +{ + st_index_t v, h[4]; + + get_d1(self); + h[0] = m_nth(dat); + h[1] = m_jd(dat); + h[2] = m_df(dat); + h[3] = m_sf(dat); + v = rb_memhash(h, sizeof(h)); + return ST2FIX(v); +} + +#include "date_tmx.h" +static void set_tmx(VALUE, struct tmx *); +static VALUE strftimev(const char *, VALUE, + void (*)(VALUE, struct tmx *)); + +/* + * call-seq: + * to_s -> string + * + * Returns a string representation of the date in +self+ + * in {ISO 8601 extended date format}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-ISO+8601+Format+Specifications] + * ('%Y-%m-%d'): + * + * Date.new(2001, 2, 3).to_s # => "2001-02-03" + * + */ +static VALUE +d_lite_to_s(VALUE self) +{ + return strftimev("%Y-%m-%d", self, set_tmx); +} + +#ifndef NDEBUG +/* :nodoc: */ +static VALUE +mk_inspect_raw(union DateData *x, VALUE klass) +{ + char flags[6]; + + flags[0] = (x->flags & COMPLEX_DAT) ? 'C' : 'S'; + flags[1] = (x->flags & HAVE_JD) ? 'j' : '-'; + flags[2] = (x->flags & HAVE_DF) ? 'd' : '-'; + flags[3] = (x->flags & HAVE_CIVIL) ? 'c' : '-'; + flags[4] = (x->flags & HAVE_TIME) ? 't' : '-'; + flags[5] = '\0'; + + if (simple_dat_p(x)) { + return rb_enc_sprintf(rb_usascii_encoding(), + "#<%"PRIsVALUE": " + "(%+"PRIsVALUE"th,%dj),+0s,%.0fj; " + "%dy%dm%dd; %s>", + klass, + x->s.nth, x->s.jd, x->s.sg, +#ifndef USE_PACK + x->s.year, x->s.mon, x->s.mday, +#else + x->s.year, + EX_MON(x->s.pc), EX_MDAY(x->s.pc), +#endif + flags); + } + else { + return rb_enc_sprintf(rb_usascii_encoding(), + "#<%"PRIsVALUE": " + "(%+"PRIsVALUE"th,%dj,%ds,%+"PRIsVALUE"n)," + "%+ds,%.0fj; " + "%dy%dm%dd %dh%dm%ds; %s>", + klass, + x->c.nth, x->c.jd, x->c.df, x->c.sf, + x->c.of, x->c.sg, +#ifndef USE_PACK + x->c.year, x->c.mon, x->c.mday, + x->c.hour, x->c.min, x->c.sec, +#else + x->c.year, + EX_MON(x->c.pc), EX_MDAY(x->c.pc), + EX_HOUR(x->c.pc), EX_MIN(x->c.pc), + EX_SEC(x->c.pc), +#endif + flags); + } +} + +/* :nodoc: */ +static VALUE +d_lite_inspect_raw(VALUE self) +{ + get_d1(self); + return mk_inspect_raw(dat, rb_obj_class(self)); +} +#endif + +static VALUE +mk_inspect(union DateData *x, VALUE klass, VALUE to_s) +{ + return rb_enc_sprintf(rb_usascii_encoding(), + "#<%"PRIsVALUE": %"PRIsVALUE" " + "((%+"PRIsVALUE"j,%ds,%+"PRIsVALUE"n),%+ds,%.0fj)>", + klass, to_s, + m_real_jd(x), m_df(x), m_sf(x), + m_of(x), m_sg(x)); +} + +/* + * call-seq: + * inspect -> string + * + * Returns a string representation of +self+: + * + * Date.new(2001, 2, 3).inspect + * # => "#" + * + */ +static VALUE +d_lite_inspect(VALUE self) +{ + get_d1(self); + return mk_inspect(dat, rb_obj_class(self), self); +} + +#include +#include "date_tmx.h" + +size_t date_strftime(char *s, size_t maxsize, const char *format, + const struct tmx *tmx); + +#define SMALLBUF 100 +static size_t +date_strftime_alloc(char **buf, const char *format, + struct tmx *tmx) +{ + size_t size, len, flen; + + (*buf)[0] = '\0'; + flen = strlen(format); + if (flen == 0) { + return 0; + } + errno = 0; + len = date_strftime(*buf, SMALLBUF, format, tmx); + if (len != 0 || (**buf == '\0' && errno != ERANGE)) return len; + for (size=1024; ; size*=2) { + *buf = xmalloc(size); + (*buf)[0] = '\0'; + len = date_strftime(*buf, size, format, tmx); + /* + * buflen can be zero EITHER because there's not enough + * room in the string, or because the control command + * goes to the empty string. Make a reasonable guess that + * if the buffer is 1024 times bigger than the length of the + * format string, it's not failing for lack of room. + */ + if (len > 0) break; + xfree(*buf); + if (size >= 1024 * flen) { + rb_sys_fail(format); + break; + } + } + return len; +} + +static VALUE +tmx_m_secs(union DateData *x) +{ + VALUE s; + int df; + + s = day_to_sec(f_sub(m_real_jd(x), + UNIX_EPOCH_IN_CJD)); + if (simple_dat_p(x)) + return s; + df = m_df(x); + if (df) + s = f_add(s, INT2FIX(df)); + return s; +} + +#define MILLISECOND_IN_NANOSECONDS 1000000 + +static VALUE +tmx_m_msecs(union DateData *x) +{ + VALUE s, sf; + + s = sec_to_ms(tmx_m_secs(x)); + if (simple_dat_p(x)) + return s; + sf = m_sf(x); + if (f_nonzero_p(sf)) + s = f_add(s, f_div(sf, INT2FIX(MILLISECOND_IN_NANOSECONDS))); + return s; +} + +static int +tmx_m_of(union DateData *x) +{ + return m_of(x); +} + +static char * +tmx_m_zone(union DateData *x) +{ + VALUE zone = m_zone(x); + /* TODO: fix potential dangling pointer */ + return RSTRING_PTR(zone); +} + +static const struct tmx_funcs tmx_funcs = { + (VALUE (*)(void *))m_real_year, + (int (*)(void *))m_yday, + (int (*)(void *))m_mon, + (int (*)(void *))m_mday, + (VALUE (*)(void *))m_real_cwyear, + (int (*)(void *))m_cweek, + (int (*)(void *))m_cwday, + (int (*)(void *))m_wnum0, + (int (*)(void *))m_wnum1, + (int (*)(void *))m_wday, + (int (*)(void *))m_hour, + (int (*)(void *))m_min, + (int (*)(void *))m_sec, + (VALUE (*)(void *))m_sf_in_sec, + (VALUE (*)(void *))tmx_m_secs, + (VALUE (*)(void *))tmx_m_msecs, + (int (*)(void *))tmx_m_of, + (char *(*)(void *))tmx_m_zone +}; + +static void +set_tmx(VALUE self, struct tmx *tmx) +{ + get_d1(self); + tmx->dat = (void *)dat; + tmx->funcs = &tmx_funcs; +} + +static VALUE +date_strftime_internal(int argc, VALUE *argv, VALUE self, + const char *default_fmt, + void (*func)(VALUE, struct tmx *)) +{ + VALUE vfmt; + const char *fmt; + long len; + char buffer[SMALLBUF], *buf = buffer; + struct tmx tmx; + VALUE str; + + rb_scan_args(argc, argv, "01", &vfmt); + + if (argc < 1) + vfmt = rb_usascii_str_new2(default_fmt); + else { + StringValue(vfmt); + if (!rb_enc_str_asciicompat_p(vfmt)) { + rb_raise(rb_eArgError, + "format should have ASCII compatible encoding"); + } + } + fmt = RSTRING_PTR(vfmt); + len = RSTRING_LEN(vfmt); + (*func)(self, &tmx); + if (memchr(fmt, '\0', len)) { + /* Ruby string may contain \0's. */ + const char *p = fmt, *pe = fmt + len; + + str = rb_str_new(0, 0); + while (p < pe) { + len = date_strftime_alloc(&buf, p, &tmx); + rb_str_cat(str, buf, len); + p += strlen(p); + if (buf != buffer) { + xfree(buf); + buf = buffer; + } + for (fmt = p; p < pe && !*p; ++p); + if (p > fmt) rb_str_cat(str, fmt, p - fmt); + } + rb_enc_copy(str, vfmt); + return str; + } + else + len = date_strftime_alloc(&buf, fmt, &tmx); + + str = rb_str_new(buf, len); + if (buf != buffer) xfree(buf); + rb_enc_copy(str, vfmt); + return str; +} + +/* + * call-seq: + * strftime(format = '%F') -> string + * + * Returns a string representation of the date in +self+, + * formatted according the given +format+: + * + * Date.new(2001, 2, 3).strftime # => "2001-02-03" + * + * For other formats, see + * {Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html]. + * + */ +static VALUE +d_lite_strftime(int argc, VALUE *argv, VALUE self) +{ + return date_strftime_internal(argc, argv, self, + "%Y-%m-%d", set_tmx); +} + +static VALUE +strftimev(const char *fmt, VALUE self, + void (*func)(VALUE, struct tmx *)) +{ + char buffer[SMALLBUF], *buf = buffer; + struct tmx tmx; + long len; + VALUE str; + + (*func)(self, &tmx); + len = date_strftime_alloc(&buf, fmt, &tmx); + RB_GC_GUARD(self); + str = rb_usascii_str_new(buf, len); + if (buf != buffer) xfree(buf); + return str; +} + +/* + * call-seq: + * asctime -> string + * + * Equivalent to #strftime with argument '%a %b %e %T %Y' + * (or its {shorthand form}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-Shorthand+Conversion+Specifiers] + * '%c'): + * + * Date.new(2001, 2, 3).asctime # => "Sat Feb 3 00:00:00 2001" + * + * See {asctime}[https://linux.die.net/man/3/asctime]. + * + */ +static VALUE +d_lite_asctime(VALUE self) +{ + return strftimev("%a %b %e %H:%M:%S %Y", self, set_tmx); +} + +/* + * call-seq: + * iso8601 -> string + * + * Equivalent to #strftime with argument '%Y-%m-%d' + * (or its {shorthand form}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-Shorthand+Conversion+Specifiers] + * '%F'); + * + * Date.new(2001, 2, 3).iso8601 # => "2001-02-03" + * + */ +static VALUE +d_lite_iso8601(VALUE self) +{ + return strftimev("%Y-%m-%d", self, set_tmx); +} + +/* + * call-seq: + * rfc3339 -> string + * + * Equivalent to #strftime with argument '%FT%T%:z'; + * see {Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html]: + * + * Date.new(2001, 2, 3).rfc3339 # => "2001-02-03T00:00:00+00:00" + * + */ +static VALUE +d_lite_rfc3339(VALUE self) +{ + return strftimev("%Y-%m-%dT%H:%M:%S%:z", self, set_tmx); +} + +/* + * call-seq: + * rfc2822 -> string + * + * Equivalent to #strftime with argument '%a, %-d %b %Y %T %z'; + * see {Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html]: + * + * Date.new(2001, 2, 3).rfc2822 # => "Sat, 3 Feb 2001 00:00:00 +0000" + * + */ +static VALUE +d_lite_rfc2822(VALUE self) +{ + return strftimev("%a, %-d %b %Y %T %z", self, set_tmx); +} + +/* + * call-seq: + * httpdate -> string + * + * Equivalent to #strftime with argument '%a, %d %b %Y %T GMT'; + * see {Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html]: + * + * Date.new(2001, 2, 3).httpdate # => "Sat, 03 Feb 2001 00:00:00 GMT" + * + */ +static VALUE +d_lite_httpdate(VALUE self) +{ + volatile VALUE dup = dup_obj_with_new_offset(self, 0); + return strftimev("%a, %d %b %Y %T GMT", dup, set_tmx); +} + +enum { + DECIMAL_SIZE_OF_LONG = DECIMAL_SIZE_OF_BITS(CHAR_BIT*sizeof(long)), + JISX0301_DATE_SIZE = DECIMAL_SIZE_OF_LONG+8 +}; + +static const char * +jisx0301_date_format(char *fmt, size_t size, VALUE jd, VALUE y) +{ + if (FIXNUM_P(jd)) { + long d = FIX2INT(jd); + long s; + char c; + if (d < 2405160) + return "%Y-%m-%d"; + if (d < 2419614) { + c = 'M'; + s = 1867; + } + else if (d < 2424875) { + c = 'T'; + s = 1911; + } + else if (d < 2447535) { + c = 'S'; + s = 1925; + } + else if (d < 2458605) { + c = 'H'; + s = 1988; + } + else { + c = 'R'; + s = 2018; + } + snprintf(fmt, size, "%c%02ld" ".%%m.%%d", c, FIX2INT(y) - s); + return fmt; + } + return "%Y-%m-%d"; +} + +/* + * call-seq: + * jisx0301 -> string + * + * Returns a string representation of the date in +self+ + * in JIS X 0301 format. + * + * Date.new(2001, 2, 3).jisx0301 # => "H13.02.03" + * + */ +static VALUE +d_lite_jisx0301(VALUE self) +{ + char fmtbuf[JISX0301_DATE_SIZE]; + const char *fmt; + + get_d1(self); + fmt = jisx0301_date_format(fmtbuf, sizeof(fmtbuf), + m_real_local_jd(dat), + m_real_year(dat)); + return strftimev(fmt, self, set_tmx); +} + +static VALUE +deconstruct_keys(VALUE self, VALUE keys, int is_datetime) +{ + VALUE h = rb_hash_new(); + long i; + + get_d1(self); + + if (NIL_P(keys)) { + rb_hash_aset(h, sym_year, m_real_year(dat)); + rb_hash_aset(h, sym_month, INT2FIX(m_mon(dat))); + rb_hash_aset(h, sym_day, INT2FIX(m_mday(dat))); + rb_hash_aset(h, sym_yday, INT2FIX(m_yday(dat))); + rb_hash_aset(h, sym_wday, INT2FIX(m_wday(dat))); + if (is_datetime) { + rb_hash_aset(h, sym_hour, INT2FIX(m_hour(dat))); + rb_hash_aset(h, sym_min, INT2FIX(m_min(dat))); + rb_hash_aset(h, sym_sec, INT2FIX(m_sec(dat))); + rb_hash_aset(h, sym_sec_fraction, m_sf_in_sec(dat)); + rb_hash_aset(h, sym_zone, m_zone(dat)); + } + + return h; + } + if (!RB_TYPE_P(keys, T_ARRAY)) { + rb_raise(rb_eTypeError, + "wrong argument type %"PRIsVALUE" (expected Array or nil)", + rb_obj_class(keys)); + + } + + for (i=0; i hash + * + * Returns a hash of the name/value pairs, to use in pattern matching. + * Possible keys are: :year, :month, :day, + * :wday, :yday. + * + * Possible usages: + * + * d = Date.new(2022, 10, 5) + * + * if d in wday: 3, day: ..7 # uses deconstruct_keys underneath + * puts "first Wednesday of the month" + * end + * #=> prints "first Wednesday of the month" + * + * case d + * in year: ...2022 + * puts "too old" + * in month: ..9 + * puts "quarter 1-3" + * in wday: 1..5, month: + * puts "working day in month #{month}" + * end + * #=> prints "working day in month 10" + * + * Note that deconstruction by pattern can also be combined with class check: + * + * if d in Date(wday: 3, day: ..7) + * puts "first Wednesday of the month" + * end + * + */ +static VALUE +d_lite_deconstruct_keys(VALUE self, VALUE keys) +{ + return deconstruct_keys(self, keys, /* is_datetime=false */ 0); +} + +#ifndef NDEBUG +/* :nodoc: */ +static VALUE +d_lite_marshal_dump_old(VALUE self) +{ + VALUE a; + + get_d1(self); + + a = rb_ary_new3(3, + m_ajd(dat), + m_of_in_day(dat), + DBL2NUM(m_sg(dat))); + + if (FL_TEST(self, FL_EXIVAR)) { + rb_copy_generic_ivar(a, self); + FL_SET(a, FL_EXIVAR); + } + + return a; +} +#endif + +/* :nodoc: */ +static VALUE +d_lite_marshal_dump(VALUE self) +{ + VALUE a; + + get_d1(self); + + a = rb_ary_new3(6, + m_nth(dat), + INT2FIX(m_jd(dat)), + INT2FIX(m_df(dat)), + m_sf(dat), + INT2FIX(m_of(dat)), + DBL2NUM(m_sg(dat))); + + if (FL_TEST(self, FL_EXIVAR)) { + rb_copy_generic_ivar(a, self); + FL_SET(a, FL_EXIVAR); + } + + return a; +} + +/* :nodoc: */ +static VALUE +d_lite_marshal_load(VALUE self, VALUE a) +{ + VALUE nth, sf; + int jd, df, of; + double sg; + + get_d1(self); + + rb_check_frozen(self); + + if (!RB_TYPE_P(a, T_ARRAY)) + rb_raise(rb_eTypeError, "expected an array"); + + switch (RARRAY_LEN(a)) { + case 2: /* 1.6.x */ + case 3: /* 1.8.x, 1.9.2 */ + { + VALUE ajd, vof, vsg; + + if (RARRAY_LEN(a) == 2) { + ajd = f_sub(RARRAY_AREF(a, 0), half_days_in_day); + vof = INT2FIX(0); + vsg = RARRAY_AREF(a, 1); + if (!k_numeric_p(vsg)) + vsg = DBL2NUM(RTEST(vsg) ? GREGORIAN : JULIAN); + } + else { + ajd = RARRAY_AREF(a, 0); + vof = RARRAY_AREF(a, 1); + vsg = RARRAY_AREF(a, 2); + } + + old_to_new(ajd, vof, vsg, + &nth, &jd, &df, &sf, &of, &sg); + } + break; + case 6: + { + nth = RARRAY_AREF(a, 0); + jd = NUM2INT(RARRAY_AREF(a, 1)); + df = NUM2INT(RARRAY_AREF(a, 2)); + sf = RARRAY_AREF(a, 3); + of = NUM2INT(RARRAY_AREF(a, 4)); + sg = NUM2DBL(RARRAY_AREF(a, 5)); + } + break; + default: + rb_raise(rb_eTypeError, "invalid size"); + break; + } + + if (simple_dat_p(dat)) { + if (df || !f_zero_p(sf) || of) { + /* loading a fractional date; promote to complex */ + dat = ruby_xrealloc(dat, sizeof(struct ComplexDateData)); + RTYPEDDATA(self)->data = dat; + goto complex_data; + } + set_to_simple(self, &dat->s, nth, jd, sg, 0, 0, 0, HAVE_JD); + } else { + complex_data: + set_to_complex(self, &dat->c, nth, jd, df, sf, of, sg, + 0, 0, 0, 0, 0, 0, + HAVE_JD | HAVE_DF); + } + + if (FL_TEST(a, FL_EXIVAR)) { + rb_copy_generic_ivar(self, a); + FL_SET(self, FL_EXIVAR); + } + + return self; +} + +/* :nodoc: */ +static VALUE +date_s__load(VALUE klass, VALUE s) +{ + VALUE a, obj; + + a = rb_marshal_load(s); + obj = d_lite_s_alloc(klass); + return d_lite_marshal_load(obj, a); +} + +/* datetime */ + +/* + * call-seq: + * DateTime.jd([jd=0[, hour=0[, minute=0[, second=0[, offset=0[, start=Date::ITALY]]]]]]) -> datetime + * + * Creates a DateTime object denoting the given chronological Julian + * day number. + * + * DateTime.jd(2451944) #=> # + * DateTime.jd(2451945) #=> # + * DateTime.jd(Rational('0.5')) + * #=> # + */ +static VALUE +datetime_s_jd(int argc, VALUE *argv, VALUE klass) +{ + VALUE vjd, vh, vmin, vs, vof, vsg, jd, fr, fr2, ret; + int h, min, s, rof; + double sg; + + rb_scan_args(argc, argv, "06", &vjd, &vh, &vmin, &vs, &vof, &vsg); + + jd = INT2FIX(0); + + h = min = s = 0; + fr2 = INT2FIX(0); + rof = 0; + sg = DEFAULT_SG; + + switch (argc) { + case 6: + val2sg(vsg, sg); + case 5: + val2off(vof, rof); + case 4: + check_numeric(vs, "second"); + num2int_with_frac(s, positive_inf); + case 3: + check_numeric(vmin, "minute"); + num2int_with_frac(min, 3); + case 2: + check_numeric(vh, "hour"); + num2int_with_frac(h, 2); + case 1: + check_numeric(vjd, "jd"); + num2num_with_frac(jd, 1); + } + + { + VALUE nth; + int rh, rmin, rs, rjd, rjd2; + + if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs)) + rb_raise(eDateError, "invalid date"); + canon24oc(); + + decode_jd(jd, &nth, &rjd); + rjd2 = jd_local_to_utc(rjd, + time_to_df(rh, rmin, rs), + rof); + + ret = d_complex_new_internal(klass, + nth, rjd2, + 0, INT2FIX(0), + rof, sg, + 0, 0, 0, + rh, rmin, rs, + HAVE_JD | HAVE_TIME); + } + add_frac(); + return ret; +} + +/* + * call-seq: + * DateTime.ordinal([year=-4712[, yday=1[, hour=0[, minute=0[, second=0[, offset=0[, start=Date::ITALY]]]]]]]) -> datetime + * + * Creates a DateTime object denoting the given ordinal date. + * + * DateTime.ordinal(2001,34) #=> # + * DateTime.ordinal(2001,34,4,5,6,'+7') + * #=> # + * DateTime.ordinal(2001,-332,-20,-55,-54,'+7') + * #=> # + */ +static VALUE +datetime_s_ordinal(int argc, VALUE *argv, VALUE klass) +{ + VALUE vy, vd, vh, vmin, vs, vof, vsg, y, fr, fr2, ret; + int d, h, min, s, rof; + double sg; + + rb_scan_args(argc, argv, "07", &vy, &vd, &vh, &vmin, &vs, &vof, &vsg); + + y = INT2FIX(-4712); + d = 1; + + h = min = s = 0; + fr2 = INT2FIX(0); + rof = 0; + sg = DEFAULT_SG; + + switch (argc) { + case 7: + val2sg(vsg, sg); + case 6: + val2off(vof, rof); + case 5: + check_numeric(vs, "second"); + num2int_with_frac(s, positive_inf); + case 4: + check_numeric(vmin, "minute"); + num2int_with_frac(min, 4); + case 3: + check_numeric(vh, "hour"); + num2int_with_frac(h, 3); + case 2: + check_numeric(vd, "yday"); + num2int_with_frac(d, 2); + case 1: + check_numeric(vy, "year"); + y = vy; + } + + { + VALUE nth; + int ry, rd, rh, rmin, rs, rjd, rjd2, ns; + + if (!valid_ordinal_p(y, d, sg, + &nth, &ry, + &rd, &rjd, + &ns)) + rb_raise(eDateError, "invalid date"); + if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs)) + rb_raise(eDateError, "invalid date"); + canon24oc(); + + rjd2 = jd_local_to_utc(rjd, + time_to_df(rh, rmin, rs), + rof); + + ret = d_complex_new_internal(klass, + nth, rjd2, + 0, INT2FIX(0), + rof, sg, + 0, 0, 0, + rh, rmin, rs, + HAVE_JD | HAVE_TIME); + } + add_frac(); + return ret; +} + +/* + * Same as DateTime.new. + */ +static VALUE +datetime_s_civil(int argc, VALUE *argv, VALUE klass) +{ + return datetime_initialize(argc, argv, d_lite_s_alloc_complex(klass)); +} + +static VALUE +datetime_initialize(int argc, VALUE *argv, VALUE self) +{ + VALUE vy, vm, vd, vh, vmin, vs, vof, vsg, y, fr, fr2, ret; + int m, d, h, min, s, rof; + double sg; + struct ComplexDateData *dat = rb_check_typeddata(self, &d_lite_type); + + if (!complex_dat_p(dat)) { + rb_raise(rb_eTypeError, "DateTime expected"); + } + + rb_scan_args(argc, argv, "08", &vy, &vm, &vd, &vh, &vmin, &vs, &vof, &vsg); + + y = INT2FIX(-4712); + m = 1; + d = 1; + + h = min = s = 0; + fr2 = INT2FIX(0); + rof = 0; + sg = DEFAULT_SG; + + switch (argc) { + case 8: + val2sg(vsg, sg); + case 7: + val2off(vof, rof); + case 6: + check_numeric(vs, "second"); + num2int_with_frac(s, positive_inf); + case 5: + check_numeric(vmin, "minute"); + num2int_with_frac(min, 5); + case 4: + check_numeric(vh, "hour"); + num2int_with_frac(h, 4); + case 3: + check_numeric(vd, "day"); + num2int_with_frac(d, 3); + case 2: + check_numeric(vm, "month"); + m = NUM2INT(vm); + case 1: + check_numeric(vy, "year"); + y = vy; + } + + if (guess_style(y, sg) < 0) { + VALUE nth; + int ry, rm, rd, rh, rmin, rs; + + if (!valid_gregorian_p(y, m, d, + &nth, &ry, + &rm, &rd)) + rb_raise(eDateError, "invalid date"); + if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs)) + rb_raise(eDateError, "invalid date"); + canon24oc(); + + set_to_complex(self, dat, + nth, 0, + 0, INT2FIX(0), + rof, sg, + ry, rm, rd, + rh, rmin, rs, + HAVE_CIVIL | HAVE_TIME); + } + else { + VALUE nth; + int ry, rm, rd, rh, rmin, rs, rjd, rjd2, ns; + + if (!valid_civil_p(y, m, d, sg, + &nth, &ry, + &rm, &rd, &rjd, + &ns)) + rb_raise(eDateError, "invalid date"); + if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs)) + rb_raise(eDateError, "invalid date"); + canon24oc(); + + rjd2 = jd_local_to_utc(rjd, + time_to_df(rh, rmin, rs), + rof); + + set_to_complex(self, dat, + nth, rjd2, + 0, INT2FIX(0), + rof, sg, + ry, rm, rd, + rh, rmin, rs, + HAVE_JD | HAVE_CIVIL | HAVE_TIME); + } + ret = self; + add_frac(); + return ret; +} + +/* + * call-seq: + * DateTime.commercial([cwyear=-4712[, cweek=1[, cwday=1[, hour=0[, minute=0[, second=0[, offset=0[, start=Date::ITALY]]]]]]]]) -> datetime + * + * Creates a DateTime object denoting the given week date. + * + * DateTime.commercial(2001) #=> # + * DateTime.commercial(2002) #=> # + * DateTime.commercial(2001,5,6,4,5,6,'+7') + * #=> # + */ +static VALUE +datetime_s_commercial(int argc, VALUE *argv, VALUE klass) +{ + VALUE vy, vw, vd, vh, vmin, vs, vof, vsg, y, fr, fr2, ret; + int w, d, h, min, s, rof; + double sg; + + rb_scan_args(argc, argv, "08", &vy, &vw, &vd, &vh, &vmin, &vs, &vof, &vsg); + + y = INT2FIX(-4712); + w = 1; + d = 1; + + h = min = s = 0; + fr2 = INT2FIX(0); + rof = 0; + sg = DEFAULT_SG; + + switch (argc) { + case 8: + val2sg(vsg, sg); + case 7: + val2off(vof, rof); + case 6: + check_numeric(vs, "second"); + num2int_with_frac(s, positive_inf); + case 5: + check_numeric(vmin, "minute"); + num2int_with_frac(min, 5); + case 4: + check_numeric(vh, "hour"); + num2int_with_frac(h, 4); + case 3: + check_numeric(vd, "cwday"); + num2int_with_frac(d, 3); + case 2: + check_numeric(vw, "cweek"); + w = NUM2INT(vw); + case 1: + check_numeric(vy, "year"); + y = vy; + } + + { + VALUE nth; + int ry, rw, rd, rh, rmin, rs, rjd, rjd2, ns; + + if (!valid_commercial_p(y, w, d, sg, + &nth, &ry, + &rw, &rd, &rjd, + &ns)) + rb_raise(eDateError, "invalid date"); + if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs)) + rb_raise(eDateError, "invalid date"); + canon24oc(); + + rjd2 = jd_local_to_utc(rjd, + time_to_df(rh, rmin, rs), + rof); + + ret = d_complex_new_internal(klass, + nth, rjd2, + 0, INT2FIX(0), + rof, sg, + 0, 0, 0, + rh, rmin, rs, + HAVE_JD | HAVE_TIME); + } + add_frac(); + return ret; +} + +#ifndef NDEBUG +/* :nodoc: */ +static VALUE +datetime_s_weeknum(int argc, VALUE *argv, VALUE klass) +{ + VALUE vy, vw, vd, vf, vh, vmin, vs, vof, vsg, y, fr, fr2, ret; + int w, d, f, h, min, s, rof; + double sg; + + rb_scan_args(argc, argv, "09", &vy, &vw, &vd, &vf, + &vh, &vmin, &vs, &vof, &vsg); + + y = INT2FIX(-4712); + w = 0; + d = 1; + f = 0; + + h = min = s = 0; + fr2 = INT2FIX(0); + rof = 0; + sg = DEFAULT_SG; + + switch (argc) { + case 9: + val2sg(vsg, sg); + case 8: + val2off(vof, rof); + case 7: + num2int_with_frac(s, positive_inf); + case 6: + num2int_with_frac(min, 6); + case 5: + num2int_with_frac(h, 5); + case 4: + f = NUM2INT(vf); + case 3: + num2int_with_frac(d, 4); + case 2: + w = NUM2INT(vw); + case 1: + y = vy; + } + + { + VALUE nth; + int ry, rw, rd, rh, rmin, rs, rjd, rjd2, ns; + + if (!valid_weeknum_p(y, w, d, f, sg, + &nth, &ry, + &rw, &rd, &rjd, + &ns)) + rb_raise(eDateError, "invalid date"); + if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs)) + rb_raise(eDateError, "invalid date"); + canon24oc(); + + rjd2 = jd_local_to_utc(rjd, + time_to_df(rh, rmin, rs), + rof); + ret = d_complex_new_internal(klass, + nth, rjd2, + 0, INT2FIX(0), + rof, sg, + 0, 0, 0, + rh, rmin, rs, + HAVE_JD | HAVE_TIME); + } + add_frac(); + return ret; +} + +/* :nodoc: */ +static VALUE +datetime_s_nth_kday(int argc, VALUE *argv, VALUE klass) +{ + VALUE vy, vm, vn, vk, vh, vmin, vs, vof, vsg, y, fr, fr2, ret; + int m, n, k, h, min, s, rof; + double sg; + + rb_scan_args(argc, argv, "09", &vy, &vm, &vn, &vk, + &vh, &vmin, &vs, &vof, &vsg); + + y = INT2FIX(-4712); + m = 1; + n = 1; + k = 1; + + h = min = s = 0; + fr2 = INT2FIX(0); + rof = 0; + sg = DEFAULT_SG; + + switch (argc) { + case 9: + val2sg(vsg, sg); + case 8: + val2off(vof, rof); + case 7: + num2int_with_frac(s, positive_inf); + case 6: + num2int_with_frac(min, 6); + case 5: + num2int_with_frac(h, 5); + case 4: + num2int_with_frac(k, 4); + case 3: + n = NUM2INT(vn); + case 2: + m = NUM2INT(vm); + case 1: + y = vy; + } + + { + VALUE nth; + int ry, rm, rn, rk, rh, rmin, rs, rjd, rjd2, ns; + + if (!valid_nth_kday_p(y, m, n, k, sg, + &nth, &ry, + &rm, &rn, &rk, &rjd, + &ns)) + rb_raise(eDateError, "invalid date"); + if (!c_valid_time_p(h, min, s, &rh, &rmin, &rs)) + rb_raise(eDateError, "invalid date"); + canon24oc(); + + rjd2 = jd_local_to_utc(rjd, + time_to_df(rh, rmin, rs), + rof); + ret = d_complex_new_internal(klass, + nth, rjd2, + 0, INT2FIX(0), + rof, sg, + 0, 0, 0, + rh, rmin, rs, + HAVE_JD | HAVE_TIME); + } + add_frac(); + return ret; +} +#endif + +/* + * call-seq: + * DateTime.now([start=Date::ITALY]) -> datetime + * + * Creates a DateTime object denoting the present time. + * + * DateTime.now #=> # + */ +static VALUE +datetime_s_now(int argc, VALUE *argv, VALUE klass) +{ + VALUE vsg, nth, ret; + double sg; +#ifdef HAVE_CLOCK_GETTIME + struct timespec ts; +#else + struct timeval tv; +#endif + time_t sec; + struct tm tm; + long sf, of; + int y, ry, m, d, h, min, s; + + rb_scan_args(argc, argv, "01", &vsg); + + if (argc < 1) + sg = DEFAULT_SG; + else + sg = NUM2DBL(vsg); + +#ifdef HAVE_CLOCK_GETTIME + if (clock_gettime(CLOCK_REALTIME, &ts) == -1) + rb_sys_fail("clock_gettime"); + sec = ts.tv_sec; +#else + if (gettimeofday(&tv, NULL) == -1) + rb_sys_fail("gettimeofday"); + sec = tv.tv_sec; +#endif + tzset(); + if (!localtime_r(&sec, &tm)) + rb_sys_fail("localtime"); + + y = tm.tm_year + 1900; + m = tm.tm_mon + 1; + d = tm.tm_mday; + h = tm.tm_hour; + min = tm.tm_min; + s = tm.tm_sec; + if (s == 60) + s = 59; +#ifdef HAVE_STRUCT_TM_TM_GMTOFF + of = tm.tm_gmtoff; +#elif defined(HAVE_TIMEZONE) +#if defined(HAVE_ALTZONE) && !defined(_AIX) + of = (long)-((tm.tm_isdst > 0) ? altzone : timezone); +#else + of = (long)-timezone; + if (tm.tm_isdst) { + time_t sec2; + + tm.tm_isdst = 0; + sec2 = mktime(&tm); + of += (long)difftime(sec2, sec); + } +#endif +#elif defined(HAVE_TIMEGM) + { + time_t sec2; + + sec2 = timegm(&tm); + of = (long)difftime(sec2, sec); + } +#else + { + struct tm tm2; + time_t sec2; + + if (!gmtime_r(&sec, &tm2)) + rb_sys_fail("gmtime"); + tm2.tm_isdst = tm.tm_isdst; + sec2 = mktime(&tm2); + of = (long)difftime(sec, sec2); + } +#endif +#ifdef HAVE_CLOCK_GETTIME + sf = ts.tv_nsec; +#else + sf = tv.tv_usec * 1000; +#endif + + if (of < -DAY_IN_SECONDS || of > DAY_IN_SECONDS) { + of = 0; + rb_warning("invalid offset is ignored"); + } + + decode_year(INT2FIX(y), -1, &nth, &ry); + + ret = d_complex_new_internal(klass, + nth, 0, + 0, LONG2NUM(sf), + (int)of, GREGORIAN, + ry, m, d, + h, min, s, + HAVE_CIVIL | HAVE_TIME); + { + get_d1(ret); + set_sg(dat, sg); + } + return ret; +} + +static VALUE +dt_new_by_frags(VALUE klass, VALUE hash, VALUE sg) +{ + VALUE jd, sf, t; + int df, of; + + if (!c_valid_start_p(NUM2DBL(sg))) { + sg = INT2FIX(DEFAULT_SG); + rb_warning("invalid start is ignored"); + } + + if (NIL_P(hash)) + rb_raise(eDateError, "invalid date"); + + if (NIL_P(ref_hash("jd")) && + NIL_P(ref_hash("yday")) && + !NIL_P(ref_hash("year")) && + !NIL_P(ref_hash("mon")) && + !NIL_P(ref_hash("mday"))) { + jd = rt__valid_civil_p(ref_hash("year"), + ref_hash("mon"), + ref_hash("mday"), sg); + + if (NIL_P(ref_hash("hour"))) + set_hash("hour", INT2FIX(0)); + if (NIL_P(ref_hash("min"))) + set_hash("min", INT2FIX(0)); + if (NIL_P(ref_hash("sec"))) + set_hash("sec", INT2FIX(0)); + else if (f_eqeq_p(ref_hash("sec"), INT2FIX(60))) + set_hash("sec", INT2FIX(59)); + } + else { + hash = rt_rewrite_frags(hash); + hash = rt_complete_frags(klass, hash); + jd = rt__valid_date_frags_p(hash, sg); + } + + if (NIL_P(jd)) + rb_raise(eDateError, "invalid date"); + + { + int rh, rmin, rs; + + if (!c_valid_time_p(NUM2INT(ref_hash("hour")), + NUM2INT(ref_hash("min")), + NUM2INT(ref_hash("sec")), + &rh, &rmin, &rs)) + rb_raise(eDateError, "invalid date"); + + df = time_to_df(rh, rmin, rs); + } + + t = ref_hash("sec_fraction"); + if (NIL_P(t)) + sf = INT2FIX(0); + else + sf = sec_to_ns(t); + + t = ref_hash("offset"); + if (NIL_P(t)) + of = 0; + else { + of = NUM2INT(t); + if (of < -DAY_IN_SECONDS || of > DAY_IN_SECONDS) { + of = 0; + rb_warning("invalid offset is ignored"); + } + } + { + VALUE nth; + int rjd, rjd2; + + decode_jd(jd, &nth, &rjd); + rjd2 = jd_local_to_utc(rjd, df, of); + df = df_local_to_utc(df, of); + + return d_complex_new_internal(klass, + nth, rjd2, + df, sf, + of, NUM2DBL(sg), + 0, 0, 0, + 0, 0, 0, + HAVE_JD | HAVE_DF); + } +} + +/* + * call-seq: + * DateTime._strptime(string[, format='%FT%T%z']) -> hash + * + * Parses the given representation of date and time with the given + * template, and returns a hash of parsed elements. _strptime does + * not support specification of flags and width unlike strftime. + * + * See also strptime(3) and #strftime. + */ +static VALUE +datetime_s__strptime(int argc, VALUE *argv, VALUE klass) +{ + return date_s__strptime_internal(argc, argv, klass, "%FT%T%z"); +} + +/* + * call-seq: + * DateTime.strptime([string='-4712-01-01T00:00:00+00:00'[, format='%FT%T%z'[ ,start=Date::ITALY]]]) -> datetime + * + * Parses the given representation of date and time with the given + * template, and creates a DateTime object. strptime does not support + * specification of flags and width unlike strftime. + * + * DateTime.strptime('2001-02-03T04:05:06+07:00', '%Y-%m-%dT%H:%M:%S%z') + * #=> # + * DateTime.strptime('03-02-2001 04:05:06 PM', '%d-%m-%Y %I:%M:%S %p') + * #=> # + * DateTime.strptime('2001-W05-6T04:05:06+07:00', '%G-W%V-%uT%H:%M:%S%z') + * #=> # + * DateTime.strptime('2001 04 6 04 05 06 +7', '%Y %U %w %H %M %S %z') + * #=> # + * DateTime.strptime('2001 05 6 04 05 06 +7', '%Y %W %u %H %M %S %z') + * #=> # + * DateTime.strptime('-1', '%s') + * #=> # + * DateTime.strptime('-1000', '%Q') + * #=> # + * DateTime.strptime('sat3feb014pm+7', '%a%d%b%y%H%p%z') + * #=> # + * + * See also strptime(3) and #strftime. + */ +static VALUE +datetime_s_strptime(int argc, VALUE *argv, VALUE klass) +{ + VALUE str, fmt, sg; + + rb_scan_args(argc, argv, "03", &str, &fmt, &sg); + + switch (argc) { + case 0: + str = rb_str_new2(JULIAN_EPOCH_DATETIME); + case 1: + fmt = rb_str_new2("%FT%T%z"); + case 2: + sg = INT2FIX(DEFAULT_SG); + } + + { + VALUE argv2[2], hash; + + argv2[0] = str; + argv2[1] = fmt; + hash = date_s__strptime(2, argv2, klass); + return dt_new_by_frags(klass, hash, sg); + } +} + +/* + * call-seq: + * DateTime.parse(string='-4712-01-01T00:00:00+00:00'[, comp=true[, start=Date::ITALY]], limit: 128) -> datetime + * + * Parses the given representation of date and time, and creates a + * DateTime object. + * + * This method *does* *not* function as a validator. If the input + * string does not match valid formats strictly, you may get a cryptic + * result. Should consider to use DateTime.strptime instead of this + * method as possible. + * + * If the optional second argument is true and the detected year is in + * the range "00" to "99", makes it full. + * + * DateTime.parse('2001-02-03T04:05:06+07:00') + * #=> # + * DateTime.parse('20010203T040506+0700') + * #=> # + * DateTime.parse('3rd Feb 2001 04:05:06 PM') + * #=> # + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. + */ +static VALUE +datetime_s_parse(int argc, VALUE *argv, VALUE klass) +{ + VALUE str, comp, sg, opt; + + argc = rb_scan_args(argc, argv, "03:", &str, &comp, &sg, &opt); + + switch (argc) { + case 0: + str = rb_str_new2(JULIAN_EPOCH_DATETIME); + case 1: + comp = Qtrue; + case 2: + sg = INT2FIX(DEFAULT_SG); + } + + { + int argc2 = 2; + VALUE argv2[3], hash; + argv2[0] = str; + argv2[1] = comp; + argv2[2] = opt; + if (!NIL_P(opt)) argc2++; + hash = date_s__parse(argc2, argv2, klass); + return dt_new_by_frags(klass, hash, sg); + } +} + +/* + * call-seq: + * DateTime.iso8601(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime + * + * Creates a new DateTime object by parsing from a string according to + * some typical ISO 8601 formats. + * + * DateTime.iso8601('2001-02-03T04:05:06+07:00') + * #=> # + * DateTime.iso8601('20010203T040506+0700') + * #=> # + * DateTime.iso8601('2001-W05-6T04:05:06+07:00') + * #=> # + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. + */ +static VALUE +datetime_s_iso8601(int argc, VALUE *argv, VALUE klass) +{ + VALUE str, sg, opt; + + argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt); + + switch (argc) { + case 0: + str = rb_str_new2(JULIAN_EPOCH_DATETIME); + case 1: + sg = INT2FIX(DEFAULT_SG); + } + + { + int argc2 = 1; + VALUE argv2[2], hash; + argv2[0] = str; + argv2[1] = opt; + if (!NIL_P(opt)) argc2++; + hash = date_s__iso8601(argc2, argv2, klass); + return dt_new_by_frags(klass, hash, sg); + } +} + +/* + * call-seq: + * DateTime.rfc3339(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime + * + * Creates a new DateTime object by parsing from a string according to + * some typical RFC 3339 formats. + * + * DateTime.rfc3339('2001-02-03T04:05:06+07:00') + * #=> # + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. + */ +static VALUE +datetime_s_rfc3339(int argc, VALUE *argv, VALUE klass) +{ + VALUE str, sg, opt; + + argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt); + + switch (argc) { + case 0: + str = rb_str_new2(JULIAN_EPOCH_DATETIME); + case 1: + sg = INT2FIX(DEFAULT_SG); + } + + { + int argc2 = 1; + VALUE argv2[2], hash; + argv2[0] = str; + argv2[1] = opt; + if (!NIL_P(opt)) argc2++; + hash = date_s__rfc3339(argc2, argv2, klass); + return dt_new_by_frags(klass, hash, sg); + } +} + +/* + * call-seq: + * DateTime.xmlschema(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime + * + * Creates a new DateTime object by parsing from a string according to + * some typical XML Schema formats. + * + * DateTime.xmlschema('2001-02-03T04:05:06+07:00') + * #=> # + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. + */ +static VALUE +datetime_s_xmlschema(int argc, VALUE *argv, VALUE klass) +{ + VALUE str, sg, opt; + + argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt); + + switch (argc) { + case 0: + str = rb_str_new2(JULIAN_EPOCH_DATETIME); + case 1: + sg = INT2FIX(DEFAULT_SG); + } + + { + int argc2 = 1; + VALUE argv2[2], hash; + argv2[0] = str; + argv2[1] = opt; + if (!NIL_P(opt)) argc2++; + hash = date_s__xmlschema(argc2, argv2, klass); + return dt_new_by_frags(klass, hash, sg); + } +} + +/* + * call-seq: + * DateTime.rfc2822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) -> datetime + * DateTime.rfc822(string='Mon, 1 Jan -4712 00:00:00 +0000'[, start=Date::ITALY], limit: 128) -> datetime + * + * Creates a new DateTime object by parsing from a string according to + * some typical RFC 2822 formats. + * + * DateTime.rfc2822('Sat, 3 Feb 2001 04:05:06 +0700') + * #=> # + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. + */ +static VALUE +datetime_s_rfc2822(int argc, VALUE *argv, VALUE klass) +{ + VALUE str, sg, opt; + + argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt); + + switch (argc) { + case 0: + str = rb_str_new2(JULIAN_EPOCH_DATETIME_RFC3339); + case 1: + sg = INT2FIX(DEFAULT_SG); + } + + { + int argc2 = 1; + VALUE argv2[2], hash; + argv2[0] = str; + argv2[1] = opt; + if (!NIL_P(opt)) argc2++; + hash = date_s__rfc2822(argc2, argv2, klass); + return dt_new_by_frags(klass, hash, sg); + } +} + +/* + * call-seq: + * DateTime.httpdate(string='Mon, 01 Jan -4712 00:00:00 GMT'[, start=Date::ITALY]) -> datetime + * + * Creates a new DateTime object by parsing from a string according to + * some RFC 2616 format. + * + * DateTime.httpdate('Sat, 03 Feb 2001 04:05:06 GMT') + * #=> # + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. + */ +static VALUE +datetime_s_httpdate(int argc, VALUE *argv, VALUE klass) +{ + VALUE str, sg, opt; + + argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt); + + switch (argc) { + case 0: + str = rb_str_new2(JULIAN_EPOCH_DATETIME_HTTPDATE); + case 1: + sg = INT2FIX(DEFAULT_SG); + } + + { + int argc2 = 1; + VALUE argv2[2], hash; + argv2[0] = str; + argv2[1] = opt; + if (!NIL_P(opt)) argc2++; + hash = date_s__httpdate(argc2, argv2, klass); + return dt_new_by_frags(klass, hash, sg); + } +} + +/* + * call-seq: + * DateTime.jisx0301(string='-4712-01-01T00:00:00+00:00'[, start=Date::ITALY], limit: 128) -> datetime + * + * Creates a new DateTime object by parsing from a string according to + * some typical JIS X 0301 formats. + * + * DateTime.jisx0301('H13.02.03T04:05:06+07:00') + * #=> # + * + * For no-era year, legacy format, Heisei is assumed. + * + * DateTime.jisx0301('13.02.03T04:05:06+07:00') + * #=> # + * + * Raise an ArgumentError when the string length is longer than _limit_. + * You can stop this check by passing limit: nil, but note + * that it may take a long time to parse. + */ +static VALUE +datetime_s_jisx0301(int argc, VALUE *argv, VALUE klass) +{ + VALUE str, sg, opt; + + argc = rb_scan_args(argc, argv, "02:", &str, &sg, &opt); + + switch (argc) { + case 0: + str = rb_str_new2(JULIAN_EPOCH_DATETIME); + case 1: + sg = INT2FIX(DEFAULT_SG); + } + + { + int argc2 = 1; + VALUE argv2[2], hash; + argv2[0] = str; + argv2[1] = opt; + if (!NIL_P(opt)) argc2++; + hash = date_s__jisx0301(argc2, argv2, klass); + return dt_new_by_frags(klass, hash, sg); + } +} + +/* + * call-seq: + * dt.to_s -> string + * + * Returns a string in an ISO 8601 format. (This method doesn't use the + * expanded representations.) + * + * DateTime.new(2001,2,3,4,5,6,'-7').to_s + * #=> "2001-02-03T04:05:06-07:00" + */ +static VALUE +dt_lite_to_s(VALUE self) +{ + return strftimev("%Y-%m-%dT%H:%M:%S%:z", self, set_tmx); +} + +/* + * call-seq: + * strftime(format = '%FT%T%:z') -> string + * + * Returns a string representation of +self+, + * formatted according the given +format: + * + * DateTime.now.strftime # => "2022-07-01T11:03:19-05:00" + * + * For other formats, + * see {Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html]: + * + */ +static VALUE +dt_lite_strftime(int argc, VALUE *argv, VALUE self) +{ + return date_strftime_internal(argc, argv, self, + "%Y-%m-%dT%H:%M:%S%:z", set_tmx); +} + +static VALUE +iso8601_timediv(VALUE self, long n) +{ + static const char timefmt[] = "T%H:%M:%S"; + static const char zone[] = "%:z"; + char fmt[sizeof(timefmt) + sizeof(zone) + rb_strlen_lit(".%N") + + DECIMAL_SIZE_OF_LONG]; + char *p = fmt; + + memcpy(p, timefmt, sizeof(timefmt)-1); + p += sizeof(timefmt)-1; + if (n > 0) p += snprintf(p, fmt+sizeof(fmt)-p, ".%%%ldN", n); + memcpy(p, zone, sizeof(zone)); + return strftimev(fmt, self, set_tmx); +} + +/* + * call-seq: + * dt.iso8601([n=0]) -> string + * dt.xmlschema([n=0]) -> string + * + * This method is equivalent to strftime('%FT%T%:z'). + * The optional argument +n+ is the number of digits for fractional seconds. + * + * DateTime.parse('2001-02-03T04:05:06.123456789+07:00').iso8601(9) + * #=> "2001-02-03T04:05:06.123456789+07:00" + */ +static VALUE +dt_lite_iso8601(int argc, VALUE *argv, VALUE self) +{ + long n = 0; + + rb_check_arity(argc, 0, 1); + if (argc >= 1) + n = NUM2LONG(argv[0]); + + return rb_str_append(strftimev("%Y-%m-%d", self, set_tmx), + iso8601_timediv(self, n)); +} + +/* + * call-seq: + * dt.rfc3339([n=0]) -> string + * + * This method is equivalent to strftime('%FT%T%:z'). + * The optional argument +n+ is the number of digits for fractional seconds. + * + * DateTime.parse('2001-02-03T04:05:06.123456789+07:00').rfc3339(9) + * #=> "2001-02-03T04:05:06.123456789+07:00" + */ +static VALUE +dt_lite_rfc3339(int argc, VALUE *argv, VALUE self) +{ + return dt_lite_iso8601(argc, argv, self); +} + +/* + * call-seq: + * dt.jisx0301([n=0]) -> string + * + * Returns a string in a JIS X 0301 format. + * The optional argument +n+ is the number of digits for fractional seconds. + * + * DateTime.parse('2001-02-03T04:05:06.123456789+07:00').jisx0301(9) + * #=> "H13.02.03T04:05:06.123456789+07:00" + */ +static VALUE +dt_lite_jisx0301(int argc, VALUE *argv, VALUE self) +{ + long n = 0; + + rb_check_arity(argc, 0, 1); + if (argc >= 1) + n = NUM2LONG(argv[0]); + + return rb_str_append(d_lite_jisx0301(self), + iso8601_timediv(self, n)); +} + +/* + * call-seq: + * deconstruct_keys(array_of_names_or_nil) -> hash + * + * Returns a hash of the name/value pairs, to use in pattern matching. + * Possible keys are: :year, :month, :day, + * :wday, :yday, :hour, :min, + * :sec, :sec_fraction, :zone. + * + * Possible usages: + * + * dt = DateTime.new(2022, 10, 5, 13, 30) + * + * if d in wday: 1..5, hour: 10..18 # uses deconstruct_keys underneath + * puts "Working time" + * end + * #=> prints "Working time" + * + * case dt + * in year: ...2022 + * puts "too old" + * in month: ..9 + * puts "quarter 1-3" + * in wday: 1..5, month: + * puts "working day in month #{month}" + * end + * #=> prints "working day in month 10" + * + * Note that deconstruction by pattern can also be combined with class check: + * + * if d in DateTime(wday: 1..5, hour: 10..18, day: ..7) + * puts "Working time, first week of the month" + * end + * + */ +static VALUE +dt_lite_deconstruct_keys(VALUE self, VALUE keys) +{ + return deconstruct_keys(self, keys, /* is_datetime=true */ 1); +} + +/* conversions */ + +#define f_subsec(x) rb_funcall(x, rb_intern("subsec"), 0) +#define f_utc_offset(x) rb_funcall(x, rb_intern("utc_offset"), 0) +#define f_local3(x,y,m,d) rb_funcall(x, rb_intern("local"), 3, y, m, d) + +/* + * call-seq: + * t.to_time -> time + * + * Returns self. + */ +static VALUE +time_to_time(VALUE self) +{ + return self; +} + +/* + * call-seq: + * t.to_date -> date + * + * Returns a Date object which denotes self. + */ +static VALUE +time_to_date(VALUE self) +{ + VALUE y, nth, ret; + int ry, m, d; + + y = f_year(self); + m = FIX2INT(f_mon(self)); + d = FIX2INT(f_mday(self)); + + decode_year(y, -1, &nth, &ry); + + ret = d_simple_new_internal(cDate, + nth, 0, + GREGORIAN, + ry, m, d, + HAVE_CIVIL); + { + get_d1(ret); + set_sg(dat, DEFAULT_SG); + } + return ret; +} + +/* + * call-seq: + * t.to_datetime -> datetime + * + * Returns a DateTime object which denotes self. + */ +static VALUE +time_to_datetime(VALUE self) +{ + VALUE y, sf, nth, ret; + int ry, m, d, h, min, s, of; + + y = f_year(self); + m = FIX2INT(f_mon(self)); + d = FIX2INT(f_mday(self)); + + h = FIX2INT(f_hour(self)); + min = FIX2INT(f_min(self)); + s = FIX2INT(f_sec(self)); + if (s == 60) + s = 59; + + sf = sec_to_ns(f_subsec(self)); + of = FIX2INT(f_utc_offset(self)); + + decode_year(y, -1, &nth, &ry); + + ret = d_complex_new_internal(cDateTime, + nth, 0, + 0, sf, + of, GREGORIAN, + ry, m, d, + h, min, s, + HAVE_CIVIL | HAVE_TIME); + { + get_d1(ret); + set_sg(dat, DEFAULT_SG); + } + return ret; +} + +/* + * call-seq: + * to_time -> time + * + * Returns a new Time object with the same value as +self+; + * if +self+ is a Julian date, derives its Gregorian date + * for conversion to the \Time object: + * + * Date.new(2001, 2, 3).to_time # => 2001-02-03 00:00:00 -0600 + * Date.new(2001, 2, 3, Date::JULIAN).to_time # => 2001-02-16 00:00:00 -0600 + * + */ +static VALUE +date_to_time(VALUE self) +{ + VALUE t; + + get_d1a(self); + + if (m_julian_p(adat)) { + VALUE g = d_lite_gregorian(self); + get_d1b(g); + adat = bdat; + self = g; + } + + t = f_local3(rb_cTime, + m_real_year(adat), + INT2FIX(m_mon(adat)), + INT2FIX(m_mday(adat))); + RB_GC_GUARD(self); /* may be the converted gregorian */ + return t; +} + +/* + * call-seq: + * to_date -> self + * + * Returns +self+. + */ +static VALUE +date_to_date(VALUE self) +{ + return self; +} + +/* + * call-seq: + * d.to_datetime -> datetime + * + * Returns a DateTime whose value is the same as +self+: + * + * Date.new(2001, 2, 3).to_datetime # => # + * + */ +static VALUE +date_to_datetime(VALUE self) +{ + get_d1a(self); + + if (simple_dat_p(adat)) { + VALUE new = d_lite_s_alloc_simple(cDateTime); + { + get_d1b(new); + bdat->s = adat->s; + return new; + } + } + else { + VALUE new = d_lite_s_alloc_complex(cDateTime); + { + get_d1b(new); + bdat->c = adat->c; + bdat->c.df = 0; + RB_OBJ_WRITE(new, &bdat->c.sf, INT2FIX(0)); +#ifndef USE_PACK + bdat->c.hour = 0; + bdat->c.min = 0; + bdat->c.sec = 0; +#else + bdat->c.pc = PACK5(EX_MON(adat->c.pc), EX_MDAY(adat->c.pc), + 0, 0, 0); + bdat->c.flags |= HAVE_DF | HAVE_TIME; +#endif + return new; + } + } +} + +/* + * call-seq: + * dt.to_time -> time + * + * Returns a Time object which denotes self. + */ +static VALUE +datetime_to_time(VALUE self) +{ + get_d1(self); + + if (m_julian_p(dat)) { + VALUE g = d_lite_gregorian(self); + get_d1a(g); + dat = adat; + self = g; + } + + { + VALUE t; + + t = rb_funcall(rb_cTime, + rb_intern("new"), + 7, + m_real_year(dat), + INT2FIX(m_mon(dat)), + INT2FIX(m_mday(dat)), + INT2FIX(m_hour(dat)), + INT2FIX(m_min(dat)), + f_add(INT2FIX(m_sec(dat)), + m_sf_in_sec(dat)), + INT2FIX(m_of(dat))); + RB_GC_GUARD(self); /* may be the converted gregorian */ + return t; + } +} + +/* + * call-seq: + * dt.to_date -> date + * + * Returns a Date object which denotes self. + */ +static VALUE +datetime_to_date(VALUE self) +{ + get_d1a(self); + + if (simple_dat_p(adat)) { + VALUE new = d_lite_s_alloc_simple(cDate); + { + get_d1b(new); + bdat->s = adat->s; + bdat->s.jd = m_local_jd(adat); + return new; + } + } + else { + VALUE new = d_lite_s_alloc_simple(cDate); + { + get_d1b(new); + copy_complex_to_simple(new, &bdat->s, &adat->c); + bdat->s.jd = m_local_jd(adat); + bdat->s.flags &= ~(HAVE_DF | HAVE_TIME | COMPLEX_DAT); + return new; + } + } +} + +/* + * call-seq: + * dt.to_datetime -> self + * + * Returns self. + */ +static VALUE +datetime_to_datetime(VALUE self) +{ + return self; +} + +#ifndef NDEBUG +/* tests */ + +#define MIN_YEAR -4713 +#define MAX_YEAR 1000000 +#define MIN_JD -327 +#define MAX_JD 366963925 + +/* :nodoc: */ +static int +test_civil(int from, int to, double sg) +{ + int j; + + fprintf(stderr, "test_civil: %d...%d (%d) - %.0f\n", + from, to, to - from, sg); + for (j = from; j <= to; j++) { + int y, m, d, rj, ns; + + c_jd_to_civil(j, sg, &y, &m, &d); + c_civil_to_jd(y, m, d, sg, &rj, &ns); + if (j != rj) { + fprintf(stderr, "%d != %d\n", j, rj); + return 0; + } + } + return 1; +} + +/* :nodoc: */ +static VALUE +date_s_test_civil(VALUE klass) +{ + if (!test_civil(MIN_JD, MIN_JD + 366, GREGORIAN)) + return Qfalse; + if (!test_civil(2305814, 2598007, GREGORIAN)) + return Qfalse; + if (!test_civil(MAX_JD - 366, MAX_JD, GREGORIAN)) + return Qfalse; + + if (!test_civil(MIN_JD, MIN_JD + 366, ITALY)) + return Qfalse; + if (!test_civil(2305814, 2598007, ITALY)) + return Qfalse; + if (!test_civil(MAX_JD - 366, MAX_JD, ITALY)) + return Qfalse; + + return Qtrue; +} + +/* :nodoc: */ +static int +test_ordinal(int from, int to, double sg) +{ + int j; + + fprintf(stderr, "test_ordinal: %d...%d (%d) - %.0f\n", + from, to, to - from, sg); + for (j = from; j <= to; j++) { + int y, d, rj, ns; + + c_jd_to_ordinal(j, sg, &y, &d); + c_ordinal_to_jd(y, d, sg, &rj, &ns); + if (j != rj) { + fprintf(stderr, "%d != %d\n", j, rj); + return 0; + } + } + return 1; +} + +/* :nodoc: */ +static VALUE +date_s_test_ordinal(VALUE klass) +{ + if (!test_ordinal(MIN_JD, MIN_JD + 366, GREGORIAN)) + return Qfalse; + if (!test_ordinal(2305814, 2598007, GREGORIAN)) + return Qfalse; + if (!test_ordinal(MAX_JD - 366, MAX_JD, GREGORIAN)) + return Qfalse; + + if (!test_ordinal(MIN_JD, MIN_JD + 366, ITALY)) + return Qfalse; + if (!test_ordinal(2305814, 2598007, ITALY)) + return Qfalse; + if (!test_ordinal(MAX_JD - 366, MAX_JD, ITALY)) + return Qfalse; + + return Qtrue; +} + +/* :nodoc: */ +static int +test_commercial(int from, int to, double sg) +{ + int j; + + fprintf(stderr, "test_commercial: %d...%d (%d) - %.0f\n", + from, to, to - from, sg); + for (j = from; j <= to; j++) { + int y, w, d, rj, ns; + + c_jd_to_commercial(j, sg, &y, &w, &d); + c_commercial_to_jd(y, w, d, sg, &rj, &ns); + if (j != rj) { + fprintf(stderr, "%d != %d\n", j, rj); + return 0; + } + } + return 1; +} + +/* :nodoc: */ +static VALUE +date_s_test_commercial(VALUE klass) +{ + if (!test_commercial(MIN_JD, MIN_JD + 366, GREGORIAN)) + return Qfalse; + if (!test_commercial(2305814, 2598007, GREGORIAN)) + return Qfalse; + if (!test_commercial(MAX_JD - 366, MAX_JD, GREGORIAN)) + return Qfalse; + + if (!test_commercial(MIN_JD, MIN_JD + 366, ITALY)) + return Qfalse; + if (!test_commercial(2305814, 2598007, ITALY)) + return Qfalse; + if (!test_commercial(MAX_JD - 366, MAX_JD, ITALY)) + return Qfalse; + + return Qtrue; +} + +/* :nodoc: */ +static int +test_weeknum(int from, int to, int f, double sg) +{ + int j; + + fprintf(stderr, "test_weeknum: %d...%d (%d) - %.0f\n", + from, to, to - from, sg); + for (j = from; j <= to; j++) { + int y, w, d, rj, ns; + + c_jd_to_weeknum(j, f, sg, &y, &w, &d); + c_weeknum_to_jd(y, w, d, f, sg, &rj, &ns); + if (j != rj) { + fprintf(stderr, "%d != %d\n", j, rj); + return 0; + } + } + return 1; +} + +/* :nodoc: */ +static VALUE +date_s_test_weeknum(VALUE klass) +{ + int f; + + for (f = 0; f <= 1; f++) { + if (!test_weeknum(MIN_JD, MIN_JD + 366, f, GREGORIAN)) + return Qfalse; + if (!test_weeknum(2305814, 2598007, f, GREGORIAN)) + return Qfalse; + if (!test_weeknum(MAX_JD - 366, MAX_JD, f, GREGORIAN)) + return Qfalse; + + if (!test_weeknum(MIN_JD, MIN_JD + 366, f, ITALY)) + return Qfalse; + if (!test_weeknum(2305814, 2598007, f, ITALY)) + return Qfalse; + if (!test_weeknum(MAX_JD - 366, MAX_JD, f, ITALY)) + return Qfalse; + } + + return Qtrue; +} + +/* :nodoc: */ +static int +test_nth_kday(int from, int to, double sg) +{ + int j; + + fprintf(stderr, "test_nth_kday: %d...%d (%d) - %.0f\n", + from, to, to - from, sg); + for (j = from; j <= to; j++) { + int y, m, n, k, rj, ns; + + c_jd_to_nth_kday(j, sg, &y, &m, &n, &k); + c_nth_kday_to_jd(y, m, n, k, sg, &rj, &ns); + if (j != rj) { + fprintf(stderr, "%d != %d\n", j, rj); + return 0; + } + } + return 1; +} + +/* :nodoc: */ +static VALUE +date_s_test_nth_kday(VALUE klass) +{ + if (!test_nth_kday(MIN_JD, MIN_JD + 366, GREGORIAN)) + return Qfalse; + if (!test_nth_kday(2305814, 2598007, GREGORIAN)) + return Qfalse; + if (!test_nth_kday(MAX_JD - 366, MAX_JD, GREGORIAN)) + return Qfalse; + + if (!test_nth_kday(MIN_JD, MIN_JD + 366, ITALY)) + return Qfalse; + if (!test_nth_kday(2305814, 2598007, ITALY)) + return Qfalse; + if (!test_nth_kday(MAX_JD - 366, MAX_JD, ITALY)) + return Qfalse; + + return Qtrue; +} + +/* :nodoc: */ +static int +test_unit_v2v(VALUE i, + VALUE (* conv1)(VALUE), + VALUE (* conv2)(VALUE)) +{ + VALUE c, o; + c = (*conv1)(i); + o = (*conv2)(c); + return f_eqeq_p(o, i); +} + +/* :nodoc: */ +static int +test_unit_v2v_iter2(VALUE (* conv1)(VALUE), + VALUE (* conv2)(VALUE)) +{ + if (!test_unit_v2v(INT2FIX(0), conv1, conv2)) + return 0; + if (!test_unit_v2v(INT2FIX(1), conv1, conv2)) + return 0; + if (!test_unit_v2v(INT2FIX(2), conv1, conv2)) + return 0; + if (!test_unit_v2v(INT2FIX(3), conv1, conv2)) + return 0; + if (!test_unit_v2v(INT2FIX(11), conv1, conv2)) + return 0; + if (!test_unit_v2v(INT2FIX(65535), conv1, conv2)) + return 0; + if (!test_unit_v2v(INT2FIX(1073741823), conv1, conv2)) + return 0; + if (!test_unit_v2v(INT2NUM(1073741824), conv1, conv2)) + return 0; + if (!test_unit_v2v(rb_rational_new2(INT2FIX(0), INT2FIX(1)), conv1, conv2)) + return 0; + if (!test_unit_v2v(rb_rational_new2(INT2FIX(1), INT2FIX(1)), conv1, conv2)) + return 0; + if (!test_unit_v2v(rb_rational_new2(INT2FIX(1), INT2FIX(2)), conv1, conv2)) + return 0; + if (!test_unit_v2v(rb_rational_new2(INT2FIX(2), INT2FIX(3)), conv1, conv2)) + return 0; + return 1; +} + +/* :nodoc: */ +static int +test_unit_v2v_iter(VALUE (* conv1)(VALUE), + VALUE (* conv2)(VALUE)) +{ + if (!test_unit_v2v_iter2(conv1, conv2)) + return 0; + if (!test_unit_v2v_iter2(conv2, conv1)) + return 0; + return 1; +} + +/* :nodoc: */ +static VALUE +date_s_test_unit_conv(VALUE klass) +{ + if (!test_unit_v2v_iter(sec_to_day, day_to_sec)) + return Qfalse; + if (!test_unit_v2v_iter(ms_to_sec, sec_to_ms)) + return Qfalse; + if (!test_unit_v2v_iter(ns_to_day, day_to_ns)) + return Qfalse; + if (!test_unit_v2v_iter(ns_to_sec, sec_to_ns)) + return Qfalse; + return Qtrue; +} + +/* :nodoc: */ +static VALUE +date_s_test_all(VALUE klass) +{ + if (date_s_test_civil(klass) == Qfalse) + return Qfalse; + if (date_s_test_ordinal(klass) == Qfalse) + return Qfalse; + if (date_s_test_commercial(klass) == Qfalse) + return Qfalse; + if (date_s_test_weeknum(klass) == Qfalse) + return Qfalse; + if (date_s_test_nth_kday(klass) == Qfalse) + return Qfalse; + if (date_s_test_unit_conv(klass) == Qfalse) + return Qfalse; + return Qtrue; +} +#endif + +static const char *monthnames[] = { + NULL, + "January", "February", "March", + "April", "May", "June", + "July", "August", "September", + "October", "November", "December" +}; + +static const char *abbr_monthnames[] = { + NULL, + "Jan", "Feb", "Mar", "Apr", + "May", "Jun", "Jul", "Aug", + "Sep", "Oct", "Nov", "Dec" +}; + +static const char *daynames[] = { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" +}; + +static const char *abbr_daynames[] = { + "Sun", "Mon", "Tue", "Wed", + "Thu", "Fri", "Sat" +}; + +static VALUE +mk_ary_of_str(long len, const char *a[]) +{ + VALUE o; + long i; + + o = rb_ary_new2(len); + for (i = 0; i < len; i++) { + VALUE e; + + if (!a[i]) + e = Qnil; + else { + e = rb_usascii_str_new2(a[i]); + rb_obj_freeze(e); + } + rb_ary_push(o, e); + } + rb_ary_freeze(o); + return o; +} + +/* :nodoc: */ +static VALUE +d_lite_zero(VALUE x) +{ + return INT2FIX(0); +} + +void +Init_date_core(void) +{ + #ifdef HAVE_RB_EXT_RACTOR_SAFE + RB_EXT_RACTOR_SAFE(true); + #endif + id_cmp = rb_intern_const("<=>"); + id_le_p = rb_intern_const("<="); + id_ge_p = rb_intern_const(">="); + id_eqeq_p = rb_intern_const("=="); + + sym_year = ID2SYM(rb_intern_const("year")); + sym_month = ID2SYM(rb_intern_const("month")); + sym_yday = ID2SYM(rb_intern_const("yday")); + sym_wday = ID2SYM(rb_intern_const("wday")); + sym_day = ID2SYM(rb_intern_const("day")); + sym_hour = ID2SYM(rb_intern_const("hour")); + sym_min = ID2SYM(rb_intern_const("min")); + sym_sec = ID2SYM(rb_intern_const("sec")); + sym_sec_fraction = ID2SYM(rb_intern_const("sec_fraction")); + sym_zone = ID2SYM(rb_intern_const("zone")); + + half_days_in_day = rb_rational_new2(INT2FIX(1), INT2FIX(2)); + +#if (LONG_MAX / DAY_IN_SECONDS) > SECOND_IN_NANOSECONDS + day_in_nanoseconds = LONG2NUM((long)DAY_IN_SECONDS * + SECOND_IN_NANOSECONDS); +#elif defined HAVE_LONG_LONG + day_in_nanoseconds = LL2NUM((LONG_LONG)DAY_IN_SECONDS * + SECOND_IN_NANOSECONDS); +#else + day_in_nanoseconds = f_mul(INT2FIX(DAY_IN_SECONDS), + INT2FIX(SECOND_IN_NANOSECONDS)); +#endif + + rb_gc_register_mark_object(half_days_in_day); + rb_gc_register_mark_object(day_in_nanoseconds); + + positive_inf = +INFINITY; + negative_inf = -INFINITY; + + /* + * \Class \Date provides methods for storing and manipulating + * calendar dates. + * + * Consider using + * {class Time}[https://docs.ruby-lang.org/en/master/Time.html] + * instead of class \Date if: + * + * - You need both dates and times; \Date handles only dates. + * - You need only Gregorian dates (and not Julian dates); + * see {Julian and Gregorian Calendars}[rdoc-ref:calendars.rdoc]. + * + * A \Date object, once created, is immutable, and cannot be modified. + * + * == Creating a \Date + * + * You can create a date for the current date, using Date.today: + * + * Date.today # => # + * + * You can create a specific date from various combinations of arguments: + * + * - Date.new takes integer year, month, and day-of-month: + * + * Date.new(1999, 12, 31) # => # + * + * - Date.ordinal takes integer year and day-of-year: + * + * Date.ordinal(1999, 365) # => # + * + * - Date.jd takes integer Julian day: + * + * Date.jd(2451544) # => # + * + * - Date.commercial takes integer commercial data (year, week, day-of-week): + * + * Date.commercial(1999, 52, 5) # => # + * + * - Date.parse takes a string, which it parses heuristically: + * + * Date.parse('1999-12-31') # => # + * Date.parse('31-12-1999') # => # + * Date.parse('1999-365') # => # + * Date.parse('1999-W52-5') # => # + * + * - Date.strptime takes a date string and a format string, + * then parses the date string according to the format string: + * + * Date.strptime('1999-12-31', '%Y-%m-%d') # => # + * Date.strptime('31-12-1999', '%d-%m-%Y') # => # + * Date.strptime('1999-365', '%Y-%j') # => # + * Date.strptime('1999-W52-5', '%G-W%V-%u') # => # + * Date.strptime('1999 52 5', '%Y %U %w') # => # + * Date.strptime('1999 52 5', '%Y %W %u') # => # + * Date.strptime('fri31dec99', '%a%d%b%y') # => # + * + * See also the specialized methods in + * {"Specialized Format Strings" in Formats for Dates and Times}[https://docs.ruby-lang.org/en/master/strftime_formatting_rdoc.html#label-Specialized+Format+Strings] + * + * == Argument +limit+ + * + * Certain singleton methods in \Date that parse string arguments + * also take optional keyword argument +limit+, + * which can limit the length of the string argument. + * + * When +limit+ is: + * + * - Non-negative: + * raises ArgumentError if the string length is greater than _limit_. + * - Other numeric or +nil+: ignores +limit+. + * - Other non-numeric: raises TypeError. + * + */ + cDate = rb_define_class("Date", rb_cObject); + + /* Exception for invalid date/time */ + eDateError = rb_define_class_under(cDate, "Error", rb_eArgError); + + rb_include_module(cDate, rb_mComparable); + + /* An array of strings of full month names in English. The first + * element is nil. + */ + rb_define_const(cDate, "MONTHNAMES", mk_ary_of_str(13, monthnames)); + + /* An array of strings of abbreviated month names in English. The + * first element is nil. + */ + rb_define_const(cDate, "ABBR_MONTHNAMES", + mk_ary_of_str(13, abbr_monthnames)); + + /* An array of strings of the full names of days of the week in English. + * The first is "Sunday". + */ + rb_define_const(cDate, "DAYNAMES", mk_ary_of_str(7, daynames)); + + /* An array of strings of abbreviated day names in English. The + * first is "Sun". + */ + rb_define_const(cDate, "ABBR_DAYNAMES", mk_ary_of_str(7, abbr_daynames)); + + /* The Julian day number of the day of calendar reform for Italy + * and some catholic countries. + */ + rb_define_const(cDate, "ITALY", INT2FIX(ITALY)); + + /* The Julian day number of the day of calendar reform for England + * and her colonies. + */ + rb_define_const(cDate, "ENGLAND", INT2FIX(ENGLAND)); + + /* The Julian day number of the day of calendar reform for the + * proleptic Julian calendar. + */ + rb_define_const(cDate, "JULIAN", DBL2NUM(JULIAN)); + + /* The Julian day number of the day of calendar reform for the + * proleptic Gregorian calendar. + */ + rb_define_const(cDate, "GREGORIAN", DBL2NUM(GREGORIAN)); + + rb_define_alloc_func(cDate, d_lite_s_alloc_simple); + +#ifndef NDEBUG + rb_define_private_method(CLASS_OF(cDate), "_valid_jd?", + date_s__valid_jd_p, -1); + rb_define_private_method(CLASS_OF(cDate), "_valid_ordinal?", + date_s__valid_ordinal_p, -1); + rb_define_private_method(CLASS_OF(cDate), "_valid_civil?", + date_s__valid_civil_p, -1); + rb_define_private_method(CLASS_OF(cDate), "_valid_date?", + date_s__valid_civil_p, -1); + rb_define_private_method(CLASS_OF(cDate), "_valid_commercial?", + date_s__valid_commercial_p, -1); + rb_define_private_method(CLASS_OF(cDate), "_valid_weeknum?", + date_s__valid_weeknum_p, -1); + rb_define_private_method(CLASS_OF(cDate), "_valid_nth_kday?", + date_s__valid_nth_kday_p, -1); +#endif + + rb_define_singleton_method(cDate, "valid_jd?", date_s_valid_jd_p, -1); + rb_define_singleton_method(cDate, "valid_ordinal?", + date_s_valid_ordinal_p, -1); + rb_define_singleton_method(cDate, "valid_civil?", date_s_valid_civil_p, -1); + rb_define_singleton_method(cDate, "valid_date?", date_s_valid_civil_p, -1); + rb_define_singleton_method(cDate, "valid_commercial?", + date_s_valid_commercial_p, -1); + +#ifndef NDEBUG + rb_define_private_method(CLASS_OF(cDate), "valid_weeknum?", + date_s_valid_weeknum_p, -1); + rb_define_private_method(CLASS_OF(cDate), "valid_nth_kday?", + date_s_valid_nth_kday_p, -1); + rb_define_private_method(CLASS_OF(cDate), "zone_to_diff", + date_s_zone_to_diff, 1); +#endif + + rb_define_singleton_method(cDate, "julian_leap?", date_s_julian_leap_p, 1); + rb_define_singleton_method(cDate, "gregorian_leap?", + date_s_gregorian_leap_p, 1); + rb_define_singleton_method(cDate, "leap?", + date_s_gregorian_leap_p, 1); + +#ifndef NDEBUG + rb_define_singleton_method(cDate, "new!", date_s_new_bang, -1); + rb_define_alias(rb_singleton_class(cDate), "new_l!", "new"); +#endif + + rb_define_singleton_method(cDate, "jd", date_s_jd, -1); + rb_define_singleton_method(cDate, "ordinal", date_s_ordinal, -1); + rb_define_singleton_method(cDate, "civil", date_s_civil, -1); + rb_define_singleton_method(cDate, "commercial", date_s_commercial, -1); + +#ifndef NDEBUG + rb_define_singleton_method(cDate, "weeknum", date_s_weeknum, -1); + rb_define_singleton_method(cDate, "nth_kday", date_s_nth_kday, -1); +#endif + + rb_define_singleton_method(cDate, "today", date_s_today, -1); + rb_define_singleton_method(cDate, "_strptime", date_s__strptime, -1); + rb_define_singleton_method(cDate, "strptime", date_s_strptime, -1); + rb_define_singleton_method(cDate, "_parse", date_s__parse, -1); + rb_define_singleton_method(cDate, "parse", date_s_parse, -1); + rb_define_singleton_method(cDate, "_iso8601", date_s__iso8601, -1); + rb_define_singleton_method(cDate, "iso8601", date_s_iso8601, -1); + rb_define_singleton_method(cDate, "_rfc3339", date_s__rfc3339, -1); + rb_define_singleton_method(cDate, "rfc3339", date_s_rfc3339, -1); + rb_define_singleton_method(cDate, "_xmlschema", date_s__xmlschema, -1); + rb_define_singleton_method(cDate, "xmlschema", date_s_xmlschema, -1); + rb_define_singleton_method(cDate, "_rfc2822", date_s__rfc2822, -1); + rb_define_singleton_method(cDate, "_rfc822", date_s__rfc2822, -1); + rb_define_singleton_method(cDate, "rfc2822", date_s_rfc2822, -1); + rb_define_singleton_method(cDate, "rfc822", date_s_rfc2822, -1); + rb_define_singleton_method(cDate, "_httpdate", date_s__httpdate, -1); + rb_define_singleton_method(cDate, "httpdate", date_s_httpdate, -1); + rb_define_singleton_method(cDate, "_jisx0301", date_s__jisx0301, -1); + rb_define_singleton_method(cDate, "jisx0301", date_s_jisx0301, -1); + + rb_define_method(cDate, "initialize", date_initialize, -1); + rb_define_method(cDate, "initialize_copy", d_lite_initialize_copy, 1); + +#ifndef NDEBUG + rb_define_method(cDate, "fill", d_lite_fill, 0); +#endif + + rb_define_method(cDate, "ajd", d_lite_ajd, 0); + rb_define_method(cDate, "amjd", d_lite_amjd, 0); + rb_define_method(cDate, "jd", d_lite_jd, 0); + rb_define_method(cDate, "mjd", d_lite_mjd, 0); + rb_define_method(cDate, "ld", d_lite_ld, 0); + + rb_define_method(cDate, "year", d_lite_year, 0); + rb_define_method(cDate, "yday", d_lite_yday, 0); + rb_define_method(cDate, "mon", d_lite_mon, 0); + rb_define_method(cDate, "month", d_lite_mon, 0); + rb_define_method(cDate, "mday", d_lite_mday, 0); + rb_define_method(cDate, "day", d_lite_mday, 0); + rb_define_method(cDate, "day_fraction", d_lite_day_fraction, 0); + + rb_define_method(cDate, "cwyear", d_lite_cwyear, 0); + rb_define_method(cDate, "cweek", d_lite_cweek, 0); + rb_define_method(cDate, "cwday", d_lite_cwday, 0); + +#ifndef NDEBUG + rb_define_private_method(cDate, "wnum0", d_lite_wnum0, 0); + rb_define_private_method(cDate, "wnum1", d_lite_wnum1, 0); +#endif + + rb_define_method(cDate, "wday", d_lite_wday, 0); + + rb_define_method(cDate, "sunday?", d_lite_sunday_p, 0); + rb_define_method(cDate, "monday?", d_lite_monday_p, 0); + rb_define_method(cDate, "tuesday?", d_lite_tuesday_p, 0); + rb_define_method(cDate, "wednesday?", d_lite_wednesday_p, 0); + rb_define_method(cDate, "thursday?", d_lite_thursday_p, 0); + rb_define_method(cDate, "friday?", d_lite_friday_p, 0); + rb_define_method(cDate, "saturday?", d_lite_saturday_p, 0); + +#ifndef NDEBUG + rb_define_method(cDate, "nth_kday?", d_lite_nth_kday_p, 2); +#endif + + rb_define_private_method(cDate, "hour", d_lite_zero, 0); + rb_define_private_method(cDate, "min", d_lite_zero, 0); + rb_define_private_method(cDate, "minute", d_lite_zero, 0); + rb_define_private_method(cDate, "sec", d_lite_zero, 0); + rb_define_private_method(cDate, "second", d_lite_zero, 0); + + rb_define_method(cDate, "julian?", d_lite_julian_p, 0); + rb_define_method(cDate, "gregorian?", d_lite_gregorian_p, 0); + rb_define_method(cDate, "leap?", d_lite_leap_p, 0); + + rb_define_method(cDate, "start", d_lite_start, 0); + rb_define_method(cDate, "new_start", d_lite_new_start, -1); + rb_define_method(cDate, "italy", d_lite_italy, 0); + rb_define_method(cDate, "england", d_lite_england, 0); + rb_define_method(cDate, "julian", d_lite_julian, 0); + rb_define_method(cDate, "gregorian", d_lite_gregorian, 0); + + rb_define_method(cDate, "+", d_lite_plus, 1); + rb_define_method(cDate, "-", d_lite_minus, 1); + + rb_define_method(cDate, "next_day", d_lite_next_day, -1); + rb_define_method(cDate, "prev_day", d_lite_prev_day, -1); + rb_define_method(cDate, "next", d_lite_next, 0); + rb_define_method(cDate, "succ", d_lite_next, 0); + + rb_define_method(cDate, ">>", d_lite_rshift, 1); + rb_define_method(cDate, "<<", d_lite_lshift, 1); + + rb_define_method(cDate, "next_month", d_lite_next_month, -1); + rb_define_method(cDate, "prev_month", d_lite_prev_month, -1); + rb_define_method(cDate, "next_year", d_lite_next_year, -1); + rb_define_method(cDate, "prev_year", d_lite_prev_year, -1); + + rb_define_method(cDate, "step", d_lite_step, -1); + rb_define_method(cDate, "upto", d_lite_upto, 1); + rb_define_method(cDate, "downto", d_lite_downto, 1); + + rb_define_method(cDate, "<=>", d_lite_cmp, 1); + rb_define_method(cDate, "===", d_lite_equal, 1); + rb_define_method(cDate, "eql?", d_lite_eql_p, 1); + rb_define_method(cDate, "hash", d_lite_hash, 0); + + rb_define_method(cDate, "to_s", d_lite_to_s, 0); +#ifndef NDEBUG + rb_define_method(cDate, "inspect_raw", d_lite_inspect_raw, 0); +#endif + rb_define_method(cDate, "inspect", d_lite_inspect, 0); + + rb_define_method(cDate, "strftime", d_lite_strftime, -1); + + rb_define_method(cDate, "asctime", d_lite_asctime, 0); + rb_define_method(cDate, "ctime", d_lite_asctime, 0); + rb_define_method(cDate, "iso8601", d_lite_iso8601, 0); + rb_define_method(cDate, "xmlschema", d_lite_iso8601, 0); + rb_define_method(cDate, "rfc3339", d_lite_rfc3339, 0); + rb_define_method(cDate, "rfc2822", d_lite_rfc2822, 0); + rb_define_method(cDate, "rfc822", d_lite_rfc2822, 0); + rb_define_method(cDate, "httpdate", d_lite_httpdate, 0); + rb_define_method(cDate, "jisx0301", d_lite_jisx0301, 0); + + rb_define_method(cDate, "deconstruct_keys", d_lite_deconstruct_keys, 1); + +#ifndef NDEBUG + rb_define_method(cDate, "marshal_dump_old", d_lite_marshal_dump_old, 0); +#endif + rb_define_method(cDate, "marshal_dump", d_lite_marshal_dump, 0); + rb_define_method(cDate, "marshal_load", d_lite_marshal_load, 1); + rb_define_singleton_method(cDate, "_load", date_s__load, 1); + + /* + * == DateTime + * + * A subclass of Date that easily handles date, hour, minute, second, + * and offset. + * + * DateTime class is considered deprecated. Use Time class. + * + * DateTime does not consider any leap seconds, does not track + * any summer time rules. + * + * A DateTime object is created with DateTime::new, DateTime::jd, + * DateTime::ordinal, DateTime::commercial, DateTime::parse, + * DateTime::strptime, DateTime::now, Time#to_datetime, etc. + * + * require 'date' + * + * DateTime.new(2001,2,3,4,5,6) + * #=> # + * + * The last element of day, hour, minute, or second can be a + * fractional number. The fractional number's precision is assumed + * at most nanosecond. + * + * DateTime.new(2001,2,3.5) + * #=> # + * + * An optional argument, the offset, indicates the difference + * between the local time and UTC. For example, Rational(3,24) + * represents ahead of 3 hours of UTC, Rational(-5,24) represents + * behind of 5 hours of UTC. The offset should be -1 to +1, and + * its precision is assumed at most second. The default value is + * zero (equals to UTC). + * + * DateTime.new(2001,2,3,4,5,6,Rational(3,24)) + * #=> # + * + * The offset also accepts string form: + * + * DateTime.new(2001,2,3,4,5,6,'+03:00') + * #=> # + * + * An optional argument, the day of calendar reform (+start+), denotes + * a Julian day number, which should be 2298874 to 2426355 or + * negative/positive infinity. + * The default value is +Date::ITALY+ (2299161=1582-10-15). + * + * A DateTime object has various methods. See each reference. + * + * d = DateTime.parse('3rd Feb 2001 04:05:06+03:30') + * #=> # + * d.hour #=> 4 + * d.min #=> 5 + * d.sec #=> 6 + * d.offset #=> (7/48) + * d.zone #=> "+03:30" + * d += Rational('1.5') + * #=> # + * d = d.new_offset('+09:00') + * #=> # + * d.strftime('%I:%M:%S %p') + * #=> "09:35:06 PM" + * d > DateTime.new(1999) + * #=> true + * + * === When should you use DateTime and when should you use Time? + * + * It's a common misconception that + * {William Shakespeare}[https://en.wikipedia.org/wiki/William_Shakespeare] + * and + * {Miguel de Cervantes}[https://en.wikipedia.org/wiki/Miguel_de_Cervantes] + * died on the same day in history - + * so much so that UNESCO named April 23 as + * {World Book Day because of this fact}[https://en.wikipedia.org/wiki/World_Book_Day]. + * However, because England hadn't yet adopted the + * {Gregorian Calendar Reform}[https://en.wikipedia.org/wiki/Gregorian_calendar#Gregorian_reform] + * (and wouldn't until {1752}[https://en.wikipedia.org/wiki/Calendar_(New_Style)_Act_1750]) + * their deaths are actually 10 days apart. + * Since Ruby's Time class implements a + * {proleptic Gregorian calendar}[https://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar] + * and has no concept of calendar reform there's no way + * to express this with Time objects. This is where DateTime steps in: + * + * shakespeare = DateTime.iso8601('1616-04-23', Date::ENGLAND) + * #=> Tue, 23 Apr 1616 00:00:00 +0000 + * cervantes = DateTime.iso8601('1616-04-23', Date::ITALY) + * #=> Sat, 23 Apr 1616 00:00:00 +0000 + * + * Already you can see something is weird - the days of the week + * are different. Taking this further: + * + * cervantes == shakespeare + * #=> false + * (shakespeare - cervantes).to_i + * #=> 10 + * + * This shows that in fact they died 10 days apart (in reality + * 11 days since Cervantes died a day earlier but was buried on + * the 23rd). We can see the actual date of Shakespeare's death by + * using the #gregorian method to convert it: + * + * shakespeare.gregorian + * #=> Tue, 03 May 1616 00:00:00 +0000 + * + * So there's an argument that all the celebrations that take + * place on the 23rd April in Stratford-upon-Avon are actually + * the wrong date since England is now using the Gregorian calendar. + * You can see why when we transition across the reform + * date boundary: + * + * # start off with the anniversary of Shakespeare's birth in 1751 + * shakespeare = DateTime.iso8601('1751-04-23', Date::ENGLAND) + * #=> Tue, 23 Apr 1751 00:00:00 +0000 + * + * # add 366 days since 1752 is a leap year and April 23 is after February 29 + * shakespeare + 366 + * #=> Thu, 23 Apr 1752 00:00:00 +0000 + * + * # add another 365 days to take us to the anniversary in 1753 + * shakespeare + 366 + 365 + * #=> Fri, 04 May 1753 00:00:00 +0000 + * + * As you can see, if we're accurately tracking the number of + * {solar years}[https://en.wikipedia.org/wiki/Tropical_year] + * since Shakespeare's birthday then the correct anniversary date + * would be the 4th May and not the 23rd April. + * + * So when should you use DateTime in Ruby and when should + * you use Time? Almost certainly you'll want to use Time + * since your app is probably dealing with current dates and + * times. However, if you need to deal with dates and times in a + * historical context you'll want to use DateTime to avoid + * making the same mistakes as UNESCO. If you also have to deal + * with timezones then best of luck - just bear in mind that + * you'll probably be dealing with + * {local solar times}[https://en.wikipedia.org/wiki/Solar_time], + * since it wasn't until the 19th century that the introduction + * of the railways necessitated the need for + * {Standard Time}[https://en.wikipedia.org/wiki/Standard_time#Great_Britain] + * and eventually timezones. + */ + + cDateTime = rb_define_class("DateTime", cDate); + rb_define_alloc_func(cDateTime, d_lite_s_alloc_complex); + + rb_define_singleton_method(cDateTime, "jd", datetime_s_jd, -1); + rb_define_singleton_method(cDateTime, "ordinal", datetime_s_ordinal, -1); + rb_define_singleton_method(cDateTime, "civil", datetime_s_civil, -1); + rb_define_singleton_method(cDateTime, "new", datetime_s_civil, -1); + rb_define_singleton_method(cDateTime, "commercial", + datetime_s_commercial, -1); + +#ifndef NDEBUG + rb_define_singleton_method(cDateTime, "weeknum", + datetime_s_weeknum, -1); + rb_define_singleton_method(cDateTime, "nth_kday", + datetime_s_nth_kday, -1); +#endif + + rb_undef_method(CLASS_OF(cDateTime), "today"); + + rb_define_singleton_method(cDateTime, "now", datetime_s_now, -1); + rb_define_singleton_method(cDateTime, "_strptime", + datetime_s__strptime, -1); + rb_define_singleton_method(cDateTime, "strptime", + datetime_s_strptime, -1); + rb_define_singleton_method(cDateTime, "parse", + datetime_s_parse, -1); + rb_define_singleton_method(cDateTime, "iso8601", + datetime_s_iso8601, -1); + rb_define_singleton_method(cDateTime, "rfc3339", + datetime_s_rfc3339, -1); + rb_define_singleton_method(cDateTime, "xmlschema", + datetime_s_xmlschema, -1); + rb_define_singleton_method(cDateTime, "rfc2822", + datetime_s_rfc2822, -1); + rb_define_singleton_method(cDateTime, "rfc822", + datetime_s_rfc2822, -1); + rb_define_singleton_method(cDateTime, "httpdate", + datetime_s_httpdate, -1); + rb_define_singleton_method(cDateTime, "jisx0301", + datetime_s_jisx0301, -1); + + rb_define_method(cDateTime, "hour", d_lite_hour, 0); + rb_define_method(cDateTime, "min", d_lite_min, 0); + rb_define_method(cDateTime, "minute", d_lite_min, 0); + rb_define_method(cDateTime, "sec", d_lite_sec, 0); + rb_define_method(cDateTime, "second", d_lite_sec, 0); + rb_define_method(cDateTime, "sec_fraction", d_lite_sec_fraction, 0); + rb_define_method(cDateTime, "second_fraction", d_lite_sec_fraction, 0); + rb_define_method(cDateTime, "offset", d_lite_offset, 0); + rb_define_method(cDateTime, "zone", d_lite_zone, 0); + rb_define_method(cDateTime, "new_offset", d_lite_new_offset, -1); + + rb_define_method(cDateTime, "to_s", dt_lite_to_s, 0); + + rb_define_method(cDateTime, "strftime", dt_lite_strftime, -1); + + rb_define_method(cDateTime, "iso8601", dt_lite_iso8601, -1); + rb_define_method(cDateTime, "xmlschema", dt_lite_iso8601, -1); + rb_define_method(cDateTime, "rfc3339", dt_lite_rfc3339, -1); + rb_define_method(cDateTime, "jisx0301", dt_lite_jisx0301, -1); + + rb_define_method(cDateTime, "deconstruct_keys", dt_lite_deconstruct_keys, 1); + + /* conversions */ + + rb_define_method(rb_cTime, "to_time", time_to_time, 0); + rb_define_method(rb_cTime, "to_date", time_to_date, 0); + rb_define_method(rb_cTime, "to_datetime", time_to_datetime, 0); + + rb_define_method(cDate, "to_time", date_to_time, 0); + rb_define_method(cDate, "to_date", date_to_date, 0); + rb_define_method(cDate, "to_datetime", date_to_datetime, 0); + + rb_define_method(cDateTime, "to_time", datetime_to_time, 0); + rb_define_method(cDateTime, "to_date", datetime_to_date, 0); + rb_define_method(cDateTime, "to_datetime", datetime_to_datetime, 0); + +#ifndef NDEBUG + /* tests */ + + rb_define_singleton_method(cDate, "test_civil", date_s_test_civil, 0); + rb_define_singleton_method(cDate, "test_ordinal", date_s_test_ordinal, 0); + rb_define_singleton_method(cDate, "test_commercial", + date_s_test_commercial, 0); + rb_define_singleton_method(cDate, "test_weeknum", date_s_test_weeknum, 0); + rb_define_singleton_method(cDate, "test_nth_kday", date_s_test_nth_kday, 0); + rb_define_singleton_method(cDate, "test_unit_conv", + date_s_test_unit_conv, 0); + rb_define_singleton_method(cDate, "test_all", date_s_test_all, 0); +#endif +} + +/* +Local variables: +c-file-style: "ruby" +End: +*/ diff --git a/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/date_parse.c b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/date_parse.c new file mode 100644 index 00000000..a1600e47 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/date_parse.c @@ -0,0 +1,3086 @@ +/* + date_parse.c: Coded by Tadayoshi Funaba 2011,2012 +*/ + +#include "ruby.h" +#include "ruby/encoding.h" +#include "ruby/re.h" +#include + +#undef strncasecmp +#define strncasecmp STRNCASECMP + +RUBY_EXTERN VALUE rb_int_positive_pow(long x, unsigned long y); +RUBY_EXTERN unsigned long ruby_scan_digits(const char *str, ssize_t len, int base, size_t *retlen, int *overflow); + +/* #define TIGHT_PARSER */ + +#define sizeof_array(o) (sizeof o / sizeof o[0]) + +#define f_negate(x) rb_funcall(x, rb_intern("-@"), 0) +#define f_add(x,y) rb_funcall(x, '+', 1, y) +#define f_sub(x,y) rb_funcall(x, '-', 1, y) +#define f_mul(x,y) rb_funcall(x, '*', 1, y) +#define f_div(x,y) rb_funcall(x, '/', 1, y) +#define f_idiv(x,y) rb_funcall(x, rb_intern("div"), 1, y) +#define f_mod(x,y) rb_funcall(x, '%', 1, y) +#define f_expt(x,y) rb_funcall(x, rb_intern("**"), 1, y) + +#define f_lt_p(x,y) rb_funcall(x, '<', 1, y) +#define f_gt_p(x,y) rb_funcall(x, '>', 1, y) +#define f_le_p(x,y) rb_funcall(x, rb_intern("<="), 1, y) +#define f_ge_p(x,y) rb_funcall(x, rb_intern(">="), 1, y) + +#define f_to_s(x) rb_funcall(x, rb_intern("to_s"), 0) + +#define f_match(r,s) rb_funcall(r, rb_intern("match"), 1, s) +#define f_aref(o,i) rb_funcall(o, rb_intern("[]"), 1, i) +#define f_aref2(o,i,j) rb_funcall(o, rb_intern("[]"), 2, i, j) +#define f_begin(o,i) rb_funcall(o, rb_intern("begin"), 1, i) +#define f_end(o,i) rb_funcall(o, rb_intern("end"), 1, i) +#define f_aset(o,i,v) rb_funcall(o, rb_intern("[]="), 2, i, v) +#define f_aset2(o,i,j,v) rb_funcall(o, rb_intern("[]="), 3, i, j, v) +#define f_sub_bang(s,r,x) rb_funcall(s, rb_intern("sub!"), 2, r, x) +#define f_gsub_bang(s,r,x) rb_funcall(s, rb_intern("gsub!"), 2, r, x) + +#define set_hash(k,v) rb_hash_aset(hash, ID2SYM(rb_intern(k"")), v) +#define ref_hash(k) rb_hash_aref(hash, ID2SYM(rb_intern(k""))) +#define del_hash(k) rb_hash_delete(hash, ID2SYM(rb_intern(k""))) + +#define cstr2num(s) rb_cstr_to_inum(s, 10, 0) +#define str2num(s) rb_str_to_inum(s, 10, 0) + +static const char abbr_days[][4] = { + "sun", "mon", "tue", "wed", + "thu", "fri", "sat" +}; + +static const char abbr_months[][4] = { + "jan", "feb", "mar", "apr", "may", "jun", + "jul", "aug", "sep", "oct", "nov", "dec" +}; + +#define issign(c) ((c) == '-' || (c) == '+') +#define asp_string() rb_str_new(" ", 1) +#ifdef TIGHT_PARSER +#define asuba_string() rb_str_new("\001", 1) +#define asubb_string() rb_str_new("\002", 1) +#define asubw_string() rb_str_new("\027", 1) +#define asubt_string() rb_str_new("\024", 1) +#endif + +static size_t +digit_span(const char *s, const char *e) +{ + size_t i = 0; + while (s + i < e && isdigit((unsigned char)s[i])) i++; + return i; +} + +static void +s3e(VALUE hash, VALUE y, VALUE m, VALUE d, int bc) +{ + VALUE vbuf = 0; + VALUE c = Qnil; + + if (!RB_TYPE_P(m, T_STRING)) + m = f_to_s(m); + + if (!NIL_P(y) && !NIL_P(m) && NIL_P(d)) { + VALUE oy = y; + VALUE om = m; + VALUE od = d; + + y = od; + m = oy; + d = om; + } + + if (NIL_P(y)) { + if (!NIL_P(d) && RSTRING_LEN(d) > 2) { + y = d; + d = Qnil; + } + if (!NIL_P(d) && RSTRING_LEN(d) > 0 && *RSTRING_PTR(d) == '\'') { + y = d; + d = Qnil; + } + } + + if (!NIL_P(y)) { + const char *s, *bp, *ep; + size_t l; + + s = RSTRING_PTR(y); + ep = RSTRING_END(y); + while (s < ep && !issign(*s) && !isdigit((unsigned char)*s)) + s++; + if (s >= ep) goto no_date; + bp = s; + if (issign((unsigned char)*s)) + s++; + l = digit_span(s, ep); + ep = s + l; + if (*ep) { + y = d; + d = rb_str_new(bp, ep - bp); + } + no_date:; + } + + if (!NIL_P(m)) { + const char *s; + + s = RSTRING_PTR(m); + if (*s == '\'' || RSTRING_LEN(m) > 2) { + /* us -> be */ + VALUE oy = y; + VALUE om = m; + VALUE od = d; + + y = om; + m = od; + d = oy; + } + } + + if (!NIL_P(d)) { + const char *s; + + s = RSTRING_PTR(d); + if (*s == '\'' || RSTRING_LEN(d) > 2) { + VALUE oy = y; + VALUE od = d; + + y = od; + d = oy; + } + } + + if (!NIL_P(y)) { + const char *s, *bp, *ep; + int sign = 0; + size_t l; + VALUE iy; + + s = RSTRING_PTR(y); + ep = RSTRING_END(y); + while (s < ep && !issign(*s) && !isdigit((unsigned char)*s)) + s++; + if (s >= ep) goto no_year; + bp = s; + if (issign(*s)) { + s++; + sign = 1; + } + if (sign) + c = Qfalse; + l = digit_span(s, ep); + ep = s + l; + if (l > 2) + c = Qfalse; + { + char *buf; + + buf = ALLOCV_N(char, vbuf, ep - bp + 1); + memcpy(buf, bp, ep - bp); + buf[ep - bp] = '\0'; + iy = cstr2num(buf); + ALLOCV_END(vbuf); + } + set_hash("year", iy); + no_year:; + } + + if (bc) + set_hash("_bc", Qtrue); + + if (!NIL_P(m)) { + const char *s, *bp, *ep; + size_t l; + VALUE im; + + s = RSTRING_PTR(m); + ep = RSTRING_END(m); + while (s < ep && !isdigit((unsigned char)*s)) + s++; + if (s >= ep) goto no_month; + bp = s; + l = digit_span(s, ep); + ep = s + l; + { + char *buf; + + buf = ALLOCV_N(char, vbuf, ep - bp + 1); + memcpy(buf, bp, ep - bp); + buf[ep - bp] = '\0'; + im = cstr2num(buf); + ALLOCV_END(vbuf); + } + set_hash("mon", im); + no_month:; + } + + if (!NIL_P(d)) { + const char *s, *bp, *ep; + size_t l; + VALUE id; + + s = RSTRING_PTR(d); + ep = RSTRING_END(d); + while (s < ep && !isdigit((unsigned char)*s)) + s++; + if (s >= ep) goto no_mday; + bp = s; + l = digit_span(s, ep); + ep = s + l; + { + char *buf; + + buf = ALLOCV_N(char, vbuf, ep - bp + 1); + memcpy(buf, bp, ep - bp); + buf[ep - bp] = '\0'; + id = cstr2num(buf); + ALLOCV_END(vbuf); + } + set_hash("mday", id); + no_mday:; + } + + if (!NIL_P(c)) + set_hash("_comp", c); +} + +#define DAYS "sunday|monday|tuesday|wednesday|thursday|friday|saturday" +#define MONTHS "january|february|march|april|may|june|july|august|september|october|november|december" +#define ABBR_DAYS "sun|mon|tue|wed|thu|fri|sat" +#define ABBR_MONTHS "jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec" + +#define NUMBER "(? n && isspace((unsigned char)s[l - n - 1])); + return n; +} + +static long +shrunk_size(const char *s, long l) +{ + long i, ni; + int sp = 0; + for (i = ni = 0; i < l; ++i) { + if (!isspace((unsigned char)s[i])) { + if (sp) ni++; + sp = 0; + ni++; + } + else { + sp = 1; + } + } + return ni < l ? ni : 0; +} + +static long +shrink_space(char *d, const char *s, long l) +{ + long i, ni; + int sp = 0; + for (i = ni = 0; i < l; ++i) { + if (!isspace((unsigned char)s[i])) { + if (sp) d[ni++] = ' '; + sp = 0; + d[ni++] = s[i]; + } + else { + sp = 1; + } + } + return ni; +} + +VALUE +date_zone_to_diff(VALUE str) +{ + VALUE offset = Qnil; + long l = RSTRING_LEN(str); + const char *s = RSTRING_PTR(str); + + { + int dst = 0; + int w; + + if ((w = str_end_with_word(s, l, "time")) > 0) { + int wtime = w; + l -= w; + if ((w = str_end_with_word(s, l, "standard")) > 0) { + l -= w; + } + else if ((w = str_end_with_word(s, l, "daylight")) > 0) { + l -= w; + dst = 1; + } + else { + l += wtime; + } + } + else if ((w = str_end_with_word(s, l, "dst")) > 0) { + l -= w; + dst = 1; + } + + { + const char *zn = s; + long sl = shrunk_size(s, l); + char shrunk_buff[MAX_WORD_LENGTH]; /* no terminator to be added */ + const struct zone *z = 0; + + if (sl <= 0) { + sl = l; + } + else if (sl <= MAX_WORD_LENGTH) { + char *d = shrunk_buff; + sl = shrink_space(d, s, l); + zn = d; + } + + if (sl > 0 && sl <= MAX_WORD_LENGTH) { + z = zonetab(zn, (unsigned int)sl); + } + + if (z) { + int d = z->offset; + if (dst) + d += 3600; + offset = INT2FIX(d); + goto ok; + } + } + + { + char *p; + int sign = 0; + long hour = 0, min = 0, sec = 0; + + if (l > 3 && + (strncasecmp(s, "gmt", 3) == 0 || + strncasecmp(s, "utc", 3) == 0)) { + s += 3; + l -= 3; + } + if (issign(*s)) { + sign = *s == '-'; + s++; + l--; + +#define out_of_range(v, min, max) ((v) < (min) || (max) < (v)) + hour = STRTOUL(s, &p, 10); + if (*p == ':') { + if (out_of_range(hour, 0, 23)) return Qnil; + s = ++p; + min = STRTOUL(s, &p, 10); + if (out_of_range(min, 0, 59)) return Qnil; + if (*p == ':') { + s = ++p; + sec = STRTOUL(s, &p, 10); + if (out_of_range(sec, 0, 59)) return Qnil; + } + } + else if (*p == ',' || *p == '.') { + /* fractional hour */ + size_t n; + int ov; + /* no over precision for offset; 10**-7 hour = 0.36 + * milliseconds should be enough. */ + const size_t max_digits = 7; /* 36 * 10**7 < 32-bit FIXNUM_MAX */ + + if (out_of_range(hour, 0, 23)) return Qnil; + + n = (s + l) - ++p; + if (n > max_digits) n = max_digits; + sec = ruby_scan_digits(p, n, 10, &n, &ov); + if ((p += n) < s + l && *p >= ('5' + !(sec & 1)) && *p <= '9') { + /* round half to even */ + sec++; + } + sec *= 36; + if (sign) { + hour = -hour; + sec = -sec; + } + if (n <= 2) { + /* HH.nn or HH.n */ + if (n == 1) sec *= 10; + offset = INT2FIX(sec + hour * 3600); + } + else { + VALUE denom = rb_int_positive_pow(10, (int)(n - 2)); + offset = f_add(rb_rational_new(INT2FIX(sec), denom), INT2FIX(hour * 3600)); + if (rb_rational_den(offset) == INT2FIX(1)) { + offset = rb_rational_num(offset); + } + } + goto ok; + } + else if (l > 2) { + size_t n; + int ov; + + if (l >= 1) + hour = ruby_scan_digits(&s[0], 2 - l % 2, 10, &n, &ov); + if (l >= 3) + min = ruby_scan_digits(&s[2 - l % 2], 2, 10, &n, &ov); + if (l >= 5) + sec = ruby_scan_digits(&s[4 - l % 2], 2, 10, &n, &ov); + } + sec += min * 60 + hour * 3600; + if (sign) sec = -sec; + offset = INT2FIX(sec); +#undef out_of_range + } + } + } + RB_GC_GUARD(str); + ok: + return offset; +} + +static int +day_num(VALUE s) +{ + int i; + + for (i = 0; i < (int)sizeof_array(abbr_days); i++) + if (strncasecmp(abbr_days[i], RSTRING_PTR(s), 3) == 0) + break; + return i; +} + +static int +mon_num(VALUE s) +{ + int i; + + for (i = 0; i < (int)sizeof_array(abbr_months); i++) + if (strncasecmp(abbr_months[i], RSTRING_PTR(s), 3) == 0) + break; + return i + 1; +} + +static int +parse_day_cb(VALUE m, VALUE hash) +{ + VALUE s; + + s = rb_reg_nth_match(1, m); + set_hash("wday", INT2FIX(day_num(s))); + return 1; +} + +static int +parse_day(VALUE str, VALUE hash) +{ + static const char pat_source[] = +#ifndef TIGHT_PARSER + "\\b(" ABBR_DAYS ")[^-/\\d\\s]*" +#else + "(" VALID_DAYS ")" +#endif + ; + static VALUE pat = Qnil; + + REGCOMP_I(pat); +#ifndef TIGHT_PARSER + SUBS(str, pat, parse_day_cb); +#else + SUBW(str, pat, parse_day_cb); +#endif +} + +static int +parse_time2_cb(VALUE m, VALUE hash) +{ + VALUE h, min, s, f, p; + + h = rb_reg_nth_match(1, m); + h = str2num(h); + + min = rb_reg_nth_match(2, m); + if (!NIL_P(min)) + min = str2num(min); + + s = rb_reg_nth_match(3, m); + if (!NIL_P(s)) + s = str2num(s); + + f = rb_reg_nth_match(4, m); + + if (!NIL_P(f)) + f = rb_rational_new2(str2num(f), + f_expt(INT2FIX(10), LONG2NUM(RSTRING_LEN(f)))); + + p = rb_reg_nth_match(5, m); + + if (!NIL_P(p)) { + int ih = NUM2INT(h); + ih %= 12; + if (*RSTRING_PTR(p) == 'P' || *RSTRING_PTR(p) == 'p') + ih += 12; + h = INT2FIX(ih); + } + + set_hash("hour", h); + if (!NIL_P(min)) + set_hash("min", min); + if (!NIL_P(s)) + set_hash("sec", s); + if (!NIL_P(f)) + set_hash("sec_fraction", f); + + return 1; +} + +static int +parse_time_cb(VALUE m, VALUE hash) +{ + static const char pat_source[] = + "\\A(\\d+)h?" + "(?:\\s*:?\\s*(\\d+)m?" + "(?:" + "\\s*:?\\s*(\\d+)(?:[,.](\\d+))?s?" + ")?" + ")?" + "(?:\\s*([ap])(?:m\\b|\\.m\\.))?"; + static VALUE pat = Qnil; + VALUE s1, s2; + + s1 = rb_reg_nth_match(1, m); + s2 = rb_reg_nth_match(2, m); + + if (!NIL_P(s2)) + set_hash("zone", s2); + + REGCOMP_I(pat); + + { + VALUE m = f_match(pat, s1); + + if (NIL_P(m)) + return 0; + parse_time2_cb(m, hash); + } + + return 1; +} + +static int +parse_time(VALUE str, VALUE hash) +{ + static const char pat_source[] = + "(" + "" NUMBER "+\\s*" + "(?:" + "(?:" + ":\\s*\\d+" + "(?:" +#ifndef TIGHT_PARSER + "\\s*:\\s*\\d+(?:[,.]\\d*)?" +#else + "\\s*:\\s*\\d+(?:[,.]\\d+)?" +#endif + ")?" + "|" + "h(?:\\s*\\d+m?(?:\\s*\\d+s?)?)?" + ")" + "(?:" + "\\s*" + "[ap](?:m\\b|\\.m\\.)" + ")?" + "|" + "[ap](?:m\\b|\\.m\\.)" + ")" + ")" + "(?:" + "\\s*" + "(" + "(?:gmt|utc?)?[-+]\\d+(?:[,.:]\\d+(?::\\d+)?)?" + "|" + "(?-i:[[:alpha:].\\s]+)(?:standard|daylight)\\stime\\b" + "|" + "(?-i:[[:alpha:]]+)(?:\\sdst)?\\b" + ")" + ")?"; + static VALUE pat = Qnil; + + REGCOMP_I(pat); +#ifndef TIGHT_PARSER + SUBS(str, pat, parse_time_cb); +#else + SUBT(str, pat, parse_time_cb); +#endif +} + +#define BEGIN_ERA "\\b" +#define END_ERA "(?!(? 1) + return 0; + return 1; +} +#endif + +static int +parse_eu_cb(VALUE m, VALUE hash) +{ +#ifndef TIGHT_PARSER + VALUE y, mon, d, b; + + d = rb_reg_nth_match(1, m); + mon = rb_reg_nth_match(2, m); + b = rb_reg_nth_match(3, m); + y = rb_reg_nth_match(4, m); + + mon = INT2FIX(mon_num(mon)); + + s3e(hash, y, mon, d, !NIL_P(b) && + (*RSTRING_PTR(b) == 'B' || + *RSTRING_PTR(b) == 'b')); +#else + VALUE y, mon, d; + + d = rb_reg_nth_match(1, m); + mon = rb_reg_nth_match(2, m); + y = rb_reg_nth_match(3, m); + + if (!check_apost(d, mon, y)) + return 0; + + mon = INT2FIX(mon_num(mon)); + + s3e(hash, y, mon, d, 0); +#endif + return 1; +} + +static int +parse_eu(VALUE str, VALUE hash) +{ + static const char pat_source[] = +#ifdef TIGHT_PARSER + BOS + FPW_COM FPT_COM +#endif +#ifndef TIGHT_PARSER + "('?" NUMBER "+)[^-\\d\\s]*" +#else + "(\\d+)(?:(?:st|nd|rd|th)\\b)?" +#endif + "\\s*" +#ifndef TIGHT_PARSER + "(" ABBR_MONTHS ")[^-\\d\\s']*" +#else + "(" VALID_MONTHS ")" +#endif + "(?:" + "\\s*" +#ifndef TIGHT_PARSER + "(?:" + BEGIN_ERA + "(c(?:e|\\.e\\.)|b(?:ce|\\.c\\.e\\.)|a(?:d|\\.d\\.)|b(?:c|\\.c\\.))" + END_ERA + ")?" + "\\s*" + "('?-?\\d+(?:(?:st|nd|rd|th)\\b)?)" +#else + "(?:" FPA ")?" + "\\s*" + "([-']?\\d+)" + "\\s*" + "(?:" FPA "|" FPB ")?" +#endif + ")?" +#ifdef TIGHT_PARSER + COM_FPT COM_FPW + EOS +#endif + ; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + SUBS(str, pat, parse_eu_cb); +} + +static int +parse_us_cb(VALUE m, VALUE hash) +{ +#ifndef TIGHT_PARSER + VALUE y, mon, d, b; + + mon = rb_reg_nth_match(1, m); + d = rb_reg_nth_match(2, m); + + b = rb_reg_nth_match(3, m); + y = rb_reg_nth_match(4, m); + + mon = INT2FIX(mon_num(mon)); + + s3e(hash, y, mon, d, !NIL_P(b) && + (*RSTRING_PTR(b) == 'B' || + *RSTRING_PTR(b) == 'b')); +#else + VALUE y, mon, d; + + mon = rb_reg_nth_match(1, m); + d = rb_reg_nth_match(2, m); + y = rb_reg_nth_match(3, m); + + if (!check_apost(mon, d, y)) + return 0; + + mon = INT2FIX(mon_num(mon)); + + s3e(hash, y, mon, d, 0); +#endif + return 1; +} + +static int +parse_us(VALUE str, VALUE hash) +{ + static const char pat_source[] = +#ifdef TIGHT_PARSER + BOS + FPW_COM FPT_COM +#endif +#ifndef TIGHT_PARSER + "\\b(" ABBR_MONTHS ")[^-\\d\\s']*" +#else + "\\b(" VALID_MONTHS ")" +#endif + "\\s*" +#ifndef TIGHT_PARSER + "('?\\d+)[^-\\d\\s']*" +#else + "('?\\d+)(?:(?:st|nd|rd|th)\\b)?" + COM_FPT +#endif + "(?:" + "\\s*+,?" + "\\s*+" +#ifndef TIGHT_PARSER + "(c(?:e|\\.e\\.)|b(?:ce|\\.c\\.e\\.)|a(?:d|\\.d\\.)|b(?:c|\\.c\\.))?" + "\\s*" + "('?-?\\d+)" +#else + "(?:" FPA ")?" + "\\s*" + "([-']?\\d+)" + "\\s*" + "(?:" FPA "|" FPB ")?" +#endif + ")?" +#ifdef TIGHT_PARSER + COM_FPT COM_FPW + EOS +#endif + ; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + SUBS(str, pat, parse_us_cb); +} + +static int +parse_iso_cb(VALUE m, VALUE hash) +{ + VALUE y, mon, d; + + y = rb_reg_nth_match(1, m); + mon = rb_reg_nth_match(2, m); + d = rb_reg_nth_match(3, m); + +#ifdef TIGHT_PARSER + if (!check_apost(y, mon, d)) + return 0; +#endif + + s3e(hash, y, mon, d, 0); + return 1; +} + +static int +parse_iso(VALUE str, VALUE hash) +{ + static const char pat_source[] = +#ifndef TIGHT_PARSER + "('?[-+]?" NUMBER "+)-(\\d+)-('?-?\\d+)" +#else + BOS + FPW_COM FPT_COM + "([-+']?\\d+)-(\\d+)-([-']?\\d+)" + TEE_FPT COM_FPW + EOS +#endif + ; + static VALUE pat = Qnil; + + REGCOMP_0(pat); + SUBS(str, pat, parse_iso_cb); +} + +static int +parse_iso21_cb(VALUE m, VALUE hash) +{ + VALUE y, w, d; + + y = rb_reg_nth_match(1, m); + w = rb_reg_nth_match(2, m); + d = rb_reg_nth_match(3, m); + + if (!NIL_P(y)) + set_hash("cwyear", str2num(y)); + set_hash("cweek", str2num(w)); + if (!NIL_P(d)) + set_hash("cwday", str2num(d)); + + return 1; +} + +static int +parse_iso21(VALUE str, VALUE hash) +{ + static const char pat_source[] = +#ifndef TIGHT_PARSER + "\\b(\\d{2}|\\d{4})?-?w(\\d{2})(?:-?(\\d))?\\b" +#else + BOS + FPW_COM FPT_COM + "(\\d{2}|\\d{4})?-?w(\\d{2})(?:-?(\\d))?" + TEE_FPT COM_FPW + EOS +#endif + ; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + SUBS(str, pat, parse_iso21_cb); +} + +static int +parse_iso22_cb(VALUE m, VALUE hash) +{ + VALUE d; + + d = rb_reg_nth_match(1, m); + set_hash("cwday", str2num(d)); + return 1; +} + +static int +parse_iso22(VALUE str, VALUE hash) +{ + static const char pat_source[] = +#ifndef TIGHT_PARSER + "-w-(\\d)\\b" +#else + BOS + FPW_COM FPT_COM + "-w-(\\d)" + TEE_FPT COM_FPW + EOS +#endif + ; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + SUBS(str, pat, parse_iso22_cb); +} + +static int +parse_iso23_cb(VALUE m, VALUE hash) +{ + VALUE mon, d; + + mon = rb_reg_nth_match(1, m); + d = rb_reg_nth_match(2, m); + + if (!NIL_P(mon)) + set_hash("mon", str2num(mon)); + set_hash("mday", str2num(d)); + + return 1; +} + +static int +parse_iso23(VALUE str, VALUE hash) +{ + static const char pat_source[] = +#ifndef TIGHT_PARSER + "--(\\d{2})?-(\\d{2})\\b" +#else + BOS + FPW_COM FPT_COM + "--(\\d{2})?-(\\d{2})" + TEE_FPT COM_FPW + EOS +#endif + ; + static VALUE pat = Qnil; + + REGCOMP_0(pat); + SUBS(str, pat, parse_iso23_cb); +} + +static int +parse_iso24_cb(VALUE m, VALUE hash) +{ + VALUE mon, d; + + mon = rb_reg_nth_match(1, m); + d = rb_reg_nth_match(2, m); + + set_hash("mon", str2num(mon)); + if (!NIL_P(d)) + set_hash("mday", str2num(d)); + + return 1; +} + +static int +parse_iso24(VALUE str, VALUE hash) +{ + static const char pat_source[] = +#ifndef TIGHT_PARSER + "--(\\d{2})(\\d{2})?\\b" +#else + BOS + FPW_COM FPT_COM + "--(\\d{2})(\\d{2})?" + TEE_FPT COM_FPW + EOS +#endif + ; + static VALUE pat = Qnil; + + REGCOMP_0(pat); + SUBS(str, pat, parse_iso24_cb); +} + +static int +parse_iso25_cb(VALUE m, VALUE hash) +{ + VALUE y, d; + + y = rb_reg_nth_match(1, m); + d = rb_reg_nth_match(2, m); + + set_hash("year", str2num(y)); + set_hash("yday", str2num(d)); + + return 1; +} + +static int +parse_iso25(VALUE str, VALUE hash) +{ + static const char pat0_source[] = +#ifndef TIGHT_PARSER + "[,.](\\d{2}|\\d{4})-\\d{3}\\b" +#else + BOS + FPW_COM FPT_COM + "[,.](\\d{2}|\\d{4})-\\d{3}" + TEE_FPT COM_FPW + EOS +#endif + ; + static VALUE pat0 = Qnil; + static const char pat_source[] = +#ifndef TIGHT_PARSER + "\\b(\\d{2}|\\d{4})-(\\d{3})\\b" +#else + BOS + FPW_COM FPT_COM + "(\\d{2}|\\d{4})-(\\d{3})" + TEE_FPT COM_FPW + EOS +#endif + ; + static VALUE pat = Qnil; + + REGCOMP_0(pat0); + REGCOMP_0(pat); + + if (!NIL_P(f_match(pat0, str))) + return 0; + SUBS(str, pat, parse_iso25_cb); +} + +static int +parse_iso26_cb(VALUE m, VALUE hash) +{ + VALUE d; + + d = rb_reg_nth_match(1, m); + set_hash("yday", str2num(d)); + + return 1; +} +static int +parse_iso26(VALUE str, VALUE hash) +{ + static const char pat0_source[] = +#ifndef TIGHT_PARSER + "\\d-\\d{3}\\b" +#else + BOS + FPW_COM FPT_COM + "\\d-\\d{3}" + TEE_FPT COM_FPW + EOS +#endif + ; + static VALUE pat0 = Qnil; + static const char pat_source[] = +#ifndef TIGHT_PARSER + "\\b-(\\d{3})\\b" +#else + BOS + FPW_COM FPT_COM + "-(\\d{3})" + TEE_FPT COM_FPW + EOS +#endif + ; + static VALUE pat = Qnil; + + REGCOMP_0(pat0); + REGCOMP_0(pat); + + if (!NIL_P(f_match(pat0, str))) + return 0; + SUBS(str, pat, parse_iso26_cb); +} + +static int +parse_iso2(VALUE str, VALUE hash) +{ + if (parse_iso21(str, hash)) + goto ok; + if (parse_iso22(str, hash)) + goto ok; + if (parse_iso23(str, hash)) + goto ok; + if (parse_iso24(str, hash)) + goto ok; + if (parse_iso25(str, hash)) + goto ok; + if (parse_iso26(str, hash)) + goto ok; + return 0; + + ok: + return 1; +} + +#define JISX0301_ERA_INITIALS "mtshr" +#define JISX0301_DEFAULT_ERA 'H' /* obsolete */ + +static int +gengo(int c) +{ + int e; + + switch (c) { + case 'M': case 'm': e = 1867; break; + case 'T': case 't': e = 1911; break; + case 'S': case 's': e = 1925; break; + case 'H': case 'h': e = 1988; break; + case 'R': case 'r': e = 2018; break; + default: e = 0; break; + } + return e; +} + +static int +parse_jis_cb(VALUE m, VALUE hash) +{ + VALUE e, y, mon, d; + int ep; + + e = rb_reg_nth_match(1, m); + y = rb_reg_nth_match(2, m); + mon = rb_reg_nth_match(3, m); + d = rb_reg_nth_match(4, m); + + ep = gengo(*RSTRING_PTR(e)); + + set_hash("year", f_add(str2num(y), INT2FIX(ep))); + set_hash("mon", str2num(mon)); + set_hash("mday", str2num(d)); + + return 1; +} + +static int +parse_jis(VALUE str, VALUE hash) +{ + static const char pat_source[] = +#ifndef TIGHT_PARSER + "\\b([" JISX0301_ERA_INITIALS "])(\\d+)\\.(\\d+)\\.(\\d+)" +#else + BOS + FPW_COM FPT_COM + "([" JISX0301_ERA_INITIALS "])(\\d+)\\.(\\d+)\\.(\\d+)" + TEE_FPT COM_FPW + EOS +#endif + ; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + SUBS(str, pat, parse_jis_cb); +} + +static int +parse_vms11_cb(VALUE m, VALUE hash) +{ + VALUE y, mon, d; + + d = rb_reg_nth_match(1, m); + mon = rb_reg_nth_match(2, m); + y = rb_reg_nth_match(3, m); + +#ifdef TIGHT_PARSER + if (!check_apost(d, mon, y)) + return 0; +#endif + + mon = INT2FIX(mon_num(mon)); + + s3e(hash, y, mon, d, 0); + return 1; +} + +static int +parse_vms11(VALUE str, VALUE hash) +{ + static const char pat_source[] = +#ifndef TIGHT_PARSER + "('?-?" NUMBER "+)-(" ABBR_MONTHS ")[^-/.]*" + "-('?-?\\d+)" +#else + BOS + FPW_COM FPT_COM + "([-']?\\d+)-(" DOTLESS_VALID_MONTHS ")" + "-([-']?\\d+)" + COM_FPT COM_FPW + EOS +#endif + ; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + SUBS(str, pat, parse_vms11_cb); +} + +static int +parse_vms12_cb(VALUE m, VALUE hash) +{ + VALUE y, mon, d; + + mon = rb_reg_nth_match(1, m); + d = rb_reg_nth_match(2, m); + y = rb_reg_nth_match(3, m); + +#ifdef TIGHT_PARSER + if (!check_apost(mon, d, y)) + return 0; +#endif + + mon = INT2FIX(mon_num(mon)); + + s3e(hash, y, mon, d, 0); + return 1; +} + +static int +parse_vms12(VALUE str, VALUE hash) +{ + static const char pat_source[] = +#ifndef TIGHT_PARSER + "\\b(" ABBR_MONTHS ")[^-/.]*" + "-('?-?\\d+)(?:-('?-?\\d+))?" +#else + BOS + FPW_COM FPT_COM + "(" DOTLESS_VALID_MONTHS ")" + "-([-']?\\d+)(?:-([-']?\\d+))?" + COM_FPT COM_FPW + EOS +#endif + ; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + SUBS(str, pat, parse_vms12_cb); +} + +static int +parse_vms(VALUE str, VALUE hash) +{ + if (parse_vms11(str, hash)) + goto ok; + if (parse_vms12(str, hash)) + goto ok; + return 0; + + ok: + return 1; +} + +static int +parse_sla_cb(VALUE m, VALUE hash) +{ + VALUE y, mon, d; + + y = rb_reg_nth_match(1, m); + mon = rb_reg_nth_match(2, m); + d = rb_reg_nth_match(3, m); + +#ifdef TIGHT_PARSER + if (!check_apost(y, mon, d)) + return 0; +#endif + + s3e(hash, y, mon, d, 0); + return 1; +} + +static int +parse_sla(VALUE str, VALUE hash) +{ + static const char pat_source[] = +#ifndef TIGHT_PARSER + "('?-?" NUMBER "+)/\\s*('?\\d+)(?:\\D\\s*('?-?\\d+))?" +#else + BOS + FPW_COM FPT_COM + "([-']?\\d+)/\\s*('?\\d+)(?:(?:[-/]|\\s+)\\s*([-']?\\d+))?" + COM_FPT COM_FPW + EOS +#endif + ; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + SUBS(str, pat, parse_sla_cb); +} + +#ifdef TIGHT_PARSER +static int +parse_sla2_cb(VALUE m, VALUE hash) +{ + VALUE y, mon, d; + + d = rb_reg_nth_match(1, m); + mon = rb_reg_nth_match(2, m); + y = rb_reg_nth_match(3, m); + + if (!check_apost(d, mon, y)) + return 0; + + mon = INT2FIX(mon_num(mon)); + + s3e(hash, y, mon, d, 0); + return 1; +} + +static int +parse_sla2(VALUE str, VALUE hash) +{ + static const char pat_source[] = + BOS + FPW_COM FPT_COM + "([-']?\\d+)/\\s*(" DOTLESS_VALID_MONTHS ")(?:(?:[-/]|\\s+)\\s*([-']?\\d+))?" + COM_FPT COM_FPW + EOS + ; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + SUBS(str, pat, parse_sla2_cb); +} + +static int +parse_sla3_cb(VALUE m, VALUE hash) +{ + VALUE y, mon, d; + + mon = rb_reg_nth_match(1, m); + d = rb_reg_nth_match(2, m); + y = rb_reg_nth_match(3, m); + + if (!check_apost(mon, d, y)) + return 0; + + mon = INT2FIX(mon_num(mon)); + + s3e(hash, y, mon, d, 0); + return 1; +} + +static int +parse_sla3(VALUE str, VALUE hash) +{ + static const char pat_source[] = + BOS + FPW_COM FPT_COM + "(" DOTLESS_VALID_MONTHS ")/\\s*([-']?\\d+)(?:(?:[-/]|\\s+)\\s*([-']?\\d+))?" + COM_FPT COM_FPW + EOS + ; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + SUBS(str, pat, parse_sla3_cb); +} +#endif + +static int +parse_dot_cb(VALUE m, VALUE hash) +{ + VALUE y, mon, d; + + y = rb_reg_nth_match(1, m); + mon = rb_reg_nth_match(2, m); + d = rb_reg_nth_match(3, m); + +#ifdef TIGHT_PARSER + if (!check_apost(y, mon, d)) + return 0; +#endif + + s3e(hash, y, mon, d, 0); + return 1; +} + +static int +parse_dot(VALUE str, VALUE hash) +{ + static const char pat_source[] = +#ifndef TIGHT_PARSER + "('?-?" NUMBER "+)\\.\\s*('?\\d+)\\.\\s*('?-?\\d+)" +#else + BOS + FPW_COM FPT_COM + "([-']?\\d+)\\.\\s*(\\d+)\\.\\s*([-']?\\d+)" + COM_FPT COM_FPW + EOS +#endif + ; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + SUBS(str, pat, parse_dot_cb); +} + +#ifdef TIGHT_PARSER +static int +parse_dot2_cb(VALUE m, VALUE hash) +{ + VALUE y, mon, d; + + d = rb_reg_nth_match(1, m); + mon = rb_reg_nth_match(2, m); + y = rb_reg_nth_match(3, m); + + if (!check_apost(d, mon, y)) + return 0; + + mon = INT2FIX(mon_num(mon)); + + s3e(hash, y, mon, d, 0); + return 1; +} + +static int +parse_dot2(VALUE str, VALUE hash) +{ + static const char pat_source[] = + BOS + FPW_COM FPT_COM + "([-']?\\d+)\\.\\s*(" DOTLESS_VALID_MONTHS ")(?:(?:[./])\\s*([-']?\\d+))?" + COM_FPT COM_FPW + EOS + ; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + SUBS(str, pat, parse_dot2_cb); +} + +static int +parse_dot3_cb(VALUE m, VALUE hash) +{ + VALUE y, mon, d; + + mon = rb_reg_nth_match(1, m); + d = rb_reg_nth_match(2, m); + y = rb_reg_nth_match(3, m); + + if (!check_apost(mon, d, y)) + return 0; + + mon = INT2FIX(mon_num(mon)); + + s3e(hash, y, mon, d, 0); + return 1; +} + +static int +parse_dot3(VALUE str, VALUE hash) +{ + static const char pat_source[] = + BOS + FPW_COM FPT_COM + "(" DOTLESS_VALID_MONTHS ")\\.\\s*([-']?\\d+)(?:(?:[./])\\s*([-']?\\d+))?" + COM_FPT COM_FPW + EOS + ; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + SUBS(str, pat, parse_dot3_cb); +} +#endif + +static int +parse_year_cb(VALUE m, VALUE hash) +{ + VALUE y; + + y = rb_reg_nth_match(1, m); + set_hash("year", str2num(y)); + return 1; +} + +static int +parse_year(VALUE str, VALUE hash) +{ + static const char pat_source[] = +#ifndef TIGHT_PARSER + "'(\\d+)\\b" +#else + BOS + FPW_COM FPT_COM + "'(\\d+)" + COM_FPT COM_FPW + EOS +#endif + ; + static VALUE pat = Qnil; + + REGCOMP_0(pat); + SUBS(str, pat, parse_year_cb); +} + +static int +parse_mon_cb(VALUE m, VALUE hash) +{ + VALUE mon; + + mon = rb_reg_nth_match(1, m); + set_hash("mon", INT2FIX(mon_num(mon))); + return 1; +} + +static int +parse_mon(VALUE str, VALUE hash) +{ + static const char pat_source[] = +#ifndef TIGHT_PARSER + "\\b(" ABBR_MONTHS ")\\S*" +#else + BOS + FPW_COM FPT_COM + "(" VALID_MONTHS ")" + COM_FPT COM_FPW + EOS +#endif + ; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + SUBS(str, pat, parse_mon_cb); +} + +static int +parse_mday_cb(VALUE m, VALUE hash) +{ + VALUE d; + + d = rb_reg_nth_match(1, m); + set_hash("mday", str2num(d)); + return 1; +} + +static int +parse_mday(VALUE str, VALUE hash) +{ + static const char pat_source[] = +#ifndef TIGHT_PARSER + "(" NUMBER "+)(st|nd|rd|th)\\b" +#else + BOS + FPW_COM FPT_COM + "(\\d+)(st|nd|rd|th)" + COM_FPT COM_FPW + EOS +#endif + ; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + SUBS(str, pat, parse_mday_cb); +} + +static int +n2i(const char *s, long f, long w) +{ + long e, i; + int v; + + e = f + w; + v = 0; + for (i = f; i < e; i++) { + v *= 10; + v += s[i] - '0'; + } + return v; +} + +static int +parse_ddd_cb(VALUE m, VALUE hash) +{ + VALUE s1, s2, s3, s4, s5; + const char *cs2, *cs3, *cs5; + long l2, l3, l4, l5; + + s1 = rb_reg_nth_match(1, m); + s2 = rb_reg_nth_match(2, m); + s3 = rb_reg_nth_match(3, m); + s4 = rb_reg_nth_match(4, m); + s5 = rb_reg_nth_match(5, m); + + cs2 = RSTRING_PTR(s2); + l2 = RSTRING_LEN(s2); + + switch (l2) { + case 2: + if (NIL_P(s3) && !NIL_P(s4)) + set_hash("sec", INT2FIX(n2i(cs2, l2-2, 2))); + else + set_hash("mday", INT2FIX(n2i(cs2, 0, 2))); + break; + case 4: + if (NIL_P(s3) && !NIL_P(s4)) { + set_hash("sec", INT2FIX(n2i(cs2, l2-2, 2))); + set_hash("min", INT2FIX(n2i(cs2, l2-4, 2))); + } + else { + set_hash("mon", INT2FIX(n2i(cs2, 0, 2))); + set_hash("mday", INT2FIX(n2i(cs2, 2, 2))); + } + break; + case 6: + if (NIL_P(s3) && !NIL_P(s4)) { + set_hash("sec", INT2FIX(n2i(cs2, l2-2, 2))); + set_hash("min", INT2FIX(n2i(cs2, l2-4, 2))); + set_hash("hour", INT2FIX(n2i(cs2, l2-6, 2))); + } + else { + int y = n2i(cs2, 0, 2); + if (!NIL_P(s1) && *RSTRING_PTR(s1) == '-') + y = -y; + set_hash("year", INT2FIX(y)); + set_hash("mon", INT2FIX(n2i(cs2, 2, 2))); + set_hash("mday", INT2FIX(n2i(cs2, 4, 2))); + } + break; + case 8: + case 10: + case 12: + case 14: + if (NIL_P(s3) && !NIL_P(s4)) { + set_hash("sec", INT2FIX(n2i(cs2, l2-2, 2))); + set_hash("min", INT2FIX(n2i(cs2, l2-4, 2))); + set_hash("hour", INT2FIX(n2i(cs2, l2-6, 2))); + set_hash("mday", INT2FIX(n2i(cs2, l2-8, 2))); + if (l2 >= 10) + set_hash("mon", INT2FIX(n2i(cs2, l2-10, 2))); + if (l2 == 12) { + int y = n2i(cs2, l2-12, 2); + if (!NIL_P(s1) && *RSTRING_PTR(s1) == '-') + y = -y; + set_hash("year", INT2FIX(y)); + } + if (l2 == 14) { + int y = n2i(cs2, l2-14, 4); + if (!NIL_P(s1) && *RSTRING_PTR(s1) == '-') + y = -y; + set_hash("year", INT2FIX(y)); + set_hash("_comp", Qfalse); + } + } + else { + int y = n2i(cs2, 0, 4); + if (!NIL_P(s1) && *RSTRING_PTR(s1) == '-') + y = -y; + set_hash("year", INT2FIX(y)); + set_hash("mon", INT2FIX(n2i(cs2, 4, 2))); + set_hash("mday", INT2FIX(n2i(cs2, 6, 2))); + if (l2 >= 10) + set_hash("hour", INT2FIX(n2i(cs2, 8, 2))); + if (l2 >= 12) + set_hash("min", INT2FIX(n2i(cs2, 10, 2))); + if (l2 >= 14) + set_hash("sec", INT2FIX(n2i(cs2, 12, 2))); + set_hash("_comp", Qfalse); + } + break; + case 3: + if (NIL_P(s3) && !NIL_P(s4)) { + set_hash("sec", INT2FIX(n2i(cs2, l2-2, 2))); + set_hash("min", INT2FIX(n2i(cs2, l2-3, 1))); + } + else + set_hash("yday", INT2FIX(n2i(cs2, 0, 3))); + break; + case 5: + if (NIL_P(s3) && !NIL_P(s4)) { + set_hash("sec", INT2FIX(n2i(cs2, l2-2, 2))); + set_hash("min", INT2FIX(n2i(cs2, l2-4, 2))); + set_hash("hour", INT2FIX(n2i(cs2, l2-5, 1))); + } + else { + int y = n2i(cs2, 0, 2); + if (!NIL_P(s1) && *RSTRING_PTR(s1) == '-') + y = -y; + set_hash("year", INT2FIX(y)); + set_hash("yday", INT2FIX(n2i(cs2, 2, 3))); + } + break; + case 7: + if (NIL_P(s3) && !NIL_P(s4)) { + set_hash("sec", INT2FIX(n2i(cs2, l2-2, 2))); + set_hash("min", INT2FIX(n2i(cs2, l2-4, 2))); + set_hash("hour", INT2FIX(n2i(cs2, l2-6, 2))); + set_hash("mday", INT2FIX(n2i(cs2, l2-7, 1))); + } + else { + int y = n2i(cs2, 0, 4); + if (!NIL_P(s1) && *RSTRING_PTR(s1) == '-') + y = -y; + set_hash("year", INT2FIX(y)); + set_hash("yday", INT2FIX(n2i(cs2, 4, 3))); + } + break; + } + RB_GC_GUARD(s2); + if (!NIL_P(s3)) { + cs3 = RSTRING_PTR(s3); + l3 = RSTRING_LEN(s3); + + if (!NIL_P(s4)) { + switch (l3) { + case 2: + case 4: + case 6: + set_hash("sec", INT2FIX(n2i(cs3, l3-2, 2))); + if (l3 >= 4) + set_hash("min", INT2FIX(n2i(cs3, l3-4, 2))); + if (l3 >= 6) + set_hash("hour", INT2FIX(n2i(cs3, l3-6, 2))); + break; + } + } + else { + switch (l3) { + case 2: + case 4: + case 6: + set_hash("hour", INT2FIX(n2i(cs3, 0, 2))); + if (l3 >= 4) + set_hash("min", INT2FIX(n2i(cs3, 2, 2))); + if (l3 >= 6) + set_hash("sec", INT2FIX(n2i(cs3, 4, 2))); + break; + } + } + RB_GC_GUARD(s3); + } + if (!NIL_P(s4)) { + l4 = RSTRING_LEN(s4); + + set_hash("sec_fraction", + rb_rational_new2(str2num(s4), + f_expt(INT2FIX(10), LONG2NUM(l4)))); + } + if (!NIL_P(s5)) { + cs5 = RSTRING_PTR(s5); + l5 = RSTRING_LEN(s5); + + set_hash("zone", s5); + + if (*cs5 == '[') { + const char *s1, *s2; + VALUE zone; + + l5 -= 2; + s1 = cs5 + 1; + s2 = memchr(s1, ':', l5); + if (s2) { + s2++; + zone = rb_str_subseq(s5, s2 - cs5, l5 - (s2 - s1)); + s5 = rb_str_subseq(s5, 1, s2 - s1); + } + else { + zone = rb_str_subseq(s5, 1, l5); + if (isdigit((unsigned char)*s1)) + s5 = rb_str_append(rb_str_new_cstr("+"), zone); + else + s5 = zone; + } + set_hash("zone", zone); + set_hash("offset", date_zone_to_diff(s5)); + } + RB_GC_GUARD(s5); + } + + return 1; +} + +static int +parse_ddd(VALUE str, VALUE hash) +{ + static const char pat_source[] = +#ifdef TIGHT_PARSER + BOS +#endif + "([-+]?)(" NUMBER "{2,14})" + "(?:" + "\\s*" + "t?" + "\\s*" + "(\\d{2,6})?(?:[,.](\\d*))?" + ")?" + "(?:" + "\\s*" + "(" + "z\\b" + "|" + "[-+]\\d{1,4}\\b" + "|" + "\\[[-+]?\\d[^\\]]*\\]" + ")" + ")?" +#ifdef TIGHT_PARSER + EOS +#endif + ; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + SUBS(str, pat, parse_ddd_cb); +} + +#ifndef TIGHT_PARSER +static int +parse_bc_cb(VALUE m, VALUE hash) +{ + set_hash("_bc", Qtrue); + return 1; +} + +static int +parse_bc(VALUE str, VALUE hash) +{ + static const char pat_source[] = + "\\b(bc\\b|bce\\b|b\\.c\\.|b\\.c\\.e\\.)"; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + SUBS(str, pat, parse_bc_cb); +} + +static int +parse_frag_cb(VALUE m, VALUE hash) +{ + VALUE s, n; + + s = rb_reg_nth_match(1, m); + + if (!NIL_P(ref_hash("hour")) && NIL_P(ref_hash("mday"))) { + n = str2num(s); + if (f_ge_p(n, INT2FIX(1)) && + f_le_p(n, INT2FIX(31))) + set_hash("mday", n); + } + if (!NIL_P(ref_hash("mday")) && NIL_P(ref_hash("hour"))) { + n = str2num(s); + if (f_ge_p(n, INT2FIX(0)) && + f_le_p(n, INT2FIX(24))) + set_hash("hour", n); + } + + return 1; +} + +static int +parse_frag(VALUE str, VALUE hash) +{ + static const char pat_source[] = "\\A\\s*(\\d{1,2})\\s*\\z"; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + SUBS(str, pat, parse_frag_cb); +} +#endif + +#ifdef TIGHT_PARSER +static int +parse_dummy_cb(VALUE m, VALUE hash) +{ + return 1; +} + +static int +parse_wday_only(VALUE str, VALUE hash) +{ + static const char pat_source[] = "\\A\\s*" FPW "\\s*\\z"; + static VALUE pat = Qnil; + + REGCOMP_0(pat); + SUBS(str, pat, parse_dummy_cb); +} + +static int +parse_time_only(VALUE str, VALUE hash) +{ + static const char pat_source[] = "\\A\\s*" FPT "\\s*\\z"; + static VALUE pat = Qnil; + + REGCOMP_0(pat); + SUBS(str, pat, parse_dummy_cb); +} + +static int +parse_wday_and_time(VALUE str, VALUE hash) +{ + static const char pat_source[] = "\\A\\s*(" FPW "\\s+" FPT "|" FPT "\\s+" FPW ")\\s*\\z"; + static VALUE pat = Qnil; + + REGCOMP_0(pat); + SUBS(str, pat, parse_dummy_cb); +} + +static unsigned +have_invalid_char_p(VALUE s) +{ + long i; + + for (i = 0; i < RSTRING_LEN(s); i++) + if (iscntrl((unsigned char)RSTRING_PTR(s)[i]) && + !isspace((unsigned char)RSTRING_PTR(s)[i])) + return 1; + return 0; +} +#endif + +#define HAVE_ALPHA (1<<0) +#define HAVE_DIGIT (1<<1) +#define HAVE_DASH (1<<2) +#define HAVE_DOT (1<<3) +#define HAVE_SLASH (1<<4) + +static unsigned +check_class(VALUE s) +{ + unsigned flags; + long i; + + flags = 0; + for (i = 0; i < RSTRING_LEN(s); i++) { + if (isalpha((unsigned char)RSTRING_PTR(s)[i])) + flags |= HAVE_ALPHA; + if (isdigit((unsigned char)RSTRING_PTR(s)[i])) + flags |= HAVE_DIGIT; + if (RSTRING_PTR(s)[i] == '-') + flags |= HAVE_DASH; + if (RSTRING_PTR(s)[i] == '.') + flags |= HAVE_DOT; + if (RSTRING_PTR(s)[i] == '/') + flags |= HAVE_SLASH; + } + return flags; +} + +#define HAVE_ELEM_P(x) ((check_class(str) & (x)) == (x)) + +#ifdef TIGHT_PARSER +#define PARSER_ERROR return rb_hash_new() +#endif + +VALUE +date__parse(VALUE str, VALUE comp) +{ + VALUE backref, hash; + +#ifdef TIGHT_PARSER + if (have_invalid_char_p(str)) + PARSER_ERROR; +#endif + + backref = rb_backref_get(); + rb_match_busy(backref); + + { + static const char pat_source[] = +#ifndef TIGHT_PARSER + "[^-+',./:@[:alnum:]\\[\\]]+" +#else + "[^[:graph:]]+" +#endif + ; + static VALUE pat = Qnil; + + REGCOMP_0(pat); + str = rb_str_dup(str); + f_gsub_bang(str, pat, asp_string()); + } + + hash = rb_hash_new(); + set_hash("_comp", comp); + + if (HAVE_ELEM_P(HAVE_ALPHA)) + parse_day(str, hash); + if (HAVE_ELEM_P(HAVE_DIGIT)) + parse_time(str, hash); + +#ifdef TIGHT_PARSER + if (HAVE_ELEM_P(HAVE_ALPHA)) + parse_era(str, hash); +#endif + + if (HAVE_ELEM_P(HAVE_ALPHA|HAVE_DIGIT)) { + if (parse_eu(str, hash)) + goto ok; + if (parse_us(str, hash)) + goto ok; + } + if (HAVE_ELEM_P(HAVE_DIGIT|HAVE_DASH)) + if (parse_iso(str, hash)) + goto ok; + if (HAVE_ELEM_P(HAVE_DIGIT|HAVE_DOT)) + if (parse_jis(str, hash)) + goto ok; + if (HAVE_ELEM_P(HAVE_ALPHA|HAVE_DIGIT|HAVE_DASH)) + if (parse_vms(str, hash)) + goto ok; + if (HAVE_ELEM_P(HAVE_DIGIT|HAVE_SLASH)) + if (parse_sla(str, hash)) + goto ok; +#ifdef TIGHT_PARSER + if (HAVE_ELEM_P(HAVE_ALPHA|HAVE_DIGIT|HAVE_SLASH)) { + if (parse_sla2(str, hash)) + goto ok; + if (parse_sla3(str, hash)) + goto ok; + } +#endif + if (HAVE_ELEM_P(HAVE_DIGIT|HAVE_DOT)) + if (parse_dot(str, hash)) + goto ok; +#ifdef TIGHT_PARSER + if (HAVE_ELEM_P(HAVE_ALPHA|HAVE_DIGIT|HAVE_DOT)) { + if (parse_dot2(str, hash)) + goto ok; + if (parse_dot3(str, hash)) + goto ok; + } +#endif + if (HAVE_ELEM_P(HAVE_DIGIT)) + if (parse_iso2(str, hash)) + goto ok; + if (HAVE_ELEM_P(HAVE_DIGIT)) + if (parse_year(str, hash)) + goto ok; + if (HAVE_ELEM_P(HAVE_ALPHA)) + if (parse_mon(str, hash)) + goto ok; + if (HAVE_ELEM_P(HAVE_DIGIT)) + if (parse_mday(str, hash)) + goto ok; + if (HAVE_ELEM_P(HAVE_DIGIT)) + if (parse_ddd(str, hash)) + goto ok; + +#ifdef TIGHT_PARSER + if (parse_wday_only(str, hash)) + goto ok; + if (parse_time_only(str, hash)) + goto ok; + if (parse_wday_and_time(str, hash)) + goto ok; + + PARSER_ERROR; /* not found */ +#endif + + ok: +#ifndef TIGHT_PARSER + if (HAVE_ELEM_P(HAVE_ALPHA)) + parse_bc(str, hash); + if (HAVE_ELEM_P(HAVE_DIGIT)) + parse_frag(str, hash); +#endif + + { + if (RTEST(del_hash("_bc"))) { + VALUE y; + + y = ref_hash("cwyear"); + if (!NIL_P(y)) { + y = f_add(f_negate(y), INT2FIX(1)); + set_hash("cwyear", y); + } + y = ref_hash("year"); + if (!NIL_P(y)) { + y = f_add(f_negate(y), INT2FIX(1)); + set_hash("year", y); + } + } + + if (RTEST(del_hash("_comp"))) { + VALUE y; + + y = ref_hash("cwyear"); + if (!NIL_P(y)) + if (f_ge_p(y, INT2FIX(0)) && f_le_p(y, INT2FIX(99))) { + if (f_ge_p(y, INT2FIX(69))) + set_hash("cwyear", f_add(y, INT2FIX(1900))); + else + set_hash("cwyear", f_add(y, INT2FIX(2000))); + } + y = ref_hash("year"); + if (!NIL_P(y)) + if (f_ge_p(y, INT2FIX(0)) && f_le_p(y, INT2FIX(99))) { + if (f_ge_p(y, INT2FIX(69))) + set_hash("year", f_add(y, INT2FIX(1900))); + else + set_hash("year", f_add(y, INT2FIX(2000))); + } + } + + } + + { + VALUE zone = ref_hash("zone"); + if (!NIL_P(zone) && NIL_P(ref_hash("offset"))) + set_hash("offset", date_zone_to_diff(zone)); + } + + rb_backref_set(backref); + + return hash; +} + +static VALUE +comp_year69(VALUE y) +{ + if (f_ge_p(y, INT2FIX(69))) + return f_add(y, INT2FIX(1900)); + return f_add(y, INT2FIX(2000)); +} + +static VALUE +comp_year50(VALUE y) +{ + if (f_ge_p(y, INT2FIX(50))) + return f_add(y, INT2FIX(1900)); + return f_add(y, INT2FIX(2000)); +} + +static VALUE +sec_fraction(VALUE f) +{ + return rb_rational_new2(str2num(f), + f_expt(INT2FIX(10), + LONG2NUM(RSTRING_LEN(f)))); +} + +#define SNUM 14 + +static int +iso8601_ext_datetime_cb(VALUE m, VALUE hash) +{ + VALUE s[SNUM + 1], y; + + { + int i; + s[0] = Qnil; + for (i = 1; i <= SNUM; i++) + s[i] = rb_reg_nth_match(i, m); + } + + if (!NIL_P(s[1])) { + if (!NIL_P(s[3])) set_hash("mday", str2num(s[3])); + if (strcmp(RSTRING_PTR(s[1]), "-") != 0) { + y = str2num(s[1]); + if (RSTRING_LEN(s[1]) < 4) + y = comp_year69(y); + set_hash("year", y); + } + if (NIL_P(s[2])) { + if (strcmp(RSTRING_PTR(s[1]), "-") != 0) + return 0; + } + else + set_hash("mon", str2num(s[2])); + } + else if (!NIL_P(s[5])) { + set_hash("yday", str2num(s[5])); + if (!NIL_P(s[4])) { + y = str2num(s[4]); + if (RSTRING_LEN(s[4]) < 4) + y = comp_year69(y); + set_hash("year", y); + } + } + else if (!NIL_P(s[8])) { + set_hash("cweek", str2num(s[7])); + set_hash("cwday", str2num(s[8])); + if (!NIL_P(s[6])) { + y = str2num(s[6]); + if (RSTRING_LEN(s[6]) < 4) + y = comp_year69(y); + set_hash("cwyear", y); + } + } + else if (!NIL_P(s[9])) { + set_hash("cwday", str2num(s[9])); + } + if (!NIL_P(s[10])) { + set_hash("hour", str2num(s[10])); + set_hash("min", str2num(s[11])); + if (!NIL_P(s[12])) + set_hash("sec", str2num(s[12])); + } + if (!NIL_P(s[13])) { + set_hash("sec_fraction", sec_fraction(s[13])); + } + if (!NIL_P(s[14])) { + set_hash("zone", s[14]); + set_hash("offset", date_zone_to_diff(s[14])); + } + + return 1; +} + +static int +iso8601_ext_datetime(VALUE str, VALUE hash) +{ + static const char pat_source[] = + "\\A\\s*(?:([-+]?\\d{2,}|-)-(\\d{2})?(?:-(\\d{2}))?|" + "([-+]?\\d{2,})?-(\\d{3})|" + "(\\d{4}|\\d{2})?-w(\\d{2})-(\\d)|" + "-w-(\\d))" + "(?:t" + "(\\d{2}):(\\d{2})(?::(\\d{2})(?:[,.](\\d+))?)?" + "(z|[-+]\\d{2}(?::?\\d{2})?)?)?\\s*\\z"; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + MATCH(str, pat, iso8601_ext_datetime_cb); +} + +#undef SNUM +#define SNUM 17 + +static int +iso8601_bas_datetime_cb(VALUE m, VALUE hash) +{ + VALUE s[SNUM + 1], y; + + { + int i; + s[0] = Qnil; + for (i = 1; i <= SNUM; i++) + s[i] = rb_reg_nth_match(i, m); + } + + if (!NIL_P(s[3])) { + set_hash("mday", str2num(s[3])); + if (strcmp(RSTRING_PTR(s[1]), "--") != 0) { + y = str2num(s[1]); + if (RSTRING_LEN(s[1]) < 4) + y = comp_year69(y); + set_hash("year", y); + } + if (*RSTRING_PTR(s[2]) == '-') { + if (strcmp(RSTRING_PTR(s[1]), "--") != 0) + return 0; + } + else + set_hash("mon", str2num(s[2])); + } + else if (!NIL_P(s[5])) { + set_hash("yday", str2num(s[5])); + y = str2num(s[4]); + if (RSTRING_LEN(s[4]) < 4) + y = comp_year69(y); + set_hash("year", y); + } + else if (!NIL_P(s[6])) { + set_hash("yday", str2num(s[6])); + } + else if (!NIL_P(s[9])) { + set_hash("cweek", str2num(s[8])); + set_hash("cwday", str2num(s[9])); + y = str2num(s[7]); + if (RSTRING_LEN(s[7]) < 4) + y = comp_year69(y); + set_hash("cwyear", y); + } + else if (!NIL_P(s[11])) { + set_hash("cweek", str2num(s[10])); + set_hash("cwday", str2num(s[11])); + } + else if (!NIL_P(s[12])) { + set_hash("cwday", str2num(s[12])); + } + if (!NIL_P(s[13])) { + set_hash("hour", str2num(s[13])); + set_hash("min", str2num(s[14])); + if (!NIL_P(s[15])) + set_hash("sec", str2num(s[15])); + } + if (!NIL_P(s[16])) { + set_hash("sec_fraction", sec_fraction(s[16])); + } + if (!NIL_P(s[17])) { + set_hash("zone", s[17]); + set_hash("offset", date_zone_to_diff(s[17])); + } + + return 1; +} + +static int +iso8601_bas_datetime(VALUE str, VALUE hash) +{ + static const char pat_source[] = + "\\A\\s*(?:([-+]?(?:\\d{4}|\\d{2})|--)(\\d{2}|-)(\\d{2})|" + "([-+]?(?:\\d{4}|\\d{2}))(\\d{3})|" + "-(\\d{3})|" + "(\\d{4}|\\d{2})w(\\d{2})(\\d)|" + "-w(\\d{2})(\\d)|" + "-w-(\\d))" + "(?:t?" + "(\\d{2})(\\d{2})(?:(\\d{2})(?:[,.](\\d+))?)?" + "(z|[-+]\\d{2}(?:\\d{2})?)?)?\\s*\\z"; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + MATCH(str, pat, iso8601_bas_datetime_cb); +} + +#undef SNUM +#define SNUM 5 + +static int +iso8601_ext_time_cb(VALUE m, VALUE hash) +{ + VALUE s[SNUM + 1]; + + { + int i; + s[0] = Qnil; + for (i = 1; i <= SNUM; i++) + s[i] = rb_reg_nth_match(i, m); + } + + set_hash("hour", str2num(s[1])); + set_hash("min", str2num(s[2])); + if (!NIL_P(s[3])) + set_hash("sec", str2num(s[3])); + if (!NIL_P(s[4])) + set_hash("sec_fraction", sec_fraction(s[4])); + if (!NIL_P(s[5])) { + set_hash("zone", s[5]); + set_hash("offset", date_zone_to_diff(s[5])); + } + + return 1; +} + +#define iso8601_bas_time_cb iso8601_ext_time_cb + +static int +iso8601_ext_time(VALUE str, VALUE hash) +{ + static const char pat_source[] = + "\\A\\s*(\\d{2}):(\\d{2})(?::(\\d{2})(?:[,.](\\d+))?" + "(z|[-+]\\d{2}(:?\\d{2})?)?)?\\s*\\z"; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + MATCH(str, pat, iso8601_ext_time_cb); +} + +static int +iso8601_bas_time(VALUE str, VALUE hash) +{ + static const char pat_source[] = + "\\A\\s*(\\d{2})(\\d{2})(?:(\\d{2})(?:[,.](\\d+))?" + "(z|[-+]\\d{2}(\\d{2})?)?)?\\s*\\z"; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + MATCH(str, pat, iso8601_bas_time_cb); +} + +VALUE +date__iso8601(VALUE str) +{ + VALUE backref, hash; + + backref = rb_backref_get(); + rb_match_busy(backref); + + hash = rb_hash_new(); + + if (iso8601_ext_datetime(str, hash)) + goto ok; + if (iso8601_bas_datetime(str, hash)) + goto ok; + if (iso8601_ext_time(str, hash)) + goto ok; + if (iso8601_bas_time(str, hash)) + goto ok; + + ok: + rb_backref_set(backref); + + return hash; +} + +#undef SNUM +#define SNUM 8 + +static int +rfc3339_cb(VALUE m, VALUE hash) +{ + VALUE s[SNUM + 1]; + + { + int i; + s[0] = Qnil; + for (i = 1; i <= SNUM; i++) + s[i] = rb_reg_nth_match(i, m); + } + + set_hash("year", str2num(s[1])); + set_hash("mon", str2num(s[2])); + set_hash("mday", str2num(s[3])); + set_hash("hour", str2num(s[4])); + set_hash("min", str2num(s[5])); + set_hash("sec", str2num(s[6])); + set_hash("zone", s[8]); + set_hash("offset", date_zone_to_diff(s[8])); + if (!NIL_P(s[7])) + set_hash("sec_fraction", sec_fraction(s[7])); + + return 1; +} + +static int +rfc3339(VALUE str, VALUE hash) +{ + static const char pat_source[] = + "\\A\\s*(-?\\d{4})-(\\d{2})-(\\d{2})" + "(?:t|\\s)" + "(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d+))?" + "(z|[-+]\\d{2}:\\d{2})\\s*\\z"; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + MATCH(str, pat, rfc3339_cb); +} + +VALUE +date__rfc3339(VALUE str) +{ + VALUE backref, hash; + + backref = rb_backref_get(); + rb_match_busy(backref); + + hash = rb_hash_new(); + rfc3339(str, hash); + rb_backref_set(backref); + return hash; +} + +#undef SNUM +#define SNUM 8 + +static int +xmlschema_datetime_cb(VALUE m, VALUE hash) +{ + VALUE s[SNUM + 1]; + + { + int i; + s[0] = Qnil; + for (i = 1; i <= SNUM; i++) + s[i] = rb_reg_nth_match(i, m); + } + + set_hash("year", str2num(s[1])); + if (!NIL_P(s[2])) + set_hash("mon", str2num(s[2])); + if (!NIL_P(s[3])) + set_hash("mday", str2num(s[3])); + if (!NIL_P(s[4])) + set_hash("hour", str2num(s[4])); + if (!NIL_P(s[5])) + set_hash("min", str2num(s[5])); + if (!NIL_P(s[6])) + set_hash("sec", str2num(s[6])); + if (!NIL_P(s[7])) + set_hash("sec_fraction", sec_fraction(s[7])); + if (!NIL_P(s[8])) { + set_hash("zone", s[8]); + set_hash("offset", date_zone_to_diff(s[8])); + } + + return 1; +} + +static int +xmlschema_datetime(VALUE str, VALUE hash) +{ + static const char pat_source[] = + "\\A\\s*(-?\\d{4,})(?:-(\\d{2})(?:-(\\d{2}))?)?" + "(?:t" + "(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d+))?)?" + "(z|[-+]\\d{2}:\\d{2})?\\s*\\z"; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + MATCH(str, pat, xmlschema_datetime_cb); +} + +#undef SNUM +#define SNUM 5 + +static int +xmlschema_time_cb(VALUE m, VALUE hash) +{ + VALUE s[SNUM + 1]; + + { + int i; + s[0] = Qnil; + for (i = 1; i <= SNUM; i++) + s[i] = rb_reg_nth_match(i, m); + } + + set_hash("hour", str2num(s[1])); + set_hash("min", str2num(s[2])); + if (!NIL_P(s[3])) + set_hash("sec", str2num(s[3])); + if (!NIL_P(s[4])) + set_hash("sec_fraction", sec_fraction(s[4])); + if (!NIL_P(s[5])) { + set_hash("zone", s[5]); + set_hash("offset", date_zone_to_diff(s[5])); + } + + return 1; +} + +static int +xmlschema_time(VALUE str, VALUE hash) +{ + static const char pat_source[] = + "\\A\\s*(\\d{2}):(\\d{2}):(\\d{2})(?:\\.(\\d+))?" + "(z|[-+]\\d{2}:\\d{2})?\\s*\\z"; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + MATCH(str, pat, xmlschema_time_cb); +} + +#undef SNUM +#define SNUM 4 + +static int +xmlschema_trunc_cb(VALUE m, VALUE hash) +{ + VALUE s[SNUM + 1]; + + { + int i; + s[0] = Qnil; + for (i = 1; i <= SNUM; i++) + s[i] = rb_reg_nth_match(i, m); + } + + if (!NIL_P(s[1])) + set_hash("mon", str2num(s[1])); + if (!NIL_P(s[2])) + set_hash("mday", str2num(s[2])); + if (!NIL_P(s[3])) + set_hash("mday", str2num(s[3])); + if (!NIL_P(s[4])) { + set_hash("zone", s[4]); + set_hash("offset", date_zone_to_diff(s[4])); + } + + return 1; +} + +static int +xmlschema_trunc(VALUE str, VALUE hash) +{ + static const char pat_source[] = + "\\A\\s*(?:--(\\d{2})(?:-(\\d{2}))?|---(\\d{2}))" + "(z|[-+]\\d{2}:\\d{2})?\\s*\\z"; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + MATCH(str, pat, xmlschema_trunc_cb); +} + +VALUE +date__xmlschema(VALUE str) +{ + VALUE backref, hash; + + backref = rb_backref_get(); + rb_match_busy(backref); + + hash = rb_hash_new(); + + if (xmlschema_datetime(str, hash)) + goto ok; + if (xmlschema_time(str, hash)) + goto ok; + if (xmlschema_trunc(str, hash)) + goto ok; + + ok: + rb_backref_set(backref); + + return hash; +} + +#undef SNUM +#define SNUM 8 + +static int +rfc2822_cb(VALUE m, VALUE hash) +{ + VALUE s[SNUM + 1], y; + + { + int i; + s[0] = Qnil; + for (i = 1; i <= SNUM; i++) + s[i] = rb_reg_nth_match(i, m); + } + + if (!NIL_P(s[1])) { + set_hash("wday", INT2FIX(day_num(s[1]))); + } + set_hash("mday", str2num(s[2])); + set_hash("mon", INT2FIX(mon_num(s[3]))); + y = str2num(s[4]); + if (RSTRING_LEN(s[4]) < 4) + y = comp_year50(y); + set_hash("year", y); + set_hash("hour", str2num(s[5])); + set_hash("min", str2num(s[6])); + if (!NIL_P(s[7])) + set_hash("sec", str2num(s[7])); + set_hash("zone", s[8]); + set_hash("offset", date_zone_to_diff(s[8])); + + return 1; +} + +static int +rfc2822(VALUE str, VALUE hash) +{ + static const char pat_source[] = + "\\A\\s*(?:(" ABBR_DAYS ")\\s*,\\s+)?" + "(\\d{1,2})\\s+" + "(" ABBR_MONTHS ")\\s+" + "(-?\\d{2,})\\s+" + "(\\d{2}):(\\d{2})(?::(\\d{2}))?\\s*" + "([-+]\\d{4}|ut|gmt|e[sd]t|c[sd]t|m[sd]t|p[sd]t|[a-ik-z])\\s*\\z"; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + MATCH(str, pat, rfc2822_cb); +} + +VALUE +date__rfc2822(VALUE str) +{ + VALUE backref, hash; + + backref = rb_backref_get(); + rb_match_busy(backref); + + hash = rb_hash_new(); + rfc2822(str, hash); + rb_backref_set(backref); + return hash; +} + +#undef SNUM +#define SNUM 8 + +static int +httpdate_type1_cb(VALUE m, VALUE hash) +{ + VALUE s[SNUM + 1]; + + { + int i; + s[0] = Qnil; + for (i = 1; i <= SNUM; i++) + s[i] = rb_reg_nth_match(i, m); + } + + set_hash("wday", INT2FIX(day_num(s[1]))); + set_hash("mday", str2num(s[2])); + set_hash("mon", INT2FIX(mon_num(s[3]))); + set_hash("year", str2num(s[4])); + set_hash("hour", str2num(s[5])); + set_hash("min", str2num(s[6])); + set_hash("sec", str2num(s[7])); + set_hash("zone", s[8]); + set_hash("offset", INT2FIX(0)); + + return 1; +} + +static int +httpdate_type1(VALUE str, VALUE hash) +{ + static const char pat_source[] = + "\\A\\s*(" ABBR_DAYS ")\\s*,\\s+" + "(\\d{2})\\s+" + "(" ABBR_MONTHS ")\\s+" + "(-?\\d{4})\\s+" + "(\\d{2}):(\\d{2}):(\\d{2})\\s+" + "(gmt)\\s*\\z"; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + MATCH(str, pat, httpdate_type1_cb); +} + +#undef SNUM +#define SNUM 8 + +static int +httpdate_type2_cb(VALUE m, VALUE hash) +{ + VALUE s[SNUM + 1], y; + + { + int i; + s[0] = Qnil; + for (i = 1; i <= SNUM; i++) + s[i] = rb_reg_nth_match(i, m); + } + + set_hash("wday", INT2FIX(day_num(s[1]))); + set_hash("mday", str2num(s[2])); + set_hash("mon", INT2FIX(mon_num(s[3]))); + y = str2num(s[4]); + if (f_ge_p(y, INT2FIX(0)) && f_le_p(y, INT2FIX(99))) + y = comp_year69(y); + set_hash("year", y); + set_hash("hour", str2num(s[5])); + set_hash("min", str2num(s[6])); + set_hash("sec", str2num(s[7])); + set_hash("zone", s[8]); + set_hash("offset", INT2FIX(0)); + + return 1; +} + +static int +httpdate_type2(VALUE str, VALUE hash) +{ + static const char pat_source[] = + "\\A\\s*(" DAYS ")\\s*,\\s+" + "(\\d{2})\\s*-\\s*" + "(" ABBR_MONTHS ")\\s*-\\s*" + "(\\d{2})\\s+" + "(\\d{2}):(\\d{2}):(\\d{2})\\s+" + "(gmt)\\s*\\z"; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + MATCH(str, pat, httpdate_type2_cb); +} + +#undef SNUM +#define SNUM 7 + +static int +httpdate_type3_cb(VALUE m, VALUE hash) +{ + VALUE s[SNUM + 1]; + + { + int i; + s[0] = Qnil; + for (i = 1; i <= SNUM; i++) + s[i] = rb_reg_nth_match(i, m); + } + + set_hash("wday", INT2FIX(day_num(s[1]))); + set_hash("mon", INT2FIX(mon_num(s[2]))); + set_hash("mday", str2num(s[3])); + set_hash("hour", str2num(s[4])); + set_hash("min", str2num(s[5])); + set_hash("sec", str2num(s[6])); + set_hash("year", str2num(s[7])); + + return 1; +} + +static int +httpdate_type3(VALUE str, VALUE hash) +{ + static const char pat_source[] = + "\\A\\s*(" ABBR_DAYS ")\\s+" + "(" ABBR_MONTHS ")\\s+" + "(\\d{1,2})\\s+" + "(\\d{2}):(\\d{2}):(\\d{2})\\s+" + "(\\d{4})\\s*\\z"; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + MATCH(str, pat, httpdate_type3_cb); +} + +VALUE +date__httpdate(VALUE str) +{ + VALUE backref, hash; + + backref = rb_backref_get(); + rb_match_busy(backref); + + hash = rb_hash_new(); + + if (httpdate_type1(str, hash)) + goto ok; + if (httpdate_type2(str, hash)) + goto ok; + if (httpdate_type3(str, hash)) + goto ok; + + ok: + rb_backref_set(backref); + + return hash; +} + +#undef SNUM +#define SNUM 9 + +static int +jisx0301_cb(VALUE m, VALUE hash) +{ + VALUE s[SNUM + 1]; + int ep; + + { + int i; + s[0] = Qnil; + for (i = 1; i <= SNUM; i++) + s[i] = rb_reg_nth_match(i, m); + } + + ep = gengo(NIL_P(s[1]) ? JISX0301_DEFAULT_ERA : *RSTRING_PTR(s[1])); + set_hash("year", f_add(str2num(s[2]), INT2FIX(ep))); + set_hash("mon", str2num(s[3])); + set_hash("mday", str2num(s[4])); + if (!NIL_P(s[5])) { + set_hash("hour", str2num(s[5])); + if (!NIL_P(s[6])) + set_hash("min", str2num(s[6])); + if (!NIL_P(s[7])) + set_hash("sec", str2num(s[7])); + } + if (!NIL_P(s[8])) + set_hash("sec_fraction", sec_fraction(s[8])); + if (!NIL_P(s[9])) { + set_hash("zone", s[9]); + set_hash("offset", date_zone_to_diff(s[9])); + } + + return 1; +} + +static int +jisx0301(VALUE str, VALUE hash) +{ + static const char pat_source[] = + "\\A\\s*([" JISX0301_ERA_INITIALS "])?(\\d{2})\\.(\\d{2})\\.(\\d{2})" + "(?:t" + "(?:(\\d{2}):(\\d{2})(?::(\\d{2})(?:[,.](\\d*))?)?" + "(z|[-+]\\d{2}(?::?\\d{2})?)?)?)?\\s*\\z"; + static VALUE pat = Qnil; + + REGCOMP_I(pat); + MATCH(str, pat, jisx0301_cb); +} + +VALUE +date__jisx0301(VALUE str) +{ + VALUE backref, hash; + + backref = rb_backref_get(); + rb_match_busy(backref); + + hash = rb_hash_new(); + if (jisx0301(str, hash)) + goto ok; + hash = date__iso8601(str); + + ok: + rb_backref_set(backref); + return hash; +} + +/* +Local variables: +c-file-style: "ruby" +End: +*/ diff --git a/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/date_strftime.c b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/date_strftime.c new file mode 100644 index 00000000..d7f28989 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/date_strftime.c @@ -0,0 +1,638 @@ +/* + date_strftime.c: based on a public-domain implementation of ANSI C + library routine strftime, which is originally written by Arnold + Robbins. + */ + +#include "ruby/ruby.h" +#include "date_tmx.h" + +#include +#include +#include +#include + +#if defined(HAVE_SYS_TIME_H) +#include +#endif + +#undef strchr /* avoid AIX weirdness */ + +#define range(low, item, hi) (item) + +#define add(x,y) (rb_funcall((x), '+', 1, (y))) +#define sub(x,y) (rb_funcall((x), '-', 1, (y))) +#define mul(x,y) (rb_funcall((x), '*', 1, (y))) +#define quo(x,y) (rb_funcall((x), rb_intern("quo"), 1, (y))) +#define div(x,y) (rb_funcall((x), rb_intern("div"), 1, (y))) +#define mod(x,y) (rb_funcall((x), '%', 1, (y))) + +static void +upcase(char *s, size_t i) +{ + do { + if (ISLOWER(*s)) + *s = TOUPPER(*s); + } while (s++, --i); +} + +static void +downcase(char *s, size_t i) +{ + do { + if (ISUPPER(*s)) + *s = TOLOWER(*s); + } while (s++, --i); +} + +/* strftime --- produce formatted time */ + +static size_t +date_strftime_with_tmx(char *s, const size_t maxsize, const char *format, + const struct tmx *tmx) +{ + char *endp = s + maxsize; + char *start = s; + const char *sp, *tp; + auto char tbuf[100]; + ptrdiff_t i; + int v, w; + size_t colons; + int precision, flags; + char padding; + /* LOCALE_[OE] and COLONS are actually modifiers, not flags */ + enum {LEFT, CHCASE, LOWER, UPPER, LOCALE_O, LOCALE_E, COLONS}; +#define BIT_OF(n) (1U<<(n)) + + /* various tables for locale C */ + static const char days_l[][10] = { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday", + }; + static const char months_l[][10] = { + "January", "February", "March", "April", + "May", "June", "July", "August", "September", + "October", "November", "December", + }; + static const char ampm[][3] = { "AM", "PM", }; + + if (s == NULL || format == NULL || tmx == NULL || maxsize == 0) + return 0; + + /* quick check if we even need to bother */ + if (strchr(format, '%') == NULL && strlen(format) + 1 >= maxsize) { + err: + errno = ERANGE; + return 0; + } + + for (; *format && s < endp - 1; format++) { +#define FLAG_FOUND() do { \ + if (precision > 0 || flags & (BIT_OF(LOCALE_E) | BIT_OF(LOCALE_O) | BIT_OF(COLONS))) \ + goto unknown; \ + } while (0) +#define NEEDS(n) do if (s >= endp || (n) >= endp - s - 1) goto err; while (0) +#define FILL_PADDING(i) do { \ + if (!(flags & BIT_OF(LEFT)) && precision > (i)) { \ + NEEDS(precision); \ + memset(s, padding ? padding : ' ', precision - (i)); \ + s += precision - (i); \ + } \ + else { \ + NEEDS(i); \ + } \ + } while (0); +#define FMT(def_pad, def_prec, fmt, val) \ + do { \ + int l; \ + if (precision <= 0) precision = (def_prec); \ + if (flags & BIT_OF(LEFT)) precision = 1; \ + l = snprintf(s, endp - s, \ + ((padding == '0' || (!padding && (def_pad) == '0')) ? \ + "%0*"fmt : "%*"fmt), \ + precision, (val)); \ + if (l < 0) goto err; \ + s += l; \ + } while (0) +#define STRFTIME(fmt) \ + do { \ + i = date_strftime_with_tmx(s, endp - s, (fmt), tmx); \ + if (!i) return 0; \ + if (flags & BIT_OF(UPPER)) \ + upcase(s, i); \ + if (!(flags & BIT_OF(LEFT)) && precision > i) { \ + if (start + maxsize < s + precision) { \ + errno = ERANGE; \ + return 0; \ + } \ + memmove(s + precision - i, s, i); \ + memset(s, padding ? padding : ' ', precision - i); \ + s += precision; \ + } \ + else s += i; \ + } while (0) +#define FMTV(def_pad, def_prec, fmt, val) \ + do { \ + VALUE tmp = (val); \ + if (FIXNUM_P(tmp)) { \ + FMT((def_pad), (def_prec), "l"fmt, FIX2LONG(tmp)); \ + } \ + else { \ + VALUE args[2], result; \ + size_t l; \ + if (precision <= 0) precision = (def_prec); \ + if (flags & BIT_OF(LEFT)) precision = 1; \ + args[0] = INT2FIX(precision); \ + args[1] = (val); \ + if (padding == '0' || (!padding && (def_pad) == '0')) \ + result = rb_str_format(2, args, rb_str_new2("%0*"fmt)); \ + else \ + result = rb_str_format(2, args, rb_str_new2("%*"fmt)); \ + l = strlcpy(s, StringValueCStr(result), endp - s); \ + if ((size_t)(endp - s) <= l) \ + goto err; \ + s += l; \ + } \ + } while (0) + + if (*format != '%') { + *s++ = *format; + continue; + } + tp = tbuf; + sp = format; + precision = -1; + flags = 0; + padding = 0; + colons = 0; + again: + switch (*++format) { + case '\0': + format--; + goto unknown; + + case 'A': /* full weekday name */ + case 'a': /* abbreviated weekday name */ + if (flags & BIT_OF(CHCASE)) { + flags &= ~(BIT_OF(LOWER) | BIT_OF(CHCASE)); + flags |= BIT_OF(UPPER); + } + { + int wday = tmx_wday; + if (wday < 0 || wday > 6) + i = 1, tp = "?"; + else { + if (*format == 'A') + i = strlen(tp = days_l[wday]); + else + i = 3, tp = days_l[wday]; + } + } + break; + + case 'B': /* full month name */ + case 'b': /* abbreviated month name */ + case 'h': /* same as %b */ + if (flags & BIT_OF(CHCASE)) { + flags &= ~(BIT_OF(LOWER) | BIT_OF(CHCASE)); + flags |= BIT_OF(UPPER); + } + { + int mon = tmx_mon; + if (mon < 1 || mon > 12) + i = 1, tp = "?"; + else { + if (*format == 'B') + i = strlen(tp = months_l[mon - 1]); + else + i = 3, tp = months_l[mon - 1]; + } + } + break; + + case 'C': /* century (year/100) */ + FMTV('0', 2, "d", div(tmx_year, INT2FIX(100))); + continue; + + case 'c': /* appropriate date and time representation */ + STRFTIME("%a %b %e %H:%M:%S %Y"); + continue; + + case 'D': + STRFTIME("%m/%d/%y"); + continue; + + case 'd': /* day of the month, 01 - 31 */ + case 'e': /* day of month, blank padded */ + v = range(1, tmx_mday, 31); + FMT((*format == 'd') ? '0' : ' ', 2, "d", v); + continue; + + case 'F': + STRFTIME("%Y-%m-%d"); + continue; + + case 'G': /* year of ISO week with century */ + case 'Y': /* year with century */ + { + VALUE year = (*format == 'G') ? tmx_cwyear : tmx_year; + if (FIXNUM_P(year)) { + long y = FIX2LONG(year); + FMT('0', 0 <= y ? 4 : 5, "ld", y); + } + else { + FMTV('0', 4, "d", year); + } + } + continue; + + case 'g': /* year of ISO week without a century */ + case 'y': /* year without a century */ + v = NUM2INT(mod((*format == 'g') ? tmx_cwyear : tmx_year, INT2FIX(100))); + FMT('0', 2, "d", v); + continue; + + case 'H': /* hour, 24-hour clock, 00 - 23 */ + case 'k': /* hour, 24-hour clock, blank pad */ + v = range(0, tmx_hour, 23); + FMT((*format == 'H') ? '0' : ' ', 2, "d", v); + continue; + + case 'I': /* hour, 12-hour clock, 01 - 12 */ + case 'l': /* hour, 12-hour clock, 1 - 12, blank pad */ + v = range(0, tmx_hour, 23); + if (v == 0) + v = 12; + else if (v > 12) + v -= 12; + FMT((*format == 'I') ? '0' : ' ', 2, "d", v); + continue; + + case 'j': /* day of the year, 001 - 366 */ + v = range(1, tmx_yday, 366); + FMT('0', 3, "d", v); + continue; + + case 'L': /* millisecond */ + case 'N': /* nanosecond */ + if (*format == 'L') + w = 3; + else + w = 9; + if (precision <= 0) + precision = w; + NEEDS(precision); + + { + VALUE subsec = tmx_sec_fraction; + int ww; + long n; + + ww = precision; + while (9 <= ww) { + subsec = mul(subsec, INT2FIX(1000000000)); + ww -= 9; + } + n = 1; + for (; 0 < ww; ww--) + n *= 10; + if (n != 1) + subsec = mul(subsec, INT2FIX(n)); + subsec = div(subsec, INT2FIX(1)); + + if (FIXNUM_P(subsec)) { + (void)snprintf(s, endp - s, "%0*ld", + precision, FIX2LONG(subsec)); + s += precision; + } + else { + VALUE args[2], result; + args[0] = INT2FIX(precision); + args[1] = subsec; + result = rb_str_format(2, args, rb_str_new2("%0*d")); + (void)strlcpy(s, StringValueCStr(result), endp - s); + s += precision; + } + } + continue; + + case 'M': /* minute, 00 - 59 */ + v = range(0, tmx_min, 59); + FMT('0', 2, "d", v); + continue; + + case 'm': /* month, 01 - 12 */ + v = range(1, tmx_mon, 12); + FMT('0', 2, "d", v); + continue; + + case 'n': /* same as \n */ + FILL_PADDING(1); + *s++ = '\n'; + continue; + + case 't': /* same as \t */ + FILL_PADDING(1); + *s++ = '\t'; + continue; + + case 'P': /* am or pm based on 12-hour clock */ + case 'p': /* AM or PM based on 12-hour clock */ + if ((*format == 'p' && (flags & BIT_OF(CHCASE))) || + (*format == 'P' && !(flags & (BIT_OF(CHCASE) | BIT_OF(UPPER))))) { + flags &= ~(BIT_OF(UPPER) | BIT_OF(CHCASE)); + flags |= BIT_OF(LOWER); + } + v = range(0, tmx_hour, 23); + if (v < 12) + tp = ampm[0]; + else + tp = ampm[1]; + i = 2; + break; + + case 'Q': /* milliseconds since Unix epoch */ + FMTV('0', 1, "d", tmx_msecs); + continue; + + case 'R': + STRFTIME("%H:%M"); + continue; + + case 'r': + STRFTIME("%I:%M:%S %p"); + continue; + + case 'S': /* second, 00 - 59 */ + v = range(0, tmx_sec, 59); + FMT('0', 2, "d", v); + continue; + + case 's': /* seconds since Unix epoch */ + FMTV('0', 1, "d", tmx_secs); + continue; + + case 'T': + STRFTIME("%H:%M:%S"); + continue; + + case 'U': /* week of year, Sunday is first day of week */ + case 'W': /* week of year, Monday is first day of week */ + v = range(0, (*format == 'U') ? tmx_wnum0 : tmx_wnum1, 53); + FMT('0', 2, "d", v); + continue; + + case 'u': /* weekday, Monday == 1, 1 - 7 */ + v = range(1, tmx_cwday, 7); + FMT('0', 1, "d", v); + continue; + + case 'V': /* week of year according ISO 8601 */ + v = range(1, tmx_cweek, 53); + FMT('0', 2, "d", v); + continue; + + case 'v': + STRFTIME("%e-%^b-%Y"); + continue; + + case 'w': /* weekday, Sunday == 0, 0 - 6 */ + v = range(0, tmx_wday, 6); + FMT('0', 1, "d", v); + continue; + + case 'X': /* appropriate time representation */ + STRFTIME("%H:%M:%S"); + continue; + + case 'x': /* appropriate date representation */ + STRFTIME("%m/%d/%y"); + continue; + + case 'Z': /* time zone name or abbreviation */ + if (flags & BIT_OF(CHCASE)) { + flags &= ~(BIT_OF(UPPER) | BIT_OF(CHCASE)); + flags |= BIT_OF(LOWER); + } + { + char *zone = tmx_zone; + if (zone == NULL) + tp = ""; + else + tp = zone; + i = strlen(tp); + } + break; + + case 'z': /* offset from UTC */ + { + long off, aoff; + int hl, hw; + + off = tmx_offset; + aoff = off; + if (aoff < 0) + aoff = -off; + + if ((aoff / 3600) < 10) + hl = 1; + else + hl = 2; + hw = 2; + if (flags & BIT_OF(LEFT) && hl == 1) + hw = 1; + + switch (colons) { + case 0: /* %z -> +hhmm */ + precision = precision <= (3 + hw) ? hw : precision - 3; + NEEDS(precision + 3); + break; + + case 1: /* %:z -> +hh:mm */ + precision = precision <= (4 + hw) ? hw : precision - 4; + NEEDS(precision + 4); + break; + + case 2: /* %::z -> +hh:mm:ss */ + precision = precision <= (7 + hw) ? hw : precision - 7; + NEEDS(precision + 7); + break; + + case 3: /* %:::z -> +hh[:mm[:ss]] */ + { + if (aoff % 3600 == 0) { + precision = precision <= (1 + hw) ? + hw : precision - 1; + NEEDS(precision + 3); + } + else if (aoff % 60 == 0) { + precision = precision <= (4 + hw) ? + hw : precision - 4; + NEEDS(precision + 4); + } + else { + precision = precision <= (7 + hw) ? + hw : precision - 7; + NEEDS(precision + 7); + } + } + break; + + default: + format--; + goto unknown; + } + if (padding == ' ' && precision > hl) { + i = snprintf(s, endp - s, "%*s", precision - hl, ""); + precision = hl; + if (i < 0) goto err; + s += i; + } + if (off < 0) { + off = -off; + *s++ = '-'; + } else { + *s++ = '+'; + } + i = snprintf(s, endp - s, "%.*ld", precision, off / 3600); + if (i < 0) goto err; + s += i; + off = off % 3600; + if (colons == 3 && off == 0) + continue; + if (1 <= colons) + *s++ = ':'; + i = snprintf(s, endp - s, "%02d", (int)(off / 60)); + if (i < 0) goto err; + s += i; + off = off % 60; + if (colons == 3 && off == 0) + continue; + if (2 <= colons) { + *s++ = ':'; + i = snprintf(s, endp - s, "%02d", (int)off); + if (i < 0) goto err; + s += i; + } + } + continue; + + case '+': + STRFTIME("%a %b %e %H:%M:%S %Z %Y"); + continue; + + case 'E': + /* POSIX locale extensions, ignored for now */ + flags |= BIT_OF(LOCALE_E); + if (*(format + 1) && strchr("cCxXyY", *(format + 1))) + goto again; + goto unknown; + case 'O': + /* POSIX locale extensions, ignored for now */ + flags |= BIT_OF(LOCALE_O); + if (*(format + 1) && strchr("deHkIlmMSuUVwWy", *(format + 1))) + goto again; + goto unknown; + + case ':': + flags |= BIT_OF(COLONS); + { + size_t l = strspn(format, ":"); + format += l; + if (*format == 'z') { + colons = l; + format--; + goto again; + } + format -= l; + } + goto unknown; + + case '_': + FLAG_FOUND(); + padding = ' '; + goto again; + + case '-': + FLAG_FOUND(); + flags |= BIT_OF(LEFT); + goto again; + + case '^': + FLAG_FOUND(); + flags |= BIT_OF(UPPER); + goto again; + + case '#': + FLAG_FOUND(); + flags |= BIT_OF(CHCASE); + goto again; + + case '0': + FLAG_FOUND(); + padding = '0'; + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + { + char *e; + unsigned long prec = strtoul(format, &e, 10); + if (prec > INT_MAX || prec > maxsize) { + errno = ERANGE; + return 0; + } + precision = (int)prec; + format = e - 1; + goto again; + } + + case '%': + FILL_PADDING(1); + *s++ = '%'; + continue; + + default: + unknown: + i = format - sp + 1; + tp = sp; + precision = -1; + flags = 0; + padding = 0; + colons = 0; + break; + } + if (i) { + FILL_PADDING(i); + memcpy(s, tp, i); + switch (flags & (BIT_OF(UPPER) | BIT_OF(LOWER))) { + case BIT_OF(UPPER): + upcase(s, i); + break; + case BIT_OF(LOWER): + downcase(s, i); + break; + } + s += i; + } + } + if (s >= endp) { + goto err; + } + if (*format == '\0') { + *s = '\0'; + return (s - start); + } + return 0; +} + +size_t +date_strftime(char *s, size_t maxsize, const char *format, + const struct tmx *tmx) +{ + return date_strftime_with_tmx(s, maxsize, format, tmx); +} + +/* +Local variables: +c-file-style: "ruby" +End: +*/ diff --git a/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/date_strptime.c b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/date_strptime.c new file mode 100644 index 00000000..da58c21a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/date_strptime.c @@ -0,0 +1,703 @@ +/* + date_strptime.c: Coded by Tadayoshi Funaba 2011,2012 +*/ + +#include "ruby.h" +#include "ruby/encoding.h" +#include "ruby/re.h" +#include + +#undef strncasecmp +#define strncasecmp STRNCASECMP + +static const char *day_names[] = { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday", +}; +static const int ABBREVIATED_DAY_NAME_LENGTH = 3; + +static const char *month_names[] = { + "January", "February", "March", "April", + "May", "June", "July", "August", "September", + "October", "November", "December", +}; +static const int ABBREVIATED_MONTH_NAME_LENGTH = 3; + +#define sizeof_array(o) (sizeof o / sizeof o[0]) + +#define f_negate(x) rb_funcall(x, rb_intern("-@"), 0) +#define f_add(x,y) rb_funcall(x, '+', 1, y) +#define f_sub(x,y) rb_funcall(x, '-', 1, y) +#define f_mul(x,y) rb_funcall(x, '*', 1, y) +#define f_div(x,y) rb_funcall(x, '/', 1, y) +#define f_idiv(x,y) rb_funcall(x, rb_intern("div"), 1, y) +#define f_mod(x,y) rb_funcall(x, '%', 1, y) +#define f_expt(x,y) rb_funcall(x, rb_intern("**"), 1, y) + +#define f_lt_p(x,y) rb_funcall(x, '<', 1, y) +#define f_gt_p(x,y) rb_funcall(x, '>', 1, y) +#define f_le_p(x,y) rb_funcall(x, rb_intern("<="), 1, y) +#define f_ge_p(x,y) rb_funcall(x, rb_intern(">="), 1, y) + +#define f_match(r,s) rb_funcall(r, rb_intern("match"), 1, s) +#define f_aref(o,i) rb_funcall(o, rb_intern("[]"), 1, i) +#define f_end(o,i) rb_funcall(o, rb_intern("end"), 1, i) + +#define issign(c) ((c) == '-' || (c) == '+') + +static int +num_pattern_p(const char *s) +{ + if (isdigit((unsigned char)*s)) + return 1; + if (*s == '%') { + s++; + if (*s == 'E' || *s == 'O') + s++; + if (*s && + (strchr("CDdeFGgHIjkLlMmNQRrSsTUuVvWwXxYy", *s) || + isdigit((unsigned char)*s))) + return 1; + } + return 0; +} + +#define NUM_PATTERN_P() num_pattern_p(&fmt[fi + 1]) + +static long +read_digits(const char *s, size_t slen, VALUE *n, size_t width) +{ + size_t l; + + if (!width) + return 0; + + l = 0; + while (l < slen && ISDIGIT(s[l])) { + if (++l == width) break; + } + + if (l == 0) + return 0; + + if ((4 * l * sizeof(char)) <= (sizeof(long)*CHAR_BIT)) { + const char *os = s; + long v; + + v = 0; + while ((size_t)(s - os) < l) { + v *= 10; + v += *s - '0'; + s++; + } + if (os == s) + return 0; + *n = LONG2NUM(v); + return l; + } + else { + VALUE vbuf = 0; + char *s2 = ALLOCV_N(char, vbuf, l + 1); + memcpy(s2, s, l); + s2[l] = '\0'; + *n = rb_cstr_to_inum(s2, 10, 0); + ALLOCV_END(vbuf); + return l; + } +} + +#define set_hash(k,v) rb_hash_aset(hash, ID2SYM(rb_intern(k"")), v) +#define ref_hash(k) rb_hash_aref(hash, ID2SYM(rb_intern(k""))) +#define del_hash(k) rb_hash_delete(hash, ID2SYM(rb_intern(k""))) + +#define fail() \ +do { \ + set_hash("_fail", Qtrue); \ + return 0; \ +} while (0) + +#define fail_p() (!NIL_P(ref_hash("_fail"))) + +#define READ_DIGITS(n,w) \ +do { \ + size_t l; \ + l = read_digits(&str[si], slen - si, &n, w); \ + if (l == 0) \ + fail(); \ + si += l; \ +} while (0) + +#define READ_DIGITS_MAX(n) READ_DIGITS(n, LONG_MAX) + +static int +valid_range_p(VALUE v, int a, int b) +{ + if (FIXNUM_P(v)) { + int vi = FIX2INT(v); + return !(vi < a || vi > b); + } + return !(f_lt_p(v, INT2NUM(a)) || f_gt_p(v, INT2NUM(b))); +} + +#define recur(fmt) \ +do { \ + size_t l; \ + l = date__strptime_internal(&str[si], slen - si, \ + fmt, sizeof fmt - 1, hash); \ + if (fail_p()) \ + return 0; \ + si += l; \ +} while (0) + +VALUE date_zone_to_diff(VALUE); + +static inline int +head_match_p(size_t len, const char *name, const char *str, size_t slen, size_t si) +{ + return slen - si >= len && strncasecmp(name, &str[si], len) == 0; +} + +static size_t +date__strptime_internal(const char *str, size_t slen, + const char *fmt, size_t flen, VALUE hash) +{ + size_t si, fi; + int c; + +#define HEAD_MATCH_P(len, name) head_match_p(len, name, str, slen, si) + si = fi = 0; + + while (fi < flen) { + if (isspace((unsigned char)fmt[fi])) { + while (si < slen && isspace((unsigned char)str[si])) + si++; + while (++fi < flen && isspace((unsigned char)fmt[fi])); + continue; + } + + if (si >= slen) fail(); + + switch (fmt[fi]) { + case '%': + + again: + fi++; + c = fmt[fi]; + + switch (c) { + case 'E': + if (fmt[fi + 1] && strchr("cCxXyY", fmt[fi + 1])) + goto again; + fi--; + goto ordinal; + case 'O': + if (fmt[fi + 1] && strchr("deHImMSuUVwWy", fmt[fi + 1])) + goto again; + fi--; + goto ordinal; + case ':': + { + int i; + + for (i = 1; i < 3 && fi + i < flen && fmt[fi+i] == ':'; ++i); + if (fmt[fi+i] == 'z') { + fi += i - 1; + goto again; + } + fail(); + } + + case 'A': + case 'a': + { + int i; + + for (i = 0; i < (int)sizeof_array(day_names); i++) { + const char *day_name = day_names[i]; + size_t l = strlen(day_name); + if (HEAD_MATCH_P(l, day_name) || + HEAD_MATCH_P(l = ABBREVIATED_DAY_NAME_LENGTH, day_name)) { + si += l; + set_hash("wday", INT2FIX(i)); + goto matched; + } + } + fail(); + } + case 'B': + case 'b': + case 'h': + { + int i; + + for (i = 0; i < (int)sizeof_array(month_names); i++) { + const char *month_name = month_names[i]; + size_t l = strlen(month_name); + if (HEAD_MATCH_P(l, month_name) || + HEAD_MATCH_P(l = ABBREVIATED_MONTH_NAME_LENGTH, month_name)) { + si += l; + set_hash("mon", INT2FIX(i + 1)); + goto matched; + } + } + fail(); + } + + case 'C': + { + VALUE n; + + if (NUM_PATTERN_P()) + READ_DIGITS(n, 2); + else + READ_DIGITS_MAX(n); + set_hash("_cent", n); + goto matched; + } + + case 'c': + recur("%a %b %e %H:%M:%S %Y"); + goto matched; + + case 'D': + recur("%m/%d/%y"); + goto matched; + + case 'd': + case 'e': + { + VALUE n; + + if (str[si] == ' ') { + si++; + READ_DIGITS(n, 1); + } else { + READ_DIGITS(n, 2); + } + if (!valid_range_p(n, 1, 31)) + fail(); + set_hash("mday", n); + goto matched; + } + + case 'F': + recur("%Y-%m-%d"); + goto matched; + + case 'G': + { + VALUE n; + + if (NUM_PATTERN_P()) + READ_DIGITS(n, 4); + else + READ_DIGITS_MAX(n); + set_hash("cwyear", n); + goto matched; + } + + case 'g': + { + VALUE n; + + READ_DIGITS(n, 2); + if (!valid_range_p(n, 0, 99)) + fail(); + set_hash("cwyear",n); + if (NIL_P(ref_hash("_cent"))) + set_hash("_cent", + INT2FIX(f_ge_p(n, INT2FIX(69)) ? 19 : 20)); + goto matched; + } + + case 'H': + case 'k': + { + VALUE n; + + if (str[si] == ' ') { + si++; + READ_DIGITS(n, 1); + } else { + READ_DIGITS(n, 2); + } + if (!valid_range_p(n, 0, 24)) + fail(); + set_hash("hour", n); + goto matched; + } + + case 'I': + case 'l': + { + VALUE n; + + if (str[si] == ' ') { + si++; + READ_DIGITS(n, 1); + } else { + READ_DIGITS(n, 2); + } + if (!valid_range_p(n, 1, 12)) + fail(); + set_hash("hour", n); + goto matched; + } + + case 'j': + { + VALUE n; + + READ_DIGITS(n, 3); + if (!valid_range_p(n, 1, 366)) + fail(); + set_hash("yday", n); + goto matched; + } + + case 'L': + case 'N': + { + VALUE n; + int sign = 1; + size_t osi; + + if (issign(str[si])) { + if (str[si] == '-') + sign = -1; + si++; + } + osi = si; + if (NUM_PATTERN_P()) + READ_DIGITS(n, c == 'L' ? 3 : 9); + else + READ_DIGITS_MAX(n); + if (sign == -1) + n = f_negate(n); + set_hash("sec_fraction", + rb_rational_new2(n, + f_expt(INT2FIX(10), + ULONG2NUM(si - osi)))); + goto matched; + } + + case 'M': + { + VALUE n; + + READ_DIGITS(n, 2); + if (!valid_range_p(n, 0, 59)) + fail(); + set_hash("min", n); + goto matched; + } + + case 'm': + { + VALUE n; + + READ_DIGITS(n, 2); + if (!valid_range_p(n, 1, 12)) + fail(); + set_hash("mon", n); + goto matched; + } + + case 'n': + case 't': + recur(" "); + goto matched; + + case 'P': + case 'p': + if (slen - si < 2) fail(); + { + char c = str[si]; + const int hour = (c == 'P' || c == 'p') ? 12 : 0; + if (!hour && !(c == 'A' || c == 'a')) fail(); + if ((c = str[si+1]) == '.') { + if (slen - si < 4 || str[si+3] != '.') fail(); + c = str[si += 2]; + } + if (!(c == 'M' || c == 'm')) fail(); + si += 2; + set_hash("_merid", INT2FIX(hour)); + goto matched; + } + + case 'Q': + { + VALUE n; + int sign = 1; + + if (str[si] == '-') { + sign = -1; + si++; + } + READ_DIGITS_MAX(n); + if (sign == -1) + n = f_negate(n); + set_hash("seconds", + rb_rational_new2(n, INT2FIX(1000))); + goto matched; + } + + case 'R': + recur("%H:%M"); + goto matched; + + case 'r': + recur("%I:%M:%S %p"); + goto matched; + + case 'S': + { + VALUE n; + + READ_DIGITS(n, 2); + if (!valid_range_p(n, 0, 60)) + fail(); + set_hash("sec", n); + goto matched; + } + + case 's': + { + VALUE n; + int sign = 1; + + if (str[si] == '-') { + sign = -1; + si++; + } + READ_DIGITS_MAX(n); + if (sign == -1) + n = f_negate(n); + set_hash("seconds", n); + goto matched; + } + + case 'T': + recur("%H:%M:%S"); + goto matched; + + case 'U': + case 'W': + { + VALUE n; + + READ_DIGITS(n, 2); + if (!valid_range_p(n, 0, 53)) + fail(); + set_hash(c == 'U' ? "wnum0" : "wnum1", n); + goto matched; + } + + case 'u': + { + VALUE n; + + READ_DIGITS(n, 1); + if (!valid_range_p(n, 1, 7)) + fail(); + set_hash("cwday", n); + goto matched; + } + + case 'V': + { + VALUE n; + + READ_DIGITS(n, 2); + if (!valid_range_p(n, 1, 53)) + fail(); + set_hash("cweek", n); + goto matched; + } + + case 'v': + recur("%e-%b-%Y"); + goto matched; + + case 'w': + { + VALUE n; + + READ_DIGITS(n, 1); + if (!valid_range_p(n, 0, 6)) + fail(); + set_hash("wday", n); + goto matched; + } + + case 'X': + recur("%H:%M:%S"); + goto matched; + + case 'x': + recur("%m/%d/%y"); + goto matched; + + case 'Y': + { + VALUE n; + int sign = 1; + + if (issign(str[si])) { + if (str[si] == '-') + sign = -1; + si++; + } + if (NUM_PATTERN_P()) + READ_DIGITS(n, 4); + else + READ_DIGITS_MAX(n); + if (sign == -1) + n = f_negate(n); + set_hash("year", n); + goto matched; + } + + case 'y': + { + VALUE n; + int sign = 1; + + READ_DIGITS(n, 2); + if (!valid_range_p(n, 0, 99)) + fail(); + if (sign == -1) + n = f_negate(n); + set_hash("year", n); + if (NIL_P(ref_hash("_cent"))) + set_hash("_cent", + INT2FIX(f_ge_p(n, INT2FIX(69)) ? 19 : 20)); + goto matched; + } + + case 'Z': + case 'z': + { + static const char pat_source[] = + "\\A(" + "(?:gmt|utc?)?[-+]\\d+(?:[,.:]\\d+(?::\\d+)?)?" + "|(?-i:[[:alpha:].\\s]+)(?:standard|daylight)\\s+time\\b" + "|(?-i:[[:alpha:]]+)(?:\\s+dst)?\\b" + ")"; + static VALUE pat = Qnil; + VALUE m, b; + + if (NIL_P(pat)) { + pat = rb_reg_new(pat_source, sizeof pat_source - 1, + ONIG_OPTION_IGNORECASE); + rb_obj_freeze(pat); + rb_gc_register_mark_object(pat); + } + + b = rb_backref_get(); + rb_match_busy(b); + m = f_match(pat, rb_usascii_str_new(&str[si], slen - si)); + + if (!NIL_P(m)) { + VALUE s, l, o; + + s = rb_reg_nth_match(1, m); + l = f_end(m, INT2FIX(0)); + o = date_zone_to_diff(s); + si += NUM2LONG(l); + set_hash("zone", s); + set_hash("offset", o); + rb_backref_set(b); + goto matched; + } + rb_backref_set(b); + fail(); + } + + case '%': + if (str[si] != '%') + fail(); + si++; + goto matched; + + case '+': + recur("%a %b %e %H:%M:%S %Z %Y"); + goto matched; + + default: + if (str[si] != '%') + fail(); + si++; + if (fi < flen) { + if (si >= slen || str[si] != fmt[fi]) + fail(); + si++; + } + goto matched; + } + default: + ordinal: + if (str[si] != fmt[fi]) + fail(); + si++; + fi++; + break; + matched: + fi++; + break; + } + } + + return si; +} + +VALUE +date__strptime(const char *str, size_t slen, + const char *fmt, size_t flen, VALUE hash) +{ + size_t si; + VALUE cent, merid; + + si = date__strptime_internal(str, slen, fmt, flen, hash); + + if (slen > si) { + VALUE s; + + s = rb_usascii_str_new(&str[si], slen - si); + set_hash("leftover", s); + } + + if (fail_p()) + return Qnil; + + cent = del_hash("_cent"); + if (!NIL_P(cent)) { + VALUE year; + + year = ref_hash("cwyear"); + if (!NIL_P(year)) + set_hash("cwyear", f_add(year, f_mul(cent, INT2FIX(100)))); + year = ref_hash("year"); + if (!NIL_P(year)) + set_hash("year", f_add(year, f_mul(cent, INT2FIX(100)))); + } + + merid = del_hash("_merid"); + if (!NIL_P(merid)) { + VALUE hour; + + hour = ref_hash("hour"); + if (!NIL_P(hour)) { + hour = f_mod(hour, INT2FIX(12)); + set_hash("hour", f_add(hour, merid)); + } + } + + return hash; +} + +/* +Local variables: +c-file-style: "ruby" +End: +*/ diff --git a/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/date_tmx.h b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/date_tmx.h new file mode 100644 index 00000000..993a1532 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/date_tmx.h @@ -0,0 +1,56 @@ +#ifndef DATE_TMX_H +#define DATE_TMX_H + +struct tmx_funcs { + VALUE (*year)(void *dat); + int (*yday)(void *dat); + int (*mon)(void *dat); + int (*mday)(void *dat); + VALUE (*cwyear)(void *dat); + int (*cweek)(void *dat); + int (*cwday)(void *dat); + int (*wnum0)(void *dat); + int (*wnum1)(void *dat); + int (*wday)(void *dat); + int (*hour)(void *dat); + int (*min)(void *dat); + int (*sec)(void *dat); + VALUE (*sec_fraction)(void *dat); + VALUE (*secs)(void *dat); + VALUE (*msecs)(void *dat); + int (*offset)(void *dat); + char *(*zone)(void *dat); +}; +struct tmx { + void *dat; + const struct tmx_funcs *funcs; +}; + +#define tmx_attr(x) (tmx->funcs->x)(tmx->dat) + +#define tmx_year tmx_attr(year) +#define tmx_yday tmx_attr(yday) +#define tmx_mon tmx_attr(mon) +#define tmx_mday tmx_attr(mday) +#define tmx_cwyear tmx_attr(cwyear) +#define tmx_cweek tmx_attr(cweek) +#define tmx_cwday tmx_attr(cwday) +#define tmx_wnum0 tmx_attr(wnum0) +#define tmx_wnum1 tmx_attr(wnum1) +#define tmx_wday tmx_attr(wday) +#define tmx_hour tmx_attr(hour) +#define tmx_min tmx_attr(min) +#define tmx_sec tmx_attr(sec) +#define tmx_sec_fraction tmx_attr(sec_fraction) +#define tmx_secs tmx_attr(secs) +#define tmx_msecs tmx_attr(msecs) +#define tmx_offset tmx_attr(offset) +#define tmx_zone tmx_attr(zone) + +#endif + +/* +Local variables: +c-file-style: "ruby" +End: +*/ diff --git a/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/extconf.rb b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/extconf.rb new file mode 100644 index 00000000..8a1467df --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/extconf.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true +require 'mkmf' + +config_string("strict_warnflags") {|w| $warnflags += " #{w}"} + +append_cflags("-Wno-compound-token-split-by-macro") if RUBY_VERSION < "2.7." +have_func("rb_category_warn") +with_werror("", {:werror => true}) do |opt, | + have_var("timezone", "time.h", opt) + have_var("altzone", "time.h", opt) +end + +create_makefile('date_core') diff --git a/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/prereq.mk b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/prereq.mk new file mode 100644 index 00000000..b5d271a3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/prereq.mk @@ -0,0 +1,19 @@ +.SUFFIXES: .list + +.list.h: + gperf --ignore-case -L ANSI-C -C -c -P -p -j1 -i 1 -g -o -t -N $(*F) $< \ + | sed -f $(top_srcdir)/tool/gperf.sed \ + > $(@F) + +zonetab.h: zonetab.list + +.PHONY: update-zonetab +update-zonetab: + $(RUBY) -C $(srcdir) update-abbr + +.PHONY: update-nothing +update-nothing: + +update = nothing + +zonetab.list: update-$(update) diff --git a/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/zonetab.h b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/zonetab.h new file mode 100644 index 00000000..2a2e8910 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/zonetab.h @@ -0,0 +1,1564 @@ +/* ANSI-C code produced by gperf version 3.1 */ +/* Command-line: gperf --ignore-case -L ANSI-C -C -c -P -p -j1 -i 1 -g -o -t -N zonetab zonetab.list */ +/* Computed positions: -k'1-4,9' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 1 "zonetab.list" + +#define GPERF_DOWNCASE 1 +#define GPERF_CASE_STRNCMP 1 +#define gperf_case_strncmp strncasecmp +struct zone { + int name; + int offset; +}; +static const struct zone *zonetab(register const char *str, register size_t len); +#line 12 "zonetab.list" +struct zone; + +#define TOTAL_KEYWORDS 316 +#define MIN_WORD_LENGTH 1 +#define MAX_WORD_LENGTH 17 +#define MIN_HASH_VALUE 2 +#define MAX_HASH_VALUE 619 +/* maximum key range = 618, duplicates = 0 */ + +#ifndef GPERF_DOWNCASE +#define GPERF_DOWNCASE 1 +static unsigned char gperf_downcase[256] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255 + }; +#endif + +#ifndef GPERF_CASE_STRNCMP +#define GPERF_CASE_STRNCMP 1 +static int +gperf_case_strncmp (register const char *s1, register const char *s2, register size_t n) +{ + for (; n > 0;) + { + unsigned char c1 = gperf_downcase[(unsigned char)*s1++]; + unsigned char c2 = gperf_downcase[(unsigned char)*s2++]; + if (c1 != 0 && c1 == c2) + { + n--; + continue; + } + return (int)c1 - (int)c2; + } + return 0; +} +#endif + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +hash (register const char *str, register size_t len) +{ + static const unsigned short asso_values[] = + { + 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 17, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 3, 2, 620, 620, 620, + 620, 620, 70, 8, 3, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 39, 176, 207, 70, 168, + 1, 5, 18, 74, 218, 2, 117, 130, 48, 88, + 125, 225, 92, 1, 1, 12, 54, 30, 36, 13, + 48, 168, 263, 59, 114, 166, 109, 39, 176, 207, + 70, 168, 1, 5, 18, 74, 218, 2, 117, 130, + 48, 88, 125, 225, 92, 1, 1, 12, 54, 30, + 36, 13, 48, 168, 263, 59, 114, 166, 109, 27, + 104, 1, 9, 4, 309, 190, 188, 177, 255, 108, + 2, 341, 3, 620, 620, 620, 620, 620, 620, 12, + 54, 30, 36, 13, 48, 168, 263, 59, 114, 166, + 109, 27, 104, 1, 9, 4, 309, 190, 188, 177, + 255, 108, 2, 341, 3, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620 + }; + register unsigned int hval = (unsigned int)len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[8]]; + /*FALLTHROUGH*/ + case 8: + case 7: + case 6: + case 5: + case 4: + hval += asso_values[(unsigned char)str[3]]; + /*FALLTHROUGH*/ + case 3: + hval += asso_values[(unsigned char)str[2]]; + /*FALLTHROUGH*/ + case 2: + hval += asso_values[(unsigned char)str[1]+6]; + /*FALLTHROUGH*/ + case 1: + hval += asso_values[(unsigned char)str[0]+52]; + break; + } + return (unsigned int)hval; +} + +struct stringpool_t + { + char stringpool_str2[sizeof("o")]; + char stringpool_str3[sizeof("x")]; + char stringpool_str4[sizeof("z")]; + char stringpool_str5[sizeof("q")]; + char stringpool_str8[sizeof("omst")]; + char stringpool_str9[sizeof("omsst")]; + char stringpool_str10[sizeof("p")]; + char stringpool_str13[sizeof("a")]; + char stringpool_str14[sizeof("e")]; + char stringpool_str15[sizeof("pet")]; + char stringpool_str16[sizeof("pmst")]; + char stringpool_str17[sizeof("pett")]; + char stringpool_str18[sizeof("petst")]; + char stringpool_str19[sizeof("eet")]; + char stringpool_str20[sizeof("aest")]; + char stringpool_str21[sizeof("eest")]; + char stringpool_str22[sizeof("eat")]; + char stringpool_str24[sizeof("east")]; + char stringpool_str25[sizeof("easst")]; + char stringpool_str26[sizeof("pst")]; + char stringpool_str27[sizeof("eastern")]; + char stringpool_str28[sizeof("m")]; + char stringpool_str29[sizeof("ast")]; + char stringpool_str30[sizeof("est")]; + char stringpool_str31[sizeof("c")]; + char stringpool_str32[sizeof("mmt")]; + char stringpool_str33[sizeof("met")]; + char stringpool_str35[sizeof("mest")]; + char stringpool_str36[sizeof("cet")]; + char stringpool_str37[sizeof("d")]; + char stringpool_str38[sizeof("cest")]; + char stringpool_str39[sizeof("cat")]; + char stringpool_str41[sizeof("cast")]; + char stringpool_str42[sizeof("magt")]; + char stringpool_str43[sizeof("magst")]; + char stringpool_str44[sizeof("mst")]; + char stringpool_str45[sizeof("msk")]; + char stringpool_str46[sizeof("cot")]; + char stringpool_str47[sizeof("cst")]; + char stringpool_str48[sizeof("aqtt")]; + char stringpool_str49[sizeof("f")]; + char stringpool_str52[sizeof("art")]; + char stringpool_str53[sizeof("fnt")]; + char stringpool_str54[sizeof("fet")]; + char stringpool_str55[sizeof("b")]; + char stringpool_str57[sizeof("anat")]; + char stringpool_str58[sizeof("anast")]; + char stringpool_str59[sizeof("bnt")]; + char stringpool_str60[sizeof("i")]; + char stringpool_str61[sizeof("pht")]; + char stringpool_str62[sizeof("at")]; + char stringpool_str63[sizeof("zp6")]; + char stringpool_str64[sizeof("mewt")]; + char stringpool_str65[sizeof("fst")]; + char stringpool_str66[sizeof("ahst")]; + char stringpool_str67[sizeof("mawt")]; + char stringpool_str68[sizeof("zp5")]; + char stringpool_str70[sizeof("bot")]; + char stringpool_str71[sizeof("bst")]; + char stringpool_str72[sizeof("pwt")]; + char stringpool_str74[sizeof("pont")]; + char stringpool_str75[sizeof("iot")]; + char stringpool_str76[sizeof("ist")]; + char stringpool_str77[sizeof("awst")]; + char stringpool_str79[sizeof("mht")]; + char stringpool_str80[sizeof("mez")]; + char stringpool_str81[sizeof("orat")]; + char stringpool_str82[sizeof("mesz")]; + char stringpool_str84[sizeof("chst")]; + char stringpool_str85[sizeof("pmdt")]; + char stringpool_str88[sizeof("central")]; + char stringpool_str89[sizeof("aedt")]; + char stringpool_str90[sizeof("act")]; + char stringpool_str91[sizeof("ect")]; + char stringpool_str92[sizeof("acst")]; + char stringpool_str93[sizeof("eadt")]; + char stringpool_str94[sizeof("brt")]; + char stringpool_str95[sizeof("chut")]; + char stringpool_str96[sizeof("brst")]; + char stringpool_str97[sizeof("cen. australia")]; + char stringpool_str100[sizeof("davt")]; + char stringpool_str101[sizeof("irst")]; + char stringpool_str102[sizeof("irkt")]; + char stringpool_str103[sizeof("irkst")]; + char stringpool_str104[sizeof("bt")]; + char stringpool_str105[sizeof("n")]; + char stringpool_str106[sizeof("btt")]; + char stringpool_str107[sizeof("mountain")]; + char stringpool_str108[sizeof("cct")]; + char stringpool_str109[sizeof("w")]; + char stringpool_str110[sizeof("l")]; + char stringpool_str111[sizeof("fwt")]; + char stringpool_str113[sizeof("msd")]; + char stringpool_str114[sizeof("wet")]; + char stringpool_str116[sizeof("west")]; + char stringpool_str117[sizeof("wat")]; + char stringpool_str119[sizeof("wast")]; + char stringpool_str120[sizeof("wakt")]; + char stringpool_str121[sizeof("nst")]; + char stringpool_str122[sizeof("acwst")]; + char stringpool_str123[sizeof("chast")]; + char stringpool_str124[sizeof("cist")]; + char stringpool_str125[sizeof("azt")]; + char stringpool_str126[sizeof("clt")]; + char stringpool_str127[sizeof("azst")]; + char stringpool_str128[sizeof("clst")]; + char stringpool_str129[sizeof("mart")]; + char stringpool_str130[sizeof("zp4")]; + char stringpool_str131[sizeof("jst")]; + char stringpool_str132[sizeof("central asia")]; + char stringpool_str133[sizeof("aft")]; + char stringpool_str134[sizeof("e. south america")]; + char stringpool_str135[sizeof("central america")]; + char stringpool_str137[sizeof("ict")]; + char stringpool_str143[sizeof("pgt")]; + char stringpool_str144[sizeof("nrt")]; + char stringpool_str145[sizeof("mexico")]; + char stringpool_str146[sizeof("awdt")]; + char stringpool_str147[sizeof("egt")]; + char stringpool_str148[sizeof("cxt")]; + char stringpool_str149[sizeof("egst")]; + char stringpool_str150[sizeof("phot")]; + char stringpool_str151[sizeof("alaskan")]; + char stringpool_str154[sizeof("nt")]; + char stringpool_str158[sizeof("wt")]; + char stringpool_str160[sizeof("west asia")]; + char stringpool_str161[sizeof("acdt")]; + char stringpool_str162[sizeof("npt")]; + char stringpool_str163[sizeof("lhst")]; + char stringpool_str164[sizeof("afghanistan")]; + char stringpool_str167[sizeof("k")]; + char stringpool_str169[sizeof("g")]; + char stringpool_str170[sizeof("irdt")]; + char stringpool_str171[sizeof("chot")]; + char stringpool_str172[sizeof("chost")]; + char stringpool_str173[sizeof("gmt")]; + char stringpool_str174[sizeof("get")]; + char stringpool_str175[sizeof("novt")]; + char stringpool_str176[sizeof("novst")]; + char stringpool_str177[sizeof("fjt")]; + char stringpool_str178[sizeof("u")]; + char stringpool_str179[sizeof("fjst")]; + char stringpool_str181[sizeof("pyst")]; + char stringpool_str182[sizeof("nct")]; + char stringpool_str183[sizeof("kst")]; + char stringpool_str184[sizeof("kost")]; + char stringpool_str185[sizeof("gst")]; + char stringpool_str186[sizeof("iran")]; + char stringpool_str187[sizeof("e. africa")]; + char stringpool_str188[sizeof("wadt")]; + char stringpool_str189[sizeof("t")]; + char stringpool_str190[sizeof("e. australia")]; + char stringpool_str191[sizeof("s")]; + char stringpool_str192[sizeof("chadt")]; + char stringpool_str193[sizeof("tmt")]; + char stringpool_str194[sizeof("cidst")]; + char stringpool_str195[sizeof("aoe")]; + char stringpool_str197[sizeof("myt")]; + char stringpool_str198[sizeof("west pacific")]; + char stringpool_str199[sizeof("mut")]; + char stringpool_str200[sizeof("wit")]; + char stringpool_str201[sizeof("sast")]; + char stringpool_str202[sizeof("sakt")]; + char stringpool_str203[sizeof("new zealand")]; + char stringpool_str204[sizeof("tot")]; + char stringpool_str205[sizeof("china")]; + char stringpool_str206[sizeof("tost")]; + char stringpool_str207[sizeof("sst")]; + char stringpool_str209[sizeof("india")]; + char stringpool_str211[sizeof("warst")]; + char stringpool_str212[sizeof("sbt")]; + char stringpool_str214[sizeof("azot")]; + char stringpool_str215[sizeof("azost")]; + char stringpool_str216[sizeof("taht")]; + char stringpool_str217[sizeof("nzt")]; + char stringpool_str218[sizeof("dateline")]; + char stringpool_str219[sizeof("nzst")]; + char stringpool_str220[sizeof("tokyo")]; + char stringpool_str221[sizeof("central pacific")]; + char stringpool_str223[sizeof("qyzt")]; + char stringpool_str224[sizeof("atlantic")]; + char stringpool_str225[sizeof("nft")]; + char stringpool_str227[sizeof("ut")]; + char stringpool_str228[sizeof("trt")]; + char stringpool_str229[sizeof("wft")]; + char stringpool_str230[sizeof("srt")]; + char stringpool_str231[sizeof("pdt")]; + char stringpool_str232[sizeof("lhdt")]; + char stringpool_str234[sizeof("adt")]; + char stringpool_str235[sizeof("edt")]; + char stringpool_str238[sizeof("pkt")]; + char stringpool_str239[sizeof("almt")]; + char stringpool_str240[sizeof("wita")]; + char stringpool_str242[sizeof("wgt")]; + char stringpool_str243[sizeof("akst")]; + char stringpool_str244[sizeof("wgst")]; + char stringpool_str246[sizeof("krat")]; + char stringpool_str247[sizeof("krast")]; + char stringpool_str248[sizeof("mid-atlantic")]; + char stringpool_str249[sizeof("mdt")]; + char stringpool_str250[sizeof("lint")]; + char stringpool_str251[sizeof("malay peninsula")]; + char stringpool_str252[sizeof("cdt")]; + char stringpool_str253[sizeof("swt")]; + char stringpool_str255[sizeof("se asia")]; + char stringpool_str256[sizeof("v")]; + char stringpool_str258[sizeof("tonga")]; + char stringpool_str259[sizeof("ckt")]; + char stringpool_str261[sizeof("vet")]; + char stringpool_str262[sizeof("caucasus")]; + char stringpool_str263[sizeof("central europe")]; + char stringpool_str264[sizeof("h")]; + char stringpool_str265[sizeof("central european")]; + char stringpool_str266[sizeof("newfoundland")]; + char stringpool_str267[sizeof("arab")]; + char stringpool_str268[sizeof("sct")]; + char stringpool_str269[sizeof("arabic")]; + char stringpool_str270[sizeof("arabian")]; + char stringpool_str271[sizeof("ddut")]; + char stringpool_str273[sizeof("vost")]; + char stringpool_str274[sizeof("hast")]; + char stringpool_str275[sizeof("nepal")]; + char stringpool_str276[sizeof("nut")]; + char stringpool_str277[sizeof("fkt")]; + char stringpool_str279[sizeof("fkst")]; + char stringpool_str280[sizeof("hst")]; + char stringpool_str281[sizeof("idt")]; + char stringpool_str284[sizeof("tlt")]; + char stringpool_str285[sizeof("w. australia")]; + char stringpool_str286[sizeof("egypt")]; + char stringpool_str287[sizeof("myanmar")]; + char stringpool_str288[sizeof("nzdt")]; + char stringpool_str289[sizeof("gft")]; + char stringpool_str290[sizeof("uzt")]; + char stringpool_str293[sizeof("north asia")]; + char stringpool_str294[sizeof("mvt")]; + char stringpool_str295[sizeof("galt")]; + char stringpool_str296[sizeof("nfdt")]; + char stringpool_str297[sizeof("cvt")]; + char stringpool_str298[sizeof("north asia east")]; + char stringpool_str300[sizeof("kgt")]; + char stringpool_str301[sizeof("aus central")]; + char stringpool_str302[sizeof("pacific")]; + char stringpool_str304[sizeof("canada central")]; + char stringpool_str306[sizeof("pacific sa")]; + char stringpool_str307[sizeof("azores")]; + char stringpool_str308[sizeof("gamt")]; + char stringpool_str309[sizeof("tft")]; + char stringpool_str310[sizeof("r")]; + char stringpool_str311[sizeof("fle")]; + char stringpool_str312[sizeof("akdt")]; + char stringpool_str313[sizeof("ulat")]; + char stringpool_str314[sizeof("ulast")]; + char stringpool_str315[sizeof("ret")]; + char stringpool_str317[sizeof("tjt")]; + char stringpool_str319[sizeof("south africa")]; + char stringpool_str324[sizeof("sgt")]; + char stringpool_str326[sizeof("ndt")]; + char stringpool_str327[sizeof("rott")]; + char stringpool_str330[sizeof("samt")]; + char stringpool_str332[sizeof("tasmania")]; + char stringpool_str334[sizeof("hovt")]; + char stringpool_str335[sizeof("hovst")]; + char stringpool_str338[sizeof("gyt")]; + char stringpool_str342[sizeof("y")]; + char stringpool_str343[sizeof("hadt")]; + char stringpool_str344[sizeof("sa western")]; + char stringpool_str345[sizeof("hawaiian")]; + char stringpool_str347[sizeof("uyt")]; + char stringpool_str349[sizeof("uyst")]; + char stringpool_str350[sizeof("yekt")]; + char stringpool_str351[sizeof("yekst")]; + char stringpool_str352[sizeof("kuyt")]; + char stringpool_str353[sizeof("yakt")]; + char stringpool_str354[sizeof("yakst")]; + char stringpool_str358[sizeof("yst")]; + char stringpool_str359[sizeof("jerusalem")]; + char stringpool_str365[sizeof("sri lanka")]; + char stringpool_str367[sizeof("yakutsk")]; + char stringpool_str375[sizeof("wib")]; + char stringpool_str377[sizeof("aus eastern")]; + char stringpool_str378[sizeof("gilt")]; + char stringpool_str387[sizeof("us mountain")]; + char stringpool_str391[sizeof("vlat")]; + char stringpool_str392[sizeof("vlast")]; + char stringpool_str395[sizeof("gtb")]; + char stringpool_str398[sizeof("taipei")]; + char stringpool_str399[sizeof("sret")]; + char stringpool_str408[sizeof("cape verde")]; + char stringpool_str417[sizeof("tkt")]; + char stringpool_str418[sizeof("samoa")]; + char stringpool_str421[sizeof("sa pacific")]; + char stringpool_str427[sizeof("vut")]; + char stringpool_str428[sizeof("idlw")]; + char stringpool_str432[sizeof("fiji")]; + char stringpool_str435[sizeof("utc")]; + char stringpool_str443[sizeof("korea")]; + char stringpool_str445[sizeof("e. europe")]; + char stringpool_str449[sizeof("syot")]; + char stringpool_str452[sizeof("n. central asia")]; + char stringpool_str455[sizeof("tvt")]; + char stringpool_str458[sizeof("w. central africa")]; + char stringpool_str466[sizeof("ekaterinburg")]; + char stringpool_str468[sizeof("vladivostok")]; + char stringpool_str476[sizeof("yapt")]; + char stringpool_str477[sizeof("us eastern")]; + char stringpool_str482[sizeof("sa eastern")]; + char stringpool_str485[sizeof("hdt")]; + char stringpool_str486[sizeof("russian")]; + char stringpool_str492[sizeof("hkt")]; + char stringpool_str497[sizeof("romance")]; + char stringpool_str540[sizeof("w. europe")]; + char stringpool_str563[sizeof("ydt")]; + char stringpool_str566[sizeof("idle")]; + char stringpool_str567[sizeof("greenwich")]; + char stringpool_str619[sizeof("greenland")]; + }; +static const struct stringpool_t stringpool_contents = + { + "o", + "x", + "z", + "q", + "omst", + "omsst", + "p", + "a", + "e", + "pet", + "pmst", + "pett", + "petst", + "eet", + "aest", + "eest", + "eat", + "east", + "easst", + "pst", + "eastern", + "m", + "ast", + "est", + "c", + "mmt", + "met", + "mest", + "cet", + "d", + "cest", + "cat", + "cast", + "magt", + "magst", + "mst", + "msk", + "cot", + "cst", + "aqtt", + "f", + "art", + "fnt", + "fet", + "b", + "anat", + "anast", + "bnt", + "i", + "pht", + "at", + "zp6", + "mewt", + "fst", + "ahst", + "mawt", + "zp5", + "bot", + "bst", + "pwt", + "pont", + "iot", + "ist", + "awst", + "mht", + "mez", + "orat", + "mesz", + "chst", + "pmdt", + "central", + "aedt", + "act", + "ect", + "acst", + "eadt", + "brt", + "chut", + "brst", + "cen. australia", + "davt", + "irst", + "irkt", + "irkst", + "bt", + "n", + "btt", + "mountain", + "cct", + "w", + "l", + "fwt", + "msd", + "wet", + "west", + "wat", + "wast", + "wakt", + "nst", + "acwst", + "chast", + "cist", + "azt", + "clt", + "azst", + "clst", + "mart", + "zp4", + "jst", + "central asia", + "aft", + "e. south america", + "central america", + "ict", + "pgt", + "nrt", + "mexico", + "awdt", + "egt", + "cxt", + "egst", + "phot", + "alaskan", + "nt", + "wt", + "west asia", + "acdt", + "npt", + "lhst", + "afghanistan", + "k", + "g", + "irdt", + "chot", + "chost", + "gmt", + "get", + "novt", + "novst", + "fjt", + "u", + "fjst", + "pyst", + "nct", + "kst", + "kost", + "gst", + "iran", + "e. africa", + "wadt", + "t", + "e. australia", + "s", + "chadt", + "tmt", + "cidst", + "aoe", + "myt", + "west pacific", + "mut", + "wit", + "sast", + "sakt", + "new zealand", + "tot", + "china", + "tost", + "sst", + "india", + "warst", + "sbt", + "azot", + "azost", + "taht", + "nzt", + "dateline", + "nzst", + "tokyo", + "central pacific", + "qyzt", + "atlantic", + "nft", + "ut", + "trt", + "wft", + "srt", + "pdt", + "lhdt", + "adt", + "edt", + "pkt", + "almt", + "wita", + "wgt", + "akst", + "wgst", + "krat", + "krast", + "mid-atlantic", + "mdt", + "lint", + "malay peninsula", + "cdt", + "swt", + "se asia", + "v", + "tonga", + "ckt", + "vet", + "caucasus", + "central europe", + "h", + "central european", + "newfoundland", + "arab", + "sct", + "arabic", + "arabian", + "ddut", + "vost", + "hast", + "nepal", + "nut", + "fkt", + "fkst", + "hst", + "idt", + "tlt", + "w. australia", + "egypt", + "myanmar", + "nzdt", + "gft", + "uzt", + "north asia", + "mvt", + "galt", + "nfdt", + "cvt", + "north asia east", + "kgt", + "aus central", + "pacific", + "canada central", + "pacific sa", + "azores", + "gamt", + "tft", + "r", + "fle", + "akdt", + "ulat", + "ulast", + "ret", + "tjt", + "south africa", + "sgt", + "ndt", + "rott", + "samt", + "tasmania", + "hovt", + "hovst", + "gyt", + "y", + "hadt", + "sa western", + "hawaiian", + "uyt", + "uyst", + "yekt", + "yekst", + "kuyt", + "yakt", + "yakst", + "yst", + "jerusalem", + "sri lanka", + "yakutsk", + "wib", + "aus eastern", + "gilt", + "us mountain", + "vlat", + "vlast", + "gtb", + "taipei", + "sret", + "cape verde", + "tkt", + "samoa", + "sa pacific", + "vut", + "idlw", + "fiji", + "utc", + "korea", + "e. europe", + "syot", + "n. central asia", + "tvt", + "w. central africa", + "ekaterinburg", + "vladivostok", + "yapt", + "us eastern", + "sa eastern", + "hdt", + "russian", + "hkt", + "romance", + "w. europe", + "ydt", + "idle", + "greenwich", + "greenland" + }; +#define stringpool ((const char *) &stringpool_contents) +const struct zone * +zonetab (register const char *str, register size_t len) +{ + static const struct zone wordlist[] = + { + {-1}, {-1}, +#line 37 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str2, -2*3600}, +#line 46 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str3, -11*3600}, +#line 48 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str4, 0*3600}, +#line 39 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str5, -4*3600}, + {-1}, {-1}, +#line 272 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str8,21600}, +#line 271 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str9,25200}, +#line 38 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str10, -3*3600}, + {-1}, {-1}, +#line 24 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str13, 1*3600}, +#line 28 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str14, 5*3600}, +#line 274 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str15,-18000}, +#line 282 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str16,-10800}, +#line 276 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str17,43200}, +#line 275 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str18,43200}, +#line 83 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str19, 2*3600}, +#line 189 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str20,36000}, +#line 91 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str21, 3*3600}, +#line 90 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str22, 3*3600}, + {-1}, +#line 104 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str24,-6*3600}, +#line 220 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str25,-18000}, +#line 22 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str26, -8*3600}, +#line 136 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str27, -18000}, +#line 35 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str28, 12*3600}, +#line 59 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str29, -4*3600}, +#line 16 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str30, -5*3600}, +#line 26 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str31, 3*3600}, +#line 259 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str32,23400}, +#line 76 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str33, 1*3600}, + {-1}, +#line 85 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str35, 2*3600}, +#line 74 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str36, 1*3600}, +#line 27 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str37, 4*3600}, +#line 82 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str38, 2*3600}, +#line 68 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str39,2*3600}, + {-1}, +#line 205 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str41,28800}, +#line 255 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str42,39600}, +#line 254 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str43,43200}, +#line 20 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str44, -7*3600}, +#line 92 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str45, 3*3600}, +#line 215 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str46,-18000}, +#line 18 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str47, -6*3600}, +#line 195 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str48,18000}, +#line 29 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str49, 6*3600}, + {-1}, {-1}, +#line 54 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str52, -3*3600}, +#line 229 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str53,-7200}, +#line 224 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str54,10800}, +#line 25 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str55, 2*3600}, + {-1}, +#line 193 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str57,43200}, +#line 192 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str58,43200}, +#line 202 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str59,28800}, +#line 32 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str60, 9*3600}, +#line 279 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str61,28800}, +#line 51 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str62, -2*3600}, +#line 97 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str63, 6*3600}, +#line 77 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str64, 1*3600}, +#line 84 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str65, 2*3600}, +#line 67 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str66,-10*3600}, +#line 257 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str67,18000}, +#line 95 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str68, 5*3600}, + {-1}, +#line 203 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str70,-14400}, +#line 73 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str71, 1*3600}, +#line 284 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str72,32400}, + {-1}, +#line 283 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str74,39600}, +#line 241 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str75,21600}, +#line 96 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str76, (5*3600+1800)}, +#line 197 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str77,28800}, + {-1}, +#line 258 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str79,43200}, +#line 78 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str80, 1*3600}, +#line 273 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str81,18000}, +#line 86 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str82, 2*3600}, + {-1}, +#line 210 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str84,36000}, +#line 281 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str85,-7200}, + {-1}, {-1}, +#line 129 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str88, -21600}, +#line 188 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str89,39600}, +#line 186 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str90,-18000}, +#line 221 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str91,-18000}, +#line 185 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str92,34200}, +#line 106 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str93,11*3600}, +#line 56 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str94, -3*3600}, +#line 211 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str95,36000}, +#line 52 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str96,-2*3600}, +#line 123 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str97, 34200}, + {-1}, {-1}, +#line 218 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str100,25200}, +#line 245 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str101,12600}, +#line 244 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str102,28800}, +#line 243 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str103,32400}, +#line 89 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str104, 3*3600}, +#line 36 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str105, -1*3600}, +#line 204 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str106,21600}, +#line 151 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str107, -25200}, +#line 99 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str108, (6*3600+1800)}, +#line 45 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str109, -10*3600}, +#line 34 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str110, 11*3600}, +#line 75 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str111, 1*3600}, + {-1}, +#line 93 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str113, 4*3600}, +#line 50 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str114, 0*3600}, + {-1}, +#line 81 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str116, 1*3600}, +#line 80 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str117, 1*3600}, + {-1}, +#line 98 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str119, 2*3600}, +#line 316 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str120,43200}, +#line 58 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str121, -(2*3600+1800)}, +#line 187 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str122,31500}, +#line 207 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str123,45900}, +#line 213 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str124,-18000}, +#line 201 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str125,14400}, +#line 60 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str126, -4*3600}, +#line 200 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str127,18000}, +#line 57 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str128,-3*3600}, +#line 256 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str129,-30600}, +#line 94 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str130, 4*3600}, +#line 102 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str131, 9*3600}, +#line 125 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str132, 21600}, +#line 190 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str133,16200}, +#line 135 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str134, -10800}, +#line 124 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str135, -21600}, + {-1}, +#line 239 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str137,25200}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 277 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str143,36000}, +#line 269 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str144,43200}, +#line 149 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str145, -21600}, +#line 196 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str146,32400}, +#line 223 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str147,-3600}, +#line 217 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str148,25200}, +#line 222 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str149,0}, +#line 278 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str150,46800}, +#line 112 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str151, -32400}, + {-1}, {-1}, +#line 71 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str154, -11*3600}, + {-1}, {-1}, {-1}, +#line 324 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str158,0}, + {-1}, +#line 181 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str160, 18000}, +#line 184 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str161,37800}, +#line 268 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str162,20700}, +#line 252 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str163,37800}, +#line 111 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str164, 16200}, + {-1}, {-1}, +#line 33 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str167, 10*3600}, + {-1}, +#line 30 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str169, 7*3600}, +#line 242 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str170,16200}, +#line 209 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str171,28800}, +#line 208 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str172,32400}, +#line 15 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str173, 0*3600}, +#line 232 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str174,14400}, +#line 267 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str175,25200}, +#line 266 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str176,25200}, +#line 226 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str177,43200}, +#line 43 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str178, -8*3600}, +#line 225 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str179,46800}, + {-1}, +#line 285 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str181,-10800}, +#line 263 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str182,39600}, +#line 103 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str183, 9*3600}, +#line 247 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str184,39600}, +#line 105 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str185, 10*3600}, +#line 146 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str186, 12600}, +#line 132 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str187, 10800}, +#line 101 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str188, 8*3600}, +#line 42 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str189, -7*3600}, +#line 133 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str190, 36000}, +#line 41 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str191, -6*3600}, +#line 206 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str192,49500}, +#line 301 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str193,18000}, +#line 212 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str194,-14400}, +#line 194 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str195,-43200}, + {-1}, +#line 262 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str197,28800}, +#line 182 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str198, 36000}, +#line 260 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str199,14400}, +#line 322 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str200,32400}, +#line 87 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str201, 2*3600}, +#line 289 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str202,39600}, +#line 155 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str203, 43200}, +#line 303 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str204,46800}, +#line 130 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str205, 28800}, +#line 302 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str206,50400}, +#line 88 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str207, -11*3600}, + {-1}, +#line 145 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str209, 19800}, + {-1}, +#line 317 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str211,-10800}, +#line 291 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str212,39600}, + {-1}, +#line 199 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str214,-3600}, +#line 198 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str215,0}, +#line 296 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str216,-36000}, +#line 109 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str217, 12*3600}, +#line 131 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str218, -43200}, +#line 108 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str219,12*3600}, +#line 173 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str220, 32400}, +#line 128 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str221, 39600}, + {-1}, +#line 286 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str223,21600}, +#line 116 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str224, -14400}, +#line 265 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str225,39600}, + {-1}, +#line 14 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str227, 0*3600}, +#line 304 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str228,10800}, +#line 318 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str229,43200}, +#line 294 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str230,-10800}, +#line 23 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str231, -7*3600}, +#line 251 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str232,39600}, + {-1}, +#line 55 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str234, -3*3600}, +#line 17 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str235, -4*3600}, + {-1}, {-1}, +#line 280 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str238,18000}, +#line 191 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str239,21600}, +#line 323 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str240,28800}, + {-1}, +#line 320 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str242,-7200}, +#line 63 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str243,-9*3600}, +#line 319 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str244,-3600}, + {-1}, +#line 249 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str246,25200}, +#line 248 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str247,28800}, +#line 150 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str248, -7200}, +#line 21 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str249, -6*3600}, +#line 253 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str250,50400}, +#line 168 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str251, 28800}, +#line 19 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str252, -5*3600}, +#line 79 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str253, 1*3600}, + {-1}, +#line 167 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str255, 25200}, +#line 44 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str256, -9*3600}, + {-1}, +#line 174 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str258, 46800}, +#line 214 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str259,-36000}, + {-1}, +#line 311 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str261,-14400}, +#line 122 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str262, 14400}, +#line 126 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str263, 3600}, +#line 31 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str264, 8*3600}, +#line 127 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str265, 3600}, +#line 156 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str266, -12600}, +#line 113 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str267, 10800}, +#line 292 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str268,14400}, +#line 115 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str269, 10800}, +#line 114 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str270, 14400}, +#line 219 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str271,36000}, + {-1}, +#line 314 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str273,21600}, +#line 69 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str274,-10*3600}, +#line 154 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str275, 20700}, +#line 270 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str276,-39600}, +#line 228 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str277,-14400}, + {-1}, +#line 227 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str279,-10800}, +#line 70 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str280,-10*3600}, +#line 240 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str281,10800}, + {-1}, {-1}, +#line 300 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str284,32400}, +#line 178 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str285, 28800}, +#line 137 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str286, 7200}, +#line 152 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str287, 23400}, +#line 110 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str288,13*3600}, +#line 233 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str289,-10800}, +#line 310 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str290,18000}, + {-1}, {-1}, +#line 158 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str293, 25200}, +#line 261 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str294,18000}, +#line 230 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str295,-21600}, +#line 264 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str296,43200}, +#line 216 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str297,-3600}, +#line 157 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str298, 28800}, + {-1}, +#line 246 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str300,21600}, +#line 117 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str301, 34200}, +#line 160 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str302, -28800}, + {-1}, +#line 120 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str304, -21600}, + {-1}, +#line 159 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str306, -14400}, +#line 119 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str307, -3600}, +#line 231 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str308,-32400}, +#line 297 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str309,18000}, +#line 40 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str310, -5*3600}, +#line 140 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str311, 7200}, +#line 61 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str312,-8*3600}, +#line 307 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str313,28800}, +#line 306 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str314,32400}, +#line 287 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str315,14400}, + {-1}, +#line 298 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str317,18000}, + {-1}, +#line 169 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str319, 7200}, + {-1}, {-1}, {-1}, {-1}, +#line 100 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str324, 8*3600}, + {-1}, +#line 53 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str326, -(1*3600+1800)}, +#line 288 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str327,-10800}, + {-1}, {-1}, +#line 290 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str330,14400}, + {-1}, +#line 172 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str332, 36000}, + {-1}, +#line 238 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str334,25200}, +#line 237 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str335,28800}, + {-1}, {-1}, +#line 235 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str338,-14400}, + {-1}, {-1}, {-1}, +#line 47 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str342, -12*3600}, +#line 64 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str343,-9*3600}, +#line 165 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str344, -14400}, +#line 144 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str345, -36000}, + {-1}, +#line 309 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str347,-10800}, + {-1}, +#line 308 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str349,-7200}, +#line 329 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str350,18000}, +#line 328 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str351,21600}, +#line 250 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str352,14400}, +#line 326 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str353,32400}, +#line 325 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str354,36000}, + {-1}, {-1}, {-1}, +#line 66 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str358, -9*3600}, +#line 147 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str359, 7200}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 170 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str365, 21600}, + {-1}, +#line 183 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str367, 32400}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 321 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str375,25200}, + {-1}, +#line 118 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str377, 36000}, +#line 234 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str378,43200}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 176 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str387, -25200}, + {-1}, {-1}, {-1}, +#line 313 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str391,36000}, +#line 312 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str392,39600}, + {-1}, {-1}, +#line 143 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str395, 7200}, + {-1}, {-1}, +#line 171 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str398, 28800}, +#line 293 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str399,39600}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 121 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str408, -3600}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 299 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str417,46800}, +#line 166 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str418, -39600}, + {-1}, {-1}, +#line 164 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str421, -18000}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 315 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str427,39600}, +#line 72 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str428,-12*3600}, + {-1}, {-1}, {-1}, +#line 139 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str432, 43200}, + {-1}, {-1}, +#line 49 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str435, 0*3600}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 148 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str443, 32400}, + {-1}, +#line 134 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str445, 7200}, + {-1}, {-1}, {-1}, +#line 295 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str449,10800}, + {-1}, {-1}, +#line 153 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str452, 21600}, + {-1}, {-1}, +#line 305 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str455,43200}, + {-1}, {-1}, +#line 179 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str458, 3600}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 138 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str466, 18000}, + {-1}, +#line 177 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str468, 36000}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 327 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str476,36000}, +#line 175 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str477, -18000}, + {-1}, {-1}, {-1}, {-1}, +#line 163 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str482, -10800}, + {-1}, {-1}, +#line 65 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str485, -9*3600}, +#line 162 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str486, 10800}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 236 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str492,28800}, + {-1}, {-1}, {-1}, {-1}, +#line 161 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str497, 3600}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 180 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str540, 3600}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, +#line 62 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str563, -8*3600}, + {-1}, {-1}, +#line 107 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str566,12*3600}, +#line 142 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str567, 0}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 141 "zonetab.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str619, -10800} + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register unsigned int key = hash (str, len); + + if (key <= MAX_HASH_VALUE) + { + register int o = wordlist[key].name; + if (o >= 0) + { + register const char *s = o + stringpool; + + if ((((unsigned char)*str ^ (unsigned char)*s) & ~32) == 0 && !gperf_case_strncmp (str, s, len) && s[len] == '\0') + return &wordlist[key]; + } + } + } + return 0; +} +#line 330 "zonetab.list" + diff --git a/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/zonetab.list b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/zonetab.list new file mode 100644 index 00000000..63b68734 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/ext/date/zonetab.list @@ -0,0 +1,330 @@ +%{ +#define GPERF_DOWNCASE 1 +#define GPERF_CASE_STRNCMP 1 +#define gperf_case_strncmp strncasecmp +struct zone { + int name; + int offset; +}; +static const struct zone *zonetab(register const char *str, register size_t len); +%} + +struct zone; +%% +ut, 0*3600 +gmt, 0*3600 +est, -5*3600 +edt, -4*3600 +cst, -6*3600 +cdt, -5*3600 +mst, -7*3600 +mdt, -6*3600 +pst, -8*3600 +pdt, -7*3600 +a, 1*3600 +b, 2*3600 +c, 3*3600 +d, 4*3600 +e, 5*3600 +f, 6*3600 +g, 7*3600 +h, 8*3600 +i, 9*3600 +k, 10*3600 +l, 11*3600 +m, 12*3600 +n, -1*3600 +o, -2*3600 +p, -3*3600 +q, -4*3600 +r, -5*3600 +s, -6*3600 +t, -7*3600 +u, -8*3600 +v, -9*3600 +w, -10*3600 +x, -11*3600 +y, -12*3600 +z, 0*3600 +utc, 0*3600 +wet, 0*3600 +at, -2*3600 +brst,-2*3600 +ndt, -(1*3600+1800) +art, -3*3600 +adt, -3*3600 +brt, -3*3600 +clst,-3*3600 +nst, -(2*3600+1800) +ast, -4*3600 +clt, -4*3600 +akdt,-8*3600 +ydt, -8*3600 +akst,-9*3600 +hadt,-9*3600 +hdt, -9*3600 +yst, -9*3600 +ahst,-10*3600 +cat,2*3600 +hast,-10*3600 +hst,-10*3600 +nt, -11*3600 +idlw,-12*3600 +bst, 1*3600 +cet, 1*3600 +fwt, 1*3600 +met, 1*3600 +mewt, 1*3600 +mez, 1*3600 +swt, 1*3600 +wat, 1*3600 +west, 1*3600 +cest, 2*3600 +eet, 2*3600 +fst, 2*3600 +mest, 2*3600 +mesz, 2*3600 +sast, 2*3600 +sst, -11*3600 +bt, 3*3600 +eat, 3*3600 +eest, 3*3600 +msk, 3*3600 +msd, 4*3600 +zp4, 4*3600 +zp5, 5*3600 +ist, (5*3600+1800) +zp6, 6*3600 +wast, 2*3600 +cct, (6*3600+1800) +sgt, 8*3600 +wadt, 8*3600 +jst, 9*3600 +kst, 9*3600 +east,-6*3600 +gst, 10*3600 +eadt,11*3600 +idle,12*3600 +nzst,12*3600 +nzt, 12*3600 +nzdt,13*3600 +afghanistan, 16200 +alaskan, -32400 +arab, 10800 +arabian, 14400 +arabic, 10800 +atlantic, -14400 +aus central, 34200 +aus eastern, 36000 +azores, -3600 +canada central, -21600 +cape verde, -3600 +caucasus, 14400 +cen. australia, 34200 +central america, -21600 +central asia, 21600 +central europe, 3600 +central european, 3600 +central pacific, 39600 +central, -21600 +china, 28800 +dateline, -43200 +e. africa, 10800 +e. australia, 36000 +e. europe, 7200 +e. south america, -10800 +eastern, -18000 +egypt, 7200 +ekaterinburg, 18000 +fiji, 43200 +fle, 7200 +greenland, -10800 +greenwich, 0 +gtb, 7200 +hawaiian, -36000 +india, 19800 +iran, 12600 +jerusalem, 7200 +korea, 32400 +mexico, -21600 +mid-atlantic, -7200 +mountain, -25200 +myanmar, 23400 +n. central asia, 21600 +nepal, 20700 +new zealand, 43200 +newfoundland, -12600 +north asia east, 28800 +north asia, 25200 +pacific sa, -14400 +pacific, -28800 +romance, 3600 +russian, 10800 +sa eastern, -10800 +sa pacific, -18000 +sa western, -14400 +samoa, -39600 +se asia, 25200 +malay peninsula, 28800 +south africa, 7200 +sri lanka, 21600 +taipei, 28800 +tasmania, 36000 +tokyo, 32400 +tonga, 46800 +us eastern, -18000 +us mountain, -25200 +vladivostok, 36000 +w. australia, 28800 +w. central africa, 3600 +w. europe, 3600 +west asia, 18000 +west pacific, 36000 +yakutsk, 32400 +acdt,37800 +acst,34200 +act,-18000 +acwst,31500 +aedt,39600 +aest,36000 +aft,16200 +almt,21600 +anast,43200 +anat,43200 +aoe,-43200 +aqtt,18000 +awdt,32400 +awst,28800 +azost,0 +azot,-3600 +azst,18000 +azt,14400 +bnt,28800 +bot,-14400 +btt,21600 +cast,28800 +chadt,49500 +chast,45900 +chost,32400 +chot,28800 +chst,36000 +chut,36000 +cidst,-14400 +cist,-18000 +ckt,-36000 +cot,-18000 +cvt,-3600 +cxt,25200 +davt,25200 +ddut,36000 +easst,-18000 +ect,-18000 +egst,0 +egt,-3600 +fet,10800 +fjst,46800 +fjt,43200 +fkst,-10800 +fkt,-14400 +fnt,-7200 +galt,-21600 +gamt,-32400 +get,14400 +gft,-10800 +gilt,43200 +gyt,-14400 +hkt,28800 +hovst,28800 +hovt,25200 +ict,25200 +idt,10800 +iot,21600 +irdt,16200 +irkst,32400 +irkt,28800 +irst,12600 +kgt,21600 +kost,39600 +krast,28800 +krat,25200 +kuyt,14400 +lhdt,39600 +lhst,37800 +lint,50400 +magst,43200 +magt,39600 +mart,-30600 +mawt,18000 +mht,43200 +mmt,23400 +mut,14400 +mvt,18000 +myt,28800 +nct,39600 +nfdt,43200 +nft,39600 +novst,25200 +novt,25200 +npt,20700 +nrt,43200 +nut,-39600 +omsst,25200 +omst,21600 +orat,18000 +pet,-18000 +petst,43200 +pett,43200 +pgt,36000 +phot,46800 +pht,28800 +pkt,18000 +pmdt,-7200 +pmst,-10800 +pont,39600 +pwt,32400 +pyst,-10800 +qyzt,21600 +ret,14400 +rott,-10800 +sakt,39600 +samt,14400 +sbt,39600 +sct,14400 +sret,39600 +srt,-10800 +syot,10800 +taht,-36000 +tft,18000 +tjt,18000 +tkt,46800 +tlt,32400 +tmt,18000 +tost,50400 +tot,46800 +trt,10800 +tvt,43200 +ulast,32400 +ulat,28800 +uyst,-7200 +uyt,-10800 +uzt,18000 +vet,-14400 +vlast,39600 +vlat,36000 +vost,21600 +vut,39600 +wakt,43200 +warst,-10800 +wft,43200 +wgst,-3600 +wgt,-7200 +wib,25200 +wit,32400 +wita,28800 +wt,0 +yakst,36000 +yakt,32400 +yapt,36000 +yekst,21600 +yekt,18000 +%% diff --git a/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/lib/date.rb b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/lib/date.rb new file mode 100644 index 00000000..aa630eb6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/lib/date.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true +# date.rb: Written by Tadayoshi Funaba 1998-2011 + +require 'date_core' + +class Date + VERSION = "3.4.1" # :nodoc: + + # call-seq: + # infinite? -> false + # + # Returns +false+ + def infinite? + false + end + + class Infinity < Numeric # :nodoc: + + def initialize(d=1) @d = d <=> 0 end + + def d() @d end + + protected :d + + def zero?() false end + def finite?() false end + def infinite?() d.nonzero? end + def nan?() d.zero? end + + def abs() self.class.new end + + def -@() self.class.new(-d) end + def +@() self.class.new(+d) end + + def <=>(other) + case other + when Infinity; return d <=> other.d + when Float::INFINITY; return d <=> 1 + when -Float::INFINITY; return d <=> -1 + when Numeric; return d + else + begin + l, r = other.coerce(self) + return l <=> r + rescue NoMethodError + end + end + nil + end + + def coerce(other) + case other + when Numeric; return -d, d + else + super + end + end + + def to_f + return 0 if @d == 0 + if @d > 0 + Float::INFINITY + else + -Float::INFINITY + end + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/lib/date_core.so b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/lib/date_core.so new file mode 100755 index 00000000..6070a253 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/date-3.4.1/lib/date_core.so differ diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/.rspec b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/.rspec new file mode 100644 index 00000000..53607ea5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/.rspec @@ -0,0 +1 @@ +--colour diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/CHANGELOG.md b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/CHANGELOG.md new file mode 100644 index 00000000..c2881230 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/CHANGELOG.md @@ -0,0 +1,518 @@ +# Changelog + +## 1.6.2 / 2025-05-12 + +- Handle upcoming changes to the `cgi` gem in Ruby 3.5 ([#147][pull-147]) + +- Fix issues found with `htmldiff` in Ruby 1.8 (which is used approximately + never, since the code change which broke Ruby 1.8 was made 6 years ago). + [#148][pull-148] + +- Fixed some standardrb formatting and configuration issues. + +## 1.6.1 / 2025-03-25 + +- Performed further work on `Diff::LCS::Ldiff` improvements ([#46][issue-46]) + and resolve several thread safety issues cleanly by making it a class. + [#129][pull-129] + +- Restructure the project to be more consistent with the rest of the projects + that I manage. + +- Increased GitHub action security. + +- Added [trusted publishing][tp] for fully automated releases. + +## 1.6.0 / 2025-02-13 + +- Baptiste Courtois (@annih) has done significant work on making `bin/ldiff` + work better, contributing a number of issues and pull requests. These include: + + - Separation of command parsing from diff-generation in `Diff::LCS::Ldiff` + code extraction making it easier to use separately from the `bin/ldiff` + command in [#103][pull-103]. This partially resolves [#46][issue-46]. + + - Improvement of binary and empty file detection and tests in [#104][pull-104] + and [#105][pull-105]. This resolves issues [#100][issue-100], + [#102][issue-102]. + + - Various ldiff fixes for output [#101][pull-101] resolves issues + [#106][issue-106] (ldiff ed scripts are inverted), [#107][issue-107] (ldiff + hunk ranges are incorrect; regression or incorrect fix for [#60][issue-60]), + and [#95][issue-95]. + +- Patrick Linnane fixed various minor typos. [#93][pull-93] + +- Mark Young added a Changelog link to the RubyGems metadata. [#92][pull-92] + This has been modified to incorporate it into the README. + +- Updated the documentation on `Diff::LCS#lcs` to be clearer about the + requirements for object equality comparison. This resolves [#70][issue-70]. + +- Governance: + + Changes described here are effective 2024-12-31. + + - Update gem management details to use markdown files for everything, enabled + in part by [flavorjones/hoe-markdown][hoe-markdown]. Several files were + renamed to be more consistent with standard practices. + + - Updated security notes with an [age][age] public key rather than pointing to + Keybase.io and a PGP public key which I no longer use. The use of the + [Tidelift security contact][tidelift] is recommended over direct disclosure. + +## 1.5.1 / 2024-01-31 + +- Peter Goldstein updated CI configuration to add Ruby 3.1 and Masato Nakamura + added Ruby 3.2 and 3.3. [#82][pull-82], [#89][pull-89] + +- Switched to [standard ruby][standard ruby] formatting. + +- Justin Steele converted the licence file to Markdown. [#84][pull-84] + +- Updated the gem SPDX identifier for GPL 2.0 or later, resolving [#86][pull-86] + by Vit Ondruch. + +- Resolve a potential security issue with `ldiff` in its use of `IO.read` + instead of `File.read`. [#91][issue-91] + +- Added MFA authentication requirement for release to RubyGems. [#90][pull-90] + +- Added Dependabot management for actions and gems. [#90][pull-90] + +- Updated CodeQL configuration. [#90][pull-90] + +## 1.5.0 / 2021-12-23 + +- Updated the CI configuration and monkey-patch Hoe. + +- Kenichi Kamiya fixed a test configuration deprecation in SimpleCov. + [#69][pull-69] + +- Tien introduced several corrections and code improvements: + + - Removed an off-by-one error when calculating an index value by embracing + Ruby iteration properly. This had a side-effect of fixing a long-standing + bug in `#traverse_sequences` where the traversal would not be transitive. + That is, `LCS(s2, s1)` should produce a sequence that is transitive with + `LCS(s1, s2)` on traversal, and applying the diff computed from those + results would result in equivalent changes that could be played forward or + backward as appropriate. [#71][pull-71], [#75][pull-75] + + - The above fix resulted in a changed order of the longest common subsequence + when callbacks were applied. After analysis, it was determined that the + computed subsequence was _equivalent_ to the prior version, so the test was + updated. This also resulted in the clarification of documentation when + traversing the sub-sequences. [#79][pull-79] + + - An infinite loop case in the case where `Diff::LCS` would be included into + an enumerable class has been fixed. [#73][pull-73] + + - Clarified the purpose of a threshold test in calculation of LCS. + [#72][pull-72], [#80][pull-80] + +- Removed autotest directory + +## 1.4.4 / 2020-07-01 + +- Fixed an issue reported by Jun Aruga in the `Diff::LCS::Ldiff` binary text + detection. [#44][issue-44] + +- Fixed a theoretical issue reported by Jun Aruga in `Diff::LCS::Hunk` to raise + a more useful exception. [#43][issue-43] + +- Added documentation that should address custom object issues as reported in + [#35][issue-35]. + +- Fixed more diff errors, in part reported in [#65][issue-65]. + + - The use of `Numeric#abs` is incorrect in `Diff::LCS::Block#diff_size`. The + diff size _must_ be accurate for correct change placement. + + - When selecting `@max_diff_size` in `Diff::LCS::Hunk`, choose it based on + `block.diff_size.abs`. + + - Made a number of changes that will, unfortunately, increase allocations at + the cost of being safe with frozen strings. + + - Add some knowledge that when `Diff::LCS::Hunk#diff` is called, that we are + processing the _last_ hunk, so some changes will be made to how the output + is generated. + + - `old`, `ed`, and `reverse_ed` formats have no differences. + + - `unified` format will report `\ No newline at end of file` given the + correct conditions, at most once. Unified range reporting also differs for + the last hunk such that the `length` of the range is reduced by one. + + - `context` format will report `\No newline at end of file` given the + correct conditions, up to once per "file". Context range reporting also + differs for the last hunk such that the `end` part of the range is reduced + by one to a minimum of one. + +- Added a bunch more tests for the cases above, and fixed `hunk_spec.rb` so that + the phrase being compared isn't nonsense French. + +- Updated formatting. + +- Added a Rake task to assist with manual testing on Ruby 1.8. + +## 1.4.3 / 2020-06-29 + +- Fixed several issues with 1.4 on Rubies older than 2.0. Some of this was + providing useful shim functions to Hoe 3.x (which dropped these older Rubies a + while ago). Specifically: + + - Removed Array#lazy from a method in `Diff::LCS::Hunk`. + + - Changed some unit tests to use old-style Symbol-keyed hashes. + + - Changed some unit test helper functions to no longer use keyword parameters, + but only a trailing options hash. + + - Made the use of `psych` dependent on `RUBY_VERSION >= 1.9`. + + Resolves [#63][issue-63]. + +## 1.4.2 / 2020-06-23 + +- Camille Drapier fixed a small issue with RuboCop configuration. [#59][pull-59] + +- Applied another fix (and unit test) to fix an issue for the Chef team. + [#60][issue-60], [#61][pull-61] + +## 1.4.1 / 2020-06-23 + +- Fix an issue where diff sizes could be negative, and they should be. + [#57][issue-57], [#58][pull-58] + +## 1.4 / 2020-06-23 + +- Ruby versions lower than 2.4 are soft-deprecated and will not be run as part + of the CI process any longer. + +- Akinora MUSHA (knu) added the ability for `Diff::LCS::Change` objects to be + implicitly treated arrays. Originally provided as pull request [#47][pull-47], + but it introduced a number of test failures as documented in [#48][issue-48], + and remediation of `Diff::LCS` itself was introduced in [#49][pull-49]. + +- Resolved [#5][issue-05] with some tests comparing output from `system` calls + to `bin/ldiff` with some pre-generated output. Resolved [#6][issue-06] with + these tests. + +- Resolved a previously undetected `bin/ldiff` issue with `--context` output not + matching `diff --context` output. + +- Resolved an issue with later versions of Ruby not working with an `OptParse` + specification of `Numeric`; this has been changed to `Integer`. + +- Brandon Fish added TruffleRuby in [#52][pull-52]. + +- Fixed two missing classes as reported in [#53][issue-53]. + +## 1.3 / 2017-01-18 + +- Bugs fixed: + + - Fixed an error for `bin/ldiff --version`. Fixes issue [#21][issue-21]. + + - Force `Diff::LCS::Change` and `Diff::LCS::ContextChange` to only perform + equality comparisons against themselves. Provided by Kevin Mook in pull + request [#29][pull-29]. + + - Fix tab expansion in `htmldiff`, provided by Mark Friedgan in pull request + [#25][pull-25]. + + - Silence Ruby 2.4 `Fixnum` deprecation warnings. Fixes issue [#38][issue-38] + and pull request [#36][pull-36]. + + - Ensure that test dependencies are loaded properly. Fixes issue + [#33][issue-33] and pull request [#34][pull-34]. + + - Fix issue [#1][issue-01] with incorrect intuition of patch direction. + Tentative fix, but the previous failure cases pass now. + +- Tooling changes: + + - Added SimpleCov and Coveralls support. + + - Change the homepage (temporarily) to the GitHub repo. + + - Updated testing and gem infrastructure. + + - Modernized the specs. + +- Cleaned up documentation. + +- Added a Code of Conduct. + +## 1.2.5 / 2013-11-08 + +- Bugs fixed: + + - Comparing arrays flattened them too far, especially with `Diff::LCS.sdiff`. + Fixed by Josh Bronson in pull request [#23][pull-23]. + +## 1.2.4 / 2013-04-20 + +- Bugs fixed: + + - A bug was introduced after 1.1.3 when pruning common sequences at the start + of comparison. Paul Kunysch (@pck) fixed this in pull request + [#18][pull-18]. Thanks! + + - The Rubinius (1.9 mode) bug in [rubinius/rubinius#2268][rubinius#2268] has + been fixed by the Rubinius team two days after it was filed. Thanks for + fixing this so quickly! + +- Switching to Raggi's hoe-gemspec2 for gemspec generation. + +## 1.2.3 / 2013-04-11 + +- Bugs Fixed: + + - The new encoding detection for diff output generation (added in 1.2.2) + introduced a bug if the left side of the comparison was the empty set. + Originally found in [rspec/rspec-expectations#238][rspec-expectations#238] + and [rspec/rspec-expectations#239][rspec-expectations#239]. Jon Rowe + developed a reasonable heuristic (left side, right side, empty string + literal) to avoid this bug. + + - There is a known issue with Rubinius in 1.9 mode reported in + [rubinius/rubinius#2268][rubinius#2268] and demonstrated in the Travis CI + builds. For all other tested platforms, diff-lcs is considered stable. As + soon as a suitably small test-case can be created for the Rubinius team to + examine, this will be added to the Rubinius issue around this. + +## 1.2.2 / 2013-03-30 + +- Bugs Fixed: + + - `Diff::LCS::Hunk` could not properly generate a difference for comparison + sets that are not US-ASCII-compatible because of the use of literal regular + expressions and strings. Jon Rowe found this in + [rspec/rspec-expectations#219][rspec-expectations#219] and provided a first + pass implementation in pull request [#15][pull-15]. I've reworked it because + of test failures in Rubinius when running in Ruby 1.9 mode. This coerces the + added values to the encoding of the old dataset (as determined by the first + piece of the old dataset). + + - Adding Travis CI testing for Ruby 2.0. + +## 1.2.1 / 2013-02-09 + +- Bugs Fixed: + + - As seen in [rspec/rspec-expectations#200][rspec-expectations#200], the + release of `Diff::LCS` 1.2 introduced an unnecessary public API change to + `Diff::LCS::Hunk` (see the change at + [rspec/rspec-expectations@3d6fc82c][rspec-expectations@3d6fc82c] for + details). The new method name (and behaviour) is more correct, but I should + not have renamed the function or should have at least provided an alias. + This release restores `Diff::LCS::Hunk#unshift` as an alias to #merge. Note + that the old `#unshift` behaviour was incorrect and will not be restored. + +## 1.2.0 / 2013-01-21 + +- Minor Enhancements: + + - Added special case handling for `Diff::LCS.patch` so that it handles patches + that are empty or contain no changes. + + - Added two new methods (`#patch_me` and `#unpatch_me`) to the include-able + module. + +- Bugs Fixed: + + - Fixed issue [#1][issue-01] patch direction detection. + + - Resolved issue [#2][issue-02] by handling `string[string.size, 1]` properly + (it returns `""` not `nil`). + + - Michael Granger (ged) fixed an implementation error in `Diff::LCS::Change` + and added specs in pull request [#8][pull-08]. Thanks! + + - Made the code auto-testable. + + - Vít Ondruch (voxik) provided the latest version of the GPL2 license file in + pull request [#10][pull-10]. Thanks! + + - Fixed a documentation issue with the include-able versions of `#patch!` and + `#unpatch!` where they implied that they would replace the original value. + Given that `Diff::LCS.patch` always returns a copy, the documentation was + incorrect and has been corrected. To provide the behaviour that was + originally documented, two new methods were added to provide this behaviour. + Found by scooter-dangle in issue [#12][issue-12]. Thanks! + +- Code Style Changes: + + - Removed trailing spaces. + + - Calling class methods using `.` instead of `::`. + + - Vít Ondruch (voxik) removed unnecessary shebangs in pull request + [#9][pull-09]. Thanks! + + - Kenichi Kamiya (kachick) removed some warnings of an unused variable in + lucky pull request [#13][pull-13]. Thanks! + + - Embarked on a major refactoring to make the files a little more manageable + and understand the code on a deeper level. + + - Adding CI via Travis CI. + +## 1.1.3 / 2011-08-27 + +- Converted to 'hoe' for release. + +- Converted tests to RSpec 2. + +- Extracted the body of `htmldiff` into a class available from + `diff/lcs/htmldiff`. + +- Migrated development and issue tracking to GitHub. + +- Bugs fixed: + + - Eliminated the explicit use of RubyGems in both `bin/htmldiff` and + `bin/ldiff`. Resolves issue [#4][issue-04]. + + - Eliminated Ruby warnings. Resolves issue [#3][issue-03]. + +## 1.1.2 / 2004-10-20 + +- Fixed a problem reported by Mauricio Fernandez in `htmldiff`. + +## 1.1.1 / 2004-09-25 + +- Fixed bug #891 (Set returned from patch command does not contain last equal + part). + +- Fixed a problem with callback initialisation code (it assumed that all + callbacks passed as classes can be initialised; now, it rescues NoMethodError + in the event of private :new being called). + +- Modified the non-initialisable callbacks to have a private `#new` method. + +- Moved `ldiff` core code to `Diff::LCS::Ldiff` (`diff/lcs/ldiff.rb`). + +## 1.1.0 + +- Eliminated the need for `Diff::LCS::Event` and removed it. + +- Added a contextual diff callback, `Diff::LCS::ContextDiffCallback`. + +- Implemented (un-)patching for standard diff callback output formats with both + `#diff` and `#sdiff`. + +- Extensive documentation changes. + +## 1.0.4 + +- Fixed a problem with `bin/ldiff` output, especially for unified format. + Newlines that should have been present weren't. + +- Changed the `.tar.gz` installer to generate Windows batch files if ones do not + exist already. Removed the existing batch files as they didn't work. + +## 1.0.3 + +- Fixed a problem with `#traverse_sequences` where the first difference from the + left sequence might not be appropriately captured. + +## 1.0.2 + +- Fixed an issue with `ldiff` not working because actions were changed from + symbols to strings. + +## 1.0.1 + +- Minor modifications to the `gemspec`, the `README`. + +- Renamed the diff program to `ldiff` (as well as the companion batch file) so + as to not collide with the standard diff program. + +- Fixed issues with RubyGems. Requires RubyGems > 0.6.1 or >= 0.6.1 with the + latest CVS version. + +## 1.0 + +- Initial release based mostly on Perl's Algorithm::Diff. + +[age]: https://github.com/FiloSottile/age +[hoe-halostatue]: https://github.com/halostatue/hoe-halostatue +[hoe-markdown]: https://github.com/flavorjones/hoe-markdown +[issue-01]: https://github.com/halostatue/diff-lcs/issues/1 +[issue-02]: https://github.com/halostatue/diff-lcs/issues/2 +[issue-03]: https://github.com/halostatue/diff-lcs/issues/3 +[issue-04]: https://github.com/halostatue/diff-lcs/issues/4 +[issue-05]: https://github.com/halostatue/diff-lcs/issues/5 +[issue-06]: https://github.com/halostatue/diff-lcs/issues/6 +[issue-12]: https://github.com/halostatue/diff-lcs/issues/12 +[issue-21]: https://github.com/halostatue/diff-lcs/issues/21 +[issue-33]: https://github.com/halostatue/diff-lcs/issues/33 +[issue-35]: https://github.com/halostatue/diff-lcs/issues/35 +[issue-38]: https://github.com/halostatue/diff-lcs/issues/38 +[issue-43]: https://github.com/halostatue/diff-lcs/issues/43 +[issue-44]: https://github.com/halostatue/diff-lcs/issues/44 +[issue-46]: https://github.com/halostatue/diff-lcs/issues/46 +[issue-48]: https://github.com/halostatue/diff-lcs/issues/48 +[issue-53]: https://github.com/halostatue/diff-lcs/issues/53 +[issue-57]: https://github.com/halostatue/diff-lcs/issues/57 +[issue-60]: https://github.com/halostatue/diff-lcs/issues/60 +[issue-63]: https://github.com/halostatue/diff-lcs/issues/63 +[issue-65]: https://github.com/halostatue/diff-lcs/issues/65 +[issue-70]: https://github.com/halostatue/diff-lcs/issues/70 +[issue-91]: https://github.com/halostatue/diff-lcs/issues/91 +[issue-95]: https://github.com/halostatue/diff-lcs/issues/95 +[issue-100]: https://github.com/halostatue/diff-lcs/issues/100 +[issue-102]: https://github.com/halostatue/diff-lcs/issues/102 +[issue-106]: https://github.com/halostatue/diff-lcs/issues/106 +[issue-107]: https://github.com/halostatue/diff-lcs/issues/107 +[pull-08]: https://github.com/halostatue/diff-lcs/pull/8 +[pull-09]: https://github.com/halostatue/diff-lcs/pull/9 +[pull-10]: https://github.com/halostatue/diff-lcs/pull/10 +[pull-13]: https://github.com/halostatue/diff-lcs/pull/13 +[pull-15]: https://github.com/halostatue/diff-lcs/pull/15 +[pull-18]: https://github.com/halostatue/diff-lcs/pull/18 +[pull-23]: https://github.com/halostatue/diff-lcs/pull/23 +[pull-25]: https://github.com/halostatue/diff-lcs/pull/25 +[pull-29]: https://github.com/halostatue/diff-lcs/pull/29 +[pull-34]: https://github.com/halostatue/diff-lcs/pull/34 +[pull-36]: https://github.com/halostatue/diff-lcs/pull/36 +[pull-47]: https://github.com/halostatue/diff-lcs/pull/47 +[pull-49]: https://github.com/halostatue/diff-lcs/pull/49 +[pull-52]: https://github.com/halostatue/diff-lcs/pull/52 +[pull-58]: https://github.com/halostatue/diff-lcs/pull/58 +[pull-59]: https://github.com/halostatue/diff-lcs/pull/59 +[pull-61]: https://github.com/halostatue/diff-lcs/pull/61 +[pull-69]: https://github.com/halostatue/diff-lcs/pull/69 +[pull-71]: https://github.com/halostatue/diff-lcs/pull/71 +[pull-72]: https://github.com/halostatue/diff-lcs/pull/72 +[pull-73]: https://github.com/halostatue/diff-lcs/pull/73 +[pull-75]: https://github.com/halostatue/diff-lcs/pull/75 +[pull-79]: https://github.com/halostatue/diff-lcs/pull/79 +[pull-80]: https://github.com/halostatue/diff-lcs/pull/80 +[pull-82]: https://github.com/halostatue/diff-lcs/pull/82 +[pull-84]: https://github.com/halostatue/diff-lcs/pull/84 +[pull-86]: https://github.com/halostatue/diff-lcs/pull/86 +[pull-89]: https://github.com/halostatue/diff-lcs/pull/89 +[pull-90]: https://github.com/halostatue/diff-lcs/pull/90 +[pull-92]: https://github.com/halostatue/diff-lcs/pull/92 +[pull-93]: https://github.com/halostatue/diff-lcs/pull/93 +[pull-101]: https://github.com/halostatue/diff-lcs/pull/101 +[pull-103]: https://github.com/halostatue/diff-lcs/pull/103 +[pull-104]: https://github.com/halostatue/diff-lcs/pull/104 +[pull-105]: https://github.com/halostatue/diff-lcs/pull/105 +[pull-129]: https://github.com/halostatue/diff-lcs/pull/129 +[pull-147]: https://github.com/halostatue/diff-lcs/pull/147 +[pull-148]: https://github.com/halostatue/diff-lcs/pull/148 +[rspec-expectations#200]: https://github.com/rspec/rspec-expectations/pull/200 +[rspec-expectations#219]: https://github.com/rspec/rspec-expectations/issues/219 +[rspec-expectations#238]: https://github.com/rspec/rspec-expectations/issues/238 +[rspec-expectations#239]: https://github.com/rspec/rspec-expectations/issues/239 +[rspec-expectations@3d6fc82c]: https://github.com/rspec/rspec-expectations/commit/3d6fc82c +[rubinius#2268]: https://github.com/rubinius/rubinius/issues/2268 +[standard ruby]: https://github.com/standardrb/standard +[tidelift]: https://tidelift.com/security +[tp]: https://guides.rubygems.org/trusted-publishing/ diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/CODE_OF_CONDUCT.md b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..184b5fb3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +- Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery, and sexual attention or advances of + any kind +- Trolling, insulting or derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email address, + without their explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official email address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at [INSERT CONTACT +METHOD]. All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +. Translations are available at +. + +[homepage]: https://www.contributor-covenant.org +[Mozilla CoC]: https://github.com/mozilla/diversity diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/CONTRIBUTING.md b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/CONTRIBUTING.md new file mode 100644 index 00000000..4bcde4bd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/CONTRIBUTING.md @@ -0,0 +1,71 @@ +# Contributing + +Contribution to diff-lcs is encouraged in any form: a bug report, a feature +request, or code contributions. There are a few DOs and DON'Ts for +contributions. + +- DO: + + - Keep the coding style that already exists for any updated Ruby code (support + or otherwise). I use [Standard Ruby][standardrb] for linting and formatting. + + - Use thoughtfully-named topic branches for contributions. Rebase your commits + into logical chunks as necessary. + + - Use [quality commit messages][qcm]. + + - Add your name or GitHub handle to `CONTRIBUTORS.md` and a record in the + `CHANGELOG.md` as a separate commit from your main change. (Follow the style + in the `CHANGELOG.md` and provide a link to your PR.) + + - Add or update tests as appropriate for your change. The test suite is + written in [RSpec][rspec]. + + - Add or update documentation as appropriate for your change. The + documentation is RDoc; diff-lcs does not use extensions that may be present + in alternative documentation generators. + +- DO NOT: + + - Modify `VERSION` in `lib/diff/lcs/version.rb`. When your patch is accepted + and a release is made, the version will be updated at that point. + + - Modify `diff-lcs.gemspec`; it is a generated file. (You _may_ use + `rake gemspec` to regenerate it if your change involves metadata related to + gem itself). + + - Modify the `Gemfile`. + +## Test Dependencies + +diff-lcs uses Ryan Davis's [Hoe][Hoe] to manage the release process, and it adds +a number of rake tasks. You will mostly be interested in `rake`, which runs +tests in the same way that `rake spec` does. + +To assist with the installation of the development dependencies for diff-lcs, I +have provided a Gemfile pointing to the (generated) `diff-lcs.gemspec` file. +`minitar.gemspec` file. This will permit you to use `bundle install` to install +the dependencies. + +You can run tests with code coverage analysis by running `rake spec:coverage`. + +## Workflow + +Here's the most direct way to get your work merged into the project: + +- Fork the project. +- Clone your fork (`git clone git://github.com//diff-lcs.git`). +- Create a topic branch to contain your change + (`git checkout -b my_awesome_feature`). +- Hack away, add tests. Not necessarily in that order. +- Make sure everything still passes by running `rake`. +- If necessary, rebase your commits into logical chunks, without errors. +- Push the branch up (`git push origin my_awesome_feature`). +- Create a pull request against halostatue/diff-lcs and describe what your + change does and the why you think it should be merged. + +[hoe]: https://github.com/seattlerb/hoe +[qcm]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html +[release-gem]: https://github.com/rubygems/release-gem +[rspec]: http://rspec.info/documentation/ +[standardrb]: https://github.com/standardrb/standard diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/CONTRIBUTORS.md b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/CONTRIBUTORS.md new file mode 100644 index 00000000..9053019c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/CONTRIBUTORS.md @@ -0,0 +1,49 @@ +# Contributors + +- Austin Ziegler (@halostatue) created diff-lcs. + +Thanks to everyone else who has contributed to diff-lcs over the years: + +- @ginriki +- @joshbronson +- @kevinmook +- @mckaz +- Akinori Musha +- Artem Ignatyev +- Brandon Fish +- Baptiste Courtois (@annih) +- Camille Drapier +- Cédric Boutillier +- @earlopain +- Gregg Kellogg +- Jagdeep Singh +- Jason Gladish +- Jon Rowe +- Josef Strzibny +- Josep (@apuratepp) +- Josh Bronson +- Jun Aruga +- Justin Steele +- Kenichi Kamiya +- Kensuke Nagae +- Kevin Ansfield +- Koichi Ito +- Mark Friedgan +- Masato Nakamura +- Mark Young +- Michael Granger +- Myron Marston +- Nicolas Leger +- Oleg Orlov +- Patrick Linnane +- Paul Kunysch +- Pete Higgins +- Peter Goldstein +- Peter Wagenet +- Philippe Lafoucrière +- Ryan Lovelett +- Scott Steele +- Simon Courtois +- Tien (@tiendo1011) +- Tomas Jura +- Vít Ondruch diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/LICENCE.md b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/LICENCE.md new file mode 100644 index 00000000..c57c3f16 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/LICENCE.md @@ -0,0 +1,40 @@ +# Licence + +This software is available under three licenses: the GNU GPL version 2 (or at +your option, a later version), the Perl Artistic license, or the MIT license. +Note that my preference for licensing is the MIT license, but Algorithm::Diff +was dually originally licensed with the Perl Artistic and the GNU GPL ("the same +terms as Perl itself") and given that the Ruby implementation originally hewed +pretty closely to the Perl version, I must maintain the additional licensing +terms. + +- Copyright 2004–2025 Austin Ziegler and contributors. +- Adapted from Algorithm::Diff (Perl) by Ned Konz and a Smalltalk version by + Mario I. Wolczko. + +## MIT License + +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 AUTHORS OR +COPYRIGHT HOLDERS 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. + +## Perl Artistic License + +See the file docs/artistic.txt in the main distribution. + +## GNU GPL version 2 + +See the file docs/COPYING.txt in the main distribution. diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/Manifest.txt b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/Manifest.txt new file mode 100644 index 00000000..fe58c86c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/Manifest.txt @@ -0,0 +1,115 @@ +.rspec +CHANGELOG.md +CODE_OF_CONDUCT.md +CONTRIBUTING.md +CONTRIBUTORS.md +LICENCE.md +Manifest.txt +README.md +Rakefile +SECURITY.md +bin/htmldiff +bin/ldiff +docs/COPYING.txt +docs/artistic.txt +lib/diff-lcs.rb +lib/diff/lcs.rb +lib/diff/lcs/array.rb +lib/diff/lcs/backports.rb +lib/diff/lcs/block.rb +lib/diff/lcs/callbacks.rb +lib/diff/lcs/change.rb +lib/diff/lcs/htmldiff.rb +lib/diff/lcs/hunk.rb +lib/diff/lcs/internals.rb +lib/diff/lcs/ldiff.rb +lib/diff/lcs/string.rb +lib/diff/lcs/version.rb +mise.toml +spec/change_spec.rb +spec/diff_spec.rb +spec/fixtures/123_x +spec/fixtures/456_x +spec/fixtures/aX +spec/fixtures/bXaX +spec/fixtures/ds1.csv +spec/fixtures/ds2.csv +spec/fixtures/empty +spec/fixtures/file1.bin +spec/fixtures/file2.bin +spec/fixtures/four_lines +spec/fixtures/four_lines_with_missing_new_line +spec/fixtures/ldiff/diff.missing_new_line1-e +spec/fixtures/ldiff/diff.missing_new_line1-f +spec/fixtures/ldiff/diff.missing_new_line2-e +spec/fixtures/ldiff/diff.missing_new_line2-f +spec/fixtures/ldiff/error.diff.chef-e +spec/fixtures/ldiff/error.diff.chef-f +spec/fixtures/ldiff/error.diff.missing_new_line1-e +spec/fixtures/ldiff/error.diff.missing_new_line1-f +spec/fixtures/ldiff/error.diff.missing_new_line2-e +spec/fixtures/ldiff/error.diff.missing_new_line2-f +spec/fixtures/ldiff/output.diff +spec/fixtures/ldiff/output.diff-c +spec/fixtures/ldiff/output.diff-e +spec/fixtures/ldiff/output.diff-f +spec/fixtures/ldiff/output.diff-u +spec/fixtures/ldiff/output.diff.bin1 +spec/fixtures/ldiff/output.diff.bin1-c +spec/fixtures/ldiff/output.diff.bin1-e +spec/fixtures/ldiff/output.diff.bin1-f +spec/fixtures/ldiff/output.diff.bin1-u +spec/fixtures/ldiff/output.diff.bin2 +spec/fixtures/ldiff/output.diff.bin2-c +spec/fixtures/ldiff/output.diff.bin2-e +spec/fixtures/ldiff/output.diff.bin2-f +spec/fixtures/ldiff/output.diff.bin2-u +spec/fixtures/ldiff/output.diff.chef +spec/fixtures/ldiff/output.diff.chef-c +spec/fixtures/ldiff/output.diff.chef-e +spec/fixtures/ldiff/output.diff.chef-f +spec/fixtures/ldiff/output.diff.chef-u +spec/fixtures/ldiff/output.diff.chef2 +spec/fixtures/ldiff/output.diff.chef2-c +spec/fixtures/ldiff/output.diff.chef2-d +spec/fixtures/ldiff/output.diff.chef2-e +spec/fixtures/ldiff/output.diff.chef2-f +spec/fixtures/ldiff/output.diff.chef2-u +spec/fixtures/ldiff/output.diff.empty.vs.four_lines +spec/fixtures/ldiff/output.diff.empty.vs.four_lines-c +spec/fixtures/ldiff/output.diff.empty.vs.four_lines-e +spec/fixtures/ldiff/output.diff.empty.vs.four_lines-f +spec/fixtures/ldiff/output.diff.empty.vs.four_lines-u +spec/fixtures/ldiff/output.diff.four_lines.vs.empty +spec/fixtures/ldiff/output.diff.four_lines.vs.empty-c +spec/fixtures/ldiff/output.diff.four_lines.vs.empty-e +spec/fixtures/ldiff/output.diff.four_lines.vs.empty-f +spec/fixtures/ldiff/output.diff.four_lines.vs.empty-u +spec/fixtures/ldiff/output.diff.issue95_trailing_context +spec/fixtures/ldiff/output.diff.issue95_trailing_context-c +spec/fixtures/ldiff/output.diff.issue95_trailing_context-e +spec/fixtures/ldiff/output.diff.issue95_trailing_context-f +spec/fixtures/ldiff/output.diff.issue95_trailing_context-u +spec/fixtures/ldiff/output.diff.missing_new_line1 +spec/fixtures/ldiff/output.diff.missing_new_line1-c +spec/fixtures/ldiff/output.diff.missing_new_line1-e +spec/fixtures/ldiff/output.diff.missing_new_line1-f +spec/fixtures/ldiff/output.diff.missing_new_line1-u +spec/fixtures/ldiff/output.diff.missing_new_line2 +spec/fixtures/ldiff/output.diff.missing_new_line2-c +spec/fixtures/ldiff/output.diff.missing_new_line2-e +spec/fixtures/ldiff/output.diff.missing_new_line2-f +spec/fixtures/ldiff/output.diff.missing_new_line2-u +spec/fixtures/new-chef +spec/fixtures/new-chef2 +spec/fixtures/old-chef +spec/fixtures/old-chef2 +spec/hunk_spec.rb +spec/issues_spec.rb +spec/lcs_spec.rb +spec/ldiff_spec.rb +spec/patch_spec.rb +spec/sdiff_spec.rb +spec/spec_helper.rb +spec/traverse_balanced_spec.rb +spec/traverse_sequences_spec.rb diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/README.md b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/README.md new file mode 100644 index 00000000..65838036 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/README.md @@ -0,0 +1,92 @@ +# Diff::LCS + +- home :: https://github.com/halostatue/diff-lcs +- changelog :: https://github.com/halostatue/diff-lcs/blob/main/CHANGELOG.md +- code :: https://github.com/halostatue/diff-lcs +- bugs :: https://github.com/halostatue/diff-lcs/issues +- rdoc :: http://rubydoc.info/github/halostatue/diff-lcs + + + + + +## Description + +Diff::LCS computes the difference between two Enumerable sequences using the +McIlroy-Hunt longest common subsequence (LCS) algorithm. It includes utilities +to create a simple HTML diff output format and a standard diff-like tool. + +This is release 1.6.1, providing a simple extension that allows for +Diff::LCS::Change objects to be treated implicitly as arrays and fixes a number +of formatting issues. + +Ruby versions below 2.5 are soft-deprecated, which means that older versions are +no longer part of the CI test suite. If any changes have been introduced that +break those versions, bug reports and patches will be accepted, but it will be +up to the reporter to verify any fixes prior to release. The next major release +will completely break compatibility. + +## Synopsis + +Using this module is quite simple. By default, Diff::LCS does not extend objects +with the Diff::LCS interface, but will be called as if it were a function: + +```ruby +require 'diff/lcs' + +seq1 = %w(a b c e h j l m n p) +seq2 = %w(b c d e f j k l m r s t) + +lcs = Diff::LCS.LCS(seq1, seq2) +diffs = Diff::LCS.diff(seq1, seq2) +sdiff = Diff::LCS.sdiff(seq1, seq2) +seq = Diff::LCS.traverse_sequences(seq1, seq2, callback_obj) +bal = Diff::LCS.traverse_balanced(seq1, seq2, callback_obj) +seq2 == Diff::LCS.patch!(seq1, diffs) +seq1 == Diff::LCS.unpatch!(seq2, diffs) +seq2 == Diff::LCS.patch!(seq1, sdiff) +seq1 == Diff::LCS.unpatch!(seq2, sdiff) +``` + +Objects can be extended with Diff::LCS: + +```ruby +seq1.extend(Diff::LCS) +lcs = seq1.lcs(seq2) +diffs = seq1.diff(seq2) +sdiff = seq1.sdiff(seq2) +seq = seq1.traverse_sequences(seq2, callback_obj) +bal = seq1.traverse_balanced(seq2, callback_obj) +seq2 == seq1.patch!(diffs) +seq1 == seq2.unpatch!(diffs) +seq2 == seq1.patch!(sdiff) +seq1 == seq2.unpatch!(sdiff) +``` + +By requiring 'diff/lcs/array' or 'diff/lcs/string', Array or String will be +extended for use this way. + +Note that Diff::LCS requires a sequenced enumerable container, which means that +the order of enumeration is both predictable and consistent for the same set of +data. While it is theoretically possible to generate a diff for an unordered +hash, it will only be meaningful if the enumeration of the hashes is consistent. +In general, this will mean that containers that behave like String or Array will +perform best. + +## History + +Diff::LCS is a port of Perl's Algorithm::Diff that uses the McIlroy-Hunt longest +common subsequence (LCS) algorithm to compute intelligent differences between +two sequenced enumerable containers. The implementation is based on Mario I. +Wolczko's [Smalltalk version 1.2][smalltalk] (1993) and Ned Konz's Perl version +[Algorithm::Diff 1.15][perl]. `Diff::LCS#sdiff` and +`Diff::LCS#traverse_balanced` were originally written for the Perl version by +Mike Schilli. + +The algorithm is described in A Fast Algorithm for Computing Longest Common +Subsequences, CACM, vol.20, no.5, pp.350-353, May 1977, with a few minor +improvements to improve the speed. A simplified description of the algorithm, +originally written for the Perl version, was written by Mark-Jason Dominus. + +[smalltalk]: ftp://st.cs.uiuc.edu/pub/Smalltalk/MANCHESTER/manchester/4.0/diff.st +[perl]: http://search.cpan.org/~nedkonz/Algorithm-Diff-1.15/ diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/Rakefile b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/Rakefile new file mode 100644 index 00000000..0bfe927b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/Rakefile @@ -0,0 +1,115 @@ +require "rubygems" +require "rspec" +require "rspec/core/rake_task" +require "hoe" +require "rake/clean" + +MAINTENANCE = ENV["MAINTENANCE"] == "true" +BUILD_DOCS = MAINTENANCE || ENV["DOCS"] == "true" +TRUSTED_RELEASE = ENV["rubygems_release_gem"] == "true" + +Hoe.plugin :halostatue +Hoe.plugin :rubygems + +Hoe.plugins.delete :debug +Hoe.plugins.delete :newb +Hoe.plugins.delete :signing +Hoe.plugins.delete :publish unless BUILD_DOCS + +if RUBY_VERSION < "1.9" + class Array # :nodoc: + def to_h + Hash[*flatten(1)] + end + end + + class Gem::Specification # :nodoc: + def metadata=(*) + end + + def default_value(*) + end + end + + class Object # :nodoc: + def caller_locations(*) + [] + end + end +end + +_spec = Hoe.spec "diff-lcs" do + developer("Austin Ziegler", "halostatue@gmail.com") + + self.trusted_release = TRUSTED_RELEASE + + require_ruby_version ">= 1.8" + + self.history_file = "CHANGELOG.md" + self.readme_file = "README.md" + self.licenses = ["MIT", "Artistic-1.0-Perl", "GPL-2.0-or-later"] + + spec_extras[:metadata] = ->(val) { + val["rubygems_mfa_required"] = "true" + } + + extra_dev_deps << ["hoe", "~> 4.0"] + extra_dev_deps << ["hoe-halostatue", "~> 2.0"] + extra_dev_deps << ["hoe-rubygems", "~> 1.0"] + extra_dev_deps << ["rspec", ">= 2.0", "< 4"] + extra_dev_deps << ["rake", ">= 10.0", "< 14"] + extra_dev_deps << ["rdoc", ">= 6.3.1", "< 7"] +end + +if BUILD_DOCS + rake_tasks = Rake.application.instance_variable_get(:@tasks) + tasks = ["publish_docs", "publish_on_announce", "debug_email", "post_blog", "announce"] + tasks.each do |task| + rake_tasks.delete(task) + end +end + +desc "Run all specifications" +RSpec::Core::RakeTask.new(:spec) do |t| + rspec_dirs = %w[spec lib].join(":") + t.rspec_opts = ["-I#{rspec_dirs}"] +end + +task :version do + require "diff/lcs/version" + puts Diff::LCS::VERSION +end + +Rake::Task["spec"].actions.uniq! { |a| a.source_location } + +# standard:disable Style/HashSyntax +task :default => :spec unless Rake::Task["default"].prereqs.include?("spec") +task :test => :spec unless Rake::Task["test"].prereqs.include?("spec") +# standard:enable Style/HashSyntax + +if RUBY_VERSION >= "3.0" && RUBY_ENGINE == "ruby" + namespace :spec do + desc "Runs test coverage. Only works Ruby 2.0+ and assumes 'simplecov' is installed." + task :coverage do + ENV["COVERAGE"] = "true" + Rake::Task["spec"].execute + end + end +end + +if MAINTENANCE + task ruby18: :package do + require "diff/lcs/version" + # standard:disable Layout/HeredocIndentation + puts <<-MESSAGE +You are starting a barebones Ruby 1.8 docker environment for testing. +A snapshot package has been built, so install it with: + + cd diff-lcs + gem install pkg/diff-lcs-#{Diff::LCS::VERSION} + + MESSAGE + # standard:enable Layout/HeredocIndentation + sh "docker run -it --rm -v #{Dir.pwd}:/root/diff-lcs bellbind/docker-ruby18-rails2 bash -l" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/SECURITY.md b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/SECURITY.md new file mode 100644 index 00000000..16854f66 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/SECURITY.md @@ -0,0 +1,41 @@ +# diff-lcs Security + +## Supported Versions + +Security reports are accepted for the most recent major release and the previous +version for a limited time after the initial major release version. After a +major release, the previous version will receive full support for six months and +security support for an additional six months (for a total of twelve months). + +Because diff-lcs 1.x supports a wide range of Ruby versions, security reports +will only be accepted when they can be demonstrated on Ruby 3.1 or higher. + +> [!information] +> +> There will be a diff-lcs 2.0 released in 2025 which narrows support to modern +> versions of Ruby only. +> +> | Release Date | Support Ends | Security Support Ends | +> | ------------ | ------------ | --------------------- | +> | 2025 | +6 months | +12 months | +> +> If the 2.0.0 release happens on 2025-07-01, regular support for diff-lcs 1.x +> will end on 2026-12-31 and security support for diff-lcs 1.x will end on +> 2026-06-30. + +## Reporting a Vulnerability + +By preference, use the [Tidelift security contact][tidelift]. Tidelift will +coordinate the fix and disclosure. + +Alternatively, Send an email to [diff-lcs@halostatue.ca][email] with the text +`Diff::LCS` in the subject. Emails sent to this address should be encrypted +using [age][age] with the following public key: + +``` +age1fc6ngxmn02m62fej5cl30lrvwmxn4k3q2atqu53aatekmnqfwumqj4g93w +``` + +[tidelift]: https://tidelift.com/security +[email]: mailto:diff-lcs@halostatue.ca +[age]: https://github.com/FiloSottile/age diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/bin/htmldiff b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/bin/htmldiff new file mode 100755 index 00000000..bcd89d21 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/bin/htmldiff @@ -0,0 +1,35 @@ +#! /usr/bin/env ruby -w +# frozen_string_literal: true + +require "diff/lcs" +require "diff/lcs/htmldiff" + +begin + require "text/format" +rescue LoadError + Diff::LCS::HTMLDiff.can_expand_tabs = false +end + +if ARGV.size < 2 or ARGV.size > 3 + warn "usage: #{File.basename($0)} old new [output.html]" + warn " #{File.basename($0)} old new > output.html" + exit 127 +end + +left = IO.read(ARGV[0]).split($/) +right = IO.read(ARGV[1]).split($/) + +options = { :title => "diff #{ARGV[0]} #{ARGV[1]}" } + +htmldiff = Diff::LCS::HTMLDiff.new(left, right, options) + +if ARGV[2] + File.open(ARGV[2], "w") do |f| + htmldiff.options[:output] = f + htmldiff.run + end +else + htmldiff.run +end + +# vim: ft=ruby diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/bin/ldiff b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/bin/ldiff new file mode 100755 index 00000000..f4734f58 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/bin/ldiff @@ -0,0 +1,9 @@ +#! /usr/bin/env ruby -w +# frozen_string_literal: true + +require 'diff/lcs' +require 'diff/lcs/ldiff' + +exit Diff::LCS::Ldiff.run(ARGV) + +# vim: ft=ruby diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/docs/COPYING.txt b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/docs/COPYING.txt new file mode 100644 index 00000000..d159169d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/docs/COPYING.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/docs/artistic.txt b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/docs/artistic.txt new file mode 100644 index 00000000..763e17a9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/docs/artistic.txt @@ -0,0 +1,127 @@ +The "Artistic License" + + Preamble + +The intent of this document is to state the conditions under which a +Package may be copied, such that the Copyright Holder maintains some +semblance of artistic control over the development of the package, +while giving the users of the package the right to use and distribute +the Package in a more-or-less customary fashion, plus the right to make +reasonable modifications. + +Definitions: + + "Package" refers to the collection of files distributed by the + Copyright Holder, and derivatives of that collection of files + created through textual modification. + + "Standard Version" refers to such a Package if it has not been + modified, or has been modified in accordance with the wishes + of the Copyright Holder as specified below. + + "Copyright Holder" is whoever is named in the copyright or + copyrights for the package. + + "You" is you, if you're thinking about copying or distributing + this Package. + + "Reasonable copying fee" is whatever you can justify on the + basis of media cost, duplication charges, time of people involved, + and so on. (You will not be required to justify it to the + Copyright Holder, but only to the computing community at large + as a market that must bear the fee.) + + "Freely Available" means that no fee is charged for the item + itself, though there may be fees involved in handling the item. + It also means that recipients of the item may redistribute it + under the same conditions they received it. + +1. You may make and give away verbatim copies of the source form of the +Standard Version of this Package without restriction, provided that you +duplicate all of the original copyright notices and associated disclaimers. + +2. You may apply bug fixes, portability fixes and other modifications +derived from the Public Domain or from the Copyright Holder. A Package +modified in such a way shall still be considered the Standard Version. + +3. You may otherwise modify your copy of this Package in any way, provided +that you insert a prominent notice in each changed file stating how and +when you changed that file, and provided that you do at least ONE of the +following: + + a) place your modifications in the Public Domain or otherwise make them + Freely Available, such as by posting said modifications to Usenet or + an equivalent medium, or placing the modifications on a major archive + site such as uunet.uu.net, or by allowing the Copyright Holder to include + your modifications in the Standard Version of the Package. + + b) use the modified Package only within your corporation or organization. + + c) rename any non-standard executables so the names do not conflict + with standard executables, which must also be provided, and provide + a separate manual page for each non-standard executable that clearly + documents how it differs from the Standard Version. + + d) make other distribution arrangements with the Copyright Holder. + +4. You may distribute the programs of this Package in object code or +executable form, provided that you do at least ONE of the following: + + a) distribute a Standard Version of the executables and library files, + together with instructions (in the manual page or equivalent) on where + to get the Standard Version. + + b) accompany the distribution with the machine-readable source of + the Package with your modifications. + + c) give non-standard executables non-standard names, and clearly + document the differences in manual pages (or equivalent), together + with instructions on where to get the Standard Version. + + d) make other distribution arrangements with the Copyright Holder. + +5. You may charge a reasonable copying fee for any distribution of this +Package. You may charge any fee you choose for support of this +Package. You may not charge a fee for this Package itself. However, +you may distribute this Package in aggregate with other (possibly +commercial) programs as part of a larger (possibly commercial) software +distribution provided that you do not advertise this Package as a +product of your own. You may embed this Package's interpreter within +an executable of yours (by linking); this shall be construed as a mere +form of aggregation, provided that the complete Standard Version of the +interpreter is so embedded. + +6. The scripts and library files supplied as input to or produced as +output from the programs of this Package do not automatically fall +under the copyright of this Package, but belong to whoever generated +them, and may be sold commercially, and may be aggregated with this +Package. If such scripts or library files are aggregated with this +Package via the so-called "undump" or "unexec" methods of producing a +binary executable image, then distribution of such an image shall +neither be construed as a distribution of this Package nor shall it +fall under the restrictions of Paragraphs 3 and 4, provided that you do +not represent such an executable image as a Standard Version of this +Package. + +7. C subroutines (or comparably compiled subroutines in other +languages) supplied by you and linked into this Package in order to +emulate subroutines and variables of the language defined by this +Package shall not be considered part of this Package, but are the +equivalent of input as in Paragraph 6, provided these subroutines do +not change the language in any way that would cause it to fail the +regression tests for the language. + +8. Aggregation of this Package with a commercial distribution is always +permitted provided that the use of this Package is embedded; that is, +when no overt attempt is made to make this Package's interfaces visible +to the end user of the commercial distribution. Such use shall not be +construed as a distribution of this Package. + +9. The name of the Copyright Holder may not be used to endorse or promote +products derived from this software without specific prior written permission. + +10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + + The End diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff-lcs.rb b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff-lcs.rb new file mode 100644 index 00000000..bc07bf99 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff-lcs.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +require "diff/lcs" diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs.rb b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs.rb new file mode 100644 index 00000000..5ee89377 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs.rb @@ -0,0 +1,742 @@ +# frozen_string_literal: true + +module Diff; end unless defined? Diff + +# == How Diff Works (by Mark-Jason Dominus) +# +# I once read an article written by the authors of +diff+; they said that they +# hard worked very hard on the algorithm until they found the right one. +# +# I think what they ended up using (and I hope someone will correct me, because +# I am not very confident about this) was the `longest common subsequence' +# method. In the LCS problem, you have two sequences of items: +# +# a b c d f g h j q z +# a b c d e f g i j k r x y z +# +# and you want to find the longest sequence of items that is present in both +# original sequences in the same order. That is, you want to find a new +# sequence *S* which can be obtained from the first sequence by deleting some +# items, and from the second sequence by deleting other items. You also want +# *S* to be as long as possible. In this case *S* is: +# +# a b c d f g j z +# +# From there it's only a small step to get diff-like output: +# +# e h i k q r x y +# + - + + - + + + +# +# This module solves the LCS problem. It also includes a canned function to +# generate +diff+-like output. +# +# It might seem from the example above that the LCS of two sequences is always +# pretty obvious, but that's not always the case, especially when the two +# sequences have many repeated elements. For example, consider +# +# a x b y c z p d q +# a b c a x b y c z +# +# A naive approach might start by matching up the +a+ and +b+ that appear at +# the beginning of each sequence, like this: +# +# a x b y c z p d q +# a b c a b y c z +# +# This finds the common subsequence +a b c z+. But actually, the LCS is +a x b +# y c z+: +# +# a x b y c z p d q +# a b c a x b y c z +module Diff::LCS +end + +require "diff/lcs/version" +require "diff/lcs/callbacks" +require "diff/lcs/internals" + +module Diff::LCS + # Returns an Array containing the longest common subsequence(s) between + # +self+ and +other+. See Diff::LCS#lcs. + # + # lcs = seq1.lcs(seq2) + # + # A note when using objects: Diff::LCS only works properly when each object + # can be used as a key in a Hash. This means that those objects must implement + # the methods +#hash+ and +#eql?+ such that two objects containing identical values + # compare identically for key purposes. That is: + # + # O.new('a').eql?(O.new('a')) == true && + # O.new('a').hash == O.new('a').hash + def lcs(other, &block) # :yields: self[i] if there are matched subsequences + Diff::LCS.lcs(self, other, &block) + end + + # Returns the difference set between +self+ and +other+. See Diff::LCS#diff. + def diff(other, callbacks = nil, &block) + Diff::LCS.diff(self, other, callbacks, &block) + end + + # Returns the balanced ("side-by-side") difference set between +self+ and + # +other+. See Diff::LCS#sdiff. + def sdiff(other, callbacks = nil, &block) + Diff::LCS.sdiff(self, other, callbacks, &block) + end + + # Traverses the discovered longest common subsequences between +self+ and + # +other+. See Diff::LCS#traverse_sequences. + def traverse_sequences(other, callbacks = nil, &block) + Diff::LCS.traverse_sequences(self, other, callbacks || Diff::LCS::SequenceCallbacks, &block) + end + + # Traverses the discovered longest common subsequences between +self+ and + # +other+ using the alternate, balanced algorithm. See + # Diff::LCS#traverse_balanced. + def traverse_balanced(other, callbacks = nil, &block) + Diff::LCS.traverse_balanced(self, other, callbacks || Diff::LCS::BalancedCallbacks, &block) + end + + # Attempts to patch +self+ with the provided +patchset+. A new sequence based + # on +self+ and the +patchset+ will be created. See Diff::LCS#patch. Attempts + # to autodiscover the direction of the patch. + def patch(patchset) + Diff::LCS.patch(self, patchset) + end + alias_method :unpatch, :patch + + # Attempts to patch +self+ with the provided +patchset+. A new sequence based + # on +self+ and the +patchset+ will be created. See Diff::LCS#patch. Does no + # patch direction autodiscovery. + def patch!(patchset) + Diff::LCS.patch!(self, patchset) + end + + # Attempts to unpatch +self+ with the provided +patchset+. A new sequence + # based on +self+ and the +patchset+ will be created. See Diff::LCS#unpatch. + # Does no patch direction autodiscovery. + def unpatch!(patchset) + Diff::LCS.unpatch!(self, patchset) + end + + # Attempts to patch +self+ with the provided +patchset+, using #patch!. If + # the sequence this is used on supports #replace, the value of +self+ will be + # replaced. See Diff::LCS#patch. Does no patch direction autodiscovery. + def patch_me(patchset) + if respond_to? :replace + replace(patch!(patchset)) + else + patch!(patchset) + end + end + + # Attempts to unpatch +self+ with the provided +patchset+, using #unpatch!. + # If the sequence this is used on supports #replace, the value of +self+ will + # be replaced. See Diff::LCS#unpatch. Does no patch direction autodiscovery. + def unpatch_me(patchset) + if respond_to? :replace + replace(unpatch!(patchset)) + else + unpatch!(patchset) + end + end +end + +class << Diff::LCS + def lcs(seq1, seq2, &block) # :yields: seq1[i] for each matched + matches = Diff::LCS::Internals.lcs(seq1, seq2) + ret = [] + string = seq1.is_a? String + matches.each_index do |i| + next if matches[i].nil? + + v = string ? seq1[i, 1] : seq1[i] + v = block[v] if block + ret << v + end + ret + end + alias_method :LCS, :lcs + + # #diff computes the smallest set of additions and deletions necessary to + # turn the first sequence into the second, and returns a description of these + # changes. + # + # See Diff::LCS::DiffCallbacks for the default behaviour. An alternate + # behaviour may be implemented with Diff::LCS::ContextDiffCallbacks. If a + # Class argument is provided for +callbacks+, #diff will attempt to + # initialise it. If the +callbacks+ object (possibly initialised) responds to + # #finish, it will be called. + def diff(seq1, seq2, callbacks = nil, &block) # :yields: diff changes + diff_traversal(:diff, seq1, seq2, callbacks || Diff::LCS::DiffCallbacks, &block) + end + + # #sdiff computes all necessary components to show two sequences and their + # minimized differences side by side, just like the Unix utility + # sdiff does: + # + # old < - + # same same + # before | after + # - > new + # + # See Diff::LCS::SDiffCallbacks for the default behaviour. An alternate + # behaviour may be implemented with Diff::LCS::ContextDiffCallbacks. If a + # Class argument is provided for +callbacks+, #diff will attempt to + # initialise it. If the +callbacks+ object (possibly initialised) responds to + # #finish, it will be called. + # + # Each element of a returned array is a Diff::LCS::ContextChange object, + # which can be implicitly converted to an array. + # + # Diff::LCS.sdiff(a, b).each do |action, (old_pos, old_element), (new_pos, new_element)| + # case action + # when '!' + # # replace + # when '-' + # # delete + # when '+' + # # insert + # end + # end + def sdiff(seq1, seq2, callbacks = nil, &block) # :yields: diff changes + diff_traversal(:sdiff, seq1, seq2, callbacks || Diff::LCS::SDiffCallbacks, &block) + end + + # #traverse_sequences is the most general facility provided by this module; + # #diff and #lcs are implemented as calls to it. + # + # The arguments to #traverse_sequences are the two sequences to traverse, and + # a callback object, like this: + # + # traverse_sequences(seq1, seq2, Diff::LCS::ContextDiffCallbacks.new) + # + # == Callback Methods + # + # Optional callback methods are emphasized. + # + # callbacks#match:: Called when +a+ and +b+ are pointing to + # common elements in +A+ and +B+. + # callbacks#discard_a:: Called when +a+ is pointing to an + # element not in +B+. + # callbacks#discard_b:: Called when +b+ is pointing to an + # element not in +A+. + # callbacks#finished_a:: Called when +a+ has reached the end of + # sequence +A+. + # callbacks#finished_b:: Called when +b+ has reached the end of + # sequence +B+. + # + # == Algorithm + # + # a---+ + # v + # A = a b c e h j l m n p + # B = b c d e f j k l m r s t + # ^ + # b---+ + # + # If there are two arrows (+a+ and +b+) pointing to elements of sequences +A+ + # and +B+, the arrows will initially point to the first elements of their + # respective sequences. #traverse_sequences will advance the arrows through + # the sequences one element at a time, calling a method on the user-specified + # callback object before each advance. It will advance the arrows in such a + # way that if there are elements A[i] and B[j] which are + # both equal and part of the longest common subsequence, there will be some + # moment during the execution of #traverse_sequences when arrow +a+ is + # pointing to A[i] and arrow +b+ is pointing to B[j]. When + # this happens, #traverse_sequences will call callbacks#match and + # then it will advance both arrows. + # + # Otherwise, one of the arrows is pointing to an element of its sequence that + # is not part of the longest common subsequence. #traverse_sequences will + # advance that arrow and will call callbacks#discard_a or + # callbacks#discard_b, depending on which arrow it advanced. If both + # arrows point to elements that are not part of the longest common + # subsequence, then #traverse_sequences will advance arrow +a+ and call the + # appropriate callback, then it will advance arrow +b+ and call the appropriate + # callback. + # + # The methods for callbacks#match, callbacks#discard_a, and + # callbacks#discard_b are invoked with an event comprising the + # action ("=", "+", or "-", respectively), the indexes +i+ and +j+, and the + # elements A[i] and B[j]. Return values are discarded by + # #traverse_sequences. + # + # === End of Sequences + # + # If arrow +a+ reaches the end of its sequence before arrow +b+ does, + # #traverse_sequence will try to call callbacks#finished_a with the + # last index and element of +A+ (A[-1]) and the current index and + # element of +B+ (B[j]). If callbacks#finished_a does not + # exist, then callbacks#discard_b will be called on each element of + # +B+ until the end of the sequence is reached (the call will be done with + # A[-1] and B[j] for each element). + # + # If +b+ reaches the end of +B+ before +a+ reaches the end of +A+, + # callbacks#finished_b will be called with the current index and + # element of +A+ (A[i]) and the last index and element of +B+ + # (A[-1]). Again, if callbacks#finished_b does not exist on + # the callback object, then callbacks#discard_a will be called on + # each element of +A+ until the end of the sequence is reached (A[i] + # and B[-1]). + # + # There is a chance that one additional callbacks#discard_a or + # callbacks#discard_b will be called after the end of the sequence + # is reached, if +a+ has not yet reached the end of +A+ or +b+ has not yet + # reached the end of +B+. + def traverse_sequences(seq1, seq2, callbacks = Diff::LCS::SequenceCallbacks) # :yields: change events + callbacks ||= Diff::LCS::SequenceCallbacks + matches = Diff::LCS::Internals.lcs(seq1, seq2) + + run_finished_a = run_finished_b = false + string = seq1.is_a?(String) + + a_size = seq1.size + b_size = seq2.size + ai = bj = 0 + + matches.each do |b_line| + if b_line.nil? + unless seq1[ai].nil? + ax = string ? seq1[ai, 1] : seq1[ai] + bx = string ? seq2[bj, 1] : seq2[bj] + + event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_a(event) + end + else + ax = string ? seq1[ai, 1] : seq1[ai] + + loop do + break unless bj < b_line + + bx = string ? seq2[bj, 1] : seq2[bj] + event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_b(event) + bj += 1 + end + bx = string ? seq2[bj, 1] : seq2[bj] + event = Diff::LCS::ContextChange.new("=", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.match(event) + bj += 1 + end + ai += 1 + end + + # The last entry (if any) processed was a match. +ai+ and +bj+ point just + # past the last matching lines in their sequences. + while (ai < a_size) || (bj < b_size) + # last A? + if ai == a_size && bj < b_size + if callbacks.respond_to?(:finished_a) && !run_finished_a + ax = string ? seq1[-1, 1] : seq1[-1] + bx = string ? seq2[bj, 1] : seq2[bj] + event = Diff::LCS::ContextChange.new(">", a_size - 1, ax, bj, bx) + event = yield event if block_given? + callbacks.finished_a(event) + run_finished_a = true + else + ax = string ? seq1[ai, 1] : seq1[ai] + loop do + bx = string ? seq2[bj, 1] : seq2[bj] + event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_b(event) + bj += 1 + break unless bj < b_size + end + end + end + + # last B? + if bj == b_size && ai < a_size + if callbacks.respond_to?(:finished_b) && !run_finished_b + ax = string ? seq1[ai, 1] : seq1[ai] + bx = string ? seq2[-1, 1] : seq2[-1] + event = Diff::LCS::ContextChange.new("<", ai, ax, b_size - 1, bx) + event = yield event if block_given? + callbacks.finished_b(event) + run_finished_b = true + else + bx = string ? seq2[bj, 1] : seq2[bj] + loop do + ax = string ? seq1[ai, 1] : seq1[ai] + event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_a(event) + ai += 1 + break unless bj < b_size + end + end + end + + if ai < a_size + ax = string ? seq1[ai, 1] : seq1[ai] + bx = string ? seq2[bj, 1] : seq2[bj] + event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_a(event) + ai += 1 + end + + if bj < b_size + ax = string ? seq1[ai, 1] : seq1[ai] + bx = string ? seq2[bj, 1] : seq2[bj] + event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_b(event) + bj += 1 + end + end + end + + # #traverse_balanced is an alternative to #traverse_sequences. It uses a + # different algorithm to iterate through the entries in the computed longest + # common subsequence. Instead of viewing the changes as insertions or + # deletions from one of the sequences, #traverse_balanced will report + # changes between the sequences. + # + # The arguments to #traverse_balanced are the two sequences to traverse and a + # callback object, like this: + # + # traverse_balanced(seq1, seq2, Diff::LCS::ContextDiffCallbacks.new) + # + # #sdiff is implemented with #traverse_balanced. + # + # == Callback Methods + # + # Optional callback methods are emphasized. + # + # callbacks#match:: Called when +a+ and +b+ are pointing to + # common elements in +A+ and +B+. + # callbacks#discard_a:: Called when +a+ is pointing to an + # element not in +B+. + # callbacks#discard_b:: Called when +b+ is pointing to an + # element not in +A+. + # callbacks#change:: Called when +a+ and +b+ are pointing to + # the same relative position, but + # A[a] and B[b] are not + # the same; a change has + # occurred. + # + # #traverse_balanced might be a bit slower than #traverse_sequences, + # noticeable only while processing huge amounts of data. + # + # == Algorithm + # + # a---+ + # v + # A = a b c e h j l m n p + # B = b c d e f j k l m r s t + # ^ + # b---+ + # + # === Matches + # + # If there are two arrows (+a+ and +b+) pointing to elements of sequences +A+ + # and +B+, the arrows will initially point to the first elements of their + # respective sequences. #traverse_sequences will advance the arrows through + # the sequences one element at a time, calling a method on the user-specified + # callback object before each advance. It will advance the arrows in such a + # way that if there are elements A[i] and B[j] which are + # both equal and part of the longest common subsequence, there will be some + # moment during the execution of #traverse_sequences when arrow +a+ is + # pointing to A[i] and arrow +b+ is pointing to B[j]. When + # this happens, #traverse_sequences will call callbacks#match and + # then it will advance both arrows. + # + # === Discards + # + # Otherwise, one of the arrows is pointing to an element of its sequence that + # is not part of the longest common subsequence. #traverse_sequences will + # advance that arrow and will call callbacks#discard_a or + # callbacks#discard_b, depending on which arrow it advanced. + # + # === Changes + # + # If both +a+ and +b+ point to elements that are not part of the longest + # common subsequence, then #traverse_sequences will try to call + # callbacks#change and advance both arrows. If + # callbacks#change is not implemented, then + # callbacks#discard_a and callbacks#discard_b will be + # called in turn. + # + # The methods for callbacks#match, callbacks#discard_a, + # callbacks#discard_b, and callbacks#change are invoked + # with an event comprising the action ("=", "+", "-", or "!", respectively), + # the indexes +i+ and +j+, and the elements A[i] and B[j]. + # Return values are discarded by #traverse_balanced. + # + # === Context + # + # Note that +i+ and +j+ may not be the same index position, even if +a+ and + # +b+ are considered to be pointing to matching or changed elements. + def traverse_balanced(seq1, seq2, callbacks = Diff::LCS::BalancedCallbacks) + matches = Diff::LCS::Internals.lcs(seq1, seq2) + a_size = seq1.size + b_size = seq2.size + ai = bj = mb = 0 + ma = -1 + string = seq1.is_a?(String) + + # Process all the lines in the match vector. + loop do + # Find next match indexes +ma+ and +mb+ + loop do + ma += 1 + break unless ma < matches.size && matches[ma].nil? + end + + break if ma >= matches.size # end of matches? + + mb = matches[ma] + + # Change(seq2) + while (ai < ma) || (bj < mb) + ax = string ? seq1[ai, 1] : seq1[ai] + bx = string ? seq2[bj, 1] : seq2[bj] + + case [(ai < ma), (bj < mb)] + when [true, true] + if callbacks.respond_to?(:change) + event = Diff::LCS::ContextChange.new("!", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.change(event) + ai += 1 + else + event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_a(event) + ai += 1 + ax = string ? seq1[ai, 1] : seq1[ai] + event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_b(event) + end + + bj += 1 + when [true, false] + event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_a(event) + ai += 1 + when [false, true] + event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_b(event) + bj += 1 + end + end + + # Match + ax = string ? seq1[ai, 1] : seq1[ai] + bx = string ? seq2[bj, 1] : seq2[bj] + event = Diff::LCS::ContextChange.new("=", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.match(event) + ai += 1 + bj += 1 + end + + while (ai < a_size) || (bj < b_size) + ax = string ? seq1[ai, 1] : seq1[ai] + bx = string ? seq2[bj, 1] : seq2[bj] + + case [(ai < a_size), (bj < b_size)] + when [true, true] + if callbacks.respond_to?(:change) + event = Diff::LCS::ContextChange.new("!", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.change(event) + ai += 1 + else + event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_a(event) + ai += 1 + ax = string ? seq1[ai, 1] : seq1[ai] + event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_b(event) + end + + bj += 1 + when [true, false] + event = Diff::LCS::ContextChange.new("-", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_a(event) + ai += 1 + when [false, true] + event = Diff::LCS::ContextChange.new("+", ai, ax, bj, bx) + event = yield event if block_given? + callbacks.discard_b(event) + bj += 1 + end + end + end + + # standard:disable Style/HashSyntax + PATCH_MAP = { # :nodoc: + :patch => {"+" => "+", "-" => "-", "!" => "!", "=" => "="}.freeze, + :unpatch => {"+" => "-", "-" => "+", "!" => "!", "=" => "="}.freeze + }.freeze + # standard:enable Style/HashSyntax + + # Applies a +patchset+ to the sequence +src+ according to the +direction+ + # (:patch or :unpatch), producing a new sequence. + # + # If the +direction+ is not specified, Diff::LCS::patch will attempt to + # discover the direction of the +patchset+. + # + # A +patchset+ can be considered to apply forward (:patch) if the + # following expression is true: + # + # patch(s1, diff(s1, s2)) -> s2 + # + # A +patchset+ can be considered to apply backward (:unpatch) if the + # following expression is true: + # + # patch(s2, diff(s1, s2)) -> s1 + # + # If the +patchset+ contains no changes, the +src+ value will be returned as + # either src.dup or +src+. A +patchset+ can be deemed as having no + # changes if the following predicate returns true: + # + # patchset.empty? or + # patchset.flatten(1).all? { |change| change.unchanged? } + # + # === Patchsets + # + # A +patchset+ is always an enumerable sequence of changes, hunks of changes, + # or a mix of the two. A hunk of changes is an enumerable sequence of + # changes: + # + # [ # patchset + # # change + # [ # hunk + # # change + # ] + # ] + # + # The +patch+ method accepts patchsets that are enumerable sequences + # containing either Diff::LCS::Change objects (or a subclass) or the array + # representations of those objects. Prior to application, array + # representations of Diff::LCS::Change objects will be reified. + def patch(src, patchset, direction = nil) + # Normalize the patchset. + has_changes, patchset = Diff::LCS::Internals.analyze_patchset(patchset) + + return src.respond_to?(:dup) ? src.dup : src unless has_changes + + string = src.is_a?(String) + # Start with a new empty type of the source's class + res = src.class.new + + direction ||= Diff::LCS::Internals.intuit_diff_direction(src, patchset) + + ai = bj = 0 + + patch_map = PATCH_MAP[direction] + + patchset.each do |change| + # Both Change and ContextChange support #action + action = patch_map[change.action] + + case change + when Diff::LCS::ContextChange + case direction + when :patch + el = change.new_element + op = change.old_position + np = change.new_position + when :unpatch + el = change.old_element + op = change.new_position + np = change.old_position + end + + case action + when "-" # Remove details from the old string + while ai < op + res << (string ? src[ai, 1] : src[ai]) + ai += 1 + bj += 1 + end + ai += 1 + when "+" + while bj < np + res << (string ? src[ai, 1] : src[ai]) + ai += 1 + bj += 1 + end + + res << el + bj += 1 + when "=" + # This only appears in sdiff output with the SDiff callback. + # Therefore, we only need to worry about dealing with a single + # element. + res << el + + ai += 1 + bj += 1 + when "!" + while ai < op + res << (string ? src[ai, 1] : src[ai]) + ai += 1 + bj += 1 + end + + bj += 1 + ai += 1 + + res << el + end + when Diff::LCS::Change + case action + when "-" + while ai < change.position + res << (string ? src[ai, 1] : src[ai]) + ai += 1 + bj += 1 + end + ai += 1 + when "+" + while bj < change.position + res << (string ? src[ai, 1] : src[ai]) + ai += 1 + bj += 1 + end + + bj += 1 + + res << change.element + end + end + end + + while ai < src.size + res << (string ? src[ai, 1] : src[ai]) + ai += 1 + bj += 1 + end + + res + end + + # Given a set of patchset, convert the current version to the prior version. + # Does no auto-discovery. + def unpatch!(src, patchset) + patch(src, patchset, :unpatch) + end + + # Given a set of patchset, convert the current version to the next version. + # Does no auto-discovery. + def patch!(src, patchset) + patch(src, patchset, :patch) + end +end + +require "diff/lcs/backports" diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/array.rb b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/array.rb new file mode 100644 index 00000000..663918a2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/array.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require "diff/lcs" + +class Array + include Diff::LCS +end diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/backports.rb b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/backports.rb new file mode 100644 index 00000000..6543c8a4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/backports.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +unless 0.respond_to?(:positive?) + class Fixnum # standard:disable Lint/UnifiedInteger + def positive? + self > 0 + end + + def negative? + self < 0 + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/block.rb b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/block.rb new file mode 100644 index 00000000..226ed6fa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/block.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +# A block is an operation removing, adding, or changing a group of items. +# Basically, this is just a list of changes, where each change adds or +# deletes a single item. Used by bin/ldiff. +class Diff::LCS::Block + attr_reader :changes, :insert, :remove + + def initialize(chunk) + @changes = [] + @insert = [] + @remove = [] + + chunk.each do |item| + @changes << item + @remove << item if item.deleting? + @insert << item if item.adding? + end + end + + def diff_size + @insert.size - @remove.size + end + + def op + case [@remove.empty?, @insert.empty?] + when [false, false] + "!" + when [false, true] + "-" + when [true, false] + "+" + else # [true, true] + "^" + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/callbacks.rb b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/callbacks.rb new file mode 100644 index 00000000..2c5a7791 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/callbacks.rb @@ -0,0 +1,327 @@ +# frozen_string_literal: true + +require "diff/lcs/change" + +module Diff::LCS + # This callback object implements the default set of callback events, + # which only returns the event itself. Note that #finished_a and + # #finished_b are not implemented -- I haven't yet figured out where they + # would be useful. + # + # Note that this is intended to be called as is, e.g., + # + # Diff::LCS.LCS(seq1, seq2, Diff::LCS::DefaultCallbacks) + class DefaultCallbacks + class << self + # Called when two items match. + def match(event) + event + end + + # Called when the old value is discarded in favour of the new value. + def discard_a(event) + event + end + + # Called when the new value is discarded in favour of the old value. + def discard_b(event) + event + end + + # Called when both the old and new values have changed. + def change(event) + event + end + + private :new + end + end + + # An alias for DefaultCallbacks that is used in + # Diff::LCS#traverse_sequences. + # + # Diff::LCS.LCS(seq1, seq2, Diff::LCS::SequenceCallbacks) + SequenceCallbacks = DefaultCallbacks + + # An alias for DefaultCallbacks that is used in + # Diff::LCS#traverse_balanced. + # + # Diff::LCS.LCS(seq1, seq2, Diff::LCS::BalancedCallbacks) + BalancedCallbacks = DefaultCallbacks + + def self.callbacks_for(callbacks) + callbacks.new + rescue + callbacks + end +end + +# This will produce a compound array of simple diff change objects. Each +# element in the #diffs array is a +hunk+ or +hunk+ array, where each +# element in each +hunk+ array is a single Change object representing the +# addition or removal of a single element from one of the two tested +# sequences. The +hunk+ provides the full context for the changes. +# +# diffs = Diff::LCS.diff(seq1, seq2) +# # This example shows a simplified array format. +# # [ [ [ '-', 0, 'a' ] ], # 1 +# # [ [ '+', 2, 'd' ] ], # 2 +# # [ [ '-', 4, 'h' ], # 3 +# # [ '+', 4, 'f' ] ], +# # [ [ '+', 6, 'k' ] ], # 4 +# # [ [ '-', 8, 'n' ], # 5 +# # [ '-', 9, 'p' ], +# # [ '+', 9, 'r' ], +# # [ '+', 10, 's' ], +# # [ '+', 11, 't' ] ] ] +# +# There are five hunks here. The first hunk says that the +a+ at position 0 +# of the first sequence should be deleted ('-'). The second hunk +# says that the +d+ at position 2 of the second sequence should be inserted +# ('+'). The third hunk says that the +h+ at position 4 of the +# first sequence should be removed and replaced with the +f+ from position 4 +# of the second sequence. The other two hunks are described similarly. +# +# === Use +# +# This callback object must be initialised and is used by the Diff::LCS#diff +# method. +# +# cbo = Diff::LCS::DiffCallbacks.new +# Diff::LCS.LCS(seq1, seq2, cbo) +# cbo.finish +# +# Note that the call to #finish is absolutely necessary, or the last set of +# changes will not be visible. Alternatively, can be used as: +# +# cbo = Diff::LCS::DiffCallbacks.new { |tcbo| Diff::LCS.LCS(seq1, seq2, tcbo) } +# +# The necessary #finish call will be made. +# +# === Simplified Array Format +# +# The simplified array format used in the example above can be obtained +# with: +# +# require 'pp' +# pp diffs.map { |e| e.map { |f| f.to_a } } +class Diff::LCS::DiffCallbacks + # Returns the difference set collected during the diff process. + attr_reader :diffs + + def initialize # :yields: self + @hunk = [] + @diffs = [] + + return unless block_given? + + begin + yield self + ensure + finish + end + end + + # Finalizes the diff process. If an unprocessed hunk still exists, then it + # is appended to the diff list. + def finish + finish_hunk + end + + def match(_event) + finish_hunk + end + + def discard_a(event) + @hunk << Diff::LCS::Change.new("-", event.old_position, event.old_element) + end + + def discard_b(event) + @hunk << Diff::LCS::Change.new("+", event.new_position, event.new_element) + end + + def finish_hunk + @diffs << @hunk unless @hunk.empty? + @hunk = [] + end + private :finish_hunk +end + +# This will produce a compound array of contextual diff change objects. Each +# element in the #diffs array is a "hunk" array, where each element in each +# "hunk" array is a single change. Each change is a Diff::LCS::ContextChange +# that contains both the old index and new index values for the change. The +# "hunk" provides the full context for the changes. Both old and new objects +# will be presented for changed objects. +nil+ will be substituted for a +# discarded object. +# +# seq1 = %w(a b c e h j l m n p) +# seq2 = %w(b c d e f j k l m r s t) +# +# diffs = Diff::LCS.diff(seq1, seq2, Diff::LCS::ContextDiffCallbacks) +# # This example shows a simplified array format. +# # [ [ [ '-', [ 0, 'a' ], [ 0, nil ] ] ], # 1 +# # [ [ '+', [ 3, nil ], [ 2, 'd' ] ] ], # 2 +# # [ [ '-', [ 4, 'h' ], [ 4, nil ] ], # 3 +# # [ '+', [ 5, nil ], [ 4, 'f' ] ] ], +# # [ [ '+', [ 6, nil ], [ 6, 'k' ] ] ], # 4 +# # [ [ '-', [ 8, 'n' ], [ 9, nil ] ], # 5 +# # [ '+', [ 9, nil ], [ 9, 'r' ] ], +# # [ '-', [ 9, 'p' ], [ 10, nil ] ], +# # [ '+', [ 10, nil ], [ 10, 's' ] ], +# # [ '+', [ 10, nil ], [ 11, 't' ] ] ] ] +# +# The five hunks shown are comprised of individual changes; if there is a +# related set of changes, they are still shown individually. +# +# This callback can also be used with Diff::LCS#sdiff, which will produce +# results like: +# +# diffs = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextCallbacks) +# # This example shows a simplified array format. +# # [ [ [ "-", [ 0, "a" ], [ 0, nil ] ] ], # 1 +# # [ [ "+", [ 3, nil ], [ 2, "d" ] ] ], # 2 +# # [ [ "!", [ 4, "h" ], [ 4, "f" ] ] ], # 3 +# # [ [ "+", [ 6, nil ], [ 6, "k" ] ] ], # 4 +# # [ [ "!", [ 8, "n" ], [ 9, "r" ] ], # 5 +# # [ "!", [ 9, "p" ], [ 10, "s" ] ], +# # [ "+", [ 10, nil ], [ 11, "t" ] ] ] ] +# +# The five hunks are still present, but are significantly shorter in total +# presentation, because changed items are shown as changes ("!") instead of +# potentially "mismatched" pairs of additions and deletions. +# +# The result of this operation is similar to that of +# Diff::LCS::SDiffCallbacks. They may be compared as: +# +# s = Diff::LCS.sdiff(seq1, seq2).reject { |e| e.action == "=" } +# c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten(1) +# +# s == c # -> true +# +# === Use +# +# This callback object must be initialised and can be used by the +# Diff::LCS#diff or Diff::LCS#sdiff methods. +# +# cbo = Diff::LCS::ContextDiffCallbacks.new +# Diff::LCS.LCS(seq1, seq2, cbo) +# cbo.finish +# +# Note that the call to #finish is absolutely necessary, or the last set of +# changes will not be visible. Alternatively, can be used as: +# +# cbo = Diff::LCS::ContextDiffCallbacks.new { |tcbo| Diff::LCS.LCS(seq1, seq2, tcbo) } +# +# The necessary #finish call will be made. +# +# === Simplified Array Format +# +# The simplified array format used in the example above can be obtained +# with: +# +# require 'pp' +# pp diffs.map { |e| e.map { |f| f.to_a } } +class Diff::LCS::ContextDiffCallbacks < Diff::LCS::DiffCallbacks + def discard_a(event) + @hunk << Diff::LCS::ContextChange.simplify(event) + end + + def discard_b(event) + @hunk << Diff::LCS::ContextChange.simplify(event) + end + + def change(event) + @hunk << Diff::LCS::ContextChange.simplify(event) + end +end + +# This will produce a simple array of diff change objects. Each element in +# the #diffs array is a single ContextChange. In the set of #diffs provided +# by SDiffCallbacks, both old and new objects will be presented for both +# changed and unchanged objects. +nil+ will be substituted +# for a discarded object. +# +# The diffset produced by this callback, when provided to Diff::LCS#sdiff, +# will compute and display the necessary components to show two sequences +# and their minimized differences side by side, just like the Unix utility +# +sdiff+. +# +# same same +# before | after +# old < - +# - > new +# +# seq1 = %w(a b c e h j l m n p) +# seq2 = %w(b c d e f j k l m r s t) +# +# diffs = Diff::LCS.sdiff(seq1, seq2) +# # This example shows a simplified array format. +# # [ [ "-", [ 0, "a"], [ 0, nil ] ], +# # [ "=", [ 1, "b"], [ 0, "b" ] ], +# # [ "=", [ 2, "c"], [ 1, "c" ] ], +# # [ "+", [ 3, nil], [ 2, "d" ] ], +# # [ "=", [ 3, "e"], [ 3, "e" ] ], +# # [ "!", [ 4, "h"], [ 4, "f" ] ], +# # [ "=", [ 5, "j"], [ 5, "j" ] ], +# # [ "+", [ 6, nil], [ 6, "k" ] ], +# # [ "=", [ 6, "l"], [ 7, "l" ] ], +# # [ "=", [ 7, "m"], [ 8, "m" ] ], +# # [ "!", [ 8, "n"], [ 9, "r" ] ], +# # [ "!", [ 9, "p"], [ 10, "s" ] ], +# # [ "+", [ 10, nil], [ 11, "t" ] ] ] +# +# The result of this operation is similar to that of +# Diff::LCS::ContextDiffCallbacks. They may be compared as: +# +# s = Diff::LCS.sdiff(seq1, seq2).reject { |e| e.action == "=" } +# c = Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks).flatten(1) +# +# s == c # -> true +# +# === Use +# +# This callback object must be initialised and is used by the Diff::LCS#sdiff +# method. +# +# cbo = Diff::LCS::SDiffCallbacks.new +# Diff::LCS.LCS(seq1, seq2, cbo) +# +# As with the other initialisable callback objects, +# Diff::LCS::SDiffCallbacks can be initialised with a block. As there is no +# "fininishing" to be done, this has no effect on the state of the object. +# +# cbo = Diff::LCS::SDiffCallbacks.new { |tcbo| Diff::LCS.LCS(seq1, seq2, tcbo) } +# +# === Simplified Array Format +# +# The simplified array format used in the example above can be obtained +# with: +# +# require 'pp' +# pp diffs.map { |e| e.to_a } +class Diff::LCS::SDiffCallbacks + # Returns the difference set collected during the diff process. + attr_reader :diffs + + def initialize # :yields: self + @diffs = [] + yield self if block_given? + end + + def match(event) + @diffs << Diff::LCS::ContextChange.simplify(event) + end + + def discard_a(event) + @diffs << Diff::LCS::ContextChange.simplify(event) + end + + def discard_b(event) + @diffs << Diff::LCS::ContextChange.simplify(event) + end + + def change(event) + @diffs << Diff::LCS::ContextChange.simplify(event) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/change.rb b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/change.rb new file mode 100644 index 00000000..714d78c8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/change.rb @@ -0,0 +1,174 @@ +# frozen_string_literal: true + +# Represents a simplistic (non-contextual) change. Represents the removal or +# addition of an element from either the old or the new sequenced +# enumerable. +class Diff::LCS::Change + IntClass = 1.class # Fixnum is deprecated in Ruby 2.4 # standard:disable Naming/ConstantName + + # The only actions valid for changes are '+' (add), '-' (delete), '=' + # (no change), '!' (changed), '<' (tail changes from first sequence), or + # '>' (tail changes from second sequence). The last two ('<>') are only + # found with Diff::LCS::diff and Diff::LCS::sdiff. + VALID_ACTIONS = %w[+ - = ! > <].freeze + + def self.valid_action?(action) + VALID_ACTIONS.include? action + end + + # Returns the action this Change represents. + attr_reader :action + + # Returns the position of the Change. + attr_reader :position + # Returns the sequence element of the Change. + attr_reader :element + + def initialize(*args) + @action, @position, @element = *args + + fail "Invalid Change Action '#{@action}'" unless Diff::LCS::Change.valid_action?(@action) + fail "Invalid Position Type" unless @position.is_a? IntClass + end + + def inspect(*_args) + "#<#{self.class}: #{to_a.inspect}>" + end + + def to_a + [@action, @position, @element] + end + + alias_method :to_ary, :to_a + + def self.from_a(arr) + arr = arr.flatten(1) + case arr.size + when 5 + Diff::LCS::ContextChange.new(*arr[0...5]) + when 3 + Diff::LCS::Change.new(*arr[0...3]) + else + fail "Invalid change array format provided." + end + end + + include Comparable + + def ==(other) + (self.class == other.class) and + (action == other.action) and + (position == other.position) and + (element == other.element) + end + + def <=>(other) + r = action <=> other.action + r = position <=> other.position if r.zero? + r = element <=> other.element if r.zero? + r + end + + def adding? + @action == "+" + end + + def deleting? + @action == "-" + end + + def unchanged? + @action == "=" + end + + def changed? + @action == "!" + end + + def finished_a? + @action == ">" + end + + def finished_b? + @action == "<" + end +end + +# Represents a contextual change. Contains the position and values of the +# elements in the old and the new sequenced enumerables as well as the action +# taken. +class Diff::LCS::ContextChange < Diff::LCS::Change + # We don't need these two values. + undef :position + undef :element + + # Returns the old position being changed. + attr_reader :old_position + # Returns the new position being changed. + attr_reader :new_position + # Returns the old element being changed. + attr_reader :old_element + # Returns the new element being changed. + attr_reader :new_element + + def initialize(*args) + @action, @old_position, @old_element, @new_position, @new_element = *args + + fail "Invalid Change Action '#{@action}'" unless Diff::LCS::Change.valid_action?(@action) + fail "Invalid (Old) Position Type" unless @old_position.nil? || @old_position.is_a?(IntClass) + fail "Invalid (New) Position Type" unless @new_position.nil? || @new_position.is_a?(IntClass) + end + + def to_a + [ + @action, + [@old_position, @old_element], + [@new_position, @new_element] + ] + end + + alias_method :to_ary, :to_a + + def self.from_a(arr) + Diff::LCS::Change.from_a(arr) + end + + # Simplifies a context change for use in some diff callbacks. '<' actions + # are converted to '-' and '>' actions are converted to '+'. + def self.simplify(event) + ea = event.to_a + + case ea[0] + when "-" + ea[2][1] = nil + when "<" + ea[0] = "-" + ea[2][1] = nil + when "+" + ea[1][1] = nil + when ">" + ea[0] = "+" + ea[1][1] = nil + end + + Diff::LCS::ContextChange.from_a(ea) + end + + def ==(other) + (self.class == other.class) and + (@action == other.action) and + (@old_position == other.old_position) and + (@new_position == other.new_position) and + (@old_element == other.old_element) and + (@new_element == other.new_element) + end + + def <=>(other) + r = @action <=> other.action + r = @old_position <=> other.old_position if r.zero? + r = @new_position <=> other.new_position if r.zero? + r = @old_element <=> other.old_element if r.zero? + r = @new_element <=> other.new_element if r.zero? + r + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/htmldiff.rb b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/htmldiff.rb new file mode 100644 index 00000000..90732438 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/htmldiff.rb @@ -0,0 +1,160 @@ +# frozen_string_literal: true + +require "erb" + +# Produce a simple HTML diff view. +class Diff::LCS::HTMLDiff + class << self + # standard:disable ThreadSafety/ClassAndModuleAttributes + attr_accessor :can_expand_tabs # :nodoc: + # standard:enable ThreadSafety/ClassAndModuleAttributes + end + self.can_expand_tabs = true + + class Callbacks # :nodoc: + attr_accessor :output + attr_accessor :match_class + attr_accessor :only_a_class + attr_accessor :only_b_class + + def initialize(output, options = {}) + @output = output + options ||= {} + + @match_class = options[:match_class] || "match" + @only_a_class = options[:only_a_class] || "only_a" + @only_b_class = options[:only_b_class] || "only_b" + end + + def htmlize(element, css_class) + element = " " if element.empty? + %(
#{element}
\n) + end + private :htmlize + + # This will be called with both lines are the same + def match(event) + @output << htmlize(event.old_element, :match_class) + end + + # This will be called when there is a line in A that isn't in B + def discard_a(event) + @output << htmlize(event.old_element, :only_a_class) + end + + # This will be called when there is a line in B that isn't in A + def discard_b(event) + @output << htmlize(event.new_element, :only_b_class) + end + end + + # standard:disable Style/HashSyntax + DEFAULT_OPTIONS = { + :expand_tabs => nil, + :output => nil, + :css => nil, + :title => nil + }.freeze + # standard:enable Style/HashSyntax + + # standard:disable Layout/HeredocIndentation + DEFAULT_CSS = <<-CSS +body { margin: 0; } +.diff +{ + border: 1px solid black; + margin: 1em 2em; +} +p +{ + margin-left: 2em; +} +pre +{ + padding-left: 1em; + margin: 0; + font-family: Inconsolata, Consolas, Lucida, Courier, monospaced; + white-space: pre; +} +.match { } +.only_a +{ + background-color: #fdd; + color: red; + text-decoration: line-through; +} +.only_b +{ + background-color: #ddf; + color: blue; + border-left: 3px solid blue +} +h1 { margin-left: 2em; } + CSS + # standard:enable Layout/HeredocIndentation + + def initialize(left, right, options = nil) + @left = left + @right = right + @options = options + + @options = DEFAULT_OPTIONS.dup if @options.nil? + end + + def verify_options + @options[:expand_tabs] ||= 4 + @options[:expand_tabs] = 4 if @options[:expand_tabs].negative? + + @options[:output] ||= $stdout + + @options[:css] ||= DEFAULT_CSS.dup + + @options[:title] ||= "diff" + end + private :verify_options + + attr_reader :options + + def run + verify_options + + if @options[:expand_tabs].positive? && self.class.can_expand_tabs + formatter = Text::Format.new + formatter.tabstop = @options[:expand_tabs] + + @left.map! { |line| formatter.expand(line.chomp) } + @right.map! { |line| formatter.expand(line.chomp) } + end + + @left.map! { |line| ERB::Util.html_escape(line.chomp) } + @right.map! { |line| ERB::Util.html_escape(line.chomp) } + + # standard:disable Layout/HeredocIndentation + @options[:output] << <<-OUTPUT + + + #{@options[:title]} + + + +

#{@options[:title]}

+

Legend: Only in Old  + Only in New

+
+ OUTPUT + # standard:enable Layout/HeredocIndentation + + callbacks = Callbacks.new(@options[:output]) + Diff::LCS.traverse_sequences(@left, @right, callbacks) + + # standard:disable Layout/HeredocIndentation + @options[:output] << <<-OUTPUT +
+ + + OUTPUT + # standard:enable Layout/HeredocIndentation + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/hunk.rb b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/hunk.rb new file mode 100644 index 00000000..24b33bca --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/hunk.rb @@ -0,0 +1,379 @@ +# frozen_string_literal: true + +require "diff/lcs/block" + +# A Hunk is a group of Blocks which overlap because of the context surrounding +# each block. (So if we're not using context, every hunk will contain one +# block.) Used in the diff program (bin/ldiff). +class Diff::LCS::Hunk + OLD_DIFF_OP_ACTION = {"+" => "a", "-" => "d", "!" => "c"}.freeze # :nodoc: + ED_DIFF_OP_ACTION = {"+" => "a", "-" => "d", "!" => "c"}.freeze # :nodoc: + + private_constant :OLD_DIFF_OP_ACTION, :ED_DIFF_OP_ACTION if respond_to?(:private_constant) + + # Create a hunk using references to both the old and new data, as well as the + # piece of data. + def initialize(data_old, data_new, piece, flag_context, file_length_difference) + # At first, a hunk will have just one Block in it + @blocks = [Diff::LCS::Block.new(piece)] + + if @blocks[0].remove.empty? && @blocks[0].insert.empty? + fail "Cannot build a hunk from #{piece.inspect}; has no add or remove actions" + end + + if String.method_defined?(:encoding) + @preferred_data_encoding = data_old.fetch(0) { data_new.fetch(0) { "" } }.encoding + end + + @data_old = data_old + @data_new = data_new + @old_empty = data_old.empty? || (data_old.size == 1 && data_old[0].empty?) + @new_empty = data_new.empty? || (data_new.size == 1 && data_new[0].empty?) + + before = after = file_length_difference + after += @blocks[0].diff_size + @file_length_difference = after # The caller must get this manually + @max_diff_size = @blocks.map { |e| e.diff_size.abs }.max + + # Save the start & end of each array. If the array doesn't exist (e.g., + # we're only adding items in this block), then figure out the line number + # based on the line number of the other file and the current difference in + # file lengths. + if @blocks[0].remove.empty? + a1 = a2 = nil + else + a1 = @blocks[0].remove[0].position + a2 = @blocks[0].remove[-1].position + end + + if @blocks[0].insert.empty? + b1 = b2 = nil + else + b1 = @blocks[0].insert[0].position + b2 = @blocks[0].insert[-1].position + end + + @start_old = a1 || (b1 - before) + @start_new = b1 || (a1 + before) + @end_old = a2 || (b2 - after) + @end_new = b2 || (a2 + after) + + self.flag_context = flag_context + end + + attr_reader :blocks + attr_reader :start_old, :start_new + attr_reader :end_old, :end_new + attr_reader :file_length_difference + + # Change the "start" and "end" fields to note that context should be added + # to this hunk. + attr_accessor :flag_context + undef :flag_context= + def flag_context=(context) # :nodoc: # standard:disable Lint/DuplicateMethods + return if context.nil? || context.zero? + + add_start = (context > @start_old) ? @start_old : context + + @start_old -= add_start + @start_new -= add_start + + old_size = @data_old.size + + add_end = + if (@end_old + context) >= old_size + old_size - @end_old - 1 + else + context + end + + @end_old += add_end + @end_new += add_end + end + + # Merges this hunk and the provided hunk together if they overlap. Returns + # a truthy value so that if there is no overlap, you can know the merge + # was skipped. + def merge(hunk) + return unless overlaps?(hunk) + + @start_old = hunk.start_old + @start_new = hunk.start_new + blocks.unshift(*hunk.blocks) + end + alias_method :unshift, :merge + + # Determines whether there is an overlap between this hunk and the + # provided hunk. This will be true if the difference between the two hunks + # start or end positions is within one position of each other. + def overlaps?(hunk) + hunk and (((@start_old - hunk.end_old) <= 1) or + ((@start_new - hunk.end_new) <= 1)) + end + + # Returns a diff string based on a format. + def diff(format, last = false) + case format + when :old + old_diff(last) + when :unified + unified_diff(last) + when :context + context_diff(last) + when :ed + self + when :reverse_ed, :ed_finish + ed_diff(format, last) + else + fail "Unknown diff format #{format}." + end + end + + # Note that an old diff can't have any context. Therefore, we know that + # there's only one block in the hunk. + def old_diff(last = false) + warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1 + + block = @blocks[0] + + if last + old_missing_newline = !@old_empty && missing_last_newline?(@data_old) + new_missing_newline = !@new_empty && missing_last_newline?(@data_new) + end + + # Calculate item number range. Old diff range is just like a context + # diff range, except the ranges are on one line with the action between + # them. + s = encode("#{context_range(:old, ",")}#{OLD_DIFF_OP_ACTION[block.op]}#{context_range(:new, ",")}\n") + # If removing anything, just print out all the remove lines in the hunk + # which is just all the remove lines in the block. + unless block.remove.empty? + @data_old[@start_old..@end_old].each { |e| s << encode("< ") + e.chomp + encode("\n") } + end + + s << encode("\\ No newline at end of file\n") if old_missing_newline && !new_missing_newline + s << encode("---\n") if block.op == "!" + + unless block.insert.empty? + @data_new[@start_new..@end_new].each { |e| s << encode("> ") + e.chomp + encode("\n") } + end + + s << encode("\\ No newline at end of file\n") if new_missing_newline && !old_missing_newline + + s + end + private :old_diff + + def unified_diff(last = false) + # Calculate item number range. + s = encode("@@ -#{unified_range(:old)} +#{unified_range(:new)} @@\n") + + # Outlist starts containing the hunk of the old file. Removing an item + # just means putting a '-' in front of it. Inserting an item requires + # getting it from the new file and splicing it in. We splice in + # +num_added+ items. Remove blocks use +num_added+ because splicing + # changed the length of outlist. + # + # We remove +num_removed+ items. Insert blocks use +num_removed+ + # because their item numbers -- corresponding to positions in the NEW + # file -- don't take removed items into account. + lo, hi, num_added, num_removed = @start_old, @end_old, 0, 0 + + # standard:disable Performance/UnfreezeString + outlist = @data_old[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") } + # standard:enable Performance/UnfreezeString + + last_block = blocks[-1] + + if last + old_missing_newline = !@old_empty && missing_last_newline?(@data_old) + new_missing_newline = !@new_empty && missing_last_newline?(@data_new) + end + + @blocks.each do |block| + block.remove.each do |item| + op = item.action.to_s # - + offset = item.position - lo + num_added + outlist[offset][0, 1] = encode(op) + num_removed += 1 + end + + if last && block == last_block && old_missing_newline && !new_missing_newline + outlist << encode('\\ No newline at end of file') + num_removed += 1 + end + + block.insert.each do |item| + op = item.action.to_s # + + offset = item.position - @start_new + num_removed + outlist[offset, 0] = encode(op) + @data_new[item.position].chomp + num_added += 1 + end + end + + outlist << encode('\\ No newline at end of file') if last && new_missing_newline + + s << outlist.join(encode("\n")) + + s + end + private :unified_diff + + def context_diff(last = false) + s = encode("***************\n") + s << encode("*** #{context_range(:old, ",")} ****\n") + r = context_range(:new, ",") + + if last + old_missing_newline = missing_last_newline?(@data_old) + new_missing_newline = missing_last_newline?(@data_new) + end + + # Print out file 1 part for each block in context diff format if there + # are any blocks that remove items + lo, hi = @start_old, @end_old + removes = @blocks.reject { |e| e.remove.empty? } + + unless removes.empty? + # standard:disable Performance/UnfreezeString + outlist = @data_old[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") } + # standard:enable Performance/UnfreezeString + + last_block = removes[-1] + + removes.each do |block| + block.remove.each do |item| + outlist[item.position - lo][0, 1] = encode(block.op) # - or ! + end + + if last && block == last_block && old_missing_newline + outlist << encode('\\ No newline at end of file') + end + end + + s << outlist.join(encode("\n")) << encode("\n") + end + + s << encode("--- #{r} ----\n") + lo, hi = @start_new, @end_new + inserts = @blocks.reject { |e| e.insert.empty? } + + unless inserts.empty? + # standard:disable Performance/UnfreezeString + outlist = @data_new[lo..hi].map { |e| String.new("#{encode(" ")}#{e.chomp}") } + # standard:enable Performance/UnfreezeString + + last_block = inserts[-1] + + inserts.each do |block| + block.insert.each do |item| + outlist[item.position - lo][0, 1] = encode(block.op) # + or ! + end + + if last && block == last_block && new_missing_newline + outlist << encode('\\ No newline at end of file') + end + end + s << outlist.join(encode("\n")) + end + + s + end + private :context_diff + + def ed_diff(format, last) + warn "Expecting only one block in an old diff hunk!" if @blocks.size > 1 + if last + # ed script doesn't support well incomplete lines + warn ": No newline at end of file\n" if !@old_empty && missing_last_newline?(@data_old) + warn ": No newline at end of file\n" if !@new_empty && missing_last_newline?(@data_new) + + if @blocks[0].op == "!" + return +"" if @blocks[0].changes[0].element == @blocks[0].changes[1].element + "\n" + return +"" if @blocks[0].changes[0].element + "\n" == @blocks[0].changes[1].element + end + end + + s = + if format == :reverse_ed + encode("#{ED_DIFF_OP_ACTION[@blocks[0].op]}#{context_range(:old, " ")}\n") + else + encode("#{context_range(:old, ",")}#{ED_DIFF_OP_ACTION[@blocks[0].op]}\n") + end + + unless @blocks[0].insert.empty? + @data_new[@start_new..@end_new].each do |e| + s << e.chomp + encode("\n") + end + s << encode(".\n") + end + s + end + private :ed_diff + + # Generate a range of item numbers to print. Only print 1 number if the + # range has only one item in it. Otherwise, it's 'start,end' + def context_range(mode, op) + case mode + when :old + s, e = (@start_old + 1), (@end_old + 1) + when :new + s, e = (@start_new + 1), (@end_new + 1) + end + + (s < e) ? "#{s}#{op}#{e}" : e.to_s + end + private :context_range + + # Generate a range of item numbers to print for unified diff. Print number + # where block starts, followed by number of lines in the block + # (don't print number of lines if it's 1) + def unified_range(mode) + case mode + when :old + return "0,0" if @old_empty + s, e = (@start_old + 1), (@end_old + 1) + when :new + return "0,0" if @new_empty + s, e = (@start_new + 1), (@end_new + 1) + end + + length = e - s + 1 + + (length <= 1) ? e.to_s : "#{s},#{length}" + end + private :unified_range + + def missing_last_newline?(data) + newline = encode("\n") + + if data[-2] + data[-2].end_with?(newline) && !data[-1].end_with?(newline) + elsif data[-1] + !data[-1].end_with?(newline) + else + true + end + end + + if String.method_defined?(:encoding) + def encode(literal, target_encoding = @preferred_data_encoding) + literal.encode target_encoding + end + + def encode_as(string, *args) + args.map { |arg| arg.encode(string.encoding) } + end + else + def encode(literal, _target_encoding = nil) + literal + end + + def encode_as(_string, *args) + args + end + end + + private :encode + private :encode_as +end diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/internals.rb b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/internals.rb new file mode 100644 index 00000000..8a9160a6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/internals.rb @@ -0,0 +1,308 @@ +# frozen_string_literal: true + +class << Diff::LCS + def diff_traversal(method, seq1, seq2, callbacks, &block) + callbacks = callbacks_for(callbacks) + case method + when :diff + traverse_sequences(seq1, seq2, callbacks) + when :sdiff + traverse_balanced(seq1, seq2, callbacks) + end + callbacks.finish if callbacks.respond_to? :finish + + if block + callbacks.diffs.map do |hunk| + if hunk.is_a? Array + hunk.map { |hunk_block| block[hunk_block] } + else + block[hunk] + end + end + else + callbacks.diffs + end + end + private :diff_traversal +end + +module Diff::LCS::Internals # :nodoc: +end + +class << Diff::LCS::Internals + # Compute the longest common subsequence between the sequenced + # Enumerables +a+ and +b+. The result is an array whose contents is such + # that + # + # result = Diff::LCS::Internals.lcs(a, b) + # result.each_with_index do |e, i| + # assert_equal(a[i], b[e]) unless e.nil? + # end + def lcs(a, b) + a_start = b_start = 0 + a_finish = a.size - 1 + b_finish = b.size - 1 + vector = [] + + # Collect any common elements at the beginning... + while (a_start <= a_finish) && (b_start <= b_finish) && (a[a_start] == b[b_start]) + vector[a_start] = b_start + a_start += 1 + b_start += 1 + end + + # Now the end... + while (a_start <= a_finish) && (b_start <= b_finish) && (a[a_finish] == b[b_finish]) + vector[a_finish] = b_finish + a_finish -= 1 + b_finish -= 1 + end + + # Now, compute the equivalence classes of positions of elements. + # An explanation for how this works: https://codeforces.com/topic/92191 + b_matches = position_hash(b, b_start..b_finish) + + thresh = [] + links = [] + string = a.is_a?(String) + + (a_start..a_finish).each do |i| + ai = string ? a[i, 1] : a[i] + bm = b_matches[ai] + k = nil + bm.reverse_each do |j| + # Although the threshold check is not mandatory for this to work, + # it may have an optimization purpose + # An attempt to remove it: https://github.com/halostatue/diff-lcs/pull/72 + # Why it is reintroduced: https://github.com/halostatue/diff-lcs/issues/78 + if k && (thresh[k] > j) && (thresh[k - 1] < j) + thresh[k] = j + else + k = replace_next_larger(thresh, j, k) + end + links[k] = [k.positive? ? links[k - 1] : nil, i, j] unless k.nil? + end + end + + unless thresh.empty? + link = links[thresh.size - 1] + until link.nil? + vector[link[1]] = link[2] + link = link[0] + end + end + + vector + end + + # This method will analyze the provided patchset to provide a single-pass + # normalization (conversion of the array form of Diff::LCS::Change objects to + # the object form of same) and detection of whether the patchset represents + # changes to be made. + def analyze_patchset(patchset, depth = 0) + fail "Patchset too complex" if depth > 1 + + has_changes = false + new_patchset = [] + + # Format: + # [ # patchset + # # hunk (change) + # [ # hunk + # # change + # ] + # ] + + patchset.each do |hunk| + case hunk + when Diff::LCS::Change + has_changes ||= !hunk.unchanged? + new_patchset << hunk + when Array + # Detect if the 'hunk' is actually an array-format change object. + if Diff::LCS::Change.valid_action? hunk[0] + hunk = Diff::LCS::Change.from_a(hunk) + has_changes ||= !hunk.unchanged? + new_patchset << hunk + else + with_changes, hunk = analyze_patchset(hunk, depth + 1) + has_changes ||= with_changes + new_patchset.concat(hunk) + end + else + fail ArgumentError, "Cannot normalise a hunk of class #{hunk.class}." + end + end + + [has_changes, new_patchset] + end + + # Examine the patchset and the source to see in which direction the + # patch should be applied. + # + # WARNING: By default, this examines the whole patch, so this could take + # some time. This also works better with Diff::LCS::ContextChange or + # Diff::LCS::Change as its source, as an array will cause the creation + # of one of the above. + def intuit_diff_direction(src, patchset, limit = nil) + string = src.is_a?(String) + count = left_match = left_miss = right_match = right_miss = 0 + + patchset.each do |change| + count += 1 + + case change + when Diff::LCS::ContextChange + le = string ? src[change.old_position, 1] : src[change.old_position] + re = string ? src[change.new_position, 1] : src[change.new_position] + + case change.action + when "-" # Remove details from the old string + if le == change.old_element + left_match += 1 + else + left_miss += 1 + end + when "+" + if re == change.new_element + right_match += 1 + else + right_miss += 1 + end + when "=" + left_miss += 1 if le != change.old_element + right_miss += 1 if re != change.new_element + when "!" + if le == change.old_element + left_match += 1 + elsif re == change.new_element + right_match += 1 + else + left_miss += 1 + right_miss += 1 + end + end + when Diff::LCS::Change + # With a simplistic change, we can't tell the difference between + # the left and right on '!' actions, so we ignore those. On '=' + # actions, if there's a miss, we miss both left and right. + element = string ? src[change.position, 1] : src[change.position] + + case change.action + when "-" + if element == change.element + left_match += 1 + else + left_miss += 1 + end + when "+" + if element == change.element + right_match += 1 + else + right_miss += 1 + end + when "=" + if element != change.element + left_miss += 1 + right_miss += 1 + end + end + end + + break if !limit.nil? && (count > limit) + end + + no_left = left_match.zero? && left_miss.positive? + no_right = right_match.zero? && right_miss.positive? + + case [no_left, no_right] + when [false, true] + :patch + when [true, false] + :unpatch + else + case left_match <=> right_match + when 1 + if left_miss.zero? + :patch + else + :unpatch + end + when -1 + if right_miss.zero? + :unpatch + else + :patch + end + else + fail "The provided patchset does not appear to apply to the provided \ +enumerable as either source or destination value." + end + end + end + + # Find the place at which +value+ would normally be inserted into the + # Enumerable. If that place is already occupied by +value+, do nothing + # and return +nil+. If the place does not exist (i.e., it is off the end + # of the Enumerable), add it to the end. Otherwise, replace the element + # at that point with +value+. It is assumed that the Enumerable's values + # are numeric. + # + # This operation preserves the sort order. + def replace_next_larger(enum, value, last_index = nil) + # Off the end? + if enum.empty? || (value > enum[-1]) + enum << value + return enum.size - 1 + end + + # Binary search for the insertion point + last_index ||= enum.size - 1 + first_index = 0 + while first_index <= last_index + i = (first_index + last_index) >> 1 + + found = enum[i] + + return nil if value == found + + if value > found + first_index = i + 1 + else + last_index = i - 1 + end + end + + # The insertion point is in first_index; overwrite the next larger + # value. + enum[first_index] = value + first_index + end + private :replace_next_larger + + # If +vector+ maps the matching elements of another collection onto this + # Enumerable, compute the inverse of +vector+ that maps this Enumerable + # onto the collection. (Currently unused.) + def inverse_vector(a, vector) + inverse = a.dup + (0...vector.size).each do |i| + inverse[vector[i]] = i unless vector[i].nil? + end + inverse + end + private :inverse_vector + + # Returns a hash mapping each element of an Enumerable to the set of + # positions it occupies in the Enumerable, optionally restricted to the + # elements specified in the range of indexes specified by +interval+. + def position_hash(enum, interval) + string = enum.is_a?(String) + hash = Hash.new { |h, k| h[k] = [] } + interval.each do |i| + k = string ? enum[i, 1] : enum[i] + hash[k] << i + end + hash + end + private :position_hash +end diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/ldiff.rb b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/ldiff.rb new file mode 100644 index 00000000..6442c9bf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/ldiff.rb @@ -0,0 +1,189 @@ +# frozen_string_literal: true + +require "optparse" +require "diff/lcs/hunk" + +class Diff::LCS::Ldiff # :nodoc: + # standard:disable Layout/HeredocIndentation + BANNER = <<-COPYRIGHT +ldiff #{Diff::LCS::VERSION} + Copyright 2004-2025 Austin Ziegler + + Part of Diff::LCS. + https://github.com/halostatue/diff-lcs + + This program is free software. It may be redistributed and/or modified under + the terms of the GPL version 2 (or later), the Perl Artistic licence, or the + MIT licence. + COPYRIGHT + # standard:enable Layout/HeredocIndentation + + InputInfo = Struct.new(:filename, :data, :stat) do + def initialize(filename) + super(filename, ::File.read(filename), ::File.stat(filename)) + end + end + + attr_reader :format, :lines # :nodoc: + attr_reader :file_old, :file_new # :nodoc: + attr_reader :data_old, :data_new # :nodoc: + + def self.run(args, input = $stdin, output = $stdout, error = $stderr) # :nodoc: + new.run(args, input, output, error) + end + + def initialize + @binary = nil + @format = :old + @lines = 0 + end + + def run(args, _input = $stdin, output = $stdout, error = $stderr) # :nodoc: + args.options do |o| + o.banner = "Usage: #{File.basename($0)} [options] oldfile newfile" + o.separator "" + o.on( + "-c", "-C", "--context [LINES]", Integer, + "Displays a context diff with LINES lines", "of context. Default 3 lines." + ) do |ctx| + @format = :context + @lines = ctx || 3 + end + o.on( + "-u", "-U", "--unified [LINES]", Integer, + "Displays a unified diff with LINES lines", "of context. Default 3 lines." + ) do |ctx| + @format = :unified + @lines = ctx || 3 + end + o.on("-e", "Creates an 'ed' script to change", "oldfile to newfile.") do |_ctx| + @format = :ed + end + o.on("-f", "Creates an 'ed' script to change", "oldfile to newfile in reverse order.") do |_ctx| + @format = :reverse_ed + end + o.on( + "-a", "--text", + "Treat the files as text and compare them", "line-by-line, even if they do not seem", "to be text." + ) do |_txt| + @binary = false + end + o.on("--binary", "Treats the files as binary.") do |_bin| + @binary = true + end + o.on("-q", "--brief", "Report only whether or not the files", "differ, not the details.") do |_ctx| + @format = :report + end + o.on_tail("--help", "Shows this text.") do + error << o + return 0 + end + o.on_tail("--version", "Shows the version of Diff::LCS.") do + error << Diff::LCS::Ldiff::BANNER + return 0 + end + o.on_tail "" + o.on_tail 'By default, runs produces an "old-style" diff, with output like UNIX diff.' + o.parse! + end + + unless args.size == 2 + error << args.options + return 127 + end + + # Defaults are for old-style diff + @format ||= :old + @lines ||= 0 + + file_old, file_new = *ARGV + diff?( + InputInfo.new(file_old), + InputInfo.new(file_new), + @format, + output, + binary: @binary, + lines: @lines + ) ? 1 : 0 + end + + def diff?(info_old, info_new, format, output, binary: nil, lines: 0) + case format + when :context + char_old = "*" * 3 + char_new = "-" * 3 + when :unified + char_old = "-" * 3 + char_new = "+" * 3 + end + + # After we've read up to a certain point in each file, the number of + # items we've read from each file will differ by FLD (could be 0). + file_length_difference = 0 + + # Test binary status + if binary.nil? + old_bin = info_old.data[0, 4096].include?("\0") + new_bin = info_new.data[0, 4096].include?("\0") + binary = old_bin || new_bin + end + + # diff yields lots of pieces, each of which is basically a Block object + if binary + has_diffs = (info_old.data != info_new.data) + if format != :report + if has_diffs + output << "Binary files #{info_old.filename} and #{info_new.filename} differ\n" + return true + end + return false + end + else + data_old = info_old.data.lines.to_a + data_new = info_new.data.lines.to_a + diffs = Diff::LCS.diff(data_old, data_new) + return false if diffs.empty? + end + + case format + when :report + output << "Files #{info_old.filename} and #{info_new.filename} differ\n" + return true + when :unified, :context + ft = info_old.stat.mtime.localtime.strftime("%Y-%m-%d %H:%M:%S.000000000 %z") + output << "#{char_old} #{info_old.filename}\t#{ft}\n" + ft = info_new.stat.mtime.localtime.strftime("%Y-%m-%d %H:%M:%S.000000000 %z") + output << "#{char_new} #{info_new.filename}\t#{ft}\n" + when :ed + real_output = output + output = [] + end + + # Loop over hunks. If a hunk overlaps with the last hunk, join them. + # Otherwise, print out the old one. + oldhunk = hunk = nil + diffs.each do |piece| + begin + hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, lines, file_length_difference) + file_length_difference = hunk.file_length_difference + + next unless oldhunk + next if lines.positive? && hunk.merge(oldhunk) + + output << oldhunk.diff(format) + output << "\n" if format == :unified + ensure + oldhunk = hunk + end + end + + last = oldhunk.diff(format, true) + last << "\n" unless last.is_a?(Diff::LCS::Hunk) || last.empty? || last.end_with?("\n") + + output << last + + output.reverse_each { |e| real_output << e.diff(:ed_finish, e == output[0]) } if format == :ed + + true + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/string.rb b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/string.rb new file mode 100644 index 00000000..9ab32e92 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/string.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class String + include Diff::LCS +end diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/version.rb b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/version.rb new file mode 100644 index 00000000..82830e3c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/lib/diff/lcs/version.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module Diff + module LCS + VERSION = "1.6.2" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/mise.toml b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/mise.toml new file mode 100644 index 00000000..22418cf1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/mise.toml @@ -0,0 +1,5 @@ +[tools] +ruby = "3.4" + +[env] +MAINTENANCE = "true" diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/change_spec.rb b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/change_spec.rb new file mode 100644 index 00000000..42533ae0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/change_spec.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Diff::LCS::Change do + describe "an add" do + subject { described_class.new("+", 0, "element") } + it { should_not be_deleting } + it { should be_adding } + it { should_not be_unchanged } + it { should_not be_changed } + it { should_not be_finished_a } + it { should_not be_finished_b } + end + + describe "a delete" do + subject { described_class.new("-", 0, "element") } + it { should be_deleting } + it { should_not be_adding } + it { should_not be_unchanged } + it { should_not be_changed } + it { should_not be_finished_a } + it { should_not be_finished_b } + end + + describe "an unchanged" do + subject { described_class.new("=", 0, "element") } + it { should_not be_deleting } + it { should_not be_adding } + it { should be_unchanged } + it { should_not be_changed } + it { should_not be_finished_a } + it { should_not be_finished_b } + end + + describe "a changed" do + subject { described_class.new("!", 0, "element") } + it { should_not be_deleting } + it { should_not be_adding } + it { should_not be_unchanged } + it { should be_changed } + it { should_not be_finished_a } + it { should_not be_finished_b } + end + + describe "a finished_a" do + subject { described_class.new(">", 0, "element") } + it { should_not be_deleting } + it { should_not be_adding } + it { should_not be_unchanged } + it { should_not be_changed } + it { should be_finished_a } + it { should_not be_finished_b } + end + + describe "a finished_b" do + subject { described_class.new("<", 0, "element") } + it { should_not be_deleting } + it { should_not be_adding } + it { should_not be_unchanged } + it { should_not be_changed } + it { should_not be_finished_a } + it { should be_finished_b } + end + + describe "as array" do + it "should be converted" do + action, position, element = described_class.new("!", 0, "element") + expect(action).to eq "!" + expect(position).to eq 0 + expect(element).to eq "element" + end + end +end + +describe Diff::LCS::ContextChange do + describe "as array" do + it "should be converted" do + action, (old_position, old_element), (new_position, new_element) = + described_class.new("!", 1, "old_element", 2, "new_element") + + expect(action).to eq "!" + expect(old_position).to eq 1 + expect(old_element).to eq "old_element" + expect(new_position).to eq 2 + expect(new_element).to eq "new_element" + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/diff_spec.rb b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/diff_spec.rb new file mode 100644 index 00000000..869f0986 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/diff_spec.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Diff::LCS, ".diff" do + include Diff::LCS::SpecHelper::Matchers + + it "correctly diffs seq1 to seq2" do + diff_s1_s2 = Diff::LCS.diff(seq1, seq2) + expect(change_diff(correct_forward_diff)).to eq(diff_s1_s2) + end + + it "correctly diffs seq2 to seq1" do + diff_s2_s1 = Diff::LCS.diff(seq2, seq1) + expect(change_diff(correct_backward_diff)).to eq(diff_s2_s1) + end + + it "correctly diffs against an empty sequence" do + diff = Diff::LCS.diff(word_sequence, []) + correct_diff = [ + [ + ["-", 0, "abcd"], + ["-", 1, "efgh"], + ["-", 2, "ijkl"], + ["-", 3, "mnopqrstuvwxyz"] + ] + ] + + expect(change_diff(correct_diff)).to eq(diff) + + diff = Diff::LCS.diff([], word_sequence) + correct_diff.each do |hunk| + hunk.each { |change| change[0] = "+" } + end + expect(change_diff(correct_diff)).to eq(diff) + end + + it "correctly diffs 'xx' and 'xaxb'" do + left = "xx" + right = "xaxb" + expect(Diff::LCS.patch(left, Diff::LCS.diff(left, right))).to eq(right) + end + + it "returns an empty diff with (hello, hello)" do + expect(Diff::LCS.diff(hello, hello)).to be_empty + end + + it "returns an empty diff with (hello_ary, hello_ary)" do + expect(Diff::LCS.diff(hello_ary, hello_ary)).to be_empty + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/123_x b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/123_x new file mode 100644 index 00000000..cd34c235 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/123_x @@ -0,0 +1,2 @@ +123 +x diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/456_x b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/456_x new file mode 100644 index 00000000..9a823ac3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/456_x @@ -0,0 +1,2 @@ +456 +x diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/aX b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/aX new file mode 100644 index 00000000..5765d6a7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/aX @@ -0,0 +1 @@ +aX diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/bXaX b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/bXaX new file mode 100644 index 00000000..a1c813db --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/bXaX @@ -0,0 +1 @@ +bXaX diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ds1.csv b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ds1.csv new file mode 100644 index 00000000..9ac84281 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ds1.csv @@ -0,0 +1,50 @@ +1,3 +2,7 +3,13 +4,21 +5,31 +6,43 +7,57 +8,73 +9,91 +10,111 +11,133 +12,157 +13,183 +14,211 +15,241 +16,273 +17,307 +18,343 +19,381 +20,421 +21,463 +22,507 +23,553 +24,601 +25,651 +26,703 +27,757 +28,813 +29,871 +30,931 +31,993 +32,1057 +33,1123 +34,1191 +35,1261 +36,1333 +37,1407 +38,1483 +39,1561 +40,1641 +41,1723 +42,1807 +43,1893 +44,1981 +45,2071 +46,2163 +47,2257 +48,2353 +49,2451 +50,2500 \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ds2.csv b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ds2.csv new file mode 100644 index 00000000..797de761 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ds2.csv @@ -0,0 +1,51 @@ + 1,3 +2,7 +3,13 +4,21 +5,31 +6,42 +7,57 +8,73 +9,91 +10,111 +11,133 +12,157 +13,183 +14,211 +15,241 +16,273 +17,307 +18,343 +19,200 +20,421 +21,463 +22,507 +23,553 +24,601 +25,651 +26,703 +27,757 +28,813 +29,871 +30,931 +31,123 +32,1057 +33,1123 +34,1000 +35,1261 +36,1333 +37,1407 +38,1483 +39,1561 +40,1641 +41,1723 +42,1807 +43,1893 +44,1981 +45,2071 +46,2163 +47,1524 +48,2353 +49,2451 +50,2500 +51,2520 diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/empty b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/empty new file mode 100644 index 00000000..e69de29b diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/file1.bin b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/file1.bin new file mode 100644 index 00000000..f76dd238 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/file1.bin differ diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/file2.bin b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/file2.bin new file mode 100644 index 00000000..ba18e3dc Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/file2.bin differ diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines new file mode 100644 index 00000000..f384549c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines @@ -0,0 +1,4 @@ +one +two +three +four diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines_with_missing_new_line b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines_with_missing_new_line new file mode 100644 index 00000000..c40a3bdd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/four_lines_with_missing_new_line @@ -0,0 +1,4 @@ +one +two +three +four \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-e b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-e new file mode 100644 index 00000000..1e8a89cd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-e @@ -0,0 +1 @@ +No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-f b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-f new file mode 100644 index 00000000..1e8a89cd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line1-f @@ -0,0 +1 @@ +No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-e b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-e new file mode 100644 index 00000000..1e8a89cd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-e @@ -0,0 +1 @@ +No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-f b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-f new file mode 100644 index 00000000..1e8a89cd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/diff.missing_new_line2-f @@ -0,0 +1 @@ +No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-e b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-e new file mode 100644 index 00000000..8ed03195 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-e @@ -0,0 +1,2 @@ +: No newline at end of file +: No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-f b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-f new file mode 100644 index 00000000..8ed03195 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.chef-f @@ -0,0 +1,2 @@ +: No newline at end of file +: No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-e b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-e new file mode 100644 index 00000000..397dd5b9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-e @@ -0,0 +1 @@ +: No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-f b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-f new file mode 100644 index 00000000..397dd5b9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line1-f @@ -0,0 +1 @@ +: No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-e b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-e new file mode 100644 index 00000000..f9493ef9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-e @@ -0,0 +1 @@ +: No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-f b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-f new file mode 100644 index 00000000..f9493ef9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/error.diff.missing_new_line2-f @@ -0,0 +1 @@ +: No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff new file mode 100644 index 00000000..fa1a3479 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff @@ -0,0 +1,4 @@ +1c1 +< aX +--- +> bXaX diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-c b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-c new file mode 100644 index 00000000..0e1ad998 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-c @@ -0,0 +1,7 @@ +*** spec/fixtures/aX 2020-06-23 11:15:32.000000000 -0400 +--- spec/fixtures/bXaX 2020-06-23 11:15:32.000000000 -0400 +*************** +*** 1 **** +! aX +--- 1 ---- +! bXaX diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-e b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-e new file mode 100644 index 00000000..13e0f7f0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-e @@ -0,0 +1,3 @@ +1c +bXaX +. diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-f b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-f new file mode 100644 index 00000000..77710c76 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-f @@ -0,0 +1,3 @@ +c1 +bXaX +. diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-u b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-u new file mode 100644 index 00000000..b84f7180 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff-u @@ -0,0 +1,5 @@ +--- spec/fixtures/aX 2020-06-23 11:15:32.000000000 -0400 ++++ spec/fixtures/bXaX 2020-06-23 11:15:32.000000000 -0400 +@@ -1 +1 @@ +-aX ++bXaX diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1 b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1 new file mode 100644 index 00000000..e69de29b diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-c b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-c new file mode 100644 index 00000000..e69de29b diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-e b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-e new file mode 100644 index 00000000..e69de29b diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-f b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-f new file mode 100644 index 00000000..e69de29b diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-u b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin1-u new file mode 100644 index 00000000..e69de29b diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2 b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2 new file mode 100644 index 00000000..41b625cd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2 @@ -0,0 +1 @@ +Binary files spec/fixtures/file1.bin and spec/fixtures/file2.bin differ diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-c b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-c new file mode 100644 index 00000000..41b625cd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-c @@ -0,0 +1 @@ +Binary files spec/fixtures/file1.bin and spec/fixtures/file2.bin differ diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-e b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-e new file mode 100644 index 00000000..41b625cd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-e @@ -0,0 +1 @@ +Binary files spec/fixtures/file1.bin and spec/fixtures/file2.bin differ diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-f b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-f new file mode 100644 index 00000000..41b625cd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-f @@ -0,0 +1 @@ +Binary files spec/fixtures/file1.bin and spec/fixtures/file2.bin differ diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-u b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-u new file mode 100644 index 00000000..41b625cd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.bin2-u @@ -0,0 +1 @@ +Binary files spec/fixtures/file1.bin and spec/fixtures/file2.bin differ diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef new file mode 100644 index 00000000..8b98efb1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef @@ -0,0 +1,4 @@ +3c3 +< "description": "hi" +--- +> "description": "lo" diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-c b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-c new file mode 100644 index 00000000..efbfa195 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-c @@ -0,0 +1,15 @@ +*** spec/fixtures/old-chef 2020-06-23 23:18:20.000000000 -0400 +--- spec/fixtures/new-chef 2020-06-23 23:18:20.000000000 -0400 +*************** +*** 1,4 **** + { + "name": "x", +! "description": "hi" + } +\ No newline at end of file +--- 1,4 ---- + { + "name": "x", +! "description": "lo" + } +\ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-e b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-e new file mode 100644 index 00000000..775d881c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-e @@ -0,0 +1,3 @@ +3c + "description": "lo" +. diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-f b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-f new file mode 100644 index 00000000..9bf1e67f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-f @@ -0,0 +1,3 @@ +c3 + "description": "lo" +. diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-u b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-u new file mode 100644 index 00000000..dbacd889 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef-u @@ -0,0 +1,9 @@ +--- spec/fixtures/old-chef 2020-06-23 23:18:20.000000000 -0400 ++++ spec/fixtures/new-chef 2020-06-23 23:18:20.000000000 -0400 +@@ -1,4 +1,4 @@ + { + "name": "x", +- "description": "hi" ++ "description": "lo" + } +\ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2 b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2 new file mode 100644 index 00000000..496b3dc8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2 @@ -0,0 +1,7 @@ +2d1 +< recipe[b::default] +14a14,17 +> recipe[o::new] +> recipe[p::new] +> recipe[q::new] +> recipe[r::new] diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-c b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-c new file mode 100644 index 00000000..8349a7a8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-c @@ -0,0 +1,20 @@ +*** spec/fixtures/old-chef2 2020-06-30 09:43:35.000000000 -0400 +--- spec/fixtures/new-chef2 2020-06-30 09:44:32.000000000 -0400 +*************** +*** 1,5 **** + recipe[a::default] +- recipe[b::default] + recipe[c::default] + recipe[d::default] + recipe[e::default] +--- 1,4 ---- +*************** +*** 12,14 **** +--- 11,17 ---- + recipe[l::default] + recipe[m::default] + recipe[n::default] ++ recipe[o::new] ++ recipe[p::new] ++ recipe[q::new] ++ recipe[r::new] diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-d b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-d new file mode 100644 index 00000000..ca32a490 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-d @@ -0,0 +1,7 @@ +d2 +a14 +recipe[o::new] +recipe[p::new] +recipe[q::new] +recipe[r::new] +. diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-e b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-e new file mode 100644 index 00000000..89f3fa07 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-e @@ -0,0 +1,7 @@ +14a +recipe[o::new] +recipe[p::new] +recipe[q::new] +recipe[r::new] +. +2d diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-f b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-f new file mode 100644 index 00000000..ca32a490 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-f @@ -0,0 +1,7 @@ +d2 +a14 +recipe[o::new] +recipe[p::new] +recipe[q::new] +recipe[r::new] +. diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-u b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-u new file mode 100644 index 00000000..ef025c7e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.chef2-u @@ -0,0 +1,16 @@ +--- spec/fixtures/old-chef2 2020-06-30 09:43:35.000000000 -0400 ++++ spec/fixtures/new-chef2 2020-06-30 09:44:32.000000000 -0400 +@@ -1,5 +1,4 @@ + recipe[a::default] +-recipe[b::default] + recipe[c::default] + recipe[d::default] + recipe[e::default] +@@ -12,3 +11,7 @@ + recipe[l::default] + recipe[m::default] + recipe[n::default] ++recipe[o::new] ++recipe[p::new] ++recipe[q::new] ++recipe[r::new] diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines new file mode 100644 index 00000000..e2afc316 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines @@ -0,0 +1,5 @@ +0a1,4 +> one +> two +> three +> four diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-c b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-c new file mode 100644 index 00000000..be0e8274 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-c @@ -0,0 +1,9 @@ +*** spec/fixtures/empty 2025-01-31 12:14:52.856031635 +0100 +--- spec/fixtures/four_lines 2025-01-31 12:13:45.476036544 +0100 +*************** +*** 0 **** +--- 1,4 ---- ++ one ++ two ++ three ++ four diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-e b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-e new file mode 100644 index 00000000..f8f92feb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-e @@ -0,0 +1,6 @@ +0a +one +two +three +four +. diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-f b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-f new file mode 100644 index 00000000..f02e5a03 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-f @@ -0,0 +1,6 @@ +a0 +one +two +three +four +. diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-u b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-u new file mode 100644 index 00000000..60bd55cc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.empty.vs.four_lines-u @@ -0,0 +1,7 @@ +--- spec/fixtures/empty 2025-01-31 12:14:52.856031635 +0100 ++++ spec/fixtures/four_lines 2025-01-31 12:13:45.476036544 +0100 +@@ -0,0 +1,4 @@ ++one ++two ++three ++four diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty new file mode 100644 index 00000000..67d0a584 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty @@ -0,0 +1,5 @@ +1,4d0 +< one +< two +< three +< four diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-c b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-c new file mode 100644 index 00000000..b216344d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-c @@ -0,0 +1,9 @@ +*** spec/fixtures/four_lines 2025-01-31 12:13:45.476036544 +0100 +--- spec/fixtures/empty 2025-01-31 12:14:52.856031635 +0100 +*************** +*** 1,4 **** +- one +- two +- three +- four +--- 0 ---- diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-e b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-e new file mode 100644 index 00000000..c821d7c9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-e @@ -0,0 +1 @@ +1,4d diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-f b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-f new file mode 100644 index 00000000..442bd5ab --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-f @@ -0,0 +1 @@ +d1 4 diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-u b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-u new file mode 100644 index 00000000..79e6d752 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.four_lines.vs.empty-u @@ -0,0 +1,7 @@ +--- spec/fixtures/four_lines 2025-01-31 12:13:45.476036544 +0100 ++++ spec/fixtures/empty 2025-01-31 12:14:52.856031635 +0100 +@@ -1,4 +0,0 @@ +-one +-two +-three +-four diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context new file mode 100644 index 00000000..4335560d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context @@ -0,0 +1,4 @@ +1c1 +< 123 +--- +> 456 diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-c b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-c new file mode 100644 index 00000000..4b759fa6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-c @@ -0,0 +1,9 @@ +*** spec/fixtures/123_x 2025-01-31 17:00:17.070615716 +0100 +--- spec/fixtures/456_x 2025-01-31 16:58:26.380624827 +0100 +*************** +*** 1,2 **** +! 123 + x +--- 1,2 ---- +! 456 + x diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-e b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-e new file mode 100644 index 00000000..7a8334b3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-e @@ -0,0 +1,3 @@ +1c +456 +. diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-f b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-f new file mode 100644 index 00000000..97223a8c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-f @@ -0,0 +1,3 @@ +c1 +456 +. diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-u b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-u new file mode 100644 index 00000000..7fbf0e2e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.issue95_trailing_context-u @@ -0,0 +1,6 @@ +--- spec/fixtures/123_x 2025-01-31 17:00:17.070615716 +0100 ++++ spec/fixtures/456_x 2025-01-31 16:58:26.380624827 +0100 +@@ -1,2 +1,2 @@ +-123 ++456 + x diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1 b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1 new file mode 100644 index 00000000..c5cb113b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1 @@ -0,0 +1,5 @@ +4c4 +< four +--- +> four +\ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-c b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-c new file mode 100644 index 00000000..55d1ade5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-c @@ -0,0 +1,14 @@ +*** spec/fixtures/four_lines 2025-01-31 12:17:43.926013315 +0100 +--- spec/fixtures/four_lines_with_missing_new_line 2025-01-31 12:17:43.926013315 +0100 +*************** +*** 1,4 **** + one + two + three +! four +--- 1,4 ---- + one + two + three +! four +\ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-e b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-e new file mode 100644 index 00000000..e69de29b diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-f b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-f new file mode 100644 index 00000000..e69de29b diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-u b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-u new file mode 100644 index 00000000..010518bf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line1-u @@ -0,0 +1,9 @@ +--- spec/fixtures/four_lines 2025-01-31 12:17:43.926013315 +0100 ++++ spec/fixtures/four_lines_with_missing_new_line 2025-01-31 12:17:43.926013315 +0100 +@@ -1,4 +1,4 @@ + one + two + three +-four ++four +\ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2 b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2 new file mode 100644 index 00000000..10e43267 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2 @@ -0,0 +1,5 @@ +4c4 +< four +\ No newline at end of file +--- +> four diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-c b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-c new file mode 100644 index 00000000..b4310305 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-c @@ -0,0 +1,14 @@ +*** spec/fixtures/four_lines_with_missing_new_line 2025-01-31 12:17:43.926013315 +0100 +--- spec/fixtures/four_lines 2025-01-31 12:17:43.926013315 +0100 +*************** +*** 1,4 **** + one + two + three +! four +\ No newline at end of file +--- 1,4 ---- + one + two + three +! four diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-e b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-e new file mode 100644 index 00000000..e69de29b diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-f b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-f new file mode 100644 index 00000000..e69de29b diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-u b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-u new file mode 100644 index 00000000..2481a9e0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/ldiff/output.diff.missing_new_line2-u @@ -0,0 +1,9 @@ +--- spec/fixtures/four_lines_with_missing_new_line 2025-01-31 12:17:43.926013315 +0100 ++++ spec/fixtures/four_lines 2025-01-31 12:17:43.926013315 +0100 +@@ -1,4 +1,4 @@ + one + two + three +-four +\ No newline at end of file ++four diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef new file mode 100644 index 00000000..d7babfec --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef @@ -0,0 +1,4 @@ +{ + "name": "x", + "description": "lo" +} \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef2 b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef2 new file mode 100644 index 00000000..8213c73c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/new-chef2 @@ -0,0 +1,17 @@ +recipe[a::default] +recipe[c::default] +recipe[d::default] +recipe[e::default] +recipe[f::default] +recipe[g::default] +recipe[h::default] +recipe[i::default] +recipe[j::default] +recipe[k::default] +recipe[l::default] +recipe[m::default] +recipe[n::default] +recipe[o::new] +recipe[p::new] +recipe[q::new] +recipe[r::new] diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef new file mode 100644 index 00000000..5f9e38b8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef @@ -0,0 +1,4 @@ +{ + "name": "x", + "description": "hi" +} \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef2 b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef2 new file mode 100644 index 00000000..4a23407f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/fixtures/old-chef2 @@ -0,0 +1,14 @@ +recipe[a::default] +recipe[b::default] +recipe[c::default] +recipe[d::default] +recipe[e::default] +recipe[f::default] +recipe[g::default] +recipe[h::default] +recipe[i::default] +recipe[j::default] +recipe[k::default] +recipe[l::default] +recipe[m::default] +recipe[n::default] diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/hunk_spec.rb b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/hunk_spec.rb new file mode 100644 index 00000000..7d910399 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/hunk_spec.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +require "spec_helper" + +if String.method_defined?(:encoding) + require "diff/lcs/hunk" + + describe Diff::LCS::Hunk do + let(:old_data) { ["Tu a un carté avec {count} itéms".encode("UTF-16LE")] } + let(:new_data) { ["Tu a un carte avec {count} items".encode("UTF-16LE")] } + let(:pieces) { Diff::LCS.diff old_data, new_data } + let(:hunk) { Diff::LCS::Hunk.new(old_data, new_data, pieces[0], 3, 0) } + + it "produces a unified diff from the two pieces" do + expected = <<-EXPECTED.gsub(/^\s+/, "").encode("UTF-16LE").chomp + @@ -1 +1 @@ + -Tu a un carté avec {count} itéms + +Tu a un carte avec {count} items + EXPECTED + + expect(hunk.diff(:unified)).to eq(expected) + end + + it "produces a unified diff from the two pieces (last entry)" do + expected = <<-EXPECTED.gsub(/^\s+/, "").encode("UTF-16LE").chomp + @@ -1 +1 @@ + -Tu a un carté avec {count} itéms + +Tu a un carte avec {count} items + \\ No newline at end of file + EXPECTED + + expect(hunk.diff(:unified, true)).to eq(expected) + end + + it "produces a context diff from the two pieces" do + expected = <<-EXPECTED.gsub(/^\s+/, "").encode("UTF-16LE").chomp + *************** + *** 1 **** + ! Tu a un carté avec {count} itéms + --- 1 ---- + ! Tu a un carte avec {count} items + EXPECTED + + expect(hunk.diff(:context)).to eq(expected) + end + + it "produces an old diff from the two pieces" do + expected = <<-EXPECTED.gsub(/^ +/, "").encode("UTF-16LE").chomp + 1c1 + < Tu a un carté avec {count} itéms + --- + > Tu a un carte avec {count} items + + EXPECTED + + expect(hunk.diff(:old)).to eq(expected) + end + + it "produces a reverse ed diff from the two pieces" do + expected = <<-EXPECTED.gsub(/^ +/, "").encode("UTF-16LE").chomp + c1 + Tu a un carte avec {count} items + . + + EXPECTED + + expect(hunk.diff(:reverse_ed)).to eq(expected) + end + + context "with empty first data set" do + let(:old_data) { [] } + + it "produces a unified diff" do + expected = <<-EXPECTED.gsub(/^\s+/, "").encode("UTF-16LE").chomp + @@ -0,0 +1 @@ + +Tu a un carte avec {count} items + EXPECTED + + expect(hunk.diff(:unified)).to eq(expected) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/issues_spec.rb b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/issues_spec.rb new file mode 100644 index 00000000..5b0fb2a1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/issues_spec.rb @@ -0,0 +1,160 @@ +# frozen_string_literal: true + +require "spec_helper" +require "diff/lcs/hunk" + +describe "Diff::LCS Issues" do + include Diff::LCS::SpecHelper::Matchers + + describe "issue #1" do + shared_examples "handles simple diffs" do |s1, s2, forward_diff| + before do + @diff_s1_s2 = Diff::LCS.diff(s1, s2) + end + + it "creates the correct diff" do + expect(change_diff(forward_diff)).to eq(@diff_s1_s2) + end + + it "creates the correct patch s1->s2" do + expect(Diff::LCS.patch(s1, @diff_s1_s2)).to eq(s2) + end + + it "creates the correct patch s2->s1" do + expect(Diff::LCS.patch(s2, @diff_s1_s2)).to eq(s1) + end + end + + describe "string" do + it_has_behavior "handles simple diffs", "aX", "bXaX", [ + [ + ["+", 0, "b"], + ["+", 1, "X"] + ] + ] + it_has_behavior "handles simple diffs", "bXaX", "aX", [ + [ + ["-", 0, "b"], + ["-", 1, "X"] + ] + ] + end + + describe "array" do + it_has_behavior "handles simple diffs", %w[a X], %w[b X a X], [ + [ + ["+", 0, "b"], + ["+", 1, "X"] + ] + ] + it_has_behavior "handles simple diffs", %w[b X a X], %w[a X], [ + [ + ["-", 0, "b"], + ["-", 1, "X"] + ] + ] + end + end + + describe "issue #57" do + it "should fail with a correct error" do + # standard:disable Style/HashSyntax + expect { + actual = {:category => "app.rack.request"} + expected = {:category => "rack.middleware", :title => "Anonymous Middleware"} + expect(actual).to eq(expected) + }.to raise_error(RSpec::Expectations::ExpectationNotMetError) + # standard:enable Style/HashSyntax + end + end + + describe "issue #65" do + def diff_lines(old_lines, new_lines) + file_length_difference = 0 + previous_hunk = nil + output = [] + + Diff::LCS.diff(old_lines, new_lines).each do |piece| + hunk = Diff::LCS::Hunk.new(old_lines, new_lines, piece, 3, file_length_difference) + file_length_difference = hunk.file_length_difference + maybe_contiguous_hunks = previous_hunk.nil? || hunk.merge(previous_hunk) + + output << "#{previous_hunk.diff(:unified)}\n" unless maybe_contiguous_hunks + + previous_hunk = hunk + end + output << "#{previous_hunk.diff(:unified, true)}\n" unless previous_hunk.nil? + output.join + end + + it "should not misplace the new chunk" do + old_data = [ + "recipe[a::default]", "recipe[b::default]", "recipe[c::default]", + "recipe[d::default]", "recipe[e::default]", "recipe[f::default]", + "recipe[g::default]", "recipe[h::default]", "recipe[i::default]", + "recipe[j::default]", "recipe[k::default]", "recipe[l::default]", + "recipe[m::default]", "recipe[n::default]" + ] + + new_data = [ + "recipe[a::default]", "recipe[c::default]", "recipe[d::default]", + "recipe[e::default]", "recipe[f::default]", "recipe[g::default]", + "recipe[h::default]", "recipe[i::default]", "recipe[j::default]", + "recipe[k::default]", "recipe[l::default]", "recipe[m::default]", + "recipe[n::default]", "recipe[o::new]", "recipe[p::new]", + "recipe[q::new]", "recipe[r::new]" + ] + + # standard:disable Layout/HeredocIndentation + expect(diff_lines(old_data, new_data)).to eq(<<-EODIFF) +@@ -1,5 +1,4 @@ + recipe[a::default] +-recipe[b::default] + recipe[c::default] + recipe[d::default] + recipe[e::default] +@@ -12,3 +11,7 @@ + recipe[l::default] + recipe[m::default] + recipe[n::default] ++recipe[o::new] ++recipe[p::new] ++recipe[q::new] ++recipe[r::new] + EODIFF + # standard:enable Layout/HeredocIndentation + end + end + + describe "issue #107 (replaces issue #60)" do + it "should produce unified output with correct context" do + # standard:disable Layout/HeredocIndentation + old_data = <<-DATA_OLD.strip.split("\n").map(&:chomp) +{ + "name": "x", + "description": "hi" +} + DATA_OLD + + new_data = <<-DATA_NEW.strip.split("\n").map(&:chomp) +{ + "name": "x", + "description": "lo" +} + DATA_NEW + + diff = ::Diff::LCS.diff(old_data, new_data) + hunk = ::Diff::LCS::Hunk.new(old_data, new_data, diff.first, 3, 0) + + expect(hunk.diff(:unified)).to eq(<<-EXPECTED.chomp) +@@ -1,4 +1,4 @@ + { + "name": "x", +- "description": "hi" ++ "description": "lo" + } + EXPECTED + # standard:enable Layout/HeredocIndentation + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/lcs_spec.rb b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/lcs_spec.rb new file mode 100644 index 00000000..c17f22f6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/lcs_spec.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Diff::LCS::Internals, ".lcs" do + include Diff::LCS::SpecHelper::Matchers + + it "returns a meaningful LCS array with (seq1, seq2)" do + res = Diff::LCS::Internals.lcs(seq1, seq2) + # The result of the LCS (less the +nil+ values) must be as long as the + # correct result. + expect(res.compact.size).to eq(correct_lcs.size) + expect(res).to correctly_map_sequence(seq1).to_other_sequence(seq2) + + # Compact these transformations and they should be the correct LCS. + x_seq1 = (0...res.size).map { |ix| res[ix] ? seq1[ix] : nil }.compact + x_seq2 = (0...res.size).map { |ix| res[ix] ? seq2[res[ix]] : nil }.compact + + expect(x_seq1).to eq(correct_lcs) + expect(x_seq2).to eq(correct_lcs) + end + + it "returns all indexes with (hello, hello)" do + expect(Diff::LCS::Internals.lcs(hello, hello)).to \ + eq((0...hello.size).to_a) + end + + it "returns all indexes with (hello_ary, hello_ary)" do + expect(Diff::LCS::Internals.lcs(hello_ary, hello_ary)).to \ + eq((0...hello_ary.size).to_a) + end +end + +describe Diff::LCS, ".LCS" do + include Diff::LCS::SpecHelper::Matchers + + it "returns the correct compacted values from Diff::LCS.LCS" do + res = Diff::LCS.LCS(seq1, seq2) + expect(res).to eq(correct_lcs) + expect(res.compact).to eq(res) + end + + it "is transitive" do + res = Diff::LCS.LCS(seq2, seq1) + expect(res).to eq(correct_lcs) + expect(res.compact).to eq(res) + end + + it "returns %W(h e l l o) with (hello, hello)" do + expect(Diff::LCS.LCS(hello, hello)).to eq(hello.chars) + end + + it "returns hello_ary with (hello_ary, hello_ary)" do + expect(Diff::LCS.LCS(hello_ary, hello_ary)).to eq(hello_ary) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/ldiff_spec.rb b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/ldiff_spec.rb new file mode 100644 index 00000000..e13b5614 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/ldiff_spec.rb @@ -0,0 +1,100 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe "bin/ldiff" do + include CaptureSubprocessIO + + # standard:disable Style/HashSyntax + fixtures = [ + {:name => "diff", :left => "aX", :right => "bXaX", :diff => 1}, + {:name => "diff.missing_new_line1", :left => "four_lines", :right => "four_lines_with_missing_new_line", :diff => 1}, + {:name => "diff.missing_new_line2", :left => "four_lines_with_missing_new_line", :right => "four_lines", :diff => 1}, + {:name => "diff.issue95_trailing_context", :left => "123_x", :right => "456_x", :diff => 1}, + {:name => "diff.four_lines.vs.empty", :left => "four_lines", :right => "empty", :diff => 1}, + {:name => "diff.empty.vs.four_lines", :left => "empty", :right => "four_lines", :diff => 1}, + {:name => "diff.bin1", :left => "file1.bin", :right => "file1.bin", :diff => 0}, + {:name => "diff.bin2", :left => "file1.bin", :right => "file2.bin", :diff => 1}, + {:name => "diff.chef", :left => "old-chef", :right => "new-chef", :diff => 1}, + {:name => "diff.chef2", :left => "old-chef2", :right => "new-chef2", :diff => 1} + ].product([nil, "-e", "-f", "-c", "-u"]).map { |(fixture, flag)| + fixture = fixture.dup + fixture[:flag] = flag + fixture + } + # standard:enable Style/HashSyntax + + def self.test_ldiff(fixture) + desc = [ + fixture[:flag], + "spec/fixtures/#{fixture[:left]}", + "spec/fixtures/#{fixture[:right]}", + "#", + "=>", + "spec/fixtures/ldiff/output.#{fixture[:name]}#{fixture[:flag]}" + ].join(" ") + + it desc do + stdout, stderr, status = run_ldiff(fixture) + expect(status).to eq(fixture[:diff]) + expect(stderr).to eq(read_fixture(fixture, mode: "error", allow_missing: true)) + expect(stdout).to eq(read_fixture(fixture, mode: "output", allow_missing: false)) + end + end + + fixtures.each do |fixture| + test_ldiff(fixture) + end + + def read_fixture(options, mode: "output", allow_missing: false) + fixture = options.fetch(:name) + flag = options.fetch(:flag) + name = "spec/fixtures/ldiff/#{mode}.#{fixture}#{flag}" + + return "" if !::File.exist?(name) && allow_missing + + data = IO.__send__(IO.respond_to?(:binread) ? :binread : :read, name) + clean_data(data, flag) + end + + def clean_data(data, flag) + data = + case flag + when "-c", "-u" + clean_output_timestamp(data) + else + data + end + data.gsub(/\r\n?/, "\n") + end + + def clean_output_timestamp(data) + data.gsub( + %r{ + ^ + [-+*]{3} + \s* + spec/fixtures/(\S+) + \s* + \d{4}-\d\d-\d\d + \s* + \d\d:\d\d:\d\d(?:\.\d+) + \s* + (?:[-+]\d{4}|Z) + }x, + '*** spec/fixtures/\1 0000-00-00 :00 =>:00 =>00.000000000 -0000' + ) + end + + def run_ldiff(options) + flag = options.fetch(:flag) + left = options.fetch(:left) + right = options.fetch(:right) + + stdout, stderr = capture_subprocess_io do + system("ruby -Ilib bin/ldiff #{flag} spec/fixtures/#{left} spec/fixtures/#{right}") + end + + [clean_data(stdout, flag), stderr, $?.exitstatus] + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/patch_spec.rb b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/patch_spec.rb new file mode 100644 index 00000000..8fc3ee25 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/patch_spec.rb @@ -0,0 +1,416 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "Diff::LCS.patch" do + include Diff::LCS::SpecHelper::Matchers + + shared_examples "patch sequences correctly" do + it "correctly patches left-to-right (patch autodiscovery)" do + expect(Diff::LCS.patch(s1, patch_set)).to eq(s2) + end + + it "correctly patches left-to-right (explicit patch)" do + expect(Diff::LCS.patch(s1, patch_set, :patch)).to eq(s2) + expect(Diff::LCS.patch!(s1, patch_set)).to eq(s2) + end + + it "correctly patches right-to-left (unpatch autodiscovery)" do + expect(Diff::LCS.patch(s2, patch_set)).to eq(s1) + end + + it "correctly patches right-to-left (explicit unpatch)" do + expect(Diff::LCS.patch(s2, patch_set, :unpatch)).to eq(s1) + expect(Diff::LCS.unpatch!(s2, patch_set)).to eq(s1) + end + end + + describe "using a Diff::LCS.diff patchset" do + describe "an empty patchset returns the source" do + it "works on a string (hello)" do + diff = Diff::LCS.diff(hello, hello) + expect(Diff::LCS.patch(hello, diff)).to eq(hello) + end + + it "works on an array %W(h e l l o)" do + diff = Diff::LCS.diff(hello_ary, hello_ary) + expect(Diff::LCS.patch(hello_ary, diff)).to eq(hello_ary) + end + end + + describe "with default diff callbacks (DiffCallbacks)" do + describe "forward (s1 -> s2)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq1 } + let(:s2) { seq2 } + let(:patch_set) { Diff::LCS.diff(seq1, seq2) } + end + end + + describe "reverse (s2 -> s1)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq2 } + let(:s2) { seq1 } + let(:patch_set) { Diff::LCS.diff(seq2, seq1) } + end + end + end + + describe "with context diff callbacks (ContextDiffCallbacks)" do + describe "forward (s1 -> s2)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq1 } + let(:s2) { seq2 } + let(:patch_set) { + Diff::LCS.diff(seq1, seq2, Diff::LCS::ContextDiffCallbacks) + } + end + end + + describe "reverse (s2 -> s1)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq2 } + let(:s2) { seq1 } + let(:patch_set) { + Diff::LCS.diff(seq2, seq1, Diff::LCS::ContextDiffCallbacks) + } + end + end + end + + describe "with sdiff callbacks (SDiffCallbacks)" do + describe "forward (s1 -> s2)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq1 } + let(:s2) { seq2 } + let(:patch_set) { + Diff::LCS.diff(seq1, seq2, Diff::LCS::SDiffCallbacks) + } + end + end + + describe "reverse (s2 -> s1)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq2 } + let(:s2) { seq1 } + let(:patch_set) { + Diff::LCS.diff(seq2, seq1, Diff::LCS::SDiffCallbacks) + } + end + end + end + end + + describe "using a Diff::LCS.sdiff patchset" do + describe "an empty patchset returns the source" do + it "works on a string (hello)" do + expect(Diff::LCS.patch(hello, Diff::LCS.sdiff(hello, hello))).to eq(hello) + end + + it "works on an array %W(h e l l o)" do + expect(Diff::LCS.patch(hello_ary, Diff::LCS.sdiff(hello_ary, hello_ary))).to eq(hello_ary) + end + end + + describe "with default diff callbacks (DiffCallbacks)" do + describe "forward (s1 -> s2)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq1 } + let(:s2) { seq2 } + let(:patch_set) { + Diff::LCS.sdiff(seq1, seq2, Diff::LCS::DiffCallbacks) + } + end + end + + describe "reverse (s2 -> s1)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq2 } + let(:s2) { seq1 } + let(:patch_set) { + Diff::LCS.sdiff(seq2, seq1, Diff::LCS::DiffCallbacks) + } + end + end + end + + describe "with context diff callbacks (DiffCallbacks)" do + describe "forward (s1 -> s2)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq1 } + let(:s2) { seq2 } + let(:patch_set) { + Diff::LCS.sdiff(seq1, seq2, Diff::LCS::ContextDiffCallbacks) + } + end + end + + describe "reverse (s2 -> s1)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq2 } + let(:s2) { seq1 } + let(:patch_set) { + Diff::LCS.sdiff(seq2, seq1, Diff::LCS::ContextDiffCallbacks) + } + end + end + end + + describe "with sdiff callbacks (SDiffCallbacks)" do + describe "forward (s1 -> s2)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq1 } + let(:s2) { seq2 } + let(:patch_set) { Diff::LCS.sdiff(seq1, seq2) } + end + end + + describe "reverse (s2 -> s1)" do + it_has_behavior "patch sequences correctly" do + let(:s1) { seq2 } + let(:s2) { seq1 } + let(:patch_set) { Diff::LCS.sdiff(seq2, seq1) } + end + end + end + end + + # Note: because of the error in autodiscovery ("does not autodiscover s1 + # to s2 patches"), this cannot use the "patch sequences correctly" shared + # set. Once the bug in autodiscovery is fixed, this can be converted as + # above. + describe "fix bug 891: patchsets do not contain the last equal part" do + before :each do + @s1 = %w[a b c d e f g h i j k] # standard:disable Layout/SpaceInsideArrayPercentLiteral + @s2 = %w[a b c d D e f g h i j k] + end + + describe "using Diff::LCS.diff with default diff callbacks" do + before :each do + @patch_set_s1_s2 = Diff::LCS.diff(@s1, @s2) + @patch_set_s2_s1 = Diff::LCS.diff(@s2, @s1) + end + + it "autodiscovers s1 to s2 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 the left-to-right patches" do + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1)).to eq(@s1) + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2)).to eq(@s1) + end + + it "correctly patches left-to-right (explicit patch)" do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2, :patch)).to eq(@s2) + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1, :patch)).to eq(@s1) + expect(Diff::LCS.patch!(@s1, @patch_set_s1_s2)).to eq(@s2) + expect(Diff::LCS.patch!(@s2, @patch_set_s2_s1)).to eq(@s1) + end + + it "correctly patches right-to-left (explicit unpatch)" do + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2, :unpatch)).to eq(@s1) + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1, :unpatch)).to eq(@s2) + expect(Diff::LCS.unpatch!(@s2, @patch_set_s1_s2)).to eq(@s1) + expect(Diff::LCS.unpatch!(@s1, @patch_set_s2_s1)).to eq(@s2) + end + end + + describe "using Diff::LCS.diff with context diff callbacks" do + before :each do + @patch_set_s1_s2 = Diff::LCS.diff(@s1, @s2, Diff::LCS::ContextDiffCallbacks) + @patch_set_s2_s1 = Diff::LCS.diff(@s2, @s1, Diff::LCS::ContextDiffCallbacks) + end + + it "autodiscovers s1 to s2 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 the left-to-right patches" do + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1)).to eq(@s1) + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2)).to eq(@s1) + end + + it "correctly patches left-to-right (explicit patch)" do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2, :patch)).to eq(@s2) + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1, :patch)).to eq(@s1) + expect(Diff::LCS.patch!(@s1, @patch_set_s1_s2)).to eq(@s2) + expect(Diff::LCS.patch!(@s2, @patch_set_s2_s1)).to eq(@s1) + end + + it "correctly patches right-to-left (explicit unpatch)" do + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2, :unpatch)).to eq(@s1) + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1, :unpatch)).to eq(@s2) + expect(Diff::LCS.unpatch!(@s2, @patch_set_s1_s2)).to eq(@s1) + expect(Diff::LCS.unpatch!(@s1, @patch_set_s2_s1)).to eq(@s2) + end + end + + describe "using Diff::LCS.diff with sdiff callbacks" do + before(:each) do + @patch_set_s1_s2 = Diff::LCS.diff(@s1, @s2, Diff::LCS::SDiffCallbacks) + @patch_set_s2_s1 = Diff::LCS.diff(@s2, @s1, Diff::LCS::SDiffCallbacks) + end + + it "autodiscovers s1 to s2 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 the left-to-right patches" do + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1)).to eq(@s1) + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2)).to eq(@s1) + end + + it "correctly patches left-to-right (explicit patch)" do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2, :patch)).to eq(@s2) + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1, :patch)).to eq(@s1) + expect(Diff::LCS.patch!(@s1, @patch_set_s1_s2)).to eq(@s2) + expect(Diff::LCS.patch!(@s2, @patch_set_s2_s1)).to eq(@s1) + end + + it "correctly patches right-to-left (explicit unpatch)" do + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2, :unpatch)).to eq(@s1) + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1, :unpatch)).to eq(@s2) + expect(Diff::LCS.unpatch!(@s2, @patch_set_s1_s2)).to eq(@s1) + expect(Diff::LCS.unpatch!(@s1, @patch_set_s2_s1)).to eq(@s2) + end + end + + describe "using Diff::LCS.sdiff with default sdiff callbacks" do + before(:each) do + @patch_set_s1_s2 = Diff::LCS.sdiff(@s1, @s2) + @patch_set_s2_s1 = Diff::LCS.sdiff(@s2, @s1) + end + + it "autodiscovers s1 to s2 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 the left-to-right patches" do + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1)).to eq(@s1) + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2)).to eq(@s1) + end + + it "correctly patches left-to-right (explicit patch)" do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2, :patch)).to eq(@s2) + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1, :patch)).to eq(@s1) + expect(Diff::LCS.patch!(@s1, @patch_set_s1_s2)).to eq(@s2) + expect(Diff::LCS.patch!(@s2, @patch_set_s2_s1)).to eq(@s1) + end + + it "correctly patches right-to-left (explicit unpatch)" do + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2, :unpatch)).to eq(@s1) + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1, :unpatch)).to eq(@s2) + expect(Diff::LCS.unpatch!(@s2, @patch_set_s1_s2)).to eq(@s1) + expect(Diff::LCS.unpatch!(@s1, @patch_set_s2_s1)).to eq(@s2) + end + end + + describe "using Diff::LCS.sdiff with context diff callbacks" do + before(:each) do + @patch_set_s1_s2 = Diff::LCS.sdiff(@s1, @s2, Diff::LCS::ContextDiffCallbacks) + @patch_set_s2_s1 = Diff::LCS.sdiff(@s2, @s1, Diff::LCS::ContextDiffCallbacks) + end + + it "autodiscovers s1 to s2 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 the left-to-right patches" do + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1)).to eq(@s1) + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2)).to eq(@s1) + end + + it "correctly patches left-to-right (explicit patch)" do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2, :patch)).to eq(@s2) + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1, :patch)).to eq(@s1) + expect(Diff::LCS.patch!(@s1, @patch_set_s1_s2)).to eq(@s2) + expect(Diff::LCS.patch!(@s2, @patch_set_s2_s1)).to eq(@s1) + end + + it "correctly patches right-to-left (explicit unpatch)" do + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2, :unpatch)).to eq(@s1) + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1, :unpatch)).to eq(@s2) + expect(Diff::LCS.unpatch!(@s2, @patch_set_s1_s2)).to eq(@s1) + expect(Diff::LCS.unpatch!(@s1, @patch_set_s2_s1)).to eq(@s2) + end + end + + describe "using Diff::LCS.sdiff with default diff callbacks" do + before(:each) do + @patch_set_s1_s2 = Diff::LCS.sdiff(@s1, @s2, Diff::LCS::DiffCallbacks) + @patch_set_s2_s1 = Diff::LCS.sdiff(@s2, @s1, Diff::LCS::DiffCallbacks) + end + + it "autodiscovers s1 to s2 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 patches" do + expect do + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1)).to eq(@s2) + end.to_not raise_error + end + + it "autodiscovers s2 to s1 the left-to-right patches" do + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1)).to eq(@s1) + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2)).to eq(@s1) + end + + it "correctly patches left-to-right (explicit patch)" do + expect(Diff::LCS.patch(@s1, @patch_set_s1_s2, :patch)).to eq(@s2) + expect(Diff::LCS.patch(@s2, @patch_set_s2_s1, :patch)).to eq(@s1) + expect(Diff::LCS.patch!(@s1, @patch_set_s1_s2)).to eq(@s2) + expect(Diff::LCS.patch!(@s2, @patch_set_s2_s1)).to eq(@s1) + end + + it "correctly patches right-to-left (explicit unpatch)" do + expect(Diff::LCS.patch(@s2, @patch_set_s1_s2, :unpatch)).to eq(@s1) + expect(Diff::LCS.patch(@s1, @patch_set_s2_s1, :unpatch)).to eq(@s2) + expect(Diff::LCS.unpatch!(@s2, @patch_set_s1_s2)).to eq(@s1) + expect(Diff::LCS.unpatch!(@s1, @patch_set_s2_s1)).to eq(@s2) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/sdiff_spec.rb b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/sdiff_spec.rb new file mode 100644 index 00000000..aded3017 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/sdiff_spec.rb @@ -0,0 +1,216 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "Diff::LCS.sdiff" do + include Diff::LCS::SpecHelper::Matchers + + shared_examples "compare sequences correctly" do + it "compares s1 -> s2 correctly" do + expect(Diff::LCS.sdiff(s1, s2)).to eq(context_diff(result)) + end + + it "compares s2 -> s1 correctly" do + expect(Diff::LCS.sdiff(s2, s1)).to eq(context_diff(reverse_sdiff(result))) + end + end + + describe "using seq1 & seq2" do + let(:s1) { seq1 } + let(:s2) { seq2 } + let(:result) { correct_forward_sdiff } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(abc def yyy xxx ghi jkl) & %w(abc dxf xxx ghi jkl)" do + let(:s1) { %w[abc def yyy xxx ghi jkl] } + let(:s2) { %w[abc dxf xxx ghi jkl] } + let(:result) { + # standard:disable Layout/ExtraSpacing + [ + ["=", [0, "abc"], [0, "abc"]], + ["!", [1, "def"], [1, "dxf"]], + ["-", [2, "yyy"], [2, nil]], + ["=", [3, "xxx"], [2, "xxx"]], + ["=", [4, "ghi"], [3, "ghi"]], + ["=", [5, "jkl"], [4, "jkl"]] + ] + # standard:enable Layout/ExtraSpacing + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(a b c d e) & %w(a e)" do + let(:s1) { %w[a b c d e] } + let(:s2) { %w[a e] } + let(:result) { + [ + ["=", [0, "a"], [0, "a"]], + ["-", [1, "b"], [1, nil]], + ["-", [2, "c"], [1, nil]], + ["-", [3, "d"], [1, nil]], + ["=", [4, "e"], [1, "e"]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(a e) & %w(a b c d e)" do + let(:s1) { %w[a e] } + let(:s2) { %w[a b c d e] } + let(:result) { + [ + ["=", [0, "a"], [0, "a"]], + ["+", [1, nil], [1, "b"]], + ["+", [1, nil], [2, "c"]], + ["+", [1, nil], [3, "d"]], + ["=", [1, "e"], [4, "e"]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(v x a e) & %w(w y a b c d e)" do + let(:s1) { %w[v x a e] } + let(:s2) { %w[w y a b c d e] } + let(:result) { + [ + ["!", [0, "v"], [0, "w"]], + ["!", [1, "x"], [1, "y"]], + ["=", [2, "a"], [2, "a"]], + ["+", [3, nil], [3, "b"]], + ["+", [3, nil], [4, "c"]], + ["+", [3, nil], [5, "d"]], + ["=", [3, "e"], [6, "e"]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(x a e) & %w(a b c d e)" do + let(:s1) { %w[x a e] } + let(:s2) { %w[a b c d e] } + let(:result) { + [ + ["-", [0, "x"], [0, nil]], + ["=", [1, "a"], [0, "a"]], + ["+", [2, nil], [1, "b"]], + ["+", [2, nil], [2, "c"]], + ["+", [2, nil], [3, "d"]], + ["=", [2, "e"], [4, "e"]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(a e) & %w(x a b c d e)" do + let(:s1) { %w[a e] } + let(:s2) { %w[x a b c d e] } + let(:result) { + [ + ["+", [0, nil], [0, "x"]], + ["=", [0, "a"], [1, "a"]], + ["+", [1, nil], [2, "b"]], + ["+", [1, nil], [3, "c"]], + ["+", [1, nil], [4, "d"]], + ["=", [1, "e"], [5, "e"]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(a e v) & %w(x a b c d e w x)" do + let(:s1) { %w[a e v] } + let(:s2) { %w[x a b c d e w x] } + let(:result) { + [ + ["+", [0, nil], [0, "x"]], + ["=", [0, "a"], [1, "a"]], + ["+", [1, nil], [2, "b"]], + ["+", [1, nil], [3, "c"]], + ["+", [1, nil], [4, "d"]], + ["=", [1, "e"], [5, "e"]], + ["!", [2, "v"], [6, "w"]], + ["+", [3, nil], [7, "x"]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w() & %w(a b c)" do + let(:s1) { %w[] } + let(:s2) { %w[a b c] } + let(:result) { + [ + ["+", [0, nil], [0, "a"]], + ["+", [0, nil], [1, "b"]], + ["+", [0, nil], [2, "c"]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(a b c) & %w(1)" do + let(:s1) { %w[a b c] } + let(:s2) { %w[1] } + let(:result) { + [ + ["!", [0, "a"], [0, "1"]], + ["-", [1, "b"], [1, nil]], + ["-", [2, "c"], [1, nil]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(a b c) & %w(c)" do + let(:s1) { %w[a b c] } + let(:s2) { %w[c] } + let(:result) { + [ + ["-", [0, "a"], [0, nil]], + ["-", [1, "b"], [0, nil]], + ["=", [2, "c"], [0, "c"]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using %w(abcd efgh ijkl mnop) & []" do + let(:s1) { %w[abcd efgh ijkl mnop] } + let(:s2) { [] } + let(:result) { + [ + ["-", [0, "abcd"], [0, nil]], + ["-", [1, "efgh"], [0, nil]], + ["-", [2, "ijkl"], [0, nil]], + ["-", [3, "mnop"], [0, nil]] + ] + } + + it_has_behavior "compare sequences correctly" + end + + describe "using [[1,2]] & []" do + let(:s1) { [[1, 2]] } + let(:s2) { [] } + let(:result) { + [ + ["-", [0, [1, 2]], [0, nil]] + ] + } + + it_has_behavior "compare sequences correctly" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/spec_helper.rb b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/spec_helper.rb new file mode 100644 index 00000000..baaa3d03 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/spec_helper.rb @@ -0,0 +1,376 @@ +# frozen_string_literal: true + +require "rubygems" +require "pathname" + +require "psych" if RUBY_VERSION >= "1.9" + +if ENV["COVERAGE"] + require "simplecov" + require "simplecov-lcov" + + SimpleCov::Formatter::LcovFormatter.config do |config| + config.report_with_single_file = true + config.lcov_file_name = "lcov.info" + end + + SimpleCov.start "test_frameworks" do + enable_coverage :branch + primary_coverage :branch + formatter SimpleCov::Formatter::MultiFormatter.new([ + SimpleCov::Formatter::HTMLFormatter, + SimpleCov::Formatter::LcovFormatter, + SimpleCov::Formatter::SimpleFormatter + ]) + end +end + +file = Pathname.new(__FILE__).expand_path +path = file.parent +parent = path.parent + +$:.unshift parent.join("lib") + +module CaptureSubprocessIO + def _synchronize + yield + end + + def capture_subprocess_io + _synchronize { _capture_subprocess_io { yield } } + end + + def _capture_subprocess_io + require "tempfile" + + captured_stdout, captured_stderr = Tempfile.new("out"), Tempfile.new("err") + + orig_stdout, orig_stderr = $stdout.dup, $stderr.dup + $stdout.reopen captured_stdout + $stderr.reopen captured_stderr + + yield + + $stdout.rewind + $stderr.rewind + + [captured_stdout.read, captured_stderr.read] + ensure + captured_stdout.unlink + captured_stderr.unlink + $stdout.reopen orig_stdout + $stderr.reopen orig_stderr + end + private :_capture_subprocess_io +end + +require "diff-lcs" + +module Diff::LCS::SpecHelper + def hello + "hello" + end + + def hello_ary + %w[h e l l o] + end + + def seq1 + %w[a b c e h j l m n p] + end + + def skipped_seq1 + %w[a h n p] + end + + def seq2 + %w[b c d e f j k l m r s t] + end + + def skipped_seq2 + %w[d f k r s t] + end + + def word_sequence + %w[abcd efgh ijkl mnopqrstuvwxyz] + end + + def correct_lcs + %w[b c e j l m] + end + + # standard:disable Layout/ExtraSpacing + def correct_forward_diff + [ + [ + ["-", 0, "a"] + ], + [ + ["+", 2, "d"] + ], + [ + ["-", 4, "h"], + ["+", 4, "f"] + ], + [ + ["+", 6, "k"] + ], + [ + ["-", 8, "n"], + ["+", 9, "r"], + ["-", 9, "p"], + ["+", 10, "s"], + ["+", 11, "t"] + ] + ] + end + + def correct_backward_diff + [ + [ + ["+", 0, "a"] + ], + [ + ["-", 2, "d"] + ], + [ + ["-", 4, "f"], + ["+", 4, "h"] + ], + [ + ["-", 6, "k"] + ], + [ + ["-", 9, "r"], + ["+", 8, "n"], + ["-", 10, "s"], + ["+", 9, "p"], + ["-", 11, "t"] + ] + ] + end + + def correct_forward_sdiff + [ + ["-", [0, "a"], [0, nil]], + ["=", [1, "b"], [0, "b"]], + ["=", [2, "c"], [1, "c"]], + ["+", [3, nil], [2, "d"]], + ["=", [3, "e"], [3, "e"]], + ["!", [4, "h"], [4, "f"]], + ["=", [5, "j"], [5, "j"]], + ["+", [6, nil], [6, "k"]], + ["=", [6, "l"], [7, "l"]], + ["=", [7, "m"], [8, "m"]], + ["!", [8, "n"], [9, "r"]], + ["!", [9, "p"], [10, "s"]], + ["+", [10, nil], [11, "t"]] + ] + end + # standard:enable Layout/ExtraSpacing + + def reverse_sdiff(forward_sdiff) + forward_sdiff.map { |line| + line[1], line[2] = line[2], line[1] + case line[0] + when "-" then line[0] = "+" + when "+" then line[0] = "-" + end + line + } + end + + def change_diff(diff) + map_diffs(diff, Diff::LCS::Change) + end + + def context_diff(diff) + map_diffs(diff, Diff::LCS::ContextChange) + end + + def format_diffs(diffs) + diffs.map { |e| + if e.is_a?(Array) + e.map { |f| f.to_a.join }.join(", ") + else + e.to_a.join + end + }.join("\n") + end + + def map_diffs(diffs, klass = Diff::LCS::ContextChange) + diffs.map do |chunks| + if klass == Diff::LCS::ContextChange + klass.from_a(chunks) + else + chunks.map { |changes| klass.from_a(changes) } + end + end + end + + def balanced_traversal(s1, s2, callback_type) + callback = __send__(callback_type) + Diff::LCS.traverse_balanced(s1, s2, callback) + callback + end + + def balanced_reverse(change_result) + new_result = [] + change_result.each do |line| + line = [line[0], line[2], line[1]] + case line[0] + when "<" + line[0] = ">" + when ">" + line[0] = "<" + end + new_result << line + end + new_result.sort_by { |line| [line[1], line[2]] } + end + + def map_to_no_change(change_result) + new_result = [] + change_result.each do |line| + case line[0] + when "!" + new_result << ["<", line[1], line[2]] + new_result << [">", line[1] + 1, line[2]] + else + new_result << line + end + end + new_result + end + + class SimpleCallback + def initialize + reset + end + + attr_reader :matched_a + attr_reader :matched_b + attr_reader :discards_a + attr_reader :discards_b + attr_reader :done_a + attr_reader :done_b + + def reset + @matched_a = [] + @matched_b = [] + @discards_a = [] + @discards_b = [] + @done_a = [] + @done_b = [] + self + end + + def match(event) + @matched_a << event.old_element + @matched_b << event.new_element + end + + def discard_b(event) + @discards_b << event.new_element + end + + def discard_a(event) + @discards_a << event.old_element + end + + def finished_a(event) + @done_a << [ + event.old_element, event.old_position, + event.new_element, event.new_position + ] + end + + def finished_b(event) + @done_b << [ + event.old_element, event.old_position, + event.new_element, event.new_position + ] + end + end + + def simple_callback + SimpleCallback.new + end + + class SimpleCallbackNoFinishers < SimpleCallback + undef :finished_a + undef :finished_b + end + + def simple_callback_no_finishers + SimpleCallbackNoFinishers.new + end + + class BalancedCallback + def initialize + reset + end + + attr_reader :result + + def reset + @result = [] + end + + def match(event) + @result << ["=", event.old_position, event.new_position] + end + + def discard_a(event) + @result << ["<", event.old_position, event.new_position] + end + + def discard_b(event) + @result << [">", event.old_position, event.new_position] + end + + def change(event) + @result << ["!", event.old_position, event.new_position] + end + end + + def balanced_callback + BalancedCallback.new + end + + class BalancedCallbackNoChange < BalancedCallback + undef :change + end + + def balanced_callback_no_change + BalancedCallbackNoChange.new + end + + module Matchers + extend RSpec::Matchers::DSL + + matcher :be_nil_or_match_values do |ii, s1, s2| + match do |ee| + expect(ee).to(satisfy { |vee| vee.nil? || s1[ii] == s2[ee] }) + end + end + + matcher :correctly_map_sequence do |s1| + match do |actual| + actual.each_index { |ii| expect(actual[ii]).to be_nil_or_match_values(ii, s1, @s2) } + end + + chain :to_other_sequence do |s2| + @s2 = s2 + end + end + end +end + +RSpec.configure do |conf| + conf.include Diff::LCS::SpecHelper + conf.alias_it_should_behave_like_to :it_has_behavior, "has behavior:" + # standard:disable Style/HashSyntax + conf.filter_run_excluding :broken => true + # standard:enable Style/HashSyntax +end diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/traverse_balanced_spec.rb b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/traverse_balanced_spec.rb new file mode 100644 index 00000000..3a3f6779 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/traverse_balanced_spec.rb @@ -0,0 +1,312 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "Diff::LCS.traverse_balanced" do + include Diff::LCS::SpecHelper::Matchers + + shared_examples "with a #change callback" do |s1, s2, result| + it "traverses s1 -> s2 correctly" do + traversal = balanced_traversal(s1, s2, :balanced_callback) + expect(traversal.result).to eq(result) + end + + it "traverses s2 -> s1 correctly" do + traversal = balanced_traversal(s2, s1, :balanced_callback) + expect(traversal.result).to eq(balanced_reverse(result)) + end + end + + shared_examples "without a #change callback" do |s1, s2, result| + it "traverses s1 -> s2 correctly" do + traversal = balanced_traversal(s1, s2, :balanced_callback_no_change) + expect(traversal.result).to eq(map_to_no_change(result)) + end + + it "traverses s2 -> s1 correctly" do + traversal = balanced_traversal(s2, s1, :balanced_callback_no_change) + expect(traversal.result).to eq(map_to_no_change(balanced_reverse(result))) + end + end + + describe "identical string sequences ('abc')" do + s1 = s2 = "abc" + + result = [ + ["=", 0, 0], + ["=", 1, 1], + ["=", 2, 2] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "identical array sequences %w(a b c)" do + s1 = s2 = %w[a b c] + + result = [ + ["=", 0, 0], + ["=", 1, 1], + ["=", 2, 2] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "sequences %w(a b c) & %w(a x c)" do + s1 = %w[a b c] + s2 = %w[a x c] + + result = [ + ["=", 0, 0], + ["!", 1, 1], + ["=", 2, 2] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "sequences %w(a x y c) & %w(a v w c)" do + s1 = %w[a x y c] + s2 = %w[a v w c] + + result = [ + ["=", 0, 0], + ["!", 1, 1], + ["!", 2, 2], + ["=", 3, 3] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "sequences %w(x y c) & %w(v w c)" do + s1 = %w[x y c] + s2 = %w[v w c] + result = [ + ["!", 0, 0], + ["!", 1, 1], + ["=", 2, 2] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "sequences %w(a x y z) & %w(b v w)" do + s1 = %w[a x y z] + s2 = %w[b v w] + result = [ + ["!", 0, 0], + ["!", 1, 1], + ["!", 2, 2], + ["<", 3, 3] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "sequences %w(a z) & %w(a)" do + s1 = %w[a z] + s2 = %w[a] + result = [ + ["=", 0, 0], + ["<", 1, 1] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "sequences %w(z a) & %w(a)" do + s1 = %w[z a] + s2 = %w[a] + result = [ + ["<", 0, 0], + ["=", 1, 0] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "sequences %w(a b c) & %w(x y z)" do + s1 = %w[a b c] + s2 = %w[x y z] + result = [ + ["!", 0, 0], + ["!", 1, 1], + ["!", 2, 2] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "sequences %w(abcd efgh ijkl mnoopqrstuvwxyz) & []" do + s1 = %w[abcd efgh ijkl mnopqrstuvwxyz] + s2 = [] + result = [ + ["<", 0, 0], + ["<", 1, 0], + ["<", 2, 0], + ["<", 3, 0] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "strings %q(a b c) & %q(a x c)" do + s1 = "a b c" + s2 = "a x c" + + result = [ + ["=", 0, 0], + ["=", 1, 1], + ["!", 2, 2], + ["=", 3, 3], + ["=", 4, 4] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "strings %q(a x y c) & %q(a v w c)" do + s1 = "a x y c" + s2 = "a v w c" + + result = [ + ["=", 0, 0], + ["=", 1, 1], + ["!", 2, 2], + ["=", 3, 3], + ["!", 4, 4], + ["=", 5, 5], + ["=", 6, 6] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "strings %q(x y c) & %q(v w c)" do + s1 = "x y c" + s2 = "v w c" + result = [ + ["!", 0, 0], + ["=", 1, 1], + ["!", 2, 2], + ["=", 3, 3], + ["=", 4, 4] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "strings %q(a x y z) & %q(b v w)" do + s1 = "a x y z" + s2 = "b v w" + result = [ + ["!", 0, 0], + ["=", 1, 1], + ["!", 2, 2], + ["=", 3, 3], + ["!", 4, 4], + ["<", 5, 5], + ["<", 6, 5] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "strings %q(a z) & %q(a)" do + s1 = "a z" + s2 = "a" + result = [ + ["=", 0, 0], + ["<", 1, 1], + ["<", 2, 1] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "strings %q(z a) & %q(a)" do + s1 = "z a" + s2 = "a" + result = [ + ["<", 0, 0], + ["<", 1, 0], + ["=", 2, 0] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "strings %q(a b c) & %q(x y z)" do + s1 = "a b c" + s2 = "x y z" + result = [ + ["!", 0, 0], + ["=", 1, 1], + ["!", 2, 2], + ["=", 3, 3], + ["!", 4, 4] + ] + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end + + describe "strings %q(abcd efgh ijkl mnopqrstuvwxyz) & %q()" do + s1 = "abcd efgh ijkl mnopqrstuvwxyz" + s2 = "" + # standard:disable Layout/ExtraSpacing + result = [ + ["<", 0, 0], + ["<", 1, 0], + ["<", 2, 0], + ["<", 3, 0], + ["<", 4, 0], + ["<", 5, 0], + ["<", 6, 0], + ["<", 7, 0], + ["<", 8, 0], + ["<", 9, 0], + ["<", 10, 0], + ["<", 11, 0], + ["<", 12, 0], + ["<", 13, 0], + ["<", 14, 0], + ["<", 15, 0], + ["<", 16, 0], + ["<", 17, 0], + ["<", 18, 0], + ["<", 19, 0], + ["<", 20, 0], + ["<", 21, 0], + ["<", 22, 0], + ["<", 23, 0], + ["<", 24, 0], + ["<", 25, 0], + ["<", 26, 0], + ["<", 27, 0], + ["<", 28, 0] + ] + # standard:enable Layout/ExtraSpacing + + it_has_behavior "with a #change callback", s1, s2, result + it_has_behavior "without a #change callback", s1, s2, result + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/traverse_sequences_spec.rb b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/traverse_sequences_spec.rb new file mode 100644 index 00000000..8e9928f1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/diff-lcs-1.6.2/spec/traverse_sequences_spec.rb @@ -0,0 +1,137 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "Diff::LCS.traverse_sequences" do + describe "callback with no finishers" do + describe "over (seq1, seq2)" do + before(:each) do + @callback_s1_s2 = simple_callback_no_finishers + Diff::LCS.traverse_sequences(seq1, seq2, @callback_s1_s2) + + @callback_s2_s1 = simple_callback_no_finishers + Diff::LCS.traverse_sequences(seq2, seq1, @callback_s2_s1) + end + + it "has the correct LCS result on left-matches" do + expect(@callback_s1_s2.matched_a).to eq(correct_lcs) + expect(@callback_s2_s1.matched_a).to eq(correct_lcs) + end + + it "has the correct LCS result on right-matches" do + expect(@callback_s1_s2.matched_b).to eq(correct_lcs) + expect(@callback_s2_s1.matched_b).to eq(correct_lcs) + end + + it "has the correct skipped sequences with the left sequence" do + expect(@callback_s1_s2.discards_a).to eq(skipped_seq1) + expect(@callback_s2_s1.discards_a).to eq(skipped_seq2) + end + + it "has the correct skipped sequences with the right sequence" do + expect(@callback_s1_s2.discards_b).to eq(skipped_seq2) + expect(@callback_s2_s1.discards_b).to eq(skipped_seq1) + end + + it "does not have anything done markers from the left or right sequences" do + expect(@callback_s1_s2.done_a).to be_empty + expect(@callback_s1_s2.done_b).to be_empty + expect(@callback_s2_s1.done_a).to be_empty + expect(@callback_s2_s1.done_b).to be_empty + end + end + + describe "over (hello, hello)" do + before(:each) do + @callback = simple_callback_no_finishers + Diff::LCS.traverse_sequences(hello, hello, @callback) + end + + it "has the correct LCS result on left-matches" do + expect(@callback.matched_a).to eq(hello.chars) + end + + it "has the correct LCS result on right-matches" do + expect(@callback.matched_b).to eq(hello.chars) + end + + it "has the correct skipped sequences with the left sequence" do + expect(@callback.discards_a).to be_empty + end + + it "has the correct skipped sequences with the right sequence" do + expect(@callback.discards_b).to be_empty + end + + it "does not have anything done markers from the left or right sequences" do + expect(@callback.done_a).to be_empty + expect(@callback.done_b).to be_empty + end + end + + describe "over (hello_ary, hello_ary)" do + before(:each) do + @callback = simple_callback_no_finishers + Diff::LCS.traverse_sequences(hello_ary, hello_ary, @callback) + end + + it "has the correct LCS result on left-matches" do + expect(@callback.matched_a).to eq(hello_ary) + end + + it "has the correct LCS result on right-matches" do + expect(@callback.matched_b).to eq(hello_ary) + end + + it "has the correct skipped sequences with the left sequence" do + expect(@callback.discards_a).to be_empty + end + + it "has the correct skipped sequences with the right sequence" do + expect(@callback.discards_b).to be_empty + end + + it "does not have anything done markers from the left or right sequences" do + expect(@callback.done_a).to be_empty + expect(@callback.done_b).to be_empty + end + end + end + + describe "callback with finisher" do + before(:each) do + @callback_s1_s2 = simple_callback + Diff::LCS.traverse_sequences(seq1, seq2, @callback_s1_s2) + @callback_s2_s1 = simple_callback + Diff::LCS.traverse_sequences(seq2, seq1, @callback_s2_s1) + end + + it "has the correct LCS result on left-matches" do + expect(@callback_s1_s2.matched_a).to eq(correct_lcs) + expect(@callback_s2_s1.matched_a).to eq(correct_lcs) + end + + it "has the correct LCS result on right-matches" do + expect(@callback_s1_s2.matched_b).to eq(correct_lcs) + expect(@callback_s2_s1.matched_b).to eq(correct_lcs) + end + + it "has the correct skipped sequences for the left sequence" do + expect(@callback_s1_s2.discards_a).to eq(skipped_seq1) + expect(@callback_s2_s1.discards_a).to eq(skipped_seq2) + end + + it "has the correct skipped sequences for the right sequence" do + expect(@callback_s1_s2.discards_b).to eq(skipped_seq2) + expect(@callback_s2_s1.discards_b).to eq(skipped_seq1) + end + + it "has done markers differently-sized sequences" do + expect(@callback_s1_s2.done_a).to eq([["p", 9, "t", 11]]) + expect(@callback_s1_s2.done_b).to be_empty + + expect(@callback_s2_s1.done_a).to be_empty + expect(@callback_s2_s1.done_b).to eq([["t", 11, "p", 9]]) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/.github/dependabot.yml b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/.github/dependabot.yml new file mode 100644 index 00000000..2fd17712 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/.github/dependabot.yml @@ -0,0 +1,15 @@ +version: 2 + +updates: + + # Maintain dependencies for GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + + # Maintain dependencies for Ruby's Bundler + - package-ecosystem: "bundler" + directory: "/" + schedule: + interval: "daily" diff --git a/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/.github/workflows/main.yml b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/.github/workflows/main.yml new file mode 100644 index 00000000..7620e33a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/.github/workflows/main.yml @@ -0,0 +1,42 @@ +name: Main +on: + push: + branches: + - main + pull_request: + branches: + - main +jobs: + test: + name: 'CI Tests' + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + # Due to https://github.com/actions/runner/issues/849, we have to use quotes for '3.0' + ruby: [jruby, 2.7, '3.0', 3.1, 3.2, 3.3, head] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v3.3.0 + + # Conditionally configure bundler via environment variables as advised + # * https://github.com/ruby/setup-ruby#bundle-config + - name: Set bundler environment variables + run: | + echo "BUNDLE_WITHOUT=checks" >> $GITHUB_ENV + if: matrix.ruby != 3.3 + + - uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true + + - run: bundle exec rspec + + - uses: codecov/codecov-action@v3.1.1 + with: + name: ${{ matrix.ruby }} + file: ./coverage/coverage.xml + + - run: bundle exec rubocop + if: matrix.ruby == 3.3 diff --git a/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/.gitignore b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/.gitignore new file mode 100644 index 00000000..b1261eeb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/.gitignore @@ -0,0 +1,11 @@ +*.gem +.bundle +Gemfile.lock +pkg +.idea +doc +.yardoc +coverage +vendor +.ruby-gemset +.ruby-version diff --git a/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/.rspec b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/.rspec new file mode 100644 index 00000000..b3eb8b49 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/.rspec @@ -0,0 +1,2 @@ +--color +--format documentation \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/.rubocop.yml b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/.rubocop.yml new file mode 100644 index 00000000..8bdb76f0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/.rubocop.yml @@ -0,0 +1,5 @@ +inherit_gem: + panolint: panolint-rubocop.yml + +require: + - rubocop-rake \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/.yardopts b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/.yardopts new file mode 100644 index 00000000..735a41e9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/.yardopts @@ -0,0 +1,7 @@ +--title 'Docile Documentation' + +--no-private +--main=README.md + +--markup-provider=redcarpet +--markup=markdown diff --git a/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/Gemfile b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/Gemfile new file mode 100644 index 00000000..43b9e224 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/Gemfile @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +# Specify gem's runtime dependencies in docile.gemspec +gemspec + +group :test do + gem "rspec", "~> 3.10" + gem "simplecov", require: false + + # CI-only test dependencies go here + if ENV.fetch("CI", nil) == "true" + gem "simplecov-cobertura", require: false, group: "test" + end +end + +# Excluded from CI except on latest MRI Ruby, to reduce compatibility burden +group :checks do + gem "panolint", github: "panorama-ed/panolint", branch: "main" +end + +# Optional, only used locally to release to rubygems.org +group :release, optional: true do + gem "rake" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/HISTORY.md b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/HISTORY.md new file mode 100644 index 00000000..ef6781c8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/HISTORY.md @@ -0,0 +1,134 @@ +# HISTORY + +## [Unreleased changes](http://github.com/ms-ati/docile/compare/v1.4.1...main) + +## [v1.4.1 (May 12, 2021)](http://github.com/ms-ati/docile/compare/v1.4.0...v1.4.1) + + - Special thanks to Mamoru TASAKA (@mtasaka): + - Starting point for a fix on the tests to pass on Ruby 3.3 + - Added support for Ruby 3.2 and 3.3 + - Removed support for Rubies below 2.7 + +## [v1.4.0 (May 12, 2021)](http://github.com/ms-ati/docile/compare/v1.3.5...v1.4.0) + + - Special thanks to Matt Schreiber (@tomeon): + - Short-circuit to calling #instance_exec directly on the DSL object (prior to + constructing a proxy object) when the DSL object and block context object are + identical (*Sorry it took over a year to review and merge this!*) + - Renamed default branch from master to main, see: https://github.com/github/renaming + - Temporarily removed YARD doc configuration, to replace after + migration to Github Actions + - Removed support for all EOL Rubies < 2.5 + - Migrated CI from Travis to Github Actions + - Special thanks (again!) to Taichi Ishitani (@taichi-ishitani): + - Use more reliable codecov github action (via simplecov-cobertura) + rather than less reliable codecov gem + - Enable bundle caching in github action setup-ruby + - Added Rubocop, and configured it to run in CI + - Added Dependabot, and configured it to run daily + - Added SECURITY.md for vulnerability reporting policy + +## [v1.3.5 (Jan 13, 2021)](http://github.com/ms-ati/docile/compare/v1.3.4...v1.3.5) + + - Special thanks to Jochen Seeber (@jochenseeber): + - Fix remaining delegation on Ruby 2.7 (PR #62) + - Remove support for Ruby 1.8.7 and REE, because they + [are no longer runnable on Travis CI](https://travis-ci.community/t/ruby-1-8-7-and-ree-builds-broken-by-ssl-certificate-failure/10866) + - Announce that continued support for any EOL Ruby versions (that is, versions + prior to Ruby 2.5 as of Jan 13 2021) will be decided on **Feb 1, 2021** + based on comments to [issue #58](https://github.com/ms-ati/docile/issues/58) + +## [v1.3.4 (Dec 22, 2020)](http://github.com/ms-ati/docile/compare/v1.3.3...v1.3.4) + + - Special thanks to Benoit Daloze (@eregon): + - Fix delegation on Ruby 2.7 (issues #45 and #44, PR #52) + +## [v1.3.3 (Dec 18, 2020)](http://github.com/ms-ati/docile/compare/v1.3.2...v1.3.3) + + - Special thanks (again!) to Taichi Ishitani (@taichi-ishitani): + - Fix keyword arg warnings on Ruby 2.7 (issue #44, PR #45) + - Filter Docile's source files from backtrace (issue #35, PR #36) + +## [v1.3.2 (Jun 12, 2019)](http://github.com/ms-ati/docile/compare/v1.3.1...v1.3.2) + + - Special thanks (again!) to Taichi Ishitani (@taichi-ishitani): + - Fix for DSL object is replaced when #dsl_eval is nested (#33, PR #34) + +## [v1.3.1 (May 24, 2018)](http://github.com/ms-ati/docile/compare/v1.3.0...v1.3.1) + + - Special thanks to Taichi Ishitani (@taichi-ishitani): + - Fix for when DSL object is also the block's context (#30) + +## [v1.3.0 (Feb 7, 2018)](http://github.com/ms-ati/docile/compare/v1.2.0...v1.3.0) + + - Allow helper methods in block's context to call DSL methods + - Add SemVer release policy explicitly + - Standardize on double-quoted string literals + - Workaround some more Travis CI shenanigans + +## [v1.2.0 (Jan 11, 2018)](http://github.com/ms-ati/docile/compare/v1.1.5...v1.2.0) + + - Special thanks to Christina Koller (@cmkoller) + - add DSL evaluation returning *return value of the block* (see `.dsl_eval_with_block_return`) + - add an example to README + - keep travis builds passing on old ruby versions + +## [v1.1.5 (Jun 15, 2014)](http://github.com/ms-ati/docile/compare/v1.1.4...v1.1.5) + + - as much as possible, loosen version restrictions on development dependencies + - clarify gemspec settings as much as possible + - bump rspec dependency to 3.0.x + +## [v1.1.4 (Jun 11, 2014)](http://github.com/ms-ati/docile/compare/v1.1.3...v1.1.4) + + - Special thanks to Ken Dreyer (@ktdreyer): + - make simplecov/coveralls optional for running tests \[[33834852c7](https://github.com/ms-ati/docile/commit/33834852c7849912b97e109e8c5c193579cc5e98)\] + - update URL in gemspec \[[174e654a07](https://github.com/ms-ati/docile/commit/174e654a075c8350b3411b212cfb409bc605348a)\] + +## [v1.1.3 (Feb 4, 2014)](http://github.com/ms-ati/docile/compare/v1.1.2...v1.1.3) + + - Special thanks to Alexey Vasiliev (@le0pard): + - fix problem to catch NoMethodError from non receiver object + - upgrade rspec format to new "expect" syntax + +## [v1.1.2 (Jan 10, 2014)](http://github.com/ms-ati/docile/compare/v1.1.1...v1.1.2) + + - remove unnecessarily nested proxy objects (thanks @Ajedi32)! + - documentation updates and corrections + +## [v1.1.1 (Nov 26, 2013)](http://github.com/ms-ati/docile/compare/v1.1.0...v1.1.1) + + - documentation updates and corrections + - fix Rubinius build in Travis CI + +## [v1.1.0 (Jul 29, 2013)](http://github.com/ms-ati/docile/compare/v1.0.5...v1.1.0) + + - add functional-style DSL objects via `Docile#dsl_eval_immutable` + +## [v1.0.5 (Jul 28, 2013)](http://github.com/ms-ati/docile/compare/v1.0.4...v1.0.5) + + - achieve 100% yard docs coverage + - fix rendering of docs at http://rubydoc.info/gems/docile + +## [v1.0.4 (Jul 25, 2013)](http://github.com/ms-ati/docile/compare/v1.0.3...v1.0.4) + + - simplify and clarify code + - fix a minor bug where FallbackContextProxy#instance_variables would return + symbols rather than strings on Ruby 1.8.x + +## [v1.0.3 (Jul 6, 2013)](http://github.com/ms-ati/docile/compare/v1.0.2...v1.0.3) + + - instrument code coverage via SimpleCov and publish to Coveralls.io + +## [v1.0.2 (Apr 1, 2013)](http://github.com/ms-ati/docile/compare/v1.0.1...v1.0.2) + + - allow passing parameters to DSL blocks (thanks @dslh!) + +## [v1.0.1 (Nov 29, 2012)](http://github.com/ms-ati/docile/compare/v1.0.0...v1.0.1) + + - relaxed rspec and rake dependencies to allow newer versions + - fixes to documentation + +## [v1.0.0 (Oct 29, 2012)](http://github.com/ms-ati/docile/compare/1b225c8a27...v1.0.0) + + - Initial Feature Set diff --git a/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/LICENSE b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/LICENSE new file mode 100644 index 00000000..b8967f95 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2012-2024 Marc Siegel + +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 +AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/README.md b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/README.md new file mode 100644 index 00000000..fe095a40 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/README.md @@ -0,0 +1,409 @@ +# Docile + +[![Gem Version](https://img.shields.io/gem/v/docile.svg)](https://rubygems.org/gems/docile) +[![Gem Downloads](https://img.shields.io/gem/dt/docile.svg)](https://rubygems.org/gems/docile) + +[![Join the chat at https://gitter.im/ms-ati/docile](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ms-ati/docile?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](http://rubydoc.info/github/ms-ati/docile) + +[![Build Status](https://github.com/ms-ati/docile/actions/workflows/main.yml/badge.svg)](https://github.com/ms-ati/docile/actions/workflows/main.yml) +[![Code Coverage](https://img.shields.io/codecov/c/github/ms-ati/docile.svg)](https://codecov.io/github/ms-ati/docile) +[![Maintainability](https://api.codeclimate.com/v1/badges/79ca631bc123f7b83b34/maintainability)](https://codeclimate.com/github/ms-ati/docile/maintainability) + +Ruby makes it possible to create very expressive **Domain Specific +Languages**, or **DSL**'s for short. However, it requires some deep knowledge and +somewhat hairy meta-programming to get the interface just right. + +"Docile" means *Ready to accept control or instruction; submissive* [[1]] + +Instead of each Ruby project reinventing this wheel, let's make our Ruby DSL +coding a bit more docile... + +[1]: http://www.google.com/search?q=docile+definition "Google" + +## Usage + +### Basic: Ruby [Array](http://ruby-doc.org/core-3.0.0/Array.html) as DSL + +Let's say that we want to make a DSL for modifying Array objects. +Wouldn't it be great if we could just treat the methods of Array as a DSL? + +```ruby +with_array([]) do + push 1 + push 2 + pop + push 3 +end +#=> [1, 3] +``` + +No problem, just define the method `with_array` like this: + +```ruby +def with_array(arr=[], &block) + Docile.dsl_eval(arr, &block) +end +``` + +Easy! + +### Next step: Allow helper methods to call DSL methods + +What if, in our use of the methods of Array as a DSL, we want to extract +helper methods which in turn call DSL methods? + +```ruby +def pop_sum_and_push(n) + sum = 0 + n.times { sum += pop } + push sum +end + +Docile.dsl_eval([]) do + push 5 + push 6 + pop_sum_and_push(2) +end +#=> [11] +``` + +Without Docile, you may find this sort of code extraction to be more +challenging. + +### Wait! Can't I do that with just `instance_eval` or `instance_exec`? + +Good question! + +In short: **No**. + +Not if you want the code in the block to be able to refer to anything +the block would normally have access to from the surrounding context. + +Let's be very specific. Docile internally uses `instance_exec` (see [execution.rb#26](lib/docile/execution.rb#L26)), adding a small layer to support referencing *local variables*, *instance variables*, and *methods* from the _block's context_ **or** the target _object's context_, interchangeably. This is "**the hard part**", where most folks making a DSL in Ruby throw up their hands. + +For example: + +```ruby +class ContextOfBlock + def example_of_contexts + @block_instance_var = 1 + block_local_var = 2 + + with_array do + push @block_instance_var + push block_local_var + pop + push block_sees_this_method + end + end + + def block_sees_this_method + 3 + end + + def with_array(&block) + { + docile: Docile.dsl_eval([], &block), + instance_eval: ([].instance_eval(&block) rescue $!), + instance_exec: ([].instance_exec(&block) rescue $!) + } + end +end + +ContextOfBlock.new.example_of_contexts +#=> { + :docile=>[1, 3], + :instance_eval=>#, + :instance_exec=># + } +``` + +As you can see, it won't be possible to call methods or access instance variables defined in the block's context using just the raw `instance_eval` or `instance_exec` methods. And in fact, Docile goes further, making it easy to maintain this support even in multi-layered DSLs. + +### Build a Pizza + +Mutating (changing) an Array instance is fine, but what usually makes a good DSL is a [Builder Pattern][2]. + +For example, let's say you want a DSL to specify how you want to build a Pizza: + +```ruby +@sauce_level = :extra + +pizza do + cheese + pepperoni + sauce @sauce_level +end +#=> # +``` + +And let's say we have a PizzaBuilder, which builds a Pizza like this: + +```ruby +Pizza = Struct.new(:cheese, :pepperoni, :bacon, :sauce) + +class PizzaBuilder + def cheese(v=true); @cheese = v; self; end + def pepperoni(v=true); @pepperoni = v; self; end + def bacon(v=true); @bacon = v; self; end + def sauce(v=nil); @sauce = v; self; end + def build + Pizza.new(!!@cheese, !!@pepperoni, !!@bacon, @sauce) + end +end + +PizzaBuilder.new.cheese.pepperoni.sauce(:extra).build +#=> # +``` + +Then implement your DSL like this: + +```ruby +def pizza(&block) + Docile.dsl_eval(PizzaBuilder.new, &block).build +end +``` + +It's just that easy! + +[2]: http://stackoverflow.com/questions/328496/when-would-you-use-the-builder-pattern "Builder Pattern" + +### Multi-level and Recursive DSLs + +Docile is a very easy way to write a multi-level DSL in Ruby, even for +a [recursive data structure such as a tree][4]: + +```ruby +Person = Struct.new(:name, :mother, :father) + +person { + name 'John Smith' + mother { + name 'Mary Smith' + } + father { + name 'Tom Smith' + mother { + name 'Jane Smith' + } + } +} + +#=> #, +# father=#, +# father=nil>> +``` + +See the full [person tree example][4] for details. + +[4]: https://gist.github.com/ms-ati/2bb17bdf10a430faba98 + +### Block parameters + +Parameters can be passed to the DSL block. + +Supposing you want to make some sort of cheap [Sinatra][3] knockoff: + +```ruby +@last_request = nil +respond '/path' do |request| + puts "Request received: #{request}" + @last_request = request +end + +def ride bike + # Play with your new bike +end + +respond '/new_bike' do |bike| + ride(bike) +end +``` + +You'd put together a dispatcher something like this: + +```ruby +require 'singleton' + +class DispatchScope + def a_method_you_can_call_from_inside_the_block + :useful_huh? + end +end + +class MessageDispatch + include Singleton + + def initialize + @responders = {} + end + + def add_responder path, &block + @responders[path] = block + end + + def dispatch path, request + Docile.dsl_eval(DispatchScope.new, request, &@responders[path]) + end +end + +def respond path, &handler + MessageDispatch.instance.add_responder path, handler +end + +def send_request path, request + MessageDispatch.instance.dispatch path, request +end +``` + +[3]: http://www.sinatrarb.com "Sinatra" + +### Functional-Style Immutable DSL Objects + +Sometimes, you want to use an object as a DSL, but it doesn't quite fit the +[imperative](http://en.wikipedia.org/wiki/Imperative_programming) pattern shown +above. + +Instead of methods like +[Array#push](http://www.ruby-doc.org/core-3.0.0/Array.html#method-i-push), which +modifies the object at hand, it has methods like +[String#reverse](http://www.ruby-doc.org/core-3.0.0/String.html#method-i-reverse), +which returns a new object without touching the original. Perhaps it's even +[frozen](http://www.ruby-doc.org/core-3.0.0/Object.html#method-i-freeze) in +order to enforce [immutability](http://en.wikipedia.org/wiki/Immutable_object). + +Wouldn't it be great if we could just treat these methods as a DSL as well? + +```ruby +s = "I'm immutable!".freeze + +with_immutable_string(s) do + reverse + upcase +end +#=> "!ELBATUMMI M'I" + +s +#=> "I'm immutable!" +``` + +No problem, just define the method `with_immutable_string` like this: + +```ruby +def with_immutable_string(str="", &block) + Docile.dsl_eval_immutable(str, &block) +end +``` + +All set! + +### Accessing the block's return value + +Sometimes you might want to access the return value of your provided block, +as opposed to the DSL object itself. In these cases, use +`dsl_eval_with_block_return`. It behaves exactly like `dsl_eval`, but returns +the output from executing the block, rather than the DSL object. + +```ruby +arr = [] +with_array(arr) do + push "a" + push "b" + push "c" + length +end +#=> 3 + +arr +#=> ["a", "b", "c"] +``` + +```ruby +def with_array(arr=[], &block) + Docile.dsl_eval_with_block_return(arr, &block) +end +``` + +## Features + + 1. Method lookup falls back from the DSL object to the block's context + 2. Local variable lookup falls back from the DSL object to the block's + context + 3. Instance variables are from the block's context only + 4. Nested DSL evaluation, correctly chaining method and variable handling + from the inner to the outer DSL scopes + 5. Alternatives for both imperative and functional styles of DSL objects + +## Installation + +``` bash +$ gem install docile +``` + +## Links +* [Source](https://github.com/ms-ati/docile) +* [Documentation](http://rubydoc.info/gems/docile) +* [Bug Tracker](https://github.com/ms-ati/docile/issues) + +## Status + +Works on [all currently supported ruby versions](https://github.com/ms-ati/docile/blob/master/.github/workflows/main.yml), +or so [Github Actions](https://github.com/ms-ati/docile/actions) +tells us. + +Used by some pretty cool gems to implement their DSLs, notably including +[SimpleCov](https://github.com/colszowka/simplecov). Keep an eye out for new +gems using Docile at the +[Ruby Toolbox](https://www.ruby-toolbox.com/projects/docile). + +## Release Policy + +Docile releases follow +[Semantic Versioning 2.0.0](https://semver.org/spec/v2.0.0.html). + +## Note on Patches/Pull Requests + + * Fork the project. + * Setup your development environment with: + `gem install bundler; bundle install` + * Make your feature addition or bug fix. + * Add tests for it. This is important so I don't break it in a future version + unintentionally. + * Commit, do not mess with rakefile, version, or history. + (if you want to have your own version, that is fine but bump version in a + commit by itself I can ignore when I pull) + * Send me a pull request. Bonus points for topic branches. + +## Releasing + +To make a new release of `Docile` to +[RubyGems](https://rubygems.org/gems/docile), first install the release +dependencies (e.g. `rake`) as follows: + +```shell +bundle config set --local with 'release' +bundle install +``` + +Then carry out these steps: + +1. Update `HISTORY.md`: + - Add an entry for the upcoming version _x.y.z_ + - Move content from _Unreleased_ to the upcoming version _x.y.z_ + - Commit with title `Update HISTORY.md for x.y.z` + +2. Update `lib/docile/version.rb` + - Replace with upcoming version _x.y.z_ + - Commit with title `Bump version to x.y.z` + +3. `bundle exec rake release` + +## Copyright & License + +Copyright (c) 2012-2024 Marc Siegel. + +Licensed under the [MIT License](http://choosealicense.com/licenses/mit/), +see [LICENSE](LICENSE) for details. diff --git a/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/Rakefile b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/Rakefile new file mode 100644 index 00000000..83e2b671 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/Rakefile @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require "rake/clean" +require "bundler/gem_tasks" +require "rspec/core/rake_task" + +# Default task for `rake` is to run rspec +task default: [:spec] + +# Use default rspec rake task +RSpec::Core::RakeTask.new + +# Configure `rake clobber` to delete all generated files +CLOBBER.include("pkg", "doc", "coverage") diff --git a/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/SECURITY.md b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/SECURITY.md new file mode 100644 index 00000000..947561c0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/SECURITY.md @@ -0,0 +1,19 @@ +# Security Policy + +## Supported Versions + +Use this section to tell people about which versions of your project are +currently being supported with security updates. + +| Version | Supported | +| ------- | ------------------ | +| 1.4.x | :white_check_mark: | +| 1.3.x | :white_check_mark: | +| < 1.3 | :x: | + +## Reporting a Vulnerability + +At this time, security issues and vulnerabilities in Docile should +be reported like any other issue. Please create an issue in the +[public issue tracker](https://github.com/ms-ati/docile/issues) on +Github. diff --git a/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/docile.gemspec b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/docile.gemspec new file mode 100644 index 00000000..22302652 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/docile.gemspec @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require_relative "lib/docile/version" + +Gem::Specification.new do |s| + s.name = "docile" + s.version = Docile::VERSION + s.author = "Marc Siegel" + s.email = "marc@usainnov.com" + s.homepage = "https://ms-ati.github.io/docile/" + s.summary = "Docile keeps your Ruby DSLs tame and well-behaved." + s.description = "Docile treats the methods of a given ruby object as a DSL "\ + "(domain specific language) within a given block. \n\n"\ + "Killer feature: you can also reference methods, instance "\ + "variables, and local variables from the original (non-DSL) "\ + "context within the block. \n\n"\ + "Docile releases follow Semantic Versioning as defined at "\ + "semver.org." + s.license = "MIT" + + # Specify oldest supported Ruby version (2.5 to support JRuby 9.2.17.0) + s.required_ruby_version = ">= 2.5.0" + + # Files included in the gem + s.files = `git ls-files -z`.split("\x0").reject do |f| + f.match(%r{^(test|spec|features)/}) + end + s.require_paths = ["lib"] + + s.metadata = { + "homepage_uri" => "https://ms-ati.github.io/docile/", + "changelog_uri" => "https://github.com/ms-ati/docile/blob/main/HISTORY.md", + "source_code_uri" => "https://github.com/ms-ati/docile", + "rubygems_mfa_required" => "true", + } +end diff --git a/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/lib/docile.rb b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/lib/docile.rb new file mode 100644 index 00000000..90e6e840 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/lib/docile.rb @@ -0,0 +1,134 @@ +# frozen_string_literal: true + +require "docile/version" +require "docile/execution" +require "docile/fallback_context_proxy" +require "docile/chaining_fallback_context_proxy" +require "docile/backtrace_filter" + +# Docile keeps your Ruby DSLs tame and well-behaved. +module Docile + extend Execution + + # Execute a block in the context of an object whose methods represent the + # commands in a DSL. + # + # @note Use with an *imperative* DSL (commands modify the context object) + # + # Use this method to execute an *imperative* DSL, which means that: + # + # 1. Each command mutates the state of the DSL context object + # 2. The return value of each command is ignored + # 3. The final return value is the original context object + # + # @example Use a String as a DSL + # Docile.dsl_eval("Hello, world!") do + # reverse! + # upcase! + # end + # #=> "!DLROW ,OLLEH" + # + # @example Use an Array as a DSL + # Docile.dsl_eval([]) do + # push 1 + # push 2 + # pop + # push 3 + # end + # #=> [1, 3] + # + # @param dsl [Object] context object whose methods make up the DSL + # @param args [Array] arguments to be passed to the block + # @param block [Proc] the block of DSL commands to be executed against the + # `dsl` context object + # @return [Object] the `dsl` context object after executing the block + def dsl_eval(dsl, *args, &block) + exec_in_proxy_context(dsl, FallbackContextProxy, *args, &block) + dsl + end + + ruby2_keywords :dsl_eval if respond_to?(:ruby2_keywords, true) + module_function :dsl_eval + + # Execute a block in the context of an object whose methods represent the + # commands in a DSL, and return *the block's return value*. + # + # @note Use with an *imperative* DSL (commands modify the context object) + # + # Use this method to execute an *imperative* DSL, which means that: + # + # 1. Each command mutates the state of the DSL context object + # 2. The return value of each command is ignored + # 3. The final return value is the original context object + # + # @example Use a String as a DSL + # Docile.dsl_eval_with_block_return("Hello, world!") do + # reverse! + # upcase! + # first + # end + # #=> "!" + # + # @example Use an Array as a DSL + # Docile.dsl_eval_with_block_return([]) do + # push "a" + # push "b" + # pop + # push "c" + # length + # end + # #=> 2 + # + # @param dsl [Object] context object whose methods make up the DSL + # @param args [Array] arguments to be passed to the block + # @param block [Proc] the block of DSL commands to be executed against the + # `dsl` context object + # @return [Object] the return value from executing the block + def dsl_eval_with_block_return(dsl, *args, &block) + exec_in_proxy_context(dsl, FallbackContextProxy, *args, &block) + end + + if respond_to?(:ruby2_keywords, true) + ruby2_keywords :dsl_eval_with_block_return + end + module_function :dsl_eval_with_block_return + + # Execute a block in the context of an immutable object whose methods, + # and the methods of their return values, represent the commands in a DSL. + # + # @note Use with a *functional* DSL (commands return successor + # context objects) + # + # Use this method to execute a *functional* DSL, which means that: + # + # 1. The original DSL context object is never mutated + # 2. Each command returns the next DSL context object + # 3. The final return value is the value returned by the last command + # + # @example Use a frozen String as a DSL + # Docile.dsl_eval_immutable("I'm immutable!".freeze) do + # reverse + # upcase + # end + # #=> "!ELBATUMMI M'I" + # + # @example Use a Float as a DSL + # Docile.dsl_eval_immutable(84.5) do + # fdiv(2) + # floor + # end + # #=> 42 + # + # @param dsl [Object] immutable context object whose methods make up the + # initial DSL + # @param args [Array] arguments to be passed to the block + # @param block [Proc] the block of DSL commands to be executed against the + # `dsl` context object and successor return values + # @return [Object] the return value of the final command in the block + def dsl_eval_immutable(dsl, *args, &block) + exec_in_proxy_context(dsl, ChainingFallbackContextProxy, *args, &block) + end + + ruby2_keywords :dsl_eval_immutable if respond_to?(:ruby2_keywords, true) + module_function :dsl_eval_immutable +end diff --git a/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/lib/docile/backtrace_filter.rb b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/lib/docile/backtrace_filter.rb new file mode 100644 index 00000000..06a66058 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/lib/docile/backtrace_filter.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Docile + # @api private + # + # This is used to remove entries pointing to Docile's source files + # from {Exception#backtrace} and {Exception#backtrace_locations}. + # + # If {NoMethodError} is caught then the exception object will be extended + # by this module to add filter functionalities. + module BacktraceFilter + FILTER_PATTERN = %r{/lib/docile/}.freeze + + def backtrace + super.grep_v(FILTER_PATTERN) + end + + if ::Exception.public_method_defined?(:backtrace_locations) + def backtrace_locations + super.reject { |location| location.absolute_path =~ FILTER_PATTERN } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/lib/docile/chaining_fallback_context_proxy.rb b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/lib/docile/chaining_fallback_context_proxy.rb new file mode 100644 index 00000000..3bc52e61 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/lib/docile/chaining_fallback_context_proxy.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require "docile/fallback_context_proxy" + +module Docile + # @api private + # + # Operates in the same manner as {FallbackContextProxy}, but replacing + # the primary `receiver` object with the result of each proxied method. + # + # This is useful for implementing DSL evaluation for immutable context + # objects. + # + # @see Docile.dsl_eval_immutable + # + # rubocop:disable Style/MissingRespondToMissing + class ChainingFallbackContextProxy < FallbackContextProxy + # Proxy methods as in {FallbackContextProxy#method_missing}, replacing + # `receiver` with the returned value. + def method_missing(method, *args, &block) + @__receiver__ = super + end + + ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true) + end + # rubocop:enable Style/MissingRespondToMissing +end diff --git a/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/lib/docile/execution.rb b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/lib/docile/execution.rb new file mode 100644 index 00000000..e8a64084 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/lib/docile/execution.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +module Docile + # @api private + # + # A namespace for functions relating to the execution of a block against a + # proxy object. + module Execution + # Execute a block in the context of an object whose methods represent the + # commands in a DSL, using a specific proxy class. + # + # @param dsl [Object] context object whose methods make up the + # (initial) DSL + # @param proxy_type [FallbackContextProxy, ChainingFallbackContextProxy] + # which class to instantiate as proxy context + # @param args [Array] arguments to be passed to the block + # @param block [Proc] the block of DSL commands to be executed + # @return [Object] the return value of the block + def exec_in_proxy_context(dsl, proxy_type, *args, &block) + block_context = eval("self", block.binding) # rubocop:disable Style/EvalWithLocation + + # Use #equal? to test strict object identity (assuming that this dictum + # from the Ruby docs holds: "[u]nlike ==, the equal? method should never + # be overridden by subclasses as it is used to determine object + # identity") + return dsl.instance_exec(*args, &block) if dsl.equal?(block_context) + + proxy_context = proxy_type.new(dsl, block_context) + begin + block_context.instance_variables.each do |ivar| + value_from_block = block_context.instance_variable_get(ivar) + proxy_context.instance_variable_set(ivar, value_from_block) + end + + proxy_context.instance_exec(*args, &block) + ensure + if block_context.respond_to?(:__docile_undo_fallback__) + block_context.send(:__docile_undo_fallback__) + end + + block_context.instance_variables.each do |ivar| + next unless proxy_context.instance_variables.include?(ivar) + + value_from_dsl_proxy = proxy_context.instance_variable_get(ivar) + block_context.instance_variable_set(ivar, value_from_dsl_proxy) + end + end + end + + ruby2_keywords :exec_in_proxy_context if respond_to?(:ruby2_keywords, true) + module_function :exec_in_proxy_context + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/lib/docile/fallback_context_proxy.rb b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/lib/docile/fallback_context_proxy.rb new file mode 100644 index 00000000..18a2e0ea --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/lib/docile/fallback_context_proxy.rb @@ -0,0 +1,107 @@ +# frozen_string_literal: true + +require "set" + +module Docile + # @api private + # + # A proxy object with a primary receiver as well as a secondary + # fallback receiver. + # + # Will attempt to forward all method calls first to the primary receiver, + # and then to the fallback receiver if the primary does not handle that + # method. + # + # This is useful for implementing DSL evaluation in the context of an object. + # + # @see Docile.dsl_eval + # + # rubocop:disable Style/MissingRespondToMissing + class FallbackContextProxy + # The set of methods which will **not** be proxied, but instead answered + # by this object directly. + NON_PROXIED_METHODS = Set[:__send__, :object_id, :__id__, :==, :equal?, + :!, :!=, :instance_exec, :instance_variables, + :instance_variable_get, :instance_variable_set, + :remove_instance_variable] + + # The set of methods which will **not** fallback from the block's context + # to the dsl object. + NON_FALLBACK_METHODS = Set[:class, :self, :respond_to?, :instance_of?] + + # The set of instance variables which are local to this object and hidden. + # All other instance variables will be copied in and out of this object + # from the scope in which this proxy was created. + NON_PROXIED_INSTANCE_VARIABLES = Set[:@__receiver__, :@__fallback__] + + # Undefine all instance methods except those in {NON_PROXIED_METHODS} + instance_methods.each do |method| + undef_method(method) unless NON_PROXIED_METHODS.include?(method.to_sym) + end + + # @param [Object] receiver the primary proxy target to which all methods + # initially will be forwarded + # @param [Object] fallback the fallback proxy target to which any methods + # not handled by `receiver` will be forwarded + def initialize(receiver, fallback) + @__receiver__ = receiver + @__fallback__ = fallback + + # Enables calling DSL methods from helper methods in the block's context + unless fallback.respond_to?(:method_missing) + # NOTE: We could switch to {#define_singleton_method} on current Rubies + singleton_class = (class << fallback; self; end) + + # instrument {#method_missing} on the block's context to fallback to + # the DSL object. This allows helper methods in the block's context to + # contain calls to methods on the DSL object. + singleton_class. + send(:define_method, :method_missing) do |method, *args, &block| + m = method.to_sym + if !NON_FALLBACK_METHODS.member?(m) && + !fallback.respond_to?(m) && + receiver.respond_to?(m) + receiver.__send__(method.to_sym, *args, &block) + else + super(method, *args, &block) + end + end + + if singleton_class.respond_to?(:ruby2_keywords, true) + singleton_class.send(:ruby2_keywords, :method_missing) + end + + # instrument a helper method to remove the above instrumentation + singleton_class. + send(:define_method, :__docile_undo_fallback__) do + singleton_class.send(:remove_method, :method_missing) + singleton_class.send(:remove_method, :__docile_undo_fallback__) + end + end + end + + # @return [Array] Instance variable names, excluding + # {NON_PROXIED_INSTANCE_VARIABLES} + def instance_variables + super.reject { |v| NON_PROXIED_INSTANCE_VARIABLES.include?(v) } + end + + # Proxy all methods, excluding {NON_PROXIED_METHODS}, first to `receiver` + # and then to `fallback` if not found. + def method_missing(method, *args, &block) + if @__receiver__.respond_to?(method.to_sym) + @__receiver__.__send__(method.to_sym, *args, &block) + else + begin + @__fallback__.__send__(method.to_sym, *args, &block) + rescue NoMethodError => e + e.extend(BacktraceFilter) + raise e + end + end + end + + ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true) + end + # rubocop:enable Style/MissingRespondToMissing +end diff --git a/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/lib/docile/version.rb b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/lib/docile/version.rb new file mode 100644 index 00000000..ba8d178a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/docile-1.4.1/lib/docile/version.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +module Docile + # The current version of this library + VERSION = "1.4.1" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/LICENSE.txt b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/LICENSE.txt new file mode 100644 index 00000000..a009caef --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/drb.gemspec b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/drb.gemspec new file mode 100644 index 00000000..40f16697 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/drb.gemspec @@ -0,0 +1,42 @@ +begin + require_relative "lib/drb/version" +rescue LoadError # Fallback to load version file in ruby core repository + require_relative "version" +end + +Gem::Specification.new do |spec| + spec.name = "drb" + spec.version = DRb::VERSION + spec.authors = ["Masatoshi SEKI"] + spec.email = ["seki@ruby-lang.org"] + + spec.summary = %q{Distributed object system for Ruby} + spec.description = %q{Distributed object system for Ruby} + spec.homepage = "https://github.com/ruby/drb" + spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0") + spec.licenses = ["Ruby", "BSD-2-Clause"] + + spec.metadata["homepage_uri"] = spec.homepage + spec.metadata["source_code_uri"] = spec.homepage + spec.metadata["changelog_uri"] = + "#{spec.homepage}/releases/tag/v#{spec.version}" + + spec.files = %w[ + LICENSE.txt + drb.gemspec + lib/drb.rb + lib/drb/acl.rb + lib/drb/drb.rb + lib/drb/eq.rb + lib/drb/extserv.rb + lib/drb/extservm.rb + lib/drb/gw.rb + lib/drb/observer.rb + lib/drb/ssl.rb + lib/drb/timeridconv.rb + lib/drb/unix.rb + lib/drb/version.rb + lib/drb/weakidconv.rb + ] + spec.require_paths = ["lib"] +end diff --git a/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb.rb b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb.rb new file mode 100644 index 00000000..2bb4716f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: false +require 'drb/drb' + diff --git a/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/acl.rb b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/acl.rb new file mode 100644 index 00000000..b004656f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/acl.rb @@ -0,0 +1,239 @@ +# frozen_string_literal: false +# Copyright (c) 2000,2002,2003 Masatoshi SEKI +# +# acl.rb is copyrighted free software by Masatoshi SEKI. +# You can redistribute it and/or modify it under the same terms as Ruby. + +require 'ipaddr' + +## +# Simple Access Control Lists. +# +# Access control lists are composed of "allow" and "deny" halves to control +# access. Use "all" or "*" to match any address. To match a specific address +# use any address or address mask that IPAddr can understand. +# +# Example: +# +# list = %w[ +# deny all +# allow 192.168.1.1 +# allow ::ffff:192.168.1.2 +# allow 192.168.1.3 +# ] +# +# # From Socket#peeraddr, see also ACL#allow_socket? +# addr = ["AF_INET", 10, "lc630", "192.168.1.3"] +# +# acl = ACL.new +# p acl.allow_addr?(addr) # => true +# +# acl = ACL.new(list, ACL::DENY_ALLOW) +# p acl.allow_addr?(addr) # => true + +class ACL + + ## + # The current version of ACL + + VERSION=["2.0.0"] + + ## + # An entry in an ACL + + class ACLEntry + + ## + # Creates a new entry using +str+. + # + # +str+ may be "*" or "all" to match any address, an IP address string + # to match a specific address, an IP address mask per IPAddr, or one + # containing "*" to match part of an IPv4 address. + # + # IPAddr::InvalidPrefixError may be raised when an IP network + # address with an invalid netmask/prefix is given. + + def initialize(str) + if str == '*' or str == 'all' + @pat = [:all] + elsif str.include?('*') + @pat = [:name, dot_pat(str)] + else + begin + @pat = [:ip, IPAddr.new(str)] + rescue IPAddr::InvalidPrefixError + # In this case, `str` shouldn't be a host name pattern + # because it contains a slash. + raise + rescue ArgumentError + @pat = [:name, dot_pat(str)] + end + end + end + + private + + ## + # Creates a regular expression to match IPv4 addresses + + def dot_pat_str(str) + list = str.split('.').collect { |s| + (s == '*') ? '.+' : s + } + list.join("\\.") + end + + private + + ## + # Creates a Regexp to match an address. + + def dot_pat(str) + /\A#{dot_pat_str(str)}\z/ + end + + public + + ## + # Matches +addr+ against this entry. + + def match(addr) + case @pat[0] + when :all + true + when :ip + begin + ipaddr = IPAddr.new(addr[3]) + ipaddr = ipaddr.ipv4_mapped if @pat[1].ipv6? && ipaddr.ipv4? + rescue ArgumentError + return false + end + (@pat[1].include?(ipaddr)) ? true : false + when :name + (@pat[1] =~ addr[2]) ? true : false + else + false + end + end + end + + ## + # A list of ACLEntry objects. Used to implement the allow and deny halves + # of an ACL + + class ACLList + + ## + # Creates an empty ACLList + + def initialize + @list = [] + end + + public + + ## + # Matches +addr+ against each ACLEntry in this list. + + def match(addr) + @list.each do |e| + return true if e.match(addr) + end + false + end + + public + + ## + # Adds +str+ as an ACLEntry in this list + + def add(str) + @list.push(ACLEntry.new(str)) + end + + end + + ## + # Default to deny + + DENY_ALLOW = 0 + + ## + # Default to allow + + ALLOW_DENY = 1 + + ## + # Creates a new ACL from +list+ with an evaluation +order+ of DENY_ALLOW or + # ALLOW_DENY. + # + # An ACL +list+ is an Array of "allow" or "deny" and an address or address + # mask or "all" or "*" to match any address: + # + # %w[ + # deny all + # allow 192.0.2.2 + # allow 192.0.2.128/26 + # ] + + def initialize(list=nil, order = DENY_ALLOW) + @order = order + @deny = ACLList.new + @allow = ACLList.new + install_list(list) if list + end + + public + + ## + # Allow connections from Socket +soc+? + + def allow_socket?(soc) + allow_addr?(soc.peeraddr) + end + + public + + ## + # Allow connections from addrinfo +addr+? It must be formatted like + # Socket#peeraddr: + # + # ["AF_INET", 10, "lc630", "192.0.2.1"] + + def allow_addr?(addr) + case @order + when DENY_ALLOW + return true if @allow.match(addr) + return false if @deny.match(addr) + return true + when ALLOW_DENY + return false if @deny.match(addr) + return true if @allow.match(addr) + return false + else + false + end + end + + public + + ## + # Adds +list+ of ACL entries to this ACL. + + def install_list(list) + i = 0 + while i < list.size + permission, domain = list.slice(i,2) + case permission.downcase + when 'allow' + @allow.add(domain) + when 'deny' + @deny.add(domain) + else + raise "Invalid ACL entry #{list}" + end + i += 2 + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/drb.rb b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/drb.rb new file mode 100644 index 00000000..8073ac09 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/drb.rb @@ -0,0 +1,1993 @@ +# frozen_string_literal: false +# +# = drb/drb.rb +# +# Distributed Ruby: _dRuby_ +# +# Copyright (c) 1999-2003 Masatoshi SEKI. You can redistribute it and/or +# modify it under the same terms as Ruby. +# +# Author:: Masatoshi SEKI +# +# Documentation:: William Webber (william@williamwebber.com) +# +# == Overview +# +# dRuby is a distributed object system for Ruby. It allows an object in one +# Ruby process to invoke methods on an object in another Ruby process on the +# same or a different machine. +# +# The Ruby standard library contains the core classes of the dRuby package. +# However, the full package also includes access control lists and the +# Rinda tuple-space distributed task management system, as well as a +# large number of samples. The full dRuby package can be downloaded from +# the dRuby home page (see *References*). +# +# For an introduction and examples of usage see the documentation to the +# DRb module. +# +# == References +# +# [http://www2a.biglobe.ne.jp/~seki/ruby/druby.html] +# The dRuby home page, in Japanese. Contains the full dRuby package +# and links to other Japanese-language sources. +# +# [http://www2a.biglobe.ne.jp/~seki/ruby/druby.en.html] +# The English version of the dRuby home page. +# +# [https://web.archive.org/web/20160611151955/https://pragprog.com/book/sidruby/the-druby-book] +# The dRuby Book: Distributed and Parallel Computing with Ruby +# by Masatoshi Seki and Makoto Inoue +# +# [http://ruby-doc.com/docs/ProgrammingRuby/html/ospace.html] +# The chapter from *Programming* *Ruby* by Dave Thomas and Andy Hunt +# which discusses dRuby. +# +# [http://www.clio.ne.jp/home/web-i31s/Flotuard/Ruby/PRC2K_seki/dRuby.en.html] +# Translation of presentation on Ruby by Masatoshi Seki. + +require 'socket' +require 'io/wait' +require 'monitor' +require_relative 'eq' +require_relative 'version' + +# +# == Overview +# +# dRuby is a distributed object system for Ruby. It is written in +# pure Ruby and uses its own protocol. No add-in services are needed +# beyond those provided by the Ruby runtime, such as TCP sockets. It +# does not rely on or interoperate with other distributed object +# systems such as CORBA, RMI, or .NET. +# +# dRuby allows methods to be called in one Ruby process upon a Ruby +# object located in another Ruby process, even on another machine. +# References to objects can be passed between processes. Method +# arguments and return values are dumped and loaded in marshalled +# format. All of this is done transparently to both the caller of the +# remote method and the object that it is called upon. +# +# An object in a remote process is locally represented by a +# DRb::DRbObject instance. This acts as a sort of proxy for the +# remote object. Methods called upon this DRbObject instance are +# forwarded to its remote object. This is arranged dynamically at run +# time. There are no statically declared interfaces for remote +# objects, such as CORBA's IDL. +# +# dRuby calls made into a process are handled by a DRb::DRbServer +# instance within that process. This reconstitutes the method call, +# invokes it upon the specified local object, and returns the value to +# the remote caller. Any object can receive calls over dRuby. There +# is no need to implement a special interface, or mixin special +# functionality. Nor, in the general case, does an object need to +# explicitly register itself with a DRbServer in order to receive +# dRuby calls. +# +# One process wishing to make dRuby calls upon another process must +# somehow obtain an initial reference to an object in the remote +# process by some means other than as the return value of a remote +# method call, as there is initially no remote object reference it can +# invoke a method upon. This is done by attaching to the server by +# URI. Each DRbServer binds itself to a URI such as +# 'druby://example.com:8787'. A DRbServer can have an object attached +# to it that acts as the server's *front* *object*. A DRbObject can +# be explicitly created from the server's URI. This DRbObject's +# remote object will be the server's front object. This front object +# can then return references to other Ruby objects in the DRbServer's +# process. +# +# Method calls made over dRuby behave largely the same as normal Ruby +# method calls made within a process. Method calls with blocks are +# supported, as are raising exceptions. In addition to a method's +# standard errors, a dRuby call may also raise one of the +# dRuby-specific errors, all of which are subclasses of DRb::DRbError. +# +# Any type of object can be passed as an argument to a dRuby call or +# returned as its return value. By default, such objects are dumped +# or marshalled at the local end, then loaded or unmarshalled at the +# remote end. The remote end therefore receives a copy of the local +# object, not a distributed reference to it; methods invoked upon this +# copy are executed entirely in the remote process, not passed on to +# the local original. This has semantics similar to pass-by-value. +# +# However, if an object cannot be marshalled, a dRuby reference to it +# is passed or returned instead. This will turn up at the remote end +# as a DRbObject instance. All methods invoked upon this remote proxy +# are forwarded to the local object, as described in the discussion of +# DRbObjects. This has semantics similar to the normal Ruby +# pass-by-reference. +# +# The easiest way to signal that we want an otherwise marshallable +# object to be passed or returned as a DRbObject reference, rather +# than marshalled and sent as a copy, is to include the +# DRb::DRbUndumped mixin module. +# +# dRuby supports calling remote methods with blocks. As blocks (or +# rather the Proc objects that represent them) are not marshallable, +# the block executes in the local, not the remote, context. Each +# value yielded to the block is passed from the remote object to the +# local block, then the value returned by each block invocation is +# passed back to the remote execution context to be collected, before +# the collected values are finally returned to the local context as +# the return value of the method invocation. +# +# == Examples of usage +# +# For more dRuby samples, see the +samples+ directory in the full +# dRuby distribution. +# +# === dRuby in client/server mode +# +# This illustrates setting up a simple client-server drb +# system. Run the server and client code in different terminals, +# starting the server code first. +# +# ==== Server code +# +# require 'drb/drb' +# +# # The URI for the server to connect to +# URI="druby://localhost:8787" +# +# class TimeServer +# +# def get_current_time +# return Time.now +# end +# +# end +# +# # The object that handles requests on the server +# FRONT_OBJECT=TimeServer.new +# +# DRb.start_service(URI, FRONT_OBJECT) +# # Wait for the drb server thread to finish before exiting. +# DRb.thread.join +# +# ==== Client code +# +# require 'drb/drb' +# +# # The URI to connect to +# SERVER_URI="druby://localhost:8787" +# +# # Start a local DRbServer to handle callbacks. +# # +# # Not necessary for this small example, but will be required +# # as soon as we pass a non-marshallable object as an argument +# # to a dRuby call. +# # +# # Note: this must be called at least once per process to take any effect. +# # This is particularly important if your application forks. +# DRb.start_service +# +# timeserver = DRbObject.new_with_uri(SERVER_URI) +# puts timeserver.get_current_time +# +# === Remote objects under dRuby +# +# This example illustrates returning a reference to an object +# from a dRuby call. The Logger instances live in the server +# process. References to them are returned to the client process, +# where methods can be invoked upon them. These methods are +# executed in the server process. +# +# ==== Server code +# +# require 'drb/drb' +# +# URI="druby://localhost:8787" +# +# class Logger +# +# # Make dRuby send Logger instances as dRuby references, +# # not copies. +# include DRb::DRbUndumped +# +# def initialize(n, fname) +# @name = n +# @filename = fname +# end +# +# def log(message) +# File.open(@filename, "a") do |f| +# f.puts("#{Time.now}: #{@name}: #{message}") +# end +# end +# +# end +# +# # We have a central object for creating and retrieving loggers. +# # This retains a local reference to all loggers created. This +# # is so an existing logger can be looked up by name, but also +# # to prevent loggers from being garbage collected. A dRuby +# # reference to an object is not sufficient to prevent it being +# # garbage collected! +# class LoggerFactory +# +# def initialize(bdir) +# @basedir = bdir +# @loggers = {} +# end +# +# def get_logger(name) +# if !@loggers.has_key? name +# # make the filename safe, then declare it to be so +# fname = name.gsub(/[.\/\\\:]/, "_") +# @loggers[name] = Logger.new(name, @basedir + "/" + fname) +# end +# return @loggers[name] +# end +# +# end +# +# FRONT_OBJECT=LoggerFactory.new("/tmp/dlog") +# +# DRb.start_service(URI, FRONT_OBJECT) +# DRb.thread.join +# +# ==== Client code +# +# require 'drb/drb' +# +# SERVER_URI="druby://localhost:8787" +# +# DRb.start_service +# +# log_service=DRbObject.new_with_uri(SERVER_URI) +# +# ["loga", "logb", "logc"].each do |logname| +# +# logger=log_service.get_logger(logname) +# +# logger.log("Hello, world!") +# logger.log("Goodbye, world!") +# logger.log("=== EOT ===") +# +# end +# +# == Security +# +# As with all network services, security needs to be considered when +# using dRuby. By allowing external access to a Ruby object, you are +# not only allowing outside clients to call the methods you have +# defined for that object, but by default to execute arbitrary Ruby +# code on your server. Consider the following: +# +# # !!! UNSAFE CODE !!! +# ro = DRbObject::new_with_uri("druby://your.server.com:8989") +# class << ro +# undef :instance_eval # force call to be passed to remote object +# end +# ro.instance_eval("`rm -rf *`") +# +# The dangers posed by instance_eval and friends are such that a +# DRbServer should only be used when clients are trusted. +# +# A DRbServer can be configured with an access control list to +# selectively allow or deny access from specified IP addresses. The +# main druby distribution provides the ACL class for this purpose. In +# general, this mechanism should only be used alongside, rather than +# as a replacement for, a good firewall. +# +# == dRuby internals +# +# dRuby is implemented using three main components: a remote method +# call marshaller/unmarshaller; a transport protocol; and an +# ID-to-object mapper. The latter two can be directly, and the first +# indirectly, replaced, in order to provide different behaviour and +# capabilities. +# +# Marshalling and unmarshalling of remote method calls is performed by +# a DRb::DRbMessage instance. This uses the Marshal module to dump +# the method call before sending it over the transport layer, then +# reconstitute it at the other end. There is normally no need to +# replace this component, and no direct way is provided to do so. +# However, it is possible to implement an alternative marshalling +# scheme as part of an implementation of the transport layer. +# +# The transport layer is responsible for opening client and server +# network connections and forwarding dRuby request across them. +# Normally, it uses DRb::DRbMessage internally to manage marshalling +# and unmarshalling. The transport layer is managed by +# DRb::DRbProtocol. Multiple protocols can be installed in +# DRbProtocol at the one time; selection between them is determined by +# the scheme of a dRuby URI. The default transport protocol is +# selected by the scheme 'druby:', and implemented by +# DRb::DRbTCPSocket. This uses plain TCP/IP sockets for +# communication. An alternative protocol, using UNIX domain sockets, +# is implemented by DRb::DRbUNIXSocket in the file drb/unix.rb, and +# selected by the scheme 'drbunix:'. A sample implementation over +# HTTP can be found in the samples accompanying the main dRuby +# distribution. +# +# The ID-to-object mapping component maps dRuby object ids to the +# objects they refer to, and vice versa. The implementation to use +# can be specified as part of a DRb::DRbServer's configuration. The +# default implementation is provided by DRb::DRbIdConv. It uses an +# object's ObjectSpace id as its dRuby id. This means that the dRuby +# reference to that object only remains meaningful for the lifetime of +# the object's process and the lifetime of the object within that +# process. A modified implementation is provided by DRb::TimerIdConv +# in the file drb/timeridconv.rb. This implementation retains a local +# reference to all objects exported over dRuby for a configurable +# period of time (defaulting to ten minutes), to prevent them being +# garbage-collected within this time. Another sample implementation +# is provided in sample/name.rb in the main dRuby distribution. This +# allows objects to specify their own id or "name". A dRuby reference +# can be made persistent across processes by having each process +# register an object using the same dRuby name. +# +module DRb + + # Superclass of all errors raised in the DRb module. + class DRbError < RuntimeError; end + + # Error raised when an error occurs on the underlying communication + # protocol. + class DRbConnError < DRbError; end + + class DRbObjectSpace # :nodoc: + # This is an internal class for DRbIdConv. This must not be used + # by users. + + include MonitorMixin + + def initialize + super() + @map = ObjectSpace::WeakMap.new + end + + def to_id(obj) + synchronize do + @map[obj.__id__] = obj + obj.__id__ + end + end + + def to_obj(ref) + synchronize do + obj = @map[ref] + raise RangeError.new("invalid reference") unless obj.__id__ == ref + obj + end + end + end + + # :nodoc: + # + # This is an internal singleton instance. This must not be used + # by users. + DRB_OBJECT_SPACE = DRbObjectSpace.new + + # Class responsible for converting between an object and its id. + # + # This, the default implementation, uses an object's local ObjectSpace + # __id__ as its id. This means that an object's identification over + # drb remains valid only while that object instance remains alive + # within the server runtime. + # + # For alternative mechanisms, see DRb::TimerIdConv in drb/timeridconv.rb + # and DRbNameIdConv in sample/name.rb in the full drb distribution. + class DRbIdConv + + # Convert an object reference id to an object. + # + # This implementation looks up the reference id in the local object + # space and returns the object it refers to. + def to_obj(ref) + DRB_OBJECT_SPACE.to_obj(ref) + end + + # Convert an object into a reference id. + # + # This implementation returns the object's __id__ in the local + # object space. + def to_id(obj) + (nil == obj) ? nil : DRB_OBJECT_SPACE.to_id(obj) + end + end + + # Mixin module making an object undumpable or unmarshallable. + # + # If an object which includes this module is returned by method + # called over drb, then the object remains in the server space + # and a reference to the object is returned, rather than the + # object being marshalled and moved into the client space. + module DRbUndumped + def _dump(dummy) # :nodoc: + raise TypeError, 'can\'t dump' + end + end + + # Error raised by the DRb module when an attempt is made to refer to + # the context's current drb server but the context does not have one. + # See #current_server. + class DRbServerNotFound < DRbError; end + + # Error raised by the DRbProtocol module when it cannot find any + # protocol implementation support the scheme specified in a URI. + class DRbBadURI < DRbError; end + + # Error raised by a dRuby protocol when it doesn't support the + # scheme specified in a URI. See DRb::DRbProtocol. + class DRbBadScheme < DRbError; end + + # An exception wrapping a DRb::DRbUnknown object + class DRbUnknownError < DRbError + + # Create a new DRbUnknownError for the DRb::DRbUnknown object +unknown+ + def initialize(unknown) + @unknown = unknown + super(unknown.name) + end + + # Get the wrapped DRb::DRbUnknown object. + attr_reader :unknown + + def self._load(s) # :nodoc: + Marshal::load(s) + end + + def _dump(lv) # :nodoc: + Marshal::dump(@unknown) + end + end + + # An exception wrapping an error object + class DRbRemoteError < DRbError + + # Creates a new remote error that wraps the Exception +error+ + def initialize(error) + @reason = error.class.to_s + super("#{error.message} (#{error.class})") + set_backtrace(error.backtrace) + end + + # the class of the error, as a string. + attr_reader :reason + end + + # Class wrapping a marshalled object whose type is unknown locally. + # + # If an object is returned by a method invoked over drb, but the + # class of the object is unknown in the client namespace, or + # the object is a constant unknown in the client namespace, then + # the still-marshalled object is returned wrapped in a DRbUnknown instance. + # + # If this object is passed as an argument to a method invoked over + # drb, then the wrapped object is passed instead. + # + # The class or constant name of the object can be read from the + # +name+ attribute. The marshalled object is held in the +buf+ + # attribute. + class DRbUnknown + + # Create a new DRbUnknown object. + # + # +buf+ is a string containing a marshalled object that could not + # be unmarshalled. +err+ is the error message that was raised + # when the unmarshalling failed. It is used to determine the + # name of the unmarshalled object. + def initialize(err, buf) + case err.to_s + when /uninitialized constant (\S+)/ + @name = $1 + when /undefined class\/module (\S+)/ + @name = $1 + else + @name = nil + end + @buf = buf + end + + # The name of the unknown thing. + # + # Class name for unknown objects; variable name for unknown + # constants. + attr_reader :name + + # Buffer contained the marshalled, unknown object. + attr_reader :buf + + def self._load(s) # :nodoc: + begin + Marshal::load(s) + rescue NameError, ArgumentError + DRbUnknown.new($!, s) + end + end + + def _dump(lv) # :nodoc: + @buf + end + + # Attempt to load the wrapped marshalled object again. + # + # If the class of the object is now known locally, the object + # will be unmarshalled and returned. Otherwise, a new + # but identical DRbUnknown object will be returned. + def reload + self.class._load(@buf) + end + + # Create a DRbUnknownError exception containing this object. + def exception + DRbUnknownError.new(self) + end + end + + # An Array wrapper that can be sent to another server via DRb. + # + # All entries in the array will be dumped or be references that point to + # the local server. + + class DRbArray + + # Creates a new DRbArray that either dumps or wraps all the items in the + # Array +ary+ so they can be loaded by a remote DRb server. + + def initialize(ary) + @ary = ary.collect { |obj| + if obj.kind_of? DRbUndumped + DRbObject.new(obj) + else + begin + Marshal.dump(obj) + obj + rescue + DRbObject.new(obj) + end + end + } + end + + def self._load(s) # :nodoc: + Marshal::load(s) + end + + def _dump(lv) # :nodoc: + Marshal.dump(@ary) + end + end + + # Handler for sending and receiving drb messages. + # + # This takes care of the low-level marshalling and unmarshalling + # of drb requests and responses sent over the wire between server + # and client. This relieves the implementor of a new drb + # protocol layer with having to deal with these details. + # + # The user does not have to directly deal with this object in + # normal use. + class DRbMessage + def initialize(config) # :nodoc: + @load_limit = config[:load_limit] + @argc_limit = config[:argc_limit] + end + + def dump(obj, error=false) # :nodoc: + case obj + when DRbUndumped + obj = make_proxy(obj, error) + when Object + # nothing + else + obj = make_proxy(obj, error) + end + begin + str = Marshal::dump(obj) + rescue + str = Marshal::dump(make_proxy(obj, error)) + end + [str.size].pack('N') + str + end + + def load(soc) # :nodoc: + begin + sz = soc.read(4) # sizeof (N) + rescue + raise(DRbConnError, $!.message, $!.backtrace) + end + raise(DRbConnError, 'connection closed') if sz.nil? + raise(DRbConnError, 'premature header') if sz.size < 4 + sz = sz.unpack('N')[0] + raise(DRbConnError, "too large packet #{sz}") if @load_limit < sz + begin + str = soc.read(sz) + rescue + raise(DRbConnError, $!.message, $!.backtrace) + end + raise(DRbConnError, 'connection closed') if str.nil? + raise(DRbConnError, 'premature marshal format(can\'t read)') if str.size < sz + DRb.mutex.synchronize do + begin + Marshal::load(str) + rescue NameError, ArgumentError + DRbUnknown.new($!, str) + end + end + end + + def send_request(stream, ref, msg_id, arg, b) # :nodoc: + ary = [] + ary.push(dump(ref.__drbref)) + ary.push(dump(msg_id.id2name)) + ary.push(dump(arg.length)) + arg.each do |e| + ary.push(dump(e)) + end + ary.push(dump(b)) + stream.write(ary.join('')) + rescue + raise(DRbConnError, $!.message, $!.backtrace) + end + + def recv_request(stream) # :nodoc: + ref = load(stream) + ro = DRb.to_obj(ref) + msg = load(stream) + argc = load(stream) + raise(DRbConnError, "too many arguments") if @argc_limit < argc + argv = Array.new(argc, nil) + argc.times do |n| + argv[n] = load(stream) + end + block = load(stream) + return ro, msg, argv, block + end + + def send_reply(stream, succ, result) # :nodoc: + stream.write(dump(succ) + dump(result, !succ)) + rescue + raise(DRbConnError, $!.message, $!.backtrace) + end + + def recv_reply(stream) # :nodoc: + succ = load(stream) + result = load(stream) + [succ, result] + end + + private + def make_proxy(obj, error=false) # :nodoc: + if error + DRbRemoteError.new(obj) + else + DRbObject.new(obj) + end + end + end + + # Module managing the underlying network protocol(s) used by drb. + # + # By default, drb uses the DRbTCPSocket protocol. Other protocols + # can be defined. A protocol must define the following class methods: + # + # [open(uri, config)] Open a client connection to the server at +uri+, + # using configuration +config+. Return a protocol + # instance for this connection. + # [open_server(uri, config)] Open a server listening at +uri+, + # using configuration +config+. Return a + # protocol instance for this listener. + # [uri_option(uri, config)] Take a URI, possibly containing an option + # component (e.g. a trailing '?param=val'), + # and return a [uri, option] tuple. + # + # All of these methods should raise a DRbBadScheme error if the URI + # does not identify the protocol they support (e.g. "druby:" for + # the standard Ruby protocol). This is how the DRbProtocol module, + # given a URI, determines which protocol implementation serves that + # protocol. + # + # The protocol instance returned by #open_server must have the + # following methods: + # + # [accept] Accept a new connection to the server. Returns a protocol + # instance capable of communicating with the client. + # [close] Close the server connection. + # [uri] Get the URI for this server. + # + # The protocol instance returned by #open must have the following methods: + # + # [send_request (ref, msg_id, arg, b)] + # Send a request to +ref+ with the given message id and arguments. + # This is most easily implemented by calling DRbMessage.send_request, + # providing a stream that sits on top of the current protocol. + # [recv_reply] + # Receive a reply from the server and return it as a [success-boolean, + # reply-value] pair. This is most easily implemented by calling + # DRb.recv_reply, providing a stream that sits on top of the + # current protocol. + # [alive?] + # Is this connection still alive? + # [close] + # Close this connection. + # + # The protocol instance returned by #open_server().accept() must have + # the following methods: + # + # [recv_request] + # Receive a request from the client and return a [object, message, + # args, block] tuple. This is most easily implemented by calling + # DRbMessage.recv_request, providing a stream that sits on top of + # the current protocol. + # [send_reply(succ, result)] + # Send a reply to the client. This is most easily implemented + # by calling DRbMessage.send_reply, providing a stream that sits + # on top of the current protocol. + # [close] + # Close this connection. + # + # A new protocol is registered with the DRbProtocol module using + # the add_protocol method. + # + # For examples of other protocols, see DRbUNIXSocket in drb/unix.rb, + # and HTTP0 in sample/http0.rb and sample/http0serv.rb in the full + # drb distribution. + module DRbProtocol + + # Add a new protocol to the DRbProtocol module. + def add_protocol(prot) + @protocol.push(prot) + end + module_function :add_protocol + + # Open a client connection to +uri+ with the configuration +config+. + # + # The DRbProtocol module asks each registered protocol in turn to + # try to open the URI. Each protocol signals that it does not handle that + # URI by raising a DRbBadScheme error. If no protocol recognises the + # URI, then a DRbBadURI error is raised. If a protocol accepts the + # URI, but an error occurs in opening it, a DRbConnError is raised. + def open(uri, config, first=true) + @protocol.each do |prot| + begin + return prot.open(uri, config) + rescue DRbBadScheme + rescue DRbConnError + raise($!) + rescue + raise(DRbConnError, "#{uri} - #{$!.inspect}") + end + end + if first && (config[:auto_load] != false) + auto_load(uri) + return open(uri, config, false) + end + raise DRbBadURI, 'can\'t parse uri:' + uri + end + module_function :open + + # Open a server listening for connections at +uri+ with + # configuration +config+. + # + # The DRbProtocol module asks each registered protocol in turn to + # try to open a server at the URI. Each protocol signals that it does + # not handle that URI by raising a DRbBadScheme error. If no protocol + # recognises the URI, then a DRbBadURI error is raised. If a protocol + # accepts the URI, but an error occurs in opening it, the underlying + # error is passed on to the caller. + def open_server(uri, config, first=true) + @protocol.each do |prot| + begin + return prot.open_server(uri, config) + rescue DRbBadScheme + end + end + if first && (config[:auto_load] != false) + auto_load(uri) + return open_server(uri, config, false) + end + raise DRbBadURI, 'can\'t parse uri:' + uri + end + module_function :open_server + + # Parse +uri+ into a [uri, option] pair. + # + # The DRbProtocol module asks each registered protocol in turn to + # try to parse the URI. Each protocol signals that it does not handle that + # URI by raising a DRbBadScheme error. If no protocol recognises the + # URI, then a DRbBadURI error is raised. + def uri_option(uri, config, first=true) + @protocol.each do |prot| + begin + uri, opt = prot.uri_option(uri, config) + # opt = nil if opt == '' + return uri, opt + rescue DRbBadScheme + end + end + if first && (config[:auto_load] != false) + auto_load(uri) + return uri_option(uri, config, false) + end + raise DRbBadURI, 'can\'t parse uri:' + uri + end + module_function :uri_option + + def auto_load(uri) # :nodoc: + if /\Adrb([a-z0-9]+):/ =~ uri + require("drb/#{$1}") rescue nil + end + end + module_function :auto_load + end + + # The default drb protocol which communicates over a TCP socket. + # + # The DRb TCP protocol URI looks like: + # druby://:?. The option is optional. + + class DRbTCPSocket + # :stopdoc: + private + def self.parse_uri(uri) + if /\Adruby:\/\/(.*?):(\d+)(\?(.*))?\z/ =~ uri + host = $1 + port = $2.to_i + option = $4 + [host, port, option] + else + raise(DRbBadScheme, uri) unless uri.start_with?('druby:') + raise(DRbBadURI, 'can\'t parse uri:' + uri) + end + end + + public + + # Open a client connection to +uri+ (DRb URI string) using configuration + # +config+. + # + # This can raise DRb::DRbBadScheme or DRb::DRbBadURI if +uri+ is not for a + # recognized protocol. See DRb::DRbServer.new for information on built-in + # URI protocols. + def self.open(uri, config) + host, port, = parse_uri(uri) + soc = TCPSocket.open(host, port) + self.new(uri, soc, config) + end + + # Returns the hostname of this server + def self.getservername + host = Socket::gethostname + begin + Socket::getaddrinfo(host, nil, + Socket::AF_UNSPEC, + Socket::SOCK_STREAM, + 0, + Socket::AI_PASSIVE)[0][3] + rescue + 'localhost' + end + end + + # For the families available for +host+, returns a TCPServer on +port+. + # If +port+ is 0 the first available port is used. IPv4 servers are + # preferred over IPv6 servers. + def self.open_server_inaddr_any(host, port) + infos = Socket::getaddrinfo(host, nil, + Socket::AF_UNSPEC, + Socket::SOCK_STREAM, + 0, + Socket::AI_PASSIVE) + families = Hash[*infos.collect { |af, *_| af }.uniq.zip([]).flatten] + return TCPServer.open('0.0.0.0', port) if families.has_key?('AF_INET') + return TCPServer.open('::', port) if families.has_key?('AF_INET6') + return TCPServer.open(port) + # :stopdoc: + end + + # Open a server listening for connections at +uri+ using + # configuration +config+. + def self.open_server(uri, config) + uri = 'druby://:0' unless uri + host, port, _ = parse_uri(uri) + config = {:tcp_original_host => host}.update(config) + if host.size == 0 + host = getservername + soc = open_server_inaddr_any(host, port) + else + soc = TCPServer.open(host, port) + end + port = soc.addr[1] if port == 0 + config[:tcp_port] = port + uri = "druby://#{host}:#{port}" + self.new(uri, soc, config) + end + + # Parse +uri+ into a [uri, option] pair. + def self.uri_option(uri, config) + host, port, option = parse_uri(uri) + return "druby://#{host}:#{port}", option + end + + # Create a new DRbTCPSocket instance. + # + # +uri+ is the URI we are connected to. + # +soc+ is the tcp socket we are bound to. +config+ is our + # configuration. + def initialize(uri, soc, config={}) + @uri = uri + @socket = soc + @config = config + @acl = config[:tcp_acl] + @msg = DRbMessage.new(config) + set_sockopt(@socket) + @shutdown_pipe_r, @shutdown_pipe_w = IO.pipe + end + + # Get the URI that we are connected to. + attr_reader :uri + + # Get the address of our TCP peer (the other end of the socket + # we are bound to. + def peeraddr + @socket.peeraddr + end + + # Get the socket. + def stream; @socket; end + + # On the client side, send a request to the server. + def send_request(ref, msg_id, arg, b) + @msg.send_request(stream, ref, msg_id, arg, b) + end + + # On the server side, receive a request from the client. + def recv_request + @msg.recv_request(stream) + end + + # On the server side, send a reply to the client. + def send_reply(succ, result) + @msg.send_reply(stream, succ, result) + end + + # On the client side, receive a reply from the server. + def recv_reply + @msg.recv_reply(stream) + end + + public + + # Close the connection. + # + # If this is an instance returned by #open_server, then this stops + # listening for new connections altogether. If this is an instance + # returned by #open or by #accept, then it closes this particular + # client-server session. + def close + shutdown + if @socket + @socket.close + @socket = nil + end + close_shutdown_pipe + end + + def close_shutdown_pipe + @shutdown_pipe_w.close + @shutdown_pipe_r.close + end + private :close_shutdown_pipe + + # On the server side, for an instance returned by #open_server, + # accept a client connection and return a new instance to handle + # the server's side of this client-server session. + def accept + while true + s = accept_or_shutdown + return nil unless s + break if (@acl ? @acl.allow_socket?(s) : true) + s.close + end + if @config[:tcp_original_host].to_s.size == 0 + uri = "druby://#{s.addr[3]}:#{@config[:tcp_port]}" + else + uri = @uri + end + self.class.new(uri, s, @config) + end + + def accept_or_shutdown + readables, = IO.select([@socket, @shutdown_pipe_r]) + if readables.include? @shutdown_pipe_r + return nil + end + @socket.accept + end + private :accept_or_shutdown + + # Graceful shutdown + def shutdown + @shutdown_pipe_w.close + end + + # Check to see if this connection is alive. + def alive? + return false unless @socket + if @socket.to_io.wait_readable(0) + close + return false + end + true + end + + def set_sockopt(soc) # :nodoc: + soc.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) + rescue IOError, Errno::ECONNRESET, Errno::EINVAL + # closed/shutdown socket, ignore error + end + end + + module DRbProtocol + @protocol = [DRbTCPSocket] # default + end + + class DRbURIOption # :nodoc: I don't understand the purpose of this class... + def initialize(option) + @option = option.to_s + end + attr_reader :option + def to_s; @option; end + + def ==(other) + return false unless DRbURIOption === other + @option == other.option + end + + def hash + @option.hash + end + + alias eql? == + end + + # Object wrapping a reference to a remote drb object. + # + # Method calls on this object are relayed to the remote + # object that this object is a stub for. + class DRbObject + + # Unmarshall a marshalled DRbObject. + # + # If the referenced object is located within the local server, then + # the object itself is returned. Otherwise, a new DRbObject is + # created to act as a stub for the remote referenced object. + def self._load(s) + uri, ref = Marshal.load(s) + + if DRb.here?(uri) + obj = DRb.to_obj(ref) + return obj + end + + self.new_with(uri, ref) + end + + # Creates a DRb::DRbObject given the reference information to the remote + # host +uri+ and object +ref+. + + def self.new_with(uri, ref) + it = self.allocate + it.instance_variable_set(:@uri, uri) + it.instance_variable_set(:@ref, ref) + it + end + + # Create a new DRbObject from a URI alone. + def self.new_with_uri(uri) + self.new(nil, uri) + end + + # Marshall this object. + # + # The URI and ref of the object are marshalled. + def _dump(lv) + Marshal.dump([@uri, @ref]) + end + + # Create a new remote object stub. + # + # +obj+ is the (local) object we want to create a stub for. Normally + # this is +nil+. +uri+ is the URI of the remote object that this + # will be a stub for. + def initialize(obj, uri=nil) + @uri = nil + @ref = nil + case obj + when Object + is_nil = obj.nil? + when BasicObject + is_nil = false + end + + if is_nil + return if uri.nil? + @uri, option = DRbProtocol.uri_option(uri, DRb.config) + @ref = DRbURIOption.new(option) unless option.nil? + else + @uri = uri ? uri : (DRb.uri rescue nil) + @ref = obj ? DRb.to_id(obj) : nil + end + end + + # Get the URI of the remote object. + def __drburi + @uri + end + + # Get the reference of the object, if local. + def __drbref + @ref + end + + undef :to_s + undef :to_a if respond_to?(:to_a) + + # Routes respond_to? to the referenced remote object. + def respond_to?(msg_id, priv=false) + case msg_id + when :_dump + true + when :marshal_dump + false + else + method_missing(:respond_to?, msg_id, priv) + end + end + + # Routes method calls to the referenced remote object. + ruby2_keywords def method_missing(msg_id, *a, &b) + if DRb.here?(@uri) + obj = DRb.to_obj(@ref) + DRb.current_server.check_insecure_method(obj, msg_id) + return obj.__send__(msg_id, *a, &b) + end + + succ, result = self.class.with_friend(@uri) do + DRbConn.open(@uri) do |conn| + conn.send_message(self, msg_id, a, b) + end + end + + if succ + return result + elsif DRbUnknown === result + raise result + else + bt = self.class.prepare_backtrace(@uri, result) + result.set_backtrace(bt + caller) + raise result + end + end + + # Given the +uri+ of another host executes the block provided. + def self.with_friend(uri) # :nodoc: + friend = DRb.fetch_server(uri) + return yield() unless friend + + save = Thread.current['DRb'] + Thread.current['DRb'] = { 'server' => friend } + return yield + ensure + Thread.current['DRb'] = save if friend + end + + # Returns a modified backtrace from +result+ with the +uri+ where each call + # in the backtrace came from. + def self.prepare_backtrace(uri, result) # :nodoc: + prefix = "(#{uri}) " + bt = [] + result.backtrace.each do |x| + break if /[`']__send__'$/ =~ x + if /\A\(druby:\/\// =~ x + bt.push(x) + else + bt.push(prefix + x) + end + end + bt + end + + def pretty_print(q) # :nodoc: + q.pp_object(self) + end + + def pretty_print_cycle(q) # :nodoc: + q.object_address_group(self) { + q.breakable + q.text '...' + } + end + end + + class ThreadObject + include MonitorMixin + + def initialize(&blk) + super() + @wait_ev = new_cond + @req_ev = new_cond + @res_ev = new_cond + @status = :wait + @req = nil + @res = nil + @thread = Thread.new(self, &blk) + end + + def alive? + @thread.alive? + end + + def kill + @thread.kill + @thread.join + end + + def method_missing(msg, *arg, &blk) + synchronize do + @wait_ev.wait_until { @status == :wait } + @req = [msg] + arg + @status = :req + @req_ev.broadcast + @res_ev.wait_until { @status == :res } + value = @res + @req = @res = nil + @status = :wait + @wait_ev.broadcast + return value + end + end + + def _execute() + synchronize do + @req_ev.wait_until { @status == :req } + @res = yield(@req) + @status = :res + @res_ev.signal + end + end + end + + # Class handling the connection between a DRbObject and the + # server the real object lives on. + # + # This class maintains a pool of connections, to reduce the + # overhead of starting and closing down connections for each + # method call. + # + # This class is used internally by DRbObject. The user does + # not normally need to deal with it directly. + class DRbConn + POOL_SIZE = 16 # :nodoc: + + def self.make_pool + ThreadObject.new do |queue| + pool = [] + while true + queue._execute do |message| + case(message[0]) + when :take then + remote_uri = message[1] + conn = nil + new_pool = [] + pool.each do |c| + if conn.nil? and c.uri == remote_uri + conn = c if c.alive? + else + new_pool.push c + end + end + pool = new_pool + conn + when :store then + conn = message[1] + pool.unshift(conn) + pool.pop.close while pool.size > POOL_SIZE + conn + else + nil + end + end + end + end + end + @pool_proxy = nil + + def self.stop_pool + @pool_proxy&.kill + @pool_proxy = nil + end + + def self.open(remote_uri) # :nodoc: + begin + @pool_proxy = make_pool unless @pool_proxy&.alive? + + conn = @pool_proxy.take(remote_uri) + conn = self.new(remote_uri) unless conn + succ, result = yield(conn) + return succ, result + + ensure + if conn + if succ + @pool_proxy.store(conn) + else + conn.close + end + end + end + end + + def initialize(remote_uri) # :nodoc: + @uri = remote_uri + @protocol = DRbProtocol.open(remote_uri, DRb.config) + end + attr_reader :uri # :nodoc: + + def send_message(ref, msg_id, arg, block) # :nodoc: + @protocol.send_request(ref, msg_id, arg, block) + @protocol.recv_reply + end + + def close # :nodoc: + @protocol.close + @protocol = nil + end + + def alive? # :nodoc: + return false unless @protocol + @protocol.alive? + end + end + + # Class representing a drb server instance. + # + # A DRbServer must be running in the local process before any incoming + # dRuby calls can be accepted, or any local objects can be passed as + # dRuby references to remote processes, even if those local objects are + # never actually called remotely. You do not need to start a DRbServer + # in the local process if you are only making outgoing dRuby calls + # passing marshalled parameters. + # + # Unless multiple servers are being used, the local DRbServer is normally + # started by calling DRb.start_service. + class DRbServer + @@acl = nil + @@idconv = DRbIdConv.new + @@secondary_server = nil + @@argc_limit = 256 + @@load_limit = 0xffffffff + @@verbose = false + + # Set the default value for the :argc_limit option. + # + # See #new(). The initial default value is 256. + def self.default_argc_limit(argc) + @@argc_limit = argc + end + + # Set the default value for the :load_limit option. + # + # See #new(). The initial default value is 25 MB. + def self.default_load_limit(sz) + @@load_limit = sz + end + + # Set the default access control list to +acl+. The default ACL is +nil+. + # + # See also DRb::ACL and #new() + def self.default_acl(acl) + @@acl = acl + end + + # Set the default value for the :id_conv option. + # + # See #new(). The initial default value is a DRbIdConv instance. + def self.default_id_conv(idconv) + @@idconv = idconv + end + + # Set the default value of the :verbose option. + # + # See #new(). The initial default value is false. + def self.verbose=(on) + @@verbose = on + end + + # Get the default value of the :verbose option. + def self.verbose + @@verbose + end + + def self.make_config(hash={}) # :nodoc: + default_config = { + :idconv => @@idconv, + :verbose => @@verbose, + :tcp_acl => @@acl, + :load_limit => @@load_limit, + :argc_limit => @@argc_limit, + } + default_config.update(hash) + end + + # Create a new DRbServer instance. + # + # +uri+ is the URI to bind to. This is normally of the form + # 'druby://:' where is a hostname of + # the local machine. If nil, then the system's default hostname + # will be bound to, on a port selected by the system; these value + # can be retrieved from the +uri+ attribute. 'druby:' specifies + # the default dRuby transport protocol: another protocol, such + # as 'drbunix:', can be specified instead. + # + # +front+ is the front object for the server, that is, the object + # to which remote method calls on the server will be passed. If + # nil, then the server will not accept remote method calls. + # + # If +config_or_acl+ is a hash, it is the configuration to + # use for this server. The following options are recognised: + # + # :idconv :: an id-to-object conversion object. This defaults + # to an instance of the class DRb::DRbIdConv. + # :verbose :: if true, all unsuccessful remote calls on objects + # in the server will be logged to $stdout. false + # by default. + # :tcp_acl :: the access control list for this server. See + # the ACL class from the main dRuby distribution. + # :load_limit :: the maximum message size in bytes accepted by + # the server. Defaults to 25 MB (26214400). + # :argc_limit :: the maximum number of arguments to a remote + # method accepted by the server. Defaults to + # 256. + # The default values of these options can be modified on + # a class-wide basis by the class methods #default_argc_limit, + # #default_load_limit, #default_acl, #default_id_conv, + # and #verbose= + # + # If +config_or_acl+ is not a hash, but is not nil, it is + # assumed to be the access control list for this server. + # See the :tcp_acl option for more details. + # + # If no other server is currently set as the primary server, + # this will become the primary server. + # + # The server will immediately start running in its own thread. + def initialize(uri=nil, front=nil, config_or_acl=nil) + if Hash === config_or_acl + config = config_or_acl.dup + else + acl = config_or_acl || @@acl + config = { + :tcp_acl => acl + } + end + + @config = self.class.make_config(config) + + @protocol = DRbProtocol.open_server(uri, @config) + @uri = @protocol.uri + @exported_uri = [@uri] + + @front = front + @idconv = @config[:idconv] + + @grp = ThreadGroup.new + @thread = run + + DRb.regist_server(self) + end + + # The URI of this DRbServer. + attr_reader :uri + + # The main thread of this DRbServer. + # + # This is the thread that listens for and accepts connections + # from clients, not that handles each client's request-response + # session. + attr_reader :thread + + # The front object of the DRbServer. + # + # This object receives remote method calls made on the server's + # URI alone, with an object id. + attr_reader :front + + # The configuration of this DRbServer + attr_reader :config + + # Set whether to operate in verbose mode. + # + # In verbose mode, failed calls are logged to stdout. + def verbose=(v); @config[:verbose]=v; end + + # Get whether the server is in verbose mode. + # + # In verbose mode, failed calls are logged to stdout. + def verbose; @config[:verbose]; end + + # Is this server alive? + def alive? + @thread.alive? + end + + # Is +uri+ the URI for this server? + def here?(uri) + @exported_uri.include?(uri) + end + + # Stop this server. + def stop_service + DRb.remove_server(self) + if Thread.current['DRb'] && Thread.current['DRb']['server'] == self + Thread.current['DRb']['stop_service'] = true + else + shutdown + end + end + + # Convert a dRuby reference to the local object it refers to. + def to_obj(ref) + return front if ref.nil? + return front[ref.to_s] if DRbURIOption === ref + @idconv.to_obj(ref) + end + + # Convert a local object to a dRuby reference. + def to_id(obj) + return nil if obj.__id__ == front.__id__ + @idconv.to_id(obj) + end + + private + + def shutdown + current = Thread.current + if @protocol.respond_to? :shutdown + @protocol.shutdown + else + [@thread, *@grp.list].each { |thread| + thread.kill unless thread == current # xxx: Thread#kill + } + end + @thread.join unless @thread == current + end + + ## + # Starts the DRb main loop in a new thread. + + def run + Thread.start do + begin + while main_loop + end + ensure + @protocol.close if @protocol + end + end + end + + # List of insecure methods. + # + # These methods are not callable via dRuby. + INSECURE_METHOD = [ + :__send__ + ] + + # Has a method been included in the list of insecure methods? + def insecure_method?(msg_id) + INSECURE_METHOD.include?(msg_id) + end + + # Coerce an object to a string, providing our own representation if + # to_s is not defined for the object. + def any_to_s(obj) + "#{obj}:#{obj.class}" + rescue + Kernel.instance_method(:to_s).bind_call(obj) + end + + # Check that a method is callable via dRuby. + # + # +obj+ is the object we want to invoke the method on. +msg_id+ is the + # method name, as a Symbol. + # + # If the method is an insecure method (see #insecure_method?) a + # SecurityError is thrown. If the method is private or undefined, + # a NameError is thrown. + def check_insecure_method(obj, msg_id) + return true if Proc === obj && msg_id == :__drb_yield + raise(ArgumentError, "#{any_to_s(msg_id)} is not a symbol") unless Symbol == msg_id.class + raise(SecurityError, "insecure method '#{msg_id}'") if insecure_method?(msg_id) + + case obj + when Object + if obj.private_methods.include?(msg_id) + desc = any_to_s(obj) + raise NoMethodError, "private method '#{msg_id}' called for #{desc}" + elsif obj.protected_methods.include?(msg_id) + desc = any_to_s(obj) + raise NoMethodError, "protected method '#{msg_id}' called for #{desc}" + else + true + end + else + if Kernel.instance_method(:private_methods).bind(obj).call.include?(msg_id) + desc = any_to_s(obj) + raise NoMethodError, "private method '#{msg_id}' called for #{desc}" + elsif Kernel.instance_method(:protected_methods).bind(obj).call.include?(msg_id) + desc = any_to_s(obj) + raise NoMethodError, "protected method '#{msg_id}' called for #{desc}" + else + true + end + end + end + public :check_insecure_method + + class InvokeMethod # :nodoc: + def initialize(drb_server, client) + @drb_server = drb_server + @client = client + end + + def perform + begin + setup_message + ensure + @result = nil + @succ = false + end + + if @block + @result = perform_with_block + else + @result = perform_without_block + end + @succ = true + case @result + when Array + if @msg_id == :to_ary + @result = DRbArray.new(@result) + end + end + return @succ, @result + rescue NoMemoryError, SystemExit, SystemStackError, SecurityError + raise + rescue Exception + @result = $! + return @succ, @result + end + + private + def init_with_client + obj, msg, argv, block = @client.recv_request + @obj = obj + @msg_id = msg.intern + @argv = argv + @block = block + end + + def check_insecure_method + @drb_server.check_insecure_method(@obj, @msg_id) + end + + def setup_message + init_with_client + check_insecure_method + end + + def block_yield(x) + if x.size == 1 && x[0].class == Array + x[0] = DRbArray.new(x[0]) + end + @block.call(*x) + end + + def perform_with_block + @obj.__send__(@msg_id, *@argv) do |*x| + jump_error = nil + begin + block_value = block_yield(x) + rescue LocalJumpError + jump_error = $! + end + if jump_error + case jump_error.reason + when :break + break(jump_error.exit_value) + else + raise jump_error + end + end + block_value + end + end + + def perform_without_block + if Proc === @obj && @msg_id == :__drb_yield + if @argv.size == 1 + ary = @argv + else + ary = [@argv] + end + ary.collect(&@obj)[0] + else + @obj.__send__(@msg_id, *@argv) + end + end + + end + + def error_print(exception) + exception.backtrace.inject(true) do |first, x| + if first + $stderr.puts "#{x}: #{exception} (#{exception.class})" + else + $stderr.puts "\tfrom #{x}" + end + false + end + end + + # The main loop performed by a DRbServer's internal thread. + # + # Accepts a connection from a client, and starts up its own + # thread to handle it. This thread loops, receiving requests + # from the client, invoking them on a local object, and + # returning responses, until the client closes the connection + # or a local method call fails. + def main_loop + client0 = @protocol.accept + return nil if !client0 + Thread.start(client0) do |client| + @grp.add Thread.current + Thread.current['DRb'] = { 'client' => client , + 'server' => self } + DRb.mutex.synchronize do + client_uri = client.uri + @exported_uri << client_uri unless @exported_uri.include?(client_uri) + end + _last_invoke_method = nil + loop do + begin + succ = false + invoke_method = InvokeMethod.new(self, client) + succ, result = invoke_method.perform + error_print(result) if !succ && verbose + unless DRbConnError === result && result.message == 'connection closed' + client.send_reply(succ, result) + end + rescue Exception => e + error_print(e) if verbose + ensure + _last_invoke_method = invoke_method + client.close unless succ + if Thread.current['DRb']['stop_service'] + shutdown + break + end + break unless succ + end + end + end + end + end + + @primary_server = nil + + # Start a dRuby server locally. + # + # The new dRuby server will become the primary server, even + # if another server is currently the primary server. + # + # +uri+ is the URI for the server to bind to. If nil, + # the server will bind to random port on the default local host + # name and use the default dRuby protocol. + # + # +front+ is the server's front object. This may be nil. + # + # +config+ is the configuration for the new server. This may + # be nil. + # + # See DRbServer::new. + def start_service(uri=nil, front=nil, config=nil) + @primary_server = DRbServer.new(uri, front, config) + end + module_function :start_service + + # The primary local dRuby server. + # + # This is the server created by the #start_service call. + attr_accessor :primary_server + module_function :primary_server=, :primary_server + + # Get the 'current' server. + # + # In the context of execution taking place within the main + # thread of a dRuby server (typically, as a result of a remote + # call on the server or one of its objects), the current + # server is that server. Otherwise, the current server is + # the primary server. + # + # If the above rule fails to find a server, a DRbServerNotFound + # error is raised. + def current_server + drb = Thread.current['DRb'] + server = (drb && drb['server']) ? drb['server'] : @primary_server + raise DRbServerNotFound unless server + return server + end + module_function :current_server + + # Stop the local dRuby server. + # + # This operates on the primary server. If there is no primary + # server currently running, it is a noop. + def stop_service + @primary_server.stop_service if @primary_server + @primary_server = nil + end + module_function :stop_service + + # Get the URI defining the local dRuby space. + # + # This is the URI of the current server. See #current_server. + def uri + drb = Thread.current['DRb'] + client = (drb && drb['client']) + if client + uri = client.uri + return uri if uri + end + current_server.uri + end + module_function :uri + + # Is +uri+ the URI for the current local server? + def here?(uri) + current_server.here?(uri) rescue false + # (current_server.uri rescue nil) == uri + end + module_function :here? + + # Get the configuration of the current server. + # + # If there is no current server, this returns the default configuration. + # See #current_server and DRbServer::make_config. + def config + current_server.config + rescue + DRbServer.make_config + end + module_function :config + + # Get the front object of the current server. + # + # This raises a DRbServerNotFound error if there is no current server. + # See #current_server. + def front + current_server.front + end + module_function :front + + # Convert a reference into an object using the current server. + # + # This raises a DRbServerNotFound error if there is no current server. + # See #current_server. + def to_obj(ref) + current_server.to_obj(ref) + end + + # Get a reference id for an object using the current server. + # + # This raises a DRbServerNotFound error if there is no current server. + # See #current_server. + def to_id(obj) + current_server.to_id(obj) + end + module_function :to_id + module_function :to_obj + + # Get the thread of the primary server. + # + # This returns nil if there is no primary server. See #primary_server. + def thread + @primary_server ? @primary_server.thread : nil + end + module_function :thread + + # Set the default id conversion object. + # + # This is expected to be an instance such as DRb::DRbIdConv that responds to + # #to_id and #to_obj that can convert objects to and from DRb references. + # + # See DRbServer#default_id_conv. + def install_id_conv(idconv) + DRbServer.default_id_conv(idconv) + end + module_function :install_id_conv + + # Set the default ACL to +acl+. + # + # See DRb::DRbServer.default_acl. + def install_acl(acl) + DRbServer.default_acl(acl) + end + module_function :install_acl + + @mutex = Thread::Mutex.new + def mutex # :nodoc: + @mutex + end + module_function :mutex + + @server = {} + # Registers +server+ with DRb. + # + # This is called when a new DRb::DRbServer is created. + # + # If there is no primary server then +server+ becomes the primary server. + # + # Example: + # + # require 'drb' + # + # s = DRb::DRbServer.new # automatically calls regist_server + # DRb.fetch_server s.uri #=> # + def regist_server(server) + @server[server.uri] = server + mutex.synchronize do + @primary_server = server unless @primary_server + end + end + module_function :regist_server + + # Removes +server+ from the list of registered servers. + def remove_server(server) + @server.delete(server.uri) + mutex.synchronize do + if @primary_server == server + @primary_server = nil + end + end + end + module_function :remove_server + + # Retrieves the server with the given +uri+. + # + # See also regist_server and remove_server. + def fetch_server(uri) + @server[uri] + end + module_function :fetch_server +end + +# :stopdoc: +DRbObject = DRb::DRbObject +DRbUndumped = DRb::DRbUndumped +DRbIdConv = DRb::DRbIdConv diff --git a/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/eq.rb b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/eq.rb new file mode 100644 index 00000000..15ca5cae --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/eq.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: false +module DRb + class DRbObject # :nodoc: + def ==(other) + return false unless DRbObject === other + (@ref == other.__drbref) && (@uri == other.__drburi) + end + + def hash + [@uri, @ref].hash + end + + alias eql? == + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/extserv.rb b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/extserv.rb new file mode 100644 index 00000000..9523fe84 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/extserv.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: false +=begin + external service + Copyright (c) 2000,2002 Masatoshi SEKI +=end + +require_relative 'drb' +require 'monitor' + +module DRb + class ExtServ + include MonitorMixin + include DRbUndumped + + def initialize(there, name, server=nil) + super() + @server = server || DRb::primary_server + @name = name + ro = DRbObject.new(nil, there) + synchronize do + @invoker = ro.register(name, DRbObject.new(self, @server.uri)) + end + end + attr_reader :server + + def front + DRbObject.new(nil, @server.uri) + end + + def stop_service + synchronize do + @invoker.unregister(@name) + server = @server + @server = nil + server.stop_service + true + end + end + + def alive? + @server ? @server.alive? : false + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/extservm.rb b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/extservm.rb new file mode 100644 index 00000000..9333a108 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/extservm.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: false +=begin + external service manager + Copyright (c) 2000 Masatoshi SEKI +=end + +require_relative 'drb' +require 'monitor' + +module DRb + class ExtServManager + include DRbUndumped + include MonitorMixin + + @@command = {} + + def self.command + @@command + end + + def self.command=(cmd) + @@command = cmd + end + + def initialize + super() + @cond = new_cond + @servers = {} + @waiting = [] + @queue = Thread::Queue.new + @thread = invoke_thread + @uri = nil + end + attr_accessor :uri + + def service(name) + synchronize do + while true + server = @servers[name] + return server if server && server.alive? # server may be `false' + invoke_service(name) + @cond.wait + end + end + end + + def register(name, ro) + synchronize do + @servers[name] = ro + @cond.signal + end + self + end + alias regist register + + def unregister(name) + synchronize do + @servers.delete(name) + end + end + alias unregist unregister + + private + def invoke_thread + Thread.new do + while name = @queue.pop + invoke_service_command(name, @@command[name]) + end + end + end + + def invoke_service(name) + @queue.push(name) + end + + def invoke_service_command(name, command) + raise "invalid command. name: #{name}" unless command + synchronize do + return if @servers.include?(name) + @servers[name] = false + end + uri = @uri || DRb.uri + if command.respond_to? :to_ary + command = command.to_ary + [uri, name] + pid = spawn(*command) + else + pid = spawn("#{command} #{uri} #{name}") + end + th = Process.detach(pid) + th[:drb_service] = name + th + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/gw.rb b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/gw.rb new file mode 100644 index 00000000..65a52547 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/gw.rb @@ -0,0 +1,161 @@ +# frozen_string_literal: false +require_relative 'drb' +require 'monitor' + +module DRb + + # Gateway id conversion forms a gateway between different DRb protocols or + # networks. + # + # The gateway needs to install this id conversion and create servers for + # each of the protocols or networks it will be a gateway between. It then + # needs to create a server that attaches to each of these networks. For + # example: + # + # require 'drb/drb' + # require 'drb/unix' + # require 'drb/gw' + # + # DRb.install_id_conv DRb::GWIdConv.new + # gw = DRb::GW.new + # s1 = DRb::DRbServer.new 'drbunix:/path/to/gateway', gw + # s2 = DRb::DRbServer.new 'druby://example:10000', gw + # + # s1.thread.join + # s2.thread.join + # + # Each client must register services with the gateway, for example: + # + # DRb.start_service 'drbunix:', nil # an anonymous server + # gw = DRbObject.new nil, 'drbunix:/path/to/gateway' + # gw[:unix] = some_service + # DRb.thread.join + + class GWIdConv < DRbIdConv + def to_obj(ref) # :nodoc: + if Array === ref && ref[0] == :DRbObject + return DRbObject.new_with(ref[1], ref[2]) + end + super(ref) + end + end + + # The GW provides a synchronized store for participants in the gateway to + # communicate. + + class GW + include MonitorMixin + + # Creates a new GW + + def initialize + super() + @hash = {} + end + + # Retrieves +key+ from the GW + + def [](key) + synchronize do + @hash[key] + end + end + + # Stores value +v+ at +key+ in the GW + + def []=(key, v) + synchronize do + @hash[key] = v + end + end + end + + class DRbObject # :nodoc: + def self._load(s) + uri, ref = Marshal.load(s) + if DRb.uri == uri + return ref ? DRb.to_obj(ref) : DRb.front + end + + self.new_with(DRb.uri, [:DRbObject, uri, ref]) + end + + def _dump(lv) + if DRb.uri == @uri + if Array === @ref && @ref[0] == :DRbObject + Marshal.dump([@ref[1], @ref[2]]) + else + Marshal.dump([@uri, @ref]) # ?? + end + else + Marshal.dump([DRb.uri, [:DRbObject, @uri, @ref]]) + end + end + end +end + +=begin +DRb.install_id_conv(DRb::GWIdConv.new) + +front = DRb::GW.new + +s1 = DRb::DRbServer.new('drbunix:/tmp/gw_b_a', front) +s2 = DRb::DRbServer.new('drbunix:/tmp/gw_b_c', front) + +s1.thread.join +s2.thread.join +=end + +=begin +# foo.rb + +require 'drb/drb' + +class Foo + include DRbUndumped + def initialize(name, peer=nil) + @name = name + @peer = peer + end + + def ping(obj) + puts "#{@name}: ping: #{obj.inspect}" + @peer.ping(self) if @peer + end +end +=end + +=begin +# gw_a.rb +require 'drb/unix' +require 'foo' + +obj = Foo.new('a') +DRb.start_service("drbunix:/tmp/gw_a", obj) + +robj = DRbObject.new_with_uri('drbunix:/tmp/gw_b_a') +robj[:a] = obj + +DRb.thread.join +=end + +=begin +# gw_c.rb +require 'drb/unix' +require 'foo' + +foo = Foo.new('c', nil) + +DRb.start_service("drbunix:/tmp/gw_c", nil) + +robj = DRbObject.new_with_uri("drbunix:/tmp/gw_b_c") + +puts "c->b" +a = robj[:a] +sleep 2 + +a.ping(foo) + +DRb.thread.join +=end + diff --git a/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/observer.rb b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/observer.rb new file mode 100644 index 00000000..0fb7301e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/observer.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: false +require 'observer' + +module DRb + # The Observable module extended to DRb. See Observable for details. + module DRbObservable + include Observable + + # Notifies observers of a change in state. See also + # Observable#notify_observers + def notify_observers(*arg) + if defined? @observer_state and @observer_state + if defined? @observer_peers + @observer_peers.each do |observer, method| + begin + observer.__send__(method, *arg) + rescue + delete_observer(observer) + end + end + end + @observer_state = false + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/ssl.rb b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/ssl.rb new file mode 100644 index 00000000..9ec55d36 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/ssl.rb @@ -0,0 +1,354 @@ +# frozen_string_literal: false +require 'socket' +require 'openssl' +require_relative 'drb' +require 'singleton' + +module DRb + + # The protocol for DRb over an SSL socket + # + # The URI for a DRb socket over SSL is: + # drbssl://:?. The option is optional + class DRbSSLSocket < DRbTCPSocket + + # SSLConfig handles the needed SSL information for establishing a + # DRbSSLSocket connection, including generating the X509 / RSA pair. + # + # An instance of this config can be passed to DRbSSLSocket.new, + # DRbSSLSocket.open and DRbSSLSocket.open_server + # + # See DRb::DRbSSLSocket::SSLConfig.new for more details + class SSLConfig + + # Default values for a SSLConfig instance. + # + # See DRb::DRbSSLSocket::SSLConfig.new for more details + DEFAULT = { + :SSLCertificate => nil, + :SSLPrivateKey => nil, + :SSLClientCA => nil, + :SSLCACertificatePath => nil, + :SSLCACertificateFile => nil, + :SSLTmpDhCallback => nil, + :SSLVerifyMode => ::OpenSSL::SSL::VERIFY_NONE, + :SSLVerifyDepth => nil, + :SSLVerifyCallback => nil, # custom verification + :SSLCertificateStore => nil, + # Must specify if you use auto generated certificate. + :SSLCertName => nil, # e.g. [["CN","fqdn.example.com"]] + :SSLCertComment => "Generated by Ruby/OpenSSL" + } + + # Create a new DRb::DRbSSLSocket::SSLConfig instance + # + # The DRb::DRbSSLSocket will take either a +config+ Hash or an instance + # of SSLConfig, and will setup the certificate for its session for the + # configuration. If want it to generate a generic certificate, the bare + # minimum is to provide the :SSLCertName + # + # === Config options + # + # From +config+ Hash: + # + # :SSLCertificate :: + # An instance of OpenSSL::X509::Certificate. If this is not provided, + # then a generic X509 is generated, with a correspond :SSLPrivateKey + # + # :SSLPrivateKey :: + # A private key instance, like OpenSSL::PKey::RSA. This key must be + # the key that signed the :SSLCertificate + # + # :SSLClientCA :: + # An OpenSSL::X509::Certificate, or Array of certificates that will + # used as ClientCAs in the SSL Context + # + # :SSLCACertificatePath :: + # A path to the directory of CA certificates. The certificates must + # be in PEM format. + # + # :SSLCACertificateFile :: + # A path to a CA certificate file, in PEM format. + # + # :SSLTmpDhCallback :: + # A DH callback. See OpenSSL::SSL::SSLContext.tmp_dh_callback + # + # :SSLMinVersion :: + # This is the minimum SSL version to allow. See + # OpenSSL::SSL::SSLContext#min_version=. + # + # :SSLMaxVersion :: + # This is the maximum SSL version to allow. See + # OpenSSL::SSL::SSLContext#max_version=. + # + # :SSLVerifyMode :: + # This is the SSL verification mode. See OpenSSL::SSL::VERIFY_* for + # available modes. The default is OpenSSL::SSL::VERIFY_NONE + # + # :SSLVerifyDepth :: + # Number of CA certificates to walk, when verifying a certificate + # chain. + # + # :SSLVerifyCallback :: + # A callback to be used for additional verification. See + # OpenSSL::SSL::SSLContext.verify_callback + # + # :SSLCertificateStore :: + # A OpenSSL::X509::Store used for verification of certificates + # + # :SSLCertName :: + # Issuer name for the certificate. This is required when generating + # the certificate (if :SSLCertificate and :SSLPrivateKey were not + # given). The value of this is to be an Array of pairs: + # + # [["C", "Raleigh"], ["ST","North Carolina"], + # ["CN","fqdn.example.com"]] + # + # See also OpenSSL::X509::Name + # + # :SSLCertComment :: + # A comment to be used for generating the certificate. The default is + # "Generated by Ruby/OpenSSL" + # + # + # === Example + # + # These values can be added after the fact, like a Hash. + # + # require 'drb/ssl' + # c = DRb::DRbSSLSocket::SSLConfig.new {} + # c[:SSLCertificate] = + # OpenSSL::X509::Certificate.new(File.read('mycert.crt')) + # c[:SSLPrivateKey] = OpenSSL::PKey::RSA.new(File.read('mycert.key')) + # c[:SSLVerifyMode] = OpenSSL::SSL::VERIFY_PEER + # c[:SSLCACertificatePath] = "/etc/ssl/certs/" + # c.setup_certificate + # + # or + # + # require 'drb/ssl' + # c = DRb::DRbSSLSocket::SSLConfig.new({ + # :SSLCertName => [["CN" => DRb::DRbSSLSocket.getservername]] + # }) + # c.setup_certificate + # + def initialize(config) + @config = config + @cert = config[:SSLCertificate] + @pkey = config[:SSLPrivateKey] + @ssl_ctx = nil + end + + # A convenience method to access the values like a Hash + def [](key); + @config[key] || DEFAULT[key] + end + + # Connect to IO +tcp+, with context of the current certificate + # configuration + def connect(tcp) + ssl = ::OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx) + ssl.sync = true + ssl.connect + ssl + end + + # Accept connection to IO +tcp+, with context of the current certificate + # configuration + def accept(tcp) + ssl = OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx) + ssl.sync = true + ssl.accept + ssl + end + + # Ensures that :SSLCertificate and :SSLPrivateKey have been provided + # or that a new certificate is generated with the other parameters + # provided. + def setup_certificate + if @cert && @pkey + return + end + + rsa = OpenSSL::PKey::RSA.new(2048){|p, n| + next unless self[:verbose] + case p + when 0; $stderr.putc "." # BN_generate_prime + when 1; $stderr.putc "+" # BN_generate_prime + when 2; $stderr.putc "*" # searching good prime, + # n = #of try, + # but also data from BN_generate_prime + when 3; $stderr.putc "\n" # found good prime, n==0 - p, n==1 - q, + # but also data from BN_generate_prime + else; $stderr.putc "*" # BN_generate_prime + end + } + + cert = OpenSSL::X509::Certificate.new + cert.version = 2 # This means v3 + cert.serial = 0 + name = OpenSSL::X509::Name.new(self[:SSLCertName]) + cert.subject = name + cert.issuer = name + cert.not_before = Time.now + cert.not_after = Time.now + (365*24*60*60) + cert.public_key = rsa.public_key + + ef = OpenSSL::X509::ExtensionFactory.new(nil,cert) + cert.extensions = [ + ef.create_extension("basicConstraints","CA:FALSE"), + ef.create_extension("subjectKeyIdentifier", "hash") ] + ef.issuer_certificate = cert + cert.add_extension(ef.create_extension("authorityKeyIdentifier", + "keyid:always,issuer:always")) + if comment = self[:SSLCertComment] + cert.add_extension(ef.create_extension("nsComment", comment)) + end + cert.sign(rsa, "SHA256") + + @cert = cert + @pkey = rsa + end + + # Establish the OpenSSL::SSL::SSLContext with the configuration + # parameters provided. + def setup_ssl_context + ctx = ::OpenSSL::SSL::SSLContext.new + ctx.cert = @cert + ctx.key = @pkey + ctx.min_version = self[:SSLMinVersion] + ctx.max_version = self[:SSLMaxVersion] + ctx.client_ca = self[:SSLClientCA] + ctx.ca_path = self[:SSLCACertificatePath] + ctx.ca_file = self[:SSLCACertificateFile] + ctx.tmp_dh_callback = self[:SSLTmpDhCallback] + ctx.verify_mode = self[:SSLVerifyMode] + ctx.verify_depth = self[:SSLVerifyDepth] + ctx.verify_callback = self[:SSLVerifyCallback] + ctx.cert_store = self[:SSLCertificateStore] + @ssl_ctx = ctx + end + end + + # Parse the dRuby +uri+ for an SSL connection. + # + # Expects drbssl://... + # + # Raises DRbBadScheme or DRbBadURI if +uri+ is not matching or malformed + def self.parse_uri(uri) # :nodoc: + if /\Adrbssl:\/\/(.*?):(\d+)(\?(.*))?\z/ =~ uri + host = $1 + port = $2.to_i + option = $4 + [host, port, option] + else + raise(DRbBadScheme, uri) unless uri.start_with?('drbssl:') + raise(DRbBadURI, 'can\'t parse uri:' + uri) + end + end + + # Return an DRb::DRbSSLSocket instance as a client-side connection, + # with the SSL connected. This is called from DRb::start_service or while + # connecting to a remote object: + # + # DRb.start_service 'drbssl://localhost:0', front, config + # + # +uri+ is the URI we are connected to, + # 'drbssl://localhost:0' above, +config+ is our + # configuration. Either a Hash or DRb::DRbSSLSocket::SSLConfig + def self.open(uri, config) + host, port, = parse_uri(uri) + soc = TCPSocket.open(host, port) + ssl_conf = SSLConfig::new(config) + ssl_conf.setup_ssl_context + ssl = ssl_conf.connect(soc) + self.new(uri, ssl, ssl_conf, true) + end + + # Returns a DRb::DRbSSLSocket instance as a server-side connection, with + # the SSL connected. This is called from DRb::start_service or while + # connecting to a remote object: + # + # DRb.start_service 'drbssl://localhost:0', front, config + # + # +uri+ is the URI we are connected to, + # 'drbssl://localhost:0' above, +config+ is our + # configuration. Either a Hash or DRb::DRbSSLSocket::SSLConfig + def self.open_server(uri, config) + uri = 'drbssl://:0' unless uri + host, port, = parse_uri(uri) + if host.size == 0 + host = getservername + soc = open_server_inaddr_any(host, port) + else + soc = TCPServer.open(host, port) + end + port = soc.addr[1] if port == 0 + @uri = "drbssl://#{host}:#{port}" + + ssl_conf = SSLConfig.new(config) + ssl_conf.setup_certificate + ssl_conf.setup_ssl_context + self.new(@uri, soc, ssl_conf, false) + end + + # This is a convenience method to parse +uri+ and separate out any + # additional options appended in the +uri+. + # + # Returns an option-less uri and the option => [uri,option] + # + # The +config+ is completely unused, so passing nil is sufficient. + def self.uri_option(uri, config) # :nodoc: + host, port, option = parse_uri(uri) + return "drbssl://#{host}:#{port}", option + end + + # Create a DRb::DRbSSLSocket instance. + # + # +uri+ is the URI we are connected to. + # +soc+ is the tcp socket we are bound to. + # +config+ is our configuration. Either a Hash or SSLConfig + # +is_established+ is a boolean of whether +soc+ is currently established + # + # This is called automatically based on the DRb protocol. + def initialize(uri, soc, config, is_established) + @ssl = is_established ? soc : nil + super(uri, soc.to_io, config) + end + + # Returns the SSL stream + def stream; @ssl; end # :nodoc: + + # Closes the SSL stream before closing the dRuby connection. + def close # :nodoc: + if @ssl + @ssl.close + @ssl = nil + end + super + end + + def accept # :nodoc: + begin + while true + soc = accept_or_shutdown + return nil unless soc + break if (@acl ? @acl.allow_socket?(soc) : true) + soc.close + end + begin + ssl = @config.accept(soc) + rescue Exception + soc.close + raise + end + self.class.new(uri, ssl, @config, true) + rescue OpenSSL::SSL::SSLError + warn("#{$!.message} (#{$!.class})", uplevel: 0) if @config[:verbose] + retry + end + end + end + + DRbProtocol.add_protocol(DRbSSLSocket) +end diff --git a/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/timeridconv.rb b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/timeridconv.rb new file mode 100644 index 00000000..3ead98a7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/timeridconv.rb @@ -0,0 +1,97 @@ +# frozen_string_literal: false +require_relative 'drb' +require 'monitor' + +module DRb + + # Timer id conversion keeps objects alive for a certain amount of time after + # their last access. The default time period is 600 seconds and can be + # changed upon initialization. + # + # To use TimerIdConv: + # + # DRb.install_id_conv TimerIdConv.new 60 # one minute + + class TimerIdConv < DRbIdConv + class TimerHolder2 # :nodoc: + include MonitorMixin + + class InvalidIndexError < RuntimeError; end + + def initialize(keeping=600) + super() + @sentinel = Object.new + @gc = {} + @renew = {} + @keeping = keeping + @expires = nil + end + + def add(obj) + synchronize do + rotate + key = obj.__id__ + @renew[key] = obj + invoke_keeper + return key + end + end + + def fetch(key) + synchronize do + rotate + obj = peek(key) + raise InvalidIndexError if obj == @sentinel + @renew[key] = obj # KeepIt + return obj + end + end + + private + def peek(key) + return @renew.fetch(key) { @gc.fetch(key, @sentinel) } + end + + def invoke_keeper + return if @expires + @expires = Time.now + @keeping + on_gc + end + + def on_gc + return unless Thread.main.alive? + return if @expires.nil? + Thread.new { rotate } if @expires < Time.now + ObjectSpace.define_finalizer(Object.new) {on_gc} + end + + def rotate + synchronize do + if @expires &.< Time.now + @gc = @renew # GCed + @renew = {} + @expires = @gc.empty? ? nil : Time.now + @keeping + end + end + end + end + + # Creates a new TimerIdConv which will hold objects for +keeping+ seconds. + def initialize(keeping=600) + @holder = TimerHolder2.new(keeping) + end + + def to_obj(ref) # :nodoc: + return super if ref.nil? + @holder.fetch(ref) + rescue TimerHolder2::InvalidIndexError + raise "invalid reference" + end + + def to_id(obj) # :nodoc: + return @holder.add(obj) + end + end +end + +# DRb.install_id_conv(TimerIdConv.new) diff --git a/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/unix.rb b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/unix.rb new file mode 100644 index 00000000..1e371ccf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/unix.rb @@ -0,0 +1,118 @@ +# frozen_string_literal: false +require 'socket' +require_relative 'drb' +require 'tmpdir' + +raise(LoadError, "UNIXServer is required") unless defined?(UNIXServer) + +module DRb + + # Implements DRb over a UNIX socket + # + # DRb UNIX socket URIs look like drbunix:?. The + # option is optional. + + class DRbUNIXSocket < DRbTCPSocket + # :stopdoc: + def self.parse_uri(uri) + if /\Adrbunix:(.*?)(\?(.*))?\z/ =~ uri + filename = $1 + option = $3 + [filename, option] + else + raise(DRbBadScheme, uri) unless uri.start_with?('drbunix:') + raise(DRbBadURI, 'can\'t parse uri:' + uri) + end + end + + def self.open(uri, config) + filename, = parse_uri(uri) + soc = UNIXSocket.open(filename) + self.new(uri, soc, config) + end + + def self.open_server(uri, config) + filename, = parse_uri(uri) + if filename.size == 0 + soc = temp_server + filename = soc.path + uri = 'drbunix:' + soc.path + else + soc = UNIXServer.open(filename) + end + owner = config[:UNIXFileOwner] + group = config[:UNIXFileGroup] + if owner || group + require 'etc' + owner = Etc.getpwnam( owner ).uid if owner + group = Etc.getgrnam( group ).gid if group + File.chown owner, group, filename + end + mode = config[:UNIXFileMode] + File.chmod(mode, filename) if mode + + self.new(uri, soc, config, true) + end + + def self.uri_option(uri, config) + filename, option = parse_uri(uri) + return "drbunix:#{filename}", option + end + + def initialize(uri, soc, config={}, server_mode = false) + super(uri, soc, config) + set_sockopt(@socket) + @server_mode = server_mode + @acl = nil + end + + # import from tempfile.rb + Max_try = 10 + private + def self.temp_server + tmpdir = Dir::tmpdir + n = 0 + while true + begin + tmpname = sprintf('%s/druby%d.%d', tmpdir, $$, n) + lock = tmpname + '.lock' + unless File.exist?(tmpname) or File.exist?(lock) + Dir.mkdir(lock) + break + end + rescue + raise "cannot generate tempfile '%s'" % tmpname if n >= Max_try + #sleep(1) + end + n += 1 + end + soc = UNIXServer.new(tmpname) + Dir.rmdir(lock) + soc + end + + public + def close + return unless @socket + shutdown # DRbProtocol#shutdown + path = @socket.path if @server_mode + @socket.close + File.unlink(path) if @server_mode + @socket = nil + close_shutdown_pipe + end + + def accept + s = accept_or_shutdown + return nil unless s + self.class.new(nil, s, @config) + end + + def set_sockopt(soc) + # no-op for now + end + end + + DRbProtocol.add_protocol(DRbUNIXSocket) + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/version.rb b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/version.rb new file mode 100644 index 00000000..176ea4c4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/version.rb @@ -0,0 +1,3 @@ +module DRb + VERSION = "2.2.3" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/weakidconv.rb b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/weakidconv.rb new file mode 100644 index 00000000..951af8a8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/drb-2.2.3/lib/drb/weakidconv.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: false +require_relative 'drb' + +module DRb + + # DRb::WeakIdConv is deprecated since 2.2.1. You don't need to use + # DRb::WeakIdConv instead of DRb::DRbIdConv. It's the same class. + # + # This file still exists for backward compatibility. + # + # To use WeakIdConv: + # + # DRb.start_service(nil, nil, {:idconv => DRb::WeakIdConv.new}) + + def self.const_missing(name) # :nodoc: + case name + when :WeakIdConv + warn("DRb::WeakIdConv is deprecated. " + + "You can use the DRb::DRbIdConv. " + + "You don't need to use this.", + uplevel: 1) + const_set(:WeakIdConv, DRbIdConv) + singleton_class.remove_method(:const_missing) + DRbIdConv + else + super + end + end +end + +# DRb.install_id_conv(WeakIdConv.new) diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/CHANGELOG.md b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/CHANGELOG.md new file mode 100644 index 00000000..48eb2251 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/CHANGELOG.md @@ -0,0 +1,404 @@ + + +## 1.3.0 2025-01-04 + + +### Changed + +- Set minimum Ruby version to 3.1 (@flash-gordon) + +[Compare v1.2.0...v1.3.0](https://github.com/dry-rb/dry-configurable/compare/v1.2.0...v1.3.0) + +## 1.2.0 2024-07-03 + + +### Changed + +- Allow `Dry::Configurable` mixin to be included multiple times in a class hierarchy (#164 by @timriley) +- Deprecate `Dry::Configurable::AlreadyIncludedError` (#164 by @timriley) + +[Compare v1.1.0...v1.2.0](https://github.com/dry-rb/dry-configurable/compare/v1.1.0...v1.2.0) + +## 1.1.0 2022-07-16 + + +### Fixed + +- Allow nested settings to default to `Undefined` (fixes #158 via #161) (@emptyflask) + + +[Compare v1.0.1...v1.1.0](https://github.com/dry-rb/dry-configurable/compare/v1.0.1...v1.1.0) + +## 1.0.1 2022-11-16 + + +### Changed + +- Renamed `@config` and `@_settings` internal instance variables to `@__config__` and `@__settings__` in order to avoid clashes with user-defined instance variables (#159 by @timriley) + +[Compare v1.0.0...v1.0.1](https://github.com/dry-rb/dry-configurable/compare/v1.0.0...v1.0.1) + +## 1.0.0 2022-11-04 + + +### Changed + +- Dependency on `dry-core` was updated to ~> 1.0 (@solnic) + +[Compare v0.16.1...v1.0.0](https://github.com/dry-rb/dry-configurable/compare/v0.16.1...v1.0.0) + +## 0.16.1 2022-10-13 + + +### Changed + +- Restored performance of config value reads (direct reader methods as well as aggregate methods like `#values` and `#to_h`) to pre-0.16.0 levels (#149 by @timriley) + +[Compare v0.16.0...v0.16.1](https://github.com/dry-rb/dry-configurable/compare/v0.16.0...v0.16.1) + +## 0.16.0 2022-10-08 + + +### Added + +- Support for custom config classes via `config_class:` option (#136 by @solnic) + + ```ruby + extend Dry::Configurable(config_class: MyConfig) + ``` + + Your config class should inherit from `Dry::Configurable::Config`. +- Return `Dry::Core::Constants::Undefined` (instead of nil) as the value for non-configured settings via a `default_undefined: true` option (#141 by @timriley) + + ```ruby + extend Dry::Configurable(default_undefined: true) + ``` + + You must opt into this feature via the `default_undefined: true` option. Non-configured setting values are still `nil` by default. + +### Fixed + +- Remove exec bit from version.rb (#139 by @Fryguy) + +### Changed + +- Improve memory usage by separating setting definitions from config values (#138 by @timriley) + + Your usage of dry-configurable may be impacted if you have been accessing objects from `_settings` or the internals of `Dry::Configurable::Config`. `_settings` now returns `Dry::Configurable::Setting` instances, which contain only the details from the setting's definition. Setting _values_ remain in `Dry::Configurable::Config`. +- Use Zeitwerk to speed up load time (#135 by @solnic) + +[Compare v0.15.0...v0.16.0](https://github.com/dry-rb/dry-configurable/compare/v0.15.0...v0.16.0) + +## 0.15.0 2022-04-21 + + +### Changed + +- The `finalize!` method (as class or instance method, depending on whether you extend or include `Dry::Configurable` respectively) now accepts a boolean `freeze_values:` argument, which if true, will recursively freeze all config values in addition to the `config` itself. (#105 by @ojab) + + ```ruby + class MyConfigurable + include Dry::Configurable + + setting :db, default: "postgre" + end + + my_obj = MyConfigurable.new + my_obj.finalize!(freeze_values: true) + my_obj.config.db << "sql" # Will raise FrozenError + ``` +- `Dry::Configurable::Config#update` will set hashes as values for non-nested settings (#131 by @ojab) + + ```ruby + class MyConfigurable + extend Dry::Configurable + + setting :sslcert, constructor: ->(v) { v&.values_at(:pem, :pass)&.join } + end + + MyConfigurable.config.update(sslcert: {pem: "cert", pass: "qwerty"}) + MyConfigurable.config.sslcert # => "certqwerty" + ``` +- `Dry::Configurable::Config#update` will accept any values implicitly convertible to hash via `#to_hash` (#133 by @timriley) + +[Compare v0.14.0...v0.15.0](https://github.com/dry-rb/dry-configurable/compare/v0.14.0...v0.15.0) + +## 0.14.0 2022-01-14 + + +### Changed + +- Settings defined after an access to `config` will still be made available on that `config`. (#130 by @timriley) +- Cloneable settings are cloned immediately upon assignment. (#130 by @timriley) +- Changes to config values in parent classes after subclasses have already been created will not be propogated to those subclasses. Subclasses created _after_ config values have been changed in the parent _will_ receive those config values. (#130 by @timriley) + +[Compare v0.13.0...v0.14.0](https://github.com/dry-rb/dry-configurable/compare/v0.13.0...v0.14.0) + +## 0.13.0 2021-09-12 + + +### Added + +- Added flags to determine whether to warn on the API usage deprecated in this release (see "Changed" section below). Set these to `false` to suppress the warnings. (#124 by @timriley) + + ```ruby + Dry::Configurable.warn_on_setting_constructor_block false + Dry::Configurable.warn_on_setting_positional_default false + ``` + +### Fixed + +- Fixed `ArgumentError` for classes including `Dry::Configurable` whose `initializer` has required kwargs. (#113 by @timriley) + +### Changed + +- Deprecated the setting constructor provided as a block. Provide it via the `constructor:` keyword argument instead. (#111 by @waiting-for-dev & @timriley) + + ```ruby + setting :path, constructor: -> path { Pathname(path) } + ``` +- Deprecated the setting default provided as the second positional argument. Provide it via the `default:` keyword argument instead. (#112 and #121 by @waiting-for-dev & @timriley) + + ```ruby + setting :path, default: "some/default/path" + ``` +- [BREAKING] Removed implicit `to_hash` conversion from `Config`. (#114 by @timriley) + +[Compare v0.12.1...v0.13.0](https://github.com/dry-rb/dry-configurable/compare/v0.12.1...v0.13.0) + +## 0.12.1 2021-02-15 + + +### Added + +- Settings may be specified with a `cloneable` option, e.g. + +```ruby +setting :component_dirs, Configuration::ComponentDirs.new, cloneable: true +``` + +This change makes it possible to provide “rich” config values that carry their own +configuration interface. + +In the above example, `ComponentDirs` could provide its own API for adding component +dirs and configuring aspects of their behavior at the same time. By being passed to +the setting along with `cloneable: true`, dry-configurable will ensure the setting's +values are cloned along with the setting at all the appropriate times. + +A custom cloneable setting value should provide its own `#initialize_copy` (used by +`Object#dup`) with the appropriate logic. (@timriley in #102) + +### Fixed + +- Only `#initialize` instance method is prepended, leaving the rest of the instance +methods to be included as normal again. This allows classes including +`Dry::Configurable` to override instance methods with their own methods as required +(@adam12 in #103) + + +[Compare v0.12.0...v0.12.1](https://github.com/dry-rb/dry-configurable/compare/v0.12.0...v0.12.1) + +## 0.12.0 2020-12-26 + + +### Fixed + +- Setting values provided by defaults and/or pre-processor blocks are no longer accidentally memoized across instances of classes including Dry::Configurable (#99) (@timriley & @esparta) + +### Changed + +- Instance behavior is now prepended, so that if you have your own `initialize`, calling `super` is no longer required (see #98 for more details) (@zabolotnov87) +- Switched to equalizer from dry-core (@solnic) + +[Compare v0.11.6...v0.12.0](https://github.com/dry-rb/dry-configurable/compare/v0.11.6...v0.12.0) + +## 0.11.6 2020-06-22 + + +### Changed + +- A meaningful error is raised when the extension is included more than once (issue #89 fixed via #94) (@landongrindheim) +- Evaluate setting input immediately when input is provided. This allows for earlier feedback from constructors designed to raise errors on invalid input (#95) (@timriley) + +[Compare v0.11.5...v0.11.6](https://github.com/dry-rb/dry-configurable/compare/v0.11.5...v0.11.6) + +## 0.11.5 2020-03-23 + + +### Fixed + +- When settings are copied or cloned, unevaluated values will no longer be copied. This prevents unintended crashes when settings have constructors expecting a certain type of value, but that value is yet to be provided (Fixed via #87) (@timriley) + +### Changed + +- A meaningful error is raised when the extension is included more than once (issue #89 fixed via #94) (@landongrindheim) + +[Compare v0.11.4...v0.11.5](https://github.com/dry-rb/dry-configurable/compare/v0.11.4...v0.11.5) + +## 0.11.4 2020-03-16 + + +### Fixed + +- `Config#update` returns `self` again (issue #60 fixed via #92) (@solnic) + +### Changed + +- `Setting#inspect` no longer uses its value - this could cause crashes when inspecting settings that are yet to have a value applied (e.g. when they have a constructor that expects a value to be present) (@timriley) + +[Compare v0.11.3...v0.11.4](https://github.com/dry-rb/dry-configurable/compare/v0.11.3...v0.11.4) + +## 0.11.3 2020-02-22 + + +### Fixed + +- Retrieving settings by a string name works again (issue #82) (@waiting-for-dev) + + +[Compare v0.11.2...v0.11.3](https://github.com/dry-rb/dry-configurable/compare/v0.11.2...v0.11.3) + +## 0.11.2 2020-02-20 + + +### Fixed + +- Warning about redefined `Setting#value` is gone (@solnic) + + +[Compare v0.11.1...v0.11.2](https://github.com/dry-rb/dry-configurable/compare/v0.11.1...v0.11.2) + +## 0.11.1 2020-02-18 + + +### Fixed + +- You can use `:settings` as a config key again (issue #80) (@solnic) +- Setting value is lazy-evaluated now, which fixes some cases where a constructor could crash with a `nil` value (@solnic) + + +[Compare v0.11.0...v0.11.1](https://github.com/dry-rb/dry-configurable/compare/v0.11.0...v0.11.1) + +## 0.11.0 2020-02-15 + +Complete rewrite of the library while keeping the public API intact. See #78 for a detailed overview. + +### Changed + +- Accessing config in a parent class no longer prevents you from adding more settings in a child class (@solnic) +- (internal) New low-level Setting and Config API (@solnic) +- (internal) `config` objects use method_missing now (@solnic) + +[Compare v0.10.0...v0.11.0](https://github.com/dry-rb/dry-configurable/compare/v0.10.0...v0.11.0) + +## 0.10.0 2020-01-31 + +YANKED because the change also broke inheritance for classes that used `configured` before other classes inherited from them. + +### Changed + +- Inheriting settings no longer defines the config object. This change fixed a use case where parent class that already used its config would prevent a child class from adding new settings (@solnic) + +[Compare v0.9.0...v0.10.0](https://github.com/dry-rb/dry-configurable/compare/v0.9.0...v0.10.0) + +## 0.9.0 2019-11-06 + + +### Fixed + +- Support for reserved names in settings. Some Kernel methods (`public_send` and `class` specifically) are not available if you use access settings via method call. Same for methods of the `Config` class. You can still access them with `[]` and `[]=`. Ruby keywords are fully supported. Invalid names containing special symbols (including `!` and `?`) are rejected. Note that these changes don't affect the `reader` option, if you define a setting named `:class` and pass `reader: true` ... well ... (flash-gordon) +- Settings can be redefined in subclasses without a warning about overriding exsting methods (flash-gordon) +- Fix warnings about using keyword arguments in 2.7 (koic) + + +[Compare v0.8.3...v0.9.0](https://github.com/dry-rb/dry-configurable/compare/v0.8.3...v0.9.0) + +## 0.8.3 2019-05-29 + + +### Fixed + +- `Configurable#dup` and `Configurable#clone` make a copy of instance-level config so that it doesn't get mutated/shared across instances (flash-gordon) + + +[Compare v0.8.2...v0.8.3](https://github.com/dry-rb/dry-configurable/compare/v0.8.2...v0.8.3) + +## 0.8.2 2019-02-25 + + +### Fixed + +- Test interface support for modules ([Neznauy](https://github.com/Neznauy)) + + +[Compare v0.8.1...v0.8.2](https://github.com/dry-rb/dry-configurable/compare/v0.8.1...v0.8.2) + +## 0.8.1 2019-02-06 + + +### Fixed + +- `.configure` doesn't require a block, this makes the behavior consistent with the previous versions ([flash-gordon](https://github.com/flash-gordon)) + + +[Compare v0.8.0...v0.8.1](https://github.com/dry-rb/dry-configurable/compare/v0.8.0...v0.8.1) + +## 0.8.0 2019-02-05 + + +### Added + +- Support for instance-level configuration landed. For usage, `include` the module instead of extending ([flash-gordon](https://github.com/flash-gordon)) + + ```ruby + class App + include Dry::Configurable + + setting :database + end + + production = App.new + production.config.database = ENV['DATABASE_URL'] + production.finalize! + + development = App.new + development.config.database = 'jdbc:sqlite:memory' + development.finalize! + ``` +- Config values can be set from a hash with `.update`. Nested settings are supported ([flash-gordon](https://github.com/flash-gordon)) + + ```ruby + class App + extend Dry::Configurable + + setting :db do + setting :host + setting :port + end + + config.update(YAML.load(File.read("config.yml"))) + end + ``` + +### Fixed + +- A number of bugs related to inheriting settings from parent class were fixed. Ideally, new behavior will be :100: predictable but if you observe any anomaly, please report ([flash-gordon](https://github.com/flash-gordon)) + +### Changed + +- [BREAKING] Minimal supported Ruby version is set to 2.3 ([flash-gordon](https://github.com/flash-gordon)) + +[Compare v0.7.0...v0.8.0](https://github.com/dry-rb/dry-configurable/compare/v0.7.0...v0.8.0) + +## 0.7.0 2017-04-25 + + +### Added + +- Introduce `Configurable.finalize!` which freezes config and its dependencies ([qcam](https://github.com/qcam)) + +### Fixed + +- Allow for boolean false as default setting value ([yuszuv](https://github.com/yuszuv)) +- Convert nested configs to nested hashes with `Config#to_h` ([saverio-kantox](https://github.com/saverio-kantox)) +- Disallow modification on frozen config ([qcam](https://github.com/qcam)) diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/LICENSE b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/LICENSE new file mode 100644 index 00000000..9f9f214d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2015-2023 dry-rb team + +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 AUTHORS OR +COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/README.md b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/README.md new file mode 100644 index 00000000..3c58feff --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/README.md @@ -0,0 +1,22 @@ + +[gem]: https://rubygems.org/gems/dry-configurable +[actions]: https://github.com/dry-rb/dry-configurable/actions + +# dry-configurable [![Gem Version](https://badge.fury.io/rb/dry-configurable.svg)][gem] [![CI Status](https://github.com/dry-rb/dry-configurable/workflows/CI/badge.svg)][actions] + +## Links + +* [User documentation](https://dry-rb.org/gems/dry-configurable) +* [API documentation](http://rubydoc.info/gems/dry-configurable) +* [Forum](https://discourse.dry-rb.org) + +## Supported Ruby versions + +This library officially supports the following Ruby versions: + +* MRI `>= 3.1` +* jruby `>= 9.4` (not tested on CI) + +## License + +See `LICENSE` file. diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/dry-configurable.gemspec b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/dry-configurable.gemspec new file mode 100644 index 00000000..b6af069a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/dry-configurable.gemspec @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +# this file is synced from dry-rb/template-gem project + +lib = File.expand_path("lib", __dir__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require "dry/configurable/version" + +Gem::Specification.new do |spec| + spec.name = "dry-configurable" + spec.authors = ["Andy Holland"] + spec.email = ["andyholland1991@aol.com"] + spec.license = "MIT" + spec.version = Dry::Configurable::VERSION.dup + + spec.summary = "A mixin to add configuration functionality to your classes" + spec.description = spec.summary + spec.homepage = "https://dry-rb.org/gems/dry-configurable" + spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-configurable.gemspec", + "lib/**/*"] + spec.bindir = "bin" + spec.executables = [] + spec.require_paths = ["lib"] + + spec.metadata["allowed_push_host"] = "https://rubygems.org" + spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-configurable/blob/main/CHANGELOG.md" + spec.metadata["source_code_uri"] = "https://github.com/dry-rb/dry-configurable" + spec.metadata["bug_tracker_uri"] = "https://github.com/dry-rb/dry-configurable/issues" + spec.metadata["rubygems_mfa_required"] = "true" + + spec.required_ruby_version = ">= 3.1" + + # to update dependencies edit project.yml + spec.add_dependency "dry-core", "~> 1.1" + spec.add_dependency "zeitwerk", "~> 2.6" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry-configurable.rb b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry-configurable.rb new file mode 100644 index 00000000..4463f8d4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry-configurable.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +require "dry/configurable" diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable.rb b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable.rb new file mode 100644 index 00000000..b89e4502 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +require "zeitwerk" + +require "dry/core" +require "dry/configurable/constants" +require "dry/configurable/errors" + +module Dry + # @api public + def self.Configurable(**options) + Configurable::Extension.new(**options) + end + + # A simple configuration mixin + # + # @example class-level configuration + # + # class App + # extend Dry::Configurable + # + # setting :database do + # setting :dsn, 'sqlite:memory' + # end + # end + # + # App.config.database.dsn = 'jdbc:sqlite:memory' + # App.config.database.dsn + # # => "jdbc:sqlite:memory" + # + # @example instance-level configuration + # + # class App + # include Dry::Configurable + # + # setting :database + # end + # + # production = App.new + # production.config.database = ENV['DATABASE_URL'] + # production.finalize! + # + # development = App.new + # development.config.database = 'jdbc:sqlite:memory' + # development.finalize! + # + # @api public + module Configurable + def self.loader + @loader ||= Zeitwerk::Loader.new.tap do |loader| + root = File.expand_path("..", __dir__) + loader.tag = "dry-configurable" + loader.inflector = Zeitwerk::GemInflector.new("#{root}/dry-configurable.rb") + loader.push_dir(root) + loader.ignore( + "#{root}/dry-configurable.rb", + "#{root}/dry/configurable/{constants,errors,version}.rb" + ) + loader.inflector.inflect("dsl" => "DSL") + end + end + + # @api private + def self.extended(klass) + super + klass.extend(Extension.new) + end + + # @api private + def self.included(klass) + super + klass.include(Extension.new) + end + + loader.setup + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/class_methods.rb b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/class_methods.rb new file mode 100644 index 00000000..73728de1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/class_methods.rb @@ -0,0 +1,112 @@ +# frozen_string_literal: true + +require "set" + +module Dry + module Configurable + module ClassMethods + include Methods + + # @api private + def inherited(subclass) + super + + subclass.instance_variable_set(:@__config_extension__, __config_extension__) + + new_settings = settings.dup + subclass.instance_variable_set(:@__settings__, new_settings) + + # Only classes **extending** Dry::Configurable have class-level config. When + # Dry::Configurable is **included**, the class-level config method is undefined because it + # resides at the instance-level instead (see `Configurable.included`). + if respond_to?(:config) + subclass.instance_variable_set(:@__config__, config.dup_for_settings(new_settings)) + end + end + + # Add a setting to the configuration + # + # @param [Mixed] name + # The accessor key for the configuration value + # @param [Mixed] default + # Default value for the setting + # @param [#call] constructor + # Transformation given value will go through + # @param [Boolean] reader + # Whether a reader accessor must be created + # @yield + # A block can be given to add nested settings. + # + # @return [Dry::Configurable::Config] + # + # @api public + def setting(...) + setting = __config_dsl__.setting(...) + + settings << setting + + __config_reader__.define(setting.name) if setting.reader? + + self + end + + # Returns the defined settings for the class. + # + # @return [Settings] + # + # @api public + def settings + @__settings__ ||= Settings.new + end + + # Return configuration + # + # @return [Config] + # + # @api public + def config + @__config__ ||= __config_build__ + end + + # @api private + def __config_build__(settings = self.settings) + __config_extension__.config_class.new(settings) + end + + # @api private + def __config_extension__ + @__config_extension__ + end + + # @api private + def __config_dsl__ + @__config_dsl__ ||= DSL.new( + config_class: __config_extension__.config_class, + default_undefined: __config_extension__.default_undefined + ) + end + + # @api private + def __config_reader__ + @__config_reader__ ||= + begin + reader = Module.new do + def self.define(name) + define_method(name) do + config[name] + end + end + end + + if included_modules.include?(InstanceMethods) + include(reader) + end + + extend(reader) + + reader + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/compiler.rb b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/compiler.rb new file mode 100644 index 00000000..03a772bf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/compiler.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +module Dry + module Configurable + # Setting compiler used internally by the DSL + # + # @api private + class Compiler + def call(ast) + Settings.new.tap do |settings| + ast.each do |node| + settings << visit(node) + end + end + end + + # @api private + def visit(node) + type, rest = node + public_send(:"visit_#{type}", rest) + end + + # @api private + def visit_setting(node) + name, opts = node + Setting.new(name, **opts) + end + + # @api private + def visit_nested(node) + parent, children = node + name, opts = parent[1] + + Setting.new(name, **opts, children: Settings.new(call(children))) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/config.rb b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/config.rb new file mode 100644 index 00000000..2a6032d8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/config.rb @@ -0,0 +1,215 @@ +# frozen_string_literal: true + +require "set" + +module Dry + module Configurable + # Config exposes setting values through a convenient API + # + # @api public + class Config + include Dry::Equalizer(:values) + + # @api private + attr_reader :_settings + + # @api private + attr_reader :_values + + # @api private + attr_reader :_configured + protected :_configured + + # @api private + def initialize(settings, values: {}) + @_settings = settings + @_values = values + @_configured = Set.new + end + + # @api private + private def initialize_copy(source) + super + @_values = source.__send__(:dup_values) + @_configured = source._configured.dup + end + + # @api private + def dup_for_settings(settings) + dup.tap { |config| config.instance_variable_set(:@_settings, settings) } + end + + # Get config value by a key + # + # @param [String,Symbol] name + # + # @return Config value + def [](name) + name = name.to_sym + + unless (setting = _settings[name]) + raise ArgumentError, "+#{name}+ is not a setting name" + end + + _values.fetch(name) { + # Mutable settings may be configured after read + _configured.add(name) if setting.cloneable? + + setting.to_value.tap { |value| + _values[name] = value + } + } + end + + # Set config value. + # Note that finalized configs cannot be changed. + # + # @param [String,Symbol] name + # @param [Object] value + def []=(name, value) + raise FrozenConfigError, "Cannot modify frozen config" if frozen? + + name = name.to_sym + + unless (setting = _settings[name]) + raise ArgumentError, "+#{name}+ is not a setting name" + end + + _configured.add(name) + + _values[name] = setting.constructor.(value) + end + + # Update config with new values + # + # @param values [Hash, #to_hash] A hash with new values + # + # @return [Config] + # + # @api public + def update(values) + values.each do |key, value| + if self[key].is_a?(self.class) + unless value.respond_to?(:to_hash) + raise ArgumentError, "#{value.inspect} is not a valid setting value" + end + + self[key].update(value.to_hash) + else + self[key] = value + end + end + self + end + + # Returns true if the value for the given key has been set on this config. + # + # For simple values, this returns true if the value has been explicitly assigned. + # + # For cloneable (mutable) values, since these are captured on read, returns true if the value + # does not compare equally to its corresdponing default value. This relies on these objects + # having functioning `#==` checks. + # + # @return [Bool] + # + # @api public + def configured?(key) + if _configured.include?(key) && _settings[key].cloneable? + return _values[key] != _settings[key].to_value + end + + _configured.include?(key) + end + + # Returns the current config values. + # + # Nested configs remain in their {Config} instances. + # + # @return [Hash] + # + # @api public + def values + # Ensure all settings are represented in values + _settings.each { |setting| self[setting.name] unless _values.key?(setting.name) } + + _values + end + + # Returns config values as a hash, with nested values also converted from {Config} instances + # into hashes. + # + # @return [Hash] + # + # @api public + def to_h + values.to_h { |key, value| [key, value.is_a?(self.class) ? value.to_h : value] } + end + + # @api private + alias_method :_dry_equalizer_hash, :hash + + # @api public + def hash + return @__hash__ if instance_variable_defined?(:@__hash__) + + _dry_equalizer_hash + end + + # @api public + def finalize!(freeze_values: false) + return self if frozen? + + values.each_value do |value| + if value.is_a?(self.class) + value.finalize!(freeze_values: freeze_values) + elsif freeze_values + value.freeze + end + end + + # Memoize the hash for the object when finalizing (regardless of whether values themselves + # are to be frozen; the intention of finalization is that no further changes should be + # made). The benefit of freezing the hash at this point is that it saves repeated expensive + # computation (through Dry::Equalizer's hash implementation) if that hash is to be used + # later in performance-sensitive situations, such as when serving as a cache key or similar. + @__hash__ = _dry_equalizer_hash + + freeze + end + + # @api private + def pristine + self.class.new(_settings) + end + + private + + def method_missing(name, *args) + setting_name = setting_name_from_method(name) + setting = _settings[setting_name] + + super unless setting + + if name.end_with?("=") + self[setting_name] = args[0] + else + self[setting_name] + end + end + + def respond_to_missing?(meth, include_private = false) + _settings.key?(setting_name_from_method(meth)) || super + end + + def setting_name_from_method(method_name) + method_name.to_s.tr("=", "").to_sym + end + + def dup_values + _values.each_with_object({}) { |(key, val), dup_hsh| + dup_hsh[key] = _settings[key].cloneable? ? val.dup : val + } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/constants.rb b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/constants.rb new file mode 100644 index 00000000..677bc2db --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/constants.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module Dry + # Shared constants + # + # @api private + module Configurable + include Dry::Core::Constants + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/dsl.rb b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/dsl.rb new file mode 100644 index 00000000..e795cb7d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/dsl.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +module Dry + module Configurable + # Setting DSL used by the class API + # + # @api private + class DSL + VALID_NAME = /\A[a-z_]\w*\z/i + + attr_reader :compiler + + attr_reader :ast + + attr_reader :options + + def initialize(**options, &block) + @compiler = Compiler.new + @ast = [] + @options = options + instance_exec(&block) if block + end + + # Registers a new setting node and compile it into a setting object + # + # @see ClassMethods.setting + # @api private + # @return Setting + def setting(name, **options, &block) + unless VALID_NAME.match?(name.to_s) + raise ArgumentError, "#{name} is not a valid setting name" + end + + ensure_valid_options(options) + + options = {default: default, config_class: config_class, **options} + + node = [:setting, [name.to_sym, options]] + + if block + ast << [:nested, [node, DSL.new(**@options, &block).ast]] + else + ast << node + end + + compiler.visit(ast.last) + end + + def config_class + options[:config_class] + end + + def default + options[:default_undefined] ? Undefined : nil + end + + private + + def ensure_valid_options(options) + return if options.none? + + invalid_keys = options.keys - Setting::OPTIONS + + raise ArgumentError, "Invalid options: #{invalid_keys.inspect}" unless invalid_keys.empty? + end + + # Returns a tuple of valid and invalid options hashes derived from the options hash + # given to the setting + def valid_and_invalid_options(options) + options.partition { |k, _| Setting::OPTIONS.include?(k) }.map(&:to_h) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/errors.rb b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/errors.rb new file mode 100644 index 00000000..d04b4ca1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/errors.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Dry + # Shared errors + # + # @api public + module Configurable + extend Dry::Core::Deprecations["dry-configurable"] + + Error = Class.new(::StandardError) + + FrozenConfigError = Class.new(Error) + + AlreadyIncludedError = Class.new(Error) + deprecate_constant( + :AlreadyIncludedError, + message: "`include Dry::Configurable` more than once (if needed)" + ) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/extension.rb b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/extension.rb new file mode 100644 index 00000000..ecfb3f0f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/extension.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +module Dry + module Configurable + class Extension < Module + # @api private + attr_reader :config_class + + # @api private + attr_reader :default_undefined + + # @api private + def initialize(config_class: Configurable::Config, default_undefined: false) + super() + @config_class = config_class + @default_undefined = default_undefined + freeze + end + + # @api private + def extended(klass) + super + klass.extend(ClassMethods) + klass.instance_variable_set(:@__config_extension__, self) + end + + # @api private + def included(klass) + super + + klass.class_eval do + extend(ClassMethods) + include(InstanceMethods) + prepend(Initializer) + + class << self + undef :config if method_defined?(:config) + undef :configure if method_defined?(:configure) + end + end + + klass.instance_variable_set(:@__config_extension__, self) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/instance_methods.rb b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/instance_methods.rb new file mode 100644 index 00000000..52680f95 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/instance_methods.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +require "dry/configurable/config" +require "dry/configurable/methods" + +module Dry + module Configurable + # Initializer method which is prepended when `Dry::Configurable` + # is included in a class + # + # @api private + module Initializer + # @api private + def initialize(*) + @__config__ = self.class.__config_build__(self.class.settings) + + super + end + ruby2_keywords(:initialize) if respond_to?(:ruby2_keywords, true) + end + + # Instance-level API when `Dry::Configurable` is included in a class + # + # @api public + module InstanceMethods + include Methods + + # Return object's configuration + # + # @return [Config] + # + # @api public + def config + @__config__ + end + + # Finalize the config and freeze the object + # + # @api public + def finalize!(freeze_values: false) + super + freeze + end + + private + + # @api public + def initialize_copy(source) + super + @__config__ = source.config.dup + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/methods.rb b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/methods.rb new file mode 100644 index 00000000..c50b3c32 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/methods.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module Dry + module Configurable + # Common API for both classes and instances + # + # @api public + module Methods + # @api public + def configure(&block) + raise FrozenConfigError, "Cannot modify frozen config" if config.frozen? + + yield(config) if block + self + end + + # Finalize and freeze configuration + # + # @return [Dry::Configurable::Config] + # + # @api public + def finalize!(freeze_values: false) + config.finalize!(freeze_values: freeze_values) + self + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/setting.rb b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/setting.rb new file mode 100644 index 00000000..e78b8b81 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/setting.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +require "set" + +module Dry + module Configurable + # A defined setting. + # + # @api public + class Setting + include Dry::Equalizer(:name, :default, :constructor, :children, :options, inspect: false) + + OPTIONS = %i[default reader constructor mutable cloneable settings config_class].freeze + + DEFAULT_CONSTRUCTOR = -> v { v }.freeze + + MUTABLE_VALUE_TYPES = [Array, Hash, Set, Config].freeze + + # @api public + attr_reader :name + + # @api public + attr_reader :default + + # @api public + attr_reader :mutable + + # @api public + attr_reader :constructor + + # @api public + attr_reader :children + + # @api public + attr_reader :options + + # @api private + def self.mutable_value?(value) + MUTABLE_VALUE_TYPES.any? { |type| value.is_a?(type) } + end + + # @api private + def initialize( + name, + default:, + constructor: DEFAULT_CONSTRUCTOR, + children: EMPTY_ARRAY, + **options + ) + @name = name + @default = default + @mutable = children.any? || options.fetch(:mutable) { + # Allow `cloneable` as an option alias for `mutable` + options.fetch(:cloneable) { Setting.mutable_value?(default) } + } + @constructor = constructor + @children = children + @options = options + end + + # @api private + def reader? + options[:reader].equal?(true) + end + + # @api public + def mutable? + mutable + end + alias_method :cloneable?, :mutable? + + # @api private + def to_value + if children.any? + (options[:config_class] || Config).new(children) + else + value = default + value = constructor.(value) unless value.eql?(Undefined) + + mutable? ? value.dup : value + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/settings.rb b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/settings.rb new file mode 100644 index 00000000..525a5542 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/settings.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +module Dry + module Configurable + # A collection of defined settings on a given class. + # + # @api private + class Settings + include Dry::Equalizer(:settings) + + include Enumerable + + # @api private + attr_reader :settings + + # @api private + def initialize(settings = EMPTY_ARRAY) + @settings = settings.each_with_object({}) { |s, m| m[s.name] = s } + end + + # @api private + private def initialize_copy(source) + @settings = source.settings.dup + end + + # @api private + def <<(setting) + settings[setting.name] = setting + self + end + + # Returns the setting for the given name, if found. + # + # @return [Setting, nil] the setting, or nil if not found + # + # @api public + def [](name) + settings[name] + end + + # Returns true if a setting for the given name is defined. + # + # @return [Boolean] + # + # @api public + def key?(name) + keys.include?(name) + end + + # Returns the list of defined setting names. + # + # @return [Array] + # + # @api public + def keys + settings.keys + end + + # @api public + def each(&) + settings.each_value(&) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/test_interface.rb b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/test_interface.rb new file mode 100644 index 00000000..72a7f736 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/test_interface.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Dry + module Configurable + # Methods meant to be used in a testing scenario + module TestInterface + # Resets configuration to default values + # + # @return [Dry::Configurable::Config] + # + # @api public + def reset_config + @__config__ = config.pristine + end + end + + # Mixes in test interface into the configurable module + # + # @api public + def enable_test_interface + extend Dry::Configurable::TestInterface + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/version.rb b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/version.rb new file mode 100644 index 00000000..536ccba3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-configurable-1.3.0/lib/dry/configurable/version.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +module Dry + module Configurable + # @api public + VERSION = "1.3.0" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/CHANGELOG.md b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/CHANGELOG.md new file mode 100644 index 00000000..f0132cd6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/CHANGELOG.md @@ -0,0 +1,380 @@ + + +## 1.1.0 2025-01-04 + + +### Changed + +- Minimal Ruby version is 3.1 (@flash-gordon) +- Fixed clash with `dry-logger` (see #80) (@flash-gordon) + +[Compare v1.0.1...v1.1.0](https://github.com/dry-rb/dry-core/compare/v1.0.1...v1.1.0) + +## 1.0.1 2023-08-06 + + +### Fixed + +- [equalizer] Add `Dry::Core.Equalizer` method to make `include Dry::Core.Equalizer(...)` work as documented (via #79) (@timriley) + + Users of Equalizer should now only need to `require "dry/core"` first. + + +### Changed + +- Minimal Ruby version is 3.0 (@flash-gordon) + +[Compare v1.0.0...v1.0.1](https://github.com/dry-rb/dry-core/compare/v1.0.0...v1.0.1) + +## 1.0.0 2022-11-04 + + +### Added + +- Import dry-container as `Dry::Core::Container` (via #77) (@solnic) + + +[Compare v0.9.1...v1.0.0](https://github.com/dry-rb/dry-core/compare/v0.9.1...v1.0.0) + +## 0.9.1 2022-10-18 + + +### Changed + +- Correct missing constant for IDENTITY (issue #75 fixed via #76) (@poloka) + +[Compare v0.9.0...v0.9.1](https://github.com/dry-rb/dry-core/compare/v0.9.0...v0.9.1) + +## 0.9.0 2022-10-15 + + +### Changed + +- dry-core now uses zeitwerk for autoloading (@solnic) + +[Compare v0.8.1...v0.9.0](https://github.com/dry-rb/dry-core/compare/v0.8.1...v0.9.0) + +## 0.8.1 2022-07-27 + + +### Fixed + +- [memoizable] plays better with inheritance. +There were cases when cached values from base claesses were used, see #70 (@flash-gordon) + + + +[Compare v0.8.0...v0.8.1](https://github.com/dry-rb/dry-core/compare/v0.8.0...v0.8.1) + +## 0.8.0 2022-07-15 + + +### Added + +- `Dry::Core::BasicObject` ported from hanami-utils (@jodosha) + +### Changed + +- [BREAKING] [descendants tracker] switch to using `Class#subclasses` on Ruby 3.1+. +This changes the order of returned subclasses (immediate subclasses now go first) (@flash-gordon) + + +[Compare v0.7.1...v0.8.0](https://github.com/dry-rb/dry-core/compare/v0.7.1...v0.8.0) + +## 0.7.1 2021-07-10 + + +### Fixed + +- [memoizable] memoizable correctly handles cases where a method +has unnamed params (e.g. happens when the new `...` syntax is used) (@flash-gordon) + + + +[Compare v0.7.0...v0.7.1](https://github.com/dry-rb/dry-core/compare/v0.7.0...v0.7.1) + +## 0.7.0 2021-07-08 + + +### Fixed + +- [memoizable] warnings when using keyword arguments (@flash-gordon) +- [deprecations] warnings show more relevant information about caller by default (@timriley) + +### Changed + +- Minimal Ruby version is 2.6 +- [memoizable] memoization of block-accepting methods is deprecated (@flash-gordon) + +[Compare v0.6.0...v0.7.0](https://github.com/dry-rb/dry-core/compare/v0.6.0...v0.7.0) + +## 0.6.0 2021-06-03 + + +### Added + +- [memoizable] support for `BasicObject` (@oleander) +- [memoizable] support for methods that accept blocks (@oleander) +- [deprecations] allow printing frame info on warn when setting up Deprecation module (via #52) (@waiting-for-dev) + +### Fixed + +- [memoizable] works with MRI 2.7+ keyword arguments now (@oleander) + + +[Compare v0.5.0...v0.6.0](https://github.com/dry-rb/dry-core/compare/v0.5.0...v0.6.0) + +## 0.5.0 2020-12-12 + + +### Added + +- dry-equalizer has been imported into dry-core as `Dry::Core::Equalizer` but the interface remains the same, which is `include Dry.Equalizer(...)` - we'll be porting all other gems that depend on dry-equalizer to the latest dry-core with equalizer included *gradually*. Eventually dry-equalizer usage will be gone completely in rom-rb/dry-rb/hanami projects (@solnic) + + +[Compare v0.4.10...v0.5.0](https://github.com/dry-rb/dry-core/compare/v0.4.10...v0.5.0) + +## 0.4.10 2020-11-19 + + +### Added + +- `ClassAttributes.defines` gets a new option for coercing values (tallica) +```ruby +class Builder + extend Dry::Core::ClassAttributes + + defines :nodes, coerce: -> value { Integer(value) } +end +``` +`:coerce` works with any callable as well as types from dry-types +```ruby +defines :nodes, coerce: Dry::Types['coercible.integer'] +``` +- `Constants::IDENTITY` which is the identity function (flash-gordon) + + +[Compare v0.4.9...v0.4.10](https://github.com/dry-rb/dry-core/compare/v0.4.9...v0.4.10) + +## 0.4.9 2019-08-09 + + +### Added + +- `Undefined.coalesce` takes a variable number of arguments and returns the first non-`Undefined` value (flash-gordon) + + ```ruby + Undefined.coalesce(Undefined, Undefined, :foo) # => :foo + ``` + +### Fixed + +- `Undefined.{dup,clone}` returns `Undefined` back, `Undefined` is a singleton (flash-gordon) + + +[Compare v0.4.8...v0.4.9](https://github.com/dry-rb/dry-core/compare/v0.4.8...v0.4.9) + +## 0.4.8 2019-06-23 + + +### Added + +- `Undefined.map` for mapping non-undefined values (flash-gordon) + + ```ruby + something = 1 + Undefined.map(something) { |v| v + 1 } # => 2 + + something = Undefined + Undefined.map(something) { |v| v + 1 } # => Undefined + ``` + + +[Compare v0.4.7...v0.4.8](https://github.com/dry-rb/dry-core/compare/v0.4.7...v0.4.8) + +## 0.4.7 2018-06-25 + + +### Fixed + +- Fix default logger for deprecations, it now uses `$stderr` by default, as it should (flash-gordon) + + +[Compare v0.4.6...v0.4.7](https://github.com/dry-rb/dry-core/compare/v0.4.6...v0.4.7) + +## 0.4.6 2018-05-15 + + +### Changed + +- Trigger constant autoloading in the class builder (radar) + +[Compare v0.4.5...v0.4.6](https://github.com/dry-rb/dry-core/compare/v0.4.5...v0.4.6) + +## 0.4.5 2018-03-14 + + +### Added + +- `Dry::Core::Memoizable`, which provides a `memoize` macro for memoizing results of instance methods (timriley) + + +[Compare v0.4.4...v0.4.5](https://github.com/dry-rb/dry-core/compare/v0.4.4...v0.4.5) + +## 0.4.4 2018-02-10 + + +### Added + +- `deprecate_constant` overrides `Module#deprecate_constant` and issues a labeled message on accessing a deprecated constant (flash-gordon) +- `Undefined.default` which accepts two arguments and returns the first if it's not `Undefined`; otherwise, returns the second one or yields a block (flash-gordon) + + +[Compare v0.4.3...v0.4.4](https://github.com/dry-rb/dry-core/compare/v0.4.3...v0.4.4) + +## 0.4.3 2018-02-03 + + +### Added + +- `Dry::Core::DescendantsTracker` which is a maintained version of the [`descendants_tracker`](https://github.com/dkubb/descendants_tracker) gem (flash-gordon) + + +[Compare v0.4.2...v0.4.3](https://github.com/dry-rb/dry-core/compare/v0.4.2...v0.4.3) + +## 0.4.2 2017-12-16 + + +### Fixed + +- Class attributes now support private setters/getters (flash-gordon) + + +[Compare v0.4.1...v0.4.2](https://github.com/dry-rb/dry-core/compare/v0.4.1...v0.4.2) + +## 0.4.1 2017-11-04 + + +### Changed + +- Improved error message on invalid attribute value (GustavoCaso) + +[Compare v0.4.0...v0.4.1](https://github.com/dry-rb/dry-core/compare/v0.4.0...v0.4.1) + +## 0.4.0 2017-11-02 + + +### Added + +- Added the `:type` option to class attributes, you can now restrict attribute values with a type. You can either use plain ruby types (`Integer`, `String`, etc) or `dry-types` (GustavoCaso) + + ```ruby + class Foo + extend Dry::Core::ClassAttributes + + defines :ruby_attr, type: Integer + defines :dry_attr, type: Dry::Types['strict.int'] + end + ``` + + +[Compare v0.3.4...v0.4.0](https://github.com/dry-rb/dry-core/compare/v0.3.4...v0.4.0) + +## 0.3.4 2017-09-29 + + +### Fixed + +- `Deprecations` output is set to `$stderr` by default now (solnic) + + +[Compare v0.3.3...v0.3.4](https://github.com/dry-rb/dry-core/compare/v0.3.3...v0.3.4) + +## 0.3.3 2017-08-31 + + +### Fixed + +- The Deprecations module now shows the right caller line (flash-gordon) + + +[Compare v0.3.2...v0.3.3](https://github.com/dry-rb/dry-core/compare/v0.3.2...v0.3.3) + +## 0.3.2 2017-08-31 + + +### Added + +- Accept an existing logger object in `Dry::Core::Deprecations.set_logger!` (flash-gordon) + + +[Compare v0.3.1...v0.3.2](https://github.com/dry-rb/dry-core/compare/v0.3.1...v0.3.2) + +## 0.3.1 2017-05-27 + + +### Added + +- Support for building classes within an existing namespace (flash-gordon) + + +[Compare v0.3.0...v0.3.1](https://github.com/dry-rb/dry-core/compare/v0.3.0...v0.3.1) + +## 0.3.0 2017-05-05 + + +### Changed + +- Class attributes are initialized _before_ running the `inherited` hook. It's slightly more convenient behavior and it's very unlikely anyone will be affected by this, but technically this is a breaking change (flash-gordon) + +[Compare v0.2.4...v0.3.0](https://github.com/dry-rb/dry-core/compare/v0.2.4...v0.3.0) + +## 0.2.4 2017-01-26 + + +### Fixed + +- Do not require deprecated method to be defined (flash-gordon) + + +[Compare v0.2.3...v0.2.4](https://github.com/dry-rb/dry-core/compare/v0.2.3...v0.2.4) + +## 0.2.3 2016-12-30 + + +### Fixed + +- Fix warnings on using uninitialized class attributes (flash-gordon) + + +[Compare v0.2.2...v0.2.3](https://github.com/dry-rb/dry-core/compare/v0.2.2...v0.2.3) + +## 0.2.2 2016-12-30 + + +### Added + +- `ClassAttributes` which provides `defines` method for defining get-or-set methods (flash-gordon) + + +[Compare v0.2.1...v0.2.2](https://github.com/dry-rb/dry-core/compare/v0.2.1...v0.2.2) + +## 0.2.1 2016-11-18 + + +### Added + +- `Constants` are now available in nested scopes (flash-gordon) + + +[Compare v0.2.0...v0.2.1](https://github.com/dry-rb/dry-core/compare/v0.2.0...v0.2.1) + +## 0.2.0 2016-11-01 + + + +[Compare v0.1.0...v0.2.0](https://github.com/dry-rb/dry-core/compare/v0.1.0...v0.2.0) + +## 0.1.0 2016-09-17 + +Initial release diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/LICENSE b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/LICENSE new file mode 100644 index 00000000..9f9f214d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2015-2023 dry-rb team + +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 AUTHORS OR +COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/README.md b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/README.md new file mode 100644 index 00000000..21d2a31d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/README.md @@ -0,0 +1,22 @@ + +[gem]: https://rubygems.org/gems/dry-core +[actions]: https://github.com/dry-rb/dry-core/actions + +# dry-core [![Gem Version](https://badge.fury.io/rb/dry-core.svg)][gem] [![CI Status](https://github.com/dry-rb/dry-core/workflows/CI/badge.svg)][actions] + +## Links + +* [User documentation](https://dry-rb.org/gems/dry-core) +* [API documentation](http://rubydoc.info/gems/dry-core) +* [Forum](https://discourse.dry-rb.org) + +## Supported Ruby versions + +This library officially supports the following Ruby versions: + +* MRI `>= 3.1` +* jruby `>= 9.4` (not tested on CI) + +## License + +See `LICENSE` file. diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/dry-core.gemspec b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/dry-core.gemspec new file mode 100644 index 00000000..95de4ff9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/dry-core.gemspec @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +# this file is synced from dry-rb/template-gem project + +lib = File.expand_path("lib", __dir__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require "dry/core/version" + +Gem::Specification.new do |spec| + spec.name = "dry-core" + spec.authors = ["Nikita Shilnikov"] + spec.email = ["fg@flashgordon.ru"] + spec.license = "MIT" + spec.version = Dry::Core::VERSION.dup + + spec.summary = "A toolset of small support modules used throughout the dry-rb ecosystem" + spec.description = spec.summary + spec.homepage = "https://dry-rb.org/gems/dry-core" + spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-core.gemspec", "lib/**/*"] + spec.bindir = "bin" + spec.executables = [] + spec.require_paths = ["lib"] + + spec.metadata["allowed_push_host"] = "https://rubygems.org" + spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-core/blob/main/CHANGELOG.md" + spec.metadata["source_code_uri"] = "https://github.com/dry-rb/dry-core" + spec.metadata["bug_tracker_uri"] = "https://github.com/dry-rb/dry-core/issues" + spec.metadata["rubygems_mfa_required"] = "true" + + spec.required_ruby_version = ">= 3.1.0" + + # to update dependencies edit project.yml + spec.add_dependency "concurrent-ruby", "~> 1.0" + spec.add_dependency "logger" + spec.add_dependency "zeitwerk", "~> 2.6" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry-core.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry-core.rb new file mode 100644 index 00000000..0ea34c41 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry-core.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +require "dry/core" diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core.rb new file mode 100644 index 00000000..e6222041 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require "zeitwerk" + +require "dry/core/constants" +require "dry/core/errors" +require "dry/core/version" + +# :nodoc: +module Dry + # :nodoc: + module Core + include Constants + + def self.loader + @loader ||= ::Zeitwerk::Loader.new.tap do |loader| + root = ::File.expand_path("..", __dir__) + loader.tag = "dry-core" + loader.inflector = ::Zeitwerk::GemInflector.new("#{root}/dry-core.rb") + loader.push_dir(root) + loader.ignore( + "#{root}/dry-core.rb", + "#{root}/dry/core/{constants,errors,version}.rb" + ) + loader.inflector.inflect("namespace_dsl" => "NamespaceDSL") + end + end + + loader.setup + + # Build an equalizer module for the inclusion in other class + # + # ## Credits + # + # Equalizer has been originally imported from the equalizer gem created by Dan Kubb + # + # @api public + def self.Equalizer(*keys, **options) + Equalizer.new(*keys, **options) + end + end + + # See dry/core/equalizer.rb + unless singleton_class.method_defined?(:Equalizer) + # Build an equalizer module for the inclusion in other class + # + # ## Credits + # + # Equalizer has been originally imported from the equalizer gem created by Dan Kubb + # + # @api public + def self.Equalizer(*keys, **options) + ::Dry::Core::Equalizer.new(*keys, **options) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/basic_object.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/basic_object.rb new file mode 100644 index 00000000..ba8dc6c5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/basic_object.rb @@ -0,0 +1,143 @@ +# frozen_string_literal: true + +# This implementation was imported from `hanami-utils` gem. +module Dry + module Core + # BasicObject + # + # @since 0.8.0 + class BasicObject < ::BasicObject + # Lookups constants at the top-level namespace, if they are missing in the + # current context. + # + # @param name [Symbol] the constant name + # + # @return [Object, Module] the constant + # + # @raise [NameError] if the constant cannot be found + # + # @since 0.8.0 + # @api private + # + # @see https://ruby-doc.org/core/Module.html#method-i-const_missing + def self.const_missing(name) + ::Object.const_get(name) + end + + # Returns the class for debugging purposes. + # + # @since 0.8.0 + # + # @see http://ruby-doc.org/core/Object.html#method-i-class + def class + (class << self; self; end).superclass + end + + # Bare minimum inspect for debugging purposes. + # + # @return [String] the inspect string + # + # @since 0.8.0 + # + # @see http://ruby-doc.org/core/Object.html#method-i-inspect + inspect_method = ::Kernel.instance_method(:inspect) + define_method(:inspect) do + original = inspect_method.bind_call(self) + "#{original[0...-1]}#{__inspect}>" + end + + # @!macro [attach] instance_of?(class) + # + # Determines if self is an instance of given class or module + # + # @param class [Class,Module] the class of module to verify + # + # @return [TrueClass,FalseClass] the result of the check + # + # @raise [TypeError] if the given argument is not of the expected types + # + # @since 0.8.0 + # + # @see http://ruby-doc.org/core/Object.html#method-i-instance_of-3F + define_method :instance_of?, ::Object.instance_method(:instance_of?) + + # @!macro [attach] is_a?(class) + # + # Determines if self is of the type of the object class or module + # + # @param class [Class,Module] the class of module to verify + # + # @return [TrueClass,FalseClass] the result of the check + # + # @raise [TypeError] if the given argument is not of the expected types + # + # @since 0.8.0 + # + # @see http://ruby-doc.org/core/Object.html#method-i-is_a-3F + define_method :is_a?, ::Object.instance_method(:is_a?) + + # @!macro [attach] kind_of?(class) + # + # Determines if self is of the kind of the object class or module + # + # @param class [Class,Module] the class of module to verify + # + # @return [TrueClass,FalseClass] the result of the check + # + # @raise [TypeError] if the given argument is not of the expected types + # + # @since 0.8.0 + # + # @see http://ruby-doc.org/core/Object.html#method-i-kind_of-3F + define_method :kind_of?, ::Object.instance_method(:kind_of?) + + # Alias for __id__ + # + # @return [Fixnum] the object id + # + # @since 0.8.0 + # + # @see http://ruby-doc.org/core/Object.html#method-i-object_id + def object_id + __id__ + end + + # Interface for pp + # + # @param printer [PP] the Pretty Printable printer + # @return [String] the pretty-printable inspection of the object + # + # @since 0.8.0 + # + # @see https://ruby-doc.org/stdlib/libdoc/pp/rdoc/PP.html + def pretty_print(printer) + printer.text(inspect) + end + + # Returns true if responds to the given method. + # + # @return [TrueClass,FalseClass] the result of the check + # + # @since 0.8.0 + # + # @see http://ruby-doc.org/core/Object.html#method-i-respond_to-3F + def respond_to?(method_name, include_all = false) # rubocop:disable Style/OptionalBooleanParameter + respond_to_missing?(method_name, include_all) + end + + private + + # Must be overridden by descendants + # + # @since 0.8.0 + # @api private + def respond_to_missing?(_method_name, _include_all) + ::Kernel.raise ::NotImplementedError + end + + # @since 0.8.0 + # @api private + def __inspect; end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/cache.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/cache.rb new file mode 100644 index 00000000..fde3e50b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/cache.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +require "concurrent/map" + +module Dry + module Core + # Allows you to cache call results that are solely determined by arguments. + # + # @example + # require 'dry/core/cache' + # + # class Foo + # extend Dry::Core::Cache + # + # def heavy_computation(arg1, arg2) + # fetch_or_store(arg1, arg2) { arg1 ^ arg2 } + # end + # end + # + # @api public + module Cache + # @api private + def self.extended(klass) + super + klass.include(Methods) + klass.instance_variable_set(:@__cache__, ::Concurrent::Map.new) + end + + # @api private + def inherited(klass) + super + klass.instance_variable_set(:@__cache__, cache) + end + + # @api private + def cache + @__cache__ + end + + # Caches a result of the block evaluation + # + # @param [Array] args List of hashable objects + # @yield An arbitrary block + # + # @note beware Proc instance hashes are not equal, i.e. -> { 1 }.hash != -> { 1 }.hash, + # this means you shouldn't pass Procs in args unless you're sure + # they are always the same instances, otherwise you introduce a memory leak + # + # @return [Object] block's return value (cached for subsequent calls with + # the same argument values) + def fetch_or_store(*args, &) + cache.fetch_or_store(args.hash, &) + end + + # Instance methods + module Methods + # Delegates call to the class-level method + # + # @param [Array] args List of hashable objects + # @yield An arbitrary block + # + # @return [Object] block's return value + def fetch_or_store(...) + self.class.fetch_or_store(...) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/class_attributes.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/class_attributes.rb new file mode 100644 index 00000000..bfaa0272 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/class_attributes.rb @@ -0,0 +1,103 @@ +# frozen_string_literal: true + +require "dry/core/constants" + +module Dry + module Core + # Internal support module for class-level settings + # + # @api public + module ClassAttributes + include Constants + # Specify what attributes a class will use + # + # @example + # class ExtraClass + # extend Dry::Core::ClassAttributes + # + # defines :hello + # + # hello 'world' + # end + # + # @example with inheritance and type checking + # + # class MyClass + # extend Dry::Core::ClassAttributes + # + # defines :one, :two, type: Integer + # + # one 1 + # two 2 + # end + # + # class OtherClass < MyClass + # two 3 + # end + # + # MyClass.one # => 1 + # MyClass.two # => 2 + # + # OtherClass.one # => 1 + # OtherClass.two # => 3 + # + # @example with dry-types + # + # class Foo + # extend Dry::Core::ClassAttributes + # + # defines :one, :two, type: Dry::Types['strict.int'] + # end + # + # @example with coercion using Proc + # + # class Bar + # extend Dry::Core::ClassAttributes + # + # defines :one, coerce: proc { |value| value.to_s } + # end + # + # @example with coercion using dry-types + # + # class Bar + # extend Dry::Core::ClassAttributes + # + # defines :one, coerce: Dry::Types['coercible.string'] + # end + # + def defines(*args, type: ::Object, coerce: IDENTITY) # rubocop:disable Metrics/PerceivedComplexity + unless coerce.respond_to?(:call) + raise ::ArgumentError, "Non-callable coerce option: #{coerce.inspect}" + end + + mod = ::Module.new do + args.each do |name| + ivar = :"@#{name}" + + define_method(name) do |value = Undefined| + if Undefined.equal?(value) + if instance_variable_defined?(ivar) + instance_variable_get(ivar) + else + nil + end + elsif type === value # rubocop:disable Style/CaseEquality + instance_variable_set(ivar, coerce.call(value)) + else + raise InvalidClassAttributeValueError.new(name, value) + end + end + end + + define_method(:inherited) do |klass| + args.each { |name| klass.send(name, send(name)) } + + super(klass) + end + end + + extend(mod) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/class_builder.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/class_builder.rb new file mode 100644 index 00000000..09c5a363 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/class_builder.rb @@ -0,0 +1,103 @@ +# frozen_string_literal: true + +module Dry + module Core + # Class for generating more classes + class ClassBuilder + ParentClassMismatch = ::Class.new(::TypeError) + + attr_reader :name, :parent, :namespace + + def initialize(name:, parent: nil, namespace: nil) + @name = name + @namespace = namespace + @parent = parent || ::Object + end + + # Generate a class based on options + # + # @example Create anonymous class + # builder = Dry::Core::ClassBuilder.new(name: 'MyClass') + # + # klass = builder.call + # klass.name # => "MyClass" + # + # @example Create named class + # builder = Dry::Core::ClassBuilder.new(name: 'User', namespace: Entities) + # + # klass = builder.call + # klass.name # => "Entities::User" + # klass.superclass.name # => "Entities::User" + # Entities::User # => "Entities::User" + # klass.superclass == Entities::User # => true + # + # @return [Class] + def call + klass = if namespace + create_named + else + create_anonymous + end + + yield(klass) if block_given? + + klass + end + + private + + # @api private + def create_anonymous + klass = ::Class.new(parent) + name = self.name + + klass.singleton_class.class_eval do + define_method(:name) { name } + alias_method :inspect, :name + alias_method :to_s, :name + end + + klass + end + + # @api private + def create_named + name = self.name + base = create_base(namespace, name, parent) + klass = ::Class.new(base) + + namespace.module_eval do + remove_const(name) + const_set(name, klass) + + remove_const(name) + const_set(name, base) + end + + klass + end + + # @api private + def create_base(namespace, name, parent) + begin + namespace.const_get(name) + rescue NameError # rubocop:disable Lint/SuppressedException + end + + if namespace.const_defined?(name, false) + existing = namespace.const_get(name) + + unless existing <= parent + raise ParentClassMismatch, "#{existing.name} must be a subclass of #{parent.name}" + end + + existing + else + klass = ::Class.new(parent || ::Object) + namespace.const_set(name, klass) + klass + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/constants.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/constants.rb new file mode 100644 index 00000000..e5f52d3b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/constants.rb @@ -0,0 +1,117 @@ +# frozen_string_literal: true + +require "set" + +module Dry + module Core + # A list of constants you can use to avoid memory allocations or identity checks. + # + # @example Just include this module to your class or module + # class Foo + # include Dry::Core::Constants + # def call(value = EMPTY_ARRAY) + # value.map(&:to_s) + # end + # end + # + # @api public + module Constants + # An empty array + EMPTY_ARRAY = [].freeze + # An empty hash + EMPTY_HASH = {}.freeze + # An empty list of options + EMPTY_OPTS = {}.freeze + # An empty set + EMPTY_SET = ::Set.new.freeze + # An empty string + EMPTY_STRING = "" + # Identity function + IDENTITY = ->(x) { x }.freeze + + # A special value you can use as a default to know if no arguments + # were passed to the method + # + # @example + # def method(value = Undefined) + # if Undefined.equal?(value) + # puts 'no args' + # else + # puts value + # end + # end + Undefined = ::Object.new.tap do |undefined| + # @api private + Self = -> { Undefined } # rubocop:disable Lint/ConstantDefinitionInBlock + + # @api public + def undefined.to_s + "Undefined" + end + + # @api public + def undefined.inspect + "Undefined" + end + + # Pick a value, if the first argument is not Undefined, return it back, + # otherwise return the second arg or yield the block. + # + # @example + # def method(val = Undefined) + # 1 + Undefined.default(val, 2) + # end + # + def undefined.default(x, y = self) + if equal?(x) + if equal?(y) + yield + else + y + end + else + x + end + end + + # Map a non-undefined value + # + # @example + # def add_five(val = Undefined) + # Undefined.map(val) { |x| x + 5 } + # end + # + def undefined.map(value) + if equal?(value) + self + else + yield(value) + end + end + + # @api public + def undefined.dup + self + end + + # @api public + def undefined.clone + self + end + + # @api public + def undefined.coalesce(*args) + args.find(Self) { |x| !equal?(x) } + end + end.freeze + + def self.included(base) + super + + constants.each do |const_name| + base.const_set(const_name, const_get(const_name)) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container.rb new file mode 100644 index 00000000..761f452b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Dry + module Core + # Thread-safe object registry + # + # @example + # + # container = Dry::Core::Container.new + # container.register(:item, 'item') + # container.resolve(:item) + # => 'item' + # + # container.register(:item1, -> { 'item' }) + # container.resolve(:item1) + # => 'item' + # + # container.register(:item2, -> { 'item' }, call: false) + # container.resolve(:item2) + # => # + # + # @api public + class Container + include Container::Mixin + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/config.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/config.rb new file mode 100644 index 00000000..207121b5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/config.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module Dry + module Core + class Container + # @api public + class Config + DEFAULT_NAMESPACE_SEPARATOR = "." + DEFAULT_RESOLVER = Resolver.new + DEFAULT_REGISTRY = Registry.new + + # @api public + attr_accessor :namespace_separator + + # @api public + attr_accessor :resolver + + # @api public + attr_accessor :registry + + # @api private + def initialize( + namespace_separator: DEFAULT_NAMESPACE_SEPARATOR, + resolver: DEFAULT_RESOLVER, + registry: DEFAULT_REGISTRY + ) + @namespace_separator = namespace_separator + @resolver = resolver + @registry = registry + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/configuration.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/configuration.rb new file mode 100644 index 00000000..be062068 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/configuration.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module Dry + module Core + class Container + # @api public + module Configuration + # Use dry/configurable if it's available + begin + require "dry/configurable" + + # @api private + def self.extended(klass) + super + klass.class_eval do + extend Dry::Configurable + + setting :namespace_separator, default: Config::DEFAULT_NAMESPACE_SEPARATOR + setting :resolver, default: Config::DEFAULT_RESOLVER + setting :registry, default: Config::DEFAULT_REGISTRY + end + end + rescue LoadError + # @api private + def config + @config ||= Container::Config.new + end + end + + # @api private + def configure + yield config + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/item.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/item.rb new file mode 100644 index 00000000..30b16a2a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/item.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +module Dry + module Core + class Container + # Base class to abstract Memoizable and Callable implementations + # + # @api abstract + # + class Item + NO_OPTIONS = {}.freeze + + # @return [Mixed] the item to be solved later + attr_reader :item + + # @return [Hash] the options to memoize, call or no. + attr_reader :options + + # @api abstract + def initialize(item, options = NO_OPTIONS) + @item = item + @options = { + call: item.is_a?(::Proc) && item.parameters.empty?, + **options + } + end + + # @api abstract + def call + raise ::NotImplementedError + end + + # @private + def value? + !callable? + end + + # @private + def callable? + options[:call] + end + + # Build a new item with transformation applied + # + # @private + def map(func) + if callable? + self.class.new(-> { func.(item.call) }, options) + else + self.class.new(func.(item), options) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/item/callable.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/item/callable.rb new file mode 100644 index 00000000..bf2ad693 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/item/callable.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Dry + module Core + class Container + class Item + # Callable class to returns a item call + # + # @api public + # + class Callable < Item + # Returns the result of item call or item + # + # @return [Mixed] + def call + callable? ? item.call : item + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/item/factory.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/item/factory.rb new file mode 100644 index 00000000..9837037b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/item/factory.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module Dry + module Core + class Container + class Item + # Factory for create an Item to register inside of container + # + # @api public + class Factory + # Creates an Item Memoizable or Callable + # @param [Mixed] item + # @param [Hash] options + # + # @raise [Dry::Core::Container::Error] + # + # @return [Dry::Core::Container::Item::Base] + def call(item, options = {}) + if options[:memoize] + Item::Memoizable.new(item, options) + else + Item::Callable.new(item, options) + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/item/memoizable.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/item/memoizable.rb new file mode 100644 index 00000000..45ec57e8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/item/memoizable.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +module Dry + module Core + class Container + class Item + # Memoizable class to store and execute item calls + # + # @api public + # + class Memoizable < Item + # @return [Mutex] the stored mutex + attr_reader :memoize_mutex + + # Returns a new Memoizable instance + # + # @param [Mixed] item + # @param [Hash] options + # + # @raise [Dry::Core::Container::Error] + # + # @return [Dry::Core::Container::Item::Base] + def initialize(item, options = {}) + super + raise_not_supported_error unless callable? + + @memoize_mutex = ::Mutex.new + end + + # Returns the result of item call using a syncronized mutex + # + # @return [Dry::Core::Container::Item::Base] + def call + memoize_mutex.synchronize do + @memoized_item ||= item.call + end + end + + private + + # @private + def raise_not_supported_error + raise ::Dry::Core::Container::Error, "Memoize only supported for a block or a proc" + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/mixin.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/mixin.rb new file mode 100644 index 00000000..ed474940 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/mixin.rb @@ -0,0 +1,311 @@ +# frozen_string_literal: true + +require "concurrent/hash" +require "dry/core/constants" + +module Dry + module Core + class Container + include ::Dry::Core::Constants + + # @api public + Error = ::Class.new(::StandardError) + + # Error raised when key is not defined in the registry + # + # @api public + KeyError = ::Class.new(::KeyError) + + if defined?(::DidYouMean::KeyErrorChecker) + ::DidYouMean.correct_error(KeyError, ::DidYouMean::KeyErrorChecker) + end + + # Mixin to expose Inversion of Control (IoC) container behaviour + # + # @example + # + # class MyClass + # extend Dry::Core::Container::Mixin + # end + # + # MyClass.register(:item, 'item') + # MyClass.resolve(:item) + # => 'item' + # + # class MyObject + # include Dry::Core::Container::Mixin + # end + # + # container = MyObject.new + # container.register(:item, 'item') + # container.resolve(:item) + # => 'item' + # + # @api public + # + # rubocop:disable Metrics/ModuleLength + module Mixin + PREFIX_NAMESPACE = lambda do |namespace, key, config| + [namespace, key].join(config.namespace_separator) + end + + # @private + def self.extended(base) + hooks_mod = ::Module.new do + def inherited(subclass) + subclass.instance_variable_set(:@_container, @_container.dup) + super + end + end + + base.class_eval do + extend Configuration + extend hooks_mod + + @_container = ::Concurrent::Hash.new + end + end + + # @private + module Initializer + def initialize(...) + @_container = ::Concurrent::Hash.new + super + end + end + + # @private + def self.included(base) + base.class_eval do + extend Configuration + prepend Initializer + + def config + self.class.config + end + end + end + + # Register an item with the container to be resolved later + # + # @param [Mixed] key + # The key to register the container item with (used to resolve) + # @param [Mixed] contents + # The item to register with the container (if no block given) + # @param [Hash] options + # Options to pass to the registry when registering the item + # @yield + # If a block is given, contents will be ignored and the block + # will be registered instead + # + # @return [Dry::Core::Container::Mixin] self + # + # @api public + def register(key, contents = nil, options = EMPTY_HASH, &block) + if block_given? + item = block + options = contents if contents.is_a?(::Hash) + else + item = contents + end + + config.registry.call(_container, key, item, options) + + self + rescue ::FrozenError + raise ::FrozenError, + "can't modify frozen #{self.class} (when attempting to register '#{key}')" + end + + # Resolve an item from the container + # + # @param [Mixed] key + # The key for the item you wish to resolve + # @yield + # Fallback block to call when a key is missing. Its result will be returned + # @yieldparam [Mixed] key Missing key + # + # @return [Mixed] + # + # @api public + def resolve(key, &) + config.resolver.call(_container, key, &) + end + + # Resolve an item from the container + # + # @param [Mixed] key + # The key for the item you wish to resolve + # + # @return [Mixed] + # + # @api public + # @see Dry::Core::Container::Mixin#resolve + def [](key) + resolve(key) + end + + # Merge in the items of the other container + # + # @param [Dry::Core::Container] other + # The other container to merge in + # @param [Symbol, nil] namespace + # Namespace to prefix other container items with, defaults to nil + # + # @return [Dry::Core::Container::Mixin] self + # + # @api public + def merge(other, namespace: nil, &block) + if namespace + _container.merge!( + other._container.each_with_object(::Concurrent::Hash.new) { |(key, item), hsh| + hsh[PREFIX_NAMESPACE.call(namespace, key, config)] = item + }, + &block + ) + else + _container.merge!(other._container, &block) + end + + self + end + + # Check whether an item is registered under the given key + # + # @param [Mixed] key + # The key you wish to check for registration with + # + # @return [Bool] + # + # @api public + def key?(key) + config.resolver.key?(_container, key) + end + + # An array of registered names for the container + # + # @return [Array] + # + # @api public + def keys + config.resolver.keys(_container) + end + + # Calls block once for each key in container, passing the key as a parameter. + # + # If no block is given, an enumerator is returned instead. + # + # @return [Dry::Core::Container::Mixin] self + # + # @api public + def each_key(&) + config.resolver.each_key(_container, &) + self + end + + # Calls block once for each key/value pair in the container, passing the key and + # the registered item parameters. + # + # If no block is given, an enumerator is returned instead. + # + # @return [Enumerator] + # + # @api public + # + # @note In discussions with other developers, it was felt that being able to iterate + # over not just the registered keys, but to see what was registered would be + # very helpful. This is a step toward doing that. + def each(&) + config.resolver.each(_container, &) + end + + # Decorates an item from the container with specified decorator + # + # @return [Dry::Core::Container::Mixin] self + # + # @api public + def decorate(key, with: nil, &block) + key = key.to_s + original = _container.delete(key) do + raise KeyError, "Nothing registered with the key #{key.inspect}" + end + + if with.is_a?(Class) + decorator = with.method(:new) + elsif block.nil? && !with.respond_to?(:call) + raise Error, "Decorator needs to be a Class, block, or respond to the `call` method" + else + decorator = with || block + end + + _container[key] = original.map(decorator) + self + end + + # Evaluate block and register items in namespace + # + # @param [Mixed] namespace + # The namespace to register items in + # + # @return [Dry::Core::Container::Mixin] self + # + # @api public + def namespace(namespace, &) + ::Dry::Core::Container::NamespaceDSL.new( + self, + namespace, + config.namespace_separator, + & + ) + + self + end + + # Import a namespace + # + # @param [Dry::Core::Container::Namespace] namespace + # The namespace to import + # + # @return [Dry::Core::Container::Mixin] self + # + # @api public + def import(namespace) + namespace(namespace.name, &namespace.block) + + self + end + + # Freeze the container. Nothing can be registered after freezing + # + # @api public + def freeze + super + _container.freeze + self + end + + # @private no, really + def _container + @_container + end + + # @api public + def dup + copy = super + copy.instance_variable_set(:@_container, _container.dup) + copy + end + + # @api public + def clone + copy = super + unless copy.frozen? + copy.instance_variable_set(:@_container, _container.dup) + end + copy + end + end + # rubocop:enable Metrics/ModuleLength + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/namespace.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/namespace.rb new file mode 100644 index 00000000..f892a85e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/namespace.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +module Dry + module Core + class Container + # Create a namespace to be imported + # + # @example + # + # ns = Dry::Core::Container::Namespace.new('name') do + # register('item', 'item') + # end + # + # container = Dry::Core::Container.new + # + # container.import(ns) + # + # container.resolve('name.item') + # => 'item' + # + # + # @api public + class Namespace + # @return [Mixed] The namespace (name) + attr_reader :name + + # @return [Proc] The block to be executed when the namespace is imported + attr_reader :block + + # Create a new namespace + # + # @param [Mixed] name + # The name of the namespace + # @yield + # The block to evaluate when the namespace is imported + # + # @return [Dry::Core::Container::Namespace] + # + # @api public + def initialize(name, &block) + @name = name + @block = block + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/namespace_dsl.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/namespace_dsl.rb new file mode 100644 index 00000000..19928e45 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/namespace_dsl.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require "delegate" + +module Dry + module Core + class Container + # @api private + class NamespaceDSL < ::SimpleDelegator + # DSL for defining namespaces + # + # @param [Dry::Core::Container::Mixin] container + # The container + # @param [String] namespace + # The namespace (name) + # @param [String] namespace_separator + # The namespace separator + # @yield + # The block to evaluate to define the namespace + # + # @return [Mixed] + # + # @api private + def initialize(container, namespace, namespace_separator, &block) + @namespace = namespace + @namespace_separator = namespace_separator + + super(container) + + if block.arity.zero? + instance_eval(&block) + else + yield self + end + end + + def register(key, ...) + super(namespaced(key), ...) + end + + def namespace(namespace, &) + super(namespaced(namespace), &) + end + + def import(namespace) + namespace(namespace.name, &namespace.block) + + self + end + + def resolve(key) + super(namespaced(key)) + end + + private + + def namespaced(key) + [@namespace, key].join(@namespace_separator) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/registry.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/registry.rb new file mode 100644 index 00000000..dfdd15a7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/registry.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +module Dry + module Core + class Container + # Default registry for registering items with the container + # + # @api public + class Registry + # @private + def initialize + @_mutex = ::Mutex.new + end + + # Register an item with the container to be resolved later + # + # @param [Concurrent::Hash] container + # The container + # @param [Mixed] key + # The key to register the container item with (used to resolve) + # @param [Mixed] item + # The item to register with the container + # @param [Hash] options + # @option options [Symbol] :call + # Whether the item should be called when resolved + # + # @raise [Dry::Core::Container::KeyError] + # If an item is already registered with the given key + # + # @return [Mixed] + # + # @api public + def call(container, key, item, options) + key = key.to_s.dup.freeze + + @_mutex.synchronize do + if container.key?(key) + raise KeyError, "There is already an item registered with the key #{key.inspect}" + end + + container[key] = factory.call(item, options) + end + end + + # @api private + def factory + @factory ||= Container::Item::Factory.new + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/resolver.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/resolver.rb new file mode 100644 index 00000000..e2a94dc4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/resolver.rb @@ -0,0 +1,90 @@ +# frozen_string_literal: true + +module Dry + module Core + class Container + # Default resolver for resolving items from container + # + # @api public + class Resolver + # Resolve an item from the container + # + # @param [Concurrent::Hash] container + # The container + # @param [Mixed] key + # The key for the item you wish to resolve + # @yield + # Fallback block to call when a key is missing. Its result will be returned + # @yieldparam [Mixed] key Missing key + # + # @raise [KeyError] + # If the given key is not registered with the container (and no block provided) + # + # + # @return [Mixed] + # + # @api public + def call(container, key) + item = container.fetch(key.to_s) do + if block_given? + return yield(key) + else + raise KeyError.new(%(key not found: "#{key}"), key: key.to_s, receiver: container) + end + end + + item.call + end + + # Check whether an items is registered under the given key + # + # @param [Concurrent::Hash] container + # The container + # @param [Mixed] key + # The key you wish to check for registration with + # + # @return [Bool] + # + # @api public + def key?(container, key) + container.key?(key.to_s) + end + + # An array of registered names for the container + # + # @return [Array] + # + # @api public + def keys(container) + container.keys + end + + # Calls block once for each key in container, passing the key as a parameter. + # + # If no block is given, an enumerator is returned instead. + # + # @return Hash + # + # @api public + def each_key(container, &) + container.each_key(&) + end + + # Calls block once for each key in container, passing the key and + # the registered item parameters. + # + # If no block is given, an enumerator is returned instead. + # + # @return Key, Value + # + # @api public + # @note In discussions with other developers, it was felt that being able + # to iterate over not just the registered keys, but to see what was + # registered would be very helpful. This is a step toward doing that. + def each(container, &) + container.map { |key, value| [key, value.call] }.each(&) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/stub.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/stub.rb new file mode 100644 index 00000000..6d588a25 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/container/stub.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +module Dry + module Core + class Container + module Stub + # Overrides resolve to look into stubbed keys first + # + # @api public + def resolve(key) + _stubs.fetch(key.to_s) { super } + end + + # Add a stub to the container + def stub(key, value, &block) + unless key?(key) + raise ::ArgumentError, "cannot stub #{key.to_s.inspect} - no such key in container" + end + + _stubs[key.to_s] = value + + if block + yield + unstub(key) + end + + self + end + + # Remove stubbed keys from the container + def unstub(*keys) + keys = _stubs.keys if keys.empty? + keys.each { |key| _stubs.delete(key.to_s) } + end + + # Stubs have already been enabled turning this into a noop + def enable_stubs! + # DO NOTHING + end + + private + + # Stubs container + def _stubs + @_stubs ||= {} + end + end + + module Mixin + # Enable stubbing functionality into the current container + def enable_stubs! + extend ::Dry::Core::Container::Stub + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/deprecations.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/deprecations.rb new file mode 100644 index 00000000..25485450 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/deprecations.rb @@ -0,0 +1,237 @@ +# frozen_string_literal: true + +require "logger" + +module Dry + module Core + # An extension for issuing warnings on using deprecated methods. + # + # @example + # + # class Foo + # def self.old_class_api; end + # def self.new_class_api; end + # + # deprecate_class_method :old_class_api, :new_class_api + # + # def old_api; end + # def new_api; end + # + # deprecate :old_api, :new_api, message: "old_api is no-no" + # end + # + # @example You also can use this module for your custom messages + # + # Dry::Core::Deprecations.announce("Foo", "use bar instead") + # Dry::Core::Deprecations.warn("Baz is going to be removed soon") + # + # @api public + module Deprecations + STACK = -> { caller.find { |l| l !~ %r{(lib/dry/core)|(gems)} } } + + class << self + # Prints a warning + # + # @param [String] msg Warning string + # @param [String] tag Tag to help identify the source of the warning. + # Defaults to "deprecated" + # @param [Integer] Caller frame to add to the message + def warn(msg, tag: nil, uplevel: nil) + caller_info = uplevel.nil? ? nil : "#{caller_locations(uplevel + 2, 1)[0]} " + tag = "[#{tag || "deprecated"}] " + hint = msg.gsub(/^\s+/, "") + + logger.warn("#{caller_info}#{tag}#{hint}") + end + + # Wraps arguments with a standard message format and prints a warning + # + # @param [Object] name what is deprecated + # @param [String] msg additional message usually containing upgrade instructions + def announce(name, msg, tag: nil, uplevel: nil) + # Bump the uplevel (if provided) by one to account for the uplevel calculation + # taking place one frame deeper in `.warn` + uplevel += 1 if uplevel + + warn(deprecation_message(name, msg), tag: tag, uplevel: uplevel) + end + + # @api private + def deprecation_message(name, msg) + <<-MSG + #{name} is deprecated and will be removed in the next major version + #{msg} + MSG + end + + # @api private + def deprecated_name_message(old, new = nil, msg = nil) + if new + deprecation_message(old, <<-MSG) + Please use #{new} instead. + #{msg} + MSG + else + deprecation_message(old, msg) + end + end + + # Returns the logger used for printing warnings. + # You can provide your own with .set_logger! + # + # @param [IO] output output stream + # + # @return [Logger] + def logger(output = $stderr) + if defined?(@logger) + @logger + else + set_logger!(output) + end + end + + # Sets a custom logger. This is a global setting. + # + # @overload set_logger!(output) + # @param [IO] output Stream for messages + # + # @overload set_logger! + # Stream messages to stdout + # + # @overload set_logger!(logger) + # @param [#warn] logger + # + # @api public + def set_logger!(output = $stderr) + if output.respond_to?(:warn) + @logger = output + else + @logger = ::Logger.new(output).tap do |logger| + logger.formatter = proc { |_, _, _, msg| "#{msg}\n" } + end + end + end + + def [](tag) + Tagged.new(tag) + end + end + + # @api private + class Tagged < ::Module + def initialize(tag) + super() + @tag = tag + end + + def extended(base) + base.extend Interface + base.deprecation_tag @tag + end + end + + module Interface + # Sets/gets deprecation tag + # + # @option [String,Symbol] tag tag + def deprecation_tag(tag = nil) + if defined?(@deprecation_tag) + @deprecation_tag + else + @deprecation_tag = tag + end + end + + # Issue a tagged warning message + # + # @param [String] msg warning message + def warn(msg) + Deprecations.warn(msg, tag: deprecation_tag) + end + + # Mark instance method as deprecated + # + # @param [Symbol] old_name deprecated method + # @param [Symbol] new_name replacement (not required) + # @option [String] message optional deprecation message + def deprecate(old_name, new_name = nil, message: nil) + full_msg = Deprecations.deprecated_name_message( + "#{name}##{old_name}", + new_name ? "#{name}##{new_name}" : nil, + message + ) + mod = self + + if new_name + undef_method old_name if method_defined?(old_name) + + define_method(old_name) do |*args, &block| + mod.warn("#{full_msg}\n#{STACK.()}") + __send__(new_name, *args, &block) + end + else + aliased_name = :"#{old_name}_without_deprecation" + alias_method aliased_name, old_name + private aliased_name + undef_method old_name + + define_method(old_name) do |*args, &block| + mod.warn("#{full_msg}\n#{STACK.()}") + __send__(aliased_name, *args, &block) + end + end + end + + # Mark class-level method as deprecated + # + # @param [Symbol] old_name deprecated method + # @param [Symbol] new_name replacement (not required) + # @option [String] message optional deprecation message + def deprecate_class_method(old_name, new_name = nil, message: nil) + full_msg = Deprecations.deprecated_name_message( + "#{name}.#{old_name}", + new_name ? "#{name}.#{new_name}" : nil, + message + ) + + meth = method(new_name || old_name) + + singleton_class.instance_exec do + undef_method old_name if method_defined?(old_name) + + define_method(old_name) do |*args, &block| + warn("#{full_msg}\n#{STACK.()}") + meth.call(*args, &block) + end + end + end + + # Mark a constant as deprecated + # @param [Symbol] constant_name constant name to be deprecated + # @option [String] message optional deprecation message + def deprecate_constant(constant_name, message: nil) + value = const_get(constant_name) + remove_const(constant_name) + + full_msg = Deprecations.deprecated_name_message( + "#{name}::#{constant_name}", + message + ) + + mod = ::Module.new do + define_method(:const_missing) do |missing| + if missing == constant_name + warn("#{full_msg}\n#{STACK.()}") + value + else + super(missing) + end + end + end + + extend(mod) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/descendants_tracker.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/descendants_tracker.rb new file mode 100644 index 00000000..f66f51fc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/descendants_tracker.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true + +require "concurrent/array" + +module Dry + module Core + # An implementation of descendants tracker, heavily inspired + # by the descendants_tracker gem. + # + # @example + # + # class Base + # extend Dry::Core::DescendantsTracker + # end + # + # class A < Base + # end + # + # class B < Base + # end + # + # class C < A + # end + # + # Base.descendants # => [C, B, A] + # A.descendants # => [C] + # B.descendants # => [] + # + module DescendantsTracker + class << self + # @api private + def setup(target) + target.instance_variable_set(:@descendants, ::Concurrent::Array.new) + end + + private + + # @api private + def extended(base) + super + + DescendantsTracker.setup(base) + end + end + + # Return the descendants of this class + # + # @example + # descendants = Parent.descendants + # + # @return [Array] + # + # @api public + attr_reader :descendants + + protected + + # @api private + def add_descendant(descendant) + ancestor = superclass + if ancestor.respond_to?(:add_descendant, true) + ancestor.add_descendant(descendant) + end + descendants.unshift(descendant) + end + + private + + # @api private + def inherited(descendant) + super + + DescendantsTracker.setup(descendant) + add_descendant(descendant) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/equalizer.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/equalizer.rb new file mode 100644 index 00000000..1f988441 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/equalizer.rb @@ -0,0 +1,156 @@ +# frozen_string_literal: true + +module Dry + module Core + # Define equality, equivalence and inspection methods + class Equalizer < ::Module + # Initialize an Equalizer with the given keys + # + # Will use the keys with which it is initialized to define #cmp?, + # #hash, and #inspect + # + # @param [Array] keys + # @param [Hash] options + # @option options [Boolean] :inspect whether to define #inspect method + # @option options [Boolean] :immutable whether to memoize #hash method + # + # @return [undefined] + # + # @api private + def initialize(*keys, **options) + super() + @keys = keys.uniq + define_methods(**options) + freeze + end + + private + + # Hook called when module is included + # + # @param [Module] descendant + # the module or class including Equalizer + # + # @return [self] + # + # @api private + def included(descendant) + super + descendant.include Methods + end + + # Define the equalizer methods based on #keys + # + # @param [Boolean] inspect whether to define #inspect method + # @param [Boolean] immutable whether to memoize #hash method + # + # @return [undefined] + # + # @api private + def define_methods(inspect: true, immutable: false) + define_cmp_method + define_hash_method(immutable: immutable) + define_inspect_method if inspect + end + + # Define an #cmp? method based on the instance's values identified by #keys + # + # @return [undefined] + # + # @api private + def define_cmp_method + keys = @keys + define_method(:cmp?) do |comparator, other| + keys.all? do |key| + __send__(key).public_send(comparator, other.__send__(key)) + end + end + private :cmp? + end + + # Define a #hash method based on the instance's values identified by #keys + # + # @return [undefined] + # + # @api private + def define_hash_method(immutable:) + calculate_hash = ->(obj) { @keys.map { |key| obj.__send__(key) }.push(obj.class).hash } + if immutable + define_method(:hash) do + @__hash__ ||= calculate_hash.call(self) + end + define_method(:freeze) do + hash + super() + end + else + define_method(:hash) do + calculate_hash.call(self) + end + end + end + + # Define an inspect method that reports the values of the instance's keys + # + # @return [undefined] + # + # @api private + def define_inspect_method + keys = @keys + define_method(:inspect) do + klass = self.class + name = klass.name || klass.inspect + "#<#{name}#{keys.map { |key| " #{key}=#{__send__(key).inspect}" }.join}>" + end + end + + # The comparison methods + module Methods + # Compare the object with other object for equality + # + # @example + # object.eql?(other) # => true or false + # + # @param [Object] other + # the other object to compare with + # + # @return [Boolean] + # + # @api public + def eql?(other) + instance_of?(other.class) && cmp?(__method__, other) + end + + # Compare the object with other object for equivalency + # + # @example + # object == other # => true or false + # + # @param [Object] other + # the other object to compare with + # + # @return [Boolean] + # + # @api public + def ==(other) + other.is_a?(self.class) && cmp?(__method__, other) + end + end + end + end + + # Old modules that depend on dry/core/equalizer may miss + # this method if dry/core is not required explicitly + unless singleton_class.method_defined?(:Equalizer) + # Build an equalizer module for the inclusion in other class + # + # ## Credits + # + # Equalizer has been originally imported from the equalizer gem created by Dan Kubb + # + # @api public + def self.Equalizer(*keys, **options) + ::Dry::Core::Equalizer.new(*keys, **options) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/errors.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/errors.rb new file mode 100644 index 00000000..c4abfcc2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/errors.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Dry + module Core + class InvalidClassAttributeValueError < ::StandardError + def initialize(name, value) + super( + "Value #{value.inspect} is invalid for class attribute #{name.inspect}" + ) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/extensions.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/extensions.rb new file mode 100644 index 00000000..b74b2a19 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/extensions.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require "set" + +module Dry + module Core + # Define extensions that can be later enabled by the user. + # + # @example + # + # class Foo + # extend Dry::Core::Extensions + # + # register_extension(:bar) do + # def bar; :bar end + # end + # end + # + # Foo.new.bar # => NoMethodError + # Foo.load_extensions(:bar) + # Foo.new.bar # => :bar + # + module Extensions + # @api private + def self.extended(obj) + super + obj.instance_variable_set(:@__available_extensions__, {}) + obj.instance_variable_set(:@__loaded_extensions__, ::Set.new) + end + + # Register an extension + # + # @param [Symbol] name extension name + # @yield extension block. This block guaranteed not to be called more than once + def register_extension(name, &block) + @__available_extensions__[name] = block + end + + # Whether an extension is available + # + # @param [Symbol] name extension name + # @return [Boolean] Extension availability + def available_extension?(name) + @__available_extensions__.key?(name) + end + + # Enables specified extensions. Already enabled extensions remain untouched + # + # @param [Array] extensions list of extension names + def load_extensions(*extensions) + extensions.each do |ext| + block = @__available_extensions__.fetch(ext) do + raise ::ArgumentError, "Unknown extension: #{ext.inspect}" + end + unless @__loaded_extensions__.include?(ext) + block.call + @__loaded_extensions__ << ext + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/inflector.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/inflector.rb new file mode 100644 index 00000000..768669a3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/inflector.rb @@ -0,0 +1,143 @@ +# frozen_string_literal: true + +module Dry + module Core + # Helper module providing thin interface around an inflection backend. + module Inflector + # List of supported backends + BACKENDS = { + activesupport: [ + "active_support/inflector", + proc { ::ActiveSupport::Inflector } + ], + dry_inflector: [ + "dry/inflector", + proc { ::Dry::Inflector.new } + ], + inflecto: [ + "inflecto", + proc { ::Inflecto } + ] + }.freeze + + # Try to activate a backend + # + # @api private + def self.realize_backend(path, backend_factory) + require path + rescue ::LoadError + nil + else + backend_factory.call + end + + # Set up first available backend + # + # @api private + def self.detect_backend + BACKENDS.inject(nil) do |backend, (_, (path, factory))| + backend || realize_backend(path, factory) + end || raise( + LoadError, + "No inflector library could be found: " \ + "please install either the `inflecto` or `activesupport` gem." + ) + end + + # Set preferred backend + # + # @param [Symbol] name backend name (:activesupport or :inflecto) + def self.select_backend(name = nil) + if name && !BACKENDS.key?(name) + raise ::NameError, "Invalid inflector library selection: '#{name}'" + end + + @inflector = name ? realize_backend(*BACKENDS[name]) : detect_backend + end + + # Inflector accessor. Lazily initializes a backend + # + # @api private + def self.inflector + defined?(@inflector) ? @inflector : select_backend + end + + # Transform string to camel case + # + # @example + # Dry::Core::Inflector.camelize('foo_bar') # => 'FooBar' + # + # @param [String] input input string + # @return Transformed string + def self.camelize(input) + inflector.camelize(input) + end + + # Transform string to snake case + # + # @example + # Dry::Core::Inflector.underscore('FooBar') # => 'foo_bar' + # + # @param [String] input input string + # @return Transformed string + def self.underscore(input) + inflector.underscore(input) + end + + # Get a singlular form of a word + # + # @example + # Dry::Core::Inflector.singularize('chars') # => 'char' + # + # @param [String] input input string + # @return Transformed string + def self.singularize(input) + inflector.singularize(input) + end + + # Get a plural form of a word + # + # @example + # Dry::Core::Inflector.pluralize('string') # => 'strings' + # + # @param [String] input input string + # @return Transformed string + def self.pluralize(input) + inflector.pluralize(input) + end + + # Remove namespaces from a constant name + # + # @example + # Dry::Core::Inflector.demodulize('Deeply::Nested::Name') # => 'Name' + # + # @param [String] input input string + # @return Unnested constant name + def self.demodulize(input) + inflector.demodulize(input) + end + + # Get a constant value by its name + # + # @example + # Dry::Core::Inflector.constantize('Foo::Bar') # => Foo::Bar + # + # @param [String] input input constant name + # @return Constant value + def self.constantize(input) + inflector.constantize(input) + end + + # Transform a file path to a constant name + # + # @example + # Dry::Core::Inflector.classify('foo/bar') # => 'Foo::Bar' + # + # @param [String] input input string + # @return Constant name + def self.classify(input) + inflector.classify(input) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/memoizable.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/memoizable.rb new file mode 100644 index 00000000..02027aa0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/memoizable.rb @@ -0,0 +1,235 @@ +# frozen_string_literal: true + +module Dry + module Core + module Memoizable + MEMOIZED_HASH = {}.freeze + PARAM_PLACEHOLDERS = %i[* ** &].freeze + + module ClassInterface + module Base + def memoize(*names) + prepend(Memoizer.new(self, names)) + end + + def inherited(base) + super + + memoizer = base.ancestors.find { _1.is_a?(Memoizer) } + base.prepend(memoizer.dup) if memoizer + end + end + + module BasicObject + include Base + + def new(*, **) + obj = super + obj.instance_eval { @__memoized__ = MEMOIZED_HASH.dup } + obj + end + end + + module Object + include Base + + def new(*, **) + obj = super + obj.instance_variable_set(:@__memoized__, MEMOIZED_HASH.dup) + obj + end + end + end + + def self.included(klass) + super + + if klass <= Object + klass.extend(ClassInterface::Object) + else + klass.extend(ClassInterface::BasicObject) + end + end + + # @api private + class Memoizer < ::Module + KERNEL = { + singleton: ::Kernel.instance_method(:singleton_class), + ivar_set: ::Kernel.instance_method(:instance_variable_set), + frozen: ::Kernel.instance_method(:frozen?) + }.freeze + + # @api private + def initialize(klass, names) + super() + names.each do |name| + define_memoizable( + method: klass.instance_method(name) + ) + end + end + + private + + # @api private + # rubocop:disable Metrics/AbcSize + def define_memoizable(method:) + parameters = method.parameters + mod = self + kernel = KERNEL + + if parameters.empty? + key = "#{__id__}:#{method.name}".hash.abs + + define_method(method.name) do + value = super() + + if kernel[:frozen].bind_call(self) + # It's not possible to modify singleton classes + # of frozen objects + mod.remove_method(method.name) + mod.module_eval(<<~RUBY, __FILE__, __LINE__ + 1) + def #{method.name} # def slow_calc + cached = @__memoized__[#{key}] # cached = @__memoized__[12345678] + # + if cached || @__memoized__.key?(#{key}) # if cached || @__memoized__.key?(12345678) + cached # cached + else # else + @__memoized__[#{key}] = super # @__memoized__[12345678] = super + end # end + end # end + RUBY + else + # We make an attr_reader for computed value. + # Readers are "special-cased" in ruby so such + # access will be the fastest way, faster than you'd + # expect :) + attr_name = :"__memozed_#{key}__" + ivar_name = :"@#{attr_name}" + kernel[:ivar_set].bind_call(self, ivar_name, value) + eigenclass = kernel[:singleton].bind_call(self) + eigenclass.attr_reader(attr_name) + eigenclass.alias_method(method.name, attr_name) + eigenclass.remove_method(attr_name) + end + + value + end + else + mapping = parameters.to_h { |k, v = nil| [k, v] } + params, binds = declaration(parameters, mapping) + last_param = parameters.last + + if last_param[0].eql?(:block) && !last_param[1].eql?(:&) + Deprecations.warn(<<~WARN) + Memoization for block-accepting methods isn't safe. + Every call creates a new block instance bloating cached results. + In the future, blocks will still be allowed but won't participate in + cache key calculation. + WARN + end + + module_eval(<<~RUBY, __FILE__, __LINE__ + 1) + def #{method.name}(#{params.join(", ")}) # def slow_calc(arg1, arg2, arg3) + key = [:"#{method.name}", #{binds.join(", ")}].hash # key = [:slow_calc, arg1, arg2, arg3].hash + # + if @__memoized__.key?(key) # if @__memoized__.key?(key) + @__memoized__[key] # @__memoized__[key] + else # else + @__memoized__[key] = super # @__memoized__[key] = super + end # end + end # end + RUBY + + end + end + + # rubocop:enable Metrics/AbcSize + # @api private + def declaration(definition, lookup) + params = [] + binds = [] + defined = {} + + definition.each do |type, name| + mapped_type = map_bind_type(type, name, lookup, defined) do + raise ::NotImplementedError, "type: #{type}, name: #{name}" + end + + if mapped_type + defined[mapped_type] = true + bind = name_from_param(name) || make_bind_name(binds.size) + + binds << bind + params << param(bind, mapped_type) + end + end + + [params, binds] + end + + # @api private + def name_from_param(name) + if PARAM_PLACEHOLDERS.include?(name) + nil + else + name + end + end + + # @api private + def make_bind_name(idx) + :"__lv_#{idx}__" + end + + # @api private + def map_bind_type(type, name, original_params, defined_types) # rubocop:disable Metrics/PerceivedComplexity + case type + when :req + :reqular + when :rest, :keyreq, :keyrest + type + when :block + if name.eql?(:&) + # most likely this is a case of delegation + # rather than actual block + nil + else + type + end + when :opt + if original_params.key?(:rest) || defined_types[:rest] + nil + else + :rest + end + when :key + if original_params.key?(:keyrest) || defined_types[:keyrest] + nil + else + :keyrest + end + else + yield + end + end + + # @api private + def param(name, type) + case type + when :reqular + name + when :rest + "*#{name}" + when :keyreq + "#{name}:" + when :keyrest + "**#{name}" + when :block + "&#{name}" + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/version.rb b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/version.rb new file mode 100644 index 00000000..91932b42 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-core-1.1.0/lib/dry/core/version.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module Dry + module Core + VERSION = "1.1.0" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/CHANGELOG.md b/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/CHANGELOG.md new file mode 100644 index 00000000..3098e82d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/CHANGELOG.md @@ -0,0 +1,112 @@ + + +## 1.2.0 2025-01-04 + + +### Changed + +- Bumped required Ruby version to 3.1 (@flash-gordon) + +[Compare v1.1.0...v1.2.0](https://github.com/dry-rb/dry-inflector/compare/v1.1.0...v1.2.0) + +## 1.1.0 2024-07-02 + + +### Added + +- Added "DB" as a default acronym (#49) (@timriley) + +### Fixed + +- Fix incorrect inflections on words separated by spaces, underscores or hyphens (#47) (@parndt) + + +[Compare v1.0.0...v1.1.0](https://github.com/dry-rb/dry-inflector/compare/v1.0.0...v1.1.0) + +## 1.0.0 2022-11-04 + + +### Changed + +- Bumped version to 1.0.0 (@solnic) + +[Compare v0.3.0...v1.0.0](https://github.com/dry-rb/dry-inflector/compare/v0.3.0...v1.0.0) + +## 0.3.0 2022-07-12 + + +### Added + +- Add CSV as default acronym (via #43) (@waiting-for-dev) + +### Changed + +- Extra dashes are now omitted when converting to camelcase (via #40) (@postmodern) + +[Compare v0.2.1...v0.3.0](https://github.com/dry-rb/dry-inflector/compare/v0.2.1...v0.3.0) + +## 0.2.1 2021-06-30 + + +### Added + +- Add default acronyms: API and CSRF (#35) (@jodosha) + +### Fixed + +- Fix singularizing -us suffix (issue #33 via #38) (@cllns) + + +[Compare v0.2.0...v0.2.1](https://github.com/dry-rb/dry-inflector/compare/v0.2.0...v0.2.1) + +## 0.2.0 2019-10-13 + + +### Added + +- [Abinoam P. Marques Jr. & Andrii Savchenko] Introduced `Dry::Inflector#camelize_upper` and `Dry::Inflector#camelize_lower`. `Dry::Inflector#camelize` is now an alias for `Dry::Inflector#camelize_upper`. ```ruby inflector.camelize_upper("data_mapper") # => "DataMapper"' inflector.camelize_lower("data_mapper") # => "dataMapper"' ``` + +### Fixed + +- [ecnal] Fixed singularization rules for words like "alias" or "status" + + +[Compare v0.1.2...v0.2.0](https://github.com/dry-rb/dry-inflector/compare/v0.1.2...v0.2.0) + +## 0.1.2 2018-04-25 + + +### Added + +- [Gustavo Caso & Nikita Shilnikov] Added support for acronyms + + +[Compare v0.1.1...v0.1.2](https://github.com/dry-rb/dry-inflector/compare/v0.1.1...v0.1.2) + +## 0.1.1 2017-11-18 + + +### Fixed + +- [Luca Guidi & Abinoam P. Marques Jr.] Ensure `Dry::Inflector#ordinalize` to work for all the numbers from 0 to 100 + + +[Compare v0.1.0...v0.1.1](https://github.com/dry-rb/dry-inflector/compare/v0.1.0...v0.1.1) + +## 0.1.0 2017-11-17 + + +### Added + +- [Luca Guidi] Introduced `Dry::Inflector#pluralize` +- [Luca Guidi] Introduced `Dry::Inflector#singularize` +- [Luca Guidi] Introduced `Dry::Inflector#camelize` +- [Luca Guidi] Introduced `Dry::Inflector#classify` +- [Luca Guidi] Introduced `Dry::Inflector#tableize` +- [Luca Guidi] Introduced `Dry::Inflector#dasherize` +- [Luca Guidi] Introduced `Dry::Inflector#underscore` +- [Luca Guidi] Introduced `Dry::Inflector#demodulize` +- [Luca Guidi] Introduced `Dry::Inflector#humanize` +- [Luca Guidi] Introduced `Dry::Inflector#ordinalize` +- [Abinoam P. Marques Jr.] Introduced `Dry::Inflector#foreign_key` +- [Abinoam P. Marques Jr.] Introduced `Dry::Inflector#constantize` diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/LICENSE b/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/LICENSE new file mode 100644 index 00000000..9f9f214d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2015-2023 dry-rb team + +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 AUTHORS OR +COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/README.md b/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/README.md new file mode 100644 index 00000000..b62d90e9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/README.md @@ -0,0 +1,22 @@ + +[gem]: https://rubygems.org/gems/dry-inflector +[actions]: https://github.com/dry-rb/dry-inflector/actions + +# dry-inflector [![Gem Version](https://badge.fury.io/rb/dry-inflector.svg)][gem] [![CI Status](https://github.com/dry-rb/dry-inflector/workflows/ci/badge.svg)][actions] + +## Links + +* [User documentation](https://dry-rb.org/gems/dry-inflector) +* [API documentation](http://rubydoc.info/gems/dry-inflector) +* [Forum](https://discourse.dry-rb.org) + +## Supported Ruby versions + +This library officially supports the following Ruby versions: + +* MRI `>= 3.0.0` +* jruby `>= 9.4` (not tested on CI) + +## License + +See `LICENSE` file. diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/dry-inflector.gemspec b/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/dry-inflector.gemspec new file mode 100644 index 00000000..6e7173c3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/dry-inflector.gemspec @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +# this file is synced from dry-rb/template-gem project + +lib = File.expand_path("lib", __dir__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require "dry/inflector/version" + +Gem::Specification.new do |spec| + spec.name = "dry-inflector" + spec.authors = ["Luca Guidi", "Andrii Savchenko", "Abinoam P. Marques Jr."] + spec.email = ["me@lucaguidi.com", "andrey@aejis.eu", "abinoam@gmail.com"] + spec.license = "MIT" + spec.version = Dry::Inflector::VERSION.dup + + spec.summary = "String inflections for dry-rb" + spec.description = spec.summary + spec.homepage = "https://dry-rb.org/gems/dry-inflector" + spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-inflector.gemspec", + "lib/**/*"] + spec.bindir = "bin" + spec.executables = [] + spec.require_paths = ["lib"] + + spec.metadata["allowed_push_host"] = "https://rubygems.org" + spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-inflector/blob/main/CHANGELOG.md" + spec.metadata["source_code_uri"] = "https://github.com/dry-rb/dry-inflector" + spec.metadata["bug_tracker_uri"] = "https://github.com/dry-rb/dry-inflector/issues" + spec.metadata["rubygems_mfa_required"] = "true" + + spec.required_ruby_version = ">= 3.1" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/lib/dry-inflector.rb b/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/lib/dry-inflector.rb new file mode 100644 index 00000000..34651b5e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/lib/dry-inflector.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +require "dry/inflector" diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/lib/dry/inflector.rb b/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/lib/dry/inflector.rb new file mode 100644 index 00000000..bfb47578 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/lib/dry/inflector.rb @@ -0,0 +1,341 @@ +# frozen_string_literal: true + +module Dry + # dry-inflector + # + # @since 0.1.0 + class Inflector + require "dry/inflector/version" + require "dry/inflector/inflections" + + # Instantiate the inflector + # + # @param blk [Proc] an optional block to specify custom inflection rules + # @yieldparam [Dry::Inflector::Inflections] the inflection rules + # + # @return [Dry::Inflector] the inflector + # + # @since 0.1.0 + # + # @example Basic usage + # require "dry/inflector" + # + # inflector = Dry::Inflector.new + # + # @example Custom inflection rules + # require "dry/inflector" + # + # inflector = Dry::Inflector.new do |inflections| + # inflections.plural "virus", "viruses" # specify a rule for #pluralize + # inflections.singular "thieves", "thief" # specify a rule for #singularize + # inflections.uncountable "dry-inflector" # add an exception for an uncountable word + # end + def initialize(&) + @inflections = Inflections.build(&) + end + + # Lower camelize a string + # + # @param input [String,Symbol] the input + # @return [String] the lower camelized string + # + # @since 0.1.3 + # + # @example + # require "dry/inflector" + # + # inflector = Dry::Inflector.new + # inflector.camelize_lower("data_mapper") # => "dataMapper" + def camelize_lower(input) + internal_camelize(input, false) + end + + # Upper camelize a string + # + # @param input [String,Symbol] the input + # @return [String] the upper camelized string + # + # @since 0.1.3 + # + # @example + # require "dry/inflector" + # + # inflector = Dry::Inflector.new + # inflector.camelize_upper("data_mapper") # => "DataMapper" + # inflector.camelize_upper("dry/inflector") # => "Dry::Inflector" + def camelize_upper(input) + internal_camelize(input, true) + end + + alias_method :camelize, :camelize_upper + + # Find a constant with the name specified in the argument string + # + # The name is assumed to be the one of a top-level constant, + # constant scope of caller is ignored + # + # @param input [String,Symbol] the input + # @return [Class, Module] the class or module + # + # @since 0.1.0 + # + # @example + # require "dry/inflector" + # + # inflector = Dry::Inflector.new + # inflector.constantize("Module") # => Module + # inflector.constantize("Dry::Inflector") # => Dry::Inflector + def constantize(input) + Object.const_get(input, false) + end + + # Classify a string + # + # @param input [String,Symbol] the input + # @return [String] the classified string + # + # @since 0.1.0 + # + # @example + # require "dry/inflector" + # + # inflector = Dry::Inflector.new + # inflector.classify("books") # => "Book" + def classify(input) + camelize(singularize(input.to_s.split(".").last)) + end + + # Dasherize a string + # + # @param input [String,Symbol] the input + # @return [String] the dasherized string + # + # @since 0.1.0 + # + # @example + # require "dry/inflector" + # + # inflector = Dry::Inflector.new + # inflector.dasherize("dry_inflector") # => "dry-inflector" + def dasherize(input) + input.to_s.tr("_", "-") + end + + # Demodulize a string + # + # @param input [String,Symbol] the input + # @return [String] the demodulized string + # + # @since 0.1.0 + # + # @example + # require "dry/inflector" + # + # inflector = Dry::Inflector.new + # inflector.demodulize("Dry::Inflector") # => "Inflector" + def demodulize(input) + input.to_s.split("::").last + end + + # Humanize a string + # + # @param input [String,Symbol] the input + # @return [String] the humanized string + # + # @since 0.1.0 + # + # @example + # require "dry/inflector" + # + # inflector = Dry::Inflector.new + # inflector.humanize("dry_inflector") # => "Dry inflector" + # inflector.humanize("author_id") # => "Author" + def humanize(input) + input = input.to_s + result = inflections.humans.apply_to(input) + result.delete_suffix!("_id") + result.tr!("_", " ") + match = /(\W)/.match(result) + separator = match ? match[0] : DEFAULT_SEPARATOR + result.split(separator).map.with_index { |word, index| + inflections.acronyms.apply_to(word, capitalize: index.zero?) + }.join(separator) + end + + # Creates a foreign key name + # + # @param input [String, Symbol] the input + # @return [String] foreign key + # + # @example + # require "dry/inflector" + # + # inflector = Dry::Inflector.new + # inflector.foreign_key("Message") => "message_id" + def foreign_key(input) + "#{underscore(demodulize(input))}_id" + end + + # Ordinalize a number + # + # @param number [Integer] the input + # @return [String] the ordinalized number + # + # @since 0.1.0 + # + # @example + # require "dry/inflector" + # + # inflector = Dry::Inflector.new + # inflector.ordinalize(1) # => "1st" + # inflector.ordinalize(2) # => "2nd" + # inflector.ordinalize(3) # => "3rd" + # inflector.ordinalize(10) # => "10th" + # inflector.ordinalize(23) # => "23rd" + def ordinalize(number) + abs_value = number.abs + + if ORDINALIZE_TH[abs_value % 100] + "#{number}th" + else + case abs_value % 10 + when 1 then "#{number}st" + when 2 then "#{number}nd" + when 3 then "#{number}rd" + else "#{number}th" + end + end + end + + # Pluralize a string + # + # @param input [String,Symbol] the input + # @return [String] the pluralized string + # + # @since 0.1.0 + # + # @example + # require "dry/inflector" + # + # inflector = Dry::Inflector.new + # inflector.pluralize("book") # => "books" + # inflector.pluralize("money") # => "money" + def pluralize(input) + input = input.to_s + return input if uncountable?(input) + + inflections.plurals.apply_to(input) + end + + # Singularize a string + # + # @param input [String] the input + # @return [String] the singularized string + # + # @since 0.1.0 + # + # @example + # require "dry/inflector" + # + # inflector = Dry::Inflector.new + # inflector.singularize("books") # => "book" + # inflector.singularize("money") # => "money" + def singularize(input) + input = input.to_s + return input if uncountable?(input) + + inflections.singulars.apply_to(input) + end + + # Tableize a string + # + # @param input [String,Symbol] the input + # @return [String] the tableized string + # + # @since 0.1.0 + # + # @example + # require "dry/inflector" + # + # inflector = Dry::Inflector.new + # inflector.tableize("Book") # => "books" + def tableize(input) + input = input.to_s.gsub("::", "_") + pluralize(underscore(input)) + end + + # Underscore a string + # + # @param input [String,Symbol] the input + # @return [String] the underscored string + # + # @since 0.1.0 + # + # @example + # require "dry/inflector" + # + # inflector = Dry::Inflector.new + # inflector.underscore("dry-inflector") # => "dry_inflector" + def underscore(input) + input = input.to_s.gsub("::", "/") + input.gsub!(inflections.acronyms.regex) do + m1 = Regexp.last_match(1) + m2 = Regexp.last_match(2) + "#{m1 ? "_" : ""}#{m2.downcase}" + end + input.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2') + input.gsub!(/([a-z\d])([A-Z])/, '\1_\2') + input.tr!("-", "_") + input.downcase! + input + end + + # Check if the input is an uncountable word + # + # @param input [String] the input + # @return [TrueClass,FalseClass] the result of the check + # + # @since 0.1.0 + # @api private + def uncountable?(input) + input.match?(/\A[[:space:]]*\z/) || + inflections.uncountables.include?(input.downcase) || + inflections.uncountables.include?(input.split(/_|\b/).last.downcase) + end + + # @return [String] + # + # @since 0.2.0 + # @api public + def to_s + "#" + end + alias_method :inspect, :to_s + + private + + # @since 0.1.0 + # @api private + ORDINALIZE_TH = {11 => true, 12 => true, 13 => true}.freeze + + # @since 0.1.2 + # @api private + DEFAULT_SEPARATOR = " " + + attr_reader :inflections + + # @since 0.1.3 + # @api private + def internal_camelize(input, upper) + input = input.to_s.dup + input.sub!(/^[a-z\d]*/) { |match| inflections.acronyms.apply_to(match, capitalize: upper) } + input.gsub!(%r{(?:[_-]|(/))([a-z\d]*)}i) do + m1 = Regexp.last_match(1) + m2 = Regexp.last_match(2) + "#{m1}#{inflections.acronyms.apply_to(m2)}" + end + input.gsub!("/", "::") + input + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/lib/dry/inflector/acronyms.rb b/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/lib/dry/inflector/acronyms.rb new file mode 100644 index 00000000..da1f0a62 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/lib/dry/inflector/acronyms.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +module Dry + class Inflector + # A set of acronyms + # + # @since 0.1.2 + # @api private + class Acronyms + attr_reader :regex + + # @since 0.1.2 + # @api private + def initialize + @rules = {} + define_regex_patterns + end + + # @since 0.1.2 + # @api private + def apply_to(word, capitalize: true) + @rules[word.downcase] || (capitalize ? word.capitalize : word) + end + + # @since 0.1.2 + # @api private + def add(rule, replacement) + @rules[rule] = replacement + define_regex_patterns + end + + private + + # @since 0.1.2 + # @api private + def define_regex_patterns + regex = @rules.empty? ? /(?=a)b/ : /#{@rules.values.join("|")}/ + @regex = /(?:(?<=([A-Za-z\d]))|\b)(#{regex})(?=\b|[^a-z])/ + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/lib/dry/inflector/inflections.rb b/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/lib/dry/inflector/inflections.rb new file mode 100644 index 00000000..2113746d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/lib/dry/inflector/inflections.rb @@ -0,0 +1,260 @@ +# frozen_string_literal: true + +require "set" +require "dry/inflector/rules" +require "dry/inflector/acronyms" + +module Dry + class Inflector + # Inflections + # + # @since 0.1.0 + class Inflections + require "dry/inflector/inflections/defaults" + + # Instantiate a set of inflection rules. + # It adds the default rules and the optional customizations, passed as a block. + # + # @param blk [Proc] the optional, custom rules + # + # @since 0.1.0 + # @api private + def self.build(&blk) + new do |inflect| + Defaults.call(inflect) + blk.call(inflect) if block_given? + end + end + + # Pluralization rules + # + # @return [Dry::Inflector::Rules] + # + # @since 0.1.0 + # @api private + attr_reader :plurals + + # Singularization rules + # + # @return [Dry::Inflector::Rules] + # + # @since 0.1.0 + # @api private + attr_reader :singulars + + # Uncountable rules + # + # @return [Set] + # + # @since 0.1.0 + # @api private + attr_reader :uncountables + + # Human rules + # + # @return [Dry::Inflector::Rules] + # + # @since 0.1.0 + # @api private + attr_reader :humans + + # Acronyms + # + # @return [Dry::Inflector::Acronyms] + # + # @since 0.1.2 + # @api private + attr_reader :acronyms + + # Instantiate the rules + # + # @return [Dry::Inflector::Inflections] + # @yieldparam [self] + # + # @since 0.1.0 + # @api private + def initialize + @plurals = Rules.new + @singulars = Rules.new + @humans = Rules.new + @uncountables = Set[] + @acronyms = Acronyms.new + + yield(self) if block_given? + end + + # Add a custom pluralization rule + # + # Specifies a new pluralization rule and its replacement. + # The rule can either be a string or a regular expression. + # + # The replacement should always be a string that may include + # references to the matched data from the rule. + # + # @param rule [String, Regexp] the rule + # @param replacement [String] the replacement + # + # @since 0.1.0 + # + # @example + # require "dry/inflector" + # + # inflector = Dry::Inflector.new do |inflections| + # inflections.plural "virus", "viruses" + # end + def plural(rule, replacement) + rule(rule, replacement, plurals) + end + + # Add a custom singularization rule + # + # Specifies a new singularization rule and its replacement. + # The rule can either be a string or a regular expression. + # + # The replacement should always be a string that may include + # references to the matched data from the rule. + # + # @param rule [String, Regexp] the rule + # @param replacement [String] the replacement + # + # @since 0.1.0 + # + # @example + # require "dry/inflector" + # + # inflector = Dry::Inflector.new do |inflections| + # inflections.singular "thieves", "thief" + # end + def singular(rule, replacement) + rule(rule, replacement, singulars) + end + + # Add a custom pluralization rule + # + # Specifies a new irregular that applies to both pluralization + # and singularization at the same time. + # + # This can only be used for strings, not regular expressions. + # You simply pass the irregular in singular and plural form. + # + # @param singular [String] the singular + # @param plural [String] the plural + # + # @since 0.1.0 + # + # @example + # require "dry/inflector" + # + # inflector = Dry::Inflector.new do |inflections| + # inflections.singular "octopus", "octopi" + # end + def irregular(singular, plural) + uncountables.delete(singular) + uncountables.delete(plural) + + add_irregular(singular, plural, plurals) + add_irregular(plural, singular, singulars) + end + + # Add a custom rule for uncountable words + # + # Uncountable will not be inflected + # + # @param [Enumerable] words + # + # @since 0.1.0 + # + # @example + # require "dry/inflector" + # + # inflector = Dry::Inflector.new do |inflections| + # inflections.uncountable "money" + # inflections.uncountable "money", "information" + # inflections.uncountable %w(money information rice) + # end + def uncountable(*words) + uncountables.merge(words.flatten) + end + + # Add one or more acronyms + # + # Acronyms affect how basic operations are performed, such + # as camelize/underscore. + # + # @param words [Array] a list of acronyms + # + # @since 0.1.2 + # + # @example + # require "dry/inflector" + # + # inflector = Dry::Inflector.new do |inflections| + # inflections.acronym "HTML" + # end + # + # inflector.camelize("html") # => "HTML" + # inflector.underscore("HTMLIsFun") # => "html_is_fun" + def acronym(*words) + words.each { |word| @acronyms.add(word.downcase, word) } + end + + # Add a custom humanize rule + # + # Specifies a humanized form of a string by a regular expression rule or + # by a string mapping. + # + # When using a regular expression based replacement, the normal humanize + # formatting is called after the replacement. + # + # When a string is used, the human form should be specified as desired + # (example: `"The name"`, not `"the_name"`) + # + # @param rule [String, Regexp] the rule + # @param replacement [String] the replacement + # + # @since 0.1.0 + # + # @example + # require "dry/inflector" + # + # inflector = Dry::Inflector.new do |inflections| + # inflections.human(/_cnt$/i, '\1_count') + # inflections.human("legacy_col_person_name", "Name") + # end + def human(rule, replacement) + humans.insert(0, [rule, replacement]) + end + + private + + # Add irregular inflection + # + # @param rule [String] the rule + # @param replacement [String] the replacement + # + # @return [undefined] + # + # @since 0.1.0 + # @api private + def add_irregular(rule, replacement, target) + head, *tail = rule.chars.to_a + rule(/(#{head})#{tail.join}\z/i, "\\1#{replacement[1..]}", target) + end + + # Add a new rule + # + # @param rule [String, Regexp] the rule + # @param replacement [String, Regexp] the replacement + # @param target [Dry::Inflector::Rules] the target + # + # @since 0.1.0 + # @api private + def rule(rule, replacement, target) + uncountables.delete(rule) + uncountables.delete(replacement) + + target.insert(0, [rule, replacement]) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/lib/dry/inflector/inflections/defaults.rb b/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/lib/dry/inflector/inflections/defaults.rb new file mode 100644 index 00000000..e7dd1480 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-inflector-1.2.0/lib/dry/inflector/inflections/defaults.rb @@ -0,0 +1,130 @@ +# frozen_string_literal: true + +module Dry + class Inflector + class Inflections + # Default inflections + # + # @since 0.1.0 + # @api private + # + # rubocop:disable Metrics/AbcSize + module Defaults + # @since 0.1.0 + # @api private + def self.call(inflect) + plural(inflect) + singular(inflect) + irregular(inflect) + uncountable(inflect) + acronyms(inflect) + end + + # @since 0.1.0 + # @api private + def self.plural(inflect) + inflect.plural(/\z/, "s") + inflect.plural(/s\z/i, "s") + inflect.plural(/(ax|test)is\z/i, '\1es') + inflect.plural(/(.*)us\z/i, '\1uses') + inflect.plural(/(octop|vir|cact)us\z/i, '\1i') + inflect.plural(/(octop|vir)i\z/i, '\1i') + inflect.plural(/(alias|status)\z/i, '\1es') + inflect.plural(/(buffal|domin|ech|embarg|her|mosquit|potat|tomat)o\z/i, '\1oes') + inflect.plural(/(? + +## 3.2.0 2025-01-01 + + +### Changed + +- Set minimal supported Ruby version to 3.1 (@flash-gordon) +- Exclude block forwarding from `Root#initialize`. This helps +with tracking down calls that shouldn't pass a block in Ruby 3.4 (see #109) (@flash-gordon) + + +[Compare v3.1.1...v3.2.0](https://github.com/dry-rb/dry-initializer/compare/v3.1.1...v3.2.0) + +## 3.1.1 2022-01-19 + + +### Changed + +- Improved error messages were rolled back, they created an implicit dependency on dry-types (@flash-gordon) + +[Compare v3.1.0...v3.1.1](https://github.com/dry-rb/dry-initializer/compare/v3.1.0...v3.1.1) + +## 3.1.0 2022-01-16 + + +### Changed + +- Improved error messages on type mismatch (@swerling) +- [BREAKING] Minimal supported Ruby version is 2.7 (@flash-gordon) + +[Compare v3.0.4...v3.1.0](https://github.com/dry-rb/dry-initializer/compare/v3.0.4...v3.1.0) + +## 3.0.4 2020-09-29 + + +### Fixed + +- Arity check for lambdas used for coercion (@flash-gordon) + + +[Compare v3.0.3...v3.0.4](https://github.com/dry-rb/dry-initializer/compare/v3.0.3...v3.0.4) + +## 3.0.3 2020-01-08 + + +### Fixed + +- Constrained member arrays work correctly now (see #33) (@bjeanes + @solnic) + + +[Compare v3.0.2...v3.0.3](https://github.com/dry-rb/dry-initializer/compare/v3.0.2...v3.0.3) + +## 3.0.2 2019-11-07 + + +### Fixed + +- Warnings about keyword arguments (flash-gordon) + + +[Compare v3.0.1...v3.0.2](https://github.com/dry-rb/dry-initializer/compare/v3.0.1...v3.0.2) + +## 3.0.1 2019-04-15 + + +### Fixed + +- Usage of underscored names of `option`-s and `param`-s (nepalez) + + You can use any sequence of underscores except for in nested types. + In nested types single underscores can be used to split alphanumeric + parts only. + + ```ruby + class Test + extend Dry::Initializer + + # Proper usage + option :foo_bar do + option :__foo__, proc(&:to_s) + end + end + + # Improper usage + option :__foo__ do + # ... + end + + option :foo__bar do + # ... + end + end + ``` + + This restriction is necessary because we constantize option/param names + when defining nested structs. + + +[Compare v3.0.0...v3.0.1](https://github.com/dry-rb/dry-initializer/compare/v3.0.0...v3.0.1) + +## 3.0.0 2019-04-14 + + +### Added + +- Support of wrapped types/coercers (nepalez) + + ```ruby + class Test + # Wrap type to the array + param :foo, [proc(&:to_s)] + end + + # And the value will be wrapped as well + test = Test.new(42) + test.foo # => ["42"] + ``` +- It works with several layers of nesting (nepalez) + + ```ruby + class Test + # Wrap type to the array + param :foo, [[proc(&:to_s)]] + end + + # And the value will be wrapped as well + test = Test.new(42) + test.foo # => [["42"]] + ``` +- Support of nested types/coercers (nepalez) + + ```ruby + class Test + param :foo do + option :bar do + option :baz, proc(&:to_s) + end + end + end + + test = Test.new(bar: { "baz" => 42 }) + test.foo.bar.baz # => "42" + ``` +- Wrapped/nested combinations are supported as well (nepalez) + + ```ruby + class Test + param :foo, [] do + option :bar, proc(&:to_s) + end + end + + test = Test.new(bar: 42) + test.foo.first.bar # => "42" + ``` +- ## [2.7.0] Unreleazed + +### Fixed + +- Roll back master to the state of [2.5.0]. + + Somehow distinction between `@default_null` and `@null` variables + in the `Dry::Initializer::Builders` broken the `rom` library. + + The version [2.6.0] has been yanked on rubygems, so the master + was rolled back to the previous state until the reason for + the incompatibility become clear (bjeanes, nepalez) +- ## [2.6.0] [2018-09-09] (YANKED) + + +[Compare v2.5.0...v3.0.0](https://github.com/dry-rb/dry-initializer/compare/v2.5.0...v3.0.0) + +## 2.5.0 2018-08-17 + + +### Fixed + +- `nil` coercion (belousovAV) + + When default value is `nil` instead of `Dry::Initializer::UNDEFINED`, + the coercion should be applied to any value, including `nil`, because + we cannot distinct "undefined" `nil` from the "assigned" `nil` value. + + +[Compare v2.4.0...v2.5.0](https://github.com/dry-rb/dry-initializer/compare/v2.4.0...v2.5.0) + +## 2.4.0 2018-02-01 + + +### Added + +- Dispatchers for adding syntax sugar to `param` and `options` (nepalez) + + ```ruby + # Converts `integer: true` to `type: proc(&:to_i)` + dispatcher = ->(op) { op[:integer] ? op.merge(type: proc(&:to_i)) : op } + # Register a dispatcher + Dry::Initializer::Dispatchers << dispatcher + # Use syntax sugar + class User + param :id, integer: true # same as param :id, proc(&:to_i) + end + ``` + + +[Compare v2.3.0...v2.4.0](https://github.com/dry-rb/dry-initializer/compare/v2.3.0...v2.4.0) + +## 2.3.0 2017-09-19 + + +### Added + +- Type coercer can take second argument for the initialized instance (nepalez) + This allows to wrap assigned value to the object that refers back + to the initializer instance. More verbose example: + + ```ruby + class Location < String + attr_reader :parameter # refers back to its parameter + + def initialize(name, parameter) + super(name) + @parameter = parameter + end + end + + class Parameter + extend Dry::Initializer + param :name + param :location, ->(value, param) { Location.new(value, param) } + end + + offset = Parameter.new "offset", location: "query" + offset.name # => "offset" + offset.location # => "query" + offset.location.parameter == offset # true + ``` + + +[Compare v2.2.0...v2.3.0](https://github.com/dry-rb/dry-initializer/compare/v2.2.0...v2.3.0) + +## 2.2.0 2017-09-13 + + +### Added + +- Option `:desc` for option/param to add a description (nepalez) +- Methods `Definition#inch` and `Config#inch` to inspect definitions (nepalez) + + ```ruby + class User + extend Dry::Initializer + option :name, proc(&:to_s), optional: true, desc: "User name" + option :email, optional: true, desc: "user email" + end + + User.dry_initializer.inch + # @!method initialize(*, **options) + # Initializes an instance of User + # @option [Object] :name (optional) User name + # @option [Object] :email (optional) User email + # @return [User] + ``` + + +[Compare v2.1.0...v2.2.0](https://github.com/dry-rb/dry-initializer/compare/v2.1.0...v2.2.0) + +## 2.1.0 2017-09-11 + + +### Added + +- Method `#options` to param/option definition (nepalez) + + ```ruby + class User + extend Dry::Initializer + option :name, proc(&:to_s), optional: true + option :email, optional: true + end + + User.dry_initializer.options.map do |option| + [option.source, option.options] + end + # => [ + # [:name, { type: proc(&:to_s), as: :name, optional: true }], + # [:email, { as: :email, optional: true }] + # ] + ``` + + This method can be helpful for replicating params/options + in another class without inheritance. + + +[Compare v2.0.0...v2.1.0](https://github.com/dry-rb/dry-initializer/compare/v2.0.0...v2.1.0) + +## 2.0.0 2017-08-28 + +and to @gzigzigzeo for persuading me to do this refactoring. + +### Added + +- Class method `.dry_initializer` -- a container for `.params` and `.options` + `.definitions` along with the `.null` setting (either `nil` or `UNDEFINED`) + used for unassigned values (nepalez) +- `.dry_initializer.attributes` method takes an instance of the same class + and returns the hash of assigned options. This provide the same + functionality as previously used instance variable `@__options__` (nepalez) + + ```ruby + object.class.dry_initializer.attributes(object) + ``` + + When you use "Dry::Initializer.define -> { ... }" syntax, + the class method `.dry_initializer` is not defined. To access attributes + you should use private instance method `#__dry_initializer_config__` instead: + + ```ruby + object.send(:__dry_initializer_config__).attributes(object) + ``` + + Both methods `.dry_initializer` and `#__dry_initializer_config__` refer + to the same object. +- `.dry_initializer.public_attributes`. This method works differently: + it looks through (possibly reloaded) readers instead of variables + (gzigzigzeo, nepalez) + + ```ruby + object.class.dry_initializer.public_attributes(object) + ``` + + You can use the same trick as above mutatis mutandis. + +### Fixed + +- Definition order dependency bug (nepalez) + + I've found out that if you provided a subclass and then changed params + or options of its superclass, these changes woudn't be reflected in + subclasses until you change any of it params/options as well. + + Now this bug is fixed: every time you call `param` or `option` at + any class, the gem scans through all its descendants to the very bottom + of the tree, and reloads their defintitions. + + Being done in load time, the rebuilt makes no effect on runtime performance. +- Possible misbehavior when you define param and option with the same name (nepalez) + + Doing this will provide `option :name` only, not both: + + ```ruby + param :name + option :name + ``` +- Attempt to redefine param/option of superclass with option/param in + its subclass will cause an exception because it would break + Liskov substitute principle with unexpected behaviour (nepalez) + + No, you can do neither these definitions, nor vice versa: + + ```ruby + class Foo + extend Dry::Intitializer + param :name + end + + class Bar < Foo + option :name + end + ``` +- When you reloading previously defined param of superclass, the gem + will check all its descendands for whether all required positional params + goes before optional ones (nepalez) + + ```ruby + class Foo + param :name + # Foo: def initializer(name) + end + + class Bar + param :email + # Bar: def initializer(name, email) + end + + class Foo + # This raises SyntaxError because in Bar this would cause wrong definition + # Foo: def initializer(name = nil) + # Bar: def initializer(name = nil, email) + param :name, optional: true + end + ``` + +### Changed + +- Under the hood I've separated param/option settings declaration (a container + with param/option settings) from code builders for initializer and readers + (nepalez) + + You can check both the code for the `__initializer__`: + + ```ruby + class Foo + extend Dry::Initializer + # ... + end + + Foo.dry_initializer.code + ``` + + and readers: + + ```ruby + Foo.dry_initializer.params.map(&:code) + Foo.dry_initializer.options.map(&:code) + + # or + + Foo.dry_initializer.definitions.values.map(&:code) + ``` + + You can also check settings for every param and option using methods + `dry_initializer.params`, `dry_initializer.options` (lists), or + `dry_initializer.definitions` (hash). + + You can check null value via `.dry_initializer.null` which is different + for `Dry::Initializer` and `Dry::Initializer[undefined: false]` modules. +- Optimized the code for `__initializer__`-s (the method where all magics occurs) + (nepalez) + + Benchmarks remained about the same: + + ```shell + rake benchmark + ``` + + ``` + Benchmark for instantiation with plain params + value_struct: 4317196.9 i/s + plain Ruby: 4129803.9 i/s - 1.05x slower + dry-initializer: 1710702.1 i/s - 2.52x slower + concord: 1372630.4 i/s - 3.15x slower + values: 601651.8 i/s - 7.18x slower + attr_extras: 535599.5 i/s - 8.06x slower + ``` + + ``` + Benchmark for instantiation with plain options + plain Ruby: 1769174.1 i/s + dry-initializer: 636634.1 i/s - 2.78x slower + kwattr: 423296.5 i/s - 4.18x slower + anima: 399415.0 i/s - 4.43x slower + ``` + + ``` + Benchmark for instantiation with coercion + plain Ruby: 1565501.0 i/s + fast_attributes: 569952.9 i/s - 2.75x slower + dry-initializer: 461122.1 i/s - 3.39x slower + virtus: 138074.8 i/s - 11.34x slower + ``` + + ``` + Benchmark for instantiation with default values + plain Ruby: 3402455.4 i/s + kwattr: 586206.5 i/s - 5.80x slower + dry-initializer: 528482.2 i/s - 6.44x slower + active_attr: 298697.7 i/s - 11.39x slower + ``` + + ``` + Benchmark for instantiation with type constraints and default values + plain Ruby: 2881696.1 i/s + dry-initializer: 470815.1 i/s - 6.12x slower + virtus: 180272.6 i/s - 15.99x slower + ``` + +[Compare v1.4.1...v2.0.0](https://github.com/dry-rb/dry-initializer/compare/v1.4.1...v2.0.0) + +## 1.4.1 2017-04-05 + + +### Fixed + +- Warning about redefined `#initialize` in case the method reloaded in a klass + that extends the module (nepalez, sergey-chechaev) + +### Changed + +- Rename `Dry::Initializer::DSL` -> `Dry::Initializer::ClassDSL` (nepalez) +- Add `Dry::Initializer::InstanceDSL` (nepalez) + +[Compare v1.4.0...v1.4.1](https://github.com/dry-rb/dry-initializer/compare/v1.4.0...v1.4.1) + +## 1.4.0 2017-03-08 + + +### Changed + +- The `@__options__` hash now collects all assigned attributes, + collected via `#option` (as before), and `#param` (nepalez) + +[Compare v1.3.0...v1.4.0](https://github.com/dry-rb/dry-initializer/compare/v1.3.0...v1.4.0) + +## 1.3.0 2017-03-05 + + +### Added + +- No-undefined configuration of the initializer (nepalez, flash-gordon) + + You can either extend or include module `Dry::Initializer` with additional option + `[undefined: false]`. This time `nil` will be assigned instead of + `Dry::Initializer::UNDEFINED`. Readers becomes faster because there is no need + to chech whether a variable was defined or not. At the same time the initializer + doesn't distinct cases when a variable was set to `nil` explicitly, and when it wasn's set at all: + + class Foo # old behavior + extend Dry::Initializer + param :qux, optional: true + end + + class Bar # new behavior + extend Dry::Initializer[undefined: false] + param :qux, optional: true + end + + Foo.new.instance_variable_get(:@qux) # => Dry::Initializer::UNDEFINED + Bar.new.instance_variable_get(:@qux) # => nil + +### Changed + +- Fixed method definitions for performance at the load time (nepalez, flash-gordon) + +[Compare v1.2.0...v1.3.0](https://github.com/dry-rb/dry-initializer/compare/v1.2.0...v1.3.0) + +## 1.2.0 2017-03-05 + + +### Fixed + +- The `@__options__` variable collects renamed options after default values and coercions were applied (nepalez) + + +[Compare v1.1.3...v1.2.0](https://github.com/dry-rb/dry-initializer/compare/v1.1.3...v1.2.0) + +## 1.1.3 2017-03-01 + + +### Added + +- Support for lambdas as default values (nepalez, gzigzigzeo) + + +[Compare v1.1.2...v1.1.3](https://github.com/dry-rb/dry-initializer/compare/v1.1.2...v1.1.3) + +## 1.1.2 2017-02-06 + + +### Changed + +- Remove previously defined methods before redefining them (flash-gordon) + +[Compare v1.1.1...v1.1.2](https://github.com/dry-rb/dry-initializer/compare/v1.1.1...v1.1.2) + +## 1.1.1 2017-02-04 + + +### Fixed + +- `@__options__` collects defined options only (nepalez) + + +[Compare v1.1.0...v1.1.1](https://github.com/dry-rb/dry-initializer/compare/v1.1.0...v1.1.1) + +## 1.1.0 2017-01-28 + + +### Added + +- enhancement via `Dry::Initializer::Attribute.dispatchers` registry (nepalez) + + ```ruby + # Register dispatcher for `:string` option + Dry::Initializer::Attribute.dispatchers << ->(string: nil, **op) do + string ? op.merge(type: proc(&:to_s)) : op + end + + # Now you can use the `:string` key for `param` and `option` + class User + extend Dry::Initializer + param :name, string: true + end + + User.new(:Andy).name # => "Andy" + ``` + +### Changed + +- optimize assignments for performance (nepalez) + +[Compare v1.0.0...v1.1.0](https://github.com/dry-rb/dry-initializer/compare/v1.0.0...v1.1.0) + +## 1.0.0 2017-01-22 + +In this version the code has been rewritten for simplicity + +### Added + +- support for reloading `param` and `option` definitions (nepalez) + + class User + extend Dry::Initializer + param :name + param :phone, optional: true + end + + User.new # => Boom! + + class Admin < User + param :name, default: proc { 'Merlin' } + end + + # order of the param not changed + Admin.new.name # => "Merlin" +- support for assignment of attributes via several options (nepalez) + + class User + extend Dry::Initializer + option :phone + option :number, as: :phone + end + + # Both ways provide the same result + User.new(phone: '1234567890').phone # => '1234567890' + User.new(number: '1234567890').phone # => '1234567890' + +### Changed + +- [BREAKING] when `param` or `option` was not defined, the corresponding **variable** is set to `Dry::Initializer::UNDEFINED`, but the **reader** (when defined) will return `nil` (nepalez) +- `Dry::Initializer` and `Dry::Initializer::Mixin` became aliases (nepalez) + +[Compare v0.11.0...v1.0.0](https://github.com/dry-rb/dry-initializer/compare/v0.11.0...v1.0.0) + +## 0.11.0 2017-01-02 + + +### Added + +- Support of reloading `#initializer` with `super` (nepalez) + + +[Compare v0.10.2...v0.11.0](https://github.com/dry-rb/dry-initializer/compare/v0.10.2...v0.11.0) + +## 0.10.2 2016-12-31 + + +### Added + +- Support of Ruby 2.4 (flas-gordon) + + +[Compare v0.10.1...v0.10.2](https://github.com/dry-rb/dry-initializer/compare/v0.10.1...v0.10.2) + +## 0.10.1 2016-12-27 + + +### Fixed + +- Wrong arity when there were no options and the last param had a default (nolith) + + +[Compare v0.10.0...v0.10.1](https://github.com/dry-rb/dry-initializer/compare/v0.10.0...v0.10.1) + +## 0.10.0 2016-11-20 + + + +[Compare v0.9.3...v0.10.0](https://github.com/dry-rb/dry-initializer/compare/v0.9.3...v0.10.0) + +## 0.9.3 2016-11-20 + + +### Fixed + +- Support of weird option names (nepalez) + + ```ruby + option :"First name", as: :first_name + ``` + + +[Compare v0.9.2...v0.9.3](https://github.com/dry-rb/dry-initializer/compare/v0.9.2...v0.9.3) + +## 0.9.2 2016-11-10 + + +### Fixed + +- Validation of attributes (params and options) (nepalez) + + +[Compare v0.9.1...v0.9.2](https://github.com/dry-rb/dry-initializer/compare/v0.9.1...v0.9.2) + +## 0.9.1 2016-11-06 + + +### Added + +- Support for renaming an option during initialization (nepalez) + + option :name, as: :username # to take :name option and create :username attribute + + +[Compare v0.9.0...v0.9.1](https://github.com/dry-rb/dry-initializer/compare/v0.9.0...v0.9.1) + +## 0.9.0 2016-11-06 + + +### Added + +- The method `#initialize` is defined when a class extended the module (nepalez) + + In previous versions the method was defined only by `param` and `option` calls. + + +[Compare v0.8.1...v0.9.0](https://github.com/dry-rb/dry-initializer/compare/v0.8.1...v0.9.0) + +## 0.8.1 2016-11-05 + + +### Added + +- Support for `dry-struct`ish syntax for constraints (type as a second parameter) (nepalez) + + option :name, Dry::Types['strict.string'] + + +[Compare v0.8.0...v0.8.1](https://github.com/dry-rb/dry-initializer/compare/v0.8.0...v0.8.1) + +## 0.8.0 2016-11-05 + +are deprecated and will be removed in the next version of the gem. + +### Added + +- support for special options like `option :end`, `option :begin` etc. (nepalez) + +### Changed + +- switched from key arguments to serialized hash argument in the initializer (nepalez) + +[Compare v0.7.0...v0.8.0](https://github.com/dry-rb/dry-initializer/compare/v0.7.0...v0.8.0) + +## 0.7.0 2016-10-11 + + +### Added + +- Shared settings with `#using` method (nepalez) + + +[Compare v0.6.0...v0.7.0](https://github.com/dry-rb/dry-initializer/compare/v0.6.0...v0.7.0) + +## 0.6.0 2016-10-09 + + +### Added + +- Support for private and protected readers in the `reader:` option (jmgarnier) + + +[Compare v0.5.0...v0.6.0](https://github.com/dry-rb/dry-initializer/compare/v0.5.0...v0.6.0) + +## 0.5.0 2016-08-21 + + +### Added + +- Allow `optional` attribute to be left undefined (nepalez) + + +[Compare v0.4.0...v0.5.0](https://github.com/dry-rb/dry-initializer/compare/v0.4.0...v0.5.0) + +## 0.4.0 2016-05-28 + + + +[Compare v0.3.3...v0.4.0](https://github.com/dry-rb/dry-initializer/compare/v0.3.3...v0.4.0) + +## 0.3.3 2016-05-28 + + + +[Compare v0.3.2...v0.3.3](https://github.com/dry-rb/dry-initializer/compare/v0.3.2...v0.3.3) + +## 0.3.2 2016-05-25 + + +### Fixed + +- Add explicit requirement for ruby 'set' (rickenharp) + + +[Compare v0.3.1...v0.3.2](https://github.com/dry-rb/dry-initializer/compare/v0.3.1...v0.3.2) + +## 0.3.1 2016-05-22 + + +### Added + +- Support for tolerance to unknown options (nepalez) + + +[Compare v0.3.0...v0.3.1](https://github.com/dry-rb/dry-initializer/compare/v0.3.0...v0.3.1) + +## 0.3.0 2016-05-19 + +its method #register doesn't mutate the builder instance. + +### Fixed + +- Prevent plugin's registry from polluting superclass (nepalez) + +### Changed + +- Made Mixin##initializer_builder method private (nepalez) +- Add Mixin#register_initializer_plugin(plugin) method (nepalez) +- Make all instances (Builder and Signature) immutable (nepalez) +- Decouple mixin from a builder to prevent pollution (nepalez) +- Ensure default value block can use private variables (jeremyf) + +[Compare v0.2.1...v0.3.0](https://github.com/dry-rb/dry-initializer/compare/v0.2.1...v0.3.0) + +## 0.2.1 2016-05-19 + + +### Fixed + +- Fix polluting superclass with declarations from subclass (nepalez) + +### Changed + +- Make all instances (Builder and Signature) immutable (nepalez) +- Decouple mixin from a builder to prevent pollution (nepalez) +- Ensure default value block can use private variables (jeremyf) + +[Compare v0.2.0...v0.2.1](https://github.com/dry-rb/dry-initializer/compare/v0.2.0...v0.2.1) + +## 0.2.0 2016-05-16 + +Default assignments became slower (while plain type constraint are not)! + +### Added + +- Support type constraint via every object's case equality (nepalez) + + ```ruby + option :name, type: /foo/ + option :name, type: (1...14) + ``` +- Support defaults and type constraints for the "container" syntax (nepalez) +- Support adding extensions via plugin system (nepalez) + +### Changed + +- Make dry-types constraint to coerce variables (nepalez) + + ```ruby + # This will coerce `name: :foo` to `"foo"` + option :name, type: Dry::Types::Coercible::String + ``` +- Stop supporing proc type constraint (nepalez) + + ```ruby + option :name, type: ->(v) { String === v } # this does NOT work any more + ``` + + later it will be implemented via coercion plugin (not added by default): + + ```ruby + require 'dry/initializer/coercion' + + class MyClass + extend Dry::Initializer::Mixin + extend Dry::Initializer::Coercion + + option :name, coercer: ->(v) { (String === v) ? v.to_sym : fail } + end + ``` + +[Compare v0.1.1...v0.2.0](https://github.com/dry-rb/dry-initializer/compare/v0.1.1...v0.2.0) + +## 0.1.1 2016-04-28 + + +### Added + +- `include Dry::Initializer.define -> do ... end` syntax (flash-gordon) + + +[Compare v0.1.0...v0.1.1](https://github.com/dry-rb/dry-initializer/compare/v0.1.0...v0.1.1) + +## 0.1.0 2016-04-26 + +Backward compatibility is broken. + +### Added + +- Use `include Dry::Initializer.define(&block)` as an alternative to extending the class (nepalez) + +### Changed + +- Use `extend Dry::Initializer::Mixin` instead of `extend Dry::Initializer` (nepalez) + +[Compare v0.0.1...v0.1.0](https://github.com/dry-rb/dry-initializer/compare/v0.0.1...v0.1.0) + +## 0.0.1 2016-04-09 + +First public release diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/LICENSE b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/LICENSE new file mode 100644 index 00000000..1761fb34 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2015-2025 dry-rb team + +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 AUTHORS OR +COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/README.md b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/README.md new file mode 100644 index 00000000..dd738967 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/README.md @@ -0,0 +1,22 @@ + +[gem]: https://rubygems.org/gems/dry-initializer +[actions]: https://github.com/dry-rb/dry-initializer/actions + +# dry-initializer [![Gem Version](https://badge.fury.io/rb/dry-initializer.svg)][gem] [![CI Status](https://github.com/dry-rb/dry-initializer/workflows/ci/badge.svg)][actions] + +## Links + +* [User documentation](https://dry-rb.org/gems/dry-initializer) +* [API documentation](http://rubydoc.info/gems/dry-initializer) +* [Forum](https://discourse.dry-rb.org) + +## Supported Ruby versions + +This library officially supports the following Ruby versions: + +* MRI `>= 3.1.0` +* jruby `>= 9.4` (not tested on CI) + +## License + +See `LICENSE` file. diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/dry-initializer.gemspec b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/dry-initializer.gemspec new file mode 100644 index 00000000..7be6cd3a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/dry-initializer.gemspec @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +# this file is synced from dry-rb/template-gem project + +lib = File.expand_path("lib", __dir__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require "dry/initializer/version" + +Gem::Specification.new do |spec| + spec.name = "dry-initializer" + spec.authors = ["Vladimir Kochnev (marshall-lee)", "Andrew Kozin (nepalez)"] + spec.email = ["andrew.kozin@gmail.com"] + spec.license = "MIT" + spec.version = Dry::Initializer::VERSION.dup + + spec.summary = "DSL for declaring params and options of the initializer" + spec.description = spec.summary + spec.homepage = "https://dry-rb.org/gems/dry-initializer" + spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-initializer.gemspec", "lib/**/*"] + spec.bindir = "bin" + spec.executables = [] + spec.require_paths = ["lib"] + + spec.metadata["allowed_push_host"] = "https://rubygems.org" + spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-initializer/blob/main/CHANGELOG.md" + spec.metadata["source_code_uri"] = "https://github.com/dry-rb/dry-initializer" + spec.metadata["bug_tracker_uri"] = "https://github.com/dry-rb/dry-initializer/issues" + + spec.required_ruby_version = ">= 3.1.0" + + # to update dependencies edit project.yml + + spec.add_development_dependency "rake" + spec.add_development_dependency "rspec" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry-initializer.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry-initializer.rb new file mode 100644 index 00000000..64e4a2ad --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry-initializer.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +require_relative "dry/initializer" diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer.rb new file mode 100644 index 00000000..1123a60a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +require "set" + +# Namespace for gems in a dry-rb community +module Dry + # + # DSL for declaring params and options of class initializers + # + module Initializer + require_relative "initializer/undefined" + require_relative "initializer/dsl" + require_relative "initializer/definition" + require_relative "initializer/builders" + require_relative "initializer/config" + require_relative "initializer/mixin" + require_relative "initializer/dispatchers" + + # Adds methods [.[]] and [.define] + extend DSL + + # Gem-related configuration + # @return [Dry::Initializer::Config] + def dry_initializer + @dry_initializer ||= Config.new(self) + end + + # Adds or redefines a parameter of [#dry_initializer] + # @param [Symbol] name + # @param [#call, nil] type (nil) + # @option opts [Proc] :default + # @option opts [Boolean] :optional + # @option opts [Symbol] :as + # @option opts [true, false, :protected, :public, :private] :reader + # @yield block with nested definition + # @return [self] itself + def param(name, type = nil, **opts, &block) + dry_initializer.param(name, type, **opts, &block) + self + end + + # Adds or redefines an option of [#dry_initializer] + # @param (see #param) + # @option (see #param) + # @yield (see #param) + # @return (see #param) + def option(name, type = nil, **opts, &block) + dry_initializer.option(name, type, **opts, &block) + self + end + + private + + def inherited(klass) + super + config = Config.new(klass, null: dry_initializer.null) + klass.send(:instance_variable_set, :@dry_initializer, config) + dry_initializer.children << config + end + + require_relative "initializer/struct" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/builders.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/builders.rb new file mode 100644 index 00000000..c9218f77 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/builders.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Dry + module Initializer + # @private + module Builders + require_relative "builders/reader" + require_relative "builders/initializer" + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/builders/attribute.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/builders/attribute.rb new file mode 100644 index 00000000..2de55c79 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/builders/attribute.rb @@ -0,0 +1,90 @@ +# frozen_string_literal: true + +module Dry + module Initializer + module Builders + # @private + class Attribute + def self.[](definition) + new(definition).call + end + + def call + lines.compact + end + + private + + def initialize(definition) + @definition = definition + @option = definition.option + @type = definition.type + @optional = definition.optional + @default = definition.default + @source = definition.source + @ivar = definition.ivar + @null = definition.null ? "Dry::Initializer::UNDEFINED" : "nil" + @opts = "__dry_initializer_options__" + @congif = "__dry_initializer_config__" + @item = "__dry_initializer_definition__" + @val = @option ? "__dry_initializer_value__" : @source + end + + def lines + [ + "", + definition_line, + reader_line, + default_line, + coercion_line, + assignment_line + ] + end + + def reader_line + return unless @option + + @optional ? optional_reader : required_reader + end + + def optional_reader + "#{@val} = #{@opts}.fetch(:'#{@source}', #{@null})" + end + + def required_reader + "#{@val} = #{@opts}.fetch(:'#{@source}')" \ + " { raise KeyError, \"\#{self.class}: #{@definition} is required\" }" + end + + def definition_line + return unless @type || @default + + "#{@item} = __dry_initializer_config__.definitions[:'#{@source}']" + end + + def default_line + return unless @default + + "#{@val} = instance_exec(&#{@item}.default) if #{@null} == #{@val}" + end + + def coercion_line + return unless @type + + arity = @type.is_a?(Proc) ? @type.arity : @type.method(:call).arity + + if arity.equal?(1) || arity.negative? + "#{@val} = #{@item}.type.call(#{@val}) unless #{@null} == #{@val}" + else + "#{@val} = #{@item}.type.call(#{@val}, self) unless #{@null} == #{@val}" + end + end + + def assignment_line + "#{@ivar} = #{@val}" \ + " unless #{@null} == #{@val} && instance_variable_defined?(:#{@ivar})" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/builders/initializer.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/builders/initializer.rb new file mode 100644 index 00000000..afb115ed --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/builders/initializer.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +module Dry + module Initializer + module Builders + # @private + class Initializer + require_relative "signature" + require_relative "attribute" + + def self.[](config) + new(config).call + end + + def call + lines.flatten.compact.join("\n") + end + + private + + def initialize(config) + @config = config + @definitions = config.definitions.values + end + + def lines + [ + undef_line, + define_line, + params_lines, + options_lines, + end_line + ] + end + + def undef_line + "undef :__dry_initializer_initialize__" \ + " if private_method_defined? :__dry_initializer_initialize__" + end + + def define_line + "private def __dry_initializer_initialize__(#{Signature[@config]})" + end + + def params_lines + @definitions.reject(&:option).flat_map { Attribute[_1] }.map { " #{_1}" } + end + + def options_lines + @definitions.select(&:option).flat_map { Attribute[_1] }.map { " #{_1}" } + end + + def end_line + "end" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/builders/reader.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/builders/reader.rb new file mode 100644 index 00000000..415e451e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/builders/reader.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +module Dry + module Initializer + module Builders + # @private + class Reader + def self.[](definition) + new(definition).call + end + + def call + lines.flatten.compact.join("\n") + end + + private + + def initialize(definition) + @target = definition.target + @ivar = definition.ivar + @null = definition.null + @reader = definition.reader + end + + def lines + [undef_line, attribute_line, method_lines, type_line] + end + + def undef_line + "undef :#{@target} if method_defined?(:#{@target})" \ + " || private_method_defined?(:#{@target})" \ + " || protected_method_defined?(:#{@target})" + end + + def attribute_line + return unless @reader + + "attr_reader :#{@target}" unless @null + end + + def method_lines + return unless @reader + return unless @null + + [ + "def #{@target}", + " #{@ivar} unless Dry::Initializer::UNDEFINED == #{@ivar}", + "end" + ] + end + + def type_line + "#{@reader} :#{@target}" if %i[private protected].include? @reader + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/builders/signature.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/builders/signature.rb new file mode 100644 index 00000000..34f03cd5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/builders/signature.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +module Dry + module Initializer + module Builders + # @private + class Signature + def self.[](config) + new(config).call + end + + def call + [*required_params, *optional_params, "*", options].compact.join(", ") + end + + private + + def initialize(config) + @config = config + @options = config.options.any? + @null = config.null ? "Dry::Initializer::UNDEFINED" : "nil" + end + + def required_params + @config.params.reject(&:optional).map(&:source) + end + + def optional_params + @config.params.select(&:optional).map { |rec| "#{rec.source} = #{@null}" } + end + + def options + "**__dry_initializer_options__" if @options + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/config.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/config.rb new file mode 100644 index 00000000..abea19cf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/config.rb @@ -0,0 +1,188 @@ +# frozen_string_literal: true + +module Dry + module Initializer + # + # Gem-related configuration of some class + # + class Config + # @!attribute [r] null + # @return [Dry::Initializer::UNDEFINED, nil] value of unassigned variable + + # @!attribute [r] extended_class + # @return [Class] the class whose config collected by current object + + # @!attribute [r] parent + # @return [Dry::Initializer::Config] parent configuration + + # @!attribute [r] definitions + # @return [Hash] + # hash of attribute definitions with their source names + + attr_reader :null, :extended_class, :parent, :definitions + + # @!attribute [r] mixin + # @return [Module] reference to the module to be included into class + def mixin + @mixin ||= Module.new.tap do |mod| + initializer = self + mod.extend(Mixin::Local) + mod.define_method(:__dry_initializer_config__) do + initializer + end + mod.send :private, :__dry_initializer_config__ + end + end + + # List of configs of all subclasses of the [#extended_class] + # @return [Array] + def children + @children ||= Set.new + end + + # List of definitions for initializer params + # @return [Array] + def params + definitions.values.reject(&:option) + end + + # List of definitions for initializer options + # @return [Array] + def options + definitions.values.select(&:option) + end + + # Adds or redefines a parameter + # @param [Symbol] name + # @param [#call, nil] type (nil) + # @option opts [Proc] :default + # @option opts [Boolean] :optional + # @option opts [Symbol] :as + # @option opts [true, false, :protected, :public, :private] :reader + # @return [self] itself + def param(name, type = nil, **opts, &block) + add_definition(false, name, type, block, **opts) + end + + # Adds or redefines an option of [#dry_initializer] + # + # @param (see #param) + # @option (see #param) + # @return (see #param) + # + def option(name, type = nil, **opts, &block) + add_definition(true, name, type, block, **opts) + end + + # The hash of public attributes for an instance of the [#extended_class] + # @param [Dry::Initializer::Instance] instance + # @return [Hash] + def public_attributes(instance) + definitions.values.each_with_object({}) do |item, obj| + key = item.target + next unless instance.respond_to? key + + val = instance.send(key) + obj[key] = val unless null == val + end + end + + # The hash of assigned attributes for an instance of the [#extended_class] + # @param [Dry::Initializer::Instance] instance + # @return [Hash] + def attributes(instance) + definitions.values.each_with_object({}) do |item, obj| + key = item.target + val = instance.send(:instance_variable_get, item.ivar) + obj[key] = val unless null == val + end + end + + # Code of the `#__initialize__` method + # @return [String] + def code + Builders::Initializer[self] + end + + # Finalizes config + # @return [self] + def finalize + @definitions = final_definitions + check_order_of_params + mixin.class_eval(code, "#{__FILE__}:#{__LINE__} class_eval") + children.each(&:finalize) + self + end + + # Human-readable representation of configured params and options + # @return [String] + def inch + line = Builders::Signature[self] + line = line.gsub("__dry_initializer_options__", "options") + lines = ["@!method initialize(#{line})"] + lines += ["Initializes an instance of #{extended_class}"] + lines += definitions.values.map(&:inch) + lines += ["@return [#{extended_class}]"] + lines.join("\n") + end + + private + + def initialize(extended_class = nil, null: UNDEFINED) + @extended_class = extended_class.tap { |klass| klass&.include mixin } + sklass = extended_class&.superclass + @parent = sklass.dry_initializer if sklass.is_a? Dry::Initializer + @null = null || parent&.null + @definitions = {} + finalize + end + + def add_definition(option, name, type, block, **opts) + opts = { + parent: extended_class, + option:, + null:, + source: name, + type:, + block:, + **opts + } + + options = Dispatchers.call(**opts) + definition = Definition.new(**options) + definitions[definition.source] = definition + finalize + mixin.class_eval definition.code + end + + def final_definitions + parent_definitions = Hash(parent&.definitions&.dup) + definitions.each_with_object(parent_definitions) do |(key, val), obj| + obj[key] = check_type(obj[key], val) + end + end + + def check_type(previous, current) + return current unless previous + return current if previous.option == current.option + + raise SyntaxError, + "cannot reload #{previous} of #{extended_class.superclass}" \ + " by #{current} of its subclass #{extended_class}" + end + + def check_order_of_params + params.inject(nil) do |optional, current| + if current.optional + current + elsif optional + raise SyntaxError, "#{extended_class}: required #{current}" \ + " goes after optional #{optional}" + else + optional + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/definition.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/definition.rb new file mode 100644 index 00000000..11317f7e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/definition.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +module Dry + module Initializer + # + # @private + # @abstract + # + # Base class for parameter or option definitions + # Defines methods to add corresponding reader to the class, + # and build value of instance attribute. + # + class Definition + attr_reader :option, :null, :source, :target, :ivar, + :type, :optional, :default, :reader, + :desc + + def options + { + as: target, + type:, + optional:, + default:, + reader:, + desc: + }.compact + end + + def name + @name ||= "#{option ? "option" : "parameter"} '#{source}'" + end + alias_method :to_s, :name + alias_method :to_str, :name + alias_method :inspect, :name + + def ==(other) + other.instance_of?(self.class) && (other.source == source) + end + + def code + Builders::Reader[self] + end + + def inch + @inch ||= (option ? "@option" : "@param ").tap do |text| + text << " [Object]" + text << (option ? " :#{source}" : " #{source}") + text << (optional ? " (optional)" : " (required)") + text << " #{desc}" if desc + end + end + + private + + def initialize(**options) + @option = options[:option] + @null = options[:null] + @source = options[:source] + @target = options[:target] + @ivar = "@#{@target}" + @type = options[:type] + @reader = options[:reader] + @default = options[:default] + @optional = options[:optional] + @desc = options[:desc] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers.rb new file mode 100644 index 00000000..04dbf3e0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers.rb @@ -0,0 +1,117 @@ +# frozen_string_literal: true + +# The module is responsible for __normalizing__ arguments +# of `.param` and `.option`. +# +# What the module does is convert the source list of arguments +# into the standard set of options: +# - `:option` -- whether an argument is an option (or param) +# - `:source` -- the name of source option +# - `:target` -- the target name of the reader +# - `:reader` -- if the reader's privacy (:public, :protected, :private, nil) +# - `:ivar` -- the target name of the variable +# - `:type` -- the callable coercer of the source value +# - `:optional` -- if the argument is optional +# - `:default` -- the proc returning the default value of the source value +# - `:null` -- the value to be set to unassigned optional argument +# +# It is this set is used to build [Dry::Initializer::Definition]. +# +# @example +# # from `option :foo, [], as: :bar, optional: :true +# input = { name: :foo, as: :bar, type: [], optional: true } +# +# Dry::Initializer::Dispatcher.call(input) +# # => { +# # source: "foo", +# # target: "bar", +# # reader: :public, +# # ivar: "@bar", +# # type: ->(v) { Array(v) } }, # simplified for brevity +# # optional: true, +# # default: -> { Dry::Initializer::UNDEFINED }, +# # } +# +# # Settings +# +# The module uses global setting `null` to define what value +# should be set to variables that kept unassigned. By default it +# uses `Dry::Initializer::UNDEFINED` +# +# # Syntax Extensions +# +# The module supports syntax extensions. You can add any number +# of custom dispatchers __on top__ of the stack of default dispatchers. +# Every dispatcher should be a callable object that takes +# the source set of options and converts it to another set of options. +# +# @example Add special dispatcher +# +# # Define a dispatcher for key :integer +# dispatcher = proc do |integer: false, **opts| +# opts.merge(type: proc(&:to_i)) if integer +# end +# +# # Register a dispatcher +# Dry::Initializer::Dispatchers << dispatcher +# +# # Now you can use option `integer: true` instead of `type: proc(&:to_i)` +# class Foo +# extend Dry::Initializer +# param :id, integer: true +# end +# +module Dry + module Initializer + module Dispatchers + extend self + + # @!attribute [rw] null Defines a value to be set to unassigned attributes + # @return [Object] + attr_accessor :null + + # + # Registers a new dispatcher + # + # @param [#call] dispatcher + # @return [self] itself + # + def <<(dispatcher) + @pipeline = [dispatcher] + pipeline + self + end + + # + # Normalizes the source set of options + # + # @param [Hash] options + # @return [Hash] normalized set of options + # + def call(**options) + options = {null:, **options} + pipeline.reduce(options) { |opts, dispatcher| dispatcher.call(**opts) } + end + + private + + require_relative "dispatchers/build_nested_type" + require_relative "dispatchers/check_type" + require_relative "dispatchers/prepare_default" + require_relative "dispatchers/prepare_ivar" + require_relative "dispatchers/prepare_optional" + require_relative "dispatchers/prepare_reader" + require_relative "dispatchers/prepare_source" + require_relative "dispatchers/prepare_target" + require_relative "dispatchers/unwrap_type" + require_relative "dispatchers/wrap_type" + + def pipeline + @pipeline ||= [ + PrepareSource, PrepareTarget, PrepareIvar, PrepareReader, + PrepareDefault, PrepareOptional, + UnwrapType, CheckType, BuildNestedType, WrapType + ] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/build_nested_type.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/build_nested_type.rb new file mode 100644 index 00000000..d575f108 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/build_nested_type.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +# Prepare nested data type from a block +# +# @example +# option :foo do +# option :bar +# option :qux +# end +# +module Dry + module Initializer + module Dispatchers + module BuildNestedType + extend self + + # rubocop: disable Metrics/ParameterLists + def call(parent:, source:, target:, type: nil, block: nil, **options) + check_certainty!(source, type, block) + check_name!(target, block) + type ||= build_nested_type(parent, target, block) + {parent:, source:, target:, type:, **options} + end + # rubocop: enable Metrics/ParameterLists + + private + + def check_certainty!(source, type, block) + return unless block + return unless type + + raise ArgumentError, <<~MESSAGE + You should define coercer of values of argument '#{source}' + either though the parameter/option, or via nested block, but not the both. + MESSAGE + end + + def check_name!(name, block) + return unless block + return unless name[/^_|__|_$/] + + raise ArgumentError, <<~MESSAGE + The name of the argument '#{name}' cannot be used for nested struct. + A proper name can use underscores _ to divide alphanumeric parts only. + MESSAGE + end + + def build_nested_type(parent, name, block) + return unless block + + klass_name = full_name(parent, name) + build_struct(klass_name, block) + end + + def full_name(parent, name) + "::#{parent.name}::#{name.to_s.split("_").compact.map(&:capitalize).join}" + end + + def build_struct(klass_name, block) + # rubocop: disable Security/Eval + eval <<~RUBY, TOPLEVEL_BINDING, __FILE__, __LINE__ + 1 + class #{klass_name} < Dry::Initializer::Struct + end + RUBY + # rubocop: enable Style/DocumentDynamicEvalDefinition + # rubocop: enable Security/Eval + const_get(klass_name).tap { _1.class_eval(&block) } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/check_type.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/check_type.rb new file mode 100644 index 00000000..2ec02a1e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/check_type.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +# Checks whether an unwrapped type is valid +# +module Dry + module Initializer + module Dispatchers + module CheckType + extend self + + def call(source:, type: nil, wrap: 0, **options) + check_if_callable! source, type + check_arity! source, type, wrap + + {source:, type:, wrap:, **options} + end + + private + + def check_if_callable!(source, type) + return if type.nil? + return if type.respond_to?(:call) + + raise ArgumentError, + "The type of the argument '#{source}' should be callable" + end + + def check_arity!(_source, type, wrap) + return if type.nil? + return if wrap.zero? + return if type.method(:call).arity.abs == 1 + + raise ArgumentError, <<~MESSAGE + The dry_intitializer supports wrapped types with one argument only. + You cannot use array types with element coercers having several arguments. + + For example, this definitions are correct: + option :foo, [proc(&:to_s)] + option :bar, type: [[]] + option :baz, ->(a, b) { [a, b] } + + While this is not: + option :foo, [->(a, b) { [a, b] }] + MESSAGE + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/prepare_default.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/prepare_default.rb new file mode 100644 index 00000000..1aa288ff --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/prepare_default.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +# Prepares the `:default` option +# +# It must respond to `.call` without arguments +# +module Dry + module Initializer + module Dispatchers + module PrepareDefault + extend self + + def call(default: nil, optional: nil, **options) + default = callable! default + check_arity! default + + {default:, optional: (optional | default), **options} + end + + private + + def callable!(default) + return unless default + return default if default.respond_to?(:call) + return callable(default.to_proc) if default.respond_to?(:to_proc) + + invalid!(default) + end + + def check_arity!(default) + return unless default + + arity = default.method(:call).arity.to_i + return unless arity.positive? + + invalid!(default) + end + + def invalid!(default) + raise TypeError, "The #{default.inspect} should be" \ + " either convertable to proc with no arguments," \ + " or respond to #call without arguments." + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/prepare_ivar.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/prepare_ivar.rb new file mode 100644 index 00000000..8f6a8f1c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/prepare_ivar.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +# Prepares the variable name of a parameter or an option. +# +module Dry + module Initializer + module Dispatchers + module PrepareIvar + module_function + + def call(target:, **options) + ivar = "@#{target}".delete("?").to_sym + + {target:, ivar:, **options} + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/prepare_optional.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/prepare_optional.rb new file mode 100644 index 00000000..350fdf0c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/prepare_optional.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +# Defines whether an argument is optional +# +module Dry + module Initializer + module Dispatchers + module PrepareOptional + module_function + + def call(optional: nil, default: nil, required: nil, **options) + optional ||= default + optional &&= !required + + {optional: !!optional, default:, **options} + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/prepare_reader.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/prepare_reader.rb new file mode 100644 index 00000000..02d6d00e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/prepare_reader.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +# Checks the reader privacy +# +module Dry + module Initializer + module Dispatchers + module PrepareReader + extend self + + def call(target: nil, reader: :public, **options) + reader = case reader.to_s + when "false", "" then nil + when "true" then :public + when "public", "private", "protected" then reader.to_sym + else invalid_reader!(target, reader) + end + + {target:, reader:, **options} + end + + private + + def invalid_reader!(target, _reader) + raise ArgumentError, <<~MESSAGE + Invalid setting for the ##{target} reader's privacy. + Use the one of the following values for the `:reader` option: + - 'public' (true) for the public reader (default) + - 'private' for the private reader + - 'protected' for the protected reader + - nil (false) if no reader should be defined + MESSAGE + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/prepare_source.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/prepare_source.rb new file mode 100644 index 00000000..fa6c7780 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/prepare_source.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +# The dispatcher verifies a correctness of the source name +# of param or option, taken as a `:source` option. +# +# We allow any stringified name for the source. +# For example, this syntax is correct because we accept any key +# in the original hash of arguments, but give them proper names: +# +# ```ruby +# class Foo +# extend Dry::Initializer +# +# option "", as: :first +# option 1, as: :second +# end +# +# foo = Foo.new("": 42, 1: 666) +# foo.first # => 42 +# foo.second # => 666 +# ``` +# +module Dry + module Initializer + module Dispatchers + module PrepareSource + module_function + + def call(source:, **options) + {source: source.to_s.to_sym, **options} + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/prepare_target.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/prepare_target.rb new file mode 100644 index 00000000..a74bb504 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/prepare_target.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +# Prepares the target name of a parameter or an option. +# +# Unlike source, the target must satisfy requirements for Ruby variable names. +# It also shouldn't be in conflict with names used by the gem. +# +module Dry + module Initializer + module Dispatchers + module PrepareTarget + extend self + + # List of variable names reserved by the gem + RESERVED = %i[ + __dry_initializer_options__ + __dry_initializer_config__ + __dry_initializer_value__ + __dry_initializer_definition__ + __dry_initializer_initializer__ + ].freeze + + def call(source:, target: nil, as: nil, **options) + target ||= as || source + target = target.to_s.to_sym.downcase + + check_ruby_name!(target) + check_reserved_names!(target) + + {source:, target:, **options} + end + + private + + def check_ruby_name!(target) + return if target[/\A[[:alpha:]_][[:alnum:]_]*\??\z/u] + + raise ArgumentError, + "The name `#{target}` is not allowed for Ruby methods" + end + + def check_reserved_names!(target) + return unless RESERVED.include?(target) + + raise ArgumentError, + "The method name `#{target}` is reserved by the dry-initializer gem" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/unwrap_type.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/unwrap_type.rb new file mode 100644 index 00000000..8af2ca91 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/unwrap_type.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +# Looks at the `:type` option and counts how many nested arrays +# it contains around either nil or a callable value. +# +# The counted number is preserved in the `:wrap` virtual option +# used by the [WrapType] dispatcher. +# +module Dry + module Initializer + module Dispatchers + module UnwrapType + extend self + + def call(type: nil, wrap: 0, **options) + type, count = unwrap(type, wrap) + + {type:, wrap: count, **options} + end + + private + + def unwrap(type, count) + if type.is_a?(::Array) + unwrap(type.first, count + 1) + else + [type, count] + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/wrap_type.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/wrap_type.rb new file mode 100644 index 00000000..b6009288 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dispatchers/wrap_type.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +# Takes `:type` and `:wrap` to construct the final value coercer +# +module Dry + module Initializer + module Dispatchers + module WrapType + extend self + + def call(type: nil, wrap: 0, **options) + {type: wrapped_type(type, wrap), **options} + end + + private + + def wrapped_type(type, count) + return type if count.zero? + + ->(value) { wrap_value(value, count, type) } + end + + def wrap_value(value, count, type) + if count.zero? + type ? type.call(value) : value + else + return [wrap_value(value, count - 1, type)] unless value.is_a?(Array) + + value.map { |item| wrap_value(item, count - 1, type) } + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dsl.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dsl.rb new file mode 100644 index 00000000..3e94db9b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/dsl.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module Dry + module Initializer + # Module-level DSL + module DSL + # Setting for null (undefined value) + # @return [nil, Dry::Initializer::UNDEFINED] + attr_reader :null + + # Returns a version of the module with custom settings + # @option settings [Boolean] :undefined + # If unassigned params and options should be treated different from nil + # @return [Dry::Initializer] + def [](undefined: true, **) + null = undefined == false ? nil : UNDEFINED + Module.new.tap do |mod| + mod.extend DSL + mod.include self + mod.send(:instance_variable_set, :@null, null) + end + end + + # Returns mixin module to be included to target class by hand + # @return [Module] + # @yield proc defining params and options + def define(procedure = nil, &block) + config = Config.new(null:) + config.instance_exec(&procedure || block) + config.mixin.include Mixin::Root + config.mixin + end + + private + + def extended(klass) + config = Config.new(klass, null:) + klass.send :instance_variable_set, :@dry_initializer, config + klass.include Mixin::Root + end + + class << self + private + + def extended(mod) + mod.instance_variable_set :@null, UNDEFINED + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/mixin.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/mixin.rb new file mode 100644 index 00000000..225314c5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/mixin.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Dry + module Initializer + # @private + module Mixin + extend DSL # @deprecated + include Dry::Initializer # @deprecated + # @deprecated + def self.extended(klass) + warn "[DEPRECATED] Use Dry::Initializer instead of its alias" \ + " Dry::Initializer::Mixin. The later will be removed in v2.1.0" + super + end + + require_relative "mixin/root" + require_relative "mixin/local" + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/mixin/local.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/mixin/local.rb new file mode 100644 index 00000000..30176f5e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/mixin/local.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Dry + module Initializer + module Mixin + # @private + module Local + attr_reader :klass + + def inspect + "Dry::Initializer::Mixin::Local[#{klass}]" + end + alias_method :to_s, :inspect + alias_method :to_str, :inspect + + private + + def included(klass) + @klass = klass + super + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/mixin/root.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/mixin/root.rb new file mode 100644 index 00000000..a5391603 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/mixin/root.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Dry + module Initializer + module Mixin + # @private + module Root + private + + def initialize(*args, **kwargs) + __dry_initializer_initialize__(*args, **kwargs) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/struct.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/struct.rb new file mode 100644 index 00000000..576948b6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/struct.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +# The nested structure that takes nested hashes with indifferent access +# +module Dry + module Initializer + class Struct + extend ::Dry::Initializer + + class << self + undef_method :param + + def new(options) + super(**Hash(options).each_with_object({}) { |(k, v), h| h[k.to_sym] = v }) + end + alias_method :call, :new + end + + # + # Represents event data as a nested hash with deeply stringified keys + # @return [Hash] + # + def to_h + self + .class + .dry_initializer + .attributes(self) + .each_with_object({}) { |(k, v), h| h[k.to_s] = __hashify(v) } + end + + private + + def __hashify(value) + case value + when Hash + value.each_with_object({}) { |(k, v), obj| obj[k.to_s] = __hashify(v) } + when Array then value.map { |v| __hashify(v) } + when Dry::Initializer::Struct then value.to_h + else value + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/undefined.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/undefined.rb new file mode 100644 index 00000000..7a6b9011 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/undefined.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +module Dry + module Initializer + module UNDEFINED + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/version.rb b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/version.rb new file mode 100644 index 00000000..ebe2f2fd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/dry/initializer/version.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module Dry + module Initializer + VERSION = "3.2.0" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/tasks/benchmark.rake b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/tasks/benchmark.rake new file mode 100644 index 00000000..acf99356 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/tasks/benchmark.rake @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +namespace :benchmark do + desc "Runs benchmarks for plain params" + task :plain_params do + system "ruby benchmarks/plain_params.rb" + end + + desc "Runs benchmarks for plain options" + task :plain_options do + system "ruby benchmarks/plain_options.rb" + end + + desc "Runs benchmarks for value coercion" + task :with_coercion do + system "ruby benchmarks/with_coercion.rb" + end + + desc "Runs benchmarks with defaults" + task :with_defaults do + system "ruby benchmarks/with_defaults.rb" + end + + desc "Runs benchmarks with defaults and coercion" + task :with_defaults_and_coercion do + system "ruby benchmarks/with_defaults_and_coercion.rb" + end + + desc "Runs benchmarks for several defaults" + task :compare_several_defaults do + system "ruby benchmarks/with_several_defaults.rb" + end +end + +desc "Runs all benchmarks" +task benchmark: %i[ + benchmark:plain_params + benchmark:plain_options + benchmark:with_coercion + benchmark:with_defaults + benchmark:with_defaults_and_coercion + benchmark:compare_several_defaults +] diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/tasks/profile.rake b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/tasks/profile.rake new file mode 100644 index 00000000..97ac7667 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-initializer-3.2.0/lib/tasks/profile.rake @@ -0,0 +1,82 @@ +# frozen_string_literal: true + +# rubocop: disable Lint/ConstantDefinitionInBlock +namespace :profile do + def profile(name, execution, &definition) + require "dry-initializer" + require "ruby-prof" + require "fileutils" + + definition.call + result = RubyProf.profile do + 1_000.times { execution.call } + end + + FileUtils.mkdir_p "./tmp" + + FileUtils.touch "./tmp/#{name}.dot" + File.open("./tmp/#{name}.dot", "w+") do |output| + RubyProf::DotPrinter.new(result).print(output, min_percent: 0) + end + + FileUtils.touch "./tmp/#{name}.html" + File.open("./tmp/#{name}.html", "w+") do |output| + RubyProf::CallStackPrinter.new(result).print(output, min_percent: 0) + end + + system "dot -Tpng ./tmp/#{name}.dot > ./tmp/#{name}.png" + end + + desc "Profiles initialization with required param and option" + task :required do + profile("required", -> { User.new :Andy, email: "andy@example.com" }) do + class User + extend Dry::Initializer + param :name + option :email + end + end + end + + desc "Profiles initialization with default param and option" + task :defaults do + profile("defaults", -> { User.new }) do + class User + extend Dry::Initializer + param :name, default: -> { :Andy } + option :email, default: -> { "andy@example.com" } + end + end + end + + desc "Profiles initialization with coerced param and option" + task :coercion do + profile("coercion", -> { User.new :Andy, email: :"andy@example.com" }) do + class User + extend Dry::Initializer + param :name, proc(&:to_s) + option :email, proc(&:to_s) + end + end + end + + desc "Profiles initialization with coerced defaults of param and option" + task :default_coercion do + profile("default_coercion", -> { User.new }) do + class User + extend Dry::Initializer + param :name, proc(&:to_s), default: -> { :Andy } + option :email, proc(&:to_s), default: -> { :"andy@example.com" } + end + end + end +end + +desc "Makes all profiling at once" +task profile: %i[ + profile:required + profile:defaults + profile:coercion + profile:default_coercion +] +# rubocop: enable Lint/ConstantDefinitionInBlock diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/CHANGELOG.md b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/CHANGELOG.md new file mode 100644 index 00000000..46babb7d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/CHANGELOG.md @@ -0,0 +1,375 @@ + + +## 1.6.0 2025-01-04 + + +### Fixed + +- Fix NoMethodError when trying to get AST of a Builder's result. (via #107) (@estum) + +### Changed + +- Set 3.1 as minimum ruby version (@flash-gordon) + +[Compare v1.5.0...v1.6.0](https://github.com/dry-rb/dry-logic/compare/v1.5.0...v1.6.0) + +## 1.5.0 2022-11-24 + + +### Added + +- `uri_rfc3986?` predicate that uses a better regexp than `uri?` (see #94 for more details) (@hieuk09) + +### Changed + +- Made `Predicates.respond_to?` compatible with `Object#respond_to?` (via #105) (@solnic) +- Made `Predicates.eql?` compatible with `Object#eql?` (via #106) (@solnic) + +[Compare v1.4.0...v1.5.0](https://github.com/dry-rb/dry-logic/compare/v1.4.0...v1.5.0) + +## 1.4.0 2022-11-04 + + +### Changed + +- Updated to dry-core 1.0 (@flash-gordon + @solnic) + +[Compare v1.3.0...v1.4.0](https://github.com/dry-rb/dry-logic/compare/v1.3.0...v1.4.0) + +## 1.3.0 2022-10-15 + + +### Changed + +- Use zeitwerk for auto-loading (@solnic + @flash-gordon) + +[Compare v1.2.0...v1.3.0](https://github.com/dry-rb/dry-logic/compare/v1.2.0...v1.3.0) + +## 1.2.0 2021-04-26 + + +### Added + +- Add predicate and operation builder DSL (@oleander) + + +[Compare v1.1.1...v1.2.0](https://github.com/dry-rb/dry-logic/compare/v1.1.1...v1.2.0) + +## 1.1.1 2021-04-14 + + +### Fixed + +- Fixed a crash under jruby caused by arg splatting in Binary operations (@flash-gordon) + + +[Compare v1.1.0...v1.1.1](https://github.com/dry-rb/dry-logic/compare/v1.1.0...v1.1.1) + +## 1.1.0 2020-12-26 + + +### Fixed + +- Nested `Check` operations no longer crash under MRI 3.0 (@oleander) + +### Changed + +- Switched to equalizer from dry-core (@solnic) + +[Compare v1.0.8...v1.1.0](https://github.com/dry-rb/dry-logic/compare/v1.0.8...v1.1.0) + +## 1.0.8 2020-09-28 + + +### Fixed + +- Better Ruby 3 support with fixed specialization for rules of negative arity (@flash-gordon) + + +[Compare v1.0.7...v1.0.8](https://github.com/dry-rb/dry-logic/compare/v1.0.7...v1.0.8) + +## 1.0.7 2020-08-13 + + +### Added + +- A new `uri?` predicate that you can use to verify `URI` strings, ie `uri?("https", "https://dry-rb.org")` (@nerburish) +- New predicates: `uuid_v1?`, `uuid_v2?`, `uuid_v3?` and `uuid_v5?` (via #75) (@jamesbrauman) + + +[Compare v1.0.6...v1.0.7](https://github.com/dry-rb/dry-logic/compare/v1.0.6...v1.0.7) + +## 1.0.6 2020-02-10 + + +### Fixed + +- Made the regexp used by `uuid_v4?` more secure (@kml) + + +[Compare v1.0.5...v1.0.6](https://github.com/dry-rb/dry-logic/compare/v1.0.5...v1.0.6) + +## 1.0.5 2019-11-07 + + +### Fixed + +- Make `format?` tolerant to `nil` values. It already worked like that before, but starting Ruby 2.7 it would produce warnings. Now it won't. Don't rely on this behavior, it's only added to make tests pass in dry-schema. Use explicit type checks instead (@flash-gordon) + + +[Compare v1.0.4...v1.0.5](https://github.com/dry-rb/dry-logic/compare/v1.0.4...v1.0.5) + +## 1.0.4 2019-11-06 + + +### Fixed + +- Fix keyword warnings (@flash-gordon) + + +[Compare v1.0.3...v1.0.4](https://github.com/dry-rb/dry-logic/compare/v1.0.3...v1.0.4) + +## 1.0.3 2019-08-01 + + +### Added + +- `bytesize?` predicate (@bmalinconico) +- `min_bytesize?` predicate (@bmalinconico) +- `max_bytesize? predicate (@bmalinconico) + +### Changed + +- Min ruby version was set to `>= 2.4.0` (@flash-gordon) + +[Compare v1.0.2...v1.0.3](https://github.com/dry-rb/dry-logic/compare/v1.0.2...v1.0.3) + +## 1.0.2 2019-06-14 + +Re-pushed 1.0.1 after dry-schema 1.2.0 release. + + +[Compare v1.0.1...v1.0.2](https://github.com/dry-rb/dry-logic/compare/v1.0.1...v1.0.2) + +## 1.0.1 2019-06-04 + +This release was removed from rubygems because it broke dry-schema. + +### Added + +- `uuid_v4?` predicate (radar) +- `respond_to?` predicate (waiting-for-dev) + + +[Compare v1.0.0...v1.0.1](https://github.com/dry-rb/dry-logic/compare/v1.0.0...v1.0.1) + +## 1.0.0 2019-04-23 + + +### Changed + +- Version bump to `1.0.0` (flash-gordon) + +[Compare v0.6.1...v1.0.0](https://github.com/dry-rb/dry-logic/compare/v0.6.1...v1.0.0) + +## 0.6.1 2019-04-18 + + +### Fixed + +- Fix a regression in dry-validation 0.x for argument-less predicates (flash-gordon) + + +[Compare v0.6.0...v0.6.1](https://github.com/dry-rb/dry-logic/compare/v0.6.0...v0.6.1) + +## 0.6.0 2019-04-04 + + +### Added + +- Generating hints can be disabled by building `Operations::And` with `hints: false` option set (solnic) + +### Changed + +- `Rule` construction has been optimized so that currying and application is multiple-times faster (flash-gordon) + +[Compare v0.5.0...v0.6.0](https://github.com/dry-rb/dry-logic/compare/v0.5.0...v0.6.0) + +## 0.5.0 2019-01-29 + + +### Added + +- `:nil?` predicate (`none?` is now an alias) (solnic) + +### Fixed + +- `Operation::Key#ast` will now return a correct AST with non-Undefined inputs (solnic) + + +[Compare v0.4.2...v0.5.0](https://github.com/dry-rb/dry-logic/compare/v0.4.2...v0.5.0) + +## 0.4.2 2017-09-15 + + +### Added + +- New `:case?` predicate matches a value against the given object with `#===` (flash-gordon) +- New `:is?` predicate checks objects identity (using `#equal?`) (flash-gordon) + +### Fixed + +- A bug with using custom predicates within a standalone module in `dry-validation` (flash-gordon) + + +[Compare v0.4.1...v0.4.2](https://github.com/dry-rb/dry-logic/compare/v0.4.1...v0.4.2) + +## 0.4.1 2017-01-23 + + +### Fixed + +- Warnings on MRI 2.4.0 are gone (jtippett) + +### Changed + +- Predicates simply reuse other predicate methods instead of referring to them via `#[]` (georgemillo) + +[Compare v0.4.0...v0.4.1](https://github.com/dry-rb/dry-logic/compare/v0.4.0...v0.4.1) + +## 0.4.0 2016-09-21 + +This is a partial rewrite focused on internal clean up and major performance improvements. This is also the beginning of the work to make this library first-class rather than "just" a rule backend for dry-validation and dry-types. + +### Added + +- `Rule#[]` which applies a rule and always returns `true` or `false` (solnic) +- `Rule#bind` which returns a rule with its predicate bound to a given object (solnic) +- `Rule#eval_args` which evaluates unbound-methods-args in the context of a given object (solnic) +- `Logic.Rule` builder function (solnic) +- Nice `#inspect` on rules and operation objects (solnic) + +### Changed + +- [BRAEKING] New result API (solnic) +- [BREAKING] `Predicate` is now `Rule::Predicate` (solnic) +- [BREAKING] `Rule::Conjunction` is now `Operation::And` (solnic) +- [BREAKING] `Rule::Disjunction` is now `Operation::Or` (solnic) +- [BREAKING] `Rule::ExlusiveDisjunction` is now `Operation::Xor` (solnic) +- [BREAKING] `Rule::Implication` is now `Operation::Implication` (solnic) +- [BREAKING] `Rule::Set` is now `Operation::Set` (solnic) +- [BREAKING] `Rule::Each` is now `Operation::Each` (solnic) +- [BREAKING] `Rule.new` accepts a predicate function as its first arg now (solnic) +- [BREAKING] `Rule#name` is now `Rule#id` (solnic) +- `Rule#parameters` is public now (solnic) + +[Compare v0.3.0...v0.4.0](https://github.com/dry-rb/dry-logic/compare/v0.3.0...v0.4.0) + +## 0.3.0 2016-07-01 + + +### Added + +- `:type?` predicate imported from dry-types (solnic) +- `Rule#curry` interface (solnic) + +### Changed + +- Predicates AST now includes information about args (names & possible values) (fran-worley + solnic) +- Predicates raise errors when they are called with invalid arity (fran-worley + solnic) +- Rules no longer evaluate input twice when building result objects (solnic) + +[Compare v0.2.3...v0.3.0](https://github.com/dry-rb/dry-logic/compare/v0.2.3...v0.3.0) + +## 0.2.3 2016-05-11 + + +### Added + +- `not_eql?`, `includes?`, `excludes?` predicates (fran-worley) + +### Changed + +- Renamed `inclusion?` to `included_in?` and deprecated `inclusion?` (fran-worley) +- Renamed `exclusion?` to `excluded_from?` and deprecated `exclusion?` (fran-worley) + +[Compare v0.2.2...v0.2.3](https://github.com/dry-rb/dry-logic/compare/v0.2.2...v0.2.3) + +## 0.2.2 2016-03-30 + + +### Added + +- `number?`, `odd?`, `even?` predicates (fran-worley) + + +[Compare v0.2.1...v0.2.2](https://github.com/dry-rb/dry-logic/compare/v0.2.1...v0.2.2) + +## 0.2.1 2016-03-20 + + +### Fixed + +- Result AST for `Rule::Each` correctly maps elements with eql inputs (solnic) + + +[Compare v0.2.0...v0.2.1](https://github.com/dry-rb/dry-logic/compare/v0.2.0...v0.2.1) + +## 0.2.0 2016-03-11 + + +### Changed + +- Entire AST has been redefined (solnic) + +[Compare v0.1.4...v0.2.0](https://github.com/dry-rb/dry-logic/compare/v0.1.4...v0.2.0) + +## 0.1.4 2016-01-27 + + +### Added + +- Support for hash-names in `Check` and `Result` which can properly resolve input + from nested results (solnic) + + +[Compare v0.1.3...v0.1.4](https://github.com/dry-rb/dry-logic/compare/v0.1.3...v0.1.4) + +## 0.1.3 2016-01-27 + + +### Added + +- Support for resolving input from `Rule::Result` (solnic) + +### Changed + +- `Check` and `Result` carry original input(s) (solnic) + +[Compare v0.1.2...v0.1.3](https://github.com/dry-rb/dry-logic/compare/v0.1.2...v0.1.3) + +## 0.1.2 2016-01-19 + + +### Fixed + +- `xor` returns wrapped results when used against another result-rule (solnic) + + +[Compare v0.1.1...v0.1.2](https://github.com/dry-rb/dry-logic/compare/v0.1.1...v0.1.2) + +## 0.1.1 2016-01-18 + + +### Added + +- `Rule::Attr` which can be applied to a data object with attr readers (SunnyMagadan) +- `Rule::Result` which can be applied to a result object (solnic) +- `true?` and `false?` predicates (solnic) + + +[Compare v0.1.0...v0.1.1](https://github.com/dry-rb/dry-logic/compare/v0.1.0...v0.1.1) + +## 0.1.0 2016-01-11 + +Code extracted from dry-validation 0.4.1 diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/LICENSE b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/LICENSE new file mode 100644 index 00000000..9f9f214d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2015-2023 dry-rb team + +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 AUTHORS OR +COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/README.md b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/README.md new file mode 100644 index 00000000..c8d31bb0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/README.md @@ -0,0 +1,22 @@ + +[gem]: https://rubygems.org/gems/dry-logic +[actions]: https://github.com/dry-rb/dry-logic/actions + +# dry-logic [![Gem Version](https://badge.fury.io/rb/dry-logic.svg)][gem] [![CI Status](https://github.com/dry-rb/dry-logic/workflows/CI/badge.svg)][actions] + +## Links + +* [User documentation](https://dry-rb.org/gems/dry-logic) +* [API documentation](http://rubydoc.info/gems/dry-logic) +* [Forum](https://discourse.dry-rb.org) + +## Supported Ruby versions + +This library officially supports the following Ruby versions: + +* MRI `>= 3.1` +* jruby `>= 9.4` (not tested on CI) + +## License + +See `LICENSE` file. diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/dry-logic.gemspec b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/dry-logic.gemspec new file mode 100644 index 00000000..386da2d0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/dry-logic.gemspec @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +# this file is synced from dry-rb/template-gem project + +lib = File.expand_path("lib", __dir__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require "dry/logic/version" + +Gem::Specification.new do |spec| + spec.name = "dry-logic" + spec.authors = ["Piotr Solnica"] + spec.email = ["piotr.solnica@gmail.com"] + spec.license = "MIT" + spec.version = Dry::Logic::VERSION.dup + + spec.summary = "Predicate logic with rule composition" + spec.description = spec.summary + spec.homepage = "https://dry-rb.org/gems/dry-logic" + spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-logic.gemspec", "lib/**/*"] + spec.bindir = "bin" + spec.executables = [] + spec.require_paths = ["lib"] + + spec.metadata["allowed_push_host"] = "https://rubygems.org" + spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-logic/blob/main/CHANGELOG.md" + spec.metadata["source_code_uri"] = "https://github.com/dry-rb/dry-logic" + spec.metadata["bug_tracker_uri"] = "https://github.com/dry-rb/dry-logic/issues" + spec.metadata["rubygems_mfa_required"] = "true" + + spec.required_ruby_version = ">= 3.1.0" + + # to update dependencies edit project.yml + spec.add_dependency "bigdecimal" + spec.add_dependency "concurrent-ruby", "~> 1.0" + spec.add_dependency "dry-core", "~> 1.1" + spec.add_dependency "zeitwerk", "~> 2.6" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry-logic.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry-logic.rb new file mode 100644 index 00000000..6405d8ca --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry-logic.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +require "dry/logic" diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic.rb new file mode 100644 index 00000000..3a1a0876 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require "zeitwerk" +require "dry/core" + +module Dry + module Logic + include Dry::Core::Constants + + def self.loader + @loader ||= Zeitwerk::Loader.new.tap do |loader| + root = File.expand_path("..", __dir__) + loader.tag = "dry-logic" + loader.inflector = Zeitwerk::GemInflector.new("#{root}/dry-logic.rb") + loader.push_dir(root) + loader.ignore( + "#{root}/dry-logic.rb", + "#{root}/dry/logic/version.rb" + ) + end + end + + loader.setup + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/appliable.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/appliable.rb new file mode 100644 index 00000000..3e7b8314 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/appliable.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module Dry + module Logic + module Appliable + def id + options[:id] + end + + def result + options[:result] + end + + def applied? + !result.nil? + end + + def success? + result.equal?(true) + end + + def failure? + !success? + end + + def to_ast + if applied? && id + [success? ? :success : :failure, [id, ast]] + else + ast + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/builder.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/builder.rb new file mode 100644 index 00000000..76c8df8e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/builder.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true + +require "singleton" +require "delegate" + +module Dry + module Logic + module Builder + IGNORED_OPERATIONS = %i[ + Abstract + Binary + Unary + ].freeze + + IGNORED_PREDICATES = [ + :predicate + ].freeze + + # Predicate and operation builder + # + # @block [Proc] + # @return [Builder::Result] + # @example Check if input is zero + # is_zero = Dry::Logic::Builder.call do + # negation { lt?(0) ^ gt?(0) } + # end + # + # p is_zero.call(1) # => false + # p is_zero.call(0) # => true + # p is_zero.call(-1) # => false + def call(&) + Context.instance.call(&) + end + module_function :call + alias_method :build, :call + public :call, :build + + class Context + include Dry::Logic + include Singleton + + module Predicates + include Logic::Predicates + end + + # @see Builder#call + def call(&) + instance_eval(&) + end + + # Defines custom predicate + # + # @name [Symbol] Name of predicate + # @Context [Proc] + def predicate(name, context = nil, &block) + if singleton_class.method_defined?(name) + singleton_class.undef_method(name) + end + + predicate = Rule::Predicate.new(context || block) + + define_singleton_method(name) do |*args| + predicate.curry(*args) + end + end + + # Defines methods for operations and predicates + def initialize + Operations.constants(false).each do |name| + next if IGNORED_OPERATIONS.include?(name) + + operation = Operations.const_get(name) + + define_singleton_method(name.downcase) do |*args, **kwargs, &block| + operation.new(*call(&block), *args, **kwargs) + end + end + + Predicates::Methods.instance_methods(false).each do |name| + unless IGNORED_PREDICATES.include?(name) + predicate(name, Predicates[name]) + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/evaluator.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/evaluator.rb new file mode 100644 index 00000000..a5d59eb3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/evaluator.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +module Dry + module Logic + class Evaluator + include Dry::Equalizer(:path) + + attr_reader :path + + class Set + include Dry::Equalizer(:evaluators) + + attr_reader :evaluators + + def self.new(paths) + super(paths.map { |path| Evaluator::Key.new(path) }) + end + + def initialize(evaluators) + @evaluators = evaluators + end + + def call(input) + evaluators.map { |evaluator| evaluator[input] } + end + alias_method :[], :call + end + + class Key < Evaluator + def call(input) + path.reduce(input) { |a, e| a[e] } + end + alias_method :[], :call + end + + class Attr < Evaluator + def call(input) + path.reduce(input) { |a, e| a.public_send(e) } + end + alias_method :[], :call + end + + def initialize(path) + @path = Array(path) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/abstract.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/abstract.rb new file mode 100644 index 00000000..408eadc1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/abstract.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +module Dry + module Logic + module Operations + class Abstract + include Core::Constants + include ::Dry::Equalizer(:rules, :options) + include Operators + + attr_reader :rules + + attr_reader :options + + def initialize(*rules, **options) + @rules = rules + @options = options + end + + def id + options[:id] + end + + def curry(*args) + new(rules.map { |rule| rule.curry(*args) }, **options) + end + + def new(rules, **new_options) + self.class.new(*rules, **options, **new_options) + end + + def with(new_options) + new(rules, **options, **new_options) + end + + def to_ast + ast + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/and.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/and.rb new file mode 100644 index 00000000..2512fcdf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/and.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +module Dry + module Logic + module Operations + class And < Binary + attr_reader :hints + + def initialize(*, **) + super + @hints = options.fetch(:hints, true) + end + + def type + :and + end + alias_method :operator, :type + + def call(input) + left_result = left.(input) + + if left_result.success? + right_result = right.(input) + + if right_result.success? + Result::SUCCESS + else + Result.new(false, id) { right_result.ast(input) } + end + else + Result.new(false, id) do + left_ast = left_result.to_ast + hints ? [type, [left_ast, [:hint, right.ast(input)]]] : left_ast + end + end + end + + def [](input) + left[input] && right[input] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/attr.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/attr.rb new file mode 100644 index 00000000..7b2ad1f2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/attr.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Dry + module Logic + module Operations + class Attr < Key + def self.evaluator(name) + Evaluator::Attr.new(name) + end + + def type + :attr + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/binary.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/binary.rb new file mode 100644 index 00000000..9d1af1b0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/binary.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Dry + module Logic + module Operations + class Binary < Abstract + attr_reader :left + + attr_reader :right + + def initialize(left, right, **options) + super + @left = left + @right = right + end + + def ast(input = Undefined) + [type, [left.ast(input), right.ast(input)]] + end + + def to_s + "#{left} #{operator.to_s.upcase} #{right}" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/check.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/check.rb new file mode 100644 index 00000000..43597825 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/check.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +module Dry + module Logic + module Operations + class Check < Unary + attr_reader :evaluator + + def self.new(rule, **options) + if options[:evaluator] + super + else + keys = options.fetch(:keys) + evaluator = Evaluator::Set.new(keys) + + super(rule, **options, evaluator: evaluator) + end + end + + def initialize(*rules, **options) + super + @evaluator = options[:evaluator] + end + + def type + :check + end + + def call(input) + *head, tail = evaluator[input] + result = rule.curry(*head).(tail) + + if result.success? + Result::SUCCESS + else + Result.new(false, id) { [type, [options[:keys], result.to_ast]] } + end + end + + def [](input) + rule[*evaluator[input].reverse] + end + + def ast(input = Undefined) + [type, [options[:keys], rule.ast(input)]] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/each.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/each.rb new file mode 100644 index 00000000..23374dff --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/each.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module Dry + module Logic + module Operations + class Each < Unary + def type + :each + end + + def call(input) + results = input.map { |element| rule.(element) } + success = results.all?(&:success?) + + Result.new(success, id) do + failures = results + .map + .with_index { |result, idx| [:key, [idx, result.ast(input[idx])]] if result.failure? } + .compact + + [:set, failures] + end + end + + def [](arr) + arr.all? { |input| rule[input] } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/implication.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/implication.rb new file mode 100644 index 00000000..7e6804ba --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/implication.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module Dry + module Logic + module Operations + class Implication < Binary + def type + :implication + end + + def operator + :then + end + + def call(input) + left_result = left.(input) + + if left_result.success? + right_result = right.(input) + Result.new(right_result.success?, id) { right_result.to_ast } + else + Result::SUCCESS + end + end + + def [](input) + if left[input] + right[input] + else + true + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/key.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/key.rb new file mode 100644 index 00000000..1be7d243 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/key.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +module Dry + module Logic + module Operations + class Key < Unary + attr_reader :evaluator + + attr_reader :path + + def self.new(rules, **options) + if options[:evaluator] + super + else + name = options.fetch(:name) + eval = options.fetch(:evaluator, evaluator(name)) + super(rules, **options, evaluator: eval, path: name) + end + end + + def self.evaluator(name) + Evaluator::Key.new(name) + end + + def initialize(*rules, **options) + super + @evaluator = options[:evaluator] + @path = options[:path] + end + + def type + :key + end + + def call(hash) + input = evaluator[hash] + result = rule.(input) + + if result.success? + Result::SUCCESS + else + Result.new(false, path) { [type, [path, result.to_ast]] } + end + end + + def [](hash) + rule[evaluator[hash]] + end + + def ast(input = Undefined) + if input.equal?(Undefined) || !input.is_a?(Hash) + [type, [path, rule.ast]] + else + [type, [path, rule.ast(evaluator[input])]] + end + end + + def to_s + "#{type}[#{path}](#{rule})" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/negation.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/negation.rb new file mode 100644 index 00000000..b2e8112f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/negation.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Dry + module Logic + module Operations + class Negation < Unary + def type + :not + end + + def call(input) + Result.new(rule.(input).failure?, id) { ast(input) } + end + + def [](input) + !rule[input] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/or.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/or.rb new file mode 100644 index 00000000..a1f21737 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/or.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module Dry + module Logic + module Operations + class Or < Binary + def type + :or + end + alias_method :operator, :type + + def call(input) + left_result = left.(input) + + if left_result.success? + Result::SUCCESS + else + right_result = right.(input) + + if right_result.success? + Result::SUCCESS + else + Result.new(false, id) { [:or, [left_result.to_ast, right_result.to_ast]] } + end + end + end + + def [](input) + left[input] || right[input] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/set.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/set.rb new file mode 100644 index 00000000..5e7e2ffa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/set.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module Dry + module Logic + module Operations + class Set < Abstract + def type + :set + end + + def call(input) + results = rules.map { |rule| rule.(input) } + success = results.all?(&:success?) + + Result.new(success, id) do + [type, results.select(&:failure?).map(&:to_ast)] + end + end + + def [](input) + rules.map { |rule| rule[input] }.all? + end + + def ast(input = Undefined) + [type, rules.map { |rule| rule.ast(input) }] + end + + def to_s + "#{type}(#{rules.map(&:to_s).join(", ")})" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/unary.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/unary.rb new file mode 100644 index 00000000..322a0ad5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/unary.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Dry + module Logic + module Operations + class Unary < Abstract + attr_reader :rule + + def initialize(*rules, **options) + super + @rule = rules.first + end + + def ast(input = Undefined) + [type, rule.ast(input)] + end + + def to_s + "#{type}(#{rule})" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/xor.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/xor.rb new file mode 100644 index 00000000..410ce4a5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operations/xor.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module Dry + module Logic + module Operations + class Xor < Binary + def type + :xor + end + alias_method :operator, :type + + def call(input) + Result.new(self[input], id) { ast(input) } + end + + def [](input) + left[input] ^ right[input] + end + + def ast(input = Undefined) + [type, rules.map { |rule| rule.ast(input) }] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operators.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operators.rb new file mode 100644 index 00000000..e1f86151 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/operators.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Dry + module Logic + module Operators + def and(other) + Operations::And.new(self, other) + end + alias_method :&, :and + + def or(other) + Operations::Or.new(self, other) + end + alias_method :|, :or + + def xor(other) + Operations::Xor.new(self, other) + end + alias_method :^, :xor + + def then(other) + Operations::Implication.new(self, other) + end + alias_method :>, :then + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/predicates.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/predicates.rb new file mode 100644 index 00000000..e75907f6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/predicates.rb @@ -0,0 +1,233 @@ +# frozen_string_literal: true + +require "dry/core/constants" + +require "bigdecimal" +require "bigdecimal/util" +require "date" +require "uri" + +module Dry + module Logic + module Predicates + include ::Dry::Core::Constants + + # rubocop:disable Metrics/ModuleLength + module Methods + def self.uuid_format(version) + ::Regexp.new(<<~FORMAT.chomp, ::Regexp::IGNORECASE) + \\A[0-9A-F]{8}-[0-9A-F]{4}-#{version}[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}\\z + FORMAT + end + + UUIDv1 = uuid_format(1) + + UUIDv2 = uuid_format(2) + + UUIDv3 = uuid_format(3) + + UUIDv4 = uuid_format(4) + + UUIDv5 = uuid_format(5) + + UUIDv6 = uuid_format(6) + + UUIDv7 = uuid_format(7) + + UUIDv8 = uuid_format(8) + + def [](name) + method(name) + end + + def type?(type, input) = input.is_a?(type) + + def nil?(input) = input.nil? + alias_method :none?, :nil? + + def key?(name, input) = input.key?(name) + + def attr?(name, input) = input.respond_to?(name) + + def empty?(input) + case input + when ::String, ::Array, ::Hash then input.empty? + when nil then true + else + false + end + end + + def filled?(input) = !empty?(input) + + def bool?(input) = input.equal?(true) || input.equal?(false) + + def date?(input) = input.is_a?(::Date) + + def date_time?(input) = input.is_a?(::DateTime) + + def time?(input) = input.is_a?(::Time) + + def number?(input) + true if Float(input) + rescue ::ArgumentError, ::TypeError + false + end + + def int?(input) = input.is_a?(::Integer) + + def float?(input) = input.is_a?(::Float) + + def decimal?(input) = input.is_a?(::BigDecimal) + + def str?(input) = input.is_a?(::String) + + def hash?(input) = input.is_a?(::Hash) + + def array?(input) = input.is_a?(::Array) + + def odd?(input) = input.odd? + + def even?(input) = input.even? + + def lt?(num, input) = input < num + + def gt?(num, input) = input > num + + def lteq?(num, input) = !gt?(num, input) + + def gteq?(num, input) = !lt?(num, input) + + def size?(size, input) + case size + when ::Integer then size.equal?(input.size) + when ::Range, ::Array then size.include?(input.size) + else + raise ::ArgumentError, "+#{size}+ is not supported type for size? predicate." + end + end + + def min_size?(num, input) = input.size >= num + + def max_size?(num, input) = input.size <= num + + def bytesize?(size, input) + case size + when ::Integer then size.equal?(input.bytesize) + when ::Range, ::Array then size.include?(input.bytesize) + else + raise ::ArgumentError, "+#{size}+ is not supported type for bytesize? predicate." + end + end + + def min_bytesize?(num, input) = input.bytesize >= num + + def max_bytesize?(num, input) = input.bytesize <= num + + def inclusion?(list, input) + deprecated(:inclusion?, :included_in?) + included_in?(list, input) + end + + def exclusion?(list, input) + deprecated(:exclusion?, :excluded_from?) + excluded_from?(list, input) + end + + def included_in?(list, input) = list.include?(input) + + def excluded_from?(list, input) = !list.include?(input) + + def includes?(value, input) + if input.respond_to?(:include?) + input.include?(value) + else + false + end + rescue ::TypeError + false + end + + def excludes?(value, input) = !includes?(value, input) + + # This overrides Object#eql? so we need to make it compatible + def eql?(left, right = Undefined) + return super(left) if right.equal?(Undefined) + + left.eql?(right) + end + + def is?(left, right) = left.equal?(right) + + def not_eql?(left, right) = !left.eql?(right) + + def true?(value) = value.equal?(true) + + def false?(value) = value.equal?(false) + + def format?(regex, input) = !input.nil? && regex.match?(input) + + def case?(pattern, input) = pattern === input # rubocop:disable Style/CaseEquality + + def uuid_v1?(input) = format?(UUIDv1, input) + + def uuid_v2?(input) = format?(UUIDv2, input) + + def uuid_v3?(input) = format?(UUIDv3, input) + + def uuid_v4?(input) = format?(UUIDv4, input) + + def uuid_v5?(input) = format?(UUIDv5, input) + + def uuid_v6?(input) = format?(UUIDv6, input) + + def uuid_v7?(input) = format?(UUIDv7, input) + + def uuid_v8?(input) = format?(UUIDv8, input) + + if defined?(::URI::RFC2396_PARSER) + def uri?(schemes, input) + uri_format = ::URI::RFC2396_PARSER.make_regexp(schemes) + format?(uri_format, input) + end + else + def uri?(schemes, input) + uri_format = ::URI::DEFAULT_PARSER.make_regexp(schemes) + format?(uri_format, input) + end + end + + def uri_rfc3986?(input) = format?(::URI::RFC3986_Parser::RFC3986_URI, input) + + # This overrides Object#respond_to? so we need to make it compatible + def respond_to?(method, input = Undefined) + return super if input.equal?(Undefined) + + input.respond_to?(method) + end + + def predicate(name, &) + define_singleton_method(name, &) + end + + def deprecated(name, in_favor_of) + Core::Deprecations.warn( + "#{name} predicate is deprecated and will " \ + "be removed in the next major version\n" \ + "Please use #{in_favor_of} predicate instead", + tag: "dry-logic", + uplevel: 3 + ) + end + end + + extend Methods + + def self.included(other) + super + other.extend(Methods) + end + end + # rubocop:enable Metrics/ModuleLength + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/result.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/result.rb new file mode 100644 index 00000000..f5633870 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/result.rb @@ -0,0 +1,96 @@ +# frozen_string_literal: true + +module Dry + module Logic + class Result + SUCCESS = ::Class.new { + def success? + true + end + + def failure? + false + end + }.new.freeze + + attr_reader :success + + attr_reader :id + + attr_reader :serializer + + def initialize(success, id = nil, &block) + @success = success + @id = id + @serializer = block + end + + def success? + success + end + + def failure? + !success? + end + + def type + success? ? :success : :failure + end + + def ast(input = Undefined) + serializer.(input) + end + + def to_ast + if id + [type, [id, ast]] + else + ast + end + end + + def to_s + visit(to_ast) + end + + private + + def visit(ast) + __send__(:"visit_#{ast[0]}", ast[1]) + end + + def visit_predicate(node) + name, args = node + + if args.empty? + name.to_s + else + "#{name}(#{args.map(&:last).map(&:inspect).join(", ")})" + end + end + + def visit_and(node) + left, right = node + "#{visit(left)} AND #{visit(right)}" + end + + def visit_or(node) + left, right = node + "#{visit(left)} OR #{visit(right)}" + end + + def visit_xor(node) + left, right = node + "#{visit(left)} XOR #{visit(right)}" + end + + def visit_not(node) + "not(#{visit(node)})" + end + + def visit_hint(node) + visit(node) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/rule.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/rule.rb new file mode 100644 index 00000000..5e7ffd12 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/rule.rb @@ -0,0 +1,98 @@ +# frozen_string_literal: true + +require "concurrent/map" + +module Dry + module Logic + def self.Rule(*args, **options, &block) + if args.any? + Rule.build(*args, **options) + elsif block + Rule.build(block, **options) + end + end + + class Rule + include Core::Constants + include ::Dry::Equalizer(:predicate, :options) + include Operators + + attr_reader :predicate + + attr_reader :options + + attr_reader :args + + attr_reader :arity + + def self.interfaces + @interfaces ||= ::Concurrent::Map.new + end + + def self.specialize(arity, curried, base = Rule) + base.interfaces.fetch_or_store([arity, curried]) do + interface = Interface.new(arity, curried) + klass = ::Class.new(base) { include interface } + base.const_set("#{base.name.split("::").last}#{interface.name}", klass) + klass + end + end + + def self.build(predicate, args: EMPTY_ARRAY, arity: predicate.arity, **options) + specialize(arity, args.size).new(predicate, {args: args, arity: arity, **options}) + end + + def initialize(predicate, options = EMPTY_HASH) + @predicate = predicate + @options = options + @args = options[:args] || EMPTY_ARRAY + @arity = options[:arity] || predicate.arity + end + + def type + :rule + end + + def id + options[:id] + end + + def curry(*new_args) + with(args: args + new_args) + end + + def bind(object) + if predicate.respond_to?(:bind) + self.class.build(predicate.bind(object), **options) + else + self.class.build( + -> *args { object.instance_exec(*args, &predicate) }, + **options, arity: arity, parameters: parameters + ) + end + end + + def eval_args(object) + with(args: args.map { |arg| arg.is_a?(UnboundMethod) ? arg.bind(object).() : arg }) + end + + def with(new_opts) + self.class.build(predicate, **options, **new_opts) + end + + def parameters + options[:parameters] || predicate.parameters + end + + def ast(input = Undefined) + [:predicate, [id, args_with_names(input)]] + end + + private + + def args_with_names(*input) + parameters.map(&:last).zip(args + input) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/rule/interface.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/rule/interface.rb new file mode 100644 index 00000000..4560e4ea --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/rule/interface.rb @@ -0,0 +1,137 @@ +# frozen_string_literal: true + +module Dry + module Logic + class Rule + class Interface < ::Module + SPLAT = ["*rest"].freeze + + attr_reader :arity + + attr_reader :curried + + def initialize(arity, curried) + super() + + @arity = arity + @curried = curried + + if !variable_arity? && curried > arity + raise ArgumentError, "wrong number of arguments (#{curried} for #{arity})" + end + + define_constructor if curried? + + if constant? + define_constant_application + else + define_application + end + end + + def constant? = arity.zero? + + def variable_arity? = arity.negative? + + def curried? = !curried.zero? + + def unapplied + if variable_arity? + unapplied = arity.abs - 1 - curried + + if unapplied.negative? + 0 + else + unapplied + end + else + arity - curried + end + end + + def name + if constant? + "Constant" + else + arity_str = + if variable_arity? + "Variable#{arity.abs - 1}Arity" + else + "#{arity}Arity" + end + + curried_str = + if curried? + "#{curried}Curried" + else + EMPTY_STRING + end + + "#{arity_str}#{curried_str}" + end + end + + def define_constructor + assignment = + if curried.equal?(1) + "@arg0 = @args[0]" + else + "#{curried_args.join(", ")} = @args" + end + + module_eval(<<~RUBY, __FILE__, __LINE__ + 1) + def initialize(*) # def initialize(*) + super # super + # + #{assignment} # @arg0 = @args[0] + end # end + RUBY + end + + def define_constant_application + module_exec do + def call(*) + if @predicate[] + Result::SUCCESS + else + Result.new(false, id) { ast } + end + end + + def [](*) + @predicate[] + end + end + end + + def define_application + splat = variable_arity? ? SPLAT : EMPTY_ARRAY + parameters = (unapplied_args + splat).join(", ") + application = "@predicate[#{(curried_args + unapplied_args + splat).join(", ")}]" + + module_eval(<<~RUBY, __FILE__, __LINE__ + 1) + def call(#{parameters}) # def call(input0, input1, *rest) + if #{application} # if @predicate[@arg0, @arg1, input0, input1, *rest] + Result::SUCCESS # ::Dry::Logic::Result::Success + else # else + Result.new(false, id) { ast(#{parameters}) } # ::Dry::Logic::Result.new(false, id) { ast(input0, input1, *rest) } + end # end + end # end + # + def [](#{parameters}) # def [](@arg0, @arg1, input0, input1, *rest) + #{application} # @predicate[@arg0, @arg1, input0, input1, *rest] + end # end + RUBY + end + + def curried_args + @curried_args ||= ::Array.new(curried) { "@arg#{_1}" } + end + + def unapplied_args + @unapplied_args ||= ::Array.new(unapplied) { "input#{_1}" } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/rule/predicate.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/rule/predicate.rb new file mode 100644 index 00000000..fc4a0f1d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/rule/predicate.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module Dry + module Logic + class Rule + class Predicate < Rule + def self.specialize(arity, curried, base = Predicate) + super + end + + def type + :predicate + end + + def name + predicate.name + end + + def to_s + if args.empty? + name.to_s + else + "#{name}(#{args.map(&:inspect).join(", ")})" + end + end + + def ast(input = Undefined) + [type, [name, args_with_names(input)]] + end + alias_method :to_ast, :ast + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/rule_compiler.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/rule_compiler.rb new file mode 100644 index 00000000..250f3f8e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/rule_compiler.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +module Dry + module Logic + class RuleCompiler + attr_reader :predicates + + def initialize(predicates) + @predicates = predicates + end + + def call(ast) + ast.map { |node| visit(node) } + end + + def visit(node) + name, nodes = node + send(:"visit_#{name}", nodes) + end + + def visit_check(node) + keys, predicate = node + Operations::Check.new(visit(predicate), keys: keys) + end + + def visit_not(node) + Operations::Negation.new(visit(node)) + end + + def visit_key(node) + name, predicate = node + Operations::Key.new(visit(predicate), name: name) + end + + def visit_attr(node) + name, predicate = node + Operations::Attr.new(visit(predicate), name: name) + end + + def visit_set(node) + Operations::Set.new(*call(node)) + end + + def visit_each(node) + Operations::Each.new(visit(node)) + end + + def visit_predicate(node) + name, params = node + predicate = Rule::Predicate.build(predicates[name]) + + if params.size > 1 + args = params.map(&:last).reject { |val| val == Undefined } + predicate.curry(*args) + else + predicate + end + end + + def visit_and(node) + left, right = node + visit(left).and(visit(right)) + end + + def visit_or(node) + left, right = node + visit(left).or(visit(right)) + end + + def visit_xor(node) + left, right = node + visit(left).xor(visit(right)) + end + + def visit_implication(node) + left, right = node + visit(left).then(visit(right)) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/version.rb b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/version.rb new file mode 100644 index 00000000..134a2bf3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-logic-1.6.0/lib/dry/logic/version.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module Dry + module Logic + VERSION = "1.6.0" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/CHANGELOG.md b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/CHANGELOG.md new file mode 100644 index 00000000..04dba850 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/CHANGELOG.md @@ -0,0 +1,885 @@ + + +## 1.14.0 2025-01-06 + + +### Added + +- Better support for sets in `excluded_from?` and `included_in?` predicates (via #480) (@flash-gordon) + +### Fixed + +- Fix info extension for maybe macro (via #484) (@flash-gordon + @santiagodoldan) +- Missing message for :uri? predicate (via #477) (@timjnh) +- JSON schema output for `maybe(:array)` (via #463) (@tomgi) + +### Changed + +- Set minimum Ruby version to 3.1 (@flash-gordon) +- `KeyValidator` works faster for large schemas (via #461) (@radarek) + +[Compare v1.13.4...v1.14.0](https://github.com/dry-rb/dry-schema/compare/v1.13.4...v1.14.0) + +## 1.13.4 2024-05-22 + + +### Added + +- Default error message for `:uri?` (issue #476 via #477) (@timjnh) + +### Fixed + +- Fix json-schema type of objects nested under arrays (issue #400 fixed via #462) (@tomgi) + +### Changed + +- i18n backend is no longer eager-loaded (via 85a9e0b) (@adam12) + +[Compare v1.13.3...v1.13.4](https://github.com/dry-rb/dry-schema/compare/v1.13.3...v1.13.4) + +## 1.13.3 2023-08-26 + + +### Fixed + +- Fix struct extension for nested struct definitions (via #466) (@flash-gordon) + + +[Compare v1.13.2...v1.13.3](https://github.com/dry-rb/dry-schema/compare/v1.13.2...v1.13.3) + +## 1.13.2 2023-05-31 + + +### Fixed + +- Fix custom predicates setting (via #460) (@solnic) + + +[Compare v1.13.1...v1.13.2](https://github.com/dry-rb/dry-schema/compare/v1.13.1...v1.13.2) + +## 1.13.1 2023-04-07 + + +### Fixed + +- Support sum types of hashes (issue #446 fixed via #457) (@segiddins) + + +[Compare v1.13.0...v1.13.1](https://github.com/dry-rb/dry-schema/compare/v1.13.0...v1.13.1) + +## 1.13.0 2022-11-24 + + +### Fixed + +- Change required metadata back to true to fix regressions (issue #438 fixed via 439) (@robhanlon22) +- Compatibility with dry-configurable 1.0.1 (@flash-gordon) +- Warnings about using pattern matching on Ruby 2.7 (issue #441 fixed via #442) (@r7kamura) +- Make message cache fully thread-safe (via #440) (@mensfeld) + + +[Compare v1.12.0...v1.13.0](https://github.com/dry-rb/dry-schema/compare/v1.12.0...v1.13.0) + +## 1.12.0 2022-11-04 + + +### Changed + +- This version depends on dry-core 1.0 and dry-configurable 1.0 (@flash-gordon) + +[Compare v1.11.3...v1.12.0](https://github.com/dry-rb/dry-schema/compare/v1.11.3...v1.12.0) + +## 1.11.3 2022-10-21 + + +### Fixed + +- Fixed `array(sum_type)` syntax which was a regression introduced in 1.10.0 (issue #436 fixed via #437) (@solnic) + + +[Compare v1.11.2...v1.11.3](https://github.com/dry-rb/dry-schema/compare/v1.11.2...v1.11.3) + +## 1.11.2 2022-10-16 + + +### Fixed + +- Setting up message backends with custom settings should work as before (see dry-rb/dry-validation#717 fixed via #435) (@solnic) + + +[Compare v1.11.1...v1.11.2](https://github.com/dry-rb/dry-schema/compare/v1.11.1...v1.11.2) + +## 1.11.1 2022-10-15 + + +### Changed + +- Depend on dry-configurable >= 0.16 - this was needed to play nice with Zeitwerk (@solnic) + +[Compare v1.11.0...v1.11.1](https://github.com/dry-rb/dry-schema/compare/v1.11.0...v1.11.1) + +## 1.11.0 2022-10-15 + + +### Changed + +- Use zeitwerk for auto-loading which speeds up requires (via #427) (@flash-gordon + @solnic) + +[Compare v1.10.6...v1.11.0](https://github.com/dry-rb/dry-schema/compare/v1.10.6...v1.11.0) + +## 1.10.6 2022-10-01 + + +### Fixed + +- Fix issues with rule name when top_namespace and namespace passed (issue #304 fixed via #432) (@RudskikhIvan) + + +[Compare v1.10.5...v1.10.6](https://github.com/dry-rb/dry-schema/compare/v1.10.5...v1.10.6) + +## 1.10.5 2022-09-21 + + +### Fixed + +- Key maps no longer include duped keys when using inheritance (issues #428 #372 fixed via #429) (@solnic) +- Key validator and coercer no longer include duped keys when using parent schemas (via #430) (@solnic) + + +[Compare v1.10.4...v1.10.5](https://github.com/dry-rb/dry-schema/compare/v1.10.4...v1.10.5) + +## 1.10.4 2022-09-13 + + +### Fixed + +- Once again reverting zeitwerk related changes that were included in 1.10.3 by an accident :( (@solnic) + + +[Compare v1.10.3...v1.10.4](https://github.com/dry-rb/dry-schema/compare/v1.10.3...v1.10.4) + +## 1.10.3 2022-09-10 + + +### Fixed + +- Addressed regressions causing issues with handling sum types (see #419 and #423 fixed via #425) (@robhanlon22) + + +[Compare v1.10.2...v1.10.3](https://github.com/dry-rb/dry-schema/compare/v1.10.2...v1.10.3) + +## 1.10.2 2022-08-23 + + +### Fixed + +- Fix value coercion for composed schemas (via #421) (@robhanlon22) + + +[Compare v1.10.1...v1.10.2](https://github.com/dry-rb/dry-schema/compare/v1.10.1...v1.10.2) + +## 1.10.1 2022-08-22 + + +### Changed + +- Reverted zeitwerk-related changes that were included in 1.10.0 by an accident (@solnic) + +[Compare v1.10.0...v1.10.1](https://github.com/dry-rb/dry-schema/compare/v1.10.0...v1.10.1) + +## 1.10.0 2022-08-16 + + +### Added + +- Allow nested `filled` and `value` macro usage (via #412) (@robhanlon22) +- Support for more complex scenarios when composing schemas (via #420) (@robhanlon22) + +### Fixed + +- Fix `or` messages for complex schemas (via #413) (@robhanlon22) +- Using `filled` with a constrained constructor type works as expected (via #416) (@robhanlon22) +- Fix types and key maps for composed schemas (via #415) (@robhanlon22) + +### Changed + +- Freeze message hash (fixes #417 via #418) (@solnic) + +[Compare v1.9.3...v1.10.0](https://github.com/dry-rb/dry-schema/compare/v1.9.3...v1.10.0) + +## 1.9.3 2022-06-23 + + +### Added + +- Support `anyOf` composition in JSON schema output (@robhanlon22) + +### Fixed + +- Allow composition of multiple ors (issue #307 fixed via #409) (@robhanlon22) + + +[Compare v1.9.2...v1.9.3](https://github.com/dry-rb/dry-schema/compare/v1.9.2...v1.9.3) + +## 1.9.2 2022-05-28 + + +### Fixed + +- Fix loose JSON schemas for nested hashes (via #401) (@tomdalling) +- Correct spelling error 'mininum' to 'minimum' in json-schema extension (via #404) (@svenanderzen) + +### Changed + +- [performance] YAML message backend allocates less strings (via #399) (@casperisfine) + +[Compare v1.9.1...v1.9.2](https://github.com/dry-rb/dry-schema/compare/v1.9.1...v1.9.2) + +## 1.9.1 2022-02-17 + + +### Fixed + +- Namespaced messages no longer crashes in certain scenarios (see dry-rb/dry-validation#692 fixed via #398) (@krekoten) + + +[Compare v1.9.0...v1.9.1](https://github.com/dry-rb/dry-schema/compare/v1.9.0...v1.9.1) + +## 1.9.0 2022-02-15 + + +### Added + +- [EXPERIMENTAL] `json_schema` extension which allows you to convert a schema into a JSON schema (via #369) (@ianks) + +### Fixed + +- Composing schemas no longer crashes in certain scenarios (issue #342 fixed via #366) (@vsuhachev) +- Fix info extension for typed arrays (issue #394 fixed via #397) (@CandyFet) + + +[Compare v1.8.0...v1.9.0](https://github.com/dry-rb/dry-schema/compare/v1.8.0...v1.9.0) + +## 1.8.0 2021-09-12 + + +### Changed + +- [internal] Upgraded to new `setting` API provided in dry-configurable 0.13.0 (@timriley in #356) + +[Compare v1.7.1...v1.8.0](https://github.com/dry-rb/dry-schema/compare/v1.7.1...v1.8.0) + +## 1.7.1 2021-08-29 + + +### Changed + +- [internal] Use explicit `#to_h` conversion of Dry::Configurable::Config, to ensure compatibility with upcoming dry-configurable 0.13.0 release (via #371) (@timriley) + +[Compare v1.7.0...v1.7.1](https://github.com/dry-rb/dry-schema/compare/v1.7.0...v1.7.1) + +## 1.7.0 2021-06-29 + +This release ships with a bunch of internal refactorings that should improve performance but if you see any unexpected behavior please do report issues. + +### Fixed + +- Handle arrays of hashes where Array constructor coerces non-Hash input (#351 fixed via #354) (@ojab) +- Run outer schema processor steps before inner ones (issue #350 fixed via #361) (@ojab) +- Fix key validator false negatives on empty collections (see #363) (@Drenmi) +- Prevent error message YAML files from being parsed multiple times (issue #352 via #364) (@alassek) +- Using constructor types should work fine now ie `required(:foo).filled(Types::Params::Integer.constructor(&:succ))` (issue #280 fixed via #365) (@solnic) +- Handle non-Hash to Hash transformation in `before(:key_coercer)` (issue #350 fixed via #362) (@ojab) + +### Changed + +- [internal] `Dry::Schema::Path` clean up and performance improvements (via #358) (@ojab) +- [internal] simplify and speed up handling of steps in nested schemas (via #360) (@ojab) + +[Compare v1.6.2...v1.7.0](https://github.com/dry-rb/dry-schema/compare/v1.6.2...v1.7.0) + +## 1.6.2 2021-04-15 + + +### Added + +- A default error message for `respond_to?` predicate (@rindek) + +### Fixed + +- Using `respond_to?` predicate in blocks works now (@rindek) + + +[Compare v1.6.1...v1.6.2](https://github.com/dry-rb/dry-schema/compare/v1.6.1...v1.6.2) + +## 1.6.1 2021-02-02 + + +### Fixed + +- Messages#[] handles meta/no meta cases more gracefully and has better interoperability with the I18n backend. This brings MessageCompiler#visit_unexpected_key up to parity with MessageCompiler#visit_predicate. Uses visit_predicate as basis for visit_unexpected_key. (@robhanlon22) + + +[Compare v1.6.0...v1.6.1](https://github.com/dry-rb/dry-schema/compare/v1.6.0...v1.6.1) + +## 1.6.0 2021-01-21 + + +### Fixed + +- Using sum types with a i18n backend no longer crashes (issue #328 fixes via #331) (@tylerhunt) + +### Changed + +- Inferring predicates from class names is deprecated. It's very unlikely your code depends on it, + however, if it does, you'll get an exception with instructions. (@flash-gordon) + + If you see an exception and don't rely on inferring, just disable it with: + + ```ruby + Dry::Schema::PredicateInferrer::Compiler.infer_predicate_by_class_name false + ``` + + Otherwise, enable it explicitly: + + ```ruby + Dry::Schema::PredicateInferrer::Compiler.infer_predicate_by_class_name true + ``` + + See https://github.com/dry-rb/dry-schema/issues/335 for rationale. + +[Compare v1.5.6...v1.6.0](https://github.com/dry-rb/dry-schema/compare/v1.5.6...v1.6.0) + +## 1.5.6 2020-10-21 + + +### Fixed + +- Fixed stack error which was a regression introduced in 1.5.5 (issue #322 fixed via #323) (@flash-gordon) + + +[Compare v1.5.5...v1.5.6](https://github.com/dry-rb/dry-schema/compare/v1.5.5...v1.5.6) + +## 1.5.5 2020-10-08 + + +### Fixed + +- Key validation works with messages that have meta-data (issue #310 fixed via #313) (@tadeusz-niemiec) +- Using an external schema along with a key specified as a `:hash` works as expected (issue #296 fixed via #315) (@tadeusz-niemiec + @solnic) +- `Result#error?(path)` works correctly when the path points to an array item (issue #317 fixed via #318) (@solnic) + + +[Compare v1.5.4...v1.5.5](https://github.com/dry-rb/dry-schema/compare/v1.5.4...v1.5.5) + +## 1.5.4 + +2020-09-03 + +### Fixed + +- Key validation works correctly with a non-nested maybe hashes (issue #311 fixed via #312) (@svobom57) + + +[Compare v1.5.3...main](https://github.com/dry-rb/dry-schema/compare/v1.5.3...main) + +## 1.5.3 2020-08-21 + + +### Fixed + +- Key validator works correctly with an array with maybe hash as its member (issue #308 fixed via #309) (@tadeusz-niemiec) + +### Changed + +- [info extension] small performance improvement in the set visitor (see #305 for more details) (@esparta) + +[Compare v1.5.2...v1.5.3](https://github.com/dry-rb/dry-schema/compare/v1.5.2...v1.5.3) + +## 1.5.2 2020-06-26 + + +### Fixed + +- `Result#{success?,failure?}` work as expected when there are only key validation failures (issue #297 fixed via #298) (@adamransom) + +### Changed + +- Using `full` option no longer adds a space between the name of a key and the message in case of languages that have no spaces between words (ie Japanese) (issue #161 closed via #292 by @tadeusz-niemiec) + +[Compare v1.5.1...v1.5.2](https://github.com/dry-rb/dry-schema/compare/v1.5.1...v1.5.2) + +## 1.5.1 2020-05-21 + + +### Fixed + +- Negated predicates support the logic operator API now (fixed via #276 by @solnic) +- Fixed circular require warning (issue #279 closed via #282 by @landongrindheim) +- Validating keys against an array with non-hash members no longer crashes (issue #283 fixed via #284 by @beechnut and issue #289 fixed via #288 by @tadeusz-niemiec) + + +[Compare v1.5.0...v1.5.1](https://github.com/dry-rb/dry-schema/compare/v1.5.0...v1.5.1) + +## 1.5.0 2020-03-11 + + +### Added + +- Support for complex sum types ie `value([:integer, array[:integer])` (issue #214) (@solnic) +- You can now set global config via `Dry::Schema.config` (issue #205) (@robhanlon22) +- Default error message for `:uuid_v4?` predicate (isssue #230) (@solnic) +- [experimental] you can compose schemas in the DSL using the standard logic operators (issue #231 closed via #245) (@solnic) +- Hash schema type can now be used with proper keys and predicates inferring. Constructor +and default types are explicitly not supported (@flash-gordon) + ```ruby + UserType = Dry::Types['hash'].schema( + name: 'string', + email: 'string' + ) + + Dry::Schema.define do + require(:user).hash(UserType) + end + ``` +- `:struct` extension which allows using dry-struct classes as source for hash schemas. Note that output will still be presented as plain hashes, returning structs from schemas will require more work, it's planned for next versions (@flash-gordon) +- `:info` extension which adds #info method to your schemas which produces a simple hash providing information about keys and types (issue #36 closed via #262) (@solnic) + +### Fixed + +- `maybe` macro in JSON schemas no longer converts empty strings to `nil`. +This was a bug in dry-types but your code may rely on this behavior. If you still +require this behavior, we recommend using a custom type (see Advanced -> Custom types in the docs) (@flash-gordon) +- YAML message backend no longer crashes when load_paths are empty (@robhanlon22) +- Callbacks can now be inherited from multiple parents (@skryukov) +- Callbacks work with nested schemas (issue #209) (@solnic) +- Custom type is respected when defining nested schemas (issue #174 closed via 263) (@solnic) +- Key map is properly inferred for maybe-hashes (issue #266 fixed via #269) (@solnic) + +### Changed + +- `:i18n` message backend delegates interpolation and caching to `I18n` (issue #211) (@robhanlon22) +- Raise ArgumentError in DSL if parent DSL configs differ (@robhanlon22) +- (internal) `PredicateInferrer` was removed. `Dry::Types::PredicateInferrer` is a drop-in replacement (@flash-gordon) + +[Compare v1.4.3...v1.5.0](https://github.com/dry-rb/dry-schema/compare/v1.4.3...v1.5.0) + +## 1.4.3 2020-01-08 + + +### Added + +- Pattern matching for `Dry::Schema::Result` objects (@flash-gordon) + ```ruby + schema = Dry::Schema::Params { required(:name).filled } + case schema.('name' => 'John') + in name: + name # => 'John' + end + ``` + Try it with monads! +- Shortcut for nested schemas in `value` and `maybe` macros (@waiting-for-dev) + ```ruby + Dry::Schema.Params do + required(:address).value(:hash) do + required(:city).filled + end + end + ``` + +### Fixed + +- Some keyword warnings that slipped into the previous release (@flash-gordon) + + +[Compare v1.4.2...v1.4.3](https://github.com/dry-rb/dry-schema/compare/v1.4.2...v1.4.3) + +## 1.4.2 2019-12-19 + + +### Fixed + +- `I18n` messages backend supports procs as text properly (issue #208) (@robhanlon22) +- `I18n` messages backend supports message meta-data (issue #210) (@robhanlon22) +- Fixed keyword warnings from MRI 2.7.0 (@flash-gordon) +- Array with a member works correctly with `maybe` (issue #206) (@solnic) + + +[Compare v1.4.1...v1.4.2](https://github.com/dry-rb/dry-schema/compare/v1.4.1...v1.4.2) + +## 1.4.1 2019-10-08 + + +### Fixed + +- Child schemas no longer mutate processing steps of their parent classes (@skryukov) + + +[Compare v1.4.0...v1.4.1](https://github.com/dry-rb/dry-schema/compare/v1.4.0...v1.4.1) + +## 1.4.0 2019-10-08 + + +### Added + +- Support for passing multiple parent schemas. They are inherited from left to right (@ianwhite) + + ```ruby + Dry::Schema.define(parent: [parent_a, parent_b, parent_c]) do + ... + end + ``` +- Improved error messages about missing translations (@skryukov) +- [experimental] before/after callbacks for schema steps (@skryukov) + + ```ruby + Dry::Schema.Params do + required(:name).value(:string) + optional(:age).value(:integer) + + before(:value_coercer) do |result| + result.to_h.compact + end + end + ``` + +### Fixed + +- Added/fixed support for custom optional types (@flash-gordon) + + +[Compare v1.3.4...v1.4.0](https://github.com/dry-rb/dry-schema/compare/v1.3.4...v1.4.0) + +## 1.3.4 2019-09-11 + + +### Fixed + +- Fixed regression where using `array?` predicate within a block would crach (issue #186) (@skryukov) + + +[Compare v1.3.3...v1.3.4](https://github.com/dry-rb/dry-schema/compare/v1.3.3...v1.3.4) + +## 1.3.3 2019-08-14 + + +### Fixed + +- Reject attempts to build a nested schema for array types built on `Dry::Types::Nominal` (fixed #171) (@flash-gordon) +- Current `I18n.locale` is now properly handled when caching message templates (@flash-gordon) +- Default processor uses strict types by default, which fixes various cases when `maybe` is used with a constructor type (@flash-gordon) +- Namespaced messages no longer causes a crash when used with nested schemas (fixed #176) (@solnic) + + +[Compare v1.3.2...v1.3.3](https://github.com/dry-rb/dry-schema/compare/v1.3.2...v1.3.3) + +## 1.3.2 2019-08-01 + + +### Added + +- Support for new predicates: `bytesize?`, `min_bytesize?` and `max_bytesize?` (@bmalinconico) + + +[Compare v1.3.1...v1.3.2](https://github.com/dry-rb/dry-schema/compare/v1.3.1...v1.3.2) + +## 1.3.1 2019-07-08 + + +### Fixed + +- `Result#error?` works correctly with nested hashes and arrays (@solnic) +- `:hints` extension no longer causes a crash where base messages are generated too (issue #165) (@solnic) + + +[Compare v1.3.0...v1.3.1](https://github.com/dry-rb/dry-schema/compare/v1.3.0...v1.3.1) + +## 1.3.0 2019-07-06 + + +### Added + +- Automatic predicate inferring for constrained types! (@flash-gordon) + + ```ruby + Types::Name = Types::String.constrained(min_size: 1) + + schema = Dry::Schema.define do + required(:name).value(Types::Name) + end + + schema.(name: '').errors.to_h # => { name: ["size cannot be less than 1"] } + ``` +- Support for redefining re-used schemas (issue #43) (@skryukov) + +### Fixed + +- Type container is passed down to nested schemas (@flash-gordon) + + +[Compare v1.2.0...v1.3.0](https://github.com/dry-rb/dry-schema/compare/v1.2.0...v1.3.0) + +## 1.2.0 2019-06-13 + + +### Added + +- Ability to configure your own type container (@Morozzzko) + + ```ruby + types = Dry::Schema::TypeContainer.new + types.register( + 'params.trimmed_string', + Types::String.constructor(&:strip).constructor(&:downcase) + ) + + Dry::Schema.Params do + config.types = types + + require(:name).value(:trimmed_string) + end + ``` + +### Fixed + +- `filled` macro no longer generates incorrect messages for arrays (issue #151) (@solnic) +- `filled` macro works correctly with constructor types (@solnic) +- `filled` works correctly with nested schemas (#149) (@solnic + @timriley) +- Custom array constructors are no longer discredited by `array` macro (@solnic) +- `BigDecimal` type is correctly handled by predicate inference (@solnic) +- Works with latest `dry-logic` which provides the new `respond_to?` predicate (#153) (@flash-gordon) + +### Changed + +- Fixes related to `filled` restored pre-1.1.0 behavior of `:hints` which are again included (@solnic) +- `filled` no longer uses filter rules to handle empty strings in `Params` (@solnic) + +[Compare v1.1.0...v1.2.0](https://github.com/dry-rb/dry-schema/compare/v1.1.0...v1.2.0) + +## 1.1.0 2019-05-30 + + +### Added + +- `config.messages.default_locale` for setting...default locale (surprise, surprise) (@solnic) +- `Config` exposes `predicates` setting too (@solnic) + +### Fixed + +- `filled` macro behavior results in `must be filled` error messages when appropriate - see PR #141 for more information (issue #134) (@solnic) +- Filter rules no longer cause keys to be added to input (issue #142) (@solnic) +- Filter rules work now with inheritance (@solnic) +- Inherited type schemas used by coercion are now properly configured as `lax` type (@solnic) +- `Config` is now finalized before instantiating schemas and properly dupped when its inherited (@flash-gordon + @solnic) +- `Config#eql?` works as expected (@solnic) +- Predicates are properly inferred from array with a member type spec, ie `array[:integer]` results in `array? + each(:integer?)` (issue #140) (@solnic) + + +[Compare v1.0.3...v1.1.0](https://github.com/dry-rb/dry-schema/compare/v1.0.3...v1.1.0) + +## 1.0.3 2019-05-21 + + +### Fixed + +- `Object#hash` is no longer used to calculate cache keys due to a potential risk of having hash collisions (@solnic) +- Predicate arguments are used again for template cache keys (@solnic) +- `I18n` messages backend no longer evaluates templates twice (@solnic) + + +[Compare v1.0.2...v1.0.3](https://github.com/dry-rb/dry-schema/compare/v1.0.2...v1.0.3) + +## 1.0.2 2019-05-12 + + +### Fixed + +- Caching message templates uses restricted set of known keys to calculate cache keys (issue #132) (@solnic) + + +[Compare v1.0.1...v1.0.2](https://github.com/dry-rb/dry-schema/compare/v1.0.1...v1.0.2) + +## 1.0.1 2019-05-08 + + +### Fixed + +- Applying `key?` predicate no longer causes recursive calls to `Result#errors` (issue #130) (@solnic) + + +[Compare v1.0.0...v1.0.1](https://github.com/dry-rb/dry-schema/compare/v1.0.0...v1.0.1) + +## 1.0.0 2019-05-03 + + +### Fixed + +- Setting `:any` as the type spec no longer crashes (@solnic) +- `Result#error?` handles paths to array elements correctly (@solnic) + +### Changed + +- [BREAKING] `Result#to_hash` was removed (@solnic) + +[Compare v0.6.0...v1.0.0](https://github.com/dry-rb/dry-schema/compare/v0.6.0...v1.0.0) + +## 0.6.0 2019-04-24 + + +### Changed + +- Dependency on `dry-types` was bumped to `~> 1.0` (@solnic) +- Dependency on `dry-logic` was bumped to `~> 1.0` (@solnic) +- Dependency on `dry-initializer` was bumped to `~> 3.0` (@solnic) + +[Compare v0.5.1...v0.6.0](https://github.com/dry-rb/dry-schema/compare/v0.5.1...v0.6.0) + +## 0.5.1 2019-04-17 + + +### Fixed + +- Key map no longer crashes on unexpected input (issue #118) (@solnic) + + +[Compare v0.5.0...v0.5.1](https://github.com/dry-rb/dry-schema/compare/v0.5.0...v0.5.1) + +## 0.5.0 2019-04-04 + + +### Added + +- Support for arbitrary meta-data in messages, ie: + + ```yaml + en: + dry_schema: + errors: + filled?: + text: "cannot be blank" + code: 123 + ``` + + Now your error hash will include `{ foo: [{ text: 'cannot be blank', code: 123 }] }` (@solnic + @flash-gordon) +- Support for type specs in `array` macro, ie `required(:tags).array(:integer)` (@solnic) +- Support for type specs in `each` macro, ie `required(:tags).each(:integer)` (@solnic) +- Shortcut for defining an array with hash as its member, ie: + + ```ruby + Dry::Schema.Params do + required(:tags).array(:hash) do + required(:name).filled(:string) + end + end + ``` + +### Fixed + +- Inferring predicates doesn't crash when `Any` type is used (@flash-gordon) +- Inferring type specs when type is already set works correctly (@solnic) + +### Changed + +- [BREAKING] `:monads` extension wraps entire result objects in `Success` or `Failure` (@flash-gordon) +- When `:hints` are disabled, result AST will not include hint nodes (@solnic) + +[Compare v0.4.0...v0.5.0](https://github.com/dry-rb/dry-schema/compare/v0.4.0...v0.5.0) + +## 0.4.0 2019-03-26 + + +### Added + +- Schemas are now compatible with procs via `#to_proc` (issue #53) (@solnic) +- Support for configuring `top_namespace` for localized messages (@solnic) +- Support for configuring more than one load path for localized messages (@solnic) +- Support for inferring predicates from arbitrary types (issue #101) (@solnic) + +### Fixed + +- Handling of messages for `optional` keys without value rules works correctly (issue #87) (@solnic) +- Message structure for `optional` keys with an array of hashes no longer duplicates keys (issue #89) (@solnic) +- Inferring `:date_time?` predicate works correctly with `DateTime` types (issue #97) (@solnic) + +### Changed + +- [BREAKING] Updated to work with `dry-types 0.15.0` (@flash-gordon) +- [BREAKING] `Result#{errors,messages,hints}` returns `MessageSet` object now which is an enumerable coercible to a hash (@solnic) +- [BREAKING] `Messages` backend classes no longer use global configuration (@solnic) +- [BREAKING] Passing a non-symbol key name in the DSL will raise `ArgumentError` (issue #29) (@solnic) +- [BREAKING] Configuration for message backends is now nested under `messages` key with following settings: + - `messages.backend` - previously `messages` + - `messages.load_paths` - previously `messages_path` + - `messages.namespace` - previously `namespace` + - `messages.top_namespace` - **new setting** see above +- [BREAKING] `Messages::I18n` uses `I18.store_translations` instead of messing with `I18n.load_path` (@solnic) +- Schemas (`Params` and `JSON`) have nicer inspect (@solnic) + +[Compare v0.3.0...v0.4.0](https://github.com/dry-rb/dry-schema/compare/v0.3.0...v0.4.0) + +## 0.3.0 2018-03-04 + + +### Fixed + +- Configuration is properly inherited from a parent schema (@skryukov) +- `Result#error?` returns `true` when a preceding key has errors (@solnic) +- Predicate inferrer no longer chokes on sum, constructor and enum types (@solnic) +- Predicate inferrer infers `:bool?` from boolean types (@solnic) +- Block-based definitions using `array` works correctly (@solnic) +- Using a disjunction with `array` and `hash` produces correct errors when element validation for array failed (@solnic) + +### Changed + +- Required ruby version was removed from gemspec for people who are stuck on MRI 2.3.x (@solnic) + +[Compare v0.2.0...v0.3.0](https://github.com/dry-rb/dry-schema/compare/v0.2.0...v0.3.0) + +## 0.2.0 2019-02-26 + + +### Added + +- New `hash` macro which prepends `hash?` type-check and allows nested schema definition (@solnic) +- New `array` macro which works like `each` but prepends `array?` type-check (@solnic) + +### Fixed + +- Rule name translation works correctly with I18n (issue #52) (@solnic) +- Rule name translation works correctly with namespaced messages (both I18n and plain YAML) (issue #57) (@solnic) +- Error messages under namespaces are correctly resolved for overridden names (issue #53) (@solnic) +- Namespaced error messages work correctly when schemas are reused within other schemas (issue #49) (@solnic) +- Child schema can override inherited rules now (issue #66) (@skryukov) +- Hints are correctly generated for disjunction that use type-check predicates (issue #24) (@solnic) +- Hints are correctly generated for nested schemas (issue #26) (@solnic) +- `filled` macro respects inferred type-check predicates and puts them in front (@solnic) +- Value coercion works correctly with re-usable nested schemas (issue #25) (@solnic) + +### Changed + +- [BREAKING] **Messages are now configured under `dry_schema` namespace by default** (issue #38) (@solnic) +- [BREAKING] Hints are now an optional feature provided by `:hints` extension, to load it do `Dry::Schema.load_extensions(:hints)` (@solnic) +- [BREAKING] Hints generation was improved in general, output of `Result#messages` and `Result#hints` changed in some cases (@solnic) +- [BREAKING] `schema` macro no longer prepends `hash?` check, for this behavior use the new `hash` macro (see #31) (@solnic) +- [BREAKING] Support for MRI < 2.4 was dropped (@solnic) + +[Compare v0.1.1...v0.2.0](https://github.com/dry-rb/dry-schema/compare/v0.1.1...v0.2.0) + +## 0.1.1 2019-02-17 + + +### Added + +- `Result#error?` supports checking nested errors too ie`result.error?('user.address')` (@solnic) + +### Fixed + +- Fix issues with templates and invalid tokens (issue #27) (@solnic) +- Fix Ruby warnings (@flash-gordon) + + +[Compare v0.1.0...v0.1.1](https://github.com/dry-rb/dry-schema/compare/v0.1.0...v0.1.1) + +## 0.1.0 2019-01-30 + +Initial release. diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/LICENSE b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/LICENSE new file mode 100644 index 00000000..9f9f214d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2015-2023 dry-rb team + +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 AUTHORS OR +COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/README.md b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/README.md new file mode 100644 index 00000000..1939b1a3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/README.md @@ -0,0 +1,22 @@ + +[gem]: https://rubygems.org/gems/dry-schema +[actions]: https://github.com/dry-rb/dry-schema/actions + +# dry-schema [![Gem Version](https://badge.fury.io/rb/dry-schema.svg)][gem] [![CI Status](https://github.com/dry-rb/dry-schema/workflows/CI/badge.svg)][actions] + +## Links + +* [User documentation](https://dry-rb.org/gems/dry-schema) +* [API documentation](http://rubydoc.info/gems/dry-schema) +* [Forum](https://discourse.dry-rb.org) + +## Supported Ruby versions + +This library officially supports the following Ruby versions: + +* MRI `>= 3.1` +* jruby `>= 9.4` (not tested on CI) + +## License + +See `LICENSE` file. diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/config/errors.yml b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/config/errors.yml new file mode 100644 index 00000000..92825418 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/config/errors.yml @@ -0,0 +1,121 @@ +en: + dry_schema: + or: "or" + + errors: + unexpected_key: "is not allowed" + + array?: "must be an array" + + empty?: "must be empty" + + excludes?: "must not include %{value}" + + excluded_from?: + arg: + default: "must not be one of: %{list}" + range: "must not be one of: %{list_left} - %{list_right}" + + exclusion?: "must not be one of: %{list}" + + eql?: "must be equal to %{left}" + + not_eql?: "must not be equal to %{left}" + + filled?: "must be filled" + + format?: "is in invalid format" + + number?: "must be a number" + + odd?: "must be odd" + + even?: "must be even" + + gt?: "must be greater than %{num}" + + gteq?: "must be greater than or equal to %{num}" + + hash?: "must be a hash" + + included_in?: + arg: + default: "must be one of: %{list}" + range: "must be one of: %{list_left} - %{list_right}" + + inclusion?: "must be one of: %{list}" + + includes?: "must include %{value}" + + bool?: "must be boolean" + + true?: "must be true" + + false?: "must be false" + + int?: "must be an integer" + + float?: "must be a float" + + decimal?: "must be a decimal" + + date?: "must be a date" + + date_time?: "must be a date time" + + time?: "must be a time" + + key?: "is missing" + + attr?: "is missing" + + lt?: "must be less than %{num}" + + lteq?: "must be less than or equal to %{num}" + + max_size?: "size cannot be greater than %{num}" + + max_bytesize?: "bytesize cannot be greater than %{num}" + + min_size?: "size cannot be less than %{num}" + + min_bytesize?: "bytesize cannot be less than %{num}" + + nil?: "cannot be defined" + + str?: "must be a string" + + type?: "must be %{type}" + + respond_to?: "must respond to %{method}" + + size?: + arg: + default: "size must be %{size}" + range: "size must be within %{size_left} - %{size_right}" + + value: + string: + arg: + default: "length must be %{size}" + range: "length must be within %{size_left} - %{size_right}" + + bytesize?: + arg: + default: "must be %{size} bytes long" + range: "must be within %{size_left} - %{size_right} bytes long" + + uri?: "is not a valid URI" + + uuid_v1?: "is not a valid UUID" + + uuid_v2?: "is not a valid UUID" + + uuid_v3?: "is not a valid UUID" + + uuid_v4?: "is not a valid UUID" + + uuid_v5?: "is not a valid UUID" + + not: + empty?: "cannot be empty" diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/dry-schema.gemspec b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/dry-schema.gemspec new file mode 100644 index 00000000..c5512558 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/dry-schema.gemspec @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +# this file is synced from dry-rb/template-gem project + +lib = File.expand_path("lib", __dir__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require "dry/schema/version" + +Gem::Specification.new do |spec| + spec.name = "dry-schema" + spec.authors = ["Piotr Solnica"] + spec.email = ["piotr.solnica@gmail.com"] + spec.license = "MIT" + spec.version = Dry::Schema::VERSION.dup + + spec.summary = "Coercion and validation for data structures" + spec.description = <<~TEXT + dry-schema provides a DSL for defining schemas with keys and rules that should be applied to + values. It supports coercion, input sanitization, custom types and localized error messages + (with or without I18n gem). It's also used as the schema engine in dry-validation. + + TEXT + spec.homepage = "https://dry-rb.org/gems/dry-schema" + spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-schema.gemspec", + "lib/**/*", "config/*.yml"] + spec.bindir = "bin" + spec.executables = [] + spec.require_paths = ["lib"] + + spec.metadata["allowed_push_host"] = "https://rubygems.org" + spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-schema/blob/main/CHANGELOG.md" + spec.metadata["source_code_uri"] = "https://github.com/dry-rb/dry-schema" + spec.metadata["bug_tracker_uri"] = "https://github.com/dry-rb/dry-schema/issues" + spec.metadata["rubygems_mfa_required"] = "true" + + spec.required_ruby_version = ">= 3.1" + + # to update dependencies edit project.yml + spec.add_dependency "concurrent-ruby", "~> 1.0" + spec.add_dependency "dry-configurable", "~> 1.0", ">= 1.0.1" + spec.add_dependency "dry-core", "~> 1.1" + spec.add_dependency "dry-initializer", "~> 3.2" + spec.add_dependency "dry-logic", "~> 1.5" + spec.add_dependency "dry-types", "~> 1.8" + spec.add_dependency "zeitwerk", "~> 2.6" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry-schema.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry-schema.rb new file mode 100644 index 00000000..0fe2f736 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry-schema.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +require "dry/schema" diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema.rb new file mode 100644 index 00000000..0b89c673 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema.rb @@ -0,0 +1,114 @@ +# frozen_string_literal: true + +require "zeitwerk" + +require "dry/core" +require "dry/configurable" +require "dry/logic" +require "dry/types" + +module Dry + # Main interface + # + # @api public + module Schema + extend ::Dry::Core::Extensions + + # @api private + def self.loader + @loader ||= ::Zeitwerk::Loader.new.tap do |loader| + root = ::File.expand_path("..", __dir__) + loader.tag = "dry-schema" + loader.inflector = ::Zeitwerk::GemInflector.new("#{root}/dry-schema.rb") + loader.inflector.inflect( + "dsl" => "DSL", + "yaml" => "YAML", + "json" => "JSON", + "i18n" => "I18n" + ) + loader.push_dir(root) + loader.ignore( + "#{root}/dry-schema.rb", + "#{root}/dry/schema/{constants,errors,version,extensions}.rb", + "#{root}/dry/schema/extensions" + ) + loader.do_not_eager_load("#{root}/dry/schema/messages/i18n.rb") + loader.inflector.inflect("dsl" => "DSL") + end + end + + # Configuration + # + # @example + # Dry::Schema.config.messages.backend = :i18n + # + # @return [Config] + # + # @api public + def self.config + @config ||= Config.new + end + + # Define a schema + # + # @example + # Dry::Schema.define do + # required(:name).filled(:string) + # required(:age).value(:integer, gt?: 0) + # end + # + # @param [Hash] options + # + # @return [Processor] + # + # @see DSL.new + # + # @api public + def self.define(...) + DSL.new(...).call + end + + # Define a schema suitable for HTTP params + # + # This schema type uses `Types::Params` for coercion by default + # + # @example + # Dry::Schema.Params do + # required(:name).filled(:string) + # required(:age).value(:integer, gt?: 0) + # end + # + # @return [Params] + # + # @see Schema#define + # + # @api public + def self.Params(**options, &) + define(**options, processor_type: Params, &) + end + singleton_class.alias_method(:Form, :Params) + + # Define a schema suitable for JSON data + # + # This schema type uses `Types::JSON` for coercion by default + # + # @example + # Dry::Schema.JSON do + # required(:name).filled(:string) + # required(:age).value(:integer, gt?: 0) + # end + # + # @return [Params] + # + # @see Schema#define + # + # @api public + def self.JSON(**options, &) + define(**options, processor_type: JSON, &) + end + + loader.setup + end +end + +require "dry/schema/extensions" diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/compiler.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/compiler.rb new file mode 100644 index 00000000..350fa721 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/compiler.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module Dry + module Schema + # Extended rule compiler used internally by the DSL + # + # @api private + class Compiler < Logic::RuleCompiler + # Builds a default compiler instance with custom predicate registry + # + # @return [Compiler] + # + # @api private + def self.new(predicates = PredicateRegistry.new) + super + end + + # @api private + def visit_and(node) + super.with(hints: false) + end + + # Build a special rule that will produce namespaced failures + # + # This is needed for schemas that are namespaced and they are + # used as nested schemas + # + # @param [Array] node + # @param [Hash] _opts Unused + # + # @return [NamespacedRule] + # + # @api private + def visit_namespace(node, _opts = EMPTY_HASH) + namespace, rest = node + NamespacedRule.new(namespace, visit(rest)) + end + + # Return true if a given predicate is supported by this compiler + # + # @param [Symbol] predicate + # + # @return [Boolean] + # + # @api private + def support?(predicate) + predicates.key?(predicate) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/config.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/config.rb new file mode 100644 index 00000000..0cefa569 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/config.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +require "dry/core/equalizer" +require "dry/configurable" +require "dry/schema/constants" + +module Dry + module Schema + # Schema definition configuration class + # + # @see DSL#configure + # + # @api public + class Config + include ::Dry::Configurable + include ::Dry::Equalizer(:to_h, inspect: false) + + # @!method predicates + # + # Return configured predicate registry + # + # @return [Schema::PredicateRegistry] + # + # @api public + setting :predicates, default: PredicateRegistry.new, constructor: -> predicates { + predicates.is_a?(PredicateRegistry) ? predicates : PredicateRegistry.new(predicates) + } + + # @!method types + # + # Return configured container with extra types + # + # @return [Hash] + # + # @api public + setting :types, default: ::Dry::Types + + # @!method messages + # + # Return configuration for message backend + # + # @return [Dry::Configurable::Config] + # + # @api public + setting :messages do + setting :backend, default: :yaml + setting :namespace + setting :load_paths, default: ::Set[DEFAULT_MESSAGES_PATH], constructor: :dup.to_proc + setting :top_namespace, default: DEFAULT_MESSAGES_ROOT + setting :default_locale + end + + # @!method validate_keys + # + # On/off switch for key validator + # + # @return [Boolean] + # + # @api public + setting :validate_keys, default: false + + # @api private + def respond_to_missing?(meth, include_private = false) + super || config.respond_to?(meth, include_private) + end + + # @api private + def inspect + "#<#{self.class} #{to_h.map { |k, v| ["#{k}=", v.inspect] }.map(&:join).join(" ")}>" + end + + private + + # Forward to the underlying config object + # + # @api private + def method_missing(meth, ...) + super unless config.respond_to?(meth) + config.public_send(meth, ...) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/constants.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/constants.rb new file mode 100644 index 00000000..4e80619b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/constants.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require "pathname" +require "dry/core/constants" + +module Dry + # Common constants used across the library + # + # @api public + module Schema + include Core::Constants + + LIST_SEPARATOR = ", " + QUESTION_MARK = "?" + DOT = "." + + # core processor steps in the default execution order + STEPS_IN_ORDER = %i[ + key_validator + key_coercer + filter_schema + value_coercer + rule_applier + ].freeze + + # Path to the default set of localized messages bundled within the gem + DEFAULT_MESSAGES_PATH = Pathname(__dir__).join("../../../config/errors.yml").realpath.freeze + + # Default namespace used for localized messages in YAML files + DEFAULT_MESSAGES_ROOT = "dry_schema" + + # An error raised when DSL is used in an incorrect way + InvalidSchemaError = ::Class.new(::StandardError) + + # An error raised when a localized message cannot be found + MissingMessageError = ::Class.new(::StandardError) do + # @api private + def initialize(path, paths = []) + *rest, rule = path + super(<<~STR) + Message template for #{rule.inspect} under #{rest.join(DOT).inspect} was not found. Searched in: + #{paths.map { |string| "\"#{string}\"" }.join("\n")} + STR + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/dsl.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/dsl.rb new file mode 100644 index 00000000..335eeb3b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/dsl.rb @@ -0,0 +1,517 @@ +# frozen_string_literal: true + +require "dry/initializer" +require "dry/schema/constants" + +module Dry + module Schema + # The schema definition DSL class + # + # The DSL is exposed by: + # - `Schema.define` + # - `Schema.Params` + # - `Schema.JSON` + # - `Schema::Params.define` - use with sub-classes + # - `Schema::JSON.define` - use with sub-classes + # + # @example class-based definition + # class UserSchema < Dry::Schema::Params + # define do + # required(:name).filled + # required(:age).filled(:integer, gt: 18) + # end + # end + # + # user_schema = UserSchema.new + # user_schema.(name: 'Jame', age: 21) + # + # @example instance-based definition shortcut + # UserSchema = Dry::Schema.Params do + # required(:name).filled + # required(:age).filled(:integer, gt: 18) + # end + # + # UserSchema.(name: 'Jame', age: 21) + # + # @api public + class DSL + Types = Schema::Types + + extend ::Dry::Initializer + + # @return [Compiler] The type of the processor (Params, JSON, or a custom sub-class) + option :processor_type, default: -> { Processor } + + # @return [Array] An array with macros defined within the DSL + option :macros, default: -> { EMPTY_ARRAY.dup } + + # @return [Compiler] A key=>type map defined within the DSL + option :types, default: -> { EMPTY_HASH.dup } + + # @return [Array] Optional parent DSL objects, that will be used to merge keys and rules + option :parent, Types::Coercible::Array, default: -> { EMPTY_ARRAY.dup }, as: :parents + + # @return [Config] Configuration object exposed via `#configure` method + option :config, optional: true, default: proc { default_config } + + # @return [ProcessorSteps] Steps for the processor + option :steps, default: proc { ProcessorSteps.new } + + # @return [Path, Array] Path under which the schema is defined + option :path, -> *args { Path[*args] if args.any? }, default: proc { EMPTY_ARRAY } + + # Build a new DSL object and evaluate provided block + # + # @param [Hash] options + # @option options [Class] :processor The processor type + # (`Params`, `JSON` or a custom sub-class) + # @option options [Compiler] :compiler An instance of a rule compiler + # (must be compatible with `Schema::Compiler`) (optional) + # @option options [Array[DSL]] :parent One or more instances of the parent DSL (optional) + # @option options [Config] :config A configuration object (optional) + # + # @see Schema.define + # @see Schema.Params + # @see Schema.JSON + # @see Processor.define + # + # @return [DSL] + # + # @api public + def self.new(**options, &) + dsl = super + dsl.instance_eval(&) if block_given? + dsl.instance_variable_set("@compiler", options[:compiler]) if options[:compiler] + dsl + end + + # Provide customized configuration for your schema + # + # @example + # Dry::Schema.define do + # configure do |config| + # config.messages.backend = :i18n + # end + # end + # + # @see Config + # + # @return [DSL] + # + # @api public + def configure(&) + config.configure(&) + self + end + + # @api private + def compiler + @compiler ||= Compiler.new(predicates) + end + + # @api private + def predicates + @predicates ||= config.predicates + end + + # Return a macro with the provided name + # + # @param [Symbol] name + # + # @return [Macros::Core] + # + # @api public + def [](name) + macros.detect { |macro| macro.name.equal?(name) } + end + + # Define a required key + # + # @example + # required(:name).filled + # + # required(:age).value(:integer) + # + # required(:user_limit).value(:integer, gt?: 0) + # + # required(:tags).filled { array? | str? } + # + # @param [Symbol] name The key name + # + # @return [Macros::Required] + # + # @api public + def required(name, &) + key(name, macro: Macros::Required, &) + end + + # Define an optional key + # + # This works exactly the same as `required` except that if a key is not present + # rules will not be applied + # + # @see DSL#required + # + # @param [Symbol] name The key name + # + # @return [Macros::Optional] + # + # @api public + def optional(name, &) + key(name, macro: Macros::Optional, &) + end + + # A generic method for defining keys + # + # @param [Symbol] name The key name + # @param [Class] macro The macro sub-class (ie `Macros::Required` or + # any other `Macros::Key` subclass) + # + # @return [Macros::Key] + # + # @api public + def key(name, macro:, &) + raise ArgumentError, "Key +#{name}+ is not a symbol" unless name.is_a?(::Symbol) + + set_type(name, Types::Any.meta(default: true)) + + macro = macro.new( + name: name, + compiler: compiler, + schema_dsl: self, + filter_schema_dsl: filter_schema_dsl + ) + + macro.value(&) if block_given? + macros << macro + macro + end + + # Build a processor based on DSL's definitions + # + # @return [Processor, Params, JSON] + # + # @api private + def call + all_steps = parents.map(&:steps) + [steps] + + result_steps = all_steps.inject { |result, steps| result.merge(steps) } + + result_steps[:key_validator] = key_validator if config.validate_keys + result_steps[:key_coercer] = key_coercer + result_steps[:value_coercer] = value_coercer + result_steps[:rule_applier] = rule_applier + result_steps[:filter_schema] = filter_schema.rule_applier if filter_rules? + + processor_type.new(schema_dsl: self, steps: result_steps) + end + + # Merge with another dsl + # + # @return [DSL] + # + # @api private + def merge(other) + new( + parent: parents + other.parents, + macros: macros + other.macros, + types: types.merge(other.types), + steps: steps.merge(other.steps) + ) + end + + # Cast this DSL into a rule object + # + # @return [RuleApplier] + def to_rule + call.to_rule + end + + # A shortcut for defining an array type with a member + # + # @example + # required(:tags).filled(array[:string]) + # + # @return [Dry::Types::Array::Member] + # + # @api public + def array + -> member_type { type_registry["array"].of(resolve_type(member_type)) } + end + + # Method allows steps injection to the processor + # + # @example + # before(:rule_applier) do |input| + # input.compact + # end + # + # @return [DSL] + # + # @api public + def before(key, &) + steps.before(key, &) + self + end + + # Method allows steps injection to the processor + # + # @example + # after(:rule_applier) do |input| + # input.compact + # end + # + # @return [DSL] + # + # @api public + def after(key, &) + steps.after(key, &) + self + end + + # The parent (last from parents) which is used for copying non mergeable configuration + # + # @return DSL + # + # @api public + def parent + @parent ||= parents.last + end + + # Return type schema used by the value coercer + # + # @return [Dry::Types::Lax] + # + # @api private + def type_schema + strict_type_schema.lax + end + + # Return type schema used when composing subschemas + # + # @return [Dry::Types::Schema] + # + # @api private + def strict_type_schema + type_registry["hash"].schema(types) + end + + # Return a new DSL instance using the same processor type + # + # @return [Dry::Types::Safe] + # + # @api private + def new(klass: self.class, **options, &) + klass.new(**options, processor_type: processor_type, config: config, &) + end + + # Set a type for the given key name + # + # @param [Symbol] name The key name + # @param [Symbol, Array, Dry::Types::Type] spec The type spec or a type object + # + # @return [Dry::Types::Safe] + # + # @api private + def set_type(name, spec) + type = resolve_type(spec) + meta = {required: false, maybe: type.optional?} + + @types[name] = type.meta(meta) + end + + # Check if a custom type was set under provided key name + # + # @return [Bool] + # + # @api private + def custom_type?(name) + !types[name].meta[:default].equal?(true) + end + + # Resolve type object from the provided spec + # + # @param [Symbol, Array, Dry::Types::Type] spec + # + # @return [Dry::Types::Type] + # + # @api private + def resolve_type(spec) + case spec + when ::Dry::Types::Type then spec + when ::Array then spec.map { |s| resolve_type(s) }.reduce(:|) + else + type_registry[spec] + end + end + + # @api private + def filter_schema + filter_schema_dsl.call + end + + # Build an input schema DSL used by `filter` API + # + # @see Macros::Value#filter + # + # @api private + def filter_schema_dsl + @filter_schema_dsl ||= new(parent: parent_filter_schemas) + end + + # Check if any filter rules were defined + # + # @api private + def filter_rules? + if instance_variable_defined?("@filter_schema_dsl") && !filter_schema_dsl.macros.empty? + return true + end + + parents.any?(&:filter_rules?) + end + + # This DSL's type map merged with any parent type maps + # + # @api private + def types + [*parents.map(&:types), @types].reduce(:merge) + end + + # @api private + def merge_types(op_class, lhs, rhs) + types_merger.(op_class, lhs, rhs) + end + + protected + + # Build a rule applier + # + # @return [RuleApplier] + # + # @api protected + def rule_applier + RuleApplier.new(rules, config: config.finalize!) + end + + # Build rules from defined macros + # + # @see #rule_applier + # + # @api protected + def rules + parent_rules.merge(macros.to_h { [_1.name, _1.to_rule] }.compact) + end + + # Build a key map from defined types + # + # @api protected + def key_map(types = self.types) + keys = types.map { |key, type| key_spec(key, type) } + km = KeyMap.new(keys) + + if key_map_type + km.public_send(key_map_type) + else + km + end + end + + private + + # @api private + def parent_filter_schemas + parents.select(&:filter_rules?).map(&:filter_schema) + end + + # Build a key validator + # + # @return [KeyValidator] + # + # @api private + def key_validator + KeyValidator.new(key_map: key_map) + end + + # Build a key coercer + # + # @return [KeyCoercer] + # + # @api private + def key_coercer + KeyCoercer.symbolized(key_map) + end + + # Build a value coercer + # + # @return [ValueCoercer] + # + # @api private + def value_coercer + ValueCoercer.new(type_schema) + end + + # Return type registry configured by the processor type + # + # @api private + def type_registry + @type_registry ||= TypeRegistry.new( + config.types, + processor_type.config.type_registry_namespace + ) + end + + # Return key map type configured by the processor type + # + # @api private + def key_map_type + processor_type.config.key_map_type + end + + # Build a key spec needed by the key map + # + # TODO: we need a key-map compiler using Types AST + # + # @api private + def key_spec(name, type) + if type.respond_to?(:keys) + {name => key_map(type.name_key_map)} + elsif type.respond_to?(:member) + kv = key_spec(name, type.member) + kv.equal?(name) ? name : kv.flatten(1) + elsif type.meta[:maybe] && type.respond_to?(:right) + key_spec(name, type.right) + elsif type.respond_to?(:type) + key_spec(name, type.type) + else + name + end + end + + # @api private + def parent_rules + parents.reduce({}) { |rules, parent| rules.merge(parent.rules) } + end + + # @api private + def parent_key_map + parents.reduce([]) { |key_map, parent| parent.key_map + key_map } + end + + # @api private + def default_config + parents.each_cons(2) do |left, right| + unless left.config == right.config + raise ::ArgumentError, + "Parent configs differ, left=#{left.inspect}, right=#{right.inspect}" + end + end + + (parent || Schema).config.dup + end + + def types_merger + @types_merger ||= TypesMerger.new(type_registry) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions.rb new file mode 100644 index 00000000..951bf5e8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +Dry::Schema.register_extension(:monads) do + require "dry/schema/extensions/monads" +end + +Dry::Schema.register_extension(:hints) do + require "dry/schema/extensions/hints" +end + +Dry::Schema.register_extension(:struct) do + require "dry/schema/extensions/struct" +end + +Dry::Schema.register_extension(:info) do + require "dry/schema/extensions/info" +end + +Dry::Schema.register_extension(:json_schema) do + require "dry/schema/extensions/json_schema" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/hints.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/hints.rb new file mode 100644 index 00000000..351b75bc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/hints.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +require "dry/schema/extensions/hints/compiler_methods" +require "dry/schema/extensions/hints/message_compiler_methods" +require "dry/schema/extensions/hints/message_set_methods" +require "dry/schema/extensions/hints/result_methods" + +module Dry + module Schema + # Hint-specific Message extensions + # + # @see Message + # + # @api public + class Message + # Hints extension for Or messages + # + # @see Message::Or + # + # @api public + module Or + class SinglePath + # @api private + def hint? + false + end + end + + class MultiPath + # @api private + def hint? + false + end + end + end + + # @api private + def hint? + false + end + end + + # A hint message sub-type + # + # @api private + class Hint < Message + # @api private + def hint? + true + end + end + + # Hints extensions + module Extensions + # @api private + module Hints + end + + Compiler.prepend(Hints::CompilerMethods) + MessageCompiler.prepend(Hints::MessageCompilerMethods) + MessageSet.prepend(Hints::MessageSetMethods) + Result.prepend(Hints::ResultMethods) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/hints/compiler_methods.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/hints/compiler_methods.rb new file mode 100644 index 00000000..cc3f71a0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/hints/compiler_methods.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Dry + module Schema + module Extensions + module Hints + # Tweaks AND visitor to enable :hints + # + # @api private + module CompilerMethods + # @api private + def visit_and(node) + super.with(hints: true) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/hints/message_compiler_methods.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/hints/message_compiler_methods.rb new file mode 100644 index 00000000..e2f6f813 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/hints/message_compiler_methods.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: true + +module Dry + module Schema + module Extensions + module Hints + # Adds support for processing [:hint, ...] nodes produced by dry-logic + # + # @api private + module MessageCompilerMethods + HINT_TYPE_EXCLUSION = %i[ + key? nil? bool? str? int? float? decimal? + date? date_time? time? hash? array? + ].freeze + + HINT_OTHER_EXCLUSION = %i[format? filled?].freeze + + # @api private + attr_reader :hints + + # @api private + def initialize(*, **) + super + @hints = @options.fetch(:hints, true) + end + + # @api private + def hints? + hints.equal?(true) + end + + # @api private + def filter(messages, opts) + Array(messages).flatten.reject { |msg| exclude?(msg, opts) }.uniq + end + + # @api private + # rubocop: disable Metrics/AbcSize + # rubocop: disable Metrics/PerceivedComplexity + # rubocop: disable Metrics/CyclomaticComplexity + def exclude?(messages, opts) + Array(messages).all? do |msg| + hints = opts.hints.reject { |h| + msg.eql?(h) || h.predicate.eql?(:filled?) + } + + key_failure = opts.key_failure?(msg.path) + predicate = msg.predicate + + (HINT_TYPE_EXCLUSION.include?(predicate) && !key_failure) || + (msg.predicate == :filled? && key_failure) || + (!key_failure && HINT_TYPE_EXCLUSION.include?(predicate) && + !hints.empty? && hints.any? { |hint| hint.path == msg.path }) || + HINT_OTHER_EXCLUSION.include?(predicate) + end + end + # rubocop: enable Metrics/CyclomaticComplexity + # rubocop: enable Metrics/PerceivedComplexity + # rubocop: enable Metrics/AbcSize + + # @api private + def message_type(options) + options[:message_type].equal?(:hint) ? Hint : Message + end + + # @api private + def visit_hint(node, opts) + if hints? + filter(visit(node, opts.(message_type: :hint)), opts) + end + end + + # @api private + def visit_predicate(node, opts) + message = super + opts.current_messages << message + message + end + + # @api private + def visit_each(_node, _opts) + # TODO: we can still generate a hint for elements here! + [] + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/hints/message_set_methods.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/hints/message_set_methods.rb new file mode 100644 index 00000000..abc13e44 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/hints/message_set_methods.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +module Dry + module Schema + module Extensions + module Hints + # Hint extensions for MessageSet + # + # @api public + module MessageSetMethods + # Filtered message hints from all messages + # + # @return [Array] + attr_reader :hints + + # Configuration option to enable/disable showing errors + # + # @return [Boolean] + attr_reader :failures + + # @api private + def initialize(messages, options = EMPTY_HASH) + super + @hints = messages.select(&:hint?) + @failures = options.fetch(:failures, true) + end + + # Dump message set to a hash with either all messages or just hints + # + # @see MessageSet#to_h + # @see ResultMethods#hints + # + # @return [HashArray>] + # + # @api public + def to_h + @to_h ||= failures ? messages_map : messages_map(hints) + end + alias_method :to_hash, :to_h + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/hints/result_methods.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/hints/result_methods.rb new file mode 100644 index 00000000..314c7a7b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/hints/result_methods.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +module Dry + module Schema + module Extensions + module Hints + # Get errors exclusively without hints + # + # @api public + module ResultMethods + # Return error messages exclusively + # + # @see Result#errors + # + # @return [MessageSet] + # + # @api public + def errors(options = EMPTY_HASH) + message_set(options.merge(hints: false)) + end + + # Get all messages including hints + # + # @see #message_set + # + # @return [MessageSet] + # + # @api public + def messages(options = EMPTY_HASH) + message_set(options) + end + + # Get hints exclusively without errors + # + # @see #message_set + # + # @return [MessageSet] + # + # @api public + def hints(options = EMPTY_HASH) + message_set(options.merge(failures: false)) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/info.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/info.rb new file mode 100644 index 00000000..fcce2fc0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/info.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require "dry/schema/extensions/info/schema_compiler" + +module Dry + module Schema + # Info extension + # + # @api public + module Info + module SchemaMethods + # Return information about keys and types + # + # @return [HashHash>] + # + # @api public + def info + compiler = SchemaCompiler.new + compiler.call(to_ast) + compiler.to_h + end + end + end + + Processor.include(Info::SchemaMethods) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/info/schema_compiler.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/info/schema_compiler.rb new file mode 100644 index 00000000..f079fcb7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/info/schema_compiler.rb @@ -0,0 +1,123 @@ +# frozen_string_literal: true + +require "dry/schema/constants" + +module Dry + module Schema + # @api private + module Info + # @api private + class SchemaCompiler + PREDICATE_TO_TYPE = { + array?: "array", + bool?: "bool", + date?: "date", + date_time?: "date_time", + decimal?: "float", + float?: "float", + hash?: "hash", + int?: "integer", + nil?: "nil", + str?: "string", + time?: "time" + }.freeze + + # @api private + attr_reader :keys + + # @api private + def initialize + @keys = EMPTY_HASH.dup + end + + # @api private + def to_h + {keys: keys} + end + + # @api private + def call(ast) + visit(ast) + end + + # @api private + def visit(node, opts = EMPTY_HASH) + meth, rest = node + public_send(:"visit_#{meth}", rest, opts) + end + + # @api private + def visit_set(node, opts = EMPTY_HASH) + target = (key = opts[:key]) ? self.class.new : self + + node.each { |child| target.visit(child, opts) } + + return unless key + + target_info = opts[:member] ? {member: target.to_h} : target.to_h + type = opts[:member] ? "array" : "hash" + + keys.update(key => {**keys[key], type: type, **target_info}) + end + + # @api private + def visit_and(node, opts = EMPTY_HASH) + left, right = node + + visit(left, opts) + visit(right, opts) + end + + # @api private + def visit_implication(node, opts = EMPTY_HASH) + case node + in [:not, [:predicate, [:nil?, _]]], el + visit(el, {**opts, nullable: true}) + else + node.each do |el| + visit(el, {**opts, required: false}) + end + end + end + + # @api private + def visit_each(node, opts = EMPTY_HASH) + visit(node, {**opts, member: true}) + end + + # @api private + def visit_key(node, opts = EMPTY_HASH) + name, rest = node + visit(rest, {**opts, key: name, required: true}) + end + + # @api private + def visit_predicate(node, opts = EMPTY_HASH) + name, rest = node + + key = opts[:key] + + if name.equal?(:key?) + keys[rest[0][1]] = { + required: opts.fetch(:required, true) + } + else + type = PREDICATE_TO_TYPE[name] + nullable = opts.fetch(:nullable, false) + assign_type(key, type, nullable) if type + end + end + + # @api private + def assign_type(key, type, nullable) + if keys[key][:type] + keys[key][:member] = type + else + keys[key][:type] = type + keys[key][:nullable] = nullable + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/json_schema.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/json_schema.rb new file mode 100644 index 00000000..637b950d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/json_schema.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require "dry/schema/extensions/json_schema/schema_compiler" + +module Dry + module Schema + # JSONSchema extension + # + # @api public + module JSONSchema + module SchemaMethods + # Convert the schema into a JSON schema hash + # + # @param [Symbol] loose Compile the schema in "loose" mode + # + # @return [HashHash>] + # + # @api public + def json_schema(loose: false) + compiler = SchemaCompiler.new(root: true, loose: loose) + compiler.call(to_ast) + compiler.to_hash + end + end + end + + Processor.include(JSONSchema::SchemaMethods) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/json_schema/schema_compiler.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/json_schema/schema_compiler.rb new file mode 100644 index 00000000..f4383693 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/json_schema/schema_compiler.rb @@ -0,0 +1,244 @@ +# frozen_string_literal: true + +require "dry/schema/constants" + +module Dry + module Schema + # @api private + module JSONSchema + # @api private + class SchemaCompiler + # An error raised when a predicate cannot be converted + UnknownConversionError = ::Class.new(::StandardError) + + IDENTITY = ->(v, _) { v }.freeze + TO_INTEGER = ->(v, _) { v.to_i }.freeze + + PREDICATE_TO_TYPE = { + array?: {type: "array"}, + bool?: {type: "boolean"}, + date?: {type: "string", format: "date"}, + date_time?: {type: "string", format: "date-time"}, + decimal?: {type: "number"}, + float?: {type: "number"}, + hash?: {type: "object"}, + int?: {type: "integer"}, + nil?: {type: "null"}, + str?: {type: "string"}, + time?: {type: "string", format: "time"}, + min_size?: {minLength: TO_INTEGER}, + max_size?: {maxLength: TO_INTEGER}, + included_in?: {enum: ->(v, _) { v.to_a }}, + filled?: EMPTY_HASH, + uri?: {format: "uri"}, + uuid_v1?: { + pattern: "^[0-9A-F]{8}-[0-9A-F]{4}-1[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$" + }, + uuid_v2?: { + pattern: "^[0-9A-F]{8}-[0-9A-F]{4}-2[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$" + }, + uuid_v3?: { + pattern: "^[0-9A-F]{8}-[0-9A-F]{4}-3[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$" + }, + uuid_v4?: { + pattern: "^[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}$" + }, + uuid_v5?: { + pattern: "^[0-9A-F]{8}-[0-9A-F]{4}-5[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$" + }, + gt?: {exclusiveMinimum: IDENTITY}, + gteq?: {minimum: IDENTITY}, + lt?: {exclusiveMaximum: IDENTITY}, + lteq?: {maximum: IDENTITY}, + odd?: {type: "integer", not: {multipleOf: 2}}, + even?: {type: "integer", multipleOf: 2} + }.freeze + + # @api private + attr_reader :keys, :required + + # @api private + def initialize(root: false, loose: false) + @keys = EMPTY_HASH.dup + @required = Set.new + @root = root + @loose = loose + end + + # @api private + def to_hash + result = {} + result[:$schema] = "http://json-schema.org/draft-06/schema#" if root? + result.merge!(type: "object", properties: keys, required: required.to_a) + result + end + + alias_method :to_h, :to_hash + + # @api private + def call(ast) + visit(ast) + end + + # @api private + def visit(node, opts = EMPTY_HASH) + meth, rest = node + public_send(:"visit_#{meth}", rest, opts) + end + + # @api private + def visit_set(node, opts = EMPTY_HASH) + target = (key = opts[:key]) ? self.class.new(loose: loose?) : self + + node.map { |child| target.visit(child, opts.except(:member)) } + + return unless key + + target_info = opts[:member] ? {items: target.to_h} : target.to_h + type = opts[:member] ? "array" : "object" + + merge_opts!(keys[key], {type: type, **target_info}) + end + + # @api private + def visit_and(node, opts = EMPTY_HASH) + left, right = node + + # We need to know the type first to apply filled macro + if left[1][0] == :filled? + visit(right, opts) + visit(left, opts) + else + visit(left, opts) + visit(right, opts) + end + end + + # @api private + def visit_or(node, opts = EMPTY_HASH) + node.each do |child| + c = self.class.new(loose: loose?) + c.keys.update(subschema: {}) + c.visit(child, opts.merge(key: :subschema)) + + any_of = (keys[opts[:key]][:anyOf] ||= []) + any_of << c.keys[:subschema] + end + end + + # @api private + def visit_implication(node, opts = EMPTY_HASH) + node.each do |el| + visit(el, **opts, required: false) + end + end + + # @api private + def visit_each(node, opts = EMPTY_HASH) + visit(node, opts.merge(member: true)) + end + + # @api private + def visit_key(node, opts = EMPTY_HASH) + name, rest = node + + if opts.fetch(:required, :true) + required << name.to_s + else + opts.delete(:required) + end + + visit(rest, opts.merge(key: name)) + end + + # @api private + def visit_not(node, opts = EMPTY_HASH) + _name, rest = node + + visit_predicate(rest, opts) + end + + # @api private + def visit_predicate(node, opts = EMPTY_HASH) + name, rest = node + + if name.equal?(:key?) + prop_name = rest[0][1] + keys[prop_name] = {} + else + target = keys[opts[:key]] + type_opts = fetch_type_opts_for_predicate(name, rest, target) + + if target[:type]&.include?("array") + target[:items] ||= {} + merge_opts!(target[:items], type_opts) + else + merge_opts!(target, type_opts) + end + end + end + + # @api private + def fetch_type_opts_for_predicate(name, rest, target) + type_opts = PREDICATE_TO_TYPE.fetch(name) do + raise_unknown_conversion_error!(:predicate, name) unless loose? + + EMPTY_HASH + end.dup + type_opts.transform_values! { |v| v.respond_to?(:call) ? v.call(rest[0][1], target) : v } + type_opts.merge!(fetch_filled_options(target[:type], target)) if name == :filled? + type_opts + end + + # @api private + def fetch_filled_options(type, _target) + case type + when "string" + {minLength: 1} + when "array" + raise_unknown_conversion_error!(:type, :array) unless loose? + + {not: {type: "null"}} + else + {not: {type: "null"}} + end + end + + # @api private + def merge_opts!(orig_opts, new_opts) + new_type = new_opts[:type] + orig_type = orig_opts[:type] + + if orig_type && new_type && orig_type != new_type + new_opts[:type] = [orig_type, new_type].flatten.uniq + end + + orig_opts.merge!(new_opts) + end + + # @api private + def root? + @root + end + + # @api private + def loose? + @loose + end + + def raise_unknown_conversion_error!(type, name) + message = <<~MSG + Could not find an equivalent conversion for #{type} #{name.inspect}. + + This means that your generated JSON schema may be missing this validation. + + You can ignore this by generating the schema in "loose" mode, i.e.: + my_schema.json_schema(loose: true) + MSG + + raise UnknownConversionError, message.chomp + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/monads.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/monads.rb new file mode 100644 index 00000000..6ed92116 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/monads.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require "dry/monads" + +# preload monads +Dry::Monads[:result] + +module Dry + module Schema + # Monad extension for Result + # + # @api public + class Result + include ::Dry::Monads::Result::Mixin + + # Turn result into a monad + # + # This makes result objects work with dry-monads (or anything with a compatible interface) + # + # @return [Dry::Monads::Success,Dry::Monads::Failure] + # + # @api public + def to_monad + if success? + Success(self) + else + Failure(self) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/struct.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/struct.rb new file mode 100644 index 00000000..200e792b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/extensions/struct.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +require "dry/struct" + +module Dry + module Schema + module Macros + class StructToSchema < ::Dry::Struct::Compiler + def call(struct) + visit(struct.to_ast) + end + + # strip away structs from AST + def visit_struct(node) + _, ast = node + visit(ast) + end + end + + Hash.option :struct_compiler, default: proc { StructToSchema.new(schema_dsl.config.types) } + + Hash.prepend(::Module.new { + def call(*args) + if args.size >= 1 && struct?(args[0]) + if block_given? + raise ArgumentError, "blocks are not supported when using " \ + "a struct class (#{name.inspect} => #{args[0]})" + end + + schema = struct_compiler.(args[0]) + + super(schema, *args.drop(1)) + type(schema_dsl.types[name].constructor(schema)) + else + super + end + end + + private + + def struct?(type) + type.is_a?(::Class) && type <= ::Dry::Struct + end + }) + end + + PredicateInferrer::Compiler.alias_method(:visit_struct, :visit_hash) + PrimitiveInferrer::Compiler.alias_method(:visit_struct, :visit_hash) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/json.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/json.rb new file mode 100644 index 00000000..81540bb5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/json.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Dry + module Schema + # JSON schema type + # + # @see Processor + # @see Schema#JSON + # + # @api public + class JSON < Processor + config.key_map_type = :stringified + config.type_registry_namespace = :json + config.filter_empty_string = false + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/key.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/key.rb new file mode 100644 index 00000000..57335af7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/key.rb @@ -0,0 +1,184 @@ +# frozen_string_literal: true + +module Dry + module Schema + # Key objects used by key maps + # + # @api public + class Key + extend ::Dry::Core::Cache + + DEFAULT_COERCER = :itself.to_proc.freeze + + include ::Dry.Equalizer(:name, :coercer) + + # @return [Symbol] The key identifier + attr_reader :id + + # @return [Symbol, String, Object] The actual key name expected in an input hash + attr_reader :name + + # @return [Proc, #call] A key name coercer function + attr_reader :coercer + + # @api private + def self.[](name, **opts) + new(name, **opts) + end + + # @api private + def self.new(*args, **kwargs) + fetch_or_store(args, kwargs) { super } + end + + # @api private + def initialize(id, name: id, coercer: DEFAULT_COERCER) + @id = id + @name = name + @coercer = coercer + end + + # @api private + def read(source) + return unless source.is_a?(::Hash) + + if source.key?(name) + yield(source[name]) + elsif source.key?(coerced_name) + yield(source[coerced_name]) + end + end + + # @api private + def write(source, target) + read(source) { |value| target[coerced_name] = value } + end + + # @api private + def coercible(&coercer) + new(coercer: coercer) + end + + # @api private + def stringified + new(name: name.to_s) + end + + # @api private + def to_dot_notation + [name.to_s] + end + + # @api private + def new(**new_opts) + self.class.new(id, name: name, coercer: coercer, **new_opts) + end + + # @api private + def dump + name + end + + private + + # @api private + def coerced_name + @__coerced_name__ ||= coercer[name] + end + + # A specialized key type which handles nested hashes + # + # @api private + class Hash < self + include ::Dry.Equalizer(:name, :members, :coercer) + + # @api private + attr_reader :members + + # @api private + def initialize(id, members:, **opts) + super(id, **opts) + @members = members + end + + # @api private + def read(source) + super if source.is_a?(::Hash) + end + + def write(source, target) + read(source) { |value| + target[coerced_name] = value.is_a?(::Hash) ? members.write(value) : value + } + end + + # @api private + def coercible(&coercer) + new(coercer: coercer, members: members.coercible(&coercer)) + end + + # @api private + def stringified + new(name: name.to_s, members: members.stringified) + end + + # @api private + def to_dot_notation + [name].product(members.flat_map(&:to_dot_notation)).map { |e| e.join(DOT) } + end + + # @api private + def dump + {name => members.map(&:dump)} + end + end + + # A specialized key type which handles nested arrays + # + # @api private + class Array < self + include ::Dry.Equalizer(:name, :member, :coercer) + + attr_reader :member + + # @api private + def initialize(id, member:, **opts) + super(id, **opts) + @member = member + end + + # @api private + def write(source, target) + read(source) { |value| + target[coerced_name] = + if value.is_a?(::Array) + value.map { |el| el.is_a?(::Hash) ? member.write(el) : el } + else + value + end + } + end + + # @api private + def coercible(&coercer) + new(coercer: coercer, member: member.coercible(&coercer)) + end + + # @api private + def stringified + new(name: name.to_s, member: member.stringified) + end + + # @api private + def to_dot_notation + [:"#{name}[]"].product(member.to_dot_notation).map { |el| el.join(DOT) } + end + + # @api private + def dump + [name, member.dump] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/key_coercer.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/key_coercer.rb new file mode 100644 index 00000000..f469765f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/key_coercer.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require "dry/core/cache" +require "dry/core/equalizer" + +module Dry + module Schema + # Coerces keys in a hash using provided coercer function + # + # @api private + class KeyCoercer + extend ::Dry::Core::Cache + include ::Dry::Equalizer(:key_map, :coercer) + + TO_SYM = :to_sym.to_proc.freeze + + attr_reader :key_map, :coercer + + # @api private + def self.new(*args) + fetch_or_store(*args) { super } + end + + # @api private + def self.symbolized(*args) + new(*args, &TO_SYM) + end + + # @api private + def initialize(key_map, &) + @key_map = key_map.coercible(&) + end + + # @api private + def call(result) + key_map.write(result.to_h) + end + alias_method :[], :call + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/key_map.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/key_map.rb new file mode 100644 index 00000000..1ee996c6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/key_map.rb @@ -0,0 +1,136 @@ +# frozen_string_literal: true + +require "dry/schema/constants" + +module Dry + module Schema + # Represents a list of keys defined by the DSL + # + # KeyMap objects expose an API for introspecting schema keys and the ability + # to rebuild an input hash using configured coercer function. + # + # Instances of this class are used as the very first step by the schema processors. + # + # @api public + class KeyMap + extend ::Dry::Core::Cache + + include ::Dry.Equalizer(:keys) + include ::Enumerable + + # @return [Array] A list of defined key objects + attr_reader :keys + + # Coerce a list of key specs into a key map + # + # @example + # KeyMap[:id, :name] + # KeyMap[:title, :artist, tags: [:name]] + # KeyMap[:title, :artist, [:tags]] + # + # @return [KeyMap] + # + # @api public + def self.[](*keys) + new(keys) + end + + # Build new, or returned a cached instance of a key map + # + # @param [Array, Array, HashArray>] args + # + # @return [KeyMap] + def self.new(*args) + fetch_or_store(*args) { super } + end + + # Set key objects + # + # @api private + def initialize(keys) + @keys = keys.map { |key| + case key + when Hash + root, rest = key.flatten + Key::Hash[root, members: KeyMap[*rest]] + when Array + root, rest = key + Key::Array[root, member: KeyMap[*rest]] + when Key + key + else + Key[key] + end + } + end + + # Write a new hash based on the source hash + # + # @param [Hash] source The source hash + # @param [Hash] target The target hash + # + # @return [Hash] + # + # @api public + def write(source, target = EMPTY_HASH.dup) + each { |key| key.write(source, target) } + target + end + + # Return a new key map that is configured to coerce keys using provided coercer function + # + # @return [KeyMap] + # + # @api public + def coercible(&coercer) + self.class.new(map { |key| key.coercible(&coercer) }) + end + + # Return a new key map with stringified keys + # + # A stringified key map is suitable for reading hashes with string keys + # + # @return [KeyMap] + # + # @api public + def stringified + self.class.new(map(&:stringified)) + end + + # @api private + def to_dot_notation + @to_dot_notation ||= map(&:to_dot_notation).flatten + end + + # Iterate over keys + # + # @api public + def each(&) + keys.each(&) + end + + # Return a new key map merged with the provided one + # + # @param [KeyMap, Array] other Either a key map or an array with key specs + # + # @return [KeyMap] + def +(other) + self.class.new(keys + other.to_a) + end + + # Return a string representation of a key map + # + # @return [String] + def inspect + "#<#{self.class}[#{keys.map(&:dump).map(&:inspect).join(", ")}]>" + end + + # Dump keys to their spec format + # + # @return [Array] + def dump + keys.map(&:dump) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/key_validator.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/key_validator.rb new file mode 100644 index 00000000..70acf708 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/key_validator.rb @@ -0,0 +1,104 @@ +# frozen_string_literal: true + +require "dry/initializer" +require "dry/schema/constants" + +module Dry + module Schema + # @api private + class KeyValidator + extend ::Dry::Initializer + + INDEX_REGEX = /\[\d+\]/ + DIGIT_REGEX = /\A\d+\z/ + BRACKETS = "[]" + + # @api private + option :key_map + + # @api private + def call(result) + input = result.to_h + + input_paths = key_paths(input) + key_paths = key_map.to_dot_notation.sort + + input_paths.each do |path| + error_path = validate_path(key_paths, path) + + next unless error_path + + result.add_error([:unexpected_key, [error_path, input]]) + end + + result + end + + private + + # @api private + def validate_path(key_paths, path) + if path[INDEX_REGEX] + key = path.gsub(INDEX_REGEX, BRACKETS) + if none_key_paths_match?(key_paths, key) + arr = path.gsub(INDEX_REGEX) { ".#{_1[1]}" } + arr.split(DOT).map { DIGIT_REGEX.match?(_1) ? Integer(_1, 10) : _1.to_sym } + end + elsif none_key_paths_match?(key_paths, path) + path + end + end + + # @api private + def none_key_paths_match?(key_paths, path) + !any_key_paths_match?(key_paths, path) + end + + # @api private + def any_key_paths_match?(key_paths, path) + find_path(key_paths, path, false) || + find_path(key_paths, path + DOT, true) || + find_path(key_paths, path + BRACKETS, true) + end + + # @api private + def find_path(key_paths, path, prefix_match) + key = key_paths.bsearch { |key_path| key_path >= path } + prefix_match ? key&.start_with?(path) : key == path + end + + # @api private + def key_paths(hash) + hash.flat_map { |key, value| + case value + when ::Hash + if value.empty? + [key.to_s] + else + [key].product(key_paths(hash[key])).map { _1.join(DOT) } + end + when ::Array + hashes_or_arrays = hashes_or_arrays(value) + + if hashes_or_arrays.empty? + [key.to_s] + else + hashes_or_arrays.flat_map.with_index { |el, idx| + key_paths(el).map { ["#{key}[#{idx}]", *_1].join(DOT) } + } + end + else + key.to_s + end + } + end + + # @api private + def hashes_or_arrays(xs) + xs.select { |x| + (x.is_a?(::Array) || x.is_a?(::Hash)) && !x.empty? + } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/array.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/array.rb new file mode 100644 index 00000000..654cb1b0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/array.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +module Dry + module Schema + module Macros + # Macro used to specify predicates for each element of an array + # + # @api private + class Array < DSL + # @api private + # rubocop: disable Metrics/PerceivedComplexity + # rubocop: disable Metrics/AbcSize + def value(*args, **opts, &block) + type(:array) + + extract_type_spec(args, set_type: false) do |*predicates, type_spec:, type_rule:| + type(schema_dsl.array[type_spec]) if type_spec + + is_hash_block = type_spec.equal?(:hash) + + if predicates.any? || opts.any? || !is_hash_block + super( + *predicates, type_spec: type_spec, type_rule: type_rule, **opts, + &(is_hash_block ? nil : block) + ) + end + + is_op = args.size.equal?(2) && args[1].is_a?(Logic::Operations::Abstract) + + if is_hash_block && !is_op + hash(&block) + elsif is_op + hash = Value.new(schema_dsl: schema_dsl.new, name: name).hash(args[1]) + + trace.captures.concat(hash.trace.captures) + + type(schema_dsl.types[name].of(hash.schema_dsl.types[name])) + end + end + + self + end + # rubocop: enable Metrics/AbcSize + # rubocop: enable Metrics/PerceivedComplexity + + # @api private + def to_ast(*) + [:and, [trace.array?.to_ast, [:each, trace.to_ast]]] + end + alias_method :ast, :to_ast + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/core.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/core.rb new file mode 100644 index 00000000..cf800752 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/core.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +require "dry/initializer" +require "dry/schema/constants" + +module Dry + module Schema + module Macros + # Abstract macro class + # + # @api private + class Core + extend Dry::Initializer + + # @api private + option :name, default: proc {}, optional: true + + # @api private + option :compiler, default: proc { Compiler.new } + + # @api private + option :schema_dsl, optional: true + + # @api private + option :trace, default: proc { Trace.new(schema_dsl&.compiler || Compiler.new) } + + # @api private + def new(**options) + self.class.new(name: name, compiler: compiler, schema_dsl: schema_dsl, **options) + end + + # @api private + def path + schema_dsl.path + end + + # @api private + def to_rule + compiler.visit(to_ast) + end + + # @api private + def to_ast(*) + trace.to_ast + end + alias_method :ast, :to_ast + + # @api private + def operation + raise NotImplementedError + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/dsl.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/dsl.rb new file mode 100644 index 00000000..37ff42a4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/dsl.rb @@ -0,0 +1,278 @@ +# frozen_string_literal: true + +module Dry + module Schema + module Macros + # Macro specialization used within the DSL + # + # @api public + class DSL < Core + include ::Dry::Logic::Operators + + undef :eql? + undef :nil? + undef :respond_to? + + # @!attribute [r] chain + # Indicate if the macro should append its rules to the provided trace + # @return [Boolean] + # @api private + option :chain, default: -> { true } + + # @!attribute [r] predicate_inferrer + # PredicateInferrer is used to infer predicate type-check from a type spec + # @return [PredicateInferrer] + # @api private + option :predicate_inferrer, default: proc { PredicateInferrer.new(compiler.predicates) } + + # @!attribute [r] primitive_inferrer + # PrimitiveInferrer used to get a list of primitive classes from configured type + # @return [PrimitiveInferrer] + # @api private + option :primitive_inferrer, default: proc { PrimitiveInferrer.new } + + # @overload value(*predicates, **predicate_opts) + # Set predicates without and with arguments + # + # @param [Array] predicates + # @param [Hash] predicate_opts + # + # @example with a predicate + # required(:name).value(:filled?) + # + # @example with a predicate with arguments + # required(:name).value(min_size?: 2) + # + # @example with a predicate with and without arguments + # required(:name).value(:filled?, min_size?: 2) + # + # @example with a block + # required(:name).value { filled? & min_size?(2) } + # + # @return [Macros::Core] + # + # @api public + def value(*args, **opts, &block) + if (type_spec_from_opts = opts[:type_spec]) + append_macro(Macros::Value) do |macro| + macro.call(*args, type_spec: type_spec_from_opts, **opts, &block) + end + else + extract_type_spec(args) do |*predicates, type_spec:, type_rule:| + append_macro(Macros::Value) do |macro| + macro.call(*predicates, type_spec: type_spec, type_rule: type_rule, **opts, &block) + end + end + end + end + + # Prepends `:filled?` predicate + # + # @example with a type spec + # required(:name).filled(:string) + # + # @example with a type spec and a predicate + # required(:name).filled(:string, format?: /\w+/) + # + # @return [Macros::Core] + # + # @api public + def filled(*args, **opts, &block) + extract_type_spec(args) do |*predicates, type_spec:, type_rule:| + append_macro(Macros::Filled) do |macro| + macro.call(*predicates, type_spec: type_spec, type_rule: type_rule, **opts, &block) + end + end + end + + # Set type specification and predicates for a maybe value + # + # @example + # required(:name).maybe(:string) + # + # @see Macros::Key#value + # + # @return [Macros::Key] + # + # @api public + def maybe(*args, **opts, &block) + extract_type_spec(args, nullable: true) do |*predicates, type_spec:, type_rule:| + append_macro(Macros::Maybe) do |macro| + macro.call(*predicates, type_spec: type_spec, type_rule: type_rule, **opts, &block) + end + end + end + + # Specify a nested hash without enforced `hash?` type-check + # + # This is a simpler building block than `hash` macro, use it + # when you want to provide `hash?` type-check with other rules + # manually. + # + # @example + # required(:tags).value(:hash, min_size?: 1).schema do + # required(:name).value(:string) + # end + # + # @return [Macros::Core] + # + # @api public + def schema(...) + append_macro(Macros::Schema) do |macro| + macro.call(...) + end + end + + # Specify a nested hash with enforced `hash?` type-check + # + # @example + # required(:tags).hash do + # required(:name).value(:string) + # end + # + # @api public + def hash(...) + append_macro(Macros::Hash) do |macro| + macro.call(...) + end + end + + # Specify predicates that should be applied to each element of an array + # + # This is a simpler building block than `array` macro, use it + # when you want to provide `array?` type-check with other rules + # manually. + # + # @example a list of strings + # required(:tags).value(:array, min_size?: 2).each(:str?) + # + # @example a list of hashes + # required(:tags).value(:array, min_size?: 2).each(:hash) do + # required(:name).filled(:string) + # end + # + # @return [Macros::Core] + # + # @api public + def each(...) + append_macro(Macros::Each) do |macro| + macro.value(...) + end + end + + # Like `each` but sets `array?` type-check + # + # @example a list of strings + # required(:tags).array(:str?) + # + # @example a list of hashes + # required(:tags).array(:hash) do + # required(:name).filled(:string) + # end + # + # @return [Macros::Core] + # + # @api public + def array(...) + append_macro(Macros::Array) do |macro| + macro.value(...) + end + end + + # Set type spec + # + # @example + # required(:name).type(:string).value(min_size?: 2) + # + # @param [Symbol, Array, Dry::Types::Type] spec + # + # @return [Macros::Key] + # + # @api public + def type(spec) + schema_dsl.set_type(name, spec) + self + end + + # @api private + def custom_type? + schema_dsl.custom_type?(name) + end + + private + + # @api private + def append_macro(macro_type) + macro = macro_type.new(schema_dsl: schema_dsl, name: name) + + yield(macro) + + if chain + trace << macro + self + else + macro + end + end + + # @api private + # rubocop: disable Metrics/AbcSize + # rubocop: disable Metrics/CyclomaticComplexity + # rubocop: disable Metrics/PerceivedComplexity + def extract_type_spec(args, nullable: false, set_type: true) + type_spec = args[0] unless schema_or_predicate?(args[0]) + + predicates = Array(type_spec ? args[1..] : args) + type_rule = nil + + if type_spec + resolved_type = resolve_type(type_spec, nullable) + + if type_spec.is_a?(::Array) + type_rule = type_spec.map { |ts| new(chain: false).value(ts) }.reduce(:|) + elsif type_spec.is_a?(Dry::Types::Sum) && set_type + type_rule = [type_spec.left, type_spec.right].map { |ts| + new(klass: Core, chain: false).value(ts) + }.reduce(:|) + else + type_predicates = predicate_inferrer[resolved_type] + + predicates.replace(type_predicates + predicates) unless type_predicates.empty? + + return self if predicates.empty? + end + end + + type(resolved_type) if set_type && resolved_type + + if type_rule + yield(*predicates, type_spec: nil, type_rule: type_rule) + else + yield(*predicates, type_spec: type_spec, type_rule: nil) + end + end + # rubocop: enable Metrics/AbcSize + # rubocop: enable Metrics/CyclomaticComplexity + # rubocop: enable Metrics/PerceivedComplexity + + # @api private + def resolve_type(type_spec, nullable) + resolved = schema_dsl.resolve_type(type_spec) + + if type_spec.is_a?(::Array) || !nullable || resolved.optional? + resolved + else + schema_dsl.resolve_type([:nil, resolved]) + end + end + + # @api private + def schema_or_predicate?(arg) + arg.is_a?(Dry::Schema::Processor) || + (arg.is_a?(Symbol) && + arg.to_s.end_with?(QUESTION_MARK)) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/each.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/each.rb new file mode 100644 index 00000000..a22dd448 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/each.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module Dry + module Schema + module Macros + # Macro used to specify predicates for each element of an array + # + # @api private + class Each < DSL + # @api private + def value(*args, **opts, &block) + extract_type_spec(args, set_type: false) do |*predicates, type_spec:, type_rule:| + if type_spec && !type_spec.is_a?(Dry::Types::Type) + type(schema_dsl.array[type_spec]) + end + + append_macro(Macros::Value) do |macro| + macro.call(*predicates, type_spec: type_spec, type_rule: type_rule, **opts, &block) + end + end + end + + # @api private + def to_ast(*) + [:each, trace.to_ast] + end + alias_method :ast, :to_ast + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/filled.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/filled.rb new file mode 100644 index 00000000..a9cb5cb7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/filled.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +module Dry + module Schema + module Macros + # Macro used to prepend `:filled?` predicate + # + # @api private + class Filled < Value + # @api private + def call(*predicates, **opts, &block) + ensure_valid_predicates(predicates) + + append_macro(Macros::Value) do |macro| + if opts[:type_spec] && !filter_empty_string? + macro.call(predicates[0], :filled?, *predicates.drop(1), **opts, &block) + elsif opts[:type_rule] + macro.call(:filled?).value(*predicates, **opts, &block) + else + macro.call(:filled?, *predicates, **opts, &block) + end + end + end + + # @api private + def ensure_valid_predicates(predicates) + if predicates.include?(:empty?) + raise ::Dry::Schema::InvalidSchemaError, "Using filled with empty? predicate is invalid" + end + + if predicates.include?(:filled?) + raise ::Dry::Schema::InvalidSchemaError, "Using filled with filled? is redundant" + end + end + + # @api private + def filter_empty_string? + !expected_primitives.include?(NilClass) && processor_config.filter_empty_string + end + + # @api private + def processor_config + schema_dsl.processor_type.config + end + + # @api private + def expected_primitives + primitive_inferrer[schema_type] + end + + # @api private + def schema_type + schema_dsl.types[name] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/hash.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/hash.rb new file mode 100644 index 00000000..d0c357b6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/hash.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module Dry + module Schema + module Macros + # Macro used to specify a nested schema + # + # @api private + class Hash < Schema + # @api private + def call(*args, &block) + if args.size >= 1 && args[0].respond_to?(:keys) + hash_type = args[0] + type_predicates = predicate_inferrer[hash_type] + all_predicats = type_predicates + args.drop(1) + + super(*all_predicats) do + hash_type.each do |key| + if key.required? + required(key.name).value(key.type) + else + optional(key.name).value(key.type) + end + instance_exec(&block) if block_given? + end + end + else + trace << hash? + + super + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/key.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/key.rb new file mode 100644 index 00000000..c80bfbd1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/key.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +module Dry + module Schema + module Macros + # Base macro for specifying rules applied to a value found under a key + # + # @api public + class Key < DSL + # @!attribute [r] filter_schema_dsl + # @return [Schema::DSL] + # @api private + option :filter_schema_dsl, default: proc { schema_dsl&.filter_schema_dsl } + + # Specify predicates that should be applied before coercion + # + # @example check format before coercing to a date + # required(:publish_date).filter(format?: /\d{4}-\d{2}-\d{2}).value(:date) + # + # @see Macros::Key#value + # + # @return [Macros::Key] + # + # @api public + def filter(...) + (filter_schema_dsl[name] || filter_schema_dsl.optional(name)).value(...) + self + end + + # Coerce macro to a rule + # + # @return [Dry::Logic::Rule] + # + # @api private + def to_rule + if trace.captures.empty? + super + else + [super, trace.to_rule(name)].reduce(operation) + end + end + + # @api private + def to_ast + [:predicate, [:key?, [[:name, name], [:input, Undefined]]]] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/maybe.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/maybe.rb new file mode 100644 index 00000000..61b46fb7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/maybe.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +module Dry + module Schema + module Macros + # Macro used to specify predicates for a value that can be `nil` + # + # @api private + class Maybe < DSL + # @api private + def call(*args, **opts, &block) + if args.include?(:empty?) + raise ::Dry::Schema::InvalidSchemaError, "Using maybe with empty? predicate is invalid" + end + + if args.include?(:nil?) + raise ::Dry::Schema::InvalidSchemaError, "Using maybe with nil? predicate is redundant" + end + + append_macro(Macros::Value) do |macro| + macro.call(*args, **opts, &block) + end + + self + end + + # @api private + def to_ast + [:implication, + [ + [:not, [:predicate, [:nil?, [[:input, Undefined]]]]], + trace.to_rule.to_ast + ]] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/optional.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/optional.rb new file mode 100644 index 00000000..902aa13c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/optional.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Dry + module Schema + module Macros + # A Key specialization used for keys that can be skipped + # + # @api private + class Optional < Key + # @api private + def operation + :then + end + + # @api private + def to_rule + super unless trace.captures.empty? + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/required.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/required.rb new file mode 100644 index 00000000..e213053c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/required.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Dry + module Schema + module Macros + # A Key specialization used for keys that must be present + # + # @api private + class Required < Key + # @api private + def operation + :and + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/schema.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/schema.rb new file mode 100644 index 00000000..5c6c6590 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/schema.rb @@ -0,0 +1,103 @@ +# frozen_string_literal: true + +module Dry + module Schema + module Macros + # Macro used to specify a nested schema + # + # @api private + class Schema < Value + # @api private + def call(*args, &block) + super(*args, &nil) unless args.empty? + + if args.size.equal?(1) && (op = args.first).is_a?(::Dry::Logic::Operations::Abstract) + process_operation(op) + end + + if block + schema = define(*args, &block) + import_steps(schema) + trace << schema.to_rule + end + + self + end + + private + + # @api private + def process_operation(op) + type(hash_type.schema(merge_operation_types(op))) + end + + # @api private + def hash_type + schema_dsl.resolve_type(:hash) + end + + # @api private + def merge_operation_types(op) + op.rules.reduce({}) do |acc, rule| + types = + case rule + when Dry::Logic::Operations::Abstract + merge_operation_types(rule) + when Processor + rule.types + else + EMPTY_HASH.dup + end + + schema_dsl.merge_types(op.class, acc, types) + end + end + + # @api private + # rubocop: disable Metrics/AbcSize + def define(*args, &) + definition = schema_dsl.new(path: schema_dsl.path, &) + schema = definition.call + type_schema = + if array_type?(parent_type) + build_array_type(parent_type, definition.strict_type_schema) + elsif redefined_schema?(args) + parent_type.schema(definition.types) + else + definition.strict_type_schema + end + final_type = optional? ? type_schema.optional : type_schema + + type(final_type) + + if schema.filter_rules? + schema_dsl[name].filter { hash?.then(schema(schema.filter_schema)) } + end + + schema + end + # rubocop: enable Metrics/AbcSize + + # @api private + def parent_type + schema_dsl.types[name] + end + + # @api private + def optional? + parent_type.optional? + end + + # @api private + def schema? + parent_type.respond_to?(:schema) + end + + # @api private + def redefined_schema?(args) + schema? && args.first.is_a?(Processor) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/value.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/value.rb new file mode 100644 index 00000000..51b34261 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/macros/value.rb @@ -0,0 +1,125 @@ +# frozen_string_literal: true + +module Dry + module Schema + module Macros + # A macro used for specifying predicates to be applied to values from a hash + # + # @api private + class Value < DSL + # @api private + # + # rubocop:disable Metrics/AbcSize + # rubocop:disable Metrics/CyclomaticComplexity + # rubocop:disable Metrics/PerceivedComplexity + def call(*args, **opts, &) + types, predicates = args.partition { _1.is_a?(::Dry::Types::Type) } + + constructor = types.select { _1.is_a?(::Dry::Types::Constructor) }.reduce(:>>) + schema = predicates.detect { _1.is_a?(Processor) } + + schema_dsl.set_type(name, constructor) if constructor + + type_spec = opts[:type_spec] + + if schema + current_type = schema_dsl.types[name] + + updated_type = + if array_type?(current_type) + build_array_type(current_type, schema.strict_type_schema) + else + schema.strict_type_schema + end + + import_steps(schema) + + if !custom_type? || array_type?(current_type) || hash_type?(current_type) + type(updated_type) + elsif maybe_type?(current_type) + type(updated_type.optional) + end + end + + trace_opts = opts.except(:type_spec, :type_rule) + + if (type_rule = opts[:type_rule]) + trace.append(type_rule).evaluate(*predicates, **trace_opts) + trace.append(new(chain: false).instance_exec(&)) if block_given? + else + trace.evaluate(*predicates, **trace_opts) + + if block_given? && type_spec.equal?(:hash) + hash(&) + elsif type_spec.is_a?(::Dry::Types::Type) && hash_type?(type_spec) + hash(type_spec) + elsif block_given? + trace.append(new(chain: false).instance_exec(&)) + end + end + + if trace.captures.empty? + raise ArgumentError, "wrong number of arguments (given 0, expected at least 1)" + end + + each(type_spec.type.member) if type_spec.respond_to?(:member) + + self + end + # rubocop:enable Metrics/AbcSize + # rubocop:enable Metrics/CyclomaticComplexity + # rubocop:enable Metrics/PerceivedComplexity + + # @api private + def array_type?(type) + primitive_inferrer[type].eql?([::Array]) + end + + # @api private + def hash_type?(type) + primitive_inferrer[type].eql?([::Hash]) + end + + # @api private + def maybe_type?(type) + type.meta[:maybe].equal?(true) + end + + # @api private + def build_array_type(array_type, member) + if array_type.respond_to?(:of) + array_type.of(member) + else + raise ArgumentError, <<~ERROR.split("\n").join(" ") + Cannot define schema for a nominal array type. + Array types must be instances of Dry::Types::Array, + usually constructed with Types::Constructor(Array) { ... } or + Dry::Types['array'].constructor { ... } + ERROR + end + end + + # @api private + def import_steps(schema) + schema_dsl.steps.import_callbacks(Path[[*path, name]], schema.steps) + end + + # @api private + def respond_to_missing?(meth, include_private = false) + super || meth.to_s.end_with?(QUESTION_MARK) + end + + private + + # @api private + def method_missing(meth, ...) + if meth.to_s.end_with?(QUESTION_MARK) + trace.__send__(meth, ...) + else + super + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/message.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/message.rb new file mode 100644 index 00000000..e1035595 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/message.rb @@ -0,0 +1,109 @@ +# frozen_string_literal: true + +require "dry/initializer" + +module Dry + module Schema + # Message objects used by message sets + # + # @api public + class Message + include ::Dry::Equalizer(:text, :path, :predicate, :input) + + extend ::Dry::Initializer + + # @!attribute [r] text + # Message text representation created from a localized template + # @return [String] + option :text + + # @!attribute [r] path + # Path to the value + # @return [String] + option :path + + # @!attribute [r] predicate + # Predicate identifier that was used to produce a message + # @return [Symbol] + option :predicate + + # @!attribute [r] args + # Optional list of arguments used by the predicate + # @return [Array] + option :args, default: proc { EMPTY_ARRAY } + + # @!attribute [r] input + # The input value + # @return [Object] + option :input + + # @!attribute [r] meta + # Arbitrary meta data + # @return [Hash] + option :meta, optional: true, default: proc { EMPTY_HASH } + + # Dump the message to a representation suitable for the message set hash + # + # @return [String,Hash] + # + # @api public + def dump + @dump ||= meta.empty? ? text : {text: text, **meta} + end + alias_method :to_s, :dump + + # Dump the message into a hash + # + # The hash will be deeply nested if the path's size is greater than 1 + # + # @see Message#to_h + # + # @return [Hash] + # + # @api public + def to_h + @to_h ||= _path.to_h(dump) + end + + # See if another message is the same + # + # If a string is passed, it will be compared with the text + # + # @param other [Message,String] + # + # @return [Boolean] + # + # @api private + def eql?(other) + other.is_a?(::String) ? text == other : super + end + + # @api private + def to_or(root) + clone = dup + clone.instance_variable_set("@path", path - root.to_a) + clone.instance_variable_set("@_path", nil) + clone + end + + # See which message is higher in the hierarchy + # + # @api private + def <=>(other) + l_path = _path + r_path = other._path + + unless l_path.same_root?(r_path) + raise ::ArgumentError, "Cannot compare messages from different root paths" + end + + l_path <=> r_path + end + + # @api private + def _path + @_path ||= Path[path] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/message/or.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/message/or.rb new file mode 100644 index 00000000..873d10ca --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/message/or.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module Dry + module Schema + # Message objects used by message sets + # + # @api public + class Message + module Or + # @api private + def self.[](left, right, messages) + msgs = [left, right].flatten + paths = msgs.map(&:path) + + if paths.uniq.size == 1 + SinglePath.new(left, right, messages) + elsif MultiPath.handler(right) + if MultiPath.handler(left) && paths.uniq.size > 1 + MultiPath.new(left, right) + else + right + end + else + msgs.max + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/message/or/abstract.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/message/or/abstract.rb new file mode 100644 index 00000000..e1f22906 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/message/or/abstract.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module Dry + module Schema + class Message + module Or + # A message type used by OR operations + # + # @abstract + # + # @api private + class Abstract + # @api private + attr_reader :left + + # @api private + attr_reader :right + + # @api private + def initialize(left, right) + @left = left + @right = right + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/message/or/multi_path.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/message/or/multi_path.rb new file mode 100644 index 00000000..fb333b41 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/message/or/multi_path.rb @@ -0,0 +1,100 @@ +# frozen_string_literal: true + +module Dry + module Schema + class Message + module Or + # A message type used by OR operations with different paths + # + # @api public + class MultiPath < Abstract + # @api private + class MessageArray + # @api private + def initialize(messages) + @messages = messages.flatten + end + + # @api private + def _paths + @messages.map(&:_path) + end + + # @api private + def to_or(root) + self.class.new(@messages.map { _1.to_or(root) }) + end + + # @api private + def to_h + MessageSet.new(@messages).to_h + end + end + + MESSAGE_ARRAY_HANDLER = -> { MessageArray.new(_1) } + + # @api private + def self.handler(message) + case message + when self + IDENTITY + when Array + MESSAGE_ARRAY_HANDLER + end + end + + # @api public + def to_h + @to_h ||= Path[[*root, :or]].to_h(messages.map(&:to_h)) + end + + # @api private + def messages + @messages ||= _messages.flat_map { _1.to_or(root) } + end + + # @api private + def root + @root ||= _paths.reduce(:&) + end + + # @api private + def path + root + end + + # @api private + def _path + @_path ||= Path[root] + end + + # @api private + def _paths + @paths ||= _messages.flat_map(&:_paths) + end + + # @api private + def to_or(root) + self.root == root ? messages : [self] + end + + private + + # @api private + def _messages + @_messages ||= [left, right].map do |message| + handler = self.class.handler(message) + + unless handler + raise ArgumentError, + "#{message.inspect} is of unknown type #{message.class.inspect}" + end + + handler.(message) + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/message/or/single_path.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/message/or/single_path.rb new file mode 100644 index 00000000..2a100a71 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/message/or/single_path.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +module Dry + module Schema + class Message + module Or + # A message type used by OR operations with the same path + # + # @api public + class SinglePath < Abstract + # @api private + attr_reader :path + + # @api private + attr_reader :_path + + # @api private + attr_reader :messages + + # @api private + def initialize(*args, messages) + super(*args.map { [_1].flatten }) + @messages = messages + message = left.first + @path = message.path + @_path = message._path + end + + # Dump a message into a string + # + # Both sides of the message will be joined using translated + # value under `dry_schema.or` message key + # + # @see Message#dump + # + # @return [String] + # + # @api public + def dump + @dump ||= [*left, *right].map(&:dump).join(" #{messages[:or]} ") + end + alias_method :to_s, :dump + + # Dump an `or` message into a hash + # + # @see Message#to_h + # + # @return [String] + # + # @api public + def to_h + @to_h ||= _path.to_h(dump) + end + + # @api private + def to_a + @to_a ||= [*left, *right] + end + + # @api private + def to_or(root) + to_ored = [left, right].map do |msgs| + msgs.map { _1.to_or(root) } + end + + self.class.new(*to_ored, messages) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/message_compiler.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/message_compiler.rb new file mode 100644 index 00000000..ca1a81a4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/message_compiler.rb @@ -0,0 +1,234 @@ +# frozen_string_literal: true + +require "dry/initializer" +require "dry/schema/constants" + +module Dry + module Schema + # Compiles rule results AST into human-readable format + # + # @api private + class MessageCompiler + extend ::Dry::Initializer + + resolve_key_predicate = proc { |node, opts| + *arg_vals, val = node.map(&:last) + [[*opts.path, arg_vals[0]], arg_vals[1..arg_vals.size - 1], val] + } + + resolve_predicate = proc { |node, opts| + [Array(opts.path), *node.map(&:last)] + } + + DEFAULT_PREDICATE_RESOLVERS = ::Hash + .new(resolve_predicate).update(key?: resolve_key_predicate).freeze + + EMPTY_OPTS = VisitorOpts.new + EMPTY_MESSAGE_SET = MessageSet.new(EMPTY_ARRAY).freeze + FULL_MESSAGE_WHITESPACE = ::Hash.new(" ").merge( + ja: "", + zh: "", + bn: "", + th: "", + lo: "", + my: "" + ) + + param :messages + + option :full, default: -> { false } + option :locale, default: -> { :en } + option :predicate_resolvers, default: -> { DEFAULT_PREDICATE_RESOLVERS } + + attr_reader :options + + attr_reader :default_lookup_options + + # @api private + def initialize(messages, **options) + super + @options = options + @default_lookup_options = options[:locale] ? {locale: locale} : EMPTY_HASH + end + + # @api private + def with(new_options) + return self if new_options.empty? + + updated_opts = options.merge(new_options) + + return self if updated_opts.eql?(options) + + self.class.new(messages, **updated_opts) + end + + # @api private + def call(ast) + return EMPTY_MESSAGE_SET if ast.empty? + + current_messages = EMPTY_ARRAY.dup + compiled_messages = ast.map { |node| visit(node, EMPTY_OPTS.dup(current_messages)) } + + MessageSet[compiled_messages, failures: options.fetch(:failures, true)] + end + + # @api private + def visit(node, opts = EMPTY_OPTS.dup) + __send__(:"visit_#{node[0]}", node[1], opts) + end + + # @api private + def visit_failure(node, opts) + rule, other = node + visit(other, opts.(rule: rule)) + end + + # @api private + def visit_hint(*) + nil + end + + # @api private + def visit_not(node, opts) + visit(node, opts.(not: true)) + end + + # @api private + def visit_and(node, opts) + left, right = node.map { |n| visit(n, opts) } + + if right + [left, right] + else + left + end + end + + # @api private + def visit_unexpected_key(node, opts) + visit_predicate([:unexpected_key, []], opts.dup.update(path: Path[node.first])) + end + + # @api private + def visit_or(node, opts) + left, right = node.map { |n| visit(n, opts) } + Message::Or[left, right, or_translator] + end + + # @api private + def or_translator + @or_translator ||= proc { |k| + message = messages.translate(k, **default_lookup_options) + message.is_a?(Hash) ? message[:text] : message + } + end + + # @api private + def visit_namespace(node, opts) + ns, rest = node + self.class.new(messages.namespaced(ns), **options).visit(rest, opts) + end + + # @api private + def visit_predicate(node, opts) + predicate, args = node + + tokens = message_tokens(args) + path, *arg_vals, input = predicate_resolvers[predicate].(args, opts) + + options = opts.dup.update( + path: path.last, **tokens, **lookup_options(arg_vals: arg_vals, input: input) + ).to_h + + template, meta = messages[predicate, options] + + unless template + raise MissingMessageError.new(path, messages.looked_up_paths(predicate, options)) + end + + text = message_text(template, tokens, options) + + message_type(options).new( + text: text, + meta: meta, + path: path, + predicate: predicate, + args: arg_vals, + input: input + ) + end + + # @api private + def message_type(*) + Message + end + + # @api private + def visit_key(node, opts) + name, other = node + visit(other, opts.(path: name)) + end + + # @api private + def visit_set(node, opts) + node.map { |el| visit(el, opts) } + end + + # @api private + def visit_implication(node, *args) + _, right = node + visit(right, *args) + end + + # @api private + def visit_xor(node, opts) + left, right = node + [visit(left, opts), visit(right, opts)].uniq + end + + # @api private + def lookup_options(arg_vals:, input:) + default_lookup_options.merge( + arg_type: arg_vals.size == 1 && arg_vals[0].class, + val_type: input.equal?(Undefined) ? ::NilClass : input.class + ) + end + + # @api private + def message_text(template, tokens, options) + text = template[template.data(tokens)] + + return text if !text || !full + + rule = options[:path] + [messages.rule(rule, options) || rule, + text].join(FULL_MESSAGE_WHITESPACE[template.options[:locale]]) + end + + # @api private + def message_tokens(args) + tokens = args.each_with_object({}) do |arg, hash| + case arg[1] + when ::Array, ::Set + hash[arg[0]] = arg[1].join(LIST_SEPARATOR) + when ::Range + hash[:"#{arg[0]}_left"] = arg[1].first + hash[:"#{arg[0]}_right"] = arg[1].last + else + hash[arg[0]] = arg[1] + end + end + args.any? { |e| e.first == :size } ? append_mapped_size_tokens(tokens) : tokens + end + + # @api private + def append_mapped_size_tokens(tokens) + # this is a temporary fix for the inconsistency in the "size" errors arguments + mapped_hash = tokens.each_with_object({}) { |(k, v), h| + h[k.to_s.gsub("size", "num").to_sym] = v + } + tokens.merge(mapped_hash) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/message_compiler/visitor_opts.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/message_compiler/visitor_opts.rb new file mode 100644 index 00000000..eec00a66 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/message_compiler/visitor_opts.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require "dry/schema/constants" + +module Dry + module Schema + # @api private + class MessageCompiler + # Optimized option hash used by visitor methods in message compiler + # + # @api private + class VisitorOpts < Hash + # @api private + def self.new + opts = super + opts[:path] = EMPTY_ARRAY + opts[:message_type] = :failure + opts[:current_messages] = EMPTY_ARRAY.dup + opts + end + + # @api private + def path + self[:path] + end + + # @api private + def call(other) + merge(other.update(path: [*path, *other[:path]])) + end + + def dup(current_messages = EMPTY_ARRAY.dup) + opts = super() + opts[:current_messages] = current_messages + opts + end + + def key_failure?(path) + failures.any? { |f| f.path == path && f.predicate.equal?(:key?) } + end + + def failures + current_messages.reject(&:hint?) + end + + def hints + current_messages.select(&:hint?) + end + + def current_messages + self[:current_messages] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/message_set.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/message_set.rb new file mode 100644 index 00000000..01c47d4f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/message_set.rb @@ -0,0 +1,144 @@ +# frozen_string_literal: true + +require "dry/core/equalizer" + +module Dry + module Schema + # A set of messages used to generate errors + # + # @see Result#message_set + # + # @api public + class MessageSet + include ::Enumerable + include ::Dry::Equalizer(:messages, :options) + + # A list of compiled message objects + # + # @return [Array] + attr_reader :messages + + # Options hash + # + # @return [Hash] + attr_reader :options + + # @api private + def self.[](messages, options = EMPTY_HASH) + new(messages.flatten, options) + end + + # @api private + def initialize(messages, options = EMPTY_HASH) + @messages = messages + @options = options + end + + # Iterate over messages + # + # @example + # result.errors.each do |message| + # puts message.text + # end + # + # @return [Array] + # + # @api public + def each(&) + return self if empty? + return to_enum unless block_given? + + messages.each(&) + end + + # Dump message set to a hash + # + # @return [HashArray>] + # + # @api public + def to_h + @to_h ||= messages_map + end + alias_method :to_hash, :to_h + + # Get a list of message texts for the given key + # + # @param [Symbol] key + # + # @return [Array] + # + # @api public + def [](key) + to_h[key] + end + + # Get a list of message texts for the given key + # + # @param [Symbol] key + # + # @return [Array] + # + # @raise KeyError + # + # @api public + def fetch(key) + self[key] || raise(::KeyError, "+#{key}+ message was not found") + end + + # Check if a message set is empty + # + # @return [Boolean] + # + # @api public + def empty? + @empty ||= messages.empty? + end + + # @api private + def freeze + to_h + empty? + super + end + + private + + # @api private + def messages_map(messages = self.messages) + combine_message_hashes(messages.map(&:to_h)).freeze + end + + # @api private + def combine_message_hashes(hashes) + hashes.reduce(EMPTY_HASH.dup) do |a, e| + a.merge(e) do |_, *values| + combine_message_values(values) + end + end + end + + # @api private + def combine_message_values(values) + hashes, other = partition_message_values(values) + combined = combine_message_hashes(hashes) + flattened = other.flatten + + if flattened.empty? + combined + elsif combined.empty? + flattened + else + [flattened, combined] + end + end + + # @api private + def partition_message_values(values) + values + .map { |value| value.is_a?(::Array) ? value : [value] } + .reduce(EMPTY_ARRAY.dup, :+) + .partition { |value| value.is_a?(::Hash) && !value[:text].is_a?(::String) } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/messages.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/messages.rb new file mode 100644 index 00000000..04631872 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/messages.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module Dry + module Schema + # An API for configuring message backends + # + # @api private + module Messages + BACKENDS = { + i18n: "I18n", + yaml: "YAML" + }.freeze + + module_function + + public def setup(config) + backend_class = BACKENDS.fetch(config.backend) do + raise "+#{config.backend}+ is not a valid messages identifier" + end + + namespace = config.namespace + options = config.to_h.select { |k, _| Abstract.setting_names.include?(k) } + + messages = Messages.const_get(backend_class).build(options) + + return messages.namespaced(namespace) if namespace + + messages + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/messages/abstract.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/messages/abstract.rb new file mode 100644 index 00000000..8f25b9d2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/messages/abstract.rb @@ -0,0 +1,203 @@ +# frozen_string_literal: true + +require "set" +require "concurrent/map" + +require "dry/schema/constants" + +module Dry + module Schema + module Messages + # Abstract class for message backends + # + # @api public + class Abstract + include ::Dry::Configurable + include ::Dry::Equalizer(:config) + + setting :default_locale + setting :load_paths, default: ::Set[DEFAULT_MESSAGES_PATH] + setting :top_namespace, default: DEFAULT_MESSAGES_ROOT + setting :root, default: "errors" + setting :lookup_options, default: %i[root predicate path val_type arg_type].freeze + + setting :lookup_paths, default: [ + "%s.rules.%s.%s.arg.%s", + "%s.rules.%s.%s", + "%s.%s.%s", + "%s.%s.value.%s", + "%s.%s.value.%s.arg.%s", + "%s.%s.value.%s", + "%s.%s.arg.%s", + "%s.%s" + ].freeze + + setting :rule_lookup_paths, default: ["rules.%s"].freeze + + setting :arg_types, default: ::Hash.new { |*| "default" }.update( + ::Range => "range" + ) + + setting :val_types, default: ::Hash.new { |*| "default" }.update( + ::Range => "range", + ::String => "string" + ) + + # @api private + def self.setting_names + @setting_names ||= settings.map { _1.name.to_sym } + end + + # @api private + def self.build(options = EMPTY_HASH) + messages = new + + messages.configure do |config| + options.each do |key, value| + config.public_send(:"#{key}=", value) + end + + config.root = "#{config.top_namespace}.#{config.root}" + + config.rule_lookup_paths = config.rule_lookup_paths.map { |path| + "#{config.top_namespace}.#{path}" + } + + yield(config) if block_given? + end + + messages.prepare + end + + # @api private + def translate(key, locale: default_locale) + t["#{config.top_namespace}.#{key}", locale: locale] + end + + # @api private + def rule(name, options = {}) + tokens = {name: name, locale: options.fetch(:locale, default_locale)} + path = rule_lookup_paths(tokens).detect { |key| key?(key, options) } + + rule = get(path, options) if path + rule.is_a?(::Hash) ? rule[:text] : rule + end + + # Retrieve a message template + # + # @return [Template] + # + # @api public + def call(predicate, options) + options = {locale: default_locale, **options} + opts = options.reject { |k,| config.lookup_options.include?(k) } + path = lookup_paths(predicate, options).detect { |key| key?(key, opts) } + + return unless path + + result = get(path, opts) + + [ + Template.new( + messages: self, + key: path, + options: opts + ), + result[:meta] + ] + end + + alias_method :[], :call + + # Check if given key is defined + # + # @return [Boolean] + # + # @api public + def key?(_key, _options = EMPTY_HASH) + raise ::NotImplementedError + end + + # Retrieve an array of looked up paths + # + # @param [Symbol] predicate + # @param [Hash] options + # + # @return [String] + # + # @api public + def looked_up_paths(predicate, options) + tokens = lookup_tokens(predicate, options) + filled_lookup_paths(tokens) + end + + # @api private + def lookup_paths(predicate, options) + tokens = lookup_tokens(predicate, options) + filled_lookup_paths(tokens) + end + + # @api private + def filled_lookup_paths(tokens) + config.lookup_paths.map { |path| path % tokens } + end + + # @api private + def rule_lookup_paths(tokens) + config.rule_lookup_paths.map { |key| key % tokens } + end + + # Return a new message backend that will look for messages under provided namespace + # + # @param [Symbol,String] namespace + # + # @api public + def namespaced(namespace) + Dry::Schema::Messages::Namespaced.new(namespace, self) + end + + # Return root path to messages file + # + # @return [Pathname] + # + # @api public + def root + config.root + end + + # @api private + def default_locale + config.default_locale + end + + # @api private + def interpolatable_data(_key, _options, **_data) + raise ::NotImplementedError + end + + # @api private + def interpolate(_key, _options, **_data) + raise ::NotImplementedError + end + + private + + # @api private + def lookup_tokens(predicate, options) + options.merge( + predicate: predicate, + root: options[:not] ? "#{root}.not" : root, + arg_type: config.arg_types[options[:arg_type]], + val_type: config.val_types[options[:val_type]], + message_type: options[:message_type] || :failure + ) + end + + # @api private + def custom_top_namespace?(path) + path.to_s == DEFAULT_MESSAGES_PATH.to_s && config.top_namespace != DEFAULT_MESSAGES_ROOT + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/messages/i18n.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/messages/i18n.rb new file mode 100644 index 00000000..49e9be54 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/messages/i18n.rb @@ -0,0 +1,133 @@ +# frozen_string_literal: true + +require "yaml" +require "i18n" + +module Dry + module Schema + module Messages + # I18n message backend + # + # @api public + class I18n < Abstract + # Translation function + # + # @return [Method] + attr_reader :t + + # @api private + def initialize + super + @t = ::I18n.method(:t) + end + + # Get a message for the given key and its options + # + # @param [Symbol] key + # @param [Hash] options + # + # @return [String] + # + # @api public + def get(key, options = EMPTY_HASH) + return unless key + + result = t.(key, locale: options.fetch(:locale, default_locale)) + + if result.is_a?(Hash) + text = result[:text] + meta = result.dup.tap { |h| h.delete(:text) } + else + text = result + meta = EMPTY_HASH.dup + end + + { + text: text, + meta: meta + } + end + + # Check if given key is defined + # + # @return [Boolean] + # + # @api public + def key?(key, options) + ::I18n.exists?(key, options.fetch(:locale, default_locale)) || + ::I18n.exists?(key, ::I18n.default_locale) + end + + # Merge messages from an additional path + # + # @param [String, Array] paths + # + # @return [Messages::I18n] + # + # @api public + def merge(paths) + prepare(paths) + end + + # @api private + def default_locale + super || ::I18n.locale || ::I18n.default_locale + end + + # @api private + def prepare(paths = config.load_paths) + paths.each do |path| + data = ::YAML.load_file(path) + + if custom_top_namespace?(path) + top_namespace = config.top_namespace + + mapped_data = data.transform_values { |v| + {top_namespace => v[DEFAULT_MESSAGES_ROOT]} + } + + store_translations(mapped_data) + else + store_translations(data) + end + end + + self + end + + # @api private + def interpolatable_data(_key, _options, **data) + data + end + + # @api private + def interpolate(key, options, **data) + text_key = "#{key}.text" + + opts = { + locale: default_locale, + **options, + **data + } + + resolved_key = key?(text_key, opts) ? text_key : key + + t.(resolved_key, **opts) + end + + private + + # @api private + def store_translations(data) + locales = data.keys.map(&:to_sym) + + ::I18n.available_locales |= locales + + locales.each do |locale| + ::I18n.backend.store_translations(locale, data[locale.to_s]) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/messages/namespaced.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/messages/namespaced.rb new file mode 100644 index 00000000..af124866 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/messages/namespaced.rb @@ -0,0 +1,93 @@ +# frozen_string_literal: true + +module Dry + module Schema + module Messages + # Namespaced messages backend + # + # @api public + class Namespaced < ::Dry::Schema::Messages::Abstract + # @api private + attr_reader :namespace + + # @api private + attr_reader :messages + + # @api private + attr_reader :config + + # @api private + attr_reader :call_opts + + # @api private + def initialize(namespace, messages) + super() + @config = messages.config + @namespace = namespace + @messages = messages + @call_opts = {namespace: namespace}.freeze + end + + # Get a message for the given key and its options + # + # @param [Symbol] key + # @param [Hash] options + # + # @return [String] + # + # @api public + def get(key, options = {}) + messages.get(key, options) + end + + # @api public + def call(key, options = {}) + super(key, options.empty? ? call_opts : options.merge(call_opts)) + end + alias_method :[], :call + + # Check if given key is defined + # + # @return [Boolean] + # + # @api public + def key?(key, *args) + messages.key?(key, *args) + end + + # @api private + def filled_lookup_paths(tokens) + super(tokens.merge(root: "#{tokens[:root]}.#{namespace}")) + super + end + + # @api private + def rule_lookup_paths(tokens) + base_paths = messages.rule_lookup_paths(tokens) + base_paths.map { |key| + key.sub(config.top_namespace, "#{config.top_namespace}.#{namespace}") + } + base_paths + end + + # @api private + def cache_key(predicate, options) + messages.cache_key(predicate, options) + end + + # @api private + def interpolatable_data(key, options, **data) + messages.interpolatable_data(key, options, **data) + end + + # @api private + def interpolate(key, options, **data) + messages.interpolate(key, options, **data) + end + + # @api private + def translate(key, **args) + messages.translate(key, **args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/messages/template.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/messages/template.rb new file mode 100644 index 00000000..42622b7c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/messages/template.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require "dry/initializer" +require "dry/core/equalizer" + +require "dry/schema/constants" + +module Dry + module Schema + module Messages + # @api private + class Template + extend ::Dry::Initializer + include ::Dry::Equalizer(:messages, :key, :options) + + option :messages + option :key + option :options + + # @api private + def data(data = EMPTY_HASH) + ensure_message! + messages.interpolatable_data(key, options, **options, **data) + end + + # @api private + def call(data = EMPTY_HASH) + ensure_message! + messages.interpolate(key, options, **data) + end + alias_method :[], :call + + private + + def ensure_message! + return if messages.key?(key, options) + + raise KeyError, "No message found for template, template=#{inspect}" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/messages/yaml.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/messages/yaml.rb new file mode 100644 index 00000000..692a0932 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/messages/yaml.rb @@ -0,0 +1,209 @@ +# frozen_string_literal: true + +require "yaml" +require "pathname" + +require "dry/schema/constants" + +module Dry + module Schema + module Messages + # Plain YAML message backend + # + # @api public + class YAML < Abstract + LOCALE_TOKEN = "%s" + TOKEN_REGEXP = /%{(\w*)}/ + EMPTY_CONTEXT = ::Object.new.tap { |ctx| + def ctx.context + binding + end + }.freeze.context + + include ::Dry::Equalizer(:data) + + # Loaded localized message templates + # + # @return [Hash] + attr_reader :data + + # Translation function + # + # @return [Proc] + attr_reader :t + + # @api private + def self.build(options = EMPTY_HASH) + super do |config| + config.default_locale = :en unless config.default_locale + + config.root = -"%s.#{config.root}" + + config.rule_lookup_paths = config.rule_lookup_paths.map { |path| + -"%s.#{path}" + } + end + end + + # @api private + # rubocop: disable Metrics/PerceivedComplexity + def self.flat_hash(hash, path = EMPTY_ARRAY, keys = {}) + hash.each do |key, value| + flat_hash(value, [*path, key], keys) if value.is_a?(Hash) + + if value.is_a?(String) && hash["text"] != value + keys[[*path, key].join(DOT)] = { + text: value, + meta: EMPTY_HASH + } + elsif value.is_a?(Hash) && value["text"].is_a?(String) + keys[[*path, key].join(DOT)] = { + text: value["text"], + meta: value.reject { _1.eql?("text") }.transform_keys(&:to_sym) + } + end + end + + keys + end + # rubocop: enable Metrics/PerceivedComplexity + + # @api private + def self.cache + @cache ||= Concurrent::Map.new do |h, k| + h.compute_if_absent(k) { Concurrent::Map.new } + end + end + + # @api private + def self.source_cache + @source_cache ||= Concurrent::Map.new + end + + # @api private + def initialize(data: EMPTY_HASH, config: nil) + super() + @data = data + @__config__ = config if config + @t = proc { |key, locale: default_locale| get("%s.#{key}", locale: locale) } + end + + # Get an array of looked up paths + # + # @param [Symbol] predicate + # @param [Hash] options + # + # @return [String] + # + # @api public + def looked_up_paths(predicate, options) + super.map { |path| path % {locale: options[:locale] || default_locale} } + end + + # Get a message for the given key and its options + # + # @param [Symbol] key + # @param [Hash] options + # + # @return [String] + # + # @api public + def get(key, options = EMPTY_HASH) + data[evaluated_key(key, options)] + end + + # Check if given key is defined + # + # @return [Boolean] + # + # @api public + def key?(key, options = EMPTY_HASH) + data.key?(evaluated_key(key, options)) + end + + # Merge messages from an additional path + # + # @param [String] overrides + # + # @return [Messages::I18n] + # + # @api public + def merge(overrides) + if overrides.is_a?(Hash) + self.class.new( + data: data.merge(self.class.flat_hash(overrides)), + config: config + ) + else + self.class.new( + data: Array(overrides).reduce(data) { |a, e| a.merge(load_translations(e)) }, + config: config + ) + end + end + + # @api private + def prepare + @data = config.load_paths.map { |path| load_translations(path) }.reduce({}, :merge) + self + end + + # @api private + def interpolatable_data(key, options, **data) + tokens = evaluation_context(key, options).fetch(:tokens) + data.select { |k,| tokens.include?(k) } + end + + # @api private + def interpolate(key, options, **data) + evaluator = evaluation_context(key, options).fetch(:evaluator) + data.empty? ? evaluator.() : evaluator.(**data) + end + + private + + # @api private + def evaluation_context(key, options) + cache.fetch_or_store(get(key, options).fetch(:text)) do |input| + tokens = input.scan(TOKEN_REGEXP).flatten(1).to_set(&:to_sym) + text = input.gsub("%", "#") + + # rubocop:disable Security/Eval + evaluator = eval(<<~RUBY, EMPTY_CONTEXT, __FILE__, __LINE__ + 1) + -> (#{tokens.map { |token| "#{token}:" }.join(", ")}) { "#{text}" } # -> (a:, b:) { "Translation #\{a} #\{b}" } + RUBY + # rubocop:enable Security/Eval + + { + tokens: tokens, + evaluator: evaluator + } + end + end + + # @api private + def cache + @cache ||= self.class.cache[self] + end + + # @api private + def load_translations(path) + data = self.class.source_cache.fetch_or_store(path) do + self.class.flat_hash(::YAML.load_file(path)).freeze + end + + return data unless custom_top_namespace?(path) + + data.transform_keys { _1.gsub(DEFAULT_MESSAGES_ROOT, config.top_namespace) } + end + + # @api private + def evaluated_key(key, options) + return key unless key.include?(LOCALE_TOKEN) + + key % {locale: options[:locale] || default_locale} + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/namespaced_rule.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/namespaced_rule.rb new file mode 100644 index 00000000..8a62821f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/namespaced_rule.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +module Dry + module Schema + # A special rule type that is configured under a specified namespace + # + # This is used internally to create rules that can be properly handled + # by the message compiler in situations where a schema reuses another schema + # but it is configured to use a message namespace + # + # @api private + class NamespacedRule + # @api private + attr_reader :rule + + # @api private + attr_reader :namespace + + # @api private + def initialize(namespace, rule) + @namespace = namespace + @rule = rule + end + + # @api private + def call(input) + result = rule.call(input) + Logic::Result.new(result.success?) { [:namespace, [namespace, result.to_ast]] } + end + + # @api private + def ast(input = Undefined) + [:namespace, [namespace, rule.ast(input)]] + end + alias_method :to_ast, :ast + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/params.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/params.rb new file mode 100644 index 00000000..d416b5aa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/params.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Dry + module Schema + # Params schema type + # + # @see Processor + # @see Schema#Params + # + # @api public + class Params < Processor + config.key_map_type = :stringified + config.type_registry_namespace = :params + config.filter_empty_string = true + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/path.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/path.rb new file mode 100644 index 00000000..ab980ce6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/path.rb @@ -0,0 +1,107 @@ +# frozen_string_literal: true + +require "dry/schema/constants" + +module Dry + module Schema + # Path represents a list of keys in a hash + # + # @api private + class Path + include ::Dry.Equalizer(:keys) + include ::Comparable + include ::Enumerable + + # @return [Array] + attr_reader :keys + + alias_method :root, :first + + # Coerce a spec into a path object + # + # @param [Path, Symbol, String, Hash, Array] spec + # + # @return [Path] + # + # @api private + def self.call(spec) + case spec + when ::Symbol, ::Array + new([*spec]) + when ::String + new(spec.split(DOT).map(&:to_sym)) + when ::Hash + new(keys_from_hash(spec)) + when self + spec + else + raise ::ArgumentError, "+spec+ must be either a Symbol, Array, Hash or a #{name}" + end + end + + # @api private + def self.[](spec) + call(spec) + end + + # Extract a list of keys from a hash + # + # @api private + def self.keys_from_hash(hash) + hash.inject([]) { |a, (k, v)| + v.is_a?(::Hash) ? a.push(k, *keys_from_hash(v)) : a.push(k, v) + } + end + + # @api private + def initialize(keys) + @keys = keys + end + + # @api private + def to_h(value = EMPTY_ARRAY.dup) + value = [value] unless value.is_a?(::Array) + + keys.reverse_each.reduce(value) { |result, key| {key => result} } + end + + # @api private + def each(&) + keys.each(&) + end + + # @api private + def include?(other) + keys[0, other.keys.length].eql?(other.keys) + end + + # @api private + def <=>(other) + return keys.length <=> other.keys.length if include?(other) || other.include?(self) + + first_uncommon_index = (self & other).keys.length + + keys[first_uncommon_index] <=> other.keys[first_uncommon_index] + end + + # @api private + def &(other) + self.class.new( + keys.take_while.with_index { |key, index| other.keys[index].eql?(key) } + ) + end + + # @api private + def last + keys.last + end + + # @api private + def same_root?(other) + root.equal?(other.root) + end + + EMPTY = new(EMPTY_ARRAY).freeze + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/predicate.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/predicate.rb new file mode 100644 index 00000000..7a6a0c82 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/predicate.rb @@ -0,0 +1,102 @@ +# frozen_string_literal: true + +require "dry/core/equalizer" +require "dry/logic/operators" + +module Dry + module Schema + # Predicate objects used within the DSL + # + # @api public + class Predicate + # A negated predicate + # + # @api private + class Negation + include ::Dry::Logic::Operators + + # @api private + attr_reader :predicate + + # @api private + def initialize(predicate) + @predicate = predicate + end + + # Dump negated predicate to an AST + # + # @return [Array] + # + # @api private + def to_ast(...) + [:not, predicate.to_ast(...)] + end + alias_method :ast, :to_ast + end + + include ::Dry::Logic::Operators + include ::Dry::Equalizer(:name, :args, :block) + + # @api private + attr_reader :compiler + + # @api private + attr_reader :name + + # @api private + attr_reader :args + + # @api private + attr_reader :arity + + # @api private + attr_reader :block + + # @api private + def initialize(compiler, name, args, block) + @compiler = compiler + @name = name + @args = args + @block = block + # Cater for optional second argument like in case of `eql?` or `respond_to?` + @arity = compiler.predicates[name].arity.abs + end + + # Negate a predicate + # + # @example + # required(:name).value(:string) { !empty? } + # + # @return [Negation] + # + # @api public + def ! + Negation.new(self) + end + + # @api private + def ensure_valid + if arity - 1 != args.size + raise ::ArgumentError, "#{name} predicate arity is invalid" + end + end + + # Compile predicate to a rule object + # + # @api private + def to_rule + compiler.visit(to_ast) + end + + # Dump predicate to an AST + # + # @return [Array] + # + # @api private + def to_ast(*) + [:predicate, [name, compiler.predicates.arg_list(name, *args)]] + end + alias_method :ast, :to_ast + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/predicate_inferrer.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/predicate_inferrer.rb new file mode 100644 index 00000000..8518c10c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/predicate_inferrer.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Dry + module Schema + # @api private + class PredicateInferrer < ::Dry::Types::PredicateInferrer + Compiler = ::Class.new(superclass::Compiler) + + def initialize(registry = PredicateRegistry.new) + super + + @compiler = Compiler.new(registry) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/predicate_registry.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/predicate_registry.rb new file mode 100644 index 00000000..5ce60d66 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/predicate_registry.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Dry + module Schema + # A registry with predicate objects from `Dry::Logic::Predicates` + # + # @api private + class PredicateRegistry < ::Dry::Types::PredicateRegistry + # @api private + def arg_list(name, *values) + predicate = self[name] + # Cater for optional second argument like in case of `eql?` or `respond_to?` + arity = predicate.arity.abs + + predicate + .parameters + .map(&:last) + .zip(values + ::Array.new(arity - values.size, Undefined)) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/primitive_inferrer.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/primitive_inferrer.rb new file mode 100644 index 00000000..daa4b8d2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/primitive_inferrer.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Dry + module Schema + # @api private + class PrimitiveInferrer < ::Dry::Types::PrimitiveInferrer + Compiler = ::Class.new(superclass::Compiler) + + def initialize + super + + @compiler = Compiler.new + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/processor.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/processor.rb new file mode 100644 index 00000000..cfb2b85c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/processor.rb @@ -0,0 +1,213 @@ +# frozen_string_literal: true + +require "dry/initializer" + +module Dry + module Schema + # Processes input data using objects configured within the DSL + # Processing is split into steps represented by `ProcessorSteps`. + # + # @see ProcessorSteps + # @see Params + # @see JSON + # + # @api public + class Processor + extend ::Dry::Initializer + extend ::Dry::Configurable + + include ::Dry::Logic::Operators + + setting :key_map_type + setting :type_registry_namespace, default: :strict + setting :filter_empty_string, default: false + + option :steps, default: -> { ProcessorSteps.new } + + option :schema_dsl + + class << self + # Return DSL configured via #define + # + # @return [DSL] + # @api private + attr_reader :definition + + # Define a schema for your processor class + # + # @see Schema#define + # @see Schema#Params + # @see Schema#JSON + # + # @return [Class] + # + # @api public + def define(&) + @definition ||= DSL.new( + processor_type: self, parent: superclass.definition, **config.to_h, & + ) + self + end + + # Build a new processor object + # + # @return [Processor] + # + # @api public + def new(options = nil) + if options || block_given? + processor = super(**(options || EMPTY_HASH)) + yield(processor) if block_given? + processor + elsif definition + definition.call + else + raise ::ArgumentError, "Cannot create a schema without a definition" + end + end + end + + # Apply processing steps to the provided input + # + # @param [Hash] input + # + # @return [Result] + # + # @api public + def call(input) + Result.new(input.dup, message_compiler: message_compiler) do |result| + steps.call(result) + end + end + alias_method :[], :call + + # @api public + def xor(_other) + raise ::NotImplementedError, "composing schemas using `xor` operator is not supported yet" + end + alias_method :^, :xor + + # Merge with another schema + # + # @param [Processor] other + # + # @return [Processor, Params, JSON] + # + # @api public + def merge(other) + schema_dsl.merge(other.schema_dsl).() + end + + # Return a proc that acts like a schema object + # + # @return [Proc] + # + # @api public + def to_proc + ->(input) { call(input) } + end + + # Return string representation + # + # @return [String] + # + # @api public + def inspect + <<~STR.strip + #<#{self.class.name} keys=#{key_map.map(&:dump)} rules=#{rules.transform_values(&:to_s)}> + STR + end + + # Return the key map + # + # @return [KeyMap] + # + # @api public + def key_map + steps.key_map + end + + # Return the type schema + # + # @return [Dry::Types::Lax] + # + # @api private + def type_schema + steps.type_schema + end + + # Return type schema used when composing subschemas + # + # @return [Dry::Types::Schema] + # + # @api private + def strict_type_schema + schema_dsl.strict_type_schema + end + + # Return the rule applier + # + # @api private + def rule_applier + steps.rule_applier + end + alias_method :to_rule, :rule_applier + + # Return the rules config + # + # @return [Dry::Types::Config] + # + # @api private + def config + @config ||= rule_applier.config + end + + # Return AST representation of the rules + # + # @api private + def to_ast(*) + rule_applier.to_ast + end + alias_method :ast, :to_ast + + # Return the message compiler + # + # @return [MessageCompiler] + # + # @api private + def message_compiler + rule_applier.message_compiler + end + + # Return the rules from rule applier + # + # @return [MessageCompiler] + # + # @api private + def rules + rule_applier.rules + end + + # Return the types from the schema DSL + # + # @api private + def types + schema_dsl.types + end + + # Check if there are filter rules + # + # @api private + def filter_rules? + @filter_rules_predicate ||= schema_dsl.filter_rules? + end + + # Return filter schema + # + # @api private + def filter_schema + @filter_schema ||= schema_dsl.filter_schema + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/processor_steps.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/processor_steps.rb new file mode 100644 index 00000000..6c774b5e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/processor_steps.rb @@ -0,0 +1,141 @@ +# frozen_string_literal: true + +require "dry/initializer" +require "dry/schema/constants" + +module Dry + module Schema + # Steps for the Dry::Schema::Processor + # + # There are 4 main steps: + # + # 1. `key_coercer` - Prepare input hash using a key map + # 2. `filter_schema` - Apply pre-coercion filtering rules + # (optional step, used only when `filter` was used) + # 3. `value_coercer` - Apply value coercions based on type specifications + # 4. `rule_applier` - Apply rules + # + # @see Processor + # + # @api public + class ProcessorSteps + extend ::Dry::Initializer + + option :steps, default: -> { EMPTY_HASH.dup } + option :before_steps, default: -> { EMPTY_HASH.dup } + option :after_steps, default: -> { EMPTY_HASH.dup } + + # Executes steps and callbacks in order + # + # @param [Result] result + # + # @return [Result] + # + # @api public + def call(result) + STEPS_IN_ORDER.each do |name| + before_steps[name]&.each { |step| step&.(result) } + steps[name]&.(result) + after_steps[name]&.each { |step| step&.(result) } + end + + result + end + + # @api private + def rule_applier + @rule_applier ||= steps[:rule_applier].executor + end + + # @api private + def key_map + @key_map ||= self[:key_coercer].executor.key_map + end + + # @api private + def type_schema + @type_schema ||= steps[:value_coercer].executor.type_schema + end + + # Returns step by name + # + # @param [Symbol] name The step name + # + # @api public + def [](name) + steps[name] + end + + # Sets step by name + # + # @param [Symbol] name The step name + # + # @api public + def []=(name, value) + steps[name] = Step.new(type: :core, name: name, executor: value) + end + + # Add passed block before mentioned step + # + # @param [Symbol] name The step name + # + # @return [ProcessorSteps] + # + # @api public + def after(name, &block) + after_steps[name] ||= EMPTY_ARRAY.dup + after_steps[name] << Step.new(type: :after, name: name, executor: block) + after_steps[name].sort_by!(&:path) + self + end + + # Add passed block before mentioned step + # + # @param [Symbol] name The step name + # + # @return [ProcessorSteps] + # + # @api public + def before(name, &block) + before_steps[name] ||= EMPTY_ARRAY.dup + before_steps[name] << Step.new(type: :before, name: name, executor: block) + before_steps[name].sort_by!(&:path) + self + end + + # Stacks callback steps and returns new ProcessorSteps instance + # + # @param [ProcessorSteps] other + # + # @return [ProcessorSteps] + # + # @api public + def merge(other) + ProcessorSteps.new( + before_steps: merge_callbacks(before_steps, other.before_steps), + after_steps: merge_callbacks(after_steps, other.after_steps) + ) + end + + # @api private + def merge_callbacks(left, right) + left.merge(right) do |_key, oldval, newval| + (oldval + newval).sort_by(&:path) + end + end + + # @api private + def import_callbacks(path, other) + other.before_steps.each do |name, steps| + before_steps[name] ||= [] + before_steps[name].concat(steps.map { |step| step.scoped(path) }).sort_by!(&:path) + end + + other.after_steps.each do |name, steps| + after_steps[name] ||= [] + after_steps[name].concat(steps.map { |step| step.scoped(path) }).sort_by!(&:path) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/result.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/result.rb new file mode 100644 index 00000000..2025e217 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/result.rb @@ -0,0 +1,203 @@ +# frozen_string_literal: true + +require "dry/initializer" +require "dry/core/equalizer" + +module Dry + module Schema + # Processing result + # + # @see Processor#call + # + # @api public + class Result + include ::Dry::Equalizer(:output, :errors) + + extend ::Dry::Initializer[undefined: false] + + # @api private + param :output, reader: false + + # A list of failure ASTs produced by rule result objects + # + # @api private + option :result_ast, default: -> { EMPTY_ARRAY.dup } + + # @api private + option :message_compiler + + # @api private + option :path, optional: true, reader: false + + # @api private + def self.new(*, **) + result = super + yield(result) if block_given? + result.freeze + end + + # Return a new result scoped to a specific path + # + # @param path [Symbol, Array, Path] + # + # @return [Result] + # + # @api private + def at(at_path, &) + new(@output, path: Path.new([*path, *Path[at_path]]), &) + end + + # @api private + def new(output, **opts, &) + self.class.new( + output, + message_compiler: message_compiler, + result_ast: result_ast, + **opts, + & + ) + end + + # @api private + def update(hash) + output.update(hash) + self + end + + # @api private + def path + @path || Path::EMPTY + end + + # Dump result to a hash returning processed and validated data + # + # @return [Hash] + # + # @api private + def output + path.equal?(Path::EMPTY) ? @output : @output.dig(*path) + end + alias_method :to_h, :output + + # @api private + def replace(value) + if value.is_a?(output.class) + output.replace(value) + elsif path.equal?(Path::EMPTY) + @output = value + else + value_holder = path.keys.length > 1 ? @output.dig(*path.to_a[0..-2]) : @output + + value_holder[path.last] = value + end + + self + end + + # @api private + def concat(other) + result_ast.concat(other.map(&:to_ast)) + self + end + + # Read value from the output hash + # + # @param [Symbol] name + # + # @return [Object] + # + # @api public + def [](name) + output[name] + end + + # Check if a given key is present in the output + # + # @param [Symbol] name + # + # @return [Boolean] + # + # @api public + def key?(name) + output.key?(name) + end + + # Check if there's an error for the provided spec + # + # @param [Symbol, HashSymbol>] spec + # + # @return [Boolean] + # + # @api public + def error?(spec) + message_set.any? { |msg| Path[msg.path].include?(Path[spec]) } + end + + # Check if the result is successful + # + # @return [Boolean] + # + # @api public + def success? + result_ast.empty? + end + + # Check if the result is not successful + # + # @return [Boolean] + # + # @api public + def failure? + !success? + end + + # Get human-readable error representation + # + # @see #message_set + # + # @return [MessageSet] + # + # @api public + def errors(options = EMPTY_HASH) + message_set(options) + end + + # Return the message set + # + # @param [Hash] options + # @option options [Symbol] :locale Alternative locale (default is :en) + # @option options [Boolean] :hints Whether to include hint messages or not + # @option options [Boolean] :full Whether to generate messages that include key names + # + # @return [MessageSet] + # + # @api public + def message_set(options = EMPTY_HASH) + message_compiler.with(options).(result_ast) + end + + # Return a string representation of the result + # + # @return [String] + # + # @api public + def inspect + "#<#{self.class}#{to_h.inspect} errors=#{errors.to_h.inspect} path=#{path.keys.inspect}>" + end + + # Pattern matching support + # + # @api private + def deconstruct_keys(_) + output + end + + # Add a new error AST node + # + # @api private + def add_error(node) + result_ast << node + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/rule_applier.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/rule_applier.rb new file mode 100644 index 00000000..32cbfb44 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/rule_applier.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require "dry/initializer" +require "dry/schema/constants" + +module Dry + module Schema + # Applies rules defined within the DSL + # + # @api private + class RuleApplier + extend ::Dry::Initializer + + # @api private + param :rules + + # @api private + option :config, default: -> { Schema.config.dup } + + # @api private + option :message_compiler, default: -> { MessageCompiler.new(Messages.setup(config.messages)) } + + # @api private + def call(input) + results = EMPTY_ARRAY.dup + + rules.each do |name, rule| + next if input.error?(name) + + result = rule.(input.to_h) + results << result if result.failure? + end + + input.concat(results) + end + + # @api private + def to_ast + if config.messages.namespace + [:namespace, [config.messages.namespace, [:set, rules.values.map(&:to_ast)]]] + else + [:set, rules.values.map(&:to_ast)] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/step.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/step.rb new file mode 100644 index 00000000..3c43fba5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/step.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +require "dry/schema/constants" + +module Dry + module Schema + # @api private + class Step + # @api private + attr_reader :name + + # @api private + attr_reader :type + + # @api private + attr_reader :executor + + # @api private + attr_reader :path + + # @api private + def initialize(type:, name:, executor:, path: Path::EMPTY) + @type = type + @name = name + @executor = executor + @path = path + validate_name(name) + end + + # @api private + def call(result) + scoped_result = path.equal?(Path::EMPTY) ? result : result.at(path) + + output = executor.(scoped_result) + scoped_result.replace(output) if output.is_a?(Hash) + output + end + + # @api private + def scoped(parent_path) + self.class.new( + type: type, + name: name, + executor: executor, + path: Path.new([*parent_path, *path]) + ) + end + + private + + # @api private + def validate_name(name) + return if STEPS_IN_ORDER.include?(name) + + raise ArgumentError, "Undefined step name #{name}. Available names: #{STEPS_IN_ORDER}" + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/trace.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/trace.rb new file mode 100644 index 00000000..da331018 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/trace.rb @@ -0,0 +1,112 @@ +# frozen_string_literal: true + +module Dry + module Schema + # Captures predicates defined within the DSL + # + # @api private + class Trace < ::BasicObject + INVALID_PREDICATES = %i[key?].freeze + + include ::Dry::Equalizer(:compiler, :captures) + + undef eql? + + # @api private + attr_reader :compiler + + # @api private + attr_reader :captures + + # @api private + def initialize(compiler = Compiler.new) + @compiler = compiler + @captures = [] + end + + # @api private + def evaluate(*args, **opts) + predicates = opts.empty? ? args : args.push(opts) + + evaluate_predicates(predicates).each do |rule| + append(rule) + end + + self + end + + # @api private + def evaluate_predicates(predicates) + predicates.flat_map do |predicate| + if predicate.respond_to?(:call) + predicate + elsif predicate.is_a?(::Array) + predicate.map { |pred| evaluate_predicates(pred).reduce(:&) }.reduce(:|) + elsif predicate.is_a?(::Hash) + predicate.map { |pred, *args| __send__(pred, *args) } + else + __send__(predicate) + end + end + end + + # @api private + def append(op) + captures << op + self + end + alias_method :<<, :append + + # @api private + def to_rule(name = nil) + return if captures.empty? + + if name + compiler.visit([:key, [name, to_ast]]) + else + reduced_rule + end + end + + # @api private + def to_ast + reduced_rule.to_ast + end + + # @api private + def class + ::Dry::Schema::Trace + end + + private + + # @api private + def reduced_rule + captures.map(&:to_ast).map(&compiler.method(:visit)).reduce(:and) + end + + def respond_to_missing?(meth, include_private = false) + super || (meth.to_s.end_with?(QUESTION_MARK) && compuiler.support?(meth)) + end + + # @api private + def method_missing(meth, *args, &block) + if meth.to_s.end_with?(QUESTION_MARK) + if ::Dry::Schema::Trace::INVALID_PREDICATES.include?(meth) + ::Kernel.raise InvalidSchemaError, "#{meth} predicate cannot be used in this context" + end + + unless compiler.support?(meth) + ::Kernel.raise ::ArgumentError, "#{meth} predicate is not defined" + end + + predicate = Predicate.new(compiler, meth, args, block) + predicate.ensure_valid + predicate + else + super + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/type_container.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/type_container.rb new file mode 100644 index 00000000..b9c92338 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/type_container.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require "dry/core/container" +require "dry/types" + +module Dry + module Schema + # A class to build containers for custom types, which can be used in schemas + # + # @example + # MyTypeContainer = Dry::Schema::TypeContainer.new + # MyTypeContainer.register('params.fancy_string', Types::FancyString) + # + # @api public + class TypeContainer + include ::Dry::Core::Container::Mixin + + def initialize(types_container = ::Dry::Types.container) + super() + + merge(types_container) + end + + alias_method :registered?, :key? + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/type_registry.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/type_registry.rb new file mode 100644 index 00000000..0b6c8669 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/type_registry.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require "dry/schema/constants" +require "dry/schema/types" + +module Dry + module Schema + # A simple wrapper around Dry::Types registry + # + # This is used internally by specialized processor sub-classes + # + # @api private + class TypeRegistry + # @api private + attr_reader :types + + # @api private + attr_reader :namespace + + # @api private + def self.new(types = ::Dry::Types, namespace = :strict) + super + end + + # @api private + def initialize(types, namespace = :strict) + @types = types + @namespace = namespace + end + + # @api private + def namespaced(ns) + self.class.new(types, ns) + end + + # @api private + def [](name) + key = [namespace, name].compact.join(DOT) + + types.registered?(key) ? types[key] : types[name.to_s] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/types.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/types.rb new file mode 100644 index 00000000..25d8fb72 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/types.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require "dry/types" + +module Dry + module Schema + # Schema's own type registry + # + # @api public + module Types + include ::Dry.Types + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/types_merger.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/types_merger.rb new file mode 100644 index 00000000..a96a5f10 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/types_merger.rb @@ -0,0 +1,139 @@ +# frozen_string_literal: true + +module Dry + module Schema + # Combines multiple logical operations into a single type, taking into + # account the type of logical operation (or, and, implication) and the + # underlying types (schemas, nominals, etc.) + # + # @api private + class TypesMerger + attr_reader :type_registry + + # @api private + class ValueMerger + attr_reader :types_merger + attr_reader :op_class + attr_reader :old + attr_reader :new + + # @api private + def initialize(types_merger, op_class, old, new) + @types_merger = types_merger + @op_class = op_class + @old = old + @new = new + end + + # @api private + def call + if op_class <= ::Dry::Logic::Operations::Or + merge_or + elsif op_class <= ::Dry::Logic::Operations::And + merge_and + elsif op_class <= ::Dry::Logic::Operations::Implication + merge_implication + else + raise ::ArgumentError, <<~MESSAGE + Can't merge operations, op_class=#{op_class} + MESSAGE + end + end + + private + + # @api private + def merge_or + old | new + end + + # @api private + def merge_ordered + return old if old == new + + unwrapped_old, old_rule = unwrap_type(old) + unwrapped_new, new_rule = unwrap_type(new) + + type = merge_unwrapped_types(unwrapped_old, unwrapped_new) + + rule = [old_rule, new_rule].compact.reduce { op_class.new(_1, _2) } + + type = ::Dry::Types::Constrained.new(type, rule: rule) if rule + + type + end + + alias_method :merge_and, :merge_ordered + alias_method :merge_implication, :merge_ordered + + # @api private + def merge_unwrapped_types(unwrapped_old, unwrapped_new) + case [unwrapped_old, unwrapped_new] + in ::Dry::Types::Schema, ::Dry::Types::Schema + merge_schemas(unwrapped_old, unwrapped_new) + in [::Dry::Types::AnyClass, _] | [::Dry::Types::Hash, ::Dry::Types::Schema] + unwrapped_new + in [::Dry::Types::Schema, ::Dry::Types::Hash] | [_, ::Dry::Types::AnyClass] + unwrapped_old + else + merge_equivalent_types(unwrapped_old, unwrapped_new) + end + end + + # @api private + def merge_schemas(unwrapped_old, unwrapped_new) + types_merger.type_registry["hash"].schema( + types_merger.call( + op_class, + unwrapped_old.name_key_map, + unwrapped_new.name_key_map + ) + ) + end + + # @api private + def merge_equivalent_types(unwrapped_old, unwrapped_new) + if unwrapped_old.primitive <= unwrapped_new.primitive + unwrapped_new + elsif unwrapped_new.primitive <= unwrapped_old.primitive + unwrapped_old + else + raise ::ArgumentError, <<~MESSAGE + Can't merge types, unwrapped_old=#{unwrapped_old.inspect}, unwrapped_new=#{unwrapped_new.inspect} + MESSAGE + end + end + + # @api private + def unwrap_type(type) + rules = [] + + loop do + rules << type.rule if type.respond_to?(:rule) + + if type.optional? + type = type.left.primitive?(nil) ? type.right : type.left + elsif type.is_a?(::Dry::Types::Decorator) + type = type.type + else + break + end + end + + [type, rules.reduce(:&)] + end + end + + def initialize(type_registry = TypeRegistry.new) + @type_registry = type_registry + end + + # @api private + def call(op_class, lhs, rhs) + lhs.merge(rhs) do |_k, old, new| + ValueMerger.new(self, op_class, old, new).call + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/value_coercer.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/value_coercer.rb new file mode 100644 index 00000000..bb51f4c4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/value_coercer.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require "dry/core/equalizer" +require "dry/initializer" + +module Dry + module Schema + # Used by the processors to coerce values in the input hash + # + # @api private + class ValueCoercer + extend ::Dry::Initializer + include ::Dry::Equalizer(:type_schema) + + # @api private + param :type_schema + + # @api private + def call(input) + if input.success? + type_schema[input.to_h] + else + type_schema.each_with_object(EMPTY_HASH.dup) do |key, hash| + name = key.name + + next unless input.key?(name) + + value = input[name] + + hash[name] = input.error?(name) ? value : key[value] + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/version.rb b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/version.rb new file mode 100644 index 00000000..5763d05a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-schema-1.14.1/lib/dry/schema/version.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module Dry + module Schema + VERSION = "1.14.1" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/CHANGELOG.md b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/CHANGELOG.md new file mode 100644 index 00000000..3d5789b8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/CHANGELOG.md @@ -0,0 +1,1178 @@ + + +## 1.8.3 2025-06-09 + + +### Fixed + +- Raise error on passing a non-module object to Instance (ref #480) (@flash-gordon) + + +[Compare v1.8.2...v1.8.3](https://github.com/dry-rb/dry-types/compare/v1.8.2...v1.8.3) + +## 1.8.2 2025-01-31 + + +### Fixed + +- Syntax errors on 3.3.0 (@flash-gordon, see #478) + + +[Compare v1.8.1...v1.8.2](https://github.com/dry-rb/dry-types/compare/v1.8.1...v1.8.2) + +## 1.8.1 2025-01-21 + + +### Fixed + +- Warnings about unused block arguments (@flash-gordon, #477) + + +[Compare v1.8.0...v1.8.1](https://github.com/dry-rb/dry-types/compare/v1.8.0...v1.8.1) + +## 1.8.0 2025-01-06 + + +### Added + +- Added `Enum#each_value` to iterate over enum values (@CharlieWWW94 in #471) + +### Fixed + +- Fixed `Default#try` to return correct result (@elcuervo + @flash-gordon in #475) + +### Changed + +- Set min Ruby version to 3.1 (@flash-gordon) +- Better representation of Enum types (@flash-gordon, see #460) + +[Compare v1.7.2...v1.8.0](https://github.com/dry-rb/dry-types/compare/v1.7.2...v1.8.0) + +## 1.7.2 2024-01-05 + + +### Fixed + +- Fixed BigDecimal warning due to not being required in gemspec (@bkuhlmann in #464) + + +[Compare v1.7.1...v1.7.2](https://github.com/dry-rb/dry-types/compare/v1.7.1...v1.7.2) + +## 1.7.1 2023-02-17 + + +### Fixed + +- Warning from jruby about overwritten keyword (@flash-gordon + @klobuczek in #454) + + +[Compare v1.7.0...v1.7.1](https://github.com/dry-rb/dry-types/compare/v1.7.0...v1.7.1) + +## 1.7.0 2022-11-04 + + +### Changed + +- This version is compatible with recently released dry-rb dependencies (@flash-gordon) +- Updated to dry-core 1.0 (@flash-gordon + @solnic) +- Dependency on dry-container was dropped (@flash-gordon) + +[Compare v1.6.1...v1.7.0](https://github.com/dry-rb/dry-types/compare/v1.6.1...v1.7.0) + +## 1.6.1 2022-10-15 + + +### Changed + +- Fix issues with internal const_missing and Inflector/Module constants (@flash-gordon + @solnic) + +[Compare v1.6.0...v1.6.1](https://github.com/dry-rb/dry-types/compare/v1.6.0...v1.6.1) + +## 1.6.0 2022-10-15 + + +### Changed + +- Optimize `PredicateRegistry` for Ruby 2.7+ (see #420 for more details) (@casperisfine) +- Use zeitwerk for auto-loading (@flash-gordon) + +[Compare v1.5.1...v1.6.0](https://github.com/dry-rb/dry-types/compare/v1.5.1...v1.6.0) + +## 1.5.1 2021-02-16 + + +### Fixed + +- Add missing requires for internal usage of `Dry::Equalizer` (@timriley in #418) + + +[Compare v1.5.0...v1.5.1](https://github.com/dry-rb/dry-types/compare/v1.5.0...v1.5.1) + +## 1.5.0 2021-01-21 + + +### Added + +- Wrapping constructor types :tada: (@flash-gordon) + + Constructor blocks can have a second argument. + The second argument is the underlying type itself: + ```ruby + age_from_year = Dry::Types['coercible.integer'].constructor do |input, type| + Date.today.year - type.(input) + end + age_from_year.('2000') # => 21 + ``` + With wrapping constructors you have control over "type application". You can even + run it more than once: + ```ruby + inc = Dry::Types['integer'].constructor(&:succ) + inc2x = inc.constructor { _2.(_2.(_2.(_1))) } + inc2x.(10) # => 13 + ``` +- Fallbacks :tada: (@flash-gordon) + + ```ruby + age = Dry::Types['coercible.ineger'].fallback(18) + age.('10') # => 10 + age.('20') # => 20 + age.('abc') # => 18 + ``` + + Fallbacks are different from default values: the later will be evaluated + only when *no input* provided. + + Under the hood, `.fallback` creates a wrapping constructor. +- `params.string` as an alias for `strict.string`. This addition should be non-breaking (@flash-gordon) +- API for defining custom type builders similar to `.default`, `.constructor`, or `.optional` (@flash-gordon) + + ```ruby + # Making an alias for `.fallback` + Dry::Types.define_builder(:or) { |type, v| type.fallback(v) } + + # Using new builder + type = Dry::Types['integer'].or(-273) + type.(:invalid) # => -273 + ``` + +### Changed + +- Inferring predicates from class names is deprecated. It's very unlikely your code depends on it, + however, if it does, you'll get an exception with instructions. (@flash-gordon) + + If you don't rely on inferring, just disable it with: + + ```ruby + Dry::Types::PredicateInferrer::Compiler.infer_predicate_by_class_name false + ``` + + Otherwise, enable it explicitly: + + ```ruby + Dry::Types::PredicateInferrer::Compiler.infer_predicate_by_class_name true + ``` + +[Compare v1.4.0...v1.5.0](https://github.com/dry-rb/dry-types/compare/v1.4.0...v1.5.0) + +## 1.4.0 2020-03-09 + + +### Fixed + +- `json.nil` no longer coerces empty strings to `nil`. It was a long-standing +bug that for some reason remained unnoticed for years. Technically, +this may be a breaking change for JSON schemas described with dry-schema (@flash-gordon) + + +[Compare v1.3.1...v1.4.0](https://github.com/dry-rb/dry-types/compare/v1.3.1...v1.4.0) + +## 1.3.1 2020-02-17 + + +### Changed + +- Predicate inferrer now returns `hash?` for hash schemas. Note, it doesn't spit more complex preds because we have different plans for dry-schema (@flash-gordon) + +[Compare v1.3.0...v1.3.1](https://github.com/dry-rb/dry-types/compare/v1.3.0...v1.3.1) + +## 1.3.0 2020-02-10 + + +### Added + +- `Schema#merge` for merging two hash schemas (@waiting-for-dev) +- Aliases for `.constructor` to non-constructor types. Now you can call `.prepend`/`.append` without silly checks for the type being a constructor (flash-gordon) + ```ruby + (Dry::Types['integer'].prepend(-> { _1 + 1 })).(1) # => 2 + (Dry::Types['coercible.integer'] >> -> { _1 * 2 }).('99') # => 198 + ``` +- `Hash::Schema#clear` returns a schema with the same options but without keys +- Optional namespace now includes strict types by default (@flash-gordon) + +### Fixed + +- `Schema::Key#optional` returns an instance of `Schema::Key` as it should have done +- Composition with function handling exceptions. This could occasionally lead to unexpected exceptions (@flash-gordon) + + +[Compare v1.2.2...v1.3.0](https://github.com/dry-rb/dry-types/compare/v1.2.2...v1.3.0) + +## 1.2.2 2019-12-14 + + +### Fixed + +- `Types.Contructor` doesn't re-wrap class instances implementing type interface, this fixes some quirks in dry-struct (@flash-gordon) + +### Changed + +- Types now use immutable equalizers. This should improve performance in certain cases e.g. in ROM (flash-gordon) +- Attempting to use non-symbol keys in hash schemas raises an error. We always supported only symbols as keys but there was no check, now it'll throw an argument error. If you want to convert strings to symbols, use `Hash#with_key_transform` (flash-gordon) +- Params and JSON types accept Time/Date/Datetime instances and boolean values. This can be useful in tests but we discourage you from relying on this behavior in production code. For example, building structs with `Params` types is considered a smell. There are dedicated tools for coercion, namely dry-schema and dry-validation. Be responsible user of dry-types! ❤ (flash-gordon) + +[Compare v1.2.1...v1.2.2](https://github.com/dry-rb/dry-types/compare/v1.2.1...v1.2.2) + +## 1.2.1 2019-11-07 + + +### Fixed + +- Fix keyword warnings reported by Ruby 2.7 (flash-gordon) +- Error type in failing case in `Array::Member` (esparta) + + +[Compare v1.2.0...v1.2.1](https://github.com/dry-rb/dry-types/compare/v1.2.0...v1.2.1) + +## 1.2.0 2019-10-06 + + +### Added + +- `Optional::Params` types that coerce empty strings to `nil` (flash-gordon) + ```ruby + Dry::Types['optional.params.integer'].('') # => nil + Dry::Types['optional.params.integer'].('140') # => 140 + Dry::Types['optional.params.integer'].('asd') # => exception! + ``` + Keep in mind, `Dry::Types['optional.params.integer']` and `Dry::Types['params.integer'].optional` are not the same, the latter doesn't handle empty strings. +- Predicate inferrer was ported from dry-schema (authored by solnic) + ```ruby + require 'dry/types/predicate_inferrer' + Dry::Types::PredicateInferrer.new[Types::String] + # => [:str?] + Dry::Types::PredicateInferrer.new[Types::String | Types::Integer] + # => [[[:str?], [:int?]]] + ``` + Note that the API of the predicate inferrer can change in the stable version, it's dictated by the needs of dry-schema so it should be considered as semi-stable. If you depend on it, write specs covering the desired behavior. Another option is copy-and-paste the whole thing to your project. +- Primitive inferrer was ported from dry-schema (authored by solnic) + ```ruby + require 'dry/types/primitive_inferrer' + Dry::Types::PrimitiveInferrer.new[Types::String] + # => [String] + Dry::Types::PrimitiveInferrer.new[Types::String | Types::Integer] + # => [String, Integer] + Dry::Types::PrimitiveInferrer.new[Types::String.optional] + # => [NilClass, String] + ``` + The primitive inferrer should be stable by now, you can rely on it. +- The `monads` extension adds `Dry::Types::Result#to_monad`. This makes it compatible with do notation from dry-monads. Load it with `Dry::Types.load_extensions(:monads)` (skryukov) + + ```ruby + Types = Dry.Types + Dry::Types.load_extensions(:monads) + + class AddTen + include Dry::Monads[:result, :do] + + def call(input) + integer = yield Types::Coercible::Integer.try(input) + + Success(integer + 10) + end + end + ``` + +### Fixed + +- Bug with using a `Bool`-named struct as a schema key (flash-gordon) +- A bunch of issues related to using `meta` on complex types (flash-gordon) +- `Types.Constructor(...)` returns a `Types::Array` as it should (flash-gordon) + +### Changed + +- `Dry::Types.[]` used to work with classes, now it's deprecated (flash-gordon) + +[Compare v1.1.1...v1.2.0](https://github.com/dry-rb/dry-types/compare/v1.1.1...v1.2.0) + +## 1.1.1 2019-07-26 + + +### Fixed + +- A bug where meta was lost for lax array types (flash-gordon) + + +[Compare v1.1.0...v1.1.1](https://github.com/dry-rb/dry-types/compare/v1.1.0...v1.1.1) + +## 1.1.0 2019-07-02 + + +### Added + +- New builder method `Interface` constructs a type which accepts objects that respond to the given methods (waiting-for-dev) + ```ruby + Types = Dry.Types() + Types::Callable = Types.Interface(:call) + Types::Callable.valid?(Object.new) # => false + Types::Callable.valid?(proc {}) # => true + ``` +- New types: `coercible.symbol`, `params.symbol`, and `json.symbol`, all use `.to_sym` for coercion (waiting-for-dev) + +### Fixed + +- Converting schema keys to maybe types (flash-gordon) +- Using `Schema#key` and `Array#member` on constuctors (flash-gordon) +- Using `meta(omittable: true)` within `transform_types` works again but produces a warning, please migrate to `.omittable` or `.required(false)` (flash-gordon) +- Bug with a constructror defined on top of enum (flash-gordon) + + +[Compare v1.0.1...v1.1.0](https://github.com/dry-rb/dry-types/compare/v1.0.1...v1.1.0) + +## 1.0.1 2019-06-04 + + +### Added + +- In a case of failure the constructor block can now pass a different value (flash-gordon) + ```ruby + not_empty_string = Types::String.constructor do |value, &failure| + value.strip.empty? ? failure.(nil) : value.strip + end + not_empty_string.(' ') { |v| v } # => nil + not_empty_string.lax.(' ') # => nil + not_empty_string.lax.(' foo ') # => "foo" + ``` +- `Schema#strict` now accepts an boolean argument. If `fales` is passed this will turn a strict schema into a non-strict one (flash-gordon) + + +[Compare v1.0.0...v1.0.1](https://github.com/dry-rb/dry-types/compare/v1.0.0...v1.0.1) + +## 1.0.0 2019-04-23 + + +### Added + +- API for custom constructor types was enhanced. If you pass your own callable to `.constructor` it can have a block in its signature. If a block is passed, you must call it on failed coercion, otherwise raise a type coercion error (flash-gordon) + Example: + ```ruby + proc do |input, &block| + if input.is_a? String + Integer(input, 10) + else + Integer(input) + end + rescue ArgumentError, TypeError => error + if block + block.call + else + raise Dry::Types::CoercionError.new( + error.message, + backtrace: error.backtrace + ) + end + end + ``` + This makes the exception handling your job so that dry-types won't have to catch and re-wrap all possible errors (this is not safe, generally speaking). +- Types now can be converted to procs thus you can pass them as blocks (flash-gordon) + ```ruby + %w(1 2 3).map(&Types::Coercible::Integer) + # => [1, 2, 3] + ``` + +### Changed + +- [BREAKING] Behavior of built-in constructor types was changed to be more strict. They will always raise an error on failed coercion (flash-gordon) + Compare: + + ```ruby + # 0.15.0 + Types::Params::Integer.('foo') + # => "foo" + + # 1.0.0 + Types::Params::Integer.('foo') + # => Dry::Types::CoercionError: invalid value for Integer(): "foo" + ``` + + To handle coercion errors `Type#call` now yields a block: + + ```ruby + Types::Params::Integer.('foo') { :invalid } # => :invalid + ``` + + This makes work with coercions more straightforward and way faster. +- [BREAKING] Safe types were renamed to Lax, this name better serves their purpose. The previous name is available but prints a warning (flash-gordon) +- [BREAKING] Metadata is now pushed down to the decorated type. It is not likely you will notice a difference but this a breaking change that enables some use cases in rom related to the usage of default types in relations (flash-gordon) +- Nominal types are now completely unconstrained. This fixes some inconsistencies when using them with constraints. `Nominal#try` will always return a successful result, for the previous behavior use `Nominal#try_coerce` or switch to strict types with passing a block to `#call` (flash-gordon) +- ## Performance improvements +- During the work on this release, a lot of performance improvements were made. dry-types 1.0 combined with dry-logic 1.0 are multiple times faster than dry-types 0.15 and dry-logic 0.5 for common cases including constraints checking and coercion (flash-gordon) + +[Compare v0.15.0...v1.0.0](https://github.com/dry-rb/dry-types/compare/v0.15.0...v1.0.0) + +## 0.15.0 2019-03-22 + + +### Added + +- Improved string representation of types (flash-gordon) + ```ruby + Dry::Types['nominal.integer'] + # => #]> + Dry::Types['params.integer'] + # => # fn=Dry::Types::Coercions::Params.to_int>]> + Dry::Types['hash'].schema(age?: 'integer') + # => # rule=[type?(Integer)]>}> rule=[type?(Hash)]>]> + Dry::Types['array'] + # => # rule=[type?(Integer)]>> rule=[type?(Array)]>]> + ``` +- Options for the list of types you want to import with `Dry.Types` (flash-gordon) + Cherry-pick only certain types: + ```ruby + module Types + include Dry.Types(:strict, :nominal, :coercible) + end + Types.constants + # => [:Strict, :Nominal, :Coercible] + ``` + Change default top-level types: + ```ruby + module Types + include Dry.Types(default: :coercible) + end + # => # fn=Kernel.Integer>]> + ``` + Rename type namespaces: + ```ruby + module Types + include Dry.Types(strict: :Strong, coercible: :Kernel) + end + ``` +- Optional keys for schemas can be provided with ?-ending symbols (flash-gordon) + ```ruby + Dry::Types['hash'].schema(name: 'string', age?: 'integer') + ``` +- Another way of making keys optional is setting `required: false` to meta. In fact, it is the preferable + way if you have to store this information in `meta`, otherwise use the Key's API (see below) (flash-gordon) + ```ruby + Dry::Types['hash'].schema( + name: Dry::Types['string'], + age: Dry::Types['integer'].meta(required: false) + ) + ``` +- Key types have API for making keys omittable and back (flash-gordon) + + ```ruby + # defining a base schema with optional keys + lax_hash = Dry::Types['hash'].with_type_transform { |key| key.required(false) } + # same as + lax_hash = Dry::Types['hash'].with_type_transform(&:omittable) + + # keys in user_schema are not required + user_schema = lax_hash.schema(name: 'string', age: 'integer') + ``` +- `Type#optional?` now recognizes more cases where `nil` is an allowed value (flash-gordon) +- `Constructor#{prepend,append}` with `<<` and `>>` as aliases. `Constructor#append` works the same way `Constructor#constrcutor` does. `Constuctor#prepend` chains functions in the reverse order, see examples (flash-gordon) + + ```ruby + to_int = Types::Coercible::Integer + inc = to_int.append { |x| x + 2 } + inc.("1") # => "1" -> 1 -> 3 + + inc = to_int.prepend { |x| x + "2" } + inc.("1") # => "1" -> "12" -> 12 + ``` +- Partial schema application for cases when you want to validate only a subset of keys (flash-gordon) + This is useful when you want to update a key or two in an already-validated hash. A perfect example is `Dry::Struct#new` where this feature is now used. + ```ruby + schema = Dry::Types['hash'].schema(name: 'string', age: 'integer') + value = schema.(name: 'John', age: 20) + update = schema.apply({ age: 21 }, skip_missing: true) + value.merge(update) + ``` + +### Fixed + +- `Hash::Map` now behaves as a constrained type if its values are constrained (flash-gordon) +- `coercible.integer` now doesn't blow up on invalid strings (exterm) + +### Changed + +- [BREAKING] Internal representation of hash schemas was changed to be a simple list of key types (flash-gordon) + `Dry::Types::Hash#with_type_transform` now yields a key type instead of type + name: + ```ruby + Dry::Types['strict.hash'].with_type_transform { |key| key.name == :age ? key.required(false) : key } + ``` +- [BREAKING] Definition types were renamed to nominal (flash-gordon) +- [BREAKING] Top-level types returned by `Dry::Types.[]` are now strict (flash-gordon) + ```ruby + # before + Dry::Types['integer'] + # => #]> + # now + Dry::Types['integer'] + # => rule=[type?(Integer)]>]> + # you can still access nominal types using namespace + Dry::Types['nominal.integer'] + # => #]> + ``` +- [BREAKING] Default values are not evaluated if the decorated type returns `nil`. They are triggered on `Undefined` instead (GustavoCaso + flash-gordon) +- [BREAKING] Support for old hash schemas was fully removed. This makes dry-types not compatible with dry-validation < 1.0 (flash-gordon) +- `Dry::Types.module` is deprecated in favor of `Dry.Types` (flash-gordon) + Keep in mind `Dry.Types` uses strict types for top-level names, that is after + ```ruby + module Types + include Dry.Types + end + ``` + `Types::Integer` is a strict type. If you want it to be nominal, use `include Dry.Types(default: :nominal)`. See other options below. +- `params.integer` now always converts strings to decimal numbers, this means `09` will be coerced to `9` (threw an error before) (skryukov) +- Ruby 2.3 is EOL and not officially supported. It may work but we don't test it. + +[Compare v0.14.1...v0.15.0](https://github.com/dry-rb/dry-types/compare/v0.14.1...v0.15.0) + +## 0.14.1 2019-03-25 + + +### Fixed + +- `coercible.integer` now doesn't blow up on invalid strings (exterm) + + +[Compare v0.14.0...v0.14.1](https://github.com/dry-rb/dry-types/compare/v0.14.0...v0.14.1) + +## 0.14.0 2019-01-29 + + +### Fixed + +- `valid?` works correctly with constructors now (cgeorgii) + +### Changed + +- [BREAKING] Support for Ruby 2.2 was dropped. It reached EOL on March 31, 2018. +- `dry-logic` was updated to `~> 0.5` (solnic) + +[Compare v0.13.4...v0.14.0](https://github.com/dry-rb/dry-types/compare/v0.13.4...v0.14.0) + +## 0.13.4 2018-12-21 + + +### Fixed + +- Fixed warnings about keyword arguments from Ruby 2.6. See https://bugs.ruby-lang.org/issues/14183 for all the details (flash-gordon) + + +[Compare v0.13.3...v0.13.4](https://github.com/dry-rb/dry-types/compare/v0.13.3...v0.13.4) + +## 0.13.3 2018-11-25 + + +### Fixed + +- `Dry::Types::Hash#try` returns `Failure` instead of throwing an exception on missing keys (GustavoCaso) + + +[Compare v0.13.2...v0.13.3](https://github.com/dry-rb/dry-types/compare/v0.13.2...v0.13.3) + +## 0.13.2 2018-05-30 + + +### Fixed + +- `Defaults#valid?` now works fine when passing `Dry::Core::Constans::Undefined` as value (GustavoCaso) +- `valid?` for constructor types wrapping `Sum`s (GustavoCaso) + + +[Compare v0.13.1...v0.13.2](https://github.com/dry-rb/dry-types/compare/v0.13.1...v0.13.2) + +## 0.13.1 2018-05-28 + + +### Added + +- `params.int` was added to make the upgrade process in dry-validation smoother (available after you `require 'dry/types/compat/int'`) (flash-gordon) + +### Fixed + +- Defaults now works fine with meta (GustavoCaso) +- Defaults are now re-decorated properly (flash-gordon) + + +[Compare v0.13.0...v0.13.1](https://github.com/dry-rb/dry-types/compare/v0.13.0...v0.13.1) + +## 0.13.0 2018-05-03 + + +### Added + +- Hash schemas were rewritten. The old API is still around but is going to be deprecated and removed before 1.0. The new API is simpler and more flexible. Instead of having a bunch of predefined schemas you can build your own by combining the following methods: + + 1. `Schema#with_key_transform`—transforms keys of input hashes, for things like symbolizing etc. + 2. `Schema#strict`—makes a schema intolerant to unknown keys. + 3. `Hash#with_type_transform`—transforms member types with an arbitrary block. For instance, + + ```ruby + optional_keys = Types::Hash.with_type_transform { |t, _key| t.optional } + schema = optional_keys.schema(name: 'strict.string', age: 'strict.int') + schema.(name: "Jane", age: nil) # => {name: "Jane", age: nil} + ``` + + Note that by default all keys are required, if a key is expected to be absent, add to the corresponding type's meta `omittable: true`: + + ```ruby + intolerant = Types::Hash.schema(name: Types::Strict::String) + intolerant[{}] # => Dry::Types::MissingKeyError + tolerant = Types::Hash.schema(name: Types::Strict::String.meta(omittable: true)) + tolerant[{}] # => {} + tolerant_with_default = Types::Hash.schema(name: Types::Strict::String.meta(omittable: true).default("John")) + tolerant[{}] # => {name: "John"} + ``` + + The new API is composable in a natural way: + + ```ruby + TOLERANT = Types::Hash.with_type_transform { |t| t.meta(omittable: true) }.freeze + user = TOLERANT.schema(name: 'strict.string', age: 'strict.int') + user.(name: "Jane") # => {name: "Jane"} + + TOLERANT_SYMBOLIZED = TOLERANT.with_key_transform(&:to_sym) + user_sym = TOLERANT_SYMBOLIZED.schema(name: 'strict.string', age: 'strict.int') + user_sym.("name" => "Jane") # => {name: "Jane"} + ``` + + (flash-gordon) +- `Types.Strict` is an alias for `Types.Instance` (flash-gordon) + ```ruby + strict_range = Types.Strict(Range) + strict_range == Types.Instance(Range) # => true + ``` +- `Enum#include?` is an alias to `Enum#valid?` (d-Pixie + flash-gordon) +- `Range` was added (GustavoCaso) +- `Array` types filter out `Undefined` values, if you have an array type with a constructor type as its member, the constructor now can return `Dry::Types::Undefined` to indicate empty value: + ```ruby + filter_empty_strings = Types::Strict::Array.of( + Types::Strict::String.constructor { |input| + input.to_s.yield_self { |s| s.empty? ? Dry::Types::Undefined : s } + } + ) + filter_empty_strings.(["John", nil, "", "Jane"]) # => ["John", "Jane"] + ``` +- `Types::Map` was added for homogeneous hashes, when only types of keys and values are known in advance, not specific key names (fledman + flash-gordon) + ```ruby + int_to_string = Types::Hash.map('strict.integer', 'strict.string') + int_to_string[0 => 'foo'] # => { 0 => "foo" } + int_to_string[0 => 1] # Dry::Types::MapError: input value 1 for key 0 is invalid: type?(String, 1) + ``` +- Enum supports mappings (bolshakov + flash-gordon) + ```ruby + dict = Types::Strict::String.enum('draft' => 0, 'published' => 10, 'archived' => 20) + dict['published'] # => 'published' + dict[10] # => 'published' + ``` + +### Fixed + +- Fixed applying constraints to optional type, i.e. `.optional.constrained` works correctly (flash-gordon) +- Fixed enum working with optionals (flash-gordon) +- ## Internal +- Dropped the `dry-configurable` dependency (GustavoCaso) +- The gem now uses `dry-inflector` for inflections instead of `inflecto` (GustavoCaso) + +### Changed + +- [BREAKING] Renamed `Types::Form` to `Types::Params`. You can opt-in the former name with `require 'dry/types/compat/form_types'`. It will be dropped in the next release (ndrluis) +- [BREAKING] The `Int` types was renamed to `Integer`, this was the only type named differently from the standard Ruby classes so it has been made consistent. The former name is available with `require 'dry/types/compat/int'` (GustavoCaso + flash-gordon) +- [BREAKING] Default types are not evaluated on `nil`. Default values are evaluated _only_ if no value were given. + ```ruby + type = Types::Strict::String.default("hello") + type[nil] # => constraint error + type[] # => "hello" + ``` + This change allowed to greatly simplify hash schemas, make them a lot more flexible yet predictable (see below). +- [BREAKING] `Dry::Types.register_class` was removed, `Dry::Types.register` was made private API, do not register your types in the global `dry-types` container, use a module instead, e.g. `Types` (flash-gordon) +- [BREAKING] Enum types don't accept value index anymore. Instead, explicit mapping is supported, see below (flash-gordon) + +[Compare v0.12.2...v0.13.0](https://github.com/dry-rb/dry-types/compare/v0.12.2...v0.13.0) + +## 0.12.2 2017-11-04 + + +### Fixed + +- The type compiler was fixed for simple rules such as used for strict type checks (flash-gordon) +- Fixed an error on `Dry::Types['json.decimal'].try(nil)` (nesaulov) +- Fixed an error on calling `try` on an array type built of constrained types (flash-gordon) +- Implemented `===` for enum types (GustavoCaso) + + +[Compare v0.12.1...v0.12.2](https://github.com/dry-rb/dry-types/compare/v0.12.1...v0.12.2) + +## 0.12.1 2017-10-11 + + +### Fixed + +- `Constructor#try` rescues `ArgumentError` (raised in cases like `Integer('foo')`) (flash-gordon) +- `#constructor` works correctly for default and enum types (solnic) +- Optional sum types work correctly in `safe` mode (GustavoCaso) +- The equalizer of constrained types respects meta (flash-gordon) + + +[Compare v0.12.0...v0.12.1](https://github.com/dry-rb/dry-types/compare/v0.12.0...v0.12.1) + +## 0.12.0 2017-09-15 + + +### Added + +- A bunch of shortcut methods for constructing types to the autogenerated module, e.g. `Types.Constructor(String, &:to_s)` (flash-gordon) +- ## Deprecated +- `Types::Array#member` was deprecated in favor of `Types::Array#of` (flash-gordon) + + +[Compare v0.11.1...v0.12.0](https://github.com/dry-rb/dry-types/compare/v0.11.1...v0.12.0) + +## 0.11.1 2017-08-14 + + +### Fixed + +- Fixed `Constructor#name` with `Sum`-types (flash-gordon) + +### Changed + +- Constructors are now equalized using `fn` and `meta` too (flash-gordon) + +[Compare v0.11.0...v0.11.1](https://github.com/dry-rb/dry-types/compare/v0.11.0...v0.11.1) + +## 0.11.0 2017-06-30 + + +### Added + +- `#to_ast` available for all type objects (GustavoCaso) +- `Types::Array#of` as an alias for `#member` (maliqq) +- Detailed failure objects are passed to results which improves constraint violation messages (GustavoCaso) + + +[Compare v0.10.3...v0.11.0](https://github.com/dry-rb/dry-types/compare/v0.10.3...v0.11.0) + +## 0.10.3 2017-05-06 + + +### Added + +- Callable defaults accept the underlying type (v-kolesnikov) + + +[Compare v0.10.2...v0.10.3](https://github.com/dry-rb/dry-types/compare/v0.10.2...v0.10.3) + +## 0.10.2 2017-04-28 + + +### Fixed + +- Fixed `Type#optional?` for sum types (flash-gordon) + + +[Compare v0.10.1...v0.10.2](https://github.com/dry-rb/dry-types/compare/v0.10.1...v0.10.2) + +## 0.10.1 2017-04-28 + + +### Added + +- `Type#optional?` returns true if type is Sum and left is nil (GustavoCaso) +- `Type#pristine` returns a type without `meta` (flash-gordon) + +### Fixed + +- `meta` is used in type equality again (solnic) +- `Any` works correctly with meta again (flash-gordon) + + +[Compare v0.10.0...v0.10.1](https://github.com/dry-rb/dry-types/compare/v0.10.0...v0.10.1) + +## 0.10.0 2017-04-26 + + +### Added + +- Types can be used in `case` statements now (GustavoCaso) + +### Fixed + +- Return original value when Date.parse raises a RangeError (jviney) + +### Changed + +- Meta data are now stored separately from options (flash-gordon) +- `Types::Object` was renamed to `Types::Any` (flash-gordon) + +[Compare v0.9.4...v0.10.0](https://github.com/dry-rb/dry-types/compare/v0.9.4...v0.10.0) + +## 0.9.4 2017-01-24 + + +### Added + +- Added `Types::Object` which passes an object of any type (flash-gordon) + + +[Compare v0.9.3...v0.9.4](https://github.com/dry-rb/dry-types/compare/v0.9.3...v0.9.4) + +## 0.9.3 2016-12-03 + + +### Fixed + +- Updated to dry-core >= 0.2.1 (ruby warnings are gone) (flash-gordon) + + +[Compare v0.9.2...v0.9.3](https://github.com/dry-rb/dry-types/compare/v0.9.2...v0.9.3) + +## 0.9.2 2016-11-13 + + +### Added + +- Support for `"Y"` and `"N"` as `true` and `false` values, respectively (scare21410) + +### Changed + +- Optimized object allocation in hash schemas, resulting in up to 25% speed boost (davydovanton) + +[Compare v0.9.1...v0.9.2](https://github.com/dry-rb/dry-types/compare/v0.9.1...v0.9.2) + +## 0.9.1 2016-11-04 + + +### Fixed + +- `Hash#strict_with_defaults` properly evaluates callable defaults (bolshakov) + +### Changed + +- `Hash#weak` accepts Hash-descendants again (solnic) + +[Compare v0.9.0...v0.9.1](https://github.com/dry-rb/dry-types/compare/v0.9.0...v0.9.1) + +## 0.9.0 2016-09-21 + + +### Added + +- `Hash#strict_with_defaults` which validates presence of all required keys and respects default types for missing _values_ (backus) +- `Type#constrained?` method (flash-gordon) + +### Fixed + +- Summing two constrained types works correctly (flash-gordon) +- `Types::Array::Member#valid?` in cases where member type is a constraint (solnic) +- `Hash::Schema#try` handles exceptions properly and returns a failure object (solnic) + +### Changed + +- [BREAKING] Renamed `Hash##{schema=>permissive}` (backus) +- [BREAKING] `dry-monads` dependency was made optional, Maybe types are available after `Dry::Types.load_extensions(:maybe)` (flash-gordon) +- [BREAKING] `Dry::Types::Struct` and `Dry::Types::Value` have been extracted to [`dry-struct`](https://github.com/dry-rb/dry-struct) (backus) +- `Types::Form::Bool` supports upcased true/false values (kirs) +- `Types::Form::{Date,DateTime,Time}` fail gracefully for invalid input (padde) +- ice_nine dependency has been dropped as it was required by Struct only (flash-gordon) + +[Compare v0.8.1...v0.9.0](https://github.com/dry-rb/dry-types/compare/v0.8.1...v0.9.0) + +## 0.8.1 2016-07-13 + + +### Fixed + +- Compiler no longer chokes on type nodes without args (solnic) +- Removed `bin/console` from gem package (solnic) + + +[Compare v0.8.0...v0.8.1](https://github.com/dry-rb/dry-types/compare/v0.8.0...v0.8.1) + +## 0.8.0 2016-07-01 + + +### Added + +- `Struct` now implements `Type` interface so ie `SomeStruct | String` works now (flash-gordon) +- `:weak` Hash constructor which can partially coerce a hash even when it includes invalid values (solnic) +- Types include `Dry::Equalizer` now (flash-gordon) + +### Fixed + +- `Struct#to_hash` descends into arrays too (nepalez) +- `Default#with` works now (flash-gordon) + +### Changed + +- `:symbolized` hash schema is now based on `:weak` schema (solnic) +- `Struct::Value` instances are now **deeply frozen** via ice_nine (backus) + +[Compare v0.7.2...v0.8.0](https://github.com/dry-rb/dry-types/compare/v0.7.2...v0.8.0) + +## 0.7.2 2016-05-11 + + +### Fixed + +- `Bool#default` gladly accepts `false` as its value (solnic) +- Creating an empty schema with input processor no longer fails (lasseebert) + +### Changed + +- Allow multiple calls to meta (solnic) +- Allow capitalised versions of true and false values for boolean coercions (nil0bject) +- Replace kleisli with dry-monads (flash-gordon) +- Use coercions from Kernel (flash-gordon) +- Decimal coercions now work with Float (flash-gordon) +- Coerce empty strings in form posts to blank arrays and hashes (timriley) +- update to use dry-logic v0.2.3 (fran-worley) + +[Compare v0.7.1...v0.7.2](https://github.com/dry-rb/dry-types/compare/v0.7.1...v0.7.2) + +## 0.7.1 2016-04-06 + + +### Added + +- `JSON::*` types with JSON-specific coercions (coop) + +### Fixed + +- Schema is properly inherited in Struct (backus) +- `constructor_type` is properly inherited in Struct (fbernier) + + +[Compare v0.7.0...v0.7.1](https://github.com/dry-rb/dry-types/compare/v0.7.0...v0.7.1) + +## 0.7.0 2016-03-30 + +Major focus of this release is to make complex type composition possible and improving constraint errors to be more meaningful. + +### Added + +- `Type#try` interface that tries to process the input and return a result object which can be either a success or failure (solnic) +- `#meta` interface for setting arbitrary meta data on types (solnic) +- `ConstraintError` has a message which includes information about the predicate which failed ie `nil violates constraints (type?(String) failed)` (solnic) +- `Struct` uses `Dry::Equalizer` too, just like `Value` (AMHOL) +- `Sum::Constrained` which has a disjunction rule built from its types (solnic) +- Compiler supports `[:constructor, [primitive, fn_proc]]` nodes (solnic) +- Compiler supports building schema-less `form.hash` types (solnic) + +### Fixed + +- `Sum` now supports complex types like `Array` or `Hash` with member types and/or constraints (solnic) +- `Default#constrained` will properly wrap a new constrained type (solnic) + +### Changed + +- [BREAKING] Renamed `Type#{optional=>maybe}` (AMHOL) +- [BREAKING] `Type#optional(other)` builds a sum: `Strict::Nil | other` (AMHOL) +- [BREAKING] Type objects are now frozen (solnic) +- [BREAKING] `Value` instances are frozen (AMHOL) +- `Array` is no longer a constructor and has a `Array::Member` subclass (solnic) +- `Hash` is no longer a constructor and is split into `Hash::Safe`, `Hash::Strict` and `Hash::Symbolized` (solnic) +- `Constrained` has now a `Constrained::Coercible` subclass which will try to apply its type prior applying its rule (solnic) +- `#maybe` uses `Strict::Nil` now (solnic) +- `Type#default` will raise if `nil` was passed for `Maybe` type (solnic) +- `Hash` with a schema will set maybe values for missing keys or nils (flash-gordon) + +[Compare v0.6.0...v0.7.0](https://github.com/dry-rb/dry-types/compare/v0.6.0...v0.7.0) + +## 0.6.0 2016-03-16 + +Renamed from `dry-data` to `dry-types` and: + +### Added + +- `Dry::Types.module` which returns a namespace for inclusion which has all + built-in types defined as constants (solnic) +- `Hash#schema` supports default values now (solnic) +- `Hash#symbolized` passes through keys that are already symbols (solnic) +- `Struct.new` uses an empty hash by default as input (solnic) +- `Struct.constructor_type` macro can be used to change attributes constructor (solnic) +- `default` accepts a block now for dynamic values (solnic) +- `Types.register_class` accepts a second arg which is the name of the class' + constructor method, defaults to `:new` (solnic) + +### Fixed + +- `Struct` will simply pass-through the input if it is already a struct (solnic) +- `default` will raise if a value violates constraints (solnic) +- Evaluating a default value tries to use type's constructor which makes it work + with types that may coerce an input into nil (solnic) +- `enum` works just fine with integer-values (solnic) +- `enum` + `default` works just fine (solnic) +- `Optional` no longer responds to `primitive` as it makes no sense since there's + no single primitive for an optional value (solnic) +- `Optional` passes-through a value which is already a maybe (solnic) + +### Changed + +- `Dry::Types::Definition` is now the base type definition object (solnic) +- `Dry::Types::Constructor` is now a type definition with a constructor function (solnic) + +[Compare v0.5.1...v0.6.0](https://github.com/dry-rb/dry-types/compare/v0.5.1...v0.6.0) + +## 0.5.1 2016-01-11 + + +### Added + +- `Dry::Data::Type#safe` for types which can skip constructor when primitive does + not match input's class (solnic) +- `form.array` and `form.hash` safe types (solnic) + + +[Compare v0.5.0...v0.5.1](https://github.com/dry-rb/dry-types/compare/v0.5.0...v0.5.1) + +## 0.5.0 2016-01-11 + + +### Added + +- `Type#default` interface for defining a type with a default value (solnic) + +### Fixed + +- `attribute` raises proper error when type definition is missing (solnic) + +### Changed + +- [BREAKING] `Dry::Data::Type.new` accepts constructor and _options_ now (solnic) +- Renamed `Dry::Data::Type::{Enum,Constrained}` => `Dry::Data::{Enum,Constrained}` (solnic) +- `dry-logic` is now a dependency for constrained types (solnic) +- Constrained types are now always available (solnic) +- `strict.*` category uses constrained types with `:type?` predicate (solnic) +- `SumType#call` no longer needs to rescue from `TypeError` (solnic) + +[Compare v0.4.2...v0.5.0](https://github.com/dry-rb/dry-types/compare/v0.4.2...v0.5.0) + +## 0.4.2 2015-12-27 + + +### Added + +- Support for arrays in type compiler (solnic) + +### Changed + +- Array member uses type objects now rather than just their constructors (solnic) + +[Compare v0.4.0...v0.4.2](https://github.com/dry-rb/dry-types/compare/v0.4.0...v0.4.2) + +## 0.4.0 2015-12-11 + + +### Added + +- Support for sum-types with constraint type (solnic) +- `Dry::Data::Type#optional` for defining optional types (solnic) + +### Changed + +- `Dry::Data['optional']` was **removed** in favor of `Dry::Data::Type#optional` (solnic) + +[Compare v0.3.2...v0.4.0](https://github.com/dry-rb/dry-types/compare/v0.3.2...v0.4.0) + +## 0.3.2 2015-12-10 + + +### Added + +- `Dry::Data::Value` which works like a struct but is a value object with equalizer (solnic) + +### Fixed + +- Added missing require for `dry-equalizer` (solnic) + + +[Compare v0.3.1...v0.3.2](https://github.com/dry-rb/dry-types/compare/v0.3.1...v0.3.2) + +## 0.3.1 2015-12-09 + + +### Changed + +- Removed require of constrained type and make it optional (solnic) + +[Compare v0.3.0...v0.3.1](https://github.com/dry-rb/dry-types/compare/v0.3.0...v0.3.1) + +## 0.3.0 2015-12-09 + + +### Added + +- `Type#constrained` interface for defining constrained types (solnic) +- `Dry::Data` can be configured with a type namespace (solnic) +- `Dry::Data.finalize` can be used to define types as constants under configured namespace (solnic) +- `Dry::Data::Type#enum` for defining an enum from a specific type (solnic) +- New types: `symbol` and `class` along with their `strict` versions (solnic) + + +[Compare v0.2.1...v0.3.0](https://github.com/dry-rb/dry-types/compare/v0.2.1...v0.3.0) + +## 0.2.1 2015-11-30 + + +### Added + +- Type compiler supports nested hashes now (solnic) + +### Fixed + +- `form.bool` sum is using correct right-side `form.false` type (solnic) + +### Changed + +- Improved structure of the ast (solnic) + +[Compare v0.2.0...v0.2.1](https://github.com/dry-rb/dry-types/compare/v0.2.0...v0.2.1) + +## 0.2.0 2015-11-29 + + +### Added + +- `form.nil` which coerces empty strings to `nil` (solnic) +- `bool` sum-type (true | false) (solnic) +- Type compiler supports sum-types now (solnic) + +### Changed + +- Constructing optional types uses the new `Dry::Data["optional"]` built-in type (solnic) + +[Compare v0.1.0...v0.2.0](https://github.com/dry-rb/dry-types/compare/v0.1.0...v0.2.0) + +## 0.1.0 2015-11-27 + + +### Added + +- `form.*` coercible types (solnic) +- `Type::Hash#strict` for defining hashes with a strict schema (solnic) +- `Type::Hash#symbolized` for defining hashes that will symbolize keys (solnic) +- `Dry::Data.register_class` short-cut interface for registering a class and + setting its `.new` method as the constructor (solnic) +- `Dry::Data::Compiler` for building a type from a simple ast (solnic) + + +[Compare v0.0.1...v0.1.0](https://github.com/dry-rb/dry-types/compare/v0.0.1...v0.1.0) + +## 0.0.1 2015-10-05 + +First public release diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/LICENSE b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/LICENSE new file mode 100644 index 00000000..9f9f214d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2015-2023 dry-rb team + +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 AUTHORS OR +COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/README.md b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/README.md new file mode 100644 index 00000000..58c3aa75 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/README.md @@ -0,0 +1,23 @@ + + +[gem]: https://rubygems.org/gems/dry-types +[actions]: https://github.com/dry-rb/dry-types/actions + +# dry-types [![Gem Version](https://badge.fury.io/rb/dry-types.svg)][gem] [![CI Status](https://github.com/dry-rb/dry-types/workflows/CI/badge.svg)][actions] + +## Links + +* [User documentation](https://dry-rb.org/gems/dry-types) +* [API documentation](http://rubydoc.info/gems/dry-types) +* [Forum](https://discourse.dry-rb.org) + +## Supported Ruby versions + +This library officially supports the following Ruby versions: + +* MRI `>= 3.1` +* jruby `>= 9.4` (not tested on CI) + +## License + +See `LICENSE` file. diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/dry-types.gemspec b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/dry-types.gemspec new file mode 100644 index 00000000..d44f2d72 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/dry-types.gemspec @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +# this file is synced from dry-rb/template-gem project + +lib = File.expand_path("lib", __dir__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require "dry/types/version" + +Gem::Specification.new do |spec| + spec.name = "dry-types" + spec.authors = ["Piotr Solnica"] + spec.email = ["piotr.solnica@gmail.com"] + spec.license = "MIT" + spec.version = Dry::Types::VERSION.dup + + spec.summary = "Type system for Ruby supporting coercions, constraints and complex types like structs, value objects, enums etc" + spec.description = spec.summary + spec.homepage = "https://dry-rb.org/gems/dry-types" + spec.files = Dir["CHANGELOG.md", "LICENSE", "README.md", "dry-types.gemspec", "lib/**/*"] + spec.bindir = "bin" + spec.executables = [] + spec.require_paths = ["lib"] + + spec.metadata["allowed_push_host"] = "https://rubygems.org" + spec.metadata["changelog_uri"] = "https://github.com/dry-rb/dry-types/blob/main/CHANGELOG.md" + spec.metadata["source_code_uri"] = "https://github.com/dry-rb/dry-types" + spec.metadata["bug_tracker_uri"] = "https://github.com/dry-rb/dry-types/issues" + spec.metadata["rubygems_mfa_required"] = "true" + + spec.required_ruby_version = ">= 3.1" + + # to update dependencies edit project.yml + spec.add_dependency "bigdecimal", "~> 3.0" + spec.add_dependency "concurrent-ruby", "~> 1.0" + spec.add_dependency "dry-core", "~> 1.0" + spec.add_dependency "dry-inflector", "~> 1.0" + spec.add_dependency "dry-logic", "~> 1.4" + spec.add_dependency "zeitwerk", "~> 2.6" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry-types.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry-types.rb new file mode 100644 index 00000000..85f2b976 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry-types.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +require "dry/types" diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types.rb new file mode 100644 index 00000000..7b3695ae --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types.rb @@ -0,0 +1,260 @@ +# frozen_string_literal: true + +require "bigdecimal" +require "date" +require "set" +require "zeitwerk" + +require "concurrent/map" + +require "dry/core" +require "dry/logic" + +require "dry/types/constraints" +require "dry/types/errors" +require "dry/types/version" + +# This must be required explicitly as it may conflict with dry-inflector +require "dry/types/inflector" +require "dry/types/module" + +module Dry + # Main library namespace + # + # @api public + module Types + extend ::Dry::Core::Extensions + extend ::Dry::Core::ClassAttributes + extend ::Dry::Core::Deprecations[:"dry-types"] + include ::Dry::Core::Constants + + TYPE_SPEC_REGEX = /(.+)<(.+)>/ + + def self.loader + @loader ||= ::Zeitwerk::Loader.new.tap do |loader| + root = ::File.expand_path("..", __dir__) + loader.tag = "dry-types" + loader.inflector = ::Zeitwerk::GemInflector.new("#{root}/dry-types.rb") + loader.inflector.inflect("json" => "JSON") + loader.push_dir(root) + loader.ignore( + "#{root}/dry-types.rb", + "#{root}/dry/types/extensions", + "#{root}/dry/types/printer", + "#{root}/dry/types/spec/types.rb", + "#{root}/dry/types/{#{%w[ + compat + constraints + core + errors + extensions + inflector + module + json + params + printer + version + ].join(",")}}.rb" + ) + end + end + + loader.setup + + # @see Dry.Types + def self.module(*namespaces, default: :nominal, **aliases) + ::Module.new(container, *namespaces, default: default, **aliases) + end + deprecate_class_method :module, message: <<~DEPRECATION + Use Dry.Types() instead. Beware, it exports strict types by default, for old behavior use Dry.Types(default: :nominal). See more options in the changelog + DEPRECATION + + # @api private + def self.included(*) + raise "Import Dry.Types, not Dry::Types" + end + + # Return container with registered built-in type objects + # + # @return [Container{String => Nominal}] + # + # @api private + def self.container + @container ||= Container.new + end + + # Check if a give type is registered + # + # @return [Boolean] + # + # @api private + def self.registered?(class_or_identifier) + container.key?(identifier(class_or_identifier)) + end + + # Register a new built-in type + # + # @param [String] name + # @param [Type] type + # @param [#call,nil] block + # + # @return [Container{String => Nominal}] + # + # @api private + def self.register(name, type = nil, &block) + container.register(name, type || block.call) + end + + # Get a built-in type by its name + # + # @param [String,Class] name + # + # @return [Type,Class] + # + # @api public + def self.[](name) + type_map.fetch_or_store(name) do + case name + when ::String + result = name.match(TYPE_SPEC_REGEX) + + if result + type_id, member_id = result[1..2] + container[type_id].of(self[member_id]) + else + container[name] + end + when ::Class + warn(<<~DEPRECATION) + Using Dry::Types.[] with a class is deprecated, please use string identifiers: Dry::Types[Integer] -> Dry::Types['integer']. + If you're using dry-struct this means changing `attribute :counter, Integer` to `attribute :counter, Dry::Types['integer']` or to `attribute :counter, 'integer'`. + DEPRECATION + + type_name = identifier(name) + + if container.key?(type_name) + self[type_name] + else + name + end + end + end + end + + # Infer a type identifier from the provided class + # + # @param [#to_s] klass + # + # @return [String] + def self.identifier(klass) + Types::Inflector.underscore(klass).tr("/", ".") + end + + # Cached type map + # + # @return [Concurrent::Map] + # + # @api private + def self.type_map + @type_map ||= ::Concurrent::Map.new + end + + # @api private + def self.const_missing(const) + underscored = Types::Inflector.underscore(const) + + if container.keys.any? { |key| key.split(".")[0] == underscored } + raise ::NameError, + "dry-types does not define constants for default types. " \ + "You can access the predefined types with [], e.g. Dry::Types['integer'] " \ + "or generate a module with types using Dry.Types()" + else + super + end + end + + # Add a new type builder method. This is a public API for defining custom + # type constructors + # + # @example simple custom type constructor + # Dry::Types.define_builder(:or_nil) do |type| + # type.optional.fallback(nil) + # end + # + # Dry::Types["integer"].or_nil.("foo") # => nil + # + # @example fallback alias + # Dry::Types.define_builder(:or) do |type, fallback| + # type.fallback(fallback) + # end + # + # Dry::Types["integer"].or(100).("foo") # => 100 + # + # @param [Symbol] method + # @param [#call] block + # + # @api public + def self.define_builder(method, &block) + Builder.define_method(method) do |*args| + block.(self, *args) + end + end + end + + # Export registered types as a module with constants + # + # @example no options + # + # module Types + # # imports all types as constants, uses modules for namespaces + # include Dry.Types() + # end + # # strict types are exported by default + # Types::Integer + # # => # rule=[type?(Integer)]>]> + # Types::Nominal::Integer + # # => #]> + # + # @example changing default types + # + # module Types + # include Dry.Types(default: :nominal) + # end + # Types::Integer + # # => #]> + # + # @example cherry-picking namespaces + # + # module Types + # include Dry.Types(:strict, :coercible) + # end + # # cherry-picking discards default types, + # # provide the :default option along with the list of + # # namespaces if you want the to be exported + # Types.constants # => [:Coercible, :Strict] + # + # @example custom names + # module Types + # include Dry.Types(coercible: :Kernel) + # end + # Types::Kernel::Integer + # # => # fn=Kernel.Integer>]> + # + # @param [Array] namespaces List of type namespaces to export + # @param [Symbol] default Default namespace to export + # @param [Hash{Symbol => Symbol}] aliases Optional renamings, like strict: :Draconian + # + # @return [Dry::Types::Module] + # + # @see Dry::Types::Module + # + # @api public + # + def self.Types(*namespaces, default: Types::Undefined, **aliases) + Types::Module.new(Types.container, *namespaces, default: default, **aliases) + end +end + +require "dry/types/core" # load built-in types +require "dry/types/extensions" +require "dry/types/printer" diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/any.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/any.rb new file mode 100644 index 00000000..08861c9c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/any.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module Dry + module Types + # Any is a nominal type that defines Object as the primitive class + # + # This type is useful in places where you can't be specific about the type + # and anything is acceptable. + # + # @api public + class AnyClass < Nominal + def self.name = "Any" + + # @api private + def initialize(**options) + super(::Object, **options) + end + + # @return [String] + # + # @api public + def name = "Any" + + # @param [Hash] new_options + # + # @return [Type] + # + # @api public + def with(**new_options) + self.class.new(**options, meta: @meta, **new_options) + end + + # @return [Array] + # + # @api public + def to_ast(meta: true) = [:any, meta ? self.meta : EMPTY_HASH] + end + + Any = AnyClass.new + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/array.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/array.rb new file mode 100644 index 00000000..c47ced59 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/array.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module Dry + module Types + # Array type can be used to define an array with optional member type + # + # @api public + class Array < Nominal + # Build an array type with a member type + # + # @param [Type,#call] type + # + # @return [Array::Member] + # + # @api public + def of(type) + member = + case type + when ::String then Types[type] + else type + end + + Array::Member.new(primitive, **options, member: member) + end + + # @api private + def constructor_type + ::Dry::Types::Array::Constructor + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/array/constructor.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/array/constructor.rb new file mode 100644 index 00000000..fb810dcd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/array/constructor.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Dry + module Types + # @api public + class Array < Nominal + # @api private + class Constructor < ::Dry::Types::Constructor + # @api private + def constructor_type = ::Dry::Types::Array::Constructor + + # @return [Lax] + # + # @api public + def lax = Lax.new(type.lax.constructor(fn, meta: meta)) + + # @see Dry::Types::Array#of + # + # @api public + def of(member) = type.of(member).constructor(fn, meta: meta) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/array/member.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/array/member.rb new file mode 100644 index 00000000..b5963d81 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/array/member.rb @@ -0,0 +1,120 @@ +# frozen_string_literal: true + +module Dry + module Types + class Array < Nominal + # Member arrays define their member type that is applied to each element + # + # @api public + class Member < Array + # @return [Type] + attr_reader :member + + # @param [Class] primitive + # @param [Hash] options + # + # @option options [Type] :member + # + # @api private + def initialize(primitive, **options) + @member = options.fetch(:member) + super + end + + # @param [Object] input + # + # @return [Array] + # + # @api private + def call_unsafe(input) + if primitive?(input) + input.each_with_object([]) do |el, output| + coerced = member.call_unsafe(el) + + output << coerced unless Undefined.equal?(coerced) + end + else + super + end + end + + # @param [Object] input + # @return [Array] + # + # @api private + def call_safe(input) + if primitive?(input) + failed = false + + result = input.each_with_object([]) do |el, output| + coerced = member.call_safe(el) { |out = el| + failed = true + out + } + + output << coerced unless Undefined.equal?(coerced) + end + + failed ? yield(result) : result + else + yield + end + end + + # @param [Array, Object] input + # @param [#call,nil] block + # + # @yieldparam [Failure] failure + # @yieldreturn [Result] + # + # @return [Result,Logic::Result] + # + # @api public + def try(input, &block) # rubocop:disable Metrics/PerceivedComplexity + if primitive?(input) + output = [] + + result = input.map { |el| member.try(el) } + result.each do |r| + output << r.input unless Undefined.equal?(r.input) + end + + if result.all?(&:success?) + success(output) + else + error = result.find(&:failure?).error + failure = failure(output, error) + block ? yield(failure) : failure + end + else + failure = failure(input, CoercionError.new("#{input} is not an array")) + block ? yield(failure) : failure + end + end + + # Build a lax type + # + # @return [Lax] + # + # @api public + def lax + Lax.new(Member.new(primitive, **options, member: member.lax, meta: meta)) + end + + # @see Nominal#to_ast + # + # @api public + def to_ast(meta: true) + if member.respond_to?(:to_ast) + [:array, [member.to_ast(meta: meta), meta ? self.meta : EMPTY_HASH]] + else + [:array, [member, meta ? self.meta : EMPTY_HASH]] + end + end + + # @api private + def constructor_type = ::Dry::Types::Array::Constructor + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/builder.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/builder.rb new file mode 100644 index 00000000..ab60823c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/builder.rb @@ -0,0 +1,205 @@ +# frozen_string_literal: true + +module Dry + module Types + # Common API for building types and composition + # + # @api public + module Builder + include ::Dry::Core::Constants + + # @return [Class] + # + # @api private + def constrained_type = Constrained + + # @return [Class] + # + # @api private + def constructor_type = Constructor + + # Compose two types into a Sum type + # + # @param [Type] other + # + # @return [Sum, Sum::Constrained] + # + # @api private + def |(other) = compose(other, Sum) + + # Compose two types into an Intersection type + # + # @param [Type] other + # + # @return [Intersection, Intersection::Constrained] + # + # @api private + def &(other) = compose(other, Intersection) + + # Compose two types into an Implication type + # + # @param [Type] other + # + # @return [Implication, Implication::Constrained] + # + # @api private + def >(other) = compose(other, Implication) + + # Turn a type into an optional type + # + # @return [Sum] + # + # @api public + def optional = Types["nil"] | self + + # Turn a type into a constrained type + # + # @param [Hash] options constraining rule (see {Types.Rule}) + # + # @return [Constrained] + # + # @api public + def constrained(...) + constrained_type.new(self, rule: Types.Rule(...)) + end + + # Turn a type into a type with a default value + # + # @param [Object] input + # @option [Boolean] shared Whether it's safe to share the value across type applications + # @param [#call,nil] block + # + # @raise [ConstraintError] + # + # @return [Default] + # + # @api public + def default(input = Undefined, options = EMPTY_HASH, &block) + unless input.frozen? || options[:shared] + where = Core::Deprecations::STACK.() + Core::Deprecations.warn( + "#{input.inspect} is mutable. " \ + "Be careful: types will return the same instance of the default " \ + "value every time. Call `.freeze` when setting the default " \ + "or pass `shared: true` to discard this warning." \ + "\n#{where}", + tag: :"dry-types" + ) + end + + value = Undefined.default(input, block) + type = Default[value].new(self, value) + + if !type.callable? && !valid?(value) + raise ConstraintError.new( + "default value #{value.inspect} violates constraints", + value + ) + else + type + end + end + + # Define an enum on top of the existing type + # + # @param [Array] values + # + # @return [Enum] + # + # @api public + def enum(*values) + mapping = + if values.length == 1 && values[0].is_a?(::Hash) + values[0] + else + values.zip(values).to_h + end + + Enum.new(constrained(included_in: mapping.keys), mapping: mapping) + end + + # Turn a type into a lax type that will rescue from type-errors and + # return the original input + # + # @return [Lax] + # + # @api public + def lax = Lax.new(self) + + # Define a constructor for the type + # + # @param [#call,nil] constructor + # @param [Hash] options + # @param [#call,nil] block + # + # @return [Constructor] + # + # @api public + def constructor(constructor = nil, **options, &block) + constructor_type[with(**options), fn: constructor || block] + end + alias_method :append, :constructor + alias_method :prepend, :constructor + alias_method :>>, :constructor + alias_method :<<, :constructor + + # Use the given value on type mismatch + # + # @param [Object] value + # @option [Boolean] shared Whether it's safe to share the value across type applications + # @param [#call,nil] fallback + # + # @return [Constructor] + # + # @api public + def fallback(value = Undefined, shared: false, &_fallback) # rubocop:disable Metrics/PerceivedComplexity + if Undefined.equal?(value) && !block_given? + raise ::ArgumentError, "fallback value or a block must be given" + end + + if !block_given? && !valid?(value) + raise ConstraintError.new( + "fallback value #{value.inspect} violates constraints", + value + ) + end + + unless value.frozen? || shared + where = Core::Deprecations::STACK.() + Core::Deprecations.warn( + "#{value.inspect} is mutable. " \ + "Be careful: types will return the same instance of the fallback " \ + "value every time. Call `.freeze` when setting the fallback " \ + "or pass `shared: true` to discard this warning." \ + "\n#{where}", + tag: :"dry-types" + ) + end + + constructor do |input, type, &| + type.(input) do |output = input| + if block_given? + yield(output) + else + value + end + end + end + end + + private + + # @api private + def compose(other, composition_class) + klass = + if constrained? && other.constrained? + composition_class::Constrained + else + composition_class + end + + klass.new(self, other) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/builder_methods.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/builder_methods.rb new file mode 100644 index 00000000..f1f7a595 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/builder_methods.rb @@ -0,0 +1,138 @@ +# frozen_string_literal: true + +module Dry + module Types + # Common API for building type objects in a convenient way + # + # + # @api public + module BuilderMethods + # @api private + def included(base) + super + base.extend(BuilderMethods) + end + + # Build an array type. + # + # Shortcut for Array#of. + # + # @example + # Types::Strings = Types.Array(Types::String) + # + # @param [Dry::Types::Type] type + # + # @return [Dry::Types::Array] + def Array(type) = Strict(::Array).of(type) + + # Build a hash schema + # + # @param [Hash{Symbol => Dry::Types::Type}] type_map + # + # @return [Dry::Types::Array] + def Hash(type_map) = Strict(::Hash).schema(type_map) + + # Build a type which values are instances of a given class + # Values are checked using `is_a?` call + # + # @example + # Types::Error = Types.Instance(StandardError) + # Types::Error = Types.Strict(StandardError) + # Types.Strict(Integer) == Types::Strict::Int # => true + # + # @param [Class,Module] klass Class or module + # + # @return [Dry::Types::Type] + def Instance(klass) + unless klass.is_a?(::Module) + raise ::ArgumentError, "Expected a class or module, got #{klass.inspect}" + end + + Nominal(klass).constrained(type: klass) + end + + alias_method :Strict, :Instance + + # Build a type with a single value + # The equality check done with `eql?` + # + # @param [Object] value + # + # @return [Dry::Types::Type] + def Value(value) = Nominal(value.class).constrained(eql: value) + + # Build a type with a single value + # The equality check done with `equal?` + # + # @param [Object] object + # + # @return [Dry::Types::Type] + def Constant(object) = Nominal(object.class).constrained(is: object) + + # Build a constructor type + # If no constructor block given it uses .new method + # + # @param [Class] klass + # @param [#call,nil] cons Value constructor + # @param [#call,nil] block Value constructor + # + # @return [Dry::Types::Type] + def Constructor(klass, cons = nil, &block) # rubocop:disable Metrics/PerceivedComplexity: + if klass.is_a?(Type) + if cons || block + klass.constructor(cons || block) + else + klass + end + else + Nominal(klass).constructor(cons || block || klass.method(:new)) + end + end + + # Build a nominal type + # + # @param [Class] klass + # + # @return [Dry::Types::Type] + def Nominal(klass) + if klass <= ::Array + Array.new(klass) + elsif klass <= ::Hash + Hash.new(klass) + else + Nominal.new(klass) + end + end + + # Build a map type + # + # @example + # Types::IntMap = Types.Map(Types::Strict::Integer, 'any') + # Types::IntStringMap = Types.Map(Types::Strict::Integer, Types::Strict::String) + # + # @param [Type] key_type Key type + # @param [Type] value_type Value type + # + # @return [Dry::Types::Map] + def Map(key_type, value_type) + Nominal(::Hash).map(key_type, value_type) + end + + # Builds a constrained nominal type accepting any value that + # responds to given methods + # + # @example + # Types::Callable = Types.Interface(:call) + # Types::Contact = Types.Interface(:name, :address) + # + # @param methods [Array] Method names + # + # @return [Dry::Types::Contrained] + def Interface(*methods) + methods.reduce(Types["nominal.any"]) do |type, method| + type.constrained(respond_to: method) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/coercions.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/coercions.rb new file mode 100644 index 00000000..e7ba9cad --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/coercions.rb @@ -0,0 +1,105 @@ +# frozen_string_literal: true + +module Dry + module Types + # Common coercion functions used by the built-in `Params` and `JSON` types + # + # @api public + module Coercions + include Dry::Core::Constants + + # @param [#to_str, Object] input + # + # @return [Date, Object] + # + # @see Date.parse + # + # @api public + def to_date(input, &) + if input.respond_to?(:to_str) + begin + ::Date.parse(input) + rescue ::ArgumentError, ::RangeError => e + CoercionError.handle(e, &) + end + elsif input.is_a?(::Date) + input + elsif block_given? + yield + else + raise CoercionError, "#{input.inspect} is not a string" + end + end + + # @param [#to_str, Object] input + # + # @return [DateTime, Object] + # + # @see DateTime.parse + # + # @api public + def to_date_time(input, &) + if input.respond_to?(:to_str) + begin + ::DateTime.parse(input) + rescue ::ArgumentError => e + CoercionError.handle(e, &) + end + elsif input.is_a?(::DateTime) + input + elsif block_given? + yield + else + raise CoercionError, "#{input.inspect} is not a string" + end + end + + # @param [#to_str, Object] input + # + # @return [Time, Object] + # + # @see Time.parse + # + # @api public + def to_time(input, &) + if input.respond_to?(:to_str) + begin + ::Time.parse(input) + rescue ::ArgumentError => e + CoercionError.handle(e, &) + end + elsif input.is_a?(::Time) + input + elsif block_given? + yield + else + raise CoercionError, "#{input.inspect} is not a string" + end + end + + # @param [#to_sym, Object] input + # + # @return [Symbol, Object] + # + # @raise CoercionError + # + # @api public + def to_symbol(input, &) + input.to_sym + rescue ::NoMethodError => e + CoercionError.handle(e, &) + end + + private + + # Checks whether String is empty + # + # @param [String, Object] value + # + # @return [Boolean] + # + # @api private + def empty_str?(value) = EMPTY_STRING.eql?(value) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/coercions/json.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/coercions/json.rb new file mode 100644 index 00000000..a67b186e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/coercions/json.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +require "date" +require "bigdecimal" +require "bigdecimal/util" +require "time" + +module Dry + module Types + module Coercions + # JSON-specific coercions + # + # @api public + module JSON + extend Coercions + + # @param [Object] input + # + # @return [nil] if the input is nil + # + # @raise CoercionError + # + # @api public + def self.to_nil(input, &) + if input.nil? + nil + elsif block_given? + yield + else + raise CoercionError, "#{input.inspect} is not nil" + end + end + + # @param [#to_d, Object] input + # + # @return [BigDecimal,nil] + # + # @raise CoercionError + # + # @api public + def self.to_decimal(input, &) + if input.is_a?(::Float) + input.to_d + else + BigDecimal(input) + end + rescue ::ArgumentError, ::TypeError + if block_given? + yield + else + raise CoercionError, "#{input} cannot be coerced to decimal" + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/coercions/params.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/coercions/params.rb new file mode 100644 index 00000000..53ae52a2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/coercions/params.rb @@ -0,0 +1,168 @@ +# frozen_string_literal: true + +require "bigdecimal" +require "bigdecimal/util" + +module Dry + module Types + module Coercions + # Params-specific coercions + # + # @api public + module Params + TRUE_VALUES = %w[1 on On ON t true True TRUE T y yes Yes YES Y].freeze + FALSE_VALUES = %w[0 off Off OFF f false False FALSE F n no No NO N].freeze + BOOLEAN_MAP = EMPTY_HASH.merge( + [true, *TRUE_VALUES].to_h { |v| [v, true] }, + [false, *FALSE_VALUES].to_h { |v| [v, false] } + ).freeze + + extend Coercions + + # @param [Object] input + # + # @return [nil] if the input is an empty string or nil + # + # @raise CoercionError + # + # @api public + def self.to_nil(input, &) + if input.nil? || empty_str?(input) + nil + elsif block_given? + yield + else + raise CoercionError, "#{input.inspect} is not nil" + end + end + + # @param [String, Object] input + # + # @return [Boolean,Object] + # + # @see TRUE_VALUES + # @see FALSE_VALUES + # + # @raise CoercionError + # + # @api public + def self.to_true(input, &) + BOOLEAN_MAP.fetch(input.to_s) do + if block_given? + yield + else + raise CoercionError, "#{input} cannot be coerced to true" + end + end + end + + # @param [String, Object] input + # + # @return [Boolean,Object] + # + # @see TRUE_VALUES + # @see FALSE_VALUES + # + # @raise CoercionError + # + # @api public + def self.to_false(input, &) + BOOLEAN_MAP.fetch(input.to_s) do + if block_given? + yield + else + raise CoercionError, "#{input} cannot be coerced to false" + end + end + end + + # @param [#to_int, #to_i, Object] input + # + # @return [Integer, nil, Object] + # + # @raise CoercionError + # + # @api public + def self.to_int(input, &) + if input.is_a?(::String) + Integer(input, 10) + else + Integer(input) + end + rescue ::ArgumentError, ::TypeError => e + CoercionError.handle(e, &) + end + + # @param [#to_f, Object] input + # + # @return [Float, nil, Object] + # + # @raise CoercionError + # + # @api public + def self.to_float(input, &) + Float(input) + rescue ::ArgumentError, ::TypeError => e + CoercionError.handle(e, &) + end + + # @param [#to_d, Object] input + # + # @return [BigDecimal, nil, Object] + # + # @raise CoercionError + # + # @api public + def self.to_decimal(input, &) + to_float(input) do + if block_given? + return yield + else + raise CoercionError, "#{input.inspect} cannot be coerced to decimal" + end + end + + input.to_d + end + + # @param [Array, String, Object] input + # + # @return [Array, Object] + # + # @raise CoercionError + # + # @api public + def self.to_ary(input, &) + if empty_str?(input) + [] + elsif input.is_a?(::Array) + input + elsif block_given? + yield + else + raise CoercionError, "#{input.inspect} cannot be coerced to array" + end + end + + # @param [Hash, String, Object] input + # + # @return [Hash, Object] + # + # @raise CoercionError + # + # @api public + def self.to_hash(input, &) + if empty_str?(input) + {} + elsif input.is_a?(::Hash) + input + elsif block_given? + yield + else + raise CoercionError, "#{input.inspect} cannot be coerced to hash" + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/compat.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/compat.rb new file mode 100644 index 00000000..8e9b8f90 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/compat.rb @@ -0,0 +1 @@ +# frozen_string_literal: true diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/compiler.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/compiler.rb new file mode 100644 index 00000000..21051111 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/compiler.rb @@ -0,0 +1,131 @@ +# frozen_string_literal: true + +module Dry + module Types + # @api private + class Compiler + extend ::Dry::Core::Deprecations[:"dry-types"] + + attr_reader :registry + + def initialize(registry) + @registry = registry + end + + def call(ast) = visit(ast) + + def visit(node) + type, body = node + send(:"visit_#{type}", body) + end + + def visit_constrained(node) + nominal, rule = node + type = visit(nominal) + type.constrained_type.new(type, rule: visit_rule(rule)) + end + + def visit_constructor(node) + nominal, fn = node + primitive = visit(nominal) + primitive.constructor(compile_fn(fn)) + end + + def visit_lax(node) + Types::Lax.new(visit(node)) + end + deprecate(:visit_safe, :visit_lax) + + def visit_nominal(node) + type, meta = node + nominal_name = "nominal.#{Types.identifier(type)}" + + if registry.registered?(nominal_name) + registry[nominal_name].meta(meta) + else + Nominal.new(type, meta: meta) + end + end + + def visit_rule(node) + ::Dry::Types.rule_compiler.([node])[0] + end + + def visit_sum(node) + *types, meta = node + types.map { |type| visit(type) }.reduce(:|).meta(meta) + end + + def visit_array(node) + member, meta = node + member = visit(member) unless member.is_a?(::Class) + registry["nominal.array"].of(member).meta(meta) + end + + def visit_hash(node) + opts, meta = node + registry["nominal.hash"].with(**opts, meta: meta) + end + + def visit_schema(node) + keys, options, meta = node + registry["nominal.hash"].schema(keys.map { |key| visit(key) }).with(**options, meta: meta) + end + + def visit_json_hash(node) + keys, meta = node + registry["json.hash"].schema(keys.map { |key| visit(key) }, meta) + end + + def visit_json_array(node) + member, meta = node + registry["json.array"].of(visit(member)).meta(meta) + end + + def visit_params_hash(node) + keys, meta = node + registry["params.hash"].schema(keys.map { |key| visit(key) }, meta) + end + + def visit_params_array(node) + member, meta = node + registry["params.array"].of(visit(member)).meta(meta) + end + + def visit_key(node) + name, required, type = node + Schema::Key.new(visit(type), name, required: required) + end + + def visit_enum(node) + type, mapping = node + Enum.new(visit(type), mapping: mapping) + end + + def visit_map(node) + key_type, value_type, meta = node + registry["nominal.hash"].map(visit(key_type), visit(value_type)).meta(meta) + end + + def visit_any(meta) + registry["any"].meta(meta) + end + + def compile_fn(fn) + type, *node = fn + + case type + when :id + ::Dry::Types::FnContainer[node.fetch(0)] + when :callable + node.fetch(0) + when :method + target, method = node + target.method(method) + else + raise ::ArgumentError, "Cannot build callable from #{fn.inspect}" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/composition.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/composition.rb new file mode 100644 index 00000000..8b56e636 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/composition.rb @@ -0,0 +1,138 @@ +# frozen_string_literal: true + +require "dry/core/equalizer" +require "dry/types/options" +require "dry/types/meta" + +module Dry + module Types + module Composition + include Type + include Builder + include Options + include Meta + include Printable + include ::Dry::Equalizer( + :left, :right, :options, :meta, + inspect: false, + immutable: true + ) + + # @return [Type] + attr_reader :left + + # @return [Type] + attr_reader :right + + module Constrained + def rule + left.rule.public_send(self.class.operator, right.rule) + end + + def constrained? + true + end + end + + def self.included(base) + composition_name = Inflector.demodulize(base) + ast_type = Inflector.underscore(composition_name).to_sym + base.define_singleton_method(:ast_type) { ast_type } + base.define_singleton_method(:composition_name) { composition_name } + base.const_set("Constrained", ::Class.new(base) { include Constrained }) + end + + # @param [Type] left + # @param [Type] right + # @param [Hash] options + # + # @api private + def initialize(left, right, **options) + super + @left, @right = left, right + freeze + end + + # @return [String] + # + # @api public + def name = "#{left.name} #{self.class.operator} #{right.name}" + + # @return [false] + # + # @api public + def default? = false + + # @return [false] + # + # @api public + def constrained? = false + + # @return [Boolean] + # + # @api public + def optional? = false + + # @param [Object] input + # + # @return [Object] + # + # @api private + def call_unsafe(input) = raise ::NotImplementedError + + # @param [Object] input + # + # @return [Object] + # + # @api private + def call_safe(input, &) = raise ::NotImplementedError + + # @param [Object] input + # + # @api public + def try(input, &) = raise ::NotImplementedError + + # @api private + def success(input) + result = try(input) + if result.success? + result + else + raise ::ArgumentError, "Invalid success value '#{input}' for #{inspect}" + end + end + + # @api private + def failure(input, _error = nil) + result = try(input) + if result.failure? + result + else + raise ::ArgumentError, "Invalid failure value '#{input}' for #{inspect}" + end + end + + # @param [Object] value + # + # @return [Boolean] + # + # @api private + def primitive?(value) = raise ::NotImplementedError + + # @see Nominal#to_ast + # + # @api public + def to_ast(meta: true) + [self.class.ast_type, + [left.to_ast(meta: meta), right.to_ast(meta: meta), meta ? self.meta : EMPTY_HASH]] + end + + # Wrap the type with a proc + # + # @return [Proc] + # + # @api public + def to_proc = proc { |value| self.(value) } + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/constrained.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/constrained.rb new file mode 100644 index 00000000..9888e9f0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/constrained.rb @@ -0,0 +1,146 @@ +# frozen_string_literal: true + +module Dry + module Types + # Constrained types apply rules to the input + # + # @api public + class Constrained + include Type + include Decorator + include Builder + include Printable + include ::Dry::Equalizer(:type, :rule, inspect: false, immutable: true) + + # @return [Dry::Logic::Rule] + attr_reader :rule + + # @param [Type] type + # + # @param [Hash] options + # + # @api public + def initialize(type, **options) + super + @rule = options.fetch(:rule) + end + + # @return [Object] + # + # @api private + def call_unsafe(input) + result = rule.(input) + + if result.success? + type.call_unsafe(input) + else + raise ConstraintError.new(result, input) + end + end + + # @return [Object] + # + # @api private + def call_safe(input, &) + if rule[input] + type.call_safe(input, &) + else + yield + end + end + + # Safe coercion attempt. It is similar to #call with a + # block given but returns a Result instance with metadata + # about errors (if any). + # + # @overload try(input) + # @param [Object] input + # @return [Logic::Result] + # + # @overload try(input) + # @param [Object] input + # @yieldparam [Failure] failure + # @yieldreturn [Object] + # @return [Object] + # + # @api public + def try(input, &) + result = rule.(input) + + if result.success? + type.try(input, &) + else + failure = failure(input, ConstraintError.new(result, input)) + block_given? ? yield(failure) : failure + end + end + + # @param *nullary_rules [Array] a list of rules that do not require an additional + # argument (e.g., :odd) + # @param **unary_rules [Hash] a list of rules that require an additional argument + # (e.g., gt: 0) + # The parameters are merger to create a rules hash provided to {Types.Rule} and combined + # using {&} with previous {#rule} + # + # @return [Constrained] + # + # @see Dry::Logic::Operators#and + # + # @api public + def constrained(*nullary_rules, **unary_rules) + nullary_rules_hash = parse_arguments(nullary_rules) + + rules = nullary_rules_hash.merge(unary_rules) + + with(rule: rule & Types.Rule(rules)) + end + + # @return [true] + # + # @api public + def constrained? = true + + # @param [Object] value + # + # @return [Boolean] + # + # @api public + def ===(value) = valid?(value) + + # Build lax type. Constraints are not applicable to lax types hence unwrapping + # + # @return [Lax] + # @api public + def lax = type.lax + + # @see Nominal#to_ast + # @api public + def to_ast(meta: true) + [:constrained, [type.to_ast(meta: meta), rule.to_ast]] + end + + # @api private + def constructor_type = type.constructor_type + + private + + # @param [Object] response + # + # @return [Boolean] + # + # @api private + def decorate?(response) = super || response.is_a?(Constructor) + + # @param [Array] positional_args + # + # @return [Hash] + # + # @api private + def parse_arguments(positional_arguments) + return positional_arguments.first if positional_arguments.first.is_a?(::Hash) + + positional_arguments.flatten.zip([]).to_h + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/constrained/coercible.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/constrained/coercible.rb new file mode 100644 index 00000000..931d72ef --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/constrained/coercible.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +module Dry + module Types + class Constrained + # Common coercion-related API for constrained types + # + # @api public + class Coercible < Constrained + # @return [Object] + # + # @api private + def call_unsafe(input) + coerced = type.call_unsafe(input) + result = rule.(coerced) + + if result.success? + coerced + else + raise ConstraintError.new(result, input) + end + end + + # @return [Object] + # + # @api private + def call_safe(input) + coerced = type.call_safe(input) { return yield } + + if rule[coerced] + coerced + else + yield(coerced) + end + end + + # @see Dry::Types::Constrained#try + # + # @api public + def try(input, &) + result = type.try(input) + + if result.success? + validation = rule.(result.input) + + if validation.success? + result + else + failure = failure(result.input, ConstraintError.new(validation, input)) + block_given? ? yield(failure) : failure + end + else + block_given? ? yield(result) : result + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/constraints.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/constraints.rb new file mode 100644 index 00000000..6032c5d0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/constraints.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module Dry + # Helper methods for constraint types + # + # @api public + module Types + # @param [Hash] options + # + # @return [Dry::Logic::Rule] + # + # @api public + def self.Rule(options) + rule_compiler.( + options.map { |key, val| + ::Dry::Logic::Rule::Predicate.build( + ::Dry::Logic::Predicates[:"#{key}?"] + ).curry(val).to_ast + } + ).reduce(:and) + end + + # @return [Dry::Logic::RuleCompiler] + # + # @api private + def self.rule_compiler + @rule_compiler ||= ::Dry::Logic::RuleCompiler.new(::Dry::Logic::Predicates) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/constructor.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/constructor.rb new file mode 100644 index 00000000..40e58741 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/constructor.rb @@ -0,0 +1,191 @@ +# frozen_string_literal: true + +module Dry + module Types + # Constructor types apply a function to the input that is supposed to return + # a new value. Coercion is a common use case for constructor types. + # + # @api public + class Constructor < Nominal + include ::Dry::Equalizer(:type, :options, inspect: false, immutable: true) + + # @return [#call] + attr_reader :fn + + # @return [Type] + attr_reader :type + + undef :constrained?, :meta, :optional?, :primitive, :default?, :name + + # @param [Builder, Object] input + # @param [Hash] options + # @param [#call, nil] block + # + # @api public + def self.new(input, fn: Undefined, **options, &block) + type = input.is_a?(Builder) ? input : Nominal.new(input) + super(type, **options, fn: Function[Undefined.default(fn, block)]) + end + + # @param [Builder, Object] input + # @param [Hash] options + # @param [#call, nil] block + # + # @api public + def self.[](type, fn:, **options) + function = Function[fn] + + if function.wrapper? + wrapper_type.new(type, fn: function, **options) + else + new(type, fn: function, **options) + end + end + + # @api private + def self.wrapper_type + @wrapper_type ||= + if self < Wrapper + self + else + const_set(:Wrapping, ::Class.new(self).include(Wrapper)) + end + end + + # Instantiate a new constructor type instance + # + # @param [Type] type + # @param [Function] fn + # @param [Hash] options + # + # @api private + def initialize(type, fn: nil, **options) + @type = type + @fn = fn + + super(type, **options, fn: fn) + end + + # @return [Object] + # + # @api private + def call_safe(input) + coerced = fn.(input) { |output = input| return yield(output) } + type.call_safe(coerced) { |output = coerced| yield(output) } + end + + # @return [Object] + # + # @api private + def call_unsafe(input) = type.call_unsafe(fn.(input)) + + # @param [Object] input + # @param [#call,nil] block + # + # @return [Logic::Result, Types::Result] + # @return [Object] if block given and try fails + # + # @api public + def try(input, &) + value = fn.(input) + rescue CoercionError => e + failure = failure(input, e) + block_given? ? yield(failure) : failure + else + type.try(value, &) + end + + # Build a new constructor by appending a block to the coercion function + # + # @param [#call, nil] new_fn + # @param [Hash] options + # @param [#call, nil] block + # + # @return [Constructor] + # + # @api public + def constructor(new_fn = nil, **options, &block) + next_fn = Function[new_fn || block] + + if next_fn.wrapper? + self.class.wrapper_type.new(with(**options), fn: next_fn) + else + with(**options, fn: fn >> next_fn) + end + end + alias_method :append, :constructor + alias_method :>>, :constructor + + # @return [Class] + # + # @api private + def constrained_type = Constrained::Coercible + + # @see Nominal#to_ast + # + # @api public + def to_ast(meta: true) + [:constructor, [type.to_ast(meta: meta), fn.to_ast]] + end + + # Build a new constructor by prepending a block to the coercion function + # + # @param [#call, nil] new_fn + # @param [Hash] options + # @param [#call, nil] block + # + # @return [Constructor] + # + # @api public + def prepend(new_fn = nil, **options, &block) + with(**options, fn: fn << (new_fn || block)) + end + alias_method :<<, :prepend + + # Build a lax type + # + # @return [Lax] + # @api public + def lax = Lax.new(constructor_type[type.lax, **options]) + + # Wrap the type with a proc + # + # @return [Proc] + # + # @api public + def to_proc = proc { self.(_1) } + + private + + # @param [Symbol] meth + # @param [Boolean] include_private + # @return [Boolean] + # + # @api private + def respond_to_missing?(meth, include_private = false) + super || type.respond_to?(meth) + end + + # Delegates missing methods to {#type} + # + # @param [Symbol] method + # @param [Array] args + # @param [#call, nil] block + # + # @api private + def method_missing(method, ...) + if type.respond_to?(method) + response = type.public_send(method, ...) + + if response.is_a?(Type) && response.instance_of?(type.class) + response.constructor_type[response, **options] + else + response + end + else + super + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/constructor/function.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/constructor/function.rb new file mode 100644 index 00000000..fed1ea94 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/constructor/function.rb @@ -0,0 +1,203 @@ +# frozen_string_literal: true + +require "concurrent/map" + +module Dry + module Types + class Constructor < Nominal + # Function is used internally by Constructor types + # + # @api private + class Function + # Wrapper for unsafe coercion functions + # + # @api private + class Safe < Function + def call(input, &) + @fn.(input) + rescue ::NoMethodError, ::TypeError, ::ArgumentError => e + CoercionError.handle(e, &) + end + end + + # Coercion via a method call on a known object + # + # @api private + class MethodCall < Function + @cache = ::Concurrent::Map.new + + # Choose or build the base class + # + # @return [Function] + def self.call_class(method, public, safe) + @cache.fetch_or_store([method, public, safe]) do + if public + ::Class.new(PublicCall) do + include PublicCall.call_interface(method, safe) + + define_method(:__to_s__) do + "#" + end + end + elsif safe + PrivateCall + else + PrivateSafeCall + end + end + end + + # Coercion with a publicly accessible method call + # + # @api private + class PublicCall < MethodCall + @interfaces = ::Concurrent::Map.new + + # Choose or build the interface + # + # @return [::Module] + def self.call_interface(method, safe) + @interfaces.fetch_or_store([method, safe]) do + ::Module.new do + if safe + module_eval(<<~RUBY, __FILE__, __LINE__ + 1) + def call(input, &) # def call(input, &) + @target.#{method}(input, &) # @target.coerce(input, &) + end # end + RUBY + else + module_eval(<<~RUBY, __FILE__, __LINE__ + 1) + def call(input, &) # def call(input, &) + @target.#{method}(input) # @target.coerce(input) + rescue ::NoMethodError, ::TypeError, ::ArgumentError => error # rescue ::NoMethodError, ::TypeError, ::ArgumentError => error + CoercionError.handle(error, &) # CoercionError.handle(error, &) + end # end + RUBY + end + end + end + end + end + + # Coercion via a private method call + # + # @api private + class PrivateCall < MethodCall + def call(input, &) = @target.send(@name, input, &) + end + + # Coercion via an unsafe private method call + # + # @api private + class PrivateSafeCall < PrivateCall + def call(input, &) + @target.send(@name, input) + rescue ::NoMethodError, ::TypeError, ::ArgumentError => e + CoercionError.handle(e, &) + end + end + + # @api private + # + # @return [MethodCall] + def self.[](fn, safe) + public = fn.receiver.respond_to?(fn.name) + MethodCall.call_class(fn.name, public, safe).new(fn) + end + + attr_reader :target, :name + + def initialize(fn) + super + @target = fn.receiver + @name = fn.name + end + + def to_ast = [:method, target, name] + end + + class Wrapper < Function + # @return [Object] + def call(input, type, &) + @fn.(input, type, &) + rescue ::NoMethodError, ::TypeError, ::ArgumentError => e + CoercionError.handle(e, &) + end + alias_method :[], :call + + def arity = 2 + end + + # Choose or build specialized invokation code for a callable + # + # @param [#call] fn + # @return [Function] + def self.[](fn) + raise ::ArgumentError, "Missing constructor block" if fn.nil? + + if fn.is_a?(Function) + fn + elsif fn.respond_to?(:arity) && fn.arity.equal?(2) + Wrapper.new(fn) + elsif fn.is_a?(::Method) + MethodCall[fn, yields_block?(fn)] + elsif yields_block?(fn) + new(fn) + else + Safe.new(fn) + end + end + + # @return [Boolean] + def self.yields_block?(fn) + *, (last_arg,) = + if fn.respond_to?(:parameters) + fn.parameters + else + fn.method(:call).parameters + end + + last_arg.equal?(:block) + end + + include ::Dry::Equalizer(:fn, immutable: true) + + attr_reader :fn + + def initialize(fn) + @fn = fn + end + + # @return [Object] + def call(input, &) = @fn.(input, &) + alias_method :[], :call + + # @return [Integer] + def arity = 1 + + def wrapper? = arity.equal?(2) + + # @return [Array] + def to_ast + if fn.is_a?(::Proc) + [:id, FnContainer.register(fn)] + else + [:callable, fn] + end + end + + # @return [Function] + def >>(other) + f = Function[other] + Function[-> x, &b { f.(self.(x, &b), &b) }] + end + + # @return [Function] + def <<(other) + f = Function[other] + Function[-> x, &b { self.(f.(x, &b), &b) }] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/constructor/wrapper.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/constructor/wrapper.rb new file mode 100644 index 00000000..bae6a8d1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/constructor/wrapper.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true + +module Dry + module Types + # @api public + class Constructor < Nominal + module Wrapper + # @return [Object] + # + # @api private + def call_safe(input, &) = fn.(input, type, &) + + # @return [Object] + # + # @api private + def call_unsafe(input) = fn.(input, type) + + # @param [Object] input + # @param [#call,nil] block + # + # @return [Logic::Result, Types::Result] + # @return [Object] if block given and try fails + # + # @api public + def try(input, &) + value = fn.(input, type) + rescue CoercionError => e + failure = failure(input, e) + block_given? ? yield(failure) : failure + else + type.try(value, &) + end + + # Define a constructor for the type + # + # @param [#call,nil] constructor + # @param [Hash] options + # @param [#call,nil] block + # + # @return [Constructor] + # + # @api public + define_method(:constructor, Builder.instance_method(:constructor)) + alias_method :append, :constructor + alias_method :>>, :constructor + + # Build a new constructor by prepending a block to the coercion function + # + # @param [#call, nil] new_fn + # @param [Hash] options + # @param [#call, nil] block + # + # @return [Constructor] + # + # @api public + def prepend(new_fn = nil, **options, &block) + prep_fn = Function[new_fn || block] + + decorated = + if prep_fn.wrapper? + type.constructor(prep_fn, **options) + else + type.prepend(prep_fn, **options) + end + + __new__(decorated) + end + alias_method :<<, :prepend + + # @return [Constructor] + # + # @api public + def lax + # return self back because wrapping function + # can handle failed type check + self + end + + private + + # Replace underlying type + # + # @api private + def __new__(type) = self.class.new(type, *@__args__.drop(1), **@options) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/container.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/container.rb new file mode 100644 index 00000000..0b0f5869 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/container.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module Dry + module Types + # Internal container for the built-in types + # + # @api private + class Container + include Core::Container::Mixin + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/core.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/core.rb new file mode 100644 index 00000000..ccdcffde --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/core.rb @@ -0,0 +1,106 @@ +# frozen_string_literal: true + +module Dry + module Types + # Primitives with {Kernel} coercion methods + KERNEL_COERCIBLE = { + string: String, + integer: Integer, + float: Float, + decimal: BigDecimal, + array: ::Array, + hash: ::Hash + }.freeze + + # Primitives with coercions through by convention `to_*` methods + METHOD_COERCIBLE = { + symbol: Symbol + }.freeze + + # By convention methods to coerce {METHOD_COERCIBLE} primitives + METHOD_COERCIBLE_METHODS = { + symbol: :to_sym + }.freeze + + # Primitives that are non-coercible + NON_COERCIBLE = { + nil: NilClass, + class: Class, + true: TrueClass, + false: FalseClass, + date: Date, + date_time: DateTime, + time: Time, + range: Range + }.freeze + + # All built-in primitives + ALL_PRIMITIVES = [ + KERNEL_COERCIBLE, METHOD_COERCIBLE, NON_COERCIBLE + ].reduce(&:merge).freeze + + # All coercible types + COERCIBLE = KERNEL_COERCIBLE.merge(METHOD_COERCIBLE).freeze + + # All built-in primitives except {NilClass} + NON_NIL = ALL_PRIMITIVES.except(:nil).freeze + + # Register generic types for {ALL_PRIMITIVES} + ALL_PRIMITIVES.each do |name, primitive| + type = Nominal[primitive].new(primitive) + register("nominal.#{name}", type) + end + + # Register strict types for {ALL_PRIMITIVES} + ALL_PRIMITIVES.each do |name, primitive| + type = self["nominal.#{name}"].constrained(type: primitive) + register(name.to_s, type) + register("strict.#{name}", type) + end + + # Register {KERNEL_COERCIBLE} types + KERNEL_COERCIBLE.each do |name, primitive| + register( + "coercible.#{name}", + self["nominal.#{name}"].constructor(::Kernel.method(primitive.name)) + ) + end + + # Register {METHOD_COERCIBLE} types + METHOD_COERCIBLE.each_key do |name| + register( + "coercible.#{name}", + self["nominal.#{name}"].constructor(&METHOD_COERCIBLE_METHODS[name]) + ) + end + + # Register optional strict {NON_NIL} types + NON_NIL.each_key do |name| + type = self[name.to_s].optional + register("optional.strict.#{name}", type) + register("optional.#{name}", type) + end + + # Register optional {COERCIBLE} types + COERCIBLE.each_key do |name| + register( + "optional.coercible.#{name}", + self["coercible.#{name}"].optional + ) + end + + # Register `:bool` since it's common and not a built-in Ruby type :( + register("nominal.bool", self["nominal.true"] | self["nominal.false"]) + bool = self["strict.true"] | self["strict.false"] + register("strict.bool", bool) + register("bool", bool) + + register("any", Any) + register("nominal.any", Any) + register("strict.any", Any) + end +end + +require "dry/types/coercions" +require "dry/types/params" +require "dry/types/json" diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/decorator.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/decorator.rb new file mode 100644 index 00000000..e01c12a3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/decorator.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +module Dry + module Types + # Common API for types + # + # @api public + module Decorator + include Options + + # @return [Type] + attr_reader :type + + # @param [Type] type + def initialize(type, *, **) + super + @type = type + end + + # @param [Object] input + # @param [#call, nil] block + # + # @return [Result,Logic::Result] + # @return [Object] if block given and try fails + # + # @api public + def try(input, &) = type.try(input, &) + + # @return [Boolean] + # + # @api public + def default? = type.default? + + # @return [Boolean] + # + # @api public + def constrained? = type.constrained? + + # @param [Symbol] meth + # @param [Boolean] include_private + # + # @return [Boolean] + # + # @api public + def respond_to_missing?(meth, include_private = false) + super || type.respond_to?(meth) + end + + # Wrap the type with a proc + # + # @return [Proc] + # + # @api public + def to_proc = proc { |value| self.(value) } + + private + + # @param [Object] response + # + # @return [Boolean] + # + # @api private + def decorate?(response) = response.is_a?(type.class) + + # Delegates missing methods to {#type} + # + # @param [Symbol] meth + # @param [Array] args + # @param [#call, nil] block + # + # @api private + def method_missing(meth, ...) + if type.respond_to?(meth) + response = type.public_send(meth, ...) + + if decorate?(response) + __new__(response) + else + response + end + else + super + end + end + + # Replace underlying type + # + # @api private + def __new__(type) + self.class.new(type, *@__args__.drop(1), **@options) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/default.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/default.rb new file mode 100644 index 00000000..77839faa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/default.rb @@ -0,0 +1,122 @@ +# frozen_string_literal: true + +module Dry + module Types + # Default types are useful when a missing value should be replaced by a default one + # + # @api public + class Default + # @api private + class Callable < Default + include ::Dry::Equalizer(:type, inspect: false, immutable: true) + + # Evaluates given callable + # @return [Object] + def evaluate + value.call(type) + end + + # @return [true] + def callable? + true + end + end + + include Type + include Decorator + include Builder + include Printable + include ::Dry::Equalizer(:type, :value, inspect: false, immutable: true) + + # @return [Object] + attr_reader :value + + alias_method :evaluate, :value + + # @param [Object, #call] value + # + # @return [Class] {Default} or {Default::Callable} + # + # @api private + def self.[](value) + if value.respond_to?(:call) + Callable + else + self + end + end + + # @param [Type] type + # @param [Object] value + # + # @api private + def initialize(type, value, **) + super + @value = value + end + + # Build a constrained type + # + # @param [Array] args see {Dry::Types::Builder#constrained} + # + # @return [Default] + # + # @api public + def constrained(...) = type.constrained(...).default(value) + + # @return [true] + # + # @api public + def default? = true + + # @param [Object] input + # + # @return [Result::Success] + # + # @api public + def try(input = Undefined, &) + if input.equal?(Undefined) + success(evaluate) + else + type.try(input) + end + end + + # @return [Boolean] + # + # @api public + def valid?(value = Undefined) = Undefined.equal?(value) || super + + # @param [Object] input + # + # @return [Object] value passed through {#type} or {#default} value + # + # @api private + def call_unsafe(input = Undefined) + if input.equal?(Undefined) + evaluate + else + Undefined.default(type.call_unsafe(input)) { evaluate } + end + end + + # @param [Object] input + # + # @return [Object] value passed through {#type} or {#default} value + # + # @api private + def call_safe(input = Undefined, &) + if input.equal?(Undefined) + evaluate + else + Undefined.default(type.call_safe(input, &)) { evaluate } + end + end + + # @return [false] + # + # @api private + def callable? = false + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/enum.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/enum.rb new file mode 100644 index 00000000..1f16ee99 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/enum.rb @@ -0,0 +1,121 @@ +# frozen_string_literal: true + +module Dry + module Types + # Enum types can be used to define an enum on top of an existing type + # + # @api public + class Enum + include Type + include ::Dry::Equalizer(:type, :mapping, inspect: false, immutable: true) + include Decorator + include Builder + + # @return [Array] + attr_reader :values + + # @return [Hash] + attr_reader :mapping + + # @return [Hash] + attr_reader :inverted_mapping + + # @param [Type] type + # @param [Hash] options + # @option options [Array] :values + # + # @api private + def initialize(type, **options) + super + @mapping = options.fetch(:mapping).freeze + @values = @mapping.keys.freeze + @inverted_mapping = @mapping.invert.freeze + freeze + end + + # @return [Object] + # + # @api private + def call_unsafe(input) = type.call_unsafe(map_value(input)) + + # @return [Object] + # + # @api private + def call_safe(input, &) = type.call_safe(map_value(input), &) + + # @see Dry::Types::Constrained#try + # + # @api public + def try(input, &) = super(map_value(input)) + + # @api private + def default(*) + raise ".enum(*values).default(value) is not supported. Call " \ + ".default(value).enum(*values) instead" + end + + # Check whether a value is in the enum + alias_method :include?, :valid? + + # @see Nominal#to_ast + # + # @api public + def to_ast(meta: true) + [:enum, [type.to_ast(meta: meta), mapping]] + end + + # @return [String] + # + # @api public + def to_s = PRINTER.(self) + + # Iterate over each enum value + # + # @return [Array, Enumerator] + # + # @api public + def each_value(&) + values.each(&) + end + + alias_method :inspect, :to_s + + # @return [String] + # + # @api public + def name = "#{super}(#{joined_values})" + + # @return [String] + # + # @api private + def joined_values + mapping.keys.map { |value| + if value.is_a?(::String) + value + else + value.inspect + end + }.join("|") + end + + private + + # Maps a value + # + # @param [Object] input + # + # @return [Object] + # + # @api private + def map_value(input) + if input.equal?(Undefined) + type.call + elsif mapping.key?(input) + input + else + inverted_mapping.fetch(input, input) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/errors.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/errors.rb new file mode 100644 index 00000000..3a69306c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/errors.rb @@ -0,0 +1,138 @@ +# frozen_string_literal: true + +module Dry + module Types + extend ::Dry::Core::ClassAttributes + + # @!attribute [r] namespace + # @return [Container{String => Nominal}] + defines :namespace + + namespace self + + # Base class for coercion errors raise by dry-types + # + class CoercionError < ::StandardError + # @api private + def self.handle(exception, meta: Undefined) + if block_given? + yield + else + raise new( + exception.message, + meta: meta, + backtrace: exception.backtrace + ) + end + end + + # Metadata associated with the error + # + # @return [Object] + attr_reader :meta + + # @api private + def initialize(message, meta: Undefined, backtrace: Undefined) + unless message.is_a?(::String) + raise ::ArgumentError, "message must be a string, #{message.class} given" + end + + super(message) + @meta = Undefined.default(meta, nil) + set_backtrace(backtrace) unless Undefined.equal?(backtrace) + end + end + + # Collection of multiple errors + # + class MultipleError < CoercionError + # @return [Array] + attr_reader :errors + + # @param [Array] errors + def initialize(errors) + super("") + @errors = errors + end + + # @return string + def message = errors.map(&:message).join(", ") + + # @return [Array] + def meta = errors.map(&:meta) + end + + class SchemaError < CoercionError + # @return [String, Symbol] + attr_reader :key + + # @return [Object] + attr_reader :value + + # @param [String,Symbol] key + # @param [Object] value + # @param [String, #to_s] result + def initialize(key, value, result) + @key = key + @value = value + super( + "#{value.inspect} (#{value.class}) has invalid type " \ + "for :#{key} violates constraints (#{result} failed)" + ) + end + end + + MapError = ::Class.new(CoercionError) + + SchemaKeyError = ::Class.new(CoercionError) + private_constant(:SchemaKeyError) + + class MissingKeyError < SchemaKeyError + # @return [Symbol] + attr_reader :key + + # @param [String,Symbol] key + def initialize(key) + @key = key + super("#{key.inspect} is missing in Hash input") + end + end + + class UnknownKeysError < SchemaKeyError + # @return [Array] + attr_reader :keys + + # @param [] keys + def initialize(keys) + @keys = keys + super("unexpected keys #{keys.inspect} in Hash input") + end + end + + class ConstraintError < CoercionError + # @return [String, #to_s] + attr_reader :result + # @return [Object] + attr_reader :input + + # @param [String, #to_s] result + # @param [Object] input + def initialize(result, input) + @result = result + @input = input + + if result.is_a?(::String) + super(result) + else + super(to_s) + end + end + + # @return [String] + def message + "#{input.inspect} violates constraints (#{result} failed)" + end + alias_method :to_s, :message + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/extensions.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/extensions.rb new file mode 100644 index 00000000..c519a039 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/extensions.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +Dry::Types.register_extension(:maybe) do + require "dry/types/extensions/maybe" +end + +Dry::Types.register_extension(:monads) do + require "dry/types/extensions/monads" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/extensions/maybe.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/extensions/maybe.rb new file mode 100644 index 00000000..7947e3ca --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/extensions/maybe.rb @@ -0,0 +1,128 @@ +# frozen_string_literal: true + +require "dry/monads" +require "dry/monads/version" + +if Gem::Version.new(Dry::Monads::VERSION) < Gem::Version.new("1.5.0") + raise "dry-types requires dry-monads >= 1.5.0" +end + +module Dry + module Types + # Maybe extension provides Maybe types where values are wrapped using `Either` monad + # + # @api public + class Maybe + include Type + include ::Dry::Equalizer(:type, :options, inspect: false, immutable: true) + include Decorator + include Builder + include Printable + include ::Dry::Monads[:maybe] + + # @param [Dry::Monads::Maybe, Object] input + # + # @return [Dry::Monads::Maybe] + # + # @api private + def call_unsafe(input = Undefined) + case input + when ::Dry::Monads::Maybe + input + when Undefined + None() + else + Maybe(type.call_unsafe(input)) + end + end + + # @param [Dry::Monads::Maybe, Object] input + # + # @return [Dry::Monads::Maybe] + # + # @api private + def call_safe(input = Undefined) + case input + when ::Dry::Monads::Maybe + input + when Undefined + None() + else + Maybe(type.call_safe(input) { |output = input| return yield(output) }) + end + end + + # @param [Object] input + # + # @return [Result::Success] + # + # @api public + def try(input = Undefined, &) + result = type.try(input) + + if result.success? + Result::Success.new(Maybe(result.input)) + else + result + end + end + + # @return [true] + # + # @api public + def default? = true + + # @param [Object] value + # + # @see Dry::Types::Builder#default + # + # @raise [ArgumentError] if nil provided as default value + # + # @api public + def default(value) + if value.nil? + raise ::ArgumentError, "nil cannot be used as a default of a maybe type" + else + super + end + end + end + + module Builder + # Turn a type into a maybe type + # + # @return [Maybe] + # + # @api public + def maybe = Maybe.new(Types["nil"] | self) + end + + # @api private + class Schema::Key # rubocop:disable Style/ClassAndModuleChildren + # @api private + def maybe = __new__(type.maybe) + end + + # @api private + class Printer + MAPPING[Maybe] = :visit_maybe + + # @api private + def visit_maybe(maybe) + visit(maybe.type) do |type| + yield "Maybe<#{type}>" + end + end + end + + # Register non-coercible maybe types + NON_NIL.each_key do |name| + register("maybe.strict.#{name}", self[name.to_s].maybe) + end + + # Register coercible maybe types + COERCIBLE.each_key do |name| + register("maybe.coercible.#{name}", self["coercible.#{name}"].maybe) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/extensions/monads.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/extensions/monads.rb new file mode 100644 index 00000000..97f6bd65 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/extensions/monads.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require "dry/monads" +require "dry/monads/version" + +if Gem::Version.new(Dry::Monads::VERSION) < Gem::Version.new("1.5.0") + raise "dry-types requires dry-monads >= 1.5.0" +end + +module Dry + module Types + # Monad extension for Result + # + # @api public + class Result + include ::Dry::Monads[:result] + + # Turn result into a monad + # + # This makes result objects work with dry-monads (or anything with a compatible interface) + # + # @return [Dry::Monads::Success,Dry::Monads::Failure] + # + # @api public + def to_monad + if success? + Success(input) + else + Failure([error, input]) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/fn_container.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/fn_container.rb new file mode 100644 index 00000000..7402fec5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/fn_container.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module Dry + module Types + # Internal container for constructor functions used by the built-in types + # + # @api private + class FnContainer + # @api private + def self.container + @container ||= Container.new + end + + # @api private + def self.register(function = ::Dry::Core::Constants::Undefined, &block) + fn = ::Dry::Core::Constants::Undefined.default(function, block) + fn_name = register_name(fn) + container.register(fn_name, fn) unless container.key?(fn_name) + fn_name + end + + # @api private + def self.[](fn_name) + if container.key?(fn_name) + container[fn_name] + else + fn_name + end + end + + # @api private + def self.register_name(function) + "fn_#{function.__id__}" + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/hash.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/hash.rb new file mode 100644 index 00000000..a4162186 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/hash.rb @@ -0,0 +1,134 @@ +# frozen_string_literal: true + +module Dry + module Types + # Hash types can be used to define maps and schemas + # + # @api public + class Hash < Nominal + NOT_REQUIRED = {required: false}.freeze + + # @overload schema(type_map, meta = EMPTY_HASH) + # @param [{Symbol => Dry::Types::Nominal}] type_map + # @param [Hash] meta + # @return [Dry::Types::Schema] + # + # @overload schema(keys) + # @param [Array] key List of schema keys + # @param [Hash] meta + # @return [Dry::Types::Schema] + # + # @api public + def schema(keys_or_map, meta = EMPTY_HASH) + if keys_or_map.is_a?(::Array) + keys = keys_or_map + else + keys = build_keys(keys_or_map) + end + + Schema.new(primitive, keys: keys, **options, meta: self.meta.merge(meta)) + end + + # Build a map type + # + # @param [Type] key_type + # @param [Type] value_type + # + # @return [Map] + # + # @api public + def map(key_type, value_type) + Map.new( + primitive, + key_type: resolve_type(key_type), + value_type: resolve_type(value_type), + meta: meta + ) + end + + # @api private + def weak(*) + raise "Support for old hash schemas was removed, please refer to the CHANGELOG " \ + "on how to proceed with the new API https://github.com/dry-rb/dry-types/blob/main/CHANGELOG.md" + end + alias_method :permissive, :weak + alias_method :strict, :weak + alias_method :strict_with_defaults, :weak + alias_method :symbolized, :weak + + # Injects a type transformation function for building schemas + # + # @param [#call,nil] proc + # @param [#call,nil] block + # + # @return [Hash] + # + # @api public + def with_type_transform(proc = nil, &block) + fn = proc || block + + raise ::ArgumentError, "a block or callable argument is required" if fn.nil? + + handle = ::Dry::Types::FnContainer.register(fn) + with(type_transform_fn: handle) + end + + # @api private + def constructor_type + ::Dry::Types::Hash::Constructor + end + + # Whether the type transforms types of schemas created by {Dry::Types::Hash#schema} + # + # @return [Boolean] + # + # @api public + def transform_types? + !options[:type_transform_fn].nil? + end + + # @param meta [Boolean] Whether to dump the meta to the AST + # + # @return [Array] An AST representation + # + # @api public + def to_ast(meta: true) + [:hash, + [options.slice(:type_transform_fn), + meta ? self.meta : EMPTY_HASH]] + end + + private + + # @api private + def build_keys(type_map) + type_fn = options.fetch(:type_transform_fn, Schema::NO_TRANSFORM) + type_transform = ::Dry::Types::FnContainer[type_fn] + + type_map.map do |map_key, type| + name, options = key_name(map_key) + key = Schema::Key.new(resolve_type(type), name, **options) + type_transform.(key) + end + end + + # @api private + def resolve_type(type) + case type + when Type then type + when ::Class, ::String then Types[type] + else type # rubocop:disable Lint/DuplicateBranch + end + end + + # @api private + def key_name(key) + if key.to_s.end_with?("?") + [key.to_s.chop.to_sym, NOT_REQUIRED] + else + [key, EMPTY_HASH] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/hash/constructor.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/hash/constructor.rb new file mode 100644 index 00000000..159cc26e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/hash/constructor.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Dry + module Types + # Hash type exposes additional APIs for working with schema hashes + # + # @api public + class Hash < Nominal + class Constructor < ::Dry::Types::Constructor + # @api private + def constructor_type = ::Dry::Types::Hash::Constructor + + # @return [Lax] + # + # @api public + def lax = Lax.new(type.lax.constructor(fn, meta: meta)) + + # @see Dry::Types::Array#of + # + # @api public + def schema(...) = type.schema(...).constructor(fn, meta: meta) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/implication.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/implication.rb new file mode 100644 index 00000000..765aba39 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/implication.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +module Dry + module Types + # Implication type + # + # @api public + class Implication + include Composition + + def self.operator = :> + + # @param [Object] input + # + # @return [Object] + # + # @api private + def call_unsafe(input) + if left.try(input).success? + right.call_unsafe(input) + else + input + end + end + + # @param [Object] input + # + # @return [Object] + # + # @api private + def call_safe(input, &) + if left.try(input).success? + right.call_safe(input, &) + else + input + end + end + + # @param [Object] input + # + # @api public + def try(input, &) + if left.try(input).success? + right.try(input, &) + else + Result::Success.new(input) + end + end + + # @param [Object] value + # + # @return [Boolean] + # + # @api private + def primitive?(value) + if left.primitive?(value) + right.primitive?(value) + else + true + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/inflector.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/inflector.rb new file mode 100644 index 00000000..0823997b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/inflector.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +require "dry/inflector" + +module Dry + module Types + Inflector = ::Dry::Inflector.new + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/intersection.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/intersection.rb new file mode 100644 index 00000000..64c43f07 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/intersection.rb @@ -0,0 +1,102 @@ +# frozen_string_literal: true + +require "dry/core/equalizer" +require "dry/types/options" +require "dry/types/meta" + +module Dry + module Types + # Intersection type + # + # @api public + class Intersection + include Composition + + def self.operator = :& + + # @param [Object] input + # + # @return [Object] + # + # @api private + def call_unsafe(input) + merge_results(left.call_unsafe(input), right.call_unsafe(input)) + end + + # @param [Object] input + # + # @return [Object] + # + # @api private + def call_safe(input, &) = try_sides(input, &).input + + # @param [Object] input + # + # @api public + def try(input) + try_sides(input) do |failure| + if block_given? + yield(failure) + else + failure + end + end + end + + # @param [Object] value + # + # @return [Boolean] + # + # @api private + def primitive?(value) + left.primitive?(value) && right.primitive?(value) + end + + private + + # @api private + def try_sides(input, &block) + results = [] + + [left, right].each do |side| + result = try_side(side, input, &block) + return result if result.failure? + + results << result + end + + Result::Success.new(merge_results(*results.map(&:input))) + end + + # @api private + def try_side(side, input) + failure = nil + + result = side.try(input) do |f| + failure = f + yield(f) + end + + if result.is_a?(Result) + result + elsif failure + Result::Failure.new(result, failure) + else + Result::Success.new(result) + end + end + + # @api private + def merge_results(left_result, right_result) + case left_result + when ::Array + left_result.zip(right_result).map { merge_results(_1, _2) } + when ::Hash + left_result.merge(right_result) + else + left_result + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/json.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/json.rb new file mode 100644 index 00000000..4652cba0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/json.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require "dry/types/coercions/json" + +module Dry + module Types + register("json.nil") do + self["nominal.nil"].constructor(Coercions::JSON.method(:to_nil)) + end + + register("json.date") do + self["nominal.date"].constructor(Coercions::JSON.method(:to_date)) + end + + register("json.date_time") do + self["nominal.date_time"].constructor(Coercions::JSON.method(:to_date_time)) + end + + register("json.time") do + self["nominal.time"].constructor(Coercions::JSON.method(:to_time)) + end + + register("json.decimal") do + self["nominal.decimal"].constructor(Coercions::JSON.method(:to_decimal)) + end + + register("json.symbol") do + self["nominal.symbol"].constructor(Coercions::JSON.method(:to_symbol)) + end + + register("json.array") { self["array"] } + + register("json.hash") { self["hash"] } + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/lax.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/lax.rb new file mode 100644 index 00000000..cb03d2a0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/lax.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +module Dry + module Types + # Lax types rescue from type-related errors when constructors fail + # + # @api public + class Lax + include Type + include Decorator + include Builder + include Printable + include ::Dry::Equalizer(:type, inspect: false, immutable: true) + + undef :options, :constructor, :<<, :>>, :prepend, :append + + # @param [Object] input + # + # @return [Object] + # + # @api public + def call(input, &) + type.call_safe(input) { |output = input| output } + end + alias_method :[], :call + alias_method :call_safe, :call + alias_method :call_unsafe, :call + + # @param [Object] input + # @param [#call,nil] block + # + # @yieldparam [Failure] failure + # @yieldreturn [Result] + # + # @return [Result,Logic::Result] + # + # @api public + def try(input, &) = type.try(input, &) + + # @see Nominal#to_ast + # + # @api public + def to_ast(meta: true) = [:lax, type.to_ast(meta: meta)] + + # @return [Lax] + # + # @api public + def lax = self + + private + + # @param [Object, Dry::Types::Constructor] response + # + # @return [Boolean] + # + # @api private + def decorate?(response) + super || response.is_a?(type.constructor_type) + end + end + + extend ::Dry::Core::Deprecations[:"dry-types"] + Safe = Lax + deprecate_constant(:Safe) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/map.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/map.rb new file mode 100644 index 00000000..74027e1b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/map.rb @@ -0,0 +1,134 @@ +# frozen_string_literal: true + +module Dry + module Types + # Homogeneous mapping. It describes a hash with unknown keys that match a certain type. + # + # @example + # type = Dry::Types['hash'].map( + # Dry::Types['integer'].constrained(gteq: 1, lteq: 10), + # Dry::Types['string'] + # ) + # + # type.(1 => 'right') + # # => {1 => 'right'} + # + # type.('1' => 'wrong') + # # Dry::Types::MapError: "1" violates constraints (type?(Integer, "1") + # # AND gteq?(1, "1") + # # AND lteq?(10, "1") failed) + # + # type.(11 => 'wrong') + # # Dry::Types::MapError: 11 violates constraints (lteq?(10, 11) failed) + # + # @api public + class Map < Nominal + def initialize(primitive, key_type: Types["any"], value_type: Types["any"], meta: EMPTY_HASH) + super + end + + # @return [Type] + # + # @api public + def key_type = options[:key_type] + + # @return [Type] + # + # @api public + def value_type = options[:value_type] + + # @return [String] + # + # @api public + def name = "Map" + + # @param [Hash] hash + # + # @return [Hash] + # + # @api private + def call_unsafe(hash) + try(hash) { |failure| + raise MapError, failure.error.message + }.input + end + + # @param [Hash] hash + # + # @return [Hash] + # + # @api private + def call_safe(hash) = try(hash) { return yield }.input + + # @param [Hash] hash + # + # @return [Result] + # + # @api public + def try(hash) + result = coerce(hash) + return result if result.success? || !block_given? + + yield(result) + end + + # @param meta [Boolean] Whether to dump the meta to the AST + # + # @return [Array] An AST representation + # + # @api public + def to_ast(meta: true) + [:map, + [key_type.to_ast(meta: true), + value_type.to_ast(meta: true), + meta ? self.meta : EMPTY_HASH]] + end + + # @return [Boolean] + # + # @api public + def constrained? = value_type.constrained? + + private + + # @api private + # rubocop:disable Metrics/AbcSize + def coerce(input) + assert_primitive(input) do + output = {} + failures = [] + + input.each do |k, v| + res_k = key_type.try(k) + res_v = value_type.try(v) + + if res_k.failure? + failures << res_k.error + elsif output.key?(res_k.input) + failures << CoercionError.new("duplicate coerced hash key #{res_k.input.inspect}") + elsif res_v.failure? + failures << res_v.error + else + output[res_k.input] = res_v.input + end + end + + if failures.empty? + success(output) + else + failure(input, MultipleError.new(failures)) + end + end + end + # rubocop:enable Metrics/AbcSize + + def assert_primitive(input) + if primitive?(input) + yield + else + failure(input, CoercionError.new("#{input.inspect} must be an instance of #{primitive}")) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/meta.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/meta.rb new file mode 100644 index 00000000..d88726bd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/meta.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +module Dry + module Types + # Storage for meta-data + # + # @api public + module Meta + def initialize(*args, meta: EMPTY_HASH, **options) + super(*args, **options) + @meta = meta.freeze + end + + # @param options [Hash] new_options + # + # @return [Type] + # + # @api public + def with(**options) = super(meta: @meta, **options) + + # @overload meta + # @return [Hash] metadata associated with type + # + # @overload meta(data) + # @param [Hash] new metadata to merge into existing metadata + # @return [Type] new type with added metadata + # + # @api public + def meta(data = Undefined) + if Undefined.equal?(data) + @meta + elsif data.empty? + self + else + with(meta: @meta.merge(data)) + end + end + + # Resets meta + # + # @return [Dry::Types::Type] + # + # @api public + def pristine = with(meta: EMPTY_HASH) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/module.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/module.rb new file mode 100644 index 00000000..3011f444 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/module.rb @@ -0,0 +1,127 @@ +# frozen_string_literal: true + +require "dry/types/builder_methods" + +module Dry + module Types + # Export types registered in a container as module constants. + # @example + # module Types + # include Dry.Types(:strict, :coercible, :nominal, default: :strict) + # end + # + # Types.constants + # # => [:Class, :Strict, :Symbol, :Integer, :Float, :String, :Array, :Hash, + # # :Decimal, :Nil, :True, :False, :Bool, :Date, :Nominal, :DateTime, :Range, + # # :Coercible, :Time] + # + # @api public + class Module < ::Module + def initialize(registry, *args, **kwargs) + @registry = registry + check_parameters(*args, **kwargs) + constants = type_constants(*args, **kwargs) + define_constants(constants) + extend(BuilderMethods) + + if constants.key?(:Nominal) + singleton_class.define_method(:included) do |base| + super(base) + base.instance_exec(const_get(:Nominal, false)) do |nominal| + extend Dry::Core::Deprecations[:"dry-types"] + const_set(:Definition, nominal) + deprecate_constant(:Definition, message: "Nominal") + end + end + end + end + + # @api private + # rubocop:disable Metrics/AbcSize + # rubocop:disable Metrics/PerceivedComplexity + def type_constants(*namespaces, default: Undefined, **aliases) + if namespaces.empty? && aliases.empty? && Undefined.equal?(default) + default_ns = :Strict + elsif Undefined.equal?(default) + default_ns = Undefined + else + default_ns = Types::Inflector.camelize(default).to_sym + end + + tree = registry_tree + + if namespaces.empty? && aliases.empty? + modules = tree.select { _2.is_a?(::Hash) }.map(&:first) + else + modules = (namespaces + aliases.keys).map { |n| + Types::Inflector.camelize(n).to_sym + } + end + + tree.each_with_object({}) do |(key, value), constants| + if modules.include?(key) + name = aliases.fetch(Inflector.underscore(key).to_sym, key) + constants[name] = value + end + + constants.update(value) if key == default_ns + end + end + # rubocop:enable Metrics/AbcSize + # rubocop:enable Metrics/PerceivedComplexity + + # @api private + def registry_tree + @registry_tree ||= @registry.keys.each_with_object({}) { |key, tree| + type = @registry[key] + *modules, const_name = key.split(".").map { |part| + Types::Inflector.camelize(part).to_sym + } + next if modules.empty? + + modules.reduce(tree) { |br, name| br[name] ||= {} }[const_name] = type + }.freeze + end + + private + + # @api private + def check_parameters(*namespaces, default: Undefined, **aliases) + referenced = namespaces.dup + referenced << default unless false.equal?(default) || Undefined.equal?(default) + referenced.concat(aliases.keys) + + known = @registry.keys.map { |k| + ns, *path = k.split(".") + ns.to_sym unless path.empty? + }.compact.uniq + + unknown = (referenced.uniq - known).first + + if unknown + raise ::ArgumentError, + "#{unknown.inspect} is not a known type namespace. " \ + "Supported options are #{known.map(&:inspect).join(", ")}" + end + end + + # @api private + def define_constants(constants, mod = self) + constants.each do |name, value| + case value + when ::Hash + if mod.const_defined?(name, false) + define_constants(value, mod.const_get(name, false)) + else + m = ::Module.new + mod.const_set(name, m) + define_constants(value, m) + end + else + mod.const_set(name, value) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/nominal.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/nominal.rb new file mode 100644 index 00000000..1c20cdac --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/nominal.rb @@ -0,0 +1,177 @@ +# frozen_string_literal: true + +module Dry + module Types + # Nominal types define a primitive class and do not apply any constructors or constraints + # + # Use these types for annotations and the base for building more complex types on top of them. + # + # @api public + class Nominal + include Type + include Options + include Meta + include Builder + include Printable + include ::Dry::Equalizer(:primitive, :options, :meta, inspect: false, immutable: true) + + # @return [Class] + attr_reader :primitive + + # @param [Class] primitive + # + # @return [Type] + # + # @api private + def self.[](primitive) + if primitive == ::Array + Types::Array + elsif primitive == ::Hash + Types::Hash + else + self + end + end + + ALWAYS = proc { true } + + # @param [Type,Class] primitive + # @param [Hash] options + # + # @api private + def initialize(primitive, **options) + super + @primitive = primitive + freeze + end + + # @return [String] + # + # @api public + def name = primitive.name + + # @return [false] + # + # @api public + def default? = false + + # @return [false] + # + # @api public + def constrained? = false + + # @return [false] + # + # @api public + def optional? = false + + # @param [BasicObject] input + # + # @return [BasicObject] + # + # @api private + def call_unsafe(input) = input + + # @param [BasicObject] input + # + # @return [BasicObject] + # + # @api private + def call_safe(input, &) = input + + # @param [Object] input + # + # @yieldparam [Failure] failure + # @yieldreturn [Result] + # + # @return [Result,Logic::Result] when a block is not provided + # @return [nil] otherwise + # + # @api public + def try(input, &) = success(input) + + # @param (see Dry::Types::Success#initialize) + # + # @return [Result::Success] + # + # @api public + def success(input) = Result::Success.new(input) + + # @param (see Failure#initialize) + # + # @return [Result::Failure] + # + # @api public + def failure(input, error) + raise ::ArgumentError, "error must be a CoercionError" unless error.is_a?(CoercionError) + + Result::Failure.new(input, error) + end + + # Checks whether value is of a #primitive class + # + # @param [Object] value + # + # @return [Boolean] + # + # @api public + def primitive?(value) = value.is_a?(primitive) + + # @api private + def coerce(input, &) + if primitive?(input) + input + elsif block_given? + yield + else + raise CoercionError, "#{input.inspect} must be an instance of #{primitive}" + end + end + + # @api private + def try_coerce(input) + result = success(input) + + coerce(input) do + result = failure( + input, + CoercionError.new("#{input.inspect} must be an instance of #{primitive}") + ) + end + + if block_given? + yield(result) + else + result + end + end + + # Return AST representation of a type nominal + # + # @return [Array] + # + # @api public + def to_ast(meta: true) + [:nominal, [primitive, meta ? self.meta : EMPTY_HASH]] + end + + # Return self. Nominal types are lax by definition + # + # @return [Nominal] + # + # @api public + def lax = self + + # Wrap the type with a proc + # + # @return [Proc] + # + # @api public + def to_proc = ALWAYS + end + + extend ::Dry::Core::Deprecations[:"dry-types"] + Definition = Nominal + deprecate_constant(:Definition, message: "Nominal") + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/options.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/options.rb new file mode 100644 index 00000000..090b3f64 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/options.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module Dry + module Types + # Common API for types with options + # + # @api private + module Options + # @return [Hash] + attr_reader :options + + # @see Nominal#initialize + # + # @api private + def initialize(*args, **options) + @__args__ = args.freeze + @options = options.freeze + end + + # @param [Hash] new_options + # + # @return [Type] + # + # @api private + def with(**new_options) + self.class.new(*@__args__, **options, **new_options) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/params.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/params.rb new file mode 100644 index 00000000..3664c75b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/params.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +require "dry/types/coercions/params" + +module Dry + module Types + register("params.nil") do + self["nominal.nil"].constructor(Coercions::Params.method(:to_nil)) + end + + register("params.date") do + self["nominal.date"].constructor(Coercions::Params.method(:to_date)) + end + + register("params.date_time") do + self["nominal.date_time"].constructor(Coercions::Params.method(:to_date_time)) + end + + register("params.time") do + self["nominal.time"].constructor(Coercions::Params.method(:to_time)) + end + + register("params.true") do + self["nominal.true"].constructor(Coercions::Params.method(:to_true)) + end + + register("params.false") do + self["nominal.false"].constructor(Coercions::Params.method(:to_false)) + end + + register("params.bool") do + self["params.true"] | self["params.false"] + end + + register("params.integer") do + self["nominal.integer"].constructor(Coercions::Params.method(:to_int)) + end + + register("params.float") do + self["nominal.float"].constructor(Coercions::Params.method(:to_float)) + end + + register("params.decimal") do + self["nominal.decimal"].constructor(Coercions::Params.method(:to_decimal)) + end + + register("params.array") do + self["nominal.array"].constructor(Coercions::Params.method(:to_ary)) + end + + register("params.hash") do + self["nominal.hash"].constructor(Coercions::Params.method(:to_hash)) + end + + register("params.symbol") do + self["nominal.symbol"].constructor(Coercions::Params.method(:to_symbol)) + end + + register("params.string", self["string"]) + + COERCIBLE.each_key do |name| + next if name.equal?(:string) + + register("optional.params.#{name}", self["params.nil"] | self["params.#{name}"]) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/predicate_inferrer.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/predicate_inferrer.rb new file mode 100644 index 00000000..6fb6c582 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/predicate_inferrer.rb @@ -0,0 +1,235 @@ +# frozen_string_literal: true + +module Dry + module Types + # PredicateInferrer returns the list of predicates used by a type. + # + # @api public + class PredicateInferrer + extend Core::Cache + + TYPE_TO_PREDICATE = { + ::DateTime => :date_time?, + ::Date => :date?, + ::Time => :time?, + ::FalseClass => :false?, + ::Integer => :int?, + ::Float => :float?, + ::NilClass => :nil?, + ::String => :str?, + ::TrueClass => :true?, + ::BigDecimal => :decimal?, + ::Array => :array? + }.freeze + + REDUCED_TYPES = { + [[[:true?], [:false?]]] => %i[bool?] + }.freeze + + HASH = %i[hash?].freeze + + ARRAY = %i[array?].freeze + + NIL = %i[nil?].freeze + + # Compiler reduces type AST into a list of predicates + # + # @api private + class Compiler + extend Core::ClassAttributes + + defines :infer_predicate_by_class_name + infer_predicate_by_class_name nil + + # @return [PredicateRegistry] + # @api private + attr_reader :registry + + # @api private + def initialize(registry) + @registry = registry + end + + # @api private + def infer_predicate(type) # rubocop:disable Metrics/PerceivedComplexity + pred = TYPE_TO_PREDICATE.fetch(type) do + if type.name.nil? || self.class.infer_predicate_by_class_name.equal?(false) + nil + else + candidate = :"#{type.name.split("::").last.downcase}?" + + if registry.key?(candidate) + if self.class.infer_predicate_by_class_name + candidate + else + raise ::KeyError, <<~MESSAGE + Automatic predicate inferring from class names is deprecated + and will be removed in dry-types 2.0. + Use `Dry::Types::PredicateInferrer::Compiler.infer_predicate_by_class_name true` + to restore the previous behavior + or `Dry::Types::PredicateInferrer::Compiler.infer_predicate_by_class_name false` + to explicitly opt-out (i.e. no exception + no inferring). + Note: for dry-schema and dry-validation use Dry::Schema::PredicateInferrer::Compiler. + MESSAGE + end + else + nil + end + end + end + + if pred.nil? + EMPTY_ARRAY + else + [pred] + end + end + + # @api private + def visit(node) + meth, rest = node + public_send(:"visit_#{meth}", rest) + end + + # @api private + def visit_nominal(node) + type = node[0] + predicate = infer_predicate(type) + + if !predicate.empty? && registry.key?(predicate[0]) + predicate + else + [type?: type] + end + end + + # @api private + def visit_hash(_) + HASH + end + alias_method :visit_schema, :visit_hash + + # @api private + def visit_array(_) + ARRAY + end + + # @api private + def visit_lax(node) + visit(node) + end + + # @api private + def visit_constructor(node) + other, * = node + visit(other) + end + + # @api private + def visit_enum(node) + other, * = node + visit(other) + end + + # @api private + def visit_sum(node) + left_node, right_node, = node + left = visit(left_node) + right = visit(right_node) + + if left.eql?(NIL) # rubocop:disable Lint/DeprecatedConstants + right + else + [[left, right]] + end + end + + # @api private + def visit_constrained(node) + other, rules = node + predicates = visit(rules) + + if predicates.empty? + visit(other) + else + [*visit(other), *merge_predicates(predicates)] + end + end + + # @api private + def visit_any(_) = EMPTY_ARRAY + + # @api private + def visit_and(node) + left, right = node + visit(left) + visit(right) + end + + # @api private + def visit_predicate(node) + pred, args = node + + if pred.equal?(:type?) || !registry.key?(pred) + EMPTY_ARRAY + else + *curried, _ = args + values = curried.map { |_, v| v } + + if values.empty? + [pred] + else + [pred => values[0]] + end + end + end + + # @api private + def visit_map(_node) + raise ::NotImplementedError, "map types are not supported yet" + end + + private + + # @api private + def merge_predicates(nodes) + preds, merged = nodes.each_with_object([[], {}]) do |predicate, (ps, h)| + if predicate.is_a?(::Hash) + h.update(predicate) + else + ps << predicate + end + end + + merged.empty? ? preds : [*preds, merged] + end + end + + # @return [Compiler] + # @api private + attr_reader :compiler + + # @api private + def initialize(registry = PredicateRegistry.new) + @compiler = Compiler.new(registry) + end + + # Infer predicate identifier from the provided type + # + # @param [Type] type + # @return [Symbol] + # + # @api private + def [](type) + self.class.fetch_or_store(type) do + predicates = compiler.visit(type.to_ast) + + if predicates.is_a?(::Hash) + predicates + else + REDUCED_TYPES[predicates] || predicates + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/predicate_registry.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/predicate_registry.rb new file mode 100644 index 00000000..2c1b8fe2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/predicate_registry.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module Dry + module Types + # A registry with predicate objects from `Dry::Logic::Predicates` + # + # @api private + class PredicateRegistry + # @api private + attr_reader :predicates + + # @api private + attr_reader :has_predicate + + KERNEL_RESPOND_TO = ::Kernel.instance_method(:respond_to?) + private_constant(:KERNEL_RESPOND_TO) + + # @api private + def initialize(predicates = Logic::Predicates) + @predicates = predicates + end + + # @api private + def key?(name) + KERNEL_RESPOND_TO.bind_call(@predicates, name) + end + + # @api private + def [](name) = predicates[name] + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/primitive_inferrer.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/primitive_inferrer.rb new file mode 100644 index 00000000..ac3bc17d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/primitive_inferrer.rb @@ -0,0 +1,87 @@ +# frozen_string_literal: true + +module Dry + module Types + # PrimitiveInferrer returns the list of classes matching a type. + # + # @api public + class PrimitiveInferrer + extend Core::Cache + + # Compiler reduces type AST into a list of primitives + # + # @api private + class Compiler + # @api private + def visit(node) + meth, rest = node + public_send(:"visit_#{meth}", rest) + end + + # @api private + def visit_nominal(node) + type, _ = node + type + end + + # @api private + def visit_hash(_) = ::Hash + alias_method :visit_schema, :visit_hash + + # @api private + def visit_array(_) = ::Array + + # @api private + def visit_lax(node) = visit(node) + + # @api private + def visit_constructor(node) + other, * = node + visit(other) + end + + # @api private + def visit_enum(node) + other, * = node + visit(other) + end + + # @api private + def visit_sum(node) + left, right = node + + [visit(left), visit(right)].flatten(1) + end + + # @api private + def visit_constrained(node) + other, * = node + visit(other) + end + + # @api private + def visit_any(_) = ::Object + end + + # @return [Compiler] + # @api private + attr_reader :compiler + + # @api private + def initialize + @compiler = Compiler.new + end + + # Infer primitives from the provided type + # + # @return [Array[Class]] + # + # @api private + def [](type) + self.class.fetch_or_store(type) do + Array(compiler.visit(type.to_ast)).freeze + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/printable.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/printable.rb new file mode 100644 index 00000000..36ab089d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/printable.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Dry + module Types + # @api private + module Printable + # @return [String] + # + # @api private + def to_s = PRINTER.(self) + alias_method :inspect, :to_s + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/printer.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/printer.rb new file mode 100644 index 00000000..a0f293de --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/printer.rb @@ -0,0 +1,297 @@ +# frozen_string_literal: true + +require "dry/types/printer/composition" + +module Dry + # rubocop:disable Metrics/AbcSize + # rubocop:disable Metrics/PerceivedComplexity + module Types + # @api private + class Printer + MAPPING = { + Nominal => :visit_nominal, + Constructor => :visit_constructor, + [ + Constrained, + Constrained::Coercible + ] => :visit_constrained, + Types::Hash => :visit_hash, + Schema => :visit_schema, + Schema::Key => :visit_key, + Map => :visit_map, + Array => :visit_array, + Array::Member => :visit_array_member, + Lax => :visit_lax, + Enum => :visit_enum, + [Default, Default::Callable] => :visit_default, + [ + Sum, + Sum::Constrained, + Intersection, + Intersection::Constrained, + Implication, + Implication::Constrained + ] => :visit_composition, + Any.class => :visit_any + }.flat_map { |k, v| Array(k).map { |kk| [kk, v] } }.to_h + + def initialize + @composition_printers = {} + freeze + end + + def call(type) + output = "".dup + visit(type) { |str| output << str } + "#" + end + + def visit(type, &) + print_with = MAPPING.fetch(type.class) do + if type.class < Constructor + :visit_constructor + elsif type.is_a?(Type) + return yield type.inspect + else + raise ArgumentError, "Do not know how to print #{type.class}" + end + end + send(print_with, type, &) + end + + def visit_any(_) = yield "Any" + + def visit_array(type) + visit_options(EMPTY_HASH, type.meta) do |opts| + yield "Array#{opts}" + end + end + + def visit_array_member(array) + visit(array.member) do |type| + visit_options(EMPTY_HASH, array.meta) do |opts| + yield "Array<#{type}#{opts}>" + end + end + end + + def visit_constructor(constructor) + visit(constructor.type) do |type| + visit_callable(constructor.fn.fn) do |fn| + options = constructor.options.dup + options.delete(:fn) + + visit_options(options) do |opts| + yield "Constructor<#{type} fn=#{fn}#{opts}>" + end + end + end + end + + def visit_constrained(constrained) + visit(constrained.type) do |type| + options = constrained.options.dup + rule = options.delete(:rule) + + visit_options(options) do |_opts| + yield "Constrained<#{type} rule=[#{rule}]>" + end + end + end + + def visit_composition(composition, &) + klass = composition.class + @composition_printers[klass] = Composition.new(self, klass) + @composition_printers[klass].visit(composition, &) + end + + def visit_enum(enum) + visit(enum.type) do |type| + options = enum.options.dup + mapping = options.delete(:mapping) + + visit_options(options) do |opts| + if mapping == enum.inverted_mapping + yield "Enum(#{enum.joined_values})<#{type}#{opts}>" + else + mapping_str = mapping.map { |key, value| + "#{key.inspect}=>#{value.inspect}" + }.join(", ") + yield "Enum<#{type} mapping={#{mapping_str}}#{opts}>" + end + end + end + end + + def visit_default(default) + visit(default.type) do |type| + visit_options(default.options) do |opts| + if default.is_a?(Default::Callable) + visit_callable(default.value) do |fn| + yield "Default<#{type} value_fn=#{fn}#{opts}>" + end + else + yield "Default<#{type} value=#{default.value.inspect}#{opts}>" + end + end + end + end + + def visit_nominal(type) + visit_options(type.options, type.meta) do |opts| + yield "Nominal<#{type.primitive}#{opts}>" + end + end + + def visit_lax(lax) + visit(lax.type) do |type| + yield "Lax<#{type}>" + end + end + + def visit_callable(callable) + fn = callable.is_a?(String) ? FnContainer[callable] : callable + + case fn + when ::Method + yield "#{fn.receiver}.#{fn.name}" + when ::Proc + path, line = fn.source_location + + if line&.zero? + yield ".#{path}" + elsif path + yield "#{path.sub("#{Dir.pwd}/", EMPTY_STRING)}:#{line}" + else + match = fn.to_s.match(/\A#\w+)\)(:? \(lambda\))?>\z/) # rubocop:disable Lint/MixedRegexpCaptureTypes + + if match + yield ".#{match[:name]}" + elsif fn.lambda? + yield "(lambda)" + else + yield "(proc)" + end + end + else + call = fn.method(:call) + + if call.owner == fn.class + yield "#{fn.class}#call" + else + yield "#{fn}.call" + end + end + end + + def visit_schema(schema) + options = schema.options.dup + size = schema.count + key_fn_str = "" + type_fn_str = "" + strict_str = "" + + strict_str = "strict " if options.delete(:strict) + + if (key_fn = options.delete(:key_transform_fn)) + visit_callable(key_fn) do |fn| + key_fn_str = "key_fn=#{fn} " + end + end + + if (type_fn = options.delete(:type_transform_fn)) + visit_callable(type_fn) do |fn| + type_fn_str = "type_fn=#{fn} " + end + end + + keys = options.delete(:keys) + + visit_options(options, schema.meta) do |opts| + opts = "#{opts[1..]} " unless opts.empty? + schema_parameters = "#{key_fn_str}#{type_fn_str}#{strict_str}#{opts}" + + header = "Schema<#{schema_parameters}keys={" + + if size.zero? + yield "#{header}}>" + else + yield header.dup << keys.map { |key| + visit(key) { |type| type } + }.join(" ") << "}>" + end + end + end + + def visit_map(map) + visit(map.key_type) do |key| + visit(map.value_type) do |value| + options = map.options.dup + options.delete(:key_type) + options.delete(:value_type) + + visit_options(options) do |_opts| + yield "Map<#{key} => #{value}>" + end + end + end + end + + def visit_key(key) + visit(key.type) do |type| + if key.required? + yield "#{key.name}: #{type}" + else + yield "#{key.name}?: #{type}" + end + end + end + + def visit_hash(hash) + options = hash.options.dup + type_fn_str = "" + + if (type_fn = options.delete(:type_transform_fn)) + visit_callable(type_fn) do |fn| + type_fn_str = "type_fn=#{fn}" + end + end + + visit_options(options, hash.meta) do |opts| + if opts.empty? && type_fn_str.empty? + yield "Hash" + else + yield "Hash<#{type_fn_str}#{opts}>" + end + end + end + + def visit_options(options, meta = EMPTY_HASH) # rubocop:disable Metrics/PerceivedComplexity + if options.empty? && meta.empty? + yield "" + else + opts = options.empty? ? "" : " options=#{options.inspect}" + + if meta.empty? + yield opts + else + values = meta.map do |key, value| + case key + when Symbol + "#{key}: #{value.inspect}" + else + "#{key.inspect}=>#{value.inspect}" + end + end + + yield "#{opts} meta={#{values.join(", ")}}" + end + end + end + end + + PRINTER = Printer.new + end + # rubocop:enable Metrics/AbcSize + # rubocop:enable Metrics/PerceivedComplexity +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/printer/composition.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/printer/composition.rb new file mode 100644 index 00000000..2d89adeb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/printer/composition.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +module Dry + module Types + # @api private + class Printer + # @api private + class Composition + def initialize(printer, composition_class) + @printer = printer + @composition_class = composition_class + freeze + end + + def visit(composition) + visit_constructors(composition) do |constructors| + @printer.visit_options(composition.options, composition.meta) do |opts| + yield "#{@composition_class.composition_name}<#{constructors}#{opts}>" + end + end + end + + private + + def visit_constructors(composition) + visit_constructor(composition.left) do |left| + visit_constructor(composition.right) do |right| + yield "#{left} #{@composition_class.operator} #{right}" + end + end + end + + def visit_constructor(type, &) + case type + when @composition_class + visit_constructors(type, &) + else + @printer.visit(type, &) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/result.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/result.rb new file mode 100644 index 00000000..fc9aa721 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/result.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +module Dry + module Types + # Result class used by {Type#try} + # + # @api public + class Result + include ::Dry::Equalizer(:input, immutable: true) + + # @return [Object] + attr_reader :input + + # @param [Object] input + # + # @api private + def initialize(input) + @input = input + end + + # Success result + # + # @api public + class Success < Result + # @return [true] + # + # @api public + def success? = true + + # @return [false] + # + # @api public + def failure? = false + end + + # Failure result + # + # @api public + class Failure < Result + include ::Dry::Equalizer(:input, :error, immutable: true) + + # @return [#to_s] + attr_reader :error + + # @param [Object] input + # + # @param [#to_s] error + # + # @api private + def initialize(input, error) + super(input) + @error = error + end + + # @return [String] + # + # @api private + def to_s = error.to_s + + # @return [false] + # + # @api public + def success? = false + + # @return [true] + # + # @api public + def failure? = true + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/schema.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/schema.rb new file mode 100644 index 00000000..ad1ecc8e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/schema.rb @@ -0,0 +1,408 @@ +# frozen_string_literal: true + +module Dry + module Types + # The built-in Hash type can be defined in terms of keys and associated types + # its values can contain. Such definitions are named {Schema}s and defined + # as lists of {Key} types. + # + # @see Dry::Types::Schema::Key + # + # {Schema} evaluates default values for keys missing in input hash + # + # @see Dry::Types::Default#evaluate + # @see Dry::Types::Default::Callable#evaluate + # + # {Schema} implements Enumerable using its keys as collection. + # + # @api public + class Schema < Hash + NO_TRANSFORM = ::Dry::Types::FnContainer.register { |x| x } + SYMBOLIZE_KEY = ::Dry::Types::FnContainer.register(:to_sym.to_proc) + + include ::Enumerable + + # @return [Array[Dry::Types::Schema::Key]] + attr_reader :keys + + # @return [Hash[Symbol, Dry::Types::Schema::Key]] + attr_reader :name_key_map + + # @return [#call] + attr_reader :transform_key + + # @param [Class] _primitive + # @param [Hash] options + # + # @option options [Array[Dry::Types::Schema::Key]] :keys + # @option options [String] :key_transform_fn + # + # @api private + def initialize(_primitive, **options) + @keys = options.fetch(:keys) + @name_key_map = keys.each_with_object({}) do |key, idx| + idx[key.name] = key + end + + key_fn = options.fetch(:key_transform_fn, NO_TRANSFORM) + + @transform_key = ::Dry::Types::FnContainer[key_fn] + + super + end + + # @param [Hash] hash + # + # @return [Hash{Symbol => Object}] + # + # @api private + def call_unsafe(hash, options = EMPTY_HASH) + resolve_unsafe(coerce(hash), options) + end + + # @param [Hash] hash + # + # @return [Hash{Symbol => Object}] + # + # @api private + def call_safe(hash, options = EMPTY_HASH) + resolve_safe(coerce(hash) { return yield }, options) { return yield } + end + + # @param [Hash] hash + # + # @option options [Boolean] :skip_missing If true don't raise error if on missing keys + # @option options [Boolean] :resolve_defaults If false default value + # won't be evaluated for missing key + # @return [Hash{Symbol => Object}] + # + # @api public + def apply(hash, options = EMPTY_HASH) = call_unsafe(hash, options) + + # @param input [Hash] hash + # + # @yieldparam [Failure] failure + # @yieldreturn [Result] + # + # @return [Logic::Result] + # @return [Object] if coercion fails and a block is given + # + # @api public + # rubocop:disable Metrics/AbcSize + # rubocop:disable Metrics/PerceivedComplexity + def try(input) + if primitive?(input) + success = true + output = {} + result = {} + + input.each do |key, value| + k = @transform_key.(key) + type = @name_key_map[k] + + if type + key_result = type.try(value) + result[k] = key_result + output[k] = key_result.input + success &&= key_result.success? + elsif strict? + success = false + end + end + + if output.size < keys.size + resolve_missing_keys(output, options) do + success = false + end + end + + success &&= primitive?(output) + + if success + failure = nil + else + error = CoercionError.new("#{input} doesn't conform schema", meta: result) + failure = failure(output, error) + end + else + failure = failure(input, CoercionError.new("#{input} must be a hash")) + end + + if failure.nil? + success(output) + elsif block_given? + yield(failure) + else + failure + end + end + # rubocop:enable Metrics/AbcSize + # rubocop:enable Metrics/PerceivedComplexity + + # @param meta [Boolean] Whether to dump the meta to the AST + # + # @return [Array] An AST representation + # + # @api public + def to_ast(meta: true) + [ + :schema, + [keys.map { |key| key.to_ast(meta: meta) }, + options.slice(:key_transform_fn, :type_transform_fn, :strict), + meta ? self.meta : EMPTY_HASH] + ] + end + + # Whether the schema rejects unknown keys + # + # @return [Boolean] + # + # @api public + def strict? + options.fetch(:strict, false) + end + + # Make the schema intolerant to unknown keys + # + # @return [Schema] + # + # @api public + def strict(strict = true) # rubocop:disable Style/OptionalBooleanParameter + with(strict: strict) + end + + # Inject a key transformation function + # + # @param [#call,nil] proc + # @param [#call,nil] block + # + # @return [Schema] + # + # @api public + def with_key_transform(proc = nil, &block) + fn = proc || block + + raise ::ArgumentError, "a block or callable argument is required" if fn.nil? + + handle = ::Dry::Types::FnContainer.register(fn) + with(key_transform_fn: handle) + end + + # Whether the schema transforms input keys + # + # @return [Boolean] + # + # @api public + def transform_keys? + !options[:key_transform_fn].nil? + end + + # @overload schema(type_map, meta = EMPTY_HASH) + # @param [{Symbol => Dry::Types::Nominal}] type_map + # @param [Hash] meta + # @return [Dry::Types::Schema] + # + # @overload schema(keys) + # @param [Array] key List of schema keys + # @param [Hash] meta + # @return [Dry::Types::Schema] + # + # @api public + def schema(keys_or_map) + if keys_or_map.is_a?(::Array) + new_keys = keys_or_map + else + new_keys = build_keys(keys_or_map) + end + + keys = merge_keys(self.keys, new_keys) + Schema.new(primitive, **options, keys: keys, meta: meta) + end + + # Iterate over each key type + # + # @return [Array,Enumerator] + # + # @api public + def each(&) + keys.each(&) + end + + # Whether the schema has the given key + # + # @param [Symbol] name Key name + # + # @return [Boolean] + # + # @api public + def key?(name) + name_key_map.key?(name) + end + + # Fetch key type by a key name + # + # Behaves as ::Hash#fetch + # + # @overload key(name, fallback = Undefined) + # @param [Symbol] name Key name + # @param [Object] fallback Optional fallback, returned if key is missing + # @return [Dry::Types::Schema::Key,Object] key type or fallback if key is not in schema + # + # @overload key(name, &block) + # @param [Symbol] name Key name + # @param [Proc] block Fallback block, runs if key is missing + # @return [Dry::Types::Schema::Key,Object] key type or block value if key is not in schema + # + # @api public + def key(name, fallback = Undefined, &) + if Undefined.equal?(fallback) + name_key_map.fetch(name, &) + else + name_key_map.fetch(name, fallback) + end + end + + # @return [Boolean] + # + # @api public + def constrained? + true + end + + # @return [Lax] + # + # @api public + def lax + Lax.new(schema(keys.map(&:lax))) + end + + # Merge given schema keys into current schema + # + # A new instance is returned. + # + # @param other [Schema] schema + # @return [Schema] + # + # @api public + def merge(other) + schema(other.keys) + end + + # Empty schema with the same options + # + # @return [Schema] + # + # @api public + def clear + with(keys: EMPTY_ARRAY) + end + + private + + # @param [Array] keys + # + # @return [Dry::Types::Schema] + # + # @api private + def merge_keys(*keys) + keys + .flatten(1) + .each_with_object({}) { |key, merged| merged[key.name] = key } + .values + end + + # Validate and coerce a hash. Raise an exception on any error + # + # @api private + # + # @return [Hash] + def resolve_unsafe(hash, options = EMPTY_HASH) + result = {} + + hash.each do |key, value| + k = @transform_key.(key) + type = @name_key_map[k] + + if type + begin + result[k] = type.call_unsafe(value) + rescue ConstraintError => e + raise SchemaError.new(type.name, value, e.result) + rescue CoercionError => e + raise SchemaError.new(type.name, value, e.message) + end + elsif strict? + raise unexpected_keys(hash.keys) + end + end + + resolve_missing_keys(result, options) if result.size < keys.size + + result + end + + # Validate and coerce a hash. Call a block and halt on any error + # + # @api private + # + # @return [Hash] + def resolve_safe(hash, options = EMPTY_HASH, &block) + result = {} + + hash.each do |key, value| + k = @transform_key.(key) + type = @name_key_map[k] + + if type + result[k] = type.call_safe(value, &block) + elsif strict? + yield + end + end + + resolve_missing_keys(result, options, &block) if result.size < keys.size + + result + end + + # Try to add missing keys to the hash + # + # @api private + def resolve_missing_keys(hash, options) # rubocop:disable Metrics/PerceivedComplexity + skip_missing = options.fetch(:skip_missing, false) + resolve_defaults = options.fetch(:resolve_defaults, true) + + keys.each do |key| + next if hash.key?(key.name) + + if key.default? && resolve_defaults + hash[key.name] = key.call_unsafe(Undefined) + elsif key.required? && !skip_missing + if block_given? + return yield + else + raise missing_key(key.name) + end + end + end + end + + # @param hash_keys [Array] + # + # @return [UnknownKeysError] + # + # @api private + def unexpected_keys(hash_keys) + extra_keys = hash_keys.map(&transform_key) - name_key_map.keys + UnknownKeysError.new(extra_keys) + end + + # @return [MissingKeyError] + # + # @api private + def missing_key(key) + MissingKeyError.new(key) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/schema/key.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/schema/key.rb new file mode 100644 index 00000000..084c0815 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/schema/key.rb @@ -0,0 +1,138 @@ +# frozen_string_literal: true + +module Dry + module Types + # Schema is a hash with explicit member types defined + # + # @api public + class Schema < Hash + # Proxy type for schema keys. Contains only key name and + # whether it's required or not. All other calls deletaged + # to the wrapped type. + # + # @see Dry::Types::Schema + class Key + extend ::Dry::Core::Deprecations[:"dry-types"] + include Type + include Dry::Equalizer(:name, :type, :options, inspect: false, immutable: true) + include Decorator + include Builder + include Printable + + # @return [Symbol] + attr_reader :name + + # @api private + def initialize(type, name, required: Undefined, **options) + required = Undefined.default(required) do + type.meta.fetch(:required) { !type.meta.fetch(:omittable, false) } + end + + unless name.is_a?(::Symbol) + raise ::ArgumentError, + "Schemas can only contain symbol keys, #{name.inspect} given" + end + + super + @name = name + end + + # @api private + def call_safe(input, &) = type.call_safe(input, &) + + # @api private + def call_unsafe(input) = type.call_unsafe(input) + + # @see Dry::Types::Nominal#try + # + # @api public + def try(input, &) = type.try(input, &) + + # Whether the key is required in schema input + # + # @return [Boolean] + # + # @api public + def required? = options.fetch(:required) + + # Control whether the key is required + # + # @overload required + # @return [Boolean] + # + # @overload required(required) + # Change key's "requireness" + # + # @param [Boolean] required New value + # @return [Dry::Types::Schema::Key] + # + # @api public + def required(required = Undefined) + if Undefined.equal?(required) + options.fetch(:required) + else + with(required: required) + end + end + + # Make key not required + # + # @return [Dry::Types::Schema::Key] + # + # @api public + def omittable = required(false) + + # Turn key into a lax type. Lax types are not strict hence such keys are not required + # + # @return [Lax] + # + # @api public + def lax = __new__(type.lax).required(false) + + # Make wrapped type optional + # + # @return [Key] + # + # @api public + def optional = __new__(type.optional) + + # Dump to internal AST representation + # + # @return [Array] + # + # @api public + def to_ast(meta: true) + [ + :key, + [ + name, + required, + type.to_ast(meta: meta) + ] + ] + end + + # @see Dry::Types::Meta#meta + # + # @api public + def meta(data = Undefined) + if Undefined.equal?(data) || !data.key?(:omittable) + super + else + self.class.warn( + "Using meta for making schema keys is deprecated, " \ + "please use .omittable or .required(false) instead" \ + "\n" + Core::Deprecations::STACK.() + ) + super.required(!data[:omittable]) + end + end + + private + + # @api private + def decorate?(response) = response.is_a?(Type) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/spec/types.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/spec/types.rb new file mode 100644 index 00000000..1a34eaac --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/spec/types.rb @@ -0,0 +1,164 @@ +# frozen_string_literal: true + +RSpec.shared_examples_for "Dry::Types::Nominal without primitive" do + def be_boolean + satisfy { |x| x == true || x == false } + end + + describe "#constrained?" do + it "returns a boolean value" do + expect(type.constrained?).to be_boolean + end + end + + describe "#default?" do + it "returns a boolean value" do + expect(type.default?).to be_boolean + end + end + + describe "#valid?" do + it "returns a boolean value" do + expect(type.valid?(1)).to be_boolean + end + end + + describe "#eql?" do + it "has #eql? defined" do + expect(type).to eql(type) + end + end + + describe "#==" do + it "has #== defined" do + expect(type).to eql(type) + end + end + + describe "#optional?" do + it "returns a boolean value" do + expect(type.optional?).to be_boolean + end + end + + describe "#to_s" do + it "returns a custom string representation" do + expect(type.to_s).to start_with("#>)).to eql(type.method(:constructor)) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/sum.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/sum.rb new file mode 100644 index 00000000..7b612ca9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/sum.rb @@ -0,0 +1,92 @@ +# frozen_string_literal: true + +module Dry + module Types + # Sum type + # + # @api public + class Sum + include Composition + + def self.operator = :| + + # @return [Boolean] + # + # @api public + def optional? = primitive?(nil) + + # @param [Object] input + # + # @return [Object] + # + # @api private + def call_unsafe(input) + left.call_safe(input) { right.call_unsafe(input) } + end + + # @param [Object] input + # + # @return [Object] + # + # @api private + def call_safe(input, &block) + left.call_safe(input) { right.call_safe(input, &block) } + end + + # @param [Object] input + # + # @api public + def try(input) + left.try(input) do + right.try(input) do |failure| + if block_given? + yield(failure) + else + failure + end + end + end + end + + # @param [Object] value + # + # @return [Boolean] + # + # @api private + def primitive?(value) + left.primitive?(value) || right.primitive?(value) + end + + # Manage metadata to the type. If the type is an optional, #meta delegates + # to the right branch + # + # @see [Meta#meta] + # + # @api public + def meta(data = Undefined) + if Undefined.equal?(data) + optional? ? right.meta : super + elsif optional? + self.class.new(left, right.meta(data), **options) + else + super + end + end + + # @param [Hash] options + # + # @return [Constrained,Sum] + # + # @see Builder#constrained + # + # @api public + def constrained(...) + if optional? + right.constrained(...).optional + else + super + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/type.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/type.rb new file mode 100644 index 00000000..7fc005c6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/type.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +module Dry + module Types + # Common Type module denoting an object is a Type + # + # @api public + module Type + extend ::Dry::Core::Deprecations[:"dry-types"] + + deprecate(:safe, :lax) + + # Whether a value is a valid member of the type + # + # @return [Boolean] + # + # @api private + def valid?(input = Undefined) + call_safe(input) { return false } + true + end + # Anything can be coerced matches + alias_method :===, :valid? + + # Apply type to a value + # + # @overload call(input = Undefined) + # Possibly unsafe coercion attempt. If a value doesn't + # match the type, an exception will be raised. + # + # @param [Object] input + # @return [Object] + # + # @overload call(input = Undefined) + # When a block is passed, {#call} will never throw an exception on + # failed coercion, instead it will call the block. + # + # @param [Object] input + # @yieldparam [Object] output Partially coerced value + # @return [Object] + # + # @api public + def call(input = Undefined, &) + if block_given? + call_safe(input, &) + else + call_unsafe(input) + end + end + alias_method :[], :call + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/version.rb b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/version.rb new file mode 100644 index 00000000..dfbc2a52 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/dry-types-1.8.3/lib/dry/types/version.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module Dry + module Types + VERSION = "1.8.3" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/.document b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/.document new file mode 100644 index 00000000..70bb6266 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/.document @@ -0,0 +1,6 @@ +LICENSE.txt +NEWS.md +README.md +ext/ +lib/ +_doc/ diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/.github/dependabot.yml b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/.github/dependabot.yml new file mode 100644 index 00000000..b18fd293 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: 'github-actions' + directory: '/' + schedule: + interval: 'weekly' diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/.github/workflows/test.yml b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/.github/workflows/test.yml new file mode 100644 index 00000000..02e96716 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/.github/workflows/test.yml @@ -0,0 +1,33 @@ +name: test + +on: + push: + branches: [master] + pull_request: + workflow_dispatch: + +jobs: + ruby-versions: + uses: ruby/actions/.github/workflows/ruby_versions.yml@master + with: + engine: cruby + versions: '["jruby", "truffleruby-head"]' + + test: + needs: ruby-versions + name: build (${{ matrix.ruby }} / ${{ matrix.os }}) + strategy: + matrix: + ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }} + os: [ubuntu-latest] + fail-fast: false + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true + - name: Run test + run: bundle exec rake test diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/.gitignore b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/.gitignore new file mode 100644 index 00000000..f53c35c0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/.gitignore @@ -0,0 +1,12 @@ +/.bundle/ +/.yardoc +/_yardoc/ +/coverage/ +/doc/ +/pkg/ +/spec/reports/ +/tmp/ +Gemfile.lock +*.so +*.bundle +*.gem diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/.rdoc_options b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/.rdoc_options new file mode 100644 index 00000000..62d6c583 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/.rdoc_options @@ -0,0 +1 @@ +main_page: README.md diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/BDSL b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/BDSL new file mode 100644 index 00000000..66d93598 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/BDSL @@ -0,0 +1,22 @@ +Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/COPYING b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/COPYING new file mode 100644 index 00000000..48e5a96d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/COPYING @@ -0,0 +1,56 @@ +Ruby is copyrighted free software by Yukihiro Matsumoto . +You can redistribute it and/or modify it under either the terms of the +2-clause BSDL (see the file BSDL), or the conditions below: + +1. You may make and give away verbatim copies of the source form of the + software without restriction, provided that you duplicate all of the + original copyright notices and associated disclaimers. + +2. You may modify your copy of the software in any way, provided that + you do at least ONE of the following: + + a. place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said + modifications to Usenet or an equivalent medium, or by allowing + the author to include your modifications in the software. + + b. use the modified software only within your corporation or + organization. + + c. give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d. make other distribution arrangements with the author. + +3. You may distribute the software in object code or binary form, + provided that you do at least ONE of the following: + + a. distribute the binaries and library files of the software, + together with instructions (in the manual page or equivalent) + on where to get the original distribution. + + b. accompany the distribution with the machine-readable source of + the software. + + c. give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d. make other distribution arrangements with the author. + +4. You may modify and include the part of the software into any other + software (possibly commercial). But some files in the distribution + are not written by the author, so that they are not under these terms. + + For the list of those files and their copying conditions, see the + file LEGAL. + +5. The scripts and library files supplied as input to or produced as + output from the software do not automatically fall under the + copyright of the software, but belong to whomever generated them, + and may be sold commercially, and may be aggregated with this + software. + +6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/Gemfile b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/Gemfile new file mode 100644 index 00000000..eded3b08 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/Gemfile @@ -0,0 +1,10 @@ +source 'https://rubygems.org' + +gemspec + +group :development do + gem 'rake' + gem 'rake-compiler' + gem 'test-unit' + gem "test-unit-ruby-core" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/LICENSE.txt b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/LICENSE.txt new file mode 100644 index 00000000..ca9fe595 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/LICENSE.txt @@ -0,0 +1,2 @@ +All the files in this distribution are covered under either the Ruby's +license (see the file COPYING) or BSD-2-Clause license (see the file BSDL). diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/NEWS.md b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/NEWS.md new file mode 100644 index 00000000..ff5ffa99 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/NEWS.md @@ -0,0 +1,61 @@ +# Change Log + +## 5.0.1 + +* Rescue `LoadError` when failing to load `erb/escape` + +## 5.0.0 + +* Bump `required_ruby_version` to Ruby 3.2+ [#60](https://github.com/ruby/erb/pull/60) +* Drop `cgi` from runtime dependencies [#59](https://github.com/ruby/erb/pull/59) +* Make `ERB::VERSION` public + +## 4.0.4 + +* Skip building the C extension for JRuby [#52](https://github.com/ruby/erb/pull/52) + +## 4.0.3 + +* Enable `frozen_string_literal` in all files [#49](https://github.com/ruby/erb/pull/49) + +## 4.0.2 + +* Fix line numbers after multi-line `<%#` [#42](https://github.com/ruby/erb/pull/42) + +## 4.0.1 + +* Stop building the C extension for TruffleRuby [#39](https://github.com/ruby/erb/pull/39) + +## 4.0.0 + +* Optimize `ERB::Util.html_escape` [#27](https://github.com/ruby/erb/pull/27) + * No longer duplicate an argument string when nothing is escaped. + * This makes `ERB::Util.html_escape` faster than `CGI.escapeHTML` in no-escape cases. + * It skips calling `#to_s` when an argument is already a String. +* Define `ERB::Escape.html_escape` as an alias to `ERB::Util.html_escape` [#38](https://github.com/ruby/erb/pull/38) + * `ERB::Util.html_escape` is known to be monkey-patched by Rails. + `ERB::Escape.html_escape` is useful when you want a non-monkey-patched version. +* Drop deprecated `-S` option from `erb` command + +## 3.0.0 + +* Bump `required_ruby_version` to Ruby 2.7+ [#23](https://github.com/ruby/erb/pull/23) +* `ERB::Util.url_encode` uses a native implementation [#23](https://github.com/ruby/erb/pull/23) +* Fix a bug that a magic comment with a wrong format could be detected [#6](https://github.com/ruby/erb/pull/6) + +## 2.2.3 + +* Bump `required_ruby_version` from 2.3 to 2.5 as it has never been supported [#3](https://github.com/ruby/erb/pull/3) + +## 2.2.2 + +* `ERB.version` returns just a version number +* `ERB::Revision` is deprecated + +## 2.2.1 + +* `ERB#initialize` warns `safe_level` and later arguments even without -w + +## 2.2.0 + +* Ruby 3.0 promoted ERB to a default gem diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/README.md b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/README.md new file mode 100644 index 00000000..908fdb7e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/README.md @@ -0,0 +1,255 @@ +# ERB + +An easy to use but powerful templating system for Ruby. + +## Introduction + +ERB provides an easy to use but powerful templating system for Ruby. Using +ERB, actual Ruby code can be added to any plain text document for the +purposes of generating document information details and/or flow control. + +A very simple example is this: + +```rb +require 'erb' + +x = 42 +template = ERB.new <<-EOF + The value of x is: <%= x %> +EOF +puts template.result(binding) +``` + +Prints: `The value of x is: 42` + +More complex examples are given below. + +## Recognized Tags + +ERB recognizes certain tags in the provided template and converts them based +on the rules below: + +```erb +<% Ruby code -- inline with output %> +<%= Ruby expression -- replace with result %> +<%# comment -- ignored -- useful in testing %> (`<% #` doesn't work. Don't use Ruby comments.) +% a line of Ruby code -- treated as <% line %> (optional -- see ERB.new) +%% replaced with % if first thing on a line and % processing is used +<%% or %%> -- replace with <% or %> respectively +``` + +All other text is passed through ERB filtering unchanged. + +## Options + +There are several settings you can change when you use ERB: +* the nature of the tags that are recognized; +* the binding used to resolve local variables in the template. + +See the ERB.new and ERB#result methods for more detail. + +## Character encodings + +ERB (or Ruby code generated by ERB) returns a string in the same +character encoding as the input string. When the input string has +a magic comment, however, it returns a string in the encoding specified +by the magic comment. + +```rb +# -*- coding: utf-8 -*- +require 'erb' + +template = ERB.new < + __ENCODING__ is <%= __ENCODING__ %>. +EOF +puts template.result +``` + +Prints: `__ENCODING__ is Big5.` + +## Examples + +### Plain Text + +ERB is useful for any generic templating situation. Note that in this example, we use the +convenient "% at start of line" tag, and we quote the template literally with +`%q{...}` to avoid trouble with the backslash. + +```rb +require "erb" + +# Create template. +template = %q{ + From: James Edward Gray II + To: <%= to %> + Subject: Addressing Needs + + <%= to[/\w+/] %>: + + Just wanted to send a quick note assuring that your needs are being + addressed. + + I want you to know that my team will keep working on the issues, + especially: + + <%# ignore numerous minor requests -- focus on priorities %> + % priorities.each do |priority| + * <%= priority %> + % end + + Thanks for your patience. + + James Edward Gray II +}.gsub(/^ /, '') + +message = ERB.new(template, trim_mode: "%<>") + +# Set up template data. +to = "Community Spokesman " +priorities = [ "Run Ruby Quiz", + "Document Modules", + "Answer Questions on Ruby Talk" ] + +# Produce result. +email = message.result +puts email +``` + +Generates: + +``` +From: James Edward Gray II +To: Community Spokesman +Subject: Addressing Needs + +Community: + +Just wanted to send a quick note assuring that your needs are being addressed. + +I want you to know that my team will keep working on the issues, especially: + + * Run Ruby Quiz + * Document Modules + * Answer Questions on Ruby Talk + +Thanks for your patience. + +James Edward Gray II +``` + +### Ruby in HTML + +ERB is often used in .rhtml files (HTML with embedded Ruby). Notice the need in +this example to provide a special binding when the template is run, so that the instance +variables in the Product object can be resolved. + +```rb +require "erb" + +# Build template data class. +class Product + def initialize( code, name, desc, cost ) + @code = code + @name = name + @desc = desc + @cost = cost + + @features = [ ] + end + + def add_feature( feature ) + @features << feature + end + + # Support templating of member data. + def get_binding + binding + end + + # ... +end + +# Create template. +template = %{ + + Ruby Toys -- <%= @name %> + + +

<%= @name %> (<%= @code %>)

+

<%= @desc %>

+ +
    + <% @features.each do |f| %> +
  • <%= f %>
  • + <% end %> +
+ +

+ <% if @cost < 10 %> + Only <%= @cost %>!!! + <% else %> + Call for a price, today! + <% end %> +

+ + + +}.gsub(/^ /, '') + +rhtml = ERB.new(template) + +# Set up template data. +toy = Product.new( "TZ-1002", + "Rubysapien", + "Geek's Best Friend! Responds to Ruby commands...", + 999.95 ) +toy.add_feature("Listens for verbal commands in the Ruby language!") +toy.add_feature("Ignores Perl, Java, and all C variants.") +toy.add_feature("Karate-Chop Action!!!") +toy.add_feature("Matz signature on left leg.") +toy.add_feature("Gem studded eyes... Rubies, of course!") + +# Produce result. +rhtml.run(toy.get_binding) +``` + +Generates (some blank lines removed): + +```html + + Ruby Toys -- Rubysapien + + +

Rubysapien (TZ-1002)

+

Geek's Best Friend! Responds to Ruby commands...

+ +
    +
  • Listens for verbal commands in the Ruby language!
  • +
  • Ignores Perl, Java, and all C variants.
  • +
  • Karate-Chop Action!!!
  • +
  • Matz signature on left leg.
  • +
  • Gem studded eyes... Rubies, of course!
  • +
+ +

+ Call for a price, today! +

+ + + +``` + +## Notes + +There are a variety of templating solutions available in various Ruby projects. +For example, RDoc, distributed with Ruby, uses its own template engine, which +can be reused elsewhere. + +Other popular engines could be found in the corresponding +[Category](https://www.ruby-toolbox.com/categories/template_engines) of +The Ruby Toolbox. + +## License + +The gem is available as open source under the terms of the [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause). diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/Rakefile b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/Rakefile new file mode 100644 index 00000000..8e83d7eb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/Rakefile @@ -0,0 +1,19 @@ +require 'bundler/gem_tasks' +require 'rake/testtask' + +Rake::TestTask.new(:test) do |t| + t.libs << 'test/lib' + t.ruby_opts << '-rhelper' + t.test_files = FileList['test/**/test_*.rb'] +end + +case RUBY_ENGINE +when 'jruby', 'truffleruby' + # not using C extension +else + require 'rake/extensiontask' + Rake::ExtensionTask.new('erb/escape') + task test: :compile +end + +task default: :test diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/_doc/cgi.rb b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/_doc/cgi.rb new file mode 100644 index 00000000..0902b73d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/_doc/cgi.rb @@ -0,0 +1,3 @@ +# See {CGI document}[https://docs.ruby-lang.org/en/master/CGI.html] +module CGI +end diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/bin/console b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/bin/console new file mode 100755 index 00000000..6355e0f6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/bin/console @@ -0,0 +1,14 @@ +#!/usr/bin/env ruby + +require "bundler/setup" +require "erb" + +# You can add fixtures and/or initialization code here to make experimenting +# with your gem easier. You can also use a different console, if you like. + +# (If you use this, don't forget to add pry to your Gemfile!) +# require "pry" +# Pry.start + +require "irb" +IRB.start(__FILE__) diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/bin/setup b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/bin/setup new file mode 100755 index 00000000..dce67d86 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/bin/setup @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -euo pipefail +IFS=$'\n\t' +set -vx + +bundle install + +# Do any other automated setup that you need to do here diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/erb.gemspec b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/erb.gemspec new file mode 100644 index 00000000..0a59abad --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/erb.gemspec @@ -0,0 +1,36 @@ +begin + require_relative 'lib/erb/version' +rescue LoadError + # for Ruby core repository + require_relative 'erb/version' +end + +Gem::Specification.new do |spec| + spec.name = 'erb' + spec.version = ERB::VERSION + spec.authors = ['Masatoshi SEKI', 'Takashi Kokubun'] + spec.email = ['seki@ruby-lang.org', 'k0kubun@ruby-lang.org'] + + spec.summary = %q{An easy to use but powerful templating system for Ruby.} + spec.description = %q{An easy to use but powerful templating system for Ruby.} + spec.homepage = 'https://github.com/ruby/erb' + spec.licenses = ['Ruby', 'BSD-2-Clause'] + + spec.metadata['homepage_uri'] = spec.homepage + spec.metadata['source_code_uri'] = spec.homepage + + spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do + `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } + end + spec.bindir = 'libexec' + spec.executables = ['erb'] + spec.require_paths = ['lib'] + + spec.required_ruby_version = '>= 3.2.0' + + if RUBY_ENGINE == 'jruby' + spec.platform = 'java' + else + spec.extensions = ['ext/erb/escape/extconf.rb'] + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/ext/erb/escape/Makefile b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/ext/erb/escape/Makefile new file mode 100644 index 00000000..0e4c9f8c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/ext/erb/escape/Makefile @@ -0,0 +1,273 @@ + +SHELL = /bin/sh + +# V=0 quiet, V=1 verbose. other values don't work. +V = 0 +V0 = $(V:0=) +Q1 = $(V:1=) +Q = $(Q1:0=@) +ECHO1 = $(V:1=@ :) +ECHO = $(ECHO1:0=@ echo) +NULLCMD = : + +#### Start of system configuration section. #### + +srcdir = . +topdir = /opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 +hdrdir = $(topdir) +arch_hdrdir = /opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux +PATH_SEPARATOR = : +VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby +prefix = $(DESTDIR)/opt/hostedtoolcache/Ruby/3.4.4/x64 +rubysitearchprefix = $(rubylibprefix)/$(sitearch) +rubyarchprefix = $(rubylibprefix)/$(arch) +rubylibprefix = $(libdir)/$(RUBY_BASE_NAME) +exec_prefix = $(prefix) +vendorarchhdrdir = $(vendorhdrdir)/$(sitearch) +sitearchhdrdir = $(sitehdrdir)/$(sitearch) +rubyarchhdrdir = $(rubyhdrdir)/$(arch) +vendorhdrdir = $(rubyhdrdir)/vendor_ruby +sitehdrdir = $(rubyhdrdir)/site_ruby +rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME) +vendorarchdir = $(vendorlibdir)/$(sitearch) +vendorlibdir = $(vendordir)/$(ruby_version) +vendordir = $(rubylibprefix)/vendor_ruby +sitearchdir = $(sitelibdir)/$(sitearch) +sitelibdir = $(sitedir)/$(ruby_version) +sitedir = $(rubylibprefix)/site_ruby +rubyarchdir = $(rubylibdir)/$(arch) +rubylibdir = $(rubylibprefix)/$(ruby_version) +sitearchincludedir = $(includedir)/$(sitearch) +archincludedir = $(includedir)/$(arch) +sitearchlibdir = $(libdir)/$(sitearch) +archlibdir = $(libdir)/$(arch) +ridir = $(datarootdir)/$(RI_BASE_NAME) +modular_gc_dir = $(DESTDIR) +mandir = $(datarootdir)/man +localedir = $(datarootdir)/locale +libdir = $(exec_prefix)/lib +psdir = $(docdir) +pdfdir = $(docdir) +dvidir = $(docdir) +htmldir = $(docdir) +infodir = $(datarootdir)/info +docdir = $(datarootdir)/doc/$(PACKAGE) +oldincludedir = $(DESTDIR)/usr/include +includedir = $(prefix)/include +runstatedir = $(localstatedir)/run +localstatedir = $(prefix)/var +sharedstatedir = $(prefix)/com +sysconfdir = $(prefix)/etc +datadir = $(datarootdir) +datarootdir = $(prefix)/share +libexecdir = $(exec_prefix)/libexec +sbindir = $(exec_prefix)/sbin +bindir = $(exec_prefix)/bin +archdir = $(rubyarchdir) + + +CC_WRAPPER = +CC = gcc +CXX = g++ +LIBRUBY = $(LIBRUBY_SO) +LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a +LIBRUBYARG_SHARED = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME) +LIBRUBYARG_STATIC = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)-static $(MAINLIBS) +empty = +OUTFLAG = -o $(empty) +COUTFLAG = -o $(empty) +CSRCFLAG = $(empty) + +RUBY_EXTCONF_H = +cflags = $(hardenflags) $(optflags) $(debugflags) $(warnflags) +cxxflags = +optflags = -O3 -fno-fast-math +debugflags = -ggdb3 +warnflags = -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef +cppflags = +CCDLFLAGS = -fPIC +CFLAGS = $(CCDLFLAGS) $(cflags) -fPIC $(ARCH_FLAG) +INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) +DEFS = +CPPFLAGS = -DENABLE_PATH_CHECK=0 $(DEFS) $(cppflags) +CXXFLAGS = $(CCDLFLAGS) $(ARCH_FLAG) +ldflags = -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed +dldflags = -Wl,--compress-debug-sections=zlib +ARCH_FLAG = +DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG) +LDSHARED = $(CC) -shared +LDSHAREDXX = $(CXX) -shared +POSTLINK = : +AR = gcc-ar +LD = ld +EXEEXT = + +RUBY_INSTALL_NAME = $(RUBY_BASE_NAME) +RUBY_SO_NAME = ruby +RUBYW_INSTALL_NAME = +RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version) +RUBYW_BASE_NAME = rubyw +RUBY_BASE_NAME = ruby + +arch = x86_64-linux +sitearch = $(arch) +ruby_version = 3.4.0 +ruby = $(bindir)/$(RUBY_BASE_NAME) +RUBY = $(ruby) +BUILTRUBY = $(bindir)/$(RUBY_BASE_NAME) +ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/backward.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h + +RM = rm -f +RM_RF = rm -fr +RMDIRS = rmdir --ignore-fail-on-non-empty -p +MAKEDIRS = /usr/bin/mkdir -p +INSTALL = /usr/bin/install -c +INSTALL_PROG = $(INSTALL) -m 0755 +INSTALL_DATA = $(INSTALL) -m 644 +COPY = cp +TOUCH = exit > + +#### End of system configuration section. #### + +preload = +libpath = . $(libdir) +LIBPATH = -L. -L$(libdir) -Wl,-rpath,$(libdir) +DEFFILE = + +CLEANFILES = mkmf.log +DISTCLEANFILES = +DISTCLEANDIRS = + +extout = +extout_prefix = +target_prefix = /erb +LOCAL_LIBS = +LIBS = $(LIBRUBYARG_SHARED) -lm -lpthread -lc +ORIG_SRCS = escape.c +SRCS = $(ORIG_SRCS) +OBJS = escape.o +HDRS = +LOCAL_HDRS = +TARGET = escape +TARGET_NAME = escape +TARGET_ENTRY = Init_$(TARGET_NAME) +DLLIB = $(TARGET).so +EXTSTATIC = +STATIC_LIB = + +TIMESTAMP_DIR = . +BINDIR = $(bindir) +RUBYCOMMONDIR = $(sitedir)$(target_prefix) +RUBYLIBDIR = $(sitelibdir)$(target_prefix) +RUBYARCHDIR = $(sitearchdir)$(target_prefix) +HDRDIR = $(sitehdrdir)$(target_prefix) +ARCHHDRDIR = $(sitearchhdrdir)$(target_prefix) +TARGET_SO_DIR = +TARGET_SO = $(TARGET_SO_DIR)$(DLLIB) +CLEANLIBS = $(TARGET_SO) false +CLEANOBJS = $(OBJS) *.bak +TARGET_SO_DIR_TIMESTAMP = $(TIMESTAMP_DIR)/.sitearchdir.-.erb.time + +all: $(DLLIB) +static: $(STATIC_LIB) +.PHONY: all install static install-so install-rb +.PHONY: clean clean-so clean-static clean-rb + +clean-static:: +clean-rb-default:: +clean-rb:: +clean-so:: +clean: clean-so clean-static clean-rb-default clean-rb + -$(Q)$(RM_RF) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time + +distclean-rb-default:: +distclean-rb:: +distclean-so:: +distclean-static:: +distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb + -$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + -$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + -$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true + +realclean: distclean +install: install-so install-rb + +install-so: $(DLLIB) $(TARGET_SO_DIR_TIMESTAMP) + $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) +clean-static:: + -$(Q)$(RM) $(STATIC_LIB) +install-rb: pre-install-rb do-install-rb install-rb-default +install-rb-default: pre-install-rb-default do-install-rb-default +pre-install-rb: Makefile +pre-install-rb-default: Makefile +do-install-rb: +do-install-rb-default: +pre-install-rb-default: + @$(NULLCMD) +$(TARGET_SO_DIR_TIMESTAMP): + $(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR) + $(Q) $(TOUCH) $@ + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + +.SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S + +.cc.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cc.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.mm.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.mm.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cxx.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cxx.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cpp.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cpp.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.c.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.c.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.m.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.m.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +$(TARGET_SO): $(OBJS) Makefile + $(ECHO) linking shared-object erb/$(DLLIB) + -$(Q)$(RM) $(@) + $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) + $(Q) $(POSTLINK) + + + +$(OBJS): $(HDRS) $(ruby_headers) diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/ext/erb/escape/escape.c b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/ext/erb/escape/escape.c new file mode 100644 index 00000000..db2abd97 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/ext/erb/escape/escape.c @@ -0,0 +1,98 @@ +#include "ruby.h" +#include "ruby/encoding.h" + +static VALUE rb_cERB, rb_mEscape, rb_cCGI; +static ID id_escapeHTML; + +#define HTML_ESCAPE_MAX_LEN 6 + +static const struct { + uint8_t len; + char str[HTML_ESCAPE_MAX_LEN+1]; +} html_escape_table[UCHAR_MAX+1] = { +#define HTML_ESCAPE(c, str) [c] = {rb_strlen_lit(str), str} + HTML_ESCAPE('\'', "'"), + HTML_ESCAPE('&', "&"), + HTML_ESCAPE('"', """), + HTML_ESCAPE('<', "<"), + HTML_ESCAPE('>', ">"), +#undef HTML_ESCAPE +}; + +static inline void +preserve_original_state(VALUE orig, VALUE dest) +{ + rb_enc_associate(dest, rb_enc_get(orig)); +} + +static inline long +escaped_length(VALUE str) +{ + const long len = RSTRING_LEN(str); + if (len >= LONG_MAX / HTML_ESCAPE_MAX_LEN) { + ruby_malloc_size_overflow(len, HTML_ESCAPE_MAX_LEN); + } + return len * HTML_ESCAPE_MAX_LEN; +} + +static VALUE +optimized_escape_html(VALUE str) +{ + VALUE vbuf; + char *buf = ALLOCV_N(char, vbuf, escaped_length(str)); + const char *cstr = RSTRING_PTR(str); + const char *end = cstr + RSTRING_LEN(str); + + char *dest = buf; + while (cstr < end) { + const unsigned char c = *cstr++; + uint8_t len = html_escape_table[c].len; + if (len) { + memcpy(dest, html_escape_table[c].str, len); + dest += len; + } + else { + *dest++ = c; + } + } + + VALUE escaped = str; + if (RSTRING_LEN(str) < (dest - buf)) { + escaped = rb_str_new(buf, dest - buf); + preserve_original_state(str, escaped); + } + ALLOCV_END(vbuf); + return escaped; +} + +/* + * ERB::Util.html_escape is similar to CGI.escapeHTML but different in the following two parts: + * + * * ERB::Util.html_escape converts an argument with #to_s first (only if it's not T_STRING) + * * ERB::Util.html_escape does not allocate a new string when nothing needs to be escaped + */ +static VALUE +erb_escape_html(VALUE self, VALUE str) +{ + if (!RB_TYPE_P(str, T_STRING)) { + str = rb_convert_type(str, T_STRING, "String", "to_s"); + } + + if (rb_enc_str_asciicompat_p(str)) { + return optimized_escape_html(str); + } + else { + return rb_funcall(rb_cCGI, id_escapeHTML, 1, str); + } +} + +void +Init_escape(void) +{ + rb_cERB = rb_define_class("ERB", rb_cObject); + rb_mEscape = rb_define_module_under(rb_cERB, "Escape"); + rb_define_module_function(rb_mEscape, "html_escape", erb_escape_html, 1); + + rb_cCGI = rb_define_class("CGI", rb_cObject); + id_escapeHTML = rb_intern("escapeHTML"); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/ext/erb/escape/extconf.rb b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/ext/erb/escape/extconf.rb new file mode 100644 index 00000000..783e8c1f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/ext/erb/escape/extconf.rb @@ -0,0 +1,8 @@ +require 'mkmf' + +case RUBY_ENGINE +when 'jruby', 'truffleruby' + File.write('Makefile', dummy_makefile($srcdir).join) +else + create_makefile 'erb/escape' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/lib/erb.rb b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/lib/erb.rb new file mode 100644 index 00000000..ebf91e47 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/lib/erb.rb @@ -0,0 +1,504 @@ +# -*- coding: us-ascii -*- +# frozen_string_literal: true +# = ERB -- Ruby Templating +# +# Author:: Masatoshi SEKI +# Documentation:: James Edward Gray II, Gavin Sinclair, and Simon Chiang +# +# See ERB for primary documentation and ERB::Util for a couple of utility +# routines. +# +# Copyright (c) 1999-2000,2002,2003 Masatoshi SEKI +# +# You can redistribute it and/or modify it under the same terms as Ruby. + +require 'erb/version' +require 'erb/compiler' +require 'erb/def_method' +require 'erb/util' + +# +# = ERB -- Ruby Templating +# +# == Introduction +# +# ERB provides an easy to use but powerful templating system for Ruby. Using +# ERB, actual Ruby code can be added to any plain text document for the +# purposes of generating document information details and/or flow control. +# +# A very simple example is this: +# +# require 'erb' +# +# x = 42 +# template = ERB.new <<-EOF +# The value of x is: <%= x %> +# EOF +# puts template.result(binding) +# +# Prints: The value of x is: 42 +# +# More complex examples are given below. +# +# +# == Recognized Tags +# +# ERB recognizes certain tags in the provided template and converts them based +# on the rules below: +# +# <% Ruby code -- inline with output %> +# <%= Ruby expression -- replace with result %> +# <%# comment -- ignored -- useful in testing %> (`<% #` doesn't work. Don't use Ruby comments.) +# % a line of Ruby code -- treated as <% line %> (optional -- see ERB.new) +# %% replaced with % if first thing on a line and % processing is used +# <%% or %%> -- replace with <% or %> respectively +# +# All other text is passed through ERB filtering unchanged. +# +# +# == Options +# +# There are several settings you can change when you use ERB: +# * the nature of the tags that are recognized; +# * the binding used to resolve local variables in the template. +# +# See the ERB.new and ERB#result methods for more detail. +# +# == Character encodings +# +# ERB (or Ruby code generated by ERB) returns a string in the same +# character encoding as the input string. When the input string has +# a magic comment, however, it returns a string in the encoding specified +# by the magic comment. +# +# # -*- coding: utf-8 -*- +# require 'erb' +# +# template = ERB.new < +# \_\_ENCODING\_\_ is <%= \_\_ENCODING\_\_ %>. +# EOF +# puts template.result +# +# Prints: \_\_ENCODING\_\_ is Big5. +# +# +# == Examples +# +# === Plain Text +# +# ERB is useful for any generic templating situation. Note that in this example, we use the +# convenient "% at start of line" tag, and we quote the template literally with +# %q{...} to avoid trouble with the backslash. +# +# require "erb" +# +# # Create template. +# template = %q{ +# From: James Edward Gray II +# To: <%= to %> +# Subject: Addressing Needs +# +# <%= to[/\w+/] %>: +# +# Just wanted to send a quick note assuring that your needs are being +# addressed. +# +# I want you to know that my team will keep working on the issues, +# especially: +# +# <%# ignore numerous minor requests -- focus on priorities %> +# % priorities.each do |priority| +# * <%= priority %> +# % end +# +# Thanks for your patience. +# +# James Edward Gray II +# }.gsub(/^ /, '') +# +# message = ERB.new(template, trim_mode: "%<>") +# +# # Set up template data. +# to = "Community Spokesman " +# priorities = [ "Run Ruby Quiz", +# "Document Modules", +# "Answer Questions on Ruby Talk" ] +# +# # Produce result. +# email = message.result +# puts email +# +# Generates: +# +# From: James Edward Gray II +# To: Community Spokesman +# Subject: Addressing Needs +# +# Community: +# +# Just wanted to send a quick note assuring that your needs are being addressed. +# +# I want you to know that my team will keep working on the issues, especially: +# +# * Run Ruby Quiz +# * Document Modules +# * Answer Questions on Ruby Talk +# +# Thanks for your patience. +# +# James Edward Gray II +# +# === Ruby in HTML +# +# ERB is often used in .rhtml files (HTML with embedded Ruby). Notice the need in +# this example to provide a special binding when the template is run, so that the instance +# variables in the Product object can be resolved. +# +# require "erb" +# +# # Build template data class. +# class Product +# def initialize( code, name, desc, cost ) +# @code = code +# @name = name +# @desc = desc +# @cost = cost +# +# @features = [ ] +# end +# +# def add_feature( feature ) +# @features << feature +# end +# +# # Support templating of member data. +# def get_binding +# binding +# end +# +# # ... +# end +# +# # Create template. +# template = %{ +# +# Ruby Toys -- <%= @name %> +# +# +#

<%= @name %> (<%= @code %>)

+#

<%= @desc %>

+# +#
    +# <% @features.each do |f| %> +#
  • <%= f %>
  • +# <% end %> +#
+# +#

+# <% if @cost < 10 %> +# Only <%= @cost %>!!! +# <% else %> +# Call for a price, today! +# <% end %> +#

+# +# +# +# }.gsub(/^ /, '') +# +# rhtml = ERB.new(template) +# +# # Set up template data. +# toy = Product.new( "TZ-1002", +# "Rubysapien", +# "Geek's Best Friend! Responds to Ruby commands...", +# 999.95 ) +# toy.add_feature("Listens for verbal commands in the Ruby language!") +# toy.add_feature("Ignores Perl, Java, and all C variants.") +# toy.add_feature("Karate-Chop Action!!!") +# toy.add_feature("Matz signature on left leg.") +# toy.add_feature("Gem studded eyes... Rubies, of course!") +# +# # Produce result. +# rhtml.run(toy.get_binding) +# +# Generates (some blank lines removed): +# +# +# Ruby Toys -- Rubysapien +# +# +#

Rubysapien (TZ-1002)

+#

Geek's Best Friend! Responds to Ruby commands...

+# +#
    +#
  • Listens for verbal commands in the Ruby language!
  • +#
  • Ignores Perl, Java, and all C variants.
  • +#
  • Karate-Chop Action!!!
  • +#
  • Matz signature on left leg.
  • +#
  • Gem studded eyes... Rubies, of course!
  • +#
+# +#

+# Call for a price, today! +#

+# +# +# +# +# +# == Notes +# +# There are a variety of templating solutions available in various Ruby projects. +# For example, RDoc, distributed with Ruby, uses its own template engine, which +# can be reused elsewhere. +# +# Other popular engines could be found in the corresponding +# {Category}[https://www.ruby-toolbox.com/categories/template_engines] of +# The Ruby Toolbox. +# +class ERB + Revision = '$Date:: $' # :nodoc: #' + deprecate_constant :Revision + + # Returns revision information for the erb.rb module. + def self.version + VERSION + end + + # + # Constructs a new ERB object with the template specified in _str_. + # + # An ERB object works by building a chunk of Ruby code that will output + # the completed template when run. + # + # If _trim_mode_ is passed a String containing one or more of the following + # modifiers, ERB will adjust its code generation as listed: + # + # % enables Ruby code processing for lines beginning with % + # <> omit newline for lines starting with <% and ending in %> + # > omit newline for lines ending in %> + # - omit blank lines ending in -%> + # + # _eoutvar_ can be used to set the name of the variable ERB will build up + # its output in. This is useful when you need to run multiple ERB + # templates through the same binding and/or when you want to control where + # output ends up. Pass the name of the variable to be used inside a String. + # + # === Example + # + # require "erb" + # + # # build data class + # class Listings + # PRODUCT = { :name => "Chicken Fried Steak", + # :desc => "A well messaged pattie, breaded and fried.", + # :cost => 9.95 } + # + # attr_reader :product, :price + # + # def initialize( product = "", price = "" ) + # @product = product + # @price = price + # end + # + # def build + # b = binding + # # create and run templates, filling member data variables + # ERB.new(<<~'END_PRODUCT', trim_mode: "", eoutvar: "@product").result b + # <%= PRODUCT[:name] %> + # <%= PRODUCT[:desc] %> + # END_PRODUCT + # ERB.new(<<~'END_PRICE', trim_mode: "", eoutvar: "@price").result b + # <%= PRODUCT[:name] %> -- <%= PRODUCT[:cost] %> + # <%= PRODUCT[:desc] %> + # END_PRICE + # end + # end + # + # # setup template data + # listings = Listings.new + # listings.build + # + # puts listings.product + "\n" + listings.price + # + # _Generates_ + # + # Chicken Fried Steak + # A well massaged pattie, breaded and fried. + # + # Chicken Fried Steak -- 9.95 + # A well massaged pattie, breaded and fried. + # + def initialize(str, safe_level=NOT_GIVEN, legacy_trim_mode=NOT_GIVEN, legacy_eoutvar=NOT_GIVEN, trim_mode: nil, eoutvar: '_erbout') + # Complex initializer for $SAFE deprecation at [Feature #14256]. Use keyword arguments to pass trim_mode or eoutvar. + if safe_level != NOT_GIVEN + warn 'Passing safe_level with the 2nd argument of ERB.new is deprecated. Do not use it, and specify other arguments as keyword arguments.', uplevel: 1 + end + if legacy_trim_mode != NOT_GIVEN + warn 'Passing trim_mode with the 3rd argument of ERB.new is deprecated. Use keyword argument like ERB.new(str, trim_mode: ...) instead.', uplevel: 1 + trim_mode = legacy_trim_mode + end + if legacy_eoutvar != NOT_GIVEN + warn 'Passing eoutvar with the 4th argument of ERB.new is deprecated. Use keyword argument like ERB.new(str, eoutvar: ...) instead.', uplevel: 1 + eoutvar = legacy_eoutvar + end + + compiler = make_compiler(trim_mode) + set_eoutvar(compiler, eoutvar) + @src, @encoding, @frozen_string = *compiler.compile(str) + @filename = nil + @lineno = 0 + @_init = self.class.singleton_class + end + NOT_GIVEN = defined?(Ractor) ? Ractor.make_shareable(Object.new) : Object.new + private_constant :NOT_GIVEN + + ## + # Creates a new compiler for ERB. See ERB::Compiler.new for details + + def make_compiler(trim_mode) + ERB::Compiler.new(trim_mode) + end + + # The Ruby code generated by ERB + attr_reader :src + + # The encoding to eval + attr_reader :encoding + + # The optional _filename_ argument passed to Kernel#eval when the ERB code + # is run + attr_accessor :filename + + # The optional _lineno_ argument passed to Kernel#eval when the ERB code + # is run + attr_accessor :lineno + + # + # Sets optional filename and line number that will be used in ERB code + # evaluation and error reporting. See also #filename= and #lineno= + # + # erb = ERB.new('<%= some_x %>') + # erb.render + # # undefined local variable or method `some_x' + # # from (erb):1 + # + # erb.location = ['file.erb', 3] + # # All subsequent error reporting would use new location + # erb.render + # # undefined local variable or method `some_x' + # # from file.erb:4 + # + def location=((filename, lineno)) + @filename = filename + @lineno = lineno if lineno + end + + # + # Can be used to set _eoutvar_ as described in ERB::new. It's probably + # easier to just use the constructor though, since calling this method + # requires the setup of an ERB _compiler_ object. + # + def set_eoutvar(compiler, eoutvar = '_erbout') + compiler.put_cmd = "#{eoutvar}.<<" + compiler.insert_cmd = "#{eoutvar}.<<" + compiler.pre_cmd = ["#{eoutvar} = +''"] + compiler.post_cmd = [eoutvar] + end + + # Generate results and print them. (see ERB#result) + def run(b=new_toplevel) + print self.result(b) + end + + # + # Executes the generated ERB code to produce a completed template, returning + # the results of that code. + # + # _b_ accepts a Binding object which is used to set the context of + # code evaluation. + # + def result(b=new_toplevel) + unless @_init.equal?(self.class.singleton_class) + raise ArgumentError, "not initialized" + end + eval(@src, b, (@filename || '(erb)'), @lineno) + end + + # Render a template on a new toplevel binding with local variables specified + # by a Hash object. + def result_with_hash(hash) + b = new_toplevel(hash.keys) + hash.each_pair do |key, value| + b.local_variable_set(key, value) + end + result(b) + end + + ## + # Returns a new binding each time *near* TOPLEVEL_BINDING for runs that do + # not specify a binding. + + def new_toplevel(vars = nil) + b = TOPLEVEL_BINDING + if vars + vars = vars.select {|v| b.local_variable_defined?(v)} + unless vars.empty? + return b.eval("tap {|;#{vars.join(',')}| break binding}") + end + end + b.dup + end + private :new_toplevel + + # Define _methodname_ as instance method of _mod_ from compiled Ruby source. + # + # example: + # filename = 'example.rhtml' # 'arg1' and 'arg2' are used in example.rhtml + # erb = ERB.new(File.read(filename)) + # erb.def_method(MyClass, 'render(arg1, arg2)', filename) + # print MyClass.new.render('foo', 123) + def def_method(mod, methodname, fname='(ERB)') + src = self.src.sub(/^(?!#|$)/) {"def #{methodname}\n"} << "\nend\n" + mod.module_eval do + eval(src, binding, fname, -1) + end + end + + # Create unnamed module, define _methodname_ as instance method of it, and return it. + # + # example: + # filename = 'example.rhtml' # 'arg1' and 'arg2' are used in example.rhtml + # erb = ERB.new(File.read(filename)) + # erb.filename = filename + # MyModule = erb.def_module('render(arg1, arg2)') + # class MyClass + # include MyModule + # end + def def_module(methodname='erb') + mod = Module.new + def_method(mod, methodname, @filename || '(ERB)') + mod + end + + # Define unnamed class which has _methodname_ as instance method, and return it. + # + # example: + # class MyClass_ + # def initialize(arg1, arg2) + # @arg1 = arg1; @arg2 = arg2 + # end + # end + # filename = 'example.rhtml' # @arg1 and @arg2 are used in example.rhtml + # erb = ERB.new(File.read(filename)) + # erb.filename = filename + # MyClass = erb.def_class(MyClass_, 'render()') + # print MyClass.new('foo', 123).render() + def def_class(superklass=Object, methodname='result') + cls = Class.new(superklass) + def_method(cls, methodname, @filename || '(ERB)') + cls + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/lib/erb/compiler.rb b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/lib/erb/compiler.rb new file mode 100644 index 00000000..08b5eb4e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/lib/erb/compiler.rb @@ -0,0 +1,488 @@ +# frozen_string_literal: true +#-- +# ERB::Compiler +# +# Compiles ERB templates into Ruby code; the compiled code produces the +# template result when evaluated. ERB::Compiler provides hooks to define how +# generated output is handled. +# +# Internally ERB does something like this to generate the code returned by +# ERB#src: +# +# compiler = ERB::Compiler.new('<>') +# compiler.pre_cmd = ["_erbout=+''"] +# compiler.put_cmd = "_erbout.<<" +# compiler.insert_cmd = "_erbout.<<" +# compiler.post_cmd = ["_erbout"] +# +# code, enc = compiler.compile("Got <%= obj %>!\n") +# puts code +# +# Generates: +# +# #coding:UTF-8 +# _erbout=+''; _erbout.<< "Got ".freeze; _erbout.<<(( obj ).to_s); _erbout.<< "!\n".freeze; _erbout +# +# By default the output is sent to the print method. For example: +# +# compiler = ERB::Compiler.new('<>') +# code, enc = compiler.compile("Got <%= obj %>!\n") +# puts code +# +# Generates: +# +# #coding:UTF-8 +# print "Got ".freeze; print(( obj ).to_s); print "!\n".freeze +# +# == Evaluation +# +# The compiled code can be used in any context where the names in the code +# correctly resolve. Using the last example, each of these print 'Got It!' +# +# Evaluate using a variable: +# +# obj = 'It' +# eval code +# +# Evaluate using an input: +# +# mod = Module.new +# mod.module_eval %{ +# def get(obj) +# #{code} +# end +# } +# extend mod +# get('It') +# +# Evaluate using an accessor: +# +# klass = Class.new Object +# klass.class_eval %{ +# attr_accessor :obj +# def initialize(obj) +# @obj = obj +# end +# def get_it +# #{code} +# end +# } +# klass.new('It').get_it +# +# Good! See also ERB#def_method, ERB#def_module, and ERB#def_class. +class ERB::Compiler # :nodoc: + class PercentLine # :nodoc: + def initialize(str) + @value = str + end + attr_reader :value + alias :to_s :value + end + + class Scanner # :nodoc: + @scanner_map = defined?(Ractor) ? Ractor.make_shareable({}) : {} + class << self + if defined?(Ractor) + def register_scanner(klass, trim_mode, percent) + @scanner_map = Ractor.make_shareable({ **@scanner_map, [trim_mode, percent] => klass }) + end + else + def register_scanner(klass, trim_mode, percent) + @scanner_map[[trim_mode, percent]] = klass + end + end + alias :regist_scanner :register_scanner + end + + def self.default_scanner=(klass) + @default_scanner = klass + end + + def self.make_scanner(src, trim_mode, percent) + klass = @scanner_map.fetch([trim_mode, percent], @default_scanner) + klass.new(src, trim_mode, percent) + end + + DEFAULT_STAGS = %w(<%% <%= <%# <%).freeze + DEFAULT_ETAGS = %w(%%> %>).freeze + def initialize(src, trim_mode, percent) + @src = src + @stag = nil + @stags = DEFAULT_STAGS + @etags = DEFAULT_ETAGS + end + attr_accessor :stag + attr_reader :stags, :etags + + def scan; end + end + + class TrimScanner < Scanner # :nodoc: + def initialize(src, trim_mode, percent) + super + @trim_mode = trim_mode + @percent = percent + if @trim_mode == '>' + @scan_reg = /(.*?)(%>\r?\n|#{(stags + etags).join('|')}|\n|\z)/m + @scan_line = self.method(:trim_line1) + elsif @trim_mode == '<>' + @scan_reg = /(.*?)(%>\r?\n|#{(stags + etags).join('|')}|\n|\z)/m + @scan_line = self.method(:trim_line2) + elsif @trim_mode == '-' + @scan_reg = /(.*?)(^[ \t]*<%\-|<%\-|-%>\r?\n|-%>|#{(stags + etags).join('|')}|\z)/m + @scan_line = self.method(:explicit_trim_line) + else + @scan_reg = /(.*?)(#{(stags + etags).join('|')}|\n|\z)/m + @scan_line = self.method(:scan_line) + end + end + + def scan(&block) + @stag = nil + if @percent + @src.each_line do |line| + percent_line(line, &block) + end + else + @scan_line.call(@src, &block) + end + nil + end + + def percent_line(line, &block) + if @stag || line[0] != ?% + return @scan_line.call(line, &block) + end + + line[0] = '' + if line[0] == ?% + @scan_line.call(line, &block) + else + yield(PercentLine.new(line.chomp)) + end + end + + def scan_line(line) + line.scan(@scan_reg) do |tokens| + tokens.each do |token| + next if token.empty? + yield(token) + end + end + end + + def trim_line1(line) + line.scan(@scan_reg) do |tokens| + tokens.each do |token| + next if token.empty? + if token == "%>\n" || token == "%>\r\n" + yield('%>') + yield(:cr) + else + yield(token) + end + end + end + end + + def trim_line2(line) + head = nil + line.scan(@scan_reg) do |tokens| + tokens.each do |token| + next if token.empty? + head = token unless head + if token == "%>\n" || token == "%>\r\n" + yield('%>') + if is_erb_stag?(head) + yield(:cr) + else + yield("\n") + end + head = nil + else + yield(token) + head = nil if token == "\n" + end + end + end + end + + def explicit_trim_line(line) + line.scan(@scan_reg) do |tokens| + tokens.each do |token| + next if token.empty? + if @stag.nil? && /[ \t]*<%-/ =~ token + yield('<%') + elsif @stag && (token == "-%>\n" || token == "-%>\r\n") + yield('%>') + yield(:cr) + elsif @stag && token == '-%>' + yield('%>') + else + yield(token) + end + end + end + end + + ERB_STAG = %w(<%= <%# <%) + def is_erb_stag?(s) + ERB_STAG.member?(s) + end + end + + Scanner.default_scanner = TrimScanner + + begin + require 'strscan' + rescue LoadError + else + class SimpleScanner < Scanner # :nodoc: + def scan + stag_reg = (stags == DEFAULT_STAGS) ? /(.*?)(<%[%=#]?|\z)/m : /(.*?)(#{stags.join('|')}|\z)/m + etag_reg = (etags == DEFAULT_ETAGS) ? /(.*?)(%%?>|\z)/m : /(.*?)(#{etags.join('|')}|\z)/m + scanner = StringScanner.new(@src) + while ! scanner.eos? + scanner.scan(@stag ? etag_reg : stag_reg) + yield(scanner[1]) + yield(scanner[2]) + end + end + end + Scanner.register_scanner(SimpleScanner, nil, false) + + class ExplicitScanner < Scanner # :nodoc: + def scan + stag_reg = /(.*?)(^[ \t]*<%-|<%-|#{stags.join('|')}|\z)/m + etag_reg = /(.*?)(-%>|#{etags.join('|')}|\z)/m + scanner = StringScanner.new(@src) + while ! scanner.eos? + scanner.scan(@stag ? etag_reg : stag_reg) + yield(scanner[1]) + + elem = scanner[2] + if /[ \t]*<%-/ =~ elem + yield('<%') + elsif elem == '-%>' + yield('%>') + yield(:cr) if scanner.scan(/(\r?\n|\z)/) + else + yield(elem) + end + end + end + end + Scanner.register_scanner(ExplicitScanner, '-', false) + end + + class Buffer # :nodoc: + def initialize(compiler, enc=nil, frozen=nil) + @compiler = compiler + @line = [] + @script = +'' + @script << "#coding:#{enc}\n" if enc + @script << "#frozen-string-literal:#{frozen}\n" unless frozen.nil? + @compiler.pre_cmd.each do |x| + push(x) + end + end + attr_reader :script + + def push(cmd) + @line << cmd + end + + def cr + @script << (@line.join('; ')) + @line = [] + @script << "\n" + end + + def close + return unless @line + @compiler.post_cmd.each do |x| + push(x) + end + @script << (@line.join('; ')) + @line = nil + end + end + + def add_put_cmd(out, content) + out.push("#{@put_cmd} #{content.dump}.freeze#{"\n" * content.count("\n")}") + end + + def add_insert_cmd(out, content) + out.push("#{@insert_cmd}((#{content}).to_s)") + end + + # Compiles an ERB template into Ruby code. Returns an array of the code + # and encoding like ["code", Encoding]. + def compile(s) + enc = s.encoding + raise ArgumentError, "#{enc} is not ASCII compatible" if enc.dummy? + s = s.b # see String#b + magic_comment = detect_magic_comment(s, enc) + out = Buffer.new(self, *magic_comment) + + self.content = +'' + scanner = make_scanner(s) + scanner.scan do |token| + next if token.nil? + next if token == '' + if scanner.stag.nil? + compile_stag(token, out, scanner) + else + compile_etag(token, out, scanner) + end + end + add_put_cmd(out, content) if content.size > 0 + out.close + return out.script, *magic_comment + end + + def compile_stag(stag, out, scanner) + case stag + when PercentLine + add_put_cmd(out, content) if content.size > 0 + self.content = +'' + out.push(stag.to_s) + out.cr + when :cr + out.cr + when '<%', '<%=', '<%#' + scanner.stag = stag + add_put_cmd(out, content) if content.size > 0 + self.content = +'' + when "\n" + content << "\n" + add_put_cmd(out, content) + self.content = +'' + when '<%%' + content << '<%' + else + content << stag + end + end + + def compile_etag(etag, out, scanner) + case etag + when '%>' + compile_content(scanner.stag, out) + scanner.stag = nil + self.content = +'' + when '%%>' + content << '%>' + else + content << etag + end + end + + def compile_content(stag, out) + case stag + when '<%' + if content[-1] == ?\n + content.chop! + out.push(content) + out.cr + else + out.push(content) + end + when '<%=' + add_insert_cmd(out, content) + when '<%#' + out.push("\n" * content.count("\n")) # only adjust lineno + end + end + + def prepare_trim_mode(mode) # :nodoc: + case mode + when 1 + return [false, '>'] + when 2 + return [false, '<>'] + when 0, nil + return [false, nil] + when String + unless mode.match?(/\A(%|-|>|<>){1,2}\z/) + warn_invalid_trim_mode(mode, uplevel: 5) + end + + perc = mode.include?('%') + if mode.include?('-') + return [perc, '-'] + elsif mode.include?('<>') + return [perc, '<>'] + elsif mode.include?('>') + return [perc, '>'] + else + [perc, nil] + end + else + warn_invalid_trim_mode(mode, uplevel: 5) + return [false, nil] + end + end + + def make_scanner(src) # :nodoc: + Scanner.make_scanner(src, @trim_mode, @percent) + end + + # Construct a new compiler using the trim_mode. See ERB::new for available + # trim modes. + def initialize(trim_mode) + @percent, @trim_mode = prepare_trim_mode(trim_mode) + @put_cmd = 'print' + @insert_cmd = @put_cmd + @pre_cmd = [] + @post_cmd = [] + end + attr_reader :percent, :trim_mode + + # The command to handle text that ends with a newline + attr_accessor :put_cmd + + # The command to handle text that is inserted prior to a newline + attr_accessor :insert_cmd + + # An array of commands prepended to compiled code + attr_accessor :pre_cmd + + # An array of commands appended to compiled code + attr_accessor :post_cmd + + private + + # A buffered text in #compile + attr_accessor :content + + def detect_magic_comment(s, enc = nil) + re = @percent ? /\G(?:<%#(.*)%>|%#(.*)\n)/ : /\G<%#(.*)%>/ + frozen = nil + s.scan(re) do + comment = $+ + comment = $1 if comment[/-\*-\s*([^\s].*?)\s*-\*-$/] + case comment + when %r"coding\s*[=:]\s*([[:alnum:]\-_]+)" + enc = Encoding.find($1.sub(/-(?:mac|dos|unix)/i, '')) + when %r"frozen[-_]string[-_]literal\s*:\s*([[:alnum:]]+)" + frozen = $1 + end + end + return enc, frozen + end + + # :stopdoc: + WARNING_UPLEVEL = Class.new { + attr_reader :c + def initialize from + @c = caller.length - from.length + end + }.new(caller(0)).c + private_constant :WARNING_UPLEVEL + # :startdoc: + + def warn_invalid_trim_mode(mode, uplevel:) + warn "Invalid ERB trim mode: #{mode.inspect} (trim_mode: nil, 0, 1, 2, or String composed of '%' and/or '-', '>', '<>')", uplevel: uplevel + WARNING_UPLEVEL + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/lib/erb/def_method.rb b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/lib/erb/def_method.rb new file mode 100644 index 00000000..e503b371 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/lib/erb/def_method.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +# ERB::DefMethod +# +# Utility module to define eRuby script as instance method. +# +# === Example +# +# example.rhtml: +# <% for item in @items %> +# <%= item %> +# <% end %> +# +# example.rb: +# require 'erb' +# class MyClass +# extend ERB::DefMethod +# def_erb_method('render()', 'example.rhtml') +# def initialize(items) +# @items = items +# end +# end +# print MyClass.new([10,20,30]).render() +# +# result: +# +# 10 +# +# 20 +# +# 30 +# +module ERB::DefMethod + # define _methodname_ as instance method of current module, using ERB + # object or eRuby file + def def_erb_method(methodname, erb_or_fname) + if erb_or_fname.kind_of? String + fname = erb_or_fname + erb = ERB.new(File.read(fname)) + erb.def_method(self, methodname, fname) + else + erb = erb_or_fname + erb.def_method(self, methodname, erb.filename || '(ERB)') + end + end + module_function :def_erb_method +end diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/lib/erb/util.rb b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/lib/erb/util.rb new file mode 100644 index 00000000..42c7a576 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/lib/erb/util.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true + +# Load CGI.escapeHTML and CGI.escapeURIComponent. +# CRuby: +# cgi.gem v0.1.0+ (Ruby 2.7-3.4) and Ruby 3.5+ stdlib have 'cgi/escape' and CGI.escapeHTML. +# cgi.gem v0.3.3+ (Ruby 3.2-3.4) and Ruby 3.5+ stdlib have CGI.escapeURIComponent. +# JRuby: cgi.gem has a Java extension 'cgi/escape'. +# TruffleRuby: lib/truffle/cgi/escape.rb requires 'cgi/util'. +require 'cgi/escape' + +# Load or define ERB::Escape#html_escape. +# We don't build the C extention 'cgi/escape' for JRuby, TruffleRuby, and WASM. +# miniruby (used by CRuby build scripts) also fails to load erb/escape.so. +begin + require 'erb/escape' +rescue LoadError + # ERB::Escape + # + # A subset of ERB::Util. Unlike ERB::Util#html_escape, we expect/hope + # Rails will not monkey-patch ERB::Escape#html_escape. + module ERB::Escape + def html_escape(s) + CGI.escapeHTML(s.to_s) + end + module_function :html_escape + end +end + +# ERB::Util +# +# A utility module for conversion routines, often handy in HTML generation. +module ERB::Util + # + # A utility method for escaping HTML tag characters in _s_. + # + # require "erb" + # include ERB::Util + # + # puts html_escape("is a > 0 & a < 10?") + # + # _Generates_ + # + # is a > 0 & a < 10? + # + include ERB::Escape # html_escape + module_function :html_escape + alias h html_escape + module_function :h + + # + # A utility method for encoding the String _s_ as a URL. + # + # require "erb" + # include ERB::Util + # + # puts url_encode("Programming Ruby: The Pragmatic Programmer's Guide") + # + # _Generates_ + # + # Programming%20Ruby%3A%20%20The%20Pragmatic%20Programmer%27s%20Guide + # + if CGI.respond_to?(:escapeURIComponent) + def url_encode(s) + CGI.escapeURIComponent(s.to_s) + end + else # cgi.gem <= v0.3.2 + def url_encode(s) + s.to_s.b.gsub(/[^a-zA-Z0-9_\-.~]/n) do |m| + sprintf("%%%02X", m.unpack1("C")) + end + end + end + alias u url_encode + module_function :u + module_function :url_encode +end diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/lib/erb/version.rb b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/lib/erb/version.rb new file mode 100644 index 00000000..3d0cedcd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/lib/erb/version.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true +class ERB + VERSION = '5.0.1' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/libexec/erb b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/libexec/erb new file mode 100755 index 00000000..4381671f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/erb-5.0.1/libexec/erb @@ -0,0 +1,164 @@ +#!/usr/bin/env ruby +# Tiny eRuby --- ERB2 +# Copyright (c) 1999-2000,2002 Masatoshi SEKI +# You can redistribute it and/or modify it under the same terms as Ruby. + +require 'erb' + +class ERB + module Main + def ARGV.switch + return nil if self.empty? + arg = self.shift + return nil if arg == '--' + case arg + when /\A-(.)(.*)/ + if $1 == '-' + arg, @maybe_arg = arg.split(/=/, 2) + return arg + end + raise 'unknown switch "-"' if $2[0] == ?- and $1 != 'T' + if $2.size > 0 + self.unshift "-#{$2}" + @maybe_arg = $2 + else + @maybe_arg = nil + end + "-#{$1}" + when /\A(\w+)=/ + arg + else + self.unshift arg + nil + end + end + + def ARGV.req_arg + (@maybe_arg || self.shift || raise('missing argument')).tap { + @maybe_arg = nil + } + end + + def trim_mode_opt(trim_mode, disable_percent) + return trim_mode if disable_percent + case trim_mode + when 0 + return '%' + when 1 + return '%>' + when 2 + return '%<>' + when '-' + return '%-' + end + end + module_function :trim_mode_opt + + def run(factory=ERB) + trim_mode = 0 + disable_percent = false + variables = {} + begin + while switch = ARGV.switch + case switch + when '-x' # ruby source + output = true + when '-n' # line number + number = true + when '-v' # verbose + $VERBOSE = true + when '--version' # version + STDERR.puts factory.version + exit + when '-d', '--debug' # debug + $DEBUG = true + when '-r' # require + require ARGV.req_arg + when '-T' # trim mode + arg = ARGV.req_arg + if arg == '-' + trim_mode = arg + next + end + raise "invalid trim mode #{arg.dump}" unless arg =~ /\A[0-2]\z/ + trim_mode = arg.to_i + when '-E', '--encoding' + arg = ARGV.req_arg + set_encoding(*arg.split(/:/, 2)) + when '-U' + set_encoding(Encoding::UTF_8, Encoding::UTF_8) + when '-P' + disable_percent = true + when '--help' + raise "print this help" + when /\A-/ + raise "unknown switch #{switch.dump}" + else + var, val = *switch.split('=', 2) + (variables ||= {})[var] = val + end + end + rescue # usage + STDERR.puts $!.to_s + STDERR.puts File.basename($0) + + " [switches] [var=value...] [inputfile]" + STDERR.puts <= 1.3.0 - [@ericproulx](https://github.com/ericproulx). +* [#2301](https://github.com/ruby-grape/grape/pull/2301): Revisit GH workflows - [@ericproulx](https://github.com/ericproulx). +* [#2311](https://github.com/ruby-grape/grape/pull/2311): Fix tests by pinning rack-test to < 2.1 - [@duffn](https://github.com/duffn). +* [#2310](https://github.com/ruby-grape/grape/pull/2310): Fix YARD docs markdown rendering - [@duffn](https://github.com/duffn). +* [#2317](https://github.com/ruby-grape/grape/pull/2317): Remove maruku and rubocop-ast as direct development/testing dependencies - [@ericproulx](https://github.com/ericproulx). +* [#2292](https://github.com/ruby-grape/grape/pull/2292): Introduce Docker to local development - [@ericproulx](https://github.com/ericproulx). +* [#2325](https://github.com/ruby-grape/grape/pull/2325): Change edge test workflows only run on demand - [@dblock](https://github.com/dblock). +* [#2324](https://github.com/ruby-grape/grape/pull/2324): Expose default in the description dsl - [@dhruvCW](https://github.com/dhruvCW). + +#### Fixes + +* [#2299](https://github.com/ruby-grape/grape/pull/2299): Fix, do not use kwargs for empty args - [@dm1try](https://github.com/dm1try). +* [#2307](https://github.com/ruby-grape/grape/pull/2307): Fixed autoloading of InvalidValue - [@fixlr](https://github.com/fixlr). +* [#2315](https://github.com/ruby-grape/grape/pull/2315): Update rspec - [@ericproulx](https://github.com/ericproulx). +* [#2319](https://github.com/ruby-grape/grape/pull/2319): Update rubocop - [@ericproulx](https://github.com/ericproulx). +* [#2323](https://github.com/ruby-grape/grape/pull/2323): Fix using endless ranges for values parameter - [@dhruvCW](https://github.com/dhruvCW). + +### 1.7.0 (2022/12/20) + +#### Features + +* [#2233](https://github.com/ruby-grape/grape/pull/2233): Added `do_not_document!` for disabling documentation to internal APIs - [@dnesteryuk](https://github.com/dnesteryuk). +* [#2235](https://github.com/ruby-grape/grape/pull/2235): Add support for Ruby 3.1 - [@petergoldstein](https://github.com/petergoldstein). +* [#2248](https://github.com/ruby-grape/grape/pull/2248): Upgraded to rspec 3.11.0 - [@dblock](https://github.com/dblock). +* [#2249](https://github.com/ruby-grape/grape/pull/2249): Split CI matrix, extract edge - [@dblock](https://github.com/dblock). +* [#2249](https://github.com/ruby-grape/grape/pull/2251): Upgraded to RuboCop 1.25.1 - [@dblock](https://github.com/dblock). +* [#2271](https://github.com/ruby-grape/grape/pull/2271): Fixed validation regression on Numeric type introduced in 1.3 - [@vasfed](https://github.com/Vasfed). +* [#2267](https://github.com/ruby-grape/grape/pull/2267): Standardized English error messages - [@dblock](https://github.com/dblock). +* [#2272](https://github.com/ruby-grape/grape/pull/2272): Added error on param init when provided type does not have `[]` coercion method, previously validation silently failed for any value - [@vasfed](https://github.com/Vasfed). +* [#2274](https://github.com/ruby-grape/grape/pull/2274): Error middleware support using rack util's symbols as status - [@dhruvCW](https://github.com/dhruvCW). +* [#2276](https://github.com/ruby-grape/grape/pull/2276): Fix exception super - [@ericproulx](https://github.com/ericproulx). +* [#2285](https://github.com/ruby-grape/grape/pull/2285), [#2287](https://github.com/ruby-grape/grape/pull/2287): Added :evaluate_given to declared(params) - [@zysend](https://github.com/zysend). + +#### Fixes + +* [#2263](https://github.com/ruby-grape/grape/pull/2263): Explicitly require `bigdecimal` and `date` - [@dblock](https://github.com/dblock). +* [#2222](https://github.com/ruby-grape/grape/pull/2222): Autoload types and validators - [@ericproulx](https://github.com/ericproulx). +* [#2232](https://github.com/ruby-grape/grape/pull/2232): Fix kwargs support in shared params definition - [@dm1try](https://github.com/dm1try). +* [#2229](https://github.com/ruby-grape/grape/pull/2229): Do not collect params in route settings - [@dnesteryuk](https://github.com/dnesteryuk). +* [#2234](https://github.com/ruby-grape/grape/pull/2234): Remove non-UTF8 characters from format before generating JSON error - [@bschmeck](https://github.com/bschmeck). +* [#2227](https://github.com/ruby-grape/grape/pull/2222): Rename `MissingGroupType` and `UnsupportedGroupType` exceptions - [@ericproulx](https://github.com/ericproulx). +* [#2244](https://github.com/ruby-grape/grape/pull/2244): Fix a breaking change in `Grape::Validations` provided in 1.6.1 - [@dm1try](https://github.com/dm1try). +* [#2250](https://github.com/ruby-grape/grape/pull/2250): Add deprecation warning for `UnsupportedGroupTypeError` and `MissingGroupTypeError` - [@ericproulx](https://github.com/ericproulx). +* [#2256](https://github.com/ruby-grape/grape/pull/2256): Raise `Grape::Exceptions::MultipartPartLimitError` from Rack when too many files are uploaded - [@bschmeck](https://github.com/bschmeck). +* [#2266](https://github.com/ruby-grape/grape/pull/2266): Fix code coverage - [@duffn](https://github.com/duffn). +* [#2284](https://github.com/ruby-grape/grape/pull/2284): Fix an unexpected backtick - [@zysend](https://github.com/zysend). + +### 1.6.2 (2021/12/30) + +#### Fixes + +* [#2219](https://github.com/ruby-grape/grape/pull/2219): Revert the changes for autoloading provided in 1.6.1 - [@dm1try](https://github.com/dm1try). + +### 1.6.1 (2021/12/28) + +#### Features + +* [#2196](https://github.com/ruby-grape/grape/pull/2196): Add support for `passwords_hashed` param for `digest_auth` - [@lHydra](https://github.com/lhydra). +* [#2208](https://github.com/ruby-grape/grape/pull/2208): Added Rails 7 support - [@ericproulx](https://github.com/ericproulx). + +#### Fixes + +* [#2206](https://github.com/ruby-grape/grape/pull/2206): Require main active_support lib before any of its extension definitions - [@annih](https://github.com/Annih). +* [#2193](https://github.com/ruby-grape/grape/pull/2193): Fixed the broken ruby-head NoMethodError spec - [@Jack12816](https://github.com/Jack12816). +* [#2192](https://github.com/ruby-grape/grape/pull/2192): Memoize the result of Grape::Middleware::Base#response - [@Jack12816](https://github.com/Jack12816). +* [#2200](https://github.com/ruby-grape/grape/pull/2200): Add validators module to all validators - [@ericproulx](https://github.com/ericproulx). +* [#2202](https://github.com/ruby-grape/grape/pull/2202): Fix random mock spec error - [@ericproulx](https://github.com/ericproulx). +* [#2203](https://github.com/ruby-grape/grape/pull/2203): Add rubocop-rspec - [@ericproulx](https://github.com/ericproulx). +* [#2207](https://github.com/ruby-grape/grape/pull/2207): Autoload Validations/Validators - [@ericproulx](https://github.com/ericproulx). +* [#2209](https://github.com/ruby-grape/grape/pull/2209): Autoload Validations/Types - [@ericproulx](https://github.com/ericproulx). + +### 1.6.0 (2021/10/04) + +#### Features + +* [#2190](https://github.com/ruby-grape/grape/pull/2190): Upgrade dev deps & drop Ruby 2.4.x support - [@dnesteryuk](https://github.com/dnesteryuk). + +#### Fixes + +* [#2176](https://github.com/ruby-grape/grape/pull/2176): Fix: OPTIONS fails if matching all routes - [@myxoh](https://github.com/myxoh). +* [#2177](https://github.com/ruby-grape/grape/pull/2177): Fix: `default` validator fails if preceded by `as` validator - [@Catsuko](https://github.com/Catsuko). +* [#2180](https://github.com/ruby-grape/grape/pull/2180): Call `super` in `API.inherited` - [@yogeshjain999](https://github.com/yogeshjain999). +* [#2189](https://github.com/ruby-grape/grape/pull/2189): Fix: rename parameters when using `:as` (behaviour and grape-swagger documentation) - [@Jack12816](https://github.com/Jack12816). + +### 1.5.3 (2021/03/07) + +#### Fixes + +* [#2161](https://github.com/ruby-grape/grape/pull/2157): Handle EOFError from Rack when given an empty multipart body - [@bschmeck](https://github.com/bschmeck). +* [#2162](https://github.com/ruby-grape/grape/pull/2162): Corrected a hash modification while iterating issue - [@Jack12816](https://github.com/Jack12816). +* [#2164](https://github.com/ruby-grape/grape/pull/2164): Fix: `coerce_with` is now called for params with `nil` value - [@braktar](https://github.com/braktar). + +### 1.5.2 (2021/02/06) + +#### Features + +* [#2157](https://github.com/ruby-grape/grape/pull/2157): Custom types can set a message to be used in the response when invalid - [@dnesteryuk](https://github.com/dnesteryuk). +* [#2145](https://github.com/ruby-grape/grape/pull/2145): Ruby 3.0 compatibility - [@ericproulx](https://github.com/ericproulx). +* [#2143](https://github.com/ruby-grape/grape/pull/2143): Enable GitHub Actions with updated RuboCop and Danger - [@anakinj](https://github.com/anakinj). + +#### Fixes + +* [#2144](https://github.com/ruby-grape/grape/pull/2144): Fix compatibility issue with activesupport 6.1 and XML serialization of arrays - [@anakinj](https://github.com/anakinj). +* [#2137](https://github.com/ruby-grape/grape/pull/2137): Fix typos - [@johnny-miyake](https://github.com/johnny-miyake). +* [#2131](https://github.com/ruby-grape/grape/pull/2131): Fix Ruby 2.7 keyword deprecation warning in validators/coerce - [@K0H205](https://github.com/K0H205). +* [#2132](https://github.com/ruby-grape/grape/pull/2132): Use #ruby2_keywords for correct delegation on Ruby <= 2.6, 2.7 and 3 - [@eregon](https://github.com/eregon). +* [#2152](https://github.com/ruby-grape/grape/pull/2152): Fix configuration method inside namespaced params - [@fsainz](https://github.com/fsainz). + +### 1.5.1 (2020/11/15) + +#### Fixes + +* [#2129](https://github.com/ruby-grape/grape/pull/2129): Fix validation error when Required Array nested inside an optional array, for Multiparam validators - [@dwhenry](https://github.com/dwhenry). +* [#2128](https://github.com/ruby-grape/grape/pull/2128): Fix validation error when Required Array nested inside an optional array - [@dwhenry](https://github.com/dwhenry). +* [#2127](https://github.com/ruby-grape/grape/pull/2127): Fix a performance issue with dependent params - [@dnesteryuk](https://github.com/dnesteryuk). +* [#2126](https://github.com/ruby-grape/grape/pull/2126): Fix warnings about redefined attribute accessors in `AttributeTranslator` - [@samsonjs](https://github.com/samsonjs). +* [#2121](https://github.com/ruby-grape/grape/pull/2121): Fix 2.7 deprecation warning in validator_factory - [@Legogris](https://github.com/Legogris). +* [#2115](https://github.com/ruby-grape/grape/pull/2115): Fix declared_params regression with multiple allowed types - [@stanhu](https://github.com/stanhu). +* [#2123](https://github.com/ruby-grape/grape/pull/2123): Fix 2.7 deprecation warning in middleware/stack - [@Legogris](https://github.com/Legogris). + +### 1.5.0 (2020/10/05) + +#### Fixes + +* [#2104](https://github.com/ruby-grape/grape/pull/2104): Fix Ruby 2.7 keyword deprecation warning - [@stanhu](https://github.com/stanhu). +* [#2103](https://github.com/ruby-grape/grape/pull/2103): Ensure complete declared params structure is present - [@tlconnor](https://github.com/tlconnor). +* [#2099](https://github.com/ruby-grape/grape/pull/2099): Added truffleruby to Travis-CI - [@gogainda](https://github.com/gogainda). +* [#2089](https://github.com/ruby-grape/grape/pull/2089): Specify order of mounting Grape with Rack::Cascade in README - [@jonmchan](https://github.com/jonmchan). +* [#2088](https://github.com/ruby-grape/grape/pull/2088): Set `Cache-Control` header only for streamed responses - [@stanhu](https://github.com/stanhu). +* [#2092](https://github.com/ruby-grape/grape/pull/2092): Correct an example params in Include Missing doc - [@huyvohcmc](https://github.com/huyvohcmc). +* [#2091](https://github.com/ruby-grape/grape/pull/2091): Fix ruby 2.7 keyword deprecations - [@dim](https://github.com/dim). +* [#2097](https://github.com/ruby-grape/grape/pull/2097): Skip to set default value unless `meets_dependency?` - [@wanabe](https://github.com/wanabe). +* [#2096](https://github.com/ruby-grape/grape/pull/2096): Fix redundant dependency check - [@braktar](https://github.com/braktar). +* [#2096](https://github.com/ruby-grape/grape/pull/2098): Fix nested coercion - [@braktar](https://github.com/braktar). +* [#2102](https://github.com/ruby-grape/grape/pull/2102): Fix retaining setup blocks when remounting APIs - [@jylamont](https://github.com/jylamont). + +### 1.4.0 (2020/07/10) + +#### Features + +* [#1520](https://github.com/ruby-grape/grape/pull/1520): Un-deprecate stream-like objects - [@urkle](https://github.com/urkle). +* [#2060](https://github.com/ruby-grape/grape/pull/2060): Drop support for Ruby 2.4 - [@dblock](https://github.com/dblock). +* [#2060](https://github.com/ruby-grape/grape/pull/2060): Upgraded Rubocop to 0.84.0 - [@dblock](https://github.com/dblock). +* [#2077](https://github.com/ruby-grape/grape/pull/2077): Simplify logic for defining declared params - [@dnesteryuk](https://github.com/dnesteryuk). +* [#2076](https://github.com/ruby-grape/grape/pull/2076): Make route information available for hooks when the automatically generated endpoints are invoked - [@anakinj](https://github.com/anakinj). + +#### Fixes + +* [#2067](https://github.com/ruby-grape/grape/pull/2067): Coerce empty String to `nil` for all primitive types except `String` - [@petekinnecom](https://github.com/petekinnecom). +* [#2064](https://github.com/ruby-grape/grape/pull/2064): Fix Ruby 2.7 deprecation warning in `Grape::Middleware::Base#initialize` - [@skarger](https://github.com/skarger). +* [#2072](https://github.com/ruby-grape/grape/pull/2072): Fix `Grape.eager_load!` and `compile!` - [@stanhu](https://github.com/stanhu). +* [#2084](https://github.com/ruby-grape/grape/pull/2084): Fix memory leak in path normalization - [@fcheung](https://github.com/fcheung). + +### 1.3.3 (2020/05/23) + +#### Features + +* [#2048](https://github.com/ruby-grape/grape/issues/2034): Grape Enterprise support is now available [via TideLift](https://tidelift.com/subscription/request-a-demo?utm_source=rubygems-grape&utm_medium=referral&utm_campaign=enterprise) - [@dblock](https://github.com/dblock). +* [#2039](https://github.com/ruby-grape/grape/pull/2039): Travis - update rails versions - [@ericproulx](https://github.com/ericproulx). +* [#2038](https://github.com/ruby-grape/grape/pull/2038): Travis - update ruby versions - [@ericproulx](https://github.com/ericproulx). +* [#2050](https://github.com/ruby-grape/grape/pull/2050): Refactor route public_send to AttributeTranslator - [@ericproulx](https://github.com/ericproulx). + +#### Fixes + +* [#2049](https://github.com/ruby-grape/grape/pull/2049): Coerce an empty string to nil in case of the bool type - [@dnesteryuk](https://github.com/dnesteryuk). +* [#2043](https://github.com/ruby-grape/grape/pull/2043): Modify declared for nested array and hash - [@kadotami](https://github.com/kadotami). +* [#2040](https://github.com/ruby-grape/grape/pull/2040): Fix a regression with Array of type nil - [@ericproulx](https://github.com/ericproulx). +* [#2054](https://github.com/ruby-grape/grape/pull/2054): Coercing of nested arrays - [@dnesteryuk](https://github.com/dnesteryuk). +* [#2050](https://github.com/ruby-grape/grape/pull/2053): Fix broken multiple mounts - [@Jack12816](https://github.com/Jack12816). + +### 1.3.2 (2020/04/12) + +#### Features + +* [#2020](https://github.com/ruby-grape/grape/pull/2020): Reduce array allocation - [@ericproulx](https://github.com/ericproulx). +* [#2015](https://github.com/ruby-grape/grape/pull/2014): Reduce MatchData allocation - [@ericproulx](https://github.com/ericproulx). +* [#2014](https://github.com/ruby-grape/grape/pull/2014): Reduce total allocated arrays - [@ericproulx](https://github.com/ericproulx). +* [#2011](https://github.com/ruby-grape/grape/pull/2011): Reduce total retained regexes - [@ericproulx](https://github.com/ericproulx). + +#### Fixes + +* [#2033](https://github.com/ruby-grape/grape/pull/2033): Ensure `Float` params are correctly coerced to `BigDecimal` - [@tlconnor](https://github.com/tlconnor). +* [#2031](https://github.com/ruby-grape/grape/pull/2031): Fix a regression with an array of a custom type - [@dnesteryuk](https://github.com/dnesteryuk). +* [#2026](https://github.com/ruby-grape/grape/pull/2026): Fix a regression in `coerce_with` when coercion returns `nil` - [@misdoro](https://github.com/misdoro). +* [#2025](https://github.com/ruby-grape/grape/pull/2025): Fix Decimal type category - [@kdoya](https://github.com/kdoya). +* [#2019](https://github.com/ruby-grape/grape/pull/2019): Avoid coercing parameter with multiple types to an empty Array - [@stanhu](https://github.com/stanhu). + +### 1.3.1 (2020/03/11) + +#### Features + +* [#2005](https://github.com/ruby-grape/grape/pull/2005): Content types registrable - [@ericproulx](https://github.com/ericproulx). +* [#2003](https://github.com/ruby-grape/grape/pull/2003): Upgraded Rubocop to 0.80.1 - [@ericproulx](https://github.com/ericproulx). +* [#2002](https://github.com/ruby-grape/grape/pull/2002): Objects allocation optimization (lazy_lookup) - [@ericproulx](https://github.com/ericproulx). + +#### Fixes + +* [#2006](https://github.com/ruby-grape/grape/pull/2006): Fix explicit rescue StandardError - [@ericproulx](https://github.com/ericproulx). +* [#2004](https://github.com/ruby-grape/grape/pull/2004): Rubocop fixes - [@ericproulx](https://github.com/ericproulx). +* [#1995](https://github.com/ruby-grape/grape/pull/1995): Fix: "undefined instance variables" and "method redefined" warnings - [@nbeyer](https://github.com/nbeyer). +* [#1994](https://github.com/ruby-grape/grape/pull/1993): Fix typos in README - [@bellmyer](https://github.com/bellmyer). +* [#1993](https://github.com/ruby-grape/grape/pull/1993): Lazy join allow header - [@ericproulx](https://github.com/ericproulx). +* [#1987](https://github.com/ruby-grape/grape/pull/1987): Re-add exactly_one_of mutually exclusive error message - [@ZeroInputCtrl](https://github.com/ZeroInputCtrl). +* [#1977](https://github.com/ruby-grape/grape/pull/1977): Skip validation for a file if it is optional and nil - [@dnesteryuk](https://github.com/dnesteryuk). +* [#1976](https://github.com/ruby-grape/grape/pull/1976): Ensure classes/modules listed for autoload really exist - [@dnesteryuk](https://github.com/dnesteryuk). +* [#1971](https://github.com/ruby-grape/grape/pull/1971): Fix BigDecimal coercion - [@FlickStuart](https://github.com/FlickStuart). +* [#1968](https://github.com/ruby-grape/grape/pull/1968): Fix args forwarding in Grape::Middleware::Stack#merge_with for ruby 2.7.0 - [@dm1try](https://github.com/dm1try). +* [#1988](https://github.com/ruby-grape/grape/pull/1988): Refactor the full_messages method and stop overriding full_message - [@hosseintoussi](https://github.com/hosseintoussi). +* [#1956](https://github.com/ruby-grape/grape/pull/1956): Comply with Rack spec, fix `undefined method [] for nil:NilClass` error when upgrading Rack - [@ioquatix](https://github.com/ioquatix). + +### 1.3.0 (2020/01/11) + +#### Features + +* [#1949](https://github.com/ruby-grape/grape/pull/1949): Add support for Ruby 2.7 - [@nbulaj](https://github.com/nbulaj). +* [#1948](https://github.com/ruby-grape/grape/pull/1948): Relax `dry-types` dependency version - [@nbulaj](https://github.com/nbulaj). +* [#1944](https://github.com/ruby-grape/grape/pull/1944): Reduces `attribute_translator` string allocations - [@ericproulx](https://github.com/ericproulx). +* [#1943](https://github.com/ruby-grape/grape/pull/1943): Reduces number of regex string allocations - [@ericproulx](https://github.com/ericproulx). +* [#1942](https://github.com/ruby-grape/grape/pull/1942): Optimizes retained memory methods - [@ericproulx](https://github.com/ericproulx). +* [#1941](https://github.com/ruby-grape/grape/pull/1941): Adds frozen string literal - [@ericproulx](https://github.com/ericproulx). +* [#1940](https://github.com/ruby-grape/grape/pull/1940): Gets rid of a needless step in `HashWithIndifferentAccess` - [@dnesteryuk](https://github.com/dnesteryuk). +* [#1938](https://github.com/ruby-grape/grape/pull/1938): Adds project metadata to the gemspec - [@orien](https://github.com/orien). +* [#1920](https://github.com/ruby-grape/grape/pull/1920): Replaces Virtus with dry-types - [@dnesteryuk](https://github.com/dnesteryuk). +* [#1930](https://github.com/ruby-grape/grape/pull/1930): Moves block call to separate method so it can be spied on - [@estolfo](https://github.com/estolfo). + +#### Fixes + +* [#1965](https://github.com/ruby-grape/grape/pull/1965): Fix typos in README - [@davidalee](https://github.com/davidalee). +* [#1963](https://github.com/ruby-grape/grape/pull/1963): The values validator must properly work with booleans - [@dnesteryuk](https://github.com/dnesteryuk). +* [#1950](https://github.com/ruby-grape/grape/pull/1950): Consider the allow_blank option in the values validator - [@dnesteryuk](https://github.com/dnesteryuk). +* [#1947](https://github.com/ruby-grape/grape/pull/1947): Careful check for empty params - [@dnesteryuk](https://github.com/dnesteryuk). +* [#1931](https://github.com/ruby-grape/grape/pull/1946): Fixes issue when using namespaces in `Grape::API::Instance` mounted directly - [@myxoh](https://github.com/myxoh). + +### 1.2.5 (2019/12/01) + +#### Features + +* [#1931](https://github.com/ruby-grape/grape/pull/1931): Introduces LazyBlock to generate expressions that will executed at mount time - [@myxoh](https://github.com/myxoh). +* [#1918](https://github.com/ruby-grape/grape/pull/1918): Helper methods to access controller context from middleware - [@NikolayRys](https://github.com/NikolayRys). +* [#1915](https://github.com/ruby-grape/grape/pull/1915): Micro optimizations in allocating hashes and arrays - [@dnesteryuk](https://github.com/dnesteryuk). +* [#1904](https://github.com/ruby-grape/grape/pull/1904): Allows Grape to load files on startup rather than on the first call - [@myxoh](https://github.com/myxoh). +* [#1907](https://github.com/ruby-grape/grape/pull/1907): Adds outside configuration to Grape with `configure` - [@unleashy](https://github.com/unleashy). +* [#1914](https://github.com/ruby-grape/grape/pull/1914): Run specs in random order - [@splattael](https://github.com/splattael). + +#### Fixes + +* [#1917](https://github.com/ruby-grape/grape/pull/1917): Update access to rack constant - [@NikolayRys](https://github.com/NikolayRys). +* [#1916](https://github.com/ruby-grape/grape/pull/1916): Drop old appraisals - [@NikolayRys](https://github.com/NikolayRys). +* [#1911](https://github.com/ruby-grape/grape/pull/1911): Make sure `Grape::Valiations::AtLeastOneOfValidator` properly treats nested params in errors - [@dnesteryuk](https://github.com/dnesteryuk). +* [#1893](https://github.com/ruby-grape/grape/pull/1893): Allows `Grape::API` to behave like a Rack::app in some instances where it was misbehaving - [@myxoh](https://github.com/myxoh). +* [#1898](https://github.com/ruby-grape/grape/pull/1898): Refactor `ValidatorFactory` to improve memory allocation - [@Bhacaz](https://github.com/Bhacaz). +* [#1900](https://github.com/ruby-grape/grape/pull/1900): Define boolean for `Grape::Api::Instance` - [@Bhacaz](https://github.com/Bhacaz). +* [#1903](https://github.com/ruby-grape/grape/pull/1903): Allow nested params renaming (Hash/Array) - [@bikolya](https://github.com/bikolya). +* [#1913](https://github.com/ruby-grape/grape/pull/1913): Fix multiple params validators to return correct messages for nested params - [@bikolya](https://github.com/bikolya). +* [#1926](https://github.com/ruby-grape/grape/pull/1926): Fixes configuration within given or mounted blocks - [@myxoh](https://github.com/myxoh). +* [#1937](https://github.com/ruby-grape/grape/pull/1937): Fix bloat in released gem - [@dblock](https://github.com/dblock). + +### 1.2.4 (2019/06/13) + +#### Features + +* [#1888](https://github.com/ruby-grape/grape/pull/1888): Makes the `configuration` hash widely available - [@myxoh](https://github.com/myxoh). +* [#1864](https://github.com/ruby-grape/grape/pull/1864): Adds `finally` on the API - [@myxoh](https://github.com/myxoh). +* [#1869](https://github.com/ruby-grape/grape/pull/1869): Fix issue with empty headers after `error!` method call - [@anaumov](https://github.com/anaumov). + +#### Fixes + +* [#1868](https://github.com/ruby-grape/grape/pull/1868): Fix NoMethodError with none hash params - [@ksss](https://github.com/ksss). +* [#1876](https://github.com/ruby-grape/grape/pull/1876): Fix const errors being hidden by bug in `const_missing` - [@dandehavilland](https://github.com/dandehavilland). + +### 1.2.3 (2019/01/16) + +#### Features + +* [#1850](https://github.com/ruby-grape/grape/pull/1850): Adds `same_as` validator - [@glaucocustodio](https://github.com/glaucocustodio). +* [#1833](https://github.com/ruby-grape/grape/pull/1833): Allows to set the `ParamBuilder` globally - [@myxoh](https://github.com/myxoh). + +#### Fixes + +* [#1852](https://github.com/ruby-grape/grape/pull/1852): `allow_blank` called after `as` when the original param is not blank - [@glaucocustodio](https://github.com/glaucocustodio). +* [#1844](https://github.com/ruby-grape/grape/pull/1844): Enforce `:tempfile` to be a `Tempfile` object in `File` validator - [@Nyangawa](https://github.com/Nyangawa). + +### 1.2.2 (2018/12/07) + +#### Features + +* [#1832](https://github.com/ruby-grape/grape/pull/1832): Support `body_name` in `desc` block - [@fotos](https://github.com/fotos). +* [#1831](https://github.com/ruby-grape/grape/pull/1831): Support `security` in `desc` block - [@fotos](https://github.com/fotos). + +#### Fixes + +* [#1836](https://github.com/ruby-grape/grape/pull/1836): Fix: memory leak not releasing `call` method calls from setup - [@myxoh](https://github.com/myxoh). +* [#1830](https://github.com/ruby-grape/grape/pull/1830), [#1829](https://github.com/ruby-grape/grape/issues/1829): Restores `self` sanity - [@myxoh](https://github.com/myxoh). + +### 1.2.1 (2018/11/28) + +#### Fixes + +* [#1825](https://github.com/ruby-grape/grape/pull/1825): `to_s` on a mounted class now responses with the API name - [@myxoh](https://github.com/myxoh). + +### 1.2.0 (2018/11/26) + +#### Features + +* [#1813](https://github.com/ruby-grape/grape/pull/1813): Add ruby 2.5 support, drop 2.2. Update rails version in travis - [@darren987469](https://github.com/darren987469). +* [#1803](https://github.com/ruby-grape/grape/pull/1803): Adds the ability to re-mount all endpoints in any location - [@myxoh](https://github.com/myxoh). +* [#1795](https://github.com/ruby-grape/grape/pull/1795): Fix vendor/subtype parsing of an invalid Accept header - [@bschmeck](https://github.com/bschmeck). +* [#1791](https://github.com/ruby-grape/grape/pull/1791): Support `summary`, `hidden`, `deprecated`, `is_array`, `nickname`, `produces`, `consumes`, `tags` options in `desc` block - [@darren987469](https://github.com/darren987469). + +#### Fixes + +* [#1796](https://github.com/ruby-grape/grape/pull/1796): Fix crash when available locales are enforced but fallback locale unavailable - [@Morred](https://github.com/Morred). +* [#1776](https://github.com/ruby-grape/grape/pull/1776): Validate response returned by the exception handler - [@darren987469](https://github.com/darren987469). +* [#1787](https://github.com/ruby-grape/grape/pull/1787): Add documented but not implemented ability to `.insert` a middleware in the stack - [@michaellennox](https://github.com/michaellennox). +* [#1788](https://github.com/ruby-grape/grape/pull/1788): Fix route requirements bug - [@darren987469](https://github.com/darren987469), [@darrellnash](https://github.com/darrellnash). +* [#1810](https://github.com/ruby-grape/grape/pull/1810): Fix support in `given` for aliased params - [@darren987469](https://github.com/darren987469). +* [#1811](https://github.com/ruby-grape/grape/pull/1811): Support nested dependent parameters - [@darren987469](https://github.com/darren987469), [@andreacfm](https://github.com/andreacfm). +* [#1822](https://github.com/ruby-grape/grape/pull/1822): Raise validation error when optional hash type parameter is received string type value and exactly_one_of be used - [@woshidan](https://github.com/woshidan). + +### 1.1.0 (2018/8/4) + +#### Features + +* [#1759](https://github.com/ruby-grape/grape/pull/1759): Instrument serialization as `'format_response.grape'` - [@zvkemp](https://github.com/zvkemp). + +#### Fixes + +* [#1762](https://github.com/ruby-grape/grape/pull/1763): Fix unsafe HTML rendering on errors - [@ctennis](https://github.com/ctennis). +* [#1759](https://github.com/ruby-grape/grape/pull/1759): Update appraisal for rails_edge - [@zvkemp](https://github.com/zvkemp). +* [#1758](https://github.com/ruby-grape/grape/pull/1758): Fix expanding load_path in gemspec - [@2maz](https://github.com/2maz). +* [#1765](https://github.com/ruby-grape/grape/pull/1765): Use 415 when request body is of an unsupported media type - [@jdmurphy](https://github.com/jdmurphy). +* [#1771](https://github.com/ruby-grape/grape/pull/1771): Fix param aliases with 'given' blocks - [@jereynolds](https://github.com/jereynolds). + +### 1.0.3 (2018/4/23) + +#### Fixes + +* [#1755](https://github.com/ruby-grape/grape/pull/1755): Fix shared params with exactly_one_of - [@milgner](https://github.com/milgner). +* [#1740](https://github.com/ruby-grape/grape/pull/1740): Fix dependent parameter validation using `given` when parameter is a `Hash` - [@jvortmann](https://github.com/jvortmann). +* [#1737](https://github.com/ruby-grape/grape/pull/1737): Fix translating error when passing symbols as params in custom validations - [@mlzhuyi](https://github.com/mlzhuyi). +* [#1749](https://github.com/ruby-grape/grape/pull/1749): Allow rescue from non-`StandardError` exceptions - [@dm1try](https://github.com/dm1try). +* [#1750](https://github.com/ruby-grape/grape/pull/1750): Fix a circular dependency warning due to router being loaded by API - [@salasrod](https://github.com/salasrod). +* [#1752](https://github.com/ruby-grape/grape/pull/1752): Fix `include_missing` behavior for aliased parameters - [@jonasoberschweiber](https://github.com/jonasoberschweiber). +* [#1754](https://github.com/ruby-grape/grape/pull/1754): Allow rescue from non-`StandardError` exceptions to use default error handling - [@jelkster](https://github.com/jelkster). +* [#1756](https://github.com/ruby-grape/grape/pull/1756): Allow custom Grape exception handlers when the built-in exception handling is enabled - [@soylent](https://github.com/soylent). + +### 1.0.2 (2018/1/10) + +#### Features + +* [#1686](https://github.com/ruby-grape/grape/pull/1686): Avoid coercion of a value if it is valid - [@timothysu](https://github.com/timothysu). +* [#1688](https://github.com/ruby-grape/grape/pull/1688): Removes yard docs - [@ramkumar-kr](https://github.com/ramkumar-kr). +* [#1702](https://github.com/ruby-grape/grape/pull/1702): Added danger-toc, verify correct TOC in README - [@dblock](https://github.com/dblock). +* [#1711](https://github.com/ruby-grape/grape/pull/1711): Automatically coerce arrays and sets of types that implement a `parse` method - [@dslh](https://github.com/dslh). + +#### Fixes + +* [#1710](https://github.com/ruby-grape/grape/pull/1710): Fix wrong transformation of empty Array in declared params - [@pablonahuelgomez](https://github.com/pablonahuelgomez). +* [#1722](https://github.com/ruby-grape/grape/pull/1722): Fix catch-all hiding multiple versions of an endpoint after the first definition - [@zherr](https://github.com/zherr). +* [#1724](https://github.com/ruby-grape/grape/pull/1724): Optional nested array validation - [@ericproulx](https://github.com/ericproulx). +* [#1725](https://github.com/ruby-grape/grape/pull/1725): Fix `rescue_from :all` documentation - [@Jelkster](https://github.com/Jelkster). +* [#1726](https://github.com/ruby-grape/grape/pull/1726): Improved startup performance during API method generation - [@jkowens](https://github.com/jkowens). +* [#1727](https://github.com/ruby-grape/grape/pull/1727): Fix infinite loop when mounting endpoint with same superclass - [@jkowens](https://github.com/jkowens). + +### 1.0.1 (2017/9/8) + +#### Features + +* [#1652](https://github.com/ruby-grape/grape/pull/1652): Add the original exception to the error_formatter the original exception - [@dcsg](https://github.com/dcsg). +* [#1665](https://github.com/ruby-grape/grape/pull/1665): Make helpers available in subclasses - [@pablonahuelgomez](https://github.com/pablonahuelgomez). +* [#1674](https://github.com/ruby-grape/grape/pull/1674): Add parameter alias (`as`) - [@glaucocustodio](https://github.com/glaucocustodio). + +#### Fixes + +* [#1652](https://github.com/ruby-grape/grape/pull/1652): Fix missing backtrace that was not being bubbled up to the `error_formatter` - [@dcsg](https://github.com/dcsg). +* [#1661](https://github.com/ruby-grape/grape/pull/1661): Handle deeply-nested dependencies correctly - [@rnubel](https://github.com/rnubel), [@jnardone](https://github.com/jnardone). +* [#1679](https://github.com/ruby-grape/grape/pull/1679): Treat StandardError from explicit values validator proc as false - [@jlfaber](https://github.com/jlfaber). + +### 1.0.0 (2017/7/3) + +#### Features + +* [#1594](https://github.com/ruby-grape/grape/pull/1594): Replace `Hashie::Mash` parameters with `ActiveSupport::HashWithIndifferentAccess` - [@james2m](https://github.com/james2m), [@dblock](https://github.com/dblock). +* [#1622](https://github.com/ruby-grape/grape/pull/1622): Add `except_values` validator to replace `except` option of `values` validator - [@jlfaber](https://github.com/jlfaber). +* [#1635](https://github.com/ruby-grape/grape/pull/1635): Instrument validators with ActiveSupport::Notifications - [@ktimothy](https://github.com/ktimothy). +* [#1646](https://github.com/ruby-grape/grape/pull/1646): Add ability to include an array of modules as helpers - [@pablonahuelgomez](https://github.com/pablonahuelgomez). +* [#1623](https://github.com/ruby-grape/grape/pull/1623): Removed `multi_json` and `multi_xml` dependencies - [@dblock](https://github.com/dblock). +* [#1650](https://github.com/ruby-grape/grape/pull/1650): Add extra specs for Boolean type field - [@tiarly](https://github.com/tiarly). + +#### Fixes + +* [#1648](https://github.com/ruby-grape/grape/pull/1631): Declared now returns declared options using the class that params is set to use - [@thogg4](https://github.com/thogg4). +* [#1632](https://github.com/ruby-grape/grape/pull/1632): Silence warnings - [@thogg4](https://github.com/thogg4). +* [#1615](https://github.com/ruby-grape/grape/pull/1615): Fix default and type validator when values is a Hash with no value attribute - [@jlfaber](https://github.com/jlfaber). +* [#1625](https://github.com/ruby-grape/grape/pull/1625): Handle `given` correctly when nested in Array params - [@rnubel](https://github.com/rnubel), [@avellable](https://github.com/avellable). +* [#1649](https://github.com/ruby-grape/grape/pull/1649): Don't share validator instances between requests - [@anakinj](https://github.com/anakinj). + +### 0.19.2 (2017/4/12) + +#### Features + +* [#1555](https://github.com/ruby-grape/grape/pull/1555): Added code coverage w/Coveralls - [@dblock](https://github.com/dblock). +* [#1568](https://github.com/ruby-grape/grape/pull/1568): Add `proc` option to `values` validator to allow custom checks - [@jlfaber](https://github.com/jlfaber). +* [#1575](https://github.com/ruby-grape/grape/pull/1575): Include nil values for missing nested params in declared - [@thogg4](https://github.com/thogg4). +* [#1585](https://github.com/ruby-grape/grape/pull/1585): Bugs in declared method - make sure correct options var is used and respect include missing for non children params - [@thogg4](https://github.com/thogg4). + +#### Fixes + +* [#1570](https://github.com/ruby-grape/grape/pull/1570): Make versioner consider the mount destination path - [@namusyaka](https://github.com/namusyaka). +* [#1579](https://github.com/ruby-grape/grape/pull/1579): Fix delete status with a return value - [@eproulx-petalmd](https://github.com/eproulx-petalmd). +* [#1559](https://github.com/ruby-grape/grape/pull/1559): You can once again pass `nil` to optional attributes with `values` validation set - [@ghiculescu](https://github.com/ghiculescu). +* [#1562](https://github.com/ruby-grape/grape/pull/1562): Fix rainbow gem installation failure above ruby 2.3.3 on travis-ci - [@brucehsu](https://github.com/brucehsu). +* [#1561](https://github.com/ruby-grape/grape/pull/1561): Fix performance issue introduced by duplicated calls in StackableValue#[] - [@brucehsu](https://github.com/brucehsu). +* [#1564](https://github.com/ruby-grape/grape/pull/1564): Fix declared params bug with nested namespaces - [@bmarini](https://github.com/bmarini). +* [#1567](https://github.com/ruby-grape/grape/pull/1567): Fix values validator when value is empty array and apply except to input array - [@jlfaber](https://github.com/jlfaber). +* [#1569](https://github.com/ruby-grape/grape/pull/1569), [#1511](https://github.com/ruby-grape/grape/issues/1511): Upgrade mustermann-grape to 1.0.0 - [@namusyaka](https://github.com/namusyaka). +* [#1589](https://github.com/ruby-grape/grape/pull/1589): [#726](https://github.com/ruby-grape/grape/issues/726): Use default_format when Content-type is missing and respond with 406 when Content-type is invalid - [@inclooder](https://github.com/inclooder). + +### 0.19.1 (2017/1/9) + +#### Features + +* [#1536](https://github.com/ruby-grape/grape/pull/1536): Updated `invalid_versioner_option` translation - [@Lavode](https://github.com/Lavode). +* [#1543](https://github.com/ruby-grape/grape/pull/1543): Added support for ruby 2.4 - [@LeFnord](https://github.com/LeFnord), [@namusyaka](https://github.com/namusyaka). + +#### Fixes + +* [#1548](https://github.com/ruby-grape/grape/pull/1548): Fix: avoid failing even if given path does not match with prefix - [@thomas-peyric](https://github.com/thomas-peyric), [@namusyaka](https://github.com/namusyaka). +* [#1550](https://github.com/ruby-grape/grape/pull/1550): Fix: return 200 as default status for DELETE - [@jthornec](https://github.com/jthornec). + +### 0.19.0 (2016/12/18) + +#### Features + +* [#1503](https://github.com/ruby-grape/grape/pull/1503): Allowed use of regexp validator with arrays - [@akoltun](https://github.com/akoltun). +* [#1507](https://github.com/ruby-grape/grape/pull/1507): Added group attributes for parameter definitions - [@304](https://github.com/304). +* [#1532](https://github.com/ruby-grape/grape/pull/1532): Set 204 as default status for DELETE - [@LeFnord](https://github.com/LeFnord). + +#### Fixes + +* [#1505](https://github.com/ruby-grape/grape/pull/1505): Run `before` and `after` callbacks, but skip the rest when handling OPTIONS - [@jlfaber](https://github.com/jlfaber). +* [#1517](https://github.com/ruby-grape/grape/pull/1517), [#1089](https://github.com/ruby-grape/grape/pull/1089): Fix: priority of ANY routes - [@namusyaka](https://github.com/namusyaka), [@wagenet](https://github.com/wagenet). +* [#1512](https://github.com/ruby-grape/grape/pull/1512): Fix: deeply nested parameters are included within `#declared(params)` - [@krbs](https://github.com/krbs). +* [#1510](https://github.com/ruby-grape/grape/pull/1510): Fix: inconsistent validation for multiple parameters - [@dgasper](https://github.com/dgasper). +* [#1526](https://github.com/ruby-grape/grape/pull/1526): Reduced warnings caused by instance variables not initialized - [@cpetschnig](https://github.com/cpetschnig). + +### 0.18.0 (2016/10/7) + +#### Features + +* [#1480](https://github.com/ruby-grape/grape/pull/1480): Used the ruby-grape-danger gem for PR linting - [@dblock](https://github.com/dblock). +* [#1486](https://github.com/ruby-grape/grape/pull/1486): Implemented except in values validator - [@jonmchan](https://github.com/jonmchan). +* [#1470](https://github.com/ruby-grape/grape/pull/1470): Dropped support for Ruby 2.0 - [@namusyaka](https://github.com/namusyaka). +* [#1490](https://github.com/ruby-grape/grape/pull/1490): Switched to Ruby-2.x+ syntax - [@namusyaka](https://github.com/namusyaka). +* [#1499](https://github.com/ruby-grape/grape/pull/1499): Support `fail_fast` param validation option - [@dgasper](https://github.com/dgasper). + +#### Fixes + +* [#1498](https://github.com/ruby-grape/grape/pull/1498): Fix: skip validations in inactive given blocks - [@jlfaber](https://github.com/jlfaber). +* [#1479](https://github.com/ruby-grape/grape/pull/1479): Fix: support inserting middleware before/after anonymous classes in the middleware stack - [@rosa](https://github.com/rosa). +* [#1488](https://github.com/ruby-grape/grape/pull/1488): Fix: ensure calling before filters when receiving OPTIONS request - [@namusyaka](https://github.com/namusyaka), [@jlfaber](https://github.com/jlfaber). +* [#1493](https://github.com/ruby-grape/grape/pull/1493): Fix: coercion and lambda fails params validation - [@jonmchan](https://github.com/jonmchan). + +### 0.17.0 (2016/7/29) + +#### Features + +* [#1393](https://github.com/ruby-grape/grape/pull/1393): Middleware can be inserted before or after default Grape middleware - [@ridiculous](https://github.com/ridiculous). +* [#1390](https://github.com/ruby-grape/grape/pull/1390): Allowed inserting middleware at arbitrary points in the middleware stack - [@rosa](https://github.com/rosa). +* [#1366](https://github.com/ruby-grape/grape/pull/1366): Stored `message_key` on `Grape::Exceptions::Validation` - [@mkou](https://github.com/mkou). +* [#1398](https://github.com/ruby-grape/grape/pull/1398): Added `rescue_from :grape_exceptions` - allow Grape to use the built-in `Grape::Exception` handing and use `rescue :all` behavior for everything else - [@mmclead](https://github.com/mmclead). +* [#1443](https://github.com/ruby-grape/grape/pull/1443): Extended `given` to receive a `Proc` - [@glaucocustodio](https://github.com/glaucocustodio). +* [#1455](https://github.com/ruby-grape/grape/pull/1455): Added an automated PR linter - [@orta](https://github.com/orta). + +#### Fixes + +* [#1463](https://github.com/ruby-grape/grape/pull/1463): Fix array indicies in error messages - [@ffloyd](https://github.com/ffloyd). +* [#1465](https://github.com/ruby-grape/grape/pull/1465): Fix 'before' being called twice when using not allowed method - [@jsteinberg](https://github.com/jsteinberg). +* [#1446](https://github.com/ruby-grape/grape/pull/1446): Fix for `env` inside `before` when using not allowed method - [@leifg](https://github.com/leifg). +* [#1438](https://github.com/ruby-grape/grape/pull/1439): Try to dup non-frozen default params with each use - [@jlfaber](https://github.com/jlfaber). +* [#1430](https://github.com/ruby-grape/grape/pull/1430): Fix for `declared(params)` inside `route_param` - [@Arkanain](https://github.com/Arkanain). +* [#1405](https://github.com/ruby-grape/grape/pull/1405): Fix priority of `rescue_from` clauses applying - [@hedgesky](https://github.com/hedgesky). +* [#1365](https://github.com/ruby-grape/grape/pull/1365): Fix finding exception handler in error middleware - [@ktimothy](https://github.com/ktimothy). +* [#1380](https://github.com/ruby-grape/grape/pull/1380): Fix `allow_blank: false` for `Time` attributes with valid values causes `NoMethodError` - [@ipkes](https://github.com/ipkes). +* [#1384](https://github.com/ruby-grape/grape/pull/1384): Fix parameter validation with an empty optional nested `Array` - [@ipkes](https://github.com/ipkes). +* [#1414](https://github.com/ruby-grape/grape/pull/1414): Fix multiple version definitions for path versioning - [@304](https://github.com/304). +* [#1415](https://github.com/ruby-grape/grape/pull/1415): Fix `declared(params, include_parent_namespaces: false)` - [@304](https://github.com/304). +* [#1421](https://github.com/ruby-grape/grape/pull/1421): Avoid polluting `Grape::Middleware::Error` - [@namusyaka](https://github.com/namusyaka). +* [#1422](https://github.com/ruby-grape/grape/pull/1422): Concat parent declared params with current one - [@plukevdh](https://github.com/plukevdh), [@rnubel](https://github.com/rnubel), [@namusyaka](https://github.com/namusyaka). + +### 0.16.2 (2016/4/12) + +#### Features + +* [#1348](https://github.com/ruby-grape/grape/pull/1348): Fix global functions polluting Grape::API scope - [@dblock](https://github.com/dblock). +* [#1357](https://github.com/ruby-grape/grape/pull/1357): Expose Route#options - [@namusyaka](https://github.com/namusyaka). + +#### Fixes + +* [#1357](https://github.com/ruby-grape/grape/pull/1357): Don't include fixed named captures as route params - [@namusyaka](https://github.com/namusyaka). +* [#1359](https://github.com/ruby-grape/grape/pull/1359): Avoid evaluating the same route twice - [@namusyaka](https://github.com/namusyaka), [@dblock](https://github.com/dblock). +* [#1361](https://github.com/ruby-grape/grape/pull/1361): Return 405 correctly even if version is using as header and wrong request method - [@namusyaka](https://github.com/namusyaka), [@dblock](https://github.com/dblock). + +### 0.16.1 (2016/4/3) + +#### Features + +* [#1276](https://github.com/ruby-grape/grape/pull/1276): Replace rack-mount with new router - [@namusyaka](https://github.com/namusyaka). +* [#1321](https://github.com/ruby-grape/grape/pull/1321): Serve files without using FileStreamer-like object - [@lfidnl](https://github.com/lfidnl). +* [#1339](https://github.com/ruby-grape/grape/pull/1339): Implement Grape::API.recognize_path - [@namusyaka](https://github.com/namusyaka). + +#### Fixes + +* [#1325](https://github.com/ruby-grape/grape/pull/1325): Params: Fix coerce_with helper with Array types - [@ngonzalez](https://github.com/ngonzalez). +* [#1326](https://github.com/ruby-grape/grape/pull/1326): Fix wrong behavior for OPTIONS and HEAD requests with catch-all - [@ekampp](https://github.com/ekampp), [@namusyaka](https://github.com/namusyaka). +* [#1330](https://github.com/ruby-grape/grape/pull/1330): Add `register` keyword for adding customized parsers and formatters - [@namusyaka](https://github.com/namusyaka). +* [#1336](https://github.com/ruby-grape/grape/pull/1336): Do not modify Hash argument to `error!` - [@tjwp](https://github.com/tjwp). + +### 0.15.0 (2016/3/8) + +#### Features + +* [#1227](https://github.com/ruby-grape/grape/pull/1227): Store `message_key` on `Grape::Exceptions::Validation` - [@stjhimy](https://github.com/sthimy). +* [#1232](https://github.com/ruby-grape/grape/pull/1232): Helpers are now available inside `rescue_from` - [@namusyaka](https://github.com/namusyaka). +* [#1237](https://github.com/ruby-grape/grape/pull/1237): Allow multiple parameters in `given`, which behaves as if the scopes were nested in the inputted order - [@ochagata](https://github.com/ochagata). +* [#1238](https://github.com/ruby-grape/grape/pull/1238): Call `after` of middleware on error - [@namusyaka](https://github.com/namusyaka). +* [#1243](https://github.com/ruby-grape/grape/pull/1243): Add `header` support for middleware - [@namusyaka](https://github.com/namusyaka). +* [#1252](https://github.com/ruby-grape/grape/pull/1252): Allow default to be a subset or equal to allowed values without raising IncompatibleOptionValues - [@jeradphelps](https://github.com/jeradphelps). +* [#1255](https://github.com/ruby-grape/grape/pull/1255): Allow param type definition in `route_param` - [@namusyaka](https://github.com/namusyaka). +* [#1257](https://github.com/ruby-grape/grape/pull/1257): Allow Proc, Symbol or String in `rescue_from with: ...` - [@namusyaka](https://github.com/namusyaka). +* [#1280](https://github.com/ruby-grape/grape/pull/1280): Support `Rack::Sendfile` middleware - [@lfidnl](https://github.com/lfidnl). +* [#1285](https://github.com/ruby-grape/grape/pull/1285): Add a warning for errors appearing in `after` callbacks - [@gregormelhorn](https://github.com/gregormelhorn). +* [#1295](https://github.com/ruby-grape/grape/pull/1295): Add custom validation messages for parameter exceptions - [@railsmith](https://github.com/railsmith). + +#### Fixes + +* [#1216](https://github.com/ruby-grape/grape/pull/1142): Fix JSON error response when calling `error!` with non-Strings - [@jrforrest](https://github.com/jrforrest). +* [#1225](https://github.com/ruby-grape/grape/pull/1225): Fix `given` with nested params not returning correct declared params - [@JanStevens](https://github.com/JanStevens). +* [#1249](https://github.com/ruby-grape/grape/pull/1249): Don't fail even if invalid type value is passed to default validator - [@namusyaka](https://github.com/namusyaka). +* [#1266](https://github.com/ruby-grape/grape/pull/1266): Fix `Allow` header including `OPTIONS` when `do_not_route_options!` is active - [@arempe93](https://github.com/arempe93). +* [#1270](https://github.com/ruby-grape/grape/pull/1270): Fix `param` versioning with a custom parameter - [@wshatch](https://github.com/wshatch). +* [#1282](https://github.com/ruby-grape/grape/pull/1282): Fix specs circular dependency - [@304](https://github.com/304). +* [#1283](https://github.com/ruby-grape/grape/pull/1283): Fix 500 error for xml format when method is not allowed - [@304](https://github.com/304). +* [#1197](https://github.com/ruby-grape/grape/pull/1290): Fix using JSON and Array[JSON] as groups when parameter is optional - [@lukeivers](https://github.com/lukeivers). + +### 0.14.0 (2015/12/07) + +#### Features + +* [#1218](https://github.com/ruby-grape/grape/pull/1218): Provide array index context in errors - [@towanda](https://github.com/towanda). +* [#1196](https://github.com/ruby-grape/grape/pull/1196): Allow multiple `before_each` blocks - [@huynhquancam](https://github.com/huynhquancam). +* [#1190](https://github.com/ruby-grape/grape/pull/1190): Bypass formatting for statuses with no entity-body - [@tylerdooling](https://github.com/tylerdooling). +* [#1188](https://github.com/ruby-grape/grape/pull/1188): Allow parameters with more than one type - [@dslh](https://github.com/dslh). +* [#1179](https://github.com/ruby-grape/grape/pull/1179): Allow all RFC6838 valid characters in header vendor - [@suan](https://github.com/suan). +* [#1170](https://github.com/ruby-grape/grape/pull/1170): Allow dashes and periods in header vendor - [@suan](https://github.com/suan). +* [#1167](https://github.com/ruby-grape/grape/pull/1167): Convenience wrapper `type: File` for validating multipart file parameters - [@dslh](https://github.com/dslh). +* [#1167](https://github.com/ruby-grape/grape/pull/1167): Refactor and extend coercion and type validation system - [@dslh](https://github.com/dslh). +* [#1163](https://github.com/ruby-grape/grape/pull/1163): First-class `JSON` parameter type - [@dslh](https://github.com/dslh). +* [#1161](https://github.com/ruby-grape/grape/pull/1161): Custom parameter coercion using `coerce_with` - [@dslh](https://github.com/dslh). + +#### Fixes + +* [#1194](https://github.com/ruby-grape/grape/pull/1194): Redirect as plain text with message - [@tylerdooling](https://github.com/tylerdooling). +* [#1185](https://github.com/ruby-grape/grape/pull/1185): Use formatters for custom vendored content types - [@tylerdooling](https://github.com/tylerdooling). +* [#1156](https://github.com/ruby-grape/grape/pull/1156): Fixed `no implicit conversion of Symbol into Integer` with nested `values` validation - [@quickpay](https://github.com/quickpay). +* [#1153](https://github.com/ruby-grape/grape/pull/1153): Fixes boolean declaration in an external file - [@towanda](https://github.com/towanda). +* [#1142](https://github.com/ruby-grape/grape/pull/1142): Makes #declared unavailable to before filters - [@jrforrest](https://github.com/jrforrest). +* [#1114](https://github.com/ruby-grape/grape/pull/1114): Fix regression which broke identical endpoints with different versions - [@suan](https://github.com/suan). +* [#1109](https://github.com/ruby-grape/grape/pull/1109): Memoize Virtus attribute and fix memory leak - [@marshall-lee](https://github.com/marshall-lee). +* [#1101](https://github.com/ruby-grape/grape/pull/1101): Fix: Incorrect media-type `Accept` header now correctly returns 406 with `strict: true` - [@elliotlarson](https://github.com/elliotlarson). +* [#1108](https://github.com/ruby-grape/grape/pull/1039): Raise a warning when `desc` is called with options hash and block - [@rngtng](https://github.com/rngtng). + +### 0.13.0 (2015/8/10) + +#### Features + +* [#1039](https://github.com/ruby-grape/grape/pull/1039): Added support for custom parameter types - [@rnubel](https://github.com/rnubel). +* [#1047](https://github.com/ruby-grape/grape/pull/1047): Adds `given` to DSL::Parameters, allowing for dependent params - [@rnubel](https://github.com/rnubel). +* [#1064](https://github.com/ruby-grape/grape/pull/1064): Add public `Grape::Exception::ValidationErrors#full_messages` - [@romanlehnert](https://github.com/romanlehnert). +* [#1079](https://github.com/ruby-grape/grape/pull/1079): Added `stream` method to take advantage of `Rack::Chunked` - [@zbelzer](https://github.com/zbelzer). +* [#1086](https://github.com/ruby-grape/grape/pull/1086): Added `ActiveSupport::Notifications` instrumentation - [@wagenet](https://github.com/wagenet). + +#### Fixes + +* [#1062](https://github.com/ruby-grape/grape/issues/1062): Fix: `Grape::Exceptions::ValidationErrors` will include headers set by `header` - [@yairgo](https://github.com/yairgo). +* [#1038](https://github.com/ruby-grape/grape/pull/1038): Avoid dup-ing the `String` class when used in inherited params - [@rnubel](https://github.com/rnubel). +* [#1042](https://github.com/ruby-grape/grape/issues/1042): Fix coercion of complex arrays - [@dim](https://github.com/dim). +* [#1045](https://github.com/ruby-grape/grape/pull/1045): Do not convert `Rack::Response` to `Rack::Response` in middleware - [@dmitry](https://github.com/dmitry). +* [#1048](https://github.com/ruby-grape/grape/pull/1048): Only dup `InheritableValues`, remove support for `deep_dup` - [@toddmazierski](https://github.com/toddmazierski). +* [#1052](https://github.com/ruby-grape/grape/pull/1052): Reset `description[:params]` when resetting validations - [@marshall-lee](https://github.com/marshall-lee). +* [#1088](https://github.com/ruby-grape/grape/pull/1088): Support ActiveSupport 3.x by explicitly requiring `Hash#except` - [@wagenet](https://github.com/wagenet). +* [#1096](https://github.com/ruby-grape/grape/pull/1096): Fix coercion on booleans - [@towanda](https://github.com/towanda). + +### 0.12.0 (2015/6/18) + +#### Features + +* [#995](https://github.com/ruby-grape/grape/issues/995): Added support for coercion to Set or Set[Other] - [@jordansexton](https://github.com/jordansexton) [@u2](https://github.com/u2). +* [#980](https://github.com/ruby-grape/grape/issues/980): Grape is now eager-loaded - [@u2](https://github.com/u2). +* [#956](https://github.com/ruby-grape/grape/issues/956): Support `present` with `Grape::Presenters::Presenter` - [@u2](https://github.com/u2). +* [#974](https://github.com/ruby-grape/grape/pull/974): Added `error!` to `rescue_from` blocks - [@whatasunnyday](https://github.com/whatasunnyday). +* [#950](https://github.com/ruby-grape/grape/pull/950): Status method can now accept one of Rack::Utils status code symbols (:ok, :found, :bad_request, etc.) - [@dabrorius](https://github.com/dabrorius). +* [#952](https://github.com/ruby-grape/grape/pull/952): Status method now raises error when called with invalid status code - [@dabrorius](https://github.com/dabrorius). +* [#957](https://github.com/ruby-grape/grape/pull/957): Regexp validator now supports `allow_blank`, `nil` value behavior changed - [@calfzhou](https://github.com/calfzhou). +* [#962](https://github.com/ruby-grape/grape/pull/962): The `default` attribute with `false` value is documented now - [@ajvondrak](https://github.com/ajvondrak). +* [#1026](https://github.com/ruby-grape/grape/pull/1026): Added `file` method, explicitly setting a file-like response object - [@dblock](https://github.com/dblock). + +#### Fixes + +* [#994](https://github.com/ruby-grape/grape/pull/994): Fixed optional Array params default to Hash - [@u2](https://github.com/u2). +* [#988](https://github.com/ruby-grape/grape/pull/988): Fixed duplicate identical endpoints - [@u2](https://github.com/u2). +* [#936](https://github.com/ruby-grape/grape/pull/936): Fixed default params processing for optional groups - [@dm1try](https://github.com/dm1try). +* [#942](https://github.com/ruby-grape/grape/pull/942): Fixed forced presence for optional params when based on a reused entity that was also required in another context - [@croeck](https://github.com/croeck). +* [#1001](https://github.com/ruby-grape/grape/pull/1001): Fixed calling endpoint with specified format with format in its path - [@hodak](https://github.com/hodak). +* [#1005](https://github.com/ruby-grape/grape/pull/1005): Fixed the Grape::Middleware::Globals - [@urkle](https://github.com/urkle). +* [#1012](https://github.com/ruby-grape/grape/pull/1012): Fixed `allow_blank: false` with a Boolean value of `false` - [@mfunaro](https://github.com/mfunaro). +* [#1023](https://github.com/ruby-grape/grape/issues/1023): Fixes unexpected behavior with `present` and an object that responds to `merge` but isn't a Hash - [@dblock](https://github.com/dblock). +* [#1017](https://github.com/ruby-grape/grape/pull/1017): Fixed `undefined method stringify_keys` with nested mutual exclusive params - [@quickpay](https://github.com/quickpay). + +### 0.11.0 (2015/2/23) + +* [#925](https://github.com/ruby-grape/grape/pull/925): Fixed `toplevel constant DateTime referenced by Virtus::Attribute::DateTime` - [@u2](https://github.com/u2). +* [#916](https://github.com/ruby-grape/grape/pull/916): Added `DateTime/Date/Numeric/Boolean` type support `allow_blank` - [@u2](https://github.com/u2). +* [#871](https://github.com/ruby-grape/grape/pull/871): Fixed `Grape::Middleware::Base#response` - [@galathius](https://github.com/galathius). +* [#559](https://github.com/ruby-grape/grape/issues/559): Added support for Rack 1.6.0, which parses requests larger than 128KB - [@myitcv](https://github.com/myitcv). +* [#876](https://github.com/ruby-grape/grape/pull/876): Call to `declared(params)` now returns a `Hashie::Mash` - [@rodzyn](https://github.com/rodzyn). +* [#879](https://github.com/ruby-grape/grape/pull/879): The `route_info` value is no longer included in `params` Hash - [@rodzyn](https://github.com/rodzyn). +* [#881](https://github.com/ruby-grape/grape/issues/881): Fixed `Grape::Validations::ValuesValidator` support for `Range` type - [@ajvondrak](https://github.com/ajvondrak). +* [#901](https://github.com/ruby-grape/grape/pull/901): Fix: callbacks defined in a version block are only called for the routes defined in that block - [@kushkella](https://github.com/kushkella). +* [#886](https://github.com/ruby-grape/grape/pull/886): Group of parameters made to require an explicit type of Hash or Array - [@jrichter1](https://github.com/jrichter1). +* [#912](https://github.com/ruby-grape/grape/pull/912): Extended the `:using` feature for param documentation to `optional` fields - [@croeck](https://github.com/croeck). +* [#906](https://github.com/ruby-grape/grape/pull/906): Fix: invalid body parse errors are not rescued by handlers - [@croeck](https://github.com/croeck). +* [#913](https://github.com/ruby-grape/grape/pull/913): Fix: Invalid accept headers are not processed by rescue handlers - [@croeck](https://github.com/croeck). +* [#913](https://github.com/ruby-grape/grape/pull/913): Fix: Invalid accept headers cause internal processing errors (500) when http_codes are defined - [@croeck](https://github.com/croeck). +* [#917](https://github.com/ruby-grape/grape/pull/917): Use HTTPS for rubygems.org - [@O-I](https://github.com/O-I). + +### 0.10.1 (2014/12/28) + +* [#868](https://github.com/ruby-grape/grape/pull/868), [#862](https://github.com/ruby-grape/grape/pull/862), [#861](https://github.com/ruby-grape/grape/pull/861): Fixed `version`, `prefix`, and other settings being overridden or changing scope when mounting API - [@yesmeck](https://github.com/yesmeck). +* [#864](https://github.com/ruby-grape/grape/pull/864): Fixed `declared(params, include_missing: false)` now returning attributes with `nil` and `false` values - [@ppadron](https://github.com/ppadron). + +### 0.10.0 (2014/12/19) + +* [#803](https://github.com/ruby-grape/grape/pull/803), [#820](https://github.com/ruby-grape/grape/pull/820): Added `all_or_none_of` parameter validator - [@loveltyoic](https://github.com/loveltyoic), [@natecj](https://github.com/natecj). +* [#774](https://github.com/ruby-grape/grape/pull/774): Extended `mutually_exclusive`, `exactly_one_of`, `at_least_one_of` to work inside any kind of group: `requires` or `optional`, `Hash` or `Array` - [@ShPakvel](https://github.com/ShPakvel). +* [#743](https://github.com/ruby-grape/grape/pull/743): Added `allow_blank` parameter validator to validate non-empty strings - [@elado](https://github.com/elado). +* [#745](https://github.com/ruby-grape/grape/pull/745): Removed `atom+xml`, `rss+xml`, and `jsonapi` content-types - [@akabraham](https://github.com/akabraham). +* [#745](https://github.com/ruby-grape/grape/pull/745): Added `:binary, application/octet-stream` content-type - [@akabraham](https://github.com/akabraham). +* [#757](https://github.com/ruby-grape/grape/pull/757): Changed `desc` can now be used with a block syntax - [@dspaeth-faber](https://github.com/dspaeth-faber). +* [#779](https://github.com/ruby-grape/grape/pull/779): Fixed using `values` with a `default` proc - [@ShPakvel](https://github.com/ShPakvel). +* [#799](https://github.com/ruby-grape/grape/pull/799): Fixed custom validators with required `Hash`, `Array` types - [@bwalex](https://github.com/bwalex). +* [#784](https://github.com/ruby-grape/grape/pull/784): Fixed `present` to not overwrite the previously added contents of the response body whebn called more than once - [@mfunaro](https://github.com/mfunaro). +* [#809](https://github.com/ruby-grape/grape/pull/809): Removed automatic `(.:format)` suffix on paths if you're using only one format (e.g., with `format :json`, `/path` will respond with JSON but `/path.xml` will be a 404) - [@ajvondrak](https://github.com/ajvondrak). +* [#816](https://github.com/ruby-grape/grape/pull/816): Added ability to filter out missing params if params is a nested hash with `declared(params, include_missing: false)` - [@georgimitev](https://github.com/georgimitev). +* [#819](https://github.com/ruby-grape/grape/pull/819): Allowed both `desc` and `description` in the params DSL - [@mzikherman](https://github.com/mzikherman). +* [#821](https://github.com/ruby-grape/grape/pull/821): Fixed passing string value when hash is expected in params - [@rebelact](https://github.com/rebelact). +* [#824](https://github.com/ruby-grape/grape/pull/824): Validate array params against list of acceptable values - [@dnd](https://github.com/dnd). +* [#813](https://github.com/ruby-grape/grape/pull/813): Routing methods dsl refactored to get rid of explicit `paths` parameter - [@AlexYankee](https://github.com/AlexYankee). +* [#826](https://github.com/ruby-grape/grape/pull/826): Find `coerce_type` for `Array` when not specified - [@manovotn](https://github.com/manovotn). +* [#645](https://github.com/ruby-grape/grape/issues/645): Invoking `body false` will return `204 No Content` - [@dblock](https://github.com/dblock). +* [#801](https://github.com/ruby-grape/grape/issues/801): Only evaluate permitted parameter `values` and `default` lazily on each request when declared as a proc - [@dblock](https://github.com/dblock). +* [#679](https://github.com/ruby-grape/grape/issues/679): Fixed `OPTIONS` method returning 404 when combined with `prefix` - [@dblock](https://github.com/dblock). +* [#679](https://github.com/ruby-grape/grape/issues/679): Fixed unsupported methods returning 404 instead of 405 when combined with `prefix` - [@dblock](https://github.com/dblock). + +### 0.9.0 (2014/8/27) + +#### Features + +* [#691](https://github.com/ruby-grape/grape/issues/691): Added `at_least_one_of` parameter validator - [@dblock](https://github.com/dblock). +* [#698](https://github.com/ruby-grape/grape/pull/698): `error!` sets `status` for `Endpoint` too - [@dspaeth-faber](https://github.com/dspaeth-faber). +* [#703](https://github.com/ruby-grape/grape/pull/703): Added support for Auth-Middleware extension - [@dspaeth-faber](https://github.com/dspaeth-faber). +* [#703](https://github.com/ruby-grape/grape/pull/703): Removed `Grape::Middleware::Auth::Basic` - [@dspaeth-faber](https://github.com/dspaeth-faber). +* [#703](https://github.com/ruby-grape/grape/pull/703): Removed `Grape::Middleware::Auth::Digest` - [@dspaeth-faber](https://github.com/dspaeth-faber). +* [#703](https://github.com/ruby-grape/grape/pull/703): Removed `Grape::Middleware::Auth::OAuth2` - [@dspaeth-faber](https://github.com/dspaeth-faber). +* [#719](https://github.com/ruby-grape/grape/pull/719): Allow passing options hash to a custom validator - [@elado](https://github.com/elado). +* [#716](https://github.com/ruby-grape/grape/pull/716): Calling `content-type` will now return the current content-type - [@dblock](https://github.com/dblock). +* [#705](https://github.com/ruby-grape/grape/pull/705): Errors can now be presented with a `Grape::Entity` class - [@dspaeth-faber](https://github.com/dspaeth-faber). + +#### Fixes + +* [#687](https://github.com/ruby-grape/grape/pull/687): Fix: `mutually_exclusive` and `exactly_one_of` validation error messages now label parameters as strings, consistently with `requires` and `optional` - [@dblock](https://github.com/dblock). + +### 0.8.0 (2014/7/10) + +#### Features + +* [#639](https://github.com/ruby-grape/grape/pull/639): Added support for blocks with reusable params - [@mibon](https://github.com/mibon). +* [#637](https://github.com/ruby-grape/grape/pull/637): Added support for `exactly_one_of` parameter validation - [@Morred](https://github.com/Morred). +* [#626](https://github.com/ruby-grape/grape/pull/626): Added support for `mutually_exclusive` parameters - [@oliverbarnes](https://github.com/oliverbarnes). +* [#617](https://github.com/ruby-grape/grape/pull/617): Running tests on Ruby 2.1.1, Rubinius 2.1 and 2.2, Ruby and JRuby HEAD - [@dblock](https://github.com/dblock). +* [#397](https://github.com/ruby-grape/grape/pull/397): Adds `Grape::Endpoint.before_each` to allow easy helper stubbing - [@mbleigh](https://github.com/mbleigh). +* [#673](https://github.com/ruby-grape/grape/pull/673): Avoid requiring non-existent fields when using Grape::Entity documentation - [@qqshfox](https://github.com/qqshfox). + +#### Fixes + +* [#671](https://github.com/ruby-grape/grape/pull/671): Allow required param with predefined set of values to be nil inside optional group - [@dm1try](https://github.com/dm1try). +* [#651](https://github.com/ruby-grape/grape/pull/651): The `rescue_from` keyword now properly defaults to rescuing subclasses of exceptions - [@xevix](https://github.com/xevix). +* [#614](https://github.com/ruby-grape/grape/pull/614): Params with `nil` value are now refused by `RegexpValidator` - [@dm1try](https://github.com/dm1try). +* [#494](https://github.com/ruby-grape/grape/issues/494): Fixed performance issue with requests carrying a large payload - [@dblock](https://github.com/dblock). +* [#619](https://github.com/ruby-grape/grape/pull/619): Convert specs to RSpec 3 syntax with Transpec - [@danielspector](https://github.com/danielspector). +* [#632](https://github.com/ruby-grape/grape/pull/632): `Grape::Endpoint#present` causes ActiveRecord to make an extra query during entity's detection - [@fixme](https://github.com/fixme). + +### 0.7.0 (2014/4/2) + +#### Features + +* [#558](https://github.com/ruby-grape/grape/pull/558): Support lambda-based values for params - [@wpschallenger](https://github.com/wpschallenger). +* [#510](https://github.com/ruby-grape/grape/pull/510): Support lambda-based default values for params - [@myitcv](https://github.com/myitcv). +* [#511](https://github.com/ruby-grape/grape/pull/511): Added `required` option for OAuth2 middleware - [@bcm](https://github.com/bcm). +* [#520](https://github.com/ruby-grape/grape/pull/520): Use `default_error_status` to specify the default status code returned from `error!` - [@salimane](https://github.com/salimane). +* [#525](https://github.com/ruby-grape/grape/pull/525): The default status code returned from `error!` has been changed from 403 to 500 - [@dblock](https://github.com/dblock). +* [#526](https://github.com/ruby-grape/grape/pull/526): Allowed specifying headers in `error!` - [@dblock](https://github.com/dblock). +* [#527](https://github.com/ruby-grape/grape/pull/527): The `before_validation` callback is now a distinct one - [@myitcv](https://github.com/myitcv). +* [#530](https://github.com/ruby-grape/grape/pull/530): Added ability to restrict `declared(params)` to the local endpoint with `include_parent_namespaces: false` - [@myitcv](https://github.com/myitcv). +* [#531](https://github.com/ruby-grape/grape/pull/531): Helpers are now available to auth middleware, executing in the context of the endpoint - [@joelvh](https://github.com/joelvh). +* [#540](https://github.com/ruby-grape/grape/pull/540): Ruby 2.1.0 is now supported - [@salimane](https://github.com/salimane). +* [#544](https://github.com/ruby-grape/grape/pull/544): The `rescue_from` keyword now handles subclasses of exceptions by default - [@xevix](https://github.com/xevix). +* [#545](https://github.com/ruby-grape/grape/pull/545): Added `type` (`Array` or `Hash`) support to `requires`, `optional` and `group` - [@bwalex](https://github.com/bwalex). +* [#550](https://github.com/ruby-grape/grape/pull/550): Added possibility to define reusable params - [@dm1try](https://github.com/dm1try). +* [#560](https://github.com/ruby-grape/grape/pull/560): Use `Grape::Entity` documentation to define required and optional parameters with `requires using:` - [@reynardmh](https://github.com/reynardmh). +* [#572](https://github.com/ruby-grape/grape/pull/572): Added `documentation` support to `requires`, `optional` and `group` parameters - [@johnallen3d](https://github.com/johnallen3d). + +#### Fixes + +* [#600](https://github.com/ruby-grape/grape/pull/600): Don't use an `Entity` constant that is available in the namespace as presenter - [@fuksito](https://github.com/fuksito). +* [#590](https://github.com/ruby-grape/grape/pull/590): Fix issue where endpoint param of type `Integer` cannot set values array - [@xevix](https://github.com/xevix). +* [#586](https://github.com/ruby-grape/grape/pull/586): Do not repeat the same validation error messages - [@kiela](https://github.com/kiela). +* [#508](https://github.com/ruby-grape/grape/pull/508): Allow parameters, such as content encoding, in `content_type` - [@dm1try](https://github.com/dm1try). +* [#492](https://github.com/ruby-grape/grape/pull/492): Don't allow to have nil value when a param is required and has a list of allowed values - [@Antti](https://github.com/Antti). +* [#495](https://github.com/ruby-grape/grape/pull/495): Fixed `ParamsScope#params` for parameters nested inside arrays - [@asross](https://github.com/asross). +* [#498](https://github.com/ruby-grape/grape/pull/498): Dry'ed up options and headers logic, allow headers to be passed to OPTIONS requests - [@karlfreeman](https://github.com/karlfreeman). +* [#500](https://github.com/ruby-grape/grape/pull/500): Skip entity auto-detection when explicitly passed - [@yaneq](https://github.com/yaneq). +* [#503](https://github.com/ruby-grape/grape/pull/503): Calling declared(params) from child namespace fails to include parent namespace defined params - [@myitcv](https://github.com/myitcv). +* [#512](https://github.com/ruby-grape/grape/pull/512): Don't create `Grape::Request` multiple times - [@dblock](https://github.com/dblock). +* [#538](https://github.com/ruby-grape/grape/pull/538): Fixed default values for grouped params - [@dm1try](https://github.com/dm1try). +* [#549](https://github.com/ruby-grape/grape/pull/549): Fixed handling of invalid version headers to return 406 if a header cannot be parsed - [@bwalex](https://github.com/bwalex). +* [#557](https://github.com/ruby-grape/grape/pull/557): Pass `content_types` option to `Grape::Middleware::Error` to fix the content-type header for custom formats - [@bernd](https://github.com/bernd). +* [#585](https://github.com/ruby-grape/grape/pull/585): Fix after boot thread-safety issue - [@etehtsea](https://github.com/etehtsea). +* [#587](https://github.com/ruby-grape/grape/pull/587): Fix oauth2 middleware compatibility with [draft-ietf-oauth-v2-31](http://tools.ietf.org/html/draft-ietf-oauth-v2-31) spec - [@etehtsea](https://github.com/etehtsea). +* [#610](https://github.com/ruby-grape/grape/pull/610): Fixed group keyword was not working with type parameter - [@klausmeyer](https://github.com/klausmeyer). + +### 0.6.1 (2013/10/19) + +#### Features + +* [#475](https://github.com/ruby-grape/grape/pull/475): Added support for the `:jsonapi`, `application/vnd.api+json` media type registered at http://jsonapi.org - [@bcm](https://github.com/bcm). +* [#471](https://github.com/ruby-grape/grape/issues/471): Added parameter validator for a list of allowed values - [@vickychijwani](https://github.com/vickychijwani). +* [#488](https://github.com/ruby-grape/grape/issues/488): Upgraded to Virtus 1.0 - [@dblock](https://github.com/dblock). + +#### Fixes + +* [#477](https://github.com/ruby-grape/grape/pull/477): Fixed `default_error_formatter` which takes a format symbol - [@vad4msiu](https://github.com/vad4msiu). + +#### Development + +* Implemented Rubocop, a Ruby code static code analyzer - [@dblock](https://github.com/dblock). + +### 0.6.0 (2013/9/16) + +#### Features + +* Grape is no longer tested against Ruby 1.8.7 - [@dblock](https://github.com/dblock). +* [#442](https://github.com/ruby-grape/grape/issues/442): Enable incrementally building on top of a previous API version - [@dblock](https://github.com/dblock). +* [#442](https://github.com/ruby-grape/grape/issues/442): API `version` can now take an array of multiple versions - [@dblock](https://github.com/dblock). +* [#444](https://github.com/ruby-grape/grape/issues/444): Added `:en` as fallback locale for I18n - [@aew](https://github.com/aew). +* [#448](https://github.com/ruby-grape/grape/pull/448): Adding POST style parameters for DELETE requests - [@dquimper](https://github.com/dquimper). +* [#450](https://github.com/ruby-grape/grape/pull/450): Added option to pass an exception handler lambda as an argument to `rescue_from` - [@robertopedroso](https://github.com/robertopedroso). +* [#443](https://github.com/ruby-grape/grape/pull/443): Let `requires` and `optional` take blocks that initialize new scopes - [@asross](https://github.com/asross). +* [#452](https://github.com/ruby-grape/grape/pull/452): Added `with` as a hash option to specify handlers for `rescue_from` and `error_formatter` - [@robertopedroso](https://github.com/robertopedroso). +* [#433](https://github.com/ruby-grape/grape/issues/433), [#462](https://github.com/ruby-grape/grape/issues/462): Validation errors are now collected and `Grape::Exceptions::ValidationErrors` is raised - [@stevschmid](https://github.com/stevschmid). + +#### Fixes + +* [#428](https://github.com/ruby-grape/grape/issues/428): Removes memoization from `Grape::Request` params to prevent middleware from freezing parameter values before `Formatter` can get them - [@mbleigh](https://github.com/mbleigh). + +### 0.5.0 (2013/6/14) + +#### Features + +* [#344](https://github.com/ruby-grape/grape/pull/344): Added `parser :type, nil` which disables input parsing for a given content-type - [@dblock](https://github.com/dblock). +* [#381](https://github.com/ruby-grape/grape/issues/381): Added `cascade false` option at API level to remove the `X-Cascade: true` header from the API response - [@dblock](https://github.com/dblock). +* [#392](https://github.com/ruby-grape/grape/pull/392): Extracted headers and params from `Endpoint` to `Grape::Request` - [@niedhui](https://github.com/niedhui). +* [#376](https://github.com/ruby-grape/grape/pull/376): Added `route_param`, syntax sugar for quick declaration of route parameters - [@mbleigh](https://github.com/mbleigh). +* [#390](https://github.com/ruby-grape/grape/pull/390): Added default value for an `optional` parameter - [@oivoodoo](https://github.com/oivoodoo). +* [#403](https://github.com/ruby-grape/grape/pull/403): Added support for versioning using the `Accept-Version` header - [@politician](https://github.com/politician). +* [#407](https://github.com/ruby-grape/grape/issues/407): Specifying `default_format` will also set the default POST/PUT data parser to the given format - [@dblock](https://github.com/dblock). +* [#241](https://github.com/ruby-grape/grape/issues/241): Present with multiple entities using an optional Symbol - [@niedhui](https://github.com/niedhui). + +#### Fixes + +* [#378](https://github.com/ruby-grape/grape/pull/378): Fix: stop rescuing all exceptions during formatting - [@kbarrette](https://github.com/kbarrette). +* [#380](https://github.com/ruby-grape/grape/pull/380): Fix: `Formatter#read_body_input` when transfer encoding is chunked - [@paulnicholon](https://github.com/paulnicholson). +* [#347](https://github.com/ruby-grape/grape/issues/347): Fix: handling non-hash body params - [@paulnicholon](https://github.com/paulnicholson). +* [#394](https://github.com/ruby-grape/grape/pull/394): Fix: path version no longer overwrites a `version` parameter - [@tmornini](https://github.com/tmornini). +* [#412](https://github.com/ruby-grape/grape/issues/412): Fix: specifying `content_type` will also override the selection of the data formatter - [@dblock](https://github.com/dblock). +* [#383](https://github.com/ruby-grape/grape/issues/383): Fix: Mounted APIs aren't inheriting settings (including `before` and `after` filters) - [@seanmoon](https://github.com/seanmoon). +* [#408](https://github.com/ruby-grape/grape/pull/408): Fix: Goliath passes request header keys as symbols not strings - [@bobek](https://github.com/bobek). +* [#417](https://github.com/ruby-grape/grape/issues/417): Fix: Rails 4 does not rewind input, causes POSTed data to be empty - [@dblock](https://github.com/dblock). +* [#423](https://github.com/ruby-grape/grape/pull/423): Fix: `Grape::Endpoint#declared` now correctly handles nested params (ie. declared with `group`) - [@jbarreneche](https://github.com/jbarreneche). +* [#427](https://github.com/ruby-grape/grape/issues/427): Fix: `declared(params)` breaks when `params` contains array - [@timhabermaas](https://github.com/timhabermaas). + +### 0.4.1 (2013/4/1) + +* [#375](https://github.com/ruby-grape/grape/pull/375): Fix: throwing an `:error` inside a middleware doesn't respect the `format` settings - [@dblock](https://github.com/dblock). + +### 0.4.0 (2013/3/17) + +* [#356](https://github.com/ruby-grape/grape/pull/356): Fix: presenting collections other than `Array` (eg. `ActiveRecord::Relation`) - [@zimbatm](https://github.com/zimbatm). +* [#352](https://github.com/ruby-grape/grape/pull/352): Fix: using `Rack::JSONP` with `Grape::Entity` responses - [@deckchair](https://github.com/deckchair). +* [#347](https://github.com/ruby-grape/grape/issues/347): Grape will accept any valid JSON as PUT or POST, including strings, symbols and arrays - [@qqshfox](https://github.com/qqshfox), [@dblock](https://github.com/dblock). +* [#347](https://github.com/ruby-grape/grape/issues/347): JSON format APIs always return valid JSON, eg. strings are now returned as `"string"` and no longer `string` - [@dblock](https://github.com/dblock). +* Raw body input from POST and PUT requests (`env['rack.input'].read`) is now available in `api.request.input` - [@dblock](https://github.com/dblock). +* Parsed body input from POST and PUT requests is now available in `api.request.body` - [@dblock](https://github.com/dblock). +* [#343](https://github.com/ruby-grape/grape/pull/343): Fix: return `Content-Type: text/plain` with error 405 - [@gustavosaume](https://github.com/gustavosaume), [@wyattisimo](https://github.com/wyattisimo). +* [#357](https://github.com/ruby-grape/grape/pull/357): Grape now requires Rack 1.3.0 or newer - [@jhecking](https://github.com/jhecking). +* [#320](https://github.com/ruby-grape/grape/issues/320): API `namespace` now supports `requirements` - [@niedhui](https://github.com/niedhui). +* [#353](https://github.com/ruby-grape/grape/issues/353): Revert to standard Ruby logger formatter, `require active_support/all` if you want old behavior - [@rhunter](https://github.com/rhunter), [@dblock](https://github.com/dblock). +* Fix: `undefined method 'call' for nil:NilClass` for an API method implementation without a block, now returns an empty string - [@dblock](https://github.com/dblock). + +### 0.3.2 (2013/2/28) + +* [#355](https://github.com/ruby-grape/grape/issues/355): Relax dependency constraint on Hashie - [@reset](https://github.com/reset). + +### 0.3.1 (2013/2/25) + +* [#351](https://github.com/ruby-grape/grape/issues/351): Compatibility with Ruby 2.0 - [@mbleigh](https://github.com/mbleigh). + +### 0.3.0 (2013/02/21) + +* [#294](https://github.com/ruby-grape/grape/issues/294): Extracted `Grape::Entity` into a [grape-entity](https://github.com/agileanimal/grape-entity) gem - [@agileanimal](https://github.com/agileanimal). +* [#340](https://github.com/ruby-grape/grape/pull/339), [#342](https://github.com/ruby-grape/grape/pull/342): Added `:cascade` option to `version` to allow disabling of rack/mount cascade behavior - [@dieb](https://github.com/dieb). +* [#333](https://github.com/ruby-grape/grape/pull/333): Added support for validation of arrays in `params` - [@flyerhzm](https://github.com/flyerhzm). +* [#306](https://github.com/ruby-grape/grape/issues/306): Added I18n support for all Grape exceptions - [@niedhui](https://github.com/niedhui). +* [#309](https://github.com/ruby-grape/grape/pull/309): Added XML support to the entity presenter - [@johnnyiller](https://github.com/johnnyiller), [@dblock](https://github.com/dblock). +* [#131](https://github.com/ruby-grape/grape/issues/131): Added instructions for Grape API reloading in Rails - [@jyn](https://github.com/jyn), [@dblock](https://github.com/dblock). +* [#317](https://github.com/ruby-grape/grape/issues/317): Added `headers` that returns a hash of parsed HTTP request headers - [@dblock](https://github.com/dblock). +* [#332](https://github.com/ruby-grape/grape/pull/332): `Grape::Exceptions::Validation` now contains full nested parameter names - [@alovak](https://github.com/alovak). +* [#328](https://github.com/ruby-grape/grape/issues/328): API version can now be specified as both String and Symbol - [@dblock](https://github.com/dblock). +* [#190](https://github.com/ruby-grape/grape/issues/190): When you add a `GET` route for a resource, a route for the `HEAD` method will also be added automatically. You can disable this behavior with `do_not_route_head!` - [@dblock](https://github.com/dblock). +* Added `do_not_route_options!`, which disables the automatic creation of the `OPTIONS` route - [@dblock](https://github.com/dblock). +* [#309](https://github.com/ruby-grape/grape/pull/309): An XML format API will return an error instead of returning a string representation of the response if the latter cannot be converted to XML - [@dblock](https://github.com/dblock). +* A formatter that raises an exception will cause the API to return a 500 error - [@dblock](https://github.com/dblock). +* [#322](https://github.com/ruby-grape/grape/issues/322): When returning a 406 status, Grape will include the requested format or content-type in the response body - [@dblock](https://github.com/dblock). +* [#60](https://github.com/ruby-grape/grape/issues/60): Fix: mounting of a Grape API onto a path - [@dblock](https://github.com/dblock). +* [#335](https://github.com/ruby-grape/grape/pull/335): Fix: request body parameters from a `PATCH` request not available in `params` - [@FreakenK](https://github.com/FreakenK). + +### 0.2.6 (2013/01/11) + +* Fix: support content-type with character set when parsing POST and PUT input - [@dblock](https://github.com/dblock). +* Fix: CVE-2013-0175, multi_xml parse vulnerability, require multi_xml 0.5.2 - [@dblock](https://github.com/dblock). + +### 0.2.5 (2013/01/10) + +* Added support for custom parsers via `parser`, in addition to built-in multipart, JSON and XML parsers - [@dblock](https://github.com/dblock). +* Removed `body_params`, data sent via a POST or PUT with a supported content-type is merged into `params` - [@dblock](https://github.com/dblock). +* Setting `format` will automatically remove other content-types by calling `content_type` - [@dblock](https://github.com/dblock). +* Setting `content_type` will prevent any input data other than the matching content-type or any Rack-supported form and parseable media types (`application/x-www-form-urlencoded`, `multipart/form-data`, `multipart/related` and `multipart/mixed`) from being parsed - [@dblock](https://github.com/dblock). +* [#305](https://github.com/ruby-grape/grape/issues/305): Fix: presenting arrays of objects via `represent` or when auto-detecting an `Entity` constant in the objects being presented - [@brandonweiss](https://github.com/brandonweiss). +* [#306](https://github.com/ruby-grape/grape/issues/306): Added i18n support for validation error messages - [@niedhui](https://github.com/niedhui). + +### 0.2.4 (2013/01/06) + +* [#297](https://github.com/ruby-grape/grape/issues/297): Added `default_error_formatter` - [@dblock](https://github.com/dblock). +* [#297](https://github.com/ruby-grape/grape/issues/297): Setting `format` will automatically set `default_error_formatter` - [@dblock](https://github.com/dblock). +* [#295](https://github.com/ruby-grape/grape/issues/295): Storing original API source block in endpoint's `source` attribute - [@dblock](https://github.com/dblock). +* [#293](https://github.com/ruby-grape/grape/pull/293): Added options to `cookies.delete`, enables passing a path - [@inst](https://github.com/inst). +* [#174](https://github.com/ruby-grape/grape/issues/174): The value of `env['PATH_INFO']` is no longer altered with `path` versioning - [@dblock](https://github.com/dblock). +* [#296](https://github.com/ruby-grape/grape/issues/296): Fix: ArgumentError with default error formatter - [@dblock](https://github.com/dblock). +* [#298](https://github.com/ruby-grape/grape/pull/298): Fix: subsequent calls to `body_params` would fail due to IO read - [@justinmcp](https://github.com/justinmcp). +* [#301](https://github.com/ruby-grape/grape/issues/301): Fix: symbol memory leak in cookie and formatter middleware - [@dblock](https://github.com/dblock). +* [#300](https://github.com/ruby-grape/grape/issues/300): Fix `Grape::API.routes` to include mounted api routes - [@aiwilliams](https://github.com/aiwilliams). +* [#302](https://github.com/ruby-grape/grape/pull/302): Fix: removed redundant `autoload` entries - [@ugisozols](https://github.com/ugisozols). +* [#172](https://github.com/ruby-grape/grape/issues/172): Fix: MultiJson deprecated methods warnings - [@dblock](https://github.com/dblock). +* [#133](https://github.com/ruby-grape/grape/issues/133): Fix: header-based versioning with use of `prefix` - [@seanmoon](https://github.com/seanmoon), [@dblock](https://github.com/dblock). +* [#280](https://github.com/ruby-grape/grape/issues/280): Fix: grouped parameters mangled in `route_params` hash - [@marcusg](https://github.com/marcusg), [@dblock](https://github.com/dblock). +* [#304](https://github.com/ruby-grape/grape/issues/304): Fix: `present x, :with => Entity` returns class references with `format :json` - [@dblock](https://github.com/dblock). +* [#196](https://github.com/ruby-grape/grape/issues/196): Fix: root requests don't work with `prefix` - [@dblock](https://github.com/dblock). + +### 0.2.3 (2012/12/24) + +* [#179](https://github.com/ruby-grape/grape/issues/178): Using `content_type` will remove all default content-types - [@dblock](https://github.com/dblock). +* [#265](https://github.com/ruby-grape/grape/issues/264): Fix: Moved `ValidationError` into `Grape::Exceptions` - [@thepumpkin1979](https://github.com/thepumpkin1979). +* [#269](https://github.com/ruby-grape/grape/pull/269): Fix: `LocalJumpError` will not be raised when using explict return in API methods - [@simulacre](https://github.com/simulacre). +* [#86](https://github.com/ruby-grape/grape/issues/275): Fix Path-based versioning not recognizing `/` route - [@walski](https://github.com/walski). +* [#273](https://github.com/ruby-grape/grape/pull/273): Disabled formatting via `serializable_hash` and added support for `format :serializable_hash` - [@dblock](https://github.com/dblock). +* [#277](https://github.com/ruby-grape/grape/pull/277): Added a DSL to declare `formatter` in API settings - [@tim-vandecasteele](https://github.com/tim-vandecasteele). +* [#284](https://github.com/ruby-grape/grape/pull/284): Added a DSL to declare `error_formatter` in API settings - [@dblock](https://github.com/dblock). +* [#285](https://github.com/ruby-grape/grape/pull/285): Removed `error_format` from API settings, now matches request format - [@dblock](https://github.com/dblock). +* [#290](https://github.com/ruby-grape/grape/pull/290): The default error format for XML is now `error/message` instead of `hash/error` - [@dpsk](https://github.com/dpsk). +* [#44](https://github.com/ruby-grape/grape/issues/44): Pass `env` into formatters to enable templating - [@dblock](https://github.com/dblock). + +### 0.2.2 (2012/12/10) + +#### Features + +* [#201](https://github.com/ruby-grape/grape/pull/201), [#236](https://github.com/ruby-grape/grape/pull/236), [#221](https://github.com/ruby-grape/grape/pull/221): Added coercion and validations support to `params` DSL - [@schmurfy](https://github.com/schmurfy), [@tim-vandecasteele](https://github.com/tim-vandecasteele), [@adamgotterer](https://github.com/adamgotterer). +* [#204](https://github.com/ruby-grape/grape/pull/204): Added ability to declare shared `params` at `namespace` level - [@tim-vandecasteele](https://github.com/tim-vandecasteele). +* [#234](https://github.com/ruby-grape/grape/pull/234): Added a DSL for creating entities via mixin - [@mbleigh](https://github.com/mbleigh). +* [#240](https://github.com/ruby-grape/grape/pull/240): Define API response format from a query string `format` parameter, if specified - [@neetiraj](https://github.com/neetiraj). +* Adds Endpoint#declared to easily filter out unexpected params - [@mbleigh](https://github.com/mbleigh). + +#### Fixes + +* [#248](https://github.com/ruby-grape/grape/pull/248): Fix: API `version` returns last version set - [@narkoz](https://github.com/narkoz). +* [#242](https://github.com/ruby-grape/grape/issues/242): Fix: permanent redirect status should be `301`, was `304` - [@adamgotterer](https://github.com/adamgotterer). +* [#211](https://github.com/ruby-grape/grape/pull/211): Fix: custom validations are no longer triggered when optional and parameter is not present - [@adamgotterer](https://github.com/adamgotterer). +* [#210](https://github.com/ruby-grape/grape/pull/210): Fix: `Endpoint#body_params` causing undefined method 'size' - [@adamgotterer](https://github.com/adamgotterer). +* [#205](https://github.com/ruby-grape/grape/pull/205): Fix: Corrected parsing of empty JSON body on POST/PUT - [@tim-vandecasteele](https://github.com/tim-vandecasteele). +* [#181](https://github.com/ruby-grape/grape/pull/181): Fix: Corrected JSON serialization of nested hashes containing `Grape::Entity` instances - [@benrosenblum](https://github.com/benrosenblum). +* [#203](https://github.com/ruby-grape/grape/pull/203): Added a check to `Entity#serializable_hash` that verifies an entity exists on an object - [@adamgotterer](https://github.com/adamgotterer). +* [#208](https://github.com/ruby-grape/grape/pull/208): `Entity#serializable_hash` must also check if attribute is generated by a user supplied block - [@ppadron](https://github.com/ppadron). +* [#252](https://github.com/ruby-grape/grape/pull/252): Resources that don't respond to a requested HTTP method return 405 (Method Not Allowed) instead of 404 (Not Found) - [@simulacre](https://github.com/simulacre). + +### 0.2.1 (2012/7/11) + +* [#186](https://github.com/ruby-grape/grape/issues/186): Fix: helpers allow multiple calls with modules and blocks - [@ppadron](https://github.com/ppadron). +* [#188](https://github.com/ruby-grape/grape/pull/188): Fix: multi-method routes append '(.:format)' only once - [@kainosnoema](https://github.com/kainosnoema). +* [#64](https://github.com/ruby-grape/grape/issues/64), [#180](https://github.com/ruby-grape/grape/pull/180): Added support to `GET` request bodies as parameters - [@bobbytables](https://github.com/bobbytables). +* [#175](https://github.com/ruby-grape/grape/pull/175): Added support for API versioning based on a request parameter - [@jackcasey](https://github.com/jackcasey). +* [#168](https://github.com/ruby-grape/grape/pull/168): Fix: Formatter can parse symbol keys in the headers hash - [@netmask](https://github.com/netmask). +* [#169](https://github.com/ruby-grape/grape/pull/169): Silence multi_json deprecation warnings - [@whiteley](https://github.com/whiteley). +* [#166](https://github.com/ruby-grape/grape/pull/166): Added support for `redirect`, including permanent and temporary - [@allenwei](https://github.com/allenwei). +* [#159](https://github.com/ruby-grape/grape/pull/159): Added `:requirements` to routes, allowing to use reserved characters in paths - [@gaiottino](https://github.com/gaiottino). +* [#156](https://github.com/ruby-grape/grape/pull/156): Added support for adding formatters to entities - [@bobbytables](https://github.com/bobbytables). +* [#183](https://github.com/ruby-grape/grape/pull/183): Added ability to include documentation in entities - [@flah00](https://github.com/flah00). +* [#189](https://github.com/ruby-grape/grape/pull/189): `HEAD` requests no longer return a body - [@stephencelis](https://github.com/stephencelis). +* [#97](https://github.com/ruby-grape/grape/issues/97): Allow overriding `Content-Type` - [@dblock](https://github.com/dblock). + +### 0.2.0 (2012/3/28) + +* Added support for inheriting exposures from entities - [@bobbytables](https://github.com/bobbytables). +* Extended formatting with `default_format` - [@dblock](https://github.com/dblock). +* Added support for cookies - [@lukaszsliwa](https://github.com/lukaszsliwa). +* Added support for declaring additional content-types - [@joeyAghion](https://github.com/joeyAghion). +* Added support for HTTP PATCH - [@LTe](https://github.com/LTe). +* Added support for describing, documenting and reflecting APIs - [@dblock](https://github.com/dblock). +* Added support for anchoring and vendoring - [@jwkoelewijn](https://github.com/jwkoelewijn). +* Added support for HTTP OPTIONS - [@grimen](https://github.com/grimen). +* Added support for silencing logger - [@evansj](https://github.com/evansj). +* Added support for helper modules - [@freelancing-god](https://github.com/freelancing-god). +* Added support for Accept header-based versioning - [@jch](https://github.com/jch), [@rodzyn](https://github.com/rodzyn). +* Added support for mounting APIs and other Rack applications within APIs - [@mbleigh](https://github.com/mbleigh). +* Added entities, multiple object representations - [@mbleigh](https://github.com/mbleigh). +* Added ability to handle XML in the incoming request body - [@jwillis](https://github.com/jwillis). +* Added support for a configurable logger - [@mbleigh](https://github.com/mbleigh). +* Added support for before and after filters - [@mbleigh](https://github.com/mbleigh). +* Extended `rescue_from`, which can now take a block - [@dblock](https://github.com/dblock). + +### 0.1.5 (2011/6/14) + +* Extended exception handling to all exceptions - [@dblock](https://github.com/dblock). +* Added support for returning JSON objects from within error blocks - [@dblock](https://github.com/dblock). +* Added support for handling incoming JSON in body - [@tedkulp](https://github.com/tedkulp). +* Added support for HTTP digest authentication - [@daddz](https://github.com/daddz). + +### 0.1.4 (2011/4/8) + +* Allow multiple definitions of the same endpoint under multiple versions - [@chrisrhoden](https://github.com/chrisrhoden). +* Added support for multipart URL parameters - [@mcastilho](https://github.com/mcastilho). +* Added support for custom formatters - [@spraints](https://github.com/spraints). + +### 0.1.3 (2011/1/10) + +* Added support for JSON format in route matching - [@aiwilliams](https://github.com/aiwilliams). +* Added suport for custom middleware - [@mbleigh](https://github.com/mbleigh). + +### 0.1.1 (2010/11/14) + +* Endpoints properly reset between each request - [@mbleigh](https://github.com/mbleigh). + +### 0.1.0 (2010/11/13) + +* Initial public release - [@mbleigh](https://github.com/mbleigh). diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/CONTRIBUTING.md b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/CONTRIBUTING.md new file mode 100644 index 00000000..084f9122 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/CONTRIBUTING.md @@ -0,0 +1,156 @@ +Contributing to Grape +===================== + +Grape is work of [hundreds of contributors](https://github.com/ruby-grape/grape/graphs/contributors). You're encouraged to submit [pull requests](https://github.com/ruby-grape/grape/pulls), [propose features and discuss issues](https://github.com/ruby-grape/grape/issues). When in doubt, ask a question in the [Grape Google Group](http://groups.google.com/group/ruby-grape). + +#### Fork the Project + +Fork the [project on Github](https://github.com/ruby-grape/grape) and check out your copy. + +``` +git clone https://github.com/contributor/grape.git +cd grape +git remote add upstream https://github.com/ruby-grape/grape.git +``` + +#### Create a Topic Branch + +Make sure your fork is up-to-date and create a topic branch for your feature or bug fix. + +``` +git checkout master +git pull upstream master +git checkout -b my-feature-branch +``` + +### Docker + +If you're familiar with [Docker](https://www.docker.com/), you can run everything through the following command: + +``` +docker-compose run --rm --build grape +``` + +About the execution process: + - displays Ruby, Rubygems, Bundle and Gemfile version when starting: + ``` + ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux-musl] + rubygems 3.4.12 + Bundler version 2.4.1 (2022-12-24 commit f3175f033c) + Running default Gemfile + ``` + - keeps the gems to the latest possible version + - executes under `bundle exec` + +Here are some examples: + +- running all specs `docker-compose run --rm --build grape rspec` +- running rspec on a specific file `docker-compose run --rm --build grape rspec spec/:file_path` +- running task `docker-compose run --rm --build grape rake ` +- running rubocop `docker-compose run --rm --build grape rubocop` +- running all specs on a specific ruby version (e.g 2.7.7) `RUBY_VERSION=2.7.7 docker-compose run --rm --build grape rspec` +- running specs on a specific gemfile (e.g rails_7_0.gemfile) `docker-compose run -e GEMFILE=rails_7_0 --rm --build grape rspec` + +#### Bundle Install and Test + +Ensure that you can build the project and run tests. + +``` +bundle install +bundle exec rake +``` + +Run tests against all supported versions of Rails. + +``` +gem install appraisal +appraisal install +appraisal rake spec +``` + +#### Write Tests + +Try to write a test that reproduces the problem you're trying to fix or describes a feature that you want to build. Add to [spec/grape](spec/grape). + +We definitely appreciate pull requests that highlight or reproduce a problem, even without a fix. + +#### Write Code + +Implement your feature or bug fix. + +Ruby style is enforced with [Rubocop](https://github.com/bbatsov/rubocop), run `bundle exec rubocop` and fix any style issues highlighted. + +Make sure that `bundle exec rake` completes without errors. + +#### Write Documentation + +Document any external behavior in the [README](README.md). + +You should also document code as necessary, using current code as examples. This project uses [YARD](https://yardoc.org/). You can run and preview the docs locally by [installing `yard`](https://yardoc.org/), running `yard server --reload` and view the docs at http://localhost:8808. + +#### Update Changelog + +Add a line to [CHANGELOG](CHANGELOG.md) under *Next Release*. Make it look like every other line, including your name and link to your Github account. + +#### Commit Changes + +Make sure git knows your name and email address: + +``` +git config --global user.name "Your Name" +git config --global user.email "contributor@example.com" +``` + +Writing good commit logs is important. A commit log should describe what changed and why. + +``` +git add ... +git commit +``` + +#### Push + +``` +git push origin my-feature-branch +``` + +#### Make a Pull Request + +Go to https://github.com/contributor/grape and select your feature branch. Click the 'Pull Request' button and fill out the form. Pull requests are usually reviewed within a few days. + +#### Rebase + +If you've been working on a change for a while, rebase with upstream/master. + +``` +git fetch upstream +git rebase upstream/master +git push origin my-feature-branch -f +``` + +#### Update CHANGELOG Again + +Update the [CHANGELOG](CHANGELOG.md) with the pull request number. A typical entry looks as follows. + +``` +* [#123](https://github.com/ruby-grape/grape/pull/123): Reticulated splines - [@contributor](https://github.com/contributor). +``` + +Amend your previous commit and force push the changes. + +``` +git commit --amend +git push origin my-feature-branch -f +``` + +#### Check on Your Pull Request + +Go back to your pull request after a few minutes and see whether it passed muster with CI. Everything should look green, otherwise fix issues and amend your commit as described above. + +#### Be Patient + +It's likely that your change will not be merged and that the nitpicky maintainers will ask you to do more, or fix seemingly benign problems. Hang in there! + +#### Thank You + +Please do know that we really appreciate and value your time and work. We love you, really. diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/LICENSE b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/LICENSE new file mode 100644 index 00000000..e689bdce --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2010-2020 Michael Bleigh, Intridea Inc. and Contributors. + +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 AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/README.md b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/README.md new file mode 100644 index 00000000..76be9280 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/README.md @@ -0,0 +1,4170 @@ +![grape logo](grape.png) + +[![Gem Version](https://badge.fury.io/rb/grape.svg)](http://badge.fury.io/rb/grape) +[![Build Status](https://github.com/ruby-grape/grape/workflows/test/badge.svg?branch=master)](https://github.com/ruby-grape/grape/actions) +[![Code Climate](https://codeclimate.com/github/ruby-grape/grape.svg)](https://codeclimate.com/github/ruby-grape/grape) +[![Coverage Status](https://coveralls.io/repos/github/ruby-grape/grape/badge.svg?branch=master)](https://coveralls.io/github/ruby-grape/grape?branch=master) +[![Inline docs](https://inch-ci.org/github/ruby-grape/grape.svg)](https://inch-ci.org/github/ruby-grape/grape) +[![Join the chat at https://gitter.im/ruby-grape/grape](https://badges.gitter.im/ruby-grape/grape.svg)](https://gitter.im/ruby-grape/grape?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + +## Table of Contents + +- [What is Grape?](#what-is-grape) +- [Stable Release](#stable-release) +- [Project Resources](#project-resources) +- [Grape for Enterprise](#grape-for-enterprise) +- [Installation](#installation) +- [Basic Usage](#basic-usage) +- [Rails 7.1](#rails-71) +- [Mounting](#mounting) + - [All](#all) + - [Rack](#rack) + - [Alongside Sinatra (or other frameworks)](#alongside-sinatra-or-other-frameworks) + - [Rails](#rails) + - [Zeitwerk](#zeitwerk) + - [Modules](#modules) +- [Remounting](#remounting) + - [Mount Configuration](#mount-configuration) +- [Versioning](#versioning) + - [Strategies](#strategies) + - [Path](#path) + - [Header](#header) + - [Accept-Version Header](#accept-version-header) + - [Param](#param) +- [Describing Methods](#describing-methods) +- [Configuration](#configuration) +- [Parameters](#parameters) + - [Params Class](#params-class) + - [Declared](#declared) + - [Include Parent Namespaces](#include-parent-namespaces) + - [Include Missing](#include-missing) + - [Evaluate Given](#evaluate-given) + - [Parameter Precedence](#parameter-precedence) +- [Parameter Validation and Coercion](#parameter-validation-and-coercion) + - [Supported Parameter Types](#supported-parameter-types) + - [Integer/Fixnum and Coercions](#integerfixnum-and-coercions) + - [Custom Types and Coercions](#custom-types-and-coercions) + - [Multipart File Parameters](#multipart-file-parameters) + - [First-Class JSON Types](#first-class-json-types) + - [Multiple Allowed Types](#multiple-allowed-types) + - [Validation of Nested Parameters](#validation-of-nested-parameters) + - [Dependent Parameters](#dependent-parameters) + - [Group Options](#group-options) + - [Renaming](#renaming) + - [Built-in Validators](#built-in-validators) + - [allow_blank](#allow_blank) + - [values](#values) + - [except_values](#except_values) + - [same_as](#same_as) + - [length](#length) + - [regexp](#regexp) + - [mutually_exclusive](#mutually_exclusive) + - [exactly_one_of](#exactly_one_of) + - [at_least_one_of](#at_least_one_of) + - [all_or_none_of](#all_or_none_of) + - [Nested mutually_exclusive, exactly_one_of, at_least_one_of, all_or_none_of](#nested-mutually_exclusive-exactly_one_of-at_least_one_of-all_or_none_of) + - [Namespace Validation and Coercion](#namespace-validation-and-coercion) + - [Custom Validators](#custom-validators) + - [Validation Errors](#validation-errors) + - [I18n](#i18n) + - [Custom Validation messages](#custom-validation-messages) + - [presence, allow_blank, values, regexp](#presence-allow_blank-values-regexp) + - [same_as](#same_as-1) + - [length](#length-1) + - [all_or_none_of](#all_or_none_of-1) + - [mutually_exclusive](#mutually_exclusive-1) + - [exactly_one_of](#exactly_one_of-1) + - [at_least_one_of](#at_least_one_of-1) + - [Coerce](#coerce) + - [With Lambdas](#with-lambdas) + - [Pass symbols for i18n translations](#pass-symbols-for-i18n-translations) + - [Overriding Attribute Names](#overriding-attribute-names) + - [With Default](#with-default) + - [Using dry-validation or dry-schema](#using-dry-validation-or-dry-schema) +- [Headers](#headers) + - [Request](#request) + - [Header Case Handling](#header-case-handling) + - [Response](#response) +- [Routes](#routes) +- [Helpers](#helpers) +- [Path Helpers](#path-helpers) +- [Parameter Documentation](#parameter-documentation) +- [Cookies](#cookies) +- [HTTP Status Code](#http-status-code) +- [Redirecting](#redirecting) +- [Recognizing Path](#recognizing-path) +- [Allowed Methods](#allowed-methods) +- [Raising Exceptions](#raising-exceptions) + - [Default Error HTTP Status Code](#default-error-http-status-code) + - [Handling 404](#handling-404) +- [Exception Handling](#exception-handling) + - [Rescuing exceptions inside namespaces](#rescuing-exceptions-inside-namespaces) + - [Unrescuable Exceptions](#unrescuable-exceptions) + - [Exceptions that should be rescued explicitly](#exceptions-that-should-be-rescued-explicitly) +- [Logging](#logging) +- [API Formats](#api-formats) + - [JSONP](#jsonp) + - [CORS](#cors) +- [Content-type](#content-type) +- [API Data Formats](#api-data-formats) +- [JSON and XML Processors](#json-and-xml-processors) +- [RESTful Model Representations](#restful-model-representations) + - [Grape Entities](#grape-entities) + - [Hypermedia and Roar](#hypermedia-and-roar) + - [Rabl](#rabl) + - [Active Model Serializers](#active-model-serializers) +- [Sending Raw or No Data](#sending-raw-or-no-data) +- [Authentication](#authentication) + - [Basic Auth](#basic-auth) + - [Register custom middleware for authentication](#register-custom-middleware-for-authentication) +- [Describing and Inspecting an API](#describing-and-inspecting-an-api) +- [Current Route and Endpoint](#current-route-and-endpoint) +- [Before, After and Finally](#before-after-and-finally) +- [Anchoring](#anchoring) +- [Instance Variables](#instance-variables) +- [Using Custom Middleware](#using-custom-middleware) + - [Grape Middleware](#grape-middleware) + - [Rails Middleware](#rails-middleware) + - [Remote IP](#remote-ip) +- [Writing Tests](#writing-tests) + - [Writing Tests with Rack](#writing-tests-with-rack) + - [RSpec](#rspec) + - [Airborne](#airborne) + - [MiniTest](#minitest) + - [Writing Tests with Rails](#writing-tests-with-rails) + - [RSpec](#rspec-1) + - [MiniTest](#minitest-1) + - [Stubbing Helpers](#stubbing-helpers) +- [Reloading API Changes in Development](#reloading-api-changes-in-development) + - [Reloading in Rack Applications](#reloading-in-rack-applications) + - [Reloading in Rails Applications](#reloading-in-rails-applications) +- [Performance Monitoring](#performance-monitoring) + - [Active Support Instrumentation](#active-support-instrumentation) + - [endpoint_run.grape](#endpoint_rungrape) + - [endpoint_render.grape](#endpoint_rendergrape) + - [endpoint_run_filters.grape](#endpoint_run_filtersgrape) + - [endpoint_run_validators.grape](#endpoint_run_validatorsgrape) + - [format_response.grape](#format_responsegrape) + - [Monitoring Products](#monitoring-products) +- [Contributing to Grape](#contributing-to-grape) +- [Security](#security) +- [License](#license) +- [Copyright](#copyright) + +## What is Grape? + +Grape is a REST-like API framework for Ruby. It's designed to run on Rack or complement existing web application frameworks such as Rails and Sinatra by providing a simple DSL to easily develop RESTful APIs. It has built-in support for common conventions, including multiple formats, subdomain/prefix restriction, content negotiation, versioning and much more. + +## Stable Release + +You're reading the documentation for the next release of Grape, 2.3.0. +Please read [UPGRADING](UPGRADING.md) when upgrading from a previous version. + +## Project Resources + +* [Grape Website](http://www.ruby-grape.org) +* [Documentation](http://www.rubydoc.info/gems/grape) +* Need help? Try [Grape Google Group](http://groups.google.com/group/ruby-grape) or [Gitter](https://gitter.im/ruby-grape/grape) +* [Follow us on Twitter](https://twitter.com/grapeframework) + +## Grape for Enterprise + +Available as part of the Tidelift Subscription. + +The maintainers of Grape are working with Tidelift to deliver commercial support and maintenance. Save time, reduce risk, and improve code health, while paying the maintainers of Grape. Click [here](https://tidelift.com/subscription/request-a-demo?utm_source=rubygems-grape&utm_medium=referral&utm_campaign=enterprise) for more details. + +## Installation + +Ruby 2.7 or newer is required. + +Grape is available as a gem, to install it run: + + bundle add grape + +## Basic Usage + +Grape APIs are Rack applications that are created by subclassing `Grape::API`. +Below is a simple example showing some of the more common features of Grape in the context of recreating parts of the Twitter API. + +```ruby +module Twitter + class API < Grape::API + version 'v1', using: :header, vendor: 'twitter' + format :json + prefix :api + + helpers do + def current_user + @current_user ||= User.authorize!(env) + end + + def authenticate! + error!('401 Unauthorized', 401) unless current_user + end + end + + resource :statuses do + desc 'Return a public timeline.' + get :public_timeline do + Status.limit(20) + end + + desc 'Return a personal timeline.' + get :home_timeline do + authenticate! + current_user.statuses.limit(20) + end + + desc 'Return a status.' + params do + requires :id, type: Integer, desc: 'Status ID.' + end + route_param :id do + get do + Status.find(params[:id]) + end + end + + desc 'Create a status.' + params do + requires :status, type: String, desc: 'Your status.' + end + post do + authenticate! + Status.create!({ + user: current_user, + text: params[:status] + }) + end + + desc 'Update a status.' + params do + requires :id, type: String, desc: 'Status ID.' + requires :status, type: String, desc: 'Your status.' + end + put ':id' do + authenticate! + current_user.statuses.find(params[:id]).update({ + user: current_user, + text: params[:status] + }) + end + + desc 'Delete a status.' + params do + requires :id, type: String, desc: 'Status ID.' + end + delete ':id' do + authenticate! + current_user.statuses.find(params[:id]).destroy + end + end + end +end +``` + +## Rails 7.1 + +Grape's [deprecator](https://api.rubyonrails.org/v7.1.0/classes/ActiveSupport/Deprecation.html) will be added to your application's deprecators [automatically](lib/grape/railtie.rb) as `:grape`, so that your application's configuration can be applied to it. + +## Mounting + +### All + + +By default Grape will compile the routes on the first route, it is possible to pre-load routes using the `compile!` method. + +```ruby +Twitter::API.compile! +``` + +This can be added to your `config.ru` (if using rackup), `application.rb` (if using rails), or any file that loads your server. + +### Rack + +The above sample creates a Rack application that can be run from a rackup `config.ru` file with `rackup`: + +```ruby +run Twitter::API +``` + +(With pre-loading you can use) + +```ruby +Twitter::API.compile! +run Twitter::API +``` + +And would respond to the following routes: + + GET /api/statuses/public_timeline + GET /api/statuses/home_timeline + GET /api/statuses/:id + POST /api/statuses + PUT /api/statuses/:id + DELETE /api/statuses/:id + +Grape will also automatically respond to HEAD and OPTIONS for all GET, and just OPTIONS for all other routes. + +### Alongside Sinatra (or other frameworks) + +If you wish to mount Grape alongside another Rack framework such as Sinatra, you can do so easily using `Rack::Cascade`: + +```ruby +# Example config.ru + +require 'sinatra' +require 'grape' + +class API < Grape::API + get :hello do + { hello: 'world' } + end +end + +class Web < Sinatra::Base + get '/' do + 'Hello world.' + end +end + +use Rack::Session::Cookie +run Rack::Cascade.new [Web, API] +``` + +Note that order of loading apps using `Rack::Cascade` matters. The grape application must be last if you want to raise custom 404 errors from grape (such as `error!('Not Found',404)`). If the grape application is not last and returns 404 or 405 response, [cascade utilizes that as a signal to try the next app](https://www.rubydoc.info/gems/rack/Rack/Cascade). This may lead to undesirable behavior showing the [wrong 404 page from the wrong app](https://github.com/ruby-grape/grape/issues/1515). + + +### Rails + +Place API files into `app/api`. Rails expects a subdirectory that matches the name of the Ruby module and a file name that matches the name of the class. In our example, the file name location and directory for `Twitter::API` should be `app/api/twitter/api.rb`. + +Modify `config/routes`: + +```ruby +mount Twitter::API => '/' +``` +#### Zeitwerk +Rails's default autoloader is `Zeitwerk`. By default, it inflects `api` as `Api` instead of `API`. To make our example work, you need to uncomment the lines at the bottom of `config/initializers/inflections.rb`, and add `API` as an acronym: + +```ruby +ActiveSupport::Inflector.inflections(:en) do |inflect| + inflect.acronym 'API' +end +``` + +### Modules + +You can mount multiple API implementations inside another one. These don't have to be different versions, but may be components of the same API. + +```ruby +class Twitter::API < Grape::API + mount Twitter::APIv1 + mount Twitter::APIv2 +end +``` + +You can also mount on a path, which is similar to using `prefix` inside the mounted API itself. + +```ruby +class Twitter::API < Grape::API + mount Twitter::APIv1 => '/v1' +end +``` + +Declarations as `before/after/rescue_from` can be placed before or after `mount`. In any case they will be inherited. + +```ruby +class Twitter::API < Grape::API + before do + header 'X-Base-Header', 'will be defined for all APIs that are mounted below' + end + + rescue_from :all do + error!({ "error" => "Internal Server Error" }, 500) + end + + mount Twitter::Users + mount Twitter::Search + + after do + clean_cache! + end + + rescue_from ZeroDivisionError do + error!({ "error" => "Not found" }, 404) + end +end +``` + +## Remounting + +You can mount the same endpoints in two different locations. + +```ruby +class Voting::API < Grape::API + namespace 'votes' do + get do + # Your logic + end + + post do + # Your logic + end + end +end + +class Post::API < Grape::API + mount Voting::API +end + +class Comment::API < Grape::API + mount Voting::API +end +``` + +Assuming that the post and comment endpoints are mounted in `/posts` and `/comments`, you should now be able to do `get /posts/votes`, `post /posts/votes`, `get /comments/votes` and `post /comments/votes`. + +### Mount Configuration + +You can configure remountable endpoints to change how they behave according to where they are mounted. + +```ruby +class Voting::API < Grape::API + namespace 'votes' do + desc "Vote for your #{configuration[:votable]}" + get do + # Your logic + end + end +end + +class Post::API < Grape::API + mount Voting::API, with: { votable: 'posts' } +end + +class Comment::API < Grape::API + mount Voting::API, with: { votable: 'comments' } +end +``` + +Note that if you're passing a hash as the first parameter to `mount`, you will need to explicitly put `()` around parameters: +```ruby +# good +mount({ ::Some::Api => '/some/api' }, with: { condition: true }) + +# bad +mount ::Some::Api => '/some/api', with: { condition: true } +``` + +You can access `configuration` on the class (to use as dynamic attributes), inside blocks (like namespace) + +If you want logic happening given on an `configuration`, you can use the helper `given`. + +```ruby +class ConditionalEndpoint::API < Grape::API + given configuration[:some_setting] do + get 'mount_this_endpoint_conditionally' do + configuration[:configurable_response] + end + end +end +``` + +If you want a block of logic running every time an endpoint is mounted (within which you can access the `configuration` Hash) + + +```ruby +class ConditionalEndpoint::API < Grape::API + mounted do + YourLogger.info "This API was mounted at: #{Time.now}" + + get configuration[:endpoint_name] do + configuration[:configurable_response] + end + end +end +``` + +More complex results can be achieved by using `mounted` as an expression within which the `configuration` is already evaluated as a Hash. + +```ruby +class ExpressionEndpointAPI < Grape::API + get(mounted { configuration[:route_name] || 'default_name' }) do + # some logic + end +end +``` + +```ruby +class BasicAPI < Grape::API + desc 'Statuses index' do + params: (configuration[:entity] || API::Entities::Status).documentation + end + params do + requires :all, using: (configuration[:entity] || API::Entities::Status).documentation + end + get '/statuses' do + statuses = Status.all + type = current_user.admin? ? :full : :default + present statuses, with: (configuration[:entity] || API::Entities::Status), type: type + end +end + +class V1 < Grape::API + version 'v1' + mount BasicAPI, with: { entity: mounted { configuration[:entity] || API::Entities::Status } } +end + +class V2 < Grape::API + version 'v2' + mount BasicAPI, with: { entity: mounted { configuration[:entity] || API::Entities::V2::Status } } +end +``` + +## Versioning + +You have the option to provide various versions of your API by establishing a separate `Grape::API` class for each offered version and then integrating them into a primary `Grape::API` class. Ensure that newer versions are mounted before older ones. The default approach to versioning directs the request to the subsequent Rack middleware if a specific version is not found. + +```ruby +require 'v1' +require 'v2' +require 'v3' +class App < Grape::API + mount V3 + mount V2 + mount V1 +end +``` + +To maintain the same endpoints from earlier API versions without rewriting them, you can indicate multiple versions within the previous API versions. + +```ruby +class V1 < Grape::API + version 'v1', 'v2', 'v3' + + get '/foo' do + # your code for GET /foo + end + + get '/other' do + # your code for GET /other + end +end + +class V2 < Grape::API + version 'v2', 'v3' + + get '/var' do + # your code for GET /var + end +end + +class V3 < Grape::API + version 'v3' + + get '/foo' do + # your new code for GET /foo + end +end +``` + +Using the example provided, the subsequent endpoints will be accessible across various versions: + +```shell +GET /v1/foo +GET /v1/other +GET /v2/foo # => Same behavior as v1 +GET /v2/other # => Same behavior as v1 +GET /v2/var # => New endpoint not available in v1 +GET /v3/foo # => Different behavior to v1 and v2 +GET /v3/other # => Same behavior as v1 and v2 +GET /v3/var # => Same behavior as v2 +``` + +There are four strategies in which clients can reach your API's endpoints: `:path`, `:header`, `:accept_version_header` and `:param`. The default strategy is `:path`. + +### Strategies + +#### Path + +```ruby +version 'v1', using: :path +``` + +Using this versioning strategy, clients should pass the desired version in the URL. + + curl http://localhost:9292/v1/statuses/public_timeline + +#### Header + +```ruby +version 'v1', using: :header, vendor: 'twitter' +``` + +Currently, Grape only supports versioned media types in the following format: + +``` +vnd.vendor-and-or-resource-v1234+format +``` + +Basically all tokens between the final `-` and the `+` will be interpreted as the version. + +Using this versioning strategy, clients should pass the desired version in the HTTP `Accept` head. + + curl -H Accept:application/vnd.twitter-v1+json http://localhost:9292/statuses/public_timeline + +By default, the first matching version is used when no `Accept` header is supplied. This behavior is similar to routing in Rails. To circumvent this default behavior, one could use the `:strict` option. When this option is set to `true`, a `406 Not Acceptable` error is returned when no correct `Accept` header is supplied. + +When an invalid `Accept` header is supplied, a `406 Not Acceptable` error is returned if the `:cascade` option is set to `false`. Otherwise a `404 Not Found` error is returned by Rack if no other route matches. + +Grape will evaluate the relative quality preference included in Accept headers and default to a quality of 1.0 when omitted. In the following example a Grape API that supports XML and JSON in that order will return JSON: + + curl -H "Accept: text/xml;q=0.8, application/json;q=0.9" localhost:1234/resource + +#### Accept-Version Header + +```ruby +version 'v1', using: :accept_version_header +``` + +Using this versioning strategy, clients should pass the desired version in the HTTP `Accept-Version` header. + + curl -H "Accept-Version:v1" http://localhost:9292/statuses/public_timeline + +By default, the first matching version is used when no `Accept-Version` header is supplied. This behavior is similar to routing in Rails. To circumvent this default behavior, one could use the `:strict` option. When this option is set to `true`, a `406 Not Acceptable` error is returned when no correct `Accept` header is supplied and the `:cascade` option is set to `false`. Otherwise a `404 Not Found` error is returned by Rack if no other route matches. + +#### Param + +```ruby +version 'v1', using: :param +``` + +Using this versioning strategy, clients should pass the desired version as a request parameter, either in the URL query string or in the request body. + + curl http://localhost:9292/statuses/public_timeline?apiver=v1 + +The default name for the query parameter is 'apiver' but can be specified using the `:parameter` option. + +```ruby +version 'v1', using: :param, parameter: 'v' +``` + + curl http://localhost:9292/statuses/public_timeline?v=v1 + + +## Describing Methods + +You can add a description to API methods and namespaces. The description would be used by [grape-swagger][grape-swagger] to generate swagger compliant documentation. + +Note: Description block is only for documentation and won't affects API behavior. + +```ruby +desc 'Returns your public timeline.' do + summary 'summary' + detail 'more details' + params API::Entities::Status.documentation + success API::Entities::Entity + failure [[401, 'Unauthorized', 'Entities::Error']] + default { code: 500, message: 'InvalidRequest', model: Entities::Error } + named 'My named route' + headers XAuthToken: { + description: 'Validates your identity', + required: true + }, + XOptionalHeader: { + description: 'Not really needed', + required: false + } + hidden false + deprecated false + is_array true + nickname 'nickname' + produces ['application/json'] + consumes ['application/json'] + tags ['tag1', 'tag2'] +end +get :public_timeline do + Status.limit(20) +end +``` + +* `detail`: A more enhanced description +* `params`: Define parameters directly from an `Entity` +* `success`: (former entity) The `Entity` to be used to present the success response for this route. +* `failure`: (former http_codes) A definition of the used failure HTTP Codes and Entities. +* `default`: The definition and `Entity` used to present the default response for this route. +* `named`: A helper to give a route a name and find it with this name in the documentation Hash +* `headers`: A definition of the used Headers +* Other options can be found in [grape-swagger][grape-swagger] + +[grape-swagger]: https://github.com/ruby-grape/grape-swagger + +## Configuration + +Use `Grape.configure` to set up global settings at load time. +Currently the configurable settings are: + +* `param_builder`: Sets the [Parameter Builder](#parameters), defaults to `Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder`. + +To change a setting value make sure that at some point during load time the following code runs + +```ruby +Grape.configure do |config| + config.setting = value +end +``` + +For example, for the `param_builder`, the following code could run in an initializer: + +```ruby +Grape.configure do |config| + config.param_builder = Grape::Extensions::Hashie::Mash::ParamBuilder +end +``` + +You can also configure a single API: + +```ruby +API.configure do |config| + config[key] = value +end +``` + +This will be available inside the API with `configuration`, as if it were [mount configuration](#mount-configuration). + +## Parameters + +Request parameters are available through the `params` hash object. This includes `GET`, `POST` and `PUT` parameters, along with any named parameters you specify in your route strings. + +```ruby +get :public_timeline do + Status.order(params[:sort_by]) +end +``` + +Parameters are automatically populated from the request body on `POST` and `PUT` for form input, JSON and XML content-types. + +The request: + +``` +curl -d '{"text": "140 characters"}' 'http://localhost:9292/statuses' -H Content-Type:application/json -v +``` + +The Grape endpoint: + +```ruby +post '/statuses' do + Status.create!(text: params[:text]) +end +``` + +Multipart POSTs and PUTs are supported as well. + +The request: + +``` +curl --form image_file='@image.jpg;type=image/jpg' http://localhost:9292/upload +``` + +The Grape endpoint: + +```ruby +post 'upload' do + # file in params[:image_file] +end +``` + +In the case of conflict between either of: + +* route string parameters +* `GET`, `POST` and `PUT` parameters +* the contents of the request body on `POST` and `PUT` + +Route string parameters will have precedence. + +### Params Class + +By default parameters are available as `ActiveSupport::HashWithIndifferentAccess`. This can be changed to, for example, Ruby `Hash` or `Hashie::Mash` for the entire API. + +```ruby +class API < Grape::API + include Grape::Extensions::Hashie::Mash::ParamBuilder + + params do + optional :color, type: String + end + get do + params.color # instead of params[:color] + end +``` + +The class can also be overridden on individual parameter blocks using `build_with` as follows. + +```ruby +params do + build_with Grape::Extensions::Hash::ParamBuilder + optional :color, type: String +end +``` + +Or globally with the [Configuration](#configuration) `Grape.configure.param_builder`. + +In the example above, `params["color"]` will return `nil` since `params` is a plain `Hash`. + +Available parameter builders are `Grape::Extensions::Hash::ParamBuilder`, `Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder` and `Grape::Extensions::Hashie::Mash::ParamBuilder`. + +### Declared + +Grape allows you to access only the parameters that have been declared by your `params` block. It will: + + * Filter out the params that have been passed, but are not allowed. + * Include any optional params that are declared but not passed. + * Perform any parameter renaming on the resulting hash. + +Consider the following API endpoint: + +````ruby +format :json + +post 'users/signup' do + { 'declared_params' => declared(params) } +end +```` + +If you do not specify any parameters, `declared` will return an empty hash. + +**Request** + +````bash +curl -X POST -H "Content-Type: application/json" localhost:9292/users/signup -d '{"user": {"first_name":"first name", "last_name": "last name"}}' +```` + +**Response** + +````json +{ + "declared_params": {} +} + +```` + +Once we add parameters requirements, grape will start returning only the declared parameters. + +````ruby +format :json + +params do + optional :user, type: Hash do + optional :first_name, type: String + optional :last_name, type: String + end +end + +post 'users/signup' do + { 'declared_params' => declared(params) } +end +```` + +**Request** + +````bash +curl -X POST -H "Content-Type: application/json" localhost:9292/users/signup -d '{"user": {"first_name":"first name", "last_name": "last name", "random": "never shown"}}' +```` + +**Response** + +````json +{ + "declared_params": { + "user": { + "first_name": "first name", + "last_name": "last name" + } + } +} +```` + +Missing params that are declared as type `Hash` or `Array` will be included. + +````ruby +format :json + +params do + optional :user, type: Hash do + optional :first_name, type: String + optional :last_name, type: String + end + optional :widgets, type: Array +end + +post 'users/signup' do + { 'declared_params' => declared(params) } +end +```` + +**Request** + +````bash +curl -X POST -H "Content-Type: application/json" localhost:9292/users/signup -d '{}' +```` + +**Response** + +````json +{ + "declared_params": { + "user": { + "first_name": null, + "last_name": null + }, + "widgets": [] + } +} +```` + +The returned hash is an `ActiveSupport::HashWithIndifferentAccess`. + +The `#declared` method is not available to `before` filters, as those are evaluated prior to parameter coercion. + +### Include Parent Namespaces + +By default `declared(params)` includes parameters that were defined in all parent namespaces. If you want to return only parameters from your current namespace, you can set `include_parent_namespaces` option to `false`. + +````ruby +format :json + +namespace :parent do + params do + requires :parent_name, type: String + end + + namespace ':parent_name' do + params do + requires :child_name, type: String + end + get ':child_name' do + { + 'without_parent_namespaces' => declared(params, include_parent_namespaces: false), + 'with_parent_namespaces' => declared(params, include_parent_namespaces: true), + } + end + end +end +```` + +**Request** + +````bash +curl -X GET -H "Content-Type: application/json" localhost:9292/parent/foo/bar +```` + +**Response** + +````json +{ + "without_parent_namespaces": { + "child_name": "bar" + }, + "with_parent_namespaces": { + "parent_name": "foo", + "child_name": "bar" + }, +} +```` + +### Include Missing + +By default `declared(params)` includes parameters that have `nil` values. If you want to return only the parameters that are not `nil`, you can use the `include_missing` option. By default, `include_missing` is set to `true`. Consider the following API: + +````ruby +format :json + +params do + requires :user, type: Hash do + requires :first_name, type: String + optional :last_name, type: String + end +end + +post 'users/signup' do + { 'declared_params' => declared(params, include_missing: false) } +end +```` + +**Request** + +````bash +curl -X POST -H "Content-Type: application/json" localhost:9292/users/signup -d '{"user": {"first_name":"first name", "random": "never shown"}}' +```` + +**Response with include_missing:false** + +````json +{ + "declared_params": { + "user": { + "first_name": "first name" + } + } +} +```` + +**Response with include_missing:true** + +````json +{ + "declared_params": { + "user": { + "first_name": "first name", + "last_name": null + } + } +} +```` + +It also works on nested hashes: + +````ruby +format :json + +params do + requires :user, type: Hash do + requires :first_name, type: String + optional :last_name, type: String + requires :address, type: Hash do + requires :city, type: String + optional :region, type: String + end + end +end + +post 'users/signup' do + { 'declared_params' => declared(params, include_missing: false) } +end +```` + +**Request** + +````bash +curl -X POST -H "Content-Type: application/json" localhost:9292/users/signup -d '{"user": {"first_name":"first name", "random": "never shown", "address": { "city": "SF"}}}' +```` + +**Response with include_missing:false** + +````json +{ + "declared_params": { + "user": { + "first_name": "first name", + "address": { + "city": "SF" + } + } + } +} +```` + +**Response with include_missing:true** + +````json +{ + "declared_params": { + "user": { + "first_name": "first name", + "last_name": null, + "address": { + "city": "Zurich", + "region": null + } + } + } +} +```` + +Note that an attribute with a `nil` value is not considered *missing* and will also be returned when `include_missing` is set to `false`: + +**Request** + +````bash +curl -X POST -H "Content-Type: application/json" localhost:9292/users/signup -d '{"user": {"first_name":"first name", "last_name": null, "address": { "city": "SF"}}}' +```` + +**Response with include_missing:false** + +````json +{ + "declared_params": { + "user": { + "first_name": "first name", + "last_name": null, + "address": { "city": "SF"} + } + } +} +```` + +### Evaluate Given + +By default `declared(params)` will not evaluate `given` and return all parameters. Use `evaluate_given` to evaluate all `given` blocks and return only parameters that satisfy `given` conditions. Consider the following API: + +````ruby +format :json + +params do + optional :child_id, type: Integer + given :child_id do + requires :father_id, type: Integer + end +end + +post 'child' do + { 'declared_params' => declared(params, evaluate_given: true) } +end +```` + +**Request** + +````bash +curl -X POST -H "Content-Type: application/json" localhost:9292/child -d '{"father_id": 1}' +```` + +**Response with evaluate_given:false** + +````json +{ + "declared_params": { + "child_id": null, + "father_id": 1 + } +} +```` + +**Response with evaluate_given:true** + +````json +{ + "declared_params": { + "child_id": null + } +} +```` + +It also works on nested hashes: + +````ruby +format :json + +params do + requires :child, type: Hash do + optional :child_id, type: Integer + given :child_id do + requires :father_id, type: Integer + end + end +end + +post 'child' do + { 'declared_params' => declared(params, evaluate_given: true) } +end +```` + +**Request** + +````bash +curl -X POST -H "Content-Type: application/json" localhost:9292/child -d '{"child": {"father_id": 1}}' +```` + +**Response with evaluate_given:false** + +````json +{ + "declared_params": { + "child": { + "child_id": null, + "father_id": 1 + } + } +} +```` + +**Response with evaluate_given:true** + +````json +{ + "declared_params": { + "child": { + "child_id": null + } + } +} +```` + +### Parameter Precedence + +Using `route_param` takes higher precedence over a regular parameter defined with same name: + +```ruby +params do + requires :foo, type: String +end +route_param :foo do + get do + { value: params[:foo] } + end +end +``` + +**Request** + +```bash +curl -X POST -H "Content-Type: application/json" localhost:9292/bar -d '{"foo": "baz"}' +``` + +**Response** + +```json +{ + "value": "bar" +} +``` + +## Parameter Validation and Coercion + +You can define validations and coercion options for your parameters using a `params` block. + +```ruby +params do + requires :id, type: Integer + optional :text, type: String, regexp: /\A[a-z]+\z/ + group :media, type: Hash do + requires :url + end + optional :audio, type: Hash do + requires :format, type: Symbol, values: [:mp3, :wav, :aac, :ogg], default: :mp3 + end + mutually_exclusive :media, :audio +end +put ':id' do + # params[:id] is an Integer +end +``` + +When a type is specified an implicit validation is done after the coercion to ensure the output type is the one declared. + +Optional parameters can have a default value. + +```ruby +params do + optional :color, type: String, default: 'blue' + optional :random_number, type: Integer, default: -> { Random.rand(1..100) } + optional :non_random_number, type: Integer, default: Random.rand(1..100) +end +``` + +Default values are eagerly evaluated. Above `:non_random_number` will evaluate to the same number for each call to the endpoint of this `params` block. To have the default evaluate lazily with each request use a lambda, like `:random_number` above. + +Note that default values will be passed through to any validation options specified. +The following example will always fail if `:color` is not explicitly provided. + +```ruby +params do + optional :color, type: String, default: 'blue', values: ['red', 'green'] +end +``` + +The correct implementation is to ensure the default value passes all validations. + +```ruby +params do + optional :color, type: String, default: 'blue', values: ['blue', 'red', 'green'] +end +``` + +You can use the value of one parameter as the default value of some other parameter. In this case, if the `primary_color` parameter is not provided, it will have the same value as the `color` one. If both of them not provided, both of them will have `blue` value. + +```ruby +params do + optional :color, type: String, default: 'blue' + optional :primary_color, type: String, default: -> (params) { params[:color] } +end +``` + +### Supported Parameter Types + +The following are all valid types, supported out of the box by Grape: + +* Integer +* Float +* BigDecimal +* Numeric +* Date +* DateTime +* Time +* Boolean +* String +* Symbol +* Rack::Multipart::UploadedFile (alias `File`) +* JSON + +### Integer/Fixnum and Coercions + +Please be aware that the behavior differs between Ruby 2.4 and earlier versions. +In Ruby 2.4, values consisting of numbers are converted to Integer, but in earlier versions it will be treated as Fixnum. + +```ruby +params do + requires :integers, type: Hash do + requires :int, coerce: Integer + end +end +get '/int' do + params[:integers][:int].class +end + +... + +get '/int' integers: { int: '45' } + #=> Integer in ruby 2.4 + #=> Fixnum in earlier ruby versions +``` + +### Custom Types and Coercions + +Aside from the default set of supported types listed above, any class can be used as a type as long as an explicit coercion method is supplied. If the type implements a class-level `parse` method, Grape will use it automatically. This method must take one string argument and return an instance of the correct type, or return an instance of `Grape::Types::InvalidValue` which optionally accepts a message to be returned in the response. + +```ruby +class Color + attr_reader :value + def initialize(color) + @value = color + end + + def self.parse(value) + return new(value) if %w[blue red green].include?(value) + + Grape::Types::InvalidValue.new('Unsupported color') + end +end + +params do + requires :color, type: Color, default: Color.new('blue') + requires :more_colors, type: Array[Color] # Collections work + optional :unique_colors, type: Set[Color] # Duplicates discarded +end + +get '/stuff' do + # params[:color] is already a Color. + params[:color].value +end +``` + +Alternatively, a custom coercion method may be supplied for any type of parameter using `coerce_with`. Any class or object may be given that implements a `parse` or `call` method, in that order of precedence. The method must accept a single string parameter, and the return value must match the given `type`. + +```ruby +params do + requires :passwd, type: String, coerce_with: Base64.method(:decode64) + requires :loud_color, type: Color, coerce_with: ->(c) { Color.parse(c.downcase) } + + requires :obj, type: Hash, coerce_with: JSON do + requires :words, type: Array[String], coerce_with: ->(val) { val.split(/\s+/) } + optional :time, type: Time, coerce_with: Chronic + end +end +``` +Note that, a `nil` value will call the custom coercion method, while a missing parameter will not. + +Example of use of `coerce_with` with a lambda (a class with a `parse` method could also have been used) +It will parse a string and return an Array of Integers, matching the `Array[Integer]` `type`. + +```ruby +params do + requires :values, type: Array[Integer], coerce_with: ->(val) { val.split(/\s+/).map(&:to_i) } +end +``` + +Grape will assert that coerced values match the given `type`, and will reject the request if they do not. To override this behaviour, custom types may implement a `parsed?` method that should accept a single argument and return `true` if the value passes type validation. + +```ruby +class SecureUri + def self.parse(value) + URI.parse value + end + + def self.parsed?(value) + value.is_a? URI::HTTPS + end +end + +params do + requires :secure_uri, type: SecureUri +end +``` + +### Multipart File Parameters + +Grape makes use of `Rack::Request`'s built-in support for multipart file parameters. Such parameters can be declared with `type: File`: + +```ruby +params do + requires :avatar, type: File +end +post '/' do + params[:avatar][:filename] # => 'avatar.png' + params[:avatar][:type] # => 'image/png' + params[:avatar][:tempfile] # => # +end +``` + +### First-Class `JSON` Types + +Grape supports complex parameters given as JSON-formatted strings using the special `type: JSON` declaration. JSON objects and arrays of objects are accepted equally, with nested validation rules applied to all objects in either case: + +```ruby +params do + requires :json, type: JSON do + requires :int, type: Integer, values: [1, 2, 3] + end +end +get '/' do + params[:json].inspect +end + +client.get('/', json: '{"int":1}') # => "{:int=>1}" +client.get('/', json: '[{"int":"1"}]') # => "[{:int=>1}]" + +client.get('/', json: '{"int":4}') # => HTTP 400 +client.get('/', json: '[{"int":4}]') # => HTTP 400 +``` + +Additionally `type: Array[JSON]` may be used, which explicitly marks the parameter as an array of objects. If a single object is supplied it will be wrapped. + +```ruby +params do + requires :json, type: Array[JSON] do + requires :int, type: Integer + end +end +get '/' do + params[:json].each { |obj| ... } # always works +end +``` +For stricter control over the type of JSON structure which may be supplied, use `type: Array, coerce_with: JSON` or `type: Hash, coerce_with: JSON`. + +### Multiple Allowed Types + +Variant-type parameters can be declared using the `types` option rather than `type`: + +```ruby +params do + requires :status_code, types: [Integer, String, Array[Integer, String]] +end +get '/' do + params[:status_code].inspect +end + +client.get('/', status_code: 'OK_GOOD') # => "OK_GOOD" +client.get('/', status_code: 300) # => 300 +client.get('/', status_code: %w(404 NOT FOUND)) # => [404, "NOT", "FOUND"] +``` + +As a special case, variant-member-type collections may also be declared, by passing a `Set` or `Array` with more than one member to `type`: + +```ruby +params do + requires :status_codes, type: Array[Integer,String] +end +get '/' do + params[:status_codes].inspect +end + +client.get('/', status_codes: %w(1 two)) # => [1, "two"] +``` + +### Validation of Nested Parameters + +Parameters can be nested using `group` or by calling `requires` or `optional` with a block. +In the [above example](#parameter-validation-and-coercion), this means `params[:media][:url]` is required along with `params[:id]`, and `params[:audio][:format]` is required only if `params[:audio]` is present. +With a block, `group`, `requires` and `optional` accept an additional option `type` which can be either `Array` or `Hash`, and defaults to `Array`. Depending on the value, the nested parameters will be treated either as values of a hash or as values of hashes in an array. + +```ruby +params do + optional :preferences, type: Array do + requires :key + requires :value + end + + requires :name, type: Hash do + requires :first_name + requires :last_name + end +end +``` + +### Dependent Parameters + +Suppose some of your parameters are only relevant if another parameter is given; Grape allows you to express this relationship through the `given` method in your parameters block, like so: + +```ruby +params do + optional :shelf_id, type: Integer + given :shelf_id do + requires :bin_id, type: Integer + end +end +``` + +In the example above Grape will use `blank?` to check whether the `shelf_id` param is present. + +`given` also takes a `Proc` with custom code. Below, the param `description` is required only if the value of `category` is equal `foo`: + +```ruby +params do + optional :category + given category: ->(val) { val == 'foo' } do + requires :description + end +end +``` + +You can rename parameters: + +```ruby +params do + optional :category, as: :type + given type: ->(val) { val == 'foo' } do + requires :description + end +end +``` + +Note: param in `given` should be the renamed one. In the example, it should be `type`, not `category`. + +### Group Options + +Parameters options can be grouped. It can be useful if you want to extract common validation or types for several parameters. +Within these groups, individual parameters can extend or selectively override the common settings, allowing you to maintain the defaults at the group level while still applying parameter-specific rules where necessary. + +The example below presents a typical case when parameters share common options. + +```ruby +params do + requires :first_name, type: String, regexp: /w+/, desc: 'First name', documentation: { in: 'body' } + optional :middle_name, type: String, regexp: /w+/, desc: 'Middle name', documentation: { in: 'body', x: { nullable: true } } + requires :last_name, type: String, regexp: /w+/, desc: 'Last name', documentation: { in: 'body' } +end +``` + +Grape allows you to present the same logic through the `with` method in your parameters block, like so: + +```ruby +params do + with(type: String, regexp: /w+/, documentation: { in: 'body' }) do + requires :first_name, desc: 'First name' + optional :middle_name, desc: 'Middle name', documentation: { x: { nullable: true } } + requires :last_name, desc: 'Last name' + end +end +``` + +You can organize settings into layers using nested `with' blocks. Each layer can use, add to, or change the settings of the layer above it. This helps to keep complex parameters organized and consistent, while still allowing for specific customizations to be made. + +```ruby +params do + with(documentation: { in: 'body' }) do # Applies documentation to all nested parameters + with(type: String, regexp: /\w+/) do # Applies type and validation to names + requires :first_name, desc: 'First name' + requires :last_name, desc: 'Last name' + end + optional :age, type: Integer, desc: 'Age', documentation: { x: { nullable: true } } # Specific settings for 'age' + end +end +``` + +### Renaming + +You can rename parameters using `as`, which can be useful when refactoring existing APIs: + +```ruby +resource :users do + params do + requires :email_address, as: :email + requires :password + end + post do + User.create!(declared(params)) # User takes email and password + end +end +``` + +The value passed to `as` will be the key when calling `declared(params)`. + +### Built-in Validators + +#### `allow_blank` + +Parameters can be defined as `allow_blank`, ensuring that they contain a value. By default, `requires` only validates that a parameter was sent in the request, regardless its value. With `allow_blank: false`, empty values or whitespace only values are invalid. + +`allow_blank` can be combined with both `requires` and `optional`. If the parameter is required, it has to contain a value. If it's optional, it's possible to not send it in the request, but if it's being sent, it has to have some value, and not an empty string/only whitespaces. + + +```ruby +params do + requires :username, allow_blank: false + optional :first_name, allow_blank: false +end +``` + +#### `values` + +Parameters can be restricted to a specific set of values with the `:values` option. + + +```ruby +params do + requires :status, type: Symbol, values: [:not_started, :processing, :done] + optional :numbers, type: Array[Integer], default: 1, values: [1, 2, 3, 5, 8] +end +``` + +Supplying a range to the `:values` option ensures that the parameter is (or parameters are) included in that range (using `Range#include?`). + +```ruby +params do + requires :latitude, type: Float, values: -90.0..+90.0 + requires :longitude, type: Float, values: -180.0..+180.0 + optional :letters, type: Array[String], values: 'a'..'z' +end +``` + +Note endless ranges are also supported with ActiveSupport >= 6.0, but they require that the type be provided. + +```ruby +params do + requires :minimum, type: Integer, values: 10.. + optional :maximum, type: Integer, values: ..10 +end +``` + +Note that *both* range endpoints have to be a `#kind_of?` your `:type` option (if you don't supply the `:type` option, it will be guessed to be equal to the class of the range's first endpoint). So the following is invalid: + +```ruby +params do + requires :invalid1, type: Float, values: 0..10 # 0.kind_of?(Float) => false + optional :invalid2, values: 0..10.0 # 10.0.kind_of?(0.class) => false +end +``` + +The `:values` option can also be supplied with a `Proc`, evaluated lazily with each request. +If the Proc has arity zero (i.e. it takes no arguments) it is expected to return either a list or a range which will then be used to validate the parameter. + +For example, given a status model you may want to restrict by hashtags that you have previously defined in the `HashTag` model. + +```ruby +params do + requires :hashtag, type: String, values: -> { Hashtag.all.map(&:tag) } +end +``` + +Alternatively, a Proc with arity one (i.e. taking one argument) can be used to explicitly validate each parameter value. In that case, the Proc is expected to return a truthy value if the parameter value is valid. The parameter will be considered invalid if the Proc returns a falsy value or if it raises a StandardError. + +```ruby +params do + requires :number, type: Integer, values: ->(v) { v.even? && v < 25 } +end +``` + +While Procs are convenient for single cases, consider using [Custom Validators](#custom-validators) in cases where a validation is used more than once. + +Note that [allow_blank](#allow_blank) validator applies while using `:values`. In the following example the absence of `:allow_blank` does not prevent `:state` from receiving blank values because `:allow_blank` defaults to `true`. + +```ruby +params do + requires :state, type: Symbol, values: [:active, :inactive] +end +``` + +#### `except_values` + +Parameters can be restricted from having a specific set of values with the `:except_values` option. + +The `except_values` validator behaves similarly to the `values` validator in that it accepts either an Array, a Range, or a Proc. Unlike the `values` validator, however, `except_values` only accepts Procs with arity zero. + +```ruby +params do + requires :browser, except_values: [ 'ie6', 'ie7', 'ie8' ] + requires :port, except_values: { value: 0..1024, message: 'is not allowed' } + requires :hashtag, except_values: -> { Hashtag.FORBIDDEN_LIST } +end +``` + +#### `same_as` + +A `same_as` option can be given to ensure that values of parameters match. + +```ruby +params do + requires :password + requires :password_confirmation, same_as: :password +end +``` + +#### `length` + +Parameters with types that support `#length` method can be restricted to have a specific length with the `:length` option. + +The validator accepts `:min` or `:max` or both options or only `:is` to validate that the value of the parameter is within the given limits. + +```ruby +params do + requires :code, type: String, length: { is: 2 } + requires :str, type: String, length: { min: 3 } + requires :list, type: [Integer], length: { min: 3, max: 5 } + requires :hash, type: Hash, length: { max: 5 } +end +``` + +#### `regexp` + +Parameters can be restricted to match a specific regular expression with the `:regexp` option. If the value does not match the regular expression an error will be returned. Note that this is true for both `requires` and `optional` parameters. + +```ruby +params do + requires :email, regexp: /.+@.+/ +end +``` + +The validator will pass if the parameter was sent without value. To ensure that the parameter contains a value, use `allow_blank: false`. + +```ruby +params do + requires :email, allow_blank: false, regexp: /.+@.+/ +end +``` + +#### `mutually_exclusive` + +Parameters can be defined as `mutually_exclusive`, ensuring that they aren't present at the same time in a request. + +```ruby +params do + optional :beer + optional :wine + mutually_exclusive :beer, :wine +end +``` + +Multiple sets can be defined: + +```ruby +params do + optional :beer + optional :wine + mutually_exclusive :beer, :wine + optional :scotch + optional :aquavit + mutually_exclusive :scotch, :aquavit +end +``` + +**Warning**: Never define mutually exclusive sets with any required params. Two mutually exclusive required params will mean params are never valid, thus making the endpoint useless. One required param mutually exclusive with an optional param will mean the latter is never valid. + +#### `exactly_one_of` + +Parameters can be defined as 'exactly_one_of', ensuring that exactly one parameter gets selected. + +```ruby +params do + optional :beer + optional :wine + exactly_one_of :beer, :wine +end +``` + +Note that using `:default` with `mutually_exclusive` will cause multiple parameters to always have a default value and raise a `Grape::Exceptions::Validation` mutually exclusive exception. + +#### `at_least_one_of` + +Parameters can be defined as 'at_least_one_of', ensuring that at least one parameter gets selected. + +```ruby +params do + optional :beer + optional :wine + optional :juice + at_least_one_of :beer, :wine, :juice +end +``` + +#### `all_or_none_of` + +Parameters can be defined as 'all_or_none_of', ensuring that all or none of parameters gets selected. + +```ruby +params do + optional :beer + optional :wine + optional :juice + all_or_none_of :beer, :wine, :juice +end +``` + +#### Nested `mutually_exclusive`, `exactly_one_of`, `at_least_one_of`, `all_or_none_of` + +All of these methods can be used at any nested level. + +```ruby +params do + requires :food, type: Hash do + optional :meat + optional :fish + optional :rice + at_least_one_of :meat, :fish, :rice + end + group :drink, type: Hash do + optional :beer + optional :wine + optional :juice + exactly_one_of :beer, :wine, :juice + end + optional :dessert, type: Hash do + optional :cake + optional :icecream + mutually_exclusive :cake, :icecream + end + optional :recipe, type: Hash do + optional :oil + optional :meat + all_or_none_of :oil, :meat + end +end +``` + +### Namespace Validation and Coercion + +Namespaces allow parameter definitions and apply to every method within the namespace. + +```ruby +namespace :statuses do + params do + requires :user_id, type: Integer, desc: 'A user ID.' + end + namespace ':user_id' do + desc "Retrieve a user's status." + params do + requires :status_id, type: Integer, desc: 'A status ID.' + end + get ':status_id' do + User.find(params[:user_id]).statuses.find(params[:status_id]) + end + end +end +``` + +The `namespace` method has a number of aliases, including: `group`, `resource`, `resources`, and `segment`. Use whichever reads the best for your API. + +You can conveniently define a route parameter as a namespace using `route_param`. + +```ruby +namespace :statuses do + route_param :id do + desc 'Returns all replies for a status.' + get 'replies' do + Status.find(params[:id]).replies + end + desc 'Returns a status.' + get do + Status.find(params[:id]) + end + end +end +``` + +You can also define a route parameter type by passing to `route_param`'s options. + +```ruby +namespace :arithmetic do + route_param :n, type: Integer do + desc 'Returns in power' + get 'power' do + params[:n] ** params[:n] + end + end +end +``` + +### Custom Validators + +```ruby +class AlphaNumeric < Grape::Validations::Validators::Base + def validate_param!(attr_name, params) + unless params[attr_name] =~ /\A[[:alnum:]]+\z/ + raise Grape::Exceptions::Validation.new params: [@scope.full_name(attr_name)], message: 'must consist of alpha-numeric characters' + end + end +end +``` + +```ruby +params do + requires :text, alpha_numeric: true +end +``` + +You can also create custom classes that take parameters. + +```ruby +class Length < Grape::Validations::Validators::Base + def validate_param!(attr_name, params) + unless params[attr_name].length <= @option + raise Grape::Exceptions::Validation.new params: [@scope.full_name(attr_name)], message: "must be at the most #{@option} characters long" + end + end +end +``` + +```ruby +params do + requires :text, length: 140 +end +``` + +You can also create custom validation that use request to validate the attribute. For example if you want to have parameters that are available to only admins, you can do the following. + +```ruby +class Admin < Grape::Validations::Validators::Base + def validate(request) + # return if the param we are checking was not in request + # @attrs is a list containing the attribute we are currently validating + # in our sample case this method once will get called with + # @attrs being [:admin_field] and once with @attrs being [:admin_false_field] + return unless request.params.key?(@attrs.first) + # check if admin flag is set to true + return unless @option + # check if user is admin or not + # as an example get a token from request and check if it's admin or not + raise Grape::Exceptions::Validation.new params: @attrs, message: 'Can not set admin-only field.' unless request.headers['X-Access-Token'] == 'admin' + end +end +``` + +And use it in your endpoint definition as: + +```ruby +params do + optional :admin_field, type: String, admin: true + optional :non_admin_field, type: String + optional :admin_false_field, type: String, admin: false +end +``` + +Every validation will have its own instance of the validator, which means that the validator can have a state. + +### Validation Errors + +Validation and coercion errors are collected and an exception of type `Grape::Exceptions::ValidationErrors` is raised. If the exception goes uncaught it will respond with a status of 400 and an error message. The validation errors are grouped by parameter name and can be accessed via `Grape::Exceptions::ValidationErrors#errors`. + + +The default response from a `Grape::Exceptions::ValidationErrors` is a humanly readable string, such as "beer, wine are mutually exclusive", in the following example. + +```ruby +params do + optional :beer + optional :wine + optional :juice + exactly_one_of :beer, :wine, :juice +end +``` + +You can rescue a `Grape::Exceptions::ValidationErrors` and respond with a custom response or turn the response into well-formatted JSON for a JSON API that separates individual parameters and the corresponding error messages. The following `rescue_from` example produces `[{"params":["beer","wine"],"messages":["are mutually exclusive"]}]`. + +```ruby +format :json +subject.rescue_from Grape::Exceptions::ValidationErrors do |e| + error! e, 400 +end +``` + +`Grape::Exceptions::ValidationErrors#full_messages` returns the validation messages as an array. `Grape::Exceptions::ValidationErrors#message` joins the messages to one string. + +For responding with an array of validation messages, you can use `Grape::Exceptions::ValidationErrors#full_messages`. +```ruby +format :json +subject.rescue_from Grape::Exceptions::ValidationErrors do |e| + error!({ messages: e.full_messages }, 400) +end +``` + +Grape returns all validation and coercion errors found by default. +To skip all subsequent validation checks when a specific param is found invalid, use `fail_fast: true`. + +The following example will not check if `:wine` is present unless it finds `:beer`. +```ruby +params do + required :beer, fail_fast: true + required :wine +end +``` +The result of empty params would be a single `Grape::Exceptions::ValidationErrors` error. + +Similarly, no regular expression test will be performed if `:blah` is blank in the following example. +```ruby +params do + required :blah, allow_blank: false, regexp: /blah/, fail_fast: true +end +``` + +### I18n + +Grape supports I18n for parameter-related error messages, but will fallback to English if translations for the default locale have not been provided. See [en.yml](lib/grape/locale/en.yml) for message keys. + +In case your app enforces available locales only and :en is not included in your available locales, Grape cannot fall back to English and will return the translation key for the error message. To avoid this behaviour, either provide a translation for your default locale or add :en to your available locales. + +### Custom Validation messages + +Grape supports custom validation messages for parameter-related and coerce-related error messages. + +#### `presence`, `allow_blank`, `values`, `regexp` + +```ruby +params do + requires :name, values: { value: 1..10, message: 'not in range from 1 to 10' }, allow_blank: { value: false, message: 'cannot be blank' }, regexp: { value: /^[a-z]+$/, message: 'format is invalid' }, message: 'is required' +end +``` + +#### `same_as` + +```ruby +params do + requires :password + requires :password_confirmation, same_as: { value: :password, message: 'not match' } +end +``` + +#### `length` + +```ruby +params do + requires :code, type: String, length: { is: 2, message: 'code is expected to be exactly 2 characters long' } + requires :str, type: String, length: { min: 5, message: 'str is expected to be at least 5 characters long' } + requires :list, type: [Integer], length: { min: 2, max: 3, message: 'list is expected to have between 2 and 3 elements' } +end +``` + +#### `all_or_none_of` + +```ruby +params do + optional :beer + optional :wine + optional :juice + all_or_none_of :beer, :wine, :juice, message: "all params are required or none is required" +end +``` + +#### `mutually_exclusive` + +```ruby +params do + optional :beer + optional :wine + optional :juice + mutually_exclusive :beer, :wine, :juice, message: "are mutually exclusive cannot pass both params" +end +``` + +#### `exactly_one_of` + +```ruby +params do + optional :beer + optional :wine + optional :juice + exactly_one_of :beer, :wine, :juice, message: { exactly_one: "are missing, exactly one parameter is required", mutual_exclusion: "are mutually exclusive, exactly one parameter is required" } +end +``` + +#### `at_least_one_of` + +```ruby +params do + optional :beer + optional :wine + optional :juice + at_least_one_of :beer, :wine, :juice, message: "are missing, please specify at least one param" +end +``` + +#### `Coerce` + +```ruby +params do + requires :int, type: { value: Integer, message: "type cast is invalid" } +end +``` + +#### `With Lambdas` + +```ruby +params do + requires :name, values: { value: -> { (1..10).to_a }, message: 'not in range from 1 to 10' } +end +``` + +#### `Pass symbols for i18n translations` + +You can pass a symbol if you want i18n translations for your custom validation messages. + +```ruby +params do + requires :name, message: :name_required +end +``` +```ruby +# en.yml + +en: + grape: + errors: + format: ! '%{attributes} %{message}' + messages: + name_required: 'must be present' +``` + +#### Overriding Attribute Names + +You can also override attribute names. + +```ruby +# en.yml + +en: + grape: + errors: + format: ! '%{attributes} %{message}' + messages: + name_required: 'must be present' + attributes: + name: 'Oops! Name' +``` +Will produce 'Oops! Name must be present' + +#### With Default + +You cannot set a custom message option for Default as it requires interpolation `%{option1}: %{value1} is incompatible with %{option2}: %{value2}`. You can change the default error message for Default by changing the `incompatible_option_values` message key inside [en.yml](lib/grape/locale/en.yml) + +```ruby +params do + requires :name, values: { value: -> { (1..10).to_a }, message: 'not in range from 1 to 10' }, default: 5 +end +``` + +### Using `dry-validation` or `dry-schema` + +As an alternative to the `params` DSL described above, you can use a schema or `dry-validation` contract to describe an endpoint's parameters. This can be especially useful if you use the above already in some other parts of your application. If not, you'll need to add `dry-validation` or `dry-schema` to your `Gemfile`. + +Then call `contract` with a contract or schema defined previously: + +```rb +CreateOrdersSchema = Dry::Schema.Params do + required(:orders).array(:hash) do + required(:name).filled(:string) + optional(:volume).maybe(:integer, lt?: 9) + end +end + +# ... + +contract CreateOrdersSchema +``` + +or with a block, using the [schema definition syntax](https://dry-rb.org/gems/dry-schema/1.13/#quick-start): + +```rb +contract do + required(:orders).array(:hash) do + required(:name).filled(:string) + optional(:volume).maybe(:integer, lt?: 9) + end +end +``` + +The latter will define a coercing schema (`Dry::Schema.Params`). When using the former approach, it's up to you to decide whether the input will need coercing. + +The `params` and `contract` declarations can also be used together in the same API, e.g. to describe different parts of a nested namespace for an endpoint. + +## Headers + +### Request +Request headers are available through the `headers` helper or from `env` in their original form. + +```ruby +get do + error!('Unauthorized', 401) unless headers['Secret-Password'] == 'swordfish' +end +``` + +```ruby +get do + error!('Unauthorized', 401) unless env['HTTP_SECRET_PASSWORD'] == 'swordfish' +end +``` + +#### Header Case Handling + +The above example may have been requested as follows: + +``` shell +curl -H "secret_PassWord: swordfish" ... +``` + +The header name will have been normalized for you. + +- In the `header` helper names will be coerced into a downcased kebab case as `secret-password` if using Rack 3. +- In the `header` helper names will be coerced into a capitalized kebab case as `Secret-PassWord` if using Rack < 3. +- In the `env` collection they appear in all uppercase, in snake case, and prefixed with 'HTTP_' as `HTTP_SECRET_PASSWORD` + +The header name will have been normalized per HTTP standards defined in [RFC2616 Section 4.2](https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2) regardless of what is being sent by a client. + +### Response + +You can set a response header with `header` inside an API. + +```ruby +header 'X-Robots-Tag', 'noindex' +``` + +When raising `error!`, pass additional headers as arguments. Additional headers will be merged with headers set before `error!` call. + +```ruby +error! 'Unauthorized', 401, 'X-Error-Detail' => 'Invalid token.' +``` + +## Routes + +To define routes you can use the `route` method or the shorthands for the HTTP verbs. To define a route that accepts any route set to `:any`. +Parts of the path that are denoted with a colon will be interpreted as route parameters. + +```ruby +route :get, 'status' do +end + +# is the same as + +get 'status' do +end + +# is the same as + +get :status do +end + +# is NOT the same as + +get ':status' do # this makes params[:status] available +end + +# This will make both params[:status_id] and params[:id] available + +get 'statuses/:status_id/reviews/:id' do +end +``` + +To declare a namespace that prefixes all routes within, use the `namespace` method. `group`, `resource`, `resources` and `segment` are aliases to this method. Any endpoints within will share their parent context as well as any configuration done in the namespace context. + +The `route_param` method is a convenient method for defining a parameter route segment. If you define a type, it will add a validation for this parameter. + +```ruby +route_param :id, type: Integer do + get 'status' do + end +end + +# is the same as + +namespace ':id' do + params do + requires :id, type: Integer + end + + get 'status' do + end +end +``` + +Optionally, you can define requirements for your named route parameters using regular expressions on namespace or endpoint. The route will match only if all requirements are met. + +```ruby +get ':id', requirements: { id: /[0-9]*/ } do + Status.find(params[:id]) +end + +namespace :outer, requirements: { id: /[0-9]*/ } do + get :id do + end + + get ':id/edit' do + end +end +``` + +## Helpers + +You can define helper methods that your endpoints can use with the `helpers` macro by either giving a block or an array of modules. + +```ruby +module StatusHelpers + def user_info(user) + "#{user} has statused #{user.statuses} status(s)" + end +end + +module HttpCodesHelpers + def unauthorized + 401 + end +end + +class API < Grape::API + # define helpers with a block + helpers do + def current_user + User.find(params[:user_id]) + end + end + + # or mix in an array of modules + helpers StatusHelpers, HttpCodesHelpers + + before do + error!('Access Denied', unauthorized) unless current_user + end + + get 'info' do + # helpers available in your endpoint and filters + user_info(current_user) + end +end +``` + +You can define reusable `params` using `helpers`. + +```ruby +class API < Grape::API + helpers do + params :pagination do + optional :page, type: Integer + optional :per_page, type: Integer + end + end + + desc 'Get collection' + params do + use :pagination # aliases: includes, use_scope + end + get do + Collection.page(params[:page]).per(params[:per_page]) + end +end +``` + +You can also define reusable `params` using shared helpers. + +```ruby +module SharedParams + extend Grape::API::Helpers + + params :period do + optional :start_date + optional :end_date + end + + params :pagination do + optional :page, type: Integer + optional :per_page, type: Integer + end +end + +class API < Grape::API + helpers SharedParams + + desc 'Get collection.' + params do + use :period, :pagination + end + + get do + Collection + .from(params[:start_date]) + .to(params[:end_date]) + .page(params[:page]) + .per(params[:per_page]) + end +end +``` + +Helpers support blocks that can help set default values. The following API can return a collection sorted by `id` or `created_at` in `asc` or `desc` order. + +```ruby +module SharedParams + extend Grape::API::Helpers + + params :order do |options| + optional :order_by, type: Symbol, values: options[:order_by], default: options[:default_order_by] + optional :order, type: Symbol, values: %i(asc desc), default: options[:default_order] + end +end + +class API < Grape::API + helpers SharedParams + + desc 'Get a sorted collection.' + params do + use :order, order_by: %i(id created_at), default_order_by: :created_at, default_order: :asc + end + + get do + Collection.send(params[:order], params[:order_by]) + end +end +``` + +## Path Helpers + +If you need methods for generating paths inside your endpoints, please see the [grape-route-helpers](https://github.com/reprah/grape-route-helpers) gem. + +## Parameter Documentation + +You can attach additional documentation to `params` using a `documentation` hash. + +```ruby +params do + optional :first_name, type: String, documentation: { example: 'Jim' } + requires :last_name, type: String, documentation: { example: 'Smith' } +end +``` + +If documentation isn't needed (for instance, it is an internal API), documentation can be disabled. + +```ruby +class API < Grape::API + do_not_document! + + # endpoints... +end +``` + +In this case, Grape won't create objects related to documentation which are retained in RAM forever. + +## Cookies + +You can set, get and delete your cookies very simply using `cookies` method. + +```ruby +class API < Grape::API + get 'status_count' do + cookies[:status_count] ||= 0 + cookies[:status_count] += 1 + { status_count: cookies[:status_count] } + end + + delete 'status_count' do + { status_count: cookies.delete(:status_count) } + end +end +``` + +Use a hash-based syntax to set more than one value. + +```ruby +cookies[:status_count] = { + value: 0, + expires: Time.tomorrow, + domain: '.twitter.com', + path: '/' +} + +cookies[:status_count][:value] +=1 +``` + +Delete a cookie with `delete`. + +```ruby +cookies.delete :status_count +``` + +Specify an optional path. + +```ruby +cookies.delete :status_count, path: '/' +``` + +## HTTP Status Code + +By default Grape returns a 201 for `POST`-Requests, 204 for `DELETE`-Requests that don't return any content, and 200 status code for all other Requests. +You can use `status` to query and set the actual HTTP Status Code + +```ruby +post do + status 202 + + if status == 200 + # do some thing + end +end +``` + +You can also use one of status codes symbols that are provided by [Rack utils](http://www.rubydoc.info/github/rack/rack/Rack/Utils#HTTP_STATUS_CODES-constant) + +```ruby +post do + status :no_content +end +``` + +## Redirecting + +You can redirect to a new url temporarily (302) or permanently (301). + +```ruby +redirect '/statuses' +``` + +```ruby +redirect '/statuses', permanent: true +``` + +## Recognizing Path + +You can recognize the endpoint matched with given path. + +This API returns an instance of `Grape::Endpoint`. + +```ruby +class API < Grape::API + get '/statuses' do + end +end + +API.recognize_path '/statuses' +``` + +Since version `2.1.0`, the `recognize_path` method takes into account the parameters type to determine which endpoint should match with given path. + +```ruby +class Books < Grape::API + resource :books do + route_param :id, type: Integer do + # GET /books/:id + get do + #... + end + end + + resource :share do + # POST /books/share + post do + # .... + end + end + end +end + +API.recognize_path '/books/1' # => /books/:id +API.recognize_path '/books/share' # => /books/share +API.recognize_path '/books/other' # => nil +``` + + +## Allowed Methods + +When you add a `GET` route for a resource, a route for the `HEAD` method will also be added automatically. You can disable this behavior with `do_not_route_head!`. + +``` ruby +class API < Grape::API + do_not_route_head! + + get '/example' do + # only responds to GET + end +end +``` + +When you add a route for a resource, a route for the `OPTIONS` method will also be added. The response to an OPTIONS request will include an "Allow" header listing the supported methods. If the resource has `before` and `after` callbacks they will be executed, but no other callbacks will run. + +```ruby +class API < Grape::API + get '/rt_count' do + { rt_count: current_user.rt_count } + end + + params do + requires :value, type: Integer, desc: 'Value to add to the rt count.' + end + put '/rt_count' do + current_user.rt_count += params[:value].to_i + { rt_count: current_user.rt_count } + end +end +``` + +``` shell +curl -v -X OPTIONS http://localhost:3000/rt_count + +> OPTIONS /rt_count HTTP/1.1 +> +< HTTP/1.1 204 No Content +< Allow: OPTIONS, GET, PUT +``` + +You can disable this behavior with `do_not_route_options!`. + +If a request for a resource is made with an unsupported HTTP method, an HTTP 405 (Method Not Allowed) response will be returned. If the resource has `before` callbacks they will be executed, but no other callbacks will run. + +``` shell +curl -X DELETE -v http://localhost:3000/rt_count/ + +> DELETE /rt_count/ HTTP/1.1 +> Host: localhost:3000 +> +< HTTP/1.1 405 Method Not Allowed +< Allow: OPTIONS, GET, PUT +``` + +## Raising Exceptions + +You can abort the execution of an API method by raising errors with `error!`. + +```ruby +error! 'Access Denied', 401 +``` + +Anything that responds to `#to_s` can be given as a first argument to `error!`. + +```ruby +error! :not_found, 404 +``` + +You can also return JSON formatted objects by raising error! and passing a hash instead of a message. + +```ruby +error!({ error: 'unexpected error', detail: 'missing widget' }, 500) +``` + +You can set additional headers for the response. They will be merged with headers set before `error!` call. + +```ruby +error!('Something went wrong', 500, 'X-Error-Detail' => 'Invalid token.') +``` + +You can present documented errors with a Grape entity using the the [grape-entity](https://github.com/ruby-grape/grape-entity) gem. + +```ruby +module API + class Error < Grape::Entity + expose :code + expose :message + end +end +``` + +The following example specifies the entity to use in the `http_codes` definition. + +```ruby +desc 'My Route' do + failure [[408, 'Unauthorized', API::Error]] +end +error!({ message: 'Unauthorized' }, 408) +``` + +The following example specifies the presented entity explicitly in the error message. + +```ruby +desc 'My Route' do + failure [[408, 'Unauthorized']] +end +error!({ message: 'Unauthorized', with: API::Error }, 408) +``` + +### Default Error HTTP Status Code + +By default Grape returns a 500 status code from `error!`. You can change this with `default_error_status`. + +``` ruby +class API < Grape::API + default_error_status 400 + get '/example' do + error! 'This should have http status code 400' + end +end +``` + +### Handling 404 + +For Grape to handle all the 404s for your API, it can be useful to use a catch-all. +In its simplest form, it can be like: + +```ruby +route :any, '*path' do + error! # or something else +end +``` + +It is very crucial to __define this endpoint at the very end of your API__, as it literally accepts every request. + +## Exception Handling + +Grape can be told to rescue all `StandardError` exceptions and return them in the API format. + +```ruby +class Twitter::API < Grape::API + rescue_from :all +end +``` + +This mimics [default `rescue` behaviour](https://ruby-doc.org/core/StandardError.html) when an exception type is not provided. +Any other exception should be rescued explicitly, see [below](#exceptions-that-should-be-rescued-explicitly). + +Grape can also rescue from all exceptions and still use the built-in exception handing. +This will give the same behavior as `rescue_from :all` with the addition that Grape will use the exception handling defined by all Exception classes that inherit `Grape::Exceptions::Base`. + +The intent of this setting is to provide a simple way to cover the most common exceptions and return any unexpected exceptions in the API format. + +```ruby +class Twitter::API < Grape::API + rescue_from :grape_exceptions +end +``` + +If you want to customize the shape of grape exceptions returned to the user, to match your `:all` handler for example, you can pass a block to `rescue_from :grape_exceptions`. + +```ruby +rescue_from :grape_exceptions do |e| + error!(e, e.status) +end +``` + +You can also rescue specific exceptions. + +```ruby +class Twitter::API < Grape::API + rescue_from ArgumentError, UserDefinedError +end +``` + +In this case ```UserDefinedError``` must be inherited from ```StandardError```. + +Notice that you could combine these two approaches (rescuing custom errors takes precedence). For example, it's useful for handling all exceptions except Grape validation errors. + +```ruby +class Twitter::API < Grape::API + rescue_from Grape::Exceptions::ValidationErrors do |e| + error!(e, 400) + end + + rescue_from :all +end +``` + +The error format will match the request format. See "Content-Types" below. + +Custom error formatters for existing and additional types can be defined with a proc. + +```ruby +class Twitter::API < Grape::API + error_formatter :txt, ->(message, backtrace, options, env, original_exception) { + "error: #{message} from #{backtrace}" + } +end +``` + +You can also use a module or class. + +```ruby +module CustomFormatter + def self.call(message, backtrace, options, env, original_exception) + { message: message, backtrace: backtrace } + end +end + +class Twitter::API < Grape::API + error_formatter :custom, CustomFormatter +end +``` + +You can rescue all exceptions with a code block. The `error!` wrapper automatically sets the default error code and content-type. + +```ruby +class Twitter::API < Grape::API + rescue_from :all do |e| + error!("rescued from #{e.class.name}") + end +end +``` + +Optionally, you can set the format, status code and headers. + +```ruby +class Twitter::API < Grape::API + format :json + rescue_from :all do |e| + error!({ error: 'Server error.' }, 500, { 'Content-Type' => 'text/error' }) + end +end +``` + +You can also rescue all exceptions with a code block and handle the Rack response at the lowest level. + +```ruby +class Twitter::API < Grape::API + rescue_from :all do |e| + Rack::Response.new([ e.message ], 500, { 'Content-type' => 'text/error' }) + end +end +``` + +Or rescue specific exceptions. + +```ruby +class Twitter::API < Grape::API + rescue_from ArgumentError do |e| + error!("ArgumentError: #{e.message}") + end + + rescue_from NoMethodError do |e| + error!("NoMethodError: #{e.message}") + end +end +``` + +By default, `rescue_from` will rescue the exceptions listed and all their subclasses. + +Assume you have the following exception classes defined. + +```ruby +module APIErrors + class ParentError < StandardError; end + class ChildError < ParentError; end +end +``` + +Then the following `rescue_from` clause will rescue exceptions of type `APIErrors::ParentError` and its subclasses (in this case `APIErrors::ChildError`). + +```ruby +rescue_from APIErrors::ParentError do |e| + error!({ + error: "#{e.class} error", + message: e.message + }, e.status) +end +``` + +To only rescue the base exception class, set `rescue_subclasses: false`. +The code below will rescue exceptions of type `RuntimeError` but _not_ its subclasses. + +```ruby +rescue_from RuntimeError, rescue_subclasses: false do |e| + error!({ + status: e.status, + message: e.message, + errors: e.errors + }, e.status) +end +``` + +Helpers are also available inside `rescue_from`. + +```ruby +class Twitter::API < Grape::API + format :json + helpers do + def server_error! + error!({ error: 'Server error.' }, 500, { 'Content-Type' => 'text/error' }) + end + end + + rescue_from :all do |e| + server_error! + end +end +``` + +The `rescue_from` handler must return a `Rack::Response` object, call `error!`, or raise an exception (either the original exception or another custom one). The exception raised in `rescue_from` will be handled outside Grape. For example, if you mount Grape in Rails, the exception will be handle by [Rails Action Controller](https://guides.rubyonrails.org/action_controller_overview.html#rescue). + +Alternately, use the `with` option in `rescue_from` to specify a method or a `proc`. + +```ruby +class Twitter::API < Grape::API + format :json + helpers do + def server_error! + error!({ error: 'Server error.' }, 500, { 'Content-Type' => 'text/error' }) + end + end + + rescue_from :all, with: :server_error! + rescue_from ArgumentError, with: -> { Rack::Response.new('rescued with a method', 400) } +end +``` + +Inside the `rescue_from` block, the environment of the original controller method(`.self` receiver) is accessible through the `#context` method. + +```ruby +class Twitter::API < Grape::API + rescue_from :all do |e| + user_id = context.params[:user_id] + error!("error for #{user_id}") + end +end +``` + +#### Rescuing exceptions inside namespaces + +You could put `rescue_from` clauses inside a namespace and they will take precedence over ones +defined in the root scope: + +```ruby +class Twitter::API < Grape::API + rescue_from ArgumentError do |e| + error!("outer") + end + + namespace :statuses do + rescue_from ArgumentError do |e| + error!("inner") + end + get do + raise ArgumentError.new + end + end +end +``` + +Here `'inner'` will be result of handling occurred `ArgumentError`. + +#### Unrescuable Exceptions + +`Grape::Exceptions::InvalidVersionHeader`, which is raised when the version in the request header doesn't match the currently evaluated version for the endpoint, will _never_ be rescued from a `rescue_from` block (even a `rescue_from :all`) This is because Grape relies on Rack to catch that error and try the next versioned-route for cases where there exist identical Grape endpoints with different versions. + +#### Exceptions that should be rescued explicitly + +Any exception that is not subclass of `StandardError` should be rescued explicitly. +Usually it is not a case for an application logic as such errors point to problems in Ruby runtime. +This is following [standard recommendations for exceptions handling](https://ruby-doc.org/core/Exception.html). + +## Logging + +`Grape::API` provides a `logger` method which by default will return an instance of the `Logger` class from Ruby's standard library. + +To log messages from within an endpoint, you need to define a helper to make the logger available in the endpoint context. + +```ruby +class API < Grape::API + helpers do + def logger + API.logger + end + end + post '/statuses' do + logger.info "#{current_user} has statused" + end +end +``` + +To change the logger level. + +```ruby +class API < Grape::API + self.logger.level = Logger::INFO +end +``` + +You can also set your own logger. + +```ruby +class MyLogger + def warning(message) + puts "this is a warning: #{message}" + end +end + +class API < Grape::API + logger MyLogger.new + helpers do + def logger + API.logger + end + end + get '/statuses' do + logger.warning "#{current_user} has statused" + end +end +``` + +For similar to Rails request logging try the [grape_logging](https://github.com/aserafin/grape_logging) or [grape-middleware-logger](https://github.com/ridiculous/grape-middleware-logger) gems. + +## API Formats + +Your API can declare which content-types to support by using `content_type`. If you do not specify any, Grape will support _XML_, _JSON_, _BINARY_, and _TXT_ content-types. The default format is `:txt`; you can change this with `default_format`. Essentially, the two APIs below are equivalent. + +```ruby +class Twitter::API < Grape::API + # no content_type declarations, so Grape uses the defaults +end + +class Twitter::API < Grape::API + # the following declarations are equivalent to the defaults + + content_type :xml, 'application/xml' + content_type :json, 'application/json' + content_type :binary, 'application/octet-stream' + content_type :txt, 'text/plain' + + default_format :txt +end +``` + +If you declare any `content_type` whatsoever, the Grape defaults will be overridden. For example, the following API will only support the `:xml` and `:rss` content-types, but not `:txt`, `:json`, or `:binary`. Importantly, this means the `:txt` default format is not supported! So, make sure to set a new `default_format`. + +```ruby +class Twitter::API < Grape::API + content_type :xml, 'application/xml' + content_type :rss, 'application/xml+rss' + + default_format :xml +end +``` + +Serialization takes place automatically. For example, you do not have to call `to_json` in each JSON API endpoint implementation. The response format (and thus the automatic serialization) is determined in the following order: +* Use the file extension, if specified. If the file is .json, choose the JSON format. +* Use the value of the `format` parameter in the query string, if specified. +* Use the format set by the `format` option, if specified. +* Attempt to find an acceptable format from the `Accept` header. +* Use the default format, if specified by the `default_format` option. +* Default to `:txt`. + +For example, consider the following API. + +```ruby +class MultipleFormatAPI < Grape::API + content_type :xml, 'application/xml' + content_type :json, 'application/json' + + default_format :json + + get :hello do + { hello: 'world' } + end +end +``` + +* `GET /hello` (with an `Accept: */*` header) does not have an extension or a `format` parameter, so it will respond with JSON (the default format). +* `GET /hello.xml` has a recognized extension, so it will respond with XML. +* `GET /hello?format=xml` has a recognized `format` parameter, so it will respond with XML. +* `GET /hello.xml?format=json` has a recognized extension (which takes precedence over the `format` parameter), so it will respond with XML. +* `GET /hello.xls` (with an `Accept: */*` header) has an extension, but that extension is not recognized, so it will respond with JSON (the default format). +* `GET /hello.xls` with an `Accept: application/xml` header has an unrecognized extension, but the `Accept` header corresponds to a recognized format, so it will respond with XML. +* `GET /hello.xls` with an `Accept: text/plain` header has an unrecognized extension *and* an unrecognized `Accept` header, so it will respond with JSON (the default format). + +You can override this process explicitly by calling `api_format` in the API itself. +For example, the following API will let you upload arbitrary files and return their contents as an attachment with the correct MIME type. + +```ruby +class Twitter::API < Grape::API + post 'attachment' do + filename = params[:file][:filename] + content_type MIME::Types.type_for(filename)[0].to_s + api_format :binary # there's no formatter for :binary, data will be returned "as is" + header 'Content-Disposition', "attachment; filename*=UTF-8''#{CGI.escape(filename)}" + params[:file][:tempfile].read + end +end +``` + +You can have your API only respond to a single format with `format`. If you use this, the API will **not** respond to file extensions other than specified in `format`. For example, consider the following API. + +```ruby +class SingleFormatAPI < Grape::API + format :json + + get :hello do + { hello: 'world' } + end +end +``` + +* `GET /hello` will respond with JSON. +* `GET /hello.json` will respond with JSON. +* `GET /hello.xml`, `GET /hello.foobar`, or *any* other extension will respond with an HTTP 404 error code. +* `GET /hello?format=xml` will respond with an HTTP 406 error code, because the XML format specified by the request parameter is not supported. +* `GET /hello` with an `Accept: application/xml` header will still respond with JSON, since it could not negotiate a recognized content-type from the headers and JSON is the effective default. + +The formats apply to parsing, too. The following API will only respond to the JSON content-type and will not parse any other input than `application/json`, `application/x-www-form-urlencoded`, `multipart/form-data`, `multipart/related` and `multipart/mixed`. All other requests will fail with an HTTP 406 error code. + +```ruby +class Twitter::API < Grape::API + format :json +end +``` + +When the content-type is omitted, Grape will return a 406 error code unless `default_format` is specified. +The following API will try to parse any data without a content-type using a JSON parser. + +```ruby +class Twitter::API < Grape::API + format :json + default_format :json +end +``` + +If you combine `format` with `rescue_from :all`, errors will be rendered using the same format. +If you do not want this behavior, set the default error formatter with `default_error_formatter`. + +```ruby +class Twitter::API < Grape::API + format :json + content_type :txt, 'text/plain' + default_error_formatter :txt +end +``` + +Custom formatters for existing and additional types can be defined with a proc. + +```ruby +class Twitter::API < Grape::API + content_type :xls, 'application/vnd.ms-excel' + formatter :xls, ->(object, env) { object.to_xls } +end +``` + +You can also use a module or class. + +```ruby +module XlsFormatter + def self.call(object, env) + object.to_xls + end +end + +class Twitter::API < Grape::API + content_type :xls, 'application/vnd.ms-excel' + formatter :xls, XlsFormatter +end +``` + +Built-in formatters are the following. + +* `:json`: use object's `to_json` when available, otherwise call `MultiJson.dump` +* `:xml`: use object's `to_xml` when available, usually via `MultiXml` +* `:txt`: use object's `to_txt` when available, otherwise `to_s` +* `:serializable_hash`: use object's `serializable_hash` when available, otherwise fallback to `:json` +* `:binary`: data will be returned "as is" + +If a body is present in a request to an API, with a Content-Type header value that is of an unsupported type a "415 Unsupported Media Type" error code will be returned by Grape. + +Response statuses that indicate no content as defined by [Rack](https://github.com/rack) [here](https://github.com/rack/rack/blob/master/lib/rack/utils.rb#L567) will bypass serialization and the body entity - though there should be none - will not be modified. + +### JSONP + +Grape supports JSONP via [Rack::JSONP](https://github.com/rack/rack-contrib), part of the [rack-contrib](https://github.com/rack/rack-contrib) gem. Add `rack-contrib` to your `Gemfile`. + +```ruby +require 'rack/contrib' + +class API < Grape::API + use Rack::JSONP + format :json + get '/' do + 'Hello World' + end +end +``` + +### CORS + +Grape supports CORS via [Rack::CORS](https://github.com/cyu/rack-cors), part of the [rack-cors](https://github.com/cyu/rack-cors) gem. Add `rack-cors` to your `Gemfile`, then use the middleware in your config.ru file. + +```ruby +require 'rack/cors' + +use Rack::Cors do + allow do + origins '*' + resource '*', headers: :any, methods: :get + end +end + +run Twitter::API + +``` + +## Content-type + +Content-type is set by the formatter. You can override the content-type of the response at runtime by setting the `Content-Type` header. + +```ruby +class API < Grape::API + get '/home_timeline_js' do + content_type 'application/javascript' + "var statuses = ...;" + end +end +``` + +## API Data Formats + +Grape accepts and parses input data sent with the POST and PUT methods as described in the Parameters section above. It also supports custom data formats. You must declare additional content-types via `content_type` and optionally supply a parser via `parser` unless a parser is already available within Grape to enable a custom format. Such a parser can be a function or a class. + +With a parser, parsed data is available "as-is" in `env['api.request.body']`. +Without a parser, data is available "as-is" and in `env['api.request.input']`. + +The following example is a trivial parser that will assign any input with the "text/custom" content-type to `:value`. The parameter will be available via `params[:value]` inside the API call. + +```ruby +module CustomParser + def self.call(object, env) + { value: object.to_s } + end +end +``` + +```ruby +content_type :txt, 'text/plain' +content_type :custom, 'text/custom' +parser :custom, CustomParser + +put 'value' do + params[:value] +end +``` + +You can invoke the above API as follows. + +``` +curl -X PUT -d 'data' 'http://localhost:9292/value' -H Content-Type:text/custom -v +``` + +You can disable parsing for a content-type with `nil`. For example, `parser :json, nil` will disable JSON parsing altogether. The request data is then available as-is in `env['api.request.body']`. + +## JSON and XML Processors + +Grape uses `JSON` and `ActiveSupport::XmlMini` for JSON and XML parsing by default. It also detects and supports [multi_json](https://github.com/intridea/multi_json) and [multi_xml](https://github.com/sferik/multi_xml). Adding those gems to your Gemfile and requiring them will enable them and allow you to swap the JSON and XML back-ends. + +## RESTful Model Representations + +Grape supports a range of ways to present your data with some help from a generic `present` method, which accepts two arguments: the object to be presented and the options associated with it. The options hash may include `:with`, which defines the entity to expose. + +### Grape Entities + +Add the [grape-entity](https://github.com/ruby-grape/grape-entity) gem to your Gemfile. +Please refer to the [grape-entity documentation](https://github.com/ruby-grape/grape-entity/blob/master/README.md) +for more details. + +The following example exposes statuses. + +```ruby +module API + module Entities + class Status < Grape::Entity + expose :user_name + expose :text, documentation: { type: 'string', desc: 'Status update text.' } + expose :ip, if: { type: :full } + expose :user_type, :user_id, if: ->(status, options) { status.user.public? } + expose :digest do |status, options| + Digest::MD5.hexdigest(status.txt) + end + expose :replies, using: API::Status, as: :replies + end + end + + class Statuses < Grape::API + version 'v1' + + desc 'Statuses index' do + params: API::Entities::Status.documentation + end + get '/statuses' do + statuses = Status.all + type = current_user.admin? ? :full : :default + present statuses, with: API::Entities::Status, type: type + end + end +end +``` + +You can use entity documentation directly in the params block with `using: Entity.documentation`. + +```ruby +module API + class Statuses < Grape::API + version 'v1' + + desc 'Create a status' + params do + requires :all, except: [:ip], using: API::Entities::Status.documentation.except(:id) + end + post '/status' do + Status.create! params + end + end +end +``` + +You can present with multiple entities using an optional Symbol argument. + +```ruby + get '/statuses' do + statuses = Status.all.page(1).per(20) + present :total_page, 10 + present :per_page, 20 + present :statuses, statuses, with: API::Entities::Status + end +``` + +The response will be + +``` + { + total_page: 10, + per_page: 20, + statuses: [] + } +``` + +In addition to separately organizing entities, it may be useful to put them as namespaced classes underneath the model they represent. + +```ruby +class Status + def entity + Entity.new(self) + end + + class Entity < Grape::Entity + expose :text, :user_id + end +end +``` + +If you organize your entities this way, Grape will automatically detect the `Entity` class and use it to present your models. In this example, if you added `present Status.new` to your endpoint, Grape will automatically detect that there is a `Status::Entity` class and use that as the representative entity. This can still be overridden by using the `:with` option or an explicit `represents` call. + +You can present `hash` with `Grape::Presenters::Presenter` to keep things consistent. + +```ruby +get '/users' do + present { id: 10, name: :dgz }, with: Grape::Presenters::Presenter +end +```` +The response will be + +```ruby +{ + id: 10, + name: 'dgz' +} +``` + +It has the same result with + +```ruby +get '/users' do + present :id, 10 + present :name, :dgz +end +``` + +### Hypermedia and Roar + +You can use [Roar](https://github.com/apotonick/roar) to render HAL or Collection+JSON with the help of [grape-roar](https://github.com/ruby-grape/grape-roar), which defines a custom JSON formatter and enables presenting entities with Grape's `present` keyword. + +### Rabl + +You can use [Rabl](https://github.com/nesquena/rabl) templates with the help of the [grape-rabl](https://github.com/ruby-grape/grape-rabl) gem, which defines a custom Grape Rabl formatter. + +### Active Model Serializers + +You can use [Active Model Serializers](https://github.com/rails-api/active_model_serializers) serializers with the help of the [grape-active_model_serializers](https://github.com/jrhe/grape-active_model_serializers) gem, which defines a custom Grape AMS formatter. + +## Sending Raw or No Data + +In general, use the binary format to send raw data. + +```ruby +class API < Grape::API + get '/file' do + content_type 'application/octet-stream' + File.binread 'file.bin' + end +end +``` + +You can set the response body explicitly with `body`. + +```ruby +class API < Grape::API + get '/' do + content_type 'text/plain' + body 'Hello World' + # return value ignored + end +end +``` + +Use `body false` to return `204 No Content` without any data or content-type. + +If you want to empty the body with an HTTP status code other than `204 No Content`, you can override the status code after specifying `body false` as follows + +```ruby +class API < Grape::API + get '/' do + body false + status 304 + end +end +``` + +You can also set the response to a file with `sendfile`. This works with the [Rack::Sendfile](https://www.rubydoc.info/gems/rack/Rack/Sendfile) middleware to optimally send the file through your web server software. + +```ruby +class API < Grape::API + get '/' do + sendfile '/path/to/file' + end +end +``` + +To stream a file in chunks use `stream` + +```ruby +class API < Grape::API + get '/' do + stream '/path/to/file' + end +end +``` + +If you want to stream non-file data use the `stream` method and a `Stream` object. +This is an object that responds to `each` and yields for each chunk to send to the client. +Each chunk will be sent as it is yielded instead of waiting for all of the content to be available. + +```ruby +class MyStream + def each + yield 'part 1' + yield 'part 2' + yield 'part 3' + end +end + +class API < Grape::API + get '/' do + stream MyStream.new + end +end +``` + +## Authentication + +### Basic Auth + +Grape has built-in Basic authentication (the given `block` is executed in the context of the current `Endpoint`). Authentication applies to the current namespace and any children, but not parents. + +```ruby +http_basic do |username, password| + # verify user's password here + # IMPORTANT: make sure you use a comparison method which isn't prone to a timing attack +end +``` + +### Register custom middleware for authentication + +Grape can use custom Middleware for authentication. How to implement these Middleware have a look at `Rack::Auth::Basic` or similar implementations. + +For registering a Middleware you need the following options: + +* `label` - the name for your authenticator to use it later +* `MiddlewareClass` - the MiddlewareClass to use for authentication +* `option_lookup_proc` - A Proc with one Argument to lookup the options at runtime (return value is an `Array` as Parameter for the Middleware). + +Example: + +```ruby + +Grape::Middleware::Auth::Strategies.add(:my_auth, AuthMiddleware, ->(options) { [options[:realm]] } ) + + +auth :my_auth, { realm: 'Test Api'} do |credentials| + # lookup the user's password here + { 'user1' => 'password1' }[username] +end + +``` + +Use [Doorkeeper](https://github.com/doorkeeper-gem/doorkeeper), [warden-oauth2](https://github.com/opperator/warden-oauth2) or [rack-oauth2](https://github.com/nov/rack-oauth2) for OAuth2 support. + +You can access the controller params, headers, and helpers through the context with the `#context` method inside any auth middleware inherited from `Grape::Middleware::Auth::Base`. + +## Describing and Inspecting an API + +Grape routes can be reflected at runtime. This can notably be useful for generating documentation. + +Grape exposes arrays of API versions and compiled routes. Each route contains a `prefix`, `version`, `namespace`, `method` and `params`. You can add custom route settings to the route metadata with `route_setting`. + +```ruby +class TwitterAPI < Grape::API + version 'v1' + desc 'Includes custom settings.' + route_setting :custom, key: 'value' + get do + + end +end +``` + +Examine the routes at runtime. + +```ruby +TwitterAPI::versions # yields [ 'v1', 'v2' ] +TwitterAPI::routes # yields an array of Grape::Route objects +TwitterAPI::routes[0].version # => 'v1' +TwitterAPI::routes[0].description # => 'Includes custom settings.' +TwitterAPI::routes[0].settings[:custom] # => { key: 'value' } +``` + +Note that `Route#route_xyz` methods have been deprecated since 0.15.0 and removed since 2.0.1. + +Please use `Route#xyz` instead. + +Note that difference of `Route#options` and `Route#settings`. + +The `options` can be referred from your route, it should be set by specifying key and value on verb methods such as `get`, `post` and `put`. +The `settings` can also be referred from your route, but it should be set by specifying key and value on `route_setting`. + +## Current Route and Endpoint + +It's possible to retrieve the information about the current route from within an API call with `route`. + +```ruby +class MyAPI < Grape::API + desc 'Returns a description of a parameter.' + params do + requires :id, type: Integer, desc: 'Identity.' + end + get 'params/:id' do + route.params[params[:id]] # yields the parameter description + end +end +``` + +The current endpoint responding to the request is `self` within the API block or `env['api.endpoint']` elsewhere. The endpoint has some interesting properties, such as `source` which gives you access to the original code block of the API implementation. This can be particularly useful for building a logger middleware. + +```ruby +class ApiLogger < Grape::Middleware::Base + def before + file = env['api.endpoint'].source.source_location[0] + line = env['api.endpoint'].source.source_location[1] + logger.debug "[api] #{file}:#{line}" + end +end +``` + +## Before, After and Finally + +Blocks can be executed before or after every API call, using `before`, `after`, `before_validation` and `after_validation`. +If the API fails the `after` call will not be triggered, if you need code to execute for sure use the `finally`. + +Before and after callbacks execute in the following order: + +1. `before` +2. `before_validation` +3. _validations_ +4. `after_validation` (upon successful validation) +5. _the API call_ (upon successful validation) +6. `after` (upon successful validation and API call) +7. `finally` (always) + +Steps 4, 5 and 6 only happen if validation succeeds. + +If a request for a resource is made with an unsupported HTTP method (returning HTTP 405) only `before` callbacks will be executed. The remaining callbacks will be bypassed. + +If a request for a resource is made that triggers the built-in `OPTIONS` handler, only `before` and `after` callbacks will be executed. The remaining callbacks will be bypassed. + +For example, using a simple `before` block to set a header. + +```ruby +before do + header 'X-Robots-Tag', 'noindex' +end +``` + +You can ensure a block of code runs after every request (including failures) with `finally`: + +```ruby +finally do + # this code will run after every request (successful or failed) +end +``` + +**Namespaces** + +Callbacks apply to each API call within and below the current namespace: + +```ruby +class MyAPI < Grape::API + get '/' do + "root - #{@blah}" + end + + namespace :foo do + before do + @blah = 'blah' + end + + get '/' do + "root - foo - #{@blah}" + end + + namespace :bar do + get '/' do + "root - foo - bar - #{@blah}" + end + end + end +end +``` + +The behavior is then: + +```bash +GET / # 'root - ' +GET /foo # 'root - foo - blah' +GET /foo/bar # 'root - foo - bar - blah' +``` + +Params on a `namespace` (or whichever alias you are using) will also be available when using `before_validation` or `after_validation`: + +```ruby +class MyAPI < Grape::API + params do + requires :blah, type: Integer + end + resource ':blah' do + after_validation do + # if we reach this point validations will have passed + @blah = declared(params, include_missing: false)[:blah] + end + + get '/' do + @blah.class + end + end +end +``` + +The behavior is then: + +```bash +GET /123 # 'Integer' +GET /foo # 400 error - 'blah is invalid' +``` + +**Versioning** + +When a callback is defined within a version block, it's only called for the routes defined in that block. + +```ruby +class Test < Grape::API + resource :foo do + version 'v1', :using => :path do + before do + @output ||= 'v1-' + end + get '/' do + @output += 'hello' + end + end + + version 'v2', :using => :path do + before do + @output ||= 'v2-' + end + get '/' do + @output += 'hello' + end + end + end +end +``` + +The behavior is then: + +```bash +GET /foo/v1 # 'v1-hello' +GET /foo/v2 # 'v2-hello' +``` + +**Altering Responses** + +Using `present` in any callback allows you to add data to a response: + +```ruby +class MyAPI < Grape::API + format :json + + after_validation do + present :name, params[:name] if params[:name] + end + + get '/greeting' do + present :greeting, 'Hello!' + end +end +``` + +The behavior is then: + +```bash +GET /greeting # {"greeting":"Hello!"} +GET /greeting?name=Alan # {"name":"Alan","greeting":"Hello!"} +``` + +Instead of altering a response, you can also terminate and rewrite it from any callback using `error!`, including `after`. This will cause all subsequent steps in the process to not be called. **This includes the actual api call and any callbacks** + +## Anchoring + +Grape by default anchors all request paths, which means that the request URL should match from start to end to match, otherwise a `404 Not Found` is returned. However, this is sometimes not what you want, because it is not always known upfront what can be expected from the call. This is because Rack-mount by default anchors requests to match from the start to the end, or not at all. +Rails solves this problem by using a `anchor: false` option in your routes. +In Grape this option can be used as well when a method is defined. + +For instance when your API needs to get part of an URL, for instance: + +```ruby +class TwitterAPI < Grape::API + namespace :statuses do + get '/(*:status)', anchor: false do + + end + end +end +``` + +This will match all paths starting with '/statuses/'. There is one caveat though: the `params[:status]` parameter only holds the first part of the request url. +Luckily this can be circumvented by using the described above syntax for path specification and using the `PATH_INFO` Rack environment variable, using `env['PATH_INFO']`. This will hold everything that comes after the '/statuses/' part. + +## Instance Variables + +You can use instance variables to pass information across the various stages of a request. An instance variable set within a `before` validator is accessible within the endpoint's code and can also be utilized within the `rescue_from` handler. + +```ruby +class TwitterAPI < Grape::API + before do + @var = 1 + end + + get '/' do + puts @var # => 1 + raise + end + + rescue_from :all do + puts @var # => 1 + end +end +``` + +The values of instance variables cannot be shared among various endpoints within the same API. This limitation arises due to Grape generating a new instance for each request made. Consequently, instance variables set within an endpoint during one request differ from those set during a subsequent request, as they exist within separate instances. + +```ruby +class TwitterAPI < Grape::API + get '/first' do + @var = 1 + puts @var # => 1 + end + + get '/second' do + puts @var # => nil + end +end +``` + +## Using Custom Middleware + +### Grape Middleware + +You can make a custom middleware by using `Grape::Middleware::Base`. +It's inherited from some grape official middlewares in fact. + +For example, you can write a middleware to log application exception. + +```ruby +class LoggingError < Grape::Middleware::Base + def after + return unless @app_response && @app_response[0] == 500 + env['rack.logger'].error("Raised error on #{env['PATH_INFO']}") + end +end +``` + +Your middleware can overwrite application response as follows, except error case. + +```ruby +class Overwriter < Grape::Middleware::Base + def after + [200, { 'Content-Type' => 'text/plain' }, ['Overwritten.']] + end +end +``` + +You can add your custom middleware with `use`, that push the middleware onto the stack, and you can also control where the middleware is inserted using `insert`, `insert_before` and `insert_after`. + +```ruby +class CustomOverwriter < Grape::Middleware::Base + def after + [200, { 'Content-Type' => 'text/plain' }, [@options[:message]]] + end +end + + +class API < Grape::API + use Overwriter + insert_before Overwriter, CustomOverwriter, message: 'Overwritten again.' + insert 0, CustomOverwriter, message: 'Overwrites all other middleware.' + + get '/' do + end +end +``` + +You can access the controller params, headers, and helpers through the context with the `#context` method inside any middleware inherited from `Grape::Middleware::Base`. + +### Rails Middleware + +Note that when you're using Grape mounted on Rails you don't have to use Rails middleware because it's already included into your middleware stack. +You only have to implement the helpers to access the specific `env` variable. + +If you are using a custom application that is inherited from `Rails::Application` and need to insert a new middleware among the ones initiated via Rails, you will need to register it manually in your custom application class. + +```ruby +class Company::Application < Rails::Application + config.middleware.insert_before(Rack::Attack, Middleware::ApiLogger) +end +``` + +### Remote IP + +By default you can access remote IP with `request.ip`. This is the remote IP address implemented by Rack. Sometimes it is desirable to get the remote IP [Rails-style](http://stackoverflow.com/questions/10997005/whats-the-difference-between-request-remote-ip-and-request-ip-in-rails) with `ActionDispatch::RemoteIp`. + +Add `gem 'actionpack'` to your Gemfile and `require 'action_dispatch/middleware/remote_ip.rb'`. Use the middleware in your API and expose a `client_ip` helper. See [this documentation](http://api.rubyonrails.org/classes/ActionDispatch/RemoteIp.html) for additional options. + +```ruby +class API < Grape::API + use ActionDispatch::RemoteIp + + helpers do + def client_ip + env['action_dispatch.remote_ip'].to_s + end + end + + get :remote_ip do + { ip: client_ip } + end +end +``` + +## Writing Tests + +### Writing Tests with Rack + +Use `rack-test` and define your API as `app`. + +#### RSpec + +You can test a Grape API with RSpec by making HTTP requests and examining the response. + +```ruby + + +describe Twitter::API do + include Rack::Test::Methods + + def app + Twitter::API + end + + context 'GET /api/statuses/public_timeline' do + it 'returns an empty array of statuses' do + get '/api/statuses/public_timeline' + expect(last_response.status).to eq(200) + expect(JSON.parse(last_response.body)).to eq [] + end + end + context 'GET /api/statuses/:id' do + it 'returns a status by id' do + status = Status.create! + get "/api/statuses/#{status.id}" + expect(last_response.body).to eq status.to_json + end + end +end +``` + +There's no standard way of sending arrays of objects via an HTTP GET, so POST JSON data and specify the correct content-type. + +```ruby +describe Twitter::API do + context 'POST /api/statuses' do + it 'creates many statuses' do + statuses = [{ text: '...' }, { text: '...'}] + post '/api/statuses', statuses.to_json, 'CONTENT_TYPE' => 'application/json' + expect(last_response.body).to eq 201 + end + end +end +``` + +#### Airborne + +You can test with other RSpec-based frameworks, including [Airborne](https://github.com/brooklynDev/airborne), which uses `rack-test` to make requests. + +```ruby +require 'airborne' + +Airborne.configure do |config| + config.rack_app = Twitter::API +end + +describe Twitter::API do + context 'GET /api/statuses/:id' do + it 'returns a status by id' do + status = Status.create! + get "/api/statuses/#{status.id}" + expect_json(status.as_json) + end + end +end +``` + +#### MiniTest + +```ruby +require 'test_helper' + +class Twitter::APITest < MiniTest::Test + include Rack::Test::Methods + + def app + Twitter::API + end + + def test_get_api_statuses_public_timeline_returns_an_empty_array_of_statuses + get '/api/statuses/public_timeline' + assert last_response.ok? + assert_equal [], JSON.parse(last_response.body) + end + + def test_get_api_statuses_id_returns_a_status_by_id + status = Status.create! + get "/api/statuses/#{status.id}" + assert_equal status.to_json, last_response.body + end +end +``` + +### Writing Tests with Rails + +#### RSpec + +```ruby +describe Twitter::API do + context 'GET /api/statuses/public_timeline' do + it 'returns an empty array of statuses' do + get '/api/statuses/public_timeline' + expect(response.status).to eq(200) + expect(JSON.parse(response.body)).to eq [] + end + end + context 'GET /api/statuses/:id' do + it 'returns a status by id' do + status = Status.create! + get "/api/statuses/#{status.id}" + expect(response.body).to eq status.to_json + end + end +end +``` + +In Rails, HTTP request tests would go into the `spec/requests` group. You may want your API code to go into `app/api` - you can match that layout under `spec` by adding the following in `spec/rails_helper.rb`. + +```ruby +RSpec.configure do |config| + config.include RSpec::Rails::RequestExampleGroup, type: :request, file_path: /spec\/api/ +end +``` + +#### MiniTest + +```ruby +class Twitter::APITest < ActiveSupport::TestCase + include Rack::Test::Methods + + def app + Rails.application + end + + test 'GET /api/statuses/public_timeline returns an empty array of statuses' do + get '/api/statuses/public_timeline' + assert last_response.ok? + assert_equal [], JSON.parse(last_response.body) + end + + test 'GET /api/statuses/:id returns a status by id' do + status = Status.create! + get "/api/statuses/#{status.id}" + assert_equal status.to_json, last_response.body + end +end +``` + +### Stubbing Helpers + +Because helpers are mixed in based on the context when an endpoint is defined, it can be difficult to stub or mock them for testing. The `Grape::Endpoint.before_each` method can help by allowing you to define behavior on the endpoint that will run before every request. + +```ruby +describe 'an endpoint that needs helpers stubbed' do + before do + Grape::Endpoint.before_each do |endpoint| + allow(endpoint).to receive(:helper_name).and_return('desired_value') + end + end + + after do + Grape::Endpoint.before_each nil + end + + it 'stubs the helper' do + + end +end +``` + +## Reloading API Changes in Development + +### Reloading in Rack Applications + +Use [grape-reload](https://github.com/AlexYankee/grape-reload). + +### Reloading in Rails Applications + +Add API paths to `config/application.rb`. + +```ruby +# Auto-load API and its subdirectories +config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb') +config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')] +``` + +Create `config/initializers/reload_api.rb`. + +```ruby +if Rails.env.development? + ActiveSupport::Dependencies.explicitly_unloadable_constants << 'Twitter::API' + + api_files = Dir[Rails.root.join('app', 'api', '**', '*.rb')] + api_reloader = ActiveSupport::FileUpdateChecker.new(api_files) do + Rails.application.reload_routes! + end + ActionDispatch::Callbacks.to_prepare do + api_reloader.execute_if_updated + end +end +``` + +For Rails >= 5.1.4, change this: + +```ruby +ActionDispatch::Callbacks.to_prepare do + api_reloader.execute_if_updated +end +``` + +to this: + +```ruby +ActiveSupport::Reloader.to_prepare do + api_reloader.execute_if_updated +end +``` + +See [StackOverflow #3282655](http://stackoverflow.com/questions/3282655/ruby-on-rails-3-reload-lib-directory-for-each-request/4368838#4368838) for more information. + +## Performance Monitoring + +### Active Support Instrumentation + +Grape has built-in support for [ActiveSupport::Notifications](http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html) which provides simple hook points to instrument key parts of your application. + +The following are currently supported: + +#### endpoint_run.grape + +The main execution of an endpoint, includes filters and rendering. + +* *endpoint* - The endpoint instance + +#### endpoint_render.grape + +The execution of the main content block of the endpoint. + +* *endpoint* - The endpoint instance + +#### endpoint_run_filters.grape + +* *endpoint* - The endpoint instance +* *filters* - The filters being executed +* *type* - The type of filters (before, before_validation, after_validation, after) + +#### endpoint_run_validators.grape + +The execution of validators. + +* *endpoint* - The endpoint instance +* *validators* - The validators being executed +* *request* - The request being validated + +#### format_response.grape + +Serialization or template rendering. + +* *env* - The request environment +* *formatter* - The formatter object (e.g., `Grape::Formatter::Json`) + +See the [ActiveSupport::Notifications documentation](http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html) for information on how to subscribe to these events. + +### Monitoring Products + +Grape integrates with following third-party tools: + +* **New Relic** - [built-in support](https://docs.newrelic.com/docs/agents/ruby-agent/frameworks/grape-instrumentation) from v3.10.0 of the official [newrelic_rpm](https://github.com/newrelic/rpm) gem, also [newrelic-grape](https://github.com/xinminlabs/newrelic-grape) gem +* **Librato Metrics** - [grape-librato](https://github.com/seanmoon/grape-librato) gem +* **[Skylight](https://www.skylight.io/)** - [skylight](https://github.com/skylightio/skylight-ruby) gem, [documentation](https://docs.skylight.io/grape/) +* **[AppSignal](https://www.appsignal.com)** - [appsignal-ruby](https://github.com/appsignal/appsignal-ruby) gem, [documentation](http://docs.appsignal.com/getting-started/supported-frameworks.html#grape) +* **[ElasticAPM](https://www.elastic.co/products/apm)** - [elastic-apm](https://github.com/elastic/apm-agent-ruby) gem, [documentation](https://www.elastic.co/guide/en/apm/agent/ruby/3.x/getting-started-rack.html#getting-started-grape) +* **[Datadog APM](https://docs.datadoghq.com/tracing/)** - [ddtrace](https://github.com/datadog/dd-trace-rb) gem, [documentation](https://docs.datadoghq.com/tracing/setup_overview/setup/ruby/#grape) + +## Contributing to Grape + +Grape is work of hundreds of contributors. You're encouraged to submit pull requests, propose features and discuss issues. + +See [CONTRIBUTING](CONTRIBUTING.md). + +## Security + +See [SECURITY](SECURITY.md) for details. + +## License + +MIT License. See [LICENSE](LICENSE) for details. + +## Copyright + +Copyright (c) 2010-2020 Michael Bleigh, Intridea Inc. and Contributors. diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/UPGRADING.md b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/UPGRADING.md new file mode 100644 index 00000000..0c6c54f6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/UPGRADING.md @@ -0,0 +1,1642 @@ +Upgrading Grape +=============== + +### Upgrading to >= 2.3.0 + +### `content_type` vs `api.format` inside API + +Before 2.3.0, `content_type` had priority over `env['api.format']` when set in an API, which was incorrect. The priority has been flipped and `env['api.format']` will be checked first. +In addition, the function `api_format` has been added. Instead of setting `env['api.format']` directly, you can call `api_format`. +See [#2506](https://github.com/ruby-grape/grape/pull/2506) for more information. + +#### Remove Deprecated Methods and Options + +- Deprecated `file` method has been removed. Use `send_file` or `stream`. +See [#2500](https://github.com/ruby-grape/grape/pull/2500) for more information. + +- The `except` and `proc` options have been removed from the `values` validator. Use `except_values` validator or assign `proc` directly to `values`. +See [#2501](https://github.com/ruby-grape/grape/pull/2501) for more information. + +- `Passing an options hash and a block to 'desc'` deprecation has been removed. Move all hash options to block instead. +See [#2502](https://github.com/ruby-grape/grape/pull/2502) for more information. + +### Upgrading to >= 2.2.0 + +### `Length` validator + +After Grape 2.2.0, `length` validator will only take effect for parameters with types that support `#length` method, will not throw `ArgumentError` exception. + +See [#2464](https://github.com/ruby-grape/grape/pull/2464) for more information. + +### Upgrading to >= 2.1.0 + +#### Optional Builder + +The `builder` gem dependency has been made optional as it's only used when generating XML. If your code does, add `builder` to your `Gemfile`. + +See [#2445](https://github.com/ruby-grape/grape/pull/2445) for more information. + +#### Deep Merging of Parameter Attributes + +Grape now uses `deep_merge` to combine parameter attributes within the `with` method. Previously, attributes defined at the parameter level would override those defined at the group level. +With deep merge, attributes are now combined, allowing for more detailed and nuanced API specifications. + +For example: + +```ruby +with(documentation: { in: 'body' }) do + optional :vault, documentation: { default: 33 } +end +``` + +Before it was equivalent to: + +```ruby +optional :vault, documentation: { default: 33 } +``` + +After it is an equivalent of: + +```ruby +optional :vault, documentation: { in: 'body', default: 33 } +``` + +See [#2432](https://github.com/ruby-grape/grape/pull/2432) for more information. + +#### Zeitwerk + +Grape's autoloader has been updated and it's now based on [Zeitwerk](https://github.com/fxn/zeitwerk). +If you MP (Monkey Patch) some files and you're not following the [file structure](https://github.com/fxn/zeitwerk?tab=readme-ov-file#file-structure), you might end up with a Zeitwerk error. + +See [#2363](https://github.com/ruby-grape/grape/pull/2363) for more information. + +#### Changes in rescue_from + +The `rack_response` method has been deprecated and the `error_response` method has been removed. Use `error!` instead. + +See [#2414](https://github.com/ruby-grape/grape/pull/2414) for more information. + +#### Change in parameters precedence + +When using together with `Grape::Extensions::Hash::ParamBuilder`, `route_param` takes higher precedence over a regular parameter defined with same name, which now matches the default param builder behavior. + +This was a regression introduced by [#2326](https://github.com/ruby-grape/grape/pull/2326) in Grape v1.8.0. + +```ruby +grape.configure do |config| + config.param_builder = Grape::Extensions::Hash::ParamBuilder +end + +params do + requires :foo, type: String +end +route_param :foo do + get do + { value: params[:foo] } + end +end +``` + +Request: + +```bash +curl -X POST -H "Content-Type: application/json" localhost:9292/bar -d '{"foo": "baz"}' +``` + +Response prior to v1.8.0: + +```json +{ + "value": "bar" +} +``` + +v1.8.0..v2.0.0: + +```json +{ + "value": "baz" +} +``` + +v2.1.0+: + +```json +{ + "value": "bar" +} +``` + +See [#2378](https://github.com/ruby-grape/grape/pull/2378) for details. + +#### Grape::Router::Route.route_xxx methods have been removed + +- `route_method` is accessible through `request_method` +- `route_path` is accessible through `path` +- Any other `route_xyz` are accessible through `options[xyz]` + +#### Instance variables scope + +Due to the changes done in [#2377](https://github.com/ruby-grape/grape/pull/2377), the instance variables defined inside each of the endpoints (or inside a `before` validator) are now accessible inside the `rescue_from`. The behavior of the instance variables was undefined until `2.1.0`. + +If you were using the same variable name defined inside an endpoint or `before` validator inside a `rescue_from` handler, you need to take in mind that you can start getting different values or you can be overriding values. + +Before: +```ruby +class TwitterAPI < Grape::API + before do + @var = 1 + end + + get '/' do + puts @var # => 1 + raise + end + + rescue_from :all do + puts @var # => nil + end +end +``` + +After: +```ruby +class TwitterAPI < Grape::API + before do + @var = 1 + end + + get '/' do + puts @var # => 1 + raise + end + + rescue_from :all do + puts @var # => 1 + end +end +``` + +#### Recognizing Path + +Grape now considers the types of the configured `route_params` in order to determine the endpoint that matches with the performed request. + +So taking into account this `Grape::API` class + +```ruby +class Books < Grape::API + resource :books do + route_param :id, type: Integer do + # GET /books/:id + get do + #... + end + end + + resource :share do + # POST /books/share + post do + # .... + end + end + end +end +``` + +Before: +```ruby +API.recognize_path '/books/1' # => /books/:id +API.recognize_path '/books/share' # => /books/:id +API.recognize_path '/books/other' # => /books/:id +``` + +After: +```ruby +API.recognize_path '/books/1' # => /books/:id +API.recognize_path '/books/share' # => /books/share +API.recognize_path '/books/other' # => nil +``` + +This implies that before this changes, when you performed `/books/other` and it matched with the `/books/:id` endpoint, you get a `400 Bad Request` response because the type of the provided `:id` param was not an `Integer`. However, after upgrading to version `2.1.0` you will get a `404 Not Found` response, because there is not a defined endpoint that matches with `/books/other`. + +See [#2379](https://github.com/ruby-grape/grape/pull/2379) for more information. + +### Upgrading to >= 2.0.0 + +#### Headers + +As per [rack/rack#1592](https://github.com/rack/rack/issues/1592) Rack 3 is following the HTTP/2+ semantics which require header names to be lower case. To avoid compatibility issues, starting with Grape 1.9.0, headers will be cased based on what version of Rack you are using. + +Given this request: + +```shell +curl -H "Content-Type: application/json" -H "Secret-Password: foo" ... +``` + +If you are using Rack 3 in your application then the headers will be set to: + +```ruby +{ "content-type" => "application/json", "secret-password" => "foo"} +``` + +This means if you are checking for header values in your application, you would need to change your code to use downcased keys. + +```ruby +get do + # This would use headers['Secret-Password'] in Rack < 3 + error!('Unauthorized', 401) unless headers['secret-password'] == 'swordfish' +end +``` + +See [#2355](https://github.com/ruby-grape/grape/pull/2355) for more information. + +#### Digest auth deprecation + +Digest auth has been removed along with the deprecation of `Rack::Auth::Digest` in Rack 3. + +See [#2294](https://github.com/ruby-grape/grape/issues/2294) for more information. + +### Upgrading to >= 1.7.0 + +#### Exceptions renaming + +The following exceptions has been renamed for consistency through exceptions naming : + +* `MissingGroupTypeError` => `MissingGroupType` +* `UnsupportedGroupTypeError` => `UnsupportedGroupType` + +See [#2227](https://github.com/ruby-grape/grape/pull/2227) for more information. + +#### Handling Multipart Limit Errors + +Rack supports a configurable limit on the number of files created from multipart parameters (`Rack::Utils.multipart_part_limit`) and raises an error if params are received that create too many files. If you were handling the Rack error directly, Grape now wraps that error in `Grape::Execeptions::TooManyMultipartFiles`. Additionally, Grape will return a 413 status code if the exception goes unhandled. + +### Upgrading to >= 1.6.0 + +#### Parameter renaming with :as + +Prior to 1.6.0 the [parameter renaming](https://github.com/ruby-grape/grape#renaming) with `:as` was directly touching the request payload ([`#params`](https://github.com/ruby-grape/grape#parameters)) while duplicating the old and the new key to be both available in the hash. This allowed clients to bypass any validation in case they knew the internal name of the parameter. Unfortunately, in combination with [grape-swagger](https://github.com/ruby-grape/grape-swagger) the internal name (name set with `:as`) of the parameters were documented. + +This behavior was fixed. Parameter renaming is now done when using the [`#declared(params)`](https://github.com/ruby-grape/grape#declared) parameters helper. This stops confusing validation/coercion behavior. + +Here comes an illustration of the old and new behaviour as code: + +```ruby +# (1) Rename a to b, while client sends +a+ +optional :a, type: Integer, as: :b +params = { a: 1 } +declared(params, include_missing: false) +# expected => { b: 1 } +# actual => { b: 1 } + +# (2) Rename a to b, while client sends +b+ +optional :a, type: Integer, as: :b, values: [1, 2, 3] +params = { b: '5' } +declared(params, include_missing: false) +# expected => { } (>= 1.6.0) +# actual => { b: '5' } (uncasted, unvalidated, <= 1.5.3) +``` + +Another implication of this change is the dependent parameter resolution. Prior to 1.6.0 the following code produced a `Grape::Exceptions::UnknownParameter` because `:a` was replaced by `:b`: + +```ruby +params do + optional :a, as: :b + given :a do # (<= 1.5.3 you had to reference +:b+ here to make it work) + requires :c + end +end +``` + +This code now works without any errors, as the renaming is just an internal behaviour of the `#declared(params)` parameter helper. + +See [#2189](https://github.com/ruby-grape/grape/pull/2189) for more information. + +### Upgrading to >= 1.5.3 + +#### Nil value and coercion + +Prior to 1.2.5 version passing a `nil` value for a parameter with a custom coercer would invoke the coercer, and not passing a parameter would not invoke it. +This behavior was not tested or documented. Version 1.3.0 quietly changed this behavior, in that `nil` values skipped the coercion. Version 1.5.3 fixes and documents this as follows: + +```ruby +class Api < Grape::API + params do + optional :value, type: Integer, coerce_with: ->(val) { val || 0 } + end + + get 'example' do + params[:my_param] + end + get '/example', params: { value: nil } + # 1.5.2 = nil + # 1.5.3 = 0 + get '/example', params: {} + # 1.5.2 = nil + # 1.5.3 = nil +end +``` +See [#2164](https://github.com/ruby-grape/grape/pull/2164) for more information. + +### Upgrading to >= 1.5.1 + +#### Dependent params + +If you use [dependent params](https://github.com/ruby-grape/grape#dependent-parameters) with +`Grape::Extensions::Hash::ParamBuilder`, make sure a parameter to be dependent on is set as a Symbol. +If a String is given, a parameter that other parameters depend on won't be found even if it is present. + +_Correct_: +```ruby +given :matrix do + # dependent params +end +``` + +_Wrong_: +```ruby +given 'matrix' do + # dependent params +end +``` + +### Upgrading to >= 1.5.0 + +Prior to 1.3.3, the `declared` helper would always return the complete params structure if `include_missing=true` was set. In 1.3.3 a regression was introduced such that a missing Hash with or without nested parameters would always resolve to `{}`. + +In 1.5.0 this behavior is reverted, so the whole params structure will always be available via `declared`, regardless of whether any params are passed. + +The following rules now apply to the `declared` helper when params are missing and `include_missing=true`: + +* Hash params with children will resolve to a Hash with keys for each declared child. +* Hash params with no children will resolve to `{}`. +* Set params will resolve to `Set.new`. +* Array params will resolve to `[]`. +* All other params will resolve to `nil`. + +#### Example + +```ruby +class Api < Grape::API + params do + optional :outer, type: Hash do + optional :inner, type: Hash do + optional :value, type: String + end + end + end + get 'example' do + declared(params, include_missing: true) + end +end +``` + +``` +get '/example' +# 1.3.3 = {} +# 1.5.0 = {outer: {inner: {value:null}}} +``` + +For more information see [#2103](https://github.com/ruby-grape/grape/pull/2103). + +### Upgrading to >= 1.4.0 + +#### Reworking stream and file and un-deprecating stream like-objects + +Previously in 0.16 stream-like objects were deprecated. This release restores their functionality for use-cases other than file streaming. + +This release deprecated `file` in favor of `sendfile` to better document its purpose. + +To deliver a file via the Sendfile support in your web server and have the Rack::Sendfile middleware enabled. See [`Rack::Sendfile`](https://www.rubydoc.info/gems/rack/Rack/Sendfile). +```ruby +class API < Grape::API + get '/' do + sendfile '/path/to/file' + end +end +``` + +Use `stream` to stream file content in chunks. + +```ruby +class API < Grape::API + get '/' do + stream '/path/to/file' + end +end +``` + +Or use `stream` to stream other kinds of content. In the following example a streamer class +streams paginated data from a database. + +```ruby +class MyObject + attr_accessor :result + + def initialize(query) + @result = query + end + + def each + yield '[' + # Do paginated DB fetches and return each page formatted + first = false + result.find_in_batches do |records| + yield process_records(records, first) + first = false + end + yield ']' + end + + def process_records(records, first) + buffer = +'' + buffer << ',' unless first + buffer << records.map(&:to_json).join(',') + buffer + end +end + +class API < Grape::API + get '/' do + stream MyObject.new(Sprocket.all) + end +end +``` + +### Upgrading to >= 1.3.3 + +#### Nil values for structures + +Nil values have always been a special case when dealing with types, especially with the following structures: + +- Array +- Hash +- Set + +The behavior for these structures has changed throughout the latest releases. For example: + +```ruby +class Api < Grape::API + params do + require :my_param, type: Array[Integer] + end + + get 'example' do + params[:my_param] + end + get '/example', params: { my_param: nil } + # 1.3.1 = [] + # 1.3.2 = nil +end +``` + +For now on, `nil` values stay `nil` values for all types, including arrays, sets and hashes. + +If you want to have the same behavior as 1.3.1, apply a `default` validator: + +```ruby +class Api < Grape::API + params do + require :my_param, type: Array[Integer], default: [] + end + + get 'example' do + params[:my_param] + end + get '/example', params: { my_param: nil } # => [] +end +``` + +#### Default validator + +Default validator is now applied for `nil` values. + +```ruby +class Api < Grape::API + params do + requires :my_param, type: Integer, default: 0 + end + + get 'example' do + params[:my_param] + end + get '/example', params: { my_param: nil } #=> before: nil, after: 0 +end +``` + +### Upgrading to >= 1.3.0 + +You will need to upgrade to this version if you depend on `rack >= 2.1.0`. + +#### Ruby + +After adding dry-types, Ruby 2.4 or newer is required. + +#### Coercion + +[Virtus](https://github.com/solnic/virtus) has been replaced by [dry-types](https://dry-rb.org/gems/dry-types/1.2/) for parameter coercion. If your project depends on Virtus outside of Grape, explicitly add it to your `Gemfile`. + +Here's an example of how to migrate a custom type from Virtus to dry-types: + +```ruby +# Legacy Grape parser +class SecureUriType < Virtus::Attribute + def coerce(input) + URI.parse value + end + + def value_coerced?(input) + value.is_a? String + end +end + +params do + requires :secure_uri, type: SecureUri +end +``` + +To use dry-types, we need to: + +1. Remove the inheritance of `Virtus::Attribute` +1. Rename `coerce` to `self.parse` +1. Rename `value_coerced?` to `self.parsed?` + +The custom type must have a class-level `parse` method to the model. A class-level `parsed?` is needed if the parsed type differs from the defined type. In the example below, since `SecureUri` is not the same as `URI::HTTPS`, `self.parsed?` is needed: + +```ruby +# New dry-types parser +class SecureUri + def self.parse(value) + URI.parse value + end + + def self.parsed?(value) + value.is_a? URI::HTTPS + end +end + +params do + requires :secure_uri, type: SecureUri +end +``` + +#### Coercing to `FalseClass` or `TrueClass` no longer works + +Previous Grape versions allowed this, though it wasn't documented: + +```ruby +requires :true_value, type: TrueClass +requires :bool_value, types: [FalseClass, TrueClass] +``` + +This is no longer supported, if you do this, your values will never be valid. Instead you should do this: + +```ruby +requires :true_value, type: Boolean # in your endpoint you should validate if this is actually `true` +requires :bool_value, type: Boolean +``` + +#### Ensure that Array types have explicit coercions + +Unlike Virtus, dry-types does not perform any implict coercions. If you have any uses of `Array[String]`, `Array[Integer]`, etc. be sure they use a `coerce_with` block. For example: + +```ruby +requires :values, type: Array[String] +``` + +It's quite common to pass a comma-separated list, such as `tag1,tag2` as `values`. Previously Virtus would implicitly coerce this to `Array(values)` so that `["tag1,tag2"]` would pass the type checks, but with `dry-types` the values are no longer coerced for you. To fix this, you might do: + +```ruby +requires :values, type: Array[String], coerce_with: ->(val) { val.split(',').map(&:strip) } +``` + +Likewise, for `Array[Integer]`, you might do: + +```ruby +requires :values, type: Array[Integer], coerce_with: ->(val) { val.split(',').map(&:strip).map(&:to_i) } +``` + +For more information see [#1920](https://github.com/ruby-grape/grape/pull/1920). + +### Upgrading to >= 1.2.4 + +#### Headers in `error!` call + +Headers in `error!` will be merged with `headers` hash. If any header need to be cleared on `error!` call, make sure to move it to the `after` block. + +```ruby +class SampleApi < Grape::API + before do + header 'X-Before-Header', 'before_call' + end + + get 'ping' do + header 'X-App-Header', 'on_call' + error! :pong, 400, 'X-Error-Details' => 'Invalid token' + end +end +``` +**Former behaviour** +```ruby + response.headers['X-Before-Header'] # => nil + response.headers['X-App-Header'] # => nil + response.headers['X-Error-Details'] # => Invalid token +``` + +**Current behaviour** +```ruby + response.headers['X-Before-Header'] # => 'before_call' + response.headers['X-App-Header'] # => 'on_call' + response.headers['X-Error-Details'] # => Invalid token +``` + +### Upgrading to >= 1.2.1 + +#### Obtaining the name of a mounted class + +In order to make obtaining the name of a mounted class simpler, we've delegated `.to_s` to `base.name` + +**Deprecated in 1.2.0** +```ruby + payload[:endpoint].options[:for].name +``` +**New** +```ruby + payload[:endpoint].options[:for].to_s +``` + +### Upgrading to >= 1.2.0 + +#### Changes in the Grape::API class + +##### Patching the class + +In an effort to make APIs re-mountable, The class `Grape::API` no longer refers to an API instance, rather, what used to be `Grape::API` is now `Grape::API::Instance` and `Grape::API` was replaced with a class that can contain several instances of `Grape::API`. + +This changes were done in such a way that no code-changes should be required. However, if experiencing problems, or relying on private methods and internal behaviour too deeply, it is possible to restore the prior behaviour by replacing the references from `Grape::API` to `Grape::API::Instance`. + +Note, this is particularly relevant if you are opening the class `Grape::API` for modification. + +**Deprecated** +```ruby +class Grape::API + # your patched logic + ... +end +``` +**New** +```ruby +class Grape::API::Instance + # your patched logic + ... +end +``` + +##### `name` (and other caveats) of the mounted API + +After the patch, the mounted API is no longer a Named class inheriting from `Grape::API`, it is an anonymous class which inherit from `Grape::API::Instance`. + +What this means in practice, is: + +- Generally: you can access the named class from the instance calling the getter `base`. +- In particular: If you need the `name`, you can use `base`.`name`. + +**Deprecated** + +```ruby + payload[:endpoint].options[:for].name +``` + +**New** + +```ruby + payload[:endpoint].options[:for].base.name +``` + +#### Changes in rescue_from returned object + +Grape will now check the object returned from `rescue_from` and ensure that it is a `Rack::Response`. That makes sure response is valid and avoids exposing service information. Change any code that invoked `Rack::Response.new(...).finish` in a custom `rescue_from` block to `Rack::Response.new(...)` to comply with the validation. + +```ruby +class Twitter::API < Grape::API + rescue_from :all do |e| + # version prior to 1.2.0 + Rack::Response.new([ e.message ], 500, { 'Content-type' => 'text/error' }).finish + # 1.2.0 version + Rack::Response.new([ e.message ], 500, { 'Content-type' => 'text/error' }) + end +end +``` + +See [#1757](https://github.com/ruby-grape/grape/pull/1757) and [#1776](https://github.com/ruby-grape/grape/pull/1776) for more information. + +### Upgrading to >= 1.1.0 + +#### Changes in HTTP Response Code for Unsupported Content Type + +For PUT, POST, PATCH, and DELETE requests where a non-empty body and a "Content-Type" header is supplied that is not supported by the Grape API, Grape will no longer return a 406 "Not Acceptable" HTTP status code and will instead return a 415 "Unsupported Media Type" so that the usage of HTTP status code falls more in line with the specification of [RFC 2616](https://www.ietf.org/rfc/rfc2616.txt). + +### Upgrading to >= 1.0.0 + +#### Changes in XML and JSON Parsers + +Grape no longer uses `multi_json` or `multi_xml` by default and uses `JSON` and `ActiveSupport::XmlMini` instead. This has no visible impact on JSON processing, but the default behavior of the XML parser has changed. For example, an XML POST containing `Bobby T.` was parsed as `Bobby T.` with `multi_xml`, and as now parsed as `{"__content__"=>"Bobby T."}` with `XmlMini`. + +If you were using `MultiJson.load`, `MultiJson.dump` or `MultiXml.parse`, you can substitute those with `Grape::Json.load`, `Grape::Json.dump`, `::Grape::Xml.parse`, or directly with `JSON.load`, `JSON.dump`, `XmlMini.parse`, etc. + +To restore previous behavior, add `multi_json` or `multi_xml` to your `Gemfile` and `require` it. + +See [#1623](https://github.com/ruby-grape/grape/pull/1623) for more information. + +#### Changes in Parameter Class + +The default class for `params` has changed from `Hashie::Mash` to `ActiveSupport::HashWithIndifferentAccess` and the `hashie` dependency has been removed. This means that by default you can no longer access parameters by method name. + +```ruby +class API < Grape::API + params do + optional :color, type: String + end + get do + params[:color] # use params[:color] instead of params.color + end +end +``` + +To restore the behavior of prior versions, add `hashie` to your `Gemfile` and `include Grape::Extensions::Hashie::Mash::ParamBuilder` in your API. + +```ruby +class API < Grape::API + include Grape::Extensions::Hashie::Mash::ParamBuilder + + params do + optional :color, type: String + end + get do + # params.color works + end +end +``` + +This behavior can also be overridden on individual parameter blocks using `build_with`. + +```ruby +params do + build_with Grape::Extensions::Hash::ParamBuilder + optional :color, type: String +end +``` + +If you're constructing your own `Grape::Request` in a middleware, you can pass different parameter handlers to create the desired `params` class with `build_params_with`. + +```ruby +def request + Grape::Request.new(env, build_params_with: Grape::Extensions::Hashie::Mash::ParamBuilder) +end +``` + +See [#1610](https://github.com/ruby-grape/grape/pull/1610) for more information. + +#### The `except`, `except_message`, and `proc` options of the `values` validator are deprecated. + +The new `except_values` validator should be used in place of the `except` and `except_message` options of the `values` validator. + +Arity one Procs may now be used directly as the `values` option to explicitly test param values. + +**Deprecated** +```ruby +params do + requires :a, values: { value: 0..99, except: [3] } + requires :b, values: { value: 0..99, except: [3], except_message: 'not allowed' } + requires :c, values: { except: ['admin'] } + requires :d, values: { proc: -> (v) { v.even? } } +end +``` +**New** +```ruby +params do + requires :a, values: 0..99, except_values: [3] + requires :b, values: 0..99, except_values: { value: [3], message: 'not allowed' } + requires :c, except_values: ['admin'] + requires :d, values: -> (v) { v.even? } +end +``` + +See [#1616](https://github.com/ruby-grape/grape/pull/1616) for more information. + +### Upgrading to >= 0.19.1 + +#### DELETE now defaults to status code 200 for responses with a body, or 204 otherwise + +Prior to this version, DELETE requests defaulted to a status code of 204 No Content, even when the response included content. This behavior confused some clients and prevented the formatter middleware from running properly. As of this version, DELETE requests will only default to a 204 No Content status code if no response body is provided, and will default to 200 OK otherwise. + +Specifically, DELETE behaviour has changed as follows: + +- In versions < 0.19.0, all DELETE requests defaulted to a 200 OK status code. +- In version 0.19.0, all DELETE requests defaulted to a 204 No Content status code, even when content was included in the response. +- As of version 0.19.1, DELETE requests default to a 204 No Content status code, unless content is supplied, in which case they default to a 200 OK status code. + +To achieve the old behavior, one can specify the status code explicitly: + +```ruby +delete :id do + status 204 # or 200, for < 0.19.0 behavior + 'foo successfully deleted' +end +``` + +One can also use the new `return_no_content` helper to explicitly return a 204 status code and an empty body for any request type: + +```ruby +delete :id do + return_no_content + 'this will not be returned' +end +``` + +See [#1550](https://github.com/ruby-grape/grape/pull/1550) for more information. + +### Upgrading to >= 0.18.1 + +#### Changes in priority of :any routes + +Prior to this version, `:any` routes were searched after matching first route and 405 routes. This behavior has changed and `:any` routes are now searched before 405 processing. In the following example the `:any` route will match first when making a request with an unsupported verb. + +```ruby +post :example do + 'example' +end +route :any, '*path' do + error! :not_found, 404 +end + +get '/example' #=> before: 405, after: 404 +``` + +#### Removed param processing from built-in OPTIONS handler + +When a request is made to the built-in `OPTIONS` handler, only the `before` and `after` callbacks associated with the resource will be run. The `before_validation` and `after_validation` callbacks and parameter validations will be skipped. + +See [#1505](https://github.com/ruby-grape/grape/pull/1505) for more information. + +#### Changed endpoint params validation + +Grape now correctly returns validation errors for all params when multiple params are passed to a requires. +The following code will return `one is missing, two is missing` when calling the endpoint without parameters. + +```ruby +params do + requires :one, :two +end +``` + +Prior to this version the response would be `one is missing`. + +See [#1510](https://github.com/ruby-grape/grape/pull/1510) for more information. + +#### The default status code for DELETE is now 204 instead of 200. + +Breaking change: Sets the default response status code for a delete request to 204. A status of 204 makes the response more distinguishable and therefore easier to handle on the client side, particularly because a DELETE request typically returns an empty body as the resource was deleted or voided. + +To achieve the old behavior, one has to set it explicitly: +```ruby +delete :id do + status 200 + 'foo successfully deleted' +end +``` + +For more information see: [#1532](https://github.com/ruby-grape/grape/pull/1532). + +### Upgrading to >= 0.17.0 + +#### Removed official support for Ruby < 2.2.2 + +Grape is no longer automatically tested against versions of Ruby prior to 2.2.2. This is because of its dependency on activesupport which, with version 5.0.0, now requires at least Ruby 2.2.2. + +See [#1441](https://github.com/ruby-grape/grape/pull/1441) for nmore information. + +#### Changed priority of `rescue_from` clauses applying + +The `rescue_from` clauses declared inside a namespace would take a priority over ones declared in the root scope. +This could possibly affect those users who use different `rescue_from` clauses in root scope and in namespaces. + +See [#1405](https://github.com/ruby-grape/grape/pull/1405) for more information. + +#### Helper methods injected inside `rescue_from` in middleware + +Helper methods are injected inside `rescue_from` may cause undesirable effects. For example, definining a helper method called `error!` will take precendence over the built-in `error!` method and should be renamed. + +See [#1451](https://github.com/ruby-grape/grape/issues/1451) for an example. + +### Upgrading to >= 0.16.0 + +#### Replace rack-mount with new router + +The `Route#route_xyz` methods have been deprecated since 0.15.1. + +Please use `Route#xyz` instead. + +Note that the `Route#route_method` was replaced by `Route#request_method`. + +The following code would work correctly. + +```ruby +TwitterAPI::versions # yields [ 'v1', 'v2' ] +TwitterAPI::routes # yields an array of Grape::Route objects +TwitterAPI::routes[0].version # => 'v1' +TwitterAPI::routes[0].description # => 'Includes custom settings.' +TwitterAPI::routes[0].settings[:custom] # => { key: 'value' } + +TwitterAPI::routes[0].request_method # => 'GET' +``` + +#### `file` method accepts path to file + +Now to serve files via Grape just pass the path to the file. Functionality with FileStreamer-like objects is deprecated. + +Please, replace your FileStreamer-like objects with paths of served files. + +Old style: + +```ruby +class FileStreamer + def initialize(file_path) + @file_path = file_path + end + + def each(&blk) + File.open(@file_path, 'rb') do |file| + file.each(10, &blk) + end + end +end + +# ... + +class API < Grape::API + get '/' do + file FileStreamer.new('/path/to/file') + end +end +``` + +New style: + +```ruby +class API < Grape::API + get '/' do + file '/path/to/file' + end +end +``` + +### Upgrading to >= 0.15.0 + +#### Changes to availability of `:with` option of `rescue_from` method + +The `:with` option of `rescue_from` does not accept value except Proc, String or Symbol now. + +If you have been depending the old behavior, you should use lambda block instead. + +```ruby +class API < Grape::API + rescue_from :all, with: -> { Rack::Response.new('rescued with a method', 400) } +end +``` + +#### Changes to behavior of `after` method of middleware on error + +The `after` method of the middleware is now also called on error. The following code would work correctly. + +```ruby +class ErrorMiddleware < Grape::Middleware::Base + def after + return unless @app_response && @app_response[0] == 500 + env['rack.logger'].debug("Raised error on #{env['PATH_INFO']}") + end +end +``` + +See [#1147](https://github.com/ruby-grape/grape/issues/1147) and [#1240](https://github.com/ruby-grape/grape/issues/1240) for discussion of the issues. + +A warning will be logged if an exception is raised in an `after` callback, which points you to middleware that was not called in the previous version and is called now. + +``` +caught error of type NoMethodError in after callback inside Api::Middleware::SomeMiddleware : undefined method `headers' for nil:NilClass +``` + +See [#1285](https://github.com/ruby-grape/grape/pull/1285) for more information. + +#### Changes to Method Not Allowed routes + +A `405 Method Not Allowed` error now causes `Grape::Exceptions::MethodNotAllowed` to be raised, which will be rescued via `rescue_from :all`. Restore old behavior with the following error handler. + +```ruby +rescue_from Grape::Exceptions::MethodNotAllowed do |e| + error! e.message, e.status, e.headers +end +``` + +See [#1283](https://github.com/ruby-grape/grape/pull/1283) for more information. + +#### Changes to Grape::Exceptions::Validation parameters + +When raising `Grape::Exceptions::Validation` explicitly, replace `message_key` with `message`. + +For example, + +```ruby +fail Grape::Exceptions::Validation, params: [:oauth_token_secret], message_key: :presence +``` + +becomes + +```ruby +fail Grape::Exceptions::Validation, params: [:oauth_token_secret], message: :presence +``` + +See [#1295](https://github.com/ruby-grape/grape/pull/1295) for more information. + +### Upgrading to >= 0.14.0 + +#### Changes to availability of DSL methods in filters + +The `#declared` method of the route DSL is no longer available in the `before` filter. Using `declared` in a `before` filter will now raise `Grape::DSL::InsideRoute::MethodNotYetAvailable`. + +See [#1074](https://github.com/ruby-grape/grape/issues/1074) for discussion of the issue. + +#### Changes to header versioning and invalid header version handling + +Identical endpoints with different versions now work correctly. A regression introduced in Grape 0.11.0 caused all but the first-mounted version for such an endpoint to wrongly throw an `InvalidAcceptHeader`. As a side effect, requests with a correct vendor but invalid version can no longer be rescued from a `rescue_from` block. + +See [#1114](https://github.com/ruby-grape/grape/pull/1114) for more information. + +#### Bypasses formatters when status code indicates no content + +To be consistent with rack and it's handling of standard responses associated with no content, both default and custom formatters will now be bypassed when processing responses for status codes defined [by rack](https://github.com/rack/rack/blob/master/lib/rack/utils.rb#L567) + +See [#1190](https://github.com/ruby-grape/grape/pull/1190) for more information. + +#### Redirects respond as plain text with message + +`#redirect` now uses `text/plain` regardless of whether that format has been enabled. This prevents formatters from attempting to serialize the message body and allows for a descriptive message body to be provided - and optionally overridden - that better fulfills the theme of the HTTP spec. + +See [#1194](https://github.com/ruby-grape/grape/pull/1194) for more information. + +### Upgrading to >= 0.12.0 + +#### Changes in middleware + +The Rack response object is no longer converted to an array by the formatter, enabling streaming. If your custom middleware is accessing `@app_response`, update it to expect a `Rack::Response` instance instead of an array. + +For example, + +```ruby +class CacheBusterMiddleware < Grape::Middleware::Base + def after + @app_response[1]['Expires'] = Time.at(0).utc.to_s + @app_response + end +end +``` + +becomes + +```ruby +class CacheBusterMiddleware < Grape::Middleware::Base + def after + @app_response.headers['Expires'] = Time.at(0).utc.to_s + @app_response + end +end +``` + +See [#1029](https://github.com/ruby-grape/grape/pull/1029) for more information. + +There is a known issue because of this change. When Grape is used with an older than 1.2.4 version of [warden](https://github.com/hassox/warden) there may be raised the following exception having the [rack-mount](https://github.com/jm/rack-mount) gem's lines as last ones in the backtrace: + +``` +NoMethodError: undefined method `[]' for nil:NilClass +``` + +The issue can be solved by upgrading warden to 1.2.4 version. + +See [#1151](https://github.com/ruby-grape/grape/issues/1151) for more information. + +#### Changes in present + +Using `present` with objects that responded to `merge` would cause early evaluation of the represented object, with unexpected side-effects, such as missing parameters or environment within rendering code. Grape now only merges represented objects with a previously rendered body, usually when multiple `present` calls are made in the same route. + +See [grape-with-roar#5](https://github.com/dblock/grape-with-roar/issues/5) and [#1023](https://github.com/ruby-grape/grape/issues/1023). + +#### Changes to regexp validator + +Parameters with `nil` value will now pass `regexp` validation. To disallow `nil` value for an endpoint, add `allow_blank: false`. + +```ruby +params do + requires :email, allow_blank: false, regexp: /.+@.+/ +end +``` + +See [#957](https://github.com/ruby-grape/grape/pull/957) for more information. + +#### Replace error_response with error! in rescue_from blocks + +Note: `error_response` is being deprecated, not removed. + +```ruby +def error!(message, status = options[:default_status], headers = {}, backtrace = []) + headers = { 'Content-Type' => content_type }.merge(headers) + rack_response(format_message(message, backtrace), status, headers) +end +``` + +For example, + +``` +error_response({ message: { message: 'No such page.', id: 'missing_page' }, status: 404, headers: { 'Content-Type' => 'api/error' }) +``` + +becomes + +``` +error!({ message: 'No such page.', id: 'missing_page' }, 404, { 'Content-Type' => 'api/error' }) +``` + +`error!` also supports just passing a message. `error!('Server error.')` and `format: :json` returns the following JSON response + +``` +{ 'error': 'Server error.' } +``` + +with a status code of 500 and a Content Type of text/error. + +Optionally, also replace `Rack::Response.new` with `error!.` +The following are equivalent: + +``` +Rack::Response.new([ e.message ], 500, { "Content-type" => "text/error" }).finish +error!(e) +``` + +See [#889](https://github.com/ruby-grape/grape/issues/889) for more information. + +#### Changes to routes when using `format` + +Version 0.10.0 has introduced a change via [#809](https://github.com/ruby-grape/grape/pull/809) whereas routes no longer got file-type suffixes added if you declared a single API `format`. This has been reverted, it's now again possible to call API with proper suffix when single `format` is defined: + +```ruby +class API < Grape::API + format :json + + get :hello do + { hello: 'world' } + end +end +``` + +Will respond with JSON to `/hello` **and** `/hello.json`. + +Will respond with 404 to `/hello.xml`, `/hello.txt` etc. + +See the [#1001](https://github.com/ruby-grape/grape/pull/1001) and [#914](https://github.com/ruby-grape/grape/issues/914) for more info. + +### Upgrading to >= 0.11.0 + +#### Added Rack 1.6.0 support + +Grape now supports, but doesn't require Rack 1.6.0. If you encounter an issue with parsing requests larger than 128KB, explictly require Rack 1.6.0 in your Gemfile. + +```ruby +gem 'rack', '~> 1.6.0' +``` + +See [#559](https://github.com/ruby-grape/grape/issues/559) for more information. + +#### Removed route_info + +Key route_info is excluded from params. + +See [#879](https://github.com/ruby-grape/grape/pull/879) for more information. + + +#### Fix callbacks within a version block + +Callbacks defined in a version block are only called for the routes defined in that block. This was a regression introduced in Grape 0.10.0, and is fixed in this version. + +See [#901](https://github.com/ruby-grape/grape/pull/901) for more information. + + +#### Make type of group of parameters required + +Groups of parameters now require their type to be set explicitly as Array or Hash. +Not setting the type now results in MissingGroupTypeError, unsupported type will raise UnsupportedTypeError. + +See [#886](https://github.com/ruby-grape/grape/pull/886) for more information. + +### Upgrading to >= 0.10.1 + +#### Changes to `declared(params, include_missing: false)` + +Attributes with `nil` values or with values that evaluate to `false` are no longer considered *missing* and will be returned when `include_missing` is set to `false`. + +See [#864](https://github.com/ruby-grape/grape/pull/864) for more information. + +### Upgrading to >= 0.10.0 + +#### Changes to content-types + +The following content-types have been removed: + +* atom (application/atom+xml) +* rss (application/rss+xml) +* jsonapi (application/jsonapi) + +This is because they have never been properly supported. + +#### Changes to desc + +New block syntax: + +Former: + +```ruby + desc "some descs", + detail: 'more details', + entity: API::Entities::Entity, + params: API::Entities::Status.documentation, + named: 'a name', + headers: [XAuthToken: { + description: 'Valdates your identity', + required: true + } + get nil, http_codes: [ + [401, 'Unauthorized', API::Entities::BaseError], + [404, 'not found', API::Entities::Error] + ] do +``` + +Now: + +```ruby +desc "some descs" do + detail 'more details' + params API::Entities::Status.documentation + success API::Entities::Entity + failure [ + [401, 'Unauthorized', API::Entities::BaseError], + [404, 'not found', API::Entities::Error] + ] + named 'a name' + headers [ + XAuthToken: { + description: 'Valdates your identity', + required: true + }, + XOptionalHeader: { + description: 'Not really needed', + required: false + } + ] +end +``` + +#### Changes to Route Options and Descriptions + +A common hack to extend Grape with custom DSL methods was manipulating `@last_description`. + +``` ruby +module Grape + module Extensions + module SortExtension + def sort(value) + @last_description ||= {} + @last_description[:sort] ||= {} + @last_description[:sort].merge! value + value + end + end + + Grape::API.extend self + end +end +``` + +You could access this value from within the API with `route.route_sort` or, more generally, via `env['api.endpoint'].options[:route_options][:sort]`. + +This will no longer work, use the documented and supported `route_setting`. + +``` ruby +module Grape + module Extensions + module SortExtension + def sort(value) + route_setting :sort, sort: value + value + end + end + + Grape::API.extend self + end +end +``` + +To retrieve this value at runtime from within an API, use `env['api.endpoint'].route_setting(:sort)` and when introspecting a mounted API, use `route.route_settings[:sort]`. + +#### Accessing Class Variables from Helpers + +It used to be possible to fetch an API class variable from a helper function. For example: + +```ruby +@@static_variable = 42 + +helpers do + def get_static_variable + @@static_variable + end +end + +get do + get_static_variable +end +``` + +This will no longer work. Use a class method instead of a helper. + +```ruby +@@static_variable = 42 + +def self.get_static_variable + @@static_variable +end + +get do + get_static_variable +end +``` + +For more information see [#836](https://github.com/ruby-grape/grape/issues/836). + +#### Changes to Custom Validators + +To implement a custom validator, you need to inherit from `Grape::Validations::Base` instead of `Grape::Validations::Validator`. + +For more information see [Custom Validators](https://github.com/ruby-grape/grape#custom-validators) in the documentation. + +#### Changes to Raising Grape::Exceptions::Validation + +In previous versions raising `Grape::Exceptions::Validation` required a single `param`. + +```ruby +raise Grape::Exceptions::Validation, param: :id, message_key: :presence +``` + +The `param` argument has been deprecated and is now an array of `params`, accepting multiple values. + +```ruby +raise Grape::Exceptions::Validation, params: [:id], message_key: :presence +``` + +#### Changes to routes when using `format` + +Routes will no longer get file-type suffixes added if you declare a single API `format`. For example, + +```ruby +class API < Grape::API + format :json + + get :hello do + { hello: 'world' } + end +end +``` + +Pre-0.10.0, this would respond with JSON to `/hello`, `/hello.json`, `/hello.xml`, `/hello.txt`, etc. + +Now, this will only respond with JSON to `/hello`, but will be a 404 when trying to access `/hello.json`, `/hello.xml`, `/hello.txt`, etc. + +If you declare further `content_type`s, this behavior will be circumvented. For example, the following API will respond with JSON to `/hello`, `/hello.json`, `/hello.xml`, `/hello.txt`, etc. + +```ruby +class API < Grape::API + format :json + content_type :json, 'application/json' + + get :hello do + { hello: 'world' } + end +end +``` + +See the [the updated API Formats documentation](https://github.com/ruby-grape/grape#api-formats) and [#809](https://github.com/ruby-grape/grape/pull/809) for more info. + +#### Changes to Evaluation of Permitted Parameter Values + +Permitted and default parameter values are now only evaluated lazily for each request when declared as a proc. The following code would raise an error at startup time. + +```ruby +params do + optional :v, values: -> { [:x, :y] }, default: -> { :z } +end +``` + +Remove the proc to get the previous behavior. + +```ruby +params do + optional :v, values: [:x, :y], default: :z +end +``` + +See [#801](https://github.com/ruby-grape/grape/issues/801) for more information. + +#### Changes to version + +If version is used with a block, the callbacks defined within that version block are not scoped to that individual block. In other words, the callback would be inherited by all versions blocks that follow the first one e.g + +```ruby +class API < Grape::API + resource :foo do + version 'v1', :using => :path do + before do + @output ||= 'hello1' + end + get '/' do + @output += '-v1' + end + end + + version 'v2', :using => :path do + before do + @output ||= 'hello2' + end + get '/:id' do + @output += '-v2' + end + end + end +end +``` + +when making a API call `GET /foo/v2/1`, the API would set instance variable `@output` to `hello1-v2` + +See [#898](https://github.com/ruby-grape/grape/issues/898) for more information. + + +### Upgrading to >= 0.9.0 + +#### Changes in Authentication + +The following middleware classes have been removed: + +* `Grape::Middleware::Auth::Basic` +* `Grape::Middleware::Auth::Digest` +* `Grape::Middleware::Auth::OAuth2` + +When you use theses classes directly like: + +```ruby + module API + class Root < Grape::API + class Protected < Grape::API + use Grape::Middleware::Auth::OAuth2, + token_class: 'AccessToken', + parameter: %w(access_token api_key) + +``` + +you have to replace these classes. + +As replacement can be used + +* `Grape::Middleware::Auth::Basic` => [`Rack::Auth::Basic`](https://github.com/rack/rack/blob/master/lib/rack/auth/basic.rb) +* `Grape::Middleware::Auth::Digest` => [`Rack::Auth::Digest::MD5`](https://github.com/rack/rack/blob/master/lib/rack/auth/digest/md5.rb) +* `Grape::Middleware::Auth::OAuth2` => [warden-oauth2](https://github.com/opperator/warden-oauth2) or [rack-oauth2](https://github.com/nov/rack-oauth2) + +If this is not possible you can extract the middleware files from [grape v0.7.0](https://github.com/ruby-grape/grape/tree/v0.7.0/lib/grape/middleware/auth) and host these files within your application + +See [#703](https://github.com/ruby-grape/Grape/pull/703) for more information. + +### Upgrading to >= 0.7.0 + +#### Changes in Exception Handling + +Assume you have the following exception classes defined. + +```ruby +class ParentError < StandardError; end +class ChildError < ParentError; end +``` + +In Grape <= 0.6.1, the `rescue_from` keyword only handled the exact exception being raised. The following code would rescue `ParentError`, but not `ChildError`. + +```ruby +rescue_from ParentError do |e| + # only rescue ParentError +end +``` + +This made it impossible to rescue an exception hieararchy, which is a more sensible default. In Grape 0.7.0 or newer, both `ParentError` and `ChildError` are rescued. + +```ruby +rescue_from ParentError do |e| + # rescue both ParentError and ChildError +end +``` + +To only rescue the base exception class, set `rescue_subclasses: false`. + +```ruby +rescue_from ParentError, rescue_subclasses: false do |e| + # only rescue ParentError +end +``` + +See [#544](https://github.com/ruby-grape/grape/pull/544) for more information. + + +#### Changes in the Default HTTP Status Code + +In Grape <= 0.6.1, the default status code returned from `error!` was 403. + +```ruby +error! "You may not reticulate this spline!" # yields HTTP error 403 +``` + +This was a bad default value, since 403 means "Forbidden". Change any call to `error!` that does not specify a status code to specify one. The new default value is a more sensible default of 500, which is "Internal Server Error". + +```ruby +error! "You may not reticulate this spline!", 403 # yields HTTP error 403 +``` + +You may also use `default_error_status` to change the global default. + +```ruby +default_error_status 400 +``` + +See [#525](https://github.com/ruby-grape/Grape/pull/525) for more information. + + +#### Changes in Parameter Declaration and Validation + +In Grape <= 0.6.1, `group`, `optional` and `requires` keywords with a block accepted either an `Array` or a `Hash`. + +```ruby +params do + requires :id, type: Integer + group :name do + requires :first_name + requires :last_name + end +end +``` + +This caused the ambiguity and unexpected errors described in [#543](https://github.com/ruby-grape/Grape/issues/543). + +In Grape 0.7.0, the `group`, `optional` and `requires` keywords take an additional `type` attribute which defaults to `Array`. This means that without a `type` attribute, these nested parameters will no longer accept a single hash, only an array (of hashes). + +Whereas in 0.6.1 the API above accepted the following json, it no longer does in 0.7.0. + +```json +{ + "id": 1, + "name": { + "first_name": "John", + "last_name" : "Doe" + } +} +``` + +The `params` block should now read as follows. + +```ruby +params do + requires :id, type: Integer + requires :name, type: Hash do + requires :first_name + requires :last_name + end +end +``` + +See [#545](https://github.com/ruby-grape/Grape/pull/545) for more information. + + +### Upgrading to 0.6.0 + +In Grape <= 0.5.0, only the first validation error was raised and processing aborted. Validation errors are now collected and a single `Grape::Exceptions::ValidationErrors` exception is raised. You can access the collection of validation errors as `.errors`. + +```ruby +rescue_from Grape::Exceptions::Validations do |e| + Rack::Response.new({ + status: 422, + message: e.message, + errors: e.errors + }.to_json, 422) +end +``` + +For more information see [#462](https://github.com/ruby-grape/grape/issues/462). diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/grape.gemspec b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/grape.gemspec new file mode 100644 index 00000000..a5d7c57a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/grape.gemspec @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +$LOAD_PATH.unshift File.expand_path('lib', __dir__) +require 'grape/version' + +Gem::Specification.new do |s| + s.name = 'grape' + s.version = Grape::VERSION + s.platform = Gem::Platform::RUBY + s.authors = ['Michael Bleigh'] + s.email = ['michael@intridea.com'] + s.homepage = 'https://github.com/ruby-grape/grape' + s.summary = 'A simple Ruby framework for building REST-like APIs.' + s.description = 'A Ruby framework for rapid API development with great conventions.' + s.license = 'MIT' + s.metadata = { + 'bug_tracker_uri' => 'https://github.com/ruby-grape/grape/issues', + 'changelog_uri' => "https://github.com/ruby-grape/grape/blob/v#{s.version}/CHANGELOG.md", + 'documentation_uri' => "https://www.rubydoc.info/gems/grape/#{s.version}", + 'source_code_uri' => "https://github.com/ruby-grape/grape/tree/v#{s.version}", + 'rubygems_mfa_required' => 'true' + } + + s.add_dependency 'activesupport', '>= 6' + s.add_dependency 'dry-types', '>= 1.1' + s.add_dependency 'mustermann-grape', '~> 1.1.0' + s.add_dependency 'rack', '>= 2' + s.add_dependency 'zeitwerk' + + s.files = Dir['lib/**/*', 'CHANGELOG.md', 'CONTRIBUTING.md', 'README.md', 'grape.png', 'UPGRADING.md', 'LICENSE', 'grape.gemspec'] + s.require_paths = ['lib'] + s.required_ruby_version = '>= 2.7.0' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/grape.png b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/grape.png new file mode 100644 index 00000000..97a0e1f8 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/grape.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape.rb new file mode 100644 index 00000000..ed6f9058 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +require 'logger' +require 'active_support' +require 'active_support/concern' +require 'active_support/configurable' +require 'active_support/version' +require 'active_support/isolated_execution_state' if ActiveSupport::VERSION::MAJOR > 6 +require 'active_support/core_ext/array/conversions' +require 'active_support/core_ext/array/extract_options' +require 'active_support/core_ext/array/wrap' +require 'active_support/core_ext/enumerable' +require 'active_support/core_ext/hash/conversions' +require 'active_support/core_ext/hash/deep_merge' +require 'active_support/core_ext/hash/except' +require 'active_support/core_ext/hash/indifferent_access' +require 'active_support/core_ext/hash/keys' +require 'active_support/core_ext/hash/reverse_merge' +require 'active_support/core_ext/hash/slice' +require 'active_support/core_ext/module/delegation' +require 'active_support/core_ext/object/blank' +require 'active_support/core_ext/object/deep_dup' +require 'active_support/core_ext/object/duplicable' +require 'active_support/core_ext/string/output_safety' +require 'active_support/core_ext/string/exclude' +require 'active_support/deprecation' +require 'active_support/inflector' +require 'active_support/ordered_options' +require 'active_support/notifications' + +require 'English' +require 'bigdecimal' +require 'date' +require 'dry-types' +require 'forwardable' +require 'json' +require 'mustermann/grape' +require 'pathname' +require 'rack' +require 'rack/auth/basic' +require 'rack/builder' +require 'rack/head' +require 'set' +require 'singleton' +require 'zeitwerk' + +loader = Zeitwerk::Loader.for_gem +loader.inflector.inflect( + 'api' => 'API', + 'dsl' => 'DSL' +) +railtie = "#{__dir__}/grape/railtie.rb" +loader.do_not_eager_load(railtie) +loader.setup + +I18n.load_path << File.expand_path('grape/locale/en.yml', __dir__) + +module Grape + include ActiveSupport::Configurable + + def self.deprecator + @deprecator ||= ActiveSupport::Deprecation.new('2.0', 'Grape') + end + + configure do |config| + config.param_builder = Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder + config.compile_methods! + end +end + +# https://api.rubyonrails.org/classes/ActiveSupport/Deprecation.html +# adding Grape.deprecator to Rails App if any +require 'grape/railtie' if defined?(Rails::Railtie) && ActiveSupport.gem_version >= Gem::Version.new('7.1') +loader.eager_load diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/api.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/api.rb new file mode 100644 index 00000000..54a4ca89 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/api.rb @@ -0,0 +1,201 @@ +# frozen_string_literal: true + +module Grape + # The API class is the primary entry point for creating Grape APIs. Users + # should subclass this class in order to build an API. + class API + # Class methods that we want to call on the API rather than on the API object + NON_OVERRIDABLE = %i[call call! configuration compile! inherited].freeze + + class Boolean + def self.build(val) + return nil if val != true && val != false + + new + end + end + + class Instance + Boolean = Grape::API::Boolean + end + + class << self + attr_accessor :base_instance, :instances + + # Rather than initializing an object of type Grape::API, create an object of type Instance + def new(...) + base_instance.new(...) + end + + # When inherited, will create a list of all instances (times the API was mounted) + # It will listen to the setup required to mount that endpoint, and replicate it on any new instance + def inherited(api) + super + + api.initial_setup(self == Grape::API ? Grape::API::Instance : @base_instance) + api.override_all_methods! + end + + # Initialize the instance variables on the remountable class, and the base_instance + # an instance that will be used to create the set up but will not be mounted + def initial_setup(base_instance_parent) + @instances = [] + @setup = [] + @base_parent = base_instance_parent + @base_instance = mount_instance + end + + # Redefines all methods so that are forwarded to add_setup and be recorded + def override_all_methods! + (base_instance.methods - Class.methods - NON_OVERRIDABLE).each do |method_override| + define_singleton_method(method_override) do |*args, &block| + add_setup(method_override, *args, &block) + end + end + end + + # Configure an API from the outside. If a block is given, it'll pass a + # configuration hash to the block which you can use to configure your + # API. If no block is given, returns the configuration hash. + # The configuration set here is accessible from inside an API with + # `configuration` as normal. + def configure + config = @base_instance.configuration + if block_given? + yield config + self + else + config + end + end + + # This is the interface point between Rack and Grape; it accepts a request + # from Rack and ultimately returns an array of three values: the status, + # the headers, and the body. See [the rack specification] + # (http://www.rubydoc.info/github/rack/rack/master/file/SPEC) for more. + # NOTE: This will only be called on an API directly mounted on RACK + def call(...) + instance_for_rack.call(...) + end + + # The remountable class can have a configuration hash to provide some dynamic class-level variables. + # For instance, a description could be done using: `desc configuration[:description]` if it may vary + # depending on where the endpoint is mounted. Use with care, if you find yourself using configuration + # too much, you may actually want to provide a new API rather than remount it. + def mount_instance(opts = {}) + instance = Class.new(@base_parent) + instance.configuration = Grape::Util::EndpointConfiguration.new(opts[:configuration] || {}) + instance.base = self + replay_setup_on(instance) + instance + end + + # Replays the set up to produce an API as defined in this class, can be called + # on classes that inherit from Grape::API + def replay_setup_on(instance) + @setup.each do |setup_step| + replay_step_on(instance, setup_step) + end + end + + def respond_to?(method, include_private = false) + super || base_instance.respond_to?(method, include_private) + end + + def respond_to_missing?(method, include_private = false) + base_instance.respond_to?(method, include_private) + end + + def method_missing(method, *args, &block) + # If there's a missing method, it may be defined on the base_instance instead. + if respond_to_missing?(method) + base_instance.send(method, *args, &block) + else + super + end + end + + def compile! + instance_for_rack.compile! # See API::Instance.compile! + end + + private + + def instance_for_rack + if never_mounted? + base_instance + else + mounted_instances.first + end + end + + # Adds a new stage to the set up require to get a Grape::API up and running + def add_setup(method, *args, &block) + setup_step = { method: method, args: args, block: block } + @setup += [setup_step] + last_response = nil + @instances.each do |instance| + last_response = replay_step_on(instance, setup_step) + end + + # Updating all previously mounted classes in the case that new methods have been executed. + if method != :mount && @setup.any? + previous_mount_steps = @setup.select { |step| step[:method] == :mount } + previous_mount_steps.each do |mount_step| + refresh_mount_step = mount_step.merge(method: :refresh_mounted_api) + @setup += [refresh_mount_step] + @instances.each do |instance| + replay_step_on(instance, refresh_mount_step) + end + end + end + + last_response + end + + def replay_step_on(instance, setup_step) + return if skip_immediate_run?(instance, setup_step[:args]) + + args = evaluate_arguments(instance.configuration, *setup_step[:args]) + response = instance.send(setup_step[:method], *args, &setup_step[:block]) + if skip_immediate_run?(instance, [response]) + response + else + evaluate_arguments(instance.configuration, response).first + end + end + + # Skips steps that contain arguments to be lazily executed (on re-mount time) + def skip_immediate_run?(instance, args) + instance.base_instance? && + (any_lazy?(args) || args.any? { |arg| arg.is_a?(Hash) && any_lazy?(arg.values) }) + end + + def any_lazy?(args) + args.any? { |argument| argument.respond_to?(:lazy?) && argument.lazy? } + end + + def evaluate_arguments(configuration, *args) + args.map do |argument| + if argument.respond_to?(:lazy?) && argument.lazy? + argument.evaluate_from(configuration) + elsif argument.is_a?(Hash) + argument.transform_values { |value| evaluate_arguments(configuration, value).first } + elsif argument.is_a?(Array) + evaluate_arguments(configuration, *argument) + else + argument + end + end + end + + def never_mounted? + mounted_instances.empty? + end + + def mounted_instances + instances - [base_instance] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/api/helpers.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/api/helpers.rb new file mode 100644 index 00000000..00da38f8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/api/helpers.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module Grape + class API + module Helpers + include Grape::DSL::Helpers::BaseHelper + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/api/instance.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/api/instance.rb new file mode 100644 index 00000000..c6a60871 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/api/instance.rb @@ -0,0 +1,246 @@ +# frozen_string_literal: true + +module Grape + class API + # The API Instance class, is the engine behind Grape::API. Each class that inherits + # from this will represent a different API instance + class Instance + include Grape::DSL::API + + class << self + attr_reader :instance, :base + attr_accessor :configuration + + def given(conditional_option, &block) + evaluate_as_instance_with_configuration(block, lazy: true) if conditional_option && block + end + + def mounted(&block) + evaluate_as_instance_with_configuration(block, lazy: true) + end + + def base=(grape_api) + @base = grape_api + grape_api.instances << self + end + + def to_s + base&.to_s || super + end + + def base_instance? + self == base.base_instance + end + + # A class-level lock to ensure the API is not compiled by multiple + # threads simultaneously within the same process. + LOCK = Mutex.new + + # Clears all defined routes, endpoints, etc., on this API. + def reset! + reset_endpoints! + reset_routes! + reset_validations! + end + + # Parses the API's definition and compiles it into an instance of + # Grape::API. + def compile + @instance ||= new # rubocop:disable Naming/MemoizedInstanceVariableName + end + + # Wipe the compiled API so we can recompile after changes were made. + def change! + @instance = nil + end + + # This is the interface point between Rack and Grape; it accepts a request + # from Rack and ultimately returns an array of three values: the status, + # the headers, and the body. See [the rack specification] + # (http://www.rubydoc.info/github/rack/rack/master/file/SPEC) for more. + def call(env) + compile! + call!(env) + end + + # A non-synchronized version of ::call. + def call!(env) + instance.call(env) + end + + # (see #cascade?) + def cascade(value = nil) + if value.nil? + inheritable_setting.namespace_inheritable.key?(:cascade) ? !namespace_inheritable(:cascade).nil? : true + else + namespace_inheritable(:cascade, value) + end + end + + def compile! + return if instance + + LOCK.synchronize { compile unless instance } + end + + # see Grape::Router#recognize_path + def recognize_path(path) + compile! + instance.router.recognize_path(path) + end + + protected + + def prepare_routes + endpoints.map(&:routes).flatten + end + + # Execute first the provided block, then each of the + # block passed in. Allows for simple 'before' setups + # of settings stack pushes. + def nest(*blocks, &block) + blocks.compact! + if blocks.any? + evaluate_as_instance_with_configuration(block) if block + blocks.each { |b| evaluate_as_instance_with_configuration(b) } + reset_validations! + else + instance_eval(&block) + end + end + + def evaluate_as_instance_with_configuration(block, lazy: false) + lazy_block = Grape::Util::Lazy::Block.new do |configuration| + value_for_configuration = configuration + self.configuration = value_for_configuration.evaluate if value_for_configuration.respond_to?(:lazy?) && value_for_configuration.lazy? + response = instance_eval(&block) + self.configuration = value_for_configuration + response + end + if base && base_instance? && lazy + lazy_block + else + lazy_block.evaluate_from(configuration) + end + end + + def inherited(subclass) + super + subclass.reset! + subclass.logger = logger.clone + end + + def inherit_settings(other_settings) + top_level_setting.inherit_from other_settings.point_in_time_copy + + # Propagate any inherited params down to our endpoints, and reset any + # compiled routes. + endpoints.each do |e| + e.inherit_settings(top_level_setting.namespace_stackable) + e.reset_routes! + end + + reset_routes! + end + end + + attr_reader :router + + # Builds the routes from the defined endpoints, effectively compiling + # this API into a usable form. + def initialize + @router = Router.new + add_head_not_allowed_methods_and_options_methods + self.class.endpoints.each do |endpoint| + endpoint.mount_in(@router) + end + + @router.compile! + @router.freeze + end + + # Handle a request. See Rack documentation for what `env` is. + def call(env) + status, headers, response = @router.call(env) + unless cascade? + headers = Grape::Util::Header.new.merge(headers) + headers.delete(Grape::Http::Headers::X_CASCADE) + end + + [status, headers, response] + end + + # Some requests may return a HTTP 404 error if grape cannot find a matching + # route. In this case, Grape::Router adds a X-Cascade header to the response + # and sets it to 'pass', indicating to grape's parents they should keep + # looking for a matching route on other resources. + # + # In some applications (e.g. mounting grape on rails), one might need to trap + # errors from reaching upstream. This is effectivelly done by unsetting + # X-Cascade. Default :cascade is true. + def cascade? + return self.class.namespace_inheritable(:cascade) if self.class.inheritable_setting.namespace_inheritable.key?(:cascade) + return self.class.namespace_inheritable(:version_options)[:cascade] if self.class.namespace_inheritable(:version_options)&.key?(:cascade) + + true + end + + reset! + + private + + # For every resource add a 'OPTIONS' route that returns an HTTP 204 response + # with a list of HTTP methods that can be called. Also add a route that + # will return an HTTP 405 response for any HTTP method that the resource + # cannot handle. + def add_head_not_allowed_methods_and_options_methods + # The paths we collected are prepared (cf. Path#prepare), so they + # contain already versioning information when using path versioning. + all_routes = self.class.endpoints.map(&:routes).flatten + + # Disable versioning so adding a route won't prepend versioning + # informations again. + without_root_prefix_and_versioning { collect_route_config_per_pattern(all_routes) } + end + + def collect_route_config_per_pattern(all_routes) + routes_by_regexp = all_routes.group_by(&:pattern_regexp) + + # Build the configuration based on the first endpoint and the collection of methods supported. + routes_by_regexp.each_value do |routes| + last_route = routes.last # Most of the configuration is taken from the last endpoint + next if routes.any? { |route| route.request_method == '*' } + + allowed_methods = routes.map(&:request_method) + allowed_methods |= [Rack::HEAD] if !self.class.namespace_inheritable(:do_not_route_head) && allowed_methods.include?(Rack::GET) + + allow_header = self.class.namespace_inheritable(:do_not_route_options) ? allowed_methods : [Rack::OPTIONS] | allowed_methods + last_route.app.options[:options_route_enabled] = true unless self.class.namespace_inheritable(:do_not_route_options) || allowed_methods.include?(Rack::OPTIONS) + + @router.associate_routes(last_route.pattern, { + endpoint: last_route.app, + allow_header: allow_header + }) + end + end + + # Allows definition of endpoints that ignore the versioning configuration + # used by the rest of your API. + def without_root_prefix_and_versioning + old_version = self.class.namespace_inheritable(:version) + old_version_options = self.class.namespace_inheritable(:version_options) + old_root_prefix = self.class.namespace_inheritable(:root_prefix) + + self.class.namespace_inheritable_to_nil(:version) + self.class.namespace_inheritable_to_nil(:version_options) + self.class.namespace_inheritable_to_nil(:root_prefix) + + yield + + self.class.namespace_inheritable(:version, old_version) + self.class.namespace_inheritable(:version_options, old_version_options) + self.class.namespace_inheritable(:root_prefix, old_root_prefix) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/content_types.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/content_types.rb new file mode 100644 index 00000000..336948b9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/content_types.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module Grape + module ContentTypes + module_function + + # Content types are listed in order of preference. + DEFAULTS = { + xml: 'application/xml', + serializable_hash: 'application/json', + json: 'application/json', + binary: 'application/octet-stream', + txt: 'text/plain' + }.freeze + + MIME_TYPES = Grape::ContentTypes::DEFAULTS.except(:serializable_hash).invert.freeze + + def content_types_for(from_settings) + from_settings.presence || DEFAULTS + end + + def mime_types_for(from_settings) + return MIME_TYPES if from_settings == Grape::ContentTypes::DEFAULTS + + from_settings.each_with_object({}) do |(k, v), types_without_params| + # remove optional parameter + types_without_params[v.split(';', 2).first] = k + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/cookies.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/cookies.rb new file mode 100644 index 00000000..7afdb67c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/cookies.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +module Grape + class Cookies + def initialize + @cookies = {} + @send_cookies = {} + end + + def read(request) + request.cookies.each do |name, value| + @cookies[name.to_s] = value + end + end + + def write(header) + @cookies.select { |key, _value| @send_cookies[key] == true }.each do |name, value| + cookie_value = value.is_a?(Hash) ? value : { value: value } + Rack::Utils.set_cookie_header! header, name, cookie_value + end + end + + def [](name) + @cookies[name.to_s] + end + + def []=(name, value) + @cookies[name.to_s] = value + @send_cookies[name.to_s] = true + end + + def each(&block) + @cookies.each(&block) + end + + # see https://github.com/rack/rack/blob/main/lib/rack/utils.rb#L338-L340 + # rubocop:disable Layout/SpaceBeforeBrackets + def delete(name, **opts) + options = opts.merge(max_age: '0', value: '', expires: Time.at(0)) + self.[]=(name, options) + end + # rubocop:enable Layout/SpaceBeforeBrackets + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dry_types.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dry_types.rb new file mode 100644 index 00000000..5f1bc3cd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dry_types.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module Grape + module DryTypes + # Call +Dry.Types()+ to add all registered types to +DryTypes+ which is + # a container in this case. Check documentation for more information + # https://dry-rb.org/gems/dry-types/1.2/getting-started/ + include Dry.Types() + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/api.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/api.rb new file mode 100644 index 00000000..09126a5f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/api.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Grape + module DSL + module API + extend ActiveSupport::Concern + + include Grape::Middleware::Auth::DSL + + include Grape::DSL::Validations + include Grape::DSL::Callbacks + include Grape::DSL::Configuration + include Grape::DSL::Helpers + include Grape::DSL::Middleware + include Grape::DSL::RequestResponse + include Grape::DSL::Routing + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/callbacks.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/callbacks.rb new file mode 100644 index 00000000..43d4b18d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/callbacks.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +module Grape + module DSL + # Blocks can be executed before or after every API call, using `before`, `after`, + # `before_validation` and `after_validation`. + # + # Before and after callbacks execute in the following order: + # + # 1. `before` + # 2. `before_validation` + # 3. _validations_ + # 4. `after_validation` + # 5. _the API call_ + # 6. `after` + # + # Steps 4, 5 and 6 only happen if validation succeeds. + module Callbacks + extend ActiveSupport::Concern + + include Grape::DSL::Configuration + + module ClassMethods + # Execute the given block before validation, coercion, or any endpoint + # code is executed. + def before(&block) + namespace_stackable(:befores, block) + end + + # Execute the given block after `before`, but prior to validation or + # coercion. + def before_validation(&block) + namespace_stackable(:before_validations, block) + end + + # Execute the given block after validations and coercions, but before + # any endpoint code. + def after_validation(&block) + namespace_stackable(:after_validations, block) + end + + # Execute the given block after the endpoint code has run. + def after(&block) + namespace_stackable(:afters, block) + end + + # Allows you to specify a something that will always be executed after a call + # API call. Unlike the `after` block, this code will run even on + # unsuccesful requests. + # @example + # class ExampleAPI < Grape::API + # before do + # ApiLogger.start + # end + # finally do + # ApiLogger.close + # end + # end + # + # This will make sure that the ApiLogger is opened and closed around every + # request + # @param ensured_block [Proc] The block to be executed after every api_call + def finally(&block) + namespace_stackable(:finallies, block) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/configuration.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/configuration.rb new file mode 100644 index 00000000..6abf7596 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/configuration.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Grape + module DSL + module Configuration + extend ActiveSupport::Concern + + module ClassMethods + include Grape::DSL::Settings + include Grape::DSL::Logger + include Grape::DSL::Desc + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/desc.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/desc.rb new file mode 100644 index 00000000..2d315502 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/desc.rb @@ -0,0 +1,124 @@ +# frozen_string_literal: true + +module Grape + module DSL + module Desc + include Grape::DSL::Settings + + ROUTE_ATTRIBUTES = %i[ + body_name + consumes + default + deprecated + description + detail + entity + headers + hidden + http_codes + is_array + named + nickname + params + produces + security + summary + tags + ].freeze + + # Add a description to the next namespace or function. + # @param description [String] descriptive string for this endpoint + # or namespace + # @param options [Hash] other properties you can set to describe the + # endpoint or namespace. Optional. + # @option options :detail [String] additional detail about this endpoint + # @option options :summary [String] summary for this endpoint + # @option options :params [Hash] param types and info. normally, you set + # these via the `params` dsl method. + # @option options :entity [Grape::Entity] the entity returned upon a + # successful call to this action + # @option options :http_codes [Array[Array]] possible HTTP codes this + # endpoint may return, with their meanings, in a 2d array + # @option options :named [String] a specific name to help find this route + # @option options :body_name [String] override the autogenerated body name param + # @option options :headers [Hash] HTTP headers this method can accept + # @option options :hidden [Boolean] hide the endpoint or not + # @option options :deprecated [Boolean] deprecate the endpoint or not + # @option options :is_array [Boolean] response entity is array or not + # @option options :nickname [String] nickname of the endpoint + # @option options :produces [Array[String]] a list of MIME types the endpoint produce + # @option options :consumes [Array[String]] a list of MIME types the endpoint consume + # @option options :security [Array[Hash]] a list of security schemes + # @option options :tags [Array[String]] a list of tags + # @yield a block yielding an instance context with methods mapping to + # each of the above, except that :entity is also aliased as #success + # and :http_codes is aliased as #failure. + # + # @example + # + # desc 'create a user' + # post '/users' do + # # ... + # end + # + # desc 'find a user' do + # detail 'locates the user from the given user ID' + # failure [ [404, 'Couldn\'t find the given user' ] ] + # success User::Entity + # end + # get '/user/:id' do + # # ... + # end + # + def desc(description, options = nil, &config_block) + opts = + if config_block + desc_container(endpoint_configuration).then do |config_class| + config_class.configure do + description(description) + end + + config_class.configure(&config_block) + config_class.settings + end + else + options&.merge(description: description) || { description: description } + end + + namespace_setting :description, opts + route_setting :description, opts + end + + # Returns an object which configures itself via an instance-context DSL. + def desc_container(endpoint_configuration) + Module.new do + include Grape::Util::StrictHashConfiguration.module(*ROUTE_ATTRIBUTES) + config_context.define_singleton_method(:configuration) do + endpoint_configuration + end + + def config_context.success(*args) + entity(*args) + end + + def config_context.failure(*args) + http_codes(*args) + end + end + end + + private + + def endpoint_configuration + return {} unless defined?(configuration) + + if configuration.respond_to?(:evaluate) + configuration.evaluate + # Within `given` or `mounted blocks` the configuration is already evaluated + elsif configuration.is_a?(Hash) + configuration + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/headers.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/headers.rb new file mode 100644 index 00000000..a02bdd58 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/headers.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Grape + module DSL + module Headers + # This method has four responsibilities: + # 1. Set a specifc header value by key + # 2. Retrieve a specifc header value by key + # 3. Retrieve all headers that have been set + # 4. Delete a specifc header key-value pair + def header(key = nil, val = nil) + if key + val ? header[key.to_s] = val : header.delete(key.to_s) + else + @header ||= Grape::Util::Header.new + end + end + alias headers header + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/helpers.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/helpers.rb new file mode 100644 index 00000000..18071228 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/helpers.rb @@ -0,0 +1,108 @@ +# frozen_string_literal: true + +module Grape + module DSL + module Helpers + extend ActiveSupport::Concern + include Grape::DSL::Configuration + + module ClassMethods + # Add helper methods that will be accessible from any + # endpoint within this namespace (and child namespaces). + # + # When called without a block, all known helpers within this scope + # are included. + # + # @param [Array] new_modules optional array of modules to include + # @param [Block] block optional block of methods to include + # + # @example Define some helpers. + # + # class ExampleAPI < Grape::API + # helpers do + # def current_user + # User.find_by_id(params[:token]) + # end + # end + # end + # + # @example Include many modules + # + # class ExampleAPI < Grape::API + # helpers Authentication, Mailer, OtherModule + # end + # + def helpers(*new_modules, &block) + include_new_modules(new_modules) + include_block(block) + include_all_in_scope if !block && new_modules.empty? + end + + protected + + def include_new_modules(modules) + return if modules.empty? + + modules.each { |mod| make_inclusion(mod) } + end + + def include_block(block) + return unless block + + Module.new.tap do |mod| + make_inclusion(mod) { mod.class_eval(&block) } + end + end + + def make_inclusion(mod, &block) + define_boolean_in_mod(mod) + inject_api_helpers_to_mod(mod, &block) + namespace_stackable(:helpers, mod) + end + + def include_all_in_scope + Module.new.tap do |mod| + namespace_stackable(:helpers).each { |mod_to_include| mod.include mod_to_include } + change! + end + end + + def define_boolean_in_mod(mod) + return if defined? mod::Boolean + + mod.const_set(:Boolean, Grape::API::Boolean) + end + + def inject_api_helpers_to_mod(mod, &block) + mod.extend(BaseHelper) unless mod.is_a?(BaseHelper) + yield if block + mod.api_changed(self) + end + end + + # This module extends user defined helpers + # to provide some API-specific functionality. + module BaseHelper + attr_accessor :api + + def params(name, &block) + @named_params ||= {} + @named_params[name] = block + end + + def api_changed(new_api) + @api = new_api + process_named_params + end + + protected + + def process_named_params + return unless instance_variable_defined?(:@named_params) && @named_params && @named_params.any? + + api.namespace_stackable(:named_params, @named_params) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/inside_route.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/inside_route.rb new file mode 100644 index 00000000..c88f7867 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/inside_route.rb @@ -0,0 +1,466 @@ +# frozen_string_literal: true + +module Grape + module DSL + module InsideRoute + extend ActiveSupport::Concern + include Grape::DSL::Settings + include Grape::DSL::Headers + + # Denotes a situation where a DSL method has been invoked in a + # filter which it should not yet be available in + class MethodNotYetAvailable < StandardError; end + + # @param type [Symbol] The type of filter for which evaluation has been + # completed + # @return [Module] A module containing method overrides suitable for the + # position in the filter evaluation sequence denoted by +type+. This + # defaults to an empty module if no overrides are defined for the given + # filter +type+. + def self.post_filter_methods(type) + @post_filter_modules ||= { before: PostBeforeFilter } + @post_filter_modules[type] + end + + # Methods which should not be available in filters until the before filter + # has completed + module PostBeforeFilter + def declared(passed_params, options = {}, declared_params = nil, params_nested_path = []) + options.reverse_merge!(include_missing: true, include_parent_namespaces: true, evaluate_given: false) + declared_params ||= optioned_declared_params(options[:include_parent_namespaces]) + + res = if passed_params.is_a?(Array) + declared_array(passed_params, options, declared_params, params_nested_path) + else + declared_hash(passed_params, options, declared_params, params_nested_path) + end + + if (key_maps = namespace_stackable(:contract_key_map)) + key_maps.each { |key_map| key_map.write(passed_params, res) } + end + + res + end + + private + + def declared_array(passed_params, options, declared_params, params_nested_path) + passed_params.map do |passed_param| + declared(passed_param || {}, options, declared_params, params_nested_path) + end + end + + def declared_hash(passed_params, options, declared_params, params_nested_path) + declared_params.each_with_object(passed_params.class.new) do |declared_param_attr, memo| + next if options[:evaluate_given] && !declared_param_attr.scope.attr_meets_dependency?(passed_params) + + declared_hash_attr(passed_params, options, declared_param_attr.key, params_nested_path, memo) + end + end + + def declared_hash_attr(passed_params, options, declared_param, params_nested_path, memo) + renamed_params = route_setting(:renamed_params) || {} + if declared_param.is_a?(Hash) + declared_param.each_pair do |declared_parent_param, declared_children_params| + params_nested_path_dup = params_nested_path.dup + params_nested_path_dup << declared_parent_param.to_s + next unless options[:include_missing] || passed_params.key?(declared_parent_param) + + rename_path = params_nested_path + [declared_parent_param.to_s] + renamed_param_name = renamed_params[rename_path] + + memo_key = optioned_param_key(renamed_param_name || declared_parent_param, options) + passed_children_params = passed_params[declared_parent_param] || passed_params.class.new + + memo[memo_key] = handle_passed_param(params_nested_path_dup, passed_children_params.any?) do + declared(passed_children_params, options, declared_children_params, params_nested_path_dup) + end + end + else + # If it is not a Hash then it does not have children. + # Find its value or set it to nil. + return unless options[:include_missing] || passed_params.key?(declared_param) + + rename_path = params_nested_path + [declared_param.to_s] + renamed_param_name = renamed_params[rename_path] + + memo_key = optioned_param_key(renamed_param_name || declared_param, options) + passed_param = passed_params[declared_param] + + params_nested_path_dup = params_nested_path.dup + params_nested_path_dup << declared_param.to_s + memo[memo_key] = passed_param || handle_passed_param(params_nested_path_dup) do + passed_param + end + end + end + + def handle_passed_param(params_nested_path, has_passed_children = false, &_block) + return yield if has_passed_children + + key = params_nested_path[0] + key += "[#{params_nested_path[1..].join('][')}]" if params_nested_path.size > 1 + + route_options_params = options[:route_options][:params] || {} + type = route_options_params.dig(key, :type) + has_children = route_options_params.keys.any? { |k| k != key && k.start_with?("#{key}[") } + + if type == 'Hash' && !has_children + {} + elsif type == 'Array' || (type&.start_with?('[') && type&.exclude?(',')) + [] + elsif type == 'Set' || type&.start_with?('#] The backtrace of the exception that caused the error. + # @param original_exception [Exception] The original exception that caused the error. + def error!(message, status = nil, additional_headers = nil, backtrace = nil, original_exception = nil) + status = self.status(status || namespace_inheritable(:default_error_status)) + headers = additional_headers.present? ? header.merge(additional_headers) : header + throw :error, + message: message, + status: status, + headers: headers, + backtrace: backtrace, + original_exception: original_exception + end + + # Creates a Rack response based on the provided message, status, and headers. + # The content type in the headers is set to the default content type unless provided. + # The message is HTML-escaped if the content type is 'text/html'. + # + # @param message [String] The content of the response. + # @param status [Integer] The HTTP status code. + # @params headers [Hash] (optional) Headers for the response + # (default: {Rack::CONTENT_TYPE => content_type}). + # + # Returns: + # A Rack::Response object containing the specified message, status, and headers. + # + def rack_response(message, status = 200, headers = { Rack::CONTENT_TYPE => content_type }) + Grape.deprecator.warn('The rack_response method has been deprecated, use error! instead.') + message = Rack::Utils.escape_html(message) if headers[Rack::CONTENT_TYPE] == 'text/html' + Rack::Response.new(Array.wrap(message), Rack::Utils.status_code(status), headers) + end + + # Redirect to a new url. + # + # @param url [String] The url to be redirect. + # @param permanent [Boolean] default false. + # @param body default a short message including the URL. + def redirect(url, permanent: false, body: nil) + body_message = body + if permanent + status 301 + body_message ||= "This resource has been moved permanently to #{url}." + elsif http_version == 'HTTP/1.1' && !request.get? + status 303 + body_message ||= "An alternate resource is located at #{url}." + else + status 302 + body_message ||= "This resource has been moved temporarily to #{url}." + end + header Grape::Http::Headers::LOCATION, url + content_type 'text/plain' + body body_message + end + + # Set or retrieve the HTTP status code. + # + # @param status [Integer] The HTTP Status Code to return for this request. + def status(status = nil) + case status + when Symbol + raise ArgumentError, "Status code :#{status} is invalid." unless Rack::Utils::SYMBOL_TO_STATUS_CODE.key?(status) + + @status = Rack::Utils.status_code(status) + when Integer + @status = status + when nil + return @status if instance_variable_defined?(:@status) && @status + + if request.post? + 201 + elsif request.delete? + if instance_variable_defined?(:@body) && @body.present? + 200 + else + 204 + end + else + 200 + end + else + raise ArgumentError, 'Status code must be Integer or Symbol.' + end + end + + # Set response content-type + def content_type(val = nil) + if val + header(Rack::CONTENT_TYPE, val) + else + header[Rack::CONTENT_TYPE] + end + end + + # Set or get a cookie + # + # @example + # cookies[:mycookie] = 'mycookie val' + # cookies['mycookie-string'] = 'mycookie string val' + # cookies[:more] = { value: '123', expires: Time.at(0) } + # cookies.delete :more + # + def cookies + @cookies ||= Cookies.new + end + + # Allows you to define the response body as something other than the + # return value. + # + # @example + # get '/body' do + # body "Body" + # "Not the Body" + # end + # + # GET /body # => "Body" + def body(value = nil) + if value + @body = value + elsif value == false + @body = '' + status 204 + else + instance_variable_defined?(:@body) ? @body : nil + end + end + + # Allows you to explicitly return no content. + # + # @example + # delete :id do + # return_no_content + # "not returned" + # end + # + # DELETE /12 # => 204 No Content, "" + def return_no_content + status 204 + body false + end + + # Allows you to send a file to the client via sendfile. + # + # @example + # get '/file' do + # sendfile FileStreamer.new(...) + # end + # + # GET /file # => "contents of file" + def sendfile(value = nil) + if value.is_a?(String) + file_body = Grape::ServeStream::FileBody.new(value) + @stream = Grape::ServeStream::StreamResponse.new(file_body) + elsif !value.is_a?(NilClass) + raise ArgumentError, 'Argument must be a file path' + else + stream + end + end + + # Allows you to define the response as a streamable object. + # + # If Content-Length and Transfer-Encoding are blank (among other conditions), + # Rack assumes this response can be streamed in chunks. + # + # @example + # get '/stream' do + # stream FileStreamer.new(...) + # end + # + # GET /stream # => "chunked contents of file" + # + # See: + # * https://github.com/rack/rack/blob/99293fa13d86cd48021630fcc4bd5acc9de5bdc3/lib/rack/chunked.rb + # * https://github.com/rack/rack/blob/99293fa13d86cd48021630fcc4bd5acc9de5bdc3/lib/rack/etag.rb + def stream(value = nil) + return if value.nil? && @stream.nil? + + header Rack::CONTENT_LENGTH, nil + header Grape::Http::Headers::TRANSFER_ENCODING, nil + header Rack::CACHE_CONTROL, 'no-cache' # Skips ETag generation (reading the response up front) + if value.is_a?(String) + file_body = Grape::ServeStream::FileBody.new(value) + @stream = Grape::ServeStream::StreamResponse.new(file_body) + elsif value.respond_to?(:each) + @stream = Grape::ServeStream::StreamResponse.new(value) + elsif !value.is_a?(NilClass) + raise ArgumentError, 'Stream object must respond to :each.' + else + @stream + end + end + + # Allows you to make use of Grape Entities by setting + # the response body to the serializable hash of the + # entity provided in the `:with` option. This has the + # added benefit of automatically passing along environment + # and version information to the serialization, making it + # very easy to do conditional exposures. See Entity docs + # for more info. + # + # @example + # + # get '/users/:id' do + # present User.find(params[:id]), + # with: API::Entities::User, + # admin: current_user.admin? + # end + def present(*args) + options = args.count > 1 ? args.extract_options! : {} + key, object = if args.count == 2 && args.first.is_a?(Symbol) + args + else + [nil, args.first] + end + entity_class = entity_class_for_obj(object, options) + + root = options.delete(:root) + + representation = if entity_class + entity_representation_for(entity_class, object, options) + else + object + end + + representation = { root => representation } if root + + if key + representation = (body || {}).merge(key => representation) + elsif entity_class.present? && body + raise ArgumentError, "Representation of type #{representation.class} cannot be merged." unless representation.respond_to?(:merge) + + representation = body.merge(representation) + end + + body representation + end + + # Returns route information for the current request. + # + # @example + # + # desc "Returns the route description." + # get '/' do + # route.description + # end + def route + env[Grape::Env::GRAPE_ROUTING_ARGS][:route_info] + end + + # Attempt to locate the Entity class for a given object, if not given + # explicitly. This is done by looking for the presence of Klass::Entity, + # where Klass is the class of the `object` parameter, or one of its + # ancestors. + # @param object [Object] the object to locate the Entity class for + # @param options [Hash] + # @option options :with [Class] the explicit entity class to use + # @return [Class] the located Entity class, or nil if none is found + def entity_class_for_obj(object, options) + entity_class = options.delete(:with) + + if entity_class.nil? + # entity class not explicitly defined, auto-detect from relation#klass or first object in the collection + object_class = if object.respond_to?(:klass) + object.klass + else + object.respond_to?(:first) ? object.first.class : object.class + end + + object_class.ancestors.each do |potential| + entity_class ||= (namespace_stackable_with_hash(:representations) || {})[potential] + end + + entity_class ||= object_class.const_get(:Entity) if object_class.const_defined?(:Entity) && object_class.const_get(:Entity).respond_to?(:represent) + end + + entity_class + end + + # @return the representation of the given object as done through + # the given entity_class. + def entity_representation_for(entity_class, object, options) + embeds = { env: env } + embeds[:version] = env[Grape::Env::API_VERSION] if env.key?(Grape::Env::API_VERSION) + entity_class.represent(object, **embeds.merge(options)) + end + + def http_version + env.fetch(Grape::Http::Headers::HTTP_VERSION) { env[Rack::SERVER_PROTOCOL] } + end + + def api_format(format) + env[Grape::Env::API_FORMAT] = format + end + + def context + self + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/logger.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/logger.rb new file mode 100644 index 00000000..516cdcd7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/logger.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Grape + module DSL + module Logger + include Grape::DSL::Settings + + attr_writer :logger + + # Set or retrive the configured logger. If none was configured, this + # method will create a new one, logging to stdout. + # @param logger [Object] the new logger to use + def logger(logger = nil) + if logger + global_setting(:logger, logger) + else + global_setting(:logger) || global_setting(:logger, ::Logger.new($stdout)) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/middleware.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/middleware.rb new file mode 100644 index 00000000..07e6f9fe --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/middleware.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +module Grape + module DSL + module Middleware + extend ActiveSupport::Concern + + include Grape::DSL::Configuration + + module ClassMethods + # Apply a custom middleware to the API. Applies + # to the current namespace and any children, but + # not parents. + # + # @param middleware_class [Class] The class of the middleware you'd like + # to inject. + def use(middleware_class, *args, &block) + arr = [:use, middleware_class, *args] + arr << block if block + + namespace_stackable(:middleware, arr) + end + + def insert(*args, &block) + arr = [:insert, *args] + arr << block if block + + namespace_stackable(:middleware, arr) + end + + def insert_before(*args, &block) + arr = [:insert_before, *args] + arr << block if block + + namespace_stackable(:middleware, arr) + end + + def insert_after(*args, &block) + arr = [:insert_after, *args] + arr << block if block + + namespace_stackable(:middleware, arr) + end + + # Retrieve an array of the middleware classes + # and arguments that are currently applied to the + # application. + def middleware + namespace_stackable(:middleware) || [] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/parameters.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/parameters.rb new file mode 100644 index 00000000..48f53bcb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/parameters.rb @@ -0,0 +1,266 @@ +# frozen_string_literal: true + +module Grape + module DSL + # Defines DSL methods, meant to be applied to a ParamsScope, which define + # and describe the parameters accepted by an endpoint, or all endpoints + # within a namespace. + module Parameters + extend ActiveSupport::Concern + + # Set the module used to build the request.params. + # + # @param build_with the ParamBuilder module to use when building request.params + # Available builders are: + # + # * Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder (default) + # * Grape::Extensions::Hash::ParamBuilder + # * Grape::Extensions::Hashie::Mash::ParamBuilder + # + # @example + # + # require 'grape/extenstions/hashie_mash' + # class API < Grape::API + # desc "Get collection" + # params do + # build_with Grape::Extensions::Hashie::Mash::ParamBuilder + # requires :user_id, type: Integer + # end + # get do + # params['user_id'] + # end + # end + def build_with(build_with = nil) + @api.namespace_inheritable(:build_params_with, build_with) + end + + # Include reusable params rules among current. + # You can define reusable params with helpers method. + # + # @example + # + # class API < Grape::API + # helpers do + # params :pagination do + # optional :page, type: Integer + # optional :per_page, type: Integer + # end + # end + # + # desc "Get collection" + # params do + # use :pagination + # end + # get do + # Collection.page(params[:page]).per(params[:per_page]) + # end + # end + def use(*names) + named_params = @api.namespace_stackable_with_hash(:named_params) || {} + options = names.extract_options! + names.each do |name| + params_block = named_params.fetch(name) do + raise "Params :#{name} not found!" + end + + if options.empty? + instance_exec(options, ¶ms_block) + else + instance_exec(**options, ¶ms_block) + end + end + end + alias use_scope use + alias includes use + + # Require one or more parameters for the current endpoint. + # + # @param attrs list of parameters names, or, if :using is + # passed as an option, which keys to include (:all or :none) from + # the :using hash. The last key can be a hash, which specifies + # options for the parameters + # @option attrs :type [Class] the type to coerce this parameter to before + # passing it to the endpoint. See {Grape::Validations::Types} for a list of + # types that are supported automatically. Custom classes may be used + # where they define a class-level `::parse` method, or in conjunction + # with the `:coerce_with` parameter. `JSON` may be supplied to denote + # `JSON`-formatted objects or arrays of objects. `Array[JSON]` accepts + # the same values as `JSON` but will wrap single objects in an `Array`. + # @option attrs :types [Array] may be supplied in place of +:type+ + # to declare an attribute that has multiple allowed types. See + # {Validations::Types::MultipleTypeCoercer} for more details on coercion + # and validation rules for variant-type parameters. + # @option attrs :desc [String] description to document this parameter + # @option attrs :default [Object] default value, if parameter is optional + # @option attrs :values [Array] permissable values for this field. If any + # other value is given, it will be handled as a validation error + # @option attrs :using [Hash[Symbol => Hash]] a hash defining keys and + # options, like that returned by {Grape::Entity#documentation}. The value + # of each key is an options hash accepting the same parameters + # @option attrs :except [Array[Symbol]] a list of keys to exclude from + # the :using Hash. The meaning of this depends on if :all or :none was + # passed; :all + :except will make the :except fields optional, whereas + # :none + :except will make the :except fields required + # @option attrs :coerce_with [#parse, #call] method to be used when coercing + # the parameter to the type named by `attrs[:type]`. Any class or object + # that defines `::parse` or `::call` may be used. + # + # @example + # + # params do + # # Basic usage: require a parameter of a certain type + # requires :user_id, type: Integer + # + # # You don't need to specify type; String is default + # requires :foo + # + # # Multiple params can be specified at once if they share + # # the same options. + # requires :x, :y, :z, type: Date + # + # # Nested parameters can be handled as hashes. You must + # # pass in a block, within which you can use any of the + # # parameters DSL methods. + # requires :user, type: Hash do + # requires :name, type: String + # end + # end + def requires(*attrs, &block) + orig_attrs = attrs.clone + + opts = attrs.extract_options!.clone + opts[:presence] = { value: true, message: opts[:message] } + opts = @group.deep_merge(opts) if instance_variable_defined?(:@group) && @group + + if opts[:using] + require_required_and_optional_fields(attrs.first, opts) + else + validate_attributes(attrs, opts, &block) + block ? new_scope(orig_attrs, &block) : push_declared_params(attrs, opts.slice(:as)) + end + end + + # Allow, but don't require, one or more parameters for the current + # endpoint. + # @param (see #requires) + # @option (see #requires) + def optional(*attrs, &block) + orig_attrs = attrs.clone + + opts = attrs.extract_options!.clone + type = opts[:type] + opts = @group.deep_merge(opts) if instance_variable_defined?(:@group) && @group + + # check type for optional parameter group + if attrs && block + raise Grape::Exceptions::MissingGroupType if type.nil? + raise Grape::Exceptions::UnsupportedGroupType unless Grape::Validations::Types.group?(type) + end + + if opts[:using] + require_optional_fields(attrs.first, opts) + else + validate_attributes(attrs, opts, &block) + + block ? new_scope(orig_attrs, true, &block) : push_declared_params(attrs, opts.slice(:as)) + end + end + + # Define common settings for one or more parameters + # @param (see #requires) + # @option (see #requires) + def with(*attrs, &block) + new_group_attrs = [@group, attrs.clone.first].compact.reduce(&:deep_merge) + new_group_scope([new_group_attrs], &block) + end + + # Disallow the given parameters to be present in the same request. + # @param attrs [*Symbol] parameters to validate + def mutually_exclusive(*attrs) + validates(attrs, mutual_exclusion: { value: true, message: extract_message_option(attrs) }) + end + + # Require exactly one of the given parameters to be present. + # @param (see #mutually_exclusive) + def exactly_one_of(*attrs) + validates(attrs, exactly_one_of: { value: true, message: extract_message_option(attrs) }) + end + + # Require at least one of the given parameters to be present. + # @param (see #mutually_exclusive) + def at_least_one_of(*attrs) + validates(attrs, at_least_one_of: { value: true, message: extract_message_option(attrs) }) + end + + # Require that either all given params are present, or none are. + # @param (see #mutually_exclusive) + def all_or_none_of(*attrs) + validates(attrs, all_or_none_of: { value: true, message: extract_message_option(attrs) }) + end + + # Define a block of validations which should be applied if and only if + # the given parameter is present. The parameters are not nested. + # @param attr [Symbol] the parameter which, if present, triggers the + # validations + # @raise Grape::Exceptions::UnknownParameter if `attr` has not been + # defined in this scope yet + # @yield a parameter definition DSL + def given(*attrs, &block) + attrs.each do |attr| + proxy_attr = first_hash_key_or_param(attr) + raise Grape::Exceptions::UnknownParameter.new(proxy_attr) unless declared_param?(proxy_attr) + end + new_lateral_scope(dependent_on: attrs, &block) + end + + # Test for whether a certain parameter has been defined in this params + # block yet. + # @return [Boolean] whether the parameter has been defined + def declared_param?(param) + if lateral? + # Elements of @declared_params of lateral scope are pushed in @parent. So check them in @parent. + @parent.declared_param?(param) + else + # @declared_params also includes hashes of options and such, but those + # won't be flattened out. + @declared_params.flatten.any? do |declared_param_attr| + first_hash_key_or_param(declared_param_attr.key) == param + end + end + end + + alias group requires + + class EmptyOptionalValue; end # rubocop:disable Lint/EmptyClass + + def map_params(params, element, is_array = false) + if params.is_a?(Array) + params.map do |el| + map_params(el, element, true) + end + elsif params.is_a?(Hash) + params[element] || (@optional && is_array ? EmptyOptionalValue : {}) + elsif params == EmptyOptionalValue + EmptyOptionalValue + else + {} + end + end + + # @param params [Hash] initial hash of parameters + # @return hash of parameters relevant for the current scope + # @api private + def params(params) + params = @parent.params(params) if instance_variable_defined?(:@parent) && @parent + params = map_params(params, @element) if instance_variable_defined?(:@element) && @element + params + end + + private + + def first_hash_key_or_param(parameter) + parameter.is_a?(Hash) ? parameter.keys.first : parameter + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/request_response.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/request_response.rb new file mode 100644 index 00000000..7f0a0d27 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/request_response.rb @@ -0,0 +1,171 @@ +# frozen_string_literal: true + +module Grape + module DSL + module RequestResponse + extend ActiveSupport::Concern + + include Grape::DSL::Configuration + + module ClassMethods + # Specify the default format for the API's serializers. + # May be `:json` or `:txt` (default). + def default_format(new_format = nil) + namespace_inheritable(:default_format, new_format.nil? ? nil : new_format.to_sym) + end + + # Specify the format for the API's serializers. + # May be `:json`, `:xml`, `:txt`, etc. + def format(new_format = nil) + return namespace_inheritable(:format) unless new_format + + symbolic_new_format = new_format.to_sym + namespace_inheritable(:format, symbolic_new_format) + namespace_inheritable(:default_error_formatter, Grape::ErrorFormatter.formatter_for(symbolic_new_format)) + + content_type = content_types[symbolic_new_format] + raise Grape::Exceptions::MissingMimeType.new(new_format) unless content_type + + namespace_stackable(:content_types, symbolic_new_format => content_type) + end + + # Specify a custom formatter for a content-type. + def formatter(content_type, new_formatter) + namespace_stackable(:formatters, content_type.to_sym => new_formatter) + end + + # Specify a custom parser for a content-type. + def parser(content_type, new_parser) + namespace_stackable(:parsers, content_type.to_sym => new_parser) + end + + # Specify a default error formatter. + def default_error_formatter(new_formatter_name = nil) + return namespace_inheritable(:default_error_formatter) unless new_formatter_name + + new_formatter = Grape::ErrorFormatter.formatter_for(new_formatter_name) + namespace_inheritable(:default_error_formatter, new_formatter) + end + + def error_formatter(format, options) + formatter = if options.is_a?(Hash) && options.key?(:with) + options[:with] + else + options + end + + namespace_stackable(:error_formatters, format.to_sym => formatter) + end + + # Specify additional content-types, e.g.: + # content_type :xls, 'application/vnd.ms-excel' + def content_type(key, val) + namespace_stackable(:content_types, key.to_sym => val) + end + + # All available content types. + def content_types + c_types = namespace_stackable_with_hash(:content_types) + Grape::ContentTypes.content_types_for c_types + end + + # Specify the default status code for errors. + def default_error_status(new_status = nil) + namespace_inheritable(:default_error_status, new_status) + end + + # Allows you to rescue certain exceptions that occur to return + # a grape error rather than raising all the way to the + # server level. + # + # @example Rescue from custom exceptions + # class ExampleAPI < Grape::API + # class CustomError < StandardError; end + # + # rescue_from CustomError + # end + # + # @overload rescue_from(*exception_classes, **options) + # @param [Array] exception_classes A list of classes that you want to rescue, or + # the symbol :all to rescue from all exceptions. + # @param [Block] block Execution block to handle the given exception. + # @param [Hash] options Options for the rescue usage. + # @option options [Boolean] :backtrace Include a backtrace in the rescue response. + # @option options [Boolean] :rescue_subclasses Also rescue subclasses of exception classes + # @param [Proc] handler Execution proc to handle the given exception as an + # alternative to passing a block. + def rescue_from(*args, &block) + if args.last.is_a?(Proc) + handler = args.pop + elsif block + handler = block + end + + options = args.extract_options! + raise ArgumentError, 'both :with option and block cannot be passed' if block && options.key?(:with) + + handler ||= extract_with(options) + + if args.include?(:all) + namespace_inheritable(:rescue_all, true) + namespace_inheritable(:all_rescue_handler, handler) + elsif args.include?(:grape_exceptions) + namespace_inheritable(:rescue_all, true) + namespace_inheritable(:rescue_grape_exceptions, true) + namespace_inheritable(:grape_exceptions_rescue_handler, handler) + else + handler_type = + case options[:rescue_subclasses] + when nil, true + :rescue_handlers + else + :base_only_rescue_handlers + end + + namespace_reverse_stackable(handler_type, args.to_h { |arg| [arg, handler] }) + end + + namespace_stackable(:rescue_options, options) + end + + # Allows you to specify a default representation entity for a + # class. This allows you to map your models to their respective + # entities once and then simply call `present` with the model. + # + # @example + # class ExampleAPI < Grape::API + # represent User, with: Entity::User + # + # get '/me' do + # present current_user # with: Entity::User is assumed + # end + # end + # + # Note that Grape will automatically go up the class ancestry to + # try to find a representing entity, so if you, for example, define + # an entity to represent `Object` then all presented objects will + # bubble up and utilize the entity provided on that `represent` call. + # + # @param model_class [Class] The model class that will be represented. + # @option options [Class] :with The entity class that will represent the model. + def represent(model_class, options) + raise Grape::Exceptions::InvalidWithOptionForRepresent.new unless options[:with].is_a?(Class) + + namespace_stackable(:representations, model_class => options[:with]) + end + + private + + def extract_with(options) + return unless options.key?(:with) + + with_option = options.delete(:with) + return with_option if with_option.instance_of?(Proc) + return with_option.to_sym if with_option.instance_of?(Symbol) || with_option.instance_of?(String) + + raise ArgumentError, "with: #{with_option.class}, expected Symbol, String or Proc" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/routing.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/routing.rb new file mode 100644 index 00000000..8145726a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/routing.rb @@ -0,0 +1,240 @@ +# frozen_string_literal: true + +module Grape + module DSL + module Routing + extend ActiveSupport::Concern + include Grape::DSL::Configuration + + module ClassMethods + attr_reader :endpoints + + # Specify an API version. + # + # @example API with legacy support. + # class MyAPI < Grape::API + # version 'v2' + # + # get '/main' do + # {some: 'data'} + # end + # + # version 'v1' do + # get '/main' do + # {legacy: 'data'} + # end + # end + # end + # + def version(*args, &block) + if args.any? + options = args.extract_options! + options = options.reverse_merge(using: :path) + requested_versions = args.flatten.map(&:to_s) + + raise Grape::Exceptions::MissingVendorOption.new if options[:using] == :header && !options.key?(:vendor) + + @versions = versions | requested_versions + + if block + within_namespace do + namespace_inheritable(:version, requested_versions) + namespace_inheritable(:version_options, options) + + instance_eval(&block) + end + else + namespace_inheritable(:version, requested_versions) + namespace_inheritable(:version_options, options) + end + end + + @versions.last if instance_variable_defined?(:@versions) && @versions + end + + # Define a root URL prefix for your entire API. + def prefix(prefix = nil) + namespace_inheritable(:root_prefix, prefix&.to_s) + end + + # Create a scope without affecting the URL. + # + # @param _name [Symbol] Purely placebo, just allows to name the scope to + # make the code more readable. + def scope(_name = nil, &block) + within_namespace do + nest(block) + end + end + + # Do not route HEAD requests to GET requests automatically. + def do_not_route_head! + namespace_inheritable(:do_not_route_head, true) + end + + # Do not automatically route OPTIONS. + def do_not_route_options! + namespace_inheritable(:do_not_route_options, true) + end + + def do_not_document! + namespace_inheritable(:do_not_document, true) + end + + def mount(mounts, *opts) + mounts = { mounts => '/' } unless mounts.respond_to?(:each_pair) + mounts.each_pair do |app, path| + if app.respond_to?(:mount_instance) + opts_with = opts.any? ? opts.first[:with] : {} + mount({ app.mount_instance(configuration: opts_with) => path }, *opts) + next + end + in_setting = inheritable_setting + + if app.respond_to?(:inheritable_setting, true) + mount_path = Grape::Router.normalize_path(path) + app.top_level_setting.namespace_stackable[:mount_path] = mount_path + + app.inherit_settings(inheritable_setting) + + in_setting = app.top_level_setting + + app.change! + change! + end + + # When trying to mount multiple times the same endpoint, remove the previous ones + # from the list of endpoints if refresh_already_mounted parameter is true + refresh_already_mounted = opts.any? ? opts.first[:refresh_already_mounted] : false + if refresh_already_mounted && !endpoints.empty? + endpoints.delete_if do |endpoint| + endpoint.options[:app].to_s == app.to_s + end + end + + endpoints << Grape::Endpoint.new( + in_setting, + method: :any, + path: path, + app: app, + route_options: { anchor: false }, + forward_match: !app.respond_to?(:inheritable_setting), + for: self + ) + end + end + + # Defines a route that will be recognized + # by the Grape API. + # + # @param methods [HTTP Verb] One or more HTTP verbs that are accepted by this route. Set to `:any` if you want any verb to be accepted. + # @param paths [String] One or more strings representing the URL segment(s) for this route. + # + # @example Defining a basic route. + # class MyAPI < Grape::API + # route(:any, '/hello') do + # {hello: 'world'} + # end + # end + def route(methods, paths = ['/'], route_options = {}, &block) + methods = '*' if methods == :any + endpoint_options = { + method: methods, + path: paths, + for: self, + route_options: { + params: namespace_stackable_with_hash(:params) || {} + }.deep_merge(route_setting(:description) || {}).deep_merge(route_options || {}) + } + + new_endpoint = Grape::Endpoint.new(inheritable_setting, endpoint_options, &block) + endpoints << new_endpoint unless endpoints.any? { |e| e.equals?(new_endpoint) } + + route_end + reset_validations! + end + + Grape::Http::Headers::SUPPORTED_METHODS.each do |supported_method| + define_method supported_method.downcase do |*args, &block| + options = args.extract_options! + paths = args.first || ['/'] + route(supported_method, paths, options, &block) + end + end + + # Declare a "namespace", which prefixes all subordinate routes with its + # name. Any endpoints within a namespace, group, resource or segment, + # etc., will share their parent context as well as any configuration + # done in the namespace context. + # + # @example + # + # namespace :foo do + # get 'bar' do + # # defines the endpoint: GET /foo/bar + # end + # end + def namespace(space = nil, options = {}, &block) + return Namespace.joined_space_path(namespace_stackable(:namespace)) unless space || block + + within_namespace do + nest(block) do + namespace_stackable(:namespace, Namespace.new(space, options)) if space + end + end + end + + alias group namespace + alias resource namespace + alias resources namespace + alias segment namespace + + # An array of API routes. + def routes + @routes ||= prepare_routes + end + + # Remove all defined routes. + def reset_routes! + endpoints.each(&:reset_routes!) + @routes = nil + end + + def reset_endpoints! + @endpoints = [] + end + + # This method allows you to quickly define a parameter route segment + # in your API. + # + # @param param [Symbol] The name of the parameter you wish to declare. + # @option options [Regexp] You may supply a regular expression that the declared parameter must meet. + def route_param(param, options = {}, &block) + options = options.dup + + options[:requirements] = { + param.to_sym => options[:requirements] + } if options[:requirements].is_a?(Regexp) + + Grape::Validations::ParamsScope.new(api: self) do + requires param, type: options[:type] + end if options.key?(:type) + + namespace(":#{param}", options, &block) + end + + # @return array of defined versions + def versions + @versions ||= [] + end + + private + + def refresh_mounted_api(mounts, *opts) + opts << { refresh_already_mounted: true } + mount(mounts, *opts) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/settings.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/settings.rb new file mode 100644 index 00000000..5c145a46 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/settings.rb @@ -0,0 +1,179 @@ +# frozen_string_literal: true + +module Grape + module DSL + # Keeps track of settings (implemented as key-value pairs, grouped by + # types), in two contexts: top-level settings which apply globally no + # matter where they're defined, and inheritable settings which apply only + # in the current scope and scopes nested under it. + module Settings + extend ActiveSupport::Concern + + attr_writer :inheritable_setting, :top_level_setting + + # Fetch our top-level settings, which apply to all endpoints in the API. + def top_level_setting + @top_level_setting ||= build_top_level_setting + end + + # Fetch our current inheritable settings, which are inherited by + # nested scopes but not shared across siblings. + def inheritable_setting + @inheritable_setting ||= Grape::Util::InheritableSetting.new.tap { |new_settings| new_settings.inherit_from top_level_setting } + end + + # @param type [Symbol] + # @param key [Symbol] + def unset(type, key) + setting = inheritable_setting.send(type) + setting.delete key + end + + # @param type [Symbol] + # @param key [Symbol] + # @param value [Object] will be stored if the value is currently empty + # @return either the old value, if it wasn't nil, or the given value + def get_or_set(type, key, value) + setting = inheritable_setting.send(type) + if value.nil? + setting[key] + else + setting[key] = value + end + end + + # @param key [Symbol] + # @param value [Object] + # @return (see #get_or_set) + def global_setting(key, value = nil) + get_or_set :global, key, value + end + + # @param key [Symbol] + def unset_global_setting(key) + unset :global, key + end + + # (see #global_setting) + def route_setting(key, value = nil) + get_or_set :route, key, value + end + + # (see #unset_global_setting) + def unset_route_setting(key) + unset :route, key + end + + # (see #global_setting) + def namespace_setting(key, value = nil) + get_or_set :namespace, key, value + end + + # (see #unset_global_setting) + def unset_namespace_setting(key) + unset :namespace, key + end + + # (see #global_setting) + def namespace_inheritable(key, value = nil) + get_or_set :namespace_inheritable, key, value + end + + # (see #unset_global_setting) + def unset_namespace_inheritable(key) + unset :namespace_inheritable, key + end + + # @param key [Symbol] + def namespace_inheritable_to_nil(key) + inheritable_setting.namespace_inheritable[key] = nil + end + + # (see #global_setting) + def namespace_stackable(key, value = nil) + get_or_set :namespace_stackable, key, value + end + + def namespace_reverse_stackable(key, value = nil) + get_or_set :namespace_reverse_stackable, key, value + end + + def namespace_stackable_with_hash(key) + settings = get_or_set :namespace_stackable, key, nil + return if settings.blank? + + settings.each_with_object({}) { |value, result| result.deep_merge!(value) } + end + + def namespace_reverse_stackable_with_hash(key) + settings = get_or_set :namespace_reverse_stackable, key, nil + return if settings.blank? + + settings.each_with_object({}) do |setting, result| + result.merge!(setting) { |_k, s1, _s2| s1 } + end + end + + # (see #unset_global_setting) + def unset_namespace_stackable(key) + unset :namespace_stackable, key + end + + # (see #global_setting) + def api_class_setting(key, value = nil) + get_or_set :api_class, key, value + end + + # (see #unset_global_setting) + def unset_api_class_setting(key) + unset :api_class, key + end + + # Fork our inheritable settings to a new instance, copied from our + # parent's, but separate so we won't modify it. Every call to this + # method should have an answering call to #namespace_end. + def namespace_start + @inheritable_setting = Grape::Util::InheritableSetting.new.tap { |new_settings| new_settings.inherit_from inheritable_setting } + end + + # Set the inheritable settings pointer back up by one level. + def namespace_end + route_end + @inheritable_setting = inheritable_setting.parent + end + + # Stop defining settings for the current route and clear them for the + # next, within a namespace. + def route_end + inheritable_setting.route_end + end + + # Execute the block within a context where our inheritable settings are forked + # to a new copy (see #namespace_start). + def within_namespace(&block) + namespace_start + + result = yield if block + + namespace_end + reset_validations! + + result + end + + private + + # Builds the current class :inheritable_setting. If available, it inherits from + # the superclass's :inheritable_setting. + def build_top_level_setting + Grape::Util::InheritableSetting.new.tap do |setting| + # Doesn't try to inherit settings from +Grape::API::Instance+ which also responds to + # +inheritable_setting+, however, it doesn't contain any user-defined settings. + # Otherwise, it would lead to an extra instance of +Grape::Util::InheritableSetting+ + # in the chain for every endpoint. + setting.inherit_from superclass.inheritable_setting if defined?(superclass) && superclass.respond_to?(:inheritable_setting) && superclass != Grape::API::Instance + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/validations.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/validations.rb new file mode 100644 index 00000000..81d71bfe --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/dsl/validations.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +module Grape + module DSL + module Validations + extend ActiveSupport::Concern + + include Grape::DSL::Configuration + + module ClassMethods + # Clears all defined parameters and validations. The main purpose of it is to clean up + # settings, so next endpoint won't interfere with previous one. + # + # params do + # # params for the endpoint below this block + # end + # post '/current' do + # # whatever + # end + # + # # somewhere between them the reset_validations! method gets called + # + # params do + # # params for the endpoint below this block + # end + # post '/next' do + # # whatever + # end + def reset_validations! + unset_namespace_stackable :declared_params + unset_namespace_stackable :validations + unset_namespace_stackable :params + end + + # Opens a root-level ParamsScope, defining parameter coercions and + # validations for the endpoint. + # @yield instance context of the new scope + def params(&block) + Grape::Validations::ParamsScope.new(api: self, type: Hash, &block) + end + + # Declare the contract to be used for the endpoint's parameters. + # @param contract [Class | Dry::Schema::Processor] + # The contract or schema to be used for validation. Optional. + # @yield a block yielding a new instance of Dry::Schema::Params + # subclass, allowing to define the schema inline. When the + # +contract+ parameter is a schema, it will be used as a parent. Optional. + def contract(contract = nil, &block) + raise ArgumentError, 'Either contract or block must be provided' unless contract || block + raise ArgumentError, 'Cannot inherit from contract, only schema' if block && contract.respond_to?(:schema) + + Grape::Validations::ContractScope.new(self, contract, &block) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/endpoint.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/endpoint.rb new file mode 100644 index 00000000..4fb0594d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/endpoint.rb @@ -0,0 +1,420 @@ +# frozen_string_literal: true + +module Grape + # An Endpoint is the proxy scope in which all routing + # blocks are executed. In other words, any methods + # on the instance level of this class may be called + # from inside a `get`, `post`, etc. + class Endpoint + include Grape::DSL::Settings + include Grape::DSL::InsideRoute + + attr_accessor :block, :source, :options + attr_reader :env, :request, :headers, :params + + class << self + def new(...) + self == Endpoint ? Class.new(Endpoint).new(...) : super + end + + def before_each(new_setup = false, &block) + @before_each ||= [] + if new_setup == false + return @before_each unless block + + @before_each << block + else + @before_each = [new_setup] + end + end + + def run_before_each(endpoint) + superclass.run_before_each(endpoint) unless self == Endpoint + before_each.each { |blk| blk.call(endpoint) if blk.respond_to?(:call) } + end + + # @api private + # + # Create an UnboundMethod that is appropriate for executing an endpoint + # route. + # + # The unbound method allows explicit calls to +return+ without raising a + # +LocalJumpError+. The method will be removed, but a +Proc+ reference to + # it will be returned. The returned +Proc+ expects a single argument: the + # instance of +Endpoint+ to bind to the method during the call. + # + # @param [String, Symbol] method_name + # @return [Proc] + # @raise [NameError] an instance method with the same name already exists + def generate_api_method(method_name, &block) + raise NameError.new("method #{method_name.inspect} already exists and cannot be used as an unbound method name") if method_defined?(method_name) + + define_method(method_name, &block) + method = instance_method(method_name) + remove_method(method_name) + + proc do |endpoint_instance| + ActiveSupport::Notifications.instrument('endpoint_render.grape', endpoint: endpoint_instance) do + method.bind_call(endpoint_instance) + end + end + end + end + + # Create a new endpoint. + # @param new_settings [InheritableSetting] settings to determine the params, + # validations, and other properties from. + # @param options [Hash] attributes of this endpoint + # @option options path [String or Array] the path to this endpoint, within + # the current scope. + # @option options method [String or Array] which HTTP method(s) can be used + # to reach this endpoint. + # @option options route_options [Hash] + # @note This happens at the time of API definition, so in this context the + # endpoint does not know if it will be mounted under a different endpoint. + # @yield a block defining what your API should do when this endpoint is hit + def initialize(new_settings, options = {}, &block) + require_option(options, :path) + require_option(options, :method) + + self.inheritable_setting = new_settings.point_in_time_copy + + # now +namespace_stackable(:declared_params)+ contains all params defined for + # this endpoint and its parents, but later it will be cleaned up, + # see +reset_validations!+ in lib/grape/dsl/validations.rb + route_setting(:declared_params, namespace_stackable(:declared_params).flatten) + route_setting(:saved_validations, namespace_stackable(:validations)) + + namespace_stackable(:representations, []) unless namespace_stackable(:representations) + namespace_inheritable(:default_error_status, 500) unless namespace_inheritable(:default_error_status) + + @options = options + + @options[:path] = Array(options[:path]) + @options[:path] << '/' if options[:path].empty? + + @options[:method] = Array(options[:method]) + @options[:route_options] ||= {} + + @lazy_initialize_lock = Mutex.new + @lazy_initialized = nil + @block = nil + + @status = nil + @stream = nil + @body = nil + @proc = nil + + return unless block + + @source = block + @block = self.class.generate_api_method(method_name, &block) + end + + # Update our settings from a given set of stackable parameters. Used when + # the endpoint's API is mounted under another one. + def inherit_settings(namespace_stackable) + parent_validations = namespace_stackable[:validations] + inheritable_setting.route[:saved_validations].concat(parent_validations) if parent_validations.any? + parent_declared_params = namespace_stackable[:declared_params] + inheritable_setting.route[:declared_params].concat(parent_declared_params.flatten) if parent_declared_params.any? + + endpoints&.each { |e| e.inherit_settings(namespace_stackable) } + end + + def require_option(options, key) + raise Grape::Exceptions::MissingOption.new(key) unless options.key?(key) + end + + def method_name + [options[:method], + Namespace.joined_space(namespace_stackable(:namespace)), + (namespace_stackable(:mount_path) || []).join('/'), + options[:path].join('/')] + .join(' ') + end + + def routes + @routes ||= endpoints ? endpoints.collect(&:routes).flatten : to_routes + end + + def reset_routes! + endpoints&.each(&:reset_routes!) + @namespace = nil + @routes = nil + end + + def mount_in(router) + return endpoints.each { |e| e.mount_in(router) } if endpoints + + reset_routes! + routes.each do |route| + router.append(route.apply(self)) + next unless !namespace_inheritable(:do_not_route_head) && route.request_method == Rack::GET + + route.dup.then do |head_route| + head_route.convert_to_head_request! + router.append(head_route.apply(self)) + end + end + end + + def to_routes + default_route_options = prepare_default_route_attributes + default_path_settings = prepare_default_path_settings + + map_routes do |method, raw_path| + prepared_path = Path.new(raw_path, namespace, default_path_settings) + params = options[:route_options].present? ? options[:route_options].merge(default_route_options) : default_route_options + route = Grape::Router::Route.new(method, prepared_path.origin, prepared_path.suffix, params) + route.apply(self) + end.flatten + end + + def prepare_routes_requirements + {}.merge!(*namespace_stackable(:namespace).map(&:requirements)).tap do |requirements| + endpoint_requirements = options.dig(:route_options, :requirements) + requirements.merge!(endpoint_requirements) if endpoint_requirements + end + end + + def prepare_default_route_attributes + { + namespace: namespace, + version: prepare_version, + requirements: prepare_routes_requirements, + prefix: namespace_inheritable(:root_prefix), + anchor: options[:route_options].fetch(:anchor, true), + settings: inheritable_setting.route.except(:declared_params, :saved_validations), + forward_match: options[:forward_match] + } + end + + def prepare_version + version = namespace_inheritable(:version) + return if version.blank? + + version.length == 1 ? version.first : version + end + + def map_routes + options[:method].map { |method| options[:path].map { |path| yield method, path } } + end + + def prepare_default_path_settings + namespace_stackable_hash = inheritable_setting.namespace_stackable.to_hash + namespace_inheritable_hash = inheritable_setting.namespace_inheritable.to_hash + namespace_stackable_hash.merge!(namespace_inheritable_hash) + end + + def namespace + @namespace ||= Namespace.joined_space_path(namespace_stackable(:namespace)) + end + + def call(env) + lazy_initialize! + dup.call!(env) + end + + def call!(env) + env[Grape::Env::API_ENDPOINT] = self + @env = env + @app.call(env) + end + + # Return the collection of endpoints within this endpoint. + # This is the case when an Grape::API mounts another Grape::API. + def endpoints + options[:app].endpoints if options[:app].respond_to?(:endpoints) + end + + def equals?(endpoint) + (options == endpoint.options) && (inheritable_setting.to_hash == endpoint.inheritable_setting.to_hash) + end + + # The purpose of this override is solely for stripping internals when an error occurs while calling + # an endpoint through an api. See https://github.com/ruby-grape/grape/issues/2398 + # Otherwise, it calls super. + def inspect + return super unless env + + "#{self.class} in '#{route.origin}' endpoint" + end + + protected + + def run + ActiveSupport::Notifications.instrument('endpoint_run.grape', endpoint: self, env: env) do + @header = Grape::Util::Header.new + @request = Grape::Request.new(env, build_params_with: namespace_inheritable(:build_params_with)) + @params = @request.params + @headers = @request.headers + begin + cookies.read(@request) + self.class.run_before_each(self) + run_filters befores, :before + + if (allowed_methods = env[Grape::Env::GRAPE_ALLOWED_METHODS]) + allow_header_value = allowed_methods.join(', ') + raise Grape::Exceptions::MethodNotAllowed.new(header.merge('Allow' => allow_header_value)) unless options? + + header Grape::Http::Headers::ALLOW, allow_header_value + response_object = '' + status 204 + else + run_filters before_validations, :before_validation + run_validators validations, request + run_filters after_validations, :after_validation + response_object = execute + end + + run_filters afters, :after + cookies.write(header) + + # status verifies body presence when DELETE + @body ||= response_object + + # The body commonly is an Array of Strings, the application instance itself, or a Stream-like object + response_object = stream || [body] + + [status, header, response_object] + ensure + run_filters finallies, :finally + end + end + end + + def execute + @block&.call(self) + end + + def helpers + lazy_initialize! && @helpers + end + + def lazy_initialize! + return true if @lazy_initialized + + @lazy_initialize_lock.synchronize do + return true if @lazy_initialized + + @helpers = build_helpers&.tap { |mod| self.class.include mod } + @app = options[:app] || build_stack(@helpers) + + @lazy_initialized = true + end + end + + def run_validators(validators, request) + validation_errors = [] + + ActiveSupport::Notifications.instrument('endpoint_run_validators.grape', endpoint: self, validators: validators, request: request) do + validators.each do |validator| + validator.validate(request) + rescue Grape::Exceptions::Validation => e + validation_errors << e + break if validator.fail_fast? + rescue Grape::Exceptions::ValidationArrayErrors => e + validation_errors.concat e.errors + break if validator.fail_fast? + end + end + + validation_errors.any? && raise(Grape::Exceptions::ValidationErrors.new(errors: validation_errors, headers: header)) + end + + def run_filters(filters, type = :other) + ActiveSupport::Notifications.instrument('endpoint_run_filters.grape', endpoint: self, filters: filters, type: type) do + filters&.each { |filter| instance_eval(&filter) } + end + post_extension = DSL::InsideRoute.post_filter_methods(type) + extend post_extension if post_extension + end + + def befores + namespace_stackable(:befores) + end + + def before_validations + namespace_stackable(:before_validations) + end + + def after_validations + namespace_stackable(:after_validations) + end + + def afters + namespace_stackable(:afters) + end + + def finallies + namespace_stackable(:finallies) + end + + def validations + return enum_for(:validations) unless block_given? + + route_setting(:saved_validations)&.each do |saved_validation| + yield Grape::Validations::ValidatorFactory.create_validator(saved_validation) + end + end + + def options? + options[:options_route_enabled] && + env[Rack::REQUEST_METHOD] == Rack::OPTIONS + end + + private + + def build_stack(helpers) + stack = Grape::Middleware::Stack.new + + content_types = namespace_stackable_with_hash(:content_types) + format = namespace_inheritable(:format) + + stack.use Rack::Head + stack.use Class.new(Grape::Middleware::Error), + helpers: helpers, + format: format, + content_types: content_types, + default_status: namespace_inheritable(:default_error_status), + rescue_all: namespace_inheritable(:rescue_all), + rescue_grape_exceptions: namespace_inheritable(:rescue_grape_exceptions), + default_error_formatter: namespace_inheritable(:default_error_formatter), + error_formatters: namespace_stackable_with_hash(:error_formatters), + rescue_options: namespace_stackable_with_hash(:rescue_options), + rescue_handlers: namespace_reverse_stackable_with_hash(:rescue_handlers), + base_only_rescue_handlers: namespace_stackable_with_hash(:base_only_rescue_handlers), + all_rescue_handler: namespace_inheritable(:all_rescue_handler), + grape_exceptions_rescue_handler: namespace_inheritable(:grape_exceptions_rescue_handler) + + stack.concat namespace_stackable(:middleware) + + if namespace_inheritable(:version).present? + stack.use Grape::Middleware::Versioner.using(namespace_inheritable(:version_options)[:using]), + versions: namespace_inheritable(:version).flatten, + version_options: namespace_inheritable(:version_options), + prefix: namespace_inheritable(:root_prefix), + mount_path: namespace_stackable(:mount_path).first + end + + stack.use Grape::Middleware::Formatter, + format: format, + default_format: namespace_inheritable(:default_format) || :txt, + content_types: content_types, + formatters: namespace_stackable_with_hash(:formatters), + parsers: namespace_stackable_with_hash(:parsers) + + builder = stack.build + builder.run ->(env) { env[Grape::Env::API_ENDPOINT].run } + builder.to_app + end + + def build_helpers + helpers = namespace_stackable(:helpers) + return if helpers.empty? + + Module.new { helpers.each { |mod_to_include| include mod_to_include } } + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/env.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/env.rb new file mode 100644 index 00000000..09392fd2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/env.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Grape + module Env + API_VERSION = 'api.version' + API_ENDPOINT = 'api.endpoint' + API_REQUEST_INPUT = 'api.request.input' + API_REQUEST_BODY = 'api.request.body' + API_TYPE = 'api.type' + API_SUBTYPE = 'api.subtype' + API_VENDOR = 'api.vendor' + API_FORMAT = 'api.format' + + GRAPE_REQUEST = 'grape.request' + GRAPE_REQUEST_HEADERS = 'grape.request.headers' + GRAPE_REQUEST_PARAMS = 'grape.request.params' + GRAPE_ROUTING_ARGS = 'grape.routing_args' + GRAPE_ALLOWED_METHODS = 'grape.allowed_methods' + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/error_formatter.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/error_formatter.rb new file mode 100644 index 00000000..7d9ace8a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/error_formatter.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Grape + module ErrorFormatter + extend Grape::Util::Registry + + module_function + + def formatter_for(format, error_formatters = nil, default_error_formatter = nil) + return error_formatters[format] if error_formatters&.key?(format) + + registry[format] || default_error_formatter || Grape::ErrorFormatter::Txt + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/error_formatter/base.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/error_formatter/base.rb new file mode 100644 index 00000000..f2cf223c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/error_formatter/base.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +module Grape + module ErrorFormatter + class Base + class << self + def call(message, backtrace, options = {}, env = nil, original_exception = nil) + merge_backtrace = backtrace.present? && options.dig(:rescue_options, :backtrace) + merge_original_exception = original_exception && options.dig(:rescue_options, :original_exception) + + wrapped_message = wrap_message(present(message, env)) + if wrapped_message.is_a?(Hash) + wrapped_message[:backtrace] = backtrace if merge_backtrace + wrapped_message[:original_exception] = original_exception.inspect if merge_original_exception + end + + format_structured_message(wrapped_message) + end + + def present(message, env) + present_options = {} + presented_message = message + if presented_message.is_a?(Hash) + presented_message = presented_message.dup + present_options[:with] = presented_message.delete(:with) + end + + presenter = env[Grape::Env::API_ENDPOINT].entity_class_for_obj(presented_message, present_options) + + unless presenter || env[Grape::Env::GRAPE_ROUTING_ARGS].nil? + # env['api.endpoint'].route does not work when the error occurs within a middleware + # the Endpoint does not have a valid env at this moment + http_codes = env[Grape::Env::GRAPE_ROUTING_ARGS][:route_info].http_codes || [] + + found_code = http_codes.find do |http_code| + (http_code[0].to_i == env[Grape::Env::API_ENDPOINT].status) && http_code[2].respond_to?(:represent) + end if env[Grape::Env::API_ENDPOINT].request + + presenter = found_code[2] if found_code + end + + if presenter + embeds = { env: env } + embeds[:version] = env[Grape::Env::API_VERSION] if env.key?(Grape::Env::API_VERSION) + presented_message = presenter.represent(presented_message, embeds).serializable_hash + end + + presented_message + end + + def wrap_message(message) + return message if message.is_a?(Hash) + + { message: message } + end + + def format_structured_message(_structured_message) + raise NotImplementedError + end + + def inherited(klass) + super + ErrorFormatter.register(klass) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/error_formatter/json.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/error_formatter/json.rb new file mode 100644 index 00000000..bed5bd39 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/error_formatter/json.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module Grape + module ErrorFormatter + class Json < Base + class << self + def format_structured_message(structured_message) + ::Grape::Json.dump(structured_message) + end + + private + + def wrap_message(message) + return message if message.is_a?(Hash) + return message.as_json if message.is_a?(Exceptions::ValidationErrors) + + { error: ensure_utf8(message) } + end + + def ensure_utf8(message) + return message unless message.respond_to? :encode + + message.encode('UTF-8', invalid: :replace, undef: :replace) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/error_formatter/jsonapi.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/error_formatter/jsonapi.rb new file mode 100644 index 00000000..ed1d2d30 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/error_formatter/jsonapi.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module Grape + module ErrorFormatter + class Jsonapi < Json; end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/error_formatter/serializable_hash.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/error_formatter/serializable_hash.rb new file mode 100644 index 00000000..14b9ed59 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/error_formatter/serializable_hash.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module Grape + module ErrorFormatter + class SerializableHash < Json; end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/error_formatter/txt.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/error_formatter/txt.rb new file mode 100644 index 00000000..7c0c7591 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/error_formatter/txt.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Grape + module ErrorFormatter + class Txt < Base + def self.format_structured_message(structured_message) + message = structured_message[:message] || Grape::Json.dump(structured_message) + Array.wrap(message).tap do |final_message| + if structured_message.key?(:backtrace) + final_message << 'backtrace:' + final_message.concat(structured_message[:backtrace]) + end + if structured_message.key?(:original_exception) + final_message << 'original exception:' + final_message << structured_message[:original_exception] + end + end.join("\r\n ") + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/error_formatter/xml.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/error_formatter/xml.rb new file mode 100644 index 00000000..c78f6d65 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/error_formatter/xml.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Grape + module ErrorFormatter + class Xml < Base + def self.format_structured_message(structured_message) + structured_message.respond_to?(:to_xml) ? structured_message.to_xml(root: :error) : structured_message.to_s + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/base.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/base.rb new file mode 100644 index 00000000..27ef78b4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/base.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true + +module Grape + module Exceptions + class Base < StandardError + BASE_MESSAGES_KEY = 'grape.errors.messages' + BASE_ATTRIBUTES_KEY = 'grape.errors.attributes' + FALLBACK_LOCALE = :en + + attr_reader :status, :headers + + def initialize(status: nil, message: nil, headers: nil) + super(message) + + @status = status + @headers = headers + end + + def [](index) + send index + end + + protected + + # TODO: translate attribute first + # if BASE_ATTRIBUTES_KEY.key respond to a string message, then short_message is returned + # if BASE_ATTRIBUTES_KEY.key respond to a Hash, means it may have problem , summary and resolution + def compose_message(key, **attributes) + short_message = translate_message(key, attributes) + return short_message unless short_message.is_a?(Hash) + + each_steps(key, attributes).with_object(+'') do |detail_array, message| + message << "\n#{detail_array[0]}:\n #{detail_array[1]}" unless detail_array[1].blank? + end + end + + def each_steps(key, attributes) + return enum_for(:each_steps, key, attributes) unless block_given? + + yield 'Problem', translate_message(:"#{key}.problem", attributes) + yield 'Summary', translate_message(:"#{key}.summary", attributes) + yield 'Resolution', translate_message(:"#{key}.resolution", attributes) + end + + def translate_attributes(keys, options = {}) + keys.map do |key| + translate("#{BASE_ATTRIBUTES_KEY}.#{key}", options.merge(default: key.to_s)) + end.join(', ') + end + + def translate_message(key, options = {}) + case key + when Symbol + translate("#{BASE_MESSAGES_KEY}.#{key}", options.merge(default: '')) + when Proc + key.call + else + key + end + end + + def translate(key, options) + message = ::I18n.translate(key, **options) + message.presence || fallback_message(key, options) + end + + def fallback_message(key, options) + if ::I18n.enforce_available_locales && ::I18n.available_locales.exclude?(FALLBACK_LOCALE) + key + else + ::I18n.translate(key, locale: FALLBACK_LOCALE, **options) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/empty_message_body.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/empty_message_body.rb new file mode 100644 index 00000000..c4fd4317 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/empty_message_body.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Grape + module Exceptions + class EmptyMessageBody < Base + def initialize(body_format) + super(message: compose_message(:empty_message_body, body_format: body_format), status: 400) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/incompatible_option_values.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/incompatible_option_values.rb new file mode 100644 index 00000000..aabe8d5e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/incompatible_option_values.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Grape + module Exceptions + class IncompatibleOptionValues < Base + def initialize(option1, value1, option2, value2) + super(message: compose_message(:incompatible_option_values, option1: option1, value1: value1, option2: option2, value2: value2)) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/invalid_accept_header.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/invalid_accept_header.rb new file mode 100644 index 00000000..fd98849c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/invalid_accept_header.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Grape + module Exceptions + class InvalidAcceptHeader < Base + def initialize(message, headers) + super(message: compose_message(:invalid_accept_header, message: message), status: 406, headers: headers) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/invalid_formatter.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/invalid_formatter.rb new file mode 100644 index 00000000..8c8a82f0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/invalid_formatter.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Grape + module Exceptions + class InvalidFormatter < Base + def initialize(klass, to_format) + super(message: compose_message(:invalid_formatter, klass: klass, to_format: to_format)) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/invalid_message_body.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/invalid_message_body.rb new file mode 100644 index 00000000..ac9c2efb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/invalid_message_body.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Grape + module Exceptions + class InvalidMessageBody < Base + def initialize(body_format) + super(message: compose_message(:invalid_message_body, body_format: body_format), status: 400) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/invalid_response.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/invalid_response.rb new file mode 100644 index 00000000..197f8399 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/invalid_response.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Grape + module Exceptions + class InvalidResponse < Base + def initialize + super(message: compose_message(:invalid_response)) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/invalid_version_header.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/invalid_version_header.rb new file mode 100644 index 00000000..cb01ec3d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/invalid_version_header.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Grape + module Exceptions + class InvalidVersionHeader < Base + def initialize(message, headers) + super(message: compose_message(:invalid_version_header, message: message), status: 406, headers: headers) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/invalid_versioner_option.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/invalid_versioner_option.rb new file mode 100644 index 00000000..9411370b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/invalid_versioner_option.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Grape + module Exceptions + class InvalidVersionerOption < Base + def initialize(strategy) + super(message: compose_message(:invalid_versioner_option, strategy: strategy)) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/invalid_with_option_for_represent.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/invalid_with_option_for_represent.rb new file mode 100644 index 00000000..d6a275fb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/invalid_with_option_for_represent.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Grape + module Exceptions + class InvalidWithOptionForRepresent < Base + def initialize + super(message: compose_message(:invalid_with_option_for_represent)) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/method_not_allowed.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/method_not_allowed.rb new file mode 100644 index 00000000..5777e4c2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/method_not_allowed.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Grape + module Exceptions + class MethodNotAllowed < Base + def initialize(headers) + super(message: '405 Not Allowed', status: 405, headers: headers) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/missing_group_type.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/missing_group_type.rb new file mode 100644 index 00000000..9a7d3180 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/missing_group_type.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Grape + module Exceptions + class MissingGroupType < Base + def initialize + super(message: compose_message(:missing_group_type)) + end + end + end +end + +Grape::Exceptions::MissingGroupTypeError = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('Grape::Exceptions::MissingGroupTypeError', 'Grape::Exceptions::MissingGroupType', Grape.deprecator) diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/missing_mime_type.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/missing_mime_type.rb new file mode 100644 index 00000000..5bf43a1d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/missing_mime_type.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Grape + module Exceptions + class MissingMimeType < Base + def initialize(new_format) + super(message: compose_message(:missing_mime_type, new_format: new_format)) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/missing_option.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/missing_option.rb new file mode 100644 index 00000000..ec35b96e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/missing_option.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Grape + module Exceptions + class MissingOption < Base + def initialize(option) + super(message: compose_message(:missing_option, option: option)) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/missing_vendor_option.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/missing_vendor_option.rb new file mode 100644 index 00000000..46e04885 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/missing_vendor_option.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Grape + module Exceptions + class MissingVendorOption < Base + def initialize + super(message: compose_message(:missing_vendor_option)) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/too_many_multipart_files.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/too_many_multipart_files.rb new file mode 100644 index 00000000..72deffb3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/too_many_multipart_files.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Grape + module Exceptions + class TooManyMultipartFiles < Base + def initialize(limit) + super(message: compose_message(:too_many_multipart_files, limit: limit), status: 413) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/unknown_options.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/unknown_options.rb new file mode 100644 index 00000000..0512a877 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/unknown_options.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Grape + module Exceptions + class UnknownOptions < Base + def initialize(options) + super(message: compose_message(:unknown_options, options: options)) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/unknown_parameter.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/unknown_parameter.rb new file mode 100644 index 00000000..0168ff39 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/unknown_parameter.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Grape + module Exceptions + class UnknownParameter < Base + def initialize(param) + super(message: compose_message(:unknown_parameter, param: param)) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/unknown_validator.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/unknown_validator.rb new file mode 100644 index 00000000..e856f2b3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/unknown_validator.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Grape + module Exceptions + class UnknownValidator < Base + def initialize(validator_type) + super(message: compose_message(:unknown_validator, validator_type: validator_type)) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/unsupported_group_type.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/unsupported_group_type.rb new file mode 100644 index 00000000..4c5e6396 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/unsupported_group_type.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Grape + module Exceptions + class UnsupportedGroupType < Base + def initialize + super(message: compose_message(:unsupported_group_type)) + end + end + end +end + +Grape::Exceptions::UnsupportedGroupTypeError = ActiveSupport::Deprecation::DeprecatedConstantProxy.new('Grape::Exceptions::UnsupportedGroupTypeError', 'Grape::Exceptions::UnsupportedGroupType', Grape.deprecator) diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/validation.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/validation.rb new file mode 100644 index 00000000..0a9e9c5d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/validation.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Grape + module Exceptions + class Validation < Base + attr_accessor :params, :message_key + + def initialize(params:, message: nil, status: nil, headers: nil) + @params = params + if message + @message_key = message if message.is_a?(Symbol) + message = translate_message(message) + end + + super(status: status, message: message, headers: headers) + end + + # Remove all the unnecessary stuff from Grape::Exceptions::Base like status + # and headers when converting a validation error to json or string + def as_json(*_args) + to_s + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/validation_array_errors.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/validation_array_errors.rb new file mode 100644 index 00000000..d7815b1f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/validation_array_errors.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Grape + module Exceptions + class ValidationArrayErrors < Base + attr_reader :errors + + def initialize(errors) + super() + @errors = errors + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/validation_errors.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/validation_errors.rb new file mode 100644 index 00000000..8859d579 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/exceptions/validation_errors.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +module Grape + module Exceptions + class ValidationErrors < Base + ERRORS_FORMAT_KEY = 'grape.errors.format' + DEFAULT_ERRORS_FORMAT = '%s %s' + + include Enumerable + + attr_reader :errors + + def initialize(errors: [], headers: {}) + @errors = errors.group_by(&:params) + super(message: full_messages.join(', '), status: 400, headers: headers) + end + + def each + errors.each_pair do |attribute, errors| + errors.each do |error| + yield attribute, error + end + end + end + + def as_json(**_opts) + errors.map do |k, v| + { + params: k, + messages: v.map(&:to_s) + } + end + end + + def to_json(*_opts) + as_json.to_json + end + + def full_messages + messages = map do |attributes, error| + I18n.t( + ERRORS_FORMAT_KEY, + default: DEFAULT_ERRORS_FORMAT, + attributes: translate_attributes(attributes), + message: error.message + ) + end + messages.uniq! + messages + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/extensions/active_support/hash_with_indifferent_access.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/extensions/active_support/hash_with_indifferent_access.rb new file mode 100644 index 00000000..2129e1c8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/extensions/active_support/hash_with_indifferent_access.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Grape + module Extensions + module ActiveSupport + module HashWithIndifferentAccess + module ParamBuilder + extend ::ActiveSupport::Concern + + included do + namespace_inheritable(:build_params_with, Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder) + end + + def params_builder + Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder + end + + def build_params + ::ActiveSupport::HashWithIndifferentAccess.new(rack_params).tap do |params| + params.deep_merge!(grape_routing_args) if env.key?(Grape::Env::GRAPE_ROUTING_ARGS) + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/extensions/hash.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/extensions/hash.rb new file mode 100644 index 00000000..cb8bd4b0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/extensions/hash.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module Grape + module Extensions + module Hash + module ParamBuilder + extend ::ActiveSupport::Concern + + included do + namespace_inheritable(:build_params_with, Grape::Extensions::Hash::ParamBuilder) + end + + def build_params + rack_params.deep_dup.tap do |params| + params.deep_symbolize_keys! + + if env.key?(Grape::Env::GRAPE_ROUTING_ARGS) + grape_routing_args.deep_symbolize_keys! + params.deep_merge!(grape_routing_args) + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/extensions/hashie/mash.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/extensions/hashie/mash.rb new file mode 100644 index 00000000..b6ae5061 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/extensions/hashie/mash.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module Grape + module Extensions + module Hashie + module Mash + module ParamBuilder + extend ::ActiveSupport::Concern + included do + namespace_inheritable(:build_params_with, Grape::Extensions::Hashie::Mash::ParamBuilder) + end + + def params_builder + Grape::Extensions::Hashie::Mash::ParamBuilder + end + + def build_params + ::Hashie::Mash.new(rack_params).tap do |params| + params.deep_merge!(grape_routing_args) if env.key?(Grape::Env::GRAPE_ROUTING_ARGS) + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/formatter.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/formatter.rb new file mode 100644 index 00000000..6d5affb3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/formatter.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Grape + module Formatter + extend Grape::Util::Registry + + module_function + + DEFAULT_LAMBDA_FORMATTER = ->(obj, _env) { obj } + + def formatter_for(api_format, formatters) + return formatters[api_format] if formatters&.key?(api_format) + + registry[api_format] || DEFAULT_LAMBDA_FORMATTER + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/formatter/base.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/formatter/base.rb new file mode 100644 index 00000000..dfd56d65 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/formatter/base.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Grape + module Formatter + class Base + def self.call(_object, _env) + raise NotImplementedError + end + + def self.inherited(klass) + super + Formatter.register(klass) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/formatter/json.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/formatter/json.rb new file mode 100644 index 00000000..bfdd2ca2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/formatter/json.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Grape + module Formatter + class Json < Base + def self.call(object, _env) + return object.to_json if object.respond_to?(:to_json) + + ::Grape::Json.dump(object) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/formatter/serializable_hash.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/formatter/serializable_hash.rb new file mode 100644 index 00000000..5b29ece1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/formatter/serializable_hash.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +module Grape + module Formatter + class SerializableHash < Base + class << self + def call(object, _env) + return object if object.is_a?(String) + return ::Grape::Json.dump(serialize(object)) if serializable?(object) + return object.to_json if object.respond_to?(:to_json) + + ::Grape::Json.dump(object) + end + + private + + def serializable?(object) + object.respond_to?(:serializable_hash) || array_serializable?(object) || object.is_a?(Hash) + end + + def serialize(object) + if object.respond_to? :serializable_hash + object.serializable_hash + elsif array_serializable?(object) + object.map(&:serializable_hash) + elsif object.is_a?(Hash) + object.transform_values { |v| serialize(v) } + else + object + end + end + + def array_serializable?(object) + object.is_a?(Array) && object.all? { |o| o.respond_to? :serializable_hash } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/formatter/txt.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/formatter/txt.rb new file mode 100644 index 00000000..cb77e4f0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/formatter/txt.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Grape + module Formatter + class Txt < Base + def self.call(object, _env) + object.respond_to?(:to_txt) ? object.to_txt : object.to_s + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/formatter/xml.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/formatter/xml.rb new file mode 100644 index 00000000..de053175 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/formatter/xml.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Grape + module Formatter + class Xml < Base + def self.call(object, _env) + return object.to_xml if object.respond_to?(:to_xml) + + raise Grape::Exceptions::InvalidFormatter.new(object.class, 'xml') + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/http/headers.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/http/headers.rb new file mode 100644 index 00000000..eb4d3891 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/http/headers.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +module Grape + module Http + module Headers + HTTP_ACCEPT_VERSION = 'HTTP_ACCEPT_VERSION' + HTTP_ACCEPT = 'HTTP_ACCEPT' + HTTP_TRANSFER_ENCODING = 'HTTP_TRANSFER_ENCODING' + HTTP_VERSION = 'HTTP_VERSION' + + ALLOW = 'Allow' + LOCATION = 'Location' + X_CASCADE = 'X-Cascade' + TRANSFER_ENCODING = 'Transfer-Encoding' + + SUPPORTED_METHODS = [ + Rack::GET, + Rack::POST, + Rack::PUT, + Rack::PATCH, + Rack::DELETE, + Rack::HEAD, + Rack::OPTIONS + ].freeze + + SUPPORTED_METHODS_WITHOUT_OPTIONS = (SUPPORTED_METHODS - [Rack::OPTIONS]).freeze + + HTTP_HEADERS = Grape::Util::Lazy::Object.new do + common_http_headers = %w[ + Version + Host + Connection + Cache-Control + Dnt + Upgrade-Insecure-Requests + User-Agent + Sec-Fetch-Dest + Accept + Sec-Fetch-Site + Sec-Fetch-Mode + Sec-Fetch-User + Accept-Encoding + Accept-Language + Cookie + ].freeze + common_http_headers.each_with_object({}) do |header, response| + response["HTTP_#{header.upcase.tr('-', '_')}"] = header + end.freeze + end + + def self.find_supported_method(route_method) + Grape::Http::Headers::SUPPORTED_METHODS.detect { |supported_method| supported_method.casecmp(route_method).zero? } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/json.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/json.rb new file mode 100644 index 00000000..a3001453 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/json.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module Grape + if defined?(::MultiJson) + Json = ::MultiJson + else + Json = ::JSON + Json::ParseError = Json::ParserError + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/locale/en.yml b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/locale/en.yml new file mode 100644 index 00000000..6b1b6ae0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/locale/en.yml @@ -0,0 +1,59 @@ +en: + grape: + errors: + format: ! '%{attributes} %{message}' + messages: + coerce: 'is invalid' + presence: 'is missing' + regexp: 'is invalid' + blank: 'is empty' + values: 'does not have a valid value' + except_values: 'has a value not allowed' + same_as: 'is not the same as %{parameter}' + length: 'is expected to have length within %{min} and %{max}' + length_is: 'is expected to have length exactly equal to %{is}' + length_min: 'is expected to have length greater than or equal to %{min}' + length_max: 'is expected to have length less than or equal to %{max}' + missing_vendor_option: + problem: 'missing :vendor option' + summary: 'when version using header, you must specify :vendor option' + resolution: "eg: version 'v1', using: :header, vendor: 'twitter'" + missing_mime_type: + problem: 'missing mime type for %{new_format}' + resolution: + "you can choose existing mime type from Grape::ContentTypes::CONTENT_TYPES + or add your own with content_type :%{new_format}, 'application/%{new_format}' + " + invalid_with_option_for_represent: + problem: 'you must specify an entity class in the :with option' + resolution: 'eg: represent User, :with => Entity::User' + missing_option: 'you must specify :%{option} options' + invalid_formatter: 'cannot convert %{klass} to %{to_format}' + invalid_versioner_option: + problem: 'unknown :using for versioner: %{strategy}' + resolution: 'available strategy for :using is :path, :header, :accept_version_header, :param' + unknown_validator: 'unknown validator: %{validator_type}' + unknown_options: 'unknown options: %{options}' + unknown_parameter: 'unknown parameter: %{param}' + incompatible_option_values: '%{option1}: %{value1} is incompatible with %{option2}: %{value2}' + mutual_exclusion: 'are mutually exclusive' + at_least_one: 'are missing, at least one parameter must be provided' + exactly_one: 'are missing, exactly one parameter must be provided' + all_or_none: 'provide all or none of parameters' + missing_group_type: 'group type is required' + unsupported_group_type: 'group type must be Array, Hash, JSON or Array[JSON]' + invalid_message_body: + problem: "message body does not match declared format" + resolution: + "when specifying %{body_format} as content-type, you must pass valid + %{body_format} in the request's 'body' + " + empty_message_body: 'empty message body supplied with %{body_format} content-type' + too_many_multipart_files: "the number of uploaded files exceeded the system's configured limit (%{limit})" + invalid_accept_header: + problem: 'invalid accept header' + resolution: '%{message}' + invalid_version_header: + problem: 'invalid version header' + resolution: '%{message}' + invalid_response: 'Invalid response' diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/auth/base.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/auth/base.rb new file mode 100644 index 00000000..d7703cd7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/auth/base.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +module Grape + module Middleware + module Auth + class Base + include Helpers + + attr_accessor :options, :app, :env + + def initialize(app, *options) + @app = app + @options = options.shift + end + + def call(env) + dup._call(env) + end + + def _call(env) + self.env = env + + if options.key?(:type) + auth_proc = options[:proc] + auth_proc_context = context + + strategy_info = Grape::Middleware::Auth::Strategies[options[:type]] + + throw(:error, status: 401, message: 'API Authorization Failed.') if strategy_info.blank? + + strategy = strategy_info.create(@app, options) do |*args| + auth_proc_context.instance_exec(*args, &auth_proc) + end + + strategy.call(env) + + else + app.call(env) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/auth/dsl.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/auth/dsl.rb new file mode 100644 index 00000000..598358d9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/auth/dsl.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module Grape + module Middleware + module Auth + module DSL + extend ActiveSupport::Concern + + module ClassMethods + # Add an authentication type to the API. Currently + # only `:http_basic`, `:http_digest` are supported. + def auth(type = nil, options = {}, &block) + if type + namespace_inheritable(:auth, options.reverse_merge(type: type.to_sym, proc: block)) + use Grape::Middleware::Auth::Base, namespace_inheritable(:auth) + else + namespace_inheritable(:auth) + end + end + + # Add HTTP Basic authorization to the API. + # + # @param [Hash] options A hash of options. + # @option options [String] :realm "API Authorization" The HTTP Basic realm. + def http_basic(options = {}, &block) + options[:realm] ||= 'API Authorization' + auth :http_basic, options, &block + end + + def http_digest(options = {}, &block) + options[:realm] ||= 'API Authorization' + + if options[:realm].respond_to?(:values_at) + options[:realm][:opaque] ||= 'secret' + else + options[:opaque] ||= 'secret' + end + + auth :http_digest, options, &block + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/auth/strategies.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/auth/strategies.rb new file mode 100644 index 00000000..56855263 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/auth/strategies.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Grape + module Middleware + module Auth + module Strategies + module_function + + def add(label, strategy, option_fetcher = ->(_) { [] }) + auth_strategies[label] = StrategyInfo.new(strategy, option_fetcher) + end + + def auth_strategies + @auth_strategies ||= { + http_basic: StrategyInfo.new(Rack::Auth::Basic, ->(settings) { [settings[:realm]] }) + } + end + + def [](label) + auth_strategies[label] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/auth/strategy_info.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/auth/strategy_info.rb new file mode 100644 index 00000000..20eb25b7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/auth/strategy_info.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Grape + module Middleware + module Auth + StrategyInfo = Struct.new(:auth_class, :settings_fetcher) do + def create(app, options, &block) + strategy_args = settings_fetcher.call(options) + + auth_class.new(app, *strategy_args, &block) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/base.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/base.rb new file mode 100644 index 00000000..af7195f8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/base.rb @@ -0,0 +1,95 @@ +# frozen_string_literal: true + +module Grape + module Middleware + class Base + include Helpers + include Grape::DSL::Headers + + attr_reader :app, :env, :options + + TEXT_HTML = 'text/html' + + # @param [Rack Application] app The standard argument for a Rack middleware. + # @param [Hash] options A hash of options, simply stored for use by subclasses. + def initialize(app, *options) + @app = app + @options = options.any? ? default_options.deep_merge(options.shift) : default_options + @app_response = nil + end + + def default_options + {} + end + + def call(env) + dup.call!(env).to_a + end + + def call!(env) + @env = env + before + begin + @app_response = @app.call(@env) + ensure + begin + after_response = after + rescue StandardError => e + warn "caught error of type #{e.class} in after callback inside #{self.class.name} : #{e.message}" + raise e + end + end + + response = after_response || @app_response + merge_headers response + response + end + + # @abstract + # Called before the application is called in the middleware lifecycle. + def before; end + + # @abstract + # Called after the application is called in the middleware lifecycle. + # @return [Response, nil] a Rack SPEC response or nil to call the application afterwards. + def after; end + + def response + return @app_response if @app_response.is_a?(Rack::Response) + + @app_response = Rack::Response.new(@app_response[2], @app_response[0], @app_response[1]) + end + + def content_types + @content_types ||= Grape::ContentTypes.content_types_for(options[:content_types]) + end + + def mime_types + @mime_types ||= Grape::ContentTypes.mime_types_for(content_types) + end + + def content_type_for(format) + content_types_indifferent_access[format] + end + + def content_type + content_type_for(env[Grape::Env::API_FORMAT] || options[:format]) || TEXT_HTML + end + + private + + def merge_headers(response) + return unless headers.is_a?(Hash) + + case response + when Rack::Response then response.headers.merge!(headers) + when Array then response[1].merge!(headers) + end + end + + def content_types_indifferent_access + @content_types_indifferent_access ||= content_types.with_indifferent_access + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/error.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/error.rb new file mode 100644 index 00000000..2dd39bc1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/error.rb @@ -0,0 +1,148 @@ +# frozen_string_literal: true + +module Grape + module Middleware + class Error < Base + def default_options + { + default_status: 500, # default status returned on error + default_message: '', + format: :txt, + helpers: nil, + formatters: {}, + error_formatters: {}, + rescue_all: false, # true to rescue all exceptions + rescue_grape_exceptions: false, + rescue_subclasses: true, # rescue subclasses of exceptions listed + rescue_options: { + backtrace: false, # true to display backtrace, true to let Grape handle Grape::Exceptions + original_exception: false # true to display exception + }, + rescue_handlers: {}, # rescue handler blocks + base_only_rescue_handlers: {}, # rescue handler blocks rescuing only the base class + all_rescue_handler: nil # rescue handler block to rescue from all exceptions + } + end + + def initialize(app, *options) + super + self.class.include(@options[:helpers]) if @options[:helpers] + end + + def call!(env) + @env = env + error_response(catch(:error) { return @app.call(@env) }) + rescue Exception => e # rubocop:disable Lint/RescueException + run_rescue_handler(find_handler(e.class), e, @env[Grape::Env::API_ENDPOINT]) + end + + private + + def rack_response(status, headers, message) + message = Rack::Utils.escape_html(message) if headers[Rack::CONTENT_TYPE] == TEXT_HTML + Rack::Response.new(Array.wrap(message), Rack::Utils.status_code(status), Grape::Util::Header.new.merge(headers)) + end + + def format_message(message, backtrace, original_exception = nil) + format = env[Grape::Env::API_FORMAT] || options[:format] + formatter = Grape::ErrorFormatter.formatter_for(format, options[:error_formatters], options[:default_error_formatter]) + return formatter.call(message, backtrace, options, env, original_exception) if formatter + + throw :error, + status: 406, + message: "The requested format '#{format}' is not supported.", + backtrace: backtrace, + original_exception: original_exception + end + + def find_handler(klass) + rescue_handler_for_base_only_class(klass) || + rescue_handler_for_class_or_its_ancestor(klass) || + rescue_handler_for_grape_exception(klass) || + rescue_handler_for_any_class(klass) || + raise + end + + def error_response(error = {}) + status = error[:status] || options[:default_status] + env[Grape::Env::API_ENDPOINT].status(status) # error! may not have been called + message = error[:message] || options[:default_message] + headers = { Rack::CONTENT_TYPE => content_type }.tap do |h| + h.merge!(error[:headers]) if error[:headers].is_a?(Hash) + end + backtrace = error[:backtrace] || error[:original_exception]&.backtrace || [] + original_exception = error.is_a?(Exception) ? error : error[:original_exception] || nil + rack_response(status, headers, format_message(message, backtrace, original_exception)) + end + + def default_rescue_handler(exception) + error_response(message: exception.message, backtrace: exception.backtrace, original_exception: exception) + end + + def rescue_handler_for_base_only_class(klass) + error, handler = options[:base_only_rescue_handlers]&.find { |err, _handler| klass == err } + + return unless error + + handler || method(:default_rescue_handler) + end + + def rescue_handler_for_class_or_its_ancestor(klass) + error, handler = options[:rescue_handlers]&.find { |err, _handler| klass <= err } + + return unless error + + handler || method(:default_rescue_handler) + end + + def rescue_handler_for_grape_exception(klass) + return unless klass <= Grape::Exceptions::Base + return method(:error_response) if klass == Grape::Exceptions::InvalidVersionHeader + return unless options[:rescue_grape_exceptions] || !options[:rescue_all] + + options[:grape_exceptions_rescue_handler] || method(:error_response) + end + + def rescue_handler_for_any_class(klass) + return unless klass <= StandardError + return unless options[:rescue_all] || options[:rescue_grape_exceptions] + + options[:all_rescue_handler] || method(:default_rescue_handler) + end + + def run_rescue_handler(handler, error, endpoint) + if handler.instance_of?(Symbol) + raise NoMethodError, "undefined method '#{handler}'" unless respond_to?(handler) + + handler = public_method(handler) + end + + response = catch(:error) do + handler.arity.zero? ? endpoint.instance_exec(&handler) : endpoint.instance_exec(error, &handler) + end + + if error?(response) + error_response(response) + elsif response.is_a?(Rack::Response) + response + else + run_rescue_handler(method(:default_rescue_handler), Grape::Exceptions::InvalidResponse.new, endpoint) + end + end + + def error!(message, status = options[:default_status], headers = {}, backtrace = [], original_exception = nil) + env[Grape::Env::API_ENDPOINT].status(status) # not error! inside route + rack_response( + status, headers.reverse_merge(Rack::CONTENT_TYPE => content_type), + format_message(message, backtrace, original_exception) + ) + end + + def error?(response) + return false unless response.is_a?(Hash) + + response.key?(:message) && response.key?(:status) && response.key?(:headers) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/filter.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/filter.rb new file mode 100644 index 00000000..10d04469 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/filter.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Grape + module Middleware + # This is a simple middleware for adding before and after filters + # to Grape APIs. It is used like so: + # + # use Grape::Middleware::Filter, before: -> { do_something }, after: -> { do_something } + class Filter < Base + def before + app.instance_eval(&options[:before]) if options[:before] + end + + def after + app.instance_eval(&options[:after]) if options[:after] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/formatter.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/formatter.rb new file mode 100644 index 00000000..5cb76146 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/formatter.rb @@ -0,0 +1,182 @@ +# frozen_string_literal: true + +module Grape + module Middleware + class Formatter < Base + CHUNKED = 'chunked' + FORMAT = 'format' + + def default_options + { + default_format: :txt, + formatters: {}, + parsers: {} + } + end + + def before + negotiate_content_type + read_body_input + end + + def after + return unless @app_response + + status, headers, bodies = *@app_response + + if Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.include?(status) + [status, headers, []] + else + build_formatted_response(status, headers, bodies) + end + end + + private + + def build_formatted_response(status, headers, bodies) + headers = ensure_content_type(headers) + + if bodies.is_a?(Grape::ServeStream::StreamResponse) + Grape::ServeStream::SendfileResponse.new([], status, headers) do |resp| + resp.body = bodies.stream + end + else + # Allow content-type to be explicitly overwritten + formatter = fetch_formatter(headers, options) + bodymap = ActiveSupport::Notifications.instrument('format_response.grape', formatter: formatter, env: env) do + bodies.collect { |body| formatter.call(body, env) } + end + Rack::Response.new(bodymap, status, headers) + end + rescue Grape::Exceptions::InvalidFormatter => e + throw :error, status: 500, message: e.message, backtrace: e.backtrace, original_exception: e + end + + def fetch_formatter(headers, options) + api_format = env.fetch(Grape::Env::API_FORMAT) { mime_types[headers[Rack::CONTENT_TYPE]] } + Grape::Formatter.formatter_for(api_format, options[:formatters]) + end + + # Set the content type header for the API format if it is not already present. + # + # @param headers [Hash] + # @return [Hash] + def ensure_content_type(headers) + if headers[Rack::CONTENT_TYPE] + headers + else + headers.merge(Rack::CONTENT_TYPE => content_type_for(env[Grape::Env::API_FORMAT])) + end + end + + def request + @request ||= Rack::Request.new(env) + end + + # store read input in env['api.request.input'] + def read_body_input + return unless + (request.post? || request.put? || request.patch? || request.delete?) && + (!request.form_data? || !request.media_type) && + !request.parseable_data? && + (request.content_length.to_i.positive? || request.env[Grape::Http::Headers::HTTP_TRANSFER_ENCODING] == CHUNKED) + + return unless (input = env[Rack::RACK_INPUT]) + + rewind_input input + body = env[Grape::Env::API_REQUEST_INPUT] = input.read + begin + read_rack_input(body) if body && !body.empty? + ensure + rewind_input input + end + end + + # store parsed input in env['api.request.body'] + def read_rack_input(body) + fmt = request.media_type ? mime_types[request.media_type] : options[:default_format] + + throw :error, status: 415, message: "The provided content-type '#{request.media_type}' is not supported." unless content_type_for(fmt) + parser = Grape::Parser.parser_for fmt, options[:parsers] + if parser + begin + body = (env[Grape::Env::API_REQUEST_BODY] = parser.call(body, env)) + if body.is_a?(Hash) + env[Rack::RACK_REQUEST_FORM_HASH] = if env.key?(Rack::RACK_REQUEST_FORM_HASH) + env[Rack::RACK_REQUEST_FORM_HASH].merge(body) + else + body + end + env[Rack::RACK_REQUEST_FORM_INPUT] = env[Rack::RACK_INPUT] + end + rescue Grape::Exceptions::Base => e + raise e + rescue StandardError => e + throw :error, status: 400, message: e.message, backtrace: e.backtrace, original_exception: e + end + else + env[Grape::Env::API_REQUEST_BODY] = body + end + end + + def negotiate_content_type + fmt = format_from_extension || format_from_params || options[:format] || format_from_header || options[:default_format] + if content_type_for(fmt) + env[Grape::Env::API_FORMAT] = fmt + else + throw :error, status: 406, message: "The requested format '#{fmt}' is not supported." + end + end + + def format_from_extension + parts = request.path.split('.') + + if parts.size > 1 + extension = parts.last + # avoid symbol memory leak on an unknown format + return extension.to_sym if content_type_for(extension) + end + nil + end + + def format_from_params + fmt = Rack::Utils.parse_nested_query(env[Rack::QUERY_STRING])[FORMAT] + # avoid symbol memory leak on an unknown format + return fmt.to_sym if content_type_for(fmt) + + fmt + end + + def format_from_header + mime_array.each do |t| + return mime_types[t] if mime_types.key?(t) + end + nil + end + + def mime_array + accept = env[Grape::Http::Headers::HTTP_ACCEPT] + return [] unless accept + + accept_into_mime_and_quality = %r{ + ( + \w+/[\w+.-]+) # eg application/vnd.example.myformat+xml + (?: + (?:;[^,]*?)? # optionally multiple formats in a row + ;\s*q=([\w.]+) # optional "quality" preference (eg q=0.5) + )? + }x + + vendor_prefix_pattern = /vnd\.[^+]+\+/ + + accept.scan(accept_into_mime_and_quality) + .sort_by { |_, quality_preference| -(quality_preference ? quality_preference.to_f : 1.0) } + .flat_map { |mime, _| [mime, mime.sub(vendor_prefix_pattern, '')] } + end + + def rewind_input(input) + input.rewind if input.respond_to?(:rewind) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/globals.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/globals.rb new file mode 100644 index 00000000..81fa9b1f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/globals.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Grape + module Middleware + class Globals < Base + def before + request = Grape::Request.new(@env, build_params_with: @options[:build_params_with]) + @env[Grape::Env::GRAPE_REQUEST] = request + @env[Grape::Env::GRAPE_REQUEST_HEADERS] = request.headers + @env[Grape::Env::GRAPE_REQUEST_PARAMS] = request.params if @env[Rack::RACK_INPUT] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/helpers.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/helpers.rb new file mode 100644 index 00000000..013a9587 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/helpers.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module Grape + module Middleware + # Common methods for all types of Grape middleware + module Helpers + def context + env[Grape::Env::API_ENDPOINT] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/stack.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/stack.rb new file mode 100644 index 00000000..8e25af38 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/stack.rb @@ -0,0 +1,119 @@ +# frozen_string_literal: true + +module Grape + module Middleware + # Class to handle the stack of middlewares based on ActionDispatch::MiddlewareStack + # It allows to insert and insert after + class Stack + class Middleware + attr_reader :args, :block, :klass + + def initialize(klass, *args, &block) + @klass = klass + @args = args + @block = block + end + + def name + klass.name + end + + def ==(other) + case other + when Middleware + klass == other.klass + when Class + klass == other || (name.nil? && klass.superclass == other) + end + end + + def inspect + klass.to_s + end + + def use_in(builder) + builder.use(@klass, *@args, &@block) + end + end + + include Enumerable + + attr_accessor :middlewares, :others + + def initialize + @middlewares = [] + @others = [] + end + + def each(&block) + @middlewares.each(&block) + end + + def size + middlewares.size + end + + def last + middlewares.last + end + + def [](index) + middlewares[index] + end + + def insert(index, *args, &block) + index = assert_index(index, :before) + middleware = self.class::Middleware.new(*args, &block) + middlewares.insert(index, middleware) + end + ruby2_keywords :insert if respond_to?(:ruby2_keywords, true) + + alias insert_before insert + + def insert_after(index, *args, &block) + index = assert_index(index, :after) + insert(index + 1, *args, &block) + end + ruby2_keywords :insert_after if respond_to?(:ruby2_keywords, true) + + def use(...) + middleware = self.class::Middleware.new(...) + middlewares.push(middleware) + end + + def merge_with(middleware_specs) + middleware_specs.each do |operation, *args| + if args.last.is_a?(Proc) + last_proc = args.pop + public_send(operation, *args, &last_proc) + else + public_send(operation, *args) + end + end + end + + # @return [Rack::Builder] the builder object with our middlewares applied + def build(builder = Rack::Builder.new) + others.shift(others.size).each { |m| merge_with(m) } + middlewares.each do |m| + m.use_in(builder) + end + builder + end + + # @description Add middlewares with :use operation to the stack. Store others with :insert_* operation for later + # @param [Array] other_specs An array of middleware specifications (e.g. [[:use, klass], [:insert_before, *args]]) + def concat(other_specs) + @others << Array(other_specs).reject { |o| o.first == :use } + merge_with(Array(other_specs).select { |o| o.first == :use }) + end + + protected + + def assert_index(index, where) + i = index.is_a?(Integer) ? index : middlewares.index(index) + i || raise("No such middleware to insert #{where}: #{index.inspect}") + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/versioner.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/versioner.rb new file mode 100644 index 00000000..bcca9fe5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/versioner.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +# Versioners set env['api.version'] when a version is defined on an API and +# on the requests. The current methods for determining version are: +# +# :header - version from HTTP Accept header. +# :accept_version_header - version from HTTP Accept-Version header +# :path - version from uri. e.g. /v1/resource +# :param - version from uri query string, e.g. /v1/resource?apiver=v1 +# See individual classes for details. +module Grape + module Middleware + module Versioner + extend Grape::Util::Registry + + module_function + + # @param strategy [Symbol] :path, :header, :accept_version_header or :param + # @return a middleware class based on strategy + def using(strategy) + raise Grape::Exceptions::InvalidVersionerOption, strategy unless registry.key?(strategy) + + registry[strategy] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/versioner/accept_version_header.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/versioner/accept_version_header.rb new file mode 100644 index 00000000..aa7a8b35 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/versioner/accept_version_header.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +module Grape + module Middleware + module Versioner + # This middleware sets various version related rack environment variables + # based on the HTTP Accept-Version header + # + # Example: For request header + # Accept-Version: v1 + # + # The following rack env variables are set: + # + # env['api.version'] => 'v1' + # + # If version does not match this route, then a 406 is raised with + # X-Cascade header to alert Grape::Router to attempt the next matched + # route. + class AcceptVersionHeader < Base + def before + potential_version = env[Grape::Http::Headers::HTTP_ACCEPT_VERSION] + potential_version = potential_version.scrub unless potential_version.nil? + + not_acceptable!('Accept-Version header must be set.') if strict? && potential_version.blank? + + return if potential_version.blank? + + not_acceptable!('The requested version is not supported.') unless potential_version_match?(potential_version) + env[Grape::Env::API_VERSION] = potential_version + end + + private + + def not_acceptable!(message) + throw :error, status: 406, headers: error_headers, message: message + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/versioner/base.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/versioner/base.rb new file mode 100644 index 00000000..68604f14 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/versioner/base.rb @@ -0,0 +1,82 @@ +# frozen_string_literal: true + +module Grape + module Middleware + module Versioner + class Base < Grape::Middleware::Base + DEFAULT_PATTERN = /.*/i.freeze + DEFAULT_PARAMETER = 'apiver' + + def self.inherited(klass) + super + Versioner.register(klass) + end + + def default_options + { + versions: nil, + prefix: nil, + mount_path: nil, + pattern: DEFAULT_PATTERN, + version_options: { + strict: false, + cascade: true, + parameter: DEFAULT_PARAMETER + } + } + end + + def versions + options[:versions] + end + + def prefix + options[:prefix] + end + + def mount_path + options[:mount_path] + end + + def pattern + options[:pattern] + end + + def version_options + options[:version_options] + end + + def strict? + version_options[:strict] + end + + # By default those errors contain an `X-Cascade` header set to `pass`, which allows nesting and stacking + # of routes (see Grape::Router) for more information). To prevent + # this behavior, and not add the `X-Cascade` header, one can set the `:cascade` option to `false`. + def cascade? + version_options[:cascade] + end + + def parameter_key + version_options[:parameter] + end + + def vendor + version_options[:vendor] + end + + def error_headers + cascade? ? { Grape::Http::Headers::X_CASCADE => 'pass' } : {} + end + + def potential_version_match?(potential_version) + versions.blank? || versions.any? { |v| v.to_s == potential_version } + end + + def version_not_found! + throw :error, status: 404, message: '404 API Version Not Found', headers: { Grape::Http::Headers::X_CASCADE => 'pass' } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/versioner/header.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/versioner/header.rb new file mode 100644 index 00000000..a34a80fc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/versioner/header.rb @@ -0,0 +1,127 @@ +# frozen_string_literal: true + +module Grape + module Middleware + module Versioner + # This middleware sets various version related rack environment variables + # based on the HTTP Accept header with the pattern: + # application/vnd.:vendor-:version+:format + # + # Example: For request header + # Accept: application/vnd.mycompany.a-cool-resource-v1+json + # + # The following rack env variables are set: + # + # env['api.type'] => 'application' + # env['api.subtype'] => 'vnd.mycompany.a-cool-resource-v1+json' + # env['api.vendor] => 'mycompany.a-cool-resource' + # env['api.version] => 'v1' + # env['api.format] => 'json' + # + # If version does not match this route, then a 406 is raised with + # X-Cascade header to alert Grape::Router to attempt the next matched + # route. + class Header < Base + def before + match_best_quality_media_type! do |media_type| + env.update( + Grape::Env::API_TYPE => media_type.type, + Grape::Env::API_SUBTYPE => media_type.subtype, + Grape::Env::API_VENDOR => media_type.vendor, + Grape::Env::API_VERSION => media_type.version, + Grape::Env::API_FORMAT => media_type.format + ) + end + end + + private + + def match_best_quality_media_type! + return unless vendor + + strict_header_checks! + media_type = Grape::Util::MediaType.best_quality(accept_header, available_media_types) + if media_type + yield media_type + else + fail! + end + end + + def accept_header + env[Grape::Http::Headers::HTTP_ACCEPT] + end + + def strict_header_checks! + return unless strict? + + accept_header_check! + version_and_vendor_check! + end + + def accept_header_check! + return if accept_header.present? + + invalid_accept_header!('Accept header must be set.') + end + + def version_and_vendor_check! + return if versions.blank? || version_and_vendor? + + invalid_accept_header!('API vendor or version not found.') + end + + def q_values_mime_types + @q_values_mime_types ||= Rack::Utils.q_values(accept_header).map(&:first) + end + + def version_and_vendor? + q_values_mime_types.any? { |mime_type| Grape::Util::MediaType.match?(mime_type) } + end + + def invalid_accept_header!(message) + raise Grape::Exceptions::InvalidAcceptHeader.new(message, error_headers) + end + + def invalid_version_header!(message) + raise Grape::Exceptions::InvalidVersionHeader.new(message, error_headers) + end + + def fail! + return if env[Grape::Env::GRAPE_ALLOWED_METHODS].present? + + media_types = q_values_mime_types.map { |mime_type| Grape::Util::MediaType.parse(mime_type) } + vendor_not_found!(media_types) || version_not_found!(media_types) + end + + def vendor_not_found!(media_types) + return unless media_types.all? { |media_type| media_type&.vendor && media_type.vendor != vendor } + + invalid_accept_header!('API vendor not found.') + end + + def version_not_found!(media_types) + return unless media_types.all? { |media_type| media_type&.version && versions&.exclude?(media_type.version) } + + invalid_version_header!('API version not found.') + end + + def available_media_types + [].tap do |available_media_types| + base_media_type = "application/vnd.#{vendor}" + content_types.each_key do |extension| + versions&.reverse_each do |version| + available_media_types << "#{base_media_type}-#{version}+#{extension}" + available_media_types << "#{base_media_type}-#{version}" + end + available_media_types << "#{base_media_type}+#{extension}" + end + + available_media_types << base_media_type + available_media_types.concat(content_types.values.flatten) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/versioner/param.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/versioner/param.rb new file mode 100644 index 00000000..771faf61 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/versioner/param.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +module Grape + module Middleware + module Versioner + # This middleware sets various version related rack environment variables + # based on the request parameters and removes that parameter from the + # request parameters for subsequent middleware and API. + # If the version substring does not match any potential initialized + # versions, a 404 error is thrown. + # If the version substring is not passed the version (highest mounted) + # version will be used. + # + # Example: For a uri path + # /resource?apiver=v1 + # + # The following rack env variables are set and path is rewritten to + # '/resource': + # + # env['api.version'] => 'v1' + class Param < Base + def before + potential_version = Rack::Utils.parse_nested_query(env[Rack::QUERY_STRING])[parameter_key] + return if potential_version.blank? + + version_not_found! unless potential_version_match?(potential_version) + env[Grape::Env::API_VERSION] = potential_version + env[Rack::RACK_REQUEST_QUERY_HASH].delete(parameter_key) if env.key? Rack::RACK_REQUEST_QUERY_HASH + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/versioner/path.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/versioner/path.rb new file mode 100644 index 00000000..dd437976 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/middleware/versioner/path.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +module Grape + module Middleware + module Versioner + # This middleware sets various version related rack environment variables + # based on the uri path and removes the version substring from the uri + # path. If the version substring does not match any potential initialized + # versions, a 404 error is thrown. + # + # Example: For a uri path + # /v1/resource + # + # The following rack env variables are set and path is rewritten to + # '/resource': + # + # env['api.version'] => 'v1' + # + class Path < Base + def before + path_info = Grape::Router.normalize_path(env[Rack::PATH_INFO]) + return if path_info == '/' + + [mount_path, Grape::Router.normalize_path(prefix)].each do |path| + path_info.delete_prefix!(path) if path.present? && path != '/' && path_info.start_with?(path) + end + + slash_position = path_info.index('/', 1) # omit the first one + return unless slash_position + + potential_version = path_info[1..slash_position - 1] + return unless potential_version.match?(pattern) + + version_not_found! unless potential_version_match?(potential_version) + env[Grape::Env::API_VERSION] = potential_version + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/namespace.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/namespace.rb new file mode 100644 index 00000000..bdaa3a53 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/namespace.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +module Grape + # A container for endpoints or other namespaces, which allows for both + # logical grouping of endpoints as well as sharing common configuration. + # May also be referred to as group, segment, or resource. + class Namespace + attr_reader :space, :options + + # @param space [String] the name of this namespace + # @param options [Hash] options hash + # @option options :requirements [Hash] param-regex pairs, all of which must + # be met by a request's params for all endpoints in this namespace, or + # validation will fail and return a 422. + def initialize(space, options) + @space = space.to_s + @options = options + end + + # Retrieves the requirements from the options hash, if given. + # @return [Hash] + def requirements + options[:requirements] || {} + end + + # (see ::joined_space_path) + def self.joined_space(settings) + settings&.map(&:space) + end + + # Join the namespaces from a list of settings to create a path prefix. + # @param settings [Array] list of Grape::Util::InheritableSettings. + def self.joined_space_path(settings) + JoinedSpaceCache[joined_space(settings)] + end + + class JoinedSpaceCache < Grape::Util::Cache + def initialize + super + @cache = Hash.new do |h, joined_space| + h[joined_space] = Grape::Router.normalize_path(joined_space.join('/')) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/parser.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/parser.rb new file mode 100644 index 00000000..9dcb81ef --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/parser.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Grape + module Parser + extend Grape::Util::Registry + + module_function + + def parser_for(format, parsers = nil) + return parsers[format] if parsers&.key?(format) + + registry[format] + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/parser/base.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/parser/base.rb new file mode 100644 index 00000000..56640d2e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/parser/base.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Grape + module Parser + class Base + def self.call(_object, _env) + raise NotImplementedError + end + + def self.inherited(klass) + super + Parser.register(klass) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/parser/json.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/parser/json.rb new file mode 100644 index 00000000..a808999c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/parser/json.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Grape + module Parser + class Json < Base + def self.call(object, _env) + ::Grape::Json.load(object) + rescue ::Grape::Json::ParseError + # handle JSON parsing errors via the rescue handlers or provide error message + raise Grape::Exceptions::InvalidMessageBody.new('application/json') + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/parser/jsonapi.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/parser/jsonapi.rb new file mode 100644 index 00000000..58e16571 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/parser/jsonapi.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module Grape + module Parser + class Jsonapi < Json; end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/parser/xml.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/parser/xml.rb new file mode 100644 index 00000000..bdb2a485 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/parser/xml.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Grape + module Parser + class Xml < Base + def self.call(object, _env) + ::Grape::Xml.parse(object) + rescue ::Grape::Xml::ParseError + # handle XML parsing errors via the rescue handlers or provide error message + raise Grape::Exceptions::InvalidMessageBody.new('application/xml') + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/path.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/path.rb new file mode 100644 index 00000000..b4e2570d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/path.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true + +module Grape + # Represents a path to an endpoint. + class Path + DEFAULT_FORMAT_SEGMENT = '(/.:format)' + NO_VERSIONING_WITH_VALID_PATH_FORMAT_SEGMENT = '(.:format)' + VERSION_SEGMENT = ':version' + + attr_reader :origin, :suffix + + def initialize(raw_path, raw_namespace, settings) + @origin = PartsCache[build_parts(raw_path, raw_namespace, settings)] + @suffix = build_suffix(raw_path, raw_namespace, settings) + end + + def to_s + "#{origin}#{suffix}" + end + + private + + def build_suffix(raw_path, raw_namespace, settings) + if uses_specific_format?(settings) + "(.#{settings[:format]})" + elsif !uses_path_versioning?(settings) || (valid_part?(raw_namespace) || valid_part?(raw_path)) + NO_VERSIONING_WITH_VALID_PATH_FORMAT_SEGMENT + else + DEFAULT_FORMAT_SEGMENT + end + end + + def build_parts(raw_path, raw_namespace, settings) + [].tap do |parts| + add_part(parts, settings[:mount_path]) + add_part(parts, settings[:root_prefix]) + parts << VERSION_SEGMENT if uses_path_versioning?(settings) + add_part(parts, raw_namespace) + add_part(parts, raw_path) + end + end + + def add_part(parts, value) + parts << value if value && not_slash?(value) + end + + def not_slash?(value) + value != '/' + end + + def uses_specific_format?(settings) + return false unless settings.key?(:format) && settings.key?(:content_types) + + settings[:format] && Array(settings[:content_types]).size == 1 + end + + def uses_path_versioning?(settings) + return false unless settings.key?(:version) && settings[:version_options]&.key?(:using) + + settings[:version] && settings[:version_options][:using] == :path + end + + def valid_part?(part) + part&.match?(/^\S/) && not_slash?(part) + end + + class PartsCache < Grape::Util::Cache + def initialize + super + @cache = Hash.new do |h, parts| + h[parts] = Grape::Router.normalize_path(parts.join('/')) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/presenters/presenter.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/presenters/presenter.rb new file mode 100644 index 00000000..78c81217 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/presenters/presenter.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Grape + module Presenters + class Presenter + def self.represent(object, **_options) + object + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/railtie.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/railtie.rb new file mode 100644 index 00000000..42eb3442 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/railtie.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module Grape + class Railtie < ::Rails::Railtie + initializer 'grape.deprecator' do |app| + app.deprecators[:grape] = Grape.deprecator + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/request.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/request.rb new file mode 100644 index 00000000..b2a62053 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/request.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module Grape + class Request < Rack::Request + HTTP_PREFIX = 'HTTP_' + + alias rack_params params + + def initialize(env, build_params_with: nil) + extend build_params_with || Grape.config.param_builder + super(env) + end + + def params + @params ||= build_params + rescue EOFError + raise Grape::Exceptions::EmptyMessageBody.new(content_type) + rescue Rack::Multipart::MultipartPartLimitError + raise Grape::Exceptions::TooManyMultipartFiles.new(Rack::Utils.multipart_part_limit) + end + + def headers + @headers ||= build_headers + end + + private + + def grape_routing_args + args = env[Grape::Env::GRAPE_ROUTING_ARGS].dup + # preserve version from query string parameters + args.delete(:version) + args.delete(:route_info) + args + end + + def build_headers + Grape::Util::Lazy::Object.new do + env.each_pair.with_object(Grape::Util::Header.new) do |(k, v), headers| + next unless k.to_s.start_with? HTTP_PREFIX + + transformed_header = Grape::Http::Headers::HTTP_HEADERS[k] || transform_header(k) + headers[transformed_header] = v + end + end + end + + def transform_header(header) + -header[5..].tr('_', '-').downcase + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/router.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/router.rb new file mode 100644 index 00000000..6889b421 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/router.rb @@ -0,0 +1,172 @@ +# frozen_string_literal: true + +module Grape + class Router + attr_reader :map, :compiled + + def self.normalize_path(path) + path = +"/#{path}" + path.squeeze!('/') + path.sub!(%r{/+\Z}, '') + path = '/' if path == '' + path + end + + def initialize + @neutral_map = [] + @neutral_regexes = [] + @map = Hash.new { |hash, key| hash[key] = [] } + @optimized_map = Hash.new { |hash, key| hash[key] = // } + end + + def compile! + return if compiled + + @union = Regexp.union(@neutral_regexes) + @neutral_regexes = nil + (Grape::Http::Headers::SUPPORTED_METHODS + ['*']).each do |method| + next unless map.key?(method) + + routes = map[method] + optimized_map = routes.map.with_index { |route, index| route.to_regexp(index) } + @optimized_map[method] = Regexp.union(optimized_map) + end + @compiled = true + end + + def append(route) + map[route.request_method] << route + end + + def associate_routes(pattern, options) + Grape::Router::GreedyRoute.new(pattern, options).then do |greedy_route| + @neutral_regexes << greedy_route.to_regexp(@neutral_map.length) + @neutral_map << greedy_route + end + end + + def call(env) + with_optimization do + response, route = identity(env) + response || rotation(env, route) + end + end + + def recognize_path(input) + any = with_optimization { greedy_match?(input) } + return if any == default_response + + any.endpoint + end + + private + + def identity(env) + route = nil + response = transaction(env) do |input, method| + route = match?(input, method) + process_route(route, env) if route + end + [response, route] + end + + def rotation(env, exact_route = nil) + response = nil + input, method = *extract_input_and_method(env) + map[method].each do |route| + next if exact_route == route + next unless route.match?(input) + + response = process_route(route, env) + break unless cascade?(response) + end + response + end + + def transaction(env) + input, method = *extract_input_and_method(env) + + # using a Proc is important since `return` will exit the enclosing function + cascade_or_return_response = proc do |response| + if response + cascade?(response).tap do |cascade| + return response unless cascade + + # we need to close the body if possible before dismissing + response[2].close if response[2].respond_to?(:close) + end + end + end + + last_response_cascade = cascade_or_return_response.call(yield(input, method)) + last_neighbor_route = greedy_match?(input) + + # If last_neighbor_route exists and request method is OPTIONS, + # return response by using #call_with_allow_headers. + return call_with_allow_headers(env, last_neighbor_route) if last_neighbor_route && method == Rack::OPTIONS && !last_response_cascade + + route = match?(input, '*') + + return last_neighbor_route.options[:endpoint].call(env) if last_neighbor_route && last_response_cascade && route + + last_response_cascade = cascade_or_return_response.call(process_route(route, env)) if route + + return call_with_allow_headers(env, last_neighbor_route) if !last_response_cascade && last_neighbor_route + + nil + end + + def process_route(route, env) + prepare_env_from_route(env, route) + route.exec(env) + end + + def make_routing_args(default_args, route, input) + args = default_args || { route_info: route } + args.merge(route.params(input)) + end + + def extract_input_and_method(env) + input = string_for(env[Rack::PATH_INFO]) + method = env[Rack::REQUEST_METHOD] + [input, method] + end + + def with_optimization + compile! unless compiled + yield || default_response + end + + def default_response + headers = Grape::Util::Header.new.merge(Grape::Http::Headers::X_CASCADE => 'pass') + [404, headers, ['404 Not Found']] + end + + def match?(input, method) + @optimized_map[method].match(input) { |m| @map[method].detect { |route| m[route.regexp_capture_index] } } + end + + def greedy_match?(input) + @union.match(input) { |m| @neutral_map.detect { |route| m[route.regexp_capture_index] } } + end + + def call_with_allow_headers(env, route) + prepare_env_from_route(env, route) + env[Grape::Env::GRAPE_ALLOWED_METHODS] = route.options[:allow_header] + route.options[:endpoint].call(env) + end + + def prepare_env_from_route(env, route) + input, = *extract_input_and_method(env) + env[Grape::Env::GRAPE_ROUTING_ARGS] = make_routing_args(env[Grape::Env::GRAPE_ROUTING_ARGS], route, input) + end + + def cascade?(response) + response && response[1][Grape::Http::Headers::X_CASCADE] == 'pass' + end + + def string_for(input) + self.class.normalize_path(input) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/router/base_route.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/router/base_route.rb new file mode 100644 index 00000000..86439e90 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/router/base_route.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +module Grape + class Router + class BaseRoute + delegate_missing_to :@options + + attr_reader :index, :pattern, :options + + def initialize(options) + @options = options.is_a?(ActiveSupport::OrderedOptions) ? options : ActiveSupport::OrderedOptions.new.update(options) + end + + alias attributes options + + def regexp_capture_index + CaptureIndexCache[index] + end + + def pattern_regexp + pattern.to_regexp + end + + def to_regexp(index) + @index = index + Regexp.new("(?<#{regexp_capture_index}>#{pattern_regexp})") + end + + class CaptureIndexCache < Grape::Util::Cache + def initialize + super + @cache = Hash.new do |h, index| + h[index] = "_#{index}" + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/router/greedy_route.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/router/greedy_route.rb new file mode 100644 index 00000000..c2fbcf8e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/router/greedy_route.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +# Act like a Grape::Router::Route but for greedy_match +# see @neutral_map + +module Grape + class Router + class GreedyRoute < BaseRoute + def initialize(pattern, options) + @pattern = pattern + super(options) + end + + # Grape::Router:Route defines params as a function + def params(_input = nil) + options[:params] || {} + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/router/pattern.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/router/pattern.rb new file mode 100644 index 00000000..4529a927 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/router/pattern.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +module Grape + class Router + class Pattern + extend Forwardable + + DEFAULT_CAPTURES = %w[format version].freeze + + attr_reader :origin, :path, :pattern, :to_regexp + + def_delegators :pattern, :params + def_delegators :to_regexp, :=== + alias match? === + + def initialize(origin, suffix, options) + @origin = origin + @path = build_path(origin, options[:anchor], suffix) + @pattern = build_pattern(@path, options[:params], options[:format], options[:version], options[:requirements]) + @to_regexp = @pattern.to_regexp + end + + def captures_default + to_regexp.names + .delete_if { |n| DEFAULT_CAPTURES.include?(n) } + .to_h { |k| [k, ''] } + end + + private + + def build_pattern(path, params, format, version, requirements) + Mustermann::Grape.new( + path, + uri_decode: true, + params: params, + capture: extract_capture(format, version, requirements) + ) + end + + def build_path(pattern, anchor, suffix) + PatternCache[[build_path_from_pattern(pattern, anchor), suffix]] + end + + def extract_capture(format, version, requirements) + capture = {}.tap do |h| + h[:format] = map_str(format) if format.present? + h[:version] = map_str(version) if version.present? + end + + return capture if requirements.blank? + + requirements.merge(capture) + end + + def build_path_from_pattern(pattern, anchor) + if pattern.end_with?('*path') + pattern.dup.insert(pattern.rindex('/') + 1, '?') + elsif anchor + pattern + elsif pattern.end_with?('/') + "#{pattern}?*path" + else + "#{pattern}/?*path" + end + end + + def map_str(value) + Array.wrap(value).map(&:to_s) + end + + class PatternCache < Grape::Util::Cache + def initialize + super + @cache = Hash.new do |h, (pattern, suffix)| + h[[pattern, suffix]] = -"#{pattern}#{suffix}" + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/router/route.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/router/route.rb new file mode 100644 index 00000000..48599610 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/router/route.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +module Grape + class Router + class Route < BaseRoute + extend Forwardable + + FORWARD_MATCH_METHOD = ->(input, pattern) { input.start_with?(pattern.origin) } + NON_FORWARD_MATCH_METHOD = ->(input, pattern) { pattern.match?(input) } + + attr_reader :app, :request_method + + def_delegators :pattern, :path, :origin + + def initialize(method, origin, path, options) + @request_method = upcase_method(method) + @pattern = Grape::Router::Pattern.new(origin, path, options) + @match_function = options[:forward_match] ? FORWARD_MATCH_METHOD : NON_FORWARD_MATCH_METHOD + super(options) + end + + def convert_to_head_request! + @request_method = Rack::HEAD + end + + def exec(env) + @app.call(env) + end + + def apply(app) + @app = app + self + end + + def match?(input) + return false if input.blank? + + @match_function.call(input, pattern) + end + + def params(input = nil) + return params_without_input if input.blank? + + parsed = pattern.params(input) + return {} unless parsed + + parsed.compact.symbolize_keys + end + + private + + def params_without_input + @params_without_input ||= pattern.captures_default.merge(attributes.params) + end + + def upcase_method(method) + method_s = method.to_s + Grape::Http::Headers::SUPPORTED_METHODS.detect { |m| m.casecmp(method_s).zero? } || method_s.upcase + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/serve_stream/file_body.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/serve_stream/file_body.rb new file mode 100644 index 00000000..b842af66 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/serve_stream/file_body.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module Grape + module ServeStream + CHUNK_SIZE = 16_384 + + # Class helps send file through API + class FileBody + attr_reader :path + + # @param path [String] + def initialize(path) + @path = path + end + + # Need for Rack::Sendfile middleware + # + # @return [String] + def to_path + path + end + + def each + File.open(path, 'rb') do |file| + while (chunk = file.read(CHUNK_SIZE)) + yield chunk + end + end + end + + def ==(other) + path == other.path + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/serve_stream/sendfile_response.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/serve_stream/sendfile_response.rb new file mode 100644 index 00000000..b46fc102 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/serve_stream/sendfile_response.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Grape + module ServeStream + # Response should respond to to_path method + # for using Rack::SendFile middleware + class SendfileResponse < Rack::Response + def respond_to?(method_name, include_all = false) + if method_name == :to_path + @body.respond_to?(:to_path, include_all) + else + super + end + end + + def to_path + @body.to_path + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/serve_stream/stream_response.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/serve_stream/stream_response.rb new file mode 100644 index 00000000..0705fbf7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/serve_stream/stream_response.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Grape + module ServeStream + # A simple class used to identify responses which represent streams (or files) and do not + # need to be formatted or pre-read by Rack::Response + class StreamResponse + attr_reader :stream + + # @param stream [Object] + def initialize(stream) + @stream = stream + end + + # Equality provided mostly for tests. + # + # @return [Boolean] + def ==(other) + stream == other.stream + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/types/invalid_value.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/types/invalid_value.rb new file mode 100644 index 00000000..ae356daa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/types/invalid_value.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +# only exists to make it shorter for external use +module Grape + module Types + InvalidValue = Class.new(Grape::Validations::Types::InvalidValue) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/base_inheritable.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/base_inheritable.rb new file mode 100644 index 00000000..cc68abab --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/base_inheritable.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +module Grape + module Util + # Base for classes which need to operate with own values kept + # in the hash and inherited values kept in a Hash-like object. + class BaseInheritable + attr_accessor :inherited_values, :new_values + + # @param inherited_values [Object] An object implementing an interface + # of the Hash class. + def initialize(inherited_values = nil) + @inherited_values = inherited_values || {} + @new_values = {} + end + + def delete(key) + new_values.delete key + end + + def initialize_copy(other) + super + self.inherited_values = other.inherited_values + self.new_values = other.new_values.dup + end + + def keys + if new_values.any? + inherited_values.keys.tap do |combined| + combined.concat(new_values.keys) + combined.uniq! + end + else + inherited_values.keys + end + end + + def key?(name) + inherited_values.key?(name) || new_values.key?(name) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/cache.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/cache.rb new file mode 100644 index 00000000..7514296c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/cache.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Grape + module Util + class Cache + include Singleton + + attr_reader :cache + + class << self + extend Forwardable + def_delegators :cache, :[] + def_delegators :instance, :cache + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/endpoint_configuration.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/endpoint_configuration.rb new file mode 100644 index 00000000..49855625 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/endpoint_configuration.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +module Grape + module Util + class EndpointConfiguration < Lazy::ValueHash + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/header.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/header.rb new file mode 100644 index 00000000..63248079 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/header.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Grape + module Util + if Gem::Version.new(Rack.release) >= Gem::Version.new('3') + require 'rack/headers' + Header = Rack::Headers + else + require 'rack/utils' + Header = Rack::Utils::HeaderHash + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/inheritable_setting.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/inheritable_setting.rb new file mode 100644 index 00000000..b3504fe9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/inheritable_setting.rb @@ -0,0 +1,100 @@ +# frozen_string_literal: true + +module Grape + module Util + # A branchable, inheritable settings object which can store both stackable + # and inheritable values (see InheritableValues and StackableValues). + class InheritableSetting + attr_accessor :route, :api_class, :namespace, :namespace_inheritable, :namespace_stackable, :namespace_reverse_stackable, :parent, :point_in_time_copies + + # Retrieve global settings. + def self.global + @global ||= {} + end + + # Clear all global settings. + # @api private + # @note only for testing + def self.reset_global! + @global = {} + end + + # Instantiate a new settings instance, with blank values. The fresh + # instance can then be set to inherit from an existing instance (see + # #inherit_from). + def initialize + self.route = {} + self.api_class = {} + self.namespace = InheritableValues.new # only inheritable from a parent when + # used with a mount, or should every API::Class be a separate namespace by default? + self.namespace_inheritable = InheritableValues.new + self.namespace_stackable = StackableValues.new + self.namespace_reverse_stackable = ReverseStackableValues.new + + self.point_in_time_copies = [] + + self.parent = nil + end + + # Return the class-level global properties. + def global + self.class.global + end + + # Set our inherited values to the given parent's current values. Also, + # update the inherited values on any settings instances which were forked + # from us. + # @param parent [InheritableSetting] + def inherit_from(parent) + return if parent.nil? + + self.parent = parent + + namespace_inheritable.inherited_values = parent.namespace_inheritable + namespace_stackable.inherited_values = parent.namespace_stackable + namespace_reverse_stackable.inherited_values = parent.namespace_reverse_stackable + self.route = parent.route.merge(route) + + point_in_time_copies.map { |cloned_one| cloned_one.inherit_from parent } + end + + # Create a point-in-time copy of this settings instance, with clones of + # all our values. Note that, should this instance's parent be set or + # changed via #inherit_from, it will copy that inheritence to any copies + # which were made. + def point_in_time_copy + self.class.new.tap do |new_setting| + point_in_time_copies << new_setting + new_setting.point_in_time_copies = [] + + new_setting.namespace = namespace.clone + new_setting.namespace_inheritable = namespace_inheritable.clone + new_setting.namespace_stackable = namespace_stackable.clone + new_setting.namespace_reverse_stackable = namespace_reverse_stackable.clone + new_setting.route = route.clone + new_setting.api_class = api_class + + new_setting.inherit_from(parent) + end + end + + # Resets the instance store of per-route settings. + # @api private + def route_end + @route = {} + end + + # Return a serializable hash of our values. + def to_hash + { + global: global.clone, + route: route.clone, + namespace: namespace.to_hash, + namespace_inheritable: namespace_inheritable.to_hash, + namespace_stackable: namespace_stackable.to_hash, + namespace_reverse_stackable: namespace_reverse_stackable.to_hash + } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/inheritable_values.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/inheritable_values.rb new file mode 100644 index 00000000..48cebb23 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/inheritable_values.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module Grape + module Util + class InheritableValues < BaseInheritable + def [](name) + values[name] + end + + def []=(name, value) + new_values[name] = value + end + + def merge(new_hash) + values.merge!(new_hash) + end + + def to_hash + values + end + + protected + + def values + @inherited_values.merge(@new_values) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/lazy/block.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/lazy/block.rb new file mode 100644 index 00000000..a47d44b0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/lazy/block.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module Grape + module Util + module Lazy + class Block + def initialize(&new_block) + @block = new_block + end + + def evaluate_from(configuration) + @block.call(configuration) + end + + def evaluate + @block.call({}) + end + + def lazy? + true + end + + def to_s + evaluate.to_s + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/lazy/object.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/lazy/object.rb new file mode 100644 index 00000000..6c10dadf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/lazy/object.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +# Based on https://github.com/HornsAndHooves/lazy_object + +module Grape + module Util + module Lazy + class Object < BasicObject + attr_reader :callable + + def initialize(&callable) + @callable = callable + end + + def __target_object__ + @__target_object__ ||= callable.call + end + + def ==(other) + __target_object__ == other + end + + def !=(other) + __target_object__ != other + end + + def ! + !__target_object__ + end + + def method_missing(method_name, *args, &block) + if __target_object__.respond_to?(method_name) + __target_object__.send(method_name, *args, &block) + else + super + end + end + + def respond_to_missing?(method_name, include_priv = false) + __target_object__.respond_to?(method_name, include_priv) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/lazy/value.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/lazy/value.rb new file mode 100644 index 00000000..59b79994 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/lazy/value.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +module Grape + module Util + module Lazy + class Value + attr_reader :access_keys + + def initialize(value, access_keys = []) + @value = value + @access_keys = access_keys + end + + def evaluate_from(configuration) + matching_lazy_value = configuration.fetch(@access_keys) + matching_lazy_value.evaluate + end + + def evaluate + @value + end + + def lazy? + true + end + + def reached_by(parent_access_keys, access_key) + @access_keys = parent_access_keys + [access_key] + self + end + + def to_s + evaluate.to_s + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/lazy/value_array.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/lazy/value_array.rb new file mode 100644 index 00000000..b4c6a88a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/lazy/value_array.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Grape + module Util + module Lazy + class ValueArray < ValueEnumerable + def initialize(array) + super + @value_hash = [] + array.each_with_index do |value, index| + self[index] = value + end + end + + def evaluate + @value_hash.map(&:evaluate) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/lazy/value_enumerable.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/lazy/value_enumerable.rb new file mode 100644 index 00000000..ce15693a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/lazy/value_enumerable.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module Grape + module Util + module Lazy + class ValueEnumerable < Value + def [](key) + if @value_hash[key].nil? + Value.new(nil).reached_by(access_keys, key) + else + @value_hash[key].reached_by(access_keys, key) + end + end + + def fetch(access_keys) + fetched_keys = access_keys.dup + value = self[fetched_keys.shift] + fetched_keys.any? ? value.fetch(fetched_keys) : value + end + + def []=(key, value) + @value_hash[key] = case value + when Hash + ValueHash.new(value) + when Array + ValueArray.new(value) + else + Value.new(value) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/lazy/value_hash.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/lazy/value_hash.rb new file mode 100644 index 00000000..c3447a0d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/lazy/value_hash.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Grape + module Util + module Lazy + class ValueHash < ValueEnumerable + def initialize(hash) + super + @value_hash = ActiveSupport::HashWithIndifferentAccess.new + hash.each do |key, value| + self[key] = value + end + end + + def evaluate + @value_hash.transform_values(&:evaluate) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/media_type.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/media_type.rb new file mode 100644 index 00000000..1812fafa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/media_type.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +module Grape + module Util + class MediaType + attr_reader :type, :subtype, :vendor, :version, :format + + # based on the HTTP Accept header with the pattern: + # application/vnd.:vendor-:version+:format + VENDOR_VERSION_HEADER_REGEX = /\Avnd\.(?[a-z0-9.\-_!^]+?)(?:-(?[a-z0-9*.]+))?(?:\+(?[a-z0-9*\-.]+))?\z/.freeze + + def initialize(type:, subtype:) + @type = type + @subtype = subtype + VENDOR_VERSION_HEADER_REGEX.match(subtype) do |m| + @vendor = m[:vendor] + @version = m[:version] + @format = m[:format] + end + end + + def ==(other) + eql?(other) + end + + def eql?(other) + self.class == other.class && + other.type == type && + other.subtype == subtype && + other.vendor == vendor && + other.version == version && + other.format == format + end + + def hash + [self.class, type, subtype, vendor, version, format].hash + end + + class << self + def best_quality(header, available_media_types) + parse(best_quality_media_type(header, available_media_types)) + end + + def parse(media_type) + return if media_type.blank? + + type, subtype = media_type.split('/', 2) + return if type.blank? || subtype.blank? + + new(type: type, subtype: subtype) + end + + def match?(media_type) + return false if media_type.blank? + + subtype = media_type.split('/', 2).last + return false if subtype.blank? + + VENDOR_VERSION_HEADER_REGEX.match?(subtype) + end + + def best_quality_media_type(header, available_media_types) + header.blank? ? available_media_types.first : Rack::Utils.best_q_match(header, available_media_types) + end + end + + private_class_method :best_quality_media_type + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/registry.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/registry.rb new file mode 100644 index 00000000..6980445e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/registry.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Grape + module Util + module Registry + def register(klass) + short_name = build_short_name(klass) + return if short_name.nil? + + warn "#{short_name} is already registered with class #{klass}" if registry.key?(short_name) + registry[short_name] = klass + end + + private + + def build_short_name(klass) + return if klass.name.blank? + + klass.name.demodulize.underscore + end + + def registry + @registry ||= {}.with_indifferent_access + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/reverse_stackable_values.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/reverse_stackable_values.rb new file mode 100644 index 00000000..43da1ead --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/reverse_stackable_values.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Grape + module Util + class ReverseStackableValues < StackableValues + protected + + def concat_values(inherited_value, new_value) + return inherited_value unless new_value + + new_value + inherited_value + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/stackable_values.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/stackable_values.rb new file mode 100644 index 00000000..64336182 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/stackable_values.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module Grape + module Util + class StackableValues < BaseInheritable + # Even if there is no value, an empty array will be returned. + def [](name) + inherited_value = inherited_values[name] + new_value = new_values[name] + + return new_value || [] unless inherited_value + + concat_values(inherited_value, new_value) + end + + def []=(name, value) + new_values[name] ||= [] + new_values[name].push value + end + + def to_hash + keys.each_with_object({}) do |key, result| + result[key] = self[key] + end + end + + protected + + def concat_values(inherited_value, new_value) + return inherited_value unless new_value + + inherited_value + new_value + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/strict_hash_configuration.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/strict_hash_configuration.rb new file mode 100644 index 00000000..4ac10585 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/util/strict_hash_configuration.rb @@ -0,0 +1,108 @@ +# frozen_string_literal: true + +module Grape + module Util + module StrictHashConfiguration + extend ActiveSupport::Concern + + module DSL + extend ActiveSupport::Concern + + module ClassMethods + def settings + config_context.to_hash + end + + def configure(&block) + config_context.instance_exec(&block) + end + end + end + + class SettingsContainer + def initialize + @settings = {} + @contexts = {} + end + + def to_hash + @settings.to_hash + end + end + + def self.config_class(*args) + new_config_class = Class.new(SettingsContainer) + + args.each do |setting_name| + if setting_name.respond_to? :values + nested_settings_methods(setting_name, new_config_class) + else + simple_settings_methods(setting_name, new_config_class) + end + end + + new_config_class + end + + def self.simple_settings_methods(setting_name, new_config_class) + setting_name_sym = setting_name.to_sym + new_config_class.class_eval do + define_method setting_name do |new_value| + @settings[setting_name_sym] = new_value + end + end + end + + def self.nested_settings_methods(setting_name, new_config_class) + new_config_class.class_eval do + setting_name.each_pair do |key, value| + define_method :"#{key}_context" do + @contexts[key] ||= Grape::Util::StrictHashConfiguration.config_class(*value).new + end + + define_method key do |&block| + send(:"#{key}_context").instance_exec(&block) + end + end + + define_method :to_hash do + @settings.to_hash.merge( + setting_name.each_key.with_object({}) do |k, merge_hash| + merge_hash[k] = send(:"#{k}_context").to_hash + end + ) + end + end + end + + def self.module(*args) + new_module = Module.new do + extend ActiveSupport::Concern + include DSL + end + + new_module.tap do |mod| + class_mod = create_class_mod(args) + + mod.const_set(:ClassMethods, class_mod) + end + end + + def self.create_class_mod(args) + new_module = Module.new do + def config_context + @config_context ||= config_class.new + end + end + + new_module.tap do |class_mod| + new_config_class = config_class(*args) + + class_mod.send(:define_method, :config_class) do + @config_class ||= new_config_class + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations.rb new file mode 100644 index 00000000..fd33071d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Grape + module Validations + extend Grape::Util::Registry + + module_function + + def require_validator(short_name) + raise Grape::Exceptions::UnknownValidator, short_name unless registry.key?(short_name) + + registry[short_name] + end + + def build_short_name(klass) + return if klass.name.blank? + + klass.name.demodulize.underscore.delete_suffix('_validator') + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/attributes_doc.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/attributes_doc.rb new file mode 100644 index 00000000..c0d5ed95 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/attributes_doc.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +module Grape + module Validations + # Documents parameters of an endpoint. If documentation isn't needed (for instance, it is an + # internal API), the class only cleans up attributes to avoid junk in RAM. + + class AttributesDoc + attr_accessor :type, :values + + # @param api [Grape::API::Instance] + # @param scope [Validations::ParamsScope] + def initialize(api, scope) + @api = api + @scope = scope + @type = type + end + + def extract_details(validations) + details[:required] = validations.key?(:presence) + + desc = validations.delete(:desc) || validations.delete(:description) + + details[:desc] = desc if desc + + documentation = validations.delete(:documentation) + + details[:documentation] = documentation if documentation + + details[:default] = validations[:default] if validations.key?(:default) + + details[:min_length] = validations[:length][:min] if validations.key?(:length) && validations[:length].key?(:min) + details[:max_length] = validations[:length][:max] if validations.key?(:length) && validations[:length].key?(:max) + end + + def document(attrs) + return if @api.namespace_inheritable(:do_not_document) + + details[:type] = type.to_s if type + details[:values] = values if values + + documented_attrs = attrs.each_with_object({}) do |name, memo| + memo[@scope.full_name(name)] = details + end + + @api.namespace_stackable(:params, documented_attrs) + end + + def required + details[:required] + end + + protected + + def details + @details ||= {} + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/attributes_iterator.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/attributes_iterator.rb new file mode 100644 index 00000000..97d7f028 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/attributes_iterator.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +module Grape + module Validations + class AttributesIterator + include Enumerable + + attr_reader :scope + + def initialize(validator, scope, params) + @scope = scope + @attrs = validator.attrs + @original_params = scope.params(params) + @params = Array.wrap(@original_params) + end + + def each(&block) + do_each(@params, &block) # because we need recursion for nested arrays + end + + private + + def do_each(params_to_process, parent_indicies = [], &block) + @scope.reset_index # gets updated depending on the size of params_to_process + params_to_process.each_with_index do |resource_params, index| + # when we get arrays of arrays it means that target element located inside array + # we need this because we want to know parent arrays indicies + if resource_params.is_a?(Array) + do_each(resource_params, [index] + parent_indicies, &block) + next + end + + if @scope.type == Array + next unless @original_params.is_a?(Array) # do not validate content of array if it isn't array + + # fill current and parent scopes with correct array indicies + parent_scope = @scope.parent + parent_indicies.each do |parent_index| + parent_scope.index = parent_index + parent_scope = parent_scope.parent + end + @scope.index = index + end + + yield_attributes(resource_params, @attrs, &block) + end + end + + def yield_attributes(_resource_params, _attrs) + raise NotImplementedError + end + + # This is a special case so that we can ignore tree's where option + # values are missing lower down. Unfortunately we can remove this + # are the parameter parsing stage as they are required to ensure + # the correct indexing is maintained + def skip?(val) + val == Grape::DSL::Parameters::EmptyOptionalValue + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/contract_scope.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/contract_scope.rb new file mode 100644 index 00000000..218f47ee --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/contract_scope.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module Grape + module Validations + class ContractScope + # Declare the contract to be used for the endpoint's parameters. + # @param api [API] the API endpoint to modify. + # @param contract the contract or schema to be used for validation. Optional. + # @yield a block yielding a new schema class. Optional. + def initialize(api, contract = nil, &block) + # When block is passed, the first arg is either schema or nil. + contract = Dry::Schema.Params(parent: contract, &block) if block + + if contract.respond_to?(:schema) + # It's a Dry::Validation::Contract, then. + contract = contract.new + key_map = contract.schema.key_map + else + # Dry::Schema::Processor, hopefully. + key_map = contract.key_map + end + + api.namespace_stackable(:contract_key_map, key_map) + + validator_options = { + validator_class: Grape::Validations.require_validator(:contract_scope), + opts: { schema: contract, fail_fast: false } + } + + api.namespace_stackable(:validations, validator_options) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/multiple_attributes_iterator.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/multiple_attributes_iterator.rb new file mode 100644 index 00000000..e5621bca --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/multiple_attributes_iterator.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Grape + module Validations + class MultipleAttributesIterator < AttributesIterator + private + + def yield_attributes(resource_params, _attrs) + yield resource_params unless skip?(resource_params) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/params_scope.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/params_scope.rb new file mode 100644 index 00000000..cb9b3f43 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/params_scope.rb @@ -0,0 +1,533 @@ +# frozen_string_literal: true + +module Grape + module Validations + class ParamsScope + attr_accessor :element, :parent, :index + attr_reader :type + + include Grape::DSL::Parameters + + # There are a number of documentation options on entities that don't have + # corresponding validators. Since there is nowhere that enumerates them all, + # we maintain a list of them here and skip looking up validators for them. + RESERVED_DOCUMENTATION_KEYWORDS = %i[as required param_type is_array format example].freeze + + class Attr + attr_accessor :key, :scope + + # Open up a new ParamsScope::Attr + # @param key [Hash, Symbol] key of attr + # @param scope [Grape::Validations::ParamsScope] scope of attr + def initialize(key, scope) + @key = key + @scope = scope + end + + # @return Array[Symbol, Hash[Symbol => Array]] declared_params with symbol instead of Attr + def self.attrs_keys(declared_params) + declared_params.map do |declared_param_attr| + attr_key(declared_param_attr) + end + end + + def self.attr_key(declared_param_attr) + return attr_key(declared_param_attr.key) if declared_param_attr.is_a?(self) + + if declared_param_attr.is_a?(Hash) + declared_param_attr.transform_values { |value| attrs_keys(value) } + else + declared_param_attr + end + end + end + + # Open up a new ParamsScope, allowing parameter definitions per + # Grape::DSL::Params. + # @param opts [Hash] options for this scope + # @option opts :element [Symbol] the element that contains this scope; for + # this to be relevant, @parent must be set + # @option opts :element_renamed [Symbol, nil] whenever this scope should + # be renamed and to what, given +nil+ no renaming is done + # @option opts :parent [ParamsScope] the scope containing this scope + # @option opts :api [API] the API endpoint to modify + # @option opts :optional [Boolean] whether or not this scope needs to have + # any parameters set or not + # @option opts :type [Class] a type meant to govern this scope (deprecated) + # @option opts :type [Hash] group options for this scope + # @option opts :dependent_on [Symbol] if present, this scope should only + # validate if this param is present in the parent scope + # @yield the instance context, open for parameter definitions + def initialize(opts, &block) + @element = opts[:element] + @element_renamed = opts[:element_renamed] + @parent = opts[:parent] + @api = opts[:api] + @optional = opts[:optional] || false + @type = opts[:type] + @group = opts[:group] + @dependent_on = opts[:dependent_on] + @declared_params = [] + @index = nil + + instance_eval(&block) if block + + configure_declared_params + end + + def configuration + @api.configuration.respond_to?(:evaluate) ? @api.configuration.evaluate : @api.configuration + end + + # @return [Boolean] whether or not this entire scope needs to be + # validated + def should_validate?(parameters) + scoped_params = params(parameters) + + return false if @optional && (scoped_params.blank? || all_element_blank?(scoped_params)) + return false unless meets_dependency?(scoped_params, parameters) + return true if parent.nil? + + parent.should_validate?(parameters) + end + + def meets_dependency?(params, request_params) + return true unless @dependent_on + return false if @parent.present? && !@parent.meets_dependency?(@parent.params(request_params), request_params) + return params.any? { |param| meets_dependency?(param, request_params) } if params.is_a?(Array) + + meets_hash_dependency?(params) + end + + def attr_meets_dependency?(params) + return true unless @dependent_on + return false if @parent.present? && !@parent.attr_meets_dependency?(params) + + meets_hash_dependency?(params) + end + + def meets_hash_dependency?(params) + # params might be anything what looks like a hash, so it must implement a `key?` method + return false unless params.respond_to?(:key?) + + @dependent_on.each do |dependency| + if dependency.is_a?(Hash) + dependency_key = dependency.keys[0] + proc = dependency.values[0] + return false unless proc.call(params.try(:[], dependency_key)) + elsif params.respond_to?(:key?) && params.try(:[], dependency).blank? + return false + end + end + + true + end + + # @return [String] the proper attribute name, with nesting considered. + def full_name(name, index: nil) + if nested? + # Find our containing element's name, and append ours. + "#{@parent.full_name(@element)}#{brackets(@index || index)}#{brackets(name)}" + elsif lateral? + # Find the name of the element as if it was at the same nesting level + # as our parent. We need to forward our index upward to achieve this. + @parent.full_name(name, index: @index) + else + # We must be the root scope, so no prefix needed. + name.to_s + end + end + + def brackets(val) + "[#{val}]" if val + end + + # @return [Boolean] whether or not this scope is the root-level scope + def root? + !@parent + end + + # A nested scope is contained in one of its parent's elements. + # @return [Boolean] whether or not this scope is nested + def nested? + @parent && @element + end + + # A lateral scope is subordinate to its parent, but its keys are at the + # same level as its parent and thus is not contained within an element. + # @return [Boolean] whether or not this scope is lateral + def lateral? + @parent && !@element + end + + # @return [Boolean] whether or not this scope needs to be present, or can + # be blank + def required? + !@optional + end + + def reset_index + @index = nil + end + + protected + + # Adds a parameter declaration to our list of validations. + # @param attrs [Array] (see Grape::DSL::Parameters#requires) + def push_declared_params(attrs, opts = {}) + opts[:declared_params_scope] = self unless opts.key?(:declared_params_scope) + return @parent.push_declared_params(attrs, opts) if lateral? + + push_renamed_param(full_path + [attrs.first], opts[:as]) if opts[:as] + @declared_params.concat(attrs.map { |attr| ::Grape::Validations::ParamsScope::Attr.new(attr, opts[:declared_params_scope]) }) + end + + # Get the full path of the parameter scope in the hierarchy. + # + # @return [Array] the nesting/path of the current parameter scope + def full_path + if nested? + (@parent.full_path + [@element]) + elsif lateral? + @parent.full_path + else + [] + end + end + + private + + # Add a new parameter which should be renamed when using the +#declared+ + # method. + # + # @param path [Array] the full path of the parameter + # (including the parameter name as last array element) + # @param new_name [String, Symbol] the new name of the parameter (the + # renamed name, with the +as: ...+ semantic) + def push_renamed_param(path, new_name) + base = @api.route_setting(:renamed_params) || {} + base[Array(path).map(&:to_s)] = new_name.to_s + @api.route_setting(:renamed_params, base) + end + + def require_required_and_optional_fields(context, opts) + if context == :all + optional_fields = Array.wrap(opts[:except]) + required_fields = opts[:using].keys.delete_if { |f| optional_fields.include?(f) } + else # context == :none + required_fields = Array.wrap(opts[:except]) + optional_fields = opts[:using].keys.delete_if { |f| required_fields.include?(f) } + end + required_fields.each do |field| + field_opts = opts[:using][field] + raise ArgumentError, "required field not exist: #{field}" unless field_opts + + requires(field, field_opts) + end + optional_fields.each do |field| + field_opts = opts[:using][field] + optional(field, field_opts) if field_opts + end + end + + def require_optional_fields(context, opts) + optional_fields = opts[:using].keys + unless context == :all + except_fields = Array.wrap(opts[:except]) + optional_fields.delete_if { |f| except_fields.include?(f) } + end + optional_fields.each do |field| + field_opts = opts[:using][field] + optional(field, field_opts) if field_opts + end + end + + def validate_attributes(attrs, opts, &block) + validations = opts.clone + validations[:type] ||= Array if block + validates(attrs, validations) + end + + # Returns a new parameter scope, subordinate to the current one and nested + # under the parameter corresponding to `attrs.first`. + # @param attrs [Array] the attributes passed to the `requires` or + # `optional` invocation that opened this scope. + # @param optional [Boolean] whether the parameter this are nested under + # is optional or not (and hence, whether this block's params will be). + # @yield parameter scope + def new_scope(attrs, optional = false, &block) + # if required params are grouped and no type or unsupported type is provided, raise an error + type = attrs[1] ? attrs[1][:type] : nil + if attrs.first && !optional + raise Grape::Exceptions::MissingGroupType if type.nil? + raise Grape::Exceptions::UnsupportedGroupType unless Grape::Validations::Types.group?(type) + end + + self.class.new( + api: @api, + element: attrs.first, + element_renamed: attrs[1][:as], + parent: self, + optional: optional, + type: type || Array, + group: @group, + &block + ) + end + + # Returns a new parameter scope, not nested under any current-level param + # but instead at the same level as the current scope. + # @param options [Hash] options to control how this new scope behaves + # @option options :dependent_on [Symbol] if given, specifies that this + # scope should only validate if this parameter from the above scope is + # present + # @yield parameter scope + def new_lateral_scope(options, &block) + self.class.new( + api: @api, + element: nil, + parent: self, + options: @optional, + type: type == Array ? Array : Hash, + dependent_on: options[:dependent_on], + &block + ) + end + + # Returns a new parameter scope, subordinate to the current one and nested + # under the parameter corresponding to `attrs.first`. + # @param attrs [Array] the attributes passed to the `requires` or + # `optional` invocation that opened this scope. + # @yield parameter scope + def new_group_scope(attrs, &block) + self.class.new(api: @api, parent: self, group: attrs.first, &block) + end + + # Pushes declared params to parent or settings + def configure_declared_params + push_renamed_param(full_path, @element_renamed) if @element_renamed + + if nested? + @parent.push_declared_params [element => @declared_params] + else + @api.namespace_stackable(:declared_params, @declared_params) + end + + # params were stored in settings, it can be cleaned from the params scope + @declared_params = nil + end + + def validates(attrs, validations) + doc = AttributesDoc.new @api, self + doc.extract_details validations + + coerce_type = infer_coercion(validations) + + doc.type = coerce_type + + default = validations[:default] + + if (values_hash = validations[:values]).is_a? Hash + values = values_hash[:value] + # NB: excepts is deprecated + excepts = values_hash[:except] + else + values = validations[:values] + end + + doc.values = values + + except_values = options_key?(:except_values, :value, validations) ? validations[:except_values][:value] : validations[:except_values] + + # NB. values and excepts should be nil, Proc, Array, or Range. + # Specifically, values should NOT be a Hash + + # use values or excepts to guess coerce type when stated type is Array + coerce_type = guess_coerce_type(coerce_type, values, except_values, excepts) + + # default value should be present in values array, if both exist and are not procs + check_incompatible_option_values(default, values, except_values, excepts) + + # type should be compatible with values array, if both exist + validate_value_coercion(coerce_type, values, except_values, excepts) + + doc.document attrs + + opts = derive_validator_options(validations) + + # Validate for presence before any other validators + validates_presence(validations, attrs, doc, opts) + + # Before we run the rest of the validators, let's handle + # whatever coercion so that we are working with correctly + # type casted values + coerce_type validations, attrs, doc, opts + + validations.each do |type, options| + # Don't try to look up validators for documentation params that don't have one. + next if RESERVED_DOCUMENTATION_KEYWORDS.include?(type) + + validate(type, options, attrs, doc, opts) + end + end + + # Validate and comprehend the +:type+, +:types+, and +:coerce_with+ + # options that have been supplied to the parameter declaration. + # The +:type+ and +:types+ options will be removed from the + # validations list, replaced appropriately with +:coerce+ and + # +:coerce_with+ options that will later be passed to + # {Validators::CoerceValidator}. The type that is returned may be + # used for documentation and further validation of parameter + # options. + # + # @param validations [Hash] list of validations supplied to the + # parameter declaration + # @return [class-like] type to which the parameter will be coerced + # @raise [ArgumentError] if the given type options are invalid + def infer_coercion(validations) + raise ArgumentError, ':type may not be supplied with :types' if validations.key?(:type) && validations.key?(:types) + + validations[:coerce] = (options_key?(:type, :value, validations) ? validations[:type][:value] : validations[:type]) if validations.key?(:type) + validations[:coerce_message] = (options_key?(:type, :message, validations) ? validations[:type][:message] : nil) if validations.key?(:type) + validations[:coerce] = (options_key?(:types, :value, validations) ? validations[:types][:value] : validations[:types]) if validations.key?(:types) + validations[:coerce_message] = (options_key?(:types, :message, validations) ? validations[:types][:message] : nil) if validations.key?(:types) + + validations.delete(:types) if validations.key?(:types) + + coerce_type = validations[:coerce] + + # Special case - when the argument is a single type that is a + # variant-type collection. + if Types.multiple?(coerce_type) && validations.key?(:type) + validations[:coerce] = Types::VariantCollectionCoercer.new( + coerce_type, + validations.delete(:coerce_with) + ) + end + validations.delete(:type) + + coerce_type + end + + # Enforce correct usage of :coerce_with parameter. + # We do not allow coercion without a type, nor with + # +JSON+ as a type since this defines its own coercion + # method. + def check_coerce_with(validations) + return unless validations.key?(:coerce_with) + # type must be supplied for coerce_with.. + raise ArgumentError, 'must supply type for coerce_with' unless validations.key?(:coerce) + + # but not special JSON types, which + # already imply coercion method + return if [JSON, Array[JSON]].exclude? validations[:coerce] + + raise ArgumentError, 'coerce_with disallowed for type: JSON' + end + + # Add type coercion validation to this scope, + # if any has been specified. + # This validation has special handling since it is + # composited from more than one +requires+/+optional+ + # parameter, and needs to be run before most other + # validations. + def coerce_type(validations, attrs, doc, opts) + check_coerce_with(validations) + + return unless validations.key?(:coerce) + + coerce_options = { + type: validations[:coerce], + method: validations[:coerce_with], + message: validations[:coerce_message] + } + validate('coerce', coerce_options, attrs, doc, opts) + validations.delete(:coerce_with) + validations.delete(:coerce) + validations.delete(:coerce_message) + end + + def guess_coerce_type(coerce_type, *values_list) + return coerce_type unless coerce_type == Array + + values_list.each do |values| + next if !values || values.is_a?(Proc) + return values.first.class if values.is_a?(Range) || !values.empty? + end + coerce_type + end + + def check_incompatible_option_values(default, values, except_values, excepts) + return unless default && !default.is_a?(Proc) + + raise Grape::Exceptions::IncompatibleOptionValues.new(:default, default, :values, values) if values && !values.is_a?(Proc) && !Array(default).all? { |def_val| values.include?(def_val) } + + if except_values && !except_values.is_a?(Proc) && Array(default).any? { |def_val| except_values.include?(def_val) } + raise Grape::Exceptions::IncompatibleOptionValues.new(:default, default, :except, except_values) + end + + return unless excepts && !excepts.is_a?(Proc) + raise Grape::Exceptions::IncompatibleOptionValues.new(:default, default, :except, excepts) \ + unless Array(default).none? { |def_val| excepts.include?(def_val) } + end + + def validate(type, options, attrs, doc, opts) + validator_options = { + attributes: attrs, + options: options, + required: doc.required, + params_scope: self, + opts: opts, + validator_class: Validations.require_validator(type) + } + @api.namespace_stackable(:validations, validator_options) + end + + def validate_value_coercion(coerce_type, *values_list) + return unless coerce_type + + coerce_type = coerce_type.first if coerce_type.is_a?(Enumerable) + values_list.each do |values| + next if !values || values.is_a?(Proc) + + value_types = values.is_a?(Range) ? [values.begin, values.end].compact : values + value_types = value_types.map { |type| Grape::API::Boolean.build(type) } if coerce_type == Grape::API::Boolean + raise Grape::Exceptions::IncompatibleOptionValues.new(:type, coerce_type, :values, values) unless value_types.all?(coerce_type) + end + end + + def extract_message_option(attrs) + return nil unless attrs.is_a?(Array) + + opts = attrs.last.is_a?(Hash) ? attrs.pop : {} + opts.key?(:message) && !opts[:message].nil? ? opts.delete(:message) : nil + end + + def options_key?(type, key, validations) + validations[type].respond_to?(:key?) && validations[type].key?(key) && !validations[type][key].nil? + end + + def all_element_blank?(scoped_params) + scoped_params.respond_to?(:all?) && scoped_params.all?(&:blank?) + end + + # Validators don't have access to each other and they don't need, however, + # some validators might influence others, so their options should be shared + def derive_validator_options(validations) + allow_blank = validations[:allow_blank] + + { + allow_blank: allow_blank.is_a?(Hash) ? allow_blank[:value] : allow_blank, + fail_fast: validations.delete(:fail_fast) || false + } + end + + def validates_presence(validations, attrs, doc, opts) + return unless validations.key?(:presence) && validations[:presence] + + validate('presence', validations.delete(:presence), attrs, doc, opts) + validations.delete(:message) if validations.key?(:message) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/single_attribute_iterator.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/single_attribute_iterator.rb new file mode 100644 index 00000000..218f4037 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/single_attribute_iterator.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module Grape + module Validations + class SingleAttributeIterator < AttributesIterator + private + + def yield_attributes(val, attrs) + return if skip?(val) + + attrs.each do |attr_name| + yield val, attr_name, empty?(val) + end + end + + # Primitives like Integers and Booleans don't respond to +empty?+. + # It could be possible to use +blank?+ instead, but + # + # false.blank? + # => true + def empty?(val) + val.respond_to?(:empty?) ? val.empty? : val.nil? + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types.rb new file mode 100644 index 00000000..86f9c9b6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types.rb @@ -0,0 +1,213 @@ +# frozen_string_literal: true + +module Grape + module Validations + # Module for code related to grape's system for + # coercion and type validation of incoming request + # parameters. + # + # Grape uses a number of tests and assertions to + # work out exactly how a parameter should be handled, + # based on the +type+ and +coerce_with+ options that + # may be supplied to {Grape::Dsl::Parameters#requires} + # and {Grape::Dsl::Parameters#optional}. The main + # entry point for this process is {Types.build_coercer}. + module Types + module_function + + PRIMITIVES = [ + # Numerical + Integer, + Float, + BigDecimal, + Numeric, + + # Date/time + Date, + DateTime, + Time, + + # Misc + Grape::API::Boolean, + String, + Symbol, + TrueClass, + FalseClass + ].freeze + + # Types representing data structures. + STRUCTURES = [Hash, Array, Set].freeze + + SPECIAL = { + ::JSON => Json, + Array[JSON] => JsonArray, + ::File => File, + Rack::Multipart::UploadedFile => File + }.freeze + + GROUPS = [Array, Hash, JSON, Array[JSON]].freeze + + # Is the given class a primitive type as recognized by Grape? + # + # @param type [Class] type to check + # @return [Boolean] whether or not the type is known by Grape as a valid + # type for a single value + def primitive?(type) + PRIMITIVES.include?(type) + end + + # Is the given class a standard data structure (collection or map) + # as recognized by Grape? + # + # @param type [Class] type to check + # @return [Boolean] whether or not the type is known by Grape as a valid + # data structure type + def structure?(type) + STRUCTURES.include?(type) + end + + # Is the declared type in fact an array of multiple allowed types? + # For example the declaration +types: [Integer,String]+ will attempt + # first to coerce given values to integer, but will also accept any + # other string. + # + # @param type [Array,Set] type (or type list!) to check + # @return [Boolean] +true+ if the given value will be treated as + # a list of types. + def multiple?(type) + (type.is_a?(Array) || type.is_a?(Set)) && type.size > 1 + end + + # Does Grape provide special coercion and validation + # routines for the given class? This does not include + # automatic handling for primitives, structures and + # otherwise recognized types. See {Types::SPECIAL}. + # + # @param type [Class] type to check + # @return [Boolean] +true+ if special routines are available + def special?(type) + SPECIAL.key? type + end + + # Is the declared type a supported group type? + # Currently supported group types are Array, Hash, JSON, and Array[JSON] + # + # @param type [Array,Class] type to check + # @return [Boolean] +true+ if the type is a supported group type + def group?(type) + GROUPS.include? type + end + + # A valid custom type must implement a class-level `parse` method, taking + # one String argument and returning the parsed value in its correct type. + # + # @param type [Class] type to check + # @return [Boolean] whether or not the type can be used as a custom type + def custom?(type) + !primitive?(type) && + !structure?(type) && + !multiple?(type) && + type.respond_to?(:parse) && + type.method(:parse).arity == 1 + end + + # Is the declared type an +Array+ or +Set+ of a {#custom?} type? + # + # @param type [Array,Class] type to check + # @return [Boolean] true if +type+ is a collection of a type that implements + # its own +#parse+ method. + def collection_of_custom?(type) + (type.is_a?(Array) || type.is_a?(Set)) && + type.length == 1 && + (custom?(type.first) || special?(type.first)) + end + + def map_special(type) + SPECIAL.fetch(type, type) + end + + # Chooses the best coercer for the given type. For example, if the type + # is Integer, it will return a coercer which will be able to coerce a value + # to the integer. + # + # There are a few very special coercers which might be returned. + # + # +Grape::Types::MultipleTypeCoercer+ is a coercer which is returned when + # the given type implies values in an array with different types. + # For example, +[Integer, String]+ allows integer and string values in + # an array. + # + # +Grape::Types::CustomTypeCoercer+ is a coercer which is returned when + # a method is specified by a user with +coerce_with+ option or the user + # specifies a custom type which implements requirments of + # +Grape::Types::CustomTypeCoercer+. + # + # +Grape::Types::CustomTypeCollectionCoercer+ is a very similar to the + # previous one, but it expects an array or set of values having a custom + # type implemented by the user. + # + # There is also a group of custom types implemented by Grape, check + # +Grape::Validations::Types::SPECIAL+ to get the full list. + # + # @param type [Class] the type to which input strings + # should be coerced + # @param method [Class,#call] the coercion method to use + # @return [Object] object to be used + # for coercion and type validation + def build_coercer(type, method: nil, strict: false) + cache_instance(type, method, strict) do + create_coercer_instance(type, method, strict) + end + end + + def create_coercer_instance(type, method, strict) + # Maps a custom type provided by Grape, it doesn't map types wrapped by collections!!! + type = Types.map_special(type) + + # Use a special coercer for multiply-typed parameters. + if Types.multiple?(type) + MultipleTypeCoercer.new(type, method) + + # Use a special coercer for custom types and coercion methods. + elsif method || Types.custom?(type) + CustomTypeCoercer.new(type, method) + + # Special coercer for collections of types that implement a parse method. + # CustomTypeCoercer (above) already handles such types when an explicit coercion + # method is supplied. + elsif Types.collection_of_custom?(type) + Types::CustomTypeCollectionCoercer.new( + Types.map_special(type.first), type.is_a?(Set) + ) + else + DryTypeCoercer.coercer_instance_for(type, strict) + end + end + + def cache_instance(type, method, strict, &_block) + key = cache_key(type, method, strict) + + return @__cache[key] if @__cache.key?(key) + + instance = yield + + @__cache_write_lock.synchronize do + @__cache[key] = instance + end + + instance + end + + def cache_key(type, method, strict) + [type, method, strict].each_with_object(+'_') do |val, memo| + next if val.nil? + + memo << '_' << val.to_s + end + end + + instance_variable_set(:@__cache, {}) + instance_variable_set(:@__cache_write_lock, Mutex.new) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/array_coercer.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/array_coercer.rb new file mode 100644 index 00000000..ec4ca41d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/array_coercer.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Types + # Coerces elements in an array. It might be an array of strings or integers or + # an array of arrays of integers. + # + # It could've been possible to use an +of+ + # method (https://dry-rb.org/gems/dry-types/1.2/array-with-member/) + # provided by dry-types. Unfortunately, it doesn't work for Grape because of + # behavior of Virtus which was used earlier, a `Grape::Validations::Types::PrimitiveCoercer` + # maintains Virtus behavior in coercing. + class ArrayCoercer < DryTypeCoercer + def initialize(type, strict = false) + super + + @coercer = scope::Array + @subtype = type.first + end + + def call(_val) + collection = super + return collection if collection.is_a?(InvalidValue) + + coerce_elements collection + end + + protected + + attr_reader :subtype + + def coerce_elements(collection) + return if collection.nil? + + collection.each_with_index do |elem, index| + return InvalidValue.new if reject?(elem) + + coerced_elem = elem_coercer.call(elem) + + return coerced_elem if coerced_elem.is_a?(InvalidValue) + + collection[index] = coerced_elem + end + + collection + end + + # This method maintains logic which was defined by Virtus for arrays. + # Virtus doesn't allow nil in arrays. + def reject?(val) + val.nil? + end + + def elem_coercer + @elem_coercer ||= DryTypeCoercer.coercer_instance_for(subtype, strict) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/custom_type_coercer.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/custom_type_coercer.rb new file mode 100644 index 00000000..b0a1e54b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/custom_type_coercer.rb @@ -0,0 +1,164 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Types + # This class will detect type classes that implement + # a class-level +parse+ method. The method should accept one + # +String+ argument and should return the value coerced to + # the appropriate type. The method may raise an exception if + # there are any problems parsing the string. + # + # Alternately an optional +method+ may be supplied (see the + # +coerce_with+ option of {Grape::Dsl::Parameters#requires}). + # This may be any class or object implementing +parse+ or +call+, + # with the same contract as described above. + # + # Type Checking + # ------------- + # + # Calls to +coerced?+ will consult this class to check + # that the coerced value produced above is in fact of the + # expected type. By default this class performs a basic check + # against the type supplied, but this behaviour will be + # overridden if the class implements a class-level + # +coerced?+ or +parsed?+ method. This method + # will receive a single parameter that is the coerced value + # and should return +true+ if the value meets type expectations. + # Arbitrary assertions may be made here but the grape validation + # system should be preferred. + # + # Alternately a proc or other object responding to +call+ may be + # supplied in place of a type. This should implement the same + # contract as +coerced?+, and must be supplied with a coercion + # +method+. + class CustomTypeCoercer + # A new coercer for the given type specification + # and coercion method. + # + # @param type [Class,#coerced?,#parsed?,#call?] + # specifier for the target type. See class docs. + # @param method [#parse,#call] + # optional coercion method. See class docs. + def initialize(type, method = nil) + coercion_method = infer_coercion_method type, method + @method = enforce_symbolized_keys type, coercion_method + @type_check = infer_type_check(type) + end + + # Coerces the given value. + # + # @param value [String] value to be coerced, in grape + # this should always be a string. + # @return [Object] the coerced result + def call(val) + coerced_val = @method.call(val) + + return coerced_val if coerced_val.is_a?(InvalidValue) + return InvalidValue.new unless coerced?(coerced_val) + + coerced_val + end + + def coerced?(val) + val.nil? || @type_check.call(val) + end + + private + + # Determine the coercion method we're expected to use + # based on the parameters given. + # + # @param type see #new + # @param method see #new + # @return [#call] coercion method + def infer_coercion_method(type, method) + if method + if method.respond_to? :parse + method.method :parse + else + method + end + else + # Try to use parse() declared on the target type. + # This may raise an exception, but we are out of ideas anyway. + type.method :parse + end + end + + # Determine how the type validity of a coerced + # value should be decided. + # + # @param type see #new + # @return [#call] a procedure which accepts a single parameter + # and returns +true+ if the passed object is of the correct type. + def infer_type_check(type) + # First check for special class methods + if type.respond_to? :coerced? + type.method :coerced? + elsif type.respond_to? :parsed? + type.method :parsed? + elsif type.respond_to? :call + # Arbitrary proc passed for type validation. + # Note that this will fail unless a method is also + # passed, or if the type also implements a parse() method. + type + elsif type.is_a?(Enumerable) + lambda do |value| + value.is_a?(Enumerable) && value.all? do |val| + recursive_type_check(type.first, val) + end + end + else + # By default, do a simple type check + ->(value) { value.is_a? type } + end + end + + def recursive_type_check(type, value) + if type.is_a?(Enumerable) && value.is_a?(Enumerable) + value.all? { |val| recursive_type_check(type.first, val) } + else + !type.is_a?(Enumerable) && value.is_a?(type) + end + end + + # Enforce symbolized keys for complex types + # by wrapping the coercion method such that + # any Hash objects in the immediate heirarchy + # have their keys recursively symbolized. + # This helps common libs such as JSON to work easily. + # + # @param type see #new + # @param method see #infer_coercion_method + # @return [#call] +method+ wrapped in an additional + # key-conversion step, or just returns +method+ + # itself if no conversion is deemed to be + # necessary. + def enforce_symbolized_keys(type, method) + # Collections have all values processed individually + if [Array, Set].include?(type) + lambda do |val| + method.call(val).tap do |new_val| + new_val.map do |item| + item.is_a?(Hash) ? item.deep_symbolize_keys : item + end + end + end + + # Hash objects are processed directly + elsif type == Hash + lambda do |val| + method.call(val).deep_symbolize_keys + end + + # Simple types are not processed. + # This includes Array types. + else + method + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/custom_type_collection_coercer.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/custom_type_collection_coercer.rb new file mode 100644 index 00000000..2a5a002f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/custom_type_collection_coercer.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Types + # See {CustomTypeCoercer} for details on types + # that will be supported by this by this coercer. + # This coercer works in the same way as +CustomTypeCoercer+ + # except that it expects to receive an array of strings to + # coerce and will return an array (or optionally, a set) + # of coerced values. + # + # +CustomTypeCoercer+ is already capable of providing type + # checking for arrays where an independent coercion method + # is supplied. As such, +CustomTypeCollectionCoercer+ does + # not allow for such a method to be supplied independently + # of the type. + class CustomTypeCollectionCoercer < CustomTypeCoercer + # A new coercer for collections of the given type. + # + # @param type [Class,#parse] + # type to which items in the array should be coerced. + # Must implement a +parse+ method which accepts a string, + # and for the purposes of type-checking it may either be + # a class, or it may implement a +coerced?+, +parsed?+ or + # +call+ method (in that order of precedence) which + # accepts a single argument and returns true if the given + # array item has been coerced correctly. + # @param set [Boolean] + # when true, a +Set+ will be returned by {#call} instead + # of an +Array+ and duplicate items will be discarded. + def initialize(type, set = false) + super(type) + @set = set + end + + # Coerces the given value. + # + # @param value [Array] an array of values to be coerced + # @return [Array,Set] the coerced result. May be an +Array+ or a + # +Set+ depending on the setting given to the constructor + def call(value) + coerced = value.map do |item| + coerced_item = super(item) + + return coerced_item if coerced_item.is_a?(InvalidValue) + + coerced_item + end + + @set ? Set.new(coerced) : coerced + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/dry_type_coercer.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/dry_type_coercer.rb new file mode 100644 index 00000000..f9672198 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/dry_type_coercer.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +module DryTypes + # Call +Dry.Types()+ to add all registered types to +DryTypes+ which is + # a container in this case. Check documentation for more information + # https://dry-rb.org/gems/dry-types/1.2/getting-started/ + include Dry.Types() +end + +module Grape + module Validations + module Types + # A base class for classes which must identify a coercer to be used. + # If the +strict+ argument is true, it won't coerce the given value + # but check its type. More information there + # https://dry-rb.org/gems/dry-types/1.2/built-in-types/ + class DryTypeCoercer + class << self + # Returns a collection coercer which corresponds to a given type. + # Example: + # + # collection_coercer_for(Array) + # #=> Grape::Validations::Types::ArrayCoercer + def collection_coercer_for(type) + case type + when Array + ArrayCoercer + when Set + SetCoercer + else + raise ArgumentError, "Unknown type: #{type}" + end + end + + # Returns an instance of a coercer for a given type + def coercer_instance_for(type, strict = false) + klass = type.instance_of?(Class) ? PrimitiveCoercer : collection_coercer_for(type) + klass.new(type, strict) + end + end + + def initialize(type, strict = false) + @type = type + @strict = strict + @scope = strict ? DryTypes::Strict : DryTypes::Params + end + + # Coerces the given value to a type which was specified during + # initialization as a type argument. + # + # @param val [Object] + def call(val) + return if val.nil? + + @coercer[val] + rescue Dry::Types::CoercionError => _e + InvalidValue.new + end + + protected + + attr_reader :scope, :type, :strict + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/file.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/file.rb new file mode 100644 index 00000000..8c2f6d92 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/file.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Types + # Implementation for parameters that are multipart file objects. + # Actual handling of these objects is provided by +Rack::Request+; + # this class is here only to assert that rack's handling has succeeded. + class File + class << self + def parse(input) + return if input.nil? + return InvalidValue.new unless parsed?(input) + + # Processing of multipart file objects + # is already taken care of by Rack::Request. + # Nothing to do here. + input + end + + def parsed?(value) + # Rack::Request creates a Hash with filename, + # content type and an IO object. Do a bit of basic + # duck-typing. + value.is_a?(::Hash) && value.key?(:tempfile) && value[:tempfile].is_a?(Tempfile) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/invalid_value.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/invalid_value.rb new file mode 100644 index 00000000..9744a285 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/invalid_value.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Types + # Instances of this class may be used as tokens to denote that a parameter value could not be + # coerced. The given message will be used as a validation error. + class InvalidValue + attr_reader :message + + def initialize(message = nil) + @message = message + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/json.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/json.rb new file mode 100644 index 00000000..61b01131 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/json.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Types + # Handles coercion and type checking for parameters that are complex + # types given as JSON-encoded strings. It accepts both JSON objects + # and arrays of objects, and will coerce the input to a +Hash+ + # or +Array+ object respectively. In either case the Grape + # validation system will apply nested validation rules to + # all returned objects. + class Json + class << self + # Coerce the input into a JSON-like data structure. + # + # @param input [String] a JSON-encoded parameter value + # @return [Hash,Array,nil] + def parse(input) + return input if parsed?(input) + + # Allow nulls and blank strings + return if input.nil? || input.match?(/^\s*$/) + + JSON.parse(input, symbolize_names: true) + end + + # Checks that the input was parsed successfully + # and isn't something odd such as an array of primitives. + # + # @param value [Object] result of {#parse} + # @return [true,false] + def parsed?(value) + value.is_a?(::Hash) || coerced_collection?(value) + end + + protected + + # Is the value an array of JSON-like objects? + # + # @param value [Object] result of {#parse} + # @return [true,false] + def coerced_collection?(value) + value.is_a?(::Array) && value.all?(::Hash) + end + end + end + + # Specialization of the {Json} attribute that is guaranteed + # to return an array of objects. Accepts both JSON-encoded + # objects and arrays of objects, but wraps single objects + # in an Array. + class JsonArray < Json + class << self + # See {Json#parse}. Wraps single objects in an array. + # + # @param input [String] JSON-encoded parameter value + # @return [Array] + def parse(input) + json = super + Array.wrap(json) unless json.nil? + end + + # See {Json#coerced_collection?} + def parsed?(value) + coerced_collection? value + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/multiple_type_coercer.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/multiple_type_coercer.rb new file mode 100644 index 00000000..304746ae --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/multiple_type_coercer.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Types + # This class is intended for use with Grape endpoint parameters that + # have been declared to be of variant-type using the +:types+ option. + # +MultipleTypeCoercer+ will build a coercer for each type declared + # in the array passed to +:types+ using {Types.build_coercer}. It will + # apply these coercers to parameter values in the order given to + # +:types+, and will return the value returned by the first coercer + # to successfully coerce the parameter value. Therefore if +String+ is + # an allowed type it should be declared last, since it will always + # successfully "coerce" the value. + class MultipleTypeCoercer + # Construct a new coercer that will attempt to coerce + # values to the given list of types in the given order. + # + # @param types [Array] list of allowed types + # @param method [#call,#parse] method by which values should be + # coerced. See class docs for default behaviour. + def initialize(types, method = nil) + @method = method.respond_to?(:parse) ? method.method(:parse) : method + + @type_coercers = types.map do |type| + if Types.multiple? type + VariantCollectionCoercer.new type, @method + else + Types.build_coercer type, strict: !@method.nil? + end + end + end + + # Coerces the given value. + # + # @param val [String] value to be coerced, in grape + # this should always be a string. + # @return [Object,InvalidValue] the coerced result, or an instance + # of {InvalidValue} if the value could not be coerced. + def call(val) + # once the value is coerced by the custom method, its type should be checked + val = @method.call(val) if @method + + coerced_val = InvalidValue.new + + @type_coercers.each do |coercer| + coerced_val = coercer.call(val) + + return coerced_val unless coerced_val.is_a?(InvalidValue) + end + + coerced_val + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/primitive_coercer.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/primitive_coercer.rb new file mode 100644 index 00000000..e59b5c6e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/primitive_coercer.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Types + # Coerces the given value to a type defined via a +type+ argument during + # initialization. When +strict+ is true, it doesn't coerce a value but check + # that it has the proper type. + class PrimitiveCoercer < DryTypeCoercer + MAPPING = { + Grape::API::Boolean => DryTypes::Params::Bool, + BigDecimal => DryTypes::Params::Decimal, + Numeric => DryTypes::Params::Integer | DryTypes::Params::Float | DryTypes::Params::Decimal, + TrueClass => DryTypes::Params::Bool.constrained(eql: true), + FalseClass => DryTypes::Params::Bool.constrained(eql: false), + + # unfortunately, a +Params+ scope doesn't contain String + String => DryTypes::Coercible::String + }.freeze + + STRICT_MAPPING = { + Grape::API::Boolean => DryTypes::Strict::Bool, + BigDecimal => DryTypes::Strict::Decimal, + Numeric => DryTypes::Strict::Integer | DryTypes::Strict::Float | DryTypes::Strict::Decimal, + TrueClass => DryTypes::Strict::Bool.constrained(eql: true), + FalseClass => DryTypes::Strict::Bool.constrained(eql: false) + }.freeze + + def initialize(type, strict = false) + super + + @type = type + + @coercer = (strict ? STRICT_MAPPING : MAPPING).fetch(type) do + scope.const_get(type.name, false) + rescue NameError + raise ArgumentError, "type #{type} should support coercion via `[]`" unless type.respond_to?(:[]) + + type + end + end + + def call(val) + return InvalidValue.new if reject?(val) + return nil if val.nil? || treat_as_nil?(val) + + super + end + + protected + + attr_reader :type + + # This method maintains logic which was defined by Virtus. For example, + # dry-types is ok to convert an array or a hash to a string, it is supported, + # but Virtus wouldn't accept it. So, this method only exists to not introduce + # breaking changes. + def reject?(val) + (val.is_a?(Array) && type == String) || + (val.is_a?(String) && type == Hash) || + (val.is_a?(Hash) && type == String) + end + + # Dry-Types treats an empty string as invalid. However, Grape considers an empty string as + # absence of a value and coerces it into nil. See a discussion there + # https://github.com/ruby-grape/grape/pull/2045 + def treat_as_nil?(val) + val == '' && type != String + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/set_coercer.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/set_coercer.rb new file mode 100644 index 00000000..9b1b311f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/set_coercer.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Types + # Takes the given array and converts it to a set. Every element of the set + # is also coerced. + class SetCoercer < ArrayCoercer + def initialize(type, strict = false) + super + + @coercer = nil + end + + def call(value) + return InvalidValue.new unless value.is_a?(Array) + + coerce_elements(value) + end + + protected + + def coerce_elements(collection) + collection.each_with_object(Set.new) do |elem, memo| + coerced_elem = elem_coercer.call(elem) + + return coerced_elem if coerced_elem.is_a?(InvalidValue) + + memo.add(coerced_elem) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/variant_collection_coercer.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/variant_collection_coercer.rb new file mode 100644 index 00000000..34982e13 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/types/variant_collection_coercer.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Types + # This class wraps {MultipleTypeCoercer}, for use with collections + # that allow members of more than one type. + class VariantCollectionCoercer + # Construct a new coercer that will attempt to coerce + # a list of values such that all members are of one of + # the given types. The container may also optionally be + # coerced to a +Set+. An arbitrary coercion +method+ may + # be supplied, which will be passed the entire collection + # as a parameter and should return a new collection, or + # may return the same one if no coercion was required. + # + # @param types [Array,Set] list of allowed types, + # also specifying the container type + # @param method [#call,#parse] method by which values should be coerced + def initialize(types, method = nil) + @types = types + @method = method.respond_to?(:parse) ? method.method(:parse) : method + + # If we have a coercion method, pass it in here to save + # building another one, even though we call it directly. + @member_coercer = MultipleTypeCoercer.new types, method + end + + # Coerce the given value. + # + # @param value [Array] collection of values to be coerced + # @return [Array,Set,InvalidValue] + # the coerced result, or an instance + # of {InvalidValue} if the value could not be coerced. + def call(value) + return unless value.is_a? Array + + value = + if @method + @method.call(value) + else + value.map { |v| @member_coercer.call(v) } + end + return Set.new value if @types.is_a? Set + + value + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validator_factory.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validator_factory.rb new file mode 100644 index 00000000..0e2022d3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validator_factory.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Grape + module Validations + class ValidatorFactory + def self.create_validator(options) + options[:validator_class].new(options[:attributes], + options[:options], + options[:required], + options[:params_scope], + options[:opts]) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/all_or_none_of_validator.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/all_or_none_of_validator.rb new file mode 100644 index 00000000..2fe553a1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/all_or_none_of_validator.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Validators + class AllOrNoneOfValidator < MultipleParamsBase + def validate_params!(params) + keys = keys_in_common(params) + return if keys.empty? || keys.length == all_keys.length + + raise Grape::Exceptions::Validation.new(params: all_keys, message: message(:all_or_none)) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/allow_blank_validator.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/allow_blank_validator.rb new file mode 100644 index 00000000..b9954c1d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/allow_blank_validator.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Validators + class AllowBlankValidator < Base + def validate_param!(attr_name, params) + return if (options_key?(:value) ? @option[:value] : @option) || !params.is_a?(Hash) + + value = params[attr_name] + value = value.scrub if value.respond_to?(:scrub) + + return if value == false || value.present? + + raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message(:blank)) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/as_validator.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/as_validator.rb new file mode 100644 index 00000000..8a3d8db1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/as_validator.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Validators + class AsValidator < Base + # We use a validator for renaming parameters. This is just a marker for + # the parameter scope to handle the renaming. No actual validation + # happens here. + def validate_param!(*); end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/at_least_one_of_validator.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/at_least_one_of_validator.rb new file mode 100644 index 00000000..3467e4f1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/at_least_one_of_validator.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Validators + class AtLeastOneOfValidator < MultipleParamsBase + def validate_params!(params) + return unless keys_in_common(params).empty? + + raise Grape::Exceptions::Validation.new(params: all_keys, message: message(:at_least_one)) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/base.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/base.rb new file mode 100644 index 00000000..890963d9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/base.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Validators + class Base + attr_reader :attrs + + # Creates a new Validator from options specified + # by a +requires+ or +optional+ directive during + # parameter definition. + # @param attrs [Array] names of attributes to which the Validator applies + # @param options [Object] implementation-dependent Validator options + # @param required [Boolean] attribute(s) are required or optional + # @param scope [ParamsScope] parent scope for this Validator + # @param opts [Hash] additional validation options + def initialize(attrs, options, required, scope, opts) + @attrs = Array(attrs) + @option = options + @required = required + @scope = scope + @fail_fast = opts[:fail_fast] + @allow_blank = opts[:allow_blank] + end + + # Validates a given request. + # @note Override #validate! unless you need to access the entire request. + # @param request [Grape::Request] the request currently being handled + # @raise [Grape::Exceptions::Validation] if validation failed + # @return [void] + def validate(request) + return unless @scope.should_validate?(request.params) + + validate!(request.params) + end + + # Validates a given parameter hash. + # @note Override #validate if you need to access the entire request. + # @param params [Hash] parameters to validate + # @raise [Grape::Exceptions::Validation] if validation failed + # @return [void] + def validate!(params) + attributes = SingleAttributeIterator.new(self, @scope, params) + # we collect errors inside array because + # there may be more than one error per field + array_errors = [] + + attributes.each do |val, attr_name, empty_val| + next if !@scope.required? && empty_val + next unless @scope.meets_dependency?(val, params) + + validate_param!(attr_name, val) if @required || (val.respond_to?(:key?) && val.key?(attr_name)) + rescue Grape::Exceptions::Validation => e + array_errors << e + end + + raise Grape::Exceptions::ValidationArrayErrors.new(array_errors) if array_errors.any? + end + + def self.inherited(klass) + super + Validations.register(klass) + end + + def message(default_key = nil) + options = instance_variable_get(:@option) + options_key?(:message) ? options[:message] : default_key + end + + def options_key?(key, options = nil) + options = instance_variable_get(:@option) if options.nil? + options.respond_to?(:key?) && options.key?(key) && !options[key].nil? + end + + def fail_fast? + @fail_fast + end + end + end + end +end + +Grape::Validations::Base = Class.new(Grape::Validations::Validators::Base) do + def self.inherited(*) + Grape.deprecator.warn 'Grape::Validations::Base is deprecated! Use Grape::Validations::Validators::Base instead.' + super + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/coerce_validator.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/coerce_validator.rb new file mode 100644 index 00000000..eaf7c406 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/coerce_validator.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Validators + class CoerceValidator < Base + def initialize(attrs, options, required, scope, opts) + super + + @converter = if type.is_a?(Grape::Validations::Types::VariantCollectionCoercer) + type + else + Types.build_coercer(type, method: @option[:method]) + end + end + + def validate_param!(attr_name, params) + raise validation_exception(attr_name) unless params.is_a? Hash + + new_value = coerce_value(params[attr_name]) + + raise validation_exception(attr_name, new_value.message) unless valid_type?(new_value) + + # Don't assign a value if it is identical. It fixes a problem with Hashie::Mash + # which looses wrappers for hashes and arrays after reassigning values + # + # h = Hashie::Mash.new(list: [1, 2, 3, 4]) + # => #> + # list = h.list + # h[:list] = list + # h + # => # + return if params[attr_name].instance_of?(new_value.class) && params[attr_name] == new_value + + params[attr_name] = new_value + end + + private + + # @!attribute [r] converter + # Object that will be used for parameter coercion and type checking. + # + # See {Types.build_coercer} + # + # @return [Object] + attr_reader :converter + + def valid_type?(val) + !val.is_a?(Types::InvalidValue) + end + + def coerce_value(val) + converter.call(val) + # Some custom types might fail, so it should be treated as an invalid value + rescue StandardError + Types::InvalidValue.new + end + + # Type to which the parameter will be coerced. + # + # @return [Class] + def type + @option[:type].is_a?(Hash) ? @option[:type][:value] : @option[:type] + end + + def validation_exception(attr_name, custom_msg = nil) + Grape::Exceptions::Validation.new( + params: [@scope.full_name(attr_name)], + message: custom_msg || message(:coerce) + ) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/contract_scope_validator.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/contract_scope_validator.rb new file mode 100644 index 00000000..b8a3365c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/contract_scope_validator.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Validators + class ContractScopeValidator < Base + attr_reader :schema + + def initialize(_attrs, _options, _required, _scope, opts) + super + @schema = opts.fetch(:schema) + end + + # Validates a given request. + # @param request [Grape::Request] the request currently being handled + # @raise [Grape::Exceptions::ValidationArrayErrors] if validation failed + # @return [void] + def validate(request) + res = schema.call(request.params) + + if res.success? + request.params.deep_merge!(res.to_h) + return + end + + raise Grape::Exceptions::ValidationArrayErrors.new(build_errors_from_messages(res.errors.messages)) + end + + private + + def build_errors_from_messages(messages) + messages.map do |message| + full_name = message.path.first.to_s + full_name << "[#{message.path[1..].join('][')}]" if message.path.size > 1 + Grape::Exceptions::Validation.new(params: [full_name], message: message.text) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/default_validator.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/default_validator.rb new file mode 100644 index 00000000..eba8c773 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/default_validator.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Validators + class DefaultValidator < Base + def initialize(attrs, options, required, scope, opts = {}) + @default = options + super + end + + def validate_param!(attr_name, params) + params[attr_name] = if @default.is_a? Proc + if @default.parameters.empty? + @default.call + else + @default.call(params) + end + elsif @default.frozen? || !@default.duplicable? + @default + else + @default.dup + end + end + + def validate!(params) + attrs = SingleAttributeIterator.new(self, @scope, params) + attrs.each do |resource_params, attr_name| + next unless @scope.meets_dependency?(resource_params, params) + + validate_param!(attr_name, resource_params) if resource_params.is_a?(Hash) && resource_params[attr_name].nil? + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/exactly_one_of_validator.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/exactly_one_of_validator.rb new file mode 100644 index 00000000..aa1c5471 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/exactly_one_of_validator.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Validators + class ExactlyOneOfValidator < MultipleParamsBase + def validate_params!(params) + keys = keys_in_common(params) + return if keys.length == 1 + raise Grape::Exceptions::Validation.new(params: all_keys, message: message(:exactly_one)) if keys.empty? + + raise Grape::Exceptions::Validation.new(params: keys, message: message(:mutual_exclusion)) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/except_values_validator.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/except_values_validator.rb new file mode 100644 index 00000000..298eb0ab --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/except_values_validator.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Validators + class ExceptValuesValidator < Base + def initialize(attrs, options, required, scope, opts) + @except = options.is_a?(Hash) ? options[:value] : options + super + end + + def validate_param!(attr_name, params) + return unless params.respond_to?(:key?) && params.key?(attr_name) + + excepts = @except.is_a?(Proc) ? @except.call : @except + return if excepts.nil? + + param_array = params[attr_name].nil? ? [nil] : Array.wrap(params[attr_name]) + raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message(:except_values)) if param_array.any? { |param| excepts.include?(param) } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/length_validator.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/length_validator.rb new file mode 100644 index 00000000..c84b4c09 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/length_validator.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Validators + class LengthValidator < Base + def initialize(attrs, options, required, scope, opts) + @min = options[:min] + @max = options[:max] + @is = options[:is] + + super + + raise ArgumentError, 'min must be an integer greater than or equal to zero' if !@min.nil? && (!@min.is_a?(Integer) || @min.negative?) + raise ArgumentError, 'max must be an integer greater than or equal to zero' if !@max.nil? && (!@max.is_a?(Integer) || @max.negative?) + raise ArgumentError, "min #{@min} cannot be greater than max #{@max}" if !@min.nil? && !@max.nil? && @min > @max + + return if @is.nil? + raise ArgumentError, 'is must be an integer greater than zero' if !@is.is_a?(Integer) || !@is.positive? + raise ArgumentError, 'is cannot be combined with min or max' if !@min.nil? || !@max.nil? + end + + def validate_param!(attr_name, params) + param = params[attr_name] + + return unless param.respond_to?(:length) + + return unless (!@min.nil? && param.length < @min) || (!@max.nil? && param.length > @max) || (!@is.nil? && param.length != @is) + + raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: build_message) + end + + def build_message + if options_key?(:message) + @option[:message] + elsif @min && @max + format I18n.t(:length, scope: 'grape.errors.messages'), min: @min, max: @max + elsif @min + format I18n.t(:length_min, scope: 'grape.errors.messages'), min: @min + elsif @max + format I18n.t(:length_max, scope: 'grape.errors.messages'), max: @max + else + format I18n.t(:length_is, scope: 'grape.errors.messages'), is: @is + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/multiple_params_base.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/multiple_params_base.rb new file mode 100644 index 00000000..29df2772 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/multiple_params_base.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Validators + class MultipleParamsBase < Base + def validate!(params) + attributes = MultipleAttributesIterator.new(self, @scope, params) + array_errors = [] + + attributes.each do |resource_params| + validate_params!(resource_params) + rescue Grape::Exceptions::Validation => e + array_errors << e + end + + raise Grape::Exceptions::ValidationArrayErrors.new(array_errors) if array_errors.any? + end + + private + + def keys_in_common(resource_params) + return [] unless resource_params.is_a?(Hash) + + all_keys & resource_params.keys.map! { |attr| @scope.full_name(attr) } + end + + def all_keys + attrs.map { |attr| @scope.full_name(attr) } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/mutual_exclusion_validator.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/mutual_exclusion_validator.rb new file mode 100644 index 00000000..8d19da34 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/mutual_exclusion_validator.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Validators + class MutualExclusionValidator < MultipleParamsBase + def validate_params!(params) + keys = keys_in_common(params) + return if keys.length <= 1 + + raise Grape::Exceptions::Validation.new(params: keys, message: message(:mutual_exclusion)) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/presence_validator.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/presence_validator.rb new file mode 100644 index 00000000..ae31dc3f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/presence_validator.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Validators + class PresenceValidator < Base + def validate_param!(attr_name, params) + return if params.respond_to?(:key?) && params.key?(attr_name) + + raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message(:presence)) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/regexp_validator.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/regexp_validator.rb new file mode 100644 index 00000000..86d3bbe0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/regexp_validator.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Validators + class RegexpValidator < Base + def validate_param!(attr_name, params) + return unless params.respond_to?(:key?) && params.key?(attr_name) + return if Array.wrap(params[attr_name]).all? { |param| param.nil? || param.to_s.scrub.match?((options_key?(:value) ? @option[:value] : @option)) } + + raise Grape::Exceptions::Validation.new(params: [@scope.full_name(attr_name)], message: message(:regexp)) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/same_as_validator.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/same_as_validator.rb new file mode 100644 index 00000000..5a65afa6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/same_as_validator.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Validators + class SameAsValidator < Base + def validate_param!(attr_name, params) + confirmation = options_key?(:value) ? @option[:value] : @option + return if params[attr_name] == params[confirmation] + + raise Grape::Exceptions::Validation.new( + params: [@scope.full_name(attr_name)], + message: build_message + ) + end + + private + + def build_message + if options_key?(:message) + @option[:message] + else + format I18n.t(:same_as, scope: 'grape.errors.messages'), parameter: @option + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/values_validator.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/values_validator.rb new file mode 100644 index 00000000..11f314a5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/validations/validators/values_validator.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +module Grape + module Validations + module Validators + class ValuesValidator < Base + def initialize(attrs, options, required, scope, opts) + @values = options.is_a?(Hash) ? options[:value] : options + super + end + + def validate_param!(attr_name, params) + return unless params.is_a?(Hash) + + val = params[attr_name] + + return if val.nil? && !required_for_root_scope? + + val = val.scrub if val.respond_to?(:scrub) + + # don't forget that +false.blank?+ is true + return if val != false && val.blank? && @allow_blank + + return if check_values?(val, attr_name) + + raise Grape::Exceptions::Validation.new( + params: [@scope.full_name(attr_name)], + message: message(:values) + ) + end + + private + + def check_values?(val, attr_name) + values = @values.is_a?(Proc) && @values.arity.zero? ? @values.call : @values + return true if values.nil? + + param_array = val.nil? ? [nil] : Array.wrap(val) + return param_array.all? { |param| values.include?(param) } unless values.is_a?(Proc) + + begin + param_array.all? { |param| values.call(param) } + rescue StandardError => e + warn "Error '#{e}' raised while validating attribute '#{attr_name}'" + false + end + end + + def required_for_root_scope? + return false unless @required + + scope = @scope + scope = scope.parent while scope.lateral? + + scope.root? + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/version.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/version.rb new file mode 100644 index 00000000..246308b4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/version.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +module Grape + # The current version of Grape. + VERSION = '2.3.0' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/xml.rb b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/xml.rb new file mode 100644 index 00000000..85287814 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-2.3.0/lib/grape/xml.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module Grape + if defined?(::MultiXml) + Xml = ::MultiXml + else + Xml = ::ActiveSupport::XmlMini + Xml::ParseError = StandardError + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/CHANGELOG.md b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/CHANGELOG.md new file mode 100644 index 00000000..c54b36a5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/CHANGELOG.md @@ -0,0 +1,747 @@ +### Next + +#### Features + +* your contribution + +#### Fixes + +* your contribution + + +### 2.1.2 (Jan 7, 2025) + +#### Features + +* [#945](https://github.com/ruby-grape/grape-swagger/pull/945): Add support for primitive data types in responses - [@gregg-platogo](https://github.com/gregg-platogo). + +#### Fixes + +* [#943](https://github.com/ruby-grape/grape-swagger/pull/943): Fix route_param documentation and type - [@4ndv](https://github.com/4ndv) +* [#944](https://github.com/ruby-grape/grape-swagger/pull/944): Amend a few typographic errors - [@pieterocp](https://github.com/pieterocp) +* Your contribution here. + + +### 2.1.1 (Sep 21, 2024) + +#### Fixes + +* [#940](https://github.com/ruby-grape/grape-swagger/pull/940): Grape 2.2.0 compatibility - [@padde](https://github.com/padde) + + +### 2.1.0 (May 14, 2024) + +#### Features + +* [#927](https://github.com/ruby-grape/grape-swagger/pull/927): Set default parameter location based on consumes - [@spaceraccoon](https://github.com/spaceraccoon) +* [#929](https://github.com/ruby-grape/grape-swagger/pull/929): Set query parameter for array of primitive types - [@spaceraccoon](https://github.com/spaceraccoon) + +#### Fixes + +* [#926](https://github.com/ruby-grape/grape-swagger/pull/926): Refactor route and namespace combination logic - [@numbata](https://github.com/numbata) + + +### 2.0.3 (April 26, 2024) + +#### Fixes + +* [#922](https://github.com/ruby-grape/grape-swagger/pull/922): Force request body to be an schema object - [@numbata](https://github.com/numbata) +* [#923](https://github.com/ruby-grape/grape-swagger/pull/923): Enabled schema definitions for body parameters in DELETE requests - [@numbata](https://github.com/numbata) +* [#924](https://github.com/ruby-grape/grape-swagger/pull/924): fix: Use mount_path to narrow down urls_for - [@chibicco](https://github.com/chibicco) + + +### 2.0.2 (Februar 2, 2024) + +#### Fixes + +* [#918](https://github.com/ruby-grape/grape-swagger/pull/918): Fix params extension does not work when param_type is body - [@numbata](https://github.com/numbata) + + +### 2.0.1 (Januar 2, 2024) + +#### Features + +* [#914](https://github.com/ruby-grape/grape-swagger/pull/914): Support Ruby 3.3 - [@LeFnord](https://github.com/LeFnord) + +#### Fixes + +* [#916](https://github.com/ruby-grape/grape-swagger/pull/916): Restore Ruby 3.0 support - [@godfat](https://github.com/godfat) + + +### 2.0.0 (November 7, 2023) + +#### Features + +* [#910](https://github.com/ruby-grape/grape-swagger/pull/910): Allow using Grape v2 - [@ninoseki](https://github.com/ninoseki) + +#### Fixes + +* [#903](https://github.com/ruby-grape/grape-swagger/pull/903): Accept `example` documentation parameter for arrays - [@VladMomotov](https://github.com/VladMomotov) + + +### 1.6.1 (May 21, 2023) + +#### Fixes + +* [#868](https://github.com/ruby-grape/grape-swagger/pull/896): Fix parsing endless range values - [@dhruvCW](https://github.com/dhruvCW) + + +### 1.6.0 (March 19, 2023) + +#### Features + +* [#872](https://github.com/ruby-grape/grape-swagger/pull/872): Add `consumes` and `produces` options to `add_swagger_documentation` - [@spaceraccoon](https://github.com/spaceraccoon) +* [#868](https://github.com/ruby-grape/grape-swagger/pull/868): Add `default` endpoint option to specify default response - [@dhruvCW](https://github.com/dhruvCW) + + +### 1.5.0 (July 28, 2022) + +#### Features + +* [#862](https://github.com/ruby-grape/grape-swagger/pull/862): Allow using nicknames for body definitions - [@magni-](https://github.com/magni-) + +#### Fixes + +* [#860](https://github.com/ruby-grape/grape-swagger/pull/860) chore: Included githubactions in the dependabot config [@naveensrinivasan](https://github.com/naveensrinivasan) +* [#843](https://github.com/ruby-grape/grape-swagger/pull/843) Syntax errors in README.md examples [@remvee](https://github.com/remvee) +* [#844](https://github.com/ruby-grape/grape-swagger/pull/844) Fixes the regexp used for parsing routes [@senhalil](https://github.com/senhalil) +* [#847](https://github.com/ruby-grape/grape-swagger/pull/847) Parse route_param type for nested endpoints [@dmoss18](https://github.com/dmoss18) +* [#856](https://github.com/ruby-grape/grape-swagger/pull/856) Remove unused methods in GrapeSwagger::DocMethods::BuildModelDefinition [@takahashim](https://github.com/takahashim) +* [#858](https://github.com/ruby-grape/grape-swagger/pull/858): Set permissions for GitHub actions [@naveensrinivasan](https://github.com/naveensrinivasan) +* [#853](https://github.com/ruby-grape/grape-swagger/pull/853): Add webrick to support Ruby 3.x [@takahashim](https://github.com/takahashim) +* [#852](https://github.com/ruby-grape/grape-swagger/pull/852): Fix example to work [@takahashim](https://github.com/takahashim) +* [#846](https://github.com/ruby-grape/grape-swagger/pull/846): Refactor oapi fetch task [@Vachman](https://github.com/Vachman) +* [#850](https://github.com/ruby-grape/grape-swagger/pull/850): Fix value of enum to be Array [@takahashim](https://github.com/takahashim) + +### 1.4.3 (January 5, 2022) + +#### Fixes + +* [#850](https://github.com/ruby-grape/grape-swagger/pull/850): Fix value of `enum` to be `Array` - [@takahashim](https://github.com/takahashim) +* [#846](https://github.com/ruby-grape/grape-swagger/pull/846): Fixes oapi rake tasks, allows generating sepcs for different API versions. +* [#852](https://github.com/ruby-grape/grape-swagger/pull/852): Fix example to work without error - [@takahashim](https://github.com/takahashim) +* [#853](https://github.com/ruby-grape/grape-swagger/pull/853): Add webrick gem so that example works in Ruby 3.x - [@takahashim](https://github.com/takahashim) +* [#844](https://github.com/ruby-grape/grape-swagger/pull/844): Fixes the regexp used for parsing routes - [@senhalil](https://github.com/senhalil) +* [#862](https://github.com/ruby-grape/grape-swagger/pull/862): Allow using nicknames for body definitions - [@magni-](https://github.com/magni-) + +### 1.4.2 (October 22, 2021) + +#### Fixes + +* [#840](https://github.com/ruby-grape/grape-swagger/pull/840): Fixes documentation of `additionalProperties` field when used with array parameters, or when setting it to `false` - [@magni-](https://github.com/magni-) +* [#841](https://github.com/ruby-grape/grape-swagger/pull/839): Fixes `type` and `format` values for object fields nested in an array ([#832](https://github.com/ruby-grape/grape-swagger/issue/832)) - [@magni-](https://github.com/magni-) +* [#839](https://github.com/ruby-grape/grape-swagger/pull/839): Fixes documentation of `false` or `nil` default parameter values - [@magni-](https://github.com/magni-) + + +### 1.4.1 (September 15, 2021) + +#### Fixes + +* [#833](https://github.com/ruby-grape/grape-swagger/pull/833): Fixes issue of examples not showing for `in: 'body'` parameters - [@stevenou](https://github.com/stevenou) + + +### 1.4.0 (March 20, 2021) + +#### Features + +* [#818](https://github.com/ruby-grape/grape-swagger/pull/818): Adds ruby 3.0 support - [@LeFnord](https://github.com/LeFnord). +* [#815](https://github.com/ruby-grape/grape-swagger/pull/815): Add required for multiple presents - [@MaximeRDY](https://github.com/MaximeRDY). + +#### Fixes + +* [#822](https://github.com/ruby-grape/grape-swagger/pull/822): Corrected the related parameter lookup on request params - [@Jack12816](https://github.com/Jack12816). + + +### 1.3.1 (November 1, 2020) + +#### Features + +* [#813](https://github.com/ruby-grape/grape-swagger/pull/813): Handle multiple presents - [@AntoineGuestin](https://github.com/AntoineGuestin). + +#### Fixes + +* [#811](https://github.com/ruby-grape/grape-swagger/pull/811): Fixes #809: supports utf8 route names - [@LeFnord](https://github.com/LeFnord). + + +### 1.3.0 (September 3, 2020) + +#### Features + +* [#804](https://github.com/ruby-grape/grape-swagger/pull/804): Don't overwrite model description with the route description - [@Bhacaz](https://github.com/Bhacaz). + + +### 1.2.1 (July 15, 2020) + +#### Fixes + +* [#801](https://github.com/ruby-grape/grape-swagger/pull/801): Fixes behaviour after grape upgrade to 1.4.0 - [@LeFnord](https://github.com/LeFnord). + + +### 1.2.0 (July 1, 2020) + +#### Features + +* [#794](https://github.com/ruby-grape/grape-swagger/pull/794): Allow `entity_name` to be inherited, fixes issue #659 - [@urkle](https://github.com/urkle). +* [#793](https://github.com/ruby-grape/grape-swagger/pull/793): Features/inheritance and discriminator - [@MaximeRDY](https://github.com/MaximeRDY). + +#### Fixes + +* [#798](https://github.com/ruby-grape/grape-swagger/pull/798): Modify full entity name separator - [@GarrettB71](https://github.com/GarrettB71). +* [#796](https://github.com/ruby-grape/grape-swagger/pull/796): Support grape 1.4.0 - [@thedanielhanke](https://github.com/thedanielhanke). + + +### 1.1.0 (April 20, 2020) + +#### Features + +* [#785](https://github.com/ruby-grape/grape-swagger/pull/785): Add extensions for params - [@MaximeRDY](https://github.com/MaximeRDY). +* [#782](https://github.com/ruby-grape/grape-swagger/pull/782): Allow passing class name as string for rake task initializer - [@misdoro](https://github.com/misdoro). +* [#786](https://github.com/ruby-grape/grape-swagger/pull/786): Use full entity name as a default - [@mrexox](https://github.com/mrexox). + + +### 1.0.0 (February 10, 2020) + +#### Features + +* [#777](https://github.com/ruby-grape/grape-swagger/pull/777): Make usage of grape >= 1.3, rack >= 2.1 - [@LeFnord](https://github.com/LeFnord). +* [#775](https://github.com/ruby-grape/grape-swagger/pull/775): Add in token_owner support to param hidden procs - [@urkle](https://github.com/urkle). + + +### 0.34.2 (January 20, 2020) + +#### Fixes + +* [#773](https://github.com/ruby-grape/grape-swagger/pull/773): Freeze rack version to 2.0.8 - [@LeFnord](https://github.com/LeFnord). + + +### 0.34.0 (January 11, 2020) + +#### Features + +* [#768](https://github.com/ruby-grape/grape-swagger/pull/768): Uses ruby 2.7, fixes grape to 1.2.5 (cause of dry-types) - [@LeFnord](https://github.com/LeFnord). +* [#761](https://github.com/ruby-grape/grape-swagger/pull/761): Add an option to configure root element for responses - [@bikolya](https://github.com/bikolya). +* [#749](https://github.com/ruby-grape/grape-swagger/pull/749): Drop support for Ruby 2.3 and below - [@LeFnord](https://github.com/LeFnord). + +#### Fixes + +* [#758](https://github.com/ruby-grape/grape-swagger/pull/758): Handle cases where a route's prefix is a nested URL - [@SimonKaluza](https://github.com/simonkaluza). +* [#757](https://github.com/ruby-grape/grape-swagger/pull/757): Fix `array_use_braces` for nested body params - [@bikolya](https://github.com/bikolya). +* [#756](https://github.com/ruby-grape/grape-swagger/pull/756): Fix reference creation when custom type for documentation is provided - [@bikolya](https://github.com/bikolya). +* [#764](https://github.com/ruby-grape/grape-swagger/pull/764): Fix root element for multi-word entities - [@bikolya](https://github.com/bikolya). + + +### 0.33.0 (June 21, 2019) + +#### Fixes + +* [#747](https://github.com/ruby-grape/grape-swagger/pull/747): Allow multiple different success responses - [@charanftp3](https://github.com/charanpanchagnula). +* [#746](https://github.com/ruby-grape/grape-swagger/pull/746): Fix path with optional format - [@fnordfish](https://github.com/fnordfish). +* [#743](https://github.com/ruby-grape/grape-swagger/pull/743): CI: use 2.4.6, 2.5.5 - [@olleolleolle](https://github.com/olleolleolle). +* [#737](https://github.com/ruby-grape/grape-swagger/pull/737): Add swagger endpoint guard to both doc endpoints - [@urkle](https://github.com/urkle). + + +### 0.32.1 (December 7, 2018) + +#### Fixes + +* [#731](https://github.com/ruby-grape/grape-swagger/pull/731): Skip empty parameters and tags arrays - [@fotos](https://github.com/fotos). +* [#729](https://github.com/ruby-grape/grape-swagger/pull/729): Allow empty security array for endpoints - [@fotos](https://github.com/fotos). + + +### 0.32.0 (November 26, 2018) + +#### Features + +* [#717](https://github.com/ruby-grape/grape-swagger/pull/717): Adds support for grape >= 1.2 - [@myxoh](https://github.com/myxoh). + +#### Fixes + +* [#720](https://github.com/ruby-grape/grape-swagger/pull/720): Fix: corrected `termsOfService` field name in additional info - [@dblock](https://github.com/dblock). + + +### 0.31.1 (October 23, 2018) + +#### Features + +* [#710](https://github.com/ruby-grape/grape-swagger/issues/710): Re-implement `api_documentation` and `specific_api_documentation` options - [@dblock](https://github.com/dblock). + + +### 0.31.0 (August 22, 2018) + +#### Features + +* [#622](https://github.com/ruby-grape/grape-swagger/pull/622): Add support for 'brackets' collection format - [@korstiaan](https://github.com/korstiaan). +* [#637](https://github.com/ruby-grape/grape-swagger/pull/637): Add an option to add braces to array params - [@adie](https://github.com/adie). +* [#688](https://github.com/ruby-grape/grape-swagger/pull/688): Use deep merge for nested parameter definitions - [@jdmurphy](https://github.com/jdmurphy). +* [#691](https://github.com/ruby-grape/grape-swagger/pull/691): Disregard order when parsing request params for arrays - [@jdmurphy](https://github.com/jdmurphy). +* [#696](https://github.com/ruby-grape/grape-swagger/pull/696): Delegate required properties parsing to model parsers - [@Bugagazavr](https://github.com/Bugagazavr). + + +### 0.30.1 (July 19, 2018) + +#### Features + +* [#686](https://github.com/ruby-grape/grape-swagger/pull/686): Allow response headers for responses with no content and for files - [@jdmurphy](https://github.com/jdmurphy). + + +### 0.30.0 (July 19, 2018) + +#### Features + +* [#684](https://github.com/ruby-grape/grape-swagger/pull/684): Add response headers - [@jdmurphy](https://github.com/jdmurphy). + +#### Fixes + +* [#681](https://github.com/ruby-grape/grape-swagger/pull/681): Provide error schemas when an endpoint can return a 204 - [@adstratm](https://github.com/adstratm). +* [#683](https://github.com/ruby-grape/grape-swagger/pull/683): Fix handling of arrays of complex entities in params so that valid OpenAPI spec is generated - [@jdmurphy](https://github.com/jdmurphy). + + +### 0.29.0 (May 22, 2018) + +#### Features + +* [#667](https://github.com/ruby-grape/grape-swagger/pull/667): Make route summary optional - [@obduk](https://github.com/obduk). +* [#670](https://github.com/ruby-grape/grape-swagger/pull/670): Add support for deprecated field - [@ioanatia](https://github.com/ioanatia). +* [#675](https://github.com/ruby-grape/grape-swagger/pull/675): Add response examples - [@gamartin](https://github.com/gamartin). + +#### Fixes + +* [#664](https://github.com/ruby-grape/grape-swagger/pull/662): Removed all references to obsolete `hide_format` parameter - [@jonmchan](https://github.com/jonmchan). +* [#669](https://github.com/ruby-grape/grape-swagger/pull/669): Fix handling of http status codes from routes - [@milgner](https://github.com/milgner). +* [#672](https://github.com/ruby-grape/grape-swagger/pull/672): Rename 'notes' to 'detail' in README - [@kjleitz](https://github.com/kjleitz). + + +### 0.28.0 (February 3, 2018) + +#### Features + +* [#622](https://github.com/ruby-grape/grape-swagger/pull/622): Add support for 'brackets' collection format - [@korstiaan](https://github.com/korstiaan). + +#### Fixes + +* [#631](https://github.com/ruby-grape/grape-swagger/pull/631): Fix order of mounts with overrides - [@adie](https://github.com/adie). +* [#267](https://github.com/ruby-grape/grape-swagger/pull/634): Fix mounting APIs in route_param namespaces - [@milgner](https://github.com/milgner), [@wojciechka](https://github.com/wojciechka). +* [#642](https://github.com/ruby-grape/grape-swagger/pull/642): Fix examples link in readme - [@iBublik](https://github.com/iBublik). +* [#641](https://github.com/ruby-grape/grape-swagger/pull/641): Exclude default success code if http_codes define one already - [@anakinj](https://github.com/anakinj). +* [#651](https://github.com/ruby-grape/grape-swagger/pull/651): Apply `values` and `default` of array params to its items - [@yewton](https://github.com/yewton). +* [#654](https://github.com/ruby-grape/grape-swagger/pull/654): Allow setting the consumes for PATCH methods - [@anakinj](https://github.com/anakinj). +* [#656](https://github.com/ruby-grape/grape-swagger/pull/656): Fix `description` field may be null - [@soranoba](https://github.com/soranoba). + + +### 0.27.3 (July 11, 2017) + +#### Features + +* [#613](https://github.com/ruby-grape/grape-swagger/pull/613): Fix Proc with arity one in param values - [@timothysu](https://github.com/timothysu). + +#### Fixes + +* [#616](https://github.com/ruby-grape/grape-swagger/pull/616): Fix swagger to show root path ([#605](https://github.com/ruby-grape/grape-swagger/issue/605)) - [@NightWolf007](https://github.com/NightWolf007). + + +### 0.27.2 (May 11, 2017) + +#### Features + +* [#608](https://github.com/ruby-grape/grape-swagger/pull/608): Support extensions on the root object - [@thogg4](https://github.com/thogg4). +* [#596](https://github.com/ruby-grape/grape-swagger/pull/596): Use route_settings for hidden and operations extensions - [@thogg4](https://github.com/thogg4). +* [#607](https://github.com/ruby-grape/grape-swagger/pull/607): Allow body parameter name to be specified - [@tjwp](https://github.com/tjwp). + + +### 0.27.1 (April 28, 2017) + +#### Features + +* [#602](https://github.com/ruby-grape/grape-swagger/pull/602): Allow security object to be defined - [@markevich](https://github.com/markevich). + + +### 0.27.0 (March 27, 2017) + +#### Features + +* [#583](https://github.com/ruby-grape/grape-swagger/pull/583): Issue #582: document file response - [@LeFnord](https://github.com/LeFnord). +* [#588](https://github.com/ruby-grape/grape-swagger/pull/588): Allow extension keys in Info object - [@mattyr](https://github.com/mattyr). +* [#589](https://github.com/ruby-grape/grape-swagger/pull/589): Allow overriding tag definitions in Info object - [@mattyr](https://github.com/mattyr). + +#### Fixes + +* [#580](https://github.com/ruby-grape/grape-swagger/pull/580): Issue #578: fixes duplicated path params - [@LeFnord](https://github.com/LeFnord). +* [#585](https://github.com/ruby-grape/grape-swagger/pull/585): Issue #584: do not mutate route.path - [@LeFnord](https://github.com/LeFnord). +* [#586](https://github.com/ruby-grape/grape-swagger/pull/586): Issue #587: Parameters delimited by dash cause exception - [@risa](https://github.com/risa). +* [#593](https://github.com/ruby-grape/grape-swagger/pull/593): Clarify hidden option in readme - [@thogg4](https://github.com/thogg4). + + +### 0.26.1 (February 3, 2017) + +#### Features + +* [#567](https://github.com/ruby-grape/grape-swagger/pull/567): Issue#566: removes markdown - [@LeFnord](https://github.com/LeFnord). +* [#568](https://github.com/ruby-grape/grape-swagger/pull/568): Adds code coverage w/ coveralls - [@LeFnord](https://github.com/LeFnord). +* [#570](https://github.com/ruby-grape/grape-swagger/pull/570): Removes dead code -> increases code coverage - [@LeFnord](https://github.com/LeFnord). +* [#576](https://github.com/ruby-grape/grape-swagger/pull/576): Allows custom format, for params and definition properties - [@LeFnord](https://github.com/LeFnord). + +#### Fixes + +* [#562](https://github.com/ruby-grape/grape-swagger/pull/562): The guard method should allow regular object methods as arguments - [@tim-vandecasteele](https://github.com/tim-vandecasteele). +* [#574](https://github.com/ruby-grape/grape-swagger/pull/574): Fixes #572: `is_array` should only be applied to success - [@LeFnord](https://github.com/LeFnord). + + +### 0.26.0 (January 9, 2017) + +#### Features + +* [#558](https://github.com/ruby-grape/grape-swagger/pull/558): Version cascading including dependency updates (includes: [LeFnord#27](https://github.com/LeFnord/grape-swagger/pull/27)) - [@LeFnord](https://github.com/LeFnord). +* [#535](https://github.com/ruby-grape/grape-swagger/pull/535): Add support for grape version cascading - [@qinix](https://github.com/qinix). +* [#560](https://github.com/ruby-grape/grape-swagger/pull/560): Map clearly Grape desc/detail to Swagger summary/description - [@frodrigo](https://github.com/frodrigo). + +#### Fixes + +* [#561](https://github.com/ruby-grape/grape-swagger/pull/561): Rename failures to failure in readme - [@justincampbell](https://github.com/justincampbell). + + +### 0.25.3 (December 18, 2016) + +#### Features + +* [#554](https://github.com/ruby-grape/grape-swagger/pull/554): Updates travis.yml to align with grape - [@LeFnord](https://github.com/LeFnord). + +#### Fixes + +* [#546](https://github.com/ruby-grape/grape-swagger/pull/546): Move development dependencies to Gemfile - [@olleolleolle](https://github.com/olleolleolle). +* [#547](https://github.com/ruby-grape/grape-swagger/pull/547): Use entity_name event if type come from a string - [@frodrigo](https://github.com/frodrigo). +* [#548](https://github.com/ruby-grape/grape-swagger/pull/548): Remove dots from operation id - [@frodrigo](https://github.com/frodrigo). +* [#553](https://github.com/ruby-grape/grape-swagger/pull/553): Align array params for post, put request - addition to [#540](https://github.com/ruby-grape/grape-swagger/pull/540) - [@LeFnord](https://github.com/LeFnord). + + +### 0.25.2 (November 30, 2016) + +#### Fixes + +* [#544](https://github.com/ruby-grape/grape-swagger/pull/544): Fixes #539 and #542; not all of 530 was commited - [@LeFnord](https://github.com/LeFnord). + + +### 0.25.1 (November 29, 2016) + +#### Features + +* [#531](https://github.com/ruby-grape/grape-swagger/pull/531): UUID data_type format support - [@migmartri](https://github.com/migmartri). +* [#534](https://github.com/ruby-grape/grape-swagger/pull/534): Allows to overwrite defaults status codes - [@LeFnord](https://github.com/LeFnord). + +#### Fixes + +* [#540](https://github.com/ruby-grape/grape-swagger/pull/540): Corrects exposing of array in post body - [@LeFnord](https://github.com/LeFnord). +* [#509](https://github.com/ruby-grape/grape-swagger/pull/509), [#529](https://github.com/ruby-grape/grape-swagger/pull/529): Making parent-less routes working - [@mur-wtag](https://github.com/mur-wtag). + + +### 0.25.0 (October 31, 2016) + +#### Features + +* [#524](https://github.com/ruby-grape/grape-swagger/pull/524): Use route tags for global tag set - [@LeFnord](https://github.com/LeFnord). +* [#523](https://github.com/ruby-grape/grape-swagger/pull/523): Allow specifying custom tags at the route level - [@jordanfbrown](https://github.com/jordanfbrown). +* [#520](https://github.com/ruby-grape/grape-swagger/pull/520): Response model can have required attributes - [@WojciechKo](https://github.com/WojciechKo). +* [#510](https://github.com/ruby-grape/grape-swagger/pull/510): Use 'token_owner' instead of 'oauth_token' on Swagger UI endpoint authorization - [@texpert](https://github.com/texpert). + +#### Fixes + +* [#527](https://github.com/ruby-grape/grape-swagger/pull/527): Accepts string as entity - [@LeFnord](https://github.com/LeFnord). +* [#515](https://github.com/ruby-grape/grape-swagger/pull/515): Removes limit on model names - [@LeFnord](https://github.com/LeFnord). +* [#511](https://github.com/ruby-grape/grape-swagger/pull/511): Fix incorrect data type linking for request params of entity types - [@serggl](https://github.com/serggl). + + +### 0.24.0 (September 23, 2016) + +#### Features + +* [#504](https://github.com/ruby-grape/grape-swagger/pull/504): Added support for set the 'collectionFormat' of arrays - [@rczjns](https://github.com/rczjns). +* [#502](https://github.com/ruby-grape/grape-swagger/pull/502): Adds specs for rake tasks - [@LeFnord](https://github.com/LeFnord). +* [#501](https://github.com/ruby-grape/grape-swagger/pull/501): Adds getting of a specified resource for Rake Tasks - [@LeFnord](https://github.com/LeFnord). +* [#500](https://github.com/ruby-grape/grape-swagger/pull/500): Adds Rake tasks to get and validate OAPI/Swagger documentation - [@LeFnord](https://github.com/LeFnord). +* [#493](https://github.com/ruby-grape/grape-swagger/pull/493): Swagger UI endpoint authorization - [@texpert](https://github.com/texpert). +* [#492](https://github.com/ruby-grape/grape/pull/492): Define security requirements on endpoint methods - [@tomregelink](https://github.com/tomregelink). +* [#497](https://github.com/ruby-grape/grape-swagger/pull/497): Use ruby-grape-danger in Dangerfile - [@dblock](https://github.com/dblock). + +#### Fixes + +* [#503](https://github.com/ruby-grape/grape-swagger/pull/503): Corrects exposing of inline definitions - [@LeFnord](https://github.com/LeFnord). +* [#494](https://github.com/ruby-grape/grape-swagger/pull/494): Header parametes are now included in documentation when body parameters have been defined - [@anakinj](https://github.com/anakinj). +* [#505](https://github.com/ruby-grape/grape-swagger/pull/505): Combines namespaces with their mounted paths to allow APIs with specified mount_paths - [@KevinLiddle](https://github.com/KevinLiddle). + + +### 0.23.0 (August 5, 2016) + +#### Features + +* [#491](https://github.com/ruby-grape/grape-swagger/pull/491): Add `ignore_defaults` option - [@pezholio](https://github.com/pezholio). +* [#486](https://github.com/ruby-grape/grape-swagger/pull/486): Use an automated PR linter, [danger.systems](http://danger.systems) - [@dblock](https://github.com/dblock). + +#### Fixes + +* [#489](https://github.com/ruby-grape/grape-swagger/pull/489): Makes version settings/usage more clear; updates `UPGRADE.md`, `README.md` - [@LeFnord](https://github.com/LeFnord). +* [#476](https://github.com/ruby-grape/grape-swagger/pull/476): Fixes for handling the parameter type when body parameters are defined inside desc block - [@anakinj](https://github.com/anakinj). +* [#478](https://github.com/ruby-grape/grape-swagger/pull/478): Refactors building of properties, corrects documentation of array items - [@LeFnord](https://github.com/LeFnord). +* [#479](https://github.com/ruby-grape/grape-swagger/pull/479): Fix regex for Array and Multi Type in doc_methods. Parsing of "[APoint]" should return "APoint" - [@frodrigo](https://github.com/frodrigo). +* [#483](https://github.com/ruby-grape/grape-swagger/pull/483): Added support for nicknamed routes - [@pbendersky](https://github.com/pbendersky). + + +### 0.22.0 (July 12, 2016) + +#### Features + +* [#470](https://github.com/ruby-grape/grape-swagger/pull/470): Document request definitions inline - [@LeFnord](https://github.com/LeFnord). +* [#448](https://github.com/ruby-grape/grape-swagger/pull/448): Header parameters are now prepended to the parameter list - [@anakinj](https://github.com/anakinj). +* [#444](https://github.com/ruby-grape/grape-swagger/pull/444): With multi types parameter the first type is use as the documentation type - [@scauglog](https://github.com/scauglog). +* [#463](https://github.com/ruby-grape/grape-swagger/pull/463): Added 'hidden' option for parameter to be exclude from generated documentation - [@anakinj](https://github.com/anakinj). +* [#471](https://github.com/ruby-grape/grape-swagger/pull/471): Allow Security Definitions Objects to be defined - [@bendodd](https://github.com/bendodd). + +#### Fixes + +* [#472](https://github.com/ruby-grape/grape-swagger/pull/472): Fixes required property for request definitions - [@LeFnord](https://github.com/LeFnord). +* [#467](https://github.com/ruby-grape/grape-swagger/pull/467): Refactors moving of body params - [@LeFnord](https://github.com/LeFnord). +* [#464](https://github.com/ruby-grape/grape-swagger/pull/464): Fixes array params, sets correct type and format for items - [@LeFnord](https://github.com/LeFnord). +* [#461](https://github.com/ruby-grape/grape-swagger/pull/461): Fixes issue by adding extensions to definitions. It appeared, if for the given status code, no definition could be found - [@LeFnord](https://github.com/LeFnord). +* [#455](https://github.com/ruby-grape/grape-swagger/pull/455): Setting `type:` option as `Array[Class]` creates `array` type in JSON - [@tyspring](https://github.com/tyspring). +* [#450](https://github.com/ruby-grape/grape-swagger/pull/438): Do not add :description to definitions if :description is missing on path - [@texpert](https://github.com/texpert). +* [#447](https://github.com/ruby-grape/grape-swagger/pull/447): Version part of the url is now ignored when generating tags for endpoint - [@anakinj](https://github.com/anakinj). +* [#444](https://github.com/ruby-grape/grape-swagger/pull/444): Default value provided in the documentation hash, override the grape default - [@scauglog](https://github.com/scauglog). +* [#443](https://github.com/ruby-grape/grape-swagger/issues/443): Type provided in the documentation hash, override the grape type - [@scauglog](https://github.com/scauglog). +* [#454](https://github.com/ruby-grape/grape-swagger/pull/454): Include documented Hashes in documentation output - [@aschuster3](https://github.com/aschuster3). +* [#457](https://github.com/ruby-grape/grape-swagger/issues/457): Using camel case on namespace throws exception on add_swagger_documentation method - [@rayko](https://github.com/rayko). + + +### 0.21.0 (June 1, 2016) + +#### Features + +* [#413](https://github.com/ruby-grape/grape-swagger/pull/413): Move all model parsing logic to separate gems `grape-swagger-entity` and added representable parser `grape-swagger` - [@Bugagazavr](https://github.com/Bugagazavr). +* [#434](https://github.com/ruby-grape/grape-swagger/pull/434): Add summary to the operation object generator to be more compliant with [OpenAPI v2](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#operation-object) - [@aschuster3](https://github.com/aschuster3). +* [#441](https://github.com/ruby-grape/grape-swagger/pull/441): Accepting `String`, `lambda` and `proc` for `host` and `base_path` - [@LeFnord](https://github.com/LeFnord). + +#### Fixes + +* [#416](https://github.com/ruby-grape/grape-swagger/pull/416): Support recursive models - [@lest](https://github.com/lest). +* [#419](https://github.com/ruby-grape/grape-swagger/pull/419): Replaced github ref to rubygems for external gems - [@Bugagazavr](https://github.com/Bugagazavr). +* [#420](https://github.com/ruby-grape/grape-swagger/pull/420): Raise SwaggerSpec exception if swagger spec isn't satisfied, when no parser for model is registered or response model is empty - [@Bugagazavr](https://github.com/Bugagazavr). +* [#438](https://github.com/ruby-grape/grape-swagger/pull/438): Route version was missing in :options passed to PathString, so Endpoint.path_and_definitions_objects wasn't returning a versioned path when required - [@texpert](https://github.com/texpert). + + +### 0.20.3 (May 9, 2016) + +#### Features + +* [#407](https://github.com/ruby-grape/grape-swagger/issues/407): Added support for Grape 0.15.x and 0.16.x - [@dblock](https://github.com/dblock). +* [#406](https://github.com/ruby-grape/grape-swagger/pull/406): Force usage of entities for response definition [issue #385](https://github.com/ruby-grape/grape-swagger/issues/385) - [@LeFnord](https://github.com/LeFnord). +* [#405](https://github.com/ruby-grape/grape-swagger/pull/405), [#403](https://github.com/ruby-grape/grape-swagger/issues/403): Added version support matrix - [@LeFnord](https://github.com/LeFnord). +* [#408](https://github.com/ruby-grape/grape-swagger/pull/408): Added support for `HEAD` endpoints - [@Bugagazavr](https://github.com/Bugagazavr). +* [#408](https://github.com/ruby-grape/grape-swagger/pull/411): Added support for `OPTIONS` endpoints - [@Bugagazavr](https://github.com/Bugagazavr). + +#### Fixes + +* [#399](https://github.com/ruby-grape/grape-swagger/pull/399), [#395](https://github.com/ruby-grape/grape-swagger/issues/395): Make param description optional - [@LeFnord](https://github.com/LeFnord). + + +### 0.20.2 (April 22, 2016) + +#### Fixes + +* [#394](https://github.com/ruby-grape/grape-swagger/pull/394): Removed overiding default through example - [@LeFnord](https://github.com/LeFnord). +* [#393](https://github.com/ruby-grape/grape-swagger/pull/393): Properly handle header parameters - [@wleeper](https://github.com/wleeper). +* [#389](https://github.com/ruby-grape/grape-swagger/pull/389): Respect X-Forwarded-Host - [@edvakf](https://github.com/edvakf). + + +### 0.20.1 (April 17, 2016) + +#### Features + +* [#382](https://github.com/ruby-grape/grape-swagger/pull/382): Made schemes optional - [@wleeper](https://github.com/wleeper). +* [#381](https://github.com/ruby-grape/grape-swagger/pull/381): Added entity property description when property documentation desc option is present - [@elciok](https://github.com/elciok). + +#### Fixes + +* [#383](https://github.com/ruby-grape/grape-swagger/pull/383): Fixed support for Grape 0.12.0 through 0.14.0 - [@LeFnord](https://github.com/LeFnord). + + +### 0.20.0 (April 9, 2016) + +#### Features + +* [#336](https://github.com/ruby-grape/grape-swagger/pull/336): Added Swagger 2.0 support - [@LeFnord](https://github.com/LeFnord). +* [#371](https://github.com/ruby-grape/grape-swagger/pull/371): Added param type `body` handling - [@LeFnord](https://github.com/LeFnord). +* [#367](https://github.com/ruby-grape/grape-swagger/pull/367): Set default `type: Integer` and `required: true` for path params, if they weren't specified inside the `params` block as required - [@LeFnord](https://github.com/LeFnord). +* [#365](https://github.com/ruby-grape/grape-swagger/pull/365): Fixed passing markdown with redcarpet even with nil description and detail - [@LeFnord](https://github.com/LeFnord). +* [#358](https://github.com/ruby-grape/grape-swagger/pull/358): Removed `allowMultiple` property from params, added `format` to definition property and renamed `defaultValue` to `default` - [@LeFnord](https://github.com/LeFnord). +* [#356](https://github.com/ruby-grape/grape-swagger/pull/356): Added `consumes` - [@LeFnord](https://github.com/LeFnord). +* [#354](https://github.com/ruby-grape/grape-swagger/pull/354): Fixed setting of `base_path` and `host`, added possibility to configure the setting of `version` and `base_path` in documented path and `operationId` - [@LeFnord](https://github.com/LeFnord). +* [#353](https://github.com/ruby-grape/grape-swagger/pull/353), [#352](https://github.com/ruby-grape/grape-swagger/pull/353): Fixed exception with routes having a dynamic `:section` - [@LeFnord](https://github.com/LeFnord). + + +### 0.10.5 (April 12, 2016) + +* [#344](https://github.com/ruby-grape/grape-swagger/pull/344): Namespace based tag included in Swagger JSON - [@LeFnord](https://github.com/LeFnord). + + +### 0.10.2 (August 19, 2015) + +#### Features + +* [#215](https://github.com/ruby-grape/grape-swagger/pull/223): Support swagger `defaultValue` without the need to set a Grape `default` - [@jv-dan](https://github.com/jv-dan). + +#### Fixes + +* [#273](https://github.com/ruby-grape/grape-swagger/pull/273): Fix for hide_format when API class uses a single format with Grape 0.12.0 - [@mattolson](https://github.com/mattolson). +* [#264](https://github.com/ruby-grape/grape-swagger/pull/264): Consistent header param types - [@QuickPay](https://github.com/QuickPay). +* [#260](https://github.com/ruby-grape/grape-swagger/pull/260), [#261](https://github.com/ruby-grape/grape-swagger/pull/261): Fixed endpoints that would wrongly be hidden if `hide_documentation_path` is set - [@QuickPay](https://github.com/QuickPay). +* [#259](https://github.com/ruby-grape/grape-swagger/pull/259): Fixed range values and converting integer :values range to a minimum/maximum numeric Range - [@u2](https://github.com/u2). +* [#252](https://github.com/ruby-grape/grape-swagger/pull/252): Allow docs to mounted in separate class than target - [@iangreenleaf](https://github.com/iangreenleaf). +* [#251](https://github.com/ruby-grape/grape-swagger/pull/251): Fixed model id equal to model name when root existing in entities - [@aitortomas](https://github.com/aitortomas). +* [#232](https://github.com/ruby-grape/grape-swagger/pull/232): Fixed missing raw array params - [@u2](https://github.com/u2). +* [#234](https://github.com/ruby-grape/grape-swagger/pull/234): Fixed range :values with float - [@azhi](https://github.com/azhi). +* [#225](https://github.com/ruby-grape/grape-swagger/pull/225): Fixed `param_type` to have it read from parameter's documentation hash - [@zsxking](https://github.com/zsxking). +* [#235](https://github.com/ruby-grape/grape-swagger/pull/235): Fixed nested entity names in parameters and as `$ref` in models - [@frodrigo](https://github.com/frodrigo). +* [#206](https://github.com/ruby-grape/grape-swagger/pull/206): Fixed 'is_array' in the return entity being ignored - [@igormoochnick](https://github.com/igormoochnick). +* [#266](https://github.com/ruby-grape/grape-swagger/pull/266): Respect primitive mapping on type and format attributes of 1.2 swagger spec - [@frodrigo](https://github.com/frodrigo). +* [#268](https://github.com/ruby-grape/grape-swagger/pull/268): Fixed handling of `type: Array[...]` - [@frodrigo](https://github.com/frodrigo). +* [#284](https://github.com/ruby-grape/grape-swagger/pull/284): Use new params syntax for swagger doc endpoint, fix an issue that `:name` params not recognized by `declared` method - [@calfzhou](https://github.com/calfzhou). +* [#286](https://github.com/ruby-grape/grape-swagger/pull/286): Use `detail` value for `notes` - fix an issue where `detail` value specified in a block passed to `desc` was ignored - [@rngtng](https://github.com/rngtng). + + +### 0.10.1 (March 11, 2015) + +* [#227](https://github.com/ruby-grape/grape-swagger/issues/227): Fix: nested routes under prefix not documented - [@dblock](https://github.com/dblock). +* [#226](https://github.com/ruby-grape/grape-swagger/issues/226): Fix: be defensive with nil exposure types - [@dblock](https://github.com/dblock). + + +### 0.10.0 (March 10, 2015) + +#### Features + +* [#217](https://github.com/ruby-grape/grape-swagger/pull/217): Support Array of entities for proper rendering of grape-entity input dependencies - [@swistaczek](https://github.com/swistaczek). +* [#214](https://github.com/ruby-grape/grape-swagger/pull/214): Allow anything that responds to `call` to be used in `:hidden` - [@zbelzer](https://github.com/zbelzer). +* [#196](https://github.com/ruby-grape/grape-swagger/pull/196): If `:type` is omitted, see if it's available in `:using` - [@jhollinger](https://github.com/jhollinger). +* [#200](https://github.com/ruby-grape/grape-swagger/pull/200): Treat `type: Symbol` as string form parameter - [@ypresto](https://github.com/ypresto). +* [#207](https://github.com/ruby-grape/grape-swagger/pull/207): Support grape `mutually_exclusive` - [@mintuhouse](https://github.com/mintuhouse). +* [#220](https://github.com/ruby-grape/grape-swagger/pull/220): Support standalone appearance of namespace routes with a custom name instead of forced nesting - [@croeck](https://github.com/croeck). + +#### Fixes + +* [#221](https://github.com/ruby-grape/grape-swagger/pull/221): Fixed group parameters' name with type Array - [@u2](https://github.com/u2). +* [#211](https://github.com/ruby-grape/grape-swagger/pull/211): Fixed the dependency, just `require 'grape'` - [@u2](https://github.com/u2). +* [#210](https://github.com/ruby-grape/grape-swagger/pull/210): Fixed the range `:values` option, now exposed as `enum` parameters - [@u2](https://github.com/u2). +* [#208](https://github.com/ruby-grape/grape-swagger/pull/208): Fixed `Float` parameters, exposed as Swagger `float` types - [@u2](https://github.com/u2). +* [#216](https://github.com/ruby-grape/grape-swagger/pull/216), [#192](https://github.com/ruby-grape/grape-swagger/issues/192), [#189](https://github.com/ruby-grape/grape-swagger/issues/189): Fixed API route paths matching for root endpoints with `grape ~> 0.10.0`, specific `format` and `:path` versioning - [@dm1try](https://github.com/dm1try), [@minch](https://github.com/minch). + + +### 0.9.0 (December 19, 2014) + +* [#91](https://github.com/ruby-grape/grape-swagger/issues/91): Fixed empty field for group parameters' name with type hash or Array - [@dukedave](https://github.com/dukedave). +* [#154](https://github.com/ruby-grape/grape-swagger/pull/154): Allow classes for type declarations inside documentation - [@mrmargolis](https://github.com/mrmargolis). +* [#162](https://github.com/ruby-grape/grape-swagger/pull/162): Fix performance issue related to having a large number of models - [@elado](https://github.com/elado). +* [#169](https://github.com/ruby-grape/grape-swagger/pull/169): Test against multiple versions of Grape - [@dblock](https://github.com/dblock). +* [#166](https://github.com/ruby-grape/grape-swagger/pull/166): Ensure compatibility with Grape 0.8.0 or newer - [@dblock](https://github.com/dblock). +* [#174](https://github.com/ruby-grape/grape-swagger/pull/172): Fix problem with using prefix name somewhere in api paths - [@grzesiek](https://github.com/grzesiek). +* [#176](https://github.com/ruby-grape/grape-swagger/pull/176): Added ability to load nested models recursively - [@sergey-verevkin](https://github.com/sergey-verevkin). +* [#179](https://github.com/ruby-grape/grape-swagger/pull/179): Document `Virtus::Attribute::Boolean` as boolean - [@eashman](https://github.com/eashman), [@dblock](https://github.com/dblock). +* [#178](https://github.com/ruby-grape/grape-swagger/issues/178): Fixed `Hash` parameters, now exposed as Swagger `object` types - [@dblock](https://github.com/dblock). +* [#167](https://github.com/ruby-grape/grape-swagger/pull/167): Support mutli-tenanted APIs, don't cache `base_path` - [@bradrobertson](https://github.com/bradrobertson), (https://github.com/dblock). +* [#185](https://github.com/ruby-grape/grape-swagger/pull/185): Support strings in `Grape::Entity.expose`'s `:using` option - [@jhollinger](https://github.com/jhollinger). + + +### 0.8.0 (August 30, 2014) + +#### Features + +* [#139](https://github.com/ruby-grape/grape-swagger/pull/139): Added support for `Rack::Multipart::UploadedFile` parameters - [@timgluz](https://github.com/timgluz). +* [#136](https://github.com/ruby-grape/grape-swagger/pull/136), [#94](https://github.com/ruby-grape/grape-swagger/pull/94): Recurse combination of namespaces when using mounted apps - [@renier](https://github.com/renier). +* [#100](https://github.com/ruby-grape/grape-swagger/pull/100): Added ability to specify a nickname for an endpoint - [@lhorne](https://github.com/lhorne). +* [#94](https://github.com/ruby-grape/grape-swagger/pull/94): Added support for namespace descriptions - [@renier](https://github.com/renier). +* [#110](https://github.com/ruby-grape/grape-swagger/pull/110), [#111](https://github.com/ruby-grape/grape-swagger/pull/111): Added `responseModel` support - [@bagilevi](https://github.com/bagilevi). +* [#114](https://github.com/ruby-grape/grape-swagger/pull/114): Added support for generating nested models from composed Grape Entities - [@dspaeth-faber](https://github.com/dspaeth-faber). +* [#124](https://github.com/ruby-grape/grape-swagger/pull/124): Added ability to change the description and parameters of the API endpoints generated by grape-swagger - [@dblock](https://github.com/dblock). +* [#128](https://github.com/ruby-grape/grape-swagger/pull/128): Combine global models and endpoint entities - [@dspaeth-faber](https://github.com/dspaeth-faber). +* [#132](https://github.com/ruby-grape/grape-swagger/pull/132): Addes support for enum values in entity documentation and form parameters - [@Antek-drzewiecki](https://github.com/Antek-drzewiecki). +* [#142](https://github.com/ruby-grape/grape-swagger/pull/142), [#143](https://github.com/ruby-grape/grape-swagger/pull/143): Added support for kramdown, redcarpet and custom formatters - [@Antek-drzewiecki](https://github.com/Antek-drzewiecki). + +#### Fixes + +* [#105](https://github.com/ruby-grape/grape-swagger/pull/105): Fixed compatibility with Swagger-UI - [@CraigCottingham](https://github.com/CraigCottingham). +* [#87](https://github.com/ruby-grape/grape-swagger/pull/87): Fixed mapping of `default` to `defaultValue` - [@m-o-e](https://github.com/m-o-e). +* [#127](https://github.com/ruby-grape/grape-swagger/pull/127): Fixed `undefined method 'reject' for nil:NilClass` error for an invalid route, now returning 404 Not Found - [@dblock](https://github.com/dblock). +* [#135](https://github.com/ruby-grape/grape-swagger/pull/135): Fixed model inclusion in models with aliased references - [@cdarne](https://github.com/cdarne). + +#### Dev + +* [#126](https://github.com/ruby-grape/grape-swagger/pull/126): Rewritten demo in the `test` folder with CORS enabled - [@dblock](https://github.com/dblock). +* Rewritten .gemspec and removed Jeweler - [@dblock](https://github.com/dblock). +* Added `GrapeSwagger::VERSION` - [@dblock](https://github.com/dblock). +* Added Rubocop, Ruby-style linter - [@dblock](https://github.com/dblock). + + +### 0.7.2 (February 6, 2014) + +* [#84](https://github.com/ruby-grape/grape-swagger/pull/84): Markdown is now Github Flavored Markdown - [@jeromegn](https://github.com/jeromegn). +* [#83](https://github.com/ruby-grape/grape-swagger/pull/83): Improved support for nested Entity types - [@jeromegn](https://github.com/jeromegn). +* [#79](https://github.com/ruby-grape/grape-swagger/pull/79): Added `dataType` to the `params` output - [@Phobos98](https://github.com/Phobos98). +* [#75](https://github.com/ruby-grape/grape-swagger/pull/75), [#82](https://github.com/ruby-grape/grape-swagger/pull/82): Added Swagger 1.2 support - [@joelvh](https://github.com/joelvh), [@jeromegn](https://github.com/jeromegn). +* [#73](https://github.com/ruby-grape/grape-swagger/pull/73): Added the ability to add additional API `info` - [@mattbeedle](https://github.com/mattbeedle). +* [#69](https://github.com/ruby-grape/grape-swagger/pull/69): Make relative `base_path` values absolute - [@dm1try](https://github.com/dm1try). +* [#66](https://github.com/ruby-grape/grape-swagger/pull/66): Fixed documentation generated for paths that don't match the base URL pattern - [@swistaczek](https://github.com/swistaczek). +* [#63](https://github.com/ruby-grape/grape-swagger/pull/63): Added support for hiding endpoints from the documentation - [@arturoherrero](https://github.com/arturoherrero). +* [#62](https://github.com/ruby-grape/grape-swagger/pull/62): Fixed handling of URLs with the `-` character - [@dadario](https://github.com/dadario). +* [#57](https://github.com/ruby-grape/grape-swagger/pull/57): Fixed documenting of multiple API versions - [@Drakula2k](https://github.com/Drakula2k). +* [#58](https://github.com/ruby-grape/grape-swagger/pull/58): Fixed resource groupings for prefixed APIs - [@aew](https://github.com/aew). +* [#56](https://github.com/ruby-grape/grape-swagger/pull/56): Fixed `hide_documentation_path` on prefixed APIs - [@spier](https://github.com/spier). +* [#54](https://github.com/ruby-grape/grape-swagger/pull/54): Adding support for generating swagger `responseClass` and models from Grape Entities - [@calebwoods](https://github.com/calebwoods). +* [#46](https://github.com/ruby-grape/grape-swagger/pull/46): Fixed translating parameter `type` to String, enables using Mongoid fields as parameter definitions - [@dblock](https://github.com/dblock). + + +### 0.6.0 (June 19, 2013) + +* Added Rails 4 support - [@jrhe](https://github.com/jrhe). +* Fix: document APIs at root level - [@dblock](https://github.com/dblock). +* Added support for procs in basepath - [@ruby-grape](https://github.com/ruby-grape). +* Support both `:desc` and `:description` when describing parameters - [@dblock](https://github.com/dblock). +* Fix: allow parameters such as `name[]` - [@dblock](https://github.com/dblock). + + +### 0.5.0 (March 28, 2013) + +* Added Grape 0.5.0 support - [@ruby-grape](https://github.com/ruby-grape). + + +### 0.4.0 (March 28, 2013) + +* Support https - [@cutalion](https://github.com/cutalion). + + +### 0.3.0 (October 19, 2012) + +* Added version support - [@agileanimal](https://github.com/agileanimal), [@fknappe](https://github.com/fknappe). +* Added support for nested parameters - [@ruby-grape](https://github.com/ruby-grape). +* Added basic support for specifying parameters that need to be passed in the header - [@agileanimal](https://github.com/agileanimal). +* Add possibility to hide the documentation paths in the generated swagger documentation - [@ruby-grape](https://github.com/ruby-grape). + + +### 0.2.1 (August 17, 2012) + +* Added support for markdown in notes field - [@ruby-grape](https://github.com/ruby-grape). +* Fix: compatibility with Rails - [@qwert666](https://github.com/qwert666). +* Fix: swagger UI history - [@ruby-grape](https://github.com/ruby-grape). + + +### 0.2.0 (July 27, 2012) + +* Use resource as root for swagger - [@ruby-grape](https://github.com/ruby-grape). +* Added support for file uploads, and proper `paramType` - [@ruby-grape](https://github.com/ruby-grape). +* Added tests - [@nathanvda](https://github.com/nathanvda). + + +### 0.1.0 (July 19, 2012) + +* Added some configurability to the generated documentation - [@ruby-grape](https://github.com/ruby-grape). +* Adapted to rails plugin structure - [@ruby-grape](https://github.com/ruby-grape). +* Allowed cross origin, so swagger can be used from official site - [@ruby-grape](https://github.com/ruby-grape). + + +### 0.0.0 (July 19, 2012) + +* Initial public release - [@ruby-grape](https://github.com/ruby-grape). diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/CONTRIBUTING.md b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/CONTRIBUTING.md new file mode 100644 index 00000000..640eb68d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/CONTRIBUTING.md @@ -0,0 +1,126 @@ +# Contributing to Grape-Swagger + +This project is work of [many contributors](https://github.com/ruby-grape/grape-swagger/graphs/contributors). +You're encouraged to submit [pull requests](https://github.com/ruby-grape/grape-swagger/pulls), +[propose features and discuss issues](https://github.com/ruby-grape/grape-swagger/issues). +When in doubt, ask a question in the [Grape Google Group](http://groups.google.com/group/ruby-grape). + +In the examples below, substitute your Github username for `contributor` in URLs. + +## Fork the Project + +Fork the [project on Github](https://github.com/ruby-grape/grape-swagger) and check out your copy. + +``` +git clone https://github.com/contributor/grape-swagger.git +cd grape-swagger +git remote add upstream https://github.com/ruby-grape/grape-swagger.git +``` + +## Create a Topic Branch + +Make sure your fork is up-to-date and create a topic branch for your feature or bug fix. + +``` +git checkout master +git pull upstream master +git checkout -b my-feature-branch +``` + +## Bundle Install and Test + +Ensure that you can build the project and run tests. + +``` +bundle install +bundle exec rake +``` + +## Write Tests + +Try to write a test that reproduces the problem you're trying to fix or describes a feature that you want to build. +Add to [spec](spec). + +We definitely appreciate pull requests that highlight or reproduce a problem, even without a fix. + +## Write Code + +Implement your feature or bug fix. + +Ruby style is enforced with [RuboCop](https://github.com/bbatsov/rubocop). +Run `bundle exec rubocop` and fix any style issues highlighted. + +Make sure that `bundle exec rake` completes without errors. + +## Write Documentation + +Document any external behavior in the [README](README.md). + +## Update Changelog + +Add a line to [CHANGELOG](CHANGELOG.md) under *Next Release*. +Make it look like every other line, including your name and link to your Github account. + +## Commit Changes + +Make sure git knows your name and email address: + +``` +git config --global user.name "Your Name" +git config --global user.email "contributor@example.com" +``` + +Writing good commit logs is important. A commit log should describe what changed and why. + +``` +git add ... +git commit +``` + +## Push + +``` +git push origin my-feature-branch +``` + +## Make a Pull Request + +Go to https://github.com/contributor/grape-swagger and select your feature branch. +Click the 'Pull Request' button and fill out the form. Pull requests are usually reviewed within a few days. + +## Rebase + +If you've been working on a change for a while, rebase with upstream/master. + +``` +git fetch upstream +git rebase upstream/master +git push origin my-feature-branch -f +``` + +## Update CHANGELOG Again + +Update the [CHANGELOG](CHANGELOG.md) with the pull request number. A typical entry looks as follows. + +``` +* [#123](https://github.com/ruby-grape/grape-swagger/pull/123): Reticulated splines - [@contributor](https://github.com/contributor). +``` + +Amend your previous commit and force push the changes. + +``` +git commit --amend +git push origin my-feature-branch -f +``` + +## Check on Your Pull Request + +Go back to your pull request after a few minutes and see whether it passed muster with GitHub Actions. Everything should look green, otherwise fix issues and amend your commit as described above. + +## Be Patient + +It's likely that your change will not be merged and that the nitpicky maintainers will ask you to do more, or fix seemingly benign problems. Hang on there! + +## Thank You + +Please do know that we really appreciate and value your time and work. We love you, really. diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/LICENSE.txt b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/LICENSE.txt new file mode 100644 index 00000000..cd001c7c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2012-2016 Tim Vandecasteele, ruby-grape and Contributors + +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 AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/README.md b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/README.md new file mode 100644 index 00000000..6b4bbbf0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/README.md @@ -0,0 +1,1811 @@ +[![Gem Version](https://badge.fury.io/rb/grape-swagger.svg)](http://badge.fury.io/rb/grape-swagger) +[![Build Status](https://travis-ci.org/ruby-grape/grape-swagger.svg?branch=master)](https://travis-ci.org/ruby-grape/grape-swagger) +[![Coverage Status](https://coveralls.io/repos/github/ruby-grape/grape-swagger/badge.svg?branch=master)](https://coveralls.io/github/ruby-grape/grape-swagger?branch=master) +[![Code Climate](https://codeclimate.com/github/ruby-grape/grape-swagger.svg)](https://codeclimate.com/github/ruby-grape/grape-swagger) + +##### Table of Contents + +* [What is grape-swagger?](#what) +* [Related Projects](#related) +* [Compatibility](#version) +* [Swagger-Spec](#swagger-spec) +* [Installation](#install) +* [Usage](#usage) +* [Model Parsers](#model_parsers) +* [Configure](#configure) +* [Routes Configuration](#routes) +* [Using Grape Entities](#grape-entity) +* [Securing the Swagger UI](#oauth) +* [Example](#example) +* [Rake Tasks](#rake) + + +## What is grape-swagger? + +The grape-swagger gem provides an autogenerated documentation for your [Grape](https://github.com/ruby-grape/grape) API. The generated documentation is Swagger-compliant, meaning it can easily be discovered in [Swagger UI](https://github.com/swagger-api/swagger-ui). You should be able to point [the petstore demo](http://petstore.swagger.io/) to your API. + +![Demo Screenshot](example/swagger-example.png) + +This screenshot is based on the [Hussars](https://github.com/LeFnord/hussars) sample app. + + +## Related Projects + +* [Grape](https://github.com/ruby-grape/grape) +* [Grape Swagger Entity](https://github.com/ruby-grape/grape-swagger-entity) + * [Grape Entity](https://github.com/ruby-grape/grape-entity) +* [Grape Swagger Representable](https://github.com/ruby-grape/grape-swagger-representable) +* [Swagger UI](https://github.com/swagger-api/swagger-ui) + + + +## Compatibility + +The following versions of grape, grape-entity and grape-swagger can currently be used together. + +| grape-swagger | swagger spec | grape | grape-entity | representable | +| ------------------ | ------------ | ----------------------- | ------------ | ------------- | +| 0.10.5 | 1.2 | >= 0.10.0 ... <= 0.14.0 | < 0.5.0 | n/a | +| 0.11.0 | 1.2 | >= 0.16.2 | < 0.5.0 | n/a | +| 0.25.2 | 2.0 | >= 0.14.0 ... <= 0.18.0 | <= 0.6.0 | >= 2.4.1 | +| 0.26.0 | 2.0 | >= 0.16.2 ... <= 1.1.0 | <= 0.6.1 | >= 2.4.1 | +| 0.27.0 | 2.0 | >= 0.16.2 ... <= 1.1.0 | >= 0.5.0 | >= 2.4.1 | +| 0.32.0 | 2.0 | >= 0.16.2 | >= 0.5.0 | >= 2.4.1 | +| 0.34.0 | 2.0 | >= 0.16.2 ... < 1.3.0 | >= 0.5.0 | >= 2.4.1 | +| >= 1.0.0 | 2.0 | >= 1.3.0 | >= 0.5.0 | >= 2.4.1 | +| >= 2.0.0 | 2.0 | >= 1.7.0 | >= 0.5.0 | >= 2.4.1 | +| >= 2.0.0 ... < 2.2 | 2.0 | >= 1.8.0 ... < 2.3.0 | >= 0.5.0 | >= 2.4.1 | + + +## Swagger-Spec + +Grape-swagger generates documentation per [Swagger / OpenAPI Spec 2.0](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md). + + + + +## Installation + +Add to your Gemfile: + +```ruby +gem 'grape-swagger' +``` + +## Upgrade + +Please see [UPGRADING](UPGRADING.md) when upgrading from a previous version. + + + +## Usage + +Mount all your different APIs (with `Grape::API` superclass) on a root node. In the root class definition, include `add_swagger_documentation`, this sets up the system and registers the documentation on '/swagger_doc'. See [example/config.ru](example/config.ru) for a simple demo. + + +```ruby +require 'grape-swagger' + +module API + class Root < Grape::API + format :json + mount API::Cats + mount API::Dogs + mount API::Pirates + add_swagger_documentation + end +end +``` + +To explore your API, either download [Swagger UI](https://github.com/swagger-api/swagger-ui) and set it up yourself or go to the [online swagger demo](http://petstore.swagger.io/) and enter your localhost url documentation root in the url field (probably something in the line of http://localhost:3000/swagger_doc). + + + +## Model Parsers + +Since 0.21.0, `Grape::Entity` is not a part of grape-swagger, you need to add `grape-swagger-entity` manually to your Gemfile. +Also added support for [representable](https://github.com/trailblazer/representable) via `grape-swagger-representable`. + +```ruby +# For Grape::Entity ( https://github.com/ruby-grape/grape-entity ) +gem 'grape-swagger-entity', '~> 0.3' +# For representable ( https://github.com/apotonick/representable ) +gem 'grape-swagger-representable', '~> 0.2' +``` + +If you are not using Rails, make sure to load the parser inside your application initialization logic, e.g., via `require 'grape-swagger/entity'` or `require 'grape-swagger/representable'`. + +### Custom Model Parsers + +You can create your own model parser, for example for [roar](https://github.com/trailblazer/roar). + +```ruby +module GrapeSwagger + module Roar + class Parser + attr_reader :model + attr_reader :endpoint + + def initialize(model, endpoint) + @model = model + @endpoint = endpoint + end + + def call + # Parse your model and return hash with model schema for swagger + end + end + end +end +``` + +Then you should register your custom parser. + +```ruby +GrapeSwagger.model_parsers.register(GrapeSwagger::Roar::Parser, Roar::Decorator) +``` + +To control model parsers sequence, you can insert your parser before or after another parser. + +#### insert_before + +```ruby +GrapeSwagger.model_parsers.insert_before(GrapeSwagger::Representable::Parser, GrapeSwagger::Roar::Parser, Roar::Decorator) +``` + +#### insert_after + +```ruby +GrapeSwagger.model_parsers.insert_after(GrapeSwagger::Roar::Parser, GrapeSwagger::Representable::Parser, Representable::Decorator) +``` + +As we know, `Roar::Decorator` uses `Representable::Decorator` as a superclass, this allows to avoid a problem when Roar objects are processed by `GrapeSwagger::Representable::Parser` instead of `GrapeSwagger::Roar::Parser`. + + +### CORS + +If you use the online demo, make sure your API supports foreign requests by enabling CORS in Grape, otherwise you'll see the API description, but requests on the API won't return. Use [rack-cors](https://github.com/cyu/rack-cors) to enable CORS. + +```ruby +require 'rack/cors' +use Rack::Cors do + allow do + origins '*' + resource '*', headers: :any, methods: [ :get, :post, :put, :delete, :options ] + end +end +``` + +Alternatively you can set CORS headers in a Grape `before` block. + +```ruby +before do + header['Access-Control-Allow-Origin'] = '*' + header['Access-Control-Request-Method'] = '*' +end +``` + + + +## Configure + +* [host](#host) +* [base_path](#base_path) +* [mount_path](#mount_path) +* [add_base_path](#add_base_path) +* [add_root](#add_root) +* [add_version](#add_version) +* [doc_version](#doc_version) +* [endpoint_auth_wrapper](#endpoint_auth_wrapper) +* [swagger_endpoint_guard](#swagger_endpoint_guard) +* [token_owner](#token_owner) +* [security_definitions](#security_definitions) +* [security](#security) +* [models](#models) +* [tags](#tags) +* [hide_documentation_path](#hide_documentation_path) +* [info](#info) +* [array_use_braces](#array_use_braces) +* [api_documentation](#api_documentation) +* [specific_api_documentation](#specific_api_documentation) +* [consumes](#consumes) +* [produces](#produces) + +You can pass a hash with optional configuration settings to ```add_swagger_documentation```. +The examples show the default value. + + +The `host` and `base_path` options also accept a `proc` or a `lambda` to evaluate, which is passed a [request](http://www.rubydoc.info/github/rack/rack/Rack/Request) object: + +```ruby +add_swagger_documentation \ + base_path: proc { |request| request.host =~ /^example/ ? '/api-example' : '/api' } +``` + + +#### host: +Sets explicit the `host`, default would be taken from `request`. +```ruby +add_swagger_documentation \ + host: 'www.example.com' +``` + + +#### base_path: +Base path of the API that's being exposed, default would be taken from `request`. +```ruby +add_swagger_documentation \ + base_path: nil +``` + +`host` and `base_path` are also accepting a `proc` or `lambda` + + +#### mount_path: +The path where the API documentation is loaded, default is: `/swagger_doc`. +```ruby +add_swagger_documentation \ + mount_path: '/swagger_doc' +``` + +#### add_base_path: +Add `basePath` key to the documented path keys, default is: `false`. +```ruby +add_swagger_documentation \ + add_base_path: true # only if base_path given +``` + +#### add_root: +Add root element to all the responses, default is: `false`. +```ruby +add_swagger_documentation \ + add_root: true +``` + +#### add_version: + +Add `version` key to the documented path keys, default is: `true`, +here the version is the API version, specified by `grape` in [`path`](https://github.com/ruby-grape/grape/#path) + +```ruby +add_swagger_documentation \ + add_version: true +``` + + +#### doc_version: + +Specify the version of the documentation at [info section](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#info-object), default is: `'0.0.1'` +```ruby +add_swagger_documentation \ + doc_version: '0.0.1' +``` + + +#### endpoint_auth_wrapper: + +Specify the middleware to use for securing endpoints. + +```ruby +add_swagger_documentation \ + endpoint_auth_wrapper: WineBouncer::OAuth2 +``` + + +#### swagger_endpoint_guard: +Specify the method and auth scopes, used by the middleware for securing endpoints. + +```ruby +add_swagger_documentation \ + swagger_endpoint_guard: 'oauth2 false' +``` + + +#### token_owner: +Specify the token_owner method, provided by the middleware, which is typically named 'resource_owner'. + +```ruby +add_swagger_documentation \ + token_owner: 'resource_owner' +``` + + +#### security_definitions: +Specify the [Security Definitions Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#security-definitions-object) + +_NOTE: [Swagger-UI is supporting only implicit flow yet](https://github.com/swagger-api/swagger-ui/issues/2406#issuecomment-248651879)_ + +```ruby +add_swagger_documentation \ + security_definitions: { + api_key: { + type: "apiKey", + name: "api_key", + in: "header" + } + } +``` + +#### security: + +Specify the [Security Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#securityRequirementObject) + +```ruby +add_swagger_documentation \ + security: [ + { + api_key: [] + } + ] +``` + + +#### models: +A list of entities to document. Combine with the [grape-entity](https://github.com/ruby-grape/grape-entity) gem. + +These would be added to the definitions section of the swagger file. + +```ruby +add_swagger_documentation \ + models: [ + TheApi::Entities::UseResponse, + TheApi::Entities::ApiError + ] +``` + + +#### tags: + +A list of tags to document. By default tags are automatically generated +for endpoints based on route names. + +```ruby +add_swagger_documentation \ + tags: [ + { name: 'widgets', description: 'A description of widgets' } + ] +``` + + +#### hide_documentation_path: (default: `true`) + +```ruby +add_swagger_documentation \ + hide_documentation_path: true +``` + +Don't show the `/swagger_doc` path in the generated swagger documentation. + + +#### info: + +```ruby +add_swagger_documentation \ + info: { + title: "The API title to be displayed on the API homepage.", + description: "A description of the API.", + contact_name: "Contact name", + contact_email: "Contact@email.com", + contact_url: "Contact URL", + license: "The name of the license.", + license_url: "www.The-URL-of-the-license.org", + terms_of_service_url: "www.The-URL-of-the-terms-and-service.com", + } +``` + +A hash merged into the `info` key of the JSON documentation. + +#### array_use_braces: + +```ruby +add_swagger_documentation \ + array_use_braces: true +``` + This setting must be `true` in order for params defined as an `Array` type to submit each element properly. + ```ruby +params do + optional :metadata, type: Array[String] +end +``` + with `array_use_braces: true`: +``` +metadata[]: { "name": "Asset ID", "value": "12345" } +metadata[]: { "name": "Asset Tag", "value": "654321"} +``` + with `array_use_braces: false`: +``` +metadata: {"name": "Asset ID", "value": "123456"} +metadata: {"name": "Asset Tag", "value": "654321"} +``` + +#### api_documentation + +Customize the Swagger API documentation route, typically contains a `desc` field. The default description is "Swagger compatible API description". + +```ruby +add_swagger_documentation \ + api_documentation: { desc: 'Reticulated splines API swagger-compatible documentation.' } +``` + +#### specific_api_documentation + +Customize the Swagger API specific documentation route, typically contains a `desc` field. The default description is "Swagger compatible API description for specific API". + +```ruby +add_swagger_documentation \ + specific_api_documentation: { desc: 'Reticulated splines API swagger-compatible endpoint documentation.' } +``` + +#### consumes + +Customize the Swagger API default global `consumes` field value. + +```ruby +add_swagger_documentation \ + consumes: ['application/json', 'application/x-www-form-urlencoded'] +``` + +#### produces + +Customize the Swagger API default global `produces` field value. + +```ruby +add_swagger_documentation \ + produces: ['text/plain'] +``` + +## Routes Configuration + +* [Swagger Header Parameters](#headers) +* [Hiding an Endpoint](#hiding) +* [Overriding Auto-Generated Nicknames](#overriding-auto-generated-nicknames) +* [Specify endpoint details](#details) +* [Overriding the route summary](#summary) +* [Overriding the tags](#overriding_the_tags) +* [Deprecating routes](#deprecating-routes) +* [Overriding the name of the body parameter](#body-param) +* [Defining an endpoint as an array](#array) +* [Using an options hash](#options) +* [Overriding parameter type](#overriding-param-type) +* [Overriding data type of the parameter](#overriding-type-of-param) +* [Multiple types](#multiple-types) +* [Array of data type](#array-type) +* [Collection Format](#collection-format) +* [Hiding parameters](#hiding-parameters) +* [Setting a Swagger default value](#default-value) +* [Setting `additionalProperties` for `object`-type parameters](#additional-properties) +* [Example parameter value](#param-example) +* [Response documentation](#response) +* [Changing default status codes](#change-status) +* [File response](#file-response) +* [Extensions](#extensions) +* [Response examples documentation](#response-examples) +* [Response headers documentation](#response-headers) +* [Adding root element to responses](#response-root) +* [Multiple present Response](#multiple-response) + +#### Swagger Header Parameters + +Swagger also supports the documentation of parameters passed in the header. Since grape's ```params[]``` doesn't return header parameters we can specify header parameters separately in a block after the description. + +```ruby +desc "Return super-secret information", { + headers: { + "XAuthToken" => { + description: "Valdates your identity", + required: true + }, + "XOptionalHeader" => { + description: "Not really needed", + required: false + } + } +} +``` + + +#### Hiding an Endpoint + +You can hide an endpoint by adding ```hidden: true``` in the description of the endpoint: + +```ruby +desc 'Hide this endpoint', hidden: true +``` + +Or by adding ```hidden: true``` on the verb method of the endpoint, such as `get`, `post` and `put`: + +```ruby +get '/kittens', hidden: true do +``` + +Or by using a route setting: + +```ruby +route_setting :swagger, { hidden: true } +get '/kittens' do +``` + +Endpoints can be conditionally hidden by providing a callable object such as a lambda which evaluates to the desired +state: + +```ruby +desc 'Conditionally hide this endpoint', hidden: lambda { ENV['EXPERIMENTAL'] != 'true' } +``` + + +#### Overriding Auto-Generated Nicknames + +You can specify a swagger nickname to use instead of the auto generated name by adding `:nickname 'string'` in the description of the endpoint. + +```ruby +desc 'Get a full list of pets', nickname: 'getAllPets' +``` + + +#### Specify endpoint details + +To specify further details for an endpoint, use the `detail` option within a block passed to `desc`: + +```ruby +desc 'Get all kittens!' do + detail 'this will expose all the kittens' +end +get '/kittens' do +``` + + +#### Overriding the route summary + +To override the summary, add `summary: '[string]'` after the description. + +```ruby +namespace 'order' do + desc 'This will be your summary', + summary: 'Now this is your summary!' + get :order_id do + ... + end +end +``` + + +#### Overriding the tags + +Tags are used for logical grouping of operations by resources or any other qualifier. To override the +tags array, add `tags: ['tag1', 'tag2']` after the description. + +```ruby +namespace 'order' do + desc 'This will be your summary', tags: ['orders'] + get :order_id do + ... + end +end +``` + + +#### Deprecating routes + +To deprecate a route add `deprecated: true` after the description. + +```ruby +namespace 'order' do + desc 'This is a deprecated route', deprecated: true + get :order_id do + ... + end +end +``` + + +#### Overriding the name of the body parameter + +By default, body parameters have a generated name based on the operation. For +deeply nested resources, this name can get very long. To override the name of +body parameter add `body_name: 'post_body'` after the description. + +```ruby +namespace 'order' do + desc 'Create an order', body_name: 'post_body' + post do + ... + end +end +``` + + +#### Defining an endpoint as an array + +You can define an endpoint as an array by adding `is_array` in the description: + +```ruby +desc 'Get a full list of pets', is_array: true +``` + + +#### Using an options hash + +The Grape DSL supports either an options hash or a restricted block to pass settings. Passing the `nickname`, `hidden` and `is_array` options together with response codes is only possible when passing an options hash. +Since the syntax differs you'll need to adjust it accordingly: + +```ruby +desc 'Get all kittens!', { + hidden: true, + is_array: true, + nickname: 'getKittens', + success: Entities::Kitten, # or success + failure: [[401, 'KittenBitesError', Entities::BadKitten]] # or failure + # also explicit as hash: [{ code: 401, message: 'KittenBitesError', model: Entities::BadKitten }] + produces: [ "array", "of", "mime_types" ], + consumes: [ "array", "of", "mime_types" ] + } +get '/kittens' do +``` + + +#### Overriding parameter type + +You can override paramType, using the documentation hash. See [parameter object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#parameter-object) for available types. + +```ruby +params do + requires :action, type: Symbol, values: [:PAUSE, :RESUME, :STOP], documentation: { param_type: 'query' } +end +post :act do + ... +end +``` + + +#### Overriding data type of the parameter + +You can override type, using the documentation hash. + +```ruby +params do + requires :input, type: String, documentation: { type: 'integer' } +end +post :act do + ... +end +``` + +```json +{ + "in": "formData", + "name": "input", + "type": "integer", + "format": "int32", + "required": true +} +``` + + +#### Multiple types + +By default when you set multiple types, the first type is selected as swagger type + +```ruby +params do + requires :action, types: [String, Integer] +end +post :act do + ... +end +``` + +```json +{ + "in": "formData", + "name": "action", + "type": "string", + "required": true +} +``` + + +#### Array of data type + +Array types are also supported. + +```ruby +params do + requires :action_ids, type: Array[Integer] +end +post :act do + ... +end +``` + +```json +{ + "in": "formData", + "name": "action_ids", + "type": "array", + "items": { + "type": "integer" + }, + "required": true +} +``` + + +#### Collection format of arrays + +You can set the collection format of an array, using the documentation hash. + +Collection format determines the format of the array if type array is used. Possible values are: +* csv - comma separated values foo,bar. +* ssv - space separated values foo bar. +* tsv - tab separated values foo\tbar. +* pipes - pipe separated values foo|bar. +* multi - corresponds to multiple parameter instances instead of multiple values for a single instance foo=bar&foo=baz. This is valid only for parameters in "query" or "formData". + +```ruby +params do + requires :statuses, type: Array[String], documentation: { collectionFormat: 'multi' } +end +post :act do + ... +end +``` + +```json +{ + "in": "formData", + "name": "statuses", + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "required": true +} +``` + + +#### Hiding parameters + +Exclude single optional parameter from the documentation + +```ruby +not_admins = lambda { |token_owner = nil| token_owner.nil? || !token_owner.admin? } + +params do + optional :one, documentation: { hidden: true } + optional :two, documentation: { hidden: -> { |t=nil| true } } + optional :three, documentation: { hidden: not_admins } +end +post :act do + ... +end +``` + + +#### Setting a Swagger default value + +Grape allows for an additional documentation hash to be passed to a parameter. + +```ruby +params do + requires :id, type: Integer, desc: 'Coffee ID' + requires :temperature, type: Integer, desc: 'Temperature of the coffee in celcius', documentation: { default: 72 } +end +``` + +Grape uses the option `default` to set a default value for optional parameters. This is different in that Grape will set your parameter to the provided default if the parameter is omitted, whereas the example value above will only set the value in the UI itself. This will set the Swagger `defaultValue` to the provided value. Note that the example value will override the Grape default value. + +```ruby +params do + requires :id, type: Integer, desc: 'Coffee ID' + optional :temperature, type: Integer, desc: 'Temperature of the coffee in celcius', default: 72 +end +``` + +### Setting `additionalProperties` for `object`-type parameters + +Use the `additional_properties` option in the `documentation` hash for `object`-type parameters to set [`additionalProperties`](https://swagger.io/specification/v2/#model-with-mapdictionary-properties). + +#### Allow any additional properties +```ruby +params do + optional :thing, type: Hash, documentation: { additional_properties: true } +end +``` + +#### Allow any additional properties of a particular type +```ruby +params do + optional :thing, type: Hash, documentation: { additional_properties: String } +end +``` + +#### Allow any additional properties matching a defined schema +```ruby +class Entity < Grape::Entity + expose :this +end + +params do + optional :thing, type: Hash, documentation: { additional_properties: Entity } +end +``` + + +#### Example parameter value + +The example parameter will populate the Swagger UI with the example value, and can be used for optional or required parameters. + +```ruby +params do + requires :id, type: Integer, documentation: { example: 123 } + optional :name, type: String, documentation: { example: 'Buddy Guy' } +end +``` + +#### Expose nested namespace as standalone route + +Use the `nested: false` property in the `swagger` option to make nested namespaces appear as standalone resources. +This option can help to structure and keep the swagger schema simple. + +```ruby +namespace 'store/order', desc: 'Order operations within a store', swagger: { nested: false } do + get :order_id do + ... + end +end +``` + +All routes that belong to this namespace (here: the `GET /order_id`) will then be assigned to the `store_order` route instead of the `store` resource route. + +It is also possible to expose a namespace within another already exposed namespace: + +```ruby +namespace 'store/order', desc: 'Order operations within a store', swagger: { nested: false } do + get :order_id do + ... + end + namespace 'actions', desc: 'Order actions', nested: false do + get 'evaluate' do + ... + end + end +end +``` +Here, the `GET /order_id` appears as operation of the `store_order` resource and the `GET /evaluate` as operation of the `store_orders_actions` route. + + +##### With a custom name + +Auto generated names for the standalone version of complex nested resource do not have a nice look. +You can set a custom name with the `name` property inside the `swagger` option, but only if the namespace gets exposed as standalone route. +The name should not contain whitespaces or any other special characters due to further issues within swagger-ui. + +```ruby +namespace 'store/order', desc: 'Order operations within a store', swagger: { nested: false, name: 'Store-orders' } do + get :order_id do + ... + end +end +``` + + +#### Response documentation + +You can also document the HTTP status codes with a description and a specified model, as ref in the schema to the definitions, that your API returns with one of the following syntax. + +In the following cases, the schema ref would be taken from route. + +```ruby +desc 'thing', failure: [ { code: 400, message: 'Invalid parameter entry' } ] +get '/thing' do + # ... +end +``` + +```ruby +desc 'thing' do + params Entities::Something.documentation + failure [ { code: 400, message: 'Invalid parameter entry' } ] +end +get '/thing' do + # ... +end +``` + +```ruby +get '/thing', failure: [ + { code: 400, message: 'Invalid parameter entry' }, + { code: 404, message: 'Not authorized' }, +] do + # ... +end +``` + +By adding a `model` key, e.g. this would be taken. Setting an empty string will act like an empty body. +```ruby +get '/thing', failure: [ + { code: 400, message: 'General error' }, + { code: 403, message: 'Forbidden error', model: '' }, + { code: 422, message: 'Invalid parameter entry', model: Entities::ApiError } +] do + # ... +end +``` +If no status code is defined [defaults](/lib/grape-swagger/endpoint.rb#L210) would be taken. + +The result is then something like following: + +```json +"responses": { + "200": { + "description": "get Horses", + "schema": { + "$ref": "#/definitions/Thing" + } + }, + "401": { + "description": "HorsesOutError", + "schema": { + "$ref": "#/definitions/ApiError" + } + } +}, +``` + + +#### Changing default status codes + + +The default status codes, one could be found (-> [status codes](lib/grape-swagger/doc_methods/status_codes.rb)) can be changed to your specific needs, to achieve it, you have to change it for grape itself and for the documentation. + +```ruby +desc 'Get a list of stuff', + success: { code: 202, model: Entities::UseResponse, message: 'a changed status code' } +get do + status 202 + # your code comes here +end +``` + +```json +"responses": { + "202": { + "description": "ok", + "schema": { + "$ref": "#/definitions/UseResponse" + } + } +}, +``` + +#### Multiple status codes for response + +Multiple values can be provided for `success` and `failure` attributes in the response. + +```ruby +desc 'Attach a field to an entity through a PUT', + success: [ + { code: 201, model: Entities::UseResponse, message: 'Successfully created' }, + { code: 204, message: 'Already exists' } + ], + failure: [ + { code: 400, message: 'Bad request' }, + { code: 404, message: 'Not found' } + ] +put do + # your code comes here +end +``` + +```json +"responses": { + "201": { + "description": "Successfully created", + "schema": { + "$ref": "#/definitions/UseResponse" + } + }, + "204": { + "description": "Already exists" + }, + "400": { + "description": "Bad request" + }, + "404": { + "description": "Not found" + } +}, +``` + + +#### File response + +Setting `success` to `File` sets a default `produces` of `application/octet-stream`. + +```ruby +desc 'Get a file', + success: File +get do + # your file response +end +``` + +```json +"produces": [ + "application/octet-stream" +], +"responses": { + "200": { + "description": "Get a file", + "schema": { + "type": "file" + } + } +} +``` + +#### Default response + +By setting the `default` option you can also define a default response that is the result returned for all unspecified status codes. +The definition supports the same syntax as `success` or `failure`. + +In the following cases, the schema ref would be taken from route. + +```ruby +desc 'thing', default: { message: 'the default response' } +get '/thing' do + # ... +end +``` +The generated swagger section will be something like + +```json +"responses": { + "default": { + "description": "the default response" + } +}, +``` +Just like with `success` or `failure` you can also provide a `model` parameter. + +```ruby +desc 'Get a list of stuff', + default: { model: Entities::UseResponse, message: 'the default response' } +get do + # your code comes here +end +``` +The generated swagger document will then correctly reference the model schema. + +```json +"responses": { + "default": { + "description": "the default response", + "schema": { + "$ref": "#/definitions/UseResponse" + } + } +}, +``` + + +#### Extensions + +Swagger spec2.0 supports extensions on different levels, for the moment, +the documentation on the root level object and the `info`, `verb`, `path` and `definition` levels are supported. + +The documented key would be generated from the `x` + `-` + key of the submitted hash, +for possibilities refer to the [extensions spec](spec/lib/extensions_spec.rb). +To get an overview *how* the extensions would be defined on grape level, see the following examples: + +- root object extension, add a `x` key to the root hash when calling ```add_swagger_documentation```: +```ruby + add_swagger_documentation \ + x: { + some: 'stuff' + }, + info: { + } +``` +this would generate: +```json +{ + "x-some": "stuff", + "info":{ + } +} +``` + +- `info` extension, add a `x` key to the `info` hash when calling ```add_swagger_documentation```: +```ruby + add_swagger_documentation \ + info: { + x: { some: 'stuff' } + } +``` +this would generate: +```json +"info":{ + "x-some":"stuff" +} +``` + +- `verb` extension, add a `x` key to the `desc` hash: +```ruby +desc 'This returns something with extension on verb level', + x: { some: 'stuff' } +``` +this would generate: +```json +"/path":{ + "get":{ + "…":"…", + "x-some":"stuff" + } +} +``` + +- `operation` extension, by setting via route settings:: +```ruby +route_setting :x_operation, { some: 'stuff' } +``` +this would generate: +```json +"/path":{ + "get":{ + "…":"…", + "x-some":"stuff" + } +} +``` + +- `path` extension, by setting via route settings: +```ruby +route_setting :x_path, { some: 'stuff' } +``` +this would generate: +```json +"/path":{ + "x-some":"stuff", + "get":{ + "…":"…", + } +} +``` + +- `definition` extension, again by setting via route settings, +here the status code must be provided, for which definition the extensions should be: +```ruby +route_setting :x_def, { for: 422, other: 'stuff' } +``` +this would generate: +```json +"/definitions":{ + "ApiError":{ + "x-other":"stuff", + "…":"…", + } +} +``` +or, for more definitions: +```ruby +route_setting :x_def, [{ for: 422, other: 'stuff' }, { for: 200, some: 'stuff' }] +``` + +- `params` extension, add a `x` key to the `documentation` hash : +```ruby +requires :foo, type: String, documentation: { x: { some: 'stuff' } } +``` +this would generate: +```json +{ + "in": "formData", + "name": "foo", + "type": "string", + "required": true, + "x-some": "stuff" +} +``` + +#### Response examples documentation + +You can also add examples to your responses by using the `desc` DSL with block syntax. + +By specifying examples to `success` and `failure`. + +```ruby +desc 'This returns examples' do + success model: Thing, examples: { 'application/json' => { description: 'Names list', items: [{ id: '123', name: 'John' }] } } + failure [[404, 'NotFound', ApiError, { 'application/json' => { code: 404, message: 'Not found' } }]] +end +get '/thing' do + ... +end +``` + +The result will look like following: + +```json + "responses": { + "200": { + "description": "This returns examples", + "schema": { + "$ref": "#/definitions/Thing" + }, + "examples": { + "application/json": { + "description": "Names list", + "items": [ + { + "id": "123", + "name": "John" + } + ] + } + } + }, + "404": { + "description": "NotFound", + "schema": { + "$ref": "#/definitions/ApiError" + }, + "examples": { + "application/json": { + "code": 404, + "message": "Not found" + } + } + } + } +``` + +Failure information can be passed as an array of arrays or an array of hashes. + +#### Response headers documentation + +You can also add header information to your responses by using the `desc` DSL with block syntax. + +By specifying headers to `success` and `failure`. + +```ruby +desc 'This returns headers' do + success model: Thing, headers: { 'Location' => { description: 'Location of resource', type: 'string' } } + failure [[404, 'NotFound', ApiError, { 'application/json' => { code: 404, message: 'Not found' } }, { 'Date' => { description: 'Date of failure', type: 'string' } }]] +end +get '/thing' do + ... +end +``` + +The result will look like following: + +```json + "responses": { + "200": { + "description": "This returns examples", + "schema": { + "$ref": "#/definitions/Thing" + }, + "headers": { + "Location": { + "description": "Location of resource", + "type": "string" + } + } + }, + "404": { + "description": "NotFound", + "schema": { + "$ref": "#/definitions/ApiError" + }, + "examples": { + "application/json": { + "code": 404, + "message": "Not found" + } + }, + "headers": { + "Date": { + "description": "Date of failure", + "type": "string" + } + } + } + } +``` + +Failure information can be passed as an array of arrays or an array of hashes. + +#### Adding root element to responses + +You can specify a custom root element for a successful response: + +```ruby +route_setting :swagger, root: 'cute_kitten' +desc 'Get a kitten' do + http_codes [{ code: 200, model: Entities::Kitten }] +end +get '/kittens/:id' do +end +``` + +The result will look like following: + +```json + "responses": { + "200": { + "description": "Get a kitten", + "schema": { + "type": "object", + "properties": { "cute_kitten": { "$ref": "#/definitions/Kitten" } } + } + } + } +``` + +If you specify `true`, the value of the root element will be deduced based on the model name. +E.g. in the following example the root element will be "kittens": + +```ruby +route_setting :swagger, root: true +desc 'Get kittens' do + is_array true + http_codes [{ code: 200, model: Entities::Kitten }] +end +get '/kittens' do +end +``` + +The result will look like following: + +```json + "responses": { + "200": { + "description": "Get kittens", + "schema": { + "type": "object", + "properties": { "type": "array", "items": { "kittens": { "$ref": "#/definitions/Kitten" } } } + } + } + } +``` +#### Multiple present Response + +You can specify a custom multiple response by using the `as` key: +```ruby +desc 'Multiple response', + success: [ + { model: Entities::EnumValues, as: :gender }, + { model: Entities::Something, as: :somethings } + ] +end + +get '/things' do + ... +end +``` +The result will look like following: +```json + "responses": { + "200": { + "description": "Multiple response", + "schema":{ + "type":"object", + "properties":{ + "gender":{ + "$ref":"#/definitions/EnumValues" + }, + "somethings":{ + "$ref":"#/definitions/Something" + } + } + } + } + } +``` +You can also specify if the response is an array, with the `is_array` key: +```ruby +desc 'Multiple response with array', + success: [ + { model: Entities::EnumValues, as: :gender }, + { model: Entities::Something, as: :somethings, is_array: true, required: true } + ] +end + +get '/things' do + ... +end +``` +The result will look like following: +```json + "responses": { + "200": { + "description": "Multiple response with array", + "schema":{ + "type":"object", + "properties":{ + "gender":{ + "$ref":"#/definitions/EnumValues" + }, + "somethings":{ + "type":"array", + "items":{ + "$ref":"#/definitions/Something" + } + } + }, + "required": ["somethings"] + } + } + } +``` + +## Using Grape Entities + +Add the [grape-entity](https://github.com/ruby-grape/grape-entity) and [grape-swagger-entity](https://github.com/ruby-grape/grape-swagger-entity) gem to your Gemfile. + +The following example exposes statuses. And exposes statuses documentation adding :type, :desc and :required. +The documented class/definition name could be set via `#entity_name`. + +```ruby +module API + module Entities + class Status < Grape::Entity + expose :text, documentation: { type: 'string', desc: 'Status update text.', required: true } + expose :links, using: Link, documentation: { type: 'link', is_array: true } + expose :numbers, documentation: { type: 'integer', desc: 'favourite number', values: [1,2,3,4] } + end + + class Link < Grape::Entity + expose :href, documentation: { type: 'url' } + expose :rel, documentation: { type: 'string'} + + def self.entity_name + 'LinkedStatus' + end + + end + end + + class Statuses < Grape::API + version 'v1' + + desc 'Statuses index', + entity: API::Entities::Status + get '/statuses' do + statuses = Status.all + type = current_user.admin? ? :full : :default + present statuses, with: API::Entities::Status, type: type + end + + desc 'Creates a new status', + entity: API::Entities::Status, + params: API::Entities::Status.documentation + post '/statuses' do + ... + end + end +end +``` + + +### Relationships + +You may safely omit `type` from relationships, as it can be inferred. However, if you need to specify or override it, use the full name of the class leaving out any modules named `Entities` or `Entity`. + + +#### 1xN + +```ruby +module API + module Entities + class Client < Grape::Entity + expose :name, documentation: { type: 'string', desc: 'Name' } + expose :addresses, using: Entities::Address, + documentation: { type: 'Entities::Address', desc: 'Addresses.', param_type: 'body', is_array: true } + end + + class Address < Grape::Entity + expose :street, documentation: { type: 'string', desc: 'Street.' } + end + end + + class Clients < Grape::API + version 'v1' + + desc 'Clients index', + params: Entities::Client.documentation, + success: Entities::Client + get '/clients' do + ... + end + end + + add_swagger_documentation +end +``` + + +#### 1x1 + +Note: `is_array` is `false` by default. + +```ruby +module API + module Entities + class Client < Grape::Entity + expose :name, documentation: { type: 'string', desc: 'Name' } + expose :address, using: Entities::Address, + documentation: { type: 'Entities::Address', desc: 'Addresses.', param_type: 'body', is_array: false } + end + + class Address < Grape::Entity + expose :street, documentation: { type: 'string', desc: 'Street' } + end + end + + class Clients < Grape::API + version 'v1' + + desc 'Clients index', + params: Entities::Client.documentation, + success: Entities::Client + get '/clients' do + ... + end + end + + add_swagger_documentation +end +``` + +#### Inheritance with allOf and discriminator +```ruby +module Entities + class Pet < Grape::Entity + expose :type, documentation: { + type: 'string', + is_discriminator: true, + required: true + } + expose :name, documentation: { + type: 'string', + required: true + } + end + + class Cat < Pet + expose :huntingSkill, documentation: { + type: 'string', + description: 'The measured skill for hunting', + default: 'lazy', + values: %w[ + clueless + lazy + adventurous + aggressive + ] + } + end +end +``` + +Should generate this definitions: +```json +{ + "definitions": { + "Pet": { + "type": "object", + "discriminator": "petType", + "properties": { + "name": { + "type": "string" + }, + "petType": { + "type": "string" + } + }, + "required": [ + "name", + "petType" + ] + }, + "Cat": { + "description": "A representation of a cat", + "allOf": [ + { + "$ref": "#/definitions/Pet" + }, + { + "type": "object", + "properties": { + "huntingSkill": { + "type": "string", + "description": "The measured skill for hunting", + "default": "lazy", + "enum": [ + "clueless", + "lazy", + "adventurous", + "aggressive" + ] + }, + "petType": { + "type": "string", + "enum": ["Cat"] + } + }, + "required": [ + "huntingSkill", + "petType" + ] + } + ] + } + } +} +``` + + + + +## Securing the Swagger UI + +The Swagger UI on Grape could be secured from unauthorized access using any middleware, which provides certain methods: + +- some guard method, which could receive as argument a string or an array of authorization scopes; +- a *before* method to be run in the Grape controller for authorization purpose; +- a set of methods which will process the access token received in the HTTP request headers (usually in the +'HTTP_AUTHORIZATION' header) and try to return the owner of the token. + +Below are some examples of securing the Swagger UI on Grape installed along with Ruby on Rails: + +- The WineBouncer and Doorkeeper gems are used in the examples; +- 'rails' and 'wine_bouncer' gems should be required prior to 'grape-swagger' in boot.rb; +- This works with a fresh PR to WineBouncer which is yet unmerged - [WineBouncer PR](https://github.com/antek-drzewiecki/wine_bouncer/pull/64). + +This is how to configure the grape_swagger documentation: + +```ruby + add_swagger_documentation base_path: '/', + title: 'My API', + doc_version: '0.0.1', + hide_documentation_path: true, + endpoint_auth_wrapper: WineBouncer::OAuth2, # This is the middleware for securing the Swagger UI + swagger_endpoint_guard: 'oauth2 false', # this is the guard method and scope + token_owner: 'resource_owner' # This is the method returning the owner of the token +``` + +The guard method should inject the Security Requirement Object into the endpoint's route settings (see Grape::DSL::Settings.route_setting method). + +The 'oauth2 false' added to swagger_documentation is making the main Swagger endpoint protected with OAuth, i.e. the +access_token is being retrieving from the HTTP request, but the 'false' scope is for skipping authorization and +showing the UI for everyone. If the scope would be set to something else, like 'oauth2 admin', for example, than the UI + wouldn't be displayed at all to unauthorized users. + +Further on, the guard could be used, where necessary, for endpoint access protection. Put it prior to the endpoint's method: + +```ruby + resource :users do + oauth2 'read, write' + get do + render_users + end + + oauth2 'admin' + post do + User.create!... + end + end +``` + +And, finally, if you want to not only restrict the access, but to completely hide the endpoint from unauthorized +users, you could pass a lambda to the :hidden key of a endpoint's description: + +```ruby + not_admins = lambda { |token_owner = nil| token_owner.nil? || !token_owner.admin? } + + resource :users do + desc 'Create user', hidden: not_admins + oauth2 'admin' + post do + User.create!... + end + end +``` + +The lambda is checking whether the user is authenticated (if not, the token_owner is nil by default), and has the admin +role - only admins can see this endpoint. + + + +## Example + +Go into example directory and run it: `$ bundle exec rackup` +go to: `http://localhost:9292/swagger_doc` to get it + +For request examples load the [postman file]() + +#### Grouping the API list using Namespace + +Use namespace for grouping APIs + +![grape-swagger-v2-new-corrected](https://cloud.githubusercontent.com/assets/1027590/13516020/979cfefa-e1f9-11e5-9624-f4a6b17a3c8a.png) + +#### Example Code + +```ruby +class NamespaceApi < Grape::API + namespace :hudson do + desc 'Document root' + get '/' do + end + + desc 'This gets something.', + detail: '_test_' + + get '/simple' do + { bla: 'something' } + end + end + + namespace :download do + desc 'download files', + success: File, + produces: ['text/csv'] + get ':id' do + # file response + end + end +end + … + +``` + + + +## Rake Tasks + +Add these lines to your Rakefile, and initialize the Task class with your Api class. + +```ruby +require 'grape-swagger/rake/oapi_tasks' +GrapeSwagger::Rake::OapiTasks.new(::Api::Base) +``` + +You may initialize with the class name as a string if the class is not yet loaded at the time Rakefile is parsed: +```ruby +require 'grape-swagger/rake/oapi_tasks' +GrapeSwagger::Rake::OapiTasks.new('::Api::Base') +``` + +#### OpenApi/Swagger Documentation + +``` +rake oapi:fetch +params: +- store={ true | file_name.json } – save as JSON (optional) +- resource=resource_name – get only for this one (optional) +``` +For multiversion API it creates several files with following naming: file_name_`API_VERSION`.json + +#### OpenApi/Swagger Validation + +**requires**: `npm` and `swagger-cli` to be installed + + +``` +rake oapi:validate +params: +- resource=resource_name – get only for this one (optional) +``` + + +## Contributing to grape-swagger + +See [CONTRIBUTING](CONTRIBUTING.md). + +## Copyright and License + +Copyright (c) 2012-2016 Tim Vandecasteele, ruby-grape and contributors. See [LICENSE.txt](LICENSE.txt) for details. diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/RELEASING.md b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/RELEASING.md new file mode 100644 index 00000000..b419e938 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/RELEASING.md @@ -0,0 +1,82 @@ +# Releasing Grape-Swagger + +There are no particular rules about when to release grape-swagger. Any co-maintainer is encouraged to release bug fixes frequently, features not so frequently and breaking API changes rarely. + +### Release + +Run tests, check that all tests succeed locally. + +``` +bundle install +rake +``` + +Check that the last build succeeded in [Travis CI](https://travis-ci.org/ruby-grape/grape-swagger) for all supported platforms. + +Change "Next" in [CHANGELOG.md](CHANGELOG.md) to the current date. + +``` +### 0.7.2 (February 6, 2014) +``` + +Remove the lines with "Your contribution here.", since there will be no more contributions to this release. + +Commit your changes. + +``` +git add CHANGELOG.md lib/grape-swagger/version.rb +git commit -m "Preparing for release, 0.7.2." +git push origin master +``` + +Release. + +``` +$ rake release + +grape-swagger 0.7.2 built to pkg/grape-swagger-0.7.2.gem. +Tagged v0.7.2. +Pushed git commits and tags. +Pushed grape-swagger 0.7.2 to rubygems.org. +``` + +### Prepare for the Next Version + +Increment the minor version, the third number, modify [lib/grape-swagger/version.rb](lib/grape-swagger/version.rb). For example, change `0.7.1` to `0.7.2`. Major versions are incremented in pull requests that require it. + +Add the next release to [CHANGELOG.md](CHANGELOG.md). + +``` +### 0.7.3 (Next) + +#### Features + +* Your contribution here. + +#### Fixes + +* Your contribution here. +``` + +Commit your changes. + +``` +git add CHANGELOG.md lib/grape-swagger/version.rb +git commit -m "Preparing for next developer iteration, 0.7.3." +git push origin master +``` + +### Make an Announcement + +Make an announcement on the [ruby-grape@googlegroups.com](mailto:ruby-grape@googlegroups.com) mailing list. The general format is as follows. + +``` +Grape-Swagger 0.7.2 has been released. + +There were 8 contributors to this release, not counting documentation. + +Please note the breaking API change in ... + +[copy/paste CHANGELOG here] + +``` diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/UPGRADING.md b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/UPGRADING.md new file mode 100644 index 00000000..1df6264c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/UPGRADING.md @@ -0,0 +1,210 @@ +## Upgrading Grape-swagger + +### Upgrading to >= x.y.z + +- Grape-swagger now documents array parameters within an object schema in Swagger. This aligns with grape's JSON structure requirements and ensures the documentation is correct. + - Previously, arrays were documented as standalone arrays, which could be incorrect based on grape's expectations. + - Check your API documentation and update your code or tests that use the old array format. + + Attention: This update may require you to make changes to ensure your API integrations continue to work correctly. + For detailed reasons behind this update, refer to GitHub issue #666. + +### Upgrading to >= 1.5.0 + +- The names generated for body parameter definitions and their references has changed. It'll now include the HTTP action as well as any path parameters. + - E.g, given a `PUT /things/:id` endpoint, `paths.things/{id}.put.parameters` in the generated Swaggerfile will contain the following: + - With `grape-swagger < 1.5.0`: `{ "name": "Things", ..., "schema": { "$ref": "#/definitions/putThings" } }` + - With `grape-swagger >= 1.5.0`: `{ "name": "putThingsId", ..., "schema": { "$ref": "#/definitions/putThingsId" } }` +- If you use the `nickname` option for an endpoint, that nickname will be used for both the parameter name and its definition reference. + - E.g., if the endpoint above were nicknamed `put-thing`, the generated Swaggerfile will contain `{ "name": "put-thing", ..., "schema": { "$ref": "#/definitions/put-thing" } }` + + +### Upgrading to >= 1.4.2 + +- `additionalProperties` has been deprecated and will be removed in a future version of `grape-swagger`. It has been replaced with `additional_properties`. +- The value of the `enum` attribute is now always an Array. If it has only one value, it will be a one-element Array. + +### Upgrading to >= 1.4.0 + +- Official support for ruby < 2.5 removed, ruby 2.5 only in testing mode, but no support. + +### Upgrading to >= 1.3.0 + +- The model (entity) description no longer comes from the route description. It will have a default value: `<> model`. + +### Upgrading to >= 1.2.0 + +- The entity_name class method is now called on parent classes for inherited entities. Now you can do this + +```ruby +module Some::Long::Module + class Base < Grape::Entity + # ... other shared logic + def self.entity_name + "V2::#{self.to_s.demodulize}" + end + end + + def MyEntity < Base + # .... + end + + def OtherEntity < Base + # revert back to the default behavior by hiding the method + private_class_method :entity_name + end +end +``` + +- Full class name is modified to use `_` separator (e.g. `A_B_C` instead of `A::B::C`). + +### Upgrading to >= 1.1.0 + +Full class name is used for referencing entity by default (e.g. `A::B::C` instead of just `C`). `Entity` and `Entities` suffixes and prefixes are omitted (e.g. if entity name is `Entities::SomeScope::MyFavourite::Entity` only `SomeScope::MyFavourite` will be used). + +### Upgrading to >= 0.26.1 + +The format can now be specified, +to achieve it for definition properties one have to use grape-swagger-entity >= 0.1.6. + +Usage of option `markdown` won't no longer be supported, +cause OAPI accepts [GFM](https://help.github.com/articles/github-flavored-markdown) and plain text. +(see: [description of `Info`](https://github.com/OAI/OpenAPI-Specification/blob/OpenAPI.next/versions/2.0.md#info-object)) + +### Upgrading to >= 0.25.2 + +Avoids ambiguous documentation of array parameters, +by enforcing correct usage of both possibilities: + +1. Array of primitive types + ```ruby + params do + requires :foo, type: Array[String] + end + ``` + +2. Array of objects + ```ruby + params do + requires :put_params, type: Array do + requires :op, type: String + requires :path, type: String + requires :value, type: String + end + end +``` + +### Upgrading to >= 0.25.0 + +The global tag set now only includes tags for documented routes. This behaviour has impact in particular for calling the documtation of a specific route. + +### Upgrading to >= 0.21.0 + +With grape >= 0.21.0, `grape-entity` support moved to separate gem `grape-swagger-entity`, if you use grape entity, update your Gemfile: + +```ruby +gem 'grape-swagger' +gem 'grape-swagger-entity' +``` + +`add_swagger_documentation` has changed from +``` ruby + add_swagger_documentation \ + api_version: '0.0.1' +``` +to + +``` ruby + add_swagger_documentation \ + doc_version: '0.0.1' +``` + +The API version self, would be set by grape, see -> [spec for #403](https://github.com/ruby-grape/grape-swagger/blob/master/spec/issues/403_versions_spec.rb). + + + +### Upgrading to >= 0.10.2 + +With grape >= 0.12.0, support for `notes` is replaced by passing a block `detail` option specified. For future compatibility, update your code: + +```ruby +desc 'Get all kittens!', notes: 'this will expose all the kittens' +``` + +to + +``` ruby + desc 'Get all kittens!' do + detail 'this will expose all the kittens' +end +``` +Be aware of https://github.com/ruby-grape/grape/issues/920, currently grape accepts either an option hash OR a block for `desc`. + +### Upgrading to >= 0.9.0 + +#### Grape-Swagger-Rails + +If you're using [grape-swagger-rails](https://github.com/ruby-grape/grape-swagger-rails), remove the `.json` extension from `GrapeSwaggerRails.options.url`. + +For example, change + +```ruby +GrapeSwaggerRails.options.url = '/api/v1/swagger_doc.json' +``` + +to + +```ruby +GrapeSwaggerRails.options.url = '/api/v1/swagger_doc' +``` + +See [#187](https://github.com/ruby-grape/grape-swagger/issues/187) for more information. + +#### Grape 0.10.0 + +If your API uses Grape 0.10.0 or newer with a single `format :json` directive, add `hide_format: true` to `add_swagger_documentation`. Otherwise nested routes will render with `.json` links to your API documentation, which will fail with a 404 Not Found. + +### Upgrading to >= 0.8.0 + +#### Changes in Configuration + +The following options have been added, removed or have been changed in the grape-swagger interface: + +* `markdown: true/false` => `markdown: GrapeSwagger::Markdown::KramdownAdapter` + +#### Markdown + +You can now configure a markdown adapter. This was originally changed because of performance issues with Kramdown and the `markdown` option no longer takes a boolean argument. Built-in adapters include Kramdown and Redcarpet. + +##### Kramdown + +To configure the markdown with Kramdown, add the kramdown gem to your Gemfile: + +`gem 'kramdown'` + +Configure grape-swagger as follows: + +```ruby +add_swagger_documentation ( + markdown: GrapeSwagger::Markdown::KramdownAdapter +) +``` + +#### Redcarpet + +To configure markdown with Redcarpet, add the redcarpet and the rouge gem to your Gemfile. Note that Redcarpet does not work with JRuby. + +```ruby +gem 'redcarpet' +gem 'rouge' +``` + +Configure grape-swagger as follows: + +```ruby +add_swagger_documentation ( + markdown: GrapeSwagger::Markdown::RedcarpetAdapter +) +``` + +See [#142](https://github.com/ruby-grape/grape-swagger/pull/142) and documentation section [Markdown in Notes](https://github.com/ruby-grape/grape-swagger#markdown-in-notes) for more information. diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/grape-swagger.gemspec b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/grape-swagger.gemspec new file mode 100644 index 00000000..c8007a0c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/grape-swagger.gemspec @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require_relative 'lib/grape-swagger/version' + +Gem::Specification.new do |s| + s.name = 'grape-swagger' + s.version = GrapeSwagger::VERSION + s.platform = Gem::Platform::RUBY + s.authors = ['LeFnord', 'Tim Vandecasteele'] + s.email = ['pscholz.le@gmail.com', 'tim.vandecasteele@gmail.com'] + s.homepage = 'https://github.com/ruby-grape/grape-swagger' + s.summary = 'Add auto generated documentation to your Grape API that can be displayed with Swagger.' + s.license = 'MIT' + + s.metadata['rubygems_mfa_required'] = 'true' + + s.required_ruby_version = '>= 3.1' + s.add_dependency 'grape', '>= 1.7', '< 3.0' + s.add_dependency 'rack-test', '~> 2' + + s.files = Dir['lib/**/*', '*.md', 'LICENSE.txt', 'grape-swagger.gemspec'] + s.require_paths = ['lib'] +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger.rb b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger.rb new file mode 100644 index 00000000..7a36ea0c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger.rb @@ -0,0 +1,202 @@ +# frozen_string_literal: true + +require 'grape' + +require 'grape-swagger/instance' + +require 'grape-swagger/version' +require 'grape-swagger/endpoint' +require 'grape-swagger/errors' + +require 'grape-swagger/doc_methods' +require 'grape-swagger/model_parsers' + +module GrapeSwagger + class << self + def model_parsers + @model_parsers ||= GrapeSwagger::ModelParsers.new + end + end + autoload :Rake, 'grape-swagger/rake/oapi_tasks' + + # Copied from https://github.com/ruby-grape/grape/blob/v2.2.0/lib/grape/formatter.rb + FORMATTER_DEFAULTS = { + json: Grape::Formatter::Json, + jsonapi: Grape::Formatter::Json, + serializable_hash: Grape::Formatter::SerializableHash, + txt: Grape::Formatter::Txt, + xml: Grape::Formatter::Xml + }.freeze + + # Copied from https://github.com/ruby-grape/grape/blob/v2.2.0/lib/grape/content_types.rb + CONTENT_TYPE_DEFAULTS = { + xml: 'application/xml', + serializable_hash: 'application/json', + json: 'application/json', + binary: 'application/octet-stream', + txt: 'text/plain' + }.freeze +end + +module SwaggerRouting + private + + def combine_routes(app, doc_klass) + app.routes.each_with_object({}) do |route, combined_routes| + route_path = route.path + route_match = route_path.split(/^.*?#{route.prefix}/).last + next unless route_match + + # want to match emojis … ;) + # route_match = route_match + # .match('\/([\p{Alnum}p{Emoji}\-\_]*?)[\.\/\(]') || route_match.match('\/([\p{Alpha}\p{Emoji}\-\_]*)$') + route_match = route_match.match('\/([\p{Alnum}\-\_]*?)[\.\/\(]') || route_match.match('\/([\p{Alpha}\-\_]*)$') + next unless route_match + + resource = route_match.captures.first + resource = '/' if resource.empty? + combined_routes[resource] ||= [] + next if doc_klass.hide_documentation_path && route.path.match(/#{doc_klass.mount_path}($|\/|\(\.)/) + + combined_routes[resource] << route + end + end + + def determine_namespaced_routes(name, parent_route, routes) + return routes.values.flatten if parent_route.nil? + + parent_route.select do |route| + route_path_start_with?(route, name) || route_namespace_equals?(route, name) + end + end + + def combine_namespace_routes(namespaces, routes) + combined_namespace_routes = {} + # iterate over each single namespace + namespaces.each_key do |name, _| + # get the parent route for the namespace + parent_route_name = extract_parent_route(name) + parent_route = routes[parent_route_name] + # fetch all routes that are within the current namespace + namespace_routes = determine_namespaced_routes(name, parent_route, routes) + + # default case when not explicitly specified or nested == true + standalone_namespaces = namespaces.reject do |_, ns| + !ns.options.key?(:swagger) || + !ns.options[:swagger].key?(:nested) || + ns.options[:swagger][:nested] != false + end + + parent_standalone_namespaces = standalone_namespaces.select { |ns_name, _| name.start_with?(ns_name) } + # add only to the main route + # if the namespace is not within any other namespace appearing as standalone resource + # rubocop:disable Style/Next + if parent_standalone_namespaces.empty? + # default option, append namespace methods to parent route + combined_namespace_routes[parent_route_name] ||= [] + combined_namespace_routes[parent_route_name].push(*namespace_routes) + end + # rubocop:enable Style/Next + end + + combined_namespace_routes + end + + def extract_parent_route(name) + route_name = name.match(%r{^/?([^/]*).*$})[1] + return route_name unless route_name.include? ':' + + matches = name.match(/\/\p{Alpha}+/) + matches.nil? ? route_name : matches[0].delete('/') + end + + def route_namespace_equals?(route, name) + patterns = Enumerator.new do |yielder| + yielder << "/#{name}" + yielder << "/:version/#{name}" + end + + patterns.any? { |p| route.namespace == p } + end + + def route_path_start_with?(route, name) + patterns = Enumerator.new do |yielder| + if route.prefix + yielder << "/#{route.prefix}/#{name}" + yielder << "/#{route.prefix}/:version/#{name}" + else + yielder << "/#{name}" + yielder << "/:version/#{name}" + end + end + + patterns.any? { |p| route.path.start_with?(p) } + end +end + +module SwaggerDocumentationAdder + attr_accessor :combined_namespaces, :combined_routes, :combined_namespace_routes + + include SwaggerRouting + + def add_swagger_documentation(options = {}) + documentation_class = create_documentation_class + + version_for(options) + options = { target_class: self }.merge(options) + @target_class = options[:target_class] + auth_wrapper = options[:endpoint_auth_wrapper] || Class.new + + use auth_wrapper if auth_wrapper.method_defined?(:before) && !middleware.flatten.include?(auth_wrapper) + + documentation_class.setup(options) + mount(documentation_class) + + combined_routes = combine_routes(@target_class, documentation_class) + combined_namespaces = combine_namespaces(@target_class) + combined_namespace_routes = combine_namespace_routes(combined_namespaces, combined_routes) + exclusive_route_keys = combined_routes.keys - combined_namespaces.keys + @target_class.combined_namespace_routes = combined_namespace_routes.merge( + combined_routes.slice(*exclusive_route_keys) + ) + @target_class.combined_routes = combined_routes + @target_class.combined_namespaces = combined_namespaces + + documentation_class + end + + private + + def version_for(options) + options[:version] = version if version + end + + def combine_namespaces(app) + combined_namespaces = {} + endpoints = app.endpoints.clone + + while endpoints.any? + endpoint = endpoints.shift + + endpoints.push(*endpoint.options[:app].endpoints) if endpoint.options[:app] + ns = endpoint.namespace_stackable(:namespace).last + next unless ns + + # use the full namespace here (not the latest level only) + # and strip leading slash + mount_path = (endpoint.namespace_stackable(:mount_path) || []).join('/') + full_namespace = (mount_path + endpoint.namespace).sub(/\/{2,}/, '/').sub(/^\//, '') + combined_namespaces[full_namespace] = ns + end + + combined_namespaces + end + + def create_documentation_class + Class.new(GrapeInstance) do + extend GrapeSwagger::DocMethods + end + end +end + +GrapeInstance.extend(SwaggerDocumentationAdder) diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods.rb b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods.rb new file mode 100644 index 00000000..efb850e3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods.rb @@ -0,0 +1,141 @@ +# frozen_string_literal: true + +require 'grape-swagger/doc_methods/status_codes' +require 'grape-swagger/doc_methods/produces_consumes' +require 'grape-swagger/doc_methods/data_type' +require 'grape-swagger/doc_methods/extensions' +require 'grape-swagger/doc_methods/format_data' +require 'grape-swagger/doc_methods/operation_id' +require 'grape-swagger/doc_methods/optional_object' +require 'grape-swagger/doc_methods/path_string' +require 'grape-swagger/doc_methods/tag_name_description' +require 'grape-swagger/doc_methods/parse_params' +require 'grape-swagger/doc_methods/move_params' +require 'grape-swagger/doc_methods/headers' +require 'grape-swagger/doc_methods/build_model_definition' +require 'grape-swagger/doc_methods/version' + +module GrapeSwagger + module DocMethods + DEFAULTS = + { + info: {}, + models: [], + doc_version: '0.0.1', + target_class: nil, + mount_path: '/swagger_doc', + host: nil, + base_path: nil, + add_base_path: false, + add_version: true, + add_root: false, + hide_documentation_path: true, + format: :json, + authorizations: nil, + security_definitions: nil, + security: nil, + api_documentation: { desc: 'Swagger compatible API description' }, + specific_api_documentation: { desc: 'Swagger compatible API description for specific API' }, + endpoint_auth_wrapper: nil, + swagger_endpoint_guard: nil, + token_owner: nil + }.freeze + + FORMATTER_METHOD = %i[format default_format default_error_formatter].freeze + + def self.output_path_definitions(combi_routes, endpoint, target_class, options) + output = endpoint.swagger_object( + target_class, + endpoint.request, + options + ) + + paths, definitions = endpoint.path_and_definition_objects(combi_routes, options) + tags = tags_from(paths, options) + + output[:tags] = tags unless tags.empty? || paths.blank? + output[:paths] = paths unless paths.blank? + output[:definitions] = definitions unless definitions.blank? + + output + end + + def self.tags_from(paths, options) + tags = GrapeSwagger::DocMethods::TagNameDescription.build(paths) + + if options[:tags] + names = options[:tags].map { |t| t[:name] } + tags.reject! { |t| names.include?(t[:name]) } + tags += options[:tags] + end + + tags + end + + def hide_documentation_path + @@hide_documentation_path + end + + def mount_path + @@mount_path + end + + def setup(options) + options = DEFAULTS.merge(options) + + # options could be set on #add_swagger_documentation call, + # for available options see #defaults + target_class = options[:target_class] + guard = options[:swagger_endpoint_guard] + api_doc = options[:api_documentation].dup + specific_api_doc = options[:specific_api_documentation].dup + + class_variables_from(options) + + setup_formatter(options[:format]) + + desc api_doc.delete(:desc), api_doc + + instance_eval(guard) unless guard.nil? + + get mount_path do + header['Access-Control-Allow-Origin'] = '*' + header['Access-Control-Request-Method'] = '*' + + GrapeSwagger::DocMethods + .output_path_definitions(target_class.combined_namespace_routes, self, target_class, options) + end + + desc specific_api_doc.delete(:desc), { params: specific_api_doc.delete(:params) || {}, **specific_api_doc } + + params do + requires :name, type: String, desc: 'Resource name of mounted API' + optional :locale, type: Symbol, desc: 'Locale of API documentation' + end + + instance_eval(guard) unless guard.nil? + + get "#{mount_path}/:name" do + I18n.locale = params[:locale] || I18n.default_locale + + combined_routes = target_class.combined_namespace_routes[params[:name]] + error!({ error: 'named resource not exist' }, 400) if combined_routes.nil? + + GrapeSwagger::DocMethods + .output_path_definitions({ params[:name] => combined_routes }, self, target_class, options) + end + end + + def class_variables_from(options) + @@mount_path = options[:mount_path] + @@class_name = options[:class_name] || options[:mount_path].delete('/') + @@hide_documentation_path = options[:hide_documentation_path] + end + + def setup_formatter(formatter) + return unless formatter + + FORMATTER_METHOD.each { |method| send(method, formatter) } + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/build_model_definition.rb b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/build_model_definition.rb new file mode 100644 index 00000000..444b17f8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/build_model_definition.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +module GrapeSwagger + module DocMethods + class BuildModelDefinition + class << self + def build(_model, properties, required, other_def_properties = {}) + definition = { type: 'object', properties: properties }.merge(other_def_properties) + + definition[:required] = required if required.is_a?(Array) && required.any? + + definition + end + + def parse_params_from_model(parsed_response, model, model_name) + if parsed_response.is_a?(Hash) && parsed_response.keys.first == :allOf + refs_or_models = parsed_response[:allOf] + parsed = parse_refs_and_models(refs_or_models, model) + + { + allOf: parsed + } + else + properties, required = parsed_response + unless properties&.any? + raise GrapeSwagger::Errors::SwaggerSpec, + "Empty model #{model_name}, swagger 2.0 doesn't support empty definitions." + end + properties, other_def_properties = parse_properties(properties) + + build( + model, properties, required, other_def_properties + ) + end + end + + def parse_properties(properties) + other_properties = {} + + discriminator_key, discriminator_value = + properties.find do |_key, value| + value[:documentation].try(:[], :is_discriminator) + end + + if discriminator_key + discriminator_value.delete(:documentation) + properties[discriminator_key] = discriminator_value + + other_properties[:discriminator] = discriminator_key + end + + [properties, other_properties] + end + + def parse_refs_and_models(refs_or_models, model) + refs_or_models.map do |ref_or_models| + if ref_or_models.is_a?(Hash) && ref_or_models.keys.first == '$ref' + ref_or_models + else + properties, required = ref_or_models + GrapeSwagger::DocMethods::BuildModelDefinition.build(model, properties, required) + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/data_type.rb b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/data_type.rb new file mode 100644 index 00000000..62f47f3c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/data_type.rb @@ -0,0 +1,110 @@ +# frozen_string_literal: true + +module GrapeSwagger + module DocMethods + class DataType + class << self + def call(value) + raw_data_type = value.is_a?(Hash) ? value[:type] : value + raw_data_type ||= 'String' + raw_data_type = parse_multi_type(raw_data_type) + + case raw_data_type.to_s + when 'Boolean', 'Date', 'Integer', 'String', 'Float', 'JSON', 'Array' + raw_data_type.to_s.downcase + when 'Hash' + 'object' + when 'Rack::Multipart::UploadedFile', 'File' + 'file' + when 'Grape::API::Boolean' + 'boolean' + when 'BigDecimal' + 'double' + when 'DateTime', 'Time' + 'dateTime' + when 'Numeric' + 'long' + when 'Symbol' + 'string' + else + parse_entity_name(raw_data_type) + end + end + + def parse_multi_type(raw_data_type) + case raw_data_type + when /\A\[.*\]\z/ + type_as_string = raw_data_type.gsub(/[\[\s+\]]/, '').split(',').first + begin + Object.const_get(type_as_string) + rescue NameError + type_as_string + end + when Array + raw_data_type.first + else + raw_data_type + end + end + + def parse_entity_name(model) + if model.respond_to?(:entity_name) + model.entity_name + elsif model.to_s.end_with?('::Entity', '::Entities') + model.to_s.split('::')[0..-2].join('_') + elsif model.to_s.start_with?('Entity::', 'Entities::', 'Representable::') + model.to_s.split('::')[1..-1].join('_') + else + model.to_s.split('::').join('_') + end + end + + def request_primitive?(type) + request_primitives.include?(type.to_s.downcase) + end + + def primitive?(type) + primitives.include?(type.to_s.downcase) + end + + def request_primitives + primitives + %w[object string boolean file json array] + end + + def primitives + PRIMITIVE_MAPPINGS.keys.map(&:downcase) + end + + def query_array_primitive?(type) + query_array_primitives.include?(type.to_s.downcase) + end + + def query_array_primitives + primitives << 'string' + end + + def mapping(value) + PRIMITIVE_MAPPINGS[value] || 'string' + end + + def collections + %w[csv ssv tsv pipes multi brackets] + end + end + + PRIMITIVE_MAPPINGS = { + 'integer' => %w[integer int32], + 'long' => %w[integer int64], + 'float' => %w[number float], + 'double' => %w[number double], + 'byte' => %w[string byte], + 'date' => %w[string date], + 'dateTime' => %w[string date-time], + 'binary' => %w[string binary], + 'password' => %w[string password], + 'email' => %w[string email], + 'uuid' => %w[string uuid] + }.freeze + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/extensions.rb b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/extensions.rb new file mode 100644 index 00000000..0c5334f7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/extensions.rb @@ -0,0 +1,102 @@ +# frozen_string_literal: true + +module GrapeSwagger + module DocMethods + class Extensions + class << self + def add(path, definitions, route) + @route = route + + description = route.settings[:description] + add_extension_to(path[method], extension(description)) if description && extended?(description, :x) + + settings = route.settings + add_extensions_to_operation(settings, path, route) if settings && extended?(settings, :x_operation) + add_extensions_to_path(settings, path) if settings && extended?(settings, :x_path) + add_extensions_to_definition(settings, path, definitions) if settings && extended?(settings, :x_def) + end + + def add_extensions_to_root(settings, object) + add_extension_to(object, extension(settings)) if extended?(settings, :x) + end + + def add_extensions_to_info(settings, info) + add_extension_to(info, extension(settings)) if extended?(settings, :x) + end + + def add_extensions_to_operation(settings, path, route) + add_extension_to(path[route.request_method.downcase.to_sym], extension(settings, :x_operation)) + end + + def add_extensions_to_path(settings, path) + add_extension_to(path, extension(settings, :x_path)) + end + + def add_extensions_to_definition(settings, path, definitions) + def_extension = extension(settings, :x_def) + + if def_extension[:x_def].is_a?(Array) + def_extension[:x_def].each { |extension| setup_definition(extension, path, definitions) } + else + setup_definition(def_extension[:x_def], path, definitions) + end + end + + def setup_definition(def_extension, path, definitions) + return unless def_extension.key?(:for) + + status = def_extension[:for] + + definition = find_definition(status, path) + add_extension_to(definitions[definition], x_def: def_extension) + end + + def find_definition(status, path) + response = path[method][:responses][status] + return if response.nil? + + return response[:schema]['$ref'].split('/').last if response[:schema].key?('$ref') + + response[:schema]['items']['$ref'].split('/').last if response[:schema].key?('items') + end + + def add_extension_to(part, extensions) + return if part.nil? + + concatenate(extensions).each do |key, value| + part[key] = value unless key.start_with?('x-for') + end + end + + def concatenate(extensions) + result = {} + + extensions.each_value do |extension| + extension.each do |key, value| + result["x-#{key}"] = value + end + end + + result + end + + def extended?(part, identifier = :x) + !extension(part, identifier).empty? + end + + def extension(part, identifier = :x) + part.select { |x| x == identifier } + end + + def method(*args) + # We're shadowing Object.method(:symbol) here so we provide + # a compatibility layer for code that introspects the methods + # of this class + return super if args.size.positive? + + @route.request_method.downcase.to_sym + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/format_data.rb b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/format_data.rb new file mode 100644 index 00000000..dee52b41 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/format_data.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +module GrapeSwagger + module DocMethods + class FormatData + class << self + def to_format(parameters) + parameters.reject { |parameter| parameter[:in] == 'body' }.each do |b| + related_parameters = parameters.select do |p| + p[:name] != b[:name] && p[:name].to_s.start_with?("#{b[:name].to_s.gsub(/\[\]\z/, '')}[") + end + parameters.reject! { |p| p[:name] == b[:name] } if move_down(b, related_parameters) + end + parameters + end + + def move_down(parameter, related_parameters) + case parameter[:type] + when 'array' + add_array(parameter, related_parameters) + unless related_parameters.blank? + add_braces(parameter, related_parameters) if parameter[:name].match?(/\A.*\[\]\z/) + return true + end + when 'object' + return true + end + false + end + + def add_braces(parameter, related_parameters) + param_name = parameter[:name].gsub(/\A(.*)\[\]\z/, '\1') + related_parameters.each { |p| p[:name] = p[:name].gsub(param_name, "#{param_name}[]") } + end + + def add_array(parameter, related_parameters) + related_parameters.each do |p| + next if p.key?(:items) + + p_type = p[:type] == 'array' ? 'string' : p[:type] + p[:items] = { type: p_type, format: p[:format], enum: p[:enum], is_array: p[:is_array] } + p[:items].compact! + p[:type] = 'array' + p[:is_array] = parameter[:is_array] + p.delete(:format) + p.delete(:enum) + p.compact! + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/headers.rb b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/headers.rb new file mode 100644 index 00000000..e84ec456 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/headers.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module GrapeSwagger + module DocMethods + class Headers + class << self + def parse(route) + route.headers.to_a.map do |route_header| + route_header.tap do |header| + hash = header[1] + description = hash.delete('description') + hash[:documentation] = { desc: description, in: 'header' } + hash[:type] = hash['type'].titleize if hash['type'] + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/move_params.rb b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/move_params.rb new file mode 100644 index 00000000..7329b46c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/move_params.rb @@ -0,0 +1,206 @@ +# frozen_string_literal: true + +require 'active_support/core_ext/hash/deep_merge' + +module GrapeSwagger + module DocMethods + class MoveParams + class << self + attr_accessor :definitions + + def can_be_moved?(http_verb, params) + move_methods.include?(http_verb) && includes_body_param?(params) + end + + def to_definition(path, params, route, definitions) + @definitions = definitions + unify!(params) + + params_to_move = movable_params(params) + + params << parent_definition_of_params(params_to_move, path, route) + + params + end + + private + + def parent_definition_of_params(params, path, route) + definition_name = OperationId.build(route, path) + # NOTE: Parent definition is always object + @definitions[definition_name] = object_type + definition = @definitions[definition_name] + move_params_to_new(definition, params) + + definition[:description] = route.description if route.try(:description) + + build_body_parameter(definition_name, route.options) + end + + def move_params_to_new(definition, params) + params, nested_params = params.partition { |x| !x[:name].to_s.include?('[') } + params.each do |param| + property = param[:name] + + param_properties, param_required = build_properties([param]) + add_properties_to_definition(definition, param_properties, param_required) + related_nested_params, nested_params = nested_params.partition { |x| x[:name].start_with?("#{property}[") } + prepare_nested_names(property, related_nested_params) + + next if related_nested_params.blank? + + nested_definition = if should_expose_as_array?([param]) + move_params_to_new(array_type, related_nested_params) + else + move_params_to_new(object_type, related_nested_params) + end + if definition.key?(:items) + definition[:items][:properties][property.to_sym].deep_merge!(nested_definition) + else + definition[:properties][property.to_sym].deep_merge!(nested_definition) + end + end + definition + end + + def build_properties(params) + properties = {} + required = [] + + params.each do |param| + name = param[:name].to_sym + + properties[name] = if should_expose_as_array?([param]) + document_as_array(param) + else + document_as_property(param) + end + add_extension_properties(properties[name], param) + + required << name if deletable?(param) && param[:required] + end + + [properties, required] + end + + def document_as_array(param) + {}.tap do |property| + property[:type] = 'array' + property[:description] = param.delete(:description) unless param[:description].nil? + property[:example] = param.delete(:example) unless param[:example].nil? + property[:items] = document_as_property(param)[:items] + end + end + + def add_extension_properties(definition, values) + values.each do |key, value| + definition[key] = value if key.start_with?('x-') + end + end + + def document_as_property(param) + property_keys.each_with_object({}) do |x, memo| + next unless param.key?(x) + + value = param[x] + if x == :type && @definitions[value].present? + memo['$ref'] = "#/definitions/#{value}" + else + memo[x] = value + end + end + end + + def movable_params(params) + to_delete = params.each_with_object([]) { |x, memo| memo << x if deletable?(x) } + delete_from(params, to_delete) + + to_delete + end + + def delete_from(params, to_delete) + to_delete.each { |x| params.delete(x) } + end + + def add_properties_to_definition(definition, properties, required) + if definition.key?(:items) + definition[:items][:properties].deep_merge!(properties) + add_to_required(definition[:items], required) + else + definition[:properties].deep_merge!(properties) + add_to_required(definition, required) + end + end + + def add_to_required(definition, value) + return if value.blank? + + definition[:required] ||= [] + definition[:required].push(*value) + end + + def build_body_parameter(name, options) + {}.tap do |x| + x[:name] = options[:body_name] || name + x[:in] = 'body' + x[:required] = true + x[:schema] = { '$ref' => "#/definitions/#{name}" } + end + end + + def build_definition(name, params) + @definitions[name] = should_expose_as_array?(params) ? array_type : object_type + + name + end + + def array_type + { type: 'array', items: { type: 'object', properties: {} } } + end + + def object_type + { type: 'object', properties: {} } + end + + def prepare_nested_names(property, params) + params.each { |x| x[:name] = x[:name].sub(property, '').sub('[', '').sub(']', '') } + end + + def unify!(params) + params.each { |x| x[:in] = x.delete(:param_type) if x[:param_type] } + params.each { |x| x[:in] = 'body' if x[:in] == 'formData' } if includes_body_param?(params) + end + + def parse_model(ref) + parts = ref.split('/') + parts.last.include?('{') ? parts[0..-2].join('/') : parts[0..-1].join('/') + end + + def property_keys + %i[type format description minimum maximum items enum default additional_properties additionalProperties + example] + end + + def deletable?(param) + param[:in] == 'body' + end + + def move_methods + [:delete, :post, :put, :patch, 'DELETE', 'POST', 'PUT', 'PATCH'] + end + + def includes_body_param?(params) + params.any? { |x| x[:in] == 'body' || x[:param_type] == 'body' } + end + + def should_expose_as_array?(params) + should_exposed_as(params) == 'array' + end + + def should_exposed_as(params) + params.any? { |x| x[:type] && x[:type] != 'array' } ? 'object' : 'array' + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/operation_id.rb b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/operation_id.rb new file mode 100644 index 00000000..e46236a6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/operation_id.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module GrapeSwagger + module DocMethods + class OperationId + class << self + def build(route, path = nil) + if route.options[:nickname] + route.options[:nickname] + else + verb = route.request_method.to_s.downcase + operation = manipulate(path) unless path.nil? + "#{verb}#{operation}" + end + end + + def manipulate(path) + operation = path.split('/').map(&:capitalize).join + operation.gsub!(/-(\w)/, &:upcase).delete!('-') if operation[/-(\w)/] + operation.gsub!(/_(\w)/, &:upcase).delete!('_') if operation.include?('_') + operation.gsub!(/\.(\w)/, &:upcase).delete!('.') if operation[/\.(\w)/] + if path.include?('{') + operation.gsub!(/\{(\w)/, &:upcase) + operation.delete!('{').delete!('}') + end + + operation + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/optional_object.rb b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/optional_object.rb new file mode 100644 index 00000000..5f007259 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/optional_object.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module GrapeSwagger + module DocMethods + class OptionalObject + class << self + def build(key, options, request = nil) + if options[key] + return evaluate(key, options, request) if options[key].is_a?(Proc) + + options[key] + else + request.send(default_values[key]) + end + end + + def evaluate(key, options, request) + options[key].arity.zero? ? options[key].call : options[key].call(request) + end + + def default_values + { + host: 'host_with_port', + base_path: 'script_name' + } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/parse_params.rb b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/parse_params.rb new file mode 100644 index 00000000..c4a1b804 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/parse_params.rb @@ -0,0 +1,196 @@ +# frozen_string_literal: true + +module GrapeSwagger + module DocMethods + class ParseParams + class << self + def call(param, settings, path, route, definitions, consumes) # rubocop:disable Metrics/ParameterLists + method = route.request_method + additional_documentation = settings.fetch(:documentation, {}) + settings.merge!(additional_documentation) + data_type = DataType.call(settings) + + value_type = settings.merge(data_type: data_type, path: path, param_name: param, method: method) + + # required properties + @parsed_param = { + in: param_type(value_type, consumes), + name: settings[:full_name] || param + } + + # optional properties + document_description(settings) + document_type_and_format(settings, data_type) + document_array_param(value_type, definitions) if value_type[:is_array] + document_default_value(settings) unless value_type[:is_array] + document_range_values(settings) unless value_type[:is_array] + document_required(settings) + document_length_limits(value_type) + document_additional_properties(definitions, settings) unless value_type[:is_array] + document_add_extensions(settings) + document_example(settings) + + @parsed_param + end + + private + + def document_description(settings) + description = settings[:desc] || settings[:description] + @parsed_param[:description] = description if description + end + + def document_required(settings) + @parsed_param[:required] = settings[:required] || false + @parsed_param[:required] = true if @parsed_param[:in] == 'path' + end + + def document_range_values(settings) + values = settings[:values] || nil + enum_or_range_values = parse_enum_or_range_values(values) + @parsed_param.merge!(enum_or_range_values) if enum_or_range_values + end + + def document_default_value(settings) + @parsed_param[:default] = settings[:default] if settings.key?(:default) + end + + def document_type_and_format(settings, data_type) + if DataType.primitive?(data_type) + data = DataType.mapping(data_type) + @parsed_param[:type], @parsed_param[:format] = data + else + @parsed_param[:type] = data_type + end + @parsed_param[:format] = settings[:format] if settings[:format].present? + end + + def document_add_extensions(settings) + GrapeSwagger::DocMethods::Extensions.add_extensions_to_root(settings, @parsed_param) + end + + def document_array_param(value_type, definitions) + if value_type[:documentation].present? + doc_type = value_type[:documentation][:type] + type = DataType.mapping(doc_type) if doc_type && !DataType.request_primitive?(doc_type) + collection_format = value_type[:documentation][:collectionFormat] + end + + array_items = parse_array_item( + definitions, + type, + value_type + ) + + @parsed_param[:items] = array_items + @parsed_param[:type] = 'array' + @parsed_param[:collectionFormat] = collection_format if DataType.collections.include?(collection_format) + end + + def parse_array_item(definitions, type, value_type) + array_items = {} + if definitions[value_type[:data_type]] + array_items['$ref'] = "#/definitions/#{@parsed_param[:type]}" + else + array_items[:type] = type || @parsed_param[:type] == 'array' ? 'string' : @parsed_param[:type] + end + array_items[:format] = @parsed_param.delete(:format) if @parsed_param[:format] + + values = value_type[:values] || nil + enum_or_range_values = parse_enum_or_range_values(values) + array_items.merge!(enum_or_range_values) if enum_or_range_values + + array_items[:default] = value_type[:default] if value_type[:default].present? + + set_additional_properties, additional_properties = parse_additional_properties(definitions, value_type) + array_items[:additionalProperties] = additional_properties if set_additional_properties + + if value_type.key?(:items) + GrapeSwagger::DocMethods::Extensions.add_extensions_to_root(value_type[:items], array_items) + end + + array_items + end + + def document_additional_properties(definitions, settings) + set_additional_properties, additional_properties = parse_additional_properties(definitions, settings) + @parsed_param[:additionalProperties] = additional_properties if set_additional_properties + end + + def parse_additional_properties(definitions, settings) + return false unless settings.key?(:additionalProperties) || settings.key?(:additional_properties) + + value = + if settings.key?(:additionalProperties) + GrapeSwagger::Errors::SwaggerSpecDeprecated.tell!(:additionalProperties) + settings[:additionalProperties] + else + settings[:additional_properties] + end + + parsed_value = + if definitions[value.to_s] + { '$ref': "#/definitions/#{value}" } + elsif value.is_a?(Class) + { type: DataType.call(value) } + else + value + end + + [true, parsed_value] + end + + def document_example(settings) + example = settings[:example] + @parsed_param[:example] = example if example + end + + def param_type(value_type, consumes) + param_type = value_type[:param_type] || value_type[:in] + if !value_type[:is_array] && value_type[:path].include?("{#{value_type[:param_name]}}") + 'path' + elsif param_type + param_type + elsif %w[POST PUT PATCH].include?(value_type[:method]) + if consumes.include?('application/x-www-form-urlencoded') || consumes.include?('multipart/form-data') + 'formData' + else + 'body' + end + elsif value_type[:is_array] && !DataType.query_array_primitive?(value_type[:data_type]) + 'formData' + else + 'query' + end + end + + def document_length_limits(value_type) + if value_type[:is_array] + @parsed_param[:minItems] = value_type[:min_length] if value_type.key?(:min_length) + @parsed_param[:maxItems] = value_type[:max_length] if value_type.key?(:max_length) + else + @parsed_param[:minLength] = value_type[:min_length] if value_type.key?(:min_length) + @parsed_param[:maxLength] = value_type[:max_length] if value_type.key?(:max_length) + end + end + + def parse_enum_or_range_values(values) + case values + when Proc + parse_enum_or_range_values(values.call) if values.parameters.empty? + when Range + parse_range_values(values) if values.first.is_a?(Integer) + when Array + { enum: values } + else + { enum: [values] } if values + end + end + + def parse_range_values(values) + { minimum: values.begin, maximum: values.end }.compact + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/path_string.rb b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/path_string.rb new file mode 100644 index 00000000..1fc02aa1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/path_string.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module GrapeSwagger + module DocMethods + class PathString + class << self + def build(route, options = {}) + path = route.path.dup + # always removing format + path.sub!(/\(\.\w+?\)$/, '') + path.sub!('(.:format)', '') + + # ... format path params + path.gsub!(/:(\w+)/, '{\1}') + + # set item from path, this could be used for the definitions object + path_name = path.gsub(%r{/{(.+?)}}, '').split('/').last + item = path_name.present? ? path_name.singularize.underscore.camelize : 'Item' + + if route.version && options[:add_version] + version = GrapeSwagger::DocMethods::Version.get(route) + version = version.first while version.is_a?(Array) + path.sub!('{version}', version.to_s) + else + path.sub!('/{version}', '') + end + + path = "#{OptionalObject.build(:base_path, options)}#{path}" if options[:add_base_path] + + [item, path.start_with?('/') ? path : "/#{path}"] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/produces_consumes.rb b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/produces_consumes.rb new file mode 100644 index 00000000..5fae277e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/produces_consumes.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module GrapeSwagger + module DocMethods + class ProducesConsumes + class << self + def call(*args) + return ['application/json'] unless args.flatten.present? + + args.flatten.map { |x| GrapeSwagger::CONTENT_TYPE_DEFAULTS[x] || x }.uniq + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/status_codes.rb b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/status_codes.rb new file mode 100644 index 00000000..07967079 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/status_codes.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module GrapeSwagger + module DocMethods + class StatusCodes + class << self + def get + { + get: { code: 200, message: 'get {item}(s)' }, + post: { code: 201, message: 'created {item}' }, + put: { code: 200, message: 'updated {item}' }, + patch: { code: 200, message: 'patched {item}' }, + delete: { code: 200, message: 'deleted {item}' }, + head: { code: 200, message: 'head {item}' }, + options: { code: 200, message: 'option {item}' } + } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/tag_name_description.rb b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/tag_name_description.rb new file mode 100644 index 00000000..b1b17dae --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/tag_name_description.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module GrapeSwagger + module DocMethods + class TagNameDescription + class << self + def build(paths) + paths.values.each_with_object([]) do |path, memo| + tags = path.values.first[:tags] + next if tags.nil? + + case tags + when String + memo << build_memo(tags) + when Array + path.values.first[:tags].each do |tag| + memo << build_memo(tag) + end + end + end.uniq + end + + private + + def build_memo(tag) + { + name: tag, + description: "Operations about #{tag.pluralize}" + } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/version.rb b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/version.rb new file mode 100644 index 00000000..0dbd25eb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/doc_methods/version.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module GrapeSwagger + module DocMethods + class Version + class << self + def get(route) + version = route.version + # for grape version 0.16.2, the version can be a string like '[:v1, :v2]' + # for grape version bigger than 0.16.2, the version can be a array like [:v1, :v2] + if version.is_a?(String) && version.start_with?('[') && version.end_with?(']') + instance_eval(version) + else + version + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/endpoint.rb b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/endpoint.rb new file mode 100644 index 00000000..15509be5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/endpoint.rb @@ -0,0 +1,506 @@ +# frozen_string_literal: true + +require 'active_support' +require 'active_support/core_ext/string/inflections' +require 'grape-swagger/endpoint/params_parser' + +module Grape + class Endpoint # rubocop:disable Metrics/ClassLength + def content_types_for(target_class) + content_types = (target_class.content_types || {}).values + + if content_types.empty? + formats = [target_class.format, target_class.default_format].compact.uniq + formats = GrapeSwagger::FORMATTER_DEFAULTS.keys if formats.empty? + content_types = GrapeSwagger::CONTENT_TYPE_DEFAULTS.select do |content_type, _mime_type| + formats.include? content_type + end.values + end + + content_types.uniq + end + + # swagger spec2.0 related parts + # + # required keys for SwaggerObject + def swagger_object(target_class, request, options) + object = { + info: info_object(options[:info].merge(version: options[:doc_version])), + swagger: '2.0', + produces: options[:produces] || content_types_for(target_class), + consumes: options[:consumes], + authorizations: options[:authorizations], + securityDefinitions: options[:security_definitions], + security: options[:security], + host: GrapeSwagger::DocMethods::OptionalObject.build(:host, options, request), + basePath: GrapeSwagger::DocMethods::OptionalObject.build(:base_path, options, request), + schemes: options[:schemes].is_a?(String) ? [options[:schemes]] : options[:schemes] + } + + GrapeSwagger::DocMethods::Extensions.add_extensions_to_root(options, object) + object.delete_if { |_, value| value.blank? } + end + + # building info object + def info_object(infos) + result = { + title: infos[:title] || 'API title', + description: infos[:description], + termsOfService: infos[:terms_of_service_url], + contact: contact_object(infos), + license: license_object(infos), + version: infos[:version] + } + + GrapeSwagger::DocMethods::Extensions.add_extensions_to_info(infos, result) + + result.delete_if { |_, value| value.blank? } + end + + # sub-objects of info object + # license + def license_object(infos) + { + name: infos.delete(:license), + url: infos.delete(:license_url) + }.delete_if { |_, value| value.blank? } + end + + # contact + def contact_object(infos) + { + name: infos.delete(:contact_name), + email: infos.delete(:contact_email), + url: infos.delete(:contact_url) + }.delete_if { |_, value| value.blank? } + end + + # building path and definitions objects + def path_and_definition_objects(namespace_routes, options) + @paths = {} + @definitions = {} + add_definitions_from options[:models] + namespace_routes.each_value do |routes| + path_item(routes, options) + end + + [@paths, @definitions] + end + + def add_definitions_from(models) + return if models.nil? + + models.each { |x| expose_params_from_model(x) } + end + + # path object + def path_item(routes, options) + routes.each do |route| + next if hidden?(route, options) + + @item, path = GrapeSwagger::DocMethods::PathString.build(route, options) + @entity = route.entity || route.options[:success] + + verb, method_object = method_object(route, options, path) + + if @paths.key?(path.to_s) + @paths[path.to_s][verb] = method_object + else + @paths[path.to_s] = { verb => method_object } + end + + GrapeSwagger::DocMethods::Extensions.add(@paths[path.to_s], @definitions, route) + end + end + + def method_object(route, options, path) + method = {} + method[:summary] = summary_object(route) + method[:description] = description_object(route) + method[:produces] = produces_object(route, options[:produces] || options[:format]) + method[:consumes] = consumes_object(route, options[:consumes] || options[:format]) + method[:parameters] = params_object(route, options, path, method[:consumes]) + method[:security] = security_object(route) + method[:responses] = response_object(route, options) + method[:tags] = route.options.fetch(:tags, tag_object(route, path)) + method[:operationId] = GrapeSwagger::DocMethods::OperationId.build(route, path) + method[:deprecated] = deprecated_object(route) + method.delete_if { |_, value| value.nil? } + + [route.request_method.downcase.to_sym, method] + end + + def deprecated_object(route) + route.options[:deprecated] if route.options.key?(:deprecated) + end + + def security_object(route) + route.options[:security] if route.options.key?(:security) + end + + def summary_object(route) + summary = route.options[:desc] if route.options.key?(:desc) + summary = route.description if route.description.present? && route.options.key?(:detail) + summary = route.options[:summary] if route.options.key?(:summary) + + summary + end + + def description_object(route) + description = route.description if route.description.present? + description = route.options[:detail] if route.options.key?(:detail) + + description + end + + def produces_object(route, format) + return ['application/octet-stream'] if file_response?(route.attributes.success) && + !route.attributes.produces.present? + + mime_types = GrapeSwagger::DocMethods::ProducesConsumes.call(format) + + route_mime_types = %i[formats content_types produces].map do |producer| + possible = route.options[producer] + GrapeSwagger::DocMethods::ProducesConsumes.call(possible) if possible.present? + end.flatten.compact.uniq + + route_mime_types.present? ? route_mime_types : mime_types + end + + SUPPORTS_CONSUMES = %i[post put patch].freeze + + def consumes_object(route, format) + return unless SUPPORTS_CONSUMES.include?(route.request_method.downcase.to_sym) + + GrapeSwagger::DocMethods::ProducesConsumes.call(route.settings.dig(:description, :consumes) || format) + end + + def params_object(route, options, path, consumes) + parameters = build_request_params(route, options).each_with_object([]) do |(param, value), memo| + next if hidden_parameter?(value) + + value = { required: false }.merge(value) if value.is_a?(Hash) + _, value = default_type([[param, value]]).first if value == '' + + if value.dig(:documentation, :type) + expose_params(value[:documentation][:type]) + elsif value[:type] + expose_params(value[:type]) + end + memo << GrapeSwagger::DocMethods::ParseParams.call(param, value, path, route, @definitions, consumes) + end + + if GrapeSwagger::DocMethods::MoveParams.can_be_moved?(route.request_method, parameters) + parameters = GrapeSwagger::DocMethods::MoveParams.to_definition(path, parameters, route, @definitions) + end + + GrapeSwagger::DocMethods::FormatData.to_format(parameters) + + parameters.presence + end + + def response_object(route, options) + codes(route).each_with_object({}) do |value, memo| + value[:message] ||= '' + memo[value[:code]] = { description: value[:message] ||= '' } unless memo[value[:code]].present? + memo[value[:code]][:headers] = value[:headers] if value[:headers] + + next build_file_response(memo[value[:code]]) if file_response?(value[:model]) + + next build_delete_response(memo, value) if delete_response?(memo, route, value) + next build_response_for_type_parameter(memo, route, value, options) if value[:type] + + # Explicitly request no model with { model: '' } + next if value[:model] == '' + + response_model = value[:model] ? expose_params_from_model(value[:model]) : @item + next unless @definitions[response_model] + next if response_model.start_with?('Swagger_doc') + + @definitions[response_model][:description] ||= "#{response_model} model" + build_memo_schema(memo, route, value, response_model, options) + memo[value[:code]][:examples] = value[:examples] if value[:examples] + end + end + + def codes(route) + http_codes_from_route(route).map do |x| + x.is_a?(Array) ? { code: x[0], message: x[1], model: x[2], examples: x[3], headers: x[4] } : x + end + end + + def success_code?(code) + status = code.is_a?(Array) ? code.first : code[:code] + status.between?(200, 299) + end + + def http_codes_from_route(route) + if route.http_codes.is_a?(Array) && route.http_codes.any? { |code| success_code?(code) } + route.http_codes.clone + else + success_codes_from_route(route) + default_code_from_route(route) + + (route.http_codes || route.options[:failure] || []) + end + end + + def success_codes_from_route(route) + if @entity.is_a?(Array) + return @entity.map do |entity| + success_code_from_entity(route, entity) + end + end + + [success_code_from_entity(route, @entity)] + end + + def tag_object(route, path) + version = GrapeSwagger::DocMethods::Version.get(route) + version = Array(version) + prefix = route.prefix.to_s.split('/').reject(&:empty?) + Array( + path.split('{')[0].split('/').reject(&:empty?).delete_if do |i| + prefix.include?(i) || version.map(&:to_s).include?(i) + end.first + ).presence + end + + private + + def default_code_from_route(route) + entity = route.options[:default_response] + return [] if entity.nil? + + default_code = { code: 'default', message: 'Default Response' } + if entity.is_a?(Hash) + default_code[:message] = entity[:message] || default_code[:message] + default_code[:model] = entity[:model] if entity[:model].present? + else + default_code[:model] = entity + end + + [default_code] + end + + def build_delete_response(memo, value) + memo[204] = memo.delete(200) + value[:code] = 204 + end + + def delete_response?(memo, route, value) + memo.key?(200) && route.request_method == 'DELETE' && value[:model].nil? + end + + def build_memo_schema(memo, route, value, response_model, options) + if memo[value[:code]][:schema] && value[:as] + memo[value[:code]][:schema][:properties].merge!(build_reference(route, value, response_model, options)) + + if value[:required] + memo[value[:code]][:schema][:required] ||= [] + memo[value[:code]][:schema][:required] << value[:as].to_s + end + + elsif value[:as] + memo[value[:code]][:schema] = { + type: :object, + properties: build_reference(route, value, response_model, options) + } + memo[value[:code]][:schema][:required] = [value[:as].to_s] if value[:required] + else + memo[value[:code]][:schema] = build_reference(route, value, response_model, options) + end + end + + def build_response_for_type_parameter(memo, _route, value, _options) + type, format = prepare_type_and_format(value) + + if memo[value[:code]].include?(:schema) && value.include?(:as) + memo[value[:code]][:schema][:properties].merge!(value[:as] => { type: type, format: format }.compact) + elsif value.include?(:as) + memo[value[:code]][:schema] = + { type: :object, properties: { value[:as] => { type: type, format: format }.compact } } + else + memo[value[:code]][:schema] = { type: type } + end + end + + def prepare_type_and_format(value) + data_type = GrapeSwagger::DocMethods::DataType.call(value[:type]) + + if GrapeSwagger::DocMethods::DataType.primitive?(data_type) + GrapeSwagger::DocMethods::DataType.mapping(data_type) + else + data_type + end + end + + def build_reference(route, value, response_model, settings) + # TODO: proof that the definition exist, if model isn't specified + reference = if value.key?(:as) + { value[:as] => build_reference_hash(response_model) } + else + build_reference_hash(response_model) + end + return reference unless value[:code] == 'default' || value[:code] < 300 + + if value.key?(:as) && value.key?(:is_array) + reference[value[:as]] = build_reference_array(reference[value[:as]]) + elsif route.options[:is_array] + reference = build_reference_array(reference) + end + + build_root(route, reference, response_model, settings) + end + + def build_reference_hash(response_model) + { '$ref' => "#/definitions/#{response_model}" } + end + + def build_reference_array(reference) + { type: 'array', items: reference } + end + + def build_root(route, reference, response_model, settings) + default_root = response_model.underscore + default_root = default_root.pluralize if route.options[:is_array] + case route.settings.dig(:swagger, :root) + when true + { type: 'object', properties: { default_root => reference } } + when false + reference + when nil + settings[:add_root] ? { type: 'object', properties: { default_root => reference } } : reference + else + { type: 'object', properties: { route.settings.dig(:swagger, :root) => reference } } + end + end + + def file_response?(value) + value.to_s.casecmp('file').zero? + end + + def build_file_response(memo) + memo['schema'] = { type: 'file' } + end + + def build_request_params(route, settings) + required = merge_params(route) + required = GrapeSwagger::DocMethods::Headers.parse(route) + required unless route.headers.nil? + + default_type(required) + + request_params = GrapeSwagger::Endpoint::ParamsParser.parse_request_params(required, settings, self) + + request_params.empty? ? required : request_params + end + + def merge_params(route) + path_params = get_path_params(route.app&.inheritable_setting&.namespace_stackable) + param_keys = route.params.keys + + # Merge path params options into route params + route_params = route.params + route_params.each_key do |key| + path = path_params[key] || {} + params = route_params[key] + params = {} unless params.is_a? Hash + route_params[key] = path.merge(params) + end + + route_params.delete_if { |key| key.is_a?(String) && param_keys.include?(key.to_sym) }.to_a + end + + # Iterates over namespaces recursively + # to build a hash of path params with options, including type + def get_path_params(stackable_values) + params = {} + return param unless stackable_values + return params unless stackable_values.is_a? Grape::Util::StackableValues + + stackable_values&.new_values&.dig(:namespace)&.each do |namespace| # rubocop:disable Style/SafeNavigationChainLength + space = namespace.space.to_s.gsub(':', '') + params[space] = namespace.options || {} + end + inherited_params = get_path_params(stackable_values.inherited_values) + inherited_params.merge(params) + end + + def default_type(params) + default_param_type = { required: true, type: 'Integer' } + params.each { |param| param[-1] = param.last.empty? ? default_param_type : param.last } + end + + def expose_params(value) + if value.is_a?(Class) && GrapeSwagger.model_parsers.find(value) + expose_params_from_model(value) + elsif value.is_a?(String) + begin + expose_params(Object.const_get(value.gsub(/\[|\]/, ''))) # try to load class from its name + rescue NameError + nil + end + end + end + + def expose_params_from_model(model) + model = model.constantize if model.is_a?(String) + model_name = model_name(model) + + return model_name if @definitions.key?(model_name) + + @definitions[model_name] = nil + + parser = GrapeSwagger.model_parsers.find(model) + raise GrapeSwagger::Errors::UnregisteredParser, "No parser registered for #{model_name}." unless parser + + parsed_response = parser.new(model, self).call + + @definitions[model_name] = + GrapeSwagger::DocMethods::BuildModelDefinition.parse_params_from_model(parsed_response, model, model_name) + + model_name + end + + def model_name(name) + GrapeSwagger::DocMethods::DataType.parse_entity_name(name) + end + + def hidden?(route, options) + route_hidden = route.settings.try(:[], :swagger).try(:[], :hidden) + route_hidden = route.options[:hidden] if route.options.key?(:hidden) + return route_hidden unless route_hidden.is_a?(Proc) + + options[:token_owner] ? route_hidden.call(send(options[:token_owner].to_sym)) : route_hidden.call + end + + def hidden_parameter?(value) + return false if value[:required] + + if value.dig(:documentation, :hidden).is_a?(Proc) + value.dig(:documentation, :hidden).call + else + value.dig(:documentation, :hidden) + end + end + + def success_code_from_entity(route, entity) + default_code = GrapeSwagger::DocMethods::StatusCodes.get[route.request_method.downcase.to_sym] + if entity.is_a?(Hash) + default_code[:code] = entity[:code] if entity[:code].present? + default_code[:model] = entity[:model] if entity[:model].present? + default_code[:message] = entity[:message] || route.description || default_code[:message].sub('{item}', @item) + default_code[:examples] = entity[:examples] if entity[:examples] + default_code[:headers] = entity[:headers] if entity[:headers] + default_code[:as] = entity[:as] if entity[:as] + default_code[:is_array] = entity[:is_array] if entity[:is_array] + default_code[:required] = entity[:required] if entity[:required] + default_code[:type] = entity[:type] if entity[:type] + else + default_code = GrapeSwagger::DocMethods::StatusCodes.get[route.request_method.downcase.to_sym] + default_code[:model] = entity if entity + default_code[:message] = route.description || default_code[:message].sub('{item}', @item) + end + + default_code + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/endpoint/params_parser.rb b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/endpoint/params_parser.rb new file mode 100644 index 00000000..1d038151 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/endpoint/params_parser.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true + +module GrapeSwagger + module Endpoint + class ParamsParser + attr_reader :params, :settings, :endpoint + + def self.parse_request_params(params, settings, endpoint) + new(params, settings, endpoint).parse_request_params + end + + def initialize(params, settings, endpoint) + @params = params + @settings = settings + @endpoint = endpoint + end + + def parse_request_params + public_params.each_with_object({}) do |(name, options), memo| + name = name.to_s + param_type = options[:type] + param_type = param_type.to_s unless param_type.nil? + + if param_type_is_array?(param_type) + options[:is_array] = true + name += '[]' if array_use_braces? + end + + memo[name] = options + end + end + + private + + def array_use_braces? + @array_use_braces ||= settings[:array_use_braces] && !includes_body_param? + end + + def param_type_is_array?(param_type) + return false unless param_type + return true if param_type == 'Array' + + param_types = param_type.match(/\[(.*)\]$/) + return false unless param_types + + param_types = param_types[0].split(',') if param_types + param_types.size == 1 + end + + def public_params + params.select { |param| public_parameter?(param) } + end + + def public_parameter?(param) + param_options = param.last + return true unless param_options.key?(:documentation) && !param_options[:required] + + param_hidden = param_options[:documentation].fetch(:hidden, false) + if param_hidden.is_a?(Proc) + param_hidden = if settings[:token_owner] + param_hidden.call(endpoint.send(settings[:token_owner].to_sym)) + else + param_hidden.call + end + end + !param_hidden + end + + def includes_body_param? + params.any? do |_, options| + options.dig(:documentation, :param_type) == 'body' || options.dig(:documentation, :in) == 'body' + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/errors.rb b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/errors.rb new file mode 100644 index 00000000..b4781699 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/errors.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module GrapeSwagger + module Errors + class UnregisteredParser < StandardError; end + + class SwaggerSpec < StandardError; end + + class SwaggerSpecDeprecated < SwaggerSpec + class << self + def tell!(what) + warn "[GrapeSwagger] usage of #{what} is deprecated" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/instance.rb b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/instance.rb new file mode 100644 index 00000000..cf1a8a0b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/instance.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +GrapeInstance = if defined? Grape::API::Instance + Grape::API::Instance + else + Grape::API + end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/model_parsers.rb b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/model_parsers.rb new file mode 100644 index 00000000..2c46c78a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/model_parsers.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +module GrapeSwagger + class ModelParsers + include Enumerable + + def initialize + @parsers = {} + end + + def register(klass, ancestor) + @parsers[klass] = ancestor.to_s + end + + def insert_before(before_klass, klass, ancestor) + subhash = @parsers.except(klass).to_a + insert_at = subhash.index(subhash.assoc(before_klass)) + insert_at = subhash.length - 1 if insert_at.nil? + @parsers = subhash.insert(insert_at, [klass, ancestor]).to_h + end + + def insert_after(after_klass, klass, ancestor) + subhash = @parsers.except(klass).to_a + insert_at = subhash.index(subhash.assoc(after_klass)) + insert_at = subhash.length - 1 if insert_at.nil? + @parsers = subhash.insert(insert_at + 1, [klass, ancestor]).to_h + end + + def each + @parsers.each_pair do |klass, ancestor| + yield klass, ancestor + end + end + + def find(model) + GrapeSwagger.model_parsers.each do |klass, ancestor| + return klass if model.ancestors.map(&:to_s).include?(ancestor) + end + nil + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/rake/oapi_tasks.rb b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/rake/oapi_tasks.rb new file mode 100644 index 00000000..feea84a2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/rake/oapi_tasks.rb @@ -0,0 +1,135 @@ +# frozen_string_literal: true + +require 'rake' +require 'rake/tasklib' +require 'rack/test' + +module GrapeSwagger + module Rake + class OapiTasks < ::Rake::TaskLib + include Rack::Test::Methods + + attr_reader :oapi + + def initialize(api_class) + super() + + if api_class.is_a? String + @api_class_name = api_class + else + @api_class = api_class + end + + define_tasks + end + + private + + def api_class + @api_class ||= @api_class_name.constantize + end + + def define_tasks + namespace :oapi do + fetch + validate + end + end + + # tasks + # + # get swagger/OpenAPI documentation + def fetch + desc 'generates OpenApi documentation … + params (usage: key=value): + store – save as JSON file, default: false (optional) + resource - if given only for that it would be generated (optional)' + task fetch: :environment do + # :nocov: + urls_for(api_class).each do |url| + make_request(url) + + save_to_file? ? File.write(file(url), @oapi) : $stdout.print(@oapi) + end + + # :nocov: + end + end + + # validates swagger/OpenAPI documentation + def validate + desc 'validates the generated OpenApi file … + params (usage: key=value): + resource - if given only for that it would be generated (optional)' + task validate: :environment do + # :nocov: + ENV.store('store', 'true') + ::Rake::Task['oapi:fetch'].invoke + exit if error? + + urls_for(api_class).each do |url| + @output = system "swagger-cli validate #{file(url)}" + + FileUtils.rm( + file(url) + ) + end + + $stdout.puts 'install swagger-cli with `npm install swagger-cli -g`' if @output.nil? + # :nocov: + end + end + + # helper methods + # + # rubocop:disable Style/StringConcatenation + def make_request(url) + get url + + @oapi = JSON.pretty_generate( + JSON.parse(last_response.body, symbolize_names: true) + ) + "\n" + end + # rubocop:enable Style/StringConcatenation + + def urls_for(api_class) + api_class.routes + .map(&:path) + .grep(/#{GrapeSwagger::DocMethods.class_variable_get(:@@mount_path)}/) + .reject { |e| e.include?(':name') } + .map { |e| format_path(e) } + .map { |e| [e, ENV.fetch('resource', nil)].join('/').chomp('/') } + end + + def format_path(path) + oapi_route = api_class.routes.select { |e| e.path == path }.first + path = path.sub(/\(\.\w+\)$/, '').sub(/\(\.:\w+\)$/, '') + path.sub(':version', oapi_route.version.to_s) + end + + def save_to_file? + ENV.fetch('store', nil).present? && !error? + end + + def error? + JSON.parse(@oapi).keys.first == 'error' + end + + def file(url) + api_version = url.split('/').last + + name = if ENV.fetch('store', nil) == 'true' || ENV.fetch('store', nil).blank? + "swagger_doc_#{api_version}.json" + else + ENV.fetch('store').sub('.json', "_#{api_version}.json") + end + + File.join(Dir.getwd, name) + end + + def app + api_class.new + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/version.rb b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/version.rb new file mode 100644 index 00000000..c37c043d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/grape-swagger-2.1.2/lib/grape-swagger/version.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +module GrapeSwagger + VERSION = '2.1.2' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/.github/workflows/ci.yml b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/.github/workflows/ci.yml new file mode 100644 index 00000000..fc3d489f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/.github/workflows/ci.yml @@ -0,0 +1,27 @@ +name: ci + +on: + - pull_request + - push + +jobs: + build: + strategy: + fail-fast: false + matrix: + ruby: + - 2.7 + - '3.0' + - 3.1 + - 3.2 + - 3.3 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + bundler-cache: true # 'bundle install' and cache gems + - name: Run rake + run: bundle exec rake diff --git a/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/.gitignore b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/.gitignore new file mode 100644 index 00000000..134a8706 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/.gitignore @@ -0,0 +1,15 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. +# +# If you find yourself ignoring temporary files generated by your text editor +# or operating system, you probably want to add a global ignore instead: +# git config --global core.excludesfile ~/.gitignore_global + +# Ignore bundler config +/.bundle +/doc +/.yardoc +/Gemfile.lock + +*.swp +*.bak +*.gem diff --git a/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/.rspec b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/.rspec new file mode 100644 index 00000000..4e1e0d2f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/.rspec @@ -0,0 +1 @@ +--color diff --git a/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/.rubocop.yml b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/.rubocop.yml new file mode 100644 index 00000000..7668a83e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/.rubocop.yml @@ -0,0 +1,42 @@ +require: rubocop-rspec +AllCops: + TargetRubyVersion: 2.0 # always the lowest version we support +Metrics/PerceivedComplexity: + Enabled: false +Metrics/CyclomaticComplexity: + Enabled: false +Metrics/MethodLength: + Enabled: false +Metrics/AbcSize: + Enabled: false +Layout/LineLength: + Enabled: false +Metrics/ClassLength: + Enabled: false +Metrics/BlockLength: + Enabled: false +Metrics/ModuleLength: + Enabled: false +Style/CaseLikeIf: + Enabled: false +Style/Documentation: + Enabled: false +Style/FrozenStringLiteralComment: + Enabled: true + EnforcedStyle: always +Style/OptionalBooleanParameter: + Enabled: false +Style/NumericPredicate: + Enabled: false +Style/RedundantFreeze: + Enabled: false +Style/RedundantReturn: + Enabled: false +RSpec/ExampleLength: + Enabled: false +RSpec/DescribeClass: + Enabled: false +RSpec/SpecFilePathFormat: + Enabled: false +RSpec/NoExpectationExample: + Enabled: false diff --git a/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/.travis.yml b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/.travis.yml new file mode 100644 index 00000000..3386da20 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/.travis.yml @@ -0,0 +1,11 @@ +sudo: false +language: ruby +cache: bundler +rvm: + - 2.0.0 + - 2.1.10 + - 2.2.8 + - 2.3.4 + - 2.4.2 + - 2.5.3 + - 2.6.0 diff --git a/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/.yardopts b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/.yardopts new file mode 100644 index 00000000..22ce944f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/.yardopts @@ -0,0 +1 @@ +--no-private diff --git a/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/Gemfile b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/Gemfile new file mode 100644 index 00000000..2dce3e5e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/Gemfile @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +source 'http://rubygems.org' +gemspec + +group :test do + gem 'rake' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/LICENSE b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/LICENSE new file mode 100644 index 00000000..9adfb9dd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2012 Liu Fengyun + +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 +AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/README.md b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/README.md new file mode 100644 index 00000000..b0ac0720 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/README.md @@ -0,0 +1,323 @@ +# Hashdiff [![Build Status](https://github.com/liufengyun/hashdiff/workflows/ci/badge.svg)](https://github.com/liufengyun/hashdiff/actions?query=workflow%3Aci) [![Gem Version](https://badge.fury.io/rb/hashdiff.svg)](http://badge.fury.io/rb/hashdiff) + +Hashdiff is a ruby library to compute the smallest difference between two hashes. + +It also supports comparing two arrays. + +Hashdiff does not monkey-patch any existing class. All features are contained inside the `Hashdiff` module. + +**Docs**: [Documentation](http://rubydoc.info/gems/hashdiff) + + +__WARNING__: Don't use the library for comparing large arrays, say ~10K (see #49). + +## Why Hashdiff? + +Given two Hashes A and B, sometimes you face the question: what's the smallest modification that can be made to change A into B? + +An algorithm that responds to this question has to do following: + +* Generate a list of additions, deletions and changes, so that `A + ChangeSet = B` and `B - ChangeSet = A`. +* Compute recursively -- Arrays and Hashes may be nested arbitrarily in A or B. +* Compute the smallest change -- it should recognize similar child Hashes or child Arrays between A and B. + +Hashdiff answers the question above using an opinionated approach: + +* Hash can be represented as a list of (dot-syntax-path, value) pairs. For example, `{a:[{c:2}]}` can be represented as `["a[0].c", 2]`. +* The change set can be represented using the dot-syntax representation. For example, `[['-', 'b.x', 3], ['~', 'b.z', 45, 30], ['+', 'b.y', 3]]`. +* It compares Arrays using the [LCS(longest common subsequence)](http://en.wikipedia.org/wiki/Longest_common_subsequence_problem) algorithm. +* It recognizes similar Hashes in an Array using a similarity value (0 < similarity <= 1). + +## Usage + +To use the gem, add the following to your Gemfile: + +```Ruby +gem 'hashdiff' +``` + +## Quick Start + +### Diff + +Two simple hashes: + +```ruby +a = {a:3, b:2} +b = {} + +diff = Hashdiff.diff(a, b) +diff.should == [['-', 'a', 3], ['-', 'b', 2]] +``` + +More complex hashes: + +```ruby +a = {a:{x:2, y:3, z:4}, b:{x:3, z:45}} +b = {a:{y:3}, b:{y:3, z:30}} + +diff = Hashdiff.diff(a, b) +diff.should == [['-', 'a.x', 2], ['-', 'a.z', 4], ['-', 'b.x', 3], ['~', 'b.z', 45, 30], ['+', 'b.y', 3]] +``` + +Arrays in hashes: + +```ruby +a = {a:[{x:2, y:3, z:4}, {x:11, y:22, z:33}], b:{x:3, z:45}} +b = {a:[{y:3}, {x:11, z:33}], b:{y:22}} + +diff = Hashdiff.best_diff(a, b) +diff.should == [['-', 'a[0].x', 2], ['-', 'a[0].z', 4], ['-', 'a[1].y', 22], ['-', 'b.x', 3], ['-', 'b.z', 45], ['+', 'b.y', 22]] +``` + +### Patch + +patch example: + +```ruby +a = {'a' => 3} +b = {'a' => {'a1' => 1, 'a2' => 2}} + +diff = Hashdiff.diff(a, b) +Hashdiff.patch!(a, diff).should == b +``` + +unpatch example: + +```ruby +a = [{'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5}, {'x' => 5, 'y' => 6, 'z' => 3}, 1] +b = [1, {'a' => 1, 'b' => 2, 'c' => 3, 'e' => 5}] + +diff = Hashdiff.diff(a, b) # diff two array is OK +Hashdiff.unpatch!(b, diff).should == a +``` + +### Options + +The following options are available: `:delimiter`, `:similarity`, `:strict`, `:ignore_keys`, +`:indifferent`, `:numeric_tolerance`, `:strip`, `:case_insensitive`, `:array_path`, +`:use_lcs`, and `:preserve_key_order` + +#### `:delimiter` + +You can specify `:delimiter` to be something other than the default dot. For example: + +```ruby +a = {a:{x:2, y:3, z:4}, b:{x:3, z:45}} +b = {a:{y:3}, b:{y:3, z:30}} + +diff = Hashdiff.diff(a, b, delimiter: '\t') +diff.should == [['-', 'a\tx', 2], ['-', 'a\tz', 4], ['-', 'b\tx', 3], ['~', 'b\tz', 45, 30], ['+', 'b\ty', 3]] +``` + +#### `:similarity` + +In cases where you have similar hash objects in arrays, you can pass a custom value for `:similarity` instead of the default `0.8`. This is interpreted as a ratio of similarity (default is 80% similar, whereas `:similarity => 0.5` would look for at least a 50% similarity). + +#### `:strict` + +The `:strict` option, which defaults to `true`, specifies whether numeric types are compared on type as well as value. By default, an Integer will never be equal to a Float (e.g. 4 != 4.0). Setting `:strict` to false makes the comparison looser (e.g. 4 == 4.0). + +#### `:ignore_keys` + +The `:ignore_keys` option allows you to specify one or more keys to ignore, which defaults to `[]` (none). Ignored keys are ignored at all levels in both hashes. For example: + +```ruby +a = { a: 4, g: 0, b: { a: 5, c: 6, e: 1 } } +b = { b: { a: 7, c: 3, f: 1 }, d: 8 } +diff = Hashdiff.diff(a, b, ignore_keys: %i[a f]) +diff.should == [['-', 'g', 0], ['-', 'b.e', 1], ['~', 'b.c', 6, 3], ['+', 'd', 8]] +``` +If you wish instead to ignore keys at a particlar level you should +use a [custom comparison method](https://github.com/liufengyun/hashdiff#specifying-a-custom-comparison-method) instead. For example to diff only at the 2nd level of both hashes: + +```ruby +a = { a: 4, g: 0, b: { a: 5, c: 6, e: 1 } } +b = { b: { a: 7, c: 3, f: 1 }, d: 8 } +diff = Hashdiff.diff(a, b) do |path, _e, _a| + arr = path.split('.') + true if %w[a f].include?(arr.last) && arr.size == 2 # note '.' is the default delimiter +end +diff.should == [['-', 'a', 4], ['-', 'g', 0], ['-', 'b.e', 1], ['~', 'b.c', 6, 3], ['+', 'd', 8]] +``` + +#### `:indifferent` + +The `:indifferent` option, which defaults to `false`, specifies whether to treat hash keys indifferently. Setting `:indifferent` to true has the effect of ignoring differences between symbol keys (ie. {a: 1} ~= {'a' => 1}) + +#### `:numeric_tolerance` + +The :numeric_tolerance option allows for a small numeric tolerance. + +```ruby +a = {x:5, y:3.75, z:7} +b = {x:6, y:3.76, z:7} + +diff = Hashdiff.diff(a, b, numeric_tolerance: 0.1) +diff.should == [["~", "x", 5, 6]] +``` + +#### `:strip` + +The :strip option strips all strings before comparing. + +```ruby +a = {x:5, s:'foo '} +b = {x:6, s:'foo'} + +diff = Hashdiff.diff(a, b, numeric_tolerance: 0.1, strip: true) +diff.should == [["~", "x", 5, 6]] +``` + +#### `:case_insensitive` + +The :case_insensitive option makes string comparisons ignore case. + +```ruby +a = {x:5, s:'FooBar'} +b = {x:6, s:'foobar'} + +diff = Hashdiff.diff(a, b, numeric_tolerance: 0.1, case_insensitive: true) +diff.should == [["~", "x", 5, 6]] +``` + +#### `:array_path` + +The :array_path option represents the path of the diff in an array rather than +a string. This can be used to show differences in between hash key types and +is useful for `patch!` when used on hashes without string keys. + +```ruby +a = {x:5} +b = {'x'=>6} + +diff = Hashdiff.diff(a, b, array_path: true) +diff.should == [['-', [:x], 5], ['+', ['x'], 6]] +``` + +For cases where there are arrays in paths their index will be added to the path. +```ruby +a = {x:[0,1]} +b = {x:[0,2]} + +diff = Hashdiff.diff(a, b, array_path: true) +diff.should == [["-", [:x, 1], 1], ["+", [:x, 1], 2]] +``` + +This shouldn't cause problems if you are comparing an array with a hash: + +```ruby +a = {x:{0=>1}} +b = {x:[1]} + +diff = Hashdiff.diff(a, b, array_path: true) +diff.should == [["~", [:x], {0=>1}, [1]]] +``` + +#### `:use_lcs` + +The :use_lcs option is used to specify whether a +[Longest common subsequence](https://en.wikipedia.org/wiki/Longest_common_subsequence_problem) +(LCS) algorithm is used to determine differences in arrays. This defaults to +`true` but can be changed to `false` for significantly faster array comparisons +(O(n) complexity rather than O(n2) for LCS). + +When :use_lcs is false the results of array comparisons have a tendency to +show changes at indexes rather than additions and subtractions when :use_lcs is +true. + +Note, currently the :similarity option has no effect when :use_lcs is false. + +```ruby +a = {x: [0, 1, 2]} +b = {x: [0, 2, 2, 3]} + +diff = Hashdiff.diff(a, b, use_lcs: false) +diff.should == [["~", "x[1]", 1, 2], ["+", "x[3]", 3]] +``` + +#### `:preserve_key_order` + +By default, the change set is ordered by operation type: deletions (-) first, then updates (~), and finally additions (+). +Within each operation group, keys are sorted alphabetically: + +```ruby +a = {d: 1, c: 1, a: 1} +b = {d: 2, b: 2, a: 2} + +diff = Hashdiff.diff(a, b) +diff.should == [["-", "c", 1], ["~", "a", 1, 2], ["~", "d", 1, 2], ["+", "b", 2]] +``` + +Setting :preserve_key_order to true processes keys in the order they appear in the first hash. +Keys that only exist in the second hash are appended in their original order: + +```ruby +a = {d: 1, c: 1, a: 1} +b = {d: 2, b: 2, a: 2} + +diff = Hashdiff.diff(a, b, preserve_key_order: true) +diff.should == [["~", "d", 1, 2], ["-", "c", 1], ["~", "a", 1, 2], ["+", "b", 2]] +``` + +#### Specifying a custom comparison method + +It's possible to specify how the values of a key should be compared. + +```ruby +a = {a:'car', b:'boat', c:'plane'} +b = {a:'bus', b:'truck', c:' plan'} + +diff = Hashdiff.diff(a, b) do |path, obj1, obj2| + case path + when /a|b|c/ + obj1.length == obj2.length + end +end + +diff.should == [['~', 'b', 'boat', 'truck']] +``` + +The yielded params of the comparison block is `|path, obj1, obj2|`, in which path is the key (or delimited compound key) to the value being compared. When comparing elements in array, the path is with the format `array[*]`. For example: + +```ruby +a = {a:'car', b:['boat', 'plane'] } +b = {a:'bus', b:['truck', ' plan'] } + +diff = Hashdiff.diff(a, b) do |path, obj1, obj2| + case path + when 'b[*]' + obj1.length == obj2.length + end +end + +diff.should == [["~", "a", "car", "bus"], ["~", "b[1]", "plane", " plan"], ["-", "b[0]", "boat"], ["+", "b[0]", "truck"]] +``` + +When a comparison block is given, it'll be given priority over other specified options. If the block returns value other than `true` or `false`, then the two values will be compared with other specified options. + +When used in conjunction with the `array_path` option, the path passed in as an argument will be an array. When determining the ordering of an array a key of `"*"` will be used in place of the `key[*]` field. It is possible, if you have hashes with integer or `"*"` keys, to have problems distinguishing between arrays and hashes - although this shouldn't be an issue unless your data is very difficult to predict and/or your custom rules are very specific. + +#### Sorting arrays before comparison + +An order difference alone between two arrays can create too many diffs to be useful. Consider sorting them prior to diffing. + +```ruby +a = {a:'car', b:['boat', 'plane'] } +b = {a:'car', b:['plane', 'boat'] } + +Hashdiff.diff(a, b).should == [["+", "b[0]", "plane"], ["-", "b[2]", "plane"]] + +b[:b].sort! + +Hashdiff.diff(a, b).should == [] +``` + +## Maintainers + +- Krzysztof Rybka ([@krzysiek1507](https://github.com/krzysiek1507)) +- Fengyun Liu ([@liufengyun](https://github.com/liufengyun)) + +## License + +Hashdiff is distributed under the MIT-LICENSE. diff --git a/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/Rakefile b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/Rakefile new file mode 100644 index 00000000..b78b4a2b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/Rakefile @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +$LOAD_PATH.push File.expand_path('lib', __dir__) + +require 'rubocop/rake_task' + +require 'bundler' +Bundler::GemHelper.install_tasks + +require 'rspec/core/rake_task' + +RuboCop::RakeTask.new + +task default: %w[spec rubocop] + +RSpec::Core::RakeTask.new(:spec) do |spec| + spec.pattern = './spec/**/*_spec.rb' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/changelog.md b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/changelog.md new file mode 100644 index 00000000..c96140dc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/changelog.md @@ -0,0 +1,123 @@ +# Change Log + +## v1.2.0 2025-5-20 + +* Added :preserve_key_order option to maintain original hash key order #99 (@robkiessling) + +## v1.1.2 2024-11-12 + +* Fix bundler cache #96 (@olleolleolle) +* Quote the '3.0' in YAML #95 (@olleolleolle) +* Fix version in source code #97 (@liufengyun) + +## v1.1.1 2024-08-02 + +* Fix bug in ignore_keys option #88 (@Matzfan) +* Exclude spec files from gem package #94 (@amatsuda) + +## v1.1.0 2023-12-14 + +* Add ignore_keys option (#86 @Matzfan) +* Remove pinned version of rake < 11 +* Bump rspec dep ~> 3.5 +* Bump rubocop dep >= 1.52.1 +* Bump rubocop-rspec dep > 1.16.0 + +## v1.0.1 2020-02-25 + +* Add indifferent option + +## v1.0.0 2019-06-06 + +* Fix typo in readme (#72 @koic) +* Fix Rubocop offence (#73 @koic) +* Bumps version to v1.0.0 (#74 @jfelchner) + +## v1.0.0.beta1 2019-06-06 + +* fix warnings in ci (#69 @y-yagi) +* drop warnings of the constant change (#70 @jfelchner) + +## v0.4.0 2019-05-28 + +* refactoring (#56 #57 #59 #61 krzysiek1507) +* fix typo in README (#64 @pboling) +* change HashDiff to Hashdiff (#65 @jfelchner) + +## v0.3.9 2019-04-22 + +* Performance tweak (thanks @krzysiek1507: #51 #52 #53) + +## v0.3.8 2018-12-30 + +* Add Rubocop and drops Ruby 1.9 support #47 + +## v0.3.7 2017-10-08 + +* remove 1.8.7 support from gemspec #39 + +## v0.3.6 2017-08-22 + +* add option `use_lcs` #35 + +## v0.3.5 2017-08-06 + +* add option `array_path` #34 + +## v0.3.4 2017-05-01 + +* performance improvement of `#similar?` #31 + +## v0.3.2 2016-12-27 + +* replace `Fixnum` by `Integer` #28 + +## v0.3.1 2016-11-24 + +* fix an error when a hash has mixed types #26 + +## v0.3.0 2016-2-11 + +* support `:case_insensitive` option + +## v0.2.3 2015-11-5 + +* improve performance of LCS algorithm #12 + +## v0.2.2 2014-10-6 + +* make library 1.8.7 compatible + +## v0.2.1 2014-7-13 + +* yield added/deleted keys for custom comparison + +## v0.2.0 2014-3-29 + +* support custom comparison blocks +* support `:strip`, `:numeric_tolerance` and `:strict` options + +## v0.1.0 2013-8-25 + +* use options for parameters `:delimiter` and `:similarity` in interfaces + +## v0.0.6 2013-3-2 + +* Add parameter for custom property-path delimiter. + +## v0.0.5 2012-7-1 + +* fix a bug in judging whehter two objects are similiar. +* add more spec test for `.best_diff` + +## v0.0.4 2012-6-24 + +Main changes in this version is to output the whole object in addition & deletion, instead of recursely add/deletes the object. + +For example, `diff({a:2, c:[4, 5]}, {a:2}) will generate following output: + + [['-', 'c', [4, 5]]] + +instead of following: + + [['-', 'c[0]', 4], ['-', 'c[1]', 5], ['-', 'c', []]] diff --git a/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/hashdiff.gemspec b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/hashdiff.gemspec new file mode 100644 index 00000000..001af536 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/hashdiff.gemspec @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +$LOAD_PATH << File.expand_path('lib', __dir__) +require 'hashdiff/version' + +Gem::Specification.new do |s| + s.name = 'hashdiff' + s.version = Hashdiff::VERSION + s.license = 'MIT' + s.summary = ' Hashdiff is a diff lib to compute the smallest difference between two hashes. ' + s.description = ' Hashdiff is a diff lib to compute the smallest difference between two hashes. ' + + s.files = `git ls-files`.split("\n").grep_v(%r{^spec/}) + s.test_files = `git ls-files -- Appraisals {spec}/*`.split("\n") + + s.require_paths = ['lib'] + s.required_ruby_version = Gem::Requirement.new('>= 2.0.0') + + s.authors = ['Liu Fengyun'] + s.email = ['liufengyunchina@gmail.com'] + + s.homepage = 'https://github.com/liufengyun/hashdiff' + + s.add_development_dependency('bluecloth') + s.add_development_dependency('rspec', '~> 3.5') + s.add_development_dependency('rubocop', '>= 1.52.1') # earliest version that works with Ruby 3.3 + s.add_development_dependency('rubocop-rspec', '> 1.16.0') # https://github.com/rubocop/rubocop-rspec/issues/461 + s.add_development_dependency('yard') + + if s.respond_to?(:metadata) + s.metadata = { + 'bug_tracker_uri' => 'https://github.com/liufengyun/hashdiff/issues', + 'changelog_uri' => 'https://github.com/liufengyun/hashdiff/blob/master/changelog.md', + 'documentation_uri' => 'https://www.rubydoc.info/gems/hashdiff', + 'homepage_uri' => 'https://github.com/liufengyun/hashdiff', + 'source_code_uri' => 'https://github.com/liufengyun/hashdiff' + } + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff.rb b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff.rb new file mode 100644 index 00000000..d44deb38 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require 'hashdiff/util' +require 'hashdiff/compare_hashes' +require 'hashdiff/lcs' +require 'hashdiff/lcs_compare_arrays' +require 'hashdiff/linear_compare_array' +require 'hashdiff/diff' +require 'hashdiff/patch' +require 'hashdiff/version' diff --git a/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff/compare_hashes.rb b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff/compare_hashes.rb new file mode 100644 index 00000000..64228953 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff/compare_hashes.rb @@ -0,0 +1,101 @@ +# frozen_string_literal: true + +module Hashdiff + # @private + # Used to compare hashes + class CompareHashes + class << self + def call(obj1, obj2, opts = {}) + return [] if obj1.empty? && obj2.empty? + + obj1_keys = obj1.keys + obj2_keys = obj2.keys + obj1_lookup = {} + obj2_lookup = {} + + if opts[:indifferent] + obj1_lookup = obj1_keys.each_with_object({}) { |k, h| h[k.to_s] = k } + obj2_lookup = obj2_keys.each_with_object({}) { |k, h| h[k.to_s] = k } + obj1_keys = obj1_keys.map { |k| k.is_a?(Symbol) ? k.to_s : k } + obj2_keys = obj2_keys.map { |k| k.is_a?(Symbol) ? k.to_s : k } + end + + added_keys = obj2_keys - obj1_keys + common_keys = obj1_keys & obj2_keys + deleted_keys = obj1_keys - obj2_keys + + result = [] + + opts[:ignore_keys].each do |k| + added_keys.delete k + common_keys.delete k + deleted_keys.delete k + end + + handle_key = lambda do |k, type| + case type + when :deleted + # add deleted properties + k = opts[:indifferent] ? obj1_lookup[k] : k + change_key = Hashdiff.prefix_append_key(opts[:prefix], k, opts) + custom_result = Hashdiff.custom_compare(opts[:comparison], change_key, obj1[k], nil) + + if custom_result + result.concat(custom_result) + else + result << ['-', change_key, obj1[k]] + end + when :common + # recursive comparison for common keys + prefix = Hashdiff.prefix_append_key(opts[:prefix], k, opts) + + k1 = opts[:indifferent] ? obj1_lookup[k] : k + k2 = opts[:indifferent] ? obj2_lookup[k] : k + result.concat(Hashdiff.diff(obj1[k1], obj2[k2], opts.merge(prefix: prefix))) + when :added + # added properties + change_key = Hashdiff.prefix_append_key(opts[:prefix], k, opts) + + k = opts[:indifferent] ? obj2_lookup[k] : k + custom_result = Hashdiff.custom_compare(opts[:comparison], change_key, nil, obj2[k]) + + if custom_result + result.concat(custom_result) + else + result << ['+', change_key, obj2[k]] + end + else + raise "Invalid type: #{type}" + end + end + + if opts[:preserve_key_order] + # Building lookups to speed up key classification + added_keys_lookup = added_keys.each_with_object({}) { |k, h| h[k] = true } + common_keys_lookup = common_keys.each_with_object({}) { |k, h| h[k] = true } + deleted_keys_lookup = deleted_keys.each_with_object({}) { |k, h| h[k] = true } + + # Iterate through all keys, preserving obj1's key order and appending any new keys from obj2. Shared keys + # (found in both obj1 and obj2) follow obj1's order since uniq only keeps the first occurrence. + (obj1_keys + obj2_keys).uniq.each do |k| + if added_keys_lookup[k] + handle_key.call(k, :added) + elsif common_keys_lookup[k] + handle_key.call(k, :common) + elsif deleted_keys_lookup[k] + handle_key.call(k, :deleted) + end + end + else + # Keys are first grouped by operation type (deletions first, then changes, then additions), and then sorted + # alphabetically within each group. + deleted_keys.sort_by(&:to_s).each { |k| handle_key.call(k, :deleted) } + common_keys.sort_by(&:to_s).each { |k| handle_key.call(k, :common) } + added_keys.sort_by(&:to_s).each { |k| handle_key.call(k, :added) } + end + + result + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff/diff.rb b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff/diff.rb new file mode 100644 index 00000000..8e24d16a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff/diff.rb @@ -0,0 +1,185 @@ +# frozen_string_literal: true + +module Hashdiff + # Best diff two objects, which tries to generate the smallest change set using different similarity values. + # + # Hashdiff.best_diff is useful in case of comparing two objects which include similar hashes in arrays. + # + # @param [Array, Hash] obj1 + # @param [Array, Hash] obj2 + # @param [Hash] options the options to use when comparing + # * :strict (Boolean) [true] whether numeric values will be compared on type as well as value. Set to false to allow comparing Integer, Float, BigDecimal to each other + # * :ignore_keys (Symbol, String or Array) [[]] a list of keys to ignore. No comparison is made for the specified key(s) in either hash + # * :indifferent (Boolean) [false] whether to treat hash keys indifferently. Set to true to ignore differences between symbol keys (ie. {a: 1} ~= {'a' => 1}) + # * :delimiter (String) ['.'] the delimiter used when returning nested key references + # * :numeric_tolerance (Numeric) [0] should be a positive numeric value. Value by which numeric differences must be greater than. By default, numeric values are compared exactly; with the :tolerance option, the difference between numeric values must be greater than the given value. + # * :strip (Boolean) [false] whether or not to call #strip on strings before comparing + # * :array_path (Boolean) [false] whether to return the path references for nested values in an array, can be used for patch compatibility with non string keys. + # * :use_lcs (Boolean) [true] whether or not to use an implementation of the Longest common subsequence algorithm for comparing arrays, produces better diffs but is slower. + # * :preserve_key_order (Boolean) [false] If false, operations are grouped by type (-, ~, then +) then by hash key alphabetically. If true, preserves the original key order from the first hash and appends new keys from the second hash in order. + # + # @yield [path, value1, value2] Optional block is used to compare each value, instead of default #==. If the block returns value other than true of false, then other specified comparison options will be used to do the comparison. + # + # @return [Array] an array of changes. + # e.g. [[ '+', 'a.b', '45' ], [ '-', 'a.c', '5' ], [ '~', 'a.x', '45', '63']] + # + # @example + # a = {'x' => [{'a' => 1, 'c' => 3, 'e' => 5}, {'y' => 3}]} + # b = {'x' => [{'a' => 1, 'b' => 2, 'e' => 5}] } + # diff = Hashdiff.best_diff(a, b) + # diff.should == [['-', 'x[0].c', 3], ['+', 'x[0].b', 2], ['-', 'x[1].y', 3], ['-', 'x[1]', {}]] + # + # @since 0.0.1 + def self.best_diff(obj1, obj2, options = {}, &block) + options[:comparison] = block if block_given? + + opts = { similarity: 0.3 }.merge!(options) + diffs1 = diff(obj1, obj2, opts) + count1 = count_diff diffs1 + + opts = { similarity: 0.5 }.merge!(options) + diffs2 = diff(obj1, obj2, opts) + count2 = count_diff diffs2 + + opts = { similarity: 0.8 }.merge!(options) + diffs3 = diff(obj1, obj2, opts) + count3 = count_diff diffs3 + + count, diffs = count1 < count2 ? [count1, diffs1] : [count2, diffs2] + count < count3 ? diffs : diffs3 + end + + # Compute the diff of two hashes or arrays + # + # @param [Array, Hash] obj1 + # @param [Array, Hash] obj2 + # @param [Hash] options the options to use when comparing + # * :strict (Boolean) [true] whether numeric values will be compared on type as well as value. Set to false to allow comparing Integer, Float, BigDecimal to each other + # * :ignore_keys (Symbol, String or Array) [[]] a list of keys to ignore. No comparison is made for the specified key(s) in either hash + # * :indifferent (Boolean) [false] whether to treat hash keys indifferently. Set to true to ignore differences between symbol keys (ie. {a: 1} ~= {'a' => 1}) + # * :similarity (Numeric) [0.8] should be between (0, 1]. Meaningful if there are similar hashes in arrays. See {best_diff}. + # * :delimiter (String) ['.'] the delimiter used when returning nested key references + # * :numeric_tolerance (Numeric) [0] should be a positive numeric value. Value by which numeric differences must be greater than. By default, numeric values are compared exactly; with the :tolerance option, the difference between numeric values must be greater than the given value. + # * :strip (Boolean) [false] whether or not to call #strip on strings before comparing + # * :array_path (Boolean) [false] whether to return the path references for nested values in an array, can be used for patch compatibility with non string keys. + # * :use_lcs (Boolean) [true] whether or not to use an implementation of the Longest common subsequence algorithm for comparing arrays, produces better diffs but is slower. + # * :preserve_key_order (Boolean) [false] If false, operations are grouped by type (-, ~, then +) then by hash key alphabetically. If true, preserves the original key order from the first hash and appends new keys from the second hash in order. + # + # + # @yield [path, value1, value2] Optional block is used to compare each value, instead of default #==. If the block returns value other than true of false, then other specified comparison options will be used to do the comparison. + # + # @return [Array] an array of changes. + # e.g. [[ '+', 'a.b', '45' ], [ '-', 'a.c', '5' ], [ '~', 'a.x', '45', '63']] + # + # @example + # a = {"a" => 1, "b" => {"b1" => 1, "b2" =>2}} + # b = {"a" => 1, "b" => {}} + # + # diff = Hashdiff.diff(a, b) + # diff.should == [['-', 'b.b1', 1], ['-', 'b.b2', 2]] + # + # @since 0.0.1 + def self.diff(obj1, obj2, options = {}, &block) + opts = { + prefix: '', + similarity: 0.8, + delimiter: '.', + strict: true, + ignore_keys: [], + indifferent: false, + strip: false, + numeric_tolerance: 0, + array_path: false, + use_lcs: true, + preserve_key_order: false + }.merge!(options) + + opts[:prefix] = [] if opts[:array_path] && opts[:prefix] == '' + + opts[:ignore_keys] = [*opts[:ignore_keys]] + + opts[:comparison] = block if block_given? + + # prefer to compare with provided block + result = custom_compare(opts[:comparison], opts[:prefix], obj1, obj2) + return result if result + + return [] if obj1.nil? && obj2.nil? + + return [['~', opts[:prefix], obj1, obj2]] if obj1.nil? || obj2.nil? + + return [['~', opts[:prefix], obj1, obj2]] unless comparable?(obj1, obj2, opts[:strict]) + + return LcsCompareArrays.call(obj1, obj2, opts) if obj1.is_a?(Array) && opts[:use_lcs] + + return LinearCompareArray.call(obj1, obj2, opts) if obj1.is_a?(Array) && !opts[:use_lcs] + + return CompareHashes.call(obj1, obj2, opts) if obj1.is_a?(Hash) + + return [] if compare_values(obj1, obj2, opts) + + [['~', opts[:prefix], obj1, obj2]] + end + + # @private + # + # diff array using LCS algorithm + def self.diff_array_lcs(arraya, arrayb, options = {}) + return [] if arraya.empty? && arrayb.empty? + + change_set = [] + + if arraya.empty? + arrayb.each_index do |index| + change_set << ['+', index, arrayb[index]] + end + + return change_set + end + + if arrayb.empty? + arraya.each_index do |index| + i = arraya.size - index - 1 + change_set << ['-', i, arraya[i]] + end + + return change_set + end + + opts = { + prefix: '', + similarity: 0.8, + delimiter: '.' + }.merge!(options) + + links = lcs(arraya, arrayb, opts) + + # yield common + yield links if block_given? + + # padding the end + links << [arraya.size, arrayb.size] + + last_x = -1 + last_y = -1 + links.each do |pair| + x, y = pair + + # remove from a, beginning from the end + (x > last_x + 1) && (x - last_x - 2).downto(0).each do |i| + change_set << ['-', last_y + i + 1, arraya[i + last_x + 1]] + end + + # add from b, beginning from the head + (y > last_y + 1) && 0.upto(y - last_y - 2).each do |i| + change_set << ['+', last_y + i + 1, arrayb[i + last_y + 1]] + end + + # update flags + last_x = x + last_y = y + end + + change_set + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff/lcs.rb b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff/lcs.rb new file mode 100644 index 00000000..b23c3e8d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff/lcs.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +module Hashdiff + # @private + # + # caculate array difference using LCS algorithm + # http://en.wikipedia.org/wiki/Longest_common_subsequence_problem + def self.lcs(arraya, arrayb, options = {}) + return [] if arraya.empty? || arrayb.empty? + + opts = { similarity: 0.8 }.merge!(options) + + opts[:prefix] = prefix_append_array_index(opts[:prefix], '*', opts) + + a_start = b_start = 0 + a_finish = arraya.size - 1 + b_finish = arrayb.size - 1 + vector = [] + + lcs = [] + (b_start..b_finish).each do |bi| + lcs[bi] = [] + (a_start..a_finish).each do |ai| + if similar?(arraya[ai], arrayb[bi], opts) + topleft = (ai > 0) && (bi > 0) ? lcs[bi - 1][ai - 1][1] : 0 + lcs[bi][ai] = [:topleft, topleft + 1] + elsif (top = bi > 0 ? lcs[bi - 1][ai][1] : 0) + left = ai > 0 ? lcs[bi][ai - 1][1] : 0 + count = top > left ? top : left + + direction = if top > left + :top + elsif top < left + :left + elsif bi.zero? + :top + elsif ai.zero? + :left + else + :both + end + + lcs[bi][ai] = [direction, count] + end + end + end + + x = a_finish + y = b_finish + while (x >= 0) && (y >= 0) && (lcs[y][x][1] > 0) + if lcs[y][x][0] == :both + x -= 1 + elsif lcs[y][x][0] == :topleft + vector.insert(0, [x, y]) + x -= 1 + y -= 1 + elsif lcs[y][x][0] == :top + y -= 1 + elsif lcs[y][x][0] == :left + x -= 1 + end + end + + vector + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff/lcs_compare_arrays.rb b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff/lcs_compare_arrays.rb new file mode 100644 index 00000000..1bae9127 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff/lcs_compare_arrays.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module Hashdiff + # @private + # Used to compare arrays using the lcs algorithm + class LcsCompareArrays + class << self + def call(obj1, obj2, opts = {}) + result = [] + + changeset = Hashdiff.diff_array_lcs(obj1, obj2, opts) do |lcs| + # use a's index for similarity + lcs.each do |pair| + prefix = Hashdiff.prefix_append_array_index(opts[:prefix], pair[0], opts) + + result.concat(Hashdiff.diff(obj1[pair[0]], obj2[pair[1]], opts.merge(prefix: prefix))) + end + end + + changeset.each do |change| + next if change[0] != '-' && change[0] != '+' + + change_key = Hashdiff.prefix_append_array_index(opts[:prefix], change[1], opts) + + result << [change[0], change_key, change[2]] + end + + result + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff/linear_compare_array.rb b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff/linear_compare_array.rb new file mode 100644 index 00000000..0b9623c7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff/linear_compare_array.rb @@ -0,0 +1,159 @@ +# frozen_string_literal: true + +module Hashdiff + # @private + # + # Used to compare arrays in a linear complexity, which produces longer diffs + # than using the lcs algorithm but is considerably faster + class LinearCompareArray + def self.call(old_array, new_array, options = {}) + instance = new(old_array, new_array, options) + instance.call + end + + def call + return [] if old_array.empty? && new_array.empty? + + self.old_index = 0 + self.new_index = 0 + # by comparing the array lengths we can expect that a number of items + # are either added or removed + self.expected_additions = new_array.length - old_array.length + + loop do + if extra_items_in_old_array? + append_deletion(old_array[old_index], old_index) + elsif extra_items_in_new_array? + append_addition(new_array[new_index], new_index) + else + compare_at_index + end + + self.old_index = old_index + 1 + self.new_index = new_index + 1 + break if iterated_through_both_arrays? + end + + changes + end + + private + + attr_reader :old_array, :new_array, :options, :additions, :deletions, :differences + attr_accessor :old_index, :new_index, :expected_additions + + def initialize(old_array, new_array, options) + @old_array = old_array + @new_array = new_array + @options = { prefix: '' }.merge!(options) + + @additions = [] + @deletions = [] + @differences = [] + end + + def extra_items_in_old_array? + old_index < old_array.length && new_index >= new_array.length + end + + def extra_items_in_new_array? + new_index < new_array.length && old_index >= old_array.length + end + + def iterated_through_both_arrays? + old_index >= old_array.length && new_index >= new_array.length + end + + def compare_at_index + difference = item_difference(old_array[old_index], new_array[new_index], old_index) + return if difference.empty? + + index_after_additions = index_of_match_after_additions + append_addititions_before_match(index_after_additions) + + index_after_deletions = index_of_match_after_deletions + append_deletions_before_match(index_after_deletions) + + match = index_after_additions || index_after_deletions + + append_differences(difference) unless match + end + + def item_difference(old_item, new_item, item_index) + prefix = Hashdiff.prefix_append_array_index(options[:prefix], item_index, options) + Hashdiff.diff(old_item, new_item, options.merge(prefix: prefix)) + end + + # look ahead in the new array to see if the current item appears later + # thereby having new items added + def index_of_match_after_additions + return unless expected_additions > 0 + + (1..expected_additions).each do |i| + next_difference = item_difference( + old_array[old_index], + new_array[new_index + i], + old_index + ) + + return new_index + i if next_difference.empty? + end + + nil + end + + # look ahead in the old array to see if the current item appears later + # thereby having items removed + def index_of_match_after_deletions + return unless expected_additions < 0 + + (1..(expected_additions.abs)).each do |i| + next_difference = item_difference( + old_array[old_index + i], + new_array[new_index], + old_index + ) + + return old_index + i if next_difference.empty? + end + + nil + end + + def append_addititions_before_match(match_index) + return unless match_index + + (new_index...match_index).each { |i| append_addition(new_array[i], i) } + self.expected_additions = expected_additions - (match_index - new_index) + self.new_index = match_index + end + + def append_deletions_before_match(match_index) + return unless match_index + + (old_index...match_index).each { |i| append_deletion(old_array[i], i) } + self.expected_additions = expected_additions + (match_index - new_index) + self.old_index = match_index + end + + def append_addition(item, index) + key = Hashdiff.prefix_append_array_index(options[:prefix], index, options) + additions << ['+', key, item] + end + + def append_deletion(item, index) + key = Hashdiff.prefix_append_array_index(options[:prefix], index, options) + deletions << ['-', key, item] + end + + def append_differences(difference) + differences.concat(difference) + end + + def changes + # this algorithm only allows there to be additions or deletions + # deletions are reverse so they don't change the index of earlier items + differences + additions + deletions.reverse + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff/patch.rb b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff/patch.rb new file mode 100644 index 00000000..31541f36 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff/patch.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true + +# +# This module provides methods to diff two hash, patch and unpatch hash +# +module Hashdiff + # Apply patch to object + # + # @param [Hash, Array] obj the object to be patched, can be an Array or a Hash + # @param [Array] changes e.g. [[ '+', 'a.b', '45' ], [ '-', 'a.c', '5' ], [ '~', 'a.x', '45', '63']] + # @param [Hash] options supports following keys: + # * :delimiter (String) ['.'] delimiter string for representing nested keys in changes array + # + # @return the object after patch + # + # @since 0.0.1 + def self.patch!(obj, changes, options = {}) + delimiter = options[:delimiter] || '.' + + changes.each do |change| + parts = change[1] + parts = decode_property_path(parts, delimiter) unless parts.is_a?(Array) + + last_part = parts.last + + parent_node = node(obj, parts[0, parts.size - 1]) + + if change[0] == '+' + if parent_node.is_a?(Array) + parent_node.insert(last_part, change[2]) + else + parent_node[last_part] = change[2] + end + elsif change[0] == '-' + if parent_node.is_a?(Array) + parent_node.delete_at(last_part) + else + parent_node.delete(last_part) + end + elsif change[0] == '~' + parent_node[last_part] = change[3] + end + end + + obj + end + + # Unpatch an object + # + # @param [Hash, Array] obj the object to be unpatched, can be an Array or a Hash + # @param [Array] changes e.g. [[ '+', 'a.b', '45' ], [ '-', 'a.c', '5' ], [ '~', 'a.x', '45', '63']] + # @param [Hash] options supports following keys: + # * :delimiter (String) ['.'] delimiter string for representing nested keys in changes array + # + # @return the object after unpatch + # + # @since 0.0.1 + def self.unpatch!(obj, changes, options = {}) + delimiter = options[:delimiter] || '.' + + changes.reverse_each do |change| + parts = change[1] + parts = decode_property_path(parts, delimiter) unless parts.is_a?(Array) + + last_part = parts.last + + parent_node = node(obj, parts[0, parts.size - 1]) + + if change[0] == '+' + if parent_node.is_a?(Array) + parent_node.delete_at(last_part) + else + parent_node.delete(last_part) + end + elsif change[0] == '-' + if parent_node.is_a?(Array) + parent_node.insert(last_part, change[2]) + else + parent_node[last_part] = change[2] + end + elsif change[0] == '~' + parent_node[last_part] = change[2] + end + end + + obj + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff/util.rb b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff/util.rb new file mode 100644 index 00000000..09ed84b4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff/util.rb @@ -0,0 +1,155 @@ +# frozen_string_literal: true + +module Hashdiff + # @private + # + # judge whether two objects are similar + def self.similar?(obja, objb, options = {}) + return compare_values(obja, objb, options) if !options[:comparison] && !any_hash_or_array?(obja, objb) + + count_a = count_nodes(obja) + count_b = count_nodes(objb) + + return true if (count_a + count_b).zero? + + opts = { similarity: 0.8 }.merge!(options) + + diffs = count_diff diff(obja, objb, opts) + + (1 - diffs / (count_a + count_b).to_f) >= opts[:similarity] + end + + # @private + # + # count node differences + def self.count_diff(diffs) + diffs.inject(0) do |sum, item| + old_change_count = count_nodes(item[2]) + new_change_count = count_nodes(item[3]) + sum + (old_change_count + new_change_count) + end + end + + # @private + # + # count total nodes for an object + def self.count_nodes(obj) + return 0 unless obj + + count = 0 + if obj.is_a?(Array) + obj.each { |e| count += count_nodes(e) } + elsif obj.is_a?(Hash) + obj.each_value { |v| count += count_nodes(v) } + else + return 1 + end + + count + end + + # @private + # + # decode property path into an array + # @param [String] path Property-string + # @param [String] delimiter Property-string delimiter + # + # e.g. "a.b[3].c" => ['a', 'b', 3, 'c'] + def self.decode_property_path(path, delimiter = '.') + path.split(delimiter).inject([]) do |memo, part| + if part =~ /^(.*)\[(\d+)\]$/ + if !Regexp.last_match(1).empty? + memo + [Regexp.last_match(1), Regexp.last_match(2).to_i] + else + memo + [Regexp.last_match(2).to_i] + end + else + memo + [part] + end + end + end + + # @private + # + # get the node of hash by given path parts + def self.node(hash, parts) + temp = hash + parts.each do |part| + temp = temp[part] + end + temp + end + + # @private + # + # check for equality or "closeness" within given tolerance + def self.compare_values(obj1, obj2, options = {}) + if options[:numeric_tolerance].is_a?(Numeric) && + obj1.is_a?(Numeric) && obj2.is_a?(Numeric) + return (obj1 - obj2).abs <= options[:numeric_tolerance] + end + + if options[:strip] == true + obj1 = obj1.strip if obj1.respond_to?(:strip) + obj2 = obj2.strip if obj2.respond_to?(:strip) + end + + if options[:case_insensitive] == true + obj1 = obj1.downcase if obj1.respond_to?(:downcase) + obj2 = obj2.downcase if obj2.respond_to?(:downcase) + end + + obj1 == obj2 + end + + # @private + # + # check if objects are comparable + def self.comparable?(obj1, obj2, strict = true) + return true if (obj1.is_a?(Array) || obj1.is_a?(Hash)) && obj2.is_a?(obj1.class) + return true if (obj2.is_a?(Array) || obj2.is_a?(Hash)) && obj1.is_a?(obj2.class) + return true if !strict && obj1.is_a?(Numeric) && obj2.is_a?(Numeric) + + obj1.is_a?(obj2.class) && obj2.is_a?(obj1.class) + end + + # @private + # + # try custom comparison + def self.custom_compare(method, key, obj1, obj2) + return unless method + + res = method.call(key, obj1, obj2) + + # nil != false here + return [['~', key, obj1, obj2]] if res == false + return [] if res == true + end + + def self.prefix_append_key(prefix, key, opts) + if opts[:array_path] + prefix + [key] + else + prefix.empty? ? key.to_s : "#{prefix}#{opts[:delimiter]}#{key}" + end + end + + def self.prefix_append_array_index(prefix, array_index, opts) + if opts[:array_path] + prefix + [array_index] + else + "#{prefix}[#{array_index}]" + end + end + + class << self + private + + # @private + # + # checks if both objects are Arrays or Hashes + def any_hash_or_array?(obja, objb) + obja.is_a?(Array) || obja.is_a?(Hash) || objb.is_a?(Array) || objb.is_a?(Hash) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff/version.rb b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff/version.rb new file mode 100644 index 00000000..fa8a75dd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/hashdiff-1.2.0/lib/hashdiff/version.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +module Hashdiff + VERSION = '1.2.0'.freeze +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/MIT-LICENSE b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/MIT-LICENSE new file mode 100644 index 00000000..ed8e9ee6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2008 The Ruby I18n team + +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 AUTHORS OR COPYRIGHT HOLDERS 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. \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/README.md b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/README.md new file mode 100644 index 00000000..7b7a6bca --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/README.md @@ -0,0 +1,127 @@ +# Ruby I18n + +[![Gem Version](https://badge.fury.io/rb/i18n.svg)](https://badge.fury.io/rb/i18n) +[![Build Status](https://github.com/ruby-i18n/i18n/workflows/Ruby/badge.svg)](https://github.com/ruby-i18n/i18n/actions?query=workflow%3ARuby) + +Ruby internationalization and localization (i18n) solution. + +Currently maintained by @radar. + +## Usage + +### Rails + +You will most commonly use this library within a Rails app. + +We support Rails versions from 6.0 and up. + +[See the Rails Guide](https://guides.rubyonrails.org/i18n.html) for an example of its usage. + +### Ruby (without Rails) + +We support Ruby versions from 3.0 and up. + +If you want to use this library without Rails, you can simply add `i18n` to your `Gemfile`: + +```ruby +gem 'i18n' +``` + +Then configure I18n with some translations, and a default locale: + +```ruby +I18n.load_path += Dir[File.expand_path("config/locales") + "/*.yml"] +I18n.default_locale = :en # (note that `en` is already the default!) +``` + +A simple translation file in your project might live at `config/locales/en.yml` and look like: + +```yml +en: + test: "This is a test" +``` + +You can then access this translation by doing: + +```ruby +I18n.t(:test) +``` + +You can switch locales in your project by setting `I18n.locale` to a different value: + +```ruby +I18n.locale = :de +I18n.t(:test) # => "Dies ist ein Test" +``` + +## Features + +* Translation and localization +* Interpolation of values to translations +* Pluralization (CLDR compatible) +* Customizable transliteration to ASCII +* Flexible defaults +* Bulk lookup +* Lambdas as translation data +* Custom key/scope separator +* Custom exception handlers +* Extensible architecture with a swappable backend + +## Pluggable Features + +* Cache +* Pluralization: lambda pluralizers stored as translation data +* Locale fallbacks, RFC4647 compliant (optionally: RFC4646 locale validation) +* [Gettext support](https://github.com/ruby-i18n/i18n/wiki/Gettext) +* Translation metadata + +## Alternative Backend + +* Chain +* ActiveRecord (optionally: ActiveRecord::Missing and ActiveRecord::StoreProcs) +* KeyValue (uses active_support/json and cannot store procs) + +For more information and lots of resources see [the 'Resources' page on the wiki](https://github.com/ruby-i18n/i18n/wiki/Resources). + +## Tests + +You can run tests both with + +* `rake test` or just `rake` +* run any test file directly, e.g. `ruby -Ilib:test test/api/simple_test.rb` + +You can run all tests against all Gemfiles with + +* `ruby test/run_all.rb` + +The structure of the test suite is a bit unusual as it uses modules to reuse +particular tests in different test cases. + +The reason for this is that we need to enforce the I18n API across various +combinations of extensions. E.g. the Simple backend alone needs to support +the same API as any combination of feature and/or optimization modules included +to the Simple backend. We test this by reusing the same API definition (implemented +as test methods) in test cases with different setups. + +You can find the test cases that enforce the API in test/api. And you can find +the API definition test methods in test/api/tests. + +All other test cases (e.g. as defined in test/backend, test/core_ext) etc. +follow the usual test setup and should be easy to grok. + +## More Documentation + +Additional documentation can be found here: https://github.com/ruby-i18n/i18n/wiki + +## Contributors + +* @radar +* @carlosantoniodasilva +* @josevalim +* @knapo +* @tigrish +* [and many more](https://github.com/ruby-i18n/i18n/graphs/contributors) + +## License + +MIT License. See the included MIT-LICENSE file. diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n.rb new file mode 100644 index 00000000..9a6a535d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n.rb @@ -0,0 +1,477 @@ +# frozen_string_literal: true + +require 'concurrent/map' +require 'concurrent/hash' + +require 'i18n/version' +require 'i18n/utils' +require 'i18n/exceptions' +require 'i18n/interpolate/ruby' + +module I18n + autoload :Backend, 'i18n/backend' + autoload :Config, 'i18n/config' + autoload :Gettext, 'i18n/gettext' + autoload :Locale, 'i18n/locale' + autoload :Tests, 'i18n/tests' + autoload :Middleware, 'i18n/middleware' + + RESERVED_KEYS = %i[ + cascade + deep_interpolation + skip_interpolation + default + exception_handler + fallback + fallback_in_progress + fallback_original_locale + format + object + raise + resolve + scope + separator + throw + ] + EMPTY_HASH = {}.freeze + + def self.new_double_nested_cache # :nodoc: + Concurrent::Map.new { |h, k| h[k] = Concurrent::Map.new } + end + + # Marks a key as reserved. Reserved keys are used internally, + # and can't also be used for interpolation. If you are using any + # extra keys as I18n options, you should call I18n.reserve_key + # before any I18n.translate (etc) calls are made. + def self.reserve_key(key) + RESERVED_KEYS << key.to_sym + @reserved_keys_pattern = nil + end + + def self.reserved_keys_pattern # :nodoc: + @reserved_keys_pattern ||= /(?E.g., ActionView ships with the translation: + # :date => {:formats => {:short => "%b %d"}}. + # + # Translations can be looked up at any level of this hash using the key argument + # and the scope option. E.g., in this example I18n.t :date + # returns the whole translations hash {:formats => {:short => "%b %d"}}. + # + # Key can be either a single key or a dot-separated key (both Strings and Symbols + # work). E.g., the short format can be looked up using both: + # I18n.t 'date.formats.short' + # I18n.t :'date.formats.short' + # + # Scope can be either a single key, a dot-separated key or an array of keys + # or dot-separated keys. Keys and scopes can be combined freely. So these + # examples will all look up the same short date format: + # I18n.t 'date.formats.short' + # I18n.t 'formats.short', :scope => 'date' + # I18n.t 'short', :scope => 'date.formats' + # I18n.t 'short', :scope => %w(date formats) + # + # *INTERPOLATION* + # + # Translations can contain interpolation variables which will be replaced by + # values passed to #translate as part of the options hash, with the keys matching + # the interpolation variable names. + # + # E.g., with a translation :foo => "foo %{bar}" the option + # value for the key +bar+ will be interpolated into the translation: + # I18n.t :foo, :bar => 'baz' # => 'foo baz' + # + # *PLURALIZATION* + # + # Translation data can contain pluralized translations. Pluralized translations + # are arrays of singular/plural versions of translations like ['Foo', 'Foos']. + # + # Note that I18n::Backend::Simple only supports an algorithm for English + # pluralization rules. Other algorithms can be supported by custom backends. + # + # This returns the singular version of a pluralized translation: + # I18n.t :foo, :count => 1 # => 'Foo' + # + # These both return the plural version of a pluralized translation: + # I18n.t :foo, :count => 0 # => 'Foos' + # I18n.t :foo, :count => 2 # => 'Foos' + # + # The :count option can be used both for pluralization and interpolation. + # E.g., with the translation + # :foo => ['%{count} foo', '%{count} foos'], count will + # be interpolated to the pluralized translation: + # I18n.t :foo, :count => 1 # => '1 foo' + # + # *DEFAULTS* + # + # This returns the translation for :foo or default if no translation was found: + # I18n.t :foo, :default => 'default' + # + # This returns the translation for :foo or the translation for :bar if no + # translation for :foo was found: + # I18n.t :foo, :default => :bar + # + # Returns the translation for :foo or the translation for :bar + # or default if no translations for :foo and :bar were found. + # I18n.t :foo, :default => [:bar, 'default'] + # + # BULK LOOKUP + # + # This returns an array with the translations for :foo and :bar. + # I18n.t [:foo, :bar] + # + # Can be used with dot-separated nested keys: + # I18n.t [:'baz.foo', :'baz.bar'] + # + # Which is the same as using a scope option: + # I18n.t [:foo, :bar], :scope => :baz + # + # *LAMBDAS* + # + # Both translations and defaults can be given as Ruby lambdas. Lambdas will be + # called and passed the key and options. + # + # E.g. assuming the key :salutation resolves to: + # lambda { |key, options| options[:gender] == 'm' ? "Mr. #{options[:name]}" : "Mrs. #{options[:name]}" } + # + # Then I18n.t(:salutation, :gender => 'w', :name => 'Smith') will result in "Mrs. Smith". + # + # Note that the string returned by lambda will go through string interpolation too, + # so the following lambda would give the same result: + # lambda { |key, options| options[:gender] == 'm' ? "Mr. %{name}" : "Mrs. %{name}" } + # + # It is recommended to use/implement lambdas in an "idempotent" way. E.g. when + # a cache layer is put in front of I18n.translate it will generate a cache key + # from the argument values passed to #translate. Therefore your lambdas should + # always return the same translations/values per unique combination of argument + # values. + # + # Ruby 2.7+ keyword arguments warning + # + # This method uses keyword arguments. + # There is a breaking change in ruby that produces warning with ruby 2.7 and won't work as expected with ruby 3.0 + # The "hash" parameter must be passed as keyword argument. + # + # Good: + # I18n.t(:salutation, :gender => 'w', :name => 'Smith') + # I18n.t(:salutation, **{ :gender => 'w', :name => 'Smith' }) + # I18n.t(:salutation, **any_hash) + # + # Bad: + # I18n.t(:salutation, { :gender => 'w', :name => 'Smith' }) + # I18n.t(:salutation, any_hash) + # + def translate(key = nil, throw: false, raise: false, locale: nil, **options) # TODO deprecate :raise + locale ||= config.locale + raise Disabled.new('t') if locale == false + enforce_available_locales!(locale) + + backend = config.backend + + if key.is_a?(Array) + key.map do |k| + translate_key(k, throw, raise, locale, backend, options) + end + else + translate_key(key, throw, raise, locale, backend, options) + end + end + alias :t :translate + + # Wrapper for translate that adds :raise => true. With + # this option, if no translation is found, it will raise I18n::MissingTranslationData + def translate!(key, **options) + translate(key, **options, raise: true) + end + alias :t! :translate! + + # Returns an array of interpolation keys for the given translation key + # + # *Examples* + # + # Suppose we have the following: + # I18n.t 'example.zero' == 'Zero interpolations' + # I18n.t 'example.one' == 'One interpolation %{foo}' + # I18n.t 'example.two' == 'Two interpolations %{foo} %{bar}' + # I18n.t 'example.three' == ['One %{foo}', 'Two %{bar}', 'Three %{baz}'] + # I18n.t 'example.one', locale: :other == 'One interpolation %{baz}' + # + # Then we can expect the following results: + # I18n.interpolation_keys('example.zero') #=> [] + # I18n.interpolation_keys('example.one') #=> ['foo'] + # I18n.interpolation_keys('example.two') #=> ['foo', 'bar'] + # I18n.interpolation_keys('example.three') #=> ['foo', 'bar', 'baz'] + # I18n.interpolation_keys('one', scope: 'example', locale: :other) #=> ['baz'] + # I18n.interpolation_keys('does-not-exist') #=> [] + # I18n.interpolation_keys('example') #=> [] + def interpolation_keys(key, **options) + raise I18n::ArgumentError if !key.is_a?(String) || key.empty? + + return [] unless exists?(key, **options.slice(:locale, :scope)) + + translation = translate(key, **options.slice(:locale, :scope)) + interpolation_keys_from_translation(translation) + .flatten.compact + end + + # Returns true if a translation exists for a given key, otherwise returns false. + def exists?(key, _locale = nil, locale: _locale, **options) + locale ||= config.locale + raise Disabled.new('exists?') if locale == false + raise I18n::ArgumentError if (key.is_a?(String) && key.empty?) || key.nil? + + config.backend.exists?(locale, key, options) + end + + # Transliterates UTF-8 characters to ASCII. By default this method will + # transliterate only Latin strings to an ASCII approximation: + # + # I18n.transliterate("Ærøskøbing") + # # => "AEroskobing" + # + # I18n.transliterate("日本語") + # # => "???" + # + # It's also possible to add support for per-locale transliterations. I18n + # expects transliteration rules to be stored at + # i18n.transliterate.rule. + # + # Transliteration rules can either be a Hash or a Proc. Procs must accept a + # single string argument. Hash rules inherit the default transliteration + # rules, while Procs do not. + # + # *Examples* + # + # Setting a Hash in .yml: + # + # i18n: + # transliterate: + # rule: + # ü: "ue" + # ö: "oe" + # + # Setting a Hash using Ruby: + # + # store_translations(:de, i18n: { + # transliterate: { + # rule: { + # 'ü' => 'ue', + # 'ö' => 'oe' + # } + # } + # }) + # + # Setting a Proc: + # + # translit = lambda {|string| MyTransliterator.transliterate(string) } + # store_translations(:xx, :i18n => {:transliterate => {:rule => translit}) + # + # Transliterating strings: + # + # I18n.locale = :en + # I18n.transliterate("Jürgen") # => "Jurgen" + # I18n.locale = :de + # I18n.transliterate("Jürgen") # => "Juergen" + # I18n.transliterate("Jürgen", :locale => :en) # => "Jurgen" + # I18n.transliterate("Jürgen", :locale => :de) # => "Juergen" + def transliterate(key, throw: false, raise: false, locale: nil, replacement: nil, **options) + locale ||= config.locale + raise Disabled.new('transliterate') if locale == false + enforce_available_locales!(locale) + + config.backend.transliterate(locale, key, replacement) + rescue I18n::ArgumentError => exception + handle_exception((throw && :throw || raise && :raise), exception, locale, key, options) + end + + # Localizes certain objects, such as dates and numbers to local formatting. + def localize(object, locale: nil, format: nil, **options) + locale ||= config.locale + raise Disabled.new('l') if locale == false + enforce_available_locales!(locale) + + format ||= :default + config.backend.localize(locale, object, format, options) + end + alias :l :localize + + # Executes block with given I18n.locale set. + def with_locale(tmp_locale = nil) + if tmp_locale == nil + yield + else + current_locale = self.locale + self.locale = tmp_locale + begin + yield + ensure + self.locale = current_locale + end + end + end + + # Merges the given locale, key and scope into a single array of keys. + # Splits keys that contain dots into multiple keys. Makes sure all + # keys are Symbols. + def normalize_keys(locale, key, scope, separator = nil) + separator ||= I18n.default_separator + + [ + *normalize_key(locale, separator), + *normalize_key(scope, separator), + *normalize_key(key, separator) + ] + end + + # Returns true when the passed locale, which can be either a String or a + # Symbol, is in the list of available locales. Returns false otherwise. + def locale_available?(locale) + I18n.config.available_locales_set.include?(locale) + end + + # Raises an InvalidLocale exception when the passed locale is not available. + def enforce_available_locales!(locale) + if locale != false && config.enforce_available_locales + raise I18n::InvalidLocale.new(locale) if !locale_available?(locale) + end + end + + def available_locales_initialized? + config.available_locales_initialized? + end + + private + + def translate_key(key, throw, raise, locale, backend, options) + result = catch(:exception) do + backend.translate(locale, key, options) + end + + if result.is_a?(MissingTranslation) + handle_exception((throw && :throw || raise && :raise), result, locale, key, options) + else + result + end + end + + # Any exceptions thrown in translate will be sent to the @@exception_handler + # which can be a Symbol, a Proc or any other Object unless they're forced to + # be raised or thrown (MissingTranslation). + # + # If exception_handler is a Symbol then it will simply be sent to I18n as + # a method call. A Proc will simply be called. In any other case the + # method #call will be called on the exception_handler object. + # + # Examples: + # + # I18n.exception_handler = :custom_exception_handler # this is the default + # I18n.custom_exception_handler(exception, locale, key, options) # will be called like this + # + # I18n.exception_handler = lambda { |*args| ... } # a lambda + # I18n.exception_handler.call(exception, locale, key, options) # will be called like this + # + # I18n.exception_handler = I18nExceptionHandler.new # an object + # I18n.exception_handler.call(exception, locale, key, options) # will be called like this + def handle_exception(handling, exception, locale, key, options) + case handling + when :raise + raise exception.respond_to?(:to_exception) ? exception.to_exception : exception + when :throw + throw :exception, exception + else + case handler = options[:exception_handler] || config.exception_handler + when Symbol + send(handler, exception, locale, key, options) + else + handler.call(exception, locale, key, options) + end + end + end + + @@normalized_key_cache = I18n.new_double_nested_cache + + def normalize_key(key, separator) + @@normalized_key_cache[separator][key] ||= + case key + when Array + key.flat_map { |k| normalize_key(k, separator) } + else + keys = key.to_s.split(separator) + keys.delete('') + keys.map! do |k| + case k + when /\A[-+]?([1-9]\d*|0)\z/ # integer + k.to_i + when 'true' + true + when 'false' + false + else + k.to_sym + end + end + keys + end + end + + def interpolation_keys_from_translation(translation) + case translation + when ::String + translation.scan(Regexp.union(I18n.config.interpolation_patterns)) + when ::Array + translation.map { |element| interpolation_keys_from_translation(element) } + else + [] + end + end + end + + extend Base +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend.rb new file mode 100644 index 00000000..863d6187 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module I18n + module Backend + autoload :Base, 'i18n/backend/base' + autoload :Cache, 'i18n/backend/cache' + autoload :CacheFile, 'i18n/backend/cache_file' + autoload :Cascade, 'i18n/backend/cascade' + autoload :Chain, 'i18n/backend/chain' + autoload :Fallbacks, 'i18n/backend/fallbacks' + autoload :Flatten, 'i18n/backend/flatten' + autoload :Gettext, 'i18n/backend/gettext' + autoload :InterpolationCompiler, 'i18n/backend/interpolation_compiler' + autoload :KeyValue, 'i18n/backend/key_value' + autoload :LazyLoadable, 'i18n/backend/lazy_loadable' + autoload :Memoize, 'i18n/backend/memoize' + autoload :Metadata, 'i18n/backend/metadata' + autoload :Pluralization, 'i18n/backend/pluralization' + autoload :Simple, 'i18n/backend/simple' + autoload :Transliterator, 'i18n/backend/transliterator' + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/base.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/base.rb new file mode 100644 index 00000000..0c59cd72 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/base.rb @@ -0,0 +1,314 @@ +# frozen_string_literal: true + +require 'yaml' +require 'json' + +module I18n + module Backend + module Base + include I18n::Backend::Transliterator + + # Accepts a list of paths to translation files. Loads translations from + # plain Ruby (*.rb), YAML files (*.yml), or JSON files (*.json). See #load_rb, #load_yml, and #load_json + # for details. + def load_translations(*filenames) + filenames = I18n.load_path if filenames.empty? + filenames.flatten.each do |filename| + loaded_translations = load_file(filename) + yield filename, loaded_translations if block_given? + end + end + + # This method receives a locale, a data hash and options for storing translations. + # Should be implemented + def store_translations(locale, data, options = EMPTY_HASH) + raise NotImplementedError + end + + def translate(locale, key, options = EMPTY_HASH) + raise I18n::ArgumentError if (key.is_a?(String) || key.is_a?(Symbol)) && key.empty? + raise InvalidLocale.new(locale) unless locale + return nil if key.nil? && !options.key?(:default) + + entry = lookup(locale, key, options[:scope], options) unless key.nil? + + if entry.nil? && options.key?(:default) + entry = default(locale, key, options[:default], options) + else + entry = resolve_entry(locale, key, entry, options) + end + + count = options[:count] + + if entry.nil? && (subtrees? || !count) + if (options.key?(:default) && !options[:default].nil?) || !options.key?(:default) + throw(:exception, I18n::MissingTranslation.new(locale, key, options)) + end + end + + entry = entry.dup if entry.is_a?(String) + entry = pluralize(locale, entry, count) if count + + if entry.nil? && !subtrees? + throw(:exception, I18n::MissingTranslation.new(locale, key, options)) + end + + deep_interpolation = options[:deep_interpolation] + skip_interpolation = options[:skip_interpolation] + values = Utils.except(options, *RESERVED_KEYS) unless options.empty? + if !skip_interpolation && values && !values.empty? + entry = if deep_interpolation + deep_interpolate(locale, entry, values) + else + interpolate(locale, entry, values) + end + elsif entry.is_a?(String) && entry =~ I18n.reserved_keys_pattern + raise ReservedInterpolationKey.new($1.to_sym, entry) + end + entry + end + + def exists?(locale, key, options = EMPTY_HASH) + lookup(locale, key, options[:scope]) != nil + end + + # Acts the same as +strftime+, but uses a localized version of the + # format string. Takes a key from the date/time formats translations as + # a format argument (e.g., :short in :'date.formats'). + def localize(locale, object, format = :default, options = EMPTY_HASH) + if object.nil? && options.include?(:default) + return options[:default] + end + raise ArgumentError, "Object must be a Date, DateTime or Time object. #{object.inspect} given." unless object.respond_to?(:strftime) + + if Symbol === format + key = format + type = object.respond_to?(:sec) ? 'time' : 'date' + options = options.merge(:raise => true, :object => object, :locale => locale) + format = I18n.t(:"#{type}.formats.#{key}", **options) + end + + format = translate_localization_format(locale, object, format, options) + object.strftime(format) + end + + # Returns an array of locales for which translations are available + # ignoring the reserved translation meta data key :i18n. + def available_locales + raise NotImplementedError + end + + def reload! + eager_load! if eager_loaded? + end + + def eager_load! + @eager_loaded = true + end + + protected + + def eager_loaded? + @eager_loaded ||= false + end + + # The method which actually looks up for the translation in the store. + def lookup(locale, key, scope = [], options = EMPTY_HASH) + raise NotImplementedError + end + + def subtrees? + true + end + + # Evaluates defaults. + # If given subject is an Array, it walks the array and returns the + # first translation that can be resolved. Otherwise it tries to resolve + # the translation directly. + def default(locale, object, subject, options = EMPTY_HASH) + if options.size == 1 && options.has_key?(:default) + options = {} + else + options = Utils.except(options, :default) + end + + case subject + when Array + subject.each do |item| + result = resolve(locale, object, item, options) + return result unless result.nil? + end and nil + else + resolve(locale, object, subject, options) + end + end + + # Resolves a translation. + # If the given subject is a Symbol, it will be translated with the + # given options. If it is a Proc then it will be evaluated. All other + # subjects will be returned directly. + def resolve(locale, object, subject, options = EMPTY_HASH) + return subject if options[:resolve] == false + result = catch(:exception) do + case subject + when Symbol + I18n.translate( + subject, + **options.merge( + :locale => locale, + :throw => true, + :skip_interpolation => true + ) + ) + when Proc + date_or_time = options.delete(:object) || object + resolve(locale, object, subject.call(date_or_time, **options)) + else + subject + end + end + result unless result.is_a?(MissingTranslation) + end + alias_method :resolve_entry, :resolve + + # Picks a translation from a pluralized mnemonic subkey according to English + # pluralization rules : + # - It will pick the :one subkey if count is equal to 1. + # - It will pick the :other subkey otherwise. + # - It will pick the :zero subkey in the special case where count is + # equal to 0 and there is a :zero subkey present. This behaviour is + # not standard with regards to the CLDR pluralization rules. + # Other backends can implement more flexible or complex pluralization rules. + def pluralize(locale, entry, count) + entry = entry.reject { |k, _v| k == :attributes } if entry.is_a?(Hash) + return entry unless entry.is_a?(Hash) && count + + key = pluralization_key(entry, count) + raise InvalidPluralizationData.new(entry, count, key) unless entry.has_key?(key) + entry[key] + end + + # Interpolates values into a given subject. + # + # if the given subject is a string then: + # method interpolates "file %{file} opened by %%{user}", :file => 'test.txt', :user => 'Mr. X' + # # => "file test.txt opened by %{user}" + # + # if the given subject is an array then: + # each element of the array is recursively interpolated (until it finds a string) + # method interpolates ["yes, %{user}", ["maybe no, %{user}", "no, %{user}"]], :user => "bartuz" + # # => ["yes, bartuz", ["maybe no, bartuz", "no, bartuz"]] + def interpolate(locale, subject, values = EMPTY_HASH) + return subject if values.empty? + + case subject + when ::String then I18n.interpolate(subject, values) + when ::Array then subject.map { |element| interpolate(locale, element, values) } + else + subject + end + end + + # Deep interpolation + # + # deep_interpolate { people: { ann: "Ann is %{ann}", john: "John is %{john}" } }, + # ann: 'good', john: 'big' + # #=> { people: { ann: "Ann is good", john: "John is big" } } + def deep_interpolate(locale, data, values = EMPTY_HASH) + return data if values.empty? + + case data + when ::String + I18n.interpolate(data, values) + when ::Hash + data.each_with_object({}) do |(k, v), result| + result[k] = deep_interpolate(locale, v, values) + end + when ::Array + data.map do |v| + deep_interpolate(locale, v, values) + end + else + data + end + end + + # Loads a single translations file by delegating to #load_rb or + # #load_yml depending on the file extension and directly merges the + # data to the existing translations. Raises I18n::UnknownFileType + # for all other file extensions. + def load_file(filename) + type = File.extname(filename).tr('.', '').downcase + raise UnknownFileType.new(type, filename) unless respond_to?(:"load_#{type}", true) + data, keys_symbolized = send(:"load_#{type}", filename) + unless data.is_a?(Hash) + raise InvalidLocaleData.new(filename, 'expects it to return a hash, but does not') + end + data.each { |locale, d| store_translations(locale, d || {}, skip_symbolize_keys: keys_symbolized) } + + data + end + + # Loads a plain Ruby translations file. eval'ing the file must yield + # a Hash containing translation data with locales as toplevel keys. + def load_rb(filename) + translations = eval(IO.read(filename), binding, filename.to_s) + [translations, false] + end + + # Loads a YAML translations file. The data must have locales as + # toplevel keys. + def load_yml(filename) + begin + if YAML.respond_to?(:unsafe_load_file) # Psych 4.0 way + [YAML.unsafe_load_file(filename, symbolize_names: true, freeze: true), true] + else + [YAML.load_file(filename), false] + end + rescue TypeError, ScriptError, StandardError => e + raise InvalidLocaleData.new(filename, e.inspect) + end + end + alias_method :load_yaml, :load_yml + + # Loads a JSON translations file. The data must have locales as + # toplevel keys. + def load_json(filename) + begin + # Use #load_file as a proxy for a version of JSON where symbolize_names and freeze are supported. + if ::JSON.respond_to?(:load_file) + [::JSON.load_file(filename, symbolize_names: true, freeze: true), true] + else + [::JSON.parse(File.read(filename)), false] + end + rescue TypeError, StandardError => e + raise InvalidLocaleData.new(filename, e.inspect) + end + end + + def translate_localization_format(locale, object, format, options) + format.to_s.gsub(/%(|\^)[aAbBpP]/) do |match| + case match + when '%a' then I18n.t!(:"date.abbr_day_names", :locale => locale, :format => format)[object.wday] + when '%^a' then I18n.t!(:"date.abbr_day_names", :locale => locale, :format => format)[object.wday].upcase + when '%A' then I18n.t!(:"date.day_names", :locale => locale, :format => format)[object.wday] + when '%^A' then I18n.t!(:"date.day_names", :locale => locale, :format => format)[object.wday].upcase + when '%b' then I18n.t!(:"date.abbr_month_names", :locale => locale, :format => format)[object.mon] + when '%^b' then I18n.t!(:"date.abbr_month_names", :locale => locale, :format => format)[object.mon].upcase + when '%B' then I18n.t!(:"date.month_names", :locale => locale, :format => format)[object.mon] + when '%^B' then I18n.t!(:"date.month_names", :locale => locale, :format => format)[object.mon].upcase + when '%p' then I18n.t!(:"time.#{(object.respond_to?(:hour) ? object.hour : 0) < 12 ? :am : :pm}", :locale => locale, :format => format).upcase + when '%P' then I18n.t!(:"time.#{(object.respond_to?(:hour) ? object.hour : 0) < 12 ? :am : :pm}", :locale => locale, :format => format).downcase + end + end + rescue MissingTranslationData => e + e.message + end + + def pluralization_key(entry, count) + key = :zero if count == 0 && entry.has_key?(:zero) + key ||= count == 1 ? :one : :other + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/cache.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/cache.rb new file mode 100644 index 00000000..40c18d65 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/cache.rb @@ -0,0 +1,113 @@ +# frozen_string_literal: true + +# This module allows you to easily cache all responses from the backend - thus +# speeding up the I18n aspects of your application quite a bit. +# +# To enable caching you can simply include the Cache module to the Simple +# backend - or whatever other backend you are using: +# +# I18n::Backend::Simple.send(:include, I18n::Backend::Cache) +# +# You will also need to set a cache store implementation that you want to use: +# +# I18n.cache_store = ActiveSupport::Cache.lookup_store(:memory_store) +# +# You can use any cache implementation you want that provides the same API as +# ActiveSupport::Cache (only the methods #fetch and #write are being used). +# +# The cache_key implementation by default assumes you pass values that return +# a valid key from #hash (see +# https://www.ruby-doc.org/core/classes/Object.html#M000337). However, you can +# configure your own digest method via which responds to #hexdigest (see +# https://ruby-doc.org/stdlib/libdoc/openssl/rdoc/OpenSSL/Digest.html): +# +# I18n.cache_key_digest = OpenSSL::Digest::SHA256.new +# +# If you use a lambda as a default value in your translation like this: +# +# I18n.t(:"date.order", :default => lambda {[:month, :day, :year]}) +# +# Then you will always have a cache miss, because each time this method +# is called the lambda will have a different hash value. If you know +# the result of the lambda is a constant as in the example above, then +# to cache this you can make the lambda a constant, like this: +# +# DEFAULT_DATE_ORDER = lambda {[:month, :day, :year]} +# ... +# I18n.t(:"date.order", :default => DEFAULT_DATE_ORDER) +# +# If the lambda may result in different values for each call then consider +# also using the Memoize backend. +# +module I18n + class << self + @@cache_store = nil + @@cache_namespace = nil + @@cache_key_digest = nil + + def cache_store + @@cache_store + end + + def cache_store=(store) + @@cache_store = store + end + + def cache_namespace + @@cache_namespace + end + + def cache_namespace=(namespace) + @@cache_namespace = namespace + end + + def cache_key_digest + @@cache_key_digest + end + + def cache_key_digest=(key_digest) + @@cache_key_digest = key_digest + end + + def perform_caching? + !cache_store.nil? + end + end + + module Backend + # TODO Should the cache be cleared if new translations are stored? + module Cache + def translate(locale, key, options = EMPTY_HASH) + I18n.perform_caching? ? fetch(cache_key(locale, key, options)) { super } : super + end + + protected + + def fetch(cache_key, &block) + result = _fetch(cache_key, &block) + throw(:exception, result) if result.is_a?(MissingTranslation) + result = result.dup if result.frozen? rescue result + result + end + + def _fetch(cache_key, &block) + result = I18n.cache_store.read(cache_key) + return result unless result.nil? + result = catch(:exception, &block) + I18n.cache_store.write(cache_key, result) unless result.is_a?(Proc) + result + end + + def cache_key(locale, key, options) + # This assumes that only simple, native Ruby values are passed to I18n.translate. + "i18n/#{I18n.cache_namespace}/#{locale}/#{digest_item(key)}/#{digest_item(options)}" + end + + private + + def digest_item(key) + I18n.cache_key_digest ? I18n.cache_key_digest.hexdigest(key.to_s) : key.to_s.hash + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/cache_file.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/cache_file.rb new file mode 100644 index 00000000..0c5e1922 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/cache_file.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require 'openssl' + +module I18n + module Backend + # Overwrites the Base load_file method to cache loaded file contents. + module CacheFile + # Optionally provide path_roots array to normalize filename paths, + # to make the cached i18n data portable across environments. + attr_accessor :path_roots + + protected + + # Track loaded translation files in the `i18n.load_file` scope, + # and skip loading the file if its contents are still up-to-date. + def load_file(filename) + initialized = !respond_to?(:initialized?) || initialized? + key = I18n::Backend::Flatten.escape_default_separator(normalized_path(filename)) + old_mtime, old_digest = initialized && lookup(:i18n, key, :load_file) + return if (mtime = File.mtime(filename).to_i) == old_mtime || + (digest = OpenSSL::Digest::SHA256.file(filename).hexdigest) == old_digest + super + store_translations(:i18n, load_file: { key => [mtime, digest] }) + end + + # Translate absolute filename to relative path for i18n key. + def normalized_path(file) + return file unless path_roots + path = path_roots.find(&file.method(:start_with?)) || + raise(InvalidLocaleData.new(file, 'outside expected path roots')) + file.sub(path, path_roots.index(path).to_s) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/cascade.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/cascade.rb new file mode 100644 index 00000000..782b07b5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/cascade.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +# The Cascade module adds the ability to do cascading lookups to backends that +# are compatible to the Simple backend. +# +# By cascading lookups we mean that for any key that can not be found the +# Cascade module strips one segment off the scope part of the key and then +# tries to look up the key in that scope. +# +# E.g. when a lookup for the key :"foo.bar.baz" does not yield a result then +# the segment :bar will be stripped off the scope part :"foo.bar" and the new +# scope :foo will be used to look up the key :baz. If that does not succeed +# then the remaining scope segment :foo will be omitted, too, and again the +# key :baz will be looked up (now with no scope). +# +# To enable a cascading lookup one passes the :cascade option: +# +# I18n.t(:'foo.bar.baz', :cascade => true) +# +# This will return the first translation found for :"foo.bar.baz", :"foo.baz" +# or :baz in this order. +# +# The cascading lookup takes precedence over resolving any given defaults. +# I.e. defaults will kick in after the cascading lookups haven't succeeded. +# +# This behavior is useful for libraries like ActiveRecord validations where +# the library wants to give users a bunch of more or less fine-grained options +# of scopes for a particular key. +# +# Thanks to Clemens Kofler for the initial idea and implementation! See +# http://github.com/clemens/i18n-cascading-backend + +module I18n + module Backend + module Cascade + def lookup(locale, key, scope = [], options = EMPTY_HASH) + return super unless cascade = options[:cascade] + + cascade = { :step => 1 } unless cascade.is_a?(Hash) + step = cascade[:step] || 1 + offset = cascade[:offset] || 1 + separator = options[:separator] || I18n.default_separator + skip_root = cascade.has_key?(:skip_root) ? cascade[:skip_root] : true + + scope = I18n.normalize_keys(nil, key, scope, separator) + key = (scope.slice!(-offset, offset) || []).join(separator) + + begin + result = super + return result unless result.nil? + scope = scope.dup + end while (!scope.empty? || !skip_root) && scope.slice!(-step, step) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/chain.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/chain.rb new file mode 100644 index 00000000..e081a91c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/chain.rb @@ -0,0 +1,130 @@ +# frozen_string_literal: true + +module I18n + module Backend + # Backend that chains multiple other backends and checks each of them when + # a translation needs to be looked up. This is useful when you want to use + # standard translations with a Simple backend but store custom application + # translations in a database or other backends. + # + # To use the Chain backend instantiate it and set it to the I18n module. + # You can add chained backends through the initializer or backends + # accessor: + # + # # preserves the existing Simple backend set to I18n.backend + # I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n.backend) + # + # The implementation assumes that all backends added to the Chain implement + # a lookup method with the same API as Simple backend does. + # + # Fallback translations using the :default option are only used by the last backend of a chain. + class Chain + module Implementation + include Base + + attr_accessor :backends + + def initialize(*backends) + self.backends = backends + end + + def initialized? + backends.all? do |backend| + backend.instance_eval do + return false unless initialized? + end + end + true + end + + def reload! + backends.each { |backend| backend.reload! } + end + + def eager_load! + backends.each { |backend| backend.eager_load! } + end + + def store_translations(locale, data, options = EMPTY_HASH) + backends.first.store_translations(locale, data, options) + end + + def available_locales + backends.map { |backend| backend.available_locales }.flatten.uniq + end + + def translate(locale, key, default_options = EMPTY_HASH) + namespace = nil + options = Utils.except(default_options, :default) + + backends.each do |backend| + catch(:exception) do + options = default_options if backend == backends.last + translation = backend.translate(locale, key, options) + if namespace_lookup?(translation, options) + namespace = _deep_merge(translation, namespace || {}) + elsif !translation.nil? || (options.key?(:default) && options[:default].nil?) + return translation + end + end + end + + return namespace if namespace + throw(:exception, I18n::MissingTranslation.new(locale, key, options)) + end + + def exists?(locale, key, options = EMPTY_HASH) + backends.any? do |backend| + backend.exists?(locale, key, options) + end + end + + def localize(locale, object, format = :default, options = EMPTY_HASH) + backends.each do |backend| + catch(:exception) do + result = backend.localize(locale, object, format, options) and return result + end + end + throw(:exception, I18n::MissingTranslation.new(locale, format, options)) + end + + protected + def init_translations + backends.each do |backend| + backend.send(:init_translations) + end + end + + def translations + backends.reverse.each_with_object({}) do |backend, memo| + partial_translations = backend.instance_eval do + init_translations unless initialized? + translations + end + Utils.deep_merge!(memo, partial_translations) { |_, a, b| b || a } + end + end + + def namespace_lookup?(result, options) + result.is_a?(Hash) && !options.has_key?(:count) + end + + private + # This is approximately what gets used in ActiveSupport. + # However since we are not guaranteed to run in an ActiveSupport context + # it is wise to have our own copy. We underscore it + # to not pollute the namespace of the including class. + def _deep_merge(hash, other_hash) + copy = hash.dup + other_hash.each_pair do |k,v| + value_from_other = hash[k] + copy[k] = value_from_other.is_a?(Hash) && v.is_a?(Hash) ? _deep_merge(value_from_other, v) : v + end + copy + end + end + + include Implementation + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/fallbacks.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/fallbacks.rb new file mode 100644 index 00000000..caa4e66e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/fallbacks.rb @@ -0,0 +1,119 @@ +# frozen_string_literal: true + +# I18n locale fallbacks are useful when you want your application to use +# translations from other locales when translations for the current locale are +# missing. E.g. you might want to use :en translations when translations in +# your applications main locale :de are missing. +# +# To enable locale fallbacks you can simply include the Fallbacks module to +# the Simple backend - or whatever other backend you are using: +# +# I18n::Backend::Simple.include(I18n::Backend::Fallbacks) +module I18n + @@fallbacks = nil + + class << self + # Returns the current fallbacks implementation. Defaults to +I18n::Locale::Fallbacks+. + def fallbacks + @@fallbacks ||= I18n::Locale::Fallbacks.new + Thread.current[:i18n_fallbacks] || @@fallbacks + end + + # Sets the current fallbacks implementation. Use this to set a different fallbacks implementation. + def fallbacks=(fallbacks) + @@fallbacks = fallbacks.is_a?(Array) ? I18n::Locale::Fallbacks.new(fallbacks) : fallbacks + Thread.current[:i18n_fallbacks] = @@fallbacks + end + end + + module Backend + module Fallbacks + # Overwrites the Base backend translate method so that it will try each + # locale given by I18n.fallbacks for the given locale. E.g. for the + # locale :"de-DE" it might try the locales :"de-DE", :de and :en + # (depends on the fallbacks implementation) until it finds a result with + # the given options. If it does not find any result for any of the + # locales it will then throw MissingTranslation as usual. + # + # The default option takes precedence over fallback locales only when + # it's a Symbol. When the default contains a String, Proc or Hash + # it is evaluated last after all the fallback locales have been tried. + def translate(locale, key, options = EMPTY_HASH) + return super unless options.fetch(:fallback, true) + return super if options[:fallback_in_progress] + default = extract_non_symbol_default!(options) if options[:default] + + fallback_options = options.merge(:fallback_in_progress => true, fallback_original_locale: locale) + I18n.fallbacks[locale].each do |fallback| + begin + catch(:exception) do + result = super(fallback, key, fallback_options) + unless result.nil? + on_fallback(locale, fallback, key, options) if locale.to_s != fallback.to_s + return result + end + end + rescue I18n::InvalidLocale + # we do nothing when the locale is invalid, as this is a fallback anyways. + end + end + + return if options.key?(:default) && options[:default].nil? + + return super(locale, nil, options.merge(:default => default)) if default + throw(:exception, I18n::MissingTranslation.new(locale, key, options)) + end + + def resolve_entry(locale, object, subject, options = EMPTY_HASH) + return subject if options[:resolve] == false + result = catch(:exception) do + options.delete(:fallback_in_progress) if options.key?(:fallback_in_progress) + + case subject + when Symbol + I18n.translate(subject, **options.merge( + :locale => options[:fallback_original_locale], + :throw => true, + :skip_interpolation => true + )) + when Proc + date_or_time = options.delete(:object) || object + resolve_entry(options[:fallback_original_locale], object, subject.call(date_or_time, **options)) + else + subject + end + end + result unless result.is_a?(MissingTranslation) + end + + def extract_non_symbol_default!(options) + defaults = [options[:default]].flatten + first_non_symbol_default = defaults.detect{|default| !default.is_a?(Symbol)} + if first_non_symbol_default + options[:default] = defaults[0, defaults.index(first_non_symbol_default)] + end + return first_non_symbol_default + end + + def exists?(locale, key, options = EMPTY_HASH) + return super unless options.fetch(:fallback, true) + I18n.fallbacks[locale].each do |fallback| + begin + return true if super(fallback, key, options) + rescue I18n::InvalidLocale + # we do nothing when the locale is invalid, as this is a fallback anyways. + end + end + + false + end + + private + + # Overwrite on_fallback to add specified logic when the fallback succeeds. + def on_fallback(_original_locale, _fallback_locale, _key, _options) + nil + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/flatten.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/flatten.rb new file mode 100644 index 00000000..e9bd9d53 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/flatten.rb @@ -0,0 +1,118 @@ +# frozen_string_literal: true + +module I18n + module Backend + # This module contains several helpers to assist flattening translations. + # You may want to flatten translations for: + # + # 1) speed up lookups, as in the Memoize backend; + # 2) In case you want to store translations in a data store, as in ActiveRecord backend; + # + # You can check both backends above for some examples. + # This module also keeps all links in a hash so they can be properly resolved when flattened. + module Flatten + SEPARATOR_ESCAPE_CHAR = "\001" + FLATTEN_SEPARATOR = "." + + # normalize_keys the flatten way. This method is significantly faster + # and creates way less objects than the one at I18n.normalize_keys. + # It also handles escaping the translation keys. + def self.normalize_flat_keys(locale, key, scope, separator) + keys = [scope, key] + keys.flatten! + keys.compact! + + separator ||= I18n.default_separator + + if separator != FLATTEN_SEPARATOR + from_str = "#{FLATTEN_SEPARATOR}#{separator}" + to_str = "#{SEPARATOR_ESCAPE_CHAR}#{FLATTEN_SEPARATOR}" + + keys.map! { |k| k.to_s.tr from_str, to_str } + end + + keys.join(".") + end + + # Receives a string and escape the default separator. + def self.escape_default_separator(key) #:nodoc: + key.to_s.tr(FLATTEN_SEPARATOR, SEPARATOR_ESCAPE_CHAR) + end + + # Shortcut to I18n::Backend::Flatten.normalize_flat_keys + # and then resolve_links. + def normalize_flat_keys(locale, key, scope, separator) + key = I18n::Backend::Flatten.normalize_flat_keys(locale, key, scope, separator) + resolve_link(locale, key) + end + + # Store flattened links. + def links + @links ||= I18n.new_double_nested_cache + end + + # Flatten keys for nested Hashes by chaining up keys: + # + # >> { "a" => { "b" => { "c" => "d", "e" => "f" }, "g" => "h" }, "i" => "j"}.wind + # => { "a.b.c" => "d", "a.b.e" => "f", "a.g" => "h", "i" => "j" } + # + def flatten_keys(hash, escape, prev_key=nil, &block) + hash.each_pair do |key, value| + key = escape_default_separator(key) if escape + curr_key = [prev_key, key].compact.join(FLATTEN_SEPARATOR).to_sym + yield curr_key, value + flatten_keys(value, escape, curr_key, &block) if value.is_a?(Hash) + end + end + + # Receives a hash of translations (where the key is a locale and + # the value is another hash) and return a hash with all + # translations flattened. + # + # Nested hashes are included in the flattened hash just if subtree + # is true and Symbols are automatically stored as links. + def flatten_translations(locale, data, escape, subtree) + hash = {} + flatten_keys(data, escape) do |key, value| + if value.is_a?(Hash) + hash[key] = value if subtree + else + store_link(locale, key, value) if value.is_a?(Symbol) + hash[key] = value + end + end + hash + end + + protected + + def store_link(locale, key, link) + links[locale.to_sym][key.to_s] = link.to_s + end + + def resolve_link(locale, key) + key, locale = key.to_s, locale.to_sym + links = self.links[locale] + + if links.key?(key) + links[key] + elsif link = find_link(locale, key) + store_link(locale, key, key.gsub(*link)) + else + key + end + end + + def find_link(locale, key) #:nodoc: + links[locale].each_pair do |from, to| + return [from, to] if key[0, from.length] == from + end && nil + end + + def escape_default_separator(key) #:nodoc: + I18n::Backend::Flatten.escape_default_separator(key) + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/gettext.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/gettext.rb new file mode 100644 index 00000000..07696463 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/gettext.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +require 'i18n/gettext' +require 'i18n/gettext/po_parser' + +module I18n + module Backend + # Experimental support for using Gettext po files to store translations. + # + # To use this you can simply include the module to the Simple backend - or + # whatever other backend you are using. + # + # I18n::Backend::Simple.include(I18n::Backend::Gettext) + # + # Now you should be able to include your Gettext translation (*.po) files to + # the +I18n.load_path+ so they're loaded to the backend and you can use them as + # usual: + # + # I18n.load_path += Dir["path/to/locales/*.po"] + # + # Following the Gettext convention this implementation expects that your + # translation files are named by their locales. E.g. the file en.po would + # contain the translations for the English locale. + # + # To translate text you must use one of the translate methods provided by + # I18n::Gettext::Helpers. + # + # include I18n::Gettext::Helpers + # puts _("some string") + # + # Without it strings containing periods (".") will not be translated. + + module Gettext + class PoData < Hash + def set_comment(msgid_or_sym, comment) + # ignore + end + end + + protected + def load_po(filename) + locale = ::File.basename(filename, '.po').to_sym + data = normalize(locale, parse(filename)) + [{ locale => data }, false] + end + + def parse(filename) + GetText::PoParser.new.parse(::File.read(filename), PoData.new) + end + + def normalize(locale, data) + data.inject({}) do |result, (key, value)| + unless key.nil? || key.empty? + key = key.gsub(I18n::Gettext::CONTEXT_SEPARATOR, '|') + key, value = normalize_pluralization(locale, key, value) if key.index("\000") + + parts = key.split('|').reverse + normalized = parts.inject({}) do |_normalized, part| + { part => _normalized.empty? ? value : _normalized } + end + + Utils.deep_merge!(result, normalized) + end + result + end + end + + def normalize_pluralization(locale, key, value) + # FIXME po_parser includes \000 chars that can not be turned into Symbols + key = key.gsub("\000", I18n::Gettext::PLURAL_SEPARATOR).split(I18n::Gettext::PLURAL_SEPARATOR).first + + keys = I18n::Gettext.plural_keys(locale) + values = value.split("\000") + raise "invalid number of plurals: #{values.size}, keys: #{keys.inspect} on #{locale} locale for msgid #{key.inspect} with values #{values.inspect}" if values.size != keys.size + + result = {} + values.each_with_index { |_value, ix| result[keys[ix]] = _value } + [key, result] + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/interpolation_compiler.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/interpolation_compiler.rb new file mode 100644 index 00000000..e37b6799 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/interpolation_compiler.rb @@ -0,0 +1,121 @@ +# frozen_string_literal: true + +# The InterpolationCompiler module contains optimizations that can tremendously +# speed up the interpolation process on the Simple backend. +# +# It works by defining a pre-compiled method on stored translation Strings that +# already bring all the knowledge about contained interpolation variables etc. +# so that the actual recurring interpolation will be very fast. +# +# To enable pre-compiled interpolations you can simply include the +# InterpolationCompiler module to the Simple backend: +# +# I18n::Backend::Simple.include(I18n::Backend::InterpolationCompiler) +# +# Note that InterpolationCompiler does not yield meaningful results and consequently +# should not be used with Ruby 1.9 (YARV) but improves performance everywhere else +# (jRuby, Rubinius). +module I18n + module Backend + module InterpolationCompiler + module Compiler + extend self + + TOKENIZER = /(%%?\{[^}]+\})/ + + def compile_if_an_interpolation(string) + if interpolated_str?(string) + string.instance_eval <<-RUBY_EVAL, __FILE__, __LINE__ + def i18n_interpolate(v = {}) + "#{compiled_interpolation_body(string)}" + end + RUBY_EVAL + end + + string + end + + def interpolated_str?(str) + str.kind_of?(::String) && str =~ TOKENIZER + end + + protected + # tokenize("foo %{bar} baz %%{buz}") # => ["foo ", "%{bar}", " baz ", "%%{buz}"] + def tokenize(str) + str.split(TOKENIZER) + end + + def compiled_interpolation_body(str) + tokenize(str).map do |token| + token.match(TOKENIZER) ? handle_interpolation_token(token) : escape_plain_str(token) + end.join + end + + def handle_interpolation_token(token) + token.start_with?('%%') ? token[1..] : compile_interpolation_token(token[2..-2]) + end + + def compile_interpolation_token(key) + "\#{#{interpolate_or_raise_missing(key)}}" + end + + def interpolate_or_raise_missing(key) + escaped_key = escape_key_sym(key) + RESERVED_KEYS.include?(key) ? reserved_key(escaped_key) : interpolate_key(escaped_key) + end + + def interpolate_key(key) + [direct_key(key), nil_key(key), missing_key(key)].join('||') + end + + def direct_key(key) + "((t = v[#{key}]) && t.respond_to?(:call) ? t.call : t)" + end + + def nil_key(key) + "(v.has_key?(#{key}) && '')" + end + + def missing_key(key) + "I18n.config.missing_interpolation_argument_handler.call(#{key}, v, self)" + end + + def reserved_key(key) + "raise(ReservedInterpolationKey.new(#{key}, self))" + end + + def escape_plain_str(str) + str.gsub(/"|\\|#/) {|x| "\\#{x}"} + end + + def escape_key_sym(key) + # rely on Ruby to do all the hard work :) + key.to_sym.inspect + end + end + + def interpolate(locale, string, values) + if string.respond_to?(:i18n_interpolate) + string.i18n_interpolate(values) + elsif values + super + else + string + end + end + + def store_translations(locale, data, options = EMPTY_HASH) + compile_all_strings_in(data) + super + end + + protected + def compile_all_strings_in(data) + data.each_value do |value| + Compiler.compile_if_an_interpolation(value) + compile_all_strings_in(value) if value.kind_of?(Hash) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/key_value.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/key_value.rb new file mode 100644 index 00000000..b937e253 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/key_value.rb @@ -0,0 +1,204 @@ +# frozen_string_literal: true + +require 'i18n/backend/base' + +module I18n + + begin + require 'oj' + class JSON + class << self + def encode(value) + Oj::Rails.encode(value) + end + def decode(value) + Oj.load(value) + end + end + end + rescue LoadError + require 'active_support/json' + JSON = ActiveSupport::JSON + end + + module Backend + # This is a basic backend for key value stores. It receives on + # initialization the store, which should respond to three methods: + # + # * store#[](key) - Used to get a value + # * store#[]=(key, value) - Used to set a value + # * store#keys - Used to get all keys + # + # Since these stores only supports string, all values are converted + # to JSON before being stored, allowing it to also store booleans, + # hashes and arrays. However, this store does not support Procs. + # + # As the ActiveRecord backend, Symbols are just supported when loading + # translations from the filesystem or through explicit store translations. + # + # Also, avoid calling I18n.available_locales since it's a somehow + # expensive operation in most stores. + # + # == Example + # + # To setup I18n to use TokyoCabinet in memory is quite straightforward: + # + # require 'rufus/tokyo/cabinet' # gem install rufus-tokyo + # I18n.backend = I18n::Backend::KeyValue.new(Rufus::Tokyo::Cabinet.new('*')) + # + # == Performance + # + # You may make this backend even faster by including the Memoize module. + # However, notice that you should properly clear the cache if you change + # values directly in the key-store. + # + # == Subtrees + # + # In most backends, you are allowed to retrieve part of a translation tree: + # + # I18n.backend.store_translations :en, :foo => { :bar => :baz } + # I18n.t "foo" #=> { :bar => :baz } + # + # This backend supports this feature by default, but it slows down the storage + # of new data considerably and makes hard to delete entries. That said, you are + # allowed to disable the storage of subtrees on initialization: + # + # I18n::Backend::KeyValue.new(@store, false) + # + # This is useful if you are using a KeyValue backend chained to a Simple backend. + class KeyValue + module Implementation + attr_accessor :store + + include Base, Flatten + + def initialize(store, subtrees=true) + @store, @subtrees = store, subtrees + end + + def initialized? + !@store.nil? + end + + def store_translations(locale, data, options = EMPTY_HASH) + escape = options.fetch(:escape, true) + flatten_translations(locale, data, escape, @subtrees).each do |key, value| + key = "#{locale}.#{key}" + + case value + when Hash + if @subtrees && (old_value = @store[key]) + old_value = JSON.decode(old_value) + value = Utils.deep_merge!(Utils.deep_symbolize_keys(old_value), value) if old_value.is_a?(Hash) + end + when Proc + raise "Key-value stores cannot handle procs" + end + + @store[key] = JSON.encode(value) unless value.is_a?(Symbol) + end + end + + def available_locales + locales = @store.keys.map { |k| k =~ /\./; $` } + locales.uniq! + locales.compact! + locales.map! { |k| k.to_sym } + locales + end + + protected + + # Queries the translations from the key-value store and converts + # them into a hash such as the one returned from loading the + # haml files + def translations + @translations = Utils.deep_symbolize_keys(@store.keys.clone.map do |main_key| + main_value = JSON.decode(@store[main_key]) + main_key.to_s.split(".").reverse.inject(main_value) do |value, key| + {key.to_sym => value} + end + end.inject{|hash, elem| Utils.deep_merge!(hash, elem)}) + end + + def init_translations + # NO OP + # This call made also inside Simple Backend and accessed by + # other plugins like I18n-js and babilu and + # to use it along with the Chain backend we need to + # provide a uniform API even for protected methods :S + end + + def subtrees? + @subtrees + end + + def lookup(locale, key, scope = [], options = EMPTY_HASH) + key = normalize_flat_keys(locale, key, scope, options[:separator]) + value = @store["#{locale}.#{key}"] + value = JSON.decode(value) if value + + if value.is_a?(Hash) + Utils.deep_symbolize_keys(value) + elsif !value.nil? + value + elsif !@subtrees + SubtreeProxy.new("#{locale}.#{key}", @store) + end + end + + def pluralize(locale, entry, count) + if subtrees? + super + else + return entry unless entry.is_a?(Hash) + key = pluralization_key(entry, count) + entry[key] + end + end + end + + class SubtreeProxy + def initialize(master_key, store) + @master_key = master_key + @store = store + @subtree = nil + end + + def has_key?(key) + @subtree && @subtree.has_key?(key) || self[key] + end + + def [](key) + unless @subtree && value = @subtree[key] + value = @store["#{@master_key}.#{key}"] + if value + value = JSON.decode(value) + (@subtree ||= {})[key] = value + end + end + value + end + + def is_a?(klass) + Hash == klass || super + end + alias :kind_of? :is_a? + + def instance_of?(klass) + Hash == klass || super + end + + def nil? + @subtree.nil? + end + + def inspect + @subtree.inspect + end + end + + include Implementation + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/lazy_loadable.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/lazy_loadable.rb new file mode 100644 index 00000000..575b32bf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/lazy_loadable.rb @@ -0,0 +1,184 @@ +# frozen_string_literal: true + +module I18n + module Backend + # Backend that lazy loads translations based on the current locale. This + # implementation avoids loading all translations up front. Instead, it only + # loads the translations that belong to the current locale. This offers a + # performance incentive in local development and test environments for + # applications with many translations for many different locales. It's + # particularly useful when the application only refers to a single locales' + # translations at a time (ex. A Rails workload). The implementation + # identifies which translation files from the load path belong to the + # current locale by pattern matching against their path name. + # + # Specifically, a translation file is considered to belong to a locale if: + # a) the filename is in the I18n load path + # b) the filename ends in a supported extension (ie. .yml, .json, .po, .rb) + # c) the filename starts with the locale identifier + # d) the locale identifier and optional proceeding text is separated by an underscore, ie. "_". + # + # Examples: + # Valid files that will be selected by this backend: + # + # "files/locales/en_translation.yml" (Selected for locale "en") + # "files/locales/fr.po" (Selected for locale "fr") + # + # Invalid files that won't be selected by this backend: + # + # "files/locales/translation-file" + # "files/locales/en-translation.unsupported" + # "files/locales/french/translation.yml" + # "files/locales/fr/translation.yml" + # + # The implementation uses this assumption to defer the loading of + # translation files until the current locale actually requires them. + # + # The backend has two working modes: lazy_load and eager_load. + # + # Note: This backend should only be enabled in test environments! + # When the mode is set to false, the backend behaves exactly like the + # Simple backend, with an additional check that the paths being loaded + # abide by the format. If paths can't be matched to the format, an error is raised. + # + # You can configure lazy loaded backends through the initializer or backends + # accessor: + # + # # In test environments + # + # I18n.backend = I18n::Backend::LazyLoadable.new(lazy_load: true) + # + # # In other environments, such as production and CI + # + # I18n.backend = I18n::Backend::LazyLoadable.new(lazy_load: false) # default + # + class LocaleExtractor + class << self + def locale_from_path(path) + name = File.basename(path, ".*") + locale = name.split("_").first + locale.to_sym unless locale.nil? + end + end + end + + class LazyLoadable < Simple + def initialize(lazy_load: false) + @lazy_load = lazy_load + end + + # Returns whether the current locale is initialized. + def initialized? + if lazy_load? + initialized_locales[I18n.locale] + else + super + end + end + + # Clean up translations and uninitialize all locales. + def reload! + if lazy_load? + @initialized_locales = nil + @translations = nil + else + super + end + end + + # Eager loading is not supported in the lazy context. + def eager_load! + if lazy_load? + raise UnsupportedMethod.new(__method__, self.class, "Cannot eager load translations because backend was configured with lazy_load: true.") + else + super + end + end + + # Parse the load path and extract all locales. + def available_locales + if lazy_load? + I18n.load_path.map { |path| LocaleExtractor.locale_from_path(path) }.uniq + else + super + end + end + + def lookup(locale, key, scope = [], options = EMPTY_HASH) + if lazy_load? + I18n.with_locale(locale) do + super + end + else + super + end + end + + protected + + + # Load translations from files that belong to the current locale. + def init_translations + file_errors = if lazy_load? + initialized_locales[I18n.locale] = true + load_translations_and_collect_file_errors(filenames_for_current_locale) + else + @initialized = true + load_translations_and_collect_file_errors(I18n.load_path) + end + + raise InvalidFilenames.new(file_errors) unless file_errors.empty? + end + + def initialized_locales + @initialized_locales ||= Hash.new(false) + end + + private + + def lazy_load? + @lazy_load + end + + class FilenameIncorrect < StandardError + def initialize(file, expected_locale, unexpected_locales) + super "#{file} can only load translations for \"#{expected_locale}\". Found translations for: #{unexpected_locales}." + end + end + + # Loads each file supplied and asserts that the file only loads + # translations as expected by the name. The method returns a list of + # errors corresponding to offending files. + def load_translations_and_collect_file_errors(files) + errors = [] + + load_translations(files) do |file, loaded_translations| + assert_file_named_correctly!(file, loaded_translations) + rescue FilenameIncorrect => e + errors << e + end + + errors + end + + # Select all files from I18n load path that belong to current locale. + # These files must start with the locale identifier (ie. "en", "pt-BR"), + # followed by an "_" demarcation to separate proceeding text. + def filenames_for_current_locale + I18n.load_path.flatten.select do |path| + LocaleExtractor.locale_from_path(path) == I18n.locale + end + end + + # Checks if a filename is named in correspondence to the translations it loaded. + # The locale extracted from the path must be the single locale loaded in the translations. + def assert_file_named_correctly!(file, translations) + loaded_locales = translations.keys.map(&:to_sym) + expected_locale = LocaleExtractor.locale_from_path(file) + unexpected_locales = loaded_locales.reject { |locale| locale == expected_locale } + + raise FilenameIncorrect.new(file, expected_locale, unexpected_locales) unless unexpected_locales.empty? + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/memoize.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/memoize.rb new file mode 100644 index 00000000..3293d2b4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/memoize.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +# Memoize module simply memoizes the values returned by lookup using +# a flat hash and can tremendously speed up the lookup process in a backend. +# +# To enable it you can simply include the Memoize module to your backend: +# +# I18n::Backend::Simple.include(I18n::Backend::Memoize) +# +# Notice that it's the responsibility of the backend to define whenever the +# cache should be cleaned. +module I18n + module Backend + module Memoize + def available_locales + @memoized_locales ||= super + end + + def store_translations(locale, data, options = EMPTY_HASH) + reset_memoizations!(locale) + super + end + + def reload! + reset_memoizations! + super + end + + def eager_load! + memoized_lookup + available_locales + super + end + + protected + + def lookup(locale, key, scope = nil, options = EMPTY_HASH) + flat_key = I18n::Backend::Flatten.normalize_flat_keys(locale, + key, scope, options[:separator]).to_sym + flat_hash = memoized_lookup[locale.to_sym] + flat_hash.key?(flat_key) ? flat_hash[flat_key] : (flat_hash[flat_key] = super) + end + + def memoized_lookup + @memoized_lookup ||= I18n.new_double_nested_cache + end + + def reset_memoizations!(locale=nil) + @memoized_locales = nil + (locale ? memoized_lookup[locale.to_sym] : memoized_lookup).clear + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/metadata.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/metadata.rb new file mode 100644 index 00000000..51ea7a2a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/metadata.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +# I18n translation metadata is useful when you want to access information +# about how a translation was looked up, pluralized or interpolated in +# your application. +# +# msg = I18n.t(:message, :default => 'Hi!', :scope => :foo) +# msg.translation_metadata +# # => { :key => :message, :scope => :foo, :default => 'Hi!' } +# +# If a :count option was passed to #translate it will be set to the metadata. +# Likewise, if any interpolation variables were passed they will also be set. +# +# To enable translation metadata you can simply include the Metadata module +# into the Simple backend class - or whatever other backend you are using: +# +# I18n::Backend::Simple.include(I18n::Backend::Metadata) +# +module I18n + module Backend + module Metadata + class << self + def included(base) + Object.class_eval do + def translation_metadata + unless self.frozen? + @translation_metadata ||= {} + else + {} + end + end + + def translation_metadata=(translation_metadata) + @translation_metadata = translation_metadata unless self.frozen? + end + end unless Object.method_defined?(:translation_metadata) + end + end + + def translate(locale, key, options = EMPTY_HASH) + metadata = { + :locale => locale, + :key => key, + :scope => options[:scope], + :default => options[:default], + :separator => options[:separator], + :values => options.reject { |name, _value| RESERVED_KEYS.include?(name) } + } + with_metadata(metadata) { super } + end + + def interpolate(locale, entry, values = EMPTY_HASH) + metadata = entry.translation_metadata.merge(:original => entry) + with_metadata(metadata) { super } + end + + def pluralize(locale, entry, count) + with_metadata(:count => count) { super } + end + + protected + + def with_metadata(metadata, &block) + result = yield + result.translation_metadata = result.translation_metadata.merge(metadata) if result + result + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/pluralization.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/pluralization.rb new file mode 100644 index 00000000..1d3277b8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/pluralization.rb @@ -0,0 +1,96 @@ +# frozen_string_literal: true + +# I18n Pluralization are useful when you want your application to +# customize pluralization rules. +# +# To enable locale specific pluralizations you can simply include the +# Pluralization module to the Simple backend - or whatever other backend you +# are using. +# +# I18n::Backend::Simple.include(I18n::Backend::Pluralization) +# +# You also need to make sure to provide pluralization algorithms to the +# backend, i.e. include them to your I18n.load_path accordingly. +module I18n + module Backend + module Pluralization + # Overwrites the Base backend translate method so that it will check the + # translation meta data space (:i18n) for a locale specific pluralization + # rule and use it to pluralize the given entry. I.e., the library expects + # pluralization rules to be stored at I18n.t(:'i18n.plural.rule') + # + # Pluralization rules are expected to respond to #call(count) and + # return a pluralization key. Valid keys depend on the pluralization + # rules for the locale, as defined in the CLDR. + # As of v41, 6 locale-specific plural categories are defined: + # :few, :many, :one, :other, :two, :zero + # + # n.b., The :one plural category does not imply the number 1. + # Instead, :one is a category for any number that behaves like 1 in + # that locale. For example, in some locales, :one is used for numbers + # that end in "1" (like 1, 21, 151) but that don't end in + # 11 (like 11, 111, 10311). + # Similar notes apply to the :two, and :zero plural categories. + # + # If you want to have different strings for the categories of count == 0 + # (e.g. "I don't have any cars") or count == 1 (e.g. "I have a single car") + # use the explicit `"0"` and `"1"` keys. + # https://unicode-org.github.io/cldr/ldml/tr35-numbers.html#Explicit_0_1_rules + def pluralize(locale, entry, count) + return entry unless entry.is_a?(Hash) && count + + pluralizer = pluralizer(locale) + if pluralizer.respond_to?(:call) + # Deprecation: The use of the `zero` key in this way is incorrect. + # Users that want a different string for the case of `count == 0` should use the explicit "0" key instead. + # We keep this incorrect behaviour for now for backwards compatibility until we can remove it. + # Ref: https://github.com/ruby-i18n/i18n/issues/629 + return entry[:zero] if count == 0 && entry.has_key?(:zero) + + # "0" and "1" are special cases + # https://unicode-org.github.io/cldr/ldml/tr35-numbers.html#Explicit_0_1_rules + if count == 0 || count == 1 + value = entry[symbolic_count(count)] + return value if value + end + + # Lateral Inheritance of "count" attribute (http://www.unicode.org/reports/tr35/#Lateral_Inheritance): + # > If there is no value for a path, and that path has a [@count="x"] attribute and value, then: + # > 1. If "x" is numeric, the path falls back to the path with [@count=«the plural rules category for x for that locale»], within that the same locale. + # > 2. If "x" is anything but "other", it falls back to a path [@count="other"], within that the same locale. + # > 3. If "x" is "other", it falls back to the path that is completely missing the count item, within that the same locale. + # Note: We don't yet implement #3 above, since we haven't decided how lateral inheritance attributes should be represented. + plural_rule_category = pluralizer.call(count) + + value = if entry.has_key?(plural_rule_category) || entry.has_key?(:other) + entry[plural_rule_category] || entry[:other] + else + raise InvalidPluralizationData.new(entry, count, plural_rule_category) + end + else + super + end + end + + protected + + def pluralizers + @pluralizers ||= {} + end + + def pluralizer(locale) + pluralizers[locale] ||= I18n.t(:'i18n.plural.rule', :locale => locale, :resolve => false) + end + + private + + # Normalizes categories of 0.0 and 1.0 + # and returns the symbolic version + def symbolic_count(count) + count = 0 if count == 0 + count = 1 if count == 1 + count.to_s.to_sym + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/simple.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/simple.rb new file mode 100644 index 00000000..2cac2452 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/simple.rb @@ -0,0 +1,113 @@ +# frozen_string_literal: true + +require 'i18n/backend/base' + +module I18n + module Backend + # A simple backend that reads translations from YAML files and stores them in + # an in-memory hash. Relies on the Base backend. + # + # The implementation is provided by a Implementation module allowing to easily + # extend Simple backend's behavior by including modules. E.g.: + # + # module I18n::Backend::Pluralization + # def pluralize(*args) + # # extended pluralization logic + # super + # end + # end + # + # I18n::Backend::Simple.include(I18n::Backend::Pluralization) + class Simple + module Implementation + include Base + + # Mutex to ensure that concurrent translations loading will be thread-safe + MUTEX = Mutex.new + + def initialized? + @initialized ||= false + end + + # Stores translations for the given locale in memory. + # This uses a deep merge for the translations hash, so existing + # translations will be overwritten by new ones only at the deepest + # level of the hash. + def store_translations(locale, data, options = EMPTY_HASH) + if I18n.enforce_available_locales && + I18n.available_locales_initialized? && + !I18n.locale_available?(locale) + return data + end + locale = locale.to_sym + translations[locale] ||= Concurrent::Hash.new + data = Utils.deep_symbolize_keys(data) unless options.fetch(:skip_symbolize_keys, false) + Utils.deep_merge!(translations[locale], data) + end + + # Get available locales from the translations hash + def available_locales + init_translations unless initialized? + translations.inject([]) do |locales, (locale, data)| + locales << locale unless data.size <= 1 && (data.empty? || data.has_key?(:i18n)) + locales + end + end + + # Clean up translations hash and set initialized to false on reload! + def reload! + @initialized = false + @translations = nil + super + end + + def eager_load! + init_translations unless initialized? + super + end + + def translations(do_init: false) + # To avoid returning empty translations, + # call `init_translations` + init_translations if do_init && !initialized? + + @translations ||= Concurrent::Hash.new do |h, k| + MUTEX.synchronize do + h[k] = Concurrent::Hash.new + end + end + end + + protected + + def init_translations + load_translations + @initialized = true + end + + # Looks up a translation from the translations hash. Returns nil if + # either key is nil, or locale, scope or key do not exist as a key in the + # nested translations hash. Splits keys or scopes containing dots + # into multiple keys, i.e. currency.format is regarded the same as + # %w(currency format). + def lookup(locale, key, scope = [], options = EMPTY_HASH) + init_translations unless initialized? + keys = I18n.normalize_keys(locale, key, scope, options[:separator]) + + keys.inject(translations) do |result, _key| + return nil unless result.is_a?(Hash) + unless result.has_key?(_key) + _key = _key.to_s.to_sym + return nil unless result.has_key?(_key) + end + result = result[_key] + result = resolve_entry(locale, _key, result, Utils.except(options.merge(:scope => nil), :count)) if result.is_a?(Symbol) + result + end + end + end + + include Implementation + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/transliterator.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/transliterator.rb new file mode 100644 index 00000000..70c0df3d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/backend/transliterator.rb @@ -0,0 +1,108 @@ +# encoding: utf-8 +# frozen_string_literal: true + +module I18n + module Backend + module Transliterator + DEFAULT_REPLACEMENT_CHAR = "?" + + # Given a locale and a UTF-8 string, return the locale's ASCII + # approximation for the string. + def transliterate(locale, string, replacement = nil) + @transliterators ||= {} + @transliterators[locale] ||= Transliterator.get I18n.t(:'i18n.transliterate.rule', + :locale => locale, :resolve => false, :default => {}) + @transliterators[locale].transliterate(string, replacement) + end + + # Get a transliterator instance. + def self.get(rule = nil) + if !rule || rule.kind_of?(Hash) + HashTransliterator.new(rule) + elsif rule.kind_of? Proc + ProcTransliterator.new(rule) + else + raise I18n::ArgumentError, "Transliteration rule must be a proc or a hash." + end + end + + # A transliterator which accepts a Proc as its transliteration rule. + class ProcTransliterator + def initialize(rule) + @rule = rule + end + + def transliterate(string, replacement = nil) + @rule.call(string) + end + end + + # A transliterator which accepts a Hash of characters as its translation + # rule. + class HashTransliterator + DEFAULT_APPROXIMATIONS = { + "À"=>"A", "Á"=>"A", "Â"=>"A", "Ã"=>"A", "Ä"=>"A", "Å"=>"A", "Æ"=>"AE", + "Ç"=>"C", "È"=>"E", "É"=>"E", "Ê"=>"E", "Ë"=>"E", "Ì"=>"I", "Í"=>"I", + "Î"=>"I", "Ï"=>"I", "Ð"=>"D", "Ñ"=>"N", "Ò"=>"O", "Ó"=>"O", "Ô"=>"O", + "Õ"=>"O", "Ö"=>"O", "×"=>"x", "Ø"=>"O", "Ù"=>"U", "Ú"=>"U", "Û"=>"U", + "Ü"=>"U", "Ý"=>"Y", "Þ"=>"Th", "ß"=>"ss", "ẞ"=>"SS", "à"=>"a", + "á"=>"a", "â"=>"a", "ã"=>"a", "ä"=>"a", "å"=>"a", "æ"=>"ae", "ç"=>"c", + "è"=>"e", "é"=>"e", "ê"=>"e", "ë"=>"e", "ì"=>"i", "í"=>"i", "î"=>"i", + "ï"=>"i", "ð"=>"d", "ñ"=>"n", "ò"=>"o", "ó"=>"o", "ô"=>"o", "õ"=>"o", + "ö"=>"o", "ø"=>"o", "ù"=>"u", "ú"=>"u", "û"=>"u", "ü"=>"u", "ý"=>"y", + "þ"=>"th", "ÿ"=>"y", "Ā"=>"A", "ā"=>"a", "Ă"=>"A", "ă"=>"a", "Ą"=>"A", + "ą"=>"a", "Ć"=>"C", "ć"=>"c", "Ĉ"=>"C", "ĉ"=>"c", "Ċ"=>"C", "ċ"=>"c", + "Č"=>"C", "č"=>"c", "Ď"=>"D", "ď"=>"d", "Đ"=>"D", "đ"=>"d", "Ē"=>"E", + "ē"=>"e", "Ĕ"=>"E", "ĕ"=>"e", "Ė"=>"E", "ė"=>"e", "Ę"=>"E", "ę"=>"e", + "Ě"=>"E", "ě"=>"e", "Ĝ"=>"G", "ĝ"=>"g", "Ğ"=>"G", "ğ"=>"g", "Ġ"=>"G", + "ġ"=>"g", "Ģ"=>"G", "ģ"=>"g", "Ĥ"=>"H", "ĥ"=>"h", "Ħ"=>"H", "ħ"=>"h", + "Ĩ"=>"I", "ĩ"=>"i", "Ī"=>"I", "ī"=>"i", "Ĭ"=>"I", "ĭ"=>"i", "Į"=>"I", + "į"=>"i", "İ"=>"I", "ı"=>"i", "IJ"=>"IJ", "ij"=>"ij", "Ĵ"=>"J", "ĵ"=>"j", + "Ķ"=>"K", "ķ"=>"k", "ĸ"=>"k", "Ĺ"=>"L", "ĺ"=>"l", "Ļ"=>"L", "ļ"=>"l", + "Ľ"=>"L", "ľ"=>"l", "Ŀ"=>"L", "ŀ"=>"l", "Ł"=>"L", "ł"=>"l", "Ń"=>"N", + "ń"=>"n", "Ņ"=>"N", "ņ"=>"n", "Ň"=>"N", "ň"=>"n", "ʼn"=>"'n", "Ŋ"=>"NG", + "ŋ"=>"ng", "Ō"=>"O", "ō"=>"o", "Ŏ"=>"O", "ŏ"=>"o", "Ő"=>"O", "ő"=>"o", + "Œ"=>"OE", "œ"=>"oe", "Ŕ"=>"R", "ŕ"=>"r", "Ŗ"=>"R", "ŗ"=>"r", "Ř"=>"R", + "ř"=>"r", "Ś"=>"S", "ś"=>"s", "Ŝ"=>"S", "ŝ"=>"s", "Ş"=>"S", "ş"=>"s", + "Š"=>"S", "š"=>"s", "Ţ"=>"T", "ţ"=>"t", "Ť"=>"T", "ť"=>"t", "Ŧ"=>"T", + "ŧ"=>"t", "Ũ"=>"U", "ũ"=>"u", "Ū"=>"U", "ū"=>"u", "Ŭ"=>"U", "ŭ"=>"u", + "Ů"=>"U", "ů"=>"u", "Ű"=>"U", "ű"=>"u", "Ų"=>"U", "ų"=>"u", "Ŵ"=>"W", + "ŵ"=>"w", "Ŷ"=>"Y", "ŷ"=>"y", "Ÿ"=>"Y", "Ź"=>"Z", "ź"=>"z", "Ż"=>"Z", + "ż"=>"z", "Ž"=>"Z", "ž"=>"z" + }.freeze + + def initialize(rule = nil) + @rule = rule + add_default_approximations + add rule if rule + end + + def transliterate(string, replacement = nil) + replacement ||= DEFAULT_REPLACEMENT_CHAR + string.gsub(/[^\x00-\x7f]/u) do |char| + approximations[char] || replacement + end + end + + private + + def approximations + @approximations ||= {} + end + + def add_default_approximations + DEFAULT_APPROXIMATIONS.each do |key, value| + approximations[key] = value + end + end + + # Add transliteration rules to the approximations hash. + def add(hash) + hash.each do |key, value| + approximations[key.to_s] = value.to_s + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/config.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/config.rb new file mode 100644 index 00000000..9878e02e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/config.rb @@ -0,0 +1,165 @@ +# frozen_string_literal: true + +require 'set' + +module I18n + class Config + # The only configuration value that is not global and scoped to thread is :locale. + # It defaults to the default_locale. + def locale + defined?(@locale) && @locale != nil ? @locale : default_locale + end + + # Sets the current locale pseudo-globally, i.e. in the Thread.current hash. + def locale=(locale) + I18n.enforce_available_locales!(locale) + @locale = locale && locale.to_sym + end + + # Returns the current backend. Defaults to +Backend::Simple+. + def backend + @@backend ||= Backend::Simple.new + end + + # Sets the current backend. Used to set a custom backend. + def backend=(backend) + @@backend = backend + end + + # Returns the current default locale. Defaults to :'en' + def default_locale + @@default_locale ||= :en + end + + # Sets the current default locale. Used to set a custom default locale. + def default_locale=(locale) + I18n.enforce_available_locales!(locale) + @@default_locale = locale && locale.to_sym + end + + # Returns an array of locales for which translations are available. + # Unless you explicitly set these through I18n.available_locales= + # the call will be delegated to the backend. + def available_locales + @@available_locales ||= nil + @@available_locales || backend.available_locales + end + + # Caches the available locales list as both strings and symbols in a Set, so + # that we can have faster lookups to do the available locales enforce check. + def available_locales_set #:nodoc: + @@available_locales_set ||= available_locales.inject(Set.new) do |set, locale| + set << locale.to_s << locale.to_sym + end + end + + # Sets the available locales. + def available_locales=(locales) + @@available_locales = Array(locales).map { |locale| locale.to_sym } + @@available_locales = nil if @@available_locales.empty? + @@available_locales_set = nil + end + + # Returns true if the available_locales have been initialized + def available_locales_initialized? + ( !!defined?(@@available_locales) && !!@@available_locales ) + end + + # Clears the available locales set so it can be recomputed again after I18n + # gets reloaded. + def clear_available_locales_set #:nodoc: + @@available_locales_set = nil + end + + # Returns the current default scope separator. Defaults to '.' + def default_separator + @@default_separator ||= '.' + end + + # Sets the current default scope separator. + def default_separator=(separator) + @@default_separator = separator + end + + # Returns the current exception handler. Defaults to an instance of + # I18n::ExceptionHandler. + def exception_handler + @@exception_handler ||= ExceptionHandler.new + end + + # Sets the exception handler. + def exception_handler=(exception_handler) + @@exception_handler = exception_handler + end + + # Returns the current handler for situations when interpolation argument + # is missing. MissingInterpolationArgument will be raised by default. + def missing_interpolation_argument_handler + @@missing_interpolation_argument_handler ||= lambda do |missing_key, provided_hash, string| + raise MissingInterpolationArgument.new(missing_key, provided_hash, string) + end + end + + # Sets the missing interpolation argument handler. It can be any + # object that responds to #call. The arguments that will be passed to #call + # are the same as for MissingInterpolationArgument initializer. Use +Proc.new+ + # if you don't care about arity. + # + # == Example: + # You can suppress raising an exception and return string instead: + # + # I18n.config.missing_interpolation_argument_handler = Proc.new do |key| + # "#{key} is missing" + # end + def missing_interpolation_argument_handler=(exception_handler) + @@missing_interpolation_argument_handler = exception_handler + end + + # Allow clients to register paths providing translation data sources. The + # backend defines acceptable sources. + # + # E.g. the provided SimpleBackend accepts a list of paths to translation + # files which are either named *.rb and contain plain Ruby Hashes or are + # named *.yml and contain YAML data. So for the SimpleBackend clients may + # register translation files like this: + # I18n.load_path << 'path/to/locale/en.yml' + def load_path + @@load_path ||= [] + end + + # Sets the load path instance. Custom implementations are expected to + # behave like a Ruby Array. + def load_path=(load_path) + @@load_path = load_path + @@available_locales_set = nil + backend.reload! + end + + # Whether or not to verify if locales are in the list of available locales. + # Defaults to true. + @@enforce_available_locales = true + def enforce_available_locales + @@enforce_available_locales + end + + def enforce_available_locales=(enforce_available_locales) + @@enforce_available_locales = enforce_available_locales + end + + # Returns the current interpolation patterns. Defaults to + # I18n::DEFAULT_INTERPOLATION_PATTERNS. + def interpolation_patterns + @@interpolation_patterns ||= I18n::DEFAULT_INTERPOLATION_PATTERNS.dup + end + + # Sets the current interpolation patterns. Used to set a interpolation + # patterns. + # + # E.g. using {{}} as a placeholder like "{{hello}}, world!": + # + # I18n.config.interpolation_patterns << /\{\{(\w+)\}\}/ + def interpolation_patterns=(interpolation_patterns) + @@interpolation_patterns = interpolation_patterns + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/exceptions.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/exceptions.rb new file mode 100644 index 00000000..23ca46ec --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/exceptions.rb @@ -0,0 +1,157 @@ +# frozen_string_literal: true + +require 'cgi' + +module I18n + class ExceptionHandler + def call(exception, _locale, _key, _options) + if exception.is_a?(MissingTranslation) + exception.message + else + raise exception + end + end + end + + class ArgumentError < ::ArgumentError; end + + class Disabled < ArgumentError + def initialize(method) + super(<<~MESSAGE) + I18n.#{method} is currently disabled, likely because your application is still in its loading phase. + + This method is meant to display text in the user locale, so calling it before the user locale has + been set is likely to display text from the wrong locale to some users. + + If you have a legitimate reason to access i18n data outside of the user flow, you can do so by passing + the desired locale explicitly with the `locale` argument, e.g. `I18n.#{method}(..., locale: :en)` + MESSAGE + end + end + + class InvalidLocale < ArgumentError + attr_reader :locale + def initialize(locale) + @locale = locale + super "#{locale.inspect} is not a valid locale" + end + end + + class InvalidLocaleData < ArgumentError + attr_reader :filename + def initialize(filename, exception_message) + @filename, @exception_message = filename, exception_message + super "can not load translations from #{filename}: #{exception_message}" + end + end + + class MissingTranslation < ArgumentError + module Base + PERMITTED_KEYS = [:scope, :default].freeze + + attr_reader :locale, :key, :options + + def initialize(locale, key, options = EMPTY_HASH) + @key, @locale, @options = key, locale, options.slice(*PERMITTED_KEYS) + options.each { |k, v| self.options[k] = v.inspect if v.is_a?(Proc) } + end + + def keys + @keys ||= I18n.normalize_keys(locale, key, options[:scope]).tap do |keys| + keys << 'no key' if keys.size < 2 + end + end + + def message + if (default = options[:default]).is_a?(Array) && default.any? + other_options = ([key, *default]).map { |k| normalized_option(k).prepend('- ') }.join("\n") + "Translation missing. Options considered were:\n#{other_options}" + else + "Translation missing: #{keys.join('.')}" + end + end + + def normalized_option(key) + I18n.normalize_keys(locale, key, options[:scope]).join('.') + end + + alias :to_s :message + + def to_exception + MissingTranslationData.new(locale, key, options) + end + end + + include Base + end + + class MissingTranslationData < ArgumentError + include MissingTranslation::Base + end + + class InvalidPluralizationData < ArgumentError + attr_reader :entry, :count, :key + def initialize(entry, count, key) + @entry, @count, @key = entry, count, key + super "translation data #{entry.inspect} can not be used with :count => #{count}. key '#{key}' is missing." + end + end + + class MissingInterpolationArgument < ArgumentError + attr_reader :key, :values, :string + def initialize(key, values, string) + @key, @values, @string = key, values, string + super "missing interpolation argument #{key.inspect} in #{string.inspect} (#{values.inspect} given)" + end + end + + class ReservedInterpolationKey < ArgumentError + attr_reader :key, :string + def initialize(key, string) + @key, @string = key, string + super "reserved key #{key.inspect} used in #{string.inspect}" + end + end + + class UnknownFileType < ArgumentError + attr_reader :type, :filename + def initialize(type, filename) + @type, @filename = type, filename + super "can not load translations from #{filename}, the file type #{type} is not known" + end + end + + class UnsupportedMethod < ArgumentError + attr_reader :method, :backend_klass, :msg + def initialize(method, backend_klass, msg) + @method = method + @backend_klass = backend_klass + @msg = msg + super "#{backend_klass} does not support the ##{method} method. #{msg}" + end + end + + class InvalidFilenames < ArgumentError + NUMBER_OF_ERRORS_SHOWN = 20 + def initialize(file_errors) + super <<~MSG + Found #{file_errors.count} error(s). + The first #{[file_errors.count, NUMBER_OF_ERRORS_SHOWN].min} error(s): + #{file_errors.map(&:message).first(NUMBER_OF_ERRORS_SHOWN).join("\n")} + + To use the LazyLoadable backend: + 1. Filenames must start with the locale. + 2. An underscore must separate the locale with any optional text that follows. + 3. The file must only contain translation data for the single locale. + + Example: + "/config/locales/fr.yml" which contains: + ```yml + fr: + dog: + chien + ``` + MSG + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/gettext.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/gettext.rb new file mode 100644 index 00000000..858daff4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/gettext.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module I18n + module Gettext + PLURAL_SEPARATOR = "\001" + CONTEXT_SEPARATOR = "\004" + + autoload :Helpers, 'i18n/gettext/helpers' + + @@plural_keys = { :en => [:one, :other] } + + class << self + # returns an array of plural keys for the given locale or the whole hash + # of locale mappings to plural keys so that we can convert from gettext's + # integer-index based style + # TODO move this information to the pluralization module + def plural_keys(*args) + args.empty? ? @@plural_keys : @@plural_keys[args.first] || @@plural_keys[:en] + end + + def extract_scope(msgid, separator) + scope = msgid.to_s.split(separator) + msgid = scope.pop + [scope, msgid] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/gettext/helpers.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/gettext/helpers.rb new file mode 100644 index 00000000..d077619f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/gettext/helpers.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +require 'i18n/gettext' + +module I18n + module Gettext + # Implements classical Gettext style accessors. To use this include the + # module to the global namespace or wherever you want to use it. + # + # include I18n::Gettext::Helpers + module Helpers + # Makes dynamic translation messages readable for the gettext parser. + # _(fruit) cannot be understood by the gettext parser. To help the parser find all your translations, + # you can add fruit = N_("Apple") which does not translate, but tells the parser: "Apple" needs translation. + # * msgid: the message id. + # * Returns: msgid. + def N_(msgsid) + msgsid + end + + def gettext(msgid, options = EMPTY_HASH) + I18n.t(msgid, **{:default => msgid, :separator => '|'}.merge(options)) + end + alias _ gettext + + def sgettext(msgid, separator = '|') + scope, msgid = I18n::Gettext.extract_scope(msgid, separator) + I18n.t(msgid, :scope => scope, :default => msgid, :separator => separator) + end + alias s_ sgettext + + def pgettext(msgctxt, msgid) + separator = I18n::Gettext::CONTEXT_SEPARATOR + sgettext([msgctxt, msgid].join(separator), separator) + end + alias p_ pgettext + + def ngettext(msgid, msgid_plural, n = 1) + nsgettext(msgid, msgid_plural, n) + end + alias n_ ngettext + + # Method signatures: + # nsgettext('Fruits|apple', 'apples', 2) + # nsgettext(['Fruits|apple', 'apples'], 2) + def nsgettext(msgid, msgid_plural, n = 1, separator = '|') + if msgid.is_a?(Array) + msgid, msgid_plural, n, separator = msgid[0], msgid[1], msgid_plural, n + separator = '|' unless separator.is_a?(::String) + end + + scope, msgid = I18n::Gettext.extract_scope(msgid, separator) + default = { :one => msgid, :other => msgid_plural } + I18n.t(msgid, :default => default, :count => n, :scope => scope, :separator => separator) + end + alias ns_ nsgettext + + # Method signatures: + # npgettext('Fruits', 'apple', 'apples', 2) + # npgettext('Fruits', ['apple', 'apples'], 2) + def npgettext(msgctxt, msgid, msgid_plural, n = 1) + separator = I18n::Gettext::CONTEXT_SEPARATOR + + if msgid.is_a?(Array) + msgid_plural, msgid, n = msgid[1], [msgctxt, msgid[0]].join(separator), msgid_plural + else + msgid = [msgctxt, msgid].join(separator) + end + + nsgettext(msgid, msgid_plural, n, separator) + end + alias np_ npgettext + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/gettext/po_parser.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/gettext/po_parser.rb new file mode 100644 index 00000000..a07fdc58 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/gettext/po_parser.rb @@ -0,0 +1,329 @@ +=begin + poparser.rb - Generate a .mo + + Copyright (C) 2003-2009 Masao Mutoh + + You may redistribute it and/or modify it under the same + license terms as Ruby. +=end + +#MODIFIED +# removed include GetText etc +# added stub translation method _(x) +require 'racc/parser' + +module GetText + + class PoParser < Racc::Parser + + def _(x) + x + end + +module_eval <<'..end src/poparser.ry modeval..id7a99570e05', 'src/poparser.ry', 108 + def unescape(orig) + ret = orig.gsub(/\\n/, "\n") + ret.gsub!(/\\t/, "\t") + ret.gsub!(/\\r/, "\r") + ret.gsub!(/\\"/, "\"") + ret + end + + def parse(str, data, ignore_fuzzy = true) + @comments = [] + @data = data + @fuzzy = false + @msgctxt = "" + $ignore_fuzzy = ignore_fuzzy + + str.strip! + @q = [] + until str.empty? do + case str + when /\A\s+/ + str = $' + when /\Amsgctxt/ + @q.push [:MSGCTXT, $&] + str = $' + when /\Amsgid_plural/ + @q.push [:MSGID_PLURAL, $&] + str = $' + when /\Amsgid/ + @q.push [:MSGID, $&] + str = $' + when /\Amsgstr/ + @q.push [:MSGSTR, $&] + str = $' + when /\A\[(\d+)\]/ + @q.push [:PLURAL_NUM, $1] + str = $' + when /\A\#~(.*)/ + $stderr.print _("Warning: obsolete msgid exists.\n") + $stderr.print " #{$&}\n" + @q.push [:COMMENT, $&] + str = $' + when /\A\#(.*)/ + @q.push [:COMMENT, $&] + str = $' + when /\A\"(.*)\"/ + @q.push [:STRING, $1] + str = $' + else + #c = str[0,1] + #@q.push [:STRING, c] + str = str[1..-1] + end + end + @q.push [false, '$end'] + if $DEBUG + @q.each do |a,b| + puts "[#{a}, #{b}]" + end + end + @yydebug = true if $DEBUG + do_parse + + if @comments.size > 0 + @data.set_comment(:last, @comments.join("\n")) + end + @data + end + + def next_token + @q.shift + end + + def on_message(msgid, msgstr) + if msgstr.size > 0 + @data[msgid] = msgstr + @data.set_comment(msgid, @comments.join("\n")) + end + @comments.clear + @msgctxt = "" + end + + def on_comment(comment) + @fuzzy = true if (/fuzzy/ =~ comment) + @comments << comment + end + + +..end src/poparser.ry modeval..id7a99570e05 + +##### racc 1.4.5 generates ### + +racc_reduce_table = [ + 0, 0, :racc_error, + 0, 10, :_reduce_none, + 2, 10, :_reduce_none, + 2, 10, :_reduce_none, + 2, 10, :_reduce_none, + 2, 12, :_reduce_5, + 1, 13, :_reduce_none, + 1, 13, :_reduce_none, + 4, 15, :_reduce_8, + 5, 16, :_reduce_9, + 2, 17, :_reduce_10, + 1, 17, :_reduce_none, + 3, 18, :_reduce_12, + 1, 11, :_reduce_13, + 2, 14, :_reduce_14, + 1, 14, :_reduce_15 ] + +racc_reduce_n = 16 + +racc_shift_n = 26 + +racc_action_table = [ + 3, 13, 5, 7, 9, 15, 16, 17, 20, 17, + 13, 17, 13, 13, 11, 17, 23, 20, 13, 17 ] + +racc_action_check = [ + 1, 16, 1, 1, 1, 12, 12, 12, 18, 18, + 7, 14, 15, 9, 3, 19, 20, 21, 23, 25 ] + +racc_action_pointer = [ + nil, 0, nil, 14, nil, nil, nil, 3, nil, 6, + nil, nil, 0, nil, 4, 5, -6, nil, 2, 8, + 8, 11, nil, 11, nil, 12 ] + +racc_action_default = [ + -1, -16, -2, -16, -3, -13, -4, -16, -6, -16, + -7, 26, -16, -15, -5, -16, -16, -14, -16, -8, + -16, -9, -11, -16, -10, -12 ] + +racc_goto_table = [ + 12, 22, 14, 4, 24, 6, 2, 8, 18, 19, + 10, 21, 1, nil, nil, nil, 25 ] + +racc_goto_check = [ + 5, 9, 5, 3, 9, 4, 2, 6, 5, 5, + 7, 8, 1, nil, nil, nil, 5 ] + +racc_goto_pointer = [ + nil, 12, 5, 2, 4, -7, 6, 9, -7, -17 ] + +racc_goto_default = [ + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil ] + +racc_token_table = { + false => 0, + Object.new => 1, + :COMMENT => 2, + :MSGID => 3, + :MSGCTXT => 4, + :MSGID_PLURAL => 5, + :MSGSTR => 6, + :STRING => 7, + :PLURAL_NUM => 8 } + +racc_use_result_var = true + +racc_nt_base = 9 + +Racc_arg = [ + racc_action_table, + racc_action_check, + racc_action_default, + racc_action_pointer, + racc_goto_table, + racc_goto_check, + racc_goto_default, + racc_goto_pointer, + racc_nt_base, + racc_reduce_table, + racc_token_table, + racc_shift_n, + racc_reduce_n, + racc_use_result_var ] + +Racc_token_to_s_table = [ +'$end', +'error', +'COMMENT', +'MSGID', +'MSGCTXT', +'MSGID_PLURAL', +'MSGSTR', +'STRING', +'PLURAL_NUM', +'$start', +'msgfmt', +'comment', +'msgctxt', +'message', +'string_list', +'single_message', +'plural_message', +'msgstr_plural', +'msgstr_plural_line'] + +Racc_debug_parser = true + +##### racc system variables end ##### + + # reduce 0 omitted + + # reduce 1 omitted + + # reduce 2 omitted + + # reduce 3 omitted + + # reduce 4 omitted + +module_eval <<'.,.,', 'src/poparser.ry', 25 + def _reduce_5( val, _values, result ) + @msgctxt = unescape(val[1]) + "\004" + result + end +.,., + + # reduce 6 omitted + + # reduce 7 omitted + +module_eval <<'.,.,', 'src/poparser.ry', 48 + def _reduce_8( val, _values, result ) + if @fuzzy and $ignore_fuzzy + if val[1] != "" + $stderr.print _("Warning: fuzzy message was ignored.\n") + $stderr.print " msgid '#{val[1]}'\n" + else + on_message('', unescape(val[3])) + end + @fuzzy = false + else + on_message(@msgctxt + unescape(val[1]), unescape(val[3])) + end + result = "" + result + end +.,., + +module_eval <<'.,.,', 'src/poparser.ry', 65 + def _reduce_9( val, _values, result ) + if @fuzzy and $ignore_fuzzy + if val[1] != "" + $stderr.print _("Warning: fuzzy message was ignored.\n") + $stderr.print "msgid = '#{val[1]}\n" + else + on_message('', unescape(val[3])) + end + @fuzzy = false + else + on_message(@msgctxt + unescape(val[1]) + "\000" + unescape(val[3]), unescape(val[4])) + end + result = "" + result + end +.,., + +module_eval <<'.,.,', 'src/poparser.ry', 76 + def _reduce_10( val, _values, result ) + if val[0].size > 0 + result = val[0] + "\000" + val[1] + else + result = "" + end + result + end +.,., + + # reduce 11 omitted + +module_eval <<'.,.,', 'src/poparser.ry', 84 + def _reduce_12( val, _values, result ) + result = val[2] + result + end +.,., + +module_eval <<'.,.,', 'src/poparser.ry', 91 + def _reduce_13( val, _values, result ) + on_comment(val[0]) + result + end +.,., + +module_eval <<'.,.,', 'src/poparser.ry', 99 + def _reduce_14( val, _values, result ) + result = val.delete_if{|item| item == ""}.join + result + end +.,., + +module_eval <<'.,.,', 'src/poparser.ry', 103 + def _reduce_15( val, _values, result ) + result = val[0] + result + end +.,., + + def _reduce_none( val, _values, result ) + result + end + + end # class PoParser + +end # module GetText diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/interpolate/ruby.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/interpolate/ruby.rb new file mode 100644 index 00000000..5b50593f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/interpolate/ruby.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +# heavily based on Masao Mutoh's gettext String interpolation extension +# http://github.com/mutoh/gettext/blob/f6566738b981fe0952548c421042ad1e0cdfb31e/lib/gettext/core_ext/string.rb + +module I18n + DEFAULT_INTERPOLATION_PATTERNS = [ + /%%/, + /%\{([\w|]+)\}/, # matches placeholders like "%{foo} or %{foo|word}" + /%<(\w+)>([^\d]*?\d*\.?\d*[bBdiouxXeEfgGcps])/ # matches placeholders like "%.d" + ].freeze + INTERPOLATION_PATTERN = Regexp.union(DEFAULT_INTERPOLATION_PATTERNS) + deprecate_constant :INTERPOLATION_PATTERN + + INTERPOLATION_PATTERNS_CACHE = Hash.new do |hash, patterns| + hash[patterns] = Regexp.union(patterns) + end + private_constant :INTERPOLATION_PATTERNS_CACHE + + class << self + # Return String or raises MissingInterpolationArgument exception. + # Missing argument's logic is handled by I18n.config.missing_interpolation_argument_handler. + def interpolate(string, values) + raise ReservedInterpolationKey.new($1.to_sym, string) if string =~ I18n.reserved_keys_pattern + raise ArgumentError.new('Interpolation values must be a Hash.') unless values.kind_of?(Hash) + interpolate_hash(string, values) + end + + def interpolate_hash(string, values) + pattern = INTERPOLATION_PATTERNS_CACHE[config.interpolation_patterns] + interpolated = false + + interpolated_string = string.gsub(pattern) do |match| + interpolated = true + + if match == '%%' + '%' + else + key = ($1 || $2 || match.tr("%{}", "")).to_sym + value = if values.key?(key) + values[key] + else + config.missing_interpolation_argument_handler.call(key, values, string) + end + value = value.call(values) if value.respond_to?(:call) + $3 ? sprintf("%#{$3}", value) : value + end + end + + interpolated ? interpolated_string : string + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/locale.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/locale.rb new file mode 100644 index 00000000..c4078e61 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/locale.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +module I18n + module Locale + autoload :Fallbacks, 'i18n/locale/fallbacks' + autoload :Tag, 'i18n/locale/tag' + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/locale/fallbacks.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/locale/fallbacks.rb new file mode 100644 index 00000000..56d08d71 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/locale/fallbacks.rb @@ -0,0 +1,107 @@ +# Locale Fallbacks +# +# Extends the I18n module to hold a fallbacks instance which is set to an +# instance of I18n::Locale::Fallbacks by default but can be swapped with a +# different implementation. +# +# Locale fallbacks will compute a number of fallback locales for a given locale. +# For example: +# +#

+# I18n.fallbacks[:"es-MX"] # => [:"es-MX", :es, :en] 
+# +# Locale fallbacks always fall back to +# +# * all parent locales of a given locale (e.g. :es for :"es-MX") first, +# * the current default locales and all of their parents second +# +# The default locales are set to [] by default but can be set to something else. +# +# One can additionally add any number of additional fallback locales manually. +# These will be added before the default locales to the fallback chain. For +# example: +# +# # using a custom locale as default fallback locale +# +# I18n.fallbacks = I18n::Locale::Fallbacks.new(:"en-GB", :"de-AT" => :de, :"de-CH" => :de) +# I18n.fallbacks[:"de-AT"] # => [:"de-AT", :de, :"en-GB", :en] +# I18n.fallbacks[:"de-CH"] # => [:"de-CH", :de, :"en-GB", :en] +# +# # mapping fallbacks to an existing instance +# +# # people speaking Catalan also speak Spanish as spoken in Spain +# fallbacks = I18n.fallbacks +# fallbacks.map(:ca => :"es-ES") +# fallbacks[:ca] # => [:ca, :"es-ES", :es, :"en-US", :en] +# +# # people speaking Arabian as spoken in Palestine also speak Hebrew as spoken in Israel +# fallbacks.map(:"ar-PS" => :"he-IL") +# fallbacks[:"ar-PS"] # => [:"ar-PS", :ar, :"he-IL", :he, :"en-US", :en] +# fallbacks[:"ar-EG"] # => [:"ar-EG", :ar, :"en-US", :en] +# +# # people speaking Sami as spoken in Finland also speak Swedish and Finnish as spoken in Finland +# fallbacks.map(:sms => [:"se-FI", :"fi-FI"]) +# fallbacks[:sms] # => [:sms, :"se-FI", :se, :"fi-FI", :fi, :"en-US", :en] + +module I18n + module Locale + class Fallbacks < Hash + def initialize(*mappings) + @map = {} + map(mappings.pop) if mappings.last.is_a?(Hash) + self.defaults = mappings.empty? ? [] : mappings + end + + def defaults=(defaults) + @defaults = defaults.flat_map { |default| compute(default, false) } + end + attr_reader :defaults + + def [](locale) + raise InvalidLocale.new(locale) if locale.nil? + raise Disabled.new('fallback#[]') if locale == false + locale = locale.to_sym + super || store(locale, compute(locale)) + end + + def map(*args, &block) + if args.count == 1 && !block_given? + mappings = args.first + mappings.each do |from, to| + from, to = from.to_sym, Array(to) + to.each do |_to| + @map[from] ||= [] + @map[from] << _to.to_sym + end + end + else + @map.map(*args, &block) + end + end + + def empty? + @map.empty? && @defaults.empty? + end + + def inspect + "#<#{self.class.name} @map=#{@map.inspect} @defaults=#{@defaults.inspect}>" + end + + protected + + def compute(tags, include_defaults = true, exclude = []) + result = [] + Array(tags).each do |tag| + tags = I18n::Locale::Tag.tag(tag).self_and_parents.map! { |t| t.to_sym } - exclude + result += tags + tags.each { |_tag| result += compute(@map[_tag], false, exclude + result) if @map[_tag] } + end + + result.push(*defaults) if include_defaults + result.uniq! + result.compact! + result + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/locale/tag.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/locale/tag.rb new file mode 100644 index 00000000..a640b446 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/locale/tag.rb @@ -0,0 +1,28 @@ +# encoding: utf-8 + +module I18n + module Locale + module Tag + autoload :Parents, 'i18n/locale/tag/parents' + autoload :Rfc4646, 'i18n/locale/tag/rfc4646' + autoload :Simple, 'i18n/locale/tag/simple' + + class << self + # Returns the current locale tag implementation. Defaults to +I18n::Locale::Tag::Simple+. + def implementation + @@implementation ||= Simple + end + + # Sets the current locale tag implementation. Use this to set a different locale tag implementation. + def implementation=(implementation) + @@implementation = implementation + end + + # Factory method for locale tags. Delegates to the current locale tag implementation. + def tag(tag) + implementation.tag(tag) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/locale/tag/parents.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/locale/tag/parents.rb new file mode 100644 index 00000000..6283e667 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/locale/tag/parents.rb @@ -0,0 +1,24 @@ +module I18n + module Locale + module Tag + module Parents + def parent + @parent ||= + begin + segs = to_a + segs.compact! + segs.length > 1 ? self.class.tag(*segs[0..(segs.length - 2)].join('-')) : nil + end + end + + def self_and_parents + @self_and_parents ||= [self].concat parents + end + + def parents + @parents ||= parent ? [parent].concat(parent.parents) : [] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/locale/tag/rfc4646.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/locale/tag/rfc4646.rb new file mode 100644 index 00000000..4ce4c751 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/locale/tag/rfc4646.rb @@ -0,0 +1,74 @@ +# RFC 4646/47 compliant Locale tag implementation that parses locale tags to +# subtags such as language, script, region, variant etc. +# +# For more information see by http://en.wikipedia.org/wiki/IETF_language_tag +# +# Rfc4646::Parser does not implement grandfathered tags. + +module I18n + module Locale + module Tag + RFC4646_SUBTAGS = [ :language, :script, :region, :variant, :extension, :privateuse, :grandfathered ] + RFC4646_FORMATS = { :language => :downcase, :script => :capitalize, :region => :upcase, :variant => :downcase } + + class Rfc4646 < Struct.new(*RFC4646_SUBTAGS) + class << self + # Parses the given tag and returns a Tag instance if it is valid. + # Returns false if the given tag is not valid according to RFC 4646. + def tag(tag) + matches = parser.match(tag) + new(*matches) if matches + end + + def parser + @@parser ||= Rfc4646::Parser + end + + def parser=(parser) + @@parser = parser + end + end + + include Parents + + RFC4646_FORMATS.each do |name, format| + define_method(name) { self[name].send(format) unless self[name].nil? } + end + + def to_sym + to_s.to_sym + end + + def to_s + @tag ||= to_a.compact.join("-") + end + + def to_a + members.collect { |attr| self.send(attr) } + end + + module Parser + PATTERN = %r{\A(?: + ([a-z]{2,3}(?:(?:-[a-z]{3}){0,3})?|[a-z]{4}|[a-z]{5,8}) # language + (?:-([a-z]{4}))? # script + (?:-([a-z]{2}|\d{3}))? # region + (?:-([0-9a-z]{5,8}|\d[0-9a-z]{3}))* # variant + (?:-([0-9a-wyz](?:-[0-9a-z]{2,8})+))* # extension + (?:-(x(?:-[0-9a-z]{1,8})+))?| # privateuse subtag + (x(?:-[0-9a-z]{1,8})+)| # privateuse tag + /* ([a-z]{1,3}(?:-[0-9a-z]{2,8}){1,2}) */ # grandfathered + )\z}xi + + class << self + def match(tag) + c = PATTERN.match(tag.to_s).captures + c[0..4] << (c[5].nil? ? c[6] : c[5]) << c[7] # TODO c[7] is grandfathered, throw a NotImplemented exception here? + rescue + false + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/locale/tag/simple.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/locale/tag/simple.rb new file mode 100644 index 00000000..18d55c28 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/locale/tag/simple.rb @@ -0,0 +1,39 @@ +# Simple Locale tag implementation that computes subtags by simply splitting +# the locale tag at '-' occurrences. +module I18n + module Locale + module Tag + class Simple + class << self + def tag(tag) + new(tag) + end + end + + include Parents + + attr_reader :tag + + def initialize(*tag) + @tag = tag.join('-').to_sym + end + + def subtags + @subtags = tag.to_s.split('-').map!(&:to_s) + end + + def to_sym + tag + end + + def to_s + tag.to_s + end + + def to_a + subtags + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/middleware.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/middleware.rb new file mode 100644 index 00000000..59b377e2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/middleware.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module I18n + class Middleware + + def initialize(app) + @app = app + end + + def call(env) + @app.call(env) + ensure + Thread.current[:i18n_config] = I18n::Config.new + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests.rb new file mode 100644 index 00000000..30d0ed53 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module I18n + module Tests + autoload :Basics, 'i18n/tests/basics' + autoload :Defaults, 'i18n/tests/defaults' + autoload :Interpolation, 'i18n/tests/interpolation' + autoload :Link, 'i18n/tests/link' + autoload :Localization, 'i18n/tests/localization' + autoload :Lookup, 'i18n/tests/lookup' + autoload :Pluralization, 'i18n/tests/pluralization' + autoload :Procs, 'i18n/tests/procs' + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/basics.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/basics.rb new file mode 100644 index 00000000..833762be --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/basics.rb @@ -0,0 +1,58 @@ +module I18n + module Tests + module Basics + def teardown + I18n.available_locales = nil + end + + test "available_locales returns the available_locales produced by the backend, by default" do + I18n.backend.store_translations('de', :foo => 'bar') + I18n.backend.store_translations('en', :foo => 'foo') + + assert_equal I18n.available_locales, I18n.backend.available_locales + end + + test "available_locales can be set to something else independently from the actual locale data" do + I18n.backend.store_translations('de', :foo => 'bar') + I18n.backend.store_translations('en', :foo => 'foo') + + I18n.available_locales = :foo + assert_equal [:foo], I18n.available_locales + + I18n.available_locales = [:foo, 'bar'] + assert_equal [:foo, :bar], I18n.available_locales + + I18n.available_locales = nil + assert_equal I18n.available_locales, I18n.backend.available_locales + end + + test "available_locales memoizes when set explicitly" do + I18n.backend.expects(:available_locales).never + I18n.available_locales = [:foo] + I18n.backend.store_translations('de', :bar => 'baz') + I18n.reload! + assert_equal [:foo], I18n.available_locales + end + + test "available_locales delegates to the backend when not set explicitly" do + original_available_locales_value = I18n.backend.available_locales + I18n.backend.expects(:available_locales).returns(original_available_locales_value).twice + assert_equal I18n.backend.available_locales, I18n.available_locales + end + + test "exists? is implemented by the backend" do + I18n.backend.store_translations(:foo, :bar => 'baz') + assert I18n.exists?(:bar, :foo) + end + + test "storing a nil value as a translation removes it from the available locale data" do + I18n.backend.store_translations(:en, :to_be_deleted => 'bar') + assert_equal 'bar', I18n.t(:to_be_deleted, :default => 'baz') + + I18n.cache_store.clear if I18n.respond_to?(:cache_store) && I18n.cache_store + I18n.backend.store_translations(:en, :to_be_deleted => nil) + assert_equal 'baz', I18n.t(:to_be_deleted, :default => 'baz') + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/defaults.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/defaults.rb new file mode 100644 index 00000000..e5db3365 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/defaults.rb @@ -0,0 +1,59 @@ +# encoding: utf-8 + +module I18n + module Tests + module Defaults + def setup + super + I18n.backend.store_translations(:en, :foo => { :bar => 'bar', :baz => 'baz' }) + end + + test "defaults: given nil as a key it returns the given default" do + assert_equal 'default', I18n.t(nil, :default => 'default') + end + + test "defaults: given a symbol as a default it translates the symbol" do + assert_equal 'bar', I18n.t(nil, :default => :'foo.bar') + end + + test "defaults: given a symbol as a default and a scope it stays inside the scope when looking up the symbol" do + assert_equal 'bar', I18n.t(:missing, :default => :bar, :scope => :foo) + end + + test "defaults: given an array as a default it returns the first match" do + assert_equal 'bar', I18n.t(:does_not_exist, :default => [:does_not_exist_2, :'foo.bar']) + end + + test "defaults: given an array as a default with false it returns false" do + assert_equal false, I18n.t(:does_not_exist, :default => [false]) + end + + test "defaults: given false it returns false" do + assert_equal false, I18n.t(:does_not_exist, :default => false) + end + + test "defaults: given nil it returns nil" do + assert_nil I18n.t(:does_not_exist, :default => nil) + end + + test "defaults: given an array of missing keys it raises a MissingTranslationData exception" do + assert_raises I18n::MissingTranslationData do + I18n.t(:does_not_exist, :default => [:does_not_exist_2, :does_not_exist_3], :raise => true) + end + end + + test "defaults: using a custom scope separator" do + # data must have been stored using the custom separator when using the ActiveRecord backend + I18n.backend.store_translations(:en, { :foo => { :bar => 'bar' } }, { :separator => '|' }) + assert_equal 'bar', I18n.t(nil, :default => :'foo|bar', :separator => '|') + end + + # Addresses issue: #599 + test "defaults: only interpolates once when resolving defaults" do + I18n.backend.store_translations(:en, :greeting => 'hey %{name}') + assert_equal 'hey %{dont_interpolate_me}', + I18n.t(:does_not_exist, :name => '%{dont_interpolate_me}', default: [:greeting]) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/interpolation.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/interpolation.rb new file mode 100644 index 00000000..03c67db7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/interpolation.rb @@ -0,0 +1,185 @@ +# encoding: utf-8 + +module I18n + module Tests + module Interpolation + # If no interpolation parameter is not given, I18n should not alter the string. + # This behavior is due to three reasons: + # + # * Checking interpolation keys in all strings hits performance, badly; + # + # * This allows us to retrieve untouched values through I18n. For example + # I could have a middleware that returns I18n lookup results in JSON + # to be processed through Javascript. Leaving the keys untouched allows + # the interpolation to happen at the javascript level; + # + # * Security concerns: if I allow users to translate a web site, they can + # insert %{} in messages causing the I18n lookup to fail in every request. + # + test "interpolation: given no values it does not alter the string" do + assert_equal 'Hi %{name}!', interpolate(:default => 'Hi %{name}!') + end + + test "interpolation: given values it interpolates them into the string" do + assert_equal 'Hi David!', interpolate(:default => 'Hi %{name}!', :name => 'David') + end + + test "interpolation: works with a pipe" do + assert_equal 'Hi david!', interpolate(:default => 'Hi %{name|lowercase}!', :'name|lowercase' => 'david') + end + + test "interpolation: given a nil value it still interpolates it into the string" do + assert_equal 'Hi !', interpolate(:default => 'Hi %{name}!', :name => nil) + end + + test "interpolation: given a lambda as a value it calls it if the string contains the key" do + assert_equal 'Hi David!', interpolate(:default => 'Hi %{name}!', :name => lambda { |*args| 'David' }) + end + + test "interpolation: given a lambda as a value it does not call it if the string does not contain the key" do + assert_nothing_raised { interpolate(:default => 'Hi!', :name => lambda { |*args| raise 'fail' }) } + end + + test "interpolation: given values but missing a key it raises I18n::MissingInterpolationArgument" do + assert_raises(I18n::MissingInterpolationArgument) do + interpolate(:default => '%{foo}', :bar => 'bar') + end + end + + test "interpolation: it does not raise I18n::MissingInterpolationArgument for escaped variables" do + assert_nothing_raised do + assert_equal 'Barr %{foo}', interpolate(:default => '%{bar} %%{foo}', :bar => 'Barr') + end + end + + test "interpolation: it does not change the original, stored translation string" do + I18n.backend.store_translations(:en, :interpolate => 'Hi %{name}!') + assert_equal 'Hi David!', interpolate(:interpolate, :name => 'David') + assert_equal 'Hi Yehuda!', interpolate(:interpolate, :name => 'Yehuda') + end + + test "interpolation: given an array interpolates each element" do + I18n.backend.store_translations(:en, :array_interpolate => ['Hi', 'Mr. %{name}', 'or sir %{name}']) + assert_equal ['Hi', 'Mr. Bartuz', 'or sir Bartuz'], interpolate(:array_interpolate, :name => 'Bartuz') + end + + test "interpolation: given the translation is in utf-8 it still works" do + assert_equal 'Häi David!', interpolate(:default => 'Häi %{name}!', :name => 'David') + end + + test "interpolation: given the value is in utf-8 it still works" do + assert_equal 'Hi ゆきひろ!', interpolate(:default => 'Hi %{name}!', :name => 'ゆきひろ') + end + + test "interpolation: given the translation and the value are in utf-8 it still works" do + assert_equal 'こんにちは、ゆきひろさん!', interpolate(:default => 'こんにちは、%{name}さん!', :name => 'ゆきひろ') + end + + if Object.const_defined?(:Encoding) + test "interpolation: given a euc-jp translation and a utf-8 value it raises Encoding::CompatibilityError" do + assert_raises(Encoding::CompatibilityError) do + interpolate(:default => euc_jp('こんにちは、%{name}さん!'), :name => 'ゆきひろ') + end + end + + test "interpolation: given a utf-8 translation and a euc-jp value it raises Encoding::CompatibilityError" do + assert_raises(Encoding::CompatibilityError) do + interpolate(:default => 'こんにちは、%{name}さん!', :name => euc_jp('ゆきひろ')) + end + end + + test "interpolation: ASCII strings in the backend should be encoded to UTF8 if interpolation options are in UTF8" do + I18n.backend.store_translations 'en', 'encoding' => ('%{who} let me go'.force_encoding("ASCII")) + result = I18n.t 'encoding', :who => "måmmå miå" + assert_equal Encoding::UTF_8, result.encoding + end + + test "interpolation: UTF8 strings in the backend are still returned as UTF8 with ASCII interpolation" do + I18n.backend.store_translations 'en', 'encoding' => 'måmmå miå %{what}' + result = I18n.t 'encoding', :what => 'let me go'.force_encoding("ASCII") + assert_equal Encoding::UTF_8, result.encoding + end + + test "interpolation: UTF8 strings in the backend are still returned as UTF8 even with numbers interpolation" do + I18n.backend.store_translations 'en', 'encoding' => '%{count} times: måmmå miå' + result = I18n.t 'encoding', :count => 3 + assert_equal Encoding::UTF_8, result.encoding + end + end + + test "interpolation: given a translations containing a reserved key it raises I18n::ReservedInterpolationKey" do + assert_raises(I18n::ReservedInterpolationKey) { interpolate(:foo => :bar, :default => '%{exception_handler}') } + assert_raises(I18n::ReservedInterpolationKey) { interpolate(:foo => :bar, :default => '%{default}') } + assert_raises(I18n::ReservedInterpolationKey) { interpolate(:foo => :bar, :default => '%{separator}') } + assert_raises(I18n::ReservedInterpolationKey) { interpolate(:foo => :bar, :default => '%{scope}') } + assert_raises(I18n::ReservedInterpolationKey) { interpolate(:default => '%{scope}') } + + I18n.backend.store_translations(:en, :interpolate => 'Hi %{scope}!') + assert_raises(I18n::ReservedInterpolationKey) { interpolate(:interpolate) } + end + + test "interpolation: it does not raise I18n::ReservedInterpolationKey for escaped variables" do + assert_nothing_raised do + assert_equal '%{separator}', interpolate(:foo => :bar, :default => '%%{separator}') + end + + # Note: The two interpolations below do not remove the escape character (%) because + # I18n should not alter the strings when no interpolation parameters are given, + # see the comment at the top of this file. + assert_nothing_raised do + assert_equal '%%{scope}', interpolate(:default => '%%{scope}') + end + + I18n.backend.store_translations(:en, :interpolate => 'Hi %%{scope}!') + assert_nothing_raised do + assert_equal 'Hi %%{scope}!', interpolate(:interpolate) + end + end + + test "interpolation: deep interpolation for default string" do + assert_equal 'Hi %{name}!', interpolate(:default => 'Hi %{name}!', :deep_interpolation => true) + end + + test "interpolation: deep interpolation for interpolated string" do + assert_equal 'Hi Ann!', interpolate(:default => 'Hi %{name}!', :name => 'Ann', :deep_interpolation => true) + end + + test "interpolation: deep interpolation for Hash" do + people = { :people => { :ann => 'Ann is %{ann}', :john => 'John is %{john}' } } + interpolated_people = { :people => { :ann => 'Ann is good', :john => 'John is big' } } + assert_equal interpolated_people, interpolate(:default => people, :ann => 'good', :john => 'big', :deep_interpolation => true) + end + + test "interpolation: deep interpolation for Array" do + people = { :people => ['Ann is %{ann}', 'John is %{john}'] } + interpolated_people = { :people => ['Ann is good', 'John is big'] } + assert_equal interpolated_people, interpolate(:default => people, :ann => 'good', :john => 'big', :deep_interpolation => true) + end + + protected + + def capture(stream) + begin + stream = stream.to_s + eval "$#{stream} = StringIO.new" + yield + result = eval("$#{stream}").string + ensure + eval("$#{stream} = #{stream.upcase}") + end + + result + end + + def euc_jp(string) + string.encode!(Encoding::EUC_JP) + end + + def interpolate(*args) + options = args.last.is_a?(Hash) ? args.pop : {} + key = args.pop + I18n.backend.translate('en', key, options) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/link.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/link.rb new file mode 100644 index 00000000..d2f20e80 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/link.rb @@ -0,0 +1,66 @@ +# encoding: utf-8 + +module I18n + module Tests + module Link + test "linked lookup: if a key resolves to a symbol it looks up the symbol" do + I18n.backend.store_translations 'en', { + :link => :linked, + :linked => 'linked' + } + assert_equal 'linked', I18n.backend.translate('en', :link) + end + + test "linked lookup: if a key resolves to a dot-separated symbol it looks up the symbol" do + I18n.backend.store_translations 'en', { + :link => :"foo.linked", + :foo => { :linked => 'linked' } + } + assert_equal('linked', I18n.backend.translate('en', :link)) + end + + test "linked lookup: if a dot-separated key resolves to a symbol it looks up the symbol" do + I18n.backend.store_translations 'en', { + :foo => { :link => :linked }, + :linked => 'linked' + } + assert_equal('linked', I18n.backend.translate('en', :'foo.link')) + end + + test "linked lookup: if a dot-separated key resolves to a dot-separated symbol it looks up the symbol" do + I18n.backend.store_translations 'en', { + :foo => { :link => :"bar.linked" }, + :bar => { :linked => 'linked' } + } + assert_equal('linked', I18n.backend.translate('en', :'foo.link')) + end + + test "linked lookup: links always refer to the absolute key" do + I18n.backend.store_translations 'en', { + :foo => { :link => :linked, :linked => 'linked in foo' }, + :linked => 'linked absolutely' + } + assert_equal 'linked absolutely', I18n.backend.translate('en', :link, :scope => :foo) + end + + test "linked lookup: a link can resolve to a namespace in the middle of a dot-separated key" do + I18n.backend.store_translations 'en', { + :activemodel => { :errors => { :messages => { :blank => "can't be blank" } } }, + :activerecord => { :errors => { :messages => :"activemodel.errors.messages" } } + } + assert_equal "can't be blank", I18n.t(:"activerecord.errors.messages.blank") + assert_equal "can't be blank", I18n.t(:"activerecord.errors.messages.blank") + end + + test "linked lookup: a link can resolve with option :count" do + I18n.backend.store_translations 'en', { + :counter => :counted, + :counted => { :foo => { :one => "one", :other => "other" }, :bar => "bar" } + } + assert_equal "one", I18n.t(:'counter.foo', count: 1) + assert_equal "other", I18n.t(:'counter.foo', count: 2) + assert_equal "bar", I18n.t(:'counter.bar', count: 3) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/localization.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/localization.rb new file mode 100644 index 00000000..53b15029 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/localization.rb @@ -0,0 +1,19 @@ +module I18n + module Tests + module Localization + autoload :Date, 'i18n/tests/localization/date' + autoload :DateTime, 'i18n/tests/localization/date_time' + autoload :Time, 'i18n/tests/localization/time' + autoload :Procs, 'i18n/tests/localization/procs' + + def self.included(base) + base.class_eval do + include I18n::Tests::Localization::Date + include I18n::Tests::Localization::DateTime + include I18n::Tests::Localization::Procs + include I18n::Tests::Localization::Time + end + end + end + end +end \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/localization/date.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/localization/date.rb new file mode 100644 index 00000000..c21fbbf3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/localization/date.rb @@ -0,0 +1,122 @@ +# encoding: utf-8 + +module I18n + module Tests + module Localization + module Date + def setup + super + setup_date_translations + @date = ::Date.new(2008, 3, 1) + end + + test "localize Date: given the short format it uses it" do + assert_equal '01. Mär', I18n.l(@date, :format => :short, :locale => :de) + end + + test "localize Date: given the long format it uses it" do + assert_equal '01. März 2008', I18n.l(@date, :format => :long, :locale => :de) + end + + test "localize Date: given the default format it uses it" do + assert_equal '01.03.2008', I18n.l(@date, :format => :default, :locale => :de) + end + + test "localize Date: given a day name format it returns the correct day name" do + assert_equal 'Samstag', I18n.l(@date, :format => '%A', :locale => :de) + end + + test "localize Date: given a uppercased day name format it returns the correct day name in upcase" do + assert_equal 'samstag'.upcase, I18n.l(@date, :format => '%^A', :locale => :de) + end + + test "localize Date: given an abbreviated day name format it returns the correct abbreviated day name" do + assert_equal 'Sa', I18n.l(@date, :format => '%a', :locale => :de) + end + + test "localize Date: given an meridian indicator format it returns the correct meridian indicator" do + assert_equal 'AM', I18n.l(@date, :format => '%p', :locale => :de) + assert_equal 'am', I18n.l(@date, :format => '%P', :locale => :de) + end + + test "localize Date: given an abbreviated and uppercased day name format it returns the correct abbreviated day name in upcase" do + assert_equal 'sa'.upcase, I18n.l(@date, :format => '%^a', :locale => :de) + end + + test "localize Date: given a month name format it returns the correct month name" do + assert_equal 'März', I18n.l(@date, :format => '%B', :locale => :de) + end + + test "localize Date: given a uppercased month name format it returns the correct month name in upcase" do + assert_equal 'märz'.upcase, I18n.l(@date, :format => '%^B', :locale => :de) + end + + test "localize Date: given an abbreviated month name format it returns the correct abbreviated month name" do + assert_equal 'Mär', I18n.l(@date, :format => '%b', :locale => :de) + end + + test "localize Date: given an abbreviated and uppercased month name format it returns the correct abbreviated month name in upcase" do + assert_equal 'mär'.upcase, I18n.l(@date, :format => '%^b', :locale => :de) + end + + test "localize Date: given a date format with the month name upcased it returns the correct value" do + assert_equal '1. FEBRUAR 2008', I18n.l(::Date.new(2008, 2, 1), :format => "%-d. %^B %Y", :locale => :de) + end + + test "localize Date: given missing translations it returns the correct error message" do + assert_equal 'Translation missing: fr.date.abbr_month_names', I18n.l(@date, :format => '%b', :locale => :fr) + end + + test "localize Date: given an unknown format it does not fail" do + assert_nothing_raised { I18n.l(@date, :format => '%x') } + end + + test "localize Date: does not modify the options hash" do + options = { :format => '%b', :locale => :de } + assert_equal 'Mär', I18n.l(@date, **options) + assert_equal({ :format => '%b', :locale => :de }, options) + assert_nothing_raised { I18n.l(@date, **options.freeze) } + end + + test "localize Date: given nil with default value it returns default" do + assert_equal 'default', I18n.l(nil, :default => 'default') + end + + test "localize Date: given nil it raises I18n::ArgumentError" do + assert_raises(I18n::ArgumentError) { I18n.l(nil) } + end + + test "localize Date: given a plain Object it raises I18n::ArgumentError" do + assert_raises(I18n::ArgumentError) { I18n.l(Object.new) } + end + + test "localize Date: given a format is missing it raises I18n::MissingTranslationData" do + assert_raises(I18n::MissingTranslationData) { I18n.l(@date, :format => :missing) } + end + + test "localize Date: it does not alter the format string" do + assert_equal '01. Februar 2009', I18n.l(::Date.parse('2009-02-01'), :format => :long, :locale => :de) + assert_equal '01. Oktober 2009', I18n.l(::Date.parse('2009-10-01'), :format => :long, :locale => :de) + end + + protected + + def setup_date_translations + I18n.backend.store_translations :de, { + :date => { + :formats => { + :default => "%d.%m.%Y", + :short => "%d. %b", + :long => "%d. %B %Y", + }, + :day_names => %w(Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag), + :abbr_day_names => %w(So Mo Di Mi Do Fr Sa), + :month_names => %w(Januar Februar März April Mai Juni Juli August September Oktober November Dezember).unshift(nil), + :abbr_month_names => %w(Jan Feb Mär Apr Mai Jun Jul Aug Sep Okt Nov Dez).unshift(nil) + } + } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/localization/date_time.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/localization/date_time.rb new file mode 100644 index 00000000..b5d3527d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/localization/date_time.rb @@ -0,0 +1,103 @@ +# encoding: utf-8 + +module I18n + module Tests + module Localization + module DateTime + def setup + super + setup_datetime_translations + @datetime = ::DateTime.new(2008, 3, 1, 6) + @other_datetime = ::DateTime.new(2008, 3, 1, 18) + end + + test "localize DateTime: given the short format it uses it" do + assert_equal '01. Mär 06:00', I18n.l(@datetime, :format => :short, :locale => :de) + end + + test "localize DateTime: given the long format it uses it" do + assert_equal '01. März 2008 06:00', I18n.l(@datetime, :format => :long, :locale => :de) + end + + test "localize DateTime: given the default format it uses it" do + assert_equal 'Sa, 01. Mär 2008 06:00:00 +0000', I18n.l(@datetime, :format => :default, :locale => :de) + end + + test "localize DateTime: given a day name format it returns the correct day name" do + assert_equal 'Samstag', I18n.l(@datetime, :format => '%A', :locale => :de) + end + + test "localize DateTime: given a uppercased day name format it returns the correct day name in upcase" do + assert_equal 'samstag'.upcase, I18n.l(@datetime, :format => '%^A', :locale => :de) + end + + test "localize DateTime: given an abbreviated day name format it returns the correct abbreviated day name" do + assert_equal 'Sa', I18n.l(@datetime, :format => '%a', :locale => :de) + end + + test "localize DateTime: given an abbreviated and uppercased day name format it returns the correct abbreviated day name in upcase" do + assert_equal 'sa'.upcase, I18n.l(@datetime, :format => '%^a', :locale => :de) + end + + test "localize DateTime: given a month name format it returns the correct month name" do + assert_equal 'März', I18n.l(@datetime, :format => '%B', :locale => :de) + end + + test "localize DateTime: given a uppercased month name format it returns the correct month name in upcase" do + assert_equal 'märz'.upcase, I18n.l(@datetime, :format => '%^B', :locale => :de) + end + + test "localize DateTime: given an abbreviated month name format it returns the correct abbreviated month name" do + assert_equal 'Mär', I18n.l(@datetime, :format => '%b', :locale => :de) + end + + test "localize DateTime: given an abbreviated and uppercased month name format it returns the correct abbreviated month name in upcase" do + assert_equal 'mär'.upcase, I18n.l(@datetime, :format => '%^b', :locale => :de) + end + + test "localize DateTime: given a date format with the month name upcased it returns the correct value" do + assert_equal '1. FEBRUAR 2008', I18n.l(::DateTime.new(2008, 2, 1, 6), :format => "%-d. %^B %Y", :locale => :de) + end + + test "localize DateTime: given missing translations it returns the correct error message" do + assert_equal 'Translation missing: fr.date.abbr_month_names', I18n.l(@datetime, :format => '%b', :locale => :fr) + end + + test "localize DateTime: given a meridian indicator format it returns the correct meridian indicator" do + assert_equal 'AM', I18n.l(@datetime, :format => '%p', :locale => :de) + assert_equal 'PM', I18n.l(@other_datetime, :format => '%p', :locale => :de) + end + + test "localize DateTime: given a meridian indicator format it returns the correct meridian indicator in downcase" do + assert_equal 'am', I18n.l(@datetime, :format => '%P', :locale => :de) + assert_equal 'pm', I18n.l(@other_datetime, :format => '%P', :locale => :de) + end + + test "localize DateTime: given an unknown format it does not fail" do + assert_nothing_raised { I18n.l(@datetime, :format => '%x') } + end + + test "localize DateTime: given a format is missing it raises I18n::MissingTranslationData" do + assert_raises(I18n::MissingTranslationData) { I18n.l(@datetime, :format => :missing) } + end + + protected + + def setup_datetime_translations + # time translations might have been set up in Tests::Api::Localization::Time + I18n.backend.store_translations :de, { + :time => { + :formats => { + :default => "%a, %d. %b %Y %H:%M:%S %z", + :short => "%d. %b %H:%M", + :long => "%d. %B %Y %H:%M" + }, + :am => 'am', + :pm => 'pm' + } + } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/localization/procs.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/localization/procs.rb new file mode 100644 index 00000000..2c5d8e15 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/localization/procs.rb @@ -0,0 +1,118 @@ +# encoding: utf-8 + +module I18n + module Tests + module Localization + module Procs + test "localize: using day names from lambdas" do + setup_time_proc_translations + time = ::Time.utc(2008, 3, 1, 6, 0) + assert_match(/Суббота/, I18n.l(time, :format => "%A, %d %B", :locale => :ru)) + assert_match(/суббота/, I18n.l(time, :format => "%d %B (%A)", :locale => :ru)) + end + + test "localize: using month names from lambdas" do + setup_time_proc_translations + time = ::Time.utc(2008, 3, 1, 6, 0) + assert_match(/марта/, I18n.l(time, :format => "%d %B %Y", :locale => :ru)) + assert_match(/Март /, I18n.l(time, :format => "%B %Y", :locale => :ru)) + end + + test "localize: using abbreviated day names from lambdas" do + setup_time_proc_translations + time = ::Time.utc(2008, 3, 1, 6, 0) + assert_match(/марта/, I18n.l(time, :format => "%d %b %Y", :locale => :ru)) + assert_match(/март /, I18n.l(time, :format => "%b %Y", :locale => :ru)) + end + + test "localize Date: given a format that resolves to a Proc it calls the Proc with the object" do + setup_time_proc_translations + date = ::Date.new(2008, 3, 1) + assert_equal '[Sat, 01 Mar 2008, {}]', I18n.l(date, :format => :proc, :locale => :ru) + end + + test "localize Date: given a format that resolves to a Proc it calls the Proc with the object and extra options" do + setup_time_proc_translations + date = ::Date.new(2008, 3, 1) + assert_equal %|[Sat, 01 Mar 2008, #{{:foo=>"foo"}}]|, I18n.l(date, :format => :proc, :foo => 'foo', :locale => :ru) + end + + test "localize DateTime: given a format that resolves to a Proc it calls the Proc with the object" do + setup_time_proc_translations + datetime = ::DateTime.new(2008, 3, 1, 6) + assert_equal '[Sat, 01 Mar 2008 06:00:00 +00:00, {}]', I18n.l(datetime, :format => :proc, :locale => :ru) + end + + test "localize DateTime: given a format that resolves to a Proc it calls the Proc with the object and extra options" do + setup_time_proc_translations + datetime = ::DateTime.new(2008, 3, 1, 6) + assert_equal %|[Sat, 01 Mar 2008 06:00:00 +00:00, #{{:foo=>"foo"}}]|, I18n.l(datetime, :format => :proc, :foo => 'foo', :locale => :ru) + end + + test "localize Time: given a format that resolves to a Proc it calls the Proc with the object" do + setup_time_proc_translations + time = ::Time.utc(2008, 3, 1, 6, 0) + assert_equal I18n::Tests::Localization::Procs.inspect_args([time], {}), I18n.l(time, :format => :proc, :locale => :ru) + end + + test "localize Time: given a format that resolves to a Proc it calls the Proc with the object and extra options" do + setup_time_proc_translations + time = ::Time.utc(2008, 3, 1, 6, 0) + options = { :foo => 'foo' } + assert_equal I18n::Tests::Localization::Procs.inspect_args([time], options), I18n.l(time, **options.merge(:format => :proc, :locale => :ru)) + end + + protected + + def self.inspect_args(args, kwargs) + args << kwargs + args = args.map do |arg| + case arg + when ::Time, ::DateTime + arg.strftime('%a, %d %b %Y %H:%M:%S %Z').sub('+0000', '+00:00') + when ::Date + arg.strftime('%a, %d %b %Y') + when Hash + arg.delete(:fallback_in_progress) + arg.delete(:fallback_original_locale) + arg.inspect + else + arg.inspect + end + end + "[#{args.join(', ')}]" + end + + def setup_time_proc_translations + I18n.backend.store_translations :ru, { + :time => { + :formats => { + :proc => lambda { |*args, **kwargs| I18n::Tests::Localization::Procs.inspect_args(args, kwargs) } + } + }, + :date => { + :formats => { + :proc => lambda { |*args, **kwargs| I18n::Tests::Localization::Procs.inspect_args(args, kwargs) } + }, + :'day_names' => lambda { |key, options| + (options[:format] =~ /^%A/) ? + %w(Воскресенье Понедельник Вторник Среда Четверг Пятница Суббота) : + %w(воскресенье понедельник вторник среда четверг пятница суббота) + }, + :'month_names' => lambda { |key, options| + (options[:format] =~ /(%d|%e)(\s*)?(%B)/) ? + %w(января февраля марта апреля мая июня июля августа сентября октября ноября декабря).unshift(nil) : + %w(Январь Февраль Март Апрель Май Июнь Июль Август Сентябрь Октябрь Ноябрь Декабрь).unshift(nil) + }, + :'abbr_month_names' => lambda { |key, options| + (options[:format] =~ /(%d|%e)(\s*)(%b)/) ? + %w(янв. февр. марта апр. мая июня июля авг. сент. окт. нояб. дек.).unshift(nil) : + %w(янв. февр. март апр. май июнь июль авг. сент. окт. нояб. дек.).unshift(nil) + }, + } + } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/localization/time.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/localization/time.rb new file mode 100644 index 00000000..456a7602 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/localization/time.rb @@ -0,0 +1,103 @@ +# encoding: utf-8 + +module I18n + module Tests + module Localization + module Time + def setup + super + setup_time_translations + @time = ::Time.utc(2008, 3, 1, 6, 0) + @other_time = ::Time.utc(2008, 3, 1, 18, 0) + end + + test "localize Time: given the short format it uses it" do + assert_equal '01. Mär 06:00', I18n.l(@time, :format => :short, :locale => :de) + end + + test "localize Time: given the long format it uses it" do + assert_equal '01. März 2008 06:00', I18n.l(@time, :format => :long, :locale => :de) + end + + # TODO Seems to break on Windows because ENV['TZ'] is ignored. What's a better way to do this? + # def test_localize_given_the_default_format_it_uses_it + # assert_equal 'Sa, 01. Mar 2008 06:00:00 +0000', I18n.l(@time, :format => :default, :locale => :de) + # end + + test "localize Time: given a day name format it returns the correct day name" do + assert_equal 'Samstag', I18n.l(@time, :format => '%A', :locale => :de) + end + + test "localize Time: given a uppercased day name format it returns the correct day name in upcase" do + assert_equal 'samstag'.upcase, I18n.l(@time, :format => '%^A', :locale => :de) + end + + test "localize Time: given an abbreviated day name format it returns the correct abbreviated day name" do + assert_equal 'Sa', I18n.l(@time, :format => '%a', :locale => :de) + end + + test "localize Time: given an abbreviated and uppercased day name format it returns the correct abbreviated day name in upcase" do + assert_equal 'sa'.upcase, I18n.l(@time, :format => '%^a', :locale => :de) + end + + test "localize Time: given a month name format it returns the correct month name" do + assert_equal 'März', I18n.l(@time, :format => '%B', :locale => :de) + end + + test "localize Time: given a uppercased month name format it returns the correct month name in upcase" do + assert_equal 'märz'.upcase, I18n.l(@time, :format => '%^B', :locale => :de) + end + + test "localize Time: given an abbreviated month name format it returns the correct abbreviated month name" do + assert_equal 'Mär', I18n.l(@time, :format => '%b', :locale => :de) + end + + test "localize Time: given an abbreviated and uppercased month name format it returns the correct abbreviated month name in upcase" do + assert_equal 'mär'.upcase, I18n.l(@time, :format => '%^b', :locale => :de) + end + + test "localize Time: given a date format with the month name upcased it returns the correct value" do + assert_equal '1. FEBRUAR 2008', I18n.l(::Time.utc(2008, 2, 1, 6, 0), :format => "%-d. %^B %Y", :locale => :de) + end + + test "localize Time: given missing translations it returns the correct error message" do + assert_equal 'Translation missing: fr.date.abbr_month_names', I18n.l(@time, :format => '%b', :locale => :fr) + end + + test "localize Time: given a meridian indicator format it returns the correct meridian indicator" do + assert_equal 'AM', I18n.l(@time, :format => '%p', :locale => :de) + assert_equal 'PM', I18n.l(@other_time, :format => '%p', :locale => :de) + end + + test "localize Time: given a meridian indicator format it returns the correct meridian indicator in upcase" do + assert_equal 'am', I18n.l(@time, :format => '%P', :locale => :de) + assert_equal 'pm', I18n.l(@other_time, :format => '%P', :locale => :de) + end + + test "localize Time: given an unknown format it does not fail" do + assert_nothing_raised { I18n.l(@time, :format => '%x') } + end + + test "localize Time: given a format is missing it raises I18n::MissingTranslationData" do + assert_raises(I18n::MissingTranslationData) { I18n.l(@time, :format => :missing) } + end + + protected + + def setup_time_translations + I18n.backend.store_translations :de, { + :time => { + :formats => { + :default => "%a, %d. %b %Y %H:%M:%S %z", + :short => "%d. %b %H:%M", + :long => "%d. %B %Y %H:%M", + }, + :am => 'am', + :pm => 'pm' + } + } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/lookup.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/lookup.rb new file mode 100644 index 00000000..f1bee792 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/lookup.rb @@ -0,0 +1,87 @@ +# encoding: utf-8 + +module I18n + module Tests + module Lookup + def setup + super + I18n.backend.store_translations(:en, :foo => { :bar => 'bar', :baz => 'baz' }, :falsy => false, :truthy => true, + :string => "a", :array => %w(a b c), :hash => { "a" => "b" }) + end + + test "lookup: it returns a string" do + assert_equal("a", I18n.t(:string)) + end + + test "lookup: it returns hash" do + assert_equal({ :a => "b" }, I18n.t(:hash)) + end + + test "lookup: it returns an array" do + assert_equal(%w(a b c), I18n.t(:array)) + end + + test "lookup: it returns a native true" do + assert I18n.t(:truthy) === true + end + + test "lookup: it returns a native false" do + assert I18n.t(:falsy) === false + end + + test "lookup: given a missing key, no default and no raise option it returns an error message" do + assert_equal "Translation missing: en.missing", I18n.t(:missing) + end + + test "lookup: given a missing key, no default and the raise option it raises MissingTranslationData" do + assert_raises(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) } + end + + test "lookup: does not raise an exception if no translation data is present for the given locale" do + assert_nothing_raised { I18n.t(:foo, :locale => :xx) } + end + + test "lookup: does not modify the options hash" do + options = {} + assert_equal "a", I18n.t(:string, **options) + assert_equal({}, options) + assert_nothing_raised { I18n.t(:string, **options.freeze) } + end + + test "lookup: given an array of keys it translates all of them" do + assert_equal %w(bar baz), I18n.t([:bar, :baz], :scope => [:foo]) + end + + test "lookup: using a custom scope separator" do + # data must have been stored using the custom separator when using the ActiveRecord backend + I18n.backend.store_translations(:en, { :foo => { :bar => 'bar' } }, { :separator => '|' }) + assert_equal 'bar', I18n.t('foo|bar', :separator => '|') + end + + # In fact it probably *should* fail but Rails currently relies on using the default locale instead. + # So we'll stick to this for now until we get it fixed in Rails. + test "lookup: given nil as a locale it does not raise but use the default locale" do + # assert_raises(I18n::InvalidLocale) { I18n.t(:bar, :locale => nil) } + assert_nothing_raised { I18n.t(:bar, :locale => nil) } + end + + test "lookup: a resulting String is not frozen" do + assert !I18n.t(:string).frozen? + end + + test "lookup: a resulting Array is not frozen" do + assert !I18n.t(:array).frozen? + end + + test "lookup: a resulting Hash is not frozen" do + assert !I18n.t(:hash).frozen? + end + + # Addresses issue: #599 + test "lookup: only interpolates once when resolving symbols" do + I18n.backend.store_translations(:en, foo: :bar, bar: '%{value}') + assert_equal '%{dont_interpolate_me}', I18n.t(:foo, value: '%{dont_interpolate_me}') + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/pluralization.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/pluralization.rb new file mode 100644 index 00000000..19e73f37 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/pluralization.rb @@ -0,0 +1,35 @@ +# encoding: utf-8 + +module I18n + module Tests + module Pluralization + test "pluralization: given 0 it returns the :zero translation if it is defined" do + assert_equal 'zero', I18n.t(:default => { :zero => 'zero' }, :count => 0) + end + + test "pluralization: given 0 it returns the :other translation if :zero is not defined" do + assert_equal 'bars', I18n.t(:default => { :other => 'bars' }, :count => 0) + end + + test "pluralization: given 1 it returns the singular translation" do + assert_equal 'bar', I18n.t(:default => { :one => 'bar' }, :count => 1) + end + + test "pluralization: given 2 it returns the :other translation" do + assert_equal 'bars', I18n.t(:default => { :other => 'bars' }, :count => 2) + end + + test "pluralization: given 3 it returns the :other translation" do + assert_equal 'bars', I18n.t(:default => { :other => 'bars' }, :count => 3) + end + + test "pluralization: given nil it returns the whole entry" do + assert_equal({ :one => 'bar' }, I18n.t(:default => { :one => 'bar' }, :count => nil)) + end + + test "pluralization: given incomplete pluralization data it raises I18n::InvalidPluralizationData" do + assert_raises(I18n::InvalidPluralizationData) { I18n.t(:default => { :one => 'bar' }, :count => 2) } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/procs.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/procs.rb new file mode 100644 index 00000000..d377117d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/tests/procs.rb @@ -0,0 +1,71 @@ +# encoding: utf-8 + +module I18n + module Tests + module Procs + test "lookup: given a translation is a proc it calls the proc with the key and interpolation values" do + I18n.backend.store_translations(:en, :a_lambda => lambda { |*args| I18n::Tests::Procs.filter_args(*args) }) + assert_equal %|[:a_lambda, #{{:foo=>"foo"}}]|, I18n.t(:a_lambda, :foo => 'foo') + end + + test "lookup: given a translation is a proc it passes the interpolation values as keyword arguments" do + I18n.backend.store_translations(:en, :a_lambda => lambda { |key, foo:, **| I18n::Tests::Procs.filter_args(key, foo: foo) }) + assert_equal %|[:a_lambda, #{{:foo=>"foo"}}]|, I18n.t(:a_lambda, :foo => 'foo') + end + + test "defaults: given a default is a Proc it calls it with the key and interpolation values" do + proc = lambda { |*args| I18n::Tests::Procs.filter_args(*args) } + assert_equal %|[nil, #{{:foo=>"foo"}}]|, I18n.t(nil, :default => proc, :foo => 'foo') + end + + test "defaults: given a default is a key that resolves to a Proc it calls it with the key and interpolation values" do + the_lambda = lambda { |*args| I18n::Tests::Procs.filter_args(*args) } + I18n.backend.store_translations(:en, :a_lambda => the_lambda) + assert_equal %|[:a_lambda, #{{:foo=>"foo"}}]|, I18n.t(nil, :default => :a_lambda, :foo => 'foo') + assert_equal %|[:a_lambda, #{{:foo=>"foo"}}]|, I18n.t(nil, :default => [nil, :a_lambda], :foo => 'foo') + end + + test "interpolation: given an interpolation value is a lambda it calls it with key and values before interpolating it" do + proc = lambda { |*args| I18n::Tests::Procs.filter_args(*args) } + if RUBY_VERSION < "3.4" + assert_match %r(\[\{:foo=>#\}\]), I18n.t(nil, :default => '%{foo}', :foo => proc) + else + assert_match %r(\[\{foo: #\}\]), I18n.t(nil, :default => '%{foo}', :foo => proc) + end + end + + test "interpolation: given a key resolves to a Proc that returns a string then interpolation still works" do + proc = lambda { |*args| "%{foo}: " + I18n::Tests::Procs.filter_args(*args) } + assert_equal %|foo: [nil, #{{:foo=>"foo"}}]|, I18n.t(nil, :default => proc, :foo => 'foo') + end + + test "pluralization: given a key resolves to a Proc that returns valid data then pluralization still works" do + proc = lambda { |*args| { :zero => 'zero', :one => 'one', :other => 'other' } } + assert_equal 'zero', I18n.t(:default => proc, :count => 0) + assert_equal 'one', I18n.t(:default => proc, :count => 1) + assert_equal 'other', I18n.t(:default => proc, :count => 2) + end + + test "lookup: given the option :resolve => false was passed it does not resolve proc translations" do + I18n.backend.store_translations(:en, :a_lambda => lambda { |*args| I18n::Tests::Procs.filter_args(*args) }) + assert_equal Proc, I18n.t(:a_lambda, :resolve => false).class + end + + test "lookup: given the option :resolve => false was passed it does not resolve proc default" do + assert_equal Proc, I18n.t(nil, :default => lambda { |*args| I18n::Tests::Procs.filter_args(*args) }, :resolve => false).class + end + + + def self.filter_args(*args) + args.map do |arg| + if arg.is_a?(Hash) + arg.delete(:fallback_in_progress) + arg.delete(:fallback_original_locale) + arg.delete(:skip_interpolation) + end + arg + end.inspect + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/utils.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/utils.rb new file mode 100644 index 00000000..88415615 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/utils.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +module I18n + module Utils + class << self + if Hash.method_defined?(:except) + def except(hash, *keys) + hash.except(*keys) + end + else + def except(hash, *keys) + hash = hash.dup + keys.each { |k| hash.delete(k) } + hash + end + end + + def deep_merge(hash, other_hash, &block) + deep_merge!(hash.dup, other_hash, &block) + end + + def deep_merge!(hash, other_hash, &block) + hash.merge!(other_hash) do |key, this_val, other_val| + if this_val.is_a?(Hash) && other_val.is_a?(Hash) + deep_merge(this_val, other_val, &block) + elsif block_given? + yield key, this_val, other_val + else + other_val + end + end + end + + def deep_symbolize_keys(hash) + hash.each_with_object({}) do |(key, value), result| + result[key.respond_to?(:to_sym) ? key.to_sym : key] = deep_symbolize_keys_in_object(value) + result + end + end + + private + + def deep_symbolize_keys_in_object(value) + case value + when Hash + deep_symbolize_keys(value) + when Array + value.map { |e| deep_symbolize_keys_in_object(e) } + else + value + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/version.rb b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/version.rb new file mode 100644 index 00000000..bdeb7172 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/i18n-1.14.7/lib/i18n/version.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +module I18n + VERSION = "1.14.7" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/.document b/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/.document new file mode 100644 index 00000000..e7488550 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/.document @@ -0,0 +1,5 @@ +LICENSE.txt +README.md +docs/ +ext/ +lib/io/console/size.rb diff --git a/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/BSDL b/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/BSDL new file mode 100644 index 00000000..66d93598 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/BSDL @@ -0,0 +1,22 @@ +Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/COPYING b/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/COPYING new file mode 100644 index 00000000..48e5a96d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/COPYING @@ -0,0 +1,56 @@ +Ruby is copyrighted free software by Yukihiro Matsumoto . +You can redistribute it and/or modify it under either the terms of the +2-clause BSDL (see the file BSDL), or the conditions below: + +1. You may make and give away verbatim copies of the source form of the + software without restriction, provided that you duplicate all of the + original copyright notices and associated disclaimers. + +2. You may modify your copy of the software in any way, provided that + you do at least ONE of the following: + + a. place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said + modifications to Usenet or an equivalent medium, or by allowing + the author to include your modifications in the software. + + b. use the modified software only within your corporation or + organization. + + c. give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d. make other distribution arrangements with the author. + +3. You may distribute the software in object code or binary form, + provided that you do at least ONE of the following: + + a. distribute the binaries and library files of the software, + together with instructions (in the manual page or equivalent) + on where to get the original distribution. + + b. accompany the distribution with the machine-readable source of + the software. + + c. give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d. make other distribution arrangements with the author. + +4. You may modify and include the part of the software into any other + software (possibly commercial). But some files in the distribution + are not written by the author, so that they are not under these terms. + + For the list of those files and their copying conditions, see the + file LEGAL. + +5. The scripts and library files supplied as input to or produced as + output from the software do not automatically fall under the + copyright of the software, but belong to whomever generated them, + and may be sold commercially, and may be aggregated with this + software. + +6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. diff --git a/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/README.md b/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/README.md new file mode 100644 index 00000000..83262a3d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/README.md @@ -0,0 +1,46 @@ +# IO.console + +Add console capabilities to IO instances. + +## Installation + +Add this line to your application's Gemfile: + +```ruby +gem 'io-console' +``` + +And then execute: + + $ bundle + +Or install it yourself as: + + $ gem install io-console + +## Usage + +```ruby +require 'io/console' + +IO.console -> # +IO.console(sym, *args) +``` + +Returns a File instance opened console. + +If `sym` is given, it will be sent to the opened console with `args` and the result will be returned instead of the console IO itself. + +## Development + +After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. + +To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). + +## Contributing + +Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/io-console. + +## License + +The gem is available as open source under the terms of the [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause). diff --git a/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/ext/io/console/Makefile b/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/ext/io/console/Makefile new file mode 100644 index 00000000..f3fd4fcf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/ext/io/console/Makefile @@ -0,0 +1,275 @@ + +SHELL = /bin/sh + +# V=0 quiet, V=1 verbose. other values don't work. +V = 0 +V0 = $(V:0=) +Q1 = $(V:1=) +Q = $(Q1:0=@) +ECHO1 = $(V:1=@ :) +ECHO = $(ECHO1:0=@ echo) +NULLCMD = : + +#### Start of system configuration section. #### + +srcdir = . +topdir = /opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 +hdrdir = $(topdir) +arch_hdrdir = /opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux +PATH_SEPARATOR = : +VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby +prefix = $(DESTDIR)/opt/hostedtoolcache/Ruby/3.4.4/x64 +rubysitearchprefix = $(rubylibprefix)/$(sitearch) +rubyarchprefix = $(rubylibprefix)/$(arch) +rubylibprefix = $(libdir)/$(RUBY_BASE_NAME) +exec_prefix = $(prefix) +vendorarchhdrdir = $(vendorhdrdir)/$(sitearch) +sitearchhdrdir = $(sitehdrdir)/$(sitearch) +rubyarchhdrdir = $(rubyhdrdir)/$(arch) +vendorhdrdir = $(rubyhdrdir)/vendor_ruby +sitehdrdir = $(rubyhdrdir)/site_ruby +rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME) +vendorarchdir = $(vendorlibdir)/$(sitearch) +vendorlibdir = $(vendordir)/$(ruby_version) +vendordir = $(rubylibprefix)/vendor_ruby +sitearchdir = $(sitelibdir)/$(sitearch) +sitelibdir = $(sitedir)/$(ruby_version) +sitedir = $(rubylibprefix)/site_ruby +rubyarchdir = $(rubylibdir)/$(arch) +rubylibdir = $(rubylibprefix)/$(ruby_version) +sitearchincludedir = $(includedir)/$(sitearch) +archincludedir = $(includedir)/$(arch) +sitearchlibdir = $(libdir)/$(sitearch) +archlibdir = $(libdir)/$(arch) +ridir = $(datarootdir)/$(RI_BASE_NAME) +modular_gc_dir = $(DESTDIR) +mandir = $(datarootdir)/man +localedir = $(datarootdir)/locale +libdir = $(exec_prefix)/lib +psdir = $(docdir) +pdfdir = $(docdir) +dvidir = $(docdir) +htmldir = $(docdir) +infodir = $(datarootdir)/info +docdir = $(datarootdir)/doc/$(PACKAGE) +oldincludedir = $(DESTDIR)/usr/include +includedir = $(prefix)/include +runstatedir = $(localstatedir)/run +localstatedir = $(prefix)/var +sharedstatedir = $(prefix)/com +sysconfdir = $(prefix)/etc +datadir = $(datarootdir) +datarootdir = $(prefix)/share +libexecdir = $(exec_prefix)/libexec +sbindir = $(exec_prefix)/sbin +bindir = $(exec_prefix)/bin +archdir = $(rubyarchdir) + + +CC_WRAPPER = +CC = gcc +CXX = g++ +LIBRUBY = $(LIBRUBY_SO) +LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a +LIBRUBYARG_SHARED = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME) +LIBRUBYARG_STATIC = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)-static $(MAINLIBS) +empty = +OUTFLAG = -o $(empty) +COUTFLAG = -o $(empty) +CSRCFLAG = $(empty) + +RUBY_EXTCONF_H = +cflags = $(hardenflags) $(optflags) $(debugflags) $(warnflags) +cxxflags = +optflags = -O3 -fno-fast-math +debugflags = -ggdb3 +warnflags = -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef +cppflags = +CCDLFLAGS = -fPIC +CFLAGS = $(CCDLFLAGS) $(cflags) -fPIC $(ARCH_FLAG) +INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) +DEFS = +CPPFLAGS = -DHAVE_RB_SYSERR_FAIL_STR -DHAVE_RB_INTERNED_STR_CSTR -DHAVE_RB_IO_PATH -DHAVE_RB_IO_DESCRIPTOR -DHAVE_RB_IO_GET_WRITE_IO -DHAVE_RB_IO_CLOSED_P -DHAVE_RB_IO_OPEN_DESCRIPTOR -DHAVE_RB_RACTOR_LOCAL_STORAGE_VALUE_NEWKEY -DHAVE_TERMIOS_H -DHAVE_CFMAKERAW -DHAVE_SYS_IOCTL_H -DHAVE_RB_IO_WAIT=1 -DHAVE_TTYNAME_R -DENABLE_PATH_CHECK=0 $(DEFS) $(cppflags) +CXXFLAGS = $(CCDLFLAGS) $(ARCH_FLAG) +ldflags = -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed +dldflags = -Wl,--compress-debug-sections=zlib +ARCH_FLAG = +DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG) +LDSHARED = $(CC) -shared +LDSHAREDXX = $(CXX) -shared +POSTLINK = : +AR = gcc-ar +LD = ld +EXEEXT = + +RUBY_INSTALL_NAME = $(RUBY_BASE_NAME) +RUBY_SO_NAME = ruby +RUBYW_INSTALL_NAME = +RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version) +RUBYW_BASE_NAME = rubyw +RUBY_BASE_NAME = ruby + +arch = x86_64-linux +sitearch = $(arch) +ruby_version = 3.4.0 +ruby = $(bindir)/$(RUBY_BASE_NAME) +RUBY = $(ruby) +BUILTRUBY = $(bindir)/$(RUBY_BASE_NAME) +ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/backward.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h + +RM = rm -f +RM_RF = rm -fr +RMDIRS = rmdir --ignore-fail-on-non-empty -p +MAKEDIRS = /usr/bin/mkdir -p +INSTALL = /usr/bin/install -c +INSTALL_PROG = $(INSTALL) -m 0755 +INSTALL_DATA = $(INSTALL) -m 644 +COPY = cp +TOUCH = exit > + +#### End of system configuration section. #### + +preload = +libpath = . $(libdir) +LIBPATH = -L. -L$(libdir) -Wl,-rpath,$(libdir) +DEFFILE = + +CLEANFILES = mkmf.log +DISTCLEANFILES = +DISTCLEANDIRS = + +extout = +extout_prefix = +target_prefix = /io +LOCAL_LIBS = +LIBS = $(LIBRUBYARG_SHARED) -lm -lpthread -lc +ORIG_SRCS = console.c +SRCS = $(ORIG_SRCS) +OBJS = console.o +HDRS = +LOCAL_HDRS = +TARGET = console +TARGET_NAME = console +TARGET_ENTRY = Init_$(TARGET_NAME) +DLLIB = $(TARGET).so +EXTSTATIC = +STATIC_LIB = + +TIMESTAMP_DIR = . +BINDIR = $(bindir) +RUBYCOMMONDIR = $(sitedir)$(target_prefix) +RUBYLIBDIR = $(sitelibdir)$(target_prefix) +RUBYARCHDIR = $(sitearchdir)$(target_prefix) +HDRDIR = $(sitehdrdir)$(target_prefix) +ARCHHDRDIR = $(sitearchhdrdir)$(target_prefix) +TARGET_SO_DIR = +TARGET_SO = $(TARGET_SO_DIR)$(DLLIB) +CLEANLIBS = $(TARGET_SO) false +CLEANOBJS = $(OBJS) *.bak +TARGET_SO_DIR_TIMESTAMP = $(TIMESTAMP_DIR)/.sitearchdir.-.io.time + +VK_HEADER = + +all: $(DLLIB) +static: $(STATIC_LIB) +.PHONY: all install static install-so install-rb +.PHONY: clean clean-so clean-static clean-rb + +clean-static:: +clean-rb-default:: +clean-rb:: +clean-so:: +clean: clean-so clean-static clean-rb-default clean-rb + -$(Q)$(RM_RF) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time + +distclean-rb-default:: +distclean-rb:: +distclean-so:: +distclean-static:: +distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb + -$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + -$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + -$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true + +realclean: distclean +install: install-so install-rb + +install-so: $(DLLIB) $(TARGET_SO_DIR_TIMESTAMP) + $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) +clean-static:: + -$(Q)$(RM) $(STATIC_LIB) +install-rb: pre-install-rb do-install-rb install-rb-default +install-rb-default: pre-install-rb-default do-install-rb-default +pre-install-rb: Makefile +pre-install-rb-default: Makefile +do-install-rb: +do-install-rb-default: +pre-install-rb-default: + @$(NULLCMD) +$(TARGET_SO_DIR_TIMESTAMP): + $(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR) + $(Q) $(TOUCH) $@ + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + +.SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S + +.cc.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cc.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.mm.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.mm.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cxx.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cxx.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cpp.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cpp.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.c.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.c.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.m.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.m.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +$(TARGET_SO): $(OBJS) Makefile + $(ECHO) linking shared-object io/$(DLLIB) + -$(Q)$(RM) $(@) + $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) + $(Q) $(POSTLINK) + + + +$(OBJS): $(HDRS) $(ruby_headers) diff --git a/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/ext/io/console/console.c b/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/ext/io/console/console.c new file mode 100644 index 00000000..80c1cddd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/ext/io/console/console.c @@ -0,0 +1,1969 @@ +/* -*- c-file-style: "ruby"; indent-tabs-mode: t -*- */ +/* + * console IO module + */ + +static const char *const +IO_CONSOLE_VERSION = "0.8.0"; + +#include "ruby.h" +#include "ruby/io.h" +#include "ruby/thread.h" + +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_FCNTL_H +#include +#endif +#ifdef HAVE_SYS_IOCTL_H +#include +#endif + +#if defined HAVE_TERMIOS_H +# include +typedef struct termios conmode; + +static int +setattr(int fd, conmode *t) +{ + while (tcsetattr(fd, TCSANOW, t)) { + if (errno != EINTR) return 0; + } + return 1; +} +# define getattr(fd, t) (tcgetattr(fd, t) == 0) +#elif defined HAVE_TERMIO_H +# include +typedef struct termio conmode; +# define setattr(fd, t) (ioctl(fd, TCSETAF, t) == 0) +# define getattr(fd, t) (ioctl(fd, TCGETA, t) == 0) +#elif defined HAVE_SGTTY_H +# include +typedef struct sgttyb conmode; +# ifdef HAVE_STTY +# define setattr(fd, t) (stty(fd, t) == 0) +# else +# define setattr(fd, t) (ioctl((fd), TIOCSETP, (t)) == 0) +# endif +# ifdef HAVE_GTTY +# define getattr(fd, t) (gtty(fd, t) == 0) +# else +# define getattr(fd, t) (ioctl((fd), TIOCGETP, (t)) == 0) +# endif +#elif defined _WIN32 +#include +#include +typedef DWORD conmode; + +#define LAST_ERROR rb_w32_map_errno(GetLastError()) +#define SET_LAST_ERROR (errno = LAST_ERROR, 0) + +static int +setattr(int fd, conmode *t) +{ + int x = SetConsoleMode((HANDLE)rb_w32_get_osfhandle(fd), *t); + if (!x) errno = LAST_ERROR; + return x; +} + +static int +getattr(int fd, conmode *t) +{ + int x = GetConsoleMode((HANDLE)rb_w32_get_osfhandle(fd), t); + if (!x) errno = LAST_ERROR; + return x; +} +#endif +#ifndef SET_LAST_ERROR +#define SET_LAST_ERROR (0) +#endif + +#define CSI "\x1b\x5b" + +static ID id_getc, id_close; +static ID id_gets, id_flush, id_chomp_bang; + +#ifndef HAVE_RB_INTERNED_STR_CSTR +# define rb_str_to_interned_str(str) rb_str_freeze(str) +# define rb_interned_str_cstr(str) rb_str_freeze(rb_usascii_str_new_cstr(str)) +#endif + +#if defined HAVE_RUBY_FIBER_SCHEDULER_H +# include "ruby/fiber/scheduler.h" +#elif defined HAVE_RB_SCHEDULER_TIMEOUT +extern VALUE rb_scheduler_timeout(struct timeval *timeout); +# define rb_fiber_scheduler_make_timeout rb_scheduler_timeout +#endif + +#ifndef HAVE_RB_IO_DESCRIPTOR +static int +io_descriptor_fallback(VALUE io) +{ + rb_io_t *fptr; + GetOpenFile(io, fptr); + return fptr->fd; +} +#define rb_io_descriptor io_descriptor_fallback +#endif + +#ifndef HAVE_RB_IO_PATH +static VALUE +io_path_fallback(VALUE io) +{ + rb_io_t *fptr; + GetOpenFile(io, fptr); + return fptr->pathv; +} +#define rb_io_path io_path_fallback +#endif + +#ifndef HAVE_RB_IO_GET_WRITE_IO +static VALUE +io_get_write_io_fallback(VALUE io) +{ + rb_io_t *fptr; + GetOpenFile(io, fptr); + VALUE wio = fptr->tied_io_for_writing; + return wio ? wio : io; +} +#define rb_io_get_write_io io_get_write_io_fallback +#endif + +#ifndef DHAVE_RB_SYSERR_FAIL_STR +# define rb_syserr_fail_str(e, mesg) rb_exc_raise(rb_syserr_new_str(e, mesg)) +#endif + +#define sys_fail(io) do { \ + int err = errno; \ + rb_syserr_fail_str(err, rb_io_path(io)); \ +} while (0) + +#ifndef HAVE_RB_F_SEND +#ifndef RB_PASS_CALLED_KEYWORDS +# define rb_funcallv_kw(recv, mid, arg, argv, kw_splat) rb_funcallv(recv, mid, arg, argv) +#endif + +static ID id___send__; + +static VALUE +rb_f_send(int argc, VALUE *argv, VALUE recv) +{ + VALUE sym = argv[0]; + ID vid = rb_check_id(&sym); + if (vid) { + --argc; + ++argv; + } + else { + vid = id___send__; + } + return rb_funcallv_kw(recv, vid, argc, argv, RB_PASS_CALLED_KEYWORDS); +} +#endif + +enum rawmode_opt_ids { + kwd_min, + kwd_time, + kwd_intr, + rawmode_opt_id_count +}; +static ID rawmode_opt_ids[rawmode_opt_id_count]; + +typedef struct { + int vmin; + int vtime; + int intr; +} rawmode_arg_t; + +#ifndef UNDEF_P +# define UNDEF_P(obj) ((obj) == Qundef) +#endif +#ifndef NIL_OR_UNDEF_P +# define NIL_OR_UNDEF_P(obj) (NIL_P(obj) || UNDEF_P(obj)) +#endif + +static rawmode_arg_t * +rawmode_opt(int *argcp, VALUE *argv, int min_argc, int max_argc, rawmode_arg_t *opts) +{ + int argc = *argcp; + rawmode_arg_t *optp = NULL; + VALUE vopts = Qnil; + VALUE optvals[rawmode_opt_id_count]; +#ifdef RB_SCAN_ARGS_PASS_CALLED_KEYWORDS + argc = rb_scan_args(argc, argv, "*:", NULL, &vopts); +#else + if (argc > min_argc) { + vopts = rb_check_hash_type(argv[argc-1]); + if (!NIL_P(vopts)) { + argv[argc-1] = vopts; + vopts = rb_extract_keywords(&argv[argc-1]); + if (!argv[argc-1]) *argcp = --argc; + if (!vopts) vopts = Qnil; + } + } +#endif + rb_check_arity(argc, min_argc, max_argc); + if (rb_get_kwargs(vopts, rawmode_opt_ids, + 0, rawmode_opt_id_count, optvals)) { + VALUE vmin = optvals[kwd_min]; + VALUE vtime = optvals[kwd_time]; + VALUE intr = optvals[kwd_intr]; + /* default values by `stty raw` */ + opts->vmin = 1; + opts->vtime = 0; + opts->intr = 0; + if (!NIL_OR_UNDEF_P(vmin)) { + opts->vmin = NUM2INT(vmin); + optp = opts; + } + if (!NIL_OR_UNDEF_P(vtime)) { + VALUE v10 = INT2FIX(10); + vtime = rb_funcall3(vtime, '*', 1, &v10); + opts->vtime = NUM2INT(vtime); + optp = opts; + } + switch (intr) { + case Qtrue: + opts->intr = 1; + optp = opts; + break; + case Qfalse: + opts->intr = 0; + optp = opts; + break; + case Qundef: + case Qnil: + break; + default: + rb_raise(rb_eArgError, "true or false expected as intr: %"PRIsVALUE, + intr); + } + } + return optp; +} + +static void +set_rawmode(conmode *t, void *arg) +{ +#ifdef HAVE_CFMAKERAW + cfmakeraw(t); + t->c_lflag &= ~(ECHOE|ECHOK); +#elif defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H + t->c_iflag &= ~(IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IXOFF|IXANY|IMAXBEL); + t->c_oflag &= ~OPOST; + t->c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ICANON|ISIG|IEXTEN|XCASE); + t->c_cflag &= ~(CSIZE|PARENB); + t->c_cflag |= CS8; + t->c_cc[VMIN] = 1; + t->c_cc[VTIME] = 0; +#elif defined HAVE_SGTTY_H + t->sg_flags &= ~ECHO; + t->sg_flags |= RAW; +#elif defined _WIN32 + *t = 0; +#endif + if (arg) { + const rawmode_arg_t *r = arg; +#ifdef VMIN + if (r->vmin >= 0) t->c_cc[VMIN] = r->vmin; +#endif +#ifdef VTIME + if (r->vtime >= 0) t->c_cc[VTIME] = r->vtime; +#endif +#ifdef ISIG + if (r->intr) { + t->c_iflag |= BRKINT; + t->c_lflag |= ISIG; + t->c_oflag |= OPOST; + } +#endif + (void)r; + } +} + +static void +set_cookedmode(conmode *t, void *arg) +{ +#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H + t->c_iflag |= (BRKINT|ISTRIP|ICRNL|IXON); + t->c_oflag |= OPOST; + t->c_lflag |= (ECHO|ECHOE|ECHOK|ECHONL|ICANON|ISIG|IEXTEN); +#elif defined HAVE_SGTTY_H + t->sg_flags |= ECHO; + t->sg_flags &= ~RAW; +#elif defined _WIN32 + *t |= ENABLE_ECHO_INPUT|ENABLE_LINE_INPUT|ENABLE_PROCESSED_INPUT; +#endif +} + +static void +set_noecho(conmode *t, void *arg) +{ +#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H + t->c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); +#elif defined HAVE_SGTTY_H + t->sg_flags &= ~ECHO; +#elif defined _WIN32 + *t &= ~ENABLE_ECHO_INPUT; +#endif +} + +static void +set_echo(conmode *t, void *arg) +{ +#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H + t->c_lflag |= (ECHO | ECHOE | ECHOK | ECHONL); +#elif defined HAVE_SGTTY_H + t->sg_flags |= ECHO; +#elif defined _WIN32 + *t |= ENABLE_ECHO_INPUT; +#endif +} + +static int +echo_p(conmode *t) +{ +#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H + return (t->c_lflag & (ECHO | ECHONL)) != 0; +#elif defined HAVE_SGTTY_H + return (t->sg_flags & ECHO) != 0; +#elif defined _WIN32 + return (*t & ENABLE_ECHO_INPUT) != 0; +#endif +} + +static int +set_ttymode(int fd, conmode *t, void (*setter)(conmode *, void *), void *arg) +{ + conmode r; + if (!getattr(fd, t)) return 0; + r = *t; + setter(&r, arg); + return setattr(fd, &r); +} + +#define GetReadFD(io) rb_io_descriptor(io) +#define GetWriteFD(io) rb_io_descriptor(rb_io_get_write_io(io)) + +#define FD_PER_IO 2 + +static VALUE +ttymode(VALUE io, VALUE (*func)(VALUE), VALUE farg, void (*setter)(conmode *, void *), void *arg) +{ + int status = -1; + int error = 0; + int fd[FD_PER_IO]; + conmode t[FD_PER_IO]; + VALUE result = Qnil; + + fd[0] = GetReadFD(io); + if (fd[0] != -1) { + if (set_ttymode(fd[0], t+0, setter, arg)) { + status = 0; + } + else { + error = errno; + fd[0] = -1; + } + } + fd[1] = GetWriteFD(io); + if (fd[1] != -1 && fd[1] != fd[0]) { + if (set_ttymode(fd[1], t+1, setter, arg)) { + status = 0; + } + else { + error = errno; + fd[1] = -1; + } + } + if (status == 0) { + result = rb_protect(func, farg, &status); + } + if (fd[0] != -1 && fd[0] == GetReadFD(io)) { + if (!setattr(fd[0], t+0)) { + error = errno; + status = -1; + } + } + if (fd[1] != -1 && fd[1] != fd[0] && fd[1] == GetWriteFD(io)) { + if (!setattr(fd[1], t+1)) { + error = errno; + status = -1; + } + } + if (status) { + if (status == -1) { + rb_syserr_fail(error, 0); + } + rb_jump_tag(status); + } + return result; +} + +#if !defined _WIN32 +struct ttymode_callback_args { + VALUE (*func)(VALUE, VALUE); + VALUE io; + VALUE farg; +}; + +static VALUE +ttymode_callback(VALUE args) +{ + struct ttymode_callback_args *argp = (struct ttymode_callback_args *)args; + return argp->func(argp->io, argp->farg); +} + +static VALUE +ttymode_with_io(VALUE io, VALUE (*func)(VALUE, VALUE), VALUE farg, void (*setter)(conmode *, void *), void *arg) +{ + struct ttymode_callback_args cargs; + cargs.func = func; + cargs.io = io; + cargs.farg = farg; + return ttymode(io, ttymode_callback, (VALUE)&cargs, setter, arg); +} +#endif + +/* + * call-seq: + * io.raw(min: nil, time: nil, intr: nil) {|io| } + * + * Yields +self+ within raw mode, and returns the result of the block. + * + * STDIN.raw(&:gets) + * + * will read and return a line without echo back and line editing. + * + * The parameter +min+ specifies the minimum number of bytes that + * should be received when a read operation is performed. (default: 1) + * + * The parameter +time+ specifies the timeout in _seconds_ with a + * precision of 1/10 of a second. (default: 0) + * + * If the parameter +intr+ is +true+, enables break, interrupt, quit, + * and suspend special characters. + * + * Refer to the manual page of termios for further details. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_raw(int argc, VALUE *argv, VALUE io) +{ + rawmode_arg_t opts, *optp = rawmode_opt(&argc, argv, 0, 0, &opts); + return ttymode(io, rb_yield, io, set_rawmode, optp); +} + +/* + * call-seq: + * io.raw!(min: nil, time: nil, intr: nil) -> io + * + * Enables raw mode, and returns +io+. + * + * If the terminal mode needs to be back, use io.raw { ... }. + * + * See IO#raw for details on the parameters. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_set_raw(int argc, VALUE *argv, VALUE io) +{ + conmode t; + rawmode_arg_t opts, *optp = rawmode_opt(&argc, argv, 0, 0, &opts); + int fd = GetReadFD(io); + if (!getattr(fd, &t)) sys_fail(io); + set_rawmode(&t, optp); + if (!setattr(fd, &t)) sys_fail(io); + return io; +} + +/* + * call-seq: + * io.cooked {|io| } + * + * Yields +self+ within cooked mode. + * + * STDIN.cooked(&:gets) + * + * will read and return a line with echo back and line editing. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_cooked(VALUE io) +{ + return ttymode(io, rb_yield, io, set_cookedmode, NULL); +} + +/* + * call-seq: + * io.cooked! + * + * Enables cooked mode. + * + * If the terminal mode needs to be back, use io.cooked { ... }. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_set_cooked(VALUE io) +{ + conmode t; + int fd = GetReadFD(io); + if (!getattr(fd, &t)) sys_fail(io); + set_cookedmode(&t, NULL); + if (!setattr(fd, &t)) sys_fail(io); + return io; +} + +#ifndef _WIN32 +static VALUE +getc_call(VALUE io) +{ + return rb_funcallv(io, id_getc, 0, 0); +} +#else +static void * +nogvl_getch(void *p) +{ + int len = 0; + wint_t *buf = p, c = _getwch(); + + switch (c) { + case WEOF: + break; + case 0x00: + case 0xe0: + buf[len++] = c; + c = _getwch(); + /* fall through */ + default: + buf[len++] = c; + break; + } + return (void *)(VALUE)len; +} +#endif + +/* + * call-seq: + * io.getch(min: nil, time: nil, intr: nil) -> char + * + * Reads and returns a character in raw mode. + * + * See IO#raw for details on the parameters. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_getch(int argc, VALUE *argv, VALUE io) +{ + rawmode_arg_t opts, *optp = rawmode_opt(&argc, argv, 0, 0, &opts); +#ifndef _WIN32 + return ttymode(io, getc_call, io, set_rawmode, optp); +#else + rb_io_t *fptr; + VALUE str; + wint_t c; + int len; + char buf[8]; + wint_t wbuf[2]; +# ifndef HAVE_RB_IO_WAIT + struct timeval *to = NULL, tv; +# else + VALUE timeout = Qnil; +# endif + + GetOpenFile(io, fptr); + if (optp) { + if (optp->vtime) { +# ifndef HAVE_RB_IO_WAIT + to = &tv; +# else + struct timeval tv; +# endif + tv.tv_sec = optp->vtime / 10; + tv.tv_usec = (optp->vtime % 10) * 100000; +# ifdef HAVE_RB_IO_WAIT + timeout = rb_fiber_scheduler_make_timeout(&tv); +# endif + } + switch (optp->vmin) { + case 1: /* default */ + break; + case 0: /* return nil when timed out */ + if (optp->vtime) break; + /* fallthru */ + default: + rb_warning("min option larger than 1 ignored"); + } + if (optp->intr) { +# ifndef HAVE_RB_IO_WAIT + int w = rb_wait_for_single_fd(fptr->fd, RB_WAITFD_IN, to); + if (w < 0) rb_eof_error(); + if (!(w & RB_WAITFD_IN)) return Qnil; +# else + VALUE result = rb_io_wait(io, RB_INT2NUM(RUBY_IO_READABLE), timeout); + if (!RTEST(result)) return Qnil; +# endif + } + else if (optp->vtime) { + rb_warning("Non-zero vtime option ignored if intr flag is unset"); + } + } + len = (int)(VALUE)rb_thread_call_without_gvl(nogvl_getch, wbuf, RUBY_UBF_IO, 0); + switch (len) { + case 0: + return Qnil; + case 2: + buf[0] = (char)wbuf[0]; + c = wbuf[1]; + len = 1; + do { + buf[len++] = (unsigned char)c; + } while ((c >>= CHAR_BIT) && len < (int)sizeof(buf)); + return rb_str_new(buf, len); + default: + c = wbuf[0]; + len = rb_uv_to_utf8(buf, c); + str = rb_utf8_str_new(buf, len); + return rb_str_conv_enc(str, NULL, rb_default_external_encoding()); + } +#endif +} + +/* + * call-seq: + * io.noecho {|io| } + * + * Yields +self+ with disabling echo back. + * + * STDIN.noecho(&:gets) + * + * will read and return a line without echo back. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_noecho(VALUE io) +{ + return ttymode(io, rb_yield, io, set_noecho, NULL); +} + +/* + * call-seq: + * io.echo = flag + * + * Enables/disables echo back. + * On some platforms, all combinations of this flags and raw/cooked + * mode may not be valid. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_set_echo(VALUE io, VALUE f) +{ + conmode t; + int fd = GetReadFD(io); + + if (!getattr(fd, &t)) sys_fail(io); + + if (RTEST(f)) + set_echo(&t, NULL); + else + set_noecho(&t, NULL); + + if (!setattr(fd, &t)) sys_fail(io); + + return io; +} + +/* + * call-seq: + * io.echo? -> true or false + * + * Returns +true+ if echo back is enabled. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_echo_p(VALUE io) +{ + conmode t; + int fd = GetReadFD(io); + + if (!getattr(fd, &t)) sys_fail(io); + return echo_p(&t) ? Qtrue : Qfalse; +} + +static const rb_data_type_t conmode_type = { + "console-mode", + {0, RUBY_TYPED_DEFAULT_FREE,}, + 0, 0, + RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; +static VALUE cConmode; + +static VALUE +conmode_alloc(VALUE klass) +{ + return rb_data_typed_object_zalloc(klass, sizeof(conmode), &conmode_type); +} + +static VALUE +conmode_new(VALUE klass, const conmode *t) +{ + VALUE obj = conmode_alloc(klass); + *(conmode *)DATA_PTR(obj) = *t; + return obj; +} + +static VALUE +conmode_init_copy(VALUE obj, VALUE obj2) +{ + conmode *t = rb_check_typeddata(obj, &conmode_type); + conmode *t2 = rb_check_typeddata(obj2, &conmode_type); + *t = *t2; + return obj; +} + +static VALUE +conmode_set_echo(VALUE obj, VALUE f) +{ + conmode *t = rb_check_typeddata(obj, &conmode_type); + if (RTEST(f)) + set_echo(t, NULL); + else + set_noecho(t, NULL); + return obj; +} + +static VALUE +conmode_set_raw(int argc, VALUE *argv, VALUE obj) +{ + conmode *t = rb_check_typeddata(obj, &conmode_type); + rawmode_arg_t opts, *optp = rawmode_opt(&argc, argv, 0, 0, &opts); + + set_rawmode(t, optp); + return obj; +} + +static VALUE +conmode_raw_new(int argc, VALUE *argv, VALUE obj) +{ + conmode *r = rb_check_typeddata(obj, &conmode_type); + conmode t = *r; + rawmode_arg_t opts, *optp = rawmode_opt(&argc, argv, 0, 0, &opts); + + set_rawmode(&t, optp); + return conmode_new(rb_obj_class(obj), &t); +} + +/* + * call-seq: + * io.console_mode -> mode + * + * Returns a data represents the current console mode. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_conmode_get(VALUE io) +{ + conmode t; + int fd = GetReadFD(io); + + if (!getattr(fd, &t)) sys_fail(io); + + return conmode_new(cConmode, &t); +} + +/* + * call-seq: + * io.console_mode = mode + * + * Sets the console mode to +mode+. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_conmode_set(VALUE io, VALUE mode) +{ + conmode *t, r; + int fd = GetReadFD(io); + + TypedData_Get_Struct(mode, conmode, &conmode_type, t); + r = *t; + + if (!setattr(fd, &r)) sys_fail(io); + + return mode; +} + +#if defined TIOCGWINSZ +typedef struct winsize rb_console_size_t; +#define getwinsize(fd, buf) (ioctl((fd), TIOCGWINSZ, (buf)) == 0) +#define setwinsize(fd, buf) (ioctl((fd), TIOCSWINSZ, (buf)) == 0) +#define winsize_row(buf) (buf)->ws_row +#define winsize_col(buf) (buf)->ws_col +#elif defined _WIN32 +typedef CONSOLE_SCREEN_BUFFER_INFO rb_console_size_t; +#define getwinsize(fd, buf) ( \ + GetConsoleScreenBufferInfo((HANDLE)rb_w32_get_osfhandle(fd), (buf)) || \ + SET_LAST_ERROR) +#define winsize_row(buf) ((buf)->srWindow.Bottom - (buf)->srWindow.Top + 1) +#define winsize_col(buf) (buf)->dwSize.X +#endif + +#if defined TIOCGWINSZ || defined _WIN32 +#define USE_CONSOLE_GETSIZE 1 +#endif + +#ifdef USE_CONSOLE_GETSIZE +/* + * call-seq: + * io.winsize -> [rows, columns] + * + * Returns console size. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_winsize(VALUE io) +{ + rb_console_size_t ws; + int fd = GetWriteFD(io); + if (!getwinsize(fd, &ws)) sys_fail(io); + return rb_assoc_new(INT2NUM(winsize_row(&ws)), INT2NUM(winsize_col(&ws))); +} + +/* + * call-seq: + * io.winsize = [rows, columns] + * + * Tries to set console size. The effect depends on the platform and + * the running environment. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_set_winsize(VALUE io, VALUE size) +{ + rb_console_size_t ws; +#if defined _WIN32 + HANDLE wh; + int newrow, newcol; + BOOL ret; +#endif + VALUE row, col, xpixel, ypixel; + const VALUE *sz; + long sizelen; + int fd; + + size = rb_Array(size); + if ((sizelen = RARRAY_LEN(size)) != 2 && sizelen != 4) { + rb_raise(rb_eArgError, "wrong number of arguments (given %ld, expected 2 or 4)", sizelen); + } + sz = RARRAY_CONST_PTR(size); + row = sz[0], col = sz[1], xpixel = ypixel = Qnil; + if (sizelen == 4) xpixel = sz[2], ypixel = sz[3]; + fd = GetWriteFD(io); +#if defined TIOCSWINSZ + ws.ws_row = ws.ws_col = ws.ws_xpixel = ws.ws_ypixel = 0; +#define SET(m) ws.ws_##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m) + SET(row); + SET(col); + SET(xpixel); + SET(ypixel); +#undef SET + if (!setwinsize(fd, &ws)) sys_fail(io); +#elif defined _WIN32 + wh = (HANDLE)rb_w32_get_osfhandle(fd); +#define SET(m) new##m = NIL_P(m) ? 0 : (unsigned short)NUM2UINT(m) + SET(row); + SET(col); +#undef SET + if (!NIL_P(xpixel)) (void)NUM2UINT(xpixel); + if (!NIL_P(ypixel)) (void)NUM2UINT(ypixel); + if (!GetConsoleScreenBufferInfo(wh, &ws)) { + rb_syserr_fail(LAST_ERROR, "GetConsoleScreenBufferInfo"); + } + ws.dwSize.X = newcol; + ret = SetConsoleScreenBufferSize(wh, ws.dwSize); + ws.srWindow.Left = 0; + ws.srWindow.Top = 0; + ws.srWindow.Right = newcol-1; + ws.srWindow.Bottom = newrow-1; + if (!SetConsoleWindowInfo(wh, TRUE, &ws.srWindow)) { + rb_syserr_fail(LAST_ERROR, "SetConsoleWindowInfo"); + } + /* retry when shrinking buffer after shrunk window */ + if (!ret && !SetConsoleScreenBufferSize(wh, ws.dwSize)) { + rb_syserr_fail(LAST_ERROR, "SetConsoleScreenBufferInfo"); + } + /* remove scrollbar if possible */ + if (!SetConsoleWindowInfo(wh, TRUE, &ws.srWindow)) { + rb_syserr_fail(LAST_ERROR, "SetConsoleWindowInfo"); + } +#endif + return io; +} +#endif + +#ifdef _WIN32 +/* + * call-seq: + * io.check_winsize_changed { ... } -> io + * + * Yields while console input events are queued. + * + * This method is Windows only. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_check_winsize_changed(VALUE io) +{ + HANDLE h; + DWORD num; + + h = (HANDLE)rb_w32_get_osfhandle(GetReadFD(io)); + while (GetNumberOfConsoleInputEvents(h, &num) && num > 0) { + INPUT_RECORD rec; + if (ReadConsoleInput(h, &rec, 1, &num)) { + if (rec.EventType == WINDOW_BUFFER_SIZE_EVENT) { + rb_yield(Qnil); + } + } + } + return io; +} +#else +#define console_check_winsize_changed rb_f_notimplement +#endif + +/* + * call-seq: + * io.iflush + * + * Flushes input buffer in kernel. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_iflush(VALUE io) +{ +#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H + int fd = GetReadFD(io); + if (tcflush(fd, TCIFLUSH)) sys_fail(io); +#endif + + return io; +} + +/* + * call-seq: + * io.oflush + * + * Flushes output buffer in kernel. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_oflush(VALUE io) +{ + int fd = GetWriteFD(io); +#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H + if (tcflush(fd, TCOFLUSH)) sys_fail(io); +#endif + (void)fd; + return io; +} + +/* + * call-seq: + * io.ioflush + * + * Flushes input and output buffers in kernel. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_ioflush(VALUE io) +{ +#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H + int fd1 = GetReadFD(io); + int fd2 = GetWriteFD(io); + + if (fd2 != -1 && fd1 != fd2) { + if (tcflush(fd1, TCIFLUSH)) sys_fail(io); + if (tcflush(fd2, TCOFLUSH)) sys_fail(io); + } + else { + if (tcflush(fd1, TCIOFLUSH)) sys_fail(io); + } +#endif + + return io; +} + +/* + * call-seq: + * io.beep + * + * Beeps on the output console. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_beep(VALUE io) +{ +#ifdef _WIN32 + MessageBeep(0); +#else + int fd = GetWriteFD(io); + if (write(fd, "\a", 1) < 0) sys_fail(io); +#endif + return io; +} + +static int +mode_in_range(VALUE val, int high, const char *modename) +{ + int mode; + if (NIL_P(val)) return 0; + if (!RB_INTEGER_TYPE_P(val)) { + wrong_value: + rb_raise(rb_eArgError, "wrong %s mode: %"PRIsVALUE, modename, val); + } + if ((mode = NUM2INT(val)) < 0 || mode > high) { + goto wrong_value; + } + return mode; +} + +#if defined _WIN32 +static void +constat_clear(HANDLE handle, WORD attr, DWORD len, COORD pos) +{ + DWORD written; + + FillConsoleOutputAttribute(handle, attr, len, pos, &written); + FillConsoleOutputCharacterW(handle, L' ', len, pos, &written); +} + +static VALUE +console_scroll(VALUE io, int line) +{ + HANDLE h; + rb_console_size_t ws; + + h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io)); + if (!GetConsoleScreenBufferInfo(h, &ws)) { + rb_syserr_fail(LAST_ERROR, 0); + } + if (line) { + SMALL_RECT scroll; + COORD destination; + CHAR_INFO fill; + scroll.Left = 0; + scroll.Top = line > 0 ? line : 0; + scroll.Right = winsize_col(&ws) - 1; + scroll.Bottom = winsize_row(&ws) - 1 + (line < 0 ? line : 0); + destination.X = 0; + destination.Y = line < 0 ? -line : 0; + fill.Char.UnicodeChar = L' '; + fill.Attributes = ws.wAttributes; + + ScrollConsoleScreenBuffer(h, &scroll, NULL, destination, &fill); + } + return io; +} + +#define GPERF_DOWNCASE 1 +#define GPERF_CASE_STRCMP 1 +#define gperf_case_strcmp STRCASECMP +#include "win32_vk.inc" + +/* + * call-seq: + * io.pressed?(key) -> bool + * + * Returns +true+ if +key+ is pressed. +key+ may be a virtual key + * code or its name (String or Symbol) with out "VK_" prefix. + * + * This method is Windows only. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_key_pressed_p(VALUE io, VALUE k) +{ + int vk = -1; + + if (FIXNUM_P(k)) { + vk = NUM2UINT(k); + } + else { + const struct vktable *t; + const char *kn; + if (SYMBOL_P(k)) { + k = rb_sym2str(k); + kn = RSTRING_PTR(k); + } + else { + kn = StringValuePtr(k); + } + t = console_win32_vk(kn, RSTRING_LEN(k)); + if (!t || (vk = (short)t->vk) == -1) { + rb_raise(rb_eArgError, "unknown virtual key code: % "PRIsVALUE, k); + } + } + return GetKeyState(vk) & 0x80 ? Qtrue : Qfalse; +} +#else +struct query_args { + char qstr[6]; + unsigned char opt; +}; + +static int +direct_query(VALUE io, const struct query_args *query) +{ + if (RB_TYPE_P(io, T_FILE)) { + VALUE wio = rb_io_get_write_io(io); + VALUE s = rb_str_new_cstr(query->qstr); + rb_io_write(wio, s); + rb_io_flush(wio); + return 1; + } + return 0; +} + +static VALUE +read_vt_response(VALUE io, VALUE query) +{ + struct query_args *qargs = (struct query_args *)query; + VALUE result, b; + int opt = 0; + int num = 0; + if (qargs) { + opt = qargs->opt; + if (!direct_query(io, qargs)) return Qnil; + } + if (rb_io_getbyte(io) != INT2FIX(0x1b)) return Qnil; + if (rb_io_getbyte(io) != INT2FIX('[')) return Qnil; + result = rb_ary_new(); + while (!NIL_P(b = rb_io_getbyte(io))) { + int c = NUM2UINT(b); + if (c == ';') { + rb_ary_push(result, INT2NUM(num)); + num = 0; + } + else if (ISDIGIT(c)) { + num = num * 10 + c - '0'; + } + else if (opt && c == opt) { + opt = 0; + } + else { + char last = (char)c; + rb_ary_push(result, INT2NUM(num)); + b = rb_str_new(&last, 1); + break; + } + } + return rb_ary_push(result, b); +} + +static VALUE +console_vt_response(int argc, VALUE *argv, VALUE io, const struct query_args *qargs) +{ + rawmode_arg_t opts, *optp = rawmode_opt(&argc, argv, 0, 1, &opts); + VALUE query = (VALUE)qargs; + VALUE ret = ttymode_with_io(io, read_vt_response, query, set_rawmode, optp); + return ret; +} + +static VALUE +console_scroll(VALUE io, int line) +{ + if (line) { + VALUE s = rb_sprintf(CSI "%d%c", line < 0 ? -line : line, + line < 0 ? 'T' : 'S'); + rb_io_write(io, s); + } + return io; +} + +# define console_key_pressed_p rb_f_notimplement +#endif + +/* + * call-seq: + * io.cursor -> [row, column] + * + * Returns the current cursor position as a two-element array of integers (row, column) + * + * io.cursor # => [3, 5] + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_cursor_pos(VALUE io) +{ +#ifdef _WIN32 + rb_console_size_t ws; + int fd = GetWriteFD(io); + if (!GetConsoleScreenBufferInfo((HANDLE)rb_w32_get_osfhandle(fd), &ws)) { + rb_syserr_fail(LAST_ERROR, 0); + } + return rb_assoc_new(UINT2NUM(ws.dwCursorPosition.Y), UINT2NUM(ws.dwCursorPosition.X)); +#else + static const struct query_args query = {"\033[6n", 0}; + VALUE resp = console_vt_response(0, 0, io, &query); + VALUE row, column, term; + unsigned int r, c; + if (!RB_TYPE_P(resp, T_ARRAY) || RARRAY_LEN(resp) != 3) return Qnil; + term = RARRAY_AREF(resp, 2); + if (!RB_TYPE_P(term, T_STRING) || RSTRING_LEN(term) != 1) return Qnil; + if (RSTRING_PTR(term)[0] != 'R') return Qnil; + row = RARRAY_AREF(resp, 0); + column = RARRAY_AREF(resp, 1); + rb_ary_resize(resp, 2); + r = NUM2UINT(row) - 1; + c = NUM2UINT(column) - 1; + RARRAY_ASET(resp, 0, INT2NUM(r)); + RARRAY_ASET(resp, 1, INT2NUM(c)); + return resp; +#endif +} + +/* + * call-seq: + * io.goto(line, column) -> io + * + * Set the cursor position at +line+ and +column+. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_goto(VALUE io, VALUE y, VALUE x) +{ +#ifdef _WIN32 + COORD pos; + int fd = GetWriteFD(io); + pos.X = NUM2UINT(x); + pos.Y = NUM2UINT(y); + if (!SetConsoleCursorPosition((HANDLE)rb_w32_get_osfhandle(fd), pos)) { + rb_syserr_fail(LAST_ERROR, 0); + } +#else + rb_io_write(io, rb_sprintf(CSI "%d;%dH", NUM2UINT(y)+1, NUM2UINT(x)+1)); +#endif + return io; +} + +static VALUE +console_move(VALUE io, int y, int x) +{ +#ifdef _WIN32 + HANDLE h; + rb_console_size_t ws; + COORD *pos = &ws.dwCursorPosition; + + h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io)); + if (!GetConsoleScreenBufferInfo(h, &ws)) { + rb_syserr_fail(LAST_ERROR, 0); + } + pos->X += x; + pos->Y += y; + if (!SetConsoleCursorPosition(h, *pos)) { + rb_syserr_fail(LAST_ERROR, 0); + } +#else + if (x || y) { + VALUE s = rb_str_new_cstr(""); + if (y) rb_str_catf(s, CSI "%d%c", y < 0 ? -y : y, y < 0 ? 'A' : 'B'); + if (x) rb_str_catf(s, CSI "%d%c", x < 0 ? -x : x, x < 0 ? 'D' : 'C'); + rb_io_write(io, s); + rb_io_flush(io); + } +#endif + return io; +} + +/* + * call-seq: + * io.goto_column(column) -> io + * + * Set the cursor position at +column+ in the same line of the current + * position. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_goto_column(VALUE io, VALUE val) +{ +#ifdef _WIN32 + HANDLE h; + rb_console_size_t ws; + COORD *pos = &ws.dwCursorPosition; + + h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io)); + if (!GetConsoleScreenBufferInfo(h, &ws)) { + rb_syserr_fail(LAST_ERROR, 0); + } + pos->X = NUM2INT(val); + if (!SetConsoleCursorPosition(h, *pos)) { + rb_syserr_fail(LAST_ERROR, 0); + } +#else + rb_io_write(io, rb_sprintf(CSI "%dG", NUM2UINT(val)+1)); +#endif + return io; +} + +/* + * call-seq: + * io.erase_line(mode) -> io + * + * Erases the line at the cursor corresponding to +mode+. + * +mode+ may be either: + * 0: after cursor + * 1: before and cursor + * 2: entire line + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_erase_line(VALUE io, VALUE val) +{ + int mode = mode_in_range(val, 2, "line erase"); +#ifdef _WIN32 + HANDLE h; + rb_console_size_t ws; + COORD *pos = &ws.dwCursorPosition; + DWORD w; + + h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io)); + if (!GetConsoleScreenBufferInfo(h, &ws)) { + rb_syserr_fail(LAST_ERROR, 0); + } + w = winsize_col(&ws); + switch (mode) { + case 0: /* after cursor */ + w -= pos->X; + break; + case 1: /* before *and* cursor */ + w = pos->X + 1; + pos->X = 0; + break; + case 2: /* entire line */ + pos->X = 0; + break; + } + constat_clear(h, ws.wAttributes, w, *pos); + return io; +#else + rb_io_write(io, rb_sprintf(CSI "%dK", mode)); +#endif + return io; +} + +/* + * call-seq: + * io.erase_screen(mode) -> io + * + * Erases the screen at the cursor corresponding to +mode+. + * +mode+ may be either: + * 0: after cursor + * 1: before and cursor + * 2: entire screen + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_erase_screen(VALUE io, VALUE val) +{ + int mode = mode_in_range(val, 3, "screen erase"); +#ifdef _WIN32 + HANDLE h; + rb_console_size_t ws; + COORD *pos = &ws.dwCursorPosition; + DWORD w; + + h = (HANDLE)rb_w32_get_osfhandle(GetWriteFD(io)); + if (!GetConsoleScreenBufferInfo(h, &ws)) { + rb_syserr_fail(LAST_ERROR, 0); + } + w = winsize_col(&ws); + switch (mode) { + case 0: /* erase after cursor */ + w = (w * (ws.srWindow.Bottom - pos->Y + 1) - pos->X); + break; + case 1: /* erase before *and* cursor */ + w = (w * (pos->Y - ws.srWindow.Top) + pos->X + 1); + pos->X = 0; + pos->Y = ws.srWindow.Top; + break; + case 2: /* erase entire screen */ + w = (w * winsize_row(&ws)); + pos->X = 0; + pos->Y = ws.srWindow.Top; + break; + case 3: /* erase entire screen */ + w = (w * ws.dwSize.Y); + pos->X = 0; + pos->Y = 0; + break; + } + constat_clear(h, ws.wAttributes, w, *pos); +#else + rb_io_write(io, rb_sprintf(CSI "%dJ", mode)); +#endif + return io; +} + +/* + * call-seq: + * io.cursor = [line, column] -> io + * + * Same as io.goto(line, column) + * + * See IO#goto. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_cursor_set(VALUE io, VALUE cpos) +{ + cpos = rb_convert_type(cpos, T_ARRAY, "Array", "to_ary"); + if (RARRAY_LEN(cpos) != 2) rb_raise(rb_eArgError, "expected 2D coordinate"); + return console_goto(io, RARRAY_AREF(cpos, 0), RARRAY_AREF(cpos, 1)); +} + +/* + * call-seq: + * io.cursor_up(n) -> io + * + * Moves the cursor up +n+ lines. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_cursor_up(VALUE io, VALUE val) +{ + return console_move(io, -NUM2INT(val), 0); +} + +/* + * call-seq: + * io.cursor_down(n) -> io + * + * Moves the cursor down +n+ lines. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_cursor_down(VALUE io, VALUE val) +{ + return console_move(io, +NUM2INT(val), 0); +} + +/* + * call-seq: + * io.cursor_left(n) -> io + * + * Moves the cursor left +n+ columns. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_cursor_left(VALUE io, VALUE val) +{ + return console_move(io, 0, -NUM2INT(val)); +} + +/* + * call-seq: + * io.cursor_right(n) -> io + * + * Moves the cursor right +n+ columns. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_cursor_right(VALUE io, VALUE val) +{ + return console_move(io, 0, +NUM2INT(val)); +} + +/* + * call-seq: + * io.scroll_forward(n) -> io + * + * Scrolls the entire scrolls forward +n+ lines. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_scroll_forward(VALUE io, VALUE val) +{ + return console_scroll(io, +NUM2INT(val)); +} + +/* + * call-seq: + * io.scroll_backward(n) -> io + * + * Scrolls the entire scrolls backward +n+ lines. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_scroll_backward(VALUE io, VALUE val) +{ + return console_scroll(io, -NUM2INT(val)); +} + +/* + * call-seq: + * io.clear_screen -> io + * + * Clears the entire screen and moves the cursor top-left corner. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_clear_screen(VALUE io) +{ + console_erase_screen(io, INT2FIX(2)); + console_goto(io, INT2FIX(0), INT2FIX(0)); + return io; +} + +#ifndef HAVE_RB_IO_OPEN_DESCRIPTOR +static VALUE +io_open_descriptor_fallback(VALUE klass, int descriptor, int mode, VALUE path, VALUE timeout, void *encoding) +{ + VALUE arguments[2] = { + (rb_update_max_fd(descriptor), INT2NUM(descriptor)), + INT2FIX(mode), + }; + + VALUE self = rb_class_new_instance(2, arguments, klass); + + rb_io_t *fptr; + GetOpenFile(self, fptr); + fptr->pathv = path; + fptr->mode |= mode; + + return self; +} +#define rb_io_open_descriptor io_open_descriptor_fallback +#endif + +#ifndef HAVE_RB_IO_CLOSED_P +static VALUE +rb_io_closed_p(VALUE io) +{ + rb_io_t *fptr = RFILE(io)->fptr; + return fptr->fd == -1 ? Qtrue : Qfalse; +} +#endif + +#if defined(RB_EXT_RACTOR_SAFE) && defined(HAVE_RB_RACTOR_LOCAL_STORAGE_VALUE_NEWKEY) +# define USE_RACTOR_STORAGE 1 +#else +# define USE_RACTOR_STORAGE 0 +#endif + +#if USE_RACTOR_STORAGE +#include "ruby/ractor.h" +static rb_ractor_local_key_t key_console_dev; + +static bool +console_dev_get(VALUE klass, VALUE *dev) +{ + return rb_ractor_local_storage_value_lookup(key_console_dev, dev); +} + +static void +console_dev_set(VALUE klass, VALUE value) +{ + rb_ractor_local_storage_value_set(key_console_dev, value); +} + +static void +console_dev_remove(VALUE klass) +{ + console_dev_set(klass, Qnil); +} + +#else + +static ID id_console; + +static int +console_dev_get(VALUE klass, VALUE *dev) +{ + if (rb_const_defined(klass, id_console)) { + *dev = rb_const_get(klass, id_console); + return 1; + } + return 0; +} + +static void +console_dev_set(VALUE klass, VALUE value) +{ + rb_const_set(klass, id_console, value); +} + +static void +console_dev_remove(VALUE klass) +{ + rb_const_remove(klass, id_console); +} + +#endif + +/* + * call-seq: + * IO.console -> # + * IO.console(sym, *args) + * + * Returns an File instance opened console. + * + * If +sym+ is given, it will be sent to the opened console with + * +args+ and the result will be returned instead of the console IO + * itself. + * + * You must require 'io/console' to use this method. + */ +static VALUE +console_dev(int argc, VALUE *argv, VALUE klass) +{ + VALUE con = 0; + VALUE sym = 0; + + rb_check_arity(argc, 0, UNLIMITED_ARGUMENTS); + + if (argc) { + Check_Type(sym = argv[0], T_SYMBOL); + } + + // Force the class to be File. + if (klass == rb_cIO) klass = rb_cFile; + + if (console_dev_get(klass, &con)) { + if (!RB_TYPE_P(con, T_FILE) || RTEST(rb_io_closed_p(con))) { + console_dev_remove(klass); + con = 0; + } + } + + if (sym) { + if (sym == ID2SYM(id_close) && argc == 1) { + if (con) { + rb_io_close(con); + console_dev_remove(klass); + con = 0; + } + return Qnil; + } + } + + if (!con) { +#if defined HAVE_TERMIOS_H || defined HAVE_TERMIO_H || defined HAVE_SGTTY_H +# define CONSOLE_DEVICE "/dev/tty" +#elif defined _WIN32 +# define CONSOLE_DEVICE "con$" +# define CONSOLE_DEVICE_FOR_READING "conin$" +# define CONSOLE_DEVICE_FOR_WRITING "conout$" +#endif +#ifndef CONSOLE_DEVICE_FOR_READING +# define CONSOLE_DEVICE_FOR_READING CONSOLE_DEVICE +#endif +#ifdef CONSOLE_DEVICE_FOR_WRITING + VALUE out; +#endif + int fd; + VALUE path = rb_obj_freeze(rb_str_new2(CONSOLE_DEVICE)); + +#ifdef CONSOLE_DEVICE_FOR_WRITING + fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_WRITING, O_RDWR, 0); + if (fd < 0) return Qnil; + out = rb_io_open_descriptor(klass, fd, FMODE_WRITABLE | FMODE_SYNC, path, Qnil, NULL); +#endif + fd = rb_cloexec_open(CONSOLE_DEVICE_FOR_READING, O_RDWR, 0); + if (fd < 0) { +#ifdef CONSOLE_DEVICE_FOR_WRITING + rb_io_close(out); +#endif + return Qnil; + } + + con = rb_io_open_descriptor(klass, fd, FMODE_READWRITE | FMODE_SYNC, path, Qnil, NULL); +#ifdef CONSOLE_DEVICE_FOR_WRITING + rb_io_set_write_io(con, out); +#endif + console_dev_set(klass, con); + } + + if (sym) { + return rb_f_send(argc, argv, con); + } + + return con; +} + +/* + * call-seq: + * io.getch(min: nil, time: nil, intr: nil) -> char + * + * See IO#getch. + */ +static VALUE +io_getch(int argc, VALUE *argv, VALUE io) +{ + return rb_funcallv(io, id_getc, argc, argv); +} + +static VALUE +puts_call(VALUE io) +{ + return rb_io_write(io, rb_default_rs); +} + +static VALUE +gets_call(VALUE io) +{ + return rb_funcallv(io, id_gets, 0, 0); +} + +static VALUE +getpass_call(VALUE io) +{ + return ttymode(io, rb_io_gets, io, set_noecho, NULL); +} + +static void +prompt(int argc, VALUE *argv, VALUE io) +{ + if (argc > 0 && !NIL_P(argv[0])) { + VALUE str = argv[0]; + StringValueCStr(str); + rb_io_write(io, str); + } +} + +static VALUE +str_chomp(VALUE str) +{ + if (!NIL_P(str)) { + const VALUE rs = rb_default_rs; /* rvalue in TruffleRuby */ + rb_funcallv(str, id_chomp_bang, 1, &rs); + } + return str; +} + +/* + * call-seq: + * io.getpass(prompt=nil) -> string + * + * Reads and returns a line without echo back. + * Prints +prompt+ unless it is +nil+. + * + * The newline character that terminates the + * read line is removed from the returned string, + * see String#chomp!. + * + * You must require 'io/console' to use this method. + * + * require 'io/console' + * IO::console.getpass("Enter password:") + * Enter password: + * # => "mypassword" + * + */ +static VALUE +console_getpass(int argc, VALUE *argv, VALUE io) +{ + VALUE str, wio; + + rb_check_arity(argc, 0, 1); + wio = rb_io_get_write_io(io); + if (wio == io && io == rb_stdin) wio = rb_stderr; + prompt(argc, argv, wio); + rb_io_flush(wio); + str = rb_ensure(getpass_call, io, puts_call, wio); + return str_chomp(str); +} + +/* + * call-seq: + * io.getpass(prompt=nil) -> string + * + * See IO#getpass. + */ +static VALUE +io_getpass(int argc, VALUE *argv, VALUE io) +{ + VALUE str; + + rb_check_arity(argc, 0, 1); + prompt(argc, argv, io); + rb_check_funcall(io, id_flush, 0, 0); + str = rb_ensure(gets_call, io, puts_call, io); + return str_chomp(str); +} + +#if defined(_WIN32) || defined(HAVE_TTYNAME_R) || defined(HAVE_TTYNAME) +/* + * call-seq: + * io.ttyname -> string or nil + * + * Returns name of associated terminal (tty) if +io+ is not a tty. + * Returns +nil+ otherwise. + */ +static VALUE +console_ttyname(VALUE io) +{ + int fd = rb_io_descriptor(io); + if (!isatty(fd)) return Qnil; +# if defined _WIN32 + return rb_usascii_str_new_lit("con"); +# elif defined HAVE_TTYNAME_R + { + char termname[1024], *tn = termname; + size_t size = sizeof(termname); + int e; + if (ttyname_r(fd, tn, size) == 0) + return rb_interned_str_cstr(tn); + if ((e = errno) == ERANGE) { + VALUE s = rb_str_new(0, size); + while (1) { + tn = RSTRING_PTR(s); + size = rb_str_capacity(s); + if (ttyname_r(fd, tn, size) == 0) { + return rb_str_to_interned_str(rb_str_resize(s, strlen(tn))); + } + if ((e = errno) != ERANGE) break; + if ((size *= 2) >= INT_MAX/2) break; + rb_str_resize(s, size); + } + } + rb_syserr_fail_str(e, rb_sprintf("ttyname_r(%d)", fd)); + UNREACHABLE_RETURN(Qnil); + } +# elif defined HAVE_TTYNAME + { + const char *tn = ttyname(fd); + if (!tn) { + int e = errno; + rb_syserr_fail_str(e, rb_sprintf("ttyname(%d)", fd)); + } + return rb_interned_str_cstr(tn); + } +# else +# error No ttyname function +# endif +} +#else +# define console_ttyname rb_f_notimplement +#endif + +/* + * IO console methods + */ +void +Init_console(void) +{ +#if USE_RACTOR_STORAGE + RB_EXT_RACTOR_SAFE(true); +#endif + +#undef rb_intern +#if USE_RACTOR_STORAGE + key_console_dev = rb_ractor_local_storage_value_newkey(); +#else + id_console = rb_intern("console"); +#endif + id_getc = rb_intern("getc"); + id_gets = rb_intern("gets"); + id_flush = rb_intern("flush"); + id_chomp_bang = rb_intern("chomp!"); + id_close = rb_intern("close"); +#define init_rawmode_opt_id(name) \ + rawmode_opt_ids[kwd_##name] = rb_intern(#name) + init_rawmode_opt_id(min); + init_rawmode_opt_id(time); + init_rawmode_opt_id(intr); +#ifndef HAVE_RB_F_SEND + id___send__ = rb_intern("__send__"); +#endif + InitVM(console); +} + +void +InitVM_console(void) +{ + rb_define_method(rb_cIO, "raw", console_raw, -1); + rb_define_method(rb_cIO, "raw!", console_set_raw, -1); + rb_define_method(rb_cIO, "cooked", console_cooked, 0); + rb_define_method(rb_cIO, "cooked!", console_set_cooked, 0); + rb_define_method(rb_cIO, "getch", console_getch, -1); + rb_define_method(rb_cIO, "echo=", console_set_echo, 1); + rb_define_method(rb_cIO, "echo?", console_echo_p, 0); + rb_define_method(rb_cIO, "console_mode", console_conmode_get, 0); + rb_define_method(rb_cIO, "console_mode=", console_conmode_set, 1); + rb_define_method(rb_cIO, "noecho", console_noecho, 0); + rb_define_method(rb_cIO, "winsize", console_winsize, 0); + rb_define_method(rb_cIO, "winsize=", console_set_winsize, 1); + rb_define_method(rb_cIO, "iflush", console_iflush, 0); + rb_define_method(rb_cIO, "oflush", console_oflush, 0); + rb_define_method(rb_cIO, "ioflush", console_ioflush, 0); + rb_define_method(rb_cIO, "beep", console_beep, 0); + rb_define_method(rb_cIO, "goto", console_goto, 2); + rb_define_method(rb_cIO, "cursor", console_cursor_pos, 0); + rb_define_method(rb_cIO, "cursor=", console_cursor_set, 1); + rb_define_method(rb_cIO, "cursor_up", console_cursor_up, 1); + rb_define_method(rb_cIO, "cursor_down", console_cursor_down, 1); + rb_define_method(rb_cIO, "cursor_left", console_cursor_left, 1); + rb_define_method(rb_cIO, "cursor_right", console_cursor_right, 1); + rb_define_method(rb_cIO, "goto_column", console_goto_column, 1); + rb_define_method(rb_cIO, "erase_line", console_erase_line, 1); + rb_define_method(rb_cIO, "erase_screen", console_erase_screen, 1); + rb_define_method(rb_cIO, "scroll_forward", console_scroll_forward, 1); + rb_define_method(rb_cIO, "scroll_backward", console_scroll_backward, 1); + rb_define_method(rb_cIO, "clear_screen", console_clear_screen, 0); + rb_define_method(rb_cIO, "pressed?", console_key_pressed_p, 1); + rb_define_method(rb_cIO, "check_winsize_changed", console_check_winsize_changed, 0); + rb_define_method(rb_cIO, "getpass", console_getpass, -1); + rb_define_method(rb_cIO, "ttyname", console_ttyname, 0); + rb_define_singleton_method(rb_cIO, "console", console_dev, -1); + { + /* :stopdoc: */ + VALUE mReadable = rb_define_module_under(rb_cIO, "generic_readable"); + /* :startdoc: */ + rb_define_method(mReadable, "getch", io_getch, -1); + rb_define_method(mReadable, "getpass", io_getpass, -1); + } + { + /* :stopdoc: */ + cConmode = rb_define_class_under(rb_cIO, "ConsoleMode", rb_cObject); + rb_define_const(cConmode, "VERSION", rb_obj_freeze(rb_str_new_cstr(IO_CONSOLE_VERSION))); + rb_define_alloc_func(cConmode, conmode_alloc); + rb_undef_method(cConmode, "initialize"); + rb_define_method(cConmode, "initialize_copy", conmode_init_copy, 1); + rb_define_method(cConmode, "echo=", conmode_set_echo, 1); + rb_define_method(cConmode, "raw!", conmode_set_raw, -1); + rb_define_method(cConmode, "raw", conmode_raw_new, -1); + /* :startdoc: */ + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/ext/io/console/extconf.rb b/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/ext/io/console/extconf.rb new file mode 100644 index 00000000..4ad7ed69 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/ext/io/console/extconf.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: false +require 'mkmf' + +# `--target-rbconfig` compatibility for Ruby 3.3 or earlier +# See https://bugs.ruby-lang.org/issues/20345 +MakeMakefile::RbConfig ||= ::RbConfig + +have_func("rb_syserr_fail_str(0, Qnil)") or +have_func("rb_syserr_new_str(0, Qnil)") or + abort + +have_func("rb_interned_str_cstr") +have_func("rb_io_path") +have_func("rb_io_descriptor") +have_func("rb_io_get_write_io") +have_func("rb_io_closed_p") +have_func("rb_io_open_descriptor") +have_func("rb_ractor_local_storage_value_newkey") + +is_wasi = /wasi/ =~ MakeMakefile::RbConfig::CONFIG["platform"] +# `ok` can be `true`, `false`, or `nil`: +# * `true` : Required headers and functions available, proceed regular build. +# * `false`: Required headers or functions not available, abort build. +# * `nil` : Unsupported compilation target, generate dummy Makefile. +# +# Skip building io/console on WASI, as it does not support termios.h. +ok = true if (RUBY_ENGINE == "ruby" && !is_wasi) || RUBY_ENGINE == "truffleruby" +hdr = nil +case +when macro_defined?("_WIN32", "") + # rb_w32_map_errno: 1.8.7 + vk_header = File.exist?("#$srcdir/win32_vk.list") ? "chksum" : "inc" + vk_header = "#{'{$(srcdir)}' if $nmake == ?m}win32_vk.#{vk_header}" +when hdr = %w"termios.h termio.h".find {|h| have_header(h)} + have_func("cfmakeraw", hdr) +when have_header(hdr = "sgtty.h") + %w"stty gtty".each {|f| have_func(f, hdr)} +else + ok = false +end if ok +case ok +when true + have_header("sys/ioctl.h") if hdr + # rb_check_hash_type: 1.9.3 + # rb_io_get_write_io: 1.9.1 + # rb_cloexec_open: 2.0.0 + # rb_funcallv: 2.1.0 + # RARRAY_CONST_PTR: 2.1.0 + # rb_sym2str: 2.2.0 + if have_macro("HAVE_RUBY_FIBER_SCHEDULER_H") + $defs << "-D""HAVE_RB_IO_WAIT=1" + elsif have_func("rb_scheduler_timeout") # 3.0 + have_func("rb_io_wait") + end + have_func("ttyname_r") or have_func("ttyname") + create_makefile("io/console") {|conf| + conf << "\n""VK_HEADER = #{vk_header}\n" + } +when nil + File.write("Makefile", dummy_makefile($srcdir).join("")) +end diff --git a/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/ext/io/console/win32_vk.inc b/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/ext/io/console/win32_vk.inc new file mode 100644 index 00000000..348e6be5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/ext/io/console/win32_vk.inc @@ -0,0 +1,1390 @@ +#define UNDEFINED_VK (unsigned short)-1 +#ifndef VK_LBUTTON +# define VK_LBUTTON UNDEFINED_VK +#endif +#ifndef VK_RBUTTON +# define VK_RBUTTON UNDEFINED_VK +#endif +#ifndef VK_CANCEL +# define VK_CANCEL UNDEFINED_VK +#endif +#ifndef VK_MBUTTON +# define VK_MBUTTON UNDEFINED_VK +#endif +#ifndef VK_XBUTTON1 +# define VK_XBUTTON1 UNDEFINED_VK +#endif +#ifndef VK_XBUTTON2 +# define VK_XBUTTON2 UNDEFINED_VK +#endif +#ifndef VK_BACK +# define VK_BACK UNDEFINED_VK +#endif +#ifndef VK_TAB +# define VK_TAB UNDEFINED_VK +#endif +#ifndef VK_CLEAR +# define VK_CLEAR UNDEFINED_VK +#endif +#ifndef VK_RETURN +# define VK_RETURN UNDEFINED_VK +#endif +#ifndef VK_SHIFT +# define VK_SHIFT UNDEFINED_VK +#endif +#ifndef VK_CONTROL +# define VK_CONTROL UNDEFINED_VK +#endif +#ifndef VK_MENU +# define VK_MENU UNDEFINED_VK +#endif +#ifndef VK_PAUSE +# define VK_PAUSE UNDEFINED_VK +#endif +#ifndef VK_CAPITAL +# define VK_CAPITAL UNDEFINED_VK +#endif +#ifndef VK_KANA +# define VK_KANA UNDEFINED_VK +#endif +#ifndef VK_HANGEUL +# define VK_HANGEUL UNDEFINED_VK +#endif +#ifndef VK_HANGUL +# define VK_HANGUL UNDEFINED_VK +#endif +#ifndef VK_JUNJA +# define VK_JUNJA UNDEFINED_VK +#endif +#ifndef VK_FINAL +# define VK_FINAL UNDEFINED_VK +#endif +#ifndef VK_HANJA +# define VK_HANJA UNDEFINED_VK +#endif +#ifndef VK_KANJI +# define VK_KANJI UNDEFINED_VK +#endif +#ifndef VK_ESCAPE +# define VK_ESCAPE UNDEFINED_VK +#endif +#ifndef VK_CONVERT +# define VK_CONVERT UNDEFINED_VK +#endif +#ifndef VK_NONCONVERT +# define VK_NONCONVERT UNDEFINED_VK +#endif +#ifndef VK_ACCEPT +# define VK_ACCEPT UNDEFINED_VK +#endif +#ifndef VK_MODECHANGE +# define VK_MODECHANGE UNDEFINED_VK +#endif +#ifndef VK_SPACE +# define VK_SPACE UNDEFINED_VK +#endif +#ifndef VK_PRIOR +# define VK_PRIOR UNDEFINED_VK +#endif +#ifndef VK_NEXT +# define VK_NEXT UNDEFINED_VK +#endif +#ifndef VK_END +# define VK_END UNDEFINED_VK +#endif +#ifndef VK_HOME +# define VK_HOME UNDEFINED_VK +#endif +#ifndef VK_LEFT +# define VK_LEFT UNDEFINED_VK +#endif +#ifndef VK_UP +# define VK_UP UNDEFINED_VK +#endif +#ifndef VK_RIGHT +# define VK_RIGHT UNDEFINED_VK +#endif +#ifndef VK_DOWN +# define VK_DOWN UNDEFINED_VK +#endif +#ifndef VK_SELECT +# define VK_SELECT UNDEFINED_VK +#endif +#ifndef VK_PRINT +# define VK_PRINT UNDEFINED_VK +#endif +#ifndef VK_EXECUTE +# define VK_EXECUTE UNDEFINED_VK +#endif +#ifndef VK_SNAPSHOT +# define VK_SNAPSHOT UNDEFINED_VK +#endif +#ifndef VK_INSERT +# define VK_INSERT UNDEFINED_VK +#endif +#ifndef VK_DELETE +# define VK_DELETE UNDEFINED_VK +#endif +#ifndef VK_HELP +# define VK_HELP UNDEFINED_VK +#endif +#ifndef VK_LWIN +# define VK_LWIN UNDEFINED_VK +#endif +#ifndef VK_RWIN +# define VK_RWIN UNDEFINED_VK +#endif +#ifndef VK_APPS +# define VK_APPS UNDEFINED_VK +#endif +#ifndef VK_SLEEP +# define VK_SLEEP UNDEFINED_VK +#endif +#ifndef VK_NUMPAD0 +# define VK_NUMPAD0 UNDEFINED_VK +#endif +#ifndef VK_NUMPAD1 +# define VK_NUMPAD1 UNDEFINED_VK +#endif +#ifndef VK_NUMPAD2 +# define VK_NUMPAD2 UNDEFINED_VK +#endif +#ifndef VK_NUMPAD3 +# define VK_NUMPAD3 UNDEFINED_VK +#endif +#ifndef VK_NUMPAD4 +# define VK_NUMPAD4 UNDEFINED_VK +#endif +#ifndef VK_NUMPAD5 +# define VK_NUMPAD5 UNDEFINED_VK +#endif +#ifndef VK_NUMPAD6 +# define VK_NUMPAD6 UNDEFINED_VK +#endif +#ifndef VK_NUMPAD7 +# define VK_NUMPAD7 UNDEFINED_VK +#endif +#ifndef VK_NUMPAD8 +# define VK_NUMPAD8 UNDEFINED_VK +#endif +#ifndef VK_NUMPAD9 +# define VK_NUMPAD9 UNDEFINED_VK +#endif +#ifndef VK_MULTIPLY +# define VK_MULTIPLY UNDEFINED_VK +#endif +#ifndef VK_ADD +# define VK_ADD UNDEFINED_VK +#endif +#ifndef VK_SEPARATOR +# define VK_SEPARATOR UNDEFINED_VK +#endif +#ifndef VK_SUBTRACT +# define VK_SUBTRACT UNDEFINED_VK +#endif +#ifndef VK_DECIMAL +# define VK_DECIMAL UNDEFINED_VK +#endif +#ifndef VK_DIVIDE +# define VK_DIVIDE UNDEFINED_VK +#endif +#ifndef VK_F1 +# define VK_F1 UNDEFINED_VK +#endif +#ifndef VK_F2 +# define VK_F2 UNDEFINED_VK +#endif +#ifndef VK_F3 +# define VK_F3 UNDEFINED_VK +#endif +#ifndef VK_F4 +# define VK_F4 UNDEFINED_VK +#endif +#ifndef VK_F5 +# define VK_F5 UNDEFINED_VK +#endif +#ifndef VK_F6 +# define VK_F6 UNDEFINED_VK +#endif +#ifndef VK_F7 +# define VK_F7 UNDEFINED_VK +#endif +#ifndef VK_F8 +# define VK_F8 UNDEFINED_VK +#endif +#ifndef VK_F9 +# define VK_F9 UNDEFINED_VK +#endif +#ifndef VK_F10 +# define VK_F10 UNDEFINED_VK +#endif +#ifndef VK_F11 +# define VK_F11 UNDEFINED_VK +#endif +#ifndef VK_F12 +# define VK_F12 UNDEFINED_VK +#endif +#ifndef VK_F13 +# define VK_F13 UNDEFINED_VK +#endif +#ifndef VK_F14 +# define VK_F14 UNDEFINED_VK +#endif +#ifndef VK_F15 +# define VK_F15 UNDEFINED_VK +#endif +#ifndef VK_F16 +# define VK_F16 UNDEFINED_VK +#endif +#ifndef VK_F17 +# define VK_F17 UNDEFINED_VK +#endif +#ifndef VK_F18 +# define VK_F18 UNDEFINED_VK +#endif +#ifndef VK_F19 +# define VK_F19 UNDEFINED_VK +#endif +#ifndef VK_F20 +# define VK_F20 UNDEFINED_VK +#endif +#ifndef VK_F21 +# define VK_F21 UNDEFINED_VK +#endif +#ifndef VK_F22 +# define VK_F22 UNDEFINED_VK +#endif +#ifndef VK_F23 +# define VK_F23 UNDEFINED_VK +#endif +#ifndef VK_F24 +# define VK_F24 UNDEFINED_VK +#endif +#ifndef VK_NUMLOCK +# define VK_NUMLOCK UNDEFINED_VK +#endif +#ifndef VK_SCROLL +# define VK_SCROLL UNDEFINED_VK +#endif +#ifndef VK_OEM_NEC_EQUAL +# define VK_OEM_NEC_EQUAL UNDEFINED_VK +#endif +#ifndef VK_OEM_FJ_JISHO +# define VK_OEM_FJ_JISHO UNDEFINED_VK +#endif +#ifndef VK_OEM_FJ_MASSHOU +# define VK_OEM_FJ_MASSHOU UNDEFINED_VK +#endif +#ifndef VK_OEM_FJ_TOUROKU +# define VK_OEM_FJ_TOUROKU UNDEFINED_VK +#endif +#ifndef VK_OEM_FJ_LOYA +# define VK_OEM_FJ_LOYA UNDEFINED_VK +#endif +#ifndef VK_OEM_FJ_ROYA +# define VK_OEM_FJ_ROYA UNDEFINED_VK +#endif +#ifndef VK_LSHIFT +# define VK_LSHIFT UNDEFINED_VK +#endif +#ifndef VK_RSHIFT +# define VK_RSHIFT UNDEFINED_VK +#endif +#ifndef VK_LCONTROL +# define VK_LCONTROL UNDEFINED_VK +#endif +#ifndef VK_RCONTROL +# define VK_RCONTROL UNDEFINED_VK +#endif +#ifndef VK_LMENU +# define VK_LMENU UNDEFINED_VK +#endif +#ifndef VK_RMENU +# define VK_RMENU UNDEFINED_VK +#endif +#ifndef VK_BROWSER_BACK +# define VK_BROWSER_BACK UNDEFINED_VK +#endif +#ifndef VK_BROWSER_FORWARD +# define VK_BROWSER_FORWARD UNDEFINED_VK +#endif +#ifndef VK_BROWSER_REFRESH +# define VK_BROWSER_REFRESH UNDEFINED_VK +#endif +#ifndef VK_BROWSER_STOP +# define VK_BROWSER_STOP UNDEFINED_VK +#endif +#ifndef VK_BROWSER_SEARCH +# define VK_BROWSER_SEARCH UNDEFINED_VK +#endif +#ifndef VK_BROWSER_FAVORITES +# define VK_BROWSER_FAVORITES UNDEFINED_VK +#endif +#ifndef VK_BROWSER_HOME +# define VK_BROWSER_HOME UNDEFINED_VK +#endif +#ifndef VK_VOLUME_MUTE +# define VK_VOLUME_MUTE UNDEFINED_VK +#endif +#ifndef VK_VOLUME_DOWN +# define VK_VOLUME_DOWN UNDEFINED_VK +#endif +#ifndef VK_VOLUME_UP +# define VK_VOLUME_UP UNDEFINED_VK +#endif +#ifndef VK_MEDIA_NEXT_TRACK +# define VK_MEDIA_NEXT_TRACK UNDEFINED_VK +#endif +#ifndef VK_MEDIA_PREV_TRACK +# define VK_MEDIA_PREV_TRACK UNDEFINED_VK +#endif +#ifndef VK_MEDIA_STOP +# define VK_MEDIA_STOP UNDEFINED_VK +#endif +#ifndef VK_MEDIA_PLAY_PAUSE +# define VK_MEDIA_PLAY_PAUSE UNDEFINED_VK +#endif +#ifndef VK_LAUNCH_MAIL +# define VK_LAUNCH_MAIL UNDEFINED_VK +#endif +#ifndef VK_LAUNCH_MEDIA_SELECT +# define VK_LAUNCH_MEDIA_SELECT UNDEFINED_VK +#endif +#ifndef VK_LAUNCH_APP1 +# define VK_LAUNCH_APP1 UNDEFINED_VK +#endif +#ifndef VK_LAUNCH_APP2 +# define VK_LAUNCH_APP2 UNDEFINED_VK +#endif +#ifndef VK_OEM_1 +# define VK_OEM_1 UNDEFINED_VK +#endif +#ifndef VK_OEM_PLUS +# define VK_OEM_PLUS UNDEFINED_VK +#endif +#ifndef VK_OEM_COMMA +# define VK_OEM_COMMA UNDEFINED_VK +#endif +#ifndef VK_OEM_MINUS +# define VK_OEM_MINUS UNDEFINED_VK +#endif +#ifndef VK_OEM_PERIOD +# define VK_OEM_PERIOD UNDEFINED_VK +#endif +#ifndef VK_OEM_2 +# define VK_OEM_2 UNDEFINED_VK +#endif +#ifndef VK_OEM_3 +# define VK_OEM_3 UNDEFINED_VK +#endif +#ifndef VK_OEM_4 +# define VK_OEM_4 UNDEFINED_VK +#endif +#ifndef VK_OEM_5 +# define VK_OEM_5 UNDEFINED_VK +#endif +#ifndef VK_OEM_6 +# define VK_OEM_6 UNDEFINED_VK +#endif +#ifndef VK_OEM_7 +# define VK_OEM_7 UNDEFINED_VK +#endif +#ifndef VK_OEM_8 +# define VK_OEM_8 UNDEFINED_VK +#endif +#ifndef VK_OEM_AX +# define VK_OEM_AX UNDEFINED_VK +#endif +#ifndef VK_OEM_102 +# define VK_OEM_102 UNDEFINED_VK +#endif +#ifndef VK_ICO_HELP +# define VK_ICO_HELP UNDEFINED_VK +#endif +#ifndef VK_ICO_00 +# define VK_ICO_00 UNDEFINED_VK +#endif +#ifndef VK_PROCESSKEY +# define VK_PROCESSKEY UNDEFINED_VK +#endif +#ifndef VK_ICO_CLEAR +# define VK_ICO_CLEAR UNDEFINED_VK +#endif +#ifndef VK_PACKET +# define VK_PACKET UNDEFINED_VK +#endif +#ifndef VK_OEM_RESET +# define VK_OEM_RESET UNDEFINED_VK +#endif +#ifndef VK_OEM_JUMP +# define VK_OEM_JUMP UNDEFINED_VK +#endif +#ifndef VK_OEM_PA1 +# define VK_OEM_PA1 UNDEFINED_VK +#endif +#ifndef VK_OEM_PA2 +# define VK_OEM_PA2 UNDEFINED_VK +#endif +#ifndef VK_OEM_PA3 +# define VK_OEM_PA3 UNDEFINED_VK +#endif +#ifndef VK_OEM_WSCTRL +# define VK_OEM_WSCTRL UNDEFINED_VK +#endif +#ifndef VK_OEM_CUSEL +# define VK_OEM_CUSEL UNDEFINED_VK +#endif +#ifndef VK_OEM_ATTN +# define VK_OEM_ATTN UNDEFINED_VK +#endif +#ifndef VK_OEM_FINISH +# define VK_OEM_FINISH UNDEFINED_VK +#endif +#ifndef VK_OEM_COPY +# define VK_OEM_COPY UNDEFINED_VK +#endif +#ifndef VK_OEM_AUTO +# define VK_OEM_AUTO UNDEFINED_VK +#endif +#ifndef VK_OEM_ENLW +# define VK_OEM_ENLW UNDEFINED_VK +#endif +#ifndef VK_OEM_BACKTAB +# define VK_OEM_BACKTAB UNDEFINED_VK +#endif +#ifndef VK_ATTN +# define VK_ATTN UNDEFINED_VK +#endif +#ifndef VK_CRSEL +# define VK_CRSEL UNDEFINED_VK +#endif +#ifndef VK_EXSEL +# define VK_EXSEL UNDEFINED_VK +#endif +#ifndef VK_EREOF +# define VK_EREOF UNDEFINED_VK +#endif +#ifndef VK_PLAY +# define VK_PLAY UNDEFINED_VK +#endif +#ifndef VK_ZOOM +# define VK_ZOOM UNDEFINED_VK +#endif +#ifndef VK_NONAME +# define VK_NONAME UNDEFINED_VK +#endif +#ifndef VK_PA1 +# define VK_PA1 UNDEFINED_VK +#endif +#ifndef VK_OEM_CLEAR +# define VK_OEM_CLEAR UNDEFINED_VK +#endif +/* ANSI-C code produced by gperf version 3.1 */ +/* Command-line: gperf --ignore-case -L ANSI-C -E -C -P -p -j1 -i 1 -g -o -t -K ofs -N console_win32_vk -k'*' win32_vk.list */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 1 "win32_vk.list" + +struct vktable {short ofs; unsigned short vk;}; +static const struct vktable *console_win32_vk(const char *, size_t); +#line 5 "win32_vk.list" +struct vktable; +/* maximum key range = 245, duplicates = 0 */ + +#ifndef GPERF_DOWNCASE +#define GPERF_DOWNCASE 1 +static unsigned char gperf_downcase[256] = + { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255 + }; +#endif + +#ifndef GPERF_CASE_STRCMP +#define GPERF_CASE_STRCMP 1 +static int +gperf_case_strcmp (register const char *s1, register const char *s2) +{ + for (;;) + { + unsigned char c1 = gperf_downcase[(unsigned char)*s1++]; + unsigned char c2 = gperf_downcase[(unsigned char)*s2++]; + if (c1 != 0 && c1 == c2) + continue; + return (int)c1 - (int)c2; + } +} +#endif + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +hash (register const char *str, register size_t len) +{ + static const unsigned short asso_values[] = + { + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 51, 74, + 80, 116, 127, 124, 95, 140, 77, 53, 7, 3, + 257, 257, 257, 257, 257, 1, 11, 1, 55, 1, + 25, 84, 31, 33, 13, 16, 2, 28, 8, 1, + 6, 10, 1, 1, 3, 4, 45, 18, 73, 79, + 30, 257, 257, 257, 257, 5, 257, 1, 11, 1, + 55, 1, 25, 84, 31, 33, 13, 16, 2, 28, + 8, 1, 6, 10, 1, 1, 3, 4, 45, 18, + 73, 79, 30, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257 + }; + register unsigned int hval = (unsigned int)len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[18]]; + /*FALLTHROUGH*/ + case 18: + hval += asso_values[(unsigned char)str[17]]; + /*FALLTHROUGH*/ + case 17: + hval += asso_values[(unsigned char)str[16]]; + /*FALLTHROUGH*/ + case 16: + hval += asso_values[(unsigned char)str[15]]; + /*FALLTHROUGH*/ + case 15: + hval += asso_values[(unsigned char)str[14]]; + /*FALLTHROUGH*/ + case 14: + hval += asso_values[(unsigned char)str[13]]; + /*FALLTHROUGH*/ + case 13: + hval += asso_values[(unsigned char)str[12]]; + /*FALLTHROUGH*/ + case 12: + hval += asso_values[(unsigned char)str[11]]; + /*FALLTHROUGH*/ + case 11: + hval += asso_values[(unsigned char)str[10]]; + /*FALLTHROUGH*/ + case 10: + hval += asso_values[(unsigned char)str[9]]; + /*FALLTHROUGH*/ + case 9: + hval += asso_values[(unsigned char)str[8]]; + /*FALLTHROUGH*/ + case 8: + hval += asso_values[(unsigned char)str[7]]; + /*FALLTHROUGH*/ + case 7: + hval += asso_values[(unsigned char)str[6]]; + /*FALLTHROUGH*/ + case 6: + hval += asso_values[(unsigned char)str[5]]; + /*FALLTHROUGH*/ + case 5: + hval += asso_values[(unsigned char)str[4]]; + /*FALLTHROUGH*/ + case 4: + hval += asso_values[(unsigned char)str[3]]; + /*FALLTHROUGH*/ + case 3: + hval += asso_values[(unsigned char)str[2]+2]; + /*FALLTHROUGH*/ + case 2: + hval += asso_values[(unsigned char)str[1]]; + /*FALLTHROUGH*/ + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return (unsigned int)hval; +} + +struct stringpool_t + { + char stringpool_str12[sizeof("UP")]; + char stringpool_str13[sizeof("APPS")]; + char stringpool_str14[sizeof("CRSEL")]; + char stringpool_str15[sizeof("SPACE")]; + char stringpool_str16[sizeof("SCROLL")]; + char stringpool_str17[sizeof("ESCAPE")]; + char stringpool_str18[sizeof("CANCEL")]; + char stringpool_str19[sizeof("ACCEPT")]; + char stringpool_str20[sizeof("SEPARATOR")]; + char stringpool_str21[sizeof("SELECT")]; + char stringpool_str22[sizeof("CONTROL")]; + char stringpool_str23[sizeof("OEM_CLEAR")]; + char stringpool_str24[sizeof("OEM_RESET")]; + char stringpool_str25[sizeof("OEM_AUTO")]; + char stringpool_str26[sizeof("OEM_CUSEL")]; + char stringpool_str28[sizeof("KANA")]; + char stringpool_str29[sizeof("OEM_PLUS")]; + char stringpool_str30[sizeof("PRIOR")]; + char stringpool_str31[sizeof("OEM_ATTN")]; + char stringpool_str32[sizeof("PAUSE")]; + char stringpool_str33[sizeof("BACK")]; + char stringpool_str34[sizeof("PACKET")]; + char stringpool_str35[sizeof("RCONTROL")]; + char stringpool_str36[sizeof("LCONTROL")]; + char stringpool_str37[sizeof("END")]; + char stringpool_str38[sizeof("HOME")]; + char stringpool_str39[sizeof("PRINT")]; + char stringpool_str40[sizeof("NUMLOCK")]; + char stringpool_str41[sizeof("LEFT")]; + char stringpool_str42[sizeof("JUNJA")]; + char stringpool_str43[sizeof("MENU")]; + char stringpool_str44[sizeof("OEM_WSCTRL")]; + char stringpool_str45[sizeof("OEM_ENLW")]; + char stringpool_str46[sizeof("NEXT")]; + char stringpool_str47[sizeof("RWIN")]; + char stringpool_str48[sizeof("LWIN")]; + char stringpool_str49[sizeof("CAPITAL")]; + char stringpool_str50[sizeof("HELP")]; + char stringpool_str51[sizeof("NONAME")]; + char stringpool_str52[sizeof("RBUTTON")]; + char stringpool_str53[sizeof("LBUTTON")]; + char stringpool_str54[sizeof("OEM_NEC_EQUAL")]; + char stringpool_str56[sizeof("INSERT")]; + char stringpool_str57[sizeof("HANJA")]; + char stringpool_str60[sizeof("SNAPSHOT")]; + char stringpool_str61[sizeof("ATTN")]; + char stringpool_str62[sizeof("TAB")]; + char stringpool_str63[sizeof("OEM_BACKTAB")]; + char stringpool_str64[sizeof("ICO_CLEAR")]; + char stringpool_str65[sizeof("CONVERT")]; + char stringpool_str66[sizeof("RETURN")]; + char stringpool_str67[sizeof("OEM_JUMP")]; + char stringpool_str71[sizeof("BROWSER_STOP")]; + char stringpool_str72[sizeof("FINAL")]; + char stringpool_str73[sizeof("ZOOM")]; + char stringpool_str74[sizeof("KANJI")]; + char stringpool_str75[sizeof("DELETE")]; + char stringpool_str76[sizeof("OEM_COMMA")]; + char stringpool_str77[sizeof("SUBTRACT")]; + char stringpool_str79[sizeof("MBUTTON")]; + char stringpool_str80[sizeof("F9")]; + char stringpool_str81[sizeof("SHIFT")]; + char stringpool_str82[sizeof("RSHIFT")]; + char stringpool_str83[sizeof("LSHIFT")]; + char stringpool_str84[sizeof("ADD")]; + char stringpool_str85[sizeof("NONCONVERT")]; + char stringpool_str86[sizeof("EXSEL")]; + char stringpool_str87[sizeof("OEM_1")]; + char stringpool_str88[sizeof("OEM_AX")]; + char stringpool_str89[sizeof("BROWSER_BACK")]; + char stringpool_str90[sizeof("OEM_8")]; + char stringpool_str91[sizeof("OEM_MINUS")]; + char stringpool_str92[sizeof("PLAY")]; + char stringpool_str93[sizeof("OEM_2")]; + char stringpool_str94[sizeof("CLEAR")]; + char stringpool_str95[sizeof("OEM_FJ_TOUROKU")]; + char stringpool_str96[sizeof("OEM_PA1")]; + char stringpool_str97[sizeof("ICO_HELP")]; + char stringpool_str98[sizeof("BROWSER_SEARCH")]; + char stringpool_str99[sizeof("SLEEP")]; + char stringpool_str101[sizeof("F1")]; + char stringpool_str102[sizeof("OEM_PA2")]; + char stringpool_str103[sizeof("OEM_COPY")]; + char stringpool_str104[sizeof("F8")]; + char stringpool_str105[sizeof("F19")]; + char stringpool_str106[sizeof("RIGHT")]; + char stringpool_str107[sizeof("F2")]; + char stringpool_str108[sizeof("OEM_6")]; + char stringpool_str109[sizeof("F18")]; + char stringpool_str111[sizeof("VOLUME_UP")]; + char stringpool_str114[sizeof("MEDIA_STOP")]; + char stringpool_str115[sizeof("OEM_PERIOD")]; + char stringpool_str117[sizeof("EREOF")]; + char stringpool_str121[sizeof("BROWSER_HOME")]; + char stringpool_str122[sizeof("F6")]; + char stringpool_str124[sizeof("BROWSER_REFRESH")]; + char stringpool_str126[sizeof("PA1")]; + char stringpool_str127[sizeof("PROCESSKEY")]; + char stringpool_str128[sizeof("DECIMAL")]; + char stringpool_str129[sizeof("OEM_3")]; + char stringpool_str130[sizeof("RMENU")]; + char stringpool_str131[sizeof("LMENU")]; + char stringpool_str132[sizeof("OEM_FJ_MASSHOU")]; + char stringpool_str133[sizeof("NUMPAD0")]; + char stringpool_str134[sizeof("HANGUL")]; + char stringpool_str135[sizeof("NUMPAD9")]; + char stringpool_str136[sizeof("HANGEUL")]; + char stringpool_str137[sizeof("OEM_5")]; + char stringpool_str138[sizeof("OEM_PA3")]; + char stringpool_str139[sizeof("VOLUME_MUTE")]; + char stringpool_str140[sizeof("OEM_4")]; + char stringpool_str141[sizeof("LAUNCH_MAIL")]; + char stringpool_str142[sizeof("OEM_FJ_JISHO")]; + char stringpool_str143[sizeof("F3")]; + char stringpool_str144[sizeof("OEM_FJ_ROYA")]; + char stringpool_str145[sizeof("OEM_FJ_LOYA")]; + char stringpool_str147[sizeof("DOWN")]; + char stringpool_str149[sizeof("OEM_FINISH")]; + char stringpool_str151[sizeof("F5")]; + char stringpool_str153[sizeof("OEM_7")]; + char stringpool_str154[sizeof("F4")]; + char stringpool_str155[sizeof("F17")]; + char stringpool_str156[sizeof("NUMPAD1")]; + char stringpool_str157[sizeof("ICO_00")]; + char stringpool_str159[sizeof("NUMPAD8")]; + char stringpool_str162[sizeof("NUMPAD2")]; + char stringpool_str164[sizeof("LAUNCH_APP1")]; + char stringpool_str165[sizeof("BROWSER_FORWARD")]; + char stringpool_str167[sizeof("F7")]; + char stringpool_str170[sizeof("LAUNCH_APP2")]; + char stringpool_str171[sizeof("MULTIPLY")]; + char stringpool_str174[sizeof("EXECUTE")]; + char stringpool_str176[sizeof("BROWSER_FAVORITES")]; + char stringpool_str177[sizeof("NUMPAD6")]; + char stringpool_str179[sizeof("F16")]; + char stringpool_str182[sizeof("F10")]; + char stringpool_str185[sizeof("VOLUME_DOWN")]; + char stringpool_str188[sizeof("F20")]; + char stringpool_str189[sizeof("MEDIA_PREV_TRACK")]; + char stringpool_str191[sizeof("MODECHANGE")]; + char stringpool_str197[sizeof("F14")]; + char stringpool_str198[sizeof("NUMPAD3")]; + char stringpool_str199[sizeof("XBUTTON1")]; + char stringpool_str203[sizeof("F24")]; + char stringpool_str205[sizeof("XBUTTON2")]; + char stringpool_str206[sizeof("NUMPAD5")]; + char stringpool_str209[sizeof("NUMPAD4")]; + char stringpool_str215[sizeof("MEDIA_PLAY_PAUSE")]; + char stringpool_str217[sizeof("LAUNCH_MEDIA_SELECT")]; + char stringpool_str218[sizeof("F11")]; + char stringpool_str220[sizeof("OEM_102")]; + char stringpool_str221[sizeof("MEDIA_NEXT_TRACK")]; + char stringpool_str222[sizeof("NUMPAD7")]; + char stringpool_str224[sizeof("F21")]; + char stringpool_str226[sizeof("F13")]; + char stringpool_str229[sizeof("F12")]; + char stringpool_str232[sizeof("F23")]; + char stringpool_str235[sizeof("F22")]; + char stringpool_str242[sizeof("F15")]; + char stringpool_str256[sizeof("DIVIDE")]; + }; +static const struct stringpool_t stringpool_contents = + { + "UP", + "APPS", + "CRSEL", + "SPACE", + "SCROLL", + "ESCAPE", + "CANCEL", + "ACCEPT", + "SEPARATOR", + "SELECT", + "CONTROL", + "OEM_CLEAR", + "OEM_RESET", + "OEM_AUTO", + "OEM_CUSEL", + "KANA", + "OEM_PLUS", + "PRIOR", + "OEM_ATTN", + "PAUSE", + "BACK", + "PACKET", + "RCONTROL", + "LCONTROL", + "END", + "HOME", + "PRINT", + "NUMLOCK", + "LEFT", + "JUNJA", + "MENU", + "OEM_WSCTRL", + "OEM_ENLW", + "NEXT", + "RWIN", + "LWIN", + "CAPITAL", + "HELP", + "NONAME", + "RBUTTON", + "LBUTTON", + "OEM_NEC_EQUAL", + "INSERT", + "HANJA", + "SNAPSHOT", + "ATTN", + "TAB", + "OEM_BACKTAB", + "ICO_CLEAR", + "CONVERT", + "RETURN", + "OEM_JUMP", + "BROWSER_STOP", + "FINAL", + "ZOOM", + "KANJI", + "DELETE", + "OEM_COMMA", + "SUBTRACT", + "MBUTTON", + "F9", + "SHIFT", + "RSHIFT", + "LSHIFT", + "ADD", + "NONCONVERT", + "EXSEL", + "OEM_1", + "OEM_AX", + "BROWSER_BACK", + "OEM_8", + "OEM_MINUS", + "PLAY", + "OEM_2", + "CLEAR", + "OEM_FJ_TOUROKU", + "OEM_PA1", + "ICO_HELP", + "BROWSER_SEARCH", + "SLEEP", + "F1", + "OEM_PA2", + "OEM_COPY", + "F8", + "F19", + "RIGHT", + "F2", + "OEM_6", + "F18", + "VOLUME_UP", + "MEDIA_STOP", + "OEM_PERIOD", + "EREOF", + "BROWSER_HOME", + "F6", + "BROWSER_REFRESH", + "PA1", + "PROCESSKEY", + "DECIMAL", + "OEM_3", + "RMENU", + "LMENU", + "OEM_FJ_MASSHOU", + "NUMPAD0", + "HANGUL", + "NUMPAD9", + "HANGEUL", + "OEM_5", + "OEM_PA3", + "VOLUME_MUTE", + "OEM_4", + "LAUNCH_MAIL", + "OEM_FJ_JISHO", + "F3", + "OEM_FJ_ROYA", + "OEM_FJ_LOYA", + "DOWN", + "OEM_FINISH", + "F5", + "OEM_7", + "F4", + "F17", + "NUMPAD1", + "ICO_00", + "NUMPAD8", + "NUMPAD2", + "LAUNCH_APP1", + "BROWSER_FORWARD", + "F7", + "LAUNCH_APP2", + "MULTIPLY", + "EXECUTE", + "BROWSER_FAVORITES", + "NUMPAD6", + "F16", + "F10", + "VOLUME_DOWN", + "F20", + "MEDIA_PREV_TRACK", + "MODECHANGE", + "F14", + "NUMPAD3", + "XBUTTON1", + "F24", + "XBUTTON2", + "NUMPAD5", + "NUMPAD4", + "MEDIA_PLAY_PAUSE", + "LAUNCH_MEDIA_SELECT", + "F11", + "OEM_102", + "MEDIA_NEXT_TRACK", + "NUMPAD7", + "F21", + "F13", + "F12", + "F23", + "F22", + "F15", + "DIVIDE" + }; +#define stringpool ((const char *) &stringpool_contents) +const struct vktable * +console_win32_vk (register const char *str, register size_t len) +{ + enum + { + TOTAL_KEYWORDS = 160, + MIN_WORD_LENGTH = 2, + MAX_WORD_LENGTH = 19, + MIN_HASH_VALUE = 12, + MAX_HASH_VALUE = 256 + }; + + static const struct vktable wordlist[] = + { + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 40 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str12, VK_UP}, +#line 52 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str13, VK_APPS}, +#line 159 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str14, VK_CRSEL}, +#line 34 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str15, VK_SPACE}, +#line 95 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str16, VK_SCROLL}, +#line 29 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str17, VK_ESCAPE}, +#line 9 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str18, VK_CANCEL}, +#line 32 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str19, VK_ACCEPT}, +#line 66 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str20, VK_SEPARATOR}, +#line 43 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str21, VK_SELECT}, +#line 18 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str22, VK_CONTROL}, +#line 166 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str23, VK_OEM_CLEAR}, +#line 145 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str24, VK_OEM_RESET}, +#line 155 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str25, VK_OEM_AUTO}, +#line 151 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str26, VK_OEM_CUSEL}, + {-1}, +#line 22 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str28, VK_KANA}, +#line 127 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str29, VK_OEM_PLUS}, +#line 35 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str30, VK_PRIOR}, +#line 152 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str31, VK_OEM_ATTN}, +#line 20 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str32, VK_PAUSE}, +#line 13 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str33, VK_BACK}, +#line 144 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str34, VK_PACKET}, +#line 105 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str35, VK_RCONTROL}, +#line 104 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str36, VK_LCONTROL}, +#line 37 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str37, VK_END}, +#line 38 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str38, VK_HOME}, +#line 44 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str39, VK_PRINT}, +#line 94 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str40, VK_NUMLOCK}, +#line 39 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str41, VK_LEFT}, +#line 25 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str42, VK_JUNJA}, +#line 19 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str43, VK_MENU}, +#line 150 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str44, VK_OEM_WSCTRL}, +#line 156 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str45, VK_OEM_ENLW}, +#line 36 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str46, VK_NEXT}, +#line 51 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str47, VK_RWIN}, +#line 50 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str48, VK_LWIN}, +#line 21 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str49, VK_CAPITAL}, +#line 49 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str50, VK_HELP}, +#line 164 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str51, VK_NONAME}, +#line 8 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str52, VK_RBUTTON}, +#line 7 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str53, VK_LBUTTON}, +#line 96 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str54, VK_OEM_NEC_EQUAL}, + {-1}, +#line 47 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str56, VK_INSERT}, +#line 27 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str57, VK_HANJA}, + {-1}, {-1}, +#line 46 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str60, VK_SNAPSHOT}, +#line 158 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str61, VK_ATTN}, +#line 14 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str62, VK_TAB}, +#line 157 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str63, VK_OEM_BACKTAB}, +#line 143 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str64, VK_ICO_CLEAR}, +#line 30 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str65, VK_CONVERT}, +#line 16 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str66, VK_RETURN}, +#line 146 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str67, VK_OEM_JUMP}, + {-1}, {-1}, {-1}, +#line 111 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str71, VK_BROWSER_STOP}, +#line 26 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str72, VK_FINAL}, +#line 163 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str73, VK_ZOOM}, +#line 28 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str74, VK_KANJI}, +#line 48 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str75, VK_DELETE}, +#line 128 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str76, VK_OEM_COMMA}, +#line 67 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str77, VK_SUBTRACT}, + {-1}, +#line 10 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str79, VK_MBUTTON}, +#line 78 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str80, VK_F9}, +#line 17 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str81, VK_SHIFT}, +#line 103 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str82, VK_RSHIFT}, +#line 102 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str83, VK_LSHIFT}, +#line 65 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str84, VK_ADD}, +#line 31 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str85, VK_NONCONVERT}, +#line 160 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str86, VK_EXSEL}, +#line 126 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str87, VK_OEM_1}, +#line 138 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str88, VK_OEM_AX}, +#line 108 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str89, VK_BROWSER_BACK}, +#line 137 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str90, VK_OEM_8}, +#line 129 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str91, VK_OEM_MINUS}, +#line 162 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str92, VK_PLAY}, +#line 131 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str93, VK_OEM_2}, +#line 15 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str94, VK_CLEAR}, +#line 99 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str95, VK_OEM_FJ_TOUROKU}, +#line 147 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str96, VK_OEM_PA1}, +#line 140 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str97, VK_ICO_HELP}, +#line 112 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str98, VK_BROWSER_SEARCH}, +#line 53 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str99, VK_SLEEP}, + {-1}, +#line 70 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str101, VK_F1}, +#line 148 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str102, VK_OEM_PA2}, +#line 154 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str103, VK_OEM_COPY}, +#line 77 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str104, VK_F8}, +#line 88 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str105, VK_F19}, +#line 41 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str106, VK_RIGHT}, +#line 71 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str107, VK_F2}, +#line 135 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str108, VK_OEM_6}, +#line 87 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str109, VK_F18}, + {-1}, +#line 117 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str111, VK_VOLUME_UP}, + {-1}, {-1}, +#line 120 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str114, VK_MEDIA_STOP}, +#line 130 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str115, VK_OEM_PERIOD}, + {-1}, +#line 161 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str117, VK_EREOF}, + {-1}, {-1}, {-1}, +#line 114 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str121, VK_BROWSER_HOME}, +#line 75 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str122, VK_F6}, + {-1}, +#line 110 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str124, VK_BROWSER_REFRESH}, + {-1}, +#line 165 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str126, VK_PA1}, +#line 142 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str127, VK_PROCESSKEY}, +#line 68 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str128, VK_DECIMAL}, +#line 132 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str129, VK_OEM_3}, +#line 107 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str130, VK_RMENU}, +#line 106 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str131, VK_LMENU}, +#line 98 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str132, VK_OEM_FJ_MASSHOU}, +#line 54 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str133, VK_NUMPAD0}, +#line 24 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str134, VK_HANGUL}, +#line 63 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str135, VK_NUMPAD9}, +#line 23 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str136, VK_HANGEUL}, +#line 134 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str137, VK_OEM_5}, +#line 149 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str138, VK_OEM_PA3}, +#line 115 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str139, VK_VOLUME_MUTE}, +#line 133 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str140, VK_OEM_4}, +#line 122 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str141, VK_LAUNCH_MAIL}, +#line 97 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str142, VK_OEM_FJ_JISHO}, +#line 72 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str143, VK_F3}, +#line 101 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str144, VK_OEM_FJ_ROYA}, +#line 100 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str145, VK_OEM_FJ_LOYA}, + {-1}, +#line 42 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str147, VK_DOWN}, + {-1}, +#line 153 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str149, VK_OEM_FINISH}, + {-1}, +#line 74 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str151, VK_F5}, + {-1}, +#line 136 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str153, VK_OEM_7}, +#line 73 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str154, VK_F4}, +#line 86 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str155, VK_F17}, +#line 55 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str156, VK_NUMPAD1}, +#line 141 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str157, VK_ICO_00}, + {-1}, +#line 62 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str159, VK_NUMPAD8}, + {-1}, {-1}, +#line 56 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str162, VK_NUMPAD2}, + {-1}, +#line 124 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str164, VK_LAUNCH_APP1}, +#line 109 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str165, VK_BROWSER_FORWARD}, + {-1}, +#line 76 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str167, VK_F7}, + {-1}, {-1}, +#line 125 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str170, VK_LAUNCH_APP2}, +#line 64 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str171, VK_MULTIPLY}, + {-1}, {-1}, +#line 45 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str174, VK_EXECUTE}, + {-1}, +#line 113 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str176, VK_BROWSER_FAVORITES}, +#line 60 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str177, VK_NUMPAD6}, + {-1}, +#line 85 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str179, VK_F16}, + {-1}, {-1}, +#line 79 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str182, VK_F10}, + {-1}, {-1}, +#line 116 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str185, VK_VOLUME_DOWN}, + {-1}, {-1}, +#line 89 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str188, VK_F20}, +#line 119 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str189, VK_MEDIA_PREV_TRACK}, + {-1}, +#line 33 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str191, VK_MODECHANGE}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 83 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str197, VK_F14}, +#line 57 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str198, VK_NUMPAD3}, +#line 11 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str199, VK_XBUTTON1}, + {-1}, {-1}, {-1}, +#line 93 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str203, VK_F24}, + {-1}, +#line 12 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str205, VK_XBUTTON2}, +#line 59 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str206, VK_NUMPAD5}, + {-1}, {-1}, +#line 58 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str209, VK_NUMPAD4}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 121 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str215, VK_MEDIA_PLAY_PAUSE}, + {-1}, +#line 123 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str217, VK_LAUNCH_MEDIA_SELECT}, +#line 80 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str218, VK_F11}, + {-1}, +#line 139 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str220, VK_OEM_102}, +#line 118 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str221, VK_MEDIA_NEXT_TRACK}, +#line 61 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str222, VK_NUMPAD7}, + {-1}, +#line 90 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str224, VK_F21}, + {-1}, +#line 82 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str226, VK_F13}, + {-1}, {-1}, +#line 81 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str229, VK_F12}, + {-1}, {-1}, +#line 92 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str232, VK_F23}, + {-1}, {-1}, +#line 91 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str235, VK_F22}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 84 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str242, VK_F15}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, +#line 69 "win32_vk.list" + {(int)(size_t)&((struct stringpool_t *)0)->stringpool_str256, VK_DIVIDE} + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register unsigned int key = hash (str, len); + + if (key <= MAX_HASH_VALUE) + { + register int o = wordlist[key].ofs; + if (o >= 0) + { + register const char *s = o + stringpool; + + if ((((unsigned char)*str ^ (unsigned char)*s) & ~32) == 0 && !gperf_case_strcmp (str, s)) + return &wordlist[key]; + } + } + } + return 0; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/lib/io/console.so b/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/lib/io/console.so new file mode 100755 index 00000000..aa2893c4 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/lib/io/console.so differ diff --git a/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/lib/io/console/size.rb b/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/lib/io/console/size.rb new file mode 100644 index 00000000..14b9a74b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/io-console-0.8.0/lib/io/console/size.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: false +# fallback to console window size +def IO.default_console_size + [ + ENV["LINES"].to_i.nonzero? || 25, + ENV["COLUMNS"].to_i.nonzero? || 80, + ] +end + +begin + require 'io/console' +rescue LoadError + class << IO + alias console_size default_console_size + end +else + # returns console window size + def IO.console_size + console.winsize + rescue NoMethodError + default_console_size + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/Gemfile b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/Gemfile new file mode 100644 index 00000000..b4e8955a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/Gemfile @@ -0,0 +1,29 @@ +source "https://rubygems.org" + +gemspec + +is_unix = RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i +is_truffleruby = RUBY_DESCRIPTION =~ /truffleruby/ + +if is_unix && ENV['WITH_VTERM'] + gem "vterm", github: "ruby/vterm-gem" + gem "yamatanooroti", github: "ruby/yamatanooroti" +end + +gem "stackprof" if is_unix && !is_truffleruby + +gem "reline", github: "ruby/reline" if ENV["WITH_LATEST_RELINE"] == "true" +gem "rake" +gem "test-unit" +gem "test-unit-ruby-core" + +gem "rubocop" + +gem "tracer" if !is_truffleruby +gem "debug", github: "ruby/debug", platforms: [:mri, :mswin] + +gem "rdoc", ">= 6.11.0" + +if RUBY_VERSION >= "3.0.0" && !is_truffleruby + gem "repl_type_completor" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/LICENSE.txt b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/LICENSE.txt new file mode 100644 index 00000000..66d93598 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/README.md b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/README.md new file mode 100644 index 00000000..b08ba26c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/README.md @@ -0,0 +1,125 @@ +# IRB + +[![Gem Version](https://badge.fury.io/rb/irb.svg)](https://badge.fury.io/rb/irb) +[![Static Badge](https://img.shields.io/badge/RDoc-flat?style=flat&label=documentation&link=https%3A%2F%2Fruby.github.io%2Firb%2F)](https://ruby.github.io/irb/) +[![build](https://github.com/ruby/irb/actions/workflows/test.yml/badge.svg)](https://github.com/ruby/irb/actions/workflows/test.yml) + + +IRB stands for "interactive Ruby" and is a tool to interactively execute Ruby expressions read from the standard input. + +The `irb` command from your shell will start the interpreter. + +## Installation + +> [!Note] +> +> IRB is a default gem of Ruby so you shouldn't need to install it separately. +> +> But if you're using Ruby 2.6 or later and want to upgrade/install a specific version of IRB, please follow these steps. + +To install it with `bundler`, add this line to your application's Gemfile: + +```ruby +gem 'irb' +``` + +And then execute: + +```shell +$ bundle +``` + +Or install it directly with: + +```shell +$ gem install irb +``` + +## Usage + +> [!Note] +> +> We're working hard to match Pry's variety of powerful features in IRB, and you can track our progress or find contribution ideas in [this document](https://ruby.github.io/irb/COMPARED_WITH_PRY_md.html). + +### The `irb` Executable + +You can start a fresh IRB session by typing `irb` in your terminal. + +In the session, you can evaluate Ruby expressions or even prototype a small Ruby script. An input is executed when it is syntactically complete. + +```shell +$ irb +irb(main):001> 1 + 2 +=> 3 +irb(main):002* class Foo +irb(main):003* def foo +irb(main):004* puts 1 +irb(main):005* end +irb(main):006> end +=> :foo +irb(main):007> Foo.new.foo +1 +=> nil +``` + +### The `binding.irb` Breakpoint + +If you use Ruby 2.5 or later versions, you can also use `binding.irb` in your program as breakpoints. + +Once a `binding.irb` is evaluated, a new IRB session will be started with the surrounding context: + +```shell +$ ruby test.rb + +From: test.rb @ line 2 : + + 1: def greet(word) + => 2: binding.irb + 3: puts "Hello #{word}" + 4: end + 5: + 6: greet("World") + +irb(main):001:0> word +=> "World" +irb(main):002:0> exit +Hello World +``` + +### Debugging + +You can use IRB as a debugging console with `debug.gem` with these options: + +- In `binding.irb`, use the `debug` command to start an `irb:rdbg` session with access to all `debug.gem` commands. +- Use the `RUBY_DEBUG_IRB_CONSOLE=1` environment variable to make `debug.gem` use IRB as the debugging console. + +To learn more about debugging with IRB, see [Debugging with IRB](https://ruby.github.io/irb/#label-Debugging+with+IRB). + +## Documentation + +https://ruby.github.io/irb/ provides a comprehensive guide to IRB's features and usage. + +## Configuration + +See the [Configuration page](https://ruby.github.io/irb/Configurations_md.html) in the documentation. + +## Extending IRB + +IRB `v1.13.0` and later versions allows users/libraries to extend its functionality through official APIs. + +For more information, please visit the [IRB Extension Guide](https://ruby.github.io/irb/EXTEND_IRB_md.html). + +## Contributing + +See [CONTRIBUTING.md](./CONTRIBUTING.md) for more information. + +## Releasing + +``` +rake release +gh release create vX.Y.Z --generate-notes +``` + +## License + +The gem is available as open source under the terms of the [2-Clause BSD License](https://opensource.org/licenses/BSD-2-Clause). diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/Rakefile b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/Rakefile new file mode 100644 index 00000000..e956107a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/Rakefile @@ -0,0 +1,52 @@ +require "bundler/gem_tasks" +require "rake/testtask" +require "rdoc/task" + +Rake::TestTask.new(:test) do |t| + t.libs << "test" << "test/lib" + t.libs << "lib" + t.ruby_opts << "-rhelper" + t.test_files = FileList["test/irb/**/test_*.rb"] +end + +# To make sure they have been correctly setup for Ruby CI. +desc "Run each irb test file in isolation." +task :test_in_isolation do + failed = false + + FileList["test/irb/**/test_*.rb"].each do |test_file| + ENV["TEST"] = test_file + begin + Rake::Task["test"].execute + rescue + failed = true + msg = "Test '#{test_file}' failed when being executed in isolation. Please make sure 'rake test TEST=#{test_file}' passes." + separation_line = '=' * msg.length + + puts <<~MSG + #{separation_line} + #{msg} + #{separation_line} + MSG + end + end + + fail "Some tests failed when being executed in isolation" if failed +end + +Rake::TestTask.new(:test_yamatanooroti) do |t| + t.libs << 'test' << "test/lib" + t.libs << 'lib' + #t.loader = :direct + t.ruby_opts << "-rhelper" + t.pattern = 'test/irb/yamatanooroti/test_*.rb' +end + +task :default => :test + +RDoc::Task.new do |rdoc| + rdoc.title = "IRB Documentation" + rdoc.main = "Index.md" + rdoc.rdoc_dir = "_site" + rdoc.options.push("lib") +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/bin/console b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/bin/console new file mode 100755 index 00000000..4405b232 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/bin/console @@ -0,0 +1,6 @@ +#!/usr/bin/env ruby + +require "bundler/setup" +require_relative "../lib/irb" + +IRB.start(__FILE__) diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/bin/setup b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/bin/setup new file mode 100755 index 00000000..cf4ad25e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/bin/setup @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +set -euo pipefail +IFS=$'\n\t' +set -vx + +bundle install diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/doc/irb/irb-tools.rd.ja b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/doc/irb/irb-tools.rd.ja new file mode 100644 index 00000000..b997f0ed --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/doc/irb/irb-tools.rd.ja @@ -0,0 +1,184 @@ +irb関連おまけコマンドとライブラリ + $Release Version: 0.7.1 $ + $Revision$ + by Keiju ISHITSUKA(Nihon Rational Co.,Ltd.) + +=begin + +:コマンド: +* rtags -- ruby tags command + +:関数ライブラリ: +* xmp -- irb version of gotoken xmp-function + +:クラスライブラリ: +* frame.rb -- frame tracer +* completion.rb -- irb completor + += rtags + +rtagsはemacs及びvi用の, TAGファイルをつくるコマンドです. + +== 使い方 + + rtags [-vi] file.... + +カレントディレクトリにemacs用のTAGSファイルができます. -viオプションを +つけた時にはvi用のtagsファイルを作成します. + +emacsの場合, 通常のetags.elがそのまま使えます. 検索可能なのは, + +* クラス +* メソッド +* 特異メソッド +* alias +* attrで宣言されたアクセサ(パラメータがシンボルか文字列リテラルに限る) +* attr_XXXで宣言されたアクセサ(パラメータがシンボルか文字列リテラルに限る) + +です. + +Cなどで使っているのと違うのは, コンプリーションに関する部分で, + +関数名は, + + 関数名( + +クラスは, + + ::クラス名::....::クラス名 + +メソッドは, + + ::クラス名::....::クラス名#メソッド名 + +特異メソッド(クラスメソッド)は + + ::クラス名::....::クラス名.メソッド名 + +でコンプリーションを行なうところです. + += xmp.rb + +ごとけんxmpの上位互換バージョンです. ただ, 非常に重いのでごとけんxmpで +は対応できない時に, 使用すると良いでしょう. + +== 使い方 + +=== 関数として使う. + + require "irb/xmp" + xmp <1 + foo + ==>1 + +=== XMPインスタンスを用いる. + +この場合は, XMPがコンテキスト情報を持つので, 変数の値などを保持してい +ます. + + require "irb/xmp" + xmp = XMP.new + xmp.puts <1 + foo + ==>1 + foo + ==>1 + +== コンテキストに関して + +XMPメソッド群のコンテキストは, 呼び出す前のコンテキストで評価されます. +明示的にコンテキストを指定するとそのコンテキストで評価します. + +例: + + xmp "foo", an_binding + +:注: +マルチスレッドには対応していません. + += frame.rb +現在実行中のフレーム情報を取り扱うためのクラスです. + +* IRB::Frame.top(n = 0) + 上からn番目のコンテキストを取り出します. nは0が最上位になります. +* IRB::Frame.bottom(n = 0) + 下からn番目のコンテキストを取り出します. nは0が最下位になります. +* IRB::Frame.sender + センダになっているオブジェクトを取り出します. センダとは, そのメソッ + ドを呼び出した側のselfのことです. + +:注: +set_trace_funcを用いてRubyの実行をトレースしています. マルチスレッドに +は対応していません. + += completion.rb +irbのcompletion機能を提供するものです. + +== 使い方 + + % irb -r irb/completion + +とするか, ~/.irbrc 中に + + require "irb/completion" + +を入れてください. irb実行中に require "irb/completion" してもよいです. + +irb実行中に (TAB) を押すとコンプレーションします. + +トップレベルで(TAB)を押すとすべての構文要素, クラス, メソッドの候補がで +ます. 候補が唯一ならば完全に補完します. + + irb(main):001:0> in + in inspect instance_eval + include install_alias_method instance_of? + initialize install_aliases instance_variables + irb(main):001:0> inspect + "main" + irb(main):002:0> foo = Object.new + # + + ((|変数名.|))の後に(TAB)を押すと, そのオブジェクトのメソッド一覧がでま + す. + + irb(main):003:0> foo. + foo.== foo.frozen? foo.protected_methods + foo.=== foo.hash foo.public_methods + foo.=~ foo.id foo.respond_to? + foo.__id__ foo.inspect foo.send + foo.__send__ foo.instance_eval foo.singleton_methods + foo.class foo.instance_of? foo.taint + foo.clone foo.instance_variables foo.tainted? + foo.display foo.is_a? foo.to_a + foo.dup foo.kind_of? foo.to_s + foo.eql? foo.method foo.type + foo.equal? foo.methods foo.untaint + foo.extend foo.nil? + foo.freeze foo.private_methods + +=end + +% Begin Emacs Environment +% Local Variables: +% mode: text +% comment-column: 0 +% comment-start: "%" +% comment-end: "\n" +% End: +% + diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/doc/irb/irb.rd.ja b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/doc/irb/irb.rd.ja new file mode 100644 index 00000000..c51e0bd6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/doc/irb/irb.rd.ja @@ -0,0 +1,425 @@ +irb -- interactive ruby + $Release Version: 0.9.5 $ + $Revision$ + by Keiju ISHITSUKA(keiju@ruby-lang.org) +=begin += irbとは? + +irbはinteractive rubyの略です. rubyの式を標準入力から簡単に入力/実行する +ためのツールです. + += 起動 + + % irb + +で行ないます. + += 使い方 + +irbの使い方は, Rubyさえ知っていればいたって簡単です. 基本的には irb と +いうコマンドを実行するだけです. irbを実行すると, 以下のようなプロンプ +トが表れてきます. 後は, rubyの式を入れて下さい. 式が完結した時点で実行 +されます. + + dim% irb + irb(main):001:0> 1+2 + 3 + irb(main):002:0> class Foo + irb(main):003:1> def foo + irb(main):004:2> print 1 + irb(main):005:2> end + irb(main):006:1> end + nil + irb(main):007:0> + +また, irbはReadlineモジュールにも対応しています. Readlineモジュールが +インストールされている時には, それを使うのが標準の動作になります. + += コマンドオプション + + irb.rb [options] file_name opts + options: + -f ~/.irbrc を読み込まない. + -d $DEBUG をtrueにする(ruby -d と同じ) + -r load-module ruby -r と同じ. + -I path $LOAD_PATH に path を追加する. + -U ruby -U と同じ. + -E enc ruby -E と同じ. + -w ruby -w と同じ. + -W[level=2] ruby -W と同じ. + --context-mode n 新しいワークスペースを作成した時に関連する Binding + オブジェクトの作成方法を 0 から 3 のいずれかに設定する. + --echo 実行結果を表示する(デフォルト). + --noecho 実行結果を表示しない. + --echo-on-assignment + 代入時に実行結果を表示する. + --noecho-on-assignment + 代入時に実行結果を表示しない. + --truncate-echo-on-assignment + 代入時に省略された実行結果を表示する(デフォルト). + --inspect 結果出力にinspectを用いる. + --noinspect 結果出力にinspectを用いない. + --singleline シングルラインエディタを利用する. + --nosingleline シングルラインエディタを利用しない. デフォルトの動 + 作は, inf-ruby-mode以外でシングルラインエディタを利 + 用しようとする. + --colorize 色付けを利用する. + --nocolorize 色付けを利用しない. + --autocomplete オートコンプリートを利用する. + --noautocomplete オートコンプリートを利用しない. + --prompt prompt-mode + --prompt-mode prompt-mode + プロンプトモードを切替えます. 現在定義されているプ + ロンプトモードは, default, simple, xmp, inf-rubyが + 用意されています. + --inf-ruby-mode emacsのinf-ruby-mode用のプロンプト表示を行なう. 特 + に指定がない限り, ラインエディタは使わなくなる. + --simple-prompt + 非常にシンプルなプロンプトを用いるモードです. + --noprompt プロンプト表示を行なわない. + --single-irb irb 中で self を実行して得られるオブジェクトをサ + ブ irb と共有する. + --tracer コマンド実行時にトレースを行なう. + --back-trace-limit n + バックトレース表示をバックトレースの頭から n, 後ろ + からnだけ行なう. デフォルトは16 + + --verbose 詳細なメッセージを出力する. + --noverbose 詳細なメッセージを出力しない(デフォルト). + -v, --version irbのバージョンを表示する. + -h, --help irb のヘルプを表示する. + -- 以降のコマンドライン引数をオプションとして扱わない. + += コンフィギュレーション + +irb起動時に``~/.irbrc''を読み込みます. もし存在しない場合は, +``.irbrc'', ``irb.rc'', ``_irbrc'', ``$irbrc''の順にloadを試みます. + +オプションを設定する代わりに, 以下のコマンドでもデフォルトの動作を設定 +できます. + + IRB.conf[:IRB_NAME]="irb" + IRB.conf[:USE_TRACER]=false + IRB.conf[:USE_LOADER]=false + IRB.conf[:IGNORE_SIGINT]=true + IRB.conf[:IGNORE_EOF]=false + IRB.conf[:INSPECT_MODE]=nil + IRB.conf[:IRB_RC] = nil + IRB.conf[:BACK_TRACE_LIMIT]=16 + IRB.conf[:USE_LOADER] = false + IRB.conf[:USE_SINGLELINE] = nil + IRB.conf[:USE_TRACER] = false + IRB.conf[:IGNORE_SIGINT] = true + IRB.conf[:IGNORE_EOF] = false + IRB.conf[:PROMPT_MODE] = :DEFAULT + IRB.conf[:PROMPT] = {...} + IRB.conf[:VERBOSE]=true + +== プロンプトの設定 + +プロンプトをカスタマイズしたい時には, + + IRB.conf[:PROMPT] + +を用います. 例えば, .irbrcの中で下のような式を記述します: + + IRB.conf[:PROMPT][:MY_PROMPT] = { # プロンプトモードの名前 + :PROMPT_I => nil, # 通常のプロンプト + :PROMPT_S => nil, # 文字列などの継続行のプロンプト + :PROMPT_C => nil, # 式が継続している時のプロンプト + :RETURN => " ==>%s\n" # リターン時のプロンプト + } + +プロンプトモードを指定したい時には, + + irb --prompt my-prompt + +でそのプロンプトモードで起動されます. または, .irbrcに下式を記述しても +OKです. + + IRB.conf[:PROMPT_MODE] = :MY_PROMPT + +PROMPT_I, PROMPT_S, PROMPT_Cは, フォーマットを指定します. + + %N 起動しているコマンド名が出力される. + %m mainオブジェクト(self)がto_sで出力される. + %M mainオブジェクト(self)がinspectされて出力される. + %l 文字列中のタイプを表す(", ', /, ], `]'は%wの中の時) + %NNi インデントのレベルを表す. NNは数字が入りprintfの%NNdと同じ. 省 + 略可能 + %NNn 行番号を表します. + %% % + +例えば, デフォルトのプロンプトモードは: + + IRB.conf[:PROMPT][:DEFAULT] = { + :PROMPT_I => "%N(%m):%03n:%i> ", + :PROMPT_S => "%N(%m):%03n:%i%l ", + :PROMPT_C => "%N(%m):%03n:%i* ", + :RETURN => "=> %s\n" + } + +となっています. + +RETURNは, 現在のところprintf形式です. 将来仕様が変わるかも知れません. + +== サブirbの設定 + +コマンドラインオプションおよびIRB.confは(サブ)irb起動時のデフォルトの +設定を決めるもので, `5. コマンド'にあるconfで個別の(サブ)irbの設定がで +きるようになっています. + +IRB.conf[:IRB_RC]にprocが設定されていると, サブirbを起動する時にその +procをirbのコンテキストを引数として呼び出します. これによって個別のサ +ブirbごとに設定を変えることができるようになります. + + += コマンド + +irb拡張コマンドは, 簡単な名前と頭に`irb_'をつけた名前と両方定義されて +います. これは, 簡単な名前がoverrideされた時のためです. + +--- exit, quit, irb_exit + 終了する. + サブirbの場合, そのサブirbを終了する. + +--- conf, irb_context + irbの現在の設定を表示する. 設定の変更は, confにメッセージを送るこ + とによって行なえる. + +--- conf.eval_history = N + 実行結果のヒストリ機能の設定. + nnは整数かnilで nn>0 であればその数だけヒストリにためる。nn==0の時は + 無制限に記憶する、nilだとヒストリ機能はやめる(デフォルト). + +--- Conf.back_trace_limit + バックトレース表示をバックトレースの頭からn, 後ろからnだけ行なう. + デフォルトは16 + +--- conf.ignore_eof = true/false + ^Dが入力された時の動作を設定する. trueの時は^Dを無視する, falseの + 時はirbを終了する. + +--- conf.ignore_sigint= true/false + ^Cが入力された時の動作を設定する. false時は, irbを終了する. trueの + 時の動作は以下のようになる: + 入力中: これまで入力したものをキャンセルしトップレベルに戻る. + 実行中: 実行を中止する. + +--- conf.inf_ruby_mode = true/false + inf-ruby-mode用のプロンプト表示を行なう. デフォルトはfalse. 特に指定 + がない限り, ラインエディタは使わなくなる. + +--- conf.inspect_mode = true/false/nil + インスペクトモードを設定する. + true: インスペクトして表示する. + false: 通常のprintで表示する. + nil: 通常モードであれば, inspect modeとなり, mathモードの時は, non + inspect modeとなる. + +--- conf.use_loader = true/false + load/require時にirbのfile読み込み機能を用いるモードのスイッチ(デフォ + ルトは用いない). このモードはIRB全体に反映される. + +--- conf.prompt_c + ifの直後など, 行が継続している時のプロンプト. + +--- conf.prompt_i + 通常のプロンプト. + +--- conf.prompt_s + 文字列中などを表すプロンプト. + +--- conf.rc + ~/.irbrcを読み込んだかどうか? + +--- conf.use_prompt = true/false + プロンプト表示するかどうか? デフォルトではプロンプトを表示する. + +--- conf.use_multiline = true/false/nil + マルチラインエディタを使うかどうか? + true: マルチラインエディタを使う. + false: マルチラインエディタを使わない. + nil: (デフォルト)inf-ruby-mode以外でマルチラインエディタを利用しよう + とする. + +--- conf.use_singleline = true/false/nil + シングルラインエディタを使うかどうか? + true: シングルラインエディタを使う. + false: シングルラインエディタを使わない. + nil: (デフォルト)inf-ruby-modeとマルチラインエディタ以外でシングルラ + インエディタを利用しようとする. +# +#--- conf.verbose=T/F +# irbからいろいろなメッセージを出力するか? + +--- cws, chws, irb_cws, irb_chws, irb_change_workspace [obj] + objをselfとする. objが省略されたときは, home workspace, すなわち + irbを起動したときのmain objectをselfとする. + +--- pushws, irb_pushws, irb_push_workspace [obj] + UNIXシェルコマンドのpushdと同様. + +--- popws, irb_popws, irb_pop_workspace + UNIXシェルコマンドのpopdと同様. + +--- irb [obj] + サブirbを立ちあげる. objが指定された時は, そのobjをselfとする. + +--- jobs, irb_jobs + サブirbのリスト + +--- fg n, irb_fg n + 指定したサブirbにスイッチする. nは, 次のものを指定する. + + irb番号 + スレッド + irbオブジェクト + self(irb objで起動した時のobj) + +--- kill n, irb_kill n + サブirbをkillする. nはfgと同じ. + +--- source, irb_source path + UNIXシェルコマンドのsourceと似ている. 現在の環境上でpath内のスクリ + プトを評価する. + +--- irb_load path, prev + + Rubyのloadのirb版. + += システム変数 + +--- _ + 前の計算の実行結果を覚えている(ローカル変数). +--- __ + 実行結果の履歴を覚えている. + __[line_no]で、その行で実行した結果を得ることができる. line_noが負の + 時には、最新の結果から-line_no前の結果を得ることができる. + += 使用例 + +以下のような感じです. + + dim% ruby irb.rb + irb(main):001:0> irb # サブirbの立ちあげ + irb#1(main):001:0> jobs # サブirbのリスト + #0->irb on main (# : stop) + #1->irb#1 on main (# : running) + nil + irb#1(main):002:0> fg 0 # jobのスイッチ + nil + irb(main):002:0> class Foo;end + nil + irb(main):003:0> irb Foo # Fooをコンテキストしてirb + # 立ちあげ + irb#2(Foo):001:0> def foo # Foo#fooの定義 + irb#2(Foo):002:1> print 1 + irb#2(Foo):003:1> end + nil + irb#2(Foo):004:0> fg 0 # jobをスイッチ + nil + irb(main):004:0> jobs # jobのリスト + #0->irb on main (# : running) + #1->irb#1 on main (# : stop) + #2->irb#2 on Foo (# : stop) + nil + irb(main):005:0> Foo.instance_methods # Foo#fooがちゃんと定義さ + # れている + ["foo"] + irb(main):006:0> fg 2 # jobをスイッチ + nil + irb#2(Foo):005:0> def bar # Foo#barを定義 + irb#2(Foo):006:1> print "bar" + irb#2(Foo):007:1> end + nil + irb#2(Foo):010:0> Foo.instance_methods + ["bar", "foo"] + irb#2(Foo):011:0> fg 0 + nil + irb(main):007:0> f = Foo.new + # + irb(main):008:0> irb f # Fooのインスタンスでirbを + # 立ちあげる. + irb#3(#):001:0> jobs + #0->irb on main (# : stop) + #1->irb#1 on main (# : stop) + #2->irb#2 on Foo (# : stop) + #3->irb#3 on # (# : running) + nil + irb#3(#):002:0> foo # f.fooの実行 + nil + irb#3(#):003:0> bar # f.barの実行 + barnil + irb#3(#):004:0> kill 1, 2, 3# jobのkill + nil + irb(main):009:0> jobs + #0->irb on main (# : running) + nil + irb(main):010:0> exit # 終了 + dim% + += 使用上の制限 + +irbは, 評価できる時点(式が閉じた時点)での逐次実行を行ないます. したがっ +て, rubyを直接使った時と, 若干異なる動作を行なう場合があります. + +現在明らかになっている問題点を説明します. + +== ローカル変数の宣言 + +rubyでは, 以下のプログラムはエラーになります. + + eval "foo = 0" + foo + -- + -:2: undefined local variable or method `foo' for # (NameError) + --- + NameError + +ところが, irbを用いると + + >> eval "foo = 0" + => 0 + >> foo + => 0 + +となり, エラーを起こしません. これは, rubyが最初にスクリプト全体をコン +パイルしてローカル変数を決定するからです. それに対し, irbは実行可能に +なる(式が閉じる)と自動的に評価しているからです. 上記の例では, + + eval "foo = 0" + +を行なった時点で評価を行ない, その時点で変数が定義されるため, 次式で +変数fooは定義されているからです. + +このようなrubyとirbの動作の違いを解決したい場合は, begin...endで括って +バッチ的に実行して下さい: + + >> begin + ?> eval "foo = 0" + >> foo + >> end + NameError: undefined local variable or method `foo' for # + (irb):3 + (irb_local_binding):1:in `eval' + +== ヒアドキュメント + +現在のところヒアドキュメントの実装は不完全です. + +== シンボル + +シンボルであるかどうかの判断を間違えることがあります. 具体的には式が完了 +しているのに継続行と見なすことがあります. + +=end + +% Begin Emacs Environment +% Local Variables: +% mode: text +% comment-column: 0 +% comment-start: "%" +% comment-end: "\n" +% End: +% diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/exe/irb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/exe/irb new file mode 100755 index 00000000..12f41e4f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/exe/irb @@ -0,0 +1,9 @@ +#!/usr/bin/env ruby +# +# irb.rb - interactive ruby +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# + +require "irb" + +IRB.start(__FILE__) diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/irb.gemspec b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/irb.gemspec new file mode 100644 index 00000000..af14713f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/irb.gemspec @@ -0,0 +1,48 @@ +begin + require_relative "lib/irb/version" +rescue LoadError + # for Ruby core repository + require_relative "version" +end + +Gem::Specification.new do |spec| + spec.name = "irb" + spec.version = IRB::VERSION + spec.authors = ["aycabta", "Keiju ISHITSUKA"] + spec.email = ["aycabta@gmail.com", "keiju@ruby-lang.org"] + + spec.summary = %q{Interactive Ruby command-line tool for REPL (Read Eval Print Loop).} + spec.description = %q{Interactive Ruby command-line tool for REPL (Read Eval Print Loop).} + spec.homepage = "https://github.com/ruby/irb" + spec.licenses = ["Ruby", "BSD-2-Clause"] + + spec.metadata["homepage_uri"] = spec.homepage + spec.metadata["source_code_uri"] = spec.homepage + spec.metadata["documentation_uri"] = "https://ruby.github.io/irb/" + spec.metadata["changelog_uri"] = "#{spec.homepage}/releases" + + spec.files = [ + "Gemfile", + "LICENSE.txt", + "README.md", + "Rakefile", + "bin/console", + "bin/setup", + "doc/irb/irb-tools.rd.ja", + "doc/irb/irb.rd.ja", + "exe/irb", + "irb.gemspec", + "man/irb.1", + ] + Dir.chdir(File.expand_path('..', __FILE__)) do + Dir.glob("lib/**/*").map {|f| f unless File.directory?(f) }.compact + end + spec.bindir = "exe" + spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } + spec.require_paths = ["lib"] + + spec.required_ruby_version = Gem::Requirement.new(">= 2.7") + + spec.add_dependency "reline", ">= 0.4.2" + spec.add_dependency "rdoc", ">= 4.0.0" + spec.add_dependency "pp", ">= 0.6.0" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb.rb new file mode 100644 index 00000000..fd0bfe35 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb.rb @@ -0,0 +1,736 @@ +# frozen_string_literal: true + +# :markup: markdown +# irb.rb - irb main module +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# + +require "ripper" +require "reline" + +require_relative "irb/init" +require_relative "irb/context" +require_relative "irb/default_commands" + +require_relative "irb/ruby-lex" +require_relative "irb/statement" +require_relative "irb/history" +require_relative "irb/input-method" +require_relative "irb/locale" +require_relative "irb/color" + +require_relative "irb/version" +require_relative "irb/easter-egg" +require_relative "irb/debug" +require_relative "irb/pager" + +module IRB + + # An exception raised by IRB.irb_abort + class Abort < Exception;end # :nodoc: + + class << self + # The current IRB::Context of the session, see IRB.conf + # + # irb + # irb(main):001:0> IRB.CurrentContext.irb_name = "foo" + # foo(main):002:0> IRB.conf[:MAIN_CONTEXT].irb_name #=> "foo" + def CurrentContext # :nodoc: + conf[:MAIN_CONTEXT] + end + + # Initializes IRB and creates a new Irb.irb object at the `TOPLEVEL_BINDING` + def start(ap_path = nil) + STDOUT.sync = true + $0 = File::basename(ap_path, ".rb") if ap_path + + setup(ap_path) + + if @CONF[:SCRIPT] + irb = Irb.new(nil, @CONF[:SCRIPT]) + else + irb = Irb.new + end + irb.run(@CONF) + end + + # Quits irb + def irb_exit(*) # :nodoc: + throw :IRB_EXIT, false + end + + # Aborts then interrupts irb. + # + # Will raise an Abort exception, or the given `exception`. + def irb_abort(irb, exception = Abort) # :nodoc: + irb.context.thread.raise exception, "abort then interrupt!" + end + end + + class Irb + # Note: instance and index assignment expressions could also be written like: + # "foo.bar=(1)" and "foo.[]=(1, bar)", when expressed that way, the former be + # parsed as :assign and echo will be suppressed, but the latter is parsed as a + # :method_add_arg and the output won't be suppressed + + PROMPT_MAIN_TRUNCATE_LENGTH = 32 + PROMPT_MAIN_TRUNCATE_OMISSION = '...' + CONTROL_CHARACTERS_PATTERN = "\x00-\x1F" + + # Returns the current context of this irb session + attr_reader :context + # The lexer used by this irb session + attr_accessor :scanner + + attr_reader :from_binding + + # Creates a new irb session + def initialize(workspace = nil, input_method = nil, from_binding: false) + @from_binding = from_binding + @context = Context.new(self, workspace, input_method) + @context.workspace.load_helper_methods_to_main + @signal_status = :IN_IRB + @scanner = RubyLex.new + @line_no = 1 + end + + # A hook point for `debug` command's breakpoint after :IRB_EXIT as well as its + # clean-up + def debug_break + # it means the debug integration has been activated + if defined?(DEBUGGER__) && DEBUGGER__.respond_to?(:capture_frames_without_irb) + # after leaving this initial breakpoint, revert the capture_frames patch + DEBUGGER__.singleton_class.send(:alias_method, :capture_frames, :capture_frames_without_irb) + # and remove the redundant method + DEBUGGER__.singleton_class.send(:undef_method, :capture_frames_without_irb) + end + end + + def debug_readline(binding) + workspace = IRB::WorkSpace.new(binding) + context.replace_workspace(workspace) + context.workspace.load_helper_methods_to_main + @line_no += 1 + + # When users run: + # 1. Debugging commands, like `step 2` + # 2. Any input that's not irb-command, like `foo = 123` + # + # + # Irb#eval_input will simply return the input, and we need to pass it to the + # debugger. + input = nil + forced_exit = catch(:IRB_EXIT) do + if History.save_history? && context.io.support_history_saving? + # Previous IRB session's history has been saved when `Irb#run` is exited We need + # to make sure the saved history is not saved again by resetting the counter + context.io.reset_history_counter + + begin + input = eval_input + ensure + context.io.save_history + end + else + input = eval_input + end + false + end + + Kernel.exit if forced_exit + + if input&.include?("\n") + @line_no += input.count("\n") - 1 + end + + input + end + + def run(conf = IRB.conf) + in_nested_session = !!conf[:MAIN_CONTEXT] + conf[:IRB_RC].call(context) if conf[:IRB_RC] + prev_context = conf[:MAIN_CONTEXT] + conf[:MAIN_CONTEXT] = context + + load_history = !in_nested_session && context.io.support_history_saving? + save_history = load_history && History.save_history? + + if load_history + context.io.load_history + end + + prev_trap = trap("SIGINT") do + signal_handle + end + + begin + if defined?(RubyVM.keep_script_lines) + keep_script_lines_backup = RubyVM.keep_script_lines + RubyVM.keep_script_lines = true + end + + forced_exit = catch(:IRB_EXIT) do + eval_input + end + ensure + # Do not restore to nil. It will cause IRB crash when used with threads. + IRB.conf[:MAIN_CONTEXT] = prev_context if prev_context + + RubyVM.keep_script_lines = keep_script_lines_backup if defined?(RubyVM.keep_script_lines) + trap("SIGINT", prev_trap) + conf[:AT_EXIT].each{|hook| hook.call} + + context.io.save_history if save_history + Kernel.exit if forced_exit + end + end + + # Evaluates input for this session. + def eval_input + configure_io + + each_top_level_statement do |statement, line_no| + signal_status(:IN_EVAL) do + begin + # If the integration with debugger is activated, we return certain input if it + # should be dealt with by debugger + if @context.with_debugger && statement.should_be_handled_by_debugger? + return statement.code + end + + @context.evaluate(statement, line_no) + + if @context.echo? && !statement.suppresses_echo? + if statement.is_assignment? + if @context.echo_on_assignment? + output_value(@context.echo_on_assignment? == :truncate) + end + else + output_value + end + end + rescue SystemExit, SignalException + raise + rescue Interrupt, Exception => exc + handle_exception(exc) + @context.workspace.local_variable_set(:_, exc) + end + end + end + end + + def read_input(prompt) + signal_status(:IN_INPUT) do + @context.io.prompt = prompt + if l = @context.io.gets + print l if @context.verbose? + else + if @context.ignore_eof? and @context.io.readable_after_eof? + l = "\n" + if @context.verbose? + printf "Use \"exit\" to leave %s\n", @context.ap_name + end + else + print "\n" if @context.prompting? + end + end + l + end + end + + def readmultiline + prompt = generate_prompt([], false, 0) + + # multiline + return read_input(prompt) if @context.io.respond_to?(:check_termination) + + # nomultiline + code = +'' + line_offset = 0 + loop do + line = read_input(prompt) + unless line + return code.empty? ? nil : code + end + + code << line + return code if command?(code) + + tokens, opens, terminated = @scanner.check_code_state(code, local_variables: @context.local_variables) + return code if terminated + + line_offset += 1 + continue = @scanner.should_continue?(tokens) + prompt = generate_prompt(opens, continue, line_offset) + end + end + + def each_top_level_statement + loop do + code = readmultiline + break unless code + yield parse_input(code), @line_no + @line_no += code.count("\n") + rescue RubyLex::TerminateLineInput + end + end + + def parse_input(code) + if code.match?(/\A\n*\z/) + return Statement::EmptyInput.new + end + + code = code.dup.force_encoding(@context.io.encoding) + is_assignment_expression = @scanner.assignment_expression?(code, local_variables: @context.local_variables) + + @context.parse_input(code, is_assignment_expression) + end + + def command?(code) + parse_input(code).is_a?(Statement::Command) + end + + def configure_io + if @context.io.respond_to?(:check_termination) + @context.io.check_termination do |code| + if Reline::IOGate.in_pasting? + rest = @scanner.check_termination_in_prev_line(code, local_variables: @context.local_variables) + if rest + Reline.delete_text + rest.bytes.reverse_each do |c| + Reline.ungetc(c) + end + true + else + false + end + else + next true if command?(code) + + _tokens, _opens, terminated = @scanner.check_code_state(code, local_variables: @context.local_variables) + terminated + end + end + end + if @context.io.respond_to?(:dynamic_prompt) + @context.io.dynamic_prompt do |lines| + tokens = RubyLex.ripper_lex_without_warning(lines.map{ |l| l + "\n" }.join, local_variables: @context.local_variables) + line_results = IRB::NestingParser.parse_by_line(tokens) + tokens_until_line = [] + line_results.map.with_index do |(line_tokens, _prev_opens, next_opens, _min_depth), line_num_offset| + line_tokens.each do |token, _s| + # Avoid appending duplicated token. Tokens that include "n" like multiline + # tstring_content can exist in multiple lines. + tokens_until_line << token if token != tokens_until_line.last + end + continue = @scanner.should_continue?(tokens_until_line) + generate_prompt(next_opens, continue, line_num_offset) + end + end + end + + if @context.io.respond_to?(:auto_indent) and @context.auto_indent_mode + @context.io.auto_indent do |lines, line_index, byte_pointer, is_newline| + next nil if lines == [nil] # Workaround for exit IRB with CTRL+d + next nil if !is_newline && lines[line_index]&.byteslice(0, byte_pointer)&.match?(/\A\s*\z/) + + code = lines[0..line_index].map { |l| "#{l}\n" }.join + tokens = RubyLex.ripper_lex_without_warning(code, local_variables: @context.local_variables) + @scanner.process_indent_level(tokens, lines, line_index, is_newline) + end + end + end + + def convert_invalid_byte_sequence(str, enc) + str.force_encoding(enc) + str.scrub { |c| + c.bytes.map{ |b| "\\x#{b.to_s(16).upcase}" }.join + } + end + + def encode_with_invalid_byte_sequence(str, enc) + conv = Encoding::Converter.new(str.encoding, enc) + dst = String.new + begin + ret = conv.primitive_convert(str, dst) + case ret + when :invalid_byte_sequence + conv.insert_output(conv.primitive_errinfo[3].dump[1..-2]) + redo + when :undefined_conversion + c = conv.primitive_errinfo[3].dup.force_encoding(conv.primitive_errinfo[1]) + conv.insert_output(c.dump[1..-2]) + redo + when :incomplete_input + conv.insert_output(conv.primitive_errinfo[3].dump[1..-2]) + when :finished + end + break + end while nil + dst + end + + def handle_exception(exc) + if exc.backtrace[0] =~ /\/irb(2)?(\/.*|-.*|\.rb)?:/ && exc.class.to_s !~ /^IRB/ && + !(SyntaxError === exc) && !(EncodingError === exc) + # The backtrace of invalid encoding hash (ex. {"\xAE": 1}) raises EncodingError without lineno. + irb_bug = true + else + irb_bug = false + # To support backtrace filtering while utilizing Exception#full_message, we need to clone + # the exception to avoid modifying the original exception's backtrace. + exc = exc.clone + filtered_backtrace = exc.backtrace.map { |l| @context.workspace.filter_backtrace(l) }.compact + backtrace_filter = IRB.conf[:BACKTRACE_FILTER] + + if backtrace_filter + if backtrace_filter.respond_to?(:call) + filtered_backtrace = backtrace_filter.call(filtered_backtrace) + else + warn "IRB.conf[:BACKTRACE_FILTER] #{backtrace_filter} should respond to `call` method" + end + end + + exc.set_backtrace(filtered_backtrace) + end + + highlight = Color.colorable? + + order = + if RUBY_VERSION < '3.0.0' + STDOUT.tty? ? :bottom : :top + else # '3.0.0' <= RUBY_VERSION + :top + end + + message = exc.full_message(order: order, highlight: highlight) + message = convert_invalid_byte_sequence(message, exc.message.encoding) + message = encode_with_invalid_byte_sequence(message, IRB.conf[:LC_MESSAGES].encoding) unless message.encoding.to_s.casecmp?(IRB.conf[:LC_MESSAGES].encoding.to_s) + message = message.gsub(/((?:^\t.+$\n)+)/) { |m| + case order + when :top + lines = m.split("\n") + when :bottom + lines = m.split("\n").reverse + end + unless irb_bug + if lines.size > @context.back_trace_limit + omit = lines.size - @context.back_trace_limit + lines = lines[0..(@context.back_trace_limit - 1)] + lines << "\t... %d levels..." % omit + end + end + lines = lines.reverse if order == :bottom + lines.map{ |l| l + "\n" }.join + } + # The "" in "(irb)" may be the top level of IRB so imitate the main object. + message = message.gsub(/\(irb\):(?\d+):in (?[`'])<(?top \(required\))>'/) { "(irb):#{$~[:num]}:in #{$~[:open_quote]}
'" } + puts message + + if irb_bug + puts "This may be an issue with IRB. If you believe this is an unexpected behavior, please report it to https://github.com/ruby/irb/issues" + end + rescue Exception => handler_exc + begin + puts exc.inspect + puts "backtraces are hidden because #{handler_exc} was raised when processing them" + rescue Exception + puts 'Uninspectable exception occurred' + end + end + + # Evaluates the given block using the given `path` as the Context#irb_path and + # `name` as the Context#irb_name. + # + # Used by the irb command `source`, see IRB@IRB+Sessions for more information. + def suspend_name(path = nil, name = nil) + @context.irb_path, back_path = path, @context.irb_path if path + @context.irb_name, back_name = name, @context.irb_name if name + begin + yield back_path, back_name + ensure + @context.irb_path = back_path if path + @context.irb_name = back_name if name + end + end + + # Evaluates the given block using the given `workspace` as the + # Context#workspace. + # + # Used by the irb command `irb_load`, see IRB@IRB+Sessions for more information. + def suspend_workspace(workspace) + current_workspace = @context.workspace + @context.replace_workspace(workspace) + yield + ensure + @context.replace_workspace current_workspace + end + + # Evaluates the given block using the given `input_method` as the Context#io. + # + # Used by the irb commands `source` and `irb_load`, see IRB@IRB+Sessions for + # more information. + def suspend_input_method(input_method) + back_io = @context.io + @context.instance_eval{@io = input_method} + begin + yield back_io + ensure + @context.instance_eval{@io = back_io} + end + end + + # Handler for the signal SIGINT, see Kernel#trap for more information. + def signal_handle + unless @context.ignore_sigint? + print "\nabort!\n" if @context.verbose? + exit + end + + case @signal_status + when :IN_INPUT + print "^C\n" + raise RubyLex::TerminateLineInput + when :IN_EVAL + IRB.irb_abort(self) + when :IN_LOAD + IRB.irb_abort(self, LoadAbort) + when :IN_IRB + # ignore + else + # ignore other cases as well + end + end + + # Evaluates the given block using the given `status`. + def signal_status(status) + return yield if @signal_status == :IN_LOAD + + signal_status_back = @signal_status + @signal_status = status + begin + yield + ensure + @signal_status = signal_status_back + end + end + + def output_value(omit = false) # :nodoc: + unless @context.return_format.include?('%') + puts @context.return_format + return + end + + winheight, winwidth = @context.io.winsize + if omit + content, overflow = Pager.take_first_page(winwidth, 1) do |out| + @context.inspect_last_value(out) + end + if overflow + content = "\n#{content}" if @context.newline_before_multiline_output? + content = "#{content}..." + content = "#{content}\e[0m" if Color.colorable? + end + puts format(@context.return_format, content.chomp) + elsif Pager.should_page? && @context.inspector_support_stream_output? + formatter_proc = ->(content, multipage) do + content = content.chomp + content = "\n#{content}" if @context.newline_before_multiline_output? && (multipage || content.include?("\n")) + format(@context.return_format, content) + end + Pager.page_with_preview(winwidth, winheight, formatter_proc) do |out| + @context.inspect_last_value(out) + end + else + content = @context.inspect_last_value.chomp + content = "\n#{content}" if @context.newline_before_multiline_output? && content.include?("\n") + Pager.page_content(format(@context.return_format, content), retain_content: true) + end + end + + # Outputs the local variables to this current session, including #signal_status + # and #context, using IRB::Locale. + def inspect + ary = [] + for iv in instance_variables + case (iv = iv.to_s) + when "@signal_status" + ary.push format("%s=:%s", iv, @signal_status.id2name) + when "@context" + ary.push format("%s=%s", iv, eval(iv).__to_s__) + else + ary.push format("%s=%s", iv, eval(iv)) + end + end + format("#<%s: %s>", self.class, ary.join(", ")) + end + + private + + def generate_prompt(opens, continue, line_offset) + ltype = @scanner.ltype_from_open_tokens(opens) + indent = @scanner.calc_indent_level(opens) + continue = opens.any? || continue + line_no = @line_no + line_offset + + if ltype + f = @context.prompt_s + elsif continue + f = @context.prompt_c + else + f = @context.prompt_i + end + f = "" unless f + if @context.prompting? + p = format_prompt(f, ltype, indent, line_no) + else + p = "" + end + if @context.auto_indent_mode and !@context.io.respond_to?(:auto_indent) + unless ltype + prompt_i = @context.prompt_i.nil? ? "" : @context.prompt_i + ind = format_prompt(prompt_i, ltype, indent, line_no)[/.*\z/].size + + indent * 2 - p.size + p += " " * ind if ind > 0 + end + end + p + end + + def truncate_prompt_main(str) # :nodoc: + str = str.tr(CONTROL_CHARACTERS_PATTERN, ' ') + if str.size <= PROMPT_MAIN_TRUNCATE_LENGTH + str + else + str[0, PROMPT_MAIN_TRUNCATE_LENGTH - PROMPT_MAIN_TRUNCATE_OMISSION.size] + PROMPT_MAIN_TRUNCATE_OMISSION + end + end + + def format_prompt(format, ltype, indent, line_no) # :nodoc: + format.gsub(/%([0-9]+)?([a-zA-Z%])/) do + case $2 + when "N" + @context.irb_name + when "m" + main_str = @context.safe_method_call_on_main(:to_s) rescue "!#{$!.class}" + truncate_prompt_main(main_str) + when "M" + main_str = @context.safe_method_call_on_main(:inspect) rescue "!#{$!.class}" + truncate_prompt_main(main_str) + when "l" + ltype + when "i" + if indent < 0 + if $1 + "-".rjust($1.to_i) + else + "-" + end + else + if $1 + format("%" + $1 + "d", indent) + else + indent.to_s + end + end + when "n" + if $1 + format("%" + $1 + "d", line_no) + else + line_no.to_s + end + when "%" + "%" unless $1 + end + end + end + end +end + +class Binding + # Opens an IRB session where `binding.irb` is called which allows for + # interactive debugging. You can call any methods or variables available in the + # current scope, and mutate state if you need to. + # + # Given a Ruby file called `potato.rb` containing the following code: + # + # class Potato + # def initialize + # @cooked = false + # binding.irb + # puts "Cooked potato: #{@cooked}" + # end + # end + # + # Potato.new + # + # Running `ruby potato.rb` will open an IRB session where `binding.irb` is + # called, and you will see the following: + # + # $ ruby potato.rb + # + # From: potato.rb @ line 4 : + # + # 1: class Potato + # 2: def initialize + # 3: @cooked = false + # => 4: binding.irb + # 5: puts "Cooked potato: #{@cooked}" + # 6: end + # 7: end + # 8: + # 9: Potato.new + # + # irb(#):001:0> + # + # You can type any valid Ruby code and it will be evaluated in the current + # context. This allows you to debug without having to run your code repeatedly: + # + # irb(#):001:0> @cooked + # => false + # irb(#):002:0> self.class + # => Potato + # irb(#):003:0> caller.first + # => ".../2.5.1/lib/ruby/2.5.0/irb/workspace.rb:85:in `eval'" + # irb(#):004:0> @cooked = true + # => true + # + # You can exit the IRB session with the `exit` command. Note that exiting will + # resume execution where `binding.irb` had paused it, as you can see from the + # output printed to standard output in this example: + # + # irb(#):005:0> exit + # Cooked potato: true + # + # See IRB for more information. + def irb(show_code: true) + # Setup IRB with the current file's path and no command line arguments + IRB.setup(source_location[0], argv: []) unless IRB.initialized? + # Create a new workspace using the current binding + workspace = IRB::WorkSpace.new(self) + # Print the code around the binding if show_code is true + STDOUT.print(workspace.code_around_binding) if show_code + # Get the original IRB instance + debugger_irb = IRB.instance_variable_get(:@debugger_irb) + + irb_path = File.expand_path(source_location[0]) + + if debugger_irb + # If we're already in a debugger session, set the workspace and irb_path for the original IRB instance + debugger_irb.context.replace_workspace(workspace) + debugger_irb.context.irb_path = irb_path + # If we've started a debugger session and hit another binding.irb, we don't want + # to start an IRB session instead, we want to resume the irb:rdbg session. + IRB::Debug.setup(debugger_irb) + IRB::Debug.insert_debug_break + debugger_irb.debug_break + else + # If we're not in a debugger session, create a new IRB instance with the current + # workspace + binding_irb = IRB::Irb.new(workspace, from_binding: true) + binding_irb.context.irb_path = irb_path + binding_irb.run(IRB.conf) + binding_irb.debug_break + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/cmd/nop.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/cmd/nop.rb new file mode 100644 index 00000000..9d2e3c4d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/cmd/nop.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +# This file is just a placeholder for backward-compatibility. +# Please require 'irb' and inherit your command from `IRB::Command::Base` instead. diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/color.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/color.rb new file mode 100644 index 00000000..a7e31108 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/color.rb @@ -0,0 +1,263 @@ +# frozen_string_literal: true +require 'reline' +require 'ripper' +require_relative 'ruby-lex' + +module IRB # :nodoc: + module Color + CLEAR = 0 + BOLD = 1 + UNDERLINE = 4 + REVERSE = 7 + BLACK = 30 + RED = 31 + GREEN = 32 + YELLOW = 33 + BLUE = 34 + MAGENTA = 35 + CYAN = 36 + WHITE = 37 + + TOKEN_KEYWORDS = { + on_kw: ['nil', 'self', 'true', 'false', '__FILE__', '__LINE__', '__ENCODING__'], + on_const: ['ENV'], + } + private_constant :TOKEN_KEYWORDS + + # A constant of all-bit 1 to match any Ripper's state in #dispatch_seq + ALL = -1 + private_constant :ALL + + begin + # Following pry's colors where possible, but sometimes having a compromise like making + # backtick and regexp as red (string's color, because they're sharing tokens). + TOKEN_SEQ_EXPRS = { + on_CHAR: [[BLUE, BOLD], ALL], + on_backtick: [[RED, BOLD], ALL], + on_comment: [[BLUE, BOLD], ALL], + on_const: [[BLUE, BOLD, UNDERLINE], ALL], + on_embexpr_beg: [[RED], ALL], + on_embexpr_end: [[RED], ALL], + on_embvar: [[RED], ALL], + on_float: [[MAGENTA, BOLD], ALL], + on_gvar: [[GREEN, BOLD], ALL], + on_backref: [[GREEN, BOLD], ALL], + on_heredoc_beg: [[RED], ALL], + on_heredoc_end: [[RED], ALL], + on_ident: [[BLUE, BOLD], Ripper::EXPR_ENDFN], + on_imaginary: [[BLUE, BOLD], ALL], + on_int: [[BLUE, BOLD], ALL], + on_kw: [[GREEN], ALL], + on_label: [[MAGENTA], ALL], + on_label_end: [[RED, BOLD], ALL], + on_qsymbols_beg: [[RED, BOLD], ALL], + on_qwords_beg: [[RED, BOLD], ALL], + on_rational: [[BLUE, BOLD], ALL], + on_regexp_beg: [[RED, BOLD], ALL], + on_regexp_end: [[RED, BOLD], ALL], + on_symbeg: [[YELLOW], ALL], + on_symbols_beg: [[RED, BOLD], ALL], + on_tstring_beg: [[RED, BOLD], ALL], + on_tstring_content: [[RED], ALL], + on_tstring_end: [[RED, BOLD], ALL], + on_words_beg: [[RED, BOLD], ALL], + on_parse_error: [[RED, REVERSE], ALL], + compile_error: [[RED, REVERSE], ALL], + on_assign_error: [[RED, REVERSE], ALL], + on_alias_error: [[RED, REVERSE], ALL], + on_class_name_error:[[RED, REVERSE], ALL], + on_param_error: [[RED, REVERSE], ALL], + on___end__: [[GREEN], ALL], + } + rescue NameError + # Give up highlighting Ripper-incompatible older Ruby + TOKEN_SEQ_EXPRS = {} + end + private_constant :TOKEN_SEQ_EXPRS + + ERROR_TOKENS = TOKEN_SEQ_EXPRS.keys.select { |k| k.to_s.end_with?('error') } + private_constant :ERROR_TOKENS + + class << self + def colorable? + supported = $stdout.tty? && (/mswin|mingw/.match?(RUBY_PLATFORM) || (ENV.key?('TERM') && ENV['TERM'] != 'dumb')) + + # because ruby/debug also uses irb's color module selectively, + # irb won't be activated in that case. + if IRB.respond_to?(:conf) + supported && !!IRB.conf.fetch(:USE_COLORIZE, true) + else + supported + end + end + + def inspect_colorable?(obj, seen: {}.compare_by_identity) + case obj + when String, Symbol, Regexp, Integer, Float, FalseClass, TrueClass, NilClass + true + when Hash + without_circular_ref(obj, seen: seen) do + obj.all? { |k, v| inspect_colorable?(k, seen: seen) && inspect_colorable?(v, seen: seen) } + end + when Array + without_circular_ref(obj, seen: seen) do + obj.all? { |o| inspect_colorable?(o, seen: seen) } + end + when Range + inspect_colorable?(obj.begin, seen: seen) && inspect_colorable?(obj.end, seen: seen) + when Module + !obj.name.nil? + else + false + end + end + + def clear(colorable: colorable?) + return '' unless colorable + "\e[#{CLEAR}m" + end + + def colorize(text, seq, colorable: colorable?) + return text unless colorable + seq = seq.map { |s| "\e[#{const_get(s)}m" }.join('') + "#{seq}#{text}#{clear(colorable: colorable)}" + end + + # If `complete` is false (code is incomplete), this does not warn compile_error. + # This option is needed to avoid warning a user when the compile_error is happening + # because the input is not wrong but just incomplete. + def colorize_code(code, complete: true, ignore_error: false, colorable: colorable?, local_variables: []) + return code unless colorable + + symbol_state = SymbolState.new + colored = +'' + lvars_code = RubyLex.generate_local_variables_assign_code(local_variables) + code_with_lvars = lvars_code ? "#{lvars_code}\n#{code}" : code + + scan(code_with_lvars, allow_last_error: !complete) do |token, str, expr| + # handle uncolorable code + if token.nil? + colored << Reline::Unicode.escape_for_print(str) + next + end + + # IRB::ColorPrinter skips colorizing fragments with any invalid token + if ignore_error && ERROR_TOKENS.include?(token) + return Reline::Unicode.escape_for_print(code) + end + + in_symbol = symbol_state.scan_token(token) + str.each_line do |line| + line = Reline::Unicode.escape_for_print(line) + if seq = dispatch_seq(token, expr, line, in_symbol: in_symbol) + colored << seq.map { |s| "\e[#{s}m" }.join('') + colored << line.sub(/\Z/, clear(colorable: colorable)) + else + colored << line + end + end + end + + if lvars_code + raise "#{lvars_code.dump} should have no \\n" if lvars_code.include?("\n") + colored.sub!(/\A.+\n/, '') # delete_prefix lvars_code with colors + end + colored + end + + private + + def without_circular_ref(obj, seen:, &block) + return false if seen.key?(obj) + seen[obj] = true + block.call + ensure + seen.delete(obj) + end + + def scan(code, allow_last_error:) + verbose, $VERBOSE = $VERBOSE, nil + RubyLex.compile_with_errors_suppressed(code) do |inner_code, line_no| + lexer = Ripper::Lexer.new(inner_code, '(ripper)', line_no) + byte_pos = 0 + line_positions = [0] + inner_code.lines.each do |line| + line_positions << line_positions.last + line.bytesize + end + + on_scan = proc do |elem| + start_pos = line_positions[elem.pos[0] - 1] + elem.pos[1] + + # yield uncolorable code + if byte_pos < start_pos + yield(nil, inner_code.byteslice(byte_pos...start_pos), nil) + end + + if byte_pos <= start_pos + str = elem.tok + yield(elem.event, str, elem.state) + byte_pos = start_pos + str.bytesize + end + end + + lexer.scan.each do |elem| + next if allow_last_error and /meets end of file|unexpected end-of-input/ =~ elem.message + on_scan.call(elem) + end + # yield uncolorable DATA section + yield(nil, inner_code.byteslice(byte_pos...inner_code.bytesize), nil) if byte_pos < inner_code.bytesize + end + ensure + $VERBOSE = verbose + end + + def dispatch_seq(token, expr, str, in_symbol:) + if ERROR_TOKENS.include?(token) + TOKEN_SEQ_EXPRS[token][0] + elsif in_symbol + [YELLOW] + elsif TOKEN_KEYWORDS.fetch(token, []).include?(str) + [CYAN, BOLD] + elsif (seq, exprs = TOKEN_SEQ_EXPRS[token]; (expr & (exprs || 0)) != 0) + seq + else + nil + end + end + end + + # A class to manage a state to know whether the current token is for Symbol or not. + class SymbolState + def initialize + # Push `true` to detect Symbol. `false` to increase the nest level for non-Symbol. + @stack = [] + end + + # Return true if the token is a part of Symbol. + def scan_token(token) + prev_state = @stack.last + case token + when :on_symbeg, :on_symbols_beg, :on_qsymbols_beg + @stack << true + when :on_ident, :on_op, :on_const, :on_ivar, :on_cvar, :on_gvar, :on_kw, :on_backtick + if @stack.last # Pop only when it's Symbol + @stack.pop + return prev_state + end + when :on_tstring_beg + @stack << false + when :on_embexpr_beg + @stack << false + return prev_state + when :on_tstring_end # :on_tstring_end may close Symbol + @stack.pop + return prev_state + when :on_embexpr_end + @stack.pop + end + @stack.last + end + end + private_constant :SymbolState + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/color_printer.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/color_printer.rb new file mode 100644 index 00000000..7a7e8178 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/color_printer.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true +require 'pp' +require_relative 'color' + +module IRB + class ColorPrinter < ::PP + class << self + def pp(obj, out = $>, width = screen_width, colorize: true) + q = ColorPrinter.new(out, width, colorize: colorize) + q.guard_inspect_key {q.pp obj} + q.flush + out << "\n" + end + + private + + def screen_width + Reline.get_screen_size.last + rescue Errno::EINVAL # in `winsize': Invalid argument - + 79 + end + end + + def initialize(out, width, colorize: true) + @colorize = colorize + + super(out, width) + end + + def pp(obj) + if String === obj + # Avoid calling Ruby 2.4+ String#pretty_print that splits a string by "\n" + text(obj.inspect) + else + super + end + end + + def text(str, width = nil) + unless str.is_a?(String) + str = str.inspect + end + width ||= str.length + + case str + when '' + when ',', '=>', '[', ']', '{', '}', '..', '...', /\A@\w+\z/ + super(str, width) + when /\A#' + super(@colorize ? Color.colorize(str, [:GREEN]) : str, width) + else + super(@colorize ? Color.colorize_code(str, ignore_error: true) : str, width) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command.rb new file mode 100644 index 00000000..68a4b527 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true +# +# irb/command.rb - irb command +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# + +require_relative "command/base" + +module IRB # :nodoc: + module Command + @commands = {} + + class << self + attr_reader :commands + + # Registers a command with the given name. + # Aliasing is intentionally not supported at the moment. + def register(name, command_class) + @commands[name.to_sym] = [command_class, []] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/backtrace.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/backtrace.rb new file mode 100644 index 00000000..687bb075 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/backtrace.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require_relative "debug" + +module IRB + # :stopdoc: + + module Command + class Backtrace < DebugCommand + def execute(arg) + execute_debug_command(pre_cmds: "backtrace #{arg}") + end + end + end + + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/base.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/base.rb new file mode 100644 index 00000000..2f39b75c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/base.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true +# +# nop.rb - +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# + +module IRB + module Command + class CommandArgumentError < StandardError; end # :nodoc: + + class << self + def extract_ruby_args(*args, **kwargs) # :nodoc: + throw :EXTRACT_RUBY_ARGS, [args, kwargs] + end + end + + class Base + class << self + def category(category = nil) + @category = category if category + @category || "No category" + end + + def description(description = nil) + @description = description if description + @description || "No description provided." + end + + def help_message(help_message = nil) + @help_message = help_message if help_message + @help_message + end + + def execute(irb_context, arg) + new(irb_context).execute(arg) + rescue CommandArgumentError => e + puts e.message + end + + private + + def highlight(text) + Color.colorize(text, [:BOLD, :BLUE]) + end + end + + def initialize(irb_context) + @irb_context = irb_context + end + + attr_reader :irb_context + + def execute(arg) + #nop + end + end + + Nop = Base # :nodoc: + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/break.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/break.rb new file mode 100644 index 00000000..a8f81fe6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/break.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require_relative "debug" + +module IRB + # :stopdoc: + + module Command + class Break < DebugCommand + def execute(arg) + execute_debug_command(pre_cmds: "break #{arg}") + end + end + end + + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/catch.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/catch.rb new file mode 100644 index 00000000..529dcbca --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/catch.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require_relative "debug" + +module IRB + # :stopdoc: + + module Command + class Catch < DebugCommand + def execute(arg) + execute_debug_command(pre_cmds: "catch #{arg}") + end + end + end + + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/cd.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/cd.rb new file mode 100644 index 00000000..b83c8689 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/cd.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module IRB + module Command + class CD < Base + category "Workspace" + description "Move into the given object or leave the current context." + + help_message(<<~HELP) + Usage: cd ([target]|..) + + IRB uses a stack of workspaces to keep track of context(s), with `pushws` and `popws` commands to manipulate the stack. + The `cd` command is an attempt to simplify the operation and will be subject to change. + + When given: + - an object, cd will use that object as the new context by pushing it onto the workspace stack. + - "..", cd will leave the current context by popping the top workspace off the stack. + - no arguments, cd will move to the top workspace on the stack by popping off all workspaces. + + Examples: + + cd Foo + cd Foo.new + cd @ivar + cd .. + cd + HELP + + def execute(arg) + case arg + when ".." + irb_context.pop_workspace + when "" + # TODO: decide what workspace commands should be kept, and underlying APIs should look like, + # and perhaps add a new API to clear the workspace stack. + prev_workspace = irb_context.pop_workspace + while prev_workspace + prev_workspace = irb_context.pop_workspace + end + else + begin + obj = eval(arg, irb_context.workspace.binding) + irb_context.push_workspace(obj) + rescue StandardError => e + warn "Error: #{e}" + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/chws.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/chws.rb new file mode 100644 index 00000000..ef456d09 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/chws.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true +# +# change-ws.rb - +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# +require_relative "../ext/change-ws" + +module IRB + # :stopdoc: + + module Command + + class CurrentWorkingWorkspace < Base + category "Workspace" + description "Show the current workspace." + + def execute(_arg) + puts "Current workspace: #{irb_context.main}" + end + end + + class ChangeWorkspace < Base + category "Workspace" + description "Change the current workspace to an object." + + def execute(arg) + if arg.empty? + irb_context.change_workspace + else + obj = eval(arg, irb_context.workspace.binding) + irb_context.change_workspace(obj) + end + + puts "Current workspace: #{irb_context.main}" + end + end + end + + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/context.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/context.rb new file mode 100644 index 00000000..b4fc8073 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/context.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module IRB + module Command + class Context < Base + category "IRB" + description "Displays current configuration." + + def execute(_arg) + # This command just displays the configuration. + # Modifying the configuration is achieved by sending a message to IRB.conf. + Pager.page_content(IRB.CurrentContext.inspect) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/continue.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/continue.rb new file mode 100644 index 00000000..0daa029b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/continue.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require_relative "debug" + +module IRB + # :stopdoc: + + module Command + class Continue < DebugCommand + def execute(arg) + execute_debug_command(do_cmds: "continue #{arg}") + end + end + end + + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/copy.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/copy.rb new file mode 100644 index 00000000..93410b87 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/copy.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +module IRB + module Command + class Copy < Base + category "Misc" + description "Copy expression output to clipboard" + + help_message(<<~HELP) + Usage: copy ([expression]) + + When given: + - an expression, copy the inspect result of the expression to the clipboard. + - no arguments, copy the last evaluated result (`_`) to the clipboard. + + Examples: + + copy Foo.new + copy User.all.to_a + copy + HELP + + def execute(arg) + # Copy last value if no expression was supplied + arg = '_' if arg.to_s.strip.empty? + + value = irb_context.workspace.binding.eval(arg) + output = irb_context.inspect_method.inspect_value(value, +'', colorize: false).chomp + + if clipboard_available? + copy_to_clipboard(output) + else + warn "System clipboard not found" + end + rescue StandardError => e + warn "Error: #{e}" + end + + private + + def copy_to_clipboard(text) + IO.popen(clipboard_program, 'w') do |io| + io.write(text) + end + + raise IOError.new("Copying to clipboard failed") unless $? == 0 + + puts "Copied to system clipboard" + rescue Errno::ENOENT => e + warn e.message + warn "Is IRB.conf[:COPY_COMMAND] set to a bad value?" + end + + def clipboard_program + @clipboard_program ||= if IRB.conf[:COPY_COMMAND] + IRB.conf[:COPY_COMMAND] + elsif executable?("pbcopy") + "pbcopy" + elsif executable?("xclip") + "xclip -selection clipboard" + end + end + + def executable?(command) + system("which #{command} > /dev/null 2>&1") + end + + def clipboard_available? + !!clipboard_program + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/debug.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/debug.rb new file mode 100644 index 00000000..3ebb57fe --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/debug.rb @@ -0,0 +1,73 @@ +require_relative "../debug" + +module IRB + # :stopdoc: + + module Command + class Debug < Base + category "Debugging" + description "Start the debugger of debug.gem." + + def execute(_arg) + execute_debug_command + end + + def execute_debug_command(pre_cmds: nil, do_cmds: nil) + pre_cmds = pre_cmds&.rstrip + do_cmds = do_cmds&.rstrip + + if irb_context.with_debugger + # If IRB is already running with a debug session, throw the command and IRB.debug_readline will pass it to the debugger. + if cmd = pre_cmds || do_cmds + throw :IRB_EXIT, cmd + else + puts "IRB is already running with a debug session." + return + end + else + # If IRB is not running with a debug session yet, then: + # 1. Check if the debugging command is run from a `binding.irb` call. + # 2. If so, try setting up the debug gem. + # 3. Insert a debug breakpoint at `Irb#debug_break` with the intended command. + # 4. Exit the current Irb#run call via `throw :IRB_EXIT`. + # 5. `Irb#debug_break` will be called and trigger the breakpoint, which will run the intended command. + unless irb_context.from_binding? + puts "Debugging commands are only available when IRB is started with binding.irb" + return + end + + if IRB.respond_to?(:JobManager) + warn "Can't start the debugger when IRB is running in a multi-IRB session." + return + end + + unless IRB::Debug.setup(irb_context.irb) + puts <<~MSG + You need to install the debug gem before using this command. + If you use `bundle exec`, please add `gem "debug"` into your Gemfile. + MSG + return + end + + IRB::Debug.insert_debug_break(pre_cmds: pre_cmds, do_cmds: do_cmds) + + # exit current Irb#run call + throw :IRB_EXIT + end + end + end + + class DebugCommand < Debug + class << self + def category + "Debugging" + end + + def description + command_name = self.name.split("::").last.downcase + "Start the debugger of debug.gem and run its `#{command_name}` command." + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/delete.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/delete.rb new file mode 100644 index 00000000..2a57a4a3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/delete.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require_relative "debug" + +module IRB + # :stopdoc: + + module Command + class Delete < DebugCommand + def execute(arg) + execute_debug_command(pre_cmds: "delete #{arg}") + end + end + end + + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/disable_irb.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/disable_irb.rb new file mode 100644 index 00000000..0b00d030 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/disable_irb.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module IRB + # :stopdoc: + + module Command + class DisableIrb < Base + category "IRB" + description "Disable binding.irb." + + def execute(*) + ::Binding.define_method(:irb) {} + IRB.irb_exit + end + end + end + + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/edit.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/edit.rb new file mode 100644 index 00000000..cb7e0c48 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/edit.rb @@ -0,0 +1,63 @@ +require 'shellwords' + +require_relative "../color" +require_relative "../source_finder" + +module IRB + # :stopdoc: + + module Command + class Edit < Base + include RubyArgsExtractor + + category "Misc" + description 'Open a file or source location.' + help_message <<~HELP_MESSAGE + Usage: edit [FILE or constant or method signature] + + Open a file in the editor specified in #{highlight('ENV["VISUAL"]')} or #{highlight('ENV["EDITOR"]')} + + - If no arguments are provided, IRB will attempt to open the file the current context was defined in. + - If FILE is provided, IRB will open the file. + - If a constant or method signature is provided, IRB will attempt to locate the source file and open it. + + Examples: + + edit + edit foo.rb + edit Foo + edit Foo#bar + HELP_MESSAGE + + def execute(arg) + # Accept string literal for backward compatibility + path = unwrap_string_literal(arg) + + if path.nil? + path = @irb_context.irb_path + elsif !File.exist?(path) + source = SourceFinder.new(@irb_context).find_source(path) + + if source&.file_exist? && !source.binary_file? + path = source.file + end + end + + unless File.exist?(path) + puts "Can not find file: #{path}" + return + end + + if editor = (ENV['VISUAL'] || ENV['EDITOR']) + puts "command: '#{editor}'" + puts " path: #{path}" + system(*Shellwords.split(editor), path) + else + puts "Can not find editor setting: ENV['VISUAL'] or ENV['EDITOR']" + end + end + end + end + + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/exit.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/exit.rb new file mode 100644 index 00000000..b4436f03 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/exit.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module IRB + # :stopdoc: + + module Command + class Exit < Base + category "IRB" + description "Exit the current irb session." + + def execute(_arg) + IRB.irb_exit + end + end + end + + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/finish.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/finish.rb new file mode 100644 index 00000000..3311a0e6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/finish.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require_relative "debug" + +module IRB + # :stopdoc: + + module Command + class Finish < DebugCommand + def execute(arg) + execute_debug_command(do_cmds: "finish #{arg}") + end + end + end + + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/force_exit.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/force_exit.rb new file mode 100644 index 00000000..14086aa8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/force_exit.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module IRB + # :stopdoc: + + module Command + class ForceExit < Base + category "IRB" + description "Exit the current process." + + def execute(_arg) + throw :IRB_EXIT, true + end + end + end + + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/help.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/help.rb new file mode 100644 index 00000000..12b468fe --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/help.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +module IRB + module Command + class Help < Base + category "Help" + description "List all available commands. Use `help ` to get information about a specific command." + + def execute(command_name) + content = + if command_name.empty? + help_message + else + if command_class = Command.load_command(command_name) + command_class.help_message || command_class.description + else + "Can't find command `#{command_name}`. Please check the command name and try again.\n\n" + end + end + Pager.page_content(content) + end + + private + + def help_message + commands_info = IRB::Command.all_commands_info + helper_methods_info = IRB::HelperMethod.all_helper_methods_info + commands_grouped_by_categories = commands_info.group_by { |cmd| cmd[:category] } + commands_grouped_by_categories["Helper methods"] = helper_methods_info + + if irb_context.with_debugger + # Remove the original "Debugging" category + commands_grouped_by_categories.delete("Debugging") + end + + longest_cmd_name_length = commands_info.map { |c| c[:display_name].length }.max + + output = StringIO.new + + help_cmds = commands_grouped_by_categories.delete("Help") + no_category_cmds = commands_grouped_by_categories.delete("No category") + aliases = irb_context.instance_variable_get(:@command_aliases).map do |alias_name, target| + { display_name: alias_name, description: "Alias for `#{target}`" } + end + + # Display help commands first + add_category_to_output("Help", help_cmds, output, longest_cmd_name_length) + + # Display the rest of the commands grouped by categories + commands_grouped_by_categories.each do |category, cmds| + add_category_to_output(category, cmds, output, longest_cmd_name_length) + end + + # Display commands without a category + if no_category_cmds + add_category_to_output("No category", no_category_cmds, output, longest_cmd_name_length) + end + + # Display aliases + add_category_to_output("Aliases", aliases, output, longest_cmd_name_length) + + # Append the debugger help at the end + if irb_context.with_debugger + # Add "Debugging (from debug.gem)" category as title + add_category_to_output("Debugging (from debug.gem)", [], output, longest_cmd_name_length) + output.puts DEBUGGER__.help + end + + output.string + end + + def add_category_to_output(category, cmds, output, longest_cmd_name_length) + output.puts Color.colorize(category, [:BOLD]) + + cmds.each do |cmd| + output.puts " #{cmd[:display_name].to_s.ljust(longest_cmd_name_length)} #{cmd[:description]}" + end + + output.puts + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/history.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/history.rb new file mode 100644 index 00000000..e385c661 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/history.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require "stringio" + +require_relative "../pager" + +module IRB + # :stopdoc: + + module Command + class History < Base + category "IRB" + description "Shows the input history. `-g [query]` or `-G [query]` allows you to filter the output." + + def execute(arg) + + if (match = arg&.match(/(-g|-G)\s+(?.+)\s*\z/)) + grep = Regexp.new(match[:grep]) + end + + formatted_inputs = irb_context.io.class::HISTORY.each_with_index.reverse_each.filter_map do |input, index| + next if grep && !input.match?(grep) + + header = "#{index}: " + + first_line, *other_lines = input.split("\n") + first_line = "#{header}#{first_line}" + + truncated_lines = other_lines.slice!(1..) # Show 1 additional line (2 total) + other_lines << "..." if truncated_lines&.any? + + other_lines.map! do |line| + " " * header.length + line + end + + [first_line, *other_lines].join("\n") + "\n" + end + + Pager.page_content(formatted_inputs.join) + end + end + end + + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/info.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/info.rb new file mode 100644 index 00000000..d08ce00a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/info.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require_relative "debug" + +module IRB + # :stopdoc: + + module Command + class Info < DebugCommand + def execute(arg) + execute_debug_command(pre_cmds: "info #{arg}") + end + end + end + + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/internal_helpers.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/internal_helpers.rb new file mode 100644 index 00000000..a01ddb1d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/internal_helpers.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module IRB + module Command + # Internal use only, for default command's backward compatibility. + module RubyArgsExtractor # :nodoc: + def unwrap_string_literal(str) + return if str.empty? + + sexp = Ripper.sexp(str) + if sexp && sexp.size == 2 && sexp.last&.first&.first == :string_literal + @irb_context.workspace.binding.eval(str).to_s + else + str + end + end + + def ruby_args(arg) + # Use throw and catch to handle arg that includes `;` + # For example: "1, kw: (2; 3); 4" will be parsed to [[1], { kw: 3 }] + catch(:EXTRACT_RUBY_ARGS) do + @irb_context.workspace.binding.eval "::IRB::Command.extract_ruby_args #{arg}" + end || [[], {}] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/irb_info.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/irb_info.rb new file mode 100644 index 00000000..6d868de9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/irb_info.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +module IRB + # :stopdoc: + + module Command + class IrbInfo < Base + category "IRB" + description "Show information about IRB." + + def execute(_arg) + str = "Ruby version: #{RUBY_VERSION}\n" + str += "IRB version: #{IRB.version}\n" + str += "InputMethod: #{IRB.CurrentContext.io.inspect}\n" + str += "Completion: #{IRB.CurrentContext.io.respond_to?(:completion_info) ? IRB.CurrentContext.io.completion_info : 'off'}\n" + rc_files = IRB.irbrc_files + str += ".irbrc paths: #{rc_files.join(", ")}\n" if rc_files.any? + str += "RUBY_PLATFORM: #{RUBY_PLATFORM}\n" + str += "LANG env: #{ENV["LANG"]}\n" if ENV["LANG"] && !ENV["LANG"].empty? + str += "LC_ALL env: #{ENV["LC_ALL"]}\n" if ENV["LC_ALL"] && !ENV["LC_ALL"].empty? + str += "East Asian Ambiguous Width: #{Reline.ambiguous_width.inspect}\n" + if RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|cygwin|bccwin|wince|emc/ + codepage = `chcp`.b.sub(/.*: (\d+)\n/, '\1') + str += "Code page: #{codepage}\n" + end + puts str + nil + end + end + end + + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/load.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/load.rb new file mode 100644 index 00000000..1cd3f279 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/load.rb @@ -0,0 +1,91 @@ +# frozen_string_literal: true +# +# load.rb - +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# +require_relative "../ext/loader" + +module IRB + # :stopdoc: + + module Command + class LoaderCommand < Base + include RubyArgsExtractor + include IrbLoader + + def raise_cmd_argument_error + raise CommandArgumentError.new("Please specify the file name.") + end + end + + class Load < LoaderCommand + category "IRB" + description "Load a Ruby file." + + def execute(arg) + args, kwargs = ruby_args(arg) + execute_internal(*args, **kwargs) + end + + def execute_internal(file_name = nil, priv = nil) + raise_cmd_argument_error unless file_name + irb_load(file_name, priv) + end + end + + class Require < LoaderCommand + category "IRB" + description "Require a Ruby file." + + def execute(arg) + args, kwargs = ruby_args(arg) + execute_internal(*args, **kwargs) + end + + def execute_internal(file_name = nil) + raise_cmd_argument_error unless file_name + + rex = Regexp.new("#{Regexp.quote(file_name)}(\.o|\.rb)?") + return false if $".find{|f| f =~ rex} + + case file_name + when /\.rb$/ + begin + if irb_load(file_name) + $".push file_name + return true + end + rescue LoadError + end + when /\.(so|o|sl)$/ + return ruby_require(file_name) + end + + begin + irb_load(f = file_name + ".rb") + $".push f + return true + rescue LoadError + return ruby_require(file_name) + end + end + end + + class Source < LoaderCommand + category "IRB" + description "Loads a given file in the current session." + + def execute(arg) + args, kwargs = ruby_args(arg) + execute_internal(*args, **kwargs) + end + + def execute_internal(file_name = nil) + raise_cmd_argument_error unless file_name + + source_file(file_name) + end + end + end + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/ls.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/ls.rb new file mode 100644 index 00000000..944efd75 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/ls.rb @@ -0,0 +1,167 @@ +# frozen_string_literal: true + +require "reline" +require "stringio" + +require_relative "../pager" +require_relative "../color" + +module IRB + # :stopdoc: + + module Command + class Ls < Base + class EvaluationError < StandardError; end + + category "Context" + description "Show methods, constants, and variables." + + help_message <<~HELP_MESSAGE + Usage: ls [obj] [-g [query]] + + -g [query] Filter the output with a query. + HELP_MESSAGE + + def evaluate(code) + @irb_context.workspace.binding.eval(code) + rescue Exception => e + puts "#{e.class}: #{e.message}" + raise EvaluationError + end + + def execute(arg) + if match = arg.match(/\A(?.+\s|)(-g|-G)\s+(?.+)$/) + target = match[:target] + grep = Regexp.new(match[:grep]) + elsif match = arg.match(/\A((?.+),|)\s*grep:(?.+)/) + # Legacy style `ls obj, grep: /regexp/` + # Evaluation order should be eval(target) then eval(grep) + target = match[:target] || '' + grep_regexp_code = match[:grep] + else + target = arg.strip + end + + if target.empty? + obj = irb_context.workspace.main + locals = irb_context.workspace.binding.local_variables + else + obj = evaluate(target) + end + + if grep_regexp_code + grep = evaluate(grep_regexp_code) + end + + o = Output.new(grep: grep) + + klass = (obj.class == Class || obj.class == Module ? obj : obj.class) + + o.dump("constants", obj.constants) if obj.respond_to?(:constants) + dump_methods(o, klass, obj) + o.dump("instance variables", obj.instance_variables) + o.dump("class variables", klass.class_variables) + o.dump("locals", locals) if locals + o.print_result + rescue EvaluationError + end + + def dump_methods(o, klass, obj) + singleton_class = begin obj.singleton_class; rescue TypeError; nil end + dumped_mods = Array.new + ancestors = klass.ancestors + ancestors = ancestors.reject { |c| c >= Object } if klass < Object + singleton_ancestors = (singleton_class&.ancestors || []).reject { |c| c >= Class } + + # singleton_class' ancestors should be at the front + maps = class_method_map(singleton_ancestors, dumped_mods) + class_method_map(ancestors, dumped_mods) + maps.each do |mod, methods| + name = mod == singleton_class ? "#{klass}.methods" : "#{mod}#methods" + o.dump(name, methods) + end + end + + def class_method_map(classes, dumped_mods) + dumped_methods = Array.new + classes.map do |mod| + next if dumped_mods.include? mod + + dumped_mods << mod + + methods = mod.public_instance_methods(false).select do |method| + if dumped_methods.include? method + false + else + dumped_methods << method + true + end + end + + [mod, methods] + end.compact + end + + class Output + MARGIN = " " + + def initialize(grep: nil) + @grep = grep + @line_width = screen_width - MARGIN.length # right padding + @io = StringIO.new + end + + def print_result + Pager.page_content(@io.string) + end + + def dump(name, strs) + strs = strs.grep(@grep) if @grep + strs = strs.sort + return if strs.empty? + + # Attempt a single line + @io.print "#{Color.colorize(name, [:BOLD, :BLUE])}: " + if fits_on_line?(strs, cols: strs.size, offset: "#{name}: ".length) + @io.puts strs.join(MARGIN) + return + end + @io.puts + + # Dump with the largest # of columns that fits on a line + cols = strs.size + until fits_on_line?(strs, cols: cols, offset: MARGIN.length) || cols == 1 + cols -= 1 + end + widths = col_widths(strs, cols: cols) + strs.each_slice(cols) do |ss| + @io.puts ss.map.with_index { |s, i| "#{MARGIN}%-#{widths[i]}s" % s }.join + end + end + + private + + def fits_on_line?(strs, cols:, offset: 0) + width = col_widths(strs, cols: cols).sum + MARGIN.length * (cols - 1) + width <= @line_width - offset + end + + def col_widths(strs, cols:) + cols.times.map do |col| + (col...strs.size).step(cols).map do |i| + strs[i].length + end.max + end + end + + def screen_width + Reline.get_screen_size.last + rescue Errno::EINVAL # in `winsize': Invalid argument - + 80 + end + end + private_constant :Output + end + end + + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/measure.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/measure.rb new file mode 100644 index 00000000..f96be20d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/measure.rb @@ -0,0 +1,49 @@ +module IRB + # :stopdoc: + + module Command + class Measure < Base + include RubyArgsExtractor + + category "Misc" + description "`measure` enables the mode to measure processing time. `measure :off` disables it." + + def initialize(*args) + super(*args) + end + + def execute(arg) + if arg&.match?(/^do$|^do[^\w]|^\{/) + warn 'Configure IRB.conf[:MEASURE_PROC] to add custom measure methods.' + return + end + args, kwargs = ruby_args(arg) + execute_internal(*args, **kwargs) + end + + def execute_internal(type = nil, arg = nil) + # Please check IRB.init_config in lib/irb/init.rb that sets + # IRB.conf[:MEASURE_PROC] to register default "measure" methods, + # "measure :time" (abbreviated as "measure") and "measure :stackprof". + + case type + when :off + IRB.unset_measure_callback(arg) + when :list + IRB.conf[:MEASURE_CALLBACKS].each do |type_name, _, arg_val| + puts "- #{type_name}" + (arg_val ? "(#{arg_val.inspect})" : '') + end + when :on + added = IRB.set_measure_callback(arg) + puts "#{added[0]} is added." if added + else + added = IRB.set_measure_callback(type, arg) + puts "#{added[0]} is added." if added + end + nil + end + end + end + + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/next.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/next.rb new file mode 100644 index 00000000..3fc6b68d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/next.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require_relative "debug" + +module IRB + # :stopdoc: + + module Command + class Next < DebugCommand + def execute(arg) + execute_debug_command(do_cmds: "next #{arg}") + end + end + end + + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/pushws.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/pushws.rb new file mode 100644 index 00000000..b51928c6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/pushws.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true +# +# change-ws.rb - +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# + +require_relative "../ext/workspaces" + +module IRB + # :stopdoc: + + module Command + class Workspaces < Base + category "Workspace" + description "Show workspaces." + + def execute(_arg) + inspection_resuls = irb_context.instance_variable_get(:@workspace_stack).map do |ws| + truncated_inspect(ws.main) + end + + puts "[" + inspection_resuls.join(", ") + "]" + end + + private + + def truncated_inspect(obj) + obj_inspection = obj.inspect + + if obj_inspection.size > 20 + obj_inspection = obj_inspection[0, 19] + "...>" + end + + obj_inspection + end + end + + class PushWorkspace < Workspaces + category "Workspace" + description "Push an object to the workspace stack." + + def execute(arg) + if arg.empty? + irb_context.push_workspace + else + obj = eval(arg, irb_context.workspace.binding) + irb_context.push_workspace(obj) + end + super + end + end + + class PopWorkspace < Workspaces + category "Workspace" + description "Pop a workspace from the workspace stack." + + def execute(_arg) + irb_context.pop_workspace + super + end + end + end + + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/show_doc.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/show_doc.rb new file mode 100644 index 00000000..8a2188e4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/show_doc.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module IRB + module Command + class ShowDoc < Base + include RubyArgsExtractor + + category "Context" + description "Look up documentation with RI." + + help_message <<~HELP_MESSAGE + Usage: show_doc [name] + + When name is provided, IRB will look up the documentation for the given name. + When no name is provided, a RI session will be started. + + Examples: + + show_doc + show_doc Array + show_doc Array#each + + HELP_MESSAGE + + def execute(arg) + # Accept string literal for backward compatibility + name = unwrap_string_literal(arg) + require 'rdoc/ri/driver' + + unless ShowDoc.const_defined?(:Ri) + opts = RDoc::RI::Driver.process_args([]) + ShowDoc.const_set(:Ri, RDoc::RI::Driver.new(opts)) + end + + if name.nil? + Ri.interactive + else + begin + Ri.display_name(name) + rescue RDoc::RI::Error + puts $!.message + end + end + + nil + rescue LoadError, SystemExit + warn "Can't display document because `rdoc` is not installed." + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/show_source.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/show_source.rb new file mode 100644 index 00000000..f4c6f104 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/show_source.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +require_relative "../source_finder" +require_relative "../pager" +require_relative "../color" + +module IRB + module Command + class ShowSource < Base + include RubyArgsExtractor + + category "Context" + description "Show the source code of a given method, class/module, or constant." + + help_message <<~HELP_MESSAGE + Usage: show_source [target] [-s] + + -s Show the super method. You can stack it like `-ss` to show the super of the super, etc. + + Examples: + + show_source Foo + show_source Foo#bar + show_source Foo#bar -s + show_source Foo.baz + show_source Foo::BAR + HELP_MESSAGE + + def execute(arg) + # Accept string literal for backward compatibility + str = unwrap_string_literal(arg) + unless str.is_a?(String) + puts "Error: Expected a string but got #{str.inspect}" + return + end + + str, esses = str.split(" -") + super_level = esses ? esses.count("s") : 0 + source = SourceFinder.new(@irb_context).find_source(str, super_level) + + if source + show_source(source) + elsif super_level > 0 + puts "Error: Couldn't locate a super definition for #{str}" + else + puts "Error: Couldn't locate a definition for #{str}" + end + nil + end + + private + + def show_source(source) + if source.binary_file? + content = "\n#{bold('Defined in binary file')}: #{source.file}\n\n" + else + code = source.colorized_content || 'Source not available' + content = <<~CONTENT + + #{bold("From")}: #{source.file}:#{source.line} + + #{code.chomp} + + CONTENT + end + Pager.page_content(content) + end + + def bold(str) + Color.colorize(str, [:BOLD]) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/step.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/step.rb new file mode 100644 index 00000000..29e5e35a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/step.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require_relative "debug" + +module IRB + # :stopdoc: + + module Command + class Step < DebugCommand + def execute(arg) + execute_debug_command(do_cmds: "step #{arg}") + end + end + end + + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/subirb.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/subirb.rb new file mode 100644 index 00000000..85af28c1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/subirb.rb @@ -0,0 +1,123 @@ +# frozen_string_literal: true +# +# multi.rb - +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# + +module IRB + # :stopdoc: + + module Command + class MultiIRBCommand < Base + include RubyArgsExtractor + + private + + def print_deprecated_warning + warn <<~MSG + Multi-irb commands are deprecated and will be removed in IRB 2.0.0. Please use workspace commands instead. + If you have any use case for multi-irb, please leave a comment at https://github.com/ruby/irb/issues/653 + MSG + end + + def extend_irb_context + # this extension patches IRB context like IRB.CurrentContext + require_relative "../ext/multi-irb" + end + + def print_debugger_warning + warn "Multi-IRB commands are not available when the debugger is enabled." + end + end + + class IrbCommand < MultiIRBCommand + category "Multi-irb (DEPRECATED)" + description "Start a child IRB." + + def execute(arg) + args, kwargs = ruby_args(arg) + execute_internal(*args, **kwargs) + end + + def execute_internal(*obj) + print_deprecated_warning + + if irb_context.with_debugger + print_debugger_warning + return + end + + extend_irb_context + IRB.irb(nil, *obj) + puts IRB.JobManager.inspect + end + end + + class Jobs < MultiIRBCommand + category "Multi-irb (DEPRECATED)" + description "List of current sessions." + + def execute(_arg) + print_deprecated_warning + + if irb_context.with_debugger + print_debugger_warning + return + end + + extend_irb_context + puts IRB.JobManager.inspect + end + end + + class Foreground < MultiIRBCommand + category "Multi-irb (DEPRECATED)" + description "Switches to the session of the given number." + + def execute(arg) + args, kwargs = ruby_args(arg) + execute_internal(*args, **kwargs) + end + + def execute_internal(key = nil) + print_deprecated_warning + + if irb_context.with_debugger + print_debugger_warning + return + end + + extend_irb_context + + raise CommandArgumentError.new("Please specify the id of target IRB job (listed in the `jobs` command).") unless key + IRB.JobManager.switch(key) + puts IRB.JobManager.inspect + end + end + + class Kill < MultiIRBCommand + category "Multi-irb (DEPRECATED)" + description "Kills the session with the given number." + + def execute(arg) + args, kwargs = ruby_args(arg) + execute_internal(*args, **kwargs) + end + + def execute_internal(*keys) + print_deprecated_warning + + if irb_context.with_debugger + print_debugger_warning + return + end + + extend_irb_context + IRB.JobManager.kill(*keys) + puts IRB.JobManager.inspect + end + end + end + + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/whereami.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/whereami.rb new file mode 100644 index 00000000..c8439f12 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/command/whereami.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module IRB + # :stopdoc: + + module Command + class Whereami < Base + category "Context" + description "Show the source code around binding.irb again." + + def execute(_arg) + code = irb_context.workspace.code_around_binding + if code + puts code + else + puts "The current context doesn't have code." + end + end + end + end + + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/completion.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/completion.rb new file mode 100644 index 00000000..3e970470 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/completion.rb @@ -0,0 +1,504 @@ +# frozen_string_literal: true +# +# irb/completion.rb - +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# From Original Idea of shugo@ruby-lang.org +# + +require_relative 'ruby-lex' + +module IRB + class BaseCompletor # :nodoc: + + # Set of reserved words used by Ruby, you should not use these for + # constants or variables + ReservedWords = %w[ + __ENCODING__ __LINE__ __FILE__ + BEGIN END + alias and + begin break + case class + def defined? do + else elsif end ensure + false for + if in + module + next nil not + or + redo rescue retry return + self super + then true + undef unless until + when while + yield + ] + + HELP_COMMAND_PREPOSING = /\Ahelp\s+/ + + def completion_candidates(preposing, target, postposing, bind:) + raise NotImplementedError + end + + def doc_namespace(preposing, matched, postposing, bind:) + raise NotImplementedError + end + + GEM_PATHS = + if defined?(Gem::Specification) + Gem::Specification.latest_specs(true).map { |s| + s.require_paths.map { |p| + if File.absolute_path?(p) + p + else + File.join(s.full_gem_path, p) + end + } + }.flatten + else + [] + end.freeze + + def retrieve_gem_and_system_load_path + candidates = (GEM_PATHS | $LOAD_PATH) + candidates.map do |p| + if p.respond_to?(:to_path) + p.to_path + else + String(p) rescue nil + end + end.compact.sort + end + + def retrieve_files_to_require_from_load_path + @files_from_load_path ||= + ( + shortest = [] + rest = retrieve_gem_and_system_load_path.each_with_object([]) { |path, result| + begin + names = Dir.glob("**/*.{rb,#{RbConfig::CONFIG['DLEXT']}}", base: path) + rescue Errno::ENOENT + nil + end + next if names.empty? + names.map! { |n| n.sub(/\.(rb|#{RbConfig::CONFIG['DLEXT']})\z/, '') }.sort! + shortest << names.shift + result.concat(names) + } + shortest.sort! | rest + ) + end + + def command_candidates(target) + if !target.empty? + IRB::Command.command_names.select { _1.start_with?(target) } + else + [] + end + end + + def retrieve_files_to_require_relative_from_current_dir + @files_from_current_dir ||= Dir.glob("**/*.{rb,#{RbConfig::CONFIG['DLEXT']}}", base: '.').map { |path| + path.sub(/\.(rb|#{RbConfig::CONFIG['DLEXT']})\z/, '') + } + end + end + + class TypeCompletor < BaseCompletor # :nodoc: + def initialize(context) + @context = context + end + + def inspect + ReplTypeCompletor.info + end + + def completion_candidates(preposing, target, _postposing, bind:) + # When completing the argument of `help` command, only commands should be candidates + return command_candidates(target) if preposing.match?(HELP_COMMAND_PREPOSING) + + commands = if preposing.empty? + command_candidates(target) + # It doesn't make sense to propose commands with other preposing + else + [] + end + + result = ReplTypeCompletor.analyze(preposing + target, binding: bind, filename: @context.irb_path) + + return commands unless result + + commands | result.completion_candidates.map { target + _1 } + end + + def doc_namespace(preposing, matched, _postposing, bind:) + result = ReplTypeCompletor.analyze(preposing + matched, binding: bind, filename: @context.irb_path) + result&.doc_namespace('') + end + end + + class RegexpCompletor < BaseCompletor # :nodoc: + KERNEL_METHODS = ::Kernel.instance_method(:methods) + KERNEL_PRIVATE_METHODS = ::Kernel.instance_method(:private_methods) + KERNEL_INSTANCE_VARIABLES = ::Kernel.instance_method(:instance_variables) + OBJECT_CLASS_INSTANCE_METHOD = ::Object.instance_method(:class) + MODULE_CONSTANTS_INSTANCE_METHOD = ::Module.instance_method(:constants) + + using Module.new { + refine ::Binding do + def eval_methods + KERNEL_METHODS.bind_call(receiver) + end + + def eval_private_methods + KERNEL_PRIVATE_METHODS.bind_call(receiver) + end + + def eval_instance_variables + KERNEL_INSTANCE_VARIABLES.bind_call(receiver) + end + + def eval_global_variables + ::Kernel.global_variables + end + + def eval_class_constants + klass = OBJECT_CLASS_INSTANCE_METHOD.bind_call(receiver) + MODULE_CONSTANTS_INSTANCE_METHOD.bind_call(klass) + end + end + } + + def inspect + 'RegexpCompletor' + end + + def complete_require_path(target, preposing, postposing) + if target =~ /\A(['"])([^'"]+)\Z/ + quote = $1 + actual_target = $2 + else + return nil # It's not String literal + end + tokens = RubyLex.ripper_lex_without_warning(preposing.gsub(/\s*\z/, '')) + tok = nil + tokens.reverse_each do |t| + unless [:on_lparen, :on_sp, :on_ignored_sp, :on_nl, :on_ignored_nl, :on_comment].include?(t.event) + tok = t + break + end + end + return unless tok&.event == :on_ident && tok.state == Ripper::EXPR_CMDARG + + case tok.tok + when 'require' + retrieve_files_to_require_from_load_path.select { |path| + path.start_with?(actual_target) + }.map { |path| + quote + path + } + when 'require_relative' + retrieve_files_to_require_relative_from_current_dir.select { |path| + path.start_with?(actual_target) + }.map { |path| + quote + path + } + end + end + + def completion_candidates(preposing, target, postposing, bind:) + if result = complete_require_path(target, preposing, postposing) + return result + end + + commands = command_candidates(target) + + # When completing the argument of `help` command, only commands should be candidates + return commands if preposing.match?(HELP_COMMAND_PREPOSING) + + # It doesn't make sense to propose commands with other preposing + commands = [] unless preposing.empty? + + completion_data = retrieve_completion_data(target, bind: bind, doc_namespace: false).compact.map{ |i| i.encode(Encoding.default_external) } + commands | completion_data + end + + def doc_namespace(_preposing, matched, _postposing, bind:) + retrieve_completion_data(matched, bind: bind, doc_namespace: true) + end + + def retrieve_completion_data(input, bind:, doc_namespace:) + case input + # this regexp only matches the closing character because of irb's Reline.completer_quote_characters setting + # details are described in: https://github.com/ruby/irb/pull/523 + when /^(.*["'`])\.([^.]*)$/ + # String + receiver = $1 + message = $2 + + if doc_namespace + "String.#{message}" + else + candidates = String.instance_methods.collect{|m| m.to_s} + select_message(receiver, message, candidates) + end + + # this regexp only matches the closing character because of irb's Reline.completer_quote_characters setting + # details are described in: https://github.com/ruby/irb/pull/523 + when /^(.*\/)\.([^.]*)$/ + # Regexp + receiver = $1 + message = $2 + + if doc_namespace + "Regexp.#{message}" + else + candidates = Regexp.instance_methods.collect{|m| m.to_s} + select_message(receiver, message, candidates) + end + + when /^([^\]]*\])\.([^.]*)$/ + # Array + receiver = $1 + message = $2 + + if doc_namespace + "Array.#{message}" + else + candidates = Array.instance_methods.collect{|m| m.to_s} + select_message(receiver, message, candidates) + end + + when /^([^\}]*\})\.([^.]*)$/ + # Hash or Proc + receiver = $1 + message = $2 + + if doc_namespace + ["Hash.#{message}", "Proc.#{message}"] + else + hash_candidates = Hash.instance_methods.collect{|m| m.to_s} + proc_candidates = Proc.instance_methods.collect{|m| m.to_s} + select_message(receiver, message, hash_candidates | proc_candidates) + end + + when /^(:[^:.]+)$/ + # Symbol + if doc_namespace + nil + else + sym = $1 + candidates = Symbol.all_symbols.collect do |s| + s.inspect + rescue EncodingError + # ignore + end + candidates.grep(/^#{Regexp.quote(sym)}/) + end + when /^::([A-Z][^:\.\(\)]*)$/ + # Absolute Constant or class methods + receiver = $1 + + candidates = Object.constants.collect{|m| m.to_s} + + if doc_namespace + candidates.find { |i| i == receiver } + else + candidates.grep(/^#{Regexp.quote(receiver)}/).collect{|e| "::" + e} + end + + when /^([A-Z].*)::([^:.]*)$/ + # Constant or class methods + receiver = $1 + message = $2 + + if doc_namespace + "#{receiver}::#{message}" + else + begin + candidates = eval("#{receiver}.constants.collect{|m| m.to_s}", bind) + candidates |= eval("#{receiver}.methods.collect{|m| m.to_s}", bind) + rescue Exception + candidates = [] + end + + select_message(receiver, message, candidates.sort, "::") + end + + when /^(:[^:.]+)(\.|::)([^.]*)$/ + # Symbol + receiver = $1 + sep = $2 + message = $3 + + if doc_namespace + "Symbol.#{message}" + else + candidates = Symbol.instance_methods.collect{|m| m.to_s} + select_message(receiver, message, candidates, sep) + end + + when /^(?-?(?:0[dbo])?[0-9_]+(?:\.[0-9_]+)?(?:(?:[eE][+-]?[0-9]+)?i?|r)?)(?\.|::)(?[^.]*)$/ + # Numeric + receiver = $~[:num] + sep = $~[:sep] + message = $~[:mes] + + begin + instance = eval(receiver, bind) + + if doc_namespace + "#{instance.class.name}.#{message}" + else + candidates = instance.methods.collect{|m| m.to_s} + select_message(receiver, message, candidates, sep) + end + rescue Exception + if doc_namespace + nil + else + [] + end + end + + when /^(-?0x[0-9a-fA-F_]+)(\.|::)([^.]*)$/ + # Numeric(0xFFFF) + receiver = $1 + sep = $2 + message = $3 + + begin + instance = eval(receiver, bind) + if doc_namespace + "#{instance.class.name}.#{message}" + else + candidates = instance.methods.collect{|m| m.to_s} + select_message(receiver, message, candidates, sep) + end + rescue Exception + if doc_namespace + nil + else + [] + end + end + + when /^(\$[^.]*)$/ + # global var + gvar = $1 + all_gvars = global_variables.collect{|m| m.to_s} + + if doc_namespace + all_gvars.find{ |i| i == gvar } + else + all_gvars.grep(Regexp.new(Regexp.quote(gvar))) + end + + when /^([^.:"].*)(\.|::)([^.]*)$/ + # variable.func or func.func + receiver = $1 + sep = $2 + message = $3 + + gv = bind.eval_global_variables.collect{|m| m.to_s}.push("true", "false", "nil") + lv = bind.local_variables.collect{|m| m.to_s} + iv = bind.eval_instance_variables.collect{|m| m.to_s} + cv = bind.eval_class_constants.collect{|m| m.to_s} + + if (gv | lv | iv | cv).include?(receiver) or /^[A-Z]/ =~ receiver && /\./ !~ receiver + # foo.func and foo is var. OR + # foo::func and foo is var. OR + # foo::Const and foo is var. OR + # Foo::Bar.func + begin + candidates = [] + rec = eval(receiver, bind) + if sep == "::" and rec.kind_of?(Module) + candidates = rec.constants.collect{|m| m.to_s} + end + candidates |= rec.methods.collect{|m| m.to_s} + rescue Exception + candidates = [] + end + else + # func1.func2 + candidates = [] + end + + if doc_namespace + rec_class = rec.is_a?(Module) ? rec : rec.class + "#{rec_class.name}#{sep}#{candidates.find{ |i| i == message }}" rescue nil + else + select_message(receiver, message, candidates, sep) + end + + when /^\.([^.]*)$/ + # unknown(maybe String) + + receiver = "" + message = $1 + + candidates = String.instance_methods(true).collect{|m| m.to_s} + + if doc_namespace + "String.#{candidates.find{ |i| i == message }}" + else + select_message(receiver, message, candidates.sort) + end + when /^\s*$/ + # empty input + if doc_namespace + nil + else + [] + end + else + if doc_namespace + vars = (bind.local_variables | bind.eval_instance_variables).collect{|m| m.to_s} + perfect_match_var = vars.find{|m| m.to_s == input} + if perfect_match_var + eval("#{perfect_match_var}.class.name", bind) rescue nil + else + candidates = (bind.eval_methods | bind.eval_private_methods | bind.local_variables | bind.eval_instance_variables | bind.eval_class_constants).collect{|m| m.to_s} + candidates |= ReservedWords + candidates.find{ |i| i == input } + end + else + candidates = (bind.eval_methods | bind.eval_private_methods | bind.local_variables | bind.eval_instance_variables | bind.eval_class_constants).collect{|m| m.to_s} + candidates |= ReservedWords + candidates.grep(/^#{Regexp.quote(input)}/).sort + end + end + end + + # Set of available operators in Ruby + Operators = %w[% & * ** + - / < << <= <=> == === =~ > >= >> [] []= ^ ! != !~] + + def select_message(receiver, message, candidates, sep = ".") + candidates.grep(/^#{Regexp.quote(message)}/).collect do |e| + case e + when /^[a-zA-Z_]/ + receiver + sep + e + when /^[0-9]/ + when *Operators + #receiver + " " + e + end + end + end + end + + module InputCompletor + class << self + private def regexp_completor + @regexp_completor ||= RegexpCompletor.new + end + + def retrieve_completion_data(input, bind: IRB.conf[:MAIN_CONTEXT].workspace.binding, doc_namespace: false) + regexp_completor.retrieve_completion_data(input, bind: bind, doc_namespace: doc_namespace) + end + end + CompletionProc = ->(target, preposing = nil, postposing = nil) { + regexp_completor.completion_candidates(preposing || '', target, postposing || '', bind: IRB.conf[:MAIN_CONTEXT].workspace.binding) + } + end + deprecate_constant :InputCompletor +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/context.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/context.rb new file mode 100644 index 00000000..395d9081 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/context.rb @@ -0,0 +1,751 @@ +# frozen_string_literal: true +# +# irb/context.rb - irb context +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# + +require_relative "workspace" +require_relative "inspector" +require_relative "input-method" +require_relative "output-method" + +module IRB + # A class that wraps the current state of the irb session, including the + # configuration of IRB.conf. + class Context + KERNEL_PUBLIC_METHOD = ::Kernel.instance_method(:public_method) + KERNEL_METHOD = ::Kernel.instance_method(:method) + + ASSIGN_OPERATORS_REGEXP = Regexp.union(%w[= += -= *= /= %= **= &= |= &&= ||= ^= <<= >>=]) + # Creates a new IRB context. + # + # The optional +input_method+ argument: + # + # +nil+:: uses stdin or Reline or Readline + # +String+:: uses a File + # +other+:: uses this as InputMethod + def initialize(irb, workspace = nil, input_method = nil) + @irb = irb + @workspace_stack = [] + if workspace + @workspace_stack << workspace + else + @workspace_stack << WorkSpace.new + end + @thread = Thread.current + + # copy of default configuration + @ap_name = IRB.conf[:AP_NAME] + @rc = IRB.conf[:RC] + @load_modules = IRB.conf[:LOAD_MODULES] + + if IRB.conf.has_key?(:USE_SINGLELINE) + @use_singleline = IRB.conf[:USE_SINGLELINE] + elsif IRB.conf.has_key?(:USE_READLINE) # backward compatibility + @use_singleline = IRB.conf[:USE_READLINE] + else + @use_singleline = nil + end + if IRB.conf.has_key?(:USE_MULTILINE) + @use_multiline = IRB.conf[:USE_MULTILINE] + elsif IRB.conf.has_key?(:USE_RELINE) # backward compatibility + warn <<~MSG.strip + USE_RELINE is deprecated, please use USE_MULTILINE instead. + MSG + @use_multiline = IRB.conf[:USE_RELINE] + elsif IRB.conf.has_key?(:USE_REIDLINE) + warn <<~MSG.strip + USE_REIDLINE is deprecated, please use USE_MULTILINE instead. + MSG + @use_multiline = IRB.conf[:USE_REIDLINE] + else + @use_multiline = nil + end + @use_autocomplete = IRB.conf[:USE_AUTOCOMPLETE] + @verbose = IRB.conf[:VERBOSE] + @io = nil + + self.inspect_mode = IRB.conf[:INSPECT_MODE] + self.use_tracer = IRB.conf[:USE_TRACER] + self.use_loader = IRB.conf[:USE_LOADER] if IRB.conf[:USE_LOADER] + self.eval_history = IRB.conf[:EVAL_HISTORY] if IRB.conf[:EVAL_HISTORY] + + @ignore_sigint = IRB.conf[:IGNORE_SIGINT] + @ignore_eof = IRB.conf[:IGNORE_EOF] + + @back_trace_limit = IRB.conf[:BACK_TRACE_LIMIT] + + self.prompt_mode = IRB.conf[:PROMPT_MODE] + + @irb_name = IRB.conf[:IRB_NAME] + + unless IRB.conf[:SINGLE_IRB] or !defined?(IRB::JobManager) + @irb_name = @irb_name + "#" + IRB.JobManager.n_jobs.to_s + end + + self.irb_path = "(" + @irb_name + ")" + + case input_method + when nil + @io = nil + case use_multiline? + when nil + if term_interactive? && IRB.conf[:PROMPT_MODE] != :INF_RUBY && !use_singleline? + # Both of multiline mode and singleline mode aren't specified. + @io = RelineInputMethod.new(build_completor) + else + @io = nil + end + when false + @io = nil + when true + @io = RelineInputMethod.new(build_completor) + end + unless @io + case use_singleline? + when nil + if (defined?(ReadlineInputMethod) && term_interactive? && + IRB.conf[:PROMPT_MODE] != :INF_RUBY) + @io = ReadlineInputMethod.new + else + @io = nil + end + when false + @io = nil + when true + if defined?(ReadlineInputMethod) + @io = ReadlineInputMethod.new + else + @io = nil + end + else + @io = nil + end + end + @io = StdioInputMethod.new unless @io + + when '-' + @io = FileInputMethod.new($stdin) + @irb_name = '-' + self.irb_path = '-' + when String + @io = FileInputMethod.new(input_method) + @irb_name = File.basename(input_method) + self.irb_path = input_method + else + @io = input_method + end + @extra_doc_dirs = IRB.conf[:EXTRA_DOC_DIRS] + + @echo = IRB.conf[:ECHO] + if @echo.nil? + @echo = true + end + + @echo_on_assignment = IRB.conf[:ECHO_ON_ASSIGNMENT] + if @echo_on_assignment.nil? + @echo_on_assignment = :truncate + end + + @newline_before_multiline_output = IRB.conf[:NEWLINE_BEFORE_MULTILINE_OUTPUT] + if @newline_before_multiline_output.nil? + @newline_before_multiline_output = true + end + + @command_aliases = IRB.conf[:COMMAND_ALIASES].dup + end + + def use_tracer=(val) + require_relative "ext/tracer" if val + IRB.conf[:USE_TRACER] = val + end + + def eval_history=(val) + self.class.remove_method(__method__) + require_relative "ext/eval_history" + __send__(__method__, val) + end + + def use_loader=(val) + self.class.remove_method(__method__) + require_relative "ext/use-loader" + __send__(__method__, val) + end + + def save_history=(val) + IRB.conf[:SAVE_HISTORY] = val + end + + def save_history + IRB.conf[:SAVE_HISTORY] + end + + # A copy of the default IRB.conf[:HISTORY_FILE] + def history_file + IRB.conf[:HISTORY_FILE] + end + + # Set IRB.conf[:HISTORY_FILE] to the given +hist+. + def history_file=(hist) + IRB.conf[:HISTORY_FILE] = hist + end + + # Workspace in the current context. + def workspace + @workspace_stack.last + end + + # Replace the current workspace with the given +workspace+. + def replace_workspace(workspace) + @workspace_stack.pop + @workspace_stack.push(workspace) + end + + # The top-level workspace, see WorkSpace#main + def main + workspace.main + end + + # The toplevel workspace, see #home_workspace + attr_reader :workspace_home + # The current thread in this context. + attr_reader :thread + # The current input method. + # + # Can be either StdioInputMethod, ReadlineInputMethod, + # RelineInputMethod, FileInputMethod or other specified when the + # context is created. See ::new for more # information on +input_method+. + attr_accessor :io + + # Current irb session. + attr_accessor :irb + # A copy of the default IRB.conf[:AP_NAME] + attr_accessor :ap_name + # A copy of the default IRB.conf[:RC] + attr_accessor :rc + # A copy of the default IRB.conf[:LOAD_MODULES] + attr_accessor :load_modules + # Can be either name from IRB.conf[:IRB_NAME], or the number of + # the current job set by JobManager, such as irb#2 + attr_accessor :irb_name + + # Can be one of the following: + # - the #irb_name surrounded by parenthesis + # - the +input_method+ passed to Context.new + # - the file path of the current IRB context in a binding.irb session + attr_reader :irb_path + + # Sets @irb_path to the given +path+ as well as @eval_path + # @eval_path is used for evaluating code in the context of IRB session + # It's the same as irb_path, but with the IRB name postfix + # This makes sure users can distinguish the methods defined in the IRB session + # from the methods defined in the current file's context, especially with binding.irb + def irb_path=(path) + @irb_path = path + + if File.exist?(path) + @eval_path = "#{path}(#{IRB.conf[:IRB_NAME]})" + else + @eval_path = path + end + end + + # Whether multiline editor mode is enabled or not. + # + # A copy of the default IRB.conf[:USE_MULTILINE] + attr_reader :use_multiline + # Whether singleline editor mode is enabled or not. + # + # A copy of the default IRB.conf[:USE_SINGLELINE] + attr_reader :use_singleline + # Whether colorization is enabled or not. + # + # A copy of the default IRB.conf[:USE_AUTOCOMPLETE] + attr_reader :use_autocomplete + # A copy of the default IRB.conf[:INSPECT_MODE] + attr_reader :inspect_mode + # Inspector for the current context + attr_reader :inspect_method + + # A copy of the default IRB.conf[:PROMPT_MODE] + attr_reader :prompt_mode + # Standard IRB prompt. + # + # See {Custom Prompts}[rdoc-ref:IRB@Custom+Prompts] for more information. + attr_accessor :prompt_i + # IRB prompt for continuated strings. + # + # See {Custom Prompts}[rdoc-ref:IRB@Custom+Prompts] for more information. + attr_accessor :prompt_s + # IRB prompt for continuated statement. (e.g. immediately after an +if+) + # + # See {Custom Prompts}[rdoc-ref:IRB@Custom+Prompts] for more information. + attr_accessor :prompt_c + + # TODO: Remove this when developing v2.0 + def prompt_n + warn "IRB::Context#prompt_n is deprecated and will be removed in the next major release." + "" + end + + # TODO: Remove this when developing v2.0 + def prompt_n=(_) + warn "IRB::Context#prompt_n= is deprecated and will be removed in the next major release." + "" + end + + # Can be either the default IRB.conf[:AUTO_INDENT], or the + # mode set by #prompt_mode= + # + # To disable auto-indentation in irb: + # + # IRB.conf[:AUTO_INDENT] = false + # + # or + # + # irb_context.auto_indent_mode = false + # + # or + # + # IRB.CurrentContext.auto_indent_mode = false + # + # See IRB@Configuration for more information. + attr_accessor :auto_indent_mode + # The format of the return statement, set by #prompt_mode= using the + # +:RETURN+ of the +mode+ passed to set the current #prompt_mode. + attr_accessor :return_format + + # Whether ^C (+control-c+) will be ignored or not. + # + # If set to +false+, ^C will quit irb. + # + # If set to +true+, + # + # * during input: cancel input then return to top level. + # * during execute: abandon current execution. + attr_accessor :ignore_sigint + # Whether ^D (+control-d+) will be ignored or not. + # + # If set to +false+, ^D will quit irb. + attr_accessor :ignore_eof + # Specify the installation locations of the ri file to be displayed in the + # document dialog. + attr_accessor :extra_doc_dirs + # Whether to echo the return value to output or not. + # + # Uses IRB.conf[:ECHO] if available, or defaults to +true+. + # + # puts "hello" + # # hello + # #=> nil + # IRB.CurrentContext.echo = false + # puts "omg" + # # omg + attr_accessor :echo + # Whether to echo for assignment expressions. + # + # If set to +false+, the value of assignment will not be shown. + # + # If set to +true+, the value of assignment will be shown. + # + # If set to +:truncate+, the value of assignment will be shown and truncated. + # + # It defaults to +:truncate+. + # + # a = "omg" + # #=> omg + # + # a = "omg" * 10 + # #=> omgomgomgomgomgomgomg... + # + # IRB.CurrentContext.echo_on_assignment = false + # a = "omg" + # + # IRB.CurrentContext.echo_on_assignment = true + # a = "omg" * 10 + # #=> omgomgomgomgomgomgomgomgomgomg + # + # To set the behaviour of showing on assignment in irb: + # + # IRB.conf[:ECHO_ON_ASSIGNMENT] = :truncate or true or false + # + # or + # + # irb_context.echo_on_assignment = :truncate or true or false + # + # or + # + # IRB.CurrentContext.echo_on_assignment = :truncate or true or false + attr_accessor :echo_on_assignment + # Whether a newline is put before multiline output. + # + # Uses IRB.conf[:NEWLINE_BEFORE_MULTILINE_OUTPUT] if available, + # or defaults to +true+. + # + # "abc\ndef" + # #=> + # abc + # def + # IRB.CurrentContext.newline_before_multiline_output = false + # "abc\ndef" + # #=> abc + # def + attr_accessor :newline_before_multiline_output + # Whether verbose messages are displayed or not. + # + # A copy of the default IRB.conf[:VERBOSE] + attr_accessor :verbose + + # The limit of backtrace lines displayed as top +n+ and tail +n+. + # + # The default value is 16. + # + # Can also be set using the +--back-trace-limit+ command line option. + attr_accessor :back_trace_limit + + # User-defined IRB command aliases + attr_accessor :command_aliases + + attr_accessor :with_debugger + + # Alias for #use_multiline + alias use_multiline? use_multiline + # Alias for #use_singleline + alias use_singleline? use_singleline + # backward compatibility + alias use_reline use_multiline + # backward compatibility + alias use_reline? use_multiline + # backward compatibility + alias use_readline use_singleline + # backward compatibility + alias use_readline? use_singleline + # Alias for #use_autocomplete + alias use_autocomplete? use_autocomplete + # Alias for #rc + alias rc? rc + alias ignore_sigint? ignore_sigint + alias ignore_eof? ignore_eof + alias echo? echo + alias echo_on_assignment? echo_on_assignment + alias newline_before_multiline_output? newline_before_multiline_output + + # Returns whether messages are displayed or not. + def verbose? + if @verbose.nil? + if @io.kind_of?(RelineInputMethod) + false + elsif defined?(ReadlineInputMethod) && @io.kind_of?(ReadlineInputMethod) + false + elsif !STDIN.tty? or @io.kind_of?(FileInputMethod) + true + else + false + end + else + @verbose + end + end + + # Whether #verbose? is +true+, and +input_method+ is either + # StdioInputMethod or RelineInputMethod or ReadlineInputMethod, see #io + # for more information. + def prompting? + verbose? || @io.prompting? + end + + # The return value of the last statement evaluated. + attr_reader :last_value + + # Sets the return value from the last statement evaluated in this context + # to #last_value. + def set_last_value(value) + @last_value = value + workspace.local_variable_set :_, value + end + + # Sets the +mode+ of the prompt in this context. + # + # See {Custom Prompts}[rdoc-ref:IRB@Custom+Prompts] for more information. + def prompt_mode=(mode) + @prompt_mode = mode + pconf = IRB.conf[:PROMPT][mode] + @prompt_i = pconf[:PROMPT_I] + @prompt_s = pconf[:PROMPT_S] + @prompt_c = pconf[:PROMPT_C] + @return_format = pconf[:RETURN] + @return_format = "%s\n" if @return_format == nil + if ai = pconf.include?(:AUTO_INDENT) + @auto_indent_mode = ai + else + @auto_indent_mode = IRB.conf[:AUTO_INDENT] + end + end + + # Whether #inspect_mode is set or not, see #inspect_mode= for more detail. + def inspect? + @inspect_mode.nil? or @inspect_mode + end + + # Whether #io uses a File for the +input_method+ passed when creating the + # current context, see ::new + def file_input? + @io.class == FileInputMethod + end + + # Specifies the inspect mode with +opt+: + # + # +true+:: display +inspect+ + # +false+:: display +to_s+ + # +nil+:: inspect mode in non-math mode, + # non-inspect mode in math mode + # + # See IRB::Inspector for more information. + # + # Can also be set using the +--inspect+ and +--noinspect+ command line + # options. + def inspect_mode=(opt) + + if i = Inspector::INSPECTORS[opt] + @inspect_mode = opt + @inspect_method = i + i.init + else + case opt + when nil + if Inspector.keys_with_inspector(Inspector::INSPECTORS[true]).include?(@inspect_mode) + self.inspect_mode = false + elsif Inspector.keys_with_inspector(Inspector::INSPECTORS[false]).include?(@inspect_mode) + self.inspect_mode = true + else + puts "Can't switch inspect mode." + return + end + when /^\s*\{.*\}\s*$/ + begin + inspector = eval "proc#{opt}" + rescue Exception + puts "Can't switch inspect mode(#{opt})." + return + end + self.inspect_mode = inspector + when Proc + self.inspect_mode = IRB::Inspector(opt) + when Inspector + prefix = "usr%d" + i = 1 + while Inspector::INSPECTORS[format(prefix, i)]; i += 1; end + @inspect_mode = format(prefix, i) + @inspect_method = opt + Inspector.def_inspector(format(prefix, i), @inspect_method) + else + puts "Can't switch inspect mode(#{opt})." + return + end + end + print "Switch to#{unless @inspect_mode; ' non';end} inspect mode.\n" if verbose? + @inspect_mode + end + + def evaluate(statement, line_no) # :nodoc: + @line_no = line_no + + case statement + when Statement::EmptyInput + return + when Statement::Expression + result = evaluate_expression(statement.code, line_no) + set_last_value(result) + when Statement::Command + statement.command_class.execute(self, statement.arg) + when Statement::IncorrectAlias + warn statement.message + end + + nil + end + + def from_binding? + @irb.from_binding + end + + def evaluate_expression(code, line_no) # :nodoc: + result = nil + if IRB.conf[:MEASURE] && IRB.conf[:MEASURE_CALLBACKS].empty? + IRB.set_measure_callback + end + + if IRB.conf[:MEASURE] && !IRB.conf[:MEASURE_CALLBACKS].empty? + last_proc = proc do + result = workspace.evaluate(code, @eval_path, line_no) + end + IRB.conf[:MEASURE_CALLBACKS].inject(last_proc) do |chain, item| + _name, callback, arg = item + proc do + callback.(self, code, line_no, arg) do + chain.call + end + end + end.call + else + result = workspace.evaluate(code, @eval_path, line_no) + end + result + end + + def parse_input(code, is_assignment_expression) + command_name, arg = code.strip.split(/\s+/, 2) + arg ||= '' + + # command can only be 1 line + if code.lines.size != 1 || + # command name is required + command_name.nil? || + # local variable have precedence over command + local_variables.include?(command_name.to_sym) || + # assignment expression is not a command + (is_assignment_expression || + (arg.start_with?(ASSIGN_OPERATORS_REGEXP) && !arg.start_with?(/==|=~/))) + return Statement::Expression.new(code, is_assignment_expression) + end + + command = command_name.to_sym + + # Check command aliases + if aliased_name = command_aliases[command] + if command_class = Command.load_command(aliased_name) + command = aliased_name + elsif HelperMethod.helper_methods[aliased_name] + message = <<~MESSAGE + Using command alias `#{command}` for helper method `#{aliased_name}` is not supported. + Please check the value of `IRB.conf[:COMMAND_ALIASES]`. + MESSAGE + return Statement::IncorrectAlias.new(message) + else + message = <<~MESSAGE + You're trying to use command alias `#{command}` for command `#{aliased_name}`, but `#{aliased_name}` does not exist. + Please check the value of `IRB.conf[:COMMAND_ALIASES]`. + MESSAGE + return Statement::IncorrectAlias.new(message) + end + else + command_class = Command.load_command(command) + end + + # Check visibility + public_method = !!KERNEL_PUBLIC_METHOD.bind_call(main, command) rescue false + private_method = !public_method && !!KERNEL_METHOD.bind_call(main, command) rescue false + if command_class && Command.execute_as_command?(command, public_method: public_method, private_method: private_method) + Statement::Command.new(code, command_class, arg) + else + Statement::Expression.new(code, is_assignment_expression) + end + end + + def colorize_input(input, complete:) + if IRB.conf[:USE_COLORIZE] && IRB::Color.colorable? + lvars = local_variables || [] + parsed_input = parse_input(input, false) + if parsed_input.is_a?(Statement::Command) + name, sep, arg = input.split(/(\s+)/, 2) + arg = IRB::Color.colorize_code(arg, complete: complete, local_variables: lvars) + "#{IRB::Color.colorize(name, [:BOLD])}\e[m#{sep}#{arg}" + else + IRB::Color.colorize_code(input, complete: complete, local_variables: lvars) + end + else + Reline::Unicode.escape_for_print(input) + end + end + + def inspect_last_value(output = +'') # :nodoc: + @inspect_method.inspect_value(@last_value, output) + end + + def inspector_support_stream_output? + @inspect_method.support_stream_output? + end + + NOPRINTING_IVARS = ["@last_value"] # :nodoc: + NO_INSPECTING_IVARS = ["@irb", "@io"] # :nodoc: + IDNAME_IVARS = ["@prompt_mode"] # :nodoc: + + alias __inspect__ inspect + def inspect # :nodoc: + array = [] + for ivar in instance_variables.sort{|e1, e2| e1 <=> e2} + ivar = ivar.to_s + name = ivar.sub(/^@(.*)$/, '\1') + val = instance_eval(ivar) + case ivar + when *NOPRINTING_IVARS + array.push format("conf.%s=%s", name, "...") + when *NO_INSPECTING_IVARS + array.push format("conf.%s=%s", name, val.to_s) + when *IDNAME_IVARS + array.push format("conf.%s=:%s", name, val.id2name) + else + array.push format("conf.%s=%s", name, val.inspect) + end + end + array.join("\n") + end + alias __to_s__ to_s + alias to_s inspect + + def local_variables # :nodoc: + workspace.binding.local_variables + end + + def safe_method_call_on_main(method_name) + main_object = main + Object === main_object ? main_object.__send__(method_name) : Object.instance_method(method_name).bind_call(main_object) + end + + private + + def term_interactive? + return true if ENV['TEST_IRB_FORCE_INTERACTIVE'] + STDIN.tty? && ENV['TERM'] != 'dumb' + end + + def build_completor + completor_type = IRB.conf[:COMPLETOR] + + # Gem repl_type_completor is added to bundled gems in Ruby 3.4. + # Use :type as default completor only in Ruby 3.4 or later. + verbose = !!completor_type + completor_type ||= RUBY_VERSION >= '3.4' ? :type : :regexp + + case completor_type + when :regexp + return RegexpCompletor.new + when :type + completor = build_type_completor(verbose: verbose) + return completor if completor + else + warn "Invalid value for IRB.conf[:COMPLETOR]: #{completor_type}" + end + # Fallback to RegexpCompletor + RegexpCompletor.new + end + + def build_type_completor(verbose:) + if RUBY_ENGINE == 'truffleruby' + # Avoid SyntaxError. truffleruby does not support endless method definition yet. + warn 'TypeCompletor is not supported on TruffleRuby yet' if verbose + return + end + + begin + require 'repl_type_completor' + rescue LoadError => e + warn "TypeCompletor requires `gem repl_type_completor`: #{e.message}" if verbose + return + end + + ReplTypeCompletor.preload_rbs + TypeCompletor.new(self) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/debug.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/debug.rb new file mode 100644 index 00000000..59be1365 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/debug.rb @@ -0,0 +1,127 @@ +# frozen_string_literal: true + +module IRB + module Debug + IRB_DIR = File.expand_path('..', __dir__) + + class << self + def insert_debug_break(pre_cmds: nil, do_cmds: nil) + options = { oneshot: true, hook_call: false } + + if pre_cmds || do_cmds + options[:command] = ['irb', pre_cmds, do_cmds] + end + if DEBUGGER__::LineBreakpoint.instance_method(:initialize).parameters.include?([:key, :skip_src]) + options[:skip_src] = true + end + + # To make debugger commands like `next` or `continue` work without asking + # the user to quit IRB after that, we need to exit IRB first and then hit + # a TracePoint on #debug_break. + file, lineno = IRB::Irb.instance_method(:debug_break).source_location + DEBUGGER__::SESSION.add_line_breakpoint(file, lineno + 1, **options) + end + + def setup(irb) + # When debug session is not started at all + unless defined?(DEBUGGER__::SESSION) + begin + require "debug/session" + rescue LoadError # debug.gem is not written in Gemfile + return false unless load_bundled_debug_gem + end + DEBUGGER__::CONFIG.set_config + configure_irb_for_debugger(irb) + + DEBUGGER__.initialize_session{ IRB::Debug::UI.new(irb) } + end + + # When debug session was previously started but not by IRB + if defined?(DEBUGGER__::SESSION) && !irb.context.with_debugger + configure_irb_for_debugger(irb) + DEBUGGER__::SESSION.reset_ui(IRB::Debug::UI.new(irb)) + end + + # Apply patches to debug gem so it skips IRB frames + unless DEBUGGER__.respond_to?(:capture_frames_without_irb) + DEBUGGER__.singleton_class.send(:alias_method, :capture_frames_without_irb, :capture_frames) + + def DEBUGGER__.capture_frames(*args) + frames = capture_frames_without_irb(*args) + frames.reject! do |frame| + frame.realpath&.start_with?(IRB_DIR) || frame.path == "" + end + frames + end + + DEBUGGER__::ThreadClient.prepend(SkipPathHelperForIRB) + end + + if !DEBUGGER__::CONFIG[:no_hint] && irb.context.io.is_a?(RelineInputMethod) + Reline.output_modifier_proc = proc do |input, complete:| + unless input.strip.empty? + cmd = input.split(/\s/, 2).first + + if !complete && DEBUGGER__.commands.key?(cmd) + input = input.sub(/\n$/, " # debug command\n") + end + end + + irb.context.colorize_input(input, complete: complete) + end + end + + true + end + + private + + def configure_irb_for_debugger(irb) + require 'irb/debug/ui' + IRB.instance_variable_set(:@debugger_irb, irb) + irb.context.with_debugger = true + irb.context.irb_name += ":rdbg" + irb.context.io.load_history if irb.context.io.class < HistorySavingAbility + end + + module SkipPathHelperForIRB + def skip_internal_path?(path) + # The latter can be removed once https://github.com/ruby/debug/issues/866 is resolved + super || path.match?(IRB_DIR) || path.match?('') + end + end + + # This is used when debug.gem is not written in Gemfile. Even if it's not + # installed by `bundle install`, debug.gem is installed by default because + # it's a bundled gem. This method tries to activate and load that. + def load_bundled_debug_gem + # Discover latest debug.gem under GEM_PATH + debug_gem = Gem.paths.path.flat_map { |path| Dir.glob("#{path}/gems/debug-*") }.select do |path| + File.basename(path).match?(/\Adebug-\d+\.\d+\.\d+(\w+)?\z/) + end.sort_by do |path| + Gem::Version.new(File.basename(path).delete_prefix('debug-')) + end.last + return false unless debug_gem + + # Discover debug/debug.so under extensions for Ruby 3.2+ + ext_name = "/debug/debug.#{RbConfig::CONFIG['DLEXT']}" + ext_path = Gem.paths.path.flat_map do |path| + Dir.glob("#{path}/extensions/**/#{File.basename(debug_gem)}#{ext_name}") + end.first + + # Attempt to forcibly load the bundled gem + if ext_path + $LOAD_PATH << ext_path.delete_suffix(ext_name) + end + $LOAD_PATH << "#{debug_gem}/lib" + begin + require "debug/session" + puts "Loaded #{File.basename(debug_gem)}" + true + rescue LoadError + false + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/debug/ui.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/debug/ui.rb new file mode 100644 index 00000000..a21ec6b1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/debug/ui.rb @@ -0,0 +1,101 @@ +require 'io/console/size' +require 'debug/console' + +module IRB + module Debug + class UI < DEBUGGER__::UI_Base + def initialize(irb) + @irb = irb + end + + def remote? + false + end + + def activate session, on_fork: false + end + + def deactivate + end + + def width + if (w = IO.console_size[1]) == 0 # for tests PTY + 80 + else + w + end + end + + def quit n + yield + exit n + end + + def ask prompt + setup_interrupt do + print prompt + ($stdin.gets || '').strip + end + end + + def puts str = nil + case str + when Array + str.each{|line| + $stdout.puts line.chomp + } + when String + Pager.page_content(str, retain_content: true) + when nil + $stdout.puts + end + end + + def readline _ + setup_interrupt do + tc = DEBUGGER__::SESSION.instance_variable_get(:@tc) + cmd = @irb.debug_readline(tc.current_frame.eval_binding || TOPLEVEL_BINDING) + + case cmd + when nil # when user types C-d + "continue" + else + cmd + end + end + end + + def setup_interrupt + DEBUGGER__::SESSION.intercept_trap_sigint false do + current_thread = Thread.current # should be session_server thread + + prev_handler = trap(:INT){ + current_thread.raise Interrupt + } + + yield + ensure + trap(:INT, prev_handler) + end + end + + def after_fork_parent + parent_pid = Process.pid + + at_exit{ + DEBUGGER__::SESSION.intercept_trap_sigint_end + trap(:SIGINT, :IGNORE) + + if Process.pid == parent_pid + # only check child process from its parent + begin + # wait for all child processes to keep terminal + Process.waitpid + rescue Errno::ESRCH, Errno::ECHILD + end + end + } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/default_commands.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/default_commands.rb new file mode 100644 index 00000000..9820a1f3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/default_commands.rb @@ -0,0 +1,279 @@ +# frozen_string_literal: true + +require_relative "command" +require_relative "command/internal_helpers" +require_relative "command/backtrace" +require_relative "command/break" +require_relative "command/catch" +require_relative "command/cd" +require_relative "command/chws" +require_relative "command/context" +require_relative "command/continue" +require_relative "command/copy" +require_relative "command/debug" +require_relative "command/delete" +require_relative "command/disable_irb" +require_relative "command/edit" +require_relative "command/exit" +require_relative "command/finish" +require_relative "command/force_exit" +require_relative "command/help" +require_relative "command/history" +require_relative "command/info" +require_relative "command/irb_info" +require_relative "command/load" +require_relative "command/ls" +require_relative "command/measure" +require_relative "command/next" +require_relative "command/pushws" +require_relative "command/show_doc" +require_relative "command/show_source" +require_relative "command/step" +require_relative "command/subirb" +require_relative "command/whereami" + +module IRB + module Command + NO_OVERRIDE = 0 + OVERRIDE_PRIVATE_ONLY = 0x01 + OVERRIDE_ALL = 0x02 + + class << self + # This API is for IRB's internal use only and may change at any time. + # Please do NOT use it. + def _register_with_aliases(name, command_class, *aliases) + @commands[name.to_sym] = [command_class, aliases] + end + + def all_commands_info + user_aliases = IRB.CurrentContext.command_aliases.each_with_object({}) do |(alias_name, target), result| + result[target] ||= [] + result[target] << alias_name + end + + commands.map do |command_name, (command_class, aliases)| + aliases = aliases.map { |a| a.first } + + if additional_aliases = user_aliases[command_name] + aliases += additional_aliases + end + + display_name = aliases.shift || command_name + { + display_name: display_name, + description: command_class.description, + category: command_class.category + } + end + end + + def command_override_policies + @@command_override_policies ||= commands.flat_map do |cmd_name, (cmd_class, aliases)| + [[cmd_name, OVERRIDE_ALL]] + aliases + end.to_h + end + + def execute_as_command?(name, public_method:, private_method:) + case command_override_policies[name] + when OVERRIDE_ALL + true + when OVERRIDE_PRIVATE_ONLY + !public_method + when NO_OVERRIDE + !public_method && !private_method + end + end + + def command_names + command_override_policies.keys.map(&:to_s) + end + + # Convert a command name to its implementation class if such command exists + def load_command(command) + command = command.to_sym + commands.each do |command_name, (command_class, aliases)| + if command_name == command || aliases.any? { |alias_name, _| alias_name == command } + return command_class + end + end + nil + end + end + + _register_with_aliases(:irb_context, Command::Context, + [:context, NO_OVERRIDE] + ) + + _register_with_aliases(:irb_exit, Command::Exit, + [:exit, OVERRIDE_PRIVATE_ONLY], + [:quit, OVERRIDE_PRIVATE_ONLY], + [:irb_quit, OVERRIDE_PRIVATE_ONLY] + ) + + _register_with_aliases(:irb_exit!, Command::ForceExit, + [:exit!, OVERRIDE_PRIVATE_ONLY] + ) + + _register_with_aliases(:irb_current_working_workspace, Command::CurrentWorkingWorkspace, + [:cwws, NO_OVERRIDE], + [:pwws, NO_OVERRIDE], + [:irb_print_working_workspace, OVERRIDE_ALL], + [:irb_cwws, OVERRIDE_ALL], + [:irb_pwws, OVERRIDE_ALL], + [:irb_current_working_binding, OVERRIDE_ALL], + [:irb_print_working_binding, OVERRIDE_ALL], + [:irb_cwb, OVERRIDE_ALL], + [:irb_pwb, OVERRIDE_ALL], + ) + + _register_with_aliases(:irb_change_workspace, Command::ChangeWorkspace, + [:chws, NO_OVERRIDE], + [:cws, NO_OVERRIDE], + [:irb_chws, OVERRIDE_ALL], + [:irb_cws, OVERRIDE_ALL], + [:irb_change_binding, OVERRIDE_ALL], + [:irb_cb, OVERRIDE_ALL], + [:cb, NO_OVERRIDE], + ) + + _register_with_aliases(:irb_workspaces, Command::Workspaces, + [:workspaces, NO_OVERRIDE], + [:irb_bindings, OVERRIDE_ALL], + [:bindings, NO_OVERRIDE], + ) + + _register_with_aliases(:irb_push_workspace, Command::PushWorkspace, + [:pushws, NO_OVERRIDE], + [:irb_pushws, OVERRIDE_ALL], + [:irb_push_binding, OVERRIDE_ALL], + [:irb_pushb, OVERRIDE_ALL], + [:pushb, NO_OVERRIDE], + ) + + _register_with_aliases(:irb_pop_workspace, Command::PopWorkspace, + [:popws, NO_OVERRIDE], + [:irb_popws, OVERRIDE_ALL], + [:irb_pop_binding, OVERRIDE_ALL], + [:irb_popb, OVERRIDE_ALL], + [:popb, NO_OVERRIDE], + ) + + _register_with_aliases(:irb_load, Command::Load) + _register_with_aliases(:irb_require, Command::Require) + _register_with_aliases(:irb_source, Command::Source, + [:source, NO_OVERRIDE] + ) + + _register_with_aliases(:irb, Command::IrbCommand) + _register_with_aliases(:irb_jobs, Command::Jobs, + [:jobs, NO_OVERRIDE] + ) + _register_with_aliases(:irb_fg, Command::Foreground, + [:fg, NO_OVERRIDE] + ) + _register_with_aliases(:irb_kill, Command::Kill, + [:kill, OVERRIDE_PRIVATE_ONLY] + ) + + _register_with_aliases(:irb_debug, Command::Debug, + [:debug, NO_OVERRIDE] + ) + _register_with_aliases(:irb_edit, Command::Edit, + [:edit, NO_OVERRIDE] + ) + + _register_with_aliases(:irb_break, Command::Break, + [:break, OVERRIDE_ALL] + ) + _register_with_aliases(:irb_catch, Command::Catch, + [:catch, OVERRIDE_PRIVATE_ONLY] + ) + _register_with_aliases(:irb_next, Command::Next, + [:next, OVERRIDE_ALL] + ) + _register_with_aliases(:irb_delete, Command::Delete, + [:delete, NO_OVERRIDE] + ) + + _register_with_aliases(:irb_step, Command::Step, + [:step, NO_OVERRIDE] + ) + _register_with_aliases(:irb_continue, Command::Continue, + [:continue, NO_OVERRIDE] + ) + _register_with_aliases(:irb_finish, Command::Finish, + [:finish, NO_OVERRIDE] + ) + _register_with_aliases(:irb_backtrace, Command::Backtrace, + [:backtrace, NO_OVERRIDE], + [:bt, NO_OVERRIDE] + ) + + _register_with_aliases(:irb_debug_info, Command::Info, + [:info, NO_OVERRIDE] + ) + + _register_with_aliases(:irb_help, Command::Help, + [:help, NO_OVERRIDE], + [:show_cmds, NO_OVERRIDE] + ) + + _register_with_aliases(:irb_show_doc, Command::ShowDoc, + [:show_doc, NO_OVERRIDE], + [:ri, NO_OVERRIDE] + ) + + _register_with_aliases(:irb_info, Command::IrbInfo) + + _register_with_aliases(:irb_ls, Command::Ls, + [:ls, NO_OVERRIDE] + ) + + _register_with_aliases(:irb_measure, Command::Measure, + [:measure, NO_OVERRIDE] + ) + + _register_with_aliases(:irb_show_source, Command::ShowSource, + [:show_source, NO_OVERRIDE] + ) + + _register_with_aliases(:irb_whereami, Command::Whereami, + [:whereami, NO_OVERRIDE] + ) + + _register_with_aliases(:irb_history, Command::History, + [:history, NO_OVERRIDE], + [:hist, NO_OVERRIDE] + ) + + _register_with_aliases(:irb_disable_irb, Command::DisableIrb, + [:disable_irb, NO_OVERRIDE] + ) + + register(:cd, Command::CD) + register(:copy, Command::Copy) + end + + ExtendCommand = Command + + # For backward compatibility, we need to keep this module: + # - As a container of helper methods + # - As a place to register commands with the deprecated def_extend_command method + module ExtendCommandBundle + # For backward compatibility + NO_OVERRIDE = Command::NO_OVERRIDE + OVERRIDE_PRIVATE_ONLY = Command::OVERRIDE_PRIVATE_ONLY + OVERRIDE_ALL = Command::OVERRIDE_ALL + + # Deprecated. Doesn't have any effect. + @EXTEND_COMMANDS = [] + + class << self + # Drepcated. Use Command.regiser instead. + def def_extend_command(cmd_name, cmd_class, _, *aliases) + Command._register_with_aliases(cmd_name, cmd_class, *aliases) + Command.class_variable_set(:@@command_override_policies, nil) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/easter-egg.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/easter-egg.rb new file mode 100644 index 00000000..07b6137b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/easter-egg.rb @@ -0,0 +1,152 @@ +require "reline" + +module IRB + class << self + class Vec + def initialize(x, y, z) + @x, @y, @z = x, y, z + end + + attr_reader :x, :y, :z + + def sub(other) + Vec.new(@x - other.x, @y - other.y, @z - other.z) + end + + def dot(other) + @x*other.x + @y*other.y + @z*other.z + end + + def cross(other) + ox, oy, oz = other.x, other.y, other.z + Vec.new(@y*oz-@z*oy, @z*ox-@x*oz, @x*oy-@y*ox) + end + + def normalize + r = Math.sqrt(self.dot(self)) + Vec.new(@x / r, @y / r, @z / r) + end + end + + class Canvas + def initialize((h, w)) + @data = (0..h-2).map { [0] * w } + @scale = [w / 2.0, h-2].min + @center = Complex(w / 2, h-2) + end + + def line((x1, y1), (x2, y2)) + p1 = Complex(x1, y1) / 2 * @scale + @center + p2 = Complex(x2, y2) / 2 * @scale + @center + line0(p1, p2) + end + + private def line0(p1, p2) + mid = (p1 + p2) / 2 + if (p1 - p2).abs < 1 + x, y = mid.rect + @data[y / 2][x] |= (y % 2 > 1 ? 2 : 1) + else + line0(p1, mid) + line0(p2, mid) + end + end + + def draw + @data.each {|row| row.fill(0) } + yield + @data.map {|row| row.map {|n| " ',;"[n] }.join }.join("\n") + end + end + + class RubyModel + def initialize + @faces = init_ruby_model + end + + def init_ruby_model + cap_vertices = (0..5).map {|i| Vec.new(*Complex.polar(1, i * Math::PI / 3).rect, 1) } + middle_vertices = (0..5).map {|i| Vec.new(*Complex.polar(2, (i + 0.5) * Math::PI / 3).rect, 0) } + bottom_vertex = Vec.new(0, 0, -2) + + faces = [cap_vertices] + 6.times do |j| + i = j-1 + faces << [cap_vertices[i], middle_vertices[i], cap_vertices[j]] + faces << [cap_vertices[j], middle_vertices[i], middle_vertices[j]] + faces << [middle_vertices[i], bottom_vertex, middle_vertices[j]] + end + + faces + end + + def render_frame(i) + angle = i / 10.0 + dir = Vec.new(*Complex.polar(1, angle).rect, Math.sin(angle)).normalize + dir2 = Vec.new(*Complex.polar(1, angle - Math::PI/2).rect, 0) + up = dir.cross(dir2) + nm = dir.cross(up) + @faces.each do |vertices| + v0, v1, v2, = vertices + if v1.sub(v0).cross(v2.sub(v0)).dot(dir) > 0 + points = vertices.map {|p| [nm.dot(p), up.dot(p)] } + (points + [points[0]]).each_cons(2) do |p1, p2| + yield p1, p2 + end + end + end + end + end + + private def easter_egg_logo(type) + @easter_egg_logos ||= File.read(File.join(__dir__, 'ruby_logo.aa'), encoding: 'UTF-8:UTF-8') + .split(/TYPE: ([A-Z_]+)\n/)[1..] + .each_slice(2) + .to_h + @easter_egg_logos[type.to_s.upcase] + end + + private def easter_egg(type = nil) + print "\e[?1049h" + type ||= [:logo, :dancing].sample + case type + when :logo + Pager.page do |io| + logo_type = STDOUT.external_encoding == Encoding::UTF_8 ? :unicode_large : :ascii_large + io.write easter_egg_logo(logo_type) + STDIN.raw { STDIN.getc } if io == STDOUT + end + when :dancing + STDOUT.cooked do + interrupted = false + prev_trap = trap("SIGINT") { interrupted = true } + canvas = Canvas.new(Reline.get_screen_size) + Reline::IOGate.set_winch_handler do + canvas = Canvas.new(Reline.get_screen_size) + end + ruby_model = RubyModel.new + print "\e[?25l" # hide cursor + 0.step do |i| # TODO (0..).each needs Ruby 2.6 or later + buff = canvas.draw do + ruby_model.render_frame(i) do |p1, p2| + canvas.line(p1, p2) + end + end + buff[0, 20] = "\e[0mPress Ctrl+C to stop\e[31m\e[1m" + print "\e[H" + buff + sleep 0.05 + break if interrupted + end + rescue Interrupt + ensure + print "\e[?25h" # show cursor + trap("SIGINT", prev_trap) + end + end + ensure + print "\e[0m\e[?1049l" + end + end +end + +IRB.__send__(:easter_egg, ARGV[0]&.to_sym) if $0 == __FILE__ diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ext/change-ws.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ext/change-ws.rb new file mode 100644 index 00000000..60e8afe3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ext/change-ws.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true +# +# irb/ext/cb.rb - +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# + +module IRB # :nodoc: + class Context + + # Inherited from +TOPLEVEL_BINDING+. + def home_workspace + if defined? @home_workspace + @home_workspace + else + @home_workspace = workspace + end + end + + # Changes the current workspace to given object or binding. + # + # If the optional argument is omitted, the workspace will be + # #home_workspace which is inherited from +TOPLEVEL_BINDING+ or the main + # object, IRB.conf[:MAIN_CONTEXT] when irb was initialized. + # + # See IRB::WorkSpace.new for more information. + def change_workspace(*_main) + if _main.empty? + replace_workspace(home_workspace) + return main + end + + workspace = WorkSpace.new(_main[0]) + replace_workspace(workspace) + workspace.load_helper_methods_to_main + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ext/eval_history.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ext/eval_history.rb new file mode 100644 index 00000000..6c21ff00 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ext/eval_history.rb @@ -0,0 +1,149 @@ +# frozen_string_literal: true +# +# history.rb - +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# + +module IRB # :nodoc: + + class Context + + NOPRINTING_IVARS.push "@eval_history_values" + + # See #set_last_value + alias _set_last_value set_last_value + + def set_last_value(value) + _set_last_value(value) + + if defined?(@eval_history) && @eval_history + @eval_history_values.push @line_no, @last_value + workspace.evaluate "__ = IRB.CurrentContext.instance_eval{@eval_history_values}" + end + + @last_value + end + + remove_method :eval_history= if method_defined?(:eval_history=) + # The command result history limit. This method is not available until + # #eval_history= was called with non-nil value (directly or via + # setting IRB.conf[:EVAL_HISTORY] in .irbrc). + attr_reader :eval_history + # Sets command result history limit. Default value is set from + # IRB.conf[:EVAL_HISTORY]. + # + # +no+ is an Integer or +nil+. + # + # Returns +no+ of history items if greater than 0. + # + # If +no+ is 0, the number of history items is unlimited. + # + # If +no+ is +nil+, execution result history isn't used (default). + # + # EvalHistory values are available via __ variable, see + # IRB::EvalHistory. + def eval_history=(no) + if no + if defined?(@eval_history) && @eval_history + @eval_history_values.size(no) + else + @eval_history_values = EvalHistory.new(no) + IRB.conf[:__TMP__EHV__] = @eval_history_values + workspace.evaluate("__ = IRB.conf[:__TMP__EHV__]") + IRB.conf.delete(:__TMP_EHV__) + end + else + @eval_history_values = nil + end + @eval_history = no + end + end + + # Represents history of results of previously evaluated commands. + # + # Available via __ variable, only if IRB.conf[:EVAL_HISTORY] + # or IRB::CurrentContext().eval_history is non-nil integer value + # (by default it is +nil+). + # + # Example (in `irb`): + # + # # Initialize history + # IRB::CurrentContext().eval_history = 10 + # # => 10 + # + # # Perform some commands... + # 1 + 2 + # # => 3 + # puts 'x' + # # x + # # => nil + # raise RuntimeError + # # ...error raised + # + # # Inspect history (format is " ": + # __ + # # => 1 10 + # # 2 3 + # # 3 nil + # + # __[1] + # # => 10 + # + class EvalHistory + + def initialize(size = 16) # :nodoc: + @size = size + @contents = [] + end + + def size(size) # :nodoc: + if size != 0 && size < @size + @contents = @contents[@size - size .. @size] + end + @size = size + end + + # Get one item of the content (both positive and negative indexes work). + def [](idx) + begin + if idx >= 0 + @contents.find{|no, val| no == idx}[1] + else + @contents[idx][1] + end + rescue NameError + nil + end + end + + def push(no, val) # :nodoc: + @contents.push [no, val] + @contents.shift if @size != 0 && @contents.size > @size + end + + alias real_inspect inspect + + def inspect # :nodoc: + if @contents.empty? + return real_inspect + end + + unless (last = @contents.pop)[1].equal?(self) + @contents.push last + last = nil + end + str = @contents.collect{|no, val| + if val.equal?(self) + "#{no} ...self-history..." + else + "#{no} #{val.inspect}" + end + }.join("\n") + if str == "" + str = "Empty." + end + @contents.push last if last + str + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ext/loader.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ext/loader.rb new file mode 100644 index 00000000..df5aaa8e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ext/loader.rb @@ -0,0 +1,127 @@ +# frozen_string_literal: true +# +# loader.rb - +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# + +module IRB # :nodoc: + # Raised in the event of an exception in a file loaded from an Irb session + class LoadAbort < Exception;end + + # Provides a few commands for loading files within an irb session. + # + # See ExtendCommandBundle for more information. + module IrbLoader + + alias ruby_load load + alias ruby_require require + + # Loads the given file similarly to Kernel#load + def irb_load(fn, priv = nil) + path = search_file_from_ruby_path(fn) + raise LoadError, "No such file to load -- #{fn}" unless path + + load_file(path, priv) + end + + def search_file_from_ruby_path(fn) # :nodoc: + if File.absolute_path?(fn) + return fn if File.exist?(fn) + return nil + end + + for path in $: + if File.exist?(f = File.join(path, fn)) + return f + end + end + return nil + end + + # Loads a given file in the current session and displays the source lines + # + # See Irb#suspend_input_method for more information. + def source_file(path) + irb = irb_context.irb + irb.suspend_name(path, File.basename(path)) do + FileInputMethod.open(path) do |io| + irb.suspend_input_method(io) do + |back_io| + irb.signal_status(:IN_LOAD) do + if back_io.kind_of?(FileInputMethod) + irb.eval_input + else + begin + irb.eval_input + rescue LoadAbort + print "load abort!!\n" + end + end + end + end + end + end + end + + # Loads the given file in the current session's context and evaluates it. + # + # See Irb#suspend_input_method for more information. + def load_file(path, priv = nil) + irb = irb_context.irb + irb.suspend_name(path, File.basename(path)) do + + if priv + ws = WorkSpace.new(Module.new) + else + ws = WorkSpace.new + end + irb.suspend_workspace(ws) do + FileInputMethod.open(path) do |io| + irb.suspend_input_method(io) do + |back_io| + irb.signal_status(:IN_LOAD) do + if back_io.kind_of?(FileInputMethod) + irb.eval_input + else + begin + irb.eval_input + rescue LoadAbort + print "load abort!!\n" + end + end + end + end + end + end + end + end + + def old # :nodoc: + back_io = @io + back_path = irb_path + back_name = @irb_name + back_scanner = @irb.scanner + begin + @io = FileInputMethod.new(path) + @irb_name = File.basename(path) + self.irb_path = path + @irb.signal_status(:IN_LOAD) do + if back_io.kind_of?(FileInputMethod) + @irb.eval_input + else + begin + @irb.eval_input + rescue LoadAbort + print "load abort!!\n" + end + end + end + ensure + @io = back_io + @irb_name = back_name + self.irb_path = back_path + @irb.scanner = back_scanner + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ext/multi-irb.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ext/multi-irb.rb new file mode 100644 index 00000000..9f234f0c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ext/multi-irb.rb @@ -0,0 +1,258 @@ +# frozen_string_literal: true +# +# irb/multi-irb.rb - multiple irb module +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# + +module IRB + class JobManager # :nodoc: + + # Creates a new JobManager object + def initialize + @jobs = [] + @current_job = nil + end + + # The active irb session + attr_accessor :current_job + + # The total number of irb sessions, used to set +irb_name+ of the current + # Context. + def n_jobs + @jobs.size + end + + # Returns the thread for the given +key+ object, see #search for more + # information. + def thread(key) + th, = search(key) + th + end + + # Returns the irb session for the given +key+ object, see #search for more + # information. + def irb(key) + _, irb = search(key) + irb + end + + # Returns the top level thread. + def main_thread + @jobs[0][0] + end + + # Returns the top level irb session. + def main_irb + @jobs[0][1] + end + + # Add the given +irb+ session to the jobs Array. + def insert(irb) + @jobs.push [Thread.current, irb] + end + + # Changes the current active irb session to the given +key+ in the jobs + # Array. + # + # Raises an IrbAlreadyDead exception if the given +key+ is no longer alive. + # + # If the given irb session is already active, an IrbSwitchedToCurrentThread + # exception is raised. + def switch(key) + th, irb = search(key) + fail IrbAlreadyDead unless th.alive? + fail IrbSwitchedToCurrentThread if th == Thread.current + @current_job = irb + th.run + Thread.stop + @current_job = irb(Thread.current) + end + + # Terminates the irb sessions specified by the given +keys+. + # + # Raises an IrbAlreadyDead exception if one of the given +keys+ is already + # terminated. + # + # See Thread#exit for more information. + def kill(*keys) + for key in keys + th, _ = search(key) + fail IrbAlreadyDead unless th.alive? + th.exit + end + end + + # Returns the associated job for the given +key+. + # + # If given an Integer, it will return the +key+ index for the jobs Array. + # + # When an instance of Irb is given, it will return the irb session + # associated with +key+. + # + # If given an instance of Thread, it will return the associated thread + # +key+ using Object#=== on the jobs Array. + # + # Otherwise returns the irb session with the same top-level binding as the + # given +key+. + # + # Raises a NoSuchJob exception if no job can be found with the given +key+. + def search(key) + job = case key + when Integer + @jobs[key] + when Irb + @jobs.find{|k, v| v.equal?(key)} + when Thread + @jobs.assoc(key) + else + @jobs.find{|k, v| v.context.main.equal?(key)} + end + fail NoSuchJob, key if job.nil? + job + end + + # Deletes the job at the given +key+. + def delete(key) + case key + when Integer + fail NoSuchJob, key unless @jobs[key] + @jobs[key] = nil + else + catch(:EXISTS) do + @jobs.each_index do + |i| + if @jobs[i] and (@jobs[i][0] == key || + @jobs[i][1] == key || + @jobs[i][1].context.main.equal?(key)) + @jobs[i] = nil + throw :EXISTS + end + end + fail NoSuchJob, key + end + end + until assoc = @jobs.pop; end unless @jobs.empty? + @jobs.push assoc + end + + # Outputs a list of jobs, see the irb command +irb_jobs+, or +jobs+. + def inspect + ary = [] + @jobs.each_index do + |i| + th, irb = @jobs[i] + next if th.nil? + + if th.alive? + if th.stop? + t_status = "stop" + else + t_status = "running" + end + else + t_status = "exited" + end + ary.push format("#%d->%s on %s (%s: %s)", + i, + irb.context.irb_name, + irb.context.main, + th, + t_status) + end + ary.join("\n") + end + end + + @JobManager = JobManager.new + + # The current JobManager in the session + def IRB.JobManager # :nodoc: + @JobManager + end + + # The current Context in this session + def IRB.CurrentContext # :nodoc: + IRB.JobManager.irb(Thread.current).context + end + + # Creates a new IRB session, see Irb.new. + # + # The optional +file+ argument is given to Context.new, along with the + # workspace created with the remaining arguments, see WorkSpace.new + def IRB.irb(file = nil, *main) # :nodoc: + workspace = WorkSpace.new(*main) + parent_thread = Thread.current + Thread.start do + begin + irb = Irb.new(workspace, file) + rescue + print "Subirb can't start with context(self): ", workspace.main.inspect, "\n" + print "return to main irb\n" + Thread.pass + Thread.main.wakeup + Thread.exit + end + @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC] + @JobManager.insert(irb) + @JobManager.current_job = irb + begin + system_exit = false + catch(:IRB_EXIT) do + irb.eval_input + end + rescue SystemExit + system_exit = true + raise + #fail + ensure + unless system_exit + @JobManager.delete(irb) + if @JobManager.current_job == irb + if parent_thread.alive? + @JobManager.current_job = @JobManager.irb(parent_thread) + parent_thread.run + else + @JobManager.current_job = @JobManager.main_irb + @JobManager.main_thread.run + end + end + end + end + end + Thread.stop + @JobManager.current_job = @JobManager.irb(Thread.current) + end + + @CONF[:SINGLE_IRB_MODE] = false + @JobManager.insert(@CONF[:MAIN_CONTEXT].irb) + @JobManager.current_job = @CONF[:MAIN_CONTEXT].irb + + class Irb + def signal_handle + unless @context.ignore_sigint? + print "\nabort!!\n" if @context.verbose? + exit + end + + case @signal_status + when :IN_INPUT + print "^C\n" + IRB.JobManager.thread(self).raise RubyLex::TerminateLineInput + when :IN_EVAL + IRB.irb_abort(self) + when :IN_LOAD + IRB.irb_abort(self, LoadAbort) + when :IN_IRB + # ignore + else + # ignore other cases as well + end + end + end + + trap("SIGINT") do + @JobManager.current_job.signal_handle + Thread.stop + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ext/tracer.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ext/tracer.rb new file mode 100644 index 00000000..fd6daa88 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ext/tracer.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true +# +# irb/lib/tracer.rb - +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# +# Loading the gem "tracer" will cause it to extend IRB commands with: +# https://github.com/ruby/tracer/blob/v0.2.2/lib/tracer/irb.rb +begin + require "tracer" +rescue LoadError + $stderr.puts "Tracer extension of IRB is enabled but tracer gem wasn't found." + return # This is about to disable loading below +end + +module IRB + class CallTracer < ::CallTracer + IRB_DIR = File.expand_path('../..', __dir__) + + def skip?(tp) + super || tp.path.match?(IRB_DIR) || tp.path.match?('') + end + end + class WorkSpace + alias __evaluate__ evaluate + # Evaluate the context of this workspace and use the Tracer library to + # output the exact lines of code are being executed in chronological order. + # + # See https://github.com/ruby/tracer for more information. + def evaluate(statements, file = __FILE__, line = __LINE__) + if IRB.conf[:USE_TRACER] == true + CallTracer.new(colorize: Color.colorable?).start do + __evaluate__(statements, file, line) + end + else + __evaluate__(statements, file, line) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ext/use-loader.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ext/use-loader.rb new file mode 100644 index 00000000..c8a3ea1f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ext/use-loader.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true +# +# use-loader.rb - +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# + +require_relative "../command/load" +require_relative "loader" + +class Object + alias __original__load__IRB_use_loader__ load + alias __original__require__IRB_use_loader__ require +end + +module IRB + module ExtendCommandBundle + remove_method :irb_load if method_defined?(:irb_load) + # Loads the given file similarly to Kernel#load, see IrbLoader#irb_load + def irb_load(*opts, &b) + Command::Load.execute(irb_context, *opts, &b) + end + remove_method :irb_require if method_defined?(:irb_require) + # Loads the given file similarly to Kernel#require + def irb_require(*opts, &b) + Command::Require.execute(irb_context, *opts, &b) + end + end + + class Context + + IRB.conf[:USE_LOADER] = false + + # Returns whether +irb+'s own file reader method is used by + # +load+/+require+ or not. + # + # This mode is globally affected (irb-wide). + def use_loader + IRB.conf[:USE_LOADER] + end + + alias use_loader? use_loader + + remove_method :use_loader= if method_defined?(:use_loader=) + # Sets IRB.conf[:USE_LOADER] + # + # See #use_loader for more information. + def use_loader=(opt) + + if IRB.conf[:USE_LOADER] != opt + IRB.conf[:USE_LOADER] = opt + if opt + (class< 1 + # swap the top two workspaces + previous_workspace, current_workspace = @workspace_stack.pop(2) + @workspace_stack.push current_workspace, previous_workspace + end + else + new_workspace = WorkSpace.new(workspace.binding, _main[0]) + @workspace_stack.push new_workspace + new_workspace.load_helper_methods_to_main + end + end + + # Removes the last element from the current #workspaces stack and returns + # it, or +nil+ if the current workspace stack is empty. + # + # Also, see #push_workspace. + def pop_workspace + @workspace_stack.pop if @workspace_stack.size > 1 + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/frame.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/frame.rb new file mode 100644 index 00000000..4b697c87 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/frame.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: true +# +# frame.rb - +# by Keiju ISHITSUKA(Nihon Rational Software Co.,Ltd) +# + +module IRB + class Frame + class FrameOverflow < StandardError + def initialize + super("frame overflow") + end + end + class FrameUnderflow < StandardError + def initialize + super("frame underflow") + end + end + + # Default number of stack frames + INIT_STACK_TIMES = 3 + # Default number of frames offset + CALL_STACK_OFFSET = 3 + + # Creates a new stack frame + def initialize + @frames = [TOPLEVEL_BINDING] * INIT_STACK_TIMES + end + + # Used by Kernel#set_trace_func to register each event in the call stack + def trace_func(event, file, line, id, binding) + case event + when 'call', 'class' + @frames.push binding + when 'return', 'end' + @frames.pop + end + end + + # Returns the +n+ number of frames on the call stack from the last frame + # initialized. + # + # Raises FrameUnderflow if there are no frames in the given stack range. + def top(n = 0) + bind = @frames[-(n + CALL_STACK_OFFSET)] + fail FrameUnderflow unless bind + bind + end + + # Returns the +n+ number of frames on the call stack from the first frame + # initialized. + # + # Raises FrameOverflow if there are no frames in the given stack range. + def bottom(n = 0) + bind = @frames[n] + fail FrameOverflow unless bind + bind + end + + # Convenience method for Frame#bottom + def Frame.bottom(n = 0) + @backtrace.bottom(n) + end + + # Convenience method for Frame#top + def Frame.top(n = 0) + @backtrace.top(n) + end + + # Returns the binding context of the caller from the last frame initialized + def Frame.sender + eval "self", @backtrace.top + end + + @backtrace = Frame.new + set_trace_func proc{|event, file, line, id, binding, klass| + @backtrace.trace_func(event, file, line, id, binding) + } + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/help.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/help.rb new file mode 100644 index 00000000..a24bc10a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/help.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true +# +# irb/help.rb - print usage module +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# + +module IRB + # Outputs the irb help message, see IRB@Command-Line+Options. + def IRB.print_usage # :nodoc: + lc = IRB.conf[:LC_MESSAGES] + path = lc.find("irb/help-message") + space_line = false + File.open(path){|f| + f.each_line do |l| + if /^\s*$/ =~ l + lc.puts l unless space_line + space_line = true + next + end + space_line = false + + l.sub!(/#.*$/, "") + next if /^\s*$/ =~ l + lc.puts l + end + } + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/helper_method.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/helper_method.rb new file mode 100644 index 00000000..f1f6fff9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/helper_method.rb @@ -0,0 +1,29 @@ +require_relative "helper_method/base" + +module IRB + module HelperMethod + @helper_methods = {} + + class << self + attr_reader :helper_methods + + def register(name, helper_class) + @helper_methods[name] = helper_class + + if defined?(HelpersContainer) + HelpersContainer.install_helper_methods + end + end + + def all_helper_methods_info + @helper_methods.map do |name, helper_class| + { display_name: name, description: helper_class.description } + end + end + end + + # Default helper_methods + require_relative "helper_method/conf" + register(:conf, HelperMethod::Conf) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/helper_method/base.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/helper_method/base.rb new file mode 100644 index 00000000..a68001ed --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/helper_method/base.rb @@ -0,0 +1,16 @@ +require "singleton" + +module IRB + module HelperMethod + class Base + include Singleton + + class << self + def description(description = nil) + @description = description if description + @description + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/helper_method/conf.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/helper_method/conf.rb new file mode 100644 index 00000000..718ed279 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/helper_method/conf.rb @@ -0,0 +1,11 @@ +module IRB + module HelperMethod + class Conf < Base + description "Returns the current IRB context." + + def execute + IRB.CurrentContext + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/history.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/history.rb new file mode 100644 index 00000000..0beff155 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/history.rb @@ -0,0 +1,116 @@ +require "pathname" + +module IRB + module History + DEFAULT_ENTRY_LIMIT = 1000 + + class << self + # Integer representation of IRB.conf[:HISTORY_FILE]. + def save_history + return 0 if IRB.conf[:SAVE_HISTORY] == false + return DEFAULT_ENTRY_LIMIT if IRB.conf[:SAVE_HISTORY] == true + IRB.conf[:SAVE_HISTORY].to_i + end + + def save_history? + !save_history.zero? + end + + def infinite? + save_history.negative? + end + + # Might be nil when HOME and XDG_CONFIG_HOME are not available. + def history_file + if (history_file = IRB.conf[:HISTORY_FILE]) + File.expand_path(history_file) + else + IRB.rc_file("_history") + end + end + end + end + + module HistorySavingAbility # :nodoc: + def support_history_saving? + true + end + + def reset_history_counter + @loaded_history_lines = self.class::HISTORY.size + end + + def load_history + history_file = History.history_file + return unless File.exist?(history_file.to_s) + + history = self.class::HISTORY + + File.open(history_file, "r:#{IRB.conf[:LC_MESSAGES].encoding}") do |f| + f.each { |l| + l = l.chomp + if self.class == RelineInputMethod and history.last&.end_with?("\\") + history.last.delete_suffix!("\\") + history.last << "\n" << l + else + history << l + end + } + end + @loaded_history_lines = history.size + @loaded_history_mtime = File.mtime(history_file) + end + + def save_history + return unless History.save_history? + return unless (history_file = History.history_file) + unless ensure_history_file_writable(history_file) + warn <<~WARN + Can't write history to #{History.history_file.inspect} due to insufficient permissions. + Please verify the value of `IRB.conf[:HISTORY_FILE]`. Ensure the folder exists and that both the folder and file (if it exists) are writable. + WARN + return + end + + history = self.class::HISTORY.to_a + + if File.exist?(history_file) && + File.mtime(history_file) != @loaded_history_mtime + history = history[@loaded_history_lines..-1] if @loaded_history_lines + append_history = true + end + + File.open(history_file, (append_history ? "a" : "w"), 0o600, encoding: IRB.conf[:LC_MESSAGES]&.encoding) do |f| + hist = history.map { |l| l.scrub.split("\n").join("\\\n") } + + unless append_history || History.infinite? + # Check size before slicing because array.last(huge_number) raises RangeError. + hist = hist.last(History.save_history) if hist.size > History.save_history + end + + f.puts(hist) + end + end + + private + + # Returns boolean whether writing to +history_file+ will be possible. + # Permissions of already existing +history_file+ are changed to + # owner-only-readable if necessary [BUG #7694]. + def ensure_history_file_writable(history_file) + history_file = Pathname.new(history_file) + + return false unless history_file.dirname.writable? + return true unless history_file.exist? + + begin + if history_file.stat.mode & 0o66 != 0 + history_file.chmod 0o600 + end + true + rescue Errno::EPERM # no permissions + false + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/init.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/init.rb new file mode 100644 index 00000000..720c4fec --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/init.rb @@ -0,0 +1,540 @@ +# frozen_string_literal: true +# +# irb/init.rb - irb initialize module +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# + +module IRB # :nodoc: + @CONF = {} + @INITIALIZED = false + # Displays current configuration. + # + # Modifying the configuration is achieved by sending a message to IRB.conf. + # + # See IRB@Configuration for more information. + def IRB.conf + @CONF + end + + def @CONF.inspect + array = [] + for k, v in sort{|a1, a2| a1[0].id2name <=> a2[0].id2name} + case k + when :MAIN_CONTEXT, :__TMP__EHV__ + array.push format("CONF[:%s]=...myself...", k.id2name) + when :PROMPT + s = v.collect{ + |kk, vv| + ss = vv.collect{|kkk, vvv| ":#{kkk.id2name}=>#{vvv.inspect}"} + format(":%s=>{%s}", kk.id2name, ss.join(", ")) + } + array.push format("CONF[:%s]={%s}", k.id2name, s.join(", ")) + else + array.push format("CONF[:%s]=%s", k.id2name, v.inspect) + end + end + array.join("\n") + end + + # Returns the current version of IRB, including release version and last + # updated date. + def IRB.version + format("irb %s (%s)", @RELEASE_VERSION, @LAST_UPDATE_DATE) + end + + def IRB.initialized? + !!@INITIALIZED + end + + # initialize config + def IRB.setup(ap_path, argv: ::ARGV) + IRB.init_config(ap_path) + IRB.init_error + IRB.parse_opts(argv: argv) + IRB.run_config + IRB.validate_config + IRB.load_modules + + unless @CONF[:PROMPT][@CONF[:PROMPT_MODE]] + fail UndefinedPromptMode, @CONF[:PROMPT_MODE] + end + @INITIALIZED = true + end + + # @CONF default setting + def IRB.init_config(ap_path) + # default configurations + unless ap_path and @CONF[:AP_NAME] + ap_path = File.join(File.dirname(File.dirname(__FILE__)), "irb.rb") + end + @CONF[:VERSION] = version + @CONF[:AP_NAME] = File::basename(ap_path, ".rb") + + @CONF[:IRB_NAME] = "irb" + @CONF[:IRB_LIB_PATH] = File.dirname(__FILE__) + + @CONF[:RC] = true + @CONF[:LOAD_MODULES] = [] + @CONF[:IRB_RC] = nil + + @CONF[:USE_SINGLELINE] = false unless defined?(ReadlineInputMethod) + @CONF[:USE_COLORIZE] = (nc = ENV['NO_COLOR']).nil? || nc.empty? + @CONF[:USE_AUTOCOMPLETE] = ENV.fetch("IRB_USE_AUTOCOMPLETE", "true") != "false" + @CONF[:COMPLETOR] = ENV["IRB_COMPLETOR"]&.to_sym + @CONF[:INSPECT_MODE] = true + @CONF[:USE_TRACER] = false + @CONF[:USE_LOADER] = false + @CONF[:IGNORE_SIGINT] = true + @CONF[:IGNORE_EOF] = false + @CONF[:USE_PAGER] = true + @CONF[:EXTRA_DOC_DIRS] = [] + @CONF[:ECHO] = nil + @CONF[:ECHO_ON_ASSIGNMENT] = nil + @CONF[:VERBOSE] = nil + + @CONF[:EVAL_HISTORY] = nil + @CONF[:SAVE_HISTORY] = History::DEFAULT_ENTRY_LIMIT + + @CONF[:BACK_TRACE_LIMIT] = 16 + + @CONF[:PROMPT] = { + :NULL => { + :PROMPT_I => nil, + :PROMPT_S => nil, + :PROMPT_C => nil, + :RETURN => "%s\n" + }, + :DEFAULT => { + :PROMPT_I => "%N(%m):%03n> ", + :PROMPT_S => "%N(%m):%03n%l ", + :PROMPT_C => "%N(%m):%03n* ", + :RETURN => "=> %s\n" + }, + :CLASSIC => { + :PROMPT_I => "%N(%m):%03n:%i> ", + :PROMPT_S => "%N(%m):%03n:%i%l ", + :PROMPT_C => "%N(%m):%03n:%i* ", + :RETURN => "%s\n" + }, + :SIMPLE => { + :PROMPT_I => ">> ", + :PROMPT_S => "%l> ", + :PROMPT_C => "?> ", + :RETURN => "=> %s\n" + }, + :INF_RUBY => { + :PROMPT_I => "%N(%m):%03n> ", + :PROMPT_S => nil, + :PROMPT_C => nil, + :RETURN => "%s\n", + :AUTO_INDENT => true + }, + :XMP => { + :PROMPT_I => nil, + :PROMPT_S => nil, + :PROMPT_C => nil, + :RETURN => " ==>%s\n" + } + } + + @CONF[:PROMPT_MODE] = (STDIN.tty? ? :DEFAULT : :NULL) + @CONF[:AUTO_INDENT] = true + + @CONF[:CONTEXT_MODE] = 4 # use a copy of TOPLEVEL_BINDING + @CONF[:SINGLE_IRB] = false + + @CONF[:MEASURE] = false + @CONF[:MEASURE_PROC] = {} + @CONF[:MEASURE_PROC][:TIME] = proc { |context, code, line_no, &block| + time = Time.now + result = block.() + now = Time.now + puts 'processing time: %fs' % (now - time) if IRB.conf[:MEASURE] + result + } + # arg can be either a symbol for the mode (:cpu, :wall, ..) or a hash for + # a more complete configuration. + # See https://github.com/tmm1/stackprof#all-options. + @CONF[:MEASURE_PROC][:STACKPROF] = proc { |context, code, line_no, arg, &block| + return block.() unless IRB.conf[:MEASURE] + success = false + begin + require 'stackprof' + success = true + rescue LoadError + puts 'Please run "gem install stackprof" before measuring by StackProf.' + end + if success + result = nil + arg = { mode: arg || :cpu } unless arg.is_a?(Hash) + stackprof_result = StackProf.run(**arg) do + result = block.() + end + case stackprof_result + when File + puts "StackProf report saved to #{stackprof_result.path}" + when Hash + StackProf::Report.new(stackprof_result).print_text + else + puts "Stackprof ran with #{arg.inspect}" + end + result + else + block.() + end + } + @CONF[:MEASURE_CALLBACKS] = [] + + @CONF[:LC_MESSAGES] = Locale.new + + @CONF[:AT_EXIT] = [] + + @CONF[:COMMAND_ALIASES] = { + # Symbol aliases + :'$' => :show_source, + :'@' => :whereami, + } + + @CONF[:COPY_COMMAND] = ENV.fetch("IRB_COPY_COMMAND", nil) + end + + def IRB.set_measure_callback(type = nil, arg = nil, &block) + added = nil + if type + type_sym = type.upcase.to_sym + if IRB.conf[:MEASURE_PROC][type_sym] + added = [type_sym, IRB.conf[:MEASURE_PROC][type_sym], arg] + end + elsif IRB.conf[:MEASURE_PROC][:CUSTOM] + added = [:CUSTOM, IRB.conf[:MEASURE_PROC][:CUSTOM], arg] + elsif block_given? + added = [:BLOCK, block, arg] + found = IRB.conf[:MEASURE_CALLBACKS].find{ |m| m[0] == added[0] && m[2] == added[2] } + if found + found[1] = block + return added + else + IRB.conf[:MEASURE_CALLBACKS] << added + return added + end + else + added = [:TIME, IRB.conf[:MEASURE_PROC][:TIME], arg] + end + if added + IRB.conf[:MEASURE] = true + found = IRB.conf[:MEASURE_CALLBACKS].find{ |m| m[0] == added[0] && m[2] == added[2] } + if found + # already added + nil + else + IRB.conf[:MEASURE_CALLBACKS] << added if added + added + end + else + nil + end + end + + def IRB.unset_measure_callback(type = nil) + if type.nil? + IRB.conf[:MEASURE_CALLBACKS].clear + else + type_sym = type.upcase.to_sym + IRB.conf[:MEASURE_CALLBACKS].reject!{ |t, | t == type_sym } + end + IRB.conf[:MEASURE] = nil if IRB.conf[:MEASURE_CALLBACKS].empty? + end + + def IRB.init_error + @CONF[:LC_MESSAGES].load("irb/error.rb") + end + + # option analyzing + def IRB.parse_opts(argv: ::ARGV) + load_path = [] + while opt = argv.shift + case opt + when "-f" + @CONF[:RC] = false + when "-d" + $DEBUG = true + $VERBOSE = true + when "-w" + Warning[:deprecated] = $VERBOSE = true + when /^-W(.+)?/ + opt = $1 || argv.shift + case opt + when "0" + $VERBOSE = nil + when "1" + $VERBOSE = false + else + Warning[:deprecated] = $VERBOSE = true + end + when /^-r(.+)?/ + opt = $1 || argv.shift + @CONF[:LOAD_MODULES].push opt if opt + when /^-I(.+)?/ + opt = $1 || argv.shift + load_path.concat(opt.split(File::PATH_SEPARATOR)) if opt + when '-U' + set_encoding("UTF-8", "UTF-8") + when /^-E(.+)?/, /^--encoding(?:=(.+))?/ + opt = $1 || argv.shift + set_encoding(*opt.split(':', 2)) + when "--inspect" + if /^-/ !~ argv.first + @CONF[:INSPECT_MODE] = argv.shift + else + @CONF[:INSPECT_MODE] = true + end + when "--noinspect" + @CONF[:INSPECT_MODE] = false + when "--no-pager" + @CONF[:USE_PAGER] = false + when "--singleline", "--readline", "--legacy" + @CONF[:USE_SINGLELINE] = true + when "--nosingleline", "--noreadline" + @CONF[:USE_SINGLELINE] = false + when "--multiline", "--reidline" + if opt == "--reidline" + warn <<~MSG.strip + --reidline is deprecated, please use --multiline instead. + MSG + end + + @CONF[:USE_MULTILINE] = true + when "--nomultiline", "--noreidline" + if opt == "--noreidline" + warn <<~MSG.strip + --noreidline is deprecated, please use --nomultiline instead. + MSG + end + + @CONF[:USE_MULTILINE] = false + when /^--extra-doc-dir(?:=(.+))?/ + opt = $1 || argv.shift + @CONF[:EXTRA_DOC_DIRS] << opt + when "--echo" + @CONF[:ECHO] = true + when "--noecho" + @CONF[:ECHO] = false + when "--echo-on-assignment" + @CONF[:ECHO_ON_ASSIGNMENT] = true + when "--noecho-on-assignment" + @CONF[:ECHO_ON_ASSIGNMENT] = false + when "--truncate-echo-on-assignment" + @CONF[:ECHO_ON_ASSIGNMENT] = :truncate + when "--verbose" + @CONF[:VERBOSE] = true + when "--noverbose" + @CONF[:VERBOSE] = false + when "--colorize" + @CONF[:USE_COLORIZE] = true + when "--nocolorize" + @CONF[:USE_COLORIZE] = false + when "--autocomplete" + @CONF[:USE_AUTOCOMPLETE] = true + when "--noautocomplete" + @CONF[:USE_AUTOCOMPLETE] = false + when "--regexp-completor" + @CONF[:COMPLETOR] = :regexp + when "--type-completor" + @CONF[:COMPLETOR] = :type + when /^--prompt-mode(?:=(.+))?/, /^--prompt(?:=(.+))?/ + opt = $1 || argv.shift + prompt_mode = opt.upcase.tr("-", "_").intern + @CONF[:PROMPT_MODE] = prompt_mode + when "--noprompt" + @CONF[:PROMPT_MODE] = :NULL + when "--script" + noscript = false + when "--noscript" + noscript = true + when "--inf-ruby-mode" + @CONF[:PROMPT_MODE] = :INF_RUBY + when "--sample-book-mode", "--simple-prompt" + @CONF[:PROMPT_MODE] = :SIMPLE + when "--tracer" + @CONF[:USE_TRACER] = true + when /^--back-trace-limit(?:=(.+))?/ + @CONF[:BACK_TRACE_LIMIT] = ($1 || argv.shift).to_i + when /^--context-mode(?:=(.+))?/ + @CONF[:CONTEXT_MODE] = ($1 || argv.shift).to_i + when "--single-irb" + @CONF[:SINGLE_IRB] = true + when "-v", "--version" + print IRB.version, "\n" + exit 0 + when "-h", "--help" + require_relative "help" + IRB.print_usage + exit 0 + when "--" + if !noscript && (opt = argv.shift) + @CONF[:SCRIPT] = opt + $0 = opt + end + break + when /^-./ + fail UnrecognizedSwitch, opt + else + if noscript + argv.unshift(opt) + else + @CONF[:SCRIPT] = opt + $0 = opt + end + break + end + end + + load_path.collect! do |path| + /\A\.\// =~ path ? path : File.expand_path(path) + end + $LOAD_PATH.unshift(*load_path) + end + + # Run the config file + def IRB.run_config + if @CONF[:RC] + irbrc_files.each do |rc| + load rc + rescue StandardError, ScriptError => e + warn "Error loading RC file '#{rc}':\n#{e.full_message(highlight: false)}" + end + end + end + + IRBRC_EXT = "rc" + + def IRB.rc_file(ext) + prepare_irbrc_name_generators + + # When irbrc exist in default location + if (rcgen = @existing_rc_name_generators.first) + return rcgen.call(ext) + end + + # When irbrc does not exist in default location + rc_file_generators do |rcgen| + return rcgen.call(ext) + end + + # When HOME and XDG_CONFIG_HOME are not available + nil + end + + def IRB.irbrc_files + prepare_irbrc_name_generators + @irbrc_files + end + + def IRB.validate_config + conf[:IRB_NAME] = conf[:IRB_NAME].to_s + + irb_rc = conf[:IRB_RC] + unless irb_rc.nil? || irb_rc.respond_to?(:call) + raise_validation_error "IRB.conf[:IRB_RC] should be a callable object. Got #{irb_rc.inspect}." + end + + back_trace_limit = conf[:BACK_TRACE_LIMIT] + unless back_trace_limit.is_a?(Integer) + raise_validation_error "IRB.conf[:BACK_TRACE_LIMIT] should be an integer. Got #{back_trace_limit.inspect}." + end + + prompt = conf[:PROMPT] + unless prompt.is_a?(Hash) + msg = "IRB.conf[:PROMPT] should be a Hash. Got #{prompt.inspect}." + + if prompt.is_a?(Symbol) + msg += " Did you mean to set `IRB.conf[:PROMPT_MODE]`?" + end + + raise_validation_error msg + end + + eval_history = conf[:EVAL_HISTORY] + unless eval_history.nil? || eval_history.is_a?(Integer) + raise_validation_error "IRB.conf[:EVAL_HISTORY] should be an integer. Got #{eval_history.inspect}." + end + end + + def IRB.raise_validation_error(msg) + raise TypeError, msg, @irbrc_files + end + + # loading modules + def IRB.load_modules + for m in @CONF[:LOAD_MODULES] + begin + require m + rescue LoadError => err + warn "#{err.class}: #{err}", uplevel: 0 + end + end + end + + class << IRB + private + + def prepare_irbrc_name_generators + return if @existing_rc_name_generators + + @existing_rc_name_generators = [] + @irbrc_files = [] + rc_file_generators do |rcgen| + irbrc = rcgen.call(IRBRC_EXT) + if File.exist?(irbrc) + @irbrc_files << irbrc + @existing_rc_name_generators << rcgen + end + end + generate_current_dir_irbrc_files.each do |irbrc| + @irbrc_files << irbrc if File.exist?(irbrc) + end + @irbrc_files.uniq! + end + + # enumerate possible rc-file base name generators + def rc_file_generators + if irbrc = ENV["IRBRC"] + yield proc{|rc| rc == "rc" ? irbrc : irbrc+rc} + end + if xdg_config_home = ENV["XDG_CONFIG_HOME"] + irb_home = File.join(xdg_config_home, "irb") + if File.directory?(irb_home) + yield proc{|rc| irb_home + "/irb#{rc}"} + end + end + if home = ENV["HOME"] + yield proc{|rc| home+"/.irb#{rc}"} + if xdg_config_home.nil? || xdg_config_home.empty? + yield proc{|rc| home+"/.config/irb/irb#{rc}"} + end + end + end + + # possible irbrc files in current directory + def generate_current_dir_irbrc_files + current_dir = Dir.pwd + %w[.irbrc irbrc _irbrc $irbrc].map { |file| "#{current_dir}/#{file}" } + end + + def set_encoding(extern, intern = nil, override: true) + verbose, $VERBOSE = $VERBOSE, nil + Encoding.default_external = extern unless extern.nil? || extern.empty? + Encoding.default_internal = intern unless intern.nil? || intern.empty? + [$stdin, $stdout, $stderr].each do |io| + io.set_encoding(extern, intern) + end + if override + @CONF[:LC_MESSAGES].instance_variable_set(:@override_encoding, extern) + else + @CONF[:LC_MESSAGES].instance_variable_set(:@encoding, extern) + end + ensure + $VERBOSE = verbose + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/input-method.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/input-method.rb new file mode 100644 index 00000000..b9bbdeb1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/input-method.rb @@ -0,0 +1,521 @@ +# frozen_string_literal: true +# +# irb/input-method.rb - input methods used irb +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# + +require_relative 'completion' +require_relative "history" +require 'io/console' +require 'reline' + +module IRB + class InputMethod + BASIC_WORD_BREAK_CHARACTERS = " \t\n`><=;|&{(" + + # The irb prompt associated with this input method + attr_accessor :prompt + + # Reads the next line from this input method. + # + # See IO#gets for more information. + def gets + fail NotImplementedError + end + public :gets + + def winsize + if instance_variable_defined?(:@stdout) && @stdout.tty? + winsize = @stdout.winsize + # If width or height is 0, something is wrong. + return winsize unless winsize.include? 0 + end + [24, 80] + end + + # Whether this input method is still readable when there is no more data to + # read. + # + # See IO#eof for more information. + def readable_after_eof? + false + end + + def support_history_saving? + false + end + + def prompting? + false + end + + # For debug message + def inspect + 'Abstract InputMethod' + end + end + + class StdioInputMethod < InputMethod + # Creates a new input method object + def initialize + @line_no = 0 + @line = [] + @stdin = IO.open(STDIN.to_i, :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-") + @stdout = IO.open(STDOUT.to_i, 'w', :external_encoding => IRB.conf[:LC_MESSAGES].encoding, :internal_encoding => "-") + end + + # Reads the next line from this input method. + # + # See IO#gets for more information. + def gets + # Workaround for debug compatibility test https://github.com/ruby/debug/pull/1100 + puts if ENV['RUBY_DEBUG_TEST_UI'] + + print @prompt + line = @stdin.gets + @line[@line_no += 1] = line + end + + # Whether the end of this input method has been reached, returns +true+ if + # there is no more data to read. + # + # See IO#eof? for more information. + def eof? + if @stdin.wait_readable(0.00001) + c = @stdin.getc + result = c.nil? ? true : false + @stdin.ungetc(c) unless c.nil? + result + else # buffer is empty + false + end + end + + # Whether this input method is still readable when there is no more data to + # read. + # + # See IO#eof for more information. + def readable_after_eof? + true + end + + def prompting? + STDIN.tty? + end + + # Returns the current line number for #io. + # + # #line counts the number of times #gets is called. + # + # See IO#lineno for more information. + def line(line_no) + @line[line_no] + end + + # The external encoding for standard input. + def encoding + @stdin.external_encoding + end + + # For debug message + def inspect + 'StdioInputMethod' + end + end + + # Use a File for IO with irb, see InputMethod + class FileInputMethod < InputMethod + class << self + def open(file, &block) + begin + io = new(file) + block.call(io) + ensure + io&.close + end + end + end + + # Creates a new input method object + def initialize(file) + @io = file.is_a?(IO) ? file : File.open(file) + @external_encoding = @io.external_encoding + end + + # Whether the end of this input method has been reached, returns +true+ if + # there is no more data to read. + # + # See IO#eof? for more information. + def eof? + @io.closed? || @io.eof? + end + + # Reads the next line from this input method. + # + # See IO#gets for more information. + def gets + print @prompt + @io.gets + end + + # The external encoding for standard input. + def encoding + @external_encoding + end + + # For debug message + def inspect + 'FileInputMethod' + end + + def close + @io.close + end + end + + class ReadlineInputMethod < StdioInputMethod + class << self + def initialize_readline + return if defined?(self::Readline) + + begin + require 'readline' + const_set(:Readline, ::Readline) + rescue LoadError + const_set(:Readline, ::Reline) + end + const_set(:HISTORY, self::Readline::HISTORY) + end + end + + include HistorySavingAbility + + # Creates a new input method object using Readline + def initialize + self.class.initialize_readline + if Readline.respond_to?(:encoding_system_needs) + IRB.__send__(:set_encoding, Readline.encoding_system_needs.name, override: false) + end + + super + + @eof = false + @completor = RegexpCompletor.new + + if Readline.respond_to?("basic_word_break_characters=") + Readline.basic_word_break_characters = BASIC_WORD_BREAK_CHARACTERS + end + Readline.completion_append_character = nil + Readline.completion_proc = ->(target) { + bind = IRB.conf[:MAIN_CONTEXT].workspace.binding + @completor.completion_candidates('', target, '', bind: bind) + } + end + + def completion_info + 'RegexpCompletor' + end + + # Reads the next line from this input method. + # + # See IO#gets for more information. + def gets + Readline.input = @stdin + Readline.output = @stdout + if l = Readline.readline(@prompt, false) + Readline::HISTORY.push(l) if !l.empty? + @line[@line_no += 1] = l + "\n" + else + @eof = true + l + end + end + + # Whether the end of this input method has been reached, returns +true+ + # if there is no more data to read. + # + # See IO#eof? for more information. + def eof? + @eof + end + + def prompting? + true + end + + # For debug message + def inspect + readline_impl = Readline == ::Reline ? 'Reline' : 'ext/readline' + str = "ReadlineInputMethod with #{readline_impl} #{Readline::VERSION}" + inputrc_path = File.expand_path(ENV['INPUTRC'] || '~/.inputrc') + str += " and #{inputrc_path}" if File.exist?(inputrc_path) + str + end + end + + class RelineInputMethod < StdioInputMethod + HISTORY = Reline::HISTORY + include HistorySavingAbility + # Creates a new input method object using Reline + def initialize(completor) + IRB.__send__(:set_encoding, Reline.encoding_system_needs.name, override: false) + + super() + + @eof = false + @completor = completor + + Reline.basic_word_break_characters = BASIC_WORD_BREAK_CHARACTERS + Reline.completion_append_character = nil + Reline.completer_quote_characters = '' + Reline.completion_proc = ->(target, preposing, postposing) { + bind = IRB.conf[:MAIN_CONTEXT].workspace.binding + @completion_params = [preposing, target, postposing, bind] + @completor.completion_candidates(preposing, target, postposing, bind: bind) + } + Reline.output_modifier_proc = proc do |input, complete:| + IRB.CurrentContext.colorize_input(input, complete: complete) + end + Reline.dig_perfect_match_proc = ->(matched) { display_document(matched) } + Reline.autocompletion = IRB.conf[:USE_AUTOCOMPLETE] + + if IRB.conf[:USE_AUTOCOMPLETE] + begin + require 'rdoc' + Reline.add_dialog_proc(:show_doc, show_doc_dialog_proc, Reline::DEFAULT_DIALOG_CONTEXT) + rescue LoadError + end + end + end + + def completion_info + autocomplete_message = Reline.autocompletion ? 'Autocomplete' : 'Tab Complete' + "#{autocomplete_message}, #{@completor.inspect}" + end + + def check_termination(&block) + @check_termination_proc = block + end + + def dynamic_prompt(&block) + @prompt_proc = block + end + + def auto_indent(&block) + @auto_indent_proc = block + end + + def retrieve_doc_namespace(matched) + preposing, _target, postposing, bind = @completion_params + @completor.doc_namespace(preposing, matched, postposing, bind: bind) + end + + def rdoc_ri_driver + return @rdoc_ri_driver if defined?(@rdoc_ri_driver) + + begin + require 'rdoc' + rescue LoadError + @rdoc_ri_driver = nil + else + options = {} + options[:extra_doc_dirs] = IRB.conf[:EXTRA_DOC_DIRS] unless IRB.conf[:EXTRA_DOC_DIRS].empty? + @rdoc_ri_driver = RDoc::RI::Driver.new(options) + end + end + + def show_doc_dialog_proc + input_method = self # self is changed in the lambda below. + ->() { + dialog.trap_key = nil + alt_d = [ + [27, 100], # Normal Alt+d when convert-meta isn't used. + # When option/alt is not configured as a meta key in terminal emulator, + # option/alt + d will send a unicode character depend on OS keyboard setting. + [195, 164], # "ä" in somewhere (FIXME: environment information is unknown). + [226, 136, 130] # "∂" Alt+d on Mac keyboard. + ] + + if just_cursor_moving and completion_journey_data.nil? + return nil + end + cursor_pos_to_render, result, pointer, autocomplete_dialog = context.pop(4) + return nil if result.nil? or pointer.nil? or pointer < 0 + + name = input_method.retrieve_doc_namespace(result[pointer]) + # Use first one because document dialog does not support multiple namespaces. + name = name.first if name.is_a?(Array) + + show_easter_egg = name&.match?(/\ARubyVM/) && !ENV['RUBY_YES_I_AM_NOT_A_NORMAL_USER'] + + driver = input_method.rdoc_ri_driver + + if key.match?(dialog.name) + if show_easter_egg + IRB.__send__(:easter_egg) + else + # RDoc::RI::Driver#display_names uses pager command internally. + # Some pager command like `more` doesn't use alternate screen + # so we need to turn on and off alternate screen manually. + begin + print "\e[?1049h" + driver.display_names([name]) + rescue RDoc::RI::Driver::NotFoundError + ensure + print "\e[?1049l" + end + end + end + + begin + name = driver.expand_name(name) + rescue RDoc::RI::Driver::NotFoundError + return nil + rescue + return nil # unknown error + end + doc = nil + used_for_class = false + if not name =~ /#|\./ + found, klasses, includes, extends = driver.classes_and_includes_and_extends_for(name) + if not found.empty? + doc = driver.class_document(name, found, klasses, includes, extends) + used_for_class = true + end + end + unless used_for_class + doc = RDoc::Markup::Document.new + begin + driver.add_method(doc, name) + rescue RDoc::RI::Driver::NotFoundError + doc = nil + rescue + return nil # unknown error + end + end + return nil if doc.nil? + width = 40 + + right_x = cursor_pos_to_render.x + autocomplete_dialog.width + if right_x + width > screen_width + right_width = screen_width - (right_x + 1) + left_x = autocomplete_dialog.column - width + left_x = 0 if left_x < 0 + left_width = width > autocomplete_dialog.column ? autocomplete_dialog.column : width + if right_width.positive? and left_width.positive? + if right_width >= left_width + width = right_width + x = right_x + else + width = left_width + x = left_x + end + elsif right_width.positive? and left_width <= 0 + width = right_width + x = right_x + elsif right_width <= 0 and left_width.positive? + width = left_width + x = left_x + else # Both are negative width. + return nil + end + else + x = right_x + end + formatter = RDoc::Markup::ToAnsi.new + formatter.width = width + dialog.trap_key = alt_d + mod_key = RUBY_PLATFORM.match?(/darwin/) ? "Option" : "Alt" + if show_easter_egg + type = STDOUT.external_encoding == Encoding::UTF_8 ? :unicode : :ascii + contents = IRB.send(:easter_egg_logo, type).split("\n") + message = "Press #{mod_key}+d to see more" + contents[0][0, message.size] = message + else + message = "Press #{mod_key}+d to read the full document" + contents = [message] + doc.accept(formatter).split("\n") + end + contents = contents.take(preferred_dialog_height) + + y = cursor_pos_to_render.y + Reline::DialogRenderInfo.new(pos: Reline::CursorPos.new(x, y), contents: contents, width: width, bg_color: '49') + } + end + + def display_document(matched) + driver = rdoc_ri_driver + return unless driver + + if matched =~ /\A(?:::)?RubyVM/ and not ENV['RUBY_YES_I_AM_NOT_A_NORMAL_USER'] + IRB.__send__(:easter_egg) + return + end + + namespace = retrieve_doc_namespace(matched) + return unless namespace + + if namespace.is_a?(Array) + out = RDoc::Markup::Document.new + namespace.each do |m| + begin + driver.add_method(out, m) + rescue RDoc::RI::Driver::NotFoundError + end + end + driver.display(out) + else + begin + driver.display_names([namespace]) + rescue RDoc::RI::Driver::NotFoundError + end + end + end + + # Reads the next line from this input method. + # + # See IO#gets for more information. + def gets + Reline.input = @stdin + Reline.output = @stdout + Reline.prompt_proc = @prompt_proc + Reline.auto_indent_proc = @auto_indent_proc if @auto_indent_proc + if l = Reline.readmultiline(@prompt, false, &@check_termination_proc) + Reline::HISTORY.push(l) if !l.empty? + @line[@line_no += 1] = l + "\n" + else + @eof = true + l + end + end + + # Whether the end of this input method has been reached, returns +true+ + # if there is no more data to read. + # + # See IO#eof? for more information. + def eof? + @eof + end + + def prompting? + true + end + + # For debug message + def inspect + config = Reline::Config.new + str = "RelineInputMethod with Reline #{Reline::VERSION}" + inputrc_path = File.expand_path(config.inputrc_path) + str += " and #{inputrc_path}" if File.exist?(inputrc_path) + str + end + end + + class ReidlineInputMethod < RelineInputMethod + def initialize + warn <<~MSG.strip + IRB::ReidlineInputMethod is deprecated, please use IRB::RelineInputMethod instead. + MSG + super + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/inspector.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/inspector.rb new file mode 100644 index 00000000..75a257b4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/inspector.rb @@ -0,0 +1,136 @@ +# frozen_string_literal: true +# +# irb/inspector.rb - inspect methods +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# + +module IRB # :nodoc: + + # Convenience method to create a new Inspector, using the given +inspect+ + # proc, and optional +init+ proc and passes them to Inspector.new + # + # irb(main):001:0> ins = IRB::Inspector(proc{ |v| "omg! #{v}" }) + # irb(main):001:0> IRB.CurrentContext.inspect_mode = ins # => omg! # + # irb(main):001:0> "what?" #=> omg! what? + # + def IRB::Inspector(inspect, init = nil) + Inspector.new(inspect, init) + end + + # An irb inspector + # + # In order to create your own custom inspector there are two things you + # should be aware of: + # + # Inspector uses #inspect_value, or +inspect_proc+, for output of return values. + # + # This also allows for an optional #init+, or +init_proc+, which is called + # when the inspector is activated. + # + # Knowing this, you can create a rudimentary inspector as follows: + # + # irb(main):001:0> ins = IRB::Inspector.new(proc{ |v| "omg! #{v}" }) + # irb(main):001:0> IRB.CurrentContext.inspect_mode = ins # => omg! # + # irb(main):001:0> "what?" #=> omg! what? + # + class Inspector + KERNEL_INSPECT = Object.instance_method(:inspect) + # Default inspectors available to irb, this includes: + # + # +:pp+:: Using Kernel#pretty_inspect + # +:yaml+:: Using YAML.dump + # +:marshal+:: Using Marshal.dump + INSPECTORS = {} + + class << self + # Determines the inspector to use where +inspector+ is one of the keys passed + # during inspector definition. + def keys_with_inspector(inspector) + INSPECTORS.select{|k, v| v == inspector}.collect{|k, v| k} + end + + # Example + # + # Inspector.def_inspector(key, init_p=nil){|v| v.inspect} + # Inspector.def_inspector([key1,..], init_p=nil){|v| v.inspect} + # Inspector.def_inspector(key, inspector) + # Inspector.def_inspector([key1,...], inspector) + def def_inspector(key, arg=nil, &block) + if block_given? + inspector = IRB::Inspector(block, arg) + else + inspector = arg + end + + case key + when Array + for k in key + def_inspector(k, inspector) + end + when Symbol + INSPECTORS[key] = inspector + INSPECTORS[key.to_s] = inspector + when String + INSPECTORS[key] = inspector + INSPECTORS[key.intern] = inspector + else + INSPECTORS[key] = inspector + end + end + end + + # Creates a new inspector object, using the given +inspect_proc+ when + # output return values in irb. + def initialize(inspect_proc, init_proc = nil) + @init = init_proc + @inspect = inspect_proc + end + + # Proc to call when the inspector is activated, good for requiring + # dependent libraries. + def init + @init.call if @init + end + + def support_stream_output? + second_parameter_type = @inspect.parameters[1]&.first + second_parameter_type == :req || second_parameter_type == :opt + end + + # Proc to call when the input is evaluated and output in irb. + def inspect_value(v, output, colorize: true) + support_stream_output? ? @inspect.call(v, output, colorize: colorize) : output << @inspect.call(v, colorize: colorize) + rescue => e + puts "An error occurred when inspecting the object: #{e.inspect}" + + begin + puts "Result of Kernel#inspect: #{KERNEL_INSPECT.bind_call(v)}" + '' + rescue => e + puts "An error occurred when running Kernel#inspect: #{e.inspect}" + puts e.backtrace.join("\n") + '' + end + end + end + + Inspector.def_inspector([false, :to_s, :raw]){|v| v.to_s} + Inspector.def_inspector([:p, :inspect]){|v, colorize: true| + Color.colorize_code(v.inspect, colorable: colorize && Color.colorable? && Color.inspect_colorable?(v)) + } + Inspector.def_inspector([true, :pp, :pretty_inspect], proc{require_relative "color_printer"}){|v, output, colorize: true| + IRB::ColorPrinter.pp(v, output, colorize: colorize) + } + Inspector.def_inspector([:yaml, :YAML], proc{require "yaml"}){|v| + begin + YAML.dump(v) + rescue + puts "(can't dump yaml. use inspect)" + v.inspect + end + } + + Inspector.def_inspector([:marshal, :Marshal, :MARSHAL, Marshal]){|v| + Marshal.dump(v) + } +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/lc/error.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/lc/error.rb new file mode 100644 index 00000000..ee0f0478 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/lc/error.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true +# +# irb/lc/error.rb - +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# + +module IRB + # :stopdoc: + + class UnrecognizedSwitch < StandardError + def initialize(val) + super("Unrecognized switch: #{val}") + end + end + class CantReturnToNormalMode < StandardError + def initialize + super("Can't return to normal mode.") + end + end + class IllegalParameter < StandardError + def initialize(val) + super("Invalid parameter(#{val}).") + end + end + class IrbAlreadyDead < StandardError + def initialize + super("Irb is already dead.") + end + end + class IrbSwitchedToCurrentThread < StandardError + def initialize + super("Switched to current thread.") + end + end + class NoSuchJob < StandardError + def initialize(val) + super("No such job(#{val}).") + end + end + class CantChangeBinding < StandardError + def initialize(val) + super("Can't change binding to (#{val}).") + end + end + class UndefinedPromptMode < StandardError + def initialize(val) + super("Undefined prompt mode(#{val}).") + end + end + + # :startdoc: +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/lc/help-message b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/lc/help-message new file mode 100644 index 00000000..37347306 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/lc/help-message @@ -0,0 +1,55 @@ +Usage: irb.rb [options] [programfile] [arguments] + -f Don't initialize from configuration file. + -d Set $DEBUG and $VERBOSE to true (same as 'ruby -d'). + -r load-module Require load-module (same as 'ruby -r'). + -I path Specify $LOAD_PATH directory (same as 'ruby -I'). + -U Set external and internal encodings to UTF-8. + -E ex[:in] Set default external (ex) and internal (in) encodings + (same as 'ruby -E'). + -w Suppress warnings (same as 'ruby -w'). + -W[level=2] Set warning level: 0=silence, 1=medium, 2=verbose + (same as 'ruby -W'). + --context-mode n Set n[0-4] to method to create Binding Object, + when new workspace was created. + --extra-doc-dir Add an extra doc dir for the doc dialog. + --echo Show result (default). + --noecho Don't show result. + --echo-on-assignment + Show result on assignment. + --noecho-on-assignment + Don't show result on assignment. + --truncate-echo-on-assignment + Show truncated result on assignment (default). + --inspect Use 'inspect' for output. + --noinspect Don't use 'inspect' for output. + --no-pager Don't use pager. + --multiline Use multiline editor module (default). + --nomultiline Don't use multiline editor module. + --singleline Use single line editor module. + --nosingleline Don't use single line editor module (default). + --colorize Use color-highlighting (default). + --nocolorize Don't use color-highlighting. + --autocomplete Use auto-completion (default). + --noautocomplete Don't use auto-completion. + --regexp-completor + Use regexp based completion (default). + --type-completor Use type based completion. + --prompt prompt-mode, --prompt-mode prompt-mode + Set prompt mode. Pre-defined prompt modes are: + 'default', 'classic', 'simple', 'inf-ruby', 'xmp', 'null'. + --inf-ruby-mode Use prompt appropriate for inf-ruby-mode on emacs. + Suppresses --multiline and --singleline. + --sample-book-mode, --simple-prompt + Set prompt mode to 'simple'. + --noprompt Don't output prompt. + --script Script mode (default, treat first argument as script) + --noscript No script mode (leave arguments in argv) + --single-irb Share self with sub-irb. + --tracer Show stack trace for each command. + --back-trace-limit n[=16] + Display backtrace top n and bottom n. + --verbose Show details. + --noverbose Don't show details. + -v, --version Print the version of irb. + -h, --help Print help. + -- Separate options of irb from the list of command-line args. diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/lc/ja/error.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/lc/ja/error.rb new file mode 100644 index 00000000..9e2e5b88 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/lc/ja/error.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true +# +# irb/lc/ja/error.rb - +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# + +module IRB + # :stopdoc: + + class UnrecognizedSwitch < StandardError + def initialize(val) + super("スイッチ(#{val})が分りません") + end + end + class CantReturnToNormalMode < StandardError + def initialize + super("Normalモードに戻れません.") + end + end + class IllegalParameter < StandardError + def initialize(val) + super("パラメータ(#{val})が間違っています.") + end + end + class IrbAlreadyDead < StandardError + def initialize + super("Irbは既に死んでいます.") + end + end + class IrbSwitchedToCurrentThread < StandardError + def initialize + super("カレントスレッドに切り替わりました.") + end + end + class NoSuchJob < StandardError + def initialize(val) + super("そのようなジョブ(#{val})はありません.") + end + end + class CantChangeBinding < StandardError + def initialize(val) + super("バインディング(#{val})に変更できません.") + end + end + class UndefinedPromptMode < StandardError + def initialize(val) + super("プロンプトモード(#{val})は定義されていません.") + end + end + + # :startdoc: +end +# vim:fileencoding=utf-8 diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/lc/ja/help-message b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/lc/ja/help-message new file mode 100644 index 00000000..844c67bb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/lc/ja/help-message @@ -0,0 +1,58 @@ +Usage: irb.rb [options] [programfile] [arguments] + -f ~/.irbrc を読み込まない. + -d $DEBUG をtrueにする(ruby -d と同じ) + -r load-module ruby -r と同じ. + -I path $LOAD_PATH に path を追加する. + -U ruby -U と同じ. + -E enc ruby -E と同じ. + -w ruby -w と同じ. + -W[level=2] ruby -W と同じ. + --context-mode n 新しいワークスペースを作成した時に関連する Binding + オブジェクトの作成方法を 0 から 4 のいずれかに設定する. + --extra-doc-dir 指定したディレクトリのドキュメントを追加で読み込む. + --echo 実行結果を表示する(デフォルト). + --noecho 実行結果を表示しない. + --echo-on-assignment + 代入結果を表示する. + --noecho-on-assignment + 代入結果を表示しない. + --truncate-echo-on-assignment + truncateされた代入結果を表示する(デフォルト). + --inspect 結果出力にinspectを用いる. + --noinspect 結果出力にinspectを用いない. + --no-pager ページャを使用しない. + --multiline マルチラインエディタを利用する. + --nomultiline マルチラインエディタを利用しない. + --singleline シングルラインエディタを利用する. + --nosingleline シングルラインエディタを利用しない. + --colorize 色付けを利用する. + --nocolorize 色付けを利用しない. + --autocomplete オートコンプリートを利用する. + --noautocomplete オートコンプリートを利用しない. + --regexp-completor + 補完に正規表現を利用する. + --type-completor 補完に型情報を利用する. + --prompt prompt-mode/--prompt-mode prompt-mode + プロンプトモードを切り替える. + 現在定義されているプロンプトモードは, + default, classic, simple, inf-ruby, xmp, null. + --inf-ruby-mode emacsのinf-ruby-mode用のプロンプト表示を行なう. 特 + に指定がない限り, シングルラインエディタとマルチラ + インエディタは使わなくなる. + --sample-book-mode/--simple-prompt + 非常にシンプルなプロンプトを用いるモードです. + --noprompt プロンプト表示を行なわない. + --script スクリプトモード(最初の引数をスクリプトファイルとして扱う、デフォルト) + --noscript 引数をargvとして扱う. + --single-irb irb 中で self を実行して得られるオブジェクトをサ + ブ irb と共有する. + --tracer コマンド実行時にトレースを行なう. + --back-trace-limit n + バックトレース表示をバックトレースの頭から n, 後ろ + からnだけ行なう. デフォルトは16 + + --verbose 詳細なメッセージを出力する. + --noverbose 詳細なメッセージを出力しない(デフォルト). + -v, --version irbのバージョンを表示する. + -h, --help irb のヘルプを表示する. + -- 以降のコマンドライン引数をオプションとして扱わない. diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/locale.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/locale.rb new file mode 100644 index 00000000..2abcc735 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/locale.rb @@ -0,0 +1,153 @@ +# frozen_string_literal: true +# +# irb/locale.rb - internationalization module +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# + +module IRB # :nodoc: + class Locale + + LOCALE_NAME_RE = %r[ + (?[[:alpha:]]{2,3}) + (?:_ (?[[:alpha:]]{2,3}) )? + (?:\. (?[^@]+) )? + (?:@ (?.*) )? + ]x + LOCALE_DIR = "/lc/" + + LEGACY_ENCODING_ALIAS_MAP = { + 'ujis' => Encoding::EUC_JP, + 'euc' => Encoding::EUC_JP + } + + @@loaded = [] + + def initialize(locale = nil) + @override_encoding = nil + @lang = @territory = @encoding_name = @modifier = nil + @locale = locale || ENV["IRB_LANG"] || ENV["LC_MESSAGES"] || ENV["LC_ALL"] || ENV["LANG"] || "C" + if m = LOCALE_NAME_RE.match(@locale) + @lang, @territory, @encoding_name, @modifier = m[:language], m[:territory], m[:codeset], m[:modifier] + + if @encoding_name + if @encoding = LEGACY_ENCODING_ALIAS_MAP[@encoding_name] + warn(("%s is obsolete. use %s" % ["#{@lang}_#{@territory}.#{@encoding_name}", "#{@lang}_#{@territory}.#{@encoding.name}"]), uplevel: 1) + else + @encoding = Encoding.find(@encoding_name) rescue nil + end + end + end + @encoding ||= (Encoding.find('locale') rescue Encoding::ASCII_8BIT) + end + + attr_reader :lang, :territory, :modifier + + def encoding + @override_encoding || @encoding + end + + def String(mes) + mes = super(mes) + if encoding + mes.encode(encoding, undef: :replace) + else + mes + end + end + + def format(*opts) + String(super(*opts)) + end + + def gets(*rs) + String(super(*rs)) + end + + def readline(*rs) + String(super(*rs)) + end + + def print(*opts) + ary = opts.collect{|opt| String(opt)} + super(*ary) + end + + def printf(*opts) + s = format(*opts) + print s + end + + def puts(*opts) + ary = opts.collect{|opt| String(opt)} + super(*ary) + end + + def load(file) + found = find(file) + if found + unless @@loaded.include?(found) + @@loaded << found # cache + Kernel.load(found) + end + else + raise LoadError, "No such file to load -- #{file}" + end + end + + def find(file, paths = $:) + dir = File.dirname(file) + dir = "" if dir == "." + base = File.basename(file) + + if dir.start_with?('/') + return each_localized_path(dir, base).find{|full_path| File.readable? full_path} + else + return search_file(paths, dir, base) + end + end + + # @param paths load paths in which IRB find a localized file. + # @param dir directory + # @param file basename to be localized + # + # typically, for the parameters and a in paths, it searches + # /// + def search_file(lib_paths, dir, file) + each_localized_path(dir, file) do |lc_path| + lib_paths.each do |libpath| + full_path = File.join(libpath, lc_path) + return full_path if File.readable?(full_path) + end + redo if defined?(Gem) and Gem.try_activate(lc_path) + end + nil + end + + def each_localized_path(dir, file) + return enum_for(:each_localized_path) unless block_given? + each_sublocale do |lc| + yield lc.nil? ? File.join(dir, LOCALE_DIR, file) : File.join(dir, LOCALE_DIR, lc, file) + end + end + + def each_sublocale + if @lang + if @territory + if @encoding_name + yield "#{@lang}_#{@territory}.#{@encoding_name}@#{@modifier}" if @modifier + yield "#{@lang}_#{@territory}.#{@encoding_name}" + end + yield "#{@lang}_#{@territory}@#{@modifier}" if @modifier + yield "#{@lang}_#{@territory}" + end + if @encoding_name + yield "#{@lang}.#{@encoding_name}@#{@modifier}" if @modifier + yield "#{@lang}.#{@encoding_name}" + end + yield "#{@lang}@#{@modifier}" if @modifier + yield "#{@lang}" + end + yield nil + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/nesting_parser.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/nesting_parser.rb new file mode 100644 index 00000000..c1c9a5cc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/nesting_parser.rb @@ -0,0 +1,239 @@ +# frozen_string_literal: true +module IRB + module NestingParser + IGNORE_TOKENS = %i[on_sp on_ignored_nl on_comment on_embdoc_beg on_embdoc on_embdoc_end] + + class << self + # Scan each token and call the given block with array of token and other information for parsing + def scan_opens(tokens) + opens = [] + pending_heredocs = [] + first_token_on_line = true + tokens.each do |t| + skip = false + last_tok, state, args = opens.last + case state + when :in_alias_undef + skip = t.event == :on_kw + when :in_unquoted_symbol + unless IGNORE_TOKENS.include?(t.event) + opens.pop + skip = true + end + when :in_lambda_head + opens.pop if t.event == :on_tlambeg || (t.event == :on_kw && t.tok == 'do') + when :in_method_head + unless IGNORE_TOKENS.include?(t.event) + next_args = [] + body = nil + if args.include?(:receiver) + case t.event + when :on_lparen, :on_ivar, :on_gvar, :on_cvar + # def (receiver). | def @ivar. | def $gvar. | def @@cvar. + next_args << :dot + when :on_kw + case t.tok + when 'self', 'true', 'false', 'nil' + # def self(arg) | def self. + next_args.push(:arg, :dot) + else + # def if(arg) + skip = true + next_args << :arg + end + when :on_op, :on_backtick + # def +(arg) + skip = true + next_args << :arg + when :on_ident, :on_const + # def a(arg) | def a. + next_args.push(:arg, :dot) + end + end + if args.include?(:dot) + # def receiver.name + next_args << :name if t.event == :on_period || (t.event == :on_op && t.tok == '::') + end + if args.include?(:name) + if %i[on_ident on_const on_op on_kw on_backtick].include?(t.event) + # def name(arg) | def receiver.name(arg) + next_args << :arg + skip = true + end + end + if args.include?(:arg) + case t.event + when :on_nl, :on_semicolon + # def receiver.f; + body = :normal + when :on_lparen + # def receiver.f() + next_args << :eq + else + if t.event == :on_op && t.tok == '=' + # def receiver.f = + body = :oneliner + else + # def receiver.f arg + next_args << :arg_without_paren + end + end + end + if args.include?(:eq) + if t.event == :on_op && t.tok == '=' + body = :oneliner + else + body = :normal + end + end + if args.include?(:arg_without_paren) + if %i[on_semicolon on_nl].include?(t.event) + # def f a; + body = :normal + else + # def f a, b + next_args << :arg_without_paren + end + end + if body == :oneliner + opens.pop + elsif body + opens[-1] = [last_tok, nil] + else + opens[-1] = [last_tok, :in_method_head, next_args] + end + end + when :in_for_while_until_condition + if t.event == :on_semicolon || t.event == :on_nl || (t.event == :on_kw && t.tok == 'do') + skip = true if t.event == :on_kw && t.tok == 'do' + opens[-1] = [last_tok, nil] + end + end + + unless skip + case t.event + when :on_kw + case t.tok + when 'begin', 'class', 'module', 'do', 'case' + opens << [t, nil] + when 'end' + opens.pop + when 'def' + opens << [t, :in_method_head, [:receiver, :name]] + when 'if', 'unless' + unless t.state.allbits?(Ripper::EXPR_LABEL) + opens << [t, nil] + end + when 'while', 'until' + unless t.state.allbits?(Ripper::EXPR_LABEL) + opens << [t, :in_for_while_until_condition] + end + when 'ensure', 'rescue' + unless t.state.allbits?(Ripper::EXPR_LABEL) + opens.pop + opens << [t, nil] + end + when 'alias' + opens << [t, :in_alias_undef, 2] + when 'undef' + opens << [t, :in_alias_undef, 1] + when 'elsif', 'else', 'when' + opens.pop + opens << [t, nil] + when 'for' + opens << [t, :in_for_while_until_condition] + when 'in' + if last_tok&.event == :on_kw && %w[case in].include?(last_tok.tok) && first_token_on_line + opens.pop + opens << [t, nil] + end + end + when :on_tlambda + opens << [t, :in_lambda_head] + when :on_lparen, :on_lbracket, :on_lbrace, :on_tlambeg, :on_embexpr_beg, :on_embdoc_beg + opens << [t, nil] + when :on_rparen, :on_rbracket, :on_rbrace, :on_embexpr_end, :on_embdoc_end + opens.pop + when :on_heredoc_beg + pending_heredocs << t + when :on_heredoc_end + opens.pop + when :on_backtick + opens << [t, nil] unless t.state == Ripper::EXPR_ARG + when :on_tstring_beg, :on_words_beg, :on_qwords_beg, :on_symbols_beg, :on_qsymbols_beg, :on_regexp_beg + opens << [t, nil] + when :on_tstring_end, :on_regexp_end, :on_label_end + opens.pop + when :on_symbeg + if t.tok == ':' + opens << [t, :in_unquoted_symbol] + else + opens << [t, nil] + end + end + end + if t.event == :on_nl || t.event == :on_semicolon + first_token_on_line = true + elsif t.event != :on_sp + first_token_on_line = false + end + if pending_heredocs.any? && t.tok.include?("\n") + pending_heredocs.reverse_each { |t| opens << [t, nil] } + pending_heredocs = [] + end + if opens.last && opens.last[1] == :in_alias_undef && !IGNORE_TOKENS.include?(t.event) && t.event != :on_heredoc_end + tok, state, arg = opens.pop + opens << [tok, state, arg - 1] if arg >= 1 + end + yield t, opens if block_given? + end + opens.map(&:first) + pending_heredocs.reverse + end + + def open_tokens(tokens) + # scan_opens without block will return a list of open tokens at last token position + scan_opens(tokens) + end + + # Calculates token information [line_tokens, prev_opens, next_opens, min_depth] for each line. + # Example code + # ["hello + # world"+( + # First line + # line_tokens: [[lbracket, '['], [tstring_beg, '"'], [tstring_content("hello\nworld"), "hello\n"]] + # prev_opens: [] + # next_tokens: [lbracket, tstring_beg] + # min_depth: 0 (minimum at beginning of line) + # Second line + # line_tokens: [[tstring_content("hello\nworld"), "world"], [tstring_end, '"'], [op, '+'], [lparen, '(']] + # prev_opens: [lbracket, tstring_beg] + # next_tokens: [lbracket, lparen] + # min_depth: 1 (minimum just after tstring_end) + def parse_by_line(tokens) + line_tokens = [] + prev_opens = [] + min_depth = 0 + output = [] + last_opens = scan_opens(tokens) do |t, opens| + depth = t == opens.last&.first ? opens.size - 1 : opens.size + min_depth = depth if depth < min_depth + if t.tok.include?("\n") + t.tok.each_line do |line| + line_tokens << [t, line] + next if line[-1] != "\n" + next_opens = opens.map(&:first) + output << [line_tokens, prev_opens, next_opens, min_depth] + prev_opens = next_opens + min_depth = prev_opens.size + line_tokens = [] + end + else + line_tokens << [t, t.tok] + end + end + output << [line_tokens, prev_opens, last_opens, min_depth] if line_tokens.any? + output + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/notifier.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/notifier.rb new file mode 100644 index 00000000..dc1b9ef1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/notifier.rb @@ -0,0 +1,230 @@ +# frozen_string_literal: true +# +# notifier.rb - output methods used by irb +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# + +require_relative "output-method" + +module IRB + # An output formatter used internally by the lexer. + module Notifier + class ErrUndefinedNotifier < StandardError + def initialize(val) + super("undefined notifier level: #{val} is specified") + end + end + class ErrUnrecognizedLevel < StandardError + def initialize(val) + super("unrecognized notifier level: #{val} is specified") + end + end + + # Define a new Notifier output source, returning a new CompositeNotifier + # with the given +prefix+ and +output_method+. + # + # The optional +prefix+ will be appended to all objects being inspected + # during output, using the given +output_method+ as the output source. If + # no +output_method+ is given, StdioOutputMethod will be used, and all + # expressions will be sent directly to STDOUT without any additional + # formatting. + def def_notifier(prefix = "", output_method = StdioOutputMethod.new) + CompositeNotifier.new(prefix, output_method) + end + module_function :def_notifier + + # An abstract class, or superclass, for CompositeNotifier and + # LeveledNotifier to inherit. It provides several wrapper methods for the + # OutputMethod object used by the Notifier. + class AbstractNotifier + # Creates a new Notifier object + def initialize(prefix, base_notifier) + @prefix = prefix + @base_notifier = base_notifier + end + + # The +prefix+ for this Notifier, which is appended to all objects being + # inspected during output. + attr_reader :prefix + + # A wrapper method used to determine whether notifications are enabled. + # + # Defaults to +true+. + def notify? + true + end + + # See OutputMethod#print for more detail. + def print(*opts) + @base_notifier.print prefix, *opts if notify? + end + + # See OutputMethod#printn for more detail. + def printn(*opts) + @base_notifier.printn prefix, *opts if notify? + end + + # See OutputMethod#printf for more detail. + def printf(format, *opts) + @base_notifier.printf(prefix + format, *opts) if notify? + end + + # See OutputMethod#puts for more detail. + def puts(*objs) + if notify? + @base_notifier.puts(*objs.collect{|obj| prefix + obj.to_s}) + end + end + + # Same as #ppx, except it uses the #prefix given during object + # initialization. + # See OutputMethod#ppx for more detail. + def pp(*objs) + if notify? + @base_notifier.ppx @prefix, *objs + end + end + + # Same as #pp, except it concatenates the given +prefix+ with the #prefix + # given during object initialization. + # + # See OutputMethod#ppx for more detail. + def ppx(prefix, *objs) + if notify? + @base_notifier.ppx @prefix+prefix, *objs + end + end + + # Execute the given block if notifications are enabled. + def exec_if + yield(@base_notifier) if notify? + end + end + + # A class that can be used to create a group of notifier objects with the + # intent of representing a leveled notification system for irb. + # + # This class will allow you to generate other notifiers, and assign them + # the appropriate level for output. + # + # The Notifier class provides a class-method Notifier.def_notifier to + # create a new composite notifier. Using the first composite notifier + # object you create, sibling notifiers can be initialized with + # #def_notifier. + class CompositeNotifier < AbstractNotifier + # Create a new composite notifier object with the given +prefix+, and + # +base_notifier+ to use for output. + def initialize(prefix, base_notifier) + super + + @notifiers = [D_NOMSG] + @level_notifier = D_NOMSG + end + + # List of notifiers in the group + attr_reader :notifiers + + # Creates a new LeveledNotifier in the composite #notifiers group. + # + # The given +prefix+ will be assigned to the notifier, and +level+ will + # be used as the index of the #notifiers Array. + # + # This method returns the newly created instance. + def def_notifier(level, prefix = "") + notifier = LeveledNotifier.new(self, level, prefix) + @notifiers[level] = notifier + notifier + end + + # Returns the leveled notifier for this object + attr_reader :level_notifier + alias level level_notifier + + # Sets the leveled notifier for this object. + # + # When the given +value+ is an instance of AbstractNotifier, + # #level_notifier is set to the given object. + # + # When an Integer is given, #level_notifier is set to the notifier at the + # index +value+ in the #notifiers Array. + # + # If no notifier exists at the index +value+ in the #notifiers Array, an + # ErrUndefinedNotifier exception is raised. + # + # An ErrUnrecognizedLevel exception is raised if the given +value+ is not + # found in the existing #notifiers Array, or an instance of + # AbstractNotifier + def level_notifier=(value) + case value + when AbstractNotifier + @level_notifier = value + when Integer + l = @notifiers[value] + raise ErrUndefinedNotifier, value unless l + @level_notifier = l + else + raise ErrUnrecognizedLevel, value unless l + end + end + + alias level= level_notifier= + end + + # A leveled notifier is comparable to the composite group from + # CompositeNotifier#notifiers. + class LeveledNotifier < AbstractNotifier + include Comparable + + # Create a new leveled notifier with the given +base+, and +prefix+ to + # send to AbstractNotifier.new + # + # The given +level+ is used to compare other leveled notifiers in the + # CompositeNotifier group to determine whether or not to output + # notifications. + def initialize(base, level, prefix) + super(prefix, base) + + @level = level + end + + # The current level of this notifier object + attr_reader :level + + # Compares the level of this notifier object with the given +other+ + # notifier. + # + # See the Comparable module for more information. + def <=>(other) + @level <=> other.level + end + + # Whether to output messages to the output method, depending on the level + # of this notifier object. + def notify? + @base_notifier.level >= self + end + end + + # NoMsgNotifier is a LeveledNotifier that's used as the default notifier + # when creating a new CompositeNotifier. + # + # This notifier is used as the +zero+ index, or level +0+, for + # CompositeNotifier#notifiers, and will not output messages of any sort. + class NoMsgNotifier < LeveledNotifier + # Creates a new notifier that should not be used to output messages. + def initialize + @base_notifier = nil + @level = 0 + @prefix = "" + end + + # Ensures notifications are ignored, see AbstractNotifier#notify? for + # more information. + def notify? + false + end + end + + D_NOMSG = NoMsgNotifier.new # :nodoc: + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/output-method.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/output-method.rb new file mode 100644 index 00000000..69942f47 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/output-method.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: true +# +# output-method.rb - output methods used by irb +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# + +module IRB + # An abstract output class for IO in irb. This is mainly used internally by + # IRB::Notifier. You can define your own output method to use with Irb.new, + # or Context.new + class OutputMethod + # Open this method to implement your own output method, raises a + # NotImplementedError if you don't define #print in your own class. + def print(*opts) + raise NotImplementedError + end + + # Prints the given +opts+, with a newline delimiter. + def printn(*opts) + print opts.join(" "), "\n" + end + + # Extends IO#printf to format the given +opts+ for Kernel#sprintf using + # #parse_printf_format + def printf(format, *opts) + if /(%*)%I/ =~ format + format, opts = parse_printf_format(format, opts) + end + print sprintf(format, *opts) + end + + # Returns an array of the given +format+ and +opts+ to be used by + # Kernel#sprintf, if there was a successful Regexp match in the given + # +format+ from #printf + # + # % + # [#0- +] + # (\*|\*[1-9][0-9]*\$|[1-9][0-9]*) + # .(\*|\*[1-9][0-9]*\$|[1-9][0-9]*|)? + # #(hh|h|l|ll|L|q|j|z|t) + # [diouxXeEfgGcsb%] + def parse_printf_format(format, opts) + return format, opts if $1.size % 2 == 1 + end + + # Calls #print on each element in the given +objs+, followed by a newline + # character. + def puts(*objs) + for obj in objs + print(*obj) + print "\n" + end + end + + # Prints the given +objs+ calling Object#inspect on each. + # + # See #puts for more detail. + def pp(*objs) + puts(*objs.collect{|obj| obj.inspect}) + end + + # Prints the given +objs+ calling Object#inspect on each and appending the + # given +prefix+. + # + # See #puts for more detail. + def ppx(prefix, *objs) + puts(*objs.collect{|obj| prefix+obj.inspect}) + end + + end + + # A standard output printer + class StdioOutputMethod < OutputMethod + # Prints the given +opts+ to standard output, see IO#print for more + # information. + def print(*opts) + STDOUT.print(*opts) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/pager.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/pager.rb new file mode 100644 index 00000000..89e1e710 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/pager.rb @@ -0,0 +1,213 @@ +# frozen_string_literal: true + +require 'reline' + +module IRB + # The implementation of this class is borrowed from RDoc's lib/rdoc/ri/driver.rb. + # Please do NOT use this class directly outside of IRB. + class Pager + PAGE_COMMANDS = [ENV['RI_PAGER'], ENV['PAGER'], 'less', 'more'].compact.uniq + + class << self + def page_content(content, **options) + if content_exceeds_screen_height?(content) + page(**options) do |io| + io.puts content + end + else + $stdout.puts content + end + end + + def page(retain_content: false) + if should_page? && pager = setup_pager(retain_content: retain_content) + begin + pid = pager.pid + yield pager + ensure + pager.close + end + else + yield $stdout + end + # When user presses Ctrl-C, IRB would raise `IRB::Abort` + # But since Pager is implemented by running paging commands like `less` in another process with `IO.popen`, + # the `IRB::Abort` exception only interrupts IRB's execution but doesn't affect the pager + # So to properly terminate the pager with Ctrl-C, we need to catch `IRB::Abort` and kill the pager process + rescue IRB::Abort + begin + begin + Process.kill("TERM", pid) if pid + rescue Errno::EINVAL + # SIGTERM not supported (windows) + Process.kill("KILL", pid) + end + rescue Errno::ESRCH + # Pager process already terminated + end + nil + rescue Errno::EPIPE + end + + def should_page? + IRB.conf[:USE_PAGER] && STDIN.tty? && (ENV.key?("TERM") && ENV["TERM"] != "dumb") + end + + def page_with_preview(width, height, formatter_proc) + overflow_callback = ->(lines) do + modified_output = formatter_proc.call(lines.join, true) + content, = take_first_page(width, [height - 2, 0].max) {|o| o.write modified_output } + content = content.chomp + content = "#{content}\e[0m" if Color.colorable? + $stdout.puts content + $stdout.puts 'Preparing full inspection value...' + end + out = PageOverflowIO.new(width, height, overflow_callback, delay: 0.1) + yield out + content = formatter_proc.call(out.string, out.multipage?) + if out.multipage? + page(retain_content: true) do |io| + io.puts content + end + else + $stdout.puts content + end + end + + def take_first_page(width, height) + overflow_callback = proc do |lines| + return lines.join, true + end + out = Pager::PageOverflowIO.new(width, height, overflow_callback) + yield out + [out.string, false] + end + + private + + def content_exceeds_screen_height?(content) + screen_height, screen_width = begin + Reline.get_screen_size + rescue Errno::EINVAL + [24, 80] + end + + pageable_height = screen_height - 3 # leave some space for previous and the current prompt + + return true if content.lines.size > pageable_height + + _, overflow = take_first_page(screen_width, pageable_height) {|out| out.write content } + overflow + end + + def setup_pager(retain_content:) + require 'shellwords' + + PAGE_COMMANDS.each do |pager_cmd| + cmd = Shellwords.split(pager_cmd) + next if cmd.empty? + + if cmd.first == 'less' + cmd << '-R' unless cmd.include?('-R') + cmd << '-X' if retain_content && !cmd.include?('-X') + end + + begin + io = IO.popen(cmd, 'w') + rescue + next + end + + if $? && $?.pid == io.pid && $?.exited? # pager didn't work + next + end + + return io + end + + nil + end + end + + # Writable IO that has page overflow callback + class PageOverflowIO + attr_reader :string, :first_page_lines + + # Maximum size of a single cell in terminal + # Assumed worst case: "\e[1;3;4;9;38;2;255;128;128;48;2;128;128;255mA\e[0m" + # bold, italic, underline, crossed_out, RGB forgound, RGB background + MAX_CHAR_PER_CELL = 50 + + def initialize(width, height, overflow_callback, delay: nil) + @lines = [] + @first_page_lines = nil + @width = width + @height = height + @buffer = +'' + @overflow_callback = overflow_callback + @col = 0 + @string = +'' + @multipage = false + @delay_until = (Time.now + delay if delay) + end + + def puts(text = '') + text = text.to_s unless text.is_a?(String) + write(text) + write("\n") unless text.end_with?("\n") + end + + def write(text) + text = text.to_s unless text.is_a?(String) + @string << text + if @multipage + if @delay_until && Time.now > @delay_until + @overflow_callback.call(@first_page_lines) + @delay_until = nil + end + return + end + + overflow_size = (@width * (@height - @lines.size) + @width - @col) * MAX_CHAR_PER_CELL + if text.size >= overflow_size + text = text[0, overflow_size] + overflow = true + end + @buffer << text + @col += Reline::Unicode.calculate_width(text, true) + if text.include?("\n") || @col >= @width + @buffer.lines.each do |line| + wrapped_lines = Reline::Unicode.split_by_width(line.chomp, @width).first.compact + wrapped_lines.pop if wrapped_lines.last == '' + @lines.concat(wrapped_lines) + if line.end_with?("\n") + if @lines.empty? || @lines.last.end_with?("\n") + @lines << "\n" + else + @lines[-1] += "\n" + end + end + end + @buffer.clear + @buffer << @lines.pop if !@lines.empty? && !@lines.last.end_with?("\n") + @col = Reline::Unicode.calculate_width(@buffer, true) + end + if overflow || @lines.size > @height || (@lines.size == @height && @col > 0) + @first_page_lines = @lines.take(@height) + if !@delay_until || Time.now > @delay_until + @overflow_callback.call(@first_page_lines) + @delay_until = nil + end + @multipage = true + end + end + + def multipage? + @multipage + end + + alias print write + alias << write + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ruby-lex.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ruby-lex.rb new file mode 100644 index 00000000..3abb53b4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ruby-lex.rb @@ -0,0 +1,476 @@ +# frozen_string_literal: true +# +# irb/ruby-lex.rb - ruby lexcal analyzer +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# + +require "ripper" +require "jruby" if RUBY_ENGINE == "jruby" +require_relative "nesting_parser" + +module IRB + # :stopdoc: + class RubyLex + ASSIGNMENT_NODE_TYPES = [ + # Local, instance, global, class, constant, instance, and index assignment: + # "foo = bar", + # "@foo = bar", + # "$foo = bar", + # "@@foo = bar", + # "::Foo = bar", + # "a::Foo = bar", + # "Foo = bar" + # "foo.bar = 1" + # "foo[1] = bar" + :assign, + + # Operation assignment: + # "foo += bar" + # "foo -= bar" + # "foo ||= bar" + # "foo &&= bar" + :opassign, + + # Multiple assignment: + # "foo, bar = 1, 2 + :massign, + ] + + ERROR_TOKENS = [ + :on_parse_error, + :compile_error, + :on_assign_error, + :on_alias_error, + :on_class_name_error, + :on_param_error + ] + + LTYPE_TOKENS = %i[ + on_heredoc_beg on_tstring_beg + on_regexp_beg on_symbeg on_backtick + on_symbols_beg on_qsymbols_beg + on_words_beg on_qwords_beg + ] + + class TerminateLineInput < StandardError + def initialize + super("Terminate Line Input") + end + end + + class << self + def compile_with_errors_suppressed(code, line_no: 1) + begin + result = yield code, line_no + rescue ArgumentError + # Ruby can issue an error for the code if there is an + # incomplete magic comment for encoding in it. Force an + # expression with a new line before the code in this + # case to prevent magic comment handling. To make sure + # line numbers in the lexed code remain the same, + # decrease the line number by one. + code = ";\n#{code}" + line_no -= 1 + result = yield code, line_no + end + result + end + + def generate_local_variables_assign_code(local_variables) + "#{local_variables.join('=')}=nil;" unless local_variables.empty? + end + + # Some part of the code is not included in Ripper's token. + # Example: DATA part, token after heredoc_beg when heredoc has unclosed embexpr. + # With interpolated tokens, tokens.map(&:tok).join will be equal to code. + def interpolate_ripper_ignored_tokens(code, tokens) + line_positions = [0] + code.lines.each do |line| + line_positions << line_positions.last + line.bytesize + end + prev_byte_pos = 0 + interpolated = [] + prev_line = 1 + tokens.each do |t| + line, col = t.pos + byte_pos = line_positions[line - 1] + col + if prev_byte_pos < byte_pos + tok = code.byteslice(prev_byte_pos...byte_pos) + pos = [prev_line, prev_byte_pos - line_positions[prev_line - 1]] + interpolated << Ripper::Lexer::Elem.new(pos, :on_ignored_by_ripper, tok, 0) + prev_line += tok.count("\n") + end + interpolated << t + prev_byte_pos = byte_pos + t.tok.bytesize + prev_line += t.tok.count("\n") + end + if prev_byte_pos < code.bytesize + tok = code.byteslice(prev_byte_pos..) + pos = [prev_line, prev_byte_pos - line_positions[prev_line - 1]] + interpolated << Ripper::Lexer::Elem.new(pos, :on_ignored_by_ripper, tok, 0) + end + interpolated + end + + def ripper_lex_without_warning(code, local_variables: []) + verbose, $VERBOSE = $VERBOSE, nil + lvars_code = generate_local_variables_assign_code(local_variables) + original_code = code + if lvars_code + code = "#{lvars_code}\n#{code}" + line_no = 0 + else + line_no = 1 + end + + compile_with_errors_suppressed(code, line_no: line_no) do |inner_code, line_no| + lexer = Ripper::Lexer.new(inner_code, '-', line_no) + tokens = [] + lexer.scan.each do |t| + next if t.pos.first == 0 + prev_tk = tokens.last + position_overlapped = prev_tk && t.pos[0] == prev_tk.pos[0] && t.pos[1] < prev_tk.pos[1] + prev_tk.tok.bytesize + if position_overlapped + tokens[-1] = t if ERROR_TOKENS.include?(prev_tk.event) && !ERROR_TOKENS.include?(t.event) + else + tokens << t + end + end + interpolate_ripper_ignored_tokens(original_code, tokens) + end + ensure + $VERBOSE = verbose + end + end + + def check_code_state(code, local_variables:) + tokens = self.class.ripper_lex_without_warning(code, local_variables: local_variables) + opens = NestingParser.open_tokens(tokens) + [tokens, opens, code_terminated?(code, tokens, opens, local_variables: local_variables)] + end + + def code_terminated?(code, tokens, opens, local_variables:) + case check_code_syntax(code, local_variables: local_variables) + when :unrecoverable_error + true + when :recoverable_error + false + when :other_error + opens.empty? && !should_continue?(tokens) + when :valid + !should_continue?(tokens) + end + end + + def assignment_expression?(code, local_variables:) + # Try to parse the code and check if the last of possibly multiple + # expressions is an assignment type. + + # If the expression is invalid, Ripper.sexp should return nil which will + # result in false being returned. Any valid expression should return an + # s-expression where the second element of the top level array is an + # array of parsed expressions. The first element of each expression is the + # expression's type. + verbose, $VERBOSE = $VERBOSE, nil + code = "#{RubyLex.generate_local_variables_assign_code(local_variables) || 'nil;'}\n#{code}" + # Get the last node_type of the line. drop(1) is to ignore the local_variables_assign_code part. + node_type = Ripper.sexp(code)&.dig(1)&.drop(1)&.dig(-1, 0) + ASSIGNMENT_NODE_TYPES.include?(node_type) + ensure + $VERBOSE = verbose + end + + def should_continue?(tokens) + # Look at the last token and check if IRB need to continue reading next line. + # Example code that should continue: `a\` `a +` `a.` + # Trailing spaces, newline, comments are skipped + return true if tokens.last&.event == :on_sp && tokens.last.tok == "\\\n" + + tokens.reverse_each do |token| + case token.event + when :on_sp, :on_nl, :on_ignored_nl, :on_comment, :on_embdoc_beg, :on_embdoc, :on_embdoc_end + # Skip + when :on_regexp_end, :on_heredoc_end, :on_semicolon + # State is EXPR_BEG but should not continue + return false + else + # Endless range should not continue + return false if token.event == :on_op && token.tok.match?(/\A\.\.\.?\z/) + + # EXPR_DOT and most of the EXPR_BEG should continue + return token.state.anybits?(Ripper::EXPR_BEG | Ripper::EXPR_DOT) + end + end + false + end + + def check_code_syntax(code, local_variables:) + lvars_code = RubyLex.generate_local_variables_assign_code(local_variables) + code = "#{lvars_code}\n#{code}" + + begin # check if parser error are available + verbose, $VERBOSE = $VERBOSE, nil + case RUBY_ENGINE + when 'ruby' + self.class.compile_with_errors_suppressed(code) do |inner_code, line_no| + RubyVM::InstructionSequence.compile(inner_code, nil, nil, line_no) + end + when 'jruby' + JRuby.compile_ir(code) + else + catch(:valid) do + eval("BEGIN { throw :valid, true }\n#{code}") + false + end + end + rescue EncodingError + # This is for a hash with invalid encoding symbol, {"\xAE": 1} + :unrecoverable_error + rescue SyntaxError => e + case e.message + when /unexpected keyword_end/ + # "syntax error, unexpected keyword_end" + # + # example: + # if ( + # end + # + # example: + # end + return :unrecoverable_error + when /unexpected '\.'/ + # "syntax error, unexpected '.'" + # + # example: + # . + return :unrecoverable_error + when /unexpected tREGEXP_BEG/ + # "syntax error, unexpected tREGEXP_BEG, expecting keyword_do or '{' or '('" + # + # example: + # method / f / + return :unrecoverable_error + when /unterminated (?:string|regexp) meets end of file/ + # "unterminated regexp meets end of file" + # + # example: + # / + # + # "unterminated string meets end of file" + # + # example: + # ' + return :recoverable_error + when /unexpected end-of-input/ + # "syntax error, unexpected end-of-input, expecting keyword_end" + # + # example: + # if true + # hoge + # if false + # fuga + # end + return :recoverable_error + else + return :other_error + end + ensure + $VERBOSE = verbose + end + :valid + end + + def calc_indent_level(opens) + indent_level = 0 + opens.each_with_index do |t, index| + case t.event + when :on_heredoc_beg + if opens[index + 1]&.event != :on_heredoc_beg + if t.tok.match?(/^<<[~-]/) + indent_level += 1 + else + indent_level = 0 + end + end + when :on_tstring_beg, :on_regexp_beg, :on_symbeg, :on_backtick + # No indent: "", //, :"", `` + # Indent: %(), %r(), %i(), %x() + indent_level += 1 if t.tok.start_with? '%' + when :on_embdoc_beg + indent_level = 0 + else + indent_level += 1 unless t.tok == 'alias' || t.tok == 'undef' + end + end + indent_level + end + + FREE_INDENT_TOKENS = %i[on_tstring_beg on_backtick on_regexp_beg on_symbeg] + + def free_indent_token?(token) + FREE_INDENT_TOKENS.include?(token&.event) + end + + # Calculates the difference of pasted code's indent and indent calculated from tokens + def indent_difference(lines, line_results, line_index) + loop do + _tokens, prev_opens, _next_opens, min_depth = line_results[line_index] + open_token = prev_opens.last + if !open_token || (open_token.event != :on_heredoc_beg && !free_indent_token?(open_token)) + # If the leading whitespace is an indent, return the difference + indent_level = calc_indent_level(prev_opens.take(min_depth)) + calculated_indent = 2 * indent_level + actual_indent = lines[line_index][/^ */].size + return actual_indent - calculated_indent + elsif open_token.event == :on_heredoc_beg && open_token.tok.match?(/^<<[^-~]/) + return 0 + end + # If the leading whitespace is not an indent but part of a multiline token + # Calculate base_indent of the multiline token's beginning line + line_index = open_token.pos[0] - 1 + end + end + + def process_indent_level(tokens, lines, line_index, is_newline) + line_results = NestingParser.parse_by_line(tokens) + result = line_results[line_index] + if result + _tokens, prev_opens, next_opens, min_depth = result + else + # When last line is empty + prev_opens = next_opens = line_results.last[2] + min_depth = next_opens.size + end + + # To correctly indent line like `end.map do`, we use shortest open tokens on each line for indent calculation. + # Shortest open tokens can be calculated by `opens.take(min_depth)` + indent = 2 * calc_indent_level(prev_opens.take(min_depth)) + + preserve_indent = lines[line_index - (is_newline ? 1 : 0)][/^ */].size + + prev_open_token = prev_opens.last + next_open_token = next_opens.last + + # Calculates base indent for pasted code on the line where prev_open_token is located + # irb(main):001:1* if a # base_indent is 2, indent calculated from tokens is 0 + # irb(main):002:1* if b # base_indent is 6, indent calculated from tokens is 2 + # irb(main):003:0> c # base_indent is 6, indent calculated from tokens is 4 + if prev_open_token + base_indent = [0, indent_difference(lines, line_results, prev_open_token.pos[0] - 1)].max + else + base_indent = 0 + end + + if free_indent_token?(prev_open_token) + if is_newline && prev_open_token.pos[0] == line_index + # First newline inside free-indent token + base_indent + indent + else + # Accept any number of indent inside free-indent token + preserve_indent + end + elsif prev_open_token&.event == :on_embdoc_beg || next_open_token&.event == :on_embdoc_beg + if prev_open_token&.event == next_open_token&.event + # Accept any number of indent inside embdoc content + preserve_indent + else + # =begin or =end + 0 + end + elsif prev_open_token&.event == :on_heredoc_beg + tok = prev_open_token.tok + if prev_opens.size <= next_opens.size + if is_newline && lines[line_index].empty? && line_results[line_index - 1][1].last != next_open_token + # First line in heredoc + tok.match?(/^<<[-~]/) ? base_indent + indent : indent + elsif tok.match?(/^<<~/) + # Accept extra indent spaces inside `<<~` heredoc + [base_indent + indent, preserve_indent].max + else + # Accept any number of indent inside other heredoc + preserve_indent + end + else + # Heredoc close + prev_line_indent_level = calc_indent_level(prev_opens) + tok.match?(/^<<[~-]/) ? base_indent + 2 * (prev_line_indent_level - 1) : 0 + end + else + base_indent + indent + end + end + + def ltype_from_open_tokens(opens) + start_token = opens.reverse_each.find do |tok| + LTYPE_TOKENS.include?(tok.event) + end + return nil unless start_token + + case start_token&.event + when :on_tstring_beg + case start_token&.tok + when ?" then ?" + when /^%.$/ then ?" + when /^%Q.$/ then ?" + when ?' then ?' + when /^%q.$/ then ?' + end + when :on_regexp_beg then ?/ + when :on_symbeg then ?: + when :on_backtick then ?` + when :on_qwords_beg then ?] + when :on_words_beg then ?] + when :on_qsymbols_beg then ?] + when :on_symbols_beg then ?] + when :on_heredoc_beg + start_token&.tok =~ /<<[-~]?(['"`])\w+\1/ + $1 || ?" + else + nil + end + end + + def check_termination_in_prev_line(code, local_variables:) + tokens = self.class.ripper_lex_without_warning(code, local_variables: local_variables) + past_first_newline = false + index = tokens.rindex do |t| + # traverse first token before last line + if past_first_newline + if t.tok.include?("\n") + true + end + elsif t.tok.include?("\n") + past_first_newline = true + false + else + false + end + end + + if index + first_token = nil + last_line_tokens = tokens[(index + 1)..(tokens.size - 1)] + last_line_tokens.each do |t| + unless [:on_sp, :on_ignored_sp, :on_comment].include?(t.event) + first_token = t + break + end + end + + if first_token && first_token.state != Ripper::EXPR_DOT + tokens_without_last_line = tokens[0..index] + code_without_last_line = tokens_without_last_line.map(&:tok).join + opens_without_last_line = NestingParser.open_tokens(tokens_without_last_line) + if code_terminated?(code_without_last_line, tokens_without_last_line, opens_without_last_line, local_variables: local_variables) + return last_line_tokens.map(&:tok).join + end + end + end + false + end + end + # :startdoc: +end + +RubyLex = IRB::RubyLex +Object.deprecate_constant(:RubyLex) diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ruby_logo.aa b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ruby_logo.aa new file mode 100644 index 00000000..d0143a44 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ruby_logo.aa @@ -0,0 +1,118 @@ +TYPE: ASCII_LARGE + + ,,,;;;;;;;;;;;;;;;;;;;;;;,, + ,,,;;;;;;;;;,, ,;;;' ''';;, + ,,;;;''' ';;;, ,,;;'' '';, + ,;;'' ;;;;;;;;,,,,,, ';; + ,;;'' ;;;;';;;'''';;;;;;;;;,,,;; + ,,;'' ;;;; ';;, ''''';;, + ,;;' ;;;' ';;, ;; + ,;;' ,;;; '';,, ;; + ,;;' ;;; ';;, ,;; + ;;' ;;;' '';,, ;;; + ,;' ;;;; ';;, ;;' + ,;;' ,;;;;' ,,,,,,,,,,,,;;;;; + ,;' ,;;;;;;;;;;;;;;;;;;;;'''''''';;; + ;;' ,;;;;;;;;;,, ;;;; + ;;' ,;;;'' ;;, ';;,, ,;;;; + ;;' ,;;;' ;; '';;, ,;';;; + ;;' ,;;;' ;;, '';;,, ,;',;;; + ,;;; ,;;;' ;; '';;,, ,;' ;;;' + ;;;; ,,;;;' ;;, ';;;' ;;; +,;;; ,;;;;' ;; ,;;; ;;; +;;;;; ,,;;;;;' ;;, ,;';; ;;; +;;;;;, ,,;;;;;;;' ;; ,;;' ;;; ;;; +;;;;;;;,,,,,,,;;;;;;;;;;;;;;,,, ;;, ,;' ;; ;;; +;;' ;;;;;;;;;;'''' ,;';; ''';;;;,,, ;; ,;; ;; ;;; +;; ;;;'' ;; ';; ''';;;;,,,, ;;, ,;;' ;;, ;; +;; ;;;;, ;;' ';; ''';;;;,,;;;;' ';; ;; +;;;;;;';, ,;; ;; '';;;;, ;;,;; +;;; ;; ;;, ;; ;; ,;;' ';;, ;;;;; +;; ;;; ;;, ;;' ;; ,,;'' ';;, ;;;;; +;; ;; ;; ;; ;; ,;;' '';, ;;;; +;;,;; ;; ;;' ;; ,;;'' ';,, ;;;' + ;;;; ';; ,;; ;;,,;;'' ';;, ;;; + ';;; ';; ;; ,;;;;;;;;;;;;;,,,,,,,,,,,, ';;;;; + ';, ';,;;' ,,,;;'' '''''''';;;;;;;;;;;;;;;;;;; + ';;,,, ;;;; ,,,,;;;;;;,,,,,;;;;;;;;;;;;;;;;;;;'''''''''''''' + ''';;;;;;;;;;;;;;''''''''''''''' +TYPE: ASCII + ,,,;;;;''''';;;'';, + ,,;'' ';;,;;; ', + ,,'' ;;'';'''';;;;;; + ,;' ;; ',, ; + ,;' ,;' ';, ; + ;' ,;; ',,,; + ,' ,;;,,,,,,,,,,,;;;; + ;' ;;';;;; ,;; + ;' ,;' ;; '',, ,;;; + ;; ,;' ; '';, ,; ;' +;; ,;;' ;; ;; ;; +;;, ,,;;' ; ;'; ;; +;';;,,,,;;;;;;;,,, ;; ,' ; ;; +; ;;''' ,;'; ''';,,, ; ,;' ;;;; +;;;;, ; '; ''';;;' ';;; +;'; ;, ;' '; ,;' ', ;;; +;;; ; ,; '; ,,' ',, ;; +;;; '; ;' ';,,'' ';,;; + '; ';,; ,,;''''''''';;;;;;,,;;; + ';,,;;,,;;;;;;;;;;'''''''''''''' +TYPE: UNICODE_LARGE + + ⣀⣤⣴⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣶⣤⣄⡀ + ⢀⣀⣤⣴⣾⣿⣿⣿⠿⣿⣿⣿⣿⣦⣀ ⢀⣤⣶⣿⠿⠛⠁⠈⠉⠙⠻⢿⣷⣦⡀ + ⢀⣠⣴⣾⡿⠿⠛⠉⠉ ⠈⠙⢿⣿⣷⣤⡀ ⣠⣴⣾⡿⠟⠉ ⠉⠻⣿⣦ + ⢀⣤⣶⣿⠟⠋⠁ ⢿⣿⣿⣿⣿⣿⣿⣧⣤⣤⣤⣀⣀⣀⡀ ⠘⢿⣷⡀ + ⢀⣠⣾⡿⠟⠉ ⢸⣿⣿⣿⠟⢿⣿⣯⡙⠛⠛⠛⠿⠿⠿⢿⣿⣿⣶⣶⣶⣦⣤⣬⣿⣧ + ⣠⣴⣿⠟⠋ ⢸⣿⣿⡿ ⠈⠻⣿⣶⣄ ⠉⠉⠉⠙⠛⢻⣿⡆ + ⣠⣾⡿⠛⠁ ⣼⣿⣿⠃ ⠈⠙⢿⣷⣤⡀ ⠈⣿⡇ + ⣠⣾⡿⠋ ⢠⣿⣿⡏ ⠙⠻⣿⣦⣀ ⣿⡇ + ⣠⣾⡿⠋ ⢀⣿⣿⣿ ⠈⠛⢿⣷⣄⡀ ⢠⣿⡇ + ⢀⣾⡿⠋ ⢀⣾⣿⣿⠇ ⠙⠻⣿⣦⣀ ⢸⣿⡇ + ⢀⣴⣿⠟⠁ ⢀⣾⣿⣿⡟ ⠈⠻⢿⣷⣄ ⣾⣿⠇ + ⢠⣾⡿⠃ ⣠⣿⣿⣿⣿⠃ ⣀⣀⣀⣀⣀⣀⣀⣀⣤⣤⣤⣤⣽⣿⣿⣿⣿ + ⣰⣿⠟ ⣴⣿⣿⣿⣿⣿⣶⣶⣿⣿⣿⣿⣿⠿⠿⠿⠿⠿⠿⠿⠿⠛⠛⠛⠛⠛⠛⠛⠛⣿⣿⣿ + ⣼⣿⠏ ⢠⣾⣿⣿⣿⡿⣿⣿⢿⣷⣦⣄ ⣼⣿⣿⣿ + ⣼⣿⠃ ⢀⣴⣿⣿⣿⠟⠋ ⢸⣿⡆⠈⠛⠿⣿⣦⣄⡀ ⣰⣿⣿⣿⡇ + ⢀⣾⣿⠃ ⢀⣴⣿⣿⣿⠟⠁ ⣿⣷ ⠈⠙⠻⣿⣶⣄⡀ ⣰⣿⠟⣿⣿⡇ + ⢀⣾⣿⠇ ⢀⣴⣿⣿⣿⠟⠁ ⢸⣿⡆ ⠙⠻⢿⣷⣤⣀ ⣰⣿⠏⢠⣿⣿⡇ + ⢠⣿⣿⡟ ⢀⣴⣿⣿⡿⠛⠁ ⣿⣷ ⠉⠻⢿⣷⣦⣀ ⣴⣿⠏ ⢸⣿⣿⠃ + ⣿⣿⣿⡇ ⣠⣴⣿⣿⡿⠋ ⢸⣿⡆ ⠈⠛⢿⣿⣿⠃ ⢸⣿⣿ +⢠⣿⣿⣿ ⢀⣴⣾⣿⣿⡿⠋ ⠈⣿⣧ ⢠⣾⣿⣿ ⢸⣿⣿ +⢸⣿⣿⣿⡇ ⣀⣴⣾⣿⣿⣿⡿⠋ ⢹⣿⡆ ⣴⣿⠟⢹⣿⡀ ⢸⣿⡿ +⢸⣿⡟⣿⣿⣄ ⣀⣤⣶⣿⣿⣿⣿⣿⡟⠉ ⠈⣿⣷ ⢠⣾⡿⠋ ⢸⣿⡇ ⣼⣿⡇ +⢸⣿⡇⢹⣿⣿⣷⣦⣤⣤⣤⣤⣤⣴⣶⣾⣿⣿⣿⣿⡿⠿⣿⣿⣿⣿⣷⣶⣤⣤⣀⡀ ⢹⣿⡆ ⢀⣴⣿⠟ ⣿⣧ ⣿⣿⡇ +⢸⣿⠃ ⢿⣿⣿⣿⣿⣿⣿⡿⠿⠿⠛⠛⠉⠉⠁ ⢰⣿⠟⣿⣷⡀⠉⠙⠛⠿⢿⣿⣶⣦⣤⣀⡀ ⠈⣿⣷ ⣠⣿⡿⠁ ⢿⣿ ⣿⣿⡇ +⢸⣿ ⢀⣾⣿⣿⠋⠉⠁ ⢀⣿⡿ ⠘⣿⣷⡀ ⠉⠙⠛⠿⠿⣿⣶⣦⣤⣄⣀ ⢹⣿⡄ ⣠⣾⡿⠋ ⢸⣿⡆ ⣿⣿ +⣸⣿⢀⣾⣿⣿⣿⣆ ⣸⣿⠃ ⠘⢿⣷⡀ ⠈⠉⠛⠻⠿⣿⣷⣶⣤⣌⣿⣷⣾⡿⠋ ⠘⣿⡇ ⣿⣿ +⣿⣿⣾⡿⣿⡿⠹⣿⡆ ⢠⣿⡏ ⠈⢿⣷⡀ ⠈⠉⠙⣻⣿⣿⣿⣀ ⣿⣷⢰⣿⣿ +⣿⣿⡿⢁⣿⡇ ⢻⣿⡄ ⣾⣿ ⠈⢿⣷⡀ ⢀⣤⣾⡿⠋⠈⠻⢿⣷⣄ ⢻⣿⢸⣿⡟ +⣿⣿⠁⢸⣿⡇ ⢻⣿⡄ ⢸⣿⠇ ⠈⢿⣷⡀ ⣀⣴⣿⠟⠋ ⠙⢿⣷⣤⡀ ⢸⣿⣿⣿⡇ +⣿⣿ ⢸⣿⠁ ⠈⢿⣷⡀ ⢀⣿⡟ ⠈⢿⣷⡀ ⢀⣤⣾⡿⠛⠁ ⠙⠻⣿⣦⡀ ⠈⣿⣿⣿⡇ +⢸⣿⡄⣿⣿ ⠈⣿⣷⡀ ⣼⣿⠃ ⠈⢿⣷⡀ ⢀⣠⣶⣿⠟⠋ ⠈⠻⣿⣦⣄ ⣿⣿⣿⠇ +⠈⣿⣷⣿⡿ ⠘⣿⣧ ⢠⣿⡏ ⠈⢿⣷⣄⣤⣶⣿⠟⠋ ⠈⠛⢿⣷⣄ ⢸⣿⣿ + ⠘⣿⣿⡇ ⠘⣿⣧ ⣾⣿ ⢀⣠⣼⣿⣿⣿⣿⣿⣷⣶⣶⣶⣶⣶⣶⣤⣤⣤⣤⣤⣤⣀⣀⣀⣀⣀⣀⡀ ⠙⢿⣷⣼⣿⣿ + ⠈⠻⣿⣦⡀ ⠹⣿⣆⢸⣿⠇ ⣀⣠⣴⣾⡿⠟⠋⠁ ⠉⠉⠉⠉⠉⠉⠛⠛⣛⣛⣛⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣿⣿⣿⡿ + ⠈⠻⢿⣷⣦⣄⣀⡀ ⢹⣿⣿⡟ ⢀⣀⣀⣤⣤⣶⣾⣿⣿⣿⣯⣥⣤⣤⣤⣤⣶⣶⣶⣶⣶⣶⣶⣾⣿⣿⣿⣿⠿⠿⠿⠿⠿⠿⠿⠟⠛⠛⠛⠛⠛⠛⠛⠉⠉⠉⠉⠉⠉ + ⠉⠙⠛⠿⠿⠿⣿⣿⣿⣿⠿⠿⠿⠿⠿⠿⠿⠛⠛⠛⠛⠛⠛⠛⠋⠉⠉⠉⠉⠉⠉⠉ +TYPE: UNICODE + ⣀⣤⣴⣾⣿⣿⣿⡛⠛⠛⠛⠛⣻⣿⠿⠛⠛⠶⣤⡀ + ⣀⣴⠾⠛⠉⠁ ⠙⣿⣶⣤⣶⣟⣉ ⠈⠻⣦ + ⣀⣴⠟⠋ ⢸⣿⠟⠻⣯⡙⠛⠛⠛⠶⠶⠶⢶⣽⣇ + ⣠⡾⠋⠁ ⣾⡿ ⠈⠛⢦⣄ ⣿ + ⣠⡾⠋ ⣰⣿⠃ ⠙⠷⣤⡀ ⣿ + ⢀⡾⠋ ⣰⣿⡏ ⠈⠻⣦⣄⢠⣿ + ⣰⠟⠁ ⣴⣿⣿⣁⣀⣠⣤⣤⣤⣤⣤⣤⣤⣴⠶⠿⣿⡏ + ⣼⠏ ⢀⣾⣿⠟⣿⠿⣯⣍⠁ ⣰⣿⡇ + ⢀⣼⠋ ⢀⣴⣿⠟⠁ ⢸⡇ ⠙⠻⢦⣄⡀ ⢠⡿⣿⡇ +⢀⣾⡏ ⢀⣴⣿⠟⠁ ⣿ ⠉⠻⢶⣄⡀⣰⡟ ⣿⠃ +⣾⣿⠁ ⣠⣶⡿⠋⠁ ⢹⡇ ⠈⣿⡏ ⢸⣿ +⣿⣿⡆ ⢀⣠⣴⣿⡿⠋ ⠈⣿ ⢀⡾⠋⣿ ⢸⣿ +⣿⠸⣿⣶⣤⣤⣤⣤⣶⣾⠿⠿⣿⣿⠶⣤⣤⣀⡀ ⢹⡇ ⣴⠟⠁ ⣿⡀⢸⣿ +⣿⢀⣿⣟⠛⠋⠉⠁ ⢰⡟⠹⣧ ⠈⠉⠛⠻⠶⢦⣤⣀⡀ ⠈⣿ ⣠⡾⠃ ⢸⡇⢸⡇ +⣿⣾⣿⢿⡄ ⣿⠁ ⠘⣧ ⠉⠙⠛⠷⣿⣿⡋ ⠸⣇⣸⡇ +⣿⠃⣿⠈⢿⡄ ⣸⠇ ⠘⣧ ⢀⣤⠾⠋⠈⠻⣦⡀ ⣿⣿⡇ +⣿⢸⡏ ⠈⣷⡀ ⢠⡿ ⠘⣧⡀ ⣠⡴⠟⠁ ⠈⠻⣦⣀ ⢿⣿⠁ +⢻⣾⡇ ⠘⣷ ⣼⠃ ⠘⣷⣠⣴⠟⠋ ⠙⢷⣄⢸⣿ + ⠻⣧⡀ ⠘⣧⣰⡏ ⢀⣠⣤⠶⠛⠉⠛⠛⠛⠛⠛⠛⠻⢶⣶⣶⣶⣶⣶⣤⣤⣽⣿⣿ + ⠈⠛⠷⢦⣤⣽⣿⣥⣤⣶⣶⡿⠿⠿⠶⠶⠶⠶⠾⠛⠛⠛⠛⠛⠛⠛⠋⠉⠉⠉⠉⠉⠉⠁ diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/source_finder.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/source_finder.rb new file mode 100644 index 00000000..6e1e5806 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/source_finder.rb @@ -0,0 +1,138 @@ +# frozen_string_literal: true + +require_relative "ruby-lex" + +module IRB + class SourceFinder + class EvaluationError < StandardError; end + + class Source + attr_reader :file, :line + def initialize(file, line, ast_source = nil) + @file = file + @line = line + @ast_source = ast_source + end + + def file_exist? + File.exist?(@file) + end + + def binary_file? + # If the line is zero, it means that the target's source is probably in a binary file. + @line.zero? + end + + def file_content + @file_content ||= File.read(@file) + end + + def colorized_content + if !binary_file? && file_exist? + end_line = find_end + # To correctly colorize, we need to colorize full content and extract the relevant lines. + colored = IRB::Color.colorize_code(file_content) + colored.lines[@line - 1...end_line].join + elsif @ast_source + IRB::Color.colorize_code(@ast_source) + end + end + + private + + def find_end + lex = RubyLex.new + code = file_content + lines = code.lines[(@line - 1)..-1] + tokens = RubyLex.ripper_lex_without_warning(lines.join) + prev_tokens = [] + + # chunk with line number + tokens.chunk { |tok| tok.pos[0] }.each do |lnum, chunk| + code = lines[0..lnum].join + prev_tokens.concat chunk + continue = lex.should_continue?(prev_tokens) + syntax = lex.check_code_syntax(code, local_variables: []) + if !continue && syntax == :valid + return @line + lnum + end + end + @line + end + end + + private_constant :Source + + def initialize(irb_context) + @irb_context = irb_context + end + + def find_source(signature, super_level = 0) + case signature + when /\A(::)?[A-Z]\w*(::[A-Z]\w*)*\z/ # ConstName, ::ConstName, ConstPath::ConstName + eval_receiver_or_owner(signature) # trigger autoload + *parts, name = signature.split('::', -1) + base = + if parts.empty? # ConstName + find_const_owner(name) + elsif parts == [''] # ::ConstName + Object + else # ConstPath::ConstName + eval_receiver_or_owner(parts.join('::')) + end + file, line = base.const_source_location(name) + when /\A(?[A-Z]\w*(::[A-Z]\w*)*)#(?[^ :.]+)\z/ # Class#method + owner = eval_receiver_or_owner(Regexp.last_match[:owner]) + method = Regexp.last_match[:method] + return unless owner.respond_to?(:instance_method) + method = method_target(owner, super_level, method, "owner") + file, line = method&.source_location + when /\A((?.+)(\.|::))?(?[^ :.]+)\z/ # method, receiver.method, receiver::method + receiver = eval_receiver_or_owner(Regexp.last_match[:receiver] || 'self') + method = Regexp.last_match[:method] + return unless receiver.respond_to?(method, true) + method = method_target(receiver, super_level, method, "receiver") + file, line = method&.source_location + end + return unless file && line + + if File.exist?(file) + Source.new(file, line) + elsif method + # Method defined with eval, probably in IRB session + source = RubyVM::InstructionSequence.of(method)&.script_lines&.join rescue nil + Source.new(file, line, source) + end + rescue EvaluationError + nil + end + + private + + def method_target(owner_receiver, super_level, method, type) + case type + when "owner" + target_method = owner_receiver.instance_method(method) + when "receiver" + target_method = owner_receiver.method(method) + end + super_level.times do |s| + target_method = target_method.super_method if target_method + end + target_method + rescue NameError + nil + end + + def eval_receiver_or_owner(code) + @irb_context.workspace.binding.eval(code) + rescue Exception + raise EvaluationError + end + + def find_const_owner(name) + module_nesting = @irb_context.workspace.binding.eval('::Module.nesting') + module_nesting.find { |mod| mod.const_defined?(name, false) } || module_nesting.find { |mod| mod.const_defined?(name) } || Object + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/statement.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/statement.rb new file mode 100644 index 00000000..6a959995 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/statement.rb @@ -0,0 +1,101 @@ +# frozen_string_literal: true + +module IRB + class Statement + attr_reader :code + + def is_assignment? + raise NotImplementedError + end + + def suppresses_echo? + raise NotImplementedError + end + + def should_be_handled_by_debugger? + raise NotImplementedError + end + + class EmptyInput < Statement + def is_assignment? + false + end + + def suppresses_echo? + true + end + + # Debugger takes empty input to repeat the last command + def should_be_handled_by_debugger? + true + end + + def code + "" + end + end + + class Expression < Statement + def initialize(code, is_assignment) + @code = code + @is_assignment = is_assignment + end + + def suppresses_echo? + @code.match?(/;\s*\z/) + end + + def should_be_handled_by_debugger? + true + end + + def is_assignment? + @is_assignment + end + end + + class IncorrectAlias < Statement + attr_reader :message + + def initialize(message) + @code = "" + @message = message + end + + def should_be_handled_by_debugger? + false + end + + def is_assignment? + false + end + + def suppresses_echo? + true + end + end + + class Command < Statement + attr_reader :command_class, :arg + + def initialize(original_code, command_class, arg) + @code = original_code + @command_class = command_class + @arg = arg + end + + def is_assignment? + false + end + + def suppresses_echo? + true + end + + def should_be_handled_by_debugger? + require_relative 'command/debug' + IRB::Command::DebugCommand > @command_class + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/version.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/version.rb new file mode 100644 index 00000000..95037011 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/version.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true +# +# irb/version.rb - irb version definition file +# by Keiju ISHITSUKA(keiju@ishitsuka.com) +# + +module IRB # :nodoc: + VERSION = "1.15.2" + @RELEASE_VERSION = VERSION + @LAST_UPDATE_DATE = "2025-04-03" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/workspace.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/workspace.rb new file mode 100644 index 00000000..ced9d786 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/workspace.rb @@ -0,0 +1,171 @@ +# frozen_string_literal: true +# +# irb/workspace-binding.rb - +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# + +require_relative "helper_method" + +IRB::TOPLEVEL_BINDING = binding +module IRB # :nodoc: + class WorkSpace + # Creates a new workspace. + # + # set self to main if specified, otherwise + # inherit main from TOPLEVEL_BINDING. + def initialize(*main) + if Binding === main[0] + @binding = main.shift + elsif IRB.conf[:SINGLE_IRB] + @binding = TOPLEVEL_BINDING + else + case IRB.conf[:CONTEXT_MODE] + when 0 # binding in proc on TOPLEVEL_BINDING + @binding = eval("proc{binding}.call", + TOPLEVEL_BINDING, + __FILE__, + __LINE__) + when 1 # binding in loaded file + require "tempfile" + f = Tempfile.open("irb-binding") + f.print <IRB.conf[:__MAIN__] + attr_reader :main + + def load_helper_methods_to_main + # Do not load helper methods to frozen objects and BasicObject + return unless Object === @main && !@main.frozen? + + ancestors = class<' : '', current_pos + 1, lines[current_pos]) + end.join("") + + "\nFrom: #{file} @ line #{pos + 1} :\n\n#{body}#{Color.clear}\n" + end + end + + module HelpersContainer + class << self + def install_helper_methods + HelperMethod.helper_methods.each do |name, helper_method_class| + define_method name do |*args, **opts, &block| + helper_method_class.instance.execute(*args, **opts, &block) + end unless method_defined?(name) + end + end + end + + install_helper_methods + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ws-for-case-2.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ws-for-case-2.rb new file mode 100644 index 00000000..03f42d73 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/ws-for-case-2.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true +# +# irb/ws-for-case-2.rb - +# by Keiju ISHITSUKA(keiju@ruby-lang.org) +# + +while true + IRB::BINDING_QUEUE.push _ = binding +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/xmp.rb b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/xmp.rb new file mode 100644 index 00000000..b1bc5328 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/lib/irb/xmp.rb @@ -0,0 +1,164 @@ +# frozen_string_literal: true +# +# xmp.rb - irb version of gotoken xmp +# by Keiju ISHITSUKA(Nippon Rational Inc.) +# + +require_relative "../irb" +require_relative "frame" + +# An example printer for irb. +# +# It's much like the standard library PrettyPrint, that shows the value of each +# expression as it runs. +# +# In order to use this library, you must first require it: +# +# require 'irb/xmp' +# +# Now, you can take advantage of the Object#xmp convenience method. +# +# xmp < foo = "bar" +# #==>"bar" +# #=> baz = 42 +# #==>42 +# +# You can also create an XMP object, with an optional binding to print +# expressions in the given binding: +# +# ctx = binding +# x = XMP.new ctx +# x.puts +# #=> today = "a good day" +# #==>"a good day" +# ctx.eval 'today # is what?' +# #=> "a good day" +class XMP + + # Creates a new XMP object. + # + # The top-level binding or, optional +bind+ parameter will be used when + # creating the workspace. See WorkSpace.new for more information. + # + # This uses the +:XMP+ prompt mode. + # See {Custom Prompts}[rdoc-ref:IRB@Custom+Prompts] for more information. + def initialize(bind = nil) + IRB.init_config(nil) + + IRB.conf[:PROMPT_MODE] = :XMP + + bind = IRB::Frame.top(1) unless bind + ws = IRB::WorkSpace.new(bind) + @io = StringInputMethod.new + @irb = IRB::Irb.new(ws, @io) + @irb.context.ignore_sigint = false + + IRB.conf[:MAIN_CONTEXT] = @irb.context + end + + # Evaluates the given +exps+, for example: + # + # require 'irb/xmp' + # x = XMP.new + # + # x.puts '{:a => 1, :b => 2, :c => 3}' + # #=> {:a => 1, :b => 2, :c => 3} + # # ==>{:a=>1, :b=>2, :c=>3} + # x.puts 'foo = "bar"' + # # => foo = "bar" + # # ==>"bar" + def puts(exps) + @io.puts exps + + if @irb.context.ignore_sigint + begin + trap_proc_b = trap("SIGINT"){@irb.signal_handle} + catch(:IRB_EXIT) do + @irb.eval_input + end + ensure + trap("SIGINT", trap_proc_b) + end + else + catch(:IRB_EXIT) do + @irb.eval_input + end + end + end + + # A custom InputMethod class used by XMP for evaluating string io. + class StringInputMethod < IRB::InputMethod + # Creates a new StringInputMethod object + def initialize + super + @exps = [] + end + + # Whether there are any expressions left in this printer. + def eof? + @exps.empty? + end + + # Reads the next expression from this printer. + # + # See IO#gets for more information. + def gets + while l = @exps.shift + next if /^\s+$/ =~ l + l.concat "\n" + print @prompt, l + break + end + l + end + + # Concatenates all expressions in this printer, separated by newlines. + # + # An Encoding::CompatibilityError is raised of the given +exps+'s encoding + # doesn't match the previous expression evaluated. + def puts(exps) + if @encoding and exps.encoding != @encoding + enc = Encoding.compatible?(@exps.join("\n"), exps) + if enc.nil? + raise Encoding::CompatibilityError, "Encoding in which the passed expression is encoded is not compatible to the preceding's one" + else + @encoding = enc + end + else + @encoding = exps.encoding + end + @exps.concat exps.split(/\n/) + end + + # Returns the encoding of last expression printed by #puts. + attr_reader :encoding + end +end + +# A convenience method that's only available when the you require the IRB::XMP standard library. +# +# Creates a new XMP object, using the given expressions as the +exps+ +# parameter, and optional binding as +bind+ or uses the top-level binding. Then +# evaluates the given expressions using the +:XMP+ prompt mode. +# +# For example: +# +# require 'irb/xmp' +# ctx = binding +# xmp 'foo = "bar"', ctx +# #=> foo = "bar" +# #==>"bar" +# ctx.eval 'foo' +# #=> "bar" +# +# See XMP.new for more information. +def xmp(exps, bind = nil) + bind = IRB::Frame.top(1) unless bind + xmp = XMP.new(bind) + xmp.puts exps + xmp +end diff --git a/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/man/irb.1 b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/man/irb.1 new file mode 100644 index 00000000..48586a3b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/irb-1.15.2/man/irb.1 @@ -0,0 +1,292 @@ +.\"Ruby is copyrighted by Yukihiro Matsumoto . +.Dd August 11, 2019 +.Dt IRB \&1 "Ruby Programmer's Reference Guide" +.Os UNIX +.Sh NAME +.Nm irb +.Nd Interactive Ruby Shell +.Sh SYNOPSIS +.Nm +.Op Fl -version +.Op Fl dfUw +.Op Fl I Ar directory +.Op Fl r Ar library +.Op Fl E Ar external Ns Op : Ns Ar internal +.Op Fl W Ns Op Ar level +.Op Fl - Ns Oo no Oc Ns inspect +.Op Fl - Ns Oo no Oc Ns multiline +.Op Fl - Ns Oo no Oc Ns singleline +.Op Fl - Ns Oo no Oc Ns echo +.Op Fl - Ns Oo no Oc Ns colorize +.Op Fl - Ns Oo no Oc Ns autocomplete +.Op Fl - Ns Oo no Oc Ns verbose +.Op Fl -prompt Ar mode +.Op Fl -prompt-mode Ar mode +.Op Fl -inf-ruby-mode +.Op Fl -simple-prompt +.Op Fl -noprompt +.Op Fl -tracer +.Op Fl -back-trace-limit Ar n +.Op Fl - +.Op program_file +.Op argument ... +.Pp +.Sh DESCRIPTION +.Nm +is the REPL(read-eval-print loop) environment for Ruby programs. +.Pp +.Sh OPTIONS +.Bl -tag -width "1234567890123" -compact +.Pp +.It Fl -version +Prints the version of +.Nm . +.Pp +.It Fl E Ar external Ns Op : Ns Ar internal +.It Fl -encoding Ar external Ns Op : Ns Ar internal +Same as `ruby -E' . +Specifies the default value(s) for external encodings and internal encoding. Values should be separated with colon (:). +.Pp +You can omit the one for internal encodings, then the value +.Pf ( Li "Encoding.default_internal" ) will be nil. +.Pp +.It Fl I Ar path +Same as `ruby -I' . +Specifies +.Li $LOAD_PATH +directory +.Pp +.It Fl U +Same as `ruby -U' . +Sets the default value for internal encodings +.Pf ( Li "Encoding.default_internal" ) to UTF-8. +.Pp +.It Fl d +Same as `ruby -d' . +Sets +.Li $DEBUG +to true. +.Pp +.It Fl f +Suppresses read of +.Pa ~/.irbrc . +.Pp +.It Fl w +Same as `ruby -w' . +.Pp +.Pp +.It Fl W +Same as `ruby -W' . +.Pp +.It Fl h +.It Fl -help +Prints a summary of the options. +.Pp +.It Fl r Ar library +Same as `ruby -r'. +Causes irb to load the library using require. +.Pp +.It Fl -inspect +Uses `inspect' for output (default except for bc mode) +.Pp +.It Fl -noinspect +Doesn't use inspect for output +.Pp +.It Fl -multiline +Uses multiline editor module. +.Pp +.It Fl -nomultiline +Doesn't use multiline editor module. +.Pp +.It Fl -singleline +Uses singleline editor module. +.Pp +.It Fl -nosingleline +Doesn't use singleline editor module. +.Pp +.Pp +.It Fl -extra-doc-dir +Add an extra doc dir for the doc dialog. +.Pp +.Pp +.It Fl -echo +Show result (default). +.Pp +.It Fl -noecho +Don't show result. +.Pp +.Pp +.It Fl -echo-on-assignment +Show result on assignment. +.Pp +.It Fl -noecho-on-assignment +Don't show result on assignment. +.Pp +.It Fl -truncate-echo-on-assignment +Show truncated result on assignment (default). +.Pp +.Pp +.It Fl -colorize +Use colorization. +.Pp +.It Fl -nocolorize +Don't use colorization. +.Pp +.Pp +.It Fl -autocomplete +Use autocompletion. +.Pp +.It Fl -noautocomplete +Don't use autocompletion. +.Pp +.Pp +.It Fl -regexp-completor +Use regexp based completion. +.Pp +.It Fl -type-completor +Use type based completion. +.Pp +.Pp +.It Fl -verbose +Show details. +.Pp +.It Fl -noverbose +Don't show details. +.Pp +.It Fl -prompt Ar mode +.It Fl -prompt-mode Ar mode +Switch prompt mode. Pre-defined prompt modes are +`default', `simple', `xmp' and `inf-ruby'. +.Pp +.It Fl -inf-ruby-mode +Uses prompt appropriate for inf-ruby-mode on emacs. +Suppresses --multiline and --singleline. +.Pp +.It Fl -simple-prompt +Makes prompts simple. +.Pp +.It Fl -noprompt +No prompt mode. +.Pp +.It Fl -tracer +Displays trace for each execution of commands. +.Pp +.It Fl -back-trace-limit Ar n +Displays backtrace top +.Ar n +and tail +.Ar n Ns . +The default value is 16. +.El +.Pp +.Sh ENVIRONMENT +.Bl -tag -compact -width "IRB_USE_AUTOCOMPLETE" +.It Ev IRB_LANG +The locale used for +.Nm . +.Pp +.It Ev IRBRC +The path to the personal initialization file. +.Pp +.It Ev XDG_CONFIG_HOME +.Nm +respects XDG_CONFIG_HOME. If it is set and +.Ev IRBRC +is unset, load +.Pa $XDG_CONFIG_HOME/irb/irbrc +as a personal initialization file. +.Pp +.It Ev RI_PAGER +The command specified would be used as a pager. +.Pp +.It Ev PAGER +The command specified would be used as a pager if +.Ev RI_PAGER +is unset. +.Pp +.It Ev VISUAL +Its value would be used to open files by the edit command. +.Pp +.It Ev EDITOR +Its value would be used to open files by the edit command if +.Ev VISUAL +is unset. +.Pp +.It Ev NO_COLOR +Assigning a value to it disables colorization. +.Pp +.It Ev IRB_USE_AUTOCOMPLETE +Assigning +.Sy false +to it disables autocompletion. +.Pp +.It Ev IRB_COMPLETOR +Autocompletion behavior. Allowed values are +.Sy regexp +or +.Sy type +. +.Pp +.It Ev IRB_COPY_COMMAND +Overrides the default program used to interface with the system clipboard. +.El +.Pp +Also +.Nm +depends on same variables as +.Xr ruby 1 . +.Pp +.Sh FILES +.Bl -tag -compact +.It Pa ~/.irbrc +Personal irb initialization. If +.Ev IRBRC +is set, read +.Pa $IRBRC +instead. If +.Ev IRBRC +is not set and +.Ev XDG_CONFIG_HOME +is set, +.Pa $XDG_CONFIG_HOME/irb/irbrc +is loaded. +.Pp +.El +.Pp +.Sh EXAMPLES +.Dl % irb +.Dl irb(main):001:0> Ic 1 + 1 +.Dl 2 +.Dl irb(main):002:0> Ic def t(x) +.Dl irb(main):003:1> Ic x + 1 +.Dl irb(main):004:1> Ic end +.Dl => :t +.Dl irb(main):005:0> Ic t(3) +.Dl => 4 +.Dl irb(main):006:0> Ic if t(3) == 4 +.Dl irb(main):007:1> Ic p :ok +.Dl irb(main):008:1> Ic end +.Dl :ok +.Dl => :ok +.Dl irb(main):009:0> Ic quit +.Dl % +.Pp +.Sh SEE ALSO +.Xr ruby 1 . +.Pp +.Sh REPORTING BUGS +.Bl -bullet +.It +Security vulnerabilities should be reported via an email to +.Mt security@ruby-lang.org . +Reported problems will be published after being fixed. +.Pp +.It +Other bugs and feature requests can be reported via the +Ruby Issue Tracking System +.Pq Lk https://bugs.ruby-lang.org/ . +Do not report security vulnerabilities +via this system because it publishes the vulnerabilities immediately. +.El +.Sh AUTHORS +Written by Keiju ISHITSUKA. diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/BSDL b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/BSDL new file mode 100644 index 00000000..66d93598 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/BSDL @@ -0,0 +1,22 @@ +Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/CHANGES.md b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/CHANGES.md new file mode 100644 index 00000000..b02ee197 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/CHANGES.md @@ -0,0 +1,646 @@ +# Changes + +### Unreleased + +### 2025-05-23 (2.12.2) + +* Fix compiler optimization level. + +### 2025-05-23 (2.12.1) + +* Fix a potential crash in large negative floating point number generation. +* Fix for JSON.pretty_generate to use passed state object's generate instead of state class as the required parameters aren't available. + +### 2025-05-12 (2.12.0) + +* Improve floating point generation to not use scientific notation as much. +* Include line and column in parser errors. Both in the message and as exception attributes. +* Handle non-string hash keys with broken `to_s` implementations. +* `JSON.generate` now uses SSE2 (x86) or NEON (arm64) instructions when available to escape strings. + +### 2025-04-25 (2.11.3) + +* Fix a regression in `JSON.pretty_generate` that could cause indentation to be off once some `#to_json` has been called. + +### 2025-04-24 (2.11.2) + +* Add back `JSON::PRETTY_STATE_PROTOTYPE`. This constant was private API but is used by popular gems like `multi_json`. + It now emits a deprecation warning. + +### 2025-04-24 (2.11.1) + +* Add back `JSON.restore`, `JSON.unparse`, `JSON.fast_unparse` and `JSON.pretty_unparse`. + These were deprecated 16 years ago, but never emited warnings, only undocumented, so are + still used by a few gems. + +### 2025-04-24 (2.11.0) + +* Optimize Integer generation to be ~1.8x faster. +* Optimize Float generation to be ~10x faster. +* Fix `JSON.load` proc argument to substitute the parsed object with the return value. + This better match `Marshal.load` behavior. +* Deprecate `JSON.fast_generate` (it's not any faster, so pointless). +* Deprecate `JSON.load_default_options`. +* Deprecate `JSON.unsafe_load_default_options`. +* Deprecate `JSON.dump_default_options`. +* Deprecate `Kernel#j` +* Deprecate `Kernel#jj` +* Remove outdated `JSON.iconv`. +* Remove `Class#json_creatable?` monkey patch. +* Remove deprecated `JSON.restore` method. +* Remove deprecated `JSON.unparse` method. +* Remove deprecated `JSON.fast_unparse` method. +* Remove deprecated `JSON.pretty_unparse` method. +* Remove deprecated `JSON::UnparserError` constant. +* Remove outdated `JSON::MissingUnicodeSupport` constant. + +### 2025-03-12 (2.10.2) + +* Fix a potential crash in the C extension parser. +* Raise a ParserError on all incomplete unicode escape sequence. This was the behavior until `2.10.0` unadvertently changed it. +* Ensure document snippets that are included in parser errors don't include truncated multibyte characters. +* Ensure parser error snippets are valid UTF-8. +* Fix `JSON::GeneratorError#detailed_message` on Ruby < 3.2 + +### 2025-02-10 (2.10.1) + +* Fix a compatibility issue with `MultiJson.dump(obj, pretty: true)`: `no implicit conversion of false into Proc (TypeError)`. + +### 2025-02-10 (2.10.0) + +* `strict: true` now accept symbols as values. Previously they'd only be accepted as hash keys. +* The C extension Parser has been entirely reimplemented from scratch. +* Introduced `JSON::Coder` as a new API allowing to customize how non native types are serialized in a non-global way. +* Introduced `JSON::Fragment` to allow assembling cached fragments in a safe way. +* The Java implementation of the generator received many optimizations. + +### 2024-12-18 (2.9.1) + +* Fix support for Solaris 10. + +### 2024-12-03 (2.9.0) + +* Fix C implementation of `script_safe` escaping to not confuse some other 3 wide characters with `\u2028` and `\u2029`. + e.g. `JSON.generate(["倩", "瀨"], script_safe: true)` would generate the wrong JSON. +* `JSON.dump(object, some_io)` now write into the IO in chunks while previously it would buffer the entire JSON before writing. +* `JSON::GeneratorError` now has a `#invalid_object` attribute, making it easier to understand why an object tree cannot be serialized. +* Numerous improvements to the JRuby extension. + +### 2024-11-14 (2.8.2) + +* `JSON.load_file` explictly read the file as UTF-8. + +### 2024-11-06 (2.8.1) + +* Fix the java packages to include the extension. + +### 2024-11-06 (2.8.0) + +* Emit a deprecation warning when `JSON.load` create custom types without the `create_additions` option being explictly enabled. + * Prefer to use `JSON.unsafe_load(string)` or `JSON.load(string, create_additions: true)`. +* Emit a deprecation warning when serializing valid UTF-8 strings encoded in `ASCII_8BIT` aka `BINARY`. +* Bump required Ruby version to 2.7. +* Add support for optionally parsing trailing commas, via `allow_trailing_comma: true`, which in cunjunction with the + pre-existing support for comments, make it suitable to parse `jsonc` documents. +* Many performance improvements to `JSON.parse` and `JSON.load`, up to `1.7x` faster on real world documents. +* Some minor performance improvements to `JSON.dump` and `JSON.generate`. +* `JSON.pretty_generate` no longer include newline inside empty object and arrays. + +### 2024-11-04 (2.7.6) + +* Fix a regression in JSON.generate when dealing with Hash keys that are string subclasses, call `to_json` on them. + +### 2024-10-25 (2.7.5) + +* Fix a memory leak when `#to_json` methods raise an exception. +* Gracefully handle formatting configs being set to `nil` instead of `""`. +* Workaround another issue caused by conflicting versions of both `json_pure` and `json` being loaded. + +### 2024-10-25 (2.7.4) + +* Workaround a bug in 3.4.8 and older https://github.com/rubygems/rubygems/pull/6490. + This bug would cause some gems with native extension to fail during compilation. +* Workaround different versions of `json` and `json_pure` being loaded (not officially supported). +* Make `json_pure` Ractor compatible. + +### 2024-10-24 (2.7.3) + +* Numerous performance optimizations in `JSON.generate` and `JSON.dump` (up to 2 times faster). +* Limit the size of ParserError exception messages, only include up to 32 bytes of the unparseable source. +* Fix json-pure's `Object#to_json` to accept non state arguments +* Fix multiline comment support in `json-pure`. +* Fix `JSON.parse` to no longer mutate the argument encoding when passed an ASCII-8BIT string. +* Fix `String#to_json` to raise on invalid encoding in `json-pure`. +* Delete code that was based on CVTUTF. +* Use the pure-Ruby generator on TruffleRuby. +* Fix `strict` mode in `json-pure` to not break on Integer. + +### 2024-04-04 (2.7.2) + +* Use rb_sym2str instead of SYM2ID #561 +* Fix memory leak when exception is raised during JSON generation #574 +* Remove references to "19" methods in JRuby #576 +* Make OpenStruct support as optional by @hsbt in #565 +* Autoload JSON::GenericObject to avoid require ostruct warning in Ruby 3.4 #577 +* Warn to install ostruct if json couldn't load it by @hsbt #578 + +### 2023-12-05 (2.7.1) + +* JSON.dump: handle unenclosed hashes regression #554 +* Overload kwargs in JSON.dump #556 +* [DOC] RDoc for additions #557 +* Fix JSON.dump overload combination #558 + +### 2023-12-01 (2.7.0) + +* Add a strict option to Generator #519 +* `escape_slash` option was renamed as `script_safe` and now also escape U+2028 and U+2029. `escape_slash` is now an alias of `script_safe` #525 +* Remove unnecessary initialization of create_id in JSON.parse() #454 +* Improvements to Hash#to_json in pure implementation generator #203 +* Use ruby_xfree to free buffers #518 +* Fix "unexpected token" offset for Infinity #507 +* Avoid using deprecated BigDecimal.new on JRuby #546 +* Removed code for Ruby 1.8 #540 +* Rename JSON::ParseError to JSON:ParserError #530 +* Call super in included hook #486 +* JRuby requires a minimum of Java 8 #516 +* Always indent even if empty #517 + +### 2022-11-30 (2.6.3) + +* bugfix json/pure mixing escaped with literal unicode raises Encoding::CompatibilityError #483 +* Stop including the parser source __LINE__ in exceptions #470 + +### 2022-11-17 (2.6.2) + +* Remove unknown keyword arg from DateTime.parse #488 +* Ignore java artifacts by @hsbt #489 +* Fix parser bug for empty string allocation #496 + +### 2021-10-24 (2.6.1) + +* Restore version.rb with 2.6.1 + +### 2021-10-14 (2.6.0) + +* Use `rb_enc_interned_str` if available to reduce allocations in `freeze: true` mode. #451. +* Bump required_ruby_version to 2.3. +* Fix compatibility with `GC.compact`. +* Fix some compilation warnings. #469 + +## 2020-12-22 (2.5.1) + +* Restore the compatibility for constants of JSON class. + +## 2020-12-22 (2.5.0) + +* Ready to Ractor-safe at Ruby 3.0. + +## 2020-12-17 (2.4.1) + +* Restore version.rb with 2.4.1 + +## 2020-12-15 (2.4.0) + +* Implement a freeze: parser option #447 +* Fix an issue with generate_pretty and empty objects in the Ruby and Java implementations #449 +* Fix JSON.load_file doc #448 +* Fix pure parser with unclosed arrays / objects #425 +* bundle the LICENSE file in the gem #444 +* Add an option to escape forward slash character #405 +* RDoc for JSON #439 #446 #442 #434 #433 #430 + +## 2020-06-30 (2.3.1) + +* Spelling and grammar fixes for comments. Pull request #191 by Josh + Kline. +* Enhance generic JSON and #generate docs. Pull request #347 by Victor + Shepelev. +* Add :nodoc: for GeneratorMethods. Pull request #349 by Victor Shepelev. +* Baseline changes to help (JRuby) development. Pull request #371 by Karol + Bucek. +* Add metadata for rubygems.org. Pull request #379 by Alexandre ZANNI. +* Remove invalid JSON.generate description from JSON module rdoc. Pull + request #384 by Jeremy Evans. +* Test with TruffleRuby in CI. Pull request #402 by Benoit Daloze. +* Rdoc enhancements. Pull request #413 by Burdette Lamar. +* Fixtures/ are not being tested... Pull request #416 by Marc-André + Lafortune. +* Use frozen string for hash key. Pull request #420 by Marc-André + Lafortune. +* Added :call-seq: to RDoc for some methods. Pull request #422 by Burdette + Lamar. +* Small typo fix. Pull request #423 by Marc-André Lafortune. + +## 2019-12-11 (2.3.0) + * Fix default of `create_additions` to always be `false` for `JSON(user_input)` + and `JSON.parse(user_input, nil)`. + Note that `JSON.load` remains with default `true` and is meant for internal + serialization of trusted data. [CVE-2020-10663] + * Fix passing args all #to_json in json/add/*. + * Fix encoding issues + * Fix issues of keyword vs positional parameter + * Fix JSON::Parser against bigdecimal updates + * Bug fixes to JRuby port + +## 2019-02-21 (2.2.0) + * Adds support for 2.6 BigDecimal and ruby standard library Set datetype. + +## 2017-04-18 (2.1.0) + * Allow passing of `decimal_class` option to specify a class as which to parse + JSON float numbers. +## 2017-03-23 (2.0.4) + * Raise exception for incomplete unicode surrogates/character escape + sequences. This problem was reported by Daniel Gollahon (dgollahon). + * Fix arbitrary heap exposure problem. This problem was reported by Ahmad + Sherif (ahmadsherif). + +## 2017-01-12 (2.0.3) + * Set `required_ruby_version` to 1.9 + * Some small fixes + +## 2016-07-26 (2.0.2) + * Specify `required_ruby_version` for json\_pure. + * Fix issue #295 failure when parsing frozen strings. + +## 2016-07-01 (2.0.1) + * Fix problem when requiring json\_pure and Parser constant was defined top + level. + * Add `RB_GC_GUARD` to avoid possible GC problem via Pete Johns. + * Store `current_nesting` on stack by Aaron Patterson. + +## 2015-09-11 (2.0.0) + * Now complies to newest JSON RFC 7159. + * Implements compatibility to ruby 2.4 integer unification. + * Drops support for old rubies whose life has ended, that is rubies < 2.0. + Also see https://www.ruby-lang.org/en/news/2014/07/01/eol-for-1-8-7-and-1-9-2/ + * There were still some mentions of dual GPL licensing in the source, but JSON + has just the Ruby license that itself includes an explicit dual-licensing + clause that allows covered software to be distributed under the terms of + the Simplified BSD License instead for all ruby versions >= 1.9.3. This is + however a GPL compatible license according to the Free Software Foundation. + I changed these mentions to be consistent with the Ruby license setting in + the gemspec files which were already correct now. + +## 2017-01-13 (1.8.6) + * Be compatible with ancient ruby 1.8 (maybe?) + +## 2015-09-11 (1.8.5) + * Be compatible with ruby 2.4.0 + * There were still some mentions of dual GPL licensing in the source, but JSON + has just the Ruby license that itself includes an explicit dual-licensing + clause that allows covered software to be distributed under the terms of + the Simplified BSD License instead for all ruby versions >= 1.9.3. This is + however a GPL compatible license according to the Free Software Foundation. + I changed these mentions to be consistent with the Ruby license setting in + the gemspec files which were already correct now. + +## 2015-06-01 (1.8.3) + * Fix potential memory leak, thx to nobu. + +## 2015-01-08 (1.8.2) + * Some performance improvements by Vipul A M . + * Fix by Jason R. Clark to avoid mutation of + `JSON.dump_default_options`. + * More tests by Michael Mac-Vicar and fixing + `space_before` accessor in generator. + * Performance on Jruby improved by Ben Browning . + * Some fixes to be compatible with the new Ruby 2.2 by Zachary Scott + and SHIBATA Hiroshi . + +## 2013-05-13 (1.8.1) + * Remove Rubinius exception since transcoding should be working now. + +## 2013-05-13 (1.8.0) + * Fix https://github.com/ruby/json/issues/162 reported by Marc-Andre + Lafortune . Thanks! + * Applied patches by Yui NARUSE to suppress warning with + -Wchar-subscripts and better validate UTF-8 strings. + * Applied patch by ginriki@github to remove unnecessary if. + * Add load/dump interface to `JSON::GenericObject` to make + serialize :some_attribute, `JSON::GenericObject` + work in Rails active models for convenient `SomeModel#some_attribute.foo.bar` + access to serialised JSON data. + +## 2013-02-04 (1.7.7) + * Security fix for JSON create_additions default value and + `JSON::GenericObject`. It should not be possible to create additions unless + explicitly requested by setting the create_additions argument to true or + using the JSON.load/dump interface. If `JSON::GenericObject` is supposed to + be automatically deserialised, this has to be explicitly enabled by + setting + JSON::GenericObject.json_creatable = true + as well. + * Remove useless assert in fbuffer implementation. + * Apply patch attached to https://github.com/ruby/json/issues#issue/155 + provided by John Shahid , Thx! + * Add license information to rubygems spec data, reported by Jordi Massaguer Pla . + * Improve documentation, thx to Zachary Scott . + +## 2012-11-29 (1.7.6) + * Add `GeneratorState#merge` alias for JRuby, fix state accessor methods. Thx to + jvshahid@github. + * Increase hash likeness of state objects. + +## 2012-08-17 (1.7.5) + * Fix compilation of extension on older rubies. + +## 2012-07-26 (1.7.4) + * Fix compilation problem on AIX, see https://github.com/ruby/json/issues/142 + +## 2012-05-12 (1.7.3) + * Work around Rubinius encoding issues using iconv for conversion instead. + +## 2012-05-11 (1.7.2) + * Fix some encoding issues, that cause problems for the pure and the + extension variant in jruby 1.9 mode. + +## 2012-04-28 (1.7.1) + * Some small fixes for building + +## 2012-04-28 (1.7.0) + * Add `JSON::GenericObject` for method access to objects transmitted via JSON. + +## 2012-04-27 (1.6.7) + * Fix possible crash when trying to parse nil value. + +## 2012-02-11 (1.6.6) + * Propagate src encoding to values made from it (fixes 1.9 mode converting + everything to ascii-8bit; harmless for 1.8 mode too) (Thomas E. Enebo + ), should fix + https://github.com/ruby/json/issues#issue/119. + * Fix https://github.com/ruby/json/issues#issue/124 Thx to Jason Hutchens. + * Fix https://github.com/ruby/json/issues#issue/117 + +## 2012-01-15 (1.6.5) + * Vit Ondruch reported a bug that shows up when using + optimisation under GCC 4.7. Thx to him, Bohuslav Kabrda + and Yui NARUSE for debugging and + developing a patch fix. + +## 2011-12-24 (1.6.4) + * Patches that improve speed on JRuby contributed by Charles Oliver Nutter + . + * Support `object_class`/`array_class` with duck typed hash/array. + +## 2011-12-01 (1.6.3) + * Let `JSON.load('')` return nil as well to make mysql text columns (default to + `''`) work better for serialization. + +## 2011-11-21 (1.6.2) + * Add support for OpenStruct and BigDecimal. + * Fix bug when parsing nil in `quirks_mode`. + * Make JSON.dump and JSON.load methods better cooperate with Rails' serialize + method. Just use: + serialize :value, JSON + * Fix bug with time serialization concerning nanoseconds. Thanks for the + patch go to Josh Partlow (jpartlow@github). + * Improve parsing speed for JSON numbers (integers and floats) in a similar way to + what Evan Phoenix suggested in: + https://github.com/ruby/json/pull/103 + +## 2011-09-18 (1.6.1) + * Using -target 1.5 to force Java bits to compile with 1.5. + +## 2011-09-12 (1.6.0) + * Extract utilities (prettifier and GUI-editor) in its own gem json-utils. + * Split json/add/core into different files for classes to be serialised. + +## 2011-08-31 (1.5.4) + * Fix memory leak when used from multiple JRuby. (Patch by + jfirebaugh@github). + * Apply patch by Eric Wong that fixes garbage collection problem + reported in https://github.com/ruby/json/issues/46. + * Add :quirks_mode option to parser and generator. + * Add support for Rational and Complex number additions via json/add/complex + and json/add/rational requires. + +## 2011-06-20 (1.5.3) + * Alias State#configure method as State#merge to increase duck type synonymy with Hash. + * Add `as_json` methods in json/add/core, so rails can create its json objects the new way. + +## 2011-05-11 (1.5.2) + * Apply documentation patch by Cory Monty . + * Add gemspecs for json and json\_pure. + * Fix bug in jruby pretty printing. + * Fix bug in `object_class` and `array_class` when inheriting from Hash or + Array. + +## 2011-01-24 (1.5.1) + * Made rake-compiler build a fat binary gem. This should fix issue + https://github.com/ruby/json/issues#issue/54. + +## 2011-01-22 (1.5.0) + * Included Java source codes for the Jruby extension made by Daniel Luz + . + * Output full exception message of `deep_const_get` to aid debugging. + * Fixed an issue with ruby 1.9 `Module#const_defined?` method, that was + reported by Riley Goodside. + +## 2010-08-09 (1.4.6) + * Fixed oversight reported in http://github.com/ruby/json/issues/closed#issue/23, + always create a new object from the state prototype. + * Made pure and ext api more similar again. + +## 2010-08-07 (1.4.5) + * Manage data structure nesting depth in state object during generation. This + should reduce problems with `to_json` method definіtions that only have one + argument. + * Some fixes in the state objects and additional tests. +## 2010-08-06 (1.4.4) + * Fixes build problem for rubinius under OS X, http://github.com/ruby/json/issues/closed#issue/25 + * Fixes crashes described in http://github.com/ruby/json/issues/closed#issue/21 and + http://github.com/ruby/json/issues/closed#issue/23 +## 2010-05-05 (1.4.3) + * Fixed some test assertions, from Ruby r27587 and r27590, patch by nobu. + * Fixed issue http://github.com/ruby/json/issues/#issue/20 reported by + electronicwhisper@github. Thx! + +## 2010-04-26 (1.4.2) + * Applied patch from naruse Yui NARUSE to make building with + Microsoft Visual C possible again. + * Applied patch from devrandom in order to allow building of + json_pure if extensiontask is not present. + * Thanks to Dustin Schneider , who reported a memory + leak, which is fixed in this release. + * Applied 993f261ccb8f911d2ae57e9db48ec7acd0187283 patch from josh@github. + +## 2010-04-25 (1.4.1) + * Fix for a bug reported by Dan DeLeo , caused by T_FIXNUM + being different on 32bit/64bit architectures. + +## 2010-04-23 (1.4.0) + * Major speed improvements and building with simplified + directory/file-structure. + * Extension should at least be compatible with MRI, YARV and Rubinius. + +## 2010-04-07 (1.2.4) + * Trigger const_missing callback to make Rails' dynamic class loading work. + +## 2010-03-11 (1.2.3) + * Added a `State#[]` method which returns an attribute's value in order to + increase duck type compatibility to Hash. + +## 2010-02-27 (1.2.2) + * Made some changes to make the building of the parser/generator compatible + to Rubinius. + +## 2009-11-25 (1.2.1) + * Added `:symbolize_names` option to Parser, which returns symbols instead of + strings in object names/keys. + +## 2009-10-01 (1.2.0) + * `fast_generate` now raises an exception for nan and infinite floats. + * On Ruby 1.8 json supports parsing of UTF-8, UTF-16BE, UTF-16LE, UTF-32BE, + and UTF-32LE JSON documents now. Under Ruby 1.9 the M17n conversion + functions are used to convert from all supported encodings. ASCII-8BIT + encoded strings are handled like all strings under Ruby 1.8 were. + * Better documentation + +## 2009-08-23 (1.1.9) + * Added forgotten main doc file `extra_rdoc_files`. + +## 2009-08-23 (1.1.8) + * Applied a patch by OZAWA Sakuro to make json/pure + work in environments that don't provide iconv. + * Applied patch by okkez_ in order to fix Ruby Bug #1768: + http://redmine.ruby-lang.org/issues/show/1768. + * Finally got around to avoid the rather paranoid escaping of ?/ characters + in the generator's output. The parsers aren't affected by this change. + Thanks to Rich Apodaca for the suggestion. + +## 2009-06-29 (1.1.7) + * Security Fix for JSON::Pure::Parser. A specially designed string could + cause catastrophic backtracking in one of the parser's regular expressions + in earlier 1.1.x versions. JSON::Ext::Parser isn't affected by this issue. + Thanks to Bartosz Blimke for reporting this + problem. + * This release also uses a less strict ruby version requirement for the + creation of the mswin32 native gem. + +## 2009-05-10 (1.1.6) + * No changes. І tested native linux gems in the last release and they don't + play well with different ruby versions other than the one the gem was built + with. This release is just to bump the version number in order to skip the + native gem on rubyforge. + +## 2009-05-10 (1.1.5) + * Started to build gems with rake-compiler gem. + * Applied patch object/array class patch from Brian Candler + and fixes. + +## 2009-04-01 (1.1.4) + * Fixed a bug in the creation of serialized generic rails objects reported by + Friedrich Graeter . + * Deleted tests/runner.rb, we're using testrb instead. + * Editor supports Infinity in numbers now. + * Made some changes in order to get the library to compile/run under Ruby + 1.9. + * Improved speed of the code path for the fast_generate method in the pure + variant. + +## 2008-07-10 (1.1.3) + * Wesley Beary reported a bug in json/add/core's DateTime + handling: If the nominator and denominator of the offset were divisible by + each other Ruby's Rational#to_s returns them as an integer not a fraction + with '/'. This caused a ZeroDivisionError during parsing. + * Use Date#start and DateTime#start instead of sg method, while + remaining backwards compatible. + * Supports ragel >= 6.0 now. + * Corrected some tests. + * Some minor changes. + +## 2007-11-27 (1.1.2) + * Remember default dir (last used directory) in editor. + * JSON::Editor.edit method added, the editor can now receive json texts from + the clipboard via C-v. + * Load json texts from an URL pasted via middle button press. + * Added :create_additions option to Parser. This makes it possible to disable + the creation of additions by force, in order to treat json texts as data + while having additions loaded. + * Jacob Maine reported, that JSON(:foo) outputs a JSON + object if the rails addition is enabled, which is wrong. It now outputs a + JSON string "foo" instead, like suggested by Jacob Maine. + * Discovered a bug in the Ruby Bugs Tracker on rubyforge, that was reported + by John Evans lgastako@gmail.com. He could produce a crash in the JSON + generator by returning something other than a String instance from a + to_json method. I now guard against this by doing a rather crude type + check, which raises an exception instead of crashing. + +## 2007-07-06 (1.1.1) + * Yui NARUSE sent some patches to fix tests for Ruby + 1.9. I applied them and adapted some of them a bit to run both on 1.8 and + 1.9. + * Introduced a `JSON.parse!` method without depth checking for people who + like danger. + * Made generate and `pretty_generate` methods configurable by an options hash. + * Added :allow_nan option to parser and generator in order to handle NaN, + Infinity, and -Infinity correctly - if requested. Floats, which aren't numbers, + aren't valid JSON according to RFC4627, so by default an exception will be + raised if any of these symbols are encountered. Thanks to Andrea Censi + for his hint about this. + * Fixed some more tests for Ruby 1.9. + * Implemented dump/load interface of Marshal as suggested in ruby-core:11405 + by murphy . + * Implemented the `max_nesting` feature for generate methods, too. + * Added some implementations for ruby core's custom objects for + serialisation/deserialisation purposes. + +## 2007-05-21 (1.1.0) + * Implemented max_nesting feature for parser to avoid stack overflows for + data from untrusted sources. If you trust the source, you can disable it + with the option max_nesting => false. + * Piers Cawley reported a bug, that not every + character can be escaped by `\` as required by RFC4627. There's a + contradiction between David Crockford's JSON checker test vectors (in + tests/fixtures) and RFC4627, though. I decided to stick to the RFC, because + the JSON checker seems to be a bit older than the RFC. + * Extended license to Ruby License, which includes the GPL. + * Added keyboard shortcuts, and 'Open location' menu item to edit_json.rb. + +## 2007-05-09 (1.0.4) + * Applied a patch from Yui NARUSE to make JSON compile + under Ruby 1.9. Thank you very much for mailing it to me! + * Made binary variants of JSON fail early, instead of falling back to the + pure version. This should avoid overshadowing of eventual problems while + loading of the binary. + +## 2007-03-24 (1.0.3) + * Improved performance of pure variant a bit. + * The ext variant of this release supports the mswin32 platform. Ugh! + +## 2007-03-24 (1.0.2) + * Ext Parser didn't parse 0e0 correctly into 0.0: Fixed! + +## 2007-03-24 (1.0.1) + * Forgot some object files in the build dir. I really like that - not! + +## 2007-03-24 (1.0.0) + * Added C implementations for the JSON generator and a ragel based JSON + parser in C. + * Much more tests, especially fixtures from json.org. + * Further improved conformance to RFC4627. + +## 2007-02-09 (0.4.3) + * Conform more to RFC4627 for JSON: This means JSON strings + now always must contain exactly one object `"{ ... }"` or array `"[ ... ]"` in + order to be parsed without raising an exception. The definition of what + constitutes a whitespace is narrower in JSON than in Ruby ([ \t\r\n]), and + there are differences in floats and integers (no octals or hexadecimals) as + well. + * Added aliases generate and `pretty_generate` of unparse and `pretty_unparse`. + * Fixed a test case. + * Catch an `Iconv::InvalidEncoding` exception, that seems to occur on some Sun + boxes with SunOS 5.8, if iconv doesn't support utf16 conversions. This was + reported by Andrew R Jackson , thanks a bunch! + +## 2006-08-25 (0.4.2) + * Fixed a bug in handling solidi (/-characters), that was reported by + Kevin Gilpin . + +## 2006-02-06 (0.4.1) + * Fixed a bug related to escaping with backslashes. Thanks for the report go + to Florian Munz . + +## 2005-09-23 (0.4.0) + * Initial Rubyforge Version diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/COPYING b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/COPYING new file mode 100644 index 00000000..426810a7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/COPYING @@ -0,0 +1,56 @@ +Ruby is copyrighted free software by Yukihiro Matsumoto . +You can redistribute it and/or modify it under either the terms of the +2-clause BSDL (see the file BSDL), or the conditions below: + + 1. You may make and give away verbatim copies of the source form of the + software without restriction, provided that you duplicate all of the + original copyright notices and associated disclaimers. + + 2. You may modify your copy of the software in any way, provided that + you do at least ONE of the following: + + a) place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said + modifications to Usenet or an equivalent medium, or by allowing + the author to include your modifications in the software. + + b) use the modified software only within your corporation or + organization. + + c) give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d) make other distribution arrangements with the author. + + 3. You may distribute the software in object code or binary form, + provided that you do at least ONE of the following: + + a) distribute the binaries and library files of the software, + together with instructions (in the manual page or equivalent) + on where to get the original distribution. + + b) accompany the distribution with the machine-readable source of + the software. + + c) give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d) make other distribution arrangements with the author. + + 4. You may modify and include the part of the software into any other + software (possibly commercial). But some files in the distribution + are not written by the author, so that they are not under these terms. + + For the list of those files and their copying conditions, see the + file LEGAL. + + 5. The scripts and library files supplied as input to or produced as + output from the software do not automatically fall under the + copyright of the software, but belong to whomever generated them, + and may be sold commercially, and may be aggregated with this + software. + + 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/LEGAL b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/LEGAL new file mode 100644 index 00000000..737d18cb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/LEGAL @@ -0,0 +1,8 @@ +# -*- rdoc -*- + += LEGAL NOTICE INFORMATION +-------------------------- + +All the files in this distribution are covered under either the Ruby's +license (see the file COPYING) or public-domain except some files +mentioned below. diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/README.md b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/README.md new file mode 100644 index 00000000..11932721 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/README.md @@ -0,0 +1,281 @@ +# JSON implementation for Ruby + +[![CI](https://github.com/ruby/json/actions/workflows/ci.yml/badge.svg)](https://github.com/ruby/json/actions/workflows/ci.yml) + +## Description + +This is an implementation of the JSON specification according to RFC 7159 +http://www.ietf.org/rfc/rfc7159.txt . + +The JSON generator generate UTF-8 character sequences by default. +If an :ascii\_only option with a true value is given, they escape all +non-ASCII and control characters with \uXXXX escape sequences, and support +UTF-16 surrogate pairs in order to be able to generate the whole range of +unicode code points. + +All strings, that are to be encoded as JSON strings, should be UTF-8 byte +sequences on the Ruby side. To encode raw binary strings, that aren't UTF-8 +encoded, please use the to\_json\_raw\_object method of String (which produces +an object, that contains a byte array) and decode the result on the receiving +endpoint. + +## Installation + +Install the gem and add to the application's Gemfile by executing: + + $ bundle add json + +If bundler is not being used to manage dependencies, install the gem by executing: + + $ gem install json + +## Basic Usage + +To use JSON you can + +```ruby +require 'json' +``` + +Now you can parse a JSON document into a ruby data structure by calling + +```ruby +JSON.parse(document) +``` + +If you want to generate a JSON document from a ruby data structure call +```ruby +JSON.generate(data) +``` + +You can also use the `pretty_generate` method (which formats the output more +verbosely and nicely) or `fast_generate` (which doesn't do any of the security +checks generate performs, e. g. nesting deepness checks). + +## Casting non native types + +JSON documents can only support Hashes, Arrays, Strings, Integers and Floats. + +By default if you attempt to serialize something else, `JSON.generate` will +search for a `#to_json` method on that object: + +```ruby +Position = Struct.new(:latitude, :longitude) do + def to_json(state = nil, *) + JSON::State.from_state(state).generate({ + latitude: latitude, + longitude: longitude, + }) + end +end + +JSON.generate([ + Position.new(12323.234, 435345.233), + Position.new(23434.676, 159435.324), +]) # => [{"latitude":12323.234,"longitude":435345.233},{"latitude":23434.676,"longitude":159435.324}] +``` + +If a `#to_json` method isn't defined on the object, `JSON.generate` will fallback to call `#to_s`: + +```ruby +JSON.generate(Object.new) # => "#" +``` + +Both of these behavior can be disabled using the `strict: true` option: + +```ruby +JSON.generate(Object.new, strict: true) # => Object not allowed in JSON (JSON::GeneratorError) +JSON.generate(Position.new(1, 2)) # => Position not allowed in JSON (JSON::GeneratorError) +``` + +## JSON::Coder + +Since `#to_json` methods are global, it can sometimes be problematic if you need a given type to be +serialized in different ways in different locations. + +Instead it is recommended to use the newer `JSON::Coder` API: + +```ruby +module MyApp + API_JSON_CODER = JSON::Coder.new do |object| + case object + when Time + object.iso8601(3) + else + object + end + end +end + +puts MyApp::API_JSON_CODER.dump(Time.now.utc) # => "2025-01-21T08:41:44.286Z" +``` + +The provided block is called for all objects that don't have a native JSON equivalent, and +must return a Ruby object that has a native JSON equivalent. + +## Combining JSON fragments + +To combine JSON fragments into a bigger JSON document, you can use `JSON::Fragment`: + +```ruby +posts_json = cache.fetch_multi(post_ids) do |post_id| + JSON.generate(Post.find(post_id)) +end +posts_json.map! { |post_json| JSON::Fragment.new(post_json) } +JSON.generate({ posts: posts_json, count: posts_json.count }) +``` + +## Round-tripping arbitrary types + +> [!CAUTION] +> You should never use `JSON.unsafe_load` nor `JSON.parse(str, create_additions: true)` to parse untrusted user input, +> as it can lead to remote code execution vulnerabilities. + +To create a JSON document from a ruby data structure, you can call +`JSON.generate` like that: + +```ruby +json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10] +# => "[1,2,{\"a\":3.141},false,true,null,\"4..10\"]" +``` + +To get back a ruby data structure from a JSON document, you have to call +JSON.parse on it: + +```ruby +JSON.parse json +# => [1, 2, {"a"=>3.141}, false, true, nil, "4..10"] +``` + +Note, that the range from the original data structure is a simple +string now. The reason for this is, that JSON doesn't support ranges +or arbitrary classes. In this case the json library falls back to call +`Object#to_json`, which is the same as `#to_s.to_json`. + +It's possible to add JSON support serialization to arbitrary classes by +simply implementing a more specialized version of the `#to_json method`, that +should return a JSON object (a hash converted to JSON with `#to_json`) like +this (don't forget the `*a` for all the arguments): + +```ruby +class Range + def to_json(*a) + { + 'json_class' => self.class.name, # = 'Range' + 'data' => [ first, last, exclude_end? ] + }.to_json(*a) + end +end +``` + +The hash key `json_class` is the class, that will be asked to deserialise the +JSON representation later. In this case it's `Range`, but any namespace of +the form `A::B` or `::A::B` will do. All other keys are arbitrary and can be +used to store the necessary data to configure the object to be deserialised. + +If the key `json_class` is found in a JSON object, the JSON parser checks +if the given class responds to the `json_create` class method. If so, it is +called with the JSON object converted to a Ruby hash. So a range can +be deserialised by implementing `Range.json_create` like this: + +```ruby +class Range + def self.json_create(o) + new(*o['data']) + end +end +``` + +Now it possible to serialise/deserialise ranges as well: + +```ruby +json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10] +# => "[1,2,{\"a\":3.141},false,true,null,{\"json_class\":\"Range\",\"data\":[4,10,false]}]" +JSON.parse json +# => [1, 2, {"a"=>3.141}, false, true, nil, 4..10] +json = JSON.generate [1, 2, {"a"=>3.141}, false, true, nil, 4..10] +# => "[1,2,{\"a\":3.141},false,true,null,{\"json_class\":\"Range\",\"data\":[4,10,false]}]" +JSON.unsafe_load json +# => [1, 2, {"a"=>3.141}, false, true, nil, 4..10] +``` + +`JSON.generate` always creates the shortest possible string representation of a +ruby data structure in one line. This is good for data storage or network +protocols, but not so good for humans to read. Fortunately there's also +`JSON.pretty_generate` (or `JSON.pretty_generate`) that creates a more readable +output: + +```ruby + puts JSON.pretty_generate([1, 2, {"a"=>3.141}, false, true, nil, 4..10]) + [ + 1, + 2, + { + "a": 3.141 + }, + false, + true, + null, + { + "json_class": "Range", + "data": [ + 4, + 10, + false + ] + } + ] +``` + +There are also the methods `Kernel#j` for generate, and `Kernel#jj` for +`pretty_generate` output to the console, that work analogous to Core Ruby's `p` and +the `pp` library's `pp` methods. + +## Development + +### Prerequisites + +1. Clone the repository +2. Install dependencies with `bundle install` + +### Testing + +The full test suite can be run with: + +```bash +bundle exec rake test +``` + +### Release + +Update the `lib/json/version.rb` file. + +``` +rbenv shell 2.6.5 +rake build +gem push pkg/json-2.3.0.gem + +rbenv shell jruby-9.2.9.0 +rake build +gem push pkg/json-2.3.0-java.gem +``` + +## Author + +Florian Frank + +## License + +Ruby License, see https://www.ruby-lang.org/en/about/license.txt. + +## Download + +The latest version of this library can be downloaded at + +* https://rubygems.org/gems/json + +Online Documentation should be located at + +* https://www.rubydoc.info/gems/json + +[Ragel]: http://www.colm.net/open-source/ragel/ diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/fbuffer/fbuffer.h b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/fbuffer/fbuffer.h new file mode 100644 index 00000000..d3237147 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/fbuffer/fbuffer.h @@ -0,0 +1,270 @@ +#ifndef _FBUFFER_H_ +#define _FBUFFER_H_ + +#include "ruby.h" +#include "ruby/encoding.h" +#include "../vendor/jeaiii-ltoa.h" + +/* shims */ +/* This is the fallback definition from Ruby 3.4 */ + +#ifndef RBIMPL_STDBOOL_H +#if defined(__cplusplus) +# if defined(HAVE_STDBOOL_H) && (__cplusplus >= 201103L) +# include +# endif +#elif defined(HAVE_STDBOOL_H) +# include +#elif !defined(HAVE__BOOL) +typedef unsigned char _Bool; +# define bool _Bool +# define true ((_Bool)+1) +# define false ((_Bool)+0) +# define __bool_true_false_are_defined +#endif +#endif + +#ifndef RB_UNLIKELY +#define RB_UNLIKELY(expr) expr +#endif + +#ifndef RB_LIKELY +#define RB_LIKELY(expr) expr +#endif + +#ifndef MAYBE_UNUSED +# define MAYBE_UNUSED(x) x +#endif + +#ifdef RUBY_DEBUG +#ifndef JSON_DEBUG +#define JSON_DEBUG RUBY_DEBUG +#endif +#endif + +enum fbuffer_type { + FBUFFER_HEAP_ALLOCATED = 0, + FBUFFER_STACK_ALLOCATED = 1, +}; + +typedef struct FBufferStruct { + enum fbuffer_type type; + unsigned long initial_length; + unsigned long len; + unsigned long capa; +#ifdef JSON_DEBUG + unsigned long requested; +#endif + char *ptr; + VALUE io; +} FBuffer; + +#define FBUFFER_STACK_SIZE 512 +#define FBUFFER_IO_BUFFER_SIZE (16384 - 1) +#define FBUFFER_INITIAL_LENGTH_DEFAULT 1024 + +#define FBUFFER_PTR(fb) ((fb)->ptr) +#define FBUFFER_LEN(fb) ((fb)->len) +#define FBUFFER_CAPA(fb) ((fb)->capa) +#define FBUFFER_PAIR(fb) FBUFFER_PTR(fb), FBUFFER_LEN(fb) + +static void fbuffer_free(FBuffer *fb); +static void fbuffer_clear(FBuffer *fb); +static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len); +static void fbuffer_append_long(FBuffer *fb, long number); +static inline void fbuffer_append_char(FBuffer *fb, char newchr); +static VALUE fbuffer_finalize(FBuffer *fb); + +static void fbuffer_stack_init(FBuffer *fb, unsigned long initial_length, char *stack_buffer, long stack_buffer_size) +{ + fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT; + if (stack_buffer) { + fb->type = FBUFFER_STACK_ALLOCATED; + fb->ptr = stack_buffer; + fb->capa = stack_buffer_size; + } +#ifdef JSON_DEBUG + fb->requested = 0; +#endif +} + +static inline void fbuffer_consumed(FBuffer *fb, unsigned long consumed) +{ +#ifdef JSON_DEBUG + if (consumed > fb->requested) { + rb_bug("fbuffer: Out of bound write"); + } + fb->requested = 0; +#endif + fb->len += consumed; +} + +static void fbuffer_free(FBuffer *fb) +{ + if (fb->ptr && fb->type == FBUFFER_HEAP_ALLOCATED) { + ruby_xfree(fb->ptr); + } +} + +static void fbuffer_clear(FBuffer *fb) +{ + fb->len = 0; +} + +static void fbuffer_flush(FBuffer *fb) +{ + rb_io_write(fb->io, rb_utf8_str_new(fb->ptr, fb->len)); + fbuffer_clear(fb); +} + +static void fbuffer_realloc(FBuffer *fb, unsigned long required) +{ + if (required > fb->capa) { + if (fb->type == FBUFFER_STACK_ALLOCATED) { + const char *old_buffer = fb->ptr; + fb->ptr = ALLOC_N(char, required); + fb->type = FBUFFER_HEAP_ALLOCATED; + MEMCPY(fb->ptr, old_buffer, char, fb->len); + } else { + REALLOC_N(fb->ptr, char, required); + } + fb->capa = required; + } +} + +static void fbuffer_do_inc_capa(FBuffer *fb, unsigned long requested) +{ + if (RB_UNLIKELY(fb->io)) { + if (fb->capa < FBUFFER_IO_BUFFER_SIZE) { + fbuffer_realloc(fb, FBUFFER_IO_BUFFER_SIZE); + } else { + fbuffer_flush(fb); + } + + if (RB_LIKELY(requested < fb->capa)) { + return; + } + } + + unsigned long required; + + if (RB_UNLIKELY(!fb->ptr)) { + fb->ptr = ALLOC_N(char, fb->initial_length); + fb->capa = fb->initial_length; + } + + for (required = fb->capa; requested > required - fb->len; required <<= 1); + + fbuffer_realloc(fb, required); +} + +static inline void fbuffer_inc_capa(FBuffer *fb, unsigned long requested) +{ +#ifdef JSON_DEBUG + fb->requested = requested; +#endif + + if (RB_UNLIKELY(requested > fb->capa - fb->len)) { + fbuffer_do_inc_capa(fb, requested); + } +} + +static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len) +{ + if (len > 0) { + fbuffer_inc_capa(fb, len); + MEMCPY(fb->ptr + fb->len, newstr, char, len); + fbuffer_consumed(fb, len); + } +} + +/* Appends a character into a buffer. The buffer needs to have sufficient capacity, via fbuffer_inc_capa(...). */ +static inline void fbuffer_append_reserved_char(FBuffer *fb, char chr) +{ +#ifdef JSON_DEBUG + if (fb->requested < 1) { + rb_bug("fbuffer: unreserved write"); + } + fb->requested--; +#endif + + fb->ptr[fb->len] = chr; + fb->len++; +} + +static void fbuffer_append_str(FBuffer *fb, VALUE str) +{ + const char *newstr = StringValuePtr(str); + unsigned long len = RSTRING_LEN(str); + + RB_GC_GUARD(str); + + fbuffer_append(fb, newstr, len); +} + +static inline void fbuffer_append_char(FBuffer *fb, char newchr) +{ + fbuffer_inc_capa(fb, 1); + *(fb->ptr + fb->len) = newchr; + fbuffer_consumed(fb, 1); +} + +static inline char *fbuffer_cursor(FBuffer *fb) +{ + return fb->ptr + fb->len; +} + +static inline void fbuffer_advance_to(FBuffer *fb, char *end) +{ + fbuffer_consumed(fb, (end - fb->ptr) - fb->len); +} + +/* + * Appends the decimal string representation of \a number into the buffer. + */ +static void fbuffer_append_long(FBuffer *fb, long number) +{ + /* + * The jeaiii_ultoa() function produces digits left-to-right, + * allowing us to write directly into the buffer, but we don't know + * the number of resulting characters. + * + * We do know, however, that the `number` argument is always in the + * range 0xc000000000000000 to 0x3fffffffffffffff, or, in decimal, + * -4611686018427387904 to 4611686018427387903. The max number of chars + * generated is therefore 20 (including a potential sign character). + */ + + static const int MAX_CHARS_FOR_LONG = 20; + + fbuffer_inc_capa(fb, MAX_CHARS_FOR_LONG); + + if (number < 0) { + fbuffer_append_reserved_char(fb, '-'); + + /* + * Since number is always > LONG_MIN, `-number` will not overflow + * and is always the positive abs() value. + */ + number = -number; + } + + char *end = jeaiii_ultoa(fbuffer_cursor(fb), number); + fbuffer_advance_to(fb, end); +} + +static VALUE fbuffer_finalize(FBuffer *fb) +{ + if (fb->io) { + fbuffer_flush(fb); + fbuffer_free(fb); + rb_io_flush(fb->io); + return fb->io; + } else { + VALUE result = rb_utf8_str_new(FBUFFER_PTR(fb), FBUFFER_LEN(fb)); + fbuffer_free(fb); + return result; + } +} + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/generator/Makefile b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/generator/Makefile new file mode 100644 index 00000000..c9afe29a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/generator/Makefile @@ -0,0 +1,273 @@ + +SHELL = /bin/sh + +# V=0 quiet, V=1 verbose. other values don't work. +V = 0 +V0 = $(V:0=) +Q1 = $(V:1=) +Q = $(Q1:0=@) +ECHO1 = $(V:1=@ :) +ECHO = $(ECHO1:0=@ echo) +NULLCMD = : + +#### Start of system configuration section. #### + +srcdir = . +topdir = /opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 +hdrdir = $(topdir) +arch_hdrdir = /opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux +PATH_SEPARATOR = : +VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby +prefix = $(DESTDIR)/opt/hostedtoolcache/Ruby/3.4.4/x64 +rubysitearchprefix = $(rubylibprefix)/$(sitearch) +rubyarchprefix = $(rubylibprefix)/$(arch) +rubylibprefix = $(libdir)/$(RUBY_BASE_NAME) +exec_prefix = $(prefix) +vendorarchhdrdir = $(vendorhdrdir)/$(sitearch) +sitearchhdrdir = $(sitehdrdir)/$(sitearch) +rubyarchhdrdir = $(rubyhdrdir)/$(arch) +vendorhdrdir = $(rubyhdrdir)/vendor_ruby +sitehdrdir = $(rubyhdrdir)/site_ruby +rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME) +vendorarchdir = $(vendorlibdir)/$(sitearch) +vendorlibdir = $(vendordir)/$(ruby_version) +vendordir = $(rubylibprefix)/vendor_ruby +sitearchdir = $(sitelibdir)/$(sitearch) +sitelibdir = $(sitedir)/$(ruby_version) +sitedir = $(rubylibprefix)/site_ruby +rubyarchdir = $(rubylibdir)/$(arch) +rubylibdir = $(rubylibprefix)/$(ruby_version) +sitearchincludedir = $(includedir)/$(sitearch) +archincludedir = $(includedir)/$(arch) +sitearchlibdir = $(libdir)/$(sitearch) +archlibdir = $(libdir)/$(arch) +ridir = $(datarootdir)/$(RI_BASE_NAME) +modular_gc_dir = $(DESTDIR) +mandir = $(datarootdir)/man +localedir = $(datarootdir)/locale +libdir = $(exec_prefix)/lib +psdir = $(docdir) +pdfdir = $(docdir) +dvidir = $(docdir) +htmldir = $(docdir) +infodir = $(datarootdir)/info +docdir = $(datarootdir)/doc/$(PACKAGE) +oldincludedir = $(DESTDIR)/usr/include +includedir = $(prefix)/include +runstatedir = $(localstatedir)/run +localstatedir = $(prefix)/var +sharedstatedir = $(prefix)/com +sysconfdir = $(prefix)/etc +datadir = $(datarootdir) +datarootdir = $(prefix)/share +libexecdir = $(exec_prefix)/libexec +sbindir = $(exec_prefix)/sbin +bindir = $(exec_prefix)/bin +archdir = $(rubyarchdir) + + +CC_WRAPPER = +CC = gcc +CXX = g++ +LIBRUBY = $(LIBRUBY_SO) +LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a +LIBRUBYARG_SHARED = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME) +LIBRUBYARG_STATIC = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)-static $(MAINLIBS) +empty = +OUTFLAG = -o $(empty) +COUTFLAG = -o $(empty) +CSRCFLAG = $(empty) + +RUBY_EXTCONF_H = +cflags = $(hardenflags) $(optflags) $(debugflags) $(warnflags) +cxxflags = +optflags = -O3 -fno-fast-math +debugflags = -ggdb3 +warnflags = -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef +cppflags = +CCDLFLAGS = -fPIC +CFLAGS = $(CCDLFLAGS) $(cflags) -fPIC -std=c99 $(ARCH_FLAG) +INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) +DEFS = +CPPFLAGS = -DJSON_GENERATOR -DHAVE_X86INTRIN_H -DHAVE_TYPE___M128I -DJSON_ENABLE_SIMD -DHAVE_CPUID_H -DENABLE_PATH_CHECK=0 $(DEFS) $(cppflags) +CXXFLAGS = $(CCDLFLAGS) $(ARCH_FLAG) +ldflags = -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed +dldflags = -Wl,--compress-debug-sections=zlib +ARCH_FLAG = +DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG) +LDSHARED = $(CC) -shared +LDSHAREDXX = $(CXX) -shared +POSTLINK = : +AR = gcc-ar +LD = ld +EXEEXT = + +RUBY_INSTALL_NAME = $(RUBY_BASE_NAME) +RUBY_SO_NAME = ruby +RUBYW_INSTALL_NAME = +RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version) +RUBYW_BASE_NAME = rubyw +RUBY_BASE_NAME = ruby + +arch = x86_64-linux +sitearch = $(arch) +ruby_version = 3.4.0 +ruby = $(bindir)/$(RUBY_BASE_NAME) +RUBY = $(ruby) +BUILTRUBY = $(bindir)/$(RUBY_BASE_NAME) +ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/backward.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h + +RM = rm -f +RM_RF = rm -fr +RMDIRS = rmdir --ignore-fail-on-non-empty -p +MAKEDIRS = /usr/bin/mkdir -p +INSTALL = /usr/bin/install -c +INSTALL_PROG = $(INSTALL) -m 0755 +INSTALL_DATA = $(INSTALL) -m 644 +COPY = cp +TOUCH = exit > + +#### End of system configuration section. #### + +preload = +libpath = . $(libdir) +LIBPATH = -L. -L$(libdir) -Wl,-rpath,$(libdir) +DEFFILE = + +CLEANFILES = mkmf.log +DISTCLEANFILES = +DISTCLEANDIRS = + +extout = +extout_prefix = +target_prefix = /json/ext +LOCAL_LIBS = +LIBS = $(LIBRUBYARG_SHARED) -lm -lpthread -lc +ORIG_SRCS = generator.c +SRCS = $(ORIG_SRCS) +OBJS = generator.o +HDRS = $(srcdir)/simd.h +LOCAL_HDRS = +TARGET = generator +TARGET_NAME = generator +TARGET_ENTRY = Init_$(TARGET_NAME) +DLLIB = $(TARGET).so +EXTSTATIC = +STATIC_LIB = + +TIMESTAMP_DIR = . +BINDIR = $(bindir) +RUBYCOMMONDIR = $(sitedir)$(target_prefix) +RUBYLIBDIR = $(sitelibdir)$(target_prefix) +RUBYARCHDIR = $(sitearchdir)$(target_prefix) +HDRDIR = $(sitehdrdir)$(target_prefix) +ARCHHDRDIR = $(sitearchhdrdir)$(target_prefix) +TARGET_SO_DIR = +TARGET_SO = $(TARGET_SO_DIR)$(DLLIB) +CLEANLIBS = $(TARGET_SO) false +CLEANOBJS = $(OBJS) *.bak +TARGET_SO_DIR_TIMESTAMP = $(TIMESTAMP_DIR)/.sitearchdir.-.json.-.ext.time + +all: $(DLLIB) +static: $(STATIC_LIB) +.PHONY: all install static install-so install-rb +.PHONY: clean clean-so clean-static clean-rb + +clean-static:: +clean-rb-default:: +clean-rb:: +clean-so:: +clean: clean-so clean-static clean-rb-default clean-rb + -$(Q)$(RM_RF) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time + +distclean-rb-default:: +distclean-rb:: +distclean-so:: +distclean-static:: +distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb + -$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + -$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + -$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true + +realclean: distclean +install: install-so install-rb + +install-so: $(DLLIB) $(TARGET_SO_DIR_TIMESTAMP) + $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) +clean-static:: + -$(Q)$(RM) $(STATIC_LIB) +install-rb: pre-install-rb do-install-rb install-rb-default +install-rb-default: pre-install-rb-default do-install-rb-default +pre-install-rb: Makefile +pre-install-rb-default: Makefile +do-install-rb: +do-install-rb-default: +pre-install-rb-default: + @$(NULLCMD) +$(TARGET_SO_DIR_TIMESTAMP): + $(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR) + $(Q) $(TOUCH) $@ + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + +.SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S + +.cc.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cc.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.mm.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.mm.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cxx.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cxx.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cpp.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cpp.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.c.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.c.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.m.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.m.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +$(TARGET_SO): $(OBJS) Makefile + $(ECHO) linking shared-object json/ext/$(DLLIB) + -$(Q)$(RM) $(@) + $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) + $(Q) $(POSTLINK) + + + +$(OBJS): $(HDRS) $(ruby_headers) diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/generator/extconf.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/generator/extconf.rb new file mode 100644 index 00000000..f58574a6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/generator/extconf.rb @@ -0,0 +1,40 @@ +require 'mkmf' + +if RUBY_ENGINE == 'truffleruby' + # The pure-Ruby generator is faster on TruffleRuby, so skip compiling the generator extension + File.write('Makefile', dummy_makefile("").join) +else + append_cflags("-std=c99") + $defs << "-DJSON_GENERATOR" + $defs << "-DJSON_DEBUG" if ENV["JSON_DEBUG"] + + if enable_config('generator-use-simd', default=!ENV["JSON_DISABLE_SIMD"]) + if RbConfig::CONFIG['host_cpu'] =~ /^(arm.*|aarch64.*)/ + # Try to compile a small program using NEON instructions + if have_header('arm_neon.h') + have_type('uint8x16_t', headers=['arm_neon.h']) && try_compile(<<~'SRC') + #include + int main() { + uint8x16_t test = vdupq_n_u8(32); + return 0; + } + SRC + $defs.push("-DJSON_ENABLE_SIMD") + end + end + + if have_header('x86intrin.h') && have_type('__m128i', headers=['x86intrin.h']) && try_compile(<<~'SRC') + #include + int main() { + __m128i test = _mm_set1_epi8(32); + return 0; + } + SRC + $defs.push("-DJSON_ENABLE_SIMD") + end + + have_header('cpuid.h') + end + + create_makefile 'json/ext/generator' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/generator/generator.c b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/generator/generator.c new file mode 100644 index 00000000..f7690a23 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/generator/generator.c @@ -0,0 +1,2188 @@ +#include "ruby.h" +#include "../fbuffer/fbuffer.h" +#include "../vendor/fpconv.c" + +#include +#include + +#include "simd.h" + +/* ruby api and some helpers */ + +typedef struct JSON_Generator_StateStruct { + VALUE indent; + VALUE space; + VALUE space_before; + VALUE object_nl; + VALUE array_nl; + VALUE as_json; + + long max_nesting; + long depth; + long buffer_initial_length; + + bool allow_nan; + bool ascii_only; + bool script_safe; + bool strict; +} JSON_Generator_State; + +#ifndef RB_UNLIKELY +#define RB_UNLIKELY(cond) (cond) +#endif + +static VALUE mJSON, cState, cFragment, mString_Extend, eGeneratorError, eNestingError, Encoding_UTF_8; + +static ID i_to_s, i_to_json, i_new, i_pack, i_unpack, i_create_id, i_extend, i_encode; +static VALUE sym_indent, sym_space, sym_space_before, sym_object_nl, sym_array_nl, sym_max_nesting, sym_allow_nan, + sym_ascii_only, sym_depth, sym_buffer_initial_length, sym_script_safe, sym_escape_slash, sym_strict, sym_as_json; + + +#define GET_STATE_TO(self, state) \ + TypedData_Get_Struct(self, JSON_Generator_State, &JSON_Generator_State_type, state) + +#define GET_STATE(self) \ + JSON_Generator_State *state; \ + GET_STATE_TO(self, state) + +struct generate_json_data; + +typedef void (*generator_func)(FBuffer *buffer, struct generate_json_data *data, VALUE obj); + +struct generate_json_data { + FBuffer *buffer; + VALUE vstate; + JSON_Generator_State *state; + VALUE obj; + generator_func func; +}; + +static VALUE cState_from_state_s(VALUE self, VALUE opts); +static VALUE cState_partial_generate(VALUE self, VALUE obj, generator_func, VALUE io); +static void generate_json(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_object(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_array(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_string(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_null(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_false(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_true(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +#ifdef RUBY_INTEGER_UNIFICATION +static void generate_json_integer(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +#endif +static void generate_json_fixnum(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_bignum(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_float(FBuffer *buffer, struct generate_json_data *data, VALUE obj); +static void generate_json_fragment(FBuffer *buffer, struct generate_json_data *data, VALUE obj); + +static int usascii_encindex, utf8_encindex, binary_encindex; + +#ifdef RBIMPL_ATTR_NORETURN +RBIMPL_ATTR_NORETURN() +#endif +static void raise_generator_error_str(VALUE invalid_object, VALUE str) +{ + VALUE exc = rb_exc_new_str(eGeneratorError, str); + rb_ivar_set(exc, rb_intern("@invalid_object"), invalid_object); + rb_exc_raise(exc); +} + +#ifdef RBIMPL_ATTR_NORETURN +RBIMPL_ATTR_NORETURN() +#endif +#ifdef RBIMPL_ATTR_FORMAT +RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 3) +#endif +static void raise_generator_error(VALUE invalid_object, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + VALUE str = rb_vsprintf(fmt, args); + va_end(args); + raise_generator_error_str(invalid_object, str); +} + +// 0 - single byte char that don't need to be escaped. +// (x | 8) - char that needs to be escaped. +static const unsigned char CHAR_LENGTH_MASK = 7; +static const unsigned char ESCAPE_MASK = 8; + +typedef struct _search_state { + const char *ptr; + const char *end; + const char *cursor; + FBuffer *buffer; + +#ifdef HAVE_SIMD + const char *chunk_base; + const char *chunk_end; + bool has_matches; + +#if defined(HAVE_SIMD_NEON) + uint64_t matches_mask; +#elif defined(HAVE_SIMD_SSE2) + int matches_mask; +#else +#error "Unknown SIMD Implementation." +#endif /* HAVE_SIMD_NEON */ +#endif /* HAVE_SIMD */ +} search_state; + +#if (defined(__GNUC__ ) || defined(__clang__)) +#define FORCE_INLINE __attribute__((always_inline)) +#else +#define FORCE_INLINE +#endif + +static inline FORCE_INLINE void search_flush(search_state *search) +{ + // Do not remove this conditional without profiling, specifically escape-heavy text. + // escape_UTF8_char_basic will advance search->ptr and search->cursor (effectively a search_flush). + // For back-to-back characters that need to be escaped, specifcally for the SIMD code paths, this method + // will be called just before calling escape_UTF8_char_basic. There will be no characers to append for the + // consecutive characters that need to be escaped. While the fbuffer_append is a no-op if + // nothing needs to be flushed, we can save a few memory references with this conditional. + if (search->ptr > search->cursor) { + fbuffer_append(search->buffer, search->cursor, search->ptr - search->cursor); + search->cursor = search->ptr; + } +} + +static const unsigned char escape_table_basic[256] = { + // ASCII Control Characters + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + // ASCII Characters + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // '"' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, // '\\' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static unsigned char (*search_escape_basic_impl)(search_state *); + +static inline unsigned char search_escape_basic(search_state *search) +{ + while (search->ptr < search->end) { + if (RB_UNLIKELY(escape_table_basic[(const unsigned char)*search->ptr])) { + search_flush(search); + return 1; + } else { + search->ptr++; + } + } + search_flush(search); + return 0; +} + +static inline FORCE_INLINE void escape_UTF8_char_basic(search_state *search) +{ + const unsigned char ch = (unsigned char)*search->ptr; + switch (ch) { + case '"': fbuffer_append(search->buffer, "\\\"", 2); break; + case '\\': fbuffer_append(search->buffer, "\\\\", 2); break; + case '/': fbuffer_append(search->buffer, "\\/", 2); break; + case '\b': fbuffer_append(search->buffer, "\\b", 2); break; + case '\f': fbuffer_append(search->buffer, "\\f", 2); break; + case '\n': fbuffer_append(search->buffer, "\\n", 2); break; + case '\r': fbuffer_append(search->buffer, "\\r", 2); break; + case '\t': fbuffer_append(search->buffer, "\\t", 2); break; + default: { + const char *hexdig = "0123456789abcdef"; + char scratch[6] = { '\\', 'u', '0', '0', 0, 0 }; + scratch[4] = hexdig[(ch >> 4) & 0xf]; + scratch[5] = hexdig[ch & 0xf]; + fbuffer_append(search->buffer, scratch, 6); + break; + } + } + search->ptr++; + search->cursor = search->ptr; +} + +/* Converts in_string to a JSON string (without the wrapping '"' + * characters) in FBuffer out_buffer. + * + * Character are JSON-escaped according to: + * + * - Always: ASCII control characters (0x00-0x1F), dquote, and + * backslash. + * + * - If out_ascii_only: non-ASCII characters (>0x7F) + * + * - If script_safe: forwardslash (/), line separator (U+2028), and + * paragraph separator (U+2029) + * + * Everything else (should be UTF-8) is just passed through and + * appended to the result. + */ +static inline void convert_UTF8_to_JSON(search_state *search) +{ + while (search_escape_basic_impl(search)) { + escape_UTF8_char_basic(search); + } +} + +static inline void escape_UTF8_char(search_state *search, unsigned char ch_len) +{ + const unsigned char ch = (unsigned char)*search->ptr; + switch (ch_len) { + case 1: { + switch (ch) { + case '"': fbuffer_append(search->buffer, "\\\"", 2); break; + case '\\': fbuffer_append(search->buffer, "\\\\", 2); break; + case '/': fbuffer_append(search->buffer, "\\/", 2); break; + case '\b': fbuffer_append(search->buffer, "\\b", 2); break; + case '\f': fbuffer_append(search->buffer, "\\f", 2); break; + case '\n': fbuffer_append(search->buffer, "\\n", 2); break; + case '\r': fbuffer_append(search->buffer, "\\r", 2); break; + case '\t': fbuffer_append(search->buffer, "\\t", 2); break; + default: { + const char *hexdig = "0123456789abcdef"; + char scratch[6] = { '\\', 'u', '0', '0', 0, 0 }; + scratch[4] = hexdig[(ch >> 4) & 0xf]; + scratch[5] = hexdig[ch & 0xf]; + fbuffer_append(search->buffer, scratch, 6); + break; + } + } + break; + } + case 3: { + if (search->ptr[2] & 1) { + fbuffer_append(search->buffer, "\\u2029", 6); + } else { + fbuffer_append(search->buffer, "\\u2028", 6); + } + break; + } + } + search->cursor = (search->ptr += ch_len); +} + +#ifdef HAVE_SIMD + +static inline FORCE_INLINE char *copy_remaining_bytes(search_state *search, unsigned long vec_len, unsigned long len) +{ + // Flush the buffer so everything up until the last 'len' characters are unflushed. + search_flush(search); + + FBuffer *buf = search->buffer; + fbuffer_inc_capa(buf, vec_len); + + char *s = (buf->ptr + buf->len); + + // Pad the buffer with dummy characters that won't need escaping. + // This seem wateful at first sight, but memset of vector length is very fast. + memset(s, 'X', vec_len); + + // Optimistically copy the remaining 'len' characters to the output FBuffer. If there are no characters + // to escape, then everything ends up in the correct spot. Otherwise it was convenient temporary storage. + MEMCPY(s, search->ptr, char, len); + + return s; +} + +#ifdef HAVE_SIMD_NEON + +static inline FORCE_INLINE unsigned char neon_next_match(search_state *search) +{ + uint64_t mask = search->matches_mask; + uint32_t index = trailing_zeros64(mask) >> 2; + + // It is assumed escape_UTF8_char_basic will only ever increase search->ptr by at most one character. + // If we want to use a similar approach for full escaping we'll need to ensure: + // search->chunk_base + index >= search->ptr + // However, since we know escape_UTF8_char_basic only increases search->ptr by one, if the next match + // is one byte after the previous match then: + // search->chunk_base + index == search->ptr + search->ptr = search->chunk_base + index; + mask &= mask - 1; + search->matches_mask = mask; + search_flush(search); + return 1; +} + +// See: https://community.arm.com/arm-community-blogs/b/servers-and-cloud-computing-blog/posts/porting-x86-vector-bitmask-optimizations-to-arm-neon +static inline FORCE_INLINE uint64_t neon_match_mask(uint8x16_t matches) +{ + const uint8x8_t res = vshrn_n_u16(vreinterpretq_u16_u8(matches), 4); + const uint64_t mask = vget_lane_u64(vreinterpret_u64_u8(res), 0); + return mask & 0x8888888888888888ull; +} + +static inline FORCE_INLINE uint64_t neon_rules_update(const char *ptr) +{ + uint8x16_t chunk = vld1q_u8((const unsigned char *)ptr); + + // Trick: c < 32 || c == 34 can be factored as c ^ 2 < 33 + // https://lemire.me/blog/2025/04/13/detect-control-characters-quotes-and-backslashes-efficiently-using-swar/ + const uint8x16_t too_low_or_dbl_quote = vcltq_u8(veorq_u8(chunk, vdupq_n_u8(2)), vdupq_n_u8(33)); + + uint8x16_t has_backslash = vceqq_u8(chunk, vdupq_n_u8('\\')); + uint8x16_t needs_escape = vorrq_u8(too_low_or_dbl_quote, has_backslash); + + return neon_match_mask(needs_escape); +} + +static inline unsigned char search_escape_basic_neon(search_state *search) +{ + if (RB_UNLIKELY(search->has_matches)) { + // There are more matches if search->matches_mask > 0. + if (search->matches_mask > 0) { + return neon_next_match(search); + } else { + // neon_next_match will only advance search->ptr up to the last matching character. + // Skip over any characters in the last chunk that occur after the last match. + search->has_matches = false; + search->ptr = search->chunk_end; + } + } + + /* + * The code below implements an SIMD-based algorithm to determine if N bytes at a time + * need to be escaped. + * + * Assume the ptr = "Te\sting!" (the double quotes are included in the string) + * + * The explanation will be limited to the first 8 bytes of the string for simplicity. However + * the vector insructions may work on larger vectors. + * + * First, we load three constants 'lower_bound', 'backslash' and 'dblquote" in vector registers. + * + * lower_bound: [20 20 20 20 20 20 20 20] + * backslash: [5C 5C 5C 5C 5C 5C 5C 5C] + * dblquote: [22 22 22 22 22 22 22 22] + * + * Next we load the first chunk of the ptr: + * [22 54 65 5C 73 74 69 6E] (" T e \ s t i n) + * + * First we check if any byte in chunk is less than 32 (0x20). This returns the following vector + * as no bytes are less than 32 (0x20): + * [0 0 0 0 0 0 0 0] + * + * Next, we check if any byte in chunk is equal to a backslash: + * [0 0 0 FF 0 0 0 0] + * + * Finally we check if any byte in chunk is equal to a double quote: + * [FF 0 0 0 0 0 0 0] + * + * Now we have three vectors where each byte indicates if the corresponding byte in chunk + * needs to be escaped. We combine these vectors with a series of logical OR instructions. + * This is the needs_escape vector and it is equal to: + * [FF 0 0 FF 0 0 0 0] + * + * Next we compute the bitwise AND between each byte and 0x1 and compute the horizontal sum of + * the values in the vector. This computes how many bytes need to be escaped within this chunk. + * + * Finally we compute a mask that indicates which bytes need to be escaped. If the mask is 0 then, + * no bytes need to be escaped and we can continue to the next chunk. If the mask is not 0 then we + * have at least one byte that needs to be escaped. + */ + while (search->ptr + sizeof(uint8x16_t) <= search->end) { + uint64_t mask = neon_rules_update(search->ptr); + + if (!mask) { + search->ptr += sizeof(uint8x16_t); + continue; + } + search->matches_mask = mask; + search->has_matches = true; + search->chunk_base = search->ptr; + search->chunk_end = search->ptr + sizeof(uint8x16_t); + return neon_next_match(search); + } + + // There are fewer than 16 bytes left. + unsigned long remaining = (search->end - search->ptr); + if (remaining >= SIMD_MINIMUM_THRESHOLD) { + char *s = copy_remaining_bytes(search, sizeof(uint8x16_t), remaining); + + uint64_t mask = neon_rules_update(s); + + if (!mask) { + // Nothing to escape, ensure search_flush doesn't do anything by setting + // search->cursor to search->ptr. + fbuffer_consumed(search->buffer, remaining); + search->ptr = search->end; + search->cursor = search->end; + return 0; + } + + search->matches_mask = mask; + search->has_matches = true; + search->chunk_end = search->end; + search->chunk_base = search->ptr; + return neon_next_match(search); + } + + if (search->ptr < search->end) { + return search_escape_basic(search); + } + + search_flush(search); + return 0; +} +#endif /* HAVE_SIMD_NEON */ + +#ifdef HAVE_SIMD_SSE2 + +#define _mm_cmpge_epu8(a, b) _mm_cmpeq_epi8(_mm_max_epu8(a, b), a) +#define _mm_cmple_epu8(a, b) _mm_cmpge_epu8(b, a) +#define _mm_cmpgt_epu8(a, b) _mm_xor_si128(_mm_cmple_epu8(a, b), _mm_set1_epi8(-1)) +#define _mm_cmplt_epu8(a, b) _mm_cmpgt_epu8(b, a) + +static inline FORCE_INLINE unsigned char sse2_next_match(search_state *search) +{ + int mask = search->matches_mask; + int index = trailing_zeros(mask); + + // It is assumed escape_UTF8_char_basic will only ever increase search->ptr by at most one character. + // If we want to use a similar approach for full escaping we'll need to ensure: + // search->chunk_base + index >= search->ptr + // However, since we know escape_UTF8_char_basic only increases search->ptr by one, if the next match + // is one byte after the previous match then: + // search->chunk_base + index == search->ptr + search->ptr = search->chunk_base + index; + mask &= mask - 1; + search->matches_mask = mask; + search_flush(search); + return 1; +} + +#if defined(__clang__) || defined(__GNUC__) +#define TARGET_SSE2 __attribute__((target("sse2"))) +#else +#define TARGET_SSE2 +#endif + +static inline TARGET_SSE2 FORCE_INLINE int sse2_update(const char *ptr) +{ + __m128i chunk = _mm_loadu_si128((__m128i const*)ptr); + + // Trick: c < 32 || c == 34 can be factored as c ^ 2 < 33 + // https://lemire.me/blog/2025/04/13/detect-control-characters-quotes-and-backslashes-efficiently-using-swar/ + __m128i too_low_or_dbl_quote = _mm_cmplt_epu8(_mm_xor_si128(chunk, _mm_set1_epi8(2)), _mm_set1_epi8(33)); + __m128i has_backslash = _mm_cmpeq_epi8(chunk, _mm_set1_epi8('\\')); + __m128i needs_escape = _mm_or_si128(too_low_or_dbl_quote, has_backslash); + return _mm_movemask_epi8(needs_escape); +} + +static inline TARGET_SSE2 FORCE_INLINE unsigned char search_escape_basic_sse2(search_state *search) +{ + if (RB_UNLIKELY(search->has_matches)) { + // There are more matches if search->matches_mask > 0. + if (search->matches_mask > 0) { + return sse2_next_match(search); + } else { + // sse2_next_match will only advance search->ptr up to the last matching character. + // Skip over any characters in the last chunk that occur after the last match. + search->has_matches = false; + if (RB_UNLIKELY(search->chunk_base + sizeof(__m128i) >= search->end)) { + search->ptr = search->end; + } else { + search->ptr = search->chunk_base + sizeof(__m128i); + } + } + } + + while (search->ptr + sizeof(__m128i) <= search->end) { + int needs_escape_mask = sse2_update(search->ptr); + + if (needs_escape_mask == 0) { + search->ptr += sizeof(__m128i); + continue; + } + + search->has_matches = true; + search->matches_mask = needs_escape_mask; + search->chunk_base = search->ptr; + return sse2_next_match(search); + } + + // There are fewer than 16 bytes left. + unsigned long remaining = (search->end - search->ptr); + if (remaining >= SIMD_MINIMUM_THRESHOLD) { + char *s = copy_remaining_bytes(search, sizeof(__m128i), remaining); + + int needs_escape_mask = sse2_update(s); + + if (needs_escape_mask == 0) { + // Nothing to escape, ensure search_flush doesn't do anything by setting + // search->cursor to search->ptr. + fbuffer_consumed(search->buffer, remaining); + search->ptr = search->end; + search->cursor = search->end; + return 0; + } + + search->has_matches = true; + search->matches_mask = needs_escape_mask; + search->chunk_base = search->ptr; + return sse2_next_match(search); + } + + if (search->ptr < search->end) { + return search_escape_basic(search); + } + + search_flush(search); + return 0; +} + +#endif /* HAVE_SIMD_SSE2 */ + +#endif /* HAVE_SIMD */ + +static const unsigned char script_safe_escape_table[256] = { + // ASCII Control Characters + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + // ASCII Characters + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, // '"' and '/' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, // '\\' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // Continuation byte + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + // First byte of a 2-byte code point + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + // First byte of a 3-byte code point + 3, 3,11, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xE2 is the start of \u2028 and \u2029 + //First byte of a 4+ byte code point + 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 9, 9, +}; + +static inline unsigned char search_script_safe_escape(search_state *search) +{ + while (search->ptr < search->end) { + unsigned char ch = (unsigned char)*search->ptr; + unsigned char ch_len = script_safe_escape_table[ch]; + + if (RB_UNLIKELY(ch_len)) { + if (ch_len & ESCAPE_MASK) { + if (RB_UNLIKELY(ch_len == 11)) { + const unsigned char *uptr = (const unsigned char *)search->ptr; + if (!(uptr[1] == 0x80 && (uptr[2] >> 1) == 0x54)) { + search->ptr += 3; + continue; + } + } + search_flush(search); + return ch_len & CHAR_LENGTH_MASK; + } else { + search->ptr += ch_len; + } + } else { + search->ptr++; + } + } + search_flush(search); + return 0; +} + +static void convert_UTF8_to_script_safe_JSON(search_state *search) +{ + unsigned char ch_len; + while ((ch_len = search_script_safe_escape(search))) { + escape_UTF8_char(search, ch_len); + } +} + +static const unsigned char ascii_only_escape_table[256] = { + // ASCII Control Characters + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + // ASCII Characters + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // '"' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, // '\\' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + // Continuation byte + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + // First byte of a 2-byte code point + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + // First byte of a 3-byte code point + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + //First byte of a 4+ byte code point + 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 9, 9, +}; + +static inline unsigned char search_ascii_only_escape(search_state *search, const unsigned char escape_table[256]) +{ + while (search->ptr < search->end) { + unsigned char ch = (unsigned char)*search->ptr; + unsigned char ch_len = escape_table[ch]; + + if (RB_UNLIKELY(ch_len)) { + search_flush(search); + return ch_len & CHAR_LENGTH_MASK; + } else { + search->ptr++; + } + } + search_flush(search); + return 0; +} + +static inline void full_escape_UTF8_char(search_state *search, unsigned char ch_len) { + const unsigned char ch = (unsigned char)*search->ptr; + switch (ch_len) { + case 1: { + switch (ch) { + case '"': fbuffer_append(search->buffer, "\\\"", 2); break; + case '\\': fbuffer_append(search->buffer, "\\\\", 2); break; + case '/': fbuffer_append(search->buffer, "\\/", 2); break; + case '\b': fbuffer_append(search->buffer, "\\b", 2); break; + case '\f': fbuffer_append(search->buffer, "\\f", 2); break; + case '\n': fbuffer_append(search->buffer, "\\n", 2); break; + case '\r': fbuffer_append(search->buffer, "\\r", 2); break; + case '\t': fbuffer_append(search->buffer, "\\t", 2); break; + default: { + const char *hexdig = "0123456789abcdef"; + char scratch[6] = { '\\', 'u', '0', '0', 0, 0 }; + scratch[4] = hexdig[(ch >> 4) & 0xf]; + scratch[5] = hexdig[ch & 0xf]; + fbuffer_append(search->buffer, scratch, 6); + break; + } + } + break; + } + default: { + const char *hexdig = "0123456789abcdef"; + char scratch[12] = { '\\', 'u', 0, 0, 0, 0, '\\', 'u' }; + + uint32_t wchar = 0; + + switch(ch_len) { + case 2: + wchar = ch & 0x1F; + break; + case 3: + wchar = ch & 0x0F; + break; + case 4: + wchar = ch & 0x07; + break; + } + + for (short i = 1; i < ch_len; i++) { + wchar = (wchar << 6) | (search->ptr[i] & 0x3F); + } + + if (wchar <= 0xFFFF) { + scratch[2] = hexdig[wchar >> 12]; + scratch[3] = hexdig[(wchar >> 8) & 0xf]; + scratch[4] = hexdig[(wchar >> 4) & 0xf]; + scratch[5] = hexdig[wchar & 0xf]; + fbuffer_append(search->buffer, scratch, 6); + } else { + uint16_t hi, lo; + wchar -= 0x10000; + hi = 0xD800 + (uint16_t)(wchar >> 10); + lo = 0xDC00 + (uint16_t)(wchar & 0x3FF); + + scratch[2] = hexdig[hi >> 12]; + scratch[3] = hexdig[(hi >> 8) & 0xf]; + scratch[4] = hexdig[(hi >> 4) & 0xf]; + scratch[5] = hexdig[hi & 0xf]; + + scratch[8] = hexdig[lo >> 12]; + scratch[9] = hexdig[(lo >> 8) & 0xf]; + scratch[10] = hexdig[(lo >> 4) & 0xf]; + scratch[11] = hexdig[lo & 0xf]; + + fbuffer_append(search->buffer, scratch, 12); + } + + break; + } + } + search->cursor = (search->ptr += ch_len); +} + +static void convert_UTF8_to_ASCII_only_JSON(search_state *search, const unsigned char escape_table[256]) +{ + unsigned char ch_len; + while ((ch_len = search_ascii_only_escape(search, escape_table))) { + full_escape_UTF8_char(search, ch_len); + } +} + +/* + * Document-module: JSON::Ext::Generator + * + * This is the JSON generator implemented as a C extension. It can be + * configured to be used by setting + * + * JSON.generator = JSON::Ext::Generator + * + * with the method generator= in JSON. + * + */ + +/* Explanation of the following: that's the only way to not pollute + * standard library's docs with GeneratorMethods:: which + * are uninformative and take a large place in a list of classes + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods + * :nodoc: + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods::Array + * :nodoc: + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods::Bignum + * :nodoc: + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods::FalseClass + * :nodoc: + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods::Fixnum + * :nodoc: + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods::Float + * :nodoc: + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods::Hash + * :nodoc: + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods::Integer + * :nodoc: + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods::NilClass + * :nodoc: + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods::Object + * :nodoc: + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods::String + * :nodoc: + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods::String::Extend + * :nodoc: + */ + +/* + * Document-module: JSON::Ext::Generator::GeneratorMethods::TrueClass + * :nodoc: + */ + +/* + * call-seq: to_json(state = nil) + * + * Returns a JSON string containing a JSON object, that is generated from + * this Hash instance. + * _state_ is a JSON::State object, that can also be used to configure the + * produced JSON string output further. + */ +static VALUE mHash_to_json(int argc, VALUE *argv, VALUE self) +{ + rb_check_arity(argc, 0, 1); + VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil); + return cState_partial_generate(Vstate, self, generate_json_object, Qfalse); +} + +/* + * call-seq: to_json(state = nil) + * + * Returns a JSON string containing a JSON array, that is generated from + * this Array instance. + * _state_ is a JSON::State object, that can also be used to configure the + * produced JSON string output further. + */ +static VALUE mArray_to_json(int argc, VALUE *argv, VALUE self) { + rb_check_arity(argc, 0, 1); + VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil); + return cState_partial_generate(Vstate, self, generate_json_array, Qfalse); +} + +#ifdef RUBY_INTEGER_UNIFICATION +/* + * call-seq: to_json(*) + * + * Returns a JSON string representation for this Integer number. + */ +static VALUE mInteger_to_json(int argc, VALUE *argv, VALUE self) +{ + rb_check_arity(argc, 0, 1); + VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil); + return cState_partial_generate(Vstate, self, generate_json_integer, Qfalse); +} + +#else +/* + * call-seq: to_json(*) + * + * Returns a JSON string representation for this Integer number. + */ +static VALUE mFixnum_to_json(int argc, VALUE *argv, VALUE self) +{ + rb_check_arity(argc, 0, 1); + VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil); + return cState_partial_generate(Vstate, self, generate_json_fixnum, Qfalse); +} + +/* + * call-seq: to_json(*) + * + * Returns a JSON string representation for this Integer number. + */ +static VALUE mBignum_to_json(int argc, VALUE *argv, VALUE self) +{ + rb_check_arity(argc, 0, 1); + VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil); + return cState_partial_generate(Vstate, self, generate_json_bignum, Qfalse); +} +#endif + +/* + * call-seq: to_json(*) + * + * Returns a JSON string representation for this Float number. + */ +static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self) +{ + rb_check_arity(argc, 0, 1); + VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil); + return cState_partial_generate(Vstate, self, generate_json_float, Qfalse); +} + +/* + * call-seq: String.included(modul) + * + * Extends _modul_ with the String::Extend module. + */ +static VALUE mString_included_s(VALUE self, VALUE modul) { + VALUE result = rb_funcall(modul, i_extend, 1, mString_Extend); + rb_call_super(1, &modul); + return result; +} + +/* + * call-seq: to_json(*) + * + * This string should be encoded with UTF-8 A call to this method + * returns a JSON string encoded with UTF16 big endian characters as + * \u????. + */ +static VALUE mString_to_json(int argc, VALUE *argv, VALUE self) +{ + rb_check_arity(argc, 0, 1); + VALUE Vstate = cState_from_state_s(cState, argc == 1 ? argv[0] : Qnil); + return cState_partial_generate(Vstate, self, generate_json_string, Qfalse); +} + +/* + * call-seq: to_json_raw_object() + * + * This method creates a raw object hash, that can be nested into + * other data structures and will be generated as a raw string. This + * method should be used, if you want to convert raw strings to JSON + * instead of UTF-8 strings, e. g. binary data. + */ +static VALUE mString_to_json_raw_object(VALUE self) +{ + VALUE ary; + VALUE result = rb_hash_new(); + rb_hash_aset(result, rb_funcall(mJSON, i_create_id, 0), rb_class_name(rb_obj_class(self))); + ary = rb_funcall(self, i_unpack, 1, rb_str_new2("C*")); + rb_hash_aset(result, rb_utf8_str_new_lit("raw"), ary); + return result; +} + +/* + * call-seq: to_json_raw(*args) + * + * This method creates a JSON text from the result of a call to + * to_json_raw_object of this String. + */ +static VALUE mString_to_json_raw(int argc, VALUE *argv, VALUE self) +{ + VALUE obj = mString_to_json_raw_object(self); + Check_Type(obj, T_HASH); + return mHash_to_json(argc, argv, obj); +} + +/* + * call-seq: json_create(o) + * + * Raw Strings are JSON Objects (the raw bytes are stored in an array for the + * key "raw"). The Ruby String can be created by this module method. + */ +static VALUE mString_Extend_json_create(VALUE self, VALUE o) +{ + VALUE ary; + Check_Type(o, T_HASH); + ary = rb_hash_aref(o, rb_str_new2("raw")); + return rb_funcall(ary, i_pack, 1, rb_str_new2("C*")); +} + +/* + * call-seq: to_json(*) + * + * Returns a JSON string for true: 'true'. + */ +static VALUE mTrueClass_to_json(int argc, VALUE *argv, VALUE self) +{ + rb_check_arity(argc, 0, 1); + return rb_utf8_str_new("true", 4); +} + +/* + * call-seq: to_json(*) + * + * Returns a JSON string for false: 'false'. + */ +static VALUE mFalseClass_to_json(int argc, VALUE *argv, VALUE self) +{ + rb_check_arity(argc, 0, 1); + return rb_utf8_str_new("false", 5); +} + +/* + * call-seq: to_json(*) + * + * Returns a JSON string for nil: 'null'. + */ +static VALUE mNilClass_to_json(int argc, VALUE *argv, VALUE self) +{ + rb_check_arity(argc, 0, 1); + return rb_utf8_str_new("null", 4); +} + +/* + * call-seq: to_json(*) + * + * Converts this object to a string (calling #to_s), converts + * it to a JSON string, and returns the result. This is a fallback, if no + * special method #to_json was defined for some object. + */ +static VALUE mObject_to_json(int argc, VALUE *argv, VALUE self) +{ + VALUE state; + VALUE string = rb_funcall(self, i_to_s, 0); + rb_scan_args(argc, argv, "01", &state); + Check_Type(string, T_STRING); + state = cState_from_state_s(cState, state); + return cState_partial_generate(state, string, generate_json_string, Qfalse); +} + +static void State_mark(void *ptr) +{ + JSON_Generator_State *state = ptr; + rb_gc_mark_movable(state->indent); + rb_gc_mark_movable(state->space); + rb_gc_mark_movable(state->space_before); + rb_gc_mark_movable(state->object_nl); + rb_gc_mark_movable(state->array_nl); + rb_gc_mark_movable(state->as_json); +} + +static void State_compact(void *ptr) +{ + JSON_Generator_State *state = ptr; + state->indent = rb_gc_location(state->indent); + state->space = rb_gc_location(state->space); + state->space_before = rb_gc_location(state->space_before); + state->object_nl = rb_gc_location(state->object_nl); + state->array_nl = rb_gc_location(state->array_nl); + state->as_json = rb_gc_location(state->as_json); +} + +static void State_free(void *ptr) +{ + JSON_Generator_State *state = ptr; + ruby_xfree(state); +} + +static size_t State_memsize(const void *ptr) +{ + return sizeof(JSON_Generator_State); +} + +#ifndef HAVE_RB_EXT_RACTOR_SAFE +# undef RUBY_TYPED_FROZEN_SHAREABLE +# define RUBY_TYPED_FROZEN_SHAREABLE 0 +#endif + +static const rb_data_type_t JSON_Generator_State_type = { + "JSON/Generator/State", + { + .dmark = State_mark, + .dfree = State_free, + .dsize = State_memsize, + .dcompact = State_compact, + }, + 0, 0, + RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE, +}; + +static void state_init(JSON_Generator_State *state) +{ + state->max_nesting = 100; + state->buffer_initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT; +} + +static VALUE cState_s_allocate(VALUE klass) +{ + JSON_Generator_State *state; + VALUE obj = TypedData_Make_Struct(klass, JSON_Generator_State, &JSON_Generator_State_type, state); + state_init(state); + return obj; +} + +static void vstate_spill(struct generate_json_data *data) +{ + VALUE vstate = cState_s_allocate(cState); + GET_STATE(vstate); + MEMCPY(state, data->state, JSON_Generator_State, 1); + data->state = state; + data->vstate = vstate; + RB_OBJ_WRITTEN(vstate, Qundef, state->indent); + RB_OBJ_WRITTEN(vstate, Qundef, state->space); + RB_OBJ_WRITTEN(vstate, Qundef, state->space_before); + RB_OBJ_WRITTEN(vstate, Qundef, state->object_nl); + RB_OBJ_WRITTEN(vstate, Qundef, state->array_nl); + RB_OBJ_WRITTEN(vstate, Qundef, state->as_json); +} + +static inline VALUE vstate_get(struct generate_json_data *data) +{ + if (RB_UNLIKELY(!data->vstate)) { + vstate_spill(data); + } + return data->vstate; +} + +struct hash_foreach_arg { + struct generate_json_data *data; + int iter; +}; + +static VALUE +convert_string_subclass(VALUE key) +{ + VALUE key_to_s = rb_funcall(key, i_to_s, 0); + + if (RB_UNLIKELY(!RB_TYPE_P(key_to_s, T_STRING))) { + VALUE cname = rb_obj_class(key); + rb_raise(rb_eTypeError, + "can't convert %"PRIsVALUE" to %s (%"PRIsVALUE"#%s gives %"PRIsVALUE")", + cname, "String", cname, "to_s", rb_obj_class(key_to_s)); + } + + return key_to_s; +} + +static int +json_object_i(VALUE key, VALUE val, VALUE _arg) +{ + struct hash_foreach_arg *arg = (struct hash_foreach_arg *)_arg; + struct generate_json_data *data = arg->data; + + FBuffer *buffer = data->buffer; + JSON_Generator_State *state = data->state; + + long depth = state->depth; + int j; + + if (arg->iter > 0) fbuffer_append_char(buffer, ','); + if (RB_UNLIKELY(data->state->object_nl)) { + fbuffer_append_str(buffer, data->state->object_nl); + } + if (RB_UNLIKELY(data->state->indent)) { + for (j = 0; j < depth; j++) { + fbuffer_append_str(buffer, data->state->indent); + } + } + + VALUE key_to_s; + switch(rb_type(key)) { + case T_STRING: + if (RB_LIKELY(RBASIC_CLASS(key) == rb_cString)) { + key_to_s = key; + } else { + key_to_s = convert_string_subclass(key); + } + break; + case T_SYMBOL: + key_to_s = rb_sym2str(key); + break; + default: + key_to_s = rb_convert_type(key, T_STRING, "String", "to_s"); + break; + } + + if (RB_LIKELY(RBASIC_CLASS(key_to_s) == rb_cString)) { + generate_json_string(buffer, data, key_to_s); + } else { + generate_json(buffer, data, key_to_s); + } + if (RB_UNLIKELY(state->space_before)) fbuffer_append_str(buffer, data->state->space_before); + fbuffer_append_char(buffer, ':'); + if (RB_UNLIKELY(state->space)) fbuffer_append_str(buffer, data->state->space); + generate_json(buffer, data, val); + + arg->iter++; + return ST_CONTINUE; +} + +static inline long increase_depth(struct generate_json_data *data) +{ + JSON_Generator_State *state = data->state; + long depth = ++state->depth; + if (RB_UNLIKELY(depth > state->max_nesting && state->max_nesting)) { + rb_raise(eNestingError, "nesting of %ld is too deep", --state->depth); + } + return depth; +} + +static void generate_json_object(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + int j; + long depth = increase_depth(data); + + if (RHASH_SIZE(obj) == 0) { + fbuffer_append(buffer, "{}", 2); + --data->state->depth; + return; + } + + fbuffer_append_char(buffer, '{'); + + struct hash_foreach_arg arg = { + .data = data, + .iter = 0, + }; + rb_hash_foreach(obj, json_object_i, (VALUE)&arg); + + depth = --data->state->depth; + if (RB_UNLIKELY(data->state->object_nl)) { + fbuffer_append_str(buffer, data->state->object_nl); + if (RB_UNLIKELY(data->state->indent)) { + for (j = 0; j < depth; j++) { + fbuffer_append_str(buffer, data->state->indent); + } + } + } + fbuffer_append_char(buffer, '}'); +} + +static void generate_json_array(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + int i, j; + long depth = increase_depth(data); + + if (RARRAY_LEN(obj) == 0) { + fbuffer_append(buffer, "[]", 2); + --data->state->depth; + return; + } + + fbuffer_append_char(buffer, '['); + if (RB_UNLIKELY(data->state->array_nl)) fbuffer_append_str(buffer, data->state->array_nl); + for(i = 0; i < RARRAY_LEN(obj); i++) { + if (i > 0) { + fbuffer_append_char(buffer, ','); + if (RB_UNLIKELY(data->state->array_nl)) fbuffer_append_str(buffer, data->state->array_nl); + } + if (RB_UNLIKELY(data->state->indent)) { + for (j = 0; j < depth; j++) { + fbuffer_append_str(buffer, data->state->indent); + } + } + generate_json(buffer, data, RARRAY_AREF(obj, i)); + } + data->state->depth = --depth; + if (RB_UNLIKELY(data->state->array_nl)) { + fbuffer_append_str(buffer, data->state->array_nl); + if (RB_UNLIKELY(data->state->indent)) { + for (j = 0; j < depth; j++) { + fbuffer_append_str(buffer, data->state->indent); + } + } + } + fbuffer_append_char(buffer, ']'); +} + +static inline int enc_utf8_compatible_p(int enc_idx) +{ + if (enc_idx == usascii_encindex) return 1; + if (enc_idx == utf8_encindex) return 1; + return 0; +} + +static VALUE encode_json_string_try(VALUE str) +{ + return rb_funcall(str, i_encode, 1, Encoding_UTF_8); +} + +static VALUE encode_json_string_rescue(VALUE str, VALUE exception) +{ + raise_generator_error_str(str, rb_funcall(exception, rb_intern("message"), 0)); + return Qundef; +} + +static inline VALUE ensure_valid_encoding(VALUE str) +{ + int encindex = RB_ENCODING_GET(str); + VALUE utf8_string; + if (RB_UNLIKELY(!enc_utf8_compatible_p(encindex))) { + if (encindex == binary_encindex) { + utf8_string = rb_enc_associate_index(rb_str_dup(str), utf8_encindex); + switch (rb_enc_str_coderange(utf8_string)) { + case ENC_CODERANGE_7BIT: + return utf8_string; + case ENC_CODERANGE_VALID: + // For historical reason, we silently reinterpret binary strings as UTF-8 if it would work. + // TODO: Raise in 3.0.0 + rb_warn("JSON.generate: UTF-8 string passed as BINARY, this will raise an encoding error in json 3.0"); + return utf8_string; + break; + } + } + + str = rb_rescue(encode_json_string_try, str, encode_json_string_rescue, str); + } + return str; +} + +static void generate_json_string(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + obj = ensure_valid_encoding(obj); + + fbuffer_append_char(buffer, '"'); + + long len; + search_state search; + search.buffer = buffer; + RSTRING_GETMEM(obj, search.ptr, len); + search.cursor = search.ptr; + search.end = search.ptr + len; + +#ifdef HAVE_SIMD + search.matches_mask = 0; + search.has_matches = false; + search.chunk_base = NULL; +#endif /* HAVE_SIMD */ + + switch(rb_enc_str_coderange(obj)) { + case ENC_CODERANGE_7BIT: + case ENC_CODERANGE_VALID: + if (RB_UNLIKELY(data->state->ascii_only)) { + convert_UTF8_to_ASCII_only_JSON(&search, data->state->script_safe ? script_safe_escape_table : ascii_only_escape_table); + } else if (RB_UNLIKELY(data->state->script_safe)) { + convert_UTF8_to_script_safe_JSON(&search); + } else { + convert_UTF8_to_JSON(&search); + } + break; + default: + raise_generator_error(obj, "source sequence is illegal/malformed utf-8"); + break; + } + fbuffer_append_char(buffer, '"'); +} + +static void generate_json_fallback(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + VALUE tmp; + if (rb_respond_to(obj, i_to_json)) { + tmp = rb_funcall(obj, i_to_json, 1, vstate_get(data)); + Check_Type(tmp, T_STRING); + fbuffer_append_str(buffer, tmp); + } else { + tmp = rb_funcall(obj, i_to_s, 0); + Check_Type(tmp, T_STRING); + generate_json_string(buffer, data, tmp); + } +} + +static inline void generate_json_symbol(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + if (data->state->strict) { + generate_json_string(buffer, data, rb_sym2str(obj)); + } else { + generate_json_fallback(buffer, data, obj); + } +} + +static void generate_json_null(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + fbuffer_append(buffer, "null", 4); +} + +static void generate_json_false(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + fbuffer_append(buffer, "false", 5); +} + +static void generate_json_true(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + fbuffer_append(buffer, "true", 4); +} + +static void generate_json_fixnum(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + fbuffer_append_long(buffer, FIX2LONG(obj)); +} + +static void generate_json_bignum(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + VALUE tmp = rb_funcall(obj, i_to_s, 0); + fbuffer_append_str(buffer, tmp); +} + +#ifdef RUBY_INTEGER_UNIFICATION +static void generate_json_integer(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + if (FIXNUM_P(obj)) + generate_json_fixnum(buffer, data, obj); + else + generate_json_bignum(buffer, data, obj); +} +#endif + +static void generate_json_float(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + double value = RFLOAT_VALUE(obj); + char allow_nan = data->state->allow_nan; + if (isinf(value) || isnan(value)) { + /* for NaN and Infinity values we either raise an error or rely on Float#to_s. */ + if (!allow_nan) { + if (data->state->strict && data->state->as_json) { + VALUE casted_obj = rb_proc_call_with_block(data->state->as_json, 1, &obj, Qnil); + if (casted_obj != obj) { + increase_depth(data); + generate_json(buffer, data, casted_obj); + data->state->depth--; + return; + } + } + raise_generator_error(obj, "%"PRIsVALUE" not allowed in JSON", rb_funcall(obj, i_to_s, 0)); + } + + VALUE tmp = rb_funcall(obj, i_to_s, 0); + fbuffer_append_str(buffer, tmp); + return; + } + + /* This implementation writes directly into the buffer. We reserve + * the 28 characters that fpconv_dtoa states as its maximum. + */ + fbuffer_inc_capa(buffer, 28); + char* d = buffer->ptr + buffer->len; + int len = fpconv_dtoa(value, d); + + /* fpconv_dtoa converts a float to its shortest string representation, + * but it adds a ".0" if this is a plain integer. + */ + fbuffer_consumed(buffer, len); +} + +static void generate_json_fragment(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + VALUE fragment = RSTRUCT_GET(obj, 0); + Check_Type(fragment, T_STRING); + fbuffer_append_str(buffer, fragment); +} + +static void generate_json(FBuffer *buffer, struct generate_json_data *data, VALUE obj) +{ + bool as_json_called = false; +start: + if (obj == Qnil) { + generate_json_null(buffer, data, obj); + } else if (obj == Qfalse) { + generate_json_false(buffer, data, obj); + } else if (obj == Qtrue) { + generate_json_true(buffer, data, obj); + } else if (RB_SPECIAL_CONST_P(obj)) { + if (RB_FIXNUM_P(obj)) { + generate_json_fixnum(buffer, data, obj); + } else if (RB_FLONUM_P(obj)) { + generate_json_float(buffer, data, obj); + } else if (RB_STATIC_SYM_P(obj)) { + generate_json_symbol(buffer, data, obj); + } else { + goto general; + } + } else { + VALUE klass = RBASIC_CLASS(obj); + switch (RB_BUILTIN_TYPE(obj)) { + case T_BIGNUM: + generate_json_bignum(buffer, data, obj); + break; + case T_HASH: + if (klass != rb_cHash) goto general; + generate_json_object(buffer, data, obj); + break; + case T_ARRAY: + if (klass != rb_cArray) goto general; + generate_json_array(buffer, data, obj); + break; + case T_STRING: + if (klass != rb_cString) goto general; + generate_json_string(buffer, data, obj); + break; + case T_SYMBOL: + generate_json_symbol(buffer, data, obj); + break; + case T_FLOAT: + if (klass != rb_cFloat) goto general; + generate_json_float(buffer, data, obj); + break; + case T_STRUCT: + if (klass != cFragment) goto general; + generate_json_fragment(buffer, data, obj); + break; + default: + general: + if (data->state->strict) { + if (RTEST(data->state->as_json) && !as_json_called) { + obj = rb_proc_call_with_block(data->state->as_json, 1, &obj, Qnil); + as_json_called = true; + goto start; + } else { + raise_generator_error(obj, "%"PRIsVALUE" not allowed in JSON", CLASS_OF(obj)); + } + } else { + generate_json_fallback(buffer, data, obj); + } + } + } +} + +static VALUE generate_json_try(VALUE d) +{ + struct generate_json_data *data = (struct generate_json_data *)d; + + data->func(data->buffer, data, data->obj); + + return Qnil; +} + +static VALUE generate_json_rescue(VALUE d, VALUE exc) +{ + struct generate_json_data *data = (struct generate_json_data *)d; + fbuffer_free(data->buffer); + + rb_exc_raise(exc); + + return Qundef; +} + +static VALUE cState_partial_generate(VALUE self, VALUE obj, generator_func func, VALUE io) +{ + GET_STATE(self); + + char stack_buffer[FBUFFER_STACK_SIZE]; + FBuffer buffer = { + .io = RTEST(io) ? io : Qfalse, + }; + fbuffer_stack_init(&buffer, state->buffer_initial_length, stack_buffer, FBUFFER_STACK_SIZE); + + struct generate_json_data data = { + .buffer = &buffer, + .vstate = self, + .state = state, + .obj = obj, + .func = func + }; + rb_rescue(generate_json_try, (VALUE)&data, generate_json_rescue, (VALUE)&data); + + return fbuffer_finalize(&buffer); +} + +/* call-seq: + * generate(obj) -> String + * generate(obj, anIO) -> anIO + * + * Generates a valid JSON document from object +obj+ and returns the + * result. If no valid JSON document can be created this method raises a + * GeneratorError exception. + */ +static VALUE cState_generate(int argc, VALUE *argv, VALUE self) +{ + rb_check_arity(argc, 1, 2); + VALUE obj = argv[0]; + VALUE io = argc > 1 ? argv[1] : Qnil; + VALUE result = cState_partial_generate(self, obj, generate_json, io); + GET_STATE(self); + (void)state; + return result; +} + +static VALUE cState_initialize(int argc, VALUE *argv, VALUE self) +{ + rb_warn("The json gem extension was loaded with the stdlib ruby code. You should upgrade rubygems with `gem update --system`"); + return self; +} + +/* + * call-seq: initialize_copy(orig) + * + * Initializes this object from orig if it can be duplicated/cloned and returns + * it. +*/ +static VALUE cState_init_copy(VALUE obj, VALUE orig) +{ + JSON_Generator_State *objState, *origState; + + if (obj == orig) return obj; + GET_STATE_TO(obj, objState); + GET_STATE_TO(orig, origState); + if (!objState) rb_raise(rb_eArgError, "unallocated JSON::State"); + + MEMCPY(objState, origState, JSON_Generator_State, 1); + objState->indent = origState->indent; + objState->space = origState->space; + objState->space_before = origState->space_before; + objState->object_nl = origState->object_nl; + objState->array_nl = origState->array_nl; + objState->as_json = origState->as_json; + return obj; +} + +/* + * call-seq: from_state(opts) + * + * Creates a State object from _opts_, which ought to be Hash to create a + * new State instance configured by _opts_, something else to create an + * unconfigured instance. If _opts_ is a State object, it is just returned. + */ +static VALUE cState_from_state_s(VALUE self, VALUE opts) +{ + if (rb_obj_is_kind_of(opts, self)) { + return opts; + } else if (rb_obj_is_kind_of(opts, rb_cHash)) { + return rb_funcall(self, i_new, 1, opts); + } else { + return rb_class_new_instance(0, NULL, cState); + } +} + +/* + * call-seq: indent() + * + * Returns the string that is used to indent levels in the JSON text. + */ +static VALUE cState_indent(VALUE self) +{ + GET_STATE(self); + return state->indent ? state->indent : rb_str_freeze(rb_utf8_str_new("", 0)); +} + +static VALUE string_config(VALUE config) +{ + if (RTEST(config)) { + Check_Type(config, T_STRING); + if (RSTRING_LEN(config)) { + return rb_str_new_frozen(config); + } + } + return Qfalse; +} + +/* + * call-seq: indent=(indent) + * + * Sets the string that is used to indent levels in the JSON text. + */ +static VALUE cState_indent_set(VALUE self, VALUE indent) +{ + GET_STATE(self); + RB_OBJ_WRITE(self, &state->indent, string_config(indent)); + return Qnil; +} + +/* + * call-seq: space() + * + * Returns the string that is used to insert a space between the tokens in a JSON + * string. + */ +static VALUE cState_space(VALUE self) +{ + GET_STATE(self); + return state->space ? state->space : rb_str_freeze(rb_utf8_str_new("", 0)); +} + +/* + * call-seq: space=(space) + * + * Sets _space_ to the string that is used to insert a space between the tokens in a JSON + * string. + */ +static VALUE cState_space_set(VALUE self, VALUE space) +{ + GET_STATE(self); + RB_OBJ_WRITE(self, &state->space, string_config(space)); + return Qnil; +} + +/* + * call-seq: space_before() + * + * Returns the string that is used to insert a space before the ':' in JSON objects. + */ +static VALUE cState_space_before(VALUE self) +{ + GET_STATE(self); + return state->space_before ? state->space_before : rb_str_freeze(rb_utf8_str_new("", 0)); +} + +/* + * call-seq: space_before=(space_before) + * + * Sets the string that is used to insert a space before the ':' in JSON objects. + */ +static VALUE cState_space_before_set(VALUE self, VALUE space_before) +{ + GET_STATE(self); + RB_OBJ_WRITE(self, &state->space_before, string_config(space_before)); + return Qnil; +} + +/* + * call-seq: object_nl() + * + * This string is put at the end of a line that holds a JSON object (or + * Hash). + */ +static VALUE cState_object_nl(VALUE self) +{ + GET_STATE(self); + return state->object_nl ? state->object_nl : rb_str_freeze(rb_utf8_str_new("", 0)); +} + +/* + * call-seq: object_nl=(object_nl) + * + * This string is put at the end of a line that holds a JSON object (or + * Hash). + */ +static VALUE cState_object_nl_set(VALUE self, VALUE object_nl) +{ + GET_STATE(self); + RB_OBJ_WRITE(self, &state->object_nl, string_config(object_nl)); + return Qnil; +} + +/* + * call-seq: array_nl() + * + * This string is put at the end of a line that holds a JSON array. + */ +static VALUE cState_array_nl(VALUE self) +{ + GET_STATE(self); + return state->array_nl ? state->array_nl : rb_str_freeze(rb_utf8_str_new("", 0)); +} + +/* + * call-seq: array_nl=(array_nl) + * + * This string is put at the end of a line that holds a JSON array. + */ +static VALUE cState_array_nl_set(VALUE self, VALUE array_nl) +{ + GET_STATE(self); + RB_OBJ_WRITE(self, &state->array_nl, string_config(array_nl)); + return Qnil; +} + +/* + * call-seq: as_json() + * + * This string is put at the end of a line that holds a JSON array. + */ +static VALUE cState_as_json(VALUE self) +{ + GET_STATE(self); + return state->as_json; +} + +/* + * call-seq: as_json=(as_json) + * + * This string is put at the end of a line that holds a JSON array. + */ +static VALUE cState_as_json_set(VALUE self, VALUE as_json) +{ + GET_STATE(self); + RB_OBJ_WRITE(self, &state->as_json, rb_convert_type(as_json, T_DATA, "Proc", "to_proc")); + return Qnil; +} + +/* +* call-seq: check_circular? +* +* Returns true, if circular data structures should be checked, +* otherwise returns false. +*/ +static VALUE cState_check_circular_p(VALUE self) +{ + GET_STATE(self); + return state->max_nesting ? Qtrue : Qfalse; +} + +/* + * call-seq: max_nesting + * + * This integer returns the maximum level of data structure nesting in + * the generated JSON, max_nesting = 0 if no maximum is checked. + */ +static VALUE cState_max_nesting(VALUE self) +{ + GET_STATE(self); + return LONG2FIX(state->max_nesting); +} + +static long long_config(VALUE num) +{ + return RTEST(num) ? FIX2LONG(num) : 0; +} + +/* + * call-seq: max_nesting=(depth) + * + * This sets the maximum level of data structure nesting in the generated JSON + * to the integer depth, max_nesting = 0 if no maximum should be checked. + */ +static VALUE cState_max_nesting_set(VALUE self, VALUE depth) +{ + GET_STATE(self); + state->max_nesting = long_config(depth); + return Qnil; +} + +/* + * call-seq: script_safe + * + * If this boolean is true, the forward slashes will be escaped in + * the json output. + */ +static VALUE cState_script_safe(VALUE self) +{ + GET_STATE(self); + return state->script_safe ? Qtrue : Qfalse; +} + +/* + * call-seq: script_safe=(enable) + * + * This sets whether or not the forward slashes will be escaped in + * the json output. + */ +static VALUE cState_script_safe_set(VALUE self, VALUE enable) +{ + GET_STATE(self); + state->script_safe = RTEST(enable); + return Qnil; +} + +/* + * call-seq: strict + * + * If this boolean is false, types unsupported by the JSON format will + * be serialized as strings. + * If this boolean is true, types unsupported by the JSON format will + * raise a JSON::GeneratorError. + */ +static VALUE cState_strict(VALUE self) +{ + GET_STATE(self); + return state->strict ? Qtrue : Qfalse; +} + +/* + * call-seq: strict=(enable) + * + * This sets whether or not to serialize types unsupported by the + * JSON format as strings. + * If this boolean is false, types unsupported by the JSON format will + * be serialized as strings. + * If this boolean is true, types unsupported by the JSON format will + * raise a JSON::GeneratorError. + */ +static VALUE cState_strict_set(VALUE self, VALUE enable) +{ + GET_STATE(self); + state->strict = RTEST(enable); + return Qnil; +} + +/* + * call-seq: allow_nan? + * + * Returns true, if NaN, Infinity, and -Infinity should be generated, otherwise + * returns false. + */ +static VALUE cState_allow_nan_p(VALUE self) +{ + GET_STATE(self); + return state->allow_nan ? Qtrue : Qfalse; +} + +/* + * call-seq: allow_nan=(enable) + * + * This sets whether or not to serialize NaN, Infinity, and -Infinity + */ +static VALUE cState_allow_nan_set(VALUE self, VALUE enable) +{ + GET_STATE(self); + state->allow_nan = RTEST(enable); + return Qnil; +} + +/* + * call-seq: ascii_only? + * + * Returns true, if only ASCII characters should be generated. Otherwise + * returns false. + */ +static VALUE cState_ascii_only_p(VALUE self) +{ + GET_STATE(self); + return state->ascii_only ? Qtrue : Qfalse; +} + +/* + * call-seq: ascii_only=(enable) + * + * This sets whether only ASCII characters should be generated. + */ +static VALUE cState_ascii_only_set(VALUE self, VALUE enable) +{ + GET_STATE(self); + state->ascii_only = RTEST(enable); + return Qnil; +} + +/* + * call-seq: depth + * + * This integer returns the current depth of data structure nesting. + */ +static VALUE cState_depth(VALUE self) +{ + GET_STATE(self); + return LONG2FIX(state->depth); +} + +/* + * call-seq: depth=(depth) + * + * This sets the maximum level of data structure nesting in the generated JSON + * to the integer depth, max_nesting = 0 if no maximum should be checked. + */ +static VALUE cState_depth_set(VALUE self, VALUE depth) +{ + GET_STATE(self); + state->depth = long_config(depth); + return Qnil; +} + +/* + * call-seq: buffer_initial_length + * + * This integer returns the current initial length of the buffer. + */ +static VALUE cState_buffer_initial_length(VALUE self) +{ + GET_STATE(self); + return LONG2FIX(state->buffer_initial_length); +} + +static void buffer_initial_length_set(JSON_Generator_State *state, VALUE buffer_initial_length) +{ + Check_Type(buffer_initial_length, T_FIXNUM); + long initial_length = FIX2LONG(buffer_initial_length); + if (initial_length > 0) { + state->buffer_initial_length = initial_length; + } +} + +/* + * call-seq: buffer_initial_length=(length) + * + * This sets the initial length of the buffer to +length+, if +length+ > 0, + * otherwise its value isn't changed. + */ +static VALUE cState_buffer_initial_length_set(VALUE self, VALUE buffer_initial_length) +{ + GET_STATE(self); + buffer_initial_length_set(state, buffer_initial_length); + return Qnil; +} + +static int configure_state_i(VALUE key, VALUE val, VALUE _arg) +{ + JSON_Generator_State *state = (JSON_Generator_State *)_arg; + + if (key == sym_indent) { state->indent = string_config(val); } + else if (key == sym_space) { state->space = string_config(val); } + else if (key == sym_space_before) { state->space_before = string_config(val); } + else if (key == sym_object_nl) { state->object_nl = string_config(val); } + else if (key == sym_array_nl) { state->array_nl = string_config(val); } + else if (key == sym_max_nesting) { state->max_nesting = long_config(val); } + else if (key == sym_allow_nan) { state->allow_nan = RTEST(val); } + else if (key == sym_ascii_only) { state->ascii_only = RTEST(val); } + else if (key == sym_depth) { state->depth = long_config(val); } + else if (key == sym_buffer_initial_length) { buffer_initial_length_set(state, val); } + else if (key == sym_script_safe) { state->script_safe = RTEST(val); } + else if (key == sym_escape_slash) { state->script_safe = RTEST(val); } + else if (key == sym_strict) { state->strict = RTEST(val); } + else if (key == sym_as_json) { state->as_json = RTEST(val) ? rb_convert_type(val, T_DATA, "Proc", "to_proc") : Qfalse; } + return ST_CONTINUE; +} + +static void configure_state(JSON_Generator_State *state, VALUE config) +{ + if (!RTEST(config)) return; + + Check_Type(config, T_HASH); + + if (!RHASH_SIZE(config)) return; + + // We assume in most cases few keys are set so it's faster to go over + // the provided keys than to check all possible keys. + rb_hash_foreach(config, configure_state_i, (VALUE)state); +} + +static VALUE cState_configure(VALUE self, VALUE opts) +{ + GET_STATE(self); + configure_state(state, opts); + return self; +} + +static VALUE cState_m_generate(VALUE klass, VALUE obj, VALUE opts, VALUE io) +{ + JSON_Generator_State state = {0}; + state_init(&state); + configure_state(&state, opts); + + char stack_buffer[FBUFFER_STACK_SIZE]; + FBuffer buffer = { + .io = RTEST(io) ? io : Qfalse, + }; + fbuffer_stack_init(&buffer, state.buffer_initial_length, stack_buffer, FBUFFER_STACK_SIZE); + + struct generate_json_data data = { + .buffer = &buffer, + .vstate = Qfalse, + .state = &state, + .obj = obj, + .func = generate_json, + }; + rb_rescue(generate_json_try, (VALUE)&data, generate_json_rescue, (VALUE)&data); + + return fbuffer_finalize(&buffer); +} + +/* + * + */ +void Init_generator(void) +{ +#ifdef HAVE_RB_EXT_RACTOR_SAFE + rb_ext_ractor_safe(true); +#endif + +#undef rb_intern + rb_require("json/common"); + + mJSON = rb_define_module("JSON"); + + rb_global_variable(&cFragment); + cFragment = rb_const_get(mJSON, rb_intern("Fragment")); + + VALUE mExt = rb_define_module_under(mJSON, "Ext"); + VALUE mGenerator = rb_define_module_under(mExt, "Generator"); + + rb_global_variable(&eGeneratorError); + eGeneratorError = rb_path2class("JSON::GeneratorError"); + + rb_global_variable(&eNestingError); + eNestingError = rb_path2class("JSON::NestingError"); + + cState = rb_define_class_under(mGenerator, "State", rb_cObject); + rb_define_alloc_func(cState, cState_s_allocate); + rb_define_singleton_method(cState, "from_state", cState_from_state_s, 1); + rb_define_method(cState, "initialize", cState_initialize, -1); + rb_define_alias(cState, "initialize", "initialize"); // avoid method redefinition warnings + rb_define_private_method(cState, "_configure", cState_configure, 1); + + rb_define_method(cState, "initialize_copy", cState_init_copy, 1); + rb_define_method(cState, "indent", cState_indent, 0); + rb_define_method(cState, "indent=", cState_indent_set, 1); + rb_define_method(cState, "space", cState_space, 0); + rb_define_method(cState, "space=", cState_space_set, 1); + rb_define_method(cState, "space_before", cState_space_before, 0); + rb_define_method(cState, "space_before=", cState_space_before_set, 1); + rb_define_method(cState, "object_nl", cState_object_nl, 0); + rb_define_method(cState, "object_nl=", cState_object_nl_set, 1); + rb_define_method(cState, "array_nl", cState_array_nl, 0); + rb_define_method(cState, "array_nl=", cState_array_nl_set, 1); + rb_define_method(cState, "as_json", cState_as_json, 0); + rb_define_method(cState, "as_json=", cState_as_json_set, 1); + rb_define_method(cState, "max_nesting", cState_max_nesting, 0); + rb_define_method(cState, "max_nesting=", cState_max_nesting_set, 1); + rb_define_method(cState, "script_safe", cState_script_safe, 0); + rb_define_method(cState, "script_safe?", cState_script_safe, 0); + rb_define_method(cState, "script_safe=", cState_script_safe_set, 1); + rb_define_alias(cState, "escape_slash", "script_safe"); + rb_define_alias(cState, "escape_slash?", "script_safe?"); + rb_define_alias(cState, "escape_slash=", "script_safe="); + rb_define_method(cState, "strict", cState_strict, 0); + rb_define_method(cState, "strict?", cState_strict, 0); + rb_define_method(cState, "strict=", cState_strict_set, 1); + rb_define_method(cState, "check_circular?", cState_check_circular_p, 0); + rb_define_method(cState, "allow_nan?", cState_allow_nan_p, 0); + rb_define_method(cState, "allow_nan=", cState_allow_nan_set, 1); + rb_define_method(cState, "ascii_only?", cState_ascii_only_p, 0); + rb_define_method(cState, "ascii_only=", cState_ascii_only_set, 1); + rb_define_method(cState, "depth", cState_depth, 0); + rb_define_method(cState, "depth=", cState_depth_set, 1); + rb_define_method(cState, "buffer_initial_length", cState_buffer_initial_length, 0); + rb_define_method(cState, "buffer_initial_length=", cState_buffer_initial_length_set, 1); + rb_define_method(cState, "generate", cState_generate, -1); + rb_define_alias(cState, "generate_new", "generate"); // :nodoc: + + rb_define_singleton_method(cState, "generate", cState_m_generate, 3); + + VALUE mGeneratorMethods = rb_define_module_under(mGenerator, "GeneratorMethods"); + + VALUE mObject = rb_define_module_under(mGeneratorMethods, "Object"); + rb_define_method(mObject, "to_json", mObject_to_json, -1); + + VALUE mHash = rb_define_module_under(mGeneratorMethods, "Hash"); + rb_define_method(mHash, "to_json", mHash_to_json, -1); + + VALUE mArray = rb_define_module_under(mGeneratorMethods, "Array"); + rb_define_method(mArray, "to_json", mArray_to_json, -1); + +#ifdef RUBY_INTEGER_UNIFICATION + VALUE mInteger = rb_define_module_under(mGeneratorMethods, "Integer"); + rb_define_method(mInteger, "to_json", mInteger_to_json, -1); +#else + VALUE mFixnum = rb_define_module_under(mGeneratorMethods, "Fixnum"); + rb_define_method(mFixnum, "to_json", mFixnum_to_json, -1); + + VALUE mBignum = rb_define_module_under(mGeneratorMethods, "Bignum"); + rb_define_method(mBignum, "to_json", mBignum_to_json, -1); +#endif + VALUE mFloat = rb_define_module_under(mGeneratorMethods, "Float"); + rb_define_method(mFloat, "to_json", mFloat_to_json, -1); + + VALUE mString = rb_define_module_under(mGeneratorMethods, "String"); + rb_define_singleton_method(mString, "included", mString_included_s, 1); + rb_define_method(mString, "to_json", mString_to_json, -1); + rb_define_method(mString, "to_json_raw", mString_to_json_raw, -1); + rb_define_method(mString, "to_json_raw_object", mString_to_json_raw_object, 0); + + mString_Extend = rb_define_module_under(mString, "Extend"); + rb_define_method(mString_Extend, "json_create", mString_Extend_json_create, 1); + + VALUE mTrueClass = rb_define_module_under(mGeneratorMethods, "TrueClass"); + rb_define_method(mTrueClass, "to_json", mTrueClass_to_json, -1); + + VALUE mFalseClass = rb_define_module_under(mGeneratorMethods, "FalseClass"); + rb_define_method(mFalseClass, "to_json", mFalseClass_to_json, -1); + + VALUE mNilClass = rb_define_module_under(mGeneratorMethods, "NilClass"); + rb_define_method(mNilClass, "to_json", mNilClass_to_json, -1); + + rb_global_variable(&Encoding_UTF_8); + Encoding_UTF_8 = rb_const_get(rb_path2class("Encoding"), rb_intern("UTF_8")); + + i_to_s = rb_intern("to_s"); + i_to_json = rb_intern("to_json"); + i_new = rb_intern("new"); + i_pack = rb_intern("pack"); + i_unpack = rb_intern("unpack"); + i_create_id = rb_intern("create_id"); + i_extend = rb_intern("extend"); + i_encode = rb_intern("encode"); + + sym_indent = ID2SYM(rb_intern("indent")); + sym_space = ID2SYM(rb_intern("space")); + sym_space_before = ID2SYM(rb_intern("space_before")); + sym_object_nl = ID2SYM(rb_intern("object_nl")); + sym_array_nl = ID2SYM(rb_intern("array_nl")); + sym_max_nesting = ID2SYM(rb_intern("max_nesting")); + sym_allow_nan = ID2SYM(rb_intern("allow_nan")); + sym_ascii_only = ID2SYM(rb_intern("ascii_only")); + sym_depth = ID2SYM(rb_intern("depth")); + sym_buffer_initial_length = ID2SYM(rb_intern("buffer_initial_length")); + sym_script_safe = ID2SYM(rb_intern("script_safe")); + sym_escape_slash = ID2SYM(rb_intern("escape_slash")); + sym_strict = ID2SYM(rb_intern("strict")); + sym_as_json = ID2SYM(rb_intern("as_json")); + + usascii_encindex = rb_usascii_encindex(); + utf8_encindex = rb_utf8_encindex(); + binary_encindex = rb_ascii8bit_encindex(); + + rb_require("json/ext/generator/state"); + + + switch(find_simd_implementation()) { +#ifdef HAVE_SIMD +#ifdef HAVE_SIMD_NEON + case SIMD_NEON: + search_escape_basic_impl = search_escape_basic_neon; + break; +#endif /* HAVE_SIMD_NEON */ +#ifdef HAVE_SIMD_SSE2 + case SIMD_SSE2: + search_escape_basic_impl = search_escape_basic_sse2; + break; +#endif /* HAVE_SIMD_SSE2 */ +#endif /* HAVE_SIMD */ + default: + search_escape_basic_impl = search_escape_basic; + break; + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/generator/simd.h b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/generator/simd.h new file mode 100644 index 00000000..b12890cb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/generator/simd.h @@ -0,0 +1,112 @@ +typedef enum { + SIMD_NONE, + SIMD_NEON, + SIMD_SSE2 +} SIMD_Implementation; + +#ifdef JSON_ENABLE_SIMD + +#ifdef __clang__ + #if __has_builtin(__builtin_ctzll) + #define HAVE_BUILTIN_CTZLL 1 + #else + #define HAVE_BUILTIN_CTZLL 0 + #endif +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define HAVE_BUILTIN_CTZLL 1 +#else + #define HAVE_BUILTIN_CTZLL 0 +#endif + +static inline uint32_t trailing_zeros64(uint64_t input) { +#if HAVE_BUILTIN_CTZLL + return __builtin_ctzll(input); +#else + uint32_t trailing_zeros = 0; + uint64_t temp = input; + while ((temp & 1) == 0 && temp > 0) { + trailing_zeros++; + temp >>= 1; + } + return trailing_zeros; +#endif +} + +static inline int trailing_zeros(int input) { + #if HAVE_BUILTIN_CTZLL + return __builtin_ctz(input); + #else + int trailing_zeros = 0; + int temp = input; + while ((temp & 1) == 0 && temp > 0) { + trailing_zeros++; + temp >>= 1; + } + return trailing_zeros; + #endif +} + +#define SIMD_MINIMUM_THRESHOLD 6 + +#if defined(__ARM_NEON) || defined(__ARM_NEON__) || defined(__aarch64__) || defined(_M_ARM64) +#include + +#define FIND_SIMD_IMPLEMENTATION_DEFINED 1 +static SIMD_Implementation find_simd_implementation(void) { + return SIMD_NEON; +} + +#define HAVE_SIMD 1 +#define HAVE_SIMD_NEON 1 + +uint8x16x4_t load_uint8x16_4(const unsigned char *table) { + uint8x16x4_t tab; + tab.val[0] = vld1q_u8(table); + tab.val[1] = vld1q_u8(table+16); + tab.val[2] = vld1q_u8(table+32); + tab.val[3] = vld1q_u8(table+48); + return tab; +} + +#endif /* ARM Neon Support.*/ + +#if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64) + +#ifdef HAVE_X86INTRIN_H +#include + +#define HAVE_SIMD 1 +#define HAVE_SIMD_SSE2 1 + +#ifdef HAVE_CPUID_H +#define FIND_SIMD_IMPLEMENTATION_DEFINED 1 + +#include +#endif /* HAVE_CPUID_H */ + +static SIMD_Implementation find_simd_implementation(void) { + +#if defined(__GNUC__ ) || defined(__clang__) +#ifdef __GNUC__ + __builtin_cpu_init(); +#endif /* __GNUC__ */ + + // TODO Revisit. I think the SSE version now only uses SSE2 instructions. + if (__builtin_cpu_supports("sse2")) { + return SIMD_SSE2; + } +#endif /* __GNUC__ || __clang__*/ + + return SIMD_NONE; +} + +#endif /* HAVE_X86INTRIN_H */ +#endif /* X86_64 Support */ + +#endif /* JSON_ENABLE_SIMD */ + +#ifndef FIND_SIMD_IMPLEMENTATION_DEFINED +static SIMD_Implementation find_simd_implementation(void) { + return SIMD_NONE; +} +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/parser/Makefile b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/parser/Makefile new file mode 100644 index 00000000..4ca9edd3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/parser/Makefile @@ -0,0 +1,273 @@ + +SHELL = /bin/sh + +# V=0 quiet, V=1 verbose. other values don't work. +V = 0 +V0 = $(V:0=) +Q1 = $(V:1=) +Q = $(Q1:0=@) +ECHO1 = $(V:1=@ :) +ECHO = $(ECHO1:0=@ echo) +NULLCMD = : + +#### Start of system configuration section. #### + +srcdir = . +topdir = /opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 +hdrdir = $(topdir) +arch_hdrdir = /opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux +PATH_SEPARATOR = : +VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby +prefix = $(DESTDIR)/opt/hostedtoolcache/Ruby/3.4.4/x64 +rubysitearchprefix = $(rubylibprefix)/$(sitearch) +rubyarchprefix = $(rubylibprefix)/$(arch) +rubylibprefix = $(libdir)/$(RUBY_BASE_NAME) +exec_prefix = $(prefix) +vendorarchhdrdir = $(vendorhdrdir)/$(sitearch) +sitearchhdrdir = $(sitehdrdir)/$(sitearch) +rubyarchhdrdir = $(rubyhdrdir)/$(arch) +vendorhdrdir = $(rubyhdrdir)/vendor_ruby +sitehdrdir = $(rubyhdrdir)/site_ruby +rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME) +vendorarchdir = $(vendorlibdir)/$(sitearch) +vendorlibdir = $(vendordir)/$(ruby_version) +vendordir = $(rubylibprefix)/vendor_ruby +sitearchdir = $(sitelibdir)/$(sitearch) +sitelibdir = $(sitedir)/$(ruby_version) +sitedir = $(rubylibprefix)/site_ruby +rubyarchdir = $(rubylibdir)/$(arch) +rubylibdir = $(rubylibprefix)/$(ruby_version) +sitearchincludedir = $(includedir)/$(sitearch) +archincludedir = $(includedir)/$(arch) +sitearchlibdir = $(libdir)/$(sitearch) +archlibdir = $(libdir)/$(arch) +ridir = $(datarootdir)/$(RI_BASE_NAME) +modular_gc_dir = $(DESTDIR) +mandir = $(datarootdir)/man +localedir = $(datarootdir)/locale +libdir = $(exec_prefix)/lib +psdir = $(docdir) +pdfdir = $(docdir) +dvidir = $(docdir) +htmldir = $(docdir) +infodir = $(datarootdir)/info +docdir = $(datarootdir)/doc/$(PACKAGE) +oldincludedir = $(DESTDIR)/usr/include +includedir = $(prefix)/include +runstatedir = $(localstatedir)/run +localstatedir = $(prefix)/var +sharedstatedir = $(prefix)/com +sysconfdir = $(prefix)/etc +datadir = $(datarootdir) +datarootdir = $(prefix)/share +libexecdir = $(exec_prefix)/libexec +sbindir = $(exec_prefix)/sbin +bindir = $(exec_prefix)/bin +archdir = $(rubyarchdir) + + +CC_WRAPPER = +CC = gcc +CXX = g++ +LIBRUBY = $(LIBRUBY_SO) +LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a +LIBRUBYARG_SHARED = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME) +LIBRUBYARG_STATIC = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)-static $(MAINLIBS) +empty = +OUTFLAG = -o $(empty) +COUTFLAG = -o $(empty) +CSRCFLAG = $(empty) + +RUBY_EXTCONF_H = +cflags = $(hardenflags) $(optflags) $(debugflags) $(warnflags) +cxxflags = +optflags = -O3 -fno-fast-math +debugflags = -ggdb3 +warnflags = -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef +cppflags = +CCDLFLAGS = -fPIC +CFLAGS = $(CCDLFLAGS) $(cflags) -fPIC -std=c99 $(ARCH_FLAG) +INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) +DEFS = +CPPFLAGS = -DHAVE_RB_ENC_INTERNED_STR -DHAVE_RB_HASH_NEW_CAPA -DHAVE_RB_HASH_BULK_INSERT -DHAVE_STRNLEN -DENABLE_PATH_CHECK=0 $(DEFS) $(cppflags) +CXXFLAGS = $(CCDLFLAGS) $(ARCH_FLAG) +ldflags = -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed +dldflags = -Wl,--compress-debug-sections=zlib +ARCH_FLAG = +DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG) +LDSHARED = $(CC) -shared +LDSHAREDXX = $(CXX) -shared +POSTLINK = : +AR = gcc-ar +LD = ld +EXEEXT = + +RUBY_INSTALL_NAME = $(RUBY_BASE_NAME) +RUBY_SO_NAME = ruby +RUBYW_INSTALL_NAME = +RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version) +RUBYW_BASE_NAME = rubyw +RUBY_BASE_NAME = ruby + +arch = x86_64-linux +sitearch = $(arch) +ruby_version = 3.4.0 +ruby = $(bindir)/$(RUBY_BASE_NAME) +RUBY = $(ruby) +BUILTRUBY = $(bindir)/$(RUBY_BASE_NAME) +ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/backward.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h + +RM = rm -f +RM_RF = rm -fr +RMDIRS = rmdir --ignore-fail-on-non-empty -p +MAKEDIRS = /usr/bin/mkdir -p +INSTALL = /usr/bin/install -c +INSTALL_PROG = $(INSTALL) -m 0755 +INSTALL_DATA = $(INSTALL) -m 644 +COPY = cp +TOUCH = exit > + +#### End of system configuration section. #### + +preload = +libpath = . $(libdir) +LIBPATH = -L. -L$(libdir) -Wl,-rpath,$(libdir) +DEFFILE = + +CLEANFILES = mkmf.log +DISTCLEANFILES = +DISTCLEANDIRS = + +extout = +extout_prefix = +target_prefix = /json/ext +LOCAL_LIBS = +LIBS = $(LIBRUBYARG_SHARED) -lm -lpthread -lc +ORIG_SRCS = parser.c +SRCS = $(ORIG_SRCS) +OBJS = parser.o +HDRS = +LOCAL_HDRS = +TARGET = parser +TARGET_NAME = parser +TARGET_ENTRY = Init_$(TARGET_NAME) +DLLIB = $(TARGET).so +EXTSTATIC = +STATIC_LIB = + +TIMESTAMP_DIR = . +BINDIR = $(bindir) +RUBYCOMMONDIR = $(sitedir)$(target_prefix) +RUBYLIBDIR = $(sitelibdir)$(target_prefix) +RUBYARCHDIR = $(sitearchdir)$(target_prefix) +HDRDIR = $(sitehdrdir)$(target_prefix) +ARCHHDRDIR = $(sitearchhdrdir)$(target_prefix) +TARGET_SO_DIR = +TARGET_SO = $(TARGET_SO_DIR)$(DLLIB) +CLEANLIBS = $(TARGET_SO) false +CLEANOBJS = $(OBJS) *.bak +TARGET_SO_DIR_TIMESTAMP = $(TIMESTAMP_DIR)/.sitearchdir.-.json.-.ext.time + +all: $(DLLIB) +static: $(STATIC_LIB) +.PHONY: all install static install-so install-rb +.PHONY: clean clean-so clean-static clean-rb + +clean-static:: +clean-rb-default:: +clean-rb:: +clean-so:: +clean: clean-so clean-static clean-rb-default clean-rb + -$(Q)$(RM_RF) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time + +distclean-rb-default:: +distclean-rb:: +distclean-so:: +distclean-static:: +distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb + -$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + -$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + -$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true + +realclean: distclean +install: install-so install-rb + +install-so: $(DLLIB) $(TARGET_SO_DIR_TIMESTAMP) + $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) +clean-static:: + -$(Q)$(RM) $(STATIC_LIB) +install-rb: pre-install-rb do-install-rb install-rb-default +install-rb-default: pre-install-rb-default do-install-rb-default +pre-install-rb: Makefile +pre-install-rb-default: Makefile +do-install-rb: +do-install-rb-default: +pre-install-rb-default: + @$(NULLCMD) +$(TARGET_SO_DIR_TIMESTAMP): + $(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR) + $(Q) $(TOUCH) $@ + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + +.SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S + +.cc.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cc.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.mm.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.mm.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cxx.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cxx.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cpp.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cpp.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.c.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.c.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.m.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.m.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +$(TARGET_SO): $(OBJS) Makefile + $(ECHO) linking shared-object json/ext/$(DLLIB) + -$(Q)$(RM) $(@) + $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) + $(Q) $(POSTLINK) + + + +$(OBJS): $(HDRS) $(ruby_headers) diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/parser/extconf.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/parser/extconf.rb new file mode 100644 index 00000000..09c96377 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/parser/extconf.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true +require 'mkmf' + +have_func("rb_enc_interned_str", "ruby.h") # RUBY_VERSION >= 3.0 +have_func("rb_hash_new_capa", "ruby.h") # RUBY_VERSION >= 3.2 +have_func("rb_hash_bulk_insert", "ruby.h") # Missing on TruffleRuby +have_func("strnlen", "string.h") # Missing on Solaris 10 + +append_cflags("-std=c99") + +create_makefile 'json/ext/parser' diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/parser/parser.c b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/parser/parser.c new file mode 100644 index 00000000..c5f30018 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/parser/parser.c @@ -0,0 +1,1416 @@ +#include "ruby.h" +#include "ruby/encoding.h" + +/* shims */ +/* This is the fallback definition from Ruby 3.4 */ + +#ifndef RBIMPL_STDBOOL_H +#if defined(__cplusplus) +# if defined(HAVE_STDBOOL_H) && (__cplusplus >= 201103L) +# include +# endif +#elif defined(HAVE_STDBOOL_H) +# include +#elif !defined(HAVE__BOOL) +typedef unsigned char _Bool; +# define bool _Bool +# define true ((_Bool)+1) +# define false ((_Bool)+0) +# define __bool_true_false_are_defined +#endif +#endif + +#ifndef RB_UNLIKELY +#define RB_UNLIKELY(expr) expr +#endif + +#ifndef RB_LIKELY +#define RB_LIKELY(expr) expr +#endif + +static VALUE mJSON, eNestingError, Encoding_UTF_8; +static VALUE CNaN, CInfinity, CMinusInfinity; + +static ID i_chr, i_aset, i_aref, + i_leftshift, i_new, i_try_convert, i_uminus, i_encode; + +static VALUE sym_max_nesting, sym_allow_nan, sym_allow_trailing_comma, sym_symbolize_names, sym_freeze, + sym_decimal_class, sym_on_load; + +static int binary_encindex; +static int utf8_encindex; + +#ifndef HAVE_RB_HASH_BULK_INSERT +// For TruffleRuby +void +rb_hash_bulk_insert(long count, const VALUE *pairs, VALUE hash) +{ + long index = 0; + while (index < count) { + VALUE name = pairs[index++]; + VALUE value = pairs[index++]; + rb_hash_aset(hash, name, value); + } + RB_GC_GUARD(hash); +} +#endif + +#ifndef HAVE_RB_HASH_NEW_CAPA +#define rb_hash_new_capa(n) rb_hash_new() +#endif + + +/* name cache */ + +#include +#include + +// Object names are likely to be repeated, and are frozen. +// As such we can re-use them if we keep a cache of the ones we've seen so far, +// and save much more expensive lookups into the global fstring table. +// This cache implementation is deliberately simple, as we're optimizing for compactness, +// to be able to fit safely on the stack. +// As such, binary search into a sorted array gives a good tradeoff between compactness and +// performance. +#define JSON_RVALUE_CACHE_CAPA 63 +typedef struct rvalue_cache_struct { + int length; + VALUE entries[JSON_RVALUE_CACHE_CAPA]; +} rvalue_cache; + +static rb_encoding *enc_utf8; + +#define JSON_RVALUE_CACHE_MAX_ENTRY_LENGTH 55 + +static inline VALUE build_interned_string(const char *str, const long length) +{ +# ifdef HAVE_RB_ENC_INTERNED_STR + return rb_enc_interned_str(str, length, enc_utf8); +# else + VALUE rstring = rb_utf8_str_new(str, length); + return rb_funcall(rb_str_freeze(rstring), i_uminus, 0); +# endif +} + +static inline VALUE build_symbol(const char *str, const long length) +{ + return rb_str_intern(build_interned_string(str, length)); +} + +static void rvalue_cache_insert_at(rvalue_cache *cache, int index, VALUE rstring) +{ + MEMMOVE(&cache->entries[index + 1], &cache->entries[index], VALUE, cache->length - index); + cache->length++; + cache->entries[index] = rstring; +} + +static inline int rstring_cache_cmp(const char *str, const long length, VALUE rstring) +{ + long rstring_length = RSTRING_LEN(rstring); + if (length == rstring_length) { + return memcmp(str, RSTRING_PTR(rstring), length); + } else { + return (int)(length - rstring_length); + } +} + +static VALUE rstring_cache_fetch(rvalue_cache *cache, const char *str, const long length) +{ + if (RB_UNLIKELY(length > JSON_RVALUE_CACHE_MAX_ENTRY_LENGTH)) { + // Common names aren't likely to be very long. So we just don't + // cache names above an arbitrary threshold. + return Qfalse; + } + + if (RB_UNLIKELY(!isalpha((unsigned char)str[0]))) { + // Simple heuristic, if the first character isn't a letter, + // we're much less likely to see this string again. + // We mostly want to cache strings that are likely to be repeated. + return Qfalse; + } + + int low = 0; + int high = cache->length - 1; + int mid = 0; + int last_cmp = 0; + + while (low <= high) { + mid = (high + low) >> 1; + VALUE entry = cache->entries[mid]; + last_cmp = rstring_cache_cmp(str, length, entry); + + if (last_cmp == 0) { + return entry; + } else if (last_cmp > 0) { + low = mid + 1; + } else { + high = mid - 1; + } + } + + if (RB_UNLIKELY(memchr(str, '\\', length))) { + // We assume the overwhelming majority of names don't need to be escaped. + // But if they do, we have to fallback to the slow path. + return Qfalse; + } + + VALUE rstring = build_interned_string(str, length); + + if (cache->length < JSON_RVALUE_CACHE_CAPA) { + if (last_cmp > 0) { + mid += 1; + } + + rvalue_cache_insert_at(cache, mid, rstring); + } + return rstring; +} + +static VALUE rsymbol_cache_fetch(rvalue_cache *cache, const char *str, const long length) +{ + if (RB_UNLIKELY(length > JSON_RVALUE_CACHE_MAX_ENTRY_LENGTH)) { + // Common names aren't likely to be very long. So we just don't + // cache names above an arbitrary threshold. + return Qfalse; + } + + if (RB_UNLIKELY(!isalpha((unsigned char)str[0]))) { + // Simple heuristic, if the first character isn't a letter, + // we're much less likely to see this string again. + // We mostly want to cache strings that are likely to be repeated. + return Qfalse; + } + + int low = 0; + int high = cache->length - 1; + int mid = 0; + int last_cmp = 0; + + while (low <= high) { + mid = (high + low) >> 1; + VALUE entry = cache->entries[mid]; + last_cmp = rstring_cache_cmp(str, length, rb_sym2str(entry)); + + if (last_cmp == 0) { + return entry; + } else if (last_cmp > 0) { + low = mid + 1; + } else { + high = mid - 1; + } + } + + if (RB_UNLIKELY(memchr(str, '\\', length))) { + // We assume the overwhelming majority of names don't need to be escaped. + // But if they do, we have to fallback to the slow path. + return Qfalse; + } + + VALUE rsymbol = build_symbol(str, length); + + if (cache->length < JSON_RVALUE_CACHE_CAPA) { + if (last_cmp > 0) { + mid += 1; + } + + rvalue_cache_insert_at(cache, mid, rsymbol); + } + return rsymbol; +} + +/* rvalue stack */ + +#define RVALUE_STACK_INITIAL_CAPA 128 + +enum rvalue_stack_type { + RVALUE_STACK_HEAP_ALLOCATED = 0, + RVALUE_STACK_STACK_ALLOCATED = 1, +}; + +typedef struct rvalue_stack_struct { + enum rvalue_stack_type type; + long capa; + long head; + VALUE *ptr; +} rvalue_stack; + +static rvalue_stack *rvalue_stack_spill(rvalue_stack *old_stack, VALUE *handle, rvalue_stack **stack_ref); + +static rvalue_stack *rvalue_stack_grow(rvalue_stack *stack, VALUE *handle, rvalue_stack **stack_ref) +{ + long required = stack->capa * 2; + + if (stack->type == RVALUE_STACK_STACK_ALLOCATED) { + stack = rvalue_stack_spill(stack, handle, stack_ref); + } else { + REALLOC_N(stack->ptr, VALUE, required); + stack->capa = required; + } + return stack; +} + +static VALUE rvalue_stack_push(rvalue_stack *stack, VALUE value, VALUE *handle, rvalue_stack **stack_ref) +{ + if (RB_UNLIKELY(stack->head >= stack->capa)) { + stack = rvalue_stack_grow(stack, handle, stack_ref); + } + stack->ptr[stack->head] = value; + stack->head++; + return value; +} + +static inline VALUE *rvalue_stack_peek(rvalue_stack *stack, long count) +{ + return stack->ptr + (stack->head - count); +} + +static inline void rvalue_stack_pop(rvalue_stack *stack, long count) +{ + stack->head -= count; +} + +static void rvalue_stack_mark(void *ptr) +{ + rvalue_stack *stack = (rvalue_stack *)ptr; + long index; + for (index = 0; index < stack->head; index++) { + rb_gc_mark(stack->ptr[index]); + } +} + +static void rvalue_stack_free(void *ptr) +{ + rvalue_stack *stack = (rvalue_stack *)ptr; + if (stack) { + ruby_xfree(stack->ptr); + ruby_xfree(stack); + } +} + +static size_t rvalue_stack_memsize(const void *ptr) +{ + const rvalue_stack *stack = (const rvalue_stack *)ptr; + return sizeof(rvalue_stack) + sizeof(VALUE) * stack->capa; +} + +static const rb_data_type_t JSON_Parser_rvalue_stack_type = { + "JSON::Ext::Parser/rvalue_stack", + { + .dmark = rvalue_stack_mark, + .dfree = rvalue_stack_free, + .dsize = rvalue_stack_memsize, + }, + 0, 0, + RUBY_TYPED_FREE_IMMEDIATELY, +}; + +static rvalue_stack *rvalue_stack_spill(rvalue_stack *old_stack, VALUE *handle, rvalue_stack **stack_ref) +{ + rvalue_stack *stack; + *handle = TypedData_Make_Struct(0, rvalue_stack, &JSON_Parser_rvalue_stack_type, stack); + *stack_ref = stack; + MEMCPY(stack, old_stack, rvalue_stack, 1); + + stack->capa = old_stack->capa << 1; + stack->ptr = ALLOC_N(VALUE, stack->capa); + stack->type = RVALUE_STACK_HEAP_ALLOCATED; + MEMCPY(stack->ptr, old_stack->ptr, VALUE, old_stack->head); + return stack; +} + +static void rvalue_stack_eagerly_release(VALUE handle) +{ + if (handle) { + rvalue_stack *stack; + TypedData_Get_Struct(handle, rvalue_stack, &JSON_Parser_rvalue_stack_type, stack); + RTYPEDDATA_DATA(handle) = NULL; + rvalue_stack_free(stack); + } +} + + +#ifndef HAVE_STRNLEN +static size_t strnlen(const char *s, size_t maxlen) +{ + char *p; + return ((p = memchr(s, '\0', maxlen)) ? p - s : maxlen); +} +#endif + +static int convert_UTF32_to_UTF8(char *buf, uint32_t ch) +{ + int len = 1; + if (ch <= 0x7F) { + buf[0] = (char) ch; + } else if (ch <= 0x07FF) { + buf[0] = (char) ((ch >> 6) | 0xC0); + buf[1] = (char) ((ch & 0x3F) | 0x80); + len++; + } else if (ch <= 0xFFFF) { + buf[0] = (char) ((ch >> 12) | 0xE0); + buf[1] = (char) (((ch >> 6) & 0x3F) | 0x80); + buf[2] = (char) ((ch & 0x3F) | 0x80); + len += 2; + } else if (ch <= 0x1fffff) { + buf[0] =(char) ((ch >> 18) | 0xF0); + buf[1] =(char) (((ch >> 12) & 0x3F) | 0x80); + buf[2] =(char) (((ch >> 6) & 0x3F) | 0x80); + buf[3] =(char) ((ch & 0x3F) | 0x80); + len += 3; + } else { + buf[0] = '?'; + } + return len; +} + +typedef struct JSON_ParserStruct { + VALUE on_load_proc; + VALUE decimal_class; + ID decimal_method_id; + int max_nesting; + bool allow_nan; + bool allow_trailing_comma; + bool parsing_name; + bool symbolize_names; + bool freeze; +} JSON_ParserConfig; + +typedef struct JSON_ParserStateStruct { + VALUE stack_handle; + const char *start; + const char *cursor; + const char *end; + rvalue_stack *stack; + rvalue_cache name_cache; + int in_array; + int current_nesting; +} JSON_ParserState; + + +#define PARSE_ERROR_FRAGMENT_LEN 32 +#ifdef RBIMPL_ATTR_NORETURN +RBIMPL_ATTR_NORETURN() +#endif +static void raise_parse_error(const char *format, JSON_ParserState *state) +{ + unsigned char buffer[PARSE_ERROR_FRAGMENT_LEN + 3]; + + const char *cursor = state->cursor; + long column = 0; + long line = 1; + + while (cursor >= state->start) { + if (*cursor-- == '\n') { + break; + } + column++; + } + + while (cursor >= state->start) { + if (*cursor-- == '\n') { + line++; + } + } + + const char *ptr = "EOF"; + if (state->cursor && state->cursor < state->end) { + ptr = state->cursor; + size_t len = 0; + while (len < PARSE_ERROR_FRAGMENT_LEN) { + char ch = ptr[len]; + if (!ch || ch == '\n' || ch == ' ' || ch == '\t' || ch == '\r') { + break; + } + len++; + } + + if (len) { + buffer[0] = '\''; + MEMCPY(buffer + 1, ptr, char, len); + + while (buffer[len] >= 0x80 && buffer[len] < 0xC0) { // Is continuation byte + len--; + } + + if (buffer[len] >= 0xC0) { // multibyte character start + len--; + } + + buffer[len + 1] = '\''; + buffer[len + 2] = '\0'; + ptr = (const char *)buffer; + } + } + + VALUE msg = rb_sprintf(format, ptr); + VALUE message = rb_enc_sprintf(enc_utf8, "%s at line %ld column %ld", RSTRING_PTR(msg), line, column); + RB_GC_GUARD(msg); + + VALUE exc = rb_exc_new_str(rb_path2class("JSON::ParserError"), message); + rb_ivar_set(exc, rb_intern("@line"), LONG2NUM(line)); + rb_ivar_set(exc, rb_intern("@column"), LONG2NUM(column)); + rb_exc_raise(exc); +} + +#ifdef RBIMPL_ATTR_NORETURN +RBIMPL_ATTR_NORETURN() +#endif +static void raise_parse_error_at(const char *format, JSON_ParserState *state, const char *at) +{ + state->cursor = at; + raise_parse_error(format, state); +} + +/* unicode */ + +static const signed char digit_values[256] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, + -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1 +}; + +static uint32_t unescape_unicode(JSON_ParserState *state, const unsigned char *p) +{ + signed char b; + uint32_t result = 0; + b = digit_values[p[0]]; + if (b < 0) raise_parse_error_at("incomplete unicode character escape sequence at %s", state, (char *)p - 2); + result = (result << 4) | (unsigned char)b; + b = digit_values[p[1]]; + if (b < 0) raise_parse_error_at("incomplete unicode character escape sequence at %s", state, (char *)p - 2); + result = (result << 4) | (unsigned char)b; + b = digit_values[p[2]]; + if (b < 0) raise_parse_error_at("incomplete unicode character escape sequence at %s", state, (char *)p - 2); + result = (result << 4) | (unsigned char)b; + b = digit_values[p[3]]; + if (b < 0) raise_parse_error_at("incomplete unicode character escape sequence at %s", state, (char *)p - 2); + result = (result << 4) | (unsigned char)b; + return result; +} + +#define GET_PARSER_CONFIG \ + JSON_ParserConfig *config; \ + TypedData_Get_Struct(self, JSON_ParserConfig, &JSON_ParserConfig_type, config) + +static const rb_data_type_t JSON_ParserConfig_type; + +static const bool whitespace[256] = { + [' '] = 1, + ['\t'] = 1, + ['\n'] = 1, + ['\r'] = 1, + ['/'] = 1, +}; + +static void +json_eat_comments(JSON_ParserState *state) +{ + if (state->cursor + 1 < state->end) { + switch(state->cursor[1]) { + case '/': { + state->cursor = memchr(state->cursor, '\n', state->end - state->cursor); + if (!state->cursor) { + state->cursor = state->end; + } else { + state->cursor++; + } + break; + } + case '*': { + state->cursor += 2; + while (true) { + state->cursor = memchr(state->cursor, '*', state->end - state->cursor); + if (!state->cursor) { + raise_parse_error_at("unexpected end of input, expected closing '*/'", state, state->end); + } else { + state->cursor++; + if (state->cursor < state->end && *state->cursor == '/') { + state->cursor++; + break; + } + } + } + break; + } + default: + raise_parse_error("unexpected token %s", state); + break; + } + } else { + raise_parse_error("unexpected token %s", state); + } +} + +static inline void +json_eat_whitespace(JSON_ParserState *state) +{ + while (state->cursor < state->end && RB_UNLIKELY(whitespace[(unsigned char)*state->cursor])) { + if (RB_LIKELY(*state->cursor != '/')) { + state->cursor++; + } else { + json_eat_comments(state); + } + } +} + +static inline VALUE build_string(const char *start, const char *end, bool intern, bool symbolize) +{ + if (symbolize) { + intern = true; + } + VALUE result; +# ifdef HAVE_RB_ENC_INTERNED_STR + if (intern) { + result = rb_enc_interned_str(start, (long)(end - start), enc_utf8); + } else { + result = rb_utf8_str_new(start, (long)(end - start)); + } +# else + result = rb_utf8_str_new(start, (long)(end - start)); + if (intern) { + result = rb_funcall(rb_str_freeze(result), i_uminus, 0); + } +# endif + + if (symbolize) { + result = rb_str_intern(result); + } + + return result; +} + +static inline VALUE json_string_fastpath(JSON_ParserState *state, const char *string, const char *stringEnd, bool is_name, bool intern, bool symbolize) +{ + size_t bufferSize = stringEnd - string; + + if (is_name && state->in_array) { + VALUE cached_key; + if (RB_UNLIKELY(symbolize)) { + cached_key = rsymbol_cache_fetch(&state->name_cache, string, bufferSize); + } else { + cached_key = rstring_cache_fetch(&state->name_cache, string, bufferSize); + } + + if (RB_LIKELY(cached_key)) { + return cached_key; + } + } + + return build_string(string, stringEnd, intern, symbolize); +} + +static VALUE json_string_unescape(JSON_ParserState *state, const char *string, const char *stringEnd, bool is_name, bool intern, bool symbolize) +{ + size_t bufferSize = stringEnd - string; + const char *p = string, *pe = string, *unescape, *bufferStart; + char *buffer; + int unescape_len; + char buf[4]; + + if (is_name && state->in_array) { + VALUE cached_key; + if (RB_UNLIKELY(symbolize)) { + cached_key = rsymbol_cache_fetch(&state->name_cache, string, bufferSize); + } else { + cached_key = rstring_cache_fetch(&state->name_cache, string, bufferSize); + } + + if (RB_LIKELY(cached_key)) { + return cached_key; + } + } + + VALUE result = rb_str_buf_new(bufferSize); + rb_enc_associate_index(result, utf8_encindex); + buffer = RSTRING_PTR(result); + bufferStart = buffer; + + while (pe < stringEnd && (pe = memchr(pe, '\\', stringEnd - pe))) { + unescape = (char *) "?"; + unescape_len = 1; + if (pe > p) { + MEMCPY(buffer, p, char, pe - p); + buffer += pe - p; + } + switch (*++pe) { + case 'n': + unescape = (char *) "\n"; + break; + case 'r': + unescape = (char *) "\r"; + break; + case 't': + unescape = (char *) "\t"; + break; + case '"': + unescape = (char *) "\""; + break; + case '\\': + unescape = (char *) "\\"; + break; + case 'b': + unescape = (char *) "\b"; + break; + case 'f': + unescape = (char *) "\f"; + break; + case 'u': + if (pe > stringEnd - 5) { + raise_parse_error_at("incomplete unicode character escape sequence at %s", state, p); + } else { + uint32_t ch = unescape_unicode(state, (unsigned char *) ++pe); + pe += 3; + /* To handle values above U+FFFF, we take a sequence of + * \uXXXX escapes in the U+D800..U+DBFF then + * U+DC00..U+DFFF ranges, take the low 10 bits from each + * to make a 20-bit number, then add 0x10000 to get the + * final codepoint. + * + * See Unicode 15: 3.8 "Surrogates", 5.3 "Handling + * Surrogate Pairs in UTF-16", and 23.6 "Surrogates + * Area". + */ + if ((ch & 0xFC00) == 0xD800) { + pe++; + if (pe > stringEnd - 6) { + raise_parse_error_at("incomplete surrogate pair at %s", state, p); + } + if (pe[0] == '\\' && pe[1] == 'u') { + uint32_t sur = unescape_unicode(state, (unsigned char *) pe + 2); + ch = (((ch & 0x3F) << 10) | ((((ch >> 6) & 0xF) + 1) << 16) + | (sur & 0x3FF)); + pe += 5; + } else { + unescape = (char *) "?"; + break; + } + } + unescape_len = convert_UTF32_to_UTF8(buf, ch); + unescape = buf; + } + break; + default: + p = pe; + continue; + } + MEMCPY(buffer, unescape, char, unescape_len); + buffer += unescape_len; + p = ++pe; + } + + if (stringEnd > p) { + MEMCPY(buffer, p, char, stringEnd - p); + buffer += stringEnd - p; + } + rb_str_set_len(result, buffer - bufferStart); + + if (symbolize) { + result = rb_str_intern(result); + } else if (intern) { + result = rb_funcall(rb_str_freeze(result), i_uminus, 0); + } + + return result; +} + +#define MAX_FAST_INTEGER_SIZE 18 +static inline VALUE fast_decode_integer(const char *p, const char *pe) +{ + bool negative = false; + if (*p == '-') { + negative = true; + p++; + } + + long long memo = 0; + while (p < pe) { + memo *= 10; + memo += *p - '0'; + p++; + } + + if (negative) { + memo = -memo; + } + return LL2NUM(memo); +} + +static VALUE json_decode_large_integer(const char *start, long len) +{ + VALUE buffer_v; + char *buffer = RB_ALLOCV_N(char, buffer_v, len + 1); + MEMCPY(buffer, start, char, len); + buffer[len] = '\0'; + VALUE number = rb_cstr2inum(buffer, 10); + RB_ALLOCV_END(buffer_v); + return number; +} + +static inline VALUE +json_decode_integer(const char *start, const char *end) +{ + long len = end - start; + if (RB_LIKELY(len < MAX_FAST_INTEGER_SIZE)) { + return fast_decode_integer(start, end); + } + return json_decode_large_integer(start, len); +} + +static VALUE json_decode_large_float(const char *start, long len) +{ + VALUE buffer_v; + char *buffer = RB_ALLOCV_N(char, buffer_v, len + 1); + MEMCPY(buffer, start, char, len); + buffer[len] = '\0'; + VALUE number = DBL2NUM(rb_cstr_to_dbl(buffer, 1)); + RB_ALLOCV_END(buffer_v); + return number; +} + +static VALUE json_decode_float(JSON_ParserConfig *config, const char *start, const char *end) +{ + long len = end - start; + + if (RB_UNLIKELY(config->decimal_class)) { + VALUE text = rb_str_new(start, len); + return rb_funcallv(config->decimal_class, config->decimal_method_id, 1, &text); + } else if (RB_LIKELY(len < 64)) { + char buffer[64]; + MEMCPY(buffer, start, char, len); + buffer[len] = '\0'; + return DBL2NUM(rb_cstr_to_dbl(buffer, 1)); + } else { + return json_decode_large_float(start, len); + } +} + +static inline VALUE json_decode_array(JSON_ParserState *state, JSON_ParserConfig *config, long count) +{ + VALUE array = rb_ary_new_from_values(count, rvalue_stack_peek(state->stack, count)); + rvalue_stack_pop(state->stack, count); + + if (config->freeze) { + RB_OBJ_FREEZE(array); + } + + return array; +} + +static inline VALUE json_decode_object(JSON_ParserState *state, JSON_ParserConfig *config, long count) +{ + VALUE object = rb_hash_new_capa(count); + rb_hash_bulk_insert(count, rvalue_stack_peek(state->stack, count), object); + + rvalue_stack_pop(state->stack, count); + + if (config->freeze) { + RB_OBJ_FREEZE(object); + } + + return object; +} + +static inline VALUE json_decode_string(JSON_ParserState *state, JSON_ParserConfig *config, const char *start, const char *end, bool escaped, bool is_name) +{ + VALUE string; + bool intern = is_name || config->freeze; + bool symbolize = is_name && config->symbolize_names; + if (escaped) { + string = json_string_unescape(state, start, end, is_name, intern, symbolize); + } else { + string = json_string_fastpath(state, start, end, is_name, intern, symbolize); + } + + return string; +} + +static inline VALUE json_push_value(JSON_ParserState *state, JSON_ParserConfig *config, VALUE value) +{ + if (RB_UNLIKELY(config->on_load_proc)) { + value = rb_proc_call_with_block(config->on_load_proc, 1, &value, Qnil); + } + rvalue_stack_push(state->stack, value, &state->stack_handle, &state->stack); + return value; +} + +static const bool string_scan[256] = { + // ASCII Control Characters + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + // ASCII Characters + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // '"' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, // '\\' + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static inline VALUE json_parse_string(JSON_ParserState *state, JSON_ParserConfig *config, bool is_name) +{ + state->cursor++; + const char *start = state->cursor; + bool escaped = false; + + while (state->cursor < state->end) { + if (RB_UNLIKELY(string_scan[(unsigned char)*state->cursor])) { + switch (*state->cursor) { + case '"': { + VALUE string = json_decode_string(state, config, start, state->cursor, escaped, is_name); + state->cursor++; + return json_push_value(state, config, string); + } + case '\\': { + state->cursor++; + escaped = true; + if ((unsigned char)*state->cursor < 0x20) { + raise_parse_error("invalid ASCII control character in string: %s", state); + } + break; + } + default: + raise_parse_error("invalid ASCII control character in string: %s", state); + break; + } + } + + state->cursor++; + } + + raise_parse_error("unexpected end of input, expected closing \"", state); + return Qfalse; +} + +static VALUE json_parse_any(JSON_ParserState *state, JSON_ParserConfig *config) +{ + json_eat_whitespace(state); + if (state->cursor >= state->end) { + raise_parse_error("unexpected end of input", state); + } + + switch (*state->cursor) { + case 'n': + if ((state->end - state->cursor >= 4) && (memcmp(state->cursor, "null", 4) == 0)) { + state->cursor += 4; + return json_push_value(state, config, Qnil); + } + + raise_parse_error("unexpected token %s", state); + break; + case 't': + if ((state->end - state->cursor >= 4) && (memcmp(state->cursor, "true", 4) == 0)) { + state->cursor += 4; + return json_push_value(state, config, Qtrue); + } + + raise_parse_error("unexpected token %s", state); + break; + case 'f': + // Note: memcmp with a small power of two compile to an integer comparison + if ((state->end - state->cursor >= 5) && (memcmp(state->cursor + 1, "alse", 4) == 0)) { + state->cursor += 5; + return json_push_value(state, config, Qfalse); + } + + raise_parse_error("unexpected token %s", state); + break; + case 'N': + // Note: memcmp with a small power of two compile to an integer comparison + if (config->allow_nan && (state->end - state->cursor >= 3) && (memcmp(state->cursor + 1, "aN", 2) == 0)) { + state->cursor += 3; + return json_push_value(state, config, CNaN); + } + + raise_parse_error("unexpected token %s", state); + break; + case 'I': + if (config->allow_nan && (state->end - state->cursor >= 8) && (memcmp(state->cursor, "Infinity", 8) == 0)) { + state->cursor += 8; + return json_push_value(state, config, CInfinity); + } + + raise_parse_error("unexpected token %s", state); + break; + case '-': + // Note: memcmp with a small power of two compile to an integer comparison + if ((state->end - state->cursor >= 9) && (memcmp(state->cursor + 1, "Infinity", 8) == 0)) { + if (config->allow_nan) { + state->cursor += 9; + return json_push_value(state, config, CMinusInfinity); + } else { + raise_parse_error("unexpected token %s", state); + } + } + // Fallthrough + case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { + bool integer = true; + + // /\A-?(0|[1-9]\d*)(\.\d+)?([Ee][-+]?\d+)?/ + const char *start = state->cursor; + state->cursor++; + + while ((state->cursor < state->end) && (*state->cursor >= '0') && (*state->cursor <= '9')) { + state->cursor++; + } + + long integer_length = state->cursor - start; + + if (RB_UNLIKELY(start[0] == '0' && integer_length > 1)) { + raise_parse_error_at("invalid number: %s", state, start); + } else if (RB_UNLIKELY(integer_length > 2 && start[0] == '-' && start[1] == '0')) { + raise_parse_error_at("invalid number: %s", state, start); + } else if (RB_UNLIKELY(integer_length == 1 && start[0] == '-')) { + raise_parse_error_at("invalid number: %s", state, start); + } + + if ((state->cursor < state->end) && (*state->cursor == '.')) { + integer = false; + state->cursor++; + + if (state->cursor == state->end || *state->cursor < '0' || *state->cursor > '9') { + raise_parse_error("invalid number: %s", state); + } + + while ((state->cursor < state->end) && (*state->cursor >= '0') && (*state->cursor <= '9')) { + state->cursor++; + } + } + + if ((state->cursor < state->end) && ((*state->cursor == 'e') || (*state->cursor == 'E'))) { + integer = false; + state->cursor++; + if ((state->cursor < state->end) && ((*state->cursor == '+') || (*state->cursor == '-'))) { + state->cursor++; + } + + if (state->cursor == state->end || *state->cursor < '0' || *state->cursor > '9') { + raise_parse_error("invalid number: %s", state); + } + + while ((state->cursor < state->end) && (*state->cursor >= '0') && (*state->cursor <= '9')) { + state->cursor++; + } + } + + if (integer) { + return json_push_value(state, config, json_decode_integer(start, state->cursor)); + } + return json_push_value(state, config, json_decode_float(config, start, state->cursor)); + } + case '"': { + // %r{\A"[^"\\\t\n\x00]*(?:\\[bfnrtu\\/"][^"\\]*)*"} + return json_parse_string(state, config, false); + break; + } + case '[': { + state->cursor++; + json_eat_whitespace(state); + long stack_head = state->stack->head; + + if ((state->cursor < state->end) && (*state->cursor == ']')) { + state->cursor++; + return json_push_value(state, config, json_decode_array(state, config, 0)); + } else { + state->current_nesting++; + if (RB_UNLIKELY(config->max_nesting && (config->max_nesting < state->current_nesting))) { + rb_raise(eNestingError, "nesting of %d is too deep", state->current_nesting); + } + state->in_array++; + json_parse_any(state, config); + } + + while (true) { + json_eat_whitespace(state); + + if (state->cursor < state->end) { + if (*state->cursor == ']') { + state->cursor++; + long count = state->stack->head - stack_head; + state->current_nesting--; + state->in_array--; + return json_push_value(state, config, json_decode_array(state, config, count)); + } + + if (*state->cursor == ',') { + state->cursor++; + if (config->allow_trailing_comma) { + json_eat_whitespace(state); + if ((state->cursor < state->end) && (*state->cursor == ']')) { + continue; + } + } + json_parse_any(state, config); + continue; + } + } + + raise_parse_error("expected ',' or ']' after array value", state); + } + break; + } + case '{': { + state->cursor++; + json_eat_whitespace(state); + long stack_head = state->stack->head; + + if ((state->cursor < state->end) && (*state->cursor == '}')) { + state->cursor++; + return json_push_value(state, config, json_decode_object(state, config, 0)); + } else { + state->current_nesting++; + if (RB_UNLIKELY(config->max_nesting && (config->max_nesting < state->current_nesting))) { + rb_raise(eNestingError, "nesting of %d is too deep", state->current_nesting); + } + + if (*state->cursor != '"') { + raise_parse_error("expected object key, got %s", state); + } + json_parse_string(state, config, true); + + json_eat_whitespace(state); + if ((state->cursor >= state->end) || (*state->cursor != ':')) { + raise_parse_error("expected ':' after object key", state); + } + state->cursor++; + + json_parse_any(state, config); + } + + while (true) { + json_eat_whitespace(state); + + if (state->cursor < state->end) { + if (*state->cursor == '}') { + state->cursor++; + state->current_nesting--; + long count = state->stack->head - stack_head; + return json_push_value(state, config, json_decode_object(state, config, count)); + } + + if (*state->cursor == ',') { + state->cursor++; + json_eat_whitespace(state); + + if (config->allow_trailing_comma) { + if ((state->cursor < state->end) && (*state->cursor == '}')) { + continue; + } + } + + if (*state->cursor != '"') { + raise_parse_error("expected object key, got: %s", state); + } + json_parse_string(state, config, true); + + json_eat_whitespace(state); + if ((state->cursor >= state->end) || (*state->cursor != ':')) { + raise_parse_error("expected ':' after object key, got: %s", state); + } + state->cursor++; + + json_parse_any(state, config); + + continue; + } + } + + raise_parse_error("expected ',' or '}' after object value, got: %s", state); + } + break; + } + + default: + raise_parse_error("unexpected character: %s", state); + break; + } + + raise_parse_error("unreacheable: %s", state); +} + +static void json_ensure_eof(JSON_ParserState *state) +{ + json_eat_whitespace(state); + if (state->cursor != state->end) { + raise_parse_error("unexpected token at end of stream %s", state); + } +} + +/* + * Document-class: JSON::Ext::Parser + * + * This is the JSON parser implemented as a C extension. It can be configured + * to be used by setting + * + * JSON.parser = JSON::Ext::Parser + * + * with the method parser= in JSON. + * + */ + +static VALUE convert_encoding(VALUE source) +{ + int encindex = RB_ENCODING_GET(source); + + if (RB_LIKELY(encindex == utf8_encindex)) { + return source; + } + + if (encindex == binary_encindex) { + // For historical reason, we silently reinterpret binary strings as UTF-8 + return rb_enc_associate_index(rb_str_dup(source), utf8_encindex); + } + + return rb_funcall(source, i_encode, 1, Encoding_UTF_8); +} + +static int parser_config_init_i(VALUE key, VALUE val, VALUE data) +{ + JSON_ParserConfig *config = (JSON_ParserConfig *)data; + + if (key == sym_max_nesting) { config->max_nesting = RTEST(val) ? FIX2INT(val) : 0; } + else if (key == sym_allow_nan) { config->allow_nan = RTEST(val); } + else if (key == sym_allow_trailing_comma) { config->allow_trailing_comma = RTEST(val); } + else if (key == sym_symbolize_names) { config->symbolize_names = RTEST(val); } + else if (key == sym_freeze) { config->freeze = RTEST(val); } + else if (key == sym_on_load) { config->on_load_proc = RTEST(val) ? val : Qfalse; } + else if (key == sym_decimal_class) { + if (RTEST(val)) { + if (rb_respond_to(val, i_try_convert)) { + config->decimal_class = val; + config->decimal_method_id = i_try_convert; + } else if (rb_respond_to(val, i_new)) { + config->decimal_class = val; + config->decimal_method_id = i_new; + } else if (RB_TYPE_P(val, T_CLASS)) { + VALUE name = rb_class_name(val); + const char *name_cstr = RSTRING_PTR(name); + const char *last_colon = strrchr(name_cstr, ':'); + if (last_colon) { + const char *mod_path_end = last_colon - 1; + VALUE mod_path = rb_str_substr(name, 0, mod_path_end - name_cstr); + config->decimal_class = rb_path_to_class(mod_path); + + const char *method_name_beg = last_colon + 1; + long before_len = method_name_beg - name_cstr; + long len = RSTRING_LEN(name) - before_len; + VALUE method_name = rb_str_substr(name, before_len, len); + config->decimal_method_id = SYM2ID(rb_str_intern(method_name)); + } else { + config->decimal_class = rb_mKernel; + config->decimal_method_id = SYM2ID(rb_str_intern(name)); + } + } + } + } + + return ST_CONTINUE; +} + +static void parser_config_init(JSON_ParserConfig *config, VALUE opts) +{ + config->max_nesting = 100; + + if (!NIL_P(opts)) { + Check_Type(opts, T_HASH); + if (RHASH_SIZE(opts) > 0) { + // We assume in most cases few keys are set so it's faster to go over + // the provided keys than to check all possible keys. + rb_hash_foreach(opts, parser_config_init_i, (VALUE)config); + } + + } +} + +/* + * call-seq: new(opts => {}) + * + * Creates a new JSON::Ext::ParserConfig instance. + * + * It will be configured by the _opts_ hash. _opts_ can have the following + * keys: + * + * _opts_ can have the following keys: + * * *max_nesting*: The maximum depth of nesting allowed in the parsed data + * structures. Disable depth checking with :max_nesting => false|nil|0, it + * defaults to 100. + * * *allow_nan*: If set to true, allow NaN, Infinity and -Infinity in + * defiance of RFC 4627 to be parsed by the Parser. This option defaults to + * false. + * * *symbolize_names*: If set to true, returns symbols for the names + * (keys) in a JSON object. Otherwise strings are returned, which is + * also the default. It's not possible to use this option in + * conjunction with the *create_additions* option. + * * *decimal_class*: Specifies which class to use instead of the default + * (Float) when parsing decimal numbers. This class must accept a single + * string argument in its constructor. + */ +static VALUE cParserConfig_initialize(VALUE self, VALUE opts) +{ + GET_PARSER_CONFIG; + + parser_config_init(config, opts); + + RB_OBJ_WRITTEN(self, Qundef, config->decimal_class); + + return self; +} + +static VALUE cParser_parse(JSON_ParserConfig *config, VALUE Vsource) +{ + Vsource = convert_encoding(StringValue(Vsource)); + StringValue(Vsource); + + VALUE rvalue_stack_buffer[RVALUE_STACK_INITIAL_CAPA]; + rvalue_stack stack = { + .type = RVALUE_STACK_STACK_ALLOCATED, + .ptr = rvalue_stack_buffer, + .capa = RVALUE_STACK_INITIAL_CAPA, + }; + + long len; + const char *start; + RSTRING_GETMEM(Vsource, start, len); + + JSON_ParserState _state = { + .start = start, + .cursor = start, + .end = start + len, + .stack = &stack, + }; + JSON_ParserState *state = &_state; + + VALUE result = json_parse_any(state, config); + + // This may be skipped in case of exception, but + // it won't cause a leak. + rvalue_stack_eagerly_release(state->stack_handle); + + json_ensure_eof(state); + + return result; +} + +/* + * call-seq: parse(source) + * + * Parses the current JSON text _source_ and returns the complete data + * structure as a result. + * It raises JSON::ParserError if fail to parse. + */ +static VALUE cParserConfig_parse(VALUE self, VALUE Vsource) +{ + GET_PARSER_CONFIG; + return cParser_parse(config, Vsource); +} + +static VALUE cParser_m_parse(VALUE klass, VALUE Vsource, VALUE opts) +{ + Vsource = convert_encoding(StringValue(Vsource)); + StringValue(Vsource); + + JSON_ParserConfig _config = {0}; + JSON_ParserConfig *config = &_config; + parser_config_init(config, opts); + + return cParser_parse(config, Vsource); +} + +static void JSON_ParserConfig_mark(void *ptr) +{ + JSON_ParserConfig *config = ptr; + rb_gc_mark(config->on_load_proc); + rb_gc_mark(config->decimal_class); +} + +static void JSON_ParserConfig_free(void *ptr) +{ + JSON_ParserConfig *config = ptr; + ruby_xfree(config); +} + +static size_t JSON_ParserConfig_memsize(const void *ptr) +{ + return sizeof(JSON_ParserConfig); +} + +static const rb_data_type_t JSON_ParserConfig_type = { + "JSON::Ext::Parser/ParserConfig", + { + JSON_ParserConfig_mark, + JSON_ParserConfig_free, + JSON_ParserConfig_memsize, + }, + 0, 0, + RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, +}; + +static VALUE cJSON_parser_s_allocate(VALUE klass) +{ + JSON_ParserConfig *config; + return TypedData_Make_Struct(klass, JSON_ParserConfig, &JSON_ParserConfig_type, config); +} + +void Init_parser(void) +{ +#ifdef HAVE_RB_EXT_RACTOR_SAFE + rb_ext_ractor_safe(true); +#endif + +#undef rb_intern + rb_require("json/common"); + mJSON = rb_define_module("JSON"); + VALUE mExt = rb_define_module_under(mJSON, "Ext"); + VALUE cParserConfig = rb_define_class_under(mExt, "ParserConfig", rb_cObject); + eNestingError = rb_path2class("JSON::NestingError"); + rb_gc_register_mark_object(eNestingError); + rb_define_alloc_func(cParserConfig, cJSON_parser_s_allocate); + rb_define_method(cParserConfig, "initialize", cParserConfig_initialize, 1); + rb_define_method(cParserConfig, "parse", cParserConfig_parse, 1); + + VALUE cParser = rb_define_class_under(mExt, "Parser", rb_cObject); + rb_define_singleton_method(cParser, "parse", cParser_m_parse, 2); + + CNaN = rb_const_get(mJSON, rb_intern("NaN")); + rb_gc_register_mark_object(CNaN); + + CInfinity = rb_const_get(mJSON, rb_intern("Infinity")); + rb_gc_register_mark_object(CInfinity); + + CMinusInfinity = rb_const_get(mJSON, rb_intern("MinusInfinity")); + rb_gc_register_mark_object(CMinusInfinity); + + rb_global_variable(&Encoding_UTF_8); + Encoding_UTF_8 = rb_const_get(rb_path2class("Encoding"), rb_intern("UTF_8")); + + sym_max_nesting = ID2SYM(rb_intern("max_nesting")); + sym_allow_nan = ID2SYM(rb_intern("allow_nan")); + sym_allow_trailing_comma = ID2SYM(rb_intern("allow_trailing_comma")); + sym_symbolize_names = ID2SYM(rb_intern("symbolize_names")); + sym_freeze = ID2SYM(rb_intern("freeze")); + sym_on_load = ID2SYM(rb_intern("on_load")); + sym_decimal_class = ID2SYM(rb_intern("decimal_class")); + + i_chr = rb_intern("chr"); + i_aset = rb_intern("[]="); + i_aref = rb_intern("[]"); + i_leftshift = rb_intern("<<"); + i_new = rb_intern("new"); + i_try_convert = rb_intern("try_convert"); + i_uminus = rb_intern("-@"); + i_encode = rb_intern("encode"); + + binary_encindex = rb_ascii8bit_encindex(); + utf8_encindex = rb_utf8_encindex(); + enc_utf8 = rb_utf8_encoding(); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/vendor/fpconv.c b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/vendor/fpconv.c new file mode 100644 index 00000000..75efd46f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/vendor/fpconv.c @@ -0,0 +1,479 @@ +// Boost Software License - Version 1.0 - August 17th, 2003 +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +// The contents of this file is extracted from https://github.com/night-shift/fpconv +// It was slightly modified to append ".0" to plain floats, for use with the https://github.com/ruby/json package. + +#include +#include +#include + +#define npowers 87 +#define steppowers 8 +#define firstpower -348 /* 10 ^ -348 */ + +#define expmax -32 +#define expmin -60 + +typedef struct Fp { + uint64_t frac; + int exp; +} Fp; + +static const Fp powers_ten[] = { + { 18054884314459144840U, -1220 }, { 13451937075301367670U, -1193 }, + { 10022474136428063862U, -1166 }, { 14934650266808366570U, -1140 }, + { 11127181549972568877U, -1113 }, { 16580792590934885855U, -1087 }, + { 12353653155963782858U, -1060 }, { 18408377700990114895U, -1034 }, + { 13715310171984221708U, -1007 }, { 10218702384817765436U, -980 }, + { 15227053142812498563U, -954 }, { 11345038669416679861U, -927 }, + { 16905424996341287883U, -901 }, { 12595523146049147757U, -874 }, + { 9384396036005875287U, -847 }, { 13983839803942852151U, -821 }, + { 10418772551374772303U, -794 }, { 15525180923007089351U, -768 }, + { 11567161174868858868U, -741 }, { 17236413322193710309U, -715 }, + { 12842128665889583758U, -688 }, { 9568131466127621947U, -661 }, + { 14257626930069360058U, -635 }, { 10622759856335341974U, -608 }, + { 15829145694278690180U, -582 }, { 11793632577567316726U, -555 }, + { 17573882009934360870U, -529 }, { 13093562431584567480U, -502 }, + { 9755464219737475723U, -475 }, { 14536774485912137811U, -449 }, + { 10830740992659433045U, -422 }, { 16139061738043178685U, -396 }, + { 12024538023802026127U, -369 }, { 17917957937422433684U, -343 }, + { 13349918974505688015U, -316 }, { 9946464728195732843U, -289 }, + { 14821387422376473014U, -263 }, { 11042794154864902060U, -236 }, + { 16455045573212060422U, -210 }, { 12259964326927110867U, -183 }, + { 18268770466636286478U, -157 }, { 13611294676837538539U, -130 }, + { 10141204801825835212U, -103 }, { 15111572745182864684U, -77 }, + { 11258999068426240000U, -50 }, { 16777216000000000000U, -24 }, + { 12500000000000000000U, 3 }, { 9313225746154785156U, 30 }, + { 13877787807814456755U, 56 }, { 10339757656912845936U, 83 }, + { 15407439555097886824U, 109 }, { 11479437019748901445U, 136 }, + { 17105694144590052135U, 162 }, { 12744735289059618216U, 189 }, + { 9495567745759798747U, 216 }, { 14149498560666738074U, 242 }, + { 10542197943230523224U, 269 }, { 15709099088952724970U, 295 }, + { 11704190886730495818U, 322 }, { 17440603504673385349U, 348 }, + { 12994262207056124023U, 375 }, { 9681479787123295682U, 402 }, + { 14426529090290212157U, 428 }, { 10748601772107342003U, 455 }, + { 16016664761464807395U, 481 }, { 11933345169920330789U, 508 }, + { 17782069995880619868U, 534 }, { 13248674568444952270U, 561 }, + { 9871031767461413346U, 588 }, { 14708983551653345445U, 614 }, + { 10959046745042015199U, 641 }, { 16330252207878254650U, 667 }, + { 12166986024289022870U, 694 }, { 18130221999122236476U, 720 }, + { 13508068024458167312U, 747 }, { 10064294952495520794U, 774 }, + { 14996968138956309548U, 800 }, { 11173611982879273257U, 827 }, + { 16649979327439178909U, 853 }, { 12405201291620119593U, 880 }, + { 9242595204427927429U, 907 }, { 13772540099066387757U, 933 }, + { 10261342003245940623U, 960 }, { 15290591125556738113U, 986 }, + { 11392378155556871081U, 1013 }, { 16975966327722178521U, 1039 }, + { 12648080533535911531U, 1066 } +}; + +static Fp find_cachedpow10(int exp, int* k) +{ + const double one_log_ten = 0.30102999566398114; + + int approx = (int)(-(exp + npowers) * one_log_ten); + int idx = (approx - firstpower) / steppowers; + + while(1) { + int current = exp + powers_ten[idx].exp + 64; + + if(current < expmin) { + idx++; + continue; + } + + if(current > expmax) { + idx--; + continue; + } + + *k = (firstpower + idx * steppowers); + + return powers_ten[idx]; + } +} + +#define fracmask 0x000FFFFFFFFFFFFFU +#define expmask 0x7FF0000000000000U +#define hiddenbit 0x0010000000000000U +#define signmask 0x8000000000000000U +#define expbias (1023 + 52) + +#define absv(n) ((n) < 0 ? -(n) : (n)) +#define minv(a, b) ((a) < (b) ? (a) : (b)) + +static const uint64_t tens[] = { + 10000000000000000000U, 1000000000000000000U, 100000000000000000U, + 10000000000000000U, 1000000000000000U, 100000000000000U, + 10000000000000U, 1000000000000U, 100000000000U, + 10000000000U, 1000000000U, 100000000U, + 10000000U, 1000000U, 100000U, + 10000U, 1000U, 100U, + 10U, 1U +}; + +static inline uint64_t get_dbits(double d) +{ + union { + double dbl; + uint64_t i; + } dbl_bits = { d }; + + return dbl_bits.i; +} + +static Fp build_fp(double d) +{ + uint64_t bits = get_dbits(d); + + Fp fp; + fp.frac = bits & fracmask; + fp.exp = (bits & expmask) >> 52; + + if(fp.exp) { + fp.frac += hiddenbit; + fp.exp -= expbias; + + } else { + fp.exp = -expbias + 1; + } + + return fp; +} + +static void normalize(Fp* fp) +{ + while ((fp->frac & hiddenbit) == 0) { + fp->frac <<= 1; + fp->exp--; + } + + int shift = 64 - 52 - 1; + fp->frac <<= shift; + fp->exp -= shift; +} + +static void get_normalized_boundaries(Fp* fp, Fp* lower, Fp* upper) +{ + upper->frac = (fp->frac << 1) + 1; + upper->exp = fp->exp - 1; + + while ((upper->frac & (hiddenbit << 1)) == 0) { + upper->frac <<= 1; + upper->exp--; + } + + int u_shift = 64 - 52 - 2; + + upper->frac <<= u_shift; + upper->exp = upper->exp - u_shift; + + + int l_shift = fp->frac == hiddenbit ? 2 : 1; + + lower->frac = (fp->frac << l_shift) - 1; + lower->exp = fp->exp - l_shift; + + + lower->frac <<= lower->exp - upper->exp; + lower->exp = upper->exp; +} + +static Fp multiply(Fp* a, Fp* b) +{ + const uint64_t lomask = 0x00000000FFFFFFFF; + + uint64_t ah_bl = (a->frac >> 32) * (b->frac & lomask); + uint64_t al_bh = (a->frac & lomask) * (b->frac >> 32); + uint64_t al_bl = (a->frac & lomask) * (b->frac & lomask); + uint64_t ah_bh = (a->frac >> 32) * (b->frac >> 32); + + uint64_t tmp = (ah_bl & lomask) + (al_bh & lomask) + (al_bl >> 32); + /* round up */ + tmp += 1U << 31; + + Fp fp = { + ah_bh + (ah_bl >> 32) + (al_bh >> 32) + (tmp >> 32), + a->exp + b->exp + 64 + }; + + return fp; +} + +static void round_digit(char* digits, int ndigits, uint64_t delta, uint64_t rem, uint64_t kappa, uint64_t frac) +{ + while (rem < frac && delta - rem >= kappa && + (rem + kappa < frac || frac - rem > rem + kappa - frac)) { + + digits[ndigits - 1]--; + rem += kappa; + } +} + +static int generate_digits(Fp* fp, Fp* upper, Fp* lower, char* digits, int* K) +{ + uint64_t wfrac = upper->frac - fp->frac; + uint64_t delta = upper->frac - lower->frac; + + Fp one; + one.frac = 1ULL << -upper->exp; + one.exp = upper->exp; + + uint64_t part1 = upper->frac >> -one.exp; + uint64_t part2 = upper->frac & (one.frac - 1); + + int idx = 0, kappa = 10; + const uint64_t* divp; + /* 1000000000 */ + for(divp = tens + 10; kappa > 0; divp++) { + + uint64_t div = *divp; + unsigned digit = (unsigned) (part1 / div); + + if (digit || idx) { + digits[idx++] = digit + '0'; + } + + part1 -= digit * div; + kappa--; + + uint64_t tmp = (part1 <<-one.exp) + part2; + if (tmp <= delta) { + *K += kappa; + round_digit(digits, idx, delta, tmp, div << -one.exp, wfrac); + + return idx; + } + } + + /* 10 */ + const uint64_t* unit = tens + 18; + + while(true) { + part2 *= 10; + delta *= 10; + kappa--; + + unsigned digit = (unsigned) (part2 >> -one.exp); + if (digit || idx) { + digits[idx++] = digit + '0'; + } + + part2 &= one.frac - 1; + if (part2 < delta) { + *K += kappa; + round_digit(digits, idx, delta, part2, one.frac, wfrac * *unit); + + return idx; + } + + unit--; + } +} + +static int grisu2(double d, char* digits, int* K) +{ + Fp w = build_fp(d); + + Fp lower, upper; + get_normalized_boundaries(&w, &lower, &upper); + + normalize(&w); + + int k; + Fp cp = find_cachedpow10(upper.exp, &k); + + w = multiply(&w, &cp); + upper = multiply(&upper, &cp); + lower = multiply(&lower, &cp); + + lower.frac++; + upper.frac--; + + *K = -k; + + return generate_digits(&w, &upper, &lower, digits, K); +} + +static int emit_digits(char* digits, int ndigits, char* dest, int K, bool neg) +{ + int exp = absv(K + ndigits - 1); + + int max_trailing_zeros = 7; + + if(neg) { + max_trailing_zeros -= 1; + } + + /* write plain integer */ + if(K >= 0 && (exp < (ndigits + max_trailing_zeros))) { + + memcpy(dest, digits, ndigits); + memset(dest + ndigits, '0', K); + + /* add a .0 to mark this as a float. */ + dest[ndigits + K] = '.'; + dest[ndigits + K + 1] = '0'; + + return ndigits + K + 2; + } + + /* write decimal w/o scientific notation */ + if(K < 0 && (K > -7 || exp < 10)) { + int offset = ndigits - absv(K); + /* fp < 1.0 -> write leading zero */ + if(offset <= 0) { + offset = -offset; + dest[0] = '0'; + dest[1] = '.'; + memset(dest + 2, '0', offset); + memcpy(dest + offset + 2, digits, ndigits); + + return ndigits + 2 + offset; + + /* fp > 1.0 */ + } else { + memcpy(dest, digits, offset); + dest[offset] = '.'; + memcpy(dest + offset + 1, digits + offset, ndigits - offset); + + return ndigits + 1; + } + } + + /* write decimal w/ scientific notation */ + ndigits = minv(ndigits, 18 - neg); + + int idx = 0; + dest[idx++] = digits[0]; + + if(ndigits > 1) { + dest[idx++] = '.'; + memcpy(dest + idx, digits + 1, ndigits - 1); + idx += ndigits - 1; + } + + dest[idx++] = 'e'; + + char sign = K + ndigits - 1 < 0 ? '-' : '+'; + dest[idx++] = sign; + + int cent = 0; + + if(exp > 99) { + cent = exp / 100; + dest[idx++] = cent + '0'; + exp -= cent * 100; + } + if(exp > 9) { + int dec = exp / 10; + dest[idx++] = dec + '0'; + exp -= dec * 10; + + } else if(cent) { + dest[idx++] = '0'; + } + + dest[idx++] = exp % 10 + '0'; + + return idx; +} + +static int filter_special(double fp, char* dest) +{ + if(fp == 0.0) { + dest[0] = '0'; + dest[1] = '.'; + dest[2] = '0'; + return 3; + } + + uint64_t bits = get_dbits(fp); + + bool nan = (bits & expmask) == expmask; + + if(!nan) { + return 0; + } + + if(bits & fracmask) { + dest[0] = 'n'; dest[1] = 'a'; dest[2] = 'n'; + + } else { + dest[0] = 'i'; dest[1] = 'n'; dest[2] = 'f'; + } + + return 3; +} + +/* Fast and accurate double to string conversion based on Florian Loitsch's + * Grisu-algorithm[1]. + * + * Input: + * fp -> the double to convert, dest -> destination buffer. + * The generated string will never be longer than 28 characters. + * Make sure to pass a pointer to at least 28 bytes of memory. + * The emitted string will not be null terminated. + * + * Output: + * The number of written characters. + * + * Exemplary usage: + * + * void print(double d) + * { + * char buf[28 + 1] // plus null terminator + * int str_len = fpconv_dtoa(d, buf); + * + * buf[str_len] = '\0'; + * printf("%s", buf); + * } + * + */ +static int fpconv_dtoa(double d, char dest[28]) +{ + char digits[18]; + + int str_len = 0; + bool neg = false; + + if(get_dbits(d) & signmask) { + dest[0] = '-'; + str_len++; + neg = true; + } + + int spec = filter_special(d, dest + str_len); + + if(spec) { + return str_len + spec; + } + + int K = 0; + int ndigits = grisu2(d, digits, &K); + + str_len += emit_digits(digits, ndigits, dest + str_len, K, neg); + + return str_len; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/vendor/jeaiii-ltoa.h b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/vendor/jeaiii-ltoa.h new file mode 100644 index 00000000..ba4f497f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/ext/json/ext/vendor/jeaiii-ltoa.h @@ -0,0 +1,267 @@ +/* + +This file is released under the terms of the MIT License. It is based on the +work of James Edward Anhalt III, with the original license listed below. + +MIT License + +Copyright (c) 2024,2025 Enrico Thierbach - https://github.com/radiospiel +Copyright (c) 2022 James Edward Anhalt III - https://github.com/jeaiii/itoa + +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 +AUTHORS OR COPYRIGHT HOLDERS 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. +*/ + +#ifndef JEAIII_TO_TEXT_H_ +#define JEAIII_TO_TEXT_H_ + +#include + +typedef uint_fast32_t u32_t; +typedef uint_fast64_t u64_t; + +#define u32(x) ((u32_t)(x)) +#define u64(x) ((u64_t)(x)) + +struct digit_pair +{ + char dd[2]; +}; + +static const struct digit_pair *digits_dd = (struct digit_pair *)( + "00" "01" "02" "03" "04" "05" "06" "07" "08" "09" + "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" + "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" + "30" "31" "32" "33" "34" "35" "36" "37" "38" "39" + "40" "41" "42" "43" "44" "45" "46" "47" "48" "49" + "50" "51" "52" "53" "54" "55" "56" "57" "58" "59" + "60" "61" "62" "63" "64" "65" "66" "67" "68" "69" + "70" "71" "72" "73" "74" "75" "76" "77" "78" "79" + "80" "81" "82" "83" "84" "85" "86" "87" "88" "89" + "90" "91" "92" "93" "94" "95" "96" "97" "98" "99" +); + +static const struct digit_pair *digits_fd = (struct digit_pair *)( + "0_" "1_" "2_" "3_" "4_" "5_" "6_" "7_" "8_" "9_" + "10" "11" "12" "13" "14" "15" "16" "17" "18" "19" + "20" "21" "22" "23" "24" "25" "26" "27" "28" "29" + "30" "31" "32" "33" "34" "35" "36" "37" "38" "39" + "40" "41" "42" "43" "44" "45" "46" "47" "48" "49" + "50" "51" "52" "53" "54" "55" "56" "57" "58" "59" + "60" "61" "62" "63" "64" "65" "66" "67" "68" "69" + "70" "71" "72" "73" "74" "75" "76" "77" "78" "79" + "80" "81" "82" "83" "84" "85" "86" "87" "88" "89" + "90" "91" "92" "93" "94" "95" "96" "97" "98" "99" +); + +static const u64_t mask24 = (u64(1) << 24) - 1; +static const u64_t mask32 = (u64(1) << 32) - 1; +static const u64_t mask57 = (u64(1) << 57) - 1; + +#define COPY(buffer, digits) memcpy(buffer, &(digits), sizeof(struct digit_pair)) + +static char * +jeaiii_ultoa(char *b, u64_t n) +{ + if (n < u32(1e2)) { + COPY(b, digits_fd[n]); + return n < 10 ? b + 1 : b + 2; + } + + if (n < u32(1e6)) { + if (n < u32(1e4)) { + u32_t f0 = u32((10 * (1 << 24) / 1e3 + 1) * n); + COPY(b, digits_fd[f0 >> 24]); + + b -= n < u32(1e3); + u32_t f2 = (f0 & mask24) * 100; + COPY(b + 2, digits_dd[f2 >> 24]); + + return b + 4; + } + + u64_t f0 = u64(10 * (1ull << 32ull)/ 1e5 + 1) * n; + COPY(b, digits_fd[f0 >> 32]); + + b -= n < u32(1e5); + u64_t f2 = (f0 & mask32) * 100; + COPY(b + 2, digits_dd[f2 >> 32]); + + u64_t f4 = (f2 & mask32) * 100; + COPY(b + 4, digits_dd[f4 >> 32]); + return b + 6; + } + + if (n < u64(1ull << 32ull)) { + if (n < u32(1e8)) { + u64_t f0 = u64(10 * (1ull << 48ull) / 1e7 + 1) * n >> 16; + COPY(b, digits_fd[f0 >> 32]); + + b -= n < u32(1e7); + u64_t f2 = (f0 & mask32) * 100; + COPY(b + 2, digits_dd[f2 >> 32]); + + u64_t f4 = (f2 & mask32) * 100; + COPY(b + 4, digits_dd[f4 >> 32]); + + u64_t f6 = (f4 & mask32) * 100; + COPY(b + 6, digits_dd[f6 >> 32]); + + return b + 8; + } + + u64_t f0 = u64(10 * (1ull << 57ull) / 1e9 + 1) * n; + COPY(b, digits_fd[f0 >> 57]); + + b -= n < u32(1e9); + u64_t f2 = (f0 & mask57) * 100; + COPY(b + 2, digits_dd[f2 >> 57]); + + u64_t f4 = (f2 & mask57) * 100; + COPY(b + 4, digits_dd[f4 >> 57]); + + u64_t f6 = (f4 & mask57) * 100; + COPY(b + 6, digits_dd[f6 >> 57]); + + u64_t f8 = (f6 & mask57) * 100; + COPY(b + 8, digits_dd[f8 >> 57]); + + return b + 10; + } + + // if we get here U must be u64 but some compilers don't know that, so reassign n to a u64 to avoid warnings + u32_t z = n % u32(1e8); + u64_t u = n / u32(1e8); + + if (u < u32(1e2)) { + // u can't be 1 digit (if u < 10 it would have been handled above as a 9 digit 32bit number) + COPY(b, digits_dd[u]); + b += 2; + } + else if (u < u32(1e6)) { + if (u < u32(1e4)) { + u32_t f0 = u32((10 * (1 << 24) / 1e3 + 1) * u); + COPY(b, digits_fd[f0 >> 24]); + + b -= u < u32(1e3); + u32_t f2 = (f0 & mask24) * 100; + COPY(b + 2, digits_dd[f2 >> 24]); + b += 4; + } + else { + u64_t f0 = u64(10 * (1ull << 32ull) / 1e5 + 1) * u; + COPY(b, digits_fd[f0 >> 32]); + + b -= u < u32(1e5); + u64_t f2 = (f0 & mask32) * 100; + COPY(b + 2, digits_dd[f2 >> 32]); + + u64_t f4 = (f2 & mask32) * 100; + COPY(b + 4, digits_dd[f4 >> 32]); + b += 6; + } + } + else if (u < u32(1e8)) { + u64_t f0 = u64(10 * (1ull << 48ull) / 1e7 + 1) * u >> 16; + COPY(b, digits_fd[f0 >> 32]); + + b -= u < u32(1e7); + u64_t f2 = (f0 & mask32) * 100; + COPY(b + 2, digits_dd[f2 >> 32]); + + u64_t f4 = (f2 & mask32) * 100; + COPY(b + 4, digits_dd[f4 >> 32]); + + u64_t f6 = (f4 & mask32) * 100; + COPY(b + 6, digits_dd[f6 >> 32]); + + b += 8; + } + else if (u < u64(1ull << 32ull)) { + u64_t f0 = u64(10 * (1ull << 57ull) / 1e9 + 1) * u; + COPY(b, digits_fd[f0 >> 57]); + + b -= u < u32(1e9); + u64_t f2 = (f0 & mask57) * 100; + COPY(b + 2, digits_dd[f2 >> 57]); + + u64_t f4 = (f2 & mask57) * 100; + COPY(b + 4, digits_dd[f4 >> 57]); + + u64_t f6 = (f4 & mask57) * 100; + COPY(b + 6, digits_dd[f6 >> 57]); + + u64_t f8 = (f6 & mask57) * 100; + COPY(b + 8, digits_dd[f8 >> 57]); + b += 10; + } + else { + u32_t y = u % u32(1e8); + u /= u32(1e8); + + // u is 2, 3, or 4 digits (if u < 10 it would have been handled above) + if (u < u32(1e2)) { + COPY(b, digits_dd[u]); + b += 2; + } + else { + u32_t f0 = u32((10 * (1 << 24) / 1e3 + 1) * u); + COPY(b, digits_fd[f0 >> 24]); + + b -= u < u32(1e3); + u32_t f2 = (f0 & mask24) * 100; + COPY(b + 2, digits_dd[f2 >> 24]); + + b += 4; + } + // do 8 digits + u64_t f0 = (u64((1ull << 48ull) / 1e6 + 1) * y >> 16) + 1; + COPY(b, digits_dd[f0 >> 32]); + + u64_t f2 = (f0 & mask32) * 100; + COPY(b + 2, digits_dd[f2 >> 32]); + + u64_t f4 = (f2 & mask32) * 100; + COPY(b + 4, digits_dd[f4 >> 32]); + + u64_t f6 = (f4 & mask32) * 100; + COPY(b + 6, digits_dd[f6 >> 32]); + b += 8; + } + + // do 8 digits + u64_t f0 = (u64((1ull << 48ull) / 1e6 + 1) * z >> 16) + 1; + COPY(b, digits_dd[f0 >> 32]); + + u64_t f2 = (f0 & mask32) * 100; + COPY(b + 2, digits_dd[f2 >> 32]); + + u64_t f4 = (f2 & mask32) * 100; + COPY(b + 4, digits_dd[f4 >> 32]); + + u64_t f6 = (f4 & mask32) * 100; + COPY(b + 6, digits_dd[f6 >> 32]); + + return b + 8; +} + +#undef u32 +#undef u64 +#undef COPY + +#endif // JEAIII_TO_TEXT_H_ diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/json.gemspec b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/json.gemspec new file mode 100644 index 00000000..943c78aa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/json.gemspec @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +version = File.foreach(File.join(__dir__, "lib/json/version.rb")) do |line| + /^\s*VERSION\s*=\s*'(.*)'/ =~ line and break $1 +end rescue nil + +spec = Gem::Specification.new do |s| + java_ext = Gem::Platform === s.platform && s.platform =~ 'java' || RUBY_ENGINE == 'jruby' + + s.name = "json" + s.version = version + + s.summary = "JSON Implementation for Ruby" + s.homepage = "https://github.com/ruby/json" + s.metadata = { + 'bug_tracker_uri' => 'https://github.com/ruby/json/issues', + 'changelog_uri' => 'https://github.com/ruby/json/blob/master/CHANGES.md', + 'documentation_uri' => 'https://docs.ruby-lang.org/en/master/JSON.html', + 'homepage_uri' => s.homepage, + 'source_code_uri' => 'https://github.com/ruby/json', + } + + s.required_ruby_version = Gem::Requirement.new(">= 2.7") + + if java_ext + s.description = "A JSON implementation as a JRuby extension." + s.author = "Daniel Luz" + s.email = "dev+ruby@mernen.com" + else + s.description = "This is a JSON implementation as a Ruby extension in C." + s.authors = ["Florian Frank"] + s.email = "flori@ping.de" + end + + s.licenses = ["Ruby"] + + s.extra_rdoc_files = ["README.md"] + s.rdoc_options = ["--title", "JSON implementation for Ruby", "--main", "README.md"] + + s.files = [ + "CHANGES.md", + "COPYING", + "BSDL", + "LEGAL", + "README.md", + "json.gemspec", + *Dir["lib/**/*.rb"], + ] + + if java_ext + s.platform = 'java' + s.files += Dir["lib/json/ext/**/*.jar"] + else + s.extensions = Dir["ext/json/**/extconf.rb"] + s.files += Dir["ext/json/**/*.{c,h}"] + end +end + +if RUBY_ENGINE == 'jruby' && $0 == __FILE__ + Gem::Builder.new(spec).build +else + spec +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json.rb new file mode 100644 index 00000000..dfd9b7df --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json.rb @@ -0,0 +1,587 @@ +# frozen_string_literal: true +require 'json/common' + +## +# = JavaScript \Object Notation (\JSON) +# +# \JSON is a lightweight data-interchange format. +# +# A \JSON value is one of the following: +# - Double-quoted text: "foo". +# - Number: +1+, +1.0+, +2.0e2+. +# - Boolean: +true+, +false+. +# - Null: +null+. +# - \Array: an ordered list of values, enclosed by square brackets: +# ["foo", 1, 1.0, 2.0e2, true, false, null] +# +# - \Object: a collection of name/value pairs, enclosed by curly braces; +# each name is double-quoted text; +# the values may be any \JSON values: +# {"a": "foo", "b": 1, "c": 1.0, "d": 2.0e2, "e": true, "f": false, "g": null} +# +# A \JSON array or object may contain nested arrays, objects, and scalars +# to any depth: +# {"foo": {"bar": 1, "baz": 2}, "bat": [0, 1, 2]} +# [{"foo": 0, "bar": 1}, ["baz", 2]] +# +# == Using \Module \JSON +# +# To make module \JSON available in your code, begin with: +# require 'json' +# +# All examples here assume that this has been done. +# +# === Parsing \JSON +# +# You can parse a \String containing \JSON data using +# either of two methods: +# - JSON.parse(source, opts) +# - JSON.parse!(source, opts) +# +# where +# - +source+ is a Ruby object. +# - +opts+ is a \Hash object containing options +# that control both input allowed and output formatting. +# +# The difference between the two methods +# is that JSON.parse! omits some checks +# and may not be safe for some +source+ data; +# use it only for data from trusted sources. +# Use the safer method JSON.parse for less trusted sources. +# +# ==== Parsing \JSON Arrays +# +# When +source+ is a \JSON array, JSON.parse by default returns a Ruby \Array: +# json = '["foo", 1, 1.0, 2.0e2, true, false, null]' +# ruby = JSON.parse(json) +# ruby # => ["foo", 1, 1.0, 200.0, true, false, nil] +# ruby.class # => Array +# +# The \JSON array may contain nested arrays, objects, and scalars +# to any depth: +# json = '[{"foo": 0, "bar": 1}, ["baz", 2]]' +# JSON.parse(json) # => [{"foo"=>0, "bar"=>1}, ["baz", 2]] +# +# ==== Parsing \JSON \Objects +# +# When the source is a \JSON object, JSON.parse by default returns a Ruby \Hash: +# json = '{"a": "foo", "b": 1, "c": 1.0, "d": 2.0e2, "e": true, "f": false, "g": null}' +# ruby = JSON.parse(json) +# ruby # => {"a"=>"foo", "b"=>1, "c"=>1.0, "d"=>200.0, "e"=>true, "f"=>false, "g"=>nil} +# ruby.class # => Hash +# +# The \JSON object may contain nested arrays, objects, and scalars +# to any depth: +# json = '{"foo": {"bar": 1, "baz": 2}, "bat": [0, 1, 2]}' +# JSON.parse(json) # => {"foo"=>{"bar"=>1, "baz"=>2}, "bat"=>[0, 1, 2]} +# +# ==== Parsing \JSON Scalars +# +# When the source is a \JSON scalar (not an array or object), +# JSON.parse returns a Ruby scalar. +# +# \String: +# ruby = JSON.parse('"foo"') +# ruby # => 'foo' +# ruby.class # => String +# \Integer: +# ruby = JSON.parse('1') +# ruby # => 1 +# ruby.class # => Integer +# \Float: +# ruby = JSON.parse('1.0') +# ruby # => 1.0 +# ruby.class # => Float +# ruby = JSON.parse('2.0e2') +# ruby # => 200 +# ruby.class # => Float +# Boolean: +# ruby = JSON.parse('true') +# ruby # => true +# ruby.class # => TrueClass +# ruby = JSON.parse('false') +# ruby # => false +# ruby.class # => FalseClass +# Null: +# ruby = JSON.parse('null') +# ruby # => nil +# ruby.class # => NilClass +# +# ==== Parsing Options +# +# ====== Input Options +# +# Option +max_nesting+ (\Integer) specifies the maximum nesting depth allowed; +# defaults to +100+; specify +false+ to disable depth checking. +# +# With the default, +false+: +# source = '[0, [1, [2, [3]]]]' +# ruby = JSON.parse(source) +# ruby # => [0, [1, [2, [3]]]] +# Too deep: +# # Raises JSON::NestingError (nesting of 2 is too deep): +# JSON.parse(source, {max_nesting: 1}) +# Bad value: +# # Raises TypeError (wrong argument type Symbol (expected Fixnum)): +# JSON.parse(source, {max_nesting: :foo}) +# +# --- +# +# Option +allow_nan+ (boolean) specifies whether to allow +# NaN, Infinity, and MinusInfinity in +source+; +# defaults to +false+. +# +# With the default, +false+: +# # Raises JSON::ParserError (225: unexpected token at '[NaN]'): +# JSON.parse('[NaN]') +# # Raises JSON::ParserError (232: unexpected token at '[Infinity]'): +# JSON.parse('[Infinity]') +# # Raises JSON::ParserError (248: unexpected token at '[-Infinity]'): +# JSON.parse('[-Infinity]') +# Allow: +# source = '[NaN, Infinity, -Infinity]' +# ruby = JSON.parse(source, {allow_nan: true}) +# ruby # => [NaN, Infinity, -Infinity] +# +# ====== Output Options +# +# Option +symbolize_names+ (boolean) specifies whether returned \Hash keys +# should be Symbols; +# defaults to +false+ (use Strings). +# +# With the default, +false+: +# source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}' +# ruby = JSON.parse(source) +# ruby # => {"a"=>"foo", "b"=>1.0, "c"=>true, "d"=>false, "e"=>nil} +# Use Symbols: +# ruby = JSON.parse(source, {symbolize_names: true}) +# ruby # => {:a=>"foo", :b=>1.0, :c=>true, :d=>false, :e=>nil} +# +# --- +# +# Option +object_class+ (\Class) specifies the Ruby class to be used +# for each \JSON object; +# defaults to \Hash. +# +# With the default, \Hash: +# source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}' +# ruby = JSON.parse(source) +# ruby.class # => Hash +# Use class \OpenStruct: +# ruby = JSON.parse(source, {object_class: OpenStruct}) +# ruby # => # +# +# --- +# +# Option +array_class+ (\Class) specifies the Ruby class to be used +# for each \JSON array; +# defaults to \Array. +# +# With the default, \Array: +# source = '["foo", 1.0, true, false, null]' +# ruby = JSON.parse(source) +# ruby.class # => Array +# Use class \Set: +# ruby = JSON.parse(source, {array_class: Set}) +# ruby # => # +# +# --- +# +# Option +create_additions+ (boolean) specifies whether to use \JSON additions in parsing. +# See {\JSON Additions}[#module-JSON-label-JSON+Additions]. +# +# === Generating \JSON +# +# To generate a Ruby \String containing \JSON data, +# use method JSON.generate(source, opts), where +# - +source+ is a Ruby object. +# - +opts+ is a \Hash object containing options +# that control both input allowed and output formatting. +# +# ==== Generating \JSON from Arrays +# +# When the source is a Ruby \Array, JSON.generate returns +# a \String containing a \JSON array: +# ruby = [0, 's', :foo] +# json = JSON.generate(ruby) +# json # => '[0,"s","foo"]' +# +# The Ruby \Array array may contain nested arrays, hashes, and scalars +# to any depth: +# ruby = [0, [1, 2], {foo: 3, bar: 4}] +# json = JSON.generate(ruby) +# json # => '[0,[1,2],{"foo":3,"bar":4}]' +# +# ==== Generating \JSON from Hashes +# +# When the source is a Ruby \Hash, JSON.generate returns +# a \String containing a \JSON object: +# ruby = {foo: 0, bar: 's', baz: :bat} +# json = JSON.generate(ruby) +# json # => '{"foo":0,"bar":"s","baz":"bat"}' +# +# The Ruby \Hash array may contain nested arrays, hashes, and scalars +# to any depth: +# ruby = {foo: [0, 1], bar: {baz: 2, bat: 3}, bam: :bad} +# json = JSON.generate(ruby) +# json # => '{"foo":[0,1],"bar":{"baz":2,"bat":3},"bam":"bad"}' +# +# ==== Generating \JSON from Other Objects +# +# When the source is neither an \Array nor a \Hash, +# the generated \JSON data depends on the class of the source. +# +# When the source is a Ruby \Integer or \Float, JSON.generate returns +# a \String containing a \JSON number: +# JSON.generate(42) # => '42' +# JSON.generate(0.42) # => '0.42' +# +# When the source is a Ruby \String, JSON.generate returns +# a \String containing a \JSON string (with double-quotes): +# JSON.generate('A string') # => '"A string"' +# +# When the source is +true+, +false+ or +nil+, JSON.generate returns +# a \String containing the corresponding \JSON token: +# JSON.generate(true) # => 'true' +# JSON.generate(false) # => 'false' +# JSON.generate(nil) # => 'null' +# +# When the source is none of the above, JSON.generate returns +# a \String containing a \JSON string representation of the source: +# JSON.generate(:foo) # => '"foo"' +# JSON.generate(Complex(0, 0)) # => '"0+0i"' +# JSON.generate(Dir.new('.')) # => '"#"' +# +# ==== Generating Options +# +# ====== Input Options +# +# Option +allow_nan+ (boolean) specifies whether +# +NaN+, +Infinity+, and -Infinity may be generated; +# defaults to +false+. +# +# With the default, +false+: +# # Raises JSON::GeneratorError (920: NaN not allowed in JSON): +# JSON.generate(JSON::NaN) +# # Raises JSON::GeneratorError (917: Infinity not allowed in JSON): +# JSON.generate(JSON::Infinity) +# # Raises JSON::GeneratorError (917: -Infinity not allowed in JSON): +# JSON.generate(JSON::MinusInfinity) +# +# Allow: +# ruby = [Float::NaN, Float::Infinity, Float::MinusInfinity] +# JSON.generate(ruby, allow_nan: true) # => '[NaN,Infinity,-Infinity]' +# +# --- +# +# Option +max_nesting+ (\Integer) specifies the maximum nesting depth +# in +obj+; defaults to +100+. +# +# With the default, +100+: +# obj = [[[[[[0]]]]]] +# JSON.generate(obj) # => '[[[[[[0]]]]]]' +# +# Too deep: +# # Raises JSON::NestingError (nesting of 2 is too deep): +# JSON.generate(obj, max_nesting: 2) +# +# ====== Escaping Options +# +# Options +script_safe+ (boolean) specifies wether '\u2028', '\u2029' +# and '/' should be escaped as to make the JSON object safe to interpolate in script +# tags. +# +# Options +ascii_only+ (boolean) specifies wether all characters outside the ASCII range +# should be escaped. +# +# ====== Output Options +# +# The default formatting options generate the most compact +# \JSON data, all on one line and with no whitespace. +# +# You can use these formatting options to generate +# \JSON data in a more open format, using whitespace. +# See also JSON.pretty_generate. +# +# - Option +array_nl+ (\String) specifies a string (usually a newline) +# to be inserted after each \JSON array; defaults to the empty \String, ''. +# - Option +object_nl+ (\String) specifies a string (usually a newline) +# to be inserted after each \JSON object; defaults to the empty \String, ''. +# - Option +indent+ (\String) specifies the string (usually spaces) to be +# used for indentation; defaults to the empty \String, ''; +# defaults to the empty \String, ''; +# has no effect unless options +array_nl+ or +object_nl+ specify newlines. +# - Option +space+ (\String) specifies a string (usually a space) to be +# inserted after the colon in each \JSON object's pair; +# defaults to the empty \String, ''. +# - Option +space_before+ (\String) specifies a string (usually a space) to be +# inserted before the colon in each \JSON object's pair; +# defaults to the empty \String, ''. +# +# In this example, +obj+ is used first to generate the shortest +# \JSON data (no whitespace), then again with all formatting options +# specified: +# +# obj = {foo: [:bar, :baz], bat: {bam: 0, bad: 1}} +# json = JSON.generate(obj) +# puts 'Compact:', json +# opts = { +# array_nl: "\n", +# object_nl: "\n", +# indent: ' ', +# space_before: ' ', +# space: ' ' +# } +# puts 'Open:', JSON.generate(obj, opts) +# +# Output: +# Compact: +# {"foo":["bar","baz"],"bat":{"bam":0,"bad":1}} +# Open: +# { +# "foo" : [ +# "bar", +# "baz" +# ], +# "bat" : { +# "bam" : 0, +# "bad" : 1 +# } +# } +# +# == \JSON Additions +# +# When you "round trip" a non-\String object from Ruby to \JSON and back, +# you have a new \String, instead of the object you began with: +# ruby0 = Range.new(0, 2) +# json = JSON.generate(ruby0) +# json # => '0..2"' +# ruby1 = JSON.parse(json) +# ruby1 # => '0..2' +# ruby1.class # => String +# +# You can use \JSON _additions_ to preserve the original object. +# The addition is an extension of a ruby class, so that: +# - \JSON.generate stores more information in the \JSON string. +# - \JSON.parse, called with option +create_additions+, +# uses that information to create a proper Ruby object. +# +# This example shows a \Range being generated into \JSON +# and parsed back into Ruby, both without and with +# the addition for \Range: +# ruby = Range.new(0, 2) +# # This passage does not use the addition for Range. +# json0 = JSON.generate(ruby) +# ruby0 = JSON.parse(json0) +# # This passage uses the addition for Range. +# require 'json/add/range' +# json1 = JSON.generate(ruby) +# ruby1 = JSON.parse(json1, create_additions: true) +# # Make a nice display. +# display = <<~EOT +# Generated JSON: +# Without addition: #{json0} (#{json0.class}) +# With addition: #{json1} (#{json1.class}) +# Parsed JSON: +# Without addition: #{ruby0.inspect} (#{ruby0.class}) +# With addition: #{ruby1.inspect} (#{ruby1.class}) +# EOT +# puts display +# +# This output shows the different results: +# Generated JSON: +# Without addition: "0..2" (String) +# With addition: {"json_class":"Range","a":[0,2,false]} (String) +# Parsed JSON: +# Without addition: "0..2" (String) +# With addition: 0..2 (Range) +# +# The \JSON module includes additions for certain classes. +# You can also craft custom additions. +# See {Custom \JSON Additions}[#module-JSON-label-Custom+JSON+Additions]. +# +# === Built-in Additions +# +# The \JSON module includes additions for certain classes. +# To use an addition, +require+ its source: +# - BigDecimal: require 'json/add/bigdecimal' +# - Complex: require 'json/add/complex' +# - Date: require 'json/add/date' +# - DateTime: require 'json/add/date_time' +# - Exception: require 'json/add/exception' +# - OpenStruct: require 'json/add/ostruct' +# - Range: require 'json/add/range' +# - Rational: require 'json/add/rational' +# - Regexp: require 'json/add/regexp' +# - Set: require 'json/add/set' +# - Struct: require 'json/add/struct' +# - Symbol: require 'json/add/symbol' +# - Time: require 'json/add/time' +# +# To reduce punctuation clutter, the examples below +# show the generated \JSON via +puts+, rather than the usual +inspect+, +# +# \BigDecimal: +# require 'json/add/bigdecimal' +# ruby0 = BigDecimal(0) # 0.0 +# json = JSON.generate(ruby0) # {"json_class":"BigDecimal","b":"27:0.0"} +# ruby1 = JSON.parse(json, create_additions: true) # 0.0 +# ruby1.class # => BigDecimal +# +# \Complex: +# require 'json/add/complex' +# ruby0 = Complex(1+0i) # 1+0i +# json = JSON.generate(ruby0) # {"json_class":"Complex","r":1,"i":0} +# ruby1 = JSON.parse(json, create_additions: true) # 1+0i +# ruby1.class # Complex +# +# \Date: +# require 'json/add/date' +# ruby0 = Date.today # 2020-05-02 +# json = JSON.generate(ruby0) # {"json_class":"Date","y":2020,"m":5,"d":2,"sg":2299161.0} +# ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02 +# ruby1.class # Date +# +# \DateTime: +# require 'json/add/date_time' +# ruby0 = DateTime.now # 2020-05-02T10:38:13-05:00 +# json = JSON.generate(ruby0) # {"json_class":"DateTime","y":2020,"m":5,"d":2,"H":10,"M":38,"S":13,"of":"-5/24","sg":2299161.0} +# ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02T10:38:13-05:00 +# ruby1.class # DateTime +# +# \Exception (and its subclasses including \RuntimeError): +# require 'json/add/exception' +# ruby0 = Exception.new('A message') # A message +# json = JSON.generate(ruby0) # {"json_class":"Exception","m":"A message","b":null} +# ruby1 = JSON.parse(json, create_additions: true) # A message +# ruby1.class # Exception +# ruby0 = RuntimeError.new('Another message') # Another message +# json = JSON.generate(ruby0) # {"json_class":"RuntimeError","m":"Another message","b":null} +# ruby1 = JSON.parse(json, create_additions: true) # Another message +# ruby1.class # RuntimeError +# +# \OpenStruct: +# require 'json/add/ostruct' +# ruby0 = OpenStruct.new(name: 'Matz', language: 'Ruby') # # +# json = JSON.generate(ruby0) # {"json_class":"OpenStruct","t":{"name":"Matz","language":"Ruby"}} +# ruby1 = JSON.parse(json, create_additions: true) # # +# ruby1.class # OpenStruct +# +# \Range: +# require 'json/add/range' +# ruby0 = Range.new(0, 2) # 0..2 +# json = JSON.generate(ruby0) # {"json_class":"Range","a":[0,2,false]} +# ruby1 = JSON.parse(json, create_additions: true) # 0..2 +# ruby1.class # Range +# +# \Rational: +# require 'json/add/rational' +# ruby0 = Rational(1, 3) # 1/3 +# json = JSON.generate(ruby0) # {"json_class":"Rational","n":1,"d":3} +# ruby1 = JSON.parse(json, create_additions: true) # 1/3 +# ruby1.class # Rational +# +# \Regexp: +# require 'json/add/regexp' +# ruby0 = Regexp.new('foo') # (?-mix:foo) +# json = JSON.generate(ruby0) # {"json_class":"Regexp","o":0,"s":"foo"} +# ruby1 = JSON.parse(json, create_additions: true) # (?-mix:foo) +# ruby1.class # Regexp +# +# \Set: +# require 'json/add/set' +# ruby0 = Set.new([0, 1, 2]) # # +# json = JSON.generate(ruby0) # {"json_class":"Set","a":[0,1,2]} +# ruby1 = JSON.parse(json, create_additions: true) # # +# ruby1.class # Set +# +# \Struct: +# require 'json/add/struct' +# Customer = Struct.new(:name, :address) # Customer +# ruby0 = Customer.new("Dave", "123 Main") # # +# json = JSON.generate(ruby0) # {"json_class":"Customer","v":["Dave","123 Main"]} +# ruby1 = JSON.parse(json, create_additions: true) # # +# ruby1.class # Customer +# +# \Symbol: +# require 'json/add/symbol' +# ruby0 = :foo # foo +# json = JSON.generate(ruby0) # {"json_class":"Symbol","s":"foo"} +# ruby1 = JSON.parse(json, create_additions: true) # foo +# ruby1.class # Symbol +# +# \Time: +# require 'json/add/time' +# ruby0 = Time.now # 2020-05-02 11:28:26 -0500 +# json = JSON.generate(ruby0) # {"json_class":"Time","s":1588436906,"n":840560000} +# ruby1 = JSON.parse(json, create_additions: true) # 2020-05-02 11:28:26 -0500 +# ruby1.class # Time +# +# +# === Custom \JSON Additions +# +# In addition to the \JSON additions provided, +# you can craft \JSON additions of your own, +# either for Ruby built-in classes or for user-defined classes. +# +# Here's a user-defined class +Foo+: +# class Foo +# attr_accessor :bar, :baz +# def initialize(bar, baz) +# self.bar = bar +# self.baz = baz +# end +# end +# +# Here's the \JSON addition for it: +# # Extend class Foo with JSON addition. +# class Foo +# # Serialize Foo object with its class name and arguments +# def to_json(*args) +# { +# JSON.create_id => self.class.name, +# 'a' => [ bar, baz ] +# }.to_json(*args) +# end +# # Deserialize JSON string by constructing new Foo object with arguments. +# def self.json_create(object) +# new(*object['a']) +# end +# end +# +# Demonstration: +# require 'json' +# # This Foo object has no custom addition. +# foo0 = Foo.new(0, 1) +# json0 = JSON.generate(foo0) +# obj0 = JSON.parse(json0) +# # Lood the custom addition. +# require_relative 'foo_addition' +# # This foo has the custom addition. +# foo1 = Foo.new(0, 1) +# json1 = JSON.generate(foo1) +# obj1 = JSON.parse(json1, create_additions: true) +# # Make a nice display. +# display = <<~EOT +# Generated JSON: +# Without custom addition: #{json0} (#{json0.class}) +# With custom addition: #{json1} (#{json1.class}) +# Parsed JSON: +# Without custom addition: #{obj0.inspect} (#{obj0.class}) +# With custom addition: #{obj1.inspect} (#{obj1.class}) +# EOT +# puts display +# +# Output: +# +# Generated JSON: +# Without custom addition: "#" (String) +# With custom addition: {"json_class":"Foo","a":[0,1]} (String) +# Parsed JSON: +# Without custom addition: "#" (String) +# With custom addition: # (Foo) +# +module JSON + require 'json/version' + require 'json/ext' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/bigdecimal.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/bigdecimal.rb new file mode 100644 index 00000000..5dbc12c0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/bigdecimal.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end +begin + require 'bigdecimal' +rescue LoadError +end + +class BigDecimal + + # See #as_json. + def self.json_create(object) + BigDecimal._load object['b'] + end + + # Methods BigDecimal#as_json and +BigDecimal.json_create+ may be used + # to serialize and deserialize a \BigDecimal object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method BigDecimal#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/bigdecimal' + # x = BigDecimal(2).as_json # => {"json_class"=>"BigDecimal", "b"=>"27:0.2e1"} + # y = BigDecimal(2.0, 4).as_json # => {"json_class"=>"BigDecimal", "b"=>"36:0.2e1"} + # z = BigDecimal(Complex(2, 0)).as_json # => {"json_class"=>"BigDecimal", "b"=>"27:0.2e1"} + # + # \Method +JSON.create+ deserializes such a hash, returning a \BigDecimal object: + # + # BigDecimal.json_create(x) # => 0.2e1 + # BigDecimal.json_create(y) # => 0.2e1 + # BigDecimal.json_create(z) # => 0.2e1 + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'b' => _dump.force_encoding(Encoding::UTF_8), + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/bigdecimal' + # puts BigDecimal(2).to_json + # puts BigDecimal(2.0, 4).to_json + # puts BigDecimal(Complex(2, 0)).to_json + # + # Output: + # + # {"json_class":"BigDecimal","b":"27:0.2e1"} + # {"json_class":"BigDecimal","b":"36:0.2e1"} + # {"json_class":"BigDecimal","b":"27:0.2e1"} + # + def to_json(*args) + as_json.to_json(*args) + end +end if defined?(::BigDecimal) diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/complex.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/complex.rb new file mode 100644 index 00000000..a69002ef --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/complex.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class Complex + + # See #as_json. + def self.json_create(object) + Complex(object['r'], object['i']) + end + + # Methods Complex#as_json and +Complex.json_create+ may be used + # to serialize and deserialize a \Complex object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method Complex#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/complex' + # x = Complex(2).as_json # => {"json_class"=>"Complex", "r"=>2, "i"=>0} + # y = Complex(2.0, 4).as_json # => {"json_class"=>"Complex", "r"=>2.0, "i"=>4} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Complex object: + # + # Complex.json_create(x) # => (2+0i) + # Complex.json_create(y) # => (2.0+4i) + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'r' => real, + 'i' => imag, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/complex' + # puts Complex(2).to_json + # puts Complex(2.0, 4).to_json + # + # Output: + # + # {"json_class":"Complex","r":2,"i":0} + # {"json_class":"Complex","r":2.0,"i":4} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/core.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/core.rb new file mode 100644 index 00000000..485f097f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/core.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true +# This file requires the implementations of ruby core's custom objects for +# serialisation/deserialisation. + +require 'json/add/date' +require 'json/add/date_time' +require 'json/add/exception' +require 'json/add/range' +require 'json/add/regexp' +require 'json/add/struct' +require 'json/add/symbol' +require 'json/add/time' diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/date.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/date.rb new file mode 100644 index 00000000..66965d49 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/date.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end +require 'date' + +class Date + + # See #as_json. + def self.json_create(object) + civil(*object.values_at('y', 'm', 'd', 'sg')) + end + + alias start sg unless method_defined?(:start) + + # Methods Date#as_json and +Date.json_create+ may be used + # to serialize and deserialize a \Date object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method Date#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/date' + # x = Date.today.as_json + # # => {"json_class"=>"Date", "y"=>2023, "m"=>11, "d"=>21, "sg"=>2299161.0} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Date object: + # + # Date.json_create(x) + # # => # + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'y' => year, + 'm' => month, + 'd' => day, + 'sg' => start, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/date' + # puts Date.today.to_json + # + # Output: + # + # {"json_class":"Date","y":2023,"m":11,"d":21,"sg":2299161.0} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/date_time.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/date_time.rb new file mode 100644 index 00000000..569f6ec1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/date_time.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end +require 'date' + +class DateTime + + # See #as_json. + def self.json_create(object) + args = object.values_at('y', 'm', 'd', 'H', 'M', 'S') + of_a, of_b = object['of'].split('/') + if of_b and of_b != '0' + args << Rational(of_a.to_i, of_b.to_i) + else + args << of_a + end + args << object['sg'] + civil(*args) + end + + alias start sg unless method_defined?(:start) + + # Methods DateTime#as_json and +DateTime.json_create+ may be used + # to serialize and deserialize a \DateTime object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method DateTime#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/datetime' + # x = DateTime.now.as_json + # # => {"json_class"=>"DateTime", "y"=>2023, "m"=>11, "d"=>21, "sg"=>2299161.0} + # + # \Method +JSON.create+ deserializes such a hash, returning a \DateTime object: + # + # DateTime.json_create(x) # BUG? Raises Date::Error "invalid date" + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'y' => year, + 'm' => month, + 'd' => day, + 'H' => hour, + 'M' => min, + 'S' => sec, + 'of' => offset.to_s, + 'sg' => start, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/datetime' + # puts DateTime.now.to_json + # + # Output: + # + # {"json_class":"DateTime","y":2023,"m":11,"d":21,"sg":2299161.0} + # + def to_json(*args) + as_json.to_json(*args) + end +end + + diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/exception.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/exception.rb new file mode 100644 index 00000000..5338ff83 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/exception.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class Exception + + # See #as_json. + def self.json_create(object) + result = new(object['m']) + result.set_backtrace object['b'] + result + end + + # Methods Exception#as_json and +Exception.json_create+ may be used + # to serialize and deserialize a \Exception object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method Exception#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/exception' + # x = Exception.new('Foo').as_json # => {"json_class"=>"Exception", "m"=>"Foo", "b"=>nil} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Exception object: + # + # Exception.json_create(x) # => # + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'm' => message, + 'b' => backtrace, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/exception' + # puts Exception.new('Foo').to_json + # + # Output: + # + # {"json_class":"Exception","m":"Foo","b":null} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/ostruct.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/ostruct.rb new file mode 100644 index 00000000..534403b7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/ostruct.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end +begin + require 'ostruct' +rescue LoadError +end + +class OpenStruct + + # See #as_json. + def self.json_create(object) + new(object['t'] || object[:t]) + end + + # Methods OpenStruct#as_json and +OpenStruct.json_create+ may be used + # to serialize and deserialize a \OpenStruct object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method OpenStruct#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/ostruct' + # x = OpenStruct.new('name' => 'Rowdy', :age => nil).as_json + # # => {"json_class"=>"OpenStruct", "t"=>{:name=>'Rowdy', :age=>nil}} + # + # \Method +JSON.create+ deserializes such a hash, returning a \OpenStruct object: + # + # OpenStruct.json_create(x) + # # => # + # + def as_json(*) + klass = self.class.name + klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!" + { + JSON.create_id => klass, + 't' => table, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/ostruct' + # puts OpenStruct.new('name' => 'Rowdy', :age => nil).to_json + # + # Output: + # + # {"json_class":"OpenStruct","t":{'name':'Rowdy',"age":null}} + # + def to_json(*args) + as_json.to_json(*args) + end +end if defined?(::OpenStruct) diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/range.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/range.rb new file mode 100644 index 00000000..eb4b29a8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/range.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class Range + + # See #as_json. + def self.json_create(object) + new(*object['a']) + end + + # Methods Range#as_json and +Range.json_create+ may be used + # to serialize and deserialize a \Range object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method Range#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/range' + # x = (1..4).as_json # => {"json_class"=>"Range", "a"=>[1, 4, false]} + # y = (1...4).as_json # => {"json_class"=>"Range", "a"=>[1, 4, true]} + # z = ('a'..'d').as_json # => {"json_class"=>"Range", "a"=>["a", "d", false]} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Range object: + # + # Range.json_create(x) # => 1..4 + # Range.json_create(y) # => 1...4 + # Range.json_create(z) # => "a".."d" + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'a' => [ first, last, exclude_end? ] + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/range' + # puts (1..4).to_json + # puts (1...4).to_json + # puts ('a'..'d').to_json + # + # Output: + # + # {"json_class":"Range","a":[1,4,false]} + # {"json_class":"Range","a":[1,4,true]} + # {"json_class":"Range","a":["a","d",false]} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/rational.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/rational.rb new file mode 100644 index 00000000..1eb23147 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/rational.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class Rational + + # See #as_json. + def self.json_create(object) + Rational(object['n'], object['d']) + end + + # Methods Rational#as_json and +Rational.json_create+ may be used + # to serialize and deserialize a \Rational object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method Rational#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/rational' + # x = Rational(2, 3).as_json + # # => {"json_class"=>"Rational", "n"=>2, "d"=>3} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Rational object: + # + # Rational.json_create(x) + # # => (2/3) + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'n' => numerator, + 'd' => denominator, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/rational' + # puts Rational(2, 3).to_json + # + # Output: + # + # {"json_class":"Rational","n":2,"d":3} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/regexp.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/regexp.rb new file mode 100644 index 00000000..f033dd1d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/regexp.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class Regexp + + # See #as_json. + def self.json_create(object) + new(object['s'], object['o']) + end + + # Methods Regexp#as_json and +Regexp.json_create+ may be used + # to serialize and deserialize a \Regexp object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method Regexp#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/regexp' + # x = /foo/.as_json + # # => {"json_class"=>"Regexp", "o"=>0, "s"=>"foo"} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Regexp object: + # + # Regexp.json_create(x) # => /foo/ + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'o' => options, + 's' => source, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/regexp' + # puts /foo/.to_json + # + # Output: + # + # {"json_class":"Regexp","o":0,"s":"foo"} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/set.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/set.rb new file mode 100644 index 00000000..c521d8b9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/set.rb @@ -0,0 +1,48 @@ +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end +defined?(::Set) or require 'set' + +class Set + + # See #as_json. + def self.json_create(object) + new object['a'] + end + + # Methods Set#as_json and +Set.json_create+ may be used + # to serialize and deserialize a \Set object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method Set#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/set' + # x = Set.new(%w/foo bar baz/).as_json + # # => {"json_class"=>"Set", "a"=>["foo", "bar", "baz"]} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Set object: + # + # Set.json_create(x) # => # + # + def as_json(*) + { + JSON.create_id => self.class.name, + 'a' => to_a, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/set' + # puts Set.new(%w/foo bar baz/).to_json + # + # Output: + # + # {"json_class":"Set","a":["foo","bar","baz"]} + # + def to_json(*args) + as_json.to_json(*args) + end +end + diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/struct.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/struct.rb new file mode 100644 index 00000000..98c38d32 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/struct.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class Struct + + # See #as_json. + def self.json_create(object) + new(*object['v']) + end + + # Methods Struct#as_json and +Struct.json_create+ may be used + # to serialize and deserialize a \Struct object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method Struct#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/struct' + # Customer = Struct.new('Customer', :name, :address, :zip) + # x = Struct::Customer.new.as_json + # # => {"json_class"=>"Struct::Customer", "v"=>[nil, nil, nil]} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Struct object: + # + # Struct::Customer.json_create(x) + # # => # + # + def as_json(*) + klass = self.class.name + klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!" + { + JSON.create_id => klass, + 'v' => values, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/struct' + # Customer = Struct.new('Customer', :name, :address, :zip) + # puts Struct::Customer.new.to_json + # + # Output: + # + # {"json_class":"Struct","t":{'name':'Rowdy',"age":null}} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/symbol.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/symbol.rb new file mode 100644 index 00000000..20dd5948 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/symbol.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class Symbol + + # Methods Symbol#as_json and +Symbol.json_create+ may be used + # to serialize and deserialize a \Symbol object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method Symbol#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/symbol' + # x = :foo.as_json + # # => {"json_class"=>"Symbol", "s"=>"foo"} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Symbol object: + # + # Symbol.json_create(x) # => :foo + # + def as_json(*) + { + JSON.create_id => self.class.name, + 's' => to_s, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/symbol' + # puts :foo.to_json + # + # Output: + # + # # {"json_class":"Symbol","s":"foo"} + # + def to_json(state = nil, *a) + state = ::JSON::State.from_state(state) + if state.strict? + super + else + as_json.to_json(state, *a) + end + end + + # See #as_json. + def self.json_create(o) + o['s'].to_sym + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/time.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/time.rb new file mode 100644 index 00000000..05a1f242 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/add/time.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true +unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED + require 'json' +end + +class Time + + # See #as_json. + def self.json_create(object) + if usec = object.delete('u') # used to be tv_usec -> tv_nsec + object['n'] = usec * 1000 + end + at(object['s'], Rational(object['n'], 1000)) + end + + # Methods Time#as_json and +Time.json_create+ may be used + # to serialize and deserialize a \Time object; + # see Marshal[https://docs.ruby-lang.org/en/master/Marshal.html]. + # + # \Method Time#as_json serializes +self+, + # returning a 2-element hash representing +self+: + # + # require 'json/add/time' + # x = Time.now.as_json + # # => {"json_class"=>"Time", "s"=>1700931656, "n"=>472846644} + # + # \Method +JSON.create+ deserializes such a hash, returning a \Time object: + # + # Time.json_create(x) + # # => 2023-11-25 11:00:56.472846644 -0600 + # + def as_json(*) + { + JSON.create_id => self.class.name, + 's' => tv_sec, + 'n' => tv_nsec, + } + end + + # Returns a JSON string representing +self+: + # + # require 'json/add/time' + # puts Time.now.to_json + # + # Output: + # + # {"json_class":"Time","s":1700931678,"n":980650786} + # + def to_json(*args) + as_json.to_json(*args) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/common.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/common.rb new file mode 100644 index 00000000..6393a6df --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/common.rb @@ -0,0 +1,1104 @@ +# frozen_string_literal: true + +require 'json/version' + +module JSON + autoload :GenericObject, 'json/generic_object' + + module ParserOptions # :nodoc: + class << self + def prepare(opts) + if opts[:object_class] || opts[:array_class] + opts = opts.dup + on_load = opts[:on_load] + + on_load = object_class_proc(opts[:object_class], on_load) if opts[:object_class] + on_load = array_class_proc(opts[:array_class], on_load) if opts[:array_class] + opts[:on_load] = on_load + end + + if opts.fetch(:create_additions, false) != false + opts = create_additions_proc(opts) + end + + opts + end + + private + + def object_class_proc(object_class, on_load) + ->(obj) do + if Hash === obj + object = object_class.new + obj.each { |k, v| object[k] = v } + obj = object + end + on_load.nil? ? obj : on_load.call(obj) + end + end + + def array_class_proc(array_class, on_load) + ->(obj) do + if Array === obj + array = array_class.new + obj.each { |v| array << v } + obj = array + end + on_load.nil? ? obj : on_load.call(obj) + end + end + + # TODO: exctract :create_additions support to another gem for version 3.0 + def create_additions_proc(opts) + if opts[:symbolize_names] + raise ArgumentError, "options :symbolize_names and :create_additions cannot be used in conjunction" + end + + opts = opts.dup + create_additions = opts.fetch(:create_additions, false) + on_load = opts[:on_load] + object_class = opts[:object_class] || Hash + + opts[:on_load] = ->(object) do + case object + when String + opts[:match_string]&.each do |pattern, klass| + if match = pattern.match(object) + create_additions_warning if create_additions.nil? + object = klass.json_create(object) + break + end + end + when object_class + if opts[:create_additions] != false + if class_name = object[JSON.create_id] + klass = JSON.deep_const_get(class_name) + if (klass.respond_to?(:json_creatable?) && klass.json_creatable?) || klass.respond_to?(:json_create) + create_additions_warning if create_additions.nil? + object = klass.json_create(object) + end + end + end + end + + on_load.nil? ? object : on_load.call(object) + end + + opts + end + + GEM_ROOT = File.expand_path("../../../", __FILE__) + "/" + def create_additions_warning + message = "JSON.load implicit support for `create_additions: true` is deprecated " \ + "and will be removed in 3.0, use JSON.unsafe_load or explicitly " \ + "pass `create_additions: true`" + + uplevel = 4 + caller_locations(uplevel, 10).each do |frame| + if frame.path.nil? || frame.path.start_with?(GEM_ROOT) || frame.path.end_with?("/truffle/cext_ruby.rb", ".c") + uplevel += 1 + else + break + end + end + + if RUBY_VERSION >= "3.0" + warn(message, uplevel: uplevel - 1, category: :deprecated) + else + warn(message, uplevel: uplevel - 1) + end + end + end + end + + class << self + # :call-seq: + # JSON[object] -> new_array or new_string + # + # If +object+ is a \String, + # calls JSON.parse with +object+ and +opts+ (see method #parse): + # json = '[0, 1, null]' + # JSON[json]# => [0, 1, nil] + # + # Otherwise, calls JSON.generate with +object+ and +opts+ (see method #generate): + # ruby = [0, 1, nil] + # JSON[ruby] # => '[0,1,null]' + def [](object, opts = nil) + if object.is_a?(String) + return JSON.parse(object, opts) + elsif object.respond_to?(:to_str) + str = object.to_str + if str.is_a?(String) + return JSON.parse(str, opts) + end + end + + JSON.generate(object, opts) + end + + # Returns the JSON parser class that is used by JSON. + attr_reader :parser + + # Set the JSON parser class _parser_ to be used by JSON. + def parser=(parser) # :nodoc: + @parser = parser + remove_const :Parser if const_defined?(:Parser, false) + const_set :Parser, parser + end + + # Return the constant located at _path_. The format of _path_ has to be + # either ::A::B::C or A::B::C. In any case, A has to be located at the top + # level (absolute namespace path?). If there doesn't exist a constant at + # the given path, an ArgumentError is raised. + def deep_const_get(path) # :nodoc: + Object.const_get(path) + rescue NameError => e + raise ArgumentError, "can't get const #{path}: #{e}" + end + + # Set the module _generator_ to be used by JSON. + def generator=(generator) # :nodoc: + old, $VERBOSE = $VERBOSE, nil + @generator = generator + generator_methods = generator::GeneratorMethods + for const in generator_methods.constants + klass = const_get(const) + modul = generator_methods.const_get(const) + klass.class_eval do + instance_methods(false).each do |m| + m.to_s == 'to_json' and remove_method m + end + include modul + end + end + self.state = generator::State + const_set :State, state + ensure + $VERBOSE = old + end + + # Returns the JSON generator module that is used by JSON. + attr_reader :generator + + # Sets or Returns the JSON generator state class that is used by JSON. + attr_accessor :state + + private + + def deprecated_singleton_attr_accessor(*attrs) + args = RUBY_VERSION >= "3.0" ? ", category: :deprecated" : "" + attrs.each do |attr| + singleton_class.class_eval <<~RUBY + def #{attr} + warn "JSON.#{attr} is deprecated and will be removed in json 3.0.0", uplevel: 1 #{args} + @#{attr} + end + + def #{attr}=(val) + warn "JSON.#{attr}= is deprecated and will be removed in json 3.0.0", uplevel: 1 #{args} + @#{attr} = val + end + + def _#{attr} + @#{attr} + end + RUBY + end + end + end + + # Sets create identifier, which is used to decide if the _json_create_ + # hook of a class should be called; initial value is +json_class+: + # JSON.create_id # => 'json_class' + def self.create_id=(new_value) + Thread.current[:"JSON.create_id"] = new_value.dup.freeze + end + + # Returns the current create identifier. + # See also JSON.create_id=. + def self.create_id + Thread.current[:"JSON.create_id"] || 'json_class' + end + + NaN = Float::NAN + + Infinity = Float::INFINITY + + MinusInfinity = -Infinity + + # The base exception for JSON errors. + class JSONError < StandardError; end + + # This exception is raised if a parser error occurs. + class ParserError < JSONError + attr_reader :line, :column + end + + # This exception is raised if the nesting of parsed data structures is too + # deep. + class NestingError < ParserError; end + + # This exception is raised if a generator or unparser error occurs. + class GeneratorError < JSONError + attr_reader :invalid_object + + def initialize(message, invalid_object = nil) + super(message) + @invalid_object = invalid_object + end + + def detailed_message(...) + # Exception#detailed_message doesn't exist until Ruby 3.2 + super_message = defined?(super) ? super : message + + if @invalid_object.nil? + super_message + else + "#{super_message}\nInvalid object: #{@invalid_object.inspect}" + end + end + end + + # Fragment of JSON document that is to be included as is: + # fragment = JSON::Fragment.new("[1, 2, 3]") + # JSON.generate({ count: 3, items: fragments }) + # + # This allows to easily assemble multiple JSON fragments that have + # been persisted somewhere without having to parse them nor resorting + # to string interpolation. + # + # Note: no validation is performed on the provided string. It is the + # responsability of the caller to ensure the string contains valid JSON. + Fragment = Struct.new(:json) do + def initialize(json) + unless string = String.try_convert(json) + raise TypeError, " no implicit conversion of #{json.class} into String" + end + + super(string) + end + + def to_json(state = nil, *) + json + end + end + + module_function + + # :call-seq: + # JSON.parse(source, opts) -> object + # + # Returns the Ruby objects created by parsing the given +source+. + # + # Argument +source+ contains the \String to be parsed. + # + # Argument +opts+, if given, contains a \Hash of options for the parsing. + # See {Parsing Options}[#module-JSON-label-Parsing+Options]. + # + # --- + # + # When +source+ is a \JSON array, returns a Ruby \Array: + # source = '["foo", 1.0, true, false, null]' + # ruby = JSON.parse(source) + # ruby # => ["foo", 1.0, true, false, nil] + # ruby.class # => Array + # + # When +source+ is a \JSON object, returns a Ruby \Hash: + # source = '{"a": "foo", "b": 1.0, "c": true, "d": false, "e": null}' + # ruby = JSON.parse(source) + # ruby # => {"a"=>"foo", "b"=>1.0, "c"=>true, "d"=>false, "e"=>nil} + # ruby.class # => Hash + # + # For examples of parsing for all \JSON data types, see + # {Parsing \JSON}[#module-JSON-label-Parsing+JSON]. + # + # Parses nested JSON objects: + # source = <<~JSON + # { + # "name": "Dave", + # "age" :40, + # "hats": [ + # "Cattleman's", + # "Panama", + # "Tophat" + # ] + # } + # JSON + # ruby = JSON.parse(source) + # ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]} + # + # --- + # + # Raises an exception if +source+ is not valid JSON: + # # Raises JSON::ParserError (783: unexpected token at ''): + # JSON.parse('') + # + def parse(source, opts = nil) + opts = ParserOptions.prepare(opts) unless opts.nil? + Parser.parse(source, opts) + end + + PARSE_L_OPTIONS = { + max_nesting: false, + allow_nan: true, + }.freeze + private_constant :PARSE_L_OPTIONS + + # :call-seq: + # JSON.parse!(source, opts) -> object + # + # Calls + # parse(source, opts) + # with +source+ and possibly modified +opts+. + # + # Differences from JSON.parse: + # - Option +max_nesting+, if not provided, defaults to +false+, + # which disables checking for nesting depth. + # - Option +allow_nan+, if not provided, defaults to +true+. + def parse!(source, opts = nil) + if opts.nil? + parse(source, PARSE_L_OPTIONS) + else + parse(source, PARSE_L_OPTIONS.merge(opts)) + end + end + + # :call-seq: + # JSON.load_file(path, opts={}) -> object + # + # Calls: + # parse(File.read(path), opts) + # + # See method #parse. + def load_file(filespec, opts = nil) + parse(File.read(filespec, encoding: Encoding::UTF_8), opts) + end + + # :call-seq: + # JSON.load_file!(path, opts = {}) + # + # Calls: + # JSON.parse!(File.read(path, opts)) + # + # See method #parse! + def load_file!(filespec, opts = nil) + parse!(File.read(filespec, encoding: Encoding::UTF_8), opts) + end + + # :call-seq: + # JSON.generate(obj, opts = nil) -> new_string + # + # Returns a \String containing the generated \JSON data. + # + # See also JSON.fast_generate, JSON.pretty_generate. + # + # Argument +obj+ is the Ruby object to be converted to \JSON. + # + # Argument +opts+, if given, contains a \Hash of options for the generation. + # See {Generating Options}[#module-JSON-label-Generating+Options]. + # + # --- + # + # When +obj+ is an \Array, returns a \String containing a \JSON array: + # obj = ["foo", 1.0, true, false, nil] + # json = JSON.generate(obj) + # json # => '["foo",1.0,true,false,null]' + # + # When +obj+ is a \Hash, returns a \String containing a \JSON object: + # obj = {foo: 0, bar: 's', baz: :bat} + # json = JSON.generate(obj) + # json # => '{"foo":0,"bar":"s","baz":"bat"}' + # + # For examples of generating from other Ruby objects, see + # {Generating \JSON from Other Objects}[#module-JSON-label-Generating+JSON+from+Other+Objects]. + # + # --- + # + # Raises an exception if any formatting option is not a \String. + # + # Raises an exception if +obj+ contains circular references: + # a = []; b = []; a.push(b); b.push(a) + # # Raises JSON::NestingError (nesting of 100 is too deep): + # JSON.generate(a) + # + def generate(obj, opts = nil) + if State === opts + opts.generate(obj) + else + State.generate(obj, opts, nil) + end + end + + # :call-seq: + # JSON.fast_generate(obj, opts) -> new_string + # + # Arguments +obj+ and +opts+ here are the same as + # arguments +obj+ and +opts+ in JSON.generate. + # + # By default, generates \JSON data without checking + # for circular references in +obj+ (option +max_nesting+ set to +false+, disabled). + # + # Raises an exception if +obj+ contains circular references: + # a = []; b = []; a.push(b); b.push(a) + # # Raises SystemStackError (stack level too deep): + # JSON.fast_generate(a) + def fast_generate(obj, opts = nil) + if RUBY_VERSION >= "3.0" + warn "JSON.fast_generate is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1, category: :deprecated + else + warn "JSON.fast_generate is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1 + end + generate(obj, opts) + end + + PRETTY_GENERATE_OPTIONS = { + indent: ' ', + space: ' ', + object_nl: "\n", + array_nl: "\n", + }.freeze + private_constant :PRETTY_GENERATE_OPTIONS + + # :call-seq: + # JSON.pretty_generate(obj, opts = nil) -> new_string + # + # Arguments +obj+ and +opts+ here are the same as + # arguments +obj+ and +opts+ in JSON.generate. + # + # Default options are: + # { + # indent: ' ', # Two spaces + # space: ' ', # One space + # array_nl: "\n", # Newline + # object_nl: "\n" # Newline + # } + # + # Example: + # obj = {foo: [:bar, :baz], bat: {bam: 0, bad: 1}} + # json = JSON.pretty_generate(obj) + # puts json + # Output: + # { + # "foo": [ + # "bar", + # "baz" + # ], + # "bat": { + # "bam": 0, + # "bad": 1 + # } + # } + # + def pretty_generate(obj, opts = nil) + return opts.generate(obj) if State === opts + + options = PRETTY_GENERATE_OPTIONS + + if opts + unless opts.is_a?(Hash) + if opts.respond_to? :to_hash + opts = opts.to_hash + elsif opts.respond_to? :to_h + opts = opts.to_h + else + raise TypeError, "can't convert #{opts.class} into Hash" + end + end + options = options.merge(opts) + end + + State.generate(obj, options, nil) + end + + # Sets or returns default options for the JSON.unsafe_load method. + # Initially: + # opts = JSON.load_default_options + # opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true} + deprecated_singleton_attr_accessor :unsafe_load_default_options + + @unsafe_load_default_options = { + :max_nesting => false, + :allow_nan => true, + :allow_blank => true, + :create_additions => true, + } + + # Sets or returns default options for the JSON.load method. + # Initially: + # opts = JSON.load_default_options + # opts # => {:max_nesting=>false, :allow_nan=>true, :allow_blank=>true, :create_additions=>true} + deprecated_singleton_attr_accessor :load_default_options + + @load_default_options = { + :allow_nan => true, + :allow_blank => true, + :create_additions => nil, + } + # :call-seq: + # JSON.unsafe_load(source, proc = nil, options = {}) -> object + # + # Returns the Ruby objects created by parsing the given +source+. + # + # BEWARE: This method is meant to serialise data from trusted user input, + # like from your own database server or clients under your control, it could + # be dangerous to allow untrusted users to pass JSON sources into it. + # + # - Argument +source+ must be, or be convertible to, a \String: + # - If +source+ responds to instance method +to_str+, + # source.to_str becomes the source. + # - If +source+ responds to instance method +to_io+, + # source.to_io.read becomes the source. + # - If +source+ responds to instance method +read+, + # source.read becomes the source. + # - If both of the following are true, source becomes the \String 'null': + # - Option +allow_blank+ specifies a truthy value. + # - The source, as defined above, is +nil+ or the empty \String ''. + # - Otherwise, +source+ remains the source. + # - Argument +proc+, if given, must be a \Proc that accepts one argument. + # It will be called recursively with each result (depth-first order). + # See details below. + # - Argument +opts+, if given, contains a \Hash of options for the parsing. + # See {Parsing Options}[#module-JSON-label-Parsing+Options]. + # The default options can be changed via method JSON.unsafe_load_default_options=. + # + # --- + # + # When no +proc+ is given, modifies +source+ as above and returns the result of + # parse(source, opts); see #parse. + # + # Source for following examples: + # source = <<~JSON + # { + # "name": "Dave", + # "age" :40, + # "hats": [ + # "Cattleman's", + # "Panama", + # "Tophat" + # ] + # } + # JSON + # + # Load a \String: + # ruby = JSON.unsafe_load(source) + # ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]} + # + # Load an \IO object: + # require 'stringio' + # object = JSON.unsafe_load(StringIO.new(source)) + # object # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]} + # + # Load a \File object: + # path = 't.json' + # File.write(path, source) + # File.open(path) do |file| + # JSON.unsafe_load(file) + # end # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]} + # + # --- + # + # When +proc+ is given: + # - Modifies +source+ as above. + # - Gets the +result+ from calling parse(source, opts). + # - Recursively calls proc(result). + # - Returns the final result. + # + # Example: + # require 'json' + # + # # Some classes for the example. + # class Base + # def initialize(attributes) + # @attributes = attributes + # end + # end + # class User < Base; end + # class Account < Base; end + # class Admin < Base; end + # # The JSON source. + # json = <<-EOF + # { + # "users": [ + # {"type": "User", "username": "jane", "email": "jane@example.com"}, + # {"type": "User", "username": "john", "email": "john@example.com"} + # ], + # "accounts": [ + # {"account": {"type": "Account", "paid": true, "account_id": "1234"}}, + # {"account": {"type": "Account", "paid": false, "account_id": "1235"}} + # ], + # "admins": {"type": "Admin", "password": "0wn3d"} + # } + # EOF + # # Deserializer method. + # def deserialize_obj(obj, safe_types = %w(User Account Admin)) + # type = obj.is_a?(Hash) && obj["type"] + # safe_types.include?(type) ? Object.const_get(type).new(obj) : obj + # end + # # Call to JSON.unsafe_load + # ruby = JSON.unsafe_load(json, proc {|obj| + # case obj + # when Hash + # obj.each {|k, v| obj[k] = deserialize_obj v } + # when Array + # obj.map! {|v| deserialize_obj v } + # end + # }) + # pp ruby + # Output: + # {"users"=> + # [#"User", "username"=>"jane", "email"=>"jane@example.com"}>, + # #"User", "username"=>"john", "email"=>"john@example.com"}>], + # "accounts"=> + # [{"account"=> + # #"Account", "paid"=>true, "account_id"=>"1234"}>}, + # {"account"=> + # #"Account", "paid"=>false, "account_id"=>"1235"}>}], + # "admins"=> + # #"Admin", "password"=>"0wn3d"}>} + # + def unsafe_load(source, proc = nil, options = nil) + opts = if options.nil? + _unsafe_load_default_options + else + _unsafe_load_default_options.merge(options) + end + + unless source.is_a?(String) + if source.respond_to? :to_str + source = source.to_str + elsif source.respond_to? :to_io + source = source.to_io.read + elsif source.respond_to?(:read) + source = source.read + end + end + + if opts[:allow_blank] && (source.nil? || source.empty?) + source = 'null' + end + result = parse(source, opts) + recurse_proc(result, &proc) if proc + result + end + + # :call-seq: + # JSON.load(source, proc = nil, options = {}) -> object + # + # Returns the Ruby objects created by parsing the given +source+. + # + # BEWARE: This method is meant to serialise data from trusted user input, + # like from your own database server or clients under your control, it could + # be dangerous to allow untrusted users to pass JSON sources into it. + # If you must use it, use JSON.unsafe_load instead to make it clear. + # + # Since JSON version 2.8.0, `load` emits a deprecation warning when a + # non native type is deserialized, without `create_additions` being explicitly + # enabled, and in JSON version 3.0, `load` will have `create_additions` disabled + # by default. + # + # - Argument +source+ must be, or be convertible to, a \String: + # - If +source+ responds to instance method +to_str+, + # source.to_str becomes the source. + # - If +source+ responds to instance method +to_io+, + # source.to_io.read becomes the source. + # - If +source+ responds to instance method +read+, + # source.read becomes the source. + # - If both of the following are true, source becomes the \String 'null': + # - Option +allow_blank+ specifies a truthy value. + # - The source, as defined above, is +nil+ or the empty \String ''. + # - Otherwise, +source+ remains the source. + # - Argument +proc+, if given, must be a \Proc that accepts one argument. + # It will be called recursively with each result (depth-first order). + # See details below. + # - Argument +opts+, if given, contains a \Hash of options for the parsing. + # See {Parsing Options}[#module-JSON-label-Parsing+Options]. + # The default options can be changed via method JSON.load_default_options=. + # + # --- + # + # When no +proc+ is given, modifies +source+ as above and returns the result of + # parse(source, opts); see #parse. + # + # Source for following examples: + # source = <<~JSON + # { + # "name": "Dave", + # "age" :40, + # "hats": [ + # "Cattleman's", + # "Panama", + # "Tophat" + # ] + # } + # JSON + # + # Load a \String: + # ruby = JSON.load(source) + # ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]} + # + # Load an \IO object: + # require 'stringio' + # object = JSON.load(StringIO.new(source)) + # object # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]} + # + # Load a \File object: + # path = 't.json' + # File.write(path, source) + # File.open(path) do |file| + # JSON.load(file) + # end # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]} + # + # --- + # + # When +proc+ is given: + # - Modifies +source+ as above. + # - Gets the +result+ from calling parse(source, opts). + # - Recursively calls proc(result). + # - Returns the final result. + # + # Example: + # require 'json' + # + # # Some classes for the example. + # class Base + # def initialize(attributes) + # @attributes = attributes + # end + # end + # class User < Base; end + # class Account < Base; end + # class Admin < Base; end + # # The JSON source. + # json = <<-EOF + # { + # "users": [ + # {"type": "User", "username": "jane", "email": "jane@example.com"}, + # {"type": "User", "username": "john", "email": "john@example.com"} + # ], + # "accounts": [ + # {"account": {"type": "Account", "paid": true, "account_id": "1234"}}, + # {"account": {"type": "Account", "paid": false, "account_id": "1235"}} + # ], + # "admins": {"type": "Admin", "password": "0wn3d"} + # } + # EOF + # # Deserializer method. + # def deserialize_obj(obj, safe_types = %w(User Account Admin)) + # type = obj.is_a?(Hash) && obj["type"] + # safe_types.include?(type) ? Object.const_get(type).new(obj) : obj + # end + # # Call to JSON.load + # ruby = JSON.load(json, proc {|obj| + # case obj + # when Hash + # obj.each {|k, v| obj[k] = deserialize_obj v } + # when Array + # obj.map! {|v| deserialize_obj v } + # end + # }) + # pp ruby + # Output: + # {"users"=> + # [#"User", "username"=>"jane", "email"=>"jane@example.com"}>, + # #"User", "username"=>"john", "email"=>"john@example.com"}>], + # "accounts"=> + # [{"account"=> + # #"Account", "paid"=>true, "account_id"=>"1234"}>}, + # {"account"=> + # #"Account", "paid"=>false, "account_id"=>"1235"}>}], + # "admins"=> + # #"Admin", "password"=>"0wn3d"}>} + # + def load(source, proc = nil, options = nil) + opts = if options.nil? + _load_default_options + else + _load_default_options.merge(options) + end + + unless source.is_a?(String) + if source.respond_to? :to_str + source = source.to_str + elsif source.respond_to? :to_io + source = source.to_io.read + elsif source.respond_to?(:read) + source = source.read + end + end + + if opts[:allow_blank] && (source.nil? || source.empty?) + source = 'null' + end + + if proc + opts = opts.dup + opts[:on_load] = proc.to_proc + end + + parse(source, opts) + end + + # Sets or returns the default options for the JSON.dump method. + # Initially: + # opts = JSON.dump_default_options + # opts # => {:max_nesting=>false, :allow_nan=>true} + deprecated_singleton_attr_accessor :dump_default_options + @dump_default_options = { + :max_nesting => false, + :allow_nan => true, + } + + # :call-seq: + # JSON.dump(obj, io = nil, limit = nil) + # + # Dumps +obj+ as a \JSON string, i.e. calls generate on the object and returns the result. + # + # The default options can be changed via method JSON.dump_default_options. + # + # - Argument +io+, if given, should respond to method +write+; + # the \JSON \String is written to +io+, and +io+ is returned. + # If +io+ is not given, the \JSON \String is returned. + # - Argument +limit+, if given, is passed to JSON.generate as option +max_nesting+. + # + # --- + # + # When argument +io+ is not given, returns the \JSON \String generated from +obj+: + # obj = {foo: [0, 1], bar: {baz: 2, bat: 3}, bam: :bad} + # json = JSON.dump(obj) + # json # => "{\"foo\":[0,1],\"bar\":{\"baz\":2,\"bat\":3},\"bam\":\"bad\"}" + # + # When argument +io+ is given, writes the \JSON \String to +io+ and returns +io+: + # path = 't.json' + # File.open(path, 'w') do |file| + # JSON.dump(obj, file) + # end # => # + # puts File.read(path) + # Output: + # {"foo":[0,1],"bar":{"baz":2,"bat":3},"bam":"bad"} + def dump(obj, anIO = nil, limit = nil, kwargs = nil) + if kwargs.nil? + if limit.nil? + if anIO.is_a?(Hash) + kwargs = anIO + anIO = nil + end + elsif limit.is_a?(Hash) + kwargs = limit + limit = nil + end + end + + unless anIO.nil? + if anIO.respond_to?(:to_io) + anIO = anIO.to_io + elsif limit.nil? && !anIO.respond_to?(:write) + anIO, limit = nil, anIO + end + end + + opts = JSON._dump_default_options + opts = opts.merge(:max_nesting => limit) if limit + opts = opts.merge(kwargs) if kwargs + + begin + State.generate(obj, opts, anIO) + rescue JSON::NestingError + raise ArgumentError, "exceed depth limit" + end + end + + # :stopdoc: + # All these were meant to be deprecated circa 2009, but were just set as undocumented + # so usage still exist in the wild. + def unparse(...) + if RUBY_VERSION >= "3.0" + warn "JSON.unparse is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1, category: :deprecated + else + warn "JSON.unparse is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1 + end + generate(...) + end + module_function :unparse + + def fast_unparse(...) + if RUBY_VERSION >= "3.0" + warn "JSON.fast_unparse is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1, category: :deprecated + else + warn "JSON.fast_unparse is deprecated and will be removed in json 3.0.0, just use JSON.generate", uplevel: 1 + end + generate(...) + end + module_function :fast_unparse + + def pretty_unparse(...) + if RUBY_VERSION >= "3.0" + warn "JSON.pretty_unparse is deprecated and will be removed in json 3.0.0, just use JSON.pretty_generate", uplevel: 1, category: :deprecated + else + warn "JSON.pretty_unparse is deprecated and will be removed in json 3.0.0, just use JSON.pretty_generate", uplevel: 1 + end + pretty_generate(...) + end + module_function :fast_unparse + + def restore(...) + if RUBY_VERSION >= "3.0" + warn "JSON.restore is deprecated and will be removed in json 3.0.0, just use JSON.load", uplevel: 1, category: :deprecated + else + warn "JSON.restore is deprecated and will be removed in json 3.0.0, just use JSON.load", uplevel: 1 + end + load(...) + end + module_function :restore + + class << self + private + + def const_missing(const_name) + case const_name + when :PRETTY_STATE_PROTOTYPE + if RUBY_VERSION >= "3.0" + warn "JSON::PRETTY_STATE_PROTOTYPE is deprecated and will be removed in json 3.0.0, just use JSON.pretty_generate", uplevel: 1, category: :deprecated + else + warn "JSON::PRETTY_STATE_PROTOTYPE is deprecated and will be removed in json 3.0.0, just use JSON.pretty_generate", uplevel: 1 + end + state.new(PRETTY_GENERATE_OPTIONS) + else + super + end + end + end + # :startdoc: + + # JSON::Coder holds a parser and generator configuration. + # + # module MyApp + # JSONC_CODER = JSON::Coder.new( + # allow_trailing_comma: true + # ) + # end + # + # MyApp::JSONC_CODER.load(document) + # + class Coder + # :call-seq: + # JSON.new(options = nil, &block) + # + # Argument +options+, if given, contains a \Hash of options for both parsing and generating. + # See {Parsing Options}[#module-JSON-label-Parsing+Options], and {Generating Options}[#module-JSON-label-Generating+Options]. + # + # For generation, the strict: true option is always set. When a Ruby object with no native \JSON counterpart is + # encoutered, the block provided to the initialize method is invoked, and must return a Ruby object that has a native + # \JSON counterpart: + # + # module MyApp + # API_JSON_CODER = JSON::Coder.new do |object| + # case object + # when Time + # object.iso8601(3) + # else + # object # Unknown type, will raise + # end + # end + # end + # + # puts MyApp::API_JSON_CODER.dump(Time.now.utc) # => "2025-01-21T08:41:44.286Z" + # + def initialize(options = nil, &as_json) + if options.nil? + options = { strict: true } + else + options = options.dup + options[:strict] = true + end + options[:as_json] = as_json if as_json + + @state = State.new(options).freeze + @parser_config = Ext::Parser::Config.new(ParserOptions.prepare(options)) + end + + # call-seq: + # dump(object) -> String + # dump(object, io) -> io + # + # Serialize the given object into a \JSON document. + def dump(object, io = nil) + @state.generate_new(object, io) + end + alias_method :generate, :dump + + # call-seq: + # load(string) -> Object + # + # Parse the given \JSON document and return an equivalent Ruby object. + def load(source) + @parser_config.parse(source) + end + alias_method :parse, :load + + # call-seq: + # load(path) -> Object + # + # Parse the given \JSON document and return an equivalent Ruby object. + def load_file(path) + load(File.read(path, encoding: Encoding::UTF_8)) + end + end +end + +module ::Kernel + private + + # Outputs _objs_ to STDOUT as JSON strings in the shortest form, that is in + # one line. + def j(*objs) + if RUBY_VERSION >= "3.0" + warn "Kernel#j is deprecated and will be removed in json 3.0.0", uplevel: 1, category: :deprecated + else + warn "Kernel#j is deprecated and will be removed in json 3.0.0", uplevel: 1 + end + + objs.each do |obj| + puts JSON.generate(obj, :allow_nan => true, :max_nesting => false) + end + nil + end + + # Outputs _objs_ to STDOUT as JSON strings in a pretty format, with + # indentation and over many lines. + def jj(*objs) + if RUBY_VERSION >= "3.0" + warn "Kernel#jj is deprecated and will be removed in json 3.0.0", uplevel: 1, category: :deprecated + else + warn "Kernel#jj is deprecated and will be removed in json 3.0.0", uplevel: 1 + end + + objs.each do |obj| + puts JSON.pretty_generate(obj, :allow_nan => true, :max_nesting => false) + end + nil + end + + # If _object_ is string-like, parse the string and return the parsed result as + # a Ruby data structure. Otherwise, generate a JSON text from the Ruby data + # structure object and return it. + # + # The _opts_ argument is passed through to generate/parse respectively. See + # generate and parse for their documentation. + def JSON(object, opts = nil) + JSON[object, opts] + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/ext.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/ext.rb new file mode 100644 index 00000000..5bacc5e3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/ext.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'json/common' + +module JSON + # This module holds all the modules/classes that implement JSON's + # functionality as C extensions. + module Ext + class Parser + class << self + def parse(...) + new(...).parse + end + alias_method :parse, :parse # Allow redefinition by extensions + end + + def initialize(source, opts = nil) + @source = source + @config = Config.new(opts) + end + + def source + @source.dup + end + + def parse + @config.parse(@source) + end + end + + require 'json/ext/parser' + Ext::Parser::Config = Ext::ParserConfig + JSON.parser = Ext::Parser + + if RUBY_ENGINE == 'truffleruby' + require 'json/truffle_ruby/generator' + JSON.generator = JSON::TruffleRuby::Generator + else + require 'json/ext/generator' + JSON.generator = Generator + end + end + + JSON_LOADED = true unless defined?(JSON::JSON_LOADED) +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/ext/generator.so b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/ext/generator.so new file mode 100755 index 00000000..bbb87731 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/ext/generator.so differ diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/ext/generator/state.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/ext/generator/state.rb new file mode 100644 index 00000000..d40c3b5e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/ext/generator/state.rb @@ -0,0 +1,106 @@ +# frozen_string_literal: true + +module JSON + module Ext + module Generator + class State + # call-seq: new(opts = {}) + # + # Instantiates a new State object, configured by _opts_. + # + # _opts_ can have the following keys: + # + # * *indent*: a string used to indent levels (default: ''), + # * *space*: a string that is put after, a : or , delimiter (default: ''), + # * *space_before*: a string that is put before a : pair delimiter (default: ''), + # * *object_nl*: a string that is put at the end of a JSON object (default: ''), + # * *array_nl*: a string that is put at the end of a JSON array (default: ''), + # * *allow_nan*: true if NaN, Infinity, and -Infinity should be + # generated, otherwise an exception is thrown, if these values are + # encountered. This options defaults to false. + # * *ascii_only*: true if only ASCII characters should be generated. This + # option defaults to false. + # * *buffer_initial_length*: sets the initial length of the generator's + # internal buffer. + def initialize(opts = nil) + if opts && !opts.empty? + configure(opts) + end + end + + # call-seq: configure(opts) + # + # Configure this State instance with the Hash _opts_, and return + # itself. + def configure(opts) + unless opts.is_a?(Hash) + if opts.respond_to?(:to_hash) + opts = opts.to_hash + elsif opts.respond_to?(:to_h) + opts = opts.to_h + else + raise TypeError, "can't convert #{opts.class} into Hash" + end + end + _configure(opts) + end + + alias_method :merge, :configure + + # call-seq: to_h + # + # Returns the configuration instance variables as a hash, that can be + # passed to the configure method. + def to_h + result = { + indent: indent, + space: space, + space_before: space_before, + object_nl: object_nl, + array_nl: array_nl, + as_json: as_json, + allow_nan: allow_nan?, + ascii_only: ascii_only?, + max_nesting: max_nesting, + script_safe: script_safe?, + strict: strict?, + depth: depth, + buffer_initial_length: buffer_initial_length, + } + + instance_variables.each do |iv| + iv = iv.to_s[1..-1] + result[iv.to_sym] = self[iv] + end + + result + end + + alias_method :to_hash, :to_h + + # call-seq: [](name) + # + # Returns the value returned by method +name+. + def [](name) + if respond_to?(name) + __send__(name) + else + instance_variable_get("@#{name}") if + instance_variables.include?("@#{name}".to_sym) # avoid warning + end + end + + # call-seq: []=(name, value) + # + # Sets the attribute name to value. + def []=(name, value) + if respond_to?(name_writer = "#{name}=") + __send__ name_writer, value + else + instance_variable_set "@#{name}", value + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/ext/parser.so b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/ext/parser.so new file mode 100755 index 00000000..008c1296 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/ext/parser.so differ diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/generic_object.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/generic_object.rb new file mode 100644 index 00000000..ec5aa9dc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/generic_object.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true +begin + require 'ostruct' +rescue LoadError + warn "JSON::GenericObject requires 'ostruct'. Please install it with `gem install ostruct`." +end + +module JSON + class GenericObject < OpenStruct + class << self + alias [] new + + def json_creatable? + @json_creatable + end + + attr_writer :json_creatable + + def json_create(data) + data = data.dup + data.delete JSON.create_id + self[data] + end + + def from_hash(object) + case + when object.respond_to?(:to_hash) + result = new + object.to_hash.each do |key, value| + result[key] = from_hash(value) + end + result + when object.respond_to?(:to_ary) + object.to_ary.map { |a| from_hash(a) } + else + object + end + end + + def load(source, proc = nil, opts = {}) + result = ::JSON.load(source, proc, opts.merge(:object_class => self)) + result.nil? ? new : result + end + + def dump(obj, *args) + ::JSON.dump(obj, *args) + end + end + self.json_creatable = false + + def to_hash + table + end + + def [](name) + __send__(name) + end unless method_defined?(:[]) + + def []=(name, value) + __send__("#{name}=", value) + end unless method_defined?(:[]=) + + def |(other) + self.class[other.to_hash.merge(to_hash)] + end + + def as_json(*) + { JSON.create_id => self.class.name }.merge to_hash + end + + def to_json(*a) + as_json.to_json(*a) + end + end if defined?(::OpenStruct) +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/truffle_ruby/generator.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/truffle_ruby/generator.rb new file mode 100644 index 00000000..c814106d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/truffle_ruby/generator.rb @@ -0,0 +1,690 @@ +# frozen_string_literal: true +module JSON + module TruffleRuby + module Generator + MAP = { + "\x0" => '\u0000', + "\x1" => '\u0001', + "\x2" => '\u0002', + "\x3" => '\u0003', + "\x4" => '\u0004', + "\x5" => '\u0005', + "\x6" => '\u0006', + "\x7" => '\u0007', + "\b" => '\b', + "\t" => '\t', + "\n" => '\n', + "\xb" => '\u000b', + "\f" => '\f', + "\r" => '\r', + "\xe" => '\u000e', + "\xf" => '\u000f', + "\x10" => '\u0010', + "\x11" => '\u0011', + "\x12" => '\u0012', + "\x13" => '\u0013', + "\x14" => '\u0014', + "\x15" => '\u0015', + "\x16" => '\u0016', + "\x17" => '\u0017', + "\x18" => '\u0018', + "\x19" => '\u0019', + "\x1a" => '\u001a', + "\x1b" => '\u001b', + "\x1c" => '\u001c', + "\x1d" => '\u001d', + "\x1e" => '\u001e', + "\x1f" => '\u001f', + '"' => '\"', + '\\' => '\\\\', + }.freeze # :nodoc: + + SCRIPT_SAFE_MAP = MAP.merge( + '/' => '\\/', + "\u2028" => '\u2028', + "\u2029" => '\u2029', + ).freeze + + SCRIPT_SAFE_ESCAPE_PATTERN = /[\/"\\\x0-\x1f\u2028-\u2029]/ + + # Convert a UTF8 encoded Ruby string _string_ to a JSON string, encoded with + # UTF16 big endian characters as \u????, and return it. + def self.utf8_to_json(string, script_safe = false) # :nodoc: + if script_safe + if SCRIPT_SAFE_ESCAPE_PATTERN.match?(string) + string.gsub(SCRIPT_SAFE_ESCAPE_PATTERN, SCRIPT_SAFE_MAP) + else + string + end + else + if /["\\\x0-\x1f]/.match?(string) + string.gsub(/["\\\x0-\x1f]/, MAP) + else + string + end + end + end + + def self.utf8_to_json_ascii(original_string, script_safe = false) # :nodoc: + string = original_string.b + map = script_safe ? SCRIPT_SAFE_MAP : MAP + string.gsub!(/[\/"\\\x0-\x1f]/n) { map[$&] || $& } + string.gsub!(/( + (?: + [\xc2-\xdf][\x80-\xbf] | + [\xe0-\xef][\x80-\xbf]{2} | + [\xf0-\xf4][\x80-\xbf]{3} + )+ | + [\x80-\xc1\xf5-\xff] # invalid + )/nx) { |c| + c.size == 1 and raise GeneratorError.new("invalid utf8 byte: '#{c}'", original_string) + s = c.encode(::Encoding::UTF_16BE, ::Encoding::UTF_8).unpack('H*')[0] + s.force_encoding(::Encoding::BINARY) + s.gsub!(/.{4}/n, '\\\\u\&') + s.force_encoding(::Encoding::UTF_8) + } + string.force_encoding(::Encoding::UTF_8) + string + rescue => e + raise GeneratorError.new(e.message, original_string) + end + + def self.valid_utf8?(string) + encoding = string.encoding + (encoding == Encoding::UTF_8 || encoding == Encoding::ASCII) && + string.valid_encoding? + end + + # This class is used to create State instances, that are use to hold data + # while generating a JSON text from a Ruby data structure. + class State + def self.generate(obj, opts = nil, io = nil) + new(opts).generate(obj, io) + end + + # Creates a State object from _opts_, which ought to be Hash to create + # a new State instance configured by _opts_, something else to create + # an unconfigured instance. If _opts_ is a State object, it is just + # returned. + def self.from_state(opts) + if opts + case + when self === opts + return opts + when opts.respond_to?(:to_hash) + return new(opts.to_hash) + when opts.respond_to?(:to_h) + return new(opts.to_h) + end + end + new + end + + # Instantiates a new State object, configured by _opts_. + # + # _opts_ can have the following keys: + # + # * *indent*: a string used to indent levels (default: ''), + # * *space*: a string that is put after, a : or , delimiter (default: ''), + # * *space_before*: a string that is put before a : pair delimiter (default: ''), + # * *object_nl*: a string that is put at the end of a JSON object (default: ''), + # * *array_nl*: a string that is put at the end of a JSON array (default: ''), + # * *script_safe*: true if U+2028, U+2029 and forward slash (/) should be escaped + # as to make the JSON object safe to interpolate in a script tag (default: false). + # * *check_circular*: is deprecated now, use the :max_nesting option instead, + # * *max_nesting*: sets the maximum level of data structure nesting in + # the generated JSON, max_nesting = 0 if no maximum should be checked. + # * *allow_nan*: true if NaN, Infinity, and -Infinity should be + # generated, otherwise an exception is thrown, if these values are + # encountered. This options defaults to false. + def initialize(opts = nil) + @indent = '' + @space = '' + @space_before = '' + @object_nl = '' + @array_nl = '' + @allow_nan = false + @ascii_only = false + @as_json = false + @depth = 0 + @buffer_initial_length = 1024 + @script_safe = false + @strict = false + @max_nesting = 100 + configure(opts) if opts + end + + # This string is used to indent levels in the JSON text. + attr_accessor :indent + + # This string is used to insert a space between the tokens in a JSON + # string. + attr_accessor :space + + # This string is used to insert a space before the ':' in JSON objects. + attr_accessor :space_before + + # This string is put at the end of a line that holds a JSON object (or + # Hash). + attr_accessor :object_nl + + # This string is put at the end of a line that holds a JSON array. + attr_accessor :array_nl + + # This proc converts unsupported types into native JSON types. + attr_accessor :as_json + + # This integer returns the maximum level of data structure nesting in + # the generated JSON, max_nesting = 0 if no maximum is checked. + attr_accessor :max_nesting + + # If this attribute is set to true, forward slashes will be escaped in + # all json strings. + attr_accessor :script_safe + + # If this attribute is set to true, attempting to serialize types not + # supported by the JSON spec will raise a JSON::GeneratorError + attr_accessor :strict + + # :stopdoc: + attr_reader :buffer_initial_length + + def buffer_initial_length=(length) + if length > 0 + @buffer_initial_length = length + end + end + # :startdoc: + + # This integer returns the current depth data structure nesting in the + # generated JSON. + attr_accessor :depth + + def check_max_nesting # :nodoc: + return if @max_nesting.zero? + current_nesting = depth + 1 + current_nesting > @max_nesting and + raise NestingError, "nesting of #{current_nesting} is too deep" + end + + # Returns true, if circular data structures are checked, + # otherwise returns false. + def check_circular? + !@max_nesting.zero? + end + + # Returns true if NaN, Infinity, and -Infinity should be considered as + # valid JSON and output. + def allow_nan? + @allow_nan + end + + # Returns true, if only ASCII characters should be generated. Otherwise + # returns false. + def ascii_only? + @ascii_only + end + + # Returns true, if forward slashes are escaped. Otherwise returns false. + def script_safe? + @script_safe + end + + # Returns true, if strict mode is enabled. Otherwise returns false. + # Strict mode only allow serializing JSON native types: Hash, Array, + # String, Integer, Float, true, false and nil. + def strict? + @strict + end + + # Configure this State instance with the Hash _opts_, and return + # itself. + def configure(opts) + if opts.respond_to?(:to_hash) + opts = opts.to_hash + elsif opts.respond_to?(:to_h) + opts = opts.to_h + else + raise TypeError, "can't convert #{opts.class} into Hash" + end + opts.each do |key, value| + instance_variable_set "@#{key}", value + end + + # NOTE: If adding new instance variables here, check whether #generate should check them for #generate_json + @indent = opts[:indent] || '' if opts.key?(:indent) + @space = opts[:space] || '' if opts.key?(:space) + @space_before = opts[:space_before] || '' if opts.key?(:space_before) + @object_nl = opts[:object_nl] || '' if opts.key?(:object_nl) + @array_nl = opts[:array_nl] || '' if opts.key?(:array_nl) + @allow_nan = !!opts[:allow_nan] if opts.key?(:allow_nan) + @as_json = opts[:as_json].to_proc if opts[:as_json] + @ascii_only = opts[:ascii_only] if opts.key?(:ascii_only) + @depth = opts[:depth] || 0 + @buffer_initial_length ||= opts[:buffer_initial_length] + + @script_safe = if opts.key?(:script_safe) + !!opts[:script_safe] + elsif opts.key?(:escape_slash) + !!opts[:escape_slash] + else + false + end + + @strict = !!opts[:strict] if opts.key?(:strict) + + if !opts.key?(:max_nesting) # defaults to 100 + @max_nesting = 100 + elsif opts[:max_nesting] + @max_nesting = opts[:max_nesting] + else + @max_nesting = 0 + end + self + end + alias merge configure + + # Returns the configuration instance variables as a hash, that can be + # passed to the configure method. + def to_h + result = {} + instance_variables.each do |iv| + iv = iv.to_s[1..-1] + result[iv.to_sym] = self[iv] + end + result + end + + alias to_hash to_h + + # Generates a valid JSON document from object +obj+ and + # returns the result. If no valid JSON document can be + # created this method raises a + # GeneratorError exception. + def generate(obj, anIO = nil) + if @indent.empty? and @space.empty? and @space_before.empty? and @object_nl.empty? and @array_nl.empty? and + !@ascii_only and !@script_safe and @max_nesting == 0 and (!@strict || Symbol === obj) + result = generate_json(obj, ''.dup) + else + result = obj.to_json(self) + end + JSON::TruffleRuby::Generator.valid_utf8?(result) or raise GeneratorError.new( + "source sequence #{result.inspect} is illegal/malformed utf-8", + obj + ) + if anIO + anIO.write(result) + anIO + else + result + end + end + + def generate_new(obj, anIO = nil) # :nodoc: + dup.generate(obj, anIO) + end + + # Handles @allow_nan, @buffer_initial_length, other ivars must be the default value (see above) + private def generate_json(obj, buf) + case obj + when Hash + buf << '{' + first = true + obj.each_pair do |k,v| + buf << ',' unless first + + key_str = k.to_s + if key_str.class == String + fast_serialize_string(key_str, buf) + elsif key_str.is_a?(String) + generate_json(key_str, buf) + else + raise TypeError, "#{k.class}#to_s returns an instance of #{key_str.class}, expected a String" + end + + buf << ':' + generate_json(v, buf) + first = false + end + buf << '}' + when Array + buf << '[' + first = true + obj.each do |e| + buf << ',' unless first + generate_json(e, buf) + first = false + end + buf << ']' + when String + if obj.class == String + fast_serialize_string(obj, buf) + else + buf << obj.to_json(self) + end + when Integer + buf << obj.to_s + when Symbol + if @strict + fast_serialize_string(obj.name, buf) + else + buf << obj.to_json(self) + end + else + # Note: Float is handled this way since Float#to_s is slow anyway + buf << obj.to_json(self) + end + end + + # Assumes !@ascii_only, !@script_safe + private def fast_serialize_string(string, buf) # :nodoc: + buf << '"' + unless string.encoding == ::Encoding::UTF_8 + begin + string = string.encode(::Encoding::UTF_8) + rescue Encoding::UndefinedConversionError => error + raise GeneratorError.new(error.message, string) + end + end + raise GeneratorError.new("source sequence is illegal/malformed utf-8", string) unless string.valid_encoding? + + if /["\\\x0-\x1f]/.match?(string) + buf << string.gsub(/["\\\x0-\x1f]/, MAP) + else + buf << string + end + buf << '"' + end + + # Return the value returned by method +name+. + def [](name) + if respond_to?(name) + __send__(name) + else + instance_variable_get("@#{name}") if + instance_variables.include?("@#{name}".to_sym) # avoid warning + end + end + + def []=(name, value) + if respond_to?(name_writer = "#{name}=") + __send__ name_writer, value + else + instance_variable_set "@#{name}", value + end + end + end + + module GeneratorMethods + module Object + # Converts this object to a string (calling #to_s), converts + # it to a JSON string, and returns the result. This is a fallback, if no + # special method #to_json was defined for some object. + def to_json(state = nil, *) + state = State.from_state(state) if state + if state&.strict? + value = self + if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value) + if state.as_json + value = state.as_json.call(value) + unless false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value + raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value) + end + value.to_json(state) + else + raise GeneratorError.new("#{value.class} not allowed in JSON", value) + end + end + else + to_s.to_json + end + end + end + + module Hash + # Returns a JSON string containing a JSON object, that is unparsed from + # this Hash instance. + # _state_ is a JSON::State object, that can also be used to configure the + # produced JSON string output further. + # _depth_ is used to find out nesting depth, to indent accordingly. + def to_json(state = nil, *) + state = State.from_state(state) + state.check_max_nesting + json_transform(state) + end + + private + + def json_shift(state) + state.object_nl.empty? or return '' + state.indent * state.depth + end + + def json_transform(state) + depth = state.depth += 1 + + if empty? + state.depth -= 1 + return '{}' + end + + delim = ",#{state.object_nl}" + result = +"{#{state.object_nl}" + first = true + indent = !state.object_nl.empty? + each { |key, value| + result << delim unless first + result << state.indent * depth if indent + + key_str = key.to_s + if key_str.is_a?(String) + key_json = key_str.to_json(state) + else + raise TypeError, "#{key.class}#to_s returns an instance of #{key_str.class}, expected a String" + end + + result = +"#{result}#{key_json}#{state.space_before}:#{state.space}" + if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value) + if state.as_json + value = state.as_json.call(value) + unless false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value + raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value) + end + result << value.to_json(state) + else + raise GeneratorError.new("#{value.class} not allowed in JSON", value) + end + elsif value.respond_to?(:to_json) + result << value.to_json(state) + else + result << %{"#{String(value)}"} + end + first = false + } + depth = state.depth -= 1 + unless first + result << state.object_nl + result << state.indent * depth if indent + end + result << '}' + result + end + end + + module Array + # Returns a JSON string containing a JSON array, that is unparsed from + # this Array instance. + # _state_ is a JSON::State object, that can also be used to configure the + # produced JSON string output further. + def to_json(state = nil, *) + state = State.from_state(state) + state.check_max_nesting + json_transform(state) + end + + private + + def json_transform(state) + depth = state.depth += 1 + + if empty? + state.depth -= 1 + return '[]' + end + + result = '['.dup + if state.array_nl.empty? + delim = "," + else + result << state.array_nl + delim = ",#{state.array_nl}" + end + + first = true + indent = !state.array_nl.empty? + each { |value| + result << delim unless first + result << state.indent * depth if indent + if state.strict? && !(false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value || Symbol == value) + if state.as_json + value = state.as_json.call(value) + unless false == value || true == value || nil == value || String === value || Array === value || Hash === value || Integer === value || Float === value || Fragment === value || Symbol === value + raise GeneratorError.new("#{value.class} returned by #{state.as_json} not allowed in JSON", value) + end + result << value.to_json(state) + else + raise GeneratorError.new("#{value.class} not allowed in JSON", value) + end + elsif value.respond_to?(:to_json) + result << value.to_json(state) + else + result << %{"#{String(value)}"} + end + first = false + } + depth = state.depth -= 1 + result << state.array_nl + result << state.indent * depth if indent + result << ']' + end + end + + module Integer + # Returns a JSON string representation for this Integer number. + def to_json(*) to_s end + end + + module Float + # Returns a JSON string representation for this Float number. + def to_json(state = nil, *args) + state = State.from_state(state) + if infinite? || nan? + if state.allow_nan? + to_s + elsif state.strict? && state.as_json + casted_value = state.as_json.call(self) + + if casted_value.equal?(self) + raise GeneratorError.new("#{self} not allowed in JSON", self) + end + + state.check_max_nesting + state.depth += 1 + result = casted_value.to_json(state, *args) + state.depth -= 1 + result + else + raise GeneratorError.new("#{self} not allowed in JSON", self) + end + else + to_s + end + end + end + + module Symbol + def to_json(state = nil, *args) + state = State.from_state(state) + if state.strict? + name.to_json(state, *args) + else + super + end + end + end + + module String + # This string should be encoded with UTF-8 A call to this method + # returns a JSON string encoded with UTF16 big endian characters as + # \u????. + def to_json(state = nil, *args) + state = State.from_state(state) + if encoding == ::Encoding::UTF_8 + unless valid_encoding? + raise GeneratorError.new("source sequence is illegal/malformed utf-8", self) + end + string = self + else + string = encode(::Encoding::UTF_8) + end + if state.ascii_only? + %("#{JSON::TruffleRuby::Generator.utf8_to_json_ascii(string, state.script_safe)}") + else + %("#{JSON::TruffleRuby::Generator.utf8_to_json(string, state.script_safe)}") + end + rescue Encoding::UndefinedConversionError => error + raise ::JSON::GeneratorError.new(error.message, self) + end + + # Module that holds the extending methods if, the String module is + # included. + module Extend + # Raw Strings are JSON Objects (the raw bytes are stored in an + # array for the key "raw"). The Ruby String can be created by this + # module method. + def json_create(o) + o['raw'].pack('C*') + end + end + + # Extends _modul_ with the String::Extend module. + def self.included(modul) + modul.extend Extend + end + + # This method creates a raw object hash, that can be nested into + # other data structures and will be unparsed as a raw string. This + # method should be used, if you want to convert raw strings to JSON + # instead of UTF-8 strings, e. g. binary data. + def to_json_raw_object + { + JSON.create_id => self.class.name, + 'raw' => self.unpack('C*'), + } + end + + # This method creates a JSON text from the result of + # a call to to_json_raw_object of this String. + def to_json_raw(*args) + to_json_raw_object.to_json(*args) + end + end + + module TrueClass + # Returns a JSON string for true: 'true'. + def to_json(*) 'true' end + end + + module FalseClass + # Returns a JSON string for false: 'false'. + def to_json(*) 'false' end + end + + module NilClass + # Returns a JSON string for nil: 'null'. + def to_json(*) 'null' end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/version.rb b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/version.rb new file mode 100644 index 00000000..15ebd12f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/json-2.12.2/lib/json/version.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +module JSON + VERSION = '2.12.2' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/LICENSE.txt b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/LICENSE.txt new file mode 100644 index 00000000..a6497a4b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017 Fumiaki MATSUSHIMA + +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 +AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/README.md b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/README.md new file mode 100644 index 00000000..dc4b8d1e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/README.md @@ -0,0 +1,88 @@ +# LanguageServer::Protocol + +A Language Server Protocol SDK for Ruby. + +[![Gem Version](https://badge.fury.io/rb/language_server-protocol.svg)](https://badge.fury.io/rb/language_server-protocol) + +## Installation + +Add this line to your application's Gemfile: + +```ruby +gem 'language_server-protocol' +``` + +And then execute: + + $ bundle + +Or install it yourself as: + + $ gem install language_server-protocol + +## Usage + +Currently, this gem supports only stdio as transport layer out of box. + +```ruby +require "language_server-protocol" + +LSP = LanguageServer::Protocol +writer = LSP::Transport::Stdio::Writer.new +reader = LSP::Transport::Stdio::Reader.new + +subscribers = { + initialize: -> { + LSP::Interface::InitializeResult.new( + capabilities: LSP::Interface::ServerCapabilities.new( + text_document_sync: LSP::Interface::TextDocumentSyncOptions.new( + change: LSP::Constant::TextDocumentSyncKind::FULL + ), + completion_provider: LSP::Interface::CompletionOptions.new( + resolve_provider: true, + trigger_characters: %w(.) + ), + definition_provider: true + ) + ) + } +} + +reader.read do |request| + result = subscribers[request[:method].to_sym].call + writer.write(id: request[:id], result: result) + exit +end +``` + +You can use any IO object as transport layer: + +```ruby +io = StringIO.new +writer = LSP::Transport::Io::Writer.new(io) +reader = LSP::Transport::Io::Reader.new(io) +``` + +## Versioning + +language_server-protocol gem does NOT use semantic versioning. +This gem versions are structured as `x.y.z.t`. +`x.y.z` indicates the [Language server protocol](https://github.com/Microsoft/language-server-protocol/) version and `t` is a monotonically increasing number. + +## Development + +After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. + +To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). + +## Contributing + +Bug reports and pull requests are welcome on GitHub at https://github.com/mtsmfm/language_server-protocol-ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. + +## License + +The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT). + +## Code of Conduct + +Everyone interacting in the LanguageServer::Protocol project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/mtsmfm/language_server-protocol-ruby/blob/main/CODE_OF_CONDUCT.md). diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server-protocol.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server-protocol.rb new file mode 100644 index 00000000..1a9c1caf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server-protocol.rb @@ -0,0 +1 @@ +require_relative "language_server/protocol" diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol.rb new file mode 100644 index 00000000..e8efc855 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol.rb @@ -0,0 +1,4 @@ +require_relative "protocol/version" +require_relative "protocol/constant" +require_relative "protocol/interface" +require_relative "protocol/transport" diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant.rb new file mode 100644 index 00000000..b9cc8f80 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant.rb @@ -0,0 +1,77 @@ +module LanguageServer + module Protocol + module Constant + autoload :CodeActionKind, "language_server/protocol/constant/code_action_kind" + autoload :CodeActionTriggerKind, "language_server/protocol/constant/code_action_trigger_kind" + autoload :CompletionItemKind, "language_server/protocol/constant/completion_item_kind" + autoload :CompletionItemTag, "language_server/protocol/constant/completion_item_tag" + autoload :CompletionTriggerKind, "language_server/protocol/constant/completion_trigger_kind" + autoload :DiagnosticSeverity, "language_server/protocol/constant/diagnostic_severity" + autoload :DiagnosticTag, "language_server/protocol/constant/diagnostic_tag" + autoload :DocumentDiagnosticReportKind, "language_server/protocol/constant/document_diagnostic_report_kind" + autoload :DocumentHighlightKind, "language_server/protocol/constant/document_highlight_kind" + autoload :ErrorCodes, "language_server/protocol/constant/error_codes" + autoload :FailureHandlingKind, "language_server/protocol/constant/failure_handling_kind" + autoload :FileChangeType, "language_server/protocol/constant/file_change_type" + autoload :FileOperationPatternKind, "language_server/protocol/constant/file_operation_pattern_kind" + autoload :FoldingRangeKind, "language_server/protocol/constant/folding_range_kind" + autoload :InitializeErrorCodes, "language_server/protocol/constant/initialize_error_codes" + autoload :InlayHintKind, "language_server/protocol/constant/inlay_hint_kind" + autoload :InsertTextFormat, "language_server/protocol/constant/insert_text_format" + autoload :InsertTextMode, "language_server/protocol/constant/insert_text_mode" + autoload :MarkupKind, "language_server/protocol/constant/markup_kind" + autoload :MessageType, "language_server/protocol/constant/message_type" + autoload :MonikerKind, "language_server/protocol/constant/moniker_kind" + autoload :NotebookCellKind, "language_server/protocol/constant/notebook_cell_kind" + autoload :PositionEncodingKind, "language_server/protocol/constant/position_encoding_kind" + autoload :PrepareSupportDefaultBehavior, "language_server/protocol/constant/prepare_support_default_behavior" + autoload :ResourceOperationKind, "language_server/protocol/constant/resource_operation_kind" + autoload :SemanticTokenModifiers, "language_server/protocol/constant/semantic_token_modifiers" + autoload :SemanticTokenTypes, "language_server/protocol/constant/semantic_token_types" + autoload :SignatureHelpTriggerKind, "language_server/protocol/constant/signature_help_trigger_kind" + autoload :SymbolKind, "language_server/protocol/constant/symbol_kind" + autoload :SymbolTag, "language_server/protocol/constant/symbol_tag" + autoload :TextDocumentSaveReason, "language_server/protocol/constant/text_document_save_reason" + autoload :TextDocumentSyncKind, "language_server/protocol/constant/text_document_sync_kind" + autoload :TokenFormat, "language_server/protocol/constant/token_format" + autoload :UniquenessLevel, "language_server/protocol/constant/uniqueness_level" + autoload :WatchKind, "language_server/protocol/constant/watch_kind" + + require_relative "constant/code_action_kind" + require_relative "constant/code_action_trigger_kind" + require_relative "constant/completion_item_kind" + require_relative "constant/completion_item_tag" + require_relative "constant/completion_trigger_kind" + require_relative "constant/diagnostic_severity" + require_relative "constant/diagnostic_tag" + require_relative "constant/document_diagnostic_report_kind" + require_relative "constant/document_highlight_kind" + require_relative "constant/error_codes" + require_relative "constant/failure_handling_kind" + require_relative "constant/file_change_type" + require_relative "constant/file_operation_pattern_kind" + require_relative "constant/folding_range_kind" + require_relative "constant/initialize_error_codes" + require_relative "constant/inlay_hint_kind" + require_relative "constant/insert_text_format" + require_relative "constant/insert_text_mode" + require_relative "constant/markup_kind" + require_relative "constant/message_type" + require_relative "constant/moniker_kind" + require_relative "constant/notebook_cell_kind" + require_relative "constant/position_encoding_kind" + require_relative "constant/prepare_support_default_behavior" + require_relative "constant/resource_operation_kind" + require_relative "constant/semantic_token_modifiers" + require_relative "constant/semantic_token_types" + require_relative "constant/signature_help_trigger_kind" + require_relative "constant/symbol_kind" + require_relative "constant/symbol_tag" + require_relative "constant/text_document_save_reason" + require_relative "constant/text_document_sync_kind" + require_relative "constant/token_format" + require_relative "constant/uniqueness_level" + require_relative "constant/watch_kind" + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/code_action_kind.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/code_action_kind.rb new file mode 100644 index 00000000..06d2f417 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/code_action_kind.rb @@ -0,0 +1,85 @@ +module LanguageServer + module Protocol + module Constant + # + # The kind of a code action. + # + # Kinds are a hierarchical list of identifiers separated by `.`, + # e.g. `"refactor.extract.function"`. + # + # The set of kinds is open and client needs to announce the kinds it supports + # to the server during initialization. + # A set of predefined code action kinds. + # + module CodeActionKind + # + # Empty kind. + # + EMPTY = '' + # + # Base kind for quickfix actions: 'quickfix'. + # + QUICK_FIX = 'quickfix' + # + # Base kind for refactoring actions: 'refactor'. + # + REFACTOR = 'refactor' + # + # Base kind for refactoring extraction actions: 'refactor.extract'. + # + # Example extract actions: + # + # - Extract method + # - Extract function + # - Extract variable + # - Extract interface from class + # - ... + # + REFACTOR_EXTRACT = 'refactor.extract' + # + # Base kind for refactoring inline actions: 'refactor.inline'. + # + # Example inline actions: + # + # - Inline function + # - Inline variable + # - Inline constant + # - ... + # + REFACTOR_INLINE = 'refactor.inline' + # + # Base kind for refactoring rewrite actions: 'refactor.rewrite'. + # + # Example rewrite actions: + # + # - Convert JavaScript function to class + # - Add or remove parameter + # - Encapsulate field + # - Make method static + # - Move method to base class + # - ... + # + REFACTOR_REWRITE = 'refactor.rewrite' + # + # Base kind for source actions: `source`. + # + # Source code actions apply to the entire file. + # + SOURCE = 'source' + # + # Base kind for an organize imports source action: + # `source.organizeImports`. + # + SOURCE_ORGANIZE_IMPORTS = 'source.organizeImports' + # + # Base kind for a 'fix all' source action: `source.fixAll`. + # + # 'Fix all' actions automatically fix errors that have a clear fix that + # do not require user input. They should not suppress errors or perform + # unsafe fixes such as generating new types or classes. + # + SOURCE_FIX_ALL = 'source.fixAll' + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/code_action_trigger_kind.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/code_action_trigger_kind.rb new file mode 100644 index 00000000..fc7ee17b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/code_action_trigger_kind.rb @@ -0,0 +1,22 @@ +module LanguageServer + module Protocol + module Constant + # + # The reason why code actions were requested. + # + module CodeActionTriggerKind + # + # Code actions were explicitly requested by the user or by an extension. + # + INVOKED = 1 + # + # Code actions were requested automatically. + # + # This typically happens when current selection in a file changes, but can + # also be triggered when file content changes. + # + AUTOMATIC = 2 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/completion_item_kind.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/completion_item_kind.rb new file mode 100644 index 00000000..8a92a9d4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/completion_item_kind.rb @@ -0,0 +1,36 @@ +module LanguageServer + module Protocol + module Constant + # + # The kind of a completion entry. + # + module CompletionItemKind + TEXT = 1 + METHOD = 2 + FUNCTION = 3 + CONSTRUCTOR = 4 + FIELD = 5 + VARIABLE = 6 + CLASS = 7 + INTERFACE = 8 + MODULE = 9 + PROPERTY = 10 + UNIT = 11 + VALUE = 12 + ENUM = 13 + KEYWORD = 14 + SNIPPET = 15 + COLOR = 16 + FILE = 17 + REFERENCE = 18 + FOLDER = 19 + ENUM_MEMBER = 20 + CONSTANT = 21 + STRUCT = 22 + EVENT = 23 + OPERATOR = 24 + TYPE_PARAMETER = 25 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/completion_item_tag.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/completion_item_tag.rb new file mode 100644 index 00000000..bdab62e7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/completion_item_tag.rb @@ -0,0 +1,16 @@ +module LanguageServer + module Protocol + module Constant + # + # Completion item tags are extra annotations that tweak the rendering of a + # completion item. + # + module CompletionItemTag + # + # Render a completion as obsolete, usually using a strike-out. + # + DEPRECATED = 1 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/completion_trigger_kind.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/completion_trigger_kind.rb new file mode 100644 index 00000000..3deef326 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/completion_trigger_kind.rb @@ -0,0 +1,26 @@ +module LanguageServer + module Protocol + module Constant + # + # How a completion was triggered + # + module CompletionTriggerKind + # + # Completion was triggered by typing an identifier (24x7 code + # complete), manual invocation (e.g Ctrl+Space) or via API. + # + INVOKED = 1 + # + # Completion was triggered by a trigger character specified by + # the `triggerCharacters` properties of the + # `CompletionRegistrationOptions`. + # + TRIGGER_CHARACTER = 2 + # + # Completion was re-triggered as the current completion list is incomplete. + # + TRIGGER_FOR_INCOMPLETE_COMPLETIONS = 3 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/diagnostic_severity.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/diagnostic_severity.rb new file mode 100644 index 00000000..f7dd6c47 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/diagnostic_severity.rb @@ -0,0 +1,24 @@ +module LanguageServer + module Protocol + module Constant + module DiagnosticSeverity + # + # Reports an error. + # + ERROR = 1 + # + # Reports a warning. + # + WARNING = 2 + # + # Reports an information. + # + INFORMATION = 3 + # + # Reports a hint. + # + HINT = 4 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/diagnostic_tag.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/diagnostic_tag.rb new file mode 100644 index 00000000..8b6b1048 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/diagnostic_tag.rb @@ -0,0 +1,24 @@ +module LanguageServer + module Protocol + module Constant + # + # The diagnostic tags. + # + module DiagnosticTag + # + # Unused or unnecessary code. + # + # Clients are allowed to render diagnostics with this tag faded out + # instead of having an error squiggle. + # + UNNECESSARY = 1 + # + # Deprecated or obsolete code. + # + # Clients are allowed to rendered diagnostics with this tag strike through. + # + DEPRECATED = 2 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/document_diagnostic_report_kind.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/document_diagnostic_report_kind.rb new file mode 100644 index 00000000..f389f9d7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/document_diagnostic_report_kind.rb @@ -0,0 +1,21 @@ +module LanguageServer + module Protocol + module Constant + # + # The document diagnostic report kinds. + # + module DocumentDiagnosticReportKind + # + # A diagnostic report with a full + # set of problems. + # + FULL = 'full' + # + # A report indicating that the last + # returned report is still accurate. + # + UNCHANGED = 'unchanged' + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/document_highlight_kind.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/document_highlight_kind.rb new file mode 100644 index 00000000..e1430249 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/document_highlight_kind.rb @@ -0,0 +1,23 @@ +module LanguageServer + module Protocol + module Constant + # + # A document highlight kind. + # + module DocumentHighlightKind + # + # A textual occurrence. + # + TEXT = 1 + # + # Read-access of a symbol, like reading a variable. + # + READ = 2 + # + # Write-access of a symbol, like writing to a variable. + # + WRITE = 3 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/error_codes.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/error_codes.rb new file mode 100644 index 00000000..23b309f0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/error_codes.rb @@ -0,0 +1,73 @@ +module LanguageServer + module Protocol + module Constant + module ErrorCodes + PARSE_ERROR = -32700 + INVALID_REQUEST = -32600 + METHOD_NOT_FOUND = -32601 + INVALID_PARAMS = -32602 + INTERNAL_ERROR = -32603 + # + # This is the start range of JSON-RPC reserved error codes. + # It doesn't denote a real error code. No LSP error codes should + # be defined between the start and end range. For backwards + # compatibility the `ServerNotInitialized` and the `UnknownErrorCode` + # are left in the range. + # + JSONRPC_RESERVED_ERROR_RANGE_START = -32099 + SERVER_ERROR_START = JSONRPC_RESERVED_ERROR_RANGE_START + # + # Error code indicating that a server received a notification or + # request before the server has received the `initialize` request. + # + SERVER_NOT_INITIALIZED = -32002 + UNKNOWN_ERROR_CODE = -32001 + # + # This is the end range of JSON-RPC reserved error codes. + # It doesn't denote a real error code. + # + JSONRPC_RESERVED_ERROR_RANGE_END = -32000 + SERVER_ERROR_END = JSONRPC_RESERVED_ERROR_RANGE_END + # + # This is the start range of LSP reserved error codes. + # It doesn't denote a real error code. + # + LSP_RESERVED_ERROR_RANGE_START = -32899 + # + # A request failed but it was syntactically correct, e.g the + # method name was known and the parameters were valid. The error + # message should contain human readable information about why + # the request failed. + # + REQUEST_FAILED = -32803 + # + # The server cancelled the request. This error code should + # only be used for requests that explicitly support being + # server cancellable. + # + SERVER_CANCELLED = -32802 + # + # The server detected that the content of a document got + # modified outside normal conditions. A server should + # NOT send this error code if it detects a content change + # in it unprocessed messages. The result even computed + # on an older state might still be useful for the client. + # + # If a client decides that a result is not of any use anymore + # the client should cancel the request. + # + CONTENT_MODIFIED = -32801 + # + # The client has canceled a request and a server as detected + # the cancel. + # + REQUEST_CANCELLED = -32800 + # + # This is the end range of LSP reserved error codes. + # It doesn't denote a real error code. + # + LSP_RESERVED_ERROR_RANGE_END = -32800 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/failure_handling_kind.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/failure_handling_kind.rb new file mode 100644 index 00000000..3b6d34dd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/failure_handling_kind.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Constant + module FailureHandlingKind + # + # Applying the workspace change is simply aborted if one of the changes + # provided fails. All operations executed before the failing operation + # stay executed. + # + ABORT = 'abort' + # + # All operations are executed transactional. That means they either all + # succeed or no changes at all are applied to the workspace. + # + TRANSACTIONAL = 'transactional' + # + # If the workspace edit contains only textual file changes they are + # executed transactional. If resource changes (create, rename or delete + # file) are part of the change the failure handling strategy is abort. + # + TEXT_ONLY_TRANSACTIONAL = 'textOnlyTransactional' + # + # The client tries to undo the operations already executed. But there is no + # guarantee that this is succeeding. + # + UNDO = 'undo' + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/file_change_type.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/file_change_type.rb new file mode 100644 index 00000000..fb1d019e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/file_change_type.rb @@ -0,0 +1,23 @@ +module LanguageServer + module Protocol + module Constant + # + # The file event type. + # + module FileChangeType + # + # The file got created. + # + CREATED = 1 + # + # The file got changed. + # + CHANGED = 2 + # + # The file got deleted. + # + DELETED = 3 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/file_operation_pattern_kind.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/file_operation_pattern_kind.rb new file mode 100644 index 00000000..10e78858 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/file_operation_pattern_kind.rb @@ -0,0 +1,20 @@ +module LanguageServer + module Protocol + module Constant + # + # A pattern kind describing if a glob pattern matches a file a folder or + # both. + # + module FileOperationPatternKind + # + # The pattern matches a file only. + # + FILE = 'file' + # + # The pattern matches a folder only. + # + FOLDER = 'folder' + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/folding_range_kind.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/folding_range_kind.rb new file mode 100644 index 00000000..72f42176 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/folding_range_kind.rb @@ -0,0 +1,24 @@ +module LanguageServer + module Protocol + module Constant + # + # A set of predefined range kinds. + # The type is a string since the value set is extensible + # + module FoldingRangeKind + # + # Folding range for a comment + # + COMMENT = 'comment' + # + # Folding range for imports or includes + # + IMPORTS = 'imports' + # + # Folding range for a region (e.g. `#region`) + # + REGION = 'region' + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/initialize_error_codes.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/initialize_error_codes.rb new file mode 100644 index 00000000..bc2aceaf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/initialize_error_codes.rb @@ -0,0 +1,16 @@ +module LanguageServer + module Protocol + module Constant + # + # Known error codes for an `InitializeErrorCodes`; + # + module InitializeErrorCodes + # + # If the protocol version provided by the client can't be handled by + # the server. + # + UNKNOWN_PROTOCOL_VERSION = 1 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/inlay_hint_kind.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/inlay_hint_kind.rb new file mode 100644 index 00000000..d4d9ec99 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/inlay_hint_kind.rb @@ -0,0 +1,19 @@ +module LanguageServer + module Protocol + module Constant + # + # Inlay hint kinds. + # + module InlayHintKind + # + # An inlay hint that for a type annotation. + # + TYPE = 1 + # + # An inlay hint that is for a parameter. + # + PARAMETER = 2 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/insert_text_format.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/insert_text_format.rb new file mode 100644 index 00000000..5eb4d6ca --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/insert_text_format.rb @@ -0,0 +1,25 @@ +module LanguageServer + module Protocol + module Constant + # + # Defines whether the insert text in a completion item should be interpreted as + # plain text or a snippet. + # + module InsertTextFormat + # + # The primary text to be inserted is treated as a plain string. + # + PLAIN_TEXT = 1 + # + # The primary text to be inserted is treated as a snippet. + # + # A snippet can define tab stops and placeholders with `$1`, `$2` + # and `${3:foo}`. `$0` defines the final tab stop, it defaults to + # the end of the snippet. Placeholders with equal identifiers are linked, + # that is typing in one will update others too. + # + SNIPPET = 2 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/insert_text_mode.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/insert_text_mode.rb new file mode 100644 index 00000000..09c7e685 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/insert_text_mode.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Constant + # + # How whitespace and indentation is handled during completion + # item insertion. + # + module InsertTextMode + # + # The insertion or replace strings is taken as it is. If the + # value is multi line the lines below the cursor will be + # inserted using the indentation defined in the string value. + # The client will not apply any kind of adjustments to the + # string. + # + AS_IS = 1 + # + # The editor adjusts leading whitespace of new lines so that + # they match the indentation up to the cursor of the line for + # which the item is accepted. + # + # Consider a line like this: <2tabs><3tabs>foo. Accepting a + # multi line completion item is indented using 2 tabs and all + # following lines inserted will be indented using 2 tabs as well. + # + ADJUST_INDENTATION = 2 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/markup_kind.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/markup_kind.rb new file mode 100644 index 00000000..58d13542 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/markup_kind.rb @@ -0,0 +1,23 @@ +module LanguageServer + module Protocol + module Constant + # + # Describes the content type that a client supports in various + # result literals like `Hover`, `ParameterInfo` or `CompletionItem`. + # + # Please note that `MarkupKinds` must not start with a `$`. This kinds + # are reserved for internal usage. + # + module MarkupKind + # + # Plain text is supported as a content format + # + PLAIN_TEXT = 'plaintext' + # + # Markdown is supported as a content format + # + MARKDOWN = 'markdown' + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/message_type.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/message_type.rb new file mode 100644 index 00000000..873df8de --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/message_type.rb @@ -0,0 +1,24 @@ +module LanguageServer + module Protocol + module Constant + module MessageType + # + # An error message. + # + ERROR = 1 + # + # A warning message. + # + WARNING = 2 + # + # An information message. + # + INFO = 3 + # + # A log message. + # + LOG = 4 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/moniker_kind.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/moniker_kind.rb new file mode 100644 index 00000000..8e2c466e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/moniker_kind.rb @@ -0,0 +1,24 @@ +module LanguageServer + module Protocol + module Constant + # + # The moniker kind. + # + module MonikerKind + # + # The moniker represent a symbol that is imported into a project + # + IMPORT = 'import' + # + # The moniker represents a symbol that is exported from a project + # + EXPORT = 'export' + # + # The moniker represents a symbol that is local to a project (e.g. a local + # variable of a function, a class not visible outside the project, ...) + # + LOCAL = 'local' + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/notebook_cell_kind.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/notebook_cell_kind.rb new file mode 100644 index 00000000..0755c968 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/notebook_cell_kind.rb @@ -0,0 +1,19 @@ +module LanguageServer + module Protocol + module Constant + # + # A notebook cell kind. + # + module NotebookCellKind + # + # A markup-cell is formatted source that is used for display. + # + MARKUP = 1 + # + # A code-cell is source code. + # + CODE = 2 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/position_encoding_kind.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/position_encoding_kind.rb new file mode 100644 index 00000000..03045e01 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/position_encoding_kind.rb @@ -0,0 +1,32 @@ +module LanguageServer + module Protocol + module Constant + # + # A type indicating how positions are encoded, + # specifically what column offsets mean. + # A set of predefined position encoding kinds. + # + module PositionEncodingKind + # + # Character offsets count UTF-8 code units (e.g bytes). + # + UTF8 = 'utf-8' + # + # Character offsets count UTF-16 code units. + # + # This is the default and must always be supported + # by servers + # + UTF16 = 'utf-16' + # + # Character offsets count UTF-32 code units. + # + # Implementation note: these are the same as Unicode code points, + # so this `PositionEncodingKind` may also be used for an + # encoding-agnostic representation of character offsets. + # + UTF32 = 'utf-32' + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/prepare_support_default_behavior.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/prepare_support_default_behavior.rb new file mode 100644 index 00000000..5ab1947f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/prepare_support_default_behavior.rb @@ -0,0 +1,13 @@ +module LanguageServer + module Protocol + module Constant + module PrepareSupportDefaultBehavior + # + # The client's default behavior is to select the identifier + # according to the language's syntax rule. + # + IDENTIFIER = 1 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/resource_operation_kind.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/resource_operation_kind.rb new file mode 100644 index 00000000..1c9d2d45 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/resource_operation_kind.rb @@ -0,0 +1,23 @@ +module LanguageServer + module Protocol + module Constant + # + # The kind of resource operations supported by the client. + # + module ResourceOperationKind + # + # Supports creating new files and folders. + # + CREATE = 'create' + # + # Supports renaming existing files and folders. + # + RENAME = 'rename' + # + # Supports deleting existing files and folders. + # + DELETE = 'delete' + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/semantic_token_modifiers.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/semantic_token_modifiers.rb new file mode 100644 index 00000000..d5da2a9d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/semantic_token_modifiers.rb @@ -0,0 +1,18 @@ +module LanguageServer + module Protocol + module Constant + module SemanticTokenModifiers + DECLARATION = 'declaration' + DEFINITION = 'definition' + READONLY = 'readonly' + STATIC = 'static' + DEPRECATED = 'deprecated' + ABSTRACT = 'abstract' + ASYNC = 'async' + MODIFICATION = 'modification' + DOCUMENTATION = 'documentation' + DEFAULT_LIBRARY = 'defaultLibrary' + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/semantic_token_types.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/semantic_token_types.rb new file mode 100644 index 00000000..98d0425a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/semantic_token_types.rb @@ -0,0 +1,35 @@ +module LanguageServer + module Protocol + module Constant + module SemanticTokenTypes + NAMESPACE = 'namespace' + # + # Represents a generic type. Acts as a fallback for types which + # can't be mapped to a specific type like class or enum. + # + TYPE = 'type' + CLASS = 'class' + ENUM = 'enum' + INTERFACE = 'interface' + STRUCT = 'struct' + TYPE_PARAMETER = 'typeParameter' + PARAMETER = 'parameter' + VARIABLE = 'variable' + PROPERTY = 'property' + ENUM_MEMBER = 'enumMember' + EVENT = 'event' + FUNCTION = 'function' + METHOD = 'method' + MACRO = 'macro' + KEYWORD = 'keyword' + MODIFIER = 'modifier' + COMMENT = 'comment' + STRING = 'string' + NUMBER = 'number' + REGEXP = 'regexp' + OPERATOR = 'operator' + DECORATOR = 'decorator' + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/signature_help_trigger_kind.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/signature_help_trigger_kind.rb new file mode 100644 index 00000000..6298eca7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/signature_help_trigger_kind.rb @@ -0,0 +1,24 @@ +module LanguageServer + module Protocol + module Constant + # + # How a signature help was triggered. + # + module SignatureHelpTriggerKind + # + # Signature help was invoked manually by the user or by a command. + # + INVOKED = 1 + # + # Signature help was triggered by a trigger character. + # + TRIGGER_CHARACTER = 2 + # + # Signature help was triggered by the cursor moving or by the document + # content changing. + # + CONTENT_CHANGE = 3 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/symbol_kind.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/symbol_kind.rb new file mode 100644 index 00000000..4a343cab --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/symbol_kind.rb @@ -0,0 +1,37 @@ +module LanguageServer + module Protocol + module Constant + # + # A symbol kind. + # + module SymbolKind + FILE = 1 + MODULE = 2 + NAMESPACE = 3 + PACKAGE = 4 + CLASS = 5 + METHOD = 6 + PROPERTY = 7 + FIELD = 8 + CONSTRUCTOR = 9 + ENUM = 10 + INTERFACE = 11 + FUNCTION = 12 + VARIABLE = 13 + CONSTANT = 14 + STRING = 15 + NUMBER = 16 + BOOLEAN = 17 + ARRAY = 18 + OBJECT = 19 + KEY = 20 + NULL = 21 + ENUM_MEMBER = 22 + STRUCT = 23 + EVENT = 24 + OPERATOR = 25 + TYPE_PARAMETER = 26 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/symbol_tag.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/symbol_tag.rb new file mode 100644 index 00000000..da56df53 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/symbol_tag.rb @@ -0,0 +1,15 @@ +module LanguageServer + module Protocol + module Constant + # + # Symbol tags are extra annotations that tweak the rendering of a symbol. + # + module SymbolTag + # + # Render a symbol as obsolete, usually using a strike-out. + # + DEPRECATED = 1 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/text_document_save_reason.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/text_document_save_reason.rb new file mode 100644 index 00000000..42b17052 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/text_document_save_reason.rb @@ -0,0 +1,24 @@ +module LanguageServer + module Protocol + module Constant + # + # Represents reasons why a text document is saved. + # + module TextDocumentSaveReason + # + # Manually triggered, e.g. by the user pressing save, by starting + # debugging, or by an API call. + # + MANUAL = 1 + # + # Automatic after a delay. + # + AFTER_DELAY = 2 + # + # When the editor lost focus. + # + FOCUS_OUT = 3 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/text_document_sync_kind.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/text_document_sync_kind.rb new file mode 100644 index 00000000..ef10dc16 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/text_document_sync_kind.rb @@ -0,0 +1,27 @@ +module LanguageServer + module Protocol + module Constant + # + # Defines how the host (editor) should sync document changes to the language + # server. + # + module TextDocumentSyncKind + # + # Documents should not be synced at all. + # + NONE = 0 + # + # Documents are synced by always sending the full content + # of the document. + # + FULL = 1 + # + # Documents are synced by sending the full content on open. + # After that only incremental updates to the document are + # sent. + # + INCREMENTAL = 2 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/token_format.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/token_format.rb new file mode 100644 index 00000000..4177d196 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/token_format.rb @@ -0,0 +1,9 @@ +module LanguageServer + module Protocol + module Constant + module TokenFormat + RELATIVE = 'relative' + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/uniqueness_level.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/uniqueness_level.rb new file mode 100644 index 00000000..31d62668 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/uniqueness_level.rb @@ -0,0 +1,31 @@ +module LanguageServer + module Protocol + module Constant + # + # Moniker uniqueness level to define scope of the moniker. + # + module UniquenessLevel + # + # The moniker is only unique inside a document + # + DOCUMENT = 'document' + # + # The moniker is unique inside a project for which a dump got created + # + PROJECT = 'project' + # + # The moniker is unique inside the group to which a project belongs + # + GROUP = 'group' + # + # The moniker is unique inside the moniker scheme. + # + SCHEME = 'scheme' + # + # The moniker is globally unique + # + GLOBAL = 'global' + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/watch_kind.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/watch_kind.rb new file mode 100644 index 00000000..415c9b6a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/constant/watch_kind.rb @@ -0,0 +1,20 @@ +module LanguageServer + module Protocol + module Constant + module WatchKind + # + # Interested in create events. + # + CREATE = 1 + # + # Interested in change events + # + CHANGE = 2 + # + # Interested in delete events + # + DELETE = 4 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface.rb new file mode 100644 index 00000000..a07e6f6e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface.rb @@ -0,0 +1,631 @@ +module LanguageServer + module Protocol + module Interface + autoload :AnnotatedTextEdit, "language_server/protocol/interface/annotated_text_edit" + autoload :ApplyWorkspaceEditParams, "language_server/protocol/interface/apply_workspace_edit_params" + autoload :ApplyWorkspaceEditResult, "language_server/protocol/interface/apply_workspace_edit_result" + autoload :CallHierarchyClientCapabilities, "language_server/protocol/interface/call_hierarchy_client_capabilities" + autoload :CallHierarchyIncomingCall, "language_server/protocol/interface/call_hierarchy_incoming_call" + autoload :CallHierarchyIncomingCallsParams, "language_server/protocol/interface/call_hierarchy_incoming_calls_params" + autoload :CallHierarchyItem, "language_server/protocol/interface/call_hierarchy_item" + autoload :CallHierarchyOptions, "language_server/protocol/interface/call_hierarchy_options" + autoload :CallHierarchyOutgoingCall, "language_server/protocol/interface/call_hierarchy_outgoing_call" + autoload :CallHierarchyOutgoingCallsParams, "language_server/protocol/interface/call_hierarchy_outgoing_calls_params" + autoload :CallHierarchyPrepareParams, "language_server/protocol/interface/call_hierarchy_prepare_params" + autoload :CallHierarchyRegistrationOptions, "language_server/protocol/interface/call_hierarchy_registration_options" + autoload :CancelParams, "language_server/protocol/interface/cancel_params" + autoload :ChangeAnnotation, "language_server/protocol/interface/change_annotation" + autoload :ClientCapabilities, "language_server/protocol/interface/client_capabilities" + autoload :CodeAction, "language_server/protocol/interface/code_action" + autoload :CodeActionClientCapabilities, "language_server/protocol/interface/code_action_client_capabilities" + autoload :CodeActionContext, "language_server/protocol/interface/code_action_context" + autoload :CodeActionOptions, "language_server/protocol/interface/code_action_options" + autoload :CodeActionParams, "language_server/protocol/interface/code_action_params" + autoload :CodeActionRegistrationOptions, "language_server/protocol/interface/code_action_registration_options" + autoload :CodeDescription, "language_server/protocol/interface/code_description" + autoload :CodeLens, "language_server/protocol/interface/code_lens" + autoload :CodeLensClientCapabilities, "language_server/protocol/interface/code_lens_client_capabilities" + autoload :CodeLensOptions, "language_server/protocol/interface/code_lens_options" + autoload :CodeLensParams, "language_server/protocol/interface/code_lens_params" + autoload :CodeLensRegistrationOptions, "language_server/protocol/interface/code_lens_registration_options" + autoload :CodeLensWorkspaceClientCapabilities, "language_server/protocol/interface/code_lens_workspace_client_capabilities" + autoload :Color, "language_server/protocol/interface/color" + autoload :ColorInformation, "language_server/protocol/interface/color_information" + autoload :ColorPresentation, "language_server/protocol/interface/color_presentation" + autoload :ColorPresentationParams, "language_server/protocol/interface/color_presentation_params" + autoload :Command, "language_server/protocol/interface/command" + autoload :CompletionClientCapabilities, "language_server/protocol/interface/completion_client_capabilities" + autoload :CompletionContext, "language_server/protocol/interface/completion_context" + autoload :CompletionItem, "language_server/protocol/interface/completion_item" + autoload :CompletionItemLabelDetails, "language_server/protocol/interface/completion_item_label_details" + autoload :CompletionList, "language_server/protocol/interface/completion_list" + autoload :CompletionOptions, "language_server/protocol/interface/completion_options" + autoload :CompletionParams, "language_server/protocol/interface/completion_params" + autoload :CompletionRegistrationOptions, "language_server/protocol/interface/completion_registration_options" + autoload :ConfigurationItem, "language_server/protocol/interface/configuration_item" + autoload :ConfigurationParams, "language_server/protocol/interface/configuration_params" + autoload :CreateFile, "language_server/protocol/interface/create_file" + autoload :CreateFileOptions, "language_server/protocol/interface/create_file_options" + autoload :CreateFilesParams, "language_server/protocol/interface/create_files_params" + autoload :DeclarationClientCapabilities, "language_server/protocol/interface/declaration_client_capabilities" + autoload :DeclarationOptions, "language_server/protocol/interface/declaration_options" + autoload :DeclarationParams, "language_server/protocol/interface/declaration_params" + autoload :DeclarationRegistrationOptions, "language_server/protocol/interface/declaration_registration_options" + autoload :DefinitionClientCapabilities, "language_server/protocol/interface/definition_client_capabilities" + autoload :DefinitionOptions, "language_server/protocol/interface/definition_options" + autoload :DefinitionParams, "language_server/protocol/interface/definition_params" + autoload :DefinitionRegistrationOptions, "language_server/protocol/interface/definition_registration_options" + autoload :DeleteFile, "language_server/protocol/interface/delete_file" + autoload :DeleteFileOptions, "language_server/protocol/interface/delete_file_options" + autoload :DeleteFilesParams, "language_server/protocol/interface/delete_files_params" + autoload :Diagnostic, "language_server/protocol/interface/diagnostic" + autoload :DiagnosticClientCapabilities, "language_server/protocol/interface/diagnostic_client_capabilities" + autoload :DiagnosticOptions, "language_server/protocol/interface/diagnostic_options" + autoload :DiagnosticRegistrationOptions, "language_server/protocol/interface/diagnostic_registration_options" + autoload :DiagnosticRelatedInformation, "language_server/protocol/interface/diagnostic_related_information" + autoload :DiagnosticServerCancellationData, "language_server/protocol/interface/diagnostic_server_cancellation_data" + autoload :DiagnosticWorkspaceClientCapabilities, "language_server/protocol/interface/diagnostic_workspace_client_capabilities" + autoload :DidChangeConfigurationClientCapabilities, "language_server/protocol/interface/did_change_configuration_client_capabilities" + autoload :DidChangeConfigurationParams, "language_server/protocol/interface/did_change_configuration_params" + autoload :DidChangeNotebookDocumentParams, "language_server/protocol/interface/did_change_notebook_document_params" + autoload :DidChangeTextDocumentParams, "language_server/protocol/interface/did_change_text_document_params" + autoload :DidChangeWatchedFilesClientCapabilities, "language_server/protocol/interface/did_change_watched_files_client_capabilities" + autoload :DidChangeWatchedFilesParams, "language_server/protocol/interface/did_change_watched_files_params" + autoload :DidChangeWatchedFilesRegistrationOptions, "language_server/protocol/interface/did_change_watched_files_registration_options" + autoload :DidChangeWorkspaceFoldersParams, "language_server/protocol/interface/did_change_workspace_folders_params" + autoload :DidCloseNotebookDocumentParams, "language_server/protocol/interface/did_close_notebook_document_params" + autoload :DidCloseTextDocumentParams, "language_server/protocol/interface/did_close_text_document_params" + autoload :DidOpenNotebookDocumentParams, "language_server/protocol/interface/did_open_notebook_document_params" + autoload :DidOpenTextDocumentParams, "language_server/protocol/interface/did_open_text_document_params" + autoload :DidSaveNotebookDocumentParams, "language_server/protocol/interface/did_save_notebook_document_params" + autoload :DidSaveTextDocumentParams, "language_server/protocol/interface/did_save_text_document_params" + autoload :DocumentColorClientCapabilities, "language_server/protocol/interface/document_color_client_capabilities" + autoload :DocumentColorOptions, "language_server/protocol/interface/document_color_options" + autoload :DocumentColorParams, "language_server/protocol/interface/document_color_params" + autoload :DocumentColorRegistrationOptions, "language_server/protocol/interface/document_color_registration_options" + autoload :DocumentDiagnosticParams, "language_server/protocol/interface/document_diagnostic_params" + autoload :DocumentDiagnosticReportPartialResult, "language_server/protocol/interface/document_diagnostic_report_partial_result" + autoload :DocumentFilter, "language_server/protocol/interface/document_filter" + autoload :DocumentFormattingClientCapabilities, "language_server/protocol/interface/document_formatting_client_capabilities" + autoload :DocumentFormattingOptions, "language_server/protocol/interface/document_formatting_options" + autoload :DocumentFormattingParams, "language_server/protocol/interface/document_formatting_params" + autoload :DocumentFormattingRegistrationOptions, "language_server/protocol/interface/document_formatting_registration_options" + autoload :DocumentHighlight, "language_server/protocol/interface/document_highlight" + autoload :DocumentHighlightClientCapabilities, "language_server/protocol/interface/document_highlight_client_capabilities" + autoload :DocumentHighlightOptions, "language_server/protocol/interface/document_highlight_options" + autoload :DocumentHighlightParams, "language_server/protocol/interface/document_highlight_params" + autoload :DocumentHighlightRegistrationOptions, "language_server/protocol/interface/document_highlight_registration_options" + autoload :DocumentLink, "language_server/protocol/interface/document_link" + autoload :DocumentLinkClientCapabilities, "language_server/protocol/interface/document_link_client_capabilities" + autoload :DocumentLinkOptions, "language_server/protocol/interface/document_link_options" + autoload :DocumentLinkParams, "language_server/protocol/interface/document_link_params" + autoload :DocumentLinkRegistrationOptions, "language_server/protocol/interface/document_link_registration_options" + autoload :DocumentOnTypeFormattingClientCapabilities, "language_server/protocol/interface/document_on_type_formatting_client_capabilities" + autoload :DocumentOnTypeFormattingOptions, "language_server/protocol/interface/document_on_type_formatting_options" + autoload :DocumentOnTypeFormattingParams, "language_server/protocol/interface/document_on_type_formatting_params" + autoload :DocumentOnTypeFormattingRegistrationOptions, "language_server/protocol/interface/document_on_type_formatting_registration_options" + autoload :DocumentRangeFormattingClientCapabilities, "language_server/protocol/interface/document_range_formatting_client_capabilities" + autoload :DocumentRangeFormattingOptions, "language_server/protocol/interface/document_range_formatting_options" + autoload :DocumentRangeFormattingParams, "language_server/protocol/interface/document_range_formatting_params" + autoload :DocumentRangeFormattingRegistrationOptions, "language_server/protocol/interface/document_range_formatting_registration_options" + autoload :DocumentSymbol, "language_server/protocol/interface/document_symbol" + autoload :DocumentSymbolClientCapabilities, "language_server/protocol/interface/document_symbol_client_capabilities" + autoload :DocumentSymbolOptions, "language_server/protocol/interface/document_symbol_options" + autoload :DocumentSymbolParams, "language_server/protocol/interface/document_symbol_params" + autoload :DocumentSymbolRegistrationOptions, "language_server/protocol/interface/document_symbol_registration_options" + autoload :ExecuteCommandClientCapabilities, "language_server/protocol/interface/execute_command_client_capabilities" + autoload :ExecuteCommandOptions, "language_server/protocol/interface/execute_command_options" + autoload :ExecuteCommandParams, "language_server/protocol/interface/execute_command_params" + autoload :ExecuteCommandRegistrationOptions, "language_server/protocol/interface/execute_command_registration_options" + autoload :ExecutionSummary, "language_server/protocol/interface/execution_summary" + autoload :FileCreate, "language_server/protocol/interface/file_create" + autoload :FileDelete, "language_server/protocol/interface/file_delete" + autoload :FileEvent, "language_server/protocol/interface/file_event" + autoload :FileOperationFilter, "language_server/protocol/interface/file_operation_filter" + autoload :FileOperationPattern, "language_server/protocol/interface/file_operation_pattern" + autoload :FileOperationPatternOptions, "language_server/protocol/interface/file_operation_pattern_options" + autoload :FileOperationRegistrationOptions, "language_server/protocol/interface/file_operation_registration_options" + autoload :FileRename, "language_server/protocol/interface/file_rename" + autoload :FileSystemWatcher, "language_server/protocol/interface/file_system_watcher" + autoload :FoldingRange, "language_server/protocol/interface/folding_range" + autoload :FoldingRangeClientCapabilities, "language_server/protocol/interface/folding_range_client_capabilities" + autoload :FoldingRangeOptions, "language_server/protocol/interface/folding_range_options" + autoload :FoldingRangeParams, "language_server/protocol/interface/folding_range_params" + autoload :FoldingRangeRegistrationOptions, "language_server/protocol/interface/folding_range_registration_options" + autoload :FormattingOptions, "language_server/protocol/interface/formatting_options" + autoload :FullDocumentDiagnosticReport, "language_server/protocol/interface/full_document_diagnostic_report" + autoload :Hover, "language_server/protocol/interface/hover" + autoload :HoverClientCapabilities, "language_server/protocol/interface/hover_client_capabilities" + autoload :HoverOptions, "language_server/protocol/interface/hover_options" + autoload :HoverParams, "language_server/protocol/interface/hover_params" + autoload :HoverParams, "language_server/protocol/interface/hover_params" + autoload :HoverRegistrationOptions, "language_server/protocol/interface/hover_registration_options" + autoload :HoverResult, "language_server/protocol/interface/hover_result" + autoload :ImplementationClientCapabilities, "language_server/protocol/interface/implementation_client_capabilities" + autoload :ImplementationOptions, "language_server/protocol/interface/implementation_options" + autoload :ImplementationParams, "language_server/protocol/interface/implementation_params" + autoload :ImplementationRegistrationOptions, "language_server/protocol/interface/implementation_registration_options" + autoload :InitializeError, "language_server/protocol/interface/initialize_error" + autoload :InitializeParams, "language_server/protocol/interface/initialize_params" + autoload :InitializeResult, "language_server/protocol/interface/initialize_result" + autoload :InitializedParams, "language_server/protocol/interface/initialized_params" + autoload :InlayHint, "language_server/protocol/interface/inlay_hint" + autoload :InlayHintClientCapabilities, "language_server/protocol/interface/inlay_hint_client_capabilities" + autoload :InlayHintLabelPart, "language_server/protocol/interface/inlay_hint_label_part" + autoload :InlayHintOptions, "language_server/protocol/interface/inlay_hint_options" + autoload :InlayHintParams, "language_server/protocol/interface/inlay_hint_params" + autoload :InlayHintRegistrationOptions, "language_server/protocol/interface/inlay_hint_registration_options" + autoload :InlayHintWorkspaceClientCapabilities, "language_server/protocol/interface/inlay_hint_workspace_client_capabilities" + autoload :InlineValueClientCapabilities, "language_server/protocol/interface/inline_value_client_capabilities" + autoload :InlineValueContext, "language_server/protocol/interface/inline_value_context" + autoload :InlineValueEvaluatableExpression, "language_server/protocol/interface/inline_value_evaluatable_expression" + autoload :InlineValueOptions, "language_server/protocol/interface/inline_value_options" + autoload :InlineValueParams, "language_server/protocol/interface/inline_value_params" + autoload :InlineValueRegistrationOptions, "language_server/protocol/interface/inline_value_registration_options" + autoload :InlineValueText, "language_server/protocol/interface/inline_value_text" + autoload :InlineValueVariableLookup, "language_server/protocol/interface/inline_value_variable_lookup" + autoload :InlineValueWorkspaceClientCapabilities, "language_server/protocol/interface/inline_value_workspace_client_capabilities" + autoload :InsertReplaceEdit, "language_server/protocol/interface/insert_replace_edit" + autoload :LinkedEditingRangeClientCapabilities, "language_server/protocol/interface/linked_editing_range_client_capabilities" + autoload :LinkedEditingRangeOptions, "language_server/protocol/interface/linked_editing_range_options" + autoload :LinkedEditingRangeParams, "language_server/protocol/interface/linked_editing_range_params" + autoload :LinkedEditingRangeRegistrationOptions, "language_server/protocol/interface/linked_editing_range_registration_options" + autoload :LinkedEditingRanges, "language_server/protocol/interface/linked_editing_ranges" + autoload :Location, "language_server/protocol/interface/location" + autoload :LocationLink, "language_server/protocol/interface/location_link" + autoload :LogMessageParams, "language_server/protocol/interface/log_message_params" + autoload :LogTraceParams, "language_server/protocol/interface/log_trace_params" + autoload :MarkupContent, "language_server/protocol/interface/markup_content" + autoload :Message, "language_server/protocol/interface/message" + autoload :MessageActionItem, "language_server/protocol/interface/message_action_item" + autoload :Moniker, "language_server/protocol/interface/moniker" + autoload :MonikerClientCapabilities, "language_server/protocol/interface/moniker_client_capabilities" + autoload :MonikerOptions, "language_server/protocol/interface/moniker_options" + autoload :MonikerParams, "language_server/protocol/interface/moniker_params" + autoload :MonikerRegistrationOptions, "language_server/protocol/interface/moniker_registration_options" + autoload :NotebookCell, "language_server/protocol/interface/notebook_cell" + autoload :NotebookCellArrayChange, "language_server/protocol/interface/notebook_cell_array_change" + autoload :NotebookCellTextDocumentFilter, "language_server/protocol/interface/notebook_cell_text_document_filter" + autoload :NotebookDocument, "language_server/protocol/interface/notebook_document" + autoload :NotebookDocumentChangeEvent, "language_server/protocol/interface/notebook_document_change_event" + autoload :NotebookDocumentClientCapabilities, "language_server/protocol/interface/notebook_document_client_capabilities" + autoload :NotebookDocumentFilter, "language_server/protocol/interface/notebook_document_filter" + autoload :NotebookDocumentIdentifier, "language_server/protocol/interface/notebook_document_identifier" + autoload :NotebookDocumentSyncClientCapabilities, "language_server/protocol/interface/notebook_document_sync_client_capabilities" + autoload :NotebookDocumentSyncOptions, "language_server/protocol/interface/notebook_document_sync_options" + autoload :NotebookDocumentSyncRegistrationOptions, "language_server/protocol/interface/notebook_document_sync_registration_options" + autoload :NotificationMessage, "language_server/protocol/interface/notification_message" + autoload :OptionalVersionedTextDocumentIdentifier, "language_server/protocol/interface/optional_versioned_text_document_identifier" + autoload :ParameterInformation, "language_server/protocol/interface/parameter_information" + autoload :PartialResultParams, "language_server/protocol/interface/partial_result_params" + autoload :Position, "language_server/protocol/interface/position" + autoload :PrepareRenameParams, "language_server/protocol/interface/prepare_rename_params" + autoload :PreviousResultId, "language_server/protocol/interface/previous_result_id" + autoload :ProgressParams, "language_server/protocol/interface/progress_params" + autoload :PublishDiagnosticsClientCapabilities, "language_server/protocol/interface/publish_diagnostics_client_capabilities" + autoload :PublishDiagnosticsParams, "language_server/protocol/interface/publish_diagnostics_params" + autoload :Range, "language_server/protocol/interface/range" + autoload :ReferenceClientCapabilities, "language_server/protocol/interface/reference_client_capabilities" + autoload :ReferenceContext, "language_server/protocol/interface/reference_context" + autoload :ReferenceOptions, "language_server/protocol/interface/reference_options" + autoload :ReferenceParams, "language_server/protocol/interface/reference_params" + autoload :ReferenceRegistrationOptions, "language_server/protocol/interface/reference_registration_options" + autoload :Registration, "language_server/protocol/interface/registration" + autoload :RegistrationParams, "language_server/protocol/interface/registration_params" + autoload :RegularExpressionsClientCapabilities, "language_server/protocol/interface/regular_expressions_client_capabilities" + autoload :RelatedFullDocumentDiagnosticReport, "language_server/protocol/interface/related_full_document_diagnostic_report" + autoload :RelatedUnchangedDocumentDiagnosticReport, "language_server/protocol/interface/related_unchanged_document_diagnostic_report" + autoload :RelativePattern, "language_server/protocol/interface/relative_pattern" + autoload :RenameClientCapabilities, "language_server/protocol/interface/rename_client_capabilities" + autoload :RenameFile, "language_server/protocol/interface/rename_file" + autoload :RenameFileOptions, "language_server/protocol/interface/rename_file_options" + autoload :RenameFilesParams, "language_server/protocol/interface/rename_files_params" + autoload :RenameOptions, "language_server/protocol/interface/rename_options" + autoload :RenameParams, "language_server/protocol/interface/rename_params" + autoload :RenameRegistrationOptions, "language_server/protocol/interface/rename_registration_options" + autoload :RequestMessage, "language_server/protocol/interface/request_message" + autoload :ResponseError, "language_server/protocol/interface/response_error" + autoload :ResponseMessage, "language_server/protocol/interface/response_message" + autoload :SaveOptions, "language_server/protocol/interface/save_options" + autoload :SelectionRange, "language_server/protocol/interface/selection_range" + autoload :SelectionRangeClientCapabilities, "language_server/protocol/interface/selection_range_client_capabilities" + autoload :SelectionRangeOptions, "language_server/protocol/interface/selection_range_options" + autoload :SelectionRangeParams, "language_server/protocol/interface/selection_range_params" + autoload :SelectionRangeRegistrationOptions, "language_server/protocol/interface/selection_range_registration_options" + autoload :SemanticTokens, "language_server/protocol/interface/semantic_tokens" + autoload :SemanticTokensClientCapabilities, "language_server/protocol/interface/semantic_tokens_client_capabilities" + autoload :SemanticTokensDelta, "language_server/protocol/interface/semantic_tokens_delta" + autoload :SemanticTokensDeltaParams, "language_server/protocol/interface/semantic_tokens_delta_params" + autoload :SemanticTokensDeltaPartialResult, "language_server/protocol/interface/semantic_tokens_delta_partial_result" + autoload :SemanticTokensEdit, "language_server/protocol/interface/semantic_tokens_edit" + autoload :SemanticTokensLegend, "language_server/protocol/interface/semantic_tokens_legend" + autoload :SemanticTokensOptions, "language_server/protocol/interface/semantic_tokens_options" + autoload :SemanticTokensParams, "language_server/protocol/interface/semantic_tokens_params" + autoload :SemanticTokensPartialResult, "language_server/protocol/interface/semantic_tokens_partial_result" + autoload :SemanticTokensRangeParams, "language_server/protocol/interface/semantic_tokens_range_params" + autoload :SemanticTokensRegistrationOptions, "language_server/protocol/interface/semantic_tokens_registration_options" + autoload :SemanticTokensWorkspaceClientCapabilities, "language_server/protocol/interface/semantic_tokens_workspace_client_capabilities" + autoload :ServerCapabilities, "language_server/protocol/interface/server_capabilities" + autoload :SetTraceParams, "language_server/protocol/interface/set_trace_params" + autoload :ShowDocumentClientCapabilities, "language_server/protocol/interface/show_document_client_capabilities" + autoload :ShowDocumentParams, "language_server/protocol/interface/show_document_params" + autoload :ShowDocumentResult, "language_server/protocol/interface/show_document_result" + autoload :ShowMessageParams, "language_server/protocol/interface/show_message_params" + autoload :ShowMessageRequestClientCapabilities, "language_server/protocol/interface/show_message_request_client_capabilities" + autoload :ShowMessageRequestParams, "language_server/protocol/interface/show_message_request_params" + autoload :SignatureHelp, "language_server/protocol/interface/signature_help" + autoload :SignatureHelpClientCapabilities, "language_server/protocol/interface/signature_help_client_capabilities" + autoload :SignatureHelpContext, "language_server/protocol/interface/signature_help_context" + autoload :SignatureHelpOptions, "language_server/protocol/interface/signature_help_options" + autoload :SignatureHelpParams, "language_server/protocol/interface/signature_help_params" + autoload :SignatureHelpRegistrationOptions, "language_server/protocol/interface/signature_help_registration_options" + autoload :SignatureInformation, "language_server/protocol/interface/signature_information" + autoload :StaticRegistrationOptions, "language_server/protocol/interface/static_registration_options" + autoload :SymbolInformation, "language_server/protocol/interface/symbol_information" + autoload :TextDocumentChangeRegistrationOptions, "language_server/protocol/interface/text_document_change_registration_options" + autoload :TextDocumentClientCapabilities, "language_server/protocol/interface/text_document_client_capabilities" + autoload :TextDocumentContentChangeEvent, "language_server/protocol/interface/text_document_content_change_event" + autoload :TextDocumentEdit, "language_server/protocol/interface/text_document_edit" + autoload :TextDocumentIdentifier, "language_server/protocol/interface/text_document_identifier" + autoload :TextDocumentItem, "language_server/protocol/interface/text_document_item" + autoload :TextDocumentPositionParams, "language_server/protocol/interface/text_document_position_params" + autoload :TextDocumentRegistrationOptions, "language_server/protocol/interface/text_document_registration_options" + autoload :TextDocumentSaveRegistrationOptions, "language_server/protocol/interface/text_document_save_registration_options" + autoload :TextDocumentSyncClientCapabilities, "language_server/protocol/interface/text_document_sync_client_capabilities" + autoload :TextDocumentSyncOptions, "language_server/protocol/interface/text_document_sync_options" + autoload :TextDocumentSyncOptions, "language_server/protocol/interface/text_document_sync_options" + autoload :TextEdit, "language_server/protocol/interface/text_edit" + autoload :TypeDefinitionClientCapabilities, "language_server/protocol/interface/type_definition_client_capabilities" + autoload :TypeDefinitionOptions, "language_server/protocol/interface/type_definition_options" + autoload :TypeDefinitionParams, "language_server/protocol/interface/type_definition_params" + autoload :TypeDefinitionRegistrationOptions, "language_server/protocol/interface/type_definition_registration_options" + autoload :TypeHierarchyItem, "language_server/protocol/interface/type_hierarchy_item" + autoload :TypeHierarchyOptions, "language_server/protocol/interface/type_hierarchy_options" + autoload :TypeHierarchyPrepareParams, "language_server/protocol/interface/type_hierarchy_prepare_params" + autoload :TypeHierarchyRegistrationOptions, "language_server/protocol/interface/type_hierarchy_registration_options" + autoload :TypeHierarchySubtypesParams, "language_server/protocol/interface/type_hierarchy_subtypes_params" + autoload :TypeHierarchySupertypesParams, "language_server/protocol/interface/type_hierarchy_supertypes_params" + autoload :UnchangedDocumentDiagnosticReport, "language_server/protocol/interface/unchanged_document_diagnostic_report" + autoload :Unregistration, "language_server/protocol/interface/unregistration" + autoload :UnregistrationParams, "language_server/protocol/interface/unregistration_params" + autoload :VersionedNotebookDocumentIdentifier, "language_server/protocol/interface/versioned_notebook_document_identifier" + autoload :VersionedTextDocumentIdentifier, "language_server/protocol/interface/versioned_text_document_identifier" + autoload :WillSaveTextDocumentParams, "language_server/protocol/interface/will_save_text_document_params" + autoload :WorkDoneProgressBegin, "language_server/protocol/interface/work_done_progress_begin" + autoload :WorkDoneProgressCancelParams, "language_server/protocol/interface/work_done_progress_cancel_params" + autoload :WorkDoneProgressCreateParams, "language_server/protocol/interface/work_done_progress_create_params" + autoload :WorkDoneProgressEnd, "language_server/protocol/interface/work_done_progress_end" + autoload :WorkDoneProgressOptions, "language_server/protocol/interface/work_done_progress_options" + autoload :WorkDoneProgressParams, "language_server/protocol/interface/work_done_progress_params" + autoload :WorkDoneProgressReport, "language_server/protocol/interface/work_done_progress_report" + autoload :WorkspaceDiagnosticParams, "language_server/protocol/interface/workspace_diagnostic_params" + autoload :WorkspaceDiagnosticReport, "language_server/protocol/interface/workspace_diagnostic_report" + autoload :WorkspaceDiagnosticReportPartialResult, "language_server/protocol/interface/workspace_diagnostic_report_partial_result" + autoload :WorkspaceEdit, "language_server/protocol/interface/workspace_edit" + autoload :WorkspaceEditClientCapabilities, "language_server/protocol/interface/workspace_edit_client_capabilities" + autoload :WorkspaceFolder, "language_server/protocol/interface/workspace_folder" + autoload :WorkspaceFoldersChangeEvent, "language_server/protocol/interface/workspace_folders_change_event" + autoload :WorkspaceFoldersServerCapabilities, "language_server/protocol/interface/workspace_folders_server_capabilities" + autoload :WorkspaceFullDocumentDiagnosticReport, "language_server/protocol/interface/workspace_full_document_diagnostic_report" + autoload :WorkspaceSymbol, "language_server/protocol/interface/workspace_symbol" + autoload :WorkspaceSymbolClientCapabilities, "language_server/protocol/interface/workspace_symbol_client_capabilities" + autoload :WorkspaceSymbolOptions, "language_server/protocol/interface/workspace_symbol_options" + autoload :WorkspaceSymbolParams, "language_server/protocol/interface/workspace_symbol_params" + autoload :WorkspaceSymbolRegistrationOptions, "language_server/protocol/interface/workspace_symbol_registration_options" + autoload :WorkspaceUnchangedDocumentDiagnosticReport, "language_server/protocol/interface/workspace_unchanged_document_diagnostic_report" + + require_relative "interface/annotated_text_edit" + require_relative "interface/apply_workspace_edit_params" + require_relative "interface/apply_workspace_edit_result" + require_relative "interface/call_hierarchy_client_capabilities" + require_relative "interface/call_hierarchy_incoming_call" + require_relative "interface/call_hierarchy_incoming_calls_params" + require_relative "interface/call_hierarchy_item" + require_relative "interface/call_hierarchy_options" + require_relative "interface/call_hierarchy_outgoing_call" + require_relative "interface/call_hierarchy_outgoing_calls_params" + require_relative "interface/call_hierarchy_prepare_params" + require_relative "interface/call_hierarchy_registration_options" + require_relative "interface/cancel_params" + require_relative "interface/change_annotation" + require_relative "interface/client_capabilities" + require_relative "interface/code_action" + require_relative "interface/code_action_client_capabilities" + require_relative "interface/code_action_context" + require_relative "interface/code_action_options" + require_relative "interface/code_action_params" + require_relative "interface/code_action_registration_options" + require_relative "interface/code_description" + require_relative "interface/code_lens" + require_relative "interface/code_lens_client_capabilities" + require_relative "interface/code_lens_options" + require_relative "interface/code_lens_params" + require_relative "interface/code_lens_registration_options" + require_relative "interface/code_lens_workspace_client_capabilities" + require_relative "interface/color" + require_relative "interface/color_information" + require_relative "interface/color_presentation" + require_relative "interface/color_presentation_params" + require_relative "interface/command" + require_relative "interface/completion_client_capabilities" + require_relative "interface/completion_context" + require_relative "interface/completion_item" + require_relative "interface/completion_item_label_details" + require_relative "interface/completion_list" + require_relative "interface/completion_options" + require_relative "interface/completion_params" + require_relative "interface/completion_registration_options" + require_relative "interface/configuration_item" + require_relative "interface/configuration_params" + require_relative "interface/create_file" + require_relative "interface/create_file_options" + require_relative "interface/create_files_params" + require_relative "interface/declaration_client_capabilities" + require_relative "interface/declaration_options" + require_relative "interface/declaration_params" + require_relative "interface/declaration_registration_options" + require_relative "interface/definition_client_capabilities" + require_relative "interface/definition_options" + require_relative "interface/definition_params" + require_relative "interface/definition_registration_options" + require_relative "interface/delete_file" + require_relative "interface/delete_file_options" + require_relative "interface/delete_files_params" + require_relative "interface/diagnostic" + require_relative "interface/diagnostic_client_capabilities" + require_relative "interface/diagnostic_options" + require_relative "interface/diagnostic_registration_options" + require_relative "interface/diagnostic_related_information" + require_relative "interface/diagnostic_server_cancellation_data" + require_relative "interface/diagnostic_workspace_client_capabilities" + require_relative "interface/did_change_configuration_client_capabilities" + require_relative "interface/did_change_configuration_params" + require_relative "interface/did_change_notebook_document_params" + require_relative "interface/did_change_text_document_params" + require_relative "interface/did_change_watched_files_client_capabilities" + require_relative "interface/did_change_watched_files_params" + require_relative "interface/did_change_watched_files_registration_options" + require_relative "interface/did_change_workspace_folders_params" + require_relative "interface/did_close_notebook_document_params" + require_relative "interface/did_close_text_document_params" + require_relative "interface/did_open_notebook_document_params" + require_relative "interface/did_open_text_document_params" + require_relative "interface/did_save_notebook_document_params" + require_relative "interface/did_save_text_document_params" + require_relative "interface/document_color_client_capabilities" + require_relative "interface/document_color_options" + require_relative "interface/document_color_params" + require_relative "interface/document_color_registration_options" + require_relative "interface/document_diagnostic_params" + require_relative "interface/document_diagnostic_report_partial_result" + require_relative "interface/document_filter" + require_relative "interface/document_formatting_client_capabilities" + require_relative "interface/document_formatting_options" + require_relative "interface/document_formatting_params" + require_relative "interface/document_formatting_registration_options" + require_relative "interface/document_highlight" + require_relative "interface/document_highlight_client_capabilities" + require_relative "interface/document_highlight_options" + require_relative "interface/document_highlight_params" + require_relative "interface/document_highlight_registration_options" + require_relative "interface/document_link" + require_relative "interface/document_link_client_capabilities" + require_relative "interface/document_link_options" + require_relative "interface/document_link_params" + require_relative "interface/document_link_registration_options" + require_relative "interface/document_on_type_formatting_client_capabilities" + require_relative "interface/document_on_type_formatting_options" + require_relative "interface/document_on_type_formatting_params" + require_relative "interface/document_on_type_formatting_registration_options" + require_relative "interface/document_range_formatting_client_capabilities" + require_relative "interface/document_range_formatting_options" + require_relative "interface/document_range_formatting_params" + require_relative "interface/document_range_formatting_registration_options" + require_relative "interface/document_symbol" + require_relative "interface/document_symbol_client_capabilities" + require_relative "interface/document_symbol_options" + require_relative "interface/document_symbol_params" + require_relative "interface/document_symbol_registration_options" + require_relative "interface/execute_command_client_capabilities" + require_relative "interface/execute_command_options" + require_relative "interface/execute_command_params" + require_relative "interface/execute_command_registration_options" + require_relative "interface/execution_summary" + require_relative "interface/file_create" + require_relative "interface/file_delete" + require_relative "interface/file_event" + require_relative "interface/file_operation_filter" + require_relative "interface/file_operation_pattern" + require_relative "interface/file_operation_pattern_options" + require_relative "interface/file_operation_registration_options" + require_relative "interface/file_rename" + require_relative "interface/file_system_watcher" + require_relative "interface/folding_range" + require_relative "interface/folding_range_client_capabilities" + require_relative "interface/folding_range_options" + require_relative "interface/folding_range_params" + require_relative "interface/folding_range_registration_options" + require_relative "interface/formatting_options" + require_relative "interface/full_document_diagnostic_report" + require_relative "interface/hover" + require_relative "interface/hover_client_capabilities" + require_relative "interface/hover_options" + require_relative "interface/hover_params" + require_relative "interface/hover_params" + require_relative "interface/hover_registration_options" + require_relative "interface/hover_result" + require_relative "interface/implementation_client_capabilities" + require_relative "interface/implementation_options" + require_relative "interface/implementation_params" + require_relative "interface/implementation_registration_options" + require_relative "interface/initialize_error" + require_relative "interface/initialize_params" + require_relative "interface/initialize_result" + require_relative "interface/initialized_params" + require_relative "interface/inlay_hint" + require_relative "interface/inlay_hint_client_capabilities" + require_relative "interface/inlay_hint_label_part" + require_relative "interface/inlay_hint_options" + require_relative "interface/inlay_hint_params" + require_relative "interface/inlay_hint_registration_options" + require_relative "interface/inlay_hint_workspace_client_capabilities" + require_relative "interface/inline_value_client_capabilities" + require_relative "interface/inline_value_context" + require_relative "interface/inline_value_evaluatable_expression" + require_relative "interface/inline_value_options" + require_relative "interface/inline_value_params" + require_relative "interface/inline_value_registration_options" + require_relative "interface/inline_value_text" + require_relative "interface/inline_value_variable_lookup" + require_relative "interface/inline_value_workspace_client_capabilities" + require_relative "interface/insert_replace_edit" + require_relative "interface/linked_editing_range_client_capabilities" + require_relative "interface/linked_editing_range_options" + require_relative "interface/linked_editing_range_params" + require_relative "interface/linked_editing_range_registration_options" + require_relative "interface/linked_editing_ranges" + require_relative "interface/location" + require_relative "interface/location_link" + require_relative "interface/log_message_params" + require_relative "interface/log_trace_params" + require_relative "interface/markup_content" + require_relative "interface/message" + require_relative "interface/message_action_item" + require_relative "interface/moniker" + require_relative "interface/moniker_client_capabilities" + require_relative "interface/moniker_options" + require_relative "interface/moniker_params" + require_relative "interface/moniker_registration_options" + require_relative "interface/notebook_cell" + require_relative "interface/notebook_cell_array_change" + require_relative "interface/notebook_cell_text_document_filter" + require_relative "interface/notebook_document" + require_relative "interface/notebook_document_change_event" + require_relative "interface/notebook_document_client_capabilities" + require_relative "interface/notebook_document_filter" + require_relative "interface/notebook_document_identifier" + require_relative "interface/notebook_document_sync_client_capabilities" + require_relative "interface/notebook_document_sync_options" + require_relative "interface/notebook_document_sync_registration_options" + require_relative "interface/notification_message" + require_relative "interface/optional_versioned_text_document_identifier" + require_relative "interface/parameter_information" + require_relative "interface/partial_result_params" + require_relative "interface/position" + require_relative "interface/prepare_rename_params" + require_relative "interface/previous_result_id" + require_relative "interface/progress_params" + require_relative "interface/publish_diagnostics_client_capabilities" + require_relative "interface/publish_diagnostics_params" + require_relative "interface/range" + require_relative "interface/reference_client_capabilities" + require_relative "interface/reference_context" + require_relative "interface/reference_options" + require_relative "interface/reference_params" + require_relative "interface/reference_registration_options" + require_relative "interface/registration" + require_relative "interface/registration_params" + require_relative "interface/regular_expressions_client_capabilities" + require_relative "interface/related_full_document_diagnostic_report" + require_relative "interface/related_unchanged_document_diagnostic_report" + require_relative "interface/relative_pattern" + require_relative "interface/rename_client_capabilities" + require_relative "interface/rename_file" + require_relative "interface/rename_file_options" + require_relative "interface/rename_files_params" + require_relative "interface/rename_options" + require_relative "interface/rename_params" + require_relative "interface/rename_registration_options" + require_relative "interface/request_message" + require_relative "interface/response_error" + require_relative "interface/response_message" + require_relative "interface/save_options" + require_relative "interface/selection_range" + require_relative "interface/selection_range_client_capabilities" + require_relative "interface/selection_range_options" + require_relative "interface/selection_range_params" + require_relative "interface/selection_range_registration_options" + require_relative "interface/semantic_tokens" + require_relative "interface/semantic_tokens_client_capabilities" + require_relative "interface/semantic_tokens_delta" + require_relative "interface/semantic_tokens_delta_params" + require_relative "interface/semantic_tokens_delta_partial_result" + require_relative "interface/semantic_tokens_edit" + require_relative "interface/semantic_tokens_legend" + require_relative "interface/semantic_tokens_options" + require_relative "interface/semantic_tokens_params" + require_relative "interface/semantic_tokens_partial_result" + require_relative "interface/semantic_tokens_range_params" + require_relative "interface/semantic_tokens_registration_options" + require_relative "interface/semantic_tokens_workspace_client_capabilities" + require_relative "interface/server_capabilities" + require_relative "interface/set_trace_params" + require_relative "interface/show_document_client_capabilities" + require_relative "interface/show_document_params" + require_relative "interface/show_document_result" + require_relative "interface/show_message_params" + require_relative "interface/show_message_request_client_capabilities" + require_relative "interface/show_message_request_params" + require_relative "interface/signature_help" + require_relative "interface/signature_help_client_capabilities" + require_relative "interface/signature_help_context" + require_relative "interface/signature_help_options" + require_relative "interface/signature_help_params" + require_relative "interface/signature_help_registration_options" + require_relative "interface/signature_information" + require_relative "interface/static_registration_options" + require_relative "interface/symbol_information" + require_relative "interface/text_document_change_registration_options" + require_relative "interface/text_document_client_capabilities" + require_relative "interface/text_document_content_change_event" + require_relative "interface/text_document_edit" + require_relative "interface/text_document_identifier" + require_relative "interface/text_document_item" + require_relative "interface/text_document_position_params" + require_relative "interface/text_document_registration_options" + require_relative "interface/text_document_save_registration_options" + require_relative "interface/text_document_sync_client_capabilities" + require_relative "interface/text_document_sync_options" + require_relative "interface/text_document_sync_options" + require_relative "interface/text_edit" + require_relative "interface/type_definition_client_capabilities" + require_relative "interface/type_definition_options" + require_relative "interface/type_definition_params" + require_relative "interface/type_definition_registration_options" + require_relative "interface/type_hierarchy_item" + require_relative "interface/type_hierarchy_options" + require_relative "interface/type_hierarchy_prepare_params" + require_relative "interface/type_hierarchy_registration_options" + require_relative "interface/type_hierarchy_subtypes_params" + require_relative "interface/type_hierarchy_supertypes_params" + require_relative "interface/unchanged_document_diagnostic_report" + require_relative "interface/unregistration" + require_relative "interface/unregistration_params" + require_relative "interface/versioned_notebook_document_identifier" + require_relative "interface/versioned_text_document_identifier" + require_relative "interface/will_save_text_document_params" + require_relative "interface/work_done_progress_begin" + require_relative "interface/work_done_progress_cancel_params" + require_relative "interface/work_done_progress_create_params" + require_relative "interface/work_done_progress_end" + require_relative "interface/work_done_progress_options" + require_relative "interface/work_done_progress_params" + require_relative "interface/work_done_progress_report" + require_relative "interface/workspace_diagnostic_params" + require_relative "interface/workspace_diagnostic_report" + require_relative "interface/workspace_diagnostic_report_partial_result" + require_relative "interface/workspace_edit" + require_relative "interface/workspace_edit_client_capabilities" + require_relative "interface/workspace_folder" + require_relative "interface/workspace_folders_change_event" + require_relative "interface/workspace_folders_server_capabilities" + require_relative "interface/workspace_full_document_diagnostic_report" + require_relative "interface/workspace_symbol" + require_relative "interface/workspace_symbol_client_capabilities" + require_relative "interface/workspace_symbol_options" + require_relative "interface/workspace_symbol_params" + require_relative "interface/workspace_symbol_registration_options" + require_relative "interface/workspace_unchanged_document_diagnostic_report" + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/annotated_text_edit.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/annotated_text_edit.rb new file mode 100644 index 00000000..4aa719fd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/annotated_text_edit.rb @@ -0,0 +1,56 @@ +module LanguageServer + module Protocol + module Interface + # + # A special text edit with an additional change annotation. + # + class AnnotatedTextEdit + def initialize(range:, new_text:, annotation_id:) + @attributes = {} + + @attributes[:range] = range + @attributes[:newText] = new_text + @attributes[:annotationId] = annotation_id + + @attributes.freeze + end + + # + # The range of the text document to be manipulated. To insert + # text into a document create a range where start === end. + # + # @return [Range] + def range + attributes.fetch(:range) + end + + # + # The string to be inserted. For delete operations use an + # empty string. + # + # @return [string] + def new_text + attributes.fetch(:newText) + end + + # + # The actual annotation identifier. + # + # @return [string] + def annotation_id + attributes.fetch(:annotationId) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/apply_workspace_edit_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/apply_workspace_edit_params.rb new file mode 100644 index 00000000..9b55171a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/apply_workspace_edit_params.rb @@ -0,0 +1,44 @@ +module LanguageServer + module Protocol + module Interface + class ApplyWorkspaceEditParams + def initialize(label: nil, edit:) + @attributes = {} + + @attributes[:label] = label if label + @attributes[:edit] = edit + + @attributes.freeze + end + + # + # An optional label of the workspace edit. This label is + # presented in the user interface for example on an undo + # stack to undo the workspace edit. + # + # @return [string] + def label + attributes.fetch(:label) + end + + # + # The edits to apply. + # + # @return [WorkspaceEdit] + def edit + attributes.fetch(:edit) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/apply_workspace_edit_result.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/apply_workspace_edit_result.rb new file mode 100644 index 00000000..178e7f3d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/apply_workspace_edit_result.rb @@ -0,0 +1,56 @@ +module LanguageServer + module Protocol + module Interface + class ApplyWorkspaceEditResult + def initialize(applied:, failure_reason: nil, failed_change: nil) + @attributes = {} + + @attributes[:applied] = applied + @attributes[:failureReason] = failure_reason if failure_reason + @attributes[:failedChange] = failed_change if failed_change + + @attributes.freeze + end + + # + # Indicates whether the edit was applied or not. + # + # @return [boolean] + def applied + attributes.fetch(:applied) + end + + # + # An optional textual description for why the edit was not applied. + # This may be used by the server for diagnostic logging or to provide + # a suitable error for a request that triggered the edit. + # + # @return [string] + def failure_reason + attributes.fetch(:failureReason) + end + + # + # Depending on the client's failure handling strategy `failedChange` + # might contain the index of the change that failed. This property is + # only available if the client signals a `failureHandling` strategy + # in its client capabilities. + # + # @return [number] + def failed_change + attributes.fetch(:failedChange) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_client_capabilities.rb new file mode 100644 index 00000000..fdeed261 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_client_capabilities.rb @@ -0,0 +1,36 @@ +module LanguageServer + module Protocol + module Interface + class CallHierarchyClientCapabilities + def initialize(dynamic_registration: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + + @attributes.freeze + end + + # + # Whether implementation supports dynamic registration. If this is set to + # `true` the client supports the new `(TextDocumentRegistrationOptions & + # StaticRegistrationOptions)` return value for the corresponding server + # capability as well. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_incoming_call.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_incoming_call.rb new file mode 100644 index 00000000..81665d11 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_incoming_call.rb @@ -0,0 +1,43 @@ +module LanguageServer + module Protocol + module Interface + class CallHierarchyIncomingCall + def initialize(from:, from_ranges:) + @attributes = {} + + @attributes[:from] = from + @attributes[:fromRanges] = from_ranges + + @attributes.freeze + end + + # + # The item that makes the call. + # + # @return [CallHierarchyItem] + def from + attributes.fetch(:from) + end + + # + # The ranges at which the calls appear. This is relative to the caller + # denoted by [`this.from`](#CallHierarchyIncomingCall.from). + # + # @return [Range[]] + def from_ranges + attributes.fetch(:fromRanges) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_incoming_calls_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_incoming_calls_params.rb new file mode 100644 index 00000000..2032e344 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_incoming_calls_params.rb @@ -0,0 +1,49 @@ +module LanguageServer + module Protocol + module Interface + class CallHierarchyIncomingCallsParams + def initialize(work_done_token: nil, partial_result_token: nil, item:) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + @attributes[:item] = item + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + # @return [CallHierarchyItem] + def item + attributes.fetch(:item) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_item.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_item.rb new file mode 100644 index 00000000..82836bbf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_item.rb @@ -0,0 +1,100 @@ +module LanguageServer + module Protocol + module Interface + class CallHierarchyItem + def initialize(name:, kind:, tags: nil, detail: nil, uri:, range:, selection_range:, data: nil) + @attributes = {} + + @attributes[:name] = name + @attributes[:kind] = kind + @attributes[:tags] = tags if tags + @attributes[:detail] = detail if detail + @attributes[:uri] = uri + @attributes[:range] = range + @attributes[:selectionRange] = selection_range + @attributes[:data] = data if data + + @attributes.freeze + end + + # + # The name of this item. + # + # @return [string] + def name + attributes.fetch(:name) + end + + # + # The kind of this item. + # + # @return [SymbolKind] + def kind + attributes.fetch(:kind) + end + + # + # Tags for this item. + # + # @return [1[]] + def tags + attributes.fetch(:tags) + end + + # + # More detail for this item, e.g. the signature of a function. + # + # @return [string] + def detail + attributes.fetch(:detail) + end + + # + # The resource identifier of this item. + # + # @return [string] + def uri + attributes.fetch(:uri) + end + + # + # The range enclosing this symbol not including leading/trailing whitespace + # but everything else, e.g. comments and code. + # + # @return [Range] + def range + attributes.fetch(:range) + end + + # + # The range that should be selected and revealed when this symbol is being + # picked, e.g. the name of a function. Must be contained by the + # [`range`](#CallHierarchyItem.range). + # + # @return [Range] + def selection_range + attributes.fetch(:selectionRange) + end + + # + # A data entry field that is preserved between a call hierarchy prepare and + # incoming calls or outgoing calls requests. + # + # @return [unknown] + def data + attributes.fetch(:data) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_options.rb new file mode 100644 index 00000000..2d352600 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_options.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Interface + class CallHierarchyOptions + def initialize(work_done_progress: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_outgoing_call.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_outgoing_call.rb new file mode 100644 index 00000000..6c636e9f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_outgoing_call.rb @@ -0,0 +1,43 @@ +module LanguageServer + module Protocol + module Interface + class CallHierarchyOutgoingCall + def initialize(to:, from_ranges:) + @attributes = {} + + @attributes[:to] = to + @attributes[:fromRanges] = from_ranges + + @attributes.freeze + end + + # + # The item that is called. + # + # @return [CallHierarchyItem] + def to + attributes.fetch(:to) + end + + # + # The range at which this item is called. This is the range relative to + # the caller, e.g the item passed to `callHierarchy/outgoingCalls` request. + # + # @return [Range[]] + def from_ranges + attributes.fetch(:fromRanges) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_outgoing_calls_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_outgoing_calls_params.rb new file mode 100644 index 00000000..d7331268 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_outgoing_calls_params.rb @@ -0,0 +1,49 @@ +module LanguageServer + module Protocol + module Interface + class CallHierarchyOutgoingCallsParams + def initialize(work_done_token: nil, partial_result_token: nil, item:) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + @attributes[:item] = item + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + # @return [CallHierarchyItem] + def item + attributes.fetch(:item) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_prepare_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_prepare_params.rb new file mode 100644 index 00000000..88501f31 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_prepare_params.rb @@ -0,0 +1,51 @@ +module LanguageServer + module Protocol + module Interface + class CallHierarchyPrepareParams + def initialize(text_document:, position:, work_done_token: nil) + @attributes = {} + + @attributes[:textDocument] = text_document + @attributes[:position] = position + @attributes[:workDoneToken] = work_done_token if work_done_token + + @attributes.freeze + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The position inside the text document. + # + # @return [Position] + def position + attributes.fetch(:position) + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_registration_options.rb new file mode 100644 index 00000000..0345d27e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/call_hierarchy_registration_options.rb @@ -0,0 +1,50 @@ +module LanguageServer + module Protocol + module Interface + class CallHierarchyRegistrationOptions + def initialize(document_selector:, work_done_progress: nil, id: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:id] = id if id + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # The id used to register the request. The id can be used to deregister + # the request again. See also Registration#id. + # + # @return [string] + def id + attributes.fetch(:id) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/cancel_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/cancel_params.rb new file mode 100644 index 00000000..3223acf0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/cancel_params.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + class CancelParams + def initialize(id:) + @attributes = {} + + @attributes[:id] = id + + @attributes.freeze + end + + # + # The request id to cancel. + # + # @return [string | number] + def id + attributes.fetch(:id) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/change_annotation.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/change_annotation.rb new file mode 100644 index 00000000..75ac91d4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/change_annotation.rb @@ -0,0 +1,57 @@ +module LanguageServer + module Protocol + module Interface + # + # Additional information that describes document changes. + # + class ChangeAnnotation + def initialize(label:, needs_confirmation: nil, description: nil) + @attributes = {} + + @attributes[:label] = label + @attributes[:needsConfirmation] = needs_confirmation if needs_confirmation + @attributes[:description] = description if description + + @attributes.freeze + end + + # + # A human-readable string describing the actual change. The string + # is rendered prominent in the user interface. + # + # @return [string] + def label + attributes.fetch(:label) + end + + # + # A flag which indicates that user confirmation is needed + # before applying the change. + # + # @return [boolean] + def needs_confirmation + attributes.fetch(:needsConfirmation) + end + + # + # A human-readable string which is rendered less prominent in + # the user interface. + # + # @return [string] + def description + attributes.fetch(:description) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/client_capabilities.rb new file mode 100644 index 00000000..0e3667ce --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/client_capabilities.rb @@ -0,0 +1,78 @@ +module LanguageServer + module Protocol + module Interface + class ClientCapabilities + def initialize(workspace: nil, text_document: nil, notebook_document: nil, window: nil, general: nil, experimental: nil) + @attributes = {} + + @attributes[:workspace] = workspace if workspace + @attributes[:textDocument] = text_document if text_document + @attributes[:notebookDocument] = notebook_document if notebook_document + @attributes[:window] = window if window + @attributes[:general] = general if general + @attributes[:experimental] = experimental if experimental + + @attributes.freeze + end + + # + # Workspace specific client capabilities. + # + # @return [{ applyEdit?: boolean; workspaceEdit?: WorkspaceEditClientCapabilities; didChangeConfiguration?: DidChangeConfigurationClientCapabilities; ... 10 more ...; diagnostics?: DiagnosticWorkspaceClientCapabilities; }] + def workspace + attributes.fetch(:workspace) + end + + # + # Text document specific client capabilities. + # + # @return [TextDocumentClientCapabilities] + def text_document + attributes.fetch(:textDocument) + end + + # + # Capabilities specific to the notebook document support. + # + # @return [NotebookDocumentClientCapabilities] + def notebook_document + attributes.fetch(:notebookDocument) + end + + # + # Window specific client capabilities. + # + # @return [{ workDoneProgress?: boolean; showMessage?: ShowMessageRequestClientCapabilities; showDocument?: ShowDocumentClientCapabilities; }] + def window + attributes.fetch(:window) + end + + # + # General client capabilities. + # + # @return [{ staleRequestSupport?: { cancel: boolean; retryOnContentModified: string[]; }; regularExpressions?: RegularExpressionsClientCapabilities; markdown?: any; positionEncodings?: string[]; }] + def general + attributes.fetch(:general) + end + + # + # Experimental client capabilities. + # + # @return [LSPAny] + def experimental + attributes.fetch(:experimental) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_action.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_action.rb new file mode 100644 index 00000000..c7876625 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_action.rb @@ -0,0 +1,127 @@ +module LanguageServer + module Protocol + module Interface + # + # A code action represents a change that can be performed in code, e.g. to fix + # a problem or to refactor code. + # + # A CodeAction must set either `edit` and/or a `command`. If both are supplied, + # the `edit` is applied first, then the `command` is executed. + # + class CodeAction + def initialize(title:, kind: nil, diagnostics: nil, is_preferred: nil, disabled: nil, edit: nil, command: nil, data: nil) + @attributes = {} + + @attributes[:title] = title + @attributes[:kind] = kind if kind + @attributes[:diagnostics] = diagnostics if diagnostics + @attributes[:isPreferred] = is_preferred if is_preferred + @attributes[:disabled] = disabled if disabled + @attributes[:edit] = edit if edit + @attributes[:command] = command if command + @attributes[:data] = data if data + + @attributes.freeze + end + + # + # A short, human-readable, title for this code action. + # + # @return [string] + def title + attributes.fetch(:title) + end + + # + # The kind of the code action. + # + # Used to filter code actions. + # + # @return [string] + def kind + attributes.fetch(:kind) + end + + # + # The diagnostics that this code action resolves. + # + # @return [Diagnostic[]] + def diagnostics + attributes.fetch(:diagnostics) + end + + # + # Marks this as a preferred action. Preferred actions are used by the + # `auto fix` command and can be targeted by keybindings. + # + # A quick fix should be marked preferred if it properly addresses the + # underlying error. A refactoring should be marked preferred if it is the + # most reasonable choice of actions to take. + # + # @return [boolean] + def is_preferred + attributes.fetch(:isPreferred) + end + + # + # Marks that the code action cannot currently be applied. + # + # Clients should follow the following guidelines regarding disabled code + # actions: + # + # - Disabled code actions are not shown in automatic lightbulbs code + # action menus. + # + # - Disabled actions are shown as faded out in the code action menu when + # the user request a more specific type of code action, such as + # refactorings. + # + # - If the user has a keybinding that auto applies a code action and only + # a disabled code actions are returned, the client should show the user + # an error message with `reason` in the editor. + # + # @return [{ reason: string; }] + def disabled + attributes.fetch(:disabled) + end + + # + # The workspace edit this code action performs. + # + # @return [WorkspaceEdit] + def edit + attributes.fetch(:edit) + end + + # + # A command this code action executes. If a code action + # provides an edit and a command, first the edit is + # executed and then the command. + # + # @return [Command] + def command + attributes.fetch(:command) + end + + # + # A data entry field that is preserved on a code action between + # a `textDocument/codeAction` and a `codeAction/resolve` request. + # + # @return [LSPAny] + def data + attributes.fetch(:data) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_action_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_action_client_capabilities.rb new file mode 100644 index 00000000..57168a7e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_action_client_capabilities.rb @@ -0,0 +1,95 @@ +module LanguageServer + module Protocol + module Interface + class CodeActionClientCapabilities + def initialize(dynamic_registration: nil, code_action_literal_support: nil, is_preferred_support: nil, disabled_support: nil, data_support: nil, resolve_support: nil, honors_change_annotations: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + @attributes[:codeActionLiteralSupport] = code_action_literal_support if code_action_literal_support + @attributes[:isPreferredSupport] = is_preferred_support if is_preferred_support + @attributes[:disabledSupport] = disabled_support if disabled_support + @attributes[:dataSupport] = data_support if data_support + @attributes[:resolveSupport] = resolve_support if resolve_support + @attributes[:honorsChangeAnnotations] = honors_change_annotations if honors_change_annotations + + @attributes.freeze + end + + # + # Whether code action supports dynamic registration. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + # + # The client supports code action literals as a valid + # response of the `textDocument/codeAction` request. + # + # @return [{ codeActionKind: { valueSet: string[]; }; }] + def code_action_literal_support + attributes.fetch(:codeActionLiteralSupport) + end + + # + # Whether code action supports the `isPreferred` property. + # + # @return [boolean] + def is_preferred_support + attributes.fetch(:isPreferredSupport) + end + + # + # Whether code action supports the `disabled` property. + # + # @return [boolean] + def disabled_support + attributes.fetch(:disabledSupport) + end + + # + # Whether code action supports the `data` property which is + # preserved between a `textDocument/codeAction` and a + # `codeAction/resolve` request. + # + # @return [boolean] + def data_support + attributes.fetch(:dataSupport) + end + + # + # Whether the client supports resolving additional code action + # properties via a separate `codeAction/resolve` request. + # + # @return [{ properties: string[]; }] + def resolve_support + attributes.fetch(:resolveSupport) + end + + # + # Whether the client honors the change annotations in + # text edits and resource operations returned via the + # `CodeAction#edit` property by for example presenting + # the workspace edit in the user interface and asking + # for confirmation. + # + # @return [boolean] + def honors_change_annotations + attributes.fetch(:honorsChangeAnnotations) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_action_context.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_action_context.rb new file mode 100644 index 00000000..18ae99ad --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_action_context.rb @@ -0,0 +1,63 @@ +module LanguageServer + module Protocol + module Interface + # + # Contains additional diagnostic information about the context in which + # a code action is run. + # + class CodeActionContext + def initialize(diagnostics:, only: nil, trigger_kind: nil) + @attributes = {} + + @attributes[:diagnostics] = diagnostics + @attributes[:only] = only if only + @attributes[:triggerKind] = trigger_kind if trigger_kind + + @attributes.freeze + end + + # + # An array of diagnostics known on the client side overlapping the range + # provided to the `textDocument/codeAction` request. They are provided so + # that the server knows which errors are currently presented to the user + # for the given range. There is no guarantee that these accurately reflect + # the error state of the resource. The primary parameter + # to compute code actions is the provided range. + # + # @return [Diagnostic[]] + def diagnostics + attributes.fetch(:diagnostics) + end + + # + # Requested kind of actions to return. + # + # Actions not of this kind are filtered out by the client before being + # shown. So servers can omit computing them. + # + # @return [string[]] + def only + attributes.fetch(:only) + end + + # + # The reason why code actions were requested. + # + # @return [CodeActionTriggerKind] + def trigger_kind + attributes.fetch(:triggerKind) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_action_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_action_options.rb new file mode 100644 index 00000000..757fdd42 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_action_options.rb @@ -0,0 +1,52 @@ +module LanguageServer + module Protocol + module Interface + class CodeActionOptions + def initialize(work_done_progress: nil, code_action_kinds: nil, resolve_provider: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:codeActionKinds] = code_action_kinds if code_action_kinds + @attributes[:resolveProvider] = resolve_provider if resolve_provider + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # CodeActionKinds that this server may return. + # + # The list of kinds may be generic, such as `CodeActionKind.Refactor`, + # or the server may list out every specific kind they provide. + # + # @return [string[]] + def code_action_kinds + attributes.fetch(:codeActionKinds) + end + + # + # The server provides support to resolve additional + # information for a code action. + # + # @return [boolean] + def resolve_provider + attributes.fetch(:resolveProvider) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_action_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_action_params.rb new file mode 100644 index 00000000..45131f2a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_action_params.rb @@ -0,0 +1,73 @@ +module LanguageServer + module Protocol + module Interface + # + # Params for the CodeActionRequest + # + class CodeActionParams + def initialize(work_done_token: nil, partial_result_token: nil, text_document:, range:, context:) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + @attributes[:textDocument] = text_document + @attributes[:range] = range + @attributes[:context] = context + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + # + # The document in which the command was invoked. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The range for which the command was invoked. + # + # @return [Range] + def range + attributes.fetch(:range) + end + + # + # Context carrying additional information. + # + # @return [CodeActionContext] + def context + attributes.fetch(:context) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_action_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_action_registration_options.rb new file mode 100644 index 00000000..c59ebf64 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_action_registration_options.rb @@ -0,0 +1,62 @@ +module LanguageServer + module Protocol + module Interface + class CodeActionRegistrationOptions + def initialize(document_selector:, work_done_progress: nil, code_action_kinds: nil, resolve_provider: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:codeActionKinds] = code_action_kinds if code_action_kinds + @attributes[:resolveProvider] = resolve_provider if resolve_provider + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # CodeActionKinds that this server may return. + # + # The list of kinds may be generic, such as `CodeActionKind.Refactor`, + # or the server may list out every specific kind they provide. + # + # @return [string[]] + def code_action_kinds + attributes.fetch(:codeActionKinds) + end + + # + # The server provides support to resolve additional + # information for a code action. + # + # @return [boolean] + def resolve_provider + attributes.fetch(:resolveProvider) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_description.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_description.rb new file mode 100644 index 00000000..eb283138 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_description.rb @@ -0,0 +1,36 @@ +module LanguageServer + module Protocol + module Interface + # + # Structure to capture a description for an error code. + # + class CodeDescription + def initialize(href:) + @attributes = {} + + @attributes[:href] = href + + @attributes.freeze + end + + # + # An URI to open with more information about the diagnostic error. + # + # @return [string] + def href + attributes.fetch(:href) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_lens.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_lens.rb new file mode 100644 index 00000000..7c2735fb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_lens.rb @@ -0,0 +1,61 @@ +module LanguageServer + module Protocol + module Interface + # + # A code lens represents a command that should be shown along with + # source text, like the number of references, a way to run tests, etc. + # + # A code lens is _unresolved_ when no command is associated to it. For + # performance reasons the creation of a code lens and resolving should be done + # in two stages. + # + class CodeLens + def initialize(range:, command: nil, data: nil) + @attributes = {} + + @attributes[:range] = range + @attributes[:command] = command if command + @attributes[:data] = data if data + + @attributes.freeze + end + + # + # The range in which this code lens is valid. Should only span a single + # line. + # + # @return [Range] + def range + attributes.fetch(:range) + end + + # + # The command this code lens represents. + # + # @return [Command] + def command + attributes.fetch(:command) + end + + # + # A data entry field that is preserved on a code lens item between + # a code lens and a code lens resolve request. + # + # @return [LSPAny] + def data + attributes.fetch(:data) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_lens_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_lens_client_capabilities.rb new file mode 100644 index 00000000..b59b8171 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_lens_client_capabilities.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + class CodeLensClientCapabilities + def initialize(dynamic_registration: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + + @attributes.freeze + end + + # + # Whether code lens supports dynamic registration. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_lens_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_lens_options.rb new file mode 100644 index 00000000..e923e862 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_lens_options.rb @@ -0,0 +1,39 @@ +module LanguageServer + module Protocol + module Interface + class CodeLensOptions + def initialize(work_done_progress: nil, resolve_provider: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:resolveProvider] = resolve_provider if resolve_provider + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # Code lens has a resolve provider as well. + # + # @return [boolean] + def resolve_provider + attributes.fetch(:resolveProvider) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_lens_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_lens_params.rb new file mode 100644 index 00000000..0386acf7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_lens_params.rb @@ -0,0 +1,52 @@ +module LanguageServer + module Protocol + module Interface + class CodeLensParams + def initialize(work_done_token: nil, partial_result_token: nil, text_document:) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + @attributes[:textDocument] = text_document + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + # + # The document to request code lens for. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_lens_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_lens_registration_options.rb new file mode 100644 index 00000000..7f99d391 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_lens_registration_options.rb @@ -0,0 +1,49 @@ +module LanguageServer + module Protocol + module Interface + class CodeLensRegistrationOptions + def initialize(document_selector:, work_done_progress: nil, resolve_provider: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:resolveProvider] = resolve_provider if resolve_provider + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # Code lens has a resolve provider as well. + # + # @return [boolean] + def resolve_provider + attributes.fetch(:resolveProvider) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_lens_workspace_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_lens_workspace_client_capabilities.rb new file mode 100644 index 00000000..c65f400f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/code_lens_workspace_client_capabilities.rb @@ -0,0 +1,39 @@ +module LanguageServer + module Protocol + module Interface + class CodeLensWorkspaceClientCapabilities + def initialize(refresh_support: nil) + @attributes = {} + + @attributes[:refreshSupport] = refresh_support if refresh_support + + @attributes.freeze + end + + # + # Whether the client implementation supports a refresh request sent from the + # server to the client. + # + # Note that this event is global and will force the client to refresh all + # code lenses currently shown. It should be used with absolute care and is + # useful for situation where a server for example detect a project wide + # change that requires such a calculation. + # + # @return [boolean] + def refresh_support + attributes.fetch(:refreshSupport) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/color.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/color.rb new file mode 100644 index 00000000..59443f10 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/color.rb @@ -0,0 +1,63 @@ +module LanguageServer + module Protocol + module Interface + # + # Represents a color in RGBA space. + # + class Color + def initialize(red:, green:, blue:, alpha:) + @attributes = {} + + @attributes[:red] = red + @attributes[:green] = green + @attributes[:blue] = blue + @attributes[:alpha] = alpha + + @attributes.freeze + end + + # + # The red component of this color in the range [0-1]. + # + # @return [number] + def red + attributes.fetch(:red) + end + + # + # The green component of this color in the range [0-1]. + # + # @return [number] + def green + attributes.fetch(:green) + end + + # + # The blue component of this color in the range [0-1]. + # + # @return [number] + def blue + attributes.fetch(:blue) + end + + # + # The alpha component of this color in the range [0-1]. + # + # @return [number] + def alpha + attributes.fetch(:alpha) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/color_information.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/color_information.rb new file mode 100644 index 00000000..20f15bed --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/color_information.rb @@ -0,0 +1,42 @@ +module LanguageServer + module Protocol + module Interface + class ColorInformation + def initialize(range:, color:) + @attributes = {} + + @attributes[:range] = range + @attributes[:color] = color + + @attributes.freeze + end + + # + # The range in the document where this color appears. + # + # @return [Range] + def range + attributes.fetch(:range) + end + + # + # The actual color value for this color range. + # + # @return [Color] + def color + attributes.fetch(:color) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/color_presentation.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/color_presentation.rb new file mode 100644 index 00000000..13e2b154 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/color_presentation.rb @@ -0,0 +1,57 @@ +module LanguageServer + module Protocol + module Interface + class ColorPresentation + def initialize(label:, text_edit: nil, additional_text_edits: nil) + @attributes = {} + + @attributes[:label] = label + @attributes[:textEdit] = text_edit if text_edit + @attributes[:additionalTextEdits] = additional_text_edits if additional_text_edits + + @attributes.freeze + end + + # + # The label of this color presentation. It will be shown on the color + # picker header. By default this is also the text that is inserted when + # selecting this color presentation. + # + # @return [string] + def label + attributes.fetch(:label) + end + + # + # An [edit](#TextEdit) which is applied to a document when selecting + # this presentation for the color. When omitted the + # [label](#ColorPresentation.label) is used. + # + # @return [TextEdit] + def text_edit + attributes.fetch(:textEdit) + end + + # + # An optional array of additional [text edits](#TextEdit) that are applied + # when selecting this color presentation. Edits must not overlap with the + # main [edit](#ColorPresentation.textEdit) nor with themselves. + # + # @return [TextEdit[]] + def additional_text_edits + attributes.fetch(:additionalTextEdits) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/color_presentation_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/color_presentation_params.rb new file mode 100644 index 00000000..7a100a94 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/color_presentation_params.rb @@ -0,0 +1,70 @@ +module LanguageServer + module Protocol + module Interface + class ColorPresentationParams + def initialize(work_done_token: nil, partial_result_token: nil, text_document:, color:, range:) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + @attributes[:textDocument] = text_document + @attributes[:color] = color + @attributes[:range] = range + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The color information to request presentations for. + # + # @return [Color] + def color + attributes.fetch(:color) + end + + # + # The range where the color would be inserted. Serves as a context. + # + # @return [Range] + def range + attributes.fetch(:range) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/command.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/command.rb new file mode 100644 index 00000000..8728ade0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/command.rb @@ -0,0 +1,52 @@ +module LanguageServer + module Protocol + module Interface + class Command + def initialize(title:, command:, arguments: nil) + @attributes = {} + + @attributes[:title] = title + @attributes[:command] = command + @attributes[:arguments] = arguments if arguments + + @attributes.freeze + end + + # + # Title of the command, like `save`. + # + # @return [string] + def title + attributes.fetch(:title) + end + + # + # The identifier of the actual command handler. + # + # @return [string] + def command + attributes.fetch(:command) + end + + # + # Arguments that the command handler should be + # invoked with. + # + # @return [LSPAny[]] + def arguments + attributes.fetch(:arguments) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/completion_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/completion_client_capabilities.rb new file mode 100644 index 00000000..fef70965 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/completion_client_capabilities.rb @@ -0,0 +1,79 @@ +module LanguageServer + module Protocol + module Interface + class CompletionClientCapabilities + def initialize(dynamic_registration: nil, completion_item: nil, completion_item_kind: nil, context_support: nil, insert_text_mode: nil, completion_list: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + @attributes[:completionItem] = completion_item if completion_item + @attributes[:completionItemKind] = completion_item_kind if completion_item_kind + @attributes[:contextSupport] = context_support if context_support + @attributes[:insertTextMode] = insert_text_mode if insert_text_mode + @attributes[:completionList] = completion_list if completion_list + + @attributes.freeze + end + + # + # Whether completion supports dynamic registration. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + # + # The client supports the following `CompletionItem` specific + # capabilities. + # + # @return [{ snippetSupport?: boolean; commitCharactersSupport?: boolean; documentationFormat?: MarkupKind[]; deprecatedSupport?: boolean; preselectSupport?: boolean; tagSupport?: { valueSet: 1[]; }; insertReplaceSupport?: boolean; resolveSupport?: { ...; }; insertTextModeSupport?: { ...; }; labelDetailsSupport?: boolean; }] + def completion_item + attributes.fetch(:completionItem) + end + + # @return [{ valueSet?: CompletionItemKind[]; }] + def completion_item_kind + attributes.fetch(:completionItemKind) + end + + # + # The client supports to send additional context information for a + # `textDocument/completion` request. + # + # @return [boolean] + def context_support + attributes.fetch(:contextSupport) + end + + # + # The client's default when the completion item doesn't provide a + # `insertTextMode` property. + # + # @return [InsertTextMode] + def insert_text_mode + attributes.fetch(:insertTextMode) + end + + # + # The client supports the following `CompletionList` specific + # capabilities. + # + # @return [{ itemDefaults?: string[]; }] + def completion_list + attributes.fetch(:completionList) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/completion_context.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/completion_context.rb new file mode 100644 index 00000000..292f3310 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/completion_context.rb @@ -0,0 +1,48 @@ +module LanguageServer + module Protocol + module Interface + # + # Contains additional information about the context in which a completion + # request is triggered. + # + class CompletionContext + def initialize(trigger_kind:, trigger_character: nil) + @attributes = {} + + @attributes[:triggerKind] = trigger_kind + @attributes[:triggerCharacter] = trigger_character if trigger_character + + @attributes.freeze + end + + # + # How the completion was triggered. + # + # @return [CompletionTriggerKind] + def trigger_kind + attributes.fetch(:triggerKind) + end + + # + # The trigger character (a single character) that has trigger code + # complete. Is undefined if + # `triggerKind !== CompletionTriggerKind.TriggerCharacter` + # + # @return [string] + def trigger_character + attributes.fetch(:triggerCharacter) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/completion_item.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/completion_item.rb new file mode 100644 index 00000000..8ff1cfc7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/completion_item.rb @@ -0,0 +1,267 @@ +module LanguageServer + module Protocol + module Interface + class CompletionItem + def initialize(label:, label_details: nil, kind: nil, tags: nil, detail: nil, documentation: nil, deprecated: nil, preselect: nil, sort_text: nil, filter_text: nil, insert_text: nil, insert_text_format: nil, insert_text_mode: nil, text_edit: nil, text_edit_text: nil, additional_text_edits: nil, commit_characters: nil, command: nil, data: nil) + @attributes = {} + + @attributes[:label] = label + @attributes[:labelDetails] = label_details if label_details + @attributes[:kind] = kind if kind + @attributes[:tags] = tags if tags + @attributes[:detail] = detail if detail + @attributes[:documentation] = documentation if documentation + @attributes[:deprecated] = deprecated if deprecated + @attributes[:preselect] = preselect if preselect + @attributes[:sortText] = sort_text if sort_text + @attributes[:filterText] = filter_text if filter_text + @attributes[:insertText] = insert_text if insert_text + @attributes[:insertTextFormat] = insert_text_format if insert_text_format + @attributes[:insertTextMode] = insert_text_mode if insert_text_mode + @attributes[:textEdit] = text_edit if text_edit + @attributes[:textEditText] = text_edit_text if text_edit_text + @attributes[:additionalTextEdits] = additional_text_edits if additional_text_edits + @attributes[:commitCharacters] = commit_characters if commit_characters + @attributes[:command] = command if command + @attributes[:data] = data if data + + @attributes.freeze + end + + # + # The label of this completion item. + # + # The label property is also by default the text that + # is inserted when selecting this completion. + # + # If label details are provided the label itself should + # be an unqualified name of the completion item. + # + # @return [string] + def label + attributes.fetch(:label) + end + + # + # Additional details for the label + # + # @return [CompletionItemLabelDetails] + def label_details + attributes.fetch(:labelDetails) + end + + # + # The kind of this completion item. Based of the kind + # an icon is chosen by the editor. The standardized set + # of available values is defined in `CompletionItemKind`. + # + # @return [CompletionItemKind] + def kind + attributes.fetch(:kind) + end + + # + # Tags for this completion item. + # + # @return [1[]] + def tags + attributes.fetch(:tags) + end + + # + # A human-readable string with additional information + # about this item, like type or symbol information. + # + # @return [string] + def detail + attributes.fetch(:detail) + end + + # + # A human-readable string that represents a doc-comment. + # + # @return [string | MarkupContent] + def documentation + attributes.fetch(:documentation) + end + + # + # Indicates if this item is deprecated. + # + # @return [boolean] + def deprecated + attributes.fetch(:deprecated) + end + + # + # Select this item when showing. + # + # *Note* that only one completion item can be selected and that the + # tool / client decides which item that is. The rule is that the *first* + # item of those that match best is selected. + # + # @return [boolean] + def preselect + attributes.fetch(:preselect) + end + + # + # A string that should be used when comparing this item + # with other items. When omitted the label is used + # as the sort text for this item. + # + # @return [string] + def sort_text + attributes.fetch(:sortText) + end + + # + # A string that should be used when filtering a set of + # completion items. When omitted the label is used as the + # filter text for this item. + # + # @return [string] + def filter_text + attributes.fetch(:filterText) + end + + # + # A string that should be inserted into a document when selecting + # this completion. When omitted the label is used as the insert text + # for this item. + # + # The `insertText` is subject to interpretation by the client side. + # Some tools might not take the string literally. For example + # VS Code when code complete is requested in this example + # `con` and a completion item with an `insertText` of + # `console` is provided it will only insert `sole`. Therefore it is + # recommended to use `textEdit` instead since it avoids additional client + # side interpretation. + # + # @return [string] + def insert_text + attributes.fetch(:insertText) + end + + # + # The format of the insert text. The format applies to both the + # `insertText` property and the `newText` property of a provided + # `textEdit`. If omitted defaults to `InsertTextFormat.PlainText`. + # + # Please note that the insertTextFormat doesn't apply to + # `additionalTextEdits`. + # + # @return [InsertTextFormat] + def insert_text_format + attributes.fetch(:insertTextFormat) + end + + # + # How whitespace and indentation is handled during completion + # item insertion. If not provided the client's default value depends on + # the `textDocument.completion.insertTextMode` client capability. + # + # @return [InsertTextMode] + def insert_text_mode + attributes.fetch(:insertTextMode) + end + + # + # An edit which is applied to a document when selecting this completion. + # When an edit is provided the value of `insertText` is ignored. + # + # *Note:* The range of the edit must be a single line range and it must + # contain the position at which completion has been requested. + # + # Most editors support two different operations when accepting a completion + # item. One is to insert a completion text and the other is to replace an + # existing text with a completion text. Since this can usually not be + # predetermined by a server it can report both ranges. Clients need to + # signal support for `InsertReplaceEdit`s via the + # `textDocument.completion.completionItem.insertReplaceSupport` client + # capability property. + # + # *Note 1:* The text edit's range as well as both ranges from an insert + # replace edit must be a [single line] and they must contain the position + # at which completion has been requested. + # *Note 2:* If an `InsertReplaceEdit` is returned the edit's insert range + # must be a prefix of the edit's replace range, that means it must be + # contained and starting at the same position. + # + # @return [TextEdit | InsertReplaceEdit] + def text_edit + attributes.fetch(:textEdit) + end + + # + # The edit text used if the completion item is part of a CompletionList and + # CompletionList defines an item default for the text edit range. + # + # Clients will only honor this property if they opt into completion list + # item defaults using the capability `completionList.itemDefaults`. + # + # If not provided and a list's default range is provided the label + # property is used as a text. + # + # @return [string] + def text_edit_text + attributes.fetch(:textEditText) + end + + # + # An optional array of additional text edits that are applied when + # selecting this completion. Edits must not overlap (including the same + # insert position) with the main edit nor with themselves. + # + # Additional text edits should be used to change text unrelated to the + # current cursor position (for example adding an import statement at the + # top of the file if the completion item will insert an unqualified type). + # + # @return [TextEdit[]] + def additional_text_edits + attributes.fetch(:additionalTextEdits) + end + + # + # An optional set of characters that when pressed while this completion is + # active will accept it first and then type that character. *Note* that all + # commit characters should have `length=1` and that superfluous characters + # will be ignored. + # + # @return [string[]] + def commit_characters + attributes.fetch(:commitCharacters) + end + + # + # An optional command that is executed *after* inserting this completion. + # *Note* that additional modifications to the current document should be + # described with the additionalTextEdits-property. + # + # @return [Command] + def command + attributes.fetch(:command) + end + + # + # A data entry field that is preserved on a completion item between + # a completion and a completion resolve request. + # + # @return [LSPAny] + def data + attributes.fetch(:data) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/completion_item_label_details.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/completion_item_label_details.rb new file mode 100644 index 00000000..a26d3ca0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/completion_item_label_details.rb @@ -0,0 +1,49 @@ +module LanguageServer + module Protocol + module Interface + # + # Additional details for a completion item label. + # + class CompletionItemLabelDetails + def initialize(detail: nil, description: nil) + @attributes = {} + + @attributes[:detail] = detail if detail + @attributes[:description] = description if description + + @attributes.freeze + end + + # + # An optional string which is rendered less prominently directly after + # {@link CompletionItem.label label}, without any spacing. Should be + # used for function signatures or type annotations. + # + # @return [string] + def detail + attributes.fetch(:detail) + end + + # + # An optional string which is rendered less prominently after + # {@link CompletionItemLabelDetails.detail}. Should be used for fully qualified + # names or file path. + # + # @return [string] + def description + attributes.fetch(:description) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/completion_list.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/completion_list.rb new file mode 100644 index 00000000..f08067cc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/completion_list.rb @@ -0,0 +1,69 @@ +module LanguageServer + module Protocol + module Interface + # + # Represents a collection of [completion items](#CompletionItem) to be + # presented in the editor. + # + class CompletionList + def initialize(is_incomplete:, item_defaults: nil, items:) + @attributes = {} + + @attributes[:isIncomplete] = is_incomplete + @attributes[:itemDefaults] = item_defaults if item_defaults + @attributes[:items] = items + + @attributes.freeze + end + + # + # This list is not complete. Further typing should result in recomputing + # this list. + # + # Recomputed lists have all their items replaced (not appended) in the + # incomplete completion sessions. + # + # @return [boolean] + def is_incomplete + attributes.fetch(:isIncomplete) + end + + # + # In many cases the items of an actual completion result share the same + # value for properties like `commitCharacters` or the range of a text + # edit. A completion list can therefore define item defaults which will + # be used if a completion item itself doesn't specify the value. + # + # If a completion list specifies a default value and a completion item + # also specifies a corresponding value the one from the item is used. + # + # Servers are only allowed to return default values if the client + # signals support for this via the `completionList.itemDefaults` + # capability. + # + # @return [{ commitCharacters?: string[]; editRange?: Range | { insert: Range; replace: Range; }; insertTextFormat?: InsertTextFormat; insertTextMode?: InsertTextMode; data?: LSPAny; }] + def item_defaults + attributes.fetch(:itemDefaults) + end + + # + # The completion items. + # + # @return [CompletionItem[]] + def items + attributes.fetch(:items) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/completion_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/completion_options.rb new file mode 100644 index 00000000..5446c090 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/completion_options.rb @@ -0,0 +1,87 @@ +module LanguageServer + module Protocol + module Interface + # + # Completion options. + # + class CompletionOptions + def initialize(work_done_progress: nil, trigger_characters: nil, all_commit_characters: nil, resolve_provider: nil, completion_item: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:triggerCharacters] = trigger_characters if trigger_characters + @attributes[:allCommitCharacters] = all_commit_characters if all_commit_characters + @attributes[:resolveProvider] = resolve_provider if resolve_provider + @attributes[:completionItem] = completion_item if completion_item + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # The additional characters, beyond the defaults provided by the client (typically + # [a-zA-Z]), that should automatically trigger a completion request. For example + # `.` in JavaScript represents the beginning of an object property or method and is + # thus a good candidate for triggering a completion request. + # + # Most tools trigger a completion request automatically without explicitly + # requesting it using a keyboard shortcut (e.g. Ctrl+Space). Typically they + # do so when the user starts to type an identifier. For example if the user + # types `c` in a JavaScript file code complete will automatically pop up + # present `console` besides others as a completion item. Characters that + # make up identifiers don't need to be listed here. + # + # @return [string[]] + def trigger_characters + attributes.fetch(:triggerCharacters) + end + + # + # The list of all possible characters that commit a completion. This field + # can be used if clients don't support individual commit characters per + # completion item. See client capability + # `completion.completionItem.commitCharactersSupport`. + # + # If a server provides both `allCommitCharacters` and commit characters on + # an individual completion item the ones on the completion item win. + # + # @return [string[]] + def all_commit_characters + attributes.fetch(:allCommitCharacters) + end + + # + # The server provides support to resolve additional + # information for a completion item. + # + # @return [boolean] + def resolve_provider + attributes.fetch(:resolveProvider) + end + + # + # The server supports the following `CompletionItem` specific + # capabilities. + # + # @return [{ labelDetailsSupport?: boolean; }] + def completion_item + attributes.fetch(:completionItem) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/completion_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/completion_params.rb new file mode 100644 index 00000000..1bd3b084 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/completion_params.rb @@ -0,0 +1,72 @@ +module LanguageServer + module Protocol + module Interface + class CompletionParams + def initialize(text_document:, position:, work_done_token: nil, partial_result_token: nil, context: nil) + @attributes = {} + + @attributes[:textDocument] = text_document + @attributes[:position] = position + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + @attributes[:context] = context if context + + @attributes.freeze + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The position inside the text document. + # + # @return [Position] + def position + attributes.fetch(:position) + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + # + # The completion context. This is only available if the client specifies + # to send this using the client capability + # `completion.contextSupport === true` + # + # @return [CompletionContext] + def context + attributes.fetch(:context) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/completion_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/completion_registration_options.rb new file mode 100644 index 00000000..0fd92c6b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/completion_registration_options.rb @@ -0,0 +1,94 @@ +module LanguageServer + module Protocol + module Interface + class CompletionRegistrationOptions + def initialize(document_selector:, work_done_progress: nil, trigger_characters: nil, all_commit_characters: nil, resolve_provider: nil, completion_item: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:triggerCharacters] = trigger_characters if trigger_characters + @attributes[:allCommitCharacters] = all_commit_characters if all_commit_characters + @attributes[:resolveProvider] = resolve_provider if resolve_provider + @attributes[:completionItem] = completion_item if completion_item + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # The additional characters, beyond the defaults provided by the client (typically + # [a-zA-Z]), that should automatically trigger a completion request. For example + # `.` in JavaScript represents the beginning of an object property or method and is + # thus a good candidate for triggering a completion request. + # + # Most tools trigger a completion request automatically without explicitly + # requesting it using a keyboard shortcut (e.g. Ctrl+Space). Typically they + # do so when the user starts to type an identifier. For example if the user + # types `c` in a JavaScript file code complete will automatically pop up + # present `console` besides others as a completion item. Characters that + # make up identifiers don't need to be listed here. + # + # @return [string[]] + def trigger_characters + attributes.fetch(:triggerCharacters) + end + + # + # The list of all possible characters that commit a completion. This field + # can be used if clients don't support individual commit characters per + # completion item. See client capability + # `completion.completionItem.commitCharactersSupport`. + # + # If a server provides both `allCommitCharacters` and commit characters on + # an individual completion item the ones on the completion item win. + # + # @return [string[]] + def all_commit_characters + attributes.fetch(:allCommitCharacters) + end + + # + # The server provides support to resolve additional + # information for a completion item. + # + # @return [boolean] + def resolve_provider + attributes.fetch(:resolveProvider) + end + + # + # The server supports the following `CompletionItem` specific + # capabilities. + # + # @return [{ labelDetailsSupport?: boolean; }] + def completion_item + attributes.fetch(:completionItem) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/configuration_item.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/configuration_item.rb new file mode 100644 index 00000000..484bacab --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/configuration_item.rb @@ -0,0 +1,42 @@ +module LanguageServer + module Protocol + module Interface + class ConfigurationItem + def initialize(scope_uri: nil, section: nil) + @attributes = {} + + @attributes[:scopeUri] = scope_uri if scope_uri + @attributes[:section] = section if section + + @attributes.freeze + end + + # + # The scope to get the configuration section for. + # + # @return [string] + def scope_uri + attributes.fetch(:scopeUri) + end + + # + # The configuration section asked for. + # + # @return [string] + def section + attributes.fetch(:section) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/configuration_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/configuration_params.rb new file mode 100644 index 00000000..66d3d5c1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/configuration_params.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Interface + class ConfigurationParams + def initialize(items:) + @attributes = {} + + @attributes[:items] = items + + @attributes.freeze + end + + # @return [ConfigurationItem[]] + def items + attributes.fetch(:items) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/create_file.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/create_file.rb new file mode 100644 index 00000000..ca247db5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/create_file.rb @@ -0,0 +1,63 @@ +module LanguageServer + module Protocol + module Interface + # + # Create file operation + # + class CreateFile + def initialize(kind:, uri:, options: nil, annotation_id: nil) + @attributes = {} + + @attributes[:kind] = kind + @attributes[:uri] = uri + @attributes[:options] = options if options + @attributes[:annotationId] = annotation_id if annotation_id + + @attributes.freeze + end + + # + # A create + # + # @return ["create"] + def kind + attributes.fetch(:kind) + end + + # + # The resource to create. + # + # @return [string] + def uri + attributes.fetch(:uri) + end + + # + # Additional options + # + # @return [CreateFileOptions] + def options + attributes.fetch(:options) + end + + # + # An optional annotation identifier describing the operation. + # + # @return [string] + def annotation_id + attributes.fetch(:annotationId) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/create_file_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/create_file_options.rb new file mode 100644 index 00000000..41920f90 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/create_file_options.rb @@ -0,0 +1,45 @@ +module LanguageServer + module Protocol + module Interface + # + # Options to create a file. + # + class CreateFileOptions + def initialize(overwrite: nil, ignore_if_exists: nil) + @attributes = {} + + @attributes[:overwrite] = overwrite if overwrite + @attributes[:ignoreIfExists] = ignore_if_exists if ignore_if_exists + + @attributes.freeze + end + + # + # Overwrite existing file. Overwrite wins over `ignoreIfExists` + # + # @return [boolean] + def overwrite + attributes.fetch(:overwrite) + end + + # + # Ignore if exists. + # + # @return [boolean] + def ignore_if_exists + attributes.fetch(:ignoreIfExists) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/create_files_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/create_files_params.rb new file mode 100644 index 00000000..2af89112 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/create_files_params.rb @@ -0,0 +1,37 @@ +module LanguageServer + module Protocol + module Interface + # + # The parameters sent in notifications/requests for user-initiated creation + # of files. + # + class CreateFilesParams + def initialize(files:) + @attributes = {} + + @attributes[:files] = files + + @attributes.freeze + end + + # + # An array of all files/folders created in this operation. + # + # @return [FileCreate[]] + def files + attributes.fetch(:files) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/declaration_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/declaration_client_capabilities.rb new file mode 100644 index 00000000..06aba3a4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/declaration_client_capabilities.rb @@ -0,0 +1,44 @@ +module LanguageServer + module Protocol + module Interface + class DeclarationClientCapabilities + def initialize(dynamic_registration: nil, link_support: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + @attributes[:linkSupport] = link_support if link_support + + @attributes.freeze + end + + # + # Whether declaration supports dynamic registration. If this is set to + # `true` the client supports the new `DeclarationRegistrationOptions` + # return value for the corresponding server capability as well. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + # + # The client supports additional metadata in the form of declaration links. + # + # @return [boolean] + def link_support + attributes.fetch(:linkSupport) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/declaration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/declaration_options.rb new file mode 100644 index 00000000..d919e00e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/declaration_options.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Interface + class DeclarationOptions + def initialize(work_done_progress: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/declaration_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/declaration_params.rb new file mode 100644 index 00000000..422ac45a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/declaration_params.rb @@ -0,0 +1,61 @@ +module LanguageServer + module Protocol + module Interface + class DeclarationParams + def initialize(text_document:, position:, work_done_token: nil, partial_result_token: nil) + @attributes = {} + + @attributes[:textDocument] = text_document + @attributes[:position] = position + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + + @attributes.freeze + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The position inside the text document. + # + # @return [Position] + def position + attributes.fetch(:position) + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/declaration_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/declaration_registration_options.rb new file mode 100644 index 00000000..5730a6a8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/declaration_registration_options.rb @@ -0,0 +1,50 @@ +module LanguageServer + module Protocol + module Interface + class DeclarationRegistrationOptions + def initialize(work_done_progress: nil, document_selector:, id: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:documentSelector] = document_selector + @attributes[:id] = id if id + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # + # The id used to register the request. The id can be used to deregister + # the request again. See also Registration#id. + # + # @return [string] + def id + attributes.fetch(:id) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/definition_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/definition_client_capabilities.rb new file mode 100644 index 00000000..96ccda48 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/definition_client_capabilities.rb @@ -0,0 +1,42 @@ +module LanguageServer + module Protocol + module Interface + class DefinitionClientCapabilities + def initialize(dynamic_registration: nil, link_support: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + @attributes[:linkSupport] = link_support if link_support + + @attributes.freeze + end + + # + # Whether definition supports dynamic registration. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + # + # The client supports additional metadata in the form of definition links. + # + # @return [boolean] + def link_support + attributes.fetch(:linkSupport) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/definition_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/definition_options.rb new file mode 100644 index 00000000..2bf8471b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/definition_options.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Interface + class DefinitionOptions + def initialize(work_done_progress: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/definition_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/definition_params.rb new file mode 100644 index 00000000..f23a9229 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/definition_params.rb @@ -0,0 +1,61 @@ +module LanguageServer + module Protocol + module Interface + class DefinitionParams + def initialize(text_document:, position:, work_done_token: nil, partial_result_token: nil) + @attributes = {} + + @attributes[:textDocument] = text_document + @attributes[:position] = position + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + + @attributes.freeze + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The position inside the text document. + # + # @return [Position] + def position + attributes.fetch(:position) + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/definition_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/definition_registration_options.rb new file mode 100644 index 00000000..cd6f86aa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/definition_registration_options.rb @@ -0,0 +1,40 @@ +module LanguageServer + module Protocol + module Interface + class DefinitionRegistrationOptions + def initialize(document_selector:, work_done_progress: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/delete_file.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/delete_file.rb new file mode 100644 index 00000000..27bee5ff --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/delete_file.rb @@ -0,0 +1,63 @@ +module LanguageServer + module Protocol + module Interface + # + # Delete file operation + # + class DeleteFile + def initialize(kind:, uri:, options: nil, annotation_id: nil) + @attributes = {} + + @attributes[:kind] = kind + @attributes[:uri] = uri + @attributes[:options] = options if options + @attributes[:annotationId] = annotation_id if annotation_id + + @attributes.freeze + end + + # + # A delete + # + # @return ["delete"] + def kind + attributes.fetch(:kind) + end + + # + # The file to delete. + # + # @return [string] + def uri + attributes.fetch(:uri) + end + + # + # Delete options. + # + # @return [DeleteFileOptions] + def options + attributes.fetch(:options) + end + + # + # An optional annotation identifier describing the operation. + # + # @return [string] + def annotation_id + attributes.fetch(:annotationId) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/delete_file_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/delete_file_options.rb new file mode 100644 index 00000000..1d81757c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/delete_file_options.rb @@ -0,0 +1,45 @@ +module LanguageServer + module Protocol + module Interface + # + # Delete file options + # + class DeleteFileOptions + def initialize(recursive: nil, ignore_if_not_exists: nil) + @attributes = {} + + @attributes[:recursive] = recursive if recursive + @attributes[:ignoreIfNotExists] = ignore_if_not_exists if ignore_if_not_exists + + @attributes.freeze + end + + # + # Delete the content recursively if a folder is denoted. + # + # @return [boolean] + def recursive + attributes.fetch(:recursive) + end + + # + # Ignore the operation if the file doesn't exist. + # + # @return [boolean] + def ignore_if_not_exists + attributes.fetch(:ignoreIfNotExists) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/delete_files_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/delete_files_params.rb new file mode 100644 index 00000000..b9da26c3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/delete_files_params.rb @@ -0,0 +1,37 @@ +module LanguageServer + module Protocol + module Interface + # + # The parameters sent in notifications/requests for user-initiated deletes + # of files. + # + class DeleteFilesParams + def initialize(files:) + @attributes = {} + + @attributes[:files] = files + + @attributes.freeze + end + + # + # An array of all files/folders deleted in this operation. + # + # @return [FileDelete[]] + def files + attributes.fetch(:files) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/diagnostic.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/diagnostic.rb new file mode 100644 index 00000000..289ac73f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/diagnostic.rb @@ -0,0 +1,110 @@ +module LanguageServer + module Protocol + module Interface + class Diagnostic + def initialize(range:, severity: nil, code: nil, code_description: nil, source: nil, message:, tags: nil, related_information: nil, data: nil) + @attributes = {} + + @attributes[:range] = range + @attributes[:severity] = severity if severity + @attributes[:code] = code if code + @attributes[:codeDescription] = code_description if code_description + @attributes[:source] = source if source + @attributes[:message] = message + @attributes[:tags] = tags if tags + @attributes[:relatedInformation] = related_information if related_information + @attributes[:data] = data if data + + @attributes.freeze + end + + # + # The range at which the message applies. + # + # @return [Range] + def range + attributes.fetch(:range) + end + + # + # The diagnostic's severity. Can be omitted. If omitted it is up to the + # client to interpret diagnostics as error, warning, info or hint. + # + # @return [DiagnosticSeverity] + def severity + attributes.fetch(:severity) + end + + # + # The diagnostic's code, which might appear in the user interface. + # + # @return [string | number] + def code + attributes.fetch(:code) + end + + # + # An optional property to describe the error code. + # + # @return [CodeDescription] + def code_description + attributes.fetch(:codeDescription) + end + + # + # A human-readable string describing the source of this + # diagnostic, e.g. 'typescript' or 'super lint'. + # + # @return [string] + def source + attributes.fetch(:source) + end + + # + # The diagnostic's message. + # + # @return [string] + def message + attributes.fetch(:message) + end + + # + # Additional metadata about the diagnostic. + # + # @return [DiagnosticTag[]] + def tags + attributes.fetch(:tags) + end + + # + # An array of related diagnostic information, e.g. when symbol-names within + # a scope collide all definitions can be marked via this property. + # + # @return [DiagnosticRelatedInformation[]] + def related_information + attributes.fetch(:relatedInformation) + end + + # + # A data entry field that is preserved between a + # `textDocument/publishDiagnostics` notification and + # `textDocument/codeAction` request. + # + # @return [unknown] + def data + attributes.fetch(:data) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/diagnostic_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/diagnostic_client_capabilities.rb new file mode 100644 index 00000000..6cad2ac4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/diagnostic_client_capabilities.rb @@ -0,0 +1,49 @@ +module LanguageServer + module Protocol + module Interface + # + # Client capabilities specific to diagnostic pull requests. + # + class DiagnosticClientCapabilities + def initialize(dynamic_registration: nil, related_document_support: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + @attributes[:relatedDocumentSupport] = related_document_support if related_document_support + + @attributes.freeze + end + + # + # Whether implementation supports dynamic registration. If this is set to + # `true` the client supports the new + # `(TextDocumentRegistrationOptions & StaticRegistrationOptions)` + # return value for the corresponding server capability as well. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + # + # Whether the clients supports related documents for document diagnostic + # pulls. + # + # @return [boolean] + def related_document_support + attributes.fetch(:relatedDocumentSupport) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/diagnostic_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/diagnostic_options.rb new file mode 100644 index 00000000..03096372 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/diagnostic_options.rb @@ -0,0 +1,64 @@ +module LanguageServer + module Protocol + module Interface + # + # Diagnostic options. + # + class DiagnosticOptions + def initialize(work_done_progress: nil, identifier: nil, inter_file_dependencies:, workspace_diagnostics:) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:identifier] = identifier if identifier + @attributes[:interFileDependencies] = inter_file_dependencies + @attributes[:workspaceDiagnostics] = workspace_diagnostics + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # An optional identifier under which the diagnostics are + # managed by the client. + # + # @return [string] + def identifier + attributes.fetch(:identifier) + end + + # + # Whether the language has inter file dependencies meaning that + # editing code in one file can result in a different diagnostic + # set in another file. Inter file dependencies are common for + # most programming languages and typically uncommon for linters. + # + # @return [boolean] + def inter_file_dependencies + attributes.fetch(:interFileDependencies) + end + + # + # The server provides support for workspace diagnostics as well. + # + # @return [boolean] + def workspace_diagnostics + attributes.fetch(:workspaceDiagnostics) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/diagnostic_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/diagnostic_registration_options.rb new file mode 100644 index 00000000..95b36341 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/diagnostic_registration_options.rb @@ -0,0 +1,84 @@ +module LanguageServer + module Protocol + module Interface + # + # Diagnostic registration options. + # + class DiagnosticRegistrationOptions + def initialize(document_selector:, work_done_progress: nil, identifier: nil, inter_file_dependencies:, workspace_diagnostics:, id: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:identifier] = identifier if identifier + @attributes[:interFileDependencies] = inter_file_dependencies + @attributes[:workspaceDiagnostics] = workspace_diagnostics + @attributes[:id] = id if id + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # An optional identifier under which the diagnostics are + # managed by the client. + # + # @return [string] + def identifier + attributes.fetch(:identifier) + end + + # + # Whether the language has inter file dependencies meaning that + # editing code in one file can result in a different diagnostic + # set in another file. Inter file dependencies are common for + # most programming languages and typically uncommon for linters. + # + # @return [boolean] + def inter_file_dependencies + attributes.fetch(:interFileDependencies) + end + + # + # The server provides support for workspace diagnostics as well. + # + # @return [boolean] + def workspace_diagnostics + attributes.fetch(:workspaceDiagnostics) + end + + # + # The id used to register the request. The id can be used to deregister + # the request again. See also Registration#id. + # + # @return [string] + def id + attributes.fetch(:id) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/diagnostic_related_information.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/diagnostic_related_information.rb new file mode 100644 index 00000000..ffbc28ce --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/diagnostic_related_information.rb @@ -0,0 +1,47 @@ +module LanguageServer + module Protocol + module Interface + # + # Represents a related message and source code location for a diagnostic. + # This should be used to point to code locations that cause or are related to + # a diagnostics, e.g when duplicating a symbol in a scope. + # + class DiagnosticRelatedInformation + def initialize(location:, message:) + @attributes = {} + + @attributes[:location] = location + @attributes[:message] = message + + @attributes.freeze + end + + # + # The location of this related diagnostic information. + # + # @return [Location] + def location + attributes.fetch(:location) + end + + # + # The message of this related diagnostic information. + # + # @return [string] + def message + attributes.fetch(:message) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/diagnostic_server_cancellation_data.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/diagnostic_server_cancellation_data.rb new file mode 100644 index 00000000..23e15285 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/diagnostic_server_cancellation_data.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + # + # Cancellation data returned from a diagnostic request. + # + class DiagnosticServerCancellationData + def initialize(retrigger_request:) + @attributes = {} + + @attributes[:retriggerRequest] = retrigger_request + + @attributes.freeze + end + + # @return [boolean] + def retrigger_request + attributes.fetch(:retriggerRequest) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/diagnostic_workspace_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/diagnostic_workspace_client_capabilities.rb new file mode 100644 index 00000000..020434b4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/diagnostic_workspace_client_capabilities.rb @@ -0,0 +1,42 @@ +module LanguageServer + module Protocol + module Interface + # + # Workspace client capabilities specific to diagnostic pull requests. + # + class DiagnosticWorkspaceClientCapabilities + def initialize(refresh_support: nil) + @attributes = {} + + @attributes[:refreshSupport] = refresh_support if refresh_support + + @attributes.freeze + end + + # + # Whether the client implementation supports a refresh request sent from + # the server to the client. + # + # Note that this event is global and will force the client to refresh all + # pulled diagnostics currently shown. It should be used with absolute care + # and is useful for situation where a server for example detects a project + # wide change that requires such a calculation. + # + # @return [boolean] + def refresh_support + attributes.fetch(:refreshSupport) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_change_configuration_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_change_configuration_client_capabilities.rb new file mode 100644 index 00000000..59d3a264 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_change_configuration_client_capabilities.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + class DidChangeConfigurationClientCapabilities + def initialize(dynamic_registration: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + + @attributes.freeze + end + + # + # Did change configuration notification supports dynamic registration. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_change_configuration_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_change_configuration_params.rb new file mode 100644 index 00000000..66287334 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_change_configuration_params.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + class DidChangeConfigurationParams + def initialize(settings:) + @attributes = {} + + @attributes[:settings] = settings + + @attributes.freeze + end + + # + # The actual changed settings + # + # @return [LSPAny] + def settings + attributes.fetch(:settings) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_change_notebook_document_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_change_notebook_document_params.rb new file mode 100644 index 00000000..087f2365 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_change_notebook_document_params.rb @@ -0,0 +1,56 @@ +module LanguageServer + module Protocol + module Interface + # + # The params sent in a change notebook document notification. + # + class DidChangeNotebookDocumentParams + def initialize(notebook_document:, change:) + @attributes = {} + + @attributes[:notebookDocument] = notebook_document + @attributes[:change] = change + + @attributes.freeze + end + + # + # The notebook document that did change. The version number points + # to the version after all provided changes have been applied. + # + # @return [VersionedNotebookDocumentIdentifier] + def notebook_document + attributes.fetch(:notebookDocument) + end + + # + # The actual changes to the notebook document. + # + # The change describes single state change to the notebook document. + # So it moves a notebook document, its cells and its cell text document + # contents from state S to S'. + # + # To mirror the content of a notebook using change events use the + # following approach: + # - start with the same initial content + # - apply the 'notebookDocument/didChange' notifications in the order + # you receive them. + # + # @return [NotebookDocumentChangeEvent] + def change + attributes.fetch(:change) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_change_text_document_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_change_text_document_params.rb new file mode 100644 index 00000000..4ef782d0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_change_text_document_params.rb @@ -0,0 +1,56 @@ +module LanguageServer + module Protocol + module Interface + class DidChangeTextDocumentParams + def initialize(text_document:, content_changes:) + @attributes = {} + + @attributes[:textDocument] = text_document + @attributes[:contentChanges] = content_changes + + @attributes.freeze + end + + # + # The document that did change. The version number points + # to the version after all provided content changes have + # been applied. + # + # @return [VersionedTextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The actual content changes. The content changes describe single state + # changes to the document. So if there are two content changes c1 (at + # array index 0) and c2 (at array index 1) for a document in state S then + # c1 moves the document from S to S' and c2 from S' to S''. So c1 is + # computed on the state S and c2 is computed on the state S'. + # + # To mirror the content of a document using change events use the following + # approach: + # - start with the same initial content + # - apply the 'textDocument/didChange' notifications in the order you + # receive them. + # - apply the `TextDocumentContentChangeEvent`s in a single notification + # in the order you receive them. + # + # @return [TextDocumentContentChangeEvent[]] + def content_changes + attributes.fetch(:contentChanges) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_change_watched_files_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_change_watched_files_client_capabilities.rb new file mode 100644 index 00000000..8ed6c186 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_change_watched_files_client_capabilities.rb @@ -0,0 +1,45 @@ +module LanguageServer + module Protocol + module Interface + class DidChangeWatchedFilesClientCapabilities + def initialize(dynamic_registration: nil, relative_pattern_support: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + @attributes[:relativePatternSupport] = relative_pattern_support if relative_pattern_support + + @attributes.freeze + end + + # + # Did change watched files notification supports dynamic registration. + # Please note that the current protocol doesn't support static + # configuration for file changes from the server side. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + # + # Whether the client has support for relative patterns + # or not. + # + # @return [boolean] + def relative_pattern_support + attributes.fetch(:relativePatternSupport) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_change_watched_files_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_change_watched_files_params.rb new file mode 100644 index 00000000..4a47ca4c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_change_watched_files_params.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + class DidChangeWatchedFilesParams + def initialize(changes:) + @attributes = {} + + @attributes[:changes] = changes + + @attributes.freeze + end + + # + # The actual file events. + # + # @return [FileEvent[]] + def changes + attributes.fetch(:changes) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_change_watched_files_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_change_watched_files_registration_options.rb new file mode 100644 index 00000000..f78e3f68 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_change_watched_files_registration_options.rb @@ -0,0 +1,36 @@ +module LanguageServer + module Protocol + module Interface + # + # Describe options to be used when registering for file system change events. + # + class DidChangeWatchedFilesRegistrationOptions + def initialize(watchers:) + @attributes = {} + + @attributes[:watchers] = watchers + + @attributes.freeze + end + + # + # The watchers to register. + # + # @return [FileSystemWatcher[]] + def watchers + attributes.fetch(:watchers) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_change_workspace_folders_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_change_workspace_folders_params.rb new file mode 100644 index 00000000..4ea9b7db --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_change_workspace_folders_params.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + class DidChangeWorkspaceFoldersParams + def initialize(event:) + @attributes = {} + + @attributes[:event] = event + + @attributes.freeze + end + + # + # The actual workspace folder change event. + # + # @return [WorkspaceFoldersChangeEvent] + def event + attributes.fetch(:event) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_close_notebook_document_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_close_notebook_document_params.rb new file mode 100644 index 00000000..5045c914 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_close_notebook_document_params.rb @@ -0,0 +1,46 @@ +module LanguageServer + module Protocol + module Interface + # + # The params sent in a close notebook document notification. + # + class DidCloseNotebookDocumentParams + def initialize(notebook_document:, cell_text_documents:) + @attributes = {} + + @attributes[:notebookDocument] = notebook_document + @attributes[:cellTextDocuments] = cell_text_documents + + @attributes.freeze + end + + # + # The notebook document that got closed. + # + # @return [NotebookDocumentIdentifier] + def notebook_document + attributes.fetch(:notebookDocument) + end + + # + # The text documents that represent the content + # of a notebook cell that got closed. + # + # @return [TextDocumentIdentifier[]] + def cell_text_documents + attributes.fetch(:cellTextDocuments) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_close_text_document_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_close_text_document_params.rb new file mode 100644 index 00000000..f98c3f8c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_close_text_document_params.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + class DidCloseTextDocumentParams + def initialize(text_document:) + @attributes = {} + + @attributes[:textDocument] = text_document + + @attributes.freeze + end + + # + # The document that was closed. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_open_notebook_document_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_open_notebook_document_params.rb new file mode 100644 index 00000000..bd48497d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_open_notebook_document_params.rb @@ -0,0 +1,46 @@ +module LanguageServer + module Protocol + module Interface + # + # The params sent in an open notebook document notification. + # + class DidOpenNotebookDocumentParams + def initialize(notebook_document:, cell_text_documents:) + @attributes = {} + + @attributes[:notebookDocument] = notebook_document + @attributes[:cellTextDocuments] = cell_text_documents + + @attributes.freeze + end + + # + # The notebook document that got opened. + # + # @return [NotebookDocument] + def notebook_document + attributes.fetch(:notebookDocument) + end + + # + # The text documents that represent the content + # of a notebook cell. + # + # @return [TextDocumentItem[]] + def cell_text_documents + attributes.fetch(:cellTextDocuments) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_open_text_document_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_open_text_document_params.rb new file mode 100644 index 00000000..9ca6ec9a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_open_text_document_params.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + class DidOpenTextDocumentParams + def initialize(text_document:) + @attributes = {} + + @attributes[:textDocument] = text_document + + @attributes.freeze + end + + # + # The document that was opened. + # + # @return [TextDocumentItem] + def text_document + attributes.fetch(:textDocument) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_save_notebook_document_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_save_notebook_document_params.rb new file mode 100644 index 00000000..36726f99 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_save_notebook_document_params.rb @@ -0,0 +1,36 @@ +module LanguageServer + module Protocol + module Interface + # + # The params sent in a save notebook document notification. + # + class DidSaveNotebookDocumentParams + def initialize(notebook_document:) + @attributes = {} + + @attributes[:notebookDocument] = notebook_document + + @attributes.freeze + end + + # + # The notebook document that got saved. + # + # @return [NotebookDocumentIdentifier] + def notebook_document + attributes.fetch(:notebookDocument) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_save_text_document_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_save_text_document_params.rb new file mode 100644 index 00000000..43523afc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/did_save_text_document_params.rb @@ -0,0 +1,43 @@ +module LanguageServer + module Protocol + module Interface + class DidSaveTextDocumentParams + def initialize(text_document:, text: nil) + @attributes = {} + + @attributes[:textDocument] = text_document + @attributes[:text] = text if text + + @attributes.freeze + end + + # + # The document that was saved. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # Optional the content when saved. Depends on the includeText value + # when the save notification was requested. + # + # @return [string] + def text + attributes.fetch(:text) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_color_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_color_client_capabilities.rb new file mode 100644 index 00000000..bb3d8dec --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_color_client_capabilities.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + class DocumentColorClientCapabilities + def initialize(dynamic_registration: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + + @attributes.freeze + end + + # + # Whether document color supports dynamic registration. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_color_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_color_options.rb new file mode 100644 index 00000000..1fa00f0a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_color_options.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Interface + class DocumentColorOptions + def initialize(work_done_progress: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_color_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_color_params.rb new file mode 100644 index 00000000..ead61c4c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_color_params.rb @@ -0,0 +1,52 @@ +module LanguageServer + module Protocol + module Interface + class DocumentColorParams + def initialize(work_done_token: nil, partial_result_token: nil, text_document:) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + @attributes[:textDocument] = text_document + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_color_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_color_registration_options.rb new file mode 100644 index 00000000..1af3533e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_color_registration_options.rb @@ -0,0 +1,50 @@ +module LanguageServer + module Protocol + module Interface + class DocumentColorRegistrationOptions + def initialize(document_selector:, id: nil, work_done_progress: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:id] = id if id + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # + # The id used to register the request. The id can be used to deregister + # the request again. See also Registration#id. + # + # @return [string] + def id + attributes.fetch(:id) + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_diagnostic_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_diagnostic_params.rb new file mode 100644 index 00000000..298851e0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_diagnostic_params.rb @@ -0,0 +1,73 @@ +module LanguageServer + module Protocol + module Interface + # + # Parameters of the document diagnostic request. + # + class DocumentDiagnosticParams + def initialize(work_done_token: nil, partial_result_token: nil, text_document:, identifier: nil, previous_result_id: nil) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + @attributes[:textDocument] = text_document + @attributes[:identifier] = identifier if identifier + @attributes[:previousResultId] = previous_result_id if previous_result_id + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The additional identifier provided during registration. + # + # @return [string] + def identifier + attributes.fetch(:identifier) + end + + # + # The result id of a previous response if provided. + # + # @return [string] + def previous_result_id + attributes.fetch(:previousResultId) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_diagnostic_report_partial_result.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_diagnostic_report_partial_result.rb new file mode 100644 index 00000000..c8f9b67f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_diagnostic_report_partial_result.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + # + # A partial result for a document diagnostic report. + # + class DocumentDiagnosticReportPartialResult + def initialize(related_documents:) + @attributes = {} + + @attributes[:relatedDocuments] = related_documents + + @attributes.freeze + end + + # @return [{ [uri: string]: FullDocumentDiagnosticReport | UnchangedDocumentDiagnosticReport; }] + def related_documents + attributes.fetch(:relatedDocuments) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_filter.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_filter.rb new file mode 100644 index 00000000..c116666f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_filter.rb @@ -0,0 +1,63 @@ +module LanguageServer + module Protocol + module Interface + class DocumentFilter + def initialize(language: nil, scheme: nil, pattern: nil) + @attributes = {} + + @attributes[:language] = language if language + @attributes[:scheme] = scheme if scheme + @attributes[:pattern] = pattern if pattern + + @attributes.freeze + end + + # + # A language id, like `typescript`. + # + # @return [string] + def language + attributes.fetch(:language) + end + + # + # A Uri [scheme](#Uri.scheme), like `file` or `untitled`. + # + # @return [string] + def scheme + attributes.fetch(:scheme) + end + + # + # A glob pattern, like `*.{ts,js}`. + # + # Glob patterns can have the following syntax: + # - `*` to match one or more characters in a path segment + # - `?` to match on one character in a path segment + # - `**` to match any number of path segments, including none + # - `{}` to group sub patterns into an OR expression. (e.g. `**​/*.{ts,js}` + # matches all TypeScript and JavaScript files) + # - `[]` to declare a range of characters to match in a path segment + # (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …) + # - `[!...]` to negate a range of characters to match in a path segment + # (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but + # not `example.0`) + # + # @return [string] + def pattern + attributes.fetch(:pattern) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_formatting_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_formatting_client_capabilities.rb new file mode 100644 index 00000000..9fd9f83e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_formatting_client_capabilities.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + class DocumentFormattingClientCapabilities + def initialize(dynamic_registration: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + + @attributes.freeze + end + + # + # Whether formatting supports dynamic registration. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_formatting_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_formatting_options.rb new file mode 100644 index 00000000..e8780868 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_formatting_options.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Interface + class DocumentFormattingOptions + def initialize(work_done_progress: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_formatting_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_formatting_params.rb new file mode 100644 index 00000000..e6627428 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_formatting_params.rb @@ -0,0 +1,51 @@ +module LanguageServer + module Protocol + module Interface + class DocumentFormattingParams + def initialize(work_done_token: nil, text_document:, options:) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:textDocument] = text_document + @attributes[:options] = options + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # The document to format. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The format options. + # + # @return [FormattingOptions] + def options + attributes.fetch(:options) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_formatting_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_formatting_registration_options.rb new file mode 100644 index 00000000..7e6d7c35 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_formatting_registration_options.rb @@ -0,0 +1,40 @@ +module LanguageServer + module Protocol + module Interface + class DocumentFormattingRegistrationOptions + def initialize(document_selector:, work_done_progress: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_highlight.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_highlight.rb new file mode 100644 index 00000000..d4347b81 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_highlight.rb @@ -0,0 +1,47 @@ +module LanguageServer + module Protocol + module Interface + # + # A document highlight is a range inside a text document which deserves + # special attention. Usually a document highlight is visualized by changing + # the background color of its range. + # + class DocumentHighlight + def initialize(range:, kind: nil) + @attributes = {} + + @attributes[:range] = range + @attributes[:kind] = kind if kind + + @attributes.freeze + end + + # + # The range this highlight applies to. + # + # @return [Range] + def range + attributes.fetch(:range) + end + + # + # The highlight kind, default is DocumentHighlightKind.Text. + # + # @return [DocumentHighlightKind] + def kind + attributes.fetch(:kind) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_highlight_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_highlight_client_capabilities.rb new file mode 100644 index 00000000..d8f56118 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_highlight_client_capabilities.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + class DocumentHighlightClientCapabilities + def initialize(dynamic_registration: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + + @attributes.freeze + end + + # + # Whether document highlight supports dynamic registration. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_highlight_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_highlight_options.rb new file mode 100644 index 00000000..97898eb4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_highlight_options.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Interface + class DocumentHighlightOptions + def initialize(work_done_progress: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_highlight_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_highlight_params.rb new file mode 100644 index 00000000..7ba70c0a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_highlight_params.rb @@ -0,0 +1,61 @@ +module LanguageServer + module Protocol + module Interface + class DocumentHighlightParams + def initialize(text_document:, position:, work_done_token: nil, partial_result_token: nil) + @attributes = {} + + @attributes[:textDocument] = text_document + @attributes[:position] = position + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + + @attributes.freeze + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The position inside the text document. + # + # @return [Position] + def position + attributes.fetch(:position) + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_highlight_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_highlight_registration_options.rb new file mode 100644 index 00000000..2268431f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_highlight_registration_options.rb @@ -0,0 +1,40 @@ +module LanguageServer + module Protocol + module Interface + class DocumentHighlightRegistrationOptions + def initialize(document_selector:, work_done_progress: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_link.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_link.rb new file mode 100644 index 00000000..2a2ecb23 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_link.rb @@ -0,0 +1,70 @@ +module LanguageServer + module Protocol + module Interface + # + # A document link is a range in a text document that links to an internal or + # external resource, like another text document or a web site. + # + class DocumentLink + def initialize(range:, target: nil, tooltip: nil, data: nil) + @attributes = {} + + @attributes[:range] = range + @attributes[:target] = target if target + @attributes[:tooltip] = tooltip if tooltip + @attributes[:data] = data if data + + @attributes.freeze + end + + # + # The range this link applies to. + # + # @return [Range] + def range + attributes.fetch(:range) + end + + # + # The uri this link points to. If missing a resolve request is sent later. + # + # @return [string] + def target + attributes.fetch(:target) + end + + # + # The tooltip text when you hover over this link. + # + # If a tooltip is provided, is will be displayed in a string that includes + # instructions on how to trigger the link, such as `{0} (ctrl + click)`. + # The specific instructions vary depending on OS, user settings, and + # localization. + # + # @return [string] + def tooltip + attributes.fetch(:tooltip) + end + + # + # A data entry field that is preserved on a document link between a + # DocumentLinkRequest and a DocumentLinkResolveRequest. + # + # @return [LSPAny] + def data + attributes.fetch(:data) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_link_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_link_client_capabilities.rb new file mode 100644 index 00000000..5b72cf1f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_link_client_capabilities.rb @@ -0,0 +1,42 @@ +module LanguageServer + module Protocol + module Interface + class DocumentLinkClientCapabilities + def initialize(dynamic_registration: nil, tooltip_support: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + @attributes[:tooltipSupport] = tooltip_support if tooltip_support + + @attributes.freeze + end + + # + # Whether document link supports dynamic registration. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + # + # Whether the client supports the `tooltip` property on `DocumentLink`. + # + # @return [boolean] + def tooltip_support + attributes.fetch(:tooltipSupport) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_link_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_link_options.rb new file mode 100644 index 00000000..c8af140f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_link_options.rb @@ -0,0 +1,39 @@ +module LanguageServer + module Protocol + module Interface + class DocumentLinkOptions + def initialize(work_done_progress: nil, resolve_provider: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:resolveProvider] = resolve_provider if resolve_provider + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # Document links have a resolve provider as well. + # + # @return [boolean] + def resolve_provider + attributes.fetch(:resolveProvider) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_link_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_link_params.rb new file mode 100644 index 00000000..b3596cbd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_link_params.rb @@ -0,0 +1,52 @@ +module LanguageServer + module Protocol + module Interface + class DocumentLinkParams + def initialize(work_done_token: nil, partial_result_token: nil, text_document:) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + @attributes[:textDocument] = text_document + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + # + # The document to provide document links for. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_link_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_link_registration_options.rb new file mode 100644 index 00000000..593c21ce --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_link_registration_options.rb @@ -0,0 +1,49 @@ +module LanguageServer + module Protocol + module Interface + class DocumentLinkRegistrationOptions + def initialize(document_selector:, work_done_progress: nil, resolve_provider: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:resolveProvider] = resolve_provider if resolve_provider + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # Document links have a resolve provider as well. + # + # @return [boolean] + def resolve_provider + attributes.fetch(:resolveProvider) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_on_type_formatting_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_on_type_formatting_client_capabilities.rb new file mode 100644 index 00000000..0941148f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_on_type_formatting_client_capabilities.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + class DocumentOnTypeFormattingClientCapabilities + def initialize(dynamic_registration: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + + @attributes.freeze + end + + # + # Whether on type formatting supports dynamic registration. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_on_type_formatting_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_on_type_formatting_options.rb new file mode 100644 index 00000000..a5f096c4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_on_type_formatting_options.rb @@ -0,0 +1,42 @@ +module LanguageServer + module Protocol + module Interface + class DocumentOnTypeFormattingOptions + def initialize(first_trigger_character:, more_trigger_character: nil) + @attributes = {} + + @attributes[:firstTriggerCharacter] = first_trigger_character + @attributes[:moreTriggerCharacter] = more_trigger_character if more_trigger_character + + @attributes.freeze + end + + # + # A character on which formatting should be triggered, like `{`. + # + # @return [string] + def first_trigger_character + attributes.fetch(:firstTriggerCharacter) + end + + # + # More trigger characters. + # + # @return [string[]] + def more_trigger_character + attributes.fetch(:moreTriggerCharacter) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_on_type_formatting_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_on_type_formatting_params.rb new file mode 100644 index 00000000..36f48a6d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_on_type_formatting_params.rb @@ -0,0 +1,65 @@ +module LanguageServer + module Protocol + module Interface + class DocumentOnTypeFormattingParams + def initialize(text_document:, position:, ch:, options:) + @attributes = {} + + @attributes[:textDocument] = text_document + @attributes[:position] = position + @attributes[:ch] = ch + @attributes[:options] = options + + @attributes.freeze + end + + # + # The document to format. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The position around which the on type formatting should happen. + # This is not necessarily the exact position where the character denoted + # by the property `ch` got typed. + # + # @return [Position] + def position + attributes.fetch(:position) + end + + # + # The character that has been typed that triggered the formatting + # on type request. That is not necessarily the last character that + # got inserted into the document since the client could auto insert + # characters as well (e.g. like automatic brace completion). + # + # @return [string] + def ch + attributes.fetch(:ch) + end + + # + # The formatting options. + # + # @return [FormattingOptions] + def options + attributes.fetch(:options) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_on_type_formatting_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_on_type_formatting_registration_options.rb new file mode 100644 index 00000000..1008261e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_on_type_formatting_registration_options.rb @@ -0,0 +1,52 @@ +module LanguageServer + module Protocol + module Interface + class DocumentOnTypeFormattingRegistrationOptions + def initialize(document_selector:, first_trigger_character:, more_trigger_character: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:firstTriggerCharacter] = first_trigger_character + @attributes[:moreTriggerCharacter] = more_trigger_character if more_trigger_character + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # + # A character on which formatting should be triggered, like `{`. + # + # @return [string] + def first_trigger_character + attributes.fetch(:firstTriggerCharacter) + end + + # + # More trigger characters. + # + # @return [string[]] + def more_trigger_character + attributes.fetch(:moreTriggerCharacter) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_range_formatting_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_range_formatting_client_capabilities.rb new file mode 100644 index 00000000..92299215 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_range_formatting_client_capabilities.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + class DocumentRangeFormattingClientCapabilities + def initialize(dynamic_registration: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + + @attributes.freeze + end + + # + # Whether formatting supports dynamic registration. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_range_formatting_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_range_formatting_options.rb new file mode 100644 index 00000000..9434f407 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_range_formatting_options.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Interface + class DocumentRangeFormattingOptions + def initialize(work_done_progress: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_range_formatting_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_range_formatting_params.rb new file mode 100644 index 00000000..bc3dd74c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_range_formatting_params.rb @@ -0,0 +1,60 @@ +module LanguageServer + module Protocol + module Interface + class DocumentRangeFormattingParams + def initialize(work_done_token: nil, text_document:, range:, options:) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:textDocument] = text_document + @attributes[:range] = range + @attributes[:options] = options + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # The document to format. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The range to format + # + # @return [Range] + def range + attributes.fetch(:range) + end + + # + # The format options + # + # @return [FormattingOptions] + def options + attributes.fetch(:options) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_range_formatting_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_range_formatting_registration_options.rb new file mode 100644 index 00000000..3bdb033f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_range_formatting_registration_options.rb @@ -0,0 +1,40 @@ +module LanguageServer + module Protocol + module Interface + class DocumentRangeFormattingRegistrationOptions + def initialize(document_selector:, work_done_progress: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_symbol.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_symbol.rb new file mode 100644 index 00000000..97d490a5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_symbol.rb @@ -0,0 +1,108 @@ +module LanguageServer + module Protocol + module Interface + # + # Represents programming constructs like variables, classes, interfaces etc. + # that appear in a document. Document symbols can be hierarchical and they + # have two ranges: one that encloses its definition and one that points to its + # most interesting range, e.g. the range of an identifier. + # + class DocumentSymbol + def initialize(name:, detail: nil, kind:, tags: nil, deprecated: nil, range:, selection_range:, children: nil) + @attributes = {} + + @attributes[:name] = name + @attributes[:detail] = detail if detail + @attributes[:kind] = kind + @attributes[:tags] = tags if tags + @attributes[:deprecated] = deprecated if deprecated + @attributes[:range] = range + @attributes[:selectionRange] = selection_range + @attributes[:children] = children if children + + @attributes.freeze + end + + # + # The name of this symbol. Will be displayed in the user interface and + # therefore must not be an empty string or a string only consisting of + # white spaces. + # + # @return [string] + def name + attributes.fetch(:name) + end + + # + # More detail for this symbol, e.g the signature of a function. + # + # @return [string] + def detail + attributes.fetch(:detail) + end + + # + # The kind of this symbol. + # + # @return [SymbolKind] + def kind + attributes.fetch(:kind) + end + + # + # Tags for this document symbol. + # + # @return [1[]] + def tags + attributes.fetch(:tags) + end + + # + # Indicates if this symbol is deprecated. + # + # @return [boolean] + def deprecated + attributes.fetch(:deprecated) + end + + # + # The range enclosing this symbol not including leading/trailing whitespace + # but everything else like comments. This information is typically used to + # determine if the clients cursor is inside the symbol to reveal in the + # symbol in the UI. + # + # @return [Range] + def range + attributes.fetch(:range) + end + + # + # The range that should be selected and revealed when this symbol is being + # picked, e.g. the name of a function. Must be contained by the `range`. + # + # @return [Range] + def selection_range + attributes.fetch(:selectionRange) + end + + # + # Children of this symbol, e.g. properties of a class. + # + # @return [DocumentSymbol[]] + def children + attributes.fetch(:children) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_symbol_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_symbol_client_capabilities.rb new file mode 100644 index 00000000..4a6e0b28 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_symbol_client_capabilities.rb @@ -0,0 +1,73 @@ +module LanguageServer + module Protocol + module Interface + class DocumentSymbolClientCapabilities + def initialize(dynamic_registration: nil, symbol_kind: nil, hierarchical_document_symbol_support: nil, tag_support: nil, label_support: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + @attributes[:symbolKind] = symbol_kind if symbol_kind + @attributes[:hierarchicalDocumentSymbolSupport] = hierarchical_document_symbol_support if hierarchical_document_symbol_support + @attributes[:tagSupport] = tag_support if tag_support + @attributes[:labelSupport] = label_support if label_support + + @attributes.freeze + end + + # + # Whether document symbol supports dynamic registration. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + # + # Specific capabilities for the `SymbolKind` in the + # `textDocument/documentSymbol` request. + # + # @return [{ valueSet?: SymbolKind[]; }] + def symbol_kind + attributes.fetch(:symbolKind) + end + + # + # The client supports hierarchical document symbols. + # + # @return [boolean] + def hierarchical_document_symbol_support + attributes.fetch(:hierarchicalDocumentSymbolSupport) + end + + # + # The client supports tags on `SymbolInformation`. Tags are supported on + # `DocumentSymbol` if `hierarchicalDocumentSymbolSupport` is set to true. + # Clients supporting tags have to handle unknown tags gracefully. + # + # @return [{ valueSet: 1[]; }] + def tag_support + attributes.fetch(:tagSupport) + end + + # + # The client supports an additional label presented in the UI when + # registering a document symbol provider. + # + # @return [boolean] + def label_support + attributes.fetch(:labelSupport) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_symbol_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_symbol_options.rb new file mode 100644 index 00000000..a83e5d49 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_symbol_options.rb @@ -0,0 +1,40 @@ +module LanguageServer + module Protocol + module Interface + class DocumentSymbolOptions + def initialize(work_done_progress: nil, label: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:label] = label if label + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # A human-readable string that is shown when multiple outlines trees + # are shown for the same document. + # + # @return [string] + def label + attributes.fetch(:label) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_symbol_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_symbol_params.rb new file mode 100644 index 00000000..e3346fe8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_symbol_params.rb @@ -0,0 +1,52 @@ +module LanguageServer + module Protocol + module Interface + class DocumentSymbolParams + def initialize(work_done_token: nil, partial_result_token: nil, text_document:) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + @attributes[:textDocument] = text_document + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_symbol_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_symbol_registration_options.rb new file mode 100644 index 00000000..bcd4b295 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/document_symbol_registration_options.rb @@ -0,0 +1,50 @@ +module LanguageServer + module Protocol + module Interface + class DocumentSymbolRegistrationOptions + def initialize(document_selector:, work_done_progress: nil, label: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:label] = label if label + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # A human-readable string that is shown when multiple outlines trees + # are shown for the same document. + # + # @return [string] + def label + attributes.fetch(:label) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/execute_command_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/execute_command_client_capabilities.rb new file mode 100644 index 00000000..fd074ec9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/execute_command_client_capabilities.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + class ExecuteCommandClientCapabilities + def initialize(dynamic_registration: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + + @attributes.freeze + end + + # + # Execute command supports dynamic registration. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/execute_command_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/execute_command_options.rb new file mode 100644 index 00000000..71f6c48f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/execute_command_options.rb @@ -0,0 +1,39 @@ +module LanguageServer + module Protocol + module Interface + class ExecuteCommandOptions + def initialize(work_done_progress: nil, commands:) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:commands] = commands + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # The commands to be executed on the server + # + # @return [string[]] + def commands + attributes.fetch(:commands) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/execute_command_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/execute_command_params.rb new file mode 100644 index 00000000..0062a128 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/execute_command_params.rb @@ -0,0 +1,51 @@ +module LanguageServer + module Protocol + module Interface + class ExecuteCommandParams + def initialize(work_done_token: nil, command:, arguments: nil) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:command] = command + @attributes[:arguments] = arguments if arguments + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # The identifier of the actual command handler. + # + # @return [string] + def command + attributes.fetch(:command) + end + + # + # Arguments that the command should be invoked with. + # + # @return [LSPAny[]] + def arguments + attributes.fetch(:arguments) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/execute_command_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/execute_command_registration_options.rb new file mode 100644 index 00000000..d522b3b8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/execute_command_registration_options.rb @@ -0,0 +1,42 @@ +module LanguageServer + module Protocol + module Interface + # + # Execute command registration options. + # + class ExecuteCommandRegistrationOptions + def initialize(work_done_progress: nil, commands:) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:commands] = commands + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # The commands to be executed on the server + # + # @return [string[]] + def commands + attributes.fetch(:commands) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/execution_summary.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/execution_summary.rb new file mode 100644 index 00000000..db0d14d0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/execution_summary.rb @@ -0,0 +1,45 @@ +module LanguageServer + module Protocol + module Interface + class ExecutionSummary + def initialize(execution_order:, success: nil) + @attributes = {} + + @attributes[:executionOrder] = execution_order + @attributes[:success] = success if success + + @attributes.freeze + end + + # + # A strict monotonically increasing value + # indicating the execution order of a cell + # inside a notebook. + # + # @return [number] + def execution_order + attributes.fetch(:executionOrder) + end + + # + # Whether the execution was successful or + # not if known by the client. + # + # @return [boolean] + def success + attributes.fetch(:success) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_create.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_create.rb new file mode 100644 index 00000000..3bfb40b0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_create.rb @@ -0,0 +1,36 @@ +module LanguageServer + module Protocol + module Interface + # + # Represents information on a file/folder create. + # + class FileCreate + def initialize(uri:) + @attributes = {} + + @attributes[:uri] = uri + + @attributes.freeze + end + + # + # A file:// URI for the location of the file/folder being created. + # + # @return [string] + def uri + attributes.fetch(:uri) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_delete.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_delete.rb new file mode 100644 index 00000000..dfc5f7dc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_delete.rb @@ -0,0 +1,36 @@ +module LanguageServer + module Protocol + module Interface + # + # Represents information on a file/folder delete. + # + class FileDelete + def initialize(uri:) + @attributes = {} + + @attributes[:uri] = uri + + @attributes.freeze + end + + # + # A file:// URI for the location of the file/folder being deleted. + # + # @return [string] + def uri + attributes.fetch(:uri) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_event.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_event.rb new file mode 100644 index 00000000..1552437a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_event.rb @@ -0,0 +1,45 @@ +module LanguageServer + module Protocol + module Interface + # + # An event describing a file change. + # + class FileEvent + def initialize(uri:, type:) + @attributes = {} + + @attributes[:uri] = uri + @attributes[:type] = type + + @attributes.freeze + end + + # + # The file's URI. + # + # @return [string] + def uri + attributes.fetch(:uri) + end + + # + # The change type. + # + # @return [number] + def type + attributes.fetch(:type) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_operation_filter.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_operation_filter.rb new file mode 100644 index 00000000..226378a7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_operation_filter.rb @@ -0,0 +1,46 @@ +module LanguageServer + module Protocol + module Interface + # + # A filter to describe in which file operation requests or notifications + # the server is interested in. + # + class FileOperationFilter + def initialize(scheme: nil, pattern:) + @attributes = {} + + @attributes[:scheme] = scheme if scheme + @attributes[:pattern] = pattern + + @attributes.freeze + end + + # + # A Uri like `file` or `untitled`. + # + # @return [string] + def scheme + attributes.fetch(:scheme) + end + + # + # The actual file operation pattern. + # + # @return [FileOperationPattern] + def pattern + attributes.fetch(:pattern) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_operation_pattern.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_operation_pattern.rb new file mode 100644 index 00000000..bc74cb54 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_operation_pattern.rb @@ -0,0 +1,67 @@ +module LanguageServer + module Protocol + module Interface + # + # A pattern to describe in which file operation requests or notifications + # the server is interested in. + # + class FileOperationPattern + def initialize(glob:, matches: nil, options: nil) + @attributes = {} + + @attributes[:glob] = glob + @attributes[:matches] = matches if matches + @attributes[:options] = options if options + + @attributes.freeze + end + + # + # The glob pattern to match. Glob patterns can have the following syntax: + # - `*` to match one or more characters in a path segment + # - `?` to match on one character in a path segment + # - `**` to match any number of path segments, including none + # - `{}` to group sub patterns into an OR expression. (e.g. `**​/*.{ts,js}` + # matches all TypeScript and JavaScript files) + # - `[]` to declare a range of characters to match in a path segment + # (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …) + # - `[!...]` to negate a range of characters to match in a path segment + # (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but + # not `example.0`) + # + # @return [string] + def glob + attributes.fetch(:glob) + end + + # + # Whether to match files or folders with this pattern. + # + # Matches both if undefined. + # + # @return [FileOperationPatternKind] + def matches + attributes.fetch(:matches) + end + + # + # Additional options used during matching. + # + # @return [FileOperationPatternOptions] + def options + attributes.fetch(:options) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_operation_pattern_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_operation_pattern_options.rb new file mode 100644 index 00000000..4ec58464 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_operation_pattern_options.rb @@ -0,0 +1,36 @@ +module LanguageServer + module Protocol + module Interface + # + # Matching options for the file operation pattern. + # + class FileOperationPatternOptions + def initialize(ignore_case: nil) + @attributes = {} + + @attributes[:ignoreCase] = ignore_case if ignore_case + + @attributes.freeze + end + + # + # The pattern should be matched ignoring casing. + # + # @return [boolean] + def ignore_case + attributes.fetch(:ignoreCase) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_operation_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_operation_registration_options.rb new file mode 100644 index 00000000..d3f38b49 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_operation_registration_options.rb @@ -0,0 +1,36 @@ +module LanguageServer + module Protocol + module Interface + # + # The options to register for file operations. + # + class FileOperationRegistrationOptions + def initialize(filters:) + @attributes = {} + + @attributes[:filters] = filters + + @attributes.freeze + end + + # + # The actual filters. + # + # @return [FileOperationFilter[]] + def filters + attributes.fetch(:filters) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_rename.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_rename.rb new file mode 100644 index 00000000..09309973 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_rename.rb @@ -0,0 +1,45 @@ +module LanguageServer + module Protocol + module Interface + # + # Represents information on a file/folder rename. + # + class FileRename + def initialize(old_uri:, new_uri:) + @attributes = {} + + @attributes[:oldUri] = old_uri + @attributes[:newUri] = new_uri + + @attributes.freeze + end + + # + # A file:// URI for the original location of the file/folder being renamed. + # + # @return [string] + def old_uri + attributes.fetch(:oldUri) + end + + # + # A file:// URI for the new location of the file/folder being renamed. + # + # @return [string] + def new_uri + attributes.fetch(:newUri) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_system_watcher.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_system_watcher.rb new file mode 100644 index 00000000..bdbe225b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/file_system_watcher.rb @@ -0,0 +1,45 @@ +module LanguageServer + module Protocol + module Interface + class FileSystemWatcher + def initialize(glob_pattern:, kind: nil) + @attributes = {} + + @attributes[:globPattern] = glob_pattern + @attributes[:kind] = kind if kind + + @attributes.freeze + end + + # + # The glob pattern to watch. See {@link GlobPattern glob pattern} + # for more detail. + # + # @return [GlobPattern] + def glob_pattern + attributes.fetch(:globPattern) + end + + # + # The kind of events of interest. If omitted it defaults + # to WatchKind.Create | WatchKind.Change | WatchKind.Delete + # which is 7. + # + # @return [number] + def kind + attributes.fetch(:kind) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/folding_range.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/folding_range.rb new file mode 100644 index 00000000..dea0df3d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/folding_range.rb @@ -0,0 +1,94 @@ +module LanguageServer + module Protocol + module Interface + # + # Represents a folding range. To be valid, start and end line must be bigger + # than zero and smaller than the number of lines in the document. Clients + # are free to ignore invalid ranges. + # + class FoldingRange + def initialize(start_line:, start_character: nil, end_line:, end_character: nil, kind: nil, collapsed_text: nil) + @attributes = {} + + @attributes[:startLine] = start_line + @attributes[:startCharacter] = start_character if start_character + @attributes[:endLine] = end_line + @attributes[:endCharacter] = end_character if end_character + @attributes[:kind] = kind if kind + @attributes[:collapsedText] = collapsed_text if collapsed_text + + @attributes.freeze + end + + # + # The zero-based start line of the range to fold. The folded area starts + # after the line's last character. To be valid, the end must be zero or + # larger and smaller than the number of lines in the document. + # + # @return [number] + def start_line + attributes.fetch(:startLine) + end + + # + # The zero-based character offset from where the folded range starts. If + # not defined, defaults to the length of the start line. + # + # @return [number] + def start_character + attributes.fetch(:startCharacter) + end + + # + # The zero-based end line of the range to fold. The folded area ends with + # the line's last character. To be valid, the end must be zero or larger + # and smaller than the number of lines in the document. + # + # @return [number] + def end_line + attributes.fetch(:endLine) + end + + # + # The zero-based character offset before the folded range ends. If not + # defined, defaults to the length of the end line. + # + # @return [number] + def end_character + attributes.fetch(:endCharacter) + end + + # + # Describes the kind of the folding range such as `comment` or `region`. + # The kind is used to categorize folding ranges and used by commands like + # 'Fold all comments'. See [FoldingRangeKind](#FoldingRangeKind) for an + # enumeration of standardized kinds. + # + # @return [string] + def kind + attributes.fetch(:kind) + end + + # + # The text that the client should show when the specified range is + # collapsed. If not defined or not supported by the client, a default + # will be chosen by the client. + # + # @return [string] + def collapsed_text + attributes.fetch(:collapsedText) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/folding_range_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/folding_range_client_capabilities.rb new file mode 100644 index 00000000..460a22be --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/folding_range_client_capabilities.rb @@ -0,0 +1,76 @@ +module LanguageServer + module Protocol + module Interface + class FoldingRangeClientCapabilities + def initialize(dynamic_registration: nil, range_limit: nil, line_folding_only: nil, folding_range_kind: nil, folding_range: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + @attributes[:rangeLimit] = range_limit if range_limit + @attributes[:lineFoldingOnly] = line_folding_only if line_folding_only + @attributes[:foldingRangeKind] = folding_range_kind if folding_range_kind + @attributes[:foldingRange] = folding_range if folding_range + + @attributes.freeze + end + + # + # Whether implementation supports dynamic registration for folding range + # providers. If this is set to `true` the client supports the new + # `FoldingRangeRegistrationOptions` return value for the corresponding + # server capability as well. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + # + # The maximum number of folding ranges that the client prefers to receive + # per document. The value serves as a hint, servers are free to follow the + # limit. + # + # @return [number] + def range_limit + attributes.fetch(:rangeLimit) + end + + # + # If set, the client signals that it only supports folding complete lines. + # If set, client will ignore specified `startCharacter` and `endCharacter` + # properties in a FoldingRange. + # + # @return [boolean] + def line_folding_only + attributes.fetch(:lineFoldingOnly) + end + + # + # Specific options for the folding range kind. + # + # @return [{ valueSet?: string[]; }] + def folding_range_kind + attributes.fetch(:foldingRangeKind) + end + + # + # Specific options for the folding range. + # + # @return [{ collapsedText?: boolean; }] + def folding_range + attributes.fetch(:foldingRange) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/folding_range_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/folding_range_options.rb new file mode 100644 index 00000000..36f6ebf3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/folding_range_options.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Interface + class FoldingRangeOptions + def initialize(work_done_progress: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/folding_range_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/folding_range_params.rb new file mode 100644 index 00000000..c4d35146 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/folding_range_params.rb @@ -0,0 +1,52 @@ +module LanguageServer + module Protocol + module Interface + class FoldingRangeParams + def initialize(work_done_token: nil, partial_result_token: nil, text_document:) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + @attributes[:textDocument] = text_document + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/folding_range_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/folding_range_registration_options.rb new file mode 100644 index 00000000..abf7938e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/folding_range_registration_options.rb @@ -0,0 +1,50 @@ +module LanguageServer + module Protocol + module Interface + class FoldingRangeRegistrationOptions + def initialize(document_selector:, work_done_progress: nil, id: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:id] = id if id + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # The id used to register the request. The id can be used to deregister + # the request again. See also Registration#id. + # + # @return [string] + def id + attributes.fetch(:id) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/formatting_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/formatting_options.rb new file mode 100644 index 00000000..e0003015 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/formatting_options.rb @@ -0,0 +1,72 @@ +module LanguageServer + module Protocol + module Interface + # + # Value-object describing what options formatting should use. + # + class FormattingOptions + def initialize(tab_size:, insert_spaces:, trim_trailing_whitespace: nil, insert_final_newline: nil, trim_final_newlines: nil) + @attributes = {} + + @attributes[:tabSize] = tab_size + @attributes[:insertSpaces] = insert_spaces + @attributes[:trimTrailingWhitespace] = trim_trailing_whitespace if trim_trailing_whitespace + @attributes[:insertFinalNewline] = insert_final_newline if insert_final_newline + @attributes[:trimFinalNewlines] = trim_final_newlines if trim_final_newlines + + @attributes.freeze + end + + # + # Size of a tab in spaces. + # + # @return [number] + def tab_size + attributes.fetch(:tabSize) + end + + # + # Prefer spaces over tabs. + # + # @return [boolean] + def insert_spaces + attributes.fetch(:insertSpaces) + end + + # + # Trim trailing whitespace on a line. + # + # @return [boolean] + def trim_trailing_whitespace + attributes.fetch(:trimTrailingWhitespace) + end + + # + # Insert a newline character at the end of the file if one does not exist. + # + # @return [boolean] + def insert_final_newline + attributes.fetch(:insertFinalNewline) + end + + # + # Trim all newlines after the final newline at the end of the file. + # + # @return [boolean] + def trim_final_newlines + attributes.fetch(:trimFinalNewlines) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/full_document_diagnostic_report.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/full_document_diagnostic_report.rb new file mode 100644 index 00000000..9f115524 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/full_document_diagnostic_report.rb @@ -0,0 +1,56 @@ +module LanguageServer + module Protocol + module Interface + # + # A diagnostic report with a full set of problems. + # + class FullDocumentDiagnosticReport + def initialize(kind:, result_id: nil, items:) + @attributes = {} + + @attributes[:kind] = kind + @attributes[:resultId] = result_id if result_id + @attributes[:items] = items + + @attributes.freeze + end + + # + # A full document diagnostic report. + # + # @return [any] + def kind + attributes.fetch(:kind) + end + + # + # An optional result id. If provided it will + # be sent on the next diagnostic request for the + # same document. + # + # @return [string] + def result_id + attributes.fetch(:resultId) + end + + # + # The actual items. + # + # @return [Diagnostic[]] + def items + attributes.fetch(:items) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/hover.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/hover.rb new file mode 100644 index 00000000..05f5366d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/hover.rb @@ -0,0 +1,46 @@ +module LanguageServer + module Protocol + module Interface + # + # The result of a hover request. + # + class Hover + def initialize(contents:, range: nil) + @attributes = {} + + @attributes[:contents] = contents + @attributes[:range] = range if range + + @attributes.freeze + end + + # + # The hover's content + # + # @return [MarkupContent | MarkedString | MarkedString[]] + def contents + attributes.fetch(:contents) + end + + # + # An optional range is a range inside a text document + # that is used to visualize a hover, e.g. by changing the background color. + # + # @return [Range] + def range + attributes.fetch(:range) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/hover_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/hover_client_capabilities.rb new file mode 100644 index 00000000..8b189edf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/hover_client_capabilities.rb @@ -0,0 +1,44 @@ +module LanguageServer + module Protocol + module Interface + class HoverClientCapabilities + def initialize(dynamic_registration: nil, content_format: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + @attributes[:contentFormat] = content_format if content_format + + @attributes.freeze + end + + # + # Whether hover supports dynamic registration. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + # + # Client supports the follow content formats if the content + # property refers to a `literal of type MarkupContent`. + # The order describes the preferred format of the client. + # + # @return [MarkupKind[]] + def content_format + attributes.fetch(:contentFormat) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/hover_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/hover_options.rb new file mode 100644 index 00000000..9b4eaa9d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/hover_options.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Interface + class HoverOptions + def initialize(work_done_progress: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/hover_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/hover_params.rb new file mode 100644 index 00000000..cfdb626c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/hover_params.rb @@ -0,0 +1,51 @@ +module LanguageServer + module Protocol + module Interface + class HoverParams + def initialize(text_document:, position:, work_done_token: nil) + @attributes = {} + + @attributes[:textDocument] = text_document + @attributes[:position] = position + @attributes[:workDoneToken] = work_done_token if work_done_token + + @attributes.freeze + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The position inside the text document. + # + # @return [Position] + def position + attributes.fetch(:position) + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/hover_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/hover_registration_options.rb new file mode 100644 index 00000000..02a4a64b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/hover_registration_options.rb @@ -0,0 +1,40 @@ +module LanguageServer + module Protocol + module Interface + class HoverRegistrationOptions + def initialize(document_selector:, work_done_progress: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/hover_result.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/hover_result.rb new file mode 100644 index 00000000..81afa632 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/hover_result.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Interface + class HoverResult + def initialize(value:) + @attributes = {} + + @attributes[:value] = value + + @attributes.freeze + end + + # @return [string] + def value + attributes.fetch(:value) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/implementation_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/implementation_client_capabilities.rb new file mode 100644 index 00000000..be8cd0dc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/implementation_client_capabilities.rb @@ -0,0 +1,44 @@ +module LanguageServer + module Protocol + module Interface + class ImplementationClientCapabilities + def initialize(dynamic_registration: nil, link_support: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + @attributes[:linkSupport] = link_support if link_support + + @attributes.freeze + end + + # + # Whether implementation supports dynamic registration. If this is set to + # `true` the client supports the new `ImplementationRegistrationOptions` + # return value for the corresponding server capability as well. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + # + # The client supports additional metadata in the form of definition links. + # + # @return [boolean] + def link_support + attributes.fetch(:linkSupport) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/implementation_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/implementation_options.rb new file mode 100644 index 00000000..09034c74 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/implementation_options.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Interface + class ImplementationOptions + def initialize(work_done_progress: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/implementation_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/implementation_params.rb new file mode 100644 index 00000000..e6fc745e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/implementation_params.rb @@ -0,0 +1,61 @@ +module LanguageServer + module Protocol + module Interface + class ImplementationParams + def initialize(text_document:, position:, work_done_token: nil, partial_result_token: nil) + @attributes = {} + + @attributes[:textDocument] = text_document + @attributes[:position] = position + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + + @attributes.freeze + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The position inside the text document. + # + # @return [Position] + def position + attributes.fetch(:position) + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/implementation_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/implementation_registration_options.rb new file mode 100644 index 00000000..3c0c5011 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/implementation_registration_options.rb @@ -0,0 +1,50 @@ +module LanguageServer + module Protocol + module Interface + class ImplementationRegistrationOptions + def initialize(document_selector:, work_done_progress: nil, id: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:id] = id if id + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # The id used to register the request. The id can be used to deregister + # the request again. See also Registration#id. + # + # @return [string] + def id + attributes.fetch(:id) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/initialize_error.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/initialize_error.rb new file mode 100644 index 00000000..a0560945 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/initialize_error.rb @@ -0,0 +1,36 @@ +module LanguageServer + module Protocol + module Interface + class InitializeError + def initialize(retry:) + @attributes = {} + + @attributes[:retry] = binding.local_variable_get(:retry) + + @attributes.freeze + end + + # + # Indicates whether the client execute the following retry logic: + # (1) show the message provided by the ResponseError to the user + # (2) user selects retry or cancel + # (3) if user selected retry the initialize method is sent again. + # + # @return [boolean] + def retry + attributes.fetch(:retry) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/initialize_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/initialize_params.rb new file mode 100644 index 00000000..3b0c955d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/initialize_params.rb @@ -0,0 +1,128 @@ +module LanguageServer + module Protocol + module Interface + class InitializeParams + def initialize(work_done_token: nil, process_id:, client_info: nil, locale: nil, root_path: nil, root_uri:, initialization_options: nil, capabilities:, trace: nil, workspace_folders: nil) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:processId] = process_id + @attributes[:clientInfo] = client_info if client_info + @attributes[:locale] = locale if locale + @attributes[:rootPath] = root_path if root_path + @attributes[:rootUri] = root_uri + @attributes[:initializationOptions] = initialization_options if initialization_options + @attributes[:capabilities] = capabilities + @attributes[:trace] = trace if trace + @attributes[:workspaceFolders] = workspace_folders if workspace_folders + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # The process Id of the parent process that started the server. Is null if + # the process has not been started by another process. If the parent + # process is not alive then the server should exit (see exit notification) + # its process. + # + # @return [number] + def process_id + attributes.fetch(:processId) + end + + # + # Information about the client + # + # @return [{ name: string; version?: string; }] + def client_info + attributes.fetch(:clientInfo) + end + + # + # The locale the client is currently showing the user interface + # in. This must not necessarily be the locale of the operating + # system. + # + # Uses IETF language tags as the value's syntax + # (See https://en.wikipedia.org/wiki/IETF_language_tag) + # + # @return [string] + def locale + attributes.fetch(:locale) + end + + # + # The rootPath of the workspace. Is null + # if no folder is open. + # + # @return [string] + def root_path + attributes.fetch(:rootPath) + end + + # + # The rootUri of the workspace. Is null if no + # folder is open. If both `rootPath` and `rootUri` are set + # `rootUri` wins. + # + # @return [string] + def root_uri + attributes.fetch(:rootUri) + end + + # + # User provided initialization options. + # + # @return [LSPAny] + def initialization_options + attributes.fetch(:initializationOptions) + end + + # + # The capabilities provided by the client (editor or tool) + # + # @return [ClientCapabilities] + def capabilities + attributes.fetch(:capabilities) + end + + # + # The initial trace setting. If omitted trace is disabled ('off'). + # + # @return [TraceValue] + def trace + attributes.fetch(:trace) + end + + # + # The workspace folders configured in the client when the server starts. + # This property is only available if the client supports workspace folders. + # It can be `null` if the client supports workspace folders but none are + # configured. + # + # @return [WorkspaceFolder[]] + def workspace_folders + attributes.fetch(:workspaceFolders) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/initialize_result.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/initialize_result.rb new file mode 100644 index 00000000..637dad6d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/initialize_result.rb @@ -0,0 +1,42 @@ +module LanguageServer + module Protocol + module Interface + class InitializeResult + def initialize(capabilities:, server_info: nil) + @attributes = {} + + @attributes[:capabilities] = capabilities + @attributes[:serverInfo] = server_info if server_info + + @attributes.freeze + end + + # + # The capabilities the language server provides. + # + # @return [ServerCapabilities] + def capabilities + attributes.fetch(:capabilities) + end + + # + # Information about the server. + # + # @return [{ name: string; version?: string; }] + def server_info + attributes.fetch(:serverInfo) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/initialized_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/initialized_params.rb new file mode 100644 index 00000000..fe7a8d08 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/initialized_params.rb @@ -0,0 +1,24 @@ +module LanguageServer + module Protocol + module Interface + class InitializedParams + def initialize() + @attributes = {} + + + @attributes.freeze + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inlay_hint.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inlay_hint.rb new file mode 100644 index 00000000..5c4a92c0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inlay_hint.rb @@ -0,0 +1,122 @@ +module LanguageServer + module Protocol + module Interface + # + # Inlay hint information. + # + class InlayHint + def initialize(position:, label:, kind: nil, text_edits: nil, tooltip: nil, padding_left: nil, padding_right: nil, data: nil) + @attributes = {} + + @attributes[:position] = position + @attributes[:label] = label + @attributes[:kind] = kind if kind + @attributes[:textEdits] = text_edits if text_edits + @attributes[:tooltip] = tooltip if tooltip + @attributes[:paddingLeft] = padding_left if padding_left + @attributes[:paddingRight] = padding_right if padding_right + @attributes[:data] = data if data + + @attributes.freeze + end + + # + # The position of this hint. + # + # @return [Position] + def position + attributes.fetch(:position) + end + + # + # The label of this hint. A human readable string or an array of + # InlayHintLabelPart label parts. + # + # *Note* that neither the string nor the label part can be empty. + # + # @return [string | InlayHintLabelPart[]] + def label + attributes.fetch(:label) + end + + # + # The kind of this hint. Can be omitted in which case the client + # should fall back to a reasonable default. + # + # @return [InlayHintKind] + def kind + attributes.fetch(:kind) + end + + # + # Optional text edits that are performed when accepting this inlay hint. + # + # *Note* that edits are expected to change the document so that the inlay + # hint (or its nearest variant) is now part of the document and the inlay + # hint itself is now obsolete. + # + # Depending on the client capability `inlayHint.resolveSupport` clients + # might resolve this property late using the resolve request. + # + # @return [TextEdit[]] + def text_edits + attributes.fetch(:textEdits) + end + + # + # The tooltip text when you hover over this item. + # + # Depending on the client capability `inlayHint.resolveSupport` clients + # might resolve this property late using the resolve request. + # + # @return [string | MarkupContent] + def tooltip + attributes.fetch(:tooltip) + end + + # + # Render padding before the hint. + # + # Note: Padding should use the editor's background color, not the + # background color of the hint itself. That means padding can be used + # to visually align/separate an inlay hint. + # + # @return [boolean] + def padding_left + attributes.fetch(:paddingLeft) + end + + # + # Render padding after the hint. + # + # Note: Padding should use the editor's background color, not the + # background color of the hint itself. That means padding can be used + # to visually align/separate an inlay hint. + # + # @return [boolean] + def padding_right + attributes.fetch(:paddingRight) + end + + # + # A data entry field that is preserved on an inlay hint between + # a `textDocument/inlayHint` and a `inlayHint/resolve` request. + # + # @return [LSPAny] + def data + attributes.fetch(:data) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inlay_hint_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inlay_hint_client_capabilities.rb new file mode 100644 index 00000000..f50db0f6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inlay_hint_client_capabilities.rb @@ -0,0 +1,46 @@ +module LanguageServer + module Protocol + module Interface + # + # Inlay hint client capabilities. + # + class InlayHintClientCapabilities + def initialize(dynamic_registration: nil, resolve_support: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + @attributes[:resolveSupport] = resolve_support if resolve_support + + @attributes.freeze + end + + # + # Whether inlay hints support dynamic registration. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + # + # Indicates which properties a client can resolve lazily on an inlay + # hint. + # + # @return [{ properties: string[]; }] + def resolve_support + attributes.fetch(:resolveSupport) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inlay_hint_label_part.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inlay_hint_label_part.rb new file mode 100644 index 00000000..3b21d8a7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inlay_hint_label_part.rb @@ -0,0 +1,79 @@ +module LanguageServer + module Protocol + module Interface + # + # An inlay hint label part allows for interactive and composite labels + # of inlay hints. + # + class InlayHintLabelPart + def initialize(value:, tooltip: nil, location: nil, command: nil) + @attributes = {} + + @attributes[:value] = value + @attributes[:tooltip] = tooltip if tooltip + @attributes[:location] = location if location + @attributes[:command] = command if command + + @attributes.freeze + end + + # + # The value of this label part. + # + # @return [string] + def value + attributes.fetch(:value) + end + + # + # The tooltip text when you hover over this label part. Depending on + # the client capability `inlayHint.resolveSupport` clients might resolve + # this property late using the resolve request. + # + # @return [string | MarkupContent] + def tooltip + attributes.fetch(:tooltip) + end + + # + # An optional source code location that represents this + # label part. + # + # The editor will use this location for the hover and for code navigation + # features: This part will become a clickable link that resolves to the + # definition of the symbol at the given location (not necessarily the + # location itself), it shows the hover that shows at the given location, + # and it shows a context menu with further code navigation commands. + # + # Depending on the client capability `inlayHint.resolveSupport` clients + # might resolve this property late using the resolve request. + # + # @return [Location] + def location + attributes.fetch(:location) + end + + # + # An optional command for this label part. + # + # Depending on the client capability `inlayHint.resolveSupport` clients + # might resolve this property late using the resolve request. + # + # @return [Command] + def command + attributes.fetch(:command) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inlay_hint_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inlay_hint_options.rb new file mode 100644 index 00000000..54e9260c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inlay_hint_options.rb @@ -0,0 +1,43 @@ +module LanguageServer + module Protocol + module Interface + # + # Inlay hint options used during static registration. + # + class InlayHintOptions + def initialize(work_done_progress: nil, resolve_provider: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:resolveProvider] = resolve_provider if resolve_provider + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # The server provides support to resolve additional + # information for an inlay hint item. + # + # @return [boolean] + def resolve_provider + attributes.fetch(:resolveProvider) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inlay_hint_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inlay_hint_params.rb new file mode 100644 index 00000000..6b12f2e3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inlay_hint_params.rb @@ -0,0 +1,54 @@ +module LanguageServer + module Protocol + module Interface + # + # A parameter literal used in inlay hint requests. + # + class InlayHintParams + def initialize(work_done_token: nil, text_document:, range:) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:textDocument] = text_document + @attributes[:range] = range + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The visible document range for which inlay hints should be computed. + # + # @return [Range] + def range + attributes.fetch(:range) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inlay_hint_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inlay_hint_registration_options.rb new file mode 100644 index 00000000..46f8ab91 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inlay_hint_registration_options.rb @@ -0,0 +1,63 @@ +module LanguageServer + module Protocol + module Interface + # + # Inlay hint options used during static or dynamic registration. + # + class InlayHintRegistrationOptions + def initialize(work_done_progress: nil, resolve_provider: nil, document_selector:, id: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:resolveProvider] = resolve_provider if resolve_provider + @attributes[:documentSelector] = document_selector + @attributes[:id] = id if id + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # The server provides support to resolve additional + # information for an inlay hint item. + # + # @return [boolean] + def resolve_provider + attributes.fetch(:resolveProvider) + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # + # The id used to register the request. The id can be used to deregister + # the request again. See also Registration#id. + # + # @return [string] + def id + attributes.fetch(:id) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inlay_hint_workspace_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inlay_hint_workspace_client_capabilities.rb new file mode 100644 index 00000000..ff5450f2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inlay_hint_workspace_client_capabilities.rb @@ -0,0 +1,42 @@ +module LanguageServer + module Protocol + module Interface + # + # Client workspace capabilities specific to inlay hints. + # + class InlayHintWorkspaceClientCapabilities + def initialize(refresh_support: nil) + @attributes = {} + + @attributes[:refreshSupport] = refresh_support if refresh_support + + @attributes.freeze + end + + # + # Whether the client implementation supports a refresh request sent from + # the server to the client. + # + # Note that this event is global and will force the client to refresh all + # inlay hints currently shown. It should be used with absolute care and + # is useful for situation where a server for example detects a project wide + # change that requires such a calculation. + # + # @return [boolean] + def refresh_support + attributes.fetch(:refreshSupport) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_client_capabilities.rb new file mode 100644 index 00000000..9ba73675 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_client_capabilities.rb @@ -0,0 +1,37 @@ +module LanguageServer + module Protocol + module Interface + # + # Client capabilities specific to inline values. + # + class InlineValueClientCapabilities + def initialize(dynamic_registration: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + + @attributes.freeze + end + + # + # Whether implementation supports dynamic registration for inline + # value providers. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_context.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_context.rb new file mode 100644 index 00000000..4cde6639 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_context.rb @@ -0,0 +1,44 @@ +module LanguageServer + module Protocol + module Interface + class InlineValueContext + def initialize(frame_id:, stopped_location:) + @attributes = {} + + @attributes[:frameId] = frame_id + @attributes[:stoppedLocation] = stopped_location + + @attributes.freeze + end + + # + # The stack frame (as a DAP Id) where the execution has stopped. + # + # @return [number] + def frame_id + attributes.fetch(:frameId) + end + + # + # The document range where execution has stopped. + # Typically the end position of the range denotes the line where the + # inline values are shown. + # + # @return [Range] + def stopped_location + attributes.fetch(:stoppedLocation) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_evaluatable_expression.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_evaluatable_expression.rb new file mode 100644 index 00000000..68d0dcd8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_evaluatable_expression.rb @@ -0,0 +1,52 @@ +module LanguageServer + module Protocol + module Interface + # + # Provide an inline value through an expression evaluation. + # + # If only a range is specified, the expression will be extracted from the + # underlying document. + # + # An optional expression can be used to override the extracted expression. + # + class InlineValueEvaluatableExpression + def initialize(range:, expression: nil) + @attributes = {} + + @attributes[:range] = range + @attributes[:expression] = expression if expression + + @attributes.freeze + end + + # + # The document range for which the inline value applies. + # The range is used to extract the evaluatable expression from the + # underlying document. + # + # @return [Range] + def range + attributes.fetch(:range) + end + + # + # If specified the expression overrides the extracted expression. + # + # @return [string] + def expression + attributes.fetch(:expression) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_options.rb new file mode 100644 index 00000000..c2b51b42 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_options.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + # + # Inline value options used during static registration. + # + class InlineValueOptions + def initialize(work_done_progress: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_params.rb new file mode 100644 index 00000000..a67c11d0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_params.rb @@ -0,0 +1,64 @@ +module LanguageServer + module Protocol + module Interface + # + # A parameter literal used in inline value requests. + # + class InlineValueParams + def initialize(work_done_token: nil, text_document:, range:, context:) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:textDocument] = text_document + @attributes[:range] = range + @attributes[:context] = context + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The document range for which inline values should be computed. + # + # @return [Range] + def range + attributes.fetch(:range) + end + + # + # Additional information about the context in which inline values were + # requested. + # + # @return [InlineValueContext] + def context + attributes.fetch(:context) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_registration_options.rb new file mode 100644 index 00000000..921e32fc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_registration_options.rb @@ -0,0 +1,53 @@ +module LanguageServer + module Protocol + module Interface + # + # Inline value options used during static or dynamic registration. + # + class InlineValueRegistrationOptions + def initialize(work_done_progress: nil, document_selector:, id: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:documentSelector] = document_selector + @attributes[:id] = id if id + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # + # The id used to register the request. The id can be used to deregister + # the request again. See also Registration#id. + # + # @return [string] + def id + attributes.fetch(:id) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_text.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_text.rb new file mode 100644 index 00000000..3afcfae9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_text.rb @@ -0,0 +1,45 @@ +module LanguageServer + module Protocol + module Interface + # + # Provide inline value as text. + # + class InlineValueText + def initialize(range:, text:) + @attributes = {} + + @attributes[:range] = range + @attributes[:text] = text + + @attributes.freeze + end + + # + # The document range for which the inline value applies. + # + # @return [Range] + def range + attributes.fetch(:range) + end + + # + # The text of the inline value. + # + # @return [string] + def text + attributes.fetch(:text) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_variable_lookup.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_variable_lookup.rb new file mode 100644 index 00000000..11638264 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_variable_lookup.rb @@ -0,0 +1,61 @@ +module LanguageServer + module Protocol + module Interface + # + # Provide inline value through a variable lookup. + # + # If only a range is specified, the variable name will be extracted from + # the underlying document. + # + # An optional variable name can be used to override the extracted name. + # + class InlineValueVariableLookup + def initialize(range:, variable_name: nil, case_sensitive_lookup:) + @attributes = {} + + @attributes[:range] = range + @attributes[:variableName] = variable_name if variable_name + @attributes[:caseSensitiveLookup] = case_sensitive_lookup + + @attributes.freeze + end + + # + # The document range for which the inline value applies. + # The range is used to extract the variable name from the underlying + # document. + # + # @return [Range] + def range + attributes.fetch(:range) + end + + # + # If specified the name of the variable to look up. + # + # @return [string] + def variable_name + attributes.fetch(:variableName) + end + + # + # How to perform the lookup. + # + # @return [boolean] + def case_sensitive_lookup + attributes.fetch(:caseSensitiveLookup) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_workspace_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_workspace_client_capabilities.rb new file mode 100644 index 00000000..9a6def7b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/inline_value_workspace_client_capabilities.rb @@ -0,0 +1,42 @@ +module LanguageServer + module Protocol + module Interface + # + # Client workspace capabilities specific to inline values. + # + class InlineValueWorkspaceClientCapabilities + def initialize(refresh_support: nil) + @attributes = {} + + @attributes[:refreshSupport] = refresh_support if refresh_support + + @attributes.freeze + end + + # + # Whether the client implementation supports a refresh request sent from + # the server to the client. + # + # Note that this event is global and will force the client to refresh all + # inline values currently shown. It should be used with absolute care and + # is useful for situation where a server for example detect a project wide + # change that requires such a calculation. + # + # @return [boolean] + def refresh_support + attributes.fetch(:refreshSupport) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/insert_replace_edit.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/insert_replace_edit.rb new file mode 100644 index 00000000..536a2d60 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/insert_replace_edit.rb @@ -0,0 +1,54 @@ +module LanguageServer + module Protocol + module Interface + # + # A special text edit to provide an insert and a replace operation. + # + class InsertReplaceEdit + def initialize(new_text:, insert:, replace:) + @attributes = {} + + @attributes[:newText] = new_text + @attributes[:insert] = insert + @attributes[:replace] = replace + + @attributes.freeze + end + + # + # The string to be inserted. + # + # @return [string] + def new_text + attributes.fetch(:newText) + end + + # + # The range if the insert is requested + # + # @return [Range] + def insert + attributes.fetch(:insert) + end + + # + # The range if the replace is requested. + # + # @return [Range] + def replace + attributes.fetch(:replace) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/linked_editing_range_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/linked_editing_range_client_capabilities.rb new file mode 100644 index 00000000..277c59f4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/linked_editing_range_client_capabilities.rb @@ -0,0 +1,36 @@ +module LanguageServer + module Protocol + module Interface + class LinkedEditingRangeClientCapabilities + def initialize(dynamic_registration: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + + @attributes.freeze + end + + # + # Whether the implementation supports dynamic registration. + # If this is set to `true` the client supports the new + # `(TextDocumentRegistrationOptions & StaticRegistrationOptions)` + # return value for the corresponding server capability as well. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/linked_editing_range_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/linked_editing_range_options.rb new file mode 100644 index 00000000..873e3f73 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/linked_editing_range_options.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Interface + class LinkedEditingRangeOptions + def initialize(work_done_progress: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/linked_editing_range_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/linked_editing_range_params.rb new file mode 100644 index 00000000..b2400e72 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/linked_editing_range_params.rb @@ -0,0 +1,51 @@ +module LanguageServer + module Protocol + module Interface + class LinkedEditingRangeParams + def initialize(text_document:, position:, work_done_token: nil) + @attributes = {} + + @attributes[:textDocument] = text_document + @attributes[:position] = position + @attributes[:workDoneToken] = work_done_token if work_done_token + + @attributes.freeze + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The position inside the text document. + # + # @return [Position] + def position + attributes.fetch(:position) + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/linked_editing_range_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/linked_editing_range_registration_options.rb new file mode 100644 index 00000000..649530e2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/linked_editing_range_registration_options.rb @@ -0,0 +1,50 @@ +module LanguageServer + module Protocol + module Interface + class LinkedEditingRangeRegistrationOptions + def initialize(document_selector:, work_done_progress: nil, id: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:id] = id if id + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # The id used to register the request. The id can be used to deregister + # the request again. See also Registration#id. + # + # @return [string] + def id + attributes.fetch(:id) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/linked_editing_ranges.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/linked_editing_ranges.rb new file mode 100644 index 00000000..3336084c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/linked_editing_ranges.rb @@ -0,0 +1,46 @@ +module LanguageServer + module Protocol + module Interface + class LinkedEditingRanges + def initialize(ranges:, word_pattern: nil) + @attributes = {} + + @attributes[:ranges] = ranges + @attributes[:wordPattern] = word_pattern if word_pattern + + @attributes.freeze + end + + # + # A list of ranges that can be renamed together. The ranges must have + # identical length and contain identical text content. The ranges cannot + # overlap. + # + # @return [Range[]] + def ranges + attributes.fetch(:ranges) + end + + # + # An optional word pattern (regular expression) that describes valid + # contents for the given ranges. If no pattern is provided, the client + # configuration's word pattern will be used. + # + # @return [string] + def word_pattern + attributes.fetch(:wordPattern) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/location.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/location.rb new file mode 100644 index 00000000..d0384968 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/location.rb @@ -0,0 +1,36 @@ +module LanguageServer + module Protocol + module Interface + class Location + def initialize(uri:, range:) + @attributes = {} + + @attributes[:uri] = uri + @attributes[:range] = range + + @attributes.freeze + end + + # @return [string] + def uri + attributes.fetch(:uri) + end + + # @return [Range] + def range + attributes.fetch(:range) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/location_link.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/location_link.rb new file mode 100644 index 00000000..5298c8cd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/location_link.rb @@ -0,0 +1,68 @@ +module LanguageServer + module Protocol + module Interface + class LocationLink + def initialize(origin_selection_range: nil, target_uri:, target_range:, target_selection_range:) + @attributes = {} + + @attributes[:originSelectionRange] = origin_selection_range if origin_selection_range + @attributes[:targetUri] = target_uri + @attributes[:targetRange] = target_range + @attributes[:targetSelectionRange] = target_selection_range + + @attributes.freeze + end + + # + # Span of the origin of this link. + # + # Used as the underlined span for mouse interaction. Defaults to the word + # range at the mouse position. + # + # @return [Range] + def origin_selection_range + attributes.fetch(:originSelectionRange) + end + + # + # The target resource identifier of this link. + # + # @return [string] + def target_uri + attributes.fetch(:targetUri) + end + + # + # The full target range of this link. If the target for example is a symbol + # then target range is the range enclosing this symbol not including + # leading/trailing whitespace but everything else like comments. This + # information is typically used to highlight the range in the editor. + # + # @return [Range] + def target_range + attributes.fetch(:targetRange) + end + + # + # The range that should be selected and revealed when this link is being + # followed, e.g the name of a function. Must be contained by the + # `targetRange`. See also `DocumentSymbol#range` + # + # @return [Range] + def target_selection_range + attributes.fetch(:targetSelectionRange) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/log_message_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/log_message_params.rb new file mode 100644 index 00000000..36b9246f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/log_message_params.rb @@ -0,0 +1,42 @@ +module LanguageServer + module Protocol + module Interface + class LogMessageParams + def initialize(type:, message:) + @attributes = {} + + @attributes[:type] = type + @attributes[:message] = message + + @attributes.freeze + end + + # + # The message type. See {@link MessageType} + # + # @return [MessageType] + def type + attributes.fetch(:type) + end + + # + # The actual message + # + # @return [string] + def message + attributes.fetch(:message) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/log_trace_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/log_trace_params.rb new file mode 100644 index 00000000..b4a2d41e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/log_trace_params.rb @@ -0,0 +1,43 @@ +module LanguageServer + module Protocol + module Interface + class LogTraceParams + def initialize(message:, verbose: nil) + @attributes = {} + + @attributes[:message] = message + @attributes[:verbose] = verbose if verbose + + @attributes.freeze + end + + # + # The message to be logged. + # + # @return [string] + def message + attributes.fetch(:message) + end + + # + # Additional information that can be computed if the `trace` configuration + # is set to `'verbose'` + # + # @return [string] + def verbose + attributes.fetch(:verbose) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/markup_content.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/markup_content.rb new file mode 100644 index 00000000..3cbea0c6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/markup_content.rb @@ -0,0 +1,68 @@ +module LanguageServer + module Protocol + module Interface + # + # A `MarkupContent` literal represents a string value which content is + # interpreted base on its kind flag. Currently the protocol supports + # `plaintext` and `markdown` as markup kinds. + # + # If the kind is `markdown` then the value can contain fenced code blocks like + # in GitHub issues. + # + # Here is an example how such a string can be constructed using + # JavaScript / TypeScript: + # ```typescript + # let markdown: MarkdownContent = { + # kind: MarkupKind.Markdown, + # value: [ + # '# Header', + # 'Some text', + # '```typescript', + # 'someCode();', + # '```' + # ].join('\n') + # }; + # ``` + # + # *Please Note* that clients might sanitize the return markdown. A client could + # decide to remove HTML from the markdown to avoid script execution. + # + class MarkupContent + def initialize(kind:, value:) + @attributes = {} + + @attributes[:kind] = kind + @attributes[:value] = value + + @attributes.freeze + end + + # + # The type of the Markup + # + # @return [MarkupKind] + def kind + attributes.fetch(:kind) + end + + # + # The content itself + # + # @return [string] + def value + attributes.fetch(:value) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/message.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/message.rb new file mode 100644 index 00000000..ceffd339 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/message.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Interface + class Message + def initialize(jsonrpc:) + @attributes = {} + + @attributes[:jsonrpc] = jsonrpc + + @attributes.freeze + end + + # @return [string] + def jsonrpc + attributes.fetch(:jsonrpc) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/message_action_item.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/message_action_item.rb new file mode 100644 index 00000000..71eadc09 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/message_action_item.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + class MessageActionItem + def initialize(title:) + @attributes = {} + + @attributes[:title] = title + + @attributes.freeze + end + + # + # A short title like 'Retry', 'Open Log' etc. + # + # @return [string] + def title + attributes.fetch(:title) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/moniker.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/moniker.rb new file mode 100644 index 00000000..74940b0e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/moniker.rb @@ -0,0 +1,64 @@ +module LanguageServer + module Protocol + module Interface + # + # Moniker definition to match LSIF 0.5 moniker definition. + # + class Moniker + def initialize(scheme:, identifier:, unique:, kind: nil) + @attributes = {} + + @attributes[:scheme] = scheme + @attributes[:identifier] = identifier + @attributes[:unique] = unique + @attributes[:kind] = kind if kind + + @attributes.freeze + end + + # + # The scheme of the moniker. For example tsc or .Net + # + # @return [string] + def scheme + attributes.fetch(:scheme) + end + + # + # The identifier of the moniker. The value is opaque in LSIF however + # schema owners are allowed to define the structure if they want. + # + # @return [string] + def identifier + attributes.fetch(:identifier) + end + + # + # The scope in which the moniker is unique + # + # @return [UniquenessLevel] + def unique + attributes.fetch(:unique) + end + + # + # The moniker kind if known. + # + # @return [MonikerKind] + def kind + attributes.fetch(:kind) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/moniker_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/moniker_client_capabilities.rb new file mode 100644 index 00000000..04d12b33 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/moniker_client_capabilities.rb @@ -0,0 +1,36 @@ +module LanguageServer + module Protocol + module Interface + class MonikerClientCapabilities + def initialize(dynamic_registration: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + + @attributes.freeze + end + + # + # Whether implementation supports dynamic registration. If this is set to + # `true` the client supports the new `(TextDocumentRegistrationOptions & + # StaticRegistrationOptions)` return value for the corresponding server + # capability as well. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/moniker_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/moniker_options.rb new file mode 100644 index 00000000..5c44abd2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/moniker_options.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Interface + class MonikerOptions + def initialize(work_done_progress: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/moniker_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/moniker_params.rb new file mode 100644 index 00000000..e693abfe --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/moniker_params.rb @@ -0,0 +1,61 @@ +module LanguageServer + module Protocol + module Interface + class MonikerParams + def initialize(text_document:, position:, work_done_token: nil, partial_result_token: nil) + @attributes = {} + + @attributes[:textDocument] = text_document + @attributes[:position] = position + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + + @attributes.freeze + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The position inside the text document. + # + # @return [Position] + def position + attributes.fetch(:position) + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/moniker_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/moniker_registration_options.rb new file mode 100644 index 00000000..646df03b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/moniker_registration_options.rb @@ -0,0 +1,40 @@ +module LanguageServer + module Protocol + module Interface + class MonikerRegistrationOptions + def initialize(document_selector:, work_done_progress: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_cell.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_cell.rb new file mode 100644 index 00000000..7ea295ce --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_cell.rb @@ -0,0 +1,69 @@ +module LanguageServer + module Protocol + module Interface + # + # A notebook cell. + # + # A cell's document URI must be unique across ALL notebook + # cells and can therefore be used to uniquely identify a + # notebook cell or the cell's text document. + # + class NotebookCell + def initialize(kind:, document:, metadata: nil, execution_summary: nil) + @attributes = {} + + @attributes[:kind] = kind + @attributes[:document] = document + @attributes[:metadata] = metadata if metadata + @attributes[:executionSummary] = execution_summary if execution_summary + + @attributes.freeze + end + + # + # The cell's kind + # + # @return [any] + def kind + attributes.fetch(:kind) + end + + # + # The URI of the cell's text document + # content. + # + # @return [string] + def document + attributes.fetch(:document) + end + + # + # Additional metadata stored with the cell. + # + # @return [LSPObject] + def metadata + attributes.fetch(:metadata) + end + + # + # Additional execution summary information + # if supported by the client. + # + # @return [ExecutionSummary] + def execution_summary + attributes.fetch(:executionSummary) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_cell_array_change.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_cell_array_change.rb new file mode 100644 index 00000000..5b368659 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_cell_array_change.rb @@ -0,0 +1,55 @@ +module LanguageServer + module Protocol + module Interface + # + # A change describing how to move a `NotebookCell` + # array from state S to S'. + # + class NotebookCellArrayChange + def initialize(start:, delete_count:, cells: nil) + @attributes = {} + + @attributes[:start] = start + @attributes[:deleteCount] = delete_count + @attributes[:cells] = cells if cells + + @attributes.freeze + end + + # + # The start offset of the cell that changed. + # + # @return [number] + def start + attributes.fetch(:start) + end + + # + # The deleted cells + # + # @return [number] + def delete_count + attributes.fetch(:deleteCount) + end + + # + # The new cells, if any + # + # @return [NotebookCell[]] + def cells + attributes.fetch(:cells) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_cell_text_document_filter.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_cell_text_document_filter.rb new file mode 100644 index 00000000..31fab2c8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_cell_text_document_filter.rb @@ -0,0 +1,52 @@ +module LanguageServer + module Protocol + module Interface + # + # A notebook cell text document filter denotes a cell text + # document by different properties. + # + class NotebookCellTextDocumentFilter + def initialize(notebook:, language: nil) + @attributes = {} + + @attributes[:notebook] = notebook + @attributes[:language] = language if language + + @attributes.freeze + end + + # + # A filter that matches against the notebook + # containing the notebook cell. If a string + # value is provided it matches against the + # notebook type. '*' matches every notebook. + # + # @return [string | NotebookDocumentFilter] + def notebook + attributes.fetch(:notebook) + end + + # + # A language id like `python`. + # + # Will be matched against the language id of the + # notebook cell document. '*' matches every language. + # + # @return [string] + def language + attributes.fetch(:language) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_document.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_document.rb new file mode 100644 index 00000000..3901e09b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_document.rb @@ -0,0 +1,74 @@ +module LanguageServer + module Protocol + module Interface + # + # A notebook document. + # + class NotebookDocument + def initialize(uri:, notebook_type:, version:, metadata: nil, cells:) + @attributes = {} + + @attributes[:uri] = uri + @attributes[:notebookType] = notebook_type + @attributes[:version] = version + @attributes[:metadata] = metadata if metadata + @attributes[:cells] = cells + + @attributes.freeze + end + + # + # The notebook document's URI. + # + # @return [string] + def uri + attributes.fetch(:uri) + end + + # + # The type of the notebook. + # + # @return [string] + def notebook_type + attributes.fetch(:notebookType) + end + + # + # The version number of this document (it will increase after each + # change, including undo/redo). + # + # @return [number] + def version + attributes.fetch(:version) + end + + # + # Additional metadata stored with the notebook + # document. + # + # @return [LSPObject] + def metadata + attributes.fetch(:metadata) + end + + # + # The cells of a notebook. + # + # @return [NotebookCell[]] + def cells + attributes.fetch(:cells) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_document_change_event.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_document_change_event.rb new file mode 100644 index 00000000..10289aff --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_document_change_event.rb @@ -0,0 +1,45 @@ +module LanguageServer + module Protocol + module Interface + # + # A change event for a notebook document. + # + class NotebookDocumentChangeEvent + def initialize(metadata: nil, cells: nil) + @attributes = {} + + @attributes[:metadata] = metadata if metadata + @attributes[:cells] = cells if cells + + @attributes.freeze + end + + # + # The changed meta data if any. + # + # @return [LSPObject] + def metadata + attributes.fetch(:metadata) + end + + # + # Changes to cells + # + # @return [{ structure?: { array: NotebookCellArrayChange; didOpen?: TextDocumentItem[]; didClose?: TextDocumentIdentifier[]; }; data?: NotebookCell[]; textContent?: { ...; }[]; }] + def cells + attributes.fetch(:cells) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_document_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_document_client_capabilities.rb new file mode 100644 index 00000000..ea52f0f7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_document_client_capabilities.rb @@ -0,0 +1,36 @@ +module LanguageServer + module Protocol + module Interface + # + # Capabilities specific to the notebook document support. + # + class NotebookDocumentClientCapabilities + def initialize(synchronization:) + @attributes = {} + + @attributes[:synchronization] = synchronization + + @attributes.freeze + end + + # + # Capabilities specific to notebook document synchronization + # + # @return [NotebookDocumentSyncClientCapabilities] + def synchronization + attributes.fetch(:synchronization) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_document_filter.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_document_filter.rb new file mode 100644 index 00000000..f47975df --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_document_filter.rb @@ -0,0 +1,79 @@ +module LanguageServer + module Protocol + module Interface + # + # A notebook document filter denotes a notebook document by + # different properties. + # + class NotebookDocumentFilter + def initialize(notebook_type: nil, scheme: nil, pattern: nil) + @attributes = {} + + @attributes[:notebookType] = notebook_type if notebook_type + @attributes[:scheme] = scheme if scheme + @attributes[:pattern] = pattern if pattern + + @attributes.freeze + end + + # + # The type of the enclosing notebook. + # + # --- OR --- + # + # The type of the enclosing notebook. + # + # --- OR --- + # + # The type of the enclosing notebook. + # + # @return [string] + def notebook_type + attributes.fetch(:notebookType) + end + + # + # A Uri [scheme](#Uri.scheme), like `file` or `untitled`. + # + # --- OR --- + # + # A Uri [scheme](#Uri.scheme), like `file` or `untitled`. + # + # --- OR --- + # + # A Uri [scheme](#Uri.scheme), like `file` or `untitled`. + # + # @return [string] + def scheme + attributes.fetch(:scheme) + end + + # + # A glob pattern. + # + # --- OR --- + # + # A glob pattern. + # + # --- OR --- + # + # A glob pattern. + # + # @return [string] + def pattern + attributes.fetch(:pattern) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_document_identifier.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_document_identifier.rb new file mode 100644 index 00000000..ab7f9c48 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_document_identifier.rb @@ -0,0 +1,36 @@ +module LanguageServer + module Protocol + module Interface + # + # A literal to identify a notebook document in the client. + # + class NotebookDocumentIdentifier + def initialize(uri:) + @attributes = {} + + @attributes[:uri] = uri + + @attributes.freeze + end + + # + # The notebook document's URI. + # + # @return [string] + def uri + attributes.fetch(:uri) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_document_sync_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_document_sync_client_capabilities.rb new file mode 100644 index 00000000..758293d9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_document_sync_client_capabilities.rb @@ -0,0 +1,48 @@ +module LanguageServer + module Protocol + module Interface + # + # Notebook specific client capabilities. + # + class NotebookDocumentSyncClientCapabilities + def initialize(dynamic_registration: nil, execution_summary_support: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + @attributes[:executionSummarySupport] = execution_summary_support if execution_summary_support + + @attributes.freeze + end + + # + # Whether implementation supports dynamic registration. If this is + # set to `true` the client supports the new + # `(TextDocumentRegistrationOptions & StaticRegistrationOptions)` + # return value for the corresponding server capability as well. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + # + # The client supports sending execution summary data per cell. + # + # @return [boolean] + def execution_summary_support + attributes.fetch(:executionSummarySupport) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_document_sync_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_document_sync_options.rb new file mode 100644 index 00000000..8e8b5edd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_document_sync_options.rb @@ -0,0 +1,56 @@ +module LanguageServer + module Protocol + module Interface + # + # Options specific to a notebook plus its cells + # to be synced to the server. + # + # If a selector provides a notebook document + # filter but no cell selector all cells of a + # matching notebook document will be synced. + # + # If a selector provides no notebook document + # filter but only a cell selector all notebook + # documents that contain at least one matching + # cell will be synced. + # + class NotebookDocumentSyncOptions + def initialize(notebook_selector:, save: nil) + @attributes = {} + + @attributes[:notebookSelector] = notebook_selector + @attributes[:save] = save if save + + @attributes.freeze + end + + # + # The notebooks to be synced + # + # @return [({ notebook: string | NotebookDocumentFilter; cells?: { language: string; }[]; } | { notebook?: string | NotebookDocumentFilter; cells: { ...; }[]; })[]] + def notebook_selector + attributes.fetch(:notebookSelector) + end + + # + # Whether save notification should be forwarded to + # the server. Will only be honored if mode === `notebook`. + # + # @return [boolean] + def save + attributes.fetch(:save) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_document_sync_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_document_sync_registration_options.rb new file mode 100644 index 00000000..c9c154db --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notebook_document_sync_registration_options.rb @@ -0,0 +1,56 @@ +module LanguageServer + module Protocol + module Interface + # + # Registration options specific to a notebook. + # + class NotebookDocumentSyncRegistrationOptions + def initialize(notebook_selector:, save: nil, id: nil) + @attributes = {} + + @attributes[:notebookSelector] = notebook_selector + @attributes[:save] = save if save + @attributes[:id] = id if id + + @attributes.freeze + end + + # + # The notebooks to be synced + # + # @return [({ notebook: string | NotebookDocumentFilter; cells?: { language: string; }[]; } | { notebook?: string | NotebookDocumentFilter; cells: { ...; }[]; })[]] + def notebook_selector + attributes.fetch(:notebookSelector) + end + + # + # Whether save notification should be forwarded to + # the server. Will only be honored if mode === `notebook`. + # + # @return [boolean] + def save + attributes.fetch(:save) + end + + # + # The id used to register the request. The id can be used to deregister + # the request again. See also Registration#id. + # + # @return [string] + def id + attributes.fetch(:id) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notification_message.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notification_message.rb new file mode 100644 index 00000000..33fe4ba6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/notification_message.rb @@ -0,0 +1,48 @@ +module LanguageServer + module Protocol + module Interface + class NotificationMessage + def initialize(jsonrpc:, method:, params: nil) + @attributes = {} + + @attributes[:jsonrpc] = jsonrpc + @attributes[:method] = method + @attributes[:params] = params if params + + @attributes.freeze + end + + # @return [string] + def jsonrpc + attributes.fetch(:jsonrpc) + end + + # + # The method to be invoked. + # + # @return [string] + def method + attributes.fetch(:method) + end + + # + # The notification's params. + # + # @return [any] + def params + attributes.fetch(:params) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/optional_versioned_text_document_identifier.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/optional_versioned_text_document_identifier.rb new file mode 100644 index 00000000..7d243ed9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/optional_versioned_text_document_identifier.rb @@ -0,0 +1,50 @@ +module LanguageServer + module Protocol + module Interface + class OptionalVersionedTextDocumentIdentifier + def initialize(uri:, version:) + @attributes = {} + + @attributes[:uri] = uri + @attributes[:version] = version + + @attributes.freeze + end + + # + # The text document's URI. + # + # @return [string] + def uri + attributes.fetch(:uri) + end + + # + # The version number of this document. If an optional versioned text document + # identifier is sent from the server to the client and the file is not + # open in the editor (the server has not received an open notification + # before) the server can send `null` to indicate that the version is + # known and the content on disk is the master (as specified with document + # content ownership). + # + # The version number of a document will increase after each change, + # including undo/redo. The number doesn't need to be consecutive. + # + # @return [number] + def version + attributes.fetch(:version) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/parameter_information.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/parameter_information.rb new file mode 100644 index 00000000..78210f98 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/parameter_information.rb @@ -0,0 +1,56 @@ +module LanguageServer + module Protocol + module Interface + # + # Represents a parameter of a callable-signature. A parameter can + # have a label and a doc-comment. + # + class ParameterInformation + def initialize(label:, documentation: nil) + @attributes = {} + + @attributes[:label] = label + @attributes[:documentation] = documentation if documentation + + @attributes.freeze + end + + # + # The label of this parameter information. + # + # Either a string or an inclusive start and exclusive end offsets within + # its containing signature label. (see SignatureInformation.label). The + # offsets are based on a UTF-16 string representation as `Position` and + # `Range` does. + # + # *Note*: a label of type string should be a substring of its containing + # signature label. Its intended use case is to highlight the parameter + # label part in the `SignatureInformation.label`. + # + # @return [string | [number, number]] + def label + attributes.fetch(:label) + end + + # + # The human-readable doc-comment of this parameter. Will be shown + # in the UI but can be omitted. + # + # @return [string | MarkupContent] + def documentation + attributes.fetch(:documentation) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/partial_result_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/partial_result_params.rb new file mode 100644 index 00000000..071458d2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/partial_result_params.rb @@ -0,0 +1,34 @@ +module LanguageServer + module Protocol + module Interface + class PartialResultParams + def initialize(partial_result_token: nil) + @attributes = {} + + @attributes[:partialResultToken] = partial_result_token if partial_result_token + + @attributes.freeze + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/position.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/position.rb new file mode 100644 index 00000000..89c18b2d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/position.rb @@ -0,0 +1,46 @@ +module LanguageServer + module Protocol + module Interface + class Position + def initialize(line:, character:) + @attributes = {} + + @attributes[:line] = line + @attributes[:character] = character + + @attributes.freeze + end + + # + # Line position in a document (zero-based). + # + # @return [number] + def line + attributes.fetch(:line) + end + + # + # Character offset on a line in a document (zero-based). The meaning of this + # offset is determined by the negotiated `PositionEncodingKind`. + # + # If the character value is greater than the line length it defaults back + # to the line length. + # + # @return [number] + def character + attributes.fetch(:character) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/prepare_rename_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/prepare_rename_params.rb new file mode 100644 index 00000000..d8f23679 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/prepare_rename_params.rb @@ -0,0 +1,51 @@ +module LanguageServer + module Protocol + module Interface + class PrepareRenameParams + def initialize(text_document:, position:, work_done_token: nil) + @attributes = {} + + @attributes[:textDocument] = text_document + @attributes[:position] = position + @attributes[:workDoneToken] = work_done_token if work_done_token + + @attributes.freeze + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The position inside the text document. + # + # @return [Position] + def position + attributes.fetch(:position) + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/previous_result_id.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/previous_result_id.rb new file mode 100644 index 00000000..b20e7ece --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/previous_result_id.rb @@ -0,0 +1,46 @@ +module LanguageServer + module Protocol + module Interface + # + # A previous result id in a workspace pull request. + # + class PreviousResultId + def initialize(uri:, value:) + @attributes = {} + + @attributes[:uri] = uri + @attributes[:value] = value + + @attributes.freeze + end + + # + # The URI for which the client knows a + # result id. + # + # @return [string] + def uri + attributes.fetch(:uri) + end + + # + # The value of the previous result id. + # + # @return [string] + def value + attributes.fetch(:value) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/progress_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/progress_params.rb new file mode 100644 index 00000000..34706ae7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/progress_params.rb @@ -0,0 +1,42 @@ +module LanguageServer + module Protocol + module Interface + class ProgressParams + def initialize(token:, value:) + @attributes = {} + + @attributes[:token] = token + @attributes[:value] = value + + @attributes.freeze + end + + # + # The progress token provided by the client or server. + # + # @return [ProgressToken] + def token + attributes.fetch(:token) + end + + # + # The progress data. + # + # @return [T] + def value + attributes.fetch(:value) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/publish_diagnostics_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/publish_diagnostics_client_capabilities.rb new file mode 100644 index 00000000..d7658be4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/publish_diagnostics_client_capabilities.rb @@ -0,0 +1,73 @@ +module LanguageServer + module Protocol + module Interface + class PublishDiagnosticsClientCapabilities + def initialize(related_information: nil, tag_support: nil, version_support: nil, code_description_support: nil, data_support: nil) + @attributes = {} + + @attributes[:relatedInformation] = related_information if related_information + @attributes[:tagSupport] = tag_support if tag_support + @attributes[:versionSupport] = version_support if version_support + @attributes[:codeDescriptionSupport] = code_description_support if code_description_support + @attributes[:dataSupport] = data_support if data_support + + @attributes.freeze + end + + # + # Whether the clients accepts diagnostics with related information. + # + # @return [boolean] + def related_information + attributes.fetch(:relatedInformation) + end + + # + # Client supports the tag property to provide meta data about a diagnostic. + # Clients supporting tags have to handle unknown tags gracefully. + # + # @return [{ valueSet: DiagnosticTag[]; }] + def tag_support + attributes.fetch(:tagSupport) + end + + # + # Whether the client interprets the version property of the + # `textDocument/publishDiagnostics` notification's parameter. + # + # @return [boolean] + def version_support + attributes.fetch(:versionSupport) + end + + # + # Client supports a codeDescription property + # + # @return [boolean] + def code_description_support + attributes.fetch(:codeDescriptionSupport) + end + + # + # Whether code action supports the `data` property which is + # preserved between a `textDocument/publishDiagnostics` and + # `textDocument/codeAction` request. + # + # @return [boolean] + def data_support + attributes.fetch(:dataSupport) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/publish_diagnostics_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/publish_diagnostics_params.rb new file mode 100644 index 00000000..ab953c15 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/publish_diagnostics_params.rb @@ -0,0 +1,52 @@ +module LanguageServer + module Protocol + module Interface + class PublishDiagnosticsParams + def initialize(uri:, version: nil, diagnostics:) + @attributes = {} + + @attributes[:uri] = uri + @attributes[:version] = version if version + @attributes[:diagnostics] = diagnostics + + @attributes.freeze + end + + # + # The URI for which diagnostic information is reported. + # + # @return [string] + def uri + attributes.fetch(:uri) + end + + # + # Optional the version number of the document the diagnostics are published + # for. + # + # @return [number] + def version + attributes.fetch(:version) + end + + # + # An array of diagnostic information items. + # + # @return [Diagnostic[]] + def diagnostics + attributes.fetch(:diagnostics) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/range.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/range.rb new file mode 100644 index 00000000..679a39e8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/range.rb @@ -0,0 +1,42 @@ +module LanguageServer + module Protocol + module Interface + class Range + def initialize(start:, end:) + @attributes = {} + + @attributes[:start] = start + @attributes[:end] = binding.local_variable_get(:end) + + @attributes.freeze + end + + # + # The range's start position. + # + # @return [Position] + def start + attributes.fetch(:start) + end + + # + # The range's end position. + # + # @return [Position] + def end + attributes.fetch(:end) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/reference_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/reference_client_capabilities.rb new file mode 100644 index 00000000..f3d204c0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/reference_client_capabilities.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + class ReferenceClientCapabilities + def initialize(dynamic_registration: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + + @attributes.freeze + end + + # + # Whether references supports dynamic registration. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/reference_context.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/reference_context.rb new file mode 100644 index 00000000..9259e7b9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/reference_context.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + class ReferenceContext + def initialize(include_declaration:) + @attributes = {} + + @attributes[:includeDeclaration] = include_declaration + + @attributes.freeze + end + + # + # Include the declaration of the current symbol. + # + # @return [boolean] + def include_declaration + attributes.fetch(:includeDeclaration) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/reference_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/reference_options.rb new file mode 100644 index 00000000..97493e23 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/reference_options.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Interface + class ReferenceOptions + def initialize(work_done_progress: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/reference_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/reference_params.rb new file mode 100644 index 00000000..d549bb58 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/reference_params.rb @@ -0,0 +1,67 @@ +module LanguageServer + module Protocol + module Interface + class ReferenceParams + def initialize(text_document:, position:, work_done_token: nil, partial_result_token: nil, context:) + @attributes = {} + + @attributes[:textDocument] = text_document + @attributes[:position] = position + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + @attributes[:context] = context + + @attributes.freeze + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The position inside the text document. + # + # @return [Position] + def position + attributes.fetch(:position) + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + # @return [ReferenceContext] + def context + attributes.fetch(:context) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/reference_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/reference_registration_options.rb new file mode 100644 index 00000000..8f90106a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/reference_registration_options.rb @@ -0,0 +1,40 @@ +module LanguageServer + module Protocol + module Interface + class ReferenceRegistrationOptions + def initialize(document_selector:, work_done_progress: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/registration.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/registration.rb new file mode 100644 index 00000000..7d3e1516 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/registration.rb @@ -0,0 +1,55 @@ +module LanguageServer + module Protocol + module Interface + # + # General parameters to register for a capability. + # + class Registration + def initialize(id:, method:, register_options: nil) + @attributes = {} + + @attributes[:id] = id + @attributes[:method] = method + @attributes[:registerOptions] = register_options if register_options + + @attributes.freeze + end + + # + # The id used to register the request. The id can be used to deregister + # the request again. + # + # @return [string] + def id + attributes.fetch(:id) + end + + # + # The method / capability to register for. + # + # @return [string] + def method + attributes.fetch(:method) + end + + # + # Options necessary for the registration. + # + # @return [LSPAny] + def register_options + attributes.fetch(:registerOptions) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/registration_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/registration_params.rb new file mode 100644 index 00000000..4b4d1b65 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/registration_params.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Interface + class RegistrationParams + def initialize(registrations:) + @attributes = {} + + @attributes[:registrations] = registrations + + @attributes.freeze + end + + # @return [Registration[]] + def registrations + attributes.fetch(:registrations) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/regular_expressions_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/regular_expressions_client_capabilities.rb new file mode 100644 index 00000000..5a27f5a5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/regular_expressions_client_capabilities.rb @@ -0,0 +1,45 @@ +module LanguageServer + module Protocol + module Interface + # + # Client capabilities specific to regular expressions. + # + class RegularExpressionsClientCapabilities + def initialize(engine:, version: nil) + @attributes = {} + + @attributes[:engine] = engine + @attributes[:version] = version if version + + @attributes.freeze + end + + # + # The engine's name. + # + # @return [string] + def engine + attributes.fetch(:engine) + end + + # + # The engine's version. + # + # @return [string] + def version + attributes.fetch(:version) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/related_full_document_diagnostic_report.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/related_full_document_diagnostic_report.rb new file mode 100644 index 00000000..eb783653 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/related_full_document_diagnostic_report.rb @@ -0,0 +1,69 @@ +module LanguageServer + module Protocol + module Interface + # + # A full diagnostic report with a set of related documents. + # + class RelatedFullDocumentDiagnosticReport + def initialize(kind:, result_id: nil, items:, related_documents: nil) + @attributes = {} + + @attributes[:kind] = kind + @attributes[:resultId] = result_id if result_id + @attributes[:items] = items + @attributes[:relatedDocuments] = related_documents if related_documents + + @attributes.freeze + end + + # + # A full document diagnostic report. + # + # @return [any] + def kind + attributes.fetch(:kind) + end + + # + # An optional result id. If provided it will + # be sent on the next diagnostic request for the + # same document. + # + # @return [string] + def result_id + attributes.fetch(:resultId) + end + + # + # The actual items. + # + # @return [Diagnostic[]] + def items + attributes.fetch(:items) + end + + # + # Diagnostics of related documents. This information is useful + # in programming languages where code in a file A can generate + # diagnostics in a file B which A depends on. An example of + # such a language is C/C++ where marco definitions in a file + # a.cpp and result in errors in a header file b.hpp. + # + # @return [{ [uri: string]: FullDocumentDiagnosticReport | UnchangedDocumentDiagnosticReport; }] + def related_documents + attributes.fetch(:relatedDocuments) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/related_unchanged_document_diagnostic_report.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/related_unchanged_document_diagnostic_report.rb new file mode 100644 index 00000000..9159a154 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/related_unchanged_document_diagnostic_report.rb @@ -0,0 +1,62 @@ +module LanguageServer + module Protocol + module Interface + # + # An unchanged diagnostic report with a set of related documents. + # + class RelatedUnchangedDocumentDiagnosticReport + def initialize(kind:, result_id:, related_documents: nil) + @attributes = {} + + @attributes[:kind] = kind + @attributes[:resultId] = result_id + @attributes[:relatedDocuments] = related_documents if related_documents + + @attributes.freeze + end + + # + # A document diagnostic report indicating + # no changes to the last result. A server can + # only return `unchanged` if result ids are + # provided. + # + # @return [any] + def kind + attributes.fetch(:kind) + end + + # + # A result id which will be sent on the next + # diagnostic request for the same document. + # + # @return [string] + def result_id + attributes.fetch(:resultId) + end + + # + # Diagnostics of related documents. This information is useful + # in programming languages where code in a file A can generate + # diagnostics in a file B which A depends on. An example of + # such a language is C/C++ where marco definitions in a file + # a.cpp and result in errors in a header file b.hpp. + # + # @return [{ [uri: string]: FullDocumentDiagnosticReport | UnchangedDocumentDiagnosticReport; }] + def related_documents + attributes.fetch(:relatedDocuments) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/relative_pattern.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/relative_pattern.rb new file mode 100644 index 00000000..0993a2c1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/relative_pattern.rb @@ -0,0 +1,48 @@ +module LanguageServer + module Protocol + module Interface + # + # A relative pattern is a helper to construct glob patterns that are matched + # relatively to a base URI. The common value for a `baseUri` is a workspace + # folder root, but it can be another absolute URI as well. + # + class RelativePattern + def initialize(base_uri:, pattern:) + @attributes = {} + + @attributes[:baseUri] = base_uri + @attributes[:pattern] = pattern + + @attributes.freeze + end + + # + # A workspace folder or a base URI to which this pattern will be matched + # against relatively. + # + # @return [string | WorkspaceFolder] + def base_uri + attributes.fetch(:baseUri) + end + + # + # The actual glob pattern; + # + # @return [string] + def pattern + attributes.fetch(:pattern) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/rename_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/rename_client_capabilities.rb new file mode 100644 index 00000000..fb890d09 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/rename_client_capabilities.rb @@ -0,0 +1,69 @@ +module LanguageServer + module Protocol + module Interface + class RenameClientCapabilities + def initialize(dynamic_registration: nil, prepare_support: nil, prepare_support_default_behavior: nil, honors_change_annotations: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + @attributes[:prepareSupport] = prepare_support if prepare_support + @attributes[:prepareSupportDefaultBehavior] = prepare_support_default_behavior if prepare_support_default_behavior + @attributes[:honorsChangeAnnotations] = honors_change_annotations if honors_change_annotations + + @attributes.freeze + end + + # + # Whether rename supports dynamic registration. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + # + # Client supports testing for validity of rename operations + # before execution. + # + # @return [boolean] + def prepare_support + attributes.fetch(:prepareSupport) + end + + # + # Client supports the default behavior result + # (`{ defaultBehavior: boolean }`). + # + # The value indicates the default behavior used by the + # client. + # + # @return [1] + def prepare_support_default_behavior + attributes.fetch(:prepareSupportDefaultBehavior) + end + + # + # Whether the client honors the change annotations in + # text edits and resource operations returned via the + # rename request's workspace edit by for example presenting + # the workspace edit in the user interface and asking + # for confirmation. + # + # @return [boolean] + def honors_change_annotations + attributes.fetch(:honorsChangeAnnotations) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/rename_file.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/rename_file.rb new file mode 100644 index 00000000..e297abb7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/rename_file.rb @@ -0,0 +1,72 @@ +module LanguageServer + module Protocol + module Interface + # + # Rename file operation + # + class RenameFile + def initialize(kind:, old_uri:, new_uri:, options: nil, annotation_id: nil) + @attributes = {} + + @attributes[:kind] = kind + @attributes[:oldUri] = old_uri + @attributes[:newUri] = new_uri + @attributes[:options] = options if options + @attributes[:annotationId] = annotation_id if annotation_id + + @attributes.freeze + end + + # + # A rename + # + # @return ["rename"] + def kind + attributes.fetch(:kind) + end + + # + # The old (existing) location. + # + # @return [string] + def old_uri + attributes.fetch(:oldUri) + end + + # + # The new location. + # + # @return [string] + def new_uri + attributes.fetch(:newUri) + end + + # + # Rename options. + # + # @return [RenameFileOptions] + def options + attributes.fetch(:options) + end + + # + # An optional annotation identifier describing the operation. + # + # @return [string] + def annotation_id + attributes.fetch(:annotationId) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/rename_file_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/rename_file_options.rb new file mode 100644 index 00000000..44d9ce98 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/rename_file_options.rb @@ -0,0 +1,45 @@ +module LanguageServer + module Protocol + module Interface + # + # Rename file options + # + class RenameFileOptions + def initialize(overwrite: nil, ignore_if_exists: nil) + @attributes = {} + + @attributes[:overwrite] = overwrite if overwrite + @attributes[:ignoreIfExists] = ignore_if_exists if ignore_if_exists + + @attributes.freeze + end + + # + # Overwrite target if existing. Overwrite wins over `ignoreIfExists` + # + # @return [boolean] + def overwrite + attributes.fetch(:overwrite) + end + + # + # Ignores if target exists. + # + # @return [boolean] + def ignore_if_exists + attributes.fetch(:ignoreIfExists) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/rename_files_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/rename_files_params.rb new file mode 100644 index 00000000..e5b7f1d4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/rename_files_params.rb @@ -0,0 +1,38 @@ +module LanguageServer + module Protocol + module Interface + # + # The parameters sent in notifications/requests for user-initiated renames + # of files. + # + class RenameFilesParams + def initialize(files:) + @attributes = {} + + @attributes[:files] = files + + @attributes.freeze + end + + # + # An array of all files/folders renamed in this operation. When a folder + # is renamed, only the folder will be included, and not its children. + # + # @return [FileRename[]] + def files + attributes.fetch(:files) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/rename_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/rename_options.rb new file mode 100644 index 00000000..cbf02e47 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/rename_options.rb @@ -0,0 +1,39 @@ +module LanguageServer + module Protocol + module Interface + class RenameOptions + def initialize(work_done_progress: nil, prepare_provider: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:prepareProvider] = prepare_provider if prepare_provider + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # Renames should be checked and tested before being executed. + # + # @return [boolean] + def prepare_provider + attributes.fetch(:prepareProvider) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/rename_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/rename_params.rb new file mode 100644 index 00000000..419d1893 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/rename_params.rb @@ -0,0 +1,62 @@ +module LanguageServer + module Protocol + module Interface + class RenameParams + def initialize(text_document:, position:, work_done_token: nil, new_name:) + @attributes = {} + + @attributes[:textDocument] = text_document + @attributes[:position] = position + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:newName] = new_name + + @attributes.freeze + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The position inside the text document. + # + # @return [Position] + def position + attributes.fetch(:position) + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # The new name of the symbol. If the given name is not valid the + # request must return a [ResponseError](#ResponseError) with an + # appropriate message set. + # + # @return [string] + def new_name + attributes.fetch(:newName) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/rename_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/rename_registration_options.rb new file mode 100644 index 00000000..9bc11b80 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/rename_registration_options.rb @@ -0,0 +1,49 @@ +module LanguageServer + module Protocol + module Interface + class RenameRegistrationOptions + def initialize(document_selector:, work_done_progress: nil, prepare_provider: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:prepareProvider] = prepare_provider if prepare_provider + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # Renames should be checked and tested before being executed. + # + # @return [boolean] + def prepare_provider + attributes.fetch(:prepareProvider) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/request_message.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/request_message.rb new file mode 100644 index 00000000..c2bb99b1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/request_message.rb @@ -0,0 +1,57 @@ +module LanguageServer + module Protocol + module Interface + class RequestMessage + def initialize(jsonrpc:, id:, method:, params: nil) + @attributes = {} + + @attributes[:jsonrpc] = jsonrpc + @attributes[:id] = id + @attributes[:method] = method + @attributes[:params] = params if params + + @attributes.freeze + end + + # @return [string] + def jsonrpc + attributes.fetch(:jsonrpc) + end + + # + # The request id. + # + # @return [string | number] + def id + attributes.fetch(:id) + end + + # + # The method to be invoked. + # + # @return [string] + def method + attributes.fetch(:method) + end + + # + # The method's params. + # + # @return [any] + def params + attributes.fetch(:params) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/response_error.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/response_error.rb new file mode 100644 index 00000000..4efdf36a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/response_error.rb @@ -0,0 +1,52 @@ +module LanguageServer + module Protocol + module Interface + class ResponseError + def initialize(code:, message:, data: nil) + @attributes = {} + + @attributes[:code] = code + @attributes[:message] = message + @attributes[:data] = data if data + + @attributes.freeze + end + + # + # A number indicating the error type that occurred. + # + # @return [number] + def code + attributes.fetch(:code) + end + + # + # A string providing a short description of the error. + # + # @return [string] + def message + attributes.fetch(:message) + end + + # + # A primitive or structured value that contains additional + # information about the error. Can be omitted. + # + # @return [any] + def data + attributes.fetch(:data) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/response_message.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/response_message.rb new file mode 100644 index 00000000..98dcceea --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/response_message.rb @@ -0,0 +1,58 @@ +module LanguageServer + module Protocol + module Interface + class ResponseMessage + def initialize(jsonrpc:, id:, result: nil, error: nil) + @attributes = {} + + @attributes[:jsonrpc] = jsonrpc + @attributes[:id] = id + @attributes[:result] = result if result + @attributes[:error] = error if error + + @attributes.freeze + end + + # @return [string] + def jsonrpc + attributes.fetch(:jsonrpc) + end + + # + # The request id. + # + # @return [string | number] + def id + attributes.fetch(:id) + end + + # + # The result of a request. This member is REQUIRED on success. + # This member MUST NOT exist if there was an error invoking the method. + # + # @return [string | number | boolean | object] + def result + attributes.fetch(:result) + end + + # + # The error object in case a request fails. + # + # @return [ResponseError] + def error + attributes.fetch(:error) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/save_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/save_options.rb new file mode 100644 index 00000000..1de39cf3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/save_options.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + class SaveOptions + def initialize(include_text: nil) + @attributes = {} + + @attributes[:includeText] = include_text if include_text + + @attributes.freeze + end + + # + # The client is supposed to include the content on save. + # + # @return [boolean] + def include_text + attributes.fetch(:includeText) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/selection_range.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/selection_range.rb new file mode 100644 index 00000000..156a2c7c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/selection_range.rb @@ -0,0 +1,43 @@ +module LanguageServer + module Protocol + module Interface + class SelectionRange + def initialize(range:, parent: nil) + @attributes = {} + + @attributes[:range] = range + @attributes[:parent] = parent if parent + + @attributes.freeze + end + + # + # The [range](#Range) of this selection range. + # + # @return [Range] + def range + attributes.fetch(:range) + end + + # + # The parent selection range containing this range. Therefore + # `parent.range` must contain `this.range`. + # + # @return [SelectionRange] + def parent + attributes.fetch(:parent) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/selection_range_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/selection_range_client_capabilities.rb new file mode 100644 index 00000000..c871ff36 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/selection_range_client_capabilities.rb @@ -0,0 +1,36 @@ +module LanguageServer + module Protocol + module Interface + class SelectionRangeClientCapabilities + def initialize(dynamic_registration: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + + @attributes.freeze + end + + # + # Whether implementation supports dynamic registration for selection range + # providers. If this is set to `true` the client supports the new + # `SelectionRangeRegistrationOptions` return value for the corresponding + # server capability as well. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/selection_range_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/selection_range_options.rb new file mode 100644 index 00000000..baf5e3de --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/selection_range_options.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Interface + class SelectionRangeOptions + def initialize(work_done_progress: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/selection_range_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/selection_range_params.rb new file mode 100644 index 00000000..b9531da6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/selection_range_params.rb @@ -0,0 +1,61 @@ +module LanguageServer + module Protocol + module Interface + class SelectionRangeParams + def initialize(work_done_token: nil, partial_result_token: nil, text_document:, positions:) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + @attributes[:textDocument] = text_document + @attributes[:positions] = positions + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The positions inside the text document. + # + # @return [Position[]] + def positions + attributes.fetch(:positions) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/selection_range_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/selection_range_registration_options.rb new file mode 100644 index 00000000..8f293c07 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/selection_range_registration_options.rb @@ -0,0 +1,50 @@ +module LanguageServer + module Protocol + module Interface + class SelectionRangeRegistrationOptions + def initialize(work_done_progress: nil, document_selector:, id: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:documentSelector] = document_selector + @attributes[:id] = id if id + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # + # The id used to register the request. The id can be used to deregister + # the request again. See also Registration#id. + # + # @return [string] + def id + attributes.fetch(:id) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens.rb new file mode 100644 index 00000000..6b5456ea --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens.rb @@ -0,0 +1,45 @@ +module LanguageServer + module Protocol + module Interface + class SemanticTokens + def initialize(result_id: nil, data:) + @attributes = {} + + @attributes[:resultId] = result_id if result_id + @attributes[:data] = data + + @attributes.freeze + end + + # + # An optional result id. If provided and clients support delta updating + # the client will include the result id in the next semantic token request. + # A server can then instead of computing all semantic tokens again simply + # send a delta. + # + # @return [string] + def result_id + attributes.fetch(:resultId) + end + + # + # The actual tokens. + # + # @return [number[]] + def data + attributes.fetch(:data) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_client_capabilities.rb new file mode 100644 index 00000000..9c32b556 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_client_capabilities.rb @@ -0,0 +1,125 @@ +module LanguageServer + module Protocol + module Interface + class SemanticTokensClientCapabilities + def initialize(dynamic_registration: nil, requests:, token_types:, token_modifiers:, formats:, overlapping_token_support: nil, multiline_token_support: nil, server_cancel_support: nil, augments_syntax_tokens: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + @attributes[:requests] = requests + @attributes[:tokenTypes] = token_types + @attributes[:tokenModifiers] = token_modifiers + @attributes[:formats] = formats + @attributes[:overlappingTokenSupport] = overlapping_token_support if overlapping_token_support + @attributes[:multilineTokenSupport] = multiline_token_support if multiline_token_support + @attributes[:serverCancelSupport] = server_cancel_support if server_cancel_support + @attributes[:augmentsSyntaxTokens] = augments_syntax_tokens if augments_syntax_tokens + + @attributes.freeze + end + + # + # Whether implementation supports dynamic registration. If this is set to + # `true` the client supports the new `(TextDocumentRegistrationOptions & + # StaticRegistrationOptions)` return value for the corresponding server + # capability as well. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + # + # Which requests the client supports and might send to the server + # depending on the server's capability. Please note that clients might not + # show semantic tokens or degrade some of the user experience if a range + # or full request is advertised by the client but not provided by the + # server. If for example the client capability `requests.full` and + # `request.range` are both set to true but the server only provides a + # range provider the client might not render a minimap correctly or might + # even decide to not show any semantic tokens at all. + # + # @return [{ range?: boolean | {}; full?: boolean | { delta?: boolean; }; }] + def requests + attributes.fetch(:requests) + end + + # + # The token types that the client supports. + # + # @return [string[]] + def token_types + attributes.fetch(:tokenTypes) + end + + # + # The token modifiers that the client supports. + # + # @return [string[]] + def token_modifiers + attributes.fetch(:tokenModifiers) + end + + # + # The formats the clients supports. + # + # @return ["relative"[]] + def formats + attributes.fetch(:formats) + end + + # + # Whether the client supports tokens that can overlap each other. + # + # @return [boolean] + def overlapping_token_support + attributes.fetch(:overlappingTokenSupport) + end + + # + # Whether the client supports tokens that can span multiple lines. + # + # @return [boolean] + def multiline_token_support + attributes.fetch(:multilineTokenSupport) + end + + # + # Whether the client allows the server to actively cancel a + # semantic token request, e.g. supports returning + # ErrorCodes.ServerCancelled. If a server does the client + # needs to retrigger the request. + # + # @return [boolean] + def server_cancel_support + attributes.fetch(:serverCancelSupport) + end + + # + # Whether the client uses semantic tokens to augment existing + # syntax tokens. If set to `true` client side created syntax + # tokens and semantic tokens are both used for colorization. If + # set to `false` the client only uses the returned semantic tokens + # for colorization. + # + # If the value is `undefined` then the client behavior is not + # specified. + # + # @return [boolean] + def augments_syntax_tokens + attributes.fetch(:augmentsSyntaxTokens) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_delta.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_delta.rb new file mode 100644 index 00000000..95003e5a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_delta.rb @@ -0,0 +1,40 @@ +module LanguageServer + module Protocol + module Interface + class SemanticTokensDelta + def initialize(result_id: nil, edits:) + @attributes = {} + + @attributes[:resultId] = result_id if result_id + @attributes[:edits] = edits + + @attributes.freeze + end + + # @return [string] + def result_id + attributes.fetch(:resultId) + end + + # + # The semantic token edits to transform a previous result into a new + # result. + # + # @return [SemanticTokensEdit[]] + def edits + attributes.fetch(:edits) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_delta_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_delta_params.rb new file mode 100644 index 00000000..7a3c26d0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_delta_params.rb @@ -0,0 +1,62 @@ +module LanguageServer + module Protocol + module Interface + class SemanticTokensDeltaParams + def initialize(work_done_token: nil, partial_result_token: nil, text_document:, previous_result_id:) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + @attributes[:textDocument] = text_document + @attributes[:previousResultId] = previous_result_id + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The result id of a previous response. The result Id can either point to + # a full response or a delta response depending on what was received last. + # + # @return [string] + def previous_result_id + attributes.fetch(:previousResultId) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_delta_partial_result.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_delta_partial_result.rb new file mode 100644 index 00000000..2bd5a43d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_delta_partial_result.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Interface + class SemanticTokensDeltaPartialResult + def initialize(edits:) + @attributes = {} + + @attributes[:edits] = edits + + @attributes.freeze + end + + # @return [SemanticTokensEdit[]] + def edits + attributes.fetch(:edits) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_edit.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_edit.rb new file mode 100644 index 00000000..c8e449e8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_edit.rb @@ -0,0 +1,51 @@ +module LanguageServer + module Protocol + module Interface + class SemanticTokensEdit + def initialize(start:, delete_count:, data: nil) + @attributes = {} + + @attributes[:start] = start + @attributes[:deleteCount] = delete_count + @attributes[:data] = data if data + + @attributes.freeze + end + + # + # The start offset of the edit. + # + # @return [number] + def start + attributes.fetch(:start) + end + + # + # The count of elements to remove. + # + # @return [number] + def delete_count + attributes.fetch(:deleteCount) + end + + # + # The elements to insert. + # + # @return [number[]] + def data + attributes.fetch(:data) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_legend.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_legend.rb new file mode 100644 index 00000000..0d70a1b2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_legend.rb @@ -0,0 +1,42 @@ +module LanguageServer + module Protocol + module Interface + class SemanticTokensLegend + def initialize(token_types:, token_modifiers:) + @attributes = {} + + @attributes[:tokenTypes] = token_types + @attributes[:tokenModifiers] = token_modifiers + + @attributes.freeze + end + + # + # The token types a server uses. + # + # @return [string[]] + def token_types + attributes.fetch(:tokenTypes) + end + + # + # The token modifiers a server uses. + # + # @return [string[]] + def token_modifiers + attributes.fetch(:tokenModifiers) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_options.rb new file mode 100644 index 00000000..afa70c77 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_options.rb @@ -0,0 +1,58 @@ +module LanguageServer + module Protocol + module Interface + class SemanticTokensOptions + def initialize(work_done_progress: nil, legend:, range: nil, full: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:legend] = legend + @attributes[:range] = range if range + @attributes[:full] = full if full + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # The legend used by the server + # + # @return [SemanticTokensLegend] + def legend + attributes.fetch(:legend) + end + + # + # Server supports providing semantic tokens for a specific range + # of a document. + # + # @return [boolean | {}] + def range + attributes.fetch(:range) + end + + # + # Server supports providing semantic tokens for a full document. + # + # @return [boolean | { delta?: boolean; }] + def full + attributes.fetch(:full) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_params.rb new file mode 100644 index 00000000..ab4d862a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_params.rb @@ -0,0 +1,52 @@ +module LanguageServer + module Protocol + module Interface + class SemanticTokensParams + def initialize(work_done_token: nil, partial_result_token: nil, text_document:) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + @attributes[:textDocument] = text_document + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_partial_result.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_partial_result.rb new file mode 100644 index 00000000..b5132fd5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_partial_result.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Interface + class SemanticTokensPartialResult + def initialize(data:) + @attributes = {} + + @attributes[:data] = data + + @attributes.freeze + end + + # @return [number[]] + def data + attributes.fetch(:data) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_range_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_range_params.rb new file mode 100644 index 00000000..82c04a5f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_range_params.rb @@ -0,0 +1,61 @@ +module LanguageServer + module Protocol + module Interface + class SemanticTokensRangeParams + def initialize(work_done_token: nil, partial_result_token: nil, text_document:, range:) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + @attributes[:textDocument] = text_document + @attributes[:range] = range + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The range the semantic tokens are requested for. + # + # @return [Range] + def range + attributes.fetch(:range) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_registration_options.rb new file mode 100644 index 00000000..ea47203b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_registration_options.rb @@ -0,0 +1,78 @@ +module LanguageServer + module Protocol + module Interface + class SemanticTokensRegistrationOptions + def initialize(document_selector:, work_done_progress: nil, legend:, range: nil, full: nil, id: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:legend] = legend + @attributes[:range] = range if range + @attributes[:full] = full if full + @attributes[:id] = id if id + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # The legend used by the server + # + # @return [SemanticTokensLegend] + def legend + attributes.fetch(:legend) + end + + # + # Server supports providing semantic tokens for a specific range + # of a document. + # + # @return [boolean | {}] + def range + attributes.fetch(:range) + end + + # + # Server supports providing semantic tokens for a full document. + # + # @return [boolean | { delta?: boolean; }] + def full + attributes.fetch(:full) + end + + # + # The id used to register the request. The id can be used to deregister + # the request again. See also Registration#id. + # + # @return [string] + def id + attributes.fetch(:id) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_workspace_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_workspace_client_capabilities.rb new file mode 100644 index 00000000..86559d07 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/semantic_tokens_workspace_client_capabilities.rb @@ -0,0 +1,39 @@ +module LanguageServer + module Protocol + module Interface + class SemanticTokensWorkspaceClientCapabilities + def initialize(refresh_support: nil) + @attributes = {} + + @attributes[:refreshSupport] = refresh_support if refresh_support + + @attributes.freeze + end + + # + # Whether the client implementation supports a refresh request sent from + # the server to the client. + # + # Note that this event is global and will force the client to refresh all + # semantic tokens currently shown. It should be used with absolute care + # and is useful for situation where a server for example detect a project + # wide change that requires such a calculation. + # + # @return [boolean] + def refresh_support + attributes.fetch(:refreshSupport) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/server_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/server_capabilities.rb new file mode 100644 index 00000000..893be388 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/server_capabilities.rb @@ -0,0 +1,352 @@ +module LanguageServer + module Protocol + module Interface + class ServerCapabilities + def initialize(position_encoding: nil, text_document_sync: nil, notebook_document_sync: nil, completion_provider: nil, hover_provider: nil, signature_help_provider: nil, declaration_provider: nil, definition_provider: nil, type_definition_provider: nil, implementation_provider: nil, references_provider: nil, document_highlight_provider: nil, document_symbol_provider: nil, code_action_provider: nil, code_lens_provider: nil, document_link_provider: nil, color_provider: nil, document_formatting_provider: nil, document_range_formatting_provider: nil, document_on_type_formatting_provider: nil, rename_provider: nil, folding_range_provider: nil, execute_command_provider: nil, selection_range_provider: nil, linked_editing_range_provider: nil, call_hierarchy_provider: nil, semantic_tokens_provider: nil, moniker_provider: nil, type_hierarchy_provider: nil, inline_value_provider: nil, inlay_hint_provider: nil, diagnostic_provider: nil, workspace_symbol_provider: nil, workspace: nil, experimental: nil) + @attributes = {} + + @attributes[:positionEncoding] = position_encoding if position_encoding + @attributes[:textDocumentSync] = text_document_sync if text_document_sync + @attributes[:notebookDocumentSync] = notebook_document_sync if notebook_document_sync + @attributes[:completionProvider] = completion_provider if completion_provider + @attributes[:hoverProvider] = hover_provider if hover_provider + @attributes[:signatureHelpProvider] = signature_help_provider if signature_help_provider + @attributes[:declarationProvider] = declaration_provider if declaration_provider + @attributes[:definitionProvider] = definition_provider if definition_provider + @attributes[:typeDefinitionProvider] = type_definition_provider if type_definition_provider + @attributes[:implementationProvider] = implementation_provider if implementation_provider + @attributes[:referencesProvider] = references_provider if references_provider + @attributes[:documentHighlightProvider] = document_highlight_provider if document_highlight_provider + @attributes[:documentSymbolProvider] = document_symbol_provider if document_symbol_provider + @attributes[:codeActionProvider] = code_action_provider if code_action_provider + @attributes[:codeLensProvider] = code_lens_provider if code_lens_provider + @attributes[:documentLinkProvider] = document_link_provider if document_link_provider + @attributes[:colorProvider] = color_provider if color_provider + @attributes[:documentFormattingProvider] = document_formatting_provider if document_formatting_provider + @attributes[:documentRangeFormattingProvider] = document_range_formatting_provider if document_range_formatting_provider + @attributes[:documentOnTypeFormattingProvider] = document_on_type_formatting_provider if document_on_type_formatting_provider + @attributes[:renameProvider] = rename_provider if rename_provider + @attributes[:foldingRangeProvider] = folding_range_provider if folding_range_provider + @attributes[:executeCommandProvider] = execute_command_provider if execute_command_provider + @attributes[:selectionRangeProvider] = selection_range_provider if selection_range_provider + @attributes[:linkedEditingRangeProvider] = linked_editing_range_provider if linked_editing_range_provider + @attributes[:callHierarchyProvider] = call_hierarchy_provider if call_hierarchy_provider + @attributes[:semanticTokensProvider] = semantic_tokens_provider if semantic_tokens_provider + @attributes[:monikerProvider] = moniker_provider if moniker_provider + @attributes[:typeHierarchyProvider] = type_hierarchy_provider if type_hierarchy_provider + @attributes[:inlineValueProvider] = inline_value_provider if inline_value_provider + @attributes[:inlayHintProvider] = inlay_hint_provider if inlay_hint_provider + @attributes[:diagnosticProvider] = diagnostic_provider if diagnostic_provider + @attributes[:workspaceSymbolProvider] = workspace_symbol_provider if workspace_symbol_provider + @attributes[:workspace] = workspace if workspace + @attributes[:experimental] = experimental if experimental + + @attributes.freeze + end + + # + # The position encoding the server picked from the encodings offered + # by the client via the client capability `general.positionEncodings`. + # + # If the client didn't provide any position encodings the only valid + # value that a server can return is 'utf-16'. + # + # If omitted it defaults to 'utf-16'. + # + # @return [string] + def position_encoding + attributes.fetch(:positionEncoding) + end + + # + # Defines how text documents are synced. Is either a detailed structure + # defining each notification or for backwards compatibility the + # TextDocumentSyncKind number. If omitted it defaults to + # `TextDocumentSyncKind.None`. + # + # @return [TextDocumentSyncOptions | TextDocumentSyncKind] + def text_document_sync + attributes.fetch(:textDocumentSync) + end + + # + # Defines how notebook documents are synced. + # + # @return [NotebookDocumentSyncOptions | NotebookDocumentSyncRegistrationOptions] + def notebook_document_sync + attributes.fetch(:notebookDocumentSync) + end + + # + # The server provides completion support. + # + # @return [CompletionOptions] + def completion_provider + attributes.fetch(:completionProvider) + end + + # + # The server provides hover support. + # + # @return [boolean | HoverOptions] + def hover_provider + attributes.fetch(:hoverProvider) + end + + # + # The server provides signature help support. + # + # @return [SignatureHelpOptions] + def signature_help_provider + attributes.fetch(:signatureHelpProvider) + end + + # + # The server provides go to declaration support. + # + # @return [boolean | DeclarationOptions | DeclarationRegistrationOptions] + def declaration_provider + attributes.fetch(:declarationProvider) + end + + # + # The server provides goto definition support. + # + # @return [boolean | DefinitionOptions] + def definition_provider + attributes.fetch(:definitionProvider) + end + + # + # The server provides goto type definition support. + # + # @return [boolean | TypeDefinitionOptions | TypeDefinitionRegistrationOptions] + def type_definition_provider + attributes.fetch(:typeDefinitionProvider) + end + + # + # The server provides goto implementation support. + # + # @return [boolean | ImplementationOptions | ImplementationRegistrationOptions] + def implementation_provider + attributes.fetch(:implementationProvider) + end + + # + # The server provides find references support. + # + # @return [boolean | ReferenceOptions] + def references_provider + attributes.fetch(:referencesProvider) + end + + # + # The server provides document highlight support. + # + # @return [boolean | DocumentHighlightOptions] + def document_highlight_provider + attributes.fetch(:documentHighlightProvider) + end + + # + # The server provides document symbol support. + # + # @return [boolean | DocumentSymbolOptions] + def document_symbol_provider + attributes.fetch(:documentSymbolProvider) + end + + # + # The server provides code actions. The `CodeActionOptions` return type is + # only valid if the client signals code action literal support via the + # property `textDocument.codeAction.codeActionLiteralSupport`. + # + # @return [boolean | CodeActionOptions] + def code_action_provider + attributes.fetch(:codeActionProvider) + end + + # + # The server provides code lens. + # + # @return [CodeLensOptions] + def code_lens_provider + attributes.fetch(:codeLensProvider) + end + + # + # The server provides document link support. + # + # @return [DocumentLinkOptions] + def document_link_provider + attributes.fetch(:documentLinkProvider) + end + + # + # The server provides color provider support. + # + # @return [boolean | DocumentColorOptions | DocumentColorRegistrationOptions] + def color_provider + attributes.fetch(:colorProvider) + end + + # + # The server provides document formatting. + # + # @return [boolean | DocumentFormattingOptions] + def document_formatting_provider + attributes.fetch(:documentFormattingProvider) + end + + # + # The server provides document range formatting. + # + # @return [boolean | DocumentRangeFormattingOptions] + def document_range_formatting_provider + attributes.fetch(:documentRangeFormattingProvider) + end + + # + # The server provides document formatting on typing. + # + # @return [DocumentOnTypeFormattingOptions] + def document_on_type_formatting_provider + attributes.fetch(:documentOnTypeFormattingProvider) + end + + # + # The server provides rename support. RenameOptions may only be + # specified if the client states that it supports + # `prepareSupport` in its initial `initialize` request. + # + # @return [boolean | RenameOptions] + def rename_provider + attributes.fetch(:renameProvider) + end + + # + # The server provides folding provider support. + # + # @return [boolean | FoldingRangeOptions | FoldingRangeRegistrationOptions] + def folding_range_provider + attributes.fetch(:foldingRangeProvider) + end + + # + # The server provides execute command support. + # + # @return [ExecuteCommandOptions] + def execute_command_provider + attributes.fetch(:executeCommandProvider) + end + + # + # The server provides selection range support. + # + # @return [boolean | SelectionRangeOptions | SelectionRangeRegistrationOptions] + def selection_range_provider + attributes.fetch(:selectionRangeProvider) + end + + # + # The server provides linked editing range support. + # + # @return [boolean | LinkedEditingRangeOptions | LinkedEditingRangeRegistrationOptions] + def linked_editing_range_provider + attributes.fetch(:linkedEditingRangeProvider) + end + + # + # The server provides call hierarchy support. + # + # @return [boolean | CallHierarchyOptions | CallHierarchyRegistrationOptions] + def call_hierarchy_provider + attributes.fetch(:callHierarchyProvider) + end + + # + # The server provides semantic tokens support. + # + # @return [SemanticTokensOptions | SemanticTokensRegistrationOptions] + def semantic_tokens_provider + attributes.fetch(:semanticTokensProvider) + end + + # + # Whether server provides moniker support. + # + # @return [boolean | MonikerOptions | MonikerRegistrationOptions] + def moniker_provider + attributes.fetch(:monikerProvider) + end + + # + # The server provides type hierarchy support. + # + # @return [boolean | TypeHierarchyOptions | TypeHierarchyRegistrationOptions] + def type_hierarchy_provider + attributes.fetch(:typeHierarchyProvider) + end + + # + # The server provides inline values. + # + # @return [boolean | InlineValueOptions | InlineValueRegistrationOptions] + def inline_value_provider + attributes.fetch(:inlineValueProvider) + end + + # + # The server provides inlay hints. + # + # @return [boolean | InlayHintOptions | InlayHintRegistrationOptions] + def inlay_hint_provider + attributes.fetch(:inlayHintProvider) + end + + # + # The server has support for pull model diagnostics. + # + # @return [DiagnosticOptions | DiagnosticRegistrationOptions] + def diagnostic_provider + attributes.fetch(:diagnosticProvider) + end + + # + # The server provides workspace symbol support. + # + # @return [boolean | WorkspaceSymbolOptions] + def workspace_symbol_provider + attributes.fetch(:workspaceSymbolProvider) + end + + # + # Workspace specific server capabilities + # + # @return [{ workspaceFolders?: WorkspaceFoldersServerCapabilities; fileOperations?: { didCreate?: FileOperationRegistrationOptions; ... 4 more ...; willDelete?: FileOperationRegistrationOptions; }; }] + def workspace + attributes.fetch(:workspace) + end + + # + # Experimental server capabilities. + # + # @return [LSPAny] + def experimental + attributes.fetch(:experimental) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/set_trace_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/set_trace_params.rb new file mode 100644 index 00000000..5e7ec770 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/set_trace_params.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + class SetTraceParams + def initialize(value:) + @attributes = {} + + @attributes[:value] = value + + @attributes.freeze + end + + # + # The new value that should be assigned to the trace setting. + # + # @return [TraceValue] + def value + attributes.fetch(:value) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/show_document_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/show_document_client_capabilities.rb new file mode 100644 index 00000000..7632df0c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/show_document_client_capabilities.rb @@ -0,0 +1,37 @@ +module LanguageServer + module Protocol + module Interface + # + # Client capabilities for the show document request. + # + class ShowDocumentClientCapabilities + def initialize(support:) + @attributes = {} + + @attributes[:support] = support + + @attributes.freeze + end + + # + # The client has support for the show document + # request. + # + # @return [boolean] + def support + attributes.fetch(:support) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/show_document_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/show_document_params.rb new file mode 100644 index 00000000..0d048d11 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/show_document_params.rb @@ -0,0 +1,71 @@ +module LanguageServer + module Protocol + module Interface + # + # Params to show a resource. + # + class ShowDocumentParams + def initialize(uri:, external: nil, take_focus: nil, selection: nil) + @attributes = {} + + @attributes[:uri] = uri + @attributes[:external] = external if external + @attributes[:takeFocus] = take_focus if take_focus + @attributes[:selection] = selection if selection + + @attributes.freeze + end + + # + # The uri to show. + # + # @return [string] + def uri + attributes.fetch(:uri) + end + + # + # Indicates to show the resource in an external program. + # To show, for example, `https://code.visualstudio.com/` + # in the default WEB browser set `external` to `true`. + # + # @return [boolean] + def external + attributes.fetch(:external) + end + + # + # An optional property to indicate whether the editor + # showing the document should take focus or not. + # Clients might ignore this property if an external + # program is started. + # + # @return [boolean] + def take_focus + attributes.fetch(:takeFocus) + end + + # + # An optional selection range if the document is a text + # document. Clients might ignore the property if an + # external program is started or the file is not a text + # file. + # + # @return [Range] + def selection + attributes.fetch(:selection) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/show_document_result.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/show_document_result.rb new file mode 100644 index 00000000..abe7b633 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/show_document_result.rb @@ -0,0 +1,36 @@ +module LanguageServer + module Protocol + module Interface + # + # The result of an show document request. + # + class ShowDocumentResult + def initialize(success:) + @attributes = {} + + @attributes[:success] = success + + @attributes.freeze + end + + # + # A boolean indicating if the show was successful. + # + # @return [boolean] + def success + attributes.fetch(:success) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/show_message_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/show_message_params.rb new file mode 100644 index 00000000..186474ab --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/show_message_params.rb @@ -0,0 +1,42 @@ +module LanguageServer + module Protocol + module Interface + class ShowMessageParams + def initialize(type:, message:) + @attributes = {} + + @attributes[:type] = type + @attributes[:message] = message + + @attributes.freeze + end + + # + # The message type. See {@link MessageType}. + # + # @return [MessageType] + def type + attributes.fetch(:type) + end + + # + # The actual message. + # + # @return [string] + def message + attributes.fetch(:message) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/show_message_request_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/show_message_request_client_capabilities.rb new file mode 100644 index 00000000..33adae12 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/show_message_request_client_capabilities.rb @@ -0,0 +1,36 @@ +module LanguageServer + module Protocol + module Interface + # + # Show message request client capabilities + # + class ShowMessageRequestClientCapabilities + def initialize(message_action_item: nil) + @attributes = {} + + @attributes[:messageActionItem] = message_action_item if message_action_item + + @attributes.freeze + end + + # + # Capabilities specific to the `MessageActionItem` type. + # + # @return [{ additionalPropertiesSupport?: boolean; }] + def message_action_item + attributes.fetch(:messageActionItem) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/show_message_request_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/show_message_request_params.rb new file mode 100644 index 00000000..3675ade6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/show_message_request_params.rb @@ -0,0 +1,51 @@ +module LanguageServer + module Protocol + module Interface + class ShowMessageRequestParams + def initialize(type:, message:, actions: nil) + @attributes = {} + + @attributes[:type] = type + @attributes[:message] = message + @attributes[:actions] = actions if actions + + @attributes.freeze + end + + # + # The message type. See {@link MessageType} + # + # @return [MessageType] + def type + attributes.fetch(:type) + end + + # + # The actual message + # + # @return [string] + def message + attributes.fetch(:message) + end + + # + # The message action items to present. + # + # @return [MessageActionItem[]] + def actions + attributes.fetch(:actions) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/signature_help.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/signature_help.rb new file mode 100644 index 00000000..f3f56313 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/signature_help.rb @@ -0,0 +1,71 @@ +module LanguageServer + module Protocol + module Interface + # + # Signature help represents the signature of something + # callable. There can be multiple signature but only one + # active and only one active parameter. + # + class SignatureHelp + def initialize(signatures:, active_signature: nil, active_parameter: nil) + @attributes = {} + + @attributes[:signatures] = signatures + @attributes[:activeSignature] = active_signature if active_signature + @attributes[:activeParameter] = active_parameter if active_parameter + + @attributes.freeze + end + + # + # One or more signatures. If no signatures are available the signature help + # request should return `null`. + # + # @return [SignatureInformation[]] + def signatures + attributes.fetch(:signatures) + end + + # + # The active signature. If omitted or the value lies outside the + # range of `signatures` the value defaults to zero or is ignore if + # the `SignatureHelp` as no signatures. + # + # Whenever possible implementors should make an active decision about + # the active signature and shouldn't rely on a default value. + # + # In future version of the protocol this property might become + # mandatory to better express this. + # + # @return [number] + def active_signature + attributes.fetch(:activeSignature) + end + + # + # The active parameter of the active signature. If omitted or the value + # lies outside the range of `signatures[activeSignature].parameters` + # defaults to 0 if the active signature has parameters. If + # the active signature has no parameters it is ignored. + # In future version of the protocol this property might become + # mandatory to better express the active parameter if the + # active signature does have any. + # + # @return [number] + def active_parameter + attributes.fetch(:activeParameter) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/signature_help_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/signature_help_client_capabilities.rb new file mode 100644 index 00000000..0a1c58f8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/signature_help_client_capabilities.rb @@ -0,0 +1,55 @@ +module LanguageServer + module Protocol + module Interface + class SignatureHelpClientCapabilities + def initialize(dynamic_registration: nil, signature_information: nil, context_support: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + @attributes[:signatureInformation] = signature_information if signature_information + @attributes[:contextSupport] = context_support if context_support + + @attributes.freeze + end + + # + # Whether signature help supports dynamic registration. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + # + # The client supports the following `SignatureInformation` + # specific properties. + # + # @return [{ documentationFormat?: MarkupKind[]; parameterInformation?: { labelOffsetSupport?: boolean; }; activeParameterSupport?: boolean; }] + def signature_information + attributes.fetch(:signatureInformation) + end + + # + # The client supports to send additional context information for a + # `textDocument/signatureHelp` request. A client that opts into + # contextSupport will also support the `retriggerCharacters` on + # `SignatureHelpOptions`. + # + # @return [boolean] + def context_support + attributes.fetch(:contextSupport) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/signature_help_context.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/signature_help_context.rb new file mode 100644 index 00000000..5cb0dd29 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/signature_help_context.rb @@ -0,0 +1,74 @@ +module LanguageServer + module Protocol + module Interface + # + # Additional information about the context in which a signature help request + # was triggered. + # + class SignatureHelpContext + def initialize(trigger_kind:, trigger_character: nil, is_retrigger:, active_signature_help: nil) + @attributes = {} + + @attributes[:triggerKind] = trigger_kind + @attributes[:triggerCharacter] = trigger_character if trigger_character + @attributes[:isRetrigger] = is_retrigger + @attributes[:activeSignatureHelp] = active_signature_help if active_signature_help + + @attributes.freeze + end + + # + # Action that caused signature help to be triggered. + # + # @return [SignatureHelpTriggerKind] + def trigger_kind + attributes.fetch(:triggerKind) + end + + # + # Character that caused signature help to be triggered. + # + # This is undefined when triggerKind !== + # SignatureHelpTriggerKind.TriggerCharacter + # + # @return [string] + def trigger_character + attributes.fetch(:triggerCharacter) + end + + # + # `true` if signature help was already showing when it was triggered. + # + # Retriggers occur when the signature help is already active and can be + # caused by actions such as typing a trigger character, a cursor move, or + # document content changes. + # + # @return [boolean] + def is_retrigger + attributes.fetch(:isRetrigger) + end + + # + # The currently active `SignatureHelp`. + # + # The `activeSignatureHelp` has its `SignatureHelp.activeSignature` field + # updated based on the user navigating through available signatures. + # + # @return [SignatureHelp] + def active_signature_help + attributes.fetch(:activeSignatureHelp) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/signature_help_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/signature_help_options.rb new file mode 100644 index 00000000..2a98a384 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/signature_help_options.rb @@ -0,0 +1,53 @@ +module LanguageServer + module Protocol + module Interface + class SignatureHelpOptions + def initialize(work_done_progress: nil, trigger_characters: nil, retrigger_characters: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:triggerCharacters] = trigger_characters if trigger_characters + @attributes[:retriggerCharacters] = retrigger_characters if retrigger_characters + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # The characters that trigger signature help + # automatically. + # + # @return [string[]] + def trigger_characters + attributes.fetch(:triggerCharacters) + end + + # + # List of characters that re-trigger signature help. + # + # These trigger characters are only active when signature help is already + # showing. All trigger characters are also counted as re-trigger + # characters. + # + # @return [string[]] + def retrigger_characters + attributes.fetch(:retriggerCharacters) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/signature_help_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/signature_help_params.rb new file mode 100644 index 00000000..330b141c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/signature_help_params.rb @@ -0,0 +1,62 @@ +module LanguageServer + module Protocol + module Interface + class SignatureHelpParams + def initialize(text_document:, position:, work_done_token: nil, context: nil) + @attributes = {} + + @attributes[:textDocument] = text_document + @attributes[:position] = position + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:context] = context if context + + @attributes.freeze + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The position inside the text document. + # + # @return [Position] + def position + attributes.fetch(:position) + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # The signature help context. This is only available if the client + # specifies to send this using the client capability + # `textDocument.signatureHelp.contextSupport === true` + # + # @return [SignatureHelpContext] + def context + attributes.fetch(:context) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/signature_help_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/signature_help_registration_options.rb new file mode 100644 index 00000000..70fa0573 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/signature_help_registration_options.rb @@ -0,0 +1,63 @@ +module LanguageServer + module Protocol + module Interface + class SignatureHelpRegistrationOptions + def initialize(document_selector:, work_done_progress: nil, trigger_characters: nil, retrigger_characters: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:triggerCharacters] = trigger_characters if trigger_characters + @attributes[:retriggerCharacters] = retrigger_characters if retrigger_characters + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # The characters that trigger signature help + # automatically. + # + # @return [string[]] + def trigger_characters + attributes.fetch(:triggerCharacters) + end + + # + # List of characters that re-trigger signature help. + # + # These trigger characters are only active when signature help is already + # showing. All trigger characters are also counted as re-trigger + # characters. + # + # @return [string[]] + def retrigger_characters + attributes.fetch(:retriggerCharacters) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/signature_information.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/signature_information.rb new file mode 100644 index 00000000..bde96f5e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/signature_information.rb @@ -0,0 +1,69 @@ +module LanguageServer + module Protocol + module Interface + # + # Represents the signature of something callable. A signature + # can have a label, like a function-name, a doc-comment, and + # a set of parameters. + # + class SignatureInformation + def initialize(label:, documentation: nil, parameters: nil, active_parameter: nil) + @attributes = {} + + @attributes[:label] = label + @attributes[:documentation] = documentation if documentation + @attributes[:parameters] = parameters if parameters + @attributes[:activeParameter] = active_parameter if active_parameter + + @attributes.freeze + end + + # + # The label of this signature. Will be shown in + # the UI. + # + # @return [string] + def label + attributes.fetch(:label) + end + + # + # The human-readable doc-comment of this signature. Will be shown + # in the UI but can be omitted. + # + # @return [string | MarkupContent] + def documentation + attributes.fetch(:documentation) + end + + # + # The parameters of this signature. + # + # @return [ParameterInformation[]] + def parameters + attributes.fetch(:parameters) + end + + # + # The index of the active parameter. + # + # If provided, this is used in place of `SignatureHelp.activeParameter`. + # + # @return [number] + def active_parameter + attributes.fetch(:activeParameter) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/static_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/static_registration_options.rb new file mode 100644 index 00000000..64480260 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/static_registration_options.rb @@ -0,0 +1,37 @@ +module LanguageServer + module Protocol + module Interface + # + # Static registration options to be returned in the initialize request. + # + class StaticRegistrationOptions + def initialize(id: nil) + @attributes = {} + + @attributes[:id] = id if id + + @attributes.freeze + end + + # + # The id used to register the request. The id can be used to deregister + # the request again. See also Registration#id. + # + # @return [string] + def id + attributes.fetch(:id) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/symbol_information.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/symbol_information.rb new file mode 100644 index 00000000..6b83c316 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/symbol_information.rb @@ -0,0 +1,93 @@ +module LanguageServer + module Protocol + module Interface + # + # Represents information about programming constructs like variables, classes, + # interfaces etc. + # + class SymbolInformation + def initialize(name:, kind:, tags: nil, deprecated: nil, location:, container_name: nil) + @attributes = {} + + @attributes[:name] = name + @attributes[:kind] = kind + @attributes[:tags] = tags if tags + @attributes[:deprecated] = deprecated if deprecated + @attributes[:location] = location + @attributes[:containerName] = container_name if container_name + + @attributes.freeze + end + + # + # The name of this symbol. + # + # @return [string] + def name + attributes.fetch(:name) + end + + # + # The kind of this symbol. + # + # @return [SymbolKind] + def kind + attributes.fetch(:kind) + end + + # + # Tags for this symbol. + # + # @return [1[]] + def tags + attributes.fetch(:tags) + end + + # + # Indicates if this symbol is deprecated. + # + # @return [boolean] + def deprecated + attributes.fetch(:deprecated) + end + + # + # The location of this symbol. The location's range is used by a tool + # to reveal the location in the editor. If the symbol is selected in the + # tool the range's start information is used to position the cursor. So + # the range usually spans more then the actual symbol's name and does + # normally include things like visibility modifiers. + # + # The range doesn't have to denote a node range in the sense of an abstract + # syntax tree. It can therefore not be used to re-construct a hierarchy of + # the symbols. + # + # @return [Location] + def location + attributes.fetch(:location) + end + + # + # The name of the symbol containing this symbol. This information is for + # user interface purposes (e.g. to render a qualifier in the user interface + # if necessary). It can't be used to re-infer a hierarchy for the document + # symbols. + # + # @return [string] + def container_name + attributes.fetch(:containerName) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_change_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_change_registration_options.rb new file mode 100644 index 00000000..e52e1853 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_change_registration_options.rb @@ -0,0 +1,47 @@ +module LanguageServer + module Protocol + module Interface + # + # Describe options to be used when registering for text document change events. + # + class TextDocumentChangeRegistrationOptions + def initialize(document_selector:, sync_kind:) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:syncKind] = sync_kind + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # + # How documents are synced to the server. See TextDocumentSyncKind.Full + # and TextDocumentSyncKind.Incremental. + # + # @return [TextDocumentSyncKind] + def sync_kind + attributes.fetch(:syncKind) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_client_capabilities.rb new file mode 100644 index 00000000..f44f398f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_client_capabilities.rb @@ -0,0 +1,297 @@ +module LanguageServer + module Protocol + module Interface + # + # Text document specific client capabilities. + # + class TextDocumentClientCapabilities + def initialize(synchronization: nil, completion: nil, hover: nil, signature_help: nil, declaration: nil, definition: nil, type_definition: nil, implementation: nil, references: nil, document_highlight: nil, document_symbol: nil, code_action: nil, code_lens: nil, document_link: nil, color_provider: nil, formatting: nil, range_formatting: nil, on_type_formatting: nil, rename: nil, publish_diagnostics: nil, folding_range: nil, selection_range: nil, linked_editing_range: nil, call_hierarchy: nil, semantic_tokens: nil, moniker: nil, type_hierarchy: nil, inline_value: nil, inlay_hint: nil, diagnostic: nil) + @attributes = {} + + @attributes[:synchronization] = synchronization if synchronization + @attributes[:completion] = completion if completion + @attributes[:hover] = hover if hover + @attributes[:signatureHelp] = signature_help if signature_help + @attributes[:declaration] = declaration if declaration + @attributes[:definition] = definition if definition + @attributes[:typeDefinition] = type_definition if type_definition + @attributes[:implementation] = implementation if implementation + @attributes[:references] = references if references + @attributes[:documentHighlight] = document_highlight if document_highlight + @attributes[:documentSymbol] = document_symbol if document_symbol + @attributes[:codeAction] = code_action if code_action + @attributes[:codeLens] = code_lens if code_lens + @attributes[:documentLink] = document_link if document_link + @attributes[:colorProvider] = color_provider if color_provider + @attributes[:formatting] = formatting if formatting + @attributes[:rangeFormatting] = range_formatting if range_formatting + @attributes[:onTypeFormatting] = on_type_formatting if on_type_formatting + @attributes[:rename] = rename if rename + @attributes[:publishDiagnostics] = publish_diagnostics if publish_diagnostics + @attributes[:foldingRange] = folding_range if folding_range + @attributes[:selectionRange] = selection_range if selection_range + @attributes[:linkedEditingRange] = linked_editing_range if linked_editing_range + @attributes[:callHierarchy] = call_hierarchy if call_hierarchy + @attributes[:semanticTokens] = semantic_tokens if semantic_tokens + @attributes[:moniker] = moniker if moniker + @attributes[:typeHierarchy] = type_hierarchy if type_hierarchy + @attributes[:inlineValue] = inline_value if inline_value + @attributes[:inlayHint] = inlay_hint if inlay_hint + @attributes[:diagnostic] = diagnostic if diagnostic + + @attributes.freeze + end + + # @return [TextDocumentSyncClientCapabilities] + def synchronization + attributes.fetch(:synchronization) + end + + # + # Capabilities specific to the `textDocument/completion` request. + # + # @return [CompletionClientCapabilities] + def completion + attributes.fetch(:completion) + end + + # + # Capabilities specific to the `textDocument/hover` request. + # + # @return [HoverClientCapabilities] + def hover + attributes.fetch(:hover) + end + + # + # Capabilities specific to the `textDocument/signatureHelp` request. + # + # @return [SignatureHelpClientCapabilities] + def signature_help + attributes.fetch(:signatureHelp) + end + + # + # Capabilities specific to the `textDocument/declaration` request. + # + # @return [DeclarationClientCapabilities] + def declaration + attributes.fetch(:declaration) + end + + # + # Capabilities specific to the `textDocument/definition` request. + # + # @return [DefinitionClientCapabilities] + def definition + attributes.fetch(:definition) + end + + # + # Capabilities specific to the `textDocument/typeDefinition` request. + # + # @return [TypeDefinitionClientCapabilities] + def type_definition + attributes.fetch(:typeDefinition) + end + + # + # Capabilities specific to the `textDocument/implementation` request. + # + # @return [ImplementationClientCapabilities] + def implementation + attributes.fetch(:implementation) + end + + # + # Capabilities specific to the `textDocument/references` request. + # + # @return [ReferenceClientCapabilities] + def references + attributes.fetch(:references) + end + + # + # Capabilities specific to the `textDocument/documentHighlight` request. + # + # @return [DocumentHighlightClientCapabilities] + def document_highlight + attributes.fetch(:documentHighlight) + end + + # + # Capabilities specific to the `textDocument/documentSymbol` request. + # + # @return [DocumentSymbolClientCapabilities] + def document_symbol + attributes.fetch(:documentSymbol) + end + + # + # Capabilities specific to the `textDocument/codeAction` request. + # + # @return [CodeActionClientCapabilities] + def code_action + attributes.fetch(:codeAction) + end + + # + # Capabilities specific to the `textDocument/codeLens` request. + # + # @return [CodeLensClientCapabilities] + def code_lens + attributes.fetch(:codeLens) + end + + # + # Capabilities specific to the `textDocument/documentLink` request. + # + # @return [DocumentLinkClientCapabilities] + def document_link + attributes.fetch(:documentLink) + end + + # + # Capabilities specific to the `textDocument/documentColor` and the + # `textDocument/colorPresentation` request. + # + # @return [DocumentColorClientCapabilities] + def color_provider + attributes.fetch(:colorProvider) + end + + # + # Capabilities specific to the `textDocument/formatting` request. + # + # @return [DocumentFormattingClientCapabilities] + def formatting + attributes.fetch(:formatting) + end + + # + # Capabilities specific to the `textDocument/rangeFormatting` request. + # + # @return [DocumentRangeFormattingClientCapabilities] + def range_formatting + attributes.fetch(:rangeFormatting) + end + + # + # request. + # Capabilities specific to the `textDocument/onTypeFormatting` request. + # + # @return [DocumentOnTypeFormattingClientCapabilities] + def on_type_formatting + attributes.fetch(:onTypeFormatting) + end + + # + # Capabilities specific to the `textDocument/rename` request. + # + # @return [RenameClientCapabilities] + def rename + attributes.fetch(:rename) + end + + # + # Capabilities specific to the `textDocument/publishDiagnostics` + # notification. + # + # @return [PublishDiagnosticsClientCapabilities] + def publish_diagnostics + attributes.fetch(:publishDiagnostics) + end + + # + # Capabilities specific to the `textDocument/foldingRange` request. + # + # @return [FoldingRangeClientCapabilities] + def folding_range + attributes.fetch(:foldingRange) + end + + # + # Capabilities specific to the `textDocument/selectionRange` request. + # + # @return [SelectionRangeClientCapabilities] + def selection_range + attributes.fetch(:selectionRange) + end + + # + # Capabilities specific to the `textDocument/linkedEditingRange` request. + # + # @return [LinkedEditingRangeClientCapabilities] + def linked_editing_range + attributes.fetch(:linkedEditingRange) + end + + # + # Capabilities specific to the various call hierarchy requests. + # + # @return [CallHierarchyClientCapabilities] + def call_hierarchy + attributes.fetch(:callHierarchy) + end + + # + # Capabilities specific to the various semantic token requests. + # + # @return [SemanticTokensClientCapabilities] + def semantic_tokens + attributes.fetch(:semanticTokens) + end + + # + # Capabilities specific to the `textDocument/moniker` request. + # + # @return [MonikerClientCapabilities] + def moniker + attributes.fetch(:moniker) + end + + # + # Capabilities specific to the various type hierarchy requests. + # + # @return [TypeHierarchyClientCapabilities] + def type_hierarchy + attributes.fetch(:typeHierarchy) + end + + # + # Capabilities specific to the `textDocument/inlineValue` request. + # + # @return [InlineValueClientCapabilities] + def inline_value + attributes.fetch(:inlineValue) + end + + # + # Capabilities specific to the `textDocument/inlayHint` request. + # + # @return [InlayHintClientCapabilities] + def inlay_hint + attributes.fetch(:inlayHint) + end + + # + # Capabilities specific to the diagnostic pull model. + # + # @return [DiagnosticClientCapabilities] + def diagnostic + attributes.fetch(:diagnostic) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_content_change_event.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_content_change_event.rb new file mode 100644 index 00000000..0f7c04ed --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_content_change_event.rb @@ -0,0 +1,59 @@ +module LanguageServer + module Protocol + module Interface + # + # An event describing a change to a text document. If only a text is provided + # it is considered to be the full content of the document. + # + class TextDocumentContentChangeEvent + def initialize(range: nil, range_length: nil, text:) + @attributes = {} + + @attributes[:range] = range if range + @attributes[:rangeLength] = range_length if range_length + @attributes[:text] = text + + @attributes.freeze + end + + # + # The range of the document that changed. + # + # @return [Range, nil] + def range + attributes.fetch(:range) + end + + # + # The optional length of the range that got replaced. + # + # @return [number, nil] + def range_length + attributes.fetch(:rangeLength) + end + + # + # The new text for the provided range. + # + # --- OR --- + # + # The new text of the whole document. + # + # @return [string] + def text + attributes.fetch(:text) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_edit.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_edit.rb new file mode 100644 index 00000000..efc07fe8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_edit.rb @@ -0,0 +1,42 @@ +module LanguageServer + module Protocol + module Interface + class TextDocumentEdit + def initialize(text_document:, edits:) + @attributes = {} + + @attributes[:textDocument] = text_document + @attributes[:edits] = edits + + @attributes.freeze + end + + # + # The text document to change. + # + # @return [OptionalVersionedTextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The edits to be applied. + # + # @return [(TextEdit | AnnotatedTextEdit)[]] + def edits + attributes.fetch(:edits) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_identifier.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_identifier.rb new file mode 100644 index 00000000..dfc04fa4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_identifier.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + class TextDocumentIdentifier + def initialize(uri:) + @attributes = {} + + @attributes[:uri] = uri + + @attributes.freeze + end + + # + # The text document's URI. + # + # @return [string] + def uri + attributes.fetch(:uri) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_item.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_item.rb new file mode 100644 index 00000000..3a6097ed --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_item.rb @@ -0,0 +1,61 @@ +module LanguageServer + module Protocol + module Interface + class TextDocumentItem + def initialize(uri:, language_id:, version:, text:) + @attributes = {} + + @attributes[:uri] = uri + @attributes[:languageId] = language_id + @attributes[:version] = version + @attributes[:text] = text + + @attributes.freeze + end + + # + # The text document's URI. + # + # @return [string] + def uri + attributes.fetch(:uri) + end + + # + # The text document's language identifier. + # + # @return [string] + def language_id + attributes.fetch(:languageId) + end + + # + # The version number of this document (it will increase after each + # change, including undo/redo). + # + # @return [number] + def version + attributes.fetch(:version) + end + + # + # The content of the opened text document. + # + # @return [string] + def text + attributes.fetch(:text) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_position_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_position_params.rb new file mode 100644 index 00000000..d5354c65 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_position_params.rb @@ -0,0 +1,42 @@ +module LanguageServer + module Protocol + module Interface + class TextDocumentPositionParams + def initialize(text_document:, position:) + @attributes = {} + + @attributes[:textDocument] = text_document + @attributes[:position] = position + + @attributes.freeze + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The position inside the text document. + # + # @return [Position] + def position + attributes.fetch(:position) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_registration_options.rb new file mode 100644 index 00000000..49373b7d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_registration_options.rb @@ -0,0 +1,37 @@ +module LanguageServer + module Protocol + module Interface + # + # General text document registration options. + # + class TextDocumentRegistrationOptions + def initialize(document_selector:) + @attributes = {} + + @attributes[:documentSelector] = document_selector + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_save_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_save_registration_options.rb new file mode 100644 index 00000000..cee01cf0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_save_registration_options.rb @@ -0,0 +1,43 @@ +module LanguageServer + module Protocol + module Interface + class TextDocumentSaveRegistrationOptions + def initialize(document_selector:, include_text: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:includeText] = include_text if include_text + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # + # The client is supposed to include the content on save. + # + # @return [boolean] + def include_text + attributes.fetch(:includeText) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_sync_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_sync_client_capabilities.rb new file mode 100644 index 00000000..36262b4d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_sync_client_capabilities.rb @@ -0,0 +1,62 @@ +module LanguageServer + module Protocol + module Interface + class TextDocumentSyncClientCapabilities + def initialize(dynamic_registration: nil, will_save: nil, will_save_wait_until: nil, did_save: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + @attributes[:willSave] = will_save if will_save + @attributes[:willSaveWaitUntil] = will_save_wait_until if will_save_wait_until + @attributes[:didSave] = did_save if did_save + + @attributes.freeze + end + + # + # Whether text document synchronization supports dynamic registration. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + # + # The client supports sending will save notifications. + # + # @return [boolean] + def will_save + attributes.fetch(:willSave) + end + + # + # The client supports sending a will save request and + # waits for a response providing text edits which will + # be applied to the document before it is saved. + # + # @return [boolean] + def will_save_wait_until + attributes.fetch(:willSaveWaitUntil) + end + + # + # The client supports did save notifications. + # + # @return [boolean] + def did_save + attributes.fetch(:didSave) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_sync_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_sync_options.rb new file mode 100644 index 00000000..5542d9e2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_document_sync_options.rb @@ -0,0 +1,78 @@ +module LanguageServer + module Protocol + module Interface + class TextDocumentSyncOptions + def initialize(open_close: nil, change: nil, will_save: nil, will_save_wait_until: nil, save: nil) + @attributes = {} + + @attributes[:openClose] = open_close if open_close + @attributes[:change] = change if change + @attributes[:willSave] = will_save if will_save + @attributes[:willSaveWaitUntil] = will_save_wait_until if will_save_wait_until + @attributes[:save] = save if save + + @attributes.freeze + end + + # + # Open and close notifications are sent to the server. If omitted open + # close notifications should not be sent. + # Open and close notifications are sent to the server. If omitted open + # close notification should not be sent. + # + # @return [boolean] + def open_close + attributes.fetch(:openClose) + end + + # + # Change notifications are sent to the server. See + # TextDocumentSyncKind.None, TextDocumentSyncKind.Full and + # TextDocumentSyncKind.Incremental. If omitted it defaults to + # TextDocumentSyncKind.None. + # + # @return [TextDocumentSyncKind] + def change + attributes.fetch(:change) + end + + # + # If present will save notifications are sent to the server. If omitted + # the notification should not be sent. + # + # @return [boolean] + def will_save + attributes.fetch(:willSave) + end + + # + # If present will save wait until requests are sent to the server. If + # omitted the request should not be sent. + # + # @return [boolean] + def will_save_wait_until + attributes.fetch(:willSaveWaitUntil) + end + + # + # If present save notifications are sent to the server. If omitted the + # notification should not be sent. + # + # @return [boolean | SaveOptions] + def save + attributes.fetch(:save) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_edit.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_edit.rb new file mode 100644 index 00000000..6e635364 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/text_edit.rb @@ -0,0 +1,44 @@ +module LanguageServer + module Protocol + module Interface + class TextEdit + def initialize(range:, new_text:) + @attributes = {} + + @attributes[:range] = range + @attributes[:newText] = new_text + + @attributes.freeze + end + + # + # The range of the text document to be manipulated. To insert + # text into a document create a range where start === end. + # + # @return [Range] + def range + attributes.fetch(:range) + end + + # + # The string to be inserted. For delete operations use an + # empty string. + # + # @return [string] + def new_text + attributes.fetch(:newText) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_definition_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_definition_client_capabilities.rb new file mode 100644 index 00000000..9cef1f94 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_definition_client_capabilities.rb @@ -0,0 +1,44 @@ +module LanguageServer + module Protocol + module Interface + class TypeDefinitionClientCapabilities + def initialize(dynamic_registration: nil, link_support: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + @attributes[:linkSupport] = link_support if link_support + + @attributes.freeze + end + + # + # Whether implementation supports dynamic registration. If this is set to + # `true` the client supports the new `TypeDefinitionRegistrationOptions` + # return value for the corresponding server capability as well. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + # + # The client supports additional metadata in the form of definition links. + # + # @return [boolean] + def link_support + attributes.fetch(:linkSupport) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_definition_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_definition_options.rb new file mode 100644 index 00000000..96385779 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_definition_options.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Interface + class TypeDefinitionOptions + def initialize(work_done_progress: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_definition_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_definition_params.rb new file mode 100644 index 00000000..d7baf5c8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_definition_params.rb @@ -0,0 +1,61 @@ +module LanguageServer + module Protocol + module Interface + class TypeDefinitionParams + def initialize(text_document:, position:, work_done_token: nil, partial_result_token: nil) + @attributes = {} + + @attributes[:textDocument] = text_document + @attributes[:position] = position + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + + @attributes.freeze + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The position inside the text document. + # + # @return [Position] + def position + attributes.fetch(:position) + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_definition_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_definition_registration_options.rb new file mode 100644 index 00000000..ee8f4d1b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_definition_registration_options.rb @@ -0,0 +1,50 @@ +module LanguageServer + module Protocol + module Interface + class TypeDefinitionRegistrationOptions + def initialize(document_selector:, work_done_progress: nil, id: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:id] = id if id + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # The id used to register the request. The id can be used to deregister + # the request again. See also Registration#id. + # + # @return [string] + def id + attributes.fetch(:id) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_hierarchy_item.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_hierarchy_item.rb new file mode 100644 index 00000000..e833ce66 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_hierarchy_item.rb @@ -0,0 +1,102 @@ +module LanguageServer + module Protocol + module Interface + class TypeHierarchyItem + def initialize(name:, kind:, tags: nil, detail: nil, uri:, range:, selection_range:, data: nil) + @attributes = {} + + @attributes[:name] = name + @attributes[:kind] = kind + @attributes[:tags] = tags if tags + @attributes[:detail] = detail if detail + @attributes[:uri] = uri + @attributes[:range] = range + @attributes[:selectionRange] = selection_range + @attributes[:data] = data if data + + @attributes.freeze + end + + # + # The name of this item. + # + # @return [string] + def name + attributes.fetch(:name) + end + + # + # The kind of this item. + # + # @return [SymbolKind] + def kind + attributes.fetch(:kind) + end + + # + # Tags for this item. + # + # @return [1[]] + def tags + attributes.fetch(:tags) + end + + # + # More detail for this item, e.g. the signature of a function. + # + # @return [string] + def detail + attributes.fetch(:detail) + end + + # + # The resource identifier of this item. + # + # @return [string] + def uri + attributes.fetch(:uri) + end + + # + # The range enclosing this symbol not including leading/trailing whitespace + # but everything else, e.g. comments and code. + # + # @return [Range] + def range + attributes.fetch(:range) + end + + # + # The range that should be selected and revealed when this symbol is being + # picked, e.g. the name of a function. Must be contained by the + # [`range`](#TypeHierarchyItem.range). + # + # @return [Range] + def selection_range + attributes.fetch(:selectionRange) + end + + # + # A data entry field that is preserved between a type hierarchy prepare and + # supertypes or subtypes requests. It could also be used to identify the + # type hierarchy in the server, helping improve the performance on + # resolving supertypes and subtypes. + # + # @return [LSPAny] + def data + attributes.fetch(:data) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_hierarchy_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_hierarchy_options.rb new file mode 100644 index 00000000..e29d64ab --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_hierarchy_options.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Interface + class TypeHierarchyOptions + def initialize(work_done_progress: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_hierarchy_prepare_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_hierarchy_prepare_params.rb new file mode 100644 index 00000000..696f5e49 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_hierarchy_prepare_params.rb @@ -0,0 +1,51 @@ +module LanguageServer + module Protocol + module Interface + class TypeHierarchyPrepareParams + def initialize(text_document:, position:, work_done_token: nil) + @attributes = {} + + @attributes[:textDocument] = text_document + @attributes[:position] = position + @attributes[:workDoneToken] = work_done_token if work_done_token + + @attributes.freeze + end + + # + # The text document. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The position inside the text document. + # + # @return [Position] + def position + attributes.fetch(:position) + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_hierarchy_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_hierarchy_registration_options.rb new file mode 100644 index 00000000..24e99627 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_hierarchy_registration_options.rb @@ -0,0 +1,50 @@ +module LanguageServer + module Protocol + module Interface + class TypeHierarchyRegistrationOptions + def initialize(document_selector:, work_done_progress: nil, id: nil) + @attributes = {} + + @attributes[:documentSelector] = document_selector + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:id] = id if id + + @attributes.freeze + end + + # + # A document selector to identify the scope of the registration. If set to + # null the document selector provided on the client side will be used. + # + # @return [DocumentSelector] + def document_selector + attributes.fetch(:documentSelector) + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # The id used to register the request. The id can be used to deregister + # the request again. See also Registration#id. + # + # @return [string] + def id + attributes.fetch(:id) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_hierarchy_subtypes_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_hierarchy_subtypes_params.rb new file mode 100644 index 00000000..2253cce3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_hierarchy_subtypes_params.rb @@ -0,0 +1,49 @@ +module LanguageServer + module Protocol + module Interface + class TypeHierarchySubtypesParams + def initialize(work_done_token: nil, partial_result_token: nil, item:) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + @attributes[:item] = item + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + # @return [TypeHierarchyItem] + def item + attributes.fetch(:item) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_hierarchy_supertypes_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_hierarchy_supertypes_params.rb new file mode 100644 index 00000000..05a91f09 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/type_hierarchy_supertypes_params.rb @@ -0,0 +1,49 @@ +module LanguageServer + module Protocol + module Interface + class TypeHierarchySupertypesParams + def initialize(work_done_token: nil, partial_result_token: nil, item:) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + @attributes[:item] = item + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + # @return [TypeHierarchyItem] + def item + attributes.fetch(:item) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/unchanged_document_diagnostic_report.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/unchanged_document_diagnostic_report.rb new file mode 100644 index 00000000..45e816f9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/unchanged_document_diagnostic_report.rb @@ -0,0 +1,50 @@ +module LanguageServer + module Protocol + module Interface + # + # A diagnostic report indicating that the last returned + # report is still accurate. + # + class UnchangedDocumentDiagnosticReport + def initialize(kind:, result_id:) + @attributes = {} + + @attributes[:kind] = kind + @attributes[:resultId] = result_id + + @attributes.freeze + end + + # + # A document diagnostic report indicating + # no changes to the last result. A server can + # only return `unchanged` if result ids are + # provided. + # + # @return [any] + def kind + attributes.fetch(:kind) + end + + # + # A result id which will be sent on the next + # diagnostic request for the same document. + # + # @return [string] + def result_id + attributes.fetch(:resultId) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/unregistration.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/unregistration.rb new file mode 100644 index 00000000..4dc4d5df --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/unregistration.rb @@ -0,0 +1,46 @@ +module LanguageServer + module Protocol + module Interface + # + # General parameters to unregister a capability. + # + class Unregistration + def initialize(id:, method:) + @attributes = {} + + @attributes[:id] = id + @attributes[:method] = method + + @attributes.freeze + end + + # + # The id used to unregister the request or notification. Usually an id + # provided during the register request. + # + # @return [string] + def id + attributes.fetch(:id) + end + + # + # The method / capability to unregister for. + # + # @return [string] + def method + attributes.fetch(:method) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/unregistration_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/unregistration_params.rb new file mode 100644 index 00000000..0369357f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/unregistration_params.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Interface + class UnregistrationParams + def initialize(unregisterations:) + @attributes = {} + + @attributes[:unregisterations] = unregisterations + + @attributes.freeze + end + + # @return [Unregistration[]] + def unregisterations + attributes.fetch(:unregisterations) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/versioned_notebook_document_identifier.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/versioned_notebook_document_identifier.rb new file mode 100644 index 00000000..f29e90c7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/versioned_notebook_document_identifier.rb @@ -0,0 +1,45 @@ +module LanguageServer + module Protocol + module Interface + # + # A versioned notebook document identifier. + # + class VersionedNotebookDocumentIdentifier + def initialize(version:, uri:) + @attributes = {} + + @attributes[:version] = version + @attributes[:uri] = uri + + @attributes.freeze + end + + # + # The version number of this notebook document. + # + # @return [number] + def version + attributes.fetch(:version) + end + + # + # The notebook document's URI. + # + # @return [string] + def uri + attributes.fetch(:uri) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/versioned_text_document_identifier.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/versioned_text_document_identifier.rb new file mode 100644 index 00000000..cb33f5f2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/versioned_text_document_identifier.rb @@ -0,0 +1,45 @@ +module LanguageServer + module Protocol + module Interface + class VersionedTextDocumentIdentifier + def initialize(uri:, version:) + @attributes = {} + + @attributes[:uri] = uri + @attributes[:version] = version + + @attributes.freeze + end + + # + # The text document's URI. + # + # @return [string] + def uri + attributes.fetch(:uri) + end + + # + # The version number of this document. + # + # The version number of a document will increase after each change, + # including undo/redo. The number doesn't need to be consecutive. + # + # @return [number] + def version + attributes.fetch(:version) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/will_save_text_document_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/will_save_text_document_params.rb new file mode 100644 index 00000000..2f91eaaa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/will_save_text_document_params.rb @@ -0,0 +1,45 @@ +module LanguageServer + module Protocol + module Interface + # + # The parameters send in a will save text document notification. + # + class WillSaveTextDocumentParams + def initialize(text_document:, reason:) + @attributes = {} + + @attributes[:textDocument] = text_document + @attributes[:reason] = reason + + @attributes.freeze + end + + # + # The document that will be saved. + # + # @return [TextDocumentIdentifier] + def text_document + attributes.fetch(:textDocument) + end + + # + # The 'TextDocumentSaveReason'. + # + # @return [TextDocumentSaveReason] + def reason + attributes.fetch(:reason) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/work_done_progress_begin.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/work_done_progress_begin.rb new file mode 100644 index 00000000..4f1a0bb2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/work_done_progress_begin.rb @@ -0,0 +1,80 @@ +module LanguageServer + module Protocol + module Interface + class WorkDoneProgressBegin + def initialize(kind:, title:, cancellable: nil, message: nil, percentage: nil) + @attributes = {} + + @attributes[:kind] = kind + @attributes[:title] = title + @attributes[:cancellable] = cancellable if cancellable + @attributes[:message] = message if message + @attributes[:percentage] = percentage if percentage + + @attributes.freeze + end + + # @return ["begin"] + def kind + attributes.fetch(:kind) + end + + # + # Mandatory title of the progress operation. Used to briefly inform about + # the kind of operation being performed. + # + # Examples: "Indexing" or "Linking dependencies". + # + # @return [string] + def title + attributes.fetch(:title) + end + + # + # Controls if a cancel button should show to allow the user to cancel the + # long running operation. Clients that don't support cancellation are + # allowed to ignore the setting. + # + # @return [boolean] + def cancellable + attributes.fetch(:cancellable) + end + + # + # Optional, more detailed associated progress message. Contains + # complementary information to the `title`. + # + # Examples: "3/25 files", "project/src/module2", "node_modules/some_dep". + # If unset, the previous progress message (if any) is still valid. + # + # @return [string] + def message + attributes.fetch(:message) + end + + # + # Optional progress percentage to display (value 100 is considered 100%). + # If not provided infinite progress is assumed and clients are allowed + # to ignore the `percentage` value in subsequent in report notifications. + # + # The value should be steadily rising. Clients are free to ignore values + # that are not following this rule. The value range is [0, 100] + # + # @return [number] + def percentage + attributes.fetch(:percentage) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/work_done_progress_cancel_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/work_done_progress_cancel_params.rb new file mode 100644 index 00000000..aa3be319 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/work_done_progress_cancel_params.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + class WorkDoneProgressCancelParams + def initialize(token:) + @attributes = {} + + @attributes[:token] = token + + @attributes.freeze + end + + # + # The token to be used to report progress. + # + # @return [ProgressToken] + def token + attributes.fetch(:token) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/work_done_progress_create_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/work_done_progress_create_params.rb new file mode 100644 index 00000000..76090a44 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/work_done_progress_create_params.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + class WorkDoneProgressCreateParams + def initialize(token:) + @attributes = {} + + @attributes[:token] = token + + @attributes.freeze + end + + # + # The token to be used to report progress. + # + # @return [ProgressToken] + def token + attributes.fetch(:token) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/work_done_progress_end.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/work_done_progress_end.rb new file mode 100644 index 00000000..31e53ae6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/work_done_progress_end.rb @@ -0,0 +1,40 @@ +module LanguageServer + module Protocol + module Interface + class WorkDoneProgressEnd + def initialize(kind:, message: nil) + @attributes = {} + + @attributes[:kind] = kind + @attributes[:message] = message if message + + @attributes.freeze + end + + # @return ["end"] + def kind + attributes.fetch(:kind) + end + + # + # Optional, a final message indicating to for example indicate the outcome + # of the operation. + # + # @return [string] + def message + attributes.fetch(:message) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/work_done_progress_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/work_done_progress_options.rb new file mode 100644 index 00000000..f0be0f56 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/work_done_progress_options.rb @@ -0,0 +1,30 @@ +module LanguageServer + module Protocol + module Interface + class WorkDoneProgressOptions + def initialize(work_done_progress: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/work_done_progress_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/work_done_progress_params.rb new file mode 100644 index 00000000..946daf12 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/work_done_progress_params.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + class WorkDoneProgressParams + def initialize(work_done_token: nil) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/work_done_progress_report.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/work_done_progress_report.rb new file mode 100644 index 00000000..05efbeaa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/work_done_progress_report.rb @@ -0,0 +1,70 @@ +module LanguageServer + module Protocol + module Interface + class WorkDoneProgressReport + def initialize(kind:, cancellable: nil, message: nil, percentage: nil) + @attributes = {} + + @attributes[:kind] = kind + @attributes[:cancellable] = cancellable if cancellable + @attributes[:message] = message if message + @attributes[:percentage] = percentage if percentage + + @attributes.freeze + end + + # @return ["report"] + def kind + attributes.fetch(:kind) + end + + # + # Controls enablement state of a cancel button. This property is only valid + # if a cancel button got requested in the `WorkDoneProgressBegin` payload. + # + # Clients that don't support cancellation or don't support control the + # button's enablement state are allowed to ignore the setting. + # + # @return [boolean] + def cancellable + attributes.fetch(:cancellable) + end + + # + # Optional, more detailed associated progress message. Contains + # complementary information to the `title`. + # + # Examples: "3/25 files", "project/src/module2", "node_modules/some_dep". + # If unset, the previous progress message (if any) is still valid. + # + # @return [string] + def message + attributes.fetch(:message) + end + + # + # Optional progress percentage to display (value 100 is considered 100%). + # If not provided infinite progress is assumed and clients are allowed + # to ignore the `percentage` value in subsequent in report notifications. + # + # The value should be steadily rising. Clients are free to ignore values + # that are not following this rule. The value range is [0, 100] + # + # @return [number] + def percentage + attributes.fetch(:percentage) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_diagnostic_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_diagnostic_params.rb new file mode 100644 index 00000000..c70c219b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_diagnostic_params.rb @@ -0,0 +1,65 @@ +module LanguageServer + module Protocol + module Interface + # + # Parameters of the workspace diagnostic request. + # + class WorkspaceDiagnosticParams + def initialize(work_done_token: nil, partial_result_token: nil, identifier: nil, previous_result_ids:) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + @attributes[:identifier] = identifier if identifier + @attributes[:previousResultIds] = previous_result_ids + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + # + # The additional identifier provided during registration. + # + # @return [string] + def identifier + attributes.fetch(:identifier) + end + + # + # The currently known diagnostic reports with their + # previous result ids. + # + # @return [PreviousResultId[]] + def previous_result_ids + attributes.fetch(:previousResultIds) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_diagnostic_report.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_diagnostic_report.rb new file mode 100644 index 00000000..a27edb1b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_diagnostic_report.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + # + # A workspace diagnostic report. + # + class WorkspaceDiagnosticReport + def initialize(items:) + @attributes = {} + + @attributes[:items] = items + + @attributes.freeze + end + + # @return [WorkspaceDocumentDiagnosticReport[]] + def items + attributes.fetch(:items) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_diagnostic_report_partial_result.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_diagnostic_report_partial_result.rb new file mode 100644 index 00000000..591bf80b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_diagnostic_report_partial_result.rb @@ -0,0 +1,33 @@ +module LanguageServer + module Protocol + module Interface + # + # A partial result for a workspace diagnostic report. + # + class WorkspaceDiagnosticReportPartialResult + def initialize(items:) + @attributes = {} + + @attributes[:items] = items + + @attributes.freeze + end + + # @return [WorkspaceDocumentDiagnosticReport[]] + def items + attributes.fetch(:items) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_edit.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_edit.rb new file mode 100644 index 00000000..7a3a8678 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_edit.rb @@ -0,0 +1,68 @@ +module LanguageServer + module Protocol + module Interface + class WorkspaceEdit + def initialize(changes: nil, document_changes: nil, change_annotations: nil) + @attributes = {} + + @attributes[:changes] = changes if changes + @attributes[:documentChanges] = document_changes if document_changes + @attributes[:changeAnnotations] = change_annotations if change_annotations + + @attributes.freeze + end + + # + # Holds changes to existing resources. + # + # @return [{}] + def changes + attributes.fetch(:changes) + end + + # + # Depending on the client capability + # `workspace.workspaceEdit.resourceOperations` document changes are either + # an array of `TextDocumentEdit`s to express changes to n different text + # documents where each text document edit addresses a specific version of + # a text document. Or it can contain above `TextDocumentEdit`s mixed with + # create, rename and delete file / folder operations. + # + # Whether a client supports versioned document edits is expressed via + # `workspace.workspaceEdit.documentChanges` client capability. + # + # If a client neither supports `documentChanges` nor + # `workspace.workspaceEdit.resourceOperations` then only plain `TextEdit`s + # using the `changes` property are supported. + # + # @return [TextDocumentEdit[] | (TextDocumentEdit | CreateFile | RenameFile | DeleteFile)[]] + def document_changes + attributes.fetch(:documentChanges) + end + + # + # A map of change annotations that can be referenced in + # `AnnotatedTextEdit`s or create, rename and delete file / folder + # operations. + # + # Whether clients honor this property depends on the client capability + # `workspace.changeAnnotationSupport`. + # + # @return [{ [id: string]: ChangeAnnotation; }] + def change_annotations + attributes.fetch(:changeAnnotations) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_edit_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_edit_client_capabilities.rb new file mode 100644 index 00000000..35267300 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_edit_client_capabilities.rb @@ -0,0 +1,75 @@ +module LanguageServer + module Protocol + module Interface + class WorkspaceEditClientCapabilities + def initialize(document_changes: nil, resource_operations: nil, failure_handling: nil, normalizes_line_endings: nil, change_annotation_support: nil) + @attributes = {} + + @attributes[:documentChanges] = document_changes if document_changes + @attributes[:resourceOperations] = resource_operations if resource_operations + @attributes[:failureHandling] = failure_handling if failure_handling + @attributes[:normalizesLineEndings] = normalizes_line_endings if normalizes_line_endings + @attributes[:changeAnnotationSupport] = change_annotation_support if change_annotation_support + + @attributes.freeze + end + + # + # The client supports versioned document changes in `WorkspaceEdit`s + # + # @return [boolean] + def document_changes + attributes.fetch(:documentChanges) + end + + # + # The resource operations the client supports. Clients should at least + # support 'create', 'rename' and 'delete' files and folders. + # + # @return [ResourceOperationKind[]] + def resource_operations + attributes.fetch(:resourceOperations) + end + + # + # The failure handling strategy of a client if applying the workspace edit + # fails. + # + # @return [FailureHandlingKind] + def failure_handling + attributes.fetch(:failureHandling) + end + + # + # Whether the client normalizes line endings to the client specific + # setting. + # If set to `true` the client will normalize line ending characters + # in a workspace edit to the client specific new line character(s). + # + # @return [boolean] + def normalizes_line_endings + attributes.fetch(:normalizesLineEndings) + end + + # + # Whether the client in general supports change annotations on text edits, + # create file, rename file and delete file changes. + # + # @return [{ groupsOnLabel?: boolean; }] + def change_annotation_support + attributes.fetch(:changeAnnotationSupport) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_folder.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_folder.rb new file mode 100644 index 00000000..6df0ef57 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_folder.rb @@ -0,0 +1,43 @@ +module LanguageServer + module Protocol + module Interface + class WorkspaceFolder + def initialize(uri:, name:) + @attributes = {} + + @attributes[:uri] = uri + @attributes[:name] = name + + @attributes.freeze + end + + # + # The associated URI for this workspace folder. + # + # @return [string] + def uri + attributes.fetch(:uri) + end + + # + # The name of the workspace folder. Used to refer to this + # workspace folder in the user interface. + # + # @return [string] + def name + attributes.fetch(:name) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_folders_change_event.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_folders_change_event.rb new file mode 100644 index 00000000..56c4c29b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_folders_change_event.rb @@ -0,0 +1,45 @@ +module LanguageServer + module Protocol + module Interface + # + # The workspace folder change event. + # + class WorkspaceFoldersChangeEvent + def initialize(added:, removed:) + @attributes = {} + + @attributes[:added] = added + @attributes[:removed] = removed + + @attributes.freeze + end + + # + # The array of added workspace folders + # + # @return [WorkspaceFolder[]] + def added + attributes.fetch(:added) + end + + # + # The array of the removed workspace folders + # + # @return [WorkspaceFolder[]] + def removed + attributes.fetch(:removed) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_folders_server_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_folders_server_capabilities.rb new file mode 100644 index 00000000..2451a6bf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_folders_server_capabilities.rb @@ -0,0 +1,48 @@ +module LanguageServer + module Protocol + module Interface + class WorkspaceFoldersServerCapabilities + def initialize(supported: nil, change_notifications: nil) + @attributes = {} + + @attributes[:supported] = supported if supported + @attributes[:changeNotifications] = change_notifications if change_notifications + + @attributes.freeze + end + + # + # The server has support for workspace folders + # + # @return [boolean] + def supported + attributes.fetch(:supported) + end + + # + # Whether the server wants to receive workspace folder + # change notifications. + # + # If a string is provided, the string is treated as an ID + # under which the notification is registered on the client + # side. The ID can be used to unregister for these events + # using the `client/unregisterCapability` request. + # + # @return [string | boolean] + def change_notifications + attributes.fetch(:changeNotifications) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_full_document_diagnostic_report.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_full_document_diagnostic_report.rb new file mode 100644 index 00000000..d7e63fa5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_full_document_diagnostic_report.rb @@ -0,0 +1,75 @@ +module LanguageServer + module Protocol + module Interface + # + # A full document diagnostic report for a workspace diagnostic result. + # + class WorkspaceFullDocumentDiagnosticReport + def initialize(kind:, result_id: nil, items:, uri:, version:) + @attributes = {} + + @attributes[:kind] = kind + @attributes[:resultId] = result_id if result_id + @attributes[:items] = items + @attributes[:uri] = uri + @attributes[:version] = version + + @attributes.freeze + end + + # + # A full document diagnostic report. + # + # @return [any] + def kind + attributes.fetch(:kind) + end + + # + # An optional result id. If provided it will + # be sent on the next diagnostic request for the + # same document. + # + # @return [string] + def result_id + attributes.fetch(:resultId) + end + + # + # The actual items. + # + # @return [Diagnostic[]] + def items + attributes.fetch(:items) + end + + # + # The URI for which diagnostic information is reported. + # + # @return [string] + def uri + attributes.fetch(:uri) + end + + # + # The version number for which the diagnostics are reported. + # If the document is not marked as open `null` can be provided. + # + # @return [number] + def version + attributes.fetch(:version) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_symbol.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_symbol.rb new file mode 100644 index 00000000..f9603835 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_symbol.rb @@ -0,0 +1,89 @@ +module LanguageServer + module Protocol + module Interface + # + # A special workspace symbol that supports locations without a range + # + class WorkspaceSymbol + def initialize(name:, kind:, tags: nil, container_name: nil, location:, data: nil) + @attributes = {} + + @attributes[:name] = name + @attributes[:kind] = kind + @attributes[:tags] = tags if tags + @attributes[:containerName] = container_name if container_name + @attributes[:location] = location + @attributes[:data] = data if data + + @attributes.freeze + end + + # + # The name of this symbol. + # + # @return [string] + def name + attributes.fetch(:name) + end + + # + # The kind of this symbol. + # + # @return [SymbolKind] + def kind + attributes.fetch(:kind) + end + + # + # Tags for this completion item. + # + # @return [1[]] + def tags + attributes.fetch(:tags) + end + + # + # The name of the symbol containing this symbol. This information is for + # user interface purposes (e.g. to render a qualifier in the user interface + # if necessary). It can't be used to re-infer a hierarchy for the document + # symbols. + # + # @return [string] + def container_name + attributes.fetch(:containerName) + end + + # + # The location of this symbol. Whether a server is allowed to + # return a location without a range depends on the client + # capability `workspace.symbol.resolveSupport`. + # + # See also `SymbolInformation.location`. + # + # @return [Location | { uri: string; }] + def location + attributes.fetch(:location) + end + + # + # A data entry field that is preserved on a workspace symbol between a + # workspace symbol request and a workspace symbol resolve request. + # + # @return [LSPAny] + def data + attributes.fetch(:data) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_symbol_client_capabilities.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_symbol_client_capabilities.rb new file mode 100644 index 00000000..41207951 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_symbol_client_capabilities.rb @@ -0,0 +1,64 @@ +module LanguageServer + module Protocol + module Interface + class WorkspaceSymbolClientCapabilities + def initialize(dynamic_registration: nil, symbol_kind: nil, tag_support: nil, resolve_support: nil) + @attributes = {} + + @attributes[:dynamicRegistration] = dynamic_registration if dynamic_registration + @attributes[:symbolKind] = symbol_kind if symbol_kind + @attributes[:tagSupport] = tag_support if tag_support + @attributes[:resolveSupport] = resolve_support if resolve_support + + @attributes.freeze + end + + # + # Symbol request supports dynamic registration. + # + # @return [boolean] + def dynamic_registration + attributes.fetch(:dynamicRegistration) + end + + # + # Specific capabilities for the `SymbolKind` in the `workspace/symbol` + # request. + # + # @return [{ valueSet?: SymbolKind[]; }] + def symbol_kind + attributes.fetch(:symbolKind) + end + + # + # The client supports tags on `SymbolInformation` and `WorkspaceSymbol`. + # Clients supporting tags have to handle unknown tags gracefully. + # + # @return [{ valueSet: 1[]; }] + def tag_support + attributes.fetch(:tagSupport) + end + + # + # The client support partial workspace symbols. The client will send the + # request `workspaceSymbol/resolve` to the server to resolve additional + # properties. + # + # @return [{ properties: string[]; }] + def resolve_support + attributes.fetch(:resolveSupport) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_symbol_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_symbol_options.rb new file mode 100644 index 00000000..9f30555e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_symbol_options.rb @@ -0,0 +1,40 @@ +module LanguageServer + module Protocol + module Interface + class WorkspaceSymbolOptions + def initialize(work_done_progress: nil, resolve_provider: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:resolveProvider] = resolve_provider if resolve_provider + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # The server provides support to resolve additional + # information for a workspace symbol. + # + # @return [boolean] + def resolve_provider + attributes.fetch(:resolveProvider) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_symbol_params.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_symbol_params.rb new file mode 100644 index 00000000..48efac33 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_symbol_params.rb @@ -0,0 +1,56 @@ +module LanguageServer + module Protocol + module Interface + # + # The parameters of a Workspace Symbol Request. + # + class WorkspaceSymbolParams + def initialize(work_done_token: nil, partial_result_token: nil, query:) + @attributes = {} + + @attributes[:workDoneToken] = work_done_token if work_done_token + @attributes[:partialResultToken] = partial_result_token if partial_result_token + @attributes[:query] = query + + @attributes.freeze + end + + # + # An optional token that a server can use to report work done progress. + # + # @return [ProgressToken] + def work_done_token + attributes.fetch(:workDoneToken) + end + + # + # An optional token that a server can use to report partial results (e.g. + # streaming) to the client. + # + # @return [ProgressToken] + def partial_result_token + attributes.fetch(:partialResultToken) + end + + # + # A query string to filter symbols by. Clients may send an empty + # string here to request all symbols. + # + # @return [string] + def query + attributes.fetch(:query) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_symbol_registration_options.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_symbol_registration_options.rb new file mode 100644 index 00000000..6c99282e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_symbol_registration_options.rb @@ -0,0 +1,40 @@ +module LanguageServer + module Protocol + module Interface + class WorkspaceSymbolRegistrationOptions + def initialize(work_done_progress: nil, resolve_provider: nil) + @attributes = {} + + @attributes[:workDoneProgress] = work_done_progress if work_done_progress + @attributes[:resolveProvider] = resolve_provider if resolve_provider + + @attributes.freeze + end + + # @return [boolean] + def work_done_progress + attributes.fetch(:workDoneProgress) + end + + # + # The server provides support to resolve additional + # information for a workspace symbol. + # + # @return [boolean] + def resolve_provider + attributes.fetch(:resolveProvider) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_unchanged_document_diagnostic_report.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_unchanged_document_diagnostic_report.rb new file mode 100644 index 00000000..611ca3f9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/interface/workspace_unchanged_document_diagnostic_report.rb @@ -0,0 +1,68 @@ +module LanguageServer + module Protocol + module Interface + # + # An unchanged document diagnostic report for a workspace diagnostic result. + # + class WorkspaceUnchangedDocumentDiagnosticReport + def initialize(kind:, result_id:, uri:, version:) + @attributes = {} + + @attributes[:kind] = kind + @attributes[:resultId] = result_id + @attributes[:uri] = uri + @attributes[:version] = version + + @attributes.freeze + end + + # + # A document diagnostic report indicating + # no changes to the last result. A server can + # only return `unchanged` if result ids are + # provided. + # + # @return [any] + def kind + attributes.fetch(:kind) + end + + # + # A result id which will be sent on the next + # diagnostic request for the same document. + # + # @return [string] + def result_id + attributes.fetch(:resultId) + end + + # + # The URI for which diagnostic information is reported. + # + # @return [string] + def uri + attributes.fetch(:uri) + end + + # + # The version number for which the diagnostics are reported. + # If the document is not marked as open `null` can be provided. + # + # @return [number] + def version + attributes.fetch(:version) + end + + attr_reader :attributes + + def to_hash + attributes + end + + def to_json(*args) + to_hash.to_json(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/transport.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/transport.rb new file mode 100644 index 00000000..41c20855 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/transport.rb @@ -0,0 +1,2 @@ +require_relative "transport/io" +require_relative "transport/stdio" diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/transport/io.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/transport/io.rb new file mode 100644 index 00000000..28c6f6402 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/transport/io.rb @@ -0,0 +1,2 @@ +require_relative "io/reader" +require_relative "io/writer" diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/transport/io/reader.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/transport/io/reader.rb new file mode 100644 index 00000000..6c2f1c5f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/transport/io/reader.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require "json" + +module LanguageServer + module Protocol + module Transport + module Io + class Reader + def initialize(io) + @io = io + io.binmode + end + + def read(&block) + while buffer = io.gets("\r\n\r\n") + content_length = buffer.match(/Content-Length: (\d+)/i)[1].to_i + message = io.read(content_length) or raise + request = JSON.parse(message, symbolize_names: true) + block.call(request) + end + end + + def close + io.close + end + + private + + attr_reader :io + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/transport/io/writer.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/transport/io/writer.rb new file mode 100644 index 00000000..f3b37f46 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/transport/io/writer.rb @@ -0,0 +1,39 @@ +module LanguageServer + module Protocol + module Transport + module Io + class Writer + attr_reader :io + + def initialize(io) + @io = io + io.binmode + end + + def write(response) + response_str = JSON.generate(response.merge( + jsonrpc: "2.0" + )) + + headers = { + "Content-Length" => response_str.bytesize + } + + headers.each do |k, v| + io.print "#{k}: #{v}\r\n" + end + + io.print "\r\n" + + io.print response_str + io.flush + end + + def close + io.close + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/transport/stdio.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/transport/stdio.rb new file mode 100644 index 00000000..0892812a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/transport/stdio.rb @@ -0,0 +1,2 @@ +require_relative "stdio/reader" +require_relative "stdio/writer" diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/transport/stdio/reader.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/transport/stdio/reader.rb new file mode 100644 index 00000000..245e9eef --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/transport/stdio/reader.rb @@ -0,0 +1,13 @@ +module LanguageServer + module Protocol + module Transport + module Stdio + class Reader < Io::Reader + def initialize + super STDIN + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/transport/stdio/writer.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/transport/stdio/writer.rb new file mode 100644 index 00000000..bdda148a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/transport/stdio/writer.rb @@ -0,0 +1,13 @@ +module LanguageServer + module Protocol + module Transport + module Stdio + class Writer < Io::Writer + def initialize + super STDOUT + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/version.rb b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/version.rb new file mode 100644 index 00000000..7f3a42c8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/language_server-protocol-3.17.0.5/lib/language_server/protocol/version.rb @@ -0,0 +1,5 @@ +module LanguageServer + module Protocol + VERSION = "3.17.0.5" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/.standard.yml b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/.standard.yml new file mode 100644 index 00000000..3a0787af --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/.standard.yml @@ -0,0 +1,3 @@ +# For available configuration options, see: +# https://github.com/testdouble/standard +ruby_version: 2.6 diff --git a/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/CHANGELOG.md b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/CHANGELOG.md new file mode 100644 index 00000000..5cbacfb8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/CHANGELOG.md @@ -0,0 +1,15 @@ +## [Unreleased] + +## [1.1.0] + +- Add `LintRoller::Support` module of classes designed to make it a little +easier to author plugins. `MergesUpstreamMetadata#merge` will allow a minimal +YAML config (say, `standard-sorbet`'s, which only contains `Enabled` values for +each rule) to merge in any other defaults from a source YAML (e.g. +`rubocop-sorbet`'s which includes `Description`, `VersionAdded`, and so on). +This way that metadata is neither absent at runtime nor duplicated in a standard +plugin that mirrors a rubocop extension + +## [1.0.0] + +- Initial release diff --git a/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/Gemfile b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/Gemfile new file mode 100644 index 00000000..fd0c4a0e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/Gemfile @@ -0,0 +1,9 @@ +source "https://rubygems.org" + +# Specify your gem's dependencies in lint_roller.gemspec +gemspec + +gem "rake" +gem "minitest" +gem "standard" +gem "m" diff --git a/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/Gemfile.lock b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/Gemfile.lock new file mode 100644 index 00000000..56a73cb9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/Gemfile.lock @@ -0,0 +1,58 @@ +PATH + remote: . + specs: + lint_roller (1.1.0) + +GEM + remote: https://rubygems.org/ + specs: + ast (2.4.2) + json (2.6.3) + language_server-protocol (3.17.0.3) + m (1.6.1) + method_source (>= 0.6.7) + rake (>= 0.9.2.2) + method_source (1.0.0) + minitest (5.18.0) + parallel (1.22.1) + parser (3.2.2.0) + ast (~> 2.4.1) + rainbow (3.1.1) + rake (13.0.6) + regexp_parser (2.7.0) + rexml (3.2.5) + rubocop (1.48.1) + json (~> 2.3) + parallel (~> 1.10) + parser (>= 3.2.0.0) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.26.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.28.0) + parser (>= 3.2.1.0) + rubocop-performance (1.16.0) + rubocop (>= 1.7.0, < 2.0) + rubocop-ast (>= 0.4.0) + ruby-progressbar (1.13.0) + standard (1.26.0) + language_server-protocol (~> 3.17.0.2) + rubocop (~> 1.48.1) + rubocop-performance (~> 1.16.0) + unicode-display_width (2.4.2) + +PLATFORMS + arm64-darwin-22 + x86_64-linux + +DEPENDENCIES + lint_roller! + m + minitest + rake + standard + +BUNDLED WITH + 2.4.10 diff --git a/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/LICENSE.txt b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/LICENSE.txt new file mode 100644 index 00000000..7f4238d4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/LICENSE.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2023 Test Double, Inc. + +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 +AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/README.md b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/README.md new file mode 100644 index 00000000..23fb72ab --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/README.md @@ -0,0 +1,173 @@ +# lint_roller - A plugin specification for linters + +`lint_roller` is an itty-bitty plugin API for code analysis tools like linters +and formatters. It provides plugins for those tools to load extensions and +specify custom rulesets. + +(As of this release, only [Standard +Ruby](https://github.com/standardrb/standard) supports `lint_roller` plugins, +but we think [RuboCop](https://github.com/rubocop/rubocop) could add support and +most plugins would be compatible with both `rubocop` and `standardrb`. +Additionally, there's nothing that would prevent other tools like +[rufo](https://github.com/ruby-formatter/rufo) from adopting it.) + +## How to make a plugin + +If you want to make a plugin, the first thing you should do is extend +[LintRoller::Plugin](/lib/lint_roller/plugin.rb) with a custom class. Let's take +this example plugin for banana-related static analysis: + +```ruby +module BananaRoller + class Plugin < LintRoller::Plugin + # `config' is a Hash of options passed to the plugin by the user + def initialize(config = {}) + @alternative = config["alternative"] ||= "chocolate" + end + + def about + LintRoller::About.new( + name: "banana_roller", + version: "1.0", # or, in a gem, probably BananaRoller::VERSION + homepage: "https://github.com/example/banana_roller", + description: "Configuration of banana-related code" + ) + end + + # `context' is an instance of LintRoller::Context provided by the runner + def supported?(context) + context.engine == :rubocop + end + + # `context' is an instance of LintRoller::Context provided by the runner + def rules(context) + LintRoller::Rules.new( + type: :path, + config_format: :rubocop, + value: Pathname.new(__dir__).join("../../config/default.yml") + ) + end + end +end +``` + +And that's pretty much it. Just a declarative way to identify your plugin, +detect whether it supports the given +[LintRoller::Context](/lib/lint_roller_context.rb) (e.g. the current `runner` +and `engine` and their respective `_version`s), for which the plugin will +ultimately its configuration as a [LintRoller::Rules](/lib/lint_roller/rules.rb) +object. + +## Packaging a plugin in a gem + +In order for a formatter to use your plugin, it needs to know what path to +require as well as the name of the plugin class to instantiate and invoke. + +To make this work seamlessly for your users without additional configuration of +their own, all you need to do is specify a metadata attribute called +`default_lint_roller_plugin` in your gemspec. + +Taking [standard-custom](https://github.com/standardrb/standard-custom) as an +example, its gemspec contains: + +```ruby +Gem::Specification.new do |spec| + # … + spec.metadata["default_lint_roller_plugin"] = "Standard::Custom::Plugin" + # … +end +``` + +Because gem specs are loaded by RubyGems and Bundler very early, remember to +specify the plugin as a string representation of the constant, as load order +usually matters, and most tools will need to be loaded before any custom +extensions. Hence, `"Standard::Custom::Plugin"` instead of +`Standard::Custom::Plugin`. + +## Using your plugin + +Once you've made your plugin, here's how it's configured from a Standard Ruby +`.standard.yml` file. + +### If your plugin is packaged as a gem + +Packaging your plugin in a gem is the golden path, both because distributing +code via [RubyGems.org](https://rubygems.org) is very neat, but also because it +makes the least work for your users. + +If your gem name is `banana_roller` and you've set +`spec.metadata["default_lint_roller_plugin"]` to `"BananaRoller::Plugin"`, then +your users could just add this to their `.standard.yml` file: + +```yaml +plugins: + - banana_roller +``` + +And that's it! During initialization, `standardrb` will `require +"banana_roller"` and know to call `BananaRoller::Plugin.new(config)` to +instantiate it. + +### If your plugin ISN'T in a gem + +If you're developing a plugin for internal use or in conjunction with a single +project, you may want it to live in the same repo as opposed to packaging it in +a gem. + +To do this, then—in lieu of a gem name—provide the path you want to be required +as its name, and (since there is no `spec.metadata` to learn of your plugin's +class name), specify it as an option on the plugin: + +```yaml +plugins: + - lib/banana_roller/plugin: + plugin_class_name: BananaRoller::Plugin +``` + +(Be careful with the indentation here! Any configuration under a plugin must be +indented in order for it to be parsed as a hash under the +`"lib/banana_roller/plugin"` key.) + +Additionally, if you want the plugin's name to make more sense, you can give +it whatever name you like in the configuration and specify the `require_path` +explicitly: + +```yaml +plugins: + - banana_roller: + require_path: lib/banana_roller/plugin + plugin_class_name: BananaRoller::Plugin +``` + +### Passing user configuration to the plugin + +When a `LintRoller::Plugin` is instantiated, users can pass a configuration hash +that tells your plugin how to behave. + +To illustrate how this works in Standard Ruby, anything passed as a hash beneath +a plugin will be passed to the class's `initialize` method: + +```yaml +plugins: + - apple_roller + - banana_roller: + require_path: lib/banana_roller/plugin + plugin_class_name: BananaRoller::Plugin + alternative: "apples" + - orange_roller: + rind: false +``` + +In the above case, `apple_roller`'s plugin class will be instantiated with +`new({})`, `banana_roller` will get all 3 of those parameters passed +`BananaRoller::Plugin.new({require_path…})`, and `orange_roller`'s class will be +called with `new({rind: false})`. + +## Code of Conduct + +This project follows Test Double's [code of +conduct](https://testdouble.com/code-of-conduct) for all community interactions, +including (but not limited to) one-on-one communications, public posts/comments, +code reviews, pull requests, and GitHub issues. If violations occur, Test Double +will take any action they deem appropriate for the infraction, up to and +including blocking a user from the organization's repositories. diff --git a/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/Rakefile b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/Rakefile new file mode 100644 index 00000000..87e8be4b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/Rakefile @@ -0,0 +1,12 @@ +require "bundler/gem_tasks" +require "rake/testtask" + +Rake::TestTask.new(:test) do |t| + t.libs << "test" + t.libs << "lib" + t.test_files = FileList["test/**/*_test.rb"] +end + +require "standard/rake" + +task default: %i[test standard:fix] diff --git a/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/lib/lint_roller.rb b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/lib/lint_roller.rb new file mode 100644 index 00000000..96939de7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/lib/lint_roller.rb @@ -0,0 +1,13 @@ +require_relative "lint_roller/version" + +require_relative "lint_roller/about" +require_relative "lint_roller/context" +require_relative "lint_roller/rules" + +require_relative "lint_roller/plugin" +require_relative "lint_roller/error" + +require_relative "lint_roller/support/merges_upstream_metadata" + +module LintRoller +end diff --git a/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/lib/lint_roller/about.rb b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/lib/lint_roller/about.rb new file mode 100644 index 00000000..fdb55574 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/lib/lint_roller/about.rb @@ -0,0 +1,9 @@ +module LintRoller + About = Struct.new( + :name, # "standard-performance" + :version, # "1.2.3" + :homepage, # "https://github.com/testdouble/standard-performance" + :description, # "A configuration of rubocop-performance rules to make Ruby go faster" + keyword_init: true + ) +end diff --git a/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/lib/lint_roller/context.rb b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/lib/lint_roller/context.rb new file mode 100644 index 00000000..ebf2f526 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/lib/lint_roller/context.rb @@ -0,0 +1,11 @@ +module LintRoller + Context = Struct.new( + :runner, # :standard, :rubocop + :runner_version, # "1.2.3" + :engine, # :rubocop + :engine_version, # "2.3.4", + :rule_format, # :rubocop + :target_ruby_version, # Gem::Version.new("2.7.0") + keyword_init: true + ) +end diff --git a/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/lib/lint_roller/error.rb b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/lib/lint_roller/error.rb new file mode 100644 index 00000000..364b7b1d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/lib/lint_roller/error.rb @@ -0,0 +1,4 @@ +module LintRoller + class Error < StandardError + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/lib/lint_roller/plugin.rb b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/lib/lint_roller/plugin.rb new file mode 100644 index 00000000..6d614dc7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/lib/lint_roller/plugin.rb @@ -0,0 +1,22 @@ +module LintRoller + class Plugin + # `config' is a Hash of options passed to the plugin by the user + def initialize(config = {}) + @config = config + end + + def about + raise Error.new("Please implement `about` and return an instance of LintRoller::About") + end + + # `context' is an instance of LintRoller::Context provided by the runner + def supported?(context) + true + end + + # `context' is an instance of LintRoller::Context provided by the runner + def rules(context) + raise Error.new("Please implement `rules(context)` and return an instance of LintRoller::Rules") + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/lib/lint_roller/rules.rb b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/lib/lint_roller/rules.rb new file mode 100644 index 00000000..1331b131 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/lib/lint_roller/rules.rb @@ -0,0 +1,17 @@ +module LintRoller + Rules = Struct.new( + # Valid values: :path, :object, :error + :type, + # Only known value right now is :rubocop but nothing would stop rufo or + # rubyfmt or prettier from adding support without a change to the gem + :config_format, + # If type is :path, String or Pathname. Otherwise, whatever :object type + # makes sense given :config_format (e.g. for RuboCop, a Hash loaded from a + # YAML file; note that providing a hash will prevent the use of RuboCop features + # like `inherit_from' and `require'!) + :value, + # If something went wrong an Error for the runner to deal with appropriately + :error, + keyword_init: true + ) +end diff --git a/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/lib/lint_roller/support/merges_upstream_metadata.rb b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/lib/lint_roller/support/merges_upstream_metadata.rb new file mode 100644 index 00000000..f595cdaa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/lib/lint_roller/support/merges_upstream_metadata.rb @@ -0,0 +1,23 @@ +module LintRoller + module Support + class MergesUpstreamMetadata + def merge(plugin_yaml, upstream_yaml) + common_upstream_values = upstream_yaml.select { |key| plugin_yaml.key?(key) } + + plugin_yaml.merge(common_upstream_values) { |key, plugin_value, upstream_value| + if plugin_value.is_a?(Hash) && upstream_value.is_a?(Hash) + plugin_value.merge(upstream_value) { |sub_key, plugin_sub_value, upstream_sub_value| + if plugin_value.key?(sub_key) + plugin_sub_value + else + upstream_sub_value + end + } + else + plugin_value + end + } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/lib/lint_roller/version.rb b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/lib/lint_roller/version.rb new file mode 100644 index 00000000..01e7c114 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/lint_roller-1.1.0/lib/lint_roller/version.rb @@ -0,0 +1,3 @@ +module LintRoller + VERSION = "1.1.0" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/.document b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/.document new file mode 100644 index 00000000..e2b95699 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/.document @@ -0,0 +1,4 @@ +BSDL +COPYING +README.md +lib/ diff --git a/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/.rdoc_options b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/.rdoc_options new file mode 100644 index 00000000..2d29a059 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/.rdoc_options @@ -0,0 +1,3 @@ +--- +main_page: README.md +title: Documentation for Logger diff --git a/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/BSDL b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/BSDL new file mode 100644 index 00000000..66d93598 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/BSDL @@ -0,0 +1,22 @@ +Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/COPYING b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/COPYING new file mode 100644 index 00000000..48e5a96d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/COPYING @@ -0,0 +1,56 @@ +Ruby is copyrighted free software by Yukihiro Matsumoto . +You can redistribute it and/or modify it under either the terms of the +2-clause BSDL (see the file BSDL), or the conditions below: + +1. You may make and give away verbatim copies of the source form of the + software without restriction, provided that you duplicate all of the + original copyright notices and associated disclaimers. + +2. You may modify your copy of the software in any way, provided that + you do at least ONE of the following: + + a. place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said + modifications to Usenet or an equivalent medium, or by allowing + the author to include your modifications in the software. + + b. use the modified software only within your corporation or + organization. + + c. give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d. make other distribution arrangements with the author. + +3. You may distribute the software in object code or binary form, + provided that you do at least ONE of the following: + + a. distribute the binaries and library files of the software, + together with instructions (in the manual page or equivalent) + on where to get the original distribution. + + b. accompany the distribution with the machine-readable source of + the software. + + c. give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d. make other distribution arrangements with the author. + +4. You may modify and include the part of the software into any other + software (possibly commercial). But some files in the distribution + are not written by the author, so that they are not under these terms. + + For the list of those files and their copying conditions, see the + file LEGAL. + +5. The scripts and library files supplied as input to or produced as + output from the software do not automatically fall under the + copyright of the software, but belong to whomever generated them, + and may be sold commercially, and may be aggregated with this + software. + +6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. diff --git a/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/README.md b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/README.md new file mode 100644 index 00000000..ceb1a213 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/README.md @@ -0,0 +1,104 @@ +# Logger + +Logger is a simple but powerful logging utility to output messages in your Ruby program. + +Logger has the following features: + + * Print messages to different levels such as `info` and `error` + * Auto-rolling of log files + * Setting the format of log messages + * Specifying a program name in conjunction with the message + +## Installation + +Add this line to your application's Gemfile: + +```ruby +gem 'logger' +``` + +And then execute: + + $ bundle + +Or install it yourself as: + + $ gem install logger + +## Usage + +### Simple Example + +```ruby +require 'logger' + +# Create a Logger that prints to STDOUT +log = Logger.new(STDOUT) +log.debug("Created Logger") + +log.info("Program finished") + +# Create a Logger that prints to STDERR +error_log = Logger.new(STDERR) +error_log = error_log.error("fatal error") +``` + +## Development + +After checking out the repo, run the following to install dependencies. + +``` +$ bin/setup +``` + +Then, run the tests as: + +``` +$ rake test +``` + +To install this gem onto your local machine, run + +``` +$ rake install +``` + +To release a new version, update the version number in `lib/logger/version.rb`, and then run + +``` +$ rake release +``` + +which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). + +## Advanced Development + +### Run tests of a specific file + +``` +$ ruby test/logger/test_logger.rb +``` + +### Run tests filtering test methods by a name + +`--name` option is available as: + +``` +$ ruby test/logger/test_logger.rb --name test_lshift +``` + +### Publish documents to GitHub Pages + +``` +$ rake gh-pages +``` + +Then, git commit and push the generated HTMLs onto `gh-pages` branch. + +## Contributing + +Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/logger. + +## License + +The gem is available as open source under the terms of the [BSD-2-Clause](BSDL). diff --git a/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger.rb b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger.rb new file mode 100644 index 00000000..4911a3f3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger.rb @@ -0,0 +1,789 @@ +# frozen_string_literal: true +# logger.rb - simple logging utility +# Copyright (C) 2000-2003, 2005, 2008, 2011 NAKAMURA, Hiroshi . +# +# Documentation:: NAKAMURA, Hiroshi and Gavin Sinclair +# License:: +# You can redistribute it and/or modify it under the same terms of Ruby's +# license; either the dual license version in 2003, or any later version. +# Revision:: $Id$ +# +# A simple system for logging messages. See Logger for more documentation. + +require 'fiber' +require 'monitor' +require 'rbconfig' + +require_relative 'logger/version' +require_relative 'logger/formatter' +require_relative 'logger/log_device' +require_relative 'logger/severity' +require_relative 'logger/errors' + +# \Class \Logger provides a simple but sophisticated logging utility that +# you can use to create one or more +# {event logs}[https://en.wikipedia.org/wiki/Logging_(software)#Event_logs] +# for your program. +# Each such log contains a chronological sequence of entries +# that provides a record of the program's activities. +# +# == About the Examples +# +# All examples on this page assume that \Logger has been required: +# +# require 'logger' +# +# == Synopsis +# +# Create a log with Logger.new: +# +# # Single log file. +# logger = Logger.new('t.log') +# # Size-based rotated logging: 3 10-megabyte files. +# logger = Logger.new('t.log', 3, 10485760) +# # Period-based rotated logging: daily (also allowed: 'weekly', 'monthly'). +# logger = Logger.new('t.log', 'daily') +# # Log to an IO stream. +# logger = Logger.new($stdout) +# +# Add entries (level, message) with Logger#add: +# +# logger.add(Logger::DEBUG, 'Maximal debugging info') +# logger.add(Logger::INFO, 'Non-error information') +# logger.add(Logger::WARN, 'Non-error warning') +# logger.add(Logger::ERROR, 'Non-fatal error') +# logger.add(Logger::FATAL, 'Fatal error') +# logger.add(Logger::UNKNOWN, 'Most severe') +# +# Close the log with Logger#close: +# +# logger.close +# +# == Entries +# +# You can add entries with method Logger#add: +# +# logger.add(Logger::DEBUG, 'Maximal debugging info') +# logger.add(Logger::INFO, 'Non-error information') +# logger.add(Logger::WARN, 'Non-error warning') +# logger.add(Logger::ERROR, 'Non-fatal error') +# logger.add(Logger::FATAL, 'Fatal error') +# logger.add(Logger::UNKNOWN, 'Most severe') +# +# These shorthand methods also add entries: +# +# logger.debug('Maximal debugging info') +# logger.info('Non-error information') +# logger.warn('Non-error warning') +# logger.error('Non-fatal error') +# logger.fatal('Fatal error') +# logger.unknown('Most severe') +# +# When you call any of these methods, +# the entry may or may not be written to the log, +# depending on the entry's severity and on the log level; +# see {Log Level}[rdoc-ref:Logger@Log+Level] +# +# An entry always has: +# +# - A severity (the required argument to #add). +# - An automatically created timestamp. +# +# And may also have: +# +# - A message. +# - A program name. +# +# Example: +# +# logger = Logger.new($stdout) +# logger.add(Logger::INFO, 'My message.', 'mung') +# # => I, [2022-05-07T17:21:46.536234 #20536] INFO -- mung: My message. +# +# The default format for an entry is: +# +# "%s, [%s #%d] %5s -- %s: %s\n" +# +# where the values to be formatted are: +# +# - \Severity (one letter). +# - Timestamp. +# - Process id. +# - \Severity (word). +# - Program name. +# - Message. +# +# You can use a different entry format by: +# +# - Setting a custom format proc (affects following entries); +# see {formatter=}[Logger.html#attribute-i-formatter]. +# - Calling any of the methods above with a block +# (affects only the one entry). +# Doing so can have two benefits: +# +# - Context: the block can evaluate the entire program context +# and create a context-dependent message. +# - Performance: the block is not evaluated unless the log level +# permits the entry actually to be written: +# +# logger.error { my_slow_message_generator } +# +# Contrast this with the string form, where the string is +# always evaluated, regardless of the log level: +# +# logger.error("#{my_slow_message_generator}") +# +# === \Severity +# +# The severity of a log entry has two effects: +# +# - Determines whether the entry is selected for inclusion in the log; +# see {Log Level}[rdoc-ref:Logger@Log+Level]. +# - Indicates to any log reader (whether a person or a program) +# the relative importance of the entry. +# +# === Timestamp +# +# The timestamp for a log entry is generated automatically +# when the entry is created. +# +# The logged timestamp is formatted by method +# {Time#strftime}[https://docs.ruby-lang.org/en/master/Time.html#method-i-strftime] +# using this format string: +# +# '%Y-%m-%dT%H:%M:%S.%6N' +# +# Example: +# +# logger = Logger.new($stdout) +# logger.add(Logger::INFO) +# # => I, [2022-05-07T17:04:32.318331 #20536] INFO -- : nil +# +# You can set a different format using method #datetime_format=. +# +# === Message +# +# The message is an optional argument to an entry method: +# +# logger = Logger.new($stdout) +# logger.add(Logger::INFO, 'My message') +# # => I, [2022-05-07T18:15:37.647581 #20536] INFO -- : My message +# +# For the default entry formatter, Logger::Formatter, +# the message object may be: +# +# - A string: used as-is. +# - An Exception: message.message is used. +# - Anything else: message.inspect is used. +# +# *Note*: Logger::Formatter does not escape or sanitize +# the message passed to it. +# Developers should be aware that malicious data (user input) +# may be in the message, and should explicitly escape untrusted data. +# +# You can use a custom formatter to escape message data; +# see the example at {formatter=}[Logger.html#attribute-i-formatter]. +# +# === Program Name +# +# The program name is an optional argument to an entry method: +# +# logger = Logger.new($stdout) +# logger.add(Logger::INFO, 'My message', 'mung') +# # => I, [2022-05-07T18:17:38.084716 #20536] INFO -- mung: My message +# +# The default program name for a new logger may be set in the call to +# Logger.new via optional keyword argument +progname+: +# +# logger = Logger.new('t.log', progname: 'mung') +# +# The default program name for an existing logger may be set +# by a call to method #progname=: +# +# logger.progname = 'mung' +# +# The current program name may be retrieved with method +# {progname}[Logger.html#attribute-i-progname]: +# +# logger.progname # => "mung" +# +# == Log Level +# +# The log level setting determines whether an entry is actually +# written to the log, based on the entry's severity. +# +# These are the defined severities (least severe to most severe): +# +# logger = Logger.new($stdout) +# logger.add(Logger::DEBUG, 'Maximal debugging info') +# # => D, [2022-05-07T17:57:41.776220 #20536] DEBUG -- : Maximal debugging info +# logger.add(Logger::INFO, 'Non-error information') +# # => I, [2022-05-07T17:59:14.349167 #20536] INFO -- : Non-error information +# logger.add(Logger::WARN, 'Non-error warning') +# # => W, [2022-05-07T18:00:45.337538 #20536] WARN -- : Non-error warning +# logger.add(Logger::ERROR, 'Non-fatal error') +# # => E, [2022-05-07T18:02:41.592912 #20536] ERROR -- : Non-fatal error +# logger.add(Logger::FATAL, 'Fatal error') +# # => F, [2022-05-07T18:05:24.703931 #20536] FATAL -- : Fatal error +# logger.add(Logger::UNKNOWN, 'Most severe') +# # => A, [2022-05-07T18:07:54.657491 #20536] ANY -- : Most severe +# +# The default initial level setting is Logger::DEBUG, the lowest level, +# which means that all entries are to be written, regardless of severity: +# +# logger = Logger.new($stdout) +# logger.level # => 0 +# logger.add(0, "My message") +# # => D, [2022-05-11T15:10:59.773668 #20536] DEBUG -- : My message +# +# You can specify a different setting in a new logger +# using keyword argument +level+ with an appropriate value: +# +# logger = Logger.new($stdout, level: Logger::ERROR) +# logger = Logger.new($stdout, level: 'error') +# logger = Logger.new($stdout, level: :error) +# logger.level # => 3 +# +# With this level, entries with severity Logger::ERROR and higher +# are written, while those with lower severities are not written: +# +# logger = Logger.new($stdout, level: Logger::ERROR) +# logger.add(3) +# # => E, [2022-05-11T15:17:20.933362 #20536] ERROR -- : nil +# logger.add(2) # Silent. +# +# You can set the log level for an existing logger +# with method #level=: +# +# logger.level = Logger::ERROR +# +# These shorthand methods also set the level: +# +# logger.debug! # => 0 +# logger.info! # => 1 +# logger.warn! # => 2 +# logger.error! # => 3 +# logger.fatal! # => 4 +# +# You can retrieve the log level with method #level. +# +# logger.level = Logger::ERROR +# logger.level # => 3 +# +# These methods return whether a given +# level is to be written: +# +# logger.level = Logger::ERROR +# logger.debug? # => false +# logger.info? # => false +# logger.warn? # => false +# logger.error? # => true +# logger.fatal? # => true +# +# == Log File Rotation +# +# By default, a log file is a single file that grows indefinitely +# (until explicitly closed); there is no file rotation. +# +# To keep log files to a manageable size, +# you can use _log_ _file_ _rotation_, which uses multiple log files: +# +# - Each log file has entries for a non-overlapping +# time interval. +# - Only the most recent log file is open and active; +# the others are closed and inactive. +# +# === Size-Based Rotation +# +# For size-based log file rotation, call Logger.new with: +# +# - Argument +logdev+ as a file path. +# - Argument +shift_age+ with a positive integer: +# the number of log files to be in the rotation. +# - Argument +shift_size+ as a positive integer: +# the maximum size (in bytes) of each log file; +# defaults to 1048576 (1 megabyte). +# +# Examples: +# +# logger = Logger.new('t.log', 3) # Three 1-megabyte files. +# logger = Logger.new('t.log', 5, 10485760) # Five 10-megabyte files. +# +# For these examples, suppose: +# +# logger = Logger.new('t.log', 3) +# +# Logging begins in the new log file, +t.log+; +# the log file is "full" and ready for rotation +# when a new entry would cause its size to exceed +shift_size+. +# +# The first time +t.log+ is full: +# +# - +t.log+ is closed and renamed to +t.log.0+. +# - A new file +t.log+ is opened. +# +# The second time +t.log+ is full: +# +# - +t.log.0 is renamed as +t.log.1+. +# - +t.log+ is closed and renamed to +t.log.0+. +# - A new file +t.log+ is opened. +# +# Each subsequent time that +t.log+ is full, +# the log files are rotated: +# +# - +t.log.1+ is removed. +# - +t.log.0 is renamed as +t.log.1+. +# - +t.log+ is closed and renamed to +t.log.0+. +# - A new file +t.log+ is opened. +# +# === Periodic Rotation +# +# For periodic rotation, call Logger.new with: +# +# - Argument +logdev+ as a file path. +# - Argument +shift_age+ as a string period indicator. +# +# Examples: +# +# logger = Logger.new('t.log', 'daily') # Rotate log files daily. +# logger = Logger.new('t.log', 'weekly') # Rotate log files weekly. +# logger = Logger.new('t.log', 'monthly') # Rotate log files monthly. +# +# Example: +# +# logger = Logger.new('t.log', 'daily') +# +# When the given period expires: +# +# - The base log file, +t.log+ is closed and renamed +# with a date-based suffix such as +t.log.20220509+. +# - A new log file +t.log+ is opened. +# - Nothing is removed. +# +# The default format for the suffix is '%Y%m%d', +# which produces a suffix similar to the one above. +# You can set a different format using create-time option +# +shift_period_suffix+; +# see details and suggestions at +# {Time#strftime}[https://docs.ruby-lang.org/en/master/Time.html#method-i-strftime]. +# +class Logger + _, name, rev = %w$Id$ + if name + name = name.chomp(",v") + else + name = File.basename(__FILE__) + end + rev ||= "v#{VERSION}" + ProgName = "#{name}/#{rev}" + + include Severity + + # Logging severity threshold (e.g. Logger::INFO). + def level + level_override[level_key] || @level + end + + # Sets the log level; returns +severity+. + # See {Log Level}[rdoc-ref:Logger@Log+Level]. + # + # Argument +severity+ may be an integer, a string, or a symbol: + # + # logger.level = Logger::ERROR # => 3 + # logger.level = 3 # => 3 + # logger.level = 'error' # => "error" + # logger.level = :error # => :error + # + # Logger#sev_threshold= is an alias for Logger#level=. + # + def level=(severity) + @level = Severity.coerce(severity) + end + + # Adjust the log level during the block execution for the current Fiber only + # + # logger.with_level(:debug) do + # logger.debug { "Hello" } + # end + def with_level(severity) + prev, level_override[level_key] = level, Severity.coerce(severity) + begin + yield + ensure + if prev + level_override[level_key] = prev + else + level_override.delete(level_key) + end + end + end + + # Program name to include in log messages. + attr_accessor :progname + + # Sets the date-time format. + # + # Argument +datetime_format+ should be either of these: + # + # - A string suitable for use as a format for method + # {Time#strftime}[https://docs.ruby-lang.org/en/master/Time.html#method-i-strftime]. + # - +nil+: the logger uses '%Y-%m-%dT%H:%M:%S.%6N'. + # + def datetime_format=(datetime_format) + @default_formatter.datetime_format = datetime_format + end + + # Returns the date-time format; see #datetime_format=. + # + def datetime_format + @default_formatter.datetime_format + end + + # Sets or retrieves the logger entry formatter proc. + # + # When +formatter+ is +nil+, the logger uses Logger::Formatter. + # + # When +formatter+ is a proc, a new entry is formatted by the proc, + # which is called with four arguments: + # + # - +severity+: The severity of the entry. + # - +time+: A Time object representing the entry's timestamp. + # - +progname+: The program name for the entry. + # - +msg+: The message for the entry (string or string-convertible object). + # + # The proc should return a string containing the formatted entry. + # + # This custom formatter uses + # {String#dump}[https://docs.ruby-lang.org/en/master/String.html#method-i-dump] + # to escape the message string: + # + # logger = Logger.new($stdout, progname: 'mung') + # original_formatter = logger.formatter || Logger::Formatter.new + # logger.formatter = proc { |severity, time, progname, msg| + # original_formatter.call(severity, time, progname, msg.dump) + # } + # logger.add(Logger::INFO, "hello \n ''") + # logger.add(Logger::INFO, "\f\x00\xff\\\"") + # + # Output: + # + # I, [2022-05-13T13:16:29.637488 #8492] INFO -- mung: "hello \n ''" + # I, [2022-05-13T13:16:29.637610 #8492] INFO -- mung: "\f\x00\xFF\\\"" + # + attr_accessor :formatter + + alias sev_threshold level + alias sev_threshold= level= + + # Returns +true+ if the log level allows entries with severity + # Logger::DEBUG to be written, +false+ otherwise. + # See {Log Level}[rdoc-ref:Logger@Log+Level]. + # + def debug?; level <= DEBUG; end + + # Sets the log level to Logger::DEBUG. + # See {Log Level}[rdoc-ref:Logger@Log+Level]. + # + def debug!; self.level = DEBUG; end + + # Returns +true+ if the log level allows entries with severity + # Logger::INFO to be written, +false+ otherwise. + # See {Log Level}[rdoc-ref:Logger@Log+Level]. + # + def info?; level <= INFO; end + + # Sets the log level to Logger::INFO. + # See {Log Level}[rdoc-ref:Logger@Log+Level]. + # + def info!; self.level = INFO; end + + # Returns +true+ if the log level allows entries with severity + # Logger::WARN to be written, +false+ otherwise. + # See {Log Level}[rdoc-ref:Logger@Log+Level]. + # + def warn?; level <= WARN; end + + # Sets the log level to Logger::WARN. + # See {Log Level}[rdoc-ref:Logger@Log+Level]. + # + def warn!; self.level = WARN; end + + # Returns +true+ if the log level allows entries with severity + # Logger::ERROR to be written, +false+ otherwise. + # See {Log Level}[rdoc-ref:Logger@Log+Level]. + # + def error?; level <= ERROR; end + + # Sets the log level to Logger::ERROR. + # See {Log Level}[rdoc-ref:Logger@Log+Level]. + # + def error!; self.level = ERROR; end + + # Returns +true+ if the log level allows entries with severity + # Logger::FATAL to be written, +false+ otherwise. + # See {Log Level}[rdoc-ref:Logger@Log+Level]. + # + def fatal?; level <= FATAL; end + + # Sets the log level to Logger::FATAL. + # See {Log Level}[rdoc-ref:Logger@Log+Level]. + # + def fatal!; self.level = FATAL; end + + # :call-seq: + # Logger.new(logdev, shift_age = 0, shift_size = 1048576, **options) + # + # With the single argument +logdev+, + # returns a new logger with all default options: + # + # Logger.new('t.log') # => # + # + # Argument +logdev+ must be one of: + # + # - A string filepath: entries are to be written + # to the file at that path; if the file at that path exists, + # new entries are appended. + # - An IO stream (typically $stdout, $stderr. or + # an open file): entries are to be written to the given stream. + # - +nil+ or +File::NULL+: no entries are to be written. + # + # Argument +shift_age+ must be one of: + # + # - The number of log files to be in the rotation. + # See {Size-Based Rotation}[rdoc-ref:Logger@Size-Based+Rotation]. + # - A string period indicator. + # See {Periodic Rotation}[rdoc-ref:Logger@Periodic+Rotation]. + # + # Argument +shift_size+ is the maximum size (in bytes) of each log file. + # See {Size-Based Rotation}[rdoc-ref:Logger@Size-Based+Rotation]. + # + # Examples: + # + # Logger.new('t.log') + # Logger.new($stdout) + # + # The keyword options are: + # + # - +level+: sets the log level; default value is Logger::DEBUG. + # See {Log Level}[rdoc-ref:Logger@Log+Level]: + # + # Logger.new('t.log', level: Logger::ERROR) + # + # - +progname+: sets the default program name; default is +nil+. + # See {Program Name}[rdoc-ref:Logger@Program+Name]: + # + # Logger.new('t.log', progname: 'mung') + # + # - +formatter+: sets the entry formatter; default is +nil+. + # See {formatter=}[Logger.html#attribute-i-formatter]. + # + # - +datetime_format+: sets the format for entry timestamp; + # default is +nil+. + # See #datetime_format=. + # + # - +binmode+: sets whether the logger writes in binary mode; + # default is +false+. + # + # - +shift_period_suffix+: sets the format for the filename suffix + # for periodic log file rotation; default is '%Y%m%d'. + # See {Periodic Rotation}[rdoc-ref:Logger@Periodic+Rotation]. + # + # - +reraise_write_errors+: An array of exception classes, which will + # be reraised if there is an error when writing to the log device. + # The default is to swallow all exceptions raised. + # - +skip_header+: If +true+, prevents the logger from writing a header + # when creating a new log file. The default is +false+, meaning + # the header will be written as usual. + # + def initialize(logdev, shift_age = 0, shift_size = 1048576, level: DEBUG, + progname: nil, formatter: nil, datetime_format: nil, + binmode: false, shift_period_suffix: '%Y%m%d', + reraise_write_errors: [], skip_header: false) + self.level = level + self.progname = progname + @default_formatter = Formatter.new + self.datetime_format = datetime_format + self.formatter = formatter + @logdev = nil + @level_override = {} + if logdev && logdev != File::NULL + @logdev = LogDevice.new(logdev, shift_age: shift_age, + shift_size: shift_size, + shift_period_suffix: shift_period_suffix, + binmode: binmode, + reraise_write_errors: reraise_write_errors, + skip_header: skip_header) + end + end + + # Sets the logger's output stream: + # + # - If +logdev+ is +nil+, reopens the current output stream. + # - If +logdev+ is a filepath, opens the indicated file for append. + # - If +logdev+ is an IO stream + # (usually $stdout, $stderr, or an open File object), + # opens the stream for append. + # + # Example: + # + # logger = Logger.new('t.log') + # logger.add(Logger::ERROR, 'one') + # logger.close + # logger.add(Logger::ERROR, 'two') # Prints 'log writing failed. closed stream' + # logger.reopen + # logger.add(Logger::ERROR, 'three') + # logger.close + # File.readlines('t.log') + # # => + # # ["# Logfile created on 2022-05-12 14:21:19 -0500 by logger.rb/v1.5.0\n", + # # "E, [2022-05-12T14:21:27.596726 #22428] ERROR -- : one\n", + # # "E, [2022-05-12T14:23:05.847241 #22428] ERROR -- : three\n"] + # + def reopen(logdev = nil, shift_age = nil, shift_size = nil, shift_period_suffix: nil, binmode: nil) + @logdev&.reopen(logdev, shift_age: shift_age, shift_size: shift_size, + shift_period_suffix: shift_period_suffix, binmode: binmode) + self + end + + # Creates a log entry, which may or may not be written to the log, + # depending on the entry's severity and on the log level. + # See {Log Level}[rdoc-ref:Logger@Log+Level] + # and {Entries}[rdoc-ref:Logger@Entries] for details. + # + # Examples: + # + # logger = Logger.new($stdout, progname: 'mung') + # logger.add(Logger::INFO) + # logger.add(Logger::ERROR, 'No good') + # logger.add(Logger::ERROR, 'No good', 'gnum') + # + # Output: + # + # I, [2022-05-12T16:25:31.469726 #36328] INFO -- mung: mung + # E, [2022-05-12T16:25:55.349414 #36328] ERROR -- mung: No good + # E, [2022-05-12T16:26:35.841134 #36328] ERROR -- gnum: No good + # + # These convenience methods have implicit severity: + # + # - #debug. + # - #info. + # - #warn. + # - #error. + # - #fatal. + # - #unknown. + # + def add(severity, message = nil, progname = nil) + severity ||= UNKNOWN + if @logdev.nil? or severity < level + return true + end + if progname.nil? + progname = @progname + end + if message.nil? + if block_given? + message = yield + else + message = progname + progname = @progname + end + end + @logdev.write( + format_message(format_severity(severity), Time.now, progname, message)) + true + end + alias log add + + # Writes the given +msg+ to the log with no formatting; + # returns the number of characters written, + # or +nil+ if no log device exists: + # + # logger = Logger.new($stdout) + # logger << 'My message.' # => 10 + # + # Output: + # + # My message. + # + def <<(msg) + @logdev&.write(msg) + end + + # Equivalent to calling #add with severity Logger::DEBUG. + # + def debug(progname = nil, &block) + add(DEBUG, nil, progname, &block) + end + + # Equivalent to calling #add with severity Logger::INFO. + # + def info(progname = nil, &block) + add(INFO, nil, progname, &block) + end + + # Equivalent to calling #add with severity Logger::WARN. + # + def warn(progname = nil, &block) + add(WARN, nil, progname, &block) + end + + # Equivalent to calling #add with severity Logger::ERROR. + # + def error(progname = nil, &block) + add(ERROR, nil, progname, &block) + end + + # Equivalent to calling #add with severity Logger::FATAL. + # + def fatal(progname = nil, &block) + add(FATAL, nil, progname, &block) + end + + # Equivalent to calling #add with severity Logger::UNKNOWN. + # + def unknown(progname = nil, &block) + add(UNKNOWN, nil, progname, &block) + end + + # Closes the logger; returns +nil+: + # + # logger = Logger.new('t.log') + # logger.close # => nil + # logger.info('foo') # Prints "log writing failed. closed stream" + # + # Related: Logger#reopen. + def close + @logdev&.close + end + +private + + # \Severity label for logging (max 5 chars). + SEV_LABEL = %w(DEBUG INFO WARN ERROR FATAL ANY).freeze + + def format_severity(severity) + SEV_LABEL[severity] || 'ANY' + end + + # Guarantee the existence of this ivar even when subclasses don't call the superclass constructor. + def level_override + unless defined?(@level_override) + bad = self.class.instance_method(:initialize) + file, line = bad.source_location + Kernel.warn <<~";;;", uplevel: 2 + Logger not initialized properly + #{file}:#{line}: info: #{bad.owner}\##{bad.name}: \ + does not call super probably + ;;; + end + @level_override ||= {} + end + + def level_key + Fiber.current + end + + def format_message(severity, datetime, progname, msg) + (@formatter || @default_formatter).call(severity, datetime, progname, msg) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/errors.rb b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/errors.rb new file mode 100644 index 00000000..88581793 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/errors.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class Logger + # not used after 1.2.7. just for compat. + class Error < RuntimeError # :nodoc: + end + class ShiftingError < Error # :nodoc: + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/formatter.rb b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/formatter.rb new file mode 100644 index 00000000..c634dbf3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/formatter.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +class Logger + # Default formatter for log messages. + class Formatter + Format = "%.1s, [%s #%d] %5s -- %s: %s\n" + DatetimeFormat = "%Y-%m-%dT%H:%M:%S.%6N" + + attr_accessor :datetime_format + + def initialize + @datetime_format = nil + end + + def call(severity, time, progname, msg) + sprintf(Format, severity, format_datetime(time), Process.pid, severity, progname, msg2str(msg)) + end + + private + + def format_datetime(time) + time.strftime(@datetime_format || DatetimeFormat) + end + + def msg2str(msg) + case msg + when ::String + msg + when ::Exception + "#{ msg.message } (#{ msg.class })\n#{ msg.backtrace.join("\n") if msg.backtrace }" + else + msg.inspect + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/log_device.rb b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/log_device.rb new file mode 100644 index 00000000..e16f3b70 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/log_device.rb @@ -0,0 +1,265 @@ +# frozen_string_literal: true + +require_relative 'period' + +class Logger + # Device used for logging messages. + class LogDevice + include Period + + attr_reader :dev + attr_reader :filename + include MonitorMixin + + def initialize( + log = nil, shift_age: nil, shift_size: nil, shift_period_suffix: nil, + binmode: false, reraise_write_errors: [], skip_header: false + ) + @dev = @filename = @shift_age = @shift_size = @shift_period_suffix = nil + @binmode = binmode + @reraise_write_errors = reraise_write_errors + @skip_header = skip_header + mon_initialize + set_dev(log) + set_file(shift_age, shift_size, shift_period_suffix) if @filename + end + + def write(message) + handle_write_errors("writing") do + synchronize do + if @shift_age and @dev.respond_to?(:stat) + handle_write_errors("shifting") {check_shift_log} + end + handle_write_errors("writing") {@dev.write(message)} + end + end + end + + def close + begin + synchronize do + @dev.close rescue nil + end + rescue Exception + @dev.close rescue nil + end + end + + def reopen(log = nil, shift_age: nil, shift_size: nil, shift_period_suffix: nil, binmode: nil) + # reopen the same filename if no argument, do nothing for IO + log ||= @filename if @filename + @binmode = binmode unless binmode.nil? + if log + synchronize do + if @filename and @dev + @dev.close rescue nil # close only file opened by Logger + @filename = nil + end + set_dev(log) + set_file(shift_age, shift_size, shift_period_suffix) if @filename + end + end + self + end + + private + + # :stopdoc: + + MODE = File::WRONLY | File::APPEND + # TruffleRuby < 24.2 does not have File::SHARE_DELETE + if File.const_defined? :SHARE_DELETE + MODE_TO_OPEN = MODE | File::SHARE_DELETE | File::BINARY + else + MODE_TO_OPEN = MODE | File::BINARY + end + MODE_TO_CREATE = MODE_TO_OPEN | File::CREAT | File::EXCL + + def set_dev(log) + if log.respond_to?(:write) and log.respond_to?(:close) + @dev = log + if log.respond_to?(:path) and path = log.path + if File.exist?(path) + @filename = path + end + end + else + @dev = open_logfile(log) + @filename = log + end + end + + def set_file(shift_age, shift_size, shift_period_suffix) + @shift_age = shift_age || @shift_age || 7 + @shift_size = shift_size || @shift_size || 1048576 + @shift_period_suffix = shift_period_suffix || @shift_period_suffix || '%Y%m%d' + + unless @shift_age.is_a?(Integer) + base_time = @dev.respond_to?(:stat) ? @dev.stat.mtime : Time.now + @next_rotate_time = next_rotate_time(base_time, @shift_age) + end + end + + if MODE_TO_OPEN == MODE + def fixup_mode(dev) + dev + end + else + def fixup_mode(dev) + return dev if @binmode + dev.autoclose = false + old_dev = dev + dev = File.new(dev.fileno, mode: MODE, path: dev.path) + old_dev.close + PathAttr.set_path(dev, filename) if defined?(PathAttr) + dev + end + end + + def open_logfile(filename) + begin + dev = File.open(filename, MODE_TO_OPEN) + rescue Errno::ENOENT + create_logfile(filename) + else + dev = fixup_mode(dev) + dev.sync = true + dev.binmode if @binmode + dev + end + end + + def create_logfile(filename) + begin + logdev = File.open(filename, MODE_TO_CREATE) + logdev.flock(File::LOCK_EX) + logdev = fixup_mode(logdev) + logdev.sync = true + logdev.binmode if @binmode + add_log_header(logdev) unless @skip_header + logdev.flock(File::LOCK_UN) + logdev + rescue Errno::EEXIST + # file is created by another process + open_logfile(filename) + end + end + + def handle_write_errors(mesg) + yield + rescue *@reraise_write_errors + raise + rescue + warn("log #{mesg} failed. #{$!}") + end + + def add_log_header(file) + file.write( + "# Logfile created on %s by %s\n" % [Time.now.to_s, Logger::ProgName] + ) if file.size == 0 + end + + def check_shift_log + if @shift_age.is_a?(Integer) + # Note: always returns false if '0'. + if @filename && (@shift_age > 0) && (@dev.stat.size > @shift_size) + lock_shift_log { shift_log_age } + end + else + now = Time.now + if now >= @next_rotate_time + @next_rotate_time = next_rotate_time(now, @shift_age) + lock_shift_log { shift_log_period(previous_period_end(now, @shift_age)) } + end + end + end + + def lock_shift_log + retry_limit = 8 + retry_sleep = 0.1 + begin + File.open(@filename, MODE_TO_OPEN) do |lock| + lock.flock(File::LOCK_EX) # inter-process locking. will be unlocked at closing file + if File.identical?(@filename, lock) and File.identical?(lock, @dev) + yield # log shifting + else + # log shifted by another process (i-node before locking and i-node after locking are different) + @dev.close rescue nil + @dev = open_logfile(@filename) + end + end + true + rescue Errno::ENOENT + # @filename file would not exist right after #rename and before #create_logfile + if retry_limit <= 0 + warn("log rotation inter-process lock failed. #{$!}") + else + sleep retry_sleep + retry_limit -= 1 + retry_sleep *= 2 + retry + end + end + rescue + warn("log rotation inter-process lock failed. #{$!}") + end + + def shift_log_age + (@shift_age-3).downto(0) do |i| + if FileTest.exist?("#{@filename}.#{i}") + File.rename("#{@filename}.#{i}", "#{@filename}.#{i+1}") + end + end + shift_log_file("#{@filename}.0") + end + + def shift_log_period(period_end) + suffix = period_end.strftime(@shift_period_suffix) + age_file = "#{@filename}.#{suffix}" + if FileTest.exist?(age_file) + # try to avoid filename crash caused by Timestamp change. + idx = 0 + # .99 can be overridden; avoid too much file search with 'loop do' + while idx < 100 + idx += 1 + age_file = "#{@filename}.#{suffix}.#{idx}" + break unless FileTest.exist?(age_file) + end + end + shift_log_file(age_file) + end + + def shift_log_file(shifted) + stat = @dev.stat + @dev.close rescue nil + File.rename(@filename, shifted) + @dev = create_logfile(@filename) + mode, uid, gid = stat.mode, stat.uid, stat.gid + begin + @dev.chmod(mode) if mode + mode = nil + @dev.chown(uid, gid) + rescue Errno::EPERM + if mode + # failed to chmod, probably nothing can do more. + elsif uid + uid = nil + retry # to change gid only + end + end + return true + end + end +end + +File.open(__FILE__) do |f| + File.new(f.fileno, autoclose: false, path: "").path +rescue IOError + module PathAttr # :nodoc: + attr_reader :path + + def self.set_path(file, path) + file.extend(self).instance_variable_set(:@path, path) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/period.rb b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/period.rb new file mode 100644 index 00000000..a0359def --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/period.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +class Logger + module Period + module_function + + SiD = 24 * 60 * 60 + + def next_rotate_time(now, shift_age) + case shift_age + when 'daily', :daily + t = Time.mktime(now.year, now.month, now.mday) + SiD + when 'weekly', :weekly + t = Time.mktime(now.year, now.month, now.mday) + SiD * (7 - now.wday) + when 'monthly', :monthly + t = Time.mktime(now.year, now.month, 1) + SiD * 32 + return Time.mktime(t.year, t.month, 1) + when 'now', 'everytime', :now, :everytime + return now + else + raise ArgumentError, "invalid :shift_age #{shift_age.inspect}, should be daily, weekly, monthly, or everytime" + end + if t.hour.nonzero? or t.min.nonzero? or t.sec.nonzero? + hour = t.hour + t = Time.mktime(t.year, t.month, t.mday) + t += SiD if hour > 12 + end + t + end + + def previous_period_end(now, shift_age) + case shift_age + when 'daily', :daily + t = Time.mktime(now.year, now.month, now.mday) - SiD / 2 + when 'weekly', :weekly + t = Time.mktime(now.year, now.month, now.mday) - (SiD * now.wday + SiD / 2) + when 'monthly', :monthly + t = Time.mktime(now.year, now.month, 1) - SiD / 2 + when 'now', 'everytime', :now, :everytime + return now + else + raise ArgumentError, "invalid :shift_age #{shift_age.inspect}, should be daily, weekly, monthly, or everytime" + end + Time.mktime(t.year, t.month, t.mday, 23, 59, 59) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/severity.rb b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/severity.rb new file mode 100644 index 00000000..e96fb0d3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/severity.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +class Logger + # Logging severity. + module Severity + # Low-level information, mostly for developers. + DEBUG = 0 + # Generic (useful) information about system operation. + INFO = 1 + # A warning. + WARN = 2 + # A handleable error condition. + ERROR = 3 + # An unhandleable error that results in a program crash. + FATAL = 4 + # An unknown message that should always be logged. + UNKNOWN = 5 + + LEVELS = { + "debug" => DEBUG, + "info" => INFO, + "warn" => WARN, + "error" => ERROR, + "fatal" => FATAL, + "unknown" => UNKNOWN, + } + private_constant :LEVELS + + def self.coerce(severity) + if severity.is_a?(Integer) + severity + else + key = severity.to_s.downcase + LEVELS[key] || raise(ArgumentError, "invalid log level: #{severity}") + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/version.rb b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/version.rb new file mode 100644 index 00000000..0d74beca --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/logger-1.7.0/lib/logger/version.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +class Logger + VERSION = "1.7.0" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/.autotest b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/.autotest new file mode 100644 index 00000000..b6fbce53 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/.autotest @@ -0,0 +1,34 @@ +# -*- ruby -*- + +require 'autotest/restart' +require 'autotest/rcov' if ENV['RCOV'] + +Autotest.add_hook :initialize do |at| + at.testlib = 'minitest/autorun' + + bench_tests = %w(TestMinitestBenchmark) + mock_tests = %w(TestMinitestMock TestMinitestStub) + spec_tests = %w(TestMinitestReporter TestMetaStatic TestMeta + TestSpecInTestCase) + unit_tests = %w(TestMinitestGuard TestMinitestRunnable + TestMinitestRunner TestMinitestTest TestMinitestUnit + TestMinitestUnitInherited TestMinitestUnitOrder + TestMinitestUnitRecording TestMinitestUnitTestCase) + + { + bench_tests => "test/minitest/test_minitest_benchmark.rb", + mock_tests => "test/minitest/test_minitest_mock.rb", + spec_tests => "test/minitest/test_minitest_reporter.rb", + unit_tests => "test/minitest/test_minitest_unit.rb", + }.each do |klasses, file| + klasses.each do |klass| + at.extra_class_map[klass] = file + end + end + + at.add_exception 'coverage.info' + at.add_exception 'coverage' +end + +# require 'autotest/rcov' +# Autotest::RCov.command = 'rcov_info' diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/History.rdoc b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/History.rdoc new file mode 100644 index 00000000..c6e8946a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/History.rdoc @@ -0,0 +1,1690 @@ +=== 5.25.5 / 2025-03-12 + +* 4 bug fixes: + + * Bumped minimum ruby to 2.7. + * Fixed expectation docs for must/wont_pattern_match. (jaredcwhite) + * Reorder Minitest::Test.ancestors to allow reaching Minitest::Assertions#skipped? (Edouard-chin) + * Update the ruby and rails compatibility tables. (bquorning) + +=== 5.25.4 / 2024-12-03 + +* 1 bug fix: + + * Fix for must_verify definition if only requiring minitest/mock (but why?). + +=== 5.25.3 / 2024-12-03 + +* 5 bug fixes: + + * Fixed assert_mock to fail instead of raise on unmet mock expectations. + * Fixed assert_mock to take an optional message argument. + * Fixed formatting of unmet mock expectation messages. + * Fixed missing must_verify expectation to match assert_mock. + * minitest/pride: Fixed to use true colors with *-direct terminals (bk2204) + +=== 5.25.2 / 2024-11-21 + +* 4 bug fixes: + + * Include class name in spec name. (thomasmarshall) + * Fixed 'redefining object_id' warning from ruby 3.4. (mattbrictson) + * Minitest top-level namespace no longer includes entire contents of README.rdoc. Too much! + * Refactored spec's describe to more cleanly determine the superclass and name + +=== 5.25.1 / 2024-08-16 + +* 2 bug fixes: + + * Fix incompatibility caused by minitest-hooks & rails invading minitest internals. + * Revert change from =~ to match? to allow for nil if $TERM undefined. + +=== 5.25.0 / 2024-08-13 + +* 2 minor enhancements: + + * Fixed some inefficiencies filtering and matching (mostly backtraces). + * Refactored siginfo handler to reduce runtime costs. Saved ~30%! + +* 5 bug fixes: + + * Added missing rdoc to get back to 100% coverage. + * Cleaning up ancient code checking for defined?(Encoding) and the like. + * Disambiguated some shadowed variables in minitest/compress. + * Fixed an ironic bug if using string-literals AND Werror. + * Improve description of test:slow task. (stomar) + +=== 5.24.1 / 2024-06-29 + +* 1 bug fix: + + * Fix the error message when an extension is invalid value. (y-yagi) + +=== 5.24.0 / 2024-06-18 + +* 2 minor enhancements: + + * Added Minitest.register_plugin. + * Extended plugin system to work with modules/classes for opt-out plugins. + +* 1 bug fix: + + * Removed anacronism, but allow load_plugins to exit gracefully if --disable=gems. + +=== 5.23.1 / 2024-05-21 + +* 1 bug fix: + + * Fully qualify the Queue class to avoid conflicts with other libraries. (rafaelfranca) + +=== 5.23.0 / 2024-05-15 + +* 3 minor enhancements: + + * Added -Werror to raise on any warning output. (byroot) + * Added UnexpectedWarning as a failure summary type, added count to output if activated. + * Added minitest/manual_plugins.rb w/ new Minitest.load method. (tenderlove) + +* 2 bug fixes: + + * Allow empty_run! and reporter to display summary for empty runs. (zzak) + * Make test task verbose using either rake's -v or -t (was just -t). + +=== 5.22.3 / 2024-03-13 + +* 1 minor enhancement: + + * MASSIVE improvement of minitest's pride plugin output: Frequencies doubled! Sine waves shifted!! Comments improved!!! Colors rotated!!!! (havenwood) + +* 3 bug fixes: + + * Improved wording on Minitest::Test#parallelize_me! to clarify it goes INSIDE your test class/describe. + * Minor changes to tests to pass when tests ran with extra flags (eg -p). + * Support Ruby 3.4's new error message format. (mame) + +=== 5.22.2 / 2024-02-07 + +* 1 bug fix: + + * Third time's a charm? Remember: 'ensure' is almost always the + wrong way to go (for results... it's great for cleaning up). + +=== 5.22.1 / 2024-02-06 + +* 1 bug fix: + + * Don't exit non-zero if no tests ran and no filter (aka, the test file is empty). + (I'm starting to think the exit 1 thing for @tenderlove was a mistake...) + +=== 5.22.0 / 2024-02-05 + +* 1 minor enhancement: + + * Added "did you mean" output if your --name filter matches nothing. (tenderlove) + +* 2 bug fixes: + + * Big cleanup of test filtering. Much prettier / more functional. + * Fix situation where Assertion#location can't find the location. (pftg) + +=== 5.21.2 / 2024-01-17 + +* 1 bug fix: + + * Fixed bug in Minitest::Compress#compress formatting w/ nested patterns. Now recurses properly. + +=== 5.21.1 / 2024-01-11 + +* 1 bug fix: + + * Rails' default backtrace filter can't currently work with caller_locations, so reverting back to caller. + +=== 5.21.0 / 2024-01-11 + +* 10 minor enhancements: + + * Add include_all kw arg to assert_respond_to and refute_respond_to. + * Added --quiet flag to skip ProgressReporter (prints the dots). Minor speedup. + * Added Minitest::Compress#compress and added it to UnexpectedError. + * Added ability to initialize BacktraceFilter w/ custom regexp. + * Filter failure backtraces using backtrace_filter before calculating location. (thomasmarshall) + * Make BacktraceFilter#filter compatible with locations (still compares strings). + * Optimized Assertion#location ~30%. + * Output relative paths for all failures/errors/backtraces. + * Refactored location information in assertions, now using locations. + * Removed thread and mutex_m dependencies. (hsbt, eregon) + +* 2 bug fixes: + + * Drop undocumented bt arg in #skip. Dunno why that ever happened, prolly for testing? + * Fix mock to work with ruby debugger enabled. (keithlayne) + +=== 5.20.0 / 2023-09-06 + +* 1 minor enhancement: + + * Optionally allow autorun exit hook to remain active in forked child. (casperisfine) + +=== 5.19.0 / 2023-07-26 + +* 2 minor enhancements: + + * Add metadata lazy accessor to Runnable / Result. (matteeyah) + * Only load minitest/unit (aka ancient MiniTest compatibility layer) if \ENV[\"MT_COMPAT\"] + +* 1 bug fix: + + * Minitest::TestTask enthusiastically added itself to default. (ParadoxV5) + +=== 5.18.1 / 2023-06-16 + +* 3 bug fixes: + + * Avoid extra string allocations when filtering tests. (tenderlove) + * Only mention deprecated \ENV[\'N\'] if it is an integer string. + * Push up test_order to Minitest::Runnable to fix minitest/hell. (koic) + +=== 5.18.0 / 2023-03-04 + +* 2 major enhancements: + + * Added assert_pattern & refute_pattern for pattern matching. (flavorjones) + * Added matching must_pattern_match & wont_pattern_match to minitest/spec. + +* 1 bug fix: + + * Support the new message format of NameError in Ruby 3.3 (mame) + +=== 5.17.0 / 2022-12-31 + +* 1 minor enhancement: + + * Refactor setup hooks into a SETUP_METHODS constant. (MSP-Greg) + +* 3 bug fixes: + + * Fix kwargs for Mock calls to delegator. (blowmage) + * Fix kwargs for expectations. (bobmazanec, blowmage) + * Remove check for .b method. (tenderlove) + +=== 5.16.3 / 2022-08-17 + +* 2 bug fixes: + + * Fixed exception sanitization by removing TypeError restriction on rescue. + * Use A instead of deprecated TESTOPTS in rake test:slow. (davidstosik) + +=== 5.16.2 / 2022-07-03 + +* 4 bug fixes: + + * Added MT_KWARGS_HACK kludge for stub to deal with ruby 2.7 kwargs nastiness. (tsugimoto) + * In #expect, pop Hash class from args if $MT_KWARGS_HACK. (casperisfine) + * In above scenario, set expected kwargs (as Objects) based on actual kwargs. + * Nuke ivars if exception fails to marshal twice (eg better_errors). (irphilli) + +=== 5.16.1 / 2022-06-20 + +* 2 bug fixes: + + * Apparently adding real kwarg support to mocks/stubs broke some code. Fixed. + * Use `MT_KWARGS_HACK=1` to activate the kludgy kwargs support w/ caveats. + * Clarified some doco wrt the block on #stub. + +=== 5.16.0 / 2022-06-14 + +* 2 major enhancements: + + * Added Minitest::TestTask. + * Dropping ruby 2.2 - 2.5. 2.6 is DTM soon too. + +* 11 minor enhancements: + + * Added --show-skips option to show skips at end of run but not require --verbose. (MSP-Greg) + * Added Minitest.seed, the random seed used by the run. + * Calling `srand Minitest.seed` before all shuffles to ensure determinism. + * Extended #stub to handle kwargs for both block and call args. (SampsonCrowley) + * Extended Mock#__call to display kwargs. + * Extended Mock#expect to record kwargs. + * Extended Mock#method_missing to take kwargs & compare them against expected. + * Mock#method_missing displays better errors on arity mismatch. + * Removed minor optimization removing empty suites before run. + * Simplified test randomization (test order will change even with fixed seed). + * assert_match now returns the MatchData on success. (Nakilon) + +* 3 bug fixes: + + * (Re)Fixed marshalling of exceptions, neutering them in 2 passes. + * Fixed more problems with rdoc. + * Had to patch up mock and stub to deal with <=2.7 kwargs oddities + +=== 5.15.0 / 2021-12-14 + +* 1 major enhancement: + + * assert_throws returns the value returned, if any. (volmer) + +* 3 minor enhancements: + + * Added -S option to skip reporting of certain types of output + * Enable Ruby deprecation warnings by default. (casperisfine) + * Use Etc.nprocessors by default in order to maximize cpu usage. (tonytonyjan) + +* 6 bug fixes: + + * Close then unlink tempfiles on Windows. (nobu) + * Fixed #skip_until for windows paths. (MSP-Greg) + * Fixed a bunch of tests for jruby and windows. (MSP-Greg) + * Fixed marshalling of specs if they error. (tenderlove, jeremyevans, et al) + * Updated deprecation message for block expectations. (blowmage) + * Use Kernel.warn directly in expectations in case CUT defines their own warn. (firien) + +=== 5.14.4 / 2021-02-23 + +* 1 bug fix: + + * Fixed deprecation warning using stub with methods using keyword arguments. (Nakilon) + +=== 5.14.3 / 2021-01-05 + +* 1 bug fix: + + * Bumped require_ruby_version to < 4 (trunk = 3.1). + +=== 5.14.2 / 2020-08-31 + +* 1 bug fix: + + * Bumped ruby version to include 3.0 (trunk). + +=== 5.14.1 / 2020-05-15 + +* 3 minor enhancements: + + * Minitest.filter_backtrace returns original backtrace if filter comes back empty. + * Minitest::BacktraceFilter now returns entire backtrace if $MT_DEBUG set in env. + * Return true on a successful refute. (jusleg) + +* 1 bug fix: + + * Fixed expectation doco to not use global expectations. + +=== 5.14.0 / 2020-01-11 + +* 2 minor enhancements: + + * Block-assertions (eg assert_output) now error if raised inside the block. (casperisfine) + * Changed assert_raises to only catch Assertion since that covers Skip and friends. + +* 3 bug fixes: + + * Added example for value wrapper with block to Expectations module. (stomar) + * Fixed use of must/wont_be_within_delta on Expectation instance. (stomar) + * Renamed UnexpectedError#exception to #error to avoid problems with reraising. (casperisfine) + +=== 5.13.0 / 2019-10-29 + +* 9 minor enhancements: + + * Added Minitest::Guard#osx? + * Added examples to documentation for assert_raises. (lxxxvi) + * Added expectations #path_must_exist and #path_wont_exist. Not thrilled with the names. + * Added fail_after(year, month, day, msg) to allow time-bombing after a deadline. + * Added skip_until(year, month, day, msg) to allow deferring until a deadline. + * Deprecated Minitest::Guard#maglev? + * Deprecated Minitest::Guard#rubinius? + * Finally added assert_path_exists and refute_path_exists. (deivid-rodriguez) + * Refactored and pulled Assertions#things_to_diff out of #diff. (BurdetteLamar) + +* 3 bug fixes: + + * Fix autorun bug that affects fork exit status in tests. (dylanahsmith/jhawthorn) + * Improved documentation for _/value/expect, especially for blocks. (svoop) + * Support new Proc#to_s format. (ko1) + +=== 5.12.2 / 2019-09-28 + +* 1 bug fix: + + * After chatting w/ @y-yagi and others, decided to lower support to include ruby 2.2. + +=== 5.12.1 / 2019-09-28 + +* 1 minor enhancement: + + * Added documentation for Reporter classes. (sshaw) + +* 3 bug fixes: + + * Avoid using 'match?' to support older ruby versions. (y-yagi) + * Fixed broken link to reference on goodness-of-fit testing. (havenwood) + * Update requirements in readme and Rakefile/hoe spec. + +=== 5.12.0 / 2019-09-22 + +* 8 minor enhancements: + + * Added a descriptive error if assert_output or assert_raises called without a block. (okuramasafumi) + * Changed mu_pp_for_diff to make having both \n and \\n easier to debug. + * Deprecated $N for specifying number of parallel test runners. Use MT_CPU. + * Deprecated use of global expectations. To be removed from MT6. + * Extended Assertions#mu_pp to encoding validity output for strings to improve diffs. + * Extended Assertions#mu_pp to output encoding and validity if invalid to improve diffs. + * Extended Assertions#mu_pp_for_diff to make escaped newlines more obvious in diffs. + * Fail gracefully when expectation used outside of `it`. + +* 3 bug fixes: + + * Check \option[:filter] klass before match. Fixes 2.6 warning. (y-yagi) + * Fixed Assertions#diff from recalculating if set to nil + * Fixed spec section of readme to not use deprecated global expectations. (CheezItMan) + +=== 5.11.3 / 2018-01-26 + +* 1 bug fix: + + * Pushed #error? up to Reportable module. (composerinteralia) + +=== 5.11.2 / 2018-01-25 + +* 1 minor enhancement: + + * Reversed Test < Result. Back to < Runnable and using Reportable for shared code. + +* 2 bug fixes: + + * Fixed Result#location for instances of Test. (alexisbernard) + * Fixed deprecation message for Runnable#marshal_dump. (y-yagi) + +=== 5.11.1 / 2018-01-02 + +* 1 bug fix: + + * Fixed Result (a superclass of Test) overriding Runnable's name accessors. (y-yagi, MSP-Greg) + +=== 5.11.0 / 2018-01-01 + +* 2 major enhancements: + + * Added Minitest::Result and Minitest::Result.from(runnable). + * Changed Minitest::Test to subclass Result and refactored methods up. + +* 7 minor enhancements: + + * Added --no-plugins and MT_NO_PLUGINS to bypass MT plugin autoloading. Helps with bad actors installed globally. + * Added bench_performance_{logarithmic,power} for spec-style benchmarks. (rickhull) + * Added deprecation warning for Runnable#marshal_dump. + * Minitest.run_one_method now checks for instance of Result, not exact same class. + * Minitest::Test.run returns a Result version of self, not self. + * ProgressReporter#prerecord now explicitly prints klass.name. Allows for fakers. + +* 4 bug fixes: + + * Object.stub no longer calls the passed block if stubbed with a callable. + * Object.stub now passes blocks down to the callable result. + * Pushed Minitest::Test#time & #time_it up to Runnable. + * Test nil equality directly in assert_equal. Fixes #679. (voxik) + +=== 5.11.0b1 / 2017-12-20 + +* 2 major enhancements: + + * Added Minitest::Result and Minitest::Result.from(runnable). + * Changed Minitest::Test to subclass Result and refactored methods up. + +* 6 minor enhancements: + + * Added --no-plugins and MT_NO_PLUGINS to bypass MT plugin autoloading. Helps with bad actors installed globally. + * Added bench_performance_{logarithmic,power} for spec-style benchmarks. (rickhull) + * Minitest.run_one_method now checks for instance of Result, not exact same class. + * Minitest::Test.run returns a Result version of self, not self. + * ProgressReporter#prerecord now explicitly prints klass.name. Allows for fakers. + * Removed Runnable.marshal_dump/load. + +* 4 bug fixes: + + * Object.stub no longer calls the passed block if stubbed with a callable. + * Object.stub now passes blocks down to the callable result. + * Pushed Minitest::Test#time & #time_it up to Runnable. + * Test nil equality directly in assert_equal. Fixes #679. (voxik) + +=== 5.10.3 / 2017-07-21 + +* 1 minor enhancement: + + * Extended documentation for Mock#expect for multiple calls to mock object. (insti) + +* 2 bug fixes: + + * Finished off missing doco. + * Fixed verbose output on parallelize_me! classes. (chanks) + +=== 5.10.2 / 2017-05-09 + +* 1 minor enhancement: + + * Added suggestion in minitest/hell to install minitest/proveit. + +* 7 bug fixes: + + * Expand MT6 to Minitest 6. (xaviershay) + * Fixed location of assert_send deprecation. (rab) + * Fixed location of nil assert_equal deprecation to work with expectations. (jeremyevans) + * Fixed minitest/hell to use parallelize_me! (azul) + * Made deprecation use warn so -W0 will silence it. + * Workaround for rdoc nodoc generation bug that totally f'd up minitest doco. (Paxa) + * Write aggregated_results directly to the IO object to avoid mixed encoding errors. (tenderlove) + +=== 5.10.1 / 2016-12-01 + +* 1 bug fix: + + * Added a hack/kludge to deal with missing #prerecord on reporters that aren't properly subclassing AbstractReporter (I'm looking at you minitest-reporters) + +=== 5.10.0 / 2016-11-30 + +* 1 major enhancement: + + * Deprecated ruby 1.8, 1.9, possibly 2.0, assert_send, & old MiniTest namespace. + +* 3 minor enhancements: + + * Warn if assert_equal expects a nil. This will fail in minitest 6+. (tenderlove) + * Added AbstractReporter#prerecord and extended ProgressReporter and CompositeReporter to use it. + * Minor optimization: remove runnables with no runnable methods before run. + +* 3 bug fixes: + + * Fix assert_throw rescuing any NameError and ArgumentError. (waldyr) + * Clean up (most of the) last remaining vestiges of minitest/unit. + * 2.4: removed deprecation warnings when referring to Fixnum. + +=== 5.9.1 / 2016-09-25 + +* 2 bug fixes: + + * Re-release to refresh gem certificate signing. ugh. + * Fixed hoe/minitest to not augment load path if we're actually testing minitest. + +=== 5.9.0 / 2016-05-16 + +* 8 minor enhancements: + + * Added Minitest.info_signal accessors to customize signal for test run info. (nate) + * Added assert_mock to make it more clear that you're testing w/ them. + * Added negative filter by test name. (utilum) + * Added warning to README that 1.8 and 1.9 support will be dropped in minitest 6. + * Automatically activate minitest/hell if $MT_HELL is defined. + * Improved default error messages for assert and refute. (bhenderson) + * minitest/hell now tries to require minitest/proveit + * mu_pp for strings prints out non-standard encodings to improve assert_equal diffs. + +* 1 bug fix: + + * Removed Interrupt from PASSTHROUGH_EXCEPTIONS (already handled). (waldyr) + +=== 5.8.5 / 2016-09-25 + +* 2 bug fixes: + + * Re-release to refresh gem certificate signing. ugh. + * Fixed hoe/minitest to not augment load path if we're actually testing minitest. + +=== 5.8.4 / 2016-01-21 + +* 1 bug fix: + + * Allow Minitest::Assertion to pass through assert_raises so inner failures are dealt with first. + +=== 5.8.3 / 2015-11-17 + +* 1 minor enhancement: + + * Added extra note about mocks and threads to readme. (zamith) + +* 1 bug fix: + + * Fixed bug in Mock#verify. (pithub/zamith) + +=== 5.8.2 / 2015-10-26 + +* 1 bug fix: + + * Fixed using parallelize_me! and capture_io (or any locking io). (arlt/tenderlove) + +=== 5.8.1 / 2015-09-23 + +* 1 minor enhancement: + + * Refactor assert_raises to be cleaner and to pass SystemExit and SignalException. (bhenderson) + +=== 5.8.0 / 2015-08-06 + +* 2 minor enhancements: + + * Add optional delegation mechanism to extend object with a mock. (zamith) + * Return early if there are no filtered methods. (jeremyevans) + +* 1 bug fix: + + * Don't extend io with pride if io is not a tty. (toy) + +=== 5.7.0 / 2015-05-27 + +* 1 major enhancement: + + * assert_raises now matches subclasses of the expected exception types. (jeremyevans) + +* 3 minor enhancements: + + * Added :block type for minitest/spec's #infect_an_assertion. (jeremyevans) + * Inline verification error messages in minitest/mock for GC performance. (zamith) + * assert_raises defaults to RuntimeError if not specified. (jeremyevans) + +* 4 bug fixes: + + * Added 'class' to minitest/mock's overridden_methods list. (zamith) + * Added file/line to infect_an_assertion's class_eval call. (jeremyevans) + * Cleared UnexpectedError's mesg w/ generic string. + * Fixed non-proc-oriented expectations when used on proc target. (jeremyevans) + +=== 5.6.1 / 2015-04-27 + +* 2 bug fixes: + + * Added Minitest.clock_time and switched all Time.now to it. (tenderlove) + * Moved Minitest::Expectations#_ into Minitest::Spec::DSL. + +=== 5.6.0 / 2015-04-13 + +* 4 major enhancements: + + * Added Minitest::Expectation value monad. + * Added Minitest::Expectations#_ that returns an Expectation. Aliased to value. + * All expectations are added to Minitest::Expectation. + * At some point, the methods on Object will be deprecated and then removed. + +* 4 minor enhancements: + + * Added a note about bundle exec pitfall in ruby 2.2+. (searls) + * Lazily start the parallel executor. (tenderlove) + * Make mocks more debugger-friendly (edward) + * Print out the current test run on interrupt. (riffraff) + +* 3 bug fixes: + + * Fix failing test under Windows. (kimhmadsen) + * Record mocked calls before they happen so mocks can raise exceptions easier (tho I'm not a fan). (corecode) + * Tried to clarify mocks vs stubs terminology better. (kkirsche) + +=== 5.5.1 / 2015-01-09 + +* 1 bug fix: + + * Fixed doco problems. (zzak) + +=== 5.5.0 / 2014-12-12 // mri 2.2.0 (as a real gem) + +* 1 minor enhancement: + + * Allow seed to be given via ENV for rake test loader sadness: eg rake SEED=42. + +=== 5.4.3 / 2014-11-11 + +* 2 bug fixes: + + * Clarified requirements for ruby are now 1.8.7 or better. + * Force encode error output in case mal-encoded exception is raised. (jasonrclark) + +=== 5.4.2 / 2014-09-26 + +* 2 minor enhancements: + + * Extract teardown method list. + * Thanks to minitest-gcstats got a 5-10% speedup via reduced GC! + +=== 5.4.1 / 2014-08-28 + +* 1 bug fix: + + * Fixed specs hidden by nesting/ordering bug (blowmage/apotonick) + +=== 5.4.0 / 2014-07-07 + +* 2 minor enhancements: + + * Kernel#describe extended to splat additional_desc. + * Spec#spec_type extended to take a splat of additional items, passed to matcher procs. + +* 1 bug fix: + + * minitest/spec should require minitest/test, not minitest/unit. (doudou) + +=== 5.3.5 / 2014-06-17 + +* 1 minor enhancement: + + * Spit and polish (mostly spit). + +=== 5.3.4 / 2014-05-15 + +* 1 minor enhancement: + + * Test classes are randomized before running. (judofyr) + +=== 5.3.3 / 2014-04-14 + +* 1 bug fix: + + * Fixed using expectations w/ DSL in Test class w/o describe. (blowmage+others) + +=== 5.3.2 / 2014-04-02 + +* 1 bug fix: + + * Fixed doco on Assertions.assertions. (xaviershay) + +=== 5.3.1 / 2014-03-14 + +* 1 minor enhancement: + + * Modified verbage on bad 'let' names to be more helpful. (Archytaus) + +* 1 bug fix: + + * Fixed 2 cases still using MiniTest. (mikesea) + +=== 5.3.0 / 2014-02-25 + +* 1 minor enhancement: + + * Mocked methods can take a block to verify state. Seattle.rb 12 bday present from ernie! Thanks!! + +=== 5.2.3 / 2014-02-10 + +* 1 bug fix: + + * Fixed Spec#let check to allow overriding of other lets. (mvz) + +=== 5.2.2 / 2014-01-22 + +* 1 minor enhancement: + + * Spec#let raises ArgumentError if you override _any_ instance method (except subject). (rynr) + +* 1 bug fix: + + * Fixed up benchmark spec doco and added a test to demonstrate. (bhenderson) + +=== 5.2.1 / 2014-01-07 + +* 1 bug fix: + + * Properly deal with horrible mix of runtime load errors + other at_exit handlers. (dougo/chqr) + +=== 5.2.0 / 2013-12-13 + +* 1 minor enhancement: + + * Change expectations to allow calling most on procs (but not calling the proc). (bhenderson+others) + +=== 5.1.0 / 2013-12-05 + +* 1 minor enhancement: + + * Use a Queue for scheduling parallel tests. (tenderlove) + +* 1 bug fix: + + * Fixed misspelling in doco. (amatsuda) + +=== 5.0.8 / 2013-09-20 + +* 1 bug fix: + + * Fixed siginfo handler by rearranging reporters and fixing to_s. (tenderlove) + +=== 5.0.7 / 2013-09-05 + +* 2 minor enhancements: + + * Added clarification about the use of thread local variables in expectations. (jemc) + * Added extra message about skipped tests, if any. Disable globally with $MT_NO_SKIP_MSG. + +* 2 bug fixes: + + * Only require minitest, not minitest/autorun in pride_plugin. (judofyr) + * Require rubygems in load_plugins in case you're not using minitest/autorun. + +=== 5.0.6 / 2013-06-28 + +* 3 minor enhancements: + + * Allow stub to pass args to blocks. (swindsor) + * Improved warning message about minitest/autorun to address 1.9's minitest/autorun. + * Made minitest/test require minitest as needed. For lib writers. (erikh) + +* 1 bug fix: + + * Fixed missing require in minitest/test. (erikh) + +=== 4.7.5 / 2013-06-21 // mri 2.1.1 + +* 2 bug fixes: + + * Fix Spec#describe_stack to be thread local. + * Fix multithreaded test failures by defining Time local to mock test namespace + +=== 5.0.5 / 2013-06-20 + +* 6 bug fixes: + + * DOH! Fixed the rest of the new casing on Minitest. (splattael) + * Fixed typo on minitest/mock rdoc. (mrgilman/guiceolin) + * Make Spec::DSL.describe_stack thread local to avoid failing on my own tests. + * Make a fake Time.now local to the tests so they won't interfere with real reporter timings. + * Make everything mockable by wrapping all 'special' methods in a smarter wrapper. (bestie) + * Raise ArgumentError if let name starts with 'test'. (johnmaxwell) + +=== 5.0.4 / 2013-06-07 + +* 5 minor enhancements: + + * Added AbstractReporter, defining required Reporter API to quack properly. + * Added doco for writing reporters. + * Refactored Reporter into ProgressReporter and SummaryReporter. (idea: phiggins, code:me+scotch) + * Refactored SummaryReporter pushing up to StatisticsReporter. (phiggins) + * Removed Reporter#run_and_report... cleaner, but doesn't "fit" in the API. + +=== 5.0.3 / 2013-05-29 + +* 4 minor enhancements: + + * Added Runnable.with_info_handler and Runnable.on_signal. + * Moved io.sync restore to Reporter#run_and_report. + * Refactored inner loop of Reporter#report to #to_s. Callable for status updates. + * Restored MT4's mid-run report (^t). (tenderlove). + +=== 5.0.2 / 2013-05-20 + +* 3 bug fixes: + + * Gem.find_files is smarter than I remember... cause I wrote it that way. *sigh* I'm getting old. + * Pride wasn't doing puts through its #io. (tmiller/tenderlove) + * Replaced Runnable#dup and Test#dup with marshal_dump/load. Too many problems cropping up on untested rails code. (tenderlove/rubys) + +=== 5.0.1 / 2013-05-14 + +* 2 bug fixes: + + * Documented Assertions' need for @assertions to be defined by the includer. + * Only load one plugin version per name. Tries for latest. + +=== 5.0.0 / 2013-05-10 + +Oh god... here we go... + +Minitest 5: + +* 4 deaths in the family: + + * MiniTest.runner is dead. No more manager objects. + * MiniTest::Unit#record is dead. Use a Reporter instance instead. + * MiniTest::Unit._run_* is dead. Runnable things are responsible for their own runs. + * MiniTest::Unit.output is dead. No more centralized IO. + +* 12 major (oft incompatible) changes: + + * Renamed MiniTest to Minitest. Your pinkies will thank me. (aliased to MiniTest) + * Removed MiniTest::Unit entirely. No more manager objects. + * Added Minitest::Runnable. Everything minitest can run subclasses this. + * Renamed MiniTest::Unit::TestCase to Minitest::Test (subclassing Runnable). + * Added Minitest::Benchmark. + * Your benchmarks need to move to their own subclass. + * Benchmarks using the spec DSL have to have "Bench" somewhere in their describe. + * MiniTest::Unit.after_tests moved to Minitest.after_run + * MiniTest::Unit.autorun is now Minitest.autorun. Just require minitest/autorun pls. + * Removed ParallelEach#grep since it isn't used anywhere. + * Renamed Runnable#__name__ to Runnable#name (but uses @NAME internally). + * Runnable#run needs to return self. Allows for swapping of results as needed. + +* 8 minor moves: + + * Moved Assertions module to minitest/assertions.rb + * Moved Expectations module to minitest/expectations.rb + * Moved Test to minitest/test.rb + * Moved everything else in minitest/unit.rb to minitest.rb + * minitest/unit.rb is now just a small (user-test only) compatibility layer. + * Moved most of minitest/pride into minitest/pride_plugin. + * minitest/pride now just activates pride. + * Moved ParallelEach under Minitest. + +* 9 additions: + + * Added a plugin system that can extend command-line options. + * Added Minitest.extensions. + * Added Minitest.reporter (only available during startup). + * Added Minitest.run(args). This is the very top of any Minitest run. + * Added Minitest::Reporter. Everything minitest can report goes through here. + * Minitest.reporter is a composite so you can add your own. + * Added Minitest::CompositeReporter. Much easier to extend with your own reporters. + * Added UnexpectedError, an Assertion subclass, to wrap up errors. + * Minitest::Test#run is now freakin' beautiful. 47 -> 17 loc + +* 11 other: + + * Removed Object.infect_with_assertions (it was already dead code). + * Runnables are responsible for knowing their result_code (eg "." or "F"). + * Minitest.autorun now returns boolean, not exit code. + * Added FAQ entry for extending via modules. (phiggins) + * Implement Runnable#dup to cleanse state back to test results. Helps with serialization. pair:tenderlove + * Moved ParallelEach under Minitest. + * Runnable#run needs to return self. Allows for swapping of results as needed. + * Minitest.init_plugins passes down options. + * Minitest.load_plugins only loads once. + * Fixed minitest/pride to work with rake test loader again. (tmiller) + * Added count/size to ParallelEach to fix use w/in stdlib's test/unit. :( (btaitelb) + +* 5 voodoo: + + * Removed mutex from minitest.rb (phiggins) + * Removed mutex from test.rb (phiggins) + * Removed Minitest::Reporter.synchronize (phiggins) + * Removed Minitest::Test.synchronize (phiggins) + * Upon loading minitest/parallel_each, record, capture_io and capture_subprocess_io are doped with synchronization code. (phiggins) + +=== 4.7.4 / 2013-05-01 + +This is probably the last release of the 4.x series. It will be merged +to ruby and will be put into maintenance mode there. + +I'm not set in stone on this, but at this point further development of +minitest (5+) will be gem-only. It is just too hard to work w/in +ruby-core w/ test-unit compatibility holding minitest development +back. + +* 2 minor enhancements: + + * Added count/size to ParallelEach to fix use w/in stdlib's test/unit. :( (btaitelb) + * Allow disabling of info_signal handler in runner. (erikh) + +=== 4.7.3 / 2013-04-20 + +* 1 bug fix: + + * Reverted stubbing of module methods change. Stub the user, not the impl. (ab9/tyabe) + +=== 4.7.2 / 2013-04-18 + +* 2 bug fixes: + + * Fixed inconsistency in refute_in_delta/epsilon. I double negatived my logic. (nettsundere) + * Fixed stubbing of module methods (eg Kernel#sleep). (steveklabnik) + +=== 4.7.1 / 2013-04-09 + +* 1 minor enhancement: + + * Added FAQ section to README + +* 1 bug fix: + + * Fixed bug where guard runs tests bypassing minitest/autorun and an ivar isn't set right. (darrencauthon) + +=== 4.7.0 / 2013-03-18 + +* 1 major enhancement: + + * Refactored MiniTest::Spec into MiniTest::Spec::DSL. + +* 1 bug fix: + + * Removed $DEBUG handler that detected when test/unit and minitest were both loaded. (tenderlove) + +=== 4.6.2 / 2013-02-27 + +* 1 minor enhancement: + + * Change error output to match Class#method, making it easier to use -n filter. + +=== 4.6.1 / 2013-02-14 + +* 1 bug fix: + + * Fixed an option processing bug caused by test/unit's irresponsibly convoluted code. (floehopper) + +=== 4.6.0 / 2013-02-07 + +* 3 major enhancements: + + * Removed ::reset_setup_teardown_hooks + * Removed the long deprecated assert_block + * Removed the long deprecated lifecycle hooks: add_(setup|teardown)_hook + +* 1 minor enhancement: + + * Allow filtering tests by suite name as well as test name. (lazyatom) + +* 2 bug fixes: + + * Made hex handling (eg object_ids) in mu_pp_for_diff more specific. (maxim) + * nodoc top-level module. (zzak) + +=== 4.5.0 / 2013-01-22 + +* 1 major enhancement: + + * Rearranged minitest/unit.rb so NO parallelization code is loaded/used until you opt-in. + +* 4 minor enhancements: + + * Added TestCase#skipped? for teardown guards + * Added maglev? guard + * Document that record can be sent twice if teardown fails or errors (randycoulman) + * Errors in teardown are now recorded. (randycoulman) + +* 3 bug fixes: + + * Added hacks and skips to get clean test runs on maglev + * Modified float tests for maglev float output differences. Not sure this is right. Not sure I care. + * Test for existance of diff.exe instead of assuming they have devkit. (blowmage/Cumbayah) + +=== 4.4.0 / 2013-01-07 + +* 3 minor enhancements: + + * Added fit_logarithic and assert_performance_logarithmic. (ktheory) + * Merge processed options so others can mess with defaults. (tenderlove) + * TestCase#message can now take another proc to defer custom message cost. (ordinaryzelig/bhenderson) + +* 1 bug fix: + + * TestCase#passed? now true if test is skipped. (qanhd) + +=== 4.3.3 / 2012-12-06 + +* 1 bug fix: + + * Updated information about stubbing. (daviddavis) + +=== 4.3.2 / 2012-11-27 // mri 2.0.0 + +* 1 minor enhancement: + + * Improved assert_equals error message to point you at #== of member objects. (kcurtin) + +=== 4.3.1 / 2012-11-23 + +* 1 bug fix: + + * Moved test_children to serial testcase to prevent random failures. + +=== 4.3.0 / 2012-11-17 + +* 4 minor enhancements: + + * Allow #autorun to run even if loaded with other test libs that call exit. (sunaku) + * Do not include Expectations in Object if $MT_NO_EXPECTATIONS is set (experimental?) + * Gave some much needed love to assert_raises. + * Mock#expect can take a block to custom-validate args. (gmoothart) + +=== 4.2.0 / 2012-11-02 + +* 4 major enhancements: + + * Added minitest/hell - run all your tests through the ringer! + * Added support for :parallel test_order to run test cases in parallel. + * Removed last_error and refactored runner code to be threadsafe. + * _run_suites now runs suites in parallel if they opt-in. + +* 4 minor enhancements: + + * Added TestCase#synchronize + * Added TestCase.make_my_diffs_pretty! + * Added TestCase.parallelize_me! + * Lock on capture_io for thread safety (tenderlove) + +=== 4.1.0 / 2012-10-05 + +* 2 minor enhancements: + + * Added skip example to readme. (dissolved) + * Extracted backtrace filter to object. (tenderlove) + +* 1 bug fix: + + * OMG I'm so dumb. Fixed access to deprecated hook class methods. I hate ruby modules. (route) + +=== 4.0.0 / 2012-09-28 + +* 1 major enhancement: + + * The names of a privately-used undocumented constants are Super Important™. + +* 1 minor enhancement: + + * Support stubbing methods that would be handled via method_missing. (jhsu) + +* 3 bug fixes: + + * Add include_private param to MiniTest::Mock#respond_to? (rf-) + * Fixed use of minitest/pride with --help. (zw963) + * Made 'No visible difference.' message more clear. (ckrailo) + +=== 3.5.0 / 2012-09-21 + +* 1 minor enhancement: + + * Added #capture_subprocess_io. (route) + +=== 3.4.0 / 2012-09-05 + +* 2 minor enhancements: + + * assert_output can now take regexps for expected values. (suggested by stomar) + * Clarified that ruby 1.9/2.0's phony gems cause serious confusion for rubygems. + +=== 3.3.0 / 2012-07-26 + +* 1 major enhancement: + + * Deprecated add_(setup|teardown)_hook in favor of (before|after)_(setup|teardown) [2013-01-01] + +* 4 minor enhancements: + + * Refactored deprecated hook system into a module. + * Refactored lifecycle hooks into a module. + * Removed after_setup/before_teardown + run_X_hooks from Spec. + * Spec#before/after now do a simple define_method and call super. DUR. + +* 2 bug fixes: + + * Fixed #passed? when used against a test that called flunk. (floehopper) + * Fixed rdoc bug preventing doco for some expectations. (stomar). + +=== 3.2.0 / 2012-06-26 + +* 1 minor enhancement: + + * Stubs now yield self. (peterhellberg) + +* 1 bug fix: + + * Fixed verbose test that only fails when run in verbose mode. mmmm irony. + +=== 3.1.0 / 2012-06-13 + +* 2 minor enhancements: + + * Removed LONG deprecated Unit.out accessor + * Removed generated method name munging from minitest/spec. (ordinaryzelig/tenderlove) + +=== 3.0.1 / 2012-05-24 + +* 1 bug fix: + + * I'm a dumbass and refactored into Mock#call. Renamed to #__call so you can mock #call. (mschuerig) + +=== 3.0.0 / 2012-05-08 + +* 3 major enhancements: + + * Added Object#stub (in minitest/mock.rb). + * Mock#expect mocks are used in the order they're given. + * Mock#verify now strictly compares against expect calls. + +* 3 minor enhancements: + + * Added caller to deprecation message. + * Mock error messages are much prettier. + * Removed String check for RHS of assert/refute_match. This lets #to_str work properly. + +* 1 bug fix: + + * Support drive letter on Windows. Patch provided from MRI by Usaku NAKAMURA. (ayumin) + +=== 2.12.1 / 2012-04-10 + +* 1 minor enhancement: + + * Added ruby releases to History.txt to make it easier to see what you're missing + +* 1 bug fix: + + * Rolled my own deprecate msg to allow MT to work with rubygems < 1.7 + +=== 2.12.0 / 2012-04-03 + +* 4 minor enhancements: + + * ::it returns test method name (wojtekmach) + * Added #record method to runner so runner subclasses can cleanly gather data. + * Added Minitest alias for MiniTest because even I forget. + * Deprecated assert_block!! Yay!!! + +* 1 bug fix: + + * Fixed warning in i_suck_and_my_tests_are_order_dependent! (phiggins) + +=== 2.11.4 / 2012-03-20 + +* 2 minor enhancements: + + * Updated known extensions + * You got your unicode in my tests! You got your tests in my unicode! (fl00r) + +* 1 bug fix: + + * Fixed MiniTest::Mock example in the readme. (conradwt) + +=== 2.11.3 / 2012-02-29 + +* 2 bug fixes: + + * Clarified that assert_raises returns the exception for further testing + * Fixed assert_in_epsilon when both args are negative. (tamc) + +=== 2.11.2 / 2012-02-14 + +* 1 minor enhancement: + + * Display failures/errors on SIGINFO. (tenderlove) + +* 1 bug fix: + + * Fixed MiniTest::Unit.after_tests for Ruby 1.9.3. (ysbaddaden) + +=== 2.11.1 / 2012-02-01 + +* 3 bug fixes: + + * Improved description for --name argument. (drd) + * Ensure Mock#expect's expected args is an Array. (mperham) + * Ensure Mock#verify verifies multiple expects of the same method. (chastell) + +=== 2.11.0 / 2012-01-25 + +* 2 minor enhancements: + + * Added before / after hooks for setup and teardown. (tenderlove) + * Pushed run_setup_hooks down to Spec. (tenderlove) + +=== 2.10.1 / 2012-01-17 + +* 1 bug fix: + + * Fixed stupid 1.9 path handling grumble grumble. (graaff) + +=== 2.10.0 / 2011-12-20 + +* 3 minor enhancements: + + * Added specs for must/wont be_empty/respond_to/be_kind_of and others. + * Added tests for assert/refute predicate. + * Split minitest/excludes.rb out to its own gem. + +* 1 bug fix: + + * Fixed must_be_empty and wont_be_empty argument handling. (mrsimo) + +=== 2.9.1 / 2011-12-13 + +* 4 minor enhancements: + + * Added a ton of tests on spec error message output. + * Cleaned up consistency of msg handling on unary expectations. + * Improved error messages on assert/refute_in_delta. + * infect_an_assertion no longer checks arity and better handles args. + +* 1 bug fix: + + * Fixed error message on specs when 2+ args and custom message provided. (chastell) + +=== 2.9.0 / 2011-12-07 + +* 4 minor enhancements: + + * Added TestCase.exclude and load_excludes for programmatic filtering of tests. + * Added guard methods so you can cleanly skip based on platform/impl + * Holy crap! 100% doco! `rdoc -C` ftw + * Switch assert_output to test stderr before stdout to possibly improve debugging + +=== 2.8.1 / 2011-11-17 + +* 1 bug fix: + + * Ugh. 1.9's test/unit violates my internals. Added const_missing. + +=== 2.8.0 / 2011-11-08 + +* 2 minor enhancements: + + * Add a method so that code can be run around a particular test case (tenderlove) + * Turn off backtrace filtering if we're running inside a ruby checkout. (drbrain) + +* 2 bug fixes: + + * Fixed 2 typos and 2 doc glitches. (splattael) + * Remove unused block arguments to avoid creating Proc objects. (k-tsj) + +=== 2.7.0 / 2011-10-25 + +* 2 minor enhancements: + + * Include failed values in the expected arg output in MockExpectationError. (nono) + * Make minitest/pride work with other 256 color capable terms. (sunaku) + +* 2 bug fixes: + + * Clarified the documentation of minitest/benchmark (eregon) + * Fixed using expectations in regular unit tests. (sunaku) + +=== 2.6.2 / 2011-10-19 + +* 1 minor enhancement: + + * Added link to vim bundle. (sunaku) + +* 2 bug fixes: + + * Force gem activation in hoe minitest plugin + * Support RUBY_VERSION='2.0.0' (nagachika) + +=== 2.6.1 / 2011-09-27 + +* 2 bug fixes: + + * Alias Spec.name from Spec.to_s so it works when @name is nil (nathany) + * Fixed assert and refute_operator where second object has a bad == method. + +=== 2.6.0 / 2011-09-13 + +* 2 minor enhancements: + + * Added specify alias for it and made desc optional. + * Spec#must_be and #wont_be can be used with predicates (metaskills) + +* 1 bug fix: + + * Fixed Mock.respond_to?(var) to work with strings. (holli) + +=== 2.5.1 / 2011-08-27 // ruby 1.9.3: p0, p125, p34579 + +* 2 minor enhancements: + + * Added gem activation for minitest in minitest/autoload to help out 1.9 users + * Extended Spec.register_spec_type to allow for procs instead of just regexps. + +=== 2.5.0 / 2011-08-18 + +* 4 minor enhancements: + + * Added 2 more arguments against rspec: let & subject in 9 loc! (emmanuel/luis) + * Added TestCase.i_suck_and_my_tests_are_order_dependent! + * Extended describe to take an optional method name (2 line change!). (emmanuel) + * Refactored and extended minitest/pride to do full 256 color support. (lolcat) + +* 1 bug fix: + + * Doc fixes. (chastell) + +=== 2.4.0 / 2011-08-09 + +* 4 minor enhancements: + + * Added simple examples for all expectations. + * Improved Mock error output when args mismatch. + * Moved all expectations from Object to MiniTest::Expectations. + * infect_with_assertions has been removed due to excessive clever + +* 4 bug fixes: + + * Fix Assertions#mu_pp to deal with immutable encoded strings. (ferrous26) + * Fix minitest/pride for MacRuby (ferrous26) + * Made error output less fancy so it is more readable + * Mock shouldn't undef === and inspect. (dgraham) + +=== 2.3.1 / 2011-06-22 + +* 1 bug fix: + + * Fixed minitest hoe plugin to be a spermy dep and not depend on itself. + +=== 2.3.0 / 2011-06-15 + +* 5 minor enhancements: + + * Add setup and teardown hooks to MiniTest::TestCase. (phiggins) + * Added nicer error messages for MiniTest::Mock. (phiggins) + * Allow for less specific expected arguments in Mock. (bhenderson/phiggins) + * Made MiniTest::Mock a blank slate. (phiggins) + * Refactored minitest/spec to use the hooks instead of define_inheritable_method. (phiggins) + +* 2 bug fixes: + + * Fixed TestCase's inherited hook. (dchelimsky/phiggins/jamis, the 'good' neighbor) + * MiniTest::Assertions#refute_empty should use mu_pp in the default message. (whatthejeff) + +=== 2.2.2 / 2011-06-01 + +* 2 bug fixes: + + * Got rid of the trailing period in message for assert_equal. (tenderlove) + * Windows needs more flushing. (Akio Tajima) + +=== 2.2.1 / 2011-05-31 + +* 1 bug fix: + + * My _ONE_ non-rubygems-using minitest user goes to Seattle.rb! + +=== 2.2.0 / 2011-05-29 + +* 6 minor enhancements: + + * assert_equal (and must_equal) now tries to diff output where it makes sense. + * Added Assertions#diff(exp, act) to be used by assert_equal. + * Added Assertions#mu_pp_for_diff + * Added Assertions.diff and diff= + * Moved minitest hoe-plugin from hoe-seattlerb. (erikh) + * Skipped tests only output details in verbose mode. (tenderlove+zenspider=xoxo) + +=== 2.1.0 / 2011-04-11 + +* 5 minor enhancements: + + * Added MiniTest::Spec.register_spec_type(matcher, klass) and spec_type(desc) + * Added ability for specs to share code via subclassing of Spec. (metaskills) + * Clarified (or tried to) bench_performance_linear's use of threshold. + * MiniTest::Unit.runner=(runner) provides an easy way of creating custom test runners for specialized needs. (justinweiss) + * Reverse order of inheritance in teardowns of specs. (deepfryed) + +* 3 bug fixes: + + * FINALLY fixed problems of inheriting specs in describe/it/describe scenario. (MGPalmer) + * Fixed a new warning in 1.9.3. + * Fixed assert_block's message handling. (nobu) + +=== 2.0.2 / 2010-12-24 + +* 1 minor enhancement: + + * Completed doco on minitest/benchmark for specs. + +* 1 bug fix: + + * Benchmarks in specs that didn't call bench_range would die. (zzak). + +=== 2.0.1 / 2010-12-15 + +* 4 minor enhancements: + + * Do not filter backtrace if $DEBUG + * Exit autorun via nested at_exit handler, in case other libs call exit + * Make options accesor lazy. + * Split printing of test name and its time. (nurse) + +* 1 bug fix: + + * Fix bug when ^T is hit before runner start + +=== 2.0.0 / 2010-11-11 + +* 3 major enhancements: + + * Added minitest/benchmark! Assert your performance! YAY! + * Refactored runner to allow for more extensibility. See minitest/benchmark. + * This makes the runner backwards incompatible in some ways! + +* 9 minor enhancements: + + * Added MiniTest::Unit.after_tests { ... } + * Improved output by adding test rates and a more sortable verbose format + * Improved readme based on feedback from others + * Added io method to TestCase. If used, it'll supplant '.EF' output. + * Refactored IO in MiniTest::Unit. + * Refactored _run_anything to _run_suite to make it easier to wrap (ngauthier) + * Spec class names are now the unmunged descriptions (btakita) + * YAY for not having redundant rdoc/readmes! + * Help output is now generated from the flags you passed straight up. + +* 4 bug fixes: + + * Fixed scoping issue on minitest/mock (srbaker/prosperity) + * Fixed some of the assertion default messages + * Fixes autorun when on windows with ruby install on different drive (larsch) + * Fixed rdoc output bug in spec.rb + +=== 1.7.2 / 2010-09-23 + +* 3 bug fixes: + + * Fixed doco for expectations and Spec. + * Fixed test_capture_io on 1.9.3+ (sora_h) + * assert_raises now lets MiniTest::Skip through. (shyouhei) + +=== 1.7.1 / 2010-09-01 + +* 1 bug fix: + + * 1.9.2 fixes for spec tests + +=== 1.7.0 / 2010-07-15 + +* 5 minor enhancements: + + * Added assert_output (mapped to must_output). + * Added assert_silent (mapped to must_be_silent). + * Added examples to readme (Mike Dalessio) + * Added options output at the top of the run, for fatal run debugging (tenderlove) + * Spec's describe method returns created class + +=== 1.6.0 / 2010-03-27 // ruby 1.9.2-p290 + +* 10 minor enhancements: + + * Added --seed argument so you can reproduce a random order for debugging. + * Added documentation for assertions + * Added more rdoc and tons of :nodoc: + * Added output to give you all the options you need to reproduce that run. + * Added proper argument parsing to minitest. + * Added unique serial # to spec names so order can be preserved (needs tests). (phrogz) + * Empty 'it' fails with default msg. (phrogz) + * Remove previous method on expect to remove 1.9 warnings + * Spec#it is now order-proof wrt subclasses/nested describes. + * assert_same error message now reports in decimal, eg: oid=123. (mattkent) + +* 2 bug fixes: + + * Fixed message on refute_same to be consistent with assert_same. + * Fixed method randomization to be stable for testing. + +=== 1.5.0 / 2010-01-06 + +* 4 minor enhancements: + + * Added ability to specify what assertions should have their args flipped. + * Don't flip arguments on *include and *respond_to assertions. + * Refactored Module.infect_an_assertion from Module.infect_with_assertions. + * before/after :all now bitches and acts like :each + +* 3 bug fixes: + + * Nested describes now map to nested test classes to avoid namespace collision. + * Using undef_method instead of remove_method to clean out inherited specs. + * assert_raises was ignoring passed in message. + +=== 1.4.2 / 2009-06-25 + +* 1 bug fix: + + * Fixed info handler for systems that don't have siginfo. + +=== 1.4.1 / 2009-06-23 + +* 1 major enhancement: + + * Handle ^C and other fatal exceptions by failing + +* 1 minor enhancement: + + * Added something to catch mixed use of test/unit and minitest if $DEBUG + +* 1 bug fix: + + * Added SIGINFO handler for finding slow tests without verbose + +=== 1.4.0 / 2009-06-18 + +* 5 minor enhancement: + + * Added clarification doco. + * Added specs and mocks to autorun. + * Changed spec test class creation to be non-destructive. + * Updated rakefile for new hoe capabilities. + * describes are nestable (via subclass). before/after/def inherits, specs don't. + +* 3 bug fixes: + + * Fixed location on must/wont. + * Switched to __name__ to avoid common ivar name. + * Fixed indentation in test file (1.9). + +=== 1.3.1 / 2009-01-20 // ruby 1.9.1-p431 + +* 1 minor enhancement: + + * Added miniunit/autorun.rb as replacement for test/unit.rb's autorun. + +* 16 bug fixes: + + * 1.9 test fixes. + * Bug fixes from nobu and akira for really odd scenarios. They run ruby funny. + * Fixed (assert|refute)_match's argument order. + * Fixed LocalJumpError in autorun if exception thrown before at_exit. + * Fixed assert_in_delta (should be >=, not >). + * Fixed assert_raises to match Modules. + * Fixed capture_io to not dup IOs. + * Fixed indentation of capture_io for ruby 1.9 warning. + * Fixed location to deal better with custom assertions and load paths. (Yuki) + * Fixed order of (must|wont)_include in MiniTest::Spec. + * Fixed skip's backtrace. + * Got arg order wrong in *_match in tests, message wrong as a result. + * Made describe private. For some reason I thought that an attribute of Kernel. + * Removed disable_autorun method, added autorun.rb instead. + * assert_match escapes if passed string for pattern. + * instance_of? is different from ===, use instance_of. + +=== 1.3.0 / 2008-10-09 + +* 2 major enhancements: + + * renamed to minitest and pulled out test/unit compatibility. + * mini/test.rb is now minitest/unit.rb, everything else maps directly. + +* 12 minor enhancements: + + * assert_match now checks that act can call =~ and converts exp to a + regexp only if needed. + * Added assert_send... seems useless to me tho. + * message now forces to string... ruby-core likes to pass classes and arrays :( + * Added -v handling and switched to @verbose from $DEBUG. + * Verbose output now includes test class name and adds a sortable running time! + * Switched message generation into procs for message deferment. + * Added skip and renamed fail to flunk. + * Improved output failure messages for assert_instance_of, assert_kind_of + * Improved output for assert_respond_to, assert_same. + * at_exit now exits false instead of errors+failures. + * Made the tests happier and more readable imhfo. + * Switched index(s) == 0 to rindex(s, 0) on nobu's suggestion. Faster. + +* 5 bug fixes: + + * 1.9: Added encoding normalization in mu_pp. + * 1.9: Fixed backtrace filtering (BTs are expanded now) + * Added back exception_details to assert_raises. DOH. + * Fixed shadowed variable in mock.rb + * Fixed stupid muscle memory message bug in assert_send. + +=== 1.2.1 / 2008-06-10 + +* 7 minor enhancements: + + * Added deprecations everywhere in test/unit. + * Added test_order to TestCase. :random on mini, :sorted on test/unit (for now). + * Big cleanup in test/unit for rails. Thanks Jeremy Kemper! + * Minor readability cleanup. + * Pushed setup/run/teardown down to testcase allowing specialized testcases. + * Removed pp. Tests run 2x faster. :/ + * Renamed deprecation methods and moved to test/unit/deprecate.rb. + +=== 1.2.0 / 2008-06-09 + +* 2 major enhancements: + + * Added Mini::Spec. + * Added Mini::Mock. Thanks Steven Baker!! + +* 23 minor enhancements: + + * Added bin/use_miniunit to make it easy to test out miniunit. + * Added -n filtering, thanks to Phil Hagelberg! + * Added args argument to #run, takes ARGV from at_exit. + * Added test name output if $DEBUG. + * Added a refute (was deny) for every assert. + * Added capture_io and a bunch of nice assertions from zentest. + * Added deprecation mechanism for assert_no/not methods to test/unit/assertions. + * Added pp output when available. + * Added tests for all assertions. Pretty much maxed out coverage. + * Added tests to verify consistency and good naming. + * Aliased and deprecated all ugly assertions. + * Cleaned out test/unit. Moved autorun there. + * Code cleanup to make extensions easier. Thanks Chad! + * Got spec args reversed in all but a couple assertions. Much more readable. + * Improved error messages across the board. Adds your message to the default. + * Moved into Mini namespace, renamed to Mini::Test and Mini::Spec. + * Pulled the assertions into their own module... + * Removed as much code as I could while still maintaining full functionality. + * Moved filter_backtrace into MiniTest. + * Removed MiniTest::Unit::run. Unnecessary. + * Removed location_of_failure. Unnecessary. + * Rewrote test/unit's filter_backtrace. Flog from 37.0 to 18.1 + * Removed assert_send. Google says it is never used. + * Renamed MiniTest::Unit.autotest to #run. + * Renamed deny to refute. + * Rewrote some ugly/confusing default assertion messages. + * assert_in_delta now defaults to 0.001 precision. Makes specs prettier. + +* 9 bug fixes: + + * Fixed assert_raises to raise outside of the inner-begin/rescue. + * Fixed for ruby 1.9 and rubinius. + * No longer exits 0 if exception in code PRE-test run causes early exit. + * Removed implementors method list from mini/test.rb - too stale. + * assert_nothing_raised takes a class as an arg. wtf? STUPID + * ".EF" output is now unbuffered. + * Bunch of changes to get working with rails... UGH. + * Added stupid hacks to deal with rails not requiring their dependencies. + * Now bitch loudly if someone defines one of my classes instead of requiring. + * Fixed infect method to work better on 1.9. + * Fixed all shadowed variable warnings in 1.9. + +=== 1.1.0 / 2007-11-08 + +* 4 major enhancements: + + * Finished writing all missing assertions. + * Output matches original test/unit. + * Documented every method needed by language implementor. + * Fully switched over to self-testing setup. + +* 2 minor enhancements: + + * Added deny (assert ! test), our favorite extension to test/unit. + * Added .autotest and fairly complete unit tests. (thanks Chad for help here) + +=== 1.0.0 / 2006-10-30 + +* 1 major enhancement + + * Birthday! diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/Manifest.txt b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/Manifest.txt new file mode 100644 index 00000000..abdd95f8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/Manifest.txt @@ -0,0 +1,32 @@ +.autotest +History.rdoc +Manifest.txt +README.rdoc +Rakefile +design_rationale.rb +lib/hoe/minitest.rb +lib/minitest.rb +lib/minitest/assertions.rb +lib/minitest/autorun.rb +lib/minitest/benchmark.rb +lib/minitest/compress.rb +lib/minitest/error_on_warning.rb +lib/minitest/expectations.rb +lib/minitest/hell.rb +lib/minitest/manual_plugins.rb +lib/minitest/mock.rb +lib/minitest/parallel.rb +lib/minitest/pride.rb +lib/minitest/pride_plugin.rb +lib/minitest/spec.rb +lib/minitest/test.rb +lib/minitest/test_task.rb +lib/minitest/unit.rb +test/minitest/metametameta.rb +test/minitest/test_minitest_assertions.rb +test/minitest/test_minitest_benchmark.rb +test/minitest/test_minitest_mock.rb +test/minitest/test_minitest_reporter.rb +test/minitest/test_minitest_spec.rb +test/minitest/test_minitest_test.rb +test/minitest/test_minitest_test_task.rb diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/README.rdoc b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/README.rdoc new file mode 100644 index 00000000..e2855b76 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/README.rdoc @@ -0,0 +1,842 @@ += minitest/{test,spec,mock,benchmark} + +home :: https://github.com/minitest/minitest +bugs :: https://github.com/minitest/minitest/issues +rdoc :: https://docs.seattlerb.org/minitest +clog :: https://github.com/minitest/minitest/blob/master/History.rdoc +vim :: https://github.com/sunaku/vim-ruby-minitest +emacs:: https://github.com/arthurnn/minitest-emacs + +== DESCRIPTION: + +minitest provides a complete suite of testing facilities supporting +TDD, BDD, mocking, and benchmarking. + + "I had a class with Jim Weirich on testing last week and we were + allowed to choose our testing frameworks. Kirk Haines and I were + paired up and we cracked open the code for a few test + frameworks... + + I MUST say that minitest is *very* readable / understandable + compared to the 'other two' options we looked at. Nicely done and + thank you for helping us keep our mental sanity." + + -- Wayne E. Seguin + +minitest/test is a small and incredibly fast unit testing framework. +It provides a rich set of assertions to make your tests clean and +readable. + +minitest/spec is a functionally complete spec engine. It hooks onto +minitest/test and seamlessly bridges test assertions over to spec +expectations. + +minitest/benchmark is an awesome way to assert the performance of your +algorithms in a repeatable manner. Now you can assert that your newb +co-worker doesn't replace your linear algorithm with an exponential +one! + +minitest/mock by Steven Baker, is a beautifully tiny mock (and stub) +object framework. + +minitest/pride shows pride in testing and adds coloring to your test +output. I guess it is an example of how to write IO pipes too. :P + +minitest/test is meant to have a clean implementation for language +implementors that need a minimal set of methods to bootstrap a working +test suite. For example, there is no magic involved for test-case +discovery. + + "Again, I can't praise enough the idea of a testing/specing + framework that I can actually read in full in one sitting!" + + -- Piotr Szotkowski + +Comparing to rspec: + + rspec is a testing DSL. minitest is ruby. + + -- Adam Hawkins, "Bow Before MiniTest" + +minitest doesn't reinvent anything that ruby already provides, like: +classes, modules, inheritance, methods. This means you only have to +learn ruby to use minitest and all of your regular OO practices like +extract-method refactorings still apply. + +== FEATURES/PROBLEMS: + +* minitest/autorun - the easy and explicit way to run all your tests. +* minitest/test - a very fast, simple, and clean test system. +* minitest/spec - a very fast, simple, and clean spec system. +* minitest/mock - a simple and clean mock/stub system. +* minitest/benchmark - an awesome way to assert your algorithm's performance. +* minitest/pride - show your pride in testing! +* minitest/test_task - a full-featured and clean rake task generator. +* Incredibly small and fast runner, but no bells and whistles. +* Written by squishy human beings. Software can never be perfect. We will all eventually die. + +== RATIONALE: + +See design_rationale.rb to see how specs and tests work in minitest. + +== SYNOPSIS: + +Given that you'd like to test the following class: + + class Meme + def i_can_has_cheezburger? + "OHAI!" + end + + def will_it_blend? + "YES!" + end + end + +=== Unit tests + +Define your tests as methods beginning with +test_+. + + require "minitest/autorun" + + class TestMeme < Minitest::Test + def setup + @meme = Meme.new + end + + def test_that_kitty_can_eat + assert_equal "OHAI!", @meme.i_can_has_cheezburger? + end + + def test_that_it_will_not_blend + refute_match /^no/i, @meme.will_it_blend? + end + + def test_that_will_be_skipped + skip "test this later" + end + end + +=== Specs + + require "minitest/autorun" + + describe Meme do + before do + @meme = Meme.new + end + + describe "when asked about cheeseburgers" do + it "must respond positively" do + _(@meme.i_can_has_cheezburger?).must_equal "OHAI!" + end + end + + describe "when asked about blending possibilities" do + it "won't say no" do + _(@meme.will_it_blend?).wont_match /^no/i + end + end + end + +For matchers support check out: + +* https://github.com/wojtekmach/minitest-matchers +* https://github.com/rmm5t/minitest-matchers_vaccine + +=== Benchmarks + +Add benchmarks to your tests. + + # optionally run benchmarks, good for CI-only work! + require "minitest/benchmark" if ENV["BENCH"] + + class TestMeme < Minitest::Benchmark + # Override self.bench_range or default range is [1, 10, 100, 1_000, 10_000] + def bench_my_algorithm + assert_performance_linear 0.9999 do |n| # n is a range value + @obj.my_algorithm(n) + end + end + end + +Or add them to your specs. If you make benchmarks optional, you'll +need to wrap your benchmarks in a conditional since the methods won't +be defined. In minitest 5, the describe name needs to match +/Bench(mark)?$/. + + describe "Meme Benchmark" do + if ENV["BENCH"] then + bench_performance_linear "my_algorithm", 0.9999 do |n| + 100.times do + @obj.my_algorithm(n) + end + end + end + end + +outputs something like: + + # Running benchmarks: + + TestBlah 100 1000 10000 + bench_my_algorithm 0.006167 0.079279 0.786993 + bench_other_algorithm 0.061679 0.792797 7.869932 + +Output is tab-delimited to make it easy to paste into a spreadsheet. + +=== Mocks + +Mocks and stubs defined using terminology by Fowler & Meszaros at +https://www.martinfowler.com/bliki/TestDouble.html: + +"Mocks are pre-programmed with expectations which form a specification +of the calls they are expected to receive. They can throw an exception +if they receive a call they don't expect and are checked during +verification to ensure they got all the calls they were expecting." + + class MemeAsker + def initialize(meme) + @meme = meme + end + + def ask(question) + method = question.tr(" ", "_") + "?" + @meme.__send__(method) + end + end + + require "minitest/autorun" + + describe MemeAsker, :ask do + describe "when passed an unpunctuated question" do + it "should invoke the appropriate predicate method on the meme" do + @meme = Minitest::Mock.new + @meme_asker = MemeAsker.new @meme + @meme.expect :will_it_blend?, :return_value + + @meme_asker.ask "will it blend" + + @meme.verify + end + end + end + +==== Multi-threading and Mocks + +Minitest mocks do not support multi-threading. If it works, fine, if it doesn't +you can use regular ruby patterns and facilities like local variables. Here's +an example of asserting that code inside a thread is run: + + def test_called_inside_thread + called = false + pr = Proc.new { called = true } + thread = Thread.new(&pr) + thread.join + assert called, "proc not called" + end + +=== Stubs + +Mocks and stubs are defined using terminology by Fowler & Meszaros at +https://www.martinfowler.com/bliki/TestDouble.html: + +"Stubs provide canned answers to calls made during the test". + +Minitest's stub method overrides a single method for the duration of +the block. + + def test_stale_eh + obj_under_test = Something.new + + refute obj_under_test.stale? + + Time.stub :now, Time.at(0) do # stub goes away once the block is done + assert obj_under_test.stale? + end + end + +A note on stubbing: In order to stub a method, the method must +actually exist prior to stubbing. Use a singleton method to create a +new non-existing method: + + def obj_under_test.fake_method + ... + end + +=== Running Your Tests + +Ideally, you'll use a rake task to run your tests (see below), either +piecemeal or all at once. BUT! You don't have to: + + % ruby -Ilib:test test/minitest/test_minitest_test.rb + Run options: --seed 37685 + + # Running: + + ...................................................................... (etc) + + Finished in 0.107130s, 1446.8403 runs/s, 2959.0217 assertions/s. + + 155 runs, 317 assertions, 0 failures, 0 errors, 0 skips + +There are runtime options available, both from minitest itself, and also +provided via plugins. To see them, simply run with +--help+: + + % ruby -Ilib:test test/minitest/test_minitest_test.rb --help + minitest options: + -h, --help Display this help. + -s, --seed SEED Sets random seed. Also via env. Eg: SEED=n rake + -v, --verbose Verbose. Show progress processing files. + -n, --name PATTERN Filter run on /regexp/ or string. + -e, --exclude PATTERN Exclude /regexp/ or string from run. + + Known extensions: pride, autotest + -p, --pride Pride. Show your testing pride! + -a, --autotest Connect to autotest server. + +=== Rake Tasks + +You can set up a rake task to run all your tests by adding this to your Rakefile: + + require "minitest/test_task" + + Minitest::TestTask.create # named test, sensible defaults + + # or more explicitly: + + Minitest::TestTask.create(:test) do |t| + t.libs << "test" + t.libs << "lib" + t.warning = false + t.test_globs = ["test/**/*_test.rb"] + end + + task :default => :test + +Each of these will generate 4 tasks: + + rake test :: Run the test suite. + rake test:cmd :: Print out the test command. + rake test:isolated :: Show which test files fail when run separately. + rake test:slow :: Show bottom 25 tests sorted by time. + +=== Rake Task Variables + +There are a bunch of variables you can supply to rake to modify the run. + + MT_LIB_EXTRAS :: Extra libs to dynamically override/inject for custom runs. + N :: -n: Tests to run (string or /regexp/). + X :: -x: Tests to exclude (string or /regexp/). + A :: Any extra arguments. Honors shell quoting. + MT_CPU :: How many threads to use for parallel test runs + SEED :: -s --seed Sets random seed. + TESTOPTS :: Deprecated, same as A + FILTER :: Deprecated, same as A + +== Writing Extensions + +To define a plugin, add a file named minitest/XXX_plugin.rb to your +project/gem. That file must be discoverable via ruby's LOAD_PATH (via +rubygems or otherwise). Minitest will find and require that file using +Gem.find_files. It will then try to call +plugin_XXX_init+ during +startup. The option processor will also try to call +plugin_XXX_options+ +passing the OptionParser instance and the current options hash. This +lets you register your own command-line options. Here's a totally +bogus example: + + # minitest/bogus_plugin.rb: + + module Minitest + def self.plugin_bogus_options(opts, options) + opts.on "--myci", "Report results to my CI" do + options[:myci] = true + options[:myci_addr] = get_myci_addr + options[:myci_port] = get_myci_port + end + end + + def self.plugin_bogus_init(options) + self.reporter << MyCI.new(options) if options[:myci] + end + end + +=== Adding custom reporters + +Minitest uses composite reporter to output test results using multiple +reporter instances. You can add new reporters to the composite during +the init_plugins phase. As we saw in +plugin_bogus_init+ above, you +simply add your reporter instance to the composite via <<. + ++AbstractReporter+ defines the API for reporters. You may subclass it +and override any method you want to achieve your desired behavior. + +start :: Called when the run has started. +record :: Called for each result, passed or otherwise. +report :: Called at the end of the run. +passed? :: Called to see if you detected any problems. + +Using our example above, here is how we might implement MyCI: + + # minitest/bogus_plugin.rb + + module Minitest + class MyCI < AbstractReporter + attr_accessor :results, :addr, :port + + def initialize options + self.results = [] + self.addr = options[:myci_addr] + self.port = options[:myci_port] + end + + def record result + self.results << result + end + + def report + CI.connect(addr, port).send_results self.results + end + end + + # code from above... + end + +== FAQ + +=== What versions are compatible with what? Or what versions are supported? + +Minitest is a dependency of rails, which until very recently had an +overzealous backwards compatibility policy. As such, I'm stuck +supporting versions of ruby that are long past EOL. Hopefully I'll be +able to support only current versions of ruby sometime in the near +future. + +NOTICE: At this point, I will only locally test/dev against the +currently 3 supported (non-EOL) versions of ruby. I cannot and will +not maintain that many builds. + +(As of 2025-02-03) + +Current versions of rails: (https://endoflife.date/rails) + + | rails | min ruby | minitest | status | EOL Date | + |-------+----------+----------+----------+------------| + | 8.0 | >= 3.2 | >= 5.1 | Current | 2026-11-07 | + | 7.2 | >= 3.1 | >= 5.1 | Current | 2026-08-09 | + | 7.1 | >= 2.7 | >= 5.1 | Security | 2025-10-01 | + | 7.0 | >= 2.7 | >= 5.1 | Security | 2025-04-01 | + | 6.1 | >= 2.5 | >= 5.1 | EOL | 2024-10-01 | + | 6.0 | >= 2.5 | >= 5.1 | EOL | 2023-06-01 | + | 5.2 | >= 2.2.2 | ~> 5.1 | EOL | 2022-06-01 | + +If you want to look at the requirements for a specific version, run: + + gem spec -r --ruby rails -v 8.0.0 + +Current versions of ruby: (https://endoflife.date/ruby) + + | ruby | Status | EOL Date | + |------+---------+------------| + | 3.4 | Current | 2028-03-31 | + | 3.3 | Maint | 2027-03-31 | + | 3.2 | Security| 2026-03-31 | + | 3.1 | EOL | 2025-03-31 | + | 3.0 | EOL | 2024-03-31 | + | 2.7 | EOL | 2023-03-31 | + | 2.6 | EOL | 2022-03-31 | + | 2.5 | EOL | 2021-03-31 | + +=== How to test SimpleDelegates? + +The following implementation and test: + + class Worker < SimpleDelegator + def work + end + end + + describe Worker do + before do + @worker = Worker.new(Object.new) + end + + it "must respond to work" do + _(@worker).must_respond_to :work + end + end + +outputs a failure: + + 1) Failure: + Worker#test_0001_must respond to work [bug11.rb:16]: + Expected # (Object) to respond to #work. + +Worker is a SimpleDelegate which in 1.9+ is a subclass of BasicObject. +Expectations are put on Object (one level down) so the Worker +(SimpleDelegate) hits +method_missing+ and delegates down to the ++Object.new+ instance. That object doesn't respond to work so the test +fails. + +You can bypass SimpleDelegate#method_missing by extending the worker +with Minitest::Expectations. You can either do that in your setup at +the instance level, like: + + before do + @worker = Worker.new(Object.new) + @worker.extend Minitest::Expectations + end + +or you can extend the Worker class (within the test file!), like: + + class Worker + include ::Minitest::Expectations + end + +=== How to share code across test classes? + +Use a module. That's exactly what they're for: + + module UsefulStuff + def useful_method + # ... + end + end + + describe Blah do + include UsefulStuff + + def test_whatever + # useful_method available here + end + end + +Remember, +describe+ simply creates test classes. It's just ruby at +the end of the day and all your normal Good Ruby Rules (tm) apply. If +you want to extend your test using setup/teardown via a module, just +make sure you ALWAYS call super. before/after automatically call super +for you, so make sure you don't do it twice. + +=== How to run code before a group of tests? + +Use a constant with begin...end like this: + + describe Blah do + SETUP = begin + # ... this runs once when describe Blah starts + end + # ... + end + +This can be useful for expensive initializations or sharing state. +Remember, this is just ruby code, so you need to make sure this +technique and sharing state doesn't interfere with your tests. + +=== Why am I seeing uninitialized constant MiniTest::Test (NameError)? + +Are you running the test with Bundler (e.g. via bundle exec )? If so, +in order to require minitest, you must first add the gem 'minitest' +to your Gemfile and run +bundle+. Once it's installed, you should be +able to require minitest and run your tests. + +== Prominent Projects using Minitest: + +* arel +* journey +* mime-types +* nokogiri +* rails (active_support et al) +* rake +* rdoc +* ...and of course, everything from seattle.rb... + +== Developing Minitest: + +Minitest requires {Hoe}[https://rubygems.org/gems/hoe]. + +=== Minitest's own tests require UTF-8 external encoding. + +This is a common problem in Windows, where the default external Encoding is +often CP850, but can affect any platform. +Minitest can run test suites using any Encoding, but to run Minitest's +own tests you must have a default external Encoding of UTF-8. + +If your encoding is wrong, you'll see errors like: + + --- expected + +++ actual + @@ -1,2 +1,3 @@ + # encoding: UTF-8 + -"Expected /\\w+/ to not match \"blah blah blah\"." + +"Expected /\\w+/ to not match # encoding: UTF-8 + +\"blah blah blah\"." + +To check your current encoding, run: + + ruby -e 'puts Encoding.default_external' + +If your output is something other than UTF-8, you can set the RUBYOPTS +env variable to a value of '-Eutf-8'. Something like: + + RUBYOPT='-Eutf-8' ruby -e 'puts Encoding.default_external' + +Check your OS/shell documentation for the precise syntax (the above +will not work on a basic Windows CMD prompt, look for the SET command). +Once you've got it successfully outputing UTF-8, use the same setting +when running rake in Minitest. + +=== Minitest's own tests require GNU (or similar) diff. + +This is also a problem primarily affecting Windows developers. PowerShell +has a command called diff, but it is not suitable for use with Minitest. + +If you see failures like either of these, you are probably missing diff tool: + + 4) Failure: + TestMinitestUnitTestCase#test_assert_equal_different_long [D:/ruby/seattlerb/minitest/test/minitest/test_minitest_test.rb:936]: + Expected: "--- expected\n+++ actual\n@@ -1 +1 @@\n-\"hahahahahahahahahahahahahahahahahahahaha\"\n+\"blahblahblahblahblahblahblahblahblahblah\"\n" + Actual: "Expected: \"hahahahahahahahahahahahahahahahahahahaha\"\n Actual: \"blahblahblahblahblahblahblahblahblahblah\"" + + + 5) Failure: + TestMinitestUnitTestCase#test_assert_equal_different_collection_hash_hex_invisible [D:/ruby/seattlerb/minitest/test/minitest/test_minitest_test.rb:845]: + Expected: "No visible difference in the Hash#inspect output.\nYou should look at the implementation of #== on Hash or its members.\n + {1=>#}" + Actual: "Expected: {1=>#}\n Actual: {1=>#}" + + +If you use Cygwin or MSYS2 or similar there are packages that include a +GNU diff for Windows. If you don't, you can download GNU diffutils from +http://gnuwin32.sourceforge.net/packages/diffutils.htm +(make sure to add it to your PATH). + +You can make sure it's installed and path is configured properly with: + + diff.exe -v + +There are multiple lines of output, the first should be something like: + + diff (GNU diffutils) 2.8.1 + +If you are using PowerShell make sure you run diff.exe, not just diff, +which will invoke the PowerShell built in function. + +== Known Extensions: + +capybara_minitest_spec :: Bridge between Capybara RSpec matchers and + Minitest::Spec expectations (e.g. + page.must_have_content("Title")). +color_pound_spec_reporter :: Test names print Ruby Object types in color with + your Minitest Spec style tests. +minispec-metadata :: Metadata for describe/it blocks & CLI tag filter. + E.g. it "requires JS driver", js: true do & + ruby test.rb --tag js runs tests tagged :js. +minispec-rails :: Minimal support to use Spec style in Rails 5+. +mini-apivore :: for swagger based automated API testing. +minitest-around :: Around block for minitest. An alternative to + setup/teardown dance. +minitest-assert_errors :: Adds Minitest assertions to test for errors raised + or not raised by Minitest itself. +minitest-autotest :: autotest is a continuous testing facility meant to + be used during development. +minitest-bacon :: minitest-bacon extends minitest with bacon-like + functionality. +minitest-bang :: Adds support for RSpec-style let! to immediately + invoke let statements before each test. +minitest-bisect :: Helps you isolate and debug random test failures. +minitest-blink1_reporter :: Display test results with a Blink1. +minitest-capistrano :: Assertions and expectations for testing + Capistrano recipes. +minitest-capybara :: Capybara matchers support for minitest unit and + spec. +minitest-cc :: It provides minimal information about code coverage. +minitest-chef-handler :: Run Minitest suites as Chef report handlers +minitest-ci :: CI reporter plugin for Minitest. +minitest-context :: Defines contexts for code reuse in Minitest + specs that share common expectations. +minitest-debugger :: Wraps assert so failed assertions drop into + the ruby debugger. +minitest-display :: Patches Minitest to allow for an easily + configurable output. +minitest-documentation :: Minimal documentation format inspired by rspec's. +minitest-doc_reporter :: Detailed output inspired by rspec's documentation + format. +minitest-emoji :: Print out emoji for your test passes, fails, and + skips. +minitest-english :: Semantically symmetric aliases for assertions and + expectations. +minitest-excludes :: Clean API for excluding certain tests you + don't want to run under certain conditions. +minitest-fail-fast :: Reimplements RSpec's "fail fast" feature +minitest-filecontent :: Support unit tests with expectation results in files. + Differing results will be stored again in files. +minitest-filesystem :: Adds assertion and expectation to help testing + filesystem contents. +minitest-firemock :: Makes your Minitest mocks more resilient. +minitest-focus :: Focus on one test at a time. +minitest-gcstats :: A minitest plugin that adds a report of the top + tests by number of objects allocated. +minitest-global_expectations:: Support minitest expectation methods for all objects +minitest-great_expectations :: Generally useful additions to minitest's + assertions and expectations. +minitest-growl :: Test notifier for minitest via growl. +minitest-happy :: GLOBALLY ACTIVATE MINITEST PRIDE! RAWR! +minitest-have_tag :: Adds Minitest assertions to test for the existence of + HTML tags, including contents, within a provided string. +minitest-heat :: Reporting that builds a heat map of failure locations +minitest-hooks :: Around and before_all/after_all/around_all hooks +minitest-hyper :: Pretty, single-page HTML reports for your Minitest runs +minitest-implicit-subject :: Implicit declaration of the test subject. +minitest-instrument :: Instrument ActiveSupport::Notifications when + test method is executed. +minitest-instrument-db :: Store information about speed of test execution + provided by minitest-instrument in database. +minitest-junit :: JUnit-style XML reporter for minitest. +minitest-keyword :: Use Minitest assertions with keyword arguments. +minitest-libnotify :: Test notifier for minitest via libnotify. +minitest-line :: Run test at line number. +minitest-logger :: Define assert_log and enable minitest to test log messages. + Supports Logger and Log4r::Logger. +minitest-macruby :: Provides extensions to minitest for macruby UI + testing. +minitest-matchers :: Adds support for RSpec-style matchers to + minitest. +minitest-matchers_vaccine :: Adds assertions that adhere to the matcher spec, + but without any expectation infections. +minitest-metadata :: Annotate tests with metadata (key-value). +minitest-mock_expectations :: Provides method call assertions for minitest. +minitest-mongoid :: Mongoid assertion matchers for Minitest. +minitest-must_not :: Provides must_not as an alias for wont in + Minitest. +minitest-optional_retry :: Automatically retry failed test to help with flakiness. +minitest-osx :: Reporter for the Mac OS X notification center. +minitest-parallel_fork :: Fork-based parallelization +minitest-parallel-db :: Run tests in parallel with a single database. +minitest-power_assert :: PowerAssert for Minitest. +minitest-predicates :: Adds support for .predicate? methods. +minitest-profile :: List the 10 slowest tests in your suite. +minitest-rails :: Minitest integration for Rails 3.x. +minitest-rails-capybara :: Capybara integration for Minitest::Rails. +minitest-reporters :: Create customizable Minitest output formats. +minitest-rg :: Colored red/green output for Minitest. +minitest-rspec_mocks :: Use RSpec Mocks with Minitest. +minitest-server :: minitest-server provides a client/server setup + with your minitest process, allowing your test + run to send its results directly to a handler. +minitest-sequel :: Minitest assertions to speed-up development and + testing of Ruby Sequel database setups. +minitest-shared_description :: Support for shared specs and shared spec + subclasses +minitest-should_syntax :: RSpec-style x.should == y assertions for + Minitest. +minitest-shouldify :: Adding all manner of shoulds to Minitest (bad + idea) +minitest-snail :: Print a list of tests that take too long +minitest-spec-context :: Provides rspec-ish context method to + Minitest::Spec. +minitest-spec-expect :: Expect syntax for Minitest::Spec (e.g. + expect(sequences).to_include :celery_man). +minitest-spec-magic :: Minitest::Spec extensions for Rails and beyond. +minitest-spec-rails :: Drop in Minitest::Spec superclass for + ActiveSupport::TestCase. +minitest-sprint :: Runs (Get it? It's fast!) your tests and makes + it easier to rerun individual failures. +minitest-stately :: Find leaking state between tests +minitest-stub_any_instance :: Stub any instance of a method on the given class + for the duration of a block. +minitest-stub-const :: Stub constants for the duration of a block. +minitest-tags :: Add tags for minitest. +minitest-unordered :: Adds a new assertion to minitest for checking the + contents of a collection, ignoring element order. +minitest-vcr :: Automatic cassette management with Minitest::Spec + and VCR. +minitest_log :: Adds structured logging, data explication, and verdicts. +minitest_owrapper :: Get tests results as a TestResult object. +minitest_should :: Shoulda style syntax for minitest test::unit. +minitest_tu_shim :: Bridges between test/unit and minitest. +mongoid-minitest :: Minitest matchers for Mongoid. +mutant-minitest :: Minitest integration for mutant. +pry-rescue :: A pry plugin w/ minitest support. See + pry-rescue/minitest.rb. +rematch :: Declutter your test files from large hardcoded data + and update them automatically when your code changes. +rspec2minitest :: Easily translate any RSpec matchers to Minitest + assertions and expectations. +stubberry :: Multiple stubbing 'berries', sweet and useful + stub helpers and assertions. ( stub_must, + assert_method_called, stubbing ORM objects by id ) + +== Unknown Extensions: + +Authors... Please send me a pull request with a description of your minitest extension. + +* assay-minitest +* detroit-minitest +* em-minitest-spec +* flexmock-minitest +* guard-minitest +* guard-minitest-decisiv +* minitest-activemodel +* minitest-ar-assertions +* minitest-capybara-unit +* minitest-colorer +* minitest-deluxe +* minitest-extra-assertions +* minitest-rails-shoulda +* minitest-spec +* minitest-spec-should +* minitest-sugar +* spork-minitest + +== Minitest related goods + +* minitest/pride fabric: https://www.spoonflower.com/fabric/3928730-again-by-katie_allen + +== REQUIREMENTS: + +* Ruby 2.3+. No magic is involved. I hope. + +== INSTALL: + + sudo gem install minitest + +On 1.9, you already have it. To get newer candy you can still install +the gem, and then requiring "minitest/autorun" should automatically +pull it in. If not, you'll need to do it yourself: + + gem "minitest" # ensures you"re using the gem, and not the built-in MT + require "minitest/autorun" + + # ... usual testing stuffs ... + +DO NOTE: There is a serious problem with the way that ruby 1.9/2.0 +packages their own gems. They install a gem specification file, but +don't install the gem contents in the gem path. This messes up +Gem.find_files and many other things (gem which, gem contents, etc). + +Just install minitest as a gem for real and you'll be happier. + +== LICENSE: + +(The MIT License) + +Copyright (c) Ryan Davis, seattle.rb + +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 AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/Rakefile b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/Rakefile new file mode 100644 index 00000000..d53528b5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/Rakefile @@ -0,0 +1,81 @@ +# -*- ruby -*- + +require "rubygems" +require "hoe" +$:.unshift "lib" # to pick up lib/minitest/test_task.rb when minitest not installed + +Hoe.plugin :seattlerb +Hoe.plugin :rdoc + +Hoe.spec "minitest" do + developer "Ryan Davis", "ryand-ruby@zenspider.com" + + license "MIT" + + require_ruby_version [">= 2.7", "< 4.0"] +end + +desc "Find missing expectations" +task :specs do + $:.unshift "lib" + require "minitest/test" + require "minitest/spec" + + pos_prefix, neg_prefix = "must", "wont" + skip_re = /^(must|wont)$|wont_(throw)|must_(block|not?_|nothing|send|raise$)/x + dont_flip_re = /(must|wont)_(include|respond_to)/ + + map = { + /(must_throw)s/ => '\1', + /(?!not)_same/ => "_be_same_as", + /_in_/ => "_be_within_", + /_operator/ => "_be", + /_includes/ => "_include", + /(must|wont)_(.*_of|nil|silent|empty)/ => '\1_be_\2', + /must_raises/ => "must_raise", + /(must|wont)_pattern/ => '\1_pattern_match', + /(must|wont)_predicate/ => '\1_be', + /(must|wont)_path_exists/ => 'path_\1_exist', + } + + expectations = Minitest::Expectations.public_instance_methods.map(&:to_s) + assertions = Minitest::Assertions.public_instance_methods.map(&:to_s) + + assertions.sort.each do |assertion| + expectation = case assertion + when /^assert/ then + assertion.sub(/^assert/, pos_prefix.to_s) + when /^refute/ then + assertion.sub(/^refute/, neg_prefix.to_s) + end + + next unless expectation + next if expectation =~ skip_re + + regexp, replacement = map.find { |re, _| expectation =~ re } + expectation.sub! regexp, replacement if replacement + + next if expectations.include? expectation + + args = [assertion, expectation].map(&:to_sym).map(&:inspect) + args << :reverse if expectation =~ dont_flip_re + + puts + puts "##" + puts "# :method: #{expectation}" + puts "# See Minitest::Assertions##{assertion}" + puts + puts "infect_an_assertion #{args.join ", "}" + end +end + +task :bugs do + sh "for f in bug*.rb ; do echo $f; echo; #{Gem.ruby} -Ilib $f && rm $f ; done" +end + +Minitest::TestTask.create :testW0 do |t| + t.warning = false + t.test_prelude = "$-w = nil" +end + +# vim: syntax=Ruby diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/design_rationale.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/design_rationale.rb new file mode 100644 index 00000000..a3fcc378 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/design_rationale.rb @@ -0,0 +1,52 @@ +# Specs: # Equivalent Unit Tests: +############################################################################### +describe Thingy do # class TestThingy < Minitest::Test + before do # def setup + do_some_setup # super + end # do_some_setup + # end + it "should do the first thing" do # + 1.must_equal 1 # def test_first_thing + end # assert_equal 1, 1 + # end + describe SubThingy do # end + before do # + do_more_setup # class TestSubThingy < TestThingy + end # def setup + # super + it "should do the second thing" do # do_more_setup + 2.must_equal 2 # end + end # + end # def test_second_thing +end # assert_equal 2, 2 + # end + # end +############################################################################### +# runs 2 specs # runs 3 tests +############################################################################### +# The specs generate: + +class ThingySpec < Minitest::Spec + def setup + super + do_some_setup + end + + def test_should_do_the_first_thing + assert_equal 1, 1 + end +end + +class SubThingySpec < ThingySpec + def setup + super + do_more_setup + end + + # because only setup/teardown is inherited, not specs + remove_method :test_should_do_the_first_thing + + def test_should_do_the_second_thing + assert_equal 2, 2 + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/hoe/minitest.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/hoe/minitest.rb new file mode 100644 index 00000000..4f59d3af --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/hoe/minitest.rb @@ -0,0 +1,29 @@ +# :stopdoc: + +class Hoe + # empty +end + +module Hoe::Minitest + def minitest? + self.name == "minitest" + end + + def initialize_minitest + unless minitest? then + dir = "../../minitest/dev/lib" + Hoe.add_include_dirs dir if File.directory? dir + end + + gem "minitest" + require "minitest" + version = Minitest::VERSION.split(".").first(2).join "." + + dependency "minitest", "~> #{version}", :development unless + minitest? or ENV["MT_NO_ISOLATE"] + end + + def define_minitest_tasks + self.testlib = :minitest + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest.rb new file mode 100644 index 00000000..b3a3bd71 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest.rb @@ -0,0 +1,1235 @@ +require "optparse" +require "stringio" +require "etc" + +require_relative "minitest/parallel" +require_relative "minitest/compress" + +## +# The top-level namespace for Minitest. Also the location of the main +# runtime. See +Minitest.run+ for more information. + +module Minitest + VERSION = "5.25.5" # :nodoc: + + @@installed_at_exit ||= false + @@after_run = [] + @extensions = [] + + def self.cattr_accessor name # :nodoc: + (class << self; self; end).attr_accessor name + end + + ## + # The random seed used for this run. This is used to srand at the + # start of the run and between each +Runnable.run+. + # + # Set via Minitest.run after processing args. + + cattr_accessor :seed + + ## + # Parallel test executor + + cattr_accessor :parallel_executor + + warn "DEPRECATED: use MT_CPU instead of N for parallel test runs" if ENV["N"] && ENV["N"].to_i > 0 + n_threads = (ENV["MT_CPU"] || ENV["N"] || Etc.nprocessors).to_i + + self.parallel_executor = Parallel::Executor.new n_threads + + ## + # Filter object for backtraces. + + cattr_accessor :backtrace_filter + + ## + # Reporter object to be used for all runs. + # + # NOTE: This accessor is only available during setup, not during runs. + + cattr_accessor :reporter + + ## + # Names of known extension plugins. + + cattr_accessor :extensions + + ## + # The signal to use for dumping information to STDERR. Defaults to "INFO". + + cattr_accessor :info_signal + self.info_signal = "INFO" + + cattr_accessor :allow_fork + self.allow_fork = false + + ## + # Registers Minitest to run at process exit + + def self.autorun + Warning[:deprecated] = true if + Object.const_defined?(:Warning) && Warning.respond_to?(:[]=) + + at_exit { + next if $! and not ($!.kind_of? SystemExit and $!.success?) + + exit_code = nil + + pid = Process.pid + at_exit { + next if !Minitest.allow_fork && Process.pid != pid + @@after_run.reverse_each(&:call) + exit exit_code || false + } + + exit_code = Minitest.run ARGV + } unless @@installed_at_exit + @@installed_at_exit = true + end + + ## + # A simple hook allowing you to run a block of code after everything + # is done running. Eg: + # + # Minitest.after_run { p $debugging_info } + + def self.after_run &block + @@after_run << block + end + + ## + # Register a plugin to be used. Does NOT require / load it. + + def self.register_plugin name_or_mod + self.extensions << name_or_mod + nil + end + + def self.load_plugins # :nodoc: + return unless defined? Gem + + seen = {} + + Gem.find_files("minitest/*_plugin.rb").each do |plugin_path| + name = File.basename plugin_path, "_plugin.rb" + + next if seen[name] + seen[name] = true + + require plugin_path + self.extensions << name + end + end + + def self.init_plugins options # :nodoc: + self.extensions.each do |mod_or_meth| + case mod_or_meth + when Symbol, String then + name = mod_or_meth + msg = "plugin_#{name}_init" + next unless self.respond_to? msg + send msg, options + when Module then + recv = mod_or_meth + next unless recv.respond_to? :minitest_plugin_init + recv.minitest_plugin_init options + else + raise ArgumentError, "plugin is %p, but it must be a symbol, string or module" % [mod_or_meth] + end + end + end + + def self.process_args args = [] # :nodoc: + options = { + :io => $stdout, + } + orig_args = args.dup + + OptionParser.new do |opts| + opts.banner = "minitest options:" + opts.version = Minitest::VERSION + + opts.on "-h", "--help", "Display this help." do + puts opts + exit + end + + opts.on "--no-plugins", "Bypass minitest plugin auto-loading (or set $MT_NO_PLUGINS)." + + desc = "Sets random seed. Also via env. Eg: SEED=n rake" + opts.on "-s", "--seed SEED", Integer, desc do |m| + options[:seed] = m.to_i + end + + opts.on "-v", "--verbose", "Verbose. Show progress processing files." do + options[:verbose] = true + end + + opts.on "-q", "--quiet", "Quiet. Show no progress processing files." do + options[:quiet] = true + end + + opts.on "--show-skips", "Show skipped at the end of run." do + options[:show_skips] = true + end + + opts.on "-n", "--name PATTERN", "Filter run on /regexp/ or string." do |a| + options[:filter] = a + end + + opts.on "-e", "--exclude PATTERN", "Exclude /regexp/ or string from run." do |a| + options[:exclude] = a + end + + opts.on "-S", "--skip CODES", String, "Skip reporting of certain types of results (eg E)." do |s| + options[:skip] = s.chars.to_a + end + + ruby27plus = ::Warning.respond_to? :[]= + + opts.on "-W[error]", String, "Turn Ruby warnings into errors" do |s| + options[:Werror] = true + case s + when "error", "all", nil then + require "minitest/error_on_warning" + $VERBOSE = true + ::Warning[:deprecated] = true if ruby27plus + else + ::Warning[s.to_sym] = true if ruby27plus # check validity of category + end + end + + unless extensions.empty? + opts.separator "" + opts.separator "Known extensions: #{extensions.join ", "}" + + extensions.each do |mod_or_meth| + case mod_or_meth + when Symbol, String then + meth = mod_or_meth + msg = "plugin_#{meth}_options" + send msg, opts, options if respond_to? msg + when Module + recv = mod_or_meth + next unless recv.respond_to? :minitest_plugin_options + recv.minitest_plugin_options opts, options + else + raise ArgumentError, "plugin is %p, but it must be a symbol, string or module" % [mod_or_meth] + end + end + end + + begin + opts.parse! args + rescue OptionParser::InvalidOption => e + puts + puts e + puts + puts opts + exit 1 + end + + orig_args -= args + end + + unless options[:seed] then + srand + options[:seed] = (ENV["SEED"] || srand).to_i % 0xFFFF + orig_args << "--seed" << options[:seed].to_s + end + + options[:args] = orig_args.map { |s| + s.match?(/[\s|&<>$()]/) ? s.inspect : s + }.join " " + + options + end + + ## + # This is the top-level run method. Everything starts from here. It + # tells each Runnable sub-class to run, and each of those are + # responsible for doing whatever they do. + # + # The overall structure of a run looks like this: + # + # Minitest.autorun + # Minitest.run(args) + # Minitest.load_plugins + # Minitest.process_args + # Minitest.init_plugins + # Minitest.__run(reporter, options) + # Runnable.runnables.each + # runnable_klass.run(reporter, options) + # self.runnable_methods.each + # self.run_one_method(self, runnable_method, reporter) + # Minitest.run_one_method(klass, runnable_method) + # klass.new(runnable_method).run + + def self.run args = [] + self.load_plugins unless args.delete("--no-plugins") || ENV["MT_NO_PLUGINS"] + + options = process_args args + + Minitest.seed = options[:seed] + srand Minitest.seed + + reporter = CompositeReporter.new + reporter << SummaryReporter.new(options[:io], options) + reporter << ProgressReporter.new(options[:io], options) unless options[:quiet] + + self.reporter = reporter # this makes it available to plugins + self.init_plugins options + self.reporter = nil # runnables shouldn't depend on the reporter, ever + + self.parallel_executor.start if parallel_executor.respond_to? :start + reporter.start + begin + __run reporter, options + rescue Interrupt + warn "Interrupted. Exiting..." + end + self.parallel_executor.shutdown + + # might have been removed/replaced during init_plugins: + summary = reporter.reporters.grep(SummaryReporter).first + + reporter.report + + return empty_run! options if summary && summary.count == 0 + reporter.passed? + end + + def self.empty_run! options # :nodoc: + filter = options[:filter] + return true unless filter # no filter, but nothing ran == success + + warn "Nothing ran for filter: %s" % [filter] + + require "did_you_mean" # soft dependency, punt if it doesn't load + + ms = Runnable.runnables.flat_map(&:runnable_methods) + cs = DidYouMean::SpellChecker.new(dictionary: ms).correct filter + + warn DidYouMean::Formatter.message_for cs unless cs.empty? + rescue LoadError + # do nothing + end + + ## + # Internal run method. Responsible for telling all Runnable + # sub-classes to run. + + def self.__run reporter, options + suites = Runnable.runnables.shuffle + parallel, serial = suites.partition { |s| s.test_order == :parallel } + + # If we run the parallel tests before the serial tests, the parallel tests + # could run in parallel with the serial tests. This would be bad because + # the serial tests won't lock around Reporter#record. Run the serial tests + # first, so that after they complete, the parallel tests will lock when + # recording results. + serial.map { |suite| suite.run reporter, options } + + parallel.map { |suite| suite.run reporter, options } + end + + def self.filter_backtrace bt # :nodoc: + result = backtrace_filter.filter bt + result = bt.dup if result.empty? + result + end + + ## + # Represents anything "runnable", like Test, Spec, Benchmark, or + # whatever you can dream up. + # + # Subclasses of this are automatically registered and available in + # Runnable.runnables. + + class Runnable + ## + # Number of assertions executed in this run. + + attr_accessor :assertions + + ## + # An assertion raised during the run, if any. + + attr_accessor :failures + + ## + # The time it took to run. + + attr_accessor :time + + def time_it # :nodoc: + t0 = Minitest.clock_time + + yield + ensure + self.time = Minitest.clock_time - t0 + end + + ## + # Name of the run. + + def name + @NAME + end + + ## + # Set the name of the run. + + def name= o + @NAME = o + end + + ## + # Returns all instance methods matching the pattern +re+. + + def self.methods_matching re + public_instance_methods(true).grep(re).map(&:to_s) + end + + def self.reset # :nodoc: + @@runnables = [] + end + + reset + + ## + # Responsible for running all runnable methods in a given class, + # each in its own instance. Each instance is passed to the + # reporter to record. + + def self.run reporter, options = {} + pos = options[:filter] + neg = options[:exclude] + + pos = Regexp.new $1 if pos.kind_of?(String) && pos =~ %r%/(.*)/% + neg = Regexp.new $1 if neg.kind_of?(String) && neg =~ %r%/(.*)/% + + filtered_methods = self.runnable_methods + .select { |m| !pos || pos === m || pos === "#{self}##{m}" } + .reject { |m| neg && (neg === m || neg === "#{self}##{m}") } + + return if filtered_methods.empty? + + t0 = name = nil + + @_info_handler = lambda do + unless reporter.passed? then + warn "Current results:" + warn reporter.reporters.grep(SummaryReporter).first + end + + warn "Current: %s#%s %.2fs" % [self, name, Minitest.clock_time - t0] + end + + with_info_handler reporter do + filtered_methods.each do |method_name| + name = method_name + t0 = Minitest.clock_time + + run_one_method self, method_name, reporter + end + end + end + + ## + # Runs a single method and has the reporter record the result. + # This was considered internal API but is factored out of run so + # that subclasses can specialize the running of an individual + # test. See Minitest::ParallelTest::ClassMethods for an example. + + def self.run_one_method klass, method_name, reporter + reporter.prerecord klass, method_name + reporter.record Minitest.run_one_method(klass, method_name) + end + + ## + # Defines the order to run tests (:random by default). Override + # this or use a convenience method to change it for your tests. + + def self.test_order + :random + end + + def self.with_info_handler reporter, &block # :nodoc: + on_signal ::Minitest.info_signal, @_info_handler, &block + end + + SIGNALS = Signal.list # :nodoc: + + def self.on_signal name, action # :nodoc: + supported = SIGNALS[name] + + old_trap = trap name do + old_trap.call if old_trap.respond_to? :call + action.call + end if supported + + yield + ensure + trap name, old_trap if supported + end + + ## + # Each subclass of Runnable is responsible for overriding this + # method to return all runnable methods. See #methods_matching. + + def self.runnable_methods + raise NotImplementedError, "subclass responsibility" + end + + ## + # Returns all subclasses of Runnable. + + def self.runnables + @@runnables + end + + @@marshal_dump_warned = false + + def marshal_dump # :nodoc: + unless @@marshal_dump_warned then + warn ["Minitest::Runnable#marshal_dump is deprecated.", + "You might be violating internals. From", caller(1..1).first].join " " + @@marshal_dump_warned = true + end + + [self.name, self.failures, self.assertions, self.time] + end + + def marshal_load ary # :nodoc: + self.name, self.failures, self.assertions, self.time = ary + end + + def failure # :nodoc: + self.failures.first + end + + def initialize name # :nodoc: + self.name = name + self.failures = [] + self.assertions = 0 + # lazy initializer for metadata + end + + ## + # Metadata you attach to the test results that get sent to the reporter. + # + # Lazily initializes to a hash, to keep memory down. + # + # NOTE: this data *must* be plain (read: marshal-able) data! + # Hashes! Arrays! Strings! + + def metadata + @metadata ||= {} + end + + ## + # Sets metadata, mainly used for +Result.from+. + + attr_writer :metadata + + ## + # Returns true if metadata exists. + + def metadata? + defined? @metadata + end + + ## + # Runs a single method. Needs to return self. + + def run + raise NotImplementedError, "subclass responsibility" + end + + ## + # Did this run pass? + # + # Note: skipped runs are not considered passing, but they don't + # cause the process to exit non-zero. + + def passed? + raise NotImplementedError, "subclass responsibility" + end + + ## + # Returns a single character string to print based on the result + # of the run. One of ".", "F", + # "E" or "S". + + def result_code + raise NotImplementedError, "subclass responsibility" + end + + ## + # Was this run skipped? See #passed? for more information. + + def skipped? + raise NotImplementedError, "subclass responsibility" + end + end + + ## + # Shared code for anything that can get passed to a Reporter. See + # Minitest::Test & Minitest::Result. + + module Reportable + ## + # Did this run pass? + # + # Note: skipped runs are not considered passing, but they don't + # cause the process to exit non-zero. + + def passed? + not self.failure + end + + BASE_DIR = "#{Dir.pwd}/" # :nodoc: + + ## + # The location identifier of this test. Depends on a method + # existing called class_name. + + def location + loc = " [#{self.failure.location.delete_prefix BASE_DIR}]" unless passed? or error? + "#{self.class_name}##{self.name}#{loc}" + end + + def class_name # :nodoc: + raise NotImplementedError, "subclass responsibility" + end + + ## + # Returns ".", "F", or "E" based on the result of the run. + + def result_code + self.failure and self.failure.result_code or "." + end + + ## + # Was this run skipped? + + def skipped? + self.failure and Skip === self.failure + end + + ## + # Did this run error? + + def error? + self.failures.any? UnexpectedError + end + end + + ## + # This represents a test result in a clean way that can be + # marshalled over a wire. Tests can do anything they want to the + # test instance and can create conditions that cause Marshal.dump to + # blow up. By using Result.from(a_test) you can be reasonably sure + # that the test result can be marshalled. + + class Result < Runnable + include Minitest::Reportable + + undef_method :marshal_dump + undef_method :marshal_load + + ## + # The class name of the test result. + + attr_accessor :klass + + ## + # The location of the test method. + + attr_accessor :source_location + + ## + # Create a new test result from a Runnable instance. + + def self.from runnable + o = runnable + + r = self.new o.name + r.klass = o.class.name + r.assertions = o.assertions + r.failures = o.failures.dup + r.time = o.time + r.metadata = o.metadata if o.metadata? + + r.source_location = o.method(o.name).source_location rescue ["unknown", -1] + + r + end + + def class_name # :nodoc: + self.klass # for Minitest::Reportable + end + + def to_s # :nodoc: + return location if passed? and not skipped? + + failures.map { |failure| + "#{failure.result_label}:\n#{self.location}:\n#{failure.message}\n" + }.join "\n" + end + end + + ## + # Defines the API for Reporters. Subclass this and override whatever + # you want. Go nuts. + + class AbstractReporter + + def initialize # :nodoc: + @mutex = Mutex.new + end + + ## + # Starts reporting on the run. + + def start + end + + ## + # About to start running a test. This allows a reporter to show + # that it is starting or that we are in the middle of a test run. + + def prerecord klass, name + end + + ## + # Output and record the result of the test. Call + # {result#result_code}[rdoc-ref:Runnable#result_code] to get the + # result character string. Stores the result of the run if the run + # did not pass. + + def record result + end + + ## + # Outputs the summary of the run. + + def report + end + + ## + # Did this run pass? + + def passed? + true + end + + def synchronize &block # :nodoc: + @mutex.synchronize(&block) + end + end + + class Reporter < AbstractReporter # :nodoc: + ## + # The IO used to report. + + attr_accessor :io + + ## + # Command-line options for this run. + + attr_accessor :options + + def initialize io = $stdout, options = {} # :nodoc: + super() + self.io = io + self.options = options + end + end + + ## + # A very simple reporter that prints the "dots" during the run. + # + # This is added to the top-level CompositeReporter at the start of + # the run. If you want to change the output of minitest via a + # plugin, pull this out of the composite and replace it with your + # own. + + class ProgressReporter < Reporter + def prerecord klass, name # :nodoc: + return unless options[:verbose] + + io.print "%s#%s = " % [klass.name, name] + io.flush + end + + def record result # :nodoc: + io.print "%.2f s = " % [result.time] if options[:verbose] + io.print result.result_code + io.puts if options[:verbose] + end + end + + ## + # A reporter that gathers statistics about a test run. Does not do + # any IO because meant to be used as a parent class for a reporter + # that does. + # + # If you want to create an entirely different type of output (eg, + # CI, HTML, etc), this is the place to start. + # + # Example: + # + # class JenkinsCIReporter < StatisticsReporter + # def report + # super # Needed to calculate some statistics + # + # print " #{new_bt.size}" + error.set_backtrace new_bt + end + + self.error = error + end + + def backtrace # :nodoc: + self.error.backtrace + end + + BASE_RE = %r%#{Dir.pwd}/% # :nodoc: + + def message # :nodoc: + bt = Minitest.filter_backtrace(self.backtrace).join("\n ") + .gsub(BASE_RE, "") + "#{self.error.class}: #{self.error.message}\n #{bt}" + end + + def result_label # :nodoc: + "Error" + end + end + + ## + # Assertion raised on warning when running in -Werror mode. + + class UnexpectedWarning < Assertion + def result_label # :nodoc: + "Warning" + end + end + + ## + # Provides a simple set of guards that you can use in your tests + # to skip execution if it is not applicable. These methods are + # mixed into Test as both instance and class methods so you + # can use them inside or outside of the test methods. + # + # def test_something_for_mri + # skip "bug 1234" if jruby? + # # ... + # end + # + # if windows? then + # # ... lots of test methods ... + # end + + module Guard + + ## + # Is this running on jruby? + + def jruby? platform = RUBY_PLATFORM + "java" == platform + end + + ## + # Is this running on maglev? + + def maglev? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE + where = Minitest.filter_backtrace(caller).first + where = where.split(":in ", 2).first # clean up noise + warn "DEPRECATED: `maglev?` called from #{where}. This will fail in Minitest 6." + "maglev" == platform + end + + ## + # Is this running on mri? + + def mri? platform = RUBY_DESCRIPTION + platform.start_with? "ruby" + end + + ## + # Is this running on macOS? + + def osx? platform = RUBY_PLATFORM + platform.include? "darwin" + end + + ## + # Is this running on rubinius? + + def rubinius? platform = defined?(RUBY_ENGINE) && RUBY_ENGINE + where = Minitest.filter_backtrace(caller).first + where = where.split(":in ", 2).first # clean up noise + warn "DEPRECATED: `rubinius?` called from #{where}. This will fail in Minitest 6." + "rbx" == platform + end + + ## + # Is this running on windows? + + def windows? platform = RUBY_PLATFORM + /mswin|mingw/.match? platform + end + end + + ## + # The standard backtrace filter for minitest. + # + # See Minitest.backtrace_filter=. + + class BacktraceFilter + + MT_RE = %r%lib/minitest|internal:warning% # :nodoc: + + ## + # The regular expression to use to filter backtraces. Defaults to +MT_RE+. + + attr_accessor :regexp + + def initialize regexp = MT_RE # :nodoc: + self.regexp = regexp + end + + ## + # Filter +bt+ to something useful. Returns the whole thing if + # $DEBUG (ruby) or $MT_DEBUG (env). + + def filter bt + return ["No backtrace"] unless bt + + return bt.dup if $DEBUG || ENV["MT_DEBUG"] + + new_bt = bt.take_while { |line| !regexp.match? line.to_s } + new_bt = bt.select { |line| !regexp.match? line.to_s } if new_bt.empty? + new_bt = bt.dup if new_bt.empty? + + new_bt + end + end + + self.backtrace_filter = BacktraceFilter.new + + def self.run_one_method klass, method_name # :nodoc: + result = klass.new(method_name).run + raise "#{klass}#run _must_ return a Result" unless Result === result + result + end + + # :stopdoc: + + if defined? Process::CLOCK_MONOTONIC # :nodoc: + def self.clock_time + Process.clock_gettime Process::CLOCK_MONOTONIC + end + else + def self.clock_time + Time.now + end + end + + class Runnable # re-open + def self.inherited klass # :nodoc: + self.runnables << klass + super + end + end + + # :startdoc: +end + +require "minitest/test" diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/assertions.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/assertions.rb new file mode 100644 index 00000000..bbc9aab9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/assertions.rb @@ -0,0 +1,855 @@ +require "rbconfig" +require "tempfile" +require "stringio" + +module Minitest + ## + # Minitest Assertions. All assertion methods accept a +msg+ which is + # printed if the assertion fails. + # + # Protocol: Nearly everything here boils up to +assert+, which + # expects to be able to increment an instance accessor named + # +assertions+. This is not provided by Assertions and must be + # provided by the thing including Assertions. See Minitest::Runnable + # for an example. + + module Assertions + UNDEFINED = Object.new # :nodoc: + + def UNDEFINED.inspect # :nodoc: + "UNDEFINED" # again with the rdoc bugs... :( + end + + ## + # Returns the diff command to use in #diff. Tries to intelligently + # figure out what diff to use. + + def self.diff + return @diff if defined? @diff + + @diff = if (RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ and + system "diff.exe", __FILE__, __FILE__) then + "diff.exe -u" + elsif system "gdiff", __FILE__, __FILE__ then + "gdiff -u" # solaris and kin suck + elsif system "diff", __FILE__, __FILE__ then + "diff -u" + else + nil + end + end + + ## + # Set the diff command to use in #diff. + + def self.diff= o + @diff = o + end + + ## + # Returns a diff between +exp+ and +act+. If there is no known + # diff command or if it doesn't make sense to diff the output + # (single line, short output), then it simply returns a basic + # comparison between the two. + # + # See +things_to_diff+ for more info. + + def diff exp, act + result = nil + + expect, butwas = things_to_diff exp, act + + return "Expected: #{mu_pp exp}\n Actual: #{mu_pp act}" unless + expect + + Tempfile.open "expect" do |a| + a.puts expect + a.flush + + Tempfile.open "butwas" do |b| + b.puts butwas + b.flush + + result = `#{Minitest::Assertions.diff} #{a.path} #{b.path}` + result.sub!(/^\-\-\- .+/, "--- expected") + result.sub!(/^\+\+\+ .+/, "+++ actual") + + if result.empty? then + klass = exp.class + result = [ + "No visible difference in the #{klass}#inspect output.\n", + "You should look at the implementation of #== on ", + "#{klass} or its members.\n", + expect, + ].join + end + end + end + + result + end + + ## + # Returns things to diff [expect, butwas], or [nil, nil] if nothing to diff. + # + # Criterion: + # + # 1. Strings include newlines or escaped newlines, but not both. + # 2. or: String lengths are > 30 characters. + # 3. or: Strings are equal to each other (but maybe different encodings?). + # 4. and: we found a diff executable. + + def things_to_diff exp, act + expect = mu_pp_for_diff exp + butwas = mu_pp_for_diff act + + e1, e2 = expect.include?("\n"), expect.include?("\\n") + b1, b2 = butwas.include?("\n"), butwas.include?("\\n") + + need_to_diff = + (e1 ^ e2 || + b1 ^ b2 || + expect.size > 30 || + butwas.size > 30 || + expect == butwas) && + Minitest::Assertions.diff + + need_to_diff && [expect, butwas] + end + + ## + # This returns a human-readable version of +obj+. By default + # #inspect is called. You can override this to use #pretty_inspect + # if you want. + # + # See Minitest::Test.make_my_diffs_pretty! + + def mu_pp obj + s = obj.inspect.encode Encoding.default_external + + return s unless String === obj && + (obj.encoding != Encoding.default_external || !obj.valid_encoding?) + + enc = "# encoding: #{obj.encoding}" + val = "# valid: #{obj.valid_encoding?}" + + [enc, val, s].join "\n" + end + + ## + # This returns a diff-able more human-readable version of +obj+. + # This differs from the regular mu_pp because it expands escaped + # newlines and makes hex-values (like object_ids) generic. This + # uses mu_pp to do the first pass and then cleans it up. + + def mu_pp_for_diff obj + str = mu_pp obj + + # both '\n' & '\\n' (_after_ mu_pp (aka inspect)) + single = str.match?(/(?exp == act printing the difference between + # the two, if possible. + # + # If there is no visible difference but the assertion fails, you + # should suspect that your #== is buggy, or your inspect output is + # missing crucial details. For nicer structural diffing, set + # Minitest::Test.make_my_diffs_pretty! + # + # For floats use assert_in_delta. + # + # See also: Minitest::Assertions.diff + + def assert_equal exp, act, msg = nil + msg = message(msg, E) { diff exp, act } + result = assert exp == act, msg + + if nil == exp then + if Minitest::VERSION >= "6" then + refute_nil exp, "Use assert_nil if expecting nil." + else + warn "DEPRECATED: Use assert_nil if expecting nil from #{_where}. This will fail in Minitest 6." + end + end + + result + end + + ## + # For comparing Floats. Fails unless +exp+ and +act+ are within +delta+ + # of each other. + # + # assert_in_delta Math::PI, (22.0 / 7.0), 0.01 + + def assert_in_delta exp, act, delta = 0.001, msg = nil + n = (exp - act).abs + msg = message(msg) { + "Expected |#{exp} - #{act}| (#{n}) to be <= #{delta}" + } + assert delta >= n, msg + end + + ## + # For comparing Floats. Fails unless +exp+ and +act+ have a relative + # error less than +epsilon+. + + def assert_in_epsilon exp, act, epsilon = 0.001, msg = nil + assert_in_delta exp, act, [exp.abs, act.abs].min * epsilon, msg + end + + ## + # Fails unless +collection+ includes +obj+. + + def assert_includes collection, obj, msg = nil + msg = message(msg) { + "Expected #{mu_pp collection} to include #{mu_pp obj}" + } + assert_respond_to collection, :include? + assert collection.include?(obj), msg + end + + ## + # Fails unless +obj+ is an instance of +cls+. + + def assert_instance_of cls, obj, msg = nil + msg = message(msg) { + "Expected #{mu_pp obj} to be an instance of #{cls}, not #{obj.class}" + } + + assert obj.instance_of?(cls), msg + end + + ## + # Fails unless +obj+ is a kind of +cls+. + + def assert_kind_of cls, obj, msg = nil + msg = message(msg) { + "Expected #{mu_pp obj} to be a kind of #{cls}, not #{obj.class}" + } + + assert obj.kind_of?(cls), msg + end + + ## + # Fails unless +matcher+ =~ +obj+. + + def assert_match matcher, obj, msg = nil + msg = message(msg) { "Expected #{mu_pp matcher} to match #{mu_pp obj}" } + assert_respond_to matcher, :=~ + matcher = Regexp.new Regexp.escape matcher if String === matcher + assert matcher =~ obj, msg + + Regexp.last_match + end + + ## + # Fails unless +obj+ is nil + + def assert_nil obj, msg = nil + msg = message(msg) { "Expected #{mu_pp obj} to be nil" } + assert obj.nil?, msg + end + + ## + # For testing with binary operators. Eg: + # + # assert_operator 5, :<=, 4 + + def assert_operator o1, op, o2 = UNDEFINED, msg = nil + return assert_predicate o1, op, msg if UNDEFINED == o2 + msg = message(msg) { "Expected #{mu_pp o1} to be #{op} #{mu_pp o2}" } + assert o1.__send__(op, o2), msg + end + + ## + # Fails if stdout or stderr do not output the expected results. + # Pass in nil if you don't care about that streams output. Pass in + # "" if you require it to be silent. Pass in a regexp if you want + # to pattern match. + # + # assert_output(/hey/) { method_with_output } + # + # NOTE: this uses #capture_io, not #capture_subprocess_io. + # + # See also: #assert_silent + + def assert_output stdout = nil, stderr = nil + flunk "assert_output requires a block to capture output." unless + block_given? + + out, err = capture_io do + yield + end + + err_msg = Regexp === stderr ? :assert_match : :assert_equal if stderr + out_msg = Regexp === stdout ? :assert_match : :assert_equal if stdout + + y = send err_msg, stderr, err, "In stderr" if err_msg + x = send out_msg, stdout, out, "In stdout" if out_msg + + (!stdout || x) && (!stderr || y) + rescue Assertion + raise + rescue => e + raise UnexpectedError, e + end + + ## + # Fails unless +path+ exists. + + def assert_path_exists path, msg = nil + msg = message(msg) { "Expected path '#{path}' to exist" } + assert File.exist?(path), msg + end + + ## + # For testing with pattern matching (only supported with Ruby 3.0 and later) + # + # # pass + # assert_pattern { [1,2,3] => [Integer, Integer, Integer] } + # + # # fail "length mismatch (given 3, expected 1)" + # assert_pattern { [1,2,3] => [Integer] } + # + # The bare => pattern will raise a NoMatchingPatternError on failure, which would + # normally be counted as a test error. This assertion rescues NoMatchingPatternError and + # generates a test failure. Any other exception will be raised as normal and generate a test + # error. + + def assert_pattern + raise NotImplementedError, "only available in Ruby 3.0+" unless RUBY_VERSION >= "3.0" + flunk "assert_pattern requires a block to capture errors." unless block_given? + + begin # TODO: remove after ruby 2.6 dropped + yield + pass + rescue NoMatchingPatternError => e + flunk e.message + end + end + + ## + # For testing with predicates. Eg: + # + # assert_predicate str, :empty? + # + # This is really meant for specs and is front-ended by assert_operator: + # + # str.must_be :empty? + + def assert_predicate o1, op, msg = nil + msg = message(msg) { "Expected #{mu_pp o1} to be #{op}" } + assert o1.__send__(op), msg + end + + ## + # Fails unless the block raises one of +exp+. Returns the + # exception matched so you can check the message, attributes, etc. + # + # +exp+ takes an optional message on the end to help explain + # failures and defaults to StandardError if no exception class is + # passed. Eg: + # + # assert_raises(CustomError) { method_with_custom_error } + # + # With custom error message: + # + # assert_raises(CustomError, 'This should have raised CustomError') { method_with_custom_error } + # + # Using the returned object: + # + # error = assert_raises(CustomError) do + # raise CustomError, 'This is really bad' + # end + # + # assert_equal 'This is really bad', error.message + + def assert_raises *exp + flunk "assert_raises requires a block to capture errors." unless + block_given? + + msg = "#{exp.pop}.\n" if String === exp.last + exp << StandardError if exp.empty? + + begin + yield + rescue *exp => e + pass # count assertion + return e + rescue Minitest::Assertion # incl Skip & UnexpectedError + # don't count assertion + raise + rescue SignalException, SystemExit + raise + rescue Exception => e + flunk proc { + exception_details(e, "#{msg}#{mu_pp exp} exception expected, not") + } + end + + exp = exp.first if exp.size == 1 + + flunk "#{msg}#{mu_pp exp} expected but nothing was raised." + end + + ## + # Fails unless +obj+ responds to +meth+. + # include_all defaults to false to match Object#respond_to? + + def assert_respond_to obj, meth, msg = nil, include_all: false + msg = message(msg) { + "Expected #{mu_pp obj} (#{obj.class}) to respond to ##{meth}" + } + assert obj.respond_to?(meth, include_all), msg + end + + ## + # Fails unless +exp+ and +act+ are #equal? + + def assert_same exp, act, msg = nil + msg = message(msg) { + data = [mu_pp(act), act.object_id, mu_pp(exp), exp.object_id] + "Expected %s (oid=%d) to be the same as %s (oid=%d)" % data + } + assert exp.equal?(act), msg + end + + ## + # +send_ary+ is a receiver, message and arguments. + # + # Fails unless the call returns a true value + + def assert_send send_ary, m = nil + warn "DEPRECATED: assert_send. From #{_where}" + + recv, msg, *args = send_ary + m = message(m) { + "Expected #{mu_pp recv}.#{msg}(*#{mu_pp args}) to return true" + } + assert recv.__send__(msg, *args), m + end + + ## + # Fails if the block outputs anything to stderr or stdout. + # + # See also: #assert_output + + def assert_silent + assert_output "", "" do + yield + end + end + + ## + # Fails unless the block throws +sym+ + + def assert_throws sym, msg = nil + default = "Expected #{mu_pp sym} to have been thrown" + caught = true + value = catch sym do + begin + yield + rescue ThreadError => e # wtf?!? 1.8 + threads == suck + default += ", not :#{e.message[/uncaught throw \`(\w+?)\'/, 1]}" + rescue ArgumentError => e # 1.9 exception + raise e unless e.message.include? "uncaught throw" + default += ", not #{e.message.split(/ /).last}" + rescue NameError => e # 1.8 exception + raise e unless e.name == sym + default += ", not #{e.name.inspect}" + end + caught = false + end + + assert caught, message(msg) { default } + value + rescue Assertion + raise + rescue => e + raise UnexpectedError, e + end + + ## + # Captures $stdout and $stderr into strings: + # + # out, err = capture_io do + # puts "Some info" + # warn "You did a bad thing" + # end + # + # assert_match %r%info%, out + # assert_match %r%bad%, err + # + # NOTE: For efficiency, this method uses StringIO and does not + # capture IO for subprocesses. Use #capture_subprocess_io for + # that. + + def capture_io + _synchronize do + begin + captured_stdout, captured_stderr = StringIO.new, StringIO.new + + orig_stdout, orig_stderr = $stdout, $stderr + $stdout, $stderr = captured_stdout, captured_stderr + + yield + + return captured_stdout.string, captured_stderr.string + ensure + $stdout = orig_stdout + $stderr = orig_stderr + end + end + end + + ## + # Captures $stdout and $stderr into strings, using Tempfile to + # ensure that subprocess IO is captured as well. + # + # out, err = capture_subprocess_io do + # system "echo Some info" + # system "echo You did a bad thing 1>&2" + # end + # + # assert_match %r%info%, out + # assert_match %r%bad%, err + # + # NOTE: This method is approximately 10x slower than #capture_io so + # only use it when you need to test the output of a subprocess. + + def capture_subprocess_io + _synchronize do + begin + require "tempfile" + + captured_stdout, captured_stderr = Tempfile.new("out"), Tempfile.new("err") + + orig_stdout, orig_stderr = $stdout.dup, $stderr.dup + $stdout.reopen captured_stdout + $stderr.reopen captured_stderr + + yield + + $stdout.rewind + $stderr.rewind + + return captured_stdout.read, captured_stderr.read + ensure + $stdout.reopen orig_stdout + $stderr.reopen orig_stderr + + orig_stdout.close + orig_stderr.close + captured_stdout.close! + captured_stderr.close! + end + end + end + + ## + # Returns details for exception +e+ + + def exception_details e, msg + [ + msg, + "Class: <#{e.class}>", + "Message: <#{e.message.inspect}>", + "---Backtrace---", + Minitest.filter_backtrace(e.backtrace), + "---------------", + ].join "\n" + end + + ## + # Fails after a given date (in the local time zone). This allows + # you to put time-bombs in your tests if you need to keep + # something around until a later date lest you forget about it. + + def fail_after y, m, d, msg + flunk msg if Time.now > Time.local(y, m, d) + end + + ## + # Fails with +msg+. + + def flunk msg = nil + msg ||= "Epic Fail!" + assert false, msg + end + + ## + # Returns a proc that will output +msg+ along with the default message. + + def message msg = nil, ending = nil, &default + proc { + msg = msg.call.chomp(".") if Proc === msg + custom_message = "#{msg}.\n" unless msg.nil? or msg.to_s.empty? + "#{custom_message}#{default.call}#{ending || "."}" + } + end + + ## + # used for counting assertions + + def pass _msg = nil + assert true + end + + ## + # Fails if +test+ is truthy. + + def refute test, msg = nil + msg ||= message { "Expected #{mu_pp test} to not be truthy" } + assert !test, msg + end + + ## + # Fails if +obj+ is empty. + + def refute_empty obj, msg = nil + msg = message(msg) { "Expected #{mu_pp obj} to not be empty" } + assert_respond_to obj, :empty? + refute obj.empty?, msg + end + + ## + # Fails if exp == act. + # + # For floats use refute_in_delta. + + def refute_equal exp, act, msg = nil + msg = message(msg) { + "Expected #{mu_pp act} to not be equal to #{mu_pp exp}" + } + refute exp == act, msg + end + + ## + # For comparing Floats. Fails if +exp+ is within +delta+ of +act+. + # + # refute_in_delta Math::PI, (22.0 / 7.0) + + def refute_in_delta exp, act, delta = 0.001, msg = nil + n = (exp - act).abs + msg = message(msg) { + "Expected |#{exp} - #{act}| (#{n}) to not be <= #{delta}" + } + refute delta >= n, msg + end + + ## + # For comparing Floats. Fails if +exp+ and +act+ have a relative error + # less than +epsilon+. + + def refute_in_epsilon a, b, epsilon = 0.001, msg = nil + refute_in_delta a, b, a * epsilon, msg + end + + ## + # Fails if +collection+ includes +obj+. + + def refute_includes collection, obj, msg = nil + msg = message(msg) { + "Expected #{mu_pp collection} to not include #{mu_pp obj}" + } + assert_respond_to collection, :include? + refute collection.include?(obj), msg + end + + ## + # Fails if +obj+ is an instance of +cls+. + + def refute_instance_of cls, obj, msg = nil + msg = message(msg) { + "Expected #{mu_pp obj} to not be an instance of #{cls}" + } + refute obj.instance_of?(cls), msg + end + + ## + # Fails if +obj+ is a kind of +cls+. + + def refute_kind_of cls, obj, msg = nil + msg = message(msg) { "Expected #{mu_pp obj} to not be a kind of #{cls}" } + refute obj.kind_of?(cls), msg + end + + ## + # Fails if +matcher+ =~ +obj+. + + def refute_match matcher, obj, msg = nil + msg = message(msg) { "Expected #{mu_pp matcher} to not match #{mu_pp obj}" } + assert_respond_to matcher, :=~ + matcher = Regexp.new Regexp.escape matcher if String === matcher + refute matcher =~ obj, msg + end + + ## + # Fails if +obj+ is nil. + + def refute_nil obj, msg = nil + msg = message(msg) { "Expected #{mu_pp obj} to not be nil" } + refute obj.nil?, msg + end + + ## + # For testing with pattern matching (only supported with Ruby 3.0 and later) + # + # # pass + # refute_pattern { [1,2,3] => [String] } + # + # # fail "NoMatchingPatternError expected, but nothing was raised." + # refute_pattern { [1,2,3] => [Integer, Integer, Integer] } + # + # This assertion expects a NoMatchingPatternError exception, and will fail if none is raised. Any + # other exceptions will be raised as normal and generate a test error. + + def refute_pattern + raise NotImplementedError, "only available in Ruby 3.0+" unless RUBY_VERSION >= "3.0" + flunk "refute_pattern requires a block to capture errors." unless block_given? + + begin + yield + flunk "NoMatchingPatternError expected, but nothing was raised." + rescue NoMatchingPatternError + pass + end + end + + ## + # Fails if +o1+ is not +op+ +o2+. Eg: + # + # refute_operator 1, :>, 2 #=> pass + # refute_operator 1, :<, 2 #=> fail + + def refute_operator o1, op, o2 = UNDEFINED, msg = nil + return refute_predicate o1, op, msg if UNDEFINED == o2 + msg = message(msg) { "Expected #{mu_pp o1} to not be #{op} #{mu_pp o2}" } + refute o1.__send__(op, o2), msg + end + + ## + # Fails if +path+ exists. + + def refute_path_exists path, msg = nil + msg = message(msg) { "Expected path '#{path}' to not exist" } + refute File.exist?(path), msg + end + + ## + # For testing with predicates. + # + # refute_predicate str, :empty? + # + # This is really meant for specs and is front-ended by refute_operator: + # + # str.wont_be :empty? + + def refute_predicate o1, op, msg = nil + msg = message(msg) { "Expected #{mu_pp o1} to not be #{op}" } + refute o1.__send__(op), msg + end + + ## + # Fails if +obj+ responds to the message +meth+. + # include_all defaults to false to match Object#respond_to? + + def refute_respond_to obj, meth, msg = nil, include_all: false + msg = message(msg) { "Expected #{mu_pp obj} to not respond to #{meth}" } + + refute obj.respond_to?(meth, include_all), msg + end + + ## + # Fails if +exp+ is the same (by object identity) as +act+. + + def refute_same exp, act, msg = nil + msg = message(msg) { + data = [mu_pp(act), act.object_id, mu_pp(exp), exp.object_id] + "Expected %s (oid=%d) to not be the same as %s (oid=%d)" % data + } + refute exp.equal?(act), msg + end + + ## + # Skips the current run. If run in verbose-mode, the skipped run + # gets listed at the end of the run but doesn't cause a failure + # exit code. + + def skip msg = nil, _ignored = nil + msg ||= "Skipped, no message given" + @skip = true + raise Minitest::Skip, msg + end + + ## + # Skips the current run until a given date (in the local time + # zone). This allows you to put some fixes on hold until a later + # date, but still holds you accountable and prevents you from + # forgetting it. + + def skip_until y, m, d, msg + skip msg if Time.now < Time.local(y, m, d) + where = caller(1..1).first.rpartition(":in").reject(&:empty?).first + warn "Stale skip_until %p at %s" % [msg, where] + end + + ## + # Was this testcase skipped? Meant for #teardown. + + def skipped? + defined?(@skip) and @skip + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/autorun.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/autorun.rb new file mode 100644 index 00000000..0555eff9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/autorun.rb @@ -0,0 +1,6 @@ +require "minitest" +require "minitest/spec" +require "minitest/mock" +require "minitest/hell" if ENV["MT_HELL"] + +Minitest.autorun diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/benchmark.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/benchmark.rb new file mode 100644 index 00000000..defdbcb3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/benchmark.rb @@ -0,0 +1,452 @@ +require "minitest/test" +require "minitest/spec" + +module Minitest + ## + # Subclass Benchmark to create your own benchmark runs. Methods + # starting with "bench_" get executed on a per-class. + # + # See Minitest::Assertions + + class Benchmark < Test + def self.io # :nodoc: + @io + end + + def io # :nodoc: + self.class.io + end + + def self.run reporter, options = {} # :nodoc: + @io = reporter.io + super + end + + def self.runnable_methods # :nodoc: + methods_matching(/^bench_/) + end + + ## + # Returns a set of ranges stepped exponentially from +min+ to + # +max+ by powers of +base+. Eg: + # + # bench_exp(2, 16, 2) # => [2, 4, 8, 16] + + def self.bench_exp min, max, base = 10 + min = (Math.log10(min) / Math.log10(base)).to_i + max = (Math.log10(max) / Math.log10(base)).to_i + + (min..max).map { |m| base ** m }.to_a + end + + ## + # Returns a set of ranges stepped linearly from +min+ to +max+ by + # +step+. Eg: + # + # bench_linear(20, 40, 10) # => [20, 30, 40] + + def self.bench_linear min, max, step = 10 + (min..max).step(step).to_a + end + + ## + # Specifies the ranges used for benchmarking for that class. + # Defaults to exponential growth from 1 to 10k by powers of 10. + # Override if you need different ranges for your benchmarks. + # + # See also: ::bench_exp and ::bench_linear. + + def self.bench_range + bench_exp 1, 10_000 + end + + ## + # Runs the given +work+, gathering the times of each run. Range + # and times are then passed to a given +validation+ proc. Outputs + # the benchmark name and times in tab-separated format, making it + # easy to paste into a spreadsheet for graphing or further + # analysis. + # + # Ranges are specified by ::bench_range. + # + # Eg: + # + # def bench_algorithm + # validation = proc { |x, y| ... } + # assert_performance validation do |n| + # @obj.algorithm(n) + # end + # end + + def assert_performance validation, &work + range = self.class.bench_range + + io.print self.name + + times = [] + + range.each do |x| + GC.start + t0 = Minitest.clock_time + instance_exec(x, &work) + t = Minitest.clock_time - t0 + + io.print "\t%9.6f" % t + times << t + end + io.puts + + validation[range, times] + end + + ## + # Runs the given +work+ and asserts that the times gathered fit to + # match a constant rate (eg, linear slope == 0) within a given + # +threshold+. Note: because we're testing for a slope of 0, R^2 + # is not a good determining factor for the fit, so the threshold + # is applied against the slope itself. As such, you probably want + # to tighten it from the default. + # + # See https://www.graphpad.com/guides/prism/8/curve-fitting/reg_intepretingnonlinr2.htm + # for more details. + # + # Fit is calculated by #fit_linear. + # + # Ranges are specified by ::bench_range. + # + # Eg: + # + # def bench_algorithm + # assert_performance_constant 0.9999 do |n| + # @obj.algorithm(n) + # end + # end + + def assert_performance_constant threshold = 0.99, &work + validation = proc do |range, times| + a, b, rr = fit_linear range, times + assert_in_delta 0, b, 1 - threshold + [a, b, rr] + end + + assert_performance validation, &work + end + + ## + # Runs the given +work+ and asserts that the times gathered fit to + # match a exponential curve within a given error +threshold+. + # + # Fit is calculated by #fit_exponential. + # + # Ranges are specified by ::bench_range. + # + # Eg: + # + # def bench_algorithm + # assert_performance_exponential 0.9999 do |n| + # @obj.algorithm(n) + # end + # end + + def assert_performance_exponential threshold = 0.99, &work + assert_performance validation_for_fit(:exponential, threshold), &work + end + + ## + # Runs the given +work+ and asserts that the times gathered fit to + # match a logarithmic curve within a given error +threshold+. + # + # Fit is calculated by #fit_logarithmic. + # + # Ranges are specified by ::bench_range. + # + # Eg: + # + # def bench_algorithm + # assert_performance_logarithmic 0.9999 do |n| + # @obj.algorithm(n) + # end + # end + + def assert_performance_logarithmic threshold = 0.99, &work + assert_performance validation_for_fit(:logarithmic, threshold), &work + end + + ## + # Runs the given +work+ and asserts that the times gathered fit to + # match a straight line within a given error +threshold+. + # + # Fit is calculated by #fit_linear. + # + # Ranges are specified by ::bench_range. + # + # Eg: + # + # def bench_algorithm + # assert_performance_linear 0.9999 do |n| + # @obj.algorithm(n) + # end + # end + + def assert_performance_linear threshold = 0.99, &work + assert_performance validation_for_fit(:linear, threshold), &work + end + + ## + # Runs the given +work+ and asserts that the times gathered curve + # fit to match a power curve within a given error +threshold+. + # + # Fit is calculated by #fit_power. + # + # Ranges are specified by ::bench_range. + # + # Eg: + # + # def bench_algorithm + # assert_performance_power 0.9999 do |x| + # @obj.algorithm + # end + # end + + def assert_performance_power threshold = 0.99, &work + assert_performance validation_for_fit(:power, threshold), &work + end + + ## + # Takes an array of x/y pairs and calculates the general R^2 value. + # + # See: https://en.wikipedia.org/wiki/Coefficient_of_determination + + def fit_error xys + y_bar = sigma(xys) { |_, y| y } / xys.size.to_f + ss_tot = sigma(xys) { |_, y| (y - y_bar) ** 2 } + ss_err = sigma(xys) { |x, y| (yield(x) - y) ** 2 } + + 1 - (ss_err / ss_tot) + end + + ## + # To fit a functional form: y = ae^(bx). + # + # Takes x and y values and returns [a, b, r^2]. + # + # See: https://mathworld.wolfram.com/LeastSquaresFittingExponential.html + + def fit_exponential xs, ys + n = xs.size + xys = xs.zip ys + sxlny = sigma(xys) { |x, y| x * Math.log(y) } + slny = sigma(xys) { |_, y| Math.log(y) } + sx2 = sigma(xys) { |x, _| x * x } + sx = sigma xs + + c = n * sx2 - sx ** 2 + a = (slny * sx2 - sx * sxlny) / c + b = ( n * sxlny - sx * slny ) / c + + return Math.exp(a), b, fit_error(xys) { |x| Math.exp(a + b * x) } + end + + ## + # To fit a functional form: y = a + b*ln(x). + # + # Takes x and y values and returns [a, b, r^2]. + # + # See: https://mathworld.wolfram.com/LeastSquaresFittingLogarithmic.html + + def fit_logarithmic xs, ys + n = xs.size + xys = xs.zip ys + slnx2 = sigma(xys) { |x, _| Math.log(x) ** 2 } + slnx = sigma(xys) { |x, _| Math.log(x) } + sylnx = sigma(xys) { |x, y| y * Math.log(x) } + sy = sigma(xys) { |_, y| y } + + c = n * slnx2 - slnx ** 2 + b = ( n * sylnx - sy * slnx ) / c + a = (sy - b * slnx) / n + + return a, b, fit_error(xys) { |x| a + b * Math.log(x) } + end + + ## + # Fits the functional form: a + bx. + # + # Takes x and y values and returns [a, b, r^2]. + # + # See: https://mathworld.wolfram.com/LeastSquaresFitting.html + + def fit_linear xs, ys + n = xs.size + xys = xs.zip ys + sx = sigma xs + sy = sigma ys + sx2 = sigma(xs) { |x| x ** 2 } + sxy = sigma(xys) { |x, y| x * y } + + c = n * sx2 - sx**2 + a = (sy * sx2 - sx * sxy) / c + b = ( n * sxy - sx * sy ) / c + + return a, b, fit_error(xys) { |x| a + b * x } + end + + ## + # To fit a functional form: y = ax^b. + # + # Takes x and y values and returns [a, b, r^2]. + # + # See: https://mathworld.wolfram.com/LeastSquaresFittingPowerLaw.html + + def fit_power xs, ys + n = xs.size + xys = xs.zip ys + slnxlny = sigma(xys) { |x, y| Math.log(x) * Math.log(y) } + slnx = sigma(xs) { |x | Math.log(x) } + slny = sigma(ys) { | y| Math.log(y) } + slnx2 = sigma(xs) { |x | Math.log(x) ** 2 } + + b = (n * slnxlny - slnx * slny) / (n * slnx2 - slnx ** 2) + a = (slny - b * slnx) / n + + return Math.exp(a), b, fit_error(xys) { |x| (Math.exp(a) * (x ** b)) } + end + + ## + # Enumerates over +enum+ mapping +block+ if given, returning the + # sum of the result. Eg: + # + # sigma([1, 2, 3]) # => 1 + 2 + 3 => 6 + # sigma([1, 2, 3]) { |n| n ** 2 } # => 1 + 4 + 9 => 14 + + def sigma enum, &block + enum = enum.map(&block) if block + enum.sum + end + + ## + # Returns a proc that calls the specified fit method and asserts + # that the error is within a tolerable threshold. + + def validation_for_fit msg, threshold + proc do |range, times| + a, b, rr = send "fit_#{msg}", range, times + assert_operator rr, :>=, threshold + [a, b, rr] + end + end + end +end + +module Minitest + ## + # The spec version of Minitest::Benchmark. + + class BenchSpec < Benchmark + extend Minitest::Spec::DSL + + ## + # This is used to define a new benchmark method. You usually don't + # use this directly and is intended for those needing to write new + # performance curve fits (eg: you need a specific polynomial fit). + # + # See ::bench_performance_linear for an example of how to use this. + + def self.bench name, &block + define_method "bench_#{name.gsub(/\W+/, "_")}", &block + end + + ## + # Specifies the ranges used for benchmarking for that class. + # + # bench_range do + # bench_exp(2, 16, 2) + # end + # + # See Minitest::Benchmark#bench_range for more details. + + def self.bench_range &block + return super unless block + + meta = (class << self; self; end) + meta.send :define_method, "bench_range", &block + end + + ## + # Create a benchmark that verifies that the performance is linear. + # + # describe "my class Bench" do + # bench_performance_linear "fast_algorithm", 0.9999 do |n| + # @obj.fast_algorithm(n) + # end + # end + + def self.bench_performance_linear name, threshold = 0.99, &work + bench name do + assert_performance_linear threshold, &work + end + end + + ## + # Create a benchmark that verifies that the performance is constant. + # + # describe "my class Bench" do + # bench_performance_constant "zoom_algorithm!" do |n| + # @obj.zoom_algorithm!(n) + # end + # end + + def self.bench_performance_constant name, threshold = 0.99, &work + bench name do + assert_performance_constant threshold, &work + end + end + + ## + # Create a benchmark that verifies that the performance is exponential. + # + # describe "my class Bench" do + # bench_performance_exponential "algorithm" do |n| + # @obj.algorithm(n) + # end + # end + + def self.bench_performance_exponential name, threshold = 0.99, &work + bench name do + assert_performance_exponential threshold, &work + end + end + + ## + # Create a benchmark that verifies that the performance is logarithmic. + # + # describe "my class Bench" do + # bench_performance_logarithmic "algorithm" do |n| + # @obj.algorithm(n) + # end + # end + + def self.bench_performance_logarithmic name, threshold = 0.99, &work + bench name do + assert_performance_logarithmic threshold, &work + end + end + + ## + # Create a benchmark that verifies that the performance is power. + # + # describe "my class Bench" do + # bench_performance_power "algorithm" do |n| + # @obj.algorithm(n) + # end + # end + + def self.bench_performance_power name, threshold = 0.99, &work + bench name do + assert_performance_power threshold, &work + end + end + end + + Minitest::Spec.register_spec_type(/Bench(mark)?$/, Minitest::BenchSpec) +end diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/compress.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/compress.rb new file mode 100644 index 00000000..7ba0c536 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/compress.rb @@ -0,0 +1,94 @@ +module Minitest + ## + # Compresses backtraces. + + module Compress + + ## + # Takes a backtrace (array of strings) and compresses repeating + # cycles in it to make it more readable. + + def compress orig + ary = orig + + eswo = ->(a, n, off) { # each_slice_with_offset + if off.zero? then + a.each_slice n + else + # [ ...off... [...n...] [...n...] ... ] + front, back = a.take(off), a.drop(off) + [front].chain back.each_slice n + end + } + + 3.times do # maybe don't use loop do here? + index = ary # [ a b c b c b c d ] + .size + .times # 0...size + .group_by { |i| ary[i] } # { a: [0] b: [1 3 5], c: [2 4 6], d: [7] } + + order = index + .reject { |k, v| v.size == 1 } # { b: [1 3 5], c: [2 4 6] } + .sort_by { |k, a1| ### sort by max dist + min offset + d = a1.each_cons(2).sum { |a2, b| b-a2 } + [-d, a1.first] + } # b: [1 3 5] c: [2 4 6] + + ranges = order + .map { |k, a1| # [[1..2 3..4] [2..3 4..5]] + a1 + .each_cons(2) + .map { |a2, b| a2..b-1 } + } + + big_ranges = ranges + .flat_map { |a| # [1..2 3..4 2..3 4..5] + a.sort_by { |r| [-r.size, r.first] }.first 5 + } + .first(100) + + culprits = big_ranges + .map { |r| + eswo[ary, r.size, r.begin] # [o1 s1 s1 s2 s2] + .chunk_while { |a, b| a == b } # [[o1] [s1 s1] [s2 s2]] + .map { |a| [a.size, a.first] } # [[1 o1] [2 s1] [2 s2]] + } + .select { |chunks| + chunks.any? { |a| a.first > 1 } # compressed anything? + } + + min = culprits + .min_by { |a| a.flatten.size } # most compressed + + break unless min + + ary = min.flat_map { |(n, lines)| + if n > 1 then + [[n, compress(lines)]] # [o1 [2 s1] [2 s2]] + else + lines + end + } + end + + format = ->(lines) { + lines.flat_map { |line| + case line + when Array then + n, lines = line + lines = format[lines] + [ + " +->> #{n} cycles of #{lines.size} lines:", + *lines.map { |s| " | #{s}" }, + " +-<<", + ] + else + line + end + } + } + + format[ary] + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/error_on_warning.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/error_on_warning.rb new file mode 100644 index 00000000..d9dc16c8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/error_on_warning.rb @@ -0,0 +1,11 @@ +module Minitest + + module ErrorOnWarning # :nodoc: + def warn message, category: nil + message = "[#{category}] #{message}" if category + raise UnexpectedWarning, message + end + end + + ::Warning.singleton_class.prepend ErrorOnWarning +end diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/expectations.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/expectations.rb new file mode 100644 index 00000000..ef144d46 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/expectations.rb @@ -0,0 +1,321 @@ +## +# It's where you hide your "assertions". +# +# Please note, because of the way that expectations are implemented, +# all expectations (eg must_equal) are dependent upon a thread local +# variable +:current_spec+. If your specs rely on mixing threads into +# the specs themselves, you're better off using assertions or the new +# _(value) wrapper. For example: +# +# it "should still work in threads" do +# my_threaded_thingy do +# (1+1).must_equal 2 # bad +# assert_equal 2, 1+1 # good +# _(1 + 1).must_equal 2 # good +# value(1 + 1).must_equal 2 # good, also #expect +# _ { 1 + "1" }.must_raise TypeError # good +# end +# end + +module Minitest::Expectations + + ## + # See Minitest::Assertions#assert_empty. + # + # _(collection).must_be_empty + # + # :method: must_be_empty + + infect_an_assertion :assert_empty, :must_be_empty, :unary + + ## + # See Minitest::Assertions#assert_equal + # + # _(a).must_equal b + # + # :method: must_equal + + infect_an_assertion :assert_equal, :must_equal + + ## + # See Minitest::Assertions#assert_in_delta + # + # _(n).must_be_close_to m [, delta] + # + # :method: must_be_close_to + + infect_an_assertion :assert_in_delta, :must_be_close_to + + infect_an_assertion :assert_in_delta, :must_be_within_delta # :nodoc: + + ## + # See Minitest::Assertions#assert_in_epsilon + # + # _(n).must_be_within_epsilon m [, epsilon] + # + # :method: must_be_within_epsilon + + infect_an_assertion :assert_in_epsilon, :must_be_within_epsilon + + ## + # See Minitest::Assertions#assert_includes + # + # _(collection).must_include obj + # + # :method: must_include + + infect_an_assertion :assert_includes, :must_include, :reverse + + ## + # See Minitest::Assertions#assert_instance_of + # + # _(obj).must_be_instance_of klass + # + # :method: must_be_instance_of + + infect_an_assertion :assert_instance_of, :must_be_instance_of + + ## + # See Minitest::Assertions#assert_kind_of + # + # _(obj).must_be_kind_of mod + # + # :method: must_be_kind_of + + infect_an_assertion :assert_kind_of, :must_be_kind_of + + ## + # See Minitest::Assertions#assert_match + # + # _(a).must_match b + # + # :method: must_match + + infect_an_assertion :assert_match, :must_match + + ## + # See Minitest::Assertions#assert_nil + # + # _(obj).must_be_nil + # + # :method: must_be_nil + + infect_an_assertion :assert_nil, :must_be_nil, :unary + + ## + # See Minitest::Assertions#assert_operator + # + # _(n).must_be :<=, 42 + # + # This can also do predicates: + # + # _(str).must_be :empty? + # + # :method: must_be + + infect_an_assertion :assert_operator, :must_be, :reverse + + ## + # See Minitest::Assertions#assert_output + # + # _ { ... }.must_output out_or_nil [, err] + # + # :method: must_output + + infect_an_assertion :assert_output, :must_output, :block + + ## + # See Minitest::Assertions#assert_pattern + # + # _ { ... }.must_pattern_match [...] + # + # :method: must_pattern_match + + infect_an_assertion :assert_pattern, :must_pattern_match, :block + + ## + # See Minitest::Assertions#assert_raises + # + # _ { ... }.must_raise exception + # + # :method: must_raise + + infect_an_assertion :assert_raises, :must_raise, :block + + ## + # See Minitest::Assertions#assert_respond_to + # + # _(obj).must_respond_to msg + # + # :method: must_respond_to + + infect_an_assertion :assert_respond_to, :must_respond_to, :reverse + + ## + # See Minitest::Assertions#assert_same + # + # _(a).must_be_same_as b + # + # :method: must_be_same_as + + infect_an_assertion :assert_same, :must_be_same_as + + ## + # See Minitest::Assertions#assert_silent + # + # _ { ... }.must_be_silent + # + # :method: must_be_silent + + infect_an_assertion :assert_silent, :must_be_silent, :block + + ## + # See Minitest::Assertions#assert_throws + # + # _ { ... }.must_throw sym + # + # :method: must_throw + + infect_an_assertion :assert_throws, :must_throw, :block + + ## + # See Minitest::Assertions#assert_path_exists + # + # _(some_path).path_must_exist + # + # :method: path_must_exist + + infect_an_assertion :assert_path_exists, :path_must_exist, :unary + + ## + # See Minitest::Assertions#refute_path_exists + # + # _(some_path).path_wont_exist + # + # :method: path_wont_exist + + infect_an_assertion :refute_path_exists, :path_wont_exist, :unary + + ## + # See Minitest::Assertions#refute_empty + # + # _(collection).wont_be_empty + # + # :method: wont_be_empty + + infect_an_assertion :refute_empty, :wont_be_empty, :unary + + ## + # See Minitest::Assertions#refute_equal + # + # _(a).wont_equal b + # + # :method: wont_equal + + infect_an_assertion :refute_equal, :wont_equal + + ## + # See Minitest::Assertions#refute_in_delta + # + # _(n).wont_be_close_to m [, delta] + # + # :method: wont_be_close_to + + infect_an_assertion :refute_in_delta, :wont_be_close_to + + infect_an_assertion :refute_in_delta, :wont_be_within_delta # :nodoc: + + ## + # See Minitest::Assertions#refute_in_epsilon + # + # _(n).wont_be_within_epsilon m [, epsilon] + # + # :method: wont_be_within_epsilon + + infect_an_assertion :refute_in_epsilon, :wont_be_within_epsilon + + ## + # See Minitest::Assertions#refute_includes + # + # _(collection).wont_include obj + # + # :method: wont_include + + infect_an_assertion :refute_includes, :wont_include, :reverse + + ## + # See Minitest::Assertions#refute_instance_of + # + # _(obj).wont_be_instance_of klass + # + # :method: wont_be_instance_of + + infect_an_assertion :refute_instance_of, :wont_be_instance_of + + ## + # See Minitest::Assertions#refute_kind_of + # + # _(obj).wont_be_kind_of mod + # + # :method: wont_be_kind_of + + infect_an_assertion :refute_kind_of, :wont_be_kind_of + + ## + # See Minitest::Assertions#refute_match + # + # _(a).wont_match b + # + # :method: wont_match + + infect_an_assertion :refute_match, :wont_match + + ## + # See Minitest::Assertions#refute_nil + # + # _(obj).wont_be_nil + # + # :method: wont_be_nil + + infect_an_assertion :refute_nil, :wont_be_nil, :unary + + ## + # See Minitest::Assertions#refute_operator + # + # _(n).wont_be :<=, 42 + # + # This can also do predicates: + # + # str.wont_be :empty? + # + # :method: wont_be + + infect_an_assertion :refute_operator, :wont_be, :reverse + + ## + # See Minitest::Assertions#refute_pattern + # + # _ { ... }.wont_pattern_match [...] + # + # :method: wont_pattern_match + + infect_an_assertion :refute_pattern, :wont_pattern_match, :block + + ## + # See Minitest::Assertions#refute_respond_to + # + # _(obj).wont_respond_to msg + # + # :method: wont_respond_to + + infect_an_assertion :refute_respond_to, :wont_respond_to, :reverse + + ## + # See Minitest::Assertions#refute_same + # + # _(a).wont_be_same_as b + # + # :method: wont_be_same_as + + infect_an_assertion :refute_same, :wont_be_same_as +end diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/hell.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/hell.rb new file mode 100644 index 00000000..73c88acd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/hell.rb @@ -0,0 +1,11 @@ +require "minitest/parallel" + +class Minitest::Test + parallelize_me! +end + +begin + require "minitest/proveit" +rescue LoadError + warn "NOTE: `gem install minitest-proveit` for even more hellish tests" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/manual_plugins.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/manual_plugins.rb new file mode 100644 index 00000000..1f3d6529 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/manual_plugins.rb @@ -0,0 +1,16 @@ +require "minitest" + +ARGV << "--no-plugins" + +module Minitest + ## + # Manually load plugins by name. + + def self.load *names + names.each do |name| + require "minitest/#{name}_plugin" + + self.extensions << name.to_s + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/mock.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/mock.rb new file mode 100644 index 00000000..6b6e2454 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/mock.rb @@ -0,0 +1,347 @@ +class MockExpectationError < StandardError; end # :nodoc: + +module Minitest # :nodoc: + + ## + # A simple and clean mock object framework. + # + # All mock objects are an instance of Mock + + class Mock + alias __respond_to? respond_to? + + overridden_methods = %i[ + === + class + inspect + instance_eval + instance_variables + object_id + public_send + respond_to_missing? + send + to_s + ] + + overridden_methods << :singleton_method_added if defined?(::DEBUGGER__) + + instance_methods.each do |m| + undef_method m unless overridden_methods.include?(m) || m =~ /^__/ + end + + overridden_methods.map(&:to_sym).each do |method_id| + old_w, $-w = $-w, nil + define_method method_id do |*args, **kwargs, &b| + if @expected_calls.key? method_id then + if kwargs.empty? then # FIX: drop this after 2.7 dead + method_missing(method_id, *args, &b) + else + method_missing(method_id, *args, **kwargs, &b) + end + else + if kwargs.empty? then # FIX: drop this after 2.7 dead + super(*args, &b) + else + super(*args, **kwargs, &b) + end + end + end + ensure + $-w = old_w + end + + def initialize delegator = nil # :nodoc: + @delegator = delegator + @expected_calls = Hash.new { |calls, name| calls[name] = [] } + @actual_calls = Hash.new { |calls, name| calls[name] = [] } + end + + @@KW_WARNED = false # :nodoc: + + ## + # Expect that method +name+ is called, optionally with +args+ (and + # +kwargs+ or a +blk+), and returns +retval+. + # + # @mock.expect(:meaning_of_life, 42) + # @mock.meaning_of_life # => 42 + # + # @mock.expect(:do_something_with, true, [some_obj, true]) + # @mock.do_something_with(some_obj, true) # => true + # + # @mock.expect(:do_something_else, true) do |a1, a2| + # a1 == "buggs" && a2 == :bunny + # end + # + # +args+ is compared to the expected args using case equality (ie, the + # '===' operator), allowing for less specific expectations. + # + # @mock.expect(:uses_any_string, true, [String]) + # @mock.uses_any_string("foo") # => true + # @mock.verify # => true + # + # @mock.expect(:uses_one_string, true, ["foo"]) + # @mock.uses_one_string("bar") # => raises MockExpectationError + # + # If a method will be called multiple times, specify a new expect for each one. + # They will be used in the order you define them. + # + # @mock.expect(:ordinal_increment, 'first') + # @mock.expect(:ordinal_increment, 'second') + # + # @mock.ordinal_increment # => 'first' + # @mock.ordinal_increment # => 'second' + # @mock.ordinal_increment # => raises MockExpectationError "No more expects available for :ordinal_increment" + # + + def expect name, retval, args = [], **kwargs, &blk + name = name.to_sym + + if blk then + raise ArgumentError, "args ignored when block given" unless args.empty? + raise ArgumentError, "kwargs ignored when block given" unless kwargs.empty? + @expected_calls[name] << { :retval => retval, :block => blk } + else + raise ArgumentError, "args must be an array" unless Array === args + + if ENV["MT_KWARGS_HAC\K"] && (Hash === args.last || + Hash == args.last) then + if kwargs.empty? then + kwargs = args.pop + else + unless @@KW_WARNED then + from = caller(1..1).first + warn "Using MT_KWARGS_HAC\K yet passing kwargs. From #{from}" + @@KW_WARNED = true + end + end + end + + @expected_calls[name] << + { :retval => retval, :args => args, :kwargs => kwargs } + end + self + end + + def __call name, data # :nodoc: + case data + when Hash then + args = data[:args].inspect[1..-2] + kwargs = data[:kwargs] + if kwargs && !kwargs.empty? then + args << ", " unless args.empty? + args << kwargs.inspect[1..-2] + end + "#{name}(#{args}) => #{data[:retval].inspect}" + else + data.map { |d| __call name, d }.join ", " + end + end + + ## + # Verify that all methods were called as expected. Raises + # +MockExpectationError+ if the mock object was not called as + # expected. + + def verify + @expected_calls.each do |name, expected| + actual = @actual_calls.fetch name, nil # defaults to [] + raise MockExpectationError, "Expected #{__call name, expected[0]}" unless actual + raise MockExpectationError, "Expected #{__call name, expected[actual.size]}, got [#{__call name, actual}]" if + actual.size < expected.size + end + true + end + + def method_missing sym, *args, **kwargs, &block # :nodoc: + unless @expected_calls.key? sym then + if @delegator && @delegator.respond_to?(sym) + if kwargs.empty? then # FIX: drop this after 2.7 dead + return @delegator.public_send(sym, *args, &block) + else + return @delegator.public_send(sym, *args, **kwargs, &block) + end + else + raise NoMethodError, "unmocked method %p, expected one of %p" % + [sym, @expected_calls.keys.sort_by(&:to_s)] + end + end + + index = @actual_calls[sym].length + expected_call = @expected_calls[sym][index] + + unless expected_call then + raise MockExpectationError, "No more expects available for %p: %p %p" % + [sym, args, kwargs] + end + + expected_args, expected_kwargs, retval, val_block = + expected_call.values_at :args, :kwargs, :retval, :block + + expected_kwargs = kwargs.to_h { |ak, av| [ak, Object] } if + Hash == expected_kwargs + + if val_block then + # keep "verify" happy + @actual_calls[sym] << expected_call + + raise MockExpectationError, "mocked method %p failed block w/ %p %p" % + [sym, args, kwargs] unless val_block.call(*args, **kwargs, &block) + + return retval + end + + if expected_args.size != args.size then + raise ArgumentError, "mocked method %p expects %d arguments, got %p" % + [sym, expected_args.size, args] + end + + if expected_kwargs.size != kwargs.size then + raise ArgumentError, "mocked method %p expects %d keyword arguments, got %p" % + [sym, expected_kwargs.size, kwargs] + end + + zipped_args = expected_args.zip args + fully_matched = zipped_args.all? { |mod, a| + mod === a or mod == a + } + + unless fully_matched then + fmt = "mocked method %p called with unexpected arguments %p" + raise MockExpectationError, fmt % [sym, args] + end + + unless expected_kwargs.keys.sort == kwargs.keys.sort then + fmt = "mocked method %p called with unexpected keywords %p vs %p" + raise MockExpectationError, fmt % [sym, expected_kwargs.keys, kwargs.keys] + end + + zipped_kwargs = expected_kwargs.to_h { |ek, ev| + av = kwargs[ek] + [ek, [ev, av]] + } + + fully_matched = zipped_kwargs.all? { |ek, (ev, av)| + ev === av or ev == av + } + + unless fully_matched then + fmt = "mocked method %p called with unexpected keyword arguments %p vs %p" + raise MockExpectationError, fmt % [sym, expected_kwargs, kwargs] + end + + @actual_calls[sym] << { + :retval => retval, + :args => zipped_args.map { |e, a| e === a ? e : a }, + :kwargs => zipped_kwargs.to_h { |k, (e, a)| [k, e === a ? e : a] }, + } + + retval + end + + def respond_to? sym, include_private = false # :nodoc: + return true if @expected_calls.key? sym.to_sym + return true if @delegator && @delegator.respond_to?(sym, include_private) + __respond_to? sym, include_private + end + end +end + +module Minitest::Assertions + ## + # Assert that the mock verifies correctly and fail if not. + + def assert_mock mock, msg = nil + assert mock.verify + rescue MockExpectationError => e + msg = message(msg) { e.message } + flunk msg + end +end + +module Minitest::Expectations + ## + # See Minitest::Assertions#assert_mock. + # + # _(collection).must_verify + # + # :method: must_verify + + infect_an_assertion :assert_mock, :must_verify, :unary if + defined?(infect_an_assertion) +end + +## +# Object extensions for Minitest::Mock. + +class Object + + ## + # Add a temporary stubbed method replacing +name+ for the duration + # of the +block+. If +val_or_callable+ responds to #call, then it + # returns the result of calling it, otherwise returns the value + # as-is. If stubbed method yields a block, +block_args+ will be + # passed along. Cleans up the stub at the end of the +block+. The + # method +name+ must exist before stubbing. + # + # def test_stale_eh + # obj_under_test = Something.new + # refute obj_under_test.stale? + # + # Time.stub :now, Time.at(0) do + # assert obj_under_test.stale? + # end + # end + #-- + # NOTE: keyword args in callables are NOT checked for correctness + # against the existing method. Too many edge cases to be worth it. + + def stub name, val_or_callable, *block_args, **block_kwargs, &block + new_name = "__minitest_stub__#{name}" + + metaclass = class << self; self; end + + if respond_to? name and not methods.map(&:to_s).include? name.to_s then + metaclass.send :define_method, name do |*args, **kwargs| + super(*args, **kwargs) + end + end + + metaclass.send :alias_method, new_name, name + + if ENV["MT_KWARGS_HAC\K"] then + metaclass.send :define_method, name do |*args, &blk| + if val_or_callable.respond_to? :call then + val_or_callable.call(*args, &blk) + else + blk.call(*block_args, **block_kwargs) if blk + val_or_callable + end + end + else + metaclass.send :define_method, name do |*args, **kwargs, &blk| + if val_or_callable.respond_to? :call then + if kwargs.empty? then # FIX: drop this after 2.7 dead + val_or_callable.call(*args, &blk) + else + val_or_callable.call(*args, **kwargs, &blk) + end + else + if blk then + if block_kwargs.empty? then # FIX: drop this after 2.7 dead + blk.call(*block_args) + else + blk.call(*block_args, **block_kwargs) + end + end + val_or_callable + end + end + end + + block[self] + ensure + metaclass.send :undef_method, name + metaclass.send :alias_method, name, new_name + metaclass.send :undef_method, new_name + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/parallel.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/parallel.rb new file mode 100644 index 00000000..6b517883 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/parallel.rb @@ -0,0 +1,70 @@ +module Minitest + module Parallel # :nodoc: + + ## + # The engine used to run multiple tests in parallel. + + class Executor + + ## + # The size of the pool of workers. + + attr_reader :size + + ## + # Create a parallel test executor of with +size+ workers. + + def initialize size + @size = size + @queue = Thread::Queue.new + @pool = nil + end + + ## + # Start the executor + + def start + @pool = Array.new(size) { + Thread.new @queue do |queue| + Thread.current.abort_on_exception = true + while job = queue.pop do + klass, method, reporter = job + reporter.synchronize { reporter.prerecord klass, method } + result = Minitest.run_one_method klass, method + reporter.synchronize { reporter.record result } + end + end + } + end + + ## + # Add a job to the queue + + def << work; @queue << work; end + + ## + # Shuts down the pool of workers by signalling them to quit and + # waiting for them all to finish what they're currently working + # on. + + def shutdown + size.times { @queue << nil } + @pool.each(&:join) + end + end + + module Test # :nodoc: + def _synchronize; Minitest::Test.io_lock.synchronize { yield }; end # :nodoc: + + module ClassMethods # :nodoc: + def run_one_method klass, method_name, reporter + Minitest.parallel_executor << [klass, method_name, reporter] + end + + def test_order + :parallel + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/pride.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/pride.rb new file mode 100644 index 00000000..f3b8e474 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/pride.rb @@ -0,0 +1,4 @@ +require "minitest" + +Minitest.load_plugins +Minitest::PrideIO.pride! diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/pride_plugin.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/pride_plugin.rb new file mode 100644 index 00000000..04b9d88c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/pride_plugin.rb @@ -0,0 +1,135 @@ +require "minitest" + +module Minitest + def self.plugin_pride_options opts, _options # :nodoc: + opts.on "-p", "--pride", "Pride. Show your testing pride!" do + PrideIO.pride! + end + end + + def self.plugin_pride_init options # :nodoc: + return unless PrideIO.pride? + + klass = ENV["TERM"] =~ /^xterm|-(?:256color|direct)$/ ? PrideLOL : PrideIO + io = klass.new options[:io] + + self.reporter.reporters.grep(Minitest::Reporter).each do |rep| + rep.io = io if rep.io.tty? + end + end + + ## + # Show your testing pride! + + class PrideIO + ## + # Activate the pride plugin. Called from both -p option and minitest/pride + + def self.pride! + @pride = true + end + + ## + # Are we showing our testing pride? + + def self.pride? + @pride ||= false + end + + # Start an escape sequence + ESC = "\e[" + + # End the escape sequence + NND = "#{ESC}0m" + + # The IO we're going to pipe through. + attr_reader :io + + def initialize io # :nodoc: + @io = io + # stolen from /System/Library/Perl/5.10.0/Term/ANSIColor.pm + # also reference https://en.wikipedia.org/wiki/ANSI_escape_code + @colors ||= (31..36).to_a + @size = @colors.size + @index = 0 + end + + ## + # Wrap print to colorize the output. + + def print o + case o + when ".", "S" then + io.print pride o + when "E", "F" then + io.print "#{ESC}41m#{ESC}37m#{o}#{NND}" + else + io.print o + end + end + + def puts *o # :nodoc: + o.map! { |s| + s.to_s.sub("Finished") { + @index = 0 + "Fabulous run".chars.map { |c| pride(c) }.join + } + } + + io.puts(*o) + end + + ## + # Color a string. + + def pride string + string = "*" if string == "." + c = @colors[@index % @size] + @index += 1 + "#{ESC}#{c}m#{string}#{NND}" + end + + def method_missing msg, *args # :nodoc: + io.send(msg, *args) + end + end + + ## + # If you thought the PrideIO was colorful... + # + # (Inspired by lolcat, but with clean math) + + class PrideLOL < PrideIO + PI_3 = Math::PI / 3 # :nodoc: + + def initialize io # :nodoc: + # walk red, green, and blue around a circle separated by equal thirds. + # + # To visualize, type this into wolfram-alpha: + # + # plot (3*sin(x)+3), (3*sin(x+2*pi/3)+3), (3*sin(x+4*pi/3)+3) + + @colors = Array.new(6 * 7) { |n| + n *= 1.0 / 3 + r = (3 * Math.sin(n ) + 3).to_i + g = (3 * Math.sin(n + 4 * PI_3) + 3).to_i + b = (3 * Math.sin(n + 2 * PI_3) + 3).to_i + + # Then we take rgb and encode them in a single number using + # base 6, shifted by 16 for the base 16 ansi colors. + 36 * r + 6 * g + b + 16 + }.rotate(4) # puts "red" first + + super + end + + ## + # Make the string even more colorful. Damnit. + + def pride string + c = @colors[@index % @size] + @index += 1 + "#{ESC}38;5;#{c}m#{string}#{NND}" + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/spec.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/spec.rb new file mode 100644 index 00000000..9ec1597d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/spec.rb @@ -0,0 +1,350 @@ +require "minitest/test" + +class Module # :nodoc: + def infect_an_assertion meth, new_name, dont_flip = false # :nodoc: + block = dont_flip == :block + dont_flip = false if block + target_obj = block ? "_{obj.method}" : "_(obj)" + + # https://eregon.me/blog/2021/02/13/correct-delegation-in-ruby-2-27-3.html + # Drop this when we can drop ruby 2.6 (aka after rails 6.1 EOL, ~2024-06) + kw_extra = "ruby2_keywords %p" % [new_name] if respond_to? :ruby2_keywords, true + + # warn "%-22p -> %p %p" % [meth, new_name, dont_flip] + self.class_eval <<-EOM, __FILE__, __LINE__ + 1 + def #{new_name} *args + where = Minitest.filter_backtrace(caller).first + where = where.split(/:in /, 2).first # clean up noise + Kernel.warn "DEPRECATED: global use of #{new_name} from #\{where}. Use #{target_obj}.#{new_name} instead. This will fail in Minitest 6." + Minitest::Expectation.new(self, Minitest::Spec.current).#{new_name}(*args) + end + #{kw_extra} + EOM + + Minitest::Expectation.class_eval <<-EOM, __FILE__, __LINE__ + 1 + def #{new_name} *args + raise "Calling ##{new_name} outside of test." unless ctx + case + when #{!!dont_flip} then + ctx.#{meth}(target, *args) + when #{block} && Proc === target then + ctx.#{meth}(*args, &target) + else + ctx.#{meth}(args.first, target, *args[1..-1]) + end + end + #{kw_extra} + EOM + end +end + +Minitest::Expectation = Struct.new :target, :ctx # :nodoc: + +## +# Kernel extensions for minitest + +module Kernel + ## + # Describe a series of expectations for a given target +desc+. + # + # Defines a test class subclassing from either Minitest::Spec or + # from the surrounding describe's class. The surrounding class may + # subclass Minitest::Spec manually in order to easily share code: + # + # class MySpec < Minitest::Spec + # # ... shared code ... + # end + # + # class TestStuff < MySpec + # it "does stuff" do + # # shared code available here + # end + # describe "inner stuff" do + # it "still does stuff" do + # # ...and here + # end + # end + # end + # + # For more information on getting started with writing specs, see: + # + # http://www.rubyinside.com/a-minitestspec-tutorial-elegant-spec-style-testing-that-comes-with-ruby-5354.html + # + # For some suggestions on how to improve your specs, try: + # + # https://betterspecs.org + # + # but do note that several items there are debatable or specific to + # rspec. + # + # For more information about expectations, see Minitest::Expectations. + + def describe desc, *additional_desc, &block # :doc: + stack = Minitest::Spec.describe_stack + is_spec_class = Class === self && kind_of?(Minitest::Spec::DSL) + name = [stack.last, desc, *additional_desc] + name.prepend self if stack.empty? && is_spec_class + sclas = + stack.last \ + || (is_spec_class && self) \ + || Minitest::Spec.spec_type(desc, *additional_desc) + + cls = sclas.create name.compact.join("::"), desc + + stack.push cls + cls.class_eval(&block) + stack.pop + cls + end + private :describe +end + +## +# Minitest::Spec -- The faster, better, less-magical spec framework! +# +# For a list of expectations, see Minitest::Expectations. + +class Minitest::Spec < Minitest::Test + + def self.current # :nodoc: + Thread.current[:current_spec] + end + + def initialize name # :nodoc: + super + Thread.current[:current_spec] = self + end + + ## + # Oh look! A Minitest::Spec::DSL module! Eat your heart out DHH. + + module DSL + ## + # Contains pairs of matchers and Spec classes to be used to + # calculate the superclass of a top-level describe. This allows for + # automatically customizable spec types. + # + # See: register_spec_type and spec_type + + TYPES = [[//, Minitest::Spec]] + + ## + # Register a new type of spec that matches the spec's description. + # This method can take either a Regexp and a spec class or a spec + # class and a block that takes the description and returns true if + # it matches. + # + # Eg: + # + # register_spec_type(/Controller$/, Minitest::Spec::Rails) + # + # or: + # + # register_spec_type(Minitest::Spec::RailsModel) do |desc| + # desc.superclass == ActiveRecord::Base + # end + + def register_spec_type *args, &block + if block then + matcher, klass = block, args.first + else + matcher, klass = *args + end + TYPES.unshift [matcher, klass] + end + + ## + # Figure out the spec class to use based on a spec's description. Eg: + # + # spec_type("BlahController") # => Minitest::Spec::Rails + + def spec_type desc, *additional + TYPES.find { |matcher, _klass| + if matcher.respond_to? :call then + matcher.call desc, *additional + else + matcher === desc.to_s + end + }.last + end + + def describe_stack # :nodoc: + Thread.current[:describe_stack] ||= [] + end + + def children # :nodoc: + @children ||= [] + end + + def nuke_test_methods! # :nodoc: + self.public_instance_methods.grep(/^test_/).each do |name| + self.send :undef_method, name + end + end + + ## + # Define a 'before' action. Inherits the way normal methods should. + # + # NOTE: +type+ is ignored and is only there to make porting easier. + # + # Equivalent to Minitest::Test#setup. + + def before _type = nil, &block + define_method :setup do + super() + self.instance_eval(&block) + end + end + + ## + # Define an 'after' action. Inherits the way normal methods should. + # + # NOTE: +type+ is ignored and is only there to make porting easier. + # + # Equivalent to Minitest::Test#teardown. + + def after _type = nil, &block + define_method :teardown do + self.instance_eval(&block) + super() + end + end + + ## + # Define an expectation with name +desc+. Name gets morphed to a + # proper test method name. For some freakish reason, people who + # write specs don't like class inheritance, so this goes way out of + # its way to make sure that expectations aren't inherited. + # + # This is also aliased to #specify and doesn't require a +desc+ arg. + # + # Hint: If you _do_ want inheritance, use minitest/test. You can mix + # and match between assertions and expectations as much as you want. + + def it desc = "anonymous", &block + block ||= proc { skip "(no tests defined)" } + + @specs ||= 0 + @specs += 1 + + name = "test_%04d_%s" % [ @specs, desc ] + + undef_klasses = self.children.reject { |c| c.public_method_defined? name } + + define_method name, &block + + undef_klasses.each do |undef_klass| + undef_klass.send :undef_method, name + end + + name + end + + ## + # Essentially, define an accessor for +name+ with +block+. + # + # Why use let instead of def? I honestly don't know. + + def let name, &block + name = name.to_s + pre, post = "let '#{name}' cannot ", ". Please use another name." + methods = Minitest::Spec.instance_methods.map(&:to_s) - %w[subject] + raise ArgumentError, "#{pre}begin with 'test'#{post}" if + name.start_with? "test" + raise ArgumentError, "#{pre}override a method in Minitest::Spec#{post}" if + methods.include? name + + define_method name do + @_memoized ||= {} + @_memoized.fetch(name) { |k| @_memoized[k] = instance_eval(&block) } + end + end + + ## + # Another lazy man's accessor generator. Made even more lazy by + # setting the name for you to +subject+. + + def subject &block + let :subject, &block + end + + def create name, desc # :nodoc: + cls = Class.new self do + @name = name + @desc = desc + + nuke_test_methods! + end + + children << cls + + cls + end + + def name # :nodoc: + defined?(@name) ? @name : super + end + + def to_s # :nodoc: + name # Can't alias due to 1.8.7, not sure why + end + + attr_reader :desc # :nodoc: + alias specify it + + ## + # Rdoc... why are you so dumb? + + module InstanceMethods + ## + # Takes a value or a block and returns a value monad that has + # all of Expectations methods available to it. + # + # _(1 + 1).must_equal 2 + # + # And for blocks: + # + # _ { 1 + "1" }.must_raise TypeError + # + # This method of expectation-based testing is preferable to + # straight-expectation methods (on Object) because it stores its + # test context, bypassing our hacky use of thread-local variables. + # + # NOTE: At some point, the methods on Object will be deprecated + # and then removed. + # + # It is also aliased to #value and #expect for your aesthetic + # pleasure: + # + # _(1 + 1).must_equal 2 + # value(1 + 1).must_equal 2 + # expect(1 + 1).must_equal 2 + + def _ value = nil, &block + Minitest::Expectation.new block || value, self + end + + alias value _ + alias expect _ + + def before_setup # :nodoc: + super + Thread.current[:current_spec] = self + end + end + + def self.extended obj # :nodoc: + obj.send :include, InstanceMethods + end + end + + extend DSL + + TYPES = DSL::TYPES # :nodoc: +end + +require "minitest/expectations" + +class Object # :nodoc: + include Minitest::Expectations unless ENV["MT_NO_EXPECTATIONS"] +end diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/test.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/test.rb new file mode 100644 index 00000000..5085dae5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/test.rb @@ -0,0 +1,237 @@ +require "minitest" unless defined? Minitest::Runnable + +module Minitest + ## + # Subclass Test to create your own tests. Typically you'll want a + # Test subclass per implementation class. + # + # See Minitest::Assertions + + class Test < Runnable + require "minitest/assertions" + include Minitest::Reportable + include Minitest::Assertions + + def class_name # :nodoc: + self.class.name # for Minitest::Reportable + end + + PASSTHROUGH_EXCEPTIONS = [NoMemoryError, SignalException, SystemExit] # :nodoc: + + SETUP_METHODS = %w[ before_setup setup after_setup ] # :nodoc: + + TEARDOWN_METHODS = %w[ before_teardown teardown after_teardown ] # :nodoc: + + # :stopdoc: + class << self; attr_accessor :io_lock; end + self.io_lock = Mutex.new + # :startdoc: + + ## + # Call this at the top of your tests when you absolutely + # positively need to have ordered tests. In doing so, you're + # admitting that you suck and your tests are weak. + + def self.i_suck_and_my_tests_are_order_dependent! + class << self + undef_method :test_order if method_defined? :test_order + define_method :test_order do :alpha end + end + end + + ## + # Make diffs for this Test use #pretty_inspect so that diff + # in assert_equal can have more details. NOTE: this is much slower + # than the regular inspect but much more usable for complex + # objects. + + def self.make_my_diffs_pretty! + require "pp" + + define_method :mu_pp, &:pretty_inspect + end + + ## + # Call this at the top of your tests (inside the +Minitest::Test+ + # subclass or +describe+ block) when you want to run your tests in + # parallel. In doing so, you're admitting that you rule and your + # tests are awesome. + + def self.parallelize_me! + include Minitest::Parallel::Test + extend Minitest::Parallel::Test::ClassMethods + end + + ## + # Returns all instance methods starting with "test_". Based on + # #test_order, the methods are either sorted, randomized + # (default), or run in parallel. + + def self.runnable_methods + methods = methods_matching(/^test_/) + + case self.test_order + when :random, :parallel then + srand Minitest.seed + methods.sort.shuffle + when :alpha, :sorted then + methods.sort + else + raise "Unknown test_order: #{self.test_order.inspect}" + end + end + + ## + # Runs a single test with setup/teardown hooks. + + def run + time_it do + capture_exceptions do + SETUP_METHODS.each do |hook| + self.send hook + end + + self.send self.name + end + + TEARDOWN_METHODS.each do |hook| + capture_exceptions do + self.send hook + end + end + end + + Result.from self # per contract + end + + ## + # Provides before/after hooks for setup and teardown. These are + # meant for library writers, NOT for regular test authors. See + # #before_setup for an example. + + module LifecycleHooks + + ## + # Runs before every test, before setup. This hook is meant for + # libraries to extend minitest. It is not meant to be used by + # test developers. + # + # As a simplistic example: + # + # module MyMinitestPlugin + # def before_setup + # super + # # ... stuff to do before setup is run + # end + # + # def after_setup + # # ... stuff to do after setup is run + # super + # end + # + # def before_teardown + # super + # # ... stuff to do before teardown is run + # end + # + # def after_teardown + # # ... stuff to do after teardown is run + # super + # end + # end + # + # class Minitest::Test + # include MyMinitestPlugin + # end + + def before_setup; end + + ## + # Runs before every test. Use this to set up before each test + # run. + + def setup; end + + ## + # Runs before every test, after setup. This hook is meant for + # libraries to extend minitest. It is not meant to be used by + # test developers. + # + # See #before_setup for an example. + + def after_setup; end + + ## + # Runs after every test, before teardown. This hook is meant for + # libraries to extend minitest. It is not meant to be used by + # test developers. + # + # See #before_setup for an example. + + def before_teardown; end + + ## + # Runs after every test. Use this to clean up after each test + # run. + + def teardown; end + + ## + # Runs after every test, after teardown. This hook is meant for + # libraries to extend minitest. It is not meant to be used by + # test developers. + # + # See #before_setup for an example. + + def after_teardown; end + end # LifecycleHooks + + def capture_exceptions # :nodoc: + yield + rescue *PASSTHROUGH_EXCEPTIONS + raise + rescue Assertion => e + self.failures << e + rescue Exception => e + self.failures << UnexpectedError.new(sanitize_exception e) + end + + def sanitize_exception e # :nodoc: + Marshal.dump e + e # good: use as-is + rescue + neuter_exception e + end + + def neuter_exception e # :nodoc: + bt = e.backtrace + msg = e.message.dup + + new_exception e.class, msg, bt # e.class can be a problem... + rescue + msg.prepend "Neutered Exception #{e.class}: " + + new_exception RuntimeError, msg, bt, true # but if this raises, we die + end + + def new_exception klass, msg, bt, kill = false # :nodoc: + ne = klass.new msg + ne.set_backtrace bt + + if kill then + ne.instance_variables.each do |v| + ne.remove_instance_variable v + end + end + + Marshal.dump ne # can raise TypeError + ne + end + + include LifecycleHooks + include Guard + extend Guard + end # Test +end + +require "minitest/unit" if ENV["MT_COMPAT"] # compatibility layer only diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/test_task.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/test_task.rb new file mode 100644 index 00000000..b98dac6e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/test_task.rb @@ -0,0 +1,307 @@ +require "shellwords" +require "rbconfig" + +begin + require "rake/tasklib" +rescue LoadError => e + warn e.message + return +end + +module Minitest # :nodoc: + + ## + # Minitest::TestTask is a rake helper that generates several rake + # tasks under the main test task's name-space. + # + # task :: the main test task + # task :cmd :: prints the command to use + # task :deps :: runs each test file by itself to find dependency errors + # task :slow :: runs the tests and reports the slowest 25 tests. + # + # Examples: + # + # Minitest::TestTask.create + # + # The most basic and default setup. + # + # Minitest::TestTask.create :my_tests + # + # The most basic/default setup, but with a custom name + # + # Minitest::TestTask.create :unit do |t| + # t.test_globs = ["test/unit/**/*_test.rb"] + # t.warning = false + # end + # + # Customize the name and only run unit tests. + # + # NOTE: To hook this task up to the default, make it a dependency: + # + # task default: :unit + + class TestTask < Rake::TaskLib + WINDOWS = RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ # :nodoc: + + ## + # Create several test-oriented tasks under +name+. Takes an + # optional block to customize variables. + + def self.create name = :test, &block + task = new name + task.instance_eval(&block) if block + task.process_env + task.define + task + end + + ## + # Extra arguments to pass to the tests. Defaults empty but gets + # populated by a number of enviroment variables: + # + # N (-n flag) :: a string or regexp of tests to run. + # X (-e flag) :: a string or regexp of tests to exclude. + # A (arg) :: quick way to inject an arbitrary argument (eg A=--help). + # + # See #process_env + + attr_accessor :extra_args + + ## + # The code to load the framework. Defaults to requiring + # minitest/autorun... + # + # Why do I have this as an option? + + attr_accessor :framework + + ## + # Extra library directories to include. Defaults to %w[lib test + # .]. Also uses $MT_LIB_EXTRAS allowing you to dynamically + # override/inject directories for custom runs. + + attr_accessor :libs + + ## + # The name of the task and base name for the other tasks generated. + + attr_accessor :name + + ## + # File globs to find test files. Defaults to something sensible to + # find test files under the test directory. + + attr_accessor :test_globs + + ## + # Turn on ruby warnings (-w flag). Defaults to true. + + attr_accessor :warning + + ## + # Optional: Additional ruby to run before the test framework is loaded. + + attr_accessor :test_prelude + + ## + # Print out commands as they run. Defaults to Rake's +trace+ (-t + # flag) option. + + attr_accessor :verbose + + ## + # Use TestTask.create instead. + + def initialize name = :test # :nodoc: + self.extra_args = [] + self.framework = %(require "minitest/autorun") + self.libs = %w[lib test .] + self.name = name + self.test_globs = ["test/**/test_*.rb", + "test/**/*_test.rb"] + self.test_prelude = nil + self.verbose = Rake.application.options.trace || Rake.verbose == true + self.warning = true + end + + ## + # Extract variables from the environment and convert them to + # command line arguments. See #extra_args. + # + # Environment Variables: + # + # MT_LIB_EXTRAS :: Extra libs to dynamically override/inject for custom runs. + # N :: Tests to run (string or /regexp/). + # X :: Tests to exclude (string or /regexp/). + # A :: Any extra arguments. Honors shell quoting. + # + # Deprecated: + # + # TESTOPTS :: For argument passing, use +A+. + # N :: For parallel testing, use +MT_CPU+. + # FILTER :: Same as +TESTOPTS+. + + def process_env + warn "TESTOPTS is deprecated in Minitest::TestTask. Use A instead" if + ENV["TESTOPTS"] + warn "FILTER is deprecated in Minitest::TestTask. Use A instead" if + ENV["FILTER"] + warn "N is deprecated in Minitest::TestTask. Use MT_CPU instead" if + ENV["N"] && ENV["N"].to_i > 0 + + lib_extras = (ENV["MT_LIB_EXTRAS"] || "").split File::PATH_SEPARATOR + self.libs[0, 0] = lib_extras + + extra_args << "-n" << ENV["N"] if ENV["N"] + extra_args << "-e" << ENV["X"] if ENV["X"] + extra_args.concat Shellwords.split(ENV["TESTOPTS"]) if ENV["TESTOPTS"] + extra_args.concat Shellwords.split(ENV["FILTER"]) if ENV["FILTER"] + extra_args.concat Shellwords.split(ENV["A"]) if ENV["A"] + + ENV.delete "N" if ENV["N"] + + # TODO? RUBY_DEBUG = ENV["RUBY_DEBUG"] + # TODO? ENV["RUBY_FLAGS"] + + extra_args.compact! + end + + def define # :nodoc: + desc "Run the test suite. Use N, X, A, and TESTOPTS to add flags/args." + task name do + ruby make_test_cmd, verbose: verbose + end + + desc "Print out the test command. Good for profiling and other tools." + task "#{name}:cmd" do + puts "ruby #{make_test_cmd}" + end + + desc "Show which test files fail when run in isolation." + task "#{name}:isolated" do + tests = Dir[*self.test_globs].uniq + + # 3 seems to be the magic number... (tho not by that much) + bad, good, n = {}, [], (ENV.delete("K") || 3).to_i + file = ENV.delete "F" + times = {} + + tt0 = Time.now + + n.threads_do tests.sort do |path| + t0 = Time.now + output = `#{Gem.ruby} #{make_test_cmd path} 2>&1` + t1 = Time.now - t0 + + times[path] = t1 + + if $?.success? + $stderr.print "." + good << path + else + $stderr.print "x" + bad[path] = output + end + end + + puts "done" + puts "Ran in %.2f seconds" % [ Time.now - tt0 ] + + if file then + require "json" + File.open file, "w" do |io| + io.puts JSON.pretty_generate times + end + end + + unless good.empty? + puts + puts "# Good tests:" + puts + good.sort.each do |path| + puts "%.2fs: %s" % [times[path], path] + end + end + + unless bad.empty? + puts + puts "# Bad tests:" + puts + bad.keys.sort.each do |path| + puts "%.2fs: %s" % [times[path], path] + end + puts + puts "# Bad Test Output:" + puts + bad.sort.each do |path, output| + puts + puts "# #{path}:" + puts output + end + exit 1 + end + end + + task "#{name}:deps" => "#{name}:isolated" # now just an alias + + desc "Run the test suite and report the slowest 25 tests." + task "#{name}:slow" do + sh ["rake #{name} A=-v", + "egrep '#test_.* s = .'", + "sort -n -k2 -t=", + "tail -25"].join " | " + end + end + + ## + # Generate the test command-line. + + def make_test_cmd globs = test_globs + tests = [] + tests.concat Dir[*globs].sort.shuffle # TODO: SEED -> srand first? + tests.map! { |f| %(require "#{f}") } + + runner = [] + runner << test_prelude if test_prelude + runner << framework + runner.concat tests + runner = runner.join "; " + + args = [] + args << "-I#{libs.join File::PATH_SEPARATOR}" unless libs.empty? + args << "-w" if warning + args << "-e" + args << "'#{runner}'" + args << "--" + args << extra_args.map(&:shellescape) + + args.join " " + end + end +end + +class Work < Queue # :nodoc: + def initialize jobs = [] # :nodoc: + super() + + jobs.each do |job| + self << job + end + + close + end +end + +class Integer # :nodoc: + def threads_do jobs # :nodoc: + q = Work.new jobs + + Array.new(self) { + Thread.new do + while job = q.pop # go until quit value + yield job + end + end + }.each(&:join) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/unit.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/unit.rb new file mode 100644 index 00000000..3c60a707 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/lib/minitest/unit.rb @@ -0,0 +1,42 @@ +unless defined?(Minitest) then + # all of this crap is just to avoid circular requires and is only + # needed if a user requires "minitest/unit" directly instead of + # "minitest/autorun", so we also warn + + from = caller.reject { |s| s =~ /rubygems/ }.join("\n ") + warn "Warning: you should require 'minitest/autorun' instead." + warn %(Warning: or add 'gem "minitest"' before 'require "minitest/autorun"') + warn "From:\n #{from}" + + module Minitest # :nodoc: + end + MiniTest = Minitest # :nodoc: # prevents minitest.rb from requiring back to us + require "minitest" +end + +MiniTest = Minitest unless defined?(MiniTest) + +module Minitest + class Unit # :nodoc: + VERSION = Minitest::VERSION + class TestCase < Minitest::Test # :nodoc: + def self.inherited klass # :nodoc: + from = caller.first + warn "MiniTest::Unit::TestCase is now Minitest::Test. From #{from}" + super + end + end + + def self.autorun # :nodoc: + from = caller.first + warn "MiniTest::Unit.autorun is now Minitest.autorun. From #{from}" + Minitest.autorun + end + + def self.after_tests &b # :nodoc: + from = caller.first + warn "MiniTest::Unit.after_tests is now Minitest.after_run. From #{from}" + Minitest.after_run(&b) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/test/minitest/metametameta.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/test/minitest/metametameta.rb new file mode 100644 index 00000000..fde506d4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/test/minitest/metametameta.rb @@ -0,0 +1,150 @@ +require "tempfile" +require "stringio" +require "minitest/autorun" + +class Minitest::Test + def with_empty_backtrace_filter + with_backtrace_filter Minitest::BacktraceFilter.new %r%.% do + yield + end + end + + def with_backtrace_filter filter + original = Minitest.backtrace_filter + + Minitest::Test.io_lock.synchronize do # try not to trounce in parallel + begin + Minitest.backtrace_filter = filter + yield + ensure + Minitest.backtrace_filter = original + end + end + end + + def error_on_warn? + defined?(Minitest::ErrorOnWarning) + end + + def assert_deprecation re = /DEPRECATED/ + re = // if $-w.nil? # "skip" if running `rake testW0` + assert_output "", re do + yield + end + rescue Minitest::UnexpectedWarning => e # raised if -Werror was used + assert_match re, e.message + end +end + +class FakeNamedTest < Minitest::Test + @@count = 0 + + def self.name + @fake_name ||= begin + @@count += 1 + "FakeNamedTest%02d" % @@count + end + end +end + +module MyModule; end +class AnError < StandardError; include MyModule; end + +class MetaMetaMetaTestCase < Minitest::Test + attr_accessor :reporter, :output, :tu + + def with_stderr err + old = $stderr + $stderr = err + yield + ensure + $stderr = old + end + + def run_tu_with_fresh_reporter flags = %w[--seed 42] + options = Minitest.process_args flags + + @output = StringIO.new(+"") + + self.reporter = Minitest::CompositeReporter.new + reporter << Minitest::SummaryReporter.new(@output, options) + reporter << Minitest::ProgressReporter.new(@output, options) + + with_stderr @output do + reporter.start + + yield reporter if block_given? + + @tus ||= [@tu] + @tus.each do |tu| + Minitest::Runnable.runnables.delete tu + + tu.run reporter, options + end + + reporter.report + end + end + + def first_reporter + reporter.reporters.first + end + + def assert_report expected, flags = %w[--seed 42], &block + header = <<~EOM + Run options: #{flags.map { |s| s.include?("|") ? s.inspect : s }.join " "} + + # Running: + + EOM + + run_tu_with_fresh_reporter flags, &block + + output = normalize_output @output.string.dup + + assert_equal header + expected, output + end + + def normalize_output output + output.sub!(/Finished in .*/, "Finished in 0.00") + output.sub!(/Loaded suite .*/, "Loaded suite blah") + + output.gsub!(/FakeNamedTest\d+/, "FakeNamedTestXX") + output.gsub!(/ = \d+.\d\d s = /, " = 0.00 s = ") + output.gsub!(/0x[A-Fa-f0-9]+/, "0xXXX") + output.gsub!(/ +$/, "") + + file = ->(s) { s.start_with?("/") ? "FULLFILE" : "FILE" } + + if windows? then + output.gsub!(/\[(?:[A-Za-z]:)?[^\]:]+:\d+\]/, "[FILE:LINE]") + output.gsub!(/^(\s+)(?:[A-Za-z]:)?[^:]+:\d+:in [`']/, '\1FILE:LINE:in \'') + else + output.gsub!(/\[([^\]:]+):\d+\]/) { "[#{file[$1]}:LINE]" } + output.gsub!(/^(\s+)([^:]+):\d+:in [`']/) { "#{$1}#{file[$2]}:LINE:in '" } + end + + output.gsub!(/in [`']block in (?:([^']+)[#.])?/, "in 'block in") + output.gsub!(/in [`'](?:([^']+)[#.])?/, "in '") + + output.gsub!(/( at )([^:]+):\d+/) { "#{$1}[#{file[$2]}:LINE]" } # eval? + + output + end + + def restore_env + old_value = ENV["MT_NO_SKIP_MSG"] + ENV.delete "MT_NO_SKIP_MSG" + + yield + ensure + ENV["MT_NO_SKIP_MSG"] = old_value + end + + def setup + super + Minitest.seed = 42 + Minitest::Test.reset + @tu = nil + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/test/minitest/test_minitest_assertions.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/test/minitest/test_minitest_assertions.rb new file mode 100644 index 00000000..77adbed6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/test/minitest/test_minitest_assertions.rb @@ -0,0 +1,1720 @@ +require "minitest/autorun" +require_relative "metametameta" + +e = Encoding.default_external +if e != Encoding::UTF_8 then + warn "" + warn "" + warn "NOTE: External encoding #{e} is not UTF-8. Tests WILL fail." + warn " Run tests with `RUBYOPT=-Eutf-8 rake` to avoid errors." + warn "" + warn "" +end + +SomeError = Class.new Exception + +unless defined? MyModule then + module MyModule; end + class AnError < StandardError; include MyModule; end +end + +class TestMinitestAssertions < Minitest::Test + # do not call parallelize_me! - teardown accesses @tc._assertions + # which is not threadsafe. Nearly every method in here is an + # assertion test so it isn't worth splitting it out further. + + # not included in JRuby + RE_LEVELS = /\(\d+ levels\) / + + class DummyTest + include Minitest::Assertions + + attr_accessor :assertions, :failure + + def initialize + self.assertions = 0 + self.failure = nil + end + end + + def setup + super + + Minitest::Test.reset + + @tc = DummyTest.new + @zomg = "zomg ponies!" # TODO: const + @assertion_count = 1 + end + + def teardown + assert_equal(@assertion_count, @tc.assertions, + "expected #{@assertion_count} assertions to be fired during the test, not #{@tc.assertions}") + end + + def assert_triggered expected, klass = Minitest::Assertion + e = assert_raises klass do + yield + end + + msg = e.message.sub(/(---Backtrace---).*/m, '\1') + msg.gsub!(/\(oid=[-0-9]+\)/, "(oid=N)") + msg.gsub!(/(\d\.\d{6})\d+/, '\1xxx') # normalize: ruby version, impl, platform + + assert_msg = Regexp === expected ? :assert_match : :assert_equal + self.send assert_msg, expected, msg + end + + def assert_unexpected expected + expected = Regexp.new expected if String === expected + + assert_triggered expected, Minitest::UnexpectedError do + yield + end + end + + def non_verbose + orig_verbose = $VERBOSE + $VERBOSE = false + + yield + ensure + $VERBOSE = orig_verbose + end + + def test_assert + @assertion_count = 2 + + @tc.assert_equal true, @tc.assert(true), "returns true on success" + end + + def test_assert__triggered + assert_triggered "Expected false to be truthy." do + @tc.assert false + end + end + + def test_assert__triggered_message + assert_triggered @zomg do + @tc.assert false, @zomg + end + end + + def test_assert__triggered_lambda + assert_triggered "whoops" do + @tc.assert false, lambda { "whoops" } + end + end + + def test_assert_empty + @assertion_count = 2 + + @tc.assert_empty [] + end + + def test_assert_empty_triggered + @assertion_count = 2 + + assert_triggered "Expected [1] to be empty." do + @tc.assert_empty [1] + end + end + + def test_assert_equal + @tc.assert_equal 1, 1 + end + + def test_assert_equal_different_collection_array_hex_invisible + exp = Object.new + act = Object.new + msg = <<~EOM.chomp + No visible difference in the Array#inspect output. + You should look at the implementation of #== on Array or its members. + [#] + EOM + assert_triggered msg do + @tc.assert_equal [exp], [act] + end + end + + def test_assert_equal_different_collection_hash_hex_invisible + exp, act = {}, {} + exp[1] = Object.new + act[1] = Object.new + act_obj = act[1] + # TODO: switch to endless when 2.7 is dropped + act_obj.define_singleton_method(:inspect) { "#" } + msg = <<~EOM.chomp % [act] + No visible difference in the Hash#inspect output. + You should look at the implementation of #== on Hash or its members. + %p + EOM + + assert_triggered msg do + @tc.assert_equal exp, act + end + end + + def test_assert_equal_different_diff_deactivated + without_diff do + assert_triggered util_msg("haha" * 10, "blah" * 10) do + exp = "haha" * 10 + act = "blah" * 10 + + @tc.assert_equal exp, act + end + end + end + + def test_assert_equal_different_message + assert_triggered "whoops.\nExpected: 1\n Actual: 2" do + @tc.assert_equal 1, 2, message { "whoops" } + end + end + + def test_assert_equal_different_lambda + assert_triggered "whoops.\nExpected: 1\n Actual: 2" do + @tc.assert_equal 1, 2, lambda { "whoops" } + end + end + + def test_assert_equal_different_hex + c = Class.new do + def initialize s; @name = s; end + end + + exp = c.new "a" + act = c.new "b" + msg = <<~EOS + --- expected + +++ actual + @@ -1 +1 @@ + -#<#:0xXXXXXX @name="a"> + +#<#:0xXXXXXX @name="b"> + EOS + + assert_triggered msg do + @tc.assert_equal exp, act + end + end + + def test_assert_equal_different_hex_invisible + exp = Object.new + act = Object.new + + msg = <<~EOM.chomp + No visible difference in the Object#inspect output. + You should look at the implementation of #== on Object or its members. + # + EOM + + assert_triggered msg do + @tc.assert_equal exp, act + end + end + + def test_assert_equal_different_long + msg = <<~EOM + --- expected + +++ actual + @@ -1 +1 @@ + -"hahahahahahahahahahahahahahahahahahahaha" + +"blahblahblahblahblahblahblahblahblahblah" + EOM + + assert_triggered msg do + exp = "haha" * 10 + act = "blah" * 10 + + @tc.assert_equal exp, act + end + end + + def test_assert_equal_different_long_invisible + msg = <<~EOM.chomp + No visible difference in the String#inspect output. + You should look at the implementation of #== on String or its members. + "blahblahblahblahblahblahblahblahblahblah" + EOM + + assert_triggered msg do + exp = "blah" * 10 + act = "blah" * 10 + def exp.== _ + false + end + @tc.assert_equal exp, act + end + end + + def test_assert_equal_different_long_msg + msg = <<~EOM + message. + --- expected + +++ actual + @@ -1 +1 @@ + -"hahahahahahahahahahahahahahahahahahahaha" + +"blahblahblahblahblahblahblahblahblahblah" + EOM + + assert_triggered msg do + exp = "haha" * 10 + act = "blah" * 10 + @tc.assert_equal exp, act, "message" + end + end + + def test_assert_equal_different_short + assert_triggered util_msg(1, 2) do + @tc.assert_equal 1, 2 + end + end + + def test_assert_equal_different_short_msg + assert_triggered util_msg(1, 2, "message") do + @tc.assert_equal 1, 2, "message" + end + end + + def test_assert_equal_different_short_multiline + msg = "--- expected\n+++ actual\n@@ -1,2 +1,2 @@\n \"a\n-b\"\n+c\"\n" + assert_triggered msg do + @tc.assert_equal "a\nb", "a\nc" + end + end + + def test_assert_equal_does_not_allow_lhs_nil + if Minitest::VERSION >= "6" then + warn "Time to strip the MT5 test" + + @assertion_count += 1 + assert_triggered(/Use assert_nil if expecting nil/) do + @tc.assert_equal nil, nil + end + else + err_re = /Use assert_nil if expecting nil from .*test_minitest_\w+.rb/ + err_re = "" if $-w.nil? + + assert_deprecation err_re do + @tc.assert_equal nil, nil + end + end + end + + def test_assert_equal_does_not_allow_lhs_nil_triggered + assert_triggered "Expected: nil\n Actual: false" do + @tc.assert_equal nil, false + end + end + + def test_assert_equal_string_bug791 + exp = <<~EOM.chomp + Expected: "\\\\n" + Actual: "\\\\" + EOM + assert_triggered exp do + @tc.assert_equal "\\n", "\\" + end + end + + def test_assert_equal_string_both_escaped_unescaped_newlines + msg = <<~EOM + --- expected + +++ actual + @@ -1,2 +1 @@ + -"A\\n + -B" + +"A\\n\\\\nB" + EOM + + assert_triggered msg do + exp = "A\\nB" + act = "A\n\\nB" + + @tc.assert_equal exp, act + end + end + + def test_assert_equal_string_encodings + msg = <<~EOM + --- expected + +++ actual + @@ -1,3 +1,3 @@ + -# encoding: UTF-8 + -# valid: false + +# encoding: #{Encoding::BINARY.name} + +# valid: true + "bad-utf8-\\xF1.txt" + EOM + + assert_triggered msg do + exp = "bad-utf8-\xF1.txt" + act = exp.dup.b + @tc.assert_equal exp, act + end + end + + def test_assert_equal_string_encodings_both_different + msg = <<~EOM + --- expected + +++ actual + @@ -1,3 +1,3 @@ + -# encoding: US-ASCII + -# valid: false + +# encoding: #{Encoding::BINARY.name} + +# valid: true + "bad-utf8-\\xF1.txt" + EOM + + assert_triggered msg do + exp = "bad-utf8-\xF1.txt".dup.force_encoding Encoding::ASCII + act = exp.dup.b + @tc.assert_equal exp, act + end + end + + def test_assert_equal_unescape_newlines + msg = <<~'EOM' # NOTE single quotes on heredoc + --- expected + +++ actual + @@ -1,2 +1,2 @@ + -"hello + +"hello\n + world" + EOM + + assert_triggered msg do + exp = "hello\nworld" + act = 'hello\nworld' # notice single quotes + + @tc.assert_equal exp, act + end + end + + def test_assert_in_delta + @tc.assert_in_delta 0.0, 1.0 / 1000, 0.1 + end + + def test_assert_in_delta_triggered + x = "1.0e-06" + assert_triggered "Expected |0.0 - 0.001| (0.001) to be <= #{x}." do + @tc.assert_in_delta 0.0, 1.0 / 1000, 0.000001 + end + end + + def test_assert_in_epsilon + @assertion_count = 10 + + @tc.assert_in_epsilon 10_000, 9991 + @tc.assert_in_epsilon 9991, 10_000 + @tc.assert_in_epsilon 1.0, 1.001 + @tc.assert_in_epsilon 1.001, 1.0 + + @tc.assert_in_epsilon 10_000, 9999.1, 0.0001 + @tc.assert_in_epsilon 9999.1, 10_000, 0.0001 + @tc.assert_in_epsilon 1.0, 1.0001, 0.0001 + @tc.assert_in_epsilon 1.0001, 1.0, 0.0001 + + @tc.assert_in_epsilon(-1, -1) + @tc.assert_in_epsilon(-10_000, -9991) + end + + def test_assert_in_epsilon_triggered + assert_triggered "Expected |10000 - 9990| (10) to be <= 9.99." do + @tc.assert_in_epsilon 10_000, 9990 + end + end + + def test_assert_in_epsilon_triggered_negative_case + x = "0.100000xxx" + y = "0.1" + assert_triggered "Expected |-1.1 - -1| (#{x}) to be <= #{y}." do + @tc.assert_in_epsilon(-1.1, -1, 0.1) + end + end + + def test_assert_includes + @assertion_count = 2 + + @tc.assert_includes [true], true + end + + def test_assert_includes_triggered + @assertion_count = 3 + + e = @tc.assert_raises Minitest::Assertion do + @tc.assert_includes [true], false + end + + expected = "Expected [true] to include false." + assert_equal expected, e.message + end + + def test_assert_instance_of + @tc.assert_instance_of String, "blah" + end + + def test_assert_instance_of_triggered + assert_triggered 'Expected "blah" to be an instance of Array, not String.' do + @tc.assert_instance_of Array, "blah" + end + end + + def test_assert_kind_of + @tc.assert_kind_of String, "blah" + end + + def test_assert_kind_of_triggered + assert_triggered 'Expected "blah" to be a kind of Array, not String.' do + @tc.assert_kind_of Array, "blah" + end + end + + def test_assert_match + @assertion_count = 2 + m = @tc.assert_match(/\w+/, "blah blah blah") + + assert_kind_of MatchData, m + assert_equal "blah", m[0] + end + + def test_assert_match_matchee_to_str + @assertion_count = 2 + + obj = Object.new + def obj.to_str; "blah" end + + @tc.assert_match "blah", obj + end + + def test_assert_match_matcher_object + @assertion_count = 2 + + pattern = Object.new + def pattern.=~ _; true end + + @tc.assert_match pattern, 5 + end + + def test_assert_match_object_triggered + @assertion_count = 2 + + pattern = Object.new + def pattern.=~ _; false end + def pattern.inspect; "[Object]" end + + assert_triggered "Expected [Object] to match 5." do + @tc.assert_match pattern, 5 + end + end + + def test_assert_match_triggered + @assertion_count = 2 + assert_triggered 'Expected /\d+/ to match "blah blah blah".' do + @tc.assert_match(/\d+/, "blah blah blah") + end + end + + def test_assert_nil + @tc.assert_nil nil + end + + def test_assert_nil_triggered + assert_triggered "Expected 42 to be nil." do + @tc.assert_nil 42 + end + end + + def test_assert_operator + @tc.assert_operator 2, :>, 1 + end + + def test_assert_operator_bad_object + bad = Object.new + def bad.== _; true end + + @tc.assert_operator bad, :equal?, bad + end + + def test_assert_operator_triggered + assert_triggered "Expected 2 to be < 1." do + @tc.assert_operator 2, :<, 1 + end + end + + def test_assert_output_both + @assertion_count = 2 + + @tc.assert_output "yay", "blah" do + print "yay" + $stderr.print "blah" + end + end + + def test_assert_output_both_regexps + @assertion_count = 4 + + @tc.assert_output(/y.y/, /bl.h/) do + print "yay" + $stderr.print "blah" + end + end + + def test_assert_output_err + @tc.assert_output nil, "blah" do + $stderr.print "blah" + end + end + + def test_assert_output_neither + @assertion_count = 0 + + @tc.assert_output do + # do nothing + end + end + + def test_assert_output_out + @tc.assert_output "blah" do + print "blah" + end + end + + def test_assert_output_triggered_both + assert_triggered util_msg("blah", "blah blah", "In stderr") do + @tc.assert_output "yay", "blah" do + print "boo" + $stderr.print "blah blah" + end + end + end + + def test_assert_output_triggered_err + assert_triggered util_msg("blah", "blah blah", "In stderr") do + @tc.assert_output nil, "blah" do + $stderr.print "blah blah" + end + end + end + + def test_assert_output_triggered_out + assert_triggered util_msg("blah", "blah blah", "In stdout") do + @tc.assert_output "blah" do + print "blah blah" + end + end + end + + def test_assert_output_no_block + assert_triggered "assert_output requires a block to capture output." do + @tc.assert_output "blah" + end + end + + def test_assert_output_nested_assert_uncaught + @assertion_count = 1 + + assert_triggered "Epic Fail!" do + @tc.assert_output "blah\n" do + puts "blah" + @tc.flunk + end + end + end + + def test_assert_output_nested_raise + @assertion_count = 2 + + @tc.assert_output "blah\n" do + @tc.assert_raises RuntimeError do + puts "blah" + raise "boom!" + end + end + end + + def test_assert_output_nested_raise_bad + @assertion_count = 0 + + assert_unexpected "boom!" do + @tc.assert_raises do # 2) bypassed via UnexpectedError + @tc.assert_output "blah\n" do # 1) captures and raises UnexpectedError + puts "not_blah" + raise "boom!" + end + end + end + end + + def test_assert_output_nested_raise_mismatch + # this test is redundant, but illustrative + @assertion_count = 0 + + assert_unexpected "boom!" do + @tc.assert_raises RuntimeError do # 2) bypassed via UnexpectedError + @tc.assert_output "blah\n" do # 1) captures and raises UnexpectedError + puts "not_blah" + raise ArgumentError, "boom!" + end + end + end + end + + def test_assert_output_nested_throw_caught + @assertion_count = 2 + + @tc.assert_output "blah\n" do + @tc.assert_throws :boom! do + puts "blah" + throw :boom! + end + end + end + + def test_assert_output_nested_throw_caught_bad + @assertion_count = 1 # want 0; can't prevent throw from escaping :( + + @tc.assert_throws :boom! do # 2) captured via catch + @tc.assert_output "blah\n" do # 1) bypassed via throw + puts "not_blah" + throw :boom! + end + end + end + + def test_assert_output_nested_throw_mismatch + @assertion_count = 0 + + assert_unexpected "uncaught throw :boom!" do + @tc.assert_throws :not_boom! do # 2) captured via assert_throws+rescue + @tc.assert_output "blah\n" do # 1) bypassed via throw + puts "not_blah" + throw :boom! + end + end + end + end + + def test_assert_output_uncaught_raise + @assertion_count = 0 + + assert_unexpected "RuntimeError: boom!" do + @tc.assert_output "blah\n" do + puts "not_blah" + raise "boom!" + end + end + end + + def test_assert_output_uncaught_throw + @assertion_count = 0 + + assert_unexpected "uncaught throw :boom!" do + @tc.assert_output "blah\n" do + puts "not_blah" + throw :boom! + end + end + end + + def test_assert_predicate + @tc.assert_predicate "", :empty? + end + + def test_assert_predicate_triggered + assert_triggered 'Expected "blah" to be empty?.' do + @tc.assert_predicate "blah", :empty? + end + end + + def test_assert_raises + @tc.assert_raises RuntimeError do + raise "blah" + end + end + + def test_assert_raises_default + @tc.assert_raises do + raise StandardError, "blah" + end + end + + def test_assert_raises_default_triggered + e = assert_raises Minitest::Assertion do + @tc.assert_raises do + raise SomeError, "blah" + end + end + + expected = <<~EOM.chomp + [StandardError] exception expected, not + Class: + Message: <"blah"> + ---Backtrace--- + FILE:LINE:in 'block in test_assert_raises_default_triggered' + --------------- + EOM + + actual = e.message.gsub(/^.+:\d+/, "FILE:LINE") + actual.gsub! RE_LEVELS, "" unless jruby? + actual.gsub!(/[`']block in (?:TestMinitestAssertions#)?/, "'block in ") + + assert_equal expected, actual + end + + def test_assert_raises_exit + @tc.assert_raises SystemExit do + exit 1 + end + end + + def test_assert_raises_module + @tc.assert_raises MyModule do + raise AnError + end + end + + def test_assert_raises_signals + @tc.assert_raises SignalException do + raise SignalException, :INT + end + end + + def test_assert_raises_throw_nested_bad + @assertion_count = 0 + + assert_unexpected "RuntimeError: boom!" do + @tc.assert_raises do + @tc.assert_throws :blah do + raise "boom!" + throw :not_blah + end + end + end + end + + ## + # *sigh* This is quite an odd scenario, but it is from real (albeit + # ugly) test code in ruby-core: + + # https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=29259 + + def test_assert_raises_skip + @assertion_count = 0 + + assert_triggered "skipped", Minitest::Skip do + @tc.assert_raises ArgumentError do + begin + raise "blah" + rescue + skip "skipped" + end + end + end + end + + def test_assert_raises_subclass + @tc.assert_raises StandardError do + raise AnError + end + end + + def test_assert_raises_subclass_triggered + e = assert_raises Minitest::Assertion do + @tc.assert_raises SomeError do + raise AnError, "some message" + end + end + + expected = <<~EOM + [SomeError] exception expected, not + Class: + Message: <"some message"> + ---Backtrace--- + FILE:LINE:in 'block in test_assert_raises_subclass_triggered' + --------------- + EOM + + actual = e.message.gsub(/^.+:\d+/, "FILE:LINE") + actual.gsub! RE_LEVELS, "" unless jruby? + actual.gsub!(/[`']block in (?:TestMinitestAssertions#)?/, "'block in ") + + assert_equal expected.chomp, actual + end + + def test_assert_raises_triggered_different + e = assert_raises Minitest::Assertion do + @tc.assert_raises RuntimeError do + raise SyntaxError, "icky" + end + end + + expected = <<~EOM.chomp + [RuntimeError] exception expected, not + Class: + Message: <"icky"> + ---Backtrace--- + FILE:LINE:in 'block in test_assert_raises_triggered_different' + --------------- + EOM + + actual = e.message.gsub(/^.+:\d+/, "FILE:LINE") + actual.gsub! RE_LEVELS, "" unless jruby? + actual.gsub!(/[`']block in (?:TestMinitestAssertions#)?/, "'block in ") + + assert_equal expected, actual + end + + def test_assert_raises_triggered_different_msg + e = assert_raises Minitest::Assertion do + @tc.assert_raises RuntimeError, "XXX" do + raise SyntaxError, "icky" + end + end + + expected = <<~EOM + XXX. + [RuntimeError] exception expected, not + Class: + Message: <"icky"> + ---Backtrace--- + FILE:LINE:in 'block in test_assert_raises_triggered_different_msg' + --------------- + EOM + + actual = e.message.gsub(/^.+:\d+/, "FILE:LINE") + actual.gsub! RE_LEVELS, "" unless jruby? + actual.gsub!(/[`']block in (?:TestMinitestAssertions#)?/, "'block in ") + + assert_equal expected.chomp, actual + end + + def test_assert_raises_triggered_none + e = assert_raises Minitest::Assertion do + @tc.assert_raises Minitest::Assertion do + # do nothing + end + end + + expected = "Minitest::Assertion expected but nothing was raised." + + assert_equal expected, e.message + end + + def test_assert_raises_triggered_none_msg + e = assert_raises Minitest::Assertion do + @tc.assert_raises Minitest::Assertion, "XXX" do + # do nothing + end + end + + expected = "XXX.\nMinitest::Assertion expected but nothing was raised." + + assert_equal expected, e.message + end + + def test_assert_raises_without_block + assert_triggered "assert_raises requires a block to capture errors." do + @tc.assert_raises StandardError + end + end + + def test_assert_respond_to + @tc.assert_respond_to "blah", :empty? + end + + def test_assert_respond_to_triggered + assert_triggered 'Expected "blah" (String) to respond to #rawr!.' do + @tc.assert_respond_to "blah", :rawr! + end + end + + def test_assert_respond_to__include_all + @tc.assert_respond_to @tc, :exit, include_all: true + end + + def test_assert_respond_to__include_all_triggered + assert_triggered(/Expected .+::DummyTest. to respond to #exit\?/) do + @tc.assert_respond_to @tc, :exit?, include_all: true + end + end + + def test_assert_same + @assertion_count = 3 + + o = "blah" + @tc.assert_same 1, 1 + @tc.assert_same :blah, :blah + @tc.assert_same o, o + end + + def test_assert_same_triggered + @assertion_count = 2 + + assert_triggered "Expected 2 (oid=N) to be the same as 1 (oid=N)." do + @tc.assert_same 1, 2 + end + + s1 = +"blah" + s2 = +"blah" + + assert_triggered 'Expected "blah" (oid=N) to be the same as "blah" (oid=N).' do + @tc.assert_same s1, s2 + end + end + + def test_assert_send + @assertion_count = 0 if error_on_warn? + assert_deprecation(/DEPRECATED: assert_send/) do + @tc.assert_send [1, :<, 2] + end + end + + def test_assert_send_bad + if error_on_warn? then + @assertion_count = 0 + assert_deprecation(/DEPRECATED: assert_send/) do + @tc.assert_send [1, :>, 2] + end + else + assert_triggered "Expected 1.>(*[2]) to return true." do + assert_deprecation(/DEPRECATED: assert_send/) do + @tc.assert_send [1, :>, 2] + end + end + end + end + + def test_assert_silent + @assertion_count = 2 + + @tc.assert_silent do + # do nothing + end + end + + def test_assert_silent_triggered_err + assert_triggered util_msg("", "blah blah", "In stderr") do + @tc.assert_silent do + $stderr.print "blah blah" + end + end + end + + def test_assert_silent_triggered_out + @assertion_count = 2 + + assert_triggered util_msg("", "blah blah", "In stdout") do + @tc.assert_silent do + print "blah blah" + end + end + end + + def test_assert_throws + v = @tc.assert_throws :blah do + throw :blah + end + + assert_nil v + end + + def test_assert_throws_value + v = @tc.assert_throws :blah do + throw :blah, 42 + end + + assert_equal 42, v + end + + def test_assert_throws_argument_exception + @assertion_count = 0 + + assert_unexpected "ArgumentError" do + @tc.assert_throws :blah do + raise ArgumentError + end + end + end + + def test_assert_throws_different + assert_triggered "Expected :blah to have been thrown, not :not_blah." do + @tc.assert_throws :blah do + throw :not_blah + end + end + end + + def test_assert_throws_name_error + @assertion_count = 0 + + assert_unexpected "NameError" do + @tc.assert_throws :blah do + raise NameError + end + end + end + + def test_assert_throws_unthrown + assert_triggered "Expected :blah to have been thrown." do + @tc.assert_throws :blah do + # do nothing + end + end + end + + def test_assert_path_exists + @tc.assert_path_exists __FILE__ + end + + def test_assert_path_exists_triggered + assert_triggered "Expected path 'blah' to exist." do + @tc.assert_path_exists "blah" + end + end + + def test_assert_pattern + if RUBY_VERSION > "3" then + @tc.assert_pattern do + exp = if RUBY_VERSION.start_with? "3.0" + "(eval):1: warning: One-line pattern matching is experimental, and the behavior may change in future versions of Ruby!\n" + else + "" + end + assert_output nil, exp do + eval "[1,2,3] => [Integer, Integer, Integer]" # eval to escape parser for ruby<3 + end + end + else + @assertion_count = 0 + + assert_raises NotImplementedError do + @tc.assert_pattern do + # do nothing + end + end + end + end + + def test_assert_pattern_traps_nomatchingpatternerror + skip unless RUBY_VERSION > "3" + exp = if RUBY_VERSION.start_with? "3.0" then + "[1, 2, 3]" # terrible error message! + else + /length mismatch/ + end + + assert_triggered exp do + @tc.assert_pattern do + capture_io do # 3.0 is noisy + eval "[1,2,3] => [Integer, Integer]" # eval to escape parser for ruby<3 + end + end + end + end + + def test_assert_pattern_raises_other_exceptions + skip unless RUBY_VERSION >= "3.0" + + @assertion_count = 0 + + assert_raises RuntimeError do + @tc.assert_pattern do + raise "boom" + end + end + end + + def test_assert_pattern_with_no_block + skip unless RUBY_VERSION >= "3.0" + + assert_triggered "assert_pattern requires a block to capture errors." do + @tc.assert_pattern + end + end + + def test_capture_io + @assertion_count = 0 + + non_verbose do + out, err = capture_io do + puts "hi" + $stderr.puts "bye!" + end + + assert_equal "hi\n", out + assert_equal "bye!\n", err + end + end + + def test_capture_subprocess_io + @assertion_count = 0 + + non_verbose do + out, err = capture_subprocess_io do + system "echo hi" + system "echo bye! 1>&2" + end + + assert_equal "hi\n", out + assert_equal "bye!", err.strip + end + end + + def test_class_asserts_match_refutes + @assertion_count = 0 + + methods = Minitest::Assertions.public_instance_methods.map(&:to_s) + + # These don't have corresponding refutes _on purpose_. They're + # useless and will never be added, so don't bother. + ignores = %w[assert_output assert_raises assert_send + assert_silent assert_throws assert_mock] + + ignores += %w[assert_allocations] # for minitest-gcstats + + asserts = methods.grep(/^assert/).sort - ignores + refutes = methods.grep(/^refute/).sort - ignores + + assert_empty refutes.map { |n| n.sub(/^refute/, "assert") } - asserts + assert_empty asserts.map { |n| n.sub(/^assert/, "refute") } - refutes + end + + def test_delta_consistency + @assertion_count = 2 + + @tc.assert_in_delta 0, 1, 1 + + assert_triggered "Expected |0 - 1| (1) to not be <= 1." do + @tc.refute_in_delta 0, 1, 1 + end + end + + def test_epsilon_consistency + @assertion_count = 2 + + @tc.assert_in_epsilon 1.0, 1.001 + + msg = "Expected |1.0 - 1.001| (0.000999xxx) to not be <= 0.001." + assert_triggered msg do + @tc.refute_in_epsilon 1.0, 1.001 + end + end + + def assert_fail_after t + @tc.fail_after t.year, t.month, t.day, "remove the deprecations" + end + + def test_fail_after + d0 = Time.now + d1 = d0 + 86_400 # I am an idiot + + assert_silent do + assert_fail_after d1 + end + + assert_triggered "remove the deprecations" do + assert_fail_after d0 + end + end + + def test_flunk + assert_triggered "Epic Fail!" do + @tc.flunk + end + end + + def test_flunk_message + assert_triggered @zomg do + @tc.flunk @zomg + end + end + + def test_pass + @tc.pass + end + + def test_refute + @assertion_count = 2 + + @tc.assert_equal true, @tc.refute(false), "returns true on success" + end + + def test_refute_empty + @assertion_count = 2 + + @tc.refute_empty [1] + end + + def test_refute_empty_triggered + @assertion_count = 2 + + assert_triggered "Expected [] to not be empty." do + @tc.refute_empty [] + end + end + + def test_refute_equal + @tc.refute_equal "blah", "yay" + end + + def test_refute_equal_triggered + assert_triggered 'Expected "blah" to not be equal to "blah".' do + @tc.refute_equal "blah", "blah" + end + end + + def test_refute_in_delta + @tc.refute_in_delta 0.0, 1.0 / 1000, 0.000001 + end + + def test_refute_in_delta_triggered + x = "0.1" + assert_triggered "Expected |0.0 - 0.001| (0.001) to not be <= #{x}." do + @tc.refute_in_delta 0.0, 1.0 / 1000, 0.1 + end + end + + def test_refute_in_epsilon + @tc.refute_in_epsilon 10_000, 9990-1 + end + + def test_refute_in_epsilon_triggered + assert_triggered "Expected |10000 - 9990| (10) to not be <= 10.0." do + @tc.refute_in_epsilon 10_000, 9990 + flunk + end + end + + def test_refute_includes + @assertion_count = 2 + + @tc.refute_includes [true], false + end + + def test_refute_includes_triggered + @assertion_count = 3 + + e = @tc.assert_raises Minitest::Assertion do + @tc.refute_includes [true], true + end + + expected = "Expected [true] to not include true." + assert_equal expected, e.message + end + + def test_refute_instance_of + @tc.refute_instance_of Array, "blah" + end + + def test_refute_instance_of_triggered + assert_triggered 'Expected "blah" to not be an instance of String.' do + @tc.refute_instance_of String, "blah" + end + end + + def test_refute_kind_of + @tc.refute_kind_of Array, "blah" + end + + def test_refute_kind_of_triggered + assert_triggered 'Expected "blah" to not be a kind of String.' do + @tc.refute_kind_of String, "blah" + end + end + + def test_refute_match + @assertion_count = 2 + @tc.refute_match(/\d+/, "blah blah blah") + end + + def test_refute_match_matcher_object + @assertion_count = 2 + pattern = Object.new + def pattern.=~ _; false end + @tc.refute_match pattern, 5 + end + + def test_refute_match_object_triggered + @assertion_count = 2 + + pattern = Object.new + def pattern.=~ _; true end + def pattern.inspect; "[Object]" end + + assert_triggered "Expected [Object] to not match 5." do + @tc.refute_match pattern, 5 + end + end + + def test_refute_match_triggered + @assertion_count = 2 + assert_triggered 'Expected /\w+/ to not match "blah blah blah".' do + @tc.refute_match(/\w+/, "blah blah blah") + end + end + + def test_refute_nil + @tc.refute_nil 42 + end + + def test_refute_nil_triggered + assert_triggered "Expected nil to not be nil." do + @tc.refute_nil nil + end + end + + def test_refute_operator + @tc.refute_operator 2, :<, 1 + end + + def test_refute_operator_bad_object + bad = Object.new + def bad.== _; true end + + @tc.refute_operator true, :equal?, bad + end + + def test_refute_operator_triggered + assert_triggered "Expected 2 to not be > 1." do + @tc.refute_operator 2, :>, 1 + end + end + + def test_refute_pattern + if RUBY_VERSION >= "3.0" + @tc.refute_pattern do + capture_io do # 3.0 is noisy + eval "[1,2,3] => [Integer, Integer, String]" + end + end + else + @assertion_count = 0 + + assert_raises NotImplementedError do + @tc.refute_pattern do + eval "[1,2,3] => [Integer, Integer, String]" + end + end + end + end + + def test_refute_pattern_expects_nomatchingpatternerror + skip unless RUBY_VERSION > "3" + + assert_triggered(/NoMatchingPatternError expected, but nothing was raised./) do + @tc.refute_pattern do + capture_io do # 3.0 is noisy + eval "[1,2,3] => [Integer, Integer, Integer]" + end + end + end + end + + def test_refute_pattern_raises_other_exceptions + skip unless RUBY_VERSION >= "3.0" + + @assertion_count = 0 + + assert_raises RuntimeError do + @tc.refute_pattern do + raise "boom" + end + end + end + + def test_refute_pattern_with_no_block + skip unless RUBY_VERSION >= "3.0" + + assert_triggered "refute_pattern requires a block to capture errors." do + @tc.refute_pattern + end + end + + def test_refute_predicate + @tc.refute_predicate "42", :empty? + end + + def test_refute_predicate_triggered + assert_triggered 'Expected "" to not be empty?.' do + @tc.refute_predicate "", :empty? + end + end + + def test_refute_respond_to + @tc.refute_respond_to "blah", :rawr! + end + + def test_refute_respond_to_triggered + assert_triggered 'Expected "blah" to not respond to empty?.' do + @tc.refute_respond_to "blah", :empty? + end + end + + def test_refute_respond_to__include_all + @tc.refute_respond_to "blah", :missing, include_all: true + end + + def test_refute_respond_to__include_all_triggered + assert_triggered(/Expected .*DummyTest.* to not respond to exit./) do + @tc.refute_respond_to @tc, :exit, include_all: true + end + end + + def test_refute_same + @tc.refute_same 1, 2 + end + + def test_refute_same_triggered + assert_triggered "Expected 1 (oid=N) to not be the same as 1 (oid=N)." do + @tc.refute_same 1, 1 + end + end + + def test_refute_path_exists + @tc.refute_path_exists "blah" + end + + def test_refute_path_exists_triggered + assert_triggered "Expected path '#{__FILE__}' to not exist." do + @tc.refute_path_exists __FILE__ + end + end + + def test_skip + @assertion_count = 0 + + assert_triggered "haha!", Minitest::Skip do + @tc.skip "haha!" + end + end + + def assert_skip_until t, msg + @tc.skip_until t.year, t.month, t.day, msg + end + + def test_skip_until + @assertion_count = 0 + + d0 = Time.now + d1 = d0 + 86_400 # I am an idiot + + assert_deprecation(/Stale skip_until \"not yet\" at .*?:\d+$/) do + assert_skip_until d0, "not yet" + end + + assert_triggered "not ready yet", Minitest::Skip do + assert_skip_until d1, "not ready yet" + end + end + + def util_msg exp, act, msg = nil + s = "Expected: #{exp.inspect}\n Actual: #{act.inspect}" + s = "#{msg}.\n#{s}" if msg + s + end + + def without_diff + old_diff = Minitest::Assertions.diff + Minitest::Assertions.diff = nil + + yield + ensure + Minitest::Assertions.diff = old_diff + end +end + +class TestMinitestAssertionHelpers < Minitest::Test + def assert_mu_pp exp, input, raw = false + act = mu_pp input + + if String === input && !raw then + assert_equal "\"#{exp}\"", act + else + assert_equal exp, act + end + end + + def assert_mu_pp_for_diff exp, input, raw = false + act = mu_pp_for_diff input + + if String === input && !raw then + assert_equal "\"#{exp}\"", act + else + assert_equal exp, act + end + end + + def test_diff_equal + msg = <<~EOM.chomp + No visible difference in the String#inspect output. + You should look at the implementation of #== on String or its members. + "blahblahblahblahblahblahblahblahblahblah" + EOM + + o1 = "blah" * 10 + o2 = "blah" * 10 + def o1.== _ + false + end + + assert_equal msg, diff(o1, o2) + end + + def test_diff_str_mixed + msg = <<~'EOM' # NOTE single quotes on heredoc + --- expected + +++ actual + @@ -1 +1 @@ + -"A\\n\nB" + +"A\n\\nB" + EOM + + exp = "A\\n\nB" + act = "A\n\\nB" + + assert_equal msg, diff(exp, act) + end + + def test_diff_str_multiline + msg = <<~EOM + --- expected + +++ actual + @@ -1,2 +1,2 @@ + "A + -B" + +C" + EOM + + exp = "A\nB" + act = "A\nC" + + assert_equal msg, diff(exp, act) + end + + def test_diff_str_simple + msg = <<~EOM.chomp + Expected: "A" + Actual: "B" + EOM + + exp = "A" + act = "B" + + assert_equal msg, diff(exp, act) + end + + def test_message + assert_equal "blah2.", message { "blah2" }.call + assert_equal "blah2.", message("") { "blah2" }.call + assert_equal "blah1.\nblah2.", message(:blah1) { "blah2" }.call + assert_equal "blah1.\nblah2.", message("blah1") { "blah2" }.call + + message = proc { "blah1" } + assert_equal "blah1.\nblah2.", message(message) { "blah2" }.call + + message = message { "blah1" } + assert_equal "blah1.\nblah2.", message(message) { "blah2" }.call + end + + def test_message_deferred + var = nil + + msg = message { var = "blah" } + + assert_nil var + + msg.call + + assert_equal "blah", var + end + + def test_mu_pp + assert_mu_pp 42.inspect, 42 + assert_mu_pp %w[a b c].inspect, %w[a b c] + assert_mu_pp "A B", "A B" + assert_mu_pp "A\\nB", "A\nB" + assert_mu_pp "A\\\\nB", 'A\nB' # notice single quotes + end + + def test_mu_pp_for_diff + assert_mu_pp_for_diff "#", Object.new + assert_mu_pp_for_diff "A B", "A B" + assert_mu_pp_for_diff [1, 2, 3].inspect, [1, 2, 3] + assert_mu_pp_for_diff "A\nB", "A\nB" + end + + def test_mu_pp_for_diff_str_bad_encoding + str = "\666".dup.force_encoding Encoding::UTF_8 + exp = "# encoding: UTF-8\n# valid: false\n\"\\xB6\"" + + assert_mu_pp_for_diff exp, str, :raw + end + + def test_mu_pp_for_diff_str_bad_encoding_both + str = "\666A\\n\nB".dup.force_encoding Encoding::UTF_8 + exp = "# encoding: UTF-8\n# valid: false\n\"\\xB6A\\\\n\\nB\"" + + assert_mu_pp_for_diff exp, str, :raw + end + + def test_mu_pp_for_diff_str_encoding + str = "A\nB".b + exp = "# encoding: #{Encoding::BINARY.name}\n# valid: true\n\"A\nB\"" + + assert_mu_pp_for_diff exp, str, :raw + end + + def test_mu_pp_for_diff_str_encoding_both + str = "A\\n\nB".b + exp = "# encoding: #{Encoding::BINARY.name}\n# valid: true\n\"A\\\\n\\nB\"" + + assert_mu_pp_for_diff exp, str, :raw + end + + def test_mu_pp_for_diff_str_nerd + assert_mu_pp_for_diff "A\\nB\\\\nC", "A\nB\\nC" + assert_mu_pp_for_diff "\\nB\\\\nC", "\nB\\nC" + assert_mu_pp_for_diff "\\nB\\\\n", "\nB\\n" + assert_mu_pp_for_diff "\\n\\\\n", "\n\\n" + assert_mu_pp_for_diff "\\\\n\\n", "\\n\n" + assert_mu_pp_for_diff "\\\\nB\\n", "\\nB\n" + assert_mu_pp_for_diff "\\\\nB\\nC", "\\nB\nC" + assert_mu_pp_for_diff "A\\\\n\\nB", "A\\n\nB" + assert_mu_pp_for_diff "A\\n\\\\nB", "A\n\\nB" + assert_mu_pp_for_diff "\\\\n\\n", "\\n\n" + assert_mu_pp_for_diff "\\n\\\\n", "\n\\n" + end + + def test_mu_pp_for_diff_str_normal + assert_mu_pp_for_diff "", "" + assert_mu_pp_for_diff "A\\n\n", "A\\n" + assert_mu_pp_for_diff "A\\n\nB", "A\\nB" + assert_mu_pp_for_diff "A\n", "A\n" + assert_mu_pp_for_diff "A\nB", "A\nB" + assert_mu_pp_for_diff "\\n\n", "\\n" + assert_mu_pp_for_diff "\n", "\n" + assert_mu_pp_for_diff "\\n\nA", "\\nA" + assert_mu_pp_for_diff "\nA", "\nA" + end + + def test_mu_pp_str_bad_encoding + str = "\666".dup.force_encoding Encoding::UTF_8 + exp = "# encoding: UTF-8\n# valid: false\n\"\\xB6\"" + + assert_mu_pp exp, str, :raw + end + + def test_mu_pp_str_encoding + str = "A\nB".b + exp = "# encoding: #{Encoding::BINARY.name}\n# valid: true\n\"A\\nB\"" + + assert_mu_pp exp, str, :raw + end + + def test_mu_pp_str_immutable + printer = Class.new { extend Minitest::Assertions } + str = "test".freeze + assert_equal '"test"', printer.mu_pp(str) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/test/minitest/test_minitest_benchmark.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/test/minitest/test_minitest_benchmark.rb new file mode 100644 index 00000000..18ce890c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/test/minitest/test_minitest_benchmark.rb @@ -0,0 +1,137 @@ +require "minitest/autorun" +require "minitest/benchmark" + +## +# Used to verify data: +# https://www.wolframalpha.com/examples/RegressionAnalysis.html + +class TestMinitestBenchmark < Minitest::Test + def test_cls_bench_exp + assert_equal [2, 4, 8, 16, 32], Minitest::Benchmark.bench_exp(2, 32, 2) + end + + def test_cls_bench_linear + assert_equal [2, 4, 6, 8, 10], Minitest::Benchmark.bench_linear(2, 10, 2) + end + + def test_cls_runnable_methods + assert_equal [], Minitest::Benchmark.runnable_methods + + c = Class.new Minitest::Benchmark do + def bench_blah + end + end + + assert_equal ["bench_blah"], c.runnable_methods + end + + def test_cls_bench_range + assert_equal [1, 10, 100, 1_000, 10_000], Minitest::Benchmark.bench_range + end + + def test_fit_exponential_clean + x = [1.0, 2.0, 3.0, 4.0, 5.0] + y = x.map { |n| 1.1 * Math.exp(2.1 * n) } + + assert_fit :exponential, x, y, 1.0, 1.1, 2.1 + end + + def test_fit_exponential_noisy + x = [1.0, 1.9, 2.6, 3.4, 5.0] + y = [12, 10, 8.2, 6.9, 5.9] + + # verified with Numbers and R + assert_fit :exponential, x, y, 0.95, 13.81148, -0.1820 + end + + def test_fit_logarithmic_clean + x = [1.0, 2.0, 3.0, 4.0, 5.0] + y = x.map { |n| 1.1 + 2.1 * Math.log(n) } + + assert_fit :logarithmic, x, y, 1.0, 1.1, 2.1 + end + + def test_fit_logarithmic_noisy + x = [1.0, 2.0, 3.0, 4.0, 5.0] + # Generated with + # y = x.map { |n| jitter = 0.999 + 0.002 * rand; (Math.log(n) ) * jitter } + y = [0.0, 0.6935, 1.0995, 1.3873, 1.6097] + + assert_fit :logarithmic, x, y, 0.95, 0, 1 + end + + def test_fit_constant_clean + x = (1..5).to_a + y = [5.0, 5.0, 5.0, 5.0, 5.0] + + assert_fit :linear, x, y, nil, 5.0, 0 + end + + def test_fit_constant_noisy + x = (1..5).to_a + y = [1.0, 1.2, 1.0, 0.8, 1.0] + + # verified in numbers and R + assert_fit :linear, x, y, nil, 1.12, -0.04 + end + + def test_fit_linear_clean + # y = m * x + b where m = 2.2, b = 3.1 + x = (1..5).to_a + y = x.map { |n| 2.2 * n + 3.1 } + + assert_fit :linear, x, y, 1.0, 3.1, 2.2 + end + + def test_fit_linear_noisy + x = [ 60, 61, 62, 63, 65] + y = [3.1, 3.6, 3.8, 4.0, 4.1] + + # verified in numbers and R + assert_fit :linear, x, y, 0.8315, -7.9635, 0.1878 + end + + def test_fit_power_clean + # y = A x ** B, where B = b and A = e ** a + # if, A = 1, B = 2, then + + x = [1.0, 2.0, 3.0, 4.0, 5.0] + y = [1.0, 4.0, 9.0, 16.0, 25.0] + + assert_fit :power, x, y, 1.0, 1.0, 2.0 + end + + def test_fit_power_noisy + # from www.engr.uidaho.edu/thompson/courses/ME330/lecture/least_squares.html + x = [10, 12, 15, 17, 20, 22, 25, 27, 30, 32, 35] + y = [95, 105, 125, 141, 173, 200, 253, 298, 385, 459, 602] + + # verified in numbers + assert_fit :power, x, y, 0.90, 2.6217, 1.4556 + + # income to % of households below income amount + # https://library.wolfram.com/infocenter/Conferences/6461/PowerLaws.nb + x = [15_000, 25_000, 35_000, 50_000, 75_000, 100_000] + y = [0.154, 0.283, 0.402, 0.55, 0.733, 0.843] + + # verified in numbers + assert_fit :power, x, y, 0.96, 3.119e-5, 0.8959 + end + + def assert_fit msg, x, y, fit, exp_a, exp_b + bench = Minitest::Benchmark.new :blah + + a, b, rr = bench.send "fit_#{msg}", x, y + + assert_operator rr, :>=, fit if fit + assert_in_delta exp_a, a + assert_in_delta exp_b, b + end +end + +describe "my class Bench" do + klass = self + it "should provide bench methods" do + klass.must_respond_to :bench + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/test/minitest/test_minitest_mock.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/test/minitest/test_minitest_mock.rb new file mode 100644 index 00000000..3823f7eb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/test/minitest/test_minitest_mock.rb @@ -0,0 +1,1218 @@ +require "minitest/autorun" + +def with_kwargs_env + ENV["MT_KWARGS_HAC\K"] = "1" + + yield +ensure + ENV.delete "MT_KWARGS_HAC\K" +end + +class TestMinitestMock < Minitest::Test + def setup + @mock = Minitest::Mock.new + .expect(:foo, nil) + .expect(:meaning_of_life, 42) + end + + def test_create_stub_method + assert_nil @mock.foo + end + + def test_allow_return_value_specification + assert_equal 42, @mock.meaning_of_life + end + + def test_blow_up_if_not_called + @mock.foo + + util_verify_bad "Expected meaning_of_life() => 42" + end + + def test_not_blow_up_if_everything_called + @mock.foo + @mock.meaning_of_life + + assert_mock @mock + end + + def test_allow_expectations_to_be_added_after_creation + @mock.expect :bar, true + assert @mock.bar + end + + def test_not_verify_if_new_expected_method_is_not_called + @mock.foo + @mock.meaning_of_life + @mock.expect :bar, true + + util_verify_bad "Expected bar() => true" + end + + def test_blow_up_on_wrong_number_of_arguments + @mock.foo + @mock.meaning_of_life + @mock.expect :sum, 3, [1, 2] + + e = assert_raises ArgumentError do + @mock.sum + end + + assert_equal "mocked method :sum expects 2 arguments, got []", e.message + end + + def test_return_mock_does_not_raise + retval = Minitest::Mock.new + mock = Minitest::Mock.new + mock.expect :foo, retval + mock.foo + + assert_mock mock + end + + def test_mock_args_does_not_raise + arg = Minitest::Mock.new + mock = Minitest::Mock.new + mock.expect :foo, nil, [arg] + mock.foo arg + + assert_mock mock + end + + def test_set_expectation_on_special_methods + mock = Minitest::Mock.new + + mock.expect :object_id, "received object_id" + assert_equal "received object_id", mock.object_id + + mock.expect :respond_to_missing?, "received respond_to_missing?" + assert_equal "received respond_to_missing?", mock.respond_to_missing? + + mock.expect :===, "received ===" + assert_equal "received ===", mock.=== + + mock.expect :inspect, "received inspect" + assert_equal "received inspect", mock.inspect + + mock.expect :to_s, "received to_s" + assert_equal "received to_s", mock.to_s + + mock.expect :public_send, "received public_send" + assert_equal "received public_send", mock.public_send + + mock.expect :send, "received send" + assert_equal "received send", mock.send + + assert_mock mock + end + + def test_expectations_can_be_satisfied_via_send + @mock.send :foo + @mock.send :meaning_of_life + + assert_mock @mock + end + + def test_expectations_can_be_satisfied_via_public_send + @mock.public_send :foo + @mock.public_send :meaning_of_life + + assert_mock @mock + end + + def test_blow_up_on_wrong_arguments + @mock.foo + @mock.meaning_of_life + @mock.expect :sum, 3, [1, 2] + + e = assert_raises MockExpectationError do + @mock.sum 2, 4 + end + + exp = "mocked method :sum called with unexpected arguments [2, 4]" + assert_equal exp, e.message + end + + def test_expect_with_non_array_args + e = assert_raises ArgumentError do + @mock.expect :blah, 3, false + end + + assert_match "args must be an array", e.message + end + + def test_respond_appropriately + assert @mock.respond_to?(:foo) + assert @mock.respond_to?(:foo, true) + assert @mock.respond_to?("foo") + assert !@mock.respond_to?(:bar) + end + + def test_no_method_error_on_unexpected_methods + e = assert_raises NoMethodError do + @mock.bar + end + + expected = "unmocked method :bar, expected one of [:foo, :meaning_of_life]" + + assert_match expected, e.message + end + + def test_assign_per_mock_return_values + a = Minitest::Mock.new + b = Minitest::Mock.new + + a.expect :foo, :a + b.expect :foo, :b + + assert_equal :a, a.foo + assert_equal :b, b.foo + end + + def test_do_not_create_stub_method_on_new_mocks + a = Minitest::Mock.new + a.expect :foo, :a + + assert !Minitest::Mock.new.respond_to?(:foo) + end + + def test_mock_is_a_blank_slate + @mock.expect :kind_of?, true, [String] + @mock.expect :==, true, [1] + + assert @mock.kind_of?(String), "didn't mock :kind_of?" + assert @mock == 1, "didn't mock :==" + end + + def test_assert_mock__pass + mock = Minitest::Mock.new + mock.expect :loose_expectation, true, [Integer] + mock.loose_expectation 1 + + result = assert_mock mock + + assert_equal true, result + end + + def assert_bad_mock klass, msg + mock = Minitest::Mock.new + mock.expect :foo, nil, [:bar] + mock.expect :foo, nil, [:baz] + + mock.foo :bar + + e = assert_raises klass do + yield mock + end + + assert_equal msg, e.message + end + + def test_verify__error + exp = "Expected foo(:baz) => nil, got [foo(:bar) => nil]" + assert_bad_mock MockExpectationError, exp do |mock| + mock.verify + end + end + + def test_assert_mock__fail + exp = "Expected foo(:baz) => nil, got [foo(:bar) => nil]." + assert_bad_mock Minitest::Assertion, exp do |mock| + assert_mock mock + end + end + + def test_assert_mock__fail_msg + exp = "BLAH.\nExpected foo(:baz) => nil, got [foo(:bar) => nil]." + assert_bad_mock Minitest::Assertion, exp do |mock| + assert_mock mock, "BLAH" + end + end + + def test_assert_mock__fail_exp + exp = "Expected foo(:baz) => nil, got [foo(:bar) => nil]." + assert_bad_mock Minitest::Assertion, exp do |mock| + describe "X" do + it "y" do + _(mock).must_verify + end + end.new(:blah).send(:test_0001_y) + end + end + + def test_assert_mock__fail_exp_msg + exp = "BLAH.\nExpected foo(:baz) => nil, got [foo(:bar) => nil]." + assert_bad_mock Minitest::Assertion, exp do |mock| + describe "X" do + it "y" do + _(mock).must_verify "BLAH" + end + end.new(:blah).send(:test_0001_y) + end + end + + def test_verify_allows_called_args_to_be_loosely_specified + mock = Minitest::Mock.new + mock.expect :loose_expectation, true, [Integer] + mock.loose_expectation 1 + + assert_mock mock + end + + def test_verify_raises_with_strict_args + mock = Minitest::Mock.new + mock.expect :strict_expectation, true, [2] + + e = assert_raises MockExpectationError do + mock.strict_expectation 1 + end + + exp = "mocked method :strict_expectation called with unexpected arguments [1]" + assert_equal exp, e.message + end + + def test_method_missing_empty + mock = Minitest::Mock.new + + mock.expect :a, nil + + mock.a + + e = assert_raises MockExpectationError do + mock.a + end + + assert_equal "No more expects available for :a: [] {}", e.message + end + + def test_same_method_expects_are_verified_when_all_called + mock = Minitest::Mock.new + mock.expect :foo, nil, [:bar] + mock.expect :foo, nil, [:baz] + + mock.foo :bar + mock.foo :baz + + assert_mock mock + end + + def test_same_method_expects_blow_up_when_not_all_called + mock = Minitest::Mock.new + mock.expect :foo, nil, [:bar] + mock.expect :foo, nil, [:baz] + + mock.foo :bar + + e = assert_raises(MockExpectationError) { mock.verify } + + exp = "Expected foo(:baz) => nil, got [foo(:bar) => nil]" + + assert_equal exp, e.message + end + + def test_same_method_expects_with_same_args_blow_up_when_not_all_called + mock = Minitest::Mock.new + mock.expect :foo, nil, [:bar] + mock.expect :foo, nil, [:bar] + + mock.foo :bar + + e = assert_raises(MockExpectationError) { mock.verify } + + exp = "Expected foo(:bar) => nil, got [foo(:bar) => nil]" + + assert_equal exp, e.message + end + + def test_delegator_calls_are_propagated + delegator = Object.new + mock = Minitest::Mock.new delegator + + refute delegator.nil? + refute mock.nil? + assert_mock mock + end + + def test_handles_kwargs_in_error_message + mock = Minitest::Mock.new + + mock.expect :foo, nil, [], kw: true + mock.expect :foo, nil, [], kw: false + + mock.foo kw: true + + e = assert_raises(MockExpectationError) { mock.verify } + + exp = "Expected foo(%p) => nil, got [foo(%p) => nil]" \ + % [{ :kw => false }, { :kw => true }] + + assert_equal exp.delete("{}"), e.message + end + + def test_verify_passes_when_mock_block_returns_true + mock = Minitest::Mock.new + mock.expect :foo, nil do + true + end + + mock.foo + + assert_mock mock + end + + def test_mock_block_is_passed_function_params + arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" } + mock = Minitest::Mock.new + mock.expect :foo, nil do |a1, a2, a3| + a1 == arg1 && a2 == arg2 && a3 == arg3 + end + + assert_silent do + if RUBY_VERSION > "3" then + mock.foo arg1, arg2, arg3 + else + mock.foo arg1, arg2, **arg3 # oddity just for ruby 2.7 + end + end + + assert_mock mock + end + + def test_mock_block_is_passed_keyword_args__block + arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" } + mock = Minitest::Mock.new + mock.expect :foo, nil do |k1:, k2:, k3:| + k1 == arg1 && k2 == arg2 && k3 == arg3 + end + + mock.foo k1: arg1, k2: arg2, k3: arg3 + + assert_mock mock + end + + def test_mock_block_is_passed_keyword_args__block_bad_missing + arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" } + mock = Minitest::Mock.new + mock.expect :foo, nil do |k1:, k2:, k3:| + k1 == arg1 && k2 == arg2 && k3 == arg3 + end + + e = assert_raises ArgumentError do + mock.foo k1: arg1, k2: arg2 + end + + # basically testing ruby ... need ? for ruby < 2.7 :( + assert_match(/missing keyword: :?k3/, e.message) + end + + def test_mock_block_is_passed_keyword_args__block_bad_extra + arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" } + mock = Minitest::Mock.new + mock.expect :foo, nil do |k1:, k2:| + k1 == arg1 && k2 == arg2 && k3 == arg3 + end + + e = assert_raises ArgumentError do + mock.foo k1: arg1, k2: arg2, k3: arg3 + end + + # basically testing ruby ... need ? for ruby < 2.7 :( + assert_match(/unknown keyword: :?k3/, e.message) + end + + def test_mock_block_is_passed_keyword_args__block_bad_value + arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" } + mock = Minitest::Mock.new + mock.expect :foo, nil do |k1:, k2:, k3:| + k1 == arg1 && k2 == arg2 && k3 == arg3 + end + + e = assert_raises MockExpectationError do + mock.foo k1: arg1, k2: arg2, k3: :BAD! + end + + exp = "mocked method :foo failed block w/ [] %p" \ + % [{ :k1 => :bar, :k2 => [1, 2, 3], :k3 => :BAD! }] + + assert_equal exp, e.message + end + + def test_mock_block_is_passed_keyword_args__args + arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" } + mock = Minitest::Mock.new + mock.expect :foo, nil, k1: arg1, k2: arg2, k3: arg3 + + mock.foo k1: arg1, k2: arg2, k3: arg3 + + assert_mock mock + end + + def test_mock_allow_all_kwargs__old_style_env + with_kwargs_env do + mock = Minitest::Mock.new + mock.expect :foo, true, [Hash] + assert_equal true, mock.foo(bar: 42) + end + end + + def test_mock_allow_all_kwargs__old_style_env__rewrite + with_kwargs_env do + mock = Minitest::Mock.new + mock.expect :foo, true, [], bar: Integer + assert_equal true, mock.foo(bar: 42) + end + end + + def test_mock_block_is_passed_keyword_args__args__old_style_bad + arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" } + mock = Minitest::Mock.new + mock.expect :foo, nil, [{ k1: arg1, k2: arg2, k3: arg3 }] + + e = assert_raises ArgumentError do + mock.foo k1: arg1, k2: arg2, k3: arg3 + end + + assert_equal "mocked method :foo expects 1 arguments, got []", e.message + end + + def test_mock_block_is_passed_keyword_args__args__old_style_env + with_kwargs_env do + arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" } + mock = Minitest::Mock.new + mock.expect :foo, nil, [{ k1: arg1, k2: arg2, k3: arg3 }] + + mock.foo k1: arg1, k2: arg2, k3: arg3 + + assert_mock mock + end + end + + def test_mock_block_is_passed_keyword_args__args__old_style_both + with_kwargs_env do + arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" } + mock = Minitest::Mock.new + + assert_deprecation(/Using MT_KWARGS_HAC. yet passing kwargs/) do + mock.expect :foo, nil, [{}], k1: arg1, k2: arg2, k3: arg3 + end + + skip "-Werror" if error_on_warn? # mock above raised, so this is dead + + mock.foo({}, k1: arg1, k2: arg2, k3: arg3) + + assert_mock mock + end + end + + def test_mock_block_is_passed_keyword_args__args_bad_missing + arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" } + mock = Minitest::Mock.new + mock.expect :foo, nil, k1: arg1, k2: arg2, k3: arg3 + + e = assert_raises ArgumentError do + mock.foo k1: arg1, k2: arg2 + end + + assert_equal "mocked method :foo expects 3 keyword arguments, got %p" % { k1: arg1, k2: arg2 }, e.message + end + + def test_mock_block_is_passed_keyword_args__args_bad_extra + arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" } + mock = Minitest::Mock.new + mock.expect :foo, nil, k1: arg1, k2: arg2 + + e = assert_raises ArgumentError do + mock.foo k1: arg1, k2: arg2, k3: arg3 + end + + assert_equal "mocked method :foo expects 2 keyword arguments, got %p" % { k1: arg1, k2: arg2, k3: arg3 }, e.message + end + + def test_mock_block_is_passed_keyword_args__args_bad_key + arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" } + mock = Minitest::Mock.new + mock.expect :foo, nil, k1: arg1, k2: arg2, k3: arg3 + + e = assert_raises MockExpectationError do + mock.foo k1: arg1, k2: arg2, BAD: arg3 + end + + assert_includes e.message, "unexpected keywords [:k1, :k2, :k3]" + assert_includes e.message, "vs [:k1, :k2, :BAD]" + end + + def test_mock_block_is_passed_keyword_args__args_bad_val + arg1, arg2, arg3 = :bar, [1, 2, 3], { :a => "a" } + mock = Minitest::Mock.new + mock.expect :foo, nil, k1: arg1, k2: arg2, k3: arg3 + + e = assert_raises MockExpectationError do + mock.foo k1: arg1, k2: :BAD!, k3: arg3 + end + + bad = { :k2 => :BAD! }.inspect.delete "{}" + assert_match(/unexpected keyword arguments.* vs .*#{bad}/, e.message) + end + + def test_mock_block_is_passed_function_block + mock = Minitest::Mock.new + block = proc { "bar" } + mock.expect :foo, nil do |arg, &blk| + arg == "foo" && blk == block + end + mock.foo "foo", &block + assert_mock mock + end + + def test_mock_forward_keyword_arguments + mock = Minitest::Mock.new + mock.expect(:foo, nil) { |bar:| bar == "bar" } + mock.foo bar: "bar" + assert_mock mock + end + + def test_verify_fails_when_mock_block_returns_false + mock = Minitest::Mock.new + mock.expect :foo, nil do + false + end + + e = assert_raises(MockExpectationError) { mock.foo } + exp = "mocked method :foo failed block w/ [] {}" + + assert_equal exp, e.message + end + + def test_mock_block_raises_if_args_passed + mock = Minitest::Mock.new + + e = assert_raises ArgumentError do + mock.expect :foo, nil, [:a, :b, :c] do + true + end + end + + exp = "args ignored when block given" + + assert_match exp, e.message + end + + def test_mock_block_raises_if_kwargs_passed + mock = Minitest::Mock.new + + e = assert_raises ArgumentError do + mock.expect :foo, nil, kwargs: 1 do + true + end + end + + exp = "kwargs ignored when block given" + + assert_match exp, e.message + end + + def test_mock_returns_retval_when_called_with_block + mock = Minitest::Mock.new + mock.expect :foo, 32 do + true + end + + rs = mock.foo + + assert_equal rs, 32 + end + + def util_verify_bad exp + e = assert_raises MockExpectationError do + @mock.verify + end + + assert_equal exp, e.message + end + + def test_mock_called_via_send + mock = Minitest::Mock.new + mock.expect :foo, true + + mock.send :foo + assert_mock mock + end + + def test_mock_called_via___send__ + mock = Minitest::Mock.new + mock.expect :foo, true + + mock.__send__ :foo + assert_mock mock + end + + def test_mock_called_via_send_with_args + mock = Minitest::Mock.new + mock.expect :foo, true, [1, 2, 3] + + mock.send :foo, 1, 2, 3 + assert_mock mock + end + +end + +require "minitest/metametameta" + +class TestMinitestStub < Minitest::Test + # Do not parallelize since we're calling stub on class methods + + def setup + super + Minitest::Test.reset + + @tc = Minitest::Test.new "fake tc" + @assertion_count = 1 + end + + def teardown + super + assert_equal @assertion_count, @tc.assertions if self.passed? + end + + class Time + def self.now + 24 + end + end + + def assert_stub val_or_callable + @assertion_count += 1 + + t = Time.now.to_i + + Time.stub :now, val_or_callable do + @tc.assert_equal 42, Time.now + end + + @tc.assert_operator Time.now.to_i, :>=, t + end + + def test_stub_private_module_method + @assertion_count += 1 + + t0 = Time.now + + self.stub :sleep, nil do + @tc.assert_nil sleep(10) + end + + @tc.assert_operator Time.now - t0, :<=, 1 + end + + def test_stub_private_module_method_indirect + @assertion_count += 1 + + fail_clapper = Class.new do + def fail_clap + raise + :clap + end + end.new + + fail_clapper.stub :raise, nil do |safe_clapper| + @tc.assert_equal :clap, safe_clapper.fail_clap # either form works + @tc.assert_equal :clap, fail_clapper.fail_clap # yay closures + end + end + + def test_stub_public_module_method + Math.stub :log10, :stubbed do + @tc.assert_equal :stubbed, Math.log10(1000) + end + end + + def test_stub_value__literal + assert_stub 42 + end + + def test_stub_block + assert_stub lambda { 42 } + end + + def test_stub_block_args + @assertion_count += 1 + + t = Time.now.to_i + + Time.stub :now, lambda { |n| n * 2 } do + @tc.assert_equal 42, Time.now(21) + end + + @tc.assert_operator Time.now.to_i, :>=, t + end + + def test_stub_callable + obj = Object.new + + def obj.call + 42 + end + + assert_stub obj + end + + def test_stub_yield_self + obj = +"foo" + + val = obj.stub :to_s, "bar" do |s| + s.to_s + end + + @tc.assert_equal "bar", val + end + + def test_dynamic_method + @assertion_count = 2 + + dynamic = Class.new do + def self.respond_to? meth + meth == :found + end + + def self.method_missing meth, *args, &block + if meth == :found + false + else + super + end + end + end + + val = dynamic.stub :found, true do |s| + s.found + end + + @tc.assert_equal true, val + @tc.assert_equal false, dynamic.found + end + + def test_stub_NameError + e = @tc.assert_raises NameError do + Time.stub :nope_nope_nope, 42 do + # do nothing + end + end + + exp = if jruby? then + /Undefined method nope_nope_nope for '#{self.class}::Time'/ + else + /undefined method [`']nope_nope_nope' for( class)? [`']#{self.class}::Time'/ + end + assert_match exp, e.message + end + + def test_mock_with_yield + mock = Minitest::Mock.new + mock.expect :write, true do + true + end + rs = nil + + File.stub :open, true, mock do + File.open "foo.txt", "r" do |f| + rs = f.write + end + end + @tc.assert_equal true, rs + end + + def test_mock_with_yield_kwargs + mock = Minitest::Mock.new + rs = nil + + File.stub :open, true, mock, kw: 42 do + File.open "foo.txt", "r" do |f, kw:| + rs = kw + end + end + + @tc.assert_equal 42, rs + end + + ## Permutation Sets: + + # [:value, :lambda] + # [:*, :block, :block_call] + # [:**, :block_args] + # + # Where: + # + # :value = a normal value + # :lambda = callable or lambda + # :* = no block + # :block = normal block + # :block_call = :lambda invokes the block (N/A for :value) + # :** = no args + # :args = args passed to stub + + ## Permutations + + # [:call, :*, :**] =>5 callable+block FIX: CALL BOTH (bug) + # [:call, :*, :**] =>6 callable + + # [:lambda, :*, :**] => lambda result + + # [:lambda, :*, :args] => lambda result NO ARGS + + # [:lambda, :block, :**] =>5 lambda result FIX: CALL BOTH (bug) + # [:lambda, :block, :**] =>6 lambda result + + # [:lambda, :block, :args] =>5 lambda result FIX: CALL BOTH (bug) + # [:lambda, :block, :args] =>6 lambda result + # [:lambda, :block, :args] =>7 raise ArgumentError + + # [:lambda, :block_call, :**] =>5 lambda FIX: BUG!-not passed block to lambda + # [:lambda, :block_call, :**] =>6 lambda+block result + + # [:lambda, :block_call, :args] =>5 lambda FIX: BUG!-not passed block to lambda + # [:lambda, :block_call, :args] =>6 lambda+block result + + # [:value, :*, :**] => value + + # [:value, :*, :args] => value, ignore args + + # [:value, :block, :**] =>5 value, call block + # [:value, :block, :**] =>6 value + + # [:value, :block, :args] =>5 value, call block w/ args + # [:value, :block, :args] =>6 value, call block w/ args, deprecated + # [:value, :block, :args] =>7 raise ArgumentError + + # [:value, :block_call, :**] => N/A + + # [:value, :block_call, :args] => N/A + + class Bar + def call &_ # to ignore unused block + puts "hi" + end + end + + class Foo + def self.blocking + yield + end + end + + class Thingy + def self.identity arg + arg + end + end + + class Keywords + def self.args req, kw1:, kw2: 24 + [req, kw1, kw2] + end + end + + def test_stub_callable_keyword_args + Keywords.stub :args, ->(*args, **kws) { [args, kws] } do + @tc.assert_equal [["woot"], { kw1: 42 }], Keywords.args("woot", kw1: 42) + end + end + + def test_stub__hash_as_last_real_arg + with_kwargs_env do + token = Object.new + def token.create_with_retry _u, _p; raise "shouldn't see this"; end + + controller = Object.new + controller.define_singleton_method :create do |u, p| + token.create_with_retry u, p + end + + params = Object.new + def params.to_hash; raise "nah"; end + + token.stub(:create_with_retry, ->(u, p) { 42 }) do + act = controller.create :u, params + @tc.assert_equal 42, act + end + end + end + + def test_stub_callable_block_5 # from tenderlove + @assertion_count += 1 + Foo.stub5 :blocking, Bar.new do + @tc.assert_output "hi\n", "" do + Foo.blocking do + @tc.flunk "shouldn't ever hit this" + end + end + end + end + + def test_stub_callable_block_6 # from tenderlove + skip_stub6 + + @assertion_count += 1 + Foo.stub6 :blocking, Bar.new do + @tc.assert_output "hi\n", "" do + Foo.blocking do + @tc.flunk "shouldn't ever hit this" + end + end + end + end + + def test_stub_lambda + Thread.stub :new, lambda { 21+21 } do + @tc.assert_equal 42, Thread.new + end + end + + def test_stub_lambda_args + Thread.stub :new, lambda { 21+21 }, :wtf do + @tc.assert_equal 42, Thread.new + end + end + + def test_stub_lambda_block_5 + Thread.stub5 :new, lambda { 21+21 } do + result = Thread.new do + @tc.flunk "shouldn't ever hit this" + end + @tc.assert_equal 42, result + end + end + + def test_stub_lambda_block_6 + skip_stub6 + + Thread.stub6 :new, lambda { 21+21 } do + result = Thread.new do + @tc.flunk "shouldn't ever hit this" + end + @tc.assert_equal 42, result + end + end + + def test_stub_lambda_block_args_5 + @assertion_count += 1 + Thingy.stub5 :identity, lambda { |y| @tc.assert_equal :nope, y; 21+21 }, :WTF? do + result = Thingy.identity :nope do |x| + @tc.flunk "shouldn't reach this" + end + @tc.assert_equal 42, result + end + end + + def test_stub_lambda_block_args_6 + skip_stub6 + + @assertion_count += 1 + Thingy.stub6 :identity, lambda { |y| @tc.assert_equal :nope, y; 21+21 }, :WTF? do + result = Thingy.identity :nope do |x| + @tc.flunk "shouldn't reach this" + end + @tc.assert_equal 42, result + end + end + + def test_stub_lambda_block_args_6_2 + skip_stub6 + + @tc.assert_raises ArgumentError do + Thingy.stub6_2 :identity, lambda { |y| :__not_run__ }, :WTF? do + # doesn't matter + end + end + end + + def test_stub_lambda_block_call_5 + @assertion_count += 1 + rs = nil + io = StringIO.new(+"", "w") + File.stub5 :open, lambda { |p, m, &blk| blk and blk.call io } do + File.open "foo.txt", "r" do |f| + rs = f && f.write("woot") + end + end + @tc.assert_equal 4, rs + @tc.assert_equal "woot", io.string + end + + def test_stub_lambda_block_call_6 + skip_stub6 + + @assertion_count += 1 + rs = nil + io = StringIO.new(+"", "w") + File.stub6 :open, lambda { |p, m, &blk| blk.call io } do + File.open "foo.txt", "r" do |f| + rs = f.write "woot" + end + end + @tc.assert_equal 4, rs + @tc.assert_equal "woot", io.string + end + + def test_stub_lambda_block_call_args_5 + @assertion_count += 1 + rs = nil + io = StringIO.new(+"", "w") + File.stub5(:open, lambda { |p, m, &blk| blk and blk.call io }, :WTF?) do + File.open "foo.txt", "r" do |f| + rs = f.write "woot" + end + end + @tc.assert_equal 4, rs + @tc.assert_equal "woot", io.string + end + + def test_stub_lambda_block_call_args_6 + skip_stub6 + + @assertion_count += 1 + rs = nil + io = StringIO.new(+"", "w") + File.stub6(:open, lambda { |p, m, &blk| blk.call io }, :WTF?) do + File.open "foo.txt", "r" do |f| + rs = f.write "woot" + end + end + @tc.assert_equal 4, rs + @tc.assert_equal "woot", io.string + end + + def test_stub_lambda_block_call_args_6_2 + skip_stub6 + + @assertion_count += 2 + rs = nil + io = StringIO.new(+"", "w") + @tc.assert_raises ArgumentError do + File.stub6_2(:open, lambda { |p, m, &blk| blk.call io }, :WTF?) do + File.open "foo.txt", "r" do |f| + rs = f.write "woot" + end + end + end + @tc.assert_nil rs + @tc.assert_equal "", io.string + end + + def test_stub_value + Thread.stub :new, 42 do + result = Thread.new + @tc.assert_equal 42, result + end + end + + def test_stub_value_args + Thread.stub :new, 42, :WTF? do + result = Thread.new + @tc.assert_equal 42, result + end + end + + def test_stub_value_block_5 + @assertion_count += 1 + Thread.stub5 :new, 42 do + result = Thread.new do + @tc.assert true + end + @tc.assert_equal 42, result + end + end + + def test_stub_value_block_6 + skip_stub6 + + Thread.stub6 :new, 42 do + result = Thread.new do + @tc.flunk "shouldn't hit this" + end + @tc.assert_equal 42, result + end + end + + def test_stub_value_block_args_5 + @assertion_count += 2 + rs = nil + io = StringIO.new(+"", "w") + File.stub5 :open, :value, io do + result = File.open "foo.txt", "r" do |f| + rs = f.write "woot" + end + @tc.assert_equal :value, result + end + @tc.assert_equal 4, rs + @tc.assert_equal "woot", io.string + end + + def test_stub_value_block_args_5__break_if_not_passed + e = @tc.assert_raises NoMethodError do + File.stub5 :open, :return_value do # intentionally bad setup w/ no args + File.open "foo.txt", "r" do |f| + f.write "woot" + end + end + end + exp = /undefined method [`']write' for nil/ + assert_match exp, e.message + end + + def test_stub_value_block_args_6 + skip_stub6 + + @assertion_count += 2 + rs = nil + io = StringIO.new(+"", "w") + assert_deprecated do + File.stub6 :open, :value, io do + result = File.open "foo.txt", "r" do |f| + rs = f.write "woot" + end + @tc.assert_equal :value, result + end + end + @tc.assert_equal 4, rs + @tc.assert_equal "woot", io.string + end + + def test_stub_value_block_args_6_2 + skip_stub6 + + @assertion_count += 2 + rs = nil + io = StringIO.new(+"", "w") + @tc.assert_raises ArgumentError do + File.stub6_2 :open, :value, io do + result = File.open "foo.txt", "r" do |f| + @tc.flunk "shouldn't hit this" + end + @tc.assert_equal :value, result + end + end + @tc.assert_nil rs + @tc.assert_equal "", io.string + end + + def assert_deprecated re = /deprecated/ + assert_output "", re do + yield + end + end + + def skip_stub6 + skip "not yet" unless STUB6 + end +end + +STUB6 = ENV["STUB6"] + +if STUB6 then + require "minitest/mock6" if STUB6 +else + class Object + alias stub5 stub + alias stub6 stub + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/test/minitest/test_minitest_reporter.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/test/minitest/test_minitest_reporter.rb new file mode 100644 index 00000000..63c0683d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/test/minitest/test_minitest_reporter.rb @@ -0,0 +1,436 @@ +require "minitest/autorun" +require "minitest/metametameta" +require "forwardable" + +class FakeTest < Minitest::Test + def woot + assert true + end +end + +class TestMinitestReporter < MetaMetaMetaTestCase + + attr_accessor :r, :io + + def new_composite_reporter + reporter = Minitest::CompositeReporter.new + reporter << Minitest::SummaryReporter.new(self.io) + reporter << Minitest::ProgressReporter.new(self.io) + + # eg reporter.results -> reporters.first.results + reporter.extend Forwardable + reporter.delegate :first => :reporters + reporter.delegate %i[results count assertions options to_s] => :first + + reporter + end + + def setup + super + self.io = StringIO.new(+"") + self.r = new_composite_reporter + end + + def error_test + unless defined? @et then + @et = FakeTest.new :woot + @et.failures << Minitest::UnexpectedError.new(begin + raise "no" + rescue => e + e + end) + @et = Minitest::Result.from @et + end + @et + end + + def system_stack_error_test + unless defined? @sse then + + ex = SystemStackError.new + + pre = ("a".."c").to_a + mid = ("aa".."ad").to_a * 67 + post = ("d".."f").to_a + ary = pre + mid + post + + ex.set_backtrace ary + + @sse = FakeTest.new :woot + @sse.failures << Minitest::UnexpectedError.new(ex) + @sse = Minitest::Result.from @sse + end + @sse + end + + def fail_test + unless defined? @ft then + @ft = FakeTest.new :woot + @ft.failures << begin + raise Minitest::Assertion, "boo" + rescue Minitest::Assertion => e + e + end + @ft = Minitest::Result.from @ft + end + @ft + end + + def passing_test + @pt ||= Minitest::Result.from FakeTest.new(:woot) + end + + def passing_test_with_metadata + test = FakeTest.new :woot + test.metadata[:meta] = :data + @pt ||= Minitest::Result.from test + end + + def skip_test + unless defined? @st then + @st = FakeTest.new :woot + @st.failures << begin + raise Minitest::Skip + rescue Minitest::Assertion => e + e + end + @st = Minitest::Result.from @st + end + @st + end + + def test_to_s + r.record passing_test + r.record fail_test + assert_match "woot", r.to_s + end + + def test_options_skip_F + r.options[:skip] = "F" + + r.record passing_test + r.record fail_test + + refute_match "woot", r.to_s + end + + def test_options_skip_E + r.options[:skip] = "E" + + r.record passing_test + r.record error_test + + refute_match "RuntimeError: no", r.to_s + end + + def test_passed_eh_empty + assert_predicate r, :passed? + end + + def test_passed_eh_failure + r.results << fail_test + + refute_predicate r, :passed? + end + + SKIP_MSG = "\n\nYou have skipped tests. Run with --verbose for details." + + def test_passed_eh_error + r.start + + r.results << error_test + + refute_predicate r, :passed? + + r.report + + refute_match SKIP_MSG, io.string + end + + def test_passed_eh_skipped + r.start + r.results << skip_test + assert r.passed? + + restore_env do + r.report + end + + assert_match SKIP_MSG, io.string + end + + def test_passed_eh_skipped_verbose + r.options[:verbose] = true + + r.start + r.results << skip_test + assert r.passed? + r.report + + refute_match SKIP_MSG, io.string + end + + def test_start + r.start + + exp = "Run options: \n\n# Running:\n\n" + + assert_equal exp, io.string + end + + def test_record_pass + r.record passing_test + + assert_equal ".", io.string + assert_empty r.results + assert_equal 1, r.count + assert_equal 0, r.assertions + end + + def test_record_pass_with_metadata + reporter = self.r + + def reporter.metadata + @metadata + end + + def reporter.record result + super + @metadata = result.metadata if result.metadata? + end + + r.record passing_test_with_metadata + + exp = { :meta => :data } + assert_equal exp, reporter.metadata + + assert_equal ".", io.string + assert_empty r.results + assert_equal 1, r.count + assert_equal 0, r.assertions + end + + def test_record_fail + fail_test = self.fail_test + r.record fail_test + + assert_equal "F", io.string + assert_equal [fail_test], r.results + assert_equal 1, r.count + assert_equal 0, r.assertions + end + + def test_record_error + error_test = self.error_test + r.record error_test + + assert_equal "E", io.string + assert_equal [error_test], r.results + assert_equal 1, r.count + assert_equal 0, r.assertions + end + + def test_record_skip + skip_test = self.skip_test + r.record skip_test + + assert_equal "S", io.string + assert_equal [skip_test], r.results + assert_equal 1, r.count + assert_equal 0, r.assertions + end + + def test_report_empty + r.start + r.report + + exp = <<~EOM + Run options: + + # Running: + + + + Finished in 0.00 + + 0 runs, 0 assertions, 0 failures, 0 errors, 0 skips + EOM + + assert_equal exp, normalize_output(io.string) + end + + def test_report_passing + r.start + r.record passing_test + r.report + + exp = <<~EOM + Run options: + + # Running: + + . + + Finished in 0.00 + + 1 runs, 0 assertions, 0 failures, 0 errors, 0 skips + EOM + + assert_equal exp, normalize_output(io.string) + end + + def test_report_failure + r.start + r.record fail_test + r.report + + exp = <<~EOM + Run options: + + # Running: + + F + + Finished in 0.00 + + 1) Failure: + FakeTest#woot [FILE:LINE]: + boo + + 1 runs, 0 assertions, 1 failures, 0 errors, 0 skips + EOM + + assert_equal exp, normalize_output(io.string) + end + + def test_report_error + r.start + r.record error_test + r.report + + exp = <<~EOM + Run options: + + # Running: + + E + + Finished in 0.00 + + 1) Error: + FakeTest#woot: + RuntimeError: no + FILE:LINE:in 'error_test' + FILE:LINE:in 'test_report_error' + + 1 runs, 0 assertions, 0 failures, 1 errors, 0 skips + EOM + + assert_equal exp, normalize_output(io.string) + end + + def test_report_error__sse + r.start + r.record system_stack_error_test + r.report + + exp = <<~EOM + Run options: + + # Running: + + E + + Finished in 0.00 + + 1) Error: + FakeTest#woot: + SystemStackError: 274 -> 12 + a + b + c + +->> 67 cycles of 4 lines: + | aa + | ab + | ac + | ad + +-<< + d + e + f + + 1 runs, 0 assertions, 0 failures, 1 errors, 0 skips + EOM + + assert_equal exp, normalize_output(io.string) + end + + def test_report_skipped + r.start + r.record skip_test + + restore_env do + r.report + end + + exp = <<~EOM + Run options: + + # Running: + + S + + Finished in 0.00 + + 1 runs, 0 assertions, 0 failures, 0 errors, 1 skips + + You have skipped tests. Run with --verbose for details. + EOM + + assert_equal exp, normalize_output(io.string) + end + + def test_report_failure_uses_backtrace_filter + filter = Minitest::BacktraceFilter.new + def filter.filter _bt + ["foo.rb:123:in 'foo'"] + end + + with_backtrace_filter filter do + r.start + r.record fail_test + r.report + end + + exp = "FakeTest#woot [foo.rb:123]" + + assert_includes io.string, exp + end + + def test_report_failure_uses_backtrace_filter_complex_sorbet + backtrace = <<~EOBT + /Users/user/.gem/ruby/3.2.2/gems/minitest-5.20.0/lib/minitest/assertions.rb:183:in 'assert' + example_test.rb:9:in 'assert_false' + /Users/user/.gem/ruby/3.2.2/gems/sorbet-runtime-0.5.11068/lib/types/private/methods/call_validation.rb:256:in 'bind_call' + /Users/user/.gem/ruby/3.2.2/gems/sorbet-runtime-0.5.11068/lib/types/private/methods/call_validation.rb:256:in 'validate_call' + /Users/user/.gem/ruby/3.2.2/gems/sorbet-runtime-0.5.11068/lib/types/private/methods/_methods.rb:275:in 'block in _on_method_added' + example_test.rb:25:in 'test_something' + /Users/user/.gem/ruby/3.2.2/gems/minitest-5.20.0/lib/minitest/test.rb:94:in 'block (3 levels) in run' + /Users/user/.gem/ruby/3.2.2/gems/minitest-5.20.0/lib/minitest/test.rb:191:in 'capture_exceptions' + /Users/user/.gem/ruby/3.2.2/gems/minitest-5.20.0/lib/minitest/test.rb:89:in 'block (2 levels) in run' + ... so many lines ... + EOBT + + filter = Minitest::BacktraceFilter.new %r%lib/minitest|gems/sorbet% + + with_backtrace_filter filter do + begin + assert_equal 1, 2 + rescue Minitest::Assertion => e + e.set_backtrace backtrace.lines.map(&:chomp) + + assert_match "example_test.rb:25", e.location + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/test/minitest/test_minitest_spec.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/test/minitest/test_minitest_spec.rb new file mode 100644 index 00000000..6286685d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/test/minitest/test_minitest_spec.rb @@ -0,0 +1,1163 @@ +require "minitest/metametameta" +require "stringio" + +class MiniSpecA < Minitest::Spec; end +class MiniSpecB < Minitest::Test; extend Minitest::Spec::DSL; end +class MiniSpecC < MiniSpecB; end +class NamedExampleA < MiniSpecA; end +class NamedExampleB < MiniSpecB; end +class NamedExampleC < MiniSpecC; end +class ExampleA; end +class ExampleB < ExampleA; end + +describe Minitest::Spec do + # do not parallelize this suite... it just can"t handle it. + + def assert_triggered expected = "blah", klass = Minitest::Assertion + @assertion_count += 1 + + e = assert_raises klass do + yield + end + + msg = e.message.sub(/(---Backtrace---).*/m, '\1') + msg.gsub!(/\(oid=[-0-9]+\)/, "(oid=N)") + msg.gsub!(/(\d\.\d{6})\d+/, '\1xxx') # normalize: ruby version, impl, platform + msg.gsub!(/:0x[Xa-fA-F0-9]{4,}[ @].+?>/, ":0xXXXXXX@PATH>") + + return unless expected + + @assertion_count += 1 + case expected + when String then + assert_equal expected, msg + when Regexp then + @assertion_count += 1 + assert_match expected, msg + else + flunk "Unknown: #{expected.inspect}" + end + end + + def assert_success spec + assert_equal true, spec + end + + before do + @assertion_count = 4 + end + + after do + _(self.assertions).must_equal @assertion_count if passed? and not skipped? + end + + it "needs to be able to catch a Minitest::Assertion exception" do + @assertion_count = 1 + + assert_triggered "Expected 1 to not be equal to 1." do + _(1).wont_equal 1 + end + end + + it "needs to check for file existence" do + @assertion_count = 3 + + assert_success _(__FILE__).path_must_exist + + assert_triggered "Expected path 'blah' to exist." do + _("blah").path_must_exist + end + end + + it "needs to check for file non-existence" do + @assertion_count = 3 + + assert_success _("blah").path_wont_exist + + assert_triggered "Expected path '#{__FILE__}' to not exist." do + _(__FILE__).path_wont_exist + end + end + + it "needs to be sensible about must_include order" do + @assertion_count += 3 # must_include is 2 assertions + + assert_success _([1, 2, 3]).must_include(2) + + assert_triggered "Expected [1, 2, 3] to include 5." do + _([1, 2, 3]).must_include 5 + end + + assert_triggered "msg.\nExpected [1, 2, 3] to include 5." do + _([1, 2, 3]).must_include 5, "msg" + end + end + + it "needs to be sensible about wont_include order" do + @assertion_count += 3 # wont_include is 2 assertions + + assert_success _([1, 2, 3]).wont_include(5) + + assert_triggered "Expected [1, 2, 3] to not include 2." do + _([1, 2, 3]).wont_include 2 + end + + assert_triggered "msg.\nExpected [1, 2, 3] to not include 2." do + _([1, 2, 3]).wont_include 2, "msg" + end + end + + it "needs to catch an expected exception" do + @assertion_count = 2 + + expect { raise "blah" }.must_raise RuntimeError + expect { raise Minitest::Assertion }.must_raise Minitest::Assertion + end + + it "needs to catch an unexpected exception" do + @assertion_count -= 2 # no positive + + msg = <<-EOM.gsub(/^ {6}/, "").chomp + [RuntimeError] exception expected, not + Class: + Message: <"woot"> + ---Backtrace--- + EOM + + assert_triggered msg do + expect { raise StandardError, "woot" }.must_raise RuntimeError + end + + assert_triggered "msg.\n#{msg}" do + expect { raise StandardError, "woot" }.must_raise RuntimeError, "msg" + end + end + + def good_pattern + capture_io do # 3.0 is noisy + eval "[1,2,3] => [Integer, Integer, Integer]" # eval to escape parser for ruby<3 + end + end + + def bad_pattern + capture_io do # 3.0 is noisy + eval "[1,2,3] => [Integer, Integer]" # eval to escape parser for ruby<3 + end + end + + it "needs to pattern match" do + @assertion_count = 1 + + if RUBY_VERSION > "3" then + expect { good_pattern }.must_pattern_match + else + assert_raises NotImplementedError do + expect {}.must_pattern_match + end + end + end + + it "needs to error on bad pattern match" do + skip unless RUBY_VERSION > "3" + + @assertion_count = 1 + + exp = if RUBY_VERSION.start_with? "3.0" + "[1, 2, 3]" # terrible error message! + else + /length mismatch/ + end + + assert_triggered exp do + expect { bad_pattern }.must_pattern_match + end + end + + it "needs to ensure silence" do + @assertion_count -= 1 # no msg + @assertion_count += 2 # assert_output is 2 assertions + + assert_success expect {}.must_be_silent + + assert_triggered "In stdout.\nExpected: \"\"\n Actual: \"xxx\"" do + expect { print "xxx" }.must_be_silent + end + end + + it "needs to have all methods named well" do + skip "N/A" if ENV["MT_NO_EXPECTATIONS"] + + @assertion_count = 2 + + methods = Minitest::Expectations.public_instance_methods.grep(/must|wont/) + methods.map!(&:to_s) if Symbol === methods.first + + musts, wonts = methods.sort.partition { |m| m.include? "must" } + + expected_musts = %w[must_be + must_be_close_to + must_be_empty + must_be_instance_of + must_be_kind_of + must_be_nil + must_be_same_as + must_be_silent + must_be_within_delta + must_be_within_epsilon + must_equal + must_include + must_match + must_output + must_pattern_match + must_raise + must_respond_to + must_throw + must_verify + path_must_exist] + + bad = %w[not raise throw send output be_silent verify] + + expected_wonts = expected_musts.map { |m| m.sub("must", "wont") }.sort + expected_wonts.reject! { |m| m =~ /wont_#{Regexp.union(*bad)}/ } + + _(musts).must_equal expected_musts + _(wonts).must_equal expected_wonts + end + + it "needs to raise if an expected exception is not raised" do + @assertion_count -= 2 # no positive test + + assert_triggered "RuntimeError expected but nothing was raised." do + expect { 42 }.must_raise RuntimeError + end + + assert_triggered "msg.\nRuntimeError expected but nothing was raised." do + expect { 42 }.must_raise RuntimeError, "msg" + end + end + + it "needs to verify binary messages" do + assert_success _(42).wont_be(:<, 24) + + assert_triggered "Expected 24 to not be < 42." do + _(24).wont_be :<, 42 + end + + assert_triggered "msg.\nExpected 24 to not be < 42." do + _(24).wont_be :<, 42, "msg" + end + end + + it "needs to verify emptyness" do + @assertion_count += 3 # empty is 2 assertions + + assert_success _([]).must_be_empty + + assert_triggered "Expected [42] to be empty." do + _([42]).must_be_empty + end + + assert_triggered "msg.\nExpected [42] to be empty." do + _([42]).must_be_empty "msg" + end + end + + it "needs to verify equality" do + @assertion_count += 1 + + assert_success _(6 * 7).must_equal(42) + + assert_triggered "Expected: 42\n Actual: 54" do + _(6 * 9).must_equal 42 + end + + assert_triggered "msg.\nExpected: 42\n Actual: 54" do + _(6 * 9).must_equal 42, "msg" + end + + assert_triggered(/^-42\n\+#\n/) do + _(proc { 42 }).must_equal 42 # proc isn't called, so expectation fails + end + end + + it "needs to warn on equality with nil" do + @assertion_count = 3 + @assertion_count += 2 unless error_on_warn? # 2 extra assertions + + exp = /DEPRECATED: Use assert_nil if expecting nil from .* This will fail in Minitest 6./ + + assert_deprecation exp do + assert_success _(nil).must_equal(nil) + end + end + + it "needs to verify floats outside a delta" do + @assertion_count += 1 # extra test + + assert_success _(24).wont_be_close_to(42) + + assert_triggered "Expected |42 - 42.0| (0.0) to not be <= 0.001." do + _(6 * 7.0).wont_be_close_to 42 + end + + x = "1.0e-05" + assert_triggered "Expected |42 - 42.0| (0.0) to not be <= #{x}." do + _(6 * 7.0).wont_be_close_to 42, 0.00001 + end + + assert_triggered "msg.\nExpected |42 - 42.0| (0.0) to not be <= #{x}." do + _(6 * 7.0).wont_be_close_to 42, 0.00001, "msg" + end + end + + it "needs to verify floats outside an epsilon" do + @assertion_count += 1 # extra test + + assert_success _(24).wont_be_within_epsilon(42) + + x = "0.042" + assert_triggered "Expected |42 - 42.0| (0.0) to not be <= #{x}." do + _(6 * 7.0).wont_be_within_epsilon 42 + end + + x = "0.00042" + assert_triggered "Expected |42 - 42.0| (0.0) to not be <= #{x}." do + _(6 * 7.0).wont_be_within_epsilon 42, 0.00001 + end + + assert_triggered "msg.\nExpected |42 - 42.0| (0.0) to not be <= #{x}." do + _(6 * 7.0).wont_be_within_epsilon 42, 0.00001, "msg" + end + end + + it "needs to verify floats within a delta" do + @assertion_count += 1 # extra test + + assert_success _(6.0 * 7).must_be_close_to(42.0) + + assert_triggered "Expected |0.0 - 0.01| (0.01) to be <= 0.001." do + _(1.0 / 100).must_be_close_to 0.0 + end + + x = "1.0e-06" + assert_triggered "Expected |0.0 - 0.001| (0.001) to be <= #{x}." do + _(1.0 / 1000).must_be_close_to 0.0, 0.000001 + end + + assert_triggered "msg.\nExpected |0.0 - 0.001| (0.001) to be <= #{x}." do + _(1.0 / 1000).must_be_close_to 0.0, 0.000001, "msg" + end + end + + it "needs to verify floats within an epsilon" do + @assertion_count += 1 # extra test + + assert_success _(6.0 * 7).must_be_within_epsilon(42.0) + + assert_triggered "Expected |0.0 - 0.01| (0.01) to be <= 0.0." do + _(1.0 / 100).must_be_within_epsilon 0.0 + end + + assert_triggered "Expected |0.0 - 0.001| (0.001) to be <= 0.0." do + _(1.0 / 1000).must_be_within_epsilon 0.0, 0.000001 + end + + assert_triggered "msg.\nExpected |0.0 - 0.001| (0.001) to be <= 0.0." do + _(1.0 / 1000).must_be_within_epsilon 0.0, 0.000001, "msg" + end + end + + it "needs to verify identity" do + assert_success _(1).must_be_same_as(1) + + assert_triggered "Expected 1 (oid=N) to be the same as 2 (oid=N)." do + _(1).must_be_same_as 2 + end + + assert_triggered "msg.\nExpected 1 (oid=N) to be the same as 2 (oid=N)." do + _(1).must_be_same_as 2, "msg" + end + end + + it "needs to verify inequality" do + @assertion_count += 2 + assert_success _(42).wont_equal(6 * 9) + assert_success _(proc {}).wont_equal(42) + + assert_triggered "Expected 1 to not be equal to 1." do + _(1).wont_equal 1 + end + + assert_triggered "msg.\nExpected 1 to not be equal to 1." do + _(1).wont_equal 1, "msg" + end + end + + it "needs to verify instances of a class" do + assert_success _(42).wont_be_instance_of(String) + + assert_triggered "Expected 42 to not be a kind of Integer." do + _(42).wont_be_kind_of Integer + end + + assert_triggered "msg.\nExpected 42 to not be an instance of Integer." do + _(42).wont_be_instance_of Integer, "msg" + end + end + + it "needs to verify kinds of a class" do + @assertion_count += 2 + + assert_success _(42).wont_be_kind_of(String) + assert_success _(proc {}).wont_be_kind_of(String) + + assert_triggered "Expected 42 to not be a kind of Integer." do + _(42).wont_be_kind_of Integer + end + + assert_triggered "msg.\nExpected 42 to not be a kind of Integer." do + _(42).wont_be_kind_of Integer, "msg" + end + end + + it "needs to verify kinds of objects" do + @assertion_count += 3 # extra test + + assert_success _(6 * 7).must_be_kind_of(Integer) + assert_success _(6 * 7).must_be_kind_of(Numeric) + + assert_triggered "Expected 42 to be a kind of String, not Integer." do + _(6 * 7).must_be_kind_of String + end + + assert_triggered "msg.\nExpected 42 to be a kind of String, not Integer." do + _(6 * 7).must_be_kind_of String, "msg" + end + + exp = "Expected # to be a kind of String, not Proc." + assert_triggered exp do + _(proc {}).must_be_kind_of String + end + end + + it "needs to verify mismatch" do + @assertion_count += 3 # match is 2 + + assert_success _("blah").wont_match(/\d+/) + + assert_triggered "Expected /\\w+/ to not match \"blah\"." do + _("blah").wont_match(/\w+/) + end + + assert_triggered "msg.\nExpected /\\w+/ to not match \"blah\"." do + _("blah").wont_match(/\w+/, "msg") + end + end + + it "needs to verify nil" do + assert_success _(nil).must_be_nil + + assert_triggered "Expected 42 to be nil." do + _(42).must_be_nil + end + + assert_triggered "msg.\nExpected 42 to be nil." do + _(42).must_be_nil "msg" + end + end + + it "needs to verify non-emptyness" do + @assertion_count += 3 # empty is 2 assertions + + assert_success _(["some item"]).wont_be_empty + + assert_triggered "Expected [] to not be empty." do + _([]).wont_be_empty + end + + assert_triggered "msg.\nExpected [] to not be empty." do + _([]).wont_be_empty "msg" + end + end + + it "needs to verify non-identity" do + assert_success _(1).wont_be_same_as(2) + + assert_triggered "Expected 1 (oid=N) to not be the same as 1 (oid=N)." do + _(1).wont_be_same_as 1 + end + + assert_triggered "msg.\nExpected 1 (oid=N) to not be the same as 1 (oid=N)." do + _(1).wont_be_same_as 1, "msg" + end + end + + it "needs to verify non-nil" do + assert_success _(42).wont_be_nil + + assert_triggered "Expected nil to not be nil." do + _(nil).wont_be_nil + end + + assert_triggered "msg.\nExpected nil to not be nil." do + _(nil).wont_be_nil "msg" + end + end + + it "needs to verify objects not responding to a message" do + assert_success _("").wont_respond_to(:woot!) + + assert_triggered "Expected \"\" to not respond to to_s." do + _("").wont_respond_to :to_s + end + + assert_triggered "msg.\nExpected \"\" to not respond to to_s." do + _("").wont_respond_to :to_s, "msg" + end + end + + it "needs to verify output in stderr" do + @assertion_count -= 1 # no msg + + assert_success expect { $stderr.print "blah" }.must_output(nil, "blah") + + assert_triggered "In stderr.\nExpected: \"blah\"\n Actual: \"xxx\"" do + expect { $stderr.print "xxx" }.must_output(nil, "blah") + end + end + + it "needs to verify output in stdout" do + @assertion_count -= 1 # no msg + + assert_success expect { print "blah" }.must_output("blah") + + assert_triggered "In stdout.\nExpected: \"blah\"\n Actual: \"xxx\"" do + expect { print "xxx" }.must_output("blah") + end + end + + it "needs to verify regexp matches" do + @assertion_count += 3 # must_match is 2 assertions + + assert_kind_of MatchData, _("blah").must_match(/\w+/) + + assert_triggered "Expected /\\d+/ to match \"blah\"." do + _("blah").must_match(/\d+/) + end + + assert_triggered "msg.\nExpected /\\d+/ to match \"blah\"." do + _("blah").must_match(/\d+/, "msg") + end + end + + describe "expect" do + before do + @assertion_count -= 3 + end + + it "can use expect" do + _(1 + 1).must_equal 2 + end + + it "can use expect with a lambda" do + _ { raise "blah" }.must_raise RuntimeError + end + + it "can use expect in a thread" do + Thread.new { _(1 + 1).must_equal 2 }.join + end + + it "can NOT use must_equal in a thread. It must use expect in a thread" do + skip "N/A" if ENV["MT_NO_EXPECTATIONS"] + + assert_raises RuntimeError, Minitest::UnexpectedWarning do + capture_io do + Thread.new { (1 + 1).must_equal 2 }.join + end + end + end + + it "fails gracefully when expectation used outside of `it`" do + skip "N/A" if ENV["MT_NO_EXPECTATIONS"] + + @assertion_count += 2 # assert_match is compound + + e = assert_raises RuntimeError, Minitest::UnexpectedWarning do + capture_io do + Thread.new { # forces ctx to be nil + describe "woot" do + (1 + 1).must_equal 2 + end + }.join + end + end + + exp = "Calling #must_equal outside of test." + exp = "DEPRECATED: global use of must_equal from" if error_on_warn? + + assert_match exp, e.message + end + + it "deprecates expectation used without _" do + skip "N/A" if ENV["MT_NO_EXPECTATIONS"] + + @assertion_count += 1 + @assertion_count += 2 unless error_on_warn? + + exp = /DEPRECATED: global use of must_equal from/ + + assert_deprecation exp do + (1 + 1).must_equal 2 + end + end + + # https://github.com/seattlerb/minitest/issues/837 + # https://github.com/rails/rails/pull/39304 + it "deprecates expectation used without _ with empty backtrace_filter" do + skip "N/A" if ENV["MT_NO_EXPECTATIONS"] + + @assertion_count += 1 + @assertion_count += 2 unless error_on_warn? + + exp = /DEPRECATED: global use of must_equal from/ + + with_empty_backtrace_filter do + assert_deprecation exp do + (1 + 1).must_equal 2 + end + end + end + end + + it "needs to verify throw" do + @assertion_count += 4 # 2 extra tests + + assert_nil expect { throw :blah }.must_throw(:blah) + assert_equal 42, expect { throw :blah, 42 }.must_throw(:blah) + + assert_triggered "Expected :blah to have been thrown." do + expect {}.must_throw :blah + end + + assert_triggered "Expected :blah to have been thrown, not :xxx." do + expect { throw :xxx }.must_throw :blah + end + + assert_triggered "msg.\nExpected :blah to have been thrown." do + expect {}.must_throw :blah, "msg" + end + + assert_triggered "msg.\nExpected :blah to have been thrown, not :xxx." do + expect { throw :xxx }.must_throw :blah, "msg" + end + end + + it "needs to verify types of objects" do + assert_success _(6 * 7).must_be_instance_of(Integer) + + exp = "Expected 42 to be an instance of String, not Integer." + + assert_triggered exp do + _(6 * 7).must_be_instance_of String + end + + assert_triggered "msg.\n#{exp}" do + _(6 * 7).must_be_instance_of String, "msg" + end + end + + it "needs to verify using any (negative) predicate" do + @assertion_count -= 1 # doesn"t take a message + + assert_success _("blah").wont_be(:empty?) + + assert_triggered "Expected \"\" to not be empty?." do + _("").wont_be :empty? + end + end + + it "needs to verify using any binary operator" do + @assertion_count -= 1 # no msg + + assert_success _(41).must_be(:<, 42) + + assert_triggered "Expected 42 to be < 41." do + _(42).must_be :<, 41 + end + end + + it "needs to verify using any predicate" do + @assertion_count -= 1 # no msg + + assert_success _("").must_be(:empty?) + + assert_triggered "Expected \"blah\" to be empty?." do + _("blah").must_be :empty? + end + end + + it "needs to verify using respond_to" do + assert_success _(42).must_respond_to(:+) + + assert_triggered "Expected 42 (Integer) to respond to #clear." do + _(42).must_respond_to :clear + end + + assert_triggered "msg.\nExpected 42 (Integer) to respond to #clear." do + _(42).must_respond_to :clear, "msg" + end + end +end + +describe Minitest::Spec, :let do + i_suck_and_my_tests_are_order_dependent! + + def _count + $let_count ||= 0 + end + + let :count do + $let_count += 1 + $let_count + end + + it "is evaluated once per example" do + _(_count).must_equal 0 + + _(count).must_equal 1 + _(count).must_equal 1 + + _(_count).must_equal 1 + end + + it "is REALLY evaluated once per example" do + _(_count).must_equal 1 + + _(count).must_equal 2 + _(count).must_equal 2 + + _(_count).must_equal 2 + end + + it 'raises an error if the name begins with "test"' do + expect { self.class.let(:test_value) { true } }.must_raise ArgumentError + end + + it "raises an error if the name shadows a normal instance method" do + expect { self.class.let(:message) { true } }.must_raise ArgumentError + end + + it "doesn't raise an error if it is just another let" do + v = proc do + describe :outer do + let :bar + describe :inner do + let :bar + end + end + :good + end.call + _(v).must_equal :good + end + + it "procs come after dont_flip" do + p = proc {} + assert_respond_to p, :call + _(p).must_respond_to :call + end +end + +describe Minitest::Spec, :subject do + attr_reader :subject_evaluation_count + + subject do + @subject_evaluation_count ||= 0 + @subject_evaluation_count += 1 + @subject_evaluation_count + end + + it "is evaluated once per example" do + _(subject).must_equal 1 + _(subject).must_equal 1 + _(subject_evaluation_count).must_equal 1 + end +end + +class TestMetaStatic < Minitest::Test + def assert_method_count expected, klass + assert_equal expected, klass.public_instance_methods.grep(/^test_/).count + end + + def test_children + Minitest::Spec.children.clear # prevents parallel run + + y = z = nil + x = describe "top-level thingy" do + y = describe "first thingy" do end + + it "top-level-it" do end + + z = describe "second thingy" do end + end + + assert_equal [x], Minitest::Spec.children + assert_equal [y, z], x.children + assert_equal [], y.children + assert_equal [], z.children + end + + def test_it_wont_remove_existing_child_test_methods + Minitest::Spec.children.clear # prevents parallel run + + inner = nil + outer = describe "outer" do + inner = describe "inner" do + it do + assert true + end + end + it do + assert true + end + end + + assert_method_count 1, outer + assert_method_count 1, inner + end + + def test_it_wont_add_test_methods_to_children + Minitest::Spec.children.clear # prevents parallel run + + inner = nil + outer = describe "outer" do + inner = describe "inner" do end + it do + assert true + end + end + + assert_method_count 1, outer + assert_method_count 0, inner + end +end + +class TestMeta < MetaMetaMetaTestCase + # do not call parallelize_me! here because specs use register_spec_type globally + + def assert_defined_methods expected, klass + assert_equal expected, klass.instance_methods(false).sort.map(&:to_s) + end + + def util_structure + y = z = nil + before_list = [] + after_list = [] + x = describe "top-level thingy" do + before { before_list << 1 } + after { after_list << 1 } + + it "top-level-it" do end + + y = describe "inner thingy" do + before { before_list << 2 } + after { after_list << 2 } + it "inner-it" do end + + z = describe "very inner thingy" do + before { before_list << 3 } + after { after_list << 3 } + it "inner-it" do end + + it { } # ignore me + specify { } # anonymous it + end + end + end + + return x, y, z, before_list, after_list + end + + def test_register_spec_type + original_types = Minitest::Spec::TYPES.dup + + assert_includes Minitest::Spec::TYPES, [//, Minitest::Spec] + + Minitest::Spec.register_spec_type(/woot/, TestMeta) + + p = lambda do |_| true end + Minitest::Spec.register_spec_type TestMeta, &p + + keys = Minitest::Spec::TYPES.map(&:first) + + assert_includes keys, /woot/ + assert_includes keys, p + ensure + Minitest::Spec::TYPES.replace original_types + end + + def test_spec_type + original_types = Minitest::Spec::TYPES.dup + + Minitest::Spec.register_spec_type(/A$/, MiniSpecA) + Minitest::Spec.register_spec_type MiniSpecB do |desc| + desc.superclass == ExampleA + end + Minitest::Spec.register_spec_type MiniSpecC do |_desc, *addl| + addl.include? :woot + end + + assert_equal MiniSpecA, Minitest::Spec.spec_type(ExampleA) + assert_equal MiniSpecB, Minitest::Spec.spec_type(ExampleB) + assert_equal MiniSpecC, Minitest::Spec.spec_type(ExampleB, :woot) + ensure + Minitest::Spec::TYPES.replace original_types + end + + def test_bug_dsl_expectations + spec_class = Class.new MiniSpecB do + it "should work" do + _(0).must_equal 0 + end + end + + test_name = spec_class.instance_methods.sort.grep(/test_/).first + + spec = spec_class.new test_name + + result = spec.run + + assert spec.passed? + assert result.passed? + assert_equal 1, result.assertions + end + + def test_name + spec_a = describe ExampleA do; end + spec_b = describe ExampleB, :random_method do; end + spec_c = describe ExampleB, :random_method, :addl_context do; end + + assert_equal "ExampleA", spec_a.name + assert_equal "ExampleB::random_method", spec_b.name + assert_equal "ExampleB::random_method::addl_context", spec_c.name + end + + def test_name2 + assert_equal "NamedExampleA", NamedExampleA.name + assert_equal "NamedExampleB", NamedExampleB.name + assert_equal "NamedExampleC", NamedExampleC.name + + spec_a = describe ExampleA do; end + spec_b = describe ExampleB, :random_method do; end + + assert_equal "ExampleA", spec_a.name + assert_equal "ExampleB::random_method", spec_b.name + end + + def test_name_inside_class + spec_a = nil + spec_b = nil + inside_class_example = Class.new Minitest::Spec + Object.const_set :InsideClassExample, inside_class_example + inside_class_example.class_eval do + spec_a = describe "a" do + spec_b = describe "b" do; end + end + end + + assert_equal "InsideClassExample::a", spec_a.name + assert_equal "InsideClassExample::a::b", spec_b.name + ensure + Object.send :remove_const, :InsideClassExample + end + + def test_structure + x, y, z, * = util_structure + + assert_equal "top-level thingy", x.to_s + assert_equal "top-level thingy::inner thingy", y.to_s + assert_equal "top-level thingy::inner thingy::very inner thingy", z.to_s + + assert_equal "top-level thingy", x.desc + assert_equal "inner thingy", y.desc + assert_equal "very inner thingy", z.desc + + top_methods = %w[setup teardown test_0001_top-level-it] + inner_methods1 = %w[setup teardown test_0001_inner-it] + inner_methods2 = inner_methods1 + + %w[test_0002_anonymous test_0003_anonymous] + + assert_defined_methods top_methods, x + assert_defined_methods inner_methods1, y + assert_defined_methods inner_methods2, z + end + + def test_structure_postfix_it + z = nil + y = describe "outer" do + # NOT here, below the inner-describe! + # it "inner-it" do end + + z = describe "inner" do + it "inner-it" do end + end + + # defined AFTER inner describe means we'll try to wipe out the inner-it + it "inner-it" do end + end + + assert_defined_methods %w[test_0001_inner-it], y + assert_defined_methods %w[test_0001_inner-it], z + end + + def test_setup_teardown_behavior + _, _, z, before_list, after_list = util_structure + + @tu = z + + run_tu_with_fresh_reporter + + size = z.runnable_methods.size + assert_equal [1, 2, 3] * size, before_list + assert_equal [3, 2, 1] * size, after_list + end + + def test_describe_first_structure + x1 = x2 = y = z = nil + x = describe "top-level thingy" do + y = describe "first thingy" do end + + x1 = it "top level it" do end + x2 = it "не латинские &いった α, β, γ, δ, ε hello!!! world" do end + + z = describe "second thingy" do end + end + + test_methods = [ + "test_0001_top level it", + "test_0002_не латинские &いった α, β, γ, δ, ε hello!!! world", + ].sort + + assert_equal test_methods, [x1, x2] + assert_defined_methods test_methods, x + assert_defined_methods [], y + assert_defined_methods [], z + end + + def test_structure_subclasses + z = nil + x = Class.new Minitest::Spec do + def xyz; end + end + y = Class.new x do + z = describe("inner") { } + end + + assert_respond_to x.new(nil), "xyz" + assert_respond_to y.new(nil), "xyz" + assert_respond_to z.new(nil), "xyz" + end +end + +class TestSpecInTestCase < MetaMetaMetaTestCase + def setup + super + + Thread.current[:current_spec] = self + @tc = self + @assertion_count = 2 + end + + def assert_triggered expected, klass = Minitest::Assertion + @assertion_count += 1 + + e = assert_raises klass do + yield + end + + msg = e.message.sub(/(---Backtrace---).*/m, "\1") + msg.gsub!(/\(oid=[-0-9]+\)/, "(oid=N)") + + assert_equal expected, msg + end + + def teardown + msg = "expected #{@assertion_count} assertions, not #{@tc.assertions}" + assert_equal @assertion_count, @tc.assertions, msg + end + + def test_expectation + @tc.assert_equal true, _(1).must_equal(1) + end + + def test_expectation_triggered + assert_triggered "Expected: 2\n Actual: 1" do + _(1).must_equal 2 + end + end + + include Minitest::Spec::DSL::InstanceMethods + + def test_expectation_with_a_message + assert_triggered "woot.\nExpected: 2\n Actual: 1" do + _(1).must_equal 2, "woot" + end + end +end + +class ValueMonadTest < Minitest::Test + attr_accessor :struct + + def setup + @struct = { :_ => "a", :value => "b", :expect => "c" } + def @struct.method_missing k # think openstruct + self[k] + end + end + + def test_value_monad_method + assert_equal "a", struct._ + end + + def test_value_monad_value_alias + assert_equal "b", struct.value + end + + def test_value_monad_expect_alias + assert_equal "c", struct.expect + end +end + +describe Minitest::Spec, :infect_an_assertion do + class << self + attr_accessor :infect_mock + end + + def assert_infects exp, act, msg = nil, foo: nil, bar: nil + self.class.infect_mock.assert_infects exp, act, msg, foo: foo, bar: bar + end + + infect_an_assertion :assert_infects, :must_infect + infect_an_assertion :assert_infects, :must_infect_without_flipping, :dont_flip + + it "infects assertions with kwargs" do + mock = Minitest::Mock.new + mock.expect :assert_infects, true, [:exp, :act, nil], foo: :foo, bar: :bar + + self.class.infect_mock = mock + + _(:act).must_infect :exp, foo: :foo, bar: :bar + + assert_mock mock + end + + it "infects assertions with kwargs (dont_flip)" do + mock = Minitest::Mock.new + mock.expect :assert_infects, true, [:act, :exp, nil], foo: :foo, bar: :bar + + self.class.infect_mock = mock + + _(:act).must_infect_without_flipping :exp, foo: :foo, bar: :bar + + assert_mock mock + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/test/minitest/test_minitest_test.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/test/minitest/test_minitest_test.rb new file mode 100644 index 00000000..77b5219c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/test/minitest/test_minitest_test.rb @@ -0,0 +1,1374 @@ +require "minitest/metametameta" + +e = Encoding.default_external +if e != Encoding::UTF_8 then + warn "" + warn "" + warn "NOTE: External encoding #{e} is not UTF-8. Tests WILL fail." + warn " Run tests with `RUBYOPT=-Eutf-8 rake` to avoid errors." + warn "" + warn "" +end + +class Minitest::Runnable + attr_reader :gc_stats # only needed if running w/ minitest-gcstats + + def whatever # faked for testing + assert true + end +end + +class TestMinitestUnit < MetaMetaMetaTestCase + parallelize_me! + + MINITEST_BASE_DIR = "./lib/minitest/mini" + BT_MIDDLE = ["#{MINITEST_BASE_DIR}/test.rb:161:in 'each'", + "#{MINITEST_BASE_DIR}/test.rb:158:in 'each'", + "#{MINITEST_BASE_DIR}/test.rb:139:in 'run'", + "#{MINITEST_BASE_DIR}/test.rb:106:in 'run'"] + + def test_filter_backtrace + # this is a semi-lame mix of relative paths. + # I cheated by making the autotest parts not have ./ + bt = (["lib/autotest.rb:571:in 'add_exception'", + "test/test_autotest.rb:62:in 'test_add_exception'", + "#{MINITEST_BASE_DIR}/test.rb:165:in '__send__'"] + + BT_MIDDLE + + ["#{MINITEST_BASE_DIR}/test.rb:29", + "test/test_autotest.rb:422"]) + bt = util_expand_bt bt + + ex = ["lib/autotest.rb:571:in 'add_exception'", + "test/test_autotest.rb:62:in 'test_add_exception'"] + ex = util_expand_bt ex + + Minitest::Test.io_lock.synchronize do # try not to trounce in parallel + fu = Minitest.filter_backtrace bt + + assert_equal ex, fu + end + end + + def test_filter_backtrace_all_unit + bt = (["#{MINITEST_BASE_DIR}/test.rb:165:in '__send__'"] + + BT_MIDDLE + + ["#{MINITEST_BASE_DIR}/test.rb:29"]) + ex = bt.clone + fu = Minitest.filter_backtrace bt + assert_equal ex, fu + end + + def test_filter_backtrace_unit_starts + bt = (["#{MINITEST_BASE_DIR}/test.rb:165:in '__send__'"] + + BT_MIDDLE + + ["#{MINITEST_BASE_DIR}/mini/test.rb:29", + "-e:1"]) + + bt = util_expand_bt bt + + ex = ["-e:1"] + Minitest::Test.io_lock.synchronize do # try not to trounce in parallel + fu = Minitest.filter_backtrace bt + assert_equal ex, fu + end + end + + def test_filter_backtrace__empty + with_empty_backtrace_filter do + bt = %w[first second third] + fu = Minitest.filter_backtrace bt.dup + assert_equal bt, fu + end + end + + def test_infectious_binary_encoding + @tu = Class.new FakeNamedTest do + def test_this_is_not_ascii_assertion + assert_equal "ЁЁЁ", "ёёё" + end + + def test_this_is_non_ascii_failure_message + raise "ЁЁЁ".dup.force_encoding(Encoding::BINARY) + end + end + + expected = <<~EOM + FE + + Finished in 0.00 + + 1) Failure: + FakeNamedTestXX#test_this_is_not_ascii_assertion [FILE:LINE]: + Expected: "ЁЁЁ" + Actual: "ёёё" + + 2) Error: + FakeNamedTestXX#test_this_is_non_ascii_failure_message: + RuntimeError: ЁЁЁ + FILE:LINE:in 'test_this_is_non_ascii_failure_message' + + 2 runs, 1 assertions, 1 failures, 1 errors, 0 skips + EOM + + Minitest::Test.io_lock.synchronize do # try not to trounce in parallel + assert_report expected + end + end + + def test_passed_eh_teardown_good + test_class = Class.new FakeNamedTest do + def teardown; assert true; end + def test_omg; assert true; end + end + + test = test_class.new :test_omg + test.run + + refute_predicate test, :error? + assert_predicate test, :passed? + refute_predicate test, :skipped? + end + + def test_passed_eh_teardown_skipped + test_class = Class.new FakeNamedTest do + def teardown; assert true; end + def test_omg; skip "bork"; end + end + + test = test_class.new :test_omg + test.run + + refute_predicate test, :error? + refute_predicate test, :passed? + assert_predicate test, :skipped? + end + + def test_passed_eh_teardown_flunked + test_class = Class.new FakeNamedTest do + def teardown; flunk; end + def test_omg; assert true; end + end + + test = test_class.new :test_omg + test.run + + refute_predicate test, :error? + refute_predicate test, :passed? + refute_predicate test, :skipped? + end + + def test_skipped_is_reachable + test_class = Class.new FakeNamedTest do + def test_omg + skip + ensure + flunk unless skipped? + end + end + + test = test_class.new :test_omg + test.run + + refute_predicate test, :error? + refute_predicate test, :passed? + + assert_predicate test, :skipped? + end + + def util_expand_bt bt + bt.map { |f| f.start_with?(".") ? File.expand_path(f) : f } + end +end + +class TestMinitestUnitInherited < MetaMetaMetaTestCase + def with_overridden_include + Class.class_eval do + def inherited_with_hacks _klass + throw :inherited_hook + end + + alias inherited_without_hacks inherited + alias inherited inherited_with_hacks + alias IGNORE_ME! inherited # 1.8 bug. god I love venture bros + end + + yield + ensure + Class.class_eval do + alias inherited inherited_without_hacks + + undef_method :inherited_with_hacks + undef_method :inherited_without_hacks + end + + refute_respond_to Class, :inherited_with_hacks + refute_respond_to Class, :inherited_without_hacks + end + + def test_inherited_hook_plays_nice_with_others + with_overridden_include do + assert_throws :inherited_hook do + Class.new FakeNamedTest + end + end + end +end + +class TestMinitestRunner < MetaMetaMetaTestCase + # do not parallelize this suite... it just can't handle it. + + def test_class_runnables + @assertion_count = 0 + + tc = Class.new Minitest::Test + + assert_equal 1, Minitest::Test.runnables.size + assert_equal [tc], Minitest::Test.runnables + end + + def test_run_test + @tu = Class.new FakeNamedTest do + attr_reader :foo + + def run + @foo = "hi mom!" + r = super + @foo = "okay" + + r + end + + def test_something + assert_equal "hi mom!", foo + end + end + + expected = <<~EOM + . + + Finished in 0.00 + + 1 runs, 1 assertions, 0 failures, 0 errors, 0 skips + EOM + + assert_report expected + end + + def test_run_error + @tu = Class.new FakeNamedTest do + def test_something + assert true + end + + def test_error + raise "unhandled exception" + end + end + + expected = <<~EOM + .E + + Finished in 0.00 + + 1) Error: + FakeNamedTestXX#test_error: + RuntimeError: unhandled exception + FILE:LINE:in 'test_error' + + 2 runs, 1 assertions, 0 failures, 1 errors, 0 skips + EOM + + assert_report expected + end + + def test_run_error_teardown + @tu = Class.new FakeNamedTest do + def test_something + assert true + end + + def teardown + raise "unhandled exception" + end + end + + expected = <<~EOM + E + + Finished in 0.00 + + 1) Error: + FakeNamedTestXX#test_something: + RuntimeError: unhandled exception + FILE:LINE:in 'teardown' + + 1 runs, 1 assertions, 0 failures, 1 errors, 0 skips + EOM + + assert_report expected + end + + def test_run_failing + setup_basic_tu + + expected = <<~EOM + .F + + Finished in 0.00 + + 1) Failure: + FakeNamedTestXX#test_failure [FILE:LINE]: + Expected false to be truthy. + + 2 runs, 2 assertions, 1 failures, 0 errors, 0 skips + EOM + + assert_report expected + end + + def setup_basic_tu + @tu = Class.new FakeNamedTest do + def test_something + assert true + end + + def test_failure + assert false + end + end + end + + def test_seed # this is set for THIS run, so I'm not testing it's actual value + assert_instance_of Integer, Minitest.seed + end + + def test_run_failing_filtered + setup_basic_tu + + expected = <<~EOM + . + + Finished in 0.00 + + 1 runs, 1 assertions, 0 failures, 0 errors, 0 skips + EOM + + assert_report expected, %w[--name /some|thing/ --seed 42] + end + + def assert_filtering filter, name, expected, a = false + args = %W[--#{filter} #{name} --seed 42] + + alpha = Class.new FakeNamedTest do + define_method :test_something do + assert a + end + end + Object.const_set :Alpha, alpha + + beta = Class.new FakeNamedTest do + define_method :test_something do + assert true + end + end + Object.const_set :Beta, beta + + @tus = [alpha, beta] + + assert_report expected, args + ensure + Object.send :remove_const, :Alpha + Object.send :remove_const, :Beta + end + + def test_run_filtered_including_suite_name + expected = <<~EOM + . + + Finished in 0.00 + + 1 runs, 1 assertions, 0 failures, 0 errors, 0 skips + EOM + + assert_filtering "name", "/Beta#test_something/", expected + end + + def test_run_filtered_including_suite_name_string + expected = <<~EOM + . + + Finished in 0.00 + + 1 runs, 1 assertions, 0 failures, 0 errors, 0 skips + EOM + + assert_filtering "name", "Beta#test_something", expected + end + + def test_run_filtered_string_method_only + expected = <<~EOM + .. + + Finished in 0.00 + + 2 runs, 2 assertions, 0 failures, 0 errors, 0 skips + EOM + + assert_filtering "name", "test_something", expected, :pass + end + + def test_run_failing_excluded + setup_basic_tu + + expected = <<~EOM + . + + Finished in 0.00 + + 1 runs, 1 assertions, 0 failures, 0 errors, 0 skips + EOM + + assert_report expected, %w[--exclude /failure/ --seed 42] + end + + def test_run_filtered_excluding_suite_name + expected = <<~EOM + . + + Finished in 0.00 + + 1 runs, 1 assertions, 0 failures, 0 errors, 0 skips + EOM + + assert_filtering "exclude", "/Alpha#test_something/", expected + end + + def test_run_filtered_excluding_suite_name_string + expected = <<~EOM + . + + Finished in 0.00 + + 1 runs, 1 assertions, 0 failures, 0 errors, 0 skips + EOM + + assert_filtering "exclude", "Alpha#test_something", expected + end + + def test_run_filtered_excluding_string_method_only + expected = <<~EOM + + + Finished in 0.00 + + 0 runs, 0 assertions, 0 failures, 0 errors, 0 skips + EOM + + assert_filtering "exclude", "test_something", expected, :pass + end + + def test_run_passing + @tu = Class.new FakeNamedTest do + def test_something + assert true + end + end + + expected = <<~EOM + . + + Finished in 0.00 + + 1 runs, 1 assertions, 0 failures, 0 errors, 0 skips + EOM + + assert_report expected + end + + def test_run_skip + @tu = Class.new FakeNamedTest do + def test_something + assert true + end + + def test_skip + skip "not yet" + end + end + + expected = <<~EOM + .S + + Finished in 0.00 + + 2 runs, 1 assertions, 0 failures, 0 errors, 1 skips + + You have skipped tests. Run with --verbose for details. + EOM + + restore_env do + assert_report expected + end + end + + def test_run_skip_verbose + @tu = Class.new FakeNamedTest do + def test_something + assert true + end + + def test_skip + skip "not yet" + end + end + + expected = <<~EOM + FakeNamedTestXX#test_something = 0.00 s = . + FakeNamedTestXX#test_skip = 0.00 s = S + + Finished in 0.00 + + 1) Skipped: + FakeNamedTestXX#test_skip [FILE:LINE]: + not yet + + 2 runs, 1 assertions, 0 failures, 0 errors, 1 skips + EOM + + assert_report expected, %w[--seed 42 --verbose] + end + + def test_run_skip_show_skips + @tu = Class.new FakeNamedTest do + def test_something + assert true + end + + def test_skip + skip "not yet" + end + end + + expected = <<~EOM + .S + + Finished in 0.00 + + 1) Skipped: + FakeNamedTestXX#test_skip [FILE:LINE]: + not yet + + 2 runs, 1 assertions, 0 failures, 0 errors, 1 skips + EOM + + assert_report expected, %w[--seed 42 --show-skips] + end + + def test_run_with_other_runner + @tu = Class.new FakeNamedTest do + def self.run reporter, options = {} + @reporter = reporter + before_my_suite + super + end + + def self.name; "wacky!" end + + def self.before_my_suite + @reporter.io.puts "Running #{self.name} tests" + @@foo = 1 + end + + def test_something + assert_equal 1, @@foo + end + + def test_something_else + assert_equal 1, @@foo + end + end + + expected = <<~EOM + Running wacky! tests + .. + + Finished in 0.00 + + 2 runs, 2 assertions, 0 failures, 0 errors, 0 skips + EOM + + assert_report expected + end + + require "monitor" + + class Latch + def initialize count = 1 + @count = count + @lock = Monitor.new + @cv = @lock.new_cond + end + + def release + @lock.synchronize do + @count -= 1 if @count > 0 + @cv.broadcast if @count == 0 + end + end + + def await + @lock.synchronize { @cv.wait_while { @count > 0 } } + end + end + + def test_run_parallel + test_count = 2 + test_latch = Latch.new test_count + wait_latch = Latch.new test_count + main_latch = Latch.new + + thread = Thread.new { + Thread.current.abort_on_exception = true + + # This latch waits until both test latches have been released. Both + # latches can't be released unless done in separate threads because + # `main_latch` keeps the test method from finishing. + test_latch.await + main_latch.release + } + + @tu = Class.new FakeNamedTest do + parallelize_me! + + test_count.times do |i| + define_method :"test_wait_on_main_thread_#{i}" do + test_latch.release + + # This latch blocks until the "main thread" releases it. The main + # thread can't release this latch until both test latches have + # been released. This forces the latches to be released in separate + # threads. + main_latch.await + assert true + end + end + end + + expected = <<~EOM + .. + + Finished in 0.00 + + 2 runs, 2 assertions, 0 failures, 0 errors, 0 skips + EOM + + skip if Minitest.parallel_executor.size < 2 # locks up test runner if 1 CPU + + assert_report expected do |reporter| + reporter.extend Module.new { + define_method :record do |result| + super(result) + wait_latch.release + end + + define_method :report do + wait_latch.await + super() + end + } + end + assert thread.join + end +end + +class TestMinitestUnitOrder < MetaMetaMetaTestCase + # do not parallelize this suite... it just can't handle it. + + def test_before_setup + call_order = [] + + @tu = Class.new FakeNamedTest do + define_method :setup do + super() + call_order << :setup + end + + define_method :before_setup do + call_order << :before_setup + end + + def test_omg; assert true; end + end + + run_tu_with_fresh_reporter + + expected = %i[before_setup setup] + assert_equal expected, call_order + end + + def test_after_teardown + call_order = [] + @tu = Class.new FakeNamedTest do + define_method :teardown do + super() + call_order << :teardown + end + + define_method :after_teardown do + call_order << :after_teardown + end + + def test_omg; assert true; end + end + + run_tu_with_fresh_reporter + + expected = %i[teardown after_teardown] + assert_equal expected, call_order + end + + def test_all_teardowns_are_guaranteed_to_run + call_order = [] + + @tu = Class.new FakeNamedTest do + define_method :after_teardown do + super() + call_order << :after_teardown + raise + end + + define_method :teardown do + super() + call_order << :teardown + raise + end + + define_method :before_teardown do + super() + call_order << :before_teardown + raise + end + + def test_omg; assert true; end + end + + run_tu_with_fresh_reporter + + expected = %i[before_teardown teardown after_teardown] + assert_equal expected, call_order + end + + def test_setup_and_teardown_survive_inheritance + call_order = [] + + @tu = Class.new FakeNamedTest do + define_method :setup do + call_order << :setup_method + end + + define_method :teardown do + call_order << :teardown_method + end + + define_method :test_something do + call_order << :test + end + end + + run_tu_with_fresh_reporter + + @tu = Class.new @tu + run_tu_with_fresh_reporter + + # Once for the parent class, once for the child + expected = %i[setup_method test teardown_method] * 2 + + assert_equal expected, call_order + end +end + +class BetterError < RuntimeError # like better_error w/o infecting RuntimeError + def set_backtrace bt + super + @bad_ivar = binding + end +end + +class TestMinitestRunnable < Minitest::Test + def setup_marshal klass + tc = klass.new "whatever" + tc.assertions = 42 + tc.failures << "a failure" + + yield tc if block_given? + + def tc.setup + @blah = "blah" + end + tc.setup + + @tc = Minitest::Result.from tc + end + + def assert_marshal expected_ivars + new_tc = Marshal.load Marshal.dump @tc + + ivars = new_tc.instance_variables.map(&:to_s).sort + ivars.delete "@gc_stats" # only needed if running w/ minitest-gcstats + assert_equal expected_ivars, ivars + assert_equal "whatever", new_tc.name + assert_equal 42, new_tc.assertions + assert_equal ["a failure"], new_tc.failures + + yield new_tc if block_given? + end + + def test_marshal + setup_marshal Minitest::Runnable + + assert_marshal %w[@NAME @assertions @failures @klass @source_location @time] + end + + def test_spec_marshal + klass = describe("whatever") { it("passes") { assert true } } + rm = klass.runnable_methods.first + + # Run the test + @tc = klass.new(rm).run + + assert_kind_of Minitest::Result, @tc + + # Pass it over the wire + over_the_wire = Marshal.load Marshal.dump @tc + + assert_equal @tc.time, over_the_wire.time + assert_equal @tc.name, over_the_wire.name + assert_equal @tc.assertions, over_the_wire.assertions + assert_equal @tc.failures, over_the_wire.failures + assert_equal @tc.klass, over_the_wire.klass + end + + def test_spec_marshal_with_exception + klass = describe("whatever") { + it("raises, badly") { + raise Class.new(StandardError), "this is bad!" + } + } + + rm = klass.runnable_methods.first + + # Run the test + @tc = klass.new(rm).run + + assert_kind_of Minitest::Result, @tc + assert_instance_of Minitest::UnexpectedError, @tc.failure + + msg = @tc.failure.error.message + assert_includes msg, "Neutered Exception #: boom", msg + + # Pass it over the wire + over_the_wire = Marshal.load Marshal.dump @tc + + assert_equal @tc.time, over_the_wire.time + assert_equal @tc.name, over_the_wire.name + assert_equal @tc.assertions, over_the_wire.assertions + assert_equal @tc.failures, over_the_wire.failures + assert_equal @tc.klass, over_the_wire.klass + end +end + +class TestMinitestTest < TestMinitestRunnable + def test_dup + setup_marshal Minitest::Test do |tc| + tc.time = 3.14 + end + + assert_marshal %w[@NAME @assertions @failures @klass @source_location @time] do |new_tc| + assert_in_epsilon 3.14, new_tc.time + end + end +end + +class TestMinitestUnitTestCase < Minitest::Test + # do not call parallelize_me! - teardown accesses @tc._assertions + # which is not threadsafe. Nearly every method in here is an + # assertion test so it isn't worth splitting it out further. + + def setup + super + + Minitest::Test.reset + + @tc = Minitest::Test.new "fake tc" + @zomg = "zomg ponies!" + @assertion_count = 1 + end + + def teardown + assert_equal(@assertion_count, @tc.assertions, + "expected #{@assertion_count} assertions to be fired during the test, not #{@tc.assertions}") if @tc.passed? + end + + def non_verbose + orig_verbose = $VERBOSE + $VERBOSE = false + + yield + ensure + $VERBOSE = orig_verbose + end + + def sample_test_case rand + srand rand + Class.new FakeNamedTest do + 100.times do |i| + define_method("test_#{i}") { assert true } + end + end.runnable_methods + end + + # srand varies with OS + def test_runnable_methods_random + @assertion_count = 0 + + random_tests_1 = sample_test_case 42 + random_tests_2 = sample_test_case 42 + random_tests_3 = sample_test_case 1_000 + + assert_equal random_tests_1, random_tests_2 + assert_equal random_tests_1, random_tests_3 + end + + def test_runnable_methods_sorted + @assertion_count = 0 + + sample_test_case = Class.new FakeNamedTest do + def self.test_order; :sorted end + def test_test3; assert "does not matter" end + def test_test2; assert "does not matter" end + def test_test1; assert "does not matter" end + end + + expected = %w[test_test1 test_test2 test_test3] + assert_equal expected, sample_test_case.runnable_methods + end + + def test_i_suck_and_my_tests_are_order_dependent_bang_sets_test_order_alpha + @assertion_count = 0 + + shitty_test_case = Class.new FakeNamedTest + + shitty_test_case.i_suck_and_my_tests_are_order_dependent! + + assert_equal :alpha, shitty_test_case.test_order + end + + def test_i_suck_and_my_tests_are_order_dependent_bang_does_not_warn + @assertion_count = 0 + + shitty_test_case = Class.new FakeNamedTest + + def shitty_test_case.test_order; :lol end + + assert_silent do + shitty_test_case.i_suck_and_my_tests_are_order_dependent! + end + end + + def test_autorun_does_not_affect_fork_success_status + @assertion_count = 0 + skip "windows doesn't have fork" unless Process.respond_to? :fork + Process.waitpid(fork {}) + assert_equal true, $?.success? + end + + def test_autorun_does_not_affect_fork_exit_status + @assertion_count = 0 + skip "windows doesn't have fork" unless Process.respond_to? :fork + Process.waitpid(fork { exit 42 }) + assert_equal 42, $?.exitstatus + end + + def test_autorun_optionally_can_affect_fork_exit_status + @assertion_count = 0 + skip "windows doesn't have fork" unless Process.respond_to? :fork + Minitest.allow_fork = true + Process.waitpid(fork { exit 42 }) + refute_equal 42, $?.exitstatus + ensure + Minitest.allow_fork = false + end +end + +class TestMinitestGuard < Minitest::Test + parallelize_me! + + def test_mri_eh + assert self.class.mri? "ruby blah" + assert self.mri? "ruby blah" + end + + def test_jruby_eh + assert self.class.jruby? "java" + assert self.jruby? "java" + end + + def test_rubinius_eh + assert_deprecation do + assert self.class.rubinius? "rbx" + end + assert_deprecation do + assert self.rubinius? "rbx" + end + end + + def test_maglev_eh + assert_deprecation do + assert self.class.maglev? "maglev" + end + assert_deprecation do + assert self.maglev? "maglev" + end + end + + def test_osx_eh + assert self.class.osx? "darwin" + assert self.osx? "darwin" + end + + def test_windows_eh + assert self.class.windows? "mswin" + assert self.windows? "mswin" + end +end + +class TestMinitestUnitRecording < MetaMetaMetaTestCase + # do not parallelize this suite... it just can't handle it. + + def assert_run_record *expected, &block + @tu = Class.new FakeNamedTest, &block + + run_tu_with_fresh_reporter + + recorded = first_reporter.results.map(&:failures).flatten.map { |f| f.error.class } + + assert_equal expected, recorded + end + + def test_run_with_bogus_reporter + # https://github.com/seattlerb/minitest/issues/659 + # TODO: remove test for minitest 6 + @tu = Class.new FakeNamedTest do + def test_method + assert true + end + end + + bogus_reporter = Class.new do # doesn't subclass AbstractReporter + def start; @success = false; end + # def prerecord klass, name; end # doesn't define full API + def record _result; @success = true; end + def report; end + def passed?; end + def results; end + def success?; @success; end + end.new + + self.reporter = Minitest::CompositeReporter.new + reporter << bogus_reporter + + Minitest::Runnable.runnables.delete @tu + + @tu.run reporter, {} + + assert_predicate bogus_reporter, :success? + end + + def test_record_passing + assert_run_record do + def test_method + assert true + end + end + end + + def test_record_failing + assert_run_record Minitest::Assertion do + def test_method + assert false + end + end + end + + def test_record_error + assert_run_record RuntimeError do + def test_method + raise "unhandled exception" + end + end + end + + def test_record_error_teardown + assert_run_record RuntimeError do + def test_method + assert true + end + + def teardown + raise "unhandled exception" + end + end + end + + def test_record_error_in_test_and_teardown + assert_run_record AnError, RuntimeError do + def test_method + raise AnError + end + + def teardown + raise "unhandled exception" + end + end + end + + def test_to_s_error_in_test_and_teardown + @tu = Class.new FakeNamedTest do + def test_method + raise AnError + end + + def teardown + raise "unhandled exception" + end + end + + run_tu_with_fresh_reporter + + exp = <<~EOM + Error: + FakeNamedTestXX#test_method: + AnError: AnError + FILE:LINE:in 'test_method' + + Error: + FakeNamedTestXX#test_method: + RuntimeError: unhandled exception + FILE:LINE:in 'teardown' + EOM + + assert_equal exp.strip, normalize_output(first_reporter.results.first.to_s).strip + end + + def test_record_skip + assert_run_record Minitest::Skip do + def test_method + skip "not yet" + end + end + end +end + +class TestUnexpectedError < Minitest::Test + def assert_compress exp, input + e = Minitest::UnexpectedError.new RuntimeError.new + + exp = exp.lines.map(&:chomp) if String === exp + act = e.compress input + + assert_equal exp, act + end + + ACT1 = %w[ a b c b c b c b c d ] + + def test_normal + assert_compress <<~EXP, %w[ a b c b c b c b c d ] + a + +->> 4 cycles of 2 lines: + | b + | c + +-<< + d + EXP + end + + def test_normal2 + assert_compress <<~EXP, %w[ a b c b c b c b c ] + a + +->> 4 cycles of 2 lines: + | b + | c + +-<< + EXP + end + + def test_longer_c_than_b + # the extra c in the front makes the overall length longer sorting it first + assert_compress <<~EXP, %w[ c a b c b c b c b c b d ] + c + a + b + +->> 4 cycles of 2 lines: + | c + | b + +-<< + d + EXP + end + + def test_1_line_cycles + assert_compress <<~EXP, %w[ c a b c b c b c b c b b b d ] + c + a + +->> 4 cycles of 2 lines: + | b + | c + +-<< + +->> 3 cycles of 1 lines: + | b + +-<< + d + EXP + end + + def test_sanity3 + pre = ("aa".."am").to_a + mid = ("a".."z").to_a * 67 + post = ("aa".."am").to_a + ary = pre + mid + post + + exp = pre + + [" +->> 67 cycles of 26 lines:"] + + ("a".."z").map { |s| " | #{s}" } + + [" +-<<"] + + post + + assert_compress exp, ary + end + + def test_absurd_patterns + assert_compress <<~EXP, %w[ a b c b c a b c b c a b c ] + +->> 2 cycles of 5 lines: + | a + | +->> 2 cycles of 2 lines: + | | b + | | c + | +-<< + +-<< + a + b + c + EXP + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/test/minitest/test_minitest_test_task.rb b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/test/minitest/test_minitest_test_task.rb new file mode 100644 index 00000000..58902f58 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/minitest-5.25.5/test/minitest/test_minitest_test_task.rb @@ -0,0 +1,57 @@ +require "minitest/autorun" + +begin + require "hoe" +rescue LoadError => e + warn e.message + return +end + +require "minitest/test_task" + +Hoe.load_plugins # make sure Hoe::Test is loaded + +class TestHoeTest < Minitest::Test + PATH = "test/minitest/test_minitest_test_task.rb" + + def util_cmd_string *prelude_framework + mt_path = %w[lib test .].join File::PATH_SEPARATOR + mt_expected = "-I%s -w -e '%srequire %p' -- " + + mt_expected % [mt_path, prelude_framework.join("; "), PATH] + end + + def util_exp_cmd + @tester.make_test_cmd.sub(/ -- .+/, " -- ") + end + + def test_make_test_cmd_for_minitest + skip "Using TESTOPTS... skipping" if ENV["TESTOPTS"] + + require "minitest/test_task" + + framework = %(require "minitest/autorun"; ) + + @tester = Minitest::TestTask.create :test do |t| + t.test_globs = [PATH] + end + + assert_equal util_cmd_string(framework), util_exp_cmd + end + + def test_make_test_cmd_for_minitest_prelude + skip "Using TESTOPTS... skipping" if ENV["TESTOPTS"] + + require "minitest/test_task" + + prelude = %(require "other/file") + framework = %(require "minitest/autorun"; ) + + @tester = Minitest::TestTask.create :test do |t| + t.test_prelude = prelude + t.test_globs = [PATH] + end + + assert_equal util_cmd_string(prelude, framework), util_exp_cmd + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/LICENSE b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/LICENSE new file mode 100644 index 00000000..bc53b031 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/LICENSE @@ -0,0 +1,23 @@ +Copyright (c) 2013-2017 Konstantin Haase +Copyright (c) 2016-2017 Zachary Scott + +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 AUTHORS OR COPYRIGHT +HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/README.md b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/README.md new file mode 100644 index 00000000..64ab4120 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/README.md @@ -0,0 +1,830 @@ +# The Amazing Mustermann + +*Make sure you view the correct docs: [latest release](http://rubydoc.info/gems/mustermann/frames), [master](http://rubydoc.info/github/rkh/mustermann/master/frames).* + +Welcome to [Mustermann](http://en.wikipedia.org/wiki/List_of_placeholder_names_by_language#German). Mustermann is your personal string matching expert. As an expert in the field of strings and patterns, Mustermann keeps its runtime dependencies to a minimum and is fully covered with specs and documentation. + +Given a string pattern, Mustermann will turn it into an object that behaves like a regular expression and has comparable performance characteristics. + +``` ruby +if '/foo/bar' =~ Mustermann.new('/foo/*') + puts 'it works!' +end + +case 'something.png' +when Mustermann.new('foo/*') then puts "prefixed with foo" +when Mustermann.new('*.pdf') then puts "it's a PDF" +when Mustermann.new('*.png') then puts "it's an image" +end + +pattern = Mustermann.new('/:prefix/*.*') +pattern.params('/a/b.c') # => { "prefix" => "a", splat => ["b", "c"] } +``` + +## Overview + +### Features + +* **[Pattern Types](#-pattern-types):** Mustermann supports a wide variety of different pattern types, making it compatible with a large variety of existing software. +* **[Fine Grained Control](#-available-options):** You can easily adjust matching behavior and add constraints to the placeholders and capture groups. +* **[Binary Operators](#-binary-operators) and [Concatenation](#-concatenation):** Patterns can be combined into composite patterns using binary operators. +* **[Regexp Look Alike](#-regexp-look-alike):** Mustermann patterns can be used as a replacement for regular expressions. +* **[Parameter Parsing](#-parameter-parsing):** Mustermann can parse matched parameters into a Sinatra-style "params" hash, including type casting. +* **[Peeking](#-peeking):** Lets you check if the beginning of a string matches a pattern. +* **[Expanding](#-expanding):** Besides parsing a parameters from an input string, a pattern object can also be used to generate a string from a set of parameters. +* **[Generating Templates](#-generating-templates):** This comes in handy when wanting to hand on patterns rather than fully expanded strings as part of an external API. +* **[Proc Look Alike](#-proc-look-alike):** Pass on a pattern instead of a block. +* **[Duck Typing](#-duck-typing):** You can create your own pattern-like objects by implementing `to_pattern`. +* **[Performance](#-performance):** Patterns are implemented with both performance and a low memory footprint in mind. + +### Additional Tooling + +These features are included in the library, but not loaded by default + +* **[Mapper](#-mapper):** A simple tool for mapping one string to another based on patterns. +* **[Sinatra Integration](#-sinatra-integration):** Mustermann can be used as a [Sinatra](http://www.sinatrarb.com/) extension. Sinatra 2.0 and beyond will use Mustermann by default. + + +## Pattern Types + +Mustermann support multiple pattern types. A pattern type defines the syntax, matching semantics and whether certain features, like [expanding](#-expanding) and [generating templates](#-generating-templates), are available. + +You can create a pattern of a certain type by passing `type` option to `Mustermann.new`: + +``` ruby +require 'mustermann' +pattern = Mustermann.new('/*/**', type: :shell) +``` + +Note that this will use the type as suggestion: When passing in a string argument, it will create a pattern of the given type, but it might choose a different type for other objects (a regular expression argument will always result in a [regexp](#-pattern-details-regexp) pattern, a symbol always in a [sinatra](#-pattern-details-sinatra) pattern, etc). + +Alternatively, you can also load and instantiate the pattern type directly: + +``` ruby +require 'mustermann/shell' +pattern = Mustermann::Shell.new('/*/**') +``` + +Mustermann itself includes the [sinatra](#-sinatra-pattern), [identity](#-identity-pattern) and [regexp](#-regexp-pattern) pattern types. Other pattern types are available as separate gems. + + +## Binary Operators + +Patterns can be combined via binary operators. These are: + +* `|` (or): Resulting pattern matches if at least one of the input pattern matches. +* `&` (and): Resulting pattern matches if all input patterns match. +* `^` (xor): Resulting pattern matches if exactly one of the input pattern matches. + +``` ruby +require 'mustermann' + +first = Mustermann.new('/foo/:input') +second = Mustermann.new('/:input/bar') + +first | second === "/foo/foo" # => true +first | second === "/foo/bar" # => true + +first & second === "/foo/foo" # => false +first & second === "/foo/bar" # => true + +first ^ second === "/foo/foo" # => true +first ^ second === "/foo/bar" # => false +``` + +These resulting objects are fully functional pattern objects, allowing you to call methods like `params` or `to_proc` on them. Moreover, *or* patterns created solely from expandable patterns will also be expandable. The same logic also applies to generating templates from *or* patterns. + + +## Concatenation + +Similar to [Binary Operators](#-binary-operators), two patterns can be concatenated using `+`. + +``` ruby +require 'mustermann' + +prefix = Mustermann.new("/:prefix") +about = prefix + "/about" + +about.params("/main/about") # => {"prefix" => "main"} +``` + +Patterns of different types can be mixed. The availability of `to_templates` and `expand` depends on the patterns being concatenated. + + +## Regexp Look Alike + +Pattern objects mimic Ruby's `Regexp` class by implementing `match`, `=~`, `===`, `names` and `named_captures`. + +``` ruby +require 'mustermann' + +pattern = Mustermann.new('/:page') +pattern.match('/') # => nil +pattern.match('/home') # => # +pattern =~ '/home' # => 0 +pattern === '/home' # => true (this allows using it in case statements) +pattern.names # => ['page'] +pattern.names # => {"page"=>[1]} + +pattern = Mustermann.new('/home', type: :identity) +pattern.match('/') # => nil +pattern.match('/home') # => # +pattern =~ '/home' # => 0 +pattern === '/home' # => true (this allows using it in case statements) +pattern.names # => [] +pattern.names # => {} +``` + +Moreover, patterns based on regular expressions (all but `identity` and `shell`) automatically convert to regular expressions when needed: + +``` ruby +require 'mustermann' + +pattern = Mustermann.new('/:page') +union = Regexp.union(pattern, /^$/) + +union =~ "/foo" # => 0 +union =~ "" # => 0 + +Regexp.try_convert(pattern) # => /.../ +``` + +This way, unless some code explicitly checks the class for a regular expression, you should be able to pass in a pattern object instead even if the code in question was not written with Mustermann in mind. + + +## Parameter Parsing + +Besides being a `Regexp` look-alike, Mustermann also adds a `params` method, that will give you a Sinatra-style hash: + +``` ruby +require 'mustermann' + +pattern = Mustermann.new('/:prefix/*.*') +pattern.params('/a/b.c') # => { "prefix" => "a", splat => ["b", "c"] } +``` + +For patterns with typed captures, it will also automatically convert them: + +``` ruby +require 'mustermann' + +pattern = Mustermann.new('//', type: :flask) +pattern.params('/page/10') # => { "prefix" => "page", "id" => 10 } +``` + + +## Peeking + +Peeking gives the option to match a pattern against the beginning of a string rather the full string. Patterns come with four methods for peeking: + +* `peek` returns the matching substring. +* `peek_size` returns the number of characters matching. +* `peek_match` will return a `MatchData` or `Mustermann::SimpleMatch` (just like `match` does for the full string) +* `peek_params` will return the `params` hash parsed from the substring and the number of characters. + +All of the above will turn `nil` if there was no match. + +``` ruby +require 'mustermann' + +pattern = Mustermann.new('/:prefix') +pattern.peek('/foo/bar') # => '/foo' +pattern.peek_size('/foo/bar') # => 4 + +path_info = '/foo/bar' +params, size = patter.peek_params(path_info) # params == { "prefix" => "foo" } +rest = path_info[size..-1] # => "/bar" +``` + + +## Expanding + +Similarly to parsing, it is also possible to generate a string from a pattern by expanding it with a hash. +For simple expansions, you can use `Pattern#expand`. + +``` ruby +pattern = Mustermann.new('/:file(.:ext)?') +pattern.expand(file: 'pony') # => "/pony" +pattern.expand(file: 'pony', ext: 'jpg') # => "/pony.jpg" +pattern.expand(ext: 'jpg') # raises Mustermann::ExpandError +``` + +Expanding can be useful for instance when implementing link helpers. + +### Expander Objects + +To get fine-grained control over expansion, you can use `Mustermann::Expander` directly. + +You can create an expander object directly from a string: + +``` ruby +require 'mustermann/expander' +expander = Mustermann::Expander("/:file.jpg") +expander.expand(file: 'pony') # => "/pony.jpg" + +expander = Mustermann::Expander(":file(.:ext)", type: :rails) +expander.expand(file: 'pony', ext: 'jpg') # => "/pony.jpg" +``` + +Or you can pass it a pattern instance: + +``` ruby +require 'mustermann' +pattern = Mustermann.new("/:file") + +require 'mustermann/expander' +expander = Mustermann::Expander.new(pattern) +``` + +### Expanding Multiple Patterns + +You can add patterns to an expander object via `<<`: + +``` ruby +require 'mustermann' + +expander = Mustermann::Expander.new +expander << "/users/:user_id" +expander << "/pages/:page_id" + +expander.expand(user_id: 15) # => "/users/15" +expander.expand(page_id: 58) # => "/pages/58" +``` + +You can set pattern options when creating the expander: + +``` ruby +require 'mustermann' + +expander = Mustermann::Expander.new(type: :template) +expander << "/users/{user_id}" +expander << "/pages/{page_id}" +``` + +Additionally, it is possible to combine patterns of different types: + +``` ruby +require 'mustermann' + +expander = Mustermann::Expander.new +expander << Mustermann.new("/users/{user_id}", type: :template) +expander << Mustermann.new("/pages/:page_id", type: :rails) +``` + +### Handling Additional Values + +The handling of additional values passed in to `expand` can be changed by setting the `additional_values` option: + +``` ruby +require 'mustermann' + +expander = Mustermann::Expander.new("/:slug", additional_values: :raise) +expander.expand(slug: "foo", value: "bar") # raises Mustermann::ExpandError + +expander = Mustermann::Expander.new("/:slug", additional_values: :ignore) +expander.expand(slug: "foo", value: "bar") # => "/foo" + +expander = Mustermann::Expander.new("/:slug", additional_values: :append) +expander.expand(slug: "foo", value: "bar") # => "/foo?value=bar" +``` + +It is also possible to pass this directly to the `expand` call: + +``` ruby +require 'mustermann' + +pattern = Mustermann.new('/:slug') +pattern.expand(:append, slug: "foo", value: "bar") # => "/foo?value=bar" +``` + + +## Generating Templates + +You can generate a list of URI templates that correspond to a Mustermann pattern (it is a list rather than a single template, as most pattern types are significantly more expressive than URI templates). + +This comes in quite handy since URI templates are not made for pattern matching. That way you can easily use a more precise template syntax and have it automatically generate hypermedia links for you. + +Template generation is supported by almost all patterns (notable exceptions are `shell`, `regexp` and `simple` patterns). + +``` ruby +require 'mustermann' + +Mustermann.new("/:name").to_templates # => ["/{name}"] +Mustermann.new("/:foo(@:bar)?/*baz").to_templates # => ["/{foo}@{bar}/{+baz}", "/{foo}/{+baz}"] +Mustermann.new("/{name}", type: :template).to_templates # => ["/{name}" +``` + +Union Composite patterns (with the | operator) support template generation if all patterns they are composed of also support it. + +``` ruby +require 'mustermann' + +pattern = Mustermann.new('/:name') +pattern |= Mustermann.new('/{name}', type: :template) +pattern |= Mustermann.new('/example/*nested') +pattern.to_templates # => ["/{name}", "/example/{+nested}"] +``` + +If accepting arbitrary patterns, you can and should use `respond_to?` to check feature availability. + +``` ruby +if pattern.respond_to? :to_templates + pattern.to_templates +else + warn "does not support template generation" +end +``` + + +## Proc Look Alike + +Patterns implement `to_proc`: + +``` ruby +require 'mustermann' +pattern = Mustermann.new('/foo') +callback = pattern.to_proc # => # + +callback.call('/foo') # => true +callback.call('/bar') # => false +``` + +They can therefore be easily passed to methods expecting a block: + +``` ruby +require 'mustermann' + +list = ["foo", "example@email.com", "bar"] +pattern = Mustermann.new(":name@:domain.:tld") +email = list.detect(&pattern) # => "example@email.com" +``` + + +## Mapper + + +You can use a mapper to transform strings according to two or more mappings: + +``` ruby +require 'mustermann/mapper' + +mapper = Mustermann::Mapper.new("/:page(.:format)?" => ["/:page/view.:format", "/:page/view.html"]) +mapper['/foo'] # => "/foo/view.html" +mapper['/foo.xml'] # => "/foo/view.xml" +mapper['/foo/bar'] # => "/foo/bar" +``` + + +## Sinatra Integration + +Mustermann is used in Sinatra by default since version 2.0, for previous versions an [extension](https://github.com/sinatra/mustermann-sinatra-extension) is available. + +### Configuration + +You can change what pattern type you want to use for your app via the `pattern` option: + +``` ruby +require 'sinatra/base' +require 'mustermann' + +class MyApp < Sinatra::Base + register Mustermann + set :pattern, type: :shell + + get '/images/*.png' do + send_file request.path_info + end + + get '/index{.htm,.html,}' do + erb :index + end +end +``` + +You can use the same setting for options: + +``` ruby +require 'sinatra' +require 'mustermann' + +register Mustermann +set :pattern, capture: { ext: %w[png jpg html txt] } + +get '/:slug(.:ext)?' do + # slug will be 'foo' for '/foo.png' + # slug will be 'foo.bar' for '/foo.bar' + # slug will be 'foo.bar' for '/foo.bar.html' + params[:slug] +end +``` + +It is also possible to pass in options to a specific route: + +``` ruby +require 'sinatra' +require 'mustermann' + +register Mustermann + +get '/:slug(.:ext)?', pattern: { greedy: false } do + # slug will be 'foo' for '/foo.png' + # slug will be 'foo' for '/foo.bar' + # slug will be 'foo' for '/foo.bar.html' + params[:slug] +end +``` + +Of course, all of the above can be combined. +Moreover, the `capture` and the `except` option can be passed to route directly. +And yes, this also works with `before` and `after` filters. + +``` ruby +require 'sinatra/base' +require 'sinatra/respond_with' +require 'mustermann' + +class MyApp < Sinatra::Base + register Mustermann, Sinatra::RespondWith + set :pattern, capture: { id: /\d+/ } # id will only match digits + + # only capture extensions known to Rack + before '*:ext', capture: Rack::Mime::MIME_TYPES.keys do + content_type params[:ext] # set Content-Type + request.path_info = params[:splat].first # drop the extension + end + + get '/:id' do + not_found unless page = Page.find params[:id] + respond_with(page) + end +end +``` + +### Why would I want this? + +* It gives you fine grained control over the pattern matching +* Allows you to use different pattern styles in your app +* The default is more robust and powerful than the built-in patterns +* Sinatra 2.0 will use Mustermann internally +* Better exceptions for broken route syntax + +### Why not include this in Sinatra 1.x? + +* It would introduce breaking changes, even though these would be minor +* Like Sinatra 2.0, Mustermann requires Ruby 2.0 or newer + + +## Duck Typing + + +### `to_pattern` + +All methods converting string input to pattern objects will also accept any arbitrary object that implements `to_pattern`: + +``` ruby +require 'mustermann' + +class MyObject + def to_pattern(**options) + Mustermann.new("/foo", **options) + end +end + +object = MyObject.new +Mustermann.new(object, type: :rails) # => # +``` + +It might also be that you want to call `to_pattern` yourself instead of `Mustermann.new`. You can load `mustermann/to_pattern` to implement this method for strings, regular expressions and pattern objects: + +``` ruby +require 'mustermann/to_pattern' + +"/foo".to_pattern # => # +"/foo".to_pattern(type: :rails) # => # +%r{/foo}.to_pattern # => # +"/foo".to_pattern.to_pattern # => # +``` + +You can also use the `Mustermann::ToPattern` mixin to easily add `to_pattern` to your own objects: + +``` ruby +require 'mustermann/to_pattern' + +class MyObject + include Mustermann::ToPattern + + def to_s + "/foo" + end +end + +MyObject.new.to_pattern # => # +``` + + +### `respond_to?` + +You can and should use `respond_to?` to check if a pattern supports certain features. + +``` ruby +require 'mustermann' +pattern = Mustermann.new("/") + +puts "supports expanding" if pattern.respond_to? :expand +puts "supports generating templates" if pattern.respond_to? :to_templates +``` + +Alternatively, you can handle a `NotImplementedError` raised from such a method. + +``` ruby +require 'mustermann' +pattern = Mustermann.new("/") + +begin + p pattern.to_templates +rescue NotImplementedError + puts "does not support generating templates" +end +``` + +This behavior corresponds to what Ruby does, for instance for [`fork`](http://ruby-doc.org/core-2.1.1/NotImplementedError.html). + + +## Available Options + + +### `capture` + +Supported by: All types except `identity`, `shell` and `simple` patterns. + +Most pattern types support changing the strings named captures will match via the `capture` options. + +Possible values for a capture: + +``` ruby +# String: Matches the given string (or any URI encoded version of it) +Mustermann.new('/index.:ext', capture: 'png') + +# Regexp: Matches the Regular expression +Mustermann.new('/:id', capture: /\d+/) + +# Symbol: Matches POSIX character class +Mustermann.new('/:id', capture: :digit) + +# Array of the above: Matches anything in the array +Mustermann.new('/:id_or_slug', capture: [/\d+/, :word]) + +# Hash of the above: Looks up the hash entry by capture name and uses value for matching +Mustermann.new('/:id.:ext', capture: { id: /\d+/, ext: ['png', 'jpg'] }) +``` + +Available POSIX character classes are: `:alnum`, `:alpha`, `:blank`, `:cntrl`, `:digit`, `:graph`, `:lower`, `:print`, `:punct`, `:space`, `:upper`, `:xdigit`, `:word` and `:ascii`. + + +### `except` + +Supported by: All types except `identity`, `shell` and `simple` patterns. + +Given you supply a second pattern via the except option. Any string that would match the primary pattern but also matches the except pattern will not result in a successful match. Feel free to read that again. Or just take a look at this example: + +``` ruby +pattern = Mustermann.new('/auth/*', except: '/auth/login') +pattern === '/auth/dunno' # => true +pattern === '/auth/login' # => false +``` + +Now, as said above, `except` treats the value as a pattern: + +``` ruby +pattern = Mustermann.new('/*anything', type: :rails, except: '/*anything.png') +pattern === '/foo.jpg' # => true +pattern === '/foo.png' # => false +``` + + +### `greedy` + +Supported by: All types except `identity` and `shell` patterns. +Default value: `true` + +**Simple** patterns are greedy, meaning that for the pattern `:foo:bar?`, everything will be captured as `foo`, `bar` will always be `nil`. By setting `greedy` to `false`, `foo` will capture as little as possible (which in this case would only be the first letter), leaving the rest to `bar`. + +**All other** supported patterns are semi-greedy. This means `:foo(.:bar)?` (`:foo(.:bar)` for Rails patterns) will capture everything before the *last* dot as `foo`. For these two pattern types, you can switch into non-greedy mode by setting the `greedy` option to false. In that case `foo` will only capture the part before the *first* dot. + +Semi-greedy behavior is not specific to dots, it works with all characters or strings. For instance, `:a(foo:b)` will capture everything before the *last* `foo` as `a`, and `:foo(bar)?` will not capture a `bar` at the end. + +``` ruby +pattern = Mustermann.new(':a.:b', greedy: true) +pattern.match('a.b.c.d') # => # + +pattern = Mustermann.new(':a.:b', greedy: false) +pattern.match('a.b.c.d') # => # +``` + + +### `space_matches_plus` + +Supported by: All types except `identity`, `regexp` and `shell` patterns. +Default value: `true` + +Most pattern types will by default also match a plus sign for a space in the pattern: + +``` ruby +Mustermann.new('a b') === 'a+b' # => true +``` + +You can disable this behavior via `space_matches_plus`: + +``` ruby +Mustermann.new('a b', space_matches_plus: false) === 'a+b' # => false +``` + +**Important:** This setting has no effect on captures, captures will always keep plus signs as plus sings and spaces as spaces: + +``` ruby +pattern = Mustermann.new(':x') +pattern.match('a b')[:x] # => 'a b' +pattern.match('a+b')[:x] # => 'a+b' +```` + + +### `uri_decode` + +Supported by all pattern types. +Default value: `true` + +Usually, characters in the pattern will also match the URI encoded version of these characters: + +``` ruby +Mustermann.new('a b') === 'a b' # => true +Mustermann.new('a b') === 'a%20b' # => true +``` + +You can avoid this by setting `uri_decode` to `false`: + +``` ruby +Mustermann.new('a b', uri_decode: false) === 'a b' # => true +Mustermann.new('a b', uri_decode: false) === 'a%20b' # => false +``` + + +### `ignore_unknown_options` + +Supported by all patterns. +Default value: `false` + +If you pass an option in that is not supported by the specific pattern type, Mustermann will raise an `ArgumentError`. +By setting `ignore_unknown_options` to `true`, it will happily ignore the option. + + +## Performance + +It's generally a good idea to reuse pattern objects, since as much computation as possible is happening during object creation, so that the actual matching or expanding is quite fast. + +Pattern objects should be treated as immutable. Their internals have been designed for both performance and low memory usage. To reduce pattern compilation, `Mustermann.new` and `Mustermann::Pattern.new` might return the same instance when given the same arguments, if that instance has not yet been garbage collected. However, this is not guaranteed, so do not rely on object identity. + +### String Matching + +When using a pattern instead of a regular expression for string matching, performance will usually be comparable. + +In certain cases, Mustermann might outperform naive, equivalent regular expressions. It achieves this by using look-ahead and atomic groups in ways that work well with a backtracking, NFA-based regular expression engine (such as the Oniguruma/Onigmo engine used by Ruby). It can be difficult and error prone to construct complex regular expressions using these techniques by hand. This only applies to patterns generating an AST internally (all but [identity](#-pattern-details-identity), [shell](#-pattern-details-shell), [simple](#-pattern-details-simple) and [regexp](#-pattern-details-regexp) patterns). + +When using a Mustermann pattern as a direct Regexp replacement (ie, via methods like `=~`, `match` or `===`), the overhead will be a single method dispatch, which some Ruby implementations might even eliminate with method inlining. This only applies to patterns using a regular expression internally (all but [identity](#-pattern-details-identity) and [shell](#-pattern-details-shell) patterns). + +### Expanding + +Pattern expansion significantly outperforms other, widely used Ruby tools for generating URLs from URL patterns in most use cases. + +This comes with a few trade-offs: + +* As with pattern compilation, as much computation as possible has been shifted to compiling expansion rules. This will add compilation overhead, which is why patterns only generate these rules on the first invocation to `Mustermann::Pattern#expand`. Create a `Mustermann::Expander` instance yourself to get better control over the point in time this computation should happen. +* Memory is sacrificed in favor of performance: The size of the expander object will grow linear with the number of possible combination for expansion keys ("/:foo/:bar" has one such combination, but "/(:foo/)?:bar?" has four) +* Parsing a params hash from a string generated from another params hash might not result in two identical hashes, and vice versa. Specifically, expanding ignores capture constraints, type casting and greediness. +* Partial expansion is (currently) not supported. + +## Details on Pattern Types + + +### `identity` + +**Supported options:** +[`uri_decode`](#-available-options--uri_decode), +[`ignore_unknown_options`](#-available-options--ignore_unknown_options). + + + + + + + + + + + + + + +
Syntax ElementDescription
any characterMatches exactly that character or a URI escaped version of it.
+ + +### `regexp` + +**Supported options:** +[`uri_decode`](#-available-options--uri_decode), +[`ignore_unknown_options`](#-available-options--ignore_unknown_options), `check_anchors`. + +The pattern string (or actual Regexp instance) should not contain anchors (`^` outside of square brackets, `$`, `\A`, `\z`, or `\Z`). +Anchors will be injected where necessary by Mustermann. + +By default, Mustermann will raise a `Mustermann::CompileError` if an anchor is encountered. +If you still want it to contain anchors at your own risk, set the `check_anchors` option to `false`. + +Using anchors will break [peeking](#-peeking) and [concatenation](#-concatenation). + + + + + + + + + + + + + + +
Syntax ElementDescription
any stringInterpreted as regular expression.
+ + +### `sinatra` + +**Supported options:** +[`capture`](#-available-options--capture), +[`except`](#-available-options--except), +[`greedy`](#-available-options--greedy), +[`space_matches_plus`](#-available-options--space_matches_plus), +[`uri_decode`](#-available-options--uri_decode), +[`ignore_unknown_options`](#-available-options--ignore_unknown_options). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Syntax ElementDescription
:name or {name} + Captures anything but a forward slash in a semi-greedy fashion. Capture is named name. + Capture behavior can be modified with capture and greedy option. +
*name or {+name} + Captures anything in a non-greedy fashion. Capture is named name. +
* or {+splat} + Captures anything in a non-greedy fashion. Capture is named splat. + It is always an array of captures, as you can use it more than once in a pattern. +
(expression) + Enclosed expression is a group. Useful when combined with ? to make it optional, + or to separate two elements that would otherwise be parsed as one. +
expression|expression|... + Will match anything matching the nested expressions. May contain any other syntax element, including captures. +
x?Makes x optional. For instance, (foo)? matches foo or an empty string.
/ + Matches forward slash. Does not match URI encoded version of forward slash. +
\xMatches x or URI encoded version of x. For instance \* matches *.
any other characterMatches exactly that character or a URI encoded version of it.
diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/bench/capturing.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/bench/capturing.rb new file mode 100644 index 00000000..1bb186a1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/bench/capturing.rb @@ -0,0 +1,57 @@ +$:.unshift File.expand_path('../lib', __dir__) + +require 'benchmark' +require 'mustermann' +require 'mustermann/regexp_based' +require 'addressable/template' + + +Mustermann.register(:regexp, Class.new(Mustermann::RegexpBased) { + def compile(**options) + Regexp.new(@string) + end +}, load: false) + +Mustermann.register(:addressable, Class.new(Mustermann::RegexpBased) { + def compile(**options) + Addressable::Template.new(@string) + end +}, load: false) + +list = [ + [:sinatra, '/*/:name' ], + [:rails, '/*prefix/:name' ], + [:simple, '/*/:name' ], + [:template, '{/prefix*}/{name}' ], + [:regexp, '\A\/(?.*?)\/(?[^\/\?#]+)\Z' ], + [:addressable, '{/prefix*}/{name}' ] +] + +def self.assert(value) + fail unless value +end + +string = '/a/b/c/d' +name = 'd' + +GC.disable + +puts "Compilation:" +Benchmark.bmbm do |x| + list.each do |type, pattern| + x.report(type) { 1_000.times { Mustermann.new(pattern, type: type) } } + end +end + +puts "", "Matching with two captures (one splat, one normal):" +Benchmark.bmbm do |x| + list.each do |type, pattern| + pattern = Mustermann.new(pattern, type: type) + x.report type do + 10_000.times do + match = pattern.match(string) + assert match[:name] == name + end + end + end +end \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/bench/regexp.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/bench/regexp.rb new file mode 100644 index 00000000..86ca31b8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/bench/regexp.rb @@ -0,0 +1,21 @@ +require 'benchmark' + +puts " atomic vs normal segments ".center(52, '=') + +types = { + normal: /\A\/(?:a|%61)\/(?[^\/\?#]+)(?:\/(?[^\/\?#]+))?\Z/, + atomic: /\A\/(?:a|%61)\/(?(?>[^\/\?#]+))(?:\/(?(?>[^\/\?#]+)))?\Z/ +} + +Benchmark.bmbm do |x| + types.each do |name, regexp| + string = "/a/" << ?a * 10000 << "/" << ?a * 5000 + fail unless regexp.match(string) + string << "/" + fail if regexp.match(string) + + x.report name.to_s do + 100.times { regexp.match(string) } + end + end +end \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/bench/simple_vs_sinatra.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/bench/simple_vs_sinatra.rb new file mode 100644 index 00000000..c16da91a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/bench/simple_vs_sinatra.rb @@ -0,0 +1,23 @@ +$:.unshift File.expand_path('../lib', __dir__) + +require 'benchmark' +require 'mustermann/simple' +require 'mustermann/sinatra' + +[Mustermann::Simple, Mustermann::Sinatra].each do |klass| + puts "", " #{klass} ".center(64, '=') + Benchmark.bmbm do |x| + no_capture = klass.new("/simple") + x.report("no captures, match") { 1_000.times { no_capture.match('/simple') } } + x.report("no captures, miss") { 1_000.times { no_capture.match('/miss') } } + + simple = klass.new("/:name") + x.report("simple, match") { 1_000.times { simple.match('/simple').captures } } + x.report("simple, miss") { 1_000.times { simple.match('/mi/ss') } } + + splat = klass.new("/*") + x.report("splat, match") { 1_000.times { splat.match("/a/b/c").captures } } + x.report("splat, miss") { 1_000.times { splat.match("/a/b/c.miss") } } + end + puts +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/bench/template_vs_addressable.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/bench/template_vs_addressable.rb new file mode 100644 index 00000000..48b54183 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/bench/template_vs_addressable.rb @@ -0,0 +1,26 @@ +$:.unshift File.expand_path('../lib', __dir__) + +require 'benchmark' +require 'mustermann/template' +require 'addressable/template' + +[Mustermann::Template, Addressable::Template].each do |klass| + puts "", " #{klass} ".center(64, '=') + Benchmark.bmbm do |x| + no_capture = klass.new("/simple") + x.report("no captures, match") { 1_000.times { no_capture.match('/simple') } } + x.report("no captures, miss") { 1_000.times { no_capture.match('/miss') } } + + simple = klass.new("/{match}") + x.report("simple, match") { 1_000.times { simple.match('/simple').captures } } + x.report("simple, miss") { 1_000.times { simple.match('/mi/ss') } } + + explode = klass.new("{/segments*}") + x.report("explode, match") { 1_000.times { explode.match("/a/b/c").captures } } + x.report("explode, miss") { 1_000.times { explode.match("/a/b/c.miss") } } + + expand = klass.new("/prefix/{foo}/something/{bar}") + x.report("expand") { 100.times { expand.expand(foo: 'foo', bar: 'bar').to_s } } + end + puts +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/bench/uri_parser_object.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/bench/uri_parser_object.rb new file mode 100644 index 00000000..62914bd5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/bench/uri_parser_object.rb @@ -0,0 +1,16 @@ +require "objspace" +require "uri" +require_relative "../lib/mustermann/ast/translator" + +translator = Mustermann::AST::Translator.new +translator.escape("foo") + +h1 = ObjectSpace.each_object.inject(Hash.new 0) { |h, o| h[o.class] += 1; h } + +100.times do + translator.escape("foo") +end + +h2 = ObjectSpace.each_object.inject(Hash.new 0) { |h, o| h[o.class] += 1; h } + +raise if (h2[URI::RFC2396_Parser] - h1[URI::RFC2396_Parser] != 0) diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann.rb new file mode 100644 index 00000000..43f35f50 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann.rb @@ -0,0 +1,133 @@ +# frozen_string_literal: true +require 'mustermann/pattern' +require 'mustermann/composite' +require 'mustermann/concat' +require 'thread' + +# Namespace and main entry point for the Mustermann library. +# +# Under normal circumstances the only external API entry point you should be using is {Mustermann.new}. +module Mustermann + # Type to use if no type is given. + # @api private + DEFAULT_TYPE = :sinatra + + # Creates a new pattern based on input. + # + # * From {Mustermann::Pattern}: returns given pattern. + # * From String: creates a pattern from the string, depending on type option (defaults to {Mustermann::Sinatra}) + # * From Regexp: creates a {Mustermann::Regular} pattern. + # * From Symbol: creates a {Mustermann::Sinatra} pattern with a single named capture named after the input. + # * From an Array or multiple inputs: creates a new pattern from each element, combines them to a {Mustermann::Composite}. + # * From anything else: Will try to call to_pattern on it or raise a TypeError. + # + # Note that if the input is a {Mustermann::Pattern}, Regexp or Symbol, the type option is ignored and if to_pattern is + # called on the object, the type will be handed on but might be ignored by the input object. + # + # If you want to enforce the pattern type, you should create them via their expected class. + # + # @example creating patterns + # require 'mustermann' + # + # Mustermann.new("/:name") # => # + # Mustermann.new("/{name}", type: :template) # => # + # Mustermann.new(/.*/) # => # + # Mustermann.new(:name, capture: :word) # => # + # Mustermann.new("/", "/*.jpg", type: :shell) # => # + # + # @example using custom #to_pattern + # require 'mustermann' + # + # class MyObject + # def to_pattern(**options) + # Mustermann.new("/:name", **options) + # end + # end + # + # Mustermann.new(MyObject.new, type: :rails) # => # + # + # @example enforcing type + # require 'mustermann/sinatra' + # + # Mustermann::Sinatra.new("/:name") + # + # @param [String, Pattern, Regexp, Symbol, #to_pattern, Array] + # input The representation of the pattern + # @param [Hash] options The options hash + # @return [Mustermann::Pattern] pattern corresponding to string. + # @raise (see []) + # @raise (see Mustermann::Pattern.new) + # @raise [TypeError] if the passed object cannot be converted to a pattern + # @see file:README.md#Types_and_Options "Types and Options" in the README + def self.new(*input, type: DEFAULT_TYPE, operator: :|, **options) + type ||= DEFAULT_TYPE + input = input.first if input.size < 2 + case input + when Pattern then input + when Regexp then self[:regexp].new(input, **options) + when String then self[type].new(input, **options) + when Symbol then self[:sinatra].new(input.inspect, **options) + when Array then input.map { |i| new(i, type: type, **options) }.inject(operator) + else + pattern = input.to_pattern(type: type, **options) if input.respond_to? :to_pattern + raise TypeError, "#{input.class} can't be coerced into Mustermann::Pattern" if pattern.nil? + pattern + end + end + + @mutex = Mutex.new + @types = {} + + # Maps a type to its factory. + # + # @example + # Mustermann[:sinatra] # => Mustermann::Sinatra + # + # @param [Symbol] name a pattern type identifier + # @raise [ArgumentError] if the type is not supported + # @return [Class, #new] pattern factory + def self.[](name) + return name if name.respond_to? :new + @types.fetch(normalized = normalized_type(name)) do + @mutex.synchronize do + error = try_require "mustermann/#{normalized}" + @types.fetch(normalized) { raise ArgumentError, "unsupported type %p#{" (#{error.message})" if error}" % name } + end + end + end + + # @return [LoadError, nil] + # @!visibility private + def self.try_require(path) + require(path) + nil + rescue LoadError => error + raise(error) unless error.path == path + error + end + + # @!visibility private + def self.register(name, type) + @types[normalized_type(name)] = type + end + + # @!visibility private + def self.normalized_type(type) + type.to_s.gsub('-', '_').downcase + end + + # @!visibility private + def self.extend_object(object) + return super unless defined? ::Sinatra::Base and object.is_a? Class and object < ::Sinatra::Base + require 'mustermann/extension' + end +end + +# :nocov: +begin + require 'mustermann/visualizer' if defined?(Pry) or defined?(IRB) +rescue LoadError => error + raise error unless error.path == 'mustermann/visualizer' + $stderr.puts(error.message) if caller_locations[1].absolute_path =~ %r{/lib/pry/|/irb/|^\((?:irb|pry)\)$} +end +# :nocov: diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/boundaries.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/boundaries.rb new file mode 100644 index 00000000..79cd8fdf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/boundaries.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true +require 'mustermann/ast/translator' + +module Mustermann + module AST + # Make sure #start and #stop is set on every node and within its parents #start and #stop. + # @!visibility private + class Boundaries < Translator + # @return [Mustermann::AST::Node] the ast passed as first argument + # @!visibility private + def self.set_boundaries(ast, string: nil, start: 0, stop: string.length) + new.translate(ast, start, stop) + ast + end + + translate(:node) do |start, stop| + t.set_boundaries(node, start, stop) + t(payload, node.start, node.stop) + end + + translate(:with_look_ahead) do |start, stop| + t.set_boundaries(node, start, stop) + t(head, node.start, node.stop) + t(payload, node.start, node.stop) + end + + translate(Array) do |start, stop| + each do |subnode| + t(subnode, start, stop) + start = subnode.stop + end + end + + translate(Object) { |*| node } + + # Checks that a node is within the given boundaries. + # @!visibility private + def set_boundaries(node, start, stop) + node.start = start if node.start.nil? or node.start < start + node.stop = node.start + node.min_size if node.stop.nil? or node.stop < node.start + node.stop = stop if node.stop > stop + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/compiler.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/compiler.rb new file mode 100644 index 00000000..c451438b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/compiler.rb @@ -0,0 +1,159 @@ +# frozen_string_literal: true +require 'mustermann/ast/translator' + +module Mustermann + # @see Mustermann::AST::Pattern + module AST + # Regexp compilation logic. + # @!visibility private + class Compiler < Translator + raises CompileError + + # Trivial compilations + translate(Array) { |**o| map { |e| t(e, **o) }.join } + translate(:node) { |**o| t(payload, **o) } + translate(:separator) { |**o| Regexp.escape(payload) } + translate(:optional) { |**o| "(?:%s)?" % t(payload, **o) } + translate(:char) { |**o| t.encoded(payload, **o) } + + translate :union do |**options| + "(?:%s)" % payload.map { |e| "(?:%s)" % t(e, **options) }.join(?|) + end + + translate :expression do |greedy: true, **options| + t(payload, allow_reserved: operator.allow_reserved, greedy: greedy && !operator.allow_reserved, + parametric: operator.parametric, separator: operator.separator, **options) + end + + translate :with_look_ahead do |**options| + lookahead = each_leaf.inject("") do |ahead, element| + ahead + t(element, skip_optional: true, lookahead: ahead, greedy: false, no_captures: true, **options).to_s + end + lookahead << (at_end ? '$' : '/') + t(head, lookahead: lookahead, **options) + t(payload, **options) + end + + # Capture compilation is complex. :( + # @!visibility private + class Capture < NodeTranslator + register :capture + + # @!visibility private + def translate(**options) + return pattern(**options) if options[:no_captures] + "(?<#{name}>#{translate(no_captures: true, **options)})" + end + + # @return [String] regexp without the named capture + # @!visibility private + def pattern(capture: nil, **options) + case capture + when Symbol then from_symbol(capture, **options) + when Array then from_array(capture, **options) + when Hash then from_hash(capture, **options) + when String then from_string(capture, **options) + when nil then from_nil(**options) + else capture + end + end + + private + def qualified(string, greedy: true, **options) "#{string}#{qualifier || "+#{?? unless greedy}"}" end + def with_lookahead(string, lookahead: nil, **options) lookahead ? "(?:(?!#{lookahead})#{string})" : string end + def from_hash(hash, **options) pattern(capture: hash[name.to_sym], **options) end + def from_array(array, **options) Regexp.union(*array.map { |e| pattern(capture: e, **options) }) end + def from_symbol(symbol, **options) qualified(with_lookahead("[[:#{symbol}:]]", **options), **options) end + def from_string(string, **options) Regexp.new(string.chars.map { |c| t.encoded(c, **options) }.join) end + def from_nil(**options) qualified(with_lookahead(default(**options), **options), **options) end + def default(**options) constraint || "[^/\\?#]" end + end + + # @!visibility private + class Splat < Capture + register :splat, :named_splat + # splats are always non-greedy + # @!visibility private + def pattern(**options) + constraint || ".*?" + end + end + + # @!visibility private + class Variable < Capture + register :variable + + # @!visibility private + def translate(**options) + return super(**options) if explode or not options[:parametric] + # Remove this line after fixing broken compatibility between 2.1 and 2.2 + options.delete(:parametric) if options.has_key?(:parametric) + parametric super(parametric: false, **options) + end + + # @!visibility private + def pattern(parametric: false, separator: nil, **options) + register_param(parametric: parametric, separator: separator, **options) + pattern = super(**options) + pattern = parametric(pattern) if parametric + pattern = "#{pattern}(?:#{Regexp.escape(separator)}#{pattern})*" if explode and separator + pattern + end + + # @!visibility private + def parametric(string) + "#{Regexp.escape(name)}(?:=#{string})?" + end + + # @!visibility private + def qualified(string, **options) + prefix ? "#{string}{1,#{prefix}}" : super(string, **options) + end + + # @!visibility private + def default(allow_reserved: false, **options) + allow_reserved ? '[\w\-\.~%\:/\?#\[\]@\!\$\&\'\(\)\*\+,;=]' : '[\w\-\.~%]' + end + + # @!visibility private + def register_param(parametric: false, split_params: nil, separator: nil, **options) + return unless explode and split_params + split_params[name] = { separator: separator, parametric: parametric } + end + end + + # @return [String] Regular expression for matching the given character in all representations + # @!visibility private + def encoded(char, uri_decode: true, space_matches_plus: true, **options) + return Regexp.escape(char) unless uri_decode + encoded = escape(char, escape: /./) + list = [escape(char), encoded.downcase, encoded.upcase].uniq.map { |c| Regexp.escape(c) } + if char == " " + list << encoded('+') if space_matches_plus + list << " " + end + "(?:%s)" % list.join("|") + end + + # Compiles an AST to a regular expression. + # @param [Mustermann::AST::Node] ast the tree + # @return [Regexp] corresponding regular expression. + # + # @!visibility private + def self.compile(ast, **options) + new.compile(ast, **options) + end + + # Compiles an AST to a regular expression. + # @param [Mustermann::AST::Node] ast the tree + # @return [Regexp] corresponding regular expression. + # + # @!visibility private + def compile(ast, except: nil, **options) + except &&= "(?!#{translate(except, no_captures: true, **options)}\\Z)" + Regexp.new("#{except}#{translate(ast, **options)}") + end + end + + private_constant :Compiler + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/expander.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/expander.rb new file mode 100644 index 00000000..f5ca874d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/expander.rb @@ -0,0 +1,147 @@ +# frozen_string_literal: true +require 'mustermann/ast/translator' +require 'mustermann/ast/compiler' +require 'ruby2_keywords' + +module Mustermann + module AST + # Looks at an AST, remembers the important bits of information to do an + # ultra fast expansion. + # + # @!visibility private + class Expander < Translator + raises ExpandError + + translate(Array, &-> (*args) do + inject(t.pattern) do |pattern, element| + t.add_to(pattern, t(element, *args)) + end + end.ruby2_keywords) + + translate :capture do |**options| + t.for_capture(node, **options) + end + + translate :named_splat, :splat do + t.pattern + t.for_capture(node) + end + + translate :expression do + t(payload, allow_reserved: operator.allow_reserved) + end + + translate :root, :group do + t(payload) + end + + translate :char do + t.pattern(t.escape(payload, also_escape: /[\/\?#\&\=%]/).gsub(?%, "%%")) + end + + translate :separator do + t.pattern(payload.gsub(?%, "%%")) + end + + translate :with_look_ahead do + t.add_to(t(head), t(payload)) + end + + translate :optional do + nested = t(payload) + nested += t.pattern unless nested.any? { |n| n.first.empty? } + nested + end + + translate :union do + payload.map { |e| t(e) }.inject(:+) + end + + # helper method for captures + # @!visibility private + def for_capture(node, **options) + name = node.name.to_sym + pattern('%s', name, name => /(?!#{pattern_for(node, **options)})./) + end + + # maps sorted key list to sprintf patterns and filters + # @!visibility private + def mappings + @mappings ||= {} + end + + # all the known keys + # @!visibility private + def keys + @keys ||= [] + end + + # add a tree for expansion + # @!visibility private + def add(ast) + translate(ast).each do |keys, pattern, filter| + self.keys.concat(keys).uniq! + mappings[keys.sort] ||= [keys, pattern, filter] + end + end + + # helper method for getting a capture's pattern. + # @!visibility private + def pattern_for(node, **options) + Compiler.new.decorator_for(node).pattern(**options) + end + + # @see Mustermann::Pattern#expand + # @!visibility private + def expand(values) + adjusted = values.each_with_object({}){ |(key, value), new_hash| + new_hash[value.instance_of?(Array) ? [key] * value.length : key] = value } + keys, pattern, filters = mappings.fetch(adjusted.keys.flatten.sort) { error_for(values) } + filters.each { |key, filter| adjusted[key] &&= escape(adjusted[key], also_escape: filter) } + pattern % (adjusted[keys] || adjusted.values_at(*keys)) + end + + # @see Mustermann::Pattern#expandable? + # @!visibility private + def expandable?(values) + values = values.keys if values.respond_to? :keys + values = values.sort if values.respond_to? :sort + mappings.include? values + end + + # @see Mustermann::Expander#with_rest + # @!visibility private + def expandable_keys(keys) + mappings.keys.select { |k| (k - keys).empty? }.max_by(&:size) || keys + end + + # helper method for raising an error for unexpandable values + # @!visibility private + def error_for(values) + expansions = mappings.keys.map(&:inspect).join(" or ") + raise error_class, "cannot expand with keys %p, possible expansions: %s" % [values.keys.sort, expansions] + end + + # @see Mustermann::AST::Translator#expand + # @!visibility private + ruby2_keywords def escape(string, *args) + return super unless string.respond_to?(:=~) + + # URI::Parser is pretty slow, let's not send every string to it, even if it's unnecessary + string =~ /\A\w*\Z/ ? string : super + end + + # Turns a sprintf pattern into our secret internal data structure. + # @!visibility private + def pattern(string = "", *keys, **filters) + [[keys, string, filters]] + end + + # Creates the product of two of our secret internal data structures. + # @!visibility private + def add_to(list, result) + list << [[], ""] if list.empty? + list.inject([]) { |l, (k1, p1, f1)| l + result.map { |k2, p2, f2| [k1+k2, p1+p2, f1.merge(f2)] } } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/node.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/node.rb new file mode 100644 index 00000000..b846e57b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/node.rb @@ -0,0 +1,222 @@ +module Mustermann + # @see Mustermann::AST::Pattern + module AST + # @!visibility private + class Node + # @!visibility private + attr_accessor :payload, :start, :stop + + # @!visibility private + # @param [Symbol] name of the node + # @return [Class] factory for the node + def self.[](name) + @names ||= {} + @names[name] ||= begin + const_name = constant_name(name) + Object.const_get(const_name) if Object.const_defined?(const_name) + end + end + + # Turns a class name into a node identifier. + # @!visibility private + def self.type + name[/[^:]+$/].split(/(?<=.)(?=[A-Z])/).map(&:downcase).join(?_).to_sym + end + + # @!visibility private + # @param [Symbol] name of the node + # @return [String] qualified name of factory for the node + def self.constant_name(name) + return self.name if name.to_sym == :node + name = name.to_s.split(?_).map(&:capitalize).join + "#{self.name}::#{name}" + end + + # Helper for creating a new instance and calling #parse on it. + # @return [Mustermann::AST::Node] + # @!visibility private + def self.parse(payload = nil, **options, &block) + new(payload, **options).tap { |n| n.parse(&block) } + end + + # @!visibility private + def initialize(payload = nil, **options) + options.each { |key, value| public_send("#{key}=", value) } + self.payload = payload + end + + # @!visibility private + def is_a?(type) + type = Node[type] if type.is_a? Symbol + super(type) + end + + # Double dispatch helper for reading from the buffer into the payload. + # @!visibility private + def parse + self.payload ||= [] + while element = yield + payload << element + end + end + + # Loop through all nodes that don't have child nodes. + # @!visibility private + def each_leaf(&block) + return enum_for(__method__) unless block_given? + called = false + Array(payload).each do |entry| + next unless entry.respond_to? :each_leaf + entry.each_leaf(&block) + called = true + end + yield(self) unless called + end + + # @return [Integer] length of the substring + # @!visibility private + def length + stop - start if start and stop + end + + # @return [Integer] minimum size for a node + # @!visibility private + def min_size + 0 + end + + # Turns a class name into a node identifier. + # @!visibility private + def type + self.class.type + end + + # @!visibility private + class Capture < Node + # @see Mustermann::AST::Compiler::Capture#default + # @!visibility private + attr_accessor :constraint + + # @see Mustermann::AST::Compiler::Capture#qualified + # @!visibility private + attr_accessor :qualifier + + # @see Mustermann::AST::Pattern#map_param + # @!visibility private + attr_accessor :convert + + # @see Mustermann::AST::Node#parse + # @!visibility private + def parse + self.payload ||= String.new + super + end + + # @!visibility private + alias_method :name, :payload + end + + # @!visibility private + class Char < Node + # @return [Integer] minimum size for a node + # @!visibility private + def min_size + 1 + end + end + + # AST node for template expressions. + # @!visibility private + class Expression < Node + # @!visibility private + attr_accessor :operator + end + + # @!visibility private + class Composition < Node + # @!visibility private + def initialize(payload = nil, **options) + super(Array(payload), **options) + end + end + + # @!visibility private + class Group < Composition + end + + # @!visibility private + class Union < Composition + end + + # @!visibility private + class Optional < Node + end + + # @!visibility private + class Or < Node + end + + # @!visibility private + class Root < Node + # @!visibility private + attr_accessor :pattern + + # Will trigger transform. + # + # @see Mustermann::AST::Node.parse + # @!visibility private + def self.parse(string, &block) + root = new + root.pattern = string + root.parse(&block) + root + end + end + + # @!visibility private + class Separator < Node + # @return [Integer] minimum size for a node + # @!visibility private + def min_size + 1 + end + end + + # @!visibility private + class Splat < Capture + # @see Mustermann::AST::Node::Capture#name + # @!visibility private + def name + "splat" + end + end + + # @!visibility private + class NamedSplat < Splat + # @see Mustermann::AST::Node::Capture#name + # @!visibility private + alias_method :name, :payload + end + + # AST node for template variables. + # @!visibility private + class Variable < Capture + # @!visibility private + attr_accessor :prefix, :explode + end + + # @!visibility private + class WithLookAhead < Node + # @!visibility private + attr_accessor :head, :at_end + + # @!visibility private + def initialize(payload, at_end, **options) + super(**options) + self.head, *self.payload = Array(payload) + self.at_end = at_end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/param_scanner.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/param_scanner.rb new file mode 100644 index 00000000..e2201809 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/param_scanner.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true +require 'mustermann/ast/translator' + +module Mustermann + module AST + # Scans an AST for param converters. + # @!visibility private + # @see Mustermann::AST::Pattern#to_templates + class ParamScanner < Translator + # @!visibility private + def self.scan_params(ast) + new.translate(ast) + end + + translate(:node) { t(payload) } + translate(Array) { map { |e| t(e) }.inject(:merge) } + translate(Object) { {} } + translate(:capture) { convert ? { name => convert } : {} } + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/parser.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/parser.rb new file mode 100644 index 00000000..5a00d2bb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/parser.rb @@ -0,0 +1,235 @@ +# frozen_string_literal: true +require 'mustermann/ast/node' +require 'forwardable' +require 'ruby2_keywords' +require 'strscan' + +module Mustermann + # @see Mustermann::AST::Pattern + module AST + # Simple, StringScanner based parser. + # @!visibility private + class Parser + # @param [String] string to be parsed + # @return [Mustermann::AST::Node] parse tree for string + # @!visibility private + def self.parse(string, **options) + new(**options).parse(string) + end + + # Defines another grammar rule for first character. + # + # @see Mustermann::Rails + # @see Mustermann::Sinatra + # @see Mustermann::Template + # @!visibility private + def self.on(*chars, &block) + chars.each do |char| + define_method("read %p" % char, &block) + end + end + + # Defines another grammar rule for a suffix. + # + # @see Mustermann::Sinatra + # @!visibility private + def self.suffix(pattern = /./, after: :node, &block) + @suffix ||= [] + @suffix << [pattern, after, block] if block + @suffix + end + + # @!visibility private + attr_reader :buffer, :string, :pattern + + extend Forwardable + def_delegators :buffer, :eos?, :getch, :pos + + # @!visibility private + def initialize(pattern: nil, **options) + @pattern = pattern + end + + # @param [String] string to be parsed + # @return [Mustermann::AST::Node] parse tree for string + # @!visibility private + def parse(string) + @string = string + @buffer = ::StringScanner.new(string) + node(:root, string) { read unless eos? } + end + + # @example + # node(:char, 'x').compile =~ 'x' # => true + # + # @param [Symbol] type node type + # @return [Mustermann::AST::Node] + # @!visibility private + ruby2_keywords def node(type, *args, &block) + type = Node[type] unless type.respond_to? :new + start = pos + node = block ? type.parse(*args, &block) : type.new(*args) + min_size(start, pos, node) + end + + # Create a node for a character we don't have an explicit rule for. + # + # @param [String] char the character + # @return [Mustermann::AST::Node] the node + # @!visibility private + def default_node(char) + char == ?/ ? node(:separator, char) : node(:char, char) + end + + # Reads the next element from the buffer. + # @return [Mustermann::AST::Node] next element + # @!visibility private + def read + start = pos + char = getch + method = "read %p" % char + element= respond_to?(method) ? send(method, char) : default_node(char) + min_size(start, pos, element) + read_suffix(element) + end + + # sets start on node to start if it's not set to a lower value. + # sets stop on node to stop if it's not set to a higher value. + # @return [Mustermann::AST::Node] the node passed as third argument + # @!visibility private + def min_size(start, stop, node) + stop ||= start + start ||= stop + node.start = start unless node.start and node.start < start + node.stop = stop unless node.stop and node.stop > stop + node + end + + # Checks for a potential suffix on the buffer. + # @param [Mustermann::AST::Node] element node without suffix + # @return [Mustermann::AST::Node] node with suffix + # @!visibility private + def read_suffix(element) + self.class.suffix.inject(element) do |ele, (regexp, after, callback)| + next ele unless ele.is_a?(after) and payload = scan(regexp) + content = instance_exec(payload, ele, &callback) + min_size(element.start, pos, content) + end + end + + # Wrapper around {StringScanner#scan} that turns strings into escaped + # regular expressions and returns a MatchData if the regexp has any + # named captures. + # + # @param [Regexp, String] regexp + # @see StringScanner#scan + # @return [String, MatchData, nil] + # @!visibility private + def scan(regexp) + regexp = Regexp.new(Regexp.escape(regexp)) unless regexp.is_a? Regexp + string = buffer.scan(regexp) + regexp.names.any? ? regexp.match(string) : string + end + + # Asserts a regular expression matches what's next on the buffer. + # Will return corresponding MatchData if regexp includes named captures. + # + # @param [Regexp] regexp expected to match + # @return [String, MatchData] the match + # @raise [Mustermann::ParseError] if expectation wasn't met + # @!visibility private + def expect(regexp, char: nil, **options) + scan(regexp) || unexpected(char, **options) + end + + # Allows to read a string inside brackets. It does not expect the string + # to start with an opening bracket. + # + # @example + # buffer.string = "fo>ba" + # read_brackets(?<, ?>) # => "fo" + # buffer.rest # => "ba" + # + # @!visibility private + def read_brackets(open, close, char: nil, escape: ?\\, quote: false, **options) + result = String.new + escape = false if escape.nil? + while (current = getch) + case current + when close then return result + when open then result << open << read_brackets(open, close) << close + when escape then result << escape << getch + else result << current + end + end + unexpected(char, **options) + end + + + # Reads an argument string of the format arg1,args2,key:value + # + # @!visibility private + def read_args(key_separator, close, separator: ?,, symbol_keys: true, **options) + list, map = [], {} + while buffer.peek(1) != close + scan(separator) + entries = read_list(close, separator, separator: key_separator, **options) + case entries.size + when 1 then list += entries + when 2 then map[symbol_keys ? entries.first.to_sym : entries.first] = entries.last + else unexpected(key_separator) + end + buffer.pos -= 1 + end + expect(close) + [list, map] + end + + # Reads a separated list with the ability to quote, escape and add spaces. + # + # @!visibility private + def read_list(*close, separator: ?,, escape: ?\\, quotes: [?", ?'], ignore: " ", **options) + result = [] + while current = getch + element = result.empty? ? result : result.last + case current + when *close then return result + when ignore then nil # do nothing + when separator then result << String.new + when escape then element << getch + when *quotes then element << read_escaped(current, escape: escape) + else element << current + end + end + unexpected(current, **options) + end + + # Read a string until a terminating character, ignoring escaped versions of said character. + # + # @!visibility private + def read_escaped(close, escape: ?\\, **options) + result = String.new + while current = getch + case current + when close then return result + when escape then result << getch + else result << current + end + end + unexpected(current, **options) + end + + # Helper for raising an exception for an unexpected character. + # Will read character from buffer if buffer is passed in. + # + # @param [String, nil] char the unexpected character + # @raise [Mustermann::ParseError, Exception] + # @!visibility private + def unexpected(char = nil, exception: ParseError) + char ||= getch + char = "space" if char == " " + raise exception, "unexpected #{char || "end of string"} while parsing #{string.inspect}" + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/pattern.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/pattern.rb new file mode 100644 index 00000000..cfd6481d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/pattern.rb @@ -0,0 +1,136 @@ +# frozen_string_literal: true +require 'mustermann/ast/parser' +require 'mustermann/ast/boundaries' +require 'mustermann/ast/compiler' +require 'mustermann/ast/transformer' +require 'mustermann/ast/validation' +require 'mustermann/ast/template_generator' +require 'mustermann/ast/param_scanner' +require 'mustermann/regexp_based' +require 'mustermann/expander' +require 'mustermann/equality_map' + +module Mustermann + # @see Mustermann::AST::Pattern + module AST + # Superclass for pattern styles that parse an AST from the string pattern. + # @abstract + class Pattern < Mustermann::RegexpBased + supported_options :capture, :except, :greedy, :space_matches_plus + + extend Forwardable, SingleForwardable + single_delegate on: :parser, suffix: :parser + instance_delegate %i[parser compiler transformer validation template_generator param_scanner boundaries] => 'self.class' + instance_delegate parse: :parser, transform: :transformer, validate: :validation, + generate_templates: :template_generator, scan_params: :param_scanner, set_boundaries: :boundaries + + # @api private + # @return [#parse] parser object for pattern + # @!visibility private + def self.parser + return Parser if self == AST::Pattern + const_set :Parser, Class.new(superclass.parser) unless const_defined? :Parser, false + const_get :Parser + end + + # @api private + # @return [#compile] compiler object for pattern + # @!visibility private + def self.compiler + Compiler + end + + # @api private + # @return [#set_boundaries] translator making sure start and stop is set on all nodes + # @!visibility private + def self.boundaries + Boundaries + end + + # @api private + # @return [#transform] transformer object for pattern + # @!visibility private + def self.transformer + Transformer + end + + # @api private + # @return [#validate] validation object for pattern + # @!visibility private + def self.validation + Validation + end + + # @api private + # @return [#generate_templates] generates URI templates for pattern + # @!visibility private + def self.template_generator + TemplateGenerator + end + + # @api private + # @return [#scan_params] param scanner for pattern + # @!visibility private + def self.param_scanner + ParamScanner + end + + # @!visibility private + def compile(**options) + options[:except] &&= parse options[:except] + compiler.compile(to_ast, **options) + rescue CompileError => error + raise error.class, "#{error.message}: #{@string.inspect}", error.backtrace + end + + # Internal AST representation of pattern. + # @!visibility private + def to_ast + @ast_cache ||= EqualityMap.new + @ast_cache.fetch(@string) do + ast = parse(@string, pattern: self) + ast &&= transform(ast) + ast &&= set_boundaries(ast, string: @string) + validate(ast) + end + end + + # All AST-based pattern implementations support expanding. + # + # @example (see Mustermann::Pattern#expand) + # @param (see Mustermann::Pattern#expand) + # @return (see Mustermann::Pattern#expand) + # @raise (see Mustermann::Pattern#expand) + # @see Mustermann::Pattern#expand + # @see Mustermann::Expander + def expand(behavior = nil, values = {}) + @expander ||= Mustermann::Expander.new(self) + @expander.expand(behavior, values) + end + + # All AST-based pattern implementations support generating templates. + # + # @example (see Mustermann::Pattern#to_templates) + # @param (see Mustermann::Pattern#to_templates) + # @return (see Mustermann::Pattern#to_templates) + # @see Mustermann::Pattern#to_templates + def to_templates + @to_templates ||= generate_templates(to_ast) + end + + # @!visibility private + # @see Mustermann::Pattern#map_param + def map_param(key, value) + return super unless param_converters.include? key + param_converters[key][super] + end + + # @!visibility private + def param_converters + @param_converters ||= scan_params(to_ast) + end + + private :compile, :parse, :transform, :validate, :generate_templates, :param_converters, :scan_params, :set_boundaries + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/template_generator.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/template_generator.rb new file mode 100644 index 00000000..763086ef --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/template_generator.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true +require 'mustermann/ast/translator' + +module Mustermann + module AST + # Turns an AST into an Array of URI templates representing the AST. + # @!visibility private + # @see Mustermann::AST::Pattern#to_templates + class TemplateGenerator < Translator + # @!visibility private + def self.generate_templates(ast) + new.translate(ast).uniq + end + + # translate(:expression) is not needed, since template patterns simply call to_s + translate(:root, :group) { t(payload) || [""] } + translate(:separator, :char) { t.escape(payload) } + translate(:capture) { "{#{name}}" } + translate(:optional) { [t(payload), ""] } + translate(:named_splat, :splat) { "{+#{name}}" } + translate(:with_look_ahead) { t([head, payload]) } + translate(:union) { payload.flat_map { |e| t(e) } } + + translate(Array) do + map { |e| Array(t(e)) }.inject { |first, second| first.product(second).map(&:join) } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/transformer.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/transformer.rb new file mode 100644 index 00000000..f21f8f3f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/transformer.rb @@ -0,0 +1,179 @@ +# frozen_string_literal: true +require 'mustermann/ast/translator' + +module Mustermann + module AST + # Takes a tree, turns it into an even better tree. + # @!visibility private + class Transformer < Translator + + # Transforms a tree. + # @note might mutate handed in tree instead of creating a new one + # @param [Mustermann::AST::Node] tree to be transformed + # @return [Mustermann::AST::Node] transformed tree + # @!visibility private + def self.transform(tree) + new.translate(tree) + end + + # recursive descent + translate(:node) do + node.payload = t(payload) + node + end + + # ignore unknown objects on the tree + translate(Object) { node } + + # turn a group containing or nodes into a union + # @!visibility private + class GroupTransformer < NodeTranslator + register :group + + # @!visibility private + def translate + payload.flatten! if payload.is_a?(Array) + return union if payload.any? { |e| e.is_a? :or } + self.payload = t(payload) + self + end + + # @!visibility private + def union + groups = split_payload.map { |g| group(g) } + Node[:union].new(groups, start: node.start, stop: node.stop) + end + + # @!visibility private + def group(elements) + return t(elements.first) if elements.size == 1 + start, stop = elements.first.start, elements.last.stop if elements.any? + Node[:group].new(t(elements), start: start, stop: stop) + end + + # @!visibility private + def split_payload + groups = [[]] + payload.each { |e| e.is_a?(:or) ? groups << [] : groups.last << e } + groups.map! + end + end + + # inject a union node right inside the root node if it contains or nodes + # @!visibility private + class RootTransformer < GroupTransformer + register :root + + # @!visibility private + def union + self.payload = [super] + self + end + end + + # URI expression transformations depending on operator + # @!visibility private + class ExpressionTransform < NodeTranslator + register :expression + + # @!visibility private + Operator ||= Struct.new(:separator, :allow_reserved, :prefix, :parametric) + + # Operators available for expressions. + # @!visibility private + OPERATORS ||= { + nil => Operator.new(?,, false, false, false), ?+ => Operator.new(?,, true, false, false), + ?# => Operator.new(?,, true, ?#, false), ?. => Operator.new(?., false, ?., false), + ?/ => Operator.new(?/, false, ?/, false), ?; => Operator.new(?;, false, ?;, true), + ?? => Operator.new(?&, false, ??, true), ?& => Operator.new(?&, false, ?&, true) + } + + # Sets operator and inserts separators in between variables. + # @!visibility private + def translate + self.operator = OPERATORS.fetch(operator) { raise CompileError, "#{operator} operator not supported" } + separator = Node[:separator].new(operator.separator) + prefix = Node[:separator].new(operator.prefix) + self.payload = Array(payload.inject { |list, element| Array(list) << t(separator.dup) << t(element) }) + payload.unshift(prefix) if operator.prefix + self + end + end + + # Inserts with_look_ahead nodes wherever appropriate + # @!visibility private + class ArrayTransform < NodeTranslator + register Array + + # the new array + # @!visibility private + def payload + @payload ||= [] + end + + # buffer for potential look ahead + # @!visibility private + def lookahead_buffer + @lookahead_buffer ||= [] + end + + # transform the array + # @!visibility private + def translate + each { |e| track t(e) } + payload.concat create_lookahead(lookahead_buffer, true) + end + + # handle a single element from the array + # @!visibility private + def track(element) + return list_for(element) << element if lookahead_buffer.empty? + return lookahead_buffer << element if lookahead? element + + lookahead = lookahead_buffer.dup + lookahead = create_lookahead(lookahead, false) if element.is_a? Node[:separator] + lookahead_buffer.clear + + payload.concat(lookahead) << element + end + + # turn look ahead buffer into look ahead node + # @!visibility private + def create_lookahead(elements, *args) + return elements unless elements.size > 1 + [Node[:with_look_ahead].new(elements, *args, start: elements.first.start, stop: elements.last.stop)] + end + + # can the given element be used in a look-ahead? + # @!visibility private + def lookahead?(element, in_lookahead = false) + case element + when Node[:char] then in_lookahead + when Node[:group] then lookahead_payload?(element.payload, in_lookahead) + when Node[:optional] then lookahead?(element.payload, true) or expect_lookahead?(element.payload) + end + end + + # does the list of elements look look-ahead-ish to you? + # @!visibility private + def lookahead_payload?(payload, in_lookahead) + return unless payload[0..-2].all? { |e| lookahead?(e, in_lookahead) } + expect_lookahead?(payload.last) or lookahead?(payload.last, in_lookahead) + end + + # can the current element deal with a look-ahead? + # @!visibility private + def expect_lookahead?(element) + return element.class == Node[:capture] unless element.is_a? Node[:group] + element.payload.all? { |e| expect_lookahead?(e) } + end + + # helper method for deciding where to put an element for now + # @!visibility private + def list_for(element) + expect_lookahead?(element) ? lookahead_buffer : payload + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/translator.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/translator.rb new file mode 100644 index 00000000..cb5ad955 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/translator.rb @@ -0,0 +1,130 @@ +# frozen_string_literal: true +require 'mustermann/ast/node' +require 'mustermann/error' +require 'ruby2_keywords' +require 'delegate' + +module Mustermann + module AST + # Implements translator pattern + # + # @abstract + # @!visibility private + class Translator + + URI_PARSER = defined?(URI::RFC2396_PARSER) ? URI::RFC2396_PARSER : URI::RFC2396_Parser.new + + # Encapsulates a single node translation + # @!visibility private + class NodeTranslator < DelegateClass(Node) + # @param [Array] types list of types to register for. + # @!visibility private + def self.register(*types) + types.each do |type| + type = Node.constant_name(type) if type.is_a? Symbol + translator.dispatch_table[type.to_s] = self + end + end + + # @param node [Mustermann::AST::Node, Object] + # @param translator [Mustermann::AST::Translator] + # + # @!visibility private + def initialize(node, translator) + @translator = translator + super(node) + end + + # @!visibility private + attr_reader :translator + + # shorthand for translating a nested object + # @!visibility private + ruby2_keywords def t(*args, &block) + return translator unless args.any? + translator.translate(*args, &block) + end + + # @!visibility private + alias_method :node, :__getobj__ + end + + # maps types to translations + # @!visibility private + def self.dispatch_table + @dispatch_table ||= {} + end + + # some magic sauce so {NodeTranslator}s know whom to talk to for {#register} + # @!visibility private + def self.inherited(subclass) + node_translator = Class.new(NodeTranslator) + node_translator.define_singleton_method(:translator) { subclass } + subclass.const_set(:NodeTranslator, node_translator) + super + end + + # DSL-ish method for specifying the exception class to use. + # @!visibility private + def self.raises(error) + define_method(:error_class) { error } + end + + # DSL method for defining single method translations. + # @!visibility private + def self.translate(*types, &block) + Class.new(const_get(:NodeTranslator)) do + register(*types) + define_method(:translate, &block) + end + end + + # Enables quick creation of a translator object. + # + # @example + # require 'mustermann' + # require 'mustermann/ast/translator' + # + # translator = Mustermann::AST::Translator.create do + # translate(:node) { [type, *t(payload)].flatten.compact } + # translate(Array) { map { |e| t(e) } } + # translate(Object) { } + # end + # + # ast = Mustermann.new('/:name').to_ast + # translator.translate(ast) # => [:root, :separator, :capture] + # + # @!visibility private + def self.create(&block) + Class.new(self, &block).new + end + + raises Mustermann::Error + + # @param [Mustermann::AST::Node, Object] node to translate + # @return decorator encapsulating translation + # + # @!visibility private + def decorator_for(node) + factory = node.class.ancestors.inject(nil) { |d,a| d || self.class.dispatch_table[a.name] } + raise error_class, "#{self.class}: Cannot translate #{node.class}" unless factory + factory.new(node, self) + end + + # Start the translation dance for a (sub)tree. + # @!visibility private + ruby2_keywords def translate(node, *args, &block) + result = decorator_for(node).translate(*args, &block) + result = result.node while result.is_a? NodeTranslator + result + end + + # @return [String] escaped character + # @!visibility private + def escape(char, parser: URI_PARSER, escape: URI_PARSER.regexp[:UNSAFE], also_escape: nil) + escape = Regexp.union(also_escape, escape) if also_escape + char.to_s =~ escape ? parser.escape(char, Regexp.union(*escape)) : char + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/validation.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/validation.rb new file mode 100644 index 00000000..3e09177b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/ast/validation.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true +require 'mustermann/ast/translator' + +module Mustermann + module AST + # Checks the AST for certain validations, like correct capture names. + # + # Internally a poor man's visitor (abusing translator to not have to implement a visitor). + # @!visibility private + class Validation < Translator + # Runs validations. + # + # @param [Mustermann::AST::Node] ast to be validated + # @return [Mustermann::AST::Node] the validated ast + # @raise [Mustermann::AST::CompileError] if validation fails + # @!visibility private + def self.validate(ast) + new.translate(ast) + ast + end + + translate(Object, :splat) {} + translate(:node) { t(payload) } + translate(Array) { each { |p| t(p)} } + translate(:capture) { t.check_name(name, forbidden: ['captures', 'splat'])} + translate(:variable, :named_splat) { t.check_name(name, forbidden: 'captures')} + + # @raise [Mustermann::CompileError] if name is not acceptable + # @!visibility private + def check_name(name, forbidden: []) + raise CompileError, "capture name can't be empty" if name.nil? or name.empty? + raise CompileError, "capture name must start with underscore or lower case letter" unless name =~ /^[a-z_]/ + raise CompileError, "capture name can't be #{name}" if Array(forbidden).include? name + raise CompileError, "can't use the same capture name twice" if names.include? name + names << name + end + + # @return [Array] list of capture names in tree + # @!visibility private + def names + @names ||= [] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/caster.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/caster.rb new file mode 100644 index 00000000..a066f958 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/caster.rb @@ -0,0 +1,109 @@ +# frozen_string_literal: true +require 'delegate' + +module Mustermann + # Class for defining and running simple Hash transformations. + # + # @example + # caster = Mustermann::Caster.new + # caster.register(:foo) { |value| { bar: value.upcase } } + # caster.cast(foo: "hello", baz: "world") # => { bar: "HELLO", baz: "world" } + # + # @see Mustermann::Expander#cast + # + # @!visibility private + class Caster < DelegateClass(Array) + # @param (see #register) + # @!visibility private + def initialize(*types, &block) + super([]) + register(*types, &block) + end + + # @param [Array] types identifier for cast type (some need block) + # @!visibility private + def register(*types, &block) + return if types.empty? and block.nil? + types << Any.new(&block) if types.empty? + types.each { |type| self << caster_for(type, &block) } + end + + # @param [Symbol, Regexp, #cast, #===] type identifier for cast type (some need block) + # @return [#cast] specific cast operation + # @!visibility private + def caster_for(type, &block) + case type + when Symbol, Regexp then Key.new(type, &block) + else type.respond_to?(:cast) ? type : Value.new(type, &block) + end + end + + # Transforms a Hash. + # @param [Hash] hash pre-transform Hash + # @return [Hash] post-transform Hash + # @!visibility private + def cast(hash) + return hash if empty? + merge = {} + hash.delete_if do |key, value| + next unless casted = lazy.map { |e| e.cast(key, value) }.detect { |e| e } + casted = { key => casted } unless casted.respond_to? :to_hash + merge.update(casted.to_hash) + end + hash.update(merge) + end + + # Class for block based casts that are triggered for every key/value pair. + # @!visibility private + class Any + # @!visibility private + def initialize(&block) + @block = block + end + + # @see Mustermann::Caster#cast + # @!visibility private + def cast(key, value) + case @block.arity + when 0 then @block.call + when 1 then @block.call(value) + else @block.call(key, value) + end + end + end + + # Class for block based casts that are triggered for key/value pairs with a matching value. + # @!visibility private + class Value < Any + # @param [#===] type used for matching values + # @!visibility private + def initialize(type, &block) + @type = type + super(&block) + end + + # @see Mustermann::Caster#cast + # @!visibility private + def cast(key, value) + super if @type === value + end + end + + # Class for block based casts that are triggered for key/value pairs with a matching key. + # @!visibility private + class Key < Any + # @param [#===] type used for matching keys + # @!visibility private + def initialize(type, &block) + @type = type + super(&block) + end + + # @see Mustermann::Caster#cast + # @!visibility private + def cast(key, value) + super if @type === key + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/composite.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/composite.rb new file mode 100644 index 00000000..280c77d9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/composite.rb @@ -0,0 +1,112 @@ +# frozen_string_literal: true +module Mustermann + # Class for pattern objects composed of multiple patterns using binary logic. + # @see Mustermann::Pattern#& + # @see Mustermann::Pattern#| + # @see Mustermann::Pattern#^ + class Composite < Pattern + attr_reader :patterns, :operator + supported_options :operator, :type + + # @see Mustermann::Pattern.supported? + def self.supported?(option, type: nil, **options) + return true if super + Mustermann[type || Mustermann::DEFAULT_TYPE].supported?(option, **options) + end + + # @return [Mustermann::Pattern] a new composite pattern + def self.new(*patterns, **options) + patterns = patterns.flatten + case patterns.size + when 0 then raise ArgumentError, 'cannot create empty composite pattern' + when 1 then patterns.first + else super(patterns, **options) + end + end + + def initialize(patterns, operator: :|, **options) + @operator = operator.to_sym + @patterns = patterns.flat_map { |p| patterns_from(p, **options) } + end + + # @see Mustermann::Pattern#== + def ==(pattern) + patterns == patterns_from(pattern) + end + + # @see Mustermann::Pattern#eql? + def eql?(pattern) + patterns.eql? patterns_from(pattern) + end + + # @see Mustermann::Pattern#hash + def hash + patterns.hash | operator.hash + end + + # @see Mustermann::Pattern#=== + def ===(string) + patterns.map { |p| p === string }.inject(operator) + end + + # @see Mustermann::Pattern#params + def params(string) + with_matching(string, :params) + end + + # @see Mustermann::Pattern#match + def match(string) + with_matching(string, :match) + end + + # @!visibility private + def respond_to_special?(method) + return false unless operator == :| + patterns.all? { |p| p.respond_to?(method) } + end + + # (see Mustermann::Pattern#expand) + def expand(behavior = nil, values = {}) + raise NotImplementedError, 'expanding not supported' unless respond_to? :expand + @expander ||= Mustermann::Expander.new(*patterns) + @expander.expand(behavior, values) + end + + # (see Mustermann::Pattern#to_templates) + def to_templates + raise NotImplementedError, 'template generation not supported' unless respond_to? :to_templates + patterns.flat_map(&:to_templates).uniq + end + + # @return [String] the string representation of the pattern + def to_s + simple_inspect + end + + # @!visibility private + def inspect + "#<%p:%s>" % [self.class, simple_inspect] + end + + # @!visibility private + def simple_inspect + pattern_strings = patterns.map { |p| p.simple_inspect } + "(#{pattern_strings.join(" #{operator} ")})" + end + + # @!visibility private + def with_matching(string, method) + return unless self === string + pattern = patterns.detect { |p| p === string } + pattern.public_send(method, string) if pattern + end + + # @!visibility private + def patterns_from(pattern, **options) + return pattern.patterns if pattern.is_a? Composite and pattern.operator == self.operator + [options.empty? && pattern.is_a?(Pattern) ? pattern : Mustermann.new(pattern, **options)] + end + + private :with_matching, :patterns_from + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/concat.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/concat.rb new file mode 100644 index 00000000..7d38c566 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/concat.rb @@ -0,0 +1,136 @@ +# frozen_string_literal: true +module Mustermann + # Class for pattern objects that are a concatenation of other patterns. + # @see Mustermann::Pattern#+ + class Concat < Composite + # Mixin for patterns to support native concatenation. + # @!visibility private + module Native + # @see Mustermann::Pattern#+ + # @!visibility private + def +(other) + other &&= Mustermann.new(other, type: :identity, **options) + if (patterns = look_ahead(other)) && !patterns.empty? + concat = (self + patterns.inject(:+)) + concat + other.patterns.slice(patterns.length..-1).inject(:+) + else + return super unless native = native_concat(other) + self.class.new(native, **options) + end + end + + # @!visibility private + def look_ahead(other) + return unless other.is_a?(Concat) + other.patterns.take_while(&method(:native_concat?)) + end + + # @!visibility private + def native_concat(other) + "#{self}#{other}" if native_concat?(other) + end + + # @!visibility private + def native_concat?(other) + other.class == self.class and other.options == options + end + + private :native_concat, :native_concat? + end + + # Should not be used directly. + # @!visibility private + def initialize(*, **) + super + AST::Validation.validate(combined_ast) if respond_to? :expand + end + + # @see Mustermann::Composite#operator + # @return [Symbol] always :+ + def operator + :+ + end + + # @see Mustermann::Pattern#=== + def ===(string) + peek_size(string) == string.size + end + + # @see Mustermann::Pattern#match + def match(string) + peeked = peek_match(string) + peeked if peeked.to_s == string + end + + # @see Mustermann::Pattern#params + def params(string) + params, size = peek_params(string) + params if size == string.size + end + + # @see Mustermann::Pattern#peek_size + def peek_size(string) + pump(string) { |p,s| p.peek_size(s) } + end + + # @see Mustermann::Pattern#peek_match + def peek_match(string) + pump(string, initial: SimpleMatch.new) do |pattern, substring| + return unless match = pattern.peek_match(substring) + [match, match.to_s.size] + end + end + + # @see Mustermann::Pattern#peek_params + def peek_params(string) + pump(string, inject_with: :merge, with_size: true) { |p, s| p.peek_params(s) } + end + + # (see Mustermann::Pattern#expand) + def expand(behavior = nil, values = {}) + raise NotImplementedError, 'expanding not supported' unless respond_to? :expand + @expander ||= Mustermann::Expander.new(self) { combined_ast } + @expander.expand(behavior, values) + end + + # (see Mustermann::Pattern#to_templates) + def to_templates + raise NotImplementedError, 'template generation not supported' unless respond_to? :to_templates + @to_templates ||= patterns.inject(['']) { |list, pattern| list.product(pattern.to_templates).map(&:join) }.uniq + end + + # @!visibility private + def respond_to_special?(method) + method = :to_ast if method.to_sym == :expand + patterns.all? { |p| p.respond_to?(method) } + end + + # used to generate results for various methods by scanning through an input string + # @!visibility private + def pump(string, inject_with: :+, initial: nil, with_size: false) + substring = string + results = Array(initial) + + patterns.each do |pattern| + result, size = yield(pattern, substring) + return unless result + results << result + size ||= result + substring = substring[size..-1] + end + + results = results.inject(inject_with) + with_size ? [results, string.size - substring.size] : results + end + + # generates one big AST from all patterns + # will not check if patterns support AST generation + # @!visibility private + def combined_ast + payload = patterns.map { |p| AST::Node[:group].new(p.to_ast.payload) } + AST::Node[:root].new(payload) + end + + private :combined_ast, :pump + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/equality_map.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/equality_map.rb new file mode 100644 index 00000000..8ec4cf30 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/equality_map.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true +module Mustermann + # A simple wrapper around ObjectSpace::WeakMap that allows matching keys by equality rather than identity. + # Used for caching. Note that `fetch` is not guaranteed to return the object, even if it has not been + # garbage collected yet, especially when used concurrently. Therefore, the block passed to `fetch` has to + # be idempotent. + # + # @example + # class ExpensiveComputation + # @map = Mustermann::EqualityMap.new + # + # def self.new(*args) + # @map.fetch(args) { super } + # end + # end + # + # @see #fetch + class EqualityMap + attr_reader :map + + def self.new + defined?(ObjectSpace::WeakMap) ? super : {} + end + + def initialize + @keys = {} + @map = ObjectSpace::WeakMap.new + end + + # @param [#hash] key for caching + # @yield block that will be called to populate entry if missing (has to be idempotent) + # @return value stored in map or result of block + def fetch(key) + identity = @keys[key.hash] + if identity == key + key = identity + elsif key.frozen? + key = key.dup + end + + # it is ok that this is not thread-safe, worst case it has double cost in + # generating, object equality is not guaranteed anyways + @map[key] ||= track(key, yield) + end + + # @param [#hash] key for identifying the object + # @param [Object] object to be stored + # @return [Object] same as the second parameter + def track(key, object) + object = object.dup if object.frozen? + ObjectSpace.define_finalizer(object, finalizer(key.hash)) + @keys[key.hash] = key + object + end + + # Finalizer proc needs to be generated in different scope so it doesn't keep a reference to the object. + # + # @param [Integer] hash for key + # @return [Proc] finalizer callback + def finalizer(hash) + proc { @keys.delete(hash) } + end + + private :track, :finalizer + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/error.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/error.rb new file mode 100644 index 00000000..d1fd52e3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/error.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true +module Mustermann + unless defined?(Mustermann::Error) + Error = Class.new(StandardError) # Raised if anything goes wrong while generating a {Pattern}. + CompileError = Class.new(Error) # Raised if anything goes wrong while compiling a {Pattern}. + ParseError = Class.new(Error) # Raised if anything goes wrong while parsing a {Pattern}. + ExpandError = Class.new(Error) # Raised if anything goes wrong while expanding a {Pattern}. + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/expander.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/expander.rb new file mode 100644 index 00000000..fe8cc293 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/expander.rb @@ -0,0 +1,209 @@ +# frozen_string_literal: true +require 'mustermann/ast/expander' +require 'mustermann/caster' +require 'mustermann' + +module Mustermann + # Allows fine-grained control over pattern expansion. + # + # @example + # expander = Mustermann::Expander.new(additional_values: :append) + # expander << "/users/:user_id" + # expander << "/pages/:page_id" + # + # expander.expand(page_id: 58, format: :html5) # => "/pages/58?format=html5" + class Expander + attr_reader :patterns, :additional_values, :caster + + # @param [Array<#to_str, Mustermann::Pattern>] patterns list of patterns to expand, see {#add}. + # @param [Symbol] additional_values behavior when encountering additional values, see {#expand}. + # @param [Hash] options used when creating/expanding patterns, see {Mustermann.new}. + def initialize(*patterns, additional_values: :raise, **options, &block) + unless additional_values == :raise or additional_values == :ignore or additional_values == :append + raise ArgumentError, "Illegal value %p for additional_values" % additional_values + end + + @patterns = [] + @api_expander = AST::Expander.new + @additional_values = additional_values + @options = options + @caster = Caster.new + add(*patterns, &block) + end + + # Add patterns to expand. + # + # @example + # expander = Mustermann::Expander.new + # expander.add("/:a.jpg", "/:b.png") + # expander.expand(a: "pony") # => "/pony.jpg" + # + # @param [Array<#to_str, Mustermann::Pattern>] patterns list of to add for expansion, Strings will be compiled to patterns. + # @return [Mustermann::Expander] the expander + def add(*patterns) + patterns.each do |pattern| + pattern = Mustermann.new(pattern, **@options) + if block_given? + @api_expander.add(yield(pattern)) + else + raise NotImplementedError, "expanding not supported for #{pattern.class}" unless pattern.respond_to? :to_ast + @api_expander.add(pattern.to_ast) + end + @patterns << pattern + end + self + end + + alias_method :<<, :add + + # Register a block as simple hash transformation that runs before expanding the pattern. + # @return [Mustermann::Expander] the expander + # + # @overload cast + # Register a block as simple hash transformation that runs before expanding the pattern for all entries. + # + # @example casting everything that implements to_param to param + # expander.cast { |o| o.to_param if o.respond_to? :to_param } + # + # @yield every key/value pair + # @yieldparam key [Symbol] omitted if block takes less than 2 + # @yieldparam value [Object] omitted if block takes no arguments + # @yieldreturn [Hash{Symbol: Object}] will replace key/value pair with returned hash + # @yieldreturn [nil, false] will keep key/value pair in hash + # @yieldreturn [Object] will replace value with returned object + # + # @overload cast(*type_matchers) + # Register a block as simple hash transformation that runs before expanding the pattern for certain entries. + # + # @example convert user to user_id + # expander = Mustermann::Expander.new('/users/:user_id') + # expand.cast(:user) { |user| { user_id: user.id } } + # + # expand.expand(user: User.current) # => "/users/42" + # + # @example convert user, page, image to user_id, page_id, image_id + # expander = Mustermann::Expander.new('/users/:user_id', '/pages/:page_id', '/:image_id.jpg') + # expand.cast(:user, :page, :image) { |key, value| { "#{key}_id".to_sym => value.id } } + # + # expand.expand(user: User.current) # => "/users/42" + # + # @example casting to multiple key/value pairs + # expander = Mustermann::Expander.new('/users/:user_id/:image_id.:format') + # expander.cast(:image) { |i| { user_id: i.owner.id, image_id: i.id, format: i.format } } + # + # expander.expander(image: User.current.avatar) # => "/users/42/avatar.jpg" + # + # @example casting all ActiveRecord objects to param + # expander.cast(ActiveRecord::Base, &:to_param) + # + # @param [Array] type_matchers + # To identify key/value pairs to match against. + # Regexps and Symbols match against key, everything else matches against value. + # + # @yield every key/value pair + # @yieldparam key [Symbol] omitted if block takes less than 2 + # @yieldparam value [Object] omitted if block takes no arguments + # @yieldreturn [Hash{Symbol: Object}] will replace key/value pair with returned hash + # @yieldreturn [nil, false] will keep key/value pair in hash + # @yieldreturn [Object] will replace value with returned object + # + # @overload cast(*cast_objects) + # + # @param [Array<#cast>] cast_objects + # Before expanding, will call #cast on these objects for each key/value pair. + # Return value will be treated same as block return values described above. + def cast(*types, &block) + caster.register(*types, &block) + self + end + + # @example Expanding a pattern + # pattern = Mustermann::Expander.new('/:name', '/:name.:ext') + # pattern.expand(name: 'hello') # => "/hello" + # pattern.expand(name: 'hello', ext: 'png') # => "/hello.png" + # + # @example Handling additional values + # pattern = Mustermann::Expander.new('/:name', '/:name.:ext') + # pattern.expand(:ignore, name: 'hello', ext: 'png', scale: '2x') # => "/hello.png" + # pattern.expand(:append, name: 'hello', ext: 'png', scale: '2x') # => "/hello.png?scale=2x" + # pattern.expand(:raise, name: 'hello', ext: 'png', scale: '2x') # raises Mustermann::ExpandError + # + # @example Setting additional values behavior for the expander object + # pattern = Mustermann::Expander.new('/:name', '/:name.:ext', additional_values: :append) + # pattern.expand(name: 'hello', ext: 'png', scale: '2x') # => "/hello.png?scale=2x" + # + # @param [Symbol] behavior + # What to do with additional key/value pairs not present in the values hash. + # Possible options: :raise, :ignore, :append. + # + # @param [Hash{Symbol: #to_s, Array<#to_s>}] values + # Values to use for expansion. + # + # @return [String] expanded string + # @raise [NotImplementedError] raised if expand is not supported. + # @raise [Mustermann::ExpandError] raised if a value is missing or unknown + def expand(behavior = nil, values = {}) + behavior, values = nil, behavior if behavior.is_a? Hash + values = map_values(values) + + case behavior || additional_values + when :raise then @api_expander.expand(values) + when :ignore then with_rest(values) { |uri, rest| uri } + when :append then with_rest(values) { |uri, rest| append(uri, rest) } + else raise ArgumentError, "unknown behavior %p" % behavior + end + end + + # @see Object#== + def ==(other) + return false unless other.class == self.class + other.patterns == patterns and other.additional_values == additional_values + end + + # @see Object#eql? + def eql?(other) + return false unless other.class == self.class + other.patterns.eql? patterns and other.additional_values.eql? additional_values + end + + # @see Object#hash + def hash + patterns.hash + additional_values.hash + end + + def expandable?(values) + return false unless values + expandable, _ = split_values(map_values(values)) + @api_expander.expandable? expandable + end + + def with_rest(values) + expandable, non_expandable = split_values(values) + yield expand(:raise, slice(values, expandable)), slice(values, non_expandable) + end + + def split_values(values) + expandable = @api_expander.expandable_keys(values.keys) + non_expandable = values.keys - expandable + [expandable, non_expandable] + end + + def slice(hash, keys) + Hash[keys.map { |k| [k, hash[k]] }] + end + + def append(uri, values) + return uri unless values and values.any? + entries = values.map { |pair| pair.map { |e| @api_expander.escape(e, also_escape: /[\/\?#\&\=%]/) }.join(?=) } + "#{ uri }#{ uri[??]??&:?? }#{ entries.join(?&) }" + end + + def map_values(values) + values = values.dup + @api_expander.keys.each { |key| values[key] ||= values.delete(key.to_s) if values.include? key.to_s } + caster.cast(values).delete_if { |k, v| v.nil? } + end + + private :with_rest, :slice, :append, :caster, :map_values, :split_values + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/extension.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/extension.rb new file mode 100644 index 00000000..29ad7c97 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/extension.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +fail "Mustermann extension for Sinatra has been extracted into its own gem. More information at https://github.com/sinatra/mustermann-sinatra-extension" diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/identity.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/identity.rb new file mode 100644 index 00000000..8045e674 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/identity.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true +require 'mustermann' +require 'mustermann/pattern' +require 'mustermann/ast/node' + +module Mustermann + # Matches strings that are identical to the pattern. + # + # @example + # Mustermann.new('/:foo', type: :identity) === '/bar' # => false + # + # @see Mustermann::Pattern + # @see file:README.md#identity Syntax description in the README + class Identity < Pattern + include Concat::Native + register :identity + + # @param (see Mustermann::Pattern#===) + # @return (see Mustermann::Pattern#===) + # @see (see Mustermann::Pattern#===) + def ===(string) + unescape(string) == @string + end + + # @param (see Mustermann::Pattern#peek_size) + # @return (see Mustermann::Pattern#peek_size) + # @see (see Mustermann::Pattern#peek_size) + def peek_size(string) + return unless unescape(string).start_with? @string + return @string.size if string.start_with? @string # optimization + @string.each_char.with_index.inject(0) do |count, (char, index)| + char_size = 1 + escaped = @@uri.escape(char, /./) + char_size = escaped.size if string[index, escaped.size].downcase == escaped.downcase + count + char_size + end + end + + # URI templates support generating templates (the logic is quite complex, though). + # + # @example (see Mustermann::Pattern#to_templates) + # @param (see Mustermann::Pattern#to_templates) + # @return (see Mustermann::Pattern#to_templates) + # @see Mustermann::Pattern#to_templates + def to_templates + [@@uri.escape(to_s)] + end + + # Generates an AST so it's compatible with {Mustermann::AST::Pattern}. + # Not used internally by {Mustermann::Identity}. + # @!visibility private + def to_ast + payload = @string.each_char.with_index.map { |c, i| AST::Node[c == ?/ ? :separator : :char].new(c, start: i, stop: i+1) } + AST::Node[:root].new(payload, pattern: @string, start: 0, stop: @string.length) + end + + # Identity patterns support expanding. + # + # This implementation does not use {Mustermann::Expander} internally to save memory and + # compilation time. + # + # @example (see Mustermann::Pattern#expand) + # @param (see Mustermann::Pattern#expand) + # @return (see Mustermann::Pattern#expand) + # @raise (see Mustermann::Pattern#expand) + # @see Mustermann::Pattern#expand + # @see Mustermann::Expander + def expand(behavior = nil, values = {}) + return to_s if values.empty? or behavior == :ignore + raise ExpandError, "cannot expand with keys %p" % values.keys.sort if behavior == :raise + raise ArgumentError, "unknown behavior %p" % behavior if behavior != :append + params = values.map { |key, value| @@uri.escape(key.to_s) + "=" + @@uri.escape(value.to_s, /[^\w]/) } + separator = @string.include?(??) ? ?& : ?? + @string + separator + params.join(?&) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/mapper.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/mapper.rb new file mode 100644 index 00000000..d2cc5f5e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/mapper.rb @@ -0,0 +1,91 @@ +# frozen_string_literal: true +require 'mustermann' +require 'mustermann/expander' + +module Mustermann + # A mapper allows mapping one string to another based on pattern parsing and expanding. + # + # @example + # require 'mustermann/mapper' + # mapper = Mustermann::Mapper.new("/:foo" => "/:foo.html") + # mapper['/example'] # => "/example.html" + class Mapper + # Creates a new mapper. + # + # @overload initialize(**options) + # @param options [Hash] options The options hash + # @yield block for generating mappings as a hash + # @yieldreturn [Hash] see {#update} + # + # @example + # require 'mustermann/mapper' + # Mustermann::Mapper.new(type: :rails) {{ + # "/:foo" => ["/:foo.html", "/:foo.:format"] + # }} + # + # @overload initialize(**options) + # @param options [Hash] options The options hash + # @yield block for generating mappings as a hash + # @yieldparam mapper [Mustermann::Mapper] the mapper instance + # + # @example + # require 'mustermann/mapper' + # Mustermann::Mapper.new(type: :rails) do |mapper| + # mapper["/:foo"] = ["/:foo.html", "/:foo.:format"] + # end + # + # @overload initialize(map = {}, **options) + # @param map [Hash] see {#update} + # @param [Hash] options The options hash + # + # @example map before options + # require 'mustermann/mapper' + # Mustermann::Mapper.new({"/:foo" => "/:foo.html"}, type: :rails) + def initialize(map = {}, additional_values: :ignore, **options, &block) + @map = [] + @options = options + @additional_values = additional_values + block.arity == 0 ? update(yield) : yield(self) if block + update(map) if map + end + + # Add multiple mappings. + # + # @param map [Hash{String, Pattern: String, Pattern, Arry, Expander}] the mapping + def update(map) + map.to_h.each_pair do |input, output| + input = Mustermann.new(input, **@options) + output = Expander.new(*output, additional_values: @additional_values, **@options) unless output.is_a? Expander + @map << [input, output] + end + end + + # @return [Hash{Patttern: Expander}] Hash version of the mapper. + def to_h + Hash[@map] + end + + # Convert a string according to mappings. You can pass in additional params. + # + # @example mapping with and without additional parameters + # mapper = Mustermann::Mapper.new("/:example" => "(/:prefix)?/:example.html") + # + def convert(input, values = {}) + @map.inject(input) do |current, (pattern, expander)| + params = pattern.params(current) + params &&= Hash[values.merge(params).map { |k,v| [k.to_s, v] }] + expander.expandable?(params) ? expander.expand(params) : current + end + end + + # Add a single mapping. + # + # @param key [String, Pattern] format of the input string + # @param value [String, Pattern, Arry, Expander] format of the output string + def []=(key, value) + update key => value + end + + alias_method :[], :convert + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/pattern.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/pattern.rb new file mode 100644 index 00000000..f9ecd01e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/pattern.rb @@ -0,0 +1,398 @@ +# frozen_string_literal: true +require 'mustermann/error' +require 'mustermann/simple_match' +require 'mustermann/equality_map' +require 'uri' + +module Mustermann + # Superclass for all pattern implementations. + # @abstract + class Pattern + include Mustermann + @@uri ||= URI::RFC2396_Parser.new + + # List of supported options. + # + # @overload supported_options + # @return [Array] list of supported options + # @overload supported_options(*list) + # Adds options to the list. + # + # @api private + # @param [Symbol] *list adds options to the list of supported options + # @return [Array] list of supported options + def self.supported_options(*list) + @supported_options ||= [] + options = @supported_options.concat(list) + options += superclass.supported_options if self < Pattern + options + end + + # Registers the pattern with Mustermann. + # @see Mustermann.register + # @!visibility private + def self.register(*names) + names.each { |name| Mustermann.register(name, self) } + end + + # @param [Symbol] option The option to check. + # @return [Boolean] Whether or not option is supported. + def self.supported?(option, **options) + supported_options.include? option + end + + # @overload new(string, **options) + # @param (see #initialize) + # @raise (see #initialize) + # @raise [ArgumentError] if some option is not supported + # @return [Mustermann::Pattern] a new instance of Mustermann::Pattern + # @see #initialize + def self.new(string, ignore_unknown_options: false, **options) + if ignore_unknown_options + options = options.select { |key, value| supported?(key, **options) if key != :ignore_unknown_options } + else + unsupported = options.keys.detect { |key| not supported?(key, **options) } + raise ArgumentError, "unsupported option %p for %p" % [unsupported, self] if unsupported + end + + @map ||= EqualityMap.new + @map.fetch([string, options]) { super(string, **options) { options } } + end + + supported_options :uri_decode, :ignore_unknown_options + attr_reader :uri_decode + + # options hash passed to new (with unsupported options removed) + # @!visibility private + attr_reader :options + + # @overload initialize(string, **options) + # @param [String] string the string representation of the pattern + # @param [Hash] options options for fine-tuning the pattern behavior + # @raise [Mustermann::Error] if the pattern can't be generated from the string + # @see file:README.md#Types_and_Options "Types and Options" in the README + # @see Mustermann.new + def initialize(string, uri_decode: true, **options) + @uri_decode = uri_decode + @string = string.to_s.dup + @options = yield.freeze if block_given? + end + + # @return [String] the string representation of the pattern + def to_s + @string.dup + end + + # @param [String] string The string to match against + # @return [MatchData, Mustermann::SimpleMatch, nil] MatchData or similar object if the pattern matches. + # @see http://ruby-doc.org/core-2.0/Regexp.html#method-i-match Regexp#match + # @see http://ruby-doc.org/core-2.0/MatchData.html MatchData + # @see Mustermann::SimpleMatch + def match(string) + SimpleMatch.new(string) if self === string + end + + # @param [String] string The string to match against + # @return [Integer, nil] nil if pattern does not match the string, zero if it does. + # @see http://ruby-doc.org/core-2.0/Regexp.html#method-i-3D-7E Regexp#=~ + def =~(string) + 0 if self === string + end + + # @param [String] string The string to match against + # @return [Boolean] Whether or not the pattern matches the given string + # @note Needs to be overridden by subclass. + # @see http://ruby-doc.org/core-2.0/Regexp.html#method-i-3D-3D-3D Regexp#=== + def ===(string) + raise NotImplementedError, 'subclass responsibility' + end + + # Used by Ruby internally for hashing. + # @return [Integer] same has value for patterns that are equal + def hash + self.class.hash | @string.hash | options.hash + end + + # Two patterns are considered equal if they are of the same type, have the same pattern string + # and the same options. + # @return [true, false] + def ==(other) + other.class == self.class and other.to_s == @string and other.options == options + end + + # Two patterns are considered equal if they are of the same type, have the same pattern string + # and the same options. + # @return [true, false] + def eql?(other) + other.class.eql?(self.class) and other.to_s.eql?(@string) and other.options.eql?(options) + end + + # Tries to match the pattern against the beginning of the string (as opposed to the full string). + # Will return the count of the matching characters if it matches. + # + # @example + # pattern = Mustermann.new('/:name') + # pattern.size("/Frank/Sinatra") # => 6 + # + # @param [String] string The string to match against + # @return [Integer, nil] the number of characters that match + def peek_size(string) + # this is a very naive, unperformant implementation + string.size.downto(0).detect { |s| self === string[0, s] } + end + + # Tries to match the pattern against the beginning of the string (as opposed to the full string). + # Will return the substring if it matches. + # + # @example + # pattern = Mustermann.new('/:name') + # pattern.peek("/Frank/Sinatra") # => "/Frank" + # + # @param [String] string The string to match against + # @return [String, nil] matched subsctring + def peek(string) + size = peek_size(string) + string[0, size] if size + end + + # Tries to match the pattern against the beginning of the string (as opposed to the full string). + # Will return a MatchData or similar instance for the matched substring. + # + # @example + # pattern = Mustermann.new('/:name') + # pattern.peek("/Frank/Sinatra") # => # + # + # @param [String] string The string to match against + # @return [MatchData, Mustermann::SimpleMatch, nil] MatchData or similar object if the pattern matches. + # @see #peek_params + def peek_match(string) + matched = peek(string) + match(matched) if matched + end + + # Tries to match the pattern against the beginning of the string (as opposed to the full string). + # Will return a two element Array with the params parsed from the substring as first entry and the length of + # the substring as second. + # + # @example + # pattern = Mustermann.new('/:name') + # params, _ = pattern.peek_params("/Frank/Sinatra") + # + # puts "Hello, #{params['name']}!" # Hello, Frank! + # + # @param [String] string The string to match against + # @return [Array, nil] Array with params hash and length of substing if matched, nil otherwise + def peek_params(string) + match = peek_match(string) + [params(captures: match), match.to_s.size] if match + end + + # @return [Hash{String: Array}] capture names mapped to capture index. + # @see http://ruby-doc.org/core-2.0/Regexp.html#method-i-named_captures Regexp#named_captures + def named_captures + {} + end + + # @return [Array] capture names. + # @see http://ruby-doc.org/core-2.0/Regexp.html#method-i-names Regexp#names + def names + [] + end + + # @param [String] string the string to match against + # @return [Hash{String: String, Array}, nil] Sinatra style params if pattern matches. + def params(string = nil, captures: nil, offset: 0) + return unless captures ||= match(string) + params = named_captures.map do |name, positions| + values = positions.map { |pos| map_param(name, captures[pos + offset]) }.flatten + values = values.first if values.size < 2 and not always_array? name + [name, values] + end + + Hash[params] + end + + # @note This method is only implemented by certain subclasses. + # + # @example Expanding a pattern + # pattern = Mustermann.new('/:name(.:ext)?') + # pattern.expand(name: 'hello') # => "/hello" + # pattern.expand(name: 'hello', ext: 'png') # => "/hello.png" + # + # @example Checking if a pattern supports expanding + # if pattern.respond_to? :expand + # pattern.expand(name: "foo") + # else + # warn "does not support expanding" + # end + # + # Expanding is supported by almost all patterns (notable exceptions are {Mustermann::Shell}, + # {Mustermann::Regular} and {Mustermann::Simple}). + # + # Union {Mustermann::Composite} patterns (with the | operator) support expanding if all + # patterns they are composed of also support it. + # + # @param (see Mustermann::Expander#expand) + # @return [String] expanded string + # @raise [NotImplementedError] raised if expand is not supported. + # @raise [Mustermann::ExpandError] raised if a value is missing or unknown + # @see Mustermann::Expander + def expand(behavior = nil, values = {}) + raise NotImplementedError, "expanding not supported by #{self.class}" + end + + # @note This method is only implemented by certain subclasses. + # + # Generates a list of URI template strings representing the pattern. + # + # Note that this transformation is lossy and the strings matching these + # templates might not match the pattern (and vice versa). + # + # This comes in quite handy since URI templates are not made for pattern matching. + # That way you can easily use a more precise template syntax and have it automatically + # generate hypermedia links for you. + # + # @example generating templates + # Mustermann.new("/:name").to_templates # => ["/{name}"] + # Mustermann.new("/:foo(@:bar)?/*baz").to_templates # => ["/{foo}@{bar}/{+baz}", "/{foo}/{+baz}"] + # Mustermann.new("/{name}", type: :template).to_templates # => ["/{name}"] + # + # @example generating templates from composite patterns + # pattern = Mustermann.new('/:name') + # pattern |= Mustermann.new('/{name}', type: :template) + # pattern |= Mustermann.new('/example/*nested') + # pattern.to_templates # => ["/{name}", "/example/{+nested}"] + # + # Template generation is supported by almost all patterns (notable exceptions are + # {Mustermann::Shell}, {Mustermann::Regular} and {Mustermann::Simple}). + # Union {Mustermann::Composite} patterns (with the | operator) support template generation + # if all patterns they are composed of also support it. + # + # @example Checking if a pattern supports expanding + # if pattern.respond_to? :to_templates + # pattern.to_templates + # else + # warn "does not support template generation" + # end + # + # @return [Array] list of URI templates + def to_templates + raise NotImplementedError, "template generation not supported by #{self.class}" + end + + # @overload |(other) + # Creates a pattern that matches any string matching either one of the patterns. + # If a string is supplied, it is treated as an identity pattern. + # + # @example + # pattern = Mustermann.new('/foo/:name') | Mustermann.new('/:first/:second') + # pattern === '/foo/bar' # => true + # pattern === '/fox/bar' # => true + # pattern === '/foo' # => false + # + # @overload &(other) + # Creates a pattern that matches any string matching both of the patterns. + # If a string is supplied, it is treated as an identity pattern. + # + # @example + # pattern = Mustermann.new('/foo/:name') & Mustermann.new('/:first/:second') + # pattern === '/foo/bar' # => true + # pattern === '/fox/bar' # => false + # pattern === '/foo' # => false + # + # @overload ^(other) + # Creates a pattern that matches any string matching exactly one of the patterns. + # If a string is supplied, it is treated as an identity pattern. + # + # @example + # pattern = Mustermann.new('/foo/:name') ^ Mustermann.new('/:first/:second') + # pattern === '/foo/bar' # => false + # pattern === '/fox/bar' # => true + # pattern === '/foo' # => false + # + # @param [Mustermann::Pattern, String] other the other pattern + # @return [Mustermann::Pattern] a composite pattern + def |(other) + Mustermann::Composite.new(self, other, operator: __callee__, type: :identity) + end + + alias_method :&, :| + alias_method :^, :| + + # @example + # require 'mustermann' + # prefix = Mustermann.new("/:prefix") + # about = prefix + "/about" + # about.params("/main/about") # => {"prefix" => "main"} + # + # Creates a concatenated pattern by combingin self with the other pattern supplied. + # Patterns of different types can be mixed. The availability of `to_templates` and + # `expand` depends on the patterns being concatenated. + # + # String input is treated as identity pattern. + # + # @param [Mustermann::Pattern, String] other pattern to be appended + # @return [Mustermann::Pattern] concatenated pattern + def +(other) + Concat.new(self, other, type: :identity) + end + + # @example + # pattern = Mustermann.new('/:a/:b') + # strings = ["foo/bar", "/foo/bar", "/foo/bar/"] + # strings.detect(&pattern) # => "/foo/bar" + # + # @return [Proc] proc wrapping {#===} + def to_proc + @to_proc ||= method(:===).to_proc + end + + # @!visibility private + # @return [Boolean] + # @see Object#respond_to? + def respond_to?(method, *args) + return super unless %i[expand to_templates].include? method + respond_to_special?(method) + end + + # @!visibility private + # @return [Boolean] + # @see #respond_to? + def respond_to_special?(method) + method(method).owner != Mustermann::Pattern + end + + # @!visibility private + def inspect + "#<%p:%p>" % [self.class, @string] + end + + # @!visibility private + def simple_inspect + type = self.class.name[/[^:]+$/].downcase + "%s:%p" % [type, @string] + end + + # @!visibility private + def map_param(key, value) + unescape(value, true) + end + + # @!visibility private + def unescape(string, decode = uri_decode) + return string unless decode and string + @@uri.unescape(string) + end + + # @!visibility private + ALWAYS_ARRAY = %w[splat captures] + + # @!visibility private + def always_array?(key) + ALWAYS_ARRAY.include? key + end + + private :unescape, :map_param, :respond_to_special? + private_constant :ALWAYS_ARRAY + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/pattern_cache.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/pattern_cache.rb new file mode 100644 index 00000000..cdab88df --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/pattern_cache.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true +require 'set' +require 'thread' +require 'mustermann' + +module Mustermann + # A simple, persistent cache for creating repositories. + # + # @example + # require 'mustermann/pattern_cache' + # cache = Mustermann::PatternCache.new + # + # # use this instead of Mustermann.new + # pattern = cache.create_pattern("/:name", type: :rails) + # + # @note + # {Mustermann::Pattern.new} (which is used by {Mustermann.new}) will reuse instances that have + # not yet been garbage collected. You only need an extra cache if you do not keep a reference to + # the patterns around. + # + # @api private + class PatternCache + # @param [Hash] pattern_options default options used for {#create_pattern} + def initialize(**pattern_options) + @cached = Set.new + @mutex = Mutex.new + @pattern_options = pattern_options + end + + # @param (see Mustermann.new) + # @return (see Mustermann.new) + # @raise (see Mustermann.new) + # @see Mustermann.new + def create_pattern(string, **pattern_options) + pattern = Mustermann.new(string, **pattern_options, **@pattern_options) + @mutex.synchronize { @cached.add(pattern) } unless @cached.include? pattern + pattern + end + + # Removes all pattern instances from the cache. + def clear + @mutex.synchronize { @cached.clear } + end + + # @return [Integer] number of currently cached patterns + def size + @mutex.synchronize { @cached.size } + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/regexp.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/regexp.rb new file mode 100644 index 00000000..66d995b0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/regexp.rb @@ -0,0 +1 @@ +require 'mustermann/regular' diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/regexp_based.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/regexp_based.rb new file mode 100644 index 00000000..b17113bb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/regexp_based.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true +require 'mustermann/pattern' +require 'forwardable' + +module Mustermann + # Superclass for patterns that internally compile to a regular expression. + # @see Mustermann::Pattern + # @abstract + class RegexpBased < Pattern + # @return [Regexp] regular expression equivalent to the pattern. + attr_reader :regexp + alias_method :to_regexp, :regexp + + # @param (see Mustermann::Pattern#initialize) + # @return (see Mustermann::Pattern#initialize) + # @see (see Mustermann::Pattern#initialize) + def initialize(string, **options) + super + regexp = compile(**options) + @peek_regexp = /\A#{regexp}/ + @regexp = /\A#{regexp}\Z/ + end + + # @param (see Mustermann::Pattern#peek_size) + # @return (see Mustermann::Pattern#peek_size) + # @see (see Mustermann::Pattern#peek_size) + def peek_size(string) + return unless match = peek_match(string) + match.to_s.size + end + + # @param (see Mustermann::Pattern#peek_match) + # @return (see Mustermann::Pattern#peek_match) + # @see (see Mustermann::Pattern#peek_match) + def peek_match(string) + @peek_regexp.match(string) + end + + extend Forwardable + def_delegators :regexp, :===, :=~, :match, :names, :named_captures + + def compile(**options) + raise NotImplementedError, 'subclass responsibility' + end + + private :compile + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/regular.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/regular.rb new file mode 100644 index 00000000..53b7c7e9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/regular.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true +require 'mustermann' +require 'mustermann/regexp_based' +require 'strscan' + +module Mustermann + # Regexp pattern implementation. + # + # @example + # Mustermann.new('/.*', type: :regexp) === '/bar' # => true + # + # @see Mustermann::Pattern + # @see file:README.md#simple Syntax description in the README + class Regular < RegexpBased + include Concat::Native + register :regexp, :regular + supported_options :check_anchors + + # @param (see Mustermann::Pattern#initialize) + # @return (see Mustermann::Pattern#initialize) + # @see (see Mustermann::Pattern#initialize) + def initialize(string, check_anchors: true, **options) + string = $1 if string.to_s =~ /\A\(\?\-mix\:(.*)\)\Z/ && string.inspect == "/#$1/" + string = string.source.gsub!(/(?] empty array for imitating MatchData interface + def names + @names.dup + end + + # @return [Array] empty array for imitating MatchData interface + def captures + @captures.dup + end + + # @return [nil] imitates MatchData interface + def [](*args) + args.map! do |arg| + next arg unless arg.is_a? Symbol or arg.is_a? String + names.index(arg.to_s) + end + @captures[*args] + end + + # @!visibility private + def +(other) + SimpleMatch.new(@string + other.to_s, + names: @names + other.names, + captures: @captures + other.captures) + end + + # @return [String] string representation + def inspect + "#<%p %p>" % [self.class, @string] + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/sinatra.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/sinatra.rb new file mode 100644 index 00000000..33fa870e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/sinatra.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true +require 'mustermann' +require 'mustermann/identity' +require 'mustermann/ast/pattern' +require 'mustermann/sinatra/parser' +require 'mustermann/sinatra/safe_renderer' +require 'mustermann/sinatra/try_convert' + +module Mustermann + # Sinatra 2.0 style pattern implementation. + # + # @example + # Mustermann.new('/:foo') === '/bar' # => true + # + # @see Mustermann::Pattern + # @see file:README.md#sinatra Syntax description in the README + class Sinatra < AST::Pattern + include Concat::Native + register :sinatra + + # Takes a string and espaces any characters that have special meaning for Sinatra patterns. + # + # @example + # require 'mustermann/sinatra' + # Mustermann::Sinatra.escape("/:name") # => "/\\:name" + # + # @param [#to_s] string the input string + # @return [String] the escaped string + def self.escape(string) + string.to_s.gsub(/[\?\(\)\*:\\\|\{\}]/) { |c| "\\#{c}" } + end + + # Tries to convert the given input object to a Sinatra pattern with the given options, without + # changing its parsing semantics. + # @return [Mustermann::Sinatra, nil] the converted pattern, if possible + # @!visibility private + def self.try_convert(input, **options) + TryConvert.convert(input, **options) + end + + # Creates a pattern that matches any string matching either one of the patterns. + # If a string is supplied, it is treated as a fully escaped Sinatra pattern. + # + # If the other pattern is also a Sintara pattern, it might join the two to a third + # sinatra pattern instead of generating a composite for efficiency reasons. + # + # This only happens if the sinatra pattern behaves exactly the same as a composite + # would in regards to matching, parsing, expanding and template generation. + # + # @example + # pattern = Mustermann.new('/foo/:name') | Mustermann.new('/:first/:second') + # pattern === '/foo/bar' # => true + # pattern === '/fox/bar' # => true + # pattern === '/foo' # => false + # + # @param [Mustermann::Pattern, String] other the other pattern + # @return [Mustermann::Pattern] a composite pattern + # @see Mustermann::Pattern#| + def |(other) + return super unless converted = self.class.try_convert(other, **options) + return super unless converted.names.empty? or names.empty? + self.class.new(safe_string + "|" + converted.safe_string, **options) + end + + # Generates a string represenation of the pattern that can safely be used for def interpolation + # without changing its semantics. + # + # @example + # require 'mustermann' + # unsafe = Mustermann.new("/:name") + # + # Mustermann.new("#{unsafe}bar").params("/foobar") # => { "namebar" => "foobar" } + # Mustermann.new("#{unsafe.safe_string}bar").params("/foobar") # => { "name" => "bar" } + # + # @return [String] string representatin of the pattern + def safe_string + @safe_string ||= SafeRenderer.translate(to_ast) + end + + # @!visibility private + def native_concat(other) + return unless converted = self.class.try_convert(other, **options) + safe_string + converted.safe_string + end + + private :native_concat + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/sinatra/parser.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/sinatra/parser.rb new file mode 100644 index 00000000..9dbb2162 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/sinatra/parser.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true +module Mustermann + class Sinatra < AST::Pattern + # Sinatra syntax definition. + # @!visibility private + class Parser < AST::Parser + on(nil, ??, ?)) { |c| unexpected(c) } + + on(?*) { |c| scan(/\w+/) ? node(:named_splat, buffer.matched) : node(:splat) } + on(?:) { |c| node(:capture) { scan(/\w+/) } } + on(?\\) { |c| node(:char, expect(/./)) } + on(?() { |c| node(:group) { read unless scan(?)) } } + on(?|) { |c| node(:or) } + + on ?{ do |char| + current_pos = buffer.pos + type = scan(?+) ? :named_splat : :capture + name = expect(/[\w\.]+/) + if type == :capture && scan(?|) + buffer.pos = current_pos + capture = proc do + start = pos + match = expect(/(?[^\|}]+)/) + node(:capture, match[:capture], start: start) + end + grouped_captures = node(:group, [capture[]]) do + if scan(?|) + [min_size(pos - 1, pos, node(:or)), capture[]] + end + end + grouped_captures if expect(?}) + else + type = :splat if type == :named_splat and name == 'splat' + expect(?}) + node(type, name) + end + end + + suffix ?? do |char, element| + node(:optional, element) + end + end + + private_constant :Parser + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/sinatra/safe_renderer.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/sinatra/safe_renderer.rb new file mode 100644 index 00000000..41a722f4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/sinatra/safe_renderer.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true +module Mustermann + class Sinatra < AST::Pattern + # Generates a string that can safely be concatenated with other strings + # without chaning its semantics + # @see #safe_string + # @!visibility private + SafeRenderer = AST::Translator.create do + translate(:splat, :named_splat) { "{+#{name}}" } + translate(:char, :separator) { Sinatra.escape(payload) } + translate(:root) { t(payload) } + translate(:group) { "(#{t(payload)})" } + translate(:union) { "(#{t(payload, join: ?|)})" } + translate(:optional) { "#{t(payload)}?" } + translate(:with_look_ahead) { t([head, payload]) } + translate(Array) { |join: ""| map { |e| t(e) }.join(join) } + + translate(:capture) do + raise Mustermann::Error, 'cannot render variables' if node.is_a? :variable + raise Mustermann::Error, 'cannot translate constraints' if constraint or qualifier or convert + prefix = node.is_a?(:splat) ? "+" : "" + "{#{prefix}#{name}}" + end + end + + private_constant :SafeRenderer + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/sinatra/try_convert.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/sinatra/try_convert.rb new file mode 100644 index 00000000..f45bcdaf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/sinatra/try_convert.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true +module Mustermann + class Sinatra < AST::Pattern + # Tries to translate objects to Sinatra patterns. + # @!visibility private + class TryConvert < AST::Translator + # @return [Mustermann::Sinatra, nil] + # @!visibility private + def self.convert(input, **options) + new(options).translate(input) + end + + # Expected options for the resulting pattern. + # @!visibility private + attr_reader :options + + # @!visibility private + def initialize(options) + @options = options + end + + # @return [Mustermann::Sinatra] + # @!visibility private + def new(input, escape = false) + input = Mustermann::Sinatra.escape(input) if escape + Mustermann::Sinatra.new(input, **options) + end + + # @return [true, false] whether or not expected pattern should have uri_decode option set + # @!visibility private + def uri_decode + options.fetch(:uri_decode, true) + end + + translate(Object) { nil } + translate(String) { t.new(self, true) } + + translate(Identity) { t.new(self, true) if uri_decode == t.uri_decode } + translate(Sinatra) { node if options == t.options } + + translate AST::Pattern do + next unless options == t.options + t.new(SafeRenderer.translate(to_ast)) rescue nil + end + end + + private_constant :TryConvert + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/to_pattern.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/to_pattern.rb new file mode 100644 index 00000000..2e418897 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/to_pattern.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true +require 'mustermann' + +module Mustermann + # Mixin for adding {#to_pattern} ducktyping to objects. + # + # @example + # require 'mustermann/to_pattern' + # + # class Foo + # include Mustermann::ToPattern + # + # def to_s + # ":foo/:bar" + # end + # end + # + # Foo.new.to_pattern # => # + # + # By default included into String, Symbol, Regexp, Array and {Mustermann::Pattern}. + module ToPattern + PRIMITIVES = [String, Symbol, Array, Regexp, Mustermann::Pattern] + private_constant :PRIMITIVES + + # Converts the object into a {Mustermann::Pattern}. + # + # @example converting a string + # ":name.png".to_pattern # => # + # + # @example converting a string with options + # "/*path".to_pattern(type: :rails) # => # + # + # @example converting a regexp + # /.*/.to_pattern # => # + # + # @example converting a pattern + # Mustermann.new("foo").to_pattern # => # + # + # @param [Hash] options The options hash. + # @return [Mustermann::Pattern] pattern corresponding to object. + def to_pattern(**options) + input = self if PRIMITIVES.any? { |p| self.is_a? p } + input ||= __getobj__ if respond_to?(:__getobj__) + Mustermann.new(input || to_s, **options) + end + + PRIMITIVES.each do |klass| + append_features(klass) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/version.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/version.rb new file mode 100644 index 00000000..d6f03380 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/lib/mustermann/version.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true +module Mustermann + VERSION ||= '3.0.3' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/mustermann.gemspec b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/mustermann.gemspec new file mode 100644 index 00000000..bbaf9114 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/mustermann.gemspec @@ -0,0 +1,18 @@ +$:.unshift File.expand_path("../lib", __FILE__) +require "mustermann/version" + +Gem::Specification.new do |s| + s.name = "mustermann" + s.version = Mustermann::VERSION + s.authors = ["Konstantin Haase", "Zachary Scott"] + s.email = "sinatrarb@googlegroups.com" + s.homepage = "https://github.com/sinatra/mustermann" + s.summary = %q{Your personal string matching expert.} + s.description = %q{A library implementing patterns that behave like regular expressions.} + s.license = 'MIT' + s.required_ruby_version = '>= 2.6.0' + s.files = `git ls-files`.split("\n") + s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") + + s.add_runtime_dependency('ruby2_keywords', '~> 0.0.1') +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/ast_spec.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/ast_spec.rb new file mode 100644 index 00000000..d04f58e6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/ast_spec.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true +require 'support' +require 'mustermann/ast/node' + +describe Mustermann::AST do + describe :type do + example { Mustermann::AST::Node[:char].type .should be == :char } + example { Mustermann::AST::Node[:char].new.type .should be == :char } + end + + describe :min_size do + example { Mustermann::AST::Node[:char].new.min_size.should be == 1 } + example { Mustermann::AST::Node[:node].new.min_size.should be == 0 } + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/composite_spec.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/composite_spec.rb new file mode 100644 index 00000000..bfc10ddd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/composite_spec.rb @@ -0,0 +1,163 @@ +# frozen_string_literal: true +require 'support' +require 'mustermann' + +describe Mustermann::Composite do + describe :new do + example 'with no argument' do + expect { Mustermann::Composite.new }. + to raise_error(ArgumentError, 'cannot create empty composite pattern') + end + + example 'with one argument' do + pattern = Mustermann.new('/foo') + Mustermann::Composite.new(pattern).should be == pattern + end + + example 'with supported type specific arguments' do + Mustermann::Composite.new("/a", "/b", greedy: true) + end + + example 'with unsupported type specific arguments' do + expect { Mustermann::Composite.new("/a", "/b", greedy: true, type: :identity) }.to raise_error(ArgumentError) + end + end + + context :| do + subject(:pattern) { Mustermann.new('/foo/:name', '/:first/:second') } + + describe :== do + example { subject.should be == subject } + example { subject.should be == Mustermann.new('/foo/:name', '/:first/:second') } + example { subject.should_not be == Mustermann.new('/foo/:name') } + example { subject.should_not be == Mustermann.new('/foo/:name', '/:first/:second', operator: :&) } + end + + describe :=== do + example { subject.should be === "/foo/bar" } + example { subject.should be === "/fox/bar" } + example { subject.should_not be === "/foo" } + end + + describe :params do + example { subject.params("/foo/bar") .should be == { "name" => "bar" } } + example { subject.params("/fox/bar") .should be == { "first" => "fox", "second" => "bar" } } + example { subject.params("/foo") .should be_nil } + end + + describe :=== do + example { subject.should match("/foo/bar") } + example { subject.should match("/fox/bar") } + example { subject.should_not match("/foo") } + end + + describe :expand do + example { subject.should respond_to(:expand) } + example { subject.expand(name: 'bar') .should be == '/foo/bar' } + example { subject.expand(first: 'fox', second: 'bar') .should be == '/fox/bar' } + + context "without expandable patterns" do + subject(:pattern) { Mustermann.new('/foo/:name', '/:first/:second', type: :simple) } + example { subject.should_not respond_to(:expand) } + example { expect { subject.expand(name: 'bar') }.to raise_error(NotImplementedError) } + end + end + + describe :to_templates do + example { should respond_to(:to_templates) } + example { should generate_templates('/foo/{name}', '/{first}/{second}') } + + context "without patterns implementing to_templates" do + subject(:pattern) { Mustermann.new('/foo/:name', '/:first/:second', type: :simple) } + example { should_not respond_to(:to_templates) } + example { expect { subject.to_templates }.to raise_error(NotImplementedError) } + end + end + + describe :eql? do + example { should be_eql(pattern) } + example { should be_eql(Mustermann.new('/foo/:name', '/:first/:second', operator: :|)) } + example { should_not be_eql(Mustermann.new('/bar/:name', '/:first/:second', operator: :|)) } + example { should_not be_eql(Mustermann.new('/foo/:name', '/:first/:second', operator: :&)) } + end + end + + context :& do + subject(:pattern) { Mustermann.new('/foo/:name', '/:first/:second', operator: :&) } + + describe :== do + example { subject.should be == subject } + example { subject.should be == Mustermann.new('/foo/:name', '/:first/:second', operator: :&) } + example { subject.should_not be == Mustermann.new('/foo/:name') } + example { subject.should_not be == Mustermann.new('/foo/:name', '/:first/:second') } + end + + describe :=== do + example { subject.should be === "/foo/bar" } + example { subject.should_not be === "/fox/bar" } + example { subject.should_not be === "/foo" } + end + + describe :params do + example { subject.params("/foo/bar") .should be == { "name" => "bar" } } + example { subject.params("/fox/bar") .should be_nil } + example { subject.params("/foo") .should be_nil } + end + + describe :match do + example { subject.should match("/foo/bar") } + example { subject.should_not match("/fox/bar") } + example { subject.should_not match("/foo") } + end + + describe :expand do + example { subject.should_not respond_to(:expand) } + example { expect { subject.expand(name: 'bar') }.to raise_error(NotImplementedError) } + end + end + + context :^ do + subject(:pattern) { Mustermann.new('/foo/:name', '/:first/:second', operator: :^) } + + describe :== do + example { subject.should be == subject } + example { subject.should_not be == Mustermann.new('/foo/:name', '/:first/:second') } + example { subject.should_not be == Mustermann.new('/foo/:name') } + example { subject.should_not be == Mustermann.new('/foo/:name', '/:first/:second', operator: :&) } + end + + describe :=== do + example { subject.should_not be === "/foo/bar" } + example { subject.should be === "/fox/bar" } + example { subject.should_not be === "/foo" } + end + + describe :params do + example { subject.params("/foo/bar") .should be_nil } + example { subject.params("/fox/bar") .should be == { "first" => "fox", "second" => "bar" } } + example { subject.params("/foo") .should be_nil } + end + + describe :match do + example { subject.should_not match("/foo/bar") } + example { subject.should match("/fox/bar") } + example { subject.should_not match("/foo") } + end + + describe :expand do + example { subject.should_not respond_to(:expand) } + example { expect { subject.expand(name: 'bar') }.to raise_error(NotImplementedError) } + end + end + + describe :inspect do + let(:sinatra) { Mustermann.new('x') } + let(:shell) { Mustermann.new('x', type: :shell) } + let(:identity) { Mustermann.new('x', type: :identity) } + + example { (sinatra | shell) .inspect.should include('(sinatra:"x" | shell:"x")') } + example { (sinatra ^ shell) .inspect.should include('(sinatra:"x" ^ shell:"x")') } + example { (sinatra | shell | identity) .inspect.should include('(sinatra:"x" | shell:"x" | identity:"x")') } + example { (sinatra | shell & identity) .inspect.should include('(sinatra:"x" | (shell:"x" & identity:"x"))') } + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/concat_spec.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/concat_spec.rb new file mode 100644 index 00000000..aea59a49 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/concat_spec.rb @@ -0,0 +1,127 @@ +# frozen_string_literal: true +require 'support' +require 'mustermann' + +describe Mustermann::Concat do + describe Mustermann::Concat::Native do + context "sinatra + sinatra" do + subject(:pattern) { Mustermann.new("/:foo") + Mustermann.new("/:bar") } + its(:class) { should be == Mustermann::Sinatra } + its(:to_s) { should be == "/{foo}/{bar}" } + end + + context "sinatra + string" do + subject(:pattern) { Mustermann.new("/:foo") + "/:bar" } + its(:class) { should be == Mustermann::Sinatra } + its(:to_s) { should be == "/{foo}/\\:bar" } + end + + context "regular + regular" do + subject(:pattern) { Mustermann.new(/foo/) + Mustermann.new(/bar/) } + its(:class) { should be == Mustermann::Regular } + its(:to_s) { should be == "foobar" } + end + + context "sinatra + rails" do + subject(:pattern) { Mustermann.new("/:foo") + Mustermann.new("/:bar", type: :rails) } + its(:class) { should be == Mustermann::Sinatra } + its(:to_s) { should be == "/{foo}/{bar}" } + end + + context "sinatra + flask" do + subject(:pattern) { Mustermann.new("/:foo") + Mustermann.new("/", type: :flask) } + its(:class) { should be == Mustermann::Sinatra } + its(:to_s) { should be == "/{foo}/{bar}" } + end + + context "sinatra + flask (typed)" do + subject(:pattern) { Mustermann.new("/:foo") + Mustermann.new("/", type: :flask) } + its(:class) { should be == Mustermann::Concat } + its(:to_s) { should be == '(sinatra:"/:foo" + flask:"/")' } + end + + context "sinatra + sinatra (different options)" do + subject(:pattern) { Mustermann.new("/:foo") + Mustermann.new("/:bar", uri_decode: false) } + its(:class) { should be == Mustermann::Concat } + its(:to_s) { should be == '(sinatra:"/:foo" + sinatra:"/:bar")' } + end + + context "sinatra + rails (different options)" do + subject(:pattern) { Mustermann.new("/:foo") + Mustermann.new("/:bar", type: :rails, uri_decode: false) } + its(:class) { should be == Mustermann::Concat } + its(:to_s) { should be == '(sinatra:"/:foo" + rails:"/:bar")' } + end + + context "sinatra + rails (different options) + sinatra" do + subject(:pattern) { Mustermann.new("/:foo") + Mustermann.new("/:bar", type: :rails, uri_decode: false) + Mustermann.new("/:baz") } + its(:class) { should be == Mustermann::Concat } + its(:to_s) { should be == '(sinatra:"/:foo" + rails:"/:bar" + sinatra:"/:baz")' } + end + + context "sinatra + (sinatra + regular)" do + subject(:pattern) { Mustermann.new("/foo") + (Mustermann.new("/bar") + Mustermann.new(/baz/)) } + its(:class) { should be == Mustermann::Concat } + its(:to_s) { should be == '(sinatra:"/foo/bar" + regular:"baz")' } + end + + context "sinatra + (sinatra + rails (different options) + sinatra)" do + subject(:pattern) { Mustermann.new("/foo") + (Mustermann.new("/bar") + Mustermann.new("/baz", type: :rails, uri_decode: false) + Mustermann.new("/boo")) } + its(:class) { should be == Mustermann::Concat } + its(:to_s) { should be == '(sinatra:"/foo/bar" + rails:"/baz" + sinatra:"/boo")' } + end + end + + subject(:pattern) { Mustermann::Concat.new("/:foo", "/:bar") } + + describe :=== do + example { (pattern === "/foo/bar") .should be true } + example { (pattern === "/foo/bar/") .should be false } + example { (pattern === "/foo") .should be false } + end + + describe :match do + it { should match("/foo/bar").capturing(foo: "foo", bar: "bar") } + it { should_not match("/foo/bar/") } + it { should_not match("/foo/") } + end + + describe :params do + example { pattern.params("/foo/bar") .should be == { "foo" => "foo", "bar" => "bar" }} + example { pattern.params("/foo/bar/") .should be_nil } + example { pattern.params("/foo") .should be_nil } + end + + describe :peek do + example { pattern.peek("/foo/bar/baz") .should be == "/foo/bar" } + example { pattern.peek("/foo") .should be_nil } + end + + describe :peek_params do + example { pattern.peek_params("/foo/bar/baz") .should be == [{ "foo" => "foo", "bar" => "bar" }, 8]} + example { pattern.peek_params("/foo") .should be_nil } + end + + describe :peek_match do + example { pattern.peek_match("/foo/bar/baz").to_s .should be == "/foo/bar" } + example { pattern.peek_match("/foo") .should be_nil } + end + + describe :peek_size do + example { pattern.peek_size("/foo/bar/baz") .should be == 8 } + example { pattern.peek_size("/foo") .should be_nil } + end + + describe :expand do + it { should expand(foo: :bar, bar: :foo) .to('/bar/foo') } + it { should expand(:append, foo: :bar, bar: :foo, baz: 42) .to('/bar/foo?baz=42') } + it { should_not expand(foo: :bar) } + end + + describe :to_templates do + subject(:pattern) { Mustermann::Concat.new("/:foo|:bar", "(/:baz)?") } + it { should generate_template("/{foo}/{baz}") } + it { should generate_template("{bar}/{baz}") } + it { should generate_template("/{foo}") } + it { should generate_template("{bar}") } + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/equality_map_spec.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/equality_map_spec.rb new file mode 100644 index 00000000..6aa982ce --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/equality_map_spec.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true +require 'support' +require 'mustermann/equality_map' + +RSpec.describe Mustermann::EqualityMap do + before { GC.disable } + after { GC.enable } + + describe :fetch do + subject { Mustermann::EqualityMap.new } + specify 'with existing entry' do + next if subject.is_a? Hash + subject.fetch("foo") { "foo" } + result = subject.fetch("foo") { "bar" } + expect(result).to be == "foo" + end + + specify 'with GC-removed entry' do + next if subject.is_a? Hash + subject.fetch(String.new('foo')) { "foo" } + expect(subject.map).to receive(:[]).and_return(nil) + result = subject.fetch(String.new('foo')) { "bar" } + expect(result).to be == "bar" + end + + specify 'allows a frozen key and value' do + next if subject.is_a? Hash + key = "foo".freeze + value = "bar".freeze + subject.fetch(key) { value } + result = subject.fetch("foo".dup) { raise "not executed" } + expect(result).to be == value + expect(result).not_to equal value + end + + specify 'allows only a single argument to be compatible with Hash#fetch' do + expect { + subject.fetch("foo", "bar", "baz") { "value" } + }.to raise_error(ArgumentError) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/expander_spec.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/expander_spec.rb new file mode 100644 index 00000000..ae418ea5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/expander_spec.rb @@ -0,0 +1,123 @@ +# frozen_string_literal: true +require 'support' +require 'mustermann/expander' + +describe Mustermann::Expander do + it 'expands a pattern' do + expander = Mustermann::Expander.new("/:foo.jpg") + expander.expand(foo: 42).should be == "/42.jpg" + end + + it 'expands multiple patterns' do + expander = Mustermann::Expander.new << "/:foo.:ext" << "/:foo" + expander.expand(foo: 42, ext: 'jpg').should be == "/42.jpg" + expander.expand(foo: 23).should be == "/23" + end + + it 'supports setting pattern options' do + expander = Mustermann::Expander.new(type: :rails) << "/:foo(.:ext)" << "/:bar" + expander.expand(foo: 42, ext: 'jpg').should be == "/42.jpg" + expander.expand(foo: 42).should be == "/42" + end + + it 'supports combining different pattern styles' do + expander = Mustermann::Expander.new << Mustermann.new("/:foo(.:ext)", type: :rails) << Mustermann.new("/:bar", type: :sinatra) + expander.expand(foo: 'pony', ext: 'jpg').should be == '/pony.jpg' + expander.expand(bar: 23).should be == "/23" + end + + it 'ignores nil values' do + expander = Mustermann::Expander.new << Mustermann.new("/:foo(.:ext)?") + expander.expand(foo: 'pony', ext: nil).should be == '/pony' + end + + it 'supports splat' do + expander = Mustermann::Expander.new << Mustermann.new("/foo/*/baz") + expander.expand(splat: 'bar').should be == '/foo/bar/baz' + end + + it 'supports multiple splats' do + expander = Mustermann::Expander.new << Mustermann.new("/foo/*/bar/*") + expander.expand(splat: [123, 456]).should be == '/foo/123/bar/456' + end + + it 'supports identity patterns' do + expander = Mustermann::Expander.new('/:foo', type: :identity) + expander.expand.should be == '/:foo' + end + + describe :additional_values do + context "illegal value" do + example { expect { Mustermann::Expander.new(additional_values: :foo) }.to raise_error(ArgumentError) } + example { expect { Mustermann::Expander.new('/').expand(:foo, a: 10) }.to raise_error(ArgumentError) } + end + + context :raise do + subject(:expander) { Mustermann::Expander.new('/:a', additional_values: :raise) } + example { expander.expand(a: ?a).should be == '/a' } + example { expect { expander.expand(a: ?a, b: ?b) }.to raise_error(Mustermann::ExpandError) } + example { expect { expander.expand(b: ?b) }.to raise_error(Mustermann::ExpandError) } + end + + context :ignore do + subject(:expander) { Mustermann::Expander.new('/:a', additional_values: :ignore) } + example { expander.expand(a: ?a).should be == '/a' } + example { expander.expand(a: ?a, b: ?b).should be == '/a' } + example { expect { expander.expand(b: ?b) }.to raise_error(Mustermann::ExpandError) } + example { expect { expander.expand(b: ?b, c: []) }.to raise_error(Mustermann::ExpandError) } + example { expect { expander.expand(b: ?b, c: [], d: ?d) }.to raise_error(Mustermann::ExpandError) } + end + + context :append do + subject(:expander) { Mustermann::Expander.new('/:a', additional_values: :append) } + example { expander.expand(a: ?a).should be == '/a' } + example { expander.expand(a: ?a, b: ?b).should be == '/a?b=b' } + example { expect { expander.expand(b: ?b) }.to raise_error(Mustermann::ExpandError) } + end + end + + describe :cast do + subject(:expander) { Mustermann::Expander.new('/:a(/:b)?') } + + example { expander.cast { "FOOBAR" }.expand(a: "foo") .should be == "/FOOBAR" } + example { expander.cast { |v| v.upcase }.expand(a: "foo") .should be == "/FOO" } + example { expander.cast { |v| v.upcase }.expand(a: "foo", b: "bar") .should be == "/FOO/BAR" } + example { expander.cast(:a) { |v| v.upcase }.expand(a: "foo", b: "bar") .should be == "/FOO/bar" } + example { expander.cast(:a, :b) { |v| v.upcase }.expand(a: "foo", b: "bar") .should be == "/FOO/BAR" } + example { expander.cast(Integer) { |k,v| "#{k}_#{v}" }.expand(a: "foo", b: 42) .should be == "/foo/b_42" } + + example do + expander.cast(:a) { |v| v.upcase } + expander.cast(:b) { |v| v.downcase } + expander.expand(a: "fOo", b: "bAr").should be == "/FOO/bar" + end + end + + describe :== do + example { Mustermann::Expander.new('/foo') .should be == Mustermann::Expander.new('/foo') } + example { Mustermann::Expander.new('/foo') .should_not be == Mustermann::Expander.new('/bar') } + example { Mustermann::Expander.new('/foo', type: :rails) .should be == Mustermann::Expander.new('/foo', type: :rails) } + example { Mustermann::Expander.new('/foo', type: :rails) .should_not be == Mustermann::Expander.new('/foo', type: :sinatra) } + end + + describe :hash do + example { Mustermann::Expander.new('/foo') .hash.should be == Mustermann::Expander.new('/foo').hash } + example { Mustermann::Expander.new('/foo') .hash.should_not be == Mustermann::Expander.new('/bar').hash } + example { Mustermann::Expander.new('/foo', type: :rails) .hash.should be == Mustermann::Expander.new('/foo', type: :rails).hash } + example { Mustermann::Expander.new('/foo', type: :rails) .hash.should_not be == Mustermann::Expander.new('/foo', type: :sinatra).hash } + end + + describe :eql? do + example { Mustermann::Expander.new('/foo') .should be_eql Mustermann::Expander.new('/foo') } + example { Mustermann::Expander.new('/foo') .should_not be_eql Mustermann::Expander.new('/bar') } + example { Mustermann::Expander.new('/foo', type: :rails) .should be_eql Mustermann::Expander.new('/foo', type: :rails) } + example { Mustermann::Expander.new('/foo', type: :rails) .should_not be_eql Mustermann::Expander.new('/foo', type: :sinatra) } + end + + describe :equal? do + example { Mustermann::Expander.new('/foo') .should_not be_equal Mustermann::Expander.new('/foo') } + example { Mustermann::Expander.new('/foo') .should_not be_equal Mustermann::Expander.new('/bar') } + example { Mustermann::Expander.new('/foo', type: :rails) .should_not be_equal Mustermann::Expander.new('/foo', type: :rails) } + example { Mustermann::Expander.new('/foo', type: :rails) .should_not be_equal Mustermann::Expander.new('/foo', type: :sinatra) } + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/identity_spec.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/identity_spec.rb new file mode 100644 index 00000000..6873df84 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/identity_spec.rb @@ -0,0 +1,127 @@ +# frozen_string_literal: true +require 'support' +require 'mustermann/identity' + +describe Mustermann::Identity do + extend Support::Pattern + + pattern '' do + it { should match('') } + it { should_not match('/') } + + it { should respond_to(:expand) } + it { should respond_to(:to_templates) } + + + it { should generate_template('') } + it { should expand.to('') } + it { should expand(:ignore, a: 10).to('') } + it { should expand(:append, a: 10).to('?a=10') } + it { should_not expand(:raise, a: 10) } + it { should_not expand(a: 10) } + + example do + pattern.match('').inspect.should be == '#' + end + end + + pattern '/' do + it { should match('/') } + it { should_not match('/foo') } + + example { pattern.params('/').should be == {} } + example { pattern.params('').should be_nil } + + it { should generate_template('/') } + it { should expand.to('/') } + end + + pattern '/foo' do + it { should match('/foo') } + it { should_not match('/bar') } + it { should_not match('/foo.bar') } + end + + pattern '/foo/bar' do + it { should match('/foo/bar') } + it { should match('/foo%2Fbar') } + it { should match('/foo%2fbar') } + end + + pattern '/:foo' do + it { should match('/:foo') } + it { should match('/%3Afoo') } + it { should_not match('/foo') } + it { should_not match('/foo?') } + it { should_not match('/foo/bar') } + it { should_not match('/') } + it { should_not match('/foo/') } + + it { should generate_template('/:foo') } + it { should expand.to('/:foo') } + end + + pattern '/föö' do + it { should match("/f%C3%B6%C3%B6") } + end + + pattern '/test$/' do + it { should match('/test$/') } + end + + pattern '/te+st/' do + it { should match('/te+st/') } + it { should_not match('/test/') } + it { should_not match('/teest/') } + end + + pattern "/path with spaces" do + it { should match('/path%20with%20spaces') } + it { should_not match('/path%2Bwith%2Bspaces') } + it { should_not match('/path+with+spaces') } + it { should generate_template('/path%20with%20spaces') } + end + + pattern '/foo&bar' do + it { should match('/foo&bar') } + end + + pattern '/test.bar' do + it { should match('/test.bar') } + it { should_not match('/test0bar') } + end + + pattern '/foo/bar', uri_decode: false do + it { should match('/foo/bar') } + it { should_not match('/foo%2Fbar') } + it { should_not match('/foo%2fbar') } + end + + pattern "/path with spaces", uri_decode: false do + it { should_not match('/path%20with%20spaces') } + it { should_not match('/path%2Bwith%2Bspaces') } + it { should_not match('/path+with+spaces') } + end + + context "peeking" do + subject(:pattern) { Mustermann::Identity.new("foo bar") } + + describe :peek_size do + example { pattern.peek_size("foo bar blah") .should be == "foo bar".size } + example { pattern.peek_size("foo%20bar blah") .should be == "foo%20bar".size } + example { pattern.peek_size("foobar") .should be_nil } + end + + describe :peek_match do + example { pattern.peek_match("foo bar blah").to_s .should be == "foo bar" } + example { pattern.peek_match("foo%20bar blah").to_s .should be == "foo%20bar" } + example { pattern.peek_match("foobar") .should be_nil } + end + + describe :peek_params do + example { pattern.peek_params("foo bar blah") .should be == [{}, "foo bar".size] } + example { pattern.peek_params("foo%20bar blah") .should be == [{}, "foo%20bar".size] } + example { pattern.peek_params("foobar") .should be_nil } + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/mapper_spec.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/mapper_spec.rb new file mode 100644 index 00000000..ced3eca6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/mapper_spec.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true +require 'support' +require 'mustermann/mapper' + +describe Mustermann::Mapper do + describe :initialize do + context 'accepts a block with no arguments, using the return value' do + subject(:mapper) { Mustermann::Mapper.new(additional_values: :raise) {{ "/foo" => "/bar" }}} + its(:to_h) { should be == { Mustermann.new("/foo") => Mustermann::Expander.new("/bar") } } + example { mapper['/foo'].should be == '/bar' } + example { mapper['/fox'].should be == '/fox' } + end + + context 'accepts a block with argument, passes instance to it' do + subject(:mapper) { Mustermann::Mapper.new(additional_values: :raise) { |m| m["/foo"] = "/bar" }} + its(:to_h) { should be == { Mustermann.new("/foo") => Mustermann::Expander.new("/bar") } } + example { mapper['/foo'].should be == '/bar' } + example { mapper['/fox'].should be == '/fox' } + end + + context 'accepts mappings followed by options' do + subject(:mapper) { Mustermann::Mapper.new({ "/foo" => "/bar" }, additional_values: :raise) } + its(:to_h) { should be == { Mustermann.new("/foo") => Mustermann::Expander.new("/bar") } } + example { mapper['/foo'].should be == '/bar' } + example { mapper['/fox'].should be == '/fox' } + end + + context 'allows specifying type' do + subject(:mapper) { Mustermann::Mapper.new({ "/foo" => "/bar" }, additional_values: :raise, type: :rails) } + its(:to_h) { should be == { Mustermann.new("/foo", type: :rails) => Mustermann::Expander.new("/bar", type: :rails) } } + example { mapper['/foo'].should be == '/bar' } + example { mapper['/fox'].should be == '/fox' } + end + end + + describe :convert do + subject(:mapper) { Mustermann::Mapper.new } + + context 'it maps params' do + before { mapper["/:a"] = "/:a.html" } + example { mapper["/foo"] .should be == "/foo.html" } + example { mapper["/foo/bar"] .should be == "/foo/bar" } + end + + context 'it supports named splats' do + before { mapper["/*a"] = "/*a.html" } + example { mapper["/foo"] .should be == "/foo.html" } + example { mapper["/foo/bar"] .should be == "/foo/bar.html" } + end + + context 'can map from patterns' do + before { mapper[Mustermann.new("/:a")] = "/:a.html" } + example { mapper["/foo"] .should be == "/foo.html" } + example { mapper["/foo/bar"] .should be == "/foo/bar" } + end + + context 'can map to patterns' do + before { mapper[Mustermann.new("/:a")] = Mustermann.new("/:a.html") } + example { mapper["/foo"] .should be == "/foo.html" } + example { mapper["/foo/bar"] .should be == "/foo/bar" } + end + + context 'can map to expanders' do + before { mapper[Mustermann.new("/:a")] = Mustermann::Expander.new("/:a.html") } + example { mapper["/foo"] .should be == "/foo.html" } + example { mapper["/foo/bar"] .should be == "/foo/bar" } + end + + context 'can map to array' do + before { mapper["/:a"] = ["/:a.html", "/:a.:f"] } + example { mapper["/foo"] .should be == "/foo.html" } + example { mapper["/foo", "f" => 'x'] .should be == "/foo.x" } + example { mapper["/foo", f: 'x'] .should be == "/foo.x" } + example { mapper["/foo/bar"] .should be == "/foo/bar" } + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/mustermann_spec.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/mustermann_spec.rb new file mode 100644 index 00000000..92830a2e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/mustermann_spec.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true +require 'support' +require 'mustermann' +require 'sinatra/base' + +describe Mustermann do + describe :new do + context "string argument" do + example { Mustermann.new('') .should be_a(Mustermann::Sinatra) } + example { Mustermann.new('', type: :identity) .should be_a(Mustermann::Identity) } + example { Mustermann.new('', type: :rails) .should be_a(Mustermann::Rails) } + example { Mustermann.new('', type: :shell) .should be_a(Mustermann::Shell) } + example { Mustermann.new('', type: :sinatra) .should be_a(Mustermann::Sinatra) } + example { Mustermann.new('', type: :simple) .should be_a(Mustermann::Simple) } + example { Mustermann.new('', type: :template) .should be_a(Mustermann::Template) } + + example { expect { Mustermann.new('', foo: :bar) }.to raise_error(ArgumentError, "unsupported option :foo for Mustermann::Sinatra") } + example { expect { Mustermann.new('', type: :ast) }.to raise_error(ArgumentError, "unsupported type :ast (cannot load such file -- mustermann/ast)") } + end + + context "pattern argument" do + subject(:pattern) { Mustermann.new('') } + example { Mustermann.new(pattern).should be == pattern } + example { Mustermann.new(pattern, type: :rails).should be_a(Mustermann::Sinatra) } + end + + context "regexp argument" do + example { Mustermann.new(//) .should be_a(Mustermann::Regular) } + example { Mustermann.new(//, type: :rails) .should be_a(Mustermann::Regular) } + end + + context "argument implementing #to_pattern" do + subject(:pattern) { Class.new { def to_pattern(**o) Mustermann.new('foo', **o) end }.new } + example { Mustermann.new(pattern) .should be_a(Mustermann::Sinatra) } + example { Mustermann.new(pattern, type: :rails) .should be_a(Mustermann::Rails) } + example { Mustermann.new(pattern).to_s.should be == 'foo' } + end + + context "multiple arguments" do + example { Mustermann.new(':a', ':b/:a') .should be_a(Mustermann::Composite) } + example { Mustermann.new(':a', ':b/:a').patterns.first .should be_a(Mustermann::Sinatra) } + example { Mustermann.new(':a', ':b/:a').operator .should be == :| } + example { Mustermann.new(':a', ':b/:a', operator: :&).operator .should be == :& } + example { Mustermann.new(':a', ':b/:a', greedy: true) .should be_a(Mustermann::Composite) } + + example { Mustermann.new('/foo', ':bar') .should be_a(Mustermann::Sinatra) } + example { Mustermann.new('/foo', ':bar').to_s .should be == "/foo|{bar}" } + end + + context "invalid arguments" do + it "raise a TypeError for unsupported types" do + expect { Mustermann.new(10) }.to raise_error(TypeError, /(Integer|Fixnum) can't be coerced into Mustermann::Pattern/) + end + end + end + + describe :[] do + example { Mustermann[:identity] .should be == Mustermann::Identity } + example { Mustermann[:rails] .should be == Mustermann::Rails } + example { Mustermann[:shell] .should be == Mustermann::Shell } + example { Mustermann[:sinatra] .should be == Mustermann::Sinatra } + example { Mustermann[:simple] .should be == Mustermann::Simple } + example { Mustermann[:template] .should be == Mustermann::Template } + + example { expect { Mustermann[:ast] }.to raise_error(ArgumentError, "unsupported type :ast (cannot load such file -- mustermann/ast)") } + example { expect { Mustermann[:expander] }.to raise_error(ArgumentError, "unsupported type :expander") } + end + + describe :extend_object do + context 'special behavior for Sinatra only' do + example { Object .new.extend(Mustermann).should be_a(Mustermann) } + example { Class .new.extend(Mustermann).should be_a(Mustermann) } + + example { expect { Sinatra.new.extend(Mustermann) }.to raise_error(RuntimeError, "Mustermann extension for Sinatra has been extracted into its own gem. More information at https://github.com/sinatra/mustermann-sinatra-extension") } + end + end + + describe :=== do + example { Mustermann.should be === Mustermann.new("") } + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/pattern_spec.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/pattern_spec.rb new file mode 100644 index 00000000..8f8db339 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/pattern_spec.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true +require 'support' +require 'mustermann/pattern' +require 'mustermann/sinatra' +require 'mustermann/rails' + +describe Mustermann::Pattern do + describe :=== do + it 'raises a NotImplementedError when used directly' do + expect { Mustermann::Pattern.new("") === "" }.to raise_error(NotImplementedError) + end + end + + describe :initialize do + it 'raises an ArgumentError for unknown options' do + expect { Mustermann::Pattern.new("", foo: :bar) }.to raise_error(ArgumentError) + end + + it 'does not complain about unknown options if ignore_unknown_options is enabled' do + expect { Mustermann::Pattern.new("", foo: :bar, ignore_unknown_options: true) }.not_to raise_error + end + end + + describe :respond_to? do + subject(:pattern) { Mustermann::Pattern.new("") } + + it { should_not respond_to(:expand) } + it { should_not respond_to(:to_templates) } + + it { expect { pattern.expand } .to raise_error(NotImplementedError) } + it { expect { pattern.to_templates } .to raise_error(NotImplementedError) } + end + + describe :== do + example { Mustermann::Pattern.new('/foo') .should be == Mustermann::Pattern.new('/foo') } + example { Mustermann::Pattern.new('/foo') .should_not be == Mustermann::Pattern.new('/bar') } + example { Mustermann::Sinatra.new('/foo') .should be == Mustermann::Sinatra.new('/foo') } + example { Mustermann::Rails.new('/foo') .should_not be == Mustermann::Sinatra.new('/foo') } + end + + describe :eql? do + example { Mustermann::Pattern.new('/foo') .should be_eql Mustermann::Pattern.new('/foo') } + example { Mustermann::Pattern.new('/foo') .should_not be_eql Mustermann::Pattern.new('/bar') } + example { Mustermann::Sinatra.new('/foo') .should be_eql Mustermann::Sinatra.new('/foo') } + example { Mustermann::Rails.new('/foo') .should_not be_eql Mustermann::Sinatra.new('/foo') } + end + + describe :equal? do + example { Mustermann::Pattern.new('/foo') .should be_equal Mustermann::Pattern.new('/foo') } + example { Mustermann::Pattern.new('/foo') .should_not be_equal Mustermann::Pattern.new('/bar') } + example { Mustermann::Sinatra.new('/foo') .should be_equal Mustermann::Sinatra.new('/foo') } + example { Mustermann::Rails.new('/foo') .should_not be_equal Mustermann::Sinatra.new('/foo') } + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/regexp_based_spec.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/regexp_based_spec.rb new file mode 100644 index 00000000..bc25fd56 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/regexp_based_spec.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true +require 'support' +require 'mustermann/regexp_based' + +describe Mustermann::RegexpBased do + it 'raises a NotImplementedError when used directly' do + expect { Mustermann::RegexpBased.new("") === "" }.to raise_error(NotImplementedError) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/regular_spec.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/regular_spec.rb new file mode 100644 index 00000000..198a00b3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/regular_spec.rb @@ -0,0 +1,119 @@ +# frozen_string_literal: true +require 'support' +require 'timeout' +require 'mustermann/regular' + +describe Mustermann::Regular do + extend Support::Pattern + + pattern '' do + it { should match('') } + it { should_not match('/') } + + it { should_not respond_to(:expand) } + it { should_not respond_to(:to_templates) } + end + + pattern '/' do + it { should match('/') } + it { should_not match('/foo') } + end + + pattern '/foo' do + it { should match('/foo') } + it { should_not match('/bar') } + it { should_not match('/foo.bar') } + end + + pattern '/foo/bar' do + it { should match('/foo/bar') } + it { should_not match('/foo%2Fbar') } + it { should_not match('/foo%2fbar') } + end + + pattern '/(?.*)' do + it { should match('/foo') .capturing foo: 'foo' } + it { should match('/bar') .capturing foo: 'bar' } + it { should match('/foo.bar') .capturing foo: 'foo.bar' } + it { should match('/%0Afoo') .capturing foo: '%0Afoo' } + it { should match('/foo%2Fbar') .capturing foo: 'foo%2Fbar' } + end + + + context 'with Regexp::EXTENDED' do + let(:pattern) { + %r{ + \/compare\/ # match any URL beginning with \/compare\/ + (.+) # extract the full path (including any directories) + \/ # match the final slash + ([^.]+) # match the first SHA1 + \.{2,3} # match .. or ... + (.+) # match the second SHA1 + }x + } + example { expect { Timeout.timeout(1){ Mustermann::Regular.new(pattern) }}.not_to raise_error } + it { expect(Mustermann::Regular.new(pattern)).to match('/compare/foo/bar..baz') } + end + + describe :check_achnors do + context 'raises on anchors' do + example { expect { Mustermann::Regular.new('^foo') }.to raise_error(Mustermann::CompileError) } + example { expect { Mustermann::Regular.new('foo$') }.to raise_error(Mustermann::CompileError) } + example { expect { Mustermann::Regular.new('\Afoo') }.to raise_error(Mustermann::CompileError) } + example { expect { Mustermann::Regular.new('foo\Z') }.to raise_error(Mustermann::CompileError) } + example { expect { Mustermann::Regular.new('foo\z') }.to raise_error(Mustermann::CompileError) } + example { expect { Mustermann::Regular.new(/^foo/) }.to raise_error(Mustermann::CompileError) } + example { expect { Mustermann::Regular.new(/foo$/) }.to raise_error(Mustermann::CompileError) } + example { expect { Mustermann::Regular.new(/\Afoo/) }.to raise_error(Mustermann::CompileError) } + example { expect { Mustermann::Regular.new(/foo\Z/) }.to raise_error(Mustermann::CompileError) } + example { expect { Mustermann::Regular.new(/foo\z/) }.to raise_error(Mustermann::CompileError) } + example { expect { Mustermann::Regular.new('[^f]') }.not_to raise_error } + example { expect { Mustermann::Regular.new('\\\A') }.not_to raise_error } + example { expect { Mustermann::Regular.new('[[:digit:]]') }.not_to raise_error } + example { expect { Mustermann::Regular.new(/[^f]/) }.not_to raise_error } + example { expect { Mustermann::Regular.new(/\\A/) }.not_to raise_error } + example { expect { Mustermann::Regular.new(/[[:digit:]]/) }.not_to raise_error } + end + + context 'with check_anchors disabled' do + example { expect { Mustermann::Regular.new('^foo', check_anchors: false) }.not_to raise_error } + example { expect { Mustermann::Regular.new('foo$', check_anchors: false) }.not_to raise_error } + example { expect { Mustermann::Regular.new('\Afoo', check_anchors: false) }.not_to raise_error } + example { expect { Mustermann::Regular.new('foo\Z', check_anchors: false) }.not_to raise_error } + example { expect { Mustermann::Regular.new('foo\z', check_anchors: false) }.not_to raise_error } + example { expect { Mustermann::Regular.new(/^foo/, check_anchors: false) }.not_to raise_error } + example { expect { Mustermann::Regular.new(/foo$/, check_anchors: false) }.not_to raise_error } + example { expect { Mustermann::Regular.new(/\Afoo/, check_anchors: false) }.not_to raise_error } + example { expect { Mustermann::Regular.new(/foo\Z/, check_anchors: false) }.not_to raise_error } + example { expect { Mustermann::Regular.new(/foo\z/, check_anchors: false) }.not_to raise_error } + example { expect { Mustermann::Regular.new('[^f]', check_anchors: false) }.not_to raise_error } + example { expect { Mustermann::Regular.new('\\\A', check_anchors: false) }.not_to raise_error } + example { expect { Mustermann::Regular.new('[[:digit:]]', check_anchors: false) }.not_to raise_error } + example { expect { Mustermann::Regular.new(/[^f]/, check_anchors: false) }.not_to raise_error } + example { expect { Mustermann::Regular.new(/\\A/, check_anchors: false) }.not_to raise_error } + example { expect { Mustermann::Regular.new(/[[:digit:]]/, check_anchors: false) }.not_to raise_error } + end + end + + context "peeking" do + subject(:pattern) { Mustermann::Regular.new("(?[^/]+)") } + + describe :peek_size do + example { pattern.peek_size("foo bar/blah") .should be == "foo bar".size } + example { pattern.peek_size("foo%20bar/blah") .should be == "foo%20bar".size } + example { pattern.peek_size("/foo bar") .should be_nil } + end + + describe :peek_match do + example { pattern.peek_match("foo bar/blah") .to_s .should be == "foo bar" } + example { pattern.peek_match("foo%20bar/blah") .to_s .should be == "foo%20bar" } + example { pattern.peek_match("/foo bar") .should be_nil } + end + + describe :peek_params do + example { pattern.peek_params("foo bar/blah") .should be == [{"name" => "foo bar"}, "foo bar".size] } + example { pattern.peek_params("foo%20bar/blah") .should be == [{"name" => "foo bar"}, "foo%20bar".size] } + example { pattern.peek_params("/foo bar") .should be_nil } + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/simple_match_spec.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/simple_match_spec.rb new file mode 100644 index 00000000..21955b4b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/simple_match_spec.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true +require 'support' +require 'mustermann/simple_match' + +describe Mustermann::SimpleMatch do + subject { Mustermann::SimpleMatch.new('example') } + its(:to_s) { should be == 'example' } + its(:names) { should be == [] } + its(:captures) { should be == [] } + example { subject[1].should be == nil } +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/sinatra_spec.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/sinatra_spec.rb new file mode 100644 index 00000000..58139bae --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/sinatra_spec.rb @@ -0,0 +1,836 @@ +# frozen_string_literal: true +require 'support' +require 'mustermann/sinatra' + +describe Mustermann::Sinatra do + extend Support::Pattern + + pattern '' do + it { should match('') } + it { should_not match('/') } + + it { should generate_template('') } + + it { should respond_to(:expand) } + it { should respond_to(:to_templates) } + end + + pattern '/' do + it { should match('/') } + it { should_not match('/foo') } + end + + pattern '/foo' do + it { should match('/foo') } + it { should_not match('/bar') } + it { should_not match('/foo.bar') } + end + + pattern '/foo/bar' do + it { should match('/foo/bar') } + it { should_not match('/foo%2Fbar') } + it { should_not match('/foo%2fbar') } + end + + pattern '/foo\/bar' do + it { should match('/foo/bar') } + it { should match('/foo%2Fbar') } + it { should match('/foo%2fbar') } + end + + pattern '/:foo' do + it { should match('/foo') .capturing foo: 'foo' } + it { should match('/bar') .capturing foo: 'bar' } + it { should match('/foo.bar') .capturing foo: 'foo.bar' } + it { should match('/%0Afoo') .capturing foo: '%0Afoo' } + it { should match('/foo%2Fbar') .capturing foo: 'foo%2Fbar' } + + it { should_not match('/foo?') } + it { should_not match('/foo/bar') } + it { should_not match('/') } + it { should_not match('/foo/') } + + it { should generate_template('/{foo}') } + end + + pattern '/föö' do + it { should match("/f%C3%B6%C3%B6") } + end + + pattern "/:foo/:bar" do + it { should match('/foo/bar') .capturing foo: 'foo', bar: 'bar' } + it { should match('/foo.bar/bar.foo') .capturing foo: 'foo.bar', bar: 'bar.foo' } + it { should match('/user@example.com/name') .capturing foo: 'user@example.com', bar: 'name' } + it { should match('/10.1/te.st') .capturing foo: '10.1', bar: 'te.st' } + it { should match('/10.1.2/te.st') .capturing foo: '10.1.2', bar: 'te.st' } + + it { should_not match('/foo%2Fbar') } + it { should_not match('/foo%2fbar') } + + example { pattern.params('/bar/foo').should be == {"foo" => "bar", "bar" => "foo"} } + example { pattern.params('').should be_nil } + + it { should generate_template('/{foo}/{bar}') } + end + + pattern "/{foo}/{bar}" do + it { should match('/foo/bar') .capturing foo: 'foo', bar: 'bar' } + it { should match('/foo.bar/bar.foo') .capturing foo: 'foo.bar', bar: 'bar.foo' } + it { should match('/user@example.com/name') .capturing foo: 'user@example.com', bar: 'name' } + it { should match('/10.1/te.st') .capturing foo: '10.1', bar: 'te.st' } + it { should match('/10.1.2/te.st') .capturing foo: '10.1.2', bar: 'te.st' } + + it { should_not match('/foo%2Fbar') } + it { should_not match('/foo%2fbar') } + + example { pattern.params('/bar/foo').should be == {"foo" => "bar", "bar" => "foo"} } + example { pattern.params('').should be_nil } + + it { should generate_template('/{foo}/{bar}') } + end + + pattern '/hello/:person' do + it { should match('/hello/Frank').capturing person: 'Frank' } + it { should generate_template('/hello/{person}') } + end + + pattern '/hello/{person}' do + it { should match('/hello/Frank').capturing person: 'Frank' } + it { should generate_template('/hello/{person}') } + end + + pattern '/?:foo?/?:bar?' do + it { should match('/hello/world') .capturing foo: 'hello', bar: 'world' } + it { should match('/hello') .capturing foo: 'hello', bar: nil } + it { should match('/') .capturing foo: nil, bar: nil } + it { should match('') .capturing foo: nil, bar: nil } + + it { should expand(foo: 'hello') .to('/hello/') } + it { should expand(foo: 'hello', bar: 'world') .to('/hello/world') } + it { should expand(bar: 'world') .to('//world') } + it { should expand .to('//') } + it { should_not expand(baz: '') } + + it { should_not match('/hello/world/') } + it { should generate_templates("", "/", "//", "//{bar}", "/{bar}", "/{foo}", "/{foo}/", "/{foo}/{bar}", "/{foo}{bar}", "{bar}", "{foo}", "{foo}/", "{foo}/{bar}", "{foo}{bar}") } + end + + pattern '/:foo_bar' do + it { should match('/hello').capturing foo_bar: 'hello' } + it { should generate_template('/{foo_bar}') } + end + + pattern '/{foo.bar}' do + it { should match('/hello').capturing :"foo.bar" => 'hello' } + it { should generate_template('/{foo.bar}') } + end + + pattern '/*' do + it { should match('/') .capturing splat: '' } + it { should match('/foo') .capturing splat: 'foo' } + it { should match('/foo/bar') .capturing splat: 'foo/bar' } + it { should generate_template('/{+splat}') } + + example { pattern.params('/foo').should be == {"splat" => ["foo"]} } + end + + pattern '/{+splat}' do + it { should match('/') .capturing splat: '' } + it { should match('/foo') .capturing splat: 'foo' } + it { should match('/foo/bar') .capturing splat: 'foo/bar' } + it { should generate_template('/{+splat}') } + + example { pattern.params('/foo').should be == {"splat" => ["foo"]} } + end + + pattern '/*foo' do + it { should match('/') .capturing foo: '' } + it { should match('/foo') .capturing foo: 'foo' } + it { should match('/foo/bar') .capturing foo: 'foo/bar' } + it { should generate_template('/{+foo}') } + + example { pattern.params('/foo') .should be == {"foo" => "foo" } } + example { pattern.params('/foo/bar') .should be == {"foo" => "foo/bar" } } + end + + pattern '/{+foo}' do + it { should match('/') .capturing foo: '' } + it { should match('/foo') .capturing foo: 'foo' } + it { should match('/foo/bar') .capturing foo: 'foo/bar' } + it { should generate_template('/{+foo}') } + + example { pattern.params('/foo') .should be == {"foo" => "foo" } } + example { pattern.params('/foo/bar') .should be == {"foo" => "foo/bar" } } + end + + pattern '/*foo/*bar' do + it { should match('/foo/bar') .capturing foo: 'foo', bar: 'bar' } + it { should generate_template('/{+foo}/{+bar}') } + end + + pattern '/{+foo}/{+bar}' do + it { should match('/foo/bar') .capturing foo: 'foo', bar: 'bar' } + it { should generate_template('/{+foo}/{+bar}') } + end + + pattern '/:foo/*' do + it { should match("/foo/bar/baz") .capturing foo: 'foo', splat: 'bar/baz' } + it { should match("/foo/") .capturing foo: 'foo', splat: '' } + it { should match('/h%20w/h%20a%20y') .capturing foo: 'h%20w', splat: 'h%20a%20y' } + it { should_not match('/foo') } + it { should generate_template('/{foo}/{+splat}') } + + example { pattern.params('/bar/foo').should be == {"splat" => ["foo"], "foo" => "bar"} } + example { pattern.params('/bar/foo/f%20o').should be == {"splat" => ["foo/f o"], "foo" => "bar"} } + end + + pattern '/{foo}/*' do + it { should match("/foo/bar/baz") .capturing foo: 'foo', splat: 'bar/baz' } + it { should match("/foo/") .capturing foo: 'foo', splat: '' } + it { should match('/h%20w/h%20a%20y') .capturing foo: 'h%20w', splat: 'h%20a%20y' } + it { should_not match('/foo') } + it { should generate_template('/{foo}/{+splat}') } + + example { pattern.params('/bar/foo').should be == {"splat" => ["foo"], "foo" => "bar"} } + example { pattern.params('/bar/foo/f%20o').should be == {"splat" => ["foo/f o"], "foo" => "bar"} } + end + + pattern '/test$/' do + it { should match('/test$/') } + end + + pattern '/te+st/' do + it { should match('/te+st/') } + it { should_not match('/test/') } + it { should_not match('/teest/') } + end + + pattern "/path with spaces" do + it { should match('/path%20with%20spaces') } + it { should match('/path%2Bwith%2Bspaces') } + it { should match('/path+with+spaces') } + + it { should generate_template('/path%20with%20spaces') } + end + + pattern '/foo&bar' do + it { should match('/foo&bar') } + end + + pattern '/foo\{bar' do + it { should match('/foo%7Bbar') } + end + + pattern '/*/:foo/*/*' do + it { should match('/bar/foo/bling/baz/boom') } + + it "should capture all splat parts" do + match = pattern.match('/bar/foo/bling/baz/boom') + match.captures.should be == ['bar', 'foo', 'bling', 'baz/boom'] + match.names.should be == ['splat', 'foo'] + end + + it 'should map to proper params' do + pattern.params('/bar/foo/bling/baz/boom').should be == { + "foo" => "foo", "splat" => ['bar', 'bling', 'baz/boom'] + } + end + end + + pattern '/{+splat}/{foo}/{+splat}/{+splat}' do + it { should match('/bar/foo/bling/baz/boom') } + + it "should capture all splat parts" do + match = pattern.match('/bar/foo/bling/baz/boom') + match.captures.should be == ['bar', 'foo', 'bling', 'baz/boom'] + match.names.should be == ['splat', 'foo'] + end + + it 'should map to proper params' do + pattern.params('/bar/foo/bling/baz/boom').should be == { + "foo" => "foo", "splat" => ['bar', 'bling', 'baz/boom'] + } + end + end + + pattern '/test.bar' do + it { should match('/test.bar') } + it { should_not match('/test0bar') } + end + + pattern '/:file.:ext' do + it { should match('/pony.jpg') .capturing file: 'pony', ext: 'jpg' } + it { should match('/pony%2Ejpg') .capturing file: 'pony', ext: 'jpg' } + it { should match('/pony%2ejpg') .capturing file: 'pony', ext: 'jpg' } + + it { should match('/pony%E6%AD%A3%2Ejpg') .capturing file: 'pony%E6%AD%A3', ext: 'jpg' } + it { should match('/pony%e6%ad%a3%2ejpg') .capturing file: 'pony%e6%ad%a3', ext: 'jpg' } + it { should match('/pony正%2Ejpg') .capturing file: 'pony正', ext: 'jpg' } + it { should match('/pony正%2ejpg') .capturing file: 'pony正', ext: 'jpg' } + it { should match('/pony正..jpg') .capturing file: 'pony正.', ext: 'jpg' } + + it { should_not match('/.jpg') } + end + + pattern '/(:a)x?' do + it { should match('/a') .capturing a: 'a' } + it { should match('/xa') .capturing a: 'xa' } + it { should match('/axa') .capturing a: 'axa' } + it { should match('/ax') .capturing a: 'a' } + it { should match('/axax') .capturing a: 'axa' } + it { should match('/axaxx') .capturing a: 'axax' } + + it { should generate_template('/{a}x') } + it { should generate_template('/{a}') } + end + + pattern '/:user(@:host)?' do + it { should match('/foo@bar') .capturing user: 'foo', host: 'bar' } + it { should match('/foo.foo@bar') .capturing user: 'foo.foo', host: 'bar' } + it { should match('/foo@bar.bar') .capturing user: 'foo', host: 'bar.bar' } + + it { should generate_template('/{user}') } + it { should generate_template('/{user}@{host}') } + end + + pattern '/:file(.:ext)?' do + it { should match('/pony') .capturing file: 'pony', ext: nil } + it { should match('/pony.jpg') .capturing file: 'pony', ext: 'jpg' } + it { should match('/pony%2Ejpg') .capturing file: 'pony', ext: 'jpg' } + it { should match('/pony%2ejpg') .capturing file: 'pony', ext: 'jpg' } + it { should match('/pony.png.jpg') .capturing file: 'pony.png', ext: 'jpg' } + it { should match('/pony.') .capturing file: 'pony.' } + it { should_not match('/.jpg') } + + it { should generate_template('/{file}') } + it { should generate_template('/{file}.{ext}') } + it { should_not generate_template('/{file}.') } + end + + pattern '/:id/test.bar' do + it { should match('/3/test.bar') .capturing id: '3' } + it { should match('/2/test.bar') .capturing id: '2' } + it { should match('/2E/test.bar') .capturing id: '2E' } + it { should match('/2e/test.bar') .capturing id: '2e' } + it { should match('/%2E/test.bar') .capturing id: '%2E' } + end + + pattern '/10/:id' do + it { should match('/10/test') .capturing id: 'test' } + it { should match('/10/te.st') .capturing id: 'te.st' } + end + + pattern '/10.1/:id' do + it { should match('/10.1/test') .capturing id: 'test' } + it { should match('/10.1/te.st') .capturing id: 'te.st' } + end + + pattern '/:foo.:bar/:id' do + it { should match('/10.1/te.st') .capturing foo: "10", bar: "1", id: "te.st" } + it { should match('/10.1.2/te.st') .capturing foo: "10.1", bar: "2", id: "te.st" } + end + + pattern '/:a/:b.?:c?' do + it { should match('/a/b') .capturing a: 'a', b: 'b', c: nil } + it { should match('/a/b.c') .capturing a: 'a', b: 'b', c: 'c' } + it { should match('/a.b/c') .capturing a: 'a.b', b: 'c', c: nil } + it { should match('/a.b/c.d') .capturing a: 'a.b', b: 'c', c: 'd' } + it { should_not match('/a.b/c.d/e') } + end + + pattern '/:a(foo:b)?' do + it { should match('/barfoobar') .capturing a: 'bar', b: 'bar' } + it { should match('/barfoobarfoobar') .capturing a: 'barfoobar', b: 'bar' } + it { should match('/bar') .capturing a: 'bar', b: nil } + it { should_not match('/') } + end + + pattern '/foo?' do + it { should match('/fo') } + it { should match('/foo') } + it { should_not match('') } + it { should_not match('/') } + it { should_not match('/f') } + it { should_not match('/fooo') } + end + + pattern '/foo\?' do + it { should match('/foo?') } + it { should_not match('/foo\?') } + it { should_not match('/fo') } + it { should_not match('/foo') } + it { should_not match('') } + it { should_not match('/') } + it { should_not match('/f') } + it { should_not match('/fooo') } + end + + pattern '/foo\\\?' do + it { should match('/foo%5c') } + it { should match('/foo') } + it { should_not match('/foo\?') } + it { should_not match('/fo') } + it { should_not match('') } + it { should_not match('/') } + it { should_not match('/f') } + it { should_not match('/fooo') } + end + + pattern '/\(' do + it { should match('/(') } + end + + pattern '/\(?' do + it { should match('/(') } + it { should match('/') } + end + + pattern '/(\()?' do + it { should match('/(') } + it { should match('/') } + end + + pattern '/(\(\))?' do + it { should match('/') } + it { should match('/()') } + it { should_not match('/(') } + end + + pattern '/\(\)?' do + it { should match('/(') } + it { should match('/()') } + it { should_not match('/') } + end + + pattern '/\*' do + it { should match('/*') } + it { should_not match('/a') } + end + + pattern '/\*/*' do + it { should match('/*/b/c') } + it { should_not match('/a/b/c') } + end + + pattern '/\:foo' do + it { should match('/:foo') } + it { should_not match('/foo') } + end + + pattern '/:fOO' do + it { should match('/a').capturing fOO: 'a' } + end + + pattern '/:_X' do + it { should match('/a').capturing _X: 'a' } + end + + pattern '/:f00' do + it { should match('/a').capturing f00: 'a' } + end + + pattern '/:foo(/:bar)?/:baz?' do + it { should match('/foo/bar/baz').capturing foo: 'foo', bar: 'bar', baz: 'baz' } + end + + pattern "/(foo|bar)" do + it { should match("/foo") } + it { should match("/bar") } + + it { should generate_template('/foo') } + it { should generate_template('/bar') } + end + + pattern "/(foo\\|bar)" do + it { should match "/foo%7Cbar" } + it { should generate_template "/foo%7Cbar" } + + it { should_not match("/foo") } + it { should_not match("/bar") } + + it { should_not generate_template('/foo') } + it { should_not generate_template('/bar') } + end + + pattern "/(:a/:b|:c)" do + it { should match("/foo") .capturing c: 'foo' } + it { should match("/foo/bar") .capturing a: 'foo', b: 'bar' } + + it { should generate_template('/{a}/{b}') } + it { should generate_template('/{c}') } + + it { should expand(a: 'foo', b: 'bar') .to('/foo/bar') } + it { should expand(c: 'foo') .to('/foo') } + it { should_not expand(a: 'foo', b: 'bar', c: 'baz') } + end + + pattern "/:a/:b|:c" do + it { should match("foo") .capturing c: 'foo' } + it { should match("/foo/bar") .capturing a: 'foo', b: 'bar' } + + it { should generate_template('/{a}/{b}') } + it { should generate_template('{c}') } + + it { should expand(a: 'foo', b: 'bar') .to('/foo/bar') } + it { should expand(c: 'foo') .to('foo') } + it { should_not expand(a: 'foo', b: 'bar', c: 'baz') } + end + + pattern "/({foo}|{bar})", capture: { foo: /\d+/, bar: /\w+/ } do + it { should match("/a") .capturing foo: nil, bar: 'a' } + it { should match("/1234") .capturing foo: "1234", bar: nil } + + it { should_not match("/a/b") } + end + + pattern "/{foo|bar}", capture: { foo: /\d+/, bar: /\w+/ } do + it { should match("/a") .capturing foo: nil, bar: 'a' } + it { should match("/1234") .capturing foo: "1234", bar: nil } + + it { should_not match("/a/b") } + end + + pattern "/{foo|bar|baz}", capture: { foo: /\d+/, bar: /[ab]+/, baz: /[cde]+/ } do + it { should match("/ab") .capturing foo: nil, bar: 'ab', baz: nil } + it { should match("/1234") .capturing foo: "1234", bar: nil, baz: nil } + it { should match("/ccddee") .capturing foo: nil, bar: nil, baz: "ccddee" } + + it { should_not match("/a/b") } + end + + pattern '/:foo', capture: /\d+/ do + it { should match('/1') .capturing foo: '1' } + it { should match('/123') .capturing foo: '123' } + + it { should_not match('/') } + it { should_not match('/foo') } + end + + pattern '/:foo', capture: /\d+/ do + it { should match('/1') .capturing foo: '1' } + it { should match('/123') .capturing foo: '123' } + + it { should_not match('/') } + it { should_not match('/foo') } + end + + pattern '/:foo', capture: '1' do + it { should match('/1').capturing foo: '1' } + + it { should_not match('/') } + it { should_not match('/foo') } + it { should_not match('/123') } + end + + pattern '/:foo', capture: 'a.b' do + it { should match('/a.b') .capturing foo: 'a.b' } + it { should match('/a%2Eb') .capturing foo: 'a%2Eb' } + it { should match('/a%2eb') .capturing foo: 'a%2eb' } + + it { should_not match('/ab') } + it { should_not match('/afb') } + it { should_not match('/a1b') } + it { should_not match('/a.bc') } + end + + pattern '/:foo(/:bar)?', capture: :alpha do + it { should match('/abc') .capturing foo: 'abc', bar: nil } + it { should match('/a/b') .capturing foo: 'a', bar: 'b' } + it { should match('/a') .capturing foo: 'a', bar: nil } + + it { should_not match('/1/2') } + it { should_not match('/a/2') } + it { should_not match('/1/b') } + it { should_not match('/1') } + it { should_not match('/1/') } + it { should_not match('/a/') } + it { should_not match('//a') } + end + + pattern '/:foo', capture: ['foo', 'bar', /\d+/] do + it { should match('/1') .capturing foo: '1' } + it { should match('/123') .capturing foo: '123' } + it { should match('/foo') .capturing foo: 'foo' } + it { should match('/bar') .capturing foo: 'bar' } + + it { should_not match('/') } + it { should_not match('/baz') } + it { should_not match('/foo1') } + end + + pattern '/:foo:bar:baz', capture: { foo: :alpha, bar: /\d+/ } do + it { should match('/ab123xy-1') .capturing foo: 'ab', bar: '123', baz: 'xy-1' } + it { should match('/ab123') .capturing foo: 'ab', bar: '12', baz: '3' } + it { should_not match('/123abcxy-1') } + it { should_not match('/abcxy-1') } + it { should_not match('/abc1') } + end + + pattern '/:foo', capture: { foo: ['foo', 'bar', /\d+/] } do + it { should match('/1') .capturing foo: '1' } + it { should match('/123') .capturing foo: '123' } + it { should match('/foo') .capturing foo: 'foo' } + it { should match('/bar') .capturing foo: 'bar' } + + it { should_not match('/') } + it { should_not match('/baz') } + it { should_not match('/foo1') } + end + + pattern '/:file(.:ext)?', capture: { ext: ['jpg', 'png'] } do + it { should match('/pony') .capturing file: 'pony', ext: nil } + it { should match('/pony.jpg') .capturing file: 'pony', ext: 'jpg' } + it { should match('/pony%2Ejpg') .capturing file: 'pony', ext: 'jpg' } + it { should match('/pony%2ejpg') .capturing file: 'pony', ext: 'jpg' } + it { should match('/pony.png') .capturing file: 'pony', ext: 'png' } + it { should match('/pony%2Epng') .capturing file: 'pony', ext: 'png' } + it { should match('/pony%2epng') .capturing file: 'pony', ext: 'png' } + it { should match('/pony.png.jpg') .capturing file: 'pony.png', ext: 'jpg' } + it { should match('/pony.jpg.png') .capturing file: 'pony.jpg', ext: 'png' } + it { should match('/pony.gif') .capturing file: 'pony.gif', ext: nil } + it { should match('/pony.') .capturing file: 'pony.', ext: nil } + it { should_not match('.jpg') } + end + + pattern '/:file:ext?', capture: { ext: ['.jpg', '.png', '.tar.gz'] } do + it { should match('/pony') .capturing file: 'pony', ext: nil } + it { should match('/pony.jpg') .capturing file: 'pony', ext: '.jpg' } + it { should match('/pony.png') .capturing file: 'pony', ext: '.png' } + it { should match('/pony.png.jpg') .capturing file: 'pony.png', ext: '.jpg' } + it { should match('/pony.jpg.png') .capturing file: 'pony.jpg', ext: '.png' } + it { should match('/pony.tar.gz') .capturing file: 'pony', ext: '.tar.gz' } + it { should match('/pony.gif') .capturing file: 'pony.gif', ext: nil } + it { should match('/pony.') .capturing file: 'pony.', ext: nil } + it { should_not match('/.jpg') } + end + + pattern '/:a(@:b)?', capture: { b: /\d+/ } do + it { should match('/a') .capturing a: 'a', b: nil } + it { should match('/a@1') .capturing a: 'a', b: '1' } + it { should match('/a@b') .capturing a: 'a@b', b: nil } + it { should match('/a@1@2') .capturing a: 'a@1', b: '2' } + end + + pattern '/(:a)b?', greedy: false do + it { should match('/ab').capturing a: 'a' } + end + + pattern '/:file(.:ext)?', greedy: false do + it { should match('/pony') .capturing file: 'pony', ext: nil } + it { should match('/pony.jpg') .capturing file: 'pony', ext: 'jpg' } + it { should match('/pony.png.jpg') .capturing file: 'pony', ext: 'png.jpg' } + end + + pattern '/auth/*', except: '/auth/login' do + it { should match('/auth/admin') } + it { should match('/auth/foobar') } + it { should_not match('/auth/login') } + end + + pattern '/:foo/:bar', except: '/:bar/20' do + it { should match('/foo/bar').capturing foo: 'foo', bar: 'bar' } + it { should_not match('/20/20') } + end + + pattern '/foo?', uri_decode: false do + it { should match('/foo') } + it { should match('/fo') } + it { should_not match('/foo?') } + end + + pattern '/foo/bar', uri_decode: false do + it { should match('/foo/bar') } + it { should_not match('/foo%2Fbar') } + it { should_not match('/foo%2fbar') } + end + + pattern "/path with spaces", uri_decode: false do + it { should match('/path with spaces') } + it { should_not match('/path%20with%20spaces') } + it { should_not match('/path%2Bwith%2Bspaces') } + it { should_not match('/path+with+spaces') } + end + + pattern "/path with spaces", space_matches_plus: false do + it { should match('/path%20with%20spaces') } + it { should_not match('/path%2Bwith%2Bspaces') } + it { should_not match('/path+with+spaces') } + end + + context 'invalid syntax' do + example 'unexpected closing parenthesis' do + expect { Mustermann::Sinatra.new('foo)bar') }. + to raise_error(Mustermann::ParseError, 'unexpected ) while parsing "foo)bar"') + end + + example 'missing closing parenthesis' do + expect { Mustermann::Sinatra.new('foo(bar') }. + to raise_error(Mustermann::ParseError, 'unexpected end of string while parsing "foo(bar"') + end + + example 'missing unescaped closing parenthesis' do + expect { Mustermann::Sinatra.new('foo(bar\)') }. + to raise_error(Mustermann::ParseError, 'unexpected end of string while parsing "foo(bar\\\\)"') + end + + example '? at beginning of route' do + expect { Mustermann::Sinatra.new('?foobar') }. + to raise_error(Mustermann::ParseError, 'unexpected ? while parsing "?foobar"') + end + + example 'double ?' do + expect { Mustermann::Sinatra.new('foo??bar') }. + to raise_error(Mustermann::ParseError, 'unexpected ? while parsing "foo??bar"') + end + + example 'dangling escape' do + expect { Mustermann::Sinatra.new('foo\\') }. + to raise_error(Mustermann::ParseError, 'unexpected end of string while parsing "foo\\\\"') + end + end + + context 'invalid capture names' do + example 'empty name' do + expect { Mustermann::Sinatra.new('/:/') }. + to raise_error(Mustermann::CompileError, "capture name can't be empty: \"/:/\"") + end + + example 'named splat' do + expect { Mustermann::Sinatra.new('/:splat/') }. + to raise_error(Mustermann::CompileError, "capture name can't be splat: \"/:splat/\"") + end + + example 'named captures' do + expect { Mustermann::Sinatra.new('/:captures/') }. + to raise_error(Mustermann::CompileError, "capture name can't be captures: \"/:captures/\"") + end + + example 'with capital letter' do + expect { Mustermann::Sinatra.new('/:Foo/') }. + to raise_error(Mustermann::CompileError, "capture name must start with underscore or lower case letter: \"/:Foo/\"") + end + + example 'with integer' do + expect { Mustermann::Sinatra.new('/:1a/') }. + to raise_error(Mustermann::CompileError, "capture name must start with underscore or lower case letter: \"/:1a/\"") + end + + example 'same name twice' do + expect { Mustermann::Sinatra.new('/:foo(/:bar)?/:bar?') }. + to raise_error(Mustermann::CompileError, "can't use the same capture name twice: \"/:foo(/:bar)?/:bar?\"") + end + end + + context 'Regexp compatibility' do + describe :=== do + example('non-matching') { Mustermann::Sinatra.new("/") .should_not be === '/foo' } + example('matching') { Mustermann::Sinatra.new("/:foo") .should be === '/foo' } + end + + describe :=~ do + example('non-matching') { Mustermann::Sinatra.new("/") .should_not be =~ '/foo' } + example('matching') { Mustermann::Sinatra.new("/:foo") .should be =~ '/foo' } + + context 'String#=~' do + example('non-matching') { "/foo".should_not be =~ Mustermann::Sinatra.new("/") } + example('matching') { "/foo".should be =~ Mustermann::Sinatra.new("/:foo") } + end + end + + describe :to_regexp do + example('empty pattern') { Mustermann::Sinatra.new('').to_regexp.should be == /\A(?-mix:)\Z/ } + + context 'Regexp.try_convert' do + example('empty pattern') { Regexp.try_convert(Mustermann::Sinatra.new('')).should be == /\A(?-mix:)\Z/ } + end + end + end + + context 'Proc compatibility' do + describe :to_proc do + example { Mustermann::Sinatra.new("/").to_proc.should be_a(Proc) } + example('non-matching') { Mustermann::Sinatra.new("/") .to_proc.call('/foo').should be == false } + example('matching') { Mustermann::Sinatra.new("/:foo") .to_proc.call('/foo').should be == true } + end + end + + context "peeking" do + subject(:pattern) { Mustermann::Sinatra.new(":name") } + + describe :peek_size do + example { pattern.peek_size("foo bar/blah") .should be == "foo bar".size } + example { pattern.peek_size("foo%20bar/blah") .should be == "foo%20bar".size } + example { pattern.peek_size("/foo bar") .should be_nil } + end + + describe :peek_match do + example { pattern.peek_match("foo bar/blah") .to_s .should be == "foo bar" } + example { pattern.peek_match("foo%20bar/blah") .to_s .should be == "foo%20bar" } + example { pattern.peek_match("/foo bar") .should be_nil } + end + + describe :peek_params do + example { pattern.peek_params("foo bar/blah") .should be == [{"name" => "foo bar"}, "foo bar".size] } + example { pattern.peek_params("foo%20bar/blah") .should be == [{"name" => "foo bar"}, "foo%20bar".size] } + example { pattern.peek_params("/foo bar") .should be_nil } + end + end + + describe :| do + let(:first) { Mustermann.new("a") } + let(:second) { Mustermann.new("b") } + subject(:composite) { first | second } + + context "with no capture names" do + its(:class) { should be == Mustermann::Sinatra } + its(:to_s) { should be == "a|b" } + end + + context "only first has captures" do + let(:first) { Mustermann.new(":a") } + its(:class) { should be == Mustermann::Sinatra } + its(:to_s) { should be == "{a}|b" } + end + + context "only second has captures" do + let(:second) { Mustermann.new(":b") } + its(:class) { should be == Mustermann::Sinatra } + its(:to_s) { should be == "a|{b}" } + end + + context "both have captures" do + let(:first) { Mustermann.new(":a") } + let(:second) { Mustermann.new(":b") } + its(:class) { should be == Mustermann::Composite } + end + + context "options mismatch" do + let(:second) { Mustermann.new(":b", greedy: false) } + its(:class) { should be == Mustermann::Composite } + end + + context "argument is a string" do + let(:second) { ":b" } + its(:class) { should be == Mustermann::Sinatra } + its(:to_s) { should be == "a|\\:b" } + end + + context "argument is an identity pattern" do + let(:second) { Mustermann::Identity.new(":b") } + its(:class) { should be == Mustermann::Sinatra } + its(:to_s) { should be == "a|\\:b" } + end + + context "argument is an identity pattern, but options mismatch" do + let(:second) { Mustermann::Identity.new(":b", uri_decode: false) } + its(:class) { should be == Mustermann::Composite } + end + end + + describe "native concatination" do + subject { Mustermann.new(prefix) + Mustermann.new(pattern) } + let(:prefix) { "/a" } + let(:pattern) { "/:b(.:c)?" } + it { should match("/a/b.json") } + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/to_pattern_spec.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/to_pattern_spec.rb new file mode 100644 index 00000000..0668f19c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-3.0.3/spec/to_pattern_spec.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true +require 'support' +require 'mustermann/to_pattern' +require 'delegate' + +describe Mustermann::ToPattern do + context String do + example { "".to_pattern .should be_a(Mustermann::Sinatra) } + example { "".to_pattern(type: :rails) .should be_a(Mustermann::Rails) } + end + + context Regexp do + example { //.to_pattern .should be_a(Mustermann::Regular) } + example { //.to_pattern(type: :rails) .should be_a(Mustermann::Regular) } + end + + context Symbol do + example { :foo.to_pattern .should be_a(Mustermann::Sinatra) } + example { :foo.to_pattern(type: :rails) .should be_a(Mustermann::Sinatra) } + end + + context Array do + example { [:foo, :bar].to_pattern .should be_a(Mustermann::Composite) } + example { [:foo, :bar].to_pattern(type: :rails) .should be_a(Mustermann::Composite) } + end + + context Mustermann::Pattern do + subject(:pattern) { Mustermann.new('') } + example { pattern.to_pattern.should be == pattern } + example { pattern.to_pattern(type: :rails).should be_a(Mustermann::Sinatra) } + end + + context 'custom class' do + let(:example_class) do + Class.new do + include Mustermann::ToPattern + def to_s + ":foo/:bar" + end + end + end + + example { example_class.new.to_pattern .should be_a(Mustermann::Sinatra) } + example { example_class.new.to_pattern(type: :rails) .should be_a(Mustermann::Rails) } + example { Mustermann.new(example_class.new) .should be_a(Mustermann::Sinatra) } + example { Mustermann.new(example_class.new, type: :rails) .should be_a(Mustermann::Rails) } + end + + context 'primitive delegate' do + let(:example_class) do + Class.new(DelegateClass(Array)) do + include Mustermann::ToPattern + end + end + + example { example_class.new([:foo, :bar]).to_pattern .should be_a(Mustermann::Composite) } + example { example_class.new([:foo, :bar]).to_pattern(type: :rails) .should be_a(Mustermann::Composite) } + end + + context 'primitive subclass' do + let(:example_class) do + Class.new(Array) do + include Mustermann::ToPattern + end + end + + example { example_class.new([:foo, :bar]).to_pattern .should be_a(Mustermann::Composite) } + example { example_class.new([:foo, :bar]).to_pattern(type: :rails) .should be_a(Mustermann::Composite) } + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/.github/workflows/tests.yml b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/.github/workflows/tests.yml new file mode 100644 index 00000000..cbfb87ca --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/.github/workflows/tests.yml @@ -0,0 +1,22 @@ +name: tests +on: + [push, pull_request] + +jobs: + test: + + runs-on: ubuntu-latest + + strategy: + matrix: + ruby-version: ['2.6', '2.7', '3.0'] + + steps: + - uses: actions/checkout@v3 + - name: Set up Ruby ${{ matrix.ruby-version }} + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby-version }} + bundler-cache: true + - name: Run tests + run: bundle exec rspec \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/.gitignore b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/.gitignore new file mode 100644 index 00000000..4b40f722 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/.gitignore @@ -0,0 +1,2 @@ +pkg +Gemfile.lock \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/.rspec b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/.rspec new file mode 100644 index 00000000..b3eb8b49 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/.rspec @@ -0,0 +1,2 @@ +--color +--format documentation \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/CHANGELOG.md b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/CHANGELOG.md new file mode 100644 index 00000000..83653553 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/CHANGELOG.md @@ -0,0 +1,5 @@ +### 1.1.0 (2023/11/24) + +#### Fixes + +* [#21](https://github.com/ruby-grape/mustermann-grape/pull/21): Introducing the `params` option to `Mustermann::Grape` to enhance matching by offering detailed information regarding the parameter types. - [@jcagarcia](https://github.com/jcagarcia). diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/Gemfile b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/Gemfile new file mode 100644 index 00000000..ee112d84 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/Gemfile @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +source 'https://rubygems.org' + +gem 'support', git: 'https://github.com/sinatra/mustermann.git' + +gemspec + +gem 'rake' +gem 'rspec-core' diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/LICENSE b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/LICENSE new file mode 100644 index 00000000..7b0dbc70 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/LICENSE @@ -0,0 +1,20 @@ +Copyright Mustermann-Grape Contributors + +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 AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/README.md b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/README.md new file mode 100644 index 00000000..c860815e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/README.md @@ -0,0 +1,84 @@ +# Grape Syntax for Mustermann + +This gem implements the `grape` pattern type for Mustermann. + +[![tests](https://github.com/ruby-grape/mustermann-grape/workflows/tests/badge.svg)](https://github.com/ruby-grape/mustermann-grape/actions?query=workflow%3Atests) + +## Overview + +**Supported options:** +`capture`, `converters`, `except`, `greedy`, `ignore_unknown_options`, `params`, `space_matches_plus` and `uri_decode` + +``` ruby +require 'mustermann/grape' + +Mustermann.new('/:id', type: :grape).params('/foo') # => { id: 'foo' } + +# Providing params option +Mustermann.new('/:id', type: :grape, params: {"id"=>{:type=>"Integer"}}).params('/1') # => { id: '1'} +Mustermann.new('/:id', type: :grape, params: {"id"=>{:type=>"Integer"}}).params('/foo') # => nil +Mustermann.new('/:id', type: :grape, params: {"id"=>{:type=>"String"}}).params('/foo') # => { id: 'foo'} +``` + +## Syntax + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Syntax ElementDescription
:name or {name} + Captures anything but a forward slash in a semi-greedy fashion. Capture is named name. + Capture behavior can be modified with capture and greedy option. +
*name or {+name} + Captures anything in a non-greedy fashion. Capture is named name. +
* or {+splat} + Captures anything in a non-greedy fashion. Capture is named splat. + It is always an array of captures, as you can use it more than once in a pattern. +
(expression) + Enclosed expression is optional. +
expression|expression|... + Will match anything matching the nested expressions. May contain any other syntax element, including captures. +
x?Makes x optional. For instance, (foo)? matches foo or an empty string.
/ + Matches forward slash. Does not match URI encoded version of forward slash. +
\xMatches x or URI encoded version of x. For instance \* matches *.
any other characterMatches exactly that character or a URI encoded version of it.
diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/Rakefile b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/Rakefile new file mode 100644 index 00000000..3e76ace7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/Rakefile @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require 'rubygems' +require 'bundler' +Bundler.setup :default, :test, :development + +Bundler::GemHelper.install_tasks + +task(default: :rspec) +task(:rspec) { ruby '-S rspec' } diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/lib/mustermann/grape.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/lib/mustermann/grape.rb new file mode 100644 index 00000000..edd005da --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/lib/mustermann/grape.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +require 'mustermann' +require 'mustermann/ast/pattern' + +module Mustermann + # Grape style pattern implementation. + # + # @example + # Mustermann.new('/:foo', type: :grape) === '/bar' # => true + # + # @see Mustermann::Pattern + # @see file:README.md#grape Syntax description in the README + class Grape < AST::Pattern + register :grape + supported_options :params + + on(nil, '?', ')') { |c| unexpected(c) } + + on('*') { |_c| scan(/\w+/) ? node(:named_splat, buffer.matched) : node(:splat) } + on(':') do |_c| + param_name = scan(/\w+/) + return node(:capture, param_name, constraint: "[^/\\?#\.]") { scan(/\w+/) } unless pattern + + params_opt = pattern.options[:params] + if params_opt && params_opt[param_name] && params_opt[param_name][:type] + param_type = params_opt[param_name][:type] + case(param_type) + when "Integer" + node(:capture, param_name, constraint: /\d/) { scan(/\w+/) } + else + node(:capture, param_name, constraint: "[^/\\?#\.]") { scan(/\w+/) } + end + else + node(:capture, param_name, constraint: "[^/\\?#\.]") { scan(/\w+/) } + end + end + on('\\') { |_c| node(:char, expect(/./)) } + on('(') { |_c| node(:optional, node(:group) { read unless scan(')') }) } + on('|') { |_c| node(:or) } + + on '{' do |_char| + type = scan('+') ? :named_splat : :capture + name = expect(/[\w\.]+/) + type = :splat if (type == :named_splat) && (name == 'splat') + expect('}') + node(type, name) + end + + suffix '?' do |_char, element| + node(:optional, element) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/lib/mustermann/grape/version.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/lib/mustermann/grape/version.rb new file mode 100644 index 00000000..a932d050 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/lib/mustermann/grape/version.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +module MustermannGrape + VERSION = '1.1.0' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/mustermann-grape.gemspec b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/mustermann-grape.gemspec new file mode 100644 index 00000000..602b5a12 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/mustermann-grape.gemspec @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +$LOAD_PATH.push File.expand_path('lib', __dir__) + +require 'mustermann/grape/version' + +Gem::Specification.new do |s| + s.name = 'mustermann-grape' + s.version = MustermannGrape::VERSION + s.authors = ['namusyaka', 'Konstantin Haase', 'Daniel Doubrovkine'] + s.email = 'namusyaka@gmail.com' + s.homepage = 'https://github.com/ruby-grape/mustermann-grape' + s.summary = 'Grape syntax for Mustermann' + s.description = 'Adds Grape style patterns to Mustermman' + s.license = 'MIT' + s.required_ruby_version = '>= 2.1.0' + s.files = `git ls-files`.split("\n") + s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") + s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) } + s.add_dependency 'mustermann', '>= 1.0.0' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/spec/grape_spec.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/spec/grape_spec.rb new file mode 100644 index 00000000..c47109d7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/spec/grape_spec.rb @@ -0,0 +1,783 @@ +# frozen_string_literal: true + +require 'spec_helper' + +require 'support/env' +require 'support/match_matcher' +require 'support/expand_matcher' +require 'support/pattern' +require 'support/generate_template_matcher' +require 'support/scan_matcher' + +describe Mustermann::Grape do + extend Support::Pattern + + pattern '' do + it { should match('') } + it { should_not match('/') } + + it { should generate_template('') } + + it { should respond_to(:expand) } + it { should respond_to(:to_templates) } + end + + pattern '/' do + it { should match('/') } + it { should_not match('/foo') } + end + + pattern '/foo' do + it { should match('/foo') } + it { should_not match('/bar') } + it { should_not match('/foo.bar') } + end + + pattern '/foo/bar' do + it { should match('/foo/bar') } + it { should_not match('/foo%2Fbar') } + it { should_not match('/foo%2fbar') } + end + + pattern '/foo\/bar' do + it { should match('/foo/bar') } + it { should match('/foo%2Fbar') } + it { should match('/foo%2fbar') } + end + + pattern '/:foo' do + it { should match('/foo') .capturing foo: 'foo' } + it { should match('/bar') .capturing foo: 'bar' } + it { should match('/%0Afoo') .capturing foo: '%0Afoo' } + it { should match('/foo%2Fbar') .capturing foo: 'foo%2Fbar' } + + it { should_not match('/foo.bar') } + it { should_not match('/foo?') } + it { should_not match('/foo/bar') } + it { should_not match('/') } + it { should_not match('/foo/') } + + it { should generate_template('/{foo}') } + end + + pattern '/föö' do + it { should match('/f%C3%B6%C3%B6') } + end + + pattern '/:foo/:bar' do + it { should match('/foo/bar') .capturing foo: 'foo', bar: 'bar' } + it { should_not match('/foo.bar/bar.foo') } + it { should_not match('/user@example.com/name') } + it { should_not match('/10.1/te.st') } + it { should_not match('/10.1.2/te.st') } + + it { should_not match('/foo%2Fbar') } + it { should_not match('/foo%2fbar') } + + example { pattern.params('/bar/foo').should be == { 'foo' => 'bar', 'bar' => 'foo' } } + example { pattern.params('').should be_nil } + + it { should generate_template('/{foo}/{bar}') } + end + + pattern '/{foo}/{bar}' do + it { should match('/foo/bar') .capturing foo: 'foo', bar: 'bar' } + it { should match('/foo.bar/bar.foo') .capturing foo: 'foo.bar', bar: 'bar.foo' } + it { should match('/user@example.com/name') .capturing foo: 'user@example.com', bar: 'name' } + it { should match('/10.1/te.st') .capturing foo: '10.1', bar: 'te.st' } + it { should match('/10.1.2/te.st') .capturing foo: '10.1.2', bar: 'te.st' } + + it { should_not match('/foo%2Fbar') } + it { should_not match('/foo%2fbar') } + + example { pattern.params('/bar/foo').should be == { 'foo' => 'bar', 'bar' => 'foo' } } + example { pattern.params('').should be_nil } + + it { should generate_template('/{foo}/{bar}') } + end + + pattern '/hello/:person' do + it { should match('/hello/Frank').capturing person: 'Frank' } + it { should generate_template('/hello/{person}') } + end + + pattern '/hello/{person}' do + it { should match('/hello/Frank').capturing person: 'Frank' } + it { should generate_template('/hello/{person}') } + end + + pattern '/?:foo?/?:bar?' do + it { should match('/hello/world') .capturing foo: 'hello', bar: 'world' } + it { should match('/hello') .capturing foo: 'hello', bar: nil } + it { should match('/') .capturing foo: nil, bar: nil } + it { should match('') .capturing foo: nil, bar: nil } + + it { should expand(foo: 'hello') .to('/hello/') } + it { should expand(foo: 'hello', bar: 'world') .to('/hello/world') } + it { should expand(bar: 'world') .to('//world') } + it { should expand .to('//') } + it { should_not expand(baz: '') } + + it { should_not match('/hello/world/') } + it { should generate_templates('', '/', '//', '//{bar}', '/{bar}', '/{foo}', '/{foo}/', '/{foo}/{bar}', '/{foo}{bar}', '{bar}', '{foo}', '{foo}/', '{foo}/{bar}', '{foo}{bar}') } + end + + pattern '/:foo_bar' do + it { should match('/hello').capturing foo_bar: 'hello' } + it { should generate_template('/{foo_bar}') } + end + + pattern '/{foo.bar}' do + it { should match('/hello').capturing "foo.bar": 'hello' } + it { should generate_template('/{foo.bar}') } + end + + pattern '/*' do + it { should match('/') .capturing splat: '' } + it { should match('/foo') .capturing splat: 'foo' } + it { should match('/foo/bar') .capturing splat: 'foo/bar' } + it { should generate_template('/{+splat}') } + + example { pattern.params('/foo').should be == { 'splat' => ['foo'] } } + end + + pattern '/{+splat}' do + it { should match('/') .capturing splat: '' } + it { should match('/foo') .capturing splat: 'foo' } + it { should match('/foo/bar') .capturing splat: 'foo/bar' } + it { should generate_template('/{+splat}') } + + example { pattern.params('/foo').should be == { 'splat' => ['foo'] } } + end + + pattern '/*foo' do + it { should match('/') .capturing foo: '' } + it { should match('/foo') .capturing foo: 'foo' } + it { should match('/foo/bar') .capturing foo: 'foo/bar' } + it { should generate_template('/{+foo}') } + + example { pattern.params('/foo') .should be == { 'foo' => 'foo' } } + example { pattern.params('/foo/bar') .should be == { 'foo' => 'foo/bar' } } + end + + pattern '/{+foo}' do + it { should match('/') .capturing foo: '' } + it { should match('/foo') .capturing foo: 'foo' } + it { should match('/foo/bar') .capturing foo: 'foo/bar' } + it { should generate_template('/{+foo}') } + + example { pattern.params('/foo') .should be == { 'foo' => 'foo' } } + example { pattern.params('/foo/bar') .should be == { 'foo' => 'foo/bar' } } + end + + pattern '/*foo/*bar' do + it { should match('/foo/bar') .capturing foo: 'foo', bar: 'bar' } + it { should generate_template('/{+foo}/{+bar}') } + end + + pattern '/{+foo}/{+bar}' do + it { should match('/foo/bar') .capturing foo: 'foo', bar: 'bar' } + it { should generate_template('/{+foo}/{+bar}') } + end + + pattern '/:foo/*' do + it { should match('/foo/bar/baz') .capturing foo: 'foo', splat: 'bar/baz' } + it { should match('/foo/') .capturing foo: 'foo', splat: '' } + it { should match('/h%20w/h%20a%20y') .capturing foo: 'h%20w', splat: 'h%20a%20y' } + it { should_not match('/foo') } + it { should generate_template('/{foo}/{+splat}') } + + example { pattern.params('/bar/foo').should be == { 'splat' => ['foo'], 'foo' => 'bar' } } + example { pattern.params('/bar/foo/f%20o').should be == { 'splat' => ['foo/f o'], 'foo' => 'bar' } } + end + + pattern '/{foo}/*' do + it { should match('/foo/bar/baz') .capturing foo: 'foo', splat: 'bar/baz' } + it { should match('/foo/') .capturing foo: 'foo', splat: '' } + it { should match('/h%20w/h%20a%20y') .capturing foo: 'h%20w', splat: 'h%20a%20y' } + it { should_not match('/foo') } + it { should generate_template('/{foo}/{+splat}') } + + example { pattern.params('/bar/foo').should be == { 'splat' => ['foo'], 'foo' => 'bar' } } + example { pattern.params('/bar/foo/f%20o').should be == { 'splat' => ['foo/f o'], 'foo' => 'bar' } } + end + + pattern '/test$/' do + it { should match('/test$/') } + end + + pattern '/te+st/' do + it { should match('/te+st/') } + it { should_not match('/test/') } + it { should_not match('/teest/') } + end + + pattern '/path with spaces' do + it { should match('/path%20with%20spaces') } + it { should match('/path%2Bwith%2Bspaces') } + it { should match('/path+with+spaces') } + + it { should generate_template('/path%20with%20spaces') } + end + + pattern '/foo&bar' do + it { should match('/foo&bar') } + end + + pattern '/foo\{bar' do + it { should match('/foo%7Bbar') } + end + + pattern '/*/:foo/*/*' do + it { should match('/bar/foo/bling/baz/boom') } + + it 'should capture all splat parts' do + match = pattern.match('/bar/foo/bling/baz/boom') + match.captures.should be == ['bar', 'foo', 'bling', 'baz/boom'] + match.names.should be == %w[splat foo] + end + + it 'should map to proper params' do + pattern.params('/bar/foo/bling/baz/boom').should be == { + 'foo' => 'foo', 'splat' => ['bar', 'bling', 'baz/boom'] + } + end + end + + pattern '/{+splat}/{foo}/{+splat}/{+splat}' do + it { should match('/bar/foo/bling/baz/boom') } + + it 'should capture all splat parts' do + match = pattern.match('/bar/foo/bling/baz/boom') + match.captures.should be == ['bar', 'foo', 'bling', 'baz/boom'] + match.names.should be == %w[splat foo] + end + + it 'should map to proper params' do + pattern.params('/bar/foo/bling/baz/boom').should be == { + 'foo' => 'foo', 'splat' => ['bar', 'bling', 'baz/boom'] + } + end + end + + pattern '/test.bar' do + it { should match('/test.bar') } + it { should_not match('/test0bar') } + end + + pattern '/:file.:ext' do + it { should match('/pony.jpg') .capturing file: 'pony', ext: 'jpg' } + it { should match('/pony%2Ejpg') .capturing file: 'pony', ext: 'jpg' } + it { should match('/pony%2ejpg') .capturing file: 'pony', ext: 'jpg' } + + it { should match('/pony%E6%AD%A3%2Ejpg') .capturing file: 'pony%E6%AD%A3', ext: 'jpg' } + it { should match('/pony%e6%ad%a3%2ejpg') .capturing file: 'pony%e6%ad%a3', ext: 'jpg' } + it { should match('/pony正%2Ejpg') .capturing file: 'pony正', ext: 'jpg' } + it { should match('/pony正%2ejpg') .capturing file: 'pony正', ext: 'jpg' } + + it { should_not match('/pony正..jpg') } + it { should_not match('/.jpg') } + end + + pattern '/(:a)x?' do + it { should match('/a') .capturing a: 'a' } + it { should match('/xa') .capturing a: 'xa' } + it { should match('/axa') .capturing a: 'axa' } + + it { should generate_template('/{a}x') } + it { should generate_template('/{a}') } + end + + pattern '/:user(@:host)?' do + it { should match('/foo@bar') .capturing user: 'foo', host: 'bar' } + it { should_not match('/foo.foo@bar') } + it { should_not match('/foo@bar.bar') } + + it { should generate_template('/{user}') } + it { should generate_template('/{user}@{host}') } + end + + pattern '/:file(.:ext)?' do + it { should match('/pony') .capturing file: 'pony', ext: nil } + it { should match('/pony.jpg') .capturing file: 'pony', ext: 'jpg' } + it { should match('/pony%2Ejpg') .capturing file: 'pony', ext: 'jpg' } + it { should match('/pony%2ejpg') .capturing file: 'pony', ext: 'jpg' } + it { should_not match('/pony.png.jpg') } + it { should_not match('/pony.') } + it { should_not match('/.jpg') } + + it { should generate_template('/{file}') } + it { should generate_template('/{file}.{ext}') } + it { should_not generate_template('/{file}.') } + end + + pattern '/:id/test.bar' do + it { should match('/3/test.bar') .capturing id: '3' } + it { should match('/2/test.bar') .capturing id: '2' } + it { should match('/2E/test.bar') .capturing id: '2E' } + it { should match('/2e/test.bar') .capturing id: '2e' } + it { should match('/%2E/test.bar') .capturing id: '%2E' } + end + + pattern '/10/:id' do + it { should match('/10/test') .capturing id: 'test' } + it { should_not match('/10/te.st') } + end + + pattern '/10.1/:id' do + it { should match('/10.1/test') .capturing id: 'test' } + it { should_not match('/10.1/te.st') } + end + + pattern '/:foo.:bar/:id' do + it { should_not match('/10.1/te.st') } + it { should_not match('/10.1.2/te.st') } + end + + pattern '/:a/:b.?:c?' do + it { should match('/a/b') .capturing a: 'a', b: 'b', c: nil } + it { should match('/a/b.c') .capturing a: 'a', b: 'b', c: 'c' } + it { should_not match('/a.b/c') } + it { should_not match('/a.b/c.d') } + it { should_not match('/a.b/c.d/e') } + end + + pattern '/:a(foo:b)?' do + it { should match('/barfoobar') .capturing a: 'bar', b: 'bar' } + it { should match('/barfoobarfoobar') .capturing a: 'barfoobar', b: 'bar' } + it { should match('/bar') .capturing a: 'bar', b: nil } + it { should_not match('/') } + end + + pattern '/foo?' do + it { should match('/fo') } + it { should match('/foo') } + it { should_not match('') } + it { should_not match('/') } + it { should_not match('/f') } + it { should_not match('/fooo') } + end + + pattern '/foo\?' do + it { should match('/foo?') } + it { should_not match('/foo\?') } + it { should_not match('/fo') } + it { should_not match('/foo') } + it { should_not match('') } + it { should_not match('/') } + it { should_not match('/f') } + it { should_not match('/fooo') } + end + + pattern '/foo\\\?' do + it { should match('/foo%5c') } + it { should match('/foo') } + it { should_not match('/foo\?') } + it { should_not match('/fo') } + it { should_not match('') } + it { should_not match('/') } + it { should_not match('/f') } + it { should_not match('/fooo') } + end + + pattern '/\(' do + it { should match('/(') } + end + + pattern '/\(?' do + it { should match('/(') } + it { should match('/') } + end + + pattern '/(\()?' do + it { should match('/(') } + it { should match('/') } + end + + pattern '/(\(\))?' do + it { should match('/') } + it { should match('/()') } + it { should_not match('/(') } + end + + pattern '/\(\)?' do + it { should match('/(') } + it { should match('/()') } + it { should_not match('/') } + end + + pattern '/\*' do + it { should match('/*') } + it { should_not match('/a') } + end + + pattern '/\*/*' do + it { should match('/*/b/c') } + it { should_not match('/a/b/c') } + end + + pattern '/\:foo' do + it { should match('/:foo') } + it { should_not match('/foo') } + end + + pattern '/:fOO' do + it { should match('/a').capturing fOO: 'a' } + end + + pattern '/:_X' do + it { should match('/a').capturing _X: 'a' } + end + + pattern '/:f00' do + it { should match('/a').capturing f00: 'a' } + end + + pattern '/:foo(/:bar)?/:baz?' do + it { should match('/foo/bar/baz').capturing foo: 'foo', bar: 'bar', baz: 'baz' } + end + + pattern '/(foo|bar)' do + it { should match('/foo') } + it { should match('/bar') } + end + + pattern '/(foo\\|bar)' do + it { should match '/foo%7Cbar' } + it { should generate_template '/foo%7Cbar' } + + it { should_not match('/foo') } + it { should_not match('/bar') } + + it { should_not generate_template('/foo') } + it { should_not generate_template('/bar') } + end + + pattern '/(:a/:b|:c)' do + it { should match('/foo') .capturing c: 'foo' } + it { should match('/foo/bar') .capturing a: 'foo', b: 'bar' } + + it { should expand(a: 'foo', b: 'bar') .to('/foo/bar') } + it { should expand(c: 'foo') .to('/foo') } + it { should_not expand(a: 'foo', b: 'bar', c: 'baz') } + end + + pattern '/:a/:b|:c' do + it { should match('foo') .capturing c: 'foo' } + it { should match('/foo/bar') .capturing a: 'foo', b: 'bar' } + + it { should generate_template('/{a}/{b}') } + it { should generate_template('{c}') } + + it { should expand(a: 'foo', b: 'bar') .to('/foo/bar') } + it { should expand(c: 'foo') .to('foo') } + it { should_not expand(a: 'foo', b: 'bar', c: 'baz') } + end + + pattern '/:foo', capture: /\d+/ do + it { should match('/1') .capturing foo: '1' } + it { should match('/123') .capturing foo: '123' } + + it { should_not match('/') } + it { should_not match('/foo') } + end + + pattern '/:foo', capture: /\d+/ do + it { should match('/1') .capturing foo: '1' } + it { should match('/123') .capturing foo: '123' } + + it { should_not match('/') } + it { should_not match('/foo') } + end + + pattern '/:foo', capture: '1' do + it { should match('/1').capturing foo: '1' } + + it { should_not match('/') } + it { should_not match('/foo') } + it { should_not match('/123') } + end + + pattern '/:foo', capture: 'a.b' do + it { should match('/a.b') .capturing foo: 'a.b' } + it { should match('/a%2Eb') .capturing foo: 'a%2Eb' } + it { should match('/a%2eb') .capturing foo: 'a%2eb' } + + it { should_not match('/ab') } + it { should_not match('/afb') } + it { should_not match('/a1b') } + it { should_not match('/a.bc') } + end + + pattern '/:foo(/:bar)?', capture: :alpha do + it { should match('/abc') .capturing foo: 'abc', bar: nil } + it { should match('/a/b') .capturing foo: 'a', bar: 'b' } + it { should match('/a') .capturing foo: 'a', bar: nil } + + it { should_not match('/1/2') } + it { should_not match('/a/2') } + it { should_not match('/1/b') } + it { should_not match('/1') } + it { should_not match('/1/') } + it { should_not match('/a/') } + it { should_not match('//a') } + end + + pattern '/:foo', capture: ['foo', 'bar', /\d+/] do + it { should match('/1') .capturing foo: '1' } + it { should match('/123') .capturing foo: '123' } + it { should match('/foo') .capturing foo: 'foo' } + it { should match('/bar') .capturing foo: 'bar' } + + it { should_not match('/') } + it { should_not match('/baz') } + it { should_not match('/foo1') } + end + + pattern '/:foo:bar:baz', capture: { foo: :alpha, bar: /\d+/ } do + it { should match('/ab123xy-1') .capturing foo: 'ab', bar: '123', baz: 'xy-1' } + it { should match('/ab123') .capturing foo: 'ab', bar: '12', baz: '3' } + it { should_not match('/123abcxy-1') } + it { should_not match('/abcxy-1') } + it { should_not match('/abc1') } + end + + pattern '/:foo', capture: { foo: ['foo', 'bar', /\d+/] } do + it { should match('/1') .capturing foo: '1' } + it { should match('/123') .capturing foo: '123' } + it { should match('/foo') .capturing foo: 'foo' } + it { should match('/bar') .capturing foo: 'bar' } + + it { should_not match('/') } + it { should_not match('/baz') } + it { should_not match('/foo1') } + end + + pattern '/:file(.:ext)?', capture: { ext: %w[jpg png] } do + it { should match('/pony') .capturing file: 'pony', ext: nil } + it { should match('/pony.jpg') .capturing file: 'pony', ext: 'jpg' } + it { should match('/pony%2Ejpg') .capturing file: 'pony', ext: 'jpg' } + it { should match('/pony%2ejpg') .capturing file: 'pony', ext: 'jpg' } + it { should match('/pony.png') .capturing file: 'pony', ext: 'png' } + it { should match('/pony%2Epng') .capturing file: 'pony', ext: 'png' } + it { should match('/pony%2epng') .capturing file: 'pony', ext: 'png' } + it { should_not match('/pony.png.jpg') } + it { should_not match('/pony.jpg.png') } + it { should_not match('/pony.gif') } + it { should_not match('/pony.') } + it { should_not match('.jpg') } + end + + pattern '/:file:ext?', capture: { ext: ['.jpg', '.png', '.tar.gz'] } do + it { should match('/pony') .capturing file: 'pony', ext: nil } + it { should match('/pony.jpg') .capturing file: 'pony', ext: '.jpg' } + it { should match('/pony.png') .capturing file: 'pony', ext: '.png' } + it { should match('/pony.tar.gz') .capturing file: 'pony', ext: '.tar.gz' } + it { should_not match('/pony.png.jpg') } + it { should_not match('/pony.jpg.png') } + it { should_not match('/pony.gif') } + it { should_not match('/pony.') } + it { should_not match('/.jpg') } + end + + pattern '/:a(@:b)?', capture: { b: /\d+/ } do + it { should match('/a') .capturing a: 'a', b: nil } + it { should match('/a@1') .capturing a: 'a', b: '1' } + it { should match('/a@b') .capturing a: 'a@b', b: nil } + it { should match('/a@1@2') .capturing a: 'a@1', b: '2' } + end + + pattern '/(:a)b?', greedy: false do + it { should match('/ab').capturing a: 'a' } + end + + pattern '/:file(.:ext)?', greedy: false do + it { should match('/pony') .capturing file: 'pony', ext: nil } + it { should match('/pony.jpg') .capturing file: 'pony', ext: 'jpg' } + it { should_not match('/pony.png.jpg') } + end + + pattern '/auth/*', except: '/auth/login' do + it { should match('/auth/admin') } + it { should match('/auth/foobar') } + it { should_not match('/auth/login') } + end + + pattern '/:foo/:bar', except: '/:bar/20' do + it { should match('/foo/bar').capturing foo: 'foo', bar: 'bar' } + it { should_not match('/20/20') } + end + + pattern '/foo?', uri_decode: false do + it { should match('/foo') } + it { should match('/fo') } + it { should_not match('/foo?') } + end + + pattern '/foo/bar', uri_decode: false do + it { should match('/foo/bar') } + it { should_not match('/foo%2Fbar') } + it { should_not match('/foo%2fbar') } + end + + pattern '/path with spaces', uri_decode: false do + it { should match('/path with spaces') } + it { should_not match('/path%20with%20spaces') } + it { should_not match('/path%2Bwith%2Bspaces') } + it { should_not match('/path+with+spaces') } + end + + pattern '/path with spaces', space_matches_plus: false do + it { should match('/path%20with%20spaces') } + it { should_not match('/path%2Bwith%2Bspaces') } + it { should_not match('/path+with+spaces') } + end + + context 'invalid syntax' do + example 'unexpected closing parenthesis' do + expect { Mustermann::Grape.new('foo)bar') } + .to raise_error(Mustermann::ParseError, 'unexpected ) while parsing "foo)bar"') + end + + example 'missing closing parenthesis' do + expect { Mustermann::Grape.new('foo(bar') } + .to raise_error(Mustermann::ParseError, 'unexpected end of string while parsing "foo(bar"') + end + + example 'missing unescaped closing parenthesis' do + expect { Mustermann::Grape.new('foo(bar\)') } + .to raise_error(Mustermann::ParseError, 'unexpected end of string while parsing "foo(bar\\\\)"') + end + + example '? at beginning of route' do + expect { Mustermann::Grape.new('?foobar') } + .to raise_error(Mustermann::ParseError, 'unexpected ? while parsing "?foobar"') + end + + example 'double ?' do + expect { Mustermann::Grape.new('foo??bar') } + .to raise_error(Mustermann::ParseError, 'unexpected ? while parsing "foo??bar"') + end + + example 'dangling escape' do + expect { Mustermann::Grape.new('foo\\') } + .to raise_error(Mustermann::ParseError, 'unexpected end of string while parsing "foo\\\\"') + end + end + + context 'invalid capture names' do + example 'empty name' do + expect { Mustermann::Grape.new('/:/') } + .to raise_error(Mustermann::CompileError, "capture name can't be empty: \"/:/\"") + end + + example 'named splat' do + expect { Mustermann::Grape.new('/:splat/') } + .to raise_error(Mustermann::CompileError, "capture name can't be splat: \"/:splat/\"") + end + + example 'named captures' do + expect { Mustermann::Grape.new('/:captures/') } + .to raise_error(Mustermann::CompileError, "capture name can't be captures: \"/:captures/\"") + end + + example 'with capital letter' do + expect { Mustermann::Grape.new('/:Foo/') } + .to raise_error(Mustermann::CompileError, 'capture name must start with underscore or lower case letter: "/:Foo/"') + end + + example 'with integer' do + expect { Mustermann::Grape.new('/:1a/') } + .to raise_error(Mustermann::CompileError, 'capture name must start with underscore or lower case letter: "/:1a/"') + end + + example 'same name twice' do + expect { Mustermann::Grape.new('/:foo(/:bar)?/:bar?') } + .to raise_error(Mustermann::CompileError, "can't use the same capture name twice: \"/:foo(/:bar)?/:bar?\"") + end + end + + context 'Regexp compatibility' do + describe :=== do + example('non-matching') { Mustermann::Grape.new('/') .should_not be === '/foo' } + example('matching') { Mustermann::Grape.new('/:foo') .should be === '/foo' } + end + + describe :=~ do + example('non-matching') { Mustermann::Grape.new('/') .should_not be =~ '/foo' } + example('matching') { Mustermann::Grape.new('/:foo') .should be =~ '/foo' } + + context 'String#=~' do + example('non-matching') { '/foo'.should_not be =~ Mustermann::Grape.new('/') } + example('matching') { '/foo'.should be =~ Mustermann::Grape.new('/:foo') } + end + end + + describe :to_regexp do + example('empty pattern') { Mustermann::Grape.new('').to_regexp.should be == /\A(?-mix:)\Z/ } + + context 'Regexp.try_convert' do + example('empty pattern') { Regexp.try_convert(Mustermann::Grape.new('')).should be == /\A(?-mix:)\Z/ } + end + end + end + + context 'Proc compatibility' do + describe :to_proc do + example { Mustermann::Grape.new('/').to_proc.should be_a(Proc) } + example('non-matching') { Mustermann::Grape.new('/') .to_proc.call('/foo').should be == false } + example('matching') { Mustermann::Grape.new('/:foo') .to_proc.call('/foo').should be == true } + end + end + + context 'peeking' do + subject(:pattern) { Mustermann::Grape.new(':name') } + + describe :peek_size do + example { pattern.peek_size('foo bar/blah') .should be == 'foo bar'.size } + example { pattern.peek_size('foo%20bar/blah') .should be == 'foo%20bar'.size } + example { pattern.peek_size('/foo bar') .should be_nil } + end + + describe :peek_match do + example { pattern.peek_match('foo bar/blah') .to_s .should be == 'foo bar' } + example { pattern.peek_match('foo%20bar/blah') .to_s .should be == 'foo%20bar' } + example { pattern.peek_match('/foo bar') .should be_nil } + end + + describe :peek_params do + example { pattern.peek_params('foo bar/blah') .should be == [{ 'name' => 'foo bar' }, 'foo bar'.size] } + example { pattern.peek_params('foo%20bar/blah') .should be == [{ 'name' => 'foo bar' }, 'foo%20bar'.size] } + example { pattern.peek_params('/foo bar') .should be_nil } + end + end + + context 'when params option is provided' do + context 'and they contain parameters information' do + pattern '/foo/:id', params: {"id"=>{:type=>"Integer"}} do + it { should match('/foo/1') } + it { should_not match('/foo/bar') } + end + + context 'and inherit routes are present' do + pattern '/foo/:id/bar/:reference', params: {"id"=>{:type=>"Integer"}, "reference"=>{:type=>"String"}} do + it { should match('/foo/1/bar/wadus') } + it { should_not match('/foo/bar/bar/wadus') } + end + + pattern '/foo/:id/bar/:reference', params: {"id"=>{:type=>"Integer"}, "reference"=>{:type=>"Integer"}} do + it { should match('/foo/1/bar/1') } + it { should_not match('/foo/1/bar/wadus') } + it { should_not match('/foo/bar/bar/1') } + end + end + end + + context 'and they do NOT contain parameters information' do + pattern '/foo/:id' do + it { should match('/foo/1') } + it { should match('/foo/bar') } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/spec/spec_helper.rb b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/spec/spec_helper.rb new file mode 100644 index 00000000..d444e7af --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/mustermann-grape-1.1.0/spec/spec_helper.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..')) + +require 'mustermann/grape' diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/changes.md b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/changes.md new file mode 100644 index 00000000..298f2f6f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/changes.md @@ -0,0 +1,332 @@ +## 2.7.2 + +* Modernize gem (list all authors, etc). +* Drop official support for Ruby 2.4. +* Fix JRuby release version. + +## 2.7.1 + +* Fix license specification. +* Fix JRuby build warnings. + +## 2.7.0 + +* Convert NIO objects to TypedData API. + +## 2.6.1 + +* Don't update `io` which is subsequently stored. Retain the original. + +## 2.6.0 + +* Fix conversion loses int precision. +* Avoid direct access to IO internals. +* Resolve issue loading both nio and nio4r gems. + +## 2.5.9 (2023-04-02) + +https://github.com/socketry/nio4r/compare/v2.5.8..v2.5.9 + +## 2.5.8 (2021-08-03) + +* [#276](https://github.com/socketry/nio4r/pull/276) + Fix missing return statement in function returning non-void (issue [#275](https://github.com/socketry/nio4r/pull/275)) + ([@ioquatix]) +* Remove `guard-rspec` from development dependencies ([@ioquatix]) + +## 2.5.7 (2021-03-04) + +* [#267](https://github.com/socketry/nio4r/pull/267) + Don't try to link universal extension + ([@ioquatix]) + +## 2.5.6 (2021-03-04) + +* [#268](https://github.com/socketry/nio4r/pull/268) + Prefer kqueue when on OSX >= v10.12.2 + ([@jcmfernandes]) + +## 2.5.5 (2021-02-05) + +* [#256](https://github.com/socketry/nio4r/pull/256) + Use libev 4.33, featuring experimental `io_uring` support. + ([@jcmfernandes]) + +* [#260](https://github.com/socketry/nio4r/pull/260) + Workaround for ARM-based macOS Ruby: Use pure Ruby for M1, since the native extension is crashing on M1 (arm64). + ([@jasl]) + +* [#252](https://github.com/socketry/nio4r/pull/252) + JRuby: Fix javac -Xlint warnings + ([@headius]) + +## 2.5.4 (2020-09-16) + +* [#251](https://github.com/socketry/nio4r/issues/251) + Intermittent SEGV during GC. + ([@boazsegev]) + +## 2.5.3 (2020-09-07) + +* [#241](https://github.com/socketry/nio4r/issues/241) + Possible bug with Ruby >= 2.7.0 and `GC.compact`. + ([@boazsegev]) + +## 2.5.2 (2019-09-24) + +* [#220](https://github.com/socketry/nio4r/issues/220) + Update to libev-4.27 & fix assorted warnings. + ([@ioquatix]) + +* [#225](https://github.com/socketry/nio4r/issues/225) + Avoid need for linux headers. + ([@ioquatix]) + +## 2.4.0 (2019-07-07) + +* [#211](https://github.com/socketry/nio4r/pull/211) + Enable KQUEUE on macOS 10.14+. + ([@ioquatix]) + +* Bump minimum supported Ruby to 2.3. + ([@ioquatix]) + +* Assorted fixes for TruffleRuby & JRuby. + ([@eregon], [@olleolleolle]) +Possible bug with Ruby >= 2.7.0 and `GC.compact` +* Update libev to v4.25. + ([@ioquatix]) + +* Bind to ephemeral (port 0) for more reliable specs. + ([@ioquatix]) + +* Improve handling of SSL sockets and related specs. + ([@MSP-Greg]) + +## 2.3.1 (2018-05-03) + +* [#188](https://github.com/socketry/nio4r/pull/188) + Fix remove interests + ([@ioquatix]) + +## 2.3.0 (2018-03-15) + +* [#183](https://github.com/socketry/nio4r/pull/183) + Allow `Monitor#interests` to be nil + ([@ioquatix]) + +## 2.2.0 (2017-12-27) + +* [#151](https://github.com/socketry/nio4r/pull/151) + `NIO::Selector`: Support for enumerating and configuring backend + ([@tarcieri]) + +* [#153](https://github.com/socketry/nio4r/pull/153) + Fix builds on Windows + ([@unak]) + +* [#157](https://github.com/socketry/nio4r/pull/157) + Windows / MinGW test failure - fix spec_helper.rb + ([@MSP-Greg]) + +* [#162](https://github.com/socketry/nio4r/pull/162) + Don't build the C extension on Windows + ([@larskanis]) + +* [#164](https://github.com/socketry/nio4r/pull/164) + Fix NIO::ByteBuffer leak + ([@HoneyryderChuck]) + +* [#170](https://github.com/socketry/nio4r/pull/170) + Avoid CancelledKeyExceptions on JRuby + ([@HoneyryderChuck]) + +* [#177](https://github.com/socketry/nio4r/pull/177) + Fix `NIO::ByteBuffer` string conversions on JRuby + ([@tarcieri]) + +* [#179](https://github.com/socketry/nio4r/pull/179) + Fix argument error when running on ruby 2.5.0 + ([@tompng]) + +* [#180](https://github.com/socketry/nio4r/pull/180) + ext/nio4r/extconf.rb: check for port_event_t in port.h (fixes #178) + ([@tarcieri]) + +## 2.1.0 (2017-05-28) + +* [#130](https://github.com/socketry/nio4r/pull/130) + Add -fno-strict-aliasing flag when compiling C ext. + ([@junaruga]) + +* [#146](https://github.com/socketry/nio4r/pull/146) + Use non-blocking select when a timeout of 0 is given. + ([@tarcieri]) + +* [#147](https://github.com/socketry/nio4r/pull/147) + Update to libev 4.24. + ([@tarcieri]) + +* [#148](https://github.com/socketry/nio4r/pull/148) + Switch to the libev 4 API internally. + ([@tarcieri]) + +## 2.0.0 (2016-12-28) + +* [#53](https://github.com/socketry/nio4r/pull/53) + Limit lock scope to prevent recursive locking. + ([@johnnyt]) + +* [#95](https://github.com/socketry/nio4r/pull/95) + NIO::ByteBuffer Google Summer of Code project. + ([@UpeksheJay], [@tarcieri]) + +* [#111](https://github.com/socketry/nio4r/pull/111) + NIO::Selector#backend introspection support. + ([@tarcieri]) + +* [#112](https://github.com/socketry/nio4r/pull/112) + Upgrade to libev 4.23. + ([@tarcieri]) + +* [#119](https://github.com/socketry/nio4r/pull/119) + Disambiguate wakeup vs timeout (fixes #63, #66). + ([@tarcieri]) + +* [#124](https://github.com/socketry/nio4r/pull/124) + Monitor interests API improvements. + ([@tarcieri]) + +* Drop Ruby 2.0 and 2.1 support, require Ruby 2.2.2+. + ([@tarcieri]) + +## 1.2.1 (2016-01-31) + +* Fix bug in the JRuby backend which cases indefinite blocking when small + timeout values are passed to the selector + +## 1.2.0 (2015-12-22) + +* Add NIO::Monitor#interests= API for changing interests. Contributed by + Upekshe Jayasekera as a Google Summer of Code project. +* Update to libev 4.22 + +## 1.1.1 (2015-07-17) + +* Update to libev 4.20 +* Fall back to io.h if unistd.h is not found +* RSpec updates +* RuboCop + +## 1.1.0 (2015-01-10) + +* Update to libev 4.19 +* Do not call ev_io_stop on monitors if the loop is already closed + +## 1.0.1 (2014-09-01) + +* Fix C compiler warnings +* Eliminate Ruby warnings about @lock_holder +* Windows improvements +* Better support for Ruby 2.1 +* Automatically require 'set' +* Update to RSpec 3 + +## 1.0.0 (2014-01-14) + +* Have Selector#register obtain the actual IO from a Monitor object + because Monitor#initialize might convert it. +* Drop 1.8 support + +## 0.5.0 (2013-08-06) + +* Fix segv when attempting to register to a closed selector +* Fix Windows support on Ruby 2.0.0 +* Upgrade to libev 4.15 + +## 0.4.6 (2013-05-27) + +* Fix for JRuby on Windows + +## 0.4.5 + +* Fix botched gem release + +## 0.4.4 + +* Fix return values for Selector_synchronize and Selector_unlock + +## 0.4.3 + +* REALLY have thread synchronization when closing selectors ;) + +## 0.4.2 + +* Attempt to work around packaging problems with bundler-api o_O + +## 0.4.1 + +* Thread synchronization when closing selectors + +## 0.4.0 + +* OpenSSL::SSL::SSLSocket support + +## 0.3.3 + +* NIO::Selector#select_each removed +* Remove event buffer +* Patch GIL unlock directly into libev +* Re-release since 0.3.2 was botched :( + +## 0.3.1 + +* Prevent CancelledKeyExceptions on JRuby + +## 0.3.0 + +* NIO::Selector#select now takes a block and behaves like select_each +* NIO::Selector#select_each is now deprecated and will be removed +* Closing monitors detaches them from their selector +* Java extension for JRuby +* Upgrade to libev 4.11 +* Bugfixes for zero/negative select timeouts +* Handle OP_CONNECT properly on JRuby + +## 0.2.2 + +* Raise IOError if asked to wake up a closed selector + +## 0.2.1 + +* Implement wakeup mechanism using raw pipes instead of ev_async, since + ev_async likes to cause segvs when used across threads (despite claims + in the documentation to the contrary) + +## 0.2.0 + +* NIO::Monitor#readiness API to query readiness, along with #readable? and + #writable? helper methods +* NIO::Selector#select_each API which avoids memory allocations if possible +* Bugfixes for the JRuby implementation + +## 0.1.0 + +* Initial release. Merry Christmas! + +[@tarcieri]: https://github.com/tarcieri +[@johnnyt]: https://github.com/johnnyt +[@UpeksheJay]: https://github.com/UpeksheJay +[@junaruga]: https://github.com/junaruga +[@unak]: https://github.com/unak +[@MSP-Greg]: https://github.com/MSP-Greg +[@larskanis]: https://github.com/larskanis +[@HoneyryderChuck]: https://github.com/HoneyryderChuck +[@tompng]: https://github.com/tompng +[@ioquatix]: https://github.com/ioquatix +[@eregon]: https://github.com/eregon +[@olleolleolle]: https://github.com/olleolleolle +[@boazsegev]: https://github.com/boazsegev +[@headius]: https://github.com/headius +[@jasl]: https://github.com/jasl +[@jcmfernandes]: https://github.com/jcmfernandes diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/Changes b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/Changes new file mode 100644 index 00000000..d200b9ee --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/Changes @@ -0,0 +1,617 @@ +Revision history for libev, a high-performance and full-featured event loop. + +TODO: for next ABI/API change, consider moving EV__IOFDSSET into io->fd instead and provide a getter. +TODO: document EV_TSTAMP_T + +4.33 Wed Mar 18 13:22:29 CET 2020 + - no changes w.r.t. 4.32. + +4.32 (EV only) + - the 4.31 timerfd code wrongly changed the priority of the signal + fd watcher, which is usually harmless unless signal fds are + also used (found via cpan tester service). + - the documentation wrongly claimed that user may modify fd and events + members in io watchers when the watcher was stopped + (found by b_jonas). + - new ev_io_modify mutator which changes only the events member, + which can be faster. also added ev::io::set (int events) method + to ev++.h. + - officially allow a zero events mask for io watchers. this should + work with older libev versions as well but was not officially + allowed before. + - do not wake up every minute when timerfd is used to detect timejumps. + - do not wake up every minute when periodics are disabled and we have + a monotonic clock. + - support a lot more "uncommon" compile time configurations, + such as ev_embed enabled but ev_timer disabled. + - use a start/stop wrapper class to reduce code duplication in + ev++.h and make it needlessly more c++-y. + - the linux aio backend is no longer compiled in by default. + - update to libecb version 0x00010008. + +4.31 Fri Dec 20 21:58:29 CET 2019 + - handle backends with minimum wait time a bit better by not + waiting in the presence of already-expired timers + (behaviour reported by Felipe Gasper). + - new feature: use timerfd to detect timejumps quickly, + can be disabled with the new EVFLAG_NOTIMERFD loop flag. + - document EV_USE_SIGNALFD feature macro. + +4.30 (EV only) + - change non-autoconf test for __kernel_rwf_t by testing + LINUX_VERSION_CODE, the most direct test I could find. + - fix a bug in the io_uring backend that polled the wrong + backend fd, causing it to not work in many cases. + +4.29 (EV only) + - add io uring autoconf and non-autoconf detection. + - disable io_uring when some header files are too old. + +4.28 (EV only) + - linuxaio backend resulted in random memory corruption + when loop is forked. + - linuxaio backend might have tried to cancel an iocb + multiple times (was unable to trigger this). + - linuxaio backend now employs a generation counter to + avoid handling spurious events from cancelled requests. + - io_cancel can return EINTR, deal with it. also, assume + io_submit also returns EINTR. + - fix some other minor bugs in linuxaio backend. + - ev_tstamp type can now be overriden by defining EV_TSTAMP_T. + - cleanup: replace expect_true/false and noinline by their + libecb counterparts. + - move syscall infrastructure from ev_linuxaio.c to ev.c. + - prepare io_uring integration. + - tweak ev_floor. + - epoll, poll, win32 Sleep and other places that use millisecond + reslution now all try to round up times. + - solaris port backend didn't compile. + - abstract time constants into their macros, for more flexibility. + +4.27 Thu Jun 27 22:43:44 CEST 2019 + - linux aio backend almost completely rewritten to work around its + limitations. + - linux aio backend now requires linux 4.19+. + - epoll backend now mandatory for linux aio backend. + - fail assertions more aggressively on invalid fd's detected + in the event loop, do not just silently fd_kill in case of + user error. + - ev_io_start/ev_io_stop now verify the watcher fd using + a syscall when EV_VERIFY is 2 or higher. + +4.26 (EV only) + - update to libecb 0x00010006. + - new experimental linux aio backend (linux 4.18+). + - removed redundant 0-ptr check in ev_once. + - updated/extended ev_set_allocator documentation. + - replaced EMPTY2 macro by array_needsize_noinit. + - minor code cleanups. + - epoll backend now uses epoll_create1 also after fork. + +4.25 Fri Dec 21 07:49:20 CET 2018 + - INCOMPATIBLE CHANGE: EV_THROW was renamed to EV_NOEXCEPT + (EV_THROW still provided) and now uses noexcept on C++11 or newer. + - move the darwin select workaround higher in ev.c, as newer versions of + darwin managed to break their broken select even more. + - ANDROID => __ANDROID__ (reported by enh@google.com). + - disable epoll_create1 on android because it has broken header files + and google is unwilling to fix them (reported by enh@google.com). + - avoid a minor compilation warning on win32. + - c++: remove deprecated dynamic throw() specifications. + - c++: improve the (unsupported) bad_loop exception class. + - backport perl ev_periodic example to C, untested. + - update libecb, biggets change is to include a memory fence + in ECB_MEMORY_FENCE_RELEASE on x86/amd64. + - minor autoconf/automake modernisation. + +4.24 Wed Dec 28 05:19:55 CET 2016 + - bump version to 4.24, as the release tarball inexplicably + didn't have the right version in ev.h, even though the cvs-tagged + version did have the right one (reported by Ales Teska). + +4.23 Wed Nov 16 18:23:41 CET 2016 + - move some declarations at the beginning to help certain retarded + microsoft compilers, even though their documentation claims + otherwise (reported by Ruslan Osmanov). + +4.22 Sun Dec 20 22:11:50 CET 2015 + - when epoll detects unremovable fds in the fd set, rebuild + only the epoll descriptor, not the signal pipe, to avoid + SIGPIPE in ev_async_send. This doesn't solve it on fork, + so document what needs to be done in ev_loop_fork + (analyzed by Benjamin Mahler). + - remove superfluous sys/timeb.h include on win32 + (analyzed by Jason Madden). + - updated libecb. + +4.20 Sat Jun 20 13:01:43 CEST 2015 + - prefer noexcept over throw () with C++ 11. + - update ecb.h due to incompatibilities with c11. + - fix a potential aliasing issue when reading and writing + watcher callbacks. + +4.19 Thu Sep 25 08:18:25 CEST 2014 + - ev.h wasn't valid C++ anymore, which tripped compilers other than + clang, msvc or gcc (analyzed by Raphael 'kena' Poss). Unfortunately, + C++ doesn't support typedefs for function pointers fully, so the affected + declarations have to spell out the types each time. + - when not using autoconf, tighten the check for clock_gettime and related + functionality. + +4.18 Fri Sep 5 17:55:26 CEST 2014 + - events on files were not always generated properly with the + epoll backend (testcase by Assaf Inbal). + - mark event pipe fd as cloexec after a fork (analyzed by Sami Farin). + - (ecb) support m68k, m88k and sh (patch by Miod Vallat). + - use a reasonable fallback for EV_NSIG instead of erroring out + when we can't detect the signal set size. + - in the absence of autoconf, do not use the clock syscall + on glibc >= 2.17 (avoids the syscall AND -lrt on systems + doing clock_gettime in userspace). + - ensure extern "C" function pointers are used for externally-visible + loop callbacks (not watcher callbacks yet). + - (ecb) work around memory barriers and volatile apparently both being + broken in visual studio 2008 and later (analysed and patch by Nicolas Noble). + +4.15 Fri Mar 1 12:04:50 CET 2013 + - destroying a non-default loop would stop the global waitpid + watcher (Denis Bilenko). + - queueing pending watchers of higher priority from a watcher now invokes + them in a timely fashion (reported by Denis Bilenko). + - add throw() to all libev functions that cannot throw exceptions, for + further code size decrease when compiling for C++. + - add throw () to callbacks that must not throw exceptions (allocator, + syserr, loop acquire/release, periodic reschedule cbs). + - fix event_base_loop return code, add event_get_callback, event_base_new, + event_base_get_method calls to improve libevent 1.x emulation and add + some libevent 2.x functionality (based on a patch by Jeff Davey). + - add more memory fences to fix a bug reported by Jeff Davey. Better + be overfenced than underprotected. + - ev_run now returns a boolean status (true meaning watchers are + still active). + - ev_once: undef EV_ERROR in ev_kqueue.c, to avoid clashing with + libev's EV_ERROR (reported by 191919). + - (ecb) add memory fence support for xlC (Darin McBride). + - (ecb) add memory fence support for gcc-mips (Anton Kirilov). + - (ecb) add memory fence support for gcc-alpha (Christian Weisgerber). + - work around some kernels losing file descriptors by leaking + the kqueue descriptor in the child. + - work around linux inotify not reporting IN_ATTRIB changes for directories + in many cases. + - include sys/syscall.h instead of plain syscall.h. + - check for io watcher loops in ev_verify, check for the most + common reported usage bug in ev_io_start. + - choose socket vs. WSASocket at compiletime using EV_USE_WSASOCKET. + - always use WSASend/WSARecv directly on windows, hoping that this + works in all cases (unlike read/write/send/recv...). + - try to detect signals around a fork faster (test program by + Denis Bilenko). + - work around recent glibc versions that leak memory in realloc. + - rename ev::embed::set to ev::embed::set_embed to avoid clashing + the watcher base set (loop) method. + - rewrite the async/signal pipe logic to always keep a valid fd, which + simplifies (and hopefully correctifies :) the race checking + on fork, at the cost of one extra fd. + - add fat, msdos, jffs2, ramfs, ntfs and btrfs to the list of + inotify-supporting filesystems. + - move orig_CFLAGS assignment to after AC_INIT, as newer autoconf + versions ignore it before + (https://bugzilla.redhat.com/show_bug.cgi?id=908096). + - add some untested android support. + - enum expressions must be of type int (reported by Juan Pablo L). + +4.11 Sat Feb 4 19:52:39 CET 2012 + - INCOMPATIBLE CHANGE: ev_timer_again now clears the pending status, as + was documented already, but not implemented in the repeating case. + - new compiletime symbols: EV_NO_SMP and EV_NO_THREADS. + - fix a race where the workaround against the epoll fork bugs + caused signals to not be handled anymore. + - correct backend_fudge for most backends, and implement a windows + specific workaround to avoid looping because we call both + select and Sleep, both with different time resolutions. + - document range and guarantees of ev_sleep. + - document reasonable ranges for periodics interval and offset. + - rename backend_fudge to backend_mintime to avoid future confusion :) + - change the default periodic reschedule function to hopefully be more + exact and correct even in corner cases or in the far future. + - do not rely on -lm anymore: use it when available but use our + own floor () if it is missing. This should make it easier to embed, + as no external libraries are required. + - strategically import macros from libecb and mark rarely-used functions + as cache-cold (saving almost 2k code size on typical amd64 setups). + - add Symbols.ev and Symbols.event files, that were missing. + - fix backend_mintime value for epoll (was 1/1024, is 1/1000 now). + - fix #3 "be smart about timeouts" to not "deadlock" when + timeout == now, also improve the section overall. + - avoid "AVOIDING FINISHING BEFORE RETURNING" idiom. + - support new EV_API_STATIC mode to make all libev symbols + static. + - supply default CFLAGS of -g -O3 with gcc when original CFLAGS + were empty. + +4.04 Wed Feb 16 09:01:51 CET 2011 + - fix two problems in the native win32 backend, where reuse of fd's + with different underlying handles caused handles not to be removed + or added to the select set (analyzed and tested by Bert Belder). + - do no rely on ceil() in ev_e?poll.c. + - backport libev to HP-UX versions before 11 v3. + - configure did not detect nanosleep and clock_gettime properly when + they are available in the libc (as opposed to -lrt). + +4.03 Tue Jan 11 14:37:25 CET 2011 + - officially support polling files with all backends. + - support files, /dev/zero etc. the same way as select in the epoll + backend, by generating events on our own. + - ports backend: work around solaris bug 6874410 and many related ones + (EINTR, maybe more), with no performance loss (note that the solaris + bug report is actually wrong, reality is far more bizarre and broken + than that). + - define EV_READ/EV_WRITE as macros in event.h, as some programs use + #ifdef to test for them. + - new (experimental) function: ev_feed_signal. + - new (to become default) EVFLAG_NOSIGMASK flag. + - new EVBACKEND_MASK symbol. + - updated COMMON IDIOMS SECTION. + +4.01 Fri Nov 5 21:51:29 CET 2010 + - automake fucked it up, apparently, --add-missing -f is not quite enough + to make it update its files, so 4.00 didn't install ev++.h and + event.h on make install. grrr. + - ev_loop(count|depth) didn't return anything (Robin Haberkorn). + - change EV_UNDEF to 0xffffffff to silence some overzealous compilers. + - use "(libev) " prefix for all libev error messages now. + +4.00 Mon Oct 25 12:32:12 CEST 2010 + - "PORTING FROM LIBEV 3.X TO 4.X" (in ev.pod) is recommended reading. + - ev_embed_stop did not correctly stop the watcher (very good + testcase by Vladimir Timofeev). + - ev_run will now always update the current loop time - it erroneously + didn't when idle watchers were active, causing timers not to fire. + - fix a bug where a timeout of zero caused the timer not to fire + in the libevent emulation (testcase by Péter Szabó). + - applied win32 fixes by Michael Lenaghan (also James Mansion). + - replace EV_MINIMAL by EV_FEATURES. + - prefer EPOLL_CTL_ADD over EPOLL_CTL_MOD in some more cases, as it + seems the former is *much* faster than the latter. + - linux kernel version detection (for inotify bug workarounds) + did not work properly. + - reduce the number of spurious wake-ups with the ports backend. + - remove dependency on sys/queue.h on freebsd (patch by Vanilla Hsu). + - do async init within ev_async_start, not ev_async_set, which avoids + an API quirk where the set function must be called in the C++ API + even when there is nothing to set. + - add (undocumented) EV_ENABLE when adding events with kqueue, + this might help with OS X, which seems to need it despite documenting + not to need it (helpfully pointed out by Tilghman Lesher). + - do not use poll by default on freebsd, it's broken (what isn't + on freebsd...). + - allow to embed epoll on kernels >= 2.6.32. + - configure now prepends -O3, not appends it, so one can still + override it. + - ev.pod: greatly expanded the portability section, added a porting + section, a description of watcher states and made lots of minor fixes. + - disable poll backend on AIX, the poll header spams the namespace + and it's not worth working around dead platforms (reported + and analyzed by Aivars Kalvans). + - improve header file compatibility of the standalone eventfd code + in an obscure case. + - implement EV_AVOID_STDIO option. + - do not use sscanf to parse linux version number (smaller, faster, + no sscanf dependency). + - new EV_CHILD_ENABLE and EV_SIGNAL_ENABLE configurable settings. + - update libev.m4 HAVE_CLOCK_SYSCALL test for newer glibcs. + - add section on accept() problems to the manpage. + - rename EV_TIMEOUT to EV_TIMER. + - rename ev_loop_count/depth/verify/loop/unloop. + - remove ev_default_destroy and ev_default_fork. + - switch to two-digit minor version. + - work around an apparent gentoo compiler bug. + - define _DARWIN_UNLIMITED_SELECT. just so. + - use enum instead of #define for most constants. + - improve compatibility to older C++ compilers. + - (experimental) ev_run/ev_default_loop/ev_break/ev_loop_new have now + default arguments when compiled as C++. + - enable automake dependency tracking. + - ev_loop_new no longer leaks memory when loop creation failed. + - new ev_cleanup watcher type. + +3.9 Thu Dec 31 07:59:59 CET 2009 + - signalfd is no longer used by default and has to be requested + explicitly - this means that easy to catch bugs become hard to + catch race conditions, but the users have spoken. + - point out the unspecified signal mask in the documentation, and + that this is a race condition regardless of EV_SIGNALFD. + - backport inotify code to C89. + - inotify file descriptors could leak into child processes. + - ev_stat watchers could keep an erroneous extra ref on the loop, + preventing exit when unregistering all watchers (testcases + provided by ry@tinyclouds.org). + - implement EV_WIN32_HANDLE_TO_FD and EV_WIN32_CLOSE_FD configuration + symbols to make it easier for apps to do their own fd management. + - support EV_IDLE_ENABLE being disabled in ev++.h + (patch by Didier Spezia). + - take advantage of inotify_init1, if available, to set cloexec/nonblock + on fd creation, to avoid races. + - the signal handling pipe wasn't always initialised under windows + (analysed by lekma). + - changed minimum glibc requirement from glibc 2.9 to 2.7, for + signalfd. + - add missing string.h include (Denis F. Latypoff). + - only replace ev_stat.prev when we detect an actual difference, + so prev is (almost) always different to attr. this might + have caused the problems with 04_stat.t. + - add ev::timer->remaining () method to C++ API. + +3.8 Sun Aug 9 14:30:45 CEST 2009 + - incompatible change: do not necessarily reset signal handler + to SIG_DFL when a sighandler is stopped. + - ev_default_destroy did not properly free or zero some members, + potentially causing crashes and memory corruption on repeated + ev_default_destroy/ev_default_loop calls. + - take advantage of signalfd on GNU/Linux systems. + - document that the signal mask might be in an unspecified + state when using libev's signal handling. + - take advantage of some GNU/Linux calls to set cloexec/nonblock + on fd creation, to avoid race conditions. + +3.7 Fri Jul 17 16:36:32 CEST 2009 + - ev_unloop and ev_loop wrongly used a global variable to exit loops, + instead of using a per-loop variable (bug caught by accident...). + - the ev_set_io_collect_interval interpretation has changed. + - add new functionality: ev_set_userdata, ev_userdata, + ev_set_invoke_pending_cb, ev_set_loop_release_cb, + ev_invoke_pending, ev_pending_count, together with a long example + about thread locking. + - add ev_timer_remaining (as requested by Denis F. Latypoff). + - add ev_loop_depth. + - calling ev_unloop in fork/prepare watchers will no longer poll + for new events. + - Denis F. Latypoff corrected many typos in example code snippets. + - honor autoconf detection of EV_USE_CLOCK_SYSCALL, also double- + check that the syscall number is available before trying to + use it (reported by ry@tinyclouds). + - use GetSystemTimeAsFileTime instead of _timeb on windows, for + slightly higher accuracy. + - properly declare ev_loop_verify and ev_now_update even when + !EV_MULTIPLICITY. + - do not compile in any priority code when EV_MAXPRI == EV_MINPRI. + - support EV_MINIMAL==2 for a reduced API. + - actually 0-initialise struct sigaction when installing signals. + - add section on hibernate and stopped processes to ev_timer docs. + +3.6 Tue Apr 28 02:49:30 CEST 2009 + - multiple timers becoming ready within an event loop iteration + will be invoked in the "correct" order now. + - do not leave the event loop early just because we have no active + watchers, fixing a problem when embedding a kqueue loop + that has active kernel events but no registered watchers + (reported by blacksand blacksand). + - correctly zero the idx values for arrays, so destroying and + reinitialising the default loop actually works (patch by + Malek Hadj-Ali). + - implement ev_suspend and ev_resume. + - new EV_CUSTOM revents flag for use by applications. + - add documentation section about priorities. + - add a glossary to the documentation. + - extend the ev_fork description slightly. + - optimize a jump out of call_pending. + +3.53 Sun Feb 15 02:38:20 CET 2009 + - fix a bug in event pipe creation on win32 that would cause a + failed assertion on event loop creation (patch by Malek Hadj-Ali). + - probe for CLOCK_REALTIME support at runtime as well and fall + back to gettimeofday if there is an error, to support older + operating systems with newer header files/libraries. + - prefer gettimeofday over clock_gettime with USE_CLOCK_SYSCALL + (default most everywhere), otherwise not. + +3.52 Wed Jan 7 21:43:02 CET 2009 + - fix compilation of select backend in fd_set mode when NFDBITS is + missing (to get it to compile on QNX, reported by Rodrigo Campos). + - better select-nfds handling when select backend is in fd_set mode. + - diagnose fd_set overruns when select backend is in fd_set mode. + - due to a thinko, instead of disabling everything but + select on the borked OS X platform, everything but select was + allowed (reported by Emanuele Giaquinta). + - actually verify that local and remote port are matching in + libev's socketpair emulation, which makes denial-of-service + attacks harder (but not impossible - it's windows). Make sure + it even works under vista, which thinks that getpeer/sockname + should return fantasy port numbers. + - include "libev" in all assertion messages for potentially + clearer diagnostics. + - event_get_version (libevent compatibility) returned + a useless string instead of the expected version string + (patch by W.C.A. Wijngaards). + +3.51 Wed Dec 24 23:00:11 CET 2008 + - fix a bug where an inotify watcher was added twice, causing + freezes on hash collisions (reported and analysed by Graham Leggett). + - new config symbol, EV_USE_CLOCK_SYSCALL, to make libev use + a direct syscall - slower, but no dependency on librt et al. + - assume negative return values != -1 signals success of port_getn + (http://cvs.epicsol.org/cgi/viewcvs.cgi/epic5/source/newio.c?rev=1.52) + (no known failure reports, but it doesn't hurt). + - fork detection in ev_embed now stops and restarts the watcher + automatically. + - EXPERIMENTAL: default the method to operator () in ev++.h, + to make it nicer to use functors (requested by Benedek László). + - fixed const object callbacks in ev++.h. + - replaced loop_ref argument of watcher.set (loop) by a direct + ev_loop * in ev++.h, to avoid clashes with functor patch. + - do not try to watch the empty string via inotify. + - inotify watchers could be leaked under certain circumstances. + - OS X 10.5 is actually even more broken than earlier versions, + so fall back to select on that piece of garbage. + - fixed some weirdness in the ev_embed documentation. + +3.49 Wed Nov 19 11:26:53 CET 2008 + - ev_stat watchers will now use inotify as a mere hint on + kernels <2.6.25, or if the filesystem is not in the + "known to be good" list. + - better mingw32 compatibility (it's not as borked as native win32) + (analysed by Roger Pack). + - include stdio.h in the example program, as too many people are + confused by the weird C language otherwise. I guess the next thing + I get told is that the "..." ellipses in the examples don't compile + with their C compiler. + +3.48 Thu Oct 30 09:02:37 CET 2008 + - further optimise away the EPOLL_CTL_ADD/MOD combo in the epoll + backend by assuming the kernel event mask hasn't changed if + ADD fails with EEXIST. + - work around spurious event notification bugs in epoll by using + a 32-bit generation counter. recreate kernel state if we receive + spurious notifications or unwanted events. this is very costly, + but I didn't come up with this horrible design. + - use memset to initialise most arrays now and do away with the + init functions. + - expand time-out strategies into a "Be smart about timeouts" section. + - drop the "struct" from all ev_watcher declarations in the + documentation and did other clarifications (yeah, it was a mistake + to have a struct AND a function called ev_loop). + - fix a bug where ev_default would not initialise the default + loop again after it was destroyed with ev_default_destroy. + - rename syserr to ev_syserr to avoid name clashes when embedding, + do similar changes for event.c. + +3.45 Tue Oct 21 21:59:26 CEST 2008 + - disable inotify usage on linux <2.6.25, as it is broken + (reported by Yoann Vandoorselaere). + - ev_stat erroneously would try to add inotify watchers + even when inotify wasn't available (this should only + have a performance impact). + - ev_once now passes both timeout and io to the callback if both + occur concurrently, instead of giving timeouts precedence. + - disable EV_USE_INOTIFY when sys/inotify.h is too old. + +3.44 Mon Sep 29 05:18:39 CEST 2008 + - embed watchers now automatically invoke ev_loop_fork on the + embedded loop when the parent loop forks. + - new function: ev_now_update (loop). + - verify_watcher was not marked static. + - improve the "associating..." manpage section. + - documentation tweaks here and there. + +3.43 Sun Jul 6 05:34:41 CEST 2008 + - include more include files on windows to get struct _stati64 + (reported by Chris Hulbert, but doesn't quite fix his issue). + - add missing #include in ev.c on windows (reported by + Matt Tolton). + +3.42 Tue Jun 17 12:12:07 CEST 2008 + - work around yet another windows bug: FD_SET actually adds fd's + multiple times to the fd_*SET*, despite official MSN docs claiming + otherwise. Reported and well-analysed by Matt Tolton. + - define NFDBITS to 0 when EV_SELECT_IS_WINSOCKET to make it compile + (reported any analysed by Chris Hulbert). + - fix a bug in ev_ebadf (this function is only used to catch + programming errors in the libev user). reported by Matt Tolton. + - fix a bug in fd_intern on win32 (could lead to compile errors + under some circumstances, but would work correctly if it compiles). + reported by Matt Tolton. + - (try to) work around missing lstat on windows. + - pass in the write fd set as except fd set under windows. windows + is so uncontrollably lame that it requires this. this means that + switching off oobinline is not supported (but tcp/ip doesn't + have oob, so that would be stupid anyways. + - use posix module symbol to auto-detect monotonic clock presence + and some other default values. + +3.41 Fri May 23 18:42:54 CEST 2008 + - work around an obscure bug in winsocket select: if you + provide only empty fd sets then select returns WSAEINVAL. how sucky. + - improve timer scheduling stability and reduce use of time_epsilon. + - use 1-based 2-heap for EV_MINIMAL, simplifies code, reduces + codesize and makes for better cache-efficiency. + - use 3-based 4-heap for !EV_MINIMAL. this makes better use + of cpu cache lines and gives better growth behaviour than + 2-based heaps. + - cache timestamp within heap for !EV_MINIMAL, to avoid random + memory accesses. + - document/add EV_USE_4HEAP and EV_HEAP_CACHE_AT. + - fix a potential aliasing issue in ev_timer_again. + - add/document ev_periodic_at, retract direct access to ->at. + - improve ev_stat docs. + - add portability requirements section. + - fix manpage headers etc. + - normalise WSA error codes to lower range on windows. + - add consistency check code that can be called automatically + or on demand to check for internal structures (ev_loop_verify). + +3.31 Wed Apr 16 20:45:04 CEST 2008 + - added last minute fix for ev_poll.c by Brandon Black. + +3.3 Wed Apr 16 19:04:10 CEST 2008 + - event_base_loopexit should return 0 on success + (W.C.A. Wijngaards). + - added linux eventfd support. + - try to autodetect epoll and inotify support + by libc header version if not using autoconf. + - new symbols: EV_DEFAULT_UC and EV_DEFAULT_UC_. + - declare functions defined in ev.h as inline if + C99 or gcc are available. + - enable inlining with gcc versions 2 and 3. + - work around broken poll implementations potentially + not clearing revents field in ev_poll (Brandon Black) + (no such systems are known at this time). + - work around a bug in realloc on openbsd and darwin, + also makes the erroneous valgrind complaints + go away (noted by various people). + - fix ev_async_pending, add c++ wrapper for ev_async + (based on patch sent by Johannes Deisenhofer). + - add sensible set method to ev::embed. + - made integer constants type int in ev.h. + +3.2 Wed Apr 2 17:11:19 CEST 2008 + - fix a 64 bit overflow issue in the select backend, + by using fd_mask instead of int for the mask. + - rename internal sighandler to avoid clash with very old perls. + - entering ev_loop will not clear the ONESHOT or NONBLOCKING + flags of any outer loops anymore. + - add ev_async_pending. + +3.1 Thu Mar 13 13:45:22 CET 2008 + - implement ev_async watchers. + - only initialise signal pipe on demand. + - make use of sig_atomic_t configurable. + - improved documentation. + +3.0 Mon Jan 28 13:14:47 CET 2008 + - API/ABI bump to version 3.0. + - ev++.h includes "ev.h" by default now, not . + - slightly improved documentation. + - speed up signal detection after a fork. + - only optionally return trace status changed in ev_child + watchers. + - experimental (and undocumented) loop wrappers for ev++.h. + +2.01 Tue Dec 25 08:04:41 CET 2007 + - separate Changes file. + - fix ev_path_set => ev_stat_set typo. + - remove event_compat.h from the libev tarball. + - change how include files are found. + - doc updates. + - update licenses, explicitly allow for GPL relicensing. + +2.0 Sat Dec 22 17:47:03 CET 2007 + - new ev_sleep, ev_set_(io|timeout)_collect_interval. + - removed epoll from embeddable fd set. + - fix embed watchers. + - renamed ev_embed.loop to other. + - added exported Symbol tables. + - undefine member wrapper macros at the end of ev.c. + - respect EV_H in ev++.h. + +1.86 Tue Dec 18 02:36:57 CET 2007 + - fix memleak on loop destroy (not relevant for perl). + +1.85 Fri Dec 14 20:32:40 CET 2007 + - fix some aliasing issues w.r.t. timers and periodics + (not relevant for perl). + +(for historic versions refer to EV/Changes, found in the Perl interface) + +0.1 Wed Oct 31 21:31:48 CET 2007 + - original version; hacked together in <24h. + diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/LICENSE b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/LICENSE new file mode 100644 index 00000000..2fdabd48 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/LICENSE @@ -0,0 +1,37 @@ +All files in libev are +Copyright (c)2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Alternatively, the contents of this package may be used under the terms +of the GNU General Public License ("GPL") version 2 or any later version, +in which case the provisions of the GPL are applicable instead of the +above. If you wish to allow the use of your version of this package only +under the terms of the GPL and not to allow others to use your version of +this file under the BSD license, indicate your decision by deleting the +provisions above and replace them with the notice and other provisions +required by the GPL in this and the other files of this package. If you do +not delete the provisions above, a recipient may use your version of this +file under either the BSD or the GPL. diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/README b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/README new file mode 100644 index 00000000..fca5fdf1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/README @@ -0,0 +1,59 @@ +libev is a high-performance event loop/event model with lots of features. +(see benchmark at http://libev.schmorp.de/bench.html) + + +ABOUT + + Homepage: http://software.schmorp.de/pkg/libev + Mailinglist: libev@lists.schmorp.de + http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev + Library Documentation: http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod + + Libev is modelled (very losely) after libevent and the Event perl + module, but is faster, scales better and is more correct, and also more + featureful. And also smaller. Yay. + + Some of the specialties of libev not commonly found elsewhere are: + + - extensive and detailed, readable documentation (not doxygen garbage). + - fully supports fork, can detect fork in various ways and automatically + re-arms kernel mechanisms that do not support fork. + - highly optimised select, poll, linux epoll, linux aio, bsd kqueue + and solaris event ports backends. + - filesystem object (path) watching (with optional linux inotify support). + - wallclock-based times (using absolute time, cron-like). + - relative timers/timeouts (handle time jumps). + - fast intra-thread communication between multiple + event loops (with optional fast linux eventfd backend). + - extremely easy to embed (fully documented, no dependencies, + autoconf supported but optional). + - very small codebase, no bloated library, simple code. + - fully extensible by being able to plug into the event loop, + integrate other event loops, integrate other event loop users. + - very little memory use (small watchers, small event loop data). + - optional C++ interface allowing method and function callbacks + at no extra memory or runtime overhead. + - optional Perl interface with similar characteristics (capable + of running Glib/Gtk2 on libev). + - support for other languages (multiple C++ interfaces, D, Ruby, + Python) available from third-parties. + + Examples of programs that embed libev: the EV perl module, node.js, + auditd, rxvt-unicode, gvpe (GNU Virtual Private Ethernet), the + Deliantra MMORPG server (http://www.deliantra.net/), Rubinius (a + next-generation Ruby VM), the Ebb web server, the Rev event toolkit. + + +CONTRIBUTORS + + libev was written and designed by Marc Lehmann and Emanuele Giaquinta. + + The following people sent in patches or made other noteworthy + contributions to the design (for minor patches, see the Changes + file. If I forgot to include you, please shout at me, it was an + accident): + + W.C.A. Wijngaards + Christopher Layne + Chris Brody + diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev.c b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev.c new file mode 100644 index 00000000..fcba49f6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev.c @@ -0,0 +1,5689 @@ +/* + * libev event processing core, watcher management + * + * Copyright (c) 2007-2019 Marc Alexander Lehmann + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License ("GPL") version 2 or any later version, + * in which case the provisions of the GPL are applicable instead of + * the above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the BSD license, indicate your decision + * by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file under + * either the BSD or the GPL. + */ + +/* ########## NIO4R PATCHERY HO! ########## */ +#include "ruby.h" +#include "ruby/thread.h" + +#ifdef __APPLE__ +#include +#endif +/* ######################################## */ + +/* this big block deduces configuration from config.h */ +#ifndef EV_STANDALONE +# ifdef EV_CONFIG_H +# include EV_CONFIG_H +# else +# include "config.h" +# endif + +# if HAVE_FLOOR +# ifndef EV_USE_FLOOR +# define EV_USE_FLOOR 1 +# endif +# endif + +# if HAVE_CLOCK_SYSCALL +# ifndef EV_USE_CLOCK_SYSCALL +# define EV_USE_CLOCK_SYSCALL 1 +# ifndef EV_USE_REALTIME +# define EV_USE_REALTIME 0 +# endif +# ifndef EV_USE_MONOTONIC +# define EV_USE_MONOTONIC 1 +# endif +# endif +# elif !defined EV_USE_CLOCK_SYSCALL +# define EV_USE_CLOCK_SYSCALL 0 +# endif + +# if HAVE_CLOCK_GETTIME +# ifndef EV_USE_MONOTONIC +# define EV_USE_MONOTONIC 1 +# endif +# ifndef EV_USE_REALTIME +# define EV_USE_REALTIME 0 +# endif +# else +# ifndef EV_USE_MONOTONIC +# define EV_USE_MONOTONIC 0 +# endif +# ifndef EV_USE_REALTIME +# define EV_USE_REALTIME 0 +# endif +# endif + +# if HAVE_NANOSLEEP +# ifndef EV_USE_NANOSLEEP +# define EV_USE_NANOSLEEP EV_FEATURE_OS +# endif +# else +# undef EV_USE_NANOSLEEP +# define EV_USE_NANOSLEEP 0 +# endif + +# if HAVE_SELECT && HAVE_SYS_SELECT_H +# ifndef EV_USE_SELECT +# define EV_USE_SELECT EV_FEATURE_BACKENDS +# endif +# else +# undef EV_USE_SELECT +# define EV_USE_SELECT 0 +# endif + +# if HAVE_POLL && HAVE_POLL_H +# ifndef EV_USE_POLL +# define EV_USE_POLL EV_FEATURE_BACKENDS +# endif +# else +# undef EV_USE_POLL +# define EV_USE_POLL 0 +# endif + +# if HAVE_EPOLL_CTL && HAVE_SYS_EPOLL_H +# ifndef EV_USE_EPOLL +# define EV_USE_EPOLL EV_FEATURE_BACKENDS +# endif +# else +# undef EV_USE_EPOLL +# define EV_USE_EPOLL 0 +# endif + +# if HAVE_LINUX_AIO_ABI_H +# ifndef EV_USE_LINUXAIO +# define EV_USE_LINUXAIO 0 /* was: EV_FEATURE_BACKENDS, always off by default */ +# endif +# else +# undef EV_USE_LINUXAIO +# define EV_USE_LINUXAIO 0 +# endif + +# if HAVE_LINUX_FS_H && HAVE_SYS_TIMERFD_H && HAVE_KERNEL_RWF_T +# ifndef EV_USE_IOURING +# define EV_USE_IOURING EV_FEATURE_BACKENDS +# endif +# else +# undef EV_USE_IOURING +# define EV_USE_IOURING 0 +# endif + +# if HAVE_KQUEUE && HAVE_SYS_EVENT_H +# ifndef EV_USE_KQUEUE +# define EV_USE_KQUEUE EV_FEATURE_BACKENDS +# endif +# else +# undef EV_USE_KQUEUE +# define EV_USE_KQUEUE 0 +# endif + +# if HAVE_PORT_H && HAVE_PORT_CREATE +# ifndef EV_USE_PORT +# define EV_USE_PORT EV_FEATURE_BACKENDS +# endif +# else +# undef EV_USE_PORT +# define EV_USE_PORT 0 +# endif + +# if HAVE_INOTIFY_INIT && HAVE_SYS_INOTIFY_H +# ifndef EV_USE_INOTIFY +# define EV_USE_INOTIFY EV_FEATURE_OS +# endif +# else +# undef EV_USE_INOTIFY +# define EV_USE_INOTIFY 0 +# endif + +# if HAVE_SIGNALFD && HAVE_SYS_SIGNALFD_H +# ifndef EV_USE_SIGNALFD +# define EV_USE_SIGNALFD EV_FEATURE_OS +# endif +# else +# undef EV_USE_SIGNALFD +# define EV_USE_SIGNALFD 0 +# endif + +# if HAVE_EVENTFD +# ifndef EV_USE_EVENTFD +# define EV_USE_EVENTFD EV_FEATURE_OS +# endif +# else +# undef EV_USE_EVENTFD +# define EV_USE_EVENTFD 0 +# endif + +# if HAVE_SYS_TIMERFD_H +# ifndef EV_USE_TIMERFD +# define EV_USE_TIMERFD EV_FEATURE_OS +# endif +# else +# undef EV_USE_TIMERFD +# define EV_USE_TIMERFD 0 +# endif + +#endif + +/* OS X, in its infinite idiocy, actually HARDCODES + * a limit of 1024 into their select. Where people have brains, + * OS X engineers apparently have a vacuum. Or maybe they were + * ordered to have a vacuum, or they do anything for money. + * This might help. Or not. + * Note that this must be defined early, as other include files + * will rely on this define as well. + */ +#define _DARWIN_UNLIMITED_SELECT 1 + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#ifdef EV_H +# include EV_H +#else +# include "ev.h" +#endif + +#if EV_NO_THREADS +# undef EV_NO_SMP +# define EV_NO_SMP 1 +# undef ECB_NO_THREADS +# define ECB_NO_THREADS 1 +#endif +#if EV_NO_SMP +# undef EV_NO_SMP +# define ECB_NO_SMP 1 +#endif + +#ifndef _WIN32 +# include +# include +# include +#else +# include +# define WIN32_LEAN_AND_MEAN +# include +# include +# ifndef EV_SELECT_IS_WINSOCKET +# define EV_SELECT_IS_WINSOCKET 1 +# endif +# undef EV_AVOID_STDIO +#endif + +/* this block tries to deduce configuration from header-defined symbols and defaults */ + +/* try to deduce the maximum number of signals on this platform */ +#if defined EV_NSIG +/* use what's provided */ +#elif defined NSIG +# define EV_NSIG (NSIG) +#elif defined _NSIG +# define EV_NSIG (_NSIG) +#elif defined SIGMAX +# define EV_NSIG (SIGMAX+1) +#elif defined SIG_MAX +# define EV_NSIG (SIG_MAX+1) +#elif defined _SIG_MAX +# define EV_NSIG (_SIG_MAX+1) +#elif defined MAXSIG +# define EV_NSIG (MAXSIG+1) +#elif defined MAX_SIG +# define EV_NSIG (MAX_SIG+1) +#elif defined SIGARRAYSIZE +# define EV_NSIG (SIGARRAYSIZE) /* Assume ary[SIGARRAYSIZE] */ +#elif defined _sys_nsig +# define EV_NSIG (_sys_nsig) /* Solaris 2.5 */ +#else +# define EV_NSIG (8 * sizeof (sigset_t) + 1) +#endif + +#ifndef EV_USE_FLOOR +# define EV_USE_FLOOR 0 +#endif + +#ifndef EV_USE_CLOCK_SYSCALL +# if __linux && __GLIBC__ == 2 && __GLIBC_MINOR__ < 17 +# define EV_USE_CLOCK_SYSCALL EV_FEATURE_OS +# else +# define EV_USE_CLOCK_SYSCALL 0 +# endif +#endif + +#if !(_POSIX_TIMERS > 0) +# ifndef EV_USE_MONOTONIC +# define EV_USE_MONOTONIC 0 +# endif +# ifndef EV_USE_REALTIME +# define EV_USE_REALTIME 0 +# endif +#endif + +#ifndef EV_USE_MONOTONIC +# if defined _POSIX_MONOTONIC_CLOCK && _POSIX_MONOTONIC_CLOCK >= 0 +# define EV_USE_MONOTONIC EV_FEATURE_OS +# else +# define EV_USE_MONOTONIC 0 +# endif +#endif + +#ifndef EV_USE_REALTIME +# define EV_USE_REALTIME !EV_USE_CLOCK_SYSCALL +#endif + +#ifndef EV_USE_NANOSLEEP +# if _POSIX_C_SOURCE >= 199309L +# define EV_USE_NANOSLEEP EV_FEATURE_OS +# else +# define EV_USE_NANOSLEEP 0 +# endif +#endif + +#ifndef EV_USE_SELECT +# define EV_USE_SELECT EV_FEATURE_BACKENDS +#endif + +#ifndef EV_USE_POLL +# ifdef _WIN32 +# define EV_USE_POLL 0 +# else +# define EV_USE_POLL EV_FEATURE_BACKENDS +# endif +#endif + +#ifndef EV_USE_EPOLL +# if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 4)) +# define EV_USE_EPOLL EV_FEATURE_BACKENDS +# else +# define EV_USE_EPOLL 0 +# endif +#endif + +#ifndef EV_USE_KQUEUE +# define EV_USE_KQUEUE 0 +#endif + +#ifndef EV_USE_PORT +# define EV_USE_PORT 0 +#endif + +#ifndef EV_USE_LINUXAIO +# define EV_USE_LINUXAIO 0 +#endif + +#ifndef EV_USE_IOURING +# define EV_USE_IOURING 0 +#endif + +#ifndef EV_USE_INOTIFY +# if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 4)) +# define EV_USE_INOTIFY EV_FEATURE_OS +# else +# define EV_USE_INOTIFY 0 +# endif +#endif + +#ifndef EV_PID_HASHSIZE +# define EV_PID_HASHSIZE EV_FEATURE_DATA ? 16 : 1 +#endif + +#ifndef EV_INOTIFY_HASHSIZE +# define EV_INOTIFY_HASHSIZE EV_FEATURE_DATA ? 16 : 1 +#endif + +#ifndef EV_USE_EVENTFD +# if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7)) +# define EV_USE_EVENTFD EV_FEATURE_OS +# else +# define EV_USE_EVENTFD 0 +# endif +#endif + +#ifndef EV_USE_SIGNALFD +# if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7)) +# define EV_USE_SIGNALFD EV_FEATURE_OS +# else +# define EV_USE_SIGNALFD 0 +# endif +#endif + +#ifndef EV_USE_TIMERFD +# if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8)) +# define EV_USE_TIMERFD EV_FEATURE_OS +# else +# define EV_USE_TIMERFD 0 +# endif +#endif + +#if 0 /* debugging */ +# define EV_VERIFY 3 +# define EV_USE_4HEAP 1 +# define EV_HEAP_CACHE_AT 1 +#endif + +#ifndef EV_VERIFY +# define EV_VERIFY (EV_FEATURE_API ? 1 : 0) +#endif + +#ifndef EV_USE_4HEAP +# define EV_USE_4HEAP EV_FEATURE_DATA +#endif + +#ifndef EV_HEAP_CACHE_AT +# define EV_HEAP_CACHE_AT EV_FEATURE_DATA +#endif + +#ifdef __ANDROID__ +/* supposedly, android doesn't typedef fd_mask */ +# undef EV_USE_SELECT +# define EV_USE_SELECT 0 +/* supposedly, we need to include syscall.h, not sys/syscall.h, so just disable */ +# undef EV_USE_CLOCK_SYSCALL +# define EV_USE_CLOCK_SYSCALL 0 +#endif + +/* aix's poll.h seems to cause lots of trouble */ +#ifdef _AIX +/* AIX has a completely broken poll.h header */ +# undef EV_USE_POLL +# define EV_USE_POLL 0 +#endif + +/* on linux, we can use a (slow) syscall to avoid a dependency on pthread, */ +/* which makes programs even slower. might work on other unices, too. */ +#if EV_USE_CLOCK_SYSCALL +# include +# ifdef SYS_clock_gettime +# define clock_gettime(id, ts) syscall (SYS_clock_gettime, (id), (ts)) +# undef EV_USE_MONOTONIC +# define EV_USE_MONOTONIC 1 +# define EV_NEED_SYSCALL 1 +# else +# undef EV_USE_CLOCK_SYSCALL +# define EV_USE_CLOCK_SYSCALL 0 +# endif +#endif + +/* this block fixes any misconfiguration where we know we run into trouble otherwise */ + +#ifndef CLOCK_MONOTONIC +# undef EV_USE_MONOTONIC +# define EV_USE_MONOTONIC 0 +#endif + +#ifndef CLOCK_REALTIME +# undef EV_USE_REALTIME +# define EV_USE_REALTIME 0 +#endif + +#if !EV_STAT_ENABLE +# undef EV_USE_INOTIFY +# define EV_USE_INOTIFY 0 +#endif + +#if !EV_USE_NANOSLEEP +/* hp-ux has it in sys/time.h, which we unconditionally include above */ +# if !defined _WIN32 && !defined __hpux +# include +# endif +#endif + +#if EV_USE_LINUXAIO +# include +# if SYS_io_getevents && EV_USE_EPOLL /* linuxaio backend requires epoll backend */ +# define EV_NEED_SYSCALL 1 +# else +# undef EV_USE_LINUXAIO +# define EV_USE_LINUXAIO 0 +# endif +#endif + +#if EV_USE_IOURING +# include +# if !SYS_io_uring_setup && __linux && !__alpha +# define SYS_io_uring_setup 425 +# define SYS_io_uring_enter 426 +# define SYS_io_uring_wregister 427 +# endif +# if SYS_io_uring_setup && EV_USE_EPOLL /* iouring backend requires epoll backend */ +# define EV_NEED_SYSCALL 1 +# else +# undef EV_USE_IOURING +# define EV_USE_IOURING 0 +# endif +#endif + +#if EV_USE_INOTIFY +# include +# include +/* some very old inotify.h headers don't have IN_DONT_FOLLOW */ +# ifndef IN_DONT_FOLLOW +# undef EV_USE_INOTIFY +# define EV_USE_INOTIFY 0 +# endif +#endif + +#if EV_USE_EVENTFD +/* our minimum requirement is glibc 2.7 which has the stub, but not the full header */ +# include +# ifndef EFD_NONBLOCK +# define EFD_NONBLOCK O_NONBLOCK +# endif +# ifndef EFD_CLOEXEC +# ifdef O_CLOEXEC +# define EFD_CLOEXEC O_CLOEXEC +# else +# define EFD_CLOEXEC 02000000 +# endif +# endif +EV_CPP(extern "C") int (eventfd) (unsigned int initval, int flags); +#endif + +#if EV_USE_SIGNALFD +/* our minimum requirement is glibc 2.7 which has the stub, but not the full header */ +# include +# ifndef SFD_NONBLOCK +# define SFD_NONBLOCK O_NONBLOCK +# endif +# ifndef SFD_CLOEXEC +# ifdef O_CLOEXEC +# define SFD_CLOEXEC O_CLOEXEC +# else +# define SFD_CLOEXEC 02000000 +# endif +# endif +EV_CPP (extern "C") int (signalfd) (int fd, const sigset_t *mask, int flags); + +struct signalfd_siginfo +{ + uint32_t ssi_signo; + char pad[128 - sizeof (uint32_t)]; +}; +#endif + +/* for timerfd, libev core requires TFD_TIMER_CANCEL_ON_SET &c */ +#if EV_USE_TIMERFD +# include +/* timerfd is only used for periodics */ +# if !(defined (TFD_TIMER_CANCEL_ON_SET) && defined (TFD_CLOEXEC) && defined (TFD_NONBLOCK)) || !EV_PERIODIC_ENABLE +# undef EV_USE_TIMERFD +# define EV_USE_TIMERFD 0 +# endif +#endif + +/*****************************************************************************/ + +#if EV_VERIFY >= 3 +# define EV_FREQUENT_CHECK ev_verify (EV_A) +#else +# define EV_FREQUENT_CHECK do { } while (0) +#endif + +/* + * This is used to work around floating point rounding problems. + * This value is good at least till the year 4000. + */ +#define MIN_INTERVAL 0.0001220703125 /* 1/2**13, good till 4000 */ +/*#define MIN_INTERVAL 0.00000095367431640625 /* 1/2**20, good till 2200 */ + +#define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */ +#define MAX_BLOCKTIME 59.743 /* never wait longer than this time (to detect time jumps) */ +#define MAX_BLOCKTIME2 1500001.07 /* same, but when timerfd is used to detect jumps, also safe delay to not overflow */ + +/* find a portable timestamp that is "always" in the future but fits into time_t. + * this is quite hard, and we are mostly guessing - we handle 32 bit signed/unsigned time_t, + * and sizes larger than 32 bit, and maybe the unlikely floating point time_t */ +#define EV_TSTAMP_HUGE \ + (sizeof (time_t) >= 8 ? 10000000000000. \ + : 0 < (time_t)4294967295 ? 4294967295. \ + : 2147483647.) \ + +#ifndef EV_TS_CONST +# define EV_TS_CONST(nv) nv +# define EV_TS_TO_MSEC(a) a * 1e3 + 0.9999 +# define EV_TS_FROM_USEC(us) us * 1e-6 +# define EV_TV_SET(tv,t) do { tv.tv_sec = (long)t; tv.tv_usec = (long)((t - tv.tv_sec) * 1e6); } while (0) +# define EV_TS_SET(ts,t) do { ts.tv_sec = (long)t; ts.tv_nsec = (long)((t - ts.tv_sec) * 1e9); } while (0) +# define EV_TV_GET(tv) ((tv).tv_sec + (tv).tv_usec * 1e-6) +# define EV_TS_GET(ts) ((ts).tv_sec + (ts).tv_nsec * 1e-9) +#endif + +/* the following is ecb.h embedded into libev - use update_ev_c to update from an external copy */ +/* ECB.H BEGIN */ +/* + * libecb - http://software.schmorp.de/pkg/libecb + * + * Copyright (©) 2009-2015,2018-2020 Marc Alexander Lehmann + * Copyright (©) 2011 Emanuele Giaquinta + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License ("GPL") version 2 or any later version, + * in which case the provisions of the GPL are applicable instead of + * the above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the BSD license, indicate your decision + * by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file under + * either the BSD or the GPL. + */ + +#ifndef ECB_H +#define ECB_H + +/* 16 bits major, 16 bits minor */ +#define ECB_VERSION 0x00010008 + +#include /* for memcpy */ + +#if defined (_WIN32) && !defined (__MINGW32__) + typedef signed char int8_t; + typedef unsigned char uint8_t; + typedef signed char int_fast8_t; + typedef unsigned char uint_fast8_t; + typedef signed short int16_t; + typedef unsigned short uint16_t; + typedef signed int int_fast16_t; + typedef unsigned int uint_fast16_t; + typedef signed int int32_t; + typedef unsigned int uint32_t; + typedef signed int int_fast32_t; + typedef unsigned int uint_fast32_t; + #if __GNUC__ + typedef signed long long int64_t; + typedef unsigned long long uint64_t; + #else /* _MSC_VER || __BORLANDC__ */ + typedef signed __int64 int64_t; + typedef unsigned __int64 uint64_t; + #endif + typedef int64_t int_fast64_t; + typedef uint64_t uint_fast64_t; + #ifdef _WIN64 + #define ECB_PTRSIZE 8 + typedef uint64_t uintptr_t; + typedef int64_t intptr_t; + #else + #define ECB_PTRSIZE 4 + typedef uint32_t uintptr_t; + typedef int32_t intptr_t; + #endif +#else + #include + #if (defined INTPTR_MAX ? INTPTR_MAX : ULONG_MAX) > 0xffffffffU + #define ECB_PTRSIZE 8 + #else + #define ECB_PTRSIZE 4 + #endif +#endif + +#define ECB_GCC_AMD64 (__amd64 || __amd64__ || __x86_64 || __x86_64__) +#define ECB_MSVC_AMD64 (_M_AMD64 || _M_X64) + +#ifndef ECB_OPTIMIZE_SIZE + #if __OPTIMIZE_SIZE__ + #define ECB_OPTIMIZE_SIZE 1 + #else + #define ECB_OPTIMIZE_SIZE 0 + #endif +#endif + +/* work around x32 idiocy by defining proper macros */ +#if ECB_GCC_AMD64 || ECB_MSVC_AMD64 + #if _ILP32 + #define ECB_AMD64_X32 1 + #else + #define ECB_AMD64 1 + #endif +#endif + +/* many compilers define _GNUC_ to some versions but then only implement + * what their idiot authors think are the "more important" extensions, + * causing enormous grief in return for some better fake benchmark numbers. + * or so. + * we try to detect these and simply assume they are not gcc - if they have + * an issue with that they should have done it right in the first place. + */ +#if !defined __GNUC_MINOR__ || defined __INTEL_COMPILER || defined __SUNPRO_C || defined __SUNPRO_CC || defined __llvm__ || defined __clang__ + #define ECB_GCC_VERSION(major,minor) 0 +#else + #define ECB_GCC_VERSION(major,minor) (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) +#endif + +#define ECB_CLANG_VERSION(major,minor) (__clang_major__ > (major) || (__clang_major__ == (major) && __clang_minor__ >= (minor))) + +#if __clang__ && defined __has_builtin + #define ECB_CLANG_BUILTIN(x) __has_builtin (x) +#else + #define ECB_CLANG_BUILTIN(x) 0 +#endif + +#if __clang__ && defined __has_extension + #define ECB_CLANG_EXTENSION(x) __has_extension (x) +#else + #define ECB_CLANG_EXTENSION(x) 0 +#endif + +#define ECB_CPP (__cplusplus+0) +#define ECB_CPP11 (__cplusplus >= 201103L) +#define ECB_CPP14 (__cplusplus >= 201402L) +#define ECB_CPP17 (__cplusplus >= 201703L) + +#if ECB_CPP + #define ECB_C 0 + #define ECB_STDC_VERSION 0 +#else + #define ECB_C 1 + #define ECB_STDC_VERSION __STDC_VERSION__ +#endif + +#define ECB_C99 (ECB_STDC_VERSION >= 199901L) +#define ECB_C11 (ECB_STDC_VERSION >= 201112L) +#define ECB_C17 (ECB_STDC_VERSION >= 201710L) + +#if ECB_CPP + #define ECB_EXTERN_C extern "C" + #define ECB_EXTERN_C_BEG ECB_EXTERN_C { + #define ECB_EXTERN_C_END } +#else + #define ECB_EXTERN_C extern + #define ECB_EXTERN_C_BEG + #define ECB_EXTERN_C_END +#endif + +/*****************************************************************************/ + +/* ECB_NO_THREADS - ecb is not used by multiple threads, ever */ +/* ECB_NO_SMP - ecb might be used in multiple threads, but only on a single cpu */ + +#if ECB_NO_THREADS + #define ECB_NO_SMP 1 +#endif + +#if ECB_NO_SMP + #define ECB_MEMORY_FENCE do { } while (0) +#endif + +/* http://www-01.ibm.com/support/knowledgecenter/SSGH3R_13.1.0/com.ibm.xlcpp131.aix.doc/compiler_ref/compiler_builtins.html */ +#if __xlC__ && ECB_CPP + #include +#endif + +#if 1400 <= _MSC_VER + #include /* fence functions _ReadBarrier, also bit search functions _BitScanReverse */ +#endif + +#ifndef ECB_MEMORY_FENCE + #if ECB_GCC_VERSION(2,5) || defined __INTEL_COMPILER || (__llvm__ && __GNUC__) || __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110 + #define ECB_MEMORY_FENCE_RELAXED __asm__ __volatile__ ("" : : : "memory") + #if __i386 || __i386__ + #define ECB_MEMORY_FENCE __asm__ __volatile__ ("lock; orb $0, -1(%%esp)" : : : "memory") + #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("" : : : "memory") + #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("" : : : "memory") + #elif ECB_GCC_AMD64 + #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mfence" : : : "memory") + #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("" : : : "memory") + #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("" : : : "memory") + #elif __powerpc__ || __ppc__ || __powerpc64__ || __ppc64__ + #define ECB_MEMORY_FENCE __asm__ __volatile__ ("sync" : : : "memory") + #elif defined __ARM_ARCH_2__ \ + || defined __ARM_ARCH_3__ || defined __ARM_ARCH_3M__ \ + || defined __ARM_ARCH_4__ || defined __ARM_ARCH_4T__ \ + || defined __ARM_ARCH_5__ || defined __ARM_ARCH_5E__ \ + || defined __ARM_ARCH_5T__ || defined __ARM_ARCH_5TE__ \ + || defined __ARM_ARCH_5TEJ__ + /* should not need any, unless running old code on newer cpu - arm doesn't support that */ + #elif defined __ARM_ARCH_6__ || defined __ARM_ARCH_6J__ \ + || defined __ARM_ARCH_6K__ || defined __ARM_ARCH_6ZK__ \ + || defined __ARM_ARCH_6T2__ + #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mcr p15,0,%0,c7,c10,5" : : "r" (0) : "memory") + #elif defined __ARM_ARCH_7__ || defined __ARM_ARCH_7A__ \ + || defined __ARM_ARCH_7R__ || defined __ARM_ARCH_7M__ + #define ECB_MEMORY_FENCE __asm__ __volatile__ ("dmb" : : : "memory") + #elif __aarch64__ + #define ECB_MEMORY_FENCE __asm__ __volatile__ ("dmb ish" : : : "memory") + #elif (__sparc || __sparc__) && !(__sparc_v8__ || defined __sparcv8) + #define ECB_MEMORY_FENCE __asm__ __volatile__ ("membar #LoadStore | #LoadLoad | #StoreStore | #StoreLoad" : : : "memory") + #define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("membar #LoadStore | #LoadLoad" : : : "memory") + #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("membar #LoadStore | #StoreStore") + #elif defined __s390__ || defined __s390x__ + #define ECB_MEMORY_FENCE __asm__ __volatile__ ("bcr 15,0" : : : "memory") + #elif defined __mips__ + /* GNU/Linux emulates sync on mips1 architectures, so we force its use */ + /* anybody else who still uses mips1 is supposed to send in their version, with detection code. */ + #define ECB_MEMORY_FENCE __asm__ __volatile__ (".set mips2; sync; .set mips0" : : : "memory") + #elif defined __alpha__ + #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mb" : : : "memory") + #elif defined __hppa__ + #define ECB_MEMORY_FENCE __asm__ __volatile__ ("" : : : "memory") + #define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("") + #elif defined __ia64__ + #define ECB_MEMORY_FENCE __asm__ __volatile__ ("mf" : : : "memory") + #elif defined __m68k__ + #define ECB_MEMORY_FENCE __asm__ __volatile__ ("" : : : "memory") + #elif defined __m88k__ + #define ECB_MEMORY_FENCE __asm__ __volatile__ ("tb1 0,%%r0,128" : : : "memory") + #elif defined __sh__ + #define ECB_MEMORY_FENCE __asm__ __volatile__ ("" : : : "memory") + #endif + #endif +#endif + +#ifndef ECB_MEMORY_FENCE + #if ECB_GCC_VERSION(4,7) + /* see comment below (stdatomic.h) about the C11 memory model. */ + #define ECB_MEMORY_FENCE __atomic_thread_fence (__ATOMIC_SEQ_CST) + #define ECB_MEMORY_FENCE_ACQUIRE __atomic_thread_fence (__ATOMIC_ACQUIRE) + #define ECB_MEMORY_FENCE_RELEASE __atomic_thread_fence (__ATOMIC_RELEASE) + #define ECB_MEMORY_FENCE_RELAXED __atomic_thread_fence (__ATOMIC_RELAXED) + + #elif ECB_CLANG_EXTENSION(c_atomic) + /* see comment below (stdatomic.h) about the C11 memory model. */ + #define ECB_MEMORY_FENCE __c11_atomic_thread_fence (__ATOMIC_SEQ_CST) + #define ECB_MEMORY_FENCE_ACQUIRE __c11_atomic_thread_fence (__ATOMIC_ACQUIRE) + #define ECB_MEMORY_FENCE_RELEASE __c11_atomic_thread_fence (__ATOMIC_RELEASE) + #define ECB_MEMORY_FENCE_RELAXED __c11_atomic_thread_fence (__ATOMIC_RELAXED) + + #elif ECB_GCC_VERSION(4,4) || defined __INTEL_COMPILER || defined __clang__ + #define ECB_MEMORY_FENCE __sync_synchronize () + #elif _MSC_VER >= 1500 /* VC++ 2008 */ + /* apparently, microsoft broke all the memory barrier stuff in Visual Studio 2008... */ + #pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier) + #define ECB_MEMORY_FENCE _ReadWriteBarrier (); MemoryBarrier() + #define ECB_MEMORY_FENCE_ACQUIRE _ReadWriteBarrier (); MemoryBarrier() /* according to msdn, _ReadBarrier is not a load fence */ + #define ECB_MEMORY_FENCE_RELEASE _WriteBarrier (); MemoryBarrier() + #elif _MSC_VER >= 1400 /* VC++ 2005 */ + #pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier) + #define ECB_MEMORY_FENCE _ReadWriteBarrier () + #define ECB_MEMORY_FENCE_ACQUIRE _ReadWriteBarrier () /* according to msdn, _ReadBarrier is not a load fence */ + #define ECB_MEMORY_FENCE_RELEASE _WriteBarrier () + #elif defined _WIN32 + #include + #define ECB_MEMORY_FENCE MemoryBarrier () /* actually just xchg on x86... scary */ + #elif __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110 + #include + #define ECB_MEMORY_FENCE __machine_rw_barrier () + #define ECB_MEMORY_FENCE_ACQUIRE __machine_acq_barrier () + #define ECB_MEMORY_FENCE_RELEASE __machine_rel_barrier () + #define ECB_MEMORY_FENCE_RELAXED __compiler_barrier () + #elif __xlC__ + #define ECB_MEMORY_FENCE __sync () + #endif +#endif + +#ifndef ECB_MEMORY_FENCE + #if ECB_C11 && !defined __STDC_NO_ATOMICS__ + /* we assume that these memory fences work on all variables/all memory accesses, */ + /* not just C11 atomics and atomic accesses */ + #include + #define ECB_MEMORY_FENCE atomic_thread_fence (memory_order_seq_cst) + #define ECB_MEMORY_FENCE_ACQUIRE atomic_thread_fence (memory_order_acquire) + #define ECB_MEMORY_FENCE_RELEASE atomic_thread_fence (memory_order_release) + #endif +#endif + +#ifndef ECB_MEMORY_FENCE + #if !ECB_AVOID_PTHREADS + /* + * if you get undefined symbol references to pthread_mutex_lock, + * or failure to find pthread.h, then you should implement + * the ECB_MEMORY_FENCE operations for your cpu/compiler + * OR provide pthread.h and link against the posix thread library + * of your system. + */ + #include + #define ECB_NEEDS_PTHREADS 1 + #define ECB_MEMORY_FENCE_NEEDS_PTHREADS 1 + + static pthread_mutex_t ecb_mf_lock = PTHREAD_MUTEX_INITIALIZER; + #define ECB_MEMORY_FENCE do { pthread_mutex_lock (&ecb_mf_lock); pthread_mutex_unlock (&ecb_mf_lock); } while (0) + #endif +#endif + +#if !defined ECB_MEMORY_FENCE_ACQUIRE && defined ECB_MEMORY_FENCE + #define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE +#endif + +#if !defined ECB_MEMORY_FENCE_RELEASE && defined ECB_MEMORY_FENCE + #define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE +#endif + +#if !defined ECB_MEMORY_FENCE_RELAXED && defined ECB_MEMORY_FENCE + #define ECB_MEMORY_FENCE_RELAXED ECB_MEMORY_FENCE /* very heavy-handed */ +#endif + +/*****************************************************************************/ + +#if ECB_CPP + #define ecb_inline static inline +#elif ECB_GCC_VERSION(2,5) + #define ecb_inline static __inline__ +#elif ECB_C99 + #define ecb_inline static inline +#else + #define ecb_inline static +#endif + +#if ECB_GCC_VERSION(3,3) + #define ecb_restrict __restrict__ +#elif ECB_C99 + #define ecb_restrict restrict +#else + #define ecb_restrict +#endif + +typedef int ecb_bool; + +#define ECB_CONCAT_(a, b) a ## b +#define ECB_CONCAT(a, b) ECB_CONCAT_(a, b) +#define ECB_STRINGIFY_(a) # a +#define ECB_STRINGIFY(a) ECB_STRINGIFY_(a) +#define ECB_STRINGIFY_EXPR(expr) ((expr), ECB_STRINGIFY_ (expr)) + +#define ecb_function_ ecb_inline + +#if ECB_GCC_VERSION(3,1) || ECB_CLANG_VERSION(2,8) + #define ecb_attribute(attrlist) __attribute__ (attrlist) +#else + #define ecb_attribute(attrlist) +#endif + +#if ECB_GCC_VERSION(3,1) || ECB_CLANG_BUILTIN(__builtin_constant_p) + #define ecb_is_constant(expr) __builtin_constant_p (expr) +#else + /* possible C11 impl for integral types + typedef struct ecb_is_constant_struct ecb_is_constant_struct; + #define ecb_is_constant(expr) _Generic ((1 ? (struct ecb_is_constant_struct *)0 : (void *)((expr) - (expr)), ecb_is_constant_struct *: 0, default: 1)) */ + + #define ecb_is_constant(expr) 0 +#endif + +#if ECB_GCC_VERSION(3,1) || ECB_CLANG_BUILTIN(__builtin_expect) + #define ecb_expect(expr,value) __builtin_expect ((expr),(value)) +#else + #define ecb_expect(expr,value) (expr) +#endif + +#if ECB_GCC_VERSION(3,1) || ECB_CLANG_BUILTIN(__builtin_prefetch) + #define ecb_prefetch(addr,rw,locality) __builtin_prefetch (addr, rw, locality) +#else + #define ecb_prefetch(addr,rw,locality) +#endif + +/* no emulation for ecb_decltype */ +#if ECB_CPP11 + // older implementations might have problems with decltype(x)::type, work around it + template struct ecb_decltype_t { typedef T type; }; + #define ecb_decltype(x) ecb_decltype_t::type +#elif ECB_GCC_VERSION(3,0) || ECB_CLANG_VERSION(2,8) + #define ecb_decltype(x) __typeof__ (x) +#endif + +#if _MSC_VER >= 1300 + #define ecb_deprecated __declspec (deprecated) +#else + #define ecb_deprecated ecb_attribute ((__deprecated__)) +#endif + +#if _MSC_VER >= 1500 + #define ecb_deprecated_message(msg) __declspec (deprecated (msg)) +#elif ECB_GCC_VERSION(4,5) + #define ecb_deprecated_message(msg) ecb_attribute ((__deprecated__ (msg)) +#else + #define ecb_deprecated_message(msg) ecb_deprecated +#endif + +#if _MSC_VER >= 1400 + #define ecb_noinline __declspec (noinline) +#else + #define ecb_noinline ecb_attribute ((__noinline__)) +#endif + +#define ecb_unused ecb_attribute ((__unused__)) +#define ecb_const ecb_attribute ((__const__)) +#define ecb_pure ecb_attribute ((__pure__)) + +#if ECB_C11 || __IBMC_NORETURN + /* http://www-01.ibm.com/support/knowledgecenter/SSGH3R_13.1.0/com.ibm.xlcpp131.aix.doc/language_ref/noreturn.html */ + #define ecb_noreturn _Noreturn +#elif ECB_CPP11 + #define ecb_noreturn [[noreturn]] +#elif _MSC_VER >= 1200 + /* http://msdn.microsoft.com/en-us/library/k6ktzx3s.aspx */ + #define ecb_noreturn __declspec (noreturn) +#else + #define ecb_noreturn ecb_attribute ((__noreturn__)) +#endif + +#if ECB_GCC_VERSION(4,3) + #define ecb_artificial ecb_attribute ((__artificial__)) + #define ecb_hot ecb_attribute ((__hot__)) + #define ecb_cold ecb_attribute ((__cold__)) +#else + #define ecb_artificial + #define ecb_hot + #define ecb_cold +#endif + +/* put around conditional expressions if you are very sure that the */ +/* expression is mostly true or mostly false. note that these return */ +/* booleans, not the expression. */ +#define ecb_expect_false(expr) ecb_expect (!!(expr), 0) +#define ecb_expect_true(expr) ecb_expect (!!(expr), 1) +/* for compatibility to the rest of the world */ +#define ecb_likely(expr) ecb_expect_true (expr) +#define ecb_unlikely(expr) ecb_expect_false (expr) + +/* count trailing zero bits and count # of one bits */ +#if ECB_GCC_VERSION(3,4) \ + || (ECB_CLANG_BUILTIN(__builtin_clz) && ECB_CLANG_BUILTIN(__builtin_clzll) \ + && ECB_CLANG_BUILTIN(__builtin_ctz) && ECB_CLANG_BUILTIN(__builtin_ctzll) \ + && ECB_CLANG_BUILTIN(__builtin_popcount)) + /* we assume int == 32 bit, long == 32 or 64 bit and long long == 64 bit */ + #define ecb_ld32(x) (__builtin_clz (x) ^ 31) + #define ecb_ld64(x) (__builtin_clzll (x) ^ 63) + #define ecb_ctz32(x) __builtin_ctz (x) + #define ecb_ctz64(x) __builtin_ctzll (x) + #define ecb_popcount32(x) __builtin_popcount (x) + /* no popcountll */ +#else + ecb_function_ ecb_const int ecb_ctz32 (uint32_t x); + ecb_function_ ecb_const int + ecb_ctz32 (uint32_t x) + { +#if 1400 <= _MSC_VER && (_M_IX86 || _M_X64 || _M_IA64 || _M_ARM) + unsigned long r; + _BitScanForward (&r, x); + return (int)r; +#else + int r = 0; + + x &= ~x + 1; /* this isolates the lowest bit */ + +#if ECB_branchless_on_i386 + r += !!(x & 0xaaaaaaaa) << 0; + r += !!(x & 0xcccccccc) << 1; + r += !!(x & 0xf0f0f0f0) << 2; + r += !!(x & 0xff00ff00) << 3; + r += !!(x & 0xffff0000) << 4; +#else + if (x & 0xaaaaaaaa) r += 1; + if (x & 0xcccccccc) r += 2; + if (x & 0xf0f0f0f0) r += 4; + if (x & 0xff00ff00) r += 8; + if (x & 0xffff0000) r += 16; +#endif + + return r; +#endif + } + + ecb_function_ ecb_const int ecb_ctz64 (uint64_t x); + ecb_function_ ecb_const int + ecb_ctz64 (uint64_t x) + { +#if 1400 <= _MSC_VER && (_M_X64 || _M_IA64 || _M_ARM) + unsigned long r; + _BitScanForward64 (&r, x); + return (int)r; +#else + int shift = x & 0xffffffff ? 0 : 32; + return ecb_ctz32 (x >> shift) + shift; +#endif + } + + ecb_function_ ecb_const int ecb_popcount32 (uint32_t x); + ecb_function_ ecb_const int + ecb_popcount32 (uint32_t x) + { + x -= (x >> 1) & 0x55555555; + x = ((x >> 2) & 0x33333333) + (x & 0x33333333); + x = ((x >> 4) + x) & 0x0f0f0f0f; + x *= 0x01010101; + + return x >> 24; + } + + ecb_function_ ecb_const int ecb_ld32 (uint32_t x); + ecb_function_ ecb_const int ecb_ld32 (uint32_t x) + { +#if 1400 <= _MSC_VER && (_M_IX86 || _M_X64 || _M_IA64 || _M_ARM) + unsigned long r; + _BitScanReverse (&r, x); + return (int)r; +#else + int r = 0; + + if (x >> 16) { x >>= 16; r += 16; } + if (x >> 8) { x >>= 8; r += 8; } + if (x >> 4) { x >>= 4; r += 4; } + if (x >> 2) { x >>= 2; r += 2; } + if (x >> 1) { r += 1; } + + return r; +#endif + } + + ecb_function_ ecb_const int ecb_ld64 (uint64_t x); + ecb_function_ ecb_const int ecb_ld64 (uint64_t x) + { +#if 1400 <= _MSC_VER && (_M_X64 || _M_IA64 || _M_ARM) + unsigned long r; + _BitScanReverse64 (&r, x); + return (int)r; +#else + int r = 0; + + if (x >> 32) { x >>= 32; r += 32; } + + return r + ecb_ld32 (x); +#endif + } +#endif + +ecb_function_ ecb_const ecb_bool ecb_is_pot32 (uint32_t x); +ecb_function_ ecb_const ecb_bool ecb_is_pot32 (uint32_t x) { return !(x & (x - 1)); } +ecb_function_ ecb_const ecb_bool ecb_is_pot64 (uint64_t x); +ecb_function_ ecb_const ecb_bool ecb_is_pot64 (uint64_t x) { return !(x & (x - 1)); } + +ecb_function_ ecb_const uint8_t ecb_bitrev8 (uint8_t x); +ecb_function_ ecb_const uint8_t ecb_bitrev8 (uint8_t x) +{ + return ( (x * 0x0802U & 0x22110U) + | (x * 0x8020U & 0x88440U)) * 0x10101U >> 16; +} + +ecb_function_ ecb_const uint16_t ecb_bitrev16 (uint16_t x); +ecb_function_ ecb_const uint16_t ecb_bitrev16 (uint16_t x) +{ + x = ((x >> 1) & 0x5555) | ((x & 0x5555) << 1); + x = ((x >> 2) & 0x3333) | ((x & 0x3333) << 2); + x = ((x >> 4) & 0x0f0f) | ((x & 0x0f0f) << 4); + x = ( x >> 8 ) | ( x << 8); + + return x; +} + +ecb_function_ ecb_const uint32_t ecb_bitrev32 (uint32_t x); +ecb_function_ ecb_const uint32_t ecb_bitrev32 (uint32_t x) +{ + x = ((x >> 1) & 0x55555555) | ((x & 0x55555555) << 1); + x = ((x >> 2) & 0x33333333) | ((x & 0x33333333) << 2); + x = ((x >> 4) & 0x0f0f0f0f) | ((x & 0x0f0f0f0f) << 4); + x = ((x >> 8) & 0x00ff00ff) | ((x & 0x00ff00ff) << 8); + x = ( x >> 16 ) | ( x << 16); + + return x; +} + +/* popcount64 is only available on 64 bit cpus as gcc builtin */ +/* so for this version we are lazy */ +ecb_function_ ecb_const int ecb_popcount64 (uint64_t x); +ecb_function_ ecb_const int +ecb_popcount64 (uint64_t x) +{ + return ecb_popcount32 (x) + ecb_popcount32 (x >> 32); +} + +ecb_inline ecb_const uint8_t ecb_rotl8 (uint8_t x, unsigned int count); +ecb_inline ecb_const uint8_t ecb_rotr8 (uint8_t x, unsigned int count); +ecb_inline ecb_const uint16_t ecb_rotl16 (uint16_t x, unsigned int count); +ecb_inline ecb_const uint16_t ecb_rotr16 (uint16_t x, unsigned int count); +ecb_inline ecb_const uint32_t ecb_rotl32 (uint32_t x, unsigned int count); +ecb_inline ecb_const uint32_t ecb_rotr32 (uint32_t x, unsigned int count); +ecb_inline ecb_const uint64_t ecb_rotl64 (uint64_t x, unsigned int count); +ecb_inline ecb_const uint64_t ecb_rotr64 (uint64_t x, unsigned int count); + +ecb_inline ecb_const uint8_t ecb_rotl8 (uint8_t x, unsigned int count) { return (x >> ( 8 - count)) | (x << count); } +ecb_inline ecb_const uint8_t ecb_rotr8 (uint8_t x, unsigned int count) { return (x << ( 8 - count)) | (x >> count); } +ecb_inline ecb_const uint16_t ecb_rotl16 (uint16_t x, unsigned int count) { return (x >> (16 - count)) | (x << count); } +ecb_inline ecb_const uint16_t ecb_rotr16 (uint16_t x, unsigned int count) { return (x << (16 - count)) | (x >> count); } +ecb_inline ecb_const uint32_t ecb_rotl32 (uint32_t x, unsigned int count) { return (x >> (32 - count)) | (x << count); } +ecb_inline ecb_const uint32_t ecb_rotr32 (uint32_t x, unsigned int count) { return (x << (32 - count)) | (x >> count); } +ecb_inline ecb_const uint64_t ecb_rotl64 (uint64_t x, unsigned int count) { return (x >> (64 - count)) | (x << count); } +ecb_inline ecb_const uint64_t ecb_rotr64 (uint64_t x, unsigned int count) { return (x << (64 - count)) | (x >> count); } + +#if ECB_CPP + +inline uint8_t ecb_ctz (uint8_t v) { return ecb_ctz32 (v); } +inline uint16_t ecb_ctz (uint16_t v) { return ecb_ctz32 (v); } +inline uint32_t ecb_ctz (uint32_t v) { return ecb_ctz32 (v); } +inline uint64_t ecb_ctz (uint64_t v) { return ecb_ctz64 (v); } + +inline bool ecb_is_pot (uint8_t v) { return ecb_is_pot32 (v); } +inline bool ecb_is_pot (uint16_t v) { return ecb_is_pot32 (v); } +inline bool ecb_is_pot (uint32_t v) { return ecb_is_pot32 (v); } +inline bool ecb_is_pot (uint64_t v) { return ecb_is_pot64 (v); } + +inline int ecb_ld (uint8_t v) { return ecb_ld32 (v); } +inline int ecb_ld (uint16_t v) { return ecb_ld32 (v); } +inline int ecb_ld (uint32_t v) { return ecb_ld32 (v); } +inline int ecb_ld (uint64_t v) { return ecb_ld64 (v); } + +inline int ecb_popcount (uint8_t v) { return ecb_popcount32 (v); } +inline int ecb_popcount (uint16_t v) { return ecb_popcount32 (v); } +inline int ecb_popcount (uint32_t v) { return ecb_popcount32 (v); } +inline int ecb_popcount (uint64_t v) { return ecb_popcount64 (v); } + +inline uint8_t ecb_bitrev (uint8_t v) { return ecb_bitrev8 (v); } +inline uint16_t ecb_bitrev (uint16_t v) { return ecb_bitrev16 (v); } +inline uint32_t ecb_bitrev (uint32_t v) { return ecb_bitrev32 (v); } + +inline uint8_t ecb_rotl (uint8_t v, unsigned int count) { return ecb_rotl8 (v, count); } +inline uint16_t ecb_rotl (uint16_t v, unsigned int count) { return ecb_rotl16 (v, count); } +inline uint32_t ecb_rotl (uint32_t v, unsigned int count) { return ecb_rotl32 (v, count); } +inline uint64_t ecb_rotl (uint64_t v, unsigned int count) { return ecb_rotl64 (v, count); } + +inline uint8_t ecb_rotr (uint8_t v, unsigned int count) { return ecb_rotr8 (v, count); } +inline uint16_t ecb_rotr (uint16_t v, unsigned int count) { return ecb_rotr16 (v, count); } +inline uint32_t ecb_rotr (uint32_t v, unsigned int count) { return ecb_rotr32 (v, count); } +inline uint64_t ecb_rotr (uint64_t v, unsigned int count) { return ecb_rotr64 (v, count); } + +#endif + +#if ECB_GCC_VERSION(4,3) || (ECB_CLANG_BUILTIN(__builtin_bswap32) && ECB_CLANG_BUILTIN(__builtin_bswap64)) + #if ECB_GCC_VERSION(4,8) || ECB_CLANG_BUILTIN(__builtin_bswap16) + #define ecb_bswap16(x) __builtin_bswap16 (x) + #else + #define ecb_bswap16(x) (__builtin_bswap32 (x) >> 16) + #endif + #define ecb_bswap32(x) __builtin_bswap32 (x) + #define ecb_bswap64(x) __builtin_bswap64 (x) +#elif _MSC_VER + #include + #define ecb_bswap16(x) ((uint16_t)_byteswap_ushort ((uint16_t)(x))) + #define ecb_bswap32(x) ((uint32_t)_byteswap_ulong ((uint32_t)(x))) + #define ecb_bswap64(x) ((uint64_t)_byteswap_uint64 ((uint64_t)(x))) +#else + ecb_function_ ecb_const uint16_t ecb_bswap16 (uint16_t x); + ecb_function_ ecb_const uint16_t + ecb_bswap16 (uint16_t x) + { + return ecb_rotl16 (x, 8); + } + + ecb_function_ ecb_const uint32_t ecb_bswap32 (uint32_t x); + ecb_function_ ecb_const uint32_t + ecb_bswap32 (uint32_t x) + { + return (((uint32_t)ecb_bswap16 (x)) << 16) | ecb_bswap16 (x >> 16); + } + + ecb_function_ ecb_const uint64_t ecb_bswap64 (uint64_t x); + ecb_function_ ecb_const uint64_t + ecb_bswap64 (uint64_t x) + { + return (((uint64_t)ecb_bswap32 (x)) << 32) | ecb_bswap32 (x >> 32); + } +#endif + +#if ECB_GCC_VERSION(4,5) || ECB_CLANG_BUILTIN(__builtin_unreachable) + #define ecb_unreachable() __builtin_unreachable () +#else + /* this seems to work fine, but gcc always emits a warning for it :/ */ + ecb_inline ecb_noreturn void ecb_unreachable (void); + ecb_inline ecb_noreturn void ecb_unreachable (void) { } +#endif + +/* try to tell the compiler that some condition is definitely true */ +#define ecb_assume(cond) if (!(cond)) ecb_unreachable (); else 0 + +ecb_inline ecb_const uint32_t ecb_byteorder_helper (void); +ecb_inline ecb_const uint32_t +ecb_byteorder_helper (void) +{ + /* the union code still generates code under pressure in gcc, */ + /* but less than using pointers, and always seems to */ + /* successfully return a constant. */ + /* the reason why we have this horrible preprocessor mess */ + /* is to avoid it in all cases, at least on common architectures */ + /* or when using a recent enough gcc version (>= 4.6) */ +#if (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) \ + || ((__i386 || __i386__ || _M_IX86 || ECB_GCC_AMD64 || ECB_MSVC_AMD64) && !__VOS__) + #define ECB_LITTLE_ENDIAN 1 + return 0x44332211; +#elif (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) \ + || ((__AARCH64EB__ || __MIPSEB__ || __ARMEB__) && !__VOS__) + #define ECB_BIG_ENDIAN 1 + return 0x11223344; +#else + union + { + uint8_t c[4]; + uint32_t u; + } u = { 0x11, 0x22, 0x33, 0x44 }; + return u.u; +#endif +} + +ecb_inline ecb_const ecb_bool ecb_big_endian (void); +ecb_inline ecb_const ecb_bool ecb_big_endian (void) { return ecb_byteorder_helper () == 0x11223344; } +ecb_inline ecb_const ecb_bool ecb_little_endian (void); +ecb_inline ecb_const ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == 0x44332211; } + +/*****************************************************************************/ +/* unaligned load/store */ + +ecb_inline uint_fast16_t ecb_be_u16_to_host (uint_fast16_t v) { return ecb_little_endian () ? ecb_bswap16 (v) : v; } +ecb_inline uint_fast32_t ecb_be_u32_to_host (uint_fast32_t v) { return ecb_little_endian () ? ecb_bswap32 (v) : v; } +ecb_inline uint_fast64_t ecb_be_u64_to_host (uint_fast64_t v) { return ecb_little_endian () ? ecb_bswap64 (v) : v; } + +ecb_inline uint_fast16_t ecb_le_u16_to_host (uint_fast16_t v) { return ecb_big_endian () ? ecb_bswap16 (v) : v; } +ecb_inline uint_fast32_t ecb_le_u32_to_host (uint_fast32_t v) { return ecb_big_endian () ? ecb_bswap32 (v) : v; } +ecb_inline uint_fast64_t ecb_le_u64_to_host (uint_fast64_t v) { return ecb_big_endian () ? ecb_bswap64 (v) : v; } + +ecb_inline uint_fast16_t ecb_peek_u16_u (const void *ptr) { uint16_t v; memcpy (&v, ptr, sizeof (v)); return v; } +ecb_inline uint_fast32_t ecb_peek_u32_u (const void *ptr) { uint32_t v; memcpy (&v, ptr, sizeof (v)); return v; } +ecb_inline uint_fast64_t ecb_peek_u64_u (const void *ptr) { uint64_t v; memcpy (&v, ptr, sizeof (v)); return v; } + +ecb_inline uint_fast16_t ecb_peek_be_u16_u (const void *ptr) { return ecb_be_u16_to_host (ecb_peek_u16_u (ptr)); } +ecb_inline uint_fast32_t ecb_peek_be_u32_u (const void *ptr) { return ecb_be_u32_to_host (ecb_peek_u32_u (ptr)); } +ecb_inline uint_fast64_t ecb_peek_be_u64_u (const void *ptr) { return ecb_be_u64_to_host (ecb_peek_u64_u (ptr)); } + +ecb_inline uint_fast16_t ecb_peek_le_u16_u (const void *ptr) { return ecb_le_u16_to_host (ecb_peek_u16_u (ptr)); } +ecb_inline uint_fast32_t ecb_peek_le_u32_u (const void *ptr) { return ecb_le_u32_to_host (ecb_peek_u32_u (ptr)); } +ecb_inline uint_fast64_t ecb_peek_le_u64_u (const void *ptr) { return ecb_le_u64_to_host (ecb_peek_u64_u (ptr)); } + +ecb_inline uint_fast16_t ecb_host_to_be_u16 (uint_fast16_t v) { return ecb_little_endian () ? ecb_bswap16 (v) : v; } +ecb_inline uint_fast32_t ecb_host_to_be_u32 (uint_fast32_t v) { return ecb_little_endian () ? ecb_bswap32 (v) : v; } +ecb_inline uint_fast64_t ecb_host_to_be_u64 (uint_fast64_t v) { return ecb_little_endian () ? ecb_bswap64 (v) : v; } + +ecb_inline uint_fast16_t ecb_host_to_le_u16 (uint_fast16_t v) { return ecb_big_endian () ? ecb_bswap16 (v) : v; } +ecb_inline uint_fast32_t ecb_host_to_le_u32 (uint_fast32_t v) { return ecb_big_endian () ? ecb_bswap32 (v) : v; } +ecb_inline uint_fast64_t ecb_host_to_le_u64 (uint_fast64_t v) { return ecb_big_endian () ? ecb_bswap64 (v) : v; } + +ecb_inline void ecb_poke_u16_u (void *ptr, uint16_t v) { memcpy (ptr, &v, sizeof (v)); } +ecb_inline void ecb_poke_u32_u (void *ptr, uint32_t v) { memcpy (ptr, &v, sizeof (v)); } +ecb_inline void ecb_poke_u64_u (void *ptr, uint64_t v) { memcpy (ptr, &v, sizeof (v)); } + +ecb_inline void ecb_poke_be_u16_u (void *ptr, uint_fast16_t v) { ecb_poke_u16_u (ptr, ecb_host_to_be_u16 (v)); } +ecb_inline void ecb_poke_be_u32_u (void *ptr, uint_fast32_t v) { ecb_poke_u32_u (ptr, ecb_host_to_be_u32 (v)); } +ecb_inline void ecb_poke_be_u64_u (void *ptr, uint_fast64_t v) { ecb_poke_u64_u (ptr, ecb_host_to_be_u64 (v)); } + +ecb_inline void ecb_poke_le_u16_u (void *ptr, uint_fast16_t v) { ecb_poke_u16_u (ptr, ecb_host_to_le_u16 (v)); } +ecb_inline void ecb_poke_le_u32_u (void *ptr, uint_fast32_t v) { ecb_poke_u32_u (ptr, ecb_host_to_le_u32 (v)); } +ecb_inline void ecb_poke_le_u64_u (void *ptr, uint_fast64_t v) { ecb_poke_u64_u (ptr, ecb_host_to_le_u64 (v)); } + +#if ECB_CPP + +inline uint8_t ecb_bswap (uint8_t v) { return v; } +inline uint16_t ecb_bswap (uint16_t v) { return ecb_bswap16 (v); } +inline uint32_t ecb_bswap (uint32_t v) { return ecb_bswap32 (v); } +inline uint64_t ecb_bswap (uint64_t v) { return ecb_bswap64 (v); } + +template inline T ecb_be_to_host (T v) { return ecb_little_endian () ? ecb_bswap (v) : v; } +template inline T ecb_le_to_host (T v) { return ecb_big_endian () ? ecb_bswap (v) : v; } +template inline T ecb_peek (const void *ptr) { return *(const T *)ptr; } +template inline T ecb_peek_be (const void *ptr) { return ecb_be_to_host (ecb_peek (ptr)); } +template inline T ecb_peek_le (const void *ptr) { return ecb_le_to_host (ecb_peek (ptr)); } +template inline T ecb_peek_u (const void *ptr) { T v; memcpy (&v, ptr, sizeof (v)); return v; } +template inline T ecb_peek_be_u (const void *ptr) { return ecb_be_to_host (ecb_peek_u (ptr)); } +template inline T ecb_peek_le_u (const void *ptr) { return ecb_le_to_host (ecb_peek_u (ptr)); } + +template inline T ecb_host_to_be (T v) { return ecb_little_endian () ? ecb_bswap (v) : v; } +template inline T ecb_host_to_le (T v) { return ecb_big_endian () ? ecb_bswap (v) : v; } +template inline void ecb_poke (void *ptr, T v) { *(T *)ptr = v; } +template inline void ecb_poke_be (void *ptr, T v) { return ecb_poke (ptr, ecb_host_to_be (v)); } +template inline void ecb_poke_le (void *ptr, T v) { return ecb_poke (ptr, ecb_host_to_le (v)); } +template inline void ecb_poke_u (void *ptr, T v) { memcpy (ptr, &v, sizeof (v)); } +template inline void ecb_poke_be_u (void *ptr, T v) { return ecb_poke_u (ptr, ecb_host_to_be (v)); } +template inline void ecb_poke_le_u (void *ptr, T v) { return ecb_poke_u (ptr, ecb_host_to_le (v)); } + +#endif + +/*****************************************************************************/ + +#if ECB_GCC_VERSION(3,0) || ECB_C99 + #define ecb_mod(m,n) ((m) % (n) + ((m) % (n) < 0 ? (n) : 0)) +#else + #define ecb_mod(m,n) ((m) < 0 ? ((n) - 1 - ((-1 - (m)) % (n))) : ((m) % (n))) +#endif + +#if ECB_CPP + template + static inline T ecb_div_rd (T val, T div) + { + return val < 0 ? - ((-val + div - 1) / div) : (val ) / div; + } + template + static inline T ecb_div_ru (T val, T div) + { + return val < 0 ? - ((-val ) / div) : (val + div - 1) / div; + } +#else + #define ecb_div_rd(val,div) ((val) < 0 ? - ((-(val) + (div) - 1) / (div)) : ((val) ) / (div)) + #define ecb_div_ru(val,div) ((val) < 0 ? - ((-(val) ) / (div)) : ((val) + (div) - 1) / (div)) +#endif + +#if ecb_cplusplus_does_not_suck + /* does not work for local types (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm) */ + template + static inline int ecb_array_length (const T (&arr)[N]) + { + return N; + } +#else + #define ecb_array_length(name) (sizeof (name) / sizeof (name [0])) +#endif + +/*****************************************************************************/ + +ecb_function_ ecb_const uint32_t ecb_binary16_to_binary32 (uint32_t x); +ecb_function_ ecb_const uint32_t +ecb_binary16_to_binary32 (uint32_t x) +{ + unsigned int s = (x & 0x8000) << (31 - 15); + int e = (x >> 10) & 0x001f; + unsigned int m = x & 0x03ff; + + if (ecb_expect_false (e == 31)) + /* infinity or NaN */ + e = 255 - (127 - 15); + else if (ecb_expect_false (!e)) + { + if (ecb_expect_true (!m)) + /* zero, handled by code below by forcing e to 0 */ + e = 0 - (127 - 15); + else + { + /* subnormal, renormalise */ + unsigned int s = 10 - ecb_ld32 (m); + + m = (m << s) & 0x3ff; /* mask implicit bit */ + e -= s - 1; + } + } + + /* e and m now are normalised, or zero, (or inf or nan) */ + e += 127 - 15; + + return s | (e << 23) | (m << (23 - 10)); +} + +ecb_function_ ecb_const uint16_t ecb_binary32_to_binary16 (uint32_t x); +ecb_function_ ecb_const uint16_t +ecb_binary32_to_binary16 (uint32_t x) +{ + unsigned int s = (x >> 16) & 0x00008000; /* sign bit, the easy part */ + unsigned int e = ((x >> 23) & 0x000000ff) - (127 - 15); /* the desired exponent */ + unsigned int m = x & 0x007fffff; + + x &= 0x7fffffff; + + /* if it's within range of binary16 normals, use fast path */ + if (ecb_expect_true (0x38800000 <= x && x <= 0x477fefff)) + { + /* mantissa round-to-even */ + m += 0x00000fff + ((m >> (23 - 10)) & 1); + + /* handle overflow */ + if (ecb_expect_false (m >= 0x00800000)) + { + m >>= 1; + e += 1; + } + + return s | (e << 10) | (m >> (23 - 10)); + } + + /* handle large numbers and infinity */ + if (ecb_expect_true (0x477fefff < x && x <= 0x7f800000)) + return s | 0x7c00; + + /* handle zero, subnormals and small numbers */ + if (ecb_expect_true (x < 0x38800000)) + { + /* zero */ + if (ecb_expect_true (!x)) + return s; + + /* handle subnormals */ + + /* too small, will be zero */ + if (e < (14 - 24)) /* might not be sharp, but is good enough */ + return s; + + m |= 0x00800000; /* make implicit bit explicit */ + + /* very tricky - we need to round to the nearest e (+10) bit value */ + { + unsigned int bits = 14 - e; + unsigned int half = (1 << (bits - 1)) - 1; + unsigned int even = (m >> bits) & 1; + + /* if this overflows, we will end up with a normalised number */ + m = (m + half + even) >> bits; + } + + return s | m; + } + + /* handle NaNs, preserve leftmost nan bits, but make sure we don't turn them into infinities */ + m >>= 13; + + return s | 0x7c00 | m | !m; +} + +/*******************************************************************************/ +/* floating point stuff, can be disabled by defining ECB_NO_LIBM */ + +/* basically, everything uses "ieee pure-endian" floating point numbers */ +/* the only noteworthy exception is ancient armle, which uses order 43218765 */ +#if 0 \ + || __i386 || __i386__ \ + || ECB_GCC_AMD64 \ + || __powerpc__ || __ppc__ || __powerpc64__ || __ppc64__ \ + || defined __s390__ || defined __s390x__ \ + || defined __mips__ \ + || defined __alpha__ \ + || defined __hppa__ \ + || defined __ia64__ \ + || defined __m68k__ \ + || defined __m88k__ \ + || defined __sh__ \ + || defined _M_IX86 || defined ECB_MSVC_AMD64 || defined _M_IA64 \ + || (defined __arm__ && (defined __ARM_EABI__ || defined __EABI__ || defined __VFP_FP__ || defined _WIN32_WCE || defined __ANDROID__)) \ + || defined __aarch64__ + #define ECB_STDFP 1 +#else + #define ECB_STDFP 0 +#endif + +#ifndef ECB_NO_LIBM + + #include /* for frexp*, ldexp*, INFINITY, NAN */ + + /* only the oldest of old doesn't have this one. solaris. */ + #ifdef INFINITY + #define ECB_INFINITY INFINITY + #else + #define ECB_INFINITY HUGE_VAL + #endif + + #ifdef NAN + #define ECB_NAN NAN + #else + #define ECB_NAN ECB_INFINITY + #endif + + #if ECB_C99 || _XOPEN_VERSION >= 600 || _POSIX_VERSION >= 200112L + #define ecb_ldexpf(x,e) ldexpf ((x), (e)) + #define ecb_frexpf(x,e) frexpf ((x), (e)) + #else + #define ecb_ldexpf(x,e) (float) ldexp ((double) (x), (e)) + #define ecb_frexpf(x,e) (float) frexp ((double) (x), (e)) + #endif + + /* convert a float to ieee single/binary32 */ + ecb_function_ ecb_const uint32_t ecb_float_to_binary32 (float x); + ecb_function_ ecb_const uint32_t + ecb_float_to_binary32 (float x) + { + uint32_t r; + + #if ECB_STDFP + memcpy (&r, &x, 4); + #else + /* slow emulation, works for anything but -0 */ + uint32_t m; + int e; + + if (x == 0e0f ) return 0x00000000U; + if (x > +3.40282346638528860e+38f) return 0x7f800000U; + if (x < -3.40282346638528860e+38f) return 0xff800000U; + if (x != x ) return 0x7fbfffffU; + + m = ecb_frexpf (x, &e) * 0x1000000U; + + r = m & 0x80000000U; + + if (r) + m = -m; + + if (e <= -126) + { + m &= 0xffffffU; + m >>= (-125 - e); + e = -126; + } + + r |= (e + 126) << 23; + r |= m & 0x7fffffU; + #endif + + return r; + } + + /* converts an ieee single/binary32 to a float */ + ecb_function_ ecb_const float ecb_binary32_to_float (uint32_t x); + ecb_function_ ecb_const float + ecb_binary32_to_float (uint32_t x) + { + float r; + + #if ECB_STDFP + memcpy (&r, &x, 4); + #else + /* emulation, only works for normals and subnormals and +0 */ + int neg = x >> 31; + int e = (x >> 23) & 0xffU; + + x &= 0x7fffffU; + + if (e) + x |= 0x800000U; + else + e = 1; + + /* we distrust ldexpf a bit and do the 2**-24 scaling by an extra multiply */ + r = ecb_ldexpf (x * (0.5f / 0x800000U), e - 126); + + r = neg ? -r : r; + #endif + + return r; + } + + /* convert a double to ieee double/binary64 */ + ecb_function_ ecb_const uint64_t ecb_double_to_binary64 (double x); + ecb_function_ ecb_const uint64_t + ecb_double_to_binary64 (double x) + { + uint64_t r; + + #if ECB_STDFP + memcpy (&r, &x, 8); + #else + /* slow emulation, works for anything but -0 */ + uint64_t m; + int e; + + if (x == 0e0 ) return 0x0000000000000000U; + if (x > +1.79769313486231470e+308) return 0x7ff0000000000000U; + if (x < -1.79769313486231470e+308) return 0xfff0000000000000U; + if (x != x ) return 0X7ff7ffffffffffffU; + + m = frexp (x, &e) * 0x20000000000000U; + + r = m & 0x8000000000000000;; + + if (r) + m = -m; + + if (e <= -1022) + { + m &= 0x1fffffffffffffU; + m >>= (-1021 - e); + e = -1022; + } + + r |= ((uint64_t)(e + 1022)) << 52; + r |= m & 0xfffffffffffffU; + #endif + + return r; + } + + /* converts an ieee double/binary64 to a double */ + ecb_function_ ecb_const double ecb_binary64_to_double (uint64_t x); + ecb_function_ ecb_const double + ecb_binary64_to_double (uint64_t x) + { + double r; + + #if ECB_STDFP + memcpy (&r, &x, 8); + #else + /* emulation, only works for normals and subnormals and +0 */ + int neg = x >> 63; + int e = (x >> 52) & 0x7ffU; + + x &= 0xfffffffffffffU; + + if (e) + x |= 0x10000000000000U; + else + e = 1; + + /* we distrust ldexp a bit and do the 2**-53 scaling by an extra multiply */ + r = ldexp (x * (0.5 / 0x10000000000000U), e - 1022); + + r = neg ? -r : r; + #endif + + return r; + } + + /* convert a float to ieee half/binary16 */ + ecb_function_ ecb_const uint16_t ecb_float_to_binary16 (float x); + ecb_function_ ecb_const uint16_t + ecb_float_to_binary16 (float x) + { + return ecb_binary32_to_binary16 (ecb_float_to_binary32 (x)); + } + + /* convert an ieee half/binary16 to float */ + ecb_function_ ecb_const float ecb_binary16_to_float (uint16_t x); + ecb_function_ ecb_const float + ecb_binary16_to_float (uint16_t x) + { + return ecb_binary32_to_float (ecb_binary16_to_binary32 (x)); + } + +#endif + +#endif + +/* ECB.H END */ + +#if ECB_MEMORY_FENCE_NEEDS_PTHREADS +/* if your architecture doesn't need memory fences, e.g. because it is + * single-cpu/core, or if you use libev in a project that doesn't use libev + * from multiple threads, then you can define ECB_NO_THREADS when compiling + * libev, in which cases the memory fences become nops. + * alternatively, you can remove this #error and link against libpthread, + * which will then provide the memory fences. + */ +# error "memory fences not defined for your architecture, please report" +#endif + +#ifndef ECB_MEMORY_FENCE +# define ECB_MEMORY_FENCE do { } while (0) +# define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE +# define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE +#endif + +#define inline_size ecb_inline + +#if EV_FEATURE_CODE +# define inline_speed ecb_inline +#else +# define inline_speed ecb_noinline static +#endif + +/*****************************************************************************/ +/* raw syscall wrappers */ + +#if EV_NEED_SYSCALL + +#include + +/* + * define some syscall wrappers for common architectures + * this is mostly for nice looks during debugging, not performance. + * our syscalls return < 0, not == -1, on error. which is good + * enough for linux aio. + * TODO: arm is also common nowadays, maybe even mips and x86 + * TODO: after implementing this, it suddenly looks like overkill, but its hard to remove... + */ +#if __GNUC__ && __linux && ECB_AMD64 && !EV_FEATURE_CODE + /* the costly errno access probably kills this for size optimisation */ + + #define ev_syscall(nr,narg,arg1,arg2,arg3,arg4,arg5,arg6) \ + ({ \ + long res; \ + register unsigned long r6 __asm__ ("r9" ); \ + register unsigned long r5 __asm__ ("r8" ); \ + register unsigned long r4 __asm__ ("r10"); \ + register unsigned long r3 __asm__ ("rdx"); \ + register unsigned long r2 __asm__ ("rsi"); \ + register unsigned long r1 __asm__ ("rdi"); \ + if (narg >= 6) r6 = (unsigned long)(arg6); \ + if (narg >= 5) r5 = (unsigned long)(arg5); \ + if (narg >= 4) r4 = (unsigned long)(arg4); \ + if (narg >= 3) r3 = (unsigned long)(arg3); \ + if (narg >= 2) r2 = (unsigned long)(arg2); \ + if (narg >= 1) r1 = (unsigned long)(arg1); \ + __asm__ __volatile__ ( \ + "syscall\n\t" \ + : "=a" (res) \ + : "0" (nr), "r" (r1), "r" (r2), "r" (r3), "r" (r4), "r" (r5) \ + : "cc", "r11", "cx", "memory"); \ + errno = -res; \ + res; \ + }) + +#endif + +#ifdef ev_syscall + #define ev_syscall0(nr) ev_syscall (nr, 0, 0, 0, 0, 0, 0, 0) + #define ev_syscall1(nr,arg1) ev_syscall (nr, 1, arg1, 0, 0, 0, 0, 0) + #define ev_syscall2(nr,arg1,arg2) ev_syscall (nr, 2, arg1, arg2, 0, 0, 0, 0) + #define ev_syscall3(nr,arg1,arg2,arg3) ev_syscall (nr, 3, arg1, arg2, arg3, 0, 0, 0) + #define ev_syscall4(nr,arg1,arg2,arg3,arg4) ev_syscall (nr, 3, arg1, arg2, arg3, arg4, 0, 0) + #define ev_syscall5(nr,arg1,arg2,arg3,arg4,arg5) ev_syscall (nr, 5, arg1, arg2, arg3, arg4, arg5, 0) + #define ev_syscall6(nr,arg1,arg2,arg3,arg4,arg5,arg6) ev_syscall (nr, 6, arg1, arg2, arg3, arg4, arg5,arg6) +#else + #define ev_syscall0(nr) syscall (nr) + #define ev_syscall1(nr,arg1) syscall (nr, arg1) + #define ev_syscall2(nr,arg1,arg2) syscall (nr, arg1, arg2) + #define ev_syscall3(nr,arg1,arg2,arg3) syscall (nr, arg1, arg2, arg3) + #define ev_syscall4(nr,arg1,arg2,arg3,arg4) syscall (nr, arg1, arg2, arg3, arg4) + #define ev_syscall5(nr,arg1,arg2,arg3,arg4,arg5) syscall (nr, arg1, arg2, arg3, arg4, arg5) + #define ev_syscall6(nr,arg1,arg2,arg3,arg4,arg5,arg6) syscall (nr, arg1, arg2, arg3, arg4, arg5,arg6) +#endif + +#endif + +/*****************************************************************************/ + +#define NUMPRI (EV_MAXPRI - EV_MINPRI + 1) + +#if EV_MINPRI == EV_MAXPRI +# define ABSPRI(w) (((W)w), 0) +#else +# define ABSPRI(w) (((W)w)->priority - EV_MINPRI) +#endif + +#define EMPTY /* required for microsofts broken pseudo-c compiler */ + +typedef ev_watcher *W; +typedef ev_watcher_list *WL; +typedef ev_watcher_time *WT; + +#define ev_active(w) ((W)(w))->active +#define ev_at(w) ((WT)(w))->at + +#if EV_USE_REALTIME +/* sig_atomic_t is used to avoid per-thread variables or locking but still */ +/* giving it a reasonably high chance of working on typical architectures */ +static EV_ATOMIC_T have_realtime; /* did clock_gettime (CLOCK_REALTIME) work? */ +#endif + +#if EV_USE_MONOTONIC +static EV_ATOMIC_T have_monotonic; /* did clock_gettime (CLOCK_MONOTONIC) work? */ +#endif + +#ifndef EV_FD_TO_WIN32_HANDLE +# define EV_FD_TO_WIN32_HANDLE(fd) _get_osfhandle (fd) +#endif +#ifndef EV_WIN32_HANDLE_TO_FD +# define EV_WIN32_HANDLE_TO_FD(handle) _open_osfhandle (handle, 0) +#endif +#ifndef EV_WIN32_CLOSE_FD +# define EV_WIN32_CLOSE_FD(fd) close (fd) +#endif + +#ifdef _WIN32 +# include "ev_win32.c" +#endif + +/*****************************************************************************/ + +#if EV_USE_LINUXAIO +# include /* probably only needed for aio_context_t */ +#endif + +/* define a suitable floor function (only used by periodics atm) */ + +#if EV_USE_FLOOR +# include +# define ev_floor(v) floor (v) +#else + +#include + +/* a floor() replacement function, should be independent of ev_tstamp type */ +ecb_noinline +static ev_tstamp +ev_floor (ev_tstamp v) +{ + /* the choice of shift factor is not terribly important */ +#if FLT_RADIX != 2 /* assume FLT_RADIX == 10 */ + const ev_tstamp shift = sizeof (unsigned long) >= 8 ? 10000000000000000000. : 1000000000.; +#else + const ev_tstamp shift = sizeof (unsigned long) >= 8 ? 18446744073709551616. : 4294967296.; +#endif + + /* special treatment for negative arguments */ + if (ecb_expect_false (v < 0.)) + { + ev_tstamp f = -ev_floor (-v); + + return f - (f == v ? 0 : 1); + } + + /* argument too large for an unsigned long? then reduce it */ + if (ecb_expect_false (v >= shift)) + { + ev_tstamp f; + + if (v == v - 1.) + return v; /* very large numbers are assumed to be integer */ + + f = shift * ev_floor (v * (1. / shift)); + return f + ev_floor (v - f); + } + + /* fits into an unsigned long */ + return (unsigned long)v; +} + +#endif + +/*****************************************************************************/ + +#ifdef __linux +# include +#endif + +ecb_noinline ecb_cold +static unsigned int +ev_linux_version (void) +{ +#ifdef __linux + unsigned int v = 0; + struct utsname buf; + int i; + char *p = buf.release; + + if (uname (&buf)) + return 0; + + for (i = 3+1; --i; ) + { + unsigned int c = 0; + + for (;;) + { + if (*p >= '0' && *p <= '9') + c = c * 10 + *p++ - '0'; + else + { + p += *p == '.'; + break; + } + } + + v = (v << 8) | c; + } + + return v; +#else + return 0; +#endif +} + +/*****************************************************************************/ + +#if EV_AVOID_STDIO +ecb_noinline ecb_cold +static void +ev_printerr (const char *msg) +{ + write (STDERR_FILENO, msg, strlen (msg)); +} +#endif + +static void (*syserr_cb)(const char *msg) EV_NOEXCEPT; + +ecb_cold +void +ev_set_syserr_cb (void (*cb)(const char *msg) EV_NOEXCEPT) EV_NOEXCEPT +{ + syserr_cb = cb; +} + +ecb_noinline ecb_cold +static void +ev_syserr (const char *msg) +{ + if (!msg) + msg = "(libev) system error"; + + if (syserr_cb) + syserr_cb (msg); + else + { +#if EV_AVOID_STDIO + ev_printerr (msg); + ev_printerr (": "); + ev_printerr (strerror (errno)); + ev_printerr ("\n"); +#else + perror (msg); +#endif + abort (); + } +} + +static void * +ev_realloc_emul (void *ptr, size_t size) EV_NOEXCEPT +{ + /* some systems, notably openbsd and darwin, fail to properly + * implement realloc (x, 0) (as required by both ansi c-89 and + * the single unix specification, so work around them here. + * recently, also (at least) fedora and debian started breaking it, + * despite documenting it otherwise. + */ + + if (size) + return realloc (ptr, size); + + free (ptr); + return 0; +} + +static void *(*alloc)(void *ptr, size_t size) EV_NOEXCEPT = ev_realloc_emul; + +ecb_cold +void +ev_set_allocator (void *(*cb)(void *ptr, size_t size) EV_NOEXCEPT) EV_NOEXCEPT +{ + alloc = cb; +} + +inline_speed void * +ev_realloc (void *ptr, size_t size) +{ + ptr = alloc (ptr, size); + + if (!ptr && size) + { +#if EV_AVOID_STDIO + ev_printerr ("(libev) memory allocation failed, aborting.\n"); +#else + fprintf (stderr, "(libev) cannot allocate %ld bytes, aborting.", size); +#endif + abort (); + } + + return ptr; +} + +#define ev_malloc(size) ev_realloc (0, (size)) +#define ev_free(ptr) ev_realloc ((ptr), 0) + +/*****************************************************************************/ + +/* set in reify when reification needed */ +#define EV_ANFD_REIFY 1 + +/* file descriptor info structure */ +typedef struct +{ + WL head; + unsigned char events; /* the events watched for */ + unsigned char reify; /* flag set when this ANFD needs reification (EV_ANFD_REIFY, EV__IOFDSET) */ + unsigned char emask; /* some backends store the actual kernel mask in here */ + unsigned char eflags; /* flags field for use by backends */ +#if EV_USE_EPOLL + unsigned int egen; /* generation counter to counter epoll bugs */ +#endif +#if EV_SELECT_IS_WINSOCKET || EV_USE_IOCP + SOCKET handle; +#endif +#if EV_USE_IOCP + OVERLAPPED or, ow; +#endif +} ANFD; + +/* stores the pending event set for a given watcher */ +typedef struct +{ + W w; + int events; /* the pending event set for the given watcher */ +} ANPENDING; + +#if EV_USE_INOTIFY +/* hash table entry per inotify-id */ +typedef struct +{ + WL head; +} ANFS; +#endif + +/* Heap Entry */ +#if EV_HEAP_CACHE_AT + /* a heap element */ + typedef struct { + ev_tstamp at; + WT w; + } ANHE; + + #define ANHE_w(he) (he).w /* access watcher, read-write */ + #define ANHE_at(he) (he).at /* access cached at, read-only */ + #define ANHE_at_cache(he) (he).at = (he).w->at /* update at from watcher */ +#else + /* a heap element */ + typedef WT ANHE; + + #define ANHE_w(he) (he) + #define ANHE_at(he) (he)->at + #define ANHE_at_cache(he) +#endif + +#if EV_MULTIPLICITY + + struct ev_loop + { + ev_tstamp ev_rt_now; + #define ev_rt_now ((loop)->ev_rt_now) + #define VAR(name,decl) decl; + #include "ev_vars.h" + #undef VAR + }; + #include "ev_wrap.h" + + static struct ev_loop default_loop_struct; + EV_API_DECL struct ev_loop *ev_default_loop_ptr = 0; /* needs to be initialised to make it a definition despite extern */ + +#else + + EV_API_DECL ev_tstamp ev_rt_now = EV_TS_CONST (0.); /* needs to be initialised to make it a definition despite extern */ + #define VAR(name,decl) static decl; + #include "ev_vars.h" + #undef VAR + + static int ev_default_loop_ptr; + +#endif + +#if EV_FEATURE_API +# define EV_RELEASE_CB if (ecb_expect_false (release_cb)) release_cb (EV_A) +# define EV_ACQUIRE_CB if (ecb_expect_false (acquire_cb)) acquire_cb (EV_A) +# define EV_INVOKE_PENDING invoke_cb (EV_A) +#else +# define EV_RELEASE_CB (void)0 +# define EV_ACQUIRE_CB (void)0 +# define EV_INVOKE_PENDING ev_invoke_pending (EV_A) +#endif + +#define EVBREAK_RECURSE 0x80 + +/*****************************************************************************/ + +#ifndef EV_HAVE_EV_TIME +ev_tstamp +ev_time (void) EV_NOEXCEPT +{ +#if EV_USE_REALTIME + if (ecb_expect_true (have_realtime)) + { + struct timespec ts; + clock_gettime (CLOCK_REALTIME, &ts); + return EV_TS_GET (ts); + } +#endif + + { + struct timeval tv; + gettimeofday (&tv, 0); + return EV_TV_GET (tv); + } +} +#endif + +inline_size ev_tstamp +get_clock (void) +{ +#if EV_USE_MONOTONIC + if (ecb_expect_true (have_monotonic)) + { + struct timespec ts; + clock_gettime (CLOCK_MONOTONIC, &ts); + return EV_TS_GET (ts); + } +#endif + + return ev_time (); +} + +#if EV_MULTIPLICITY +ev_tstamp +ev_now (EV_P) EV_NOEXCEPT +{ + return ev_rt_now; +} +#endif + +void +ev_sleep (ev_tstamp delay) EV_NOEXCEPT +{ + if (delay > EV_TS_CONST (0.)) + { +#if EV_USE_NANOSLEEP + struct timespec ts; + + EV_TS_SET (ts, delay); + nanosleep (&ts, 0); +#elif defined _WIN32 + /* maybe this should round up, as ms is very low resolution */ + /* compared to select (µs) or nanosleep (ns) */ + Sleep ((unsigned long)(EV_TS_TO_MSEC (delay))); +#else + struct timeval tv; + + /* here we rely on sys/time.h + sys/types.h + unistd.h providing select */ + /* something not guaranteed by newer posix versions, but guaranteed */ + /* by older ones */ + EV_TV_SET (tv, delay); + select (0, 0, 0, 0, &tv); +#endif + } +} + +/*****************************************************************************/ + +#define MALLOC_ROUND 4096 /* prefer to allocate in chunks of this size, must be 2**n and >> 4 longs */ + +/* find a suitable new size for the given array, */ +/* hopefully by rounding to a nice-to-malloc size */ +inline_size int +array_nextsize (int elem, int cur, int cnt) +{ + int ncur = cur + 1; + + do + ncur <<= 1; + while (cnt > ncur); + + /* if size is large, round to MALLOC_ROUND - 4 * longs to accommodate malloc overhead */ + if (elem * ncur > MALLOC_ROUND - sizeof (void *) * 4) + { + ncur *= elem; + ncur = (ncur + elem + (MALLOC_ROUND - 1) + sizeof (void *) * 4) & ~(MALLOC_ROUND - 1); + ncur = ncur - sizeof (void *) * 4; + ncur /= elem; + } + + return ncur; +} + +ecb_noinline ecb_cold +static void * +array_realloc (int elem, void *base, int *cur, int cnt) +{ + *cur = array_nextsize (elem, *cur, cnt); + return ev_realloc (base, elem * *cur); +} + +#define array_needsize_noinit(base,offset,count) + +#define array_needsize_zerofill(base,offset,count) \ + memset ((void *)(base + offset), 0, sizeof (*(base)) * (count)) + +#define array_needsize(type,base,cur,cnt,init) \ + if (ecb_expect_false ((cnt) > (cur))) \ + { \ + ecb_unused int ocur_ = (cur); \ + (base) = (type *)array_realloc \ + (sizeof (type), (base), &(cur), (cnt)); \ + init ((base), ocur_, ((cur) - ocur_)); \ + } + +#if 0 +#define array_slim(type,stem) \ + if (stem ## max < array_roundsize (stem ## cnt >> 2)) \ + { \ + stem ## max = array_roundsize (stem ## cnt >> 1); \ + base = (type *)ev_realloc (base, sizeof (type) * (stem ## max));\ + fprintf (stderr, "slimmed down " # stem " to %d\n", stem ## max);/*D*/\ + } +#endif + +#define array_free(stem, idx) \ + ev_free (stem ## s idx); stem ## cnt idx = stem ## max idx = 0; stem ## s idx = 0 + +/*****************************************************************************/ + +/* dummy callback for pending events */ +ecb_noinline +static void +pendingcb (EV_P_ ev_prepare *w, int revents) +{ +} + +ecb_noinline +void +ev_feed_event (EV_P_ void *w, int revents) EV_NOEXCEPT +{ + W w_ = (W)w; + int pri = ABSPRI (w_); + + if (ecb_expect_false (w_->pending)) + pendings [pri][w_->pending - 1].events |= revents; + else + { + w_->pending = ++pendingcnt [pri]; + array_needsize (ANPENDING, pendings [pri], pendingmax [pri], w_->pending, array_needsize_noinit); + pendings [pri][w_->pending - 1].w = w_; + pendings [pri][w_->pending - 1].events = revents; + } + + pendingpri = NUMPRI - 1; +} + +inline_speed void +feed_reverse (EV_P_ W w) +{ + array_needsize (W, rfeeds, rfeedmax, rfeedcnt + 1, array_needsize_noinit); + rfeeds [rfeedcnt++] = w; +} + +inline_size void +feed_reverse_done (EV_P_ int revents) +{ + do + ev_feed_event (EV_A_ rfeeds [--rfeedcnt], revents); + while (rfeedcnt); +} + +inline_speed void +queue_events (EV_P_ W *events, int eventcnt, int type) +{ + int i; + + for (i = 0; i < eventcnt; ++i) + ev_feed_event (EV_A_ events [i], type); +} + +/*****************************************************************************/ + +inline_speed void +fd_event_nocheck (EV_P_ int fd, int revents) +{ + ANFD *anfd = anfds + fd; + ev_io *w; + + for (w = (ev_io *)anfd->head; w; w = (ev_io *)((WL)w)->next) + { + int ev = w->events & revents; + + if (ev) + ev_feed_event (EV_A_ (W)w, ev); + } +} + +/* do not submit kernel events for fds that have reify set */ +/* because that means they changed while we were polling for new events */ +inline_speed void +fd_event (EV_P_ int fd, int revents) +{ + ANFD *anfd = anfds + fd; + + if (ecb_expect_true (!anfd->reify)) + fd_event_nocheck (EV_A_ fd, revents); +} + +void +ev_feed_fd_event (EV_P_ int fd, int revents) EV_NOEXCEPT +{ + if (fd >= 0 && fd < anfdmax) + fd_event_nocheck (EV_A_ fd, revents); +} + +/* make sure the external fd watch events are in-sync */ +/* with the kernel/libev internal state */ +inline_size void +fd_reify (EV_P) +{ + int i; + + /* most backends do not modify the fdchanges list in backend_modfiy. + * except io_uring, which has fixed-size buffers which might force us + * to handle events in backend_modify, causing fdchanges to be amended, + * which could result in an endless loop. + * to avoid this, we do not dynamically handle fds that were added + * during fd_reify. that means that for those backends, fdchangecnt + * might be non-zero during poll, which must cause them to not block. + * to not put too much of a burden on other backends, this detail + * needs to be handled in the backend. + */ + int changecnt = fdchangecnt; + +#if EV_SELECT_IS_WINSOCKET || EV_USE_IOCP + for (i = 0; i < changecnt; ++i) + { + int fd = fdchanges [i]; + ANFD *anfd = anfds + fd; + + if (anfd->reify & EV__IOFDSET && anfd->head) + { + SOCKET handle = EV_FD_TO_WIN32_HANDLE (fd); + + if (handle != anfd->handle) + { + unsigned long arg; + + assert (("libev: only socket fds supported in this configuration", ioctlsocket (handle, FIONREAD, &arg) == 0)); + + /* handle changed, but fd didn't - we need to do it in two steps */ + backend_modify (EV_A_ fd, anfd->events, 0); + anfd->events = 0; + anfd->handle = handle; + } + } + } +#endif + + for (i = 0; i < changecnt; ++i) + { + int fd = fdchanges [i]; + ANFD *anfd = anfds + fd; + ev_io *w; + + unsigned char o_events = anfd->events; + unsigned char o_reify = anfd->reify; + + anfd->reify = 0; + + /*if (ecb_expect_true (o_reify & EV_ANFD_REIFY)) probably a deoptimisation */ + { + anfd->events = 0; + + for (w = (ev_io *)anfd->head; w; w = (ev_io *)((WL)w)->next) + anfd->events |= (unsigned char)w->events; + + if (o_events != anfd->events) + o_reify = EV__IOFDSET; /* actually |= */ + } + + if (o_reify & EV__IOFDSET) + backend_modify (EV_A_ fd, o_events, anfd->events); + } + + /* normally, fdchangecnt hasn't changed. if it has, then new fds have been added. + * this is a rare case (see beginning comment in this function), so we copy them to the + * front and hope the backend handles this case. + */ + if (ecb_expect_false (fdchangecnt != changecnt)) + memmove (fdchanges, fdchanges + changecnt, (fdchangecnt - changecnt) * sizeof (*fdchanges)); + + fdchangecnt -= changecnt; +} + +/* something about the given fd changed */ +inline_size +void +fd_change (EV_P_ int fd, int flags) +{ + unsigned char reify = anfds [fd].reify; + anfds [fd].reify = reify | flags; + + if (ecb_expect_true (!reify)) + { + ++fdchangecnt; + array_needsize (int, fdchanges, fdchangemax, fdchangecnt, array_needsize_noinit); + fdchanges [fdchangecnt - 1] = fd; + } +} + +/* the given fd is invalid/unusable, so make sure it doesn't hurt us anymore */ +inline_speed ecb_cold void +fd_kill (EV_P_ int fd) +{ + ev_io *w; + + while ((w = (ev_io *)anfds [fd].head)) + { + ev_io_stop (EV_A_ w); + ev_feed_event (EV_A_ (W)w, EV_ERROR | EV_READ | EV_WRITE); + } +} + +/* check whether the given fd is actually valid, for error recovery */ +inline_size ecb_cold int +fd_valid (int fd) +{ +#ifdef _WIN32 + return EV_FD_TO_WIN32_HANDLE (fd) != -1; +#else + return fcntl (fd, F_GETFD) != -1; +#endif +} + +/* called on EBADF to verify fds */ +ecb_noinline ecb_cold +static void +fd_ebadf (EV_P) +{ + int fd; + + for (fd = 0; fd < anfdmax; ++fd) + if (anfds [fd].events) + if (!fd_valid (fd) && errno == EBADF) + fd_kill (EV_A_ fd); +} + +/* called on ENOMEM in select/poll to kill some fds and retry */ +ecb_noinline ecb_cold +static void +fd_enomem (EV_P) +{ + int fd; + + for (fd = anfdmax; fd--; ) + if (anfds [fd].events) + { + fd_kill (EV_A_ fd); + break; + } +} + +/* usually called after fork if backend needs to re-arm all fds from scratch */ +ecb_noinline +static void +fd_rearm_all (EV_P) +{ + int fd; + + for (fd = 0; fd < anfdmax; ++fd) + if (anfds [fd].events) + { + anfds [fd].events = 0; + anfds [fd].emask = 0; + fd_change (EV_A_ fd, EV__IOFDSET | EV_ANFD_REIFY); + } +} + +/* used to prepare libev internal fd's */ +/* this is not fork-safe */ +inline_speed void +fd_intern (int fd) +{ +#ifdef _WIN32 + unsigned long arg = 1; + ioctlsocket (EV_FD_TO_WIN32_HANDLE (fd), FIONBIO, &arg); +#else + fcntl (fd, F_SETFD, FD_CLOEXEC); + fcntl (fd, F_SETFL, O_NONBLOCK); +#endif +} + +/*****************************************************************************/ + +/* + * the heap functions want a real array index. array index 0 is guaranteed to not + * be in-use at any time. the first heap entry is at array [HEAP0]. DHEAP gives + * the branching factor of the d-tree. + */ + +/* + * at the moment we allow libev the luxury of two heaps, + * a small-code-size 2-heap one and a ~1.5kb larger 4-heap + * which is more cache-efficient. + * the difference is about 5% with 50000+ watchers. + */ +#if EV_USE_4HEAP + +#define DHEAP 4 +#define HEAP0 (DHEAP - 1) /* index of first element in heap */ +#define HPARENT(k) ((((k) - HEAP0 - 1) / DHEAP) + HEAP0) +#define UPHEAP_DONE(p,k) ((p) == (k)) + +/* away from the root */ +inline_speed void +downheap (ANHE *heap, int N, int k) +{ + ANHE he = heap [k]; + ANHE *E = heap + N + HEAP0; + + for (;;) + { + ev_tstamp minat; + ANHE *minpos; + ANHE *pos = heap + DHEAP * (k - HEAP0) + HEAP0 + 1; + + /* find minimum child */ + if (ecb_expect_true (pos + DHEAP - 1 < E)) + { + /* fast path */ (minpos = pos + 0), (minat = ANHE_at (*minpos)); + if ( minat > ANHE_at (pos [1])) (minpos = pos + 1), (minat = ANHE_at (*minpos)); + if ( minat > ANHE_at (pos [2])) (minpos = pos + 2), (minat = ANHE_at (*minpos)); + if ( minat > ANHE_at (pos [3])) (minpos = pos + 3), (minat = ANHE_at (*minpos)); + } + else if (pos < E) + { + /* slow path */ (minpos = pos + 0), (minat = ANHE_at (*minpos)); + if (pos + 1 < E && minat > ANHE_at (pos [1])) (minpos = pos + 1), (minat = ANHE_at (*minpos)); + if (pos + 2 < E && minat > ANHE_at (pos [2])) (minpos = pos + 2), (minat = ANHE_at (*minpos)); + if (pos + 3 < E && minat > ANHE_at (pos [3])) (minpos = pos + 3), (minat = ANHE_at (*minpos)); + } + else + break; + + if (ANHE_at (he) <= minat) + break; + + heap [k] = *minpos; + ev_active (ANHE_w (*minpos)) = k; + + k = minpos - heap; + } + + heap [k] = he; + ev_active (ANHE_w (he)) = k; +} + +#else /* not 4HEAP */ + +#define HEAP0 1 +#define HPARENT(k) ((k) >> 1) +#define UPHEAP_DONE(p,k) (!(p)) + +/* away from the root */ +inline_speed void +downheap (ANHE *heap, int N, int k) +{ + ANHE he = heap [k]; + + for (;;) + { + int c = k << 1; + + if (c >= N + HEAP0) + break; + + c += c + 1 < N + HEAP0 && ANHE_at (heap [c]) > ANHE_at (heap [c + 1]) + ? 1 : 0; + + if (ANHE_at (he) <= ANHE_at (heap [c])) + break; + + heap [k] = heap [c]; + ev_active (ANHE_w (heap [k])) = k; + + k = c; + } + + heap [k] = he; + ev_active (ANHE_w (he)) = k; +} +#endif + +/* towards the root */ +inline_speed void +upheap (ANHE *heap, int k) +{ + ANHE he = heap [k]; + + for (;;) + { + int p = HPARENT (k); + + if (UPHEAP_DONE (p, k) || ANHE_at (heap [p]) <= ANHE_at (he)) + break; + + heap [k] = heap [p]; + ev_active (ANHE_w (heap [k])) = k; + k = p; + } + + heap [k] = he; + ev_active (ANHE_w (he)) = k; +} + +/* move an element suitably so it is in a correct place */ +inline_size void +adjustheap (ANHE *heap, int N, int k) +{ + if (k > HEAP0 && ANHE_at (heap [k]) <= ANHE_at (heap [HPARENT (k)])) + upheap (heap, k); + else + downheap (heap, N, k); +} + +/* rebuild the heap: this function is used only once and executed rarely */ +inline_size void +reheap (ANHE *heap, int N) +{ + int i; + + /* we don't use floyds algorithm, upheap is simpler and is more cache-efficient */ + /* also, this is easy to implement and correct for both 2-heaps and 4-heaps */ + for (i = 0; i < N; ++i) + upheap (heap, i + HEAP0); +} + +/*****************************************************************************/ + +/* associate signal watchers to a signal */ +typedef struct +{ + EV_ATOMIC_T pending; +#if EV_MULTIPLICITY + EV_P; +#endif + WL head; +} ANSIG; + +static ANSIG signals [EV_NSIG - 1]; + +/*****************************************************************************/ + +#if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE + +ecb_noinline ecb_cold +static void +evpipe_init (EV_P) +{ + if (!ev_is_active (&pipe_w)) + { + int fds [2]; + +# if EV_USE_EVENTFD + fds [0] = -1; + fds [1] = eventfd (0, EFD_NONBLOCK | EFD_CLOEXEC); + if (fds [1] < 0 && errno == EINVAL) + fds [1] = eventfd (0, 0); + + if (fds [1] < 0) +# endif + { + while (pipe (fds)) + ev_syserr ("(libev) error creating signal/async pipe"); + + fd_intern (fds [0]); + } + + evpipe [0] = fds [0]; + + if (evpipe [1] < 0) + evpipe [1] = fds [1]; /* first call, set write fd */ + else + { + /* on subsequent calls, do not change evpipe [1] */ + /* so that evpipe_write can always rely on its value. */ + /* this branch does not do anything sensible on windows, */ + /* so must not be executed on windows */ + + dup2 (fds [1], evpipe [1]); + close (fds [1]); + } + + fd_intern (evpipe [1]); + + ev_io_set (&pipe_w, evpipe [0] < 0 ? evpipe [1] : evpipe [0], EV_READ); + ev_io_start (EV_A_ &pipe_w); + ev_unref (EV_A); /* watcher should not keep loop alive */ + } +} + +inline_speed void +evpipe_write (EV_P_ EV_ATOMIC_T *flag) +{ + ECB_MEMORY_FENCE; /* push out the write before this function was called, acquire flag */ + + if (ecb_expect_true (*flag)) + return; + + *flag = 1; + ECB_MEMORY_FENCE_RELEASE; /* make sure flag is visible before the wakeup */ + + pipe_write_skipped = 1; + + ECB_MEMORY_FENCE; /* make sure pipe_write_skipped is visible before we check pipe_write_wanted */ + + if (pipe_write_wanted) + { + int old_errno; + + pipe_write_skipped = 0; + ECB_MEMORY_FENCE_RELEASE; + + old_errno = errno; /* save errno because write will clobber it */ + +#if EV_USE_EVENTFD + if (evpipe [0] < 0) + { + uint64_t counter = 1; + write (evpipe [1], &counter, sizeof (uint64_t)); + } + else +#endif + { +#ifdef _WIN32 + WSABUF buf; + DWORD sent; + buf.buf = (char *)&buf; + buf.len = 1; + WSASend (EV_FD_TO_WIN32_HANDLE (evpipe [1]), &buf, 1, &sent, 0, 0, 0); +#else + write (evpipe [1], &(evpipe [1]), 1); +#endif + } + + errno = old_errno; + } +} + +/* called whenever the libev signal pipe */ +/* got some events (signal, async) */ +static void +pipecb (EV_P_ ev_io *iow, int revents) +{ + int i; + + if (revents & EV_READ) + { +#if EV_USE_EVENTFD + if (evpipe [0] < 0) + { + uint64_t counter; + read (evpipe [1], &counter, sizeof (uint64_t)); + } + else +#endif + { + char dummy[4]; +#ifdef _WIN32 + WSABUF buf; + DWORD recvd; + DWORD flags = 0; + buf.buf = dummy; + buf.len = sizeof (dummy); + WSARecv (EV_FD_TO_WIN32_HANDLE (evpipe [0]), &buf, 1, &recvd, &flags, 0, 0); +#else + read (evpipe [0], &dummy, sizeof (dummy)); +#endif + } + } + + pipe_write_skipped = 0; + + ECB_MEMORY_FENCE; /* push out skipped, acquire flags */ + +#if EV_SIGNAL_ENABLE + if (sig_pending) + { + sig_pending = 0; + + ECB_MEMORY_FENCE; + + for (i = EV_NSIG - 1; i--; ) + if (ecb_expect_false (signals [i].pending)) + ev_feed_signal_event (EV_A_ i + 1); + } +#endif + +#if EV_ASYNC_ENABLE + if (async_pending) + { + async_pending = 0; + + ECB_MEMORY_FENCE; + + for (i = asynccnt; i--; ) + if (asyncs [i]->sent) + { + asyncs [i]->sent = 0; + ECB_MEMORY_FENCE_RELEASE; + ev_feed_event (EV_A_ asyncs [i], EV_ASYNC); + } + } +#endif +} + +/*****************************************************************************/ + +void +ev_feed_signal (int signum) EV_NOEXCEPT +{ +#if EV_MULTIPLICITY + EV_P; + ECB_MEMORY_FENCE_ACQUIRE; + EV_A = signals [signum - 1].loop; + + if (!EV_A) + return; +#endif + + signals [signum - 1].pending = 1; + evpipe_write (EV_A_ &sig_pending); +} + +static void +ev_sighandler (int signum) +{ +#ifdef _WIN32 + signal (signum, ev_sighandler); +#endif + + ev_feed_signal (signum); +} + +ecb_noinline +void +ev_feed_signal_event (EV_P_ int signum) EV_NOEXCEPT +{ + WL w; + + if (ecb_expect_false (signum <= 0 || signum >= EV_NSIG)) + return; + + --signum; + +#if EV_MULTIPLICITY + /* it is permissible to try to feed a signal to the wrong loop */ + /* or, likely more useful, feeding a signal nobody is waiting for */ + + if (ecb_expect_false (signals [signum].loop != EV_A)) + return; +#endif + + signals [signum].pending = 0; + ECB_MEMORY_FENCE_RELEASE; + + for (w = signals [signum].head; w; w = w->next) + ev_feed_event (EV_A_ (W)w, EV_SIGNAL); +} + +#if EV_USE_SIGNALFD +static void +sigfdcb (EV_P_ ev_io *iow, int revents) +{ + struct signalfd_siginfo si[2], *sip; /* these structs are big */ + + for (;;) + { + ssize_t res = read (sigfd, si, sizeof (si)); + + /* not ISO-C, as res might be -1, but works with SuS */ + for (sip = si; (char *)sip < (char *)si + res; ++sip) + ev_feed_signal_event (EV_A_ sip->ssi_signo); + + if (res < (ssize_t)sizeof (si)) + break; + } +} +#endif + +#endif + +/*****************************************************************************/ + +#if EV_CHILD_ENABLE +static WL childs [EV_PID_HASHSIZE]; + +static ev_signal childev; + +#ifndef WIFCONTINUED +# define WIFCONTINUED(status) 0 +#endif + +/* handle a single child status event */ +inline_speed void +child_reap (EV_P_ int chain, int pid, int status) +{ + ev_child *w; + int traced = WIFSTOPPED (status) || WIFCONTINUED (status); + + for (w = (ev_child *)childs [chain & ((EV_PID_HASHSIZE) - 1)]; w; w = (ev_child *)((WL)w)->next) + { + if ((w->pid == pid || !w->pid) + && (!traced || (w->flags & 1))) + { + ev_set_priority (w, EV_MAXPRI); /* need to do it *now*, this *must* be the same prio as the signal watcher itself */ + w->rpid = pid; + w->rstatus = status; + ev_feed_event (EV_A_ (W)w, EV_CHILD); + } + } +} + +#ifndef WCONTINUED +# define WCONTINUED 0 +#endif + +/* called on sigchld etc., calls waitpid */ +static void +childcb (EV_P_ ev_signal *sw, int revents) +{ + int pid, status; + + /* some systems define WCONTINUED but then fail to support it (linux 2.4) */ + if (0 >= (pid = waitpid (-1, &status, WNOHANG | WUNTRACED | WCONTINUED))) + if (!WCONTINUED + || errno != EINVAL + || 0 >= (pid = waitpid (-1, &status, WNOHANG | WUNTRACED))) + return; + + /* make sure we are called again until all children have been reaped */ + /* we need to do it this way so that the callback gets called before we continue */ + ev_feed_event (EV_A_ (W)sw, EV_SIGNAL); + + child_reap (EV_A_ pid, pid, status); + if ((EV_PID_HASHSIZE) > 1) + child_reap (EV_A_ 0, pid, status); /* this might trigger a watcher twice, but feed_event catches that */ +} + +#endif + +/*****************************************************************************/ + +#if EV_USE_TIMERFD + +static void periodics_reschedule (EV_P); + +static void +timerfdcb (EV_P_ ev_io *iow, int revents) +{ + struct itimerspec its = { 0 }; + + its.it_value.tv_sec = ev_rt_now + (int)MAX_BLOCKTIME2; + timerfd_settime (timerfd, TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, &its, 0); + + ev_rt_now = ev_time (); + /* periodics_reschedule only needs ev_rt_now */ + /* but maybe in the future we want the full treatment. */ + /* + now_floor = EV_TS_CONST (0.); + time_update (EV_A_ EV_TSTAMP_HUGE); + */ +#if EV_PERIODIC_ENABLE + periodics_reschedule (EV_A); +#endif +} + +ecb_noinline ecb_cold +static void +evtimerfd_init (EV_P) +{ + if (!ev_is_active (&timerfd_w)) + { + timerfd = timerfd_create (CLOCK_REALTIME, TFD_NONBLOCK | TFD_CLOEXEC); + + if (timerfd >= 0) + { + fd_intern (timerfd); /* just to be sure */ + + ev_io_init (&timerfd_w, timerfdcb, timerfd, EV_READ); + ev_set_priority (&timerfd_w, EV_MINPRI); + ev_io_start (EV_A_ &timerfd_w); + ev_unref (EV_A); /* watcher should not keep loop alive */ + + /* (re-) arm timer */ + timerfdcb (EV_A_ 0, 0); + } + } +} + +#endif + +/*****************************************************************************/ + +#if EV_USE_IOCP +# include "ev_iocp.c" +#endif +#if EV_USE_PORT +# include "ev_port.c" +#endif +#if EV_USE_KQUEUE +# include "ev_kqueue.c" +#endif +#if EV_USE_EPOLL +# include "ev_epoll.c" +#endif +#if EV_USE_LINUXAIO +# include "ev_linuxaio.c" +#endif +#if EV_USE_IOURING +# include "ev_iouring.c" +#endif +#if EV_USE_POLL +# include "ev_poll.c" +#endif +#if EV_USE_SELECT +# include "ev_select.c" +#endif + +ecb_cold int +ev_version_major (void) EV_NOEXCEPT +{ + return EV_VERSION_MAJOR; +} + +ecb_cold int +ev_version_minor (void) EV_NOEXCEPT +{ + return EV_VERSION_MINOR; +} + +/* return true if we are running with elevated privileges and should ignore env variables */ +inline_size ecb_cold int +enable_secure (void) +{ +#ifdef _WIN32 + return 0; +#else + return getuid () != geteuid () + || getgid () != getegid (); +#endif +} + +ecb_cold +unsigned int +ev_supported_backends (void) EV_NOEXCEPT +{ + unsigned int flags = 0; + + if (EV_USE_PORT ) flags |= EVBACKEND_PORT; + if (EV_USE_KQUEUE ) flags |= EVBACKEND_KQUEUE; + if (EV_USE_EPOLL ) flags |= EVBACKEND_EPOLL; + if (EV_USE_LINUXAIO && ev_linux_version () >= 0x041300) flags |= EVBACKEND_LINUXAIO; /* 4.19+ */ + if (EV_USE_IOURING && ev_linux_version () >= 0x050601 ) flags |= EVBACKEND_IOURING; /* 5.6.1+ */ + if (EV_USE_POLL ) flags |= EVBACKEND_POLL; + if (EV_USE_SELECT ) flags |= EVBACKEND_SELECT; + + return flags; +} + +ecb_cold +unsigned int +ev_recommended_backends (void) EV_NOEXCEPT +{ + unsigned int flags = ev_supported_backends (); + +/* apple has a poor track record but post 10.12.2 it seems to work sufficiently well */ +#if defined(__APPLE__) && (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_14) + /* only select works correctly on that "unix-certified" platform */ + flags &= ~EVBACKEND_KQUEUE; /* horribly broken, even for sockets */ + flags &= ~EVBACKEND_POLL; /* poll is based on kqueue from 10.5 onwards */ +#endif + +#if !defined(__NetBSD__) && !defined(__APPLE__) + /* kqueue is borked on everything but netbsd and osx >= 10.12.2 apparently */ + /* it usually doesn't work correctly on anything but sockets and pipes */ + flags &= ~EVBACKEND_KQUEUE; +#endif + +#ifdef __FreeBSD__ + flags &= ~EVBACKEND_POLL; /* poll return value is unusable (http://forums.freebsd.org/archive/index.php/t-10270.html) */ +#endif + +#ifdef __linux__ + /* NOTE: linuxaio is very experimental, never recommend */ + flags &= ~EVBACKEND_LINUXAIO; + + /* NOTE: io_uring is super experimental, never recommend */ + flags &= ~EVBACKEND_IOURING; +#endif + + return flags; +} + +ecb_cold +unsigned int +ev_embeddable_backends (void) EV_NOEXCEPT +{ + int flags = EVBACKEND_EPOLL | EVBACKEND_KQUEUE | EVBACKEND_PORT | EVBACKEND_IOURING; + + /* epoll embeddability broken on all linux versions up to at least 2.6.23 */ + if (ev_linux_version () < 0x020620) /* disable it on linux < 2.6.32 */ + flags &= ~EVBACKEND_EPOLL; + + /* EVBACKEND_LINUXAIO is theoretically embeddable, but suffers from a performance overhead */ + + return flags; +} + +unsigned int +ev_backend (EV_P) EV_NOEXCEPT +{ + return backend; +} + +#if EV_FEATURE_API +unsigned int +ev_iteration (EV_P) EV_NOEXCEPT +{ + return loop_count; +} + +unsigned int +ev_depth (EV_P) EV_NOEXCEPT +{ + return loop_depth; +} + +void +ev_set_io_collect_interval (EV_P_ ev_tstamp interval) EV_NOEXCEPT +{ + io_blocktime = interval; +} + +void +ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval) EV_NOEXCEPT +{ + timeout_blocktime = interval; +} + +void +ev_set_userdata (EV_P_ void *data) EV_NOEXCEPT +{ + userdata = data; +} + +void * +ev_userdata (EV_P) EV_NOEXCEPT +{ + return userdata; +} + +void +ev_set_invoke_pending_cb (EV_P_ ev_loop_callback invoke_pending_cb) EV_NOEXCEPT +{ + invoke_cb = invoke_pending_cb; +} + +void +ev_set_loop_release_cb (EV_P_ void (*release)(EV_P) EV_NOEXCEPT, void (*acquire)(EV_P) EV_NOEXCEPT) EV_NOEXCEPT +{ + release_cb = release; + acquire_cb = acquire; +} +#endif + +/* initialise a loop structure, must be zero-initialised */ +ecb_noinline ecb_cold +static void +loop_init (EV_P_ unsigned int flags) EV_NOEXCEPT +{ + if (!backend) + { + origflags = flags; + +#if EV_USE_REALTIME + if (!have_realtime) + { + struct timespec ts; + + if (!clock_gettime (CLOCK_REALTIME, &ts)) + have_realtime = 1; + } +#endif + +#if EV_USE_MONOTONIC + if (!have_monotonic) + { + struct timespec ts; + + if (!clock_gettime (CLOCK_MONOTONIC, &ts)) + have_monotonic = 1; + } +#endif + + /* pid check not overridable via env */ +#ifndef _WIN32 + if (flags & EVFLAG_FORKCHECK) + curpid = getpid (); +#endif + + if (!(flags & EVFLAG_NOENV) + && !enable_secure () + && getenv ("LIBEV_FLAGS")) + flags = atoi (getenv ("LIBEV_FLAGS")); + + ev_rt_now = ev_time (); + mn_now = get_clock (); + now_floor = mn_now; + rtmn_diff = ev_rt_now - mn_now; +#if EV_FEATURE_API + invoke_cb = ev_invoke_pending; +#endif + + io_blocktime = 0.; + timeout_blocktime = 0.; + backend = 0; + backend_fd = -1; + sig_pending = 0; +#if EV_ASYNC_ENABLE + async_pending = 0; +#endif + pipe_write_skipped = 0; + pipe_write_wanted = 0; + evpipe [0] = -1; + evpipe [1] = -1; +#if EV_USE_INOTIFY + fs_fd = flags & EVFLAG_NOINOTIFY ? -1 : -2; +#endif +#if EV_USE_SIGNALFD + sigfd = flags & EVFLAG_SIGNALFD ? -2 : -1; +#endif +#if EV_USE_TIMERFD + timerfd = flags & EVFLAG_NOTIMERFD ? -1 : -2; +#endif + + if (!(flags & EVBACKEND_MASK)) + flags |= ev_recommended_backends (); + +#if EV_USE_IOCP + if (!backend && (flags & EVBACKEND_IOCP )) backend = iocp_init (EV_A_ flags); +#endif +#if EV_USE_PORT + if (!backend && (flags & EVBACKEND_PORT )) backend = port_init (EV_A_ flags); +#endif +#if EV_USE_KQUEUE + if (!backend && (flags & EVBACKEND_KQUEUE )) backend = kqueue_init (EV_A_ flags); +#endif +#if EV_USE_IOURING + if (!backend && (flags & EVBACKEND_IOURING )) backend = iouring_init (EV_A_ flags); +#endif +#if EV_USE_LINUXAIO + if (!backend && (flags & EVBACKEND_LINUXAIO)) backend = linuxaio_init (EV_A_ flags); +#endif +#if EV_USE_EPOLL + if (!backend && (flags & EVBACKEND_EPOLL )) backend = epoll_init (EV_A_ flags); +#endif +#if EV_USE_POLL + if (!backend && (flags & EVBACKEND_POLL )) backend = poll_init (EV_A_ flags); +#endif +#if EV_USE_SELECT + if (!backend && (flags & EVBACKEND_SELECT )) backend = select_init (EV_A_ flags); +#endif + + ev_prepare_init (&pending_w, pendingcb); + +#if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE + ev_init (&pipe_w, pipecb); + ev_set_priority (&pipe_w, EV_MAXPRI); +#endif + } +} + +/* free up a loop structure */ +ecb_cold +void +ev_loop_destroy (EV_P) +{ + int i; + +#if EV_MULTIPLICITY + /* mimic free (0) */ + if (!EV_A) + return; +#endif + +#if EV_CLEANUP_ENABLE + /* queue cleanup watchers (and execute them) */ + if (ecb_expect_false (cleanupcnt)) + { + queue_events (EV_A_ (W *)cleanups, cleanupcnt, EV_CLEANUP); + EV_INVOKE_PENDING; + } +#endif + +#if EV_CHILD_ENABLE + if (ev_is_default_loop (EV_A) && ev_is_active (&childev)) + { + ev_ref (EV_A); /* child watcher */ + ev_signal_stop (EV_A_ &childev); + } +#endif + + if (ev_is_active (&pipe_w)) + { + /*ev_ref (EV_A);*/ + /*ev_io_stop (EV_A_ &pipe_w);*/ + + if (evpipe [0] >= 0) EV_WIN32_CLOSE_FD (evpipe [0]); + if (evpipe [1] >= 0) EV_WIN32_CLOSE_FD (evpipe [1]); + } + +#if EV_USE_SIGNALFD + if (ev_is_active (&sigfd_w)) + close (sigfd); +#endif + +#if EV_USE_TIMERFD + if (ev_is_active (&timerfd_w)) + close (timerfd); +#endif + +#if EV_USE_INOTIFY + if (fs_fd >= 0) + close (fs_fd); +#endif + + if (backend_fd >= 0) + close (backend_fd); + +#if EV_USE_IOCP + if (backend == EVBACKEND_IOCP ) iocp_destroy (EV_A); +#endif +#if EV_USE_PORT + if (backend == EVBACKEND_PORT ) port_destroy (EV_A); +#endif +#if EV_USE_KQUEUE + if (backend == EVBACKEND_KQUEUE ) kqueue_destroy (EV_A); +#endif +#if EV_USE_IOURING + if (backend == EVBACKEND_IOURING ) iouring_destroy (EV_A); +#endif +#if EV_USE_LINUXAIO + if (backend == EVBACKEND_LINUXAIO) linuxaio_destroy (EV_A); +#endif +#if EV_USE_EPOLL + if (backend == EVBACKEND_EPOLL ) epoll_destroy (EV_A); +#endif +#if EV_USE_POLL + if (backend == EVBACKEND_POLL ) poll_destroy (EV_A); +#endif +#if EV_USE_SELECT + if (backend == EVBACKEND_SELECT ) select_destroy (EV_A); +#endif + + for (i = NUMPRI; i--; ) + { + array_free (pending, [i]); +#if EV_IDLE_ENABLE + array_free (idle, [i]); +#endif + } + + ev_free (anfds); anfds = 0; anfdmax = 0; + + /* have to use the microsoft-never-gets-it-right macro */ + array_free (rfeed, EMPTY); + array_free (fdchange, EMPTY); + array_free (timer, EMPTY); +#if EV_PERIODIC_ENABLE + array_free (periodic, EMPTY); +#endif +#if EV_FORK_ENABLE + array_free (fork, EMPTY); +#endif +#if EV_CLEANUP_ENABLE + array_free (cleanup, EMPTY); +#endif + array_free (prepare, EMPTY); + array_free (check, EMPTY); +#if EV_ASYNC_ENABLE + array_free (async, EMPTY); +#endif + + backend = 0; + +#if EV_MULTIPLICITY + if (ev_is_default_loop (EV_A)) +#endif + ev_default_loop_ptr = 0; +#if EV_MULTIPLICITY + else + ev_free (EV_A); +#endif +} + +#if EV_USE_INOTIFY +inline_size void infy_fork (EV_P); +#endif + +inline_size void +loop_fork (EV_P) +{ +#if EV_USE_PORT + if (backend == EVBACKEND_PORT ) port_fork (EV_A); +#endif +#if EV_USE_KQUEUE + if (backend == EVBACKEND_KQUEUE ) kqueue_fork (EV_A); +#endif +#if EV_USE_IOURING + if (backend == EVBACKEND_IOURING ) iouring_fork (EV_A); +#endif +#if EV_USE_LINUXAIO + if (backend == EVBACKEND_LINUXAIO) linuxaio_fork (EV_A); +#endif +#if EV_USE_EPOLL + if (backend == EVBACKEND_EPOLL ) epoll_fork (EV_A); +#endif +#if EV_USE_INOTIFY + infy_fork (EV_A); +#endif + + if (postfork != 2) + { + #if EV_USE_SIGNALFD + /* surprisingly, nothing needs to be done for signalfd, accoridng to docs, it does the right thing on fork */ + #endif + + #if EV_USE_TIMERFD + if (ev_is_active (&timerfd_w)) + { + ev_ref (EV_A); + ev_io_stop (EV_A_ &timerfd_w); + + close (timerfd); + timerfd = -2; + + evtimerfd_init (EV_A); + /* reschedule periodics, in case we missed something */ + ev_feed_event (EV_A_ &timerfd_w, EV_CUSTOM); + } + #endif + + #if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE + if (ev_is_active (&pipe_w)) + { + /* pipe_write_wanted must be false now, so modifying fd vars should be safe */ + + ev_ref (EV_A); + ev_io_stop (EV_A_ &pipe_w); + + if (evpipe [0] >= 0) + EV_WIN32_CLOSE_FD (evpipe [0]); + + evpipe_init (EV_A); + /* iterate over everything, in case we missed something before */ + ev_feed_event (EV_A_ &pipe_w, EV_CUSTOM); + } + #endif + } + + postfork = 0; +} + +#if EV_MULTIPLICITY + +ecb_cold +struct ev_loop * +ev_loop_new (unsigned int flags) EV_NOEXCEPT +{ + EV_P = (struct ev_loop *)ev_malloc (sizeof (struct ev_loop)); + + memset (EV_A, 0, sizeof (struct ev_loop)); + loop_init (EV_A_ flags); + + if (ev_backend (EV_A)) + return EV_A; + + ev_free (EV_A); + return 0; +} + +#endif /* multiplicity */ + +#if EV_VERIFY +ecb_noinline ecb_cold +static void +verify_watcher (EV_P_ W w) +{ + assert (("libev: watcher has invalid priority", ABSPRI (w) >= 0 && ABSPRI (w) < NUMPRI)); + + if (w->pending) + assert (("libev: pending watcher not on pending queue", pendings [ABSPRI (w)][w->pending - 1].w == w)); +} + +ecb_noinline ecb_cold +static void +verify_heap (EV_P_ ANHE *heap, int N) +{ + int i; + + for (i = HEAP0; i < N + HEAP0; ++i) + { + assert (("libev: active index mismatch in heap", ev_active (ANHE_w (heap [i])) == i)); + assert (("libev: heap condition violated", i == HEAP0 || ANHE_at (heap [HPARENT (i)]) <= ANHE_at (heap [i]))); + assert (("libev: heap at cache mismatch", ANHE_at (heap [i]) == ev_at (ANHE_w (heap [i])))); + + verify_watcher (EV_A_ (W)ANHE_w (heap [i])); + } +} + +ecb_noinline ecb_cold +static void +array_verify (EV_P_ W *ws, int cnt) +{ + while (cnt--) + { + assert (("libev: active index mismatch", ev_active (ws [cnt]) == cnt + 1)); + verify_watcher (EV_A_ ws [cnt]); + } +} +#endif + +#if EV_FEATURE_API +void ecb_cold +ev_verify (EV_P) EV_NOEXCEPT +{ +#if EV_VERIFY + int i; + WL w, w2; + + assert (activecnt >= -1); + + assert (fdchangemax >= fdchangecnt); + for (i = 0; i < fdchangecnt; ++i) + assert (("libev: negative fd in fdchanges", fdchanges [i] >= 0)); + + assert (anfdmax >= 0); + for (i = 0; i < anfdmax; ++i) + { + int j = 0; + + for (w = w2 = anfds [i].head; w; w = w->next) + { + verify_watcher (EV_A_ (W)w); + + if (j++ & 1) + { + assert (("libev: io watcher list contains a loop", w != w2)); + w2 = w2->next; + } + + assert (("libev: inactive fd watcher on anfd list", ev_active (w) == 1)); + assert (("libev: fd mismatch between watcher and anfd", ((ev_io *)w)->fd == i)); + } + } + + assert (timermax >= timercnt); + verify_heap (EV_A_ timers, timercnt); + +#if EV_PERIODIC_ENABLE + assert (periodicmax >= periodiccnt); + verify_heap (EV_A_ periodics, periodiccnt); +#endif + + for (i = NUMPRI; i--; ) + { + assert (pendingmax [i] >= pendingcnt [i]); +#if EV_IDLE_ENABLE + assert (idleall >= 0); + assert (idlemax [i] >= idlecnt [i]); + array_verify (EV_A_ (W *)idles [i], idlecnt [i]); +#endif + } + +#if EV_FORK_ENABLE + assert (forkmax >= forkcnt); + array_verify (EV_A_ (W *)forks, forkcnt); +#endif + +#if EV_CLEANUP_ENABLE + assert (cleanupmax >= cleanupcnt); + array_verify (EV_A_ (W *)cleanups, cleanupcnt); +#endif + +#if EV_ASYNC_ENABLE + assert (asyncmax >= asynccnt); + array_verify (EV_A_ (W *)asyncs, asynccnt); +#endif + +#if EV_PREPARE_ENABLE + assert (preparemax >= preparecnt); + array_verify (EV_A_ (W *)prepares, preparecnt); +#endif + +#if EV_CHECK_ENABLE + assert (checkmax >= checkcnt); + array_verify (EV_A_ (W *)checks, checkcnt); +#endif + +# if 0 +#if EV_CHILD_ENABLE + for (w = (ev_child *)childs [chain & ((EV_PID_HASHSIZE) - 1)]; w; w = (ev_child *)((WL)w)->next) + for (signum = EV_NSIG; signum--; ) if (signals [signum].pending) +#endif +# endif +#endif +} +#endif + +#if EV_MULTIPLICITY +ecb_cold +struct ev_loop * +#else +int +#endif +ev_default_loop (unsigned int flags) EV_NOEXCEPT +{ + if (!ev_default_loop_ptr) + { +#if EV_MULTIPLICITY + EV_P = ev_default_loop_ptr = &default_loop_struct; +#else + ev_default_loop_ptr = 1; +#endif + + loop_init (EV_A_ flags); + + if (ev_backend (EV_A)) + { +#if EV_CHILD_ENABLE + ev_signal_init (&childev, childcb, SIGCHLD); + ev_set_priority (&childev, EV_MAXPRI); + ev_signal_start (EV_A_ &childev); + ev_unref (EV_A); /* child watcher should not keep loop alive */ +#endif + } + else + ev_default_loop_ptr = 0; + } + + return ev_default_loop_ptr; +} + +void +ev_loop_fork (EV_P) EV_NOEXCEPT +{ + postfork = 1; +} + +/*****************************************************************************/ + +void +ev_invoke (EV_P_ void *w, int revents) +{ + EV_CB_INVOKE ((W)w, revents); +} + +unsigned int +ev_pending_count (EV_P) EV_NOEXCEPT +{ + int pri; + unsigned int count = 0; + + for (pri = NUMPRI; pri--; ) + count += pendingcnt [pri]; + + return count; +} + +ecb_noinline +void +ev_invoke_pending (EV_P) +{ + pendingpri = NUMPRI; + + do + { + --pendingpri; + + /* pendingpri possibly gets modified in the inner loop */ + while (pendingcnt [pendingpri]) + { + ANPENDING *p = pendings [pendingpri] + --pendingcnt [pendingpri]; + + p->w->pending = 0; + EV_CB_INVOKE (p->w, p->events); + EV_FREQUENT_CHECK; + } + } + while (pendingpri); +} + +#if EV_IDLE_ENABLE +/* make idle watchers pending. this handles the "call-idle */ +/* only when higher priorities are idle" logic */ +inline_size void +idle_reify (EV_P) +{ + if (ecb_expect_false (idleall)) + { + int pri; + + for (pri = NUMPRI; pri--; ) + { + if (pendingcnt [pri]) + break; + + if (idlecnt [pri]) + { + queue_events (EV_A_ (W *)idles [pri], idlecnt [pri], EV_IDLE); + break; + } + } + } +} +#endif + +/* make timers pending */ +inline_size void +timers_reify (EV_P) +{ + EV_FREQUENT_CHECK; + + if (timercnt && ANHE_at (timers [HEAP0]) < mn_now) + { + do + { + ev_timer *w = (ev_timer *)ANHE_w (timers [HEAP0]); + + /*assert (("libev: inactive timer on timer heap detected", ev_is_active (w)));*/ + + /* first reschedule or stop timer */ + if (w->repeat) + { + ev_at (w) += w->repeat; + if (ev_at (w) < mn_now) + ev_at (w) = mn_now; + + assert (("libev: negative ev_timer repeat value found while processing timers", w->repeat > EV_TS_CONST (0.))); + + ANHE_at_cache (timers [HEAP0]); + downheap (timers, timercnt, HEAP0); + } + else + ev_timer_stop (EV_A_ w); /* nonrepeating: stop timer */ + + EV_FREQUENT_CHECK; + feed_reverse (EV_A_ (W)w); + } + while (timercnt && ANHE_at (timers [HEAP0]) < mn_now); + + feed_reverse_done (EV_A_ EV_TIMER); + } +} + +#if EV_PERIODIC_ENABLE + +ecb_noinline +static void +periodic_recalc (EV_P_ ev_periodic *w) +{ + ev_tstamp interval = w->interval > MIN_INTERVAL ? w->interval : MIN_INTERVAL; + ev_tstamp at = w->offset + interval * ev_floor ((ev_rt_now - w->offset) / interval); + + /* the above almost always errs on the low side */ + while (at <= ev_rt_now) + { + ev_tstamp nat = at + w->interval; + + /* when resolution fails us, we use ev_rt_now */ + if (ecb_expect_false (nat == at)) + { + at = ev_rt_now; + break; + } + + at = nat; + } + + ev_at (w) = at; +} + +/* make periodics pending */ +inline_size void +periodics_reify (EV_P) +{ + EV_FREQUENT_CHECK; + + while (periodiccnt && ANHE_at (periodics [HEAP0]) < ev_rt_now) + { + do + { + ev_periodic *w = (ev_periodic *)ANHE_w (periodics [HEAP0]); + + /*assert (("libev: inactive timer on periodic heap detected", ev_is_active (w)));*/ + + /* first reschedule or stop timer */ + if (w->reschedule_cb) + { + ev_at (w) = w->reschedule_cb (w, ev_rt_now); + + assert (("libev: ev_periodic reschedule callback returned time in the past", ev_at (w) >= ev_rt_now)); + + ANHE_at_cache (periodics [HEAP0]); + downheap (periodics, periodiccnt, HEAP0); + } + else if (w->interval) + { + periodic_recalc (EV_A_ w); + ANHE_at_cache (periodics [HEAP0]); + downheap (periodics, periodiccnt, HEAP0); + } + else + ev_periodic_stop (EV_A_ w); /* nonrepeating: stop timer */ + + EV_FREQUENT_CHECK; + feed_reverse (EV_A_ (W)w); + } + while (periodiccnt && ANHE_at (periodics [HEAP0]) < ev_rt_now); + + feed_reverse_done (EV_A_ EV_PERIODIC); + } +} + +/* simply recalculate all periodics */ +/* TODO: maybe ensure that at least one event happens when jumping forward? */ +ecb_noinline ecb_cold +static void +periodics_reschedule (EV_P) +{ + int i; + + /* adjust periodics after time jump */ + for (i = HEAP0; i < periodiccnt + HEAP0; ++i) + { + ev_periodic *w = (ev_periodic *)ANHE_w (periodics [i]); + + if (w->reschedule_cb) + ev_at (w) = w->reschedule_cb (w, ev_rt_now); + else if (w->interval) + periodic_recalc (EV_A_ w); + + ANHE_at_cache (periodics [i]); + } + + reheap (periodics, periodiccnt); +} +#endif + +/* adjust all timers by a given offset */ +ecb_noinline ecb_cold +static void +timers_reschedule (EV_P_ ev_tstamp adjust) +{ + int i; + + for (i = 0; i < timercnt; ++i) + { + ANHE *he = timers + i + HEAP0; + ANHE_w (*he)->at += adjust; + ANHE_at_cache (*he); + } +} + +/* fetch new monotonic and realtime times from the kernel */ +/* also detect if there was a timejump, and act accordingly */ +inline_speed void +time_update (EV_P_ ev_tstamp max_block) +{ +#if EV_USE_MONOTONIC + if (ecb_expect_true (have_monotonic)) + { + int i; + ev_tstamp odiff = rtmn_diff; + + mn_now = get_clock (); + + /* only fetch the realtime clock every 0.5*MIN_TIMEJUMP seconds */ + /* interpolate in the meantime */ + if (ecb_expect_true (mn_now - now_floor < EV_TS_CONST (MIN_TIMEJUMP * .5))) + { + ev_rt_now = rtmn_diff + mn_now; + return; + } + + now_floor = mn_now; + ev_rt_now = ev_time (); + + /* loop a few times, before making important decisions. + * on the choice of "4": one iteration isn't enough, + * in case we get preempted during the calls to + * ev_time and get_clock. a second call is almost guaranteed + * to succeed in that case, though. and looping a few more times + * doesn't hurt either as we only do this on time-jumps or + * in the unlikely event of having been preempted here. + */ + for (i = 4; --i; ) + { + ev_tstamp diff; + rtmn_diff = ev_rt_now - mn_now; + + diff = odiff - rtmn_diff; + + if (ecb_expect_true ((diff < EV_TS_CONST (0.) ? -diff : diff) < EV_TS_CONST (MIN_TIMEJUMP))) + return; /* all is well */ + + ev_rt_now = ev_time (); + mn_now = get_clock (); + now_floor = mn_now; + } + + /* no timer adjustment, as the monotonic clock doesn't jump */ + /* timers_reschedule (EV_A_ rtmn_diff - odiff) */ +# if EV_PERIODIC_ENABLE + periodics_reschedule (EV_A); +# endif + } + else +#endif + { + ev_rt_now = ev_time (); + + if (ecb_expect_false (mn_now > ev_rt_now || ev_rt_now > mn_now + max_block + EV_TS_CONST (MIN_TIMEJUMP))) + { + /* adjust timers. this is easy, as the offset is the same for all of them */ + timers_reschedule (EV_A_ ev_rt_now - mn_now); +#if EV_PERIODIC_ENABLE + periodics_reschedule (EV_A); +#endif + } + + mn_now = ev_rt_now; + } +} + +/* ########## NIO4R PATCHERY HO! ########## */ +struct ev_poll_args { + struct ev_loop *loop; + ev_tstamp waittime; +}; + +static +void * ev_backend_poll(void *ptr) +{ + struct ev_poll_args *args = (struct ev_poll_args *)ptr; + struct ev_loop *loop = args->loop; + backend_poll (EV_A_ args->waittime); + + return NULL; +} +/* ######################################## */ + +int +ev_run (EV_P_ int flags) +{ +/* ########## NIO4R PATCHERY HO! ########## */ + struct ev_poll_args poll_args; +/* ######################################## */ + +#if EV_FEATURE_API + ++loop_depth; +#endif + + assert (("libev: ev_loop recursion during release detected", loop_done != EVBREAK_RECURSE)); + + loop_done = EVBREAK_CANCEL; + + EV_INVOKE_PENDING; /* in case we recurse, ensure ordering stays nice and clean */ + + do + { +#if EV_VERIFY >= 2 + ev_verify (EV_A); +#endif + +#ifndef _WIN32 + if (ecb_expect_false (curpid)) /* penalise the forking check even more */ + if (ecb_expect_false (getpid () != curpid)) + { + curpid = getpid (); + postfork = 1; + } +#endif + +#if EV_FORK_ENABLE + /* we might have forked, so queue fork handlers */ + if (ecb_expect_false (postfork)) + if (forkcnt) + { + queue_events (EV_A_ (W *)forks, forkcnt, EV_FORK); + EV_INVOKE_PENDING; + } +#endif + +#if EV_PREPARE_ENABLE + /* queue prepare watchers (and execute them) */ + if (ecb_expect_false (preparecnt)) + { + queue_events (EV_A_ (W *)prepares, preparecnt, EV_PREPARE); + EV_INVOKE_PENDING; + } +#endif + + if (ecb_expect_false (loop_done)) + break; + + /* we might have forked, so reify kernel state if necessary */ + if (ecb_expect_false (postfork)) + loop_fork (EV_A); + + /* update fd-related kernel structures */ + fd_reify (EV_A); + + /* calculate blocking time */ + { + ev_tstamp waittime = 0.; + ev_tstamp sleeptime = 0.; + + /* remember old timestamp for io_blocktime calculation */ + ev_tstamp prev_mn_now = mn_now; + + /* update time to cancel out callback processing overhead */ + time_update (EV_A_ EV_TS_CONST (EV_TSTAMP_HUGE)); + + /* from now on, we want a pipe-wake-up */ + pipe_write_wanted = 1; + + ECB_MEMORY_FENCE; /* make sure pipe_write_wanted is visible before we check for potential skips */ + + if (ecb_expect_true (!(flags & EVRUN_NOWAIT || idleall || !activecnt || pipe_write_skipped))) + { + waittime = EV_TS_CONST (MAX_BLOCKTIME); + +#if EV_USE_TIMERFD + /* sleep a lot longer when we can reliably detect timejumps */ + if (ecb_expect_true (timerfd >= 0)) + waittime = EV_TS_CONST (MAX_BLOCKTIME2); +#endif +#if !EV_PERIODIC_ENABLE + /* without periodics but with monotonic clock there is no need */ + /* for any time jump detection, so sleep longer */ + if (ecb_expect_true (have_monotonic)) + waittime = EV_TS_CONST (MAX_BLOCKTIME2); +#endif + + if (timercnt) + { + ev_tstamp to = ANHE_at (timers [HEAP0]) - mn_now; + if (waittime > to) waittime = to; + } + +#if EV_PERIODIC_ENABLE + if (periodiccnt) + { + ev_tstamp to = ANHE_at (periodics [HEAP0]) - ev_rt_now; + if (waittime > to) waittime = to; + } +#endif + + /* don't let timeouts decrease the waittime below timeout_blocktime */ + if (ecb_expect_false (waittime < timeout_blocktime)) + waittime = timeout_blocktime; + + /* now there are two more special cases left, either we have + * already-expired timers, so we should not sleep, or we have timers + * that expire very soon, in which case we need to wait for a minimum + * amount of time for some event loop backends. + */ + if (ecb_expect_false (waittime < backend_mintime)) + waittime = waittime <= EV_TS_CONST (0.) + ? EV_TS_CONST (0.) + : backend_mintime; + + /* extra check because io_blocktime is commonly 0 */ + if (ecb_expect_false (io_blocktime)) + { + sleeptime = io_blocktime - (mn_now - prev_mn_now); + + if (sleeptime > waittime - backend_mintime) + sleeptime = waittime - backend_mintime; + + if (ecb_expect_true (sleeptime > EV_TS_CONST (0.))) + { + ev_sleep (sleeptime); + waittime -= sleeptime; + } + } + } + +#if EV_FEATURE_API + ++loop_count; +#endif + assert ((loop_done = EVBREAK_RECURSE, 1)); /* assert for side effect */ + +/* +########################## NIO4R PATCHERY HO! ########################## + +According to the grandwizards of Ruby, locking and unlocking of the global +interpreter lock are apparently too powerful a concept for a mere mortal to +wield (although redefining what + and - do to numbers is totally cool). +And so it came to pass that the only acceptable way to release the global +interpreter lock is through a convoluted callback system that thakes a +function pointer. While the grandwizard of libev foresaw this sort of scenario, +he too attempted to place an API with callbacks on it, one that runs before +the system call, and one that runs immediately after. + +And so it came to pass that trying to wrap everything up in callbacks created +two incompatible APIs, Ruby's which releases the global interpreter lock and +reacquires it when the callback returns, and libev's, which wants two +callbacks, one which runs before the polling operation starts, and one which +runs after it finishes. + +These two systems are incompatible as they both want to use callbacks to +solve the same problem, however libev wants to use before/after callbacks, +and Ruby wants to use an "around" callback. This presents a significant +problem as these two patterns of callbacks are diametrical opposites of each +other and thus cannot be composed. + +And thus we are left with no choice but to patch the internals of libev in +order to release a mutex at just the precise moment. + +This is a great example of a situation where granular locking and unlocking +of the GVL is practically required. The goal is to get as close to the +system call as possible, and to keep the GVL unlocked for the shortest +amount of time possible. + +Perhaps Ruby could benefit from such an API, e.g: + +rb_thread_unsafe_dangerous_crazy_blocking_region_begin(...); +rb_thread_unsafe_dangerous_crazy_blocking_region_end(...); + +####################################################################### +*/ + + poll_args.loop = loop; + poll_args.waittime = waittime; + rb_thread_call_without_gvl(ev_backend_poll, (void *)&poll_args, RUBY_UBF_IO, 0); +/* +############################# END PATCHERY ############################ +*/ + + assert ((loop_done = EVBREAK_CANCEL, 1)); /* assert for side effect */ + + pipe_write_wanted = 0; /* just an optimisation, no fence needed */ + + ECB_MEMORY_FENCE_ACQUIRE; + if (pipe_write_skipped) + { + assert (("libev: pipe_w not active, but pipe not written", ev_is_active (&pipe_w))); + ev_feed_event (EV_A_ &pipe_w, EV_CUSTOM); + } + + /* update ev_rt_now, do magic */ + time_update (EV_A_ waittime + sleeptime); + } + + /* queue pending timers and reschedule them */ + timers_reify (EV_A); /* relative timers called last */ +#if EV_PERIODIC_ENABLE + periodics_reify (EV_A); /* absolute timers called first */ +#endif + +#if EV_IDLE_ENABLE + /* queue idle watchers unless other events are pending */ + idle_reify (EV_A); +#endif + +#if EV_CHECK_ENABLE + /* queue check watchers, to be executed first */ + if (ecb_expect_false (checkcnt)) + queue_events (EV_A_ (W *)checks, checkcnt, EV_CHECK); +#endif + + EV_INVOKE_PENDING; + } + while (ecb_expect_true ( + activecnt + && !loop_done + && !(flags & (EVRUN_ONCE | EVRUN_NOWAIT)) + )); + + if (loop_done == EVBREAK_ONE) + loop_done = EVBREAK_CANCEL; + +#if EV_FEATURE_API + --loop_depth; +#endif + + return activecnt; +} + +void +ev_break (EV_P_ int how) EV_NOEXCEPT +{ + loop_done = how; +} + +void +ev_ref (EV_P) EV_NOEXCEPT +{ + ++activecnt; +} + +void +ev_unref (EV_P) EV_NOEXCEPT +{ + --activecnt; +} + +void +ev_now_update (EV_P) EV_NOEXCEPT +{ + time_update (EV_A_ EV_TSTAMP_HUGE); +} + +void +ev_suspend (EV_P) EV_NOEXCEPT +{ + ev_now_update (EV_A); +} + +void +ev_resume (EV_P) EV_NOEXCEPT +{ + ev_tstamp mn_prev = mn_now; + + ev_now_update (EV_A); + timers_reschedule (EV_A_ mn_now - mn_prev); +#if EV_PERIODIC_ENABLE + /* TODO: really do this? */ + periodics_reschedule (EV_A); +#endif +} + +/*****************************************************************************/ +/* singly-linked list management, used when the expected list length is short */ + +inline_size void +wlist_add (WL *head, WL elem) +{ + elem->next = *head; + *head = elem; +} + +inline_size void +wlist_del (WL *head, WL elem) +{ + while (*head) + { + if (ecb_expect_true (*head == elem)) + { + *head = elem->next; + break; + } + + head = &(*head)->next; + } +} + +/* internal, faster, version of ev_clear_pending */ +inline_speed void +clear_pending (EV_P_ W w) +{ + if (w->pending) + { + pendings [ABSPRI (w)][w->pending - 1].w = (W)&pending_w; + w->pending = 0; + } +} + +int +ev_clear_pending (EV_P_ void *w) EV_NOEXCEPT +{ + W w_ = (W)w; + int pending = w_->pending; + + if (ecb_expect_true (pending)) + { + ANPENDING *p = pendings [ABSPRI (w_)] + pending - 1; + p->w = (W)&pending_w; + w_->pending = 0; + return p->events; + } + else + return 0; +} + +inline_size void +pri_adjust (EV_P_ W w) +{ + int pri = ev_priority (w); + pri = pri < EV_MINPRI ? EV_MINPRI : pri; + pri = pri > EV_MAXPRI ? EV_MAXPRI : pri; + ev_set_priority (w, pri); +} + +inline_speed void +ev_start (EV_P_ W w, int active) +{ + pri_adjust (EV_A_ w); + w->active = active; + ev_ref (EV_A); +} + +inline_size void +ev_stop (EV_P_ W w) +{ + ev_unref (EV_A); + w->active = 0; +} + +/*****************************************************************************/ + +ecb_noinline +void +ev_io_start (EV_P_ ev_io *w) EV_NOEXCEPT +{ + int fd = w->fd; + + if (ecb_expect_false (ev_is_active (w))) + return; + + assert (("libev: ev_io_start called with negative fd", fd >= 0)); + assert (("libev: ev_io_start called with illegal event mask", !(w->events & ~(EV__IOFDSET | EV_READ | EV_WRITE)))); + +#if EV_VERIFY >= 2 + assert (("libev: ev_io_start called on watcher with invalid fd", fd_valid (fd))); +#endif + EV_FREQUENT_CHECK; + + ev_start (EV_A_ (W)w, 1); + array_needsize (ANFD, anfds, anfdmax, fd + 1, array_needsize_zerofill); + wlist_add (&anfds[fd].head, (WL)w); + + /* common bug, apparently */ + assert (("libev: ev_io_start called with corrupted watcher", ((WL)w)->next != (WL)w)); + + fd_change (EV_A_ fd, w->events & EV__IOFDSET | EV_ANFD_REIFY); + w->events &= ~EV__IOFDSET; + + EV_FREQUENT_CHECK; +} + +ecb_noinline +void +ev_io_stop (EV_P_ ev_io *w) EV_NOEXCEPT +{ + clear_pending (EV_A_ (W)w); + if (ecb_expect_false (!ev_is_active (w))) + return; + + assert (("libev: ev_io_stop called with illegal fd (must stay constant after start!)", w->fd >= 0 && w->fd < anfdmax)); + +#if EV_VERIFY >= 2 + assert (("libev: ev_io_stop called on watcher with invalid fd", fd_valid (w->fd))); +#endif + EV_FREQUENT_CHECK; + + wlist_del (&anfds[w->fd].head, (WL)w); + ev_stop (EV_A_ (W)w); + + fd_change (EV_A_ w->fd, EV_ANFD_REIFY); + + EV_FREQUENT_CHECK; +} + +ecb_noinline +void +ev_timer_start (EV_P_ ev_timer *w) EV_NOEXCEPT +{ + if (ecb_expect_false (ev_is_active (w))) + return; + + ev_at (w) += mn_now; + + assert (("libev: ev_timer_start called with negative timer repeat value", w->repeat >= 0.)); + + EV_FREQUENT_CHECK; + + ++timercnt; + ev_start (EV_A_ (W)w, timercnt + HEAP0 - 1); + array_needsize (ANHE, timers, timermax, ev_active (w) + 1, array_needsize_noinit); + ANHE_w (timers [ev_active (w)]) = (WT)w; + ANHE_at_cache (timers [ev_active (w)]); + upheap (timers, ev_active (w)); + + EV_FREQUENT_CHECK; + + /*assert (("libev: internal timer heap corruption", timers [ev_active (w)] == (WT)w));*/ +} + +ecb_noinline +void +ev_timer_stop (EV_P_ ev_timer *w) EV_NOEXCEPT +{ + clear_pending (EV_A_ (W)w); + if (ecb_expect_false (!ev_is_active (w))) + return; + + EV_FREQUENT_CHECK; + + { + int active = ev_active (w); + + assert (("libev: internal timer heap corruption", ANHE_w (timers [active]) == (WT)w)); + + --timercnt; + + if (ecb_expect_true (active < timercnt + HEAP0)) + { + timers [active] = timers [timercnt + HEAP0]; + adjustheap (timers, timercnt, active); + } + } + + ev_at (w) -= mn_now; + + ev_stop (EV_A_ (W)w); + + EV_FREQUENT_CHECK; +} + +ecb_noinline +void +ev_timer_again (EV_P_ ev_timer *w) EV_NOEXCEPT +{ + EV_FREQUENT_CHECK; + + clear_pending (EV_A_ (W)w); + + if (ev_is_active (w)) + { + if (w->repeat) + { + ev_at (w) = mn_now + w->repeat; + ANHE_at_cache (timers [ev_active (w)]); + adjustheap (timers, timercnt, ev_active (w)); + } + else + ev_timer_stop (EV_A_ w); + } + else if (w->repeat) + { + ev_at (w) = w->repeat; + ev_timer_start (EV_A_ w); + } + + EV_FREQUENT_CHECK; +} + +ev_tstamp +ev_timer_remaining (EV_P_ ev_timer *w) EV_NOEXCEPT +{ + return ev_at (w) - (ev_is_active (w) ? mn_now : EV_TS_CONST (0.)); +} + +#if EV_PERIODIC_ENABLE +ecb_noinline +void +ev_periodic_start (EV_P_ ev_periodic *w) EV_NOEXCEPT +{ + if (ecb_expect_false (ev_is_active (w))) + return; + +#if EV_USE_TIMERFD + if (timerfd == -2) + evtimerfd_init (EV_A); +#endif + + if (w->reschedule_cb) + ev_at (w) = w->reschedule_cb (w, ev_rt_now); + else if (w->interval) + { + assert (("libev: ev_periodic_start called with negative interval value", w->interval >= 0.)); + periodic_recalc (EV_A_ w); + } + else + ev_at (w) = w->offset; + + EV_FREQUENT_CHECK; + + ++periodiccnt; + ev_start (EV_A_ (W)w, periodiccnt + HEAP0 - 1); + array_needsize (ANHE, periodics, periodicmax, ev_active (w) + 1, array_needsize_noinit); + ANHE_w (periodics [ev_active (w)]) = (WT)w; + ANHE_at_cache (periodics [ev_active (w)]); + upheap (periodics, ev_active (w)); + + EV_FREQUENT_CHECK; + + /*assert (("libev: internal periodic heap corruption", ANHE_w (periodics [ev_active (w)]) == (WT)w));*/ +} + +ecb_noinline +void +ev_periodic_stop (EV_P_ ev_periodic *w) EV_NOEXCEPT +{ + clear_pending (EV_A_ (W)w); + if (ecb_expect_false (!ev_is_active (w))) + return; + + EV_FREQUENT_CHECK; + + { + int active = ev_active (w); + + assert (("libev: internal periodic heap corruption", ANHE_w (periodics [active]) == (WT)w)); + + --periodiccnt; + + if (ecb_expect_true (active < periodiccnt + HEAP0)) + { + periodics [active] = periodics [periodiccnt + HEAP0]; + adjustheap (periodics, periodiccnt, active); + } + } + + ev_stop (EV_A_ (W)w); + + EV_FREQUENT_CHECK; +} + +ecb_noinline +void +ev_periodic_again (EV_P_ ev_periodic *w) EV_NOEXCEPT +{ + /* TODO: use adjustheap and recalculation */ + ev_periodic_stop (EV_A_ w); + ev_periodic_start (EV_A_ w); +} +#endif + +#ifndef SA_RESTART +# define SA_RESTART 0 +#endif + +#if EV_SIGNAL_ENABLE + +ecb_noinline +void +ev_signal_start (EV_P_ ev_signal *w) EV_NOEXCEPT +{ + if (ecb_expect_false (ev_is_active (w))) + return; + + assert (("libev: ev_signal_start called with illegal signal number", w->signum > 0 && w->signum < EV_NSIG)); + +#if EV_MULTIPLICITY + assert (("libev: a signal must not be attached to two different loops", + !signals [w->signum - 1].loop || signals [w->signum - 1].loop == loop)); + + signals [w->signum - 1].loop = EV_A; + ECB_MEMORY_FENCE_RELEASE; +#endif + + EV_FREQUENT_CHECK; + +#if EV_USE_SIGNALFD + if (sigfd == -2) + { + sigfd = signalfd (-1, &sigfd_set, SFD_NONBLOCK | SFD_CLOEXEC); + if (sigfd < 0 && errno == EINVAL) + sigfd = signalfd (-1, &sigfd_set, 0); /* retry without flags */ + + if (sigfd >= 0) + { + fd_intern (sigfd); /* doing it twice will not hurt */ + + sigemptyset (&sigfd_set); + + ev_io_init (&sigfd_w, sigfdcb, sigfd, EV_READ); + ev_set_priority (&sigfd_w, EV_MAXPRI); + ev_io_start (EV_A_ &sigfd_w); + ev_unref (EV_A); /* signalfd watcher should not keep loop alive */ + } + } + + if (sigfd >= 0) + { + /* TODO: check .head */ + sigaddset (&sigfd_set, w->signum); + sigprocmask (SIG_BLOCK, &sigfd_set, 0); + + signalfd (sigfd, &sigfd_set, 0); + } +#endif + + ev_start (EV_A_ (W)w, 1); + wlist_add (&signals [w->signum - 1].head, (WL)w); + + if (!((WL)w)->next) +# if EV_USE_SIGNALFD + if (sigfd < 0) /*TODO*/ +# endif + { +# ifdef _WIN32 + evpipe_init (EV_A); + + signal (w->signum, ev_sighandler); +# else + struct sigaction sa; + + evpipe_init (EV_A); + + sa.sa_handler = ev_sighandler; + sigfillset (&sa.sa_mask); + sa.sa_flags = SA_RESTART; /* if restarting works we save one iteration */ + sigaction (w->signum, &sa, 0); + + if (origflags & EVFLAG_NOSIGMASK) + { + sigemptyset (&sa.sa_mask); + sigaddset (&sa.sa_mask, w->signum); + sigprocmask (SIG_UNBLOCK, &sa.sa_mask, 0); + } +#endif + } + + EV_FREQUENT_CHECK; +} + +ecb_noinline +void +ev_signal_stop (EV_P_ ev_signal *w) EV_NOEXCEPT +{ + clear_pending (EV_A_ (W)w); + if (ecb_expect_false (!ev_is_active (w))) + return; + + EV_FREQUENT_CHECK; + + wlist_del (&signals [w->signum - 1].head, (WL)w); + ev_stop (EV_A_ (W)w); + + if (!signals [w->signum - 1].head) + { +#if EV_MULTIPLICITY + signals [w->signum - 1].loop = 0; /* unattach from signal */ +#endif +#if EV_USE_SIGNALFD + if (sigfd >= 0) + { + sigset_t ss; + + sigemptyset (&ss); + sigaddset (&ss, w->signum); + sigdelset (&sigfd_set, w->signum); + + signalfd (sigfd, &sigfd_set, 0); + sigprocmask (SIG_UNBLOCK, &ss, 0); + } + else +#endif + signal (w->signum, SIG_DFL); + } + + EV_FREQUENT_CHECK; +} + +#endif + +#if EV_CHILD_ENABLE + +void +ev_child_start (EV_P_ ev_child *w) EV_NOEXCEPT +{ +#if EV_MULTIPLICITY + assert (("libev: child watchers are only supported in the default loop", loop == ev_default_loop_ptr)); +#endif + if (ecb_expect_false (ev_is_active (w))) + return; + + EV_FREQUENT_CHECK; + + ev_start (EV_A_ (W)w, 1); + wlist_add (&childs [w->pid & ((EV_PID_HASHSIZE) - 1)], (WL)w); + + EV_FREQUENT_CHECK; +} + +void +ev_child_stop (EV_P_ ev_child *w) EV_NOEXCEPT +{ + clear_pending (EV_A_ (W)w); + if (ecb_expect_false (!ev_is_active (w))) + return; + + EV_FREQUENT_CHECK; + + wlist_del (&childs [w->pid & ((EV_PID_HASHSIZE) - 1)], (WL)w); + ev_stop (EV_A_ (W)w); + + EV_FREQUENT_CHECK; +} + +#endif + +#if EV_STAT_ENABLE + +# ifdef _WIN32 +# undef lstat +# define lstat(a,b) _stati64 (a,b) +# endif + +#define DEF_STAT_INTERVAL 5.0074891 +#define NFS_STAT_INTERVAL 30.1074891 /* for filesystems potentially failing inotify */ +#define MIN_STAT_INTERVAL 0.1074891 + +ecb_noinline static void stat_timer_cb (EV_P_ ev_timer *w_, int revents); + +#if EV_USE_INOTIFY + +/* the * 2 is to allow for alignment padding, which for some reason is >> 8 */ +# define EV_INOTIFY_BUFSIZE (sizeof (struct inotify_event) * 2 + NAME_MAX) + +ecb_noinline +static void +infy_add (EV_P_ ev_stat *w) +{ + w->wd = inotify_add_watch (fs_fd, w->path, + IN_ATTRIB | IN_DELETE_SELF | IN_MOVE_SELF | IN_MODIFY + | IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO + | IN_DONT_FOLLOW | IN_MASK_ADD); + + if (w->wd >= 0) + { + struct statfs sfs; + + /* now local changes will be tracked by inotify, but remote changes won't */ + /* unless the filesystem is known to be local, we therefore still poll */ + /* also do poll on <2.6.25, but with normal frequency */ + + if (!fs_2625) + w->timer.repeat = w->interval ? w->interval : DEF_STAT_INTERVAL; + else if (!statfs (w->path, &sfs) + && (sfs.f_type == 0x1373 /* devfs */ + || sfs.f_type == 0x4006 /* fat */ + || sfs.f_type == 0x4d44 /* msdos */ + || sfs.f_type == 0xEF53 /* ext2/3 */ + || sfs.f_type == 0x72b6 /* jffs2 */ + || sfs.f_type == 0x858458f6 /* ramfs */ + || sfs.f_type == 0x5346544e /* ntfs */ + || sfs.f_type == 0x3153464a /* jfs */ + || sfs.f_type == 0x9123683e /* btrfs */ + || sfs.f_type == 0x52654973 /* reiser3 */ + || sfs.f_type == 0x01021994 /* tmpfs */ + || sfs.f_type == 0x58465342 /* xfs */)) + w->timer.repeat = 0.; /* filesystem is local, kernel new enough */ + else + w->timer.repeat = w->interval ? w->interval : NFS_STAT_INTERVAL; /* remote, use reduced frequency */ + } + else + { + /* can't use inotify, continue to stat */ + w->timer.repeat = w->interval ? w->interval : DEF_STAT_INTERVAL; + + /* if path is not there, monitor some parent directory for speedup hints */ + /* note that exceeding the hardcoded path limit is not a correctness issue, */ + /* but an efficiency issue only */ + if ((errno == ENOENT || errno == EACCES) && strlen (w->path) < 4096) + { + char path [4096]; + strcpy (path, w->path); + + do + { + int mask = IN_MASK_ADD | IN_DELETE_SELF | IN_MOVE_SELF + | (errno == EACCES ? IN_ATTRIB : IN_CREATE | IN_MOVED_TO); + + char *pend = strrchr (path, '/'); + + if (!pend || pend == path) + break; + + *pend = 0; + w->wd = inotify_add_watch (fs_fd, path, mask); + } + while (w->wd < 0 && (errno == ENOENT || errno == EACCES)); + } + } + + if (w->wd >= 0) + wlist_add (&fs_hash [w->wd & ((EV_INOTIFY_HASHSIZE) - 1)].head, (WL)w); + + /* now re-arm timer, if required */ + if (ev_is_active (&w->timer)) ev_ref (EV_A); + ev_timer_again (EV_A_ &w->timer); + if (ev_is_active (&w->timer)) ev_unref (EV_A); +} + +ecb_noinline +static void +infy_del (EV_P_ ev_stat *w) +{ + int slot; + int wd = w->wd; + + if (wd < 0) + return; + + w->wd = -2; + slot = wd & ((EV_INOTIFY_HASHSIZE) - 1); + wlist_del (&fs_hash [slot].head, (WL)w); + + /* remove this watcher, if others are watching it, they will rearm */ + inotify_rm_watch (fs_fd, wd); +} + +ecb_noinline +static void +infy_wd (EV_P_ int slot, int wd, struct inotify_event *ev) +{ + if (slot < 0) + /* overflow, need to check for all hash slots */ + for (slot = 0; slot < (EV_INOTIFY_HASHSIZE); ++slot) + infy_wd (EV_A_ slot, wd, ev); + else + { + WL w_; + + for (w_ = fs_hash [slot & ((EV_INOTIFY_HASHSIZE) - 1)].head; w_; ) + { + ev_stat *w = (ev_stat *)w_; + w_ = w_->next; /* lets us remove this watcher and all before it */ + + if (w->wd == wd || wd == -1) + { + if (ev->mask & (IN_IGNORED | IN_UNMOUNT | IN_DELETE_SELF)) + { + wlist_del (&fs_hash [slot & ((EV_INOTIFY_HASHSIZE) - 1)].head, (WL)w); + w->wd = -1; + infy_add (EV_A_ w); /* re-add, no matter what */ + } + + stat_timer_cb (EV_A_ &w->timer, 0); + } + } + } +} + +static void +infy_cb (EV_P_ ev_io *w, int revents) +{ + char buf [EV_INOTIFY_BUFSIZE]; + int ofs; + int len = read (fs_fd, buf, sizeof (buf)); + + for (ofs = 0; ofs < len; ) + { + struct inotify_event *ev = (struct inotify_event *)(buf + ofs); + infy_wd (EV_A_ ev->wd, ev->wd, ev); + ofs += sizeof (struct inotify_event) + ev->len; + } +} + +inline_size ecb_cold +void +ev_check_2625 (EV_P) +{ + /* kernels < 2.6.25 are borked + * http://www.ussg.indiana.edu/hypermail/linux/kernel/0711.3/1208.html + */ + if (ev_linux_version () < 0x020619) + return; + + fs_2625 = 1; +} + +inline_size int +infy_newfd (void) +{ +#if defined IN_CLOEXEC && defined IN_NONBLOCK + int fd = inotify_init1 (IN_CLOEXEC | IN_NONBLOCK); + if (fd >= 0) + return fd; +#endif + return inotify_init (); +} + +inline_size void +infy_init (EV_P) +{ + if (fs_fd != -2) + return; + + fs_fd = -1; + + ev_check_2625 (EV_A); + + fs_fd = infy_newfd (); + + if (fs_fd >= 0) + { + fd_intern (fs_fd); + ev_io_init (&fs_w, infy_cb, fs_fd, EV_READ); + ev_set_priority (&fs_w, EV_MAXPRI); + ev_io_start (EV_A_ &fs_w); + ev_unref (EV_A); + } +} + +inline_size void +infy_fork (EV_P) +{ + int slot; + + if (fs_fd < 0) + return; + + ev_ref (EV_A); + ev_io_stop (EV_A_ &fs_w); + close (fs_fd); + fs_fd = infy_newfd (); + + if (fs_fd >= 0) + { + fd_intern (fs_fd); + ev_io_set (&fs_w, fs_fd, EV_READ); + ev_io_start (EV_A_ &fs_w); + ev_unref (EV_A); + } + + for (slot = 0; slot < (EV_INOTIFY_HASHSIZE); ++slot) + { + WL w_ = fs_hash [slot].head; + fs_hash [slot].head = 0; + + while (w_) + { + ev_stat *w = (ev_stat *)w_; + w_ = w_->next; /* lets us add this watcher */ + + w->wd = -1; + + if (fs_fd >= 0) + infy_add (EV_A_ w); /* re-add, no matter what */ + else + { + w->timer.repeat = w->interval ? w->interval : DEF_STAT_INTERVAL; + if (ev_is_active (&w->timer)) ev_ref (EV_A); + ev_timer_again (EV_A_ &w->timer); + if (ev_is_active (&w->timer)) ev_unref (EV_A); + } + } + } +} + +#endif + +#ifdef _WIN32 +# define EV_LSTAT(p,b) _stati64 (p, b) +#else +# define EV_LSTAT(p,b) lstat (p, b) +#endif + +void +ev_stat_stat (EV_P_ ev_stat *w) EV_NOEXCEPT +{ + if (lstat (w->path, &w->attr) < 0) + w->attr.st_nlink = 0; + else if (!w->attr.st_nlink) + w->attr.st_nlink = 1; +} + +ecb_noinline +static void +stat_timer_cb (EV_P_ ev_timer *w_, int revents) +{ + ev_stat *w = (ev_stat *)(((char *)w_) - offsetof (ev_stat, timer)); + + ev_statdata prev = w->attr; + ev_stat_stat (EV_A_ w); + + /* memcmp doesn't work on netbsd, they.... do stuff to their struct stat */ + if ( + prev.st_dev != w->attr.st_dev + || prev.st_ino != w->attr.st_ino + || prev.st_mode != w->attr.st_mode + || prev.st_nlink != w->attr.st_nlink + || prev.st_uid != w->attr.st_uid + || prev.st_gid != w->attr.st_gid + || prev.st_rdev != w->attr.st_rdev + || prev.st_size != w->attr.st_size + || prev.st_atime != w->attr.st_atime + || prev.st_mtime != w->attr.st_mtime + || prev.st_ctime != w->attr.st_ctime + ) { + /* we only update w->prev on actual differences */ + /* in case we test more often than invoke the callback, */ + /* to ensure that prev is always different to attr */ + w->prev = prev; + + #if EV_USE_INOTIFY + if (fs_fd >= 0) + { + infy_del (EV_A_ w); + infy_add (EV_A_ w); + ev_stat_stat (EV_A_ w); /* avoid race... */ + } + #endif + + ev_feed_event (EV_A_ w, EV_STAT); + } +} + +void +ev_stat_start (EV_P_ ev_stat *w) EV_NOEXCEPT +{ + if (ecb_expect_false (ev_is_active (w))) + return; + + ev_stat_stat (EV_A_ w); + + if (w->interval < MIN_STAT_INTERVAL && w->interval) + w->interval = MIN_STAT_INTERVAL; + + ev_timer_init (&w->timer, stat_timer_cb, 0., w->interval ? w->interval : DEF_STAT_INTERVAL); + ev_set_priority (&w->timer, ev_priority (w)); + +#if EV_USE_INOTIFY + infy_init (EV_A); + + if (fs_fd >= 0) + infy_add (EV_A_ w); + else +#endif + { + ev_timer_again (EV_A_ &w->timer); + ev_unref (EV_A); + } + + ev_start (EV_A_ (W)w, 1); + + EV_FREQUENT_CHECK; +} + +void +ev_stat_stop (EV_P_ ev_stat *w) EV_NOEXCEPT +{ + clear_pending (EV_A_ (W)w); + if (ecb_expect_false (!ev_is_active (w))) + return; + + EV_FREQUENT_CHECK; + +#if EV_USE_INOTIFY + infy_del (EV_A_ w); +#endif + + if (ev_is_active (&w->timer)) + { + ev_ref (EV_A); + ev_timer_stop (EV_A_ &w->timer); + } + + ev_stop (EV_A_ (W)w); + + EV_FREQUENT_CHECK; +} +#endif + +#if EV_IDLE_ENABLE +void +ev_idle_start (EV_P_ ev_idle *w) EV_NOEXCEPT +{ + if (ecb_expect_false (ev_is_active (w))) + return; + + pri_adjust (EV_A_ (W)w); + + EV_FREQUENT_CHECK; + + { + int active = ++idlecnt [ABSPRI (w)]; + + ++idleall; + ev_start (EV_A_ (W)w, active); + + array_needsize (ev_idle *, idles [ABSPRI (w)], idlemax [ABSPRI (w)], active, array_needsize_noinit); + idles [ABSPRI (w)][active - 1] = w; + } + + EV_FREQUENT_CHECK; +} + +void +ev_idle_stop (EV_P_ ev_idle *w) EV_NOEXCEPT +{ + clear_pending (EV_A_ (W)w); + if (ecb_expect_false (!ev_is_active (w))) + return; + + EV_FREQUENT_CHECK; + + { + int active = ev_active (w); + + idles [ABSPRI (w)][active - 1] = idles [ABSPRI (w)][--idlecnt [ABSPRI (w)]]; + ev_active (idles [ABSPRI (w)][active - 1]) = active; + + ev_stop (EV_A_ (W)w); + --idleall; + } + + EV_FREQUENT_CHECK; +} +#endif + +#if EV_PREPARE_ENABLE +void +ev_prepare_start (EV_P_ ev_prepare *w) EV_NOEXCEPT +{ + if (ecb_expect_false (ev_is_active (w))) + return; + + EV_FREQUENT_CHECK; + + ev_start (EV_A_ (W)w, ++preparecnt); + array_needsize (ev_prepare *, prepares, preparemax, preparecnt, array_needsize_noinit); + prepares [preparecnt - 1] = w; + + EV_FREQUENT_CHECK; +} + +void +ev_prepare_stop (EV_P_ ev_prepare *w) EV_NOEXCEPT +{ + clear_pending (EV_A_ (W)w); + if (ecb_expect_false (!ev_is_active (w))) + return; + + EV_FREQUENT_CHECK; + + { + int active = ev_active (w); + + prepares [active - 1] = prepares [--preparecnt]; + ev_active (prepares [active - 1]) = active; + } + + ev_stop (EV_A_ (W)w); + + EV_FREQUENT_CHECK; +} +#endif + +#if EV_CHECK_ENABLE +void +ev_check_start (EV_P_ ev_check *w) EV_NOEXCEPT +{ + if (ecb_expect_false (ev_is_active (w))) + return; + + EV_FREQUENT_CHECK; + + ev_start (EV_A_ (W)w, ++checkcnt); + array_needsize (ev_check *, checks, checkmax, checkcnt, array_needsize_noinit); + checks [checkcnt - 1] = w; + + EV_FREQUENT_CHECK; +} + +void +ev_check_stop (EV_P_ ev_check *w) EV_NOEXCEPT +{ + clear_pending (EV_A_ (W)w); + if (ecb_expect_false (!ev_is_active (w))) + return; + + EV_FREQUENT_CHECK; + + { + int active = ev_active (w); + + checks [active - 1] = checks [--checkcnt]; + ev_active (checks [active - 1]) = active; + } + + ev_stop (EV_A_ (W)w); + + EV_FREQUENT_CHECK; +} +#endif + +#if EV_EMBED_ENABLE +ecb_noinline +void +ev_embed_sweep (EV_P_ ev_embed *w) EV_NOEXCEPT +{ + ev_run (w->other, EVRUN_NOWAIT); +} + +static void +embed_io_cb (EV_P_ ev_io *io, int revents) +{ + ev_embed *w = (ev_embed *)(((char *)io) - offsetof (ev_embed, io)); + + if (ev_cb (w)) + ev_feed_event (EV_A_ (W)w, EV_EMBED); + else + ev_run (w->other, EVRUN_NOWAIT); +} + +static void +embed_prepare_cb (EV_P_ ev_prepare *prepare, int revents) +{ + ev_embed *w = (ev_embed *)(((char *)prepare) - offsetof (ev_embed, prepare)); + + { + EV_P = w->other; + + while (fdchangecnt) + { + fd_reify (EV_A); + ev_run (EV_A_ EVRUN_NOWAIT); + } + } +} + +#if EV_FORK_ENABLE +static void +embed_fork_cb (EV_P_ ev_fork *fork_w, int revents) +{ + ev_embed *w = (ev_embed *)(((char *)fork_w) - offsetof (ev_embed, fork)); + + ev_embed_stop (EV_A_ w); + + { + EV_P = w->other; + + ev_loop_fork (EV_A); + ev_run (EV_A_ EVRUN_NOWAIT); + } + + ev_embed_start (EV_A_ w); +} +#endif + +#if 0 +static void +embed_idle_cb (EV_P_ ev_idle *idle, int revents) +{ + ev_idle_stop (EV_A_ idle); +} +#endif + +void +ev_embed_start (EV_P_ ev_embed *w) EV_NOEXCEPT +{ + if (ecb_expect_false (ev_is_active (w))) + return; + + { + EV_P = w->other; + assert (("libev: loop to be embedded is not embeddable", backend & ev_embeddable_backends ())); + ev_io_init (&w->io, embed_io_cb, backend_fd, EV_READ); + } + + EV_FREQUENT_CHECK; + + ev_set_priority (&w->io, ev_priority (w)); + ev_io_start (EV_A_ &w->io); + + ev_prepare_init (&w->prepare, embed_prepare_cb); + ev_set_priority (&w->prepare, EV_MINPRI); + ev_prepare_start (EV_A_ &w->prepare); + +#if EV_FORK_ENABLE + ev_fork_init (&w->fork, embed_fork_cb); + ev_fork_start (EV_A_ &w->fork); +#endif + + /*ev_idle_init (&w->idle, e,bed_idle_cb);*/ + + ev_start (EV_A_ (W)w, 1); + + EV_FREQUENT_CHECK; +} + +void +ev_embed_stop (EV_P_ ev_embed *w) EV_NOEXCEPT +{ + clear_pending (EV_A_ (W)w); + if (ecb_expect_false (!ev_is_active (w))) + return; + + EV_FREQUENT_CHECK; + + ev_io_stop (EV_A_ &w->io); + ev_prepare_stop (EV_A_ &w->prepare); +#if EV_FORK_ENABLE + ev_fork_stop (EV_A_ &w->fork); +#endif + + ev_stop (EV_A_ (W)w); + + EV_FREQUENT_CHECK; +} +#endif + +#if EV_FORK_ENABLE +void +ev_fork_start (EV_P_ ev_fork *w) EV_NOEXCEPT +{ + if (ecb_expect_false (ev_is_active (w))) + return; + + EV_FREQUENT_CHECK; + + ev_start (EV_A_ (W)w, ++forkcnt); + array_needsize (ev_fork *, forks, forkmax, forkcnt, array_needsize_noinit); + forks [forkcnt - 1] = w; + + EV_FREQUENT_CHECK; +} + +void +ev_fork_stop (EV_P_ ev_fork *w) EV_NOEXCEPT +{ + clear_pending (EV_A_ (W)w); + if (ecb_expect_false (!ev_is_active (w))) + return; + + EV_FREQUENT_CHECK; + + { + int active = ev_active (w); + + forks [active - 1] = forks [--forkcnt]; + ev_active (forks [active - 1]) = active; + } + + ev_stop (EV_A_ (W)w); + + EV_FREQUENT_CHECK; +} +#endif + +#if EV_CLEANUP_ENABLE +void +ev_cleanup_start (EV_P_ ev_cleanup *w) EV_NOEXCEPT +{ + if (ecb_expect_false (ev_is_active (w))) + return; + + EV_FREQUENT_CHECK; + + ev_start (EV_A_ (W)w, ++cleanupcnt); + array_needsize (ev_cleanup *, cleanups, cleanupmax, cleanupcnt, array_needsize_noinit); + cleanups [cleanupcnt - 1] = w; + + /* cleanup watchers should never keep a refcount on the loop */ + ev_unref (EV_A); + EV_FREQUENT_CHECK; +} + +void +ev_cleanup_stop (EV_P_ ev_cleanup *w) EV_NOEXCEPT +{ + clear_pending (EV_A_ (W)w); + if (ecb_expect_false (!ev_is_active (w))) + return; + + EV_FREQUENT_CHECK; + ev_ref (EV_A); + + { + int active = ev_active (w); + + cleanups [active - 1] = cleanups [--cleanupcnt]; + ev_active (cleanups [active - 1]) = active; + } + + ev_stop (EV_A_ (W)w); + + EV_FREQUENT_CHECK; +} +#endif + +#if EV_ASYNC_ENABLE +void +ev_async_start (EV_P_ ev_async *w) EV_NOEXCEPT +{ + if (ecb_expect_false (ev_is_active (w))) + return; + + w->sent = 0; + + evpipe_init (EV_A); + + EV_FREQUENT_CHECK; + + ev_start (EV_A_ (W)w, ++asynccnt); + array_needsize (ev_async *, asyncs, asyncmax, asynccnt, array_needsize_noinit); + asyncs [asynccnt - 1] = w; + + EV_FREQUENT_CHECK; +} + +void +ev_async_stop (EV_P_ ev_async *w) EV_NOEXCEPT +{ + clear_pending (EV_A_ (W)w); + if (ecb_expect_false (!ev_is_active (w))) + return; + + EV_FREQUENT_CHECK; + + { + int active = ev_active (w); + + asyncs [active - 1] = asyncs [--asynccnt]; + ev_active (asyncs [active - 1]) = active; + } + + ev_stop (EV_A_ (W)w); + + EV_FREQUENT_CHECK; +} + +void +ev_async_send (EV_P_ ev_async *w) EV_NOEXCEPT +{ + w->sent = 1; + evpipe_write (EV_A_ &async_pending); +} +#endif + +/*****************************************************************************/ + +struct ev_once +{ + ev_io io; + ev_timer to; + void (*cb)(int revents, void *arg); + void *arg; +}; + +static void +once_cb (EV_P_ struct ev_once *once, int revents) +{ + void (*cb)(int revents, void *arg) = once->cb; + void *arg = once->arg; + + ev_io_stop (EV_A_ &once->io); + ev_timer_stop (EV_A_ &once->to); + ev_free (once); + + cb (revents, arg); +} + +static void +once_cb_io (EV_P_ ev_io *w, int revents) +{ + struct ev_once *once = (struct ev_once *)(((char *)w) - offsetof (struct ev_once, io)); + + once_cb (EV_A_ once, revents | ev_clear_pending (EV_A_ &once->to)); +} + +static void +once_cb_to (EV_P_ ev_timer *w, int revents) +{ + struct ev_once *once = (struct ev_once *)(((char *)w) - offsetof (struct ev_once, to)); + + once_cb (EV_A_ once, revents | ev_clear_pending (EV_A_ &once->io)); +} + +void +ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg) EV_NOEXCEPT +{ + struct ev_once *once = (struct ev_once *)ev_malloc (sizeof (struct ev_once)); + + once->cb = cb; + once->arg = arg; + + ev_init (&once->io, once_cb_io); + if (fd >= 0) + { + ev_io_set (&once->io, fd, events); + ev_io_start (EV_A_ &once->io); + } + + ev_init (&once->to, once_cb_to); + if (timeout >= 0.) + { + ev_timer_set (&once->to, timeout, 0.); + ev_timer_start (EV_A_ &once->to); + } +} + +/*****************************************************************************/ + +#if EV_WALK_ENABLE +ecb_cold +void +ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w)) EV_NOEXCEPT +{ + int i, j; + ev_watcher_list *wl, *wn; + + if (types & (EV_IO | EV_EMBED)) + for (i = 0; i < anfdmax; ++i) + for (wl = anfds [i].head; wl; ) + { + wn = wl->next; + +#if EV_EMBED_ENABLE + if (ev_cb ((ev_io *)wl) == embed_io_cb) + { + if (types & EV_EMBED) + cb (EV_A_ EV_EMBED, ((char *)wl) - offsetof (struct ev_embed, io)); + } + else +#endif +#if EV_USE_INOTIFY + if (ev_cb ((ev_io *)wl) == infy_cb) + ; + else +#endif + if ((ev_io *)wl != &pipe_w) + if (types & EV_IO) + cb (EV_A_ EV_IO, wl); + + wl = wn; + } + + if (types & (EV_TIMER | EV_STAT)) + for (i = timercnt + HEAP0; i-- > HEAP0; ) +#if EV_STAT_ENABLE + /*TODO: timer is not always active*/ + if (ev_cb ((ev_timer *)ANHE_w (timers [i])) == stat_timer_cb) + { + if (types & EV_STAT) + cb (EV_A_ EV_STAT, ((char *)ANHE_w (timers [i])) - offsetof (struct ev_stat, timer)); + } + else +#endif + if (types & EV_TIMER) + cb (EV_A_ EV_TIMER, ANHE_w (timers [i])); + +#if EV_PERIODIC_ENABLE + if (types & EV_PERIODIC) + for (i = periodiccnt + HEAP0; i-- > HEAP0; ) + cb (EV_A_ EV_PERIODIC, ANHE_w (periodics [i])); +#endif + +#if EV_IDLE_ENABLE + if (types & EV_IDLE) + for (j = NUMPRI; j--; ) + for (i = idlecnt [j]; i--; ) + cb (EV_A_ EV_IDLE, idles [j][i]); +#endif + +#if EV_FORK_ENABLE + if (types & EV_FORK) + for (i = forkcnt; i--; ) + if (ev_cb (forks [i]) != embed_fork_cb) + cb (EV_A_ EV_FORK, forks [i]); +#endif + +#if EV_ASYNC_ENABLE + if (types & EV_ASYNC) + for (i = asynccnt; i--; ) + cb (EV_A_ EV_ASYNC, asyncs [i]); +#endif + +#if EV_PREPARE_ENABLE + if (types & EV_PREPARE) + for (i = preparecnt; i--; ) +# if EV_EMBED_ENABLE + if (ev_cb (prepares [i]) != embed_prepare_cb) +# endif + cb (EV_A_ EV_PREPARE, prepares [i]); +#endif + +#if EV_CHECK_ENABLE + if (types & EV_CHECK) + for (i = checkcnt; i--; ) + cb (EV_A_ EV_CHECK, checks [i]); +#endif + +#if EV_SIGNAL_ENABLE + if (types & EV_SIGNAL) + for (i = 0; i < EV_NSIG - 1; ++i) + for (wl = signals [i].head; wl; ) + { + wn = wl->next; + cb (EV_A_ EV_SIGNAL, wl); + wl = wn; + } +#endif + +#if EV_CHILD_ENABLE + if (types & EV_CHILD) + for (i = (EV_PID_HASHSIZE); i--; ) + for (wl = childs [i]; wl; ) + { + wn = wl->next; + cb (EV_A_ EV_CHILD, wl); + wl = wn; + } +#endif +/* EV_STAT 0x00001000 /* stat data changed */ +/* EV_EMBED 0x00010000 /* embedded event loop needs sweep */ +} +#endif + +#if EV_MULTIPLICITY + #include "ev_wrap.h" +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev.h b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev.h new file mode 100644 index 00000000..e6162167 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev.h @@ -0,0 +1,859 @@ +/* + * libev native API header + * + * Copyright (c) 2007-2020 Marc Alexander Lehmann + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License ("GPL") version 2 or any later version, + * in which case the provisions of the GPL are applicable instead of + * the above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the BSD license, indicate your decision + * by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file under + * either the BSD or the GPL. + */ + +#ifndef EV_H_ +#define EV_H_ + +#ifdef __cplusplus +# define EV_CPP(x) x +# if __cplusplus >= 201103L +# define EV_NOEXCEPT noexcept +# else +# define EV_NOEXCEPT +# endif +#else +# define EV_CPP(x) +# define EV_NOEXCEPT +#endif +#define EV_THROW EV_NOEXCEPT /* pre-4.25, do not use in new code */ + +EV_CPP(extern "C" {) + +/*****************************************************************************/ + +/* pre-4.0 compatibility */ +#ifndef EV_COMPAT3 +# define EV_COMPAT3 1 +#endif + +#ifndef EV_FEATURES +# if defined __OPTIMIZE_SIZE__ +# define EV_FEATURES 0x7c +# else +# define EV_FEATURES 0x7f +# endif +#endif + +#define EV_FEATURE_CODE ((EV_FEATURES) & 1) +#define EV_FEATURE_DATA ((EV_FEATURES) & 2) +#define EV_FEATURE_CONFIG ((EV_FEATURES) & 4) +#define EV_FEATURE_API ((EV_FEATURES) & 8) +#define EV_FEATURE_WATCHERS ((EV_FEATURES) & 16) +#define EV_FEATURE_BACKENDS ((EV_FEATURES) & 32) +#define EV_FEATURE_OS ((EV_FEATURES) & 64) + +/* these priorities are inclusive, higher priorities will be invoked earlier */ +#ifndef EV_MINPRI +# define EV_MINPRI (EV_FEATURE_CONFIG ? -2 : 0) +#endif +#ifndef EV_MAXPRI +# define EV_MAXPRI (EV_FEATURE_CONFIG ? +2 : 0) +#endif + +#ifndef EV_MULTIPLICITY +# define EV_MULTIPLICITY EV_FEATURE_CONFIG +#endif + +#ifndef EV_PERIODIC_ENABLE +# define EV_PERIODIC_ENABLE EV_FEATURE_WATCHERS +#endif + +#ifndef EV_STAT_ENABLE +# define EV_STAT_ENABLE EV_FEATURE_WATCHERS +#endif + +#ifndef EV_PREPARE_ENABLE +# define EV_PREPARE_ENABLE EV_FEATURE_WATCHERS +#endif + +#ifndef EV_CHECK_ENABLE +# define EV_CHECK_ENABLE EV_FEATURE_WATCHERS +#endif + +#ifndef EV_IDLE_ENABLE +# define EV_IDLE_ENABLE EV_FEATURE_WATCHERS +#endif + +#ifndef EV_FORK_ENABLE +# define EV_FORK_ENABLE EV_FEATURE_WATCHERS +#endif + +#ifndef EV_CLEANUP_ENABLE +# define EV_CLEANUP_ENABLE EV_FEATURE_WATCHERS +#endif + +#ifndef EV_SIGNAL_ENABLE +# define EV_SIGNAL_ENABLE EV_FEATURE_WATCHERS +#endif + +#ifndef EV_CHILD_ENABLE +# ifdef _WIN32 +# define EV_CHILD_ENABLE 0 +# else +# define EV_CHILD_ENABLE EV_FEATURE_WATCHERS +#endif +#endif + +#ifndef EV_ASYNC_ENABLE +# define EV_ASYNC_ENABLE EV_FEATURE_WATCHERS +#endif + +#ifndef EV_EMBED_ENABLE +# define EV_EMBED_ENABLE EV_FEATURE_WATCHERS +#endif + +#ifndef EV_WALK_ENABLE +# define EV_WALK_ENABLE 0 /* not yet */ +#endif + +/*****************************************************************************/ + +#if EV_CHILD_ENABLE && !EV_SIGNAL_ENABLE +# undef EV_SIGNAL_ENABLE +# define EV_SIGNAL_ENABLE 1 +#endif + +/*****************************************************************************/ + +#ifndef EV_TSTAMP_T +# define EV_TSTAMP_T double +#endif +typedef EV_TSTAMP_T ev_tstamp; + +#include /* for memmove */ + +#ifndef EV_ATOMIC_T +# include +# define EV_ATOMIC_T sig_atomic_t volatile +#endif + +#if EV_STAT_ENABLE +# ifdef _WIN32 +# include +# include +# endif +# include +#endif + +/* support multiple event loops? */ +#if EV_MULTIPLICITY +struct ev_loop; +# define EV_P struct ev_loop *loop /* a loop as sole parameter in a declaration */ +# define EV_P_ EV_P, /* a loop as first of multiple parameters */ +# define EV_A loop /* a loop as sole argument to a function call */ +# define EV_A_ EV_A, /* a loop as first of multiple arguments */ +# define EV_DEFAULT_UC ev_default_loop_uc_ () /* the default loop, if initialised, as sole arg */ +# define EV_DEFAULT_UC_ EV_DEFAULT_UC, /* the default loop as first of multiple arguments */ +# define EV_DEFAULT ev_default_loop (0) /* the default loop as sole arg */ +# define EV_DEFAULT_ EV_DEFAULT, /* the default loop as first of multiple arguments */ +#else +# define EV_P void +# define EV_P_ +# define EV_A +# define EV_A_ +# define EV_DEFAULT +# define EV_DEFAULT_ +# define EV_DEFAULT_UC +# define EV_DEFAULT_UC_ +# undef EV_EMBED_ENABLE +#endif + +/* EV_INLINE is used for functions in header files */ +#if __STDC_VERSION__ >= 199901L || __GNUC__ >= 3 +# define EV_INLINE static inline +#else +# define EV_INLINE static +#endif + +#ifdef EV_API_STATIC +# define EV_API_DECL static +#else +# define EV_API_DECL extern +#endif + +/* EV_PROTOTYPES can be used to switch of prototype declarations */ +#ifndef EV_PROTOTYPES +# define EV_PROTOTYPES 1 +#endif + +/*****************************************************************************/ + +#define EV_VERSION_MAJOR 4 +#define EV_VERSION_MINOR 33 + +/* eventmask, revents, events... */ +enum { + EV_UNDEF = (int)0xFFFFFFFF, /* guaranteed to be invalid */ + EV_NONE = 0x00, /* no events */ + EV_READ = 0x01, /* ev_io detected read will not block */ + EV_WRITE = 0x02, /* ev_io detected write will not block */ + EV__IOFDSET = 0x80, /* internal use only */ + EV_IO = EV_READ, /* alias for type-detection */ + EV_TIMER = 0x00000100, /* timer timed out */ +#if EV_COMPAT3 + EV_TIMEOUT = EV_TIMER, /* pre 4.0 API compatibility */ +#endif + EV_PERIODIC = 0x00000200, /* periodic timer timed out */ + EV_SIGNAL = 0x00000400, /* signal was received */ + EV_CHILD = 0x00000800, /* child/pid had status change */ + EV_STAT = 0x00001000, /* stat data changed */ + EV_IDLE = 0x00002000, /* event loop is idling */ + EV_PREPARE = 0x00004000, /* event loop about to poll */ + EV_CHECK = 0x00008000, /* event loop finished poll */ + EV_EMBED = 0x00010000, /* embedded event loop needs sweep */ + EV_FORK = 0x00020000, /* event loop resumed in child */ + EV_CLEANUP = 0x00040000, /* event loop resumed in child */ + EV_ASYNC = 0x00080000, /* async intra-loop signal */ + EV_CUSTOM = 0x01000000, /* for use by user code */ + EV_ERROR = (int)0x80000000 /* sent when an error occurs */ +}; + +/* can be used to add custom fields to all watchers, while losing binary compatibility */ +#ifndef EV_COMMON +# define EV_COMMON void *data; +#endif + +#ifndef EV_CB_DECLARE +# define EV_CB_DECLARE(type) void (*cb)(EV_P_ struct type *w, int revents); +#endif +#ifndef EV_CB_INVOKE +# define EV_CB_INVOKE(watcher,revents) (watcher)->cb (EV_A_ (watcher), (revents)) +#endif + +/* not official, do not use */ +#define EV_CB(type,name) void name (EV_P_ struct ev_ ## type *w, int revents) + +/* + * struct member types: + * private: you may look at them, but not change them, + * and they might not mean anything to you. + * ro: can be read anytime, but only changed when the watcher isn't active. + * rw: can be read and modified anytime, even when the watcher is active. + * + * some internal details that might be helpful for debugging: + * + * active is either 0, which means the watcher is not active, + * or the array index of the watcher (periodics, timers) + * or the array index + 1 (most other watchers) + * or simply 1 for watchers that aren't in some array. + * pending is either 0, in which case the watcher isn't, + * or the array index + 1 in the pendings array. + */ + +#if EV_MINPRI == EV_MAXPRI +# define EV_DECL_PRIORITY +#elif !defined (EV_DECL_PRIORITY) +# define EV_DECL_PRIORITY int priority; +#endif + +/* shared by all watchers */ +#define EV_WATCHER(type) \ + int active; /* private */ \ + int pending; /* private */ \ + EV_DECL_PRIORITY /* private */ \ + EV_COMMON /* rw */ \ + EV_CB_DECLARE (type) /* private */ + +#define EV_WATCHER_LIST(type) \ + EV_WATCHER (type) \ + struct ev_watcher_list *next; /* private */ + +#define EV_WATCHER_TIME(type) \ + EV_WATCHER (type) \ + ev_tstamp at; /* private */ + +/* base class, nothing to see here unless you subclass */ +typedef struct ev_watcher +{ + EV_WATCHER (ev_watcher) +} ev_watcher; + +/* base class, nothing to see here unless you subclass */ +typedef struct ev_watcher_list +{ + EV_WATCHER_LIST (ev_watcher_list) +} ev_watcher_list; + +/* base class, nothing to see here unless you subclass */ +typedef struct ev_watcher_time +{ + EV_WATCHER_TIME (ev_watcher_time) +} ev_watcher_time; + +/* invoked when fd is either EV_READable or EV_WRITEable */ +/* revent EV_READ, EV_WRITE */ +typedef struct ev_io +{ + EV_WATCHER_LIST (ev_io) + + int fd; /* ro */ + int events; /* ro */ +} ev_io; + +/* invoked after a specific time, repeatable (based on monotonic clock) */ +/* revent EV_TIMEOUT */ +typedef struct ev_timer +{ + EV_WATCHER_TIME (ev_timer) + + ev_tstamp repeat; /* rw */ +} ev_timer; + +/* invoked at some specific time, possibly repeating at regular intervals (based on UTC) */ +/* revent EV_PERIODIC */ +typedef struct ev_periodic +{ + EV_WATCHER_TIME (ev_periodic) + + ev_tstamp offset; /* rw */ + ev_tstamp interval; /* rw */ + ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now) EV_NOEXCEPT; /* rw */ +} ev_periodic; + +/* invoked when the given signal has been received */ +/* revent EV_SIGNAL */ +typedef struct ev_signal +{ + EV_WATCHER_LIST (ev_signal) + + int signum; /* ro */ +} ev_signal; + +/* invoked when sigchld is received and waitpid indicates the given pid */ +/* revent EV_CHILD */ +/* does not support priorities */ +typedef struct ev_child +{ + EV_WATCHER_LIST (ev_child) + + int flags; /* private */ + int pid; /* ro */ + int rpid; /* rw, holds the received pid */ + int rstatus; /* rw, holds the exit status, use the macros from sys/wait.h */ +} ev_child; + +#if EV_STAT_ENABLE +/* st_nlink = 0 means missing file or other error */ +# ifdef _WIN32 +typedef struct _stati64 ev_statdata; +# else +typedef struct stat ev_statdata; +# endif + +/* invoked each time the stat data changes for a given path */ +/* revent EV_STAT */ +typedef struct ev_stat +{ + EV_WATCHER_LIST (ev_stat) + + ev_timer timer; /* private */ + ev_tstamp interval; /* ro */ + const char *path; /* ro */ + ev_statdata prev; /* ro */ + ev_statdata attr; /* ro */ + + int wd; /* wd for inotify, fd for kqueue */ +} ev_stat; +#endif + +/* invoked when the nothing else needs to be done, keeps the process from blocking */ +/* revent EV_IDLE */ +typedef struct ev_idle +{ + EV_WATCHER (ev_idle) +} ev_idle; + +/* invoked for each run of the mainloop, just before the blocking call */ +/* you can still change events in any way you like */ +/* revent EV_PREPARE */ +typedef struct ev_prepare +{ + EV_WATCHER (ev_prepare) +} ev_prepare; + +/* invoked for each run of the mainloop, just after the blocking call */ +/* revent EV_CHECK */ +typedef struct ev_check +{ + EV_WATCHER (ev_check) +} ev_check; + +/* the callback gets invoked before check in the child process when a fork was detected */ +/* revent EV_FORK */ +typedef struct ev_fork +{ + EV_WATCHER (ev_fork) +} ev_fork; + +/* is invoked just before the loop gets destroyed */ +/* revent EV_CLEANUP */ +typedef struct ev_cleanup +{ + EV_WATCHER (ev_cleanup) +} ev_cleanup; + +#if EV_EMBED_ENABLE +/* used to embed an event loop inside another */ +/* the callback gets invoked when the event loop has handled events, and can be 0 */ +typedef struct ev_embed +{ + EV_WATCHER (ev_embed) + + struct ev_loop *other; /* ro */ +#undef EV_IO_ENABLE +#define EV_IO_ENABLE 1 + ev_io io; /* private */ +#undef EV_PREPARE_ENABLE +#define EV_PREPARE_ENABLE 1 + ev_prepare prepare; /* private */ + ev_check check; /* unused */ + ev_timer timer; /* unused */ + ev_periodic periodic; /* unused */ + ev_idle idle; /* unused */ + ev_fork fork; /* private */ + ev_cleanup cleanup; /* unused */ +} ev_embed; +#endif + +#if EV_ASYNC_ENABLE +/* invoked when somebody calls ev_async_send on the watcher */ +/* revent EV_ASYNC */ +typedef struct ev_async +{ + EV_WATCHER (ev_async) + + EV_ATOMIC_T sent; /* private */ +} ev_async; + +# define ev_async_pending(w) (+(w)->sent) +#endif + +/* the presence of this union forces similar struct layout */ +union ev_any_watcher +{ + struct ev_watcher w; + struct ev_watcher_list wl; + + struct ev_io io; + struct ev_timer timer; + struct ev_periodic periodic; + struct ev_signal signal; + struct ev_child child; +#if EV_STAT_ENABLE + struct ev_stat stat; +#endif +#if EV_IDLE_ENABLE + struct ev_idle idle; +#endif + struct ev_prepare prepare; + struct ev_check check; +#if EV_FORK_ENABLE + struct ev_fork fork; +#endif +#if EV_CLEANUP_ENABLE + struct ev_cleanup cleanup; +#endif +#if EV_EMBED_ENABLE + struct ev_embed embed; +#endif +#if EV_ASYNC_ENABLE + struct ev_async async; +#endif +}; + +/* flag bits for ev_default_loop and ev_loop_new */ +enum { + /* the default */ + EVFLAG_AUTO = 0x00000000U, /* not quite a mask */ + /* flag bits */ + EVFLAG_NOENV = 0x01000000U, /* do NOT consult environment */ + EVFLAG_FORKCHECK = 0x02000000U, /* check for a fork in each iteration */ + /* debugging/feature disable */ + EVFLAG_NOINOTIFY = 0x00100000U, /* do not attempt to use inotify */ +#if EV_COMPAT3 + EVFLAG_NOSIGFD = 0, /* compatibility to pre-3.9 */ +#endif + EVFLAG_SIGNALFD = 0x00200000U, /* attempt to use signalfd */ + EVFLAG_NOSIGMASK = 0x00400000U, /* avoid modifying the signal mask */ + EVFLAG_NOTIMERFD = 0x00800000U /* avoid creating a timerfd */ +}; + +/* method bits to be ored together */ +enum { + EVBACKEND_SELECT = 0x00000001U, /* available just about anywhere */ + EVBACKEND_POLL = 0x00000002U, /* !win, !aix, broken on osx */ + EVBACKEND_EPOLL = 0x00000004U, /* linux */ + EVBACKEND_KQUEUE = 0x00000008U, /* bsd, broken on osx */ + EVBACKEND_DEVPOLL = 0x00000010U, /* solaris 8 */ /* NYI */ + EVBACKEND_PORT = 0x00000020U, /* solaris 10 */ + EVBACKEND_LINUXAIO = 0x00000040U, /* linux AIO, 4.19+ */ + EVBACKEND_IOURING = 0x00000080U, /* linux io_uring, 5.1+ */ + EVBACKEND_ALL = 0x000000FFU, /* all known backends */ + EVBACKEND_MASK = 0x0000FFFFU /* all future backends */ +}; + +#if EV_PROTOTYPES +EV_API_DECL int ev_version_major (void) EV_NOEXCEPT; +EV_API_DECL int ev_version_minor (void) EV_NOEXCEPT; + +EV_API_DECL unsigned int ev_supported_backends (void) EV_NOEXCEPT; +EV_API_DECL unsigned int ev_recommended_backends (void) EV_NOEXCEPT; +EV_API_DECL unsigned int ev_embeddable_backends (void) EV_NOEXCEPT; + +EV_API_DECL ev_tstamp ev_time (void) EV_NOEXCEPT; +EV_API_DECL void ev_sleep (ev_tstamp delay) EV_NOEXCEPT; /* sleep for a while */ + +/* Sets the allocation function to use, works like realloc. + * It is used to allocate and free memory. + * If it returns zero when memory needs to be allocated, the library might abort + * or take some potentially destructive action. + * The default is your system realloc function. + */ +EV_API_DECL void ev_set_allocator (void *(*cb)(void *ptr, size_t size) EV_NOEXCEPT) EV_NOEXCEPT; + +/* set the callback function to call on a + * retryable syscall error + * (such as failed select, poll, epoll_wait) + */ +EV_API_DECL void ev_set_syserr_cb (void (*cb)(const char *msg) EV_NOEXCEPT) EV_NOEXCEPT; + +#if EV_MULTIPLICITY + +/* the default loop is the only one that handles signals and child watchers */ +/* you can call this as often as you like */ +EV_API_DECL struct ev_loop *ev_default_loop (unsigned int flags EV_CPP (= 0)) EV_NOEXCEPT; + +#ifdef EV_API_STATIC +EV_API_DECL struct ev_loop *ev_default_loop_ptr; +#endif + +EV_INLINE struct ev_loop * +ev_default_loop_uc_ (void) EV_NOEXCEPT +{ + extern struct ev_loop *ev_default_loop_ptr; + + return ev_default_loop_ptr; +} + +EV_INLINE int +ev_is_default_loop (EV_P) EV_NOEXCEPT +{ + return EV_A == EV_DEFAULT_UC; +} + +/* create and destroy alternative loops that don't handle signals */ +EV_API_DECL struct ev_loop *ev_loop_new (unsigned int flags EV_CPP (= 0)) EV_NOEXCEPT; + +EV_API_DECL ev_tstamp ev_now (EV_P) EV_NOEXCEPT; /* time w.r.t. timers and the eventloop, updated after each poll */ + +#else + +EV_API_DECL int ev_default_loop (unsigned int flags EV_CPP (= 0)) EV_NOEXCEPT; /* returns true when successful */ + +EV_API_DECL ev_tstamp ev_rt_now; + +EV_INLINE ev_tstamp +ev_now (void) EV_NOEXCEPT +{ + return ev_rt_now; +} + +/* looks weird, but ev_is_default_loop (EV_A) still works if this exists */ +EV_INLINE int +ev_is_default_loop (void) EV_NOEXCEPT +{ + return 1; +} + +#endif /* multiplicity */ + +/* destroy event loops, also works for the default loop */ +EV_API_DECL void ev_loop_destroy (EV_P); + +/* this needs to be called after fork, to duplicate the loop */ +/* when you want to re-use it in the child */ +/* you can call it in either the parent or the child */ +/* you can actually call it at any time, anywhere :) */ +EV_API_DECL void ev_loop_fork (EV_P) EV_NOEXCEPT; + +EV_API_DECL unsigned int ev_backend (EV_P) EV_NOEXCEPT; /* backend in use by loop */ + +EV_API_DECL void ev_now_update (EV_P) EV_NOEXCEPT; /* update event loop time */ + +#if EV_WALK_ENABLE +/* walk (almost) all watchers in the loop of a given type, invoking the */ +/* callback on every such watcher. The callback might stop the watcher, */ +/* but do nothing else with the loop */ +EV_API_DECL void ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w)) EV_NOEXCEPT; +#endif + +#endif /* prototypes */ + +/* ev_run flags values */ +enum { + EVRUN_NOWAIT = 1, /* do not block/wait */ + EVRUN_ONCE = 2 /* block *once* only */ +}; + +/* ev_break how values */ +enum { + EVBREAK_CANCEL = 0, /* undo unloop */ + EVBREAK_ONE = 1, /* unloop once */ + EVBREAK_ALL = 2 /* unloop all loops */ +}; + +#if EV_PROTOTYPES +EV_API_DECL int ev_run (EV_P_ int flags EV_CPP (= 0)); +EV_API_DECL void ev_break (EV_P_ int how EV_CPP (= EVBREAK_ONE)) EV_NOEXCEPT; /* break out of the loop */ + +/* + * ref/unref can be used to add or remove a refcount on the mainloop. every watcher + * keeps one reference. if you have a long-running watcher you never unregister that + * should not keep ev_loop from running, unref() after starting, and ref() before stopping. + */ +EV_API_DECL void ev_ref (EV_P) EV_NOEXCEPT; +EV_API_DECL void ev_unref (EV_P) EV_NOEXCEPT; + +/* + * convenience function, wait for a single event, without registering an event watcher + * if timeout is < 0, do wait indefinitely + */ +EV_API_DECL void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg) EV_NOEXCEPT; + +EV_API_DECL void ev_invoke_pending (EV_P); /* invoke all pending watchers */ + +# if EV_FEATURE_API +EV_API_DECL unsigned int ev_iteration (EV_P) EV_NOEXCEPT; /* number of loop iterations */ +EV_API_DECL unsigned int ev_depth (EV_P) EV_NOEXCEPT; /* #ev_loop enters - #ev_loop leaves */ +EV_API_DECL void ev_verify (EV_P) EV_NOEXCEPT; /* abort if loop data corrupted */ + +EV_API_DECL void ev_set_io_collect_interval (EV_P_ ev_tstamp interval) EV_NOEXCEPT; /* sleep at least this time, default 0 */ +EV_API_DECL void ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval) EV_NOEXCEPT; /* sleep at least this time, default 0 */ + +/* advanced stuff for threading etc. support, see docs */ +EV_API_DECL void ev_set_userdata (EV_P_ void *data) EV_NOEXCEPT; +EV_API_DECL void *ev_userdata (EV_P) EV_NOEXCEPT; +typedef void (*ev_loop_callback)(EV_P); +EV_API_DECL void ev_set_invoke_pending_cb (EV_P_ ev_loop_callback invoke_pending_cb) EV_NOEXCEPT; +/* C++ doesn't allow the use of the ev_loop_callback typedef here, so we need to spell it out */ +EV_API_DECL void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P) EV_NOEXCEPT, void (*acquire)(EV_P) EV_NOEXCEPT) EV_NOEXCEPT; + +EV_API_DECL unsigned int ev_pending_count (EV_P) EV_NOEXCEPT; /* number of pending events, if any */ + +/* + * stop/start the timer handling. + */ +EV_API_DECL void ev_suspend (EV_P) EV_NOEXCEPT; +EV_API_DECL void ev_resume (EV_P) EV_NOEXCEPT; +#endif + +#endif + +/* these may evaluate ev multiple times, and the other arguments at most once */ +/* either use ev_init + ev_TYPE_set, or the ev_TYPE_init macro, below, to first initialise a watcher */ +#define ev_init(ev,cb_) do { \ + ((ev_watcher *)(void *)(ev))->active = \ + ((ev_watcher *)(void *)(ev))->pending = 0; \ + ev_set_priority ((ev), 0); \ + ev_set_cb ((ev), cb_); \ +} while (0) + +#define ev_io_modify(ev,events_) do { (ev)->events = (ev)->events & EV__IOFDSET | (events_); } while (0) +#define ev_io_set(ev,fd_,events_) do { (ev)->fd = (fd_); (ev)->events = (events_) | EV__IOFDSET; } while (0) +#define ev_timer_set(ev,after_,repeat_) do { ((ev_watcher_time *)(ev))->at = (after_); (ev)->repeat = (repeat_); } while (0) +#define ev_periodic_set(ev,ofs_,ival_,rcb_) do { (ev)->offset = (ofs_); (ev)->interval = (ival_); (ev)->reschedule_cb = (rcb_); } while (0) +#define ev_signal_set(ev,signum_) do { (ev)->signum = (signum_); } while (0) +#define ev_child_set(ev,pid_,trace_) do { (ev)->pid = (pid_); (ev)->flags = !!(trace_); } while (0) +#define ev_stat_set(ev,path_,interval_) do { (ev)->path = (path_); (ev)->interval = (interval_); (ev)->wd = -2; } while (0) +#define ev_idle_set(ev) /* nop, yes, this is a serious in-joke */ +#define ev_prepare_set(ev) /* nop, yes, this is a serious in-joke */ +#define ev_check_set(ev) /* nop, yes, this is a serious in-joke */ +#define ev_embed_set(ev,other_) do { (ev)->other = (other_); } while (0) +#define ev_fork_set(ev) /* nop, yes, this is a serious in-joke */ +#define ev_cleanup_set(ev) /* nop, yes, this is a serious in-joke */ +#define ev_async_set(ev) /* nop, yes, this is a serious in-joke */ + +#define ev_io_init(ev,cb,fd,events) do { ev_init ((ev), (cb)); ev_io_set ((ev),(fd),(events)); } while (0) +#define ev_timer_init(ev,cb,after,repeat) do { ev_init ((ev), (cb)); ev_timer_set ((ev),(after),(repeat)); } while (0) +#define ev_periodic_init(ev,cb,ofs,ival,rcb) do { ev_init ((ev), (cb)); ev_periodic_set ((ev),(ofs),(ival),(rcb)); } while (0) +#define ev_signal_init(ev,cb,signum) do { ev_init ((ev), (cb)); ev_signal_set ((ev), (signum)); } while (0) +#define ev_child_init(ev,cb,pid,trace) do { ev_init ((ev), (cb)); ev_child_set ((ev),(pid),(trace)); } while (0) +#define ev_stat_init(ev,cb,path,interval) do { ev_init ((ev), (cb)); ev_stat_set ((ev),(path),(interval)); } while (0) +#define ev_idle_init(ev,cb) do { ev_init ((ev), (cb)); ev_idle_set ((ev)); } while (0) +#define ev_prepare_init(ev,cb) do { ev_init ((ev), (cb)); ev_prepare_set ((ev)); } while (0) +#define ev_check_init(ev,cb) do { ev_init ((ev), (cb)); ev_check_set ((ev)); } while (0) +#define ev_embed_init(ev,cb,other) do { ev_init ((ev), (cb)); ev_embed_set ((ev),(other)); } while (0) +#define ev_fork_init(ev,cb) do { ev_init ((ev), (cb)); ev_fork_set ((ev)); } while (0) +#define ev_cleanup_init(ev,cb) do { ev_init ((ev), (cb)); ev_cleanup_set ((ev)); } while (0) +#define ev_async_init(ev,cb) do { ev_init ((ev), (cb)); ev_async_set ((ev)); } while (0) + +#define ev_is_pending(ev) (0 + ((ev_watcher *)(void *)(ev))->pending) /* ro, true when watcher is waiting for callback invocation */ +#define ev_is_active(ev) (0 + ((ev_watcher *)(void *)(ev))->active) /* ro, true when the watcher has been started */ + +#define ev_cb_(ev) (ev)->cb /* rw */ +#define ev_cb(ev) (memmove (&ev_cb_ (ev), &((ev_watcher *)(ev))->cb, sizeof (ev_cb_ (ev))), (ev)->cb) + +#if EV_MINPRI == EV_MAXPRI +# define ev_priority(ev) ((ev), EV_MINPRI) +# define ev_set_priority(ev,pri) ((ev), (pri)) +#else +# define ev_priority(ev) (+(((ev_watcher *)(void *)(ev))->priority)) +# define ev_set_priority(ev,pri) ( (ev_watcher *)(void *)(ev))->priority = (pri) +#endif + +#define ev_periodic_at(ev) (+((ev_watcher_time *)(ev))->at) + +#ifndef ev_set_cb +/* memmove is used here to avoid strict aliasing violations, and hopefully is optimized out by any reasonable compiler */ +# define ev_set_cb(ev,cb_) (ev_cb_ (ev) = (cb_), memmove (&((ev_watcher *)(ev))->cb, &ev_cb_ (ev), sizeof (ev_cb_ (ev)))) +#endif + +/* stopping (enabling, adding) a watcher does nothing if it is already running */ +/* stopping (disabling, deleting) a watcher does nothing unless it's already running */ +#if EV_PROTOTYPES + +/* feeds an event into a watcher as if the event actually occurred */ +/* accepts any ev_watcher type */ +EV_API_DECL void ev_feed_event (EV_P_ void *w, int revents) EV_NOEXCEPT; +EV_API_DECL void ev_feed_fd_event (EV_P_ int fd, int revents) EV_NOEXCEPT; +#if EV_SIGNAL_ENABLE +EV_API_DECL void ev_feed_signal (int signum) EV_NOEXCEPT; +EV_API_DECL void ev_feed_signal_event (EV_P_ int signum) EV_NOEXCEPT; +#endif +EV_API_DECL void ev_invoke (EV_P_ void *w, int revents); +EV_API_DECL int ev_clear_pending (EV_P_ void *w) EV_NOEXCEPT; + +EV_API_DECL void ev_io_start (EV_P_ ev_io *w) EV_NOEXCEPT; +EV_API_DECL void ev_io_stop (EV_P_ ev_io *w) EV_NOEXCEPT; + +EV_API_DECL void ev_timer_start (EV_P_ ev_timer *w) EV_NOEXCEPT; +EV_API_DECL void ev_timer_stop (EV_P_ ev_timer *w) EV_NOEXCEPT; +/* stops if active and no repeat, restarts if active and repeating, starts if inactive and repeating */ +EV_API_DECL void ev_timer_again (EV_P_ ev_timer *w) EV_NOEXCEPT; +/* return remaining time */ +EV_API_DECL ev_tstamp ev_timer_remaining (EV_P_ ev_timer *w) EV_NOEXCEPT; + +#if EV_PERIODIC_ENABLE +EV_API_DECL void ev_periodic_start (EV_P_ ev_periodic *w) EV_NOEXCEPT; +EV_API_DECL void ev_periodic_stop (EV_P_ ev_periodic *w) EV_NOEXCEPT; +EV_API_DECL void ev_periodic_again (EV_P_ ev_periodic *w) EV_NOEXCEPT; +#endif + +/* only supported in the default loop */ +#if EV_SIGNAL_ENABLE +EV_API_DECL void ev_signal_start (EV_P_ ev_signal *w) EV_NOEXCEPT; +EV_API_DECL void ev_signal_stop (EV_P_ ev_signal *w) EV_NOEXCEPT; +#endif + +/* only supported in the default loop */ +# if EV_CHILD_ENABLE +EV_API_DECL void ev_child_start (EV_P_ ev_child *w) EV_NOEXCEPT; +EV_API_DECL void ev_child_stop (EV_P_ ev_child *w) EV_NOEXCEPT; +# endif + +# if EV_STAT_ENABLE +EV_API_DECL void ev_stat_start (EV_P_ ev_stat *w) EV_NOEXCEPT; +EV_API_DECL void ev_stat_stop (EV_P_ ev_stat *w) EV_NOEXCEPT; +EV_API_DECL void ev_stat_stat (EV_P_ ev_stat *w) EV_NOEXCEPT; +# endif + +# if EV_IDLE_ENABLE +EV_API_DECL void ev_idle_start (EV_P_ ev_idle *w) EV_NOEXCEPT; +EV_API_DECL void ev_idle_stop (EV_P_ ev_idle *w) EV_NOEXCEPT; +# endif + +#if EV_PREPARE_ENABLE +EV_API_DECL void ev_prepare_start (EV_P_ ev_prepare *w) EV_NOEXCEPT; +EV_API_DECL void ev_prepare_stop (EV_P_ ev_prepare *w) EV_NOEXCEPT; +#endif + +#if EV_CHECK_ENABLE +EV_API_DECL void ev_check_start (EV_P_ ev_check *w) EV_NOEXCEPT; +EV_API_DECL void ev_check_stop (EV_P_ ev_check *w) EV_NOEXCEPT; +#endif + +# if EV_FORK_ENABLE +EV_API_DECL void ev_fork_start (EV_P_ ev_fork *w) EV_NOEXCEPT; +EV_API_DECL void ev_fork_stop (EV_P_ ev_fork *w) EV_NOEXCEPT; +# endif + +# if EV_CLEANUP_ENABLE +EV_API_DECL void ev_cleanup_start (EV_P_ ev_cleanup *w) EV_NOEXCEPT; +EV_API_DECL void ev_cleanup_stop (EV_P_ ev_cleanup *w) EV_NOEXCEPT; +# endif + +# if EV_EMBED_ENABLE +/* only supported when loop to be embedded is in fact embeddable */ +EV_API_DECL void ev_embed_start (EV_P_ ev_embed *w) EV_NOEXCEPT; +EV_API_DECL void ev_embed_stop (EV_P_ ev_embed *w) EV_NOEXCEPT; +EV_API_DECL void ev_embed_sweep (EV_P_ ev_embed *w) EV_NOEXCEPT; +# endif + +# if EV_ASYNC_ENABLE +EV_API_DECL void ev_async_start (EV_P_ ev_async *w) EV_NOEXCEPT; +EV_API_DECL void ev_async_stop (EV_P_ ev_async *w) EV_NOEXCEPT; +EV_API_DECL void ev_async_send (EV_P_ ev_async *w) EV_NOEXCEPT; +# endif + +#if EV_COMPAT3 + #define EVLOOP_NONBLOCK EVRUN_NOWAIT + #define EVLOOP_ONESHOT EVRUN_ONCE + #define EVUNLOOP_CANCEL EVBREAK_CANCEL + #define EVUNLOOP_ONE EVBREAK_ONE + #define EVUNLOOP_ALL EVBREAK_ALL + #if EV_PROTOTYPES + EV_INLINE void ev_loop (EV_P_ int flags) { ev_run (EV_A_ flags); } + EV_INLINE void ev_unloop (EV_P_ int how ) { ev_break (EV_A_ how ); } + EV_INLINE void ev_default_destroy (void) { ev_loop_destroy (EV_DEFAULT); } + EV_INLINE void ev_default_fork (void) { ev_loop_fork (EV_DEFAULT); } + #if EV_FEATURE_API + EV_INLINE unsigned int ev_loop_count (EV_P) { return ev_iteration (EV_A); } + EV_INLINE unsigned int ev_loop_depth (EV_P) { return ev_depth (EV_A); } + EV_INLINE void ev_loop_verify (EV_P) { ev_verify (EV_A); } + #endif + #endif +#else + typedef struct ev_loop ev_loop; +#endif + +#endif + +EV_CPP(}) + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_epoll.c b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_epoll.c new file mode 100644 index 00000000..58cfa684 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_epoll.c @@ -0,0 +1,298 @@ +/* + * libev epoll fd activity backend + * + * Copyright (c) 2007,2008,2009,2010,2011,2016,2017,2019 Marc Alexander Lehmann + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License ("GPL") version 2 or any later version, + * in which case the provisions of the GPL are applicable instead of + * the above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the BSD license, indicate your decision + * by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file under + * either the BSD or the GPL. + */ + +/* + * general notes about epoll: + * + * a) epoll silently removes fds from the fd set. as nothing tells us + * that an fd has been removed otherwise, we have to continually + * "rearm" fds that we suspect *might* have changed (same + * problem with kqueue, but much less costly there). + * b) the fact that ADD != MOD creates a lot of extra syscalls due to a) + * and seems not to have any advantage. + * c) the inability to handle fork or file descriptors (think dup) + * limits the applicability over poll, so this is not a generic + * poll replacement. + * d) epoll doesn't work the same as select with many file descriptors + * (such as files). while not critical, no other advanced interface + * seems to share this (rather non-unixy) limitation. + * e) epoll claims to be embeddable, but in practise you never get + * a ready event for the epoll fd (broken: <=2.6.26, working: >=2.6.32). + * f) epoll_ctl returning EPERM means the fd is always ready. + * + * lots of "weird code" and complication handling in this file is due + * to these design problems with epoll, as we try very hard to avoid + * epoll_ctl syscalls for common usage patterns and handle the breakage + * ensuing from receiving events for closed and otherwise long gone + * file descriptors. + */ + +#include + +#define EV_EMASK_EPERM 0x80 + +static void +epoll_modify (EV_P_ int fd, int oev, int nev) +{ + struct epoll_event ev; + unsigned char oldmask; + + /* + * we handle EPOLL_CTL_DEL by ignoring it here + * on the assumption that the fd is gone anyways + * if that is wrong, we have to handle the spurious + * event in epoll_poll. + * if the fd is added again, we try to ADD it, and, if that + * fails, we assume it still has the same eventmask. + */ + if (!nev) + return; + + oldmask = anfds [fd].emask; + anfds [fd].emask = nev; + + /* store the generation counter in the upper 32 bits, the fd in the lower 32 bits */ + ev.data.u64 = (uint64_t)(uint32_t)fd + | ((uint64_t)(uint32_t)++anfds [fd].egen << 32); + ev.events = (nev & EV_READ ? EPOLLIN : 0) + | (nev & EV_WRITE ? EPOLLOUT : 0); + + if (ecb_expect_true (!epoll_ctl (backend_fd, oev && oldmask != nev ? EPOLL_CTL_MOD : EPOLL_CTL_ADD, fd, &ev))) + return; + + if (ecb_expect_true (errno == ENOENT)) + { + /* if ENOENT then the fd went away, so try to do the right thing */ + if (!nev) + goto dec_egen; + + if (!epoll_ctl (backend_fd, EPOLL_CTL_ADD, fd, &ev)) + return; + } + else if (ecb_expect_true (errno == EEXIST)) + { + /* EEXIST means we ignored a previous DEL, but the fd is still active */ + /* if the kernel mask is the same as the new mask, we assume it hasn't changed */ + if (oldmask == nev) + goto dec_egen; + + if (!epoll_ctl (backend_fd, EPOLL_CTL_MOD, fd, &ev)) + return; + } + else if (ecb_expect_true (errno == EPERM)) + { + /* EPERM means the fd is always ready, but epoll is too snobbish */ + /* to handle it, unlike select or poll. */ + anfds [fd].emask = EV_EMASK_EPERM; + + /* add fd to epoll_eperms, if not already inside */ + if (!(oldmask & EV_EMASK_EPERM)) + { + array_needsize (int, epoll_eperms, epoll_epermmax, epoll_epermcnt + 1, array_needsize_noinit); + epoll_eperms [epoll_epermcnt++] = fd; + } + + return; + } + else + assert (("libev: I/O watcher with invalid fd found in epoll_ctl", errno != EBADF && errno != ELOOP && errno != EINVAL)); + + fd_kill (EV_A_ fd); + +dec_egen: + /* we didn't successfully call epoll_ctl, so decrement the generation counter again */ + --anfds [fd].egen; +} + +static void +epoll_poll (EV_P_ ev_tstamp timeout) +{ + int i; + int eventcnt; + + if (ecb_expect_false (epoll_epermcnt)) + timeout = EV_TS_CONST (0.); + + /* epoll wait times cannot be larger than (LONG_MAX - 999UL) / HZ msecs, which is below */ + /* the default libev max wait time, however. */ + EV_RELEASE_CB; + eventcnt = epoll_wait (backend_fd, epoll_events, epoll_eventmax, EV_TS_TO_MSEC (timeout)); + EV_ACQUIRE_CB; + + if (ecb_expect_false (eventcnt < 0)) + { + if (errno != EINTR) + ev_syserr ("(libev) epoll_wait"); + + return; + } + + for (i = 0; i < eventcnt; ++i) + { + struct epoll_event *ev = epoll_events + i; + + int fd = (uint32_t)ev->data.u64; /* mask out the lower 32 bits */ + int want = anfds [fd].events; + int got = (ev->events & (EPOLLOUT | EPOLLERR | EPOLLHUP) ? EV_WRITE : 0) + | (ev->events & (EPOLLIN | EPOLLERR | EPOLLHUP) ? EV_READ : 0); + + /* + * check for spurious notification. + * this only finds spurious notifications on egen updates + * other spurious notifications will be found by epoll_ctl, below + * we assume that fd is always in range, as we never shrink the anfds array + */ + if (ecb_expect_false ((uint32_t)anfds [fd].egen != (uint32_t)(ev->data.u64 >> 32))) + { + /* recreate kernel state */ + postfork |= 2; + continue; + } + + if (ecb_expect_false (got & ~want)) + { + anfds [fd].emask = want; + + /* + * we received an event but are not interested in it, try mod or del + * this often happens because we optimistically do not unregister fds + * when we are no longer interested in them, but also when we get spurious + * notifications for fds from another process. this is partially handled + * above with the gencounter check (== our fd is not the event fd), and + * partially here, when epoll_ctl returns an error (== a child has the fd + * but we closed it). + * note: for events such as POLLHUP, where we can't know whether it refers + * to EV_READ or EV_WRITE, we might issue redundant EPOLL_CTL_MOD calls. + */ + ev->events = (want & EV_READ ? EPOLLIN : 0) + | (want & EV_WRITE ? EPOLLOUT : 0); + + /* pre-2.6.9 kernels require a non-null pointer with EPOLL_CTL_DEL, */ + /* which is fortunately easy to do for us. */ + if (epoll_ctl (backend_fd, want ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, fd, ev)) + { + postfork |= 2; /* an error occurred, recreate kernel state */ + continue; + } + } + + fd_event (EV_A_ fd, got); + } + + /* if the receive array was full, increase its size */ + if (ecb_expect_false (eventcnt == epoll_eventmax)) + { + ev_free (epoll_events); + epoll_eventmax = array_nextsize (sizeof (struct epoll_event), epoll_eventmax, epoll_eventmax + 1); + epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax); + } + + /* now synthesize events for all fds where epoll fails, while select works... */ + for (i = epoll_epermcnt; i--; ) + { + int fd = epoll_eperms [i]; + unsigned char events = anfds [fd].events & (EV_READ | EV_WRITE); + + if (anfds [fd].emask & EV_EMASK_EPERM && events) + fd_event (EV_A_ fd, events); + else + { + epoll_eperms [i] = epoll_eperms [--epoll_epermcnt]; + anfds [fd].emask = 0; + } + } +} + +static int +epoll_epoll_create (void) +{ + int fd; + +#if defined EPOLL_CLOEXEC && !defined __ANDROID__ + fd = epoll_create1 (EPOLL_CLOEXEC); + + if (fd < 0 && (errno == EINVAL || errno == ENOSYS)) +#endif + { + fd = epoll_create (256); + + if (fd >= 0) + fcntl (fd, F_SETFD, FD_CLOEXEC); + } + + return fd; +} + +inline_size +int +epoll_init (EV_P_ int flags) +{ + if ((backend_fd = epoll_epoll_create ()) < 0) + return 0; + + backend_mintime = EV_TS_CONST (1e-3); /* epoll does sometimes return early, this is just to avoid the worst */ + backend_modify = epoll_modify; + backend_poll = epoll_poll; + + epoll_eventmax = 64; /* initial number of events receivable per poll */ + epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax); + + return EVBACKEND_EPOLL; +} + +inline_size +void +epoll_destroy (EV_P) +{ + ev_free (epoll_events); + array_free (epoll_eperm, EMPTY); +} + +ecb_cold +static void +epoll_fork (EV_P) +{ + close (backend_fd); + + while ((backend_fd = epoll_epoll_create ()) < 0) + ev_syserr ("(libev) epoll_create"); + + fd_rearm_all (EV_A); +} + diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_iouring.c b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_iouring.c new file mode 100644 index 00000000..30a3d5fe --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_iouring.c @@ -0,0 +1,694 @@ +/* + * libev linux io_uring fd activity backend + * + * Copyright (c) 2019-2020 Marc Alexander Lehmann + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License ("GPL") version 2 or any later version, + * in which case the provisions of the GPL are applicable instead of + * the above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the BSD license, indicate your decision + * by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file under + * either the BSD or the GPL. + */ + +/* + * general notes about linux io_uring: + * + * a) it's the best interface I have seen so far. on linux. + * b) best is not necessarily very good. + * c) it's better than the aio mess, doesn't suffer from the fork problems + * of linux aio or epoll and so on and so on. and you could do event stuff + * without any syscalls. what's not to like? + * d) ok, it's vastly more complex, but that's ok, really. + * e) why two mmaps instead of one? one would be more space-efficient, + * and I can't see what benefit two would have (other than being + * somehow resizable/relocatable, but that's apparently not possible). + * f) hmm, it's practically undebuggable (gdb can't access the memory, and + * the bizarre way structure offsets are communicated makes it hard to + * just print the ring buffer heads, even *iff* the memory were visible + * in gdb. but then, that's also ok, really. + * g) well, you cannot specify a timeout when waiting for events. no, + * seriously, the interface doesn't support a timeout. never seen _that_ + * before. sure, you can use a timerfd, but that's another syscall + * you could have avoided. overall, this bizarre omission smells + * like a µ-optimisation by the io_uring author for his personal + * applications, to the detriment of everybody else who just wants + * an event loop. but, umm, ok, if that's all, it could be worse. + * (from what I gather from the author Jens Axboe, it simply didn't + * occur to him, and he made good on it by adding an unlimited nuber + * of timeouts later :). + * h) initially there was a hardcoded limit of 4096 outstanding events. + * later versions not only bump this to 32k, but also can handle + * an unlimited amount of events, so this only affects the batch size. + * i) unlike linux aio, you *can* register more then the limit + * of fd events. while early verisons of io_uring signalled an overflow + * and you ended up getting wet. 5.5+ does not do this anymore. + * j) but, oh my! it had exactly the same bugs as the linux aio backend, + * where some undocumented poll combinations just fail. fortunately, + * after finally reaching the author, he was more than willing to fix + * this probably in 5.6+. + * k) overall, the *API* itself is, I dare to say, not a total trainwreck. + * once the bugs ae fixed (probably in 5.6+), it will be without + * competition. + */ + +/* TODO: use internal TIMEOUT */ +/* TODO: take advantage of single mmap, NODROP etc. */ +/* TODO: resize cq/sq size independently */ + +#include +#include +#include +#include + +#define IOURING_INIT_ENTRIES 32 + +/*****************************************************************************/ +/* syscall wrapdadoop - this section has the raw api/abi definitions */ + +#include +#include + +/* mostly directly taken from the kernel or documentation */ + +struct io_uring_sqe +{ + __u8 opcode; + __u8 flags; + __u16 ioprio; + __s32 fd; + union { + __u64 off; + __u64 addr2; + }; + __u64 addr; + __u32 len; + union { + __kernel_rwf_t rw_flags; + __u32 fsync_flags; + __u16 poll_events; + __u32 sync_range_flags; + __u32 msg_flags; + __u32 timeout_flags; + __u32 accept_flags; + __u32 cancel_flags; + __u32 open_flags; + __u32 statx_flags; + }; + __u64 user_data; + union { + __u16 buf_index; + __u64 __pad2[3]; + }; +}; + +struct io_uring_cqe +{ + __u64 user_data; + __s32 res; + __u32 flags; +}; + +struct io_sqring_offsets +{ + __u32 head; + __u32 tail; + __u32 ring_mask; + __u32 ring_entries; + __u32 flags; + __u32 dropped; + __u32 array; + __u32 resv1; + __u64 resv2; +}; + +struct io_cqring_offsets +{ + __u32 head; + __u32 tail; + __u32 ring_mask; + __u32 ring_entries; + __u32 overflow; + __u32 cqes; + __u64 resv[2]; +}; + +struct io_uring_params +{ + __u32 sq_entries; + __u32 cq_entries; + __u32 flags; + __u32 sq_thread_cpu; + __u32 sq_thread_idle; + __u32 features; + __u32 resv[4]; + struct io_sqring_offsets sq_off; + struct io_cqring_offsets cq_off; +}; + +#define IORING_SETUP_CQSIZE 0x00000008 + +#define IORING_OP_POLL_ADD 6 +#define IORING_OP_POLL_REMOVE 7 +#define IORING_OP_TIMEOUT 11 +#define IORING_OP_TIMEOUT_REMOVE 12 + +/* relative or absolute, reference clock is CLOCK_MONOTONIC */ +struct iouring_kernel_timespec +{ + int64_t tv_sec; + long long tv_nsec; +}; + +#define IORING_TIMEOUT_ABS 0x00000001 + +#define IORING_ENTER_GETEVENTS 0x01 + +#define IORING_OFF_SQ_RING 0x00000000ULL +#define IORING_OFF_CQ_RING 0x08000000ULL +#define IORING_OFF_SQES 0x10000000ULL + +#define IORING_FEAT_SINGLE_MMAP 0x00000001 +#define IORING_FEAT_NODROP 0x00000002 +#define IORING_FEAT_SUBMIT_STABLE 0x00000004 + +inline_size +int +evsys_io_uring_setup (unsigned entries, struct io_uring_params *params) +{ + return ev_syscall2 (SYS_io_uring_setup, entries, params); +} + +inline_size +int +evsys_io_uring_enter (int fd, unsigned to_submit, unsigned min_complete, unsigned flags, const sigset_t *sig, size_t sigsz) +{ + return ev_syscall6 (SYS_io_uring_enter, fd, to_submit, min_complete, flags, sig, sigsz); +} + +/*****************************************************************************/ +/* actual backed implementation */ + +/* we hope that volatile will make the compiler access this variables only once */ +#define EV_SQ_VAR(name) *(volatile unsigned *)((char *)iouring_sq_ring + iouring_sq_ ## name) +#define EV_CQ_VAR(name) *(volatile unsigned *)((char *)iouring_cq_ring + iouring_cq_ ## name) + +/* the index array */ +#define EV_SQ_ARRAY ((unsigned *)((char *)iouring_sq_ring + iouring_sq_array)) + +/* the submit/completion queue entries */ +#define EV_SQES ((struct io_uring_sqe *) iouring_sqes) +#define EV_CQES ((struct io_uring_cqe *)((char *)iouring_cq_ring + iouring_cq_cqes)) + +inline_speed +int +iouring_enter (EV_P_ ev_tstamp timeout) +{ + int res; + + EV_RELEASE_CB; + + res = evsys_io_uring_enter (iouring_fd, iouring_to_submit, 1, + timeout > EV_TS_CONST (0.) ? IORING_ENTER_GETEVENTS : 0, 0, 0); + + assert (("libev: io_uring_enter did not consume all sqes", (res < 0 || res == iouring_to_submit))); + + iouring_to_submit = 0; + + EV_ACQUIRE_CB; + + return res; +} + +/* TODO: can we move things around so we don't need this forward-reference? */ +static void +iouring_poll (EV_P_ ev_tstamp timeout); + +static +struct io_uring_sqe * +iouring_sqe_get (EV_P) +{ + unsigned tail; + + for (;;) + { + tail = EV_SQ_VAR (tail); + + if (ecb_expect_true (tail + 1 - EV_SQ_VAR (head) <= EV_SQ_VAR (ring_entries))) + break; /* whats the problem, we have free sqes */ + + /* queue full, need to flush and possibly handle some events */ + +#if EV_FEATURE_CODE + /* first we ask the kernel nicely, most often this frees up some sqes */ + int res = iouring_enter (EV_A_ EV_TS_CONST (0.)); + + ECB_MEMORY_FENCE_ACQUIRE; /* better safe than sorry */ + + if (res >= 0) + continue; /* yes, it worked, try again */ +#endif + + /* some problem, possibly EBUSY - do the full poll and let it handle any issues */ + + iouring_poll (EV_A_ EV_TS_CONST (0.)); + /* iouring_poll should have done ECB_MEMORY_FENCE_ACQUIRE for us */ + } + + /*assert (("libev: io_uring queue full after flush", tail + 1 - EV_SQ_VAR (head) <= EV_SQ_VAR (ring_entries)));*/ + + return EV_SQES + (tail & EV_SQ_VAR (ring_mask)); +} + +inline_size +void +iouring_sqe_submit (EV_P_ struct io_uring_sqe *sqe) +{ + unsigned idx = sqe - EV_SQES; + + EV_SQ_ARRAY [idx] = idx; + ECB_MEMORY_FENCE_RELEASE; + ++EV_SQ_VAR (tail); + /*ECB_MEMORY_FENCE_RELEASE; /* for the time being we assume this is not needed */ + ++iouring_to_submit; +} + +/*****************************************************************************/ + +/* when the timerfd expires we simply note the fact, + * as the purpose of the timerfd is to wake us up, nothing else. + * the next iteration should re-set it. + */ +static void +iouring_tfd_cb (EV_P_ struct ev_io *w, int revents) +{ + iouring_tfd_to = EV_TSTAMP_HUGE; +} + +/* called for full and partial cleanup */ +ecb_cold +static void +iouring_internal_destroy (EV_P) +{ + close (iouring_tfd); + close (iouring_fd); + + if (iouring_sq_ring != MAP_FAILED) munmap (iouring_sq_ring, iouring_sq_ring_size); + if (iouring_cq_ring != MAP_FAILED) munmap (iouring_cq_ring, iouring_cq_ring_size); + if (iouring_sqes != MAP_FAILED) munmap (iouring_sqes , iouring_sqes_size ); + + if (ev_is_active (&iouring_tfd_w)) + { + ev_ref (EV_A); + ev_io_stop (EV_A_ &iouring_tfd_w); + } +} + +ecb_cold +static int +iouring_internal_init (EV_P) +{ + struct io_uring_params params = { 0 }; + + iouring_to_submit = 0; + + iouring_tfd = -1; + iouring_sq_ring = MAP_FAILED; + iouring_cq_ring = MAP_FAILED; + iouring_sqes = MAP_FAILED; + + if (!have_monotonic) /* cannot really happen, but what if11 */ + return -1; + + for (;;) + { + iouring_fd = evsys_io_uring_setup (iouring_entries, ¶ms); + + if (iouring_fd >= 0) + break; /* yippie */ + + if (errno != EINVAL) + return -1; /* we failed */ + +#if TODO + if ((~params.features) & (IORING_FEAT_NODROP | IORING_FEATURE_SINGLE_MMAP | IORING_FEAT_SUBMIT_STABLE)) + return -1; /* we require the above features */ +#endif + + /* EINVAL: lots of possible reasons, but maybe + * it is because we hit the unqueryable hardcoded size limit + */ + + /* we hit the limit already, give up */ + if (iouring_max_entries) + return -1; + + /* first time we hit EINVAL? assume we hit the limit, so go back and retry */ + iouring_entries >>= 1; + iouring_max_entries = iouring_entries; + } + + iouring_sq_ring_size = params.sq_off.array + params.sq_entries * sizeof (unsigned); + iouring_cq_ring_size = params.cq_off.cqes + params.cq_entries * sizeof (struct io_uring_cqe); + iouring_sqes_size = params.sq_entries * sizeof (struct io_uring_sqe); + + iouring_sq_ring = mmap (0, iouring_sq_ring_size, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_POPULATE, iouring_fd, IORING_OFF_SQ_RING); + iouring_cq_ring = mmap (0, iouring_cq_ring_size, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_POPULATE, iouring_fd, IORING_OFF_CQ_RING); + iouring_sqes = mmap (0, iouring_sqes_size, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_POPULATE, iouring_fd, IORING_OFF_SQES); + + if (iouring_sq_ring == MAP_FAILED || iouring_cq_ring == MAP_FAILED || iouring_sqes == MAP_FAILED) + return -1; + + iouring_sq_head = params.sq_off.head; + iouring_sq_tail = params.sq_off.tail; + iouring_sq_ring_mask = params.sq_off.ring_mask; + iouring_sq_ring_entries = params.sq_off.ring_entries; + iouring_sq_flags = params.sq_off.flags; + iouring_sq_dropped = params.sq_off.dropped; + iouring_sq_array = params.sq_off.array; + + iouring_cq_head = params.cq_off.head; + iouring_cq_tail = params.cq_off.tail; + iouring_cq_ring_mask = params.cq_off.ring_mask; + iouring_cq_ring_entries = params.cq_off.ring_entries; + iouring_cq_overflow = params.cq_off.overflow; + iouring_cq_cqes = params.cq_off.cqes; + + iouring_tfd = timerfd_create (CLOCK_MONOTONIC, TFD_CLOEXEC); + + if (iouring_tfd < 0) + return iouring_tfd; + + iouring_tfd_to = EV_TSTAMP_HUGE; + + return 0; +} + +ecb_cold +static void +iouring_fork (EV_P) +{ + iouring_internal_destroy (EV_A); + + while (iouring_internal_init (EV_A) < 0) + ev_syserr ("(libev) io_uring_setup"); + + fd_rearm_all (EV_A); + + ev_io_stop (EV_A_ &iouring_tfd_w); + ev_io_set (EV_A_ &iouring_tfd_w, iouring_tfd, EV_READ); + ev_io_start (EV_A_ &iouring_tfd_w); +} + +/*****************************************************************************/ + +static void +iouring_modify (EV_P_ int fd, int oev, int nev) +{ + if (oev) + { + /* we assume the sqe's are all "properly" initialised */ + struct io_uring_sqe *sqe = iouring_sqe_get (EV_A); + sqe->opcode = IORING_OP_POLL_REMOVE; + sqe->fd = fd; + /* Jens Axboe notified me that user_data is not what is documented, but is + * some kind of unique ID that has to match, otherwise the request cannot + * be removed. Since we don't *really* have that, we pass in the old + * generation counter - if that fails, too bad, it will hopefully be removed + * at close time and then be ignored. */ + sqe->addr = (uint32_t)fd | ((__u64)(uint32_t)anfds [fd].egen << 32); + sqe->user_data = (uint64_t)-1; + iouring_sqe_submit (EV_A_ sqe); + + /* increment generation counter to avoid handling old events */ + ++anfds [fd].egen; + } + + if (nev) + { + struct io_uring_sqe *sqe = iouring_sqe_get (EV_A); + sqe->opcode = IORING_OP_POLL_ADD; + sqe->fd = fd; + sqe->addr = 0; + sqe->user_data = (uint32_t)fd | ((__u64)(uint32_t)anfds [fd].egen << 32); + sqe->poll_events = + (nev & EV_READ ? POLLIN : 0) + | (nev & EV_WRITE ? POLLOUT : 0); + iouring_sqe_submit (EV_A_ sqe); + } +} + +inline_size +void +iouring_tfd_update (EV_P_ ev_tstamp timeout) +{ + ev_tstamp tfd_to = mn_now + timeout; + + /* we assume there will be many iterations per timer change, so + * we only re-set the timerfd when we have to because its expiry + * is too late. + */ + if (ecb_expect_false (tfd_to < iouring_tfd_to)) + { + struct itimerspec its; + + iouring_tfd_to = tfd_to; + EV_TS_SET (its.it_interval, 0.); + EV_TS_SET (its.it_value, tfd_to); + + if (timerfd_settime (iouring_tfd, TFD_TIMER_ABSTIME, &its, 0) < 0) + assert (("libev: iouring timerfd_settime failed", 0)); + } +} + +inline_size +void +iouring_process_cqe (EV_P_ struct io_uring_cqe *cqe) +{ + int fd = cqe->user_data & 0xffffffffU; + uint32_t gen = cqe->user_data >> 32; + int res = cqe->res; + + /* user_data -1 is a remove that we are not atm. interested in */ + if (cqe->user_data == (uint64_t)-1) + return; + + assert (("libev: io_uring fd must be in-bounds", fd >= 0 && fd < anfdmax)); + + /* documentation lies, of course. the result value is NOT like + * normal syscalls, but like linux raw syscalls, i.e. negative + * error numbers. fortunate, as otherwise there would be no way + * to get error codes at all. still, why not document this? + */ + + /* ignore event if generation doesn't match */ + /* other than skipping removal events, */ + /* this should actually be very rare */ + if (ecb_expect_false (gen != (uint32_t)anfds [fd].egen)) + return; + + if (ecb_expect_false (res < 0)) + { + /*TODO: EINVAL handling (was something failed with this fd)*/ + + if (res == -EBADF) + { + assert (("libev: event loop rejected bad fd", res != -EBADF)); + fd_kill (EV_A_ fd); + } + else + { + errno = -res; + ev_syserr ("(libev) IORING_OP_POLL_ADD"); + } + + return; + } + + /* feed events, we do not expect or handle POLLNVAL */ + fd_event ( + EV_A_ + fd, + (res & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0) + | (res & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0) + ); + + /* io_uring is oneshot, so we need to re-arm the fd next iteration */ + /* this also means we usually have to do at least one syscall per iteration */ + anfds [fd].events = 0; + fd_change (EV_A_ fd, EV_ANFD_REIFY); +} + +/* called when the event queue overflows */ +ecb_cold +static void +iouring_overflow (EV_P) +{ + /* we have two options, resize the queue (by tearing down + * everything and recreating it, or living with it + * and polling. + * we implement this by resizing the queue, and, if that fails, + * we just recreate the state on every failure, which + * kind of is a very inefficient poll. + * one danger is, due to the bios toward lower fds, + * we will only really get events for those, so + * maybe we need a poll() fallback, after all. + */ + /*EV_CQ_VAR (overflow) = 0;*/ /* need to do this if we keep the state and poll manually */ + + fd_rearm_all (EV_A); + + /* we double the size until we hit the hard-to-probe maximum */ + if (!iouring_max_entries) + { + iouring_entries <<= 1; + iouring_fork (EV_A); + } + else + { + /* we hit the kernel limit, we should fall back to something else. + * we can either poll() a few times and hope for the best, + * poll always, or switch to epoll. + * TODO: is this necessary with newer kernels? + */ + + iouring_internal_destroy (EV_A); + + /* this should make it so that on return, we don't call any uring functions */ + iouring_to_submit = 0; + + for (;;) + { + backend = epoll_init (EV_A_ 0); + + if (backend) + break; + + ev_syserr ("(libev) iouring switch to epoll"); + } + } +} + +/* handle any events in the completion queue, return true if there were any */ +static int +iouring_handle_cq (EV_P) +{ + unsigned head, tail, mask; + + head = EV_CQ_VAR (head); + ECB_MEMORY_FENCE_ACQUIRE; + tail = EV_CQ_VAR (tail); + + if (head == tail) + return 0; + + /* it can only overflow if we have events, yes, yes? */ + if (ecb_expect_false (EV_CQ_VAR (overflow))) + { + iouring_overflow (EV_A); + return 1; + } + + mask = EV_CQ_VAR (ring_mask); + + do + iouring_process_cqe (EV_A_ &EV_CQES [head++ & mask]); + while (head != tail); + + EV_CQ_VAR (head) = head; + ECB_MEMORY_FENCE_RELEASE; + + return 1; +} + +static void +iouring_poll (EV_P_ ev_tstamp timeout) +{ + /* if we have events, no need for extra syscalls, but we might have to queue events */ + /* we also clar the timeout if there are outstanding fdchanges */ + /* the latter should only happen if both the sq and cq are full, most likely */ + /* because we have a lot of event sources that immediately complete */ + /* TODO: fdchacngecnt is always 0 because fd_reify does not have two buffers yet */ + if (iouring_handle_cq (EV_A) || fdchangecnt) + timeout = EV_TS_CONST (0.); + else + /* no events, so maybe wait for some */ + iouring_tfd_update (EV_A_ timeout); + + /* only enter the kernel if we have something to submit, or we need to wait */ + if (timeout || iouring_to_submit) + { + int res = iouring_enter (EV_A_ timeout); + + if (ecb_expect_false (res < 0)) + if (errno == EINTR) + /* ignore */; + else if (errno == EBUSY) + /* cq full, cannot submit - should be rare because we flush the cq first, so simply ignore */; + else + ev_syserr ("(libev) iouring setup"); + else + iouring_handle_cq (EV_A); + } +} + +inline_size +int +iouring_init (EV_P_ int flags) +{ + iouring_entries = IOURING_INIT_ENTRIES; + iouring_max_entries = 0; + + if (iouring_internal_init (EV_A) < 0) + { + iouring_internal_destroy (EV_A); + return 0; + } + + ev_io_init (&iouring_tfd_w, iouring_tfd_cb, iouring_tfd, EV_READ); + ev_set_priority (&iouring_tfd_w, EV_MINPRI); + ev_io_start (EV_A_ &iouring_tfd_w); + ev_unref (EV_A); /* watcher should not keep loop alive */ + + backend_modify = iouring_modify; + backend_poll = iouring_poll; + + return EVBACKEND_IOURING; +} + +inline_size +void +iouring_destroy (EV_P) +{ + iouring_internal_destroy (EV_A); +} + diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_kqueue.c b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_kqueue.c new file mode 100644 index 00000000..69c5147f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_kqueue.c @@ -0,0 +1,224 @@ +/* + * libev kqueue backend + * + * Copyright (c) 2007,2008,2009,2010,2011,2012,2013,2016,2019 Marc Alexander Lehmann + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License ("GPL") version 2 or any later version, + * in which case the provisions of the GPL are applicable instead of + * the above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the BSD license, indicate your decision + * by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file under + * either the BSD or the GPL. + */ + +#include +#include +#include +#include +#include + +inline_speed +void +kqueue_change (EV_P_ int fd, int filter, int flags, int fflags) +{ + ++kqueue_changecnt; + array_needsize (struct kevent, kqueue_changes, kqueue_changemax, kqueue_changecnt, array_needsize_noinit); + + EV_SET (&kqueue_changes [kqueue_changecnt - 1], fd, filter, flags, fflags, 0, 0); +} + +/* OS X at least needs this */ +#ifndef EV_ENABLE +# define EV_ENABLE 0 +#endif +#ifndef NOTE_EOF +# define NOTE_EOF 0 +#endif + +static void +kqueue_modify (EV_P_ int fd, int oev, int nev) +{ + if (oev != nev) + { + if (oev & EV_READ) + kqueue_change (EV_A_ fd, EVFILT_READ , EV_DELETE, 0); + + if (oev & EV_WRITE) + kqueue_change (EV_A_ fd, EVFILT_WRITE, EV_DELETE, 0); + } + + /* to detect close/reopen reliably, we have to re-add */ + /* event requests even when oev == nev */ + + if (nev & EV_READ) + kqueue_change (EV_A_ fd, EVFILT_READ , EV_ADD | EV_ENABLE, NOTE_EOF); + + if (nev & EV_WRITE) + kqueue_change (EV_A_ fd, EVFILT_WRITE, EV_ADD | EV_ENABLE, NOTE_EOF); +} + +static void +kqueue_poll (EV_P_ ev_tstamp timeout) +{ + int res, i; + struct timespec ts; + + /* need to resize so there is enough space for errors */ + if (kqueue_changecnt > kqueue_eventmax) + { + ev_free (kqueue_events); + kqueue_eventmax = array_nextsize (sizeof (struct kevent), kqueue_eventmax, kqueue_changecnt); + kqueue_events = (struct kevent *)ev_malloc (sizeof (struct kevent) * kqueue_eventmax); + } + + EV_RELEASE_CB; + EV_TS_SET (ts, timeout); + res = kevent (backend_fd, kqueue_changes, kqueue_changecnt, kqueue_events, kqueue_eventmax, &ts); + EV_ACQUIRE_CB; + kqueue_changecnt = 0; + + if (ecb_expect_false (res < 0)) + { + if (errno != EINTR) + ev_syserr ("(libev) kqueue kevent"); + + return; + } + + for (i = 0; i < res; ++i) + { + int fd = kqueue_events [i].ident; + + if (ecb_expect_false (kqueue_events [i].flags & EV_ERROR)) + { + int err = kqueue_events [i].data; + + /* we are only interested in errors for fds that we are interested in :) */ + if (anfds [fd].events) + { + if (err == ENOENT) /* resubmit changes on ENOENT */ + kqueue_modify (EV_A_ fd, 0, anfds [fd].events); + else if (err == EBADF) /* on EBADF, we re-check the fd */ + { + if (fd_valid (fd)) + kqueue_modify (EV_A_ fd, 0, anfds [fd].events); + else + { + assert (("libev: kqueue found invalid fd", 0)); + fd_kill (EV_A_ fd); + } + } + else /* on all other errors, we error out on the fd */ + { + assert (("libev: kqueue found invalid fd", 0)); + fd_kill (EV_A_ fd); + } + } + } + else + fd_event ( + EV_A_ + fd, + kqueue_events [i].filter == EVFILT_READ ? EV_READ + : kqueue_events [i].filter == EVFILT_WRITE ? EV_WRITE + : 0 + ); + } + + if (ecb_expect_false (res == kqueue_eventmax)) + { + ev_free (kqueue_events); + kqueue_eventmax = array_nextsize (sizeof (struct kevent), kqueue_eventmax, kqueue_eventmax + 1); + kqueue_events = (struct kevent *)ev_malloc (sizeof (struct kevent) * kqueue_eventmax); + } +} + +inline_size +int +kqueue_init (EV_P_ int flags) +{ + /* initialize the kernel queue */ + kqueue_fd_pid = getpid (); + if ((backend_fd = kqueue ()) < 0) + return 0; + + fcntl (backend_fd, F_SETFD, FD_CLOEXEC); /* not sure if necessary, hopefully doesn't hurt */ + + backend_mintime = EV_TS_CONST (1e-9); /* apparently, they did the right thing in freebsd */ + backend_modify = kqueue_modify; + backend_poll = kqueue_poll; + + kqueue_eventmax = 64; /* initial number of events receivable per poll */ + kqueue_events = (struct kevent *)ev_malloc (sizeof (struct kevent) * kqueue_eventmax); + + kqueue_changes = 0; + kqueue_changemax = 0; + kqueue_changecnt = 0; + + return EVBACKEND_KQUEUE; +} + +inline_size +void +kqueue_destroy (EV_P) +{ + ev_free (kqueue_events); + ev_free (kqueue_changes); +} + +inline_size +void +kqueue_fork (EV_P) +{ + /* some BSD kernels don't just destroy the kqueue itself, + * but also close the fd, which isn't documented, and + * impossible to support properly. + * we remember the pid of the kqueue call and only close + * the fd if the pid is still the same. + * this leaks fds on sane kernels, but BSD interfaces are + * notoriously buggy and rarely get fixed. + */ + pid_t newpid = getpid (); + + if (newpid == kqueue_fd_pid) + close (backend_fd); + + kqueue_fd_pid = newpid; + while ((backend_fd = kqueue ()) < 0) + ev_syserr ("(libev) kqueue"); + + fcntl (backend_fd, F_SETFD, FD_CLOEXEC); + + /* re-register interest in fds */ + fd_rearm_all (EV_A); +} + +/* sys/event.h defines EV_ERROR */ +#undef EV_ERROR + diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_linuxaio.c b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_linuxaio.c new file mode 100644 index 00000000..4687a703 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_linuxaio.c @@ -0,0 +1,620 @@ +/* + * libev linux aio fd activity backend + * + * Copyright (c) 2019 Marc Alexander Lehmann + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License ("GPL") version 2 or any later version, + * in which case the provisions of the GPL are applicable instead of + * the above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the BSD license, indicate your decision + * by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file under + * either the BSD or the GPL. + */ + +/* + * general notes about linux aio: + * + * a) at first, the linux aio IOCB_CMD_POLL functionality introduced in + * 4.18 looks too good to be true: both watchers and events can be + * batched, and events can even be handled in userspace using + * a ring buffer shared with the kernel. watchers can be canceled + * regardless of whether the fd has been closed. no problems with fork. + * ok, the ring buffer is 200% undocumented (there isn't even a + * header file), but otherwise, it's pure bliss! + * b) ok, watchers are one-shot, so you have to re-arm active ones + * on every iteration. so much for syscall-less event handling, + * but at least these re-arms can be batched, no big deal, right? + * c) well, linux as usual: the documentation lies to you: io_submit + * sometimes returns EINVAL because the kernel doesn't feel like + * handling your poll mask - ttys can be polled for POLLOUT, + * POLLOUT|POLLIN, but polling for POLLIN fails. just great, + * so we have to fall back to something else (hello, epoll), + * but at least the fallback can be slow, because these are + * exceptional cases, right? + * d) hmm, you have to tell the kernel the maximum number of watchers + * you want to queue when initialising the aio context. but of + * course the real limit is magically calculated in the kernel, and + * is often higher then we asked for. so we just have to destroy + * the aio context and re-create it a bit larger if we hit the limit. + * (starts to remind you of epoll? well, it's a bit more deterministic + * and less gambling, but still ugly as hell). + * e) that's when you find out you can also hit an arbitrary system-wide + * limit. or the kernel simply doesn't want to handle your watchers. + * what the fuck do we do then? you guessed it, in the middle + * of event handling we have to switch to 100% epoll polling. and + * that better is as fast as normal epoll polling, so you practically + * have to use the normal epoll backend with all its quirks. + * f) end result of this train wreck: it inherits all the disadvantages + * from epoll, while adding a number on its own. why even bother to use + * it? because if conditions are right and your fds are supported and you + * don't hit a limit, this backend is actually faster, doesn't gamble with + * your fds, batches watchers and events and doesn't require costly state + * recreates. well, until it does. + * g) all of this makes this backend use almost twice as much code as epoll. + * which in turn uses twice as much code as poll. and that#s not counting + * the fact that this backend also depends on the epoll backend, making + * it three times as much code as poll, or kqueue. + * h) bleah. why can't linux just do kqueue. sure kqueue is ugly, but by now + * it's clear that whatever linux comes up with is far, far, far worse. + */ + +#include /* actually linux/time.h, but we must assume they are compatible */ +#include +#include + +/*****************************************************************************/ +/* syscall wrapdadoop - this section has the raw api/abi definitions */ + +#include /* no glibc wrappers */ + +/* aio_abi.h is not versioned in any way, so we cannot test for its existance */ +#define IOCB_CMD_POLL 5 + +/* taken from linux/fs/aio.c. yup, that's a .c file. + * not only is this totally undocumented, not even the source code + * can tell you what the future semantics of compat_features and + * incompat_features are, or what header_length actually is for. + */ +#define AIO_RING_MAGIC 0xa10a10a1 +#define EV_AIO_RING_INCOMPAT_FEATURES 0 +struct aio_ring +{ + unsigned id; /* kernel internal index number */ + unsigned nr; /* number of io_events */ + unsigned head; /* Written to by userland or by kernel. */ + unsigned tail; + + unsigned magic; + unsigned compat_features; + unsigned incompat_features; + unsigned header_length; /* size of aio_ring */ + + struct io_event io_events[0]; +}; + +inline_size +int +evsys_io_setup (unsigned nr_events, aio_context_t *ctx_idp) +{ + return ev_syscall2 (SYS_io_setup, nr_events, ctx_idp); +} + +inline_size +int +evsys_io_destroy (aio_context_t ctx_id) +{ + return ev_syscall1 (SYS_io_destroy, ctx_id); +} + +inline_size +int +evsys_io_submit (aio_context_t ctx_id, long nr, struct iocb *cbp[]) +{ + return ev_syscall3 (SYS_io_submit, ctx_id, nr, cbp); +} + +inline_size +int +evsys_io_cancel (aio_context_t ctx_id, struct iocb *cbp, struct io_event *result) +{ + return ev_syscall3 (SYS_io_cancel, ctx_id, cbp, result); +} + +inline_size +int +evsys_io_getevents (aio_context_t ctx_id, long min_nr, long nr, struct io_event *events, struct timespec *timeout) +{ + return ev_syscall5 (SYS_io_getevents, ctx_id, min_nr, nr, events, timeout); +} + +/*****************************************************************************/ +/* actual backed implementation */ + +ecb_cold +static int +linuxaio_nr_events (EV_P) +{ + /* we start with 16 iocbs and incraese from there + * that's tiny, but the kernel has a rather low system-wide + * limit that can be reached quickly, so let's be parsimonious + * with this resource. + * Rest assured, the kernel generously rounds up small and big numbers + * in different ways (but doesn't seem to charge you for it). + * The 15 here is because the kernel usually has a power of two as aio-max-nr, + * and this helps to take advantage of that limit. + */ + + /* we try to fill 4kB pages exactly. + * the ring buffer header is 32 bytes, every io event is 32 bytes. + * the kernel takes the io requests number, doubles it, adds 2 + * and adds the ring buffer. + * the way we use this is by starting low, and then roughly doubling the + * size each time we hit a limit. + */ + + int requests = 15 << linuxaio_iteration; + int one_page = (4096 + / sizeof (struct io_event) ) / 2; /* how many fit into one page */ + int first_page = ((4096 - sizeof (struct aio_ring)) + / sizeof (struct io_event) - 2) / 2; /* how many fit into the first page */ + + /* if everything fits into one page, use count exactly */ + if (requests > first_page) + /* otherwise, round down to full pages and add the first page */ + requests = requests / one_page * one_page + first_page; + + return requests; +} + +/* we use out own wrapper structure in case we ever want to do something "clever" */ +typedef struct aniocb +{ + struct iocb io; + /*int inuse;*/ +} *ANIOCBP; + +inline_size +void +linuxaio_array_needsize_iocbp (ANIOCBP *base, int offset, int count) +{ + while (count--) + { + /* TODO: quite the overhead to allocate every iocb separately, maybe use our own allocator? */ + ANIOCBP iocb = (ANIOCBP)ev_malloc (sizeof (*iocb)); + + /* full zero initialise is probably not required at the moment, but + * this is not well documented, so we better do it. + */ + memset (iocb, 0, sizeof (*iocb)); + + iocb->io.aio_lio_opcode = IOCB_CMD_POLL; + iocb->io.aio_fildes = offset; + + base [offset++] = iocb; + } +} + +ecb_cold +static void +linuxaio_free_iocbp (EV_P) +{ + while (linuxaio_iocbpmax--) + ev_free (linuxaio_iocbps [linuxaio_iocbpmax]); + + linuxaio_iocbpmax = 0; /* next resize will completely reallocate the array, at some overhead */ +} + +static void +linuxaio_modify (EV_P_ int fd, int oev, int nev) +{ + array_needsize (ANIOCBP, linuxaio_iocbps, linuxaio_iocbpmax, fd + 1, linuxaio_array_needsize_iocbp); + ANIOCBP iocb = linuxaio_iocbps [fd]; + ANFD *anfd = &anfds [fd]; + + if (ecb_expect_false (iocb->io.aio_reqprio < 0)) + { + /* we handed this fd over to epoll, so undo this first */ + /* we do it manually because the optimisations on epoll_modify won't do us any good */ + epoll_ctl (backend_fd, EPOLL_CTL_DEL, fd, 0); + anfd->emask = 0; + iocb->io.aio_reqprio = 0; + } + else if (ecb_expect_false (iocb->io.aio_buf)) + { + /* iocb active, so cancel it first before resubmit */ + /* this assumes we only ever get one call per fd per loop iteration */ + for (;;) + { + /* on all relevant kernels, io_cancel fails with EINPROGRESS on "success" */ + if (ecb_expect_false (evsys_io_cancel (linuxaio_ctx, &iocb->io, (struct io_event *)0) == 0)) + break; + + if (ecb_expect_true (errno == EINPROGRESS)) + break; + + /* the EINPROGRESS test is for nicer error message. clumsy. */ + if (errno != EINTR) + { + assert (("libev: linuxaio unexpected io_cancel failed", errno != EINTR && errno != EINPROGRESS)); + break; + } + } + + /* increment generation counter to avoid handling old events */ + ++anfd->egen; + } + + iocb->io.aio_buf = (nev & EV_READ ? POLLIN : 0) + | (nev & EV_WRITE ? POLLOUT : 0); + + if (nev) + { + iocb->io.aio_data = (uint32_t)fd | ((__u64)(uint32_t)anfd->egen << 32); + + /* queue iocb up for io_submit */ + /* this assumes we only ever get one call per fd per loop iteration */ + ++linuxaio_submitcnt; + array_needsize (struct iocb *, linuxaio_submits, linuxaio_submitmax, linuxaio_submitcnt, array_needsize_noinit); + linuxaio_submits [linuxaio_submitcnt - 1] = &iocb->io; + } +} + +static void +linuxaio_epoll_cb (EV_P_ struct ev_io *w, int revents) +{ + epoll_poll (EV_A_ 0); +} + +inline_speed +void +linuxaio_fd_rearm (EV_P_ int fd) +{ + anfds [fd].events = 0; + linuxaio_iocbps [fd]->io.aio_buf = 0; + fd_change (EV_A_ fd, EV_ANFD_REIFY); +} + +static void +linuxaio_parse_events (EV_P_ struct io_event *ev, int nr) +{ + while (nr) + { + int fd = ev->data & 0xffffffff; + uint32_t gen = ev->data >> 32; + int res = ev->res; + + assert (("libev: iocb fd must be in-bounds", fd >= 0 && fd < anfdmax)); + + /* only accept events if generation counter matches */ + if (ecb_expect_true (gen == (uint32_t)anfds [fd].egen)) + { + /* feed events, we do not expect or handle POLLNVAL */ + fd_event ( + EV_A_ + fd, + (res & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0) + | (res & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0) + ); + + /* linux aio is oneshot: rearm fd. TODO: this does more work than strictly needed */ + linuxaio_fd_rearm (EV_A_ fd); + } + + --nr; + ++ev; + } +} + +/* get any events from ring buffer, return true if any were handled */ +static int +linuxaio_get_events_from_ring (EV_P) +{ + struct aio_ring *ring = (struct aio_ring *)linuxaio_ctx; + unsigned head, tail; + + /* the kernel reads and writes both of these variables, */ + /* as a C extension, we assume that volatile use here */ + /* both makes reads atomic and once-only */ + head = *(volatile unsigned *)&ring->head; + ECB_MEMORY_FENCE_ACQUIRE; + tail = *(volatile unsigned *)&ring->tail; + + if (head == tail) + return 0; + + /* parse all available events, but only once, to avoid starvation */ + if (ecb_expect_true (tail > head)) /* normal case around */ + linuxaio_parse_events (EV_A_ ring->io_events + head, tail - head); + else /* wrapped around */ + { + linuxaio_parse_events (EV_A_ ring->io_events + head, ring->nr - head); + linuxaio_parse_events (EV_A_ ring->io_events, tail); + } + + ECB_MEMORY_FENCE_RELEASE; + /* as an extension to C, we hope that the volatile will make this atomic and once-only */ + *(volatile unsigned *)&ring->head = tail; + + return 1; +} + +inline_size +int +linuxaio_ringbuf_valid (EV_P) +{ + struct aio_ring *ring = (struct aio_ring *)linuxaio_ctx; + + return ecb_expect_true (ring->magic == AIO_RING_MAGIC) + && ring->incompat_features == EV_AIO_RING_INCOMPAT_FEATURES + && ring->header_length == sizeof (struct aio_ring); /* TODO: or use it to find io_event[0]? */ +} + +/* read at least one event from kernel, or timeout */ +inline_size +void +linuxaio_get_events (EV_P_ ev_tstamp timeout) +{ + struct timespec ts; + struct io_event ioev[8]; /* 256 octet stack space */ + int want = 1; /* how many events to request */ + int ringbuf_valid = linuxaio_ringbuf_valid (EV_A); + + if (ecb_expect_true (ringbuf_valid)) + { + /* if the ring buffer has any events, we don't wait or call the kernel at all */ + if (linuxaio_get_events_from_ring (EV_A)) + return; + + /* if the ring buffer is empty, and we don't have a timeout, then don't call the kernel */ + if (!timeout) + return; + } + else + /* no ringbuffer, request slightly larger batch */ + want = sizeof (ioev) / sizeof (ioev [0]); + + /* no events, so wait for some + * for fairness reasons, we do this in a loop, to fetch all events + */ + for (;;) + { + int res; + + EV_RELEASE_CB; + + EV_TS_SET (ts, timeout); + res = evsys_io_getevents (linuxaio_ctx, 1, want, ioev, &ts); + + EV_ACQUIRE_CB; + + if (res < 0) + if (errno == EINTR) + /* ignored, retry */; + else + ev_syserr ("(libev) linuxaio io_getevents"); + else if (res) + { + /* at least one event available, handle them */ + linuxaio_parse_events (EV_A_ ioev, res); + + if (ecb_expect_true (ringbuf_valid)) + { + /* if we have a ring buffer, handle any remaining events in it */ + linuxaio_get_events_from_ring (EV_A); + + /* at this point, we should have handled all outstanding events */ + break; + } + else if (res < want) + /* otherwise, if there were fewere events than we wanted, we assume there are no more */ + break; + } + else + break; /* no events from the kernel, we are done */ + + timeout = EV_TS_CONST (0.); /* only wait in the first iteration */ + } +} + +inline_size +int +linuxaio_io_setup (EV_P) +{ + linuxaio_ctx = 0; + return evsys_io_setup (linuxaio_nr_events (EV_A), &linuxaio_ctx); +} + +static void +linuxaio_poll (EV_P_ ev_tstamp timeout) +{ + int submitted; + + /* first phase: submit new iocbs */ + + /* io_submit might return less than the requested number of iocbs */ + /* this is, afaics, only because of errors, but we go by the book and use a loop, */ + /* which allows us to pinpoint the erroneous iocb */ + for (submitted = 0; submitted < linuxaio_submitcnt; ) + { + int res = evsys_io_submit (linuxaio_ctx, linuxaio_submitcnt - submitted, linuxaio_submits + submitted); + + if (ecb_expect_false (res < 0)) + if (errno == EINVAL) + { + /* This happens for unsupported fds, officially, but in my testing, + * also randomly happens for supported fds. We fall back to good old + * poll() here, under the assumption that this is a very rare case. + * See https://lore.kernel.org/patchwork/patch/1047453/ to see + * discussion about such a case (ttys) where polling for POLLIN + * fails but POLLIN|POLLOUT works. + */ + struct iocb *iocb = linuxaio_submits [submitted]; + epoll_modify (EV_A_ iocb->aio_fildes, 0, anfds [iocb->aio_fildes].events); + iocb->aio_reqprio = -1; /* mark iocb as epoll */ + + res = 1; /* skip this iocb - another iocb, another chance */ + } + else if (errno == EAGAIN) + { + /* This happens when the ring buffer is full, or some other shit we + * don't know and isn't documented. Most likely because we have too + * many requests and linux aio can't be assed to handle them. + * In this case, we try to allocate a larger ring buffer, freeing + * ours first. This might fail, in which case we have to fall back to 100% + * epoll. + * God, how I hate linux not getting its act together. Ever. + */ + evsys_io_destroy (linuxaio_ctx); + linuxaio_submitcnt = 0; + + /* rearm all fds with active iocbs */ + { + int fd; + for (fd = 0; fd < linuxaio_iocbpmax; ++fd) + if (linuxaio_iocbps [fd]->io.aio_buf) + linuxaio_fd_rearm (EV_A_ fd); + } + + ++linuxaio_iteration; + if (linuxaio_io_setup (EV_A) < 0) + { + /* TODO: rearm all and recreate epoll backend from scratch */ + /* TODO: might be more prudent? */ + + /* to bad, we can't get a new aio context, go 100% epoll */ + linuxaio_free_iocbp (EV_A); + ev_io_stop (EV_A_ &linuxaio_epoll_w); + ev_ref (EV_A); + linuxaio_ctx = 0; + + backend = EVBACKEND_EPOLL; + backend_modify = epoll_modify; + backend_poll = epoll_poll; + } + + timeout = EV_TS_CONST (0.); + /* it's easiest to handle this mess in another iteration */ + return; + } + else if (errno == EBADF) + { + assert (("libev: event loop rejected bad fd", errno != EBADF)); + fd_kill (EV_A_ linuxaio_submits [submitted]->aio_fildes); + + res = 1; /* skip this iocb */ + } + else if (errno == EINTR) /* not seen in reality, not documented */ + res = 0; /* silently ignore and retry */ + else + { + ev_syserr ("(libev) linuxaio io_submit"); + res = 0; + } + + submitted += res; + } + + linuxaio_submitcnt = 0; + + /* second phase: fetch and parse events */ + + linuxaio_get_events (EV_A_ timeout); +} + +inline_size +int +linuxaio_init (EV_P_ int flags) +{ + /* would be great to have a nice test for IOCB_CMD_POLL instead */ + /* also: test some semi-common fd types, such as files and ttys in recommended_backends */ + /* 4.18 introduced IOCB_CMD_POLL, 4.19 made epoll work, and we need that */ + if (ev_linux_version () < 0x041300) + return 0; + + if (!epoll_init (EV_A_ 0)) + return 0; + + linuxaio_iteration = 0; + + if (linuxaio_io_setup (EV_A) < 0) + { + epoll_destroy (EV_A); + return 0; + } + + ev_io_init (&linuxaio_epoll_w, linuxaio_epoll_cb, backend_fd, EV_READ); + ev_set_priority (&linuxaio_epoll_w, EV_MAXPRI); + ev_io_start (EV_A_ &linuxaio_epoll_w); + ev_unref (EV_A); /* watcher should not keep loop alive */ + + backend_modify = linuxaio_modify; + backend_poll = linuxaio_poll; + + linuxaio_iocbpmax = 0; + linuxaio_iocbps = 0; + + linuxaio_submits = 0; + linuxaio_submitmax = 0; + linuxaio_submitcnt = 0; + + return EVBACKEND_LINUXAIO; +} + +inline_size +void +linuxaio_destroy (EV_P) +{ + epoll_destroy (EV_A); + linuxaio_free_iocbp (EV_A); + evsys_io_destroy (linuxaio_ctx); /* fails in child, aio context is destroyed */ +} + +ecb_cold +static void +linuxaio_fork (EV_P) +{ + linuxaio_submitcnt = 0; /* all pointers were invalidated */ + linuxaio_free_iocbp (EV_A); /* this frees all iocbs, which is very heavy-handed */ + evsys_io_destroy (linuxaio_ctx); /* fails in child, aio context is destroyed */ + + linuxaio_iteration = 0; /* we start over in the child */ + + while (linuxaio_io_setup (EV_A) < 0) + ev_syserr ("(libev) linuxaio io_setup"); + + /* forking epoll should also effectively unregister all fds from the backend */ + epoll_fork (EV_A); + /* epoll_fork already did this. hopefully */ + /*fd_rearm_all (EV_A);*/ + + ev_io_stop (EV_A_ &linuxaio_epoll_w); + ev_io_set (EV_A_ &linuxaio_epoll_w, backend_fd, EV_READ); + ev_io_start (EV_A_ &linuxaio_epoll_w); +} + diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_poll.c b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_poll.c new file mode 100644 index 00000000..e5508ddb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_poll.c @@ -0,0 +1,156 @@ +/* + * libev poll fd activity backend + * + * Copyright (c) 2007,2008,2009,2010,2011,2016,2019 Marc Alexander Lehmann + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License ("GPL") version 2 or any later version, + * in which case the provisions of the GPL are applicable instead of + * the above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the BSD license, indicate your decision + * by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file under + * either the BSD or the GPL. + */ + +#include + +inline_size +void +array_needsize_pollidx (int *base, int offset, int count) +{ + /* using memset (.., -1, ...) is tempting, we we try + * to be ultraportable + */ + base += offset; + while (count--) + *base++ = -1; +} + +static void +poll_modify (EV_P_ int fd, int oev, int nev) +{ + int idx; + + if (oev == nev) + return; + + array_needsize (int, pollidxs, pollidxmax, fd + 1, array_needsize_pollidx); + + idx = pollidxs [fd]; + + if (idx < 0) /* need to allocate a new pollfd */ + { + pollidxs [fd] = idx = pollcnt++; + array_needsize (struct pollfd, polls, pollmax, pollcnt, array_needsize_noinit); + polls [idx].fd = fd; + } + + assert (polls [idx].fd == fd); + + if (nev) + polls [idx].events = + (nev & EV_READ ? POLLIN : 0) + | (nev & EV_WRITE ? POLLOUT : 0); + else /* remove pollfd */ + { + pollidxs [fd] = -1; + + if (ecb_expect_true (idx < --pollcnt)) + { + polls [idx] = polls [pollcnt]; + pollidxs [polls [idx].fd] = idx; + } + } +} + +static void +poll_poll (EV_P_ ev_tstamp timeout) +{ + struct pollfd *p; + int res; + + EV_RELEASE_CB; + res = poll (polls, pollcnt, EV_TS_TO_MSEC (timeout)); + EV_ACQUIRE_CB; + + if (ecb_expect_false (res < 0)) + { + if (errno == EBADF) + fd_ebadf (EV_A); + else if (errno == ENOMEM && !syserr_cb) + fd_enomem (EV_A); + else if (errno != EINTR) + ev_syserr ("(libev) poll"); + } + else + for (p = polls; res; ++p) + { + assert (("libev: poll returned illegal result, broken BSD kernel?", p < polls + pollcnt)); + + if (ecb_expect_false (p->revents)) /* this expect is debatable */ + { + --res; + + if (ecb_expect_false (p->revents & POLLNVAL)) + { + assert (("libev: poll found invalid fd in poll set", 0)); + fd_kill (EV_A_ p->fd); + } + else + fd_event ( + EV_A_ + p->fd, + (p->revents & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0) + | (p->revents & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0) + ); + } + } +} + +inline_size +int +poll_init (EV_P_ int flags) +{ + backend_mintime = EV_TS_CONST (1e-3); + backend_modify = poll_modify; + backend_poll = poll_poll; + + pollidxs = 0; pollidxmax = 0; + polls = 0; pollmax = 0; pollcnt = 0; + + return EVBACKEND_POLL; +} + +inline_size +void +poll_destroy (EV_P) +{ + ev_free (pollidxs); + ev_free (polls); +} + diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_port.c b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_port.c new file mode 100644 index 00000000..f4cd9d99 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_port.c @@ -0,0 +1,192 @@ +/* + * libev solaris event port backend + * + * Copyright (c) 2007,2008,2009,2010,2011,2019 Marc Alexander Lehmann + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License ("GPL") version 2 or any later version, + * in which case the provisions of the GPL are applicable instead of + * the above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the BSD license, indicate your decision + * by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file under + * either the BSD or the GPL. + */ + +/* useful reading: + * + * http://bugs.opensolaris.org/view_bug.do?bug_id=6268715 (random results) + * http://bugs.opensolaris.org/view_bug.do?bug_id=6455223 (just totally broken) + * http://bugs.opensolaris.org/view_bug.do?bug_id=6873782 (manpage ETIME) + * http://bugs.opensolaris.org/view_bug.do?bug_id=6874410 (implementation ETIME) + * http://www.mail-archive.com/networking-discuss@opensolaris.org/msg11898.html ETIME vs. nget + * http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libc/port/gen/event_port.c (libc) + * http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/fs/portfs/port.c#1325 (kernel) + */ + +#include +#include +#include +#include +#include +#include + +inline_speed +void +port_associate_and_check (EV_P_ int fd, int ev) +{ + if (0 > + port_associate ( + backend_fd, PORT_SOURCE_FD, fd, + (ev & EV_READ ? POLLIN : 0) + | (ev & EV_WRITE ? POLLOUT : 0), + 0 + ) + ) + { + if (errno == EBADFD) + { + assert (("libev: port_associate found invalid fd", errno != EBADFD)); + fd_kill (EV_A_ fd); + } + else + ev_syserr ("(libev) port_associate"); + } +} + +static void +port_modify (EV_P_ int fd, int oev, int nev) +{ + /* we need to reassociate no matter what, as closes are + * once more silently being discarded. + */ + if (!nev) + { + if (oev) + port_dissociate (backend_fd, PORT_SOURCE_FD, fd); + } + else + port_associate_and_check (EV_A_ fd, nev); +} + +static void +port_poll (EV_P_ ev_tstamp timeout) +{ + int res, i; + struct timespec ts; + uint_t nget = 1; + + /* we initialise this to something we will skip in the loop, as */ + /* port_getn can return with nget unchanged, but no indication */ + /* whether it was the original value or has been updated :/ */ + port_events [0].portev_source = 0; + + EV_RELEASE_CB; + EV_TS_SET (ts, timeout); + res = port_getn (backend_fd, port_events, port_eventmax, &nget, &ts); + EV_ACQUIRE_CB; + + /* port_getn may or may not set nget on error */ + /* so we rely on port_events [0].portev_source not being updated */ + if (res == -1 && errno != ETIME && errno != EINTR) + ev_syserr ("(libev) port_getn (see http://bugs.opensolaris.org/view_bug.do?bug_id=6268715, try LIBEV_FLAGS=3 env variable)"); + + for (i = 0; i < nget; ++i) + { + if (port_events [i].portev_source == PORT_SOURCE_FD) + { + int fd = port_events [i].portev_object; + + fd_event ( + EV_A_ + fd, + (port_events [i].portev_events & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0) + | (port_events [i].portev_events & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0) + ); + + fd_change (EV_A_ fd, EV__IOFDSET); + } + } + + if (ecb_expect_false (nget == port_eventmax)) + { + ev_free (port_events); + port_eventmax = array_nextsize (sizeof (port_event_t), port_eventmax, port_eventmax + 1); + port_events = (port_event_t *)ev_malloc (sizeof (port_event_t) * port_eventmax); + } +} + +inline_size +int +port_init (EV_P_ int flags) +{ + /* Initialize the kernel queue */ + if ((backend_fd = port_create ()) < 0) + return 0; + + assert (("libev: PORT_SOURCE_FD must not be zero", PORT_SOURCE_FD)); + + fcntl (backend_fd, F_SETFD, FD_CLOEXEC); /* not sure if necessary, hopefully doesn't hurt */ + + /* if my reading of the opensolaris kernel sources are correct, then + * opensolaris does something very stupid: it checks if the time has already + * elapsed and doesn't round up if that is the case, otherwise it DOES round + * up. Since we can't know what the case is, we need to guess by using a + * "large enough" timeout. Normally, 1e-9 would be correct. + */ + backend_mintime = EV_TS_CONST (1e-3); /* needed to compensate for port_getn returning early */ + backend_modify = port_modify; + backend_poll = port_poll; + + port_eventmax = 64; /* initial number of events receivable per poll */ + port_events = (port_event_t *)ev_malloc (sizeof (port_event_t) * port_eventmax); + + return EVBACKEND_PORT; +} + +inline_size +void +port_destroy (EV_P) +{ + ev_free (port_events); +} + +inline_size +void +port_fork (EV_P) +{ + close (backend_fd); + + while ((backend_fd = port_create ()) < 0) + ev_syserr ("(libev) port"); + + fcntl (backend_fd, F_SETFD, FD_CLOEXEC); + + /* re-register interest in fds */ + fd_rearm_all (EV_A); +} + diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_select.c b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_select.c new file mode 100644 index 00000000..b862c811 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_select.c @@ -0,0 +1,316 @@ +/* + * libev select fd activity backend + * + * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License ("GPL") version 2 or any later version, + * in which case the provisions of the GPL are applicable instead of + * the above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the BSD license, indicate your decision + * by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file under + * either the BSD or the GPL. + */ + +#ifndef _WIN32 +/* for unix systems */ +# include +# ifndef __hpux +/* for REAL unix systems */ +# include +# endif +#endif + +#ifndef EV_SELECT_USE_FD_SET +# ifdef NFDBITS +# define EV_SELECT_USE_FD_SET 0 +# else +# define EV_SELECT_USE_FD_SET 1 +# endif +#endif + +#if EV_SELECT_IS_WINSOCKET +# undef EV_SELECT_USE_FD_SET +# define EV_SELECT_USE_FD_SET 1 +# undef NFDBITS +# define NFDBITS 0 +#endif + +#if !EV_SELECT_USE_FD_SET +# define NFDBYTES (NFDBITS / 8) +#endif + +#include + +static void +select_modify (EV_P_ int fd, int oev, int nev) +{ + if (oev == nev) + return; + + { +#if EV_SELECT_USE_FD_SET + + #if EV_SELECT_IS_WINSOCKET + SOCKET handle = anfds [fd].handle; + #else + int handle = fd; + #endif + + assert (("libev: fd >= FD_SETSIZE passed to fd_set-based select backend", fd < FD_SETSIZE)); + + /* FD_SET is broken on windows (it adds the fd to a set twice or more, + * which eventually leads to overflows). Need to call it only on changes. + */ + #if EV_SELECT_IS_WINSOCKET + if ((oev ^ nev) & EV_READ) + #endif + if (nev & EV_READ) + FD_SET (handle, (fd_set *)vec_ri); + else + FD_CLR (handle, (fd_set *)vec_ri); + + #if EV_SELECT_IS_WINSOCKET + if ((oev ^ nev) & EV_WRITE) + #endif + if (nev & EV_WRITE) + FD_SET (handle, (fd_set *)vec_wi); + else + FD_CLR (handle, (fd_set *)vec_wi); + +#else + + int word = fd / NFDBITS; + fd_mask mask = 1UL << (fd % NFDBITS); + + if (ecb_expect_false (vec_max <= word)) + { + int new_max = word + 1; + + vec_ri = ev_realloc (vec_ri, new_max * NFDBYTES); + vec_ro = ev_realloc (vec_ro, new_max * NFDBYTES); /* could free/malloc */ + vec_wi = ev_realloc (vec_wi, new_max * NFDBYTES); + vec_wo = ev_realloc (vec_wo, new_max * NFDBYTES); /* could free/malloc */ + #ifdef _WIN32 + vec_eo = ev_realloc (vec_eo, new_max * NFDBYTES); /* could free/malloc */ + #endif + + for (; vec_max < new_max; ++vec_max) + ((fd_mask *)vec_ri) [vec_max] = + ((fd_mask *)vec_wi) [vec_max] = 0; + } + + ((fd_mask *)vec_ri) [word] |= mask; + if (!(nev & EV_READ)) + ((fd_mask *)vec_ri) [word] &= ~mask; + + ((fd_mask *)vec_wi) [word] |= mask; + if (!(nev & EV_WRITE)) + ((fd_mask *)vec_wi) [word] &= ~mask; +#endif + } +} + +static void +select_poll (EV_P_ ev_tstamp timeout) +{ + struct timeval tv; + int res; + int fd_setsize; + + EV_RELEASE_CB; + EV_TV_SET (tv, timeout); + +#if EV_SELECT_USE_FD_SET + fd_setsize = sizeof (fd_set); +#else + fd_setsize = vec_max * NFDBYTES; +#endif + + memcpy (vec_ro, vec_ri, fd_setsize); + memcpy (vec_wo, vec_wi, fd_setsize); + +#ifdef _WIN32 + /* pass in the write set as except set. + * the idea behind this is to work around a windows bug that causes + * errors to be reported as an exception and not by setting + * the writable bit. this is so uncontrollably lame. + */ + memcpy (vec_eo, vec_wi, fd_setsize); + res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, (fd_set *)vec_eo, &tv); +#elif EV_SELECT_USE_FD_SET + fd_setsize = anfdmax < FD_SETSIZE ? anfdmax : FD_SETSIZE; + res = select (fd_setsize, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv); +#else + res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv); +#endif + EV_ACQUIRE_CB; + + if (ecb_expect_false (res < 0)) + { + #if EV_SELECT_IS_WINSOCKET + errno = WSAGetLastError (); + #endif + #ifdef WSABASEERR + /* on windows, select returns incompatible error codes, fix this */ + if (errno >= WSABASEERR && errno < WSABASEERR + 1000) + if (errno == WSAENOTSOCK) + errno = EBADF; + else + errno -= WSABASEERR; + #endif + + #ifdef _WIN32 + /* select on windows erroneously returns EINVAL when no fd sets have been + * provided (this is documented). what microsoft doesn't tell you that this bug + * exists even when the fd sets _are_ provided, so we have to check for this bug + * here and emulate by sleeping manually. + * we also get EINVAL when the timeout is invalid, but we ignore this case here + * and assume that EINVAL always means: you have to wait manually. + */ + if (errno == EINVAL) + { + if (timeout) + { + unsigned long ms = EV_TS_TO_MSEC (timeout); + Sleep (ms ? ms : 1); + } + + return; + } + #endif + + if (errno == EBADF) + fd_ebadf (EV_A); + else if (errno == ENOMEM && !syserr_cb) + fd_enomem (EV_A); + else if (errno != EINTR) + ev_syserr ("(libev) select"); + + return; + } + +#if EV_SELECT_USE_FD_SET + + { + int fd; + + for (fd = 0; fd < anfdmax; ++fd) + if (anfds [fd].events) + { + int events = 0; + #if EV_SELECT_IS_WINSOCKET + SOCKET handle = anfds [fd].handle; + #else + int handle = fd; + #endif + + if (FD_ISSET (handle, (fd_set *)vec_ro)) events |= EV_READ; + if (FD_ISSET (handle, (fd_set *)vec_wo)) events |= EV_WRITE; + #ifdef _WIN32 + if (FD_ISSET (handle, (fd_set *)vec_eo)) events |= EV_WRITE; + #endif + + if (ecb_expect_true (events)) + fd_event (EV_A_ fd, events); + } + } + +#else + + { + int word, bit; + for (word = vec_max; word--; ) + { + fd_mask word_r = ((fd_mask *)vec_ro) [word]; + fd_mask word_w = ((fd_mask *)vec_wo) [word]; + #ifdef _WIN32 + word_w |= ((fd_mask *)vec_eo) [word]; + #endif + + if (word_r || word_w) + for (bit = NFDBITS; bit--; ) + { + fd_mask mask = 1UL << bit; + int events = 0; + + events |= word_r & mask ? EV_READ : 0; + events |= word_w & mask ? EV_WRITE : 0; + + if (ecb_expect_true (events)) + fd_event (EV_A_ word * NFDBITS + bit, events); + } + } + } + +#endif +} + +inline_size +int +select_init (EV_P_ int flags) +{ + backend_mintime = EV_TS_CONST (1e-6); + backend_modify = select_modify; + backend_poll = select_poll; + +#if EV_SELECT_USE_FD_SET + vec_ri = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_ri); + vec_ro = ev_malloc (sizeof (fd_set)); + vec_wi = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_wi); + vec_wo = ev_malloc (sizeof (fd_set)); + #ifdef _WIN32 + vec_eo = ev_malloc (sizeof (fd_set)); + #endif +#else + vec_max = 0; + vec_ri = 0; + vec_ro = 0; + vec_wi = 0; + vec_wo = 0; + #ifdef _WIN32 + vec_eo = 0; + #endif +#endif + + return EVBACKEND_SELECT; +} + +inline_size +void +select_destroy (EV_P) +{ + ev_free (vec_ri); + ev_free (vec_ro); + ev_free (vec_wi); + ev_free (vec_wo); + #ifdef _WIN32 + ev_free (vec_eo); + #endif +} + diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_vars.h b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_vars.h new file mode 100644 index 00000000..fb0c5831 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_vars.h @@ -0,0 +1,249 @@ +/* + * loop member variable declarations + * + * Copyright (c) 2007,2008,2009,2010,2011,2012,2013,2019 Marc Alexander Lehmann + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License ("GPL") version 2 or any later version, + * in which case the provisions of the GPL are applicable instead of + * the above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the BSD license, indicate your decision + * by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file under + * either the BSD or the GPL. + */ + +#define VARx(type,name) VAR(name, type name) + +VARx(ev_tstamp, now_floor) /* last time we refreshed rt_time */ +VARx(ev_tstamp, mn_now) /* monotonic clock "now" */ +VARx(ev_tstamp, rtmn_diff) /* difference realtime - monotonic time */ + +/* for reverse feeding of events */ +VARx(W *, rfeeds) +VARx(int, rfeedmax) +VARx(int, rfeedcnt) + +VAR (pendings, ANPENDING *pendings [NUMPRI]) +VAR (pendingmax, int pendingmax [NUMPRI]) +VAR (pendingcnt, int pendingcnt [NUMPRI]) +VARx(int, pendingpri) /* highest priority currently pending */ +VARx(ev_prepare, pending_w) /* dummy pending watcher */ + +VARx(ev_tstamp, io_blocktime) +VARx(ev_tstamp, timeout_blocktime) + +VARx(int, backend) +VARx(int, activecnt) /* total number of active events ("refcount") */ +VARx(EV_ATOMIC_T, loop_done) /* signal by ev_break */ + +VARx(int, backend_fd) +VARx(ev_tstamp, backend_mintime) /* assumed typical timer resolution */ +VAR (backend_modify, void (*backend_modify)(EV_P_ int fd, int oev, int nev)) +VAR (backend_poll , void (*backend_poll)(EV_P_ ev_tstamp timeout)) + +VARx(ANFD *, anfds) +VARx(int, anfdmax) + +VAR (evpipe, int evpipe [2]) +VARx(ev_io, pipe_w) +VARx(EV_ATOMIC_T, pipe_write_wanted) +VARx(EV_ATOMIC_T, pipe_write_skipped) + +#if !defined(_WIN32) || EV_GENWRAP +VARx(pid_t, curpid) +#endif + +VARx(char, postfork) /* true if we need to recreate kernel state after fork */ + +#if EV_USE_SELECT || EV_GENWRAP +VARx(void *, vec_ri) +VARx(void *, vec_ro) +VARx(void *, vec_wi) +VARx(void *, vec_wo) +#if defined(_WIN32) || EV_GENWRAP +VARx(void *, vec_eo) +#endif +VARx(int, vec_max) +#endif + +#if EV_USE_POLL || EV_GENWRAP +VARx(struct pollfd *, polls) +VARx(int, pollmax) +VARx(int, pollcnt) +VARx(int *, pollidxs) /* maps fds into structure indices */ +VARx(int, pollidxmax) +#endif + +#if EV_USE_EPOLL || EV_GENWRAP +VARx(struct epoll_event *, epoll_events) +VARx(int, epoll_eventmax) +VARx(int *, epoll_eperms) +VARx(int, epoll_epermcnt) +VARx(int, epoll_epermmax) +#endif + +#if EV_USE_LINUXAIO || EV_GENWRAP +VARx(aio_context_t, linuxaio_ctx) +VARx(int, linuxaio_iteration) +VARx(struct aniocb **, linuxaio_iocbps) +VARx(int, linuxaio_iocbpmax) +VARx(struct iocb **, linuxaio_submits) +VARx(int, linuxaio_submitcnt) +VARx(int, linuxaio_submitmax) +VARx(ev_io, linuxaio_epoll_w) +#endif + +#if EV_USE_IOURING || EV_GENWRAP +VARx(int, iouring_fd) +VARx(unsigned, iouring_to_submit); +VARx(int, iouring_entries) +VARx(int, iouring_max_entries) +VARx(void *, iouring_sq_ring) +VARx(void *, iouring_cq_ring) +VARx(void *, iouring_sqes) +VARx(uint32_t, iouring_sq_ring_size) +VARx(uint32_t, iouring_cq_ring_size) +VARx(uint32_t, iouring_sqes_size) +VARx(uint32_t, iouring_sq_head) +VARx(uint32_t, iouring_sq_tail) +VARx(uint32_t, iouring_sq_ring_mask) +VARx(uint32_t, iouring_sq_ring_entries) +VARx(uint32_t, iouring_sq_flags) +VARx(uint32_t, iouring_sq_dropped) +VARx(uint32_t, iouring_sq_array) +VARx(uint32_t, iouring_cq_head) +VARx(uint32_t, iouring_cq_tail) +VARx(uint32_t, iouring_cq_ring_mask) +VARx(uint32_t, iouring_cq_ring_entries) +VARx(uint32_t, iouring_cq_overflow) +VARx(uint32_t, iouring_cq_cqes) +VARx(ev_tstamp, iouring_tfd_to) +VARx(int, iouring_tfd) +VARx(ev_io, iouring_tfd_w) +#endif + +#if EV_USE_KQUEUE || EV_GENWRAP +VARx(pid_t, kqueue_fd_pid) +VARx(struct kevent *, kqueue_changes) +VARx(int, kqueue_changemax) +VARx(int, kqueue_changecnt) +VARx(struct kevent *, kqueue_events) +VARx(int, kqueue_eventmax) +#endif + +#if EV_USE_PORT || EV_GENWRAP +VARx(struct port_event *, port_events) +VARx(int, port_eventmax) +#endif + +#if EV_USE_IOCP || EV_GENWRAP +VARx(HANDLE, iocp) +#endif + +VARx(int *, fdchanges) +VARx(int, fdchangemax) +VARx(int, fdchangecnt) + +VARx(ANHE *, timers) +VARx(int, timermax) +VARx(int, timercnt) + +#if EV_PERIODIC_ENABLE || EV_GENWRAP +VARx(ANHE *, periodics) +VARx(int, periodicmax) +VARx(int, periodiccnt) +#endif + +#if EV_IDLE_ENABLE || EV_GENWRAP +VAR (idles, ev_idle **idles [NUMPRI]) +VAR (idlemax, int idlemax [NUMPRI]) +VAR (idlecnt, int idlecnt [NUMPRI]) +#endif +VARx(int, idleall) /* total number */ + +VARx(struct ev_prepare **, prepares) +VARx(int, preparemax) +VARx(int, preparecnt) + +VARx(struct ev_check **, checks) +VARx(int, checkmax) +VARx(int, checkcnt) + +#if EV_FORK_ENABLE || EV_GENWRAP +VARx(struct ev_fork **, forks) +VARx(int, forkmax) +VARx(int, forkcnt) +#endif + +#if EV_CLEANUP_ENABLE || EV_GENWRAP +VARx(struct ev_cleanup **, cleanups) +VARx(int, cleanupmax) +VARx(int, cleanupcnt) +#endif + +#if EV_ASYNC_ENABLE || EV_GENWRAP +VARx(EV_ATOMIC_T, async_pending) +VARx(struct ev_async **, asyncs) +VARx(int, asyncmax) +VARx(int, asynccnt) +#endif + +#if EV_USE_INOTIFY || EV_GENWRAP +VARx(int, fs_fd) +VARx(ev_io, fs_w) +VARx(char, fs_2625) /* whether we are running in linux 2.6.25 or newer */ +VAR (fs_hash, ANFS fs_hash [EV_INOTIFY_HASHSIZE]) +#endif + +VARx(EV_ATOMIC_T, sig_pending) +#if EV_USE_SIGNALFD || EV_GENWRAP +VARx(int, sigfd) +VARx(ev_io, sigfd_w) +VARx(sigset_t, sigfd_set) +#endif + +#if EV_USE_TIMERFD || EV_GENWRAP +VARx(int, timerfd) /* timerfd for time jump detection */ +VARx(ev_io, timerfd_w) +#endif + +VARx(unsigned int, origflags) /* original loop flags */ + +#if EV_FEATURE_API || EV_GENWRAP +VARx(unsigned int, loop_count) /* total number of loop iterations/blocks */ +VARx(unsigned int, loop_depth) /* #ev_run enters - #ev_run leaves */ + +VARx(void *, userdata) +/* C++ doesn't support the ev_loop_callback typedef here. stinks. */ +VAR (release_cb, void (*release_cb)(EV_P) EV_NOEXCEPT) +VAR (acquire_cb, void (*acquire_cb)(EV_P) EV_NOEXCEPT) +VAR (invoke_cb , ev_loop_callback invoke_cb) +#endif + +#undef VARx + diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_win32.c b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_win32.c new file mode 100644 index 00000000..97344c3e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_win32.c @@ -0,0 +1,162 @@ +/* + * libev win32 compatibility cruft (_not_ a backend) + * + * Copyright (c) 2007,2008,2009 Marc Alexander Lehmann + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License ("GPL") version 2 or any later version, + * in which case the provisions of the GPL are applicable instead of + * the above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the BSD license, indicate your decision + * by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file under + * either the BSD or the GPL. + */ + +#ifdef _WIN32 + +/* note: the comment below could not be substantiated, but what would I care */ +/* MSDN says this is required to handle SIGFPE */ +/* my wild guess would be that using something floating-pointy is required */ +/* for the crt to do something about it */ +volatile double SIGFPE_REQ = 0.0f; + +static SOCKET +ev_tcp_socket (void) +{ +#if EV_USE_WSASOCKET + return WSASocket (AF_INET, SOCK_STREAM, 0, 0, 0, 0); +#else + return socket (AF_INET, SOCK_STREAM, 0); +#endif +} + +/* oh, the humanity! */ +static int +ev_pipe (int filedes [2]) +{ + struct sockaddr_in addr = { 0 }; + int addr_size = sizeof (addr); + struct sockaddr_in adr2; + int adr2_size = sizeof (adr2); + SOCKET listener; + SOCKET sock [2] = { -1, -1 }; + + if ((listener = ev_tcp_socket ()) == INVALID_SOCKET) + return -1; + + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); + addr.sin_port = 0; + + if (bind (listener, (struct sockaddr *)&addr, addr_size)) + goto fail; + + if (getsockname (listener, (struct sockaddr *)&addr, &addr_size)) + goto fail; + + if (listen (listener, 1)) + goto fail; + + if ((sock [0] = ev_tcp_socket ()) == INVALID_SOCKET) + goto fail; + + if (connect (sock [0], (struct sockaddr *)&addr, addr_size)) + goto fail; + + /* TODO: returns INVALID_SOCKET on winsock accept, not < 0. fix it */ + /* when convenient, probably by just removing error checking altogether? */ + if ((sock [1] = accept (listener, 0, 0)) < 0) + goto fail; + + /* windows vista returns fantasy port numbers for sockets: + * example for two interconnected tcp sockets: + * + * (Socket::unpack_sockaddr_in getsockname $sock0)[0] == 53364 + * (Socket::unpack_sockaddr_in getpeername $sock0)[0] == 53363 + * (Socket::unpack_sockaddr_in getsockname $sock1)[0] == 53363 + * (Socket::unpack_sockaddr_in getpeername $sock1)[0] == 53365 + * + * wow! tridirectional sockets! + * + * this way of checking ports seems to work: + */ + if (getpeername (sock [0], (struct sockaddr *)&addr, &addr_size)) + goto fail; + + if (getsockname (sock [1], (struct sockaddr *)&adr2, &adr2_size)) + goto fail; + + errno = WSAEINVAL; + if (addr_size != adr2_size + || addr.sin_addr.s_addr != adr2.sin_addr.s_addr /* just to be sure, I mean, it's windows */ + || addr.sin_port != adr2.sin_port) + goto fail; + + closesocket (listener); + +#if EV_SELECT_IS_WINSOCKET + filedes [0] = EV_WIN32_HANDLE_TO_FD (sock [0]); + filedes [1] = EV_WIN32_HANDLE_TO_FD (sock [1]); +#else + /* when select isn't winsocket, we also expect socket, connect, accept etc. + * to work on fds */ + filedes [0] = sock [0]; + filedes [1] = sock [1]; +#endif + + return 0; + +fail: + closesocket (listener); + + if (sock [0] != INVALID_SOCKET) closesocket (sock [0]); + if (sock [1] != INVALID_SOCKET) closesocket (sock [1]); + + return -1; +} + +#undef pipe +#define pipe(filedes) ev_pipe (filedes) + +#define EV_HAVE_EV_TIME 1 +ev_tstamp +ev_time (void) +{ + FILETIME ft; + ULARGE_INTEGER ui; + + GetSystemTimeAsFileTime (&ft); + ui.u.LowPart = ft.dwLowDateTime; + ui.u.HighPart = ft.dwHighDateTime; + + /* also, msvc cannot convert ulonglong to double... yes, it is that sucky */ + return EV_TS_FROM_USEC (((LONGLONG)(ui.QuadPart - 116444736000000000) * 1e-1)); +} + +#endif + diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_wrap.h b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_wrap.h new file mode 100644 index 00000000..45d793ce --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/libev/ev_wrap.h @@ -0,0 +1,272 @@ +/* DO NOT EDIT, automatically generated by update_ev_wrap */ +#ifndef EV_WRAP_H +#define EV_WRAP_H +#define acquire_cb ((loop)->acquire_cb) +#define activecnt ((loop)->activecnt) +#define anfdmax ((loop)->anfdmax) +#define anfds ((loop)->anfds) +#define async_pending ((loop)->async_pending) +#define asynccnt ((loop)->asynccnt) +#define asyncmax ((loop)->asyncmax) +#define asyncs ((loop)->asyncs) +#define backend ((loop)->backend) +#define backend_fd ((loop)->backend_fd) +#define backend_mintime ((loop)->backend_mintime) +#define backend_modify ((loop)->backend_modify) +#define backend_poll ((loop)->backend_poll) +#define checkcnt ((loop)->checkcnt) +#define checkmax ((loop)->checkmax) +#define checks ((loop)->checks) +#define cleanupcnt ((loop)->cleanupcnt) +#define cleanupmax ((loop)->cleanupmax) +#define cleanups ((loop)->cleanups) +#define curpid ((loop)->curpid) +#define epoll_epermcnt ((loop)->epoll_epermcnt) +#define epoll_epermmax ((loop)->epoll_epermmax) +#define epoll_eperms ((loop)->epoll_eperms) +#define epoll_eventmax ((loop)->epoll_eventmax) +#define epoll_events ((loop)->epoll_events) +#define evpipe ((loop)->evpipe) +#define fdchangecnt ((loop)->fdchangecnt) +#define fdchangemax ((loop)->fdchangemax) +#define fdchanges ((loop)->fdchanges) +#define forkcnt ((loop)->forkcnt) +#define forkmax ((loop)->forkmax) +#define forks ((loop)->forks) +#define fs_2625 ((loop)->fs_2625) +#define fs_fd ((loop)->fs_fd) +#define fs_hash ((loop)->fs_hash) +#define fs_w ((loop)->fs_w) +#define idleall ((loop)->idleall) +#define idlecnt ((loop)->idlecnt) +#define idlemax ((loop)->idlemax) +#define idles ((loop)->idles) +#define invoke_cb ((loop)->invoke_cb) +#define io_blocktime ((loop)->io_blocktime) +#define iocp ((loop)->iocp) +#define iouring_cq_cqes ((loop)->iouring_cq_cqes) +#define iouring_cq_head ((loop)->iouring_cq_head) +#define iouring_cq_overflow ((loop)->iouring_cq_overflow) +#define iouring_cq_ring ((loop)->iouring_cq_ring) +#define iouring_cq_ring_entries ((loop)->iouring_cq_ring_entries) +#define iouring_cq_ring_mask ((loop)->iouring_cq_ring_mask) +#define iouring_cq_ring_size ((loop)->iouring_cq_ring_size) +#define iouring_cq_tail ((loop)->iouring_cq_tail) +#define iouring_entries ((loop)->iouring_entries) +#define iouring_fd ((loop)->iouring_fd) +#define iouring_max_entries ((loop)->iouring_max_entries) +#define iouring_sq_array ((loop)->iouring_sq_array) +#define iouring_sq_dropped ((loop)->iouring_sq_dropped) +#define iouring_sq_flags ((loop)->iouring_sq_flags) +#define iouring_sq_head ((loop)->iouring_sq_head) +#define iouring_sq_ring ((loop)->iouring_sq_ring) +#define iouring_sq_ring_entries ((loop)->iouring_sq_ring_entries) +#define iouring_sq_ring_mask ((loop)->iouring_sq_ring_mask) +#define iouring_sq_ring_size ((loop)->iouring_sq_ring_size) +#define iouring_sq_tail ((loop)->iouring_sq_tail) +#define iouring_sqes ((loop)->iouring_sqes) +#define iouring_sqes_size ((loop)->iouring_sqes_size) +#define iouring_tfd ((loop)->iouring_tfd) +#define iouring_tfd_to ((loop)->iouring_tfd_to) +#define iouring_tfd_w ((loop)->iouring_tfd_w) +#define iouring_to_submit ((loop)->iouring_to_submit) +#define kqueue_changecnt ((loop)->kqueue_changecnt) +#define kqueue_changemax ((loop)->kqueue_changemax) +#define kqueue_changes ((loop)->kqueue_changes) +#define kqueue_eventmax ((loop)->kqueue_eventmax) +#define kqueue_events ((loop)->kqueue_events) +#define kqueue_fd_pid ((loop)->kqueue_fd_pid) +#define linuxaio_ctx ((loop)->linuxaio_ctx) +#define linuxaio_epoll_w ((loop)->linuxaio_epoll_w) +#define linuxaio_iocbpmax ((loop)->linuxaio_iocbpmax) +#define linuxaio_iocbps ((loop)->linuxaio_iocbps) +#define linuxaio_iteration ((loop)->linuxaio_iteration) +#define linuxaio_submitcnt ((loop)->linuxaio_submitcnt) +#define linuxaio_submitmax ((loop)->linuxaio_submitmax) +#define linuxaio_submits ((loop)->linuxaio_submits) +#define loop_count ((loop)->loop_count) +#define loop_depth ((loop)->loop_depth) +#define loop_done ((loop)->loop_done) +#define mn_now ((loop)->mn_now) +#define now_floor ((loop)->now_floor) +#define origflags ((loop)->origflags) +#define pending_w ((loop)->pending_w) +#define pendingcnt ((loop)->pendingcnt) +#define pendingmax ((loop)->pendingmax) +#define pendingpri ((loop)->pendingpri) +#define pendings ((loop)->pendings) +#define periodiccnt ((loop)->periodiccnt) +#define periodicmax ((loop)->periodicmax) +#define periodics ((loop)->periodics) +#define pipe_w ((loop)->pipe_w) +#define pipe_write_skipped ((loop)->pipe_write_skipped) +#define pipe_write_wanted ((loop)->pipe_write_wanted) +#define pollcnt ((loop)->pollcnt) +#define pollidxmax ((loop)->pollidxmax) +#define pollidxs ((loop)->pollidxs) +#define pollmax ((loop)->pollmax) +#define polls ((loop)->polls) +#define port_eventmax ((loop)->port_eventmax) +#define port_events ((loop)->port_events) +#define postfork ((loop)->postfork) +#define preparecnt ((loop)->preparecnt) +#define preparemax ((loop)->preparemax) +#define prepares ((loop)->prepares) +#define release_cb ((loop)->release_cb) +#define rfeedcnt ((loop)->rfeedcnt) +#define rfeedmax ((loop)->rfeedmax) +#define rfeeds ((loop)->rfeeds) +#define rtmn_diff ((loop)->rtmn_diff) +#define sig_pending ((loop)->sig_pending) +#define sigfd ((loop)->sigfd) +#define sigfd_set ((loop)->sigfd_set) +#define sigfd_w ((loop)->sigfd_w) +#define timeout_blocktime ((loop)->timeout_blocktime) +#define timercnt ((loop)->timercnt) +#define timerfd ((loop)->timerfd) +#define timerfd_w ((loop)->timerfd_w) +#define timermax ((loop)->timermax) +#define timers ((loop)->timers) +#define userdata ((loop)->userdata) +#define vec_eo ((loop)->vec_eo) +#define vec_max ((loop)->vec_max) +#define vec_ri ((loop)->vec_ri) +#define vec_ro ((loop)->vec_ro) +#define vec_wi ((loop)->vec_wi) +#define vec_wo ((loop)->vec_wo) +#else +#undef EV_WRAP_H +#undef acquire_cb +#undef activecnt +#undef anfdmax +#undef anfds +#undef async_pending +#undef asynccnt +#undef asyncmax +#undef asyncs +#undef backend +#undef backend_fd +#undef backend_mintime +#undef backend_modify +#undef backend_poll +#undef checkcnt +#undef checkmax +#undef checks +#undef cleanupcnt +#undef cleanupmax +#undef cleanups +#undef curpid +#undef epoll_epermcnt +#undef epoll_epermmax +#undef epoll_eperms +#undef epoll_eventmax +#undef epoll_events +#undef evpipe +#undef fdchangecnt +#undef fdchangemax +#undef fdchanges +#undef forkcnt +#undef forkmax +#undef forks +#undef fs_2625 +#undef fs_fd +#undef fs_hash +#undef fs_w +#undef idleall +#undef idlecnt +#undef idlemax +#undef idles +#undef invoke_cb +#undef io_blocktime +#undef iocp +#undef iouring_cq_cqes +#undef iouring_cq_head +#undef iouring_cq_overflow +#undef iouring_cq_ring +#undef iouring_cq_ring_entries +#undef iouring_cq_ring_mask +#undef iouring_cq_ring_size +#undef iouring_cq_tail +#undef iouring_entries +#undef iouring_fd +#undef iouring_max_entries +#undef iouring_sq_array +#undef iouring_sq_dropped +#undef iouring_sq_flags +#undef iouring_sq_head +#undef iouring_sq_ring +#undef iouring_sq_ring_entries +#undef iouring_sq_ring_mask +#undef iouring_sq_ring_size +#undef iouring_sq_tail +#undef iouring_sqes +#undef iouring_sqes_size +#undef iouring_tfd +#undef iouring_tfd_to +#undef iouring_tfd_w +#undef iouring_to_submit +#undef kqueue_changecnt +#undef kqueue_changemax +#undef kqueue_changes +#undef kqueue_eventmax +#undef kqueue_events +#undef kqueue_fd_pid +#undef linuxaio_ctx +#undef linuxaio_epoll_w +#undef linuxaio_iocbpmax +#undef linuxaio_iocbps +#undef linuxaio_iteration +#undef linuxaio_submitcnt +#undef linuxaio_submitmax +#undef linuxaio_submits +#undef loop_count +#undef loop_depth +#undef loop_done +#undef mn_now +#undef now_floor +#undef origflags +#undef pending_w +#undef pendingcnt +#undef pendingmax +#undef pendingpri +#undef pendings +#undef periodiccnt +#undef periodicmax +#undef periodics +#undef pipe_w +#undef pipe_write_skipped +#undef pipe_write_wanted +#undef pollcnt +#undef pollidxmax +#undef pollidxs +#undef pollmax +#undef polls +#undef port_eventmax +#undef port_events +#undef postfork +#undef preparecnt +#undef preparemax +#undef prepares +#undef release_cb +#undef rfeedcnt +#undef rfeedmax +#undef rfeeds +#undef rtmn_diff +#undef sig_pending +#undef sigfd +#undef sigfd_set +#undef sigfd_w +#undef timeout_blocktime +#undef timercnt +#undef timerfd +#undef timerfd_w +#undef timermax +#undef timers +#undef userdata +#undef vec_eo +#undef vec_max +#undef vec_ri +#undef vec_ro +#undef vec_wi +#undef vec_wo +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/.clang-format b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/.clang-format new file mode 100644 index 00000000..6ad3f63f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/.clang-format @@ -0,0 +1,16 @@ +--- +Language: Cpp +BasedOnStyle: WebKit +AllowAllParametersOfDeclarationOnNextLine: false +BinPackArguments: false +BinPackParameters: false +AlignConsecutiveMacros: false +AlignConsecutiveAssignments: false +BreakBeforeBraces: Linux +BraceWrapping: + AfterControlStatement: Never +IndentCaseLabels: true +PointerAlignment: Right +SpaceBeforeParens: ControlStatements +IndentWidth: 4 +... diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/Makefile b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/Makefile new file mode 100644 index 00000000..1e8a6645 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/Makefile @@ -0,0 +1,273 @@ + +SHELL = /bin/sh + +# V=0 quiet, V=1 verbose. other values don't work. +V = 0 +V0 = $(V:0=) +Q1 = $(V:1=) +Q = $(Q1:0=@) +ECHO1 = $(V:1=@ :) +ECHO = $(ECHO1:0=@ echo) +NULLCMD = : + +#### Start of system configuration section. #### + +srcdir = . +topdir = /opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 +hdrdir = $(topdir) +arch_hdrdir = /opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux +PATH_SEPARATOR = : +VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby +prefix = $(DESTDIR)/opt/hostedtoolcache/Ruby/3.4.4/x64 +rubysitearchprefix = $(rubylibprefix)/$(sitearch) +rubyarchprefix = $(rubylibprefix)/$(arch) +rubylibprefix = $(libdir)/$(RUBY_BASE_NAME) +exec_prefix = $(prefix) +vendorarchhdrdir = $(vendorhdrdir)/$(sitearch) +sitearchhdrdir = $(sitehdrdir)/$(sitearch) +rubyarchhdrdir = $(rubyhdrdir)/$(arch) +vendorhdrdir = $(rubyhdrdir)/vendor_ruby +sitehdrdir = $(rubyhdrdir)/site_ruby +rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME) +vendorarchdir = $(vendorlibdir)/$(sitearch) +vendorlibdir = $(vendordir)/$(ruby_version) +vendordir = $(rubylibprefix)/vendor_ruby +sitearchdir = $(sitelibdir)/$(sitearch) +sitelibdir = $(sitedir)/$(ruby_version) +sitedir = $(rubylibprefix)/site_ruby +rubyarchdir = $(rubylibdir)/$(arch) +rubylibdir = $(rubylibprefix)/$(ruby_version) +sitearchincludedir = $(includedir)/$(sitearch) +archincludedir = $(includedir)/$(arch) +sitearchlibdir = $(libdir)/$(sitearch) +archlibdir = $(libdir)/$(arch) +ridir = $(datarootdir)/$(RI_BASE_NAME) +modular_gc_dir = $(DESTDIR) +mandir = $(datarootdir)/man +localedir = $(datarootdir)/locale +libdir = $(exec_prefix)/lib +psdir = $(docdir) +pdfdir = $(docdir) +dvidir = $(docdir) +htmldir = $(docdir) +infodir = $(datarootdir)/info +docdir = $(datarootdir)/doc/$(PACKAGE) +oldincludedir = $(DESTDIR)/usr/include +includedir = $(prefix)/include +runstatedir = $(localstatedir)/run +localstatedir = $(prefix)/var +sharedstatedir = $(prefix)/com +sysconfdir = $(prefix)/etc +datadir = $(datarootdir) +datarootdir = $(prefix)/share +libexecdir = $(exec_prefix)/libexec +sbindir = $(exec_prefix)/sbin +bindir = $(exec_prefix)/bin +archdir = $(rubyarchdir) + + +CC_WRAPPER = +CC = gcc +CXX = g++ +LIBRUBY = $(LIBRUBY_SO) +LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a +LIBRUBYARG_SHARED = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME) +LIBRUBYARG_STATIC = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)-static $(MAINLIBS) +empty = +OUTFLAG = -o $(empty) +COUTFLAG = -o $(empty) +CSRCFLAG = $(empty) + +RUBY_EXTCONF_H = +cflags = $(hardenflags) $(optflags) $(debugflags) $(warnflags) +cxxflags = +optflags = -O3 -fno-fast-math -fno-strict-aliasing +debugflags = -ggdb3 +warnflags = -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef +cppflags = +CCDLFLAGS = -fPIC +CFLAGS = $(CCDLFLAGS) $(cflags) -fPIC $(ARCH_FLAG) +INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) +DEFS = +CPPFLAGS = -DHAVE_UNISTD_H -DHAVE_RB_IO_DESCRIPTOR -DHAVE_LINUX_AIO_ABI_H -DEV_USE_LINUXAIO -DHAVE_LINUX_IO_URING_H -DEV_USE_IOURING -DHAVE_SYS_SELECT_H -DEV_USE_SELECT -DHAVE_SYS_EPOLL_H -DEV_USE_EPOLL -DHAVE_SYS_RESOURCE_H -DHAVE_SYS_RESOURCE_H -DEV_STANDALONE -DENABLE_PATH_CHECK=0 $(DEFS) $(cppflags) +CXXFLAGS = $(CCDLFLAGS) $(ARCH_FLAG) +ldflags = -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed +dldflags = -Wl,--compress-debug-sections=zlib +ARCH_FLAG = +DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG) +LDSHARED = $(CC) -shared +LDSHAREDXX = $(CXX) -shared +POSTLINK = : +AR = gcc-ar +LD = ld +EXEEXT = + +RUBY_INSTALL_NAME = $(RUBY_BASE_NAME) +RUBY_SO_NAME = ruby +RUBYW_INSTALL_NAME = +RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version) +RUBYW_BASE_NAME = rubyw +RUBY_BASE_NAME = ruby + +arch = x86_64-linux +sitearch = $(arch) +ruby_version = 3.4.0 +ruby = $(bindir)/$(RUBY_BASE_NAME) +RUBY = $(ruby) +BUILTRUBY = $(bindir)/$(RUBY_BASE_NAME) +ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/backward.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h + +RM = rm -f +RM_RF = rm -fr +RMDIRS = rmdir --ignore-fail-on-non-empty -p +MAKEDIRS = /usr/bin/mkdir -p +INSTALL = /usr/bin/install -c +INSTALL_PROG = $(INSTALL) -m 0755 +INSTALL_DATA = $(INSTALL) -m 644 +COPY = cp +TOUCH = exit > + +#### End of system configuration section. #### + +preload = +libpath = . $(libdir) +LIBPATH = -L. -L$(libdir) -Wl,-rpath,$(libdir) +DEFFILE = + +CLEANFILES = mkmf.log +DISTCLEANFILES = +DISTCLEANDIRS = + +extout = +extout_prefix = +target_prefix = +LOCAL_LIBS = +LIBS = $(LIBRUBYARG_SHARED) -lm -lpthread -lc +ORIG_SRCS = bytebuffer.c monitor.c nio4r_ext.c selector.c +SRCS = $(ORIG_SRCS) +OBJS = bytebuffer.o monitor.o nio4r_ext.o selector.o +HDRS = $(srcdir)/libev.h $(srcdir)/nio4r.h +LOCAL_HDRS = +TARGET = nio4r_ext +TARGET_NAME = nio4r_ext +TARGET_ENTRY = Init_$(TARGET_NAME) +DLLIB = $(TARGET).so +EXTSTATIC = +STATIC_LIB = + +TIMESTAMP_DIR = . +BINDIR = $(bindir) +RUBYCOMMONDIR = $(sitedir)$(target_prefix) +RUBYLIBDIR = $(sitelibdir)$(target_prefix) +RUBYARCHDIR = $(sitearchdir)$(target_prefix) +HDRDIR = $(sitehdrdir)$(target_prefix) +ARCHHDRDIR = $(sitearchhdrdir)$(target_prefix) +TARGET_SO_DIR = +TARGET_SO = $(TARGET_SO_DIR)$(DLLIB) +CLEANLIBS = $(TARGET_SO) false +CLEANOBJS = $(OBJS) *.bak +TARGET_SO_DIR_TIMESTAMP = $(TIMESTAMP_DIR)/.sitearchdir.time + +all: $(DLLIB) +static: $(STATIC_LIB) +.PHONY: all install static install-so install-rb +.PHONY: clean clean-so clean-static clean-rb + +clean-static:: +clean-rb-default:: +clean-rb:: +clean-so:: +clean: clean-so clean-static clean-rb-default clean-rb + -$(Q)$(RM_RF) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time + +distclean-rb-default:: +distclean-rb:: +distclean-so:: +distclean-static:: +distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb + -$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + -$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + -$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true + +realclean: distclean +install: install-so install-rb + +install-so: $(DLLIB) $(TARGET_SO_DIR_TIMESTAMP) + $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) +clean-static:: + -$(Q)$(RM) $(STATIC_LIB) +install-rb: pre-install-rb do-install-rb install-rb-default +install-rb-default: pre-install-rb-default do-install-rb-default +pre-install-rb: Makefile +pre-install-rb-default: Makefile +do-install-rb: +do-install-rb-default: +pre-install-rb-default: + @$(NULLCMD) +$(TARGET_SO_DIR_TIMESTAMP): + $(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR) + $(Q) $(TOUCH) $@ + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + +.SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S + +.cc.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cc.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.mm.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.mm.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cxx.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cxx.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cpp.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cpp.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.c.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.c.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.m.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.m.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +$(TARGET_SO): $(OBJS) Makefile + $(ECHO) linking shared-object $(DLLIB) + -$(Q)$(RM) $(@) + $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) + $(Q) $(POSTLINK) + + + +$(OBJS): $(HDRS) $(ruby_headers) diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/bytebuffer.c b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/bytebuffer.c new file mode 100644 index 00000000..99e34f2b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/bytebuffer.c @@ -0,0 +1,465 @@ +#include "nio4r.h" + +static VALUE mNIO = Qnil; +static VALUE cNIO_ByteBuffer = Qnil; +static VALUE cNIO_ByteBuffer_OverflowError = Qnil; +static VALUE cNIO_ByteBuffer_UnderflowError = Qnil; +static VALUE cNIO_ByteBuffer_MarkUnsetError = Qnil; + +/* Allocator/deallocator */ +static VALUE NIO_ByteBuffer_allocate(VALUE klass); +static void NIO_ByteBuffer_free(void *data); +static size_t NIO_ByteBuffer_memsize(const void *data); + +/* Methods */ +static VALUE NIO_ByteBuffer_initialize(VALUE self, VALUE capacity); +static VALUE NIO_ByteBuffer_clear(VALUE self); +static VALUE NIO_ByteBuffer_get_position(VALUE self); +static VALUE NIO_ByteBuffer_set_position(VALUE self, VALUE new_position); +static VALUE NIO_ByteBuffer_get_limit(VALUE self); +static VALUE NIO_ByteBuffer_set_limit(VALUE self, VALUE new_limit); +static VALUE NIO_ByteBuffer_capacity(VALUE self); +static VALUE NIO_ByteBuffer_remaining(VALUE self); +static VALUE NIO_ByteBuffer_full(VALUE self); +static VALUE NIO_ByteBuffer_get(int argc, VALUE *argv, VALUE self); +static VALUE NIO_ByteBuffer_fetch(VALUE self, VALUE index); +static VALUE NIO_ByteBuffer_put(VALUE self, VALUE string); +static VALUE NIO_ByteBuffer_write_to(VALUE self, VALUE file); +static VALUE NIO_ByteBuffer_read_from(VALUE self, VALUE file); +static VALUE NIO_ByteBuffer_flip(VALUE self); +static VALUE NIO_ByteBuffer_rewind(VALUE self); +static VALUE NIO_ByteBuffer_mark(VALUE self); +static VALUE NIO_ByteBuffer_reset(VALUE self); +static VALUE NIO_ByteBuffer_compact(VALUE self); +static VALUE NIO_ByteBuffer_each(VALUE self); +static VALUE NIO_ByteBuffer_inspect(VALUE self); + +#define MARK_UNSET -1 + +/* Compatibility for Ruby <= 3.1 */ +#ifndef HAVE_RB_IO_DESCRIPTOR +static int +io_descriptor_fallback(VALUE io) +{ + rb_io_t *fptr; + GetOpenFile(io, fptr); + return fptr->fd; +} +#define rb_io_descriptor io_descriptor_fallback +#endif + +static void +io_set_nonblock(VALUE io) +{ + rb_io_t *fptr; + GetOpenFile(io, fptr); + rb_io_set_nonblock(fptr); +} + +void Init_NIO_ByteBuffer() +{ + mNIO = rb_define_module("NIO"); + cNIO_ByteBuffer = rb_define_class_under(mNIO, "ByteBuffer", rb_cObject); + rb_define_alloc_func(cNIO_ByteBuffer, NIO_ByteBuffer_allocate); + + cNIO_ByteBuffer_OverflowError = rb_define_class_under(cNIO_ByteBuffer, "OverflowError", rb_eIOError); + cNIO_ByteBuffer_UnderflowError = rb_define_class_under(cNIO_ByteBuffer, "UnderflowError", rb_eIOError); + cNIO_ByteBuffer_MarkUnsetError = rb_define_class_under(cNIO_ByteBuffer, "MarkUnsetError", rb_eIOError); + + rb_include_module(cNIO_ByteBuffer, rb_mEnumerable); + + rb_define_method(cNIO_ByteBuffer, "initialize", NIO_ByteBuffer_initialize, 1); + rb_define_method(cNIO_ByteBuffer, "clear", NIO_ByteBuffer_clear, 0); + rb_define_method(cNIO_ByteBuffer, "position", NIO_ByteBuffer_get_position, 0); + rb_define_method(cNIO_ByteBuffer, "position=", NIO_ByteBuffer_set_position, 1); + rb_define_method(cNIO_ByteBuffer, "limit", NIO_ByteBuffer_get_limit, 0); + rb_define_method(cNIO_ByteBuffer, "limit=", NIO_ByteBuffer_set_limit, 1); + rb_define_method(cNIO_ByteBuffer, "capacity", NIO_ByteBuffer_capacity, 0); + rb_define_method(cNIO_ByteBuffer, "size", NIO_ByteBuffer_capacity, 0); + rb_define_method(cNIO_ByteBuffer, "remaining", NIO_ByteBuffer_remaining, 0); + rb_define_method(cNIO_ByteBuffer, "full?", NIO_ByteBuffer_full, 0); + rb_define_method(cNIO_ByteBuffer, "get", NIO_ByteBuffer_get, -1); + rb_define_method(cNIO_ByteBuffer, "[]", NIO_ByteBuffer_fetch, 1); + rb_define_method(cNIO_ByteBuffer, "<<", NIO_ByteBuffer_put, 1); + rb_define_method(cNIO_ByteBuffer, "read_from", NIO_ByteBuffer_read_from, 1); + rb_define_method(cNIO_ByteBuffer, "write_to", NIO_ByteBuffer_write_to, 1); + rb_define_method(cNIO_ByteBuffer, "flip", NIO_ByteBuffer_flip, 0); + rb_define_method(cNIO_ByteBuffer, "rewind", NIO_ByteBuffer_rewind, 0); + rb_define_method(cNIO_ByteBuffer, "mark", NIO_ByteBuffer_mark, 0); + rb_define_method(cNIO_ByteBuffer, "reset", NIO_ByteBuffer_reset, 0); + rb_define_method(cNIO_ByteBuffer, "compact", NIO_ByteBuffer_compact, 0); + rb_define_method(cNIO_ByteBuffer, "each", NIO_ByteBuffer_each, 0); + rb_define_method(cNIO_ByteBuffer, "inspect", NIO_ByteBuffer_inspect, 0); +} + +static const rb_data_type_t NIO_ByteBuffer_type = { + "NIO::ByteBuffer", + { + NULL, // Nothing to mark + NIO_ByteBuffer_free, + NIO_ByteBuffer_memsize, + }, + 0, + 0, + RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED +}; + +static VALUE NIO_ByteBuffer_allocate(VALUE klass) +{ + struct NIO_ByteBuffer *bytebuffer = (struct NIO_ByteBuffer *)xmalloc(sizeof(struct NIO_ByteBuffer)); + bytebuffer->buffer = NULL; + return TypedData_Wrap_Struct(klass, &NIO_ByteBuffer_type, bytebuffer); +} + +static void NIO_ByteBuffer_free(void *data) +{ + struct NIO_ByteBuffer *buffer = (struct NIO_ByteBuffer *)data; + if (buffer->buffer) + xfree(buffer->buffer); + xfree(buffer); +} + +static size_t NIO_ByteBuffer_memsize(const void *data) +{ + const struct NIO_ByteBuffer *buffer = (const struct NIO_ByteBuffer *)data; + size_t memsize = sizeof(struct NIO_ByteBuffer); + if (buffer->buffer) + memsize += buffer->capacity; + return memsize; +} + +static VALUE NIO_ByteBuffer_initialize(VALUE self, VALUE capacity) +{ + struct NIO_ByteBuffer *buffer; + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); + + buffer->capacity = NUM2INT(capacity); + buffer->buffer = xmalloc(buffer->capacity); + + NIO_ByteBuffer_clear(self); + + return self; +} + +static VALUE NIO_ByteBuffer_clear(VALUE self) +{ + struct NIO_ByteBuffer *buffer; + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); + + memset(buffer->buffer, 0, buffer->capacity); + + buffer->position = 0; + buffer->limit = buffer->capacity; + buffer->mark = MARK_UNSET; + + return self; +} + +static VALUE NIO_ByteBuffer_get_position(VALUE self) +{ + struct NIO_ByteBuffer *buffer; + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); + + return INT2NUM(buffer->position); +} + +static VALUE NIO_ByteBuffer_set_position(VALUE self, VALUE new_position) +{ + int pos; + struct NIO_ByteBuffer *buffer; + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); + + pos = NUM2INT(new_position); + + if (pos < 0) { + rb_raise(rb_eArgError, "negative position given"); + } + + if (pos > buffer->limit) { + rb_raise(rb_eArgError, "specified position exceeds limit"); + } + + buffer->position = pos; + + if (buffer->mark > buffer->position) { + buffer->mark = MARK_UNSET; + } + + return new_position; +} + +static VALUE NIO_ByteBuffer_get_limit(VALUE self) +{ + struct NIO_ByteBuffer *buffer; + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); + + return INT2NUM(buffer->limit); +} + +static VALUE NIO_ByteBuffer_set_limit(VALUE self, VALUE new_limit) +{ + int lim; + struct NIO_ByteBuffer *buffer; + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); + + lim = NUM2INT(new_limit); + + if (lim < 0) { + rb_raise(rb_eArgError, "negative limit given"); + } + + if (lim > buffer->capacity) { + rb_raise(rb_eArgError, "specified limit exceeds capacity"); + } + + buffer->limit = lim; + + if (buffer->position > lim) { + buffer->position = lim; + } + + if (buffer->mark > lim) { + buffer->mark = MARK_UNSET; + } + + return new_limit; +} + +static VALUE NIO_ByteBuffer_capacity(VALUE self) +{ + struct NIO_ByteBuffer *buffer; + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); + + return INT2NUM(buffer->capacity); +} + +static VALUE NIO_ByteBuffer_remaining(VALUE self) +{ + struct NIO_ByteBuffer *buffer; + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); + + return INT2NUM(buffer->limit - buffer->position); +} + +static VALUE NIO_ByteBuffer_full(VALUE self) +{ + struct NIO_ByteBuffer *buffer; + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); + + return buffer->position == buffer->limit ? Qtrue : Qfalse; +} + +static VALUE NIO_ByteBuffer_get(int argc, VALUE *argv, VALUE self) +{ + int len; + VALUE length, result; + struct NIO_ByteBuffer *buffer; + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); + + rb_scan_args(argc, argv, "01", &length); + + if (length == Qnil) { + len = buffer->limit - buffer->position; + } else { + len = NUM2INT(length); + } + + if (len < 0) { + rb_raise(rb_eArgError, "negative length given"); + } + + if (len > buffer->limit - buffer->position) { + rb_raise(cNIO_ByteBuffer_UnderflowError, "not enough data in buffer"); + } + + result = rb_str_new(buffer->buffer + buffer->position, len); + buffer->position += len; + + return result; +} + +static VALUE NIO_ByteBuffer_fetch(VALUE self, VALUE index) +{ + int i; + struct NIO_ByteBuffer *buffer; + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); + + i = NUM2INT(index); + + if (i < 0) { + rb_raise(rb_eArgError, "negative index given"); + } + + if (i >= buffer->limit) { + rb_raise(rb_eArgError, "specified index exceeds limit"); + } + + return INT2NUM(buffer->buffer[i]); +} + +static VALUE NIO_ByteBuffer_put(VALUE self, VALUE string) +{ + long length; + struct NIO_ByteBuffer *buffer; + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); + + StringValue(string); + length = RSTRING_LEN(string); + + if (length > buffer->limit - buffer->position) { + rb_raise(cNIO_ByteBuffer_OverflowError, "buffer is full"); + } + + memcpy(buffer->buffer + buffer->position, StringValuePtr(string), length); + buffer->position += length; + + return self; +} + +static VALUE NIO_ByteBuffer_read_from(VALUE self, VALUE io) +{ + struct NIO_ByteBuffer *buffer; + ssize_t nbytes, bytes_read; + + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); + + io = rb_convert_type(io, T_FILE, "IO", "to_io"); + io_set_nonblock(io); + + nbytes = buffer->limit - buffer->position; + if (nbytes == 0) { + rb_raise(cNIO_ByteBuffer_OverflowError, "buffer is full"); + } + + bytes_read = read(rb_io_descriptor(io), buffer->buffer + buffer->position, nbytes); + + if (bytes_read < 0) { + if (errno == EAGAIN) { + return INT2NUM(0); + } else { + rb_sys_fail("write"); + } + } + + buffer->position += bytes_read; + + return SIZET2NUM(bytes_read); +} + +static VALUE NIO_ByteBuffer_write_to(VALUE self, VALUE io) +{ + struct NIO_ByteBuffer *buffer; + ssize_t nbytes, bytes_written; + + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); + io = rb_convert_type(io, T_FILE, "IO", "to_io"); + io_set_nonblock(io); + + nbytes = buffer->limit - buffer->position; + if (nbytes == 0) { + rb_raise(cNIO_ByteBuffer_UnderflowError, "no data remaining in buffer"); + } + + bytes_written = write(rb_io_descriptor(io), buffer->buffer + buffer->position, nbytes); + + if (bytes_written < 0) { + if (errno == EAGAIN) { + return INT2NUM(0); + } else { + rb_sys_fail("write"); + } + } + + buffer->position += bytes_written; + + return SIZET2NUM(bytes_written); +} + +static VALUE NIO_ByteBuffer_flip(VALUE self) +{ + struct NIO_ByteBuffer *buffer; + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); + + buffer->limit = buffer->position; + buffer->position = 0; + buffer->mark = MARK_UNSET; + + return self; +} + +static VALUE NIO_ByteBuffer_rewind(VALUE self) +{ + struct NIO_ByteBuffer *buffer; + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); + + buffer->position = 0; + buffer->mark = MARK_UNSET; + + return self; +} + +static VALUE NIO_ByteBuffer_mark(VALUE self) +{ + struct NIO_ByteBuffer *buffer; + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); + + buffer->mark = buffer->position; + return self; +} + +static VALUE NIO_ByteBuffer_reset(VALUE self) +{ + struct NIO_ByteBuffer *buffer; + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); + + if (buffer->mark < 0) { + rb_raise(cNIO_ByteBuffer_MarkUnsetError, "mark has not been set"); + } else { + buffer->position = buffer->mark; + } + + return self; +} + +static VALUE NIO_ByteBuffer_compact(VALUE self) +{ + struct NIO_ByteBuffer *buffer; + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); + + memmove(buffer->buffer, buffer->buffer + buffer->position, buffer->limit - buffer->position); + buffer->position = buffer->limit - buffer->position; + buffer->limit = buffer->capacity; + + return self; +} + +static VALUE NIO_ByteBuffer_each(VALUE self) +{ + int i; + struct NIO_ByteBuffer *buffer; + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); + + if (rb_block_given_p()) { + for (i = 0; i < buffer->limit; i++) { + rb_yield(INT2NUM(buffer->buffer[i])); + } + } else { + rb_raise(rb_eArgError, "no block given"); + } + + return self; +} + +static VALUE NIO_ByteBuffer_inspect(VALUE self) +{ + struct NIO_ByteBuffer *buffer; + TypedData_Get_Struct(self, struct NIO_ByteBuffer, &NIO_ByteBuffer_type, buffer); + + return rb_sprintf( + "#<%s:%p @position=%d @limit=%d @capacity=%d>", + rb_class2name(CLASS_OF(self)), + (void *)self, + buffer->position, + buffer->limit, + buffer->capacity); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/extconf.rb b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/extconf.rb new file mode 100644 index 00000000..b4ae1124 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/extconf.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +# Released under the MIT License. +# Copyright, 2011-2020, by Tony Arcieri. +# Copyright, 2014, by Hiroshi Shibata. +# Copyright, 2014, by Sergey Avseyev. +# Copyright, 2015, by Daniel Berger. +# Copyright, 2017, by Jun Aruga. +# Copyright, 2017, by Usaku Nakamura. +# Copyright, 2017, by Lars Kanis. +# Copyright, 2019-2023, by Samuel Williams. +# Copyright, 2020, by Gregory Longtin. +# Copyright, 2020, by Boaz Segev. +# Copyright, 2020, by Joao Fernandes. +# Copyright, 2021, by Jeffrey Martin. + +require "rubygems" + +# Write a dummy Makefile on Windows because we use the pure Ruby implementation there +if Gem.win_platform? + begin + require "devkit" if RUBY_PLATFORM.include?("mingw") + rescue LoadError => e + end + File.write("Makefile", "all install::\n") + File.write("nio4r_ext.so", "") + exit +end + +require "mkmf" + +have_header("unistd.h") +have_func("rb_io_descriptor") + +$defs << "-DEV_USE_LINUXAIO" if have_header("linux/aio_abi.h") +$defs << "-DEV_USE_IOURING" if have_header("linux/io_uring.h") +$defs << "-DEV_USE_SELECT" if have_header("sys/select.h") +$defs << "-DEV_USE_POLL" if have_type("port_event_t", "poll.h") +$defs << "-DEV_USE_EPOLL" if have_header("sys/epoll.h") +$defs << "-DEV_USE_KQUEUE" if have_header("sys/event.h") && have_header("sys/queue.h") +$defs << "-DEV_USE_PORT" if have_type("port_event_t", "port.h") +$defs << "-DHAVE_SYS_RESOURCE_H" if have_header("sys/resource.h") + +$defs << "-DEV_STANDALONE" # prevent libev from assuming "config.h" exists + +CONFIG["optflags"] << " -fno-strict-aliasing" unless RUBY_PLATFORM =~ /mswin/ + +if RUBY_PLATFORM =~ /darwin/ + $DLDFLAGS.gsub!(/\-arch\s+[^\s]+/, "") +end + +dir_config "nio4r_ext" +create_makefile "nio4r_ext" diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/libev.h b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/libev.h new file mode 100644 index 00000000..40763484 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/libev.h @@ -0,0 +1,7 @@ +#ifdef _WIN32 +#define EV_SELECT_IS_WINSOCKET 1 +#define EV_USE_MONOTONIC 0 +#define EV_USE_REALTIME 0 +#endif + +#include "../libev/ev.h" diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/monitor.c b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/monitor.c new file mode 100644 index 00000000..cb44d44a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/monitor.c @@ -0,0 +1,344 @@ +/* + * Copyright (c) 2011 Tony Arcieri. Distributed under the MIT License. See + * LICENSE.txt for further details. + */ + +#include "nio4r.h" +#include + +static VALUE mNIO = Qnil; +static VALUE cNIO_Monitor = Qnil; + +/* Allocator/deallocator */ +static VALUE NIO_Monitor_allocate(VALUE klass); +static void NIO_Monitor_mark(void *data); +static size_t NIO_Monitor_memsize(const void *data); + +/* Methods */ +static VALUE NIO_Monitor_initialize(VALUE self, VALUE selector, VALUE io, VALUE interests); +static VALUE NIO_Monitor_close(int argc, VALUE *argv, VALUE self); +static VALUE NIO_Monitor_is_closed(VALUE self); +static VALUE NIO_Monitor_io(VALUE self); +static VALUE NIO_Monitor_interests(VALUE self); +static VALUE NIO_Monitor_set_interests(VALUE self, VALUE interests); +static VALUE NIO_Monitor_add_interest(VALUE self, VALUE interest); +static VALUE NIO_Monitor_remove_interest(VALUE self, VALUE interest); +static VALUE NIO_Monitor_selector(VALUE self); +static VALUE NIO_Monitor_is_readable(VALUE self); +static VALUE NIO_Monitor_is_writable(VALUE self); +static VALUE NIO_Monitor_value(VALUE self); +static VALUE NIO_Monitor_set_value(VALUE self, VALUE obj); +static VALUE NIO_Monitor_readiness(VALUE self); + +/* Internal C functions */ +static int NIO_Monitor_symbol2interest(VALUE interests); +static void NIO_Monitor_update_interests(VALUE self, int interests); + +/* Compatibility for Ruby <= 3.1 */ +#ifndef HAVE_RB_IO_DESCRIPTOR +static int +io_descriptor_fallback(VALUE io) +{ + rb_io_t *fptr; + GetOpenFile(io, fptr); + return fptr->fd; +} +#define rb_io_descriptor io_descriptor_fallback +#endif + +/* Monitor control how a channel is being waited for by a monitor */ +void Init_NIO_Monitor() +{ + mNIO = rb_define_module("NIO"); + cNIO_Monitor = rb_define_class_under(mNIO, "Monitor", rb_cObject); + rb_define_alloc_func(cNIO_Monitor, NIO_Monitor_allocate); + + rb_define_method(cNIO_Monitor, "initialize", NIO_Monitor_initialize, 3); + rb_define_method(cNIO_Monitor, "close", NIO_Monitor_close, -1); + rb_define_method(cNIO_Monitor, "closed?", NIO_Monitor_is_closed, 0); + rb_define_method(cNIO_Monitor, "io", NIO_Monitor_io, 0); + rb_define_method(cNIO_Monitor, "interests", NIO_Monitor_interests, 0); + rb_define_method(cNIO_Monitor, "interests=", NIO_Monitor_set_interests, 1); + rb_define_method(cNIO_Monitor, "add_interest", NIO_Monitor_add_interest, 1); + rb_define_method(cNIO_Monitor, "remove_interest", NIO_Monitor_remove_interest, 1); + rb_define_method(cNIO_Monitor, "selector", NIO_Monitor_selector, 0); + rb_define_method(cNIO_Monitor, "value", NIO_Monitor_value, 0); + rb_define_method(cNIO_Monitor, "value=", NIO_Monitor_set_value, 1); + rb_define_method(cNIO_Monitor, "readiness", NIO_Monitor_readiness, 0); + rb_define_method(cNIO_Monitor, "readable?", NIO_Monitor_is_readable, 0); + rb_define_method(cNIO_Monitor, "writable?", NIO_Monitor_is_writable, 0); + rb_define_method(cNIO_Monitor, "writeable?", NIO_Monitor_is_writable, 0); +} + +static const rb_data_type_t NIO_Monitor_type = { + "NIO::Monitor", + { + NIO_Monitor_mark, + RUBY_TYPED_DEFAULT_FREE, + NIO_Monitor_memsize, + }, + 0, + 0, + RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED +}; + +static VALUE NIO_Monitor_allocate(VALUE klass) +{ + struct NIO_Monitor *monitor = (struct NIO_Monitor *)xmalloc(sizeof(struct NIO_Monitor)); + assert(monitor); + *monitor = (struct NIO_Monitor){.self = Qnil}; + return TypedData_Wrap_Struct(klass, &NIO_Monitor_type, monitor); +} + +static void NIO_Monitor_mark(void *data) +{ + struct NIO_Monitor *monitor = (struct NIO_Monitor *)data; + rb_gc_mark(monitor->self); +} + +static size_t NIO_Monitor_memsize(const void *data) +{ + const struct NIO_Monitor *monitor = (const struct NIO_Monitor *)data; + return sizeof(*monitor); +} + +static VALUE NIO_Monitor_initialize(VALUE self, VALUE io, VALUE interests, VALUE selector_obj) +{ + struct NIO_Monitor *monitor; + struct NIO_Selector *selector; + ID interests_id; + + interests_id = SYM2ID(interests); + + TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor); + + if (interests_id == rb_intern("r")) { + monitor->interests = EV_READ; + } else if (interests_id == rb_intern("w")) { + monitor->interests = EV_WRITE; + } else if (interests_id == rb_intern("rw")) { + monitor->interests = EV_READ | EV_WRITE; + } else { + rb_raise(rb_eArgError, "invalid event type %s (must be :r, :w, or :rw)", RSTRING_PTR(rb_funcall(interests, rb_intern("inspect"), 0))); + } + + int descriptor = rb_io_descriptor(rb_convert_type(io, T_FILE, "IO", "to_io")); + ev_io_init(&monitor->ev_io, NIO_Selector_monitor_callback, descriptor, monitor->interests); + + rb_ivar_set(self, rb_intern("io"), io); + rb_ivar_set(self, rb_intern("interests"), interests); + rb_ivar_set(self, rb_intern("selector"), selector_obj); + + selector = NIO_Selector_unwrap(selector_obj); + + RB_OBJ_WRITE(self, &monitor->self, self); + monitor->ev_io.data = (void *)monitor; + + /* We can safely hang onto this as we also hang onto a reference to the + object where it originally came from */ + monitor->selector = selector; + + if (monitor->interests) { + ev_io_start(selector->ev_loop, &monitor->ev_io); + } + + return Qnil; +} + +static VALUE NIO_Monitor_close(int argc, VALUE *argv, VALUE self) +{ + VALUE deregister, selector; + struct NIO_Monitor *monitor; + TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor); + + rb_scan_args(argc, argv, "01", &deregister); + selector = rb_ivar_get(self, rb_intern("selector")); + + if (selector != Qnil) { + /* if ev_loop is 0, it means that the loop has been stopped already (see NIO_Selector_shutdown) */ + if (monitor->interests && monitor->selector->ev_loop) { + ev_io_stop(monitor->selector->ev_loop, &monitor->ev_io); + } + + monitor->selector = 0; + rb_ivar_set(self, rb_intern("selector"), Qnil); + + /* Default value is true */ + if (deregister == Qtrue || deregister == Qnil) { + rb_funcall(selector, rb_intern("deregister"), 1, rb_ivar_get(self, rb_intern("io"))); + } + } + + return Qnil; +} + +static VALUE NIO_Monitor_is_closed(VALUE self) +{ + struct NIO_Monitor *monitor; + TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor); + + return monitor->selector == 0 ? Qtrue : Qfalse; +} + +static VALUE NIO_Monitor_io(VALUE self) +{ + return rb_ivar_get(self, rb_intern("io")); +} + +static VALUE NIO_Monitor_interests(VALUE self) +{ + return rb_ivar_get(self, rb_intern("interests")); +} + +static VALUE NIO_Monitor_set_interests(VALUE self, VALUE interests) +{ + if (NIL_P(interests)) { + NIO_Monitor_update_interests(self, 0); + } else { + NIO_Monitor_update_interests(self, NIO_Monitor_symbol2interest(interests)); + } + + return rb_ivar_get(self, rb_intern("interests")); +} + +static VALUE NIO_Monitor_add_interest(VALUE self, VALUE interest) +{ + struct NIO_Monitor *monitor; + TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor); + + interest = monitor->interests | NIO_Monitor_symbol2interest(interest); + NIO_Monitor_update_interests(self, (int)interest); + + return rb_ivar_get(self, rb_intern("interests")); +} + +static VALUE NIO_Monitor_remove_interest(VALUE self, VALUE interest) +{ + struct NIO_Monitor *monitor; + TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor); + + interest = monitor->interests & ~NIO_Monitor_symbol2interest(interest); + NIO_Monitor_update_interests(self, (int)interest); + + return rb_ivar_get(self, rb_intern("interests")); +} + +static VALUE NIO_Monitor_selector(VALUE self) +{ + return rb_ivar_get(self, rb_intern("selector")); +} + +static VALUE NIO_Monitor_value(VALUE self) +{ + return rb_ivar_get(self, rb_intern("value")); +} + +static VALUE NIO_Monitor_set_value(VALUE self, VALUE obj) +{ + return rb_ivar_set(self, rb_intern("value"), obj); +} + +static VALUE NIO_Monitor_readiness(VALUE self) +{ + struct NIO_Monitor *monitor; + TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor); + + if ((monitor->revents & (EV_READ | EV_WRITE)) == (EV_READ | EV_WRITE)) { + return ID2SYM(rb_intern("rw")); + } else if (monitor->revents & EV_READ) { + return ID2SYM(rb_intern("r")); + } else if (monitor->revents & EV_WRITE) { + return ID2SYM(rb_intern("w")); + } else { + return Qnil; + } +} + +static VALUE NIO_Monitor_is_readable(VALUE self) +{ + struct NIO_Monitor *monitor; + TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor); + + if (monitor->revents & EV_READ) { + return Qtrue; + } else { + return Qfalse; + } +} + +static VALUE NIO_Monitor_is_writable(VALUE self) +{ + struct NIO_Monitor *monitor; + TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor); + + if (monitor->revents & EV_WRITE) { + return Qtrue; + } else { + return Qfalse; + } +} + +/* Internal C functions */ + +static int NIO_Monitor_symbol2interest(VALUE interests) +{ + ID interests_id; + interests_id = SYM2ID(interests); + + if (interests_id == rb_intern("r")) { + return EV_READ; + } else if (interests_id == rb_intern("w")) { + return EV_WRITE; + } else if (interests_id == rb_intern("rw")) { + return EV_READ | EV_WRITE; + } else { + rb_raise(rb_eArgError, "invalid interest type %s (must be :r, :w, or :rw)", RSTRING_PTR(rb_funcall(interests, rb_intern("inspect"), 0))); + } +} + +static void NIO_Monitor_update_interests(VALUE self, int interests) +{ + ID interests_id; + struct NIO_Monitor *monitor; + TypedData_Get_Struct(self, struct NIO_Monitor, &NIO_Monitor_type, monitor); + + if (NIO_Monitor_is_closed(self) == Qtrue) { + rb_raise(rb_eEOFError, "monitor is closed"); + } + + if (interests) { + switch (interests) { + case EV_READ: + interests_id = rb_intern("r"); + break; + case EV_WRITE: + interests_id = rb_intern("w"); + break; + case EV_READ | EV_WRITE: + interests_id = rb_intern("rw"); + break; + default: + rb_raise(rb_eRuntimeError, "bogus NIO_Monitor_update_interests! (%d)", interests); + } + + rb_ivar_set(self, rb_intern("interests"), ID2SYM(interests_id)); + } else { + rb_ivar_set(self, rb_intern("interests"), Qnil); + } + + if (monitor->interests != interests) { + // If the monitor currently has interests, we should stop it. + if (monitor->interests) { + ev_io_stop(monitor->selector->ev_loop, &monitor->ev_io); + } + + // Assign the interests we are now monitoring for: + monitor->interests = interests; + ev_io_set(&monitor->ev_io, monitor->ev_io.fd, monitor->interests); + + // If we are interested in events, schedule the monitor back into the event loop: + if (monitor->interests) { + ev_io_start(monitor->selector->ev_loop, &monitor->ev_io); + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/nio4r.h b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/nio4r.h new file mode 100644 index 00000000..dc65e914 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/nio4r.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011 Tony Arcieri. Distributed under the MIT License. See + * LICENSE.txt for further details. + */ + +#ifndef NIO4R_H +#define NIO4R_H + +#include "libev.h" +#include "ruby.h" +#include "ruby/io.h" + +struct NIO_Selector { + struct ev_loop *ev_loop; + struct ev_timer timer; /* for timeouts */ + struct ev_io wakeup; + + int ready_count; + int closed, selecting; + int wakeup_reader, wakeup_writer; + volatile int wakeup_fired; + + VALUE ready_array; +}; + +struct NIO_callback_data { + VALUE *monitor; + struct NIO_Selector *selector; +}; + +struct NIO_Monitor { + VALUE self; + int interests, revents; + struct ev_io ev_io; + struct NIO_Selector *selector; +}; + +struct NIO_ByteBuffer { + char *buffer; + int position, limit, capacity, mark; +}; + +struct NIO_Selector *NIO_Selector_unwrap(VALUE selector); + +/* Thunk between libev callbacks in NIO::Monitors and NIO::Selectors */ +void NIO_Selector_monitor_callback(struct ev_loop *ev_loop, struct ev_io *io, int revents); + +#endif /* NIO4R_H */ diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/nio4r_ext.c b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/nio4r_ext.c new file mode 100644 index 00000000..d2c2cb7b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/nio4r_ext.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2011-2017 Tony Arcieri. Distributed under the MIT License. + * See LICENSE.txt for further details. + */ + +#include "../libev/ev.c" +#include "nio4r.h" + +void Init_NIO_Selector(); +void Init_NIO_Monitor(); +void Init_NIO_ByteBuffer(); + +void Init_nio4r_ext() +{ + #ifdef HAVE_RB_EXT_RACTOR_SAFE + rb_ext_ractor_safe(true); + #endif + + ev_set_allocator(xrealloc); + + Init_NIO_Selector(); + Init_NIO_Monitor(); + Init_NIO_ByteBuffer(); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/org/nio4r/ByteBuffer.java b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/org/nio4r/ByteBuffer.java new file mode 100644 index 00000000..8764b7cd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/org/nio4r/ByteBuffer.java @@ -0,0 +1,295 @@ +package org.nio4r; + +import java.io.IOException; +import java.io.Serializable; +import java.nio.channels.Channel; +import java.nio.channels.SelectableChannel; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; +import java.nio.BufferOverflowException; +import java.nio.BufferUnderflowException; +import java.nio.InvalidMarkException; + +import org.jruby.Ruby; +import org.jruby.RubyClass; +import org.jruby.RubyIO; +import org.jruby.RubyNumeric; +import org.jruby.RubyObject; +import org.jruby.RubyString; +import org.jruby.anno.JRubyMethod; +import org.jruby.exceptions.RaiseException; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.builtin.IRubyObject; +import org.jruby.runtime.Block; + +/* +created by Upekshej + */ +public class ByteBuffer extends RubyObject { + private static final long serialVersionUID = -6903439483039149324L; + private transient java.nio.ByteBuffer byteBuffer; + + public static RaiseException newOverflowError(ThreadContext context, String message) { + RubyClass klass = context.runtime.getModule("NIO").getClass("ByteBuffer").getClass("OverflowError"); + return context.runtime.newRaiseException(klass, message); + } + + public static RaiseException newUnderflowError(ThreadContext context, String message) { + RubyClass klass = context.runtime.getModule("NIO").getClass("ByteBuffer").getClass("UnderflowError"); + return context.runtime.newRaiseException(klass, message); + } + + public static RaiseException newMarkUnsetError(ThreadContext context, String message) { + RubyClass klass = context.runtime.getModule("NIO").getClass("ByteBuffer").getClass("MarkUnsetError"); + return context.runtime.newRaiseException(klass, message); + } + + public ByteBuffer(final Ruby ruby, RubyClass rubyClass) { + super(ruby, rubyClass); + } + + @JRubyMethod + public IRubyObject initialize(ThreadContext context, IRubyObject capacity) { + this.byteBuffer = java.nio.ByteBuffer.allocate(RubyNumeric.num2int(capacity)); + return this; + } + + @JRubyMethod + public IRubyObject clear(ThreadContext context) { + this.byteBuffer.clear(); + return this; + } + + @JRubyMethod(name = "position") + public IRubyObject getPosition(ThreadContext context) { + return context.getRuntime().newFixnum(this.byteBuffer.position()); + } + + @JRubyMethod(name = "position=") + public IRubyObject setPosition(ThreadContext context, IRubyObject newPosition) { + int pos = RubyNumeric.num2int(newPosition); + + if(pos < 0) { + throw context.runtime.newArgumentError("negative position given"); + } + + if(pos > this.byteBuffer.limit()) { + throw context.runtime.newArgumentError("specified position exceeds limit"); + } + + try { + this.byteBuffer.position(pos); + return newPosition; + } catch(IllegalArgumentException e) { + throw context.runtime.newArgumentError(e.getLocalizedMessage()); + } + } + + @JRubyMethod(name = "limit") + public IRubyObject getLimit(ThreadContext context) { + return context.getRuntime().newFixnum(this.byteBuffer.limit()); + } + + @JRubyMethod(name = "limit=") + public IRubyObject setLimit(ThreadContext context, IRubyObject newLimit) { + int lim = RubyNumeric.num2int(newLimit); + + if(lim < 0) { + throw context.runtime.newArgumentError("negative limit given"); + } + + if(lim > this.byteBuffer.capacity()) { + throw context.runtime.newArgumentError("specified limit exceeds capacity"); + } + + try { + this.byteBuffer.limit(lim); + return newLimit; + } catch(IllegalArgumentException e) { + throw context.runtime.newArgumentError(e.getLocalizedMessage()); + } + } + + @JRubyMethod(name = {"capacity", "size"}) + public IRubyObject capacity(ThreadContext context) { + return context.getRuntime().newFixnum(this.byteBuffer.capacity()); + } + + @JRubyMethod + public IRubyObject remaining(ThreadContext context) { + return context.getRuntime().newFixnum(this.byteBuffer.remaining()); + } + + @JRubyMethod(name = "full?") + public IRubyObject isFull(ThreadContext context) { + if (this.byteBuffer.hasRemaining()) { + return context.getRuntime().getFalse(); + } else { + return context.getRuntime().getTrue(); + } + } + + @JRubyMethod + public IRubyObject get(ThreadContext context) { + return this.get(context, context.getRuntime().newFixnum(this.byteBuffer.remaining())); + } + + @JRubyMethod + public IRubyObject get(ThreadContext context, IRubyObject length) { + int len = RubyNumeric.num2int(length); + byte[] bytes = new byte[len]; + + try { + this.byteBuffer.get(bytes); + } catch(BufferUnderflowException e) { + throw ByteBuffer.newUnderflowError(context, "not enough data in buffer"); + } + + return RubyString.newString(context.getRuntime(), bytes); + } + + @JRubyMethod(name = "[]") + public IRubyObject fetch(ThreadContext context, IRubyObject index) { + int i = RubyNumeric.num2int(index); + + if(i < 0) { + throw context.runtime.newArgumentError("negative index given"); + } + + if(i >= this.byteBuffer.limit()) { + throw context.runtime.newArgumentError("index exceeds limit"); + } + + return context.getRuntime().newFixnum(this.byteBuffer.get(i)); + } + + @JRubyMethod(name = "<<") + public IRubyObject put(ThreadContext context, IRubyObject str) { + try { + this.byteBuffer.put(str.convertToString().getByteList().bytes()); + } catch(BufferOverflowException e) { + throw ByteBuffer.newOverflowError(context, "buffer is full"); + } + + return this; + } + + @JRubyMethod(name = "read_from") + public IRubyObject readFrom(ThreadContext context, IRubyObject io) { + Ruby runtime = context.runtime; + Channel channel = RubyIO.convertToIO(context, io).getChannel(); + + if(!this.byteBuffer.hasRemaining()) { + throw ByteBuffer.newOverflowError(context, "buffer is full"); + } + + if(!(channel instanceof ReadableByteChannel) || !(channel instanceof SelectableChannel)) { + throw runtime.newArgumentError("unsupported IO object: " + io.getType().toString()); + } + + try { + ((SelectableChannel)channel).configureBlocking(false); + } catch(IOException ie) { + throw runtime.newIOError(ie.getLocalizedMessage()); + } + + try { + int bytesRead = ((ReadableByteChannel)channel).read(this.byteBuffer); + + if(bytesRead >= 0) { + return runtime.newFixnum(bytesRead); + } else { + throw runtime.newEOFError(); + } + } catch(IOException ie) { + throw runtime.newIOError(ie.getLocalizedMessage()); + } + } + + @JRubyMethod(name = "write_to") + public IRubyObject writeTo(ThreadContext context, IRubyObject io) { + Ruby runtime = context.runtime; + Channel channel = RubyIO.convertToIO(context, io).getChannel(); + + if(!this.byteBuffer.hasRemaining()) { + throw ByteBuffer.newUnderflowError(context, "not enough data in buffer"); + } + + if(!(channel instanceof WritableByteChannel) || !(channel instanceof SelectableChannel)) { + throw runtime.newArgumentError("unsupported IO object: " + io.getType().toString()); + } + + try { + ((SelectableChannel)channel).configureBlocking(false); + } catch(IOException ie) { + throw runtime.newIOError(ie.getLocalizedMessage()); + } + + try { + int bytesWritten = ((WritableByteChannel)channel).write(this.byteBuffer); + + if(bytesWritten >= 0) { + return runtime.newFixnum(bytesWritten); + } else { + throw runtime.newEOFError(); + } + } catch(IOException ie) { + throw runtime.newIOError(ie.getLocalizedMessage()); + } + } + + @JRubyMethod + public IRubyObject flip(ThreadContext context) { + this.byteBuffer.flip(); + return this; + } + + @JRubyMethod + public IRubyObject rewind(ThreadContext context) { + this.byteBuffer.rewind(); + return this; + } + + @JRubyMethod + public IRubyObject mark(ThreadContext context) { + this.byteBuffer.mark(); + return this; + } + + @JRubyMethod + public IRubyObject reset(ThreadContext context) { + try { + this.byteBuffer.reset(); + return this; + } catch(InvalidMarkException ie) { + throw ByteBuffer.newMarkUnsetError(context, "mark has not been set"); + } + } + + @JRubyMethod + public IRubyObject compact(ThreadContext context) { + this.byteBuffer.compact(); + return this; + } + + @JRubyMethod + public IRubyObject each(ThreadContext context, Block block) { + for(int i = 0; i < this.byteBuffer.limit(); i++) { + block.call(context, context.getRuntime().newFixnum(this.byteBuffer.get(i))); + } + + return this; + } + + @JRubyMethod + public IRubyObject inspect(ThreadContext context) { + return context.runtime.newString(String.format( + "#<%s:0x%x @position=%d @limit=%d @capacity=%d>", + this.getType().toString(), + System.identityHashCode(this), + this.byteBuffer.position(), + this.byteBuffer.limit(), + this.byteBuffer.capacity() + )); + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/org/nio4r/Monitor.java b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/org/nio4r/Monitor.java new file mode 100644 index 00000000..bfe5d1c8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/org/nio4r/Monitor.java @@ -0,0 +1,176 @@ +package org.nio4r; + +import java.nio.channels.Channel; +import java.nio.channels.SelectableChannel; +import java.nio.channels.SelectionKey; + +import org.jruby.Ruby; +import org.jruby.RubyClass; +import org.jruby.RubyIO; +import org.jruby.RubyObject; +import org.jruby.anno.JRubyMethod; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.builtin.IRubyObject; + +public class Monitor extends RubyObject { + private static final long serialVersionUID = -3733782997115074794L; + private transient SelectionKey key; + private RubyIO io; + private transient IRubyObject interests, selector, value, closed; + + public Monitor(final Ruby ruby, RubyClass rubyClass) { + super(ruby, rubyClass); + } + + @JRubyMethod + public IRubyObject initialize(ThreadContext context, IRubyObject selectable, IRubyObject interests, IRubyObject selector) { + this.io = RubyIO.convertToIO(context, selectable); + this.interests = interests; + this.selector = selector; + + this.value = context.nil; + this.closed = context.getRuntime().getFalse(); + + return context.nil; + } + + public void setSelectionKey(SelectionKey key) { + this.key = key; + key.attach(this); + } + + @JRubyMethod + public IRubyObject io(ThreadContext context) { + return io; + } + + @JRubyMethod + public IRubyObject selector(ThreadContext context) { + return selector; + } + + @JRubyMethod(name = "interests") + public IRubyObject getInterests(ThreadContext context) { + return interests; + } + + @JRubyMethod(name = "interests=") + public IRubyObject setInterests(ThreadContext context, IRubyObject interests) { + if(this.closed == context.getRuntime().getTrue()) { + throw context.getRuntime().newEOFError("monitor is closed"); + } + + Ruby ruby = context.getRuntime(); + SelectableChannel channel = (SelectableChannel)io.getChannel(); + + if(interests != context.nil) { + key.interestOps(Nio4r.symbolToInterestOps(ruby, channel, interests)); + } else { + key.interestOps(0); + } + + this.interests = interests; + + return this.interests; + } + + @JRubyMethod(name = "add_interest") + public IRubyObject addInterest(ThreadContext context, IRubyObject interest) { + if(this.closed == context.getRuntime().getTrue()) { + throw context.getRuntime().newEOFError("monitor is closed"); + } + + Ruby ruby = context.getRuntime(); + SelectableChannel channel = (SelectableChannel)io.getChannel(); + int newInterestOps = key.interestOps() | Nio4r.symbolToInterestOps(ruby, channel, interest); + + key.interestOps(newInterestOps); + this.interests = Nio4r.interestOpsToSymbol(ruby, newInterestOps); + + return this.interests; + } + + @JRubyMethod(name = "remove_interest") + public IRubyObject removeInterest(ThreadContext context, IRubyObject interest) { + if(this.closed == context.getRuntime().getTrue()) { + throw context.getRuntime().newEOFError("monitor is closed"); + } + + Ruby ruby = context.getRuntime(); + SelectableChannel channel = (SelectableChannel)io.getChannel(); + int newInterestOps = key.interestOps() & ~Nio4r.symbolToInterestOps(ruby, channel, interest); + + key.interestOps(newInterestOps); + this.interests = Nio4r.interestOpsToSymbol(ruby, newInterestOps); + + return this.interests; + } + + @JRubyMethod + public IRubyObject readiness(ThreadContext context) { + if(!key.isValid()) + return this.interests; + return Nio4r.interestOpsToSymbol(context.getRuntime(), key.readyOps()); + } + + @JRubyMethod(name = "readable?") + public IRubyObject isReadable(ThreadContext context) { + Ruby runtime = context.getRuntime(); + if (!this.key.isValid()) + return runtime.getTrue(); + int readyOps = this.key.readyOps(); + + if((readyOps & SelectionKey.OP_READ) != 0 || (readyOps & SelectionKey.OP_ACCEPT) != 0) { + return runtime.getTrue(); + } else { + return runtime.getFalse(); + } + } + + @JRubyMethod(name = {"writable?", "writeable?"}) + public IRubyObject writable(ThreadContext context) { + Ruby runtime = context.getRuntime(); + if (!this.key.isValid()) + return runtime.getTrue(); + int readyOps = this.key.readyOps(); + + if((readyOps & SelectionKey.OP_WRITE) != 0 || (readyOps & SelectionKey.OP_CONNECT) != 0) { + return runtime.getTrue(); + } else { + return runtime.getFalse(); + } + } + + @JRubyMethod(name = "value") + public IRubyObject getValue(ThreadContext context) { + return this.value; + } + + @JRubyMethod(name = "value=") + public IRubyObject setValue(ThreadContext context, IRubyObject obj) { + this.value = obj; + return context.nil; + } + + @JRubyMethod + public IRubyObject close(ThreadContext context) { + return close(context, context.getRuntime().getTrue()); + } + + @JRubyMethod + public IRubyObject close(ThreadContext context, IRubyObject deregister) { + Ruby runtime = context.getRuntime(); + this.closed = runtime.getTrue(); + + if(deregister == runtime.getTrue()) { + selector.callMethod(context, "deregister", io); + } + + return context.nil; + } + + @JRubyMethod(name = "closed?") + public IRubyObject isClosed(ThreadContext context) { + return this.closed; + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/org/nio4r/Nio4r.java b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/org/nio4r/Nio4r.java new file mode 100644 index 00000000..ccb066a0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/org/nio4r/Nio4r.java @@ -0,0 +1,104 @@ +package org.nio4r; + +import java.nio.channels.SelectableChannel; +import java.nio.channels.SelectionKey; +import java.nio.channels.SocketChannel; + +import org.jruby.Ruby; +import org.jruby.RubyClass; +import org.jruby.RubyModule; +import org.jruby.runtime.ObjectAllocator; +import org.jruby.runtime.load.Library; +import org.jruby.runtime.builtin.IRubyObject; + +import org.nio4r.ByteBuffer; +import org.nio4r.Monitor; +import org.nio4r.Selector; + +public class Nio4r implements Library { + private Ruby ruby; + + public void load(final Ruby ruby, boolean bln) { + this.ruby = ruby; + + RubyModule nio = ruby.defineModule("NIO"); + + RubyClass selector = ruby.defineClassUnder("Selector", ruby.getObject(), new ObjectAllocator() { + public IRubyObject allocate(Ruby ruby, RubyClass rc) { + return new Selector(ruby, rc); + } + }, nio); + + selector.defineAnnotatedMethods(Selector.class); + + RubyClass monitor = ruby.defineClassUnder("Monitor", ruby.getObject(), new ObjectAllocator() { + public IRubyObject allocate(Ruby ruby, RubyClass rc) { + return new Monitor(ruby, rc); + } + }, nio); + + monitor.defineAnnotatedMethods(Monitor.class); + + RubyClass byteBuffer = ruby.defineClassUnder("ByteBuffer", ruby.getObject(), new ObjectAllocator() { + public IRubyObject allocate(Ruby ruby, RubyClass rc) { + return new ByteBuffer(ruby, rc); + } + }, nio); + + byteBuffer.defineAnnotatedMethods(ByteBuffer.class); + byteBuffer.includeModule(ruby.getEnumerable()); + + ruby.defineClassUnder("OverflowError", ruby.getIOError(), ruby.getIOError().getAllocator(), byteBuffer); + ruby.defineClassUnder("UnderflowError", ruby.getIOError(), ruby.getIOError().getAllocator(), byteBuffer); + ruby.defineClassUnder("MarkUnsetError", ruby.getIOError(), ruby.getIOError().getAllocator(), byteBuffer); + } + + public static int symbolToInterestOps(Ruby ruby, SelectableChannel channel, IRubyObject interest) { + if(interest == ruby.newSymbol("r")) { + if((channel.validOps() & SelectionKey.OP_ACCEPT) != 0) { + return SelectionKey.OP_ACCEPT; + } else { + return SelectionKey.OP_READ; + } + } else if(interest == ruby.newSymbol("w")) { + if(channel instanceof SocketChannel && !((SocketChannel)channel).isConnected()) { + return SelectionKey.OP_CONNECT; + } else { + return SelectionKey.OP_WRITE; + } + } else if(interest == ruby.newSymbol("rw")) { + int interestOps = 0; + + /* nio4r emulates the POSIX behavior, which is sloppy about allowed modes */ + if((channel.validOps() & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0) { + interestOps |= symbolToInterestOps(ruby, channel, ruby.newSymbol("r")); + } + + if((channel.validOps() & (SelectionKey.OP_WRITE | SelectionKey.OP_CONNECT)) != 0) { + interestOps |= symbolToInterestOps(ruby, channel, ruby.newSymbol("w")); + } + + return interestOps; + } else { + throw ruby.newArgumentError("invalid interest type: " + interest); + } + } + + public static IRubyObject interestOpsToSymbol(Ruby ruby, int interestOps) { + switch(interestOps) { + case SelectionKey.OP_READ: + case SelectionKey.OP_ACCEPT: + return ruby.newSymbol("r"); + case SelectionKey.OP_WRITE: + case SelectionKey.OP_CONNECT: + return ruby.newSymbol("w"); + case SelectionKey.OP_READ | SelectionKey.OP_CONNECT: + case SelectionKey.OP_READ | SelectionKey.OP_WRITE: + return ruby.newSymbol("rw"); + case 0: + return ruby.getNil(); + default: + throw ruby.newArgumentError("unknown interest op combination"); + } + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/org/nio4r/Selector.java b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/org/nio4r/Selector.java new file mode 100644 index 00000000..99c0f280 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/org/nio4r/Selector.java @@ -0,0 +1,297 @@ +package org.nio4r; + +import java.util.Iterator; +import java.util.Map; +import java.util.HashMap; +import java.io.IOException; +import java.nio.channels.Channel; +import java.nio.channels.SelectableChannel; +import java.nio.channels.SelectionKey; + +import org.jruby.Ruby; +import org.jruby.RubyArray; +import org.jruby.RubyClass; +import org.jruby.RubyIO; +import org.jruby.RubyNumeric; +import org.jruby.RubyObject; +import org.jruby.anno.JRubyMethod; +import org.jruby.runtime.Block; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.builtin.IRubyObject; +import org.jruby.util.io.OpenFile; + +public class Selector extends RubyObject { + private static final long serialVersionUID = -14562818539414873L; + private transient java.nio.channels.Selector selector; + private HashMap cancelledKeys; + private volatile boolean wakeupFired; + + public Selector(final Ruby ruby, RubyClass rubyClass) { + super(ruby, rubyClass); + } + + @JRubyMethod(meta = true) + public static IRubyObject backends(ThreadContext context, IRubyObject self) { + return context.runtime.newArray(context.runtime.newSymbol("java")); + } + + @JRubyMethod + public IRubyObject initialize(ThreadContext context) { + initialize(context, context.runtime.newSymbol("java")); + return context.nil; + } + + @JRubyMethod + public IRubyObject initialize(ThreadContext context, IRubyObject backend) { + if(backend != context.runtime.newSymbol("java") && !backend.isNil()) { + throw context.runtime.newArgumentError(":java is the only supported backend"); + } + + this.cancelledKeys = new HashMap(); + this.wakeupFired = false; + + try { + this.selector = java.nio.channels.Selector.open(); + } catch(IOException ie) { + throw context.runtime.newIOError(ie.getLocalizedMessage()); + } + + return context.nil; + } + + @JRubyMethod + public IRubyObject backend(ThreadContext context) { + return context.runtime.newSymbol("java"); + } + + @JRubyMethod + public IRubyObject close(ThreadContext context) { + try { + this.selector.close(); + } catch(IOException ie) { + throw context.runtime.newIOError(ie.getLocalizedMessage()); + } + + return context.nil; + } + + @JRubyMethod(name = "closed?") + public IRubyObject isClosed(ThreadContext context) { + Ruby runtime = context.getRuntime(); + return this.selector.isOpen() ? runtime.getFalse() : runtime.getTrue(); + } + + @JRubyMethod(name = "empty?") + public IRubyObject isEmpty(ThreadContext context) { + Ruby runtime = context.getRuntime(); + return this.selector.keys().isEmpty() ? runtime.getTrue() : runtime.getFalse(); + } + + @JRubyMethod + public IRubyObject register(ThreadContext context, IRubyObject io, IRubyObject interests) { + Ruby runtime = context.getRuntime(); + Channel rawChannel = RubyIO.convertToIO(context, io).getChannel(); + + if(!this.selector.isOpen()) { + throw context.getRuntime().newIOError("selector is closed"); + } + + if(!(rawChannel instanceof SelectableChannel)) { + throw runtime.newArgumentError("not a selectable IO object"); + } + + SelectableChannel channel = (SelectableChannel)rawChannel; + + try { + channel.configureBlocking(false); + } catch(IOException ie) { + throw runtime.newIOError(ie.getLocalizedMessage()); + } + + int interestOps = Nio4r.symbolToInterestOps(runtime, channel, interests); + SelectionKey key; + + key = this.cancelledKeys.remove(channel); + + if(key != null) { + key.interestOps(interestOps); + } else { + try { + key = channel.register(this.selector, interestOps); + } catch(java.lang.IllegalArgumentException ia) { + throw runtime.newArgumentError("mode not supported for this object: " + interests); + } catch(java.nio.channels.ClosedChannelException cce) { + throw context.runtime.newIOError(cce.getLocalizedMessage()); + } + } + + RubyClass monitorClass = runtime.getModule("NIO").getClass("Monitor"); + Monitor monitor = (Monitor)monitorClass.newInstance(context, io, interests, this, null); + monitor.setSelectionKey(key); + + return monitor; + } + + @JRubyMethod + public IRubyObject deregister(ThreadContext context, IRubyObject io) { + Ruby runtime = context.getRuntime(); + OpenFile file = RubyIO.convertToIO(context, io).getOpenFileInitialized(); + if (file.fd() == null) + return context.nil; + Channel rawChannel = file.channel(); + + if(!(rawChannel instanceof SelectableChannel)) { + throw runtime.newArgumentError("not a selectable IO object"); + } + + SelectableChannel channel = (SelectableChannel)rawChannel; + SelectionKey key = channel.keyFor(this.selector); + + if(key == null) + return context.nil; + + Monitor monitor = (Monitor)key.attachment(); + monitor.close(context, runtime.getFalse()); + cancelledKeys.put(channel, key); + + return monitor; + } + + @JRubyMethod(name = "registered?") + public IRubyObject isRegistered(ThreadContext context, IRubyObject io) { + Ruby runtime = context.getRuntime(); + Channel rawChannel = RubyIO.convertToIO(context, io).getChannel(); + + if(!(rawChannel instanceof SelectableChannel)) { + throw runtime.newArgumentError("not a selectable IO object"); + } + + SelectableChannel channel = (SelectableChannel)rawChannel; + SelectionKey key = channel.keyFor(this.selector); + + if(key == null) + return context.nil; + + + if(((Monitor)key.attachment()).isClosed(context) == runtime.getTrue()) { + return runtime.getFalse(); + } else { + return runtime.getTrue(); + } + } + + @JRubyMethod + public synchronized IRubyObject select(ThreadContext context, Block block) { + return select(context, context.nil, block); + } + + @JRubyMethod + public synchronized IRubyObject select(ThreadContext context, IRubyObject timeout, Block block) { + Ruby runtime = context.getRuntime(); + + if(!this.selector.isOpen()) { + throw context.getRuntime().newIOError("selector is closed"); + } + + this.wakeupFired = false; + int ready = doSelect(runtime, context, timeout); + + /* Timeout */ + if(ready <= 0 && !this.wakeupFired) { + return context.nil; + } + + RubyArray array = null; + + if(!block.isGiven()) { + array = runtime.newArray(this.selector.selectedKeys().size()); + } + + Iterator selectedKeys = this.selector.selectedKeys().iterator(); + while(selectedKeys.hasNext()) { + SelectionKey key = selectedKeys.next(); + processKey(key); + + selectedKeys.remove(); + + if(block.isGiven()) { + block.call(context, (IRubyObject)key.attachment()); + } else { + array.add(key.attachment()); + } + } + + if(block.isGiven()) { + return RubyNumeric.int2fix(runtime, ready); + } else { + return array; + } + } + + /* Run the selector */ + private int doSelect(Ruby runtime, ThreadContext context, IRubyObject timeout) { + int result; + + cancelKeys(); + try { + context.getThread().beforeBlockingCall(context); + if(timeout.isNil()) { + result = this.selector.select(); + } else { + double t = RubyNumeric.num2dbl(timeout); + if(t == 0) { + result = this.selector.selectNow(); + } else if(t < 0) { + throw runtime.newArgumentError("time interval must be positive"); + } else { + long timeoutMilliSeconds = (long)(t * 1000); + if(timeoutMilliSeconds == 0) { + result = this.selector.selectNow(); + } else { + result = this.selector.select(timeoutMilliSeconds); + } + } + } + context.getThread().afterBlockingCall(); + return result; + } catch(IOException ie) { + throw runtime.newIOError(ie.getLocalizedMessage()); + } + } + + /* Flush our internal buffer of cancelled keys */ + private void cancelKeys() { + Iterator> cancelledKeys = this.cancelledKeys.entrySet().iterator(); + while(cancelledKeys.hasNext()) { + Map.Entry entry = cancelledKeys.next(); + SelectionKey key = entry.getValue(); + key.cancel(); + cancelledKeys.remove(); + } + } + + // Remove connect interest from connected sockets + // See: http://stackoverflow.com/questions/204186/java-nio-select-returns-without-selected-keys-why + private void processKey(SelectionKey key) { + if(key.isValid() && (key.readyOps() & SelectionKey.OP_CONNECT) != 0) { + int interestOps = key.interestOps(); + + interestOps &= ~SelectionKey.OP_CONNECT; + interestOps |= SelectionKey.OP_WRITE; + + key.interestOps(interestOps); + } + } + + @JRubyMethod + public IRubyObject wakeup(ThreadContext context) { + if(!this.selector.isOpen()) { + throw context.getRuntime().newIOError("selector is closed"); + } + + this.wakeupFired = true; + this.selector.wakeup(); + + return context.nil; + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/selector.c b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/selector.c new file mode 100644 index 00000000..662254c5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/ext/nio4r/selector.c @@ -0,0 +1,606 @@ +/* + * Copyright (c) 2011 Tony Arcieri. Distributed under the MIT License. See + * LICENSE.txt for further details. + */ + +#include "nio4r.h" +#ifdef HAVE_RUBYSIG_H +#include "rubysig.h" +#endif + +#ifdef HAVE_UNISTD_H +#include +#else +#include +#endif + +#include +#include + +static VALUE mNIO = Qnil; +static VALUE cNIO_Monitor = Qnil; +static VALUE cNIO_Selector = Qnil; + +/* Allocator/deallocator */ +static VALUE NIO_Selector_allocate(VALUE klass); +static void NIO_Selector_mark(void *data); +static void NIO_Selector_shutdown(struct NIO_Selector *selector); +static void NIO_Selector_free(void *data); +static size_t NIO_Selector_memsize(const void *data); + +/* Class methods */ +static VALUE NIO_Selector_supported_backends(VALUE klass); + +/* Instance methods */ +static VALUE NIO_Selector_initialize(int argc, VALUE *argv, VALUE self); +static VALUE NIO_Selector_backend(VALUE self); +static VALUE NIO_Selector_register(VALUE self, VALUE selectable, VALUE interest); +static VALUE NIO_Selector_deregister(VALUE self, VALUE io); +static VALUE NIO_Selector_is_registered(VALUE self, VALUE io); +static VALUE NIO_Selector_select(int argc, VALUE *argv, VALUE self); +static VALUE NIO_Selector_wakeup(VALUE self); +static VALUE NIO_Selector_close(VALUE self); +static VALUE NIO_Selector_closed(VALUE self); +static VALUE NIO_Selector_is_empty(VALUE self); + +/* Internal functions */ +static VALUE NIO_Selector_synchronize(VALUE self, VALUE (*func)(VALUE arg), VALUE arg); +static VALUE NIO_Selector_unlock(VALUE lock); +static VALUE NIO_Selector_register_synchronized(VALUE arg); +static VALUE NIO_Selector_deregister_synchronized(VALUE arg); +static VALUE NIO_Selector_select_synchronized(VALUE arg); +static VALUE NIO_Selector_close_synchronized(VALUE arg); +static VALUE NIO_Selector_closed_synchronized(VALUE arg); + +static int NIO_Selector_run(struct NIO_Selector *selector, VALUE timeout); +static void NIO_Selector_timeout_callback(struct ev_loop *ev_loop, struct ev_timer *timer, int revents); +static void NIO_Selector_wakeup_callback(struct ev_loop *ev_loop, struct ev_io *io, int revents); + +/* Default number of slots in the buffer for selected monitors */ +#define INITIAL_READY_BUFFER 32 + +/* Ruby 1.8 needs us to busy wait and run the green threads scheduler every 10ms */ +#define BUSYWAIT_INTERVAL 0.01 + +/* Selectors wait for events */ +void Init_NIO_Selector(void) +{ + mNIO = rb_define_module("NIO"); + cNIO_Selector = rb_define_class_under(mNIO, "Selector", rb_cObject); + rb_define_alloc_func(cNIO_Selector, NIO_Selector_allocate); + + rb_define_singleton_method(cNIO_Selector, "backends", NIO_Selector_supported_backends, 0); + rb_define_method(cNIO_Selector, "initialize", NIO_Selector_initialize, -1); + rb_define_method(cNIO_Selector, "backend", NIO_Selector_backend, 0); + rb_define_method(cNIO_Selector, "register", NIO_Selector_register, 2); + rb_define_method(cNIO_Selector, "deregister", NIO_Selector_deregister, 1); + rb_define_method(cNIO_Selector, "registered?", NIO_Selector_is_registered, 1); + rb_define_method(cNIO_Selector, "select", NIO_Selector_select, -1); + rb_define_method(cNIO_Selector, "wakeup", NIO_Selector_wakeup, 0); + rb_define_method(cNIO_Selector, "close", NIO_Selector_close, 0); + rb_define_method(cNIO_Selector, "closed?", NIO_Selector_closed, 0); + rb_define_method(cNIO_Selector, "empty?", NIO_Selector_is_empty, 0); + + cNIO_Monitor = rb_define_class_under(mNIO, "Monitor", rb_cObject); +} + +static const rb_data_type_t NIO_Selector_type = { + "NIO::Selector", + { + NIO_Selector_mark, + NIO_Selector_free, + NIO_Selector_memsize, + }, + 0, + 0, + RUBY_TYPED_WB_PROTECTED // Don't free immediately because of shutdown +}; + +/* Create the libev event loop and incoming event buffer */ +static VALUE NIO_Selector_allocate(VALUE klass) +{ + struct NIO_Selector *selector; + int fds[2]; + + /* Use a pipe to implement the wakeup mechanism. I know libev provides + async watchers that implement this same behavior, but I'm getting + segvs trying to use that between threads, despite claims of thread + safety. Pipes are nice and safe to use between threads. + + Note that Java NIO uses this same mechanism */ + if (pipe(fds) < 0) { + rb_sys_fail("pipe"); + } + + /* Use non-blocking reads/writes during wakeup, in case the buffer is full */ + if (fcntl(fds[0], F_SETFL, O_NONBLOCK) < 0 || fcntl(fds[1], F_SETFL, O_NONBLOCK) < 0) { + rb_sys_fail("fcntl"); + } + + VALUE obj = TypedData_Make_Struct(klass, struct NIO_Selector, &NIO_Selector_type, selector); + /* Defer initializing the loop to #initialize */ + selector->ev_loop = 0; + + ev_init(&selector->timer, NIO_Selector_timeout_callback); + + selector->wakeup_reader = fds[0]; + selector->wakeup_writer = fds[1]; + + ev_io_init(&selector->wakeup, NIO_Selector_wakeup_callback, selector->wakeup_reader, EV_READ); + selector->wakeup.data = (void *)selector; + + selector->closed = selector->selecting = selector->wakeup_fired = selector->ready_count = 0; + RB_OBJ_WRITE(obj, &selector->ready_array, Qnil); + return obj; +} + +struct NIO_Selector *NIO_Selector_unwrap(VALUE self) +{ + struct NIO_Selector *selector; + TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector); + return selector; +} + +/* NIO selectors store all Ruby objects in instance variables so mark is a stub */ +static void NIO_Selector_mark(void *data) +{ + struct NIO_Selector *selector = (struct NIO_Selector *)data; + if (selector->ready_array != Qnil) { + rb_gc_mark(selector->ready_array); + } +} + +/* Free a Selector's system resources. + Called by both NIO::Selector#close and the finalizer below */ +static void NIO_Selector_shutdown(struct NIO_Selector *selector) +{ + if (selector->closed) { + return; + } + + close(selector->wakeup_reader); + close(selector->wakeup_writer); + + if (selector->ev_loop) { + ev_loop_destroy(selector->ev_loop); + selector->ev_loop = 0; + } + + selector->closed = 1; +} + +/* Ruby finalizer for selector objects */ +static void NIO_Selector_free(void *data) +{ + struct NIO_Selector *selector = (struct NIO_Selector *)data; + NIO_Selector_shutdown(selector); + xfree(selector); +} + +static size_t NIO_Selector_memsize(const void *data) +{ + return sizeof(struct NIO_Selector); +} + +/* Return an array of symbols for supported backends */ +static VALUE NIO_Selector_supported_backends(VALUE klass) +{ + unsigned int backends = ev_supported_backends(); + VALUE result = rb_ary_new(); + + if (backends & EVBACKEND_EPOLL) { + rb_ary_push(result, ID2SYM(rb_intern("epoll"))); + } + + if (backends & EVBACKEND_POLL) { + rb_ary_push(result, ID2SYM(rb_intern("poll"))); + } + + if (backends & EVBACKEND_KQUEUE) { + rb_ary_push(result, ID2SYM(rb_intern("kqueue"))); + } + + if (backends & EVBACKEND_SELECT) { + rb_ary_push(result, ID2SYM(rb_intern("select"))); + } + + if (backends & EVBACKEND_PORT) { + rb_ary_push(result, ID2SYM(rb_intern("port"))); + } + + if (backends & EVBACKEND_LINUXAIO) { + rb_ary_push(result, ID2SYM(rb_intern("linuxaio"))); + } + + if (backends & EVBACKEND_IOURING) { + rb_ary_push(result, ID2SYM(rb_intern("io_uring"))); + } + + return result; +} + +/* Create a new selector. This is more or less the pure Ruby version + translated into an MRI cext */ +static VALUE NIO_Selector_initialize(int argc, VALUE *argv, VALUE self) +{ + ID backend_id; + VALUE backend; + VALUE lock; + + struct NIO_Selector *selector; + unsigned int flags = 0; + + TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector); + + rb_scan_args(argc, argv, "01", &backend); + + if (backend != Qnil) { + if (!rb_ary_includes(NIO_Selector_supported_backends(CLASS_OF(self)), backend)) { + rb_raise(rb_eArgError, "unsupported backend: %s", RSTRING_PTR(rb_funcall(backend, rb_intern("inspect"), 0))); + } + + backend_id = SYM2ID(backend); + + if (backend_id == rb_intern("epoll")) { + flags = EVBACKEND_EPOLL; + } else if (backend_id == rb_intern("poll")) { + flags = EVBACKEND_POLL; + } else if (backend_id == rb_intern("kqueue")) { + flags = EVBACKEND_KQUEUE; + } else if (backend_id == rb_intern("select")) { + flags = EVBACKEND_SELECT; + } else if (backend_id == rb_intern("port")) { + flags = EVBACKEND_PORT; + } else if (backend_id == rb_intern("linuxaio")) { + flags = EVBACKEND_LINUXAIO; + } else if (backend_id == rb_intern("io_uring")) { + flags = EVBACKEND_IOURING; + } else { + rb_raise(rb_eArgError, "unsupported backend: %s", RSTRING_PTR(rb_funcall(backend, rb_intern("inspect"), 0))); + } + } + + /* Ensure the selector loop has not yet been initialized */ + assert(!selector->ev_loop); + + selector->ev_loop = ev_loop_new(flags); + if (!selector->ev_loop) { + rb_raise(rb_eIOError, "error initializing event loop"); + } + + ev_io_start(selector->ev_loop, &selector->wakeup); + + rb_ivar_set(self, rb_intern("selectables"), rb_hash_new()); + rb_ivar_set(self, rb_intern("lock_holder"), Qnil); + + lock = rb_class_new_instance(0, 0, rb_const_get(rb_cObject, rb_intern("Mutex"))); + rb_ivar_set(self, rb_intern("lock"), lock); + rb_ivar_set(self, rb_intern("lock_holder"), Qnil); + + return Qnil; +} + +static VALUE NIO_Selector_backend(VALUE self) +{ + struct NIO_Selector *selector; + + TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector); + if (selector->closed) { + rb_raise(rb_eIOError, "selector is closed"); + } + + switch (ev_backend(selector->ev_loop)) { + case EVBACKEND_EPOLL: + return ID2SYM(rb_intern("epoll")); + case EVBACKEND_POLL: + return ID2SYM(rb_intern("poll")); + case EVBACKEND_KQUEUE: + return ID2SYM(rb_intern("kqueue")); + case EVBACKEND_SELECT: + return ID2SYM(rb_intern("select")); + case EVBACKEND_PORT: + return ID2SYM(rb_intern("port")); + case EVBACKEND_LINUXAIO: + return ID2SYM(rb_intern("linuxaio")); + case EVBACKEND_IOURING: + return ID2SYM(rb_intern("io_uring")); + } + + return ID2SYM(rb_intern("unknown")); +} + +/* Synchronize around a reentrant selector lock */ +static VALUE NIO_Selector_synchronize(VALUE self, VALUE (*func)(VALUE arg), VALUE arg) +{ + VALUE current_thread, lock_holder, lock; + + current_thread = rb_thread_current(); + lock_holder = rb_ivar_get(self, rb_intern("lock_holder")); + + if (lock_holder != current_thread) { + lock = rb_ivar_get(self, rb_intern("lock")); + rb_funcall(lock, rb_intern("lock"), 0); + rb_ivar_set(self, rb_intern("lock_holder"), current_thread); + + /* We've acquired the lock, so ensure we unlock it */ + return rb_ensure(func, (VALUE)arg, NIO_Selector_unlock, self); + } else { + /* We already hold the selector lock, so no need to unlock it */ + return func(arg); + } +} + +/* Unlock the selector mutex */ +static VALUE NIO_Selector_unlock(VALUE self) +{ + VALUE lock; + + rb_ivar_set(self, rb_intern("lock_holder"), Qnil); + + lock = rb_ivar_get(self, rb_intern("lock")); + rb_funcall(lock, rb_intern("unlock"), 0); + + return Qnil; +} + +/* Register an IO object with the selector for the given interests */ +static VALUE NIO_Selector_register(VALUE self, VALUE io, VALUE interests) +{ + VALUE args[3] = {self, io, interests}; + return NIO_Selector_synchronize(self, NIO_Selector_register_synchronized, (VALUE)args); +} + +/* Internal implementation of register after acquiring mutex */ +static VALUE NIO_Selector_register_synchronized(VALUE _args) +{ + VALUE self, io, interests, selectables, monitor; + VALUE monitor_args[3]; + struct NIO_Selector *selector; + + VALUE *args = (VALUE *)_args; + self = args[0]; + io = args[1]; + interests = args[2]; + + TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector); + if (selector->closed) { + rb_raise(rb_eIOError, "selector is closed"); + } + + selectables = rb_ivar_get(self, rb_intern("selectables")); + monitor = rb_hash_lookup(selectables, io); + + if (monitor != Qnil) + rb_raise(rb_eArgError, "this IO is already registered with selector"); + + /* Create a new NIO::Monitor */ + monitor_args[0] = io; + monitor_args[1] = interests; + monitor_args[2] = self; + + monitor = rb_class_new_instance(3, monitor_args, cNIO_Monitor); + rb_hash_aset(selectables, rb_funcall(monitor, rb_intern("io"), 0), monitor); + + return monitor; +} + +/* Deregister an IO object from the selector */ +static VALUE NIO_Selector_deregister(VALUE self, VALUE io) +{ + VALUE args[2] = {self, io}; + return NIO_Selector_synchronize(self, NIO_Selector_deregister_synchronized, (VALUE)args); +} + +/* Internal implementation of register after acquiring mutex */ +static VALUE NIO_Selector_deregister_synchronized(VALUE _args) +{ + VALUE self, io, selectables, monitor; + + VALUE *args = (VALUE *)_args; + self = args[0]; + io = args[1]; + + selectables = rb_ivar_get(self, rb_intern("selectables")); + monitor = rb_hash_delete(selectables, io); + + if (monitor != Qnil) { + rb_funcall(monitor, rb_intern("close"), 1, Qfalse); + } + + return monitor; +} + +/* Is the given IO object registered with the selector */ +static VALUE NIO_Selector_is_registered(VALUE self, VALUE io) +{ + VALUE selectables = rb_ivar_get(self, rb_intern("selectables")); + + /* Perhaps this should be holding the mutex? */ + return rb_funcall(selectables, rb_intern("has_key?"), 1, io); +} + +/* Select from all registered IO objects */ +static VALUE NIO_Selector_select(int argc, VALUE *argv, VALUE self) +{ + VALUE timeout; + + rb_scan_args(argc, argv, "01", &timeout); + + if (timeout != Qnil && NUM2DBL(timeout) < 0) { + rb_raise(rb_eArgError, "time interval must be positive"); + } + + VALUE args[2] = {self, timeout}; + return NIO_Selector_synchronize(self, NIO_Selector_select_synchronized, (VALUE)args); +} + +/* Internal implementation of select with the selector lock held */ +static VALUE NIO_Selector_select_synchronized(VALUE _args) +{ + int ready; + VALUE ready_array; + struct NIO_Selector *selector; + + VALUE *args = (VALUE *)_args; + + TypedData_Get_Struct(args[0], struct NIO_Selector, &NIO_Selector_type, selector); + + if (selector->closed) { + rb_raise(rb_eIOError, "selector is closed"); + } + + if (!rb_block_given_p()) { + RB_OBJ_WRITE(args[0], &selector->ready_array, rb_ary_new()); + } + + ready = NIO_Selector_run(selector, args[1]); + + /* Timeout */ + if (ready < 0) { + if (!rb_block_given_p()) { + RB_OBJ_WRITE(args[0], &selector->ready_array, Qnil); + } + + return Qnil; + } + + if (rb_block_given_p()) { + return INT2NUM(ready); + } else { + ready_array = selector->ready_array; + RB_OBJ_WRITE(args[0], &selector->ready_array, Qnil); + return ready_array; + } +} + +static int NIO_Selector_run(struct NIO_Selector *selector, VALUE timeout) +{ + int ev_run_flags = EVRUN_ONCE; + int result; + double timeout_val; + + selector->selecting = 1; + selector->wakeup_fired = 0; + + if (timeout == Qnil) { + /* Don't fire a wakeup timeout if we weren't passed one */ + ev_timer_stop(selector->ev_loop, &selector->timer); + } else { + timeout_val = NUM2DBL(timeout); + if (timeout_val == 0) { + /* If we've been given an explicit timeout of 0, perform a non-blocking + select operation */ + ev_run_flags = EVRUN_NOWAIT; + } else { + selector->timer.repeat = timeout_val; + ev_timer_again(selector->ev_loop, &selector->timer); + } + } + + /* libev is patched to release the GIL when it makes its system call */ + ev_run(selector->ev_loop, ev_run_flags); + + result = selector->ready_count; + selector->selecting = selector->ready_count = 0; + + if (result > 0 || selector->wakeup_fired) { + selector->wakeup_fired = 0; + return result; + } else { + return -1; + } +} + +/* Wake the selector up from another thread */ +static VALUE NIO_Selector_wakeup(VALUE self) +{ + struct NIO_Selector *selector; + TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector); + + if (selector->closed) { + rb_raise(rb_eIOError, "selector is closed"); + } + + selector->wakeup_fired = 1; + write(selector->wakeup_writer, "\0", 1); + + return Qnil; +} + +/* Close the selector and free system resources */ +static VALUE NIO_Selector_close(VALUE self) +{ + return NIO_Selector_synchronize(self, NIO_Selector_close_synchronized, self); +} + +static VALUE NIO_Selector_close_synchronized(VALUE self) +{ + struct NIO_Selector *selector; + + TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector); + + NIO_Selector_shutdown(selector); + + return Qnil; +} + +/* Is the selector closed? */ +static VALUE NIO_Selector_closed(VALUE self) +{ + return NIO_Selector_synchronize(self, NIO_Selector_closed_synchronized, self); +} + +static VALUE NIO_Selector_closed_synchronized(VALUE self) +{ + struct NIO_Selector *selector; + + TypedData_Get_Struct(self, struct NIO_Selector, &NIO_Selector_type, selector); + + return selector->closed ? Qtrue : Qfalse; +} + +/* True if there are monitors on the loop */ +static VALUE NIO_Selector_is_empty(VALUE self) +{ + VALUE selectables = rb_ivar_get(self, rb_intern("selectables")); + + return rb_funcall(selectables, rb_intern("empty?"), 0) == Qtrue ? Qtrue : Qfalse; +} + +/* Called whenever a timeout fires on the event loop */ +static void NIO_Selector_timeout_callback(struct ev_loop *ev_loop, struct ev_timer *timer, int revents) +{ +} + +/* Called whenever a wakeup request is sent to a selector */ +static void NIO_Selector_wakeup_callback(struct ev_loop *ev_loop, struct ev_io *io, int revents) +{ + char buffer[128]; + struct NIO_Selector *selector = (struct NIO_Selector *)io->data; + selector->selecting = 0; + + /* Drain the wakeup pipe, giving us level-triggered behavior */ + while (read(selector->wakeup_reader, buffer, 128) > 0) + ; +} + +/* libev callback fired whenever a monitor gets an event */ +void NIO_Selector_monitor_callback(struct ev_loop *ev_loop, struct ev_io *io, int revents) +{ + struct NIO_Monitor *monitor_data = (struct NIO_Monitor *)io->data; + struct NIO_Selector *selector = monitor_data->selector; + VALUE monitor = monitor_data->self; + + assert(monitor_data->interests != 0); + + assert(selector != 0); + selector->ready_count++; + monitor_data->revents = revents; + + if (rb_block_given_p()) { + rb_yield(monitor); + } else { + assert(selector->ready_array != Qnil); + rb_ary_push(selector->ready_array, monitor); + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/lib/nio.rb b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/lib/nio.rb new file mode 100644 index 00000000..bca3ee6b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/lib/nio.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +# Released under the MIT License. +# Copyright, 2011-2017, by Tony Arcieri. +# Copyright, 2013, by Stephen von Takach. +# Copyright, 2013, by Per Lundberg. +# Copyright, 2014, by Marek Kowalcze. +# Copyright, 2016, by Upekshe Jayasekera. +# Copyright, 2019-2023, by Samuel Williams. +# Copyright, 2021, by Jun Jiang. + +require "socket" +require "nio/version" + +# New I/O for Ruby +module NIO + # NIO implementation, one of the following (as a string): + # * select: in pure Ruby using Kernel.select + # * libev: as a C extension using libev + # * java: using Java NIO + def self.engine + ENGINE + end + + def self.pure?(env = ENV) + # The user has explicitly opted in to non-native implementation: + if env["NIO4R_PURE"] == "true" + return true + end + + # Native Ruby on Windows is not supported: + if (Gem.win_platform? && !defined?(JRUBY_VERSION)) + return true + end + + # M1 native extension is crashing on M1 (arm64): + # if RUBY_PLATFORM =~ /darwin/ && RUBY_PLATFORM =~ /arm64/ + # return true + # end + + return false + end +end + +if NIO.pure? + require "nio/monitor" + require "nio/selector" + require "nio/bytebuffer" + NIO::ENGINE = "ruby" +else + require "nio4r_ext" + + if defined?(JRUBY_VERSION) + require "java" + require "jruby" + org.nio4r.Nio4r.new.load(JRuby.runtime, false) + NIO::ENGINE = "java" + else + NIO::ENGINE = "libev" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/lib/nio/bytebuffer.rb b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/lib/nio/bytebuffer.rb new file mode 100644 index 00000000..7171120d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/lib/nio/bytebuffer.rb @@ -0,0 +1,235 @@ +# frozen_string_literal: true + +# Released under the MIT License. +# Copyright, 2016, by Upekshe Jayasekera. +# Copyright, 2016-2017, by Tony Arcieri. +# Copyright, 2020, by Thomas Dziedzic. +# Copyright, 2023, by Samuel Williams. + +module NIO + # Efficient byte buffers for performant I/O operations + class ByteBuffer + include Enumerable + + attr_reader :position, :limit, :capacity + + # Insufficient capacity in buffer + OverflowError = Class.new(IOError) + + # Not enough data remaining in buffer + UnderflowError = Class.new(IOError) + + # Mark has not been set + MarkUnsetError = Class.new(IOError) + + # Create a new ByteBuffer, either with a specified capacity or populating + # it from a given string + # + # @param capacity [Integer] size of buffer in bytes + # + # @return [NIO::ByteBuffer] + def initialize(capacity) + raise TypeError, "no implicit conversion of #{capacity.class} to Integer" unless capacity.is_a?(Integer) + + @capacity = capacity + clear + end + + # Clear the buffer, resetting it to the default state + def clear + @buffer = ("\0" * @capacity).force_encoding(Encoding::BINARY) + @position = 0 + @limit = @capacity + @mark = nil + + self + end + + # Set the position to the given value. New position must be less than limit. + # Preserves mark if it's less than the new position, otherwise clears it. + # + # @param new_position [Integer] position in the buffer + # + # @raise [ArgumentError] new position was invalid + def position=(new_position) + raise ArgumentError, "negative position given" if new_position < 0 + raise ArgumentError, "specified position exceeds capacity" if new_position > @capacity + + @mark = nil if @mark && @mark > new_position + @position = new_position + end + + # Set the limit to the given value. New limit must be less than capacity. + # Preserves limit and mark if they're less than the new limit, otherwise + # sets position to the new limit and clears the mark. + # + # @param new_limit [Integer] position in the buffer + # + # @raise [ArgumentError] new limit was invalid + def limit=(new_limit) + raise ArgumentError, "negative limit given" if new_limit < 0 + raise ArgumentError, "specified limit exceeds capacity" if new_limit > @capacity + + @position = new_limit if @position > new_limit + @mark = nil if @mark && @mark > new_limit + @limit = new_limit + end + + # Number of bytes remaining in the buffer before the limit + # + # @return [Integer] number of bytes remaining + def remaining + @limit - @position + end + + # Does the ByteBuffer have any space remaining? + # + # @return [true, false] + def full? + remaining.zero? + end + + # Obtain the requested number of bytes from the buffer, advancing the position. + # If no length is given, all remaining bytes are consumed. + # + # @raise [NIO::ByteBuffer::UnderflowError] not enough data remaining in buffer + # + # @return [String] bytes read from buffer + def get(length = remaining) + raise ArgumentError, "negative length given" if length < 0 + raise UnderflowError, "not enough data in buffer" if length > @limit - @position + + result = @buffer[@position...length] + @position += length + result + end + + # Obtain the byte at a given index in the buffer as an Integer + # + # @raise [ArgumentError] index is invalid (either negative or larger than limit) + # + # @return [Integer] byte at the given index + def [](index) + raise ArgumentError, "negative index given" if index < 0 + raise ArgumentError, "specified index exceeds limit" if index >= @limit + + @buffer.bytes[index] + end + + # Add a String to the buffer + # + # @param str [#to_str] data to add to the buffer + # + # @raise [TypeError] given a non-string type + # @raise [NIO::ByteBuffer::OverflowError] buffer is full + # + # @return [self] + def put(str) + raise TypeError, "expected String, got #{str.class}" unless str.respond_to?(:to_str) + + str = str.to_str + + raise OverflowError, "buffer is full" if str.length > @limit - @position + + @buffer[@position...str.length] = str + @position += str.length + self + end + alias << put + + # Perform a non-blocking read from the given IO object into the buffer + # Reads as much data as is immediately available and returns + # + # @param [IO] Ruby IO object to read from + # + # @return [Integer] number of bytes read (0 if none were available) + def read_from(io) + nbytes = @limit - @position + raise OverflowError, "buffer is full" if nbytes.zero? + + bytes_read = IO.try_convert(io).read_nonblock(nbytes, exception: false) + return 0 if bytes_read == :wait_readable + + self << bytes_read + bytes_read.length + end + + # Perform a non-blocking write of the buffer's contents to the given I/O object + # Writes as much data as is immediately possible and returns + # + # @param [IO] Ruby IO object to write to + # + # @return [Integer] number of bytes written (0 if the write would block) + def write_to(io) + nbytes = @limit - @position + raise UnderflowError, "no data remaining in buffer" if nbytes.zero? + + bytes_written = IO.try_convert(io).write_nonblock(@buffer[@position...@limit], exception: false) + return 0 if bytes_written == :wait_writable + + @position += bytes_written + bytes_written + end + + # Set the buffer's current position as the limit and set the position to 0 + def flip + @limit = @position + @position = 0 + @mark = nil + self + end + + # Set the buffer's current position to 0, leaving the limit unchanged + def rewind + @position = 0 + @mark = nil + self + end + + # Mark a position to return to using the `#reset` method + def mark + @mark = @position + self + end + + # Reset position to the previously marked location + # + # @raise [NIO::ByteBuffer::MarkUnsetError] mark has not been set (call `#mark` first) + def reset + raise MarkUnsetError, "mark has not been set" unless @mark + + @position = @mark + self + end + + # Move data between the position and limit to the beginning of the buffer + # Sets the position to the end of the moved data, and the limit to the capacity + def compact + @buffer[0...(@limit - @position)] = @buffer[@position...@limit] + @position = @limit - @position + @limit = capacity + self + end + + # Iterate over the bytes in the buffer (as Integers) + # + # @return [self] + def each(&block) + @buffer[0...@limit].each_byte(&block) + end + + # Inspect the state of the buffer + # + # @return [String] string describing the state of the buffer + def inspect + format( + "#<%s:0x%x @position=%d @limit=%d @capacity=%d>", + self.class, + object_id << 1, + @position, + @limit, + @capacity + ) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/lib/nio/monitor.rb b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/lib/nio/monitor.rb new file mode 100644 index 00000000..c7bd26eb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/lib/nio/monitor.rb @@ -0,0 +1,124 @@ +# frozen_string_literal: true + +# Released under the MIT License. +# Copyright, 2011-2018, by Tony Arcieri. +# Copyright, 2015, by Upekshe Jayasekera. +# Copyright, 2015, by Vladimir Kochnev. +# Copyright, 2018-2023, by Samuel Williams. +# Copyright, 2019-2020, by Gregory Longtin. + +module NIO + # Monitors watch IO objects for specific events + class Monitor + attr_reader :io, :interests, :selector + attr_accessor :value, :readiness + + # :nodoc: + def initialize(io, interests, selector) + unless defined?(::OpenSSL) && io.is_a?(::OpenSSL::SSL::SSLSocket) + unless io.is_a?(IO) + if IO.respond_to? :try_convert + io = IO.try_convert(io) + elsif io.respond_to? :to_io + io = io.to_io + end + + raise TypeError, "can't convert #{io.class} into IO" unless io.is_a? IO + end + end + + @io = io + @interests = interests + @selector = selector + @closed = false + end + + # Replace the existing interest set with a new one + # + # @param interests [:r, :w, :rw, nil] I/O readiness we're interested in (read/write/readwrite) + # + # @return [Symbol] new interests + def interests=(interests) + raise EOFError, "monitor is closed" if closed? + raise ArgumentError, "bad interests: #{interests}" unless [:r, :w, :rw, nil].include?(interests) + + @interests = interests + end + + # Add new interests to the existing interest set + # + # @param interests [:r, :w, :rw] new I/O interests (read/write/readwrite) + # + # @return [self] + def add_interest(interest) + case interest + when :r + case @interests + when :r then @interests = :r + when :w then @interests = :rw + when :rw then @interests = :rw + when nil then @interests = :r + end + when :w + case @interests + when :r then @interests = :rw + when :w then @interests = :w + when :rw then @interests = :rw + when nil then @interests = :w + end + when :rw + @interests = :rw + else raise ArgumentError, "bad interests: #{interest}" + end + end + + # Remove interests from the existing interest set + # + # @param interests [:r, :w, :rw] I/O interests to remove (read/write/readwrite) + # + # @return [self] + def remove_interest(interest) + case interest + when :r + case @interests + when :r then @interests = nil + when :w then @interests = :w + when :rw then @interests = :w + when nil then @interests = nil + end + when :w + case @interests + when :r then @interests = :r + when :w then @interests = nil + when :rw then @interests = :r + when nil then @interests = nil + end + when :rw + @interests = nil + else raise ArgumentError, "bad interests: #{interest}" + end + end + + # Is the IO object readable? + def readable? + readiness == :r || readiness == :rw + end + + # Is the IO object writable? + def writable? + readiness == :w || readiness == :rw + end + alias writeable? writable? + + # Is this monitor closed? + def closed? + @closed + end + + # Deactivate this monitor + def close(deregister = true) + @closed = true + @selector.deregister(io) if deregister + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/lib/nio/selector.rb b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/lib/nio/selector.rb new file mode 100644 index 00000000..b422e997 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/lib/nio/selector.rb @@ -0,0 +1,188 @@ +# frozen_string_literal: true + +# Released under the MIT License. +# Copyright, 2011-2017, by Tony Arcieri. +# Copyright, 2012, by Logan Bowers. +# Copyright, 2013, by Sadayuki Furuhashi. +# Copyright, 2013, by Stephen von Takach. +# Copyright, 2013, by Tim Carey-Smith. +# Copyright, 2013, by Ravil Bayramgalin. +# Copyright, 2014, by Sergey Avseyev. +# Copyright, 2014, by John Thornton. +# Copyright, 2015, by Vladimir Kochnev. +# Copyright, 2015, by Upekshe Jayasekera. +# Copyright, 2019-2020, by Gregory Longtin. +# Copyright, 2020-2021, by Joao Fernandes. +# Copyright, 2023, by Samuel Williams. + +require "set" + +module NIO + # Selectors monitor IO objects for events of interest + class Selector + # Return supported backends as symbols + # + # See `#backend` method definition for all possible backends + def self.backends + [:ruby] + end + + # Create a new NIO::Selector + def initialize(backend = :ruby) + raise ArgumentError, "unsupported backend: #{backend}" unless [:ruby, nil].include?(backend) + + @selectables = {} + @lock = Mutex.new + + # Other threads can wake up a selector + @wakeup, @waker = IO.pipe + @closed = false + end + + # Return a symbol representing the backend I/O multiplexing mechanism used. + # Supported backends are: + # * :ruby - pure Ruby (i.e IO.select) + # * :java - Java NIO on JRuby + # * :epoll - libev w\ Linux epoll + # * :poll - libev w\ POSIX poll + # * :kqueue - libev w\ BSD kqueue + # * :select - libev w\ SysV select + # * :port - libev w\ I/O completion ports + # * :linuxaio - libev w\ Linux AIO io_submit (experimental) + # * :io_uring - libev w\ Linux io_uring (experimental) + # * :unknown - libev w\ unknown backend + def backend + :ruby + end + + # Register interest in an IO object with the selector for the given types + # of events. Valid event types for interest are: + # * :r - is the IO readable? + # * :w - is the IO writeable? + # * :rw - is the IO either readable or writeable? + def register(io, interest) + unless defined?(::OpenSSL) && io.is_a?(::OpenSSL::SSL::SSLSocket) + io = IO.try_convert(io) + end + + @lock.synchronize do + raise IOError, "selector is closed" if closed? + + monitor = @selectables[io] + raise ArgumentError, "already registered as #{monitor.interests.inspect}" if monitor + + monitor = Monitor.new(io, interest, self) + @selectables[monitor.io] = monitor + + monitor + end + end + + # Deregister the given IO object from the selector + def deregister(io) + @lock.synchronize do + monitor = @selectables.delete IO.try_convert(io) + monitor.close(false) if monitor && !monitor.closed? + monitor + end + end + + # Is the given IO object registered with the selector? + def registered?(io) + @lock.synchronize { @selectables.key? io } + end + + # Select which monitors are ready + def select(timeout = nil) + selected_monitors = Set.new + + @lock.synchronize do + readers = [@wakeup] + writers = [] + + @selectables.each do |io, monitor| + readers << io if monitor.interests == :r || monitor.interests == :rw + writers << io if monitor.interests == :w || monitor.interests == :rw + monitor.readiness = nil + end + + ready_readers, ready_writers = Kernel.select(readers, writers, [], timeout) + return unless ready_readers # timeout + + ready_readers.each do |io| + if io == @wakeup + # Clear all wakeup signals we've received by reading them + # Wakeups should have level triggered behavior + @wakeup.read(@wakeup.stat.size) + else + monitor = @selectables[io] + monitor.readiness = :r + selected_monitors << monitor + end + end + + ready_writers.each do |io| + monitor = @selectables[io] + monitor.readiness = monitor.readiness == :r ? :rw : :w + selected_monitors << monitor + end + end + + if block_given? + selected_monitors.each { |m| yield m } + selected_monitors.size + else + selected_monitors.to_a + end + end + + # Wake up a thread that's in the middle of selecting on this selector, if + # any such thread exists. + # + # Invoking this method more than once between two successive select calls + # has the same effect as invoking it just once. In other words, it provides + # level-triggered behavior. + def wakeup + # Send the selector a signal in the form of writing data to a pipe + begin + @waker.write_nonblock "\0" + rescue IO::WaitWritable + # This indicates the wakeup pipe is full, which means the other thread + # has already received many wakeup calls, but not processed them yet. + # The other thread will completely drain this pipe when it wakes up, + # so it's ok to ignore this exception if it occurs: we know the other + # thread has already been signaled to wake up + end + + nil + end + + # Close this selector and free its resources + def close + @lock.synchronize do + return if @closed + + begin + @wakeup.close + rescue IOError + end + + begin + @waker.close + rescue IOError + end + + @closed = true + end + end + + # Is this selector closed? + def closed? + @closed + end + + def empty? + @selectables.empty? + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/lib/nio/version.rb b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/lib/nio/version.rb new file mode 100644 index 00000000..3b043fd3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/lib/nio/version.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# Released under the MIT License. +# Copyright, 2011-2018, by Tony Arcieri. +# Copyright, 2018-2024, by Samuel Williams. +# Copyright, 2023, by Tsimnuj Hawj. + +module NIO + VERSION = "2.7.4" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/lib/nio4r.rb b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/lib/nio4r.rb new file mode 100644 index 00000000..d551e82b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/lib/nio4r.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +# Released under the MIT License. +# Copyright, 2023, by Phillip Aldridge. +# Copyright, 2023, by Samuel Williams. + +require_relative "nio" diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/lib/nio4r_ext.so b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/lib/nio4r_ext.so new file mode 100755 index 00000000..9aa3501f Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/lib/nio4r_ext.so differ diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/license.md b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/license.md new file mode 100644 index 00000000..ad37246b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/license.md @@ -0,0 +1,80 @@ +# MIT License + +Copyright, 2011-2020, by Tony Arcieri. +Copyright, 2012, by Bernd Ahlers. +Copyright, 2012, by Logan Bowers. +Copyright, 2012, by Dirkjan Bussink. +Copyright, 2013, by Sadayuki Furuhashi. +Copyright, 2013, by Shannon Skipper. +Copyright, 2013, by Stephen von Takach. +Copyright, 2013, by Tim Carey-Smith. +Copyright, 2013, by Per Lundberg. +Copyright, 2013, by Ravil Bayramgalin. +Copyright, 2013, by Luis Lavena. +Copyright, 2014, by Anatol Pomozov. +Copyright, 2014, by Hiroshi Shibata. +Copyright, 2014, by Marek Kowalcze. +Copyright, 2014, by Sergey Avseyev. +Copyright, 2014, by John Thornton. +Copyright, 2015-2017, by Tiago Cardoso. +Copyright, 2015, by Daniel Berger. +Copyright, 2015-2016, by Upekshe Jayasekera. +Copyright, 2015, by Vladimir Kochnev. +Copyright, 2016-2018, by Jun Aruga. +Copyright, 2016, by Omer Katz. +Copyright, 2016, by Denis Washington. +Copyright, 2016-2021, by Olle Jonsson. +Copyright, 2017, by Tao Luo. +Copyright, 2017, by Usaku Nakamura. +Copyright, 2017-2022, by Gregory Longtin. +Copyright, 2017, by Lars Kanis. +Copyright, 2017, by Tomoya Ishida. +Copyright, 2018-2024, by Samuel Williams. +Copyright, 2019, by Cédric Boutillier. +Copyright, 2019-2020, by Benoit Daloze. +Copyright, 2019, by Jesús Burgos Maciá. +Copyright, 2019, by Thomas Kuntz. +Copyright, 2019, by Orien Madgwick. +Copyright, 2019, by Zhang Kang. +Copyright, 2020, by Thomas Dziedzic. +Copyright, 2020, by Elad Eyal. +Copyright, 2020, by Pedro Paiva. +Copyright, 2020, by Boaz Segev. +Copyright, 2020, by Charles Oliver Nutter. +Copyright, 2020-2021, by Joao Fernandes. +Copyright, 2021, by Jun Jiang. +Copyright, 2021, by Pavel Lobashov. +Copyright, 2021, by Jeffrey Martin. +Copyright, 2023-2024, by Pavel Rosický. +Copyright, 2023, by Tsimnuj Hawj. +Copyright, 2023, by Phillip Aldridge. +Copyright, 2023, by Maxime Demolin. +Copyright, 2023-2024, by Vít Ondruch. +Copyright, 2023, by Jean Boussier. + +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 +AUTHORS OR COPYRIGHT HOLDERS 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. + +## libev + +Released under the BSD-2-Clause OR GPL-2.0-or-later license. +See [ext/libev/LICENSE] for details. + +Copyright, 2007-2019, by Marc Alexander Lehmann. + +[ext/libev/LICENSE]: https://github.com/socketry/nio4r/blob/master/ext/libev/LICENSE diff --git a/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/readme.md b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/readme.md new file mode 100644 index 00000000..1c528919 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/nio4r-2.7.4/readme.md @@ -0,0 +1,91 @@ +# ![nio4r](https://raw.github.com/socketry/nio4r/master/logo.png) + +[![Development Status](https://github.com/socketry/nio4r/workflows/Test/badge.svg)](https://github.com/socketry/nio4r/actions?workflow=Test) + +**New I/O for Ruby (nio4r)**: cross-platform asynchronous I/O primitives for +scalable network clients and servers. Modeled after the Java NIO API, but +simplified for ease-of-use. + +**nio4r** provides an abstract, cross-platform stateful I/O selector API for Ruby. +I/O selectors are the heart of "reactor"-based event loops, and monitor +multiple I/O objects for various types of readiness, e.g. ready for reading or +writing. + +## Projects using nio4r + + - [ActionCable](https://rubygems.org/gems/actioncable): Rails 5 WebSocket protocol, uses nio4r for a WebSocket server + - [Celluloid](https://github.com/celluloid/celluloid-io): Actor-based concurrency framework, uses nio4r for async I/O + - [Async](https://github.com/socketry/async): Asynchronous I/O framework for Ruby + - [Puma](https://github.com/puma/puma): Ruby/Rack web server built for concurrency + +## Goals + + - Expose high-level interfaces for stateful IO selectors + - Keep the API small to maximize both portability and performance across many + different OSes and Ruby VMs + - Provide inherently thread-safe facilities for working with IO objects + +## Supported platforms + + - Ruby 2.5 + - Ruby 2.6 + - Ruby 2.7 + - Ruby 3.0 + - [JRuby](https://github.com/jruby/jruby) + - [TruffleRuby](https://github.com/oracle/truffleruby) + +## Supported backends + + - **libev**: MRI C extension targeting multiple native IO selector APIs (e.g epoll, kqueue) + - **Java NIO**: JRuby extension which wraps the Java NIO subsystem + - **Pure Ruby**: `Kernel.select`-based backend that should work on any Ruby interpreter + +## Documentation + +[Please see the nio4r wiki](https://github.com/socketry/nio4r/wiki) +for more detailed documentation and usage notes: + + - [Getting Started](https://github.com/socketry/nio4r/wiki/Getting-Started): Introduction to nio4r's components + - [Selectors](https://github.com/socketry/nio4r/wiki/Selectors): monitor multiple `IO` objects for readiness events + - [Monitors](https://github.com/socketry/nio4r/wiki/Monitors): control interests and inspect readiness for specific `IO` objects + - [Byte Buffers](https://github.com/socketry/nio4r/wiki/Byte-Buffers): fixed-size native buffers for high-performance I/O + +See also: + + - [YARD API documentation](http://www.rubydoc.info/gems/nio4r/frames) + +## Non-goals + +**nio4r** is not a full-featured event framework like [EventMachine](https://github.com/eventmachine/eventmachine) or [Cool.io](https://coolio.github.io/). +Instead, nio4r is the sort of thing you might write a library like that on +top of. nio4r provides a minimal API such that individual Ruby implementers +may choose to produce optimized versions for their platform, without having +to maintain a large codebase. + +## Releases + +Bump the version first: + + bundle exec bake gem:release:version:patch + +### CRuby + + rake clean + rake release + +### JRuby + +You might need to delete `Gemfile.lock` before trying to `bundle install`. + + # Ensure you have the correct JDK: + pacman -Syu jdk-openjdk + archlinux-java set java-19-openjdk + + # Ensure you are using jruby: + chruby jruby + bundle update + + # Build the package: + rake clean + rake compile + rake release diff --git a/vendor/bundle/ruby/3.4.0/gems/parallel-1.27.0/MIT-LICENSE.txt b/vendor/bundle/ruby/3.4.0/gems/parallel-1.27.0/MIT-LICENSE.txt new file mode 100644 index 00000000..a8889b2a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parallel-1.27.0/MIT-LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (C) 2013 Michael Grosser + +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 AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/parallel-1.27.0/lib/parallel.rb b/vendor/bundle/ruby/3.4.0/gems/parallel-1.27.0/lib/parallel.rb new file mode 100644 index 00000000..d0c3f373 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parallel-1.27.0/lib/parallel.rb @@ -0,0 +1,708 @@ +# frozen_string_literal: true +require 'rbconfig' +require 'parallel/version' + +module Parallel + Stop = Object.new.freeze + + class DeadWorker < StandardError + end + + class Break < StandardError + attr_reader :value + + def initialize(value = nil) + super() + @value = value + end + end + + class Kill < Break + end + + class UndumpableException < StandardError + attr_reader :backtrace + + def initialize(original) + super("#{original.class}: #{original.message}") + @backtrace = original.backtrace + end + end + + class ExceptionWrapper + attr_reader :exception + + def initialize(exception) + # Remove the bindings stack added by the better_errors gem, + # because it cannot be marshalled + if exception.instance_variable_defined? :@__better_errors_bindings_stack + exception.send :remove_instance_variable, :@__better_errors_bindings_stack + end + + @exception = + begin + Marshal.dump(exception) && exception + rescue StandardError + UndumpableException.new(exception) + end + end + end + + class Worker + attr_reader :pid, :read, :write + attr_accessor :thread + + def initialize(read, write, pid) + @read = read + @write = write + @pid = pid + end + + def stop + close_pipes + wait # if it goes zombie, rather wait here to be able to debug + end + + # might be passed to started_processes and simultaneously closed by another thread + # when running in isolation mode, so we have to check if it is closed before closing + def close_pipes + read.close unless read.closed? + write.close unless write.closed? + end + + def work(data) + begin + Marshal.dump(data, write) + rescue Errno::EPIPE + raise DeadWorker + end + + result = begin + Marshal.load(read) + rescue EOFError + raise DeadWorker + end + raise result.exception if result.is_a?(ExceptionWrapper) + result + end + + private + + def wait + Process.wait(pid) + rescue Interrupt + # process died + end + end + + class JobFactory + def initialize(source, mutex) + @lambda = (source.respond_to?(:call) && source) || queue_wrapper(source) + @source = source.to_a unless @lambda # turn Range and other Enumerable-s into an Array + @mutex = mutex + @index = -1 + @stopped = false + end + + def next + if producer? + # - index and item stay in sync + # - do not call lambda after it has returned Stop + item, index = @mutex.synchronize do + return if @stopped + item = @lambda.call + @stopped = (item == Stop) + return if @stopped + [item, @index += 1] + end + else + index = @mutex.synchronize { @index += 1 } + return if index >= size + item = @source[index] + end + [item, index] + end + + def size + if producer? + Float::INFINITY + else + @source.size + end + end + + # generate item that is sent to workers + # just index is faster + less likely to blow up with unserializable errors + def pack(item, index) + producer? ? [item, index] : index + end + + # unpack item that is sent to workers + def unpack(data) + producer? ? data : [@source[data], data] + end + + private + + def producer? + @lambda + end + + def queue_wrapper(array) + array.respond_to?(:num_waiting) && array.respond_to?(:pop) && -> { array.pop(false) } + end + end + + class UserInterruptHandler + INTERRUPT_SIGNAL = :SIGINT + + class << self + # kill all these pids or threads if user presses Ctrl+c + def kill_on_ctrl_c(pids, options) + @to_be_killed ||= [] + old_interrupt = nil + signal = options.fetch(:interrupt_signal, INTERRUPT_SIGNAL) + + if @to_be_killed.empty? + old_interrupt = trap_interrupt(signal) do + warn 'Parallel execution interrupted, exiting ...' + @to_be_killed.flatten.each { |pid| kill(pid) } + end + end + + @to_be_killed << pids + + yield + ensure + @to_be_killed.pop # do not kill pids that could be used for new processes + restore_interrupt(old_interrupt, signal) if @to_be_killed.empty? + end + + def kill(thing) + Process.kill(:KILL, thing) + rescue Errno::ESRCH + # some linux systems already automatically killed the children at this point + # so we just ignore them not being there + end + + private + + def trap_interrupt(signal) + old = Signal.trap signal, 'IGNORE' + + Signal.trap signal do + yield + if !old || old == "DEFAULT" + raise Interrupt + else + old.call + end + end + + old + end + + def restore_interrupt(old, signal) + Signal.trap signal, old + end + end + end + + class << self + def in_threads(options = { count: 2 }) + threads = [] + count, = extract_count_from_options(options) + + Thread.handle_interrupt(Exception => :never) do + Thread.handle_interrupt(Exception => :immediate) do + count.times do |i| + threads << Thread.new { yield(i) } + end + threads.map(&:value) + end + ensure + threads.each(&:kill) + end + end + + def in_processes(options = {}, &block) + count, options = extract_count_from_options(options) + count ||= processor_count + map(0...count, options.merge(in_processes: count), &block) + end + + def each(array, options = {}, &block) + map(array, options.merge(preserve_results: false), &block) + end + + def any?(*args, &block) + raise "You must provide a block when calling #any?" if block.nil? + !each(*args) { |*a| raise Kill if block.call(*a) } + end + + def all?(*args, &block) + raise "You must provide a block when calling #all?" if block.nil? + !!each(*args) { |*a| raise Kill unless block.call(*a) } + end + + def each_with_index(array, options = {}, &block) + each(array, options.merge(with_index: true), &block) + end + + def map(source, options = {}, &block) + options = options.dup + options[:mutex] = Mutex.new + + if options[:in_processes] && options[:in_threads] + raise ArgumentError, "Please specify only one of `in_processes` or `in_threads`." + elsif RUBY_PLATFORM =~ (/java/) && !options[:in_processes] + method = :in_threads + size = options[method] || processor_count + elsif options[:in_threads] + method = :in_threads + size = options[method] + elsif options[:in_ractors] + method = :in_ractors + size = options[method] + else + method = :in_processes + if Process.respond_to?(:fork) + size = options[method] || processor_count + else + warn "Process.fork is not supported by this Ruby" + size = 0 + end + end + + job_factory = JobFactory.new(source, options[:mutex]) + size = [job_factory.size, size].min + + options[:return_results] = (options[:preserve_results] != false || !!options[:finish]) + add_progress_bar!(job_factory, options) + + result = + if size == 0 + work_direct(job_factory, options, &block) + elsif method == :in_threads + work_in_threads(job_factory, options.merge(count: size), &block) + elsif method == :in_ractors + work_in_ractors(job_factory, options.merge(count: size), &block) + else + work_in_processes(job_factory, options.merge(count: size), &block) + end + + return result.value if result.is_a?(Break) + raise result if result.is_a?(Exception) + options[:return_results] ? result : source + end + + def map_with_index(array, options = {}, &block) + map(array, options.merge(with_index: true), &block) + end + + def flat_map(...) + map(...).flatten(1) + end + + def filter_map(...) + map(...).compact + end + + # Number of physical processor cores on the current system. + def physical_processor_count + @physical_processor_count ||= begin + ppc = + case RbConfig::CONFIG["target_os"] + when /darwin[12]/ + IO.popen("/usr/sbin/sysctl -n hw.physicalcpu").read.to_i + when /linux/ + cores = {} # unique physical ID / core ID combinations + phy = 0 + File.read("/proc/cpuinfo").scan(/^physical id.*|^core id.*/) do |ln| + if ln.start_with?("physical") + phy = ln[/\d+/] + elsif ln.start_with?("core") + cid = "#{phy}:#{ln[/\d+/]}" + cores[cid] = true unless cores[cid] + end + end + cores.count + when /mswin|mingw/ + physical_processor_count_windows + else + processor_count + end + # fall back to logical count if physical info is invalid + ppc > 0 ? ppc : processor_count + end + end + + # Number of processors seen by the OS or value considering CPU quota if the process is inside a cgroup, + # used for process scheduling + def processor_count + @processor_count ||= Integer(ENV['PARALLEL_PROCESSOR_COUNT'] || available_processor_count) + end + + def worker_number + Thread.current[:parallel_worker_number] + end + + # TODO: this does not work when doing threads in forks, so should remove and yield the number instead if needed + def worker_number=(worker_num) + Thread.current[:parallel_worker_number] = worker_num + end + + private + + def physical_processor_count_windows + # Get-CimInstance introduced in PowerShell 3 or earlier: https://learn.microsoft.com/en-us/previous-versions/powershell/module/cimcmdlets/get-ciminstance?view=powershell-3.0 + result = run( + 'powershell -command "Get-CimInstance -ClassName Win32_Processor -Property NumberOfCores ' \ + '| Select-Object -Property NumberOfCores"' + ) + if !result || $?.exitstatus != 0 + # fallback to deprecated wmic for older systems + result = run("wmic cpu get NumberOfCores") + end + if !result || $?.exitstatus != 0 + # Bail out if both commands returned something unexpected + warn "guessing pyhsical processor count" + processor_count + else + # powershell: "\nNumberOfCores\n-------------\n 4\n\n\n" + # wmic: "NumberOfCores \n\n4 \n\n\n\n" + result.scan(/\d+/).map(&:to_i).reduce(:+) + end + end + + def run(command) + IO.popen(command, &:read) + rescue Errno::ENOENT + # Ignore + end + + def add_progress_bar!(job_factory, options) + if (progress_options = options[:progress]) + raise "Progressbar can only be used with array like items" if job_factory.size == Float::INFINITY + require 'ruby-progressbar' + + if progress_options == true + progress_options = { title: "Progress" } + elsif progress_options.respond_to? :to_str + progress_options = { title: progress_options.to_str } + end + + progress_options = { + total: job_factory.size, + format: '%t |%E | %B | %a' + }.merge(progress_options) + + progress = ProgressBar.create(progress_options) + old_finish = options[:finish] + options[:finish] = lambda do |item, i, result| + old_finish.call(item, i, result) if old_finish + progress.increment + end + end + end + + def work_direct(job_factory, options, &block) + self.worker_number = 0 + results = [] + exception = nil + begin + while (set = job_factory.next) + item, index = set + results << with_instrumentation(item, index, options) do + call_with_index(item, index, options, &block) + end + end + rescue StandardError + exception = $! + end + exception || results + ensure + self.worker_number = nil + end + + def work_in_threads(job_factory, options, &block) + raise "interrupt_signal is no longer supported for threads" if options[:interrupt_signal] + results = [] + results_mutex = Mutex.new # arrays are not thread-safe on jRuby + exception = nil + + in_threads(options) do |worker_num| + self.worker_number = worker_num + # as long as there are more jobs, work on one of them + while !exception && (set = job_factory.next) + begin + item, index = set + result = with_instrumentation item, index, options do + call_with_index(item, index, options, &block) + end + results_mutex.synchronize { results[index] = result } + rescue StandardError + exception = $! + end + end + end + + exception || results + end + + def work_in_ractors(job_factory, options) + exception = nil + results = [] + results_mutex = Mutex.new # arrays are not thread-safe on jRuby + + callback = options[:ractor] + if block_given? || !callback + raise ArgumentError, "pass the code you want to execute as `ractor: [ClassName, :method_name]`" + end + + # build + ractors = Array.new(options.fetch(:count)) do + Ractor.new do + loop do + got = receive + (klass, method_name), item, index = got + break if index == :break + begin + Ractor.yield [nil, klass.send(method_name, item), item, index] + rescue StandardError => e + Ractor.yield [e, nil, item, index] + end + end + end + end + + # start + ractors.dup.each do |ractor| + if (set = job_factory.next) + item, index = set + instrument_start item, index, options + ractor.send [callback, item, index] + else + ractor.send([[nil, nil], nil, :break]) # stop the ractor + ractors.delete ractor + end + end + + # replace with new items + while (set = job_factory.next) + item_next, index_next = set + done, (exception, result, item, index) = Ractor.select(*ractors) + if exception + ractors.delete done + break + end + instrument_finish item, index, result, options + results_mutex.synchronize { results[index] = (options[:preserve_results] == false ? nil : result) } + + instrument_start item_next, index_next, options + done.send([callback, item_next, index_next]) + end + + # finish + ractors.each do |ractor| + (new_exception, result, item, index) = ractor.take + exception ||= new_exception + next if new_exception + instrument_finish item, index, result, options + results_mutex.synchronize { results[index] = (options[:preserve_results] == false ? nil : result) } + ractor.send([[nil, nil], nil, :break]) # stop the ractor + end + + exception || results + end + + def work_in_processes(job_factory, options, &blk) + workers = create_workers(job_factory, options, &blk) + results = [] + results_mutex = Mutex.new # arrays are not thread-safe + exception = nil + + UserInterruptHandler.kill_on_ctrl_c(workers.map(&:pid), options) do + in_threads(options) do |i| + worker = workers[i] + worker.thread = Thread.current + worked = false + + begin + loop do + break if exception + item, index = job_factory.next + break unless index + + if options[:isolation] + worker = replace_worker(job_factory, workers, i, options, blk) if worked + worked = true + worker.thread = Thread.current + end + + begin + result = with_instrumentation item, index, options do + worker.work(job_factory.pack(item, index)) + end + results_mutex.synchronize { results[index] = result } # arrays are not threads safe on jRuby + rescue StandardError => e + exception = e + if exception.is_a?(Kill) + (workers - [worker]).each do |w| + w.thread&.kill + UserInterruptHandler.kill(w.pid) + end + end + end + end + ensure + worker.stop + end + end + end + + exception || results + end + + def replace_worker(job_factory, workers, index, options, blk) + options[:mutex].synchronize do + # old worker is no longer used ... stop it + worker = workers[index] + worker.stop + + # create a new replacement worker + running = workers - [worker] + workers[index] = worker(job_factory, options.merge(started_workers: running, worker_number: index), &blk) + end + end + + def create_workers(job_factory, options, &block) + workers = [] + Array.new(options[:count]).each_with_index do |_, i| + workers << worker(job_factory, options.merge(started_workers: workers, worker_number: i), &block) + end + workers + end + + def worker(job_factory, options, &block) + child_read, parent_write = IO.pipe + parent_read, child_write = IO.pipe + + pid = Process.fork do + self.worker_number = options[:worker_number] + + begin + options.delete(:started_workers).each(&:close_pipes) + + parent_write.close + parent_read.close + + process_incoming_jobs(child_read, child_write, job_factory, options, &block) + ensure + child_read.close + child_write.close + end + end + + child_read.close + child_write.close + + Worker.new(parent_read, parent_write, pid) + end + + def process_incoming_jobs(read, write, job_factory, options, &block) + until read.eof? + data = Marshal.load(read) + item, index = job_factory.unpack(data) + + result = + begin + call_with_index(item, index, options, &block) + # https://github.com/rspec/rspec-support/blob/673133cdd13b17077b3d88ece8d7380821f8d7dc/lib/rspec/support.rb#L132-L140 + rescue NoMemoryError, SignalException, Interrupt, SystemExit # rubocop:disable Lint/ShadowedException + raise $! + rescue Exception # # rubocop:disable Lint/RescueException + ExceptionWrapper.new($!) + end + + begin + Marshal.dump(result, write) + rescue Errno::EPIPE + return # parent thread already dead + end + end + end + + # options is either a Integer or a Hash with :count + def extract_count_from_options(options) + if options.is_a?(Hash) + count = options[:count] + else + count = options + options = {} + end + [count, options] + end + + def call_with_index(item, index, options, &block) + args = [item] + args << index if options[:with_index] + results = block.call(*args) + if options[:return_results] + results + else + nil # avoid GC overhead of passing large results around + end + end + + def with_instrumentation(item, index, options) + instrument_start(item, index, options) + result = yield + instrument_finish(item, index, result, options) + result unless options[:preserve_results] == false + end + + def instrument_finish(item, index, result, options) + return unless (on_finish = options[:finish]) + return instrument_finish_in_order(item, index, result, options) if options[:finish_in_order] + options[:mutex].synchronize { on_finish.call(item, index, result) } + end + + # yield results in the order of the input items + # needs to use `options` to store state between executions + # needs to use `done` index since a nil result would also be valid + def instrument_finish_in_order(item, index, result, options) + options[:mutex].synchronize do + # initialize our state + options[:finish_done] ||= [] + options[:finish_expecting] ||= 0 # we wait for item at index 0 + + # store current result + options[:finish_done][index] = [item, result] + + # yield all results that are now in order + break unless index == options[:finish_expecting] + index.upto(options[:finish_done].size).each do |i| + break unless (done = options[:finish_done][i]) + options[:finish_done][i] = nil # allow GC to free this item and result + options[:finish].call(done[0], i, done[1]) + options[:finish_expecting] += 1 + end + end + end + + def instrument_start(item, index, options) + return unless (on_start = options[:start]) + options[:mutex].synchronize { on_start.call(item, index) } + end + + def available_processor_count + gem 'concurrent-ruby', '>= 1.3.4' + require 'concurrent-ruby' + Concurrent.available_processor_count.floor + rescue LoadError + require 'etc' + Etc.nprocessors + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parallel-1.27.0/lib/parallel/version.rb b/vendor/bundle/ruby/3.4.0/gems/parallel-1.27.0/lib/parallel/version.rb new file mode 100644 index 00000000..4397fbbb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parallel-1.27.0/lib/parallel/version.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true +module Parallel + VERSION = Version = '1.27.0' # rubocop:disable Naming/ConstantName +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/LICENSE.txt b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/LICENSE.txt new file mode 100644 index 00000000..43f97889 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/LICENSE.txt @@ -0,0 +1,26 @@ +Copyright (c) 2013-2024 parser project contributors +Copyright (c) 2013-2016 Catherine + +Parts of the source are derived from ruby_parser: +Copyright (c) Ryan Davis, seattle.rb + +MIT License + +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 AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/bin/ruby-parse b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/bin/ruby-parse new file mode 100755 index 00000000..e5d30f84 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/bin/ruby-parse @@ -0,0 +1,7 @@ +#! /usr/bin/env ruby +# frozen_string_literal: true + +$LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__)) +require 'parser/runner/ruby_parse' + +Parser::Runner::RubyParse.go(ARGV) diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/bin/ruby-rewrite b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/bin/ruby-rewrite new file mode 100755 index 00000000..10f7d631 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/bin/ruby-rewrite @@ -0,0 +1,7 @@ +#! /usr/bin/env ruby +# frozen_string_literal: true + +$LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__)) +require 'parser/runner/ruby_rewrite' + +Parser::Runner::RubyRewrite.go(ARGV) diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/gauntlet_parser.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/gauntlet_parser.rb new file mode 100644 index 00000000..371b7e40 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/gauntlet_parser.rb @@ -0,0 +1,123 @@ +# frozen_string_literal: true + +require 'gauntlet' +require_relative 'parser/all' +require 'shellwords' + +class ParserGauntlet < Gauntlet + RUBY20 = 'ruby' + RUBY19 = 'ruby1.9.1' + RUBY18 = '/opt/rubies/ruby-1.8.7-p370/bin/ruby' + + def try(parser, ruby, file, show_ok: false) + try_ruby = lambda do |e| + Process.spawn(%{#{ruby} -c #{Shellwords.escape file}}, + :err => '/dev/null', :out => '/dev/null') + _, status = Process.wait2 + + if status.success? + # Bug in Parser. + puts "Parser bug." + @result[file] = { parser.to_s => "#{e.class}: #{e.to_s}" } + else + # No, this file is not Ruby. + yield if block_given? + end + end + + begin + parser.parse_file(file) + + rescue Parser::SyntaxError => e + if e.diagnostic.location.resize(2).is?('<%') + puts "ERb." + return + end + + try_ruby.call(e) + + rescue ArgumentError, RegexpError, + Encoding::UndefinedConversionError => e + puts "#{file}: #{e.class}: #{e.to_s}" + + try_ruby.call(e) + + rescue Interrupt + raise + + rescue Exception => e + puts "Parser bug: #{file} #{e.class}: #{e.to_s}" + @result[file] = { parser.to_s => "#{e.class}: #{e.to_s}" } + + else + puts "Ok." if show_ok + end + end + + def parse(name) + puts "GEM: #{name}" + + @result = {} + + if ENV.include?('FAST') + total_size = Dir["**/*.rb"].map(&File.method(:size)).reduce(:+) + if total_size > 300_000 + puts "Skip." + return + end + end + + Dir["**/*.rb"].each do |file| + next if File.directory? file + + try(Parser::Ruby20, RUBY20, file) do + puts "Trying 1.9:" + try(Parser::Ruby19, RUBY19, file, show_ok: true) do + puts "Trying 1.8:" + try(Parser::Ruby18, RUBY18, file, show_ok: true) do + puts "Invalid syntax." + end + end + end + end + + @result + end + + def run(name) + data[name] = parse(name) + self.dirty = true + end + + def should_skip?(name) + data[name] == {} + end + + def load_yaml(*) + data = super + @was_errors = data.count { |_name, errs| errs != {} } + + data + end + + def shutdown + super + + errors = data.count { |_name, errs| errs != {} } + total = data.count + percent = "%.5f" % [100 - errors.to_f / total * 100] + puts "!!! was: #{@was_errors} now: #{errors} total: #{total} frac: #{percent}%" + end +end + +filter = ARGV.shift +filter = Regexp.new filter if filter + +gauntlet = ParserGauntlet.new + +if ENV.include? 'UPDATE' + gauntlet.source_index + gauntlet.update_gem_tarballs +end + +gauntlet.run_the_gauntlet filter diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser.rb new file mode 100644 index 00000000..d8969e25 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser.rb @@ -0,0 +1,91 @@ +# frozen_string_literal: true + +if RUBY_VERSION =~ /^1\.[89]\./ + require_relative 'parser/version' + raise LoadError, <<-UNSUPPORTED_VERSION_MSG +parser v#{Parser::VERSION} cannot run on Ruby #{RUBY_VERSION}. +Please upgrade to Ruby 2.0.0 or higher, or use an older version of the parser gem. + UNSUPPORTED_VERSION_MSG +end + +require 'set' +require 'racc/parser' + +require 'ast' + +## +# @api public +# +module Parser + require_relative 'parser/version' + require_relative 'parser/messages' + require_relative 'parser/deprecation' + + module AST + require_relative 'parser/ast/node' + require_relative 'parser/ast/processor' + require_relative 'parser/meta' + end + + module Source + require_relative 'parser/source/buffer' + require_relative 'parser/source/range' + + require_relative 'parser/source/comment' + require_relative 'parser/source/comment/associator' + + require_relative 'parser/source/rewriter' + require_relative 'parser/source/rewriter/action' + require_relative 'parser/source/tree_rewriter' + require_relative 'parser/source/tree_rewriter/action' + + require_relative 'parser/source/map' + require_relative 'parser/source/map/operator' + require_relative 'parser/source/map/collection' + require_relative 'parser/source/map/constant' + require_relative 'parser/source/map/variable' + require_relative 'parser/source/map/keyword' + require_relative 'parser/source/map/definition' + require_relative 'parser/source/map/method_definition' + require_relative 'parser/source/map/send' + require_relative 'parser/source/map/index' + require_relative 'parser/source/map/condition' + require_relative 'parser/source/map/ternary' + require_relative 'parser/source/map/for' + require_relative 'parser/source/map/rescue_body' + require_relative 'parser/source/map/heredoc' + require_relative 'parser/source/map/objc_kwarg' + end + + require_relative 'parser/syntax_error' + require_relative 'parser/clobbering_error' + require_relative 'parser/unknown_encoding_in_magic_comment_error' + require_relative 'parser/diagnostic' + require_relative 'parser/diagnostic/engine' + + require_relative 'parser/static_environment' + + if RUBY_ENGINE == 'truffleruby' + require_relative 'parser/lexer-F0' + else + require_relative 'parser/lexer-F1' + end + require_relative 'parser/lexer-strings' + require_relative 'parser/lexer/literal' + require_relative 'parser/lexer/stack_state' + require_relative 'parser/lexer/dedenter' + + module Builders + require_relative 'parser/builders/default' + end + + require_relative 'parser/context' + require_relative 'parser/max_numparam_stack' + require_relative 'parser/current_arg_stack' + require_relative 'parser/variables_stack' + + require_relative 'parser/base' + + require_relative 'parser/rewriter' + require_relative 'parser/tree_rewriter' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/all.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/all.rb new file mode 100644 index 00000000..81334308 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/all.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require_relative 'ruby18' +require_relative 'ruby19' +require_relative 'ruby20' +require_relative 'ruby21' +require_relative 'ruby22' +require_relative 'ruby23' +require_relative 'ruby24' +require_relative 'ruby25' +require_relative 'ruby26' +require_relative 'ruby27' +require_relative 'ruby30' +require_relative 'ruby31' +require_relative 'ruby32' +require_relative 'ruby33' +require_relative 'ruby34' diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ast/node.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ast/node.rb new file mode 100644 index 00000000..bee8e29a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ast/node.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +module Parser + module AST + + ## + # {Parser::AST::Node} contains information about a single AST node and its + # child nodes. It extends the basic [AST::Node](https://www.rubydoc.info/gems/ast/AST/Node) + # class provided by gem [ast](https://www.rubydoc.info/gems/ast). + # + # @api public + # + # @!attribute [r] location + # Source map for this Node. + # @return [Parser::Source::Map] + # + class Node < ::AST::Node + attr_reader :location + + alias loc location + + ## + # Assigns various properties to this AST node. Currently only the + # location can be set. + # + # @param [Hash] properties + # @option properties [Parser::Source::Map] :location Location information + # of the node. + # + def assign_properties(properties) + if (location = properties[:location]) + location = location.dup if location.frozen? + location.node = self + @location = location + end + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ast/processor.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ast/processor.rb new file mode 100644 index 00000000..9636c43e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ast/processor.rb @@ -0,0 +1,293 @@ +# frozen_string_literal: true + +module Parser + module AST + + ## + # @api public + # + class Processor + include ::AST::Processor::Mixin + + def process_regular_node(node) + node.updated(nil, process_all(node)) + end + + alias on_dstr process_regular_node + alias on_dsym process_regular_node + alias on_regexp process_regular_node + alias on_xstr process_regular_node + alias on_splat process_regular_node + alias on_kwsplat process_regular_node + alias on_array process_regular_node + alias on_pair process_regular_node + alias on_hash process_regular_node + alias on_kwargs process_regular_node + alias on_irange process_regular_node + alias on_erange process_regular_node + + def on_var(node) + node + end + + # @private + def process_variable_node(node) + on_var(node) + end + + alias on_lvar process_variable_node + alias on_ivar process_variable_node + alias on_gvar process_variable_node + alias on_cvar process_variable_node + alias on_back_ref process_variable_node + alias on_nth_ref process_variable_node + + def on_vasgn(node) + name, value_node = *node + + if !value_node.nil? + node.updated(nil, [ + name, process(value_node) + ]) + else + node + end + end + + # @private + def process_var_asgn_node(node) + on_vasgn(node) + end + + alias on_lvasgn process_var_asgn_node + alias on_ivasgn process_var_asgn_node + alias on_gvasgn process_var_asgn_node + alias on_cvasgn process_var_asgn_node + + alias on_and_asgn process_regular_node + alias on_or_asgn process_regular_node + + def on_op_asgn(node) + var_node, method_name, value_node = *node + + node.updated(nil, [ + process(var_node), method_name, process(value_node) + ]) + end + + alias on_mlhs process_regular_node + alias on_masgn process_regular_node + + def on_const(node) + scope_node, name = *node + + node.updated(nil, [ + process(scope_node), name + ]) + end + + def on_casgn(node) + scope_node, name, value_node = *node + + if !value_node.nil? + node.updated(nil, [ + process(scope_node), name, process(value_node) + ]) + else + node.updated(nil, [ + process(scope_node), name + ]) + end + end + + alias on_args process_regular_node + + def on_argument(node) + arg_name, value_node = *node + + if !value_node.nil? + node.updated(nil, [ + arg_name, process(value_node) + ]) + else + node + end + end + + # @private + def process_argument_node(node) + on_argument(node) + end + + alias on_arg process_argument_node + alias on_optarg process_argument_node + alias on_restarg process_argument_node + alias on_blockarg process_argument_node + alias on_shadowarg process_argument_node + alias on_kwarg process_argument_node + alias on_kwoptarg process_argument_node + alias on_kwrestarg process_argument_node + alias on_forward_arg process_argument_node + + def on_procarg0(node) + if node.children[0].is_a?(Symbol) + # This branch gets executed when the builder + # is not configured to emit and 'arg' inside 'procarg0', i.e. when + # Parser::Builders::Default.emit_arg_inside_procarg0 + # is set to false. + # + # If this flag is set to true this branch is unreachable. + # s(:procarg0, :a) + on_argument(node) + else + # s(:procarg0, s(:arg, :a), s(:arg, :b)) + process_regular_node(node) + end + end + + alias on_arg_expr process_regular_node + alias on_restarg_expr process_regular_node + alias on_blockarg_expr process_regular_node + alias on_block_pass process_regular_node + + alias on_forwarded_restarg process_regular_node + alias on_forwarded_kwrestarg process_regular_node + + alias on_module process_regular_node + alias on_class process_regular_node + alias on_sclass process_regular_node + + def on_def(node) + name, args_node, body_node = *node + + node.updated(nil, [ + name, + process(args_node), process(body_node) + ]) + end + + def on_defs(node) + definee_node, name, args_node, body_node = *node + + node.updated(nil, [ + process(definee_node), name, + process(args_node), process(body_node) + ]) + end + + alias on_undef process_regular_node + alias on_alias process_regular_node + + def on_send(node) + receiver_node, method_name, *arg_nodes = *node + + receiver_node = process(receiver_node) if receiver_node + node.updated(nil, [ + receiver_node, method_name, *process_all(arg_nodes) + ]) + end + + alias on_csend on_send + + alias on_index process_regular_node + alias on_indexasgn process_regular_node + + alias on_block process_regular_node + alias on_lambda process_regular_node + + def on_numblock(node) + method_call, max_numparam, body = *node + + node.updated(nil, [ + process(method_call), max_numparam, process(body) + ]) + end + + alias on_while process_regular_node + alias on_while_post process_regular_node + alias on_until process_regular_node + alias on_until_post process_regular_node + alias on_for process_regular_node + + alias on_return process_regular_node + alias on_break process_regular_node + alias on_next process_regular_node + alias on_redo process_regular_node + alias on_retry process_regular_node + alias on_super process_regular_node + alias on_yield process_regular_node + alias on_defined? process_regular_node + + alias on_not process_regular_node + alias on_and process_regular_node + alias on_or process_regular_node + + alias on_if process_regular_node + + alias on_when process_regular_node + alias on_case process_regular_node + + alias on_iflipflop process_regular_node + alias on_eflipflop process_regular_node + + alias on_match_current_line process_regular_node + alias on_match_with_lvasgn process_regular_node + + alias on_resbody process_regular_node + alias on_rescue process_regular_node + alias on_ensure process_regular_node + + alias on_begin process_regular_node + alias on_kwbegin process_regular_node + + alias on_preexe process_regular_node + alias on_postexe process_regular_node + + alias on_case_match process_regular_node + alias on_in_match process_regular_node + alias on_match_pattern process_regular_node + alias on_match_pattern_p process_regular_node + alias on_in_pattern process_regular_node + alias on_if_guard process_regular_node + alias on_unless_guard process_regular_node + alias on_match_var process_variable_node + alias on_match_rest process_regular_node + alias on_pin process_regular_node + alias on_match_alt process_regular_node + alias on_match_as process_regular_node + alias on_array_pattern process_regular_node + alias on_array_pattern_with_tail process_regular_node + alias on_hash_pattern process_regular_node + alias on_const_pattern process_regular_node + alias on_find_pattern process_regular_node + + # @private + def process_variable_node(node) + warn 'Parser::AST::Processor#process_variable_node is deprecated as a' \ + ' public API and will be removed. Please use ' \ + 'Parser::AST::Processor#on_var instead.' + on_var(node) + end + + # @private + def process_var_asgn_node(node) + warn 'Parser::AST::Processor#process_var_asgn_node is deprecated as a' \ + ' public API and will be removed. Please use ' \ + 'Parser::AST::Processor#on_vasgn instead.' + on_vasgn(node) + end + + # @private + def process_argument_node(node) + warn 'Parser::AST::Processor#process_argument_node is deprecated as a' \ + ' public API and will be removed. Please use ' \ + 'Parser::AST::Processor#on_argument instead.' + on_argument(node) + end + + def on_empty_else(node) + node + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/base.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/base.rb new file mode 100644 index 00000000..6698edb9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/base.rb @@ -0,0 +1,294 @@ +# frozen_string_literal: true + +module Parser + + ## + # Base class for version-specific parsers. + # + # @api public + # + # @!attribute [r] diagnostics + # @return [Parser::Diagnostic::Engine] + # + # @!attribute [r] static_env + # @return [Parser::StaticEnvironment] + # + # @!attribute [r] version + # @return [Integer] + # + class Base < Racc::Parser + ## + # Parses a string of Ruby code and returns the AST. If the source + # cannot be parsed, {SyntaxError} is raised and a diagnostic is + # printed to `stderr`. + # + # @example + # Parser::Base.parse('puts "hello"') + # + # @param [String] string The block of code to parse. + # @param [String] file The name of the file the code originated from. + # @param [Numeric] line The initial line number. + # @return [Parser::AST::Node] + # + def self.parse(string, file='(string)', line=1) + parser = default_parser + source_buffer = setup_source_buffer(file, line, string, parser.default_encoding) + parser.parse(source_buffer) + end + + ## + # Parses a string of Ruby code and returns the AST and comments. If the + # source cannot be parsed, {SyntaxError} is raised and a diagnostic is + # printed to `stderr`. + # + # @example + # Parser::Base.parse_with_comments('puts "hello"') + # + # @param [String] string The block of code to parse. + # @param [String] file The name of the file the code originated from. + # @param [Numeric] line The initial line number. + # @return [Array] + # + def self.parse_with_comments(string, file='(string)', line=1) + parser = default_parser + source_buffer = setup_source_buffer(file, line, string, parser.default_encoding) + parser.parse_with_comments(source_buffer) + end + + ## + # Parses Ruby source code by reading it from a file. If the source + # cannot be parsed, {SyntaxError} is raised and a diagnostic is + # printed to `stderr`. + # + # @param [String] filename Path to the file to parse. + # @return [Parser::AST::Node] + # @see #parse + # + def self.parse_file(filename) + parse(File.read(filename), filename) + end + + ## + # Parses Ruby source code by reading it from a file and returns the AST and + # comments. If the source cannot be parsed, {SyntaxError} is raised and a + # diagnostic is printed to `stderr`. + # + # @param [String] filename Path to the file to parse. + # @return [Array] + # @see #parse + # + def self.parse_file_with_comments(filename) + parse_with_comments(File.read(filename), filename) + end + + ## + # @return [Parser::Base] parser with the default options set. + # + def self.default_parser + parser = new + + parser.diagnostics.all_errors_are_fatal = true + parser.diagnostics.ignore_warnings = true + + parser.diagnostics.consumer = lambda do |diagnostic| + $stderr.puts(diagnostic.render) + end + + parser + end + + def self.setup_source_buffer(file, line, string, encoding) + string = string.dup.force_encoding(encoding) + + source_buffer = Source::Buffer.new(file, line) + + if name == 'Parser::Ruby18' + source_buffer.raw_source = string + else + source_buffer.source = string + end + + source_buffer + end + private_class_method :setup_source_buffer + + attr_reader :lexer + attr_reader :diagnostics + attr_reader :builder + attr_reader :static_env + attr_reader :source_buffer + attr_reader :context + attr_reader :max_numparam_stack + attr_reader :current_arg_stack + attr_reader :pattern_variables + attr_reader :pattern_hash_keys + + ## + # @param [Parser::Builders::Default] builder The AST builder to use. + # + def initialize(builder=Parser::Builders::Default.new) + @diagnostics = Diagnostic::Engine.new + + @static_env = StaticEnvironment.new + + # Stack that holds current parsing context + @context = Context.new + + # Maximum numbered parameters stack + @max_numparam_stack = MaxNumparamStack.new + + # Current argument names stack + @current_arg_stack = CurrentArgStack.new + + # Stack of set of variables used in the current pattern + @pattern_variables = VariablesStack.new + + # Stack of set of keys used in the current hash in pattern matchinig + @pattern_hash_keys = VariablesStack.new + + @lexer = Lexer.new(version) + @lexer.diagnostics = @diagnostics + @lexer.static_env = @static_env + @lexer.context = @context + + @builder = builder + @builder.parser = self + + # Last emitted token + @last_token = nil + + if self.class::Racc_debug_parser && ENV['RACC_DEBUG'] + @yydebug = true + end + + reset + end + + ## + # Resets the state of the parser. + # + def reset + @source_buffer = nil + + @lexer.reset + @static_env.reset + @context.reset + @current_arg_stack.reset + @pattern_variables.reset + @pattern_hash_keys.reset + + self + end + + ## + # Parses a source buffer and returns the AST, or `nil` in case of a non fatal error. + # + # @param [Parser::Source::Buffer] source_buffer The source buffer to parse. + # @return [Parser::AST::Node, nil] + # + def parse(source_buffer) + @lexer.source_buffer = source_buffer + @source_buffer = source_buffer + + do_parse || nil # Force `false` to `nil`, see https://github.com/ruby/racc/pull/136 + ensure + # Don't keep references to the source file. + @source_buffer = nil + @lexer.source_buffer = nil + end + + ## + # Parses a source buffer and returns the AST and the source code comments. + # + # @see #parse + # @see Parser::Source::Comment#associate + # @return [Array] + # + def parse_with_comments(source_buffer) + @lexer.comments = [] + + [ parse(source_buffer), @lexer.comments ] + ensure + @lexer.comments = nil + end + + ## + # Parses a source buffer and returns the AST, the source code comments, + # and the tokens emitted by the lexer. In case of a fatal error, a {SyntaxError} + # is raised, unless `recover` is true. In case of an error + # (non-fatal or recovered), `nil` is returned instead of the AST, and + # comments as well as tokens are only returned up to the location of + # the error. + # + # Currently, token stream format returned by #tokenize is not documented, + # but is considered part of a public API and only changed according + # to Semantic Versioning. + # + # However, note that the exact token composition of various constructs + # might vary. For example, a string `"foo"` is represented equally well + # by `:tSTRING_BEG " :tSTRING_CONTENT foo :tSTRING_END "` and + # `:tSTRING "foo"`; such details must not be relied upon. + # + # @param [Parser::Source::Buffer] source_buffer + # @param [Boolean] recover If true, recover from syntax errors. False by default. + # @return [Array] + # + def tokenize(source_buffer, recover=false) + @lexer.tokens = [] + @lexer.comments = [] + + begin + ast = parse(source_buffer) + rescue Parser::SyntaxError + raise if !recover + end + + [ ast, @lexer.comments, @lexer.tokens ] + ensure + @lexer.tokens = nil + @lexer.comments = nil + end + + private + + def next_token + token = @lexer.advance + @last_token = token + token + end + + def check_kwarg_name(name_t) + case name_t[0] + when /^[a-z_]/ + # OK + when /^[A-Z]/ + diagnostic :error, :argument_const, nil, name_t + end + end + + def diagnostic(level, reason, arguments, location_t, highlights_ts=[]) + _, location = location_t + + highlights = highlights_ts.map do |token| + _, range = token + range + end + + @diagnostics.process( + Diagnostic.new(level, reason, arguments, location, highlights)) + + if level == :error + yyerror + end + end + + def on_error(error_token_id, error_value, value_stack) + token_name = token_to_str(error_token_id) + _, location = error_value + + @diagnostics.process(Diagnostic.new( + :error, :unexpected_token, { :token => token_name }, location)) + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/builders/default.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/builders/default.rb new file mode 100644 index 00000000..26097653 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/builders/default.rb @@ -0,0 +1,2351 @@ +# frozen_string_literal: true + +module Parser + + ## + # Default AST builder. Uses {AST::Node}s. + # + class Builders::Default + class << self + ## + # AST compatibility attribute; since `-> {}` is not semantically + # equivalent to `lambda {}`, all new code should set this attribute + # to true. + # + # If set to false (the default), `-> {}` is emitted as + # `s(:block, s(:send, nil, :lambda), s(:args), nil)`. + # + # If set to true, `-> {}` is emitted as + # `s(:block, s(:lambda), s(:args), nil)`. + # + # @return [Boolean] + attr_accessor :emit_lambda + end + + @emit_lambda = false + + class << self + ## + # AST compatibility attribute; block arguments of `m { |a| }` are + # not semantically equivalent to block arguments of `m { |a,| }` or `m { |a, b| }`, + # all new code should set this attribute to true. + # + # If set to false (the default), arguments of `m { |a| }` are emitted as + # `s(:args, s(:arg, :a))`. + # + # If set to true, arguments of `m { |a| }` are emitted as + # `s(:args, s(:procarg0, :a)). + # + # @return [Boolean] + attr_accessor :emit_procarg0 + end + + @emit_procarg0 = false + + class << self + ## + # AST compatibility attribute; locations of `__ENCODING__` are not the same + # as locations of `Encoding::UTF_8` causing problems during rewriting, + # all new code should set this attribute to true. + # + # If set to false (the default), `__ENCODING__` is emitted as + # ` s(:const, s(:const, nil, :Encoding), :UTF_8)`. + # + # If set to true, `__ENCODING__` is emitted as + # `s(:__ENCODING__)`. + # + # @return [Boolean] + attr_accessor :emit_encoding + end + + @emit_encoding = false + + class << self + ## + # AST compatibility attribute; indexed assignment, `x[] = 1`, is not + # semantically equivalent to calling the method directly, `x.[]=(1)`. + # Specifically, in the former case, the expression's value is always 1, + # and in the latter case, the expression's value is the return value + # of the `[]=` method. + # + # If set to false (the default), `self[1]` is emitted as + # `s(:send, s(:self), :[], s(:int, 1))`, and `self[1] = 2` is + # emitted as `s(:send, s(:self), :[]=, s(:int, 1), s(:int, 2))`. + # + # If set to true, `self[1]` is emitted as + # `s(:index, s(:self), s(:int, 1))`, and `self[1] = 2` is + # emitted as `s(:indexasgn, s(:self), s(:int, 1), s(:int, 2))`. + # + # @return [Boolean] + attr_accessor :emit_index + end + + @emit_index = false + + class << self + ## + # AST compatibility attribute; causes a single non-mlhs + # block argument to be wrapped in s(:procarg0). + # + # If set to false (the default), block arguments `|a|` are emitted as + # `s(:args, s(:procarg0, :a))` + # + # If set to true, block arguments `|a|` are emitted as + # `s(:args, s(:procarg0, s(:arg, :a))` + # + # @return [Boolean] + attr_accessor :emit_arg_inside_procarg0 + end + + @emit_arg_inside_procarg0 = false + + class << self + ## + # AST compatibility attribute; arguments forwarding initially + # didn't have support for leading arguments + # (i.e. `def m(a, ...); end` was a syntax error). However, Ruby 3.0 + # added support for any number of arguments in front of the `...`. + # + # If set to false (the default): + # 1. `def m(...) end` is emitted as + # s(:def, :m, s(:forward_args), nil) + # 2. `def m(a, b, ...) end` is emitted as + # s(:def, :m, + # s(:args, s(:arg, :a), s(:arg, :b), s(:forward_arg))) + # + # If set to true it uses a single format: + # 1. `def m(...) end` is emitted as + # s(:def, :m, s(:args, s(:forward_arg))) + # 2. `def m(a, b, ...) end` is emitted as + # s(:def, :m, s(:args, s(:arg, :a), s(:arg, :b), s(:forward_arg))) + # + # It does't matter that much on 2.7 (because there can't be any leading arguments), + # but on 3.0 it should be better enabled to use a single AST format. + # + # @return [Boolean] + attr_accessor :emit_forward_arg + end + + @emit_forward_arg = false + + class << self + ## + # AST compatibility attribute; Starting from Ruby 2.7 keyword arguments + # of method calls that are passed explicitly as a hash (i.e. with curly braces) + # are treated as positional arguments and Ruby 2.7 emits a warning on such method + # call. Ruby 3.0 given an ArgumentError. + # + # If set to false (the default) the last hash argument is emitted as `hash`: + # + # ``` + # (send nil :foo + # (hash + # (pair + # (sym :bar) + # (int 42)))) + # ``` + # + # If set to true it is emitted as `kwargs`: + # + # ``` + # (send nil :foo + # (kwargs + # (pair + # (sym :bar) + # (int 42)))) + # ``` + # + # Note that `kwargs` node is just a replacement for `hash` argument, + # so if there's are multiple arguments (or a `kwsplat`) all of them + # are wrapped into `kwargs` instead of `hash`: + # + # ``` + # (send nil :foo + # (kwargs + # (pair + # (sym :a) + # (int 42)) + # (kwsplat + # (send nil :b)) + # (pair + # (sym :c) + # (int 10)))) + # ``` + attr_accessor :emit_kwargs + end + + @emit_kwargs = false + + class << self + ## + # AST compatibility attribute; Starting from 3.0 Ruby returns + # true/false from single-line pattern matching with `in` keyword. + # + # Before 3.0 there was an exception if given value doesn't match pattern. + # + # NOTE: This attribute affects only Ruby 2.7 grammar. + # 3.0 grammar always emits `match_pattern`/`match_pattern_p` + # + # If compatibility attribute set to false `foo in bar` is emitted as `in_match`: + # + # ``` + # (in-match + # (send nil :foo) + # (match-var :bar)) + # ``` + # + # If set to true it's emitted as `match_pattern_p`: + # ``` + # (match-pattern-p + # (send nil :foo) + # (match-var :bar)) + # ``` + attr_accessor :emit_match_pattern + end + + @emit_match_pattern = false + + class << self + ## + # @api private + def modernize + @emit_lambda = true + @emit_procarg0 = true + @emit_encoding = true + @emit_index = true + @emit_arg_inside_procarg0 = true + @emit_forward_arg = true + @emit_kwargs = true + @emit_match_pattern = true + end + end + + ## + # @api private + attr_accessor :parser + + ## + # If set to true (the default), `__FILE__` and `__LINE__` are transformed to + # literal nodes. For example, `s(:str, "lib/foo.rb")` and `s(:int, 10)`. + # + # If set to false, `__FILE__` and `__LINE__` are emitted as-is, + # i.e. as `s(:__FILE__)` and `s(:__LINE__)` nodes. + # + # Source maps are identical in both cases. + # + # @return [Boolean] + attr_accessor :emit_file_line_as_literals + + ## + # Initializes attributes: + # + # * `emit_file_line_as_literals`: `true` + def initialize + @emit_file_line_as_literals = true + end + + # @!parse private + + # + # Literals + # + + # Singletons + + def nil(nil_t) + n0(:nil, + token_map(nil_t)) + end + + def true(true_t) + n0(:true, + token_map(true_t)) + end + + def false(false_t) + n0(:false, + token_map(false_t)) + end + + # Numerics + + def integer(integer_t) + numeric(:int, integer_t) + end + + def float(float_t) + numeric(:float, float_t) + end + + def rational(rational_t) + numeric(:rational, rational_t) + end + + def complex(complex_t) + numeric(:complex, complex_t) + end + + def numeric(kind, token) + n(kind, [ value(token) ], + Source::Map::Operator.new(nil, loc(token))) + end + private :numeric + + def unary_num(unary_t, numeric) + value, = *numeric + operator_loc = loc(unary_t) + + case value(unary_t) + when '+' + value = +value + when '-' + value = -value + end + + numeric.updated(nil, [ value ], + :location => + Source::Map::Operator.new( + operator_loc, + operator_loc.join(numeric.loc.expression))) + end + + def __LINE__(__LINE__t) + n0(:__LINE__, + token_map(__LINE__t)) + end + + # Strings + + def string(string_t) + n(:str, [ string_value(string_t) ], + delimited_string_map(string_t)) + end + + def string_internal(string_t) + n(:str, [ string_value(string_t) ], + unquoted_map(string_t)) + end + + def string_compose(begin_t, parts, end_t) + if collapse_string_parts?(parts) + if begin_t.nil? && end_t.nil? + parts.first + else + n(:str, parts.first.children, + string_map(begin_t, parts, end_t)) + end + else + n(:dstr, [ *parts ], + string_map(begin_t, parts, end_t)) + end + end + + def character(char_t) + n(:str, [ string_value(char_t) ], + prefix_string_map(char_t)) + end + + def __FILE__(__FILE__t) + n0(:__FILE__, + token_map(__FILE__t)) + end + + # Symbols + + def symbol(symbol_t) + n(:sym, [ string_value(symbol_t).to_sym ], + prefix_string_map(symbol_t)) + end + + def symbol_internal(symbol_t) + n(:sym, [ string_value(symbol_t).to_sym ], + unquoted_map(symbol_t)) + end + + def symbol_compose(begin_t, parts, end_t) + if collapse_string_parts?(parts) + str = parts.first + + n(:sym, [ str.children.first.to_sym ], + collection_map(begin_t, str.loc.expression, end_t)) + elsif @parser.version == 18 && parts.empty? + diagnostic :error, :empty_symbol, nil, loc(begin_t).join(loc(end_t)) + else + n(:dsym, [ *parts ], + collection_map(begin_t, parts, end_t)) + end + end + + # Executable strings + + def xstring_compose(begin_t, parts, end_t) + n(:xstr, [ *parts ], + string_map(begin_t, parts, end_t)) + end + + # Indented (interpolated, noninterpolated, executable) strings + + def dedent_string(node, dedent_level) + if !dedent_level.nil? + dedenter = Lexer::Dedenter.new(dedent_level) + + case node.type + when :str + str = node.children.first + dedenter.dedent(str) + when :dstr, :xstr + children = node.children.map do |str_node| + if str_node.type == :str + str = str_node.children.first + dedenter.dedent(str) + next nil if str.empty? + else + dedenter.interrupt + end + str_node + end + + node = node.updated(nil, children.compact) + end + end + + node + end + + # Regular expressions + + def regexp_options(regopt_t) + options = value(regopt_t). + each_char.sort.uniq. + map(&:to_sym) + + n(:regopt, options, + token_map(regopt_t)) + end + + def regexp_compose(begin_t, parts, end_t, options) + begin + static_regexp(parts, options) + rescue RegexpError, Encoding::UndefinedConversionError => e + diagnostic :error, :invalid_regexp, { :message => e.message }, + loc(begin_t).join(loc(end_t)) + end + + n(:regexp, (parts << options), + regexp_map(begin_t, end_t, options)) + end + + # Arrays + + def array(begin_t, elements, end_t) + n(:array, elements, + collection_map(begin_t, elements, end_t)) + end + + def splat(star_t, arg=nil) + if arg.nil? + n0(:splat, + unary_op_map(star_t)) + else + n(:splat, [ arg ], + unary_op_map(star_t, arg)) + end + end + + def word(parts) + if collapse_string_parts?(parts) + parts.first + else + n(:dstr, [ *parts ], + collection_map(nil, parts, nil)) + end + end + + def words_compose(begin_t, parts, end_t) + n(:array, [ *parts ], + collection_map(begin_t, parts, end_t)) + end + + def symbols_compose(begin_t, parts, end_t) + parts = parts.map do |part| + case part.type + when :str + value, = *part + part.updated(:sym, [ value.to_sym ]) + when :dstr + part.updated(:dsym) + else + part + end + end + + n(:array, [ *parts ], + collection_map(begin_t, parts, end_t)) + end + + # Hashes + + def pair(key, assoc_t, value) + n(:pair, [ key, value ], + binary_op_map(key, assoc_t, value)) + end + + def pair_list_18(list) + if list.size % 2 != 0 + diagnostic :error, :odd_hash, nil, list.last.loc.expression + else + list. + each_slice(2).map do |key, value| + n(:pair, [ key, value ], + binary_op_map(key, nil, value)) + end + end + end + + def pair_keyword(key_t, value) + key_map, pair_map = pair_keyword_map(key_t, value) + + key = n(:sym, [ value(key_t).to_sym ], key_map) + + n(:pair, [ key, value ], pair_map) + end + + def pair_quoted(begin_t, parts, end_t, value) + end_t, pair_map = pair_quoted_map(begin_t, end_t, value) + + key = symbol_compose(begin_t, parts, end_t) + + n(:pair, [ key, value ], pair_map) + end + + def pair_label(key_t) + key_l = loc(key_t) + value_l = key_l.adjust(end_pos: -1) + + label = value(key_t) + value = + if label =~ /\A[[:upper:]]/ + n(:const, [ nil, label.to_sym ], Source::Map::Constant.new(nil, value_l, value_l)) + else + n(:ident, [ label.to_sym ], Source::Map::Variable.new(value_l)) + end + pair_keyword(key_t, accessible(value)) + end + + def kwsplat(dstar_t, arg) + n(:kwsplat, [ arg ], + unary_op_map(dstar_t, arg)) + end + + def associate(begin_t, pairs, end_t) + key_set = Set.new + + pairs.each do |pair| + next unless pair.type.eql?(:pair) + + key, = *pair + + case key.type + when :sym, :str, :int, :float + when :rational, :complex, :regexp + next unless @parser.version >= 31 + else + next + end + + unless key_set.add?(key) + diagnostic :warning, :duplicate_hash_key, nil, key.loc.expression + end + end + + n(:hash, [ *pairs ], + collection_map(begin_t, pairs, end_t)) + end + + # Ranges + + def range_inclusive(lhs, dot2_t, rhs) + n(:irange, [ lhs, rhs ], + range_map(lhs, dot2_t, rhs)) + end + + def range_exclusive(lhs, dot3_t, rhs) + n(:erange, [ lhs, rhs ], + range_map(lhs, dot3_t, rhs)) + end + + # + # Access + # + + def self(token) + n0(:self, + token_map(token)) + end + + def ident(token) + n(:ident, [ value(token).to_sym ], + variable_map(token)) + end + + def ivar(token) + n(:ivar, [ value(token).to_sym ], + variable_map(token)) + end + + def gvar(token) + gvar_name = value(token) + + if gvar_name.start_with?('$0') && gvar_name.length > 2 + diagnostic :error, :gvar_name, { :name => gvar_name }, loc(token) + end + + n(:gvar, [ gvar_name.to_sym ], + variable_map(token)) + end + + def cvar(token) + n(:cvar, [ value(token).to_sym ], + variable_map(token)) + end + + def back_ref(token) + n(:back_ref, [ value(token).to_sym ], + token_map(token)) + end + + def nth_ref(token) + n(:nth_ref, [ value(token) ], + token_map(token)) + end + + def accessible(node) + case node.type + when :__FILE__ + if @emit_file_line_as_literals + n(:str, [ node.loc.expression.source_buffer.name ], + node.loc.dup) + else + node + end + + when :__LINE__ + if @emit_file_line_as_literals + n(:int, [ node.loc.expression.line ], + node.loc.dup) + else + node + end + + when :__ENCODING__ + if !self.class.emit_encoding + n(:const, [ n(:const, [ nil, :Encoding], nil), :UTF_8 ], + node.loc.dup) + else + node + end + + when :ident + name, = *node + + if %w[? !].any? { |c| name.to_s.end_with?(c) } + diagnostic :error, :invalid_id_to_get, + { :identifier => name.to_s }, node.loc.expression + end + + # Numbered parameters are not declared anywhere, + # so they take precedence over method calls in numblock contexts + if @parser.version >= 27 && @parser.try_declare_numparam(node) + return node.updated(:lvar) + end + + unless @parser.static_env.declared?(name) + if @parser.version == 33 && + name == :it && + @parser.context.in_block && + !@parser.max_numparam_stack.has_ordinary_params? + diagnostic :warning, :ambiguous_it_call, nil, node.loc.expression + end + + return n(:send, [ nil, name ], + var_send_map(node)) + end + + if name.to_s == parser.current_arg_stack.top + diagnostic :error, :circular_argument_reference, + { :var_name => name.to_s }, node.loc.expression + end + + node.updated(:lvar) + + else + node + end + end + + def const(name_t) + n(:const, [ nil, value(name_t).to_sym ], + constant_map(nil, nil, name_t)) + end + + def const_global(t_colon3, name_t) + cbase = n0(:cbase, token_map(t_colon3)) + + n(:const, [ cbase, value(name_t).to_sym ], + constant_map(cbase, t_colon3, name_t)) + end + + def const_fetch(scope, t_colon2, name_t) + n(:const, [ scope, value(name_t).to_sym ], + constant_map(scope, t_colon2, name_t)) + end + + def __ENCODING__(__ENCODING__t) + n0(:__ENCODING__, + token_map(__ENCODING__t)) + end + + # + # Assignment + # + + def assignable(node) + case node.type + when :cvar + node.updated(:cvasgn) + + when :ivar + node.updated(:ivasgn) + + when :gvar + node.updated(:gvasgn) + + when :const + if @parser.context.in_def + diagnostic :error, :dynamic_const, nil, node.loc.expression + end + + node.updated(:casgn) + + when :ident + name, = *node + + var_name = node.children[0].to_s + name_loc = node.loc.expression + + check_assignment_to_numparam(var_name, name_loc) + check_reserved_for_numparam(var_name, name_loc) + + @parser.static_env.declare(name) + + node.updated(:lvasgn) + + when :match_var + name, = *node + + var_name = node.children[0].to_s + name_loc = node.loc.expression + + check_assignment_to_numparam(var_name, name_loc) + check_reserved_for_numparam(var_name, name_loc) + + node + + when :nil, :self, :true, :false, + :__FILE__, :__LINE__, :__ENCODING__ + diagnostic :error, :invalid_assignment, nil, node.loc.expression + + when :back_ref, :nth_ref + diagnostic :error, :backref_assignment, nil, node.loc.expression + end + end + + def const_op_assignable(node) + node.updated(:casgn) + end + + def assign(lhs, eql_t, rhs) + (lhs << rhs).updated(nil, nil, + :location => lhs.loc. + with_operator(loc(eql_t)). + with_expression(join_exprs(lhs, rhs))) + end + + def op_assign(lhs, op_t, rhs) + case lhs.type + when :gvasgn, :ivasgn, :lvasgn, :cvasgn, :casgn, :send, :csend, :index + operator = value(op_t)[0..-1].to_sym + source_map = lhs.loc. + with_operator(loc(op_t)). + with_expression(join_exprs(lhs, rhs)) + + if lhs.type == :index + lhs = lhs.updated(:indexasgn) + end + + case operator + when :'&&' + n(:and_asgn, [ lhs, rhs ], source_map) + when :'||' + n(:or_asgn, [ lhs, rhs ], source_map) + else + n(:op_asgn, [ lhs, operator, rhs ], source_map) + end + + when :back_ref, :nth_ref + diagnostic :error, :backref_assignment, nil, lhs.loc.expression + end + end + + def multi_lhs(begin_t, items, end_t) + n(:mlhs, [ *items ], + collection_map(begin_t, items, end_t)) + end + + def multi_assign(lhs, eql_t, rhs) + n(:masgn, [ lhs, rhs ], + binary_op_map(lhs, eql_t, rhs)) + end + + # + # Class and module definition + # + + def def_class(class_t, name, + lt_t, superclass, + body, end_t) + n(:class, [ name, superclass, body ], + module_definition_map(class_t, name, lt_t, end_t)) + end + + def def_sclass(class_t, lshft_t, expr, + body, end_t) + n(:sclass, [ expr, body ], + module_definition_map(class_t, nil, lshft_t, end_t)) + end + + def def_module(module_t, name, + body, end_t) + n(:module, [ name, body ], + module_definition_map(module_t, name, nil, end_t)) + end + + # + # Method (un)definition + # + + def def_method(def_t, name_t, args, + body, end_t) + check_reserved_for_numparam(value(name_t), loc(name_t)) + + n(:def, [ value(name_t).to_sym, args, body ], + definition_map(def_t, nil, name_t, end_t)) + end + + def def_endless_method(def_t, name_t, args, + assignment_t, body) + check_reserved_for_numparam(value(name_t), loc(name_t)) + + n(:def, [ value(name_t).to_sym, args, body ], + endless_definition_map(def_t, nil, name_t, assignment_t, body)) + end + + def def_singleton(def_t, definee, dot_t, + name_t, args, + body, end_t) + validate_definee(definee) + check_reserved_for_numparam(value(name_t), loc(name_t)) + + n(:defs, [ definee, value(name_t).to_sym, args, body ], + definition_map(def_t, dot_t, name_t, end_t)) + end + + def def_endless_singleton(def_t, definee, dot_t, + name_t, args, + assignment_t, body) + validate_definee(definee) + check_reserved_for_numparam(value(name_t), loc(name_t)) + + n(:defs, [ definee, value(name_t).to_sym, args, body ], + endless_definition_map(def_t, dot_t, name_t, assignment_t, body)) + end + + def undef_method(undef_t, names) + n(:undef, [ *names ], + keyword_map(undef_t, nil, names, nil)) + end + + def alias(alias_t, to, from) + n(:alias, [ to, from ], + keyword_map(alias_t, nil, [to, from], nil)) + end + + # + # Formal arguments + # + + def args(begin_t, args, end_t, check_args=true) + args = check_duplicate_args(args) if check_args + validate_no_forward_arg_after_restarg(args) + + map = collection_map(begin_t, args, end_t) + if !self.class.emit_forward_arg && args.length == 1 && args[0].type == :forward_arg + n(:forward_args, [], map) + else + n(:args, args, map) + end + end + + def numargs(max_numparam) + n(:numargs, [ max_numparam ], nil) + end + + def forward_only_args(begin_t, dots_t, end_t) + if self.class.emit_forward_arg + arg = forward_arg(dots_t) + n(:args, [ arg ], + collection_map(begin_t, [ arg ], end_t)) + else + n(:forward_args, [], collection_map(begin_t, token_map(dots_t), end_t)) + end + end + + def forward_arg(dots_t) + n(:forward_arg, [], token_map(dots_t)) + end + + def arg(name_t) + check_reserved_for_numparam(value(name_t), loc(name_t)) + + n(:arg, [ value(name_t).to_sym ], + variable_map(name_t)) + end + + def optarg(name_t, eql_t, value) + check_reserved_for_numparam(value(name_t), loc(name_t)) + + n(:optarg, [ value(name_t).to_sym, value ], + variable_map(name_t). + with_operator(loc(eql_t)). + with_expression(loc(name_t).join(value.loc.expression))) + end + + def restarg(star_t, name_t=nil) + if name_t + check_reserved_for_numparam(value(name_t), loc(name_t)) + n(:restarg, [ value(name_t).to_sym ], + arg_prefix_map(star_t, name_t)) + else + n0(:restarg, + arg_prefix_map(star_t)) + end + end + + def kwarg(name_t) + check_reserved_for_numparam(value(name_t), loc(name_t)) + + n(:kwarg, [ value(name_t).to_sym ], + kwarg_map(name_t)) + end + + def kwoptarg(name_t, value) + check_reserved_for_numparam(value(name_t), loc(name_t)) + + n(:kwoptarg, [ value(name_t).to_sym, value ], + kwarg_map(name_t, value)) + end + + def kwrestarg(dstar_t, name_t=nil) + if name_t + check_reserved_for_numparam(value(name_t), loc(name_t)) + + n(:kwrestarg, [ value(name_t).to_sym ], + arg_prefix_map(dstar_t, name_t)) + else + n0(:kwrestarg, + arg_prefix_map(dstar_t)) + end + end + + def kwnilarg(dstar_t, nil_t) + n0(:kwnilarg, + arg_prefix_map(dstar_t, nil_t)) + end + + def shadowarg(name_t) + check_reserved_for_numparam(value(name_t), loc(name_t)) + + n(:shadowarg, [ value(name_t).to_sym ], + variable_map(name_t)) + end + + def blockarg(amper_t, name_t) + if !name_t.nil? + check_reserved_for_numparam(value(name_t), loc(name_t)) + end + + arg_name = name_t ? value(name_t).to_sym : nil + n(:blockarg, [ arg_name ], + arg_prefix_map(amper_t, name_t)) + end + + def procarg0(arg) + if self.class.emit_procarg0 + if arg.type == :arg && self.class.emit_arg_inside_procarg0 + n(:procarg0, [ arg ], + Source::Map::Collection.new(nil, nil, arg.location.expression)) + else + arg.updated(:procarg0) + end + else + arg + end + end + + # Ruby 1.8 block arguments + + def arg_expr(expr) + if expr.type == :lvasgn + expr.updated(:arg) + else + n(:arg_expr, [ expr ], + expr.loc.dup) + end + end + + def restarg_expr(star_t, expr=nil) + if expr.nil? + n0(:restarg, token_map(star_t)) + elsif expr.type == :lvasgn + expr.updated(:restarg) + else + n(:restarg_expr, [ expr ], + expr.loc.dup) + end + end + + def blockarg_expr(amper_t, expr) + if expr.type == :lvasgn + expr.updated(:blockarg) + else + n(:blockarg_expr, [ expr ], + expr.loc.dup) + end + end + + # MacRuby Objective-C arguments + + def objc_kwarg(kwname_t, assoc_t, name_t) + kwname_l = loc(kwname_t) + if assoc_t.nil? # a: b, not a => b + kwname_l = kwname_l.resize(kwname_l.size - 1) + operator_l = kwname_l.end.resize(1) + else + operator_l = loc(assoc_t) + end + + n(:objc_kwarg, [ value(kwname_t).to_sym, value(name_t).to_sym ], + Source::Map::ObjcKwarg.new(kwname_l, operator_l, loc(name_t), + kwname_l.join(loc(name_t)))) + end + + def objc_restarg(star_t, name=nil) + if name.nil? + n0(:restarg, arg_prefix_map(star_t)) + elsif name.type == :arg # regular restarg + name.updated(:restarg, nil, + { :location => name.loc.with_operator(loc(star_t)) }) + else # restarg with objc_kwarg inside + n(:objc_restarg, [ name ], + unary_op_map(star_t, name)) + end + end + + # + # Method calls + # + + def call_type_for_dot(dot_t) + if !dot_t.nil? && value(dot_t) == :anddot + :csend + else + # This case is a bit tricky. ruby23.y returns the token tDOT with + # the value :dot, and the token :tANDDOT with the value :anddot. + # + # But, ruby{18..22}.y (which unconditionally expect tDOT) just + # return "." there, since they are to be kept close to the corresponding + # Ruby MRI grammars. + # + # Thankfully, we don't have to care. + :send + end + end + + def forwarded_args(dots_t) + n(:forwarded_args, [], token_map(dots_t)) + end + + def forwarded_restarg(star_t) + n(:forwarded_restarg, [], token_map(star_t)) + end + + def forwarded_kwrestarg(dstar_t) + n(:forwarded_kwrestarg, [], token_map(dstar_t)) + end + + def call_method(receiver, dot_t, selector_t, + lparen_t=nil, args=[], rparen_t=nil) + type = call_type_for_dot(dot_t) + + if self.class.emit_kwargs + rewrite_hash_args_to_kwargs(args) + end + + if selector_t.nil? + n(type, [ receiver, :call, *args ], + send_map(receiver, dot_t, nil, lparen_t, args, rparen_t)) + else + n(type, [ receiver, value(selector_t).to_sym, *args ], + send_map(receiver, dot_t, selector_t, lparen_t, args, rparen_t)) + end + end + + def call_lambda(lambda_t) + if self.class.emit_lambda + n0(:lambda, expr_map(loc(lambda_t))) + else + n(:send, [ nil, :lambda ], + send_map(nil, nil, lambda_t)) + end + end + + def block(method_call, begin_t, args, body, end_t) + if method_call.type == :yield + diagnostic :error, :block_given_to_yield, nil, method_call.loc.keyword, [loc(begin_t)] + end + + if method_call.type == :super + *_args, last_arg = *method_call + else + _receiver, _selector, *_args, last_arg = *method_call + end + if last_arg && (last_arg.type == :block_pass || last_arg.type == :forwarded_args) + if (@parser.version == 33 && method_call.type != :super) || @parser.version != 33 + diagnostic :error, :block_and_blockarg, nil, last_arg.loc.expression, [loc(begin_t)] + end + end + + if args.type == :numargs + block_type = :numblock + args = args.children[0] + else + block_type = :block + end + + if [:send, :csend, :index, :super, :zsuper, :lambda].include?(method_call.type) + n(block_type, [ method_call, args, body ], + block_map(method_call.loc.expression, begin_t, end_t)) + else + # Code like "return foo 1 do end" is reduced in a weird sequence. + # Here, method_call is actually (return). + actual_send, = *method_call + block = + n(block_type, [ actual_send, args, body ], + block_map(actual_send.loc.expression, begin_t, end_t)) + + n(method_call.type, [ block ], + method_call.loc.with_expression(join_exprs(method_call, block))) + end + end + + def block_pass(amper_t, arg) + n(:block_pass, [ arg ], + unary_op_map(amper_t, arg)) + end + + def objc_varargs(pair, rest_of_varargs) + value, first_vararg = *pair + vararg_array = array(nil, [ first_vararg, *rest_of_varargs ], nil). + updated(:objc_varargs) + pair.updated(nil, [ value, vararg_array ], + { :location => pair.loc.with_expression( + pair.loc.expression.join(vararg_array.loc.expression)) }) + end + + def attr_asgn(receiver, dot_t, selector_t) + method_name = (value(selector_t) + '=').to_sym + type = call_type_for_dot(dot_t) + + # Incomplete method call. + n(type, [ receiver, method_name ], + send_map(receiver, dot_t, selector_t)) + end + + def index(receiver, lbrack_t, indexes, rbrack_t) + if self.class.emit_kwargs + rewrite_hash_args_to_kwargs(indexes) + end + + if self.class.emit_index + n(:index, [ receiver, *indexes ], + index_map(receiver, lbrack_t, rbrack_t)) + else + n(:send, [ receiver, :[], *indexes ], + send_index_map(receiver, lbrack_t, rbrack_t)) + end + end + + def index_asgn(receiver, lbrack_t, indexes, rbrack_t) + if self.class.emit_kwargs + rewrite_hash_args_to_kwargs(indexes) + end + + if self.class.emit_index + n(:indexasgn, [ receiver, *indexes ], + index_map(receiver, lbrack_t, rbrack_t)) + else + # Incomplete method call. + n(:send, [ receiver, :[]=, *indexes ], + send_index_map(receiver, lbrack_t, rbrack_t)) + end + end + + def binary_op(receiver, operator_t, arg) + source_map = send_binary_op_map(receiver, operator_t, arg) + + if @parser.version == 18 + operator = value(operator_t) + + if operator == '!=' + method_call = n(:send, [ receiver, :==, arg ], source_map) + elsif operator == '!~' + method_call = n(:send, [ receiver, :=~, arg ], source_map) + end + + if %w(!= !~).include?(operator) + return n(:not, [ method_call ], + expr_map(source_map.expression)) + end + end + + n(:send, [ receiver, value(operator_t).to_sym, arg ], + source_map) + end + + def match_op(receiver, match_t, arg) + source_map = send_binary_op_map(receiver, match_t, arg) + + if (regexp = static_regexp_node(receiver)) + regexp.names.each do |name| + @parser.static_env.declare(name) + end + + n(:match_with_lvasgn, [ receiver, arg ], + source_map) + else + n(:send, [ receiver, :=~, arg ], + source_map) + end + end + + def unary_op(op_t, receiver) + case value(op_t) + when '+', '-' + method = value(op_t) + '@' + else + method = value(op_t) + end + + n(:send, [ receiver, method.to_sym ], + send_unary_op_map(op_t, receiver)) + end + + def not_op(not_t, begin_t=nil, receiver=nil, end_t=nil) + if @parser.version == 18 + n(:not, [ check_condition(receiver) ], + unary_op_map(not_t, receiver)) + else + if receiver.nil? + nil_node = n0(:begin, collection_map(begin_t, nil, end_t)) + + n(:send, [ + nil_node, :'!' + ], send_unary_op_map(not_t, nil_node)) + else + n(:send, [ check_condition(receiver), :'!' ], + send_map(nil, nil, not_t, begin_t, [receiver], end_t)) + end + end + end + + # + # Control flow + # + + # Logical operations: and, or + + def logical_op(type, lhs, op_t, rhs) + n(type, [ lhs, rhs ], + binary_op_map(lhs, op_t, rhs)) + end + + # Conditionals + + def condition(cond_t, cond, then_t, + if_true, else_t, if_false, end_t) + n(:if, [ check_condition(cond), if_true, if_false ], + condition_map(cond_t, cond, then_t, if_true, else_t, if_false, end_t)) + end + + def condition_mod(if_true, if_false, cond_t, cond) + n(:if, [ check_condition(cond), if_true, if_false ], + keyword_mod_map(if_true || if_false, cond_t, cond)) + end + + def ternary(cond, question_t, if_true, colon_t, if_false) + n(:if, [ check_condition(cond), if_true, if_false ], + ternary_map(cond, question_t, if_true, colon_t, if_false)) + end + + # Case matching + + def when(when_t, patterns, then_t, body) + children = patterns << body + n(:when, children, + keyword_map(when_t, then_t, children, nil)) + end + + def case(case_t, expr, when_bodies, else_t, else_body, end_t) + n(:case, [ expr, *(when_bodies << else_body)], + condition_map(case_t, expr, nil, nil, else_t, else_body, end_t)) + end + + # Loops + + def loop(type, keyword_t, cond, do_t, body, end_t) + n(type, [ check_condition(cond), body ], + keyword_map(keyword_t, do_t, nil, end_t)) + end + + def loop_mod(type, body, keyword_t, cond) + if body.type == :kwbegin + type = :"#{type}_post" + end + + n(type, [ check_condition(cond), body ], + keyword_mod_map(body, keyword_t, cond)) + end + + def for(for_t, iterator, in_t, iteratee, + do_t, body, end_t) + n(:for, [ iterator, iteratee, body ], + for_map(for_t, in_t, do_t, end_t)) + end + + # Keywords + + def keyword_cmd(type, keyword_t, lparen_t=nil, args=[], rparen_t=nil) + if type == :yield && args.count > 0 + last_arg = args.last + if last_arg.type == :block_pass + diagnostic :error, :block_given_to_yield, nil, loc(keyword_t), [last_arg.loc.expression] + end + end + + if %i[yield super].include?(type) && self.class.emit_kwargs + rewrite_hash_args_to_kwargs(args) + end + + n(type, args, + keyword_map(keyword_t, lparen_t, args, rparen_t)) + end + + # BEGIN, END + + def preexe(preexe_t, lbrace_t, compstmt, rbrace_t) + n(:preexe, [ compstmt ], + keyword_map(preexe_t, lbrace_t, [], rbrace_t)) + end + + def postexe(postexe_t, lbrace_t, compstmt, rbrace_t) + n(:postexe, [ compstmt ], + keyword_map(postexe_t, lbrace_t, [], rbrace_t)) + end + + # Exception handling + + def rescue_body(rescue_t, + exc_list, assoc_t, exc_var, + then_t, compound_stmt) + n(:resbody, [ exc_list, exc_var, compound_stmt ], + rescue_body_map(rescue_t, exc_list, assoc_t, + exc_var, then_t, compound_stmt)) + end + + def begin_body(compound_stmt, rescue_bodies=[], + else_t=nil, else_=nil, + ensure_t=nil, ensure_=nil) + if rescue_bodies.any? + if else_t + compound_stmt = + n(:rescue, + [ compound_stmt, *(rescue_bodies + [ else_ ]) ], + eh_keyword_map(compound_stmt, nil, rescue_bodies, else_t, else_)) + else + compound_stmt = + n(:rescue, + [ compound_stmt, *(rescue_bodies + [ nil ]) ], + eh_keyword_map(compound_stmt, nil, rescue_bodies, nil, nil)) + end + elsif else_t + statements = [] + if !compound_stmt.nil? + if compound_stmt.type == :begin + statements += compound_stmt.children + else + statements.push(compound_stmt) + end + end + statements.push( + n(:begin, [ else_ ], + collection_map(else_t, [ else_ ], nil))) + compound_stmt = + n(:begin, statements, + collection_map(nil, statements, nil)) + end + + if ensure_t + compound_stmt = + n(:ensure, + [ compound_stmt, ensure_ ], + eh_keyword_map(compound_stmt, ensure_t, [ ensure_ ], nil, nil)) + end + + compound_stmt + end + + # + # Expression grouping + # + + def compstmt(statements) + case + when statements.none? + nil + when statements.one? + statements.first + else + n(:begin, statements, + collection_map(nil, statements, nil)) + end + end + + def begin(begin_t, body, end_t) + if body.nil? + # A nil expression: `()'. + n0(:begin, + collection_map(begin_t, nil, end_t)) + elsif body.type == :mlhs || + (body.type == :begin && + body.loc.begin.nil? && body.loc.end.nil?) + # Synthesized (begin) from compstmt "a; b" or (mlhs) + # from multi_lhs "(a, b) = *foo". + n(body.type, body.children, + collection_map(begin_t, body.children, end_t)) + else + n(:begin, [ body ], + collection_map(begin_t, [ body ], end_t)) + end + end + + def begin_keyword(begin_t, body, end_t) + if body.nil? + # A nil expression: `begin end'. + n0(:kwbegin, + collection_map(begin_t, nil, end_t)) + elsif (body.type == :begin && + body.loc.begin.nil? && body.loc.end.nil?) + # Synthesized (begin) from compstmt "a; b". + n(:kwbegin, body.children, + collection_map(begin_t, body.children, end_t)) + else + n(:kwbegin, [ body ], + collection_map(begin_t, [ body ], end_t)) + end + end + + # + # PATTERN MATCHING + # + + def case_match(case_t, expr, in_bodies, else_t, else_body, end_t) + else_body = n(:empty_else, nil, token_map(else_t)) if else_t && !else_body + n(:case_match, [ expr, *(in_bodies << else_body)], + condition_map(case_t, expr, nil, nil, else_t, else_body, end_t)) + end + + def in_match(lhs, in_t, rhs) + n(:in_match, [lhs, rhs], + binary_op_map(lhs, in_t, rhs)) + end + + def match_pattern(lhs, match_t, rhs) + n(:match_pattern, [lhs, rhs], + binary_op_map(lhs, match_t, rhs)) + end + + def match_pattern_p(lhs, match_t, rhs) + n(:match_pattern_p, [lhs, rhs], + binary_op_map(lhs, match_t, rhs)) + end + + def in_pattern(in_t, pattern, guard, then_t, body) + children = [pattern, guard, body] + n(:in_pattern, children, + keyword_map(in_t, then_t, children.compact, nil)) + end + + def if_guard(if_t, if_body) + n(:if_guard, [if_body], guard_map(if_t, if_body)) + end + + def unless_guard(unless_t, unless_body) + n(:unless_guard, [unless_body], guard_map(unless_t, unless_body)) + end + + def match_var(name_t) + name = value(name_t).to_sym + name_l = loc(name_t) + + check_lvar_name(name, name_l) + check_duplicate_pattern_variable(name, name_l) + @parser.static_env.declare(name) + + n(:match_var, [ name ], + variable_map(name_t)) + end + + def match_hash_var(name_t) + name = value(name_t).to_sym + + expr_l = loc(name_t) + name_l = expr_l.adjust(end_pos: -1) + + check_lvar_name(name, name_l) + check_duplicate_pattern_variable(name, name_l) + @parser.static_env.declare(name) + + n(:match_var, [ name ], + Source::Map::Variable.new(name_l, expr_l)) + end + + def match_hash_var_from_str(begin_t, strings, end_t) + if strings.length > 1 + diagnostic :error, :pm_interp_in_var_name, nil, loc(begin_t).join(loc(end_t)) + end + + string = strings[0] + + case string.type + when :str + # MRI supports plain strings in hash pattern matching + name, = *string + name_l = string.loc.expression + + check_lvar_name(name, name_l) + check_duplicate_pattern_variable(name, name_l) + + @parser.static_env.declare(name) + + if (begin_l = string.loc.begin) + # exclude beginning of the string from the location of the variable + name_l = name_l.adjust(begin_pos: begin_l.length) + end + + if (end_l = string.loc.end) + # exclude end of the string from the location of the variable + name_l = name_l.adjust(end_pos: -end_l.length) + end + + expr_l = loc(begin_t).join(string.loc.expression).join(loc(end_t)) + n(:match_var, [ name.to_sym ], + Source::Map::Variable.new(name_l, expr_l)) + when :begin + match_hash_var_from_str(begin_t, string.children, end_t) + else + # we only can get here if there is an interpolation, e.g., ``in "#{ a }":` + diagnostic :error, :pm_interp_in_var_name, nil, loc(begin_t).join(loc(end_t)) + end + end + + def match_rest(star_t, name_t = nil) + if name_t.nil? + n0(:match_rest, + unary_op_map(star_t)) + else + name = match_var(name_t) + n(:match_rest, [ name ], + unary_op_map(star_t, name)) + end + end + + def hash_pattern(lbrace_t, kwargs, rbrace_t) + args = check_duplicate_args(kwargs) + n(:hash_pattern, args, + collection_map(lbrace_t, args, rbrace_t)) + end + + def array_pattern(lbrack_t, elements, rbrack_t) + return n(:array_pattern, nil, collection_map(lbrack_t, [], rbrack_t)) if elements.nil? + + trailing_comma = false + + node_elements = elements.map do |element| + if element.type == :match_with_trailing_comma + trailing_comma = true + element.children.first + else + trailing_comma = false + element + end + end + + node_type = trailing_comma ? :array_pattern_with_tail : :array_pattern + + n(node_type, node_elements, + collection_map(lbrack_t, elements, rbrack_t)) + end + + def find_pattern(lbrack_t, elements, rbrack_t) + n(:find_pattern, elements, + collection_map(lbrack_t, elements, rbrack_t)) + end + + def match_with_trailing_comma(match, comma_t) + n(:match_with_trailing_comma, [ match ], expr_map(match.loc.expression.join(loc(comma_t)))) + end + + def const_pattern(const, ldelim_t, pattern, rdelim_t) + n(:const_pattern, [const, pattern], + Source::Map::Collection.new( + loc(ldelim_t), loc(rdelim_t), + const.loc.expression.join(loc(rdelim_t)) + ) + ) + end + + def pin(pin_t, var) + n(:pin, [ var ], + send_unary_op_map(pin_t, var)) + end + + def match_alt(left, pipe_t, right) + source_map = binary_op_map(left, pipe_t, right) + + n(:match_alt, [ left, right ], + source_map) + end + + def match_as(value, assoc_t, as) + source_map = binary_op_map(value, assoc_t, as) + + n(:match_as, [ value, as ], + source_map) + end + + def match_nil_pattern(dstar_t, nil_t) + n0(:match_nil_pattern, + arg_prefix_map(dstar_t, nil_t)) + end + + def match_pair(label_type, label, value) + if label_type == :label + check_duplicate_pattern_key(label[0], label[1]) + pair_keyword(label, value) + else + begin_t, parts, end_t = label + label_loc = loc(begin_t).join(loc(end_t)) + + # quoted label like "label": value + if (var_name = static_string(parts)) + check_duplicate_pattern_key(var_name, label_loc) + else + diagnostic :error, :pm_interp_in_var_name, nil, label_loc + end + + pair_quoted(begin_t, parts, end_t, value) + end + end + + def match_label(label_type, label) + if label_type == :label + match_hash_var(label) + else + # quoted label like "label": value + begin_t, strings, end_t = label + match_hash_var_from_str(begin_t, strings, end_t) + end + end + + private + + # + # VERIFICATION + # + + def check_condition(cond) + case cond.type + when :masgn + if @parser.version <= 23 + diagnostic :error, :masgn_as_condition, nil, cond.loc.expression + else + cond + end + + when :begin + if cond.children.count == 1 + cond.updated(nil, [ + check_condition(cond.children.last) + ]) + else + cond + end + + when :and, :or + lhs, rhs = *cond + + if @parser.version == 18 + cond + else + cond.updated(cond.type, [ + check_condition(lhs), + check_condition(rhs) + ]) + end + + when :irange, :erange + lhs, rhs = *cond + + type = case cond.type + when :irange then :iflipflop + when :erange then :eflipflop + end + + lhs_condition = check_condition(lhs) unless lhs.nil? + rhs_condition = check_condition(rhs) unless rhs.nil? + + return cond.updated(type, [ + lhs_condition, + rhs_condition + ]) + + when :regexp + n(:match_current_line, [ cond ], expr_map(cond.loc.expression)) + + else + cond + end + end + + def check_duplicate_args(args, map={}) + args.each do |this_arg| + case this_arg.type + when :arg, :optarg, :restarg, :blockarg, + :kwarg, :kwoptarg, :kwrestarg, + :shadowarg + + check_duplicate_arg(this_arg, map) + + when :procarg0 + + if this_arg.children[0].is_a?(Symbol) + # s(:procarg0, :a) + check_duplicate_arg(this_arg, map) + else + # s(:procarg0, s(:arg, :a), ...) + check_duplicate_args(this_arg.children, map) + end + + when :mlhs + check_duplicate_args(this_arg.children, map) + end + end + end + + def check_duplicate_arg(this_arg, map={}) + this_name, = *this_arg + + that_arg = map[this_name] + that_name, = *that_arg + + if that_arg.nil? + map[this_name] = this_arg + elsif arg_name_collides?(this_name, that_name) + diagnostic :error, :duplicate_argument, nil, + this_arg.loc.name, [ that_arg.loc.name ] + end + end + + def validate_no_forward_arg_after_restarg(args) + restarg = nil + forward_arg = nil + args.each do |arg| + case arg.type + when :restarg then restarg = arg + when :forward_arg then forward_arg = arg + end + end + + if !forward_arg.nil? && !restarg.nil? + diagnostic :error, :forward_arg_after_restarg, nil, forward_arg.loc.expression, [restarg.loc.expression] + end + end + + def check_assignment_to_numparam(name, loc) + # MRI < 2.7 treats numbered parameters as regular variables + # and so it's allowed to perform assignments like `_1 = 42`. + return if @parser.version < 27 + + assigning_to_numparam = + @parser.context.in_dynamic_block? && + name =~ /\A_([1-9])\z/ && + @parser.max_numparam_stack.has_numparams? + + if assigning_to_numparam + diagnostic :error, :cant_assign_to_numparam, { :name => name }, loc + end + end + + def check_reserved_for_numparam(name, loc) + # MRI < 3.0 accepts assignemnt to variables like _1 + # if it's not a numbered parameter. MRI 3.0 and newer throws an error. + return if @parser.version < 30 + + if name =~ /\A_([1-9])\z/ + diagnostic :error, :reserved_for_numparam, { :name => name }, loc + end + end + + def arg_name_collides?(this_name, that_name) + case @parser.version + when 18 + this_name == that_name + when 19 + # Ignore underscore. + this_name != :_ && + this_name == that_name + else + # Ignore everything beginning with underscore. + this_name && this_name[0] != '_' && + this_name == that_name + end + end + + def check_lvar_name(name, loc) + if name =~ /\A[[[:lower:]]_][[[:alnum:]]_]*\z/ + # OK + else + diagnostic :error, :lvar_name, { name: name }, loc + end + end + + def check_duplicate_pattern_variable(name, loc) + return if name.to_s.start_with?('_') + + if @parser.pattern_variables.declared?(name) + diagnostic :error, :duplicate_variable_name, { name: name.to_s }, loc + end + + @parser.pattern_variables.declare(name) + end + + def check_duplicate_pattern_key(name, loc) + if @parser.pattern_hash_keys.declared?(name) + diagnostic :error, :duplicate_pattern_key, { name: name.to_s }, loc + end + + @parser.pattern_hash_keys.declare(name) + end + + # + # SOURCE MAPS + # + + def n(type, children, source_map) + AST::Node.new(type, children, :location => source_map) + end + + def n0(type, source_map) + n(type, [], source_map) + end + + def join_exprs(left_expr, right_expr) + left_expr.loc.expression. + join(right_expr.loc.expression) + end + + def token_map(token) + Source::Map.new(loc(token)) + end + + def delimited_string_map(string_t) + str_range = loc(string_t) + + begin_l = str_range.with(end_pos: str_range.begin_pos + 1) + + end_l = str_range.with(begin_pos: str_range.end_pos - 1) + + Source::Map::Collection.new(begin_l, end_l, + loc(string_t)) + end + + def prefix_string_map(symbol) + str_range = loc(symbol) + + begin_l = str_range.with(end_pos: str_range.begin_pos + 1) + + Source::Map::Collection.new(begin_l, nil, + loc(symbol)) + end + + def unquoted_map(token) + Source::Map::Collection.new(nil, nil, + loc(token)) + end + + def pair_keyword_map(key_t, value_e) + key_range = loc(key_t) + + key_l = key_range.adjust(end_pos: -1) + + colon_l = key_range.with(begin_pos: key_range.end_pos - 1) + + [ # key map + Source::Map::Collection.new(nil, nil, + key_l), + # pair map + Source::Map::Operator.new(colon_l, + key_range.join(value_e.loc.expression)) ] + end + + def pair_quoted_map(begin_t, end_t, value_e) + end_l = loc(end_t) + + quote_l = end_l.with(begin_pos: end_l.end_pos - 2, + end_pos: end_l.end_pos - 1) + + colon_l = end_l.with(begin_pos: end_l.end_pos - 1) + + [ # modified end token + [ value(end_t), quote_l ], + # pair map + Source::Map::Operator.new(colon_l, + loc(begin_t).join(value_e.loc.expression)) ] + end + + def expr_map(loc) + Source::Map.new(loc) + end + + def collection_map(begin_t, parts, end_t) + if begin_t.nil? || end_t.nil? + if parts.any? + expr_l = join_exprs(parts.first, parts.last) + elsif !begin_t.nil? + expr_l = loc(begin_t) + elsif !end_t.nil? + expr_l = loc(end_t) + end + else + expr_l = loc(begin_t).join(loc(end_t)) + end + + Source::Map::Collection.new(loc(begin_t), loc(end_t), expr_l) + end + + def string_map(begin_t, parts, end_t) + if begin_t && value(begin_t).start_with?('<<') + if parts.any? + expr_l = join_exprs(parts.first, parts.last) + else + expr_l = loc(end_t).begin + end + + Source::Map::Heredoc.new(loc(begin_t), expr_l, loc(end_t)) + else + collection_map(begin_t, parts, end_t) + end + end + + def regexp_map(begin_t, end_t, options_e) + Source::Map::Collection.new(loc(begin_t), loc(end_t), + loc(begin_t).join(options_e.loc.expression)) + end + + def constant_map(scope, colon2_t, name_t) + if scope.nil? + expr_l = loc(name_t) + else + expr_l = scope.loc.expression.join(loc(name_t)) + end + + Source::Map::Constant.new(loc(colon2_t), loc(name_t), expr_l) + end + + def variable_map(name_t) + Source::Map::Variable.new(loc(name_t)) + end + + def binary_op_map(left_e, op_t, right_e) + Source::Map::Operator.new(loc(op_t), join_exprs(left_e, right_e)) + end + + def unary_op_map(op_t, arg_e=nil) + if arg_e.nil? + expr_l = loc(op_t) + else + expr_l = loc(op_t).join(arg_e.loc.expression) + end + + Source::Map::Operator.new(loc(op_t), expr_l) + end + + def range_map(start_e, op_t, end_e) + if start_e && end_e + expr_l = join_exprs(start_e, end_e) + elsif start_e + expr_l = start_e.loc.expression.join(loc(op_t)) + elsif end_e + expr_l = loc(op_t).join(end_e.loc.expression) + end + + Source::Map::Operator.new(loc(op_t), expr_l) + end + + def arg_prefix_map(op_t, name_t=nil) + if name_t.nil? + expr_l = loc(op_t) + else + expr_l = loc(op_t).join(loc(name_t)) + end + + Source::Map::Variable.new(loc(name_t), expr_l) + end + + def kwarg_map(name_t, value_e=nil) + label_range = loc(name_t) + name_range = label_range.adjust(end_pos: -1) + + if value_e + expr_l = loc(name_t).join(value_e.loc.expression) + else + expr_l = loc(name_t) + end + + Source::Map::Variable.new(name_range, expr_l) + end + + def module_definition_map(keyword_t, name_e, operator_t, end_t) + if name_e + name_l = name_e.loc.expression + end + + Source::Map::Definition.new(loc(keyword_t), + loc(operator_t), name_l, + loc(end_t)) + end + + def definition_map(keyword_t, operator_t, name_t, end_t) + Source::Map::MethodDefinition.new(loc(keyword_t), + loc(operator_t), loc(name_t), + loc(end_t), nil, nil) + end + + def endless_definition_map(keyword_t, operator_t, name_t, assignment_t, body_e) + body_l = body_e.loc.expression + + Source::Map::MethodDefinition.new(loc(keyword_t), + loc(operator_t), loc(name_t), nil, + loc(assignment_t), body_l) + end + + def send_map(receiver_e, dot_t, selector_t, begin_t=nil, args=[], end_t=nil) + if receiver_e + begin_l = receiver_e.loc.expression + elsif selector_t + begin_l = loc(selector_t) + end + + if end_t + end_l = loc(end_t) + elsif args.any? + end_l = args.last.loc.expression + elsif selector_t + end_l = loc(selector_t) + end + + Source::Map::Send.new(loc(dot_t), loc(selector_t), + loc(begin_t), loc(end_t), + begin_l.join(end_l)) + end + + def var_send_map(variable_e) + Source::Map::Send.new(nil, variable_e.loc.expression, + nil, nil, + variable_e.loc.expression) + end + + def send_binary_op_map(lhs_e, selector_t, rhs_e) + Source::Map::Send.new(nil, loc(selector_t), + nil, nil, + join_exprs(lhs_e, rhs_e)) + end + + def send_unary_op_map(selector_t, arg_e) + if arg_e.nil? + expr_l = loc(selector_t) + else + expr_l = loc(selector_t).join(arg_e.loc.expression) + end + + Source::Map::Send.new(nil, loc(selector_t), + nil, nil, + expr_l) + end + + def index_map(receiver_e, lbrack_t, rbrack_t) + Source::Map::Index.new(loc(lbrack_t), loc(rbrack_t), + receiver_e.loc.expression.join(loc(rbrack_t))) + end + + def send_index_map(receiver_e, lbrack_t, rbrack_t) + Source::Map::Send.new(nil, loc(lbrack_t).join(loc(rbrack_t)), + nil, nil, + receiver_e.loc.expression.join(loc(rbrack_t))) + end + + def block_map(receiver_l, begin_t, end_t) + Source::Map::Collection.new(loc(begin_t), loc(end_t), + receiver_l.join(loc(end_t))) + end + + def keyword_map(keyword_t, begin_t, args, end_t) + args ||= [] + + if end_t + end_l = loc(end_t) + elsif args.any? && !args.last.nil? + end_l = args.last.loc.expression + elsif args.any? && args.count > 1 + end_l = args[-2].loc.expression + else + end_l = loc(keyword_t) + end + + Source::Map::Keyword.new(loc(keyword_t), loc(begin_t), loc(end_t), + loc(keyword_t).join(end_l)) + end + + def keyword_mod_map(pre_e, keyword_t, post_e) + Source::Map::Keyword.new(loc(keyword_t), nil, nil, + join_exprs(pre_e, post_e)) + end + + def condition_map(keyword_t, cond_e, begin_t, body_e, else_t, else_e, end_t) + if end_t + end_l = loc(end_t) + elsif else_e && else_e.loc.expression + end_l = else_e.loc.expression + elsif loc(else_t) + end_l = loc(else_t) + elsif body_e && body_e.loc.expression + end_l = body_e.loc.expression + elsif loc(begin_t) + end_l = loc(begin_t) + else + end_l = cond_e.loc.expression + end + + Source::Map::Condition.new(loc(keyword_t), + loc(begin_t), loc(else_t), loc(end_t), + loc(keyword_t).join(end_l)) + end + + def ternary_map(begin_e, question_t, mid_e, colon_t, end_e) + Source::Map::Ternary.new(loc(question_t), loc(colon_t), + join_exprs(begin_e, end_e)) + end + + def for_map(keyword_t, in_t, begin_t, end_t) + Source::Map::For.new(loc(keyword_t), loc(in_t), + loc(begin_t), loc(end_t), + loc(keyword_t).join(loc(end_t))) + end + + def rescue_body_map(keyword_t, exc_list_e, assoc_t, + exc_var_e, then_t, + compstmt_e) + end_l = compstmt_e.loc.expression if compstmt_e + end_l = loc(then_t) if end_l.nil? && then_t + end_l = exc_var_e.loc.expression if end_l.nil? && exc_var_e + end_l = exc_list_e.loc.expression if end_l.nil? && exc_list_e + end_l = loc(keyword_t) if end_l.nil? + + Source::Map::RescueBody.new(loc(keyword_t), loc(assoc_t), loc(then_t), + loc(keyword_t).join(end_l)) + end + + def eh_keyword_map(compstmt_e, keyword_t, body_es, + else_t, else_e) + if compstmt_e.nil? + if keyword_t.nil? + begin_l = body_es.first.loc.expression + else + begin_l = loc(keyword_t) + end + else + begin_l = compstmt_e.loc.expression + end + + if else_t + if else_e.nil? + end_l = loc(else_t) + else + end_l = else_e.loc.expression + end + elsif !body_es.last.nil? + end_l = body_es.last.loc.expression + else + end_l = loc(keyword_t) + end + + Source::Map::Condition.new(loc(keyword_t), nil, loc(else_t), nil, + begin_l.join(end_l)) + end + + def guard_map(keyword_t, guard_body_e) + keyword_l = loc(keyword_t) + guard_body_l = guard_body_e.loc.expression + + Source::Map::Keyword.new(keyword_l, nil, nil, keyword_l.join(guard_body_l)) + end + + # + # HELPERS + # + + # Extract a static string from e.g. a regular expression, + # honoring the fact that MRI expands interpolations like #{""} + # at parse time. + def static_string(nodes) + nodes.map do |node| + case node.type + when :str + node.children[0] + when :begin + if (string = static_string(node.children)) + string + else + return nil + end + else + return nil + end + end.join + end + + def static_regexp(parts, options) + source = static_string(parts) + return nil if source.nil? + + source = case + when options.children.include?(:u) + source.encode(Encoding::UTF_8) + when options.children.include?(:e) + source.encode(Encoding::EUC_JP) + when options.children.include?(:s) + source.encode(Encoding::WINDOWS_31J) + when options.children.include?(:n) + source.encode(Encoding::BINARY) + else + source + end + + begin + old_verbose, $VERBOSE = $VERBOSE, nil + Regexp.new(source, (Regexp::EXTENDED if options.children.include?(:x))) + ensure + $VERBOSE = old_verbose + end + end + + def static_regexp_node(node) + if node.type == :regexp + if @parser.version >= 33 && node.children[0..-2].any? { |child| child.type != :str } + return nil + end + + parts, options = node.children[0..-2], node.children[-1] + static_regexp(parts, options) + end + end + + def collapse_string_parts?(parts) + parts.one? && + [:str, :dstr].include?(parts.first.type) + end + + def value(token) + token[0] + end + + def string_value(token) + unless token[0].valid_encoding? + diagnostic(:error, :invalid_encoding, nil, token[1]) + end + + token[0] + end + + def loc(token) + # Pass through `nil`s and return nil for tNL. + token[1] if token && token[0] + end + + def diagnostic(type, reason, arguments, location, highlights=[]) + @parser.diagnostics.process( + Diagnostic.new(type, reason, arguments, location, highlights)) + + if type == :error + @parser.send :yyerror + end + end + + def validate_definee(definee) + case definee.type + when :int, :str, :dstr, :sym, :dsym, + :regexp, :array, :hash + + diagnostic :error, :singleton_literal, nil, definee.loc.expression + false + else + true + end + end + + def rewrite_hash_args_to_kwargs(args) + if args.any? && kwargs?(args.last) + # foo(..., bar: baz) + args[args.length - 1] = args[args.length - 1].updated(:kwargs) + elsif args.length > 1 && args.last.type == :block_pass && kwargs?(args[args.length - 2]) + # foo(..., bar: baz, &blk) + args[args.length - 2] = args[args.length - 2].updated(:kwargs) + end + end + + def kwargs?(node) + node.type == :hash && node.loc.begin.nil? && node.loc.end.nil? + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/clobbering_error.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/clobbering_error.rb new file mode 100644 index 00000000..61240c3d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/clobbering_error.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Parser + ## + # {Parser::ClobberingError} is raised when {Parser::Source::Rewriter} + # detects a clobbering rewrite action. This class inherits {RuntimeError} + # rather than {StandardError} for backward compatibility. + # + # @api public + # + class ClobberingError < RuntimeError + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/color.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/color.rb new file mode 100644 index 00000000..d528f79b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/color.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module Parser + module Color + def self.color(str, code, bold: false) + return str unless STDOUT.tty? + code = Array(code) + code.unshift(1) if bold + "\e[#{code.join(';')}m#{str}\e[0m" + end + + def self.red(str, bold: false) + color(str, 31, bold: bold) + end + + def self.green(str, bold: false) + color(str, 32, bold: bold) + end + + def self.yellow(str, bold: false) + color(str, 33, bold: bold) + end + + def self.magenta(str, bold: false) + color(str, 35, bold: bold) + end + + def self.underline(str) + color(str, 4) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/context.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/context.rb new file mode 100644 index 00000000..cb5411ef --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/context.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module Parser + # Context of parsing that is represented by a stack of scopes. + # + # Supported states: + # + :class - in the class body (class A; end) + # + :module - in the module body (module M; end) + # + :sclass - in the singleton class body (class << obj; end) + # + :def - in the method body (def m; end) + # + :defs - in the singleton method body (def self.m; end) + # + :def_open_args - in the arglist of the method definition + # keep in mind that it's set **only** after reducing the first argument, + # if you need to handle the first argument check `lex_state == expr_fname` + # + :block - in the block body (tap {}) + # + :lambda - in the lambda body (-> {}) + # + class Context + FLAGS = %i[ + in_defined + in_kwarg + in_argdef + in_def + in_class + in_block + in_lambda + cant_return + ] + + def initialize + reset + end + + def reset + @in_defined = false + @in_kwarg = false + @in_argdef = false + @in_def = false + @in_class = false + @in_block = false + @in_lambda = false + @cant_return = false + end + + attr_accessor(*FLAGS) + + def in_dynamic_block? + in_block || in_lambda + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/current.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/current.rb new file mode 100644 index 00000000..adb25f52 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/current.rb @@ -0,0 +1,146 @@ +# frozen_string_literal: true + +module Parser + class << self + def warn_syntax_deviation(feature, version) + warn "warning: parser/current is loading #{feature}, which recognizes " \ + "#{version}-compliant syntax, but you are running #{RUBY_VERSION}.\n" \ + "Please see https://github.com/whitequark/parser#compatibility-with-ruby-mri." + end + private :warn_syntax_deviation + end + + case RUBY_VERSION + when /^2\.0\./ + current_version = '2.0.0' + if RUBY_VERSION != current_version + warn_syntax_deviation 'parser/ruby20', current_version + end + + require_relative 'ruby20' + CurrentRuby = Ruby20 + + when /^2\.1\./ + current_version = '2.1.10' + if RUBY_VERSION != current_version + warn_syntax_deviation 'parser/ruby21', current_version + end + + require_relative 'ruby21' + CurrentRuby = Ruby21 + + when /^2\.2\./ + current_version = '2.2.10' + if RUBY_VERSION != current_version + warn_syntax_deviation 'parser/ruby22', current_version + end + + require_relative 'ruby22' + CurrentRuby = Ruby22 + + when /^2\.3\./ + current_version = '2.3.8' + if RUBY_VERSION != current_version + warn_syntax_deviation 'parser/ruby23', current_version + end + + require_relative 'ruby23' + CurrentRuby = Ruby23 + + when /^2\.4\./ + current_version = '2.4.10' + if RUBY_VERSION != current_version + warn_syntax_deviation 'parser/ruby24', current_version + end + + require_relative 'ruby24' + CurrentRuby = Ruby24 + + when /^2\.5\./ + current_version = '2.5.9' + if RUBY_VERSION != current_version + warn_syntax_deviation 'parser/ruby25', current_version + end + + require_relative 'ruby25' + CurrentRuby = Ruby25 + + when /^2\.6\./ + current_version = '2.6.10' + if RUBY_VERSION != current_version + warn_syntax_deviation 'parser/ruby26', current_version + end + + require_relative 'ruby26' + CurrentRuby = Ruby26 + + when /^2\.7\./ + current_version = '2.7.8' + if RUBY_VERSION != current_version + warn_syntax_deviation 'parser/ruby27', current_version + end + + require_relative 'ruby27' + CurrentRuby = Ruby27 + + when /^3\.0\./ + current_version = '3.0.7' + if RUBY_VERSION != current_version + warn_syntax_deviation 'parser/ruby30', current_version + end + + require_relative 'ruby30' + CurrentRuby = Ruby30 + + when /^3\.1\./ + current_version = '3.1.7' + if RUBY_VERSION != current_version + warn_syntax_deviation 'parser/ruby31', current_version + end + + require_relative 'ruby31' + CurrentRuby = Ruby31 + + when /^3\.2\./ + current_version = '3.2.8' + if RUBY_VERSION != current_version + warn_syntax_deviation 'parser/ruby32', current_version + end + + require_relative 'ruby32' + CurrentRuby = Ruby32 + + when /^3\.3\./ + current_version = '3.3.8' + if RUBY_VERSION != current_version + warn_syntax_deviation 'parser/ruby33', current_version + end + + require_relative 'ruby33' + CurrentRuby = Ruby33 + + when /^3\.4\./ + current_version = '3.4.0-dev' + if RUBY_VERSION != current_version + warn_syntax_deviation 'parser/ruby34', current_version + end + + require_relative 'ruby34' + CurrentRuby = Ruby34 + + else # :nocov: + # Keep this in sync with released Ruby. + warn_syntax_deviation 'parser/ruby33', '3.3.x' + require_relative 'ruby33' + CurrentRuby = Ruby33 + end + # @!parse + # ## + # # @api public + # # + # # Parser for the running version of Ruby. NOTE: Supports only Ruby <= 3.3. To parse Ruby 3.4+, please use the prism gem. You can also use them in conjunction to support multiple versions using a backwards-compatible AST. + # # + # # @see https://ruby.github.io/prism/rb/docs/ruby_api_md.html prism gem documentation + # # @see https://github.com/whitequark/parser/blob/master/doc/PRISM_TRANSLATION.md Guide to using prism and parser together. + # class ::Parser::CurrentRuby < ::Parser::Base; end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/current_arg_stack.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/current_arg_stack.rb new file mode 100644 index 00000000..d0d58027 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/current_arg_stack.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +module Parser + # Stack that holds names of current arguments, + # i.e. while parsing + # def m1(a = (def m2(b = def m3(c = 1); end); end)); end + # ^ + # stack is [:a, :b, :c] + # + # Emulates `p->cur_arg` in MRI's parse.y + # + # @api private + # + class CurrentArgStack + attr_reader :stack + + def initialize + @stack = [] + freeze + end + + def empty? + @stack.size == 0 + end + + def push(value) + @stack << value + end + + def set(value) + @stack[@stack.length - 1] = value + end + + def pop + @stack.pop + end + + def reset + @stack.clear + end + + def top + @stack.last + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/deprecation.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/deprecation.rb new file mode 100644 index 00000000..0e9b6ed7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/deprecation.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Parser + ## + # @api private + # + module Deprecation + attr_writer :warned_of_deprecation + def warn_of_deprecation + @warned_of_deprecation ||= warn(self::DEPRECATION_WARNING) || true + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/diagnostic.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/diagnostic.rb new file mode 100644 index 00000000..e9f1b0a9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/diagnostic.rb @@ -0,0 +1,163 @@ +# frozen_string_literal: true + +module Parser + + ## + # @api public + # + # @!attribute [r] level + # @see LEVELS + # @return [Symbol] diagnostic level + # + # @!attribute [r] reason + # @see Parser::MESSAGES + # @return [Symbol] reason for error + # + # @!attribute [r] arguments + # @see Parser::MESSAGES + # @return [Symbol] extended arguments that describe the error + # + # @!attribute [r] message + # @return [String] error message + # + # @!attribute [r] location + # Main error-related source range. + # @return [Parser::Source::Range] + # + # @!attribute [r] highlights + # Supplementary error-related source ranges. + # @return [Array] + # + class Diagnostic + ## + # Collection of the available diagnostic levels. + # + # @return [Array] + # + LEVELS = [:note, :warning, :error, :fatal].freeze + + attr_reader :level, :reason, :arguments + attr_reader :location, :highlights + + ## + # @param [Symbol] level + # @param [Symbol] reason + # @param [Hash] arguments + # @param [Parser::Source::Range] location + # @param [Array] highlights + # + def initialize(level, reason, arguments, location, highlights=[]) + unless LEVELS.include?(level) + raise ArgumentError, + "Diagnostic#level must be one of #{LEVELS.join(', ')}; " \ + "#{level.inspect} provided." + end + raise 'Expected a location' unless location + + @level = level + @reason = reason + @arguments = (arguments || {}).dup.freeze + @location = location + @highlights = highlights.dup.freeze + + freeze + end + + ## + # @return [String] the rendered message. + # + def message + Messages.compile(@reason, @arguments) + end + + ## + # Renders the diagnostic message as a clang-like diagnostic. + # + # @example + # diagnostic.render # => + # # [ + # # "(fragment:0):1:5: error: unexpected token $end", + # # "foo +", + # # " ^" + # # ] + # + # @return [Array] + # + def render + if @location.line == @location.last_line || @location.is?("\n") + ["#{@location}: #{@level}: #{message}"] + render_line(@location) + else + # multi-line diagnostic + first_line = first_line_only(@location) + last_line = last_line_only(@location) + num_lines = (@location.last_line - @location.line) + 1 + buffer = @location.source_buffer + + last_lineno, last_column = buffer.decompose_position(@location.end_pos) + ["#{@location}-#{last_lineno}:#{last_column}: #{@level}: #{message}"] + + render_line(first_line, num_lines > 2, false) + + render_line(last_line, false, true) + end + end + + private + + ## + # Renders one source line in clang diagnostic style, with highlights. + # + # @return [Array] + # + def render_line(range, ellipsis=false, range_end=false) + source_line = range.source_line + highlight_line = ' ' * source_line.length + + @highlights.each do |highlight| + line_range = range.source_buffer.line_range(range.line) + if highlight = highlight.intersect(line_range) + highlight_line[highlight.column_range] = '~' * highlight.size + end + end + + if range.is?("\n") + highlight_line += "^" + else + if !range_end && range.size >= 1 + highlight_line[range.column_range] = '^' + '~' * (range.size - 1) + else + highlight_line[range.column_range] = '~' * range.size + end + end + + highlight_line += '...' if ellipsis + + [source_line, highlight_line]. + map { |line| "#{range.source_buffer.name}:#{range.line}: #{line}" } + end + + ## + # If necessary, shrink a `Range` so as to include only the first line. + # + # @return [Parser::Source::Range] + # + def first_line_only(range) + if range.line != range.last_line + range.resize(range.source =~ /\n/) + else + range + end + end + + ## + # If necessary, shrink a `Range` so as to include only the last line. + # + # @return [Parser::Source::Range] + # + def last_line_only(range) + if range.line != range.last_line + range.adjust(begin_pos: range.source =~ /[^\n]*\z/) + else + range + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/diagnostic/engine.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/diagnostic/engine.rb new file mode 100644 index 00000000..a29f6178 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/diagnostic/engine.rb @@ -0,0 +1,104 @@ +# frozen_string_literal: true + +module Parser + + ## + # {Parser::Diagnostic::Engine} provides a basic API for dealing with + # diagnostics by delegating them to registered consumers. + # + # @example + # buffer = Parser::Source::Buffer.new(__FILE__, source: 'foobar') + # + # consumer = lambda do |diagnostic| + # puts diagnostic.message + # end + # + # engine = Parser::Diagnostic::Engine.new(consumer) + # diagnostic = Parser::Diagnostic.new( + # :warning, :unexpected_token, { :token => 'abc' }, buffer, 1..2) + # + # engine.process(diagnostic) # => "unexpected token abc" + # + # @api public + # + # @!attribute [rw] consumer + # @return [#call(Diagnostic)] + # + # @!attribute [rw] all_errors_are_fatal + # When set to `true` any error that is encountered will result in + # {Parser::SyntaxError} being raised. + # @return [Boolean] + # + # @!attribute [rw] ignore_warnings + # When set to `true` warnings will be ignored. + # @return [Boolean] + # + class Diagnostic::Engine + attr_accessor :consumer + + attr_accessor :all_errors_are_fatal + attr_accessor :ignore_warnings + + ## + # @param [#call(Diagnostic)] consumer + # + def initialize(consumer=nil) + @consumer = consumer + + @all_errors_are_fatal = false + @ignore_warnings = false + end + + ## + # Processes a `diagnostic`: + # * Passes the diagnostic to the consumer, if it's not a warning when + # `ignore_warnings` is set. + # * After that, raises {Parser::SyntaxError} when `all_errors_are_fatal` + # is set to true. + # + # @param [Parser::Diagnostic] diagnostic + # @return [Parser::Diagnostic::Engine] + # @see ignore? + # @see raise? + # + def process(diagnostic) + if ignore?(diagnostic) + # do nothing + elsif @consumer + @consumer.call(diagnostic) + end + + if raise?(diagnostic) + raise Parser::SyntaxError, diagnostic + end + + self + end + + protected + + ## + # Checks whether `diagnostic` should be ignored. + # + # @param [Parser::Diagnostic] diagnostic + # @return [Boolean] + # + def ignore?(diagnostic) + @ignore_warnings && + diagnostic.level == :warning + end + + ## + # Checks whether `diagnostic` should be raised as an exception. + # + # @param [Parser::Diagnostic] diagnostic + # @return [Boolean] + # + def raise?(diagnostic) + (@all_errors_are_fatal && + diagnostic.level == :error) || + diagnostic.level == :fatal + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/lexer-F0.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/lexer-F0.rb new file mode 100644 index 00000000..6c430828 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/lexer-F0.rb @@ -0,0 +1,12931 @@ +# -*- encoding:utf-8; warn-indent:false; frozen_string_literal: true -*- + +# line 1 "lib/parser/lexer.rl" + +# line 3 "lib/parser/lexer.rl" +# +# === BEFORE YOU START === +# +# Read the Ruby Hacking Guide chapter 11, available in English at +# http://whitequark.org/blog/2013/04/01/ruby-hacking-guide-ch-11-finite-state-lexer/ +# +# Remember two things about Ragel scanners: +# +# 1) Longest match wins. +# +# 2) If two matches have the same length, the first +# in source code wins. +# +# General rules of making Ragel and Bison happy: +# +# * `p` (position) and `@te` contain the index of the character +# they're pointing to ("current"), plus one. `@ts` contains the index +# of the corresponding character. The code for extracting matched token is: +# +# @source_buffer.slice(@ts...@te) +# +# * If your input is `foooooooobar` and the rule is: +# +# 'f' 'o'+ +# +# the result will be: +# +# foooooooobar +# ^ ts=0 ^ p=te=9 +# +# * A Ragel lexer action should not emit more than one token, unless +# you know what you are doing. +# +# * All Ragel commands (fnext, fgoto, ...) end with a semicolon. +# +# * If an action emits the token and transitions to another state, use +# these Ragel commands: +# +# emit($whatever) +# fnext $next_state; fbreak; +# +# If you perform `fgoto` in an action which does not emit a token nor +# rewinds the stream pointer, the parser's side-effectful, +# context-sensitive lookahead actions will break in a hard to detect +# and debug way. +# +# * If an action does not emit a token: +# +# fgoto $next_state; +# +# * If an action features lookbehind, i.e. matches characters with the +# intent of passing them to another action: +# +# p = @ts - 1 +# fgoto $next_state; +# +# or, if the lookbehind consists of a single character: +# +# fhold; fgoto $next_state; +# +# * Ragel merges actions. So, if you have `e_lparen = '(' %act` and +# `c_lparen = '('` and a lexer action `e_lparen | c_lparen`, the result +# _will_ invoke the action `act`. +# +# e_something stands for "something with **e**mbedded action". +# +# * EOF is explicit and is matched by `c_eof`. If you want to introspect +# the state of the lexer, add this rule to the state: +# +# c_eof => do_eof; +# +# * If you proceed past EOF, the lexer will complain: +# +# NoMethodError: undefined method `ord' for nil:NilClass +# + +class Parser::Lexer + + +# line 85 "lib/parser/lexer-F0.rb" +class << self + attr_accessor :_lex_actions + private :_lex_actions, :_lex_actions= +end +self._lex_actions = [ + 0, 1, 0, 1, 16, 1, 17, 1, + 18, 1, 19, 1, 32, 1, 33, 1, + 34, 1, 35, 1, 37, 1, 38, 1, + 39, 1, 40, 1, 41, 1, 42, 1, + 43, 1, 44, 1, 45, 1, 46, 1, + 47, 1, 48, 1, 49, 1, 50, 1, + 51, 1, 52, 1, 53, 1, 54, 1, + 55, 1, 56, 1, 57, 1, 61, 1, + 62, 1, 63, 1, 64, 1, 65, 1, + 66, 1, 67, 1, 68, 1, 69, 1, + 70, 1, 71, 1, 72, 1, 73, 1, + 74, 1, 75, 1, 76, 1, 77, 1, + 78, 1, 79, 1, 80, 1, 81, 1, + 82, 1, 83, 1, 84, 1, 85, 1, + 86, 1, 87, 1, 88, 1, 89, 1, + 90, 1, 91, 1, 93, 1, 94, 1, + 95, 1, 100, 1, 101, 1, 102, 1, + 103, 1, 104, 1, 105, 1, 106, 1, + 107, 1, 112, 1, 113, 1, 114, 1, + 115, 1, 116, 1, 119, 1, 120, 1, + 121, 1, 122, 1, 125, 1, 126, 1, + 128, 1, 129, 1, 130, 1, 131, 1, + 132, 1, 133, 1, 135, 1, 136, 1, + 139, 1, 140, 1, 141, 1, 142, 1, + 144, 1, 145, 1, 155, 1, 156, 1, + 157, 1, 158, 1, 159, 1, 160, 1, + 161, 1, 162, 1, 163, 1, 164, 1, + 165, 1, 166, 1, 168, 1, 169, 1, + 170, 1, 171, 1, 172, 1, 173, 1, + 174, 1, 176, 1, 178, 1, 179, 1, + 180, 1, 184, 1, 186, 1, 187, 1, + 189, 1, 190, 1, 191, 1, 192, 1, + 193, 1, 194, 1, 195, 1, 196, 1, + 197, 1, 198, 1, 199, 1, 200, 1, + 201, 1, 203, 1, 204, 1, 205, 1, + 206, 1, 207, 1, 208, 1, 210, 1, + 211, 1, 230, 1, 231, 1, 232, 1, + 233, 1, 234, 1, 235, 1, 236, 1, + 237, 1, 238, 1, 240, 1, 241, 1, + 242, 1, 243, 1, 244, 1, 246, 1, + 247, 1, 248, 1, 250, 1, 252, 1, + 254, 1, 255, 1, 256, 1, 258, 1, + 259, 1, 260, 1, 263, 1, 264, 1, + 266, 1, 267, 1, 268, 1, 269, 1, + 270, 1, 271, 1, 274, 1, 275, 1, + 276, 1, 277, 1, 278, 1, 279, 1, + 280, 1, 281, 1, 282, 1, 283, 1, + 286, 1, 287, 1, 288, 1, 289, 1, + 290, 1, 291, 1, 292, 1, 293, 1, + 294, 1, 295, 1, 296, 2, 0, 18, + 2, 0, 100, 2, 0, 104, 2, 0, + 105, 2, 0, 167, 2, 0, 169, 2, + 0, 239, 2, 0, 284, 2, 0, 285, + 2, 0, 288, 2, 0, 289, 2, 2, + 249, 2, 3, 249, 2, 4, 249, 2, + 5, 249, 2, 6, 249, 2, 7, 249, + 2, 9, 251, 2, 10, 251, 2, 11, + 251, 2, 12, 251, 2, 13, 251, 2, + 14, 111, 2, 14, 134, 2, 14, 181, + 2, 14, 245, 2, 15, 261, 2, 16, + 0, 2, 16, 32, 2, 16, 33, 2, + 16, 34, 2, 16, 75, 2, 16, 84, + 2, 16, 94, 2, 16, 105, 2, 16, + 116, 2, 16, 118, 2, 16, 135, 2, + 16, 142, 2, 16, 143, 2, 16, 155, + 2, 16, 168, 2, 16, 190, 2, 16, + 201, 2, 16, 202, 2, 16, 208, 2, + 16, 209, 2, 16, 264, 2, 16, 265, + 2, 16, 292, 2, 17, 18, 2, 18, + 0, 2, 18, 75, 2, 18, 84, 2, + 18, 94, 2, 18, 117, 2, 18, 135, + 2, 18, 142, 2, 18, 190, 2, 18, + 201, 2, 18, 208, 2, 18, 264, 2, + 18, 292, 2, 19, 92, 2, 19, 177, + 2, 19, 188, 2, 19, 271, 2, 20, + 92, 2, 20, 177, 2, 20, 188, 2, + 20, 257, 2, 21, 177, 2, 21, 188, + 2, 22, 177, 2, 22, 188, 2, 23, + 177, 2, 23, 188, 2, 24, 177, 2, + 24, 198, 2, 25, 177, 2, 25, 188, + 2, 26, 177, 2, 27, 253, 2, 28, + 110, 2, 28, 182, 2, 28, 262, 2, + 29, 261, 2, 30, 108, 2, 30, 109, + 2, 30, 127, 2, 30, 183, 2, 30, + 260, 2, 31, 261, 2, 35, 0, 2, + 36, 175, 2, 37, 179, 2, 38, 179, + 2, 39, 185, 2, 41, 47, 2, 42, + 47, 2, 43, 47, 2, 44, 47, 2, + 45, 47, 2, 46, 47, 2, 47, 1, + 2, 53, 0, 2, 53, 49, 2, 53, + 58, 2, 53, 59, 2, 53, 60, 2, + 53, 96, 2, 53, 97, 2, 53, 98, + 2, 53, 99, 2, 53, 123, 2, 53, + 124, 2, 53, 137, 2, 53, 138, 2, + 53, 147, 2, 53, 148, 2, 53, 149, + 2, 53, 150, 2, 53, 151, 2, 53, + 152, 2, 53, 153, 2, 53, 154, 2, + 53, 212, 2, 53, 213, 2, 53, 215, + 2, 53, 216, 2, 53, 217, 2, 53, + 218, 2, 53, 219, 2, 53, 220, 2, + 53, 221, 2, 53, 223, 2, 53, 224, + 2, 53, 225, 2, 53, 226, 2, 53, + 227, 2, 53, 228, 2, 53, 229, 2, + 53, 272, 2, 53, 273, 3, 17, 18, + 0, 3, 17, 18, 75, 3, 17, 18, + 84, 3, 17, 18, 94, 3, 17, 18, + 117, 3, 17, 18, 135, 3, 17, 18, + 142, 3, 17, 18, 190, 3, 17, 18, + 201, 3, 17, 18, 208, 3, 17, 18, + 264, 3, 17, 18, 292, 3, 45, 47, + 1, 3, 46, 47, 1, 3, 47, 1, + 249, 3, 48, 8, 251, 3, 49, 8, + 251, 3, 53, 0, 99, 3, 53, 16, + 98, 3, 53, 16, 124, 3, 53, 16, + 272, 3, 53, 18, 146, 3, 53, 18, + 214, 3, 53, 18, 272, 3, 53, 33, + 97, 3, 53, 39, 152, 3, 53, 39, + 153, 3, 53, 45, 221, 4, 41, 47, + 1, 249, 4, 42, 47, 1, 249, 4, + 43, 47, 1, 249, 4, 44, 47, 1, + 249, 4, 45, 47, 1, 249, 4, 46, + 47, 1, 249, 4, 53, 16, 33, 97, + 4, 53, 17, 18, 146, 4, 53, 17, + 18, 272, 4, 53, 47, 1, 222, 5, + 53, 45, 47, 1, 222, 5, 53, 46, + 47, 1, 222 +] + +class << self + attr_accessor :_lex_trans_keys + private :_lex_trans_keys, :_lex_trans_keys= +end +self._lex_trans_keys = [ + 0, 0, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 58, 58, 58, 58, 46, 46, + 0, 127, 58, 58, 60, + 60, 62, 62, 10, 10, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 115, 115, + 99, 99, 117, 117, 101, + 101, 108, 116, 101, 101, + 115, 115, 115, 115, 105, 105, + 108, 108, 105, 105, 108, + 108, 58, 58, 0, 127, + 10, 10, 0, 127, 9, 92, + 10, 10, 9, 92, 58, + 58, 98, 98, 101, 101, + 103, 103, 105, 105, 110, 110, + 0, 127, 61, 61, 9, + 92, 9, 92, 9, 92, + 9, 92, 9, 92, 10, 10, + 0, 127, 0, 127, 61, + 126, 93, 93, 0, 127, + 0, 127, 10, 10, 34, 34, + 10, 10, 39, 39, 0, + 127, 10, 96, 96, 96, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 58, 58, 58, 58, + 0, 127, 43, 57, 48, 57, + 48, 57, 48, 57, 48, + 57, 115, 115, 99, 99, + 117, 117, 101, 101, 99, 99, + 117, 117, 101, 101, 0, + 127, 58, 58, 9, 92, + 9, 92, 9, 92, 9, 92, + 9, 92, 9, 92, 60, + 60, 10, 10, 9, 92, + 9, 92, 10, 10, 10, 10, + 10, 10, 10, 10, 46, + 46, 101, 101, 103, 103, + 105, 105, 110, 110, 69, 69, + 78, 78, 68, 68, 95, + 95, 95, 95, 0, 26, + 0, 0, 36, 64, 0, 127, + 48, 57, 0, 127, 0, + 127, 0, 127, 0, 127, + 9, 32, 0, 0, 61, 126, + 10, 10, 10, 10, 0, + 127, 0, 127, 48, 57, + 115, 115, 38, 38, 42, 42, + 64, 64, 58, 58, 60, + 61, 62, 62, 61, 126, + 61, 61, 61, 62, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 93, 93, 10, 10, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 124, 124, 0, 127, + 0, 127, 9, 32, 10, 10, + 10, 10, 46, 46, 10, + 10, 0, 0, 0, 127, + 0, 127, 61, 61, 0, 0, + 9, 32, 0, 0, 61, + 126, 10, 10, 10, 10, + 38, 38, 42, 42, 64, 64, + 60, 61, 62, 62, 61, + 126, 61, 61, 61, 62, + 0, 127, 93, 93, 10, 10, + 124, 124, 0, 126, 0, + 127, 0, 61, 9, 61, + 9, 61, 0, 0, 9, 61, + 9, 62, 46, 46, 46, + 46, 58, 58, 9, 32, + 0, 0, 0, 127, 0, 0, + 9, 124, 0, 0, 10, + 10, 10, 10, 0, 0, + 9, 61, 58, 58, 60, 60, + 62, 62, 9, 32, 10, + 10, 0, 127, 102, 102, + 101, 101, 110, 110, 104, 104, + 0, 127, 0, 127, 0, + 127, 0, 0, 0, 127, + 10, 10, 0, 123, 9, 32, + 10, 10, 10, 10, 10, + 10, 0, 0, 111, 111, + 0, 0, 0, 127, 0, 127, + 9, 32, 0, 0, 10, + 10, 10, 10, 10, 10, + 0, 0, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 58, 61, 0, 0, 61, + 126, 61, 61, 0, 0, + 0, 0, 0, 0, 9, 32, + 61, 61, 9, 32, 61, + 126, 10, 10, 10, 10, + 0, 127, 38, 61, 0, 0, + 42, 61, 61, 61, 9, + 92, 9, 92, 9, 92, + 46, 46, 46, 46, 10, 10, + 0, 26, 0, 127, 0, + 127, 61, 61, 0, 0, + 61, 126, 61, 62, 0, 0, + 0, 0, 0, 0, 0, + 0, 61, 126, 0, 127, + 48, 57, 38, 38, 42, 42, + 64, 64, 60, 61, 62, + 62, 61, 61, 61, 62, + 0, 127, 48, 57, 0, 127, + 124, 124, 64, 64, 60, + 61, 0, 0, 10, 34, + 10, 39, 96, 96, 62, 62, + 61, 126, 61, 62, 0, + 26, 0, 127, 0, 127, + 0, 127, 0, 0, 10, 10, + 0, 0, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 61, 126, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 0, 61, 124, 0, + 92, 9, 32, 0, 0, + 10, 10, 10, 10, 10, 10, + 0, 0, 0, 127, 0, + 127, 9, 32, 0, 0, + 10, 10, 10, 10, 10, 10, + 0, 0, 0, 127, 0, + 127, 61, 61, 0, 0, + 9, 32, 0, 0, 61, 126, + 10, 10, 10, 10, 0, + 127, 0, 127, 48, 57, + 61, 61, 38, 61, 0, 0, + 0, 0, 42, 61, 61, + 62, 46, 57, 46, 46, + 10, 10, 48, 101, 48, 95, + 46, 120, 48, 114, 43, + 57, 48, 105, 102, 102, + 0, 0, 101, 105, 0, 0, + 0, 0, 48, 114, 48, + 114, 48, 114, 48, 114, + 105, 114, 102, 102, 0, 0, + 101, 105, 115, 115, 0, + 0, 0, 0, 48, 114, + 48, 114, 48, 114, 48, 114, + 48, 114, 48, 114, 48, + 114, 48, 114, 46, 114, + 48, 114, 46, 114, 48, 114, + 58, 58, 60, 61, 62, + 62, 61, 126, 61, 61, + 61, 62, 0, 127, 0, 127, + 0, 0, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 0, + 10, 10, 0, 0, 0, + 0, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 9, 92, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 0, 61, 124, 0, 0, + 9, 92, 9, 92, 9, 92, + 46, 46, 46, 46, 10, + 10, 46, 46, 10, 10, + 10, 61, 10, 10, 10, 101, + 10, 110, 10, 100, 10, + 10, 0, 95, 9, 32, + 0, 0, 10, 10, 10, 10, + 98, 98, 9, 32, 10, + 10, 95, 95, 0 +] + +class << self + attr_accessor :_lex_key_spans + private :_lex_key_spans, :_lex_key_spans= +end +self._lex_key_spans = [ + 0, 128, 128, 128, 128, 128, 128, 128, + 1, 1, 1, 128, 1, 1, 1, 1, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 1, 1, 1, 1, 9, 1, + 1, 1, 1, 1, 1, 1, 1, 128, + 1, 128, 84, 1, 84, 1, 1, 1, + 1, 1, 1, 128, 1, 84, 84, 84, + 84, 84, 1, 128, 128, 66, 1, 128, + 128, 1, 1, 1, 1, 128, 87, 1, + 128, 128, 128, 128, 128, 128, 1, 1, + 128, 15, 10, 10, 10, 10, 1, 1, + 1, 1, 1, 1, 1, 128, 1, 84, + 84, 84, 84, 84, 84, 1, 1, 84, + 84, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 27, + 0, 29, 128, 10, 128, 128, 128, 128, + 24, 0, 66, 1, 1, 128, 128, 10, + 1, 1, 1, 1, 1, 2, 1, 66, + 1, 2, 128, 128, 128, 128, 128, 128, + 128, 1, 1, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 1, 128, + 128, 24, 1, 1, 1, 1, 0, 128, + 128, 1, 0, 24, 0, 66, 1, 1, + 1, 1, 1, 2, 1, 66, 1, 2, + 128, 1, 1, 1, 127, 128, 62, 53, + 53, 0, 53, 54, 1, 1, 1, 24, + 0, 128, 0, 116, 0, 1, 1, 0, + 53, 1, 1, 1, 24, 1, 128, 1, + 1, 1, 1, 128, 128, 128, 0, 128, + 1, 124, 24, 1, 1, 1, 0, 1, + 0, 128, 128, 24, 0, 1, 1, 1, + 0, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 4, 0, 66, 1, 0, + 0, 0, 24, 1, 24, 66, 1, 1, + 128, 24, 0, 20, 1, 84, 84, 84, + 1, 1, 1, 27, 128, 128, 1, 0, + 66, 2, 0, 0, 0, 0, 66, 128, + 10, 1, 1, 1, 2, 1, 1, 2, + 128, 10, 128, 1, 1, 2, 0, 25, + 30, 1, 1, 66, 2, 27, 128, 128, + 128, 0, 1, 0, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 66, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 0, 64, 93, 24, 0, + 1, 1, 1, 0, 128, 128, 24, 0, + 1, 1, 1, 0, 128, 128, 1, 0, + 24, 0, 66, 1, 1, 128, 128, 10, + 1, 24, 0, 0, 20, 2, 12, 1, + 1, 54, 48, 75, 67, 15, 58, 1, + 0, 5, 0, 0, 67, 67, 67, 67, + 10, 1, 0, 5, 1, 0, 0, 67, + 67, 67, 67, 67, 67, 67, 67, 69, + 67, 69, 67, 1, 2, 1, 66, 1, + 2, 128, 128, 0, 128, 128, 128, 128, + 128, 128, 0, 1, 0, 0, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 84, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 0, 64, 0, + 84, 84, 84, 1, 1, 1, 1, 1, + 52, 1, 92, 101, 91, 1, 96, 24, + 0, 1, 1, 1, 24, 1, 1 +] + +class << self + attr_accessor :_lex_index_offsets + private :_lex_index_offsets, :_lex_index_offsets= +end +self._lex_index_offsets = [ + 0, 0, 129, 258, 387, 516, 645, 774, + 903, 905, 907, 909, 1038, 1040, 1042, 1044, + 1046, 1175, 1304, 1433, 1562, 1691, 1820, 1949, + 2078, 2207, 2336, 2465, 2594, 2723, 2852, 2981, + 3110, 3239, 3368, 3370, 3372, 3374, 3376, 3386, + 3388, 3390, 3392, 3394, 3396, 3398, 3400, 3402, + 3531, 3533, 3662, 3747, 3749, 3834, 3836, 3838, + 3840, 3842, 3844, 3846, 3975, 3977, 4062, 4147, + 4232, 4317, 4402, 4404, 4533, 4662, 4729, 4731, + 4860, 4989, 4991, 4993, 4995, 4997, 5126, 5214, + 5216, 5345, 5474, 5603, 5732, 5861, 5990, 5992, + 5994, 6123, 6139, 6150, 6161, 6172, 6183, 6185, + 6187, 6189, 6191, 6193, 6195, 6197, 6326, 6328, + 6413, 6498, 6583, 6668, 6753, 6838, 6840, 6842, + 6927, 7012, 7014, 7016, 7018, 7020, 7022, 7024, + 7026, 7028, 7030, 7032, 7034, 7036, 7038, 7040, + 7068, 7069, 7099, 7228, 7239, 7368, 7497, 7626, + 7755, 7780, 7781, 7848, 7850, 7852, 7981, 8110, + 8121, 8123, 8125, 8127, 8129, 8131, 8134, 8136, + 8203, 8205, 8208, 8337, 8466, 8595, 8724, 8853, + 8982, 9111, 9113, 9115, 9244, 9373, 9502, 9631, + 9760, 9889, 10018, 10147, 10276, 10405, 10534, 10663, + 10792, 10921, 11050, 11179, 11308, 11437, 11566, 11695, + 11824, 11953, 12082, 12211, 12340, 12469, 12598, 12727, + 12856, 12985, 13114, 13243, 13372, 13501, 13630, 13759, + 13888, 14017, 14146, 14275, 14404, 14533, 14662, 14791, + 14920, 15049, 15178, 15307, 15436, 15565, 15694, 15823, + 15952, 16081, 16210, 16339, 16468, 16597, 16726, 16855, + 16984, 17113, 17242, 17371, 17500, 17629, 17758, 17887, + 18016, 18145, 18274, 18403, 18532, 18661, 18790, 18919, + 19048, 19177, 19306, 19435, 19564, 19693, 19822, 19824, + 19953, 20082, 20107, 20109, 20111, 20113, 20115, 20116, + 20245, 20374, 20376, 20377, 20402, 20403, 20470, 20472, + 20474, 20476, 20478, 20480, 20483, 20485, 20552, 20554, + 20557, 20686, 20688, 20690, 20692, 20820, 20949, 21012, + 21066, 21120, 21121, 21175, 21230, 21232, 21234, 21236, + 21261, 21262, 21391, 21392, 21509, 21510, 21512, 21514, + 21515, 21569, 21571, 21573, 21575, 21600, 21602, 21731, + 21733, 21735, 21737, 21739, 21868, 21997, 22126, 22127, + 22256, 22258, 22383, 22408, 22410, 22412, 22414, 22415, + 22417, 22418, 22547, 22676, 22701, 22702, 22704, 22706, + 22708, 22709, 22838, 22967, 23096, 23225, 23354, 23483, + 23612, 23741, 23870, 23999, 24128, 24257, 24386, 24515, + 24644, 24773, 24902, 25031, 25036, 25037, 25104, 25106, + 25107, 25108, 25109, 25134, 25136, 25161, 25228, 25230, + 25232, 25361, 25386, 25387, 25408, 25410, 25495, 25580, + 25665, 25667, 25669, 25671, 25699, 25828, 25957, 25959, + 25960, 26027, 26030, 26031, 26032, 26033, 26034, 26101, + 26230, 26241, 26243, 26245, 26247, 26250, 26252, 26254, + 26257, 26386, 26397, 26526, 26528, 26530, 26533, 26534, + 26560, 26591, 26593, 26595, 26662, 26665, 26693, 26822, + 26951, 27080, 27081, 27083, 27084, 27213, 27342, 27471, + 27600, 27729, 27858, 27987, 28116, 28245, 28374, 28503, + 28632, 28761, 28890, 29019, 29148, 29277, 29406, 29535, + 29664, 29793, 29922, 30051, 30180, 30309, 30438, 30567, + 30696, 30825, 30954, 31083, 31212, 31341, 31470, 31599, + 31728, 31857, 31986, 32115, 32244, 32373, 32502, 32631, + 32760, 32889, 33018, 33147, 33276, 33405, 33534, 33663, + 33792, 33921, 34050, 34179, 34308, 34437, 34566, 34695, + 34824, 34953, 35020, 35149, 35278, 35407, 35536, 35665, + 35794, 35923, 36052, 36181, 36310, 36439, 36568, 36697, + 36826, 36955, 37084, 37213, 37342, 37471, 37600, 37729, + 37858, 37987, 38116, 38245, 38246, 38311, 38405, 38430, + 38431, 38433, 38435, 38437, 38438, 38567, 38696, 38721, + 38722, 38724, 38726, 38728, 38729, 38858, 38987, 38989, + 38990, 39015, 39016, 39083, 39085, 39087, 39216, 39345, + 39356, 39358, 39383, 39384, 39385, 39406, 39409, 39422, + 39424, 39426, 39481, 39530, 39606, 39674, 39690, 39749, + 39751, 39752, 39758, 39759, 39760, 39828, 39896, 39964, + 40032, 40043, 40045, 40046, 40052, 40054, 40055, 40056, + 40124, 40192, 40260, 40328, 40396, 40464, 40532, 40600, + 40670, 40738, 40808, 40876, 40878, 40881, 40883, 40950, + 40952, 40955, 41084, 41213, 41214, 41343, 41472, 41601, + 41730, 41859, 41988, 41989, 41991, 41992, 41993, 42122, + 42251, 42380, 42509, 42638, 42767, 42896, 43025, 43154, + 43283, 43412, 43541, 43670, 43799, 43928, 44057, 44186, + 44315, 44444, 44573, 44702, 44831, 44960, 45089, 45218, + 45347, 45476, 45605, 45734, 45863, 45992, 46121, 46250, + 46379, 46508, 46637, 46766, 46851, 46980, 47109, 47238, + 47367, 47496, 47625, 47754, 47883, 48012, 48141, 48270, + 48399, 48528, 48657, 48786, 48915, 49044, 49173, 49302, + 49431, 49560, 49689, 49818, 49947, 50076, 50205, 50334, + 50463, 50592, 50721, 50850, 50979, 51108, 51237, 51366, + 51495, 51624, 51753, 51882, 52011, 52140, 52269, 52398, + 52527, 52656, 52785, 52914, 53043, 53172, 53301, 53430, + 53559, 53688, 53817, 53946, 54075, 54204, 54333, 54462, + 54591, 54720, 54849, 54978, 55107, 55236, 55237, 55302, + 55303, 55388, 55473, 55558, 55560, 55562, 55564, 55566, + 55568, 55621, 55623, 55716, 55818, 55910, 55912, 56009, + 56034, 56035, 56037, 56039, 56041, 56066, 56068 +] + +class << self + attr_accessor :_lex_indicies + private :_lex_indicies, :_lex_indicies= +end +self._lex_indicies = [ + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 1, 1, 2, 1, 2, 1, 1, + 2, 2, 1, 1, 1, 3, 1, 1, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 1, 2, 2, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 2, 2, 1, 2, + 0, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 2, 2, 2, 2, + 2, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 2, 2, 2, + 1, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 2, 2, 2, + 2, 1, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 2, 2, 2, 2, + 2, 2, 6, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 2, 2, 2, + 2, 5, 2, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 2, 2, 2, + 2, 2, 5, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 2, 2, 2, + 2, 2, 2, 2, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 2, 2, + 2, 2, 7, 2, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 2, 2, + 2, 2, 2, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 8, 8, + 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 8, + 8, 8, 8, 9, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 8, + 8, 8, 8, 8, 9, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 11, + 11, 11, 11, 11, 11, 11, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 10, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 14, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 15, 12, 12, 12, 12, 14, 12, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 12, 12, 12, 12, 13, 12, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 12, 12, 12, 12, 12, 13, 15, + 12, 12, 16, 17, 12, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 20, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 21, + 18, 18, 18, 18, 20, 18, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 18, 18, 18, 18, 19, 18, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 18, 18, 18, 18, 18, 19, 21, 18, + 23, 22, 24, 22, 25, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 27, + 22, 27, 27, 27, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 27, 22, + 22, 22, 22, 28, 29, 22, 30, 22, + 31, 32, 33, 34, 35, 28, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 36, 22, 37, 33, 38, 39, 22, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 40, 41, 33, 42, 26, 22, 26, + 26, 26, 26, 26, 26, 26, 26, 43, + 26, 26, 26, 26, 26, 26, 26, 26, + 44, 26, 26, 45, 26, 46, 26, 26, + 26, 47, 48, 22, 42, 22, 26, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 49, 22, 49, 49, 49, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 49, + 22, 22, 22, 22, 50, 51, 22, 52, + 22, 53, 54, 55, 56, 57, 50, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 58, 22, 59, 55, 60, 61, 22, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 62, 63, 55, 24, 19, 22, + 19, 19, 19, 19, 19, 19, 19, 19, + 64, 19, 19, 19, 19, 19, 19, 19, + 19, 65, 19, 19, 66, 19, 67, 19, + 19, 19, 68, 69, 22, 24, 22, 19, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 20, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 21, 22, 22, 22, 22, 20, + 22, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 22, 22, 22, 22, 19, + 22, 19, 19, 19, 19, 19, 70, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 22, 22, 22, 22, 22, + 19, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 20, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 21, 22, 22, 22, 22, + 20, 22, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 22, 22, 22, 22, + 19, 22, 19, 19, 19, 19, 71, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 22, 22, 22, 22, + 22, 19, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 20, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 21, 22, 22, 22, + 22, 20, 22, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 22, 22, 22, + 22, 19, 22, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 72, 19, 19, + 19, 19, 19, 19, 19, 22, 22, 22, + 22, 22, 19, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 20, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 21, 22, 22, + 22, 22, 20, 22, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 22, 22, + 22, 22, 19, 22, 19, 19, 73, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 22, 22, + 22, 22, 22, 19, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 20, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 21, 22, + 22, 22, 22, 20, 22, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 22, + 22, 22, 22, 19, 22, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 74, 19, 19, 19, 19, 19, 22, + 22, 22, 22, 22, 19, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 20, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 21, + 22, 22, 22, 22, 20, 22, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 22, 22, 22, 22, 19, 22, 19, 19, + 19, 19, 70, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 22, 22, 22, 22, 22, 19, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 20, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 21, 22, 22, 22, 22, 20, 22, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 22, 22, 22, 22, 19, 22, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 75, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 22, 22, 22, 22, 22, 19, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 20, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 21, 22, 22, 22, 22, 20, 22, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 22, 22, 22, 22, 19, 22, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 76, 19, 19, 19, 19, + 19, 19, 19, 77, 19, 19, 19, 19, + 19, 19, 22, 22, 22, 22, 22, 19, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 20, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 21, 22, 22, 22, 22, 20, + 22, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 22, 22, 22, 22, 19, + 22, 19, 19, 19, 19, 78, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 22, 22, 22, 22, 22, + 19, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 20, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 21, 22, 22, 22, 22, + 20, 22, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 22, 22, 22, 22, + 19, 22, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 79, 19, 19, 19, + 19, 19, 19, 19, 22, 22, 22, 22, + 22, 19, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 20, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 21, 22, 22, 22, + 22, 20, 22, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 22, 22, 22, + 22, 19, 22, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 70, 19, 19, + 19, 19, 19, 19, 19, 22, 22, 22, + 22, 22, 19, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 20, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 21, 22, 22, + 22, 22, 20, 22, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 22, 22, + 22, 22, 19, 22, 19, 19, 19, 19, + 19, 19, 19, 19, 80, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 22, 22, + 22, 22, 22, 19, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 20, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 21, 22, + 22, 22, 22, 20, 22, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 22, + 22, 22, 22, 19, 22, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 70, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 22, + 22, 22, 22, 22, 19, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 20, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 21, + 22, 22, 22, 22, 20, 22, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 22, 22, 22, 22, 19, 22, 19, 19, + 19, 19, 19, 19, 19, 81, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 22, 22, 22, 22, 22, 19, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 20, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 21, 22, 22, 22, 22, 20, 22, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 22, 22, 22, 22, 19, 22, 19, + 19, 19, 19, 19, 19, 19, 19, 82, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 22, 22, 22, 22, 22, 19, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 20, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 21, 22, 22, 22, 22, 20, 22, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 22, 22, 22, 22, 19, 22, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 74, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 22, 22, 22, 22, 22, 19, + 84, 83, 85, 83, 86, 83, 55, 83, + 87, 83, 83, 83, 83, 83, 83, 83, + 88, 83, 89, 83, 90, 83, 55, 83, + 91, 83, 55, 83, 92, 83, 86, 83, + 94, 93, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 97, 95, 97, 97, 97, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 97, 95, 95, 95, 95, 95, + 95, 95, 98, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 95, 99, 95, + 95, 96, 95, 96, 96, 96, 100, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 95, 95, 95, + 95, 95, 96, 101, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 103, 95, + 103, 103, 103, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 103, 95, 95, + 95, 95, 95, 95, 95, 104, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 95, 105, 95, 95, 102, 95, 102, 102, + 102, 106, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 95, 95, 95, 95, 95, 102, 108, 107, + 108, 108, 108, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 108, 107, 107, + 107, 107, 107, 107, 107, 109, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 110, 107, 111, 107, 112, 107, 112, + 112, 112, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 112, 107, 107, 107, + 107, 107, 107, 107, 113, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 114, 107, 115, 116, 118, 117, 119, 117, + 120, 117, 121, 117, 122, 117, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, + 124, 124, 124, 124, 124, 124, 124, 123, + 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, + 123, 124, 124, 124, 124, 124, 124, 123, + 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, + 123, 124, 124, 124, 124, 124, 123, 125, + 115, 126, 127, 126, 126, 126, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 126, 115, 115, 128, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 129, 129, 129, 129, 129, 129, 129, 129, + 129, 129, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 130, 115, 131, 132, + 131, 131, 131, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 131, 115, 115, + 133, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 134, 134, 134, + 134, 134, 134, 134, 134, 134, 134, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 135, 115, 137, 138, 137, 137, 137, + 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 137, 136, 136, 139, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 141, 136, + 143, 144, 143, 143, 143, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 143, + 142, 142, 145, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 147, 142, 143, 148, 143, + 143, 143, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 143, 142, 142, 145, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 147, 142, 127, 115, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 151, 151, 149, + 151, 149, 151, 151, 149, 149, 151, 151, + 151, 152, 151, 151, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 151, 151, + 151, 151, 151, 151, 151, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 149, + 151, 149, 149, 150, 151, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 149, + 149, 149, 151, 149, 150, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 151, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 149, + 149, 149, 149, 149, 149, 149, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 151, + 149, 149, 149, 149, 151, 149, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 151, + 149, 149, 149, 149, 149, 151, 154, 151, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 151, + 149, 154, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 156, 149, 149, + 149, 149, 157, 149, 149, 149, 149, 149, + 158, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 125, 149, 149, 149, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 149, 149, + 149, 149, 155, 159, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 149, 149, + 149, 158, 149, 155, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 162, 161, + 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 161, 161, + 161, 161, 161, 161, 161, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 161, + 161, 161, 161, 160, 161, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 161, + 161, 161, 161, 161, 160, 164, 163, 167, + 166, 162, 161, 167, 168, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 156, + 149, 149, 149, 149, 157, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, + 149, 149, 149, 149, 155, 159, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, + 149, 149, 149, 149, 149, 155, 170, 169, + 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 167, 169, 167, 170, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 172, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 173, 115, 115, 174, 115, 172, + 115, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 115, 115, 115, 115, 171, + 115, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 115, 115, 115, 115, 115, + 171, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 172, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 173, 149, 149, 174, 149, + 172, 149, 171, 171, 171, 171, 171, 171, + 175, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 149, 149, 149, 149, + 171, 149, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 149, 149, 149, 149, + 149, 171, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 172, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 173, 149, 149, 174, + 149, 172, 149, 171, 171, 171, 171, 171, + 171, 171, 171, 176, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 149, 149, 149, + 149, 171, 149, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 149, 149, 149, + 149, 149, 171, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 172, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 173, 149, 149, + 174, 149, 172, 149, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 177, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 149, 149, + 149, 149, 171, 149, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 149, 149, + 149, 149, 149, 171, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 172, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 173, 149, + 149, 174, 149, 172, 149, 171, 171, 171, + 177, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 149, + 149, 149, 149, 171, 149, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 149, + 149, 149, 149, 149, 171, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 180, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 181, + 178, 178, 178, 178, 180, 178, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, + 178, 178, 178, 178, 179, 178, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, + 178, 178, 178, 178, 178, 179, 181, 178, + 178, 182, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 184, 184, 184, 184, 184, 184, + 184, 184, 184, 184, 183, 183, 183, 183, + 183, 183, 183, 184, 184, 184, 184, 184, + 184, 184, 184, 184, 184, 184, 184, 184, + 184, 184, 184, 184, 184, 184, 184, 184, + 184, 184, 184, 184, 184, 183, 183, 183, + 183, 184, 183, 184, 184, 184, 184, 184, + 184, 184, 184, 184, 184, 184, 184, 184, + 184, 184, 184, 184, 184, 184, 184, 184, + 184, 184, 184, 184, 184, 183, 183, 183, + 183, 183, 184, 186, 185, 186, 185, 185, + 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 185, 187, 187, 187, 187, 187, + 187, 187, 187, 187, 187, 185, 188, 188, + 188, 188, 188, 188, 188, 188, 188, 188, + 185, 190, 190, 190, 190, 190, 190, 190, + 190, 190, 190, 189, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 189, 193, + 192, 194, 192, 195, 192, 196, 192, 198, + 197, 199, 197, 200, 197, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 183, + 183, 183, 183, 183, 183, 183, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 183, 183, 183, 183, 201, 183, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 183, 183, 183, 183, 183, 201, 202, 189, + 203, 204, 203, 203, 203, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 203, + 189, 189, 205, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 206, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 207, 189, 208, 209, 208, + 208, 208, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 208, 189, 189, 210, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 211, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 212, 189, 214, 215, 214, 214, 214, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 214, 213, 213, 216, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 217, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 218, 213, 220, + 221, 220, 220, 220, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 220, 219, + 219, 222, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 223, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 224, 219, 220, 221, 220, 220, + 220, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 220, 219, 219, 222, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 225, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 224, + 219, 220, 226, 220, 220, 220, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 220, 219, 219, 222, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 223, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 224, 219, 227, 189, + 204, 189, 229, 230, 229, 229, 229, 228, + 228, 228, 228, 228, 228, 228, 228, 228, + 228, 228, 228, 228, 228, 228, 228, 228, + 228, 229, 228, 228, 231, 228, 228, 232, + 228, 228, 228, 228, 228, 228, 228, 233, + 228, 228, 228, 228, 228, 228, 228, 228, + 228, 228, 228, 228, 228, 228, 228, 228, + 228, 228, 228, 228, 228, 228, 228, 228, + 228, 228, 228, 228, 228, 228, 228, 228, + 228, 228, 228, 228, 228, 228, 228, 228, + 228, 228, 228, 228, 228, 234, 228, 236, + 230, 236, 236, 236, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 236, 235, + 235, 231, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + 235, 235, 234, 235, 239, 238, 241, 240, + 242, 237, 243, 237, 244, 228, 246, 245, + 247, 245, 248, 245, 249, 245, 250, 245, + 251, 245, 252, 245, 253, 245, 254, 245, + 255, 245, 245, 245, 255, 245, 245, 245, + 245, 245, 256, 245, 245, 245, 245, 245, + 245, 245, 245, 245, 245, 245, 245, 245, + 245, 245, 255, 245, 257, 258, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 259, 2, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 260, 260, 260, + 260, 260, 260, 260, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 260, 260, + 260, 260, 0, 260, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 260, 260, + 260, 260, 260, 0, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 260, 261, + 261, 261, 261, 261, 261, 261, 261, 261, + 261, 261, 261, 261, 261, 261, 261, 261, + 261, 261, 261, 261, 261, 261, 261, 261, + 261, 261, 261, 261, 261, 261, 261, 261, + 261, 261, 261, 261, 261, 261, 261, 261, + 261, 261, 261, 261, 261, 261, 261, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 261, 261, 261, 261, 261, 261, 261, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 261, 261, 261, 261, 5, 261, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 261, 261, 261, 261, 261, 5, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 262, 262, 262, 262, 262, 262, + 262, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 262, 262, 262, 262, 7, + 262, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 262, 262, 262, 262, 262, + 7, 264, 265, 265, 265, 264, 265, 265, + 265, 265, 266, 267, 266, 266, 266, 265, + 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 264, 265, 265, 265, 265, + 265, 266, 268, 265, 269, 270, 271, 272, + 265, 265, 265, 273, 274, 265, 274, 265, + 275, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 276, 265, 277, 278, 279, + 265, 265, 280, 281, 280, 280, 282, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 283, 284, 265, 275, + 285, 275, 286, 287, 288, 289, 290, 291, + 263, 263, 292, 263, 263, 263, 293, 294, + 295, 263, 263, 296, 297, 298, 299, 263, + 300, 263, 301, 263, 265, 302, 265, 274, + 265, 263, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 304, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 303, 303, 303, 304, + 303, 304, 303, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 303, 303, 303, + 303, 263, 303, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 303, 303, 303, + 303, 303, 263, 266, 305, 266, 266, 266, + 305, 305, 305, 305, 305, 305, 305, 305, + 305, 305, 305, 305, 305, 305, 305, 305, + 305, 305, 266, 305, 306, 275, 307, 307, + 275, 307, 307, 307, 307, 307, 307, 307, + 307, 307, 307, 307, 307, 307, 307, 307, + 307, 307, 307, 307, 307, 307, 307, 307, + 307, 307, 307, 307, 307, 307, 307, 307, + 307, 307, 307, 307, 307, 307, 307, 307, + 307, 307, 307, 307, 307, 307, 307, 307, + 307, 307, 307, 307, 307, 307, 307, 307, + 307, 307, 307, 307, 307, 307, 275, 307, + 308, 309, 310, 311, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 9, 9, 312, + 9, 312, 9, 9, 312, 312, 9, 9, + 9, 314, 9, 9, 315, 315, 315, 315, + 315, 315, 315, 315, 315, 315, 9, 9, + 9, 9, 9, 9, 9, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 312, + 9, 312, 312, 313, 9, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 312, + 312, 312, 9, 312, 313, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 316, + 316, 316, 316, 316, 316, 316, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 313, + 316, 316, 316, 316, 313, 316, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 313, + 316, 316, 316, 316, 316, 313, 315, 315, + 315, 315, 315, 315, 315, 315, 315, 315, + 316, 317, 307, 275, 307, 275, 307, 275, + 307, 319, 318, 275, 320, 307, 275, 307, + 321, 275, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, + 312, 275, 312, 275, 307, 275, 275, 307, + 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, + 303, 304, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 303, 303, 303, 304, 303, 304, + 303, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 303, 303, 303, 303, 280, + 303, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 303, 303, 303, 303, 303, + 280, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 304, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 322, 322, 322, 304, 322, + 304, 322, 280, 280, 280, 280, 323, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 322, 322, 322, 322, + 280, 322, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 322, 322, 322, 322, + 322, 280, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 304, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 322, 322, 322, 304, + 322, 304, 322, 280, 280, 280, 280, 280, + 280, 324, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 322, 322, 322, + 322, 280, 322, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 322, 322, 322, + 322, 322, 280, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 304, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 322, 322, 322, + 304, 322, 304, 322, 280, 280, 280, 280, + 280, 280, 280, 280, 325, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 322, 322, + 322, 322, 280, 322, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 322, 322, + 322, 322, 322, 280, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 304, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 322, 322, + 322, 304, 322, 304, 322, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 326, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 322, + 322, 322, 322, 280, 322, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 322, + 322, 322, 322, 322, 280, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 304, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 322, + 322, 322, 304, 322, 304, 322, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 327, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 322, 322, 322, 322, 280, 322, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 322, 322, 322, 322, 322, 280, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 304, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 322, 322, 322, 304, 322, 304, 322, 280, + 280, 280, 326, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 322, 322, 322, 322, 280, 322, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 322, 322, 322, 322, 322, 280, 321, + 312, 267, 312, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 304, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 304, 328, 304, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 329, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 328, 263, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 304, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 304, 328, 304, 328, 263, 263, 263, + 263, 330, 331, 263, 263, 263, 263, 263, + 332, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 263, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 328, 263, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 304, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 304, 328, 304, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 333, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 263, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 328, 263, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 304, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 304, 328, 304, 328, 263, + 263, 334, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 263, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 328, 263, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 304, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 304, 328, 304, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 335, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 263, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 328, 263, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 304, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 304, 328, 304, + 328, 263, 263, 263, 336, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 263, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 328, + 263, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 304, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 304, 328, + 304, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 337, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 263, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 328, 263, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 304, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 304, + 328, 304, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 338, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 263, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 328, 263, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 304, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 304, 328, 304, 328, 263, 263, 263, 263, + 263, 263, 339, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 263, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 328, 263, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 304, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 304, 328, 304, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 340, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 328, 263, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 304, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 304, 328, 304, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 341, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 328, 263, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 304, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 304, 328, 304, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 342, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 263, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 328, 263, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 304, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 304, 328, 304, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 343, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 263, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 328, 263, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 304, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 304, 328, 304, + 328, 263, 263, 263, 263, 339, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 263, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 328, + 263, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 304, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 304, 328, + 304, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 344, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 263, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 328, 263, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 304, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 304, + 328, 304, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 343, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 263, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 328, 263, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 304, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 304, 328, 304, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 263, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 345, + 263, 346, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 328, 263, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 304, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 304, 328, 304, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 263, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 347, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 328, 263, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 304, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 304, 328, 304, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 263, 328, 348, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 328, 263, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 304, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 304, 328, 304, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 263, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 341, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 328, 263, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 304, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 304, 328, 304, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 263, 328, + 263, 263, 263, 341, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 328, 263, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 304, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 304, 328, 304, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 263, + 328, 263, 263, 263, 263, 349, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 350, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 328, + 263, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 304, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 304, 328, + 304, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 263, 328, 263, 263, 263, 263, 263, 263, + 351, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 328, 263, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 304, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 304, + 328, 304, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 263, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 352, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 328, 263, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 304, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 304, 328, 304, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 263, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 341, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 328, 263, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 304, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 304, 328, 304, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 263, 328, 263, 263, 263, + 263, 353, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 328, 263, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 304, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 304, 328, 304, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 263, 328, 354, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 328, 263, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 304, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 304, 328, 304, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 263, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 341, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 328, 263, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 304, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 304, 328, 304, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 263, 328, + 355, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 356, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 328, 263, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 304, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 304, 328, 304, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 263, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 357, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 328, + 263, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 304, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 304, 328, + 304, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 263, 328, 263, 263, 263, 263, 341, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 328, 263, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 304, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 304, + 328, 304, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 263, 328, 358, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 328, 263, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 304, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 304, 328, 304, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 263, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 348, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 328, 263, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 304, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 304, 328, 304, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 263, 328, 263, 263, 263, + 263, 359, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 341, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 328, 263, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 304, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 304, 328, 304, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 263, 328, 263, 263, + 263, 263, 263, 360, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 328, 263, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 304, + 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 361, 361, 361, 304, 361, 304, 361, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 361, 361, 361, 361, 263, 361, 263, + 263, 263, 263, 263, 263, 263, 263, 362, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 361, 361, 361, 361, 361, 263, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 304, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 304, 328, 304, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 263, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 363, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 328, 263, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 304, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 304, 328, 304, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 263, + 328, 263, 263, 263, 263, 364, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 328, + 263, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 304, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 304, 328, + 304, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 263, 328, 263, 263, 263, 365, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 328, 263, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 304, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 304, + 328, 366, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 263, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 328, 263, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 304, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 304, 328, 304, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 263, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 367, + 263, 368, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 328, 263, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 304, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 304, 328, 304, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 263, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 369, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 328, 263, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 304, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 304, 328, 304, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 263, 328, 263, 263, + 263, 263, 341, 263, 263, 263, 370, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 328, 263, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 304, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 304, 328, 304, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 263, 328, 263, + 263, 263, 263, 263, 341, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 328, 263, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 304, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 304, 328, 304, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 263, 328, + 263, 263, 263, 341, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 371, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 328, 263, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 304, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 304, 328, 304, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 263, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 372, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 328, + 263, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 304, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 304, 328, + 304, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 263, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 357, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 328, 263, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 304, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 304, + 328, 304, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 263, 328, 373, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 295, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 328, 263, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 304, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 304, 328, 304, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 263, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 355, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 328, 263, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 304, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 304, 328, 304, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 263, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 341, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 328, 263, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 304, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 304, 328, 304, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 263, 328, 263, 263, + 263, 263, 263, 341, 263, 263, 263, 263, + 263, 263, 263, 341, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 328, 263, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 304, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 304, 328, 304, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 263, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 374, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 328, 263, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 304, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 304, 328, 304, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 263, 328, + 263, 263, 263, 375, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 328, 263, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 304, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 304, 328, 304, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 263, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 376, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 328, + 263, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 304, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 304, 328, + 304, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 263, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 357, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 328, 263, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 304, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 304, + 328, 304, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 263, 328, 263, 263, 263, 263, 377, + 263, 263, 263, 378, 263, 263, 263, 263, + 263, 379, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 328, 263, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 304, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 304, 328, 304, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 263, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 379, 263, 263, 328, 328, + 328, 328, 328, 263, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 304, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 304, 328, 304, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 263, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 341, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 328, 263, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 304, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 304, 328, 304, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 263, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 341, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 328, 263, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 304, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 304, 328, 304, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 263, 328, 263, + 263, 263, 263, 380, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 328, 263, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 304, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 304, 328, 304, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 263, 328, + 263, 263, 263, 381, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 382, 383, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 328, 263, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 304, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 304, 328, 304, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 263, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 341, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 328, + 263, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 304, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 304, 328, + 304, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 263, 328, 263, 263, 384, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 328, 263, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 304, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 304, + 328, 304, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 263, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 357, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 328, 263, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 304, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 304, 328, 304, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 263, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 385, 263, 263, + 386, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 328, 263, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 304, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 304, 328, 304, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 263, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 341, 263, 328, + 328, 328, 328, 328, 263, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 304, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 304, 328, 304, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 263, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 352, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 328, 263, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 304, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 304, 328, 304, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 263, 328, 263, + 263, 263, 263, 387, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 388, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 328, 263, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 304, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 304, 328, 304, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 263, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 370, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 328, 263, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 304, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 304, 328, 304, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 263, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 389, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 328, + 263, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 304, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 304, 328, + 304, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 263, 328, 263, 263, 263, 263, 295, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 328, 263, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 304, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 304, + 328, 304, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 263, 328, 263, 263, 263, 263, 263, + 263, 263, 390, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 384, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 328, 263, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 304, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 304, 328, 304, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 263, 328, 263, 263, 263, 263, + 352, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 328, 263, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 304, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 304, 328, 304, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 263, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 391, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 328, 263, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 304, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 304, 328, 304, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 263, 328, 263, 263, + 263, 392, 263, 263, 263, 263, 263, 263, + 263, 393, 263, 263, 263, 263, 263, 263, + 263, 394, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 328, 263, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 304, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 304, 328, 304, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 263, 328, 263, + 263, 263, 263, 370, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 328, 263, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 304, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 304, 328, 304, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 263, 328, + 263, 263, 263, 263, 358, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 328, 263, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 304, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 304, 328, 304, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 263, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 378, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 328, + 263, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 304, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 304, 328, + 304, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 263, 328, 263, 263, 263, 263, 263, 263, + 263, 395, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 328, 263, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 304, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 304, + 328, 304, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 263, 328, 263, 263, 263, 263, 352, + 263, 263, 263, 376, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 328, 263, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 304, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 304, 328, 304, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 263, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 396, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 328, 263, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 304, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 304, 328, 304, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 263, 328, 263, 263, 263, + 263, 397, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 328, 263, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 304, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 304, 328, 304, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 263, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 346, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 328, 263, 275, 307, + 399, 400, 400, 400, 399, 400, 400, 400, + 400, 401, 400, 401, 401, 401, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 399, 400, 400, 400, 400, 400, + 401, 400, 400, 402, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 403, 400, + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 400, 404, 400, 400, 398, + 400, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 400, 400, 400, 400, 400, + 398, 405, 405, 405, 405, 405, 405, 405, + 405, 405, 405, 405, 405, 405, 405, 405, + 405, 405, 405, 405, 405, 405, 405, 405, + 405, 405, 405, 405, 405, 405, 405, 405, + 405, 405, 14, 405, 405, 405, 405, 405, + 405, 405, 405, 405, 405, 405, 405, 405, + 405, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 15, 405, 405, 405, 405, + 14, 405, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 405, 405, 405, 405, + 13, 405, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 405, 405, 405, 405, + 405, 13, 401, 406, 401, 401, 401, 406, + 406, 406, 406, 406, 406, 406, 406, 406, + 406, 406, 406, 406, 406, 406, 406, 406, + 406, 401, 406, 407, 408, 409, 410, 411, + 405, 412, 405, 413, 415, 416, 416, 416, + 415, 416, 416, 416, 416, 417, 418, 417, + 417, 417, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 415, 416, + 416, 416, 416, 416, 417, 419, 416, 420, + 416, 421, 422, 416, 416, 416, 423, 424, + 416, 424, 416, 421, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 425, 426, 427, 416, 416, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 429, + 430, 416, 421, 414, 421, 414, 414, 414, + 414, 414, 414, 414, 414, 414, 414, 414, + 414, 414, 414, 414, 414, 414, 414, 414, + 414, 414, 414, 414, 414, 414, 414, 416, + 431, 416, 424, 416, 414, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 433, 432, + 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 414, 414, 414, + 414, 414, 414, 414, 414, 414, 414, 432, + 432, 432, 432, 432, 433, 432, 414, 414, + 414, 414, 414, 414, 414, 414, 414, 414, + 414, 414, 414, 414, 414, 414, 414, 414, + 414, 414, 414, 414, 414, 414, 414, 414, + 432, 432, 432, 432, 414, 432, 414, 414, + 414, 414, 414, 414, 414, 414, 414, 414, + 414, 414, 414, 414, 414, 414, 414, 414, + 414, 414, 414, 414, 414, 414, 414, 414, + 432, 432, 432, 432, 432, 414, 435, 434, + 436, 417, 437, 417, 417, 417, 437, 437, + 437, 437, 437, 437, 437, 437, 437, 437, + 437, 437, 437, 437, 437, 437, 437, 437, + 417, 437, 438, 421, 439, 439, 421, 439, + 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 421, 439, 440, 441, + 442, 443, 421, 439, 421, 439, 421, 439, + 421, 444, 439, 421, 439, 446, 421, 445, + 445, 445, 445, 445, 445, 445, 445, 445, + 445, 445, 445, 445, 445, 445, 445, 445, + 445, 445, 445, 445, 445, 445, 445, 445, + 445, 445, 445, 445, 445, 445, 445, 445, + 445, 445, 445, 445, 445, 445, 445, 445, + 445, 445, 445, 445, 445, 445, 445, 445, + 445, 445, 445, 445, 445, 445, 445, 445, + 445, 445, 445, 445, 445, 445, 421, 445, + 421, 439, 421, 421, 439, 447, 447, 447, + 447, 447, 447, 447, 447, 447, 447, 447, + 447, 447, 447, 447, 447, 447, 447, 447, + 447, 447, 447, 447, 447, 447, 447, 447, + 447, 447, 447, 447, 447, 447, 433, 447, + 447, 447, 447, 447, 447, 447, 447, 447, + 447, 447, 447, 447, 447, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 447, + 447, 447, 447, 447, 433, 447, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 447, 447, 447, 447, 428, 447, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 447, 447, 447, 447, 447, 428, 446, 445, + 418, 445, 421, 439, 449, 448, 448, 448, + 449, 448, 448, 448, 448, 450, 451, 450, + 450, 450, 448, 448, 448, 448, 448, 448, + 448, 448, 448, 448, 448, 448, 449, 448, + 448, 448, 448, 448, 450, 448, 448, 452, + 448, 24, 453, 448, 454, 448, 455, 24, + 55, 456, 57, 24, 448, 448, 448, 448, + 448, 448, 448, 448, 448, 448, 457, 448, + 458, 55, 459, 460, 448, 448, 448, 448, + 448, 448, 448, 448, 448, 448, 448, 448, + 448, 448, 448, 448, 448, 448, 448, 448, + 448, 448, 448, 448, 448, 448, 448, 55, + 461, 55, 24, 448, 448, 448, 448, 448, + 448, 448, 448, 448, 448, 462, 448, 448, + 448, 448, 448, 448, 448, 448, 463, 448, + 448, 464, 448, 465, 448, 448, 448, 68, + 69, 448, 24, 448, 466, 466, 466, 466, + 466, 466, 466, 466, 466, 450, 466, 450, + 450, 450, 466, 466, 466, 466, 466, 466, + 466, 466, 466, 466, 466, 466, 466, 466, + 466, 466, 466, 466, 450, 466, 466, 466, + 466, 50, 51, 466, 52, 466, 53, 54, + 55, 56, 57, 50, 466, 466, 466, 466, + 466, 466, 466, 466, 466, 466, 58, 466, + 59, 55, 60, 61, 466, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 62, + 63, 55, 24, 19, 466, 19, 19, 19, + 19, 19, 19, 19, 19, 64, 19, 19, + 19, 19, 19, 19, 19, 19, 65, 19, + 19, 66, 19, 67, 19, 19, 19, 68, + 69, 466, 24, 466, 19, 467, 468, 468, + 468, 467, 468, 468, 468, 468, 55, 469, + 55, 55, 55, 468, 468, 468, 468, 468, + 468, 468, 468, 468, 468, 468, 468, 467, + 468, 468, 468, 468, 468, 55, 468, 468, + 468, 468, 468, 468, 468, 468, 468, 468, + 468, 468, 468, 468, 468, 468, 468, 468, + 468, 468, 468, 468, 468, 468, 468, 468, + 468, 468, 55, 468, 55, 469, 55, 55, + 55, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 55, 18, 18, 18, 18, + 18, 24, 18, 18, 18, 18, 18, 18, + 18, 55, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 55, 18, 55, 469, 55, 55, 55, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 55, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 55, 18, + 470, 55, 469, 55, 55, 55, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, + 55, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 472, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 55, 471, 55, + 469, 55, 55, 55, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 55, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 55, 55, 18, 473, 467, + 55, 467, 475, 474, 477, 478, 477, 477, + 477, 476, 476, 476, 476, 476, 476, 476, + 476, 476, 476, 476, 476, 476, 476, 476, + 476, 476, 476, 477, 476, 479, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 20, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 21, 467, 467, 467, 467, 20, 467, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 467, 467, 467, 467, 19, 467, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 467, 467, 467, 467, 467, 19, 480, + 55, 469, 55, 55, 55, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 55, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 55, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 24, 467, 481, 482, 483, + 484, 485, 486, 55, 469, 55, 55, 55, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 55, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 24, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 55, + 467, 55, 474, 24, 487, 24, 487, 488, + 489, 488, 488, 488, 476, 476, 476, 476, + 476, 476, 476, 476, 476, 476, 476, 476, + 476, 476, 476, 476, 476, 476, 488, 476, + 490, 487, 491, 491, 491, 491, 491, 491, + 491, 491, 491, 27, 491, 27, 27, 27, + 491, 491, 491, 491, 491, 491, 491, 491, + 491, 491, 491, 491, 491, 491, 491, 491, + 491, 491, 27, 491, 491, 491, 491, 28, + 29, 491, 30, 491, 31, 32, 33, 34, + 35, 28, 491, 491, 491, 491, 491, 491, + 491, 491, 491, 491, 36, 491, 37, 33, + 38, 39, 491, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 40, 41, 33, + 42, 26, 491, 26, 26, 26, 26, 26, + 26, 26, 26, 43, 26, 26, 26, 26, + 26, 26, 26, 26, 44, 26, 26, 45, + 26, 46, 26, 26, 26, 47, 48, 491, + 42, 491, 26, 55, 487, 492, 487, 493, + 487, 494, 487, 495, 94, 94, 94, 495, + 94, 94, 94, 94, 496, 94, 496, 496, + 496, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 495, 94, 94, + 94, 94, 94, 496, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 94, 497, + 94, 94, 96, 94, 96, 96, 96, 100, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 94, 94, + 94, 94, 94, 96, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 498, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 94, 93, + 93, 93, 93, 498, 93, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 93, + 93, 93, 93, 96, 93, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 93, + 93, 93, 93, 93, 96, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 97, 499, + 97, 97, 97, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 97, 499, 499, + 499, 499, 499, 499, 499, 98, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 499, 99, 499, 499, 96, 499, 96, 96, + 96, 100, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 499, 499, 499, 499, 499, 96, 500, 499, + 499, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, + 498, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 94, 499, 499, 499, 499, 498, 499, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 499, 499, 499, 499, 96, 499, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 501, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 499, 499, 499, 499, 499, 96, + 101, 499, 503, 502, 502, 502, 503, 502, + 502, 502, 502, 504, 502, 504, 504, 504, + 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 503, 502, 502, 502, + 502, 502, 504, 502, 502, 505, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 506, 502, + 502, 502, 502, 502, 502, 502, 507, 502, + 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 508, 502, 504, + 509, 504, 504, 504, 509, 509, 509, 509, + 509, 509, 509, 509, 509, 509, 509, 509, + 509, 509, 509, 509, 509, 509, 504, 509, + 510, 511, 512, 513, 515, 514, 516, 517, + 514, 518, 520, 521, 521, 521, 520, 521, + 521, 521, 521, 522, 523, 522, 522, 522, + 521, 521, 521, 521, 521, 521, 521, 521, + 521, 521, 521, 521, 520, 521, 521, 521, + 521, 521, 522, 521, 521, 524, 521, 521, + 521, 521, 521, 521, 521, 521, 521, 521, + 521, 521, 521, 521, 521, 521, 521, 521, + 521, 521, 521, 521, 521, 521, 521, 521, + 521, 521, 521, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 521, 525, 521, + 521, 519, 521, 519, 519, 519, 519, 519, + 519, 519, 519, 526, 519, 519, 519, 519, + 519, 519, 519, 519, 527, 519, 519, 528, + 519, 529, 519, 519, 519, 521, 521, 521, + 521, 521, 519, 530, 530, 530, 530, 530, + 530, 530, 530, 530, 530, 530, 530, 530, + 530, 530, 530, 530, 530, 530, 530, 530, + 530, 530, 530, 530, 530, 530, 530, 530, + 530, 530, 530, 530, 530, 530, 530, 530, + 530, 530, 530, 530, 530, 530, 530, 530, + 530, 530, 530, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 530, 530, 530, + 530, 530, 530, 530, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 530, 530, + 530, 530, 519, 530, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 530, 530, + 530, 530, 530, 519, 522, 531, 522, 522, + 522, 531, 531, 531, 531, 531, 531, 531, + 531, 531, 531, 531, 531, 531, 531, 531, + 531, 531, 531, 522, 531, 532, 533, 534, + 535, 536, 538, 537, 539, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 540, + 540, 540, 540, 540, 540, 540, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 540, 540, 540, 540, 519, 540, 519, 519, + 519, 519, 519, 541, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 540, 540, 540, 540, 540, 519, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 540, 540, 540, 540, 540, 540, 540, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 540, 540, 540, 540, 519, 540, 519, + 519, 519, 519, 542, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 540, 540, 540, 540, 540, 519, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 540, 540, 540, 540, 540, 540, 540, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 540, 540, 540, 540, 519, 540, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 543, 519, 519, 519, 519, 519, + 519, 519, 540, 540, 540, 540, 540, 519, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 540, 540, 540, 540, 540, 540, + 540, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 540, 540, 540, 540, 519, + 540, 519, 519, 544, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 540, 540, 540, 540, 540, + 519, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 540, 540, 540, 540, 540, + 540, 540, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 540, 540, 540, 540, + 519, 540, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 545, 519, + 519, 519, 519, 519, 540, 540, 540, 540, + 540, 519, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 540, 540, 540, 540, + 540, 540, 540, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 540, 540, 540, + 540, 519, 540, 519, 519, 519, 519, 541, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 540, 540, 540, + 540, 540, 519, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 540, 540, 540, + 540, 540, 540, 540, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 540, 540, + 540, 540, 519, 540, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 546, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 540, 540, + 540, 540, 540, 519, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 540, 540, + 540, 540, 540, 540, 540, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 540, + 540, 540, 540, 519, 540, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 547, 519, 519, 519, 519, 519, 519, 519, + 548, 519, 519, 519, 519, 519, 519, 540, + 540, 540, 540, 540, 519, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 540, + 540, 540, 540, 540, 540, 540, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 540, 540, 540, 540, 519, 540, 519, 519, + 519, 519, 549, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 540, 540, 540, 540, 540, 519, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 540, 540, 540, 540, 540, 540, 540, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 540, 540, 540, 540, 519, 540, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 550, 519, 519, 519, 519, 519, 519, + 519, 540, 540, 540, 540, 540, 519, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 540, 540, 540, 540, 540, 540, 540, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 540, 540, 540, 540, 519, 540, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 541, 519, 519, 519, 519, 519, + 519, 519, 540, 540, 540, 540, 540, 519, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 540, 540, 540, 540, 540, 540, + 540, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 540, 540, 540, 540, 519, + 540, 519, 519, 519, 519, 519, 519, 519, + 519, 551, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 540, 540, 540, 540, 540, + 519, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 540, 540, 540, 540, 540, + 540, 540, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 540, 540, 540, 540, + 519, 540, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 541, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 540, 540, 540, 540, + 540, 519, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 540, 540, 540, 540, + 540, 540, 540, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 540, 540, 540, + 540, 519, 540, 519, 519, 519, 519, 519, + 519, 519, 552, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 540, 540, 540, + 540, 540, 519, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 540, 540, 540, + 540, 540, 540, 540, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 540, 540, + 540, 540, 519, 540, 519, 519, 519, 519, + 519, 519, 519, 519, 553, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 540, 540, + 540, 540, 540, 519, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 540, 540, + 540, 540, 540, 540, 540, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 540, + 540, 540, 540, 519, 540, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 545, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 540, + 540, 540, 540, 540, 519, 555, 125, 125, + 125, 555, 125, 125, 125, 125, 556, 557, + 556, 556, 556, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 555, + 125, 125, 125, 125, 125, 556, 558, 125, + 559, 125, 560, 561, 125, 562, 125, 563, + 564, 125, 565, 566, 567, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 568, + 125, 569, 570, 571, 572, 125, 573, 574, + 573, 573, 575, 573, 573, 573, 573, 573, + 573, 573, 573, 573, 573, 573, 573, 573, + 573, 573, 573, 573, 573, 573, 573, 573, + 576, 577, 125, 578, 579, 125, 580, 581, + 582, 583, 584, 585, 554, 554, 586, 554, + 554, 554, 587, 588, 589, 554, 554, 590, + 591, 592, 593, 554, 594, 554, 595, 554, + 596, 597, 125, 578, 125, 554, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 598, 599, 599, 599, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 172, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 173, 598, 598, 174, 598, 172, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 600, 598, 598, 554, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 598, 598, 598, 598, 554, 602, + 601, 601, 603, 601, 604, 606, 607, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 608, 605, + 610, 609, 611, 612, 613, 556, 614, 556, + 556, 556, 614, 614, 614, 614, 614, 614, + 614, 614, 614, 614, 614, 614, 614, 614, + 614, 614, 614, 614, 556, 614, 616, 615, + 618, 619, 618, 618, 618, 617, 617, 617, + 617, 617, 617, 617, 617, 617, 617, 617, + 617, 617, 617, 617, 617, 617, 617, 618, + 617, 125, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 125, 620, 621, 622, 623, 624, + 626, 626, 626, 626, 626, 626, 626, 626, + 626, 626, 626, 626, 626, 626, 626, 626, + 626, 626, 626, 626, 626, 626, 626, 626, + 626, 626, 626, 626, 626, 626, 626, 626, + 626, 626, 626, 626, 626, 626, 626, 626, + 626, 626, 626, 626, 626, 626, 626, 626, + 625, 625, 625, 625, 625, 625, 625, 625, + 625, 625, 626, 626, 626, 626, 626, 626, + 626, 627, 627, 627, 627, 627, 627, 627, + 627, 627, 627, 627, 627, 627, 627, 627, + 627, 627, 627, 627, 627, 627, 627, 627, + 627, 627, 627, 626, 626, 626, 626, 626, + 626, 627, 627, 627, 627, 627, 627, 627, + 627, 627, 627, 627, 627, 627, 627, 627, + 627, 627, 627, 627, 627, 627, 627, 627, + 627, 627, 627, 626, 626, 626, 626, 626, + 625, 629, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 628, + 125, 628, 630, 632, 631, 631, 631, 631, + 631, 631, 631, 631, 631, 631, 631, 631, + 631, 631, 631, 631, 631, 631, 125, 631, + 125, 115, 126, 127, 126, 126, 126, 628, + 628, 628, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 628, + 628, 126, 628, 628, 128, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 628, + 628, 129, 129, 129, 129, 129, 129, 129, + 129, 129, 129, 628, 628, 628, 125, 628, + 628, 628, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 628, 628, 130, 628, 143, + 144, 143, 143, 143, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 143, 142, + 142, 145, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 147, 142, 126, 127, 126, 126, + 126, 628, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 126, 628, 628, 128, 628, + 628, 628, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 129, 129, 129, 129, 129, + 129, 129, 129, 129, 129, 628, 628, 628, + 125, 125, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 130, + 628, 634, 620, 636, 635, 638, 637, 620, + 639, 639, 639, 620, 639, 639, 639, 639, + 639, 639, 639, 639, 639, 639, 639, 639, + 639, 639, 639, 639, 639, 639, 639, 639, + 639, 620, 639, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 641, 642, 620, 643, + 151, 644, 642, 620, 620, 645, 646, 620, + 646, 620, 151, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 647, 620, 648, + 649, 650, 620, 651, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 652, 620, + 620, 151, 640, 151, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 620, 653, + 620, 654, 620, 640, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 656, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 655, 655, + 655, 657, 655, 656, 655, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 640, 655, + 655, 655, 655, 640, 655, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 640, 655, + 655, 655, 655, 655, 640, 659, 658, 660, + 662, 663, 661, 661, 661, 661, 661, 661, + 661, 661, 661, 661, 661, 661, 661, 661, + 661, 661, 661, 661, 661, 661, 661, 661, + 661, 661, 661, 661, 661, 661, 661, 661, + 661, 661, 661, 661, 661, 661, 661, 661, + 661, 661, 661, 661, 661, 661, 661, 661, + 661, 661, 661, 661, 661, 661, 661, 661, + 661, 661, 661, 661, 661, 661, 661, 661, + 661, 664, 661, 666, 667, 665, 668, 669, + 670, 671, 151, 655, 655, 672, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 151, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 655, + 655, 655, 655, 655, 655, 655, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, + 655, 655, 655, 655, 150, 655, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, + 655, 655, 655, 655, 655, 150, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, + 655, 673, 655, 151, 655, 151, 655, 151, + 674, 655, 151, 655, 151, 655, 151, 151, + 655, 675, 675, 675, 675, 675, 675, 675, + 675, 675, 675, 675, 675, 675, 675, 675, + 675, 675, 675, 675, 675, 675, 675, 675, + 675, 675, 675, 675, 675, 675, 675, 675, + 675, 675, 675, 675, 675, 675, 675, 675, + 675, 675, 675, 675, 675, 675, 675, 675, + 675, 677, 677, 677, 677, 677, 677, 677, + 677, 677, 677, 675, 675, 675, 675, 675, + 675, 678, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 675, 675, 675, 675, + 676, 675, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 675, 675, 675, 675, + 675, 676, 680, 680, 680, 680, 680, 680, + 680, 680, 680, 680, 679, 681, 681, 681, + 681, 681, 681, 681, 681, 681, 681, 681, + 681, 681, 681, 681, 681, 681, 681, 681, + 681, 681, 681, 681, 681, 681, 681, 681, + 681, 681, 681, 681, 681, 681, 681, 681, + 681, 681, 681, 681, 681, 681, 681, 681, + 681, 681, 681, 681, 681, 683, 683, 683, + 683, 683, 683, 683, 683, 683, 683, 681, + 681, 681, 681, 681, 681, 681, 682, 682, + 682, 682, 682, 682, 682, 682, 682, 682, + 682, 682, 682, 682, 682, 682, 682, 682, + 682, 682, 682, 682, 682, 682, 682, 682, + 681, 681, 681, 681, 682, 681, 682, 682, + 682, 682, 682, 682, 682, 682, 682, 682, + 682, 682, 682, 682, 682, 682, 682, 682, + 682, 682, 682, 682, 682, 682, 682, 682, + 681, 681, 681, 681, 681, 682, 673, 655, + 672, 655, 684, 685, 620, 686, 166, 156, + 156, 156, 156, 156, 156, 156, 156, 156, + 156, 156, 156, 156, 156, 156, 156, 156, + 156, 156, 156, 156, 156, 156, 167, 156, + 168, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 167, 157, 167, + 170, 125, 620, 578, 125, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 125, 620, 125, 629, + 620, 690, 689, 689, 689, 690, 689, 689, + 689, 689, 689, 689, 689, 689, 689, 689, + 689, 689, 689, 689, 689, 689, 689, 689, + 689, 689, 689, 690, 689, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 172, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 173, + 115, 115, 174, 115, 172, 115, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 115, 115, 115, 115, 171, 115, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 115, 115, 115, 115, 115, 171, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 172, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 173, 620, 620, 174, 620, 172, 620, 171, + 171, 171, 171, 691, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 620, 620, 620, 620, 171, 620, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 620, 620, 620, 620, 620, 171, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 172, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 173, 620, 620, 174, 620, 172, 620, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 692, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 620, 620, 620, 620, 171, 620, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 620, 620, 620, 620, 620, 171, + 693, 694, 620, 615, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 598, 599, + 599, 599, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 172, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 173, 598, + 598, 174, 598, 172, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 600, 598, 598, 695, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 598, 598, 598, 598, 554, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 598, + 599, 599, 599, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 172, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 173, + 598, 598, 174, 598, 172, 598, 554, 554, + 554, 554, 696, 697, 554, 554, 554, 554, + 554, 698, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 600, 598, 598, 554, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 598, 598, 598, 598, 554, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 598, 599, 599, 599, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 172, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 173, 598, 598, 174, 598, 172, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 699, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 600, 598, 598, 554, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 598, 598, 598, 598, 554, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 598, 599, 599, 599, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 172, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 173, 598, 598, 174, 598, 172, 598, + 554, 554, 700, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 600, 598, 598, 554, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 598, 598, 598, 598, 554, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 598, 599, 599, 599, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 172, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 173, 598, 598, 174, 598, 172, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 701, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 600, 598, 598, 554, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 598, 598, 598, 598, + 554, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 598, 599, 599, 599, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 172, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 173, 598, 598, 174, 598, + 172, 598, 554, 554, 554, 702, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 600, 598, 598, + 554, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 598, 598, 598, + 598, 554, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 598, 599, 599, 599, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 172, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 173, 598, 598, 174, + 598, 172, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 703, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 600, 598, + 598, 554, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 598, 598, + 598, 598, 554, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 598, 599, 599, + 599, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 172, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 173, 598, 598, + 174, 598, 172, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 704, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 600, + 598, 598, 554, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 598, + 598, 598, 598, 554, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 598, 599, + 599, 599, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 172, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 173, 598, + 598, 174, 598, 172, 598, 554, 554, 554, + 554, 554, 554, 705, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 600, 598, 598, 554, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 598, 598, 598, 598, 554, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 598, + 599, 599, 599, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 172, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 173, + 598, 598, 174, 598, 172, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 600, 598, 598, 706, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 598, 598, 598, 598, 554, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 598, 599, 599, 599, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 172, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 173, 598, 598, 174, 598, 172, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 600, 598, 598, 707, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 598, 598, 598, 598, 554, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 172, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 173, 115, 115, 174, 115, 172, 115, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 115, 115, 115, 115, 554, 115, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 115, 115, 115, 115, 115, 554, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 598, 599, 599, 599, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 172, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 173, 598, 598, 174, 598, 172, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 708, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 600, 598, 598, 554, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 598, 598, 598, 598, + 554, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 598, 599, 599, 599, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 172, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 173, 598, 598, 174, 598, + 172, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 709, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 600, 598, 598, + 554, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 598, 598, 598, + 598, 554, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 598, 599, 599, 599, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 172, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 173, 598, 598, 174, + 598, 172, 598, 554, 554, 554, 554, 705, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 600, 598, + 598, 554, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 598, 598, + 598, 598, 554, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 598, 599, 599, + 599, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 172, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 173, 598, 598, + 174, 598, 172, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 710, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 600, + 598, 598, 554, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 598, + 598, 598, 598, 554, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 598, 599, + 599, 599, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 172, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 173, 598, + 598, 174, 598, 172, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 709, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 600, 598, 598, 554, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 598, 598, 598, 598, 554, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 598, + 599, 599, 599, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 172, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 173, + 598, 598, 174, 598, 172, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 600, 598, 598, 554, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 711, 554, 712, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 598, 598, 598, 598, 554, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 598, 599, 599, 599, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 172, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 173, 598, 598, 174, 598, 172, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 600, 598, 598, 554, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 713, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 598, 598, 598, 598, 554, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 598, 599, 599, 599, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 172, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 173, 598, 598, 174, 598, 172, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 600, 598, 598, 554, 598, + 714, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 598, 598, 598, 598, 554, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 598, 599, 599, 599, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 172, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 173, 598, 598, 174, 598, 172, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 600, 598, 598, 554, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 707, 554, 554, 554, 554, + 554, 554, 554, 598, 598, 598, 598, 598, + 554, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 598, 599, 599, 599, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 172, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 173, 598, 598, 174, 598, + 172, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 600, 598, 598, + 554, 598, 554, 554, 554, 707, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 598, 598, 598, + 598, 554, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 598, 599, 599, 599, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 172, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 173, 598, 598, 174, + 598, 172, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 600, 598, + 598, 554, 598, 554, 554, 554, 554, 715, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 716, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 598, 598, + 598, 598, 554, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 598, 599, 599, + 599, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 172, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 173, 598, 598, + 174, 598, 172, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 600, + 598, 598, 554, 598, 554, 554, 554, 554, + 554, 554, 717, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 598, + 598, 598, 598, 554, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 598, 599, + 599, 599, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 172, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 173, 598, + 598, 174, 598, 172, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 600, 598, 598, 554, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 718, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 598, 598, 598, 598, 554, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 598, + 599, 599, 599, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 172, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 173, + 598, 598, 174, 598, 172, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 600, 598, 598, 554, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 707, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 598, 598, 598, 598, 554, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 598, 599, 599, 599, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 172, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 173, 598, 598, 174, 598, 172, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 600, 598, 598, 554, 598, 554, + 554, 554, 554, 719, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 598, 598, 598, 598, 554, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 598, 599, 599, 599, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 172, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 173, 598, 598, 174, 598, 172, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 600, 598, 598, 554, 598, + 720, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 598, 598, 598, 598, 554, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 598, 599, 599, 599, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 172, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 173, 598, 598, 174, 598, 172, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 600, 598, 598, 554, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 707, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 598, 598, 598, 598, + 554, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 598, 599, 599, 599, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 172, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 173, 598, 598, 174, 598, + 172, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 600, 598, 598, + 554, 598, 721, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 722, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 598, 598, 598, + 598, 554, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 598, 599, 599, 599, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 172, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 173, 598, 598, 174, + 598, 172, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 600, 598, + 598, 554, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 723, 554, 554, + 554, 554, 554, 554, 554, 598, 598, 598, + 598, 598, 554, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 598, 599, 599, + 599, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 172, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 173, 598, 598, + 174, 598, 172, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 600, + 598, 598, 554, 598, 554, 554, 554, 554, + 707, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 598, + 598, 598, 598, 554, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 598, 599, + 599, 599, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 172, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 173, 598, + 598, 174, 598, 172, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 600, 598, 598, 554, 598, 724, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 598, 598, 598, 598, 554, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 598, + 599, 599, 599, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 172, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 173, + 598, 598, 174, 598, 172, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 600, 598, 598, 554, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 714, 554, 554, 554, 554, 554, 554, 554, + 598, 598, 598, 598, 598, 554, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 598, 599, 599, 599, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 172, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 173, 598, 598, 174, 598, 172, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 600, 598, 598, 554, 598, 554, + 554, 554, 554, 725, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 707, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 598, 598, 598, 598, 554, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 598, 599, 599, 599, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 172, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 173, 598, 598, 174, 598, 172, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 600, 598, 598, 554, 598, + 554, 554, 554, 554, 554, 707, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 598, 598, 598, 598, 554, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 598, 599, 599, 599, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 172, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 173, 598, 598, 174, 598, 172, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 600, 598, 598, 554, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 726, 554, 727, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 598, 598, 598, 598, + 554, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 598, 599, 599, 599, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 172, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 173, 598, 598, 174, 598, + 172, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 600, 598, 598, + 554, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 728, 554, 554, 554, + 554, 554, 554, 554, 598, 598, 598, 598, + 598, 554, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 598, 599, 599, 599, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 172, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 173, 598, 598, 174, + 598, 172, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 600, 598, + 598, 554, 598, 554, 554, 554, 554, 707, + 554, 554, 554, 725, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 598, 598, + 598, 598, 554, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 598, 599, 599, + 599, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 172, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 173, 598, 598, + 174, 598, 172, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 600, + 598, 598, 554, 598, 554, 554, 554, 707, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 729, 554, + 554, 554, 554, 554, 554, 554, 598, 598, + 598, 598, 598, 554, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 598, 599, + 599, 599, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 172, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 173, 598, + 598, 174, 598, 172, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 600, 598, 598, 554, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 730, 554, 554, 554, 554, 554, 598, + 598, 598, 598, 598, 554, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 598, + 599, 599, 599, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 172, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 173, + 598, 598, 174, 598, 172, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 600, 598, 598, 554, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 723, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 598, 598, 598, 598, 554, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 598, 599, 599, 599, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 172, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 173, 598, 598, 174, 598, 172, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 600, 598, 598, 554, 598, 731, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 589, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 598, 598, 598, 598, 554, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 598, 599, 599, 599, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 172, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 173, 598, 598, 174, 598, 172, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 600, 598, 598, 554, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 721, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 598, 598, 598, 598, 554, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 598, 599, 599, 599, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 172, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 173, 598, 598, 174, 598, 172, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 600, 598, 598, 554, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 707, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 598, 598, 598, 598, + 554, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 598, 599, 599, 599, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 172, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 173, 598, 598, 174, 598, + 172, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 600, 598, 598, + 554, 598, 554, 554, 554, 554, 554, 732, + 554, 554, 554, 554, 554, 554, 554, 707, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 598, 598, 598, + 598, 554, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 598, 599, 599, 599, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 172, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 173, 598, 598, 174, + 598, 172, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 600, 598, + 598, 554, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 733, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 598, 598, + 598, 598, 554, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 598, 599, 599, + 599, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 172, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 173, 598, 598, + 174, 598, 172, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 600, + 598, 598, 554, 598, 554, 554, 554, 734, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 598, + 598, 598, 598, 554, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 598, 599, + 599, 599, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 172, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 173, 598, + 598, 174, 598, 172, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 600, 598, 598, 554, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 735, 554, 554, 554, 554, 554, 598, + 598, 598, 598, 598, 554, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 598, + 599, 599, 599, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 172, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 173, + 598, 598, 174, 598, 172, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 600, 598, 598, 554, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 723, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 598, 598, 598, 598, 554, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 598, 599, 599, 599, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 172, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 173, 598, 598, 174, 598, 172, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 600, 598, 598, 554, 598, 554, + 554, 554, 554, 736, 554, 554, 554, 737, + 554, 554, 554, 554, 554, 738, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 598, 598, 598, 598, 554, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 598, 599, 599, 599, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 172, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 173, 598, 598, 174, 598, 172, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 600, 598, 598, 554, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 738, + 554, 554, 598, 598, 598, 598, 598, 554, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 598, 599, 599, 599, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 172, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 173, 598, 598, 174, 598, 172, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 600, 598, 598, 554, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 707, 554, 554, 554, + 554, 554, 554, 598, 598, 598, 598, 598, + 554, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 598, 599, 599, 599, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 172, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 173, 598, 598, 174, 598, + 172, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 600, 598, 598, + 554, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 707, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 598, 598, 598, + 598, 554, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 598, 599, 599, 599, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 172, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 173, 598, 598, 174, + 598, 172, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 600, 598, + 598, 554, 598, 554, 554, 554, 554, 739, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 598, 598, + 598, 598, 554, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 598, 599, 599, + 599, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 172, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 173, 598, 598, + 174, 598, 172, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 600, + 598, 598, 554, 598, 554, 554, 554, 740, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 741, 742, + 554, 554, 554, 554, 554, 554, 598, 598, + 598, 598, 598, 554, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 598, 599, + 599, 599, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 172, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 173, 598, + 598, 174, 598, 172, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 600, 598, 598, 554, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 707, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 598, 598, 598, 598, 554, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 598, + 599, 599, 599, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 172, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 173, + 598, 598, 174, 598, 172, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 600, 598, 598, 554, 598, 554, 554, + 743, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 598, 598, 598, 598, 554, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 598, 599, 599, 599, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 172, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 173, 598, 598, 174, 598, 172, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 600, 598, 598, 554, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 744, 554, 554, 554, 554, + 554, 598, 598, 598, 598, 598, 554, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 598, 599, 599, 599, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 172, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 173, 598, 598, 174, 598, 172, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 600, 598, 598, 554, 598, + 554, 554, 554, 554, 745, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 598, 598, 598, 598, 554, + 746, 746, 746, 746, 746, 746, 746, 746, + 746, 746, 746, 746, 746, 746, 746, 746, + 746, 746, 746, 746, 746, 746, 746, 746, + 746, 746, 746, 746, 746, 746, 746, 746, + 746, 748, 746, 746, 746, 746, 746, 746, + 746, 746, 746, 746, 746, 746, 746, 746, + 747, 747, 747, 747, 747, 747, 747, 747, + 747, 747, 749, 746, 746, 750, 746, 748, + 746, 747, 747, 747, 747, 747, 747, 747, + 747, 747, 747, 747, 747, 747, 747, 747, + 747, 747, 747, 747, 747, 747, 747, 747, + 747, 747, 747, 746, 746, 746, 746, 747, + 746, 747, 747, 747, 747, 747, 747, 747, + 747, 747, 747, 747, 747, 747, 747, 747, + 747, 747, 747, 747, 747, 747, 747, 747, + 747, 747, 747, 746, 746, 746, 746, 746, + 747, 606, 751, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 608, 605, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 598, 599, + 599, 599, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 172, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 173, 598, + 598, 174, 598, 172, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 600, 598, 598, 554, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 752, 554, + 554, 753, 554, 554, 554, 554, 554, 598, + 598, 598, 598, 598, 554, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 598, + 599, 599, 599, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 172, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 173, + 598, 598, 174, 598, 172, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 600, 598, 598, 554, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 707, 554, + 598, 598, 598, 598, 598, 554, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 598, 599, 599, 599, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 172, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 173, 598, 598, 174, 598, 172, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 600, 598, 598, 554, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 718, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 598, 598, 598, 598, 554, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 598, 599, 599, 599, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 172, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 173, 598, 598, 174, 598, 172, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 600, 598, 598, 554, 598, + 554, 554, 554, 554, 754, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 755, 554, 554, 554, + 554, 554, 598, 598, 598, 598, 598, 554, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 598, 599, 599, 599, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 172, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 173, 598, 598, 174, 598, 172, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 600, 598, 598, 554, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 725, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 598, 598, 598, 598, + 554, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 598, 599, 599, 599, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 172, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 173, 598, 598, 174, 598, + 172, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 600, 598, 598, + 554, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 756, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 598, 598, 598, + 598, 554, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 598, 599, 599, 599, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 172, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 173, 598, 598, 174, + 598, 172, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 600, 598, + 598, 554, 598, 554, 554, 554, 554, 589, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 598, 598, + 598, 598, 554, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 598, 599, 599, + 599, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 172, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 173, 598, 598, + 174, 598, 172, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 600, + 598, 598, 554, 598, 554, 554, 554, 554, + 554, 554, 554, 757, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 758, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 598, + 598, 598, 598, 554, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 598, 599, + 599, 599, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 172, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 173, 598, + 598, 174, 598, 172, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 600, 598, 598, 554, 598, 554, 554, 554, + 554, 718, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 598, 598, 598, 598, 554, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 598, + 599, 599, 599, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 172, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 173, + 598, 598, 174, 598, 172, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 600, 598, 598, 554, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 723, 554, 554, 554, 554, 554, + 598, 598, 598, 598, 598, 554, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 598, 599, 599, 599, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 172, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 173, 598, 598, 174, 598, 172, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 600, 598, 598, 554, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 759, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 598, 598, 598, 598, 554, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 598, 599, 599, 599, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 172, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 173, 598, 598, 174, 598, 172, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 600, 598, 598, 554, 598, + 554, 554, 554, 760, 554, 554, 554, 554, + 554, 554, 554, 761, 554, 554, 554, 554, + 554, 554, 554, 762, 554, 554, 554, 554, + 554, 554, 598, 598, 598, 598, 598, 554, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 598, 599, 599, 599, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 172, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 173, 598, 598, 174, 598, 172, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 600, 598, 598, 554, + 598, 554, 554, 554, 554, 725, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 598, 598, 598, 598, + 554, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 598, 599, 599, 599, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 172, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 173, 598, 598, 174, 598, + 172, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 600, 598, 598, + 554, 598, 554, 554, 554, 554, 763, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 598, 598, 598, + 598, 554, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 598, 599, 599, 599, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 172, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 173, 598, 598, 174, + 598, 172, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 600, 598, + 598, 554, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 764, 554, 554, + 554, 554, 554, 554, 554, 598, 598, 598, + 598, 598, 554, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 598, 599, 599, + 599, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 172, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 173, 598, 598, + 174, 598, 172, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 600, + 598, 598, 554, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 732, 554, + 554, 554, 554, 554, 554, 554, 598, 598, + 598, 598, 598, 554, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 598, 599, + 599, 599, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 172, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 173, 598, + 598, 174, 598, 172, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 600, 598, 598, 554, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 765, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 598, 598, 598, 598, 554, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 598, + 599, 599, 599, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 172, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 173, + 598, 598, 174, 598, 172, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 600, 598, 598, 554, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 732, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 598, 598, 598, 598, 554, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 598, 599, 599, 599, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 172, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 173, 598, 598, 174, 598, 172, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 600, 598, 598, 554, 598, 554, + 554, 554, 554, 554, 554, 554, 766, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 598, 598, 598, 598, 554, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 598, 599, 599, 599, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 172, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 173, 598, 598, 174, 598, 172, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 600, 598, 598, 554, 598, + 554, 554, 554, 554, 718, 554, 554, 554, + 767, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 598, 598, 598, 598, 554, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 598, 599, 599, 599, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 172, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 173, 598, 598, 174, 598, 172, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 600, 598, 598, 554, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 768, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 598, 598, 598, 598, + 554, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 598, 599, 599, 599, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 172, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 173, 598, 598, 174, 598, + 172, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 600, 598, 598, + 554, 598, 554, 554, 554, 554, 732, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 598, 598, 598, + 598, 554, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 598, 599, 599, 599, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 172, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 173, 598, 598, 174, + 598, 172, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 600, 598, + 598, 554, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 769, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 598, 598, + 598, 598, 554, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 598, 599, 599, + 599, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 172, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 173, 598, 598, + 174, 598, 172, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 600, + 598, 598, 554, 598, 554, 554, 554, 554, + 770, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 598, + 598, 598, 598, 554, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 598, 599, + 599, 599, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 172, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 173, 598, + 598, 174, 598, 172, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 600, 598, 598, 554, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 712, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 598, 598, 598, 598, 554, 771, 125, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 772, 620, 774, + 773, 773, 773, 774, 773, 773, 773, 773, + 775, 776, 775, 775, 775, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, + 773, 774, 773, 773, 773, 773, 773, 775, + 773, 773, 777, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 778, 773, 775, 779, 775, + 775, 775, 779, 779, 779, 779, 779, 779, + 779, 779, 779, 779, 779, 779, 779, 779, + 779, 779, 779, 779, 775, 779, 780, 781, + 782, 783, 784, 786, 785, 787, 789, 790, + 790, 790, 789, 790, 790, 790, 790, 791, + 792, 791, 791, 791, 790, 790, 790, 790, + 790, 790, 790, 790, 790, 790, 790, 790, + 789, 790, 790, 790, 790, 790, 791, 790, + 793, 794, 790, 790, 790, 793, 790, 790, + 790, 790, 790, 790, 790, 790, 790, 790, + 790, 790, 790, 790, 790, 790, 790, 790, + 790, 790, 790, 790, 790, 790, 790, 788, + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 790, 795, 790, 790, 788, 790, 788, + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 790, 790, 790, 790, 790, 788, 796, + 796, 796, 796, 796, 796, 796, 796, 796, + 796, 796, 796, 796, 796, 796, 796, 796, + 796, 796, 796, 796, 796, 796, 796, 796, + 796, 796, 796, 796, 796, 796, 796, 796, + 180, 796, 796, 796, 796, 796, 796, 796, + 796, 796, 796, 796, 796, 796, 796, 179, + 179, 179, 179, 179, 179, 179, 179, 179, + 179, 181, 796, 796, 796, 796, 180, 796, + 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 796, 796, 796, 796, 179, 796, + 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 796, 796, 796, 796, 796, 179, + 791, 797, 791, 791, 791, 797, 797, 797, + 797, 797, 797, 797, 797, 797, 797, 797, + 797, 797, 797, 797, 797, 797, 797, 791, + 797, 798, 799, 800, 801, 802, 803, 796, + 804, 806, 807, 807, 807, 806, 807, 807, + 807, 807, 808, 809, 808, 808, 808, 807, + 807, 807, 807, 807, 807, 807, 807, 807, + 807, 807, 807, 806, 807, 807, 807, 807, + 807, 808, 810, 811, 812, 813, 814, 815, + 811, 816, 817, 818, 814, 819, 820, 821, + 814, 822, 823, 823, 823, 823, 823, 823, + 823, 823, 823, 824, 825, 826, 827, 828, + 829, 830, 831, 832, 831, 831, 833, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 834, 835, 836, 814, + 837, 811, 838, 839, 840, 841, 842, 843, + 805, 805, 844, 805, 805, 805, 845, 846, + 847, 805, 805, 848, 849, 850, 851, 805, + 852, 805, 853, 805, 854, 855, 856, 857, + 807, 805, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 858, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 189, 189, 189, 189, + 189, 858, 189, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 189, 189, 189, + 189, 805, 189, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 189, 189, 189, + 189, 189, 805, 860, 859, 861, 808, 862, + 808, 808, 808, 862, 862, 862, 862, 862, + 862, 862, 862, 862, 862, 862, 862, 862, + 862, 862, 862, 862, 862, 808, 862, 863, + 865, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 865, 864, 866, 867, 868, 869, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 184, 184, 870, 184, 870, 184, 184, 870, + 870, 184, 184, 184, 871, 184, 184, 872, + 872, 872, 872, 872, 872, 872, 872, 872, + 872, 184, 184, 184, 184, 184, 184, 184, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 870, 184, 870, 870, 201, 184, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 870, 870, 870, 184, 870, 201, + 873, 873, 873, 873, 873, 873, 873, 873, + 873, 873, 873, 873, 873, 873, 873, 873, + 873, 873, 873, 873, 873, 873, 873, 873, + 873, 873, 873, 873, 873, 873, 873, 873, + 873, 873, 873, 873, 873, 873, 873, 873, + 873, 873, 873, 873, 873, 873, 873, 873, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 873, 873, 873, 873, 873, 873, + 873, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 873, 873, 873, 873, 201, + 873, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 873, 873, 873, 873, 873, + 201, 872, 872, 872, 872, 872, 872, 872, + 872, 872, 872, 873, 874, 189, 814, 875, + 875, 875, 875, 875, 875, 875, 876, 875, + 875, 875, 875, 875, 875, 875, 875, 875, + 875, 875, 875, 875, 875, 874, 875, 877, + 878, 814, 879, 879, 879, 879, 879, 879, + 879, 879, 879, 879, 879, 879, 879, 879, + 879, 879, 879, 879, 874, 879, 874, 880, + 875, 882, 881, 188, 188, 188, 188, 188, + 188, 188, 188, 188, 188, 881, 884, 883, + 885, 883, 188, 188, 188, 188, 188, 188, + 188, 188, 188, 188, 886, 886, 886, 886, + 886, 886, 886, 886, 886, 886, 886, 887, + 886, 886, 886, 886, 886, 886, 886, 886, + 886, 886, 886, 886, 886, 886, 886, 886, + 886, 886, 886, 886, 886, 886, 886, 886, + 886, 888, 886, 886, 886, 886, 886, 887, + 886, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 187, 886, 886, 886, 886, 886, + 886, 886, 886, 886, 886, 886, 886, 886, + 886, 886, 886, 886, 886, 886, 886, 886, + 886, 886, 886, 886, 886, 886, 886, 886, + 886, 886, 886, 886, 886, 886, 886, 886, + 186, 886, 890, 889, 891, 891, 891, 891, + 891, 891, 891, 891, 891, 891, 889, 889, + 889, 889, 889, 889, 889, 889, 892, 889, + 893, 894, 889, 889, 889, 889, 889, 889, + 889, 889, 889, 895, 889, 889, 889, 889, + 889, 889, 889, 889, 896, 889, 889, 889, + 889, 889, 889, 897, 889, 889, 892, 889, + 893, 894, 889, 889, 889, 898, 889, 889, + 889, 889, 889, 895, 889, 889, 899, 889, + 889, 889, 889, 889, 896, 889, 190, 190, + 190, 190, 190, 190, 190, 190, 190, 190, + 900, 900, 900, 900, 900, 900, 900, 900, + 900, 900, 900, 901, 900, 900, 900, 900, + 900, 900, 900, 900, 900, 900, 900, 900, + 900, 900, 900, 900, 900, 900, 900, 900, + 900, 900, 900, 900, 900, 902, 900, 900, + 900, 900, 900, 901, 900, 900, 900, 903, + 900, 900, 900, 900, 900, 900, 900, 900, + 904, 900, 905, 189, 905, 189, 189, 191, + 191, 191, 191, 191, 191, 191, 191, 191, + 191, 189, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 906, 906, 906, 906, + 906, 906, 906, 906, 906, 906, 906, 906, + 906, 906, 906, 906, 906, 906, 906, 906, + 906, 906, 906, 906, 906, 906, 906, 906, + 906, 906, 906, 906, 906, 906, 906, 906, + 906, 905, 906, 906, 906, 906, 906, 906, + 906, 906, 906, 907, 906, 909, 908, 910, + 912, 911, 911, 911, 913, 911, 914, 915, + 891, 891, 891, 891, 891, 891, 891, 891, + 891, 891, 889, 889, 889, 889, 889, 889, + 889, 889, 889, 889, 889, 889, 889, 889, + 889, 889, 889, 889, 889, 889, 889, 889, + 889, 889, 889, 889, 889, 889, 889, 889, + 889, 889, 889, 889, 889, 889, 889, 897, + 889, 889, 889, 889, 889, 889, 889, 889, + 889, 898, 889, 889, 889, 889, 889, 889, + 889, 889, 899, 889, 916, 916, 916, 916, + 916, 916, 916, 916, 916, 916, 889, 889, + 889, 889, 889, 889, 889, 889, 889, 889, + 889, 889, 889, 889, 889, 889, 889, 889, + 889, 889, 889, 889, 889, 889, 889, 889, + 889, 889, 889, 889, 889, 889, 889, 889, + 889, 889, 889, 917, 889, 889, 889, 889, + 889, 889, 889, 889, 889, 898, 889, 889, + 889, 889, 889, 889, 889, 889, 899, 889, + 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 920, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 921, 918, 918, 918, 918, 918, 918, + 918, 918, 922, 918, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 923, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 921, 918, 918, + 918, 918, 918, 918, 918, 918, 922, 918, + 921, 918, 918, 918, 918, 918, 918, 918, + 918, 922, 918, 925, 924, 926, 928, 927, + 927, 927, 929, 927, 931, 930, 932, 933, + 935, 935, 934, 934, 934, 934, 934, 934, + 934, 934, 934, 934, 934, 934, 934, 934, + 934, 934, 934, 934, 934, 934, 934, 934, + 934, 934, 934, 934, 934, 934, 934, 934, + 934, 934, 934, 934, 934, 934, 934, 934, + 934, 934, 934, 934, 934, 934, 934, 936, + 934, 934, 934, 934, 934, 934, 934, 934, + 934, 937, 934, 934, 934, 934, 934, 934, + 934, 934, 938, 934, 939, 939, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 940, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 921, 918, 918, + 918, 918, 918, 918, 918, 918, 922, 918, + 939, 939, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 923, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 921, 918, 918, 918, 918, 918, 918, + 918, 918, 922, 918, 942, 942, 942, 942, + 942, 942, 942, 942, 942, 942, 941, 941, + 941, 941, 941, 941, 941, 941, 941, 941, + 941, 941, 941, 941, 941, 941, 941, 941, + 941, 941, 941, 941, 941, 941, 941, 941, + 941, 941, 941, 941, 941, 941, 941, 941, + 941, 941, 941, 943, 941, 941, 941, 941, + 941, 941, 941, 941, 941, 944, 941, 941, + 941, 941, 941, 941, 941, 941, 945, 941, + 947, 947, 947, 947, 947, 947, 947, 947, + 947, 947, 946, 946, 946, 946, 946, 946, + 946, 946, 946, 946, 946, 946, 946, 946, + 946, 946, 946, 946, 946, 946, 946, 946, + 946, 946, 946, 946, 946, 946, 946, 946, + 946, 946, 946, 946, 946, 946, 946, 948, + 946, 946, 946, 946, 946, 946, 946, 946, + 946, 949, 946, 946, 946, 946, 946, 946, + 946, 946, 950, 946, 952, 952, 952, 952, + 952, 952, 952, 952, 952, 952, 951, 951, + 951, 951, 951, 951, 951, 952, 952, 952, + 952, 952, 952, 951, 951, 951, 951, 951, + 951, 951, 951, 951, 951, 951, 951, 951, + 951, 951, 951, 951, 951, 951, 951, 951, + 951, 951, 951, 953, 951, 952, 952, 952, + 952, 952, 952, 951, 951, 954, 951, 951, + 951, 951, 951, 951, 951, 951, 955, 951, + 956, 956, 956, 956, 956, 956, 956, 956, + 956, 956, 918, 918, 918, 918, 918, 918, + 918, 956, 956, 956, 956, 956, 956, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 957, + 918, 956, 956, 956, 956, 956, 956, 918, + 918, 921, 918, 918, 918, 918, 918, 918, + 918, 918, 922, 918, 956, 956, 956, 956, + 956, 956, 956, 956, 956, 956, 918, 918, + 918, 918, 918, 918, 918, 956, 956, 956, + 956, 956, 956, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 923, 918, 956, 956, 956, + 956, 956, 956, 918, 918, 921, 918, 918, + 918, 918, 918, 918, 918, 918, 922, 918, + 959, 958, 960, 960, 960, 960, 960, 960, + 960, 960, 960, 960, 958, 958, 958, 958, + 958, 958, 958, 958, 958, 958, 958, 961, + 958, 958, 958, 958, 958, 958, 958, 958, + 958, 958, 958, 958, 958, 958, 958, 958, + 958, 958, 958, 958, 958, 958, 958, 958, + 958, 962, 958, 958, 958, 958, 958, 961, + 958, 958, 958, 963, 958, 958, 958, 958, + 958, 958, 958, 958, 964, 958, 965, 965, + 965, 965, 965, 965, 965, 965, 965, 965, + 958, 958, 958, 958, 958, 958, 958, 958, + 958, 958, 958, 958, 958, 958, 958, 958, + 958, 958, 958, 958, 958, 958, 958, 958, + 958, 958, 958, 958, 958, 958, 958, 958, + 958, 958, 958, 958, 958, 966, 958, 958, + 958, 958, 958, 958, 958, 958, 958, 963, + 958, 958, 958, 958, 958, 958, 958, 958, + 964, 958, 967, 918, 968, 968, 968, 968, + 968, 968, 968, 968, 968, 968, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 969, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 970, 918, 918, 918, 918, + 918, 969, 918, 918, 918, 921, 918, 918, + 918, 918, 918, 918, 918, 918, 922, 918, + 968, 968, 968, 968, 968, 968, 968, 968, + 968, 968, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 923, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 921, 918, 918, 918, 918, 918, 918, + 918, 918, 922, 918, 876, 883, 814, 971, + 875, 865, 875, 972, 973, 883, 883, 883, + 883, 883, 883, 883, 883, 883, 883, 883, + 883, 883, 883, 883, 883, 883, 883, 883, + 883, 883, 883, 883, 883, 883, 883, 883, + 883, 883, 883, 883, 883, 883, 883, 883, + 883, 883, 883, 883, 883, 883, 883, 883, + 883, 883, 883, 883, 883, 883, 883, 883, + 883, 883, 883, 883, 883, 883, 883, 883, + 883, 883, 883, 883, 865, 883, 865, 875, + 865, 814, 875, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 870, 870, 870, + 870, 870, 870, 974, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 870, 870, + 870, 870, 201, 870, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 870, 870, + 870, 870, 870, 201, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 858, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 975, 189, + 189, 189, 189, 858, 189, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 189, + 189, 189, 189, 831, 189, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 189, + 189, 189, 189, 189, 831, 976, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 858, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 975, 977, 977, 977, 977, 858, 977, 831, + 831, 831, 831, 978, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 977, 977, 977, 977, 831, 977, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 977, 977, 977, 977, 977, 831, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 858, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 975, 977, 977, 977, 977, 858, 977, + 831, 831, 831, 831, 831, 831, 979, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 977, 977, 977, 977, 831, 977, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 977, 977, 977, 977, 977, 831, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 858, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 975, 977, 977, 977, 977, 858, + 977, 831, 831, 831, 831, 831, 831, 831, + 831, 980, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 977, 977, 977, 977, 831, + 977, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 977, 977, 977, 977, 977, + 831, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 858, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 975, 977, 977, 977, 977, + 858, 977, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 981, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 977, 977, 977, 977, + 831, 977, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 977, 977, 977, 977, + 977, 831, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 858, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 975, 977, 977, 977, + 977, 858, 977, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 982, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 977, 977, 977, + 977, 831, 977, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 977, 977, 977, + 977, 977, 831, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 858, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 975, 977, 977, + 977, 977, 858, 977, 831, 831, 831, 981, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 977, 977, + 977, 977, 831, 977, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 977, 977, + 977, 977, 977, 831, 983, 985, 984, 986, + 987, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 858, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 989, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 990, + 991, 805, 805, 805, 805, 805, 992, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 805, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 993, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 994, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 805, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 858, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 858, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 995, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 805, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 805, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 858, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 858, 988, 805, + 805, 805, 996, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 805, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 805, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 858, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 858, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 997, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 805, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 805, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 858, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 858, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 998, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 805, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 805, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 858, 988, 805, 805, 805, 805, 805, 805, + 999, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 805, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 1000, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 1001, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 1002, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 805, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 858, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 858, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 1003, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 805, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 805, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 858, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 858, 988, 805, + 805, 805, 805, 1004, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 805, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 805, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 858, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 858, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 1005, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 805, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 858, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 858, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 1006, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 805, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 858, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 1007, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 805, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 1003, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 805, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 1008, + 805, 1009, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 1010, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 805, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 858, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 858, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 805, 988, 1011, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 805, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 858, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 858, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 805, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 1012, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 805, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 858, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 858, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 805, 988, + 805, 805, 805, 1013, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 805, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 858, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 858, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 805, + 988, 805, 805, 805, 805, 1014, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 1015, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 805, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 858, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 805, 988, 805, 805, 805, 805, 805, 805, + 1016, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 805, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 1017, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 1013, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 805, 1018, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 805, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 858, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 858, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 805, 988, 1019, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 805, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 858, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 858, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 805, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 1020, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 805, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 858, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 858, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 805, 988, + 1021, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 1022, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 805, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 858, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 858, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 805, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 1023, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 805, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 858, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 805, 988, 805, 805, 805, 805, 1013, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 805, 988, 1024, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 1025, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 1026, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 805, 1027, 1027, 1027, + 1027, 1027, 1027, 1027, 1027, 1027, 203, 204, + 203, 203, 203, 1027, 1027, 1027, 1027, 1027, + 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, + 1027, 1027, 1027, 1027, 1027, 203, 858, 1027, + 205, 1027, 1027, 1027, 1027, 1027, 1027, 1027, + 1027, 1027, 1027, 1027, 1027, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 1027, + 1027, 206, 1027, 1027, 858, 1027, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 1027, 207, 1027, 1027, 805, 1027, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 1027, 1027, 1027, 1027, 1027, 805, 220, 221, + 220, 220, 220, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 220, 219, 219, + 222, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 225, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 224, 219, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 805, 805, + 1029, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 1030, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 805, 805, 1031, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 805, 1032, 1032, 1032, + 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, + 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, + 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, + 1032, 1032, 1032, 1032, 1032, 1032, 858, 1032, + 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, + 1032, 1032, 1032, 1032, 1032, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 1032, + 1032, 1032, 1032, 1032, 858, 1032, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 1032, 1032, 1032, 1032, 805, 1032, 805, 805, + 805, 805, 805, 805, 805, 805, 1033, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 1032, 1032, 1032, 1032, 1032, 805, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 858, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 858, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 805, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 1034, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 805, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 858, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 858, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 805, 988, + 805, 805, 805, 805, 1035, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 805, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 858, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 858, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 805, + 988, 805, 805, 805, 1036, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 805, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 1037, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 805, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 805, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 1038, 805, + 1039, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 1040, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 805, 1013, 805, 805, 805, 1041, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 805, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 858, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 858, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 805, 988, 805, 805, + 805, 805, 805, 1013, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 805, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 858, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 858, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 805, 988, 805, + 805, 805, 1006, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 1042, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 805, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 858, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 858, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 805, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 1043, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 805, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 858, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 858, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 805, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 1023, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 805, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 858, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 805, 988, 1044, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 847, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 805, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 1045, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 1046, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 805, 1006, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 805, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 858, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 858, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 805, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 1013, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 805, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 858, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 858, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 805, 988, 805, + 805, 805, 805, 805, 1047, 805, 805, 805, + 805, 805, 805, 805, 1013, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 805, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 858, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 858, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 805, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 1048, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 805, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 858, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 858, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 805, + 988, 805, 805, 805, 1049, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 805, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 858, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 805, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 1050, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 805, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 1023, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 805, 805, + 1051, 805, 805, 805, 1052, 805, 805, 805, + 805, 805, 1053, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 1054, 805, 805, 988, + 988, 988, 988, 988, 805, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 858, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 858, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 805, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 1020, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 805, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 858, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 858, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 805, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 1006, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 805, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 858, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 858, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 805, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 1055, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 805, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 858, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 858, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 805, + 988, 805, 805, 805, 805, 1056, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 805, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 858, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 805, 988, 805, 805, 805, 1057, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 1058, 1059, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 805, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 1006, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 1060, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 1061, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 805, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 858, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 858, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 805, 988, 805, 805, + 805, 805, 1047, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 805, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 858, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 858, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 805, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 1062, 805, 805, 1063, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 805, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 858, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 858, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 805, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 1006, 805, 988, 988, 988, 988, 988, 805, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 858, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 858, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 805, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 1064, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 805, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 858, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 805, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 1020, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 805, 988, 805, 805, 805, 805, 1065, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 1066, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 1067, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 805, 805, 1006, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 805, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 858, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 858, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 805, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 1068, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 805, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 858, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 858, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 805, 988, 805, + 805, 805, 805, 1069, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 805, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 858, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 858, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 805, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 1055, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 805, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 858, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 858, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 805, + 988, 805, 805, 805, 805, 805, 805, 805, + 1070, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 1071, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 805, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 858, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 805, 988, 805, 805, 805, 805, 1017, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 805, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 1046, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 1072, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 1073, 805, 805, 805, 805, 805, 805, 805, + 1074, 805, 805, 805, 805, 805, 805, 805, + 1075, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 805, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 858, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 858, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 805, 988, 805, 805, + 805, 805, 1076, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 805, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 858, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 858, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 805, 988, 805, + 805, 805, 805, 805, 1012, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 805, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 858, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 858, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 805, 988, + 805, 805, 805, 805, 1077, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 805, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 858, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 858, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 805, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 1078, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 805, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 858, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 805, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 1047, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 805, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 1079, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 1047, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 805, 805, 805, 805, 1080, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 805, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 858, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 858, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 805, 988, 805, 805, + 805, 805, 1017, 805, 805, 805, 1081, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 805, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 858, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 858, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 805, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 1082, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 805, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 858, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 858, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 805, 988, + 805, 805, 805, 805, 1047, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 805, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 858, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 858, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 805, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 1083, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 805, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 858, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 805, 988, 805, 805, 805, 805, 1084, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 805, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 1085, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 805, 1055, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 1086, 874, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 814, 864, 1087, 1089, + 1088, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, + 1088, 1088, 1088, 1088, 1088, 1088, 1089, 1088, + 1088, 1090, 1088, 1088, 1091, 1088, 1088, 1088, + 1088, 1088, 1088, 1088, 233, 1088, 1088, 1088, + 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, + 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, + 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, + 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, + 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, + 1088, 1088, 1092, 1088, 229, 230, 229, 229, + 229, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 229, 1093, 1093, 231, 1093, + 1093, 232, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 233, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 234, + 1093, 236, 1094, 236, 236, 236, 1094, 1094, + 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, + 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, + 236, 1094, 1094, 231, 1094, 1094, 1094, 1094, + 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, + 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, + 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, + 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, + 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, + 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, + 1094, 1094, 1094, 1094, 234, 1094, 1096, 1095, + 1098, 1097, 239, 238, 244, 1093, 242, 1093, + 1100, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1101, 1099, 1100, 1099, 1100, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1103, 1099, 1100, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1104, 1099, 1100, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1105, 1099, 1107, 1105, + 1109, 1108, 1108, 1108, 1109, 1108, 1108, 1108, + 1108, 1110, 1111, 1110, 1110, 1110, 1108, 1108, + 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, + 1108, 1108, 1109, 1108, 1108, 1108, 1108, 1108, + 1110, 1108, 1108, 1112, 1108, 1108, 1108, 1108, + 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, + 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, + 1108, 1108, 1108, 1108, 1108, 1113, 1108, 1108, + 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, + 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, + 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, + 1108, 1108, 1108, 1108, 1114, 1108, 1108, 1115, + 1108, 1110, 1116, 1110, 1110, 1110, 1116, 1116, + 1116, 1116, 1116, 1116, 1116, 1116, 1116, 1116, + 1116, 1116, 1116, 1116, 1116, 1116, 1116, 1116, + 1110, 1116, 1117, 1118, 1119, 1120, 1121, 1123, + 1122, 1125, 1126, 1125, 1125, 1125, 1124, 1124, + 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, + 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, + 1125, 1124, 1111, 1122, 1127, 1122, 0 +] + +class << self + attr_accessor :_lex_trans_targs + private :_lex_trans_targs, :_lex_trans_targs= +end +self._lex_trans_targs = [ + 130, 129, 0, 2, 131, 132, 4, 133, + 134, 134, 134, 134, 247, 7, 8, 9, + 247, 247, 276, 11, 12, 276, 276, 280, + 280, 16, 11, 17, 278, 279, 281, 282, + 280, 276, 283, 284, 286, 13, 14, 287, + 288, 15, 280, 18, 19, 24, 31, 290, + 291, 17, 278, 279, 281, 282, 280, 276, + 283, 284, 286, 13, 14, 287, 288, 15, + 18, 19, 24, 31, 290, 291, 289, 20, + 21, 22, 23, 25, 26, 29, 27, 28, + 30, 32, 33, 276, 35, 36, 37, 39, + 42, 40, 41, 43, 45, 307, 307, 307, + 308, 47, 310, 48, 311, 49, 308, 47, + 310, 48, 311, 345, 50, 345, 51, 52, + 50, 345, 51, 345, 345, 345, 55, 56, + 57, 58, 356, 345, 345, 345, 61, 62, + 63, 345, 66, 61, 62, 63, 345, 66, + 64, 64, 62, 63, 366, 65, 64, 64, + 62, 63, 366, 65, 62, 345, 383, 345, + 68, 384, 390, 72, 399, 400, 77, 78, + 72, 73, 398, 73, 398, 345, 74, 75, + 76, 401, 79, 80, 347, 53, 349, 82, + 83, 406, 508, 85, 86, 87, 508, 516, + 516, 516, 90, 538, 537, 516, 540, 542, + 516, 95, 96, 97, 546, 516, 99, 100, + 557, 526, 579, 103, 104, 105, 109, 110, + 103, 104, 105, 109, 110, 106, 106, 104, + 105, 107, 108, 106, 106, 104, 105, 107, + 108, 627, 104, 516, 696, 111, 698, 113, + 117, 699, 115, 696, 112, 696, 114, 698, + 114, 698, 116, 698, 696, 710, 119, 120, + 121, 716, 123, 124, 125, 126, 127, 710, + 710, 128, 1, 3, 129, 129, 129, 135, + 134, 134, 136, 137, 138, 139, 141, 144, + 145, 146, 147, 134, 148, 149, 151, 153, + 154, 155, 159, 161, 162, 163, 179, 184, + 191, 196, 203, 210, 213, 214, 218, 212, + 222, 230, 234, 236, 241, 243, 246, 134, + 134, 134, 134, 134, 134, 140, 134, 140, + 134, 142, 5, 143, 134, 6, 134, 134, + 150, 152, 134, 156, 157, 158, 154, 160, + 134, 164, 165, 174, 177, 166, 167, 168, + 169, 170, 171, 172, 173, 135, 175, 176, + 178, 180, 183, 181, 182, 185, 188, 186, + 187, 189, 190, 192, 194, 193, 195, 197, + 198, 134, 199, 200, 201, 202, 134, 204, + 207, 205, 206, 208, 209, 211, 215, 216, + 217, 219, 221, 220, 223, 224, 225, 227, + 226, 228, 229, 231, 232, 233, 235, 237, + 238, 239, 240, 242, 244, 245, 248, 247, + 247, 249, 250, 252, 253, 247, 247, 247, + 251, 247, 251, 10, 254, 247, 256, 255, + 255, 259, 260, 261, 262, 255, 264, 265, + 266, 267, 269, 271, 272, 273, 274, 275, + 255, 257, 255, 258, 255, 255, 255, 255, + 255, 263, 255, 263, 268, 255, 270, 255, + 276, 276, 277, 292, 293, 279, 295, 296, + 283, 297, 298, 299, 300, 301, 303, 304, + 305, 306, 276, 276, 276, 276, 276, 276, + 280, 285, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 294, 276, 294, 276, 276, + 276, 276, 302, 276, 34, 38, 44, 307, + 309, 312, 46, 307, 307, 308, 313, 313, + 314, 315, 317, 319, 320, 313, 313, 316, + 313, 316, 313, 318, 313, 313, 313, 322, + 321, 321, 323, 324, 325, 327, 329, 330, + 335, 342, 321, 321, 321, 321, 326, 321, + 326, 321, 328, 321, 321, 322, 331, 332, + 333, 334, 336, 337, 340, 338, 339, 341, + 343, 344, 346, 345, 354, 355, 357, 358, + 360, 361, 362, 363, 365, 367, 368, 371, + 372, 397, 403, 404, 405, 406, 407, 408, + 409, 410, 364, 412, 429, 434, 441, 446, + 448, 454, 457, 458, 462, 456, 466, 477, + 481, 484, 492, 496, 499, 500, 345, 50, + 51, 345, 53, 348, 345, 345, 350, 352, + 353, 345, 351, 345, 345, 345, 345, 345, + 54, 345, 345, 345, 345, 345, 359, 345, + 359, 345, 345, 59, 345, 60, 345, 345, + 364, 345, 369, 345, 370, 345, 345, 345, + 373, 382, 345, 67, 385, 386, 387, 345, + 388, 69, 391, 392, 70, 395, 396, 345, + 374, 376, 345, 375, 345, 345, 377, 380, + 381, 345, 378, 379, 345, 345, 345, 345, + 345, 345, 389, 345, 383, 393, 394, 345, + 393, 345, 383, 393, 71, 402, 345, 345, + 345, 345, 345, 81, 84, 345, 411, 413, + 414, 424, 427, 415, 416, 417, 418, 419, + 420, 421, 422, 423, 425, 426, 428, 430, + 433, 431, 432, 435, 438, 436, 437, 439, + 440, 442, 444, 443, 445, 447, 449, 451, + 450, 452, 453, 455, 423, 459, 460, 461, + 463, 465, 464, 467, 468, 469, 474, 470, + 471, 472, 345, 346, 347, 53, 473, 352, + 475, 476, 478, 479, 480, 482, 483, 485, + 486, 487, 490, 488, 489, 491, 493, 494, + 495, 497, 498, 345, 364, 501, 501, 502, + 503, 504, 506, 501, 501, 501, 505, 501, + 505, 501, 507, 501, 509, 508, 508, 510, + 511, 508, 512, 514, 508, 508, 508, 508, + 513, 508, 513, 515, 508, 517, 516, 516, + 520, 521, 522, 516, 523, 525, 528, 529, + 530, 531, 532, 516, 533, 534, 539, 567, + 571, 516, 572, 574, 576, 516, 577, 578, + 580, 584, 586, 587, 589, 590, 608, 613, + 620, 628, 635, 642, 647, 648, 652, 646, + 657, 667, 673, 676, 685, 689, 693, 694, + 695, 528, 518, 516, 519, 516, 516, 516, + 516, 516, 516, 524, 516, 524, 516, 88, + 527, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 535, 516, 536, 516, 516, 89, + 91, 516, 92, 548, 559, 562, 541, 563, + 564, 549, 553, 555, 516, 541, 92, 543, + 545, 93, 516, 543, 516, 544, 516, 516, + 94, 547, 516, 516, 550, 552, 516, 550, + 551, 553, 555, 552, 516, 554, 516, 516, + 556, 558, 516, 98, 516, 516, 516, 560, + 552, 553, 555, 560, 561, 516, 550, 552, + 553, 555, 516, 550, 552, 553, 555, 516, + 565, 552, 553, 555, 565, 566, 516, 92, + 567, 541, 568, 553, 555, 569, 552, 92, + 569, 541, 570, 573, 575, 516, 101, 102, + 516, 516, 581, 582, 583, 578, 585, 516, + 516, 588, 516, 516, 516, 591, 592, 601, + 606, 593, 594, 595, 596, 597, 598, 599, + 600, 517, 602, 603, 604, 605, 517, 607, + 609, 612, 610, 611, 517, 517, 614, 617, + 615, 616, 618, 619, 517, 621, 623, 622, + 624, 625, 626, 516, 516, 629, 517, 630, + 516, 631, 632, 633, 634, 518, 636, 639, + 637, 638, 640, 641, 643, 644, 645, 517, + 649, 650, 651, 653, 655, 656, 654, 517, + 658, 659, 660, 663, 661, 662, 664, 665, + 666, 668, 670, 669, 671, 672, 674, 675, + 677, 678, 680, 683, 679, 681, 682, 684, + 686, 687, 688, 690, 691, 692, 516, 516, + 696, 697, 701, 702, 703, 696, 696, 696, + 700, 696, 696, 705, 704, 706, 704, 707, + 708, 709, 704, 704, 710, 710, 711, 712, + 713, 715, 717, 718, 710, 710, 710, 714, + 710, 714, 710, 118, 710, 710, 710, 122 +] + +class << self + attr_accessor :_lex_trans_actions + private :_lex_trans_actions, :_lex_trans_actions= +end +self._lex_trans_actions = [ + 0, 53, 0, 0, 0, 0, 0, 0, + 95, 65, 93, 71, 111, 0, 0, 0, + 99, 101, 161, 0, 0, 135, 157, 727, + 733, 1, 3, 3, 481, 971, 3, 484, + 971, 499, 971, 3, 3, 481, 3, 487, + 3, 3, 901, 3, 3, 3, 3, 3, + 3, 0, 11, 925, 0, 13, 925, 139, + 925, 0, 0, 11, 0, 15, 0, 0, + 0, 0, 0, 0, 0, 0, 733, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 159, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 171, 163, 169, + 742, 0, 0, 0, 742, 1, 905, 3, + 3, 3, 905, 259, 0, 219, 0, 1, + 3, 520, 3, 265, 217, 261, 0, 0, + 0, 0, 0, 255, 201, 223, 0, 1, + 0, 195, 0, 3, 478, 3, 517, 3, + 5, 547, 829, 547, 976, 547, 0, 7, + 550, 7, 913, 7, 397, 263, 0, 209, + 0, 0, 0, 0, 751, 751, 0, 0, + 17, 17, 676, 0, 1, 257, 0, 0, + 0, 751, 0, 0, 766, 0, 0, 0, + 0, 766, 287, 0, 0, 0, 275, 351, + 295, 347, 0, 51, 51, 353, 805, 805, + 349, 0, 0, 0, 0, 345, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, + 3, 478, 3, 3, 3, 5, 547, 829, + 547, 547, 547, 0, 7, 550, 7, 7, + 7, 917, 397, 291, 371, 0, 823, 0, + 45, 45, 0, 369, 0, 373, 5, 981, + 0, 921, 1, 909, 357, 393, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 381, + 427, 395, 0, 0, 55, 59, 57, 724, + 75, 73, 0, 1, 0, 0, 51, 51, + 0, 0, 0, 67, 0, 0, 0, 0, + 721, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 97, + 63, 89, 490, 85, 833, 5, 553, 0, + 91, 0, 0, 0, 83, 0, 87, 69, + 0, 0, 79, 0, 0, 0, 718, 0, + 81, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 718, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 77, 0, 0, 0, 0, 61, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 51, 105, + 103, 0, 0, 51, 0, 109, 107, 837, + 5, 556, 0, 0, 1, 493, 0, 117, + 115, 0, 1, 0, 0, 113, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 121, 0, 586, 0, 598, 125, 496, 123, + 841, 5, 559, 0, 0, 127, 0, 119, + 141, 143, 736, 1, 0, 733, 0, 0, + 733, 0, 0, 0, 0, 0, 0, 51, + 51, 51, 153, 151, 131, 406, 658, 147, + 730, 0, 149, 133, 145, 137, 403, 646, + 463, 505, 845, 5, 562, 0, 661, 155, + 129, 400, 897, 502, 0, 0, 0, 165, + 51, 51, 0, 167, 664, 739, 175, 177, + 0, 0, 0, 0, 0, 179, 849, 5, + 565, 0, 181, 1, 508, 173, 466, 748, + 185, 183, 0, 1, 0, 0, 0, 0, + 0, 0, 193, 189, 514, 853, 5, 568, + 0, 191, 1, 511, 187, 745, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 769, 225, 0, 712, 0, 0, + 51, 757, 0, 0, 757, 757, 0, 0, + 51, 772, 0, 772, 0, 772, 772, 772, + 0, 0, 772, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 0, 0, 247, 25, + 25, 592, 9, 0, 604, 613, 0, 766, + 0, 619, 0, 637, 631, 625, 249, 523, + 3, 251, 221, 412, 253, 857, 5, 571, + 0, 231, 199, 0, 241, 0, 667, 229, + 757, 227, 0, 243, 0, 245, 409, 197, + 0, 0, 205, 0, 0, 0, 0, 215, + 0, 0, 0, 0, 0, 0, 0, 235, + 0, 0, 589, 0, 601, 610, 0, 0, + 0, 616, 0, 0, 634, 640, 628, 622, + 207, 203, 0, 682, 19, 19, 0, 237, + 0, 685, 21, 21, 0, 0, 679, 233, + 239, 211, 213, 0, 0, 649, 1, 769, + 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 766, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 763, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, + 769, 760, 688, 933, 929, 23, 23, 760, + 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 469, 754, 267, 269, 0, + 1, 0, 0, 271, 529, 861, 5, 574, + 0, 273, 1, 526, 51, 281, 279, 0, + 1, 277, 0, 0, 285, 283, 535, 865, + 5, 577, 0, 1, 532, 811, 315, 313, + 0, 1, 0, 293, 0, 51, 817, 0, + 0, 0, 0, 307, 0, 0, 799, 799, + 0, 309, 0, 0, 0, 305, 51, 808, + 808, 808, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 820, 814, 595, 0, 607, 341, 541, + 337, 301, 869, 5, 580, 0, 343, 0, + 0, 327, 303, 335, 297, 670, 673, 333, + 289, 329, 0, 339, 0, 415, 323, 0, + 0, 966, 881, 37, 0, 0, 997, 0, + 0, 37, 706, 706, 893, 802, 0, 43, + 715, 0, 889, 41, 448, 0, 451, 454, + 0, 0, 460, 457, 37, 37, 885, 0, + 0, 39, 39, 0, 433, 0, 442, 430, + 51, 0, 439, 0, 445, 436, 956, 33, + 33, 700, 700, 0, 0, 946, 29, 29, + 694, 694, 951, 31, 31, 697, 697, 941, + 27, 27, 691, 691, 0, 0, 961, 877, + 937, 991, 35, 703, 703, 937, 35, 709, + 799, 986, 0, 0, 0, 299, 0, 0, + 643, 325, 808, 808, 808, 796, 808, 652, + 311, 1, 538, 655, 331, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 793, 0, 0, 0, 0, 796, 0, + 0, 0, 0, 0, 778, 784, 0, 0, + 0, 0, 0, 0, 787, 0, 0, 0, + 0, 0, 784, 321, 319, 0, 775, 0, + 317, 0, 0, 0, 0, 790, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 781, + 0, 0, 0, 0, 0, 0, 0, 790, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 472, 475, + 359, 826, 826, 45, 826, 367, 361, 365, + 0, 363, 355, 0, 421, 0, 377, 0, + 0, 0, 375, 418, 383, 385, 0, 1, + 0, 51, 0, 51, 387, 544, 873, 5, + 583, 0, 391, 0, 389, 379, 424, 0 +] + +class << self + attr_accessor :_lex_to_state_actions + private :_lex_to_state_actions, :_lex_to_state_actions= +end +self._lex_to_state_actions = [ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 47, 47, 0, 0, 0, 0, 47, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 47, + 0, 0, 0, 0, 0, 0, 0, 47, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 47, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 47, 0, 0, 0, 0, + 0, 47, 0, 0, 0, 0, 0, 0, + 0, 47, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 47, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 47, 0, 0, + 0, 0, 0, 0, 47, 0, 0, 0, + 0, 0, 0, 0, 47, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 47, 0, 0, 0, 0, 0, 0, 0, + 47, 0, 0, 0, 0, 0, 47, 0, + 0, 0, 0, 0, 0, 0, 0 +] + +class << self + attr_accessor :_lex_from_state_actions + private :_lex_from_state_actions, :_lex_from_state_actions= +end +self._lex_from_state_actions = [ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 49, 49, 0, 0, 0, 0, 49, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 49, + 0, 0, 0, 0, 0, 0, 0, 49, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 49, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 49, 0, 0, 0, 0, + 0, 49, 0, 0, 0, 0, 0, 0, + 0, 49, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 49, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 49, 0, 0, + 0, 0, 0, 0, 49, 0, 0, 0, + 0, 0, 0, 0, 49, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 49, 0, 0, 0, 0, 0, 0, 0, + 49, 0, 0, 0, 0, 0, 49, 0, + 0, 0, 0, 0, 0, 0, 0 +] + +class << self + attr_accessor :_lex_eof_trans + private :_lex_eof_trans, :_lex_eof_trans= +end +self._lex_eof_trans = [ + 0, 0, 0, 0, 0, 9, 11, 13, + 13, 13, 13, 19, 19, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 94, 96, + 96, 96, 108, 108, 108, 116, 118, 118, + 118, 118, 118, 124, 116, 116, 116, 116, + 116, 116, 116, 150, 150, 150, 150, 150, + 150, 116, 166, 116, 166, 150, 150, 116, + 116, 150, 150, 150, 150, 179, 179, 179, + 184, 186, 186, 186, 190, 190, 193, 193, + 193, 193, 198, 198, 198, 184, 190, 190, + 190, 190, 190, 190, 190, 190, 190, 229, + 236, 238, 238, 238, 238, 229, 246, 246, + 246, 246, 246, 246, 246, 246, 246, 246, + 0, 0, 261, 261, 262, 263, 0, 304, + 306, 307, 308, 309, 311, 313, 317, 317, + 308, 308, 308, 308, 319, 308, 308, 313, + 308, 308, 304, 323, 323, 323, 323, 323, + 323, 313, 313, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 362, 329, + 329, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 308, 0, + 406, 407, 408, 410, 406, 406, 414, 0, + 433, 435, 437, 438, 439, 440, 441, 443, + 440, 440, 440, 440, 440, 446, 440, 440, + 448, 446, 446, 440, 0, 467, 468, 19, + 19, 471, 472, 19, 468, 468, 475, 477, + 480, 468, 481, 468, 482, 483, 485, 487, + 468, 475, 488, 488, 477, 488, 492, 488, + 488, 488, 488, 0, 94, 500, 501, 500, + 500, 0, 510, 511, 513, 515, 517, 515, + 519, 0, 531, 532, 533, 534, 536, 538, + 540, 541, 541, 541, 541, 541, 541, 541, + 541, 541, 541, 541, 541, 541, 541, 541, + 541, 0, 599, 602, 605, 606, 610, 612, + 613, 614, 615, 616, 618, 621, 622, 624, + 626, 629, 631, 632, 116, 629, 634, 629, + 621, 636, 638, 621, 621, 656, 659, 661, + 662, 666, 669, 670, 671, 672, 656, 656, + 656, 656, 656, 656, 656, 656, 656, 656, + 676, 680, 682, 656, 656, 621, 687, 688, + 688, 688, 621, 621, 621, 689, 116, 621, + 621, 694, 621, 616, 599, 599, 599, 599, + 599, 599, 599, 599, 599, 599, 599, 116, + 599, 599, 599, 599, 599, 599, 599, 599, + 599, 599, 599, 599, 599, 599, 599, 599, + 599, 599, 599, 599, 599, 599, 599, 599, + 599, 599, 599, 599, 599, 599, 599, 599, + 599, 599, 599, 599, 599, 599, 599, 599, + 599, 599, 599, 599, 599, 599, 599, 599, + 747, 606, 599, 599, 599, 599, 599, 599, + 599, 599, 599, 599, 599, 599, 599, 599, + 599, 599, 599, 599, 599, 599, 599, 599, + 599, 599, 599, 772, 621, 0, 780, 781, + 782, 784, 786, 788, 0, 797, 798, 799, + 800, 802, 797, 805, 0, 190, 860, 862, + 863, 864, 865, 867, 869, 871, 874, 874, + 190, 876, 878, 879, 880, 876, 882, 884, + 884, 887, 887, 890, 901, 190, 907, 909, + 911, 912, 915, 916, 890, 890, 919, 919, + 919, 925, 927, 928, 931, 933, 934, 935, + 919, 919, 942, 947, 952, 919, 919, 959, + 959, 919, 919, 884, 876, 876, 884, 876, + 876, 871, 190, 977, 978, 978, 978, 978, + 978, 978, 984, 871, 987, 988, 989, 989, + 989, 989, 989, 989, 989, 989, 989, 989, + 989, 989, 989, 989, 989, 989, 989, 989, + 989, 989, 989, 989, 989, 989, 989, 989, + 989, 989, 989, 989, 989, 989, 989, 989, + 989, 989, 1028, 1029, 989, 989, 1033, 989, + 989, 989, 989, 989, 989, 989, 989, 989, + 989, 989, 989, 989, 989, 989, 989, 989, + 989, 989, 989, 989, 989, 989, 989, 989, + 989, 989, 989, 989, 989, 989, 989, 989, + 989, 989, 989, 989, 989, 989, 989, 989, + 989, 989, 989, 989, 989, 989, 989, 989, + 989, 989, 989, 989, 989, 989, 989, 989, + 989, 989, 989, 989, 989, 1087, 865, 1088, + 0, 1094, 1095, 1096, 1098, 1094, 1094, 1094, + 0, 1103, 1103, 1103, 1103, 1107, 0, 1117, + 1118, 1119, 1121, 1123, 1125, 1123, 1123 +] + +class << self + attr_accessor :lex_start +end +self.lex_start = 128; +class << self + attr_accessor :lex_error +end +self.lex_error = 0; + +class << self + attr_accessor :lex_en_expr_variable +end +self.lex_en_expr_variable = 129; +class << self + attr_accessor :lex_en_expr_fname +end +self.lex_en_expr_fname = 134; +class << self + attr_accessor :lex_en_expr_endfn +end +self.lex_en_expr_endfn = 247; +class << self + attr_accessor :lex_en_expr_dot +end +self.lex_en_expr_dot = 255; +class << self + attr_accessor :lex_en_expr_arg +end +self.lex_en_expr_arg = 276; +class << self + attr_accessor :lex_en_expr_cmdarg +end +self.lex_en_expr_cmdarg = 307; +class << self + attr_accessor :lex_en_expr_endarg +end +self.lex_en_expr_endarg = 313; +class << self + attr_accessor :lex_en_expr_mid +end +self.lex_en_expr_mid = 321; +class << self + attr_accessor :lex_en_expr_beg +end +self.lex_en_expr_beg = 345; +class << self + attr_accessor :lex_en_expr_labelarg +end +self.lex_en_expr_labelarg = 501; +class << self + attr_accessor :lex_en_expr_value +end +self.lex_en_expr_value = 508; +class << self + attr_accessor :lex_en_expr_end +end +self.lex_en_expr_end = 516; +class << self + attr_accessor :lex_en_leading_dot +end +self.lex_en_leading_dot = 696; +class << self + attr_accessor :lex_en_line_comment +end +self.lex_en_line_comment = 704; +class << self + attr_accessor :lex_en_line_begin +end +self.lex_en_line_begin = 710; +class << self + attr_accessor :lex_en_inside_string +end +self.lex_en_inside_string = 128; + + +# line 82 "lib/parser/lexer.rl" + # % + + attr_reader :source_buffer + + attr_accessor :diagnostics + attr_accessor :static_env + attr_accessor :force_utf32 + + attr_accessor :cond, :cmdarg, :context, :command_start + + attr_accessor :tokens, :comments + + attr_reader :paren_nest, :cmdarg_stack, :cond_stack, :lambda_stack, :version + + def initialize(version) + @version = version + @static_env = nil + @context = nil + + @tokens = nil + @comments = nil + + @_lex_actions = + if self.class.respond_to?(:_lex_actions, true) + self.class.send :_lex_actions + else + [] + end + + @emit_integer = lambda { |chars, p| emit(:tINTEGER, chars); p } + @emit_rational = lambda { |chars, p| emit(:tRATIONAL, Rational(chars)); p } + @emit_imaginary = lambda { |chars, p| emit(:tIMAGINARY, Complex(0, chars)); p } + @emit_imaginary_rational = lambda { |chars, p| emit(:tIMAGINARY, Complex(0, Rational(chars))); p } + @emit_integer_re = lambda { |chars, p| emit(:tINTEGER, chars, @ts, @te - 2); p - 2 } + @emit_integer_if = lambda { |chars, p| emit(:tINTEGER, chars, @ts, @te - 2); p - 2 } + @emit_integer_rescue = lambda { |chars, p| emit(:tINTEGER, chars, @ts, @te - 6); p - 6 } + + @emit_float = lambda { |chars, p| emit(:tFLOAT, construct_float(chars)); p } + @emit_imaginary_float = lambda { |chars, p| emit(:tIMAGINARY, Complex(0, construct_float(chars))); p } + @emit_float_if = lambda { |chars, p| emit(:tFLOAT, construct_float(chars), @ts, @te - 2); p - 2 } + @emit_float_rescue = lambda { |chars, p| emit(:tFLOAT, construct_float(chars), @ts, @te - 6); p - 6 } + + reset + end + + def construct_float(chars) + begin + old_verbose, $VERBOSE = $VERBOSE, nil + Float(chars) + ensure + $VERBOSE = old_verbose + end + end + + def reset(reset_state=true) + # Ragel state: + if reset_state + # Unit tests set state prior to resetting lexer. + @cs = self.class.lex_en_line_begin + + @cond = StackState.new('cond') + @cmdarg = StackState.new('cmdarg') + @cond_stack = [] + @cmdarg_stack = [] + end + + @force_utf32 = false # Set to true by some tests + + @source_pts = nil # @source as a codepoint array + + @p = 0 # stream position (saved manually in #advance) + @ts = nil # token start + @te = nil # token end + @act = 0 # next action + + @stack = [] # state stack + @top = 0 # state stack top pointer + + # Lexer state: + @token_queue = [] + + @eq_begin_s = nil # location of last encountered =begin + @sharp_s = nil # location of last encountered # + + @newline_s = nil # location of last encountered newline + + @num_base = nil # last numeric base + @num_digits_s = nil # starting position of numeric digits + @num_suffix_s = nil # starting position of numeric suffix + @num_xfrm = nil # numeric suffix-induced transformation + + # Ruby 1.9 ->() lambdas emit a distinct token if do/{ is + # encountered after a matching closing parenthesis. + @paren_nest = 0 + @lambda_stack = [] + + # If the lexer is in `command state' (aka expr_value) + # at the entry to #advance, it will transition to expr_cmdarg + # instead of expr_arg at certain points. + @command_start = true + + # State before =begin / =end block comment + @cs_before_block_comment = self.class.lex_en_line_begin + + @strings = Parser::LexerStrings.new(self, @version) + end + + def source_buffer=(source_buffer) + @source_buffer = source_buffer + + if @source_buffer + source = @source_buffer.source + + if source.encoding == Encoding::UTF_8 + @source_pts = source.unpack('U*') + else + @source_pts = source.unpack('C*') + end + + if @source_pts[0] == 0xfeff + # Skip byte order mark. + @p = 1 + end + else + @source_pts = nil + end + + @strings.source_buffer = @source_buffer + @strings.source_pts = @source_pts + end + + def encoding + @source_buffer.source.encoding + end + + LEX_STATES = { + :line_begin => lex_en_line_begin, + :expr_dot => lex_en_expr_dot, + :expr_fname => lex_en_expr_fname, + :expr_value => lex_en_expr_value, + :expr_beg => lex_en_expr_beg, + :expr_mid => lex_en_expr_mid, + :expr_arg => lex_en_expr_arg, + :expr_cmdarg => lex_en_expr_cmdarg, + :expr_end => lex_en_expr_end, + :expr_endarg => lex_en_expr_endarg, + :expr_endfn => lex_en_expr_endfn, + :expr_labelarg => lex_en_expr_labelarg, + + :inside_string => lex_en_inside_string + } + + def state + LEX_STATES.invert.fetch(@cs, @cs) + end + + def state=(state) + @cs = LEX_STATES.fetch(state) + end + + def push_cmdarg + @cmdarg_stack.push(@cmdarg) + @cmdarg = StackState.new("cmdarg.#{@cmdarg_stack.count}") + end + + def pop_cmdarg + @cmdarg = @cmdarg_stack.pop + end + + def push_cond + @cond_stack.push(@cond) + @cond = StackState.new("cond.#{@cond_stack.count}") + end + + def pop_cond + @cond = @cond_stack.pop + end + + def dedent_level + @strings.dedent_level + end + + # Return next token: [type, value]. + def advance + unless @token_queue.empty? + return @token_queue.shift + end + + # Ugly, but dependent on Ragel output. Consider refactoring it somehow. + klass = self.class + _lex_trans_keys = klass.send :_lex_trans_keys + _lex_key_spans = klass.send :_lex_key_spans + _lex_index_offsets = klass.send :_lex_index_offsets + _lex_indicies = klass.send :_lex_indicies + _lex_trans_targs = klass.send :_lex_trans_targs + _lex_trans_actions = klass.send :_lex_trans_actions + _lex_to_state_actions = klass.send :_lex_to_state_actions + _lex_from_state_actions = klass.send :_lex_from_state_actions + _lex_eof_trans = klass.send :_lex_eof_trans + _lex_actions = @_lex_actions + + pe = @source_pts.size + 2 + p, eof = @p, pe + + cmd_state = @command_start + @command_start = false + + +# line 8577 "lib/parser/lexer-F0.rb" +begin # ragel flat + testEof = false + _slen, _trans, _keys, _inds, _acts, _nacts = nil + _goto_level = 0 + _resume = 10 + _eof_trans = 15 + _again = 20 + _test_eof = 30 + _out = 40 + while true + _trigger_goto = false + if _goto_level <= 0 + if p == pe + _goto_level = _test_eof + next + end + if @cs == 0 + _goto_level = _out + next + end + end + if _goto_level <= _resume + _acts = _lex_from_state_actions[ @cs] + _nacts = _lex_actions[_acts] + _acts += 1 + while _nacts > 0 + _nacts -= 1 + _acts += 1 + case _lex_actions[_acts - 1] + when 52 then +# line 1 "NONE" + begin + @ts = p + end +# line 8612 "lib/parser/lexer-F0.rb" + end # from state action switch + end + if _trigger_goto + next + end + _keys = @cs << 1 + _inds = _lex_index_offsets[ @cs] + _slen = _lex_key_spans[ @cs] + _wide = ( (@source_pts[p] || 0)) + _trans = if ( _slen > 0 && + _lex_trans_keys[_keys] <= _wide && + _wide <= _lex_trans_keys[_keys + 1] + ) then + _lex_indicies[ _inds + _wide - _lex_trans_keys[_keys] ] + else + _lex_indicies[ _inds + _slen ] + end + end + if _goto_level <= _eof_trans + @cs = _lex_trans_targs[_trans] + if _lex_trans_actions[_trans] != 0 + _acts = _lex_trans_actions[_trans] + _nacts = _lex_actions[_acts] + _acts += 1 + while _nacts > 0 + _nacts -= 1 + _acts += 1 + case _lex_actions[_acts - 1] + when 0 then +# line 548 "lib/parser/lexer.rl" + begin + + # Record position of a newline for precise location reporting on tNL + # tokens. + # + # This action is embedded directly into c_nl, as it is idempotent and + # there are no cases when we need to skip it. + @newline_s = p + end + when 1 then +# line 682 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_integer end + when 2 then +# line 683 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_rational end + when 3 then +# line 684 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_imaginary end + when 4 then +# line 685 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_imaginary_rational end + when 5 then +# line 686 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_integer_re end + when 6 then +# line 687 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_integer_if end + when 7 then +# line 688 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_integer_rescue end + when 8 then +# line 691 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_float end + when 9 then +# line 692 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_imaginary_float end + when 10 then +# line 693 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_float_if end + when 11 then +# line 697 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_rational end + when 12 then +# line 698 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_imaginary_rational end + when 13 then +# line 699 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_float_rescue end + when 14 then +# line 705 "lib/parser/lexer.rl" + begin + + e_lbrace + end + when 15 then +# line 709 "lib/parser/lexer.rl" + begin + + if @strings.close_interp_on_current_literal(p) + p = p - 1; + @cs = 128; + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + + @paren_nest -= 1 + end + when 16 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end + when 17 then +# line 742 "lib/parser/lexer.rl" + begin + @sharp_s = p - 1 end + when 18 then +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end + when 19 then +# line 786 "lib/parser/lexer.rl" + begin + tm = p end + when 20 then +# line 787 "lib/parser/lexer.rl" + begin + tm = p - 2 end + when 21 then +# line 792 "lib/parser/lexer.rl" + begin + tm = p end + when 22 then +# line 793 "lib/parser/lexer.rl" + begin + tm = p - 2 end + when 23 then +# line 794 "lib/parser/lexer.rl" + begin + tm = p - 2 end + when 24 then +# line 795 "lib/parser/lexer.rl" + begin + tm = p - 2 end + when 25 then +# line 796 "lib/parser/lexer.rl" + begin + tm = p - 3 end + when 26 then +# line 801 "lib/parser/lexer.rl" + begin + tm = p - 2 end + when 27 then +# line 806 "lib/parser/lexer.rl" + begin + tm = p - 2 end + when 28 then +# line 812 "lib/parser/lexer.rl" + begin + + @cond.push(false); @cmdarg.push(false) + + @paren_nest += 1 + end + when 29 then +# line 818 "lib/parser/lexer.rl" + begin + + @paren_nest -= 1 + end + when 30 then +# line 825 "lib/parser/lexer.rl" + begin + + @cond.push(false); @cmdarg.push(false) + + @paren_nest += 1 + + if version?(18) + @command_start = true + end + end + when 31 then +# line 835 "lib/parser/lexer.rl" + begin + + @paren_nest -= 1 + end + when 32 then +# line 1070 "lib/parser/lexer.rl" + begin + tm = p end + when 33 then +# line 1083 "lib/parser/lexer.rl" + begin + tm = p end + when 34 then +# line 1111 "lib/parser/lexer.rl" + begin + tm = p end + when 35 then +# line 1308 "lib/parser/lexer.rl" + begin + heredoc_e = p end + when 36 then +# line 1309 "lib/parser/lexer.rl" + begin + new_herebody_s = p end + when 37 then +# line 1409 "lib/parser/lexer.rl" + begin + tm = p - 1; diag_msg = :ivar_name end + when 38 then +# line 1410 "lib/parser/lexer.rl" + begin + tm = p - 2; diag_msg = :cvar_name end + when 39 then +# line 1497 "lib/parser/lexer.rl" + begin + tm = p end + when 40 then +# line 1604 "lib/parser/lexer.rl" + begin + ident_tok = tok; ident_ts = @ts; ident_te = @te; end + when 41 then +# line 1790 "lib/parser/lexer.rl" + begin + @num_base = 16; @num_digits_s = p end + when 42 then +# line 1791 "lib/parser/lexer.rl" + begin + @num_base = 10; @num_digits_s = p end + when 43 then +# line 1792 "lib/parser/lexer.rl" + begin + @num_base = 8; @num_digits_s = p end + when 44 then +# line 1793 "lib/parser/lexer.rl" + begin + @num_base = 2; @num_digits_s = p end + when 45 then +# line 1794 "lib/parser/lexer.rl" + begin + @num_base = 10; @num_digits_s = @ts end + when 46 then +# line 1795 "lib/parser/lexer.rl" + begin + @num_base = 8; @num_digits_s = @ts end + when 47 then +# line 1796 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end + when 48 then +# line 1839 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end + when 49 then +# line 1840 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end + when 50 then +# line 2043 "lib/parser/lexer.rl" + begin + tm = p end + when 53 then +# line 1 "NONE" + begin + @te = p+1 + end + when 54 then +# line 857 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + emit_global_var + + @cs = (stack_pop); begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 55 then +# line 857 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit_global_var + + @cs = (stack_pop); begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 56 then +# line 864 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit_class_var + + @cs = (stack_pop); begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 57 then +# line 871 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit_instance_var + + @cs = (stack_pop); begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 58 then +# line 889 "lib/parser/lexer.rl" + begin + @act = 4; end + when 59 then +# line 893 "lib/parser/lexer.rl" + begin + @act = 5; end + when 60 then +# line 897 "lib/parser/lexer.rl" + begin + @act = 6; end + when 61 then +# line 889 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit_table(KEYWORDS_BEGIN); + @cs = 247; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 62 then +# line 897 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit(:tIDENTIFIER) + @cs = 247; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 63 then +# line 901 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = @ts - 1 + @cs = 516; begin + @stack[ @top] = @cs + @top+= 1 + @cs = 129 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 64 then +# line 910 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit_table(PUNCTUATION) + @cs = 247; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 65 then +# line 914 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = p - 1; p = p - 1; begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 66 then +# line 920 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + if version?(23) + type, delimiter = tok[0..-2], tok[-1].chr + @strings.push_literal(type, delimiter, @ts) + begin + @cs = 128 + _trigger_goto = true + _goto_level = _again + break + end + + else + p = @ts - 1 + begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + + end + end + end + when 67 then +# line 934 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = p - 1; begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 68 then +# line 575 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Sit at EOF indefinitely. #advance would return $eof each time. + # This allows to feed the lexer more data if needed; this is only used + # in tests. + # + # Note that this action is not embedded into e_eof like e_nl and e_bs + # below. This is due to the fact that scanner state at EOF is observed + # by tests, and encapsulating it in a rule would break the introspection. + p = p - 1; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 69 then +# line 889 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit_table(KEYWORDS_BEGIN); + @cs = 247; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 70 then +# line 893 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tCONSTANT) + @cs = 247; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 71 then +# line 897 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tIDENTIFIER) + @cs = 247; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 72 then +# line 901 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = @ts - 1 + @cs = 516; begin + @stack[ @top] = @cs + @top+= 1 + @cs = 129 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 73 then +# line 910 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit_table(PUNCTUATION) + @cs = 247; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 74 then +# line 917 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 345 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 75 then +# line 931 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 76 then +# line 934 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 77 then +# line 910 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin emit_table(PUNCTUATION) + @cs = 247; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 78 then +# line 934 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin p = p - 1; begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 79 then +# line 1 "NONE" + begin + case @act + when 4 then + begin begin p = (( @te))-1; end + emit_table(KEYWORDS_BEGIN); + @cs = 247; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + when 5 then + begin begin p = (( @te))-1; end + emit(:tCONSTANT) + @cs = 247; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + when 6 then + begin begin p = (( @te))-1; end + emit(:tIDENTIFIER) + @cs = 247; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end +end + end + when 80 then +# line 946 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit(:tLABEL, tok(@ts, @te - 2), @ts, @te - 1) + p = p - 1; @cs = 501; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 81 then +# line 950 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + if @version >= 31 && @context.in_argdef + emit(:tBDOT3, '...'.freeze) + # emit(:tNL, "\n".freeze, @te - 1, @te) + @cs = 516; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + else + p -= 3; + begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + + end + end + end + when 82 then +# line 964 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = p - 1; begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 83 then +# line 575 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Sit at EOF indefinitely. #advance would return $eof each time. + # This allows to feed the lexer more data if needed; this is only used + # in tests. + # + # Note that this action is not embedded into e_eof like e_nl and e_bs + # below. This is due to the fact that scanner state at EOF is observed + # by tests, and encapsulating it in a rule would break the introspection. + p = p - 1; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 84 then +# line 961 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 85 then +# line 964 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 86 then +# line 964 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin p = p - 1; begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 87 then +# line 990 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit_table(PUNCTUATION) + @cs = 276; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 88 then +# line 996 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = p - 1; begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 89 then +# line 575 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Sit at EOF indefinitely. #advance would return $eof each time. + # This allows to feed the lexer more data if needed; this is only used + # in tests. + # + # Note that this action is not embedded into e_eof like e_nl and e_bs + # below. This is due to the fact that scanner state at EOF is observed + # by tests, and encapsulating it in a rule would break the introspection. + p = p - 1; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 90 then +# line 975 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tCONSTANT) + @cs = (arg_or_cmdarg(cmd_state)); begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 91 then +# line 979 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tIDENTIFIER) + @cs = (arg_or_cmdarg(cmd_state)); begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 92 then +# line 983 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tFID, tok(@ts, tm), @ts, tm) + @cs = (arg_or_cmdarg(cmd_state)); p = tm - 1; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 93 then +# line 990 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit_table(PUNCTUATION) + @cs = 276; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 94 then +# line 993 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 95 then +# line 996 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 96 then +# line 1074 "lib/parser/lexer.rl" + begin + @act = 33; end + when 97 then +# line 1084 "lib/parser/lexer.rl" + begin + @act = 34; end + when 98 then +# line 1123 "lib/parser/lexer.rl" + begin + @act = 39; end + when 99 then +# line 1128 "lib/parser/lexer.rl" + begin + @act = 40; end + when 100 then +# line 1056 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Unlike expr_beg as invoked in the next rule, do not warn + p = @ts - 1 + begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + + end + end + when 101 then +# line 1074 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + check_ambiguous_slash(tm) + + p = tm - 1 + begin + @cs = 345 + _trigger_goto = true + _goto_level = _again + break + end + + end + end + when 102 then +# line 1095 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = p - 1; p = p - 1; begin + @cs = 345 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 103 then +# line 1103 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = @ts - 1; begin + @cs = 345 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 104 then +# line 1112 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = tm - 1; begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 105 then +# line 1123 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + p = @ts - 1 + begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + + end + end + when 106 then +# line 1137 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = p - 1; begin + @cs = 345 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 107 then +# line 575 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Sit at EOF indefinitely. #advance would return $eof each time. + # This allows to feed the lexer more data if needed; this is only used + # in tests. + # + # Note that this action is not embedded into e_eof like e_nl and e_bs + # below. This is due to the fact that scanner state at EOF is observed + # by tests, and encapsulating it in a rule would break the introspection. + p = p - 1; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 108 then +# line 1012 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + if version?(18) + emit(:tLPAREN2, '('.freeze, @te - 1, @te) + @cs = 508; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + else + emit(:tLPAREN_ARG, '('.freeze, @te - 1, @te) + @cs = 345; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + end + when 109 then +# line 1025 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tLPAREN2, '('.freeze) + @cs = 345; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 110 then +# line 1031 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tLBRACK, '['.freeze, @te - 1, @te) + @cs = 345; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 111 then +# line 1037 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + if @lambda_stack.last == @paren_nest + @lambda_stack.pop + emit(:tLAMBEG, '{'.freeze, @te - 1, @te) + else + emit(:tLCURLY, '{'.freeze, @te - 1, @te) + end + @command_start = true + @paren_nest += 1 + @cs = 508; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 112 then +# line 1065 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 345 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 113 then +# line 1084 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + diagnostic :warning, :ambiguous_prefix, { :prefix => tok(tm, @te) }, + range(tm, @te) + + p = tm - 1 + begin + @cs = 345 + _trigger_goto = true + _goto_level = _again + break + end + + end + end + when 114 then +# line 1100 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 345 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 115 then +# line 1123 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + p = @ts - 1 + begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + + end + end + when 116 then +# line 1128 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 117 then +# line 1131 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 118 then +# line 1134 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 119 then +# line 1137 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 345 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 120 then +# line 1128 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + end + when 121 then +# line 1137 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin p = p - 1; begin + @cs = 345 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 122 then +# line 1 "NONE" + begin + case @act + when 33 then + begin begin p = (( @te))-1; end + + check_ambiguous_slash(tm) + + p = tm - 1 + begin + @cs = 345 + _trigger_goto = true + _goto_level = _again + break + end + + end + when 34 then + begin begin p = (( @te))-1; end + + diagnostic :warning, :ambiguous_prefix, { :prefix => tok(tm, @te) }, + range(tm, @te) + + p = tm - 1 + begin + @cs = 345 + _trigger_goto = true + _goto_level = _again + break + end + + end + when 39 then + begin begin p = (( @te))-1; end + + p = @ts - 1 + begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + + end + else + begin begin p = (( @te))-1; end +end +end + end + when 123 then +# line 1160 "lib/parser/lexer.rl" + begin + @act = 46; end + when 124 then +# line 1173 "lib/parser/lexer.rl" + begin + @act = 47; end + when 125 then +# line 1173 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = @ts - 1 + begin + @cs = 276 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 126 then +# line 575 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Sit at EOF indefinitely. #advance would return $eof each time. + # This allows to feed the lexer more data if needed; this is only used + # in tests. + # + # Note that this action is not embedded into e_eof like e_nl and e_bs + # below. This is due to the fact that scanner state at EOF is observed + # by tests, and encapsulating it in a rule would break the introspection. + p = p - 1; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 127 then +# line 1150 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit(:tLPAREN_ARG, '('.freeze, @te - 1, @te) + if version?(18) + @cs = 508; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + else + @cs = 345; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + end + when 128 then +# line 1173 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = @ts - 1 + begin + @cs = 276 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 129 then +# line 1173 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin p = @ts - 1 + begin + @cs = 276 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 130 then +# line 1 "NONE" + begin + case @act + when 46 then + begin begin p = (( @te))-1; end + + if @cond.active? + emit(:kDO_COND, 'do'.freeze, @te - 2, @te) + else + emit(:kDO, 'do'.freeze, @te - 2, @te) + end + @cs = 508; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + when 47 then + begin begin p = (( @te))-1; end + p = @ts - 1 + begin + @cs = 276 + _trigger_goto = true + _goto_level = _again + break + end + end +end + end + when 131 then +# line 1209 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit_do(true) + @cs = 508; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 132 then +# line 1215 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = p - 1; begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 133 then +# line 575 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Sit at EOF indefinitely. #advance would return $eof each time. + # This allows to feed the lexer more data if needed; this is only used + # in tests. + # + # Note that this action is not embedded into e_eof like e_nl and e_bs + # below. This is due to the fact that scanner state at EOF is observed + # by tests, and encapsulating it in a rule would break the introspection. + p = p - 1; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 134 then +# line 1196 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + if @lambda_stack.last == @paren_nest + @lambda_stack.pop + emit(:tLAMBEG, '{'.freeze) + else + emit(:tLBRACE_ARG, '{'.freeze) + end + @paren_nest += 1 + @command_start = true + @cs = 508; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 135 then +# line 1212 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 136 then +# line 1215 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 137 then +# line 1227 "lib/parser/lexer.rl" + begin + @act = 54; end + when 138 then +# line 1231 "lib/parser/lexer.rl" + begin + @act = 55; end + when 139 then +# line 1239 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = p - 1; begin + @cs = 345 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 140 then +# line 575 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Sit at EOF indefinitely. #advance would return $eof each time. + # This allows to feed the lexer more data if needed; this is only used + # in tests. + # + # Note that this action is not embedded into e_eof like e_nl and e_bs + # below. This is due to the fact that scanner state at EOF is observed + # by tests, and encapsulating it in a rule would break the introspection. + p = p - 1; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 141 then +# line 1231 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = @ts - 1; begin + @cs = 345 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 142 then +# line 1233 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 143 then +# line 1236 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 144 then +# line 1239 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 345 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 145 then +# line 1 "NONE" + begin + case @act + when 54 then + begin begin p = (( @te))-1; end + emit_table(KEYWORDS) + @cs = 345; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + when 55 then + begin begin p = (( @te))-1; end + p = @ts - 1; begin + @cs = 345 + _trigger_goto = true + _goto_level = _again + break + end + end +end + end + when 146 then +# line 1254 "lib/parser/lexer.rl" + begin + @act = 60; end + when 147 then +# line 1357 "lib/parser/lexer.rl" + begin + @act = 67; end + when 148 then +# line 1451 "lib/parser/lexer.rl" + begin + @act = 76; end + when 149 then +# line 1492 "lib/parser/lexer.rl" + begin + @act = 80; end + when 150 then +# line 1498 "lib/parser/lexer.rl" + begin + @act = 81; end + when 151 then +# line 1504 "lib/parser/lexer.rl" + begin + @act = 82; end + when 152 then +# line 1595 "lib/parser/lexer.rl" + begin + @act = 86; end + when 153 then +# line 840 "lib/parser/lexer.rl" + begin + @act = 87; end + when 154 then +# line 1641 "lib/parser/lexer.rl" + begin + @act = 91; end + when 155 then +# line 1254 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + emit(:tUNARY_NUM, tok(@ts, @ts + 1), @ts, @ts + 1) + p = p - 1; @cs = 516; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 156 then +# line 1271 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + type = delimiter = tok[0].chr + @strings.push_literal(type, delimiter, @ts) + + p = p - 1; + begin + @cs = 128 + _trigger_goto = true + _goto_level = _again + break + end + + end + end + when 157 then +# line 1281 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + type, delimiter = @source_buffer.slice(@ts, 1).chr, tok[-1].chr + @strings.push_literal(type, delimiter, @ts) + begin + @cs = 128 + _trigger_goto = true + _goto_level = _again + break + end + + end + end + when 158 then +# line 1289 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + type, delimiter = tok[0..-2], tok[-1].chr + @strings.push_literal(type, delimiter, @ts) + begin + @cs = 128 + _trigger_goto = true + _goto_level = _again + break + end + + end + end + when 159 then +# line 1366 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + p = p - 1; p = p - 1; + emit(:tSYMBEG, tok(@ts, @ts + 1), @ts, @ts + 1) + begin + @cs = 134 + _trigger_goto = true + _goto_level = _again + break + end + + end + end + when 160 then +# line 1374 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + type, delimiter = tok, tok[-1].chr + @strings.push_literal(type, delimiter, @ts); + + begin + @cs = 128 + _trigger_goto = true + _goto_level = _again + break + end + + end + end + when 161 then +# line 1384 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + emit(:tSYMBOL, tok(@ts + 1, @ts + 2)) + @cs = 516; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 162 then +# line 1398 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + gvar_name = tok(@ts + 1) + + if @version >= 33 && gvar_name.start_with?('$0') && gvar_name.length > 2 + diagnostic :error, :gvar_name, { :name => gvar_name }, range(@ts + 1, @te) + end + + emit(:tSYMBOL, gvar_name, @ts) + @cs = 516; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 163 then +# line 1425 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + p, next_state = @strings.read_character_constant(@ts) + p = p - 1; # Ragel will do `p += 1` to consume input, prevent it + + # If strings lexer founds a character constant (?a) emit it, + # otherwise read ternary operator + if @token_queue.empty? + begin + @cs = (next_state) + _trigger_goto = true + _goto_level = _again + break + end + + else + @cs = (next_state); + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + end + when 164 then +# line 1440 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + diagnostic :fatal, :incomplete_escape, nil, range(@ts, @ts + 1) + end + end + when 165 then +# line 1492 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit_table(PUNCTUATION_BEGIN) + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 166 then +# line 1513 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + p = p - 1; + + if version?(18) + ident = tok(@ts, @te - 2) + + emit((@source_buffer.slice(@ts, 1) =~ /[A-Z]/) ? :tCONSTANT : :tIDENTIFIER, + ident, @ts, @te - 2) + p = p - 1; # continue as a symbol + + if !@static_env.nil? && @static_env.declared?(ident) + @cs = 516; + else + @cs = (arg_or_cmdarg(cmd_state)); + end + else + emit(:tLABEL, tok(@ts, @te - 2), @ts, @te - 1) + @cs = 501; + end + + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 167 then +# line 1551 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Here we scan and conditionally emit "\n": + # + if it's there + # + and emitted we do nothing + # + and not emitted we return `p` to "\n" to process it on the next scan + # + if it's not there we do nothing + followed_by_nl = @te - 1 == @newline_s + nl_emitted = false + dots_te = followed_by_nl ? @te - 1 : @te + + if @version >= 30 + if @lambda_stack.any? && @lambda_stack.last + 1 == @paren_nest + # To reject `->(...)` like `->...` + emit(:tDOT3, '...'.freeze, @ts, dots_te) + else + emit(:tBDOT3, '...'.freeze, @ts, dots_te) + + if @version >= 31 && followed_by_nl && @context.in_argdef + emit(:tNL, @te - 1, @te) + nl_emitted = true + end + end + elsif @version >= 27 + emit(:tBDOT3, '...'.freeze, @ts, dots_te) + else + emit(:tDOT3, '...'.freeze, @ts, dots_te) + end + + if followed_by_nl && !nl_emitted + # return "\n" to process it on the next scan + p = p - 1; + end + + @cs = 345; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 168 then +# line 1606 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + emit(:tIDENTIFIER, ident_tok, ident_ts, ident_te) + p = ident_te - 1 + + if !@static_env.nil? && @static_env.declared?(ident_tok) && @version < 25 + @cs = 247; + else + @cs = 307; + end + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 169 then +# line 1625 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + p = @ts - 1 + @cs_before_block_comment = @cs + begin + @cs = 710 + _trigger_goto = true + _goto_level = _again + break + end + + end + end + when 170 then +# line 1641 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = @ts - 1; begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 171 then +# line 575 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Sit at EOF indefinitely. #advance would return $eof each time. + # This allows to feed the lexer more data if needed; this is only used + # in tests. + # + # Note that this action is not embedded into e_eof like e_nl and e_bs + # below. This is due to the fact that scanner state at EOF is observed + # by tests, and encapsulating it in a rule would break the introspection. + p = p - 1; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 172 then +# line 1254 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit(:tUNARY_NUM, tok(@ts, @ts + 1), @ts, @ts + 1) + p = p - 1; @cs = 516; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 173 then +# line 1261 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tSTAR, '*'.freeze) + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 174 then +# line 1296 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + diagnostic :fatal, :string_eof, nil, range(@ts, @ts + 1) + end + end + when 175 then +# line 1310 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + tok(@ts, heredoc_e) =~ /^<<(-?)(~?)(["'`]?)(.*)\3$/m + + indent = !$1.empty? || !$2.empty? + dedent_body = !$2.empty? + type = $3.empty? ? '<<"'.freeze : ('<<'.freeze + $3) + delimiter = $4 + + if @version >= 27 + if delimiter.count("\n") > 0 || delimiter.count("\r") > 0 + diagnostic :error, :unterminated_heredoc_id, nil, range(@ts, @ts + 1) + end + elsif @version >= 24 + if delimiter.count("\n") > 0 + if delimiter.end_with?("\n") + diagnostic :warning, :heredoc_id_ends_with_nl, nil, range(@ts, @ts + 1) + delimiter = delimiter.rstrip + else + diagnostic :fatal, :heredoc_id_has_newline, nil, range(@ts, @ts + 1) + end + end + end + + if dedent_body && version?(18, 19, 20, 21, 22) + emit(:tLSHFT, '<<'.freeze, @ts, @ts + 2) + p = @ts + 1 + @cs = 345; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + else + @strings.push_literal(type, delimiter, @ts, heredoc_e, indent, dedent_body); + @strings.herebody_s ||= new_herebody_s + + p = @strings.herebody_s - 1 + @cs = 128; + end + end + end + when 176 then +# line 1357 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + diagnostic :error, :unterminated_heredoc_id, nil, range(@ts, @ts + 1) + end + end + when 177 then +# line 1390 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm) + p = tm - 1 + @cs = 516; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 178 then +# line 1398 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + gvar_name = tok(@ts + 1) + + if @version >= 33 && gvar_name.start_with?('$0') && gvar_name.length > 2 + diagnostic :error, :gvar_name, { :name => gvar_name }, range(@ts + 1, @te) + end + + emit(:tSYMBOL, gvar_name, @ts) + @cs = 516; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 179 then +# line 1412 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit_colon_with_digits(p, tm, diag_msg) + + @cs = 516; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 180 then +# line 1440 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + diagnostic :fatal, :incomplete_escape, nil, range(@ts, @ts + 1) + end + end + when 181 then +# line 1468 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + if @lambda_stack.last == @paren_nest + @lambda_stack.pop + @command_start = true + emit(:tLAMBEG, '{'.freeze) + else + emit(:tLBRACE, '{'.freeze) + end + @paren_nest += 1 + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 182 then +# line 1482 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tLBRACK, '['.freeze) + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 183 then +# line 1487 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tLPAREN, '('.freeze) + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 184 then +# line 1492 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit_table(PUNCTUATION_BEGIN) + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 185 then +# line 1498 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:kRESCUE, 'rescue'.freeze, @ts, tm) + p = tm - 1 + @cs = 321; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 186 then +# line 1540 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + if @version >= 27 + emit(:tBDOT2) + else + emit(:tDOT2) + end + + @cs = 345; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 187 then +# line 1551 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + # Here we scan and conditionally emit "\n": + # + if it's there + # + and emitted we do nothing + # + and not emitted we return `p` to "\n" to process it on the next scan + # + if it's not there we do nothing + followed_by_nl = @te - 1 == @newline_s + nl_emitted = false + dots_te = followed_by_nl ? @te - 1 : @te + + if @version >= 30 + if @lambda_stack.any? && @lambda_stack.last + 1 == @paren_nest + # To reject `->(...)` like `->...` + emit(:tDOT3, '...'.freeze, @ts, dots_te) + else + emit(:tBDOT3, '...'.freeze, @ts, dots_te) + + if @version >= 31 && followed_by_nl && @context.in_argdef + emit(:tNL, @te - 1, @te) + nl_emitted = true + end + end + elsif @version >= 27 + emit(:tBDOT3, '...'.freeze, @ts, dots_te) + else + emit(:tDOT3, '...'.freeze, @ts, dots_te) + end + + if followed_by_nl && !nl_emitted + # return "\n" to process it on the next scan + p = p - 1; + end + + @cs = 345; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 188 then +# line 1595 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = @ts - 1 + begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 189 then +# line 840 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit(:tIDENTIFIER) + + if !@static_env.nil? && @static_env.declared?(tok) + @cs = 247; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + elsif @version >= 32 && tok =~ /\A_[1-9]\z/ + @cs = 247; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + else + @cs = (arg_or_cmdarg(cmd_state)); begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + end + when 190 then +# line 1622 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 191 then +# line 1625 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + p = @ts - 1 + @cs_before_block_comment = @cs + begin + @cs = 710 + _trigger_goto = true + _goto_level = _again + break + end + + end + end + when 192 then +# line 1641 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = @ts - 1; begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 193 then +# line 1296 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin + diagnostic :fatal, :string_eof, nil, range(@ts, @ts + 1) + end + end + when 194 then +# line 1357 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin + diagnostic :error, :unterminated_heredoc_id, nil, range(@ts, @ts + 1) + end + end + when 195 then +# line 840 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin + emit(:tIDENTIFIER) + + if !@static_env.nil? && @static_env.declared?(tok) + @cs = 247; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + elsif @version >= 32 && tok =~ /\A_[1-9]\z/ + @cs = 247; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + else + @cs = (arg_or_cmdarg(cmd_state)); begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + end + when 196 then +# line 1622 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + end + when 197 then +# line 1641 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin p = @ts - 1; begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 198 then +# line 1 "NONE" + begin + case @act + when 60 then + begin begin p = (( @te))-1; end + + emit(:tUNARY_NUM, tok(@ts, @ts + 1), @ts, @ts + 1) + p = p - 1; @cs = 516; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + when 67 then + begin begin p = (( @te))-1; end + + diagnostic :error, :unterminated_heredoc_id, nil, range(@ts, @ts + 1) + end + when 76 then + begin begin p = (( @te))-1; end + + if @version >= 27 + emit(:tPIPE, tok(@ts, @ts + 1), @ts, @ts + 1) + p = p - 1; + @cs = 345; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + else + p -= 2 + begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + + end + end + when 80 then + begin begin p = (( @te))-1; end + emit_table(PUNCTUATION_BEGIN) + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + when 81 then + begin begin p = (( @te))-1; end + emit(:kRESCUE, 'rescue'.freeze, @ts, tm) + p = tm - 1 + @cs = 321; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + when 82 then + begin begin p = (( @te))-1; end + emit_table(KEYWORDS_BEGIN) + @command_start = true + @cs = 508; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + when 86 then + begin begin p = (( @te))-1; end + p = @ts - 1 + begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + end + when 87 then + begin begin p = (( @te))-1; end + + emit(:tIDENTIFIER) + + if !@static_env.nil? && @static_env.declared?(tok) + @cs = 247; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + elsif @version >= 32 && tok =~ /\A_[1-9]\z/ + @cs = 247; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + else + @cs = (arg_or_cmdarg(cmd_state)); begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 91 then + begin begin p = (( @te))-1; end + p = @ts - 1; begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + end +end + end + when 199 then +# line 1661 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = p - 1; begin + @cs = 345 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 200 then +# line 575 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Sit at EOF indefinitely. #advance would return $eof each time. + # This allows to feed the lexer more data if needed; this is only used + # in tests. + # + # Note that this action is not embedded into e_eof like e_nl and e_bs + # below. This is due to the fact that scanner state at EOF is observed + # by tests, and encapsulating it in a rule would break the introspection. + p = p - 1; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 201 then +# line 1649 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 202 then +# line 1652 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + if @context.in_kwarg + p = p - 1; begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + + else + begin + @cs = 710 + _trigger_goto = true + _goto_level = _again + break + end + + end + end + end + when 203 then +# line 1661 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 345 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 204 then +# line 1671 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = @ts - 1 + begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 205 then +# line 1676 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + @strings.push_literal(tok, tok, @ts) + begin + @cs = 128 + _trigger_goto = true + _goto_level = _again + break + end + + end + end + when 206 then +# line 1687 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = p - 1; begin + @cs = 345 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 207 then +# line 575 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Sit at EOF indefinitely. #advance would return $eof each time. + # This allows to feed the lexer more data if needed; this is only used + # in tests. + # + # Note that this action is not embedded into e_eof like e_nl and e_bs + # below. This is due to the fact that scanner state at EOF is observed + # by tests, and encapsulating it in a rule would break the introspection. + p = p - 1; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 208 then +# line 1681 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 209 then +# line 1684 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin begin + @cs = 710 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 210 then +# line 1687 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 345 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 211 then +# line 1687 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin p = p - 1; begin + @cs = 345 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 212 then +# line 1706 "lib/parser/lexer.rl" + begin + @act = 104; end + when 213 then +# line 1735 "lib/parser/lexer.rl" + begin + @act = 105; end + when 214 then +# line 1739 "lib/parser/lexer.rl" + begin + @act = 106; end + when 215 then +# line 1744 "lib/parser/lexer.rl" + begin + @act = 107; end + when 216 then +# line 1749 "lib/parser/lexer.rl" + begin + @act = 108; end + when 217 then +# line 1754 "lib/parser/lexer.rl" + begin + @act = 109; end + when 218 then +# line 1758 "lib/parser/lexer.rl" + begin + @act = 110; end + when 219 then +# line 1769 "lib/parser/lexer.rl" + begin + @act = 111; end + when 220 then +# line 1783 "lib/parser/lexer.rl" + begin + @act = 112; end + when 221 then +# line 1797 "lib/parser/lexer.rl" + begin + @act = 113; end + when 222 then +# line 1815 "lib/parser/lexer.rl" + begin + @act = 115; end + when 223 then +# line 1827 "lib/parser/lexer.rl" + begin + @act = 116; end + when 224 then +# line 1842 "lib/parser/lexer.rl" + begin + @act = 117; end + when 225 then +# line 1871 "lib/parser/lexer.rl" + begin + @act = 119; end + when 226 then +# line 840 "lib/parser/lexer.rl" + begin + @act = 123; end + when 227 then +# line 1893 "lib/parser/lexer.rl" + begin + @act = 124; end + when 228 then +# line 1919 "lib/parser/lexer.rl" + begin + @act = 126; end + when 229 then +# line 1925 "lib/parser/lexer.rl" + begin + @act = 127; end + when 230 then +# line 1698 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + emit(:tLAMBDA, '->'.freeze, @ts, @ts + 2) + + @lambda_stack.push @paren_nest + @cs = 247; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 231 then +# line 1739 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit_singleton_class + @cs = 508; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 232 then +# line 1860 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + type, delimiter = tok, tok[-1].chr + @strings.push_literal(type, delimiter, @ts, nil, false, false, true); + begin + @cs = 128 + _trigger_goto = true + _goto_level = _again + break + end + + end + end + when 233 then +# line 1879 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = @ts - 1; begin + @stack[ @top] = @cs + @top+= 1 + @cs = 129 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 234 then +# line 1886 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit_table(PUNCTUATION) + @cs = 255; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 235 then +# line 1910 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + emit_table(PUNCTUATION) + @cs = 508; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 236 then +# line 1919 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + emit_table(PUNCTUATION); + @cs = 508; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 237 then +# line 1946 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit(:tOP_ASGN, tok(@ts, @te - 1)) + @cs = 345; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 238 then +# line 1950 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit(:tEH, '?'.freeze) + @cs = 508; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 239 then +# line 1958 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + if @paren_nest == 0 + diagnostic :warning, :triple_dot_at_eol, nil, range(@ts, @te - 1) + end + + emit(:tDOT3, '...'.freeze, @ts, @te - 1) + p = p - 1; + @cs = 345; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 240 then +# line 1969 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit_table(PUNCTUATION) + @cs = 345; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 241 then +# line 1982 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit(:tSEMI, ';'.freeze) + @command_start = true + @cs = 508; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 242 then +# line 1986 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + diagnostic :error, :bare_backslash, nil, range(@ts, @ts + 1) + p = p - 1; + end + end + when 243 then +# line 1992 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + diagnostic :fatal, :unexpected, { :character => tok.inspect[1..-2] } + end + end + when 244 then +# line 575 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Sit at EOF indefinitely. #advance would return $eof each time. + # This allows to feed the lexer more data if needed; this is only used + # in tests. + # + # Note that this action is not embedded into e_eof like e_nl and e_bs + # below. This is due to the fact that scanner state at EOF is observed + # by tests, and encapsulating it in a rule would break the introspection. + p = p - 1; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 245 then +# line 1706 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + if @lambda_stack.last == @paren_nest + @lambda_stack.pop + + if tok == '{'.freeze + emit(:tLAMBEG, '{'.freeze) + else # 'do' + emit(:kDO_LAMBDA, 'do'.freeze) + end + else + if tok == '{'.freeze + emit(:tLCURLY, '{'.freeze) + else # 'do' + emit_do + end + end + if tok == '{'.freeze + @paren_nest += 1 + end + @command_start = true + + @cs = 508; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 246 then +# line 1735 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit_table(KEYWORDS) + @cs = 134; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 247 then +# line 1739 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit_singleton_class + @cs = 508; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 248 then +# line 1749 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit_table(KEYWORDS) + @command_start = true + @cs = 508; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 249 then +# line 1797 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + digits = numeric_literal_int + + if version?(18, 19, 20) + emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits.to_i(@num_base), p) + end + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 250 then +# line 1810 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + diagnostic :error, :no_dot_digit_literal + end + end + when 251 then +# line 1842 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + digits = tok(@ts, @num_suffix_s) + + if version?(18, 19, 20) + emit(:tFLOAT, Float(digits), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits, p) + end + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 252 then +# line 1871 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tCONSTANT) + @cs = (arg_or_cmdarg(cmd_state)); begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 253 then +# line 1875 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tCONSTANT, tok(@ts, tm), @ts, tm) + p = tm - 1; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 254 then +# line 1879 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = @ts - 1; begin + @stack[ @top] = @cs + @top+= 1 + @cs = 129 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 255 then +# line 1886 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit_table(PUNCTUATION) + @cs = 255; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 256 then +# line 840 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit(:tIDENTIFIER) + + if !@static_env.nil? && @static_env.declared?(tok) + @cs = 247; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + elsif @version >= 32 && tok =~ /\A_[1-9]\z/ + @cs = 247; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + else + @cs = (arg_or_cmdarg(cmd_state)); begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + end + when 257 then +# line 1893 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + if tm == @te + # Suffix was consumed, e.g. foo! + emit(:tFID) + else + # Suffix was not consumed, e.g. foo!= + emit(:tIDENTIFIER, tok(@ts, tm), @ts, tm) + p = tm - 1 + end + @cs = 276; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 258 then +# line 1910 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit_table(PUNCTUATION) + @cs = 508; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 259 then +# line 1919 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit_table(PUNCTUATION); + @cs = 508; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 260 then +# line 1925 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit_table(PUNCTUATION) + @cs = 345; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 261 then +# line 1929 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit_rbrace_rparen_rbrack + + if tok == '}'.freeze || tok == ']'.freeze + if @version >= 25 + @cs = 516; + else + @cs = 313; + end + else # ) + # fnext expr_endfn; ? + end + + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 262 then +# line 1954 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tLBRACK2, '['.freeze) + @cs = 345; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 263 then +# line 1969 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit_table(PUNCTUATION) + @cs = 345; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 264 then +# line 1976 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 265 then +# line 1979 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin begin + @cs = 696 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 266 then +# line 1992 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + diagnostic :fatal, :unexpected, { :character => tok.inspect[1..-2] } + end + end + when 267 then +# line 1797 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin + digits = numeric_literal_int + + if version?(18, 19, 20) + emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits.to_i(@num_base), p) + end + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 268 then +# line 1810 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin + diagnostic :error, :no_dot_digit_literal + end + end + when 269 then +# line 1842 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin + digits = tok(@ts, @num_suffix_s) + + if version?(18, 19, 20) + emit(:tFLOAT, Float(digits), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits, p) + end + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 270 then +# line 1992 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin + diagnostic :fatal, :unexpected, { :character => tok.inspect[1..-2] } + end + end + when 271 then +# line 1 "NONE" + begin + case @act + when 104 then + begin begin p = (( @te))-1; end + + if @lambda_stack.last == @paren_nest + @lambda_stack.pop + + if tok == '{'.freeze + emit(:tLAMBEG, '{'.freeze) + else # 'do' + emit(:kDO_LAMBDA, 'do'.freeze) + end + else + if tok == '{'.freeze + emit(:tLCURLY, '{'.freeze) + else # 'do' + emit_do + end + end + if tok == '{'.freeze + @paren_nest += 1 + end + @command_start = true + + @cs = 508; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + when 105 then + begin begin p = (( @te))-1; end + emit_table(KEYWORDS) + @cs = 134; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + when 106 then + begin begin p = (( @te))-1; end + emit_singleton_class + @cs = 508; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + when 107 then + begin begin p = (( @te))-1; end + emit_table(KEYWORDS) + @cs = 345; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + when 108 then + begin begin p = (( @te))-1; end + emit_table(KEYWORDS) + @command_start = true + @cs = 508; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + when 109 then + begin begin p = (( @te))-1; end + emit_table(KEYWORDS) + @cs = 321; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + when 110 then + begin begin p = (( @te))-1; end + + emit_table(KEYWORDS) + + if version?(18) && tok == 'not'.freeze + @cs = 345; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + else + @cs = 276; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 111 then + begin begin p = (( @te))-1; end + + if version?(18) + emit(:tIDENTIFIER) + + unless !@static_env.nil? && @static_env.declared?(tok) + @cs = (arg_or_cmdarg(cmd_state)); + end + else + emit(:k__ENCODING__, '__ENCODING__'.freeze) + end + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + when 112 then + begin begin p = (( @te))-1; end + emit_table(KEYWORDS) + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + when 113 then + begin begin p = (( @te))-1; end + + digits = numeric_literal_int + + if version?(18, 19, 20) + emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits.to_i(@num_base), p) + end + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + when 115 then + begin begin p = (( @te))-1; end + + if version?(18, 19, 20) + diagnostic :error, + :trailing_in_number, { :character => tok(@te - 1, @te) }, + range(@te - 1, @te) + else + emit(:tINTEGER, tok(@ts, @te - 1).to_i, @ts, @te - 1) + p = p - 1; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 116 then + begin begin p = (( @te))-1; end + + if version?(18, 19, 20) + diagnostic :error, + :trailing_in_number, { :character => tok(@te - 1, @te) }, + range(@te - 1, @te) + else + emit(:tFLOAT, tok(@ts, @te - 1).to_f, @ts, @te - 1) + p = p - 1; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 117 then + begin begin p = (( @te))-1; end + + digits = tok(@ts, @num_suffix_s) + + if version?(18, 19, 20) + emit(:tFLOAT, Float(digits), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits, p) + end + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + when 119 then + begin begin p = (( @te))-1; end + emit(:tCONSTANT) + @cs = (arg_or_cmdarg(cmd_state)); begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + when 123 then + begin begin p = (( @te))-1; end + + emit(:tIDENTIFIER) + + if !@static_env.nil? && @static_env.declared?(tok) + @cs = 247; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + elsif @version >= 32 && tok =~ /\A_[1-9]\z/ + @cs = 247; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + else + @cs = (arg_or_cmdarg(cmd_state)); begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 124 then + begin begin p = (( @te))-1; end + + if tm == @te + # Suffix was consumed, e.g. foo! + emit(:tFID) + else + # Suffix was not consumed, e.g. foo!= + emit(:tIDENTIFIER, tok(@ts, tm), @ts, tm) + p = tm - 1 + end + @cs = 276; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + when 126 then + begin begin p = (( @te))-1; end + + emit_table(PUNCTUATION); + @cs = 508; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + when 127 then + begin begin p = (( @te))-1; end + emit_table(PUNCTUATION) + @cs = 345; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end +end + end + when 272 then +# line 2008 "lib/parser/lexer.rl" + begin + @act = 140; end + when 273 then +# line 2047 "lib/parser/lexer.rl" + begin + @act = 144; end + when 274 then +# line 2033 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + emit(:tNL, nil, @newline_s, @newline_s + 1) + if @version < 27 + p = p - 1; @cs = 710; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + else + emit(:tBDOT3) + @cs = 345; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + end + when 275 then +# line 2044 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = tm - 1; begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 276 then +# line 2047 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit(:tNL, nil, @newline_s, @newline_s + 1) + p = p - 1; @cs = 710; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 277 then +# line 2008 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + if @version < 27 + # Ruby before 2.7 doesn't support comments before leading dot. + # If a line after "a" starts with a comment then "a" is a self-contained statement. + # So in that case we emit a special tNL token and start reading the + # next line as a separate statement. + # + # Note: block comments before leading dot are not supported on any version of Ruby. + emit(:tNL, nil, @newline_s, @newline_s + 1) + p = p - 1; @cs = 710; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + end + when 278 then +# line 2022 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit(:tNL, nil, @newline_s, @newline_s + 1) + if @version < 27 + p = p - 1; @cs = 710; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + else + emit(:tBDOT2) + @cs = 345; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + end + when 279 then +# line 2044 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = tm - 1; begin + @cs = 516 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 280 then +# line 2047 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tNL, nil, @newline_s, @newline_s + 1) + p = p - 1; @cs = 710; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 281 then +# line 2008 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin + if @version < 27 + # Ruby before 2.7 doesn't support comments before leading dot. + # If a line after "a" starts with a comment then "a" is a self-contained statement. + # So in that case we emit a special tNL token and start reading the + # next line as a separate statement. + # + # Note: block comments before leading dot are not supported on any version of Ruby. + emit(:tNL, nil, @newline_s, @newline_s + 1) + p = p - 1; @cs = 710; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + end + when 282 then +# line 2047 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin emit(:tNL, nil, @newline_s, @newline_s + 1) + p = p - 1; @cs = 710; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end + end + when 283 then +# line 1 "NONE" + begin + case @act + when 140 then + begin begin p = (( @te))-1; end + + if @version < 27 + # Ruby before 2.7 doesn't support comments before leading dot. + # If a line after "a" starts with a comment then "a" is a self-contained statement. + # So in that case we emit a special tNL token and start reading the + # next line as a separate statement. + # + # Note: block comments before leading dot are not supported on any version of Ruby. + emit(:tNL, nil, @newline_s, @newline_s + 1) + p = p - 1; @cs = 710; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 144 then + begin begin p = (( @te))-1; end + emit(:tNL, nil, @newline_s, @newline_s + 1) + p = p - 1; @cs = 710; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + end +end + end + when 284 then +# line 2057 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + emit_comment(@eq_begin_s, @te) + begin + @cs = (@cs_before_block_comment) + _trigger_goto = true + _goto_level = _again + break + end + + end + end + when 285 then +# line 2062 "lib/parser/lexer.rl" + begin + @te = p+1 + end + when 286 then +# line 2057 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit_comment(@eq_begin_s, @te) + begin + @cs = (@cs_before_block_comment) + _trigger_goto = true + _goto_level = _again + break + end + + end + end + when 287 then +# line 2065 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + diagnostic :fatal, :embedded_document, nil, + range(@eq_begin_s, @eq_begin_s + '=begin'.length) + end + end + when 288 then +# line 2075 "lib/parser/lexer.rl" + begin + @te = p+1 + begin @eq_begin_s = @ts + begin + @cs = 704 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 289 then +# line 2079 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = pe - 3 end + end + when 290 then +# line 2082 "lib/parser/lexer.rl" + begin + @te = p+1 + begin cmd_state = true; p = p - 1; begin + @cs = 508 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 291 then +# line 575 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Sit at EOF indefinitely. #advance would return $eof each time. + # This allows to feed the lexer more data if needed; this is only used + # in tests. + # + # Note that this action is not embedded into e_eof like e_nl and e_bs + # below. This is due to the fact that scanner state at EOF is observed + # by tests, and encapsulating it in a rule would break the introspection. + p = p - 1; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 292 then +# line 2072 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 293 then +# line 2075 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin @eq_begin_s = @ts + begin + @cs = 704 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 294 then +# line 2082 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin cmd_state = true; p = p - 1; begin + @cs = 508 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 295 then +# line 2082 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin cmd_state = true; p = p - 1; begin + @cs = 508 + _trigger_goto = true + _goto_level = _again + break + end + end + end + when 296 then +# line 2089 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + p, next_state = @strings.advance(p) + + p = p - 1; # Ragel will do `p += 1` to consume input, prevent it + @cs = (next_state); + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end +# line 12630 "lib/parser/lexer-F0.rb" + end # action switch + end + end + if _trigger_goto + next + end + end + if _goto_level <= _again + _acts = _lex_to_state_actions[ @cs] + _nacts = _lex_actions[_acts] + _acts += 1 + while _nacts > 0 + _nacts -= 1 + _acts += 1 + case _lex_actions[_acts - 1] + when 51 then +# line 1 "NONE" + begin + @ts = nil; end +# line 12650 "lib/parser/lexer-F0.rb" + end # to state action switch + end + if _trigger_goto + next + end + if @cs == 0 + _goto_level = _out + next + end + p += 1 + if p != pe + _goto_level = _resume + next + end + end + if _goto_level <= _test_eof + if p == eof + if _lex_eof_trans[ @cs] > 0 + _trans = _lex_eof_trans[ @cs] - 1; + _goto_level = _eof_trans + next; + end + end + end + if _goto_level <= _out + break + end + end + end + +# line 290 "lib/parser/lexer.rl" + # % + + # Ragel creates a local variable called `testEof` but it doesn't use + # it in any assignment. This dead code is here to swallow the warning. + # It has no runtime cost because Ruby doesn't produce any instructions from it. + if false + testEof + end + + @p = p + + if @token_queue.any? + @token_queue.shift + elsif @cs == klass.lex_error + [ false, [ '$error'.freeze, range(p - 1, p) ] ] + else + eof = @source_pts.size + [ false, [ '$eof'.freeze, range(eof, eof) ] ] + end + end + + protected + + def version?(*versions) + versions.include?(@version) + end + + def stack_pop + @top -= 1 + @stack[@top] + end + + def tok(s = @ts, e = @te) + @source_buffer.slice(s, e - s) + end + + def range(s = @ts, e = @te) + Parser::Source::Range.new(@source_buffer, s, e) + end + + def emit(type, value = tok, s = @ts, e = @te) + token = [ type, [ value, range(s, e) ] ] + + @token_queue.push(token) + + @tokens.push(token) if @tokens + + token + end + + def emit_table(table, s = @ts, e = @te) + value = tok(s, e) + + emit(table[value], value, s, e) + end + + def emit_do(do_block=false) + if @cond.active? + emit(:kDO_COND, 'do'.freeze) + elsif @cmdarg.active? || do_block + emit(:kDO_BLOCK, 'do'.freeze) + else + emit(:kDO, 'do'.freeze) + end + end + + def arg_or_cmdarg(cmd_state) + if cmd_state + self.class.lex_en_expr_cmdarg + else + self.class.lex_en_expr_arg + end + end + + def emit_comment(s = @ts, e = @te) + if @comments + @comments.push(Parser::Source::Comment.new(range(s, e))) + end + + if @tokens + @tokens.push([ :tCOMMENT, [ tok(s, e), range(s, e) ] ]) + end + + nil + end + + def emit_comment_from_range(p, pe) + emit_comment(@sharp_s, p == pe ? p - 2 : p) + end + + def diagnostic(type, reason, arguments=nil, location=range, highlights=[]) + @diagnostics.process( + Parser::Diagnostic.new(type, reason, arguments, location, highlights)) + end + + + def e_lbrace + @cond.push(false); @cmdarg.push(false) + + current_literal = @strings.literal + if current_literal + current_literal.start_interp_brace + end + end + + def numeric_literal_int + digits = tok(@num_digits_s, @num_suffix_s) + + if digits.end_with? '_'.freeze + diagnostic :error, :trailing_in_number, { :character => '_'.freeze }, + range(@te - 1, @te) + elsif digits.empty? && @num_base == 8 && version?(18) + # 1.8 did not raise an error on 0o. + digits = '0'.freeze + elsif digits.empty? + diagnostic :error, :empty_numeric + elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/)) + invalid_s = @num_digits_s + invalid_idx + diagnostic :error, :invalid_octal, nil, + range(invalid_s, invalid_s + 1) + end + digits + end + + def on_newline(p) + @strings.on_newline(p) + end + + def check_ambiguous_slash(tm) + if tok(tm, tm + 1) == '/'.freeze + # Ambiguous regexp literal. + if @version < 30 + diagnostic :warning, :ambiguous_literal, nil, range(tm, tm + 1) + else + diagnostic :warning, :ambiguous_regexp, nil, range(tm, tm + 1) + end + end + end + + def emit_global_var(ts = @ts, te = @te) + if tok(ts, te) =~ /^\$([1-9][0-9]*)$/ + emit(:tNTH_REF, tok(ts + 1, te).to_i, ts, te) + elsif tok =~ /^\$([&`'+])$/ + emit(:tBACK_REF, tok(ts, te), ts, te) + else + emit(:tGVAR, tok(ts, te), ts, te) + end + end + + def emit_class_var(ts = @ts, te = @te) + if tok(ts, te) =~ /^@@[0-9]/ + diagnostic :error, :cvar_name, { :name => tok(ts, te) } + end + + emit(:tCVAR, tok(ts, te), ts, te) + end + + def emit_instance_var(ts = @ts, te = @te) + if tok(ts, te) =~ /^@[0-9]/ + diagnostic :error, :ivar_name, { :name => tok(ts, te) } + end + + emit(:tIVAR, tok(ts, te), ts, te) + end + + def emit_rbrace_rparen_rbrack + emit_table(PUNCTUATION) + + if @version < 24 + @cond.lexpop + @cmdarg.lexpop + else + @cond.pop + @cmdarg.pop + end + end + + def emit_colon_with_digits(p, tm, diag_msg) + if @version >= 27 + diagnostic :error, diag_msg, { name: tok(tm, @te) }, range(tm, @te) + else + emit(:tCOLON, tok(@ts, @ts + 1), @ts, @ts + 1) + p = @ts + end + p + end + + def emit_singleton_class + emit(:kCLASS, 'class'.freeze, @ts, @ts + 5) + emit(:tLSHFT, '<<'.freeze, @te - 2, @te) + end + + # Mapping of strings to parser tokens. + + PUNCTUATION = { + '=' => :tEQL, '&' => :tAMPER2, '|' => :tPIPE, + '!' => :tBANG, '^' => :tCARET, '+' => :tPLUS, + '-' => :tMINUS, '*' => :tSTAR2, '/' => :tDIVIDE, + '%' => :tPERCENT, '~' => :tTILDE, ',' => :tCOMMA, + ';' => :tSEMI, '.' => :tDOT, '..' => :tDOT2, + '...' => :tDOT3, '[' => :tLBRACK2, ']' => :tRBRACK, + '(' => :tLPAREN2, ')' => :tRPAREN, '?' => :tEH, + ':' => :tCOLON, '&&' => :tANDOP, '||' => :tOROP, + '-@' => :tUMINUS, '+@' => :tUPLUS, '~@' => :tTILDE, + '**' => :tPOW, '->' => :tLAMBDA, '=~' => :tMATCH, + '!~' => :tNMATCH, '==' => :tEQ, '!=' => :tNEQ, + '>' => :tGT, '>>' => :tRSHFT, '>=' => :tGEQ, + '<' => :tLT, '<<' => :tLSHFT, '<=' => :tLEQ, + '=>' => :tASSOC, '::' => :tCOLON2, '===' => :tEQQ, + '<=>' => :tCMP, '[]' => :tAREF, '[]=' => :tASET, + '{' => :tLCURLY, '}' => :tRCURLY, '`' => :tBACK_REF2, + '!@' => :tBANG, '&.' => :tANDDOT, + } + + PUNCTUATION_BEGIN = { + '&' => :tAMPER, '*' => :tSTAR, '**' => :tDSTAR, + '+' => :tUPLUS, '-' => :tUMINUS, '::' => :tCOLON3, + '(' => :tLPAREN, '{' => :tLBRACE, '[' => :tLBRACK, + } + + KEYWORDS = { + 'if' => :kIF_MOD, 'unless' => :kUNLESS_MOD, + 'while' => :kWHILE_MOD, 'until' => :kUNTIL_MOD, + 'rescue' => :kRESCUE_MOD, 'defined?' => :kDEFINED, + 'BEGIN' => :klBEGIN, 'END' => :klEND, + } + + KEYWORDS_BEGIN = { + 'if' => :kIF, 'unless' => :kUNLESS, + 'while' => :kWHILE, 'until' => :kUNTIL, + 'rescue' => :kRESCUE, 'defined?' => :kDEFINED, + 'BEGIN' => :klBEGIN, 'END' => :klEND, + } + + ESCAPE_WHITESPACE = { + " " => '\s', "\r" => '\r', "\n" => '\n', "\t" => '\t', + "\v" => '\v', "\f" => '\f' + } + + %w(class module def undef begin end then elsif else ensure case when + for break next redo retry in do return yield super self nil true + false and or not alias __FILE__ __LINE__ __ENCODING__).each do |keyword| + KEYWORDS_BEGIN[keyword] = KEYWORDS[keyword] = :"k#{keyword.upcase}" + end + + +# line 2098 "lib/parser/lexer.rl" + + # % +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/lexer-F1.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/lexer-F1.rb new file mode 100644 index 00000000..08e9d37e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/lexer-F1.rb @@ -0,0 +1,14884 @@ +# -*- encoding:utf-8; warn-indent:false; frozen_string_literal: true -*- + +# line 1 "lib/parser/lexer.rl" + +# line 3 "lib/parser/lexer.rl" +# +# === BEFORE YOU START === +# +# Read the Ruby Hacking Guide chapter 11, available in English at +# http://whitequark.org/blog/2013/04/01/ruby-hacking-guide-ch-11-finite-state-lexer/ +# +# Remember two things about Ragel scanners: +# +# 1) Longest match wins. +# +# 2) If two matches have the same length, the first +# in source code wins. +# +# General rules of making Ragel and Bison happy: +# +# * `p` (position) and `@te` contain the index of the character +# they're pointing to ("current"), plus one. `@ts` contains the index +# of the corresponding character. The code for extracting matched token is: +# +# @source_buffer.slice(@ts...@te) +# +# * If your input is `foooooooobar` and the rule is: +# +# 'f' 'o'+ +# +# the result will be: +# +# foooooooobar +# ^ ts=0 ^ p=te=9 +# +# * A Ragel lexer action should not emit more than one token, unless +# you know what you are doing. +# +# * All Ragel commands (fnext, fgoto, ...) end with a semicolon. +# +# * If an action emits the token and transitions to another state, use +# these Ragel commands: +# +# emit($whatever) +# fnext $next_state; fbreak; +# +# If you perform `fgoto` in an action which does not emit a token nor +# rewinds the stream pointer, the parser's side-effectful, +# context-sensitive lookahead actions will break in a hard to detect +# and debug way. +# +# * If an action does not emit a token: +# +# fgoto $next_state; +# +# * If an action features lookbehind, i.e. matches characters with the +# intent of passing them to another action: +# +# p = @ts - 1 +# fgoto $next_state; +# +# or, if the lookbehind consists of a single character: +# +# fhold; fgoto $next_state; +# +# * Ragel merges actions. So, if you have `e_lparen = '(' %act` and +# `c_lparen = '('` and a lexer action `e_lparen | c_lparen`, the result +# _will_ invoke the action `act`. +# +# e_something stands for "something with **e**mbedded action". +# +# * EOF is explicit and is matched by `c_eof`. If you want to introspect +# the state of the lexer, add this rule to the state: +# +# c_eof => do_eof; +# +# * If you proceed past EOF, the lexer will complain: +# +# NoMethodError: undefined method `ord' for nil:NilClass +# + +class Parser::Lexer + + +# line 85 "lib/parser/lexer-F1.rb" +class << self + attr_accessor :_lex_trans_keys + private :_lex_trans_keys, :_lex_trans_keys= +end +self._lex_trans_keys = [ + 0, 0, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 58, 58, 58, 58, 46, 46, + 0, 127, 58, 58, 60, + 60, 62, 62, 10, 10, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 115, 115, + 99, 99, 117, 117, 101, + 101, 108, 116, 101, 101, + 115, 115, 115, 115, 105, 105, + 108, 108, 105, 105, 108, + 108, 58, 58, 0, 127, + 10, 10, 0, 127, 9, 92, + 10, 10, 9, 92, 58, + 58, 98, 98, 101, 101, + 103, 103, 105, 105, 110, 110, + 0, 127, 61, 61, 9, + 92, 9, 92, 9, 92, + 9, 92, 9, 92, 10, 10, + 0, 127, 0, 127, 61, + 126, 93, 93, 0, 127, + 0, 127, 10, 10, 34, 34, + 10, 10, 39, 39, 0, + 127, 10, 96, 96, 96, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 58, 58, 58, 58, + 0, 127, 43, 57, 48, 57, + 48, 57, 48, 57, 48, + 57, 115, 115, 99, 99, + 117, 117, 101, 101, 99, 99, + 117, 117, 101, 101, 0, + 127, 58, 58, 9, 92, + 9, 92, 9, 92, 9, 92, + 9, 92, 9, 92, 60, + 60, 10, 10, 9, 92, + 9, 92, 10, 10, 10, 10, + 10, 10, 10, 10, 46, + 46, 101, 101, 103, 103, + 105, 105, 110, 110, 69, 69, + 78, 78, 68, 68, 95, + 95, 95, 95, 0, 26, + 0, 0, 36, 64, 0, 127, + 48, 57, 0, 127, 0, + 127, 0, 127, 0, 127, + 9, 32, 0, 0, 61, 126, + 10, 10, 10, 10, 0, + 127, 0, 127, 48, 57, + 115, 115, 38, 38, 42, 42, + 64, 64, 58, 58, 60, + 61, 62, 62, 61, 126, + 61, 61, 61, 62, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 93, 93, 10, 10, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 124, 124, 0, 127, + 0, 127, 9, 32, 10, 10, + 10, 10, 46, 46, 10, + 10, 0, 0, 0, 127, + 0, 127, 61, 61, 0, 0, + 9, 32, 0, 0, 61, + 126, 10, 10, 10, 10, + 38, 38, 42, 42, 64, 64, + 60, 61, 62, 62, 61, + 126, 61, 61, 61, 62, + 0, 127, 93, 93, 10, 10, + 124, 124, 0, 126, 0, + 127, 0, 61, 9, 61, + 9, 61, 0, 0, 9, 61, + 9, 62, 46, 46, 46, + 46, 58, 58, 9, 32, + 0, 0, 0, 127, 0, 0, + 9, 124, 0, 0, 10, + 10, 10, 10, 0, 0, + 9, 61, 58, 58, 60, 60, + 62, 62, 9, 32, 10, + 10, 0, 127, 102, 102, + 101, 101, 110, 110, 104, 104, + 0, 127, 0, 127, 0, + 127, 0, 0, 0, 127, + 10, 10, 0, 123, 9, 32, + 10, 10, 10, 10, 10, + 10, 0, 0, 111, 111, + 0, 0, 0, 127, 0, 127, + 9, 32, 0, 0, 10, + 10, 10, 10, 10, 10, + 0, 0, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 58, 61, 0, 0, 61, + 126, 61, 61, 0, 0, + 0, 0, 0, 0, 9, 32, + 61, 61, 9, 32, 61, + 126, 10, 10, 10, 10, + 0, 127, 38, 61, 0, 0, + 42, 61, 61, 61, 9, + 92, 9, 92, 9, 92, + 46, 46, 46, 46, 10, 10, + 0, 26, 0, 127, 0, + 127, 61, 61, 0, 0, + 61, 126, 61, 62, 0, 0, + 0, 0, 0, 0, 0, + 0, 61, 126, 0, 127, + 48, 57, 38, 38, 42, 42, + 64, 64, 60, 61, 62, + 62, 61, 61, 61, 62, + 0, 127, 48, 57, 0, 127, + 124, 124, 64, 64, 60, + 61, 0, 0, 10, 34, + 10, 39, 96, 96, 62, 62, + 61, 126, 61, 62, 0, + 26, 0, 127, 0, 127, + 0, 127, 0, 0, 10, 10, + 0, 0, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 61, 126, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 0, 61, 124, 0, + 92, 9, 32, 0, 0, + 10, 10, 10, 10, 10, 10, + 0, 0, 0, 127, 0, + 127, 9, 32, 0, 0, + 10, 10, 10, 10, 10, 10, + 0, 0, 0, 127, 0, + 127, 61, 61, 0, 0, + 9, 32, 0, 0, 61, 126, + 10, 10, 10, 10, 0, + 127, 0, 127, 48, 57, + 61, 61, 38, 61, 0, 0, + 0, 0, 42, 61, 61, + 62, 46, 57, 46, 46, + 10, 10, 48, 101, 48, 95, + 46, 120, 48, 114, 43, + 57, 48, 105, 102, 102, + 0, 0, 101, 105, 0, 0, + 0, 0, 48, 114, 48, + 114, 48, 114, 48, 114, + 105, 114, 102, 102, 0, 0, + 101, 105, 115, 115, 0, + 0, 0, 0, 48, 114, + 48, 114, 48, 114, 48, 114, + 48, 114, 48, 114, 48, + 114, 48, 114, 46, 114, + 48, 114, 46, 114, 48, 114, + 58, 58, 60, 61, 62, + 62, 61, 126, 61, 61, + 61, 62, 0, 127, 0, 127, + 0, 0, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 0, + 10, 10, 0, 0, 0, + 0, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 9, 92, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 0, 61, 124, 0, 0, + 9, 92, 9, 92, 9, 92, + 46, 46, 46, 46, 10, + 10, 46, 46, 10, 10, + 10, 61, 10, 10, 10, 101, + 10, 110, 10, 100, 10, + 10, 0, 95, 9, 32, + 0, 0, 10, 10, 10, 10, + 98, 98, 9, 32, 10, + 10, 95, 95, 0 +] + +class << self + attr_accessor :_lex_key_spans + private :_lex_key_spans, :_lex_key_spans= +end +self._lex_key_spans = [ + 0, 128, 128, 128, 128, 128, 128, 128, + 1, 1, 1, 128, 1, 1, 1, 1, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 1, 1, 1, 1, 9, 1, + 1, 1, 1, 1, 1, 1, 1, 128, + 1, 128, 84, 1, 84, 1, 1, 1, + 1, 1, 1, 128, 1, 84, 84, 84, + 84, 84, 1, 128, 128, 66, 1, 128, + 128, 1, 1, 1, 1, 128, 87, 1, + 128, 128, 128, 128, 128, 128, 1, 1, + 128, 15, 10, 10, 10, 10, 1, 1, + 1, 1, 1, 1, 1, 128, 1, 84, + 84, 84, 84, 84, 84, 1, 1, 84, + 84, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 27, + 0, 29, 128, 10, 128, 128, 128, 128, + 24, 0, 66, 1, 1, 128, 128, 10, + 1, 1, 1, 1, 1, 2, 1, 66, + 1, 2, 128, 128, 128, 128, 128, 128, + 128, 1, 1, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 1, 128, + 128, 24, 1, 1, 1, 1, 0, 128, + 128, 1, 0, 24, 0, 66, 1, 1, + 1, 1, 1, 2, 1, 66, 1, 2, + 128, 1, 1, 1, 127, 128, 62, 53, + 53, 0, 53, 54, 1, 1, 1, 24, + 0, 128, 0, 116, 0, 1, 1, 0, + 53, 1, 1, 1, 24, 1, 128, 1, + 1, 1, 1, 128, 128, 128, 0, 128, + 1, 124, 24, 1, 1, 1, 0, 1, + 0, 128, 128, 24, 0, 1, 1, 1, + 0, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 4, 0, 66, 1, 0, + 0, 0, 24, 1, 24, 66, 1, 1, + 128, 24, 0, 20, 1, 84, 84, 84, + 1, 1, 1, 27, 128, 128, 1, 0, + 66, 2, 0, 0, 0, 0, 66, 128, + 10, 1, 1, 1, 2, 1, 1, 2, + 128, 10, 128, 1, 1, 2, 0, 25, + 30, 1, 1, 66, 2, 27, 128, 128, + 128, 0, 1, 0, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 66, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 0, 64, 93, 24, 0, + 1, 1, 1, 0, 128, 128, 24, 0, + 1, 1, 1, 0, 128, 128, 1, 0, + 24, 0, 66, 1, 1, 128, 128, 10, + 1, 24, 0, 0, 20, 2, 12, 1, + 1, 54, 48, 75, 67, 15, 58, 1, + 0, 5, 0, 0, 67, 67, 67, 67, + 10, 1, 0, 5, 1, 0, 0, 67, + 67, 67, 67, 67, 67, 67, 67, 69, + 67, 69, 67, 1, 2, 1, 66, 1, + 2, 128, 128, 0, 128, 128, 128, 128, + 128, 128, 0, 1, 0, 0, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 84, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 0, 64, 0, + 84, 84, 84, 1, 1, 1, 1, 1, + 52, 1, 92, 101, 91, 1, 96, 24, + 0, 1, 1, 1, 24, 1, 1 +] + +class << self + attr_accessor :_lex_index_offsets + private :_lex_index_offsets, :_lex_index_offsets= +end +self._lex_index_offsets = [ + 0, 0, 129, 258, 387, 516, 645, 774, + 903, 905, 907, 909, 1038, 1040, 1042, 1044, + 1046, 1175, 1304, 1433, 1562, 1691, 1820, 1949, + 2078, 2207, 2336, 2465, 2594, 2723, 2852, 2981, + 3110, 3239, 3368, 3370, 3372, 3374, 3376, 3386, + 3388, 3390, 3392, 3394, 3396, 3398, 3400, 3402, + 3531, 3533, 3662, 3747, 3749, 3834, 3836, 3838, + 3840, 3842, 3844, 3846, 3975, 3977, 4062, 4147, + 4232, 4317, 4402, 4404, 4533, 4662, 4729, 4731, + 4860, 4989, 4991, 4993, 4995, 4997, 5126, 5214, + 5216, 5345, 5474, 5603, 5732, 5861, 5990, 5992, + 5994, 6123, 6139, 6150, 6161, 6172, 6183, 6185, + 6187, 6189, 6191, 6193, 6195, 6197, 6326, 6328, + 6413, 6498, 6583, 6668, 6753, 6838, 6840, 6842, + 6927, 7012, 7014, 7016, 7018, 7020, 7022, 7024, + 7026, 7028, 7030, 7032, 7034, 7036, 7038, 7040, + 7068, 7069, 7099, 7228, 7239, 7368, 7497, 7626, + 7755, 7780, 7781, 7848, 7850, 7852, 7981, 8110, + 8121, 8123, 8125, 8127, 8129, 8131, 8134, 8136, + 8203, 8205, 8208, 8337, 8466, 8595, 8724, 8853, + 8982, 9111, 9113, 9115, 9244, 9373, 9502, 9631, + 9760, 9889, 10018, 10147, 10276, 10405, 10534, 10663, + 10792, 10921, 11050, 11179, 11308, 11437, 11566, 11695, + 11824, 11953, 12082, 12211, 12340, 12469, 12598, 12727, + 12856, 12985, 13114, 13243, 13372, 13501, 13630, 13759, + 13888, 14017, 14146, 14275, 14404, 14533, 14662, 14791, + 14920, 15049, 15178, 15307, 15436, 15565, 15694, 15823, + 15952, 16081, 16210, 16339, 16468, 16597, 16726, 16855, + 16984, 17113, 17242, 17371, 17500, 17629, 17758, 17887, + 18016, 18145, 18274, 18403, 18532, 18661, 18790, 18919, + 19048, 19177, 19306, 19435, 19564, 19693, 19822, 19824, + 19953, 20082, 20107, 20109, 20111, 20113, 20115, 20116, + 20245, 20374, 20376, 20377, 20402, 20403, 20470, 20472, + 20474, 20476, 20478, 20480, 20483, 20485, 20552, 20554, + 20557, 20686, 20688, 20690, 20692, 20820, 20949, 21012, + 21066, 21120, 21121, 21175, 21230, 21232, 21234, 21236, + 21261, 21262, 21391, 21392, 21509, 21510, 21512, 21514, + 21515, 21569, 21571, 21573, 21575, 21600, 21602, 21731, + 21733, 21735, 21737, 21739, 21868, 21997, 22126, 22127, + 22256, 22258, 22383, 22408, 22410, 22412, 22414, 22415, + 22417, 22418, 22547, 22676, 22701, 22702, 22704, 22706, + 22708, 22709, 22838, 22967, 23096, 23225, 23354, 23483, + 23612, 23741, 23870, 23999, 24128, 24257, 24386, 24515, + 24644, 24773, 24902, 25031, 25036, 25037, 25104, 25106, + 25107, 25108, 25109, 25134, 25136, 25161, 25228, 25230, + 25232, 25361, 25386, 25387, 25408, 25410, 25495, 25580, + 25665, 25667, 25669, 25671, 25699, 25828, 25957, 25959, + 25960, 26027, 26030, 26031, 26032, 26033, 26034, 26101, + 26230, 26241, 26243, 26245, 26247, 26250, 26252, 26254, + 26257, 26386, 26397, 26526, 26528, 26530, 26533, 26534, + 26560, 26591, 26593, 26595, 26662, 26665, 26693, 26822, + 26951, 27080, 27081, 27083, 27084, 27213, 27342, 27471, + 27600, 27729, 27858, 27987, 28116, 28245, 28374, 28503, + 28632, 28761, 28890, 29019, 29148, 29277, 29406, 29535, + 29664, 29793, 29922, 30051, 30180, 30309, 30438, 30567, + 30696, 30825, 30954, 31083, 31212, 31341, 31470, 31599, + 31728, 31857, 31986, 32115, 32244, 32373, 32502, 32631, + 32760, 32889, 33018, 33147, 33276, 33405, 33534, 33663, + 33792, 33921, 34050, 34179, 34308, 34437, 34566, 34695, + 34824, 34953, 35020, 35149, 35278, 35407, 35536, 35665, + 35794, 35923, 36052, 36181, 36310, 36439, 36568, 36697, + 36826, 36955, 37084, 37213, 37342, 37471, 37600, 37729, + 37858, 37987, 38116, 38245, 38246, 38311, 38405, 38430, + 38431, 38433, 38435, 38437, 38438, 38567, 38696, 38721, + 38722, 38724, 38726, 38728, 38729, 38858, 38987, 38989, + 38990, 39015, 39016, 39083, 39085, 39087, 39216, 39345, + 39356, 39358, 39383, 39384, 39385, 39406, 39409, 39422, + 39424, 39426, 39481, 39530, 39606, 39674, 39690, 39749, + 39751, 39752, 39758, 39759, 39760, 39828, 39896, 39964, + 40032, 40043, 40045, 40046, 40052, 40054, 40055, 40056, + 40124, 40192, 40260, 40328, 40396, 40464, 40532, 40600, + 40670, 40738, 40808, 40876, 40878, 40881, 40883, 40950, + 40952, 40955, 41084, 41213, 41214, 41343, 41472, 41601, + 41730, 41859, 41988, 41989, 41991, 41992, 41993, 42122, + 42251, 42380, 42509, 42638, 42767, 42896, 43025, 43154, + 43283, 43412, 43541, 43670, 43799, 43928, 44057, 44186, + 44315, 44444, 44573, 44702, 44831, 44960, 45089, 45218, + 45347, 45476, 45605, 45734, 45863, 45992, 46121, 46250, + 46379, 46508, 46637, 46766, 46851, 46980, 47109, 47238, + 47367, 47496, 47625, 47754, 47883, 48012, 48141, 48270, + 48399, 48528, 48657, 48786, 48915, 49044, 49173, 49302, + 49431, 49560, 49689, 49818, 49947, 50076, 50205, 50334, + 50463, 50592, 50721, 50850, 50979, 51108, 51237, 51366, + 51495, 51624, 51753, 51882, 52011, 52140, 52269, 52398, + 52527, 52656, 52785, 52914, 53043, 53172, 53301, 53430, + 53559, 53688, 53817, 53946, 54075, 54204, 54333, 54462, + 54591, 54720, 54849, 54978, 55107, 55236, 55237, 55302, + 55303, 55388, 55473, 55558, 55560, 55562, 55564, 55566, + 55568, 55621, 55623, 55716, 55818, 55910, 55912, 56009, + 56034, 56035, 56037, 56039, 56041, 56066, 56068 +] + +class << self + attr_accessor :_lex_indicies + private :_lex_indicies, :_lex_indicies= +end +self._lex_indicies = [ + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 1, 1, 2, 1, 2, 1, 1, + 2, 2, 1, 1, 1, 3, 1, 1, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 1, 1, 1, 1, 1, 1, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 1, 2, 2, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 2, 2, 1, 2, + 0, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 2, 2, 2, 2, + 2, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 2, 2, 2, + 1, 2, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 2, 2, 2, 2, + 2, 1, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 2, 2, 2, 2, + 2, 2, 6, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 2, 2, 2, + 2, 5, 2, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 2, 2, 2, + 2, 2, 5, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 2, 2, 2, + 2, 2, 2, 2, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 2, 2, + 2, 2, 7, 2, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 2, 2, + 2, 2, 2, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 8, 8, + 8, 8, 8, 8, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 8, + 8, 8, 8, 9, 8, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 8, + 8, 8, 8, 8, 9, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 11, + 11, 11, 11, 11, 11, 11, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 10, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 14, + 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 15, 12, 12, 12, 12, 14, 12, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 12, 12, 12, 12, 13, 12, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 12, 12, 12, 12, 12, 13, 15, + 12, 12, 16, 17, 12, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 20, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 21, + 18, 18, 18, 18, 20, 18, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 18, 18, 18, 18, 19, 18, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 18, 18, 18, 18, 18, 19, 21, 18, + 23, 22, 24, 22, 25, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 27, + 22, 27, 27, 27, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 27, 22, + 22, 22, 22, 28, 29, 22, 30, 22, + 31, 32, 33, 34, 35, 28, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 36, 22, 37, 33, 38, 39, 22, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 40, 41, 33, 42, 26, 22, 26, + 26, 26, 26, 26, 26, 26, 26, 43, + 26, 26, 26, 26, 26, 26, 26, 26, + 44, 26, 26, 45, 26, 46, 26, 26, + 26, 47, 48, 22, 42, 22, 26, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 49, 22, 49, 49, 49, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 49, + 22, 22, 22, 22, 50, 51, 22, 52, + 22, 53, 54, 55, 56, 57, 50, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 58, 22, 59, 55, 60, 61, 22, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 62, 63, 55, 24, 19, 22, + 19, 19, 19, 19, 19, 19, 19, 19, + 64, 19, 19, 19, 19, 19, 19, 19, + 19, 65, 19, 19, 66, 19, 67, 19, + 19, 19, 68, 69, 22, 24, 22, 19, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 20, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 21, 22, 22, 22, 22, 20, + 22, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 22, 22, 22, 22, 19, + 22, 19, 19, 19, 19, 19, 70, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 22, 22, 22, 22, 22, + 19, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 20, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 21, 22, 22, 22, 22, + 20, 22, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 22, 22, 22, 22, + 19, 22, 19, 19, 19, 19, 71, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 22, 22, 22, 22, + 22, 19, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 20, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 21, 22, 22, 22, + 22, 20, 22, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 22, 22, 22, + 22, 19, 22, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 72, 19, 19, + 19, 19, 19, 19, 19, 22, 22, 22, + 22, 22, 19, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 20, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 21, 22, 22, + 22, 22, 20, 22, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 22, 22, + 22, 22, 19, 22, 19, 19, 73, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 22, 22, + 22, 22, 22, 19, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 20, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 21, 22, + 22, 22, 22, 20, 22, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 22, + 22, 22, 22, 19, 22, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 74, 19, 19, 19, 19, 19, 22, + 22, 22, 22, 22, 19, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 20, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 21, + 22, 22, 22, 22, 20, 22, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 22, 22, 22, 22, 19, 22, 19, 19, + 19, 19, 70, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 22, 22, 22, 22, 22, 19, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 20, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 21, 22, 22, 22, 22, 20, 22, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 22, 22, 22, 22, 19, 22, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 75, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 22, 22, 22, 22, 22, 19, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 20, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 21, 22, 22, 22, 22, 20, 22, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 22, 22, 22, 22, 19, 22, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 76, 19, 19, 19, 19, + 19, 19, 19, 77, 19, 19, 19, 19, + 19, 19, 22, 22, 22, 22, 22, 19, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 20, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 21, 22, 22, 22, 22, 20, + 22, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 22, 22, 22, 22, 19, + 22, 19, 19, 19, 19, 78, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 22, 22, 22, 22, 22, + 19, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 20, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 21, 22, 22, 22, 22, + 20, 22, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 22, 22, 22, 22, + 19, 22, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 79, 19, 19, 19, + 19, 19, 19, 19, 22, 22, 22, 22, + 22, 19, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 20, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 21, 22, 22, 22, + 22, 20, 22, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 22, 22, 22, + 22, 19, 22, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 70, 19, 19, + 19, 19, 19, 19, 19, 22, 22, 22, + 22, 22, 19, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 20, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 21, 22, 22, + 22, 22, 20, 22, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 22, 22, + 22, 22, 19, 22, 19, 19, 19, 19, + 19, 19, 19, 19, 80, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 22, 22, + 22, 22, 22, 19, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 20, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 21, 22, + 22, 22, 22, 20, 22, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 22, + 22, 22, 22, 19, 22, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 70, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 22, + 22, 22, 22, 22, 19, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 20, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 21, + 22, 22, 22, 22, 20, 22, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 22, 22, 22, 22, 19, 22, 19, 19, + 19, 19, 19, 19, 19, 81, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 22, 22, 22, 22, 22, 19, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 20, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 21, 22, 22, 22, 22, 20, 22, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 22, 22, 22, 22, 19, 22, 19, + 19, 19, 19, 19, 19, 19, 19, 82, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 22, 22, 22, 22, 22, 19, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, + 20, 22, 22, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 21, 22, 22, 22, 22, 20, 22, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 22, 22, 22, 22, 19, 22, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 74, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 22, 22, 22, 22, 22, 19, + 84, 83, 85, 83, 86, 83, 55, 83, + 87, 83, 83, 83, 83, 83, 83, 83, + 88, 83, 89, 83, 90, 83, 55, 83, + 91, 83, 55, 83, 92, 83, 86, 83, + 94, 93, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 97, 95, 97, 97, 97, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 97, 95, 95, 95, 95, 95, + 95, 95, 98, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 95, 99, 95, + 95, 96, 95, 96, 96, 96, 100, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 95, 95, 95, + 95, 95, 96, 101, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 103, 95, + 103, 103, 103, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 103, 95, 95, + 95, 95, 95, 95, 95, 104, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 95, 105, 95, 95, 102, 95, 102, 102, + 102, 106, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 95, 95, 95, 95, 95, 102, 108, 107, + 108, 108, 108, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 108, 107, 107, + 107, 107, 107, 107, 107, 109, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 110, 107, 111, 107, 112, 107, 112, + 112, 112, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 112, 107, 107, 107, + 107, 107, 107, 107, 113, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, + 114, 107, 115, 116, 118, 117, 119, 117, + 120, 117, 121, 117, 122, 117, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, + 124, 124, 124, 124, 124, 124, 124, 123, + 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, + 123, 124, 124, 124, 124, 124, 124, 123, + 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, + 123, 124, 124, 124, 124, 124, 123, 125, + 115, 126, 127, 126, 126, 126, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 126, 115, 115, 128, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 129, 129, 129, 129, 129, 129, 129, 129, + 129, 129, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 130, 115, 131, 132, + 131, 131, 131, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 131, 115, 115, + 133, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 134, 134, 134, + 134, 134, 134, 134, 134, 134, 134, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 135, 115, 137, 138, 137, 137, 137, + 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 137, 136, 136, 139, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 140, 140, 140, 140, 140, 140, + 140, 140, 140, 140, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 136, 136, 136, 141, 136, + 143, 144, 143, 143, 143, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 143, + 142, 142, 145, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 147, 142, 143, 148, 143, + 143, 143, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 143, 142, 142, 145, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 147, 142, 127, 115, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 151, 151, 149, + 151, 149, 151, 151, 149, 149, 151, 151, + 151, 152, 151, 151, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 151, 151, + 151, 151, 151, 151, 151, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 149, + 151, 149, 149, 150, 151, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 149, + 149, 149, 151, 149, 150, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 151, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 149, + 149, 149, 149, 149, 149, 149, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 151, + 149, 149, 149, 149, 151, 149, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 151, + 151, 151, 151, 151, 151, 151, 151, 151, + 149, 149, 149, 149, 149, 151, 154, 151, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 151, + 149, 154, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 156, 149, 149, + 149, 149, 157, 149, 149, 149, 149, 149, + 158, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 125, 149, 149, 149, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 149, 149, + 149, 149, 155, 159, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 149, 149, + 149, 158, 149, 155, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 162, 161, + 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 161, 161, 161, 161, + 161, 161, 161, 161, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 161, 161, + 161, 161, 161, 161, 161, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 161, + 161, 161, 161, 160, 161, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 161, + 161, 161, 161, 161, 160, 164, 163, 167, + 166, 162, 161, 167, 168, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 156, + 149, 149, 149, 149, 157, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, + 149, 149, 149, 149, 155, 159, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, + 155, 155, 155, 155, 155, 155, 155, 155, + 149, 149, 149, 149, 149, 155, 170, 169, + 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 167, 169, 167, 170, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 172, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 173, 115, 115, 174, 115, 172, + 115, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 115, 115, 115, 115, 171, + 115, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 115, 115, 115, 115, 115, + 171, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 172, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 173, 149, 149, 174, 149, + 172, 149, 171, 171, 171, 171, 171, 171, + 175, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 149, 149, 149, 149, + 171, 149, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 149, 149, 149, 149, + 149, 171, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 172, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 173, 149, 149, 174, + 149, 172, 149, 171, 171, 171, 171, 171, + 171, 171, 171, 176, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 149, 149, 149, + 149, 171, 149, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 149, 149, 149, + 149, 149, 171, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 172, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 173, 149, 149, + 174, 149, 172, 149, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 177, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 149, 149, + 149, 149, 171, 149, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 149, 149, + 149, 149, 149, 171, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 172, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 173, 149, + 149, 174, 149, 172, 149, 171, 171, 171, + 177, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 149, + 149, 149, 149, 171, 149, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 149, + 149, 149, 149, 149, 171, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 180, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 181, + 178, 178, 178, 178, 180, 178, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, + 178, 178, 178, 178, 179, 178, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, + 178, 178, 178, 178, 178, 179, 181, 178, + 178, 182, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 184, 184, 184, 184, 184, 184, + 184, 184, 184, 184, 183, 183, 183, 183, + 183, 183, 183, 184, 184, 184, 184, 184, + 184, 184, 184, 184, 184, 184, 184, 184, + 184, 184, 184, 184, 184, 184, 184, 184, + 184, 184, 184, 184, 184, 183, 183, 183, + 183, 184, 183, 184, 184, 184, 184, 184, + 184, 184, 184, 184, 184, 184, 184, 184, + 184, 184, 184, 184, 184, 184, 184, 184, + 184, 184, 184, 184, 184, 183, 183, 183, + 183, 183, 184, 186, 185, 186, 185, 185, + 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 185, 187, 187, 187, 187, 187, + 187, 187, 187, 187, 187, 185, 188, 188, + 188, 188, 188, 188, 188, 188, 188, 188, + 185, 190, 190, 190, 190, 190, 190, 190, + 190, 190, 190, 189, 191, 191, 191, 191, + 191, 191, 191, 191, 191, 191, 189, 193, + 192, 194, 192, 195, 192, 196, 192, 198, + 197, 199, 197, 200, 197, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 183, + 183, 183, 183, 183, 183, 183, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 183, 183, 183, 183, 201, 183, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 183, 183, 183, 183, 183, 201, 202, 189, + 203, 204, 203, 203, 203, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 203, + 189, 189, 205, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 206, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 207, 189, 208, 209, 208, + 208, 208, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 208, 189, 189, 210, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 211, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 212, 189, 214, 215, 214, 214, 214, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 214, 213, 213, 216, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 217, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 218, 213, 220, + 221, 220, 220, 220, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 220, 219, + 219, 222, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 223, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 224, 219, 220, 221, 220, 220, + 220, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 220, 219, 219, 222, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 225, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 224, + 219, 220, 226, 220, 220, 220, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 220, 219, 219, 222, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 223, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 224, 219, 227, 189, + 204, 189, 229, 230, 229, 229, 229, 228, + 228, 228, 228, 228, 228, 228, 228, 228, + 228, 228, 228, 228, 228, 228, 228, 228, + 228, 229, 228, 228, 231, 228, 228, 232, + 228, 228, 228, 228, 228, 228, 228, 233, + 228, 228, 228, 228, 228, 228, 228, 228, + 228, 228, 228, 228, 228, 228, 228, 228, + 228, 228, 228, 228, 228, 228, 228, 228, + 228, 228, 228, 228, 228, 228, 228, 228, + 228, 228, 228, 228, 228, 228, 228, 228, + 228, 228, 228, 228, 228, 234, 228, 236, + 230, 236, 236, 236, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 236, 235, + 235, 231, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, + 235, 235, 234, 235, 239, 238, 241, 240, + 242, 237, 243, 237, 244, 228, 246, 245, + 247, 245, 248, 245, 249, 245, 250, 245, + 251, 245, 252, 245, 253, 245, 254, 245, + 255, 245, 245, 245, 255, 245, 245, 245, + 245, 245, 256, 245, 245, 245, 245, 245, + 245, 245, 245, 245, 245, 245, 245, 245, + 245, 245, 255, 245, 257, 258, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 259, 2, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, + 260, 260, 260, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 260, 260, 260, + 260, 260, 260, 260, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 260, 260, + 260, 260, 0, 260, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 260, 260, + 260, 260, 260, 0, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 260, 261, + 261, 261, 261, 261, 261, 261, 261, 261, + 261, 261, 261, 261, 261, 261, 261, 261, + 261, 261, 261, 261, 261, 261, 261, 261, + 261, 261, 261, 261, 261, 261, 261, 261, + 261, 261, 261, 261, 261, 261, 261, 261, + 261, 261, 261, 261, 261, 261, 261, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 261, 261, 261, 261, 261, 261, 261, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 261, 261, 261, 261, 5, 261, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 261, 261, 261, 261, 261, 5, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 262, 262, 262, 262, 262, 262, + 262, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 262, 262, 262, 262, 7, + 262, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 262, 262, 262, 262, 262, + 7, 264, 265, 265, 265, 264, 265, 265, + 265, 265, 266, 267, 266, 266, 266, 265, + 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 264, 265, 265, 265, 265, + 265, 266, 268, 265, 269, 270, 271, 272, + 265, 265, 265, 273, 274, 265, 274, 265, + 275, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 276, 265, 277, 278, 279, + 265, 265, 280, 281, 280, 280, 282, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 283, 284, 265, 275, + 285, 275, 286, 287, 288, 289, 290, 291, + 263, 263, 292, 263, 263, 263, 293, 294, + 295, 263, 263, 296, 297, 298, 299, 263, + 300, 263, 301, 263, 265, 302, 265, 274, + 265, 263, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 304, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 303, 303, 303, 304, + 303, 304, 303, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 303, 303, 303, + 303, 263, 303, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 303, 303, 303, + 303, 303, 263, 266, 305, 266, 266, 266, + 305, 305, 305, 305, 305, 305, 305, 305, + 305, 305, 305, 305, 305, 305, 305, 305, + 305, 305, 266, 305, 306, 275, 307, 307, + 275, 307, 307, 307, 307, 307, 307, 307, + 307, 307, 307, 307, 307, 307, 307, 307, + 307, 307, 307, 307, 307, 307, 307, 307, + 307, 307, 307, 307, 307, 307, 307, 307, + 307, 307, 307, 307, 307, 307, 307, 307, + 307, 307, 307, 307, 307, 307, 307, 307, + 307, 307, 307, 307, 307, 307, 307, 307, + 307, 307, 307, 307, 307, 307, 275, 307, + 308, 309, 310, 311, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 9, 9, 312, + 9, 312, 9, 9, 312, 312, 9, 9, + 9, 314, 9, 9, 315, 315, 315, 315, + 315, 315, 315, 315, 315, 315, 9, 9, + 9, 9, 9, 9, 9, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 312, + 9, 312, 312, 313, 9, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 312, + 312, 312, 9, 312, 313, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 316, + 316, 316, 316, 316, 316, 316, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 313, + 316, 316, 316, 316, 313, 316, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 313, + 313, 313, 313, 313, 313, 313, 313, 313, + 316, 316, 316, 316, 316, 313, 315, 315, + 315, 315, 315, 315, 315, 315, 315, 315, + 316, 317, 307, 275, 307, 275, 307, 275, + 307, 319, 318, 275, 320, 307, 275, 307, + 321, 275, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, + 312, 275, 312, 275, 307, 275, 275, 307, + 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, + 303, 304, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 303, 303, 303, 304, 303, 304, + 303, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 303, 303, 303, 303, 280, + 303, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 303, 303, 303, 303, 303, + 280, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 304, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 322, 322, 322, 304, 322, + 304, 322, 280, 280, 280, 280, 323, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 322, 322, 322, 322, + 280, 322, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 322, 322, 322, 322, + 322, 280, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 304, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 322, 322, 322, 304, + 322, 304, 322, 280, 280, 280, 280, 280, + 280, 324, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 322, 322, 322, + 322, 280, 322, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 322, 322, 322, + 322, 322, 280, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 304, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 322, 322, 322, + 304, 322, 304, 322, 280, 280, 280, 280, + 280, 280, 280, 280, 325, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 322, 322, + 322, 322, 280, 322, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 322, 322, + 322, 322, 322, 280, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 304, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 322, 322, + 322, 304, 322, 304, 322, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 326, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 322, + 322, 322, 322, 280, 322, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 322, + 322, 322, 322, 322, 280, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 304, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 322, + 322, 322, 304, 322, 304, 322, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 327, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 322, 322, 322, 322, 280, 322, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 322, 322, 322, 322, 322, 280, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 322, 304, + 322, 322, 322, 322, 322, 322, 322, 322, + 322, 322, 322, 322, 322, 322, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 322, 322, 322, 304, 322, 304, 322, 280, + 280, 280, 326, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 322, 322, 322, 322, 280, 322, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, + 280, 322, 322, 322, 322, 322, 280, 321, + 312, 267, 312, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 304, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 304, 328, 304, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 329, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 328, 263, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 304, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 304, 328, 304, 328, 263, 263, 263, + 263, 330, 331, 263, 263, 263, 263, 263, + 332, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 263, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 328, 263, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 304, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 304, 328, 304, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 333, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 263, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 328, 263, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 304, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 304, 328, 304, 328, 263, + 263, 334, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 263, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 328, 263, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 304, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 304, 328, 304, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 335, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 263, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 328, 263, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 304, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 304, 328, 304, + 328, 263, 263, 263, 336, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 263, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 328, + 263, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 304, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 304, 328, + 304, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 337, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 263, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 328, 263, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 304, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 304, + 328, 304, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 338, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 263, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 328, 263, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 304, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 304, 328, 304, 328, 263, 263, 263, 263, + 263, 263, 339, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 263, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 328, 263, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 304, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 304, 328, 304, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 340, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 328, 263, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 304, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 304, 328, 304, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 341, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 328, 263, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 304, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 304, 328, 304, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 342, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 263, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 328, 263, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 304, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 304, 328, 304, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 343, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 263, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 328, 263, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 304, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 304, 328, 304, + 328, 263, 263, 263, 263, 339, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 263, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 328, + 263, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 304, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 304, 328, + 304, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 344, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 263, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 328, 263, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 304, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 304, + 328, 304, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 343, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 263, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 328, 263, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 304, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 304, 328, 304, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 263, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 345, + 263, 346, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 328, 263, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 304, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 304, 328, 304, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 263, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 347, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 328, 263, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 304, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 304, 328, 304, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 263, 328, 348, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 328, 263, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 304, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 304, 328, 304, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 263, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 341, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 328, 263, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 304, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 304, 328, 304, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 263, 328, + 263, 263, 263, 341, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 328, 263, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 304, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 304, 328, 304, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 263, + 328, 263, 263, 263, 263, 349, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 350, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 328, + 263, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 304, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 304, 328, + 304, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 263, 328, 263, 263, 263, 263, 263, 263, + 351, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 328, 263, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 304, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 304, + 328, 304, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 263, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 352, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 328, 263, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 304, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 304, 328, 304, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 263, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 341, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 328, 263, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 304, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 304, 328, 304, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 263, 328, 263, 263, 263, + 263, 353, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 328, 263, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 304, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 304, 328, 304, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 263, 328, 354, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 328, 263, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 304, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 304, 328, 304, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 263, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 341, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 328, 263, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 304, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 304, 328, 304, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 263, 328, + 355, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 356, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 328, 263, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 304, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 304, 328, 304, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 263, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 357, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 328, + 263, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 304, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 304, 328, + 304, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 263, 328, 263, 263, 263, 263, 341, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 328, 263, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 304, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 304, + 328, 304, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 263, 328, 358, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 328, 263, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 304, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 304, 328, 304, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 263, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 348, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 328, 263, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 304, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 304, 328, 304, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 263, 328, 263, 263, 263, + 263, 359, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 341, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 328, 263, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 304, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 304, 328, 304, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 263, 328, 263, 263, + 263, 263, 263, 360, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 328, 263, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 304, + 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 361, 361, 361, 304, 361, 304, 361, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 361, 361, 361, 361, 263, 361, 263, + 263, 263, 263, 263, 263, 263, 263, 362, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 361, 361, 361, 361, 361, 263, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 304, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 304, 328, 304, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 263, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 363, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 328, 263, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 304, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 304, 328, 304, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 263, + 328, 263, 263, 263, 263, 364, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 328, + 263, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 304, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 304, 328, + 304, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 263, 328, 263, 263, 263, 365, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 328, 263, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 304, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 304, + 328, 366, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 263, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 328, 263, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 304, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 304, 328, 304, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 263, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 367, + 263, 368, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 328, 263, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 304, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 304, 328, 304, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 263, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 369, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 328, 263, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 304, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 304, 328, 304, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 263, 328, 263, 263, + 263, 263, 341, 263, 263, 263, 370, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 328, 263, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 304, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 304, 328, 304, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 263, 328, 263, + 263, 263, 263, 263, 341, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 328, 263, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 304, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 304, 328, 304, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 263, 328, + 263, 263, 263, 341, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 371, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 328, 263, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 304, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 304, 328, 304, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 263, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 372, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 328, + 263, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 304, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 304, 328, + 304, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 263, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 357, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 328, 263, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 304, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 304, + 328, 304, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 263, 328, 373, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 295, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 328, 263, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 304, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 304, 328, 304, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 263, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 355, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 328, 263, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 304, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 304, 328, 304, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 263, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 341, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 328, 263, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 304, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 304, 328, 304, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 263, 328, 263, 263, + 263, 263, 263, 341, 263, 263, 263, 263, + 263, 263, 263, 341, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 328, 263, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 304, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 304, 328, 304, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 263, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 374, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 328, 263, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 304, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 304, 328, 304, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 263, 328, + 263, 263, 263, 375, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 328, 263, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 304, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 304, 328, 304, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 263, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 376, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 328, + 263, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 304, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 304, 328, + 304, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 263, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 357, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 328, 263, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 304, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 304, + 328, 304, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 263, 328, 263, 263, 263, 263, 377, + 263, 263, 263, 378, 263, 263, 263, 263, + 263, 379, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 328, 263, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 304, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 304, 328, 304, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 263, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 379, 263, 263, 328, 328, + 328, 328, 328, 263, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 304, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 304, 328, 304, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 263, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 341, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 328, 263, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 304, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 304, 328, 304, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 263, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 341, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 328, 263, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 304, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 304, 328, 304, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 263, 328, 263, + 263, 263, 263, 380, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 328, 263, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 304, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 304, 328, 304, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 263, 328, + 263, 263, 263, 381, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 382, 383, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 328, 263, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 304, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 304, 328, 304, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 263, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 341, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 328, + 263, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 304, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 304, 328, + 304, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 263, 328, 263, 263, 384, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 328, 263, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 304, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 304, + 328, 304, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 263, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 357, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 328, 263, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 304, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 304, 328, 304, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 263, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 385, 263, 263, + 386, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 328, 263, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 304, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 304, 328, 304, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 263, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 341, 263, 328, + 328, 328, 328, 328, 263, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 304, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 304, 328, 304, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 263, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 352, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 328, 263, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 304, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 304, 328, 304, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 263, 328, 263, + 263, 263, 263, 387, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 388, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 328, 263, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 304, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 304, 328, 304, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 263, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 370, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 328, 263, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 304, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 304, 328, 304, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 263, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 389, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 328, + 263, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 304, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 304, 328, + 304, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 263, 328, 263, 263, 263, 263, 295, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 328, 263, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 304, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 304, + 328, 304, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 263, 328, 263, 263, 263, 263, 263, + 263, 263, 390, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 384, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 328, 263, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 304, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 304, 328, 304, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 263, 328, 263, 263, 263, 263, + 352, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 328, 263, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 304, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 304, 328, 304, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 263, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 391, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 328, 263, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 304, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 304, 328, 304, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 263, 328, 263, 263, + 263, 392, 263, 263, 263, 263, 263, 263, + 263, 393, 263, 263, 263, 263, 263, 263, + 263, 394, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 328, 263, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 304, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 304, 328, 304, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 263, 328, 263, + 263, 263, 263, 370, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 328, 328, 263, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 304, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 328, 328, 328, 304, 328, 304, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 263, 328, + 263, 263, 263, 263, 358, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 328, 328, 263, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 304, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 328, 328, 328, 304, 328, 304, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 263, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 378, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 328, 328, + 263, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 304, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 328, 328, 328, 304, 328, + 304, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 263, 328, 263, 263, 263, 263, 263, 263, + 263, 395, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 328, + 328, 263, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 304, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 328, 328, 328, 304, + 328, 304, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 263, 328, 263, 263, 263, 263, 352, + 263, 263, 263, 376, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 328, 328, 263, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 304, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 328, 328, 328, + 304, 328, 304, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 263, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 396, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 328, 328, 263, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 304, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 328, 328, + 328, 304, 328, 304, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 263, 328, 263, 263, 263, + 263, 397, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 328, 328, 263, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 304, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 328, + 328, 328, 304, 328, 304, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 263, 328, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 263, 346, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, + 328, 328, 328, 328, 328, 263, 275, 307, + 399, 400, 400, 400, 399, 400, 400, 400, + 400, 401, 400, 401, 401, 401, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 399, 400, 400, 400, 400, 400, + 401, 400, 400, 402, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 403, 400, + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 400, 404, 400, 400, 398, + 400, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 400, 400, 400, 400, 400, + 398, 405, 405, 405, 405, 405, 405, 405, + 405, 405, 405, 405, 405, 405, 405, 405, + 405, 405, 405, 405, 405, 405, 405, 405, + 405, 405, 405, 405, 405, 405, 405, 405, + 405, 405, 14, 405, 405, 405, 405, 405, + 405, 405, 405, 405, 405, 405, 405, 405, + 405, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 15, 405, 405, 405, 405, + 14, 405, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 405, 405, 405, 405, + 13, 405, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 405, 405, 405, 405, + 405, 13, 401, 406, 401, 401, 401, 406, + 406, 406, 406, 406, 406, 406, 406, 406, + 406, 406, 406, 406, 406, 406, 406, 406, + 406, 401, 406, 407, 408, 409, 410, 411, + 405, 412, 405, 413, 415, 416, 416, 416, + 415, 416, 416, 416, 416, 417, 418, 417, + 417, 417, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 415, 416, + 416, 416, 416, 416, 417, 419, 416, 420, + 416, 421, 422, 416, 416, 416, 423, 424, + 416, 424, 416, 421, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 425, 426, 427, 416, 416, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 429, + 430, 416, 421, 414, 421, 414, 414, 414, + 414, 414, 414, 414, 414, 414, 414, 414, + 414, 414, 414, 414, 414, 414, 414, 414, + 414, 414, 414, 414, 414, 414, 414, 416, + 431, 416, 424, 416, 414, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, 433, 432, + 432, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 414, 414, 414, + 414, 414, 414, 414, 414, 414, 414, 432, + 432, 432, 432, 432, 433, 432, 414, 414, + 414, 414, 414, 414, 414, 414, 414, 414, + 414, 414, 414, 414, 414, 414, 414, 414, + 414, 414, 414, 414, 414, 414, 414, 414, + 432, 432, 432, 432, 414, 432, 414, 414, + 414, 414, 414, 414, 414, 414, 414, 414, + 414, 414, 414, 414, 414, 414, 414, 414, + 414, 414, 414, 414, 414, 414, 414, 414, + 432, 432, 432, 432, 432, 414, 435, 434, + 436, 417, 437, 417, 417, 417, 437, 437, + 437, 437, 437, 437, 437, 437, 437, 437, + 437, 437, 437, 437, 437, 437, 437, 437, + 417, 437, 438, 421, 439, 439, 421, 439, + 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 421, 439, 440, 441, + 442, 443, 421, 439, 421, 439, 421, 439, + 421, 444, 439, 421, 439, 446, 421, 445, + 445, 445, 445, 445, 445, 445, 445, 445, + 445, 445, 445, 445, 445, 445, 445, 445, + 445, 445, 445, 445, 445, 445, 445, 445, + 445, 445, 445, 445, 445, 445, 445, 445, + 445, 445, 445, 445, 445, 445, 445, 445, + 445, 445, 445, 445, 445, 445, 445, 445, + 445, 445, 445, 445, 445, 445, 445, 445, + 445, 445, 445, 445, 445, 445, 421, 445, + 421, 439, 421, 421, 439, 447, 447, 447, + 447, 447, 447, 447, 447, 447, 447, 447, + 447, 447, 447, 447, 447, 447, 447, 447, + 447, 447, 447, 447, 447, 447, 447, 447, + 447, 447, 447, 447, 447, 447, 433, 447, + 447, 447, 447, 447, 447, 447, 447, 447, + 447, 447, 447, 447, 447, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 447, + 447, 447, 447, 447, 433, 447, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 447, 447, 447, 447, 428, 447, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, + 447, 447, 447, 447, 447, 428, 446, 445, + 418, 445, 421, 439, 449, 448, 448, 448, + 449, 448, 448, 448, 448, 450, 451, 450, + 450, 450, 448, 448, 448, 448, 448, 448, + 448, 448, 448, 448, 448, 448, 449, 448, + 448, 448, 448, 448, 450, 448, 448, 452, + 448, 24, 453, 448, 454, 448, 455, 24, + 55, 456, 57, 24, 448, 448, 448, 448, + 448, 448, 448, 448, 448, 448, 457, 448, + 458, 55, 459, 460, 448, 448, 448, 448, + 448, 448, 448, 448, 448, 448, 448, 448, + 448, 448, 448, 448, 448, 448, 448, 448, + 448, 448, 448, 448, 448, 448, 448, 55, + 461, 55, 24, 448, 448, 448, 448, 448, + 448, 448, 448, 448, 448, 462, 448, 448, + 448, 448, 448, 448, 448, 448, 463, 448, + 448, 464, 448, 465, 448, 448, 448, 68, + 69, 448, 24, 448, 466, 466, 466, 466, + 466, 466, 466, 466, 466, 450, 466, 450, + 450, 450, 466, 466, 466, 466, 466, 466, + 466, 466, 466, 466, 466, 466, 466, 466, + 466, 466, 466, 466, 450, 466, 466, 466, + 466, 50, 51, 466, 52, 466, 53, 54, + 55, 56, 57, 50, 466, 466, 466, 466, + 466, 466, 466, 466, 466, 466, 58, 466, + 59, 55, 60, 61, 466, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 62, + 63, 55, 24, 19, 466, 19, 19, 19, + 19, 19, 19, 19, 19, 64, 19, 19, + 19, 19, 19, 19, 19, 19, 65, 19, + 19, 66, 19, 67, 19, 19, 19, 68, + 69, 466, 24, 466, 19, 467, 468, 468, + 468, 467, 468, 468, 468, 468, 55, 469, + 55, 55, 55, 468, 468, 468, 468, 468, + 468, 468, 468, 468, 468, 468, 468, 467, + 468, 468, 468, 468, 468, 55, 468, 468, + 468, 468, 468, 468, 468, 468, 468, 468, + 468, 468, 468, 468, 468, 468, 468, 468, + 468, 468, 468, 468, 468, 468, 468, 468, + 468, 468, 55, 468, 55, 469, 55, 55, + 55, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 55, 18, 18, 18, 18, + 18, 24, 18, 18, 18, 18, 18, 18, + 18, 55, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 55, 18, 55, 469, 55, 55, 55, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 55, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 55, 18, + 470, 55, 469, 55, 55, 55, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, + 55, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 472, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 55, 471, 55, + 469, 55, 55, 55, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 55, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 55, 55, 18, 473, 467, + 55, 467, 475, 474, 477, 478, 477, 477, + 477, 476, 476, 476, 476, 476, 476, 476, + 476, 476, 476, 476, 476, 476, 476, 476, + 476, 476, 476, 477, 476, 479, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 20, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 21, 467, 467, 467, 467, 20, 467, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 467, 467, 467, 467, 19, 467, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 19, 467, 467, 467, 467, 467, 19, 480, + 55, 469, 55, 55, 55, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 55, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 55, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 24, 467, 481, 482, 483, + 484, 485, 486, 55, 469, 55, 55, 55, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 55, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 24, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 55, + 467, 55, 474, 24, 487, 24, 487, 488, + 489, 488, 488, 488, 476, 476, 476, 476, + 476, 476, 476, 476, 476, 476, 476, 476, + 476, 476, 476, 476, 476, 476, 488, 476, + 490, 487, 491, 491, 491, 491, 491, 491, + 491, 491, 491, 27, 491, 27, 27, 27, + 491, 491, 491, 491, 491, 491, 491, 491, + 491, 491, 491, 491, 491, 491, 491, 491, + 491, 491, 27, 491, 491, 491, 491, 28, + 29, 491, 30, 491, 31, 32, 33, 34, + 35, 28, 491, 491, 491, 491, 491, 491, + 491, 491, 491, 491, 36, 491, 37, 33, + 38, 39, 491, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 40, 41, 33, + 42, 26, 491, 26, 26, 26, 26, 26, + 26, 26, 26, 43, 26, 26, 26, 26, + 26, 26, 26, 26, 44, 26, 26, 45, + 26, 46, 26, 26, 26, 47, 48, 491, + 42, 491, 26, 55, 487, 492, 487, 493, + 487, 494, 487, 495, 94, 94, 94, 495, + 94, 94, 94, 94, 496, 94, 496, 496, + 496, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 495, 94, 94, + 94, 94, 94, 496, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 94, 497, + 94, 94, 96, 94, 96, 96, 96, 100, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 94, 94, + 94, 94, 94, 96, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 93, 498, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 93, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 94, 93, + 93, 93, 93, 498, 93, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 93, + 93, 93, 93, 96, 93, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 93, + 93, 93, 93, 93, 96, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 97, 499, + 97, 97, 97, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 97, 499, 499, + 499, 499, 499, 499, 499, 98, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 499, 99, 499, 499, 96, 499, 96, 96, + 96, 100, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 499, 499, 499, 499, 499, 96, 500, 499, + 499, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, + 498, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 94, 499, 499, 499, 499, 498, 499, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 499, 499, 499, 499, 96, 499, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 501, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 499, 499, 499, 499, 499, 96, + 101, 499, 503, 502, 502, 502, 503, 502, + 502, 502, 502, 504, 502, 504, 504, 504, + 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 503, 502, 502, 502, + 502, 502, 504, 502, 502, 505, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 506, 502, + 502, 502, 502, 502, 502, 502, 507, 502, + 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 508, 502, 504, + 509, 504, 504, 504, 509, 509, 509, 509, + 509, 509, 509, 509, 509, 509, 509, 509, + 509, 509, 509, 509, 509, 509, 504, 509, + 510, 511, 512, 513, 515, 514, 516, 517, + 514, 518, 520, 521, 521, 521, 520, 521, + 521, 521, 521, 522, 523, 522, 522, 522, + 521, 521, 521, 521, 521, 521, 521, 521, + 521, 521, 521, 521, 520, 521, 521, 521, + 521, 521, 522, 521, 521, 524, 521, 521, + 521, 521, 521, 521, 521, 521, 521, 521, + 521, 521, 521, 521, 521, 521, 521, 521, + 521, 521, 521, 521, 521, 521, 521, 521, + 521, 521, 521, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 521, 525, 521, + 521, 519, 521, 519, 519, 519, 519, 519, + 519, 519, 519, 526, 519, 519, 519, 519, + 519, 519, 519, 519, 527, 519, 519, 528, + 519, 529, 519, 519, 519, 521, 521, 521, + 521, 521, 519, 530, 530, 530, 530, 530, + 530, 530, 530, 530, 530, 530, 530, 530, + 530, 530, 530, 530, 530, 530, 530, 530, + 530, 530, 530, 530, 530, 530, 530, 530, + 530, 530, 530, 530, 530, 530, 530, 530, + 530, 530, 530, 530, 530, 530, 530, 530, + 530, 530, 530, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 530, 530, 530, + 530, 530, 530, 530, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 530, 530, + 530, 530, 519, 530, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 530, 530, + 530, 530, 530, 519, 522, 531, 522, 522, + 522, 531, 531, 531, 531, 531, 531, 531, + 531, 531, 531, 531, 531, 531, 531, 531, + 531, 531, 531, 522, 531, 532, 533, 534, + 535, 536, 538, 537, 539, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 540, + 540, 540, 540, 540, 540, 540, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 540, 540, 540, 540, 519, 540, 519, 519, + 519, 519, 519, 541, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 540, 540, 540, 540, 540, 519, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 540, 540, 540, 540, 540, 540, 540, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 540, 540, 540, 540, 519, 540, 519, + 519, 519, 519, 542, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 540, 540, 540, 540, 540, 519, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 540, 540, 540, 540, 540, 540, 540, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 540, 540, 540, 540, 519, 540, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 543, 519, 519, 519, 519, 519, + 519, 519, 540, 540, 540, 540, 540, 519, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 540, 540, 540, 540, 540, 540, + 540, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 540, 540, 540, 540, 519, + 540, 519, 519, 544, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 540, 540, 540, 540, 540, + 519, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 540, 540, 540, 540, 540, + 540, 540, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 540, 540, 540, 540, + 519, 540, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 545, 519, + 519, 519, 519, 519, 540, 540, 540, 540, + 540, 519, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 540, 540, 540, 540, + 540, 540, 540, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 540, 540, 540, + 540, 519, 540, 519, 519, 519, 519, 541, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 540, 540, 540, + 540, 540, 519, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 540, 540, 540, + 540, 540, 540, 540, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 540, 540, + 540, 540, 519, 540, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 546, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 540, 540, + 540, 540, 540, 519, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 540, 540, + 540, 540, 540, 540, 540, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 540, + 540, 540, 540, 519, 540, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 547, 519, 519, 519, 519, 519, 519, 519, + 548, 519, 519, 519, 519, 519, 519, 540, + 540, 540, 540, 540, 519, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 540, + 540, 540, 540, 540, 540, 540, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 540, 540, 540, 540, 519, 540, 519, 519, + 519, 519, 549, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 540, 540, 540, 540, 540, 519, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 540, 540, 540, 540, 540, 540, 540, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 540, 540, 540, 540, 519, 540, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 550, 519, 519, 519, 519, 519, 519, + 519, 540, 540, 540, 540, 540, 519, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 540, 540, 540, 540, 540, 540, 540, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 540, 540, 540, 540, 519, 540, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 541, 519, 519, 519, 519, 519, + 519, 519, 540, 540, 540, 540, 540, 519, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 540, 540, 540, 540, 540, 540, + 540, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 540, 540, 540, 540, 519, + 540, 519, 519, 519, 519, 519, 519, 519, + 519, 551, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 540, 540, 540, 540, 540, + 519, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 540, 540, 540, 540, 540, + 540, 540, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 540, 540, 540, 540, + 519, 540, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 541, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 540, 540, 540, 540, + 540, 519, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 540, 540, 540, 540, + 540, 540, 540, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 540, 540, 540, + 540, 519, 540, 519, 519, 519, 519, 519, + 519, 519, 552, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 540, 540, 540, + 540, 540, 519, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 540, 540, 540, + 540, 540, 540, 540, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 540, 540, + 540, 540, 519, 540, 519, 519, 519, 519, + 519, 519, 519, 519, 553, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 540, 540, + 540, 540, 540, 519, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, 540, 540, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 540, 540, + 540, 540, 540, 540, 540, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 540, + 540, 540, 540, 519, 540, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, + 545, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 540, + 540, 540, 540, 540, 519, 555, 125, 125, + 125, 555, 125, 125, 125, 125, 556, 557, + 556, 556, 556, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 555, + 125, 125, 125, 125, 125, 556, 558, 125, + 559, 125, 560, 561, 125, 562, 125, 563, + 564, 125, 565, 566, 567, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 568, + 125, 569, 570, 571, 572, 125, 573, 574, + 573, 573, 575, 573, 573, 573, 573, 573, + 573, 573, 573, 573, 573, 573, 573, 573, + 573, 573, 573, 573, 573, 573, 573, 573, + 576, 577, 125, 578, 579, 125, 580, 581, + 582, 583, 584, 585, 554, 554, 586, 554, + 554, 554, 587, 588, 589, 554, 554, 590, + 591, 592, 593, 554, 594, 554, 595, 554, + 596, 597, 125, 578, 125, 554, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 598, 599, 599, 599, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 172, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 173, 598, 598, 174, 598, 172, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 600, 598, 598, 554, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 598, 598, 598, 598, 554, 602, + 601, 601, 603, 601, 604, 606, 607, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 608, 605, + 610, 609, 611, 612, 613, 556, 614, 556, + 556, 556, 614, 614, 614, 614, 614, 614, + 614, 614, 614, 614, 614, 614, 614, 614, + 614, 614, 614, 614, 556, 614, 616, 615, + 618, 619, 618, 618, 618, 617, 617, 617, + 617, 617, 617, 617, 617, 617, 617, 617, + 617, 617, 617, 617, 617, 617, 617, 618, + 617, 125, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 125, 620, 621, 622, 623, 624, + 626, 626, 626, 626, 626, 626, 626, 626, + 626, 626, 626, 626, 626, 626, 626, 626, + 626, 626, 626, 626, 626, 626, 626, 626, + 626, 626, 626, 626, 626, 626, 626, 626, + 626, 626, 626, 626, 626, 626, 626, 626, + 626, 626, 626, 626, 626, 626, 626, 626, + 625, 625, 625, 625, 625, 625, 625, 625, + 625, 625, 626, 626, 626, 626, 626, 626, + 626, 627, 627, 627, 627, 627, 627, 627, + 627, 627, 627, 627, 627, 627, 627, 627, + 627, 627, 627, 627, 627, 627, 627, 627, + 627, 627, 627, 626, 626, 626, 626, 626, + 626, 627, 627, 627, 627, 627, 627, 627, + 627, 627, 627, 627, 627, 627, 627, 627, + 627, 627, 627, 627, 627, 627, 627, 627, + 627, 627, 627, 626, 626, 626, 626, 626, + 625, 629, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 628, + 125, 628, 630, 632, 631, 631, 631, 631, + 631, 631, 631, 631, 631, 631, 631, 631, + 631, 631, 631, 631, 631, 631, 125, 631, + 125, 115, 126, 127, 126, 126, 126, 628, + 628, 628, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 628, + 628, 126, 628, 628, 128, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 628, + 628, 129, 129, 129, 129, 129, 129, 129, + 129, 129, 129, 628, 628, 628, 125, 628, + 628, 628, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 628, 628, 130, 628, 143, + 144, 143, 143, 143, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 143, 142, + 142, 145, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 147, 142, 126, 127, 126, 126, + 126, 628, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 126, 628, 628, 128, 628, + 628, 628, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 129, 129, 129, 129, 129, + 129, 129, 129, 129, 129, 628, 628, 628, + 125, 125, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 628, 628, 628, 628, 130, + 628, 634, 620, 636, 635, 638, 637, 620, + 639, 639, 639, 620, 639, 639, 639, 639, + 639, 639, 639, 639, 639, 639, 639, 639, + 639, 639, 639, 639, 639, 639, 639, 639, + 639, 620, 639, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 641, 642, 620, 643, + 151, 644, 642, 620, 620, 645, 646, 620, + 646, 620, 151, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 647, 620, 648, + 649, 650, 620, 651, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 652, 620, + 620, 151, 640, 151, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 620, 653, + 620, 654, 620, 640, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 656, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 655, 655, + 655, 657, 655, 656, 655, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 640, 655, + 655, 655, 655, 640, 655, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 640, 640, 655, + 655, 655, 655, 655, 640, 659, 658, 660, + 662, 663, 661, 661, 661, 661, 661, 661, + 661, 661, 661, 661, 661, 661, 661, 661, + 661, 661, 661, 661, 661, 661, 661, 661, + 661, 661, 661, 661, 661, 661, 661, 661, + 661, 661, 661, 661, 661, 661, 661, 661, + 661, 661, 661, 661, 661, 661, 661, 661, + 661, 661, 661, 661, 661, 661, 661, 661, + 661, 661, 661, 661, 661, 661, 661, 661, + 661, 664, 661, 666, 667, 665, 668, 669, + 670, 671, 151, 655, 655, 672, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 151, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 655, 655, 655, + 655, 655, 655, 655, 655, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 655, + 655, 655, 655, 655, 655, 655, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, + 655, 655, 655, 655, 150, 655, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 150, 150, 150, 150, + 655, 655, 655, 655, 655, 150, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, + 655, 673, 655, 151, 655, 151, 655, 151, + 674, 655, 151, 655, 151, 655, 151, 151, + 655, 675, 675, 675, 675, 675, 675, 675, + 675, 675, 675, 675, 675, 675, 675, 675, + 675, 675, 675, 675, 675, 675, 675, 675, + 675, 675, 675, 675, 675, 675, 675, 675, + 675, 675, 675, 675, 675, 675, 675, 675, + 675, 675, 675, 675, 675, 675, 675, 675, + 675, 677, 677, 677, 677, 677, 677, 677, + 677, 677, 677, 675, 675, 675, 675, 675, + 675, 678, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 675, 675, 675, 675, + 676, 675, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, + 676, 676, 676, 676, 675, 675, 675, 675, + 675, 676, 680, 680, 680, 680, 680, 680, + 680, 680, 680, 680, 679, 681, 681, 681, + 681, 681, 681, 681, 681, 681, 681, 681, + 681, 681, 681, 681, 681, 681, 681, 681, + 681, 681, 681, 681, 681, 681, 681, 681, + 681, 681, 681, 681, 681, 681, 681, 681, + 681, 681, 681, 681, 681, 681, 681, 681, + 681, 681, 681, 681, 681, 683, 683, 683, + 683, 683, 683, 683, 683, 683, 683, 681, + 681, 681, 681, 681, 681, 681, 682, 682, + 682, 682, 682, 682, 682, 682, 682, 682, + 682, 682, 682, 682, 682, 682, 682, 682, + 682, 682, 682, 682, 682, 682, 682, 682, + 681, 681, 681, 681, 682, 681, 682, 682, + 682, 682, 682, 682, 682, 682, 682, 682, + 682, 682, 682, 682, 682, 682, 682, 682, + 682, 682, 682, 682, 682, 682, 682, 682, + 681, 681, 681, 681, 681, 682, 673, 655, + 672, 655, 684, 685, 620, 686, 166, 156, + 156, 156, 156, 156, 156, 156, 156, 156, + 156, 156, 156, 156, 156, 156, 156, 156, + 156, 156, 156, 156, 156, 156, 167, 156, + 168, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 157, 157, 157, + 157, 157, 157, 157, 157, 167, 157, 167, + 170, 125, 620, 578, 125, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 125, 620, 125, 629, + 620, 690, 689, 689, 689, 690, 689, 689, + 689, 689, 689, 689, 689, 689, 689, 689, + 689, 689, 689, 689, 689, 689, 689, 689, + 689, 689, 689, 690, 689, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 172, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 173, + 115, 115, 174, 115, 172, 115, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 115, 115, 115, 115, 171, 115, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 115, 115, 115, 115, 115, 171, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 172, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 173, 620, 620, 174, 620, 172, 620, 171, + 171, 171, 171, 691, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 620, 620, 620, 620, 171, 620, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 620, 620, 620, 620, 620, 171, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 172, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 173, 620, 620, 174, 620, 172, 620, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 692, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 620, 620, 620, 620, 171, 620, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 620, 620, 620, 620, 620, 171, + 693, 694, 620, 615, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 598, 599, + 599, 599, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 172, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 173, 598, + 598, 174, 598, 172, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 600, 598, 598, 695, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 598, 598, 598, 598, 554, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 598, + 599, 599, 599, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 172, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 173, + 598, 598, 174, 598, 172, 598, 554, 554, + 554, 554, 696, 697, 554, 554, 554, 554, + 554, 698, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 600, 598, 598, 554, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 598, 598, 598, 598, 554, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 598, 599, 599, 599, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 172, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 173, 598, 598, 174, 598, 172, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 699, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 600, 598, 598, 554, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 598, 598, 598, 598, 554, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 598, 599, 599, 599, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 172, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 173, 598, 598, 174, 598, 172, 598, + 554, 554, 700, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 600, 598, 598, 554, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 598, 598, 598, 598, 554, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 598, 599, 599, 599, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 172, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 173, 598, 598, 174, 598, 172, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 701, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 600, 598, 598, 554, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 598, 598, 598, 598, + 554, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 598, 599, 599, 599, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 172, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 173, 598, 598, 174, 598, + 172, 598, 554, 554, 554, 702, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 600, 598, 598, + 554, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 598, 598, 598, + 598, 554, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 598, 599, 599, 599, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 172, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 173, 598, 598, 174, + 598, 172, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 703, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 600, 598, + 598, 554, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 598, 598, + 598, 598, 554, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 598, 599, 599, + 599, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 172, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 173, 598, 598, + 174, 598, 172, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 704, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 600, + 598, 598, 554, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 598, + 598, 598, 598, 554, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 598, 599, + 599, 599, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 172, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 173, 598, + 598, 174, 598, 172, 598, 554, 554, 554, + 554, 554, 554, 705, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 600, 598, 598, 554, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 598, 598, 598, 598, 554, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 598, + 599, 599, 599, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 172, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 173, + 598, 598, 174, 598, 172, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 600, 598, 598, 706, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 598, 598, 598, 598, 554, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 598, 599, 599, 599, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 172, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 173, 598, 598, 174, 598, 172, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 600, 598, 598, 707, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 598, 598, 598, 598, 554, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, + 172, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 173, 115, 115, 174, 115, 172, 115, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 115, 115, 115, 115, 554, 115, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 115, 115, 115, 115, 115, 554, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 598, 599, 599, 599, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 172, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 173, 598, 598, 174, 598, 172, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 708, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 600, 598, 598, 554, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 598, 598, 598, 598, + 554, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 598, 599, 599, 599, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 172, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 173, 598, 598, 174, 598, + 172, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 709, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 600, 598, 598, + 554, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 598, 598, 598, + 598, 554, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 598, 599, 599, 599, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 172, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 173, 598, 598, 174, + 598, 172, 598, 554, 554, 554, 554, 705, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 600, 598, + 598, 554, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 598, 598, + 598, 598, 554, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 598, 599, 599, + 599, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 172, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 173, 598, 598, + 174, 598, 172, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 710, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 600, + 598, 598, 554, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 598, + 598, 598, 598, 554, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 598, 599, + 599, 599, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 172, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 173, 598, + 598, 174, 598, 172, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 709, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 600, 598, 598, 554, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 598, 598, 598, 598, 554, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 598, + 599, 599, 599, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 172, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 173, + 598, 598, 174, 598, 172, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 600, 598, 598, 554, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 711, 554, 712, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 598, 598, 598, 598, 554, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 598, 599, 599, 599, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 172, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 173, 598, 598, 174, 598, 172, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 600, 598, 598, 554, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 713, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 598, 598, 598, 598, 554, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 598, 599, 599, 599, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 172, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 173, 598, 598, 174, 598, 172, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 600, 598, 598, 554, 598, + 714, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 598, 598, 598, 598, 554, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 598, 599, 599, 599, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 172, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 173, 598, 598, 174, 598, 172, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 600, 598, 598, 554, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 707, 554, 554, 554, 554, + 554, 554, 554, 598, 598, 598, 598, 598, + 554, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 598, 599, 599, 599, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 172, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 173, 598, 598, 174, 598, + 172, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 600, 598, 598, + 554, 598, 554, 554, 554, 707, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 598, 598, 598, + 598, 554, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 598, 599, 599, 599, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 172, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 173, 598, 598, 174, + 598, 172, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 600, 598, + 598, 554, 598, 554, 554, 554, 554, 715, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 716, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 598, 598, + 598, 598, 554, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 598, 599, 599, + 599, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 172, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 173, 598, 598, + 174, 598, 172, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 600, + 598, 598, 554, 598, 554, 554, 554, 554, + 554, 554, 717, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 598, + 598, 598, 598, 554, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 598, 599, + 599, 599, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 172, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 173, 598, + 598, 174, 598, 172, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 600, 598, 598, 554, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 718, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 598, 598, 598, 598, 554, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 598, + 599, 599, 599, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 172, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 173, + 598, 598, 174, 598, 172, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 600, 598, 598, 554, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 707, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 598, 598, 598, 598, 554, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 598, 599, 599, 599, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 172, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 173, 598, 598, 174, 598, 172, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 600, 598, 598, 554, 598, 554, + 554, 554, 554, 719, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 598, 598, 598, 598, 554, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 598, 599, 599, 599, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 172, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 173, 598, 598, 174, 598, 172, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 600, 598, 598, 554, 598, + 720, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 598, 598, 598, 598, 554, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 598, 599, 599, 599, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 172, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 173, 598, 598, 174, 598, 172, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 600, 598, 598, 554, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 707, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 598, 598, 598, 598, + 554, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 598, 599, 599, 599, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 172, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 173, 598, 598, 174, 598, + 172, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 600, 598, 598, + 554, 598, 721, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 722, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 598, 598, 598, + 598, 554, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 598, 599, 599, 599, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 172, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 173, 598, 598, 174, + 598, 172, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 600, 598, + 598, 554, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 723, 554, 554, + 554, 554, 554, 554, 554, 598, 598, 598, + 598, 598, 554, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 598, 599, 599, + 599, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 172, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 173, 598, 598, + 174, 598, 172, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 600, + 598, 598, 554, 598, 554, 554, 554, 554, + 707, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 598, + 598, 598, 598, 554, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 598, 599, + 599, 599, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 172, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 173, 598, + 598, 174, 598, 172, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 600, 598, 598, 554, 598, 724, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 598, 598, 598, 598, 554, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 598, + 599, 599, 599, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 172, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 173, + 598, 598, 174, 598, 172, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 600, 598, 598, 554, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 714, 554, 554, 554, 554, 554, 554, 554, + 598, 598, 598, 598, 598, 554, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 598, 599, 599, 599, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 172, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 173, 598, 598, 174, 598, 172, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 600, 598, 598, 554, 598, 554, + 554, 554, 554, 725, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 707, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 598, 598, 598, 598, 554, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 598, 599, 599, 599, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 172, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 173, 598, 598, 174, 598, 172, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 600, 598, 598, 554, 598, + 554, 554, 554, 554, 554, 707, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 598, 598, 598, 598, 554, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 598, 599, 599, 599, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 172, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 173, 598, 598, 174, 598, 172, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 600, 598, 598, 554, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 726, 554, 727, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 598, 598, 598, 598, + 554, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 598, 599, 599, 599, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 172, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 173, 598, 598, 174, 598, + 172, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 600, 598, 598, + 554, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 728, 554, 554, 554, + 554, 554, 554, 554, 598, 598, 598, 598, + 598, 554, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 598, 599, 599, 599, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 172, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 173, 598, 598, 174, + 598, 172, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 600, 598, + 598, 554, 598, 554, 554, 554, 554, 707, + 554, 554, 554, 725, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 598, 598, + 598, 598, 554, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 598, 599, 599, + 599, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 172, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 173, 598, 598, + 174, 598, 172, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 600, + 598, 598, 554, 598, 554, 554, 554, 707, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 729, 554, + 554, 554, 554, 554, 554, 554, 598, 598, + 598, 598, 598, 554, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 598, 599, + 599, 599, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 172, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 173, 598, + 598, 174, 598, 172, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 600, 598, 598, 554, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 730, 554, 554, 554, 554, 554, 598, + 598, 598, 598, 598, 554, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 598, + 599, 599, 599, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 172, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 173, + 598, 598, 174, 598, 172, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 600, 598, 598, 554, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 723, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 598, 598, 598, 598, 554, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 598, 599, 599, 599, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 172, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 173, 598, 598, 174, 598, 172, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 600, 598, 598, 554, 598, 731, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 589, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 598, 598, 598, 598, 554, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 598, 599, 599, 599, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 172, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 173, 598, 598, 174, 598, 172, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 600, 598, 598, 554, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 721, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 598, 598, 598, 598, 554, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 598, 599, 599, 599, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 172, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 173, 598, 598, 174, 598, 172, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 600, 598, 598, 554, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 707, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 598, 598, 598, 598, + 554, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 598, 599, 599, 599, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 172, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 173, 598, 598, 174, 598, + 172, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 600, 598, 598, + 554, 598, 554, 554, 554, 554, 554, 732, + 554, 554, 554, 554, 554, 554, 554, 707, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 598, 598, 598, + 598, 554, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 598, 599, 599, 599, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 172, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 173, 598, 598, 174, + 598, 172, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 600, 598, + 598, 554, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 733, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 598, 598, + 598, 598, 554, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 598, 599, 599, + 599, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 172, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 173, 598, 598, + 174, 598, 172, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 600, + 598, 598, 554, 598, 554, 554, 554, 734, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 598, + 598, 598, 598, 554, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 598, 599, + 599, 599, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 172, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 173, 598, + 598, 174, 598, 172, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 600, 598, 598, 554, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 735, 554, 554, 554, 554, 554, 598, + 598, 598, 598, 598, 554, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 598, + 599, 599, 599, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 172, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 173, + 598, 598, 174, 598, 172, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 600, 598, 598, 554, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 723, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 598, 598, 598, 598, 554, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 598, 599, 599, 599, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 172, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 173, 598, 598, 174, 598, 172, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 600, 598, 598, 554, 598, 554, + 554, 554, 554, 736, 554, 554, 554, 737, + 554, 554, 554, 554, 554, 738, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 598, 598, 598, 598, 554, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 598, 599, 599, 599, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 172, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 173, 598, 598, 174, 598, 172, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 600, 598, 598, 554, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 738, + 554, 554, 598, 598, 598, 598, 598, 554, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 598, 599, 599, 599, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 172, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 173, 598, 598, 174, 598, 172, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 600, 598, 598, 554, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 707, 554, 554, 554, + 554, 554, 554, 598, 598, 598, 598, 598, + 554, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 598, 599, 599, 599, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 172, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 173, 598, 598, 174, 598, + 172, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 600, 598, 598, + 554, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 707, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 598, 598, 598, + 598, 554, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 598, 599, 599, 599, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 172, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 173, 598, 598, 174, + 598, 172, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 600, 598, + 598, 554, 598, 554, 554, 554, 554, 739, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 598, 598, + 598, 598, 554, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 598, 599, 599, + 599, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 172, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 173, 598, 598, + 174, 598, 172, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 600, + 598, 598, 554, 598, 554, 554, 554, 740, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 741, 742, + 554, 554, 554, 554, 554, 554, 598, 598, + 598, 598, 598, 554, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 598, 599, + 599, 599, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 172, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 173, 598, + 598, 174, 598, 172, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 600, 598, 598, 554, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 707, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 598, 598, 598, 598, 554, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 598, + 599, 599, 599, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 172, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 173, + 598, 598, 174, 598, 172, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 600, 598, 598, 554, 598, 554, 554, + 743, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 598, 598, 598, 598, 554, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 598, 599, 599, 599, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 172, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 173, 598, 598, 174, 598, 172, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 600, 598, 598, 554, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 744, 554, 554, 554, 554, + 554, 598, 598, 598, 598, 598, 554, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 598, 599, 599, 599, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 172, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 173, 598, 598, 174, 598, 172, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 600, 598, 598, 554, 598, + 554, 554, 554, 554, 745, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 598, 598, 598, 598, 554, + 746, 746, 746, 746, 746, 746, 746, 746, + 746, 746, 746, 746, 746, 746, 746, 746, + 746, 746, 746, 746, 746, 746, 746, 746, + 746, 746, 746, 746, 746, 746, 746, 746, + 746, 748, 746, 746, 746, 746, 746, 746, + 746, 746, 746, 746, 746, 746, 746, 746, + 747, 747, 747, 747, 747, 747, 747, 747, + 747, 747, 749, 746, 746, 750, 746, 748, + 746, 747, 747, 747, 747, 747, 747, 747, + 747, 747, 747, 747, 747, 747, 747, 747, + 747, 747, 747, 747, 747, 747, 747, 747, + 747, 747, 747, 746, 746, 746, 746, 747, + 746, 747, 747, 747, 747, 747, 747, 747, + 747, 747, 747, 747, 747, 747, 747, 747, + 747, 747, 747, 747, 747, 747, 747, 747, + 747, 747, 747, 746, 746, 746, 746, 746, + 747, 606, 751, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, + 605, 605, 608, 605, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 598, 599, + 599, 599, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 172, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 173, 598, + 598, 174, 598, 172, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 600, 598, 598, 554, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 752, 554, + 554, 753, 554, 554, 554, 554, 554, 598, + 598, 598, 598, 598, 554, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 598, + 599, 599, 599, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 172, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 173, + 598, 598, 174, 598, 172, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 600, 598, 598, 554, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 707, 554, + 598, 598, 598, 598, 598, 554, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 598, 599, 599, 599, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 172, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 173, 598, 598, 174, 598, 172, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 600, 598, 598, 554, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 718, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 598, 598, 598, 598, 554, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 598, 599, 599, 599, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 172, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 173, 598, 598, 174, 598, 172, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 600, 598, 598, 554, 598, + 554, 554, 554, 554, 754, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 755, 554, 554, 554, + 554, 554, 598, 598, 598, 598, 598, 554, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 598, 599, 599, 599, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 172, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 173, 598, 598, 174, 598, 172, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 600, 598, 598, 554, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 725, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 598, 598, 598, 598, + 554, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 598, 599, 599, 599, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 172, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 173, 598, 598, 174, 598, + 172, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 600, 598, 598, + 554, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 756, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 598, 598, 598, + 598, 554, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 598, 599, 599, 599, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 172, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 173, 598, 598, 174, + 598, 172, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 600, 598, + 598, 554, 598, 554, 554, 554, 554, 589, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 598, 598, + 598, 598, 554, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 598, 599, 599, + 599, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 172, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 173, 598, 598, + 174, 598, 172, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 600, + 598, 598, 554, 598, 554, 554, 554, 554, + 554, 554, 554, 757, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 758, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 598, + 598, 598, 598, 554, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 598, 599, + 599, 599, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 172, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 173, 598, + 598, 174, 598, 172, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 600, 598, 598, 554, 598, 554, 554, 554, + 554, 718, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 598, 598, 598, 598, 554, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 598, + 599, 599, 599, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 172, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 173, + 598, 598, 174, 598, 172, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 600, 598, 598, 554, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 723, 554, 554, 554, 554, 554, + 598, 598, 598, 598, 598, 554, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 598, 599, 599, 599, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 172, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 173, 598, 598, 174, 598, 172, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 600, 598, 598, 554, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 759, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 598, 598, 598, 598, 554, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 598, 599, 599, 599, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 172, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 173, 598, 598, 174, 598, 172, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 600, 598, 598, 554, 598, + 554, 554, 554, 760, 554, 554, 554, 554, + 554, 554, 554, 761, 554, 554, 554, 554, + 554, 554, 554, 762, 554, 554, 554, 554, + 554, 554, 598, 598, 598, 598, 598, 554, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 598, 599, 599, 599, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 172, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 173, 598, 598, 174, 598, 172, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 600, 598, 598, 554, + 598, 554, 554, 554, 554, 725, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 598, 598, 598, 598, + 554, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 598, 599, 599, 599, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 172, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 173, 598, 598, 174, 598, + 172, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 600, 598, 598, + 554, 598, 554, 554, 554, 554, 763, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 598, 598, 598, + 598, 554, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 598, 599, 599, 599, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 172, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 173, 598, 598, 174, + 598, 172, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 600, 598, + 598, 554, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 764, 554, 554, + 554, 554, 554, 554, 554, 598, 598, 598, + 598, 598, 554, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 598, 599, 599, + 599, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 172, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 173, 598, 598, + 174, 598, 172, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 600, + 598, 598, 554, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 732, 554, + 554, 554, 554, 554, 554, 554, 598, 598, + 598, 598, 598, 554, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 598, 599, + 599, 599, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 172, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 173, 598, + 598, 174, 598, 172, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 600, 598, 598, 554, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 765, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 598, 598, 598, 598, 554, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 598, + 599, 599, 599, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 172, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 173, + 598, 598, 174, 598, 172, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 600, 598, 598, 554, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 732, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 598, 598, 598, 598, 598, 554, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 598, 599, 599, 599, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 599, 172, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 173, 598, 598, 174, 598, 172, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 600, 598, 598, 554, 598, 554, + 554, 554, 554, 554, 554, 554, 766, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 598, 598, 598, 598, 598, 554, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 598, 599, 599, 599, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 599, + 172, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 173, 598, 598, 174, 598, 172, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 600, 598, 598, 554, 598, + 554, 554, 554, 554, 718, 554, 554, 554, + 767, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 598, 598, 598, 598, 598, 554, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 598, 599, 599, 599, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 599, 172, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 173, 598, 598, 174, 598, 172, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 600, 598, 598, 554, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 768, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 598, 598, 598, 598, 598, + 554, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 598, 599, 599, 599, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 599, 172, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 173, 598, 598, 174, 598, + 172, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 600, 598, 598, + 554, 598, 554, 554, 554, 554, 732, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 598, 598, 598, 598, + 598, 554, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 598, 599, 599, 599, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 599, 172, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 173, 598, 598, 174, + 598, 172, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 600, 598, + 598, 554, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 769, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 598, 598, 598, + 598, 598, 554, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 598, 599, 599, + 599, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 599, 172, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 173, 598, 598, + 174, 598, 172, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 600, + 598, 598, 554, 598, 554, 554, 554, 554, + 770, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 598, 598, + 598, 598, 598, 554, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 599, 598, 599, + 599, 599, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 599, 172, 598, 598, + 598, 598, 598, 598, 598, 598, 598, 598, + 598, 598, 598, 598, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 173, 598, + 598, 174, 598, 172, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 600, 598, 598, 554, 598, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, + 712, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 598, + 598, 598, 598, 598, 554, 771, 125, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 772, 620, 774, + 773, 773, 773, 774, 773, 773, 773, 773, + 775, 776, 775, 775, 775, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, + 773, 774, 773, 773, 773, 773, 773, 775, + 773, 773, 777, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, + 773, 773, 773, 778, 773, 775, 779, 775, + 775, 775, 779, 779, 779, 779, 779, 779, + 779, 779, 779, 779, 779, 779, 779, 779, + 779, 779, 779, 779, 775, 779, 780, 781, + 782, 783, 784, 786, 785, 787, 789, 790, + 790, 790, 789, 790, 790, 790, 790, 791, + 792, 791, 791, 791, 790, 790, 790, 790, + 790, 790, 790, 790, 790, 790, 790, 790, + 789, 790, 790, 790, 790, 790, 791, 790, + 793, 794, 790, 790, 790, 793, 790, 790, + 790, 790, 790, 790, 790, 790, 790, 790, + 790, 790, 790, 790, 790, 790, 790, 790, + 790, 790, 790, 790, 790, 790, 790, 788, + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 790, 795, 790, 790, 788, 790, 788, + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 790, 790, 790, 790, 790, 788, 796, + 796, 796, 796, 796, 796, 796, 796, 796, + 796, 796, 796, 796, 796, 796, 796, 796, + 796, 796, 796, 796, 796, 796, 796, 796, + 796, 796, 796, 796, 796, 796, 796, 796, + 180, 796, 796, 796, 796, 796, 796, 796, + 796, 796, 796, 796, 796, 796, 796, 179, + 179, 179, 179, 179, 179, 179, 179, 179, + 179, 181, 796, 796, 796, 796, 180, 796, + 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 796, 796, 796, 796, 179, 796, + 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 796, 796, 796, 796, 796, 179, + 791, 797, 791, 791, 791, 797, 797, 797, + 797, 797, 797, 797, 797, 797, 797, 797, + 797, 797, 797, 797, 797, 797, 797, 791, + 797, 798, 799, 800, 801, 802, 803, 796, + 804, 806, 807, 807, 807, 806, 807, 807, + 807, 807, 808, 809, 808, 808, 808, 807, + 807, 807, 807, 807, 807, 807, 807, 807, + 807, 807, 807, 806, 807, 807, 807, 807, + 807, 808, 810, 811, 812, 813, 814, 815, + 811, 816, 817, 818, 814, 819, 820, 821, + 814, 822, 823, 823, 823, 823, 823, 823, + 823, 823, 823, 824, 825, 826, 827, 828, + 829, 830, 831, 832, 831, 831, 833, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 834, 835, 836, 814, + 837, 811, 838, 839, 840, 841, 842, 843, + 805, 805, 844, 805, 805, 805, 845, 846, + 847, 805, 805, 848, 849, 850, 851, 805, + 852, 805, 853, 805, 854, 855, 856, 857, + 807, 805, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 858, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 189, 189, 189, 189, + 189, 858, 189, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 189, 189, 189, + 189, 805, 189, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 189, 189, 189, + 189, 189, 805, 860, 859, 861, 808, 862, + 808, 808, 808, 862, 862, 862, 862, 862, + 862, 862, 862, 862, 862, 862, 862, 862, + 862, 862, 862, 862, 862, 808, 862, 863, + 865, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 865, 864, 866, 867, 868, 869, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 184, 184, 870, 184, 870, 184, 184, 870, + 870, 184, 184, 184, 871, 184, 184, 872, + 872, 872, 872, 872, 872, 872, 872, 872, + 872, 184, 184, 184, 184, 184, 184, 184, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 870, 184, 870, 870, 201, 184, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 870, 870, 870, 184, 870, 201, + 873, 873, 873, 873, 873, 873, 873, 873, + 873, 873, 873, 873, 873, 873, 873, 873, + 873, 873, 873, 873, 873, 873, 873, 873, + 873, 873, 873, 873, 873, 873, 873, 873, + 873, 873, 873, 873, 873, 873, 873, 873, + 873, 873, 873, 873, 873, 873, 873, 873, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 873, 873, 873, 873, 873, 873, + 873, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 873, 873, 873, 873, 201, + 873, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 873, 873, 873, 873, 873, + 201, 872, 872, 872, 872, 872, 872, 872, + 872, 872, 872, 873, 874, 189, 814, 875, + 875, 875, 875, 875, 875, 875, 876, 875, + 875, 875, 875, 875, 875, 875, 875, 875, + 875, 875, 875, 875, 875, 874, 875, 877, + 878, 814, 879, 879, 879, 879, 879, 879, + 879, 879, 879, 879, 879, 879, 879, 879, + 879, 879, 879, 879, 874, 879, 874, 880, + 875, 882, 881, 188, 188, 188, 188, 188, + 188, 188, 188, 188, 188, 881, 884, 883, + 885, 883, 188, 188, 188, 188, 188, 188, + 188, 188, 188, 188, 886, 886, 886, 886, + 886, 886, 886, 886, 886, 886, 886, 887, + 886, 886, 886, 886, 886, 886, 886, 886, + 886, 886, 886, 886, 886, 886, 886, 886, + 886, 886, 886, 886, 886, 886, 886, 886, + 886, 888, 886, 886, 886, 886, 886, 887, + 886, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 187, 886, 886, 886, 886, 886, + 886, 886, 886, 886, 886, 886, 886, 886, + 886, 886, 886, 886, 886, 886, 886, 886, + 886, 886, 886, 886, 886, 886, 886, 886, + 886, 886, 886, 886, 886, 886, 886, 886, + 186, 886, 890, 889, 891, 891, 891, 891, + 891, 891, 891, 891, 891, 891, 889, 889, + 889, 889, 889, 889, 889, 889, 892, 889, + 893, 894, 889, 889, 889, 889, 889, 889, + 889, 889, 889, 895, 889, 889, 889, 889, + 889, 889, 889, 889, 896, 889, 889, 889, + 889, 889, 889, 897, 889, 889, 892, 889, + 893, 894, 889, 889, 889, 898, 889, 889, + 889, 889, 889, 895, 889, 889, 899, 889, + 889, 889, 889, 889, 896, 889, 190, 190, + 190, 190, 190, 190, 190, 190, 190, 190, + 900, 900, 900, 900, 900, 900, 900, 900, + 900, 900, 900, 901, 900, 900, 900, 900, + 900, 900, 900, 900, 900, 900, 900, 900, + 900, 900, 900, 900, 900, 900, 900, 900, + 900, 900, 900, 900, 900, 902, 900, 900, + 900, 900, 900, 901, 900, 900, 900, 903, + 900, 900, 900, 900, 900, 900, 900, 900, + 904, 900, 905, 189, 905, 189, 189, 191, + 191, 191, 191, 191, 191, 191, 191, 191, + 191, 189, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 191, 906, 906, 906, 906, + 906, 906, 906, 906, 906, 906, 906, 906, + 906, 906, 906, 906, 906, 906, 906, 906, + 906, 906, 906, 906, 906, 906, 906, 906, + 906, 906, 906, 906, 906, 906, 906, 906, + 906, 905, 906, 906, 906, 906, 906, 906, + 906, 906, 906, 907, 906, 909, 908, 910, + 912, 911, 911, 911, 913, 911, 914, 915, + 891, 891, 891, 891, 891, 891, 891, 891, + 891, 891, 889, 889, 889, 889, 889, 889, + 889, 889, 889, 889, 889, 889, 889, 889, + 889, 889, 889, 889, 889, 889, 889, 889, + 889, 889, 889, 889, 889, 889, 889, 889, + 889, 889, 889, 889, 889, 889, 889, 897, + 889, 889, 889, 889, 889, 889, 889, 889, + 889, 898, 889, 889, 889, 889, 889, 889, + 889, 889, 899, 889, 916, 916, 916, 916, + 916, 916, 916, 916, 916, 916, 889, 889, + 889, 889, 889, 889, 889, 889, 889, 889, + 889, 889, 889, 889, 889, 889, 889, 889, + 889, 889, 889, 889, 889, 889, 889, 889, + 889, 889, 889, 889, 889, 889, 889, 889, + 889, 889, 889, 917, 889, 889, 889, 889, + 889, 889, 889, 889, 889, 898, 889, 889, + 889, 889, 889, 889, 889, 889, 899, 889, + 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 920, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 921, 918, 918, 918, 918, 918, 918, + 918, 918, 922, 918, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 923, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 921, 918, 918, + 918, 918, 918, 918, 918, 918, 922, 918, + 921, 918, 918, 918, 918, 918, 918, 918, + 918, 922, 918, 925, 924, 926, 928, 927, + 927, 927, 929, 927, 931, 930, 932, 933, + 935, 935, 934, 934, 934, 934, 934, 934, + 934, 934, 934, 934, 934, 934, 934, 934, + 934, 934, 934, 934, 934, 934, 934, 934, + 934, 934, 934, 934, 934, 934, 934, 934, + 934, 934, 934, 934, 934, 934, 934, 934, + 934, 934, 934, 934, 934, 934, 934, 936, + 934, 934, 934, 934, 934, 934, 934, 934, + 934, 937, 934, 934, 934, 934, 934, 934, + 934, 934, 938, 934, 939, 939, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 940, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 921, 918, 918, + 918, 918, 918, 918, 918, 918, 922, 918, + 939, 939, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 923, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 921, 918, 918, 918, 918, 918, 918, + 918, 918, 922, 918, 942, 942, 942, 942, + 942, 942, 942, 942, 942, 942, 941, 941, + 941, 941, 941, 941, 941, 941, 941, 941, + 941, 941, 941, 941, 941, 941, 941, 941, + 941, 941, 941, 941, 941, 941, 941, 941, + 941, 941, 941, 941, 941, 941, 941, 941, + 941, 941, 941, 943, 941, 941, 941, 941, + 941, 941, 941, 941, 941, 944, 941, 941, + 941, 941, 941, 941, 941, 941, 945, 941, + 947, 947, 947, 947, 947, 947, 947, 947, + 947, 947, 946, 946, 946, 946, 946, 946, + 946, 946, 946, 946, 946, 946, 946, 946, + 946, 946, 946, 946, 946, 946, 946, 946, + 946, 946, 946, 946, 946, 946, 946, 946, + 946, 946, 946, 946, 946, 946, 946, 948, + 946, 946, 946, 946, 946, 946, 946, 946, + 946, 949, 946, 946, 946, 946, 946, 946, + 946, 946, 950, 946, 952, 952, 952, 952, + 952, 952, 952, 952, 952, 952, 951, 951, + 951, 951, 951, 951, 951, 952, 952, 952, + 952, 952, 952, 951, 951, 951, 951, 951, + 951, 951, 951, 951, 951, 951, 951, 951, + 951, 951, 951, 951, 951, 951, 951, 951, + 951, 951, 951, 953, 951, 952, 952, 952, + 952, 952, 952, 951, 951, 954, 951, 951, + 951, 951, 951, 951, 951, 951, 955, 951, + 956, 956, 956, 956, 956, 956, 956, 956, + 956, 956, 918, 918, 918, 918, 918, 918, + 918, 956, 956, 956, 956, 956, 956, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 957, + 918, 956, 956, 956, 956, 956, 956, 918, + 918, 921, 918, 918, 918, 918, 918, 918, + 918, 918, 922, 918, 956, 956, 956, 956, + 956, 956, 956, 956, 956, 956, 918, 918, + 918, 918, 918, 918, 918, 956, 956, 956, + 956, 956, 956, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 923, 918, 956, 956, 956, + 956, 956, 956, 918, 918, 921, 918, 918, + 918, 918, 918, 918, 918, 918, 922, 918, + 959, 958, 960, 960, 960, 960, 960, 960, + 960, 960, 960, 960, 958, 958, 958, 958, + 958, 958, 958, 958, 958, 958, 958, 961, + 958, 958, 958, 958, 958, 958, 958, 958, + 958, 958, 958, 958, 958, 958, 958, 958, + 958, 958, 958, 958, 958, 958, 958, 958, + 958, 962, 958, 958, 958, 958, 958, 961, + 958, 958, 958, 963, 958, 958, 958, 958, + 958, 958, 958, 958, 964, 958, 965, 965, + 965, 965, 965, 965, 965, 965, 965, 965, + 958, 958, 958, 958, 958, 958, 958, 958, + 958, 958, 958, 958, 958, 958, 958, 958, + 958, 958, 958, 958, 958, 958, 958, 958, + 958, 958, 958, 958, 958, 958, 958, 958, + 958, 958, 958, 958, 958, 966, 958, 958, + 958, 958, 958, 958, 958, 958, 958, 963, + 958, 958, 958, 958, 958, 958, 958, 958, + 964, 958, 967, 918, 968, 968, 968, 968, + 968, 968, 968, 968, 968, 968, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 969, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 970, 918, 918, 918, 918, + 918, 969, 918, 918, 918, 921, 918, 918, + 918, 918, 918, 918, 918, 918, 922, 918, + 968, 968, 968, 968, 968, 968, 968, 968, + 968, 968, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 923, + 918, 918, 918, 918, 918, 918, 918, 918, + 918, 921, 918, 918, 918, 918, 918, 918, + 918, 918, 922, 918, 876, 883, 814, 971, + 875, 865, 875, 972, 973, 883, 883, 883, + 883, 883, 883, 883, 883, 883, 883, 883, + 883, 883, 883, 883, 883, 883, 883, 883, + 883, 883, 883, 883, 883, 883, 883, 883, + 883, 883, 883, 883, 883, 883, 883, 883, + 883, 883, 883, 883, 883, 883, 883, 883, + 883, 883, 883, 883, 883, 883, 883, 883, + 883, 883, 883, 883, 883, 883, 883, 883, + 883, 883, 883, 883, 865, 883, 865, 875, + 865, 814, 875, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 870, 870, 870, 870, 870, + 870, 870, 870, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 870, 870, 870, + 870, 870, 870, 974, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 870, 870, + 870, 870, 201, 870, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 870, 870, + 870, 870, 870, 201, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 189, 858, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, 189, 189, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 975, 189, + 189, 189, 189, 858, 189, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 189, + 189, 189, 189, 831, 189, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 189, + 189, 189, 189, 189, 831, 976, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 858, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 975, 977, 977, 977, 977, 858, 977, 831, + 831, 831, 831, 978, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 977, 977, 977, 977, 831, 977, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 977, 977, 977, 977, 977, 831, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 858, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 975, 977, 977, 977, 977, 858, 977, + 831, 831, 831, 831, 831, 831, 979, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 977, 977, 977, 977, 831, 977, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 977, 977, 977, 977, 977, 831, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 858, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 975, 977, 977, 977, 977, 858, + 977, 831, 831, 831, 831, 831, 831, 831, + 831, 980, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 977, 977, 977, 977, 831, + 977, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 977, 977, 977, 977, 977, + 831, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 858, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 975, 977, 977, 977, 977, + 858, 977, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 981, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 977, 977, 977, 977, + 831, 977, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 977, 977, 977, 977, + 977, 831, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 858, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 975, 977, 977, 977, + 977, 858, 977, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 982, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 977, 977, 977, + 977, 831, 977, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 977, 977, 977, + 977, 977, 831, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 858, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 975, 977, 977, + 977, 977, 858, 977, 831, 831, 831, 981, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 977, 977, + 977, 977, 831, 977, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 831, 831, + 831, 831, 831, 831, 831, 831, 977, 977, + 977, 977, 977, 831, 983, 985, 984, 986, + 987, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 858, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 989, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 990, + 991, 805, 805, 805, 805, 805, 992, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 805, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 993, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 994, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 805, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 858, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 858, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 995, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 805, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 805, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 858, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 858, 988, 805, + 805, 805, 996, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 805, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 805, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 858, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 858, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 997, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 805, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 805, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 858, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 858, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 998, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 805, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 805, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 858, 988, 805, 805, 805, 805, 805, 805, + 999, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 805, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 1000, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 1001, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 1002, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 805, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 858, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 858, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 1003, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 805, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 805, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 858, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 858, 988, 805, + 805, 805, 805, 1004, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 805, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 805, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 858, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 858, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 1005, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 805, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 858, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 858, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 1006, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 805, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 858, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 1007, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 805, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 1003, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 805, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 1008, + 805, 1009, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 1010, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 805, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 858, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 858, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 805, 988, 1011, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 805, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 858, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 858, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 805, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 1012, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 805, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 858, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 858, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 805, 988, + 805, 805, 805, 1013, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 805, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 858, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 858, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 805, + 988, 805, 805, 805, 805, 1014, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 1015, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 805, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 858, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 805, 988, 805, 805, 805, 805, 805, 805, + 1016, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 805, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 1017, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 1013, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 805, 1018, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 805, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 858, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 858, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 805, 988, 1019, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 805, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 858, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 858, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 805, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 1020, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 805, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 858, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 858, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 805, 988, + 1021, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 1022, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 805, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 858, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 858, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 805, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 1023, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 805, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 858, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 805, 988, 805, 805, 805, 805, 1013, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 805, 988, 1024, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 1025, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 1026, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 805, 1027, 1027, 1027, + 1027, 1027, 1027, 1027, 1027, 1027, 203, 204, + 203, 203, 203, 1027, 1027, 1027, 1027, 1027, + 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, + 1027, 1027, 1027, 1027, 1027, 203, 858, 1027, + 205, 1027, 1027, 1027, 1027, 1027, 1027, 1027, + 1027, 1027, 1027, 1027, 1027, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 1027, + 1027, 206, 1027, 1027, 858, 1027, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 1027, 207, 1027, 1027, 805, 1027, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 1027, 1027, 1027, 1027, 1027, 805, 220, 221, + 220, 220, 220, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 220, 219, 219, + 222, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 225, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, + 219, 224, 219, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 805, 805, + 1029, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 1030, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 805, 805, 1031, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 805, 1032, 1032, 1032, + 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, + 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, + 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, + 1032, 1032, 1032, 1032, 1032, 1032, 858, 1032, + 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, + 1032, 1032, 1032, 1032, 1032, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 1032, + 1032, 1032, 1032, 1032, 858, 1032, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 1032, 1032, 1032, 1032, 805, 1032, 805, 805, + 805, 805, 805, 805, 805, 805, 1033, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 1032, 1032, 1032, 1032, 1032, 805, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 858, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 858, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 805, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 1034, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 805, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 858, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 858, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 805, 988, + 805, 805, 805, 805, 1035, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 805, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 858, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 858, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 805, + 988, 805, 805, 805, 1036, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 805, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 1037, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 805, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 805, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 1038, 805, + 1039, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 1040, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 805, 1013, 805, 805, 805, 1041, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 805, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 858, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 858, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 805, 988, 805, 805, + 805, 805, 805, 1013, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 805, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 858, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 858, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 805, 988, 805, + 805, 805, 1006, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 1042, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 805, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 858, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 858, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 805, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 1043, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 805, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 858, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 858, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 805, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 1023, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 805, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 858, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 805, 988, 1044, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 847, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 805, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 1045, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 1046, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 805, 1006, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 805, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 858, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 858, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 805, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 1013, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 805, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 858, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 858, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 805, 988, 805, + 805, 805, 805, 805, 1047, 805, 805, 805, + 805, 805, 805, 805, 1013, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 805, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 858, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 858, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 805, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 1048, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 805, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 858, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 858, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 805, + 988, 805, 805, 805, 1049, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 805, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 858, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 805, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 1050, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 805, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 1023, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 805, 805, + 1051, 805, 805, 805, 1052, 805, 805, 805, + 805, 805, 1053, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 1054, 805, 805, 988, + 988, 988, 988, 988, 805, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 858, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 858, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 805, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 1020, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 805, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 858, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 858, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 805, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 1006, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 805, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 858, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 858, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 805, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 1055, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 805, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 858, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 858, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 805, + 988, 805, 805, 805, 805, 1056, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 805, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 858, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 805, 988, 805, 805, 805, 1057, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 1058, 1059, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 805, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 1006, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 1060, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 1061, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 805, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 858, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 858, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 805, 988, 805, 805, + 805, 805, 1047, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 805, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 858, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 858, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 805, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 1062, 805, 805, 1063, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 805, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 858, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 858, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 805, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 1006, 805, 988, 988, 988, 988, 988, 805, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 858, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 858, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 805, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 1064, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 805, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 858, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 805, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 1020, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 805, 988, 805, 805, 805, 805, 1065, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 1066, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 1067, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 805, 805, 1006, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 805, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 858, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 858, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 805, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 1068, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 805, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 858, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 858, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 805, 988, 805, + 805, 805, 805, 1069, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 805, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 858, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 858, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 805, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 1055, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 805, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 858, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 858, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 805, + 988, 805, 805, 805, 805, 805, 805, 805, + 1070, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 1071, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 805, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 858, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 805, 988, 805, 805, 805, 805, 1017, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 805, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 1046, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 1072, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 1073, 805, 805, 805, 805, 805, 805, 805, + 1074, 805, 805, 805, 805, 805, 805, 805, + 1075, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 805, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 858, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 858, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 805, 988, 805, 805, + 805, 805, 1076, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 805, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 858, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 858, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 805, 988, 805, + 805, 805, 805, 805, 1012, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 805, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 858, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 858, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 805, 988, + 805, 805, 805, 805, 1077, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 805, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 858, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 858, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 805, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 1078, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 805, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 858, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 805, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 1047, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 805, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 1079, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 1047, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 858, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 858, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 805, 988, 805, 805, 805, + 805, 805, 805, 805, 1080, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 805, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 858, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 988, + 988, 988, 988, 988, 858, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 805, 988, 805, 805, + 805, 805, 1017, 805, 805, 805, 1081, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 805, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 858, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 988, 988, 988, 988, 988, 858, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 805, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 1082, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 805, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 858, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 988, 988, 988, 988, 988, 858, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 805, 988, + 805, 805, 805, 805, 1047, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 805, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 858, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 988, 988, 988, 988, 988, 858, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 805, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 1083, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 805, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 858, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 988, 988, 988, 988, 988, + 858, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 805, 988, 805, 805, 805, 805, 1084, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 805, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 858, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 988, 988, 988, 988, + 988, 858, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 805, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 1085, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 805, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 988, 858, 988, 988, 988, + 988, 988, 988, 988, 988, 988, 988, 988, + 988, 988, 988, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 988, 988, 988, + 988, 988, 858, 988, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 805, 988, 805, 805, 805, 1055, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 805, 805, + 805, 805, 805, 805, 805, 805, 988, 988, + 988, 988, 988, 805, 1086, 874, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, + 864, 864, 864, 864, 814, 864, 1087, 1089, + 1088, 1089, 1089, 1089, 1088, 1088, 1088, 1088, + 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, + 1088, 1088, 1088, 1088, 1088, 1088, 1089, 1088, + 1088, 1090, 1088, 1088, 1091, 1088, 1088, 1088, + 1088, 1088, 1088, 1088, 233, 1088, 1088, 1088, + 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, + 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, + 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, + 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, + 1088, 1088, 1088, 1088, 1088, 1088, 1088, 1088, + 1088, 1088, 1092, 1088, 229, 230, 229, 229, + 229, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 229, 1093, 1093, 231, 1093, + 1093, 232, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 233, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + 1093, 1093, 1093, 1093, 1093, 1093, 1093, 234, + 1093, 236, 1094, 236, 236, 236, 1094, 1094, + 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, + 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, + 236, 1094, 1094, 231, 1094, 1094, 1094, 1094, + 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, + 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, + 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, + 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, + 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, + 1094, 1094, 1094, 1094, 1094, 1094, 1094, 1094, + 1094, 1094, 1094, 1094, 234, 1094, 1096, 1095, + 1098, 1097, 239, 238, 244, 1093, 242, 1093, + 1100, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1101, 1099, 1100, 1099, 1100, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1103, 1099, 1100, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1104, 1099, 1100, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1099, 1099, 1099, 1099, + 1099, 1099, 1099, 1099, 1105, 1099, 1107, 1105, + 1109, 1108, 1108, 1108, 1109, 1108, 1108, 1108, + 1108, 1110, 1111, 1110, 1110, 1110, 1108, 1108, + 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, + 1108, 1108, 1109, 1108, 1108, 1108, 1108, 1108, + 1110, 1108, 1108, 1112, 1108, 1108, 1108, 1108, + 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, + 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, + 1108, 1108, 1108, 1108, 1108, 1113, 1108, 1108, + 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, + 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, + 1108, 1108, 1108, 1108, 1108, 1108, 1108, 1108, + 1108, 1108, 1108, 1108, 1114, 1108, 1108, 1115, + 1108, 1110, 1116, 1110, 1110, 1110, 1116, 1116, + 1116, 1116, 1116, 1116, 1116, 1116, 1116, 1116, + 1116, 1116, 1116, 1116, 1116, 1116, 1116, 1116, + 1110, 1116, 1117, 1118, 1119, 1120, 1121, 1123, + 1122, 1125, 1126, 1125, 1125, 1125, 1124, 1124, + 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, + 1124, 1124, 1124, 1124, 1124, 1124, 1124, 1124, + 1125, 1124, 1111, 1122, 1127, 1122, 0 +] + +class << self + attr_accessor :_lex_trans_targs + private :_lex_trans_targs, :_lex_trans_targs= +end +self._lex_trans_targs = [ + 130, 129, 0, 2, 131, 132, 4, 133, + 134, 134, 134, 134, 247, 7, 8, 9, + 247, 247, 276, 11, 12, 276, 276, 280, + 280, 16, 11, 17, 278, 279, 281, 282, + 280, 276, 283, 284, 286, 13, 14, 287, + 288, 15, 280, 18, 19, 24, 31, 290, + 291, 17, 278, 279, 281, 282, 280, 276, + 283, 284, 286, 13, 14, 287, 288, 15, + 18, 19, 24, 31, 290, 291, 289, 20, + 21, 22, 23, 25, 26, 29, 27, 28, + 30, 32, 33, 276, 35, 36, 37, 39, + 42, 40, 41, 43, 45, 307, 307, 307, + 308, 47, 310, 48, 311, 49, 308, 47, + 310, 48, 311, 345, 50, 345, 51, 52, + 50, 345, 51, 345, 345, 345, 55, 56, + 57, 58, 356, 345, 345, 345, 61, 62, + 63, 345, 66, 61, 62, 63, 345, 66, + 64, 64, 62, 63, 366, 65, 64, 64, + 62, 63, 366, 65, 62, 345, 383, 345, + 68, 384, 390, 72, 399, 400, 77, 78, + 72, 73, 398, 73, 398, 345, 74, 75, + 76, 401, 79, 80, 347, 53, 349, 82, + 83, 406, 508, 85, 86, 87, 508, 516, + 516, 516, 90, 538, 537, 516, 540, 542, + 516, 95, 96, 97, 546, 516, 99, 100, + 557, 526, 579, 103, 104, 105, 109, 110, + 103, 104, 105, 109, 110, 106, 106, 104, + 105, 107, 108, 106, 106, 104, 105, 107, + 108, 627, 104, 516, 696, 111, 698, 113, + 117, 699, 115, 696, 112, 696, 114, 698, + 114, 698, 116, 698, 696, 710, 119, 120, + 121, 716, 123, 124, 125, 126, 127, 710, + 710, 128, 1, 3, 129, 129, 129, 135, + 134, 134, 136, 137, 138, 139, 141, 144, + 145, 146, 147, 134, 148, 149, 151, 153, + 154, 155, 159, 161, 162, 163, 179, 184, + 191, 196, 203, 210, 213, 214, 218, 212, + 222, 230, 234, 236, 241, 243, 246, 134, + 134, 134, 134, 134, 134, 140, 134, 140, + 134, 142, 5, 143, 134, 6, 134, 134, + 150, 152, 134, 156, 157, 158, 154, 160, + 134, 164, 165, 174, 177, 166, 167, 168, + 169, 170, 171, 172, 173, 135, 175, 176, + 178, 180, 183, 181, 182, 185, 188, 186, + 187, 189, 190, 192, 194, 193, 195, 197, + 198, 134, 199, 200, 201, 202, 134, 204, + 207, 205, 206, 208, 209, 211, 215, 216, + 217, 219, 221, 220, 223, 224, 225, 227, + 226, 228, 229, 231, 232, 233, 235, 237, + 238, 239, 240, 242, 244, 245, 248, 247, + 247, 249, 250, 252, 253, 247, 247, 247, + 251, 247, 251, 10, 254, 247, 256, 255, + 255, 259, 260, 261, 262, 255, 264, 265, + 266, 267, 269, 271, 272, 273, 274, 275, + 255, 257, 255, 258, 255, 255, 255, 255, + 255, 263, 255, 263, 268, 255, 270, 255, + 276, 276, 277, 292, 293, 279, 295, 296, + 283, 297, 298, 299, 300, 301, 303, 304, + 305, 306, 276, 276, 276, 276, 276, 276, + 280, 285, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 294, 276, 294, 276, 276, + 276, 276, 302, 276, 34, 38, 44, 307, + 309, 312, 46, 307, 307, 308, 313, 313, + 314, 315, 317, 319, 320, 313, 313, 316, + 313, 316, 313, 318, 313, 313, 313, 322, + 321, 321, 323, 324, 325, 327, 329, 330, + 335, 342, 321, 321, 321, 321, 326, 321, + 326, 321, 328, 321, 321, 322, 331, 332, + 333, 334, 336, 337, 340, 338, 339, 341, + 343, 344, 346, 345, 354, 355, 357, 358, + 360, 361, 362, 363, 365, 367, 368, 371, + 372, 397, 403, 404, 405, 406, 407, 408, + 409, 410, 364, 412, 429, 434, 441, 446, + 448, 454, 457, 458, 462, 456, 466, 477, + 481, 484, 492, 496, 499, 500, 345, 50, + 51, 345, 53, 348, 345, 345, 350, 352, + 353, 345, 351, 345, 345, 345, 345, 345, + 54, 345, 345, 345, 345, 345, 359, 345, + 359, 345, 345, 59, 345, 60, 345, 345, + 364, 345, 369, 345, 370, 345, 345, 345, + 373, 382, 345, 67, 385, 386, 387, 345, + 388, 69, 391, 392, 70, 395, 396, 345, + 374, 376, 345, 375, 345, 345, 377, 380, + 381, 345, 378, 379, 345, 345, 345, 345, + 345, 345, 389, 345, 383, 393, 394, 345, + 393, 345, 383, 393, 71, 402, 345, 345, + 345, 345, 345, 81, 84, 345, 411, 413, + 414, 424, 427, 415, 416, 417, 418, 419, + 420, 421, 422, 423, 425, 426, 428, 430, + 433, 431, 432, 435, 438, 436, 437, 439, + 440, 442, 444, 443, 445, 447, 449, 451, + 450, 452, 453, 455, 423, 459, 460, 461, + 463, 465, 464, 467, 468, 469, 474, 470, + 471, 472, 345, 346, 347, 53, 473, 352, + 475, 476, 478, 479, 480, 482, 483, 485, + 486, 487, 490, 488, 489, 491, 493, 494, + 495, 497, 498, 345, 364, 501, 501, 502, + 503, 504, 506, 501, 501, 501, 505, 501, + 505, 501, 507, 501, 509, 508, 508, 510, + 511, 508, 512, 514, 508, 508, 508, 508, + 513, 508, 513, 515, 508, 517, 516, 516, + 520, 521, 522, 516, 523, 525, 528, 529, + 530, 531, 532, 516, 533, 534, 539, 567, + 571, 516, 572, 574, 576, 516, 577, 578, + 580, 584, 586, 587, 589, 590, 608, 613, + 620, 628, 635, 642, 647, 648, 652, 646, + 657, 667, 673, 676, 685, 689, 693, 694, + 695, 528, 518, 516, 519, 516, 516, 516, + 516, 516, 516, 524, 516, 524, 516, 88, + 527, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 535, 516, 536, 516, 516, 89, + 91, 516, 92, 548, 559, 562, 541, 563, + 564, 549, 553, 555, 516, 541, 92, 543, + 545, 93, 516, 543, 516, 544, 516, 516, + 94, 547, 516, 516, 550, 552, 516, 550, + 551, 553, 555, 552, 516, 554, 516, 516, + 556, 558, 516, 98, 516, 516, 516, 560, + 552, 553, 555, 560, 561, 516, 550, 552, + 553, 555, 516, 550, 552, 553, 555, 516, + 565, 552, 553, 555, 565, 566, 516, 92, + 567, 541, 568, 553, 555, 569, 552, 92, + 569, 541, 570, 573, 575, 516, 101, 102, + 516, 516, 581, 582, 583, 578, 585, 516, + 516, 588, 516, 516, 516, 591, 592, 601, + 606, 593, 594, 595, 596, 597, 598, 599, + 600, 517, 602, 603, 604, 605, 517, 607, + 609, 612, 610, 611, 517, 517, 614, 617, + 615, 616, 618, 619, 517, 621, 623, 622, + 624, 625, 626, 516, 516, 629, 517, 630, + 516, 631, 632, 633, 634, 518, 636, 639, + 637, 638, 640, 641, 643, 644, 645, 517, + 649, 650, 651, 653, 655, 656, 654, 517, + 658, 659, 660, 663, 661, 662, 664, 665, + 666, 668, 670, 669, 671, 672, 674, 675, + 677, 678, 680, 683, 679, 681, 682, 684, + 686, 687, 688, 690, 691, 692, 516, 516, + 696, 697, 701, 702, 703, 696, 696, 696, + 700, 696, 696, 705, 704, 706, 704, 707, + 708, 709, 704, 704, 710, 710, 711, 712, + 713, 715, 717, 718, 710, 710, 710, 714, + 710, 714, 710, 118, 710, 710, 710, 122 +] + +class << self + attr_accessor :_lex_trans_actions + private :_lex_trans_actions, :_lex_trans_actions= +end +self._lex_trans_actions = [ + 0, 1, 0, 0, 0, 0, 0, 0, + 2, 3, 4, 5, 6, 0, 0, 0, + 7, 8, 9, 0, 0, 10, 11, 12, + 13, 14, 15, 15, 16, 17, 15, 18, + 17, 19, 17, 15, 15, 16, 15, 20, + 15, 15, 21, 15, 15, 15, 15, 15, + 15, 0, 22, 23, 0, 24, 23, 25, + 23, 0, 0, 22, 0, 26, 0, 0, + 0, 0, 0, 0, 0, 0, 13, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 27, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 28, 29, 30, + 31, 0, 0, 0, 31, 14, 32, 15, + 15, 15, 32, 33, 0, 34, 0, 14, + 15, 35, 15, 36, 37, 38, 0, 0, + 0, 0, 0, 39, 40, 41, 0, 14, + 0, 42, 0, 15, 43, 15, 44, 15, + 45, 46, 47, 46, 48, 46, 0, 49, + 50, 49, 51, 49, 52, 53, 0, 54, + 0, 0, 0, 0, 55, 55, 0, 0, + 56, 56, 57, 0, 14, 58, 0, 0, + 0, 55, 0, 0, 59, 0, 0, 0, + 0, 59, 60, 0, 0, 0, 61, 62, + 63, 64, 0, 65, 65, 66, 67, 67, + 68, 0, 0, 0, 0, 69, 0, 0, + 0, 0, 0, 0, 14, 0, 0, 0, + 15, 43, 15, 15, 15, 45, 46, 47, + 46, 46, 46, 0, 49, 50, 49, 49, + 49, 70, 52, 71, 72, 0, 73, 0, + 74, 74, 0, 75, 0, 76, 45, 77, + 0, 78, 14, 79, 80, 81, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 82, + 83, 86, 0, 0, 87, 88, 89, 90, + 91, 92, 0, 14, 0, 0, 65, 65, + 0, 0, 0, 93, 0, 0, 0, 0, + 94, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 95, + 96, 97, 98, 99, 100, 45, 101, 0, + 102, 0, 0, 0, 103, 0, 104, 105, + 0, 0, 106, 0, 0, 0, 107, 0, + 108, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 107, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 109, 0, 0, 0, 0, 110, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 65, 111, + 112, 0, 0, 65, 0, 113, 114, 115, + 45, 116, 0, 0, 14, 117, 0, 118, + 119, 0, 14, 0, 0, 120, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 121, 0, 122, 0, 123, 124, 125, 126, + 127, 45, 128, 0, 0, 129, 0, 130, + 131, 132, 133, 14, 0, 13, 0, 0, + 13, 0, 0, 0, 0, 0, 0, 65, + 65, 65, 134, 135, 136, 137, 138, 139, + 140, 0, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 45, 150, 0, 151, 152, + 153, 154, 155, 156, 0, 0, 0, 157, + 65, 65, 0, 158, 159, 160, 161, 162, + 0, 0, 0, 0, 0, 163, 164, 45, + 165, 0, 166, 14, 167, 168, 169, 170, + 171, 172, 0, 14, 0, 0, 0, 0, + 0, 0, 173, 174, 175, 176, 45, 177, + 0, 178, 14, 179, 180, 181, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 182, 183, 0, 184, 0, 0, + 65, 185, 0, 0, 185, 185, 0, 0, + 65, 186, 0, 186, 0, 186, 186, 186, + 0, 0, 186, 182, 182, 182, 182, 182, + 182, 182, 182, 182, 182, 182, 182, 182, + 182, 182, 182, 182, 0, 0, 187, 188, + 188, 189, 190, 0, 191, 192, 0, 59, + 0, 193, 0, 194, 195, 196, 197, 198, + 15, 199, 200, 201, 202, 203, 45, 204, + 0, 205, 206, 0, 207, 0, 208, 209, + 185, 210, 0, 211, 0, 212, 213, 214, + 0, 0, 215, 0, 0, 0, 0, 216, + 0, 0, 0, 0, 0, 0, 0, 217, + 0, 0, 218, 0, 219, 220, 0, 0, + 0, 221, 0, 0, 222, 223, 224, 225, + 226, 227, 0, 228, 229, 229, 0, 230, + 0, 231, 232, 232, 0, 0, 233, 234, + 235, 236, 237, 0, 0, 238, 14, 182, + 182, 182, 182, 182, 182, 182, 182, 182, + 182, 182, 182, 59, 182, 182, 182, 182, + 182, 182, 182, 182, 182, 182, 182, 182, + 182, 182, 182, 182, 182, 182, 182, 182, + 182, 182, 182, 182, 239, 182, 182, 182, + 182, 182, 182, 182, 182, 182, 182, 182, + 182, 240, 241, 242, 243, 244, 244, 240, + 182, 182, 182, 182, 182, 182, 182, 182, + 182, 182, 182, 182, 182, 182, 182, 182, + 182, 182, 182, 245, 246, 247, 248, 0, + 14, 0, 0, 249, 250, 251, 45, 252, + 0, 253, 14, 254, 65, 255, 256, 0, + 14, 257, 0, 0, 258, 259, 260, 261, + 45, 262, 0, 14, 263, 264, 265, 266, + 0, 14, 0, 267, 0, 65, 268, 0, + 0, 0, 0, 269, 0, 0, 270, 270, + 0, 271, 0, 0, 0, 272, 65, 273, + 273, 273, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 274, 275, 276, 0, 277, 278, 279, + 280, 281, 282, 45, 283, 0, 284, 0, + 0, 285, 286, 287, 288, 289, 290, 291, + 292, 293, 0, 294, 0, 295, 296, 0, + 0, 297, 298, 299, 0, 0, 300, 0, + 0, 299, 301, 301, 302, 303, 0, 304, + 305, 0, 306, 307, 308, 0, 309, 310, + 0, 0, 311, 312, 299, 299, 313, 0, + 0, 314, 314, 0, 315, 0, 316, 317, + 65, 0, 318, 0, 319, 320, 321, 322, + 322, 323, 323, 0, 0, 324, 325, 325, + 326, 326, 327, 328, 328, 329, 329, 330, + 331, 331, 332, 332, 0, 0, 333, 334, + 335, 336, 337, 338, 338, 335, 337, 339, + 270, 340, 0, 0, 0, 341, 0, 0, + 342, 343, 273, 273, 273, 344, 273, 345, + 346, 14, 347, 348, 349, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 350, 0, 0, 0, 0, 344, 0, + 0, 0, 0, 0, 351, 352, 0, 0, + 0, 0, 0, 0, 353, 0, 0, 0, + 0, 0, 352, 354, 355, 0, 356, 0, + 357, 0, 0, 0, 0, 358, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 359, + 0, 0, 0, 0, 0, 0, 0, 358, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 360, 361, + 362, 363, 363, 74, 363, 364, 365, 366, + 0, 367, 368, 0, 369, 0, 370, 0, + 0, 0, 371, 372, 373, 374, 0, 14, + 0, 65, 0, 65, 375, 376, 377, 45, + 378, 0, 379, 0, 380, 381, 382, 0 +] + +class << self + attr_accessor :_lex_to_state_actions + private :_lex_to_state_actions, :_lex_to_state_actions= +end +self._lex_to_state_actions = [ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 84, 84, 0, 0, 0, 0, 84, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 84, + 0, 0, 0, 0, 0, 0, 0, 84, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 84, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 84, 0, 0, 0, 0, + 0, 84, 0, 0, 0, 0, 0, 0, + 0, 84, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 84, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 84, 0, 0, + 0, 0, 0, 0, 84, 0, 0, 0, + 0, 0, 0, 0, 84, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 84, 0, 0, 0, 0, 0, 0, 0, + 84, 0, 0, 0, 0, 0, 84, 0, + 0, 0, 0, 0, 0, 0, 0 +] + +class << self + attr_accessor :_lex_from_state_actions + private :_lex_from_state_actions, :_lex_from_state_actions= +end +self._lex_from_state_actions = [ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 85, 85, 0, 0, 0, 0, 85, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 85, + 0, 0, 0, 0, 0, 0, 0, 85, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 85, 0, 0, 0, 0, + 0, 85, 0, 0, 0, 0, 0, 0, + 0, 85, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 85, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 85, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 85, 0, 0, 0, 0, 0, 0, 0, + 85, 0, 0, 0, 0, 0, 85, 0, + 0, 0, 0, 0, 0, 0, 0 +] + +class << self + attr_accessor :_lex_eof_trans + private :_lex_eof_trans, :_lex_eof_trans= +end +self._lex_eof_trans = [ + 0, 0, 0, 0, 0, 9, 11, 13, + 13, 13, 13, 19, 19, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 94, 96, + 96, 96, 108, 108, 108, 116, 118, 118, + 118, 118, 118, 124, 116, 116, 116, 116, + 116, 116, 116, 150, 150, 150, 150, 150, + 150, 116, 166, 116, 166, 150, 150, 116, + 116, 150, 150, 150, 150, 179, 179, 179, + 184, 186, 186, 186, 190, 190, 193, 193, + 193, 193, 198, 198, 198, 184, 190, 190, + 190, 190, 190, 190, 190, 190, 190, 229, + 236, 238, 238, 238, 238, 229, 246, 246, + 246, 246, 246, 246, 246, 246, 246, 246, + 0, 0, 261, 261, 262, 263, 0, 304, + 306, 307, 308, 309, 311, 313, 317, 317, + 308, 308, 308, 308, 319, 308, 308, 313, + 308, 308, 304, 323, 323, 323, 323, 323, + 323, 313, 313, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 362, 329, + 329, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 308, 0, + 406, 407, 408, 410, 406, 406, 414, 0, + 433, 435, 437, 438, 439, 440, 441, 443, + 440, 440, 440, 440, 440, 446, 440, 440, + 448, 446, 446, 440, 0, 467, 468, 19, + 19, 471, 472, 19, 468, 468, 475, 477, + 480, 468, 481, 468, 482, 483, 485, 487, + 468, 475, 488, 488, 477, 488, 492, 488, + 488, 488, 488, 0, 94, 500, 501, 500, + 500, 0, 510, 511, 513, 515, 517, 515, + 519, 0, 531, 532, 533, 534, 536, 538, + 540, 541, 541, 541, 541, 541, 541, 541, + 541, 541, 541, 541, 541, 541, 541, 541, + 541, 0, 599, 602, 605, 606, 610, 612, + 613, 614, 615, 616, 618, 621, 622, 624, + 626, 629, 631, 632, 116, 629, 634, 629, + 621, 636, 638, 621, 621, 656, 659, 661, + 662, 666, 669, 670, 671, 672, 656, 656, + 656, 656, 656, 656, 656, 656, 656, 656, + 676, 680, 682, 656, 656, 621, 687, 688, + 688, 688, 621, 621, 621, 689, 116, 621, + 621, 694, 621, 616, 599, 599, 599, 599, + 599, 599, 599, 599, 599, 599, 599, 116, + 599, 599, 599, 599, 599, 599, 599, 599, + 599, 599, 599, 599, 599, 599, 599, 599, + 599, 599, 599, 599, 599, 599, 599, 599, + 599, 599, 599, 599, 599, 599, 599, 599, + 599, 599, 599, 599, 599, 599, 599, 599, + 599, 599, 599, 599, 599, 599, 599, 599, + 747, 606, 599, 599, 599, 599, 599, 599, + 599, 599, 599, 599, 599, 599, 599, 599, + 599, 599, 599, 599, 599, 599, 599, 599, + 599, 599, 599, 772, 621, 0, 780, 781, + 782, 784, 786, 788, 0, 797, 798, 799, + 800, 802, 797, 805, 0, 190, 860, 862, + 863, 864, 865, 867, 869, 871, 874, 874, + 190, 876, 878, 879, 880, 876, 882, 884, + 884, 887, 887, 890, 901, 190, 907, 909, + 911, 912, 915, 916, 890, 890, 919, 919, + 919, 925, 927, 928, 931, 933, 934, 935, + 919, 919, 942, 947, 952, 919, 919, 959, + 959, 919, 919, 884, 876, 876, 884, 876, + 876, 871, 190, 977, 978, 978, 978, 978, + 978, 978, 984, 871, 987, 988, 989, 989, + 989, 989, 989, 989, 989, 989, 989, 989, + 989, 989, 989, 989, 989, 989, 989, 989, + 989, 989, 989, 989, 989, 989, 989, 989, + 989, 989, 989, 989, 989, 989, 989, 989, + 989, 989, 1028, 1029, 989, 989, 1033, 989, + 989, 989, 989, 989, 989, 989, 989, 989, + 989, 989, 989, 989, 989, 989, 989, 989, + 989, 989, 989, 989, 989, 989, 989, 989, + 989, 989, 989, 989, 989, 989, 989, 989, + 989, 989, 989, 989, 989, 989, 989, 989, + 989, 989, 989, 989, 989, 989, 989, 989, + 989, 989, 989, 989, 989, 989, 989, 989, + 989, 989, 989, 989, 989, 1087, 865, 1088, + 0, 1094, 1095, 1096, 1098, 1094, 1094, 1094, + 0, 1103, 1103, 1103, 1103, 1107, 0, 1117, + 1118, 1119, 1121, 1123, 1125, 1123, 1123 +] + +class << self + attr_accessor :lex_start +end +self.lex_start = 128; +class << self + attr_accessor :lex_error +end +self.lex_error = 0; + +class << self + attr_accessor :lex_en_expr_variable +end +self.lex_en_expr_variable = 129; +class << self + attr_accessor :lex_en_expr_fname +end +self.lex_en_expr_fname = 134; +class << self + attr_accessor :lex_en_expr_endfn +end +self.lex_en_expr_endfn = 247; +class << self + attr_accessor :lex_en_expr_dot +end +self.lex_en_expr_dot = 255; +class << self + attr_accessor :lex_en_expr_arg +end +self.lex_en_expr_arg = 276; +class << self + attr_accessor :lex_en_expr_cmdarg +end +self.lex_en_expr_cmdarg = 307; +class << self + attr_accessor :lex_en_expr_endarg +end +self.lex_en_expr_endarg = 313; +class << self + attr_accessor :lex_en_expr_mid +end +self.lex_en_expr_mid = 321; +class << self + attr_accessor :lex_en_expr_beg +end +self.lex_en_expr_beg = 345; +class << self + attr_accessor :lex_en_expr_labelarg +end +self.lex_en_expr_labelarg = 501; +class << self + attr_accessor :lex_en_expr_value +end +self.lex_en_expr_value = 508; +class << self + attr_accessor :lex_en_expr_end +end +self.lex_en_expr_end = 516; +class << self + attr_accessor :lex_en_leading_dot +end +self.lex_en_leading_dot = 696; +class << self + attr_accessor :lex_en_line_comment +end +self.lex_en_line_comment = 704; +class << self + attr_accessor :lex_en_line_begin +end +self.lex_en_line_begin = 710; +class << self + attr_accessor :lex_en_inside_string +end +self.lex_en_inside_string = 128; + + +# line 82 "lib/parser/lexer.rl" + # % + + attr_reader :source_buffer + + attr_accessor :diagnostics + attr_accessor :static_env + attr_accessor :force_utf32 + + attr_accessor :cond, :cmdarg, :context, :command_start + + attr_accessor :tokens, :comments + + attr_reader :paren_nest, :cmdarg_stack, :cond_stack, :lambda_stack, :version + + def initialize(version) + @version = version + @static_env = nil + @context = nil + + @tokens = nil + @comments = nil + + @_lex_actions = + if self.class.respond_to?(:_lex_actions, true) + self.class.send :_lex_actions + else + [] + end + + @emit_integer = lambda { |chars, p| emit(:tINTEGER, chars); p } + @emit_rational = lambda { |chars, p| emit(:tRATIONAL, Rational(chars)); p } + @emit_imaginary = lambda { |chars, p| emit(:tIMAGINARY, Complex(0, chars)); p } + @emit_imaginary_rational = lambda { |chars, p| emit(:tIMAGINARY, Complex(0, Rational(chars))); p } + @emit_integer_re = lambda { |chars, p| emit(:tINTEGER, chars, @ts, @te - 2); p - 2 } + @emit_integer_if = lambda { |chars, p| emit(:tINTEGER, chars, @ts, @te - 2); p - 2 } + @emit_integer_rescue = lambda { |chars, p| emit(:tINTEGER, chars, @ts, @te - 6); p - 6 } + + @emit_float = lambda { |chars, p| emit(:tFLOAT, construct_float(chars)); p } + @emit_imaginary_float = lambda { |chars, p| emit(:tIMAGINARY, Complex(0, construct_float(chars))); p } + @emit_float_if = lambda { |chars, p| emit(:tFLOAT, construct_float(chars), @ts, @te - 2); p - 2 } + @emit_float_rescue = lambda { |chars, p| emit(:tFLOAT, construct_float(chars), @ts, @te - 6); p - 6 } + + reset + end + + def construct_float(chars) + begin + old_verbose, $VERBOSE = $VERBOSE, nil + Float(chars) + ensure + $VERBOSE = old_verbose + end + end + + def reset(reset_state=true) + # Ragel state: + if reset_state + # Unit tests set state prior to resetting lexer. + @cs = self.class.lex_en_line_begin + + @cond = StackState.new('cond') + @cmdarg = StackState.new('cmdarg') + @cond_stack = [] + @cmdarg_stack = [] + end + + @force_utf32 = false # Set to true by some tests + + @source_pts = nil # @source as a codepoint array + + @p = 0 # stream position (saved manually in #advance) + @ts = nil # token start + @te = nil # token end + @act = 0 # next action + + @stack = [] # state stack + @top = 0 # state stack top pointer + + # Lexer state: + @token_queue = [] + + @eq_begin_s = nil # location of last encountered =begin + @sharp_s = nil # location of last encountered # + + @newline_s = nil # location of last encountered newline + + @num_base = nil # last numeric base + @num_digits_s = nil # starting position of numeric digits + @num_suffix_s = nil # starting position of numeric suffix + @num_xfrm = nil # numeric suffix-induced transformation + + # Ruby 1.9 ->() lambdas emit a distinct token if do/{ is + # encountered after a matching closing parenthesis. + @paren_nest = 0 + @lambda_stack = [] + + # If the lexer is in `command state' (aka expr_value) + # at the entry to #advance, it will transition to expr_cmdarg + # instead of expr_arg at certain points. + @command_start = true + + # State before =begin / =end block comment + @cs_before_block_comment = self.class.lex_en_line_begin + + @strings = Parser::LexerStrings.new(self, @version) + end + + def source_buffer=(source_buffer) + @source_buffer = source_buffer + + if @source_buffer + source = @source_buffer.source + + if source.encoding == Encoding::UTF_8 + @source_pts = source.unpack('U*') + else + @source_pts = source.unpack('C*') + end + + if @source_pts[0] == 0xfeff + # Skip byte order mark. + @p = 1 + end + else + @source_pts = nil + end + + @strings.source_buffer = @source_buffer + @strings.source_pts = @source_pts + end + + def encoding + @source_buffer.source.encoding + end + + LEX_STATES = { + :line_begin => lex_en_line_begin, + :expr_dot => lex_en_expr_dot, + :expr_fname => lex_en_expr_fname, + :expr_value => lex_en_expr_value, + :expr_beg => lex_en_expr_beg, + :expr_mid => lex_en_expr_mid, + :expr_arg => lex_en_expr_arg, + :expr_cmdarg => lex_en_expr_cmdarg, + :expr_end => lex_en_expr_end, + :expr_endarg => lex_en_expr_endarg, + :expr_endfn => lex_en_expr_endfn, + :expr_labelarg => lex_en_expr_labelarg, + + :inside_string => lex_en_inside_string + } + + def state + LEX_STATES.invert.fetch(@cs, @cs) + end + + def state=(state) + @cs = LEX_STATES.fetch(state) + end + + def push_cmdarg + @cmdarg_stack.push(@cmdarg) + @cmdarg = StackState.new("cmdarg.#{@cmdarg_stack.count}") + end + + def pop_cmdarg + @cmdarg = @cmdarg_stack.pop + end + + def push_cond + @cond_stack.push(@cond) + @cond = StackState.new("cond.#{@cond_stack.count}") + end + + def pop_cond + @cond = @cond_stack.pop + end + + def dedent_level + @strings.dedent_level + end + + # Return next token: [type, value]. + def advance + unless @token_queue.empty? + return @token_queue.shift + end + + # Ugly, but dependent on Ragel output. Consider refactoring it somehow. + klass = self.class + _lex_trans_keys = klass.send :_lex_trans_keys + _lex_key_spans = klass.send :_lex_key_spans + _lex_index_offsets = klass.send :_lex_index_offsets + _lex_indicies = klass.send :_lex_indicies + _lex_trans_targs = klass.send :_lex_trans_targs + _lex_trans_actions = klass.send :_lex_trans_actions + _lex_to_state_actions = klass.send :_lex_to_state_actions + _lex_from_state_actions = klass.send :_lex_from_state_actions + _lex_eof_trans = klass.send :_lex_eof_trans + _lex_actions = @_lex_actions + + pe = @source_pts.size + 2 + p, eof = @p, pe + + cmd_state = @command_start + @command_start = false + + +# line 8444 "lib/parser/lexer-F1.rb" +begin + testEof = false + _slen, _trans, _keys, _inds, _acts, _nacts = nil + _goto_level = 0 + _resume = 10 + _eof_trans = 15 + _again = 20 + _test_eof = 30 + _out = 40 + while true + if _goto_level <= 0 + if p == pe + _goto_level = _test_eof + next + end + if @cs == 0 + _goto_level = _out + next + end + end + if _goto_level <= _resume + case _lex_from_state_actions[ @cs] + when 85 then +# line 1 "NONE" + begin + @ts = p + end +# line 8472 "lib/parser/lexer-F1.rb" + end + _keys = @cs << 1 + _inds = _lex_index_offsets[ @cs] + _slen = _lex_key_spans[ @cs] + _wide = ( (@source_pts[p] || 0)) + _trans = if ( _slen > 0 && + _lex_trans_keys[_keys] <= _wide && + _wide <= _lex_trans_keys[_keys + 1] + ) then + _lex_indicies[ _inds + _wide - _lex_trans_keys[_keys] ] + else + _lex_indicies[ _inds + _slen ] + end + end + if _goto_level <= _eof_trans + @cs = _lex_trans_targs[_trans] + if _lex_trans_actions[_trans] != 0 + case _lex_trans_actions[_trans] + when 14 then +# line 548 "lib/parser/lexer.rl" + begin + + # Record position of a newline for precise location reporting on tNL + # tokens. + # + # This action is embedded directly into c_nl, as it is idempotent and + # there are no cases when we need to skip it. + @newline_s = p + end + when 15 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end + when 45 then +# line 742 "lib/parser/lexer.rl" + begin + @sharp_s = p - 1 end + when 49 then +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end + when 190 then +# line 786 "lib/parser/lexer.rl" + begin + tm = p end + when 22 then +# line 1070 "lib/parser/lexer.rl" + begin + tm = p end + when 24 then +# line 1083 "lib/parser/lexer.rl" + begin + tm = p end + when 26 then +# line 1111 "lib/parser/lexer.rl" + begin + tm = p end + when 56 then +# line 1308 "lib/parser/lexer.rl" + begin + heredoc_e = p end + when 229 then +# line 1409 "lib/parser/lexer.rl" + begin + tm = p - 1; diag_msg = :ivar_name end + when 232 then +# line 1410 "lib/parser/lexer.rl" + begin + tm = p - 2; diag_msg = :cvar_name end + when 244 then +# line 1497 "lib/parser/lexer.rl" + begin + tm = p end + when 188 then +# line 1604 "lib/parser/lexer.rl" + begin + ident_tok = tok; ident_ts = @ts; ident_te = @te; end + when 331 then +# line 1790 "lib/parser/lexer.rl" + begin + @num_base = 16; @num_digits_s = p end + when 325 then +# line 1791 "lib/parser/lexer.rl" + begin + @num_base = 10; @num_digits_s = p end + when 328 then +# line 1792 "lib/parser/lexer.rl" + begin + @num_base = 8; @num_digits_s = p end + when 322 then +# line 1793 "lib/parser/lexer.rl" + begin + @num_base = 2; @num_digits_s = p end + when 337 then +# line 1794 "lib/parser/lexer.rl" + begin + @num_base = 10; @num_digits_s = @ts end + when 299 then +# line 1795 "lib/parser/lexer.rl" + begin + @num_base = 8; @num_digits_s = @ts end + when 314 then +# line 1796 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end + when 307 then +# line 1839 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end + when 304 then +# line 1840 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end + when 74 then +# line 2043 "lib/parser/lexer.rl" + begin + tm = p end + when 65 then +# line 1 "NONE" + begin + @te = p+1 + end + when 1 then +# line 857 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + emit_global_var + + @cs = (stack_pop); begin + p += 1 + _goto_level = _out + next + end + + end + end + when 87 then +# line 857 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit_global_var + + @cs = (stack_pop); begin + p += 1 + _goto_level = _out + next + end + + end + end + when 89 then +# line 864 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit_class_var + + @cs = (stack_pop); begin + p += 1 + _goto_level = _out + next + end + + end + end + when 88 then +# line 871 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit_instance_var + + @cs = (stack_pop); begin + p += 1 + _goto_level = _out + next + end + + end + end + when 110 then +# line 889 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit_table(KEYWORDS_BEGIN); + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + end + end + when 96 then +# line 897 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit(:tIDENTIFIER) + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + end + end + when 3 then +# line 901 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = @ts - 1 + @cs = 516; begin + @stack[ @top] = @cs + @top+= 1 + @cs = 129 + _goto_level = _again + next + end + end + end + when 93 then +# line 910 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit_table(PUNCTUATION) + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + end + end + when 105 then +# line 914 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = p - 1; p = p - 1; begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 5 then +# line 920 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + if version?(23) + type, delimiter = tok[0..-2], tok[-1].chr + @strings.push_literal(type, delimiter, @ts) + begin + @cs = 128 + _goto_level = _again + next + end + + else + p = @ts - 1 + begin + @cs = 516 + _goto_level = _again + next + end + + end + end + end + when 92 then +# line 934 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = p - 1; begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 91 then +# line 575 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Sit at EOF indefinitely. #advance would return $eof each time. + # This allows to feed the lexer more data if needed; this is only used + # in tests. + # + # Note that this action is not embedded into e_eof like e_nl and e_bs + # below. This is due to the fact that scanner state at EOF is observed + # by tests, and encapsulating it in a rule would break the introspection. + p = p - 1; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 109 then +# line 889 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit_table(KEYWORDS_BEGIN); + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + end + end + when 106 then +# line 893 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tCONSTANT) + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + end + end + when 108 then +# line 897 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tIDENTIFIER) + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + end + end + when 103 then +# line 901 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = @ts - 1 + @cs = 516; begin + @stack[ @top] = @cs + @top+= 1 + @cs = 129 + _goto_level = _again + next + end + end + end + when 99 then +# line 910 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit_table(PUNCTUATION) + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + end + end + when 104 then +# line 917 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 345 + _goto_level = _again + next + end + end + end + when 97 then +# line 931 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 102 then +# line 934 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 4 then +# line 910 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin emit_table(PUNCTUATION) + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + end + end + when 2 then +# line 934 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin p = p - 1; begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 95 then +# line 1 "NONE" + begin + case @act + when 4 then + begin begin p = (( @te))-1; end + emit_table(KEYWORDS_BEGIN); + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + end + when 5 then + begin begin p = (( @te))-1; end + emit(:tCONSTANT) + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + end + when 6 then + begin begin p = (( @te))-1; end + emit(:tIDENTIFIER) + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + end +end + end + when 7 then +# line 946 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit(:tLABEL, tok(@ts, @te - 2), @ts, @te - 1) + p = p - 1; @cs = 501; begin + p += 1 + _goto_level = _out + next + end + end + end + when 8 then +# line 950 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + if @version >= 31 && @context.in_argdef + emit(:tBDOT3, '...'.freeze) + # emit(:tNL, "\n".freeze, @te - 1, @te) + @cs = 516; begin + p += 1 + _goto_level = _out + next + end + + else + p -= 3; + begin + @cs = 516 + _goto_level = _again + next + end + + end + end + end + when 112 then +# line 964 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = p - 1; begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 111 then +# line 575 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Sit at EOF indefinitely. #advance would return $eof each time. + # This allows to feed the lexer more data if needed; this is only used + # in tests. + # + # Note that this action is not embedded into e_eof like e_nl and e_bs + # below. This is due to the fact that scanner state at EOF is observed + # by tests, and encapsulating it in a rule would break the introspection. + p = p - 1; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 114 then +# line 961 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 113 then +# line 964 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 6 then +# line 964 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin p = p - 1; begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 120 then +# line 990 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit_table(PUNCTUATION) + @cs = 276; begin + p += 1 + _goto_level = _out + next + end + end + end + when 119 then +# line 996 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = p - 1; begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 118 then +# line 575 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Sit at EOF indefinitely. #advance would return $eof each time. + # This allows to feed the lexer more data if needed; this is only used + # in tests. + # + # Note that this action is not embedded into e_eof like e_nl and e_bs + # below. This is due to the fact that scanner state at EOF is observed + # by tests, and encapsulating it in a rule would break the introspection. + p = p - 1; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 130 then +# line 975 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tCONSTANT) + @cs = (arg_or_cmdarg(cmd_state)); begin + p += 1 + _goto_level = _out + next + end + end + end + when 121 then +# line 979 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tIDENTIFIER) + @cs = (arg_or_cmdarg(cmd_state)); begin + p += 1 + _goto_level = _out + next + end + end + end + when 126 then +# line 990 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit_table(PUNCTUATION) + @cs = 276; begin + p += 1 + _goto_level = _out + next + end + end + end + when 124 then +# line 993 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 129 then +# line 996 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 153 then +# line 1056 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Unlike expr_beg as invoked in the next rule, do not warn + p = @ts - 1 + begin + @cs = 516 + _goto_level = _again + next + end + + end + end + when 136 then +# line 1074 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + check_ambiguous_slash(tm) + + p = tm - 1 + begin + @cs = 345 + _goto_level = _again + next + end + + end + end + when 142 then +# line 1095 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = p - 1; p = p - 1; begin + @cs = 345 + _goto_level = _again + next + end + end + end + when 10 then +# line 1103 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = @ts - 1; begin + @cs = 345 + _goto_level = _again + next + end + end + end + when 144 then +# line 1112 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = tm - 1; begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 25 then +# line 1123 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + p = @ts - 1 + begin + @cs = 516 + _goto_level = _again + next + end + + end + end + when 131 then +# line 1137 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = p - 1; begin + @cs = 345 + _goto_level = _again + next + end + end + end + when 132 then +# line 575 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Sit at EOF indefinitely. #advance would return $eof each time. + # This allows to feed the lexer more data if needed; this is only used + # in tests. + # + # Note that this action is not embedded into e_eof like e_nl and e_bs + # below. This is due to the fact that scanner state at EOF is observed + # by tests, and encapsulating it in a rule would break the introspection. + p = p - 1; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 143 then +# line 1065 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 345 + _goto_level = _again + next + end + end + end + when 139 then +# line 1084 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + diagnostic :warning, :ambiguous_prefix, { :prefix => tok(tm, @te) }, + range(tm, @te) + + p = tm - 1 + begin + @cs = 345 + _goto_level = _again + next + end + + end + end + when 141 then +# line 1100 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 345 + _goto_level = _again + next + end + end + end + when 135 then +# line 1123 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + p = @ts - 1 + begin + @cs = 516 + _goto_level = _again + next + end + + end + end + when 134 then +# line 1128 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 152 then +# line 1137 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 345 + _goto_level = _again + next + end + end + end + when 11 then +# line 1128 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + end + when 27 then +# line 1137 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin p = p - 1; begin + @cs = 345 + _goto_level = _again + next + end + end + end + when 9 then +# line 1 "NONE" + begin + case @act + when 33 then + begin begin p = (( @te))-1; end + + check_ambiguous_slash(tm) + + p = tm - 1 + begin + @cs = 345 + _goto_level = _again + next + end + + end + when 34 then + begin begin p = (( @te))-1; end + + diagnostic :warning, :ambiguous_prefix, { :prefix => tok(tm, @te) }, + range(tm, @te) + + p = tm - 1 + begin + @cs = 345 + _goto_level = _again + next + end + + end + when 39 then + begin begin p = (( @te))-1; end + + p = @ts - 1 + begin + @cs = 516 + _goto_level = _again + next + end + + end + else + begin begin p = (( @te))-1; end +end +end + end + when 29 then +# line 1173 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = @ts - 1 + begin + @cs = 276 + _goto_level = _again + next + end + end + end + when 157 then +# line 575 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Sit at EOF indefinitely. #advance would return $eof each time. + # This allows to feed the lexer more data if needed; this is only used + # in tests. + # + # Note that this action is not embedded into e_eof like e_nl and e_bs + # below. This is due to the fact that scanner state at EOF is observed + # by tests, and encapsulating it in a rule would break the introspection. + p = p - 1; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 158 then +# line 1173 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = @ts - 1 + begin + @cs = 276 + _goto_level = _again + next + end + end + end + when 30 then +# line 1173 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin p = @ts - 1 + begin + @cs = 276 + _goto_level = _again + next + end + end + end + when 28 then +# line 1 "NONE" + begin + case @act + when 46 then + begin begin p = (( @te))-1; end + + if @cond.active? + emit(:kDO_COND, 'do'.freeze, @te - 2, @te) + else + emit(:kDO, 'do'.freeze, @te - 2, @te) + end + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + + end + when 47 then + begin begin p = (( @te))-1; end + p = @ts - 1 + begin + @cs = 276 + _goto_level = _again + next + end + end +end + end + when 168 then +# line 1209 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit_do(true) + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + end + end + when 161 then +# line 1215 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = p - 1; begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 162 then +# line 575 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Sit at EOF indefinitely. #advance would return $eof each time. + # This allows to feed the lexer more data if needed; this is only used + # in tests. + # + # Note that this action is not embedded into e_eof like e_nl and e_bs + # below. This is due to the fact that scanner state at EOF is observed + # by tests, and encapsulating it in a rule would break the introspection. + p = p - 1; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 163 then +# line 1212 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 166 then +# line 1215 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 172 then +# line 1239 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = p - 1; begin + @cs = 345 + _goto_level = _again + next + end + end + end + when 171 then +# line 575 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Sit at EOF indefinitely. #advance would return $eof each time. + # This allows to feed the lexer more data if needed; this is only used + # in tests. + # + # Note that this action is not embedded into e_eof like e_nl and e_bs + # below. This is due to the fact that scanner state at EOF is observed + # by tests, and encapsulating it in a rule would break the introspection. + p = p - 1; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 180 then +# line 1231 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = @ts - 1; begin + @cs = 345 + _goto_level = _again + next + end + end + end + when 174 then +# line 1233 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 178 then +# line 1239 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 345 + _goto_level = _again + next + end + end + end + when 173 then +# line 1 "NONE" + begin + case @act + when 54 then + begin begin p = (( @te))-1; end + emit_table(KEYWORDS) + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + end + when 55 then + begin begin p = (( @te))-1; end + p = @ts - 1; begin + @cs = 345 + _goto_level = _again + next + end + end +end + end + when 42 then +# line 1254 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + emit(:tUNARY_NUM, tok(@ts, @ts + 1), @ts, @ts + 1) + p = p - 1; @cs = 516; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 214 then +# line 1271 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + type = delimiter = tok[0].chr + @strings.push_literal(type, delimiter, @ts) + + p = p - 1; + begin + @cs = 128 + _goto_level = _again + next + end + + end + end + when 206 then +# line 1281 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + type, delimiter = @source_buffer.slice(@ts, 1).chr, tok[-1].chr + @strings.push_literal(type, delimiter, @ts) + begin + @cs = 128 + _goto_level = _again + next + end + + end + end + when 40 then +# line 1289 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + type, delimiter = tok[0..-2], tok[-1].chr + @strings.push_literal(type, delimiter, @ts) + begin + @cs = 128 + _goto_level = _again + next + end + + end + end + when 227 then +# line 1366 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + p = p - 1; p = p - 1; + emit(:tSYMBEG, tok(@ts, @ts + 1), @ts, @ts + 1) + begin + @cs = 134 + _goto_level = _again + next + end + + end + end + when 215 then +# line 1374 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + type, delimiter = tok, tok[-1].chr + @strings.push_literal(type, delimiter, @ts); + + begin + @cs = 128 + _goto_level = _again + next + end + + end + end + when 226 then +# line 1384 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + emit(:tSYMBOL, tok(@ts + 1, @ts + 2)) + @cs = 516; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 54 then +# line 1398 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + gvar_name = tok(@ts + 1) + + if @version >= 33 && gvar_name.start_with?('$0') && gvar_name.length > 2 + diagnostic :error, :gvar_name, { :name => gvar_name }, range(@ts + 1, @te) + end + + emit(:tSYMBOL, gvar_name, @ts) + @cs = 516; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 236 then +# line 1425 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + p, next_state = @strings.read_character_constant(@ts) + p = p - 1; # Ragel will do `p += 1` to consume input, prevent it + + # If strings lexer founds a character constant (?a) emit it, + # otherwise read ternary operator + if @token_queue.empty? + begin + @cs = (next_state) + _goto_level = _again + next + end + + else + @cs = (next_state); + begin + p += 1 + _goto_level = _out + next + end + + end + end + end + when 237 then +# line 1440 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + diagnostic :fatal, :incomplete_escape, nil, range(@ts, @ts + 1) + end + end + when 216 then +# line 1492 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit_table(PUNCTUATION_BEGIN) + begin + p += 1 + _goto_level = _out + next + end + end + end + when 37 then +# line 1513 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + p = p - 1; + + if version?(18) + ident = tok(@ts, @te - 2) + + emit((@source_buffer.slice(@ts, 1) =~ /[A-Z]/) ? :tCONSTANT : :tIDENTIFIER, + ident, @ts, @te - 2) + p = p - 1; # continue as a symbol + + if !@static_env.nil? && @static_env.declared?(ident) + @cs = 516; + else + @cs = (arg_or_cmdarg(cmd_state)); + end + else + emit(:tLABEL, tok(@ts, @te - 2), @ts, @te - 1) + @cs = 501; + end + + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 34 then +# line 1606 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + emit(:tIDENTIFIER, ident_tok, ident_ts, ident_te) + p = ident_te - 1 + + if !@static_env.nil? && @static_env.declared?(ident_tok) && @version < 25 + @cs = 247; + else + @cs = 307; + end + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 200 then +# line 1625 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + p = @ts - 1 + @cs_before_block_comment = @cs + begin + @cs = 710 + _goto_level = _again + next + end + + end + end + when 41 then +# line 1641 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = @ts - 1; begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 183 then +# line 575 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Sit at EOF indefinitely. #advance would return $eof each time. + # This allows to feed the lexer more data if needed; this is only used + # in tests. + # + # Note that this action is not embedded into e_eof like e_nl and e_bs + # below. This is due to the fact that scanner state at EOF is observed + # by tests, and encapsulating it in a rule would break the introspection. + p = p - 1; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 210 then +# line 1254 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit(:tUNARY_NUM, tok(@ts, @ts + 1), @ts, @ts + 1) + p = p - 1; @cs = 516; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 209 then +# line 1261 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tSTAR, '*'.freeze) + begin + p += 1 + _goto_level = _out + next + end + end + end + when 205 then +# line 1296 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + diagnostic :fatal, :string_eof, nil, range(@ts, @ts + 1) + end + end + when 234 then +# line 1357 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + diagnostic :error, :unterminated_heredoc_id, nil, range(@ts, @ts + 1) + end + end + when 217 then +# line 1398 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + gvar_name = tok(@ts + 1) + + if @version >= 33 && gvar_name.start_with?('$0') && gvar_name.length > 2 + diagnostic :error, :gvar_name, { :name => gvar_name }, range(@ts + 1, @te) + end + + emit(:tSYMBOL, gvar_name, @ts) + @cs = 516; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 230 then +# line 1412 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit_colon_with_digits(p, tm, diag_msg) + + @cs = 516; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 235 then +# line 1440 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + diagnostic :fatal, :incomplete_escape, nil, range(@ts, @ts + 1) + end + end + when 207 then +# line 1492 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit_table(PUNCTUATION_BEGIN) + begin + p += 1 + _goto_level = _out + next + end + end + end + when 211 then +# line 1540 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + if @version >= 27 + emit(:tBDOT2) + else + emit(:tDOT2) + end + + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 212 then +# line 1551 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + # Here we scan and conditionally emit "\n": + # + if it's there + # + and emitted we do nothing + # + and not emitted we return `p` to "\n" to process it on the next scan + # + if it's not there we do nothing + followed_by_nl = @te - 1 == @newline_s + nl_emitted = false + dots_te = followed_by_nl ? @te - 1 : @te + + if @version >= 30 + if @lambda_stack.any? && @lambda_stack.last + 1 == @paren_nest + # To reject `->(...)` like `->...` + emit(:tDOT3, '...'.freeze, @ts, dots_te) + else + emit(:tBDOT3, '...'.freeze, @ts, dots_te) + + if @version >= 31 && followed_by_nl && @context.in_argdef + emit(:tNL, @te - 1, @te) + nl_emitted = true + end + end + elsif @version >= 27 + emit(:tBDOT3, '...'.freeze, @ts, dots_te) + else + emit(:tDOT3, '...'.freeze, @ts, dots_te) + end + + if followed_by_nl && !nl_emitted + # return "\n" to process it on the next scan + p = p - 1; + end + + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 187 then +# line 840 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit(:tIDENTIFIER) + + if !@static_env.nil? && @static_env.declared?(tok) + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + + elsif @version >= 32 && tok =~ /\A_[1-9]\z/ + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + + else + @cs = (arg_or_cmdarg(cmd_state)); begin + p += 1 + _goto_level = _out + next + end + + end + end + end + when 197 then +# line 1622 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 199 then +# line 1625 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + p = @ts - 1 + @cs_before_block_comment = @cs + begin + @cs = 710 + _goto_level = _again + next + end + + end + end + when 202 then +# line 1641 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = @ts - 1; begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 39 then +# line 1296 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin + diagnostic :fatal, :string_eof, nil, range(@ts, @ts + 1) + end + end + when 58 then +# line 1357 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin + diagnostic :error, :unterminated_heredoc_id, nil, range(@ts, @ts + 1) + end + end + when 33 then +# line 840 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin + emit(:tIDENTIFIER) + + if !@static_env.nil? && @static_env.declared?(tok) + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + + elsif @version >= 32 && tok =~ /\A_[1-9]\z/ + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + + else + @cs = (arg_or_cmdarg(cmd_state)); begin + p += 1 + _goto_level = _out + next + end + + end + end + end + when 38 then +# line 1622 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + end + when 53 then +# line 1641 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin p = @ts - 1; begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 36 then +# line 1 "NONE" + begin + case @act + when 60 then + begin begin p = (( @te))-1; end + + emit(:tUNARY_NUM, tok(@ts, @ts + 1), @ts, @ts + 1) + p = p - 1; @cs = 516; begin + p += 1 + _goto_level = _out + next + end + + end + when 67 then + begin begin p = (( @te))-1; end + + diagnostic :error, :unterminated_heredoc_id, nil, range(@ts, @ts + 1) + end + when 76 then + begin begin p = (( @te))-1; end + + if @version >= 27 + emit(:tPIPE, tok(@ts, @ts + 1), @ts, @ts + 1) + p = p - 1; + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + + else + p -= 2 + begin + @cs = 516 + _goto_level = _again + next + end + + end + end + when 80 then + begin begin p = (( @te))-1; end + emit_table(PUNCTUATION_BEGIN) + begin + p += 1 + _goto_level = _out + next + end + end + when 81 then + begin begin p = (( @te))-1; end + emit(:kRESCUE, 'rescue'.freeze, @ts, tm) + p = tm - 1 + @cs = 321; begin + p += 1 + _goto_level = _out + next + end + end + when 82 then + begin begin p = (( @te))-1; end + emit_table(KEYWORDS_BEGIN) + @command_start = true + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + end + when 86 then + begin begin p = (( @te))-1; end + p = @ts - 1 + begin + @cs = 516 + _goto_level = _again + next + end + end + when 87 then + begin begin p = (( @te))-1; end + + emit(:tIDENTIFIER) + + if !@static_env.nil? && @static_env.declared?(tok) + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + + elsif @version >= 32 && tok =~ /\A_[1-9]\z/ + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + + else + @cs = (arg_or_cmdarg(cmd_state)); begin + p += 1 + _goto_level = _out + next + end + + end + end + when 91 then + begin begin p = (( @te))-1; end + p = @ts - 1; begin + @cs = 516 + _goto_level = _again + next + end + end +end + end + when 247 then +# line 1661 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = p - 1; begin + @cs = 345 + _goto_level = _again + next + end + end + end + when 248 then +# line 575 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Sit at EOF indefinitely. #advance would return $eof each time. + # This allows to feed the lexer more data if needed; this is only used + # in tests. + # + # Note that this action is not embedded into e_eof like e_nl and e_bs + # below. This is due to the fact that scanner state at EOF is observed + # by tests, and encapsulating it in a rule would break the introspection. + p = p - 1; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 249 then +# line 1649 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 253 then +# line 1661 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 345 + _goto_level = _again + next + end + end + end + when 61 then +# line 1671 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = @ts - 1 + begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 257 then +# line 1676 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + @strings.push_literal(tok, tok, @ts) + begin + @cs = 128 + _goto_level = _again + next + end + + end + end + when 256 then +# line 1687 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = p - 1; begin + @cs = 345 + _goto_level = _again + next + end + end + end + when 255 then +# line 575 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Sit at EOF indefinitely. #advance would return $eof each time. + # This allows to feed the lexer more data if needed; this is only used + # in tests. + # + # Note that this action is not embedded into e_eof like e_nl and e_bs + # below. This is due to the fact that scanner state at EOF is observed + # by tests, and encapsulating it in a rule would break the introspection. + p = p - 1; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 259 then +# line 1681 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 258 then +# line 1687 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 345 + _goto_level = _again + next + end + end + end + when 60 then +# line 1687 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin p = p - 1; begin + @cs = 345 + _goto_level = _again + next + end + end + end + when 292 then +# line 1698 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + emit(:tLAMBDA, '->'.freeze, @ts, @ts + 2) + + @lambda_stack.push @paren_nest + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 71 then +# line 1739 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit_singleton_class + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + end + end + when 267 then +# line 1860 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + type, delimiter = tok, tok[-1].chr + @strings.push_literal(type, delimiter, @ts, nil, false, false, true); + begin + @cs = 128 + _goto_level = _again + next + end + + end + end + when 63 then +# line 1879 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = @ts - 1; begin + @stack[ @top] = @cs + @top+= 1 + @cs = 129 + _goto_level = _again + next + end + end + end + when 288 then +# line 1886 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit_table(PUNCTUATION) + @cs = 255; begin + p += 1 + _goto_level = _out + next + end + end + end + when 341 then +# line 1910 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + emit_table(PUNCTUATION) + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 281 then +# line 1919 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + emit_table(PUNCTUATION); + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 286 then +# line 1946 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit(:tOP_ASGN, tok(@ts, @te - 1)) + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + end + end + when 272 then +# line 1950 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit(:tEH, '?'.freeze) + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + end + end + when 269 then +# line 1969 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit_table(PUNCTUATION) + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + end + end + when 271 then +# line 1982 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit(:tSEMI, ';'.freeze) + @command_start = true + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + end + end + when 346 then +# line 1986 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + diagnostic :error, :bare_backslash, nil, range(@ts, @ts + 1) + p = p - 1; + end + end + when 266 then +# line 1992 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + diagnostic :fatal, :unexpected, { :character => tok.inspect[1..-2] } + end + end + when 265 then +# line 575 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Sit at EOF indefinitely. #advance would return $eof each time. + # This allows to feed the lexer more data if needed; this is only used + # in tests. + # + # Note that this action is not embedded into e_eof like e_nl and e_bs + # below. This is due to the fact that scanner state at EOF is observed + # by tests, and encapsulating it in a rule would break the introspection. + p = p - 1; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 357 then +# line 1735 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit_table(KEYWORDS) + @cs = 134; begin + p += 1 + _goto_level = _out + next + end + end + end + when 355 then +# line 1739 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit_singleton_class + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + end + end + when 354 then +# line 1749 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit_table(KEYWORDS) + @command_start = true + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + end + end + when 296 then +# line 1810 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + diagnostic :error, :no_dot_digit_literal + end + end + when 343 then +# line 1871 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tCONSTANT) + @cs = (arg_or_cmdarg(cmd_state)); begin + p += 1 + _goto_level = _out + next + end + end + end + when 285 then +# line 1879 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = @ts - 1; begin + @stack[ @top] = @cs + @top+= 1 + @cs = 129 + _goto_level = _again + next + end + end + end + when 293 then +# line 1886 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit_table(PUNCTUATION) + @cs = 255; begin + p += 1 + _goto_level = _out + next + end + end + end + when 349 then +# line 840 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit(:tIDENTIFIER) + + if !@static_env.nil? && @static_env.declared?(tok) + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + + elsif @version >= 32 && tok =~ /\A_[1-9]\z/ + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + + else + @cs = (arg_or_cmdarg(cmd_state)); begin + p += 1 + _goto_level = _out + next + end + + end + end + end + when 291 then +# line 1910 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit_table(PUNCTUATION) + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 287 then +# line 1919 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit_table(PUNCTUATION); + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 280 then +# line 1925 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit_table(PUNCTUATION) + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + end + end + when 294 then +# line 1969 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit_table(PUNCTUATION) + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + end + end + when 278 then +# line 1976 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 284 then +# line 1992 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + diagnostic :fatal, :unexpected, { :character => tok.inspect[1..-2] } + end + end + when 69 then +# line 1797 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin + digits = numeric_literal_int + + if version?(18, 19, 20) + emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits.to_i(@num_base), p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 64 then +# line 1810 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin + diagnostic :error, :no_dot_digit_literal + end + end + when 68 then +# line 1842 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin + digits = tok(@ts, @num_suffix_s) + + if version?(18, 19, 20) + emit(:tFLOAT, Float(digits), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits, p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 62 then +# line 1992 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin + diagnostic :fatal, :unexpected, { :character => tok.inspect[1..-2] } + end + end + when 66 then +# line 1 "NONE" + begin + case @act + when 104 then + begin begin p = (( @te))-1; end + + if @lambda_stack.last == @paren_nest + @lambda_stack.pop + + if tok == '{'.freeze + emit(:tLAMBEG, '{'.freeze) + else # 'do' + emit(:kDO_LAMBDA, 'do'.freeze) + end + else + if tok == '{'.freeze + emit(:tLCURLY, '{'.freeze) + else # 'do' + emit_do + end + end + if tok == '{'.freeze + @paren_nest += 1 + end + @command_start = true + + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + + end + when 105 then + begin begin p = (( @te))-1; end + emit_table(KEYWORDS) + @cs = 134; begin + p += 1 + _goto_level = _out + next + end + end + when 106 then + begin begin p = (( @te))-1; end + emit_singleton_class + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + end + when 107 then + begin begin p = (( @te))-1; end + emit_table(KEYWORDS) + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + end + when 108 then + begin begin p = (( @te))-1; end + emit_table(KEYWORDS) + @command_start = true + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + end + when 109 then + begin begin p = (( @te))-1; end + emit_table(KEYWORDS) + @cs = 321; begin + p += 1 + _goto_level = _out + next + end + end + when 110 then + begin begin p = (( @te))-1; end + + emit_table(KEYWORDS) + + if version?(18) && tok == 'not'.freeze + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + + else + @cs = 276; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 111 then + begin begin p = (( @te))-1; end + + if version?(18) + emit(:tIDENTIFIER) + + unless !@static_env.nil? && @static_env.declared?(tok) + @cs = (arg_or_cmdarg(cmd_state)); + end + else + emit(:k__ENCODING__, '__ENCODING__'.freeze) + end + begin + p += 1 + _goto_level = _out + next + end + + end + when 112 then + begin begin p = (( @te))-1; end + emit_table(KEYWORDS) + begin + p += 1 + _goto_level = _out + next + end + end + when 113 then + begin begin p = (( @te))-1; end + + digits = numeric_literal_int + + if version?(18, 19, 20) + emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits.to_i(@num_base), p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + when 115 then + begin begin p = (( @te))-1; end + + if version?(18, 19, 20) + diagnostic :error, + :trailing_in_number, { :character => tok(@te - 1, @te) }, + range(@te - 1, @te) + else + emit(:tINTEGER, tok(@ts, @te - 1).to_i, @ts, @te - 1) + p = p - 1; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 116 then + begin begin p = (( @te))-1; end + + if version?(18, 19, 20) + diagnostic :error, + :trailing_in_number, { :character => tok(@te - 1, @te) }, + range(@te - 1, @te) + else + emit(:tFLOAT, tok(@ts, @te - 1).to_f, @ts, @te - 1) + p = p - 1; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 117 then + begin begin p = (( @te))-1; end + + digits = tok(@ts, @num_suffix_s) + + if version?(18, 19, 20) + emit(:tFLOAT, Float(digits), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits, p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + when 119 then + begin begin p = (( @te))-1; end + emit(:tCONSTANT) + @cs = (arg_or_cmdarg(cmd_state)); begin + p += 1 + _goto_level = _out + next + end + end + when 123 then + begin begin p = (( @te))-1; end + + emit(:tIDENTIFIER) + + if !@static_env.nil? && @static_env.declared?(tok) + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + + elsif @version >= 32 && tok =~ /\A_[1-9]\z/ + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + + else + @cs = (arg_or_cmdarg(cmd_state)); begin + p += 1 + _goto_level = _out + next + end + + end + end + when 124 then + begin begin p = (( @te))-1; end + + if tm == @te + # Suffix was consumed, e.g. foo! + emit(:tFID) + else + # Suffix was not consumed, e.g. foo!= + emit(:tIDENTIFIER, tok(@ts, tm), @ts, tm) + p = tm - 1 + end + @cs = 276; begin + p += 1 + _goto_level = _out + next + end + + end + when 126 then + begin begin p = (( @te))-1; end + + emit_table(PUNCTUATION); + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + + end + when 127 then + begin begin p = (( @te))-1; end + emit_table(PUNCTUATION) + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + end +end + end + when 368 then +# line 2033 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + emit(:tNL, nil, @newline_s, @newline_s + 1) + if @version < 27 + p = p - 1; @cs = 710; begin + p += 1 + _goto_level = _out + next + end + + else + emit(:tBDOT3) + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + + end + end + end + when 80 then +# line 2044 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = tm - 1; begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 362 then +# line 2047 "lib/parser/lexer.rl" + begin + @te = p+1 + begin emit(:tNL, nil, @newline_s, @newline_s + 1) + p = p - 1; @cs = 710; begin + p += 1 + _goto_level = _out + next + end + end + end + when 365 then +# line 2008 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + if @version < 27 + # Ruby before 2.7 doesn't support comments before leading dot. + # If a line after "a" starts with a comment then "a" is a self-contained statement. + # So in that case we emit a special tNL token and start reading the + # next line as a separate statement. + # + # Note: block comments before leading dot are not supported on any version of Ruby. + emit(:tNL, nil, @newline_s, @newline_s + 1) + p = p - 1; @cs = 710; begin + p += 1 + _goto_level = _out + next + end + + end + end + end + when 367 then +# line 2022 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit(:tNL, nil, @newline_s, @newline_s + 1) + if @version < 27 + p = p - 1; @cs = 710; begin + p += 1 + _goto_level = _out + next + end + + else + emit(:tBDOT2) + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + + end + end + end + when 366 then +# line 2044 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = tm - 1; begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 364 then +# line 2047 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tNL, nil, @newline_s, @newline_s + 1) + p = p - 1; @cs = 710; begin + p += 1 + _goto_level = _out + next + end + end + end + when 75 then +# line 2008 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin + if @version < 27 + # Ruby before 2.7 doesn't support comments before leading dot. + # If a line after "a" starts with a comment then "a" is a self-contained statement. + # So in that case we emit a special tNL token and start reading the + # next line as a separate statement. + # + # Note: block comments before leading dot are not supported on any version of Ruby. + emit(:tNL, nil, @newline_s, @newline_s + 1) + p = p - 1; @cs = 710; begin + p += 1 + _goto_level = _out + next + end + + end + end + end + when 72 then +# line 2047 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin emit(:tNL, nil, @newline_s, @newline_s + 1) + p = p - 1; @cs = 710; begin + p += 1 + _goto_level = _out + next + end + end + end + when 76 then +# line 1 "NONE" + begin + case @act + when 140 then + begin begin p = (( @te))-1; end + + if @version < 27 + # Ruby before 2.7 doesn't support comments before leading dot. + # If a line after "a" starts with a comment then "a" is a self-contained statement. + # So in that case we emit a special tNL token and start reading the + # next line as a separate statement. + # + # Note: block comments before leading dot are not supported on any version of Ruby. + emit(:tNL, nil, @newline_s, @newline_s + 1) + p = p - 1; @cs = 710; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 144 then + begin begin p = (( @te))-1; end + emit(:tNL, nil, @newline_s, @newline_s + 1) + p = p - 1; @cs = 710; begin + p += 1 + _goto_level = _out + next + end + end +end + end + when 371 then +# line 2057 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit_comment(@eq_begin_s, @te) + begin + @cs = (@cs_before_block_comment) + _goto_level = _again + next + end + + end + end + when 370 then +# line 2065 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + diagnostic :fatal, :embedded_document, nil, + range(@eq_begin_s, @eq_begin_s + '=begin'.length) + end + end + when 381 then +# line 2075 "lib/parser/lexer.rl" + begin + @te = p+1 + begin @eq_begin_s = @ts + begin + @cs = 704 + _goto_level = _again + next + end + end + end + when 82 then +# line 2079 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = pe - 3 end + end + when 373 then +# line 2082 "lib/parser/lexer.rl" + begin + @te = p+1 + begin cmd_state = true; p = p - 1; begin + @cs = 508 + _goto_level = _again + next + end + end + end + when 374 then +# line 575 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Sit at EOF indefinitely. #advance would return $eof each time. + # This allows to feed the lexer more data if needed; this is only used + # in tests. + # + # Note that this action is not embedded into e_eof like e_nl and e_bs + # below. This is due to the fact that scanner state at EOF is observed + # by tests, and encapsulating it in a rule would break the introspection. + p = p - 1; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 375 then +# line 2072 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 380 then +# line 2075 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin @eq_begin_s = @ts + begin + @cs = 704 + _goto_level = _again + next + end + end + end + when 379 then +# line 2082 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin cmd_state = true; p = p - 1; begin + @cs = 508 + _goto_level = _again + next + end + end + end + when 81 then +# line 2082 "lib/parser/lexer.rl" + begin + begin p = (( @te))-1; end + begin cmd_state = true; p = p - 1; begin + @cs = 508 + _goto_level = _again + next + end + end + end + when 86 then +# line 2089 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + p, next_state = @strings.advance(p) + + p = p - 1; # Ragel will do `p += 1` to consume input, prevent it + @cs = (next_state); + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 52 then +# line 548 "lib/parser/lexer.rl" + begin + + # Record position of a newline for precise location reporting on tNL + # tokens. + # + # This action is embedded directly into c_nl, as it is idempotent and + # there are no cases when we need to skip it. + @newline_s = p + end +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end + when 154 then +# line 548 "lib/parser/lexer.rl" + begin + + # Record position of a newline for precise location reporting on tNL + # tokens. + # + # This action is embedded directly into c_nl, as it is idempotent and + # there are no cases when we need to skip it. + @newline_s = p + end +# line 1056 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Unlike expr_beg as invoked in the next rule, do not warn + p = @ts - 1 + begin + @cs = 516 + _goto_level = _again + next + end + + end + end + when 145 then +# line 548 "lib/parser/lexer.rl" + begin + + # Record position of a newline for precise location reporting on tNL + # tokens. + # + # This action is embedded directly into c_nl, as it is idempotent and + # there are no cases when we need to skip it. + @newline_s = p + end +# line 1112 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = tm - 1; begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 137 then +# line 548 "lib/parser/lexer.rl" + begin + + # Record position of a newline for precise location reporting on tNL + # tokens. + # + # This action is embedded directly into c_nl, as it is idempotent and + # there are no cases when we need to skip it. + @newline_s = p + end +# line 1123 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + p = @ts - 1 + begin + @cs = 516 + _goto_level = _again + next + end + + end + end + when 213 then +# line 548 "lib/parser/lexer.rl" + begin + + # Record position of a newline for precise location reporting on tNL + # tokens. + # + # This action is embedded directly into c_nl, as it is idempotent and + # there are no cases when we need to skip it. + @newline_s = p + end +# line 1551 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + # Here we scan and conditionally emit "\n": + # + if it's there + # + and emitted we do nothing + # + and not emitted we return `p` to "\n" to process it on the next scan + # + if it's not there we do nothing + followed_by_nl = @te - 1 == @newline_s + nl_emitted = false + dots_te = followed_by_nl ? @te - 1 : @te + + if @version >= 30 + if @lambda_stack.any? && @lambda_stack.last + 1 == @paren_nest + # To reject `->(...)` like `->...` + emit(:tDOT3, '...'.freeze, @ts, dots_te) + else + emit(:tBDOT3, '...'.freeze, @ts, dots_te) + + if @version >= 31 && followed_by_nl && @context.in_argdef + emit(:tNL, @te - 1, @te) + nl_emitted = true + end + end + elsif @version >= 27 + emit(:tBDOT3, '...'.freeze, @ts, dots_te) + else + emit(:tDOT3, '...'.freeze, @ts, dots_te) + end + + if followed_by_nl && !nl_emitted + # return "\n" to process it on the next scan + p = p - 1; + end + + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 201 then +# line 548 "lib/parser/lexer.rl" + begin + + # Record position of a newline for precise location reporting on tNL + # tokens. + # + # This action is embedded directly into c_nl, as it is idempotent and + # there are no cases when we need to skip it. + @newline_s = p + end +# line 1625 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + p = @ts - 1 + @cs_before_block_comment = @cs + begin + @cs = 710 + _goto_level = _again + next + end + + end + end + when 295 then +# line 548 "lib/parser/lexer.rl" + begin + + # Record position of a newline for precise location reporting on tNL + # tokens. + # + # This action is embedded directly into c_nl, as it is idempotent and + # there are no cases when we need to skip it. + @newline_s = p + end +# line 1958 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + if @paren_nest == 0 + diagnostic :warning, :triple_dot_at_eol, nil, range(@ts, @te - 1) + end + + emit(:tDOT3, '...'.freeze, @ts, @te - 1) + p = p - 1; + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 372 then +# line 548 "lib/parser/lexer.rl" + begin + + # Record position of a newline for precise location reporting on tNL + # tokens. + # + # This action is embedded directly into c_nl, as it is idempotent and + # there are no cases when we need to skip it. + @newline_s = p + end +# line 2057 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + emit_comment(@eq_begin_s, @te) + begin + @cs = (@cs_before_block_comment) + _goto_level = _again + next + end + + end + end + when 369 then +# line 548 "lib/parser/lexer.rl" + begin + + # Record position of a newline for precise location reporting on tNL + # tokens. + # + # This action is embedded directly into c_nl, as it is idempotent and + # there are no cases when we need to skip it. + @newline_s = p + end +# line 2062 "lib/parser/lexer.rl" + begin + @te = p+1 + end + when 382 then +# line 548 "lib/parser/lexer.rl" + begin + + # Record position of a newline for precise location reporting on tNL + # tokens. + # + # This action is embedded directly into c_nl, as it is idempotent and + # there are no cases when we need to skip it. + @newline_s = p + end +# line 2075 "lib/parser/lexer.rl" + begin + @te = p+1 + begin @eq_begin_s = @ts + begin + @cs = 704 + _goto_level = _again + next + end + end + end + when 83 then +# line 548 "lib/parser/lexer.rl" + begin + + # Record position of a newline for precise location reporting on tNL + # tokens. + # + # This action is embedded directly into c_nl, as it is idempotent and + # there are no cases when we need to skip it. + @newline_s = p + end +# line 2079 "lib/parser/lexer.rl" + begin + @te = p+1 + begin p = pe - 3 end + end + when 317 then +# line 683 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_rational end +# line 1797 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + digits = numeric_literal_int + + if version?(18, 19, 20) + emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits.to_i(@num_base), p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 315 then +# line 684 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_imaginary end +# line 1797 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + digits = numeric_literal_int + + if version?(18, 19, 20) + emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits.to_i(@num_base), p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 320 then +# line 685 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_imaginary_rational end +# line 1797 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + digits = numeric_literal_int + + if version?(18, 19, 20) + emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits.to_i(@num_base), p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 318 then +# line 686 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_integer_re end +# line 1797 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + digits = numeric_literal_int + + if version?(18, 19, 20) + emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits.to_i(@num_base), p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 316 then +# line 687 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_integer_if end +# line 1797 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + digits = numeric_literal_int + + if version?(18, 19, 20) + emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits.to_i(@num_base), p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 319 then +# line 688 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_integer_rescue end +# line 1797 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + digits = numeric_literal_int + + if version?(18, 19, 20) + emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits.to_i(@num_base), p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 308 then +# line 692 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_imaginary_float end +# line 1842 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + digits = tok(@ts, @num_suffix_s) + + if version?(18, 19, 20) + emit(:tFLOAT, Float(digits), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits, p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 309 then +# line 693 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_float_if end +# line 1842 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + digits = tok(@ts, @num_suffix_s) + + if version?(18, 19, 20) + emit(:tFLOAT, Float(digits), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits, p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 310 then +# line 697 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_rational end +# line 1842 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + digits = tok(@ts, @num_suffix_s) + + if version?(18, 19, 20) + emit(:tFLOAT, Float(digits), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits, p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 312 then +# line 698 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_imaginary_rational end +# line 1842 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + digits = tok(@ts, @num_suffix_s) + + if version?(18, 19, 20) + emit(:tFLOAT, Float(digits), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits, p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 311 then +# line 699 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_float_rescue end +# line 1842 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + digits = tok(@ts, @num_suffix_s) + + if version?(18, 19, 20) + emit(:tFLOAT, Float(digits), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits, p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 147 then +# line 705 "lib/parser/lexer.rl" + begin + + e_lbrace + end +# line 1037 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + if @lambda_stack.last == @paren_nest + @lambda_stack.pop + emit(:tLAMBEG, '{'.freeze, @te - 1, @te) + else + emit(:tLCURLY, '{'.freeze, @te - 1, @te) + end + @command_start = true + @paren_nest += 1 + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 169 then +# line 705 "lib/parser/lexer.rl" + begin + + e_lbrace + end +# line 1196 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + if @lambda_stack.last == @paren_nest + @lambda_stack.pop + emit(:tLAMBEG, '{'.freeze) + else + emit(:tLBRACE_ARG, '{'.freeze) + end + @paren_nest += 1 + @command_start = true + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 245 then +# line 705 "lib/parser/lexer.rl" + begin + + e_lbrace + end +# line 1468 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + if @lambda_stack.last == @paren_nest + @lambda_stack.pop + @command_start = true + emit(:tLAMBEG, '{'.freeze) + else + emit(:tLBRACE, '{'.freeze) + end + @paren_nest += 1 + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 360 then +# line 705 "lib/parser/lexer.rl" + begin + + e_lbrace + end +# line 1706 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + if @lambda_stack.last == @paren_nest + @lambda_stack.pop + + if tok == '{'.freeze + emit(:tLAMBEG, '{'.freeze) + else # 'do' + emit(:kDO_LAMBDA, 'do'.freeze) + end + else + if tok == '{'.freeze + emit(:tLCURLY, '{'.freeze) + else # 'do' + emit_do + end + end + if tok == '{'.freeze + @paren_nest += 1 + end + @command_start = true + + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 361 then +# line 709 "lib/parser/lexer.rl" + begin + + if @strings.close_interp_on_current_literal(p) + p = p - 1; + @cs = 128; + begin + p += 1 + _goto_level = _out + next + end + + end + + @paren_nest -= 1 + end +# line 1929 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit_rbrace_rparen_rbrack + + if tok == '}'.freeze || tok == ']'.freeze + if @version >= 25 + @cs = 516; + else + @cs = 313; + end + else # ) + # fnext expr_endfn; ? + end + + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 43 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 548 "lib/parser/lexer.rl" + begin + + # Record position of a newline for precise location reporting on tNL + # tokens. + # + # This action is embedded directly into c_nl, as it is idempotent and + # there are no cases when we need to skip it. + @newline_s = p + end + when 16 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 1070 "lib/parser/lexer.rl" + begin + tm = p end + when 18 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 1083 "lib/parser/lexer.rl" + begin + tm = p end + when 20 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 1111 "lib/parser/lexer.rl" + begin + tm = p end + when 98 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 931 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 117 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 961 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 125 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 993 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 19 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 1123 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + p = @ts - 1 + begin + @cs = 516 + _goto_level = _again + next + end + + end + end + when 156 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 1128 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 148 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 1134 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 167 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 1212 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 179 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 1233 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 175 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 1236 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = p - 1; begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 44 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 1254 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + emit(:tUNARY_NUM, tok(@ts, @ts + 1), @ts, @ts + 1) + p = p - 1; @cs = 516; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 35 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 1606 "lib/parser/lexer.rl" + begin + @te = p+1 + begin + emit(:tIDENTIFIER, ident_tok, ident_ts, ident_te) + p = ident_te - 1 + + if !@static_env.nil? && @static_env.declared?(ident_tok) && @version < 25 + @cs = 247; + else + @cs = 307; + end + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 198 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 1622 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 254 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 1649 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 250 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 1652 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + if @context.in_kwarg + p = p - 1; begin + @cs = 516 + _goto_level = _again + next + end + + else + begin + @cs = 710 + _goto_level = _again + next + end + + end + end + end + when 263 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 1681 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 260 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 1684 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin begin + @cs = 710 + _goto_level = _again + next + end + end + end + when 347 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 1976 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 279 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 1979 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin begin + @cs = 696 + _goto_level = _again + next + end + end + end + when 376 then +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 2072 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 46 then +# line 742 "lib/parser/lexer.rl" + begin + @sharp_s = p - 1 end +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end + when 50 then +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 548 "lib/parser/lexer.rl" + begin + + # Record position of a newline for precise location reporting on tNL + # tokens. + # + # This action is embedded directly into c_nl, as it is idempotent and + # there are no cases when we need to skip it. + @newline_s = p + end + when 101 then +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 931 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 116 then +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 961 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 128 then +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 993 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 150 then +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 1131 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 165 then +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 1212 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 177 then +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 1233 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 204 then +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 1622 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 252 then +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 1649 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 262 then +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 1681 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 283 then +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 1976 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 378 then +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 2072 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 122 then +# line 786 "lib/parser/lexer.rl" + begin + tm = p end +# line 983 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tFID, tok(@ts, tm), @ts, tm) + @cs = (arg_or_cmdarg(cmd_state)); p = tm - 1; begin + p += 1 + _goto_level = _out + next + end + end + end + when 218 then +# line 786 "lib/parser/lexer.rl" + begin + tm = p end +# line 1390 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm) + p = tm - 1 + @cs = 516; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 189 then +# line 786 "lib/parser/lexer.rl" + begin + tm = p end +# line 1595 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = @ts - 1 + begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 276 then +# line 786 "lib/parser/lexer.rl" + begin + tm = p end +# line 1 "NONE" + begin + case @act + when 104 then + begin begin p = (( @te))-1; end + + if @lambda_stack.last == @paren_nest + @lambda_stack.pop + + if tok == '{'.freeze + emit(:tLAMBEG, '{'.freeze) + else # 'do' + emit(:kDO_LAMBDA, 'do'.freeze) + end + else + if tok == '{'.freeze + emit(:tLCURLY, '{'.freeze) + else # 'do' + emit_do + end + end + if tok == '{'.freeze + @paren_nest += 1 + end + @command_start = true + + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + + end + when 105 then + begin begin p = (( @te))-1; end + emit_table(KEYWORDS) + @cs = 134; begin + p += 1 + _goto_level = _out + next + end + end + when 106 then + begin begin p = (( @te))-1; end + emit_singleton_class + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + end + when 107 then + begin begin p = (( @te))-1; end + emit_table(KEYWORDS) + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + end + when 108 then + begin begin p = (( @te))-1; end + emit_table(KEYWORDS) + @command_start = true + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + end + when 109 then + begin begin p = (( @te))-1; end + emit_table(KEYWORDS) + @cs = 321; begin + p += 1 + _goto_level = _out + next + end + end + when 110 then + begin begin p = (( @te))-1; end + + emit_table(KEYWORDS) + + if version?(18) && tok == 'not'.freeze + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + + else + @cs = 276; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 111 then + begin begin p = (( @te))-1; end + + if version?(18) + emit(:tIDENTIFIER) + + unless !@static_env.nil? && @static_env.declared?(tok) + @cs = (arg_or_cmdarg(cmd_state)); + end + else + emit(:k__ENCODING__, '__ENCODING__'.freeze) + end + begin + p += 1 + _goto_level = _out + next + end + + end + when 112 then + begin begin p = (( @te))-1; end + emit_table(KEYWORDS) + begin + p += 1 + _goto_level = _out + next + end + end + when 113 then + begin begin p = (( @te))-1; end + + digits = numeric_literal_int + + if version?(18, 19, 20) + emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits.to_i(@num_base), p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + when 115 then + begin begin p = (( @te))-1; end + + if version?(18, 19, 20) + diagnostic :error, + :trailing_in_number, { :character => tok(@te - 1, @te) }, + range(@te - 1, @te) + else + emit(:tINTEGER, tok(@ts, @te - 1).to_i, @ts, @te - 1) + p = p - 1; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 116 then + begin begin p = (( @te))-1; end + + if version?(18, 19, 20) + diagnostic :error, + :trailing_in_number, { :character => tok(@te - 1, @te) }, + range(@te - 1, @te) + else + emit(:tFLOAT, tok(@ts, @te - 1).to_f, @ts, @te - 1) + p = p - 1; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 117 then + begin begin p = (( @te))-1; end + + digits = tok(@ts, @num_suffix_s) + + if version?(18, 19, 20) + emit(:tFLOAT, Float(digits), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits, p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + when 119 then + begin begin p = (( @te))-1; end + emit(:tCONSTANT) + @cs = (arg_or_cmdarg(cmd_state)); begin + p += 1 + _goto_level = _out + next + end + end + when 123 then + begin begin p = (( @te))-1; end + + emit(:tIDENTIFIER) + + if !@static_env.nil? && @static_env.declared?(tok) + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + + elsif @version >= 32 && tok =~ /\A_[1-9]\z/ + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + + else + @cs = (arg_or_cmdarg(cmd_state)); begin + p += 1 + _goto_level = _out + next + end + + end + end + when 124 then + begin begin p = (( @te))-1; end + + if tm == @te + # Suffix was consumed, e.g. foo! + emit(:tFID) + else + # Suffix was not consumed, e.g. foo!= + emit(:tIDENTIFIER, tok(@ts, tm), @ts, tm) + p = tm - 1 + end + @cs = 276; begin + p += 1 + _goto_level = _out + next + end + + end + when 126 then + begin begin p = (( @te))-1; end + + emit_table(PUNCTUATION); + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + + end + when 127 then + begin begin p = (( @te))-1; end + emit_table(PUNCTUATION) + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + end +end + end + when 123 then +# line 787 "lib/parser/lexer.rl" + begin + tm = p - 2 end +# line 983 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tFID, tok(@ts, tm), @ts, tm) + @cs = (arg_or_cmdarg(cmd_state)); p = tm - 1; begin + p += 1 + _goto_level = _out + next + end + end + end + when 219 then +# line 787 "lib/parser/lexer.rl" + begin + tm = p - 2 end +# line 1390 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm) + p = tm - 1 + @cs = 516; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 191 then +# line 787 "lib/parser/lexer.rl" + begin + tm = p - 2 end +# line 1595 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = @ts - 1 + begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 277 then +# line 787 "lib/parser/lexer.rl" + begin + tm = p - 2 end +# line 1893 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + if tm == @te + # Suffix was consumed, e.g. foo! + emit(:tFID) + else + # Suffix was not consumed, e.g. foo!= + emit(:tIDENTIFIER, tok(@ts, tm), @ts, tm) + p = tm - 1 + end + @cs = 276; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 220 then +# line 792 "lib/parser/lexer.rl" + begin + tm = p end +# line 1390 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm) + p = tm - 1 + @cs = 516; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 192 then +# line 792 "lib/parser/lexer.rl" + begin + tm = p end +# line 1595 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = @ts - 1 + begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 221 then +# line 793 "lib/parser/lexer.rl" + begin + tm = p - 2 end +# line 1390 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm) + p = tm - 1 + @cs = 516; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 193 then +# line 793 "lib/parser/lexer.rl" + begin + tm = p - 2 end +# line 1595 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = @ts - 1 + begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 225 then +# line 794 "lib/parser/lexer.rl" + begin + tm = p - 2 end +# line 1390 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm) + p = tm - 1 + @cs = 516; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 196 then +# line 794 "lib/parser/lexer.rl" + begin + tm = p - 2 end +# line 1595 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = @ts - 1 + begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 224 then +# line 795 "lib/parser/lexer.rl" + begin + tm = p - 2 end +# line 1390 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm) + p = tm - 1 + @cs = 516; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 195 then +# line 795 "lib/parser/lexer.rl" + begin + tm = p - 2 end +# line 1 "NONE" + begin + case @act + when 60 then + begin begin p = (( @te))-1; end + + emit(:tUNARY_NUM, tok(@ts, @ts + 1), @ts, @ts + 1) + p = p - 1; @cs = 516; begin + p += 1 + _goto_level = _out + next + end + + end + when 67 then + begin begin p = (( @te))-1; end + + diagnostic :error, :unterminated_heredoc_id, nil, range(@ts, @ts + 1) + end + when 76 then + begin begin p = (( @te))-1; end + + if @version >= 27 + emit(:tPIPE, tok(@ts, @ts + 1), @ts, @ts + 1) + p = p - 1; + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + + else + p -= 2 + begin + @cs = 516 + _goto_level = _again + next + end + + end + end + when 80 then + begin begin p = (( @te))-1; end + emit_table(PUNCTUATION_BEGIN) + begin + p += 1 + _goto_level = _out + next + end + end + when 81 then + begin begin p = (( @te))-1; end + emit(:kRESCUE, 'rescue'.freeze, @ts, tm) + p = tm - 1 + @cs = 321; begin + p += 1 + _goto_level = _out + next + end + end + when 82 then + begin begin p = (( @te))-1; end + emit_table(KEYWORDS_BEGIN) + @command_start = true + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + end + when 86 then + begin begin p = (( @te))-1; end + p = @ts - 1 + begin + @cs = 516 + _goto_level = _again + next + end + end + when 87 then + begin begin p = (( @te))-1; end + + emit(:tIDENTIFIER) + + if !@static_env.nil? && @static_env.declared?(tok) + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + + elsif @version >= 32 && tok =~ /\A_[1-9]\z/ + @cs = 247; begin + p += 1 + _goto_level = _out + next + end + + else + @cs = (arg_or_cmdarg(cmd_state)); begin + p += 1 + _goto_level = _out + next + end + + end + end + when 91 then + begin begin p = (( @te))-1; end + p = @ts - 1; begin + @cs = 516 + _goto_level = _again + next + end + end +end + end + when 222 then +# line 796 "lib/parser/lexer.rl" + begin + tm = p - 3 end +# line 1390 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm) + p = tm - 1 + @cs = 516; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 194 then +# line 796 "lib/parser/lexer.rl" + begin + tm = p - 3 end +# line 1595 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin p = @ts - 1 + begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 223 then +# line 801 "lib/parser/lexer.rl" + begin + tm = p - 2 end +# line 1390 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit(:tSYMBOL, tok(@ts + 1, tm), @ts, tm) + p = tm - 1 + @cs = 516; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 342 then +# line 806 "lib/parser/lexer.rl" + begin + tm = p - 2 end +# line 1875 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tCONSTANT, tok(@ts, tm), @ts, tm) + p = tm - 1; begin + p += 1 + _goto_level = _out + next + end + end + end + when 146 then +# line 812 "lib/parser/lexer.rl" + begin + + @cond.push(false); @cmdarg.push(false) + + @paren_nest += 1 + end +# line 1031 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tLBRACK, '['.freeze, @te - 1, @te) + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + end + end + when 238 then +# line 812 "lib/parser/lexer.rl" + begin + + @cond.push(false); @cmdarg.push(false) + + @paren_nest += 1 + end +# line 1482 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tLBRACK, '['.freeze) + begin + p += 1 + _goto_level = _out + next + end + end + end + when 345 then +# line 812 "lib/parser/lexer.rl" + begin + + @cond.push(false); @cmdarg.push(false) + + @paren_nest += 1 + end +# line 1954 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tLBRACK2, '['.freeze) + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + end + end + when 348 then +# line 818 "lib/parser/lexer.rl" + begin + + @paren_nest -= 1 + end +# line 1929 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit_rbrace_rparen_rbrack + + if tok == '}'.freeze || tok == ']'.freeze + if @version >= 25 + @cs = 516; + else + @cs = 313; + end + else # ) + # fnext expr_endfn; ? + end + + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 138 then +# line 825 "lib/parser/lexer.rl" + begin + + @cond.push(false); @cmdarg.push(false) + + @paren_nest += 1 + + if version?(18) + @command_start = true + end + end +# line 1012 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + if version?(18) + emit(:tLPAREN2, '('.freeze, @te - 1, @te) + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + + else + emit(:tLPAREN_ARG, '('.freeze, @te - 1, @te) + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + + end + end + end + when 151 then +# line 825 "lib/parser/lexer.rl" + begin + + @cond.push(false); @cmdarg.push(false) + + @paren_nest += 1 + + if version?(18) + @command_start = true + end + end +# line 1025 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tLPAREN2, '('.freeze) + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + end + end + when 159 then +# line 825 "lib/parser/lexer.rl" + begin + + @cond.push(false); @cmdarg.push(false) + + @paren_nest += 1 + + if version?(18) + @command_start = true + end + end +# line 1150 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit(:tLPAREN_ARG, '('.freeze, @te - 1, @te) + if version?(18) + @cs = 508; begin + p += 1 + _goto_level = _out + next + end + + else + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + + end + end + end + when 208 then +# line 825 "lib/parser/lexer.rl" + begin + + @cond.push(false); @cmdarg.push(false) + + @paren_nest += 1 + + if version?(18) + @command_start = true + end + end +# line 1487 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:tLPAREN, '('.freeze) + begin + p += 1 + _goto_level = _out + next + end + end + end + when 289 then +# line 825 "lib/parser/lexer.rl" + begin + + @cond.push(false); @cmdarg.push(false) + + @paren_nest += 1 + + if version?(18) + @command_start = true + end + end +# line 1925 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit_table(PUNCTUATION) + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + end + end + when 290 then +# line 835 "lib/parser/lexer.rl" + begin + + @paren_nest -= 1 + end +# line 1929 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit_rbrace_rparen_rbrack + + if tok == '}'.freeze || tok == ']'.freeze + if @version >= 25 + @cs = 516; + else + @cs = 313; + end + else # ) + # fnext expr_endfn; ? + end + + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 57 then +# line 1308 "lib/parser/lexer.rl" + begin + heredoc_e = p end +# line 548 "lib/parser/lexer.rl" + begin + + # Record position of a newline for precise location reporting on tNL + # tokens. + # + # This action is embedded directly into c_nl, as it is idempotent and + # there are no cases when we need to skip it. + @newline_s = p + end + when 233 then +# line 1309 "lib/parser/lexer.rl" + begin + new_herebody_s = p end +# line 1310 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + tok(@ts, heredoc_e) =~ /^<<(-?)(~?)(["'`]?)(.*)\3$/m + + indent = !$1.empty? || !$2.empty? + dedent_body = !$2.empty? + type = $3.empty? ? '<<"'.freeze : ('<<'.freeze + $3) + delimiter = $4 + + if @version >= 27 + if delimiter.count("\n") > 0 || delimiter.count("\r") > 0 + diagnostic :error, :unterminated_heredoc_id, nil, range(@ts, @ts + 1) + end + elsif @version >= 24 + if delimiter.count("\n") > 0 + if delimiter.end_with?("\n") + diagnostic :warning, :heredoc_id_ends_with_nl, nil, range(@ts, @ts + 1) + delimiter = delimiter.rstrip + else + diagnostic :fatal, :heredoc_id_has_newline, nil, range(@ts, @ts + 1) + end + end + end + + if dedent_body && version?(18, 19, 20, 21, 22) + emit(:tLSHFT, '<<'.freeze, @ts, @ts + 2) + p = @ts + 1 + @cs = 345; begin + p += 1 + _goto_level = _out + next + end + + else + @strings.push_literal(type, delimiter, @ts, heredoc_e, indent, dedent_body); + @strings.herebody_s ||= new_herebody_s + + p = @strings.herebody_s - 1 + @cs = 128; + end + end + end + when 228 then +# line 1409 "lib/parser/lexer.rl" + begin + tm = p - 1; diag_msg = :ivar_name end +# line 1412 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit_colon_with_digits(p, tm, diag_msg) + + @cs = 516; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 231 then +# line 1410 "lib/parser/lexer.rl" + begin + tm = p - 2; diag_msg = :cvar_name end +# line 1412 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + emit_colon_with_digits(p, tm, diag_msg) + + @cs = 516; begin + p += 1 + _goto_level = _out + next + end + + end + end + when 241 then +# line 1497 "lib/parser/lexer.rl" + begin + tm = p end +# line 1498 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin emit(:kRESCUE, 'rescue'.freeze, @ts, tm) + p = tm - 1 + @cs = 321; begin + p += 1 + _goto_level = _out + next + end + end + end + when 332 then +# line 1790 "lib/parser/lexer.rl" + begin + @num_base = 16; @num_digits_s = p end +# line 1796 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end + when 326 then +# line 1791 "lib/parser/lexer.rl" + begin + @num_base = 10; @num_digits_s = p end +# line 1796 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end + when 329 then +# line 1792 "lib/parser/lexer.rl" + begin + @num_base = 8; @num_digits_s = p end +# line 1796 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end + when 323 then +# line 1793 "lib/parser/lexer.rl" + begin + @num_base = 2; @num_digits_s = p end +# line 1796 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end + when 338 then +# line 1794 "lib/parser/lexer.rl" + begin + @num_base = 10; @num_digits_s = @ts end +# line 1796 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end + when 301 then +# line 1795 "lib/parser/lexer.rl" + begin + @num_base = 8; @num_digits_s = @ts end +# line 1796 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end + when 339 then +# line 1796 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end +# line 682 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_integer end + when 184 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 548 "lib/parser/lexer.rl" + begin + + # Record position of a newline for precise location reporting on tNL + # tokens. + # + # This action is embedded directly into c_nl, as it is idempotent and + # there are no cases when we need to skip it. + @newline_s = p + end + when 305 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1840 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end + when 107 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 889 "lib/parser/lexer.rl" + begin + @act = 4; end + when 94 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 893 "lib/parser/lexer.rl" + begin + @act = 5; end + when 90 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 897 "lib/parser/lexer.rl" + begin + @act = 6; end + when 12 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1074 "lib/parser/lexer.rl" + begin + @act = 33; end + when 140 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1084 "lib/parser/lexer.rl" + begin + @act = 34; end + when 13 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1123 "lib/parser/lexer.rl" + begin + @act = 39; end + when 133 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1128 "lib/parser/lexer.rl" + begin + @act = 40; end + when 160 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1160 "lib/parser/lexer.rl" + begin + @act = 46; end + when 31 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1173 "lib/parser/lexer.rl" + begin + @act = 47; end + when 181 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1227 "lib/parser/lexer.rl" + begin + @act = 54; end + when 170 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1231 "lib/parser/lexer.rl" + begin + @act = 55; end + when 55 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1357 "lib/parser/lexer.rl" + begin + @act = 67; end + when 246 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1451 "lib/parser/lexer.rl" + begin + @act = 76; end + when 185 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1492 "lib/parser/lexer.rl" + begin + @act = 80; end + when 240 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1498 "lib/parser/lexer.rl" + begin + @act = 81; end + when 239 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1504 "lib/parser/lexer.rl" + begin + @act = 82; end + when 59 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1595 "lib/parser/lexer.rl" + begin + @act = 86; end + when 182 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 840 "lib/parser/lexer.rl" + begin + @act = 87; end + when 186 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1641 "lib/parser/lexer.rl" + begin + @act = 91; end + when 356 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1706 "lib/parser/lexer.rl" + begin + @act = 104; end + when 351 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1735 "lib/parser/lexer.rl" + begin + @act = 105; end + when 359 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1744 "lib/parser/lexer.rl" + begin + @act = 107; end + when 352 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1749 "lib/parser/lexer.rl" + begin + @act = 108; end + when 353 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1754 "lib/parser/lexer.rl" + begin + @act = 109; end + when 358 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1758 "lib/parser/lexer.rl" + begin + @act = 110; end + when 350 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1769 "lib/parser/lexer.rl" + begin + @act = 111; end + when 344 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1783 "lib/parser/lexer.rl" + begin + @act = 112; end + when 270 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1797 "lib/parser/lexer.rl" + begin + @act = 113; end + when 303 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1827 "lib/parser/lexer.rl" + begin + @act = 116; end + when 67 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1842 "lib/parser/lexer.rl" + begin + @act = 117; end + when 273 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1871 "lib/parser/lexer.rl" + begin + @act = 119; end + when 264 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 840 "lib/parser/lexer.rl" + begin + @act = 123; end + when 275 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1893 "lib/parser/lexer.rl" + begin + @act = 124; end + when 268 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1919 "lib/parser/lexer.rl" + begin + @act = 126; end + when 274 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1925 "lib/parser/lexer.rl" + begin + @act = 127; end + when 73 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 2008 "lib/parser/lexer.rl" + begin + @act = 140; end + when 363 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 2047 "lib/parser/lexer.rl" + begin + @act = 144; end + when 47 then +# line 742 "lib/parser/lexer.rl" + begin + @sharp_s = p - 1 end +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 548 "lib/parser/lexer.rl" + begin + + # Record position of a newline for precise location reporting on tNL + # tokens. + # + # This action is embedded directly into c_nl, as it is idempotent and + # there are no cases when we need to skip it. + @newline_s = p + end + when 100 then +# line 742 "lib/parser/lexer.rl" + begin + @sharp_s = p - 1 end +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 931 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 115 then +# line 742 "lib/parser/lexer.rl" + begin + @sharp_s = p - 1 end +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 961 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 127 then +# line 742 "lib/parser/lexer.rl" + begin + @sharp_s = p - 1 end +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 993 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 149 then +# line 742 "lib/parser/lexer.rl" + begin + @sharp_s = p - 1 end +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 1131 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin begin + @cs = 516 + _goto_level = _again + next + end + end + end + when 164 then +# line 742 "lib/parser/lexer.rl" + begin + @sharp_s = p - 1 end +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 1212 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 176 then +# line 742 "lib/parser/lexer.rl" + begin + @sharp_s = p - 1 end +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 1233 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 203 then +# line 742 "lib/parser/lexer.rl" + begin + @sharp_s = p - 1 end +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 1622 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 251 then +# line 742 "lib/parser/lexer.rl" + begin + @sharp_s = p - 1 end +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 1649 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 261 then +# line 742 "lib/parser/lexer.rl" + begin + @sharp_s = p - 1 end +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 1681 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 282 then +# line 742 "lib/parser/lexer.rl" + begin + @sharp_s = p - 1 end +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 1976 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 377 then +# line 742 "lib/parser/lexer.rl" + begin + @sharp_s = p - 1 end +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 2072 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; end + when 334 then +# line 1794 "lib/parser/lexer.rl" + begin + @num_base = 10; @num_digits_s = @ts end +# line 1796 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end +# line 682 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_integer end + when 298 then +# line 1795 "lib/parser/lexer.rl" + begin + @num_base = 8; @num_digits_s = @ts end +# line 1796 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end +# line 682 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_integer end + when 313 then +# line 1796 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end +# line 682 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_integer end +# line 1797 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + digits = numeric_literal_int + + if version?(18, 19, 20) + emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits.to_i(@num_base), p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 306 then +# line 1839 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end +# line 691 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_float end +# line 1842 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + digits = tok(@ts, @num_suffix_s) + + if version?(18, 19, 20) + emit(:tFLOAT, Float(digits), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits, p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 302 then +# line 1840 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end +# line 691 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_float end +# line 1842 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + digits = tok(@ts, @num_suffix_s) + + if version?(18, 19, 20) + emit(:tFLOAT, Float(digits), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits, p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 155 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 548 "lib/parser/lexer.rl" + begin + + # Record position of a newline for precise location reporting on tNL + # tokens. + # + # This action is embedded directly into c_nl, as it is idempotent and + # there are no cases when we need to skip it. + @newline_s = p + end +# line 1128 "lib/parser/lexer.rl" + begin + @act = 40; end + when 21 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 1123 "lib/parser/lexer.rl" + begin + @act = 39; end + when 32 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 1173 "lib/parser/lexer.rl" + begin + @act = 47; end + when 79 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 2008 "lib/parser/lexer.rl" + begin + @act = 140; end + when 51 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 1254 "lib/parser/lexer.rl" + begin + @act = 60; end + when 70 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 1739 "lib/parser/lexer.rl" + begin + @act = 106; end + when 78 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 2008 "lib/parser/lexer.rl" + begin + @act = 140; end + when 23 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1083 "lib/parser/lexer.rl" + begin + tm = p end +# line 1084 "lib/parser/lexer.rl" + begin + @act = 34; end + when 243 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1497 "lib/parser/lexer.rl" + begin + tm = p end +# line 1595 "lib/parser/lexer.rl" + begin + @act = 86; end + when 242 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1497 "lib/parser/lexer.rl" + begin + tm = p end +# line 840 "lib/parser/lexer.rl" + begin + @act = 87; end + when 335 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1794 "lib/parser/lexer.rl" + begin + @num_base = 10; @num_digits_s = @ts end +# line 1797 "lib/parser/lexer.rl" + begin + @act = 113; end + when 330 then +# line 1790 "lib/parser/lexer.rl" + begin + @num_base = 16; @num_digits_s = p end +# line 1796 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end +# line 682 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_integer end +# line 1797 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + digits = numeric_literal_int + + if version?(18, 19, 20) + emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits.to_i(@num_base), p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 324 then +# line 1791 "lib/parser/lexer.rl" + begin + @num_base = 10; @num_digits_s = p end +# line 1796 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end +# line 682 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_integer end +# line 1797 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + digits = numeric_literal_int + + if version?(18, 19, 20) + emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits.to_i(@num_base), p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 327 then +# line 1792 "lib/parser/lexer.rl" + begin + @num_base = 8; @num_digits_s = p end +# line 1796 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end +# line 682 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_integer end +# line 1797 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + digits = numeric_literal_int + + if version?(18, 19, 20) + emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits.to_i(@num_base), p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 321 then +# line 1793 "lib/parser/lexer.rl" + begin + @num_base = 2; @num_digits_s = p end +# line 1796 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end +# line 682 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_integer end +# line 1797 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + digits = numeric_literal_int + + if version?(18, 19, 20) + emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits.to_i(@num_base), p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 333 then +# line 1794 "lib/parser/lexer.rl" + begin + @num_base = 10; @num_digits_s = @ts end +# line 1796 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end +# line 682 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_integer end +# line 1797 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + digits = numeric_literal_int + + if version?(18, 19, 20) + emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits.to_i(@num_base), p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 297 then +# line 1795 "lib/parser/lexer.rl" + begin + @num_base = 8; @num_digits_s = @ts end +# line 1796 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end +# line 682 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_integer end +# line 1797 "lib/parser/lexer.rl" + begin + @te = p +p = p - 1; begin + digits = numeric_literal_int + + if version?(18, 19, 20) + emit(:tINTEGER, digits.to_i(@num_base), @ts, @num_suffix_s) + p = @num_suffix_s - 1 + else + p = @num_xfrm.call(digits.to_i(@num_base), p) + end + begin + p += 1 + _goto_level = _out + next + end + + end + end + when 17 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 732 "lib/parser/lexer.rl" + begin + + p = on_newline(p) + end +# line 1083 "lib/parser/lexer.rl" + begin + tm = p end +# line 1084 "lib/parser/lexer.rl" + begin + @act = 34; end + when 48 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 742 "lib/parser/lexer.rl" + begin + @sharp_s = p - 1 end +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 1254 "lib/parser/lexer.rl" + begin + @act = 60; end + when 77 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 742 "lib/parser/lexer.rl" + begin + @sharp_s = p - 1 end +# line 745 "lib/parser/lexer.rl" + begin + emit_comment_from_range(p, pe) end +# line 2008 "lib/parser/lexer.rl" + begin + @act = 140; end + when 340 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1796 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end +# line 682 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_integer end +# line 1815 "lib/parser/lexer.rl" + begin + @act = 115; end + when 336 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1794 "lib/parser/lexer.rl" + begin + @num_base = 10; @num_digits_s = @ts end +# line 1796 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end +# line 682 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_integer end +# line 1815 "lib/parser/lexer.rl" + begin + @act = 115; end + when 300 then +# line 1 "NONE" + begin + @te = p+1 + end +# line 1795 "lib/parser/lexer.rl" + begin + @num_base = 8; @num_digits_s = @ts end +# line 1796 "lib/parser/lexer.rl" + begin + @num_suffix_s = p end +# line 682 "lib/parser/lexer.rl" + begin + @num_xfrm = @emit_integer end +# line 1815 "lib/parser/lexer.rl" + begin + @act = 115; end +# line 14595 "lib/parser/lexer-F1.rb" + end + end + end + if _goto_level <= _again + case _lex_to_state_actions[ @cs] + when 84 then +# line 1 "NONE" + begin + @ts = nil; end +# line 14605 "lib/parser/lexer-F1.rb" + end + + if @cs == 0 + _goto_level = _out + next + end + p += 1 + if p != pe + _goto_level = _resume + next + end + end + if _goto_level <= _test_eof + if p == eof + if _lex_eof_trans[ @cs] > 0 + _trans = _lex_eof_trans[ @cs] - 1; + _goto_level = _eof_trans + next; + end + end + + end + if _goto_level <= _out + break + end +end + end + +# line 290 "lib/parser/lexer.rl" + # % + + # Ragel creates a local variable called `testEof` but it doesn't use + # it in any assignment. This dead code is here to swallow the warning. + # It has no runtime cost because Ruby doesn't produce any instructions from it. + if false + testEof + end + + @p = p + + if @token_queue.any? + @token_queue.shift + elsif @cs == klass.lex_error + [ false, [ '$error'.freeze, range(p - 1, p) ] ] + else + eof = @source_pts.size + [ false, [ '$eof'.freeze, range(eof, eof) ] ] + end + end + + protected + + def version?(*versions) + versions.include?(@version) + end + + def stack_pop + @top -= 1 + @stack[@top] + end + + def tok(s = @ts, e = @te) + @source_buffer.slice(s, e - s) + end + + def range(s = @ts, e = @te) + Parser::Source::Range.new(@source_buffer, s, e) + end + + def emit(type, value = tok, s = @ts, e = @te) + token = [ type, [ value, range(s, e) ] ] + + @token_queue.push(token) + + @tokens.push(token) if @tokens + + token + end + + def emit_table(table, s = @ts, e = @te) + value = tok(s, e) + + emit(table[value], value, s, e) + end + + def emit_do(do_block=false) + if @cond.active? + emit(:kDO_COND, 'do'.freeze) + elsif @cmdarg.active? || do_block + emit(:kDO_BLOCK, 'do'.freeze) + else + emit(:kDO, 'do'.freeze) + end + end + + def arg_or_cmdarg(cmd_state) + if cmd_state + self.class.lex_en_expr_cmdarg + else + self.class.lex_en_expr_arg + end + end + + def emit_comment(s = @ts, e = @te) + if @comments + @comments.push(Parser::Source::Comment.new(range(s, e))) + end + + if @tokens + @tokens.push([ :tCOMMENT, [ tok(s, e), range(s, e) ] ]) + end + + nil + end + + def emit_comment_from_range(p, pe) + emit_comment(@sharp_s, p == pe ? p - 2 : p) + end + + def diagnostic(type, reason, arguments=nil, location=range, highlights=[]) + @diagnostics.process( + Parser::Diagnostic.new(type, reason, arguments, location, highlights)) + end + + + def e_lbrace + @cond.push(false); @cmdarg.push(false) + + current_literal = @strings.literal + if current_literal + current_literal.start_interp_brace + end + end + + def numeric_literal_int + digits = tok(@num_digits_s, @num_suffix_s) + + if digits.end_with? '_'.freeze + diagnostic :error, :trailing_in_number, { :character => '_'.freeze }, + range(@te - 1, @te) + elsif digits.empty? && @num_base == 8 && version?(18) + # 1.8 did not raise an error on 0o. + digits = '0'.freeze + elsif digits.empty? + diagnostic :error, :empty_numeric + elsif @num_base == 8 && (invalid_idx = digits.index(/[89]/)) + invalid_s = @num_digits_s + invalid_idx + diagnostic :error, :invalid_octal, nil, + range(invalid_s, invalid_s + 1) + end + digits + end + + def on_newline(p) + @strings.on_newline(p) + end + + def check_ambiguous_slash(tm) + if tok(tm, tm + 1) == '/'.freeze + # Ambiguous regexp literal. + if @version < 30 + diagnostic :warning, :ambiguous_literal, nil, range(tm, tm + 1) + else + diagnostic :warning, :ambiguous_regexp, nil, range(tm, tm + 1) + end + end + end + + def emit_global_var(ts = @ts, te = @te) + if tok(ts, te) =~ /^\$([1-9][0-9]*)$/ + emit(:tNTH_REF, tok(ts + 1, te).to_i, ts, te) + elsif tok =~ /^\$([&`'+])$/ + emit(:tBACK_REF, tok(ts, te), ts, te) + else + emit(:tGVAR, tok(ts, te), ts, te) + end + end + + def emit_class_var(ts = @ts, te = @te) + if tok(ts, te) =~ /^@@[0-9]/ + diagnostic :error, :cvar_name, { :name => tok(ts, te) } + end + + emit(:tCVAR, tok(ts, te), ts, te) + end + + def emit_instance_var(ts = @ts, te = @te) + if tok(ts, te) =~ /^@[0-9]/ + diagnostic :error, :ivar_name, { :name => tok(ts, te) } + end + + emit(:tIVAR, tok(ts, te), ts, te) + end + + def emit_rbrace_rparen_rbrack + emit_table(PUNCTUATION) + + if @version < 24 + @cond.lexpop + @cmdarg.lexpop + else + @cond.pop + @cmdarg.pop + end + end + + def emit_colon_with_digits(p, tm, diag_msg) + if @version >= 27 + diagnostic :error, diag_msg, { name: tok(tm, @te) }, range(tm, @te) + else + emit(:tCOLON, tok(@ts, @ts + 1), @ts, @ts + 1) + p = @ts + end + p + end + + def emit_singleton_class + emit(:kCLASS, 'class'.freeze, @ts, @ts + 5) + emit(:tLSHFT, '<<'.freeze, @te - 2, @te) + end + + # Mapping of strings to parser tokens. + + PUNCTUATION = { + '=' => :tEQL, '&' => :tAMPER2, '|' => :tPIPE, + '!' => :tBANG, '^' => :tCARET, '+' => :tPLUS, + '-' => :tMINUS, '*' => :tSTAR2, '/' => :tDIVIDE, + '%' => :tPERCENT, '~' => :tTILDE, ',' => :tCOMMA, + ';' => :tSEMI, '.' => :tDOT, '..' => :tDOT2, + '...' => :tDOT3, '[' => :tLBRACK2, ']' => :tRBRACK, + '(' => :tLPAREN2, ')' => :tRPAREN, '?' => :tEH, + ':' => :tCOLON, '&&' => :tANDOP, '||' => :tOROP, + '-@' => :tUMINUS, '+@' => :tUPLUS, '~@' => :tTILDE, + '**' => :tPOW, '->' => :tLAMBDA, '=~' => :tMATCH, + '!~' => :tNMATCH, '==' => :tEQ, '!=' => :tNEQ, + '>' => :tGT, '>>' => :tRSHFT, '>=' => :tGEQ, + '<' => :tLT, '<<' => :tLSHFT, '<=' => :tLEQ, + '=>' => :tASSOC, '::' => :tCOLON2, '===' => :tEQQ, + '<=>' => :tCMP, '[]' => :tAREF, '[]=' => :tASET, + '{' => :tLCURLY, '}' => :tRCURLY, '`' => :tBACK_REF2, + '!@' => :tBANG, '&.' => :tANDDOT, + } + + PUNCTUATION_BEGIN = { + '&' => :tAMPER, '*' => :tSTAR, '**' => :tDSTAR, + '+' => :tUPLUS, '-' => :tUMINUS, '::' => :tCOLON3, + '(' => :tLPAREN, '{' => :tLBRACE, '[' => :tLBRACK, + } + + KEYWORDS = { + 'if' => :kIF_MOD, 'unless' => :kUNLESS_MOD, + 'while' => :kWHILE_MOD, 'until' => :kUNTIL_MOD, + 'rescue' => :kRESCUE_MOD, 'defined?' => :kDEFINED, + 'BEGIN' => :klBEGIN, 'END' => :klEND, + } + + KEYWORDS_BEGIN = { + 'if' => :kIF, 'unless' => :kUNLESS, + 'while' => :kWHILE, 'until' => :kUNTIL, + 'rescue' => :kRESCUE, 'defined?' => :kDEFINED, + 'BEGIN' => :klBEGIN, 'END' => :klEND, + } + + ESCAPE_WHITESPACE = { + " " => '\s', "\r" => '\r', "\n" => '\n', "\t" => '\t', + "\v" => '\v', "\f" => '\f' + } + + %w(class module def undef begin end then elsif else ensure case when + for break next redo retry in do return yield super self nil true + false and or not alias __FILE__ __LINE__ __ENCODING__).each do |keyword| + KEYWORDS_BEGIN[keyword] = KEYWORDS[keyword] = :"k#{keyword.upcase}" + end + + +# line 2098 "lib/parser/lexer.rl" + + # % +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/lexer-strings.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/lexer-strings.rb new file mode 100644 index 00000000..02ac7631 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/lexer-strings.rb @@ -0,0 +1,5433 @@ +# -*- encoding:utf-8; warn-indent:false; frozen_string_literal: true -*- + +# line 1 "lib/parser/lexer-strings.rl" + +# line 3 "lib/parser/lexer-strings.rl" +class Parser::LexerStrings + + +# line 9 "lib/parser/lexer-strings.rb" +class << self + attr_accessor :_lex_actions + private :_lex_actions, :_lex_actions= +end +self._lex_actions = [ + 0, 1, 0, 1, 18, 1, 22, 1, + 23, 1, 24, 1, 25, 1, 26, 1, + 27, 1, 28, 1, 32, 1, 33, 1, + 34, 1, 35, 1, 36, 1, 37, 1, + 38, 1, 42, 1, 43, 1, 44, 1, + 46, 1, 47, 1, 48, 1, 49, 1, + 52, 1, 53, 1, 54, 1, 55, 1, + 56, 1, 57, 1, 60, 1, 61, 1, + 62, 1, 63, 1, 64, 1, 65, 1, + 66, 1, 69, 1, 70, 1, 71, 1, + 72, 1, 73, 1, 74, 1, 75, 1, + 76, 1, 77, 1, 79, 1, 80, 1, + 81, 2, 0, 27, 2, 0, 37, 2, + 0, 46, 2, 0, 52, 2, 0, 56, + 2, 0, 62, 2, 0, 65, 2, 0, + 72, 2, 0, 77, 2, 1, 31, 2, + 1, 41, 2, 1, 78, 2, 2, 31, + 2, 2, 41, 2, 2, 78, 2, 3, + 31, 2, 3, 41, 2, 3, 78, 2, + 8, 31, 2, 8, 41, 2, 8, 78, + 2, 10, 31, 2, 10, 41, 2, 10, + 78, 2, 11, 31, 2, 11, 41, 2, + 11, 78, 2, 12, 31, 2, 12, 41, + 2, 12, 78, 2, 13, 31, 2, 13, + 41, 2, 13, 78, 2, 14, 31, 2, + 14, 41, 2, 14, 78, 2, 15, 31, + 2, 15, 41, 2, 15, 78, 2, 16, + 31, 2, 16, 41, 2, 16, 78, 2, + 17, 31, 2, 17, 41, 2, 17, 78, + 2, 18, 45, 2, 18, 51, 2, 19, + 30, 2, 19, 40, 2, 19, 59, 2, + 19, 68, 2, 20, 29, 2, 20, 30, + 2, 20, 39, 2, 20, 40, 2, 20, + 58, 2, 20, 59, 2, 20, 67, 2, + 20, 68, 2, 21, 29, 2, 21, 30, + 2, 21, 39, 2, 21, 40, 2, 21, + 58, 2, 21, 59, 2, 21, 67, 2, + 21, 68, 2, 22, 78, 2, 25, 0, + 3, 0, 50, 18, 3, 2, 5, 31, + 3, 2, 5, 41, 3, 2, 5, 78, + 3, 2, 6, 31, 3, 2, 6, 41, + 3, 2, 6, 78, 3, 4, 5, 31, + 3, 4, 5, 41, 3, 4, 5, 78, + 3, 4, 6, 31, 3, 4, 6, 41, + 3, 4, 6, 78, 3, 8, 6, 31, + 3, 8, 6, 41, 3, 8, 6, 78, + 3, 9, 5, 31, 3, 9, 5, 41, + 3, 9, 5, 78, 3, 15, 16, 31, + 3, 15, 16, 41, 3, 15, 16, 78, + 3, 18, 17, 31, 3, 18, 17, 41, + 3, 18, 17, 78, 4, 2, 5, 6, + 31, 4, 2, 5, 6, 41, 4, 2, + 5, 6, 78, 4, 4, 5, 6, 31, + 4, 4, 5, 6, 41, 4, 4, 5, + 6, 78, 4, 7, 5, 6, 31, 4, + 7, 5, 6, 41, 4, 7, 5, 6, + 78, 4, 9, 5, 6, 31, 4, 9, + 5, 6, 41, 4, 9, 5, 6, 78 +] + +class << self + attr_accessor :_lex_trans_keys + private :_lex_trans_keys, :_lex_trans_keys= +end +self._lex_trans_keys = [ + 0, 0, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 45, 0, 120, 0, 120, + 0, 92, 0, 120, 0, 120, + 0, 45, 0, 120, 0, + 120, 67, 99, 45, 45, + 0, 92, 0, 120, 0, 102, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 45, + 0, 120, 0, 120, 0, 92, + 0, 120, 0, 120, 0, + 45, 0, 120, 0, 120, + 67, 99, 45, 45, 0, 92, + 0, 120, 0, 102, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 127, 0, + 122, 0, 45, 0, 120, + 0, 120, 0, 92, 0, 120, + 0, 120, 0, 45, 0, + 120, 0, 120, 67, 99, + 45, 45, 0, 92, 0, 120, + 0, 102, 0, 26, 0, + 92, 9, 32, 36, 123, + 0, 127, 0, 0, 48, 57, + 0, 127, 0, 127, 0, + 127, 0, 127, 0, 120, + 0, 0, 0, 0, 48, 55, + 48, 55, 0, 0, 0, + 0, 0, 92, 0, 0, + 0, 0, 0, 0, 0, 92, + 45, 45, 0, 0, 0, + 0, 0, 0, 0, 92, + 48, 102, 48, 102, 0, 0, + 48, 102, 48, 102, 0, + 0, 0, 45, 0, 92, + 0, 92, 0, 0, 0, 0, + 0, 92, 48, 102, 48, + 102, 0, 0, 0, 45, + 10, 10, 0, 92, 48, 123, + 48, 102, 48, 102, 48, + 102, 0, 0, 0, 125, + 0, 125, 0, 0, 0, 125, + 0, 0, 0, 125, 0, + 125, 0, 125, 0, 125, + 0, 0, 0, 125, 0, 125, + 0, 125, 0, 125, 0, + 125, 0, 125, 0, 0, + 0, 0, 48, 102, 0, 0, + 0, 92, 36, 123, 0, + 127, 0, 0, 48, 57, + 0, 127, 0, 127, 0, 127, + 0, 127, 0, 120, 0, + 0, 0, 0, 48, 55, + 48, 55, 0, 0, 0, 0, + 0, 92, 0, 0, 0, + 0, 0, 0, 0, 92, + 45, 45, 0, 0, 0, 0, + 0, 0, 0, 92, 48, + 102, 48, 102, 0, 0, + 48, 102, 48, 102, 0, 0, + 0, 45, 0, 92, 0, + 92, 0, 0, 0, 0, + 0, 92, 48, 102, 48, 102, + 0, 0, 0, 45, 10, + 10, 0, 92, 48, 123, + 48, 102, 48, 102, 48, 102, + 0, 0, 0, 125, 0, + 125, 0, 0, 0, 125, + 0, 0, 0, 125, 0, 125, + 0, 125, 0, 125, 0, + 0, 0, 125, 0, 125, + 0, 125, 0, 125, 0, 125, + 0, 125, 0, 0, 0, + 0, 48, 102, 0, 0, + 0, 92, 9, 32, 0, 26, + 0, 92, 0, 26, 0, + 35, 36, 123, 0, 127, + 0, 0, 48, 57, 0, 127, + 0, 127, 0, 127, 0, + 127, 0, 26, 0, 35, + 9, 32, 36, 123, 0, 127, + 0, 0, 48, 57, 0, + 127, 0, 127, 0, 127, + 0, 127, 0, 32, 9, 32, + 65, 122, 65, 122, 63, + 63, 0, 0, 0, 127, + 0, 127, 0, 120, 0, 0, + 0, 0, 48, 55, 48, + 55, 0, 0, 0, 0, + 0, 92, 0, 0, 0, 0, + 0, 0, 0, 92, 45, + 45, 0, 0, 0, 0, + 0, 0, 0, 92, 48, 102, + 48, 102, 0, 0, 48, + 102, 48, 102, 0, 0, + 0, 45, 0, 92, 0, 92, + 0, 0, 0, 0, 0, + 92, 48, 102, 48, 102, + 0, 0, 0, 45, 10, 10, + 0, 92, 48, 123, 48, + 102, 48, 102, 48, 102, + 0, 0, 0, 125, 0, 125, + 0, 0, 0, 125, 0, + 0, 0, 125, 0, 125, + 0, 125, 0, 125, 0, 0, + 0, 125, 0, 125, 0, + 125, 0, 125, 0, 125, + 0, 125, 0, 125, 0, 125, + 0, 125, 0, 125, 0, + 125, 0, 125, 0, 125, + 0, 125, 0, 125, 0, 125, + 0, 125, 0, 125, 0, + 125, 0, 0, 0, 0, + 48, 102, 0, 0, 0 +] + +class << self + attr_accessor :_lex_key_spans + private :_lex_key_spans, :_lex_key_spans= +end +self._lex_key_spans = [ + 0, 128, 128, 128, 128, 46, 121, 121, + 93, 121, 121, 46, 121, 121, 33, 1, + 93, 121, 103, 128, 128, 128, 128, 46, + 121, 121, 93, 121, 121, 46, 121, 121, + 33, 1, 93, 121, 103, 128, 128, 128, + 128, 128, 128, 128, 128, 123, 46, 121, + 121, 93, 121, 121, 46, 121, 121, 33, + 1, 93, 121, 103, 27, 93, 24, 88, + 128, 0, 10, 128, 128, 128, 128, 121, + 0, 0, 8, 8, 0, 0, 93, 0, + 0, 0, 93, 1, 0, 0, 0, 93, + 55, 55, 0, 55, 55, 0, 46, 93, + 93, 0, 0, 93, 55, 55, 0, 46, + 1, 93, 76, 55, 55, 55, 0, 126, + 126, 0, 126, 0, 126, 126, 126, 126, + 0, 126, 126, 126, 126, 126, 126, 0, + 0, 55, 0, 93, 88, 128, 0, 10, + 128, 128, 128, 128, 121, 0, 0, 8, + 8, 0, 0, 93, 0, 0, 0, 93, + 1, 0, 0, 0, 93, 55, 55, 0, + 55, 55, 0, 46, 93, 93, 0, 0, + 93, 55, 55, 0, 46, 1, 93, 76, + 55, 55, 55, 0, 126, 126, 0, 126, + 0, 126, 126, 126, 126, 0, 126, 126, + 126, 126, 126, 126, 0, 0, 55, 0, + 93, 24, 27, 93, 27, 36, 88, 128, + 0, 10, 128, 128, 128, 128, 27, 36, + 24, 88, 128, 0, 10, 128, 128, 128, + 128, 33, 24, 58, 58, 1, 0, 128, + 128, 121, 0, 0, 8, 8, 0, 0, + 93, 0, 0, 0, 93, 1, 0, 0, + 0, 93, 55, 55, 0, 55, 55, 0, + 46, 93, 93, 0, 0, 93, 55, 55, + 0, 46, 1, 93, 76, 55, 55, 55, + 0, 126, 126, 0, 126, 0, 126, 126, + 126, 126, 0, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 0, 0, + 55, 0 +] + +class << self + attr_accessor :_lex_index_offsets + private :_lex_index_offsets, :_lex_index_offsets= +end +self._lex_index_offsets = [ + 0, 0, 129, 258, 387, 516, 563, 685, + 807, 901, 1023, 1145, 1192, 1314, 1436, 1470, + 1472, 1566, 1688, 1792, 1921, 2050, 2179, 2308, + 2355, 2477, 2599, 2693, 2815, 2937, 2984, 3106, + 3228, 3262, 3264, 3358, 3480, 3584, 3713, 3842, + 3971, 4100, 4229, 4358, 4487, 4616, 4740, 4787, + 4909, 5031, 5125, 5247, 5369, 5416, 5538, 5660, + 5694, 5696, 5790, 5912, 6016, 6044, 6138, 6163, + 6252, 6381, 6382, 6393, 6522, 6651, 6780, 6909, + 7031, 7032, 7033, 7042, 7051, 7052, 7053, 7147, + 7148, 7149, 7150, 7244, 7246, 7247, 7248, 7249, + 7343, 7399, 7455, 7456, 7512, 7568, 7569, 7616, + 7710, 7804, 7805, 7806, 7900, 7956, 8012, 8013, + 8060, 8062, 8156, 8233, 8289, 8345, 8401, 8402, + 8529, 8656, 8657, 8784, 8785, 8912, 9039, 9166, + 9293, 9294, 9421, 9548, 9675, 9802, 9929, 10056, + 10057, 10058, 10114, 10115, 10209, 10298, 10427, 10428, + 10439, 10568, 10697, 10826, 10955, 11077, 11078, 11079, + 11088, 11097, 11098, 11099, 11193, 11194, 11195, 11196, + 11290, 11292, 11293, 11294, 11295, 11389, 11445, 11501, + 11502, 11558, 11614, 11615, 11662, 11756, 11850, 11851, + 11852, 11946, 12002, 12058, 12059, 12106, 12108, 12202, + 12279, 12335, 12391, 12447, 12448, 12575, 12702, 12703, + 12830, 12831, 12958, 13085, 13212, 13339, 13340, 13467, + 13594, 13721, 13848, 13975, 14102, 14103, 14104, 14160, + 14161, 14255, 14280, 14308, 14402, 14430, 14467, 14556, + 14685, 14686, 14697, 14826, 14955, 15084, 15213, 15241, + 15278, 15303, 15392, 15521, 15522, 15533, 15662, 15791, + 15920, 16049, 16083, 16108, 16167, 16226, 16228, 16229, + 16358, 16487, 16609, 16610, 16611, 16620, 16629, 16630, + 16631, 16725, 16726, 16727, 16728, 16822, 16824, 16825, + 16826, 16827, 16921, 16977, 17033, 17034, 17090, 17146, + 17147, 17194, 17288, 17382, 17383, 17384, 17478, 17534, + 17590, 17591, 17638, 17640, 17734, 17811, 17867, 17923, + 17979, 17980, 18107, 18234, 18235, 18362, 18363, 18490, + 18617, 18744, 18871, 18872, 18999, 19126, 19253, 19380, + 19507, 19634, 19761, 19888, 20015, 20142, 20269, 20396, + 20523, 20650, 20777, 20904, 21031, 21158, 21285, 21286, + 21287, 21343 +] + +class << self + attr_accessor :_lex_indicies + private :_lex_indicies, :_lex_indicies= +end +self._lex_indicies = [ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 0, 2, 0, 2, 2, + 0, 0, 2, 2, 2, 3, 2, 2, + 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 2, 2, 2, 2, 2, 2, + 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 2, 0, 0, 1, + 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 0, 0, 2, 0, + 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 0, 0, 0, 0, 0, + 0, 0, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 0, 0, 0, 0, + 2, 0, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 0, 0, 0, 0, + 0, 0, 7, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 0, 0, 0, + 0, 5, 0, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 0, 0, 0, + 0, 0, 5, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 0, 0, 0, + 0, 0, 0, 0, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 0, 0, + 0, 0, 8, 0, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 0, 0, + 0, 0, 0, 8, 10, 11, 11, 11, + 10, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 10, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 12, 11, 10, 13, 13, 13, 10, + 13, 13, 13, 13, 13, 14, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 10, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 15, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 16, 13, 10, 13, 13, + 13, 10, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 10, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 17, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 16, 13, 10, + 18, 18, 18, 10, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 10, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 19, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 20, 18, 10, 21, 21, + 21, 10, 21, 21, 21, 21, 21, 22, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 10, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 23, 21, 10, + 21, 21, 21, 10, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 10, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 23, + 21, 10, 11, 11, 11, 10, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 10, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 24, 11, + 10, 25, 25, 25, 10, 25, 25, 25, + 25, 25, 26, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 10, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 27, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 28, 25, 25, 25, + 25, 25, 25, 29, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, + 30, 25, 10, 25, 25, 25, 10, 25, + 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 10, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 30, 25, 31, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 32, 10, 32, 10, + 10, 33, 33, 33, 10, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 10, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 34, + 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 35, 33, 10, 13, + 13, 13, 10, 13, 13, 13, 13, 13, + 14, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 10, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 17, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 16, 13, + 10, 36, 36, 36, 10, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 10, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 36, 36, 36, 36, 36, 36, + 36, 37, 37, 37, 37, 37, 37, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, + 36, 37, 37, 37, 37, 37, 37, 36, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 40, 40, 38, 40, 38, 40, 40, + 38, 38, 40, 40, 40, 41, 40, 40, + 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 40, 40, 40, 40, 40, 40, + 40, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 38, 40, 38, 38, 39, + 40, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 38, 38, 38, 40, 38, + 39, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 38, 38, 38, 38, 38, + 38, 38, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 38, 38, 38, 38, + 40, 38, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 38, 38, 38, 38, + 38, 40, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 38, 38, 38, 38, + 38, 38, 45, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 38, 38, 38, + 38, 43, 38, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 38, 38, 38, + 38, 38, 43, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 38, 38, 38, + 38, 38, 38, 38, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 38, 38, + 38, 38, 46, 38, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 38, 38, + 38, 38, 38, 46, 48, 49, 49, 49, + 48, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 48, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 50, 49, 48, 51, 51, 51, 48, + 51, 51, 51, 51, 51, 52, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 48, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 53, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 54, 51, 48, 51, 51, + 51, 48, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 48, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 55, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 54, 51, 48, + 56, 56, 56, 48, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 48, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 57, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 58, 56, 48, 59, 59, + 59, 48, 59, 59, 59, 59, 59, 60, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 48, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 61, 59, 48, + 59, 59, 59, 48, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 48, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 61, + 59, 48, 49, 49, 49, 48, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 48, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 62, 49, + 48, 63, 63, 63, 48, 63, 63, 63, + 63, 63, 64, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 48, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 65, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 66, 63, 63, 63, + 63, 63, 63, 67, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 68, 63, 48, 63, 63, 63, 48, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 48, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 68, 63, 69, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 70, 48, 70, 48, + 48, 71, 71, 71, 48, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 48, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 72, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 73, 71, 48, 51, + 51, 51, 48, 51, 51, 51, 51, 51, + 52, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 48, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 55, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 54, 51, + 48, 74, 74, 74, 48, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 48, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 74, 74, 74, 74, 74, 74, + 74, 75, 75, 75, 75, 75, 75, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 74, + 74, 75, 75, 75, 75, 75, 75, 74, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 78, 78, 76, 78, 76, 78, 78, + 76, 76, 78, 78, 78, 79, 78, 78, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 78, 78, 78, 78, 78, 78, + 78, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 76, 78, 76, 76, 77, + 78, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 76, 76, 76, 78, 76, + 77, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 76, 76, 76, 76, 76, + 76, 76, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 76, 76, 76, 76, + 78, 76, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 76, 76, 76, 76, + 76, 78, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 76, 76, 76, 76, + 76, 76, 83, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 76, 76, 76, + 76, 81, 76, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 76, 76, 76, + 76, 76, 81, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 76, 76, 76, + 76, 76, 76, 76, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 76, 76, + 76, 76, 84, 76, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 76, 76, + 76, 76, 76, 84, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 88, 88, 86, + 88, 86, 88, 88, 86, 86, 88, 88, + 88, 89, 88, 88, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 88, 88, + 88, 88, 88, 88, 88, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 86, + 88, 86, 86, 87, 88, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 86, + 86, 86, 88, 86, 87, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 86, + 86, 86, 86, 86, 86, 86, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 86, 86, 86, 86, 88, 86, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 86, 86, 86, 86, 86, 88, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, + 86, 86, 86, 86, 86, 86, 93, 91, + 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, + 91, 86, 86, 86, 86, 91, 86, 91, + 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, + 91, 86, 86, 86, 86, 86, 91, 86, + 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 86, 86, 86, 86, 86, 86, 86, + 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 86, 86, 86, 86, 94, 86, + 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 86, 86, 86, 86, 86, 94, + 97, 96, 96, 96, 97, 96, 96, 96, + 96, 98, 99, 98, 98, 98, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 97, 96, 96, 96, 96, 96, + 98, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, + 96, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 96, 101, 96, 96, 100, + 96, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 100, 96, 102, 103, 103, 103, + 102, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 102, 103, + 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, + 103, 104, 103, 102, 105, 105, 105, 102, + 105, 105, 105, 105, 105, 106, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 102, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 107, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 108, 105, 102, 105, 105, + 105, 102, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 102, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 109, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 108, 105, 102, + 110, 110, 110, 102, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 102, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 111, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 112, 110, 102, 113, 113, + 113, 102, 113, 113, 113, 113, 113, 114, + 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 102, + 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 115, 113, 102, + 113, 113, 113, 102, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, + 113, 102, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 115, + 113, 102, 103, 103, 103, 102, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 102, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 116, 103, + 102, 117, 117, 117, 102, 117, 117, 117, + 117, 117, 118, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 102, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 119, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 120, 117, 117, 117, + 117, 117, 117, 121, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, + 122, 117, 102, 117, 117, 117, 102, 117, + 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 102, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 117, 117, 117, 117, 117, 117, + 117, 117, 122, 117, 123, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, 124, 102, 124, 102, + 102, 125, 125, 125, 102, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 102, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 126, + 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 127, 125, 102, 105, + 105, 105, 102, 105, 105, 105, 105, 105, + 106, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 102, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 109, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 108, 105, + 102, 128, 128, 128, 102, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 102, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 129, 129, 129, 129, 129, 129, 129, 129, + 129, 129, 128, 128, 128, 128, 128, 128, + 128, 129, 129, 129, 129, 129, 129, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 129, 129, 129, 129, 129, 129, 128, + 97, 130, 130, 130, 97, 130, 130, 130, + 130, 130, 130, 130, 130, 130, 130, 130, + 130, 130, 130, 130, 130, 130, 130, 130, + 130, 130, 97, 130, 132, 131, 131, 131, + 132, 131, 131, 131, 131, 133, 134, 133, + 133, 133, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 132, 131, + 131, 131, 131, 131, 133, 131, 131, 135, + 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, + 136, 131, 133, 137, 133, 133, 133, 137, + 137, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 137, + 137, 133, 137, 139, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 140, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 141, 138, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 142, 142, + 142, 142, 142, 142, 142, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 142, + 142, 142, 142, 1, 142, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 142, + 142, 142, 142, 142, 1, 142, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, + 142, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, + 143, 143, 143, 143, 143, 143, 143, 143, + 143, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 143, 143, 143, 143, 143, + 143, 143, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 143, 143, 143, 143, + 5, 143, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 143, 143, 143, 143, + 143, 5, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 144, 144, 144, 144, 144, 144, + 144, 144, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 144, 144, 144, 144, + 144, 144, 144, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 144, 144, 144, + 144, 6, 144, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 144, 144, 144, + 144, 144, 6, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 145, 145, 145, + 145, 145, 145, 145, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 145, 145, + 145, 145, 8, 145, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 145, 145, + 145, 145, 145, 8, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 146, 146, 146, 146, + 146, 146, 146, 146, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 146, 146, + 146, 146, 146, 146, 146, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 146, + 146, 146, 146, 9, 146, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 146, + 146, 146, 146, 146, 9, 149, 148, 148, + 148, 149, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 149, + 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 150, 150, 150, + 150, 150, 150, 150, 150, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, + 151, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 152, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, + 153, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 154, 148, 148, 155, 148, 156, + 157, 159, 159, 159, 159, 159, 159, 159, + 159, 158, 160, 160, 160, 160, 160, 160, + 160, 160, 158, 158, 161, 161, 33, 33, + 33, 161, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 161, + 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 34, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, + 33, 162, 33, 163, 164, 165, 165, 33, + 33, 33, 165, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, + 165, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 34, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 166, 33, 32, 165, 167, 168, + 169, 169, 18, 18, 18, 169, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 169, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 19, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 170, 18, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 169, 169, 169, 169, 169, 169, 169, + 171, 171, 171, 171, 171, 171, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, + 169, 169, 169, 169, 169, 169, 169, 169, + 171, 171, 171, 171, 171, 171, 169, 173, + 173, 173, 173, 173, 173, 173, 173, 173, + 173, 172, 172, 172, 172, 172, 172, 172, + 173, 173, 173, 173, 173, 173, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, + 172, 172, 172, 172, 172, 172, 172, 172, + 173, 173, 173, 173, 173, 173, 172, 172, + 174, 174, 174, 174, 174, 174, 174, 174, + 174, 174, 165, 165, 165, 165, 165, 165, + 165, 174, 174, 174, 174, 174, 174, 165, + 165, 165, 165, 165, 165, 165, 165, 165, + 165, 165, 165, 165, 165, 165, 165, 165, + 165, 165, 165, 165, 165, 165, 165, 165, + 165, 174, 174, 174, 174, 174, 174, 165, + 176, 176, 176, 176, 176, 176, 176, 176, + 176, 176, 175, 175, 175, 175, 175, 175, + 175, 176, 176, 176, 176, 176, 176, 175, + 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 175, + 175, 175, 175, 175, 175, 175, 175, 175, + 175, 176, 176, 176, 176, 176, 176, 175, + 175, 165, 11, 11, 11, 165, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 165, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 177, 11, + 161, 18, 18, 18, 161, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 161, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 19, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 20, 18, 161, 178, + 178, 178, 161, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 161, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 179, 178, 180, 181, 181, 178, + 178, 178, 181, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 181, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 178, 178, 178, 178, 178, 178, + 178, 178, 182, 178, 183, 183, 183, 183, + 183, 183, 183, 183, 183, 183, 181, 181, + 181, 181, 181, 181, 181, 183, 183, 183, + 183, 183, 183, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 181, 181, 181, + 181, 181, 181, 181, 181, 183, 183, 183, + 183, 183, 183, 181, 185, 185, 185, 185, + 185, 185, 185, 185, 185, 185, 184, 184, + 184, 184, 184, 184, 184, 185, 185, 185, + 185, 185, 185, 184, 184, 184, 184, 184, + 184, 184, 184, 184, 184, 184, 184, 184, + 184, 184, 184, 184, 184, 184, 184, 184, + 184, 184, 184, 184, 184, 185, 185, 185, + 185, 185, 185, 184, 184, 181, 11, 11, + 11, 181, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 181, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 177, 11, 186, 181, 181, 18, + 18, 18, 181, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 181, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 19, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 20, 18, 188, 188, 188, 188, + 188, 188, 188, 188, 188, 188, 187, 187, + 187, 187, 187, 187, 187, 188, 188, 188, + 188, 188, 188, 187, 187, 187, 187, 187, + 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 187, 187, 187, 188, 188, 188, + 188, 188, 188, 187, 187, 187, 187, 187, + 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 187, 187, 187, 187, 187, 189, + 187, 190, 190, 190, 190, 190, 190, 190, + 190, 190, 190, 187, 187, 187, 187, 187, + 187, 187, 190, 190, 190, 190, 190, 190, + 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 190, 190, 190, 190, 190, 190, + 187, 191, 191, 191, 191, 191, 191, 191, + 191, 191, 191, 187, 187, 187, 187, 187, + 187, 187, 191, 191, 191, 191, 191, 191, + 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 191, 191, 191, 191, 191, 191, + 187, 192, 192, 192, 192, 192, 192, 192, + 192, 192, 192, 187, 187, 187, 187, 187, + 187, 187, 192, 192, 192, 192, 192, 192, + 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 187, 187, 187, 187, 187, 187, + 187, 187, 192, 192, 192, 192, 192, 192, + 187, 193, 196, 195, 195, 195, 196, 195, + 195, 195, 195, 197, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 196, 195, 195, 195, + 195, 195, 197, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 198, 195, 195, 195, 195, + 195, 195, 195, 198, 198, 198, 198, 198, + 198, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 198, 198, 198, 198, 198, + 198, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 199, + 195, 196, 195, 195, 195, 196, 195, 195, + 195, 195, 194, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 196, 195, 195, 195, 195, + 195, 194, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, + 195, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 195, 195, 195, 195, 195, + 195, 195, 200, 200, 200, 200, 200, 200, + 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 200, 200, 200, 200, 200, 200, + 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 201, 195, + 194, 196, 200, 200, 200, 196, 200, 200, + 200, 200, 194, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 196, 200, 200, 200, 200, + 200, 194, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 200, 200, 200, 200, 194, 200, + 202, 196, 203, 203, 203, 196, 203, 203, + 203, 203, 197, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 196, 203, 203, 203, 203, + 203, 197, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 198, 198, 198, 198, 198, 198, 198, + 198, 198, 198, 203, 203, 203, 203, 203, + 203, 203, 198, 198, 198, 198, 198, 198, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 198, 198, 198, 198, 198, 198, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 194, 203, + 196, 203, 203, 203, 196, 203, 203, 203, + 203, 194, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 196, 203, 203, 203, 203, 203, + 194, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 200, 200, 200, 200, 200, 200, 200, 200, + 200, 200, 203, 203, 203, 203, 203, 203, + 203, 200, 200, 200, 200, 200, 200, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 200, 200, 200, 200, 200, 200, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 196, 203, 196, + 203, 203, 203, 196, 203, 203, 203, 203, + 204, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 196, 203, 203, 203, 203, 203, 204, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 205, + 205, 205, 205, 205, 205, 205, 205, 205, + 205, 203, 203, 203, 203, 203, 203, 203, + 205, 205, 205, 205, 205, 205, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 205, 205, 205, 205, 205, 205, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 206, 203, 196, 203, + 203, 203, 196, 203, 203, 203, 203, 204, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 196, 203, 203, 203, 203, 203, 204, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 198, 198, + 198, 198, 198, 198, 198, 198, 198, 198, + 203, 203, 203, 203, 203, 203, 203, 198, + 198, 198, 198, 198, 198, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 198, + 198, 198, 198, 198, 198, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 206, 203, 207, 196, 203, + 203, 203, 196, 203, 203, 203, 203, 204, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 196, 203, 203, 203, 203, 203, 204, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 208, 208, + 208, 208, 208, 208, 208, 208, 208, 208, + 203, 203, 203, 203, 203, 203, 203, 208, + 208, 208, 208, 208, 208, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 208, + 208, 208, 208, 208, 208, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 206, 203, 196, 203, 203, + 203, 196, 203, 203, 203, 203, 204, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 196, + 203, 203, 203, 203, 203, 204, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 209, 209, 209, + 209, 209, 209, 209, 209, 209, 209, 203, + 203, 203, 203, 203, 203, 203, 209, 209, + 209, 209, 209, 209, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 209, 209, + 209, 209, 209, 209, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 206, 203, 196, 203, 203, 203, + 196, 203, 203, 203, 203, 204, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 196, 203, + 203, 203, 203, 203, 204, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 210, 210, 210, 210, + 210, 210, 210, 210, 210, 210, 203, 203, + 203, 203, 203, 203, 203, 210, 210, 210, + 210, 210, 210, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 210, 210, 210, + 210, 210, 210, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 206, 203, 196, 203, 203, 203, 196, + 203, 203, 203, 203, 204, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 196, 203, 203, + 203, 203, 203, 204, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 211, 211, 211, 211, 211, + 211, 211, 211, 211, 211, 203, 203, 203, + 203, 203, 203, 203, 211, 211, 211, 211, + 211, 211, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 211, 211, 211, 211, + 211, 211, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 206, 203, 196, 203, 203, 203, 196, 203, + 203, 203, 203, 204, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 196, 203, 203, 203, + 203, 203, 204, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 212, 212, 212, 212, 212, 212, + 212, 212, 212, 212, 203, 203, 203, 203, + 203, 203, 203, 212, 212, 212, 212, 212, + 212, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 212, 212, 212, 212, 212, + 212, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 206, + 203, 196, 203, 203, 203, 196, 203, 203, + 203, 203, 194, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 196, 203, 203, 203, 203, + 203, 194, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 212, 212, 212, 212, 212, 212, 212, + 212, 212, 212, 203, 203, 203, 203, 203, + 203, 203, 212, 212, 212, 212, 212, 212, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 212, 212, 212, 212, 212, 212, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 194, 203, + 213, 214, 216, 216, 216, 216, 216, 216, + 216, 216, 216, 216, 215, 215, 215, 215, + 215, 215, 215, 216, 216, 216, 216, 216, + 216, 215, 215, 215, 215, 215, 215, 215, + 215, 215, 215, 215, 215, 215, 215, 215, + 215, 215, 215, 215, 215, 215, 215, 215, + 215, 215, 215, 216, 216, 216, 216, 216, + 216, 215, 215, 218, 217, 217, 217, 218, + 217, 217, 217, 217, 217, 219, 217, 217, + 217, 217, 217, 217, 217, 217, 217, 217, + 217, 217, 217, 217, 217, 218, 217, 217, + 217, 217, 217, 217, 217, 217, 220, 217, + 217, 217, 217, 217, 217, 217, 217, 217, + 217, 217, 217, 217, 217, 217, 217, 217, + 217, 217, 217, 217, 217, 217, 217, 217, + 217, 217, 217, 217, 217, 217, 217, 217, + 217, 217, 217, 217, 217, 217, 217, 217, + 217, 217, 217, 217, 217, 217, 217, 217, + 217, 217, 217, 217, 217, 217, 217, 221, + 217, 223, 222, 222, 222, 222, 222, 222, + 222, 222, 222, 222, 222, 222, 222, 222, + 222, 222, 222, 222, 222, 222, 222, 222, + 222, 222, 222, 222, 222, 224, 222, 222, + 222, 222, 222, 222, 222, 222, 222, 222, + 222, 222, 222, 222, 222, 222, 222, 222, + 222, 222, 222, 222, 222, 222, 222, 222, + 222, 222, 222, 222, 222, 222, 222, 222, + 222, 222, 222, 222, 222, 222, 222, 222, + 222, 222, 222, 222, 222, 222, 222, 222, + 222, 222, 222, 222, 222, 222, 222, 222, + 225, 222, 226, 226, 226, 226, 226, 226, + 226, 226, 226, 226, 226, 226, 226, 226, + 226, 226, 226, 226, 226, 226, 226, 226, + 226, 226, 226, 226, 226, 226, 226, 226, + 226, 226, 226, 226, 226, 226, 226, 226, + 226, 226, 226, 226, 226, 226, 226, 226, + 226, 226, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 226, 226, 226, 226, + 226, 226, 226, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 226, 226, 226, + 226, 39, 226, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 226, 226, 226, + 226, 226, 39, 226, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 226, 227, + 227, 227, 227, 227, 227, 227, 227, 227, + 227, 227, 227, 227, 227, 227, 227, 227, + 227, 227, 227, 227, 227, 227, 227, 227, + 227, 227, 227, 227, 227, 227, 227, 227, + 227, 227, 227, 227, 227, 227, 227, 227, + 227, 227, 227, 227, 227, 227, 227, 43, + 43, 43, 43, 43, 43, 43, 43, 43, + 43, 227, 227, 227, 227, 227, 227, 227, + 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 227, 227, 227, 227, 43, 227, + 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 227, 227, 227, 227, 227, 43, + 228, 228, 228, 228, 228, 228, 228, 228, + 228, 228, 228, 228, 228, 228, 228, 228, + 228, 228, 228, 228, 228, 228, 228, 228, + 228, 228, 228, 228, 228, 228, 228, 228, + 228, 228, 228, 228, 228, 228, 228, 228, + 228, 228, 228, 228, 228, 228, 228, 228, + 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 228, 228, 228, 228, 228, 228, + 228, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 228, 228, 228, 228, 44, + 228, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 228, 228, 228, 228, 228, + 44, 229, 229, 229, 229, 229, 229, 229, + 229, 229, 229, 229, 229, 229, 229, 229, + 229, 229, 229, 229, 229, 229, 229, 229, + 229, 229, 229, 229, 229, 229, 229, 229, + 229, 229, 229, 229, 229, 229, 229, 229, + 229, 229, 229, 229, 229, 229, 229, 229, + 229, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 229, 229, 229, 229, 229, + 229, 229, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 229, 229, 229, 229, + 46, 229, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 229, 229, 229, 229, + 229, 46, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 230, 230, 230, 230, + 230, 230, 230, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 230, 230, 230, + 230, 47, 230, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 47, + 47, 47, 47, 47, 47, 230, 230, 230, + 230, 230, 47, 233, 232, 232, 232, 233, + 232, 232, 232, 232, 232, 232, 232, 232, + 232, 232, 232, 232, 232, 232, 232, 232, + 232, 232, 232, 232, 232, 233, 232, 232, + 232, 232, 232, 232, 232, 232, 232, 232, + 232, 232, 232, 232, 232, 232, 232, 232, + 232, 232, 232, 234, 234, 234, 234, 234, + 234, 234, 234, 232, 232, 232, 232, 232, + 232, 232, 232, 232, 232, 232, 235, 232, + 232, 232, 232, 232, 232, 232, 232, 232, + 236, 232, 232, 232, 232, 232, 232, 232, + 232, 232, 232, 232, 232, 232, 232, 232, + 232, 232, 232, 232, 232, 232, 237, 232, + 232, 232, 232, 232, 232, 232, 232, 232, + 232, 232, 232, 232, 232, 232, 232, 232, + 238, 232, 232, 239, 232, 240, 241, 243, + 243, 243, 243, 243, 243, 243, 243, 242, + 244, 244, 244, 244, 244, 244, 244, 244, + 242, 242, 245, 245, 71, 71, 71, 245, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 245, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 72, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 246, + 71, 247, 248, 249, 249, 71, 71, 71, + 249, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 249, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 72, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, + 250, 71, 70, 249, 251, 252, 253, 253, + 56, 56, 56, 253, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 253, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 57, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 254, 56, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 253, + 253, 253, 253, 253, 253, 253, 255, 255, + 255, 255, 255, 255, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 255, 255, + 255, 255, 255, 255, 253, 257, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 256, + 256, 256, 256, 256, 256, 256, 257, 257, + 257, 257, 257, 257, 256, 256, 256, 256, + 256, 256, 256, 256, 256, 256, 256, 256, + 256, 256, 256, 256, 256, 256, 256, 256, + 256, 256, 256, 256, 256, 256, 257, 257, + 257, 257, 257, 257, 256, 256, 258, 258, + 258, 258, 258, 258, 258, 258, 258, 258, + 249, 249, 249, 249, 249, 249, 249, 258, + 258, 258, 258, 258, 258, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 258, + 258, 258, 258, 258, 258, 249, 260, 260, + 260, 260, 260, 260, 260, 260, 260, 260, + 259, 259, 259, 259, 259, 259, 259, 260, + 260, 260, 260, 260, 260, 259, 259, 259, + 259, 259, 259, 259, 259, 259, 259, 259, + 259, 259, 259, 259, 259, 259, 259, 259, + 259, 259, 259, 259, 259, 259, 259, 260, + 260, 260, 260, 260, 260, 259, 259, 249, + 49, 49, 49, 249, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 249, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 261, 49, 245, 56, + 56, 56, 245, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 245, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 57, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 58, 56, 245, 262, 262, 262, + 245, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 245, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 263, 262, 264, 265, 265, 262, 262, 262, + 265, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 265, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, 262, 262, + 266, 262, 267, 267, 267, 267, 267, 267, + 267, 267, 267, 267, 265, 265, 265, 265, + 265, 265, 265, 267, 267, 267, 267, 267, + 267, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 267, 267, 267, 267, 267, + 267, 265, 269, 269, 269, 269, 269, 269, + 269, 269, 269, 269, 268, 268, 268, 268, + 268, 268, 268, 269, 269, 269, 269, 269, + 269, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 269, 269, 269, 269, 269, + 269, 268, 268, 265, 49, 49, 49, 265, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 265, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 261, 49, 270, 265, 265, 56, 56, 56, + 265, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 265, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 57, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, + 58, 56, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 271, 271, 271, 271, + 271, 271, 271, 272, 272, 272, 272, 272, + 272, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 272, 272, 272, 272, 272, + 272, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 273, 271, 274, + 274, 274, 274, 274, 274, 274, 274, 274, + 274, 271, 271, 271, 271, 271, 271, 271, + 274, 274, 274, 274, 274, 274, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, + 274, 274, 274, 274, 274, 274, 271, 275, + 275, 275, 275, 275, 275, 275, 275, 275, + 275, 271, 271, 271, 271, 271, 271, 271, + 275, 275, 275, 275, 275, 275, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, + 275, 275, 275, 275, 275, 275, 271, 276, + 276, 276, 276, 276, 276, 276, 276, 276, + 276, 271, 271, 271, 271, 271, 271, 271, + 276, 276, 276, 276, 276, 276, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, + 276, 276, 276, 276, 276, 276, 271, 277, + 280, 279, 279, 279, 280, 279, 279, 279, + 279, 281, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 280, 279, 279, 279, 279, 279, + 281, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, + 282, 282, 282, 282, 282, 282, 282, 282, + 282, 282, 279, 279, 279, 279, 279, 279, + 279, 282, 282, 282, 282, 282, 282, 279, + 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, + 279, 282, 282, 282, 282, 282, 282, 279, + 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 283, 279, 280, + 279, 279, 279, 280, 279, 279, 279, 279, + 278, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, + 279, 280, 279, 279, 279, 279, 279, 278, + 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 284, + 284, 284, 284, 284, 284, 284, 284, 284, + 284, 279, 279, 279, 279, 279, 279, 279, + 284, 284, 284, 284, 284, 284, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, + 284, 284, 284, 284, 284, 284, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 279, 279, 279, 279, + 279, 279, 279, 279, 285, 279, 278, 280, + 284, 284, 284, 280, 284, 284, 284, 284, + 278, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, + 284, 280, 284, 284, 284, 284, 284, 278, + 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 278, 284, 286, 280, + 287, 287, 287, 280, 287, 287, 287, 287, + 281, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 280, 287, 287, 287, 287, 287, 281, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 282, + 282, 282, 282, 282, 282, 282, 282, 282, + 282, 287, 287, 287, 287, 287, 287, 287, + 282, 282, 282, 282, 282, 282, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 282, 282, 282, 282, 282, 282, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 278, 287, 280, 287, + 287, 287, 280, 287, 287, 287, 287, 278, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 280, 287, 287, 287, 287, 287, 278, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, + 287, 287, 287, 287, 287, 287, 287, 284, + 284, 284, 284, 284, 284, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 284, + 284, 284, 284, 284, 284, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 280, 287, 280, 287, 287, + 287, 280, 287, 287, 287, 287, 288, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 280, + 287, 287, 287, 287, 287, 288, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 287, + 287, 287, 287, 287, 287, 287, 289, 289, + 289, 289, 289, 289, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 289, 289, + 289, 289, 289, 289, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 290, 287, 280, 287, 287, 287, + 280, 287, 287, 287, 287, 288, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 280, 287, + 287, 287, 287, 287, 288, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 282, 282, 282, 282, + 282, 282, 282, 282, 282, 282, 287, 287, + 287, 287, 287, 287, 287, 282, 282, 282, + 282, 282, 282, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 282, 282, 282, + 282, 282, 282, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 290, 287, 291, 280, 287, 287, 287, + 280, 287, 287, 287, 287, 288, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 280, 287, + 287, 287, 287, 287, 288, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 292, 292, 292, 292, + 292, 292, 292, 292, 292, 292, 287, 287, + 287, 287, 287, 287, 287, 292, 292, 292, + 292, 292, 292, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 292, 292, 292, + 292, 292, 292, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 290, 287, 280, 287, 287, 287, 280, + 287, 287, 287, 287, 288, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 280, 287, 287, + 287, 287, 287, 288, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 293, 293, 293, 293, 293, + 293, 293, 293, 293, 293, 287, 287, 287, + 287, 287, 287, 287, 293, 293, 293, 293, + 293, 293, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 293, 293, 293, 293, + 293, 293, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 290, 287, 280, 287, 287, 287, 280, 287, + 287, 287, 287, 288, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 280, 287, 287, 287, + 287, 287, 288, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 294, 294, 294, 294, 294, 294, + 294, 294, 294, 294, 287, 287, 287, 287, + 287, 287, 287, 294, 294, 294, 294, 294, + 294, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 294, 294, 294, 294, 294, + 294, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 290, + 287, 280, 287, 287, 287, 280, 287, 287, + 287, 287, 288, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 280, 287, 287, 287, 287, + 287, 288, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, 287, 287, 287, 287, 287, + 287, 287, 295, 295, 295, 295, 295, 295, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 295, 295, 295, 295, 295, 295, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 290, 287, + 280, 287, 287, 287, 280, 287, 287, 287, + 287, 288, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 280, 287, 287, 287, 287, 287, + 288, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 296, 296, 296, 296, 296, 296, 296, 296, + 296, 296, 287, 287, 287, 287, 287, 287, + 287, 296, 296, 296, 296, 296, 296, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 296, 296, 296, 296, 296, 296, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 290, 287, 280, + 287, 287, 287, 280, 287, 287, 287, 287, + 278, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 280, 287, 287, 287, 287, 287, 278, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 296, + 296, 296, 296, 296, 296, 296, 296, 296, + 296, 287, 287, 287, 287, 287, 287, 287, + 296, 296, 296, 296, 296, 296, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 296, 296, 296, 296, 296, 296, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 278, 287, 297, 298, + 300, 300, 300, 300, 300, 300, 300, 300, + 300, 300, 299, 299, 299, 299, 299, 299, + 299, 300, 300, 300, 300, 300, 300, 299, + 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, + 299, 299, 299, 299, 299, 299, 299, 299, + 299, 300, 300, 300, 300, 300, 300, 299, + 299, 302, 301, 301, 301, 302, 301, 301, + 301, 301, 303, 304, 303, 303, 303, 301, + 301, 301, 301, 301, 301, 301, 301, 301, + 301, 301, 301, 302, 301, 301, 301, 301, + 301, 303, 301, 301, 301, 301, 301, 301, + 301, 301, 301, 301, 301, 301, 301, 301, + 301, 301, 301, 301, 301, 301, 301, 301, + 301, 301, 301, 301, 301, 301, 301, 301, + 301, 301, 301, 301, 301, 301, 301, 301, + 301, 301, 301, 301, 301, 301, 301, 301, + 301, 301, 301, 301, 301, 301, 301, 301, + 301, 301, 301, 301, 301, 305, 301, 303, + 306, 303, 303, 303, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 303, 306, + 307, 308, 308, 308, 307, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, 307, 308, 310, 309, 309, 309, + 310, 309, 309, 309, 309, 309, 311, 309, + 309, 309, 309, 309, 309, 309, 309, 309, + 309, 309, 309, 309, 309, 309, 310, 309, + 309, 309, 309, 309, 309, 309, 309, 309, + 309, 309, 309, 309, 309, 309, 309, 309, + 309, 309, 309, 309, 309, 309, 309, 309, + 309, 309, 309, 309, 309, 309, 309, 309, + 309, 309, 309, 309, 309, 309, 309, 309, + 309, 309, 309, 309, 309, 309, 309, 309, + 309, 309, 309, 309, 309, 309, 309, 309, + 309, 309, 309, 309, 309, 309, 309, 309, + 312, 309, 313, 314, 314, 314, 313, 314, + 314, 314, 314, 314, 315, 314, 314, 314, + 314, 314, 314, 314, 314, 314, 314, 314, + 314, 314, 314, 314, 313, 314, 317, 316, + 316, 316, 317, 316, 316, 316, 316, 316, + 318, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, 316, + 317, 316, 316, 316, 316, 316, 316, 316, + 316, 319, 316, 321, 320, 320, 320, 320, + 320, 320, 320, 320, 320, 320, 320, 320, + 320, 320, 320, 320, 320, 320, 320, 320, + 320, 320, 320, 320, 320, 320, 320, 322, + 320, 320, 320, 320, 320, 320, 320, 320, + 320, 320, 320, 320, 320, 320, 320, 320, + 320, 320, 320, 320, 320, 320, 320, 320, + 320, 320, 320, 320, 320, 320, 320, 320, + 320, 320, 320, 320, 320, 320, 320, 320, + 320, 320, 320, 320, 320, 320, 320, 320, + 320, 320, 320, 320, 320, 320, 320, 320, + 320, 320, 323, 320, 324, 324, 324, 324, + 324, 324, 324, 324, 324, 324, 324, 324, + 324, 324, 324, 324, 324, 324, 324, 324, + 324, 324, 324, 324, 324, 324, 324, 324, + 324, 324, 324, 324, 324, 324, 324, 324, + 324, 324, 324, 324, 324, 324, 324, 324, + 324, 324, 324, 324, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 324, 324, + 324, 324, 324, 324, 324, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 324, + 324, 324, 324, 77, 324, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 77, + 77, 77, 77, 77, 77, 77, 77, 324, + 324, 324, 324, 324, 77, 324, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 324, 325, 325, 325, 325, 325, 325, 325, + 325, 325, 325, 325, 325, 325, 325, 325, + 325, 325, 325, 325, 325, 325, 325, 325, + 325, 325, 325, 325, 325, 325, 325, 325, + 325, 325, 325, 325, 325, 325, 325, 325, + 325, 325, 325, 325, 325, 325, 325, 325, + 325, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 325, 325, 325, 325, 325, + 325, 325, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 325, 325, 325, 325, + 81, 325, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 325, 325, 325, 325, + 325, 81, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, + 326, 326, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 326, 326, 326, 326, + 326, 326, 326, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 326, 326, 326, + 326, 82, 326, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 326, 326, 326, + 326, 326, 82, 327, 327, 327, 327, 327, + 327, 327, 327, 327, 327, 327, 327, 327, + 327, 327, 327, 327, 327, 327, 327, 327, + 327, 327, 327, 327, 327, 327, 327, 327, + 327, 327, 327, 327, 327, 327, 327, 327, + 327, 327, 327, 327, 327, 327, 327, 327, + 327, 327, 327, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 327, 327, 327, + 327, 327, 327, 327, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 327, 327, + 327, 327, 84, 327, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 327, 327, + 327, 327, 327, 84, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, 328, 84, 84, 84, 84, + 84, 84, 84, 84, 84, 84, 328, 328, + 328, 328, 328, 328, 328, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 328, + 328, 328, 328, 85, 328, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 85, + 85, 85, 85, 85, 85, 85, 85, 328, + 328, 328, 328, 328, 85, 330, 329, 329, + 329, 330, 329, 329, 329, 329, 329, 331, + 329, 329, 329, 329, 329, 329, 329, 329, + 329, 329, 329, 329, 329, 329, 329, 330, + 329, 333, 332, 332, 332, 333, 332, 332, + 332, 332, 334, 335, 334, 334, 334, 332, + 332, 332, 332, 332, 332, 332, 332, 332, + 332, 332, 332, 333, 332, 332, 332, 332, + 332, 334, 332, 332, 336, 332, 334, 337, + 334, 334, 334, 337, 337, 337, 337, 337, + 337, 337, 337, 337, 337, 337, 337, 337, + 337, 337, 337, 337, 337, 334, 337, 339, + 338, 338, 338, 338, 338, 338, 338, 338, + 338, 338, 338, 338, 338, 338, 338, 338, + 338, 338, 338, 338, 338, 338, 338, 338, + 338, 338, 338, 340, 338, 338, 338, 338, + 338, 338, 338, 338, 338, 338, 338, 338, + 338, 338, 338, 338, 338, 338, 338, 338, + 338, 338, 338, 338, 338, 338, 338, 338, + 338, 338, 338, 338, 338, 338, 338, 338, + 338, 338, 338, 338, 338, 338, 338, 338, + 338, 338, 338, 338, 338, 338, 338, 338, + 338, 338, 338, 338, 338, 338, 341, 338, + 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, 342, + 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 342, 342, 342, 342, 342, 342, + 342, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 342, 342, 342, 342, 87, + 342, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 87, 342, 342, 342, 342, 342, + 87, 342, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 342, 343, 343, 343, + 343, 343, 343, 343, 343, 343, 343, 343, + 343, 343, 343, 343, 343, 343, 343, 343, + 343, 343, 343, 343, 343, 343, 343, 343, + 343, 343, 343, 343, 343, 343, 343, 343, + 343, 343, 343, 343, 343, 343, 343, 343, + 343, 343, 343, 343, 343, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 343, + 343, 343, 343, 343, 343, 343, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, + 343, 343, 343, 343, 91, 343, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, + 343, 343, 343, 343, 343, 91, 344, 344, + 344, 344, 344, 344, 344, 344, 344, 344, + 344, 344, 344, 344, 344, 344, 344, 344, + 344, 344, 344, 344, 344, 344, 344, 344, + 344, 344, 344, 344, 344, 344, 344, 344, + 344, 344, 344, 344, 344, 344, 344, 344, + 344, 344, 344, 344, 344, 344, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, + 344, 344, 344, 344, 344, 344, 344, 92, + 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, + 92, 344, 344, 344, 344, 92, 344, 92, + 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, + 92, 344, 344, 344, 344, 344, 92, 345, + 345, 345, 345, 345, 345, 345, 345, 345, + 345, 345, 345, 345, 345, 345, 345, 345, + 345, 345, 345, 345, 345, 345, 345, 345, + 345, 345, 345, 345, 345, 345, 345, 345, + 345, 345, 345, 345, 345, 345, 345, 345, + 345, 345, 345, 345, 345, 345, 345, 94, + 94, 94, 94, 94, 94, 94, 94, 94, + 94, 345, 345, 345, 345, 345, 345, 345, + 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 345, 345, 345, 345, 94, 345, + 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 345, 345, 345, 345, 345, 94, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 346, 346, 346, 346, 346, 346, 346, 346, + 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 346, 346, 346, 346, 346, 346, + 346, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 346, 346, 346, 346, 95, + 346, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 346, 346, 346, 346, 346, + 95, 348, 347, 347, 347, 348, 347, 347, + 347, 347, 349, 350, 349, 349, 349, 347, + 347, 347, 347, 347, 347, 347, 347, 347, + 347, 347, 347, 348, 347, 347, 347, 347, + 347, 349, 347, 349, 351, 349, 349, 349, + 351, 351, 351, 351, 351, 351, 351, 351, + 351, 351, 351, 351, 351, 351, 351, 351, + 351, 351, 349, 351, 353, 353, 353, 353, + 353, 353, 353, 353, 353, 353, 353, 353, + 353, 353, 353, 353, 353, 353, 353, 353, + 353, 353, 353, 353, 353, 353, 352, 352, + 352, 352, 352, 352, 353, 353, 353, 353, + 353, 353, 353, 353, 353, 353, 353, 353, + 353, 353, 353, 353, 353, 353, 353, 353, + 353, 353, 353, 353, 353, 353, 352, 353, + 353, 353, 353, 353, 353, 353, 353, 353, + 353, 353, 353, 353, 353, 353, 353, 353, + 353, 353, 353, 353, 353, 353, 353, 353, + 353, 354, 354, 354, 354, 354, 354, 353, + 353, 353, 353, 353, 353, 353, 353, 353, + 353, 353, 353, 353, 353, 353, 353, 353, + 353, 353, 353, 353, 353, 353, 353, 353, + 353, 354, 355, 97, 356, 356, 356, 356, + 356, 356, 356, 356, 356, 356, 356, 356, + 356, 356, 356, 356, 356, 356, 356, 356, + 356, 356, 356, 356, 356, 356, 356, 356, + 356, 356, 356, 356, 356, 356, 356, 356, + 356, 356, 356, 356, 356, 356, 356, 356, + 356, 356, 356, 356, 356, 356, 356, 356, + 356, 356, 356, 356, 356, 356, 356, 356, + 356, 356, 356, 356, 356, 356, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 356, 356, 356, 356, 357, 356, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 357, 357, 357, 357, 357, 357, 357, 357, + 356, 356, 356, 356, 356, 357, 358, 358, + 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 358, 358, + 358, 358, 358, 358, 358, 358, 359, 359, + 359, 359, 359, 359, 359, 359, 359, 359, + 358, 358, 358, 358, 358, 358, 358, 359, + 359, 359, 359, 359, 359, 359, 359, 359, + 359, 359, 359, 359, 359, 359, 359, 359, + 359, 359, 359, 359, 359, 359, 359, 359, + 359, 358, 358, 358, 358, 359, 358, 359, + 359, 359, 359, 359, 359, 359, 359, 359, + 359, 359, 359, 359, 359, 359, 359, 359, + 359, 359, 359, 359, 359, 359, 359, 359, + 359, 358, 358, 358, 358, 358, 359, 362, + 361, 361, 361, 362, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 361, + 361, 362, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 363, + 363, 363, 363, 363, 363, 363, 363, 361, + 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 364, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 365, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 366, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 361, 361, 361, 361, + 361, 361, 361, 361, 367, 361, 361, 368, + 361, 369, 370, 372, 372, 372, 372, 372, + 372, 372, 372, 371, 373, 373, 373, 373, + 373, 373, 373, 373, 371, 371, 374, 374, + 125, 125, 125, 374, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, + 125, 374, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 126, 125, + 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 375, 125, 376, 377, 378, + 378, 125, 125, 125, 378, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 378, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 126, + 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 379, 125, 124, 378, + 380, 381, 382, 382, 110, 110, 110, 382, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 382, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 111, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 383, + 110, 384, 384, 384, 384, 384, 384, 384, + 384, 384, 384, 382, 382, 382, 382, 382, + 382, 382, 384, 384, 384, 384, 384, 384, + 382, 382, 382, 382, 382, 382, 382, 382, + 382, 382, 382, 382, 382, 382, 382, 382, + 382, 382, 382, 382, 382, 382, 382, 382, + 382, 382, 384, 384, 384, 384, 384, 384, + 382, 386, 386, 386, 386, 386, 386, 386, + 386, 386, 386, 385, 385, 385, 385, 385, + 385, 385, 386, 386, 386, 386, 386, 386, + 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 386, 386, 386, 386, 386, 386, + 385, 385, 387, 387, 387, 387, 387, 387, + 387, 387, 387, 387, 378, 378, 378, 378, + 378, 378, 378, 387, 387, 387, 387, 387, + 387, 378, 378, 378, 378, 378, 378, 378, + 378, 378, 378, 378, 378, 378, 378, 378, + 378, 378, 378, 378, 378, 378, 378, 378, + 378, 378, 378, 387, 387, 387, 387, 387, + 387, 378, 389, 389, 389, 389, 389, 389, + 389, 389, 389, 389, 388, 388, 388, 388, + 388, 388, 388, 389, 389, 389, 389, 389, + 389, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 389, 389, 389, 389, 389, + 389, 388, 388, 378, 103, 103, 103, 378, + 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 378, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, + 390, 103, 374, 110, 110, 110, 374, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 374, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 111, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 112, 110, + 374, 391, 391, 391, 374, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 374, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 392, 391, 393, 394, + 394, 391, 391, 391, 394, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 394, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 391, 391, 391, 391, + 391, 391, 391, 391, 395, 391, 396, 396, + 396, 396, 396, 396, 396, 396, 396, 396, + 394, 394, 394, 394, 394, 394, 394, 396, + 396, 396, 396, 396, 396, 394, 394, 394, + 394, 394, 394, 394, 394, 394, 394, 394, + 394, 394, 394, 394, 394, 394, 394, 394, + 394, 394, 394, 394, 394, 394, 394, 396, + 396, 396, 396, 396, 396, 394, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, + 397, 397, 397, 397, 397, 397, 397, 398, + 398, 398, 398, 398, 398, 397, 397, 397, + 397, 397, 397, 397, 397, 397, 397, 397, + 397, 397, 397, 397, 397, 397, 397, 397, + 397, 397, 397, 397, 397, 397, 397, 398, + 398, 398, 398, 398, 398, 397, 397, 394, + 103, 103, 103, 394, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, + 103, 394, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 390, 103, 399, 394, + 394, 110, 110, 110, 394, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 394, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 111, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 112, 110, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, + 400, 400, 400, 400, 400, 400, 400, 401, + 401, 401, 401, 401, 401, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 401, + 401, 401, 401, 401, 401, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 402, 400, 403, 403, 403, 403, 403, + 403, 403, 403, 403, 403, 400, 400, 400, + 400, 400, 400, 400, 403, 403, 403, 403, + 403, 403, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 403, 403, 403, 403, + 403, 403, 400, 404, 404, 404, 404, 404, + 404, 404, 404, 404, 404, 400, 400, 400, + 400, 400, 400, 400, 404, 404, 404, 404, + 404, 404, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 404, 404, 404, 404, + 404, 404, 400, 405, 405, 405, 405, 405, + 405, 405, 405, 405, 405, 400, 400, 400, + 400, 400, 400, 400, 405, 405, 405, 405, + 405, 405, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 405, 405, 405, 405, + 405, 405, 400, 406, 409, 408, 408, 408, + 409, 408, 408, 408, 408, 410, 408, 408, + 408, 408, 408, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 408, 408, 409, 408, + 408, 408, 408, 408, 410, 408, 408, 408, + 408, 408, 408, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 411, 411, 411, 411, + 411, 411, 411, 411, 411, 411, 408, 408, + 408, 408, 408, 408, 408, 411, 411, 411, + 411, 411, 411, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 408, 411, 411, 411, + 411, 411, 411, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 408, 408, 408, 408, + 408, 412, 408, 409, 408, 408, 408, 409, + 408, 408, 408, 408, 407, 408, 408, 408, + 408, 408, 408, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 408, 409, 408, 408, + 408, 408, 408, 407, 408, 408, 408, 408, + 408, 408, 408, 408, 408, 408, 408, 408, + 408, 408, 408, 413, 413, 413, 413, 413, + 413, 413, 413, 413, 413, 408, 408, 408, + 408, 408, 408, 408, 413, 413, 413, 413, + 413, 413, 408, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 413, 413, 413, 413, + 413, 413, 408, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 408, 408, 408, 408, + 414, 408, 407, 409, 413, 413, 413, 409, + 413, 413, 413, 413, 407, 413, 413, 413, + 413, 413, 413, 413, 413, 413, 413, 413, + 413, 413, 413, 413, 413, 409, 413, 413, + 413, 413, 413, 407, 413, 413, 413, 413, + 413, 413, 413, 413, 413, 413, 413, 413, + 413, 413, 413, 413, 413, 413, 413, 413, + 413, 413, 413, 413, 413, 413, 413, 413, + 413, 413, 413, 413, 413, 413, 413, 413, + 413, 413, 413, 413, 413, 413, 413, 413, + 413, 413, 413, 413, 413, 413, 413, 413, + 413, 413, 413, 413, 413, 413, 413, 413, + 413, 413, 413, 413, 413, 413, 413, 413, + 413, 413, 413, 413, 413, 413, 413, 413, + 413, 413, 413, 413, 413, 413, 413, 413, + 413, 413, 413, 413, 413, 413, 413, 413, + 407, 413, 415, 409, 416, 416, 416, 409, + 416, 416, 416, 416, 410, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 409, 416, 416, + 416, 416, 416, 410, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 417, 417, 417, 417, 417, + 417, 417, 417, 417, 417, 416, 416, 416, + 416, 416, 416, 416, 417, 417, 417, 417, + 417, 417, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 417, 417, 417, 417, + 417, 417, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 407, 416, 409, 416, 416, 416, 409, 416, + 416, 416, 416, 407, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 409, 416, 416, 416, + 416, 416, 407, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 413, 413, 413, 413, 413, 413, + 413, 413, 413, 413, 416, 416, 416, 416, + 416, 416, 416, 413, 413, 413, 413, 413, + 413, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 413, 413, 413, 413, 413, + 413, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 409, + 416, 409, 416, 416, 416, 409, 416, 416, + 416, 416, 418, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 409, 416, 416, 416, 416, + 416, 418, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 419, 419, 419, 419, 419, 419, 419, + 419, 419, 419, 416, 416, 416, 416, 416, + 416, 416, 419, 419, 419, 419, 419, 419, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 419, 419, 419, 419, 419, 419, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 420, 416, + 409, 416, 416, 416, 409, 416, 416, 416, + 416, 418, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 409, 416, 416, 416, 416, 416, + 418, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 417, 417, 417, 417, 417, 417, 417, 417, + 417, 417, 416, 416, 416, 416, 416, 416, + 416, 417, 417, 417, 417, 417, 417, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 417, 417, 417, 417, 417, 417, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 420, 416, 421, + 409, 416, 416, 416, 409, 416, 416, 416, + 416, 418, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 409, 416, 416, 416, 416, 416, + 418, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 422, 422, 422, 422, 422, 422, 422, 422, + 422, 422, 416, 416, 416, 416, 416, 416, + 416, 422, 422, 422, 422, 422, 422, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 422, 422, 422, 422, 422, 422, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 420, 416, 409, + 416, 416, 416, 409, 416, 416, 416, 416, + 418, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 409, 416, 416, 416, 416, 416, 418, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 423, + 423, 423, 423, 423, 423, 423, 423, 423, + 423, 416, 416, 416, 416, 416, 416, 416, + 423, 423, 423, 423, 423, 423, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 423, 423, 423, 423, 423, 423, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 420, 416, 409, 416, + 416, 416, 409, 416, 416, 416, 416, 418, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 409, 416, 416, 416, 416, 416, 418, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 424, 424, + 424, 424, 424, 424, 424, 424, 424, 424, + 416, 416, 416, 416, 416, 416, 416, 424, + 424, 424, 424, 424, 424, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 424, + 424, 424, 424, 424, 424, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 420, 416, 409, 416, 416, + 416, 409, 416, 416, 416, 416, 418, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 409, + 416, 416, 416, 416, 416, 418, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 425, 425, 425, + 425, 425, 425, 425, 425, 425, 425, 416, + 416, 416, 416, 416, 416, 416, 425, 425, + 425, 425, 425, 425, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 425, 425, + 425, 425, 425, 425, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 420, 416, 409, 416, 416, 416, + 409, 416, 416, 416, 416, 418, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 409, 416, + 416, 416, 416, 416, 418, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 426, 426, 426, 426, + 426, 426, 426, 426, 426, 426, 416, 416, + 416, 416, 416, 416, 416, 426, 426, 426, + 426, 426, 426, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 426, 426, 426, + 426, 426, 426, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 420, 416, 409, 416, 416, 416, 409, + 416, 416, 416, 416, 407, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 409, 416, 416, + 416, 416, 416, 407, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 426, 426, 426, 426, 426, + 426, 426, 426, 426, 426, 416, 416, 416, + 416, 416, 416, 416, 426, 426, 426, 426, + 426, 426, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 426, 426, 426, 426, + 426, 426, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 407, 416, 409, 416, 416, 416, 409, 416, + 416, 416, 416, 427, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 409, 416, 416, 416, + 416, 416, 427, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 416, 416, 416, 416, + 416, 416, 416, 428, 428, 428, 428, 428, + 428, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 428, 428, 428, 428, 428, + 428, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 420, + 416, 409, 416, 416, 416, 409, 416, 416, + 416, 416, 427, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 409, 416, 416, 416, 416, + 416, 427, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 429, 429, 429, 429, 429, 429, 429, + 429, 429, 429, 416, 416, 416, 416, 416, + 416, 416, 429, 429, 429, 429, 429, 429, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 429, 429, 429, 429, 429, 429, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 420, 416, + 409, 416, 416, 416, 409, 416, 416, 416, + 416, 427, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 409, 416, 416, 416, 416, 416, + 427, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 430, 430, 430, 430, 430, 430, 430, 430, + 430, 430, 416, 416, 416, 416, 416, 416, + 416, 430, 430, 430, 430, 430, 430, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 430, 430, 430, 430, 430, 430, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 407, 416, 409, + 416, 416, 416, 409, 416, 416, 416, 416, + 427, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 409, 416, 416, 416, 416, 416, 427, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 431, + 431, 431, 431, 431, 431, 431, 431, 431, + 431, 416, 416, 416, 416, 416, 416, 416, + 431, 431, 431, 431, 431, 431, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 431, 431, 431, 431, 431, 431, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 407, 416, 409, 416, + 416, 416, 409, 416, 416, 416, 416, 427, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 409, 416, 416, 416, 416, 416, 427, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 432, 432, + 432, 432, 432, 432, 432, 432, 432, 432, + 416, 416, 416, 416, 416, 416, 416, 432, + 432, 432, 432, 432, 432, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 432, + 432, 432, 432, 432, 432, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 407, 416, 409, 416, 416, + 416, 409, 416, 416, 416, 416, 427, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 409, + 416, 416, 416, 416, 416, 427, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 433, 433, 433, + 433, 433, 433, 433, 433, 433, 433, 416, + 416, 416, 416, 416, 416, 416, 433, 433, + 433, 433, 433, 433, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 433, 433, + 433, 433, 433, 433, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 407, 416, 409, 416, 416, 416, + 409, 416, 416, 416, 416, 427, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 409, 416, + 416, 416, 416, 416, 427, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 434, 434, 434, 434, + 434, 434, 434, 434, 434, 434, 416, 416, + 416, 416, 416, 416, 416, 434, 434, 434, + 434, 434, 434, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 434, 434, 434, + 434, 434, 434, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 407, 416, 409, 416, 416, 416, 409, + 416, 416, 416, 416, 427, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 409, 416, 416, + 416, 416, 416, 427, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 426, 426, 426, 426, 426, + 426, 426, 426, 426, 426, 416, 416, 416, + 416, 416, 416, 416, 426, 426, 426, 426, + 426, 426, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 426, 426, 426, 426, + 426, 426, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 407, 416, 409, 416, 416, 416, 409, 416, + 416, 416, 416, 427, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 409, 416, 416, 416, + 416, 416, 427, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 435, 435, 435, 435, 435, 435, + 435, 435, 435, 435, 416, 416, 416, 416, + 416, 416, 416, 435, 435, 435, 435, 435, + 435, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 435, 435, 435, 435, 435, + 435, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 420, + 416, 409, 416, 416, 416, 409, 416, 416, + 416, 416, 427, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 409, 416, 416, 416, 416, + 416, 427, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 416, 416, 416, 416, 416, + 416, 416, 436, 436, 436, 436, 436, 436, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 436, 436, 436, 436, 436, 436, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 420, 416, + 409, 416, 416, 416, 409, 416, 416, 416, + 416, 427, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 409, 416, 416, 416, 416, 416, + 427, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 437, 437, 437, 437, 437, 437, 437, 437, + 437, 437, 416, 416, 416, 416, 416, 416, + 416, 437, 437, 437, 437, 437, 437, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 437, 437, 437, 437, 437, 437, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 420, 416, 409, + 416, 416, 416, 409, 416, 416, 416, 416, + 427, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 409, 416, 416, 416, 416, 416, 427, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 438, + 438, 438, 438, 438, 438, 438, 438, 438, + 438, 416, 416, 416, 416, 416, 416, 416, + 438, 438, 438, 438, 438, 438, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 438, 438, 438, 438, 438, 438, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 420, 416, 409, 416, + 416, 416, 409, 416, 416, 416, 416, 427, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 409, 416, 416, 416, 416, 416, 427, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 426, 426, + 426, 426, 426, 426, 426, 426, 426, 426, + 416, 416, 416, 416, 416, 416, 416, 426, + 426, 426, 426, 426, 426, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 426, + 426, 426, 426, 426, 426, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 420, 416, 439, 440, 442, + 442, 442, 442, 442, 442, 442, 442, 442, + 442, 441, 441, 441, 441, 441, 441, 441, + 442, 442, 442, 442, 442, 442, 441, 441, + 441, 441, 441, 441, 441, 441, 441, 441, + 441, 441, 441, 441, 441, 441, 441, 441, + 441, 441, 441, 441, 441, 441, 441, 441, + 442, 442, 442, 442, 442, 442, 441, 441, + 0 +] + +class << self + attr_accessor :_lex_trans_targs + private :_lex_trans_targs, :_lex_trans_targs= +end +self._lex_trans_targs = [ + 61, 64, 65, 2, 66, 67, 68, 4, + 69, 70, 61, 77, 78, 81, 82, 94, + 91, 83, 84, 85, 9, 86, 87, 88, + 96, 98, 99, 103, 104, 105, 100, 15, + 8, 79, 80, 17, 128, 129, 131, 133, + 134, 20, 135, 136, 137, 22, 138, 139, + 131, 146, 147, 150, 151, 163, 160, 152, + 153, 154, 27, 155, 156, 157, 165, 167, + 168, 172, 173, 174, 169, 33, 26, 148, + 149, 35, 197, 198, 205, 207, 208, 38, + 209, 210, 211, 40, 212, 213, 215, 218, + 219, 42, 220, 221, 222, 44, 223, 224, + 230, 0, 229, 229, 231, 233, 229, 239, + 240, 243, 244, 256, 253, 245, 246, 247, + 50, 248, 249, 250, 258, 260, 261, 265, + 266, 267, 262, 56, 49, 241, 242, 58, + 303, 304, 60, 61, 61, 62, 61, 63, + 71, 61, 61, 1, 3, 61, 61, 61, + 61, 61, 61, 61, 72, 73, 74, 5, + 11, 16, 106, 18, 61, 61, 61, 75, + 76, 61, 6, 61, 61, 61, 7, 61, + 61, 61, 10, 89, 61, 90, 92, 61, + 93, 95, 97, 12, 61, 61, 13, 101, + 61, 102, 14, 61, 107, 111, 108, 109, + 110, 61, 61, 112, 113, 116, 118, 127, + 114, 115, 61, 117, 119, 121, 120, 61, + 122, 123, 124, 125, 126, 61, 61, 61, + 130, 131, 131, 131, 132, 140, 131, 19, + 21, 131, 131, 131, 131, 131, 131, 131, + 141, 142, 143, 23, 29, 34, 175, 36, + 131, 131, 131, 144, 145, 131, 24, 131, + 131, 131, 25, 131, 131, 131, 28, 158, + 131, 159, 161, 131, 162, 164, 166, 30, + 131, 131, 31, 170, 131, 171, 32, 131, + 176, 180, 177, 178, 179, 131, 131, 181, + 182, 185, 187, 196, 183, 184, 131, 186, + 188, 190, 189, 131, 191, 192, 193, 194, + 195, 131, 131, 131, 199, 200, 200, 201, + 200, 202, 200, 200, 200, 203, 203, 203, + 204, 203, 203, 203, 205, 205, 205, 206, + 205, 37, 39, 205, 205, 205, 205, 205, + 205, 214, 214, 214, 215, 215, 216, 215, + 217, 215, 215, 41, 43, 215, 215, 215, + 215, 215, 215, 225, 225, 226, 225, 225, + 227, 228, 227, 45, 229, 232, 229, 232, + 229, 234, 235, 236, 46, 52, 57, 268, + 59, 229, 229, 229, 237, 238, 229, 47, + 229, 229, 229, 48, 229, 229, 229, 51, + 251, 229, 252, 254, 229, 255, 257, 259, + 53, 229, 229, 54, 263, 229, 264, 55, + 229, 269, 273, 270, 271, 272, 229, 229, + 274, 275, 278, 289, 302, 276, 277, 229, + 279, 280, 281, 283, 282, 229, 284, 285, + 286, 287, 288, 290, 297, 291, 292, 293, + 294, 295, 296, 298, 299, 300, 301, 229, + 229, 229, 305 +] + +class << self + attr_accessor :_lex_trans_actions + private :_lex_trans_actions, :_lex_trans_actions= +end +self._lex_trans_actions = [ + 25, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 23, 0, 11, 0, 301, 0, + 0, 11, 0, 0, 0, 0, 301, 0, + 11, 0, 301, 0, 11, 11, 0, 0, + 0, 0, 0, 0, 0, 0, 37, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 35, 0, 11, 0, 301, 0, 0, 11, + 0, 0, 0, 0, 301, 0, 11, 0, + 301, 0, 11, 11, 0, 0, 0, 0, + 0, 0, 0, 0, 61, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 77, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 89, 121, 0, 11, 93, 0, + 11, 0, 301, 0, 0, 11, 0, 0, + 0, 0, 301, 0, 11, 0, 301, 0, + 11, 11, 0, 0, 0, 0, 0, 0, + 0, 0, 95, 17, 15, 0, 97, 11, + 11, 19, 21, 0, 0, 13, 238, 277, + 274, 253, 250, 392, 3, 3, 3, 3, + 3, 3, 3, 3, 133, 223, 160, 0, + 0, 142, 0, 332, 151, 308, 0, 419, + 356, 404, 0, 0, 449, 0, 0, 368, + 0, 11, 0, 0, 344, 320, 0, 0, + 434, 0, 1, 196, 0, 0, 0, 0, + 0, 187, 214, 0, 0, 0, 0, 0, + 0, 0, 380, 0, 0, 0, 0, 124, + 0, 0, 0, 0, 0, 205, 178, 169, + 0, 31, 29, 100, 11, 11, 33, 0, + 0, 27, 241, 283, 280, 259, 256, 396, + 3, 3, 3, 3, 3, 3, 3, 3, + 136, 226, 163, 0, 0, 145, 0, 336, + 154, 312, 0, 424, 360, 409, 0, 0, + 454, 0, 0, 372, 0, 11, 0, 0, + 348, 324, 0, 0, 439, 0, 1, 199, + 0, 0, 0, 0, 0, 190, 217, 0, + 0, 0, 0, 0, 0, 0, 384, 0, + 0, 0, 0, 127, 0, 0, 0, 0, + 0, 208, 181, 172, 0, 41, 39, 0, + 103, 0, 43, 45, 232, 49, 47, 106, + 0, 51, 235, 304, 57, 55, 109, 11, + 59, 0, 0, 53, 244, 289, 286, 265, + 262, 65, 63, 112, 71, 69, 0, 115, + 11, 73, 75, 0, 0, 67, 247, 295, + 292, 271, 268, 81, 79, 0, 118, 83, + 85, 0, 87, 0, 298, 5, 91, 0, + 400, 3, 3, 3, 3, 3, 3, 3, + 3, 139, 229, 166, 0, 0, 148, 0, + 340, 157, 316, 0, 429, 364, 414, 0, + 0, 459, 0, 0, 376, 0, 11, 0, + 0, 352, 328, 0, 0, 444, 0, 1, + 202, 0, 0, 0, 0, 0, 193, 220, + 0, 0, 0, 0, 0, 0, 0, 388, + 0, 0, 0, 0, 0, 130, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 211, + 184, 175, 0 +] + +class << self + attr_accessor :_lex_to_state_actions + private :_lex_to_state_actions, :_lex_to_state_actions= +end +self._lex_to_state_actions = [ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 7, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 7, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 0, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 7, 0, 7, 0, 7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0 +] + +class << self + attr_accessor :_lex_from_state_actions + private :_lex_from_state_actions, :_lex_from_state_actions= +end +self._lex_from_state_actions = [ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 9, 0, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 9, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 9, 0, 9, 0, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0 +] + +class << self + attr_accessor :_lex_eof_trans + private :_lex_eof_trans, :_lex_eof_trans= +end +self._lex_eof_trans = [ + 0, 1, 1, 1, 1, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 39, 39, 39, 39, 49, + 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 77, 77, 77, + 77, 87, 87, 87, 87, 0, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 103, 103, 0, 0, 138, 139, + 143, 143, 143, 144, 145, 146, 147, 148, + 157, 158, 159, 159, 159, 162, 162, 164, + 165, 166, 166, 166, 168, 169, 170, 170, + 170, 173, 173, 166, 176, 176, 166, 162, + 162, 181, 182, 182, 182, 185, 185, 182, + 182, 182, 188, 188, 188, 188, 194, 195, + 195, 195, 195, 203, 195, 195, 195, 195, + 208, 195, 195, 195, 195, 195, 195, 214, + 215, 216, 216, 0, 223, 227, 227, 227, + 228, 229, 230, 231, 232, 241, 242, 243, + 243, 243, 246, 246, 248, 249, 250, 250, + 250, 252, 253, 254, 254, 254, 257, 257, + 250, 260, 260, 250, 246, 246, 265, 266, + 266, 266, 269, 269, 266, 266, 266, 272, + 272, 272, 272, 278, 279, 279, 279, 279, + 287, 279, 279, 279, 279, 292, 279, 279, + 279, 279, 279, 279, 298, 299, 300, 300, + 0, 307, 308, 0, 314, 0, 321, 325, + 325, 325, 326, 327, 328, 329, 0, 0, + 338, 339, 343, 343, 343, 344, 345, 346, + 347, 0, 352, 0, 355, 0, 357, 357, + 359, 361, 370, 371, 372, 372, 372, 375, + 375, 377, 378, 379, 379, 379, 381, 382, + 383, 383, 383, 386, 386, 379, 389, 389, + 379, 375, 375, 394, 395, 395, 395, 398, + 398, 395, 395, 395, 401, 401, 401, 401, + 407, 408, 408, 408, 408, 416, 408, 408, + 408, 408, 422, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 408, 408, 440, 441, + 442, 442 +] + +class << self + attr_accessor :lex_start +end +self.lex_start = 60; +class << self + attr_accessor :lex_error +end +self.lex_error = 0; + +class << self + attr_accessor :lex_en_interp_words +end +self.lex_en_interp_words = 61; +class << self + attr_accessor :lex_en_interp_string +end +self.lex_en_interp_string = 131; +class << self + attr_accessor :lex_en_plain_words +end +self.lex_en_plain_words = 200; +class << self + attr_accessor :lex_en_plain_string +end +self.lex_en_plain_string = 203; +class << self + attr_accessor :lex_en_interp_backslash_delimited +end +self.lex_en_interp_backslash_delimited = 205; +class << self + attr_accessor :lex_en_plain_backslash_delimited +end +self.lex_en_plain_backslash_delimited = 214; +class << self + attr_accessor :lex_en_interp_backslash_delimited_words +end +self.lex_en_interp_backslash_delimited_words = 215; +class << self + attr_accessor :lex_en_plain_backslash_delimited_words +end +self.lex_en_plain_backslash_delimited_words = 225; +class << self + attr_accessor :lex_en_regexp_modifiers +end +self.lex_en_regexp_modifiers = 227; +class << self + attr_accessor :lex_en_character +end +self.lex_en_character = 229; +class << self + attr_accessor :lex_en_unknown +end +self.lex_en_unknown = 60; + + +# line 6 "lib/parser/lexer-strings.rl" + # % + + ESCAPES = { + ?a.ord => "\a", ?b.ord => "\b", ?e.ord => "\e", ?f.ord => "\f", + ?n.ord => "\n", ?r.ord => "\r", ?s.ord => "\s", ?t.ord => "\t", + ?v.ord => "\v", ?\\.ord => "\\" + }.freeze + + REGEXP_META_CHARACTERS = Regexp.union(*"\\$()*+.<>?[]^{|}".chars).freeze + + attr_accessor :herebody_s + + # Set by "main" lexer + attr_accessor :source_buffer, :source_pts + + def initialize(lexer, version) + @lexer = lexer + @version = version + + @_lex_actions = + if self.class.respond_to?(:_lex_actions, true) + self.class.send :_lex_actions + else + [] + end + + reset + end + + def reset + @cs = self.class.lex_en_unknown + @literal_stack = [] + + @escape_s = nil # starting position of current sequence + @escape = nil # last escaped sequence, as string + + @herebody_s = nil # starting position of current heredoc line + + # After encountering the closing line of <<~SQUIGGLY_HEREDOC, + # we store the indentation level and give it out to the parser + # on request. It is not possible to infer indentation level just + # from the AST because escape sequences such as `\ ` or `\t` are + # expanded inside the lexer, but count as non-whitespace for + # indentation purposes. + @dedent_level = nil + end + + LEX_STATES = { + :interp_string => lex_en_interp_string, + :interp_words => lex_en_interp_words, + :plain_string => lex_en_plain_string, + :plain_words => lex_en_plain_string, + } + + def advance(p) + # Ugly, but dependent on Ragel output. Consider refactoring it somehow. + klass = self.class + _lex_trans_keys = klass.send :_lex_trans_keys + _lex_key_spans = klass.send :_lex_key_spans + _lex_index_offsets = klass.send :_lex_index_offsets + _lex_indicies = klass.send :_lex_indicies + _lex_trans_targs = klass.send :_lex_trans_targs + _lex_trans_actions = klass.send :_lex_trans_actions + _lex_to_state_actions = klass.send :_lex_to_state_actions + _lex_from_state_actions = klass.send :_lex_from_state_actions + _lex_eof_trans = klass.send :_lex_eof_trans + _lex_actions = @_lex_actions + + pe = source_pts.size + 2 + eof = pe + + +# line 3357 "lib/parser/lexer-strings.rb" +begin # ragel flat + testEof = false + _slen, _trans, _keys, _inds, _acts, _nacts = nil + _goto_level = 0 + _resume = 10 + _eof_trans = 15 + _again = 20 + _test_eof = 30 + _out = 40 + while true + _trigger_goto = false + if _goto_level <= 0 + if p == pe + _goto_level = _test_eof + next + end + if @cs == 0 + _goto_level = _out + next + end + end + if _goto_level <= _resume + _acts = _lex_from_state_actions[ @cs] + _nacts = _lex_actions[_acts] + _acts += 1 + while _nacts > 0 + _nacts -= 1 + _acts += 1 + case _lex_actions[_acts - 1] + when 24 then +# line 1 "NONE" + begin + @ts = p + end +# line 3392 "lib/parser/lexer-strings.rb" + end # from state action switch + end + if _trigger_goto + next + end + _keys = @cs << 1 + _inds = _lex_index_offsets[ @cs] + _slen = _lex_key_spans[ @cs] + _wide = ( (source_pts[p] || 0)) + _trans = if ( _slen > 0 && + _lex_trans_keys[_keys] <= _wide && + _wide <= _lex_trans_keys[_keys + 1] + ) then + _lex_indicies[ _inds + _wide - _lex_trans_keys[_keys] ] + else + _lex_indicies[ _inds + _slen ] + end + end + if _goto_level <= _eof_trans + @cs = _lex_trans_targs[_trans] + if _lex_trans_actions[_trans] != 0 + _acts = _lex_trans_actions[_trans] + _nacts = _lex_actions[_acts] + _acts += 1 + while _nacts > 0 + _nacts -= 1 + _acts += 1 + case _lex_actions[_acts - 1] + when 0 then +# line 534 "lib/parser/lexer-strings.rl" + begin + + # Record position of a newline for precise location reporting on tNL + # tokens. + # + # This action is embedded directly into c_nl, as it is idempotent and + # there are no cases when we need to skip it. + @newline_s = p + end + when 1 then +# line 590 "lib/parser/lexer-strings.rl" + begin + + unicode_points(p) + end + when 2 then +# line 594 "lib/parser/lexer-strings.rl" + begin + + unescape_char(p) + end + when 3 then +# line 598 "lib/parser/lexer-strings.rl" + begin + + diagnostic :fatal, :invalid_escape + end + when 4 then +# line 602 "lib/parser/lexer-strings.rl" + begin + + read_post_meta_or_ctrl_char(p) + end + when 5 then +# line 606 "lib/parser/lexer-strings.rl" + begin + + slash_c_char + end + when 6 then +# line 610 "lib/parser/lexer-strings.rl" + begin + + slash_m_char + end + when 7 then +# line 616 "lib/parser/lexer-strings.rl" + begin + encode_escaped_char(p) end + when 8 then +# line 622 "lib/parser/lexer-strings.rl" + begin + @escape = "\x7f" end + when 9 then +# line 623 "lib/parser/lexer-strings.rl" + begin + encode_escaped_char(p) end + when 10 then +# line 630 "lib/parser/lexer-strings.rl" + begin + @escape = encode_escape(tok(@escape_s, p).to_i(8) % 0x100) end + when 11 then +# line 634 "lib/parser/lexer-strings.rl" + begin + @escape = encode_escape(tok(@escape_s + 1, p).to_i(16)) end + when 12 then +# line 638 "lib/parser/lexer-strings.rl" + begin + + diagnostic :fatal, :invalid_hex_escape, nil, range(@escape_s - 1, p + 2) + end + when 13 then +# line 644 "lib/parser/lexer-strings.rl" + begin + @escape = tok(@escape_s + 1, p).to_i(16).chr(Encoding::UTF_8) end + when 14 then +# line 648 "lib/parser/lexer-strings.rl" + begin + + check_invalid_escapes(p) + end + when 15 then +# line 654 "lib/parser/lexer-strings.rl" + begin + + check_invalid_escapes(p) + end + when 16 then +# line 668 "lib/parser/lexer-strings.rl" + begin + + diagnostic :fatal, :unterminated_unicode, nil, range(p - 1, p) + end + when 17 then +# line 694 "lib/parser/lexer-strings.rl" + begin + + diagnostic :fatal, :escape_eof, nil, range(p - 1, p) + end + when 18 then +# line 700 "lib/parser/lexer-strings.rl" + begin + + @escape_s = p + @escape = nil + end + when 19 then +# line 817 "lib/parser/lexer-strings.rl" + begin + interp_var_kind = :gvar end + when 20 then +# line 818 "lib/parser/lexer-strings.rl" + begin + interp_var_kind = :cvar end + when 21 then +# line 819 "lib/parser/lexer-strings.rl" + begin + interp_var_kind = :ivar end + when 22 then +# line 953 "lib/parser/lexer-strings.rl" + begin + @escape = nil end + when 25 then +# line 1 "NONE" + begin + @te = p+1 + end + when 26 then +# line 851 "lib/parser/lexer-strings.rl" + begin + @te = p+1 + begin + current_literal = literal + extend_interp_code(current_literal) + @root_lexer_state = @lexer.class.lex_en_expr_value; + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 27 then +# line 770 "lib/parser/lexer-strings.rl" + begin + @te = p+1 + begin + current_literal = literal + extend_string_eol_check_eof(current_literal, pe) + + if current_literal.heredoc? + line = extend_string_eol_heredoc_line + + # Try ending the heredoc with the complete most recently + # scanned line. @herebody_s always refers to the start of such line. + if current_literal.nest_and_try_closing(line, @herebody_s, @ts) + # Adjust @herebody_s to point to the next line. + @herebody_s = @te + + # Continue regular lexing after the heredoc reference (< unknown_options.join } + end + + emit(:tREGEXP_OPT) + @root_lexer_state = @lexer.class.lex_en_expr_end; + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 77 then +# line 962 "lib/parser/lexer-strings.rl" + begin + @te = p+1 + begin + escape = ESCAPE_WHITESPACE[source_buffer.slice(@ts + 1, 1)] + diagnostic :warning, :invalid_escape_use, { :escape => escape }, range + + p = @ts - 1 + @root_lexer_state = @lexer.class.lex_en_expr_end; + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 78 then +# line 955 "lib/parser/lexer-strings.rl" + begin + @te = p +p = p - 1; begin + emit_character_constant + + @root_lexer_state = @lexer.class.lex_en_expr_end; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 79 then +# line 973 "lib/parser/lexer-strings.rl" + begin + @te = p +p = p - 1; begin + p = @ts - 1 + @root_lexer_state = @lexer.class.lex_en_expr_end; + begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 80 then +# line 955 "lib/parser/lexer-strings.rl" + begin + begin p = (( @te))-1; end + begin + emit_character_constant + + @root_lexer_state = @lexer.class.lex_en_expr_end; begin + p += 1 + _trigger_goto = true + _goto_level = _out + break + end + + end + end + when 81 then +# line 981 "lib/parser/lexer-strings.rl" + begin + @te = p+1 + begin raise 'bug' end + end +# line 4935 "lib/parser/lexer-strings.rb" + end # action switch + end + end + if _trigger_goto + next + end + end + if _goto_level <= _again + _acts = _lex_to_state_actions[ @cs] + _nacts = _lex_actions[_acts] + _acts += 1 + while _nacts > 0 + _nacts -= 1 + _acts += 1 + case _lex_actions[_acts - 1] + when 23 then +# line 1 "NONE" + begin + @ts = nil; end +# line 4955 "lib/parser/lexer-strings.rb" + end # to state action switch + end + if _trigger_goto + next + end + if @cs == 0 + _goto_level = _out + next + end + p += 1 + if p != pe + _goto_level = _resume + next + end + end + if _goto_level <= _test_eof + if p == eof + if _lex_eof_trans[ @cs] > 0 + _trans = _lex_eof_trans[ @cs] - 1; + _goto_level = _eof_trans + next; + end + end + end + if _goto_level <= _out + break + end + end + end + +# line 78 "lib/parser/lexer-strings.rl" + # % + + # Ragel creates a local variable called `testEof` but it doesn't use + # it in any assignment. This dead code is here to swallow the warning. + # It has no runtime cost because Ruby doesn't produce any instructions from it. + if false + testEof + end + + [p, @root_lexer_state] + end + + def read_character_constant(p) + @cs = self.class.lex_en_character + + advance(p) + end + + # + # === LITERAL STACK === + # + + def push_literal(*args) + new_literal = Parser::Lexer::Literal.new(self, *args) + @literal_stack.push(new_literal) + @cs = next_state_for_literal(new_literal) + end + + def next_state_for_literal(literal) + if literal.words? && literal.backslash_delimited? + if literal.interpolate? + self.class.lex_en_interp_backslash_delimited_words + else + self.class.lex_en_plain_backslash_delimited_words + end + elsif literal.words? && !literal.backslash_delimited? + if literal.interpolate? + self.class.lex_en_interp_words + else + self.class.lex_en_plain_words + end + elsif !literal.words? && literal.backslash_delimited? + if literal.interpolate? + self.class.lex_en_interp_backslash_delimited + else + self.class.lex_en_plain_backslash_delimited + end + else + if literal.interpolate? + self.class.lex_en_interp_string + else + self.class.lex_en_plain_string + end + end + end + + def continue_lexing(current_literal) + @cs = next_state_for_literal(current_literal) + end + + def literal + @literal_stack.last + end + + def pop_literal + old_literal = @literal_stack.pop + + @dedent_level = old_literal.dedent_level + + if old_literal.type == :tREGEXP_BEG + @root_lexer_state = @lexer.class.lex_en_inside_string + + # Fetch modifiers. + self.class.lex_en_regexp_modifiers + else + @root_lexer_state = @lexer.class.lex_en_expr_end + + # Do nothing, yield to main lexer + nil + end + end + + def close_interp_on_current_literal(p) + current_literal = literal + if current_literal + if current_literal.end_interp_brace_and_try_closing + if version?(18, 19) + emit(:tRCURLY, '}'.freeze, p - 1, p) + @lexer.cond.lexpop + @lexer.cmdarg.lexpop + else + emit(:tSTRING_DEND, '}'.freeze, p - 1, p) + end + + if current_literal.saved_herebody_s + @herebody_s = current_literal.saved_herebody_s + end + + continue_lexing(current_literal) + + return true + end + end + end + + def dedent_level + # We erase @dedent_level as a precaution to avoid accidentally + # using a stale value. + dedent_level, @dedent_level = @dedent_level, nil + dedent_level + end + + # This hook is triggered by "main" lexer on every newline character + def on_newline(p) + # After every heredoc was parsed, @herebody_s contains the + # position of next token after all heredocs. + if @herebody_s + p = @herebody_s + @herebody_s = nil + end + p + end + + protected + + def eof_codepoint?(point) + [0x04, 0x1a, 0x00].include? point + end + + def version?(*versions) + versions.include?(@version) + end + + def tok(s = @ts, e = @te) + @source_buffer.slice(s, e - s) + end + + def range(s = @ts, e = @te) + Parser::Source::Range.new(@source_buffer, s, e) + end + + def emit(type, value = tok, s = @ts, e = @te) + @lexer.send(:emit, type, value, s, e) + end + + def diagnostic(type, reason, arguments=nil, location=range, highlights=[]) + @lexer.send(:diagnostic, type, reason, arguments, location, highlights) + end + + def cond + @lexer.cond + end + + def emit_invalid_escapes? + # always true for old Rubies + return true if @version < 32 + + # in "?\u123" case we don't push any literals + # but we always emit invalid escapes + return true if literal.nil? + + # Ruby >= 32, regexp, exceptional case + !literal.regexp? + end + + # String escaping + + def extend_string_escaped + current_literal = literal + # Get the first character after the backslash. + escaped_char = source_buffer.slice(@escape_s, 1).chr + + if current_literal.munge_escape? escaped_char + # If this particular literal uses this character as an opening + # or closing delimiter, it is an escape sequence for that + # particular character. Write it without the backslash. + + if current_literal.regexp? && REGEXP_META_CHARACTERS.match(escaped_char) + # Regular expressions should include escaped delimiters in their + # escaped form, except when the escaped character is + # a closing delimiter but not a regexp metacharacter. + # + # The backslash itself cannot be used as a closing delimiter + # at the same time as an escape symbol, but it is always munged, + # so this branch also executes for the non-closing-delimiter case + # for the backslash. + current_literal.extend_string(tok, @ts, @te) + else + current_literal.extend_string(escaped_char, @ts, @te) + end + else + # It does not. So this is an actual escape sequence, yay! + if current_literal.squiggly_heredoc? && escaped_char == "\n".freeze + # Squiggly heredocs like + # <<~-HERE + # 1\ + # 2 + # HERE + # treat '\' as a line continuation, but still dedent the body, so the heredoc above becomes "12\n". + # This information is emitted as is, without escaping, + # later this escape sequence (\\\n) gets handled manually in the Lexer::Dedenter + current_literal.extend_string(tok, @ts, @te) + elsif current_literal.supports_line_continuation_via_slash? && escaped_char == "\n".freeze + # Heredocs, regexp and a few other types of literals support line + # continuation via \\\n sequence. The code like + # "a\ + # b" + # must be parsed as "ab" + current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) + elsif current_literal.regexp? && @version >= 31 && %w[c C m M].include?(escaped_char) + # Ruby >= 3.1 escapes \c- and \m chars, that's the only escape sequence + # supported by regexes so far, so it needs a separate branch. + current_literal.extend_string(@escape, @ts, @te) + elsif current_literal.regexp? + # Regular expressions should include escape sequences in their + # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x") + current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te) + else + current_literal.extend_string(@escape || tok, @ts, @te) + end + end + end + + def extend_interp_code(current_literal) + current_literal.flush_string + current_literal.extend_content + + emit(:tSTRING_DBEG, '#{'.freeze) + + if current_literal.heredoc? + current_literal.saved_herebody_s = @herebody_s + @herebody_s = nil + end + + current_literal.start_interp_brace + @lexer.command_start = true + end + + def extend_interp_digit_var + if @version >= 27 + literal.extend_string(tok, @ts, @te) + else + message = tok.start_with?('#@@') ? :cvar_name : :ivar_name + diagnostic :error, message, { :name => tok(@ts + 1, @te) }, range(@ts + 1, @te) + end + end + + def extend_string_eol_check_eof(current_literal, pe) + if @te == pe + diagnostic :fatal, :string_eof, nil, + range(current_literal.str_s, current_literal.str_s + 1) + end + end + + def extend_string_eol_heredoc_line + line = tok(@herebody_s, @ts).gsub(/\r+$/, ''.freeze) + + if version?(18, 19, 20) + # See ruby:c48b4209c + line = line.gsub(/\r.*$/, ''.freeze) + end + line + end + + def extend_string_eol_heredoc_intertwined(p) + if @herebody_s + # This is a regular literal intertwined with a heredoc. Like: + # + # p <<-foo+"1 + # bar + # foo + # 2" + # + # which, incidentally, evaluates to "bar\n1\n2". + p = @herebody_s - 1 + @herebody_s = nil + end + p + end + + def extend_string_eol_words(current_literal, p) + if current_literal.words? && !eof_codepoint?(source_pts[p]) + current_literal.extend_space @ts, @te + else + # A literal newline is appended if the heredoc was _not_ closed + # this time (see fbreak above). See also Literal#nest_and_try_closing + # for rationale of calling #flush_string here. + current_literal.extend_string tok, @ts, @te + current_literal.flush_string + end + end + + def extend_string_slice_end(lookahead) + # tLABEL_END is only possible in non-cond context on >= 2.2 + if @version >= 22 && !cond.active? + lookahead = source_buffer.slice(@te, 2) + end + lookahead + end + + def extend_string_for_token_range(current_literal, string) + current_literal.extend_string(string, @ts, @te) + end + + def encode_escape(ord) + ord.chr.force_encoding(source_buffer.source.encoding) + end + + def unescape_char(p) + codepoint = source_pts[p - 1] + + if @version >= 30 && (codepoint == 117 || codepoint == 85) # 'u' or 'U' + diagnostic :fatal, :invalid_escape + end + + if (@escape = ESCAPES[codepoint]).nil? + @escape = encode_escape(source_buffer.slice(p - 1, 1)) + end + end + + def unicode_points(p) + @escape = "" + + codepoints = tok(@escape_s + 2, p - 1) + codepoint_s = @escape_s + 2 + + if @version < 24 + if codepoints.start_with?(" ") || codepoints.start_with?("\t") + diagnostic :fatal, :invalid_unicode_escape, nil, + range(@escape_s + 2, @escape_s + 3) + end + + if spaces_p = codepoints.index(/[ \t]{2}/) + diagnostic :fatal, :invalid_unicode_escape, nil, + range(codepoint_s + spaces_p + 1, codepoint_s + spaces_p + 2) + end + + if codepoints.end_with?(" ") || codepoints.end_with?("\t") + diagnostic :fatal, :invalid_unicode_escape, nil, range(p - 1, p) + end + end + + codepoints.scan(/([0-9a-fA-F]+)|([ \t]+)/).each do |(codepoint_str, spaces)| + if spaces + codepoint_s += spaces.length + else + codepoint = codepoint_str.to_i(16) + + if codepoint >= 0x110000 + diagnostic :error, :unicode_point_too_large, nil, + range(codepoint_s, codepoint_s + codepoint_str.length) + break + end + + # UTF-16 surrogate pairs. These are actually accepted before Ruby 2.4 + # but can't be represented in the AST. Make them a syntax error in + # all versions instead, Ruby would raise an exception otherwise. + if codepoint & 0xfffff800 == 0xd800 + diagnostic :error, :invalid_unicode_escape, nil, + range(codepoint_s, codepoint_s + codepoint_str.length) + break + end + + @escape += codepoint.chr(Encoding::UTF_8) + codepoint_s += codepoint_str.length + end + end + end + + def read_post_meta_or_ctrl_char(p) + @escape = source_buffer.slice(p - 1, 1).chr + + if @version >= 27 && ((0..8).include?(@escape.ord) || (14..31).include?(@escape.ord)) + diagnostic :fatal, :invalid_escape + end + end + + def extend_interp_var(current_literal) + current_literal.flush_string + current_literal.extend_content + + emit(:tSTRING_DVAR, nil, @ts, @ts + 1) + + @ts + end + + def emit_interp_var(interp_var_kind) + case interp_var_kind + when :cvar + @lexer.send(:emit_class_var, @ts + 1, @te) + when :ivar + @lexer.send(:emit_instance_var, @ts + 1, @te) + when :gvar + @lexer.send(:emit_global_var, @ts + 1, @te) + end + end + + def encode_escaped_char(p) + @escape = encode_escape(tok(p - 2, p).to_i(16)) + end + + def slash_c_char + @escape = encode_escape(@escape[0].ord & 0x9f) + end + + def slash_m_char + @escape = encode_escape(@escape[0].ord | 0x80) + end + + def emit_character_constant + value = @escape || tok(@ts + 1) + + if version?(18) + emit(:tINTEGER, value.getbyte(0)) + else + emit(:tCHARACTER, value) + end + end + + def check_ambiguous_slash(tm) + if tok(tm, tm + 1) == '/'.freeze + # Ambiguous regexp literal. + if @version < 30 + diagnostic :warning, :ambiguous_literal, nil, range(tm, tm + 1) + else + diagnostic :warning, :ambiguous_regexp, nil, range(tm, tm + 1) + end + end + end + + def check_invalid_escapes(p) + if emit_invalid_escapes? + diagnostic :fatal, :invalid_unicode_escape, nil, range(@escape_s - 1, p) + end + end + + ESCAPE_WHITESPACE = { + " " => '\s', "\r" => '\r', "\n" => '\n', "\t" => '\t', + "\v" => '\v', "\f" => '\f' + } + + +# line 984 "lib/parser/lexer-strings.rl" + + # % + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/lexer/dedenter.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/lexer/dedenter.rb new file mode 100644 index 00000000..5746cff6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/lexer/dedenter.rb @@ -0,0 +1,88 @@ +# frozen_string_literal: true + +module Parser + + class Lexer::Dedenter + # Tab (\t) counts as 8 spaces + TAB_WIDTH = 8 + + def initialize(dedent_level) + @dedent_level = dedent_level + @at_line_begin = true + @indent_level = 0 + end + + # For a heredoc like + # <<-HERE + # a + # b + # HERE + # this method gets called with " a\n" and " b\n" + # + # However, the following heredoc: + # + # <<-HERE + # a\ + # b + # HERE + # calls this method only once with a string " a\\\n b\n" + # + # This is important because technically it's a single line, + # but it has to be concatenated __after__ dedenting. + # + # It has no effect for non-squiggly heredocs, i.e. it simply removes "\\\n" + # Of course, lexer could do it but once again: it's all because of dedenting. + # + def dedent(string) + original_encoding = string.encoding + # Prevent the following error when processing binary encoded source. + # "\xC0".split # => ArgumentError (invalid byte sequence in UTF-8) + lines = string.force_encoding(Encoding::BINARY).split("\\\n") + if lines.length == 1 + # If the line continuation sequence was found but there is no second + # line, it was not really a line continuation and must be ignored. + lines = [string.force_encoding(original_encoding)] + else + lines.map! {|s| s.force_encoding(original_encoding) } + end + + if @at_line_begin + lines_to_dedent = lines + else + _first, *lines_to_dedent = lines + end + + lines_to_dedent.each do |line| + left_to_remove = @dedent_level + remove = 0 + + line.each_char do |char| + break if left_to_remove <= 0 + case char + when ?\s + remove += 1 + left_to_remove -= 1 + when ?\t + break if TAB_WIDTH * (remove / TAB_WIDTH + 1) > @dedent_level + remove += 1 + left_to_remove -= TAB_WIDTH + else + # no more spaces or tabs + break + end + end + + line.slice!(0, remove) + end + + string.replace(lines.join) + + @at_line_begin = string.end_with?("\n") + end + + def interrupt + @at_line_begin = false + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/lexer/explanation.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/lexer/explanation.rb new file mode 100644 index 00000000..2ca384c5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/lexer/explanation.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +module Parser + + module Lexer::Explanation + + def self.included(klass) + klass.class_exec do + alias_method :state_before_explanation=, :state= + alias_method :advance_before_explanation, :advance + + remove_method :state=, :advance + end + end + + # Like #advance, but also pretty-print the token and its position + # in the stream to `stdout`. + def advance + type, (val, range) = advance_before_explanation + + more = "(in-kwarg)" if @context.in_kwarg + + puts decorate(range, + Color.green("#{type} #{val.inspect}"), + "#{state.to_s.ljust(12)} #{@cond} #{@cmdarg} #{more}") + + [ type, [val, range] ] + end + + def state=(new_state) + puts " #{Color.yellow(">>> STATE SET <<<", bold: true)} " + + "#{new_state.to_s.ljust(12)} #{@cond} #{@cmdarg}".rjust(66) + + self.state_before_explanation = new_state + end + + private + + def decorate(range, token, info) + from, to = range.begin.column, range.end.column + + line = range.source_line + ' ' + line[from...to] = Color.underline(line[from...to]) + + tail_len = to - from - 1 + tail = '~' * (tail_len >= 0 ? tail_len : 0) + decoration = "#{" " * from}#{Color.red("^#{tail}", bold: true)} #{token} ". + ljust(68) + info + + [ line, decoration ] + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/lexer/literal.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/lexer/literal.rb new file mode 100644 index 00000000..537d32ea --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/lexer/literal.rb @@ -0,0 +1,284 @@ +# encoding: binary +# frozen_string_literal: true + +module Parser + + class Lexer::Literal + DELIMITERS = { '(' => ')', '[' => ']', '{' => '}', '<' => '>' } + SPACE = ' '.ord + TAB = "\t".ord + + TYPES = { + # type start token interpolate? + "'" => [ :tSTRING_BEG, false ], + "<<'" => [ :tSTRING_BEG, false ], + '%q' => [ :tSTRING_BEG, false ], + '"' => [ :tSTRING_BEG, true ], + '<<"' => [ :tSTRING_BEG, true ], + '%' => [ :tSTRING_BEG, true ], + '%Q' => [ :tSTRING_BEG, true ], + + '%w' => [ :tQWORDS_BEG, false ], + '%W' => [ :tWORDS_BEG, true ], + + '%i' => [ :tQSYMBOLS_BEG, false ], + '%I' => [ :tSYMBOLS_BEG, true ], + + ":'" => [ :tSYMBEG, false ], + '%s' => [ :tSYMBEG, false ], + ':"' => [ :tSYMBEG, true ], + + '/' => [ :tREGEXP_BEG, true ], + '%r' => [ :tREGEXP_BEG, true ], + + '%x' => [ :tXSTRING_BEG, true ], + '`' => [ :tXSTRING_BEG, true ], + '<<`' => [ :tXSTRING_BEG, true ], + } + + attr_reader :heredoc_e, :str_s, :dedent_level + attr_accessor :saved_herebody_s + + def initialize(lexer, str_type, delimiter, str_s, heredoc_e = nil, + indent = false, dedent_body = false, label_allowed = false) + @lexer = lexer + @nesting = 1 + + # DELIMITERS and TYPES are hashes with keys encoded in binary. + # Coerce incoming data to the same encoding. + str_type = coerce_encoding(str_type) + delimiter = coerce_encoding(delimiter) + + unless TYPES.include?(str_type) + lexer.send(:diagnostic, :error, :unexpected_percent_str, + { :type => str_type }, @lexer.send(:range, str_s, str_s + 2)) + end + + # String type. For :'foo', it is :' + @str_type = str_type + # Start of the string type specifier. + @str_s = str_s + + @start_tok, @interpolate = TYPES[str_type] + @start_delim = DELIMITERS.include?(delimiter) ? delimiter : nil + @end_delim = DELIMITERS.fetch(delimiter, delimiter) + + @heredoc_e = heredoc_e + @indent = indent + @label_allowed = label_allowed + + @dedent_body = dedent_body + @dedent_level = nil + + @interp_braces = 0 + + @space_emitted = true + + # Monolithic strings are glued into a single token, e.g. + # tSTRING_BEG tSTRING_CONTENT tSTRING_END -> tSTRING. + @monolithic = (@start_tok == :tSTRING_BEG && + %w(' ").include?(str_type) && + !heredoc?) + + # Capture opening delimiter in percent-literals. + @str_type += delimiter if @str_type.start_with?('%'.freeze) + + clear_buffer + + emit_start_tok unless @monolithic + end + + def interpolate? + @interpolate + end + + def words? + type == :tWORDS_BEG || type == :tQWORDS_BEG || + type == :tSYMBOLS_BEG || type == :tQSYMBOLS_BEG + end + + def regexp? + type == :tREGEXP_BEG + end + + def heredoc? + !!@heredoc_e + end + + def plain_heredoc? + heredoc? && !@dedent_body + end + + def squiggly_heredoc? + heredoc? && @dedent_body + end + + def backslash_delimited? + @end_delim == '\\'.freeze + end + + def type + @start_tok + end + + def munge_escape?(character) + character = coerce_encoding(character) + + if words? && character =~ /[ \t\v\r\f\n]/ + true + else + ['\\'.freeze, @start_delim, @end_delim].include?(character) + end + end + + def nest_and_try_closing(delimiter, ts, te, lookahead=nil) + delimiter = coerce_encoding(delimiter) + + if @start_delim && @start_delim == delimiter + @nesting += 1 + elsif delimiter?(delimiter) + @nesting -= 1 + end + + # Finalize if last matching delimiter is closed. + if @nesting == 0 + if words? + extend_space(ts, ts) + end + + if lookahead && @label_allowed && lookahead[0] == ?: && + lookahead[1] != ?: && @start_tok == :tSTRING_BEG + # This is a quoted label. + flush_string + emit(:tLABEL_END, @end_delim, ts, te + 1) + elsif @monolithic + # Emit the string as a single token. + emit(:tSTRING, @buffer, @str_s, te) + else + # If this is a heredoc, @buffer contains the sentinel now. + # Just throw it out. Lexer flushes the heredoc after each + # non-heredoc-terminating \n anyway, so no data will be lost. + flush_string unless heredoc? + + emit(:tSTRING_END, @end_delim, ts, te) + end + end + end + + def infer_indent_level(line) + return if !@dedent_body + + indent_level = 0 + line.each_char do |char| + case char + when ?\s + indent_level += 1 + when ?\t + indent_level += (8 - indent_level % 8) + else + if @dedent_level.nil? || @dedent_level > indent_level + @dedent_level = indent_level + end + break + end + end + end + + def start_interp_brace + @interp_braces += 1 + end + + def end_interp_brace_and_try_closing + @interp_braces -= 1 + + (@interp_braces == 0) + end + + def extend_string(string, ts, te) + @buffer_s ||= ts + @buffer_e = te + + @buffer << string + end + + def flush_string + if @monolithic + emit_start_tok + @monolithic = false + end + + unless @buffer.empty? + emit(:tSTRING_CONTENT, @buffer, @buffer_s, @buffer_e) + + clear_buffer + extend_content + end + end + + def extend_content + @space_emitted = false + end + + def extend_space(ts, te) + flush_string + + unless @space_emitted + emit(:tSPACE, nil, ts, te) + + @space_emitted = true + end + end + + def supports_line_continuation_via_slash? + !words? && @interpolate + end + + protected + + def delimiter?(delimiter) + if heredoc? + # This heredoc is valid: + # <<~E + # E + # and this: + # <<~E + # E + # but this one is not: + # <<~' E' + # E + # because there are not enough leading spaces in the closing delimiter. + delimiter.end_with?(@end_delim) && + delimiter.sub(/#{Regexp.escape(@end_delim)}\z/, '').bytes.all? { |c| c == SPACE || c == TAB } + elsif @indent + @end_delim == delimiter.lstrip + else + @end_delim == delimiter + end + end + + def coerce_encoding(string) + string.b + end + + def clear_buffer + @buffer = ''.dup + + # Prime the buffer with lexer encoding; otherwise, + # concatenation will produce varying results. + @buffer.force_encoding(@lexer.source_buffer.source.encoding) + + @buffer_s = nil + @buffer_e = nil + end + + def emit_start_tok + str_e = @heredoc_e || @str_s + @str_type.length + emit(@start_tok, @str_type, @str_s, str_e) + end + + def emit(token, type, s, e) + @lexer.send(:emit, token, type, s, e) + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/lexer/stack_state.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/lexer/stack_state.rb new file mode 100644 index 00000000..d97114f1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/lexer/stack_state.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +module Parser + + class Lexer::StackState + def initialize(name) + @name = name.freeze + clear + end + + def clear + @stack = 0 + end + + def push(bit) + bit_value = bit ? 1 : 0 + @stack = (@stack << 1) | bit_value + + bit + end + + def pop + bit_value = @stack & 1 + @stack >>= 1 + + bit_value == 1 + end + + def lexpop + @stack = ((@stack >> 1) | (@stack & 1)) + @stack[0] == 1 + end + + def active? + @stack[0] == 1 + end + + def empty? + @stack == 0 + end + + def to_s + "[#{@stack.to_s(2)} <= #{@name}]" + end + + alias inspect to_s + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/macruby.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/macruby.rb new file mode 100644 index 00000000..647409c2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/macruby.rb @@ -0,0 +1,9634 @@ +# -*- encoding:utf-8; warn-indent:false; frozen_string_literal: true -*- +# +# DO NOT MODIFY!!!! +# This file is automatically generated by Racc 1.8.1 +# from Racc grammar file "macruby.y". +# + +require 'racc/parser.rb' + + +require_relative '../parser' + +module Parser + class MacRuby < Parser::Base + + + def version + 19 # closest released match: v1_9_0_2 + end + + def default_encoding + Encoding::BINARY + end + + def local_push + @static_env.extend_static + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + end + + def local_pop + @static_env.unextend + @lexer.cmdarg.pop + @lexer.cond.pop + end +##### State transition tables begin ### + +racc_action_table = [ + -460, 5, 69, 70, 66, 9, 52, -460, -460, -460, + 58, 59, -460, -460, -460, 62, -460, 60, 61, 63, + 28, 29, 67, 68, -460, 257, -460, -460, -460, 27, + 26, 25, 93, 92, 94, 95, -460, -460, 18, -460, + -460, -460, -460, -460, 8, 42, 7, 10, 97, 96, + 98, 87, 51, 89, 88, 90, 535, 91, 99, 100, + 514, 85, 86, 39, 40, 38, -460, -460, -460, -460, + -460, -460, -460, -460, -460, -460, -460, -460, -460, -460, + 101, 468, -460, -460, -460, 37, -460, -460, 31, -93, + -460, 53, 54, -460, -460, 55, -460, 33, -460, 556, + -460, 41, -460, -460, -460, -460, -460, -460, -460, 19, + -460, 256, -460, -100, 84, 76, 79, 80, 208, 81, + 82, 113, -99, 736, 77, 83, -460, -460, -460, -460, + -463, -460, 57, -460, 78, -460, 759, -463, -463, -463, + -473, 204, -463, -463, -463, 667, -463, 526, 514, -87, + 197, 527, 514, 588, -463, 209, -463, -463, -463, -95, + 504, 534, 555, 503, 198, -97, -463, -463, 667, -463, + -463, -463, -463, -463, 105, 514, 514, -95, -97, 104, + -94, 105, 205, 206, -92, -94, 104, 587, 105, -93, + -100, 588, 199, 104, -85, 419, -463, -463, -463, -463, + -463, -463, -463, -463, -463, -463, -463, -463, -463, -463, + 205, 206, -463, -463, -463, -87, -463, -463, -92, 200, + -463, -96, -89, -463, -463, 587, -463, -91, -463, 247, + -463, 667, -463, -463, -463, -463, -463, -463, -463, -286, + -463, 758, -463, 300, -100, 105, -286, -286, -286, 588, + 104, -87, -286, -286, -87, -286, -463, -463, -463, -463, + -87, -463, 105, -463, -87, -463, 105, 104, 105, 786, + -89, 104, 105, 104, 257, -286, -286, 104, -286, -286, + -286, -286, -286, 587, 301, -86, 257, -96, -89, 105, + 105, -95, -97, -98, 104, 104, -95, -97, -534, -94, + 209, 631, 209, 520, -94, -286, -286, -286, -286, -286, + -286, -286, -286, -286, -286, -286, -286, -286, -286, 205, + 206, -286, -286, -286, -89, 573, -473, -89, 366, -286, + 491, 105, -286, -89, 545, -96, 104, -286, 252, -286, + -96, -286, -286, -286, -286, -286, -286, -286, -538, -286, + 252, -286, -534, 205, 206, -538, -538, -538, -535, 767, + 256, -538, -538, 719, -538, -286, -286, 588, -90, -85, + -286, 249, 256, -538, -98, -93, -531, -404, 250, -99, + 504, 205, 206, 506, -538, -538, -460, -538, -538, -538, + -538, -538, -88, -460, 379, 547, 546, 543, -90, 767, + 775, 587, 647, 646, 645, 651, 648, 768, 545, 209, + 504, 418, -95, 506, -538, -538, -538, -538, -538, -538, + -538, -538, -538, -538, -538, -538, -538, -538, -460, -404, + -538, -538, -538, 420, 574, -460, -404, 421, -538, 720, + -531, -538, 545, 209, -460, -404, -538, 817, -538, 208, + -538, -538, -538, -538, -538, -538, -538, 76, -538, -538, + -538, 545, -531, -404, 302, 303, 77, -532, -538, 547, + 546, 548, 803, -538, -538, -538, 78, -88, 850, -538, + -538, -538, -538, -96, -463, -538, -538, -538, -97, -538, + 775, -463, 647, 646, 645, 651, 648, 228, -538, -538, + -538, -538, 376, 547, 546, 550, -538, 378, 377, -538, + -538, -470, -538, -538, -538, -538, -538, 453, -470, -463, + -538, -94, 547, 546, 552, 545, -463, -538, 545, 225, + -469, -532, -534, 227, 226, -463, -538, -469, 464, -538, + -538, -538, -538, -538, -538, -538, -538, -538, -538, -538, + -538, -538, -538, -532, -538, -538, -538, -538, -538, 721, + -538, 486, 487, -538, 491, -538, -538, -538, 938, -538, + -534, -538, 466, -538, -538, -538, -538, -538, -538, -538, + -538, -538, -80, -538, -538, -538, 547, 546, -66, 547, + 546, 557, -538, 468, 504, 699, 228, 506, 568, -538, + -538, -538, -538, -286, -538, 569, -538, -91, -96, 707, + -286, -286, -286, -99, -65, -286, -286, -286, 732, -286, + 647, 646, 645, 651, 648, 228, 205, 206, 225, -286, + -286, -286, 227, 226, 223, 224, 205, 206, 209, -286, + -286, -87, -286, -286, -286, -286, -286, -95, -89, -471, + 781, 631, -86, -468, -97, 653, -471, 225, -94, 476, + -468, 227, 226, 105, 657, 656, 660, 659, 104, -286, + -286, -286, -286, -286, -286, -286, -286, -286, -286, -286, + -286, -286, -286, 477, 202, -286, -286, -286, -330, 722, + -286, 203, 484, -286, 261, -330, -286, -286, 731, -286, + 201, -286, 209, -286, -330, -286, -286, -286, -286, -286, + -286, -286, 252, -286, 488, -286, 492, 650, -465, 647, + 646, 645, 651, 648, 493, -465, -466, 228, -467, -286, + -286, -286, -286, -466, -286, -467, -286, 499, -98, 277, + 69, 70, 66, 9, 52, 540, 105, 500, 58, 59, + 507, 104, 541, 62, 653, 60, 61, 63, 28, 29, + 67, 68, 508, 657, 656, 660, 659, 27, 26, 25, + 93, 92, 94, 95, 693, 694, 18, 468, 695, 99, + 100, 562, 8, 42, 520, 10, 97, 96, 98, 87, + 51, 89, 88, 90, 368, 91, 99, 100, 524, 85, + 86, 39, 40, 38, 228, 232, 237, 238, 239, 234, + 236, 244, 245, 240, 241, 415, 221, 222, -472, 105, + 242, 243, 416, 37, 104, -472, 279, 105, 525, 53, + 54, 417, 104, 55, -472, 33, 225, 558, 231, 41, + 227, 226, 223, 224, 235, 233, 229, 19, 230, 781, + 631, 105, 84, 76, 79, 80, 104, 81, 82, 228, + 561, 482, 77, 83, 564, 246, -281, -233, 483, -266, + 57, 209, 78, -281, -281, -281, 252, 481, -281, -281, + -281, 650, -281, 647, 646, 645, 651, 648, 578, 228, + 228, 225, -281, -281, -281, 227, 226, 223, 224, 228, + 228, 209, -281, -281, 209, -281, -281, -281, -281, -281, + 775, 209, 647, 646, 645, 651, 648, -80, 653, 639, + 775, 613, 647, 646, 645, 651, 648, 657, 656, 660, + 659, 209, -281, -281, -281, -281, -281, -281, -281, -281, + -281, -281, -281, -281, -281, -281, 497, 771, -281, -281, + -281, -280, 624, -281, 631, 209, -281, 771, -280, -281, + -281, 663, -281, 520, -281, 670, -281, -280, -281, -281, + -281, -281, -281, -281, -281, 494, -281, 698, -281, 701, + 522, -267, 495, 708, 453, 453, 209, 523, 724, 466, + 209, 417, -281, -281, -281, -281, 521, -281, 743, -281, + 277, 69, 70, 66, 9, 52, 468, 624, 530, 58, + 59, 209, 252, 252, 62, 529, 60, 61, 63, 28, + 29, 67, 68, 624, 531, 228, 228, 750, 27, 26, + 25, 93, 92, 94, 95, -266, 775, 18, 647, 646, + 645, 651, 648, 8, 42, 754, 10, 97, 96, 98, + 87, 51, 89, 88, 90, 761, 91, 99, 100, 763, + 85, 86, 39, 40, 38, 775, 766, 647, 646, 645, + 651, 648, 775, 771, 647, 646, 645, 651, 648, -287, + 769, -287, 774, 777, 37, 778, -287, 31, -287, 631, + 53, 54, 785, 209, 55, -287, 33, -287, 209, 794, + 41, 775, 771, 647, 646, 645, 651, 648, 19, 653, + -268, 774, 805, 84, 76, 79, 80, 807, 81, 82, + 660, 659, 810, 77, 83, 5, 69, 70, 66, 9, + 52, 57, 811, 78, 58, 59, 731, 818, 653, 62, + 209, 60, 61, 63, 28, 29, 67, 68, 824, 660, + 659, 825, 624, 27, 26, 25, 93, 92, 94, 95, + 731, 775, 18, 647, 646, 645, 651, 648, 8, 42, + 7, 10, 97, 96, 98, 87, 51, 89, 88, 90, + 845, 91, 99, 100, 848, 85, 86, 39, 40, 38, + 775, 767, 647, 646, 645, 651, 648, 775, 771, 647, + 646, 645, 651, 648, -472, 209, -286, 901, 852, 37, + 854, -472, 31, -286, 860, 53, 54, 862, -535, 55, + -472, 33, -286, 209, 865, 41, 775, 771, 647, 646, + 645, 651, 648, 19, 653, -269, 872, 873, 84, 76, + 79, 80, 876, 81, 82, 660, 659, 878, 77, 83, + 277, 69, 70, 66, 9, 52, 57, 466, 78, 58, + 59, 881, 886, 653, 62, 209, 60, 61, 63, 28, + 29, 67, 68, 890, 660, 659, 893, 895, 27, 26, + 25, 93, 92, 94, 95, 897, 775, 18, 647, 646, + 645, 651, 648, 8, 42, 897, 10, 97, 96, 98, + 87, 51, 89, 88, 90, 209, 91, 99, 100, 902, + 85, 86, 39, 40, 38, 775, 905, 647, 646, 645, + 651, 648, 775, 771, 647, 646, 645, 651, 648, 884, + 906, -286, -280, 911, 37, 913, 885, 31, -286, -280, + 53, 54, 916, -535, 55, 883, 33, -286, -280, 918, + 41, 775, 771, 647, 646, 645, 651, 648, 19, 653, + 897, 897, 923, 84, 76, 79, 80, 499, 81, 82, + 660, 659, 931, 77, 83, 277, 69, 70, 66, 9, + 52, 57, 932, 78, 58, 59, 940, 466, 653, 62, + 209, 60, 61, 63, 28, 29, 67, 68, 953, 660, + 659, 897, 897, 27, 26, 25, 93, 92, 94, 95, + 897, 815, 18, 647, 646, 645, 957, 648, 8, 42, + 940, 10, 97, 96, 98, 87, 51, 89, 88, 90, + 960, 91, 99, 100, 961, 85, 86, 39, 40, 38, + 815, 530, 647, 646, 645, 963, 648, 775, 922, 647, + 646, 645, 651, 648, -287, 897, -286, 531, 897, 37, + 897, -287, 31, -286, -535, 53, 54, -534, -535, 55, + -287, 33, -286, 940, 897, 41, 775, 940, 647, 646, + 645, 651, 648, 19, 653, 897, nil, nil, 84, 76, + 79, 80, nil, 81, 82, 660, 659, nil, 77, 83, + 277, 69, 70, 66, 9, 52, 57, nil, 78, 58, + 59, nil, nil, 653, 62, nil, 60, 61, 63, 28, + 29, 67, 68, nil, 660, 659, nil, nil, 27, 26, + 25, 93, 92, 94, 95, nil, nil, 18, 108, 109, + 110, 111, 112, 8, 42, nil, 10, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, 228, 108, 109, 110, 111, + 112, nil, 775, nil, 647, 646, 645, 651, 648, nil, + nil, 242, 243, nil, 37, nil, nil, 279, nil, nil, + 53, 54, nil, nil, 55, nil, 33, 225, nil, 231, + 41, 227, 226, 223, 224, nil, nil, nil, 19, 653, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + 660, 659, nil, 77, 83, 277, 69, 70, 66, 9, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 28, 29, 67, 68, 108, 109, + 110, 111, 112, 27, 26, 25, 93, 92, 94, 95, + nil, nil, 18, nil, nil, nil, nil, 565, 8, 42, + nil, 10, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + 228, 232, 237, 238, 239, 234, 236, 244, 245, 240, + 241, nil, 221, 222, nil, nil, 242, 243, nil, 37, + nil, nil, 279, nil, nil, 53, 54, nil, nil, 55, + nil, 33, 225, nil, 231, 41, 227, 226, 223, 224, + 235, 233, 229, 19, 230, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 246, -539, nil, nil, nil, 57, nil, 78, -539, + -539, -539, nil, nil, -539, -539, -539, 650, -539, 647, + 646, 645, 651, 648, nil, nil, nil, -539, -539, -539, + -539, 108, 109, 110, 111, 112, nil, nil, -539, -539, + nil, -539, -539, -539, -539, -539, nil, nil, nil, nil, + nil, nil, nil, nil, 653, 688, nil, nil, nil, nil, + nil, nil, nil, 657, 656, 660, 659, nil, -539, -539, + -539, -539, -539, -539, -539, -539, -539, -539, -539, -539, + -539, -539, nil, nil, -539, -539, -539, nil, nil, -539, + nil, nil, -539, nil, nil, -539, -539, nil, -539, nil, + -539, nil, -539, nil, -539, -539, -539, -539, -539, -539, + -539, -540, -539, -539, -539, nil, nil, nil, -540, -540, + -540, nil, nil, -540, -540, -540, 228, -540, -539, -539, + -539, -539, nil, -539, nil, -539, -540, -540, -540, -540, + nil, nil, 242, 243, nil, nil, nil, -540, -540, nil, + -540, -540, -540, -540, -540, nil, nil, nil, 225, nil, + 231, nil, 227, 226, 223, 224, nil, nil, 229, nil, + 230, nil, nil, nil, nil, nil, nil, -540, -540, -540, + -540, -540, -540, -540, -540, -540, -540, -540, -540, -540, + -540, nil, nil, -540, -540, -540, nil, nil, -540, nil, + nil, -540, nil, nil, -540, -540, nil, -540, nil, -540, + nil, -540, nil, -540, -540, -540, -540, -540, -540, -540, + nil, -540, -540, -540, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, -540, -540, -540, + -540, nil, -540, nil, -540, 277, 69, 70, 66, 9, + 52, nil, nil, nil, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 28, 29, 67, 68, nil, nil, + nil, nil, nil, 27, 26, 25, 93, 92, 94, 95, + nil, nil, 18, nil, nil, nil, nil, nil, 8, 42, + nil, 10, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + 228, 232, 237, 238, 239, 234, 236, 244, 245, 240, + 241, nil, -557, -557, nil, nil, 242, 243, nil, 37, + nil, nil, 31, nil, nil, 53, 54, nil, nil, 55, + nil, 33, 225, nil, 231, 41, 227, 226, 223, 224, + 235, 233, 229, 19, 230, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + 277, 69, 70, 66, 9, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 28, + 29, 67, 68, nil, nil, nil, nil, nil, 27, 26, + 25, 93, 92, 94, 95, nil, nil, 18, nil, nil, + nil, nil, nil, 8, 42, nil, 10, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, 228, 232, 237, 238, 239, + 234, 236, 244, 245, 240, 241, nil, -557, -557, nil, + nil, 242, 243, nil, 37, nil, nil, 31, nil, nil, + 53, 54, nil, nil, 55, nil, 33, 225, nil, 231, + 41, 227, 226, 223, 224, 235, 233, 229, 19, 230, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, 277, 69, 70, 66, 9, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 28, 29, 67, 68, nil, nil, + nil, nil, nil, 27, 26, 25, 93, 92, 94, 95, + nil, nil, 18, nil, nil, nil, nil, nil, 8, 42, + nil, 10, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + 228, -557, -557, -557, -557, 234, 236, nil, nil, -557, + -557, nil, nil, nil, nil, nil, 242, 243, nil, 37, + nil, nil, 31, nil, nil, 53, 54, nil, nil, 55, + nil, 33, 225, nil, 231, 41, 227, 226, 223, 224, + 235, 233, 229, 19, 230, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + 277, 69, 70, 66, 9, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 28, + 29, 67, 68, nil, nil, nil, nil, nil, 27, 26, + 25, 93, 92, 94, 95, nil, nil, 18, nil, nil, + nil, nil, nil, 8, 42, nil, 10, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, 228, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 242, 243, nil, 37, nil, nil, 31, nil, nil, + 53, 54, nil, nil, 55, nil, 33, 225, nil, 231, + 41, 227, 226, 223, 224, nil, nil, 229, 19, 230, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, 277, 69, 70, 66, 9, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 28, 29, 67, 68, nil, nil, + nil, nil, nil, 27, 26, 25, 93, 92, 94, 95, + nil, nil, 18, nil, nil, nil, nil, nil, 8, 42, + nil, 10, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + 228, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 242, 243, nil, 37, + nil, nil, 31, nil, nil, 53, 54, nil, nil, 55, + nil, 33, 225, nil, 231, 41, 227, 226, 223, 224, + nil, nil, 229, 19, 230, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + 277, 69, 70, 66, 9, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 28, + 29, 67, 68, nil, nil, nil, nil, nil, 27, 26, + 25, 93, 92, 94, 95, nil, nil, 18, nil, nil, + nil, nil, nil, 8, 42, nil, 10, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, 228, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 242, 243, nil, 37, nil, nil, 31, nil, nil, + 53, 54, nil, nil, 55, nil, 33, 225, nil, 231, + 41, 227, 226, 223, 224, nil, nil, 229, 19, 230, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, 277, 69, 70, 66, 9, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 28, 29, 67, 68, nil, nil, + nil, nil, nil, 27, 26, 25, 93, 92, 94, 95, + nil, nil, 18, nil, nil, nil, nil, nil, 8, 42, + nil, 10, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + 228, -557, -557, -557, -557, 234, 236, nil, nil, -557, + -557, nil, nil, nil, nil, nil, 242, 243, nil, 37, + nil, nil, 31, nil, nil, 53, 54, nil, nil, 55, + nil, 33, 225, nil, 231, 41, 227, 226, 223, 224, + 235, 233, 229, 19, 230, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + 277, 69, 70, 66, 9, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 28, + 29, 67, 68, nil, nil, nil, nil, nil, 27, 26, + 25, 93, 92, 94, 95, nil, nil, 18, nil, nil, + nil, nil, nil, 8, 42, nil, 10, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, 228, -557, -557, -557, -557, + 234, 236, nil, nil, -557, -557, nil, nil, nil, nil, + nil, 242, 243, nil, 37, nil, nil, 31, nil, nil, + 53, 54, nil, nil, 55, nil, 33, 225, nil, 231, + 41, 227, 226, 223, 224, 235, 233, 229, 19, 230, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, 277, 69, 70, 66, 9, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 28, 29, 67, 68, nil, nil, + nil, nil, nil, 27, 26, 25, 93, 92, 94, 95, + nil, nil, 18, nil, nil, nil, nil, nil, 8, 42, + nil, 10, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + 228, -557, -557, -557, -557, 234, 236, nil, nil, -557, + -557, nil, nil, nil, nil, nil, 242, 243, nil, 37, + nil, nil, 31, nil, nil, 53, 54, nil, nil, 55, + nil, 33, 225, nil, 231, 41, 227, 226, 223, 224, + 235, 233, 229, 19, 230, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + 277, 69, 70, 66, 9, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 28, + 29, 67, 68, nil, nil, nil, nil, nil, 27, 26, + 25, 93, 92, 94, 95, nil, nil, 18, nil, nil, + nil, nil, nil, 8, 42, nil, 10, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, 228, -557, -557, -557, -557, + 234, 236, nil, nil, -557, -557, nil, nil, nil, nil, + nil, 242, 243, nil, 37, nil, nil, 31, nil, nil, + 53, 54, nil, nil, 55, nil, 33, 225, nil, 231, + 41, 227, 226, 223, 224, 235, 233, 229, 19, 230, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, 277, 69, 70, 66, 9, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 28, 29, 67, 68, nil, nil, + nil, nil, nil, 27, 26, 25, 93, 92, 94, 95, + nil, nil, 18, nil, nil, nil, nil, nil, 8, 42, + nil, 10, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + 228, -557, -557, -557, -557, 234, 236, nil, nil, -557, + -557, nil, nil, nil, nil, nil, 242, 243, nil, 37, + nil, nil, 31, nil, nil, 53, 54, nil, nil, 55, + nil, 33, 225, nil, 231, 41, 227, 226, 223, 224, + 235, 233, 229, 19, 230, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + 277, 69, 70, 66, 9, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 28, + 29, 67, 68, nil, nil, nil, nil, nil, 27, 26, + 25, 93, 92, 94, 95, nil, nil, 18, nil, nil, + nil, nil, nil, 8, 42, nil, 10, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, 228, 232, 237, 238, 239, + 234, 236, nil, nil, 240, 241, nil, nil, nil, nil, + nil, 242, 243, nil, 37, nil, nil, 31, nil, nil, + 53, 54, nil, nil, 55, nil, 33, 225, nil, 231, + 41, 227, 226, 223, 224, 235, 233, 229, 19, 230, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, 277, 69, 70, 66, 9, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 28, 29, 67, 68, nil, nil, + nil, nil, nil, 27, 26, 25, 93, 92, 94, 95, + nil, nil, 18, nil, nil, nil, nil, nil, 8, 42, + nil, 10, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + 228, 232, 237, 238, 239, 234, 236, 244, nil, 240, + 241, nil, nil, nil, nil, nil, 242, 243, nil, 37, + nil, nil, 31, nil, nil, 53, 54, nil, nil, 55, + nil, 33, 225, nil, 231, 41, 227, 226, 223, 224, + 235, 233, 229, 19, 230, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + 277, 69, 70, 66, 9, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 28, + 29, 67, 68, nil, nil, nil, nil, nil, 27, 26, + 25, 93, 92, 94, 95, nil, nil, 18, nil, nil, + nil, nil, nil, 8, 42, nil, 10, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, 228, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 242, 243, nil, 37, nil, nil, 31, nil, nil, + 53, 54, nil, nil, 55, nil, 33, 225, nil, 231, + 41, 227, 226, 223, 224, nil, nil, nil, 19, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, 277, 69, 70, 66, 9, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 28, 29, 67, 68, nil, nil, + nil, nil, nil, 27, 26, 25, 93, 92, 94, 95, + nil, nil, 18, nil, nil, nil, nil, nil, 8, 42, + nil, 10, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + 228, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 242, 243, nil, 37, + nil, nil, 31, nil, nil, 53, 54, nil, nil, 55, + nil, 33, 225, nil, nil, 41, 227, 226, 223, 224, + nil, nil, nil, 19, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + 277, 69, 70, 66, 9, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 28, + 29, 67, 68, nil, nil, nil, nil, nil, 27, 26, + 25, 93, 92, 94, 95, nil, nil, 18, nil, nil, + nil, nil, nil, 8, 42, nil, 10, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 37, nil, nil, 31, nil, nil, + 53, 54, nil, nil, 55, nil, 33, nil, nil, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 19, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, 277, 69, 70, 66, 9, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 28, 29, 67, 68, nil, nil, + nil, nil, nil, 27, 26, 25, 93, 92, 94, 95, + nil, nil, 18, nil, nil, nil, nil, nil, 8, 42, + nil, 10, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 37, + nil, nil, 31, nil, nil, 53, 54, nil, nil, 55, + nil, 33, nil, nil, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 19, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + 277, 69, 70, 66, 9, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 28, + 29, 67, 68, nil, nil, nil, nil, nil, 27, 26, + 25, 93, 92, 94, 95, nil, nil, 18, nil, nil, + nil, nil, nil, 8, 42, nil, 10, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 37, nil, nil, 31, nil, nil, + 53, 54, nil, nil, 55, nil, 33, nil, nil, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 19, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, 277, 69, 70, 66, 9, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 28, 29, 67, 68, nil, nil, + nil, nil, nil, 27, 26, 25, 93, 92, 94, 95, + nil, nil, 18, nil, nil, nil, nil, nil, 8, 42, + nil, 10, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 37, + nil, nil, 31, nil, nil, 53, 54, nil, nil, 55, + nil, 33, nil, nil, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 19, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + 277, 69, 70, 66, 9, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 28, + 29, 67, 68, nil, nil, nil, nil, nil, 27, 26, + 25, 93, 92, 94, 95, nil, nil, 18, nil, nil, + nil, nil, nil, 8, 42, nil, 10, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 37, nil, nil, 31, nil, nil, + 53, 54, nil, nil, 55, nil, 33, nil, nil, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 19, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, 277, 69, 70, 66, 9, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 28, 29, 67, 68, nil, nil, + nil, nil, nil, 27, 26, 25, 93, 92, 94, 95, + nil, nil, 18, nil, nil, nil, nil, nil, 8, 42, + nil, 10, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 37, + nil, nil, 31, nil, nil, 53, 54, nil, nil, 55, + nil, 33, nil, nil, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 19, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + 277, 69, 70, 66, 9, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 28, + 29, 67, 68, nil, nil, nil, nil, nil, 27, 26, + 25, 93, 92, 94, 95, nil, nil, 18, nil, nil, + nil, nil, nil, 8, 42, nil, 10, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 37, nil, nil, 31, nil, nil, + 53, 54, nil, nil, 55, nil, 33, nil, nil, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 19, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, 9, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 28, 29, 67, 68, nil, nil, + nil, nil, nil, 27, 26, 25, 93, 92, 94, 95, + nil, nil, 18, nil, nil, nil, nil, nil, 8, 42, + 7, 10, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 37, + nil, nil, 31, nil, nil, 53, 54, nil, nil, 55, + nil, 33, nil, nil, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 19, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 69, 70, 66, nil, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 28, + 29, 67, 68, nil, nil, nil, nil, nil, 27, 26, + 25, 93, 92, 94, 95, nil, nil, 220, nil, nil, + nil, nil, nil, nil, 42, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 213, nil, nil, 219, nil, nil, + 53, 54, nil, nil, 55, nil, nil, nil, nil, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 218, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, nil, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 28, 29, 67, 68, nil, nil, + nil, nil, nil, 27, 26, 25, 93, 92, 94, 95, + nil, nil, 220, nil, nil, nil, nil, nil, nil, 42, + nil, nil, 97, 96, 98, 87, 51, 89, 88, 90, + 272, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 213, + nil, nil, 219, nil, nil, 53, 54, nil, nil, 55, + nil, 270, nil, 268, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 218, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 69, 70, 66, nil, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 28, + 29, 67, 68, nil, nil, nil, nil, nil, 27, 26, + 25, 93, 92, 94, 95, nil, nil, 220, nil, nil, + nil, nil, nil, nil, 42, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, 272, 91, 99, 100, nil, + 85, 86, 39, 40, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 213, nil, nil, 219, nil, nil, + 53, 54, nil, nil, 55, nil, 270, nil, 268, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 218, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, nil, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 28, 29, 67, 68, nil, nil, + nil, nil, nil, 27, 26, 25, 93, 92, 94, 95, + nil, nil, 220, nil, nil, nil, nil, nil, nil, 42, + nil, nil, 97, 96, 98, 87, 51, 89, 88, 90, + 272, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 213, + nil, nil, 219, nil, nil, 53, 54, nil, nil, 55, + nil, 270, nil, 268, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 218, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 69, 70, 66, nil, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 293, + 294, 67, 68, nil, nil, nil, nil, nil, 289, 290, + 296, 93, 92, 94, 95, nil, nil, 220, nil, nil, + nil, nil, nil, nil, 291, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, nil, 650, 297, 647, 646, 645, 651, 648, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 287, nil, nil, 284, nil, nil, + 53, 54, nil, nil, 55, nil, 283, nil, nil, nil, + 653, nil, nil, nil, nil, nil, nil, nil, nil, 657, + 656, 660, 659, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, nil, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 293, 294, 67, 68, nil, nil, + nil, nil, nil, 289, 290, 296, 93, 92, 94, 95, + nil, nil, 220, nil, nil, nil, nil, 562, nil, 291, + nil, nil, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, nil, nil, 297, + 228, 232, 237, 238, 239, 234, 236, 244, 245, 240, + 241, nil, 221, 222, nil, nil, 242, 243, nil, 287, + nil, nil, 219, nil, nil, 53, 54, nil, nil, 55, + nil, nil, 225, nil, 231, nil, 227, 226, 223, 224, + 235, 233, 229, nil, 230, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 246, nil, 299, nil, nil, 57, nil, 78, 69, + 70, 66, nil, 52, nil, nil, nil, 58, 59, nil, + nil, nil, 62, nil, 60, 61, 63, 293, 294, 67, + 68, nil, nil, nil, nil, nil, 289, 290, 296, 93, + 92, 94, 95, nil, nil, 220, nil, nil, nil, nil, + nil, nil, 42, nil, nil, 97, 96, 98, 87, 51, + 89, 88, 90, nil, 91, 99, 100, nil, 85, 86, + 39, 40, 38, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 213, nil, nil, 219, nil, nil, 53, 54, + nil, nil, 55, nil, nil, nil, nil, nil, 41, nil, + nil, nil, nil, nil, nil, nil, 218, nil, nil, nil, + nil, 84, 76, 79, 80, nil, 81, 82, nil, nil, + nil, 77, 83, nil, 69, 70, 66, nil, 52, 57, + nil, 78, 58, 59, nil, nil, nil, 62, nil, 60, + 61, 63, 293, 294, 67, 68, nil, nil, nil, nil, + nil, 289, 290, 296, 93, 92, 94, 95, nil, nil, + 220, nil, nil, nil, nil, nil, nil, 42, nil, nil, + 97, 96, 98, 87, 51, 89, 88, 90, nil, 91, + 99, 100, nil, 85, 86, 39, 40, 38, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 213, nil, nil, + 219, nil, nil, 53, 54, nil, nil, 55, nil, nil, + nil, nil, nil, 41, nil, nil, nil, nil, nil, nil, + nil, 218, nil, nil, nil, nil, 84, 76, 79, 80, + nil, 81, 82, nil, nil, nil, 77, 83, nil, 69, + 70, 66, nil, 52, 57, nil, 78, 58, 59, nil, + nil, nil, 62, nil, 60, 61, 63, 293, 294, 67, + 68, nil, nil, nil, nil, nil, 289, 290, 296, 93, + 92, 94, 95, nil, nil, 220, nil, nil, nil, nil, + nil, nil, 42, nil, nil, 97, 96, 98, 87, 51, + 89, 88, 90, nil, 91, 99, 100, nil, 85, 86, + 39, 40, 38, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 213, nil, nil, 219, nil, nil, 53, 54, + nil, nil, 55, nil, nil, nil, nil, nil, 41, nil, + nil, nil, nil, nil, nil, nil, 218, nil, nil, nil, + nil, 84, 76, 79, 80, nil, 81, 82, nil, nil, + nil, 77, 83, nil, 69, 70, 66, nil, 52, 57, + nil, 78, 58, 59, nil, nil, nil, 62, nil, 60, + 61, 63, 28, 29, 67, 68, nil, nil, nil, nil, + nil, 27, 26, 25, 93, 92, 94, 95, nil, nil, + 18, nil, nil, nil, nil, nil, nil, 42, nil, nil, + 97, 96, 98, 87, 51, 89, 88, 90, nil, 91, + 99, 100, nil, 85, 86, 39, 40, 38, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 213, nil, nil, + 219, nil, nil, 53, 54, nil, nil, 55, nil, nil, + nil, nil, nil, 41, nil, nil, nil, nil, nil, nil, + nil, 19, nil, nil, nil, nil, 84, 76, 79, 80, + nil, 81, 82, nil, nil, nil, 77, 83, nil, 69, + 70, 66, nil, 52, 57, nil, 78, 58, 59, nil, + nil, nil, 62, nil, 60, 61, 63, 293, 294, 67, + 68, nil, nil, nil, nil, nil, 289, 290, 296, 93, + 92, 94, 95, nil, nil, 220, nil, nil, nil, nil, + nil, nil, 42, nil, nil, 97, 96, 98, 87, 51, + 89, 88, 90, 272, 91, 99, 100, nil, 85, 86, + 39, 40, 38, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 213, nil, nil, 219, nil, nil, 53, 54, + nil, nil, 55, nil, 270, nil, nil, nil, 41, nil, + nil, nil, nil, nil, nil, nil, 218, nil, nil, nil, + nil, 84, 76, 79, 80, nil, 81, 82, nil, nil, + nil, 77, 83, nil, 69, 70, 66, nil, 52, 57, + nil, 78, 58, 59, nil, nil, nil, 62, nil, 60, + 61, 63, 293, 294, 67, 68, nil, nil, nil, nil, + nil, 289, 290, 296, 93, 92, 94, 95, nil, nil, + 220, nil, nil, nil, nil, nil, nil, 42, nil, nil, + 97, 96, 98, 87, 51, 89, 88, 90, 272, 91, + 99, 100, nil, 85, 86, 39, 40, 38, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 213, nil, nil, + 219, nil, nil, 53, 54, nil, nil, 55, nil, nil, + nil, nil, nil, 41, nil, nil, nil, nil, nil, nil, + nil, 218, nil, nil, nil, nil, 84, 76, 79, 80, + nil, 81, 82, nil, nil, nil, 77, 83, nil, 69, + 70, 66, nil, 52, 57, nil, 78, 58, 59, nil, + nil, nil, 62, nil, 60, 61, 63, 28, 29, 67, + 68, nil, nil, nil, nil, nil, 27, 26, 25, 93, + 92, 94, 95, nil, nil, 18, nil, nil, nil, nil, + nil, nil, 42, nil, nil, 97, 96, 98, 87, 51, + 89, 88, 90, nil, 91, 99, 100, nil, 85, 86, + 39, 40, 38, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 213, nil, nil, 219, nil, nil, 53, 54, + nil, nil, 55, nil, nil, nil, nil, nil, 41, nil, + nil, nil, nil, nil, nil, nil, 19, nil, nil, nil, + nil, 84, 76, 79, 80, nil, 81, 82, nil, nil, + nil, 77, 83, nil, 69, 70, 66, nil, 52, 57, + nil, 78, 58, 59, nil, nil, nil, 62, nil, 60, + 61, 63, 28, 29, 67, 68, nil, nil, nil, nil, + nil, 27, 26, 25, 93, 92, 94, 95, nil, nil, + 18, nil, nil, nil, nil, nil, nil, 42, nil, nil, + 97, 96, 98, 87, 51, 89, 88, 90, nil, 91, + 99, 100, nil, 85, 86, 39, 40, 38, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 213, nil, nil, + 219, nil, nil, 53, 54, nil, nil, 55, nil, nil, + nil, nil, nil, 41, nil, nil, nil, nil, nil, nil, + nil, 19, nil, nil, nil, nil, 84, 76, 79, 80, + nil, 81, 82, nil, nil, nil, 77, 83, nil, 69, + 70, 66, nil, 52, 57, nil, 78, 58, 59, nil, + nil, nil, 62, nil, 60, 61, 63, 28, 29, 67, + 68, nil, nil, nil, nil, nil, 27, 26, 25, 93, + 92, 94, 95, nil, nil, 18, nil, nil, nil, nil, + nil, nil, 42, nil, nil, 97, 96, 98, 87, 51, + 89, 88, 90, nil, 91, 99, 100, nil, 85, 86, + 39, 40, 38, 228, 232, 237, 238, 239, 234, 236, + 244, 245, 240, 241, nil, 221, 222, nil, nil, 242, + 243, nil, 213, nil, -233, 219, nil, nil, 53, 54, + nil, nil, 55, nil, nil, 225, nil, 231, 41, 227, + 226, 223, 224, 235, 233, 229, 19, 230, nil, nil, + nil, 84, 76, 79, 80, nil, 81, 82, nil, nil, + nil, 77, 83, 105, 246, nil, -233, nil, 104, 57, + nil, 78, 69, 70, 66, nil, 52, nil, nil, nil, + 58, 59, nil, nil, nil, 62, nil, 60, 61, 63, + 293, 294, 67, 68, nil, nil, nil, nil, nil, 289, + 290, 296, 93, 92, 94, 95, nil, nil, 220, nil, + nil, nil, nil, nil, nil, 291, nil, nil, 97, 96, + 98, 87, 51, 89, 88, 90, nil, 91, 99, 100, + nil, 85, 86, nil, 650, 297, 647, 646, 645, 651, + 648, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 331, nil, nil, 31, nil, + nil, 53, 54, nil, nil, 55, nil, 33, nil, nil, + nil, 653, nil, nil, nil, nil, nil, nil, nil, nil, + 657, 656, 660, 659, 84, 76, 79, 80, nil, 81, + 82, nil, nil, nil, 77, 83, nil, 69, 70, 66, + nil, 52, 57, nil, 78, 58, 59, nil, nil, nil, + 62, nil, 60, 61, 63, 293, 294, 67, 68, nil, + nil, nil, nil, nil, 289, 290, 296, 93, 92, 94, + 95, nil, nil, 220, nil, nil, nil, nil, nil, nil, + 291, nil, nil, 97, 96, 98, 336, 51, 89, 88, + 337, nil, 91, 99, 100, nil, 85, 86, nil, 650, + 297, 647, 646, 645, 651, 648, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 343, nil, nil, + 338, nil, nil, 219, nil, nil, 53, 54, nil, nil, + 55, nil, nil, nil, nil, nil, 653, nil, nil, nil, + nil, nil, nil, nil, nil, 657, 656, 660, 659, 84, + 76, 79, 80, nil, 81, 82, nil, nil, nil, 77, + 83, nil, 69, 70, 66, nil, 52, 57, nil, 78, + 58, 59, nil, nil, nil, 62, nil, 60, 61, 63, + 293, 294, 67, 68, nil, nil, nil, nil, nil, 289, + 290, 296, 93, 92, 94, 95, nil, nil, 220, nil, + nil, nil, nil, nil, nil, 291, nil, nil, 97, 96, + 98, 336, 51, 89, 88, 337, nil, 91, 99, 100, + nil, 85, 86, nil, 732, 297, 647, 646, 645, 651, + 648, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 338, nil, nil, 219, nil, + nil, 53, 54, nil, nil, 55, nil, nil, nil, nil, + nil, 653, nil, nil, nil, nil, nil, nil, nil, nil, + 657, 656, 660, 659, 84, 76, 79, 80, nil, 81, + 82, nil, nil, nil, 77, 83, nil, 69, 70, 66, + 9, 52, 57, nil, 78, 58, 59, nil, nil, nil, + 62, nil, 60, 61, 63, 28, 29, 67, 68, nil, + nil, nil, nil, nil, 27, 26, 25, 93, 92, 94, + 95, nil, nil, 18, nil, nil, nil, nil, nil, 8, + 42, 7, 10, 97, 96, 98, 87, 51, 89, 88, + 90, nil, 91, 99, 100, nil, 85, 86, 39, 40, + 38, 228, 232, 237, 238, 239, 234, 236, 244, 245, + 240, 241, nil, 221, 222, nil, nil, 242, 243, nil, + 37, nil, nil, 31, nil, nil, 53, 54, nil, nil, + 55, nil, 33, 225, nil, 231, 41, 227, 226, 223, + 224, 235, 233, 229, 19, 230, nil, nil, nil, 84, + 76, 79, 80, nil, 81, 82, nil, nil, nil, 77, + 83, nil, 246, nil, nil, nil, 368, 57, nil, 78, + 69, 70, 66, nil, 52, nil, nil, nil, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 28, 29, + 67, 68, nil, nil, nil, nil, nil, 27, 26, 25, + 93, 92, 94, 95, nil, nil, 18, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 97, 96, 98, 87, + 51, 89, 88, 90, nil, 91, 99, 100, nil, 85, + 86, 39, 40, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, nil, 219, nil, nil, 53, + 54, nil, nil, 55, nil, nil, nil, nil, nil, 41, + nil, nil, nil, nil, nil, nil, nil, 19, nil, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 69, 70, 66, nil, 52, + 57, nil, 78, 58, 59, nil, nil, nil, 62, nil, + 60, 61, 63, 28, 29, 67, 68, nil, nil, nil, + nil, nil, 27, 26, 25, 93, 92, 94, 95, nil, + nil, 18, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 97, 96, 98, 87, 51, 89, 88, 90, nil, + 91, 99, 100, nil, 85, 86, 39, 40, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 213, nil, + nil, 219, nil, nil, 53, 54, nil, nil, 55, nil, + nil, nil, nil, nil, 41, nil, nil, nil, nil, nil, + nil, nil, 19, nil, nil, nil, nil, 84, 76, 79, + 80, nil, 81, 82, nil, nil, nil, 77, 83, nil, + 69, 70, 66, nil, 52, 57, nil, 78, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 28, 29, + 67, 68, nil, nil, nil, nil, nil, 27, 26, 25, + 93, 92, 94, 95, nil, nil, 18, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 97, 96, 98, 87, + 51, 89, 88, 90, nil, 91, 99, 100, nil, 85, + 86, 39, 40, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, nil, 219, nil, nil, 53, + 54, nil, nil, 55, nil, nil, nil, nil, nil, 41, + nil, nil, nil, nil, nil, nil, nil, 19, nil, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 69, 70, 66, nil, 52, + 57, nil, 78, 58, 59, nil, nil, nil, 62, nil, + 60, 61, 63, 28, 29, 67, 68, nil, nil, nil, + nil, nil, 27, 26, 25, 93, 92, 94, 95, nil, + nil, 18, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 97, 96, 98, 87, 51, 89, 88, 90, nil, + 91, 99, 100, nil, 85, 86, 39, 40, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 213, nil, + nil, 219, nil, nil, 53, 54, nil, nil, 55, nil, + nil, nil, nil, nil, 41, nil, nil, nil, nil, nil, + nil, nil, 19, nil, nil, nil, nil, 84, 76, 79, + 80, nil, 81, 82, nil, nil, nil, 77, 83, nil, + 69, 70, 66, 9, 52, 57, nil, 78, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 28, 29, + 67, 68, nil, nil, nil, nil, nil, 27, 26, 25, + 93, 92, 94, 95, nil, nil, 18, nil, nil, nil, + nil, nil, 8, 42, nil, 10, 97, 96, 98, 87, + 51, 89, 88, 90, nil, 91, 99, 100, nil, 85, + 86, 39, 40, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 37, nil, nil, 31, nil, nil, 53, + 54, nil, nil, 55, nil, 33, nil, nil, nil, 41, + nil, nil, nil, nil, nil, nil, nil, 19, nil, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 69, 70, 66, nil, 52, + 57, nil, 78, 58, 59, nil, nil, nil, 62, nil, + 60, 61, 63, 28, 29, 67, 68, nil, nil, nil, + nil, nil, 27, 26, 25, 93, 92, 94, 95, nil, + nil, 220, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 97, 96, 98, 87, 51, 89, 88, 90, nil, + 91, 99, 100, nil, 85, 86, 39, 40, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 213, nil, + nil, 219, nil, nil, 53, 54, nil, nil, 55, nil, + 385, nil, nil, nil, 41, nil, nil, nil, nil, nil, + nil, nil, 218, nil, nil, nil, nil, 84, 76, 79, + 80, nil, 81, 82, nil, nil, nil, 77, 83, nil, + 69, 70, 66, nil, 52, 57, nil, 78, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 28, 29, + 67, 68, nil, nil, nil, nil, nil, 27, 26, 25, + 93, 92, 94, 95, nil, nil, 220, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 97, 96, 98, 87, + 51, 89, 88, 90, nil, 91, 99, 100, nil, 85, + 86, 39, 40, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, nil, 219, nil, nil, 53, + 54, nil, nil, 55, nil, 385, nil, nil, nil, 41, + nil, nil, nil, nil, nil, nil, nil, 218, nil, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 69, 70, 66, nil, 52, + 57, nil, 78, 58, 59, nil, nil, nil, 62, nil, + 60, 61, 63, 28, 29, 67, 68, nil, nil, nil, + nil, nil, 27, 26, 25, 93, 92, 94, 95, nil, + nil, 220, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 97, 96, 98, 87, 51, 89, 88, 90, nil, + 91, 99, 100, nil, 85, 86, 39, 40, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 213, nil, + nil, 219, nil, nil, 53, 54, nil, nil, 55, nil, + nil, nil, nil, nil, 41, nil, nil, nil, nil, nil, + nil, nil, 218, nil, nil, nil, nil, 84, 76, 79, + 80, nil, 81, 82, nil, nil, nil, 77, 83, nil, + 69, 70, 66, nil, 52, 57, nil, 78, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 28, 29, + 67, 68, nil, nil, nil, nil, nil, 27, 26, 25, + 93, 92, 94, 95, nil, nil, 220, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 97, 96, 98, 87, + 51, 89, 88, 90, 272, 91, 99, 100, nil, 85, + 86, 39, 40, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, nil, 219, nil, nil, 53, + 54, nil, nil, 55, nil, 270, nil, 268, nil, 41, + nil, nil, nil, nil, nil, nil, nil, 218, nil, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 69, 70, 66, nil, 52, + 57, nil, 78, 58, 59, nil, nil, nil, 62, nil, + 60, 61, 63, 28, 29, 67, 68, nil, nil, nil, + nil, nil, 27, 26, 25, 93, 92, 94, 95, nil, + nil, 220, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 97, 96, 98, 87, 51, 89, 88, 90, nil, + 91, 99, 100, nil, 85, 86, 39, 40, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 213, nil, + nil, 219, nil, nil, 53, 54, nil, nil, 55, nil, + nil, nil, nil, nil, 41, nil, nil, nil, nil, nil, + nil, nil, 218, nil, nil, nil, nil, 84, 76, 79, + 80, nil, 81, 82, nil, nil, nil, 77, 83, nil, + 69, 70, 66, nil, 52, 57, nil, 78, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 28, 29, + 67, 68, nil, nil, nil, nil, nil, 27, 26, 25, + 93, 92, 94, 95, nil, nil, 18, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 97, 96, 98, 87, + 51, 89, 88, 90, nil, 91, 99, 100, nil, 85, + 86, 39, 40, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, nil, 219, nil, nil, 53, + 54, nil, nil, 55, nil, nil, nil, nil, nil, 41, + nil, nil, nil, nil, nil, nil, nil, 19, nil, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 69, 70, 66, nil, 52, + 57, nil, 78, 58, 59, nil, nil, nil, 62, nil, + 60, 61, 63, 28, 29, 67, 68, nil, nil, nil, + nil, nil, 27, 26, 25, 93, 92, 94, 95, nil, + nil, 18, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 97, 96, 98, 87, 51, 89, 88, 90, nil, + 91, 99, 100, nil, 85, 86, 39, 40, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 213, nil, + nil, 219, nil, nil, 53, 54, nil, nil, 55, nil, + nil, nil, nil, nil, 41, nil, nil, nil, nil, nil, + nil, nil, 19, nil, nil, nil, nil, 84, 76, 79, + 80, nil, 81, 82, nil, nil, nil, 77, 83, nil, + 69, 70, 66, nil, 52, 57, nil, 78, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 28, 29, + 67, 68, nil, nil, nil, nil, nil, 27, 26, 25, + 93, 92, 94, 95, nil, nil, 18, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 97, 96, 98, 87, + 51, 89, 88, 90, nil, 91, 99, 100, nil, 85, + 86, 39, 40, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, nil, 219, nil, nil, 53, + 54, nil, nil, 55, nil, nil, nil, nil, nil, 41, + nil, nil, nil, nil, nil, nil, nil, 19, nil, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 69, 70, 66, nil, 52, + 57, nil, 78, 58, 59, nil, nil, nil, 62, nil, + 60, 61, 63, 28, 29, 67, 68, nil, nil, nil, + nil, nil, 27, 26, 25, 93, 92, 94, 95, nil, + nil, 18, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 97, 96, 98, 87, 51, 89, 88, 90, nil, + 91, 99, 100, nil, 85, 86, 39, 40, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 213, nil, + nil, 219, nil, nil, 53, 54, nil, nil, 55, nil, + nil, nil, nil, nil, 41, nil, nil, nil, nil, nil, + nil, nil, 19, nil, nil, nil, nil, 84, 76, 79, + 80, nil, 81, 82, nil, nil, nil, 77, 83, 209, + 69, 70, 66, nil, 52, 57, nil, 78, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 293, 294, + 67, 68, nil, nil, nil, nil, nil, 289, 290, 296, + 93, 92, 94, 95, nil, nil, 220, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 97, 96, 98, 87, + 51, 89, 88, 90, nil, 91, 99, 100, nil, 85, + 86, 39, 40, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, nil, 219, nil, nil, 53, + 54, nil, nil, 55, nil, nil, nil, nil, nil, 41, + nil, nil, nil, nil, nil, nil, nil, 218, nil, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 69, 70, 66, nil, 52, + 57, nil, 78, 58, 59, nil, nil, nil, 62, nil, + 60, 61, 63, 293, 294, 67, 68, nil, nil, nil, + nil, nil, 289, 290, 296, 93, 92, 94, 95, nil, + nil, 220, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 97, 96, 98, 87, 51, 89, 88, 90, nil, + 91, 99, 100, nil, 85, 86, 39, 40, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 213, nil, + nil, 219, nil, nil, 53, 54, nil, nil, 55, nil, + nil, nil, nil, nil, 41, nil, nil, nil, nil, nil, + nil, nil, 218, nil, nil, nil, nil, 84, 76, 79, + 80, nil, 81, 82, nil, nil, nil, 77, 83, nil, + 69, 70, 66, nil, 52, 57, nil, 78, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 293, 294, + 67, 68, nil, nil, nil, nil, nil, 289, 290, 296, + 93, 92, 94, 95, nil, nil, 220, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 97, 96, 98, 87, + 51, 89, 88, 90, nil, 91, 99, 100, nil, 85, + 86, 39, 40, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, nil, 219, nil, nil, 53, + 54, nil, nil, 55, nil, nil, nil, nil, nil, 41, + nil, nil, nil, nil, nil, nil, nil, 218, nil, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 69, 70, 66, nil, 52, + 57, nil, 78, 58, 59, nil, nil, nil, 62, nil, + 60, 61, 63, 293, 294, 67, 68, nil, nil, nil, + nil, nil, 289, 290, 296, 93, 92, 94, 95, nil, + nil, 220, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 97, 96, 98, 87, 51, 89, 88, 90, nil, + 91, 99, 100, nil, 85, 86, 39, 40, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 213, nil, + nil, 219, nil, nil, 53, 54, nil, nil, 55, nil, + nil, nil, nil, nil, 41, nil, nil, nil, nil, nil, + nil, nil, 218, nil, nil, nil, nil, 84, 76, 79, + 80, nil, 81, 82, nil, nil, nil, 77, 83, nil, + 69, 70, 66, nil, 52, 57, nil, 78, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 293, 294, + 67, 68, nil, nil, nil, nil, nil, 289, 290, 296, + 93, 92, 94, 95, nil, nil, 220, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 97, 96, 98, 87, + 51, 89, 88, 90, nil, 91, 99, 100, nil, 85, + 86, 39, 40, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, nil, 219, nil, nil, 53, + 54, nil, nil, 55, nil, nil, nil, nil, nil, 41, + nil, nil, nil, nil, nil, nil, nil, 218, nil, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 69, 70, 66, nil, 52, + 57, nil, 78, 58, 59, nil, nil, nil, 62, nil, + 60, 61, 63, 293, 294, 67, 68, nil, nil, nil, + nil, nil, 289, 290, 296, 93, 92, 94, 95, nil, + nil, 220, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 97, 96, 98, 87, 51, 89, 88, 90, nil, + 91, 99, 100, nil, 85, 86, 39, 40, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 213, nil, + nil, 219, nil, nil, 53, 54, nil, nil, 55, nil, + nil, nil, nil, nil, 41, nil, nil, nil, nil, nil, + nil, nil, 218, nil, nil, nil, nil, 84, 76, 79, + 80, nil, 81, 82, nil, nil, nil, 77, 83, nil, + 69, 70, 66, nil, 52, 57, nil, 78, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 293, 294, + 67, 68, nil, nil, nil, nil, nil, 289, 290, 296, + 93, 92, 94, 95, nil, nil, 220, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 97, 96, 98, 87, + 51, 89, 88, 90, nil, 91, 99, 100, nil, 85, + 86, 39, 40, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, nil, 219, nil, nil, 53, + 54, nil, nil, 55, nil, nil, nil, nil, nil, 41, + nil, nil, nil, nil, nil, nil, nil, 218, nil, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 69, 70, 66, nil, 52, + 57, nil, 78, 58, 59, nil, nil, nil, 62, nil, + 60, 61, 63, 293, 294, 67, 68, nil, nil, nil, + nil, nil, 289, 290, 296, 93, 92, 94, 95, nil, + nil, 220, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 97, 96, 98, 87, 51, 89, 88, 90, nil, + 91, 99, 100, nil, 85, 86, 39, 40, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 213, nil, + nil, 219, nil, nil, 53, 54, nil, nil, 55, nil, + nil, nil, nil, nil, 41, nil, nil, nil, nil, nil, + nil, nil, 218, nil, nil, nil, nil, 84, 76, 79, + 80, nil, 81, 82, nil, nil, nil, 77, 83, nil, + 69, 70, 66, nil, 52, 57, nil, 78, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 293, 294, + 67, 68, nil, nil, nil, nil, nil, 289, 290, 296, + 93, 92, 94, 95, nil, nil, 220, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 97, 96, 98, 87, + 51, 89, 88, 90, nil, 91, 99, 100, nil, 85, + 86, 39, 40, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, nil, 219, nil, nil, 53, + 54, nil, nil, 55, nil, nil, nil, nil, nil, 41, + nil, nil, nil, nil, nil, nil, nil, 218, nil, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 69, 70, 66, nil, 52, + 57, nil, 78, 58, 59, nil, nil, nil, 62, nil, + 60, 61, 63, 293, 294, 67, 68, nil, nil, nil, + nil, nil, 289, 290, 296, 93, 92, 94, 95, nil, + nil, 220, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 97, 96, 98, 87, 51, 89, 88, 90, nil, + 91, 99, 100, nil, 85, 86, 39, 40, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 213, nil, + nil, 219, nil, nil, 53, 54, nil, nil, 55, nil, + nil, nil, nil, nil, 41, nil, nil, nil, nil, nil, + nil, nil, 218, nil, nil, nil, nil, 84, 76, 79, + 80, nil, 81, 82, nil, nil, nil, 77, 83, nil, + 69, 70, 66, nil, 52, 57, nil, 78, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 293, 294, + 67, 68, nil, nil, nil, nil, nil, 289, 290, 296, + 93, 92, 94, 95, nil, nil, 220, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 97, 96, 98, 87, + 51, 89, 88, 90, nil, 91, 99, 100, nil, 85, + 86, 39, 40, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, nil, 219, nil, nil, 53, + 54, nil, nil, 55, nil, nil, nil, nil, nil, 41, + nil, nil, nil, nil, nil, nil, nil, 218, nil, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 69, 70, 66, nil, 52, + 57, nil, 78, 58, 59, nil, nil, nil, 62, nil, + 60, 61, 63, 293, 294, 67, 68, nil, nil, nil, + nil, nil, 289, 290, 296, 93, 92, 94, 95, nil, + nil, 220, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 97, 96, 98, 87, 51, 89, 88, 90, nil, + 91, 99, 100, nil, 85, 86, 39, 40, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 213, nil, + nil, 219, nil, nil, 53, 54, nil, nil, 55, nil, + nil, nil, nil, nil, 41, nil, nil, nil, nil, nil, + nil, nil, 218, nil, nil, nil, nil, 84, 76, 79, + 80, nil, 81, 82, nil, nil, nil, 77, 83, nil, + 69, 70, 66, nil, 52, 57, nil, 78, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 293, 294, + 67, 68, nil, nil, nil, nil, nil, 289, 290, 296, + 93, 92, 94, 95, nil, nil, 220, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 97, 96, 98, 87, + 51, 89, 88, 90, nil, 91, 99, 100, nil, 85, + 86, 39, 40, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, nil, 219, nil, nil, 53, + 54, nil, nil, 55, nil, nil, nil, nil, nil, 41, + nil, nil, nil, nil, nil, nil, nil, 218, nil, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 69, 70, 66, nil, 52, + 57, nil, 78, 58, 59, nil, nil, nil, 62, nil, + 60, 61, 63, 293, 294, 67, 68, nil, nil, nil, + nil, nil, 289, 290, 296, 93, 92, 94, 95, nil, + nil, 220, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 97, 96, 98, 87, 51, 89, 88, 90, nil, + 91, 99, 100, nil, 85, 86, 39, 40, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 213, nil, + nil, 219, nil, nil, 53, 54, nil, nil, 55, nil, + nil, nil, nil, nil, 41, nil, nil, nil, nil, nil, + nil, nil, 218, nil, nil, nil, nil, 84, 76, 79, + 80, nil, 81, 82, nil, nil, nil, 77, 83, nil, + 69, 70, 66, nil, 52, 57, nil, 78, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 293, 294, + 67, 68, nil, nil, nil, nil, nil, 289, 290, 296, + 93, 92, 94, 95, nil, nil, 220, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 97, 96, 98, 87, + 51, 89, 88, 90, nil, 91, 99, 100, nil, 85, + 86, 39, 40, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, nil, 219, nil, nil, 53, + 54, nil, nil, 55, nil, nil, nil, nil, nil, 41, + nil, nil, nil, nil, nil, nil, nil, 218, nil, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 69, 70, 66, nil, 52, + 57, nil, 78, 58, 59, nil, nil, nil, 62, nil, + 60, 61, 63, 293, 294, 67, 68, nil, nil, nil, + nil, nil, 289, 290, 296, 93, 92, 94, 95, nil, + nil, 220, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 97, 96, 98, 87, 51, 89, 88, 90, nil, + 91, 99, 100, nil, 85, 86, 39, 40, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 213, nil, + nil, 219, nil, nil, 53, 54, nil, nil, 55, nil, + nil, nil, nil, nil, 41, nil, nil, nil, nil, nil, + nil, nil, 218, nil, nil, nil, nil, 84, 76, 79, + 80, nil, 81, 82, nil, nil, nil, 77, 83, nil, + 69, 70, 66, nil, 52, 57, nil, 78, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 293, 294, + 67, 68, nil, nil, nil, nil, nil, 289, 290, 296, + 93, 92, 94, 95, nil, nil, 220, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 97, 96, 98, 87, + 51, 89, 88, 90, nil, 91, 99, 100, nil, 85, + 86, 39, 40, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, nil, 219, nil, nil, 53, + 54, nil, nil, 55, nil, nil, nil, nil, nil, 41, + nil, nil, nil, nil, nil, nil, nil, 218, nil, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 69, 70, 66, nil, 52, + 57, nil, 78, 58, 59, nil, nil, nil, 62, nil, + 60, 61, 63, 293, 294, 67, 68, nil, nil, nil, + nil, nil, 289, 290, 296, 93, 92, 94, 95, nil, + nil, 220, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 97, 96, 98, 87, 51, 89, 88, 90, nil, + 91, 99, 100, nil, 85, 86, 39, 40, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 213, nil, + nil, 219, nil, nil, 53, 54, nil, nil, 55, nil, + nil, nil, nil, nil, 41, nil, nil, nil, nil, nil, + nil, nil, 218, nil, nil, nil, nil, 84, 76, 79, + 80, nil, 81, 82, nil, nil, nil, 77, 83, nil, + 69, 70, 66, nil, 52, 57, nil, 78, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 293, 294, + 67, 68, nil, nil, nil, nil, nil, 289, 290, 296, + 93, 92, 94, 95, nil, nil, 220, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 97, 96, 98, 87, + 51, 89, 88, 90, nil, 91, 99, 100, nil, 85, + 86, 39, 40, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, nil, 219, nil, nil, 53, + 54, nil, nil, 55, nil, nil, nil, nil, nil, 41, + nil, nil, nil, nil, nil, nil, nil, 218, nil, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 69, 70, 66, nil, 52, + 57, nil, 78, 58, 59, nil, nil, nil, 62, nil, + 60, 61, 63, 293, 294, 67, 68, nil, nil, nil, + nil, nil, 289, 290, 296, 93, 92, 94, 95, nil, + nil, 220, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 97, 96, 98, 87, 51, 89, 88, 90, nil, + 91, 99, 100, nil, 85, 86, 39, 40, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 213, nil, + nil, 219, nil, nil, 53, 54, nil, nil, 55, nil, + nil, nil, nil, nil, 41, nil, nil, nil, nil, nil, + nil, nil, 218, nil, nil, nil, nil, 84, 76, 79, + 80, nil, 81, 82, nil, nil, nil, 77, 83, nil, + 69, 70, 66, nil, 52, 57, nil, 78, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 293, 294, + 67, 68, nil, nil, nil, nil, nil, 289, 290, 296, + 93, 92, 94, 95, nil, nil, 220, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 97, 96, 98, 87, + 51, 89, 88, 90, nil, 91, 99, 100, nil, 85, + 86, 39, 40, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, nil, 219, nil, nil, 53, + 54, nil, nil, 55, nil, nil, nil, nil, nil, 41, + nil, nil, nil, nil, nil, nil, nil, 218, nil, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 69, 70, 66, nil, 52, + 57, nil, 78, 58, 59, nil, nil, nil, 62, nil, + 60, 61, 63, 293, 294, 67, 68, nil, nil, nil, + nil, nil, 289, 290, 296, 93, 92, 94, 95, nil, + nil, 220, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 97, 96, 98, 87, 51, 89, 88, 90, nil, + 91, 99, 100, nil, 85, 86, 39, 40, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 213, nil, + nil, 219, nil, nil, 53, 54, nil, nil, 55, nil, + nil, nil, nil, nil, 41, nil, nil, nil, nil, nil, + nil, nil, 218, nil, nil, nil, nil, 84, 76, 79, + 80, nil, 81, 82, nil, nil, nil, 77, 83, nil, + 69, 70, 66, nil, 52, 57, nil, 78, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 293, 294, + 67, 68, nil, nil, nil, nil, nil, 289, 290, 296, + 93, 92, 94, 95, nil, nil, 220, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 97, 96, 98, 87, + 51, 89, 88, 90, nil, 91, 99, 100, nil, 85, + 86, 39, 40, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, nil, 219, nil, nil, 53, + 54, nil, nil, 55, nil, nil, nil, nil, nil, 41, + nil, nil, nil, nil, nil, nil, nil, 218, nil, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 69, 70, 66, nil, 52, + 57, nil, 78, 58, 59, nil, nil, nil, 62, nil, + 60, 61, 63, 293, 294, 67, 68, nil, nil, nil, + nil, nil, 289, 290, 296, 93, 92, 94, 95, nil, + nil, 220, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 97, 96, 98, 87, 51, 89, 88, 90, nil, + 91, 99, 100, nil, 85, 86, 39, 40, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 213, nil, + nil, 219, nil, nil, 53, 54, nil, nil, 55, nil, + nil, nil, nil, nil, 41, nil, nil, nil, nil, nil, + nil, nil, 218, nil, nil, nil, nil, 84, 76, 79, + 80, nil, 81, 82, nil, nil, nil, 77, 83, nil, + 69, 70, 66, nil, 52, 57, nil, 78, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 293, 294, + 67, 68, nil, nil, nil, nil, nil, 289, 290, 296, + 93, 92, 94, 95, nil, nil, 220, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 97, 96, 98, 87, + 51, 89, 88, 90, nil, 91, 99, 100, nil, 85, + 86, 39, 40, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, nil, 219, nil, nil, 53, + 54, nil, nil, 55, nil, nil, nil, nil, nil, 41, + nil, nil, nil, nil, nil, nil, nil, 218, nil, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 69, 70, 66, nil, 52, + 57, nil, 78, 58, 59, nil, nil, nil, 62, nil, + 60, 61, 63, 293, 294, 67, 68, nil, nil, nil, + nil, nil, 289, 290, 296, 93, 92, 94, 95, nil, + nil, 220, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 97, 96, 98, 87, 51, 89, 88, 90, nil, + 91, 99, 100, nil, 85, 86, 39, 40, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 213, nil, + nil, 219, nil, nil, 53, 54, nil, nil, 55, nil, + nil, nil, nil, nil, 41, nil, nil, nil, nil, nil, + nil, nil, 218, nil, nil, nil, nil, 84, 76, 79, + 80, nil, 81, 82, nil, nil, nil, 77, 83, nil, + 69, 70, 66, nil, 52, 57, nil, 78, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 293, 294, + 67, 68, nil, nil, nil, nil, nil, 289, 290, 296, + 93, 92, 94, 95, nil, nil, 220, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 97, 96, 98, 87, + 51, 89, 88, 90, nil, 91, 99, 100, nil, 85, + 86, 39, 40, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, nil, 219, nil, nil, 53, + 54, nil, nil, 55, nil, nil, nil, nil, nil, 41, + nil, nil, nil, nil, nil, nil, nil, 218, nil, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 69, 70, 66, nil, 52, + 57, nil, 78, 58, 59, nil, nil, nil, 62, nil, + 60, 61, 63, 28, 29, 67, 68, nil, nil, nil, + nil, nil, 27, 26, 25, 93, 92, 94, 95, nil, + nil, 220, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 97, 96, 98, 87, 51, 89, 88, 90, 272, + 91, 99, 100, nil, 85, 86, 39, 40, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 213, nil, + nil, 219, nil, nil, 53, 54, nil, nil, 55, nil, + 270, nil, 268, nil, 41, nil, nil, nil, nil, nil, + nil, nil, 218, nil, nil, nil, nil, 84, 76, 79, + 80, nil, 81, 82, nil, nil, nil, 77, 83, nil, + 69, 70, 66, nil, 52, 57, nil, 78, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 28, 29, + 67, 68, nil, nil, nil, nil, nil, 27, 26, 25, + 93, 92, 94, 95, nil, nil, 220, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 97, 96, 98, 87, + 51, 89, 88, 90, 272, 91, 99, 100, nil, 85, + 86, 39, 40, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, nil, 219, nil, nil, 458, + 54, nil, nil, 55, nil, 270, nil, 268, nil, 41, + nil, nil, nil, nil, nil, nil, nil, 218, nil, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 69, 70, 66, nil, 52, + 57, nil, 78, 58, 59, nil, nil, nil, 62, nil, + 60, 61, 63, 28, 29, 67, 68, nil, nil, nil, + nil, nil, 27, 26, 25, 93, 92, 94, 95, nil, + nil, 220, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 97, 96, 98, 87, 51, 89, 88, 90, 272, + 91, 99, 100, nil, 85, 86, 39, 40, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 213, nil, + nil, 219, nil, nil, 53, 54, nil, nil, 55, nil, + 270, nil, 268, nil, 41, nil, nil, nil, nil, nil, + nil, nil, 218, nil, nil, nil, nil, 84, 76, 79, + 80, nil, 81, 82, nil, nil, nil, 77, 83, 209, + 69, 70, 66, nil, 52, 57, nil, 78, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 293, 294, + 67, 68, nil, nil, nil, nil, nil, 289, 290, 296, + 93, 92, 94, 95, nil, nil, 220, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 97, 96, 98, 87, + 51, 89, 88, 90, nil, 91, 99, 100, nil, 85, + 86, 39, 40, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, nil, 219, nil, nil, 53, + 54, nil, nil, 55, nil, nil, nil, nil, nil, 41, + nil, nil, nil, nil, nil, nil, nil, 218, nil, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 69, 70, 66, nil, 52, + 57, nil, 78, 58, 59, nil, nil, nil, 62, nil, + 60, 61, 63, 293, 294, 67, 68, nil, nil, nil, + nil, nil, 289, 290, 296, 93, 92, 94, 95, nil, + nil, 220, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 97, 96, 98, 87, 51, 89, 88, 90, nil, + 91, 99, 100, nil, 85, 86, 39, 40, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 213, nil, + nil, 219, nil, nil, 53, 54, nil, nil, 55, nil, + nil, nil, nil, nil, 41, nil, nil, nil, nil, nil, + nil, nil, 218, nil, nil, nil, nil, 84, 76, 79, + 80, nil, 81, 82, nil, nil, nil, 77, 83, nil, + 69, 70, 66, nil, 52, 57, nil, 78, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 293, 294, + 67, 68, nil, nil, nil, nil, nil, 289, 290, 296, + 93, 92, 94, 95, nil, nil, 220, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 97, 96, 98, 87, + 51, 89, 88, 90, nil, 91, 99, 100, nil, 85, + 86, 39, 40, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, nil, 219, nil, nil, 53, + 54, nil, nil, 55, nil, nil, nil, nil, nil, 41, + nil, nil, nil, nil, nil, nil, nil, 218, nil, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 69, 70, 66, 9, 52, + 57, nil, 78, 58, 59, nil, nil, nil, 62, nil, + 60, 61, 63, 28, 29, 67, 68, nil, nil, nil, + nil, nil, 27, 26, 25, 93, 92, 94, 95, nil, + nil, 18, nil, nil, nil, nil, nil, 8, 42, nil, + 10, 97, 96, 98, 87, 51, 89, 88, 90, nil, + 91, 99, 100, nil, 85, 86, 39, 40, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 37, nil, + nil, 31, nil, nil, 53, 54, nil, nil, 55, nil, + 33, nil, nil, nil, 41, nil, nil, nil, nil, nil, + nil, nil, 19, nil, nil, nil, nil, 84, 76, 79, + 80, nil, 81, 82, nil, nil, nil, 77, 83, nil, + 69, 70, 66, nil, 52, 57, nil, 78, 58, 59, + nil, nil, nil, 62, nil, 60, 61, 63, 293, 294, + 67, 68, nil, nil, nil, nil, nil, 289, 290, 296, + 93, 92, 94, 95, nil, nil, 220, nil, nil, nil, + nil, nil, nil, 291, nil, nil, 97, 96, 98, 87, + 51, 89, 88, 90, nil, 91, 99, 100, nil, 85, + 86, nil, nil, 297, 228, 232, 237, 238, 239, 234, + 236, 244, 245, 240, 241, nil, 221, 222, nil, nil, + 242, 243, nil, 287, nil, nil, 219, nil, nil, 53, + 54, nil, nil, 55, nil, nil, 225, nil, 231, nil, + 227, 226, 223, 224, 235, 233, 229, nil, 230, nil, + nil, nil, 84, 76, 79, 80, nil, 81, 82, nil, + nil, nil, 77, 83, nil, 246, nil, 479, nil, nil, + 57, nil, 78, 69, 70, 66, nil, 52, nil, nil, + nil, 58, 59, nil, nil, nil, 62, nil, 60, 61, + 63, 293, 294, 67, 68, nil, nil, nil, nil, nil, + 289, 290, 296, 93, 92, 94, 95, nil, nil, 220, + nil, nil, nil, nil, nil, nil, 291, nil, nil, 97, + 96, 98, 87, 51, 89, 88, 90, nil, 91, 99, + 100, nil, 85, 86, nil, 732, 297, 647, 646, 645, + 651, 648, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 287, nil, nil, 284, + nil, nil, 53, 54, nil, nil, 55, nil, nil, nil, + nil, nil, 653, nil, nil, nil, nil, nil, nil, nil, + nil, 657, 656, 660, 659, 84, 76, 79, 80, nil, + 81, 82, nil, nil, nil, 77, 83, nil, 69, 70, + 66, nil, 52, 57, nil, 78, 58, 59, nil, nil, + nil, 62, nil, 60, 61, 63, 293, 294, 67, 68, + nil, nil, nil, nil, nil, 289, 290, 296, 93, 92, + 94, 95, nil, nil, 220, nil, nil, nil, nil, nil, + nil, 42, nil, nil, 97, 96, 98, 87, 51, 89, + 88, 90, nil, 91, 99, 100, nil, 85, 86, 39, + 40, 38, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 213, nil, nil, 219, 497, nil, 53, 54, nil, + nil, 55, nil, nil, nil, nil, nil, 41, nil, nil, + nil, nil, nil, nil, nil, 218, nil, nil, nil, nil, + 84, 76, 79, 80, nil, 81, 82, nil, nil, nil, + 77, 83, nil, 69, 70, 66, nil, 52, 57, nil, + 78, 58, 59, nil, nil, nil, 62, nil, 60, 61, + 63, 28, 29, 67, 68, nil, nil, nil, nil, nil, + 27, 26, 25, 93, 92, 94, 95, nil, nil, 18, + nil, nil, nil, nil, nil, nil, 42, nil, nil, 97, + 96, 98, 87, 51, 89, 88, 90, nil, 91, 99, + 100, nil, 85, 86, 39, 40, 38, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 213, nil, nil, 219, + nil, nil, 53, 54, nil, nil, 55, nil, nil, nil, + nil, nil, 41, nil, nil, nil, nil, nil, nil, nil, + 19, nil, nil, nil, nil, 84, 76, 79, 80, nil, + 81, 82, nil, nil, nil, 77, 83, nil, 69, 70, + 66, nil, 52, 57, nil, 78, 58, 59, nil, nil, + nil, 62, nil, 60, 61, 63, 28, 29, 67, 68, + nil, nil, nil, nil, nil, 27, 26, 25, 93, 92, + 94, 95, nil, nil, 18, nil, nil, nil, nil, nil, + nil, 42, nil, nil, 97, 96, 98, 87, 51, 89, + 88, 90, nil, 91, 99, 100, nil, 85, 86, 39, + 40, 38, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 213, nil, nil, 219, nil, nil, 53, 54, nil, + nil, 55, nil, nil, nil, nil, nil, 41, nil, nil, + nil, nil, nil, nil, nil, 19, nil, nil, nil, nil, + 84, 76, 79, 80, nil, 81, 82, nil, nil, nil, + 77, 83, nil, 69, 70, 66, nil, 52, 57, nil, + 78, 58, 59, nil, nil, nil, 62, nil, 60, 61, + 63, 28, 29, 67, 68, nil, nil, nil, nil, nil, + 27, 26, 25, 93, 92, 94, 95, nil, nil, 18, + nil, nil, nil, nil, nil, nil, 42, nil, nil, 97, + 96, 98, 87, 51, 89, 88, 90, nil, 91, 99, + 100, nil, 85, 86, 39, 40, 38, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 213, nil, nil, 219, + nil, nil, 53, 54, nil, nil, 55, nil, nil, nil, + nil, nil, 41, nil, nil, nil, nil, nil, nil, nil, + 19, nil, nil, nil, nil, 84, 76, 79, 80, nil, + 81, 82, nil, nil, nil, 77, 83, nil, 69, 70, + 66, nil, 52, 57, nil, 78, 58, 59, nil, nil, + nil, 62, nil, 60, 61, 63, 28, 29, 67, 68, + nil, nil, nil, nil, nil, 27, 26, 25, 93, 92, + 94, 95, nil, nil, 18, nil, nil, nil, nil, nil, + nil, 42, nil, nil, 97, 96, 98, 87, 51, 89, + 88, 90, nil, 91, 99, 100, nil, 85, 86, 39, + 40, 38, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 213, nil, nil, 219, nil, nil, 53, 54, nil, + nil, 55, nil, nil, nil, nil, nil, 41, nil, nil, + nil, nil, nil, nil, nil, 19, nil, nil, nil, nil, + 84, 76, 79, 80, nil, 81, 82, nil, nil, nil, + 77, 83, nil, 69, 70, 66, nil, 52, 57, nil, + 78, 58, 59, nil, nil, nil, 62, nil, 60, 61, + 63, 293, 294, 67, 68, nil, nil, nil, nil, nil, + 289, 290, 296, 93, 92, 94, 95, nil, nil, 220, + nil, nil, nil, nil, nil, nil, 42, nil, nil, 97, + 96, 98, 87, 51, 89, 88, 90, nil, 91, 99, + 100, nil, 85, 86, 39, 40, 38, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 213, nil, nil, 219, + nil, nil, 53, 54, nil, nil, 55, nil, nil, nil, + nil, nil, 41, nil, nil, nil, nil, nil, nil, nil, + 218, nil, nil, nil, nil, 84, 76, 79, 80, nil, + 81, 82, nil, nil, nil, 77, 83, nil, 69, 70, + 66, nil, 52, 57, nil, 78, 58, 59, nil, nil, + nil, 62, nil, 60, 61, 63, 28, 29, 67, 68, + nil, nil, nil, nil, nil, 27, 26, 25, 93, 92, + 94, 95, nil, nil, 220, nil, nil, nil, nil, nil, + nil, 42, nil, nil, 97, 96, 98, 87, 51, 89, + 88, 90, 272, 91, 99, 100, nil, 85, 86, 39, + 40, 38, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 213, nil, nil, 219, nil, nil, 53, 54, nil, + nil, 55, nil, 270, nil, 268, nil, 41, nil, nil, + nil, nil, nil, nil, nil, 218, nil, nil, nil, nil, + 84, 76, 79, 80, nil, 81, 82, nil, nil, nil, + 77, 83, nil, 69, 70, 66, nil, 52, 57, nil, + 78, 58, 59, nil, nil, nil, 62, nil, 60, 61, + 63, 293, 294, 67, 68, nil, nil, nil, nil, nil, + 289, 290, 296, 93, 92, 94, 95, nil, nil, 220, + nil, nil, nil, nil, nil, nil, 42, nil, nil, 97, + 96, 98, 87, 51, 89, 88, 90, nil, 91, 99, + 100, nil, 85, 86, 39, 40, 38, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 213, nil, nil, 219, + nil, nil, 53, 54, nil, nil, 55, nil, nil, nil, + nil, nil, 41, nil, nil, nil, nil, nil, nil, nil, + 218, nil, nil, nil, nil, 84, 76, 79, 80, nil, + 81, 82, nil, nil, nil, 77, 83, nil, 69, 70, + 66, nil, 52, 57, nil, 78, 58, 59, nil, nil, + nil, 62, nil, 60, 61, 63, 293, 294, 67, 68, + nil, nil, nil, nil, nil, 289, 290, 296, 93, 92, + 94, 95, nil, nil, 220, nil, nil, nil, nil, nil, + nil, 42, nil, nil, 97, 96, 98, 87, 51, 89, + 88, 90, nil, 91, 99, 100, nil, 85, 86, 39, + 40, 38, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 213, nil, nil, 219, nil, nil, 53, 54, nil, + nil, 55, nil, nil, nil, nil, nil, 41, nil, nil, + nil, nil, nil, nil, nil, 218, nil, nil, nil, nil, + 84, 76, 79, 80, nil, 81, 82, nil, nil, nil, + 77, 83, nil, 69, 70, 66, nil, 52, 57, nil, + 78, 58, 59, nil, nil, nil, 62, nil, 60, 61, + 63, 293, 294, 67, 68, nil, nil, nil, nil, nil, + 289, 290, 296, 93, 92, 94, 95, nil, nil, 220, + nil, nil, nil, nil, nil, nil, 42, nil, nil, 97, + 96, 98, 87, 51, 89, 88, 90, nil, 91, 99, + 100, nil, 85, 86, 39, 40, 38, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 213, nil, nil, 219, + nil, nil, 53, 54, nil, nil, 55, nil, nil, nil, + nil, nil, 41, nil, nil, nil, nil, nil, nil, nil, + 218, nil, nil, nil, nil, 84, 76, 79, 80, nil, + 81, 82, nil, nil, nil, 77, 83, nil, 69, 70, + 66, nil, 52, 57, nil, 78, 58, 59, nil, nil, + nil, 62, nil, 60, 61, 63, 28, 29, 67, 68, + nil, nil, nil, nil, nil, 27, 26, 25, 93, 92, + 94, 95, nil, nil, 18, nil, nil, nil, nil, nil, + nil, 42, nil, nil, 97, 96, 98, 87, 51, 89, + 88, 90, 272, 91, 99, 100, nil, 85, 86, 39, + 40, 38, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 213, nil, nil, 219, nil, nil, 53, 54, nil, + nil, 55, nil, nil, nil, 268, nil, 41, nil, nil, + nil, nil, nil, nil, nil, 19, nil, nil, nil, nil, + 84, 76, 79, 80, nil, 81, 82, nil, nil, nil, + 77, 83, nil, 69, 70, 66, nil, 52, 57, nil, + 78, 58, 59, nil, nil, nil, 62, nil, 60, 61, + 63, 293, 294, 67, 68, nil, nil, nil, nil, nil, + 289, 290, 296, 93, 92, 94, 95, nil, nil, 220, + nil, nil, nil, nil, nil, nil, 42, nil, nil, 97, + 96, 98, 87, 51, 89, 88, 90, 272, 91, 99, + 100, nil, 85, 86, 39, 40, 38, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 213, nil, nil, 219, + nil, nil, 53, 54, nil, nil, 55, nil, 608, nil, + 268, nil, 41, nil, nil, nil, nil, nil, nil, nil, + 218, nil, nil, nil, nil, 84, 76, 79, 80, nil, + 81, 82, nil, nil, nil, 77, 83, nil, 69, 70, + 66, nil, 52, 57, nil, 78, 58, 59, nil, nil, + nil, 62, nil, 60, 61, 63, 293, 294, 67, 68, + nil, nil, nil, nil, nil, 289, 290, 296, 93, 92, + 94, 95, nil, nil, 220, nil, nil, nil, nil, nil, + nil, 42, nil, nil, 97, 96, 98, 87, 51, 89, + 88, 90, 272, 91, 99, 100, nil, 85, 86, 39, + 40, 38, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 213, nil, nil, 219, nil, nil, 53, 54, nil, + nil, 55, nil, nil, nil, 268, nil, 41, nil, nil, + nil, nil, nil, nil, nil, 218, nil, nil, nil, nil, + 84, 76, 79, 80, nil, 81, 82, nil, nil, nil, + 77, 83, nil, 69, 70, 66, nil, 52, 57, nil, + 78, 58, 59, nil, nil, nil, 62, nil, 60, 61, + 63, 293, 294, 67, 68, nil, nil, nil, nil, nil, + 289, 290, 296, 93, 92, 94, 95, nil, nil, 220, + nil, nil, nil, nil, nil, nil, 42, nil, nil, 97, + 96, 98, 87, 51, 89, 88, 90, nil, 91, 99, + 100, nil, 85, 86, 39, 40, 38, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 213, nil, nil, 219, + nil, nil, 53, 54, nil, nil, 55, nil, nil, nil, + nil, nil, 41, nil, nil, nil, nil, nil, nil, nil, + 218, nil, nil, nil, nil, 84, 76, 79, 80, nil, + 81, 82, nil, nil, nil, 77, 83, nil, 69, 70, + 66, 9, 52, 57, nil, 78, 58, 59, nil, nil, + nil, 62, nil, 60, 61, 63, 28, 29, 67, 68, + nil, nil, nil, nil, nil, 27, 26, 25, 93, 92, + 94, 95, nil, nil, 18, nil, nil, nil, nil, nil, + 8, 42, nil, 10, 97, 96, 98, 87, 51, 89, + 88, 90, nil, 91, 99, 100, nil, 85, 86, 39, + 40, 38, 228, 232, 237, 238, 239, 234, 236, 244, + 245, 240, 241, nil, 221, 222, nil, nil, 242, 243, + nil, 37, nil, nil, 31, nil, nil, 53, 54, nil, + nil, 55, nil, 33, 225, nil, 231, 41, 227, 226, + 223, 224, 235, 233, 229, 19, 230, nil, nil, nil, + 84, 76, 79, 80, nil, 81, 82, nil, nil, nil, + 77, 83, nil, 246, nil, nil, nil, 368, 57, nil, + 78, 69, 70, 66, nil, 52, nil, nil, nil, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 293, + 294, 67, 68, nil, nil, nil, nil, nil, 289, 290, + 296, 93, 92, 94, 95, nil, nil, 220, nil, nil, + nil, nil, nil, nil, 291, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, nil, 650, 297, 647, 646, 645, 651, 648, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 287, nil, nil, 284, nil, nil, + 53, 54, nil, nil, 55, nil, nil, nil, nil, nil, + 653, 688, nil, nil, nil, nil, nil, nil, nil, 657, + 656, 660, 659, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, nil, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 28, 29, 67, 68, nil, nil, + nil, nil, nil, 27, 26, 25, 93, 92, 94, 95, + nil, nil, 220, nil, nil, nil, nil, nil, nil, 42, + nil, nil, 97, 96, 98, 87, 51, 89, 88, 90, + 272, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 213, + nil, nil, 219, nil, nil, 53, 54, nil, nil, 55, + nil, 270, nil, 268, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 218, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 69, 70, 66, nil, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 293, + 294, 67, 68, nil, nil, nil, nil, nil, 289, 290, + 296, 93, 92, 94, 95, nil, nil, 220, nil, nil, + nil, nil, nil, nil, 291, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, nil, 650, 297, 647, 646, 645, 651, 648, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 287, nil, nil, 284, nil, nil, + 53, 54, nil, nil, 55, nil, nil, nil, nil, nil, + 653, nil, nil, nil, nil, nil, nil, nil, nil, 657, + 656, 660, 659, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, nil, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 293, 294, 67, 68, nil, nil, + nil, nil, nil, 289, 290, 296, 93, 92, 94, 95, + nil, nil, 220, nil, nil, nil, nil, nil, nil, 42, + nil, nil, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 213, + nil, nil, 219, nil, nil, 53, 54, nil, nil, 55, + nil, nil, nil, nil, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 218, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 69, 70, 66, nil, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 293, + 294, 67, 68, nil, nil, nil, nil, nil, 289, 290, + 296, 93, 92, 94, 95, nil, nil, 220, nil, nil, + nil, nil, nil, nil, 42, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 213, nil, nil, 219, nil, nil, + 53, 54, nil, nil, 55, nil, nil, nil, nil, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 218, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, nil, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 293, 294, 67, 68, nil, nil, + nil, nil, nil, 289, 290, 296, 93, 92, 94, 95, + nil, nil, 220, nil, nil, nil, nil, nil, nil, 42, + nil, nil, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 213, + nil, nil, 219, nil, nil, 53, 54, nil, nil, 55, + nil, nil, nil, nil, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 218, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 69, 70, 66, nil, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 28, + 29, 67, 68, nil, nil, nil, nil, nil, 27, 26, + 25, 93, 92, 94, 95, nil, nil, 18, nil, nil, + nil, nil, nil, nil, 42, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 213, nil, nil, 219, nil, nil, + 53, 54, nil, nil, 55, nil, nil, nil, nil, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 19, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, nil, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 293, 294, 67, 68, nil, nil, + nil, nil, nil, 289, 290, 296, 93, 92, 94, 95, + nil, nil, 220, nil, nil, nil, nil, nil, nil, 42, + nil, nil, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 213, + nil, nil, 219, nil, nil, 53, 54, nil, nil, 55, + nil, 385, nil, nil, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 218, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 69, 70, 66, nil, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 293, + 294, 67, 68, nil, nil, nil, nil, nil, 289, 290, + 296, 93, 92, 94, 95, nil, nil, 220, nil, nil, + nil, nil, nil, nil, 42, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, 272, 91, 99, 100, nil, + 85, 86, 39, 40, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 213, nil, nil, 219, nil, nil, + 53, 54, nil, nil, 55, nil, 608, nil, nil, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 218, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, nil, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 293, 294, 67, 68, nil, nil, + nil, nil, nil, 289, 290, 296, 93, 92, 94, 95, + nil, nil, 220, nil, nil, nil, nil, nil, nil, 42, + nil, nil, 97, 96, 98, 87, 51, 89, 88, 90, + 272, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 213, + nil, nil, 219, nil, nil, 53, 54, nil, nil, 55, + nil, nil, nil, nil, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 218, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 69, 70, 66, nil, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 293, + 294, 67, 68, nil, nil, nil, nil, nil, 289, 290, + 296, 93, 92, 94, 95, nil, nil, 220, nil, nil, + nil, nil, nil, nil, 42, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 213, nil, nil, 219, nil, nil, + 53, 54, nil, nil, 55, nil, 270, nil, nil, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 218, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, nil, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 28, 29, 67, 68, nil, nil, + nil, nil, nil, 27, 26, 25, 93, 92, 94, 95, + nil, nil, 220, nil, nil, nil, nil, nil, nil, 42, + nil, nil, 97, 96, 98, 87, 51, 89, 88, 90, + 272, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 213, + nil, nil, 219, nil, nil, 53, 54, nil, nil, 55, + nil, 270, nil, 268, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 218, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 69, 70, 66, nil, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 28, + 29, 67, 68, nil, nil, nil, nil, nil, 27, 26, + 25, 93, 92, 94, 95, nil, nil, 220, nil, nil, + nil, nil, nil, nil, 42, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, 272, 91, 99, 100, nil, + 85, 86, 39, 40, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 213, nil, nil, 219, nil, nil, + 53, 54, nil, nil, 55, nil, 270, nil, 268, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 218, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, nil, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 28, 29, 67, 68, nil, nil, + nil, nil, nil, 27, 26, 25, 93, 92, 94, 95, + nil, nil, 18, nil, nil, nil, nil, nil, nil, 42, + nil, nil, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 213, + nil, nil, 219, nil, nil, 53, 54, nil, nil, 55, + nil, nil, nil, nil, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 19, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 69, 70, 66, nil, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 293, + 294, 67, 68, nil, nil, nil, nil, nil, 289, 290, + 296, 93, 92, 94, 95, nil, nil, 220, nil, nil, + nil, nil, nil, nil, 42, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 213, nil, nil, 219, nil, nil, + 53, 54, nil, nil, 55, nil, nil, nil, nil, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 218, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, nil, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 293, 294, 67, 68, nil, nil, + nil, nil, nil, 289, 290, 296, 93, 92, 94, 95, + nil, nil, 220, nil, nil, nil, nil, nil, nil, 42, + nil, nil, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 213, + nil, nil, 219, nil, nil, 53, 54, nil, nil, 55, + nil, 705, nil, nil, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 218, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 69, 70, 66, nil, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 293, + 294, 67, 68, nil, nil, nil, nil, nil, 289, 290, + 296, 93, 92, 94, 95, nil, nil, 220, nil, nil, + nil, nil, nil, nil, 42, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 213, nil, nil, 219, nil, nil, + 53, 54, nil, nil, 55, nil, nil, nil, nil, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 218, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, nil, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 28, 29, 67, 68, nil, nil, + nil, nil, nil, 27, 26, 25, 93, 92, 94, 95, + nil, nil, 220, nil, nil, nil, nil, nil, nil, 42, + nil, nil, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 213, + nil, nil, 219, nil, nil, 53, 54, nil, nil, 55, + nil, nil, nil, nil, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 218, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 69, 70, 66, nil, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 28, + 29, 67, 68, nil, nil, nil, nil, nil, 27, 26, + 25, 93, 92, 94, 95, nil, nil, 220, nil, nil, + nil, nil, nil, nil, 42, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 213, nil, nil, 219, nil, nil, + 53, 54, nil, nil, 55, nil, nil, nil, nil, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 218, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, nil, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 28, 29, 67, 68, nil, nil, + nil, nil, nil, 27, 26, 25, 93, 92, 94, 95, + nil, nil, 220, nil, nil, nil, nil, nil, nil, 42, + nil, nil, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 213, + nil, nil, 219, nil, nil, 53, 54, nil, nil, 55, + nil, nil, nil, nil, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 218, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 69, 70, 66, nil, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 28, + 29, 67, 68, nil, nil, nil, nil, nil, 27, 26, + 25, 93, 92, 94, 95, nil, nil, 220, nil, nil, + nil, nil, nil, nil, 42, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 213, nil, nil, 219, nil, nil, + 53, 54, nil, nil, 55, nil, nil, nil, nil, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 218, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, nil, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 293, 294, 67, 68, nil, nil, + nil, nil, nil, 289, 290, 296, 93, 92, 94, 95, + nil, nil, 220, nil, nil, nil, nil, nil, nil, 42, + nil, nil, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 213, + nil, nil, 219, nil, nil, 53, 54, nil, nil, 55, + nil, nil, nil, nil, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 218, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 69, 70, 66, nil, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 293, + 294, 67, 68, nil, nil, nil, nil, nil, 289, 290, + 296, 93, 92, 94, 95, nil, nil, 220, nil, nil, + nil, nil, nil, nil, 291, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, nil, 732, 297, 647, 646, 645, 651, 648, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 287, nil, nil, 284, nil, nil, + 53, 54, nil, nil, 55, nil, nil, nil, nil, nil, + 653, nil, nil, nil, nil, nil, nil, nil, nil, 657, + 656, 660, 659, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, nil, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 293, 294, 67, 68, nil, nil, + nil, nil, nil, 289, 290, 296, 93, 92, 94, 95, + nil, nil, 220, nil, nil, nil, nil, nil, nil, 291, + nil, nil, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, nil, nil, 297, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 287, + nil, nil, 284, nil, nil, 53, 54, nil, nil, 55, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 69, 70, 66, nil, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 28, + 29, 67, 68, nil, nil, nil, nil, nil, 27, 26, + 25, 93, 92, 94, 95, nil, nil, 18, nil, nil, + nil, nil, nil, nil, 42, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 213, nil, nil, 219, nil, nil, + 53, 54, nil, nil, 55, nil, nil, nil, nil, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 19, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, nil, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 293, 294, 67, 68, nil, nil, + nil, nil, nil, 289, 290, 296, 93, 92, 94, 95, + nil, nil, 220, nil, nil, nil, nil, nil, nil, 42, + nil, nil, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 213, + nil, nil, 219, nil, nil, 53, 54, nil, nil, 55, + nil, nil, nil, nil, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 218, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 69, 70, 66, nil, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 28, + 29, 67, 68, nil, nil, nil, nil, nil, 27, 26, + 25, 93, 92, 94, 95, nil, nil, 220, nil, nil, + nil, nil, nil, nil, 42, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 213, nil, nil, 219, nil, nil, + 53, 54, nil, nil, 55, nil, nil, nil, nil, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 218, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, nil, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 293, 294, 67, 68, nil, nil, + nil, nil, nil, 289, 290, 296, 93, 92, 94, 95, + nil, nil, 220, nil, nil, nil, nil, nil, nil, 42, + nil, nil, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 213, + nil, nil, 219, nil, nil, 53, 54, nil, nil, 55, + nil, nil, nil, nil, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 218, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 69, 70, 66, nil, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 293, + 294, 67, 68, nil, nil, nil, nil, nil, 289, 290, + 296, 93, 92, 94, 95, nil, nil, 220, nil, nil, + nil, nil, nil, nil, 42, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 213, nil, nil, 219, nil, nil, + 53, 54, nil, nil, 55, nil, nil, nil, nil, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 218, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, nil, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 293, 294, 67, 68, nil, nil, + nil, nil, nil, 289, 290, 296, 93, 92, 94, 95, + nil, nil, 220, nil, nil, nil, nil, nil, nil, 42, + nil, nil, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 213, + nil, nil, 219, nil, nil, 53, 54, nil, nil, 55, + nil, nil, nil, nil, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 218, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 69, 70, 66, nil, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 293, + 294, 67, 68, nil, nil, nil, nil, nil, 289, 290, + 296, 93, 92, 94, 95, nil, nil, 220, nil, nil, + nil, nil, nil, nil, 42, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 213, nil, nil, 219, nil, nil, + 53, 54, nil, nil, 55, nil, nil, nil, nil, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 218, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, nil, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 293, 294, 67, 68, nil, nil, + nil, nil, nil, 289, 290, 296, 93, 92, 94, 95, + nil, nil, 220, nil, nil, nil, nil, nil, nil, 42, + nil, nil, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 213, + nil, nil, 219, nil, nil, 53, 54, nil, nil, 55, + nil, nil, nil, nil, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 218, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 69, 70, 66, nil, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 293, + 294, 67, 68, nil, nil, nil, nil, nil, 289, 290, + 296, 93, 92, 94, 95, nil, nil, 220, nil, nil, + nil, nil, nil, nil, 42, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, 272, 91, 99, 100, nil, + 85, 86, 39, 40, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 213, nil, nil, 219, nil, nil, + 53, 54, nil, nil, 55, nil, 270, nil, 268, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 218, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, nil, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 293, 294, 67, 68, nil, nil, + nil, nil, nil, 289, 290, 296, 93, 92, 94, 95, + nil, nil, 220, nil, nil, nil, nil, nil, nil, 42, + nil, nil, 97, 96, 98, 87, 51, 89, 88, 90, + 272, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 213, + nil, nil, 219, nil, nil, 53, 54, nil, nil, 55, + nil, 270, nil, 268, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 218, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 69, 70, 66, nil, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 293, + 294, 67, 68, nil, nil, nil, nil, nil, 289, 290, + 296, 93, 92, 94, 95, nil, nil, 220, nil, nil, + nil, nil, nil, nil, 291, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, nil, nil, 297, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 831, nil, nil, 219, nil, nil, + 53, 54, nil, nil, 55, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, nil, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 293, 294, 67, 68, nil, nil, + nil, nil, nil, 289, 290, 296, 93, 92, 94, 95, + nil, nil, 220, nil, nil, nil, nil, nil, nil, 42, + nil, nil, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 213, + nil, nil, 219, nil, nil, 53, 54, nil, nil, 55, + nil, nil, nil, nil, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 218, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 69, 70, 66, nil, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 28, + 29, 67, 68, nil, nil, nil, nil, nil, 27, 26, + 25, 93, 92, 94, 95, nil, nil, 18, nil, nil, + nil, nil, nil, nil, 42, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 213, nil, nil, 219, nil, nil, + 53, 54, nil, nil, 55, nil, nil, nil, nil, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 19, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, nil, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 293, 294, 67, 68, nil, nil, + nil, nil, nil, 289, 290, 296, 93, 92, 94, 95, + nil, nil, 220, nil, nil, nil, nil, nil, nil, 42, + nil, nil, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 213, + nil, nil, 219, nil, nil, 53, 54, nil, nil, 55, + nil, 608, nil, nil, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 218, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 69, 70, 66, nil, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 293, + 294, 67, 68, nil, nil, nil, nil, nil, 289, 290, + 296, 93, 92, 94, 95, nil, nil, 220, nil, nil, + nil, nil, nil, nil, 42, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, nil, 91, 99, 100, nil, + 85, 86, 39, 40, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 213, nil, nil, 219, nil, nil, + 53, 54, nil, nil, 55, nil, nil, nil, nil, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 218, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, nil, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 293, 294, 67, 68, nil, nil, + nil, nil, nil, 289, 290, 296, 93, 92, 94, 95, + nil, nil, 220, nil, nil, nil, nil, nil, nil, 291, + nil, nil, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, nil, nil, 297, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 875, + nil, nil, 219, nil, nil, 53, 54, nil, nil, 55, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 69, 70, 66, nil, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 293, + 294, 67, 68, nil, nil, nil, nil, nil, 289, 290, + 296, 93, 92, 94, 95, nil, nil, 220, nil, nil, + nil, nil, nil, nil, 42, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, 272, 91, 99, 100, nil, + 85, 86, 39, 40, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 213, nil, nil, 219, nil, nil, + 53, 54, nil, nil, 55, nil, 608, nil, 268, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 218, nil, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, nil, 69, 70, 66, nil, + 52, 57, nil, 78, 58, 59, nil, nil, nil, 62, + nil, 60, 61, 63, 293, 294, 67, 68, nil, nil, + nil, nil, nil, 289, 290, 296, 93, 92, 94, 95, + nil, nil, 220, nil, nil, nil, nil, nil, nil, 42, + nil, nil, 97, 96, 98, 87, 51, 89, 88, 90, + nil, 91, 99, 100, nil, 85, 86, 39, 40, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 213, + nil, nil, 219, nil, nil, 53, 54, nil, nil, 55, + nil, 608, nil, 268, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 218, nil, nil, nil, nil, 84, 76, + 79, 80, nil, 81, 82, nil, nil, nil, 77, 83, + nil, 69, 70, 66, nil, 52, 57, nil, 78, 58, + 59, nil, nil, nil, 62, nil, 60, 61, 63, 28, + 29, 67, 68, nil, nil, nil, nil, nil, 27, 26, + 25, 93, 92, 94, 95, nil, nil, 220, nil, nil, + nil, nil, nil, nil, 42, nil, nil, 97, 96, 98, + 87, 51, 89, 88, 90, 272, 91, 99, 100, nil, + 85, 86, 39, 40, 38, 228, 232, 237, 238, 239, + 234, 236, 244, 245, 240, 241, nil, 221, 222, nil, + nil, 242, 243, nil, 213, nil, nil, 219, nil, nil, + 53, 54, nil, nil, 55, nil, 270, 225, 268, 231, + 41, 227, 226, 223, 224, 235, 233, 229, 218, 230, + nil, nil, nil, 84, 76, 79, 80, nil, 81, 82, + nil, nil, nil, 77, 83, 209, 246, -403, nil, nil, + nil, 57, nil, 78, -403, -403, -403, nil, nil, -403, + -403, -403, nil, -403, nil, nil, nil, nil, nil, nil, + nil, nil, -403, -403, -403, nil, nil, nil, nil, nil, + nil, nil, nil, -403, -403, nil, -403, -403, -403, -403, + -403, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, -403, -403, -403, -403, -403, -403, -403, + -403, -403, -403, -403, -403, -403, -403, nil, nil, -403, + -403, -403, nil, nil, -403, nil, 252, -403, nil, nil, + -403, -403, nil, -403, nil, -403, nil, -403, nil, -403, + -403, -403, -403, -403, -403, -403, -293, -403, -403, -403, + nil, nil, nil, -293, -293, -293, nil, nil, -293, -293, + -293, nil, -293, -403, -403, nil, -403, nil, -403, nil, + nil, nil, -293, -293, nil, nil, nil, nil, nil, nil, + nil, nil, -293, -293, nil, -293, -293, -293, -293, -293, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, -293, -293, -293, -293, -293, -293, -293, -293, + -293, -293, -293, -293, -293, -293, nil, nil, -293, -293, + -293, nil, nil, -293, nil, 261, -293, nil, nil, -293, + -293, nil, -293, nil, -293, nil, -293, nil, -293, -293, + -293, -293, -293, -293, -293, -239, -293, nil, -293, nil, + nil, nil, -239, -239, -239, nil, nil, -239, -239, -239, + nil, -239, -293, -293, nil, -293, nil, -293, nil, nil, + -239, -239, -239, nil, nil, nil, nil, nil, nil, nil, + nil, -239, -239, nil, -239, -239, -239, -239, -239, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, -239, -239, -239, -239, -239, -239, -239, -239, -239, + -239, -239, -239, -239, -239, nil, nil, -239, -239, -239, + nil, nil, -239, nil, 252, -239, nil, nil, -239, -239, + nil, -239, nil, -239, nil, -239, nil, -239, -239, -239, + -239, -239, -239, -239, -239, -239, -239, -239, nil, nil, + nil, -239, -239, -239, nil, nil, -239, -239, -239, nil, + -239, -239, -239, nil, -239, nil, -239, nil, nil, nil, + -239, nil, nil, nil, nil, nil, nil, nil, nil, nil, + -239, -239, nil, -239, -239, -239, -239, -239, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, -239, + nil, nil, nil, nil, nil, nil, -239, -239, -239, nil, + nil, -239, -239, -239, nil, -239, nil, nil, nil, nil, + nil, -239, nil, nil, nil, -239, nil, nil, -239, nil, + nil, nil, nil, 252, -239, -239, -239, nil, -239, -239, + -239, -239, -239, nil, nil, nil, nil, nil, 394, 398, + nil, nil, 395, nil, nil, nil, -239, nil, nil, nil, + 149, 150, nil, 146, 128, 129, 130, 137, 134, 136, + -239, nil, 131, 132, nil, -239, -239, 151, 152, 138, + 139, nil, nil, -239, nil, nil, 252, nil, 252, -239, + nil, nil, nil, nil, 143, 142, nil, 127, 148, 145, + 144, 140, 141, 135, 133, 125, 147, 126, nil, nil, + 153, -239, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, -239, nil, nil, nil, nil, + -239, 164, 175, 165, 188, 161, 181, 171, 170, 191, + 192, 186, 169, 168, 163, 189, 193, 194, 173, 162, + 176, 180, 182, 174, 167, nil, nil, nil, 183, 190, + 185, 184, 177, 187, 172, 160, 179, 178, nil, nil, + nil, nil, nil, 159, 166, 157, 158, 154, 155, 156, + 116, 118, 115, nil, 117, nil, nil, nil, nil, nil, + nil, nil, 149, 150, nil, 146, 128, 129, 130, 137, + 134, 136, nil, nil, 131, 132, nil, nil, nil, 151, + 152, 138, 139, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 143, 142, nil, 127, + 148, 145, 144, 140, 141, 135, 133, 125, 147, 126, + nil, nil, 153, 84, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 83, 164, 175, 165, 188, 161, + 181, 171, 170, 191, 192, 186, 169, 168, 163, 189, + 193, 194, 173, 162, 176, 180, 182, 174, 167, nil, + nil, nil, 183, 190, 185, 184, 177, 187, 172, 160, + 179, 178, nil, nil, nil, nil, nil, 159, 166, 157, + 158, 154, 155, 156, 116, 118, nil, nil, 117, nil, + nil, nil, nil, nil, nil, nil, 149, 150, nil, 146, + 128, 129, 130, 137, 134, 136, nil, nil, 131, 132, + nil, nil, nil, 151, 152, 138, 139, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 143, 142, nil, 127, 148, 145, 144, 140, 141, 135, + 133, 125, 147, 126, nil, nil, 153, 84, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 83, 164, + 175, 165, 188, 161, 181, 171, 170, 191, 192, 186, + 169, 168, 163, 189, 193, 194, 173, 162, 176, 180, + 182, 174, 167, nil, nil, nil, 183, 190, 185, 184, + 177, 187, 172, 160, 179, 178, nil, nil, nil, nil, + nil, 159, 166, 157, 158, 154, 155, 156, 116, 118, + nil, nil, 117, nil, nil, nil, nil, nil, nil, nil, + 149, 150, nil, 146, 128, 129, 130, 137, 134, 136, + nil, nil, 131, 132, nil, nil, nil, 151, 152, 138, + 139, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 143, 142, nil, 127, 148, 145, + 144, 140, 141, 135, 133, 125, 147, 126, nil, nil, + 153, 84, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 83, 164, 175, 165, 188, 161, 181, 171, + 170, 191, 192, 186, 169, 168, 163, 189, 193, 194, + 173, 162, 176, 180, 182, 174, 167, nil, nil, nil, + 183, 190, 185, 184, 177, 187, 172, 160, 179, 178, + nil, nil, nil, nil, nil, 159, 166, 157, 158, 154, + 155, 156, 116, 118, nil, nil, 117, nil, nil, nil, + nil, nil, nil, nil, 149, 150, nil, 146, 128, 129, + 130, 137, 134, 136, nil, nil, 131, 132, nil, nil, + nil, 151, 152, 138, 139, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 143, 142, + nil, 127, 148, 145, 144, 140, 141, 135, 133, 125, + 147, 126, nil, nil, 153, 84, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 83, 164, 175, 165, + 188, 161, 181, 171, 170, 191, 192, 186, 169, 168, + 163, 189, 193, 194, 173, 162, 176, 180, 182, 174, + 167, nil, nil, nil, 183, 190, 185, 353, 352, 354, + 351, 160, 179, 178, nil, nil, nil, nil, nil, 159, + 166, 157, 158, 348, 349, 350, 346, 118, 89, 88, + 347, nil, 91, nil, nil, nil, nil, nil, 149, 150, + nil, 146, 128, 129, 130, 137, 134, 136, nil, nil, + 131, 132, nil, nil, nil, 151, 152, 138, 139, nil, + nil, nil, nil, nil, 358, nil, nil, nil, nil, nil, + nil, nil, 143, 142, nil, 127, 148, 145, 144, 140, + 141, 135, 133, 125, 147, 126, nil, nil, 153, 164, + 175, 165, 188, 161, 181, 171, 170, 191, 192, 186, + 169, 168, 163, 189, 193, 194, 173, 162, 176, 180, + 182, 174, 167, nil, nil, nil, 183, 190, 185, 184, + 177, 187, 172, 160, 179, 178, nil, nil, nil, nil, + nil, 159, 166, 157, 158, 154, 155, 156, 116, 118, + nil, nil, 117, nil, nil, nil, nil, nil, nil, nil, + 149, 150, nil, 146, 128, 129, 130, 137, 134, 136, + nil, nil, 131, 132, nil, nil, nil, 151, 152, 138, + 139, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 143, 142, nil, 127, 148, 145, + 144, 140, 141, 135, 133, 125, 147, 126, 401, 405, + 153, nil, 400, nil, nil, nil, nil, nil, nil, nil, + 149, 150, nil, 146, 128, 129, 130, 137, 134, 136, + nil, nil, 131, 132, nil, nil, nil, 151, 152, 138, + 139, nil, nil, nil, nil, nil, 252, nil, nil, nil, + nil, nil, nil, nil, 143, 142, nil, 127, 148, 145, + 144, 140, 141, 135, 133, 125, 147, 126, 450, 398, + 153, nil, 451, nil, nil, nil, nil, nil, nil, nil, + 149, 150, nil, 146, 128, 129, 130, 137, 134, 136, + nil, nil, 131, 132, nil, nil, nil, 151, 152, 138, + 139, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 143, 142, nil, 127, 148, 145, + 144, 140, 141, 135, 133, 125, 147, 126, 450, 398, + 153, nil, 451, nil, nil, nil, nil, nil, nil, nil, + 149, 150, nil, 146, 128, 129, 130, 137, 134, 136, + nil, nil, 131, 132, nil, nil, nil, 151, 152, 138, + 139, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 143, 142, nil, 127, 148, 145, + 144, 140, 141, 135, 133, 125, 147, 126, 579, 398, + 153, nil, 580, nil, nil, nil, nil, nil, nil, nil, + 149, 150, nil, 146, 128, 129, 130, 137, 134, 136, + nil, nil, 131, 132, nil, nil, nil, 151, 152, 138, + 139, nil, nil, nil, nil, nil, 252, nil, nil, nil, + nil, nil, nil, nil, 143, 142, nil, 127, 148, 145, + 144, 140, 141, 135, 133, 125, 147, 126, 581, 405, + 153, nil, 582, nil, nil, nil, nil, nil, nil, nil, + 149, 150, nil, 146, 128, 129, 130, 137, 134, 136, + nil, nil, 131, 132, nil, nil, nil, 151, 152, 138, + 139, nil, nil, nil, nil, nil, 252, nil, nil, nil, + nil, nil, nil, nil, 143, 142, nil, 127, 148, 145, + 144, 140, 141, 135, 133, 125, 147, 126, 617, 398, + 153, nil, 618, nil, nil, nil, nil, nil, nil, nil, + 149, 150, nil, 146, 128, 129, 130, 137, 134, 136, + nil, nil, 131, 132, nil, nil, nil, 151, 152, 138, + 139, nil, nil, nil, nil, nil, 252, nil, nil, nil, + nil, nil, nil, nil, 143, 142, nil, 127, 148, 145, + 144, 140, 141, 135, 133, 125, 147, 126, 620, 405, + 153, nil, 621, nil, nil, nil, nil, nil, nil, nil, + 149, 150, nil, 146, 128, 129, 130, 137, 134, 136, + nil, nil, 131, 132, nil, nil, nil, 151, 152, 138, + 139, nil, nil, nil, nil, nil, 252, nil, nil, nil, + nil, nil, nil, nil, 143, 142, nil, 127, 148, 145, + 144, 140, 141, 135, 133, 125, 147, 126, 579, 398, + 153, nil, 580, nil, nil, nil, nil, nil, nil, nil, + 149, 150, nil, 146, 128, 129, 130, 137, 134, 136, + nil, nil, 131, 132, nil, nil, nil, 151, 152, 138, + 139, nil, nil, nil, nil, nil, 252, nil, nil, nil, + nil, nil, nil, nil, 143, 142, nil, 127, 148, 145, + 144, 140, 141, 135, 133, 125, 147, 126, 581, 405, + 153, nil, 582, nil, nil, nil, nil, nil, nil, nil, + 149, 150, nil, 146, 128, 129, 130, 137, 134, 136, + nil, nil, 131, 132, nil, nil, nil, 151, 152, 138, + 139, nil, nil, nil, nil, nil, 252, nil, nil, nil, + nil, nil, nil, nil, 143, 142, nil, 127, 148, 145, + 144, 140, 141, 135, 133, 125, 147, 126, 673, 398, + 153, nil, 674, nil, nil, nil, nil, nil, nil, nil, + 149, 150, nil, 146, 128, 129, 130, 137, 134, 136, + nil, nil, 131, 132, nil, nil, nil, 151, 152, 138, + 139, nil, nil, nil, nil, nil, 252, nil, nil, nil, + nil, nil, nil, nil, 143, 142, nil, 127, 148, 145, + 144, 140, 141, 135, 133, 125, 147, 126, 675, 405, + 153, nil, 676, nil, nil, nil, nil, nil, nil, nil, + 149, 150, nil, 146, 128, 129, 130, 137, 134, 136, + nil, nil, 131, 132, nil, nil, nil, 151, 152, 138, + 139, nil, nil, nil, nil, nil, 252, nil, nil, nil, + nil, nil, nil, nil, 143, 142, nil, 127, 148, 145, + 144, 140, 141, 135, 133, 125, 147, 126, 678, 405, + 153, nil, 679, nil, nil, nil, nil, nil, nil, nil, + 149, 150, nil, 146, 128, 129, 130, 137, 134, 136, + nil, nil, 131, 132, nil, nil, nil, 151, 152, 138, + 139, nil, nil, nil, nil, nil, 252, nil, nil, nil, + nil, nil, nil, nil, 143, 142, nil, 127, 148, 145, + 144, 140, 141, 135, 133, 125, 147, 126, 450, 398, + 153, nil, 451, nil, nil, nil, nil, nil, nil, nil, + 149, 150, nil, 146, 128, 129, 130, 137, 134, 136, + nil, nil, 131, 132, nil, nil, nil, 151, 152, 138, + 139, nil, nil, nil, nil, nil, 252, nil, nil, nil, + nil, nil, nil, nil, 143, 142, nil, 127, 148, 145, + 144, 140, 141, 135, 133, 125, 147, 126, 927, 398, + 153, nil, 928, nil, nil, nil, nil, nil, nil, nil, + 149, 150, nil, 146, 128, 129, 130, 137, 134, 136, + nil, nil, 131, 132, nil, nil, nil, 151, 152, 138, + 139, nil, nil, nil, nil, nil, 252, nil, nil, nil, + nil, nil, nil, nil, 143, 142, nil, 127, 148, 145, + 144, 140, 141, 135, 133, 125, 147, 126, 929, 405, + 153, nil, 930, nil, nil, nil, nil, nil, nil, nil, + 149, 150, nil, 146, 128, 129, 130, 137, 134, 136, + nil, nil, 131, 132, nil, nil, nil, 151, 152, 138, + 139, nil, nil, nil, nil, nil, 252, nil, nil, nil, + nil, nil, nil, nil, 143, 142, nil, 127, 148, 145, + 144, 140, 141, 135, 133, 125, 147, 126, 949, 405, + 153, nil, 948, nil, nil, nil, nil, nil, nil, nil, + 149, 150, nil, 146, 128, 129, 130, 137, 134, 136, + nil, nil, 131, 132, nil, nil, nil, 151, 152, 138, + 139, nil, nil, nil, nil, nil, 252, nil, nil, nil, + nil, nil, nil, nil, 143, 142, nil, 127, 148, 145, + 144, 140, 141, 135, 133, 125, 147, 126, nil, nil, + 153, 228, 232, 237, 238, 239, 234, 236, 244, 245, + 240, 241, nil, 221, 222, nil, nil, 242, 243, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, 231, nil, 227, 226, 223, + 224, 235, 233, 229, nil, 230, nil, 228, 232, 237, + 238, 239, 234, 236, 244, 245, 240, 241, nil, 221, + 222, nil, 246, 242, 243, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 225, + nil, 231, nil, 227, 226, 223, 224, 235, 233, 229, + nil, 230, nil, 228, 232, 237, 238, 239, 234, 236, + 244, 245, 240, 241, nil, 221, 222, nil, 246, 242, + 243, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, 231, nil, 227, + 226, 223, 224, 235, 233, 229, nil, 230, nil, 228, + 232, 237, 238, 239, 234, 236, 244, 245, 240, 241, + nil, 221, 222, nil, 246, 242, 243, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 225, nil, 231, nil, 227, 226, 223, 224, 235, + 233, 229, nil, 230, nil, 228, 232, 237, 238, 239, + 234, 236, 244, 245, 240, 241, nil, 221, 222, nil, + 246, 242, 243, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 225, nil, 231, + nil, 227, 226, 223, 224, 235, 233, 229, nil, 230, + nil, 228, 232, 237, 238, 239, 234, 236, 244, 245, + 240, 241, nil, 221, 222, nil, 246, 242, 243, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, 231, nil, 227, 226, 223, + 224, 235, 233, 229, nil, 230, nil, 228, 232, 237, + 238, 239, 234, 236, 244, 245, 240, 241, nil, 221, + 222, nil, 246, 242, 243, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 225, + nil, 231, nil, 227, 226, 223, 224, 235, 233, 229, + nil, 230, nil, 228, 232, 237, 238, 239, 234, 236, + 244, 245, 240, 241, nil, 221, 222, nil, 246, 242, + 243, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, 231, nil, 227, + 226, 223, 224, 235, 233, 229, nil, 230, nil, 228, + 232, 237, 238, 239, 234, 236, 244, 245, 240, 241, + nil, 221, 222, nil, 246, 242, 243, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 225, nil, 231, nil, 227, 226, 223, 224, 235, + 233, 229, nil, 230, nil, 228, 232, 237, 238, 239, + 234, 236, 244, 245, 240, 241, nil, 221, 222, nil, + 246, 242, 243, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 225, nil, 231, + nil, 227, 226, 223, 224, 235, 233, 229, nil, 230, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246 ] + +racc_action_check = [ + 87, 0, 0, 0, 0, 0, 0, 87, 87, 87, + 0, 0, 87, 87, 87, 0, 87, 0, 0, 0, + 0, 0, 0, 0, 87, 56, 87, 87, 87, 0, + 0, 0, 0, 0, 0, 0, 87, 87, 0, 87, + 87, 87, 87, 87, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 342, 0, 0, 0, + 322, 0, 0, 0, 0, 0, 87, 87, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 1, 597, 87, 87, 87, 0, 87, 87, 0, 329, + 87, 0, 0, 87, 87, 0, 87, 0, 87, 364, + 87, 0, 87, 87, 87, 87, 87, 87, 87, 0, + 87, 56, 87, 332, 0, 0, 0, 0, 18, 0, + 0, 7, 524, 597, 0, 0, 87, 87, 87, 87, + 90, 87, 0, 87, 0, 87, 638, 90, 90, 90, + 212, 15, 90, 90, 90, 516, 90, 338, 323, 617, + 10, 338, 671, 448, 90, 18, 90, 90, 90, 673, + 313, 342, 364, 313, 11, 674, 90, 90, 517, 90, + 90, 90, 90, 90, 322, 753, 853, 927, 928, 322, + 788, 342, 536, 536, 15, 951, 342, 448, 3, 212, + 15, 459, 12, 3, 329, 214, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 412, 412, 90, 90, 90, 617, 90, 90, 332, 13, + 90, 929, 618, 90, 90, 459, 90, 524, 90, 21, + 90, 789, 90, 90, 90, 90, 90, 90, 90, 400, + 90, 638, 90, 35, 214, 516, 400, 400, 400, 460, + 516, 617, 400, 400, 617, 400, 90, 90, 90, 90, + 617, 90, 323, 90, 673, 90, 671, 323, 517, 671, + 674, 671, 536, 517, 24, 400, 400, 536, 400, 400, + 400, 400, 400, 460, 37, 788, 292, 675, 618, 753, + 853, 927, 928, 676, 753, 853, 927, 928, 929, 951, + 412, 858, 42, 858, 951, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, 400, 542, + 542, 400, 400, 400, 618, 400, 36, 618, 101, 400, + 418, 789, 400, 618, 360, 929, 789, 400, 24, 400, + 929, 400, 400, 400, 400, 400, 400, 400, 401, 400, + 292, 400, 675, 628, 628, 401, 401, 401, 676, 650, + 24, 401, 401, 579, 401, 400, 400, 594, 400, 36, + 400, 23, 292, 401, 400, 36, 336, 746, 23, 418, + 314, 16, 16, 314, 401, 401, 346, 401, 401, 401, + 401, 401, 675, 346, 195, 360, 360, 360, 676, 732, + 774, 594, 774, 774, 774, 774, 774, 650, 361, 542, + 317, 213, 579, 317, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, 401, 401, 401, 336, 746, + 401, 401, 401, 215, 401, 336, 746, 216, 401, 580, + 336, 401, 362, 628, 336, 746, 401, 732, 401, 220, + 401, 401, 401, 401, 401, 401, 401, 74, 401, 401, + 401, 363, 336, 746, 38, 38, 74, 337, 620, 361, + 361, 361, 723, 581, 401, 401, 74, 401, 774, 401, + 581, 581, 581, 401, 347, 581, 581, 581, 580, 581, + 901, 347, 901, 901, 901, 901, 901, 424, 581, 581, + 581, 581, 115, 362, 362, 362, 678, 115, 115, 581, + 581, 348, 581, 581, 581, 581, 581, 251, 348, 337, + 620, 723, 363, 363, 363, 553, 337, 620, 365, 424, + 349, 337, 620, 424, 424, 337, 620, 349, 265, 581, + 581, 581, 581, 581, 581, 581, 581, 581, 581, 581, + 581, 581, 581, 337, 620, 581, 581, 581, 678, 581, + 581, 297, 297, 581, 301, 678, 581, 581, 901, 581, + 678, 581, 266, 581, 678, 581, 581, 581, 581, 581, + 581, 581, 612, 581, 581, 581, 553, 553, 612, 365, + 365, 365, 678, 269, 637, 553, 443, 637, 394, 581, + 581, 581, 581, 582, 581, 395, 581, 301, 581, 566, + 582, 582, 582, 301, 278, 582, 582, 582, 587, 582, + 587, 587, 587, 587, 587, 425, 311, 311, 443, 582, + 582, 582, 443, 443, 443, 443, 321, 321, 280, 582, + 582, 394, 582, 582, 582, 582, 582, 394, 395, 350, + 662, 662, 566, 351, 395, 587, 350, 425, 566, 281, + 351, 425, 425, 275, 587, 587, 587, 587, 275, 582, + 582, 582, 582, 582, 582, 582, 582, 582, 582, 582, + 582, 582, 582, 282, 14, 582, 582, 582, 43, 582, + 582, 14, 287, 582, 290, 43, 582, 582, 587, 582, + 14, 582, 291, 582, 43, 582, 582, 582, 582, 582, + 582, 582, 296, 582, 298, 582, 302, 639, 352, 639, + 639, 639, 639, 639, 303, 352, 353, 306, 354, 582, + 582, 582, 582, 353, 582, 354, 582, 309, 582, 31, + 31, 31, 31, 31, 31, 356, 326, 310, 31, 31, + 315, 326, 356, 31, 639, 31, 31, 31, 31, 31, + 31, 31, 316, 639, 639, 639, 639, 31, 31, 31, + 31, 31, 31, 31, 546, 546, 31, 318, 546, 546, + 546, 383, 31, 31, 327, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 328, 31, 31, 31, 331, 31, + 31, 31, 31, 31, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 211, 383, 383, 285, 535, + 383, 383, 211, 31, 535, 285, 31, 683, 333, 31, + 31, 211, 683, 31, 285, 31, 383, 374, 383, 31, + 383, 383, 383, 383, 383, 383, 383, 31, 383, 941, + 941, 689, 31, 31, 31, 31, 689, 31, 31, 444, + 380, 286, 31, 31, 386, 383, 51, 383, 286, 388, + 31, 392, 31, 51, 51, 51, 402, 286, 51, 51, + 51, 511, 51, 511, 511, 511, 511, 511, 414, 426, + 427, 444, 51, 51, 51, 444, 444, 444, 444, 428, + 429, 455, 51, 51, 461, 51, 51, 51, 51, 51, + 850, 474, 850, 850, 850, 850, 850, 475, 511, 511, + 902, 478, 902, 902, 902, 902, 902, 511, 511, 511, + 511, 480, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 485, 850, 51, 51, + 51, 288, 489, 51, 498, 501, 51, 902, 288, 51, + 51, 513, 51, 518, 51, 519, 51, 288, 51, 51, + 51, 51, 51, 51, 51, 304, 51, 550, 51, 556, + 330, 563, 304, 567, 570, 575, 583, 330, 585, 598, + 600, 304, 51, 51, 51, 51, 330, 51, 605, 51, + 52, 52, 52, 52, 52, 52, 607, 614, 340, 52, + 52, 616, 619, 622, 52, 340, 52, 52, 52, 52, + 52, 52, 52, 623, 340, 626, 627, 629, 52, 52, + 52, 52, 52, 52, 52, 632, 653, 52, 653, 653, + 653, 653, 653, 52, 52, 633, 52, 52, 52, 52, + 52, 52, 52, 52, 52, 641, 52, 52, 52, 642, + 52, 52, 52, 52, 52, 771, 643, 771, 771, 771, + 771, 771, 766, 653, 766, 766, 766, 766, 766, 484, + 651, 527, 653, 658, 52, 661, 484, 52, 527, 664, + 52, 52, 669, 672, 52, 484, 52, 527, 681, 686, + 52, 810, 771, 810, 810, 810, 810, 810, 52, 766, + 704, 771, 725, 52, 52, 52, 52, 726, 52, 52, + 766, 766, 727, 52, 52, 113, 113, 113, 113, 113, + 113, 52, 729, 52, 113, 113, 730, 734, 810, 113, + 739, 113, 113, 113, 113, 113, 113, 113, 740, 810, + 810, 741, 745, 113, 113, 113, 113, 113, 113, 113, + 760, 848, 113, 848, 848, 848, 848, 848, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 767, 113, 113, 113, 773, 113, 113, 113, 113, 113, + 938, 775, 938, 938, 938, 938, 938, 893, 848, 893, + 893, 893, 893, 893, 829, 776, 621, 848, 779, 113, + 782, 829, 113, 621, 791, 113, 113, 795, 621, 113, + 829, 113, 621, 796, 799, 113, 895, 938, 895, 895, + 895, 895, 895, 113, 893, 800, 812, 813, 113, 113, + 113, 113, 819, 113, 113, 893, 893, 820, 113, 113, + 197, 197, 197, 197, 197, 197, 113, 822, 113, 197, + 197, 826, 831, 895, 197, 836, 197, 197, 197, 197, + 197, 197, 197, 837, 895, 895, 838, 841, 197, 197, + 197, 197, 197, 197, 197, 842, 940, 197, 940, 940, + 940, 940, 940, 197, 197, 844, 197, 197, 197, 197, + 197, 197, 197, 197, 197, 847, 197, 197, 197, 849, + 197, 197, 197, 197, 197, 957, 855, 957, 957, 957, + 957, 957, 897, 940, 897, 897, 897, 897, 897, 830, + 856, 679, 832, 861, 197, 866, 830, 197, 679, 832, + 197, 197, 867, 679, 197, 830, 197, 679, 832, 868, + 197, 916, 957, 916, 916, 916, 916, 916, 197, 897, + 869, 871, 875, 197, 197, 197, 197, 882, 197, 197, + 897, 897, 887, 197, 197, 219, 219, 219, 219, 219, + 219, 197, 888, 197, 219, 219, 903, 924, 916, 219, + 926, 219, 219, 219, 219, 219, 219, 219, 933, 916, + 916, 934, 935, 219, 219, 219, 219, 219, 219, 219, + 936, 731, 219, 731, 731, 731, 937, 731, 219, 219, + 939, 219, 219, 219, 219, 219, 219, 219, 219, 219, + 942, 219, 219, 219, 943, 219, 219, 219, 219, 219, + 873, 874, 873, 873, 873, 944, 873, 918, 874, 918, + 918, 918, 918, 918, 886, 945, 930, 874, 946, 219, + 947, 886, 219, 930, 948, 219, 219, 949, 930, 219, + 886, 219, 930, 958, 967, 219, 953, 968, 953, 953, + 953, 953, 953, 219, 918, 969, nil, nil, 219, 219, + 219, 219, nil, 219, 219, 918, 918, nil, 219, 219, + 279, 279, 279, 279, 279, 279, 219, nil, 219, 279, + 279, nil, nil, 953, 279, nil, 279, 279, 279, 279, + 279, 279, 279, nil, 953, 953, nil, nil, 279, 279, + 279, 279, 279, 279, 279, nil, nil, 279, 6, 6, + 6, 6, 6, 279, 279, nil, 279, 279, 279, 279, + 279, 279, 279, 279, 279, nil, 279, 279, 279, nil, + 279, 279, 279, 279, 279, 430, 276, 276, 276, 276, + 276, nil, 963, nil, 963, 963, 963, 963, 963, nil, + nil, 430, 430, nil, 279, nil, nil, 279, nil, nil, + 279, 279, nil, nil, 279, nil, 279, 430, nil, 430, + 279, 430, 430, 430, 430, nil, nil, nil, 279, 963, + nil, nil, nil, 279, 279, 279, 279, nil, 279, 279, + 963, 963, nil, 279, 279, 284, 284, 284, 284, 284, + 284, 279, nil, 279, 284, 284, nil, nil, nil, 284, + nil, 284, 284, 284, 284, 284, 284, 284, 473, 473, + 473, 473, 473, 284, 284, 284, 284, 284, 284, 284, + nil, nil, 284, nil, nil, nil, nil, 391, 284, 284, + nil, 284, 284, 284, 284, 284, 284, 284, 284, 284, + nil, 284, 284, 284, nil, 284, 284, 284, 284, 284, + 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, + 391, nil, 391, 391, nil, nil, 391, 391, nil, 284, + nil, nil, 284, nil, nil, 284, 284, nil, nil, 284, + nil, 284, 391, nil, 391, 284, 391, 391, 391, 391, + 391, 391, 391, 284, 391, nil, nil, nil, 284, 284, + 284, 284, nil, 284, 284, nil, nil, nil, 284, 284, + nil, 391, 405, nil, nil, nil, 284, nil, 284, 405, + 405, 405, nil, nil, 405, 405, 405, 538, 405, 538, + 538, 538, 538, 538, nil, nil, nil, 405, 405, 405, + 405, 611, 611, 611, 611, 611, nil, nil, 405, 405, + nil, 405, 405, 405, 405, 405, nil, nil, nil, nil, + nil, nil, nil, nil, 538, 538, nil, nil, nil, nil, + nil, nil, nil, 538, 538, 538, 538, nil, 405, 405, + 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, + 405, 405, nil, nil, 405, 405, 405, nil, nil, 405, + nil, nil, 405, nil, nil, 405, 405, nil, 405, nil, + 405, nil, 405, nil, 405, 405, 405, 405, 405, 405, + 405, 406, 405, 405, 405, nil, nil, nil, 406, 406, + 406, nil, nil, 406, 406, 406, 434, 406, 405, 405, + 405, 405, nil, 405, nil, 405, 406, 406, 406, 406, + nil, nil, 434, 434, nil, nil, nil, 406, 406, nil, + 406, 406, 406, 406, 406, nil, nil, nil, 434, nil, + 434, nil, 434, 434, 434, 434, nil, nil, 434, nil, + 434, nil, nil, nil, nil, nil, nil, 406, 406, 406, + 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, + 406, nil, nil, 406, 406, 406, nil, nil, 406, nil, + nil, 406, nil, nil, 406, 406, nil, 406, nil, 406, + nil, 406, nil, 406, 406, 406, 406, 406, 406, 406, + nil, 406, 406, 406, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 406, 406, 406, + 406, nil, 406, nil, 406, 512, 512, 512, 512, 512, + 512, nil, nil, nil, 512, 512, nil, nil, nil, 512, + nil, 512, 512, 512, 512, 512, 512, 512, nil, nil, + nil, nil, nil, 512, 512, 512, 512, 512, 512, 512, + nil, nil, 512, nil, nil, nil, nil, nil, 512, 512, + nil, 512, 512, 512, 512, 512, 512, 512, 512, 512, + nil, 512, 512, 512, nil, 512, 512, 512, 512, 512, + 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, + 422, nil, 422, 422, nil, nil, 422, 422, nil, 512, + nil, nil, 512, nil, nil, 512, 512, nil, nil, 512, + nil, 512, 422, nil, 422, 512, 422, 422, 422, 422, + 422, 422, 422, 512, 422, nil, nil, nil, 512, 512, + 512, 512, nil, 512, 512, nil, nil, nil, 512, 512, + 515, 515, 515, 515, 515, 515, 512, nil, 512, 515, + 515, nil, nil, nil, 515, nil, 515, 515, 515, 515, + 515, 515, 515, nil, nil, nil, nil, nil, 515, 515, + 515, 515, 515, 515, 515, nil, nil, 515, nil, nil, + nil, nil, nil, 515, 515, nil, 515, 515, 515, 515, + 515, 515, 515, 515, 515, nil, 515, 515, 515, nil, + 515, 515, 515, 515, 515, 423, 423, 423, 423, 423, + 423, 423, 423, 423, 423, 423, nil, 423, 423, nil, + nil, 423, 423, nil, 515, nil, nil, 515, nil, nil, + 515, 515, nil, nil, 515, nil, 515, 423, nil, 423, + 515, 423, 423, 423, 423, 423, 423, 423, 515, 423, + nil, nil, nil, 515, 515, 515, 515, nil, 515, 515, + nil, nil, nil, 515, 515, 537, 537, 537, 537, 537, + 537, 515, nil, 515, 537, 537, nil, nil, nil, 537, + nil, 537, 537, 537, 537, 537, 537, 537, nil, nil, + nil, nil, nil, 537, 537, 537, 537, 537, 537, 537, + nil, nil, 537, nil, nil, nil, nil, nil, 537, 537, + nil, 537, 537, 537, 537, 537, 537, 537, 537, 537, + nil, 537, 537, 537, nil, 537, 537, 537, 537, 537, + 433, 433, 433, 433, 433, 433, 433, nil, nil, 433, + 433, nil, nil, nil, nil, nil, 433, 433, nil, 537, + nil, nil, 537, nil, nil, 537, 537, nil, nil, 537, + nil, 537, 433, nil, 433, 537, 433, 433, 433, 433, + 433, 433, 433, 537, 433, nil, nil, nil, 537, 537, + 537, 537, nil, 537, 537, nil, nil, nil, 537, 537, + 589, 589, 589, 589, 589, 589, 537, nil, 537, 589, + 589, nil, nil, nil, 589, nil, 589, 589, 589, 589, + 589, 589, 589, nil, nil, nil, nil, nil, 589, 589, + 589, 589, 589, 589, 589, nil, nil, 589, nil, nil, + nil, nil, nil, 589, 589, nil, 589, 589, 589, 589, + 589, 589, 589, 589, 589, nil, 589, 589, 589, nil, + 589, 589, 589, 589, 589, 435, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 435, 435, nil, 589, nil, nil, 589, nil, nil, + 589, 589, nil, nil, 589, nil, 589, 435, nil, 435, + 589, 435, 435, 435, 435, nil, nil, 435, 589, 435, + nil, nil, nil, 589, 589, 589, 589, nil, 589, 589, + nil, nil, nil, 589, 589, 602, 602, 602, 602, 602, + 602, 589, nil, 589, 602, 602, nil, nil, nil, 602, + nil, 602, 602, 602, 602, 602, 602, 602, nil, nil, + nil, nil, nil, 602, 602, 602, 602, 602, 602, 602, + nil, nil, 602, nil, nil, nil, nil, nil, 602, 602, + nil, 602, 602, 602, 602, 602, 602, 602, 602, 602, + nil, 602, 602, 602, nil, 602, 602, 602, 602, 602, + 436, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 436, 436, nil, 602, + nil, nil, 602, nil, nil, 602, 602, nil, nil, 602, + nil, 602, 436, nil, 436, 602, 436, 436, 436, 436, + nil, nil, 436, 602, 436, nil, nil, nil, 602, 602, + 602, 602, nil, 602, 602, nil, nil, nil, 602, 602, + 603, 603, 603, 603, 603, 603, 602, nil, 602, 603, + 603, nil, nil, nil, 603, nil, 603, 603, 603, 603, + 603, 603, 603, nil, nil, nil, nil, nil, 603, 603, + 603, 603, 603, 603, 603, nil, nil, 603, nil, nil, + nil, nil, nil, 603, 603, nil, 603, 603, 603, 603, + 603, 603, 603, 603, 603, nil, 603, 603, 603, nil, + 603, 603, 603, 603, 603, 437, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 437, 437, nil, 603, nil, nil, 603, nil, nil, + 603, 603, nil, nil, 603, nil, 603, 437, nil, 437, + 603, 437, 437, 437, 437, nil, nil, 437, 603, 437, + nil, nil, nil, 603, 603, 603, 603, nil, 603, 603, + nil, nil, nil, 603, 603, 631, 631, 631, 631, 631, + 631, 603, nil, 603, 631, 631, nil, nil, nil, 631, + nil, 631, 631, 631, 631, 631, 631, 631, nil, nil, + nil, nil, nil, 631, 631, 631, 631, 631, 631, 631, + nil, nil, 631, nil, nil, nil, nil, nil, 631, 631, + nil, 631, 631, 631, 631, 631, 631, 631, 631, 631, + nil, 631, 631, 631, nil, 631, 631, 631, 631, 631, + 438, 438, 438, 438, 438, 438, 438, nil, nil, 438, + 438, nil, nil, nil, nil, nil, 438, 438, nil, 631, + nil, nil, 631, nil, nil, 631, 631, nil, nil, 631, + nil, 631, 438, nil, 438, 631, 438, 438, 438, 438, + 438, 438, 438, 631, 438, nil, nil, nil, 631, 631, + 631, 631, nil, 631, 631, nil, nil, nil, 631, 631, + 682, 682, 682, 682, 682, 682, 631, nil, 631, 682, + 682, nil, nil, nil, 682, nil, 682, 682, 682, 682, + 682, 682, 682, nil, nil, nil, nil, nil, 682, 682, + 682, 682, 682, 682, 682, nil, nil, 682, nil, nil, + nil, nil, nil, 682, 682, nil, 682, 682, 682, 682, + 682, 682, 682, 682, 682, nil, 682, 682, 682, nil, + 682, 682, 682, 682, 682, 439, 439, 439, 439, 439, + 439, 439, nil, nil, 439, 439, nil, nil, nil, nil, + nil, 439, 439, nil, 682, nil, nil, 682, nil, nil, + 682, 682, nil, nil, 682, nil, 682, 439, nil, 439, + 682, 439, 439, 439, 439, 439, 439, 439, 682, 439, + nil, nil, nil, 682, 682, 682, 682, nil, 682, 682, + nil, nil, nil, 682, 682, 687, 687, 687, 687, 687, + 687, 682, nil, 682, 687, 687, nil, nil, nil, 687, + nil, 687, 687, 687, 687, 687, 687, 687, nil, nil, + nil, nil, nil, 687, 687, 687, 687, 687, 687, 687, + nil, nil, 687, nil, nil, nil, nil, nil, 687, 687, + nil, 687, 687, 687, 687, 687, 687, 687, 687, 687, + nil, 687, 687, 687, nil, 687, 687, 687, 687, 687, + 440, 440, 440, 440, 440, 440, 440, nil, nil, 440, + 440, nil, nil, nil, nil, nil, 440, 440, nil, 687, + nil, nil, 687, nil, nil, 687, 687, nil, nil, 687, + nil, 687, 440, nil, 440, 687, 440, 440, 440, 440, + 440, 440, 440, 687, 440, nil, nil, nil, 687, 687, + 687, 687, nil, 687, 687, nil, nil, nil, 687, 687, + 697, 697, 697, 697, 697, 697, 687, nil, 687, 697, + 697, nil, nil, nil, 697, nil, 697, 697, 697, 697, + 697, 697, 697, nil, nil, nil, nil, nil, 697, 697, + 697, 697, 697, 697, 697, nil, nil, 697, nil, nil, + nil, nil, nil, 697, 697, nil, 697, 697, 697, 697, + 697, 697, 697, 697, 697, nil, 697, 697, 697, nil, + 697, 697, 697, 697, 697, 441, 441, 441, 441, 441, + 441, 441, nil, nil, 441, 441, nil, nil, nil, nil, + nil, 441, 441, nil, 697, nil, nil, 697, nil, nil, + 697, 697, nil, nil, 697, nil, 697, 441, nil, 441, + 697, 441, 441, 441, 441, 441, 441, 441, 697, 441, + nil, nil, nil, 697, 697, 697, 697, nil, 697, 697, + nil, nil, nil, 697, 697, 735, 735, 735, 735, 735, + 735, 697, nil, 697, 735, 735, nil, nil, nil, 735, + nil, 735, 735, 735, 735, 735, 735, 735, nil, nil, + nil, nil, nil, 735, 735, 735, 735, 735, 735, 735, + nil, nil, 735, nil, nil, nil, nil, nil, 735, 735, + nil, 735, 735, 735, 735, 735, 735, 735, 735, 735, + nil, 735, 735, 735, nil, 735, 735, 735, 735, 735, + 442, 442, 442, 442, 442, 442, 442, nil, nil, 442, + 442, nil, nil, nil, nil, nil, 442, 442, nil, 735, + nil, nil, 735, nil, nil, 735, 735, nil, nil, 735, + nil, 735, 442, nil, 442, 735, 442, 442, 442, 442, + 442, 442, 442, 735, 442, nil, nil, nil, 735, 735, + 735, 735, nil, 735, 735, nil, nil, nil, 735, 735, + 750, 750, 750, 750, 750, 750, 735, nil, 735, 750, + 750, nil, nil, nil, 750, nil, 750, 750, 750, 750, + 750, 750, 750, nil, nil, nil, nil, nil, 750, 750, + 750, 750, 750, 750, 750, nil, nil, 750, nil, nil, + nil, nil, nil, 750, 750, nil, 750, 750, 750, 750, + 750, 750, 750, 750, 750, nil, 750, 750, 750, nil, + 750, 750, 750, 750, 750, 445, 445, 445, 445, 445, + 445, 445, nil, nil, 445, 445, nil, nil, nil, nil, + nil, 445, 445, nil, 750, nil, nil, 750, nil, nil, + 750, 750, nil, nil, 750, nil, 750, 445, nil, 445, + 750, 445, 445, 445, 445, 445, 445, 445, 750, 445, + nil, nil, nil, 750, 750, 750, 750, nil, 750, 750, + nil, nil, nil, 750, 750, 783, 783, 783, 783, 783, + 783, 750, nil, 750, 783, 783, nil, nil, nil, 783, + nil, 783, 783, 783, 783, 783, 783, 783, nil, nil, + nil, nil, nil, 783, 783, 783, 783, 783, 783, 783, + nil, nil, 783, nil, nil, nil, nil, nil, 783, 783, + nil, 783, 783, 783, 783, 783, 783, 783, 783, 783, + nil, 783, 783, 783, nil, 783, 783, 783, 783, 783, + 446, 446, 446, 446, 446, 446, 446, 446, nil, 446, + 446, nil, nil, nil, nil, nil, 446, 446, nil, 783, + nil, nil, 783, nil, nil, 783, 783, nil, nil, 783, + nil, 783, 446, nil, 446, 783, 446, 446, 446, 446, + 446, 446, 446, 783, 446, nil, nil, nil, 783, 783, + 783, 783, nil, 783, 783, nil, nil, nil, 783, 783, + 784, 784, 784, 784, 784, 784, 783, nil, 783, 784, + 784, nil, nil, nil, 784, nil, 784, 784, 784, 784, + 784, 784, 784, nil, nil, nil, nil, nil, 784, 784, + 784, 784, 784, 784, 784, nil, nil, 784, nil, nil, + nil, nil, nil, 784, 784, nil, 784, 784, 784, 784, + 784, 784, 784, 784, 784, nil, 784, 784, 784, nil, + 784, 784, 784, 784, 784, 431, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 431, 431, nil, 784, nil, nil, 784, nil, nil, + 784, 784, nil, nil, 784, nil, 784, 431, nil, 431, + 784, 431, 431, 431, 431, nil, nil, nil, 784, nil, + nil, nil, nil, 784, 784, 784, 784, nil, 784, 784, + nil, nil, nil, 784, 784, 787, 787, 787, 787, 787, + 787, 784, nil, 784, 787, 787, nil, nil, nil, 787, + nil, 787, 787, 787, 787, 787, 787, 787, nil, nil, + nil, nil, nil, 787, 787, 787, 787, 787, 787, 787, + nil, nil, 787, nil, nil, nil, nil, nil, 787, 787, + nil, 787, 787, 787, 787, 787, 787, 787, 787, 787, + nil, 787, 787, 787, nil, 787, 787, 787, 787, 787, + 432, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 432, 432, nil, 787, + nil, nil, 787, nil, nil, 787, 787, nil, nil, 787, + nil, 787, 432, nil, nil, 787, 432, 432, 432, 432, + nil, nil, nil, 787, nil, nil, nil, nil, 787, 787, + 787, 787, nil, 787, 787, nil, nil, nil, 787, 787, + 793, 793, 793, 793, 793, 793, 787, nil, 787, 793, + 793, nil, nil, nil, 793, nil, 793, 793, 793, 793, + 793, 793, 793, nil, nil, nil, nil, nil, 793, 793, + 793, 793, 793, 793, 793, nil, nil, 793, nil, nil, + nil, nil, nil, 793, 793, nil, 793, 793, 793, 793, + 793, 793, 793, 793, 793, nil, 793, 793, 793, nil, + 793, 793, 793, 793, 793, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 793, nil, nil, 793, nil, nil, + 793, 793, nil, nil, 793, nil, 793, nil, nil, nil, + 793, nil, nil, nil, nil, nil, nil, nil, 793, nil, + nil, nil, nil, 793, 793, 793, 793, nil, 793, 793, + nil, nil, nil, 793, 793, 828, 828, 828, 828, 828, + 828, 793, nil, 793, 828, 828, nil, nil, nil, 828, + nil, 828, 828, 828, 828, 828, 828, 828, nil, nil, + nil, nil, nil, 828, 828, 828, 828, 828, 828, 828, + nil, nil, 828, nil, nil, nil, nil, nil, 828, 828, + nil, 828, 828, 828, 828, 828, 828, 828, 828, 828, + nil, 828, 828, 828, nil, 828, 828, 828, 828, 828, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 828, + nil, nil, 828, nil, nil, 828, 828, nil, nil, 828, + nil, 828, nil, nil, nil, 828, nil, nil, nil, nil, + nil, nil, nil, 828, nil, nil, nil, nil, 828, 828, + 828, 828, nil, 828, 828, nil, nil, nil, 828, 828, + 834, 834, 834, 834, 834, 834, 828, nil, 828, 834, + 834, nil, nil, nil, 834, nil, 834, 834, 834, 834, + 834, 834, 834, nil, nil, nil, nil, nil, 834, 834, + 834, 834, 834, 834, 834, nil, nil, 834, nil, nil, + nil, nil, nil, 834, 834, nil, 834, 834, 834, 834, + 834, 834, 834, 834, 834, nil, 834, 834, 834, nil, + 834, 834, 834, 834, 834, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 834, nil, nil, 834, nil, nil, + 834, 834, nil, nil, 834, nil, 834, nil, nil, nil, + 834, nil, nil, nil, nil, nil, nil, nil, 834, nil, + nil, nil, nil, 834, 834, 834, 834, nil, 834, 834, + nil, nil, nil, 834, 834, 835, 835, 835, 835, 835, + 835, 834, nil, 834, 835, 835, nil, nil, nil, 835, + nil, 835, 835, 835, 835, 835, 835, 835, nil, nil, + nil, nil, nil, 835, 835, 835, 835, 835, 835, 835, + nil, nil, 835, nil, nil, nil, nil, nil, 835, 835, + nil, 835, 835, 835, 835, 835, 835, 835, 835, 835, + nil, 835, 835, 835, nil, 835, 835, 835, 835, 835, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 835, + nil, nil, 835, nil, nil, 835, 835, nil, nil, 835, + nil, 835, nil, nil, nil, 835, nil, nil, nil, nil, + nil, nil, nil, 835, nil, nil, nil, nil, 835, 835, + 835, 835, nil, 835, 835, nil, nil, nil, 835, 835, + 904, 904, 904, 904, 904, 904, 835, nil, 835, 904, + 904, nil, nil, nil, 904, nil, 904, 904, 904, 904, + 904, 904, 904, nil, nil, nil, nil, nil, 904, 904, + 904, 904, 904, 904, 904, nil, nil, 904, nil, nil, + nil, nil, nil, 904, 904, nil, 904, 904, 904, 904, + 904, 904, 904, 904, 904, nil, 904, 904, 904, nil, + 904, 904, 904, 904, 904, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 904, nil, nil, 904, nil, nil, + 904, 904, nil, nil, 904, nil, 904, nil, nil, nil, + 904, nil, nil, nil, nil, nil, nil, nil, 904, nil, + nil, nil, nil, 904, 904, 904, 904, nil, 904, 904, + nil, nil, nil, 904, 904, 910, 910, 910, 910, 910, + 910, 904, nil, 904, 910, 910, nil, nil, nil, 910, + nil, 910, 910, 910, 910, 910, 910, 910, nil, nil, + nil, nil, nil, 910, 910, 910, 910, 910, 910, 910, + nil, nil, 910, nil, nil, nil, nil, nil, 910, 910, + nil, 910, 910, 910, 910, 910, 910, 910, 910, 910, + nil, 910, 910, 910, nil, 910, 910, 910, 910, 910, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 910, + nil, nil, 910, nil, nil, 910, 910, nil, nil, 910, + nil, 910, nil, nil, nil, 910, nil, nil, nil, nil, + nil, nil, nil, 910, nil, nil, nil, nil, 910, 910, + 910, 910, nil, 910, 910, nil, nil, nil, 910, 910, + 912, 912, 912, 912, 912, 912, 910, nil, 910, 912, + 912, nil, nil, nil, 912, nil, 912, 912, 912, 912, + 912, 912, 912, nil, nil, nil, nil, nil, 912, 912, + 912, 912, 912, 912, 912, nil, nil, 912, nil, nil, + nil, nil, nil, 912, 912, nil, 912, 912, 912, 912, + 912, 912, 912, 912, 912, nil, 912, 912, 912, nil, + 912, 912, 912, 912, 912, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 912, nil, nil, 912, nil, nil, + 912, 912, nil, nil, 912, nil, 912, nil, nil, nil, + 912, nil, nil, nil, nil, nil, nil, nil, 912, nil, + nil, nil, nil, 912, 912, 912, 912, nil, 912, 912, + nil, nil, nil, 912, 912, nil, 5, 5, 5, 5, + 5, 912, nil, 912, 5, 5, nil, nil, nil, 5, + nil, 5, 5, 5, 5, 5, 5, 5, nil, nil, + nil, nil, nil, 5, 5, 5, 5, 5, 5, 5, + nil, nil, 5, nil, nil, nil, nil, nil, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + nil, 5, 5, 5, nil, 5, 5, 5, 5, 5, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 5, + nil, nil, 5, nil, nil, 5, 5, nil, nil, 5, + nil, 5, nil, nil, nil, 5, nil, nil, nil, nil, + nil, nil, nil, 5, nil, nil, nil, nil, 5, 5, + 5, 5, nil, 5, 5, nil, nil, nil, 5, 5, + nil, 19, 19, 19, nil, 19, 5, nil, 5, 19, + 19, nil, nil, nil, 19, nil, 19, 19, 19, 19, + 19, 19, 19, nil, nil, nil, nil, nil, 19, 19, + 19, 19, 19, 19, 19, nil, nil, 19, nil, nil, + nil, nil, nil, nil, 19, nil, nil, 19, 19, 19, + 19, 19, 19, 19, 19, nil, 19, 19, 19, nil, + 19, 19, 19, 19, 19, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 19, nil, nil, 19, nil, nil, + 19, 19, nil, nil, 19, nil, nil, nil, nil, nil, + 19, nil, nil, nil, nil, nil, nil, nil, 19, nil, + nil, nil, nil, 19, 19, 19, 19, nil, 19, 19, + nil, nil, nil, 19, 19, nil, 27, 27, 27, nil, + 27, 19, nil, 19, 27, 27, nil, nil, nil, 27, + nil, 27, 27, 27, 27, 27, 27, 27, nil, nil, + nil, nil, nil, 27, 27, 27, 27, 27, 27, 27, + nil, nil, 27, nil, nil, nil, nil, nil, nil, 27, + nil, nil, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, nil, 27, 27, 27, 27, 27, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 27, + nil, nil, 27, nil, nil, 27, 27, nil, nil, 27, + nil, 27, nil, 27, nil, 27, nil, nil, nil, nil, + nil, nil, nil, 27, nil, nil, nil, nil, 27, 27, + 27, 27, nil, 27, 27, nil, nil, nil, 27, 27, + nil, 28, 28, 28, nil, 28, 27, nil, 27, 28, + 28, nil, nil, nil, 28, nil, 28, 28, 28, 28, + 28, 28, 28, nil, nil, nil, nil, nil, 28, 28, + 28, 28, 28, 28, 28, nil, nil, 28, nil, nil, + nil, nil, nil, nil, 28, nil, nil, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, nil, + 28, 28, 28, 28, 28, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 28, nil, nil, 28, nil, nil, + 28, 28, nil, nil, 28, nil, 28, nil, 28, nil, + 28, nil, nil, nil, nil, nil, nil, nil, 28, nil, + nil, nil, nil, 28, 28, 28, 28, nil, 28, 28, + nil, nil, nil, 28, 28, nil, 29, 29, 29, nil, + 29, 28, nil, 28, 29, 29, nil, nil, nil, 29, + nil, 29, 29, 29, 29, 29, 29, 29, nil, nil, + nil, nil, nil, 29, 29, 29, 29, 29, 29, 29, + nil, nil, 29, nil, nil, nil, nil, nil, nil, 29, + nil, nil, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, nil, 29, 29, 29, 29, 29, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 29, + nil, nil, 29, nil, nil, 29, 29, nil, nil, 29, + nil, 29, nil, 29, nil, 29, nil, nil, nil, nil, + nil, nil, nil, 29, nil, nil, nil, nil, 29, 29, + 29, 29, nil, 29, 29, nil, nil, nil, 29, 29, + nil, 32, 32, 32, nil, 32, 29, nil, 29, 32, + 32, nil, nil, nil, 32, nil, 32, 32, 32, 32, + 32, 32, 32, nil, nil, nil, nil, nil, 32, 32, + 32, 32, 32, 32, 32, nil, nil, 32, nil, nil, + nil, nil, nil, nil, 32, nil, nil, 32, 32, 32, + 32, 32, 32, 32, 32, nil, 32, 32, 32, nil, + 32, 32, nil, 688, 32, 688, 688, 688, 688, 688, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 32, nil, nil, 32, nil, nil, + 32, 32, nil, nil, 32, nil, 32, nil, nil, nil, + 688, nil, nil, nil, nil, nil, nil, nil, nil, 688, + 688, 688, 688, 32, 32, 32, 32, nil, 32, 32, + nil, nil, nil, 32, 32, nil, 33, 33, 33, nil, + 33, 32, nil, 32, 33, 33, nil, nil, nil, 33, + nil, 33, 33, 33, 33, 33, 33, 33, nil, nil, + nil, nil, nil, 33, 33, 33, 33, 33, 33, 33, + nil, nil, 33, nil, nil, nil, nil, 584, nil, 33, + nil, nil, 33, 33, 33, 33, 33, 33, 33, 33, + nil, 33, 33, 33, nil, 33, 33, nil, nil, 33, + 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, + 584, nil, 584, 584, nil, nil, 584, 584, nil, 33, + nil, nil, 33, nil, nil, 33, 33, nil, nil, 33, + nil, nil, 584, nil, 584, nil, 584, 584, 584, 584, + 584, 584, 584, nil, 584, nil, nil, nil, 33, 33, + 33, 33, nil, 33, 33, nil, nil, nil, 33, 33, + nil, 584, nil, 33, nil, nil, 33, nil, 33, 39, + 39, 39, nil, 39, nil, nil, nil, 39, 39, nil, + nil, nil, 39, nil, 39, 39, 39, 39, 39, 39, + 39, nil, nil, nil, nil, nil, 39, 39, 39, 39, + 39, 39, 39, nil, nil, 39, nil, nil, nil, nil, + nil, nil, 39, nil, nil, 39, 39, 39, 39, 39, + 39, 39, 39, nil, 39, 39, 39, nil, 39, 39, + 39, 39, 39, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 39, nil, nil, 39, nil, nil, 39, 39, + nil, nil, 39, nil, nil, nil, nil, nil, 39, nil, + nil, nil, nil, nil, nil, nil, 39, nil, nil, nil, + nil, 39, 39, 39, 39, nil, 39, 39, nil, nil, + nil, 39, 39, nil, 40, 40, 40, nil, 40, 39, + nil, 39, 40, 40, nil, nil, nil, 40, nil, 40, + 40, 40, 40, 40, 40, 40, nil, nil, nil, nil, + nil, 40, 40, 40, 40, 40, 40, 40, nil, nil, + 40, nil, nil, nil, nil, nil, nil, 40, nil, nil, + 40, 40, 40, 40, 40, 40, 40, 40, nil, 40, + 40, 40, nil, 40, 40, 40, 40, 40, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 40, nil, nil, + 40, nil, nil, 40, 40, nil, nil, 40, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, 40, 40, 40, 40, + nil, 40, 40, nil, nil, nil, 40, 40, nil, 41, + 41, 41, nil, 41, 40, nil, 40, 41, 41, nil, + nil, nil, 41, nil, 41, 41, 41, 41, 41, 41, + 41, nil, nil, nil, nil, nil, 41, 41, 41, 41, + 41, 41, 41, nil, nil, 41, nil, nil, nil, nil, + nil, nil, 41, nil, nil, 41, 41, 41, 41, 41, + 41, 41, 41, nil, 41, 41, 41, nil, 41, 41, + 41, 41, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 41, nil, nil, 41, nil, nil, 41, 41, + nil, nil, 41, nil, nil, nil, nil, nil, 41, nil, + nil, nil, nil, nil, nil, nil, 41, nil, nil, nil, + nil, 41, 41, 41, 41, nil, 41, 41, nil, nil, + nil, 41, 41, nil, 53, 53, 53, nil, 53, 41, + nil, 41, 53, 53, nil, nil, nil, 53, nil, 53, + 53, 53, 53, 53, 53, 53, nil, nil, nil, nil, + nil, 53, 53, 53, 53, 53, 53, 53, nil, nil, + 53, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 53, 53, 53, 53, 53, 53, 53, 53, nil, 53, + 53, 53, nil, 53, 53, 53, 53, 53, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 53, nil, nil, 53, 53, nil, nil, 53, nil, nil, + nil, nil, nil, 53, nil, nil, nil, nil, nil, nil, + nil, 53, nil, nil, nil, nil, 53, 53, 53, 53, + nil, 53, 53, nil, nil, nil, 53, 53, nil, 54, + 54, 54, nil, 54, 53, nil, 53, 54, 54, nil, + nil, nil, 54, nil, 54, 54, 54, 54, 54, 54, + 54, nil, nil, nil, nil, nil, 54, 54, 54, 54, + 54, 54, 54, nil, nil, 54, nil, nil, nil, nil, + nil, nil, 54, nil, nil, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, nil, 54, 54, + 54, 54, 54, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 54, nil, nil, 54, nil, nil, 54, 54, + nil, nil, 54, nil, 54, nil, nil, nil, 54, nil, + nil, nil, nil, nil, nil, nil, 54, nil, nil, nil, + nil, 54, 54, 54, 54, nil, 54, 54, nil, nil, + nil, 54, 54, nil, 55, 55, 55, nil, 55, 54, + nil, 54, 55, 55, nil, nil, nil, 55, nil, 55, + 55, 55, 55, 55, 55, 55, nil, nil, nil, nil, + nil, 55, 55, 55, 55, 55, 55, 55, nil, nil, + 55, nil, nil, nil, nil, nil, nil, 55, nil, nil, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, nil, 55, 55, 55, 55, 55, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 55, nil, nil, + 55, nil, nil, 55, 55, nil, nil, 55, nil, nil, + nil, nil, nil, 55, nil, nil, nil, nil, nil, nil, + nil, 55, nil, nil, nil, nil, 55, 55, 55, 55, + nil, 55, 55, nil, nil, nil, 55, 55, nil, 58, + 58, 58, nil, 58, 55, nil, 55, 58, 58, nil, + nil, nil, 58, nil, 58, 58, 58, 58, 58, 58, + 58, nil, nil, nil, nil, nil, 58, 58, 58, 58, + 58, 58, 58, nil, nil, 58, nil, nil, nil, nil, + nil, nil, 58, nil, nil, 58, 58, 58, 58, 58, + 58, 58, 58, nil, 58, 58, 58, nil, 58, 58, + 58, 58, 58, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 58, nil, nil, 58, nil, nil, 58, 58, + nil, nil, 58, nil, nil, nil, nil, nil, 58, nil, + nil, nil, nil, nil, nil, nil, 58, nil, nil, nil, + nil, 58, 58, 58, 58, nil, 58, 58, nil, nil, + nil, 58, 58, nil, 59, 59, 59, nil, 59, 58, + nil, 58, 59, 59, nil, nil, nil, 59, nil, 59, + 59, 59, 59, 59, 59, 59, nil, nil, nil, nil, + nil, 59, 59, 59, 59, 59, 59, 59, nil, nil, + 59, nil, nil, nil, nil, nil, nil, 59, nil, nil, + 59, 59, 59, 59, 59, 59, 59, 59, nil, 59, + 59, 59, nil, 59, 59, 59, 59, 59, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 59, nil, nil, + 59, nil, nil, 59, 59, nil, nil, 59, nil, nil, + nil, nil, nil, 59, nil, nil, nil, nil, nil, nil, + nil, 59, nil, nil, nil, nil, 59, 59, 59, 59, + nil, 59, 59, nil, nil, nil, 59, 59, nil, 62, + 62, 62, nil, 62, 59, nil, 59, 62, 62, nil, + nil, nil, 62, nil, 62, 62, 62, 62, 62, 62, + 62, nil, nil, nil, nil, nil, 62, 62, 62, 62, + 62, 62, 62, nil, nil, 62, nil, nil, nil, nil, + nil, nil, 62, nil, nil, 62, 62, 62, 62, 62, + 62, 62, 62, nil, 62, 62, 62, nil, 62, 62, + 62, 62, 62, 596, 596, 596, 596, 596, 596, 596, + 596, 596, 596, 596, nil, 596, 596, nil, nil, 596, + 596, nil, 62, nil, 596, 62, nil, nil, 62, 62, + nil, nil, 62, nil, nil, 596, nil, 596, 62, 596, + 596, 596, 596, 596, 596, 596, 62, 596, nil, nil, + nil, 62, 62, 62, 62, nil, 62, 62, nil, nil, + nil, 62, 62, 62, 596, nil, 596, nil, 62, 62, + nil, 62, 63, 63, 63, nil, 63, nil, nil, nil, + 63, 63, nil, nil, nil, 63, nil, 63, 63, 63, + 63, 63, 63, 63, nil, nil, nil, nil, nil, 63, + 63, 63, 63, 63, 63, 63, nil, nil, 63, nil, + nil, nil, nil, nil, nil, 63, nil, nil, 63, 63, + 63, 63, 63, 63, 63, 63, nil, 63, 63, 63, + nil, 63, 63, nil, 761, 63, 761, 761, 761, 761, + 761, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 63, nil, nil, 63, nil, + nil, 63, 63, nil, nil, 63, nil, 63, nil, nil, + nil, 761, nil, nil, nil, nil, nil, nil, nil, nil, + 761, 761, 761, 761, 63, 63, 63, 63, nil, 63, + 63, nil, nil, nil, 63, 63, nil, 64, 64, 64, + nil, 64, 63, nil, 63, 64, 64, nil, nil, nil, + 64, nil, 64, 64, 64, 64, 64, 64, 64, nil, + nil, nil, nil, nil, 64, 64, 64, 64, 64, 64, + 64, nil, nil, 64, nil, nil, nil, nil, nil, nil, + 64, nil, nil, 64, 64, 64, 64, 64, 64, 64, + 64, nil, 64, 64, 64, nil, 64, 64, nil, 763, + 64, 763, 763, 763, 763, 763, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 64, nil, nil, + 64, nil, nil, 64, nil, nil, 64, 64, nil, nil, + 64, nil, nil, nil, nil, nil, 763, nil, nil, nil, + nil, nil, nil, nil, nil, 763, 763, 763, 763, 64, + 64, 64, 64, nil, 64, 64, nil, nil, nil, 64, + 64, nil, 65, 65, 65, nil, 65, 64, nil, 64, + 65, 65, nil, nil, nil, 65, nil, 65, 65, 65, + 65, 65, 65, 65, nil, nil, nil, nil, nil, 65, + 65, 65, 65, 65, 65, 65, nil, nil, 65, nil, + nil, nil, nil, nil, nil, 65, nil, nil, 65, 65, + 65, 65, 65, 65, 65, 65, nil, 65, 65, 65, + nil, 65, 65, nil, 805, 65, 805, 805, 805, 805, + 805, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 65, nil, nil, 65, nil, + nil, 65, 65, nil, nil, 65, nil, nil, nil, nil, + nil, 805, nil, nil, nil, nil, nil, nil, nil, nil, + 805, 805, 805, 805, 65, 65, 65, 65, nil, 65, + 65, nil, nil, nil, 65, 65, nil, 103, 103, 103, + 103, 103, 65, nil, 65, 103, 103, nil, nil, nil, + 103, nil, 103, 103, 103, 103, 103, 103, 103, nil, + nil, nil, nil, nil, 103, 103, 103, 103, 103, 103, + 103, nil, nil, 103, nil, nil, nil, nil, nil, 103, + 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, + 103, nil, 103, 103, 103, nil, 103, 103, 103, 103, + 103, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, nil, 20, 20, nil, nil, 20, 20, nil, + 103, nil, nil, 103, nil, nil, 103, 103, nil, nil, + 103, nil, 103, 20, nil, 20, 103, 20, 20, 20, + 20, 20, 20, 20, 103, 20, nil, nil, nil, 103, + 103, 103, 103, nil, 103, 103, nil, nil, nil, 103, + 103, nil, 20, nil, nil, nil, 103, 103, nil, 103, + 108, 108, 108, nil, 108, nil, nil, nil, 108, 108, + nil, nil, nil, 108, nil, 108, 108, 108, 108, 108, + 108, 108, nil, nil, nil, nil, nil, 108, 108, 108, + 108, 108, 108, 108, nil, nil, 108, nil, nil, nil, + nil, nil, nil, 108, nil, nil, 108, 108, 108, 108, + 108, 108, 108, 108, nil, 108, 108, 108, nil, 108, + 108, 108, 108, 108, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 108, nil, nil, 108, nil, nil, 108, + 108, nil, nil, 108, nil, nil, nil, nil, nil, 108, + nil, nil, nil, nil, nil, nil, nil, 108, nil, nil, + nil, nil, 108, 108, 108, 108, nil, 108, 108, nil, + nil, nil, 108, 108, nil, 109, 109, 109, nil, 109, + 108, nil, 108, 109, 109, nil, nil, nil, 109, nil, + 109, 109, 109, 109, 109, 109, 109, nil, nil, nil, + nil, nil, 109, 109, 109, 109, 109, 109, 109, nil, + nil, 109, nil, nil, nil, nil, nil, nil, 109, nil, + nil, 109, 109, 109, 109, 109, 109, 109, 109, nil, + 109, 109, 109, nil, 109, 109, 109, 109, 109, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 109, nil, + nil, 109, nil, nil, 109, 109, nil, nil, 109, nil, + nil, nil, nil, nil, 109, nil, nil, nil, nil, nil, + nil, nil, 109, nil, nil, nil, nil, 109, 109, 109, + 109, nil, 109, 109, nil, nil, nil, 109, 109, nil, + 110, 110, 110, nil, 110, 109, nil, 109, 110, 110, + nil, nil, nil, 110, nil, 110, 110, 110, 110, 110, + 110, 110, nil, nil, nil, nil, nil, 110, 110, 110, + 110, 110, 110, 110, nil, nil, 110, nil, nil, nil, + nil, nil, nil, 110, nil, nil, 110, 110, 110, 110, + 110, 110, 110, 110, nil, 110, 110, 110, nil, 110, + 110, 110, 110, 110, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 110, nil, nil, 110, nil, nil, 110, + 110, nil, nil, 110, nil, nil, nil, nil, nil, 110, + nil, nil, nil, nil, nil, nil, nil, 110, nil, nil, + nil, nil, 110, 110, 110, 110, nil, 110, 110, nil, + nil, nil, 110, 110, nil, 111, 111, 111, nil, 111, + 110, nil, 110, 111, 111, nil, nil, nil, 111, nil, + 111, 111, 111, 111, 111, 111, 111, nil, nil, nil, + nil, nil, 111, 111, 111, 111, 111, 111, 111, nil, + nil, 111, nil, nil, nil, nil, nil, nil, 111, nil, + nil, 111, 111, 111, 111, 111, 111, 111, 111, nil, + 111, 111, 111, nil, 111, 111, 111, 111, 111, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 111, nil, + nil, 111, nil, nil, 111, 111, nil, nil, 111, nil, + nil, nil, nil, nil, 111, nil, nil, nil, nil, nil, + nil, nil, 111, nil, nil, nil, nil, 111, 111, 111, + 111, nil, 111, 111, nil, nil, nil, 111, 111, nil, + 112, 112, 112, 112, 112, 111, nil, 111, 112, 112, + nil, nil, nil, 112, nil, 112, 112, 112, 112, 112, + 112, 112, nil, nil, nil, nil, nil, 112, 112, 112, + 112, 112, 112, 112, nil, nil, 112, nil, nil, nil, + nil, nil, 112, 112, nil, 112, 112, 112, 112, 112, + 112, 112, 112, 112, nil, 112, 112, 112, nil, 112, + 112, 112, 112, 112, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 112, nil, nil, 112, nil, nil, 112, + 112, nil, nil, 112, nil, 112, nil, nil, nil, 112, + nil, nil, nil, nil, nil, nil, nil, 112, nil, nil, + nil, nil, 112, 112, 112, 112, nil, 112, 112, nil, + nil, nil, 112, 112, nil, 198, 198, 198, nil, 198, + 112, nil, 112, 198, 198, nil, nil, nil, 198, nil, + 198, 198, 198, 198, 198, 198, 198, nil, nil, nil, + nil, nil, 198, 198, 198, 198, 198, 198, 198, nil, + nil, 198, nil, nil, nil, nil, nil, nil, 198, nil, + nil, 198, 198, 198, 198, 198, 198, 198, 198, nil, + 198, 198, 198, nil, 198, 198, 198, 198, 198, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 198, nil, + nil, 198, nil, nil, 198, 198, nil, nil, 198, nil, + 198, nil, nil, nil, 198, nil, nil, nil, nil, nil, + nil, nil, 198, nil, nil, nil, nil, 198, 198, 198, + 198, nil, 198, 198, nil, nil, nil, 198, 198, nil, + 199, 199, 199, nil, 199, 198, nil, 198, 199, 199, + nil, nil, nil, 199, nil, 199, 199, 199, 199, 199, + 199, 199, nil, nil, nil, nil, nil, 199, 199, 199, + 199, 199, 199, 199, nil, nil, 199, nil, nil, nil, + nil, nil, nil, 199, nil, nil, 199, 199, 199, 199, + 199, 199, 199, 199, nil, 199, 199, 199, nil, 199, + 199, 199, 199, 199, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 199, nil, nil, 199, nil, nil, 199, + 199, nil, nil, 199, nil, 199, nil, nil, nil, 199, + nil, nil, nil, nil, nil, nil, nil, 199, nil, nil, + nil, nil, 199, 199, 199, 199, nil, 199, 199, nil, + nil, nil, 199, 199, nil, 200, 200, 200, nil, 200, + 199, nil, 199, 200, 200, nil, nil, nil, 200, nil, + 200, 200, 200, 200, 200, 200, 200, nil, nil, nil, + nil, nil, 200, 200, 200, 200, 200, 200, 200, nil, + nil, 200, nil, nil, nil, nil, nil, nil, 200, nil, + nil, 200, 200, 200, 200, 200, 200, 200, 200, nil, + 200, 200, 200, nil, 200, 200, 200, 200, 200, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 200, nil, + nil, 200, nil, nil, 200, 200, nil, nil, 200, nil, + nil, nil, nil, nil, 200, nil, nil, nil, nil, nil, + nil, nil, 200, nil, nil, nil, nil, 200, 200, 200, + 200, nil, 200, 200, nil, nil, nil, 200, 200, nil, + 201, 201, 201, nil, 201, 200, nil, 200, 201, 201, + nil, nil, nil, 201, nil, 201, 201, 201, 201, 201, + 201, 201, nil, nil, nil, nil, nil, 201, 201, 201, + 201, 201, 201, 201, nil, nil, 201, nil, nil, nil, + nil, nil, nil, 201, nil, nil, 201, 201, 201, 201, + 201, 201, 201, 201, 201, 201, 201, 201, nil, 201, + 201, 201, 201, 201, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 201, nil, nil, 201, nil, nil, 201, + 201, nil, nil, 201, nil, 201, nil, 201, nil, 201, + nil, nil, nil, nil, nil, nil, nil, 201, nil, nil, + nil, nil, 201, 201, 201, 201, nil, 201, 201, nil, + nil, nil, 201, 201, nil, 204, 204, 204, nil, 204, + 201, nil, 201, 204, 204, nil, nil, nil, 204, nil, + 204, 204, 204, 204, 204, 204, 204, nil, nil, nil, + nil, nil, 204, 204, 204, 204, 204, 204, 204, nil, + nil, 204, nil, nil, nil, nil, nil, nil, 204, nil, + nil, 204, 204, 204, 204, 204, 204, 204, 204, nil, + 204, 204, 204, nil, 204, 204, 204, 204, 204, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 204, nil, + nil, 204, nil, nil, 204, 204, nil, nil, 204, nil, + nil, nil, nil, nil, 204, nil, nil, nil, nil, nil, + nil, nil, 204, nil, nil, nil, nil, 204, 204, 204, + 204, nil, 204, 204, nil, nil, nil, 204, 204, nil, + 205, 205, 205, nil, 205, 204, nil, 204, 205, 205, + nil, nil, nil, 205, nil, 205, 205, 205, 205, 205, + 205, 205, nil, nil, nil, nil, nil, 205, 205, 205, + 205, 205, 205, 205, nil, nil, 205, nil, nil, nil, + nil, nil, nil, 205, nil, nil, 205, 205, 205, 205, + 205, 205, 205, 205, nil, 205, 205, 205, nil, 205, + 205, 205, 205, 205, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 205, nil, nil, 205, nil, nil, 205, + 205, nil, nil, 205, nil, nil, nil, nil, nil, 205, + nil, nil, nil, nil, nil, nil, nil, 205, nil, nil, + nil, nil, 205, 205, 205, 205, nil, 205, 205, nil, + nil, nil, 205, 205, nil, 206, 206, 206, nil, 206, + 205, nil, 205, 206, 206, nil, nil, nil, 206, nil, + 206, 206, 206, 206, 206, 206, 206, nil, nil, nil, + nil, nil, 206, 206, 206, 206, 206, 206, 206, nil, + nil, 206, nil, nil, nil, nil, nil, nil, 206, nil, + nil, 206, 206, 206, 206, 206, 206, 206, 206, nil, + 206, 206, 206, nil, 206, 206, 206, 206, 206, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 206, nil, + nil, 206, nil, nil, 206, 206, nil, nil, 206, nil, + nil, nil, nil, nil, 206, nil, nil, nil, nil, nil, + nil, nil, 206, nil, nil, nil, nil, 206, 206, 206, + 206, nil, 206, 206, nil, nil, nil, 206, 206, nil, + 207, 207, 207, nil, 207, 206, nil, 206, 207, 207, + nil, nil, nil, 207, nil, 207, 207, 207, 207, 207, + 207, 207, nil, nil, nil, nil, nil, 207, 207, 207, + 207, 207, 207, 207, nil, nil, 207, nil, nil, nil, + nil, nil, nil, 207, nil, nil, 207, 207, 207, 207, + 207, 207, 207, 207, nil, 207, 207, 207, nil, 207, + 207, 207, 207, 207, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 207, nil, nil, 207, nil, nil, 207, + 207, nil, nil, 207, nil, nil, nil, nil, nil, 207, + nil, nil, nil, nil, nil, nil, nil, 207, nil, nil, + nil, nil, 207, 207, 207, 207, nil, 207, 207, nil, + nil, nil, 207, 207, nil, 208, 208, 208, nil, 208, + 207, nil, 207, 208, 208, nil, nil, nil, 208, nil, + 208, 208, 208, 208, 208, 208, 208, nil, nil, nil, + nil, nil, 208, 208, 208, 208, 208, 208, 208, nil, + nil, 208, nil, nil, nil, nil, nil, nil, 208, nil, + nil, 208, 208, 208, 208, 208, 208, 208, 208, nil, + 208, 208, 208, nil, 208, 208, 208, 208, 208, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 208, nil, + nil, 208, nil, nil, 208, 208, nil, nil, 208, nil, + nil, nil, nil, nil, 208, nil, nil, nil, nil, nil, + nil, nil, 208, nil, nil, nil, nil, 208, 208, 208, + 208, nil, 208, 208, nil, nil, nil, 208, 208, 208, + 218, 218, 218, nil, 218, 208, nil, 208, 218, 218, + nil, nil, nil, 218, nil, 218, 218, 218, 218, 218, + 218, 218, nil, nil, nil, nil, nil, 218, 218, 218, + 218, 218, 218, 218, nil, nil, 218, nil, nil, nil, + nil, nil, nil, 218, nil, nil, 218, 218, 218, 218, + 218, 218, 218, 218, nil, 218, 218, 218, nil, 218, + 218, 218, 218, 218, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 218, nil, nil, 218, nil, nil, 218, + 218, nil, nil, 218, nil, nil, nil, nil, nil, 218, + nil, nil, nil, nil, nil, nil, nil, 218, nil, nil, + nil, nil, 218, 218, 218, 218, nil, 218, 218, nil, + nil, nil, 218, 218, nil, 221, 221, 221, nil, 221, + 218, nil, 218, 221, 221, nil, nil, nil, 221, nil, + 221, 221, 221, 221, 221, 221, 221, nil, nil, nil, + nil, nil, 221, 221, 221, 221, 221, 221, 221, nil, + nil, 221, nil, nil, nil, nil, nil, nil, 221, nil, + nil, 221, 221, 221, 221, 221, 221, 221, 221, nil, + 221, 221, 221, nil, 221, 221, 221, 221, 221, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 221, nil, + nil, 221, nil, nil, 221, 221, nil, nil, 221, nil, + nil, nil, nil, nil, 221, nil, nil, nil, nil, nil, + nil, nil, 221, nil, nil, nil, nil, 221, 221, 221, + 221, nil, 221, 221, nil, nil, nil, 221, 221, nil, + 222, 222, 222, nil, 222, 221, nil, 221, 222, 222, + nil, nil, nil, 222, nil, 222, 222, 222, 222, 222, + 222, 222, nil, nil, nil, nil, nil, 222, 222, 222, + 222, 222, 222, 222, nil, nil, 222, nil, nil, nil, + nil, nil, nil, 222, nil, nil, 222, 222, 222, 222, + 222, 222, 222, 222, nil, 222, 222, 222, nil, 222, + 222, 222, 222, 222, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 222, nil, nil, 222, nil, nil, 222, + 222, nil, nil, 222, nil, nil, nil, nil, nil, 222, + nil, nil, nil, nil, nil, nil, nil, 222, nil, nil, + nil, nil, 222, 222, 222, 222, nil, 222, 222, nil, + nil, nil, 222, 222, nil, 223, 223, 223, nil, 223, + 222, nil, 222, 223, 223, nil, nil, nil, 223, nil, + 223, 223, 223, 223, 223, 223, 223, nil, nil, nil, + nil, nil, 223, 223, 223, 223, 223, 223, 223, nil, + nil, 223, nil, nil, nil, nil, nil, nil, 223, nil, + nil, 223, 223, 223, 223, 223, 223, 223, 223, nil, + 223, 223, 223, nil, 223, 223, 223, 223, 223, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 223, nil, + nil, 223, nil, nil, 223, 223, nil, nil, 223, nil, + nil, nil, nil, nil, 223, nil, nil, nil, nil, nil, + nil, nil, 223, nil, nil, nil, nil, 223, 223, 223, + 223, nil, 223, 223, nil, nil, nil, 223, 223, nil, + 224, 224, 224, nil, 224, 223, nil, 223, 224, 224, + nil, nil, nil, 224, nil, 224, 224, 224, 224, 224, + 224, 224, nil, nil, nil, nil, nil, 224, 224, 224, + 224, 224, 224, 224, nil, nil, 224, nil, nil, nil, + nil, nil, nil, 224, nil, nil, 224, 224, 224, 224, + 224, 224, 224, 224, nil, 224, 224, 224, nil, 224, + 224, 224, 224, 224, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 224, nil, nil, 224, nil, nil, 224, + 224, nil, nil, 224, nil, nil, nil, nil, nil, 224, + nil, nil, nil, nil, nil, nil, nil, 224, nil, nil, + nil, nil, 224, 224, 224, 224, nil, 224, 224, nil, + nil, nil, 224, 224, nil, 225, 225, 225, nil, 225, + 224, nil, 224, 225, 225, nil, nil, nil, 225, nil, + 225, 225, 225, 225, 225, 225, 225, nil, nil, nil, + nil, nil, 225, 225, 225, 225, 225, 225, 225, nil, + nil, 225, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 225, 225, 225, 225, 225, 225, 225, 225, nil, + 225, 225, 225, nil, 225, 225, 225, 225, 225, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 225, nil, nil, 225, 225, nil, nil, 225, nil, + nil, nil, nil, nil, 225, nil, nil, nil, nil, nil, + nil, nil, 225, nil, nil, nil, nil, 225, 225, 225, + 225, nil, 225, 225, nil, nil, nil, 225, 225, nil, + 226, 226, 226, nil, 226, 225, nil, 225, 226, 226, + nil, nil, nil, 226, nil, 226, 226, 226, 226, 226, + 226, 226, nil, nil, nil, nil, nil, 226, 226, 226, + 226, 226, 226, 226, nil, nil, 226, nil, nil, nil, + nil, nil, nil, 226, nil, nil, 226, 226, 226, 226, + 226, 226, 226, 226, nil, 226, 226, 226, nil, 226, + 226, 226, 226, 226, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 226, nil, nil, 226, nil, nil, 226, + 226, nil, nil, 226, nil, nil, nil, nil, nil, 226, + nil, nil, nil, nil, nil, nil, nil, 226, nil, nil, + nil, nil, 226, 226, 226, 226, nil, 226, 226, nil, + nil, nil, 226, 226, nil, 227, 227, 227, nil, 227, + 226, nil, 226, 227, 227, nil, nil, nil, 227, nil, + 227, 227, 227, 227, 227, 227, 227, nil, nil, nil, + nil, nil, 227, 227, 227, 227, 227, 227, 227, nil, + nil, 227, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 227, 227, 227, 227, 227, 227, 227, 227, nil, + 227, 227, 227, nil, 227, 227, 227, 227, 227, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 227, nil, nil, 227, 227, nil, nil, 227, nil, + nil, nil, nil, nil, 227, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, nil, nil, 227, 227, 227, + 227, nil, 227, 227, nil, nil, nil, 227, 227, nil, + 228, 228, 228, nil, 228, 227, nil, 227, 228, 228, + nil, nil, nil, 228, nil, 228, 228, 228, 228, 228, + 228, 228, nil, nil, nil, nil, nil, 228, 228, 228, + 228, 228, 228, 228, nil, nil, 228, nil, nil, nil, + nil, nil, nil, 228, nil, nil, 228, 228, 228, 228, + 228, 228, 228, 228, nil, 228, 228, 228, nil, 228, + 228, 228, 228, 228, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 228, nil, nil, 228, nil, nil, 228, + 228, nil, nil, 228, nil, nil, nil, nil, nil, 228, + nil, nil, nil, nil, nil, nil, nil, 228, nil, nil, + nil, nil, 228, 228, 228, 228, nil, 228, 228, nil, + nil, nil, 228, 228, nil, 229, 229, 229, nil, 229, + 228, nil, 228, 229, 229, nil, nil, nil, 229, nil, + 229, 229, 229, 229, 229, 229, 229, nil, nil, nil, + nil, nil, 229, 229, 229, 229, 229, 229, 229, nil, + nil, 229, nil, nil, nil, nil, nil, nil, 229, nil, + nil, 229, 229, 229, 229, 229, 229, 229, 229, nil, + 229, 229, 229, nil, 229, 229, 229, 229, 229, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 229, nil, + nil, 229, nil, nil, 229, 229, nil, nil, 229, nil, + nil, nil, nil, nil, 229, nil, nil, nil, nil, nil, + nil, nil, 229, nil, nil, nil, nil, 229, 229, 229, + 229, nil, 229, 229, nil, nil, nil, 229, 229, nil, + 230, 230, 230, nil, 230, 229, nil, 229, 230, 230, + nil, nil, nil, 230, nil, 230, 230, 230, 230, 230, + 230, 230, nil, nil, nil, nil, nil, 230, 230, 230, + 230, 230, 230, 230, nil, nil, 230, nil, nil, nil, + nil, nil, nil, 230, nil, nil, 230, 230, 230, 230, + 230, 230, 230, 230, nil, 230, 230, 230, nil, 230, + 230, 230, 230, 230, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, 230, nil, nil, 230, + 230, nil, nil, 230, nil, nil, nil, nil, nil, 230, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + nil, nil, 230, 230, 230, 230, nil, 230, 230, nil, + nil, nil, 230, 230, nil, 231, 231, 231, nil, 231, + 230, nil, 230, 231, 231, nil, nil, nil, 231, nil, + 231, 231, 231, 231, 231, 231, 231, nil, nil, nil, + nil, nil, 231, 231, 231, 231, 231, 231, 231, nil, + nil, 231, nil, nil, nil, nil, nil, nil, 231, nil, + nil, 231, 231, 231, 231, 231, 231, 231, 231, nil, + 231, 231, 231, nil, 231, 231, 231, 231, 231, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 231, nil, + nil, 231, nil, nil, 231, 231, nil, nil, 231, nil, + nil, nil, nil, nil, 231, nil, nil, nil, nil, nil, + nil, nil, 231, nil, nil, nil, nil, 231, 231, 231, + 231, nil, 231, 231, nil, nil, nil, 231, 231, nil, + 232, 232, 232, nil, 232, 231, nil, 231, 232, 232, + nil, nil, nil, 232, nil, 232, 232, 232, 232, 232, + 232, 232, nil, nil, nil, nil, nil, 232, 232, 232, + 232, 232, 232, 232, nil, nil, 232, nil, nil, nil, + nil, nil, nil, 232, nil, nil, 232, 232, 232, 232, + 232, 232, 232, 232, nil, 232, 232, 232, nil, 232, + 232, 232, 232, 232, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 232, nil, nil, 232, nil, nil, 232, + 232, nil, nil, 232, nil, nil, nil, nil, nil, 232, + nil, nil, nil, nil, nil, nil, nil, 232, nil, nil, + nil, nil, 232, 232, 232, 232, nil, 232, 232, nil, + nil, nil, 232, 232, nil, 233, 233, 233, nil, 233, + 232, nil, 232, 233, 233, nil, nil, nil, 233, nil, + 233, 233, 233, 233, 233, 233, 233, nil, nil, nil, + nil, nil, 233, 233, 233, 233, 233, 233, 233, nil, + nil, 233, nil, nil, nil, nil, nil, nil, 233, nil, + nil, 233, 233, 233, 233, 233, 233, 233, 233, nil, + 233, 233, 233, nil, 233, 233, 233, 233, 233, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 233, nil, + nil, 233, nil, nil, 233, 233, nil, nil, 233, nil, + nil, nil, nil, nil, 233, nil, nil, nil, nil, nil, + nil, nil, 233, nil, nil, nil, nil, 233, 233, 233, + 233, nil, 233, 233, nil, nil, nil, 233, 233, nil, + 234, 234, 234, nil, 234, 233, nil, 233, 234, 234, + nil, nil, nil, 234, nil, 234, 234, 234, 234, 234, + 234, 234, nil, nil, nil, nil, nil, 234, 234, 234, + 234, 234, 234, 234, nil, nil, 234, nil, nil, nil, + nil, nil, nil, 234, nil, nil, 234, 234, 234, 234, + 234, 234, 234, 234, nil, 234, 234, 234, nil, 234, + 234, 234, 234, 234, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 234, nil, nil, 234, nil, nil, 234, + 234, nil, nil, 234, nil, nil, nil, nil, nil, 234, + nil, nil, nil, nil, nil, nil, nil, 234, nil, nil, + nil, nil, 234, 234, 234, 234, nil, 234, 234, nil, + nil, nil, 234, 234, nil, 235, 235, 235, nil, 235, + 234, nil, 234, 235, 235, nil, nil, nil, 235, nil, + 235, 235, 235, 235, 235, 235, 235, nil, nil, nil, + nil, nil, 235, 235, 235, 235, 235, 235, 235, nil, + nil, 235, nil, nil, nil, nil, nil, nil, 235, nil, + nil, 235, 235, 235, 235, 235, 235, 235, 235, nil, + 235, 235, 235, nil, 235, 235, 235, 235, 235, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 235, nil, + nil, 235, nil, nil, 235, 235, nil, nil, 235, nil, + nil, nil, nil, nil, 235, nil, nil, nil, nil, nil, + nil, nil, 235, nil, nil, nil, nil, 235, 235, 235, + 235, nil, 235, 235, nil, nil, nil, 235, 235, nil, + 236, 236, 236, nil, 236, 235, nil, 235, 236, 236, + nil, nil, nil, 236, nil, 236, 236, 236, 236, 236, + 236, 236, nil, nil, nil, nil, nil, 236, 236, 236, + 236, 236, 236, 236, nil, nil, 236, nil, nil, nil, + nil, nil, nil, 236, nil, nil, 236, 236, 236, 236, + 236, 236, 236, 236, nil, 236, 236, 236, nil, 236, + 236, 236, 236, 236, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 236, nil, nil, 236, nil, nil, 236, + 236, nil, nil, 236, nil, nil, nil, nil, nil, 236, + nil, nil, nil, nil, nil, nil, nil, 236, nil, nil, + nil, nil, 236, 236, 236, 236, nil, 236, 236, nil, + nil, nil, 236, 236, nil, 237, 237, 237, nil, 237, + 236, nil, 236, 237, 237, nil, nil, nil, 237, nil, + 237, 237, 237, 237, 237, 237, 237, nil, nil, nil, + nil, nil, 237, 237, 237, 237, 237, 237, 237, nil, + nil, 237, nil, nil, nil, nil, nil, nil, 237, nil, + nil, 237, 237, 237, 237, 237, 237, 237, 237, nil, + 237, 237, 237, nil, 237, 237, 237, 237, 237, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 237, nil, + nil, 237, nil, nil, 237, 237, nil, nil, 237, nil, + nil, nil, nil, nil, 237, nil, nil, nil, nil, nil, + nil, nil, 237, nil, nil, nil, nil, 237, 237, 237, + 237, nil, 237, 237, nil, nil, nil, 237, 237, nil, + 238, 238, 238, nil, 238, 237, nil, 237, 238, 238, + nil, nil, nil, 238, nil, 238, 238, 238, 238, 238, + 238, 238, nil, nil, nil, nil, nil, 238, 238, 238, + 238, 238, 238, 238, nil, nil, 238, nil, nil, nil, + nil, nil, nil, 238, nil, nil, 238, 238, 238, 238, + 238, 238, 238, 238, nil, 238, 238, 238, nil, 238, + 238, 238, 238, 238, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 238, nil, nil, 238, nil, nil, 238, + 238, nil, nil, 238, nil, nil, nil, nil, nil, 238, + nil, nil, nil, nil, nil, nil, nil, 238, nil, nil, + nil, nil, 238, 238, 238, 238, nil, 238, 238, nil, + nil, nil, 238, 238, nil, 239, 239, 239, nil, 239, + 238, nil, 238, 239, 239, nil, nil, nil, 239, nil, + 239, 239, 239, 239, 239, 239, 239, nil, nil, nil, + nil, nil, 239, 239, 239, 239, 239, 239, 239, nil, + nil, 239, nil, nil, nil, nil, nil, nil, 239, nil, + nil, 239, 239, 239, 239, 239, 239, 239, 239, nil, + 239, 239, 239, nil, 239, 239, 239, 239, 239, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 239, nil, + nil, 239, nil, nil, 239, 239, nil, nil, 239, nil, + nil, nil, nil, nil, 239, nil, nil, nil, nil, nil, + nil, nil, 239, nil, nil, nil, nil, 239, 239, 239, + 239, nil, 239, 239, nil, nil, nil, 239, 239, nil, + 240, 240, 240, nil, 240, 239, nil, 239, 240, 240, + nil, nil, nil, 240, nil, 240, 240, 240, 240, 240, + 240, 240, nil, nil, nil, nil, nil, 240, 240, 240, + 240, 240, 240, 240, nil, nil, 240, nil, nil, nil, + nil, nil, nil, 240, nil, nil, 240, 240, 240, 240, + 240, 240, 240, 240, nil, 240, 240, 240, nil, 240, + 240, 240, 240, 240, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 240, nil, nil, 240, nil, nil, 240, + 240, nil, nil, 240, nil, nil, nil, nil, nil, 240, + nil, nil, nil, nil, nil, nil, nil, 240, nil, nil, + nil, nil, 240, 240, 240, 240, nil, 240, 240, nil, + nil, nil, 240, 240, nil, 241, 241, 241, nil, 241, + 240, nil, 240, 241, 241, nil, nil, nil, 241, nil, + 241, 241, 241, 241, 241, 241, 241, nil, nil, nil, + nil, nil, 241, 241, 241, 241, 241, 241, 241, nil, + nil, 241, nil, nil, nil, nil, nil, nil, 241, nil, + nil, 241, 241, 241, 241, 241, 241, 241, 241, nil, + 241, 241, 241, nil, 241, 241, 241, 241, 241, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 241, nil, + nil, 241, nil, nil, 241, 241, nil, nil, 241, nil, + nil, nil, nil, nil, 241, nil, nil, nil, nil, nil, + nil, nil, 241, nil, nil, nil, nil, 241, 241, 241, + 241, nil, 241, 241, nil, nil, nil, 241, 241, nil, + 242, 242, 242, nil, 242, 241, nil, 241, 242, 242, + nil, nil, nil, 242, nil, 242, 242, 242, 242, 242, + 242, 242, nil, nil, nil, nil, nil, 242, 242, 242, + 242, 242, 242, 242, nil, nil, 242, nil, nil, nil, + nil, nil, nil, 242, nil, nil, 242, 242, 242, 242, + 242, 242, 242, 242, nil, 242, 242, 242, nil, 242, + 242, 242, 242, 242, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 242, nil, nil, 242, nil, nil, 242, + 242, nil, nil, 242, nil, nil, nil, nil, nil, 242, + nil, nil, nil, nil, nil, nil, nil, 242, nil, nil, + nil, nil, 242, 242, 242, 242, nil, 242, 242, nil, + nil, nil, 242, 242, nil, 243, 243, 243, nil, 243, + 242, nil, 242, 243, 243, nil, nil, nil, 243, nil, + 243, 243, 243, 243, 243, 243, 243, nil, nil, nil, + nil, nil, 243, 243, 243, 243, 243, 243, 243, nil, + nil, 243, nil, nil, nil, nil, nil, nil, 243, nil, + nil, 243, 243, 243, 243, 243, 243, 243, 243, nil, + 243, 243, 243, nil, 243, 243, 243, 243, 243, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 243, nil, + nil, 243, nil, nil, 243, 243, nil, nil, 243, nil, + nil, nil, nil, nil, 243, nil, nil, nil, nil, nil, + nil, nil, 243, nil, nil, nil, nil, 243, 243, 243, + 243, nil, 243, 243, nil, nil, nil, 243, 243, nil, + 244, 244, 244, nil, 244, 243, nil, 243, 244, 244, + nil, nil, nil, 244, nil, 244, 244, 244, 244, 244, + 244, 244, nil, nil, nil, nil, nil, 244, 244, 244, + 244, 244, 244, 244, nil, nil, 244, nil, nil, nil, + nil, nil, nil, 244, nil, nil, 244, 244, 244, 244, + 244, 244, 244, 244, nil, 244, 244, 244, nil, 244, + 244, 244, 244, 244, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 244, nil, nil, 244, nil, nil, 244, + 244, nil, nil, 244, nil, nil, nil, nil, nil, 244, + nil, nil, nil, nil, nil, nil, nil, 244, nil, nil, + nil, nil, 244, 244, 244, 244, nil, 244, 244, nil, + nil, nil, 244, 244, nil, 245, 245, 245, nil, 245, + 244, nil, 244, 245, 245, nil, nil, nil, 245, nil, + 245, 245, 245, 245, 245, 245, 245, nil, nil, nil, + nil, nil, 245, 245, 245, 245, 245, 245, 245, nil, + nil, 245, nil, nil, nil, nil, nil, nil, 245, nil, + nil, 245, 245, 245, 245, 245, 245, 245, 245, nil, + 245, 245, 245, nil, 245, 245, 245, 245, 245, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 245, nil, + nil, 245, nil, nil, 245, 245, nil, nil, 245, nil, + nil, nil, nil, nil, 245, nil, nil, nil, nil, nil, + nil, nil, 245, nil, nil, nil, nil, 245, 245, 245, + 245, nil, 245, 245, nil, nil, nil, 245, 245, nil, + 246, 246, 246, nil, 246, 245, nil, 245, 246, 246, + nil, nil, nil, 246, nil, 246, 246, 246, 246, 246, + 246, 246, nil, nil, nil, nil, nil, 246, 246, 246, + 246, 246, 246, 246, nil, nil, 246, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 246, 246, 246, 246, + 246, 246, 246, 246, nil, 246, 246, 246, nil, 246, + 246, 246, 246, 246, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 246, nil, nil, 246, + 246, nil, nil, 246, nil, nil, nil, nil, nil, 246, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + nil, nil, 246, 246, 246, 246, nil, 246, 246, nil, + nil, nil, 246, 246, nil, 252, 252, 252, nil, 252, + 246, nil, 246, 252, 252, nil, nil, nil, 252, nil, + 252, 252, 252, 252, 252, 252, 252, nil, nil, nil, + nil, nil, 252, 252, 252, 252, 252, 252, 252, nil, + nil, 252, nil, nil, nil, nil, nil, nil, 252, nil, + nil, 252, 252, 252, 252, 252, 252, 252, 252, 252, + 252, 252, 252, nil, 252, 252, 252, 252, 252, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 252, nil, + nil, 252, nil, nil, 252, 252, nil, nil, 252, nil, + 252, nil, 252, nil, 252, nil, nil, nil, nil, nil, + nil, nil, 252, nil, nil, nil, nil, 252, 252, 252, + 252, nil, 252, 252, nil, nil, nil, 252, 252, nil, + 253, 253, 253, nil, 253, 252, nil, 252, 253, 253, + nil, nil, nil, 253, nil, 253, 253, 253, 253, 253, + 253, 253, nil, nil, nil, nil, nil, 253, 253, 253, + 253, 253, 253, 253, nil, nil, 253, nil, nil, nil, + nil, nil, nil, 253, nil, nil, 253, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, nil, 253, + 253, 253, 253, 253, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 253, nil, nil, 253, nil, nil, 253, + 253, nil, nil, 253, nil, 253, nil, 253, nil, 253, + nil, nil, nil, nil, nil, nil, nil, 253, nil, nil, + nil, nil, 253, 253, 253, 253, nil, 253, 253, nil, + nil, nil, 253, 253, nil, 261, 261, 261, nil, 261, + 253, nil, 253, 261, 261, nil, nil, nil, 261, nil, + 261, 261, 261, 261, 261, 261, 261, nil, nil, nil, + nil, nil, 261, 261, 261, 261, 261, 261, 261, nil, + nil, 261, nil, nil, nil, nil, nil, nil, 261, nil, + nil, 261, 261, 261, 261, 261, 261, 261, 261, 261, + 261, 261, 261, nil, 261, 261, 261, 261, 261, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 261, nil, + nil, 261, nil, nil, 261, 261, nil, nil, 261, nil, + 261, nil, 261, nil, 261, nil, nil, nil, nil, nil, + nil, nil, 261, nil, nil, nil, nil, 261, 261, 261, + 261, nil, 261, 261, nil, nil, nil, 261, 261, 261, + 268, 268, 268, nil, 268, 261, nil, 261, 268, 268, + nil, nil, nil, 268, nil, 268, 268, 268, 268, 268, + 268, 268, nil, nil, nil, nil, nil, 268, 268, 268, + 268, 268, 268, 268, nil, nil, 268, nil, nil, nil, + nil, nil, nil, 268, nil, nil, 268, 268, 268, 268, + 268, 268, 268, 268, nil, 268, 268, 268, nil, 268, + 268, 268, 268, 268, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 268, nil, nil, 268, nil, nil, 268, + 268, nil, nil, 268, nil, nil, nil, nil, nil, 268, + nil, nil, nil, nil, nil, nil, nil, 268, nil, nil, + nil, nil, 268, 268, 268, 268, nil, 268, 268, nil, + nil, nil, 268, 268, nil, 270, 270, 270, nil, 270, + 268, nil, 268, 270, 270, nil, nil, nil, 270, nil, + 270, 270, 270, 270, 270, 270, 270, nil, nil, nil, + nil, nil, 270, 270, 270, 270, 270, 270, 270, nil, + nil, 270, nil, nil, nil, nil, nil, nil, 270, nil, + nil, 270, 270, 270, 270, 270, 270, 270, 270, nil, + 270, 270, 270, nil, 270, 270, 270, 270, 270, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 270, nil, + nil, 270, nil, nil, 270, 270, nil, nil, 270, nil, + nil, nil, nil, nil, 270, nil, nil, nil, nil, nil, + nil, nil, 270, nil, nil, nil, nil, 270, 270, 270, + 270, nil, 270, 270, nil, nil, nil, 270, 270, nil, + 272, 272, 272, nil, 272, 270, nil, 270, 272, 272, + nil, nil, nil, 272, nil, 272, 272, 272, 272, 272, + 272, 272, nil, nil, nil, nil, nil, 272, 272, 272, + 272, 272, 272, 272, nil, nil, 272, nil, nil, nil, + nil, nil, nil, 272, nil, nil, 272, 272, 272, 272, + 272, 272, 272, 272, nil, 272, 272, 272, nil, 272, + 272, 272, 272, 272, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 272, nil, nil, 272, nil, nil, 272, + 272, nil, nil, 272, nil, nil, nil, nil, nil, 272, + nil, nil, nil, nil, nil, nil, nil, 272, nil, nil, + nil, nil, 272, 272, 272, 272, nil, 272, 272, nil, + nil, nil, 272, 272, nil, 277, 277, 277, 277, 277, + 272, nil, 272, 277, 277, nil, nil, nil, 277, nil, + 277, 277, 277, 277, 277, 277, 277, nil, nil, nil, + nil, nil, 277, 277, 277, 277, 277, 277, 277, nil, + nil, 277, nil, nil, nil, nil, nil, 277, 277, nil, + 277, 277, 277, 277, 277, 277, 277, 277, 277, nil, + 277, 277, 277, nil, 277, 277, 277, 277, 277, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 277, nil, + nil, 277, nil, nil, 277, 277, nil, nil, 277, nil, + 277, nil, nil, nil, 277, nil, nil, nil, nil, nil, + nil, nil, 277, nil, nil, nil, nil, 277, 277, 277, + 277, nil, 277, 277, nil, nil, nil, 277, 277, nil, + 283, 283, 283, nil, 283, 277, nil, 277, 283, 283, + nil, nil, nil, 283, nil, 283, 283, 283, 283, 283, + 283, 283, nil, nil, nil, nil, nil, 283, 283, 283, + 283, 283, 283, 283, nil, nil, 283, nil, nil, nil, + nil, nil, nil, 283, nil, nil, 283, 283, 283, 283, + 283, 283, 283, 283, nil, 283, 283, 283, nil, 283, + 283, nil, nil, 283, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, nil, 263, 263, nil, nil, + 263, 263, nil, 283, nil, nil, 283, nil, nil, 283, + 283, nil, nil, 283, nil, nil, 263, nil, 263, nil, + 263, 263, 263, 263, 263, 263, 263, nil, 263, nil, + nil, nil, 283, 283, 283, 283, nil, 283, 283, nil, + nil, nil, 283, 283, nil, 263, nil, 283, nil, nil, + 283, nil, 283, 299, 299, 299, nil, 299, nil, nil, + nil, 299, 299, nil, nil, nil, 299, nil, 299, 299, + 299, 299, 299, 299, 299, nil, nil, nil, nil, nil, + 299, 299, 299, 299, 299, 299, 299, nil, nil, 299, + nil, nil, nil, nil, nil, nil, 299, nil, nil, 299, + 299, 299, 299, 299, 299, 299, 299, nil, 299, 299, + 299, nil, 299, 299, nil, 807, 299, 807, 807, 807, + 807, 807, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 299, nil, nil, 299, + nil, nil, 299, 299, nil, nil, 299, nil, nil, nil, + nil, nil, 807, nil, nil, nil, nil, nil, nil, nil, + nil, 807, 807, 807, 807, 299, 299, 299, 299, nil, + 299, 299, nil, nil, nil, 299, 299, nil, 308, 308, + 308, nil, 308, 299, nil, 299, 308, 308, nil, nil, + nil, 308, nil, 308, 308, 308, 308, 308, 308, 308, + nil, nil, nil, nil, nil, 308, 308, 308, 308, 308, + 308, 308, nil, nil, 308, nil, nil, nil, nil, nil, + nil, 308, nil, nil, 308, 308, 308, 308, 308, 308, + 308, 308, nil, 308, 308, 308, nil, 308, 308, 308, + 308, 308, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 308, nil, nil, 308, 308, nil, 308, 308, nil, + nil, 308, nil, nil, nil, nil, nil, 308, nil, nil, + nil, nil, nil, nil, nil, 308, nil, nil, nil, nil, + 308, 308, 308, 308, nil, 308, 308, nil, nil, nil, + 308, 308, nil, 324, 324, 324, nil, 324, 308, nil, + 308, 324, 324, nil, nil, nil, 324, nil, 324, 324, + 324, 324, 324, 324, 324, nil, nil, nil, nil, nil, + 324, 324, 324, 324, 324, 324, 324, nil, nil, 324, + nil, nil, nil, nil, nil, nil, 324, nil, nil, 324, + 324, 324, 324, 324, 324, 324, 324, nil, 324, 324, + 324, nil, 324, 324, 324, 324, 324, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 324, nil, nil, 324, + nil, nil, 324, 324, nil, nil, 324, nil, nil, nil, + nil, nil, 324, nil, nil, nil, nil, nil, nil, nil, + 324, nil, nil, nil, nil, 324, 324, 324, 324, nil, + 324, 324, nil, nil, nil, 324, 324, nil, 325, 325, + 325, nil, 325, 324, nil, 324, 325, 325, nil, nil, + nil, 325, nil, 325, 325, 325, 325, 325, 325, 325, + nil, nil, nil, nil, nil, 325, 325, 325, 325, 325, + 325, 325, nil, nil, 325, nil, nil, nil, nil, nil, + nil, 325, nil, nil, 325, 325, 325, 325, 325, 325, + 325, 325, nil, 325, 325, 325, nil, 325, 325, 325, + 325, 325, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 325, nil, nil, 325, nil, nil, 325, 325, nil, + nil, 325, nil, nil, nil, nil, nil, 325, nil, nil, + nil, nil, nil, nil, nil, 325, nil, nil, nil, nil, + 325, 325, 325, 325, nil, 325, 325, nil, nil, nil, + 325, 325, nil, 343, 343, 343, nil, 343, 325, nil, + 325, 343, 343, nil, nil, nil, 343, nil, 343, 343, + 343, 343, 343, 343, 343, nil, nil, nil, nil, nil, + 343, 343, 343, 343, 343, 343, 343, nil, nil, 343, + nil, nil, nil, nil, nil, nil, 343, nil, nil, 343, + 343, 343, 343, 343, 343, 343, 343, nil, 343, 343, + 343, nil, 343, 343, 343, 343, 343, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 343, nil, nil, 343, + nil, nil, 343, 343, nil, nil, 343, nil, nil, nil, + nil, nil, 343, nil, nil, nil, nil, nil, nil, nil, + 343, nil, nil, nil, nil, 343, 343, 343, 343, nil, + 343, 343, nil, nil, nil, 343, 343, nil, 358, 358, + 358, nil, 358, 343, nil, 343, 358, 358, nil, nil, + nil, 358, nil, 358, 358, 358, 358, 358, 358, 358, + nil, nil, nil, nil, nil, 358, 358, 358, 358, 358, + 358, 358, nil, nil, 358, nil, nil, nil, nil, nil, + nil, 358, nil, nil, 358, 358, 358, 358, 358, 358, + 358, 358, nil, 358, 358, 358, nil, 358, 358, 358, + 358, 358, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 358, nil, nil, 358, nil, nil, 358, 358, nil, + nil, 358, nil, nil, nil, nil, nil, 358, nil, nil, + nil, nil, nil, nil, nil, 358, nil, nil, nil, nil, + 358, 358, 358, 358, nil, 358, 358, nil, nil, nil, + 358, 358, nil, 385, 385, 385, nil, 385, 358, nil, + 358, 385, 385, nil, nil, nil, 385, nil, 385, 385, + 385, 385, 385, 385, 385, nil, nil, nil, nil, nil, + 385, 385, 385, 385, 385, 385, 385, nil, nil, 385, + nil, nil, nil, nil, nil, nil, 385, nil, nil, 385, + 385, 385, 385, 385, 385, 385, 385, nil, 385, 385, + 385, nil, 385, 385, 385, 385, 385, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 385, nil, nil, 385, + nil, nil, 385, 385, nil, nil, 385, nil, nil, nil, + nil, nil, 385, nil, nil, nil, nil, nil, nil, nil, + 385, nil, nil, nil, nil, 385, 385, 385, 385, nil, + 385, 385, nil, nil, nil, 385, 385, nil, 417, 417, + 417, nil, 417, 385, nil, 385, 417, 417, nil, nil, + nil, 417, nil, 417, 417, 417, 417, 417, 417, 417, + nil, nil, nil, nil, nil, 417, 417, 417, 417, 417, + 417, 417, nil, nil, 417, nil, nil, nil, nil, nil, + nil, 417, nil, nil, 417, 417, 417, 417, 417, 417, + 417, 417, 417, 417, 417, 417, nil, 417, 417, 417, + 417, 417, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 417, nil, nil, 417, nil, nil, 417, 417, nil, + nil, 417, nil, 417, nil, 417, nil, 417, nil, nil, + nil, nil, nil, nil, nil, 417, nil, nil, nil, nil, + 417, 417, 417, 417, nil, 417, 417, nil, nil, nil, + 417, 417, nil, 419, 419, 419, nil, 419, 417, nil, + 417, 419, 419, nil, nil, nil, 419, nil, 419, 419, + 419, 419, 419, 419, 419, nil, nil, nil, nil, nil, + 419, 419, 419, 419, 419, 419, 419, nil, nil, 419, + nil, nil, nil, nil, nil, nil, 419, nil, nil, 419, + 419, 419, 419, 419, 419, 419, 419, nil, 419, 419, + 419, nil, 419, 419, 419, 419, 419, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 419, nil, nil, 419, + nil, nil, 419, 419, nil, nil, 419, nil, nil, nil, + nil, nil, 419, nil, nil, nil, nil, nil, nil, nil, + 419, nil, nil, nil, nil, 419, 419, 419, 419, nil, + 419, 419, nil, nil, nil, 419, 419, nil, 420, 420, + 420, nil, 420, 419, nil, 419, 420, 420, nil, nil, + nil, 420, nil, 420, 420, 420, 420, 420, 420, 420, + nil, nil, nil, nil, nil, 420, 420, 420, 420, 420, + 420, 420, nil, nil, 420, nil, nil, nil, nil, nil, + nil, 420, nil, nil, 420, 420, 420, 420, 420, 420, + 420, 420, nil, 420, 420, 420, nil, 420, 420, 420, + 420, 420, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 420, nil, nil, 420, nil, nil, 420, 420, nil, + nil, 420, nil, nil, nil, nil, nil, 420, nil, nil, + nil, nil, nil, nil, nil, 420, nil, nil, nil, nil, + 420, 420, 420, 420, nil, 420, 420, nil, nil, nil, + 420, 420, nil, 421, 421, 421, nil, 421, 420, nil, + 420, 421, 421, nil, nil, nil, 421, nil, 421, 421, + 421, 421, 421, 421, 421, nil, nil, nil, nil, nil, + 421, 421, 421, 421, 421, 421, 421, nil, nil, 421, + nil, nil, nil, nil, nil, nil, 421, nil, nil, 421, + 421, 421, 421, 421, 421, 421, 421, nil, 421, 421, + 421, nil, 421, 421, 421, 421, 421, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 421, nil, nil, 421, + nil, nil, 421, 421, nil, nil, 421, nil, nil, nil, + nil, nil, 421, nil, nil, nil, nil, nil, nil, nil, + 421, nil, nil, nil, nil, 421, 421, 421, 421, nil, + 421, 421, nil, nil, nil, 421, 421, nil, 458, 458, + 458, nil, 458, 421, nil, 421, 458, 458, nil, nil, + nil, 458, nil, 458, 458, 458, 458, 458, 458, 458, + nil, nil, nil, nil, nil, 458, 458, 458, 458, 458, + 458, 458, nil, nil, 458, nil, nil, nil, nil, nil, + nil, 458, nil, nil, 458, 458, 458, 458, 458, 458, + 458, 458, 458, 458, 458, 458, nil, 458, 458, 458, + 458, 458, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 458, nil, nil, 458, nil, nil, 458, 458, nil, + nil, 458, nil, nil, nil, 458, nil, 458, nil, nil, + nil, nil, nil, nil, nil, 458, nil, nil, nil, nil, + 458, 458, 458, 458, nil, 458, 458, nil, nil, nil, + 458, 458, nil, 464, 464, 464, nil, 464, 458, nil, + 458, 464, 464, nil, nil, nil, 464, nil, 464, 464, + 464, 464, 464, 464, 464, nil, nil, nil, nil, nil, + 464, 464, 464, 464, 464, 464, 464, nil, nil, 464, + nil, nil, nil, nil, nil, nil, 464, nil, nil, 464, + 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, + 464, nil, 464, 464, 464, 464, 464, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 464, nil, nil, 464, + nil, nil, 464, 464, nil, nil, 464, nil, 464, nil, + 464, nil, 464, nil, nil, nil, nil, nil, nil, nil, + 464, nil, nil, nil, nil, 464, 464, 464, 464, nil, + 464, 464, nil, nil, nil, 464, 464, nil, 466, 466, + 466, nil, 466, 464, nil, 464, 466, 466, nil, nil, + nil, 466, nil, 466, 466, 466, 466, 466, 466, 466, + nil, nil, nil, nil, nil, 466, 466, 466, 466, 466, + 466, 466, nil, nil, 466, nil, nil, nil, nil, nil, + nil, 466, nil, nil, 466, 466, 466, 466, 466, 466, + 466, 466, 466, 466, 466, 466, nil, 466, 466, 466, + 466, 466, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 466, nil, nil, 466, nil, nil, 466, 466, nil, + nil, 466, nil, nil, nil, 466, nil, 466, nil, nil, + nil, nil, nil, nil, nil, 466, nil, nil, nil, nil, + 466, 466, 466, 466, nil, 466, 466, nil, nil, nil, + 466, 466, nil, 468, 468, 468, nil, 468, 466, nil, + 466, 468, 468, nil, nil, nil, 468, nil, 468, 468, + 468, 468, 468, 468, 468, nil, nil, nil, nil, nil, + 468, 468, 468, 468, 468, 468, 468, nil, nil, 468, + nil, nil, nil, nil, nil, nil, 468, nil, nil, 468, + 468, 468, 468, 468, 468, 468, 468, nil, 468, 468, + 468, nil, 468, 468, 468, 468, 468, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 468, nil, nil, 468, + nil, nil, 468, 468, nil, nil, 468, nil, nil, nil, + nil, nil, 468, nil, nil, nil, nil, nil, nil, nil, + 468, nil, nil, nil, nil, 468, 468, 468, 468, nil, + 468, 468, nil, nil, nil, 468, 468, nil, 472, 472, + 472, 472, 472, 468, nil, 468, 472, 472, nil, nil, + nil, 472, nil, 472, 472, 472, 472, 472, 472, 472, + nil, nil, nil, nil, nil, 472, 472, 472, 472, 472, + 472, 472, nil, nil, 472, nil, nil, nil, nil, nil, + 472, 472, nil, 472, 472, 472, 472, 472, 472, 472, + 472, 472, nil, 472, 472, 472, nil, 472, 472, 472, + 472, 472, 408, 408, 408, 408, 408, 408, 408, 408, + 408, 408, 408, nil, 408, 408, nil, nil, 408, 408, + nil, 472, nil, nil, 472, nil, nil, 472, 472, nil, + nil, 472, nil, 472, 408, nil, 408, 472, 408, 408, + 408, 408, 408, 408, 408, 472, 408, nil, nil, nil, + 472, 472, 472, 472, nil, 472, 472, nil, nil, nil, + 472, 472, nil, 408, nil, nil, nil, 472, 472, nil, + 472, 479, 479, 479, nil, 479, nil, nil, nil, 479, + 479, nil, nil, nil, 479, nil, 479, 479, 479, 479, + 479, 479, 479, nil, nil, nil, nil, nil, 479, 479, + 479, 479, 479, 479, 479, nil, nil, 479, nil, nil, + nil, nil, nil, nil, 479, nil, nil, 479, 479, 479, + 479, 479, 479, 479, 479, nil, 479, 479, 479, nil, + 479, 479, nil, 864, 479, 864, 864, 864, 864, 864, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 479, nil, nil, 479, nil, nil, + 479, 479, nil, nil, 479, nil, nil, nil, nil, nil, + 864, 864, nil, nil, nil, nil, nil, nil, nil, 864, + 864, 864, 864, 479, 479, 479, 479, nil, 479, 479, + nil, nil, nil, 479, 479, nil, 481, 481, 481, nil, + 481, 479, nil, 479, 481, 481, nil, nil, nil, 481, + nil, 481, 481, 481, 481, 481, 481, 481, nil, nil, + nil, nil, nil, 481, 481, 481, 481, 481, 481, 481, + nil, nil, 481, nil, nil, nil, nil, nil, nil, 481, + nil, nil, 481, 481, 481, 481, 481, 481, 481, 481, + 481, 481, 481, 481, nil, 481, 481, 481, 481, 481, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 481, + nil, nil, 481, nil, nil, 481, 481, nil, nil, 481, + nil, 481, nil, 481, nil, 481, nil, nil, nil, nil, + nil, nil, nil, 481, nil, nil, nil, nil, 481, 481, + 481, 481, nil, 481, 481, nil, nil, nil, 481, 481, + nil, 488, 488, 488, nil, 488, 481, nil, 481, 488, + 488, nil, nil, nil, 488, nil, 488, 488, 488, 488, + 488, 488, 488, nil, nil, nil, nil, nil, 488, 488, + 488, 488, 488, 488, 488, nil, nil, 488, nil, nil, + nil, nil, nil, nil, 488, nil, nil, 488, 488, 488, + 488, 488, 488, 488, 488, nil, 488, 488, 488, nil, + 488, 488, nil, 890, 488, 890, 890, 890, 890, 890, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 488, nil, nil, 488, nil, nil, + 488, 488, nil, nil, 488, nil, nil, nil, nil, nil, + 890, nil, nil, nil, nil, nil, nil, nil, nil, 890, + 890, 890, 890, 488, 488, 488, 488, nil, 488, 488, + nil, nil, nil, 488, 488, nil, 491, 491, 491, nil, + 491, 488, nil, 488, 491, 491, nil, nil, nil, 491, + nil, 491, 491, 491, 491, 491, 491, 491, nil, nil, + nil, nil, nil, 491, 491, 491, 491, 491, 491, 491, + nil, nil, 491, nil, nil, nil, nil, nil, nil, 491, + nil, nil, 491, 491, 491, 491, 491, 491, 491, 491, + nil, 491, 491, 491, nil, 491, 491, 491, 491, 491, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 491, + nil, nil, 491, nil, nil, 491, 491, nil, nil, 491, + nil, nil, nil, nil, nil, 491, nil, nil, nil, nil, + nil, nil, nil, 491, nil, nil, nil, nil, 491, 491, + 491, 491, nil, 491, 491, nil, nil, nil, 491, 491, + nil, 492, 492, 492, nil, 492, 491, nil, 491, 492, + 492, nil, nil, nil, 492, nil, 492, 492, 492, 492, + 492, 492, 492, nil, nil, nil, nil, nil, 492, 492, + 492, 492, 492, 492, 492, nil, nil, 492, nil, nil, + nil, nil, nil, nil, 492, nil, nil, 492, 492, 492, + 492, 492, 492, 492, 492, nil, 492, 492, 492, nil, + 492, 492, 492, 492, 492, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 492, nil, nil, 492, nil, nil, + 492, 492, nil, nil, 492, nil, nil, nil, nil, nil, + 492, nil, nil, nil, nil, nil, nil, nil, 492, nil, + nil, nil, nil, 492, 492, 492, 492, nil, 492, 492, + nil, nil, nil, 492, 492, nil, 493, 493, 493, nil, + 493, 492, nil, 492, 493, 493, nil, nil, nil, 493, + nil, 493, 493, 493, 493, 493, 493, 493, nil, nil, + nil, nil, nil, 493, 493, 493, 493, 493, 493, 493, + nil, nil, 493, nil, nil, nil, nil, nil, nil, 493, + nil, nil, 493, 493, 493, 493, 493, 493, 493, 493, + nil, 493, 493, 493, nil, 493, 493, 493, 493, 493, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 493, + nil, nil, 493, nil, nil, 493, 493, nil, nil, 493, + nil, nil, nil, nil, nil, 493, nil, nil, nil, nil, + nil, nil, nil, 493, nil, nil, nil, nil, 493, 493, + 493, 493, nil, 493, 493, nil, nil, nil, 493, 493, + nil, 497, 497, 497, nil, 497, 493, nil, 493, 497, + 497, nil, nil, nil, 497, nil, 497, 497, 497, 497, + 497, 497, 497, nil, nil, nil, nil, nil, 497, 497, + 497, 497, 497, 497, 497, nil, nil, 497, nil, nil, + nil, nil, nil, nil, 497, nil, nil, 497, 497, 497, + 497, 497, 497, 497, 497, nil, 497, 497, 497, nil, + 497, 497, 497, 497, 497, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 497, nil, nil, 497, nil, nil, + 497, 497, nil, nil, 497, nil, nil, nil, nil, nil, + 497, nil, nil, nil, nil, nil, nil, nil, 497, nil, + nil, nil, nil, 497, 497, 497, 497, nil, 497, 497, + nil, nil, nil, 497, 497, nil, 499, 499, 499, nil, + 499, 497, nil, 497, 499, 499, nil, nil, nil, 499, + nil, 499, 499, 499, 499, 499, 499, 499, nil, nil, + nil, nil, nil, 499, 499, 499, 499, 499, 499, 499, + nil, nil, 499, nil, nil, nil, nil, nil, nil, 499, + nil, nil, 499, 499, 499, 499, 499, 499, 499, 499, + nil, 499, 499, 499, nil, 499, 499, 499, 499, 499, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 499, + nil, nil, 499, nil, nil, 499, 499, nil, nil, 499, + nil, 499, nil, nil, nil, 499, nil, nil, nil, nil, + nil, nil, nil, 499, nil, nil, nil, nil, 499, 499, + 499, 499, nil, 499, 499, nil, nil, nil, 499, 499, + nil, 503, 503, 503, nil, 503, 499, nil, 499, 503, + 503, nil, nil, nil, 503, nil, 503, 503, 503, 503, + 503, 503, 503, nil, nil, nil, nil, nil, 503, 503, + 503, 503, 503, 503, 503, nil, nil, 503, nil, nil, + nil, nil, nil, nil, 503, nil, nil, 503, 503, 503, + 503, 503, 503, 503, 503, 503, 503, 503, 503, nil, + 503, 503, 503, 503, 503, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 503, nil, nil, 503, nil, nil, + 503, 503, nil, nil, 503, nil, 503, nil, nil, nil, + 503, nil, nil, nil, nil, nil, nil, nil, 503, nil, + nil, nil, nil, 503, 503, 503, 503, nil, 503, 503, + nil, nil, nil, 503, 503, nil, 506, 506, 506, nil, + 506, 503, nil, 503, 506, 506, nil, nil, nil, 506, + nil, 506, 506, 506, 506, 506, 506, 506, nil, nil, + nil, nil, nil, 506, 506, 506, 506, 506, 506, 506, + nil, nil, 506, nil, nil, nil, nil, nil, nil, 506, + nil, nil, 506, 506, 506, 506, 506, 506, 506, 506, + 506, 506, 506, 506, nil, 506, 506, 506, 506, 506, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 506, + nil, nil, 506, nil, nil, 506, 506, nil, nil, 506, + nil, nil, nil, nil, nil, 506, nil, nil, nil, nil, + nil, nil, nil, 506, nil, nil, nil, nil, 506, 506, + 506, 506, nil, 506, 506, nil, nil, nil, 506, 506, + nil, 520, 520, 520, nil, 520, 506, nil, 506, 520, + 520, nil, nil, nil, 520, nil, 520, 520, 520, 520, + 520, 520, 520, nil, nil, nil, nil, nil, 520, 520, + 520, 520, 520, 520, 520, nil, nil, 520, nil, nil, + nil, nil, nil, nil, 520, nil, nil, 520, 520, 520, + 520, 520, 520, 520, 520, nil, 520, 520, 520, nil, + 520, 520, 520, 520, 520, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 520, nil, nil, 520, nil, nil, + 520, 520, nil, nil, 520, nil, 520, nil, nil, nil, + 520, nil, nil, nil, nil, nil, nil, nil, 520, nil, + nil, nil, nil, 520, 520, 520, 520, nil, 520, 520, + nil, nil, nil, 520, 520, nil, 521, 521, 521, nil, + 521, 520, nil, 520, 521, 521, nil, nil, nil, 521, + nil, 521, 521, 521, 521, 521, 521, 521, nil, nil, + nil, nil, nil, 521, 521, 521, 521, 521, 521, 521, + nil, nil, 521, nil, nil, nil, nil, nil, nil, 521, + nil, nil, 521, 521, 521, 521, 521, 521, 521, 521, + 521, 521, 521, 521, nil, 521, 521, 521, 521, 521, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 521, + nil, nil, 521, nil, nil, 521, 521, nil, nil, 521, + nil, 521, nil, 521, nil, 521, nil, nil, nil, nil, + nil, nil, nil, 521, nil, nil, nil, nil, 521, 521, + 521, 521, nil, 521, 521, nil, nil, nil, 521, 521, + nil, 531, 531, 531, nil, 531, 521, nil, 521, 531, + 531, nil, nil, nil, 531, nil, 531, 531, 531, 531, + 531, 531, 531, nil, nil, nil, nil, nil, 531, 531, + 531, 531, 531, 531, 531, nil, nil, 531, nil, nil, + nil, nil, nil, nil, 531, nil, nil, 531, 531, 531, + 531, 531, 531, 531, 531, 531, 531, 531, 531, nil, + 531, 531, 531, 531, 531, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 531, nil, nil, 531, nil, nil, + 531, 531, nil, nil, 531, nil, 531, nil, 531, nil, + 531, nil, nil, nil, nil, nil, nil, nil, 531, nil, + nil, nil, nil, 531, 531, 531, 531, nil, 531, 531, + nil, nil, nil, 531, 531, nil, 534, 534, 534, nil, + 534, 531, nil, 531, 534, 534, nil, nil, nil, 534, + nil, 534, 534, 534, 534, 534, 534, 534, nil, nil, + nil, nil, nil, 534, 534, 534, 534, 534, 534, 534, + nil, nil, 534, nil, nil, nil, nil, nil, nil, 534, + nil, nil, 534, 534, 534, 534, 534, 534, 534, 534, + nil, 534, 534, 534, nil, 534, 534, 534, 534, 534, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 534, + nil, nil, 534, nil, nil, 534, 534, nil, nil, 534, + nil, nil, nil, nil, nil, 534, nil, nil, nil, nil, + nil, nil, nil, 534, nil, nil, nil, nil, 534, 534, + 534, 534, nil, 534, 534, nil, nil, nil, 534, 534, + nil, 562, 562, 562, nil, 562, 534, nil, 534, 562, + 562, nil, nil, nil, 562, nil, 562, 562, 562, 562, + 562, 562, 562, nil, nil, nil, nil, nil, 562, 562, + 562, 562, 562, 562, 562, nil, nil, 562, nil, nil, + nil, nil, nil, nil, 562, nil, nil, 562, 562, 562, + 562, 562, 562, 562, 562, nil, 562, 562, 562, nil, + 562, 562, 562, 562, 562, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 562, nil, nil, 562, nil, nil, + 562, 562, nil, nil, 562, nil, nil, nil, nil, nil, + 562, nil, nil, nil, nil, nil, nil, nil, 562, nil, + nil, nil, nil, 562, 562, 562, 562, nil, 562, 562, + nil, nil, nil, 562, 562, nil, 564, 564, 564, nil, + 564, 562, nil, 562, 564, 564, nil, nil, nil, 564, + nil, 564, 564, 564, 564, 564, 564, 564, nil, nil, + nil, nil, nil, 564, 564, 564, 564, 564, 564, 564, + nil, nil, 564, nil, nil, nil, nil, nil, nil, 564, + nil, nil, 564, 564, 564, 564, 564, 564, 564, 564, + nil, 564, 564, 564, nil, 564, 564, 564, 564, 564, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 564, + nil, nil, 564, nil, nil, 564, 564, nil, nil, 564, + nil, 564, nil, nil, nil, 564, nil, nil, nil, nil, + nil, nil, nil, 564, nil, nil, nil, nil, 564, 564, + 564, 564, nil, 564, 564, nil, nil, nil, 564, 564, + nil, 565, 565, 565, nil, 565, 564, nil, 564, 565, + 565, nil, nil, nil, 565, nil, 565, 565, 565, 565, + 565, 565, 565, nil, nil, nil, nil, nil, 565, 565, + 565, 565, 565, 565, 565, nil, nil, 565, nil, nil, + nil, nil, nil, nil, 565, nil, nil, 565, 565, 565, + 565, 565, 565, 565, 565, nil, 565, 565, 565, nil, + 565, 565, 565, 565, 565, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 565, nil, nil, 565, nil, nil, + 565, 565, nil, nil, 565, nil, nil, nil, nil, nil, + 565, nil, nil, nil, nil, nil, nil, nil, 565, nil, + nil, nil, nil, 565, 565, 565, 565, nil, 565, 565, + nil, nil, nil, 565, 565, nil, 568, 568, 568, nil, + 568, 565, nil, 565, 568, 568, nil, nil, nil, 568, + nil, 568, 568, 568, 568, 568, 568, 568, nil, nil, + nil, nil, nil, 568, 568, 568, 568, 568, 568, 568, + nil, nil, 568, nil, nil, nil, nil, nil, nil, 568, + nil, nil, 568, 568, 568, 568, 568, 568, 568, 568, + nil, 568, 568, 568, nil, 568, 568, 568, 568, 568, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 568, + nil, nil, 568, nil, nil, 568, 568, nil, nil, 568, + nil, nil, nil, nil, nil, 568, nil, nil, nil, nil, + nil, nil, nil, 568, nil, nil, nil, nil, 568, 568, + 568, 568, nil, 568, 568, nil, nil, nil, 568, 568, + nil, 569, 569, 569, nil, 569, 568, nil, 568, 569, + 569, nil, nil, nil, 569, nil, 569, 569, 569, 569, + 569, 569, 569, nil, nil, nil, nil, nil, 569, 569, + 569, 569, 569, 569, 569, nil, nil, 569, nil, nil, + nil, nil, nil, nil, 569, nil, nil, 569, 569, 569, + 569, 569, 569, 569, 569, nil, 569, 569, 569, nil, + 569, 569, 569, 569, 569, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 569, nil, nil, 569, nil, nil, + 569, 569, nil, nil, 569, nil, nil, nil, nil, nil, + 569, nil, nil, nil, nil, nil, nil, nil, 569, nil, + nil, nil, nil, 569, 569, 569, 569, nil, 569, 569, + nil, nil, nil, 569, 569, nil, 573, 573, 573, nil, + 573, 569, nil, 569, 573, 573, nil, nil, nil, 573, + nil, 573, 573, 573, 573, 573, 573, 573, nil, nil, + nil, nil, nil, 573, 573, 573, 573, 573, 573, 573, + nil, nil, 573, nil, nil, nil, nil, nil, nil, 573, + nil, nil, 573, 573, 573, 573, 573, 573, 573, 573, + nil, 573, 573, 573, nil, 573, 573, 573, 573, 573, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 573, + nil, nil, 573, nil, nil, 573, 573, nil, nil, 573, + nil, nil, nil, nil, nil, 573, nil, nil, nil, nil, + nil, nil, nil, 573, nil, nil, nil, nil, 573, 573, + 573, 573, nil, 573, 573, nil, nil, nil, 573, 573, + nil, 574, 574, 574, nil, 574, 573, nil, 573, 574, + 574, nil, nil, nil, 574, nil, 574, 574, 574, 574, + 574, 574, 574, nil, nil, nil, nil, nil, 574, 574, + 574, 574, 574, 574, 574, nil, nil, 574, nil, nil, + nil, nil, nil, nil, 574, nil, nil, 574, 574, 574, + 574, 574, 574, 574, 574, nil, 574, 574, 574, nil, + 574, 574, 574, 574, 574, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 574, nil, nil, 574, nil, nil, + 574, 574, nil, nil, 574, nil, nil, nil, nil, nil, + 574, nil, nil, nil, nil, nil, nil, nil, 574, nil, + nil, nil, nil, 574, 574, 574, 574, nil, 574, 574, + nil, nil, nil, 574, 574, nil, 608, 608, 608, nil, + 608, 574, nil, 574, 608, 608, nil, nil, nil, 608, + nil, 608, 608, 608, 608, 608, 608, 608, nil, nil, + nil, nil, nil, 608, 608, 608, 608, 608, 608, 608, + nil, nil, 608, nil, nil, nil, nil, nil, nil, 608, + nil, nil, 608, 608, 608, 608, 608, 608, 608, 608, + nil, 608, 608, 608, nil, 608, 608, 608, 608, 608, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 608, + nil, nil, 608, nil, nil, 608, 608, nil, nil, 608, + nil, nil, nil, nil, nil, 608, nil, nil, nil, nil, + nil, nil, nil, 608, nil, nil, nil, nil, 608, 608, + 608, 608, nil, 608, 608, nil, nil, nil, 608, 608, + nil, 613, 613, 613, nil, 613, 608, nil, 608, 613, + 613, nil, nil, nil, 613, nil, 613, 613, 613, 613, + 613, 613, 613, nil, nil, nil, nil, nil, 613, 613, + 613, 613, 613, 613, 613, nil, nil, 613, nil, nil, + nil, nil, nil, nil, 613, nil, nil, 613, 613, 613, + 613, 613, 613, 613, 613, nil, 613, 613, 613, nil, + 613, 613, nil, 913, 613, 913, 913, 913, 913, 913, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 613, nil, nil, 613, nil, nil, + 613, 613, nil, nil, 613, nil, nil, nil, nil, nil, + 913, nil, nil, nil, nil, nil, nil, nil, nil, 913, + 913, 913, 913, 613, 613, 613, 613, nil, 613, 613, + nil, nil, nil, 613, 613, nil, 624, 624, 624, nil, + 624, 613, nil, 613, 624, 624, nil, nil, nil, 624, + nil, 624, 624, 624, 624, 624, 624, 624, nil, nil, + nil, nil, nil, 624, 624, 624, 624, 624, 624, 624, + nil, nil, 624, nil, nil, nil, nil, nil, nil, 624, + nil, nil, 624, 624, 624, 624, 624, 624, 624, 624, + nil, 624, 624, 624, nil, 624, 624, nil, nil, 624, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 624, + nil, nil, 624, nil, nil, 624, 624, nil, nil, 624, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 624, 624, + 624, 624, nil, 624, 624, nil, nil, nil, 624, 624, + nil, 677, 677, 677, nil, 677, 624, nil, 624, 677, + 677, nil, nil, nil, 677, nil, 677, 677, 677, 677, + 677, 677, 677, nil, nil, nil, nil, nil, 677, 677, + 677, 677, 677, 677, 677, nil, nil, 677, nil, nil, + nil, nil, nil, nil, 677, nil, nil, 677, 677, 677, + 677, 677, 677, 677, 677, nil, 677, 677, 677, nil, + 677, 677, 677, 677, 677, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 677, nil, nil, 677, nil, nil, + 677, 677, nil, nil, 677, nil, nil, nil, nil, nil, + 677, nil, nil, nil, nil, nil, nil, nil, 677, nil, + nil, nil, nil, 677, 677, 677, 677, nil, 677, 677, + nil, nil, nil, 677, 677, nil, 705, 705, 705, nil, + 705, 677, nil, 677, 705, 705, nil, nil, nil, 705, + nil, 705, 705, 705, 705, 705, 705, 705, nil, nil, + nil, nil, nil, 705, 705, 705, 705, 705, 705, 705, + nil, nil, 705, nil, nil, nil, nil, nil, nil, 705, + nil, nil, 705, 705, 705, 705, 705, 705, 705, 705, + nil, 705, 705, 705, nil, 705, 705, 705, 705, 705, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 705, + nil, nil, 705, nil, nil, 705, 705, nil, nil, 705, + nil, nil, nil, nil, nil, 705, nil, nil, nil, nil, + nil, nil, nil, 705, nil, nil, nil, nil, 705, 705, + 705, 705, nil, 705, 705, nil, nil, nil, 705, 705, + nil, 707, 707, 707, nil, 707, 705, nil, 705, 707, + 707, nil, nil, nil, 707, nil, 707, 707, 707, 707, + 707, 707, 707, nil, nil, nil, nil, nil, 707, 707, + 707, 707, 707, 707, 707, nil, nil, 707, nil, nil, + nil, nil, nil, nil, 707, nil, nil, 707, 707, 707, + 707, 707, 707, 707, 707, nil, 707, 707, 707, nil, + 707, 707, 707, 707, 707, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 707, nil, nil, 707, nil, nil, + 707, 707, nil, nil, 707, nil, nil, nil, nil, nil, + 707, nil, nil, nil, nil, nil, nil, nil, 707, nil, + nil, nil, nil, 707, 707, 707, 707, nil, 707, 707, + nil, nil, nil, 707, 707, nil, 719, 719, 719, nil, + 719, 707, nil, 707, 719, 719, nil, nil, nil, 719, + nil, 719, 719, 719, 719, 719, 719, 719, nil, nil, + nil, nil, nil, 719, 719, 719, 719, 719, 719, 719, + nil, nil, 719, nil, nil, nil, nil, nil, nil, 719, + nil, nil, 719, 719, 719, 719, 719, 719, 719, 719, + nil, 719, 719, 719, nil, 719, 719, 719, 719, 719, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 719, + nil, nil, 719, nil, nil, 719, 719, nil, nil, 719, + nil, nil, nil, nil, nil, 719, nil, nil, nil, nil, + nil, nil, nil, 719, nil, nil, nil, nil, 719, 719, + 719, 719, nil, 719, 719, nil, nil, nil, 719, 719, + nil, 720, 720, 720, nil, 720, 719, nil, 719, 720, + 720, nil, nil, nil, 720, nil, 720, 720, 720, 720, + 720, 720, 720, nil, nil, nil, nil, nil, 720, 720, + 720, 720, 720, 720, 720, nil, nil, 720, nil, nil, + nil, nil, nil, nil, 720, nil, nil, 720, 720, 720, + 720, 720, 720, 720, 720, nil, 720, 720, 720, nil, + 720, 720, 720, 720, 720, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 720, nil, nil, 720, nil, nil, + 720, 720, nil, nil, 720, nil, nil, nil, nil, nil, + 720, nil, nil, nil, nil, nil, nil, nil, 720, nil, + nil, nil, nil, 720, 720, 720, 720, nil, 720, 720, + nil, nil, nil, 720, 720, nil, 721, 721, 721, nil, + 721, 720, nil, 720, 721, 721, nil, nil, nil, 721, + nil, 721, 721, 721, 721, 721, 721, 721, nil, nil, + nil, nil, nil, 721, 721, 721, 721, 721, 721, 721, + nil, nil, 721, nil, nil, nil, nil, nil, nil, 721, + nil, nil, 721, 721, 721, 721, 721, 721, 721, 721, + nil, 721, 721, 721, nil, 721, 721, 721, 721, 721, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 721, + nil, nil, 721, nil, nil, 721, 721, nil, nil, 721, + nil, nil, nil, nil, nil, 721, nil, nil, nil, nil, + nil, nil, nil, 721, nil, nil, nil, nil, 721, 721, + 721, 721, nil, 721, 721, nil, nil, nil, 721, 721, + nil, 722, 722, 722, nil, 722, 721, nil, 721, 722, + 722, nil, nil, nil, 722, nil, 722, 722, 722, 722, + 722, 722, 722, nil, nil, nil, nil, nil, 722, 722, + 722, 722, 722, 722, 722, nil, nil, 722, nil, nil, + nil, nil, nil, nil, 722, nil, nil, 722, 722, 722, + 722, 722, 722, 722, 722, nil, 722, 722, 722, nil, + 722, 722, 722, 722, 722, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 722, nil, nil, 722, nil, nil, + 722, 722, nil, nil, 722, nil, nil, nil, nil, nil, + 722, nil, nil, nil, nil, nil, nil, nil, 722, nil, + nil, nil, nil, 722, 722, 722, 722, nil, 722, 722, + nil, nil, nil, 722, 722, nil, 724, 724, 724, nil, + 724, 722, nil, 722, 724, 724, nil, nil, nil, 724, + nil, 724, 724, 724, 724, 724, 724, 724, nil, nil, + nil, nil, nil, 724, 724, 724, 724, 724, 724, 724, + nil, nil, 724, nil, nil, nil, nil, nil, nil, 724, + nil, nil, 724, 724, 724, 724, 724, 724, 724, 724, + nil, 724, 724, 724, nil, 724, 724, 724, 724, 724, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 724, + nil, nil, 724, nil, nil, 724, 724, nil, nil, 724, + nil, nil, nil, nil, nil, 724, nil, nil, nil, nil, + nil, nil, nil, 724, nil, nil, nil, nil, 724, 724, + 724, 724, nil, 724, 724, nil, nil, nil, 724, 724, + nil, 736, 736, 736, nil, 736, 724, nil, 724, 736, + 736, nil, nil, nil, 736, nil, 736, 736, 736, 736, + 736, 736, 736, nil, nil, nil, nil, nil, 736, 736, + 736, 736, 736, 736, 736, nil, nil, 736, nil, nil, + nil, nil, nil, nil, 736, nil, nil, 736, 736, 736, + 736, 736, 736, 736, 736, 736, 736, 736, 736, nil, + 736, 736, 736, 736, 736, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 736, nil, nil, 736, nil, nil, + 736, 736, nil, nil, 736, nil, 736, nil, 736, nil, + 736, nil, nil, nil, nil, nil, nil, nil, 736, nil, + nil, nil, nil, 736, 736, 736, 736, nil, 736, 736, + nil, nil, nil, 736, 736, nil, 743, 743, 743, nil, + 743, 736, nil, 736, 743, 743, nil, nil, nil, 743, + nil, 743, 743, 743, 743, 743, 743, 743, nil, nil, + nil, nil, nil, 743, 743, 743, 743, 743, 743, 743, + nil, nil, 743, nil, nil, nil, nil, nil, nil, 743, + nil, nil, 743, 743, 743, 743, 743, 743, 743, 743, + 743, 743, 743, 743, nil, 743, 743, 743, 743, 743, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 743, + nil, nil, 743, nil, nil, 743, 743, nil, nil, 743, + nil, 743, nil, 743, nil, 743, nil, nil, nil, nil, + nil, nil, nil, 743, nil, nil, nil, nil, 743, 743, + 743, 743, nil, 743, 743, nil, nil, nil, 743, 743, + nil, 754, 754, 754, nil, 754, 743, nil, 743, 754, + 754, nil, nil, nil, 754, nil, 754, 754, 754, 754, + 754, 754, 754, nil, nil, nil, nil, nil, 754, 754, + 754, 754, 754, 754, 754, nil, nil, 754, nil, nil, + nil, nil, nil, nil, 754, nil, nil, 754, 754, 754, + 754, 754, 754, 754, 754, nil, 754, 754, 754, nil, + 754, 754, nil, nil, 754, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 754, nil, nil, 754, nil, nil, + 754, 754, nil, nil, 754, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 754, 754, 754, 754, nil, 754, 754, + nil, nil, nil, 754, 754, nil, 768, 768, 768, nil, + 768, 754, nil, 754, 768, 768, nil, nil, nil, 768, + nil, 768, 768, 768, 768, 768, 768, 768, nil, nil, + nil, nil, nil, 768, 768, 768, 768, 768, 768, 768, + nil, nil, 768, nil, nil, nil, nil, nil, nil, 768, + nil, nil, 768, 768, 768, 768, 768, 768, 768, 768, + nil, 768, 768, 768, nil, 768, 768, 768, 768, 768, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 768, + nil, nil, 768, nil, nil, 768, 768, nil, nil, 768, + nil, nil, nil, nil, nil, 768, nil, nil, nil, nil, + nil, nil, nil, 768, nil, nil, nil, nil, 768, 768, + 768, 768, nil, 768, 768, nil, nil, nil, 768, 768, + nil, 781, 781, 781, nil, 781, 768, nil, 768, 781, + 781, nil, nil, nil, 781, nil, 781, 781, 781, 781, + 781, 781, 781, nil, nil, nil, nil, nil, 781, 781, + 781, 781, 781, 781, 781, nil, nil, 781, nil, nil, + nil, nil, nil, nil, 781, nil, nil, 781, 781, 781, + 781, 781, 781, 781, 781, nil, 781, 781, 781, nil, + 781, 781, 781, 781, 781, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 781, nil, nil, 781, nil, nil, + 781, 781, nil, nil, 781, nil, nil, nil, nil, nil, + 781, nil, nil, nil, nil, nil, nil, nil, 781, nil, + nil, nil, nil, 781, 781, 781, 781, nil, 781, 781, + nil, nil, nil, 781, 781, nil, 786, 786, 786, nil, + 786, 781, nil, 781, 786, 786, nil, nil, nil, 786, + nil, 786, 786, 786, 786, 786, 786, 786, nil, nil, + nil, nil, nil, 786, 786, 786, 786, 786, 786, 786, + nil, nil, 786, nil, nil, nil, nil, nil, nil, 786, + nil, nil, 786, 786, 786, 786, 786, 786, 786, 786, + nil, 786, 786, 786, nil, 786, 786, 786, 786, 786, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 786, + nil, nil, 786, nil, nil, 786, 786, nil, nil, 786, + nil, 786, nil, nil, nil, 786, nil, nil, nil, nil, + nil, nil, nil, 786, nil, nil, nil, nil, 786, 786, + 786, 786, nil, 786, 786, nil, nil, nil, 786, 786, + nil, 803, 803, 803, nil, 803, 786, nil, 786, 803, + 803, nil, nil, nil, 803, nil, 803, 803, 803, 803, + 803, 803, 803, nil, nil, nil, nil, nil, 803, 803, + 803, 803, 803, 803, 803, nil, nil, 803, nil, nil, + nil, nil, nil, nil, 803, nil, nil, 803, 803, 803, + 803, 803, 803, 803, 803, nil, 803, 803, 803, nil, + 803, 803, 803, 803, 803, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 803, nil, nil, 803, nil, nil, + 803, 803, nil, nil, 803, nil, nil, nil, nil, nil, + 803, nil, nil, nil, nil, nil, nil, nil, 803, nil, + nil, nil, nil, 803, 803, 803, 803, nil, 803, 803, + nil, nil, nil, 803, 803, nil, 817, 817, 817, nil, + 817, 803, nil, 803, 817, 817, nil, nil, nil, 817, + nil, 817, 817, 817, 817, 817, 817, 817, nil, nil, + nil, nil, nil, 817, 817, 817, 817, 817, 817, 817, + nil, nil, 817, nil, nil, nil, nil, nil, nil, 817, + nil, nil, 817, 817, 817, 817, 817, 817, 817, 817, + nil, 817, 817, 817, nil, 817, 817, nil, nil, 817, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 817, + nil, nil, 817, nil, nil, 817, 817, nil, nil, 817, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 817, 817, + 817, 817, nil, 817, 817, nil, nil, nil, 817, 817, + nil, 878, 878, 878, nil, 878, 817, nil, 817, 878, + 878, nil, nil, nil, 878, nil, 878, 878, 878, 878, + 878, 878, 878, nil, nil, nil, nil, nil, 878, 878, + 878, 878, 878, 878, 878, nil, nil, 878, nil, nil, + nil, nil, nil, nil, 878, nil, nil, 878, 878, 878, + 878, 878, 878, 878, 878, 878, 878, 878, 878, nil, + 878, 878, 878, 878, 878, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 878, nil, nil, 878, nil, nil, + 878, 878, nil, nil, 878, nil, 878, nil, 878, nil, + 878, nil, nil, nil, nil, nil, nil, nil, 878, nil, + nil, nil, nil, 878, 878, 878, 878, nil, 878, 878, + nil, nil, nil, 878, 878, nil, 881, 881, 881, nil, + 881, 878, nil, 878, 881, 881, nil, nil, nil, 881, + nil, 881, 881, 881, 881, 881, 881, 881, nil, nil, + nil, nil, nil, 881, 881, 881, 881, 881, 881, 881, + nil, nil, 881, nil, nil, nil, nil, nil, nil, 881, + nil, nil, 881, 881, 881, 881, 881, 881, 881, 881, + nil, 881, 881, 881, nil, 881, 881, 881, 881, 881, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 881, + nil, nil, 881, nil, nil, 881, 881, nil, nil, 881, + nil, 881, nil, 881, nil, 881, nil, nil, nil, nil, + nil, nil, nil, 881, nil, nil, nil, nil, 881, 881, + 881, 881, nil, 881, 881, nil, nil, nil, 881, 881, + nil, 883, 883, 883, nil, 883, 881, nil, 881, 883, + 883, nil, nil, nil, 883, nil, 883, 883, 883, 883, + 883, 883, 883, nil, nil, nil, nil, nil, 883, 883, + 883, 883, 883, 883, 883, nil, nil, 883, nil, nil, + nil, nil, nil, nil, 883, nil, nil, 883, 883, 883, + 883, 883, 883, 883, 883, 883, 883, 883, 883, nil, + 883, 883, 883, 883, 883, 447, 447, 447, 447, 447, + 447, 447, 447, 447, 447, 447, nil, 447, 447, nil, + nil, 447, 447, nil, 883, nil, nil, 883, nil, nil, + 883, 883, nil, nil, 883, nil, 883, 447, 883, 447, + 883, 447, 447, 447, 447, 447, 447, 447, 883, 447, + nil, nil, nil, 883, 883, 883, 883, nil, 883, 883, + nil, nil, nil, 883, 883, 447, 447, 25, nil, nil, + nil, 883, nil, 883, 25, 25, 25, nil, nil, 25, + 25, 25, nil, 25, nil, nil, nil, nil, nil, nil, + nil, nil, 25, 25, 25, nil, nil, nil, nil, nil, + nil, nil, nil, 25, 25, nil, 25, 25, 25, 25, + 25, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, nil, nil, 25, + 25, 25, nil, nil, 25, nil, 25, 25, nil, nil, + 25, 25, nil, 25, nil, 25, nil, 25, nil, 25, + 25, 25, 25, 25, 25, 25, 26, 25, 25, 25, + nil, nil, nil, 26, 26, 26, nil, nil, 26, 26, + 26, nil, 26, 25, 25, nil, 25, nil, 25, nil, + nil, nil, 26, 26, nil, nil, nil, nil, nil, nil, + nil, nil, 26, 26, nil, 26, 26, 26, 26, 26, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, nil, nil, 26, 26, + 26, nil, nil, 26, nil, 26, 26, nil, nil, 26, + 26, nil, 26, nil, 26, nil, 26, nil, 26, 26, + 26, 26, 26, 26, 26, 396, 26, nil, 26, nil, + nil, nil, 396, 396, 396, nil, nil, 396, 396, 396, + nil, 396, 26, 26, nil, 26, nil, 26, nil, nil, + 396, 396, 396, nil, nil, nil, nil, nil, nil, nil, + nil, 396, 396, nil, 396, 396, 396, 396, 396, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 396, 396, 396, 396, 396, 396, 396, 396, 396, + 396, 396, 396, 396, 396, nil, nil, 396, 396, 396, + nil, nil, 396, nil, 396, 396, nil, nil, 396, 396, + nil, 396, nil, 396, nil, 396, nil, 396, 396, 396, + 396, 396, 396, 396, 449, 396, 396, 396, nil, nil, + nil, 449, 449, 449, nil, nil, 449, 449, 449, nil, + 449, 396, 396, nil, 396, nil, 396, nil, nil, nil, + 449, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 449, 449, nil, 449, 449, 449, 449, 449, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 452, + nil, nil, nil, nil, nil, nil, 452, 452, 452, nil, + nil, 452, 452, 452, nil, 452, nil, nil, nil, nil, + nil, 449, nil, nil, nil, 452, nil, nil, 449, nil, + nil, nil, nil, 449, 449, 452, 452, nil, 452, 452, + 452, 452, 452, nil, nil, nil, nil, nil, 202, 202, + nil, nil, 202, nil, nil, nil, 449, nil, nil, nil, + 202, 202, nil, 202, 202, 202, 202, 202, 202, 202, + 449, nil, 202, 202, nil, 449, 452, 202, 202, 202, + 202, nil, nil, 452, nil, nil, 202, nil, 452, 452, + nil, nil, nil, nil, 202, 202, nil, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, nil, nil, + 202, 452, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 452, nil, nil, nil, nil, + 452, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, nil, nil, nil, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, nil, nil, + nil, nil, nil, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, nil, 8, nil, nil, nil, nil, nil, + nil, nil, 8, 8, nil, 8, 8, 8, 8, 8, + 8, 8, nil, nil, 8, 8, nil, nil, nil, 8, + 8, 8, 8, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 8, 8, nil, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + nil, nil, 8, 8, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, nil, + nil, nil, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, nil, nil, nil, nil, nil, 9, 9, 9, + 9, 9, 9, 9, 9, 9, nil, nil, 9, nil, + nil, nil, nil, nil, nil, nil, 9, 9, nil, 9, + 9, 9, 9, 9, 9, 9, nil, nil, 9, 9, + nil, nil, nil, 9, 9, 9, 9, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 9, 9, nil, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, nil, nil, 9, 9, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 9, 375, + 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, + 375, 375, 375, 375, 375, 375, 375, 375, 375, 375, + 375, 375, 375, nil, nil, nil, 375, 375, 375, 375, + 375, 375, 375, 375, 375, 375, nil, nil, nil, nil, + nil, 375, 375, 375, 375, 375, 375, 375, 375, 375, + nil, nil, 375, nil, nil, nil, nil, nil, nil, nil, + 375, 375, nil, 375, 375, 375, 375, 375, 375, 375, + nil, nil, 375, 375, nil, nil, nil, 375, 375, 375, + 375, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 375, 375, nil, 375, 375, 375, + 375, 375, 375, 375, 375, 375, 375, 375, nil, nil, + 375, 375, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 375, 560, 560, 560, 560, 560, 560, 560, + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, + 560, 560, 560, 560, 560, 560, 560, nil, nil, nil, + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, + nil, nil, nil, nil, nil, 560, 560, 560, 560, 560, + 560, 560, 560, 560, nil, nil, 560, nil, nil, nil, + nil, nil, nil, nil, 560, 560, nil, 560, 560, 560, + 560, 560, 560, 560, nil, nil, 560, 560, nil, nil, + nil, 560, 560, 560, 560, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 560, 560, + nil, 560, 560, 560, 560, 560, 560, 560, 560, 560, + 560, 560, nil, nil, 560, 560, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 560, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, nil, nil, nil, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, nil, nil, nil, nil, nil, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, nil, 66, nil, nil, nil, nil, nil, 66, 66, + nil, 66, 66, 66, 66, 66, 66, 66, nil, nil, + 66, 66, nil, nil, nil, 66, 66, 66, 66, nil, + nil, nil, nil, nil, 66, nil, nil, nil, nil, nil, + nil, nil, 66, 66, nil, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, nil, nil, 66, 690, + 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, + 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, + 690, 690, 690, nil, nil, nil, 690, 690, 690, 690, + 690, 690, 690, 690, 690, 690, nil, nil, nil, nil, + nil, 690, 690, 690, 690, 690, 690, 690, 690, 690, + nil, nil, 690, nil, nil, nil, nil, nil, nil, nil, + 690, 690, nil, 690, 690, 690, 690, 690, 690, 690, + nil, nil, 690, 690, nil, nil, nil, 690, 690, 690, + 690, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 690, 690, nil, 690, 690, 690, + 690, 690, 690, 690, 690, 690, 690, 690, 203, 203, + 690, nil, 203, nil, nil, nil, nil, nil, nil, nil, + 203, 203, nil, 203, 203, 203, 203, 203, 203, 203, + nil, nil, 203, 203, nil, nil, nil, 203, 203, 203, + 203, nil, nil, nil, nil, nil, 203, nil, nil, nil, + nil, nil, nil, nil, 203, 203, nil, 203, 203, 203, + 203, 203, 203, 203, 203, 203, 203, 203, 249, 249, + 203, nil, 249, nil, nil, nil, nil, nil, nil, nil, + 249, 249, nil, 249, 249, 249, 249, 249, 249, 249, + nil, nil, 249, 249, nil, nil, nil, 249, 249, 249, + 249, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 249, 249, nil, 249, 249, 249, + 249, 249, 249, 249, 249, 249, 249, 249, 250, 250, + 249, nil, 250, nil, nil, nil, nil, nil, nil, nil, + 250, 250, nil, 250, 250, 250, 250, 250, 250, 250, + nil, nil, 250, 250, nil, nil, nil, 250, 250, 250, + 250, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 250, 250, nil, 250, 250, 250, + 250, 250, 250, 250, 250, 250, 250, 250, 415, 415, + 250, nil, 415, nil, nil, nil, nil, nil, nil, nil, + 415, 415, nil, 415, 415, 415, 415, 415, 415, 415, + nil, nil, 415, 415, nil, nil, nil, 415, 415, 415, + 415, nil, nil, nil, nil, nil, 415, nil, nil, nil, + nil, nil, nil, nil, 415, 415, nil, 415, 415, 415, + 415, 415, 415, 415, 415, 415, 415, 415, 416, 416, + 415, nil, 416, nil, nil, nil, nil, nil, nil, nil, + 416, 416, nil, 416, 416, 416, 416, 416, 416, 416, + nil, nil, 416, 416, nil, nil, nil, 416, 416, 416, + 416, nil, nil, nil, nil, nil, 416, nil, nil, nil, + nil, nil, nil, nil, 416, 416, nil, 416, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, 482, 482, + 416, nil, 482, nil, nil, nil, nil, nil, nil, nil, + 482, 482, nil, 482, 482, 482, 482, 482, 482, 482, + nil, nil, 482, 482, nil, nil, nil, 482, 482, 482, + 482, nil, nil, nil, nil, nil, 482, nil, nil, nil, + nil, nil, nil, nil, 482, 482, nil, 482, 482, 482, + 482, 482, 482, 482, 482, 482, 482, 482, 483, 483, + 482, nil, 483, nil, nil, nil, nil, nil, nil, nil, + 483, 483, nil, 483, 483, 483, 483, 483, 483, 483, + nil, nil, 483, 483, nil, nil, nil, 483, 483, 483, + 483, nil, nil, nil, nil, nil, 483, nil, nil, nil, + nil, nil, nil, nil, 483, 483, nil, 483, 483, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 494, 494, + 483, nil, 494, nil, nil, nil, nil, nil, nil, nil, + 494, 494, nil, 494, 494, 494, 494, 494, 494, 494, + nil, nil, 494, 494, nil, nil, nil, 494, 494, 494, + 494, nil, nil, nil, nil, nil, 494, nil, nil, nil, + nil, nil, nil, nil, 494, 494, nil, 494, 494, 494, + 494, 494, 494, 494, 494, 494, 494, 494, 495, 495, + 494, nil, 495, nil, nil, nil, nil, nil, nil, nil, + 495, 495, nil, 495, 495, 495, 495, 495, 495, 495, + nil, nil, 495, 495, nil, nil, nil, 495, 495, 495, + 495, nil, nil, nil, nil, nil, 495, nil, nil, nil, + nil, nil, nil, nil, 495, 495, nil, 495, 495, 495, + 495, 495, 495, 495, 495, 495, 495, 495, 522, 522, + 495, nil, 522, nil, nil, nil, nil, nil, nil, nil, + 522, 522, nil, 522, 522, 522, 522, 522, 522, 522, + nil, nil, 522, 522, nil, nil, nil, 522, 522, 522, + 522, nil, nil, nil, nil, nil, 522, nil, nil, nil, + nil, nil, nil, nil, 522, 522, nil, 522, 522, 522, + 522, 522, 522, 522, 522, 522, 522, 522, 523, 523, + 522, nil, 523, nil, nil, nil, nil, nil, nil, nil, + 523, 523, nil, 523, 523, 523, 523, 523, 523, 523, + nil, nil, 523, 523, nil, nil, nil, 523, 523, 523, + 523, nil, nil, nil, nil, nil, 523, nil, nil, nil, + nil, nil, nil, nil, 523, 523, nil, 523, 523, 523, + 523, 523, 523, 523, 523, 523, 523, 523, 529, 529, + 523, nil, 529, nil, nil, nil, nil, nil, nil, nil, + 529, 529, nil, 529, 529, 529, 529, 529, 529, 529, + nil, nil, 529, 529, nil, nil, nil, 529, 529, 529, + 529, nil, nil, nil, nil, nil, 529, nil, nil, nil, + nil, nil, nil, nil, 529, 529, nil, 529, 529, 529, + 529, 529, 529, 529, 529, 529, 529, 529, 530, 530, + 529, nil, 530, nil, nil, nil, nil, nil, nil, nil, + 530, 530, nil, 530, 530, 530, 530, 530, 530, 530, + nil, nil, 530, 530, nil, nil, nil, 530, 530, 530, + 530, nil, nil, nil, nil, nil, 530, nil, nil, nil, + nil, nil, nil, nil, 530, 530, nil, 530, 530, 530, + 530, 530, 530, 530, 530, 530, 530, 530, 884, 884, + 530, nil, 884, nil, nil, nil, nil, nil, nil, nil, + 884, 884, nil, 884, 884, 884, 884, 884, 884, 884, + nil, nil, 884, 884, nil, nil, nil, 884, 884, 884, + 884, nil, nil, nil, nil, nil, 884, nil, nil, nil, + nil, nil, nil, nil, 884, 884, nil, 884, 884, 884, + 884, 884, 884, 884, 884, 884, 884, 884, 885, 885, + 884, nil, 885, nil, nil, nil, nil, nil, nil, nil, + 885, 885, nil, 885, 885, 885, 885, 885, 885, 885, + nil, nil, 885, 885, nil, nil, nil, 885, 885, 885, + 885, nil, nil, nil, nil, nil, 885, nil, nil, nil, + nil, nil, nil, nil, 885, 885, nil, 885, 885, 885, + 885, 885, 885, 885, 885, 885, 885, 885, 922, 922, + 885, nil, 922, nil, nil, nil, nil, nil, nil, nil, + 922, 922, nil, 922, 922, 922, 922, 922, 922, 922, + nil, nil, 922, 922, nil, nil, nil, 922, 922, 922, + 922, nil, nil, nil, nil, nil, 922, nil, nil, nil, + nil, nil, nil, nil, 922, 922, nil, 922, 922, 922, + 922, 922, 922, 922, 922, 922, 922, 922, nil, nil, + 922, 496, 496, 496, 496, 496, 496, 496, 496, 496, + 496, 496, nil, 496, 496, nil, nil, 496, 496, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 496, nil, 496, nil, 496, 496, 496, + 496, 496, 496, 496, nil, 496, nil, 625, 625, 625, + 625, 625, 625, 625, 625, 625, 625, 625, nil, 625, + 625, nil, 496, 625, 625, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 625, + nil, 625, nil, 625, 625, 625, 625, 625, 625, 625, + nil, 625, nil, 703, 703, 703, 703, 703, 703, 703, + 703, 703, 703, 703, nil, 703, 703, nil, 625, 703, + 703, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 703, nil, 703, nil, 703, + 703, 703, 703, 703, 703, 703, nil, 703, nil, 706, + 706, 706, 706, 706, 706, 706, 706, 706, 706, 706, + nil, 706, 706, nil, 703, 706, 706, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 706, nil, 706, nil, 706, 706, 706, 706, 706, + 706, 706, nil, 706, nil, 710, 710, 710, 710, 710, + 710, 710, 710, 710, 710, 710, nil, 710, 710, nil, + 706, 710, 710, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 710, nil, 710, + nil, 710, 710, 710, 710, 710, 710, 710, nil, 710, + nil, 712, 712, 712, 712, 712, 712, 712, 712, 712, + 712, 712, nil, 712, 712, nil, 710, 712, 712, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 712, nil, 712, nil, 712, 712, 712, + 712, 712, 712, 712, nil, 712, nil, 715, 715, 715, + 715, 715, 715, 715, 715, 715, 715, 715, nil, 715, + 715, nil, 712, 715, 715, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 715, + nil, 715, nil, 715, 715, 715, 715, 715, 715, 715, + nil, 715, nil, 717, 717, 717, 717, 717, 717, 717, + 717, 717, 717, 717, nil, 717, 717, nil, 715, 717, + 717, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 717, nil, 717, nil, 717, + 717, 717, 717, 717, 717, 717, nil, 717, nil, 802, + 802, 802, 802, 802, 802, 802, 802, 802, 802, 802, + nil, 802, 802, nil, 717, 802, 802, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 802, nil, 802, nil, 802, 802, 802, 802, 802, + 802, 802, nil, 802, nil, 804, 804, 804, 804, 804, + 804, 804, 804, 804, 804, 804, nil, 804, 804, nil, + 802, 804, 804, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 804, nil, 804, + nil, 804, 804, 804, 804, 804, 804, 804, nil, 804, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 804 ] + +racc_action_pointer = [ + 0, 80, nil, 62, nil, 4744, 1499, 10, 21299, 21423, + 39, 29, 57, 133, 607, 55, 345, nil, 29, 4869, + 7135, 202, nil, 294, 249, 20787, 20896, 4994, 5119, 5244, + nil, 738, 5369, 5494, nil, 114, 240, 229, 403, 5627, + 5752, 5877, 176, 611, nil, nil, nil, nil, nil, nil, + nil, 866, 999, 6002, 6127, 6252, 0, nil, 6377, 6502, + nil, nil, 6627, 6760, 6885, 7010, 21795, nil, nil, nil, + nil, nil, nil, nil, 342, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 0, nil, nil, + 130, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 328, nil, 7135, nil, nil, nil, nil, 7268, 7393, + 7518, 7643, 7768, 1124, nil, 449, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 265, nil, 1249, 7893, 8018, + 8143, 8268, 21167, 21967, 8393, 8518, 8643, 8768, 8893, nil, + nil, 738, 54, 356, 109, 298, 351, nil, 9018, 1374, + 360, 9143, 9268, 9393, 9518, 9643, 9768, 9893, 10018, 10143, + 10268, 10393, 10518, 10643, 10768, 10893, 11018, 11143, 11268, 11393, + 11518, 11643, 11768, 11893, 12018, 12143, 12268, nil, nil, 22027, + 22087, 421, 12393, 12518, nil, nil, nil, nil, nil, nil, + nil, 12643, nil, 13268, nil, 409, 443, nil, 12768, 506, + 12893, nil, 13018, nil, nil, 537, 1527, 13143, 479, 1499, + 512, 569, 554, 13268, 1624, 741, 784, 637, 874, nil, + 605, 576, 261, nil, nil, nil, 623, 500, 585, 13401, + nil, 478, 650, 658, 898, nil, 661, nil, 13526, 730, + 738, 590, nil, 34, 254, 656, 650, 284, 690, nil, + nil, 600, 48, 136, 13651, 13776, 620, 768, 663, 65, + 903, 743, 89, 804, nil, nil, 351, 442, 96, nil, + 931, nil, 55, 13901, nil, nil, 309, 407, 434, 453, + 572, 576, 641, 649, 651, nil, 668, nil, 14026, nil, + 274, 348, 382, 401, 39, 468, nil, nil, nil, nil, + nil, nil, nil, nil, 725, 21547, nil, nil, nil, nil, + 748, nil, nil, 738, nil, 14151, 735, nil, 740, nil, + nil, 1624, 745, nil, 512, 519, 21005, nil, nil, nil, + 239, 348, 787, nil, nil, 1752, 1861, nil, 15276, nil, + nil, nil, 174, nil, 798, 22147, 22207, 14276, 244, 14401, + 14526, 14651, 1994, 2119, 431, 559, 823, 824, 833, 834, + 1499, 3619, 3744, 2244, 1810, 2369, 2494, 2619, 2744, 2869, + 2994, 3119, 3244, 530, 793, 3369, 3494, 20659, 79, 21114, + nil, nil, 21169, nil, nil, 775, nil, nil, 14776, 117, + 175, 778, nil, nil, 14901, nil, 15026, nil, 15151, nil, + nil, nil, 15276, 1609, 785, 788, nil, nil, 792, 15409, + 805, 15534, 22267, 22327, 1002, 857, nil, nil, 15659, 823, + nil, 15784, 15909, 16034, 22387, 22447, 22915, 16159, 940, 16284, + nil, 829, nil, 16409, nil, nil, 16534, nil, nil, nil, + nil, 830, 1994, 949, nil, 2119, 119, 142, 947, 956, + 16659, 16784, 22507, 22567, 98, nil, nil, 1004, nil, 22627, + 22687, 16909, nil, nil, 17034, 693, 146, 2244, 1716, nil, + nil, nil, 283, nil, nil, nil, 721, nil, nil, nil, + 859, nil, nil, 465, nil, nil, 849, nil, nil, nil, + 21671, nil, 17159, 852, 17284, 17409, 523, 889, 17534, 17659, + 888, nil, nil, 17784, 17909, 889, nil, nil, nil, 277, + 353, 473, 603, 860, 5494, 860, nil, 567, nil, 2369, + nil, nil, nil, nil, 293, nil, 6627, -6, 860, nil, + 864, nil, 2494, 2619, nil, 869, nil, 919, 18034, nil, + nil, 1742, 453, 18159, 878, nil, 885, 125, 198, 923, + 443, 1129, 924, 894, 18284, 22961, 959, 960, 317, 1019, + nil, 2744, 906, 958, nil, nil, nil, 468, 108, 666, + nil, 926, 930, 937, nil, nil, nil, nil, nil, nil, + 272, 1029, nil, 985, nil, nil, nil, nil, 1032, nil, + nil, 1034, 637, nil, 1075, nil, nil, nil, nil, 1083, + nil, 140, 967, 135, 141, 263, 269, 18409, 481, 1254, + nil, 972, 2869, 701, nil, nil, 1090, 2994, 5382, 725, + 21907, nil, nil, nil, nil, nil, nil, 3119, nil, nil, + nil, nil, nil, 23007, 981, 18534, 23053, 18659, nil, nil, + 23099, nil, 23145, nil, nil, 23191, nil, 23237, nil, 18784, + 18909, 19034, 19159, 386, 19284, 983, 988, 993, nil, 1024, + 1005, 1360, 312, nil, 1128, 3244, 19409, nil, nil, 1014, + 1036, 1142, nil, 19534, nil, 1023, 352, nil, nil, nil, + 3369, nil, nil, 163, 19659, nil, nil, nil, nil, nil, + 1029, 6773, nil, 6898, nil, nil, 1021, 1129, 19784, nil, + nil, 1014, nil, 1055, 349, 1104, 1079, nil, nil, 1199, + nil, 19909, 1201, 3494, 3619, nil, 20034, 3744, 156, 205, + nil, 1205, nil, 3869, nil, 1208, 1097, nil, nil, 1112, + 1106, nil, 23283, 20159, 23329, 7023, nil, 13414, nil, nil, + 1050, nil, 1128, 1108, nil, nil, nil, 20284, nil, 1130, + 1118, nil, 1128, nil, nil, nil, 1132, nil, 3994, 1127, + 1252, 1207, 1255, nil, 4119, 4244, 1139, 1144, 1147, nil, + nil, 1148, 1156, nil, 1166, nil, nil, 1179, 1110, 1180, + 859, nil, nil, 164, nil, 1307, 1321, nil, 287, nil, + nil, 1324, nil, nil, 15422, nil, 1206, 1213, 1220, 1231, + nil, 1232, nil, 1389, 1364, 1307, nil, nil, 20409, nil, + nil, 20534, 1360, 20659, 22747, 22807, 1377, 1260, 1373, nil, + 15672, nil, nil, 1146, nil, 1175, nil, 1271, nil, nil, + nil, 439, 869, 1257, 4369, nil, nil, nil, nil, nil, + 4494, nil, 4619, 18172, nil, nil, 1300, nil, 1396, nil, + nil, nil, 22867, nil, 1258, nil, 1264, 165, 166, 209, + 1379, nil, nil, 1269, 1272, 1273, 1281, 1287, 1139, 1291, + 1235, 836, 1421, 1425, 1316, 1326, 1329, 1331, 1375, 1378, + nil, 173, nil, 1425, nil, nil, nil, 1264, 1344, nil, + nil, nil, nil, 1521, nil, nil, nil, 1345, 1348, 1356, + nil, nil ] + +racc_action_default = [ + -3, -557, -1, -543, -4, -557, -7, -557, -557, -557, + -557, -557, -557, -557, -557, -280, -39, -40, -545, -557, + -45, -47, -48, -49, -255, -255, -255, -290, -326, -327, + -65, -11, -69, -77, -79, -557, -472, -557, -557, -557, + -557, -557, -545, -232, -273, -274, -275, -276, -277, -278, + -279, -533, -11, -557, -556, -525, -298, -300, -557, -557, + -304, -307, -543, -557, -557, -557, -557, -328, -329, -331, + -332, -421, -422, -423, -424, -425, -440, -428, -429, -442, + -444, -433, -438, -454, -442, -456, -457, -531, -461, -462, + -532, -464, -465, -466, -467, -468, -469, -470, -471, -474, + -475, -557, -2, -544, -552, -553, -554, -6, -557, -557, + -557, -557, -557, -3, -15, -557, -106, -107, -108, -109, + -110, -111, -112, -113, -114, -118, -119, -120, -121, -122, + -123, -124, -125, -126, -127, -128, -129, -130, -131, -132, + -133, -134, -135, -136, -137, -138, -139, -140, -141, -142, + -143, -144, -145, -146, -147, -148, -149, -150, -151, -152, + -153, -154, -155, -156, -157, -158, -159, -160, -161, -162, + -163, -164, -165, -166, -167, -168, -169, -170, -171, -172, + -173, -174, -175, -176, -177, -178, -179, -180, -181, -182, + -183, -184, -185, -186, -187, -20, -115, -11, -557, -557, + -557, -241, -557, -557, -557, -557, -557, -557, -545, -546, + -44, -557, -472, -557, -280, -557, -557, -224, -557, -11, + -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, + -557, -557, -557, -557, -557, -557, -557, -557, -557, -557, + -557, -557, -557, -557, -557, -557, -557, -391, -393, -557, + -557, -54, -241, -557, -297, -396, -405, -407, -60, -402, + -61, -545, -62, -233, -243, -265, -265, -248, -557, -266, + -557, -527, -557, -63, -64, -543, -12, -557, -67, -11, + -545, -557, -70, -73, -11, -85, -557, -557, -92, -290, + -293, -545, -557, -326, -327, -330, -403, -557, -75, -557, + -81, -287, -458, -459, -557, -209, -210, -225, -557, -413, + -557, -283, -234, -549, -549, -557, -557, -549, -557, -299, + -383, -46, -557, -557, -557, -557, -543, -557, -544, -472, + -557, -557, -280, -557, -342, -343, -101, -102, -557, -104, + -557, -280, -557, -557, -472, -319, -106, -107, -147, -148, + -149, -165, -170, -177, -180, -321, -557, -523, -557, -426, + -557, -557, -557, -557, -557, -557, 972, -5, -555, -21, + -22, -23, -24, -25, -557, -557, -17, -18, -19, -116, + -557, -27, -36, -188, -266, -557, -557, -28, -37, -38, + -29, -190, -545, -242, -534, -535, -255, -400, -536, -537, + -535, -534, -255, -399, -401, -536, -537, -35, -198, -41, + -42, -43, -545, -296, -557, -557, -557, -241, -287, -557, + -557, -557, -199, -200, -201, -202, -203, -204, -205, -206, + -211, -212, -213, -214, -215, -216, -217, -218, -219, -220, + -221, -222, -223, -226, -227, -228, -229, -545, -372, -255, + -534, -535, -255, -52, -55, -545, -256, -257, -258, -372, + -372, -545, -292, -244, -264, -245, -264, -262, -557, -267, + -530, -10, -544, -14, -545, -66, -285, -82, -71, -557, + -545, -241, -557, -557, -91, -557, -458, -459, -557, -78, + -83, -557, -557, -557, -557, -557, -230, -557, -556, -556, + -282, -545, -235, -551, -550, -237, -551, -288, -289, -526, + -301, -495, -11, -333, -334, -11, -557, -557, -557, -557, + -557, -241, -557, -557, -287, -312, -101, -102, -103, -557, + -557, -241, -315, -476, -557, -557, -557, -11, -495, -323, + -541, -542, -545, -427, -441, -446, -557, -448, -430, -443, + -557, -445, -432, -557, -435, -437, -557, -455, -8, -16, + -557, -26, -557, -272, -557, -557, -404, -557, -557, -557, + -56, -240, -397, -557, -557, -58, -398, -295, -547, -534, + -535, -534, -535, -545, -188, -557, -373, -377, -375, -11, + -50, -394, -51, -395, -372, -238, -45, -557, -265, -254, + -545, -260, -11, -11, -291, -265, -263, -268, -557, -528, + -529, -13, -68, -557, -74, -80, -545, -534, -535, -239, + -88, -90, -557, -76, -557, -197, -207, -208, -545, -556, + -340, -11, -414, -556, -415, -416, -284, -549, -557, -495, + -386, -522, -522, -522, -494, -496, -497, -498, -499, -500, + -501, -557, -504, -557, -506, -512, -514, -515, -517, -518, + -519, -557, -556, -335, -556, -305, -336, -337, -308, -557, + -311, -557, -545, -534, -535, -538, -286, -557, -101, -102, + -105, -545, -11, -557, -478, -317, -557, -11, -495, -557, + -557, -524, -447, -450, -451, -452, -453, -11, -431, -434, + -436, -439, -117, -189, -270, -557, -191, -557, -548, -31, + -193, -32, -194, -57, -33, -196, -34, -195, -59, -557, + -557, -557, -557, -404, -557, -522, -522, -522, -371, -557, + -377, -557, -501, -510, -557, -11, -557, -251, -259, -545, + -557, -557, -246, -264, -269, -72, -86, -84, -294, -9, + -11, -420, -341, -557, -557, -418, -236, -384, -387, -389, + -377, -557, -487, -557, -490, -492, -557, -557, -557, -503, + -344, -557, -346, -348, -355, -501, -545, -516, -520, -557, + -338, -557, -557, -11, -11, -310, -557, -11, -404, -557, + -404, -557, -477, -11, -320, -557, -545, -480, -324, -557, + -271, -30, -192, -557, -231, -362, -364, -557, -367, -369, + -557, -374, -557, -378, -379, -381, -382, -557, -392, -557, + -265, -250, -265, -261, -406, -408, -265, -419, -11, -93, + -557, -557, -100, -417, -11, -11, -545, -522, -522, -507, + -521, -522, -522, -513, -522, -502, -508, -545, -557, -353, + -557, -505, -302, -557, -303, -557, -557, -268, -556, -313, + -316, -557, -322, -479, -495, -449, -522, -522, -522, -522, + -511, -522, -376, -557, -509, -557, -53, -249, -264, -252, + -247, -264, -413, -241, -557, -557, -99, -557, -557, -385, + -557, -483, -485, -557, -488, -557, -491, -557, -493, -345, + -347, -351, -557, -356, -11, -306, -309, -409, -410, -411, + -11, -318, -11, -557, -359, -361, -557, -365, -557, -368, + -370, -380, -557, -287, -265, -412, -545, -534, -535, -538, + -98, -388, -390, -522, -522, -522, -522, -349, -557, -354, + -557, -556, -557, -557, -522, -522, -522, -522, -286, -538, + -253, -404, -481, -557, -484, -486, -489, -557, -352, -339, + -314, -325, -357, -557, -360, -363, -366, -522, -350, -522, + -482, -358 ] + +racc_goto_table = [ + 119, 119, 207, 392, 355, 11, 210, 313, 498, 629, + 11, 314, 317, 519, 687, 310, 489, 13, 454, 566, + 295, 295, 13, 103, 396, 402, 308, 779, 102, 264, + 264, 264, 727, 106, 640, 282, 11, 512, 515, 726, + 609, 463, 465, 114, 196, 278, 644, 312, 13, 382, + 389, 295, 295, 295, 455, 6, 729, 11, 119, 281, + 6, 322, 323, 122, 122, 326, 124, 124, 334, 13, + 298, 449, 452, 644, 502, 505, 280, 528, 509, 814, + 609, 255, 259, 251, 258, 260, 816, 327, 665, 668, + 599, 839, 106, 843, 776, 870, 606, 900, 606, 107, + 262, 273, 274, 2, 544, 361, 551, 554, 11, 1, + 365, 369, 370, 371, 372, 589, 749, 11, 11, 903, + 13, 591, 728, 195, 593, 335, 602, 603, 375, 13, + 13, 342, 345, 594, 560, 839, 315, 601, 456, 600, + 739, 357, 316, 319, 510, 333, 532, 356, 539, 501, + 320, 386, 386, 324, 783, 325, 784, 677, 6, 910, + 682, 793, 760, 537, 538, 690, 864, 373, 6, 730, + 813, 939, 638, 757, 644, 782, 511, 248, 834, 835, + 448, 459, 460, 907, 633, 381, 387, 390, 753, 900, + 359, 407, 360, 362, 363, 406, 614, 367, 553, 812, + 364, 870, 11, 264, 669, 623, 838, 958, 841, 692, + 723, 796, 847, 697, 13, 837, 374, nil, nil, 583, + 843, 921, nil, 644, 11, 380, 968, 839, 816, 836, + nil, nil, nil, nil, nil, nil, 13, 396, 402, nil, + nil, nil, nil, 746, nil, nil, nil, 281, nil, nil, + 867, nil, 868, nil, 264, 264, nil, 866, nil, 397, + nil, 735, nil, 264, nil, nil, nil, nil, 680, nil, + nil, 295, nil, nil, nil, 485, nil, nil, nil, nil, + nil, nil, 11, 616, 11, nil, nil, 295, nil, 11, + nil, nil, nil, 278, 13, 472, 13, 700, 278, 788, + 471, 13, 490, nil, 619, 106, 959, 281, 790, nil, + nil, nil, 281, nil, nil, nil, 619, 609, nil, nil, + 478, 318, nil, 672, 474, nil, 457, 516, 517, 480, + 745, nil, 473, 681, 461, 933, nil, 713, nil, nil, + 912, nil, 718, nil, 619, nil, nil, nil, nil, 255, + 634, 518, 619, 259, nil, nil, 106, nil, 944, nil, + nil, 859, nil, nil, nil, nil, nil, 119, 821, 908, + nil, nil, 533, nil, 737, 606, 567, nil, nil, nil, + nil, 742, nil, nil, nil, 14, 787, nil, nil, nil, + 14, nil, nil, nil, nil, nil, nil, nil, 756, 644, + nil, nil, nil, nil, 211, nil, nil, nil, 406, nil, + 559, nil, 211, 211, 211, 598, 14, 286, 286, 264, + nil, 605, nil, nil, nil, nil, nil, nil, nil, nil, + 122, 585, nil, 124, nil, nil, nil, 14, 211, nil, + nil, nil, nil, 211, 211, nil, nil, 211, 330, 340, + 340, nil, 386, 571, nil, 570, nil, nil, nil, 576, + 637, 575, nil, nil, 384, 388, nil, 295, 828, nil, + nil, nil, 397, 671, nil, 406, 295, 11, nil, nil, + nil, nil, 490, 264, nil, nil, nil, 406, 14, 13, + nil, 490, 635, 211, 211, 211, 211, 14, 14, nil, + 686, nil, nil, nil, nil, nil, 571, nil, 590, 571, + 606, 592, nil, 606, nil, 406, nil, 11, nil, nil, + 11, 406, nil, 264, nil, nil, nil, 611, nil, 13, + nil, nil, 13, 264, 467, nil, 469, 683, 470, 397, + 662, nil, 11, 664, 909, nil, 666, 666, nil, nil, + nil, 397, 119, 951, 13, 709, 711, nil, nil, nil, + 714, 716, nil, nil, nil, 684, 685, 567, 904, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 397, + nil, 925, 14, 211, 211, 211, 211, 397, nil, 211, + 211, 211, 211, 211, 11, 702, 877, nil, 879, nil, + 567, 295, 880, nil, 14, nil, 13, 11, 11, 15, + nil, nil, 295, nil, 15, 122, 490, 734, 124, 13, + 13, nil, 751, nil, nil, nil, 755, 747, 798, nil, + 740, 741, nil, nil, nil, nil, 11, 211, 211, nil, + 15, 288, 288, nil, nil, 791, 211, nil, 13, nil, + 795, 563, nil, nil, nil, nil, 567, nil, nil, 752, + nil, 15, 14, nil, 14, 567, nil, nil, 286, 14, + nil, nil, 332, 341, 341, nil, 571, nil, nil, 576, + 789, nil, 119, nil, 286, 926, nil, 11, nil, 820, + nil, nil, 11, 822, 801, nil, 826, nil, nil, 13, + 950, nil, 11, nil, 13, nil, 619, nil, nil, 211, + 211, nil, 15, 792, 13, nil, nil, nil, nil, 797, + 725, 15, 15, nil, 597, 799, nil, nil, 211, nil, + 607, nil, 318, nil, 610, nil, nil, nil, nil, nil, + 11, nil, 295, 211, nil, nil, nil, nil, nil, nil, + nil, nil, 13, nil, nil, 11, 861, nil, nil, 833, + nil, nil, nil, 819, nil, 632, nil, 13, nil, 607, + nil, nil, 318, 770, nil, nil, nil, nil, 827, nil, + nil, nil, nil, nil, 853, nil, 384, nil, 11, 11, + nil, nil, 11, nil, nil, nil, nil, 413, 11, nil, + 13, 13, 211, nil, 13, 295, 15, nil, nil, nil, + 13, 855, 856, nil, nil, 858, nil, nil, nil, 666, + nil, nil, nil, nil, nil, nil, nil, nil, 15, nil, + 704, nil, nil, 11, nil, 924, nil, nil, nil, 11, + 11, nil, nil, 211, nil, 13, nil, nil, nil, nil, + 462, 13, 13, nil, nil, nil, 882, 14, nil, nil, + nil, nil, 887, 888, 286, nil, 211, nil, nil, 475, + nil, nil, nil, 286, 744, 943, nil, 406, nil, nil, + nil, nil, 211, nil, nil, 264, 15, nil, 15, nil, + nil, 770, 288, 15, 849, nil, 842, 14, nil, 844, + 14, nil, nil, nil, nil, nil, 211, nil, 288, 11, + 567, nil, nil, nil, 406, 11, 211, 11, nil, 211, + nil, 13, 14, nil, nil, nil, nil, 13, nil, 13, + nil, nil, 941, nil, nil, nil, nil, nil, 942, nil, + 869, 397, nil, 871, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 211, 211, nil, nil, 311, 211, 211, + nil, nil, 321, 321, nil, nil, 321, nil, 770, nil, + 770, 800, nil, nil, 14, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 14, 14, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 286, nil, + nil, 577, nil, nil, nil, nil, nil, nil, nil, 286, + nil, nil, 321, 321, 321, 321, 14, nil, nil, nil, + nil, 937, 770, 934, nil, nil, 935, nil, 936, nil, + nil, nil, nil, nil, 846, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 595, nil, 945, nil, nil, 946, + 604, 947, 857, nil, nil, nil, nil, nil, 770, nil, + 770, nil, 211, 612, nil, nil, nil, 14, nil, 615, + nil, nil, 14, nil, 24, nil, nil, 770, nil, 24, + nil, 15, 14, nil, nil, nil, 967, nil, 288, nil, + 636, nil, 211, 24, nil, nil, 969, 288, nil, nil, + nil, 24, 24, 24, nil, 24, nil, nil, nil, 409, + 410, 411, 412, nil, nil, nil, nil, nil, nil, nil, + 14, 15, nil, nil, 15, nil, 24, 24, nil, nil, + nil, 691, 24, 24, nil, 14, 24, nil, nil, 830, + nil, nil, nil, nil, 607, nil, 15, 857, nil, nil, + nil, nil, nil, nil, nil, 696, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 211, nil, 14, 14, + nil, nil, 14, nil, nil, nil, nil, 24, 14, nil, + nil, nil, 24, 24, 24, 24, 24, 24, nil, 738, + nil, nil, nil, nil, nil, nil, nil, nil, 15, nil, + nil, nil, 874, nil, nil, nil, nil, nil, nil, nil, + nil, 15, 15, 14, nil, nil, nil, 748, nil, 14, + 14, nil, 288, nil, nil, nil, nil, nil, 321, 321, + nil, nil, nil, 288, nil, nil, nil, nil, nil, nil, + 15, nil, nil, nil, nil, nil, nil, 536, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 542, nil, nil, nil, nil, nil, 211, nil, + nil, 24, 24, 24, 24, 24, nil, nil, 24, 24, + 24, 24, 24, nil, nil, nil, nil, nil, nil, 14, + nil, 15, nil, 24, nil, 14, 15, 14, nil, nil, + nil, nil, nil, nil, nil, nil, 15, nil, 36, nil, + nil, nil, nil, 36, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 24, 24, 823, nil, + nil, nil, nil, nil, nil, 24, nil, nil, nil, 36, + 285, 285, nil, nil, 15, nil, nil, nil, nil, nil, + nil, 24, nil, 24, nil, nil, nil, nil, 24, 15, + 36, nil, 311, 832, nil, 851, nil, nil, nil, nil, + nil, 329, 344, 344, 344, nil, 762, 764, 765, nil, + nil, nil, nil, nil, nil, 863, nil, nil, nil, nil, + nil, nil, 15, 15, nil, nil, 15, nil, 24, 24, + nil, 628, 15, nil, nil, nil, nil, nil, nil, nil, + nil, 36, nil, nil, nil, nil, nil, 24, nil, nil, + 36, 36, nil, nil, nil, 889, 341, nil, nil, nil, + nil, nil, 24, nil, nil, nil, 899, 15, 321, nil, + nil, nil, nil, 15, 15, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 806, 808, 809, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 24, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 36, nil, nil, nil, nil, + nil, nil, nil, 15, nil, nil, nil, nil, nil, 15, + nil, 15, nil, nil, nil, nil, nil, 36, nil, nil, + nil, nil, 24, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 24, nil, nil, nil, + nil, nil, nil, nil, nil, 24, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 24, 891, 892, nil, nil, 894, 896, nil, 898, + nil, 321, nil, nil, nil, 36, 24, 36, nil, 24, + nil, 285, 36, nil, nil, 24, nil, nil, nil, nil, + nil, 914, 915, 917, 919, 24, 920, 285, 24, nil, + nil, 24, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 24, 24, nil, nil, nil, 24, 24, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 24, nil, nil, nil, nil, 952, 954, + 955, 956, nil, nil, nil, nil, 24, 24, nil, 962, + 964, 965, 966, nil, nil, 321, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 970, nil, 971, 24, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 24, nil, nil, nil, nil, 24, nil, nil, nil, + nil, 24, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 24, nil, nil, nil, nil, nil, nil, nil, nil, + 36, 24, nil, nil, nil, nil, nil, 285, nil, nil, + nil, nil, nil, nil, nil, nil, 285, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 24, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 36, nil, nil, 36, 24, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 36, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 24, nil, 24, 24, nil, + nil, 24, nil, nil, nil, nil, nil, 24, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 36, nil, nil, + nil, nil, 24, nil, nil, nil, nil, nil, 24, 24, + 36, 36, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 285, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 285, nil, nil, nil, nil, nil, nil, 36, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 217, nil, nil, nil, nil, 24, nil, nil, + 263, 263, 263, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 305, 306, 307, nil, nil, nil, 24, nil, + nil, nil, nil, nil, 24, nil, 24, 263, 263, nil, + 36, nil, nil, nil, nil, 36, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 36, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 36, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 36, nil, + nil, nil, 829, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 36, 36, nil, nil, 36, nil, nil, nil, nil, + nil, 36, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 344, nil, nil, nil, nil, + nil, 383, 263, 391, 263, nil, 36, 408, nil, nil, + nil, nil, 36, 36, nil, nil, nil, nil, nil, nil, + nil, 217, nil, nil, 422, 423, 424, 425, 426, 427, + 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, + 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, + nil, nil, nil, nil, nil, 263, 263, nil, nil, nil, + nil, nil, nil, nil, 263, nil, nil, nil, nil, nil, + nil, 263, nil, 263, nil, 263, nil, nil, nil, nil, + nil, nil, 36, nil, nil, nil, nil, nil, 36, nil, + 36, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 496, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 263, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 263, nil, 408, 584, 391, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 596, nil, nil, nil, nil, nil, 263, nil, 263, + nil, 263, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 263, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 625, 626, 627, nil, nil, nil, + nil, nil, 263, nil, nil, nil, 263, nil, nil, 263, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 263, 263, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 263, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 703, nil, 263, 706, nil, + nil, 710, 712, nil, nil, nil, 715, 717, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 263, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 263, nil, + 802, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 710, 712, 717, 715, nil, 804, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 263, + nil, nil, nil, nil, nil, nil, 263, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 263, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 263, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 802, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 263, nil, nil, 263, nil, 263 ] + +racc_goto_check = [ + 52, 52, 29, 22, 51, 17, 18, 61, 10, 11, + 17, 63, 63, 87, 93, 8, 47, 20, 36, 23, + 58, 58, 20, 6, 34, 34, 29, 85, 4, 31, + 31, 31, 117, 91, 128, 45, 17, 84, 84, 116, + 157, 66, 66, 14, 14, 41, 119, 60, 20, 25, + 25, 58, 58, 58, 22, 7, 121, 17, 52, 9, + 7, 16, 16, 55, 55, 16, 56, 56, 17, 20, + 46, 34, 34, 119, 62, 62, 42, 49, 62, 123, + 157, 64, 64, 35, 35, 35, 124, 4, 86, 86, + 67, 152, 91, 153, 112, 154, 67, 110, 67, 5, + 40, 40, 40, 2, 147, 143, 147, 147, 17, 1, + 143, 16, 16, 16, 16, 37, 12, 17, 17, 113, + 20, 65, 119, 15, 65, 19, 37, 37, 28, 20, + 20, 50, 50, 38, 57, 152, 59, 68, 69, 71, + 72, 79, 80, 81, 83, 88, 90, 94, 95, 96, + 97, 61, 61, 98, 99, 100, 101, 102, 7, 103, + 104, 105, 128, 106, 107, 108, 109, 7, 7, 114, + 122, 113, 125, 126, 119, 11, 127, 129, 130, 131, + 132, 134, 135, 136, 137, 18, 18, 18, 138, 110, + 141, 18, 142, 144, 145, 52, 47, 5, 146, 121, + 148, 154, 17, 31, 87, 47, 117, 113, 117, 149, + 23, 128, 112, 150, 20, 151, 2, nil, nil, 22, + 153, 123, nil, 119, 17, 9, 113, 152, 124, 121, + nil, nil, nil, nil, nil, nil, 20, 34, 34, nil, + nil, nil, nil, 23, nil, nil, nil, 9, nil, nil, + 117, nil, 117, nil, 31, 31, nil, 116, nil, 64, + nil, 37, nil, 31, nil, nil, nil, nil, 49, nil, + nil, 58, nil, nil, nil, 29, nil, nil, nil, nil, + nil, nil, 17, 22, 17, nil, nil, 58, nil, 17, + nil, nil, nil, 41, 20, 6, 20, 147, 41, 23, + 4, 20, 45, nil, 34, 91, 85, 9, 23, nil, + nil, nil, 9, nil, nil, nil, 34, 157, nil, nil, + 46, 26, nil, 22, 42, nil, 40, 16, 16, 42, + 47, nil, 7, 22, 40, 117, nil, 36, nil, nil, + 93, nil, 36, nil, 34, nil, nil, nil, nil, 64, + 25, 4, 34, 64, nil, nil, 91, nil, 117, nil, + nil, 86, nil, nil, nil, nil, nil, 52, 67, 11, + nil, nil, 91, nil, 66, 67, 29, nil, nil, nil, + nil, 66, nil, nil, nil, 21, 84, nil, nil, nil, + 21, nil, nil, nil, nil, nil, nil, nil, 62, 119, + nil, nil, nil, nil, 21, nil, nil, nil, 52, nil, + 14, nil, 21, 21, 21, 63, 21, 21, 21, 31, + nil, 63, nil, nil, nil, nil, nil, nil, nil, nil, + 55, 29, nil, 56, nil, nil, nil, 21, 21, nil, + nil, nil, nil, 21, 21, nil, nil, 21, 21, 21, + 21, nil, 61, 64, nil, 35, nil, nil, nil, 64, + 63, 35, nil, nil, 26, 26, nil, 58, 84, nil, + nil, nil, 64, 61, nil, 52, 58, 17, nil, nil, + nil, nil, 45, 31, nil, nil, nil, 52, 21, 20, + nil, 45, 60, 21, 21, 21, 21, 21, 21, nil, + 8, nil, nil, nil, nil, nil, 64, nil, 35, 64, + 67, 35, nil, 67, nil, 52, nil, 17, nil, nil, + 17, 52, nil, 31, nil, nil, nil, 7, nil, 20, + nil, nil, 20, 31, 26, nil, 26, 16, 26, 64, + 9, nil, 17, 9, 87, nil, 91, 91, nil, nil, + nil, 64, 52, 23, 20, 18, 18, nil, nil, nil, + 18, 18, nil, nil, nil, 91, 91, 29, 84, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 64, + nil, 10, 21, 21, 21, 21, 21, 64, nil, 21, + 21, 21, 21, 21, 17, 14, 66, nil, 66, nil, + 29, 58, 66, nil, 21, nil, 20, 17, 17, 24, + nil, nil, 58, nil, 24, 55, 45, 9, 56, 20, + 20, nil, 60, nil, nil, nil, 60, 45, 51, nil, + 9, 9, nil, nil, nil, nil, 17, 21, 21, nil, + 24, 24, 24, nil, nil, 8, 21, nil, 20, nil, + 8, 26, nil, nil, nil, nil, 29, nil, nil, 9, + nil, 24, 21, nil, 21, 29, nil, nil, 21, 21, + nil, nil, 24, 24, 24, nil, 64, nil, nil, 64, + 16, nil, 52, nil, 21, 22, nil, 17, nil, 61, + nil, nil, 17, 63, 18, nil, 61, nil, nil, 20, + 66, nil, 17, nil, 20, nil, 34, nil, nil, 21, + 21, nil, 24, 91, 20, nil, nil, nil, nil, 91, + 115, 24, 24, nil, 26, 9, nil, nil, 21, nil, + 26, nil, 26, nil, 26, nil, nil, nil, nil, nil, + 17, nil, 58, 21, nil, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, 17, 8, nil, nil, 17, + nil, nil, nil, 9, nil, 26, nil, 20, nil, 26, + nil, nil, 26, 111, nil, nil, nil, nil, 9, nil, + nil, nil, nil, nil, 16, nil, 26, nil, 17, 17, + nil, nil, 17, nil, nil, nil, nil, 43, 17, nil, + 20, 20, 21, nil, 20, 58, 24, nil, nil, nil, + 20, 9, 9, nil, nil, 9, nil, nil, nil, 91, + nil, nil, nil, nil, nil, nil, nil, nil, 24, nil, + 26, nil, nil, 17, nil, 63, nil, nil, nil, 17, + 17, nil, nil, 21, nil, 20, nil, nil, nil, nil, + 43, 20, 20, nil, nil, nil, 9, 21, nil, nil, + nil, nil, 9, 9, 21, nil, 21, nil, nil, 43, + nil, nil, nil, 21, 26, 8, nil, 52, nil, nil, + nil, nil, 21, nil, nil, 31, 24, nil, 24, nil, + nil, 111, 24, 24, 111, nil, 115, 21, nil, 115, + 21, nil, nil, nil, nil, nil, 21, nil, 24, 17, + 29, nil, nil, nil, 52, 17, 21, 17, nil, 21, + nil, 20, 21, nil, nil, nil, nil, 20, nil, 20, + nil, nil, 9, nil, nil, nil, nil, nil, 9, nil, + 115, 64, nil, 115, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 21, 21, nil, nil, 27, 21, 21, + nil, nil, 27, 27, nil, nil, 27, nil, 111, nil, + 111, 26, nil, nil, 21, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 21, 21, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 21, nil, + nil, 43, nil, nil, nil, nil, nil, nil, nil, 21, + nil, nil, 27, 27, 27, 27, 21, nil, nil, nil, + nil, 111, 111, 115, nil, nil, 115, nil, 115, nil, + nil, nil, nil, nil, 26, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 43, nil, 115, nil, nil, 115, + 43, 115, 26, nil, nil, nil, nil, nil, 111, nil, + 111, nil, 21, 43, nil, nil, nil, 21, nil, 43, + nil, nil, 21, nil, 39, nil, nil, 111, nil, 39, + nil, 24, 21, nil, nil, nil, 115, nil, 24, nil, + 43, nil, 21, 39, nil, nil, 115, 24, nil, nil, + nil, 39, 39, 39, nil, 39, nil, nil, nil, 27, + 27, 27, 27, nil, nil, nil, nil, nil, nil, nil, + 21, 24, nil, nil, 24, nil, 39, 39, nil, nil, + nil, 43, 39, 39, nil, 21, 39, nil, nil, 21, + nil, nil, nil, nil, 26, nil, 24, 26, nil, nil, + nil, nil, nil, nil, nil, 24, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 21, nil, 21, 21, + nil, nil, 21, nil, nil, nil, nil, 39, 21, nil, + nil, nil, 39, 39, 39, 39, 39, 39, nil, 43, + nil, nil, nil, nil, nil, nil, nil, nil, 24, nil, + nil, nil, 21, nil, nil, nil, nil, nil, nil, nil, + nil, 24, 24, 21, nil, nil, nil, 43, nil, 21, + 21, nil, 24, nil, nil, nil, nil, nil, 27, 27, + nil, nil, nil, 24, nil, nil, nil, nil, nil, nil, + 24, nil, nil, nil, nil, nil, nil, 27, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 27, nil, nil, nil, nil, nil, 21, nil, + nil, 39, 39, 39, 39, 39, nil, nil, 39, 39, + 39, 39, 39, nil, nil, nil, nil, nil, nil, 21, + nil, 24, nil, 39, nil, 21, 24, 21, nil, nil, + nil, nil, nil, nil, nil, nil, 24, nil, 48, nil, + nil, nil, nil, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 39, 39, 43, nil, + nil, nil, nil, nil, nil, 39, nil, nil, nil, 48, + 48, 48, nil, nil, 24, nil, nil, nil, nil, nil, + nil, 39, nil, 39, nil, nil, nil, nil, 39, 24, + 48, nil, 27, 24, nil, 43, nil, nil, nil, nil, + nil, 48, 48, 48, 48, nil, 118, 118, 118, nil, + nil, nil, nil, nil, nil, 43, nil, nil, nil, nil, + nil, nil, 24, 24, nil, nil, 24, nil, 39, 39, + nil, 27, 24, nil, nil, nil, nil, nil, nil, nil, + nil, 48, nil, nil, nil, nil, nil, 39, nil, nil, + 48, 48, nil, nil, nil, 43, 24, nil, nil, nil, + nil, nil, 39, nil, nil, nil, 43, 24, 27, nil, + nil, nil, nil, 24, 24, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 118, 118, 118, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 39, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 48, nil, nil, nil, nil, + nil, nil, nil, 24, nil, nil, nil, nil, nil, 24, + nil, 24, nil, nil, nil, nil, nil, 48, nil, nil, + nil, nil, 39, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 39, nil, nil, nil, + nil, nil, nil, nil, nil, 39, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 39, 118, 118, nil, nil, 118, 118, nil, 118, + nil, 27, nil, nil, nil, 48, 39, 48, nil, 39, + nil, 48, 48, nil, nil, 39, nil, nil, nil, nil, + nil, 118, 118, 118, 118, 39, 118, 48, 39, nil, + nil, 39, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 39, 39, nil, nil, nil, 39, 39, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 39, nil, nil, nil, nil, 118, 118, + 118, 118, nil, nil, nil, nil, 39, 39, nil, 118, + 118, 118, 118, nil, nil, 27, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 118, nil, 118, 39, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 39, nil, nil, nil, nil, 39, nil, nil, nil, + nil, 39, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 39, nil, nil, nil, nil, nil, nil, nil, nil, + 48, 39, nil, nil, nil, nil, nil, 48, nil, nil, + nil, nil, nil, nil, nil, nil, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 39, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 48, nil, nil, 48, 39, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 39, nil, 39, 39, nil, + nil, 39, nil, nil, nil, nil, nil, 39, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 48, nil, nil, + nil, nil, 39, nil, nil, nil, nil, nil, 39, 39, + 48, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 48, nil, nil, nil, nil, nil, nil, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 30, nil, nil, nil, nil, 39, nil, nil, + 30, 30, 30, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 30, 30, 30, nil, nil, nil, 39, nil, + nil, nil, nil, nil, 39, nil, 39, 30, 30, nil, + 48, nil, nil, nil, nil, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 48, nil, + nil, nil, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 48, 48, nil, nil, 48, nil, nil, nil, nil, + nil, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 48, nil, nil, nil, nil, + nil, 30, 30, 30, 30, nil, 48, 30, nil, nil, + nil, nil, 48, 48, nil, nil, nil, nil, nil, nil, + nil, 30, nil, nil, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, + nil, nil, nil, nil, nil, 30, 30, nil, nil, nil, + nil, nil, nil, nil, 30, nil, nil, nil, nil, nil, + nil, 30, nil, 30, nil, 30, nil, nil, nil, nil, + nil, nil, 48, nil, nil, nil, nil, nil, 48, nil, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 30, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 30, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 30, nil, 30, 30, 30, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 30, nil, nil, nil, nil, nil, 30, nil, 30, + nil, 30, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 30, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 30, 30, 30, nil, nil, nil, + nil, nil, 30, nil, nil, nil, 30, nil, nil, 30, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 30, 30, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 30, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 30, nil, 30, 30, nil, + nil, 30, 30, nil, nil, nil, 30, 30, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 30, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 30, nil, + 30, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 30, 30, 30, 30, nil, 30, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 30, + nil, nil, nil, nil, nil, nil, 30, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 30, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 30, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 30, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 30, nil, nil, 30, nil, 30 ] + +racc_goto_pointer = [ + nil, 109, 103, nil, 25, 94, 20, 55, -37, 28, + -301, -489, -513, nil, 35, 114, 3, 5, -13, 62, + 17, 385, -198, -373, 609, -149, 266, 904, 14, -16, + 1933, 2, nil, nil, -178, 59, -233, -333, -320, 1074, + 73, 14, 45, 589, nil, 3, 37, -283, 1308, -261, + 67, -62, -8, nil, nil, 55, 58, -245, -12, 82, + -7, -47, -239, -43, 57, -328, -224, -368, -321, -115, + nil, -319, -461, nil, nil, nil, nil, nil, nil, 75, + 87, 87, nil, -176, -285, -635, -428, -314, 82, nil, + -196, 30, nil, -524, 81, -208, -162, 93, 93, -511, + 94, -512, -368, -700, -372, -524, -182, -191, -374, -632, + -751, 120, -559, -731, -418, 133, -548, -555, 735, -465, + nil, -531, -561, -652, -645, -339, -465, -144, -477, 156, + -580, -580, -67, nil, -75, -75, -675, -315, -445, nil, + nil, 116, 116, 26, 113, 113, -165, -256, 118, -337, + -334, -546, -670, -670, -712, nil, nil, -426 ] + +racc_goto_default = [ + nil, nil, nil, 3, nil, 4, 328, 276, nil, 309, + nil, 780, nil, 275, nil, nil, nil, 215, 17, 12, + 216, 304, nil, nil, 214, nil, 269, 16, nil, 414, + 20, 21, 22, 23, 622, nil, nil, nil, nil, 292, + 393, 30, nil, nil, 32, 35, 34, nil, 212, 339, + nil, 121, 399, 120, 123, 72, 73, nil, 43, nil, + 630, 265, nil, 266, 404, 572, nil, 267, nil, nil, + 253, nil, nil, 44, 45, 46, 47, 48, 49, 50, + nil, 254, 56, nil, nil, nil, nil, nil, nil, 64, + nil, 513, 65, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 772, 652, nil, 773, nil, 641, nil, 643, nil, 840, + 586, nil, nil, nil, 649, nil, nil, nil, 689, nil, + nil, nil, nil, 403, nil, nil, nil, nil, nil, 71, + 74, 75, nil, nil, nil, nil, nil, 549, nil, nil, + nil, 642, 654, 655, 733, 658, 661, 271 ] + +racc_reduce_table = [ + 0, 0, :racc_error, + 1, 138, :_reduce_none, + 2, 139, :_reduce_2, + 0, 140, :_reduce_3, + 1, 140, :_reduce_4, + 3, 140, :_reduce_5, + 2, 140, :_reduce_6, + 1, 142, :_reduce_none, + 4, 142, :_reduce_8, + 4, 145, :_reduce_9, + 2, 146, :_reduce_10, + 0, 150, :_reduce_11, + 1, 150, :_reduce_12, + 3, 150, :_reduce_13, + 2, 150, :_reduce_14, + 0, 165, :_reduce_15, + 4, 144, :_reduce_16, + 3, 144, :_reduce_17, + 3, 144, :_reduce_18, + 3, 144, :_reduce_19, + 2, 144, :_reduce_20, + 3, 144, :_reduce_21, + 3, 144, :_reduce_22, + 3, 144, :_reduce_23, + 3, 144, :_reduce_24, + 3, 144, :_reduce_25, + 4, 144, :_reduce_26, + 3, 144, :_reduce_27, + 3, 144, :_reduce_28, + 3, 144, :_reduce_29, + 6, 144, :_reduce_30, + 5, 144, :_reduce_31, + 5, 144, :_reduce_32, + 5, 144, :_reduce_33, + 5, 144, :_reduce_34, + 3, 144, :_reduce_35, + 3, 144, :_reduce_36, + 3, 144, :_reduce_37, + 3, 144, :_reduce_38, + 1, 144, :_reduce_none, + 1, 164, :_reduce_none, + 3, 164, :_reduce_41, + 3, 164, :_reduce_42, + 3, 164, :_reduce_43, + 2, 164, :_reduce_44, + 1, 164, :_reduce_none, + 1, 153, :_reduce_none, + 1, 155, :_reduce_none, + 1, 155, :_reduce_none, + 1, 169, :_reduce_none, + 4, 169, :_reduce_50, + 4, 169, :_reduce_51, + 0, 175, :_reduce_52, + 5, 173, :_reduce_53, + 2, 168, :_reduce_54, + 3, 168, :_reduce_55, + 4, 168, :_reduce_56, + 5, 168, :_reduce_57, + 4, 168, :_reduce_58, + 5, 168, :_reduce_59, + 2, 168, :_reduce_60, + 2, 168, :_reduce_61, + 2, 168, :_reduce_62, + 2, 168, :_reduce_63, + 2, 168, :_reduce_64, + 1, 156, :_reduce_65, + 3, 156, :_reduce_66, + 1, 179, :_reduce_67, + 3, 179, :_reduce_68, + 1, 178, :_reduce_none, + 2, 178, :_reduce_70, + 3, 178, :_reduce_71, + 5, 178, :_reduce_72, + 2, 178, :_reduce_73, + 4, 178, :_reduce_74, + 2, 178, :_reduce_75, + 4, 178, :_reduce_76, + 1, 178, :_reduce_77, + 3, 178, :_reduce_78, + 1, 182, :_reduce_none, + 3, 182, :_reduce_80, + 2, 181, :_reduce_81, + 3, 181, :_reduce_82, + 1, 184, :_reduce_83, + 3, 184, :_reduce_84, + 1, 183, :_reduce_85, + 4, 183, :_reduce_86, + 3, 183, :_reduce_87, + 3, 183, :_reduce_88, + 3, 183, :_reduce_89, + 3, 183, :_reduce_90, + 2, 183, :_reduce_91, + 1, 183, :_reduce_92, + 1, 154, :_reduce_93, + 4, 154, :_reduce_94, + 3, 154, :_reduce_95, + 3, 154, :_reduce_96, + 3, 154, :_reduce_97, + 3, 154, :_reduce_98, + 2, 154, :_reduce_99, + 1, 154, :_reduce_100, + 1, 186, :_reduce_101, + 1, 186, :_reduce_none, + 2, 187, :_reduce_103, + 1, 187, :_reduce_104, + 3, 187, :_reduce_105, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 191, :_reduce_111, + 1, 191, :_reduce_none, + 1, 151, :_reduce_none, + 1, 151, :_reduce_none, + 1, 152, :_reduce_115, + 0, 194, :_reduce_116, + 4, 152, :_reduce_117, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 3, 167, :_reduce_188, + 5, 167, :_reduce_189, + 3, 167, :_reduce_190, + 5, 167, :_reduce_191, + 6, 167, :_reduce_192, + 5, 167, :_reduce_193, + 5, 167, :_reduce_194, + 5, 167, :_reduce_195, + 5, 167, :_reduce_196, + 4, 167, :_reduce_197, + 3, 167, :_reduce_198, + 3, 167, :_reduce_199, + 3, 167, :_reduce_200, + 3, 167, :_reduce_201, + 3, 167, :_reduce_202, + 3, 167, :_reduce_203, + 3, 167, :_reduce_204, + 3, 167, :_reduce_205, + 3, 167, :_reduce_206, + 4, 167, :_reduce_207, + 4, 167, :_reduce_208, + 2, 167, :_reduce_209, + 2, 167, :_reduce_210, + 3, 167, :_reduce_211, + 3, 167, :_reduce_212, + 3, 167, :_reduce_213, + 3, 167, :_reduce_214, + 3, 167, :_reduce_215, + 3, 167, :_reduce_216, + 3, 167, :_reduce_217, + 3, 167, :_reduce_218, + 3, 167, :_reduce_219, + 3, 167, :_reduce_220, + 3, 167, :_reduce_221, + 3, 167, :_reduce_222, + 3, 167, :_reduce_223, + 2, 167, :_reduce_224, + 2, 167, :_reduce_225, + 3, 167, :_reduce_226, + 3, 167, :_reduce_227, + 3, 167, :_reduce_228, + 3, 167, :_reduce_229, + 3, 167, :_reduce_230, + 6, 167, :_reduce_231, + 1, 167, :_reduce_none, + 1, 163, :_reduce_none, + 1, 196, :_reduce_none, + 2, 196, :_reduce_none, + 4, 196, :_reduce_236, + 2, 196, :_reduce_237, + 3, 201, :_reduce_238, + 0, 202, :_reduce_239, + 1, 202, :_reduce_none, + 0, 159, :_reduce_241, + 1, 159, :_reduce_none, + 1, 177, :_reduce_243, + 2, 177, :_reduce_244, + 2, 177, :_reduce_245, + 4, 177, :_reduce_246, + 6, 177, :_reduce_247, + 1, 177, :_reduce_248, + 4, 205, :_reduce_249, + 3, 205, :_reduce_250, + 2, 205, :_reduce_251, + 4, 205, :_reduce_252, + 6, 205, :_reduce_253, + 1, 205, :_reduce_254, + 0, 207, :_reduce_255, + 2, 172, :_reduce_256, + 1, 206, :_reduce_257, + 0, 208, :_reduce_258, + 3, 206, :_reduce_259, + 0, 209, :_reduce_260, + 4, 206, :_reduce_261, + 2, 204, :_reduce_262, + 2, 203, :_reduce_263, + 1, 203, :_reduce_264, + 0, 203, :_reduce_265, + 1, 198, :_reduce_266, + 2, 198, :_reduce_267, + 3, 198, :_reduce_268, + 4, 198, :_reduce_269, + 3, 162, :_reduce_270, + 4, 162, :_reduce_271, + 2, 162, :_reduce_272, + 1, 195, :_reduce_none, + 1, 195, :_reduce_none, + 1, 195, :_reduce_none, + 1, 195, :_reduce_none, + 1, 195, :_reduce_none, + 1, 195, :_reduce_none, + 1, 195, :_reduce_none, + 1, 195, :_reduce_none, + 1, 195, :_reduce_281, + 3, 195, :_reduce_282, + 0, 233, :_reduce_283, + 4, 195, :_reduce_284, + 3, 195, :_reduce_285, + 3, 195, :_reduce_286, + 2, 195, :_reduce_287, + 3, 195, :_reduce_288, + 3, 195, :_reduce_289, + 1, 195, :_reduce_290, + 4, 195, :_reduce_291, + 3, 195, :_reduce_292, + 1, 195, :_reduce_293, + 5, 195, :_reduce_294, + 4, 195, :_reduce_295, + 3, 195, :_reduce_296, + 2, 195, :_reduce_297, + 1, 195, :_reduce_none, + 2, 195, :_reduce_299, + 0, 234, :_reduce_300, + 3, 195, :_reduce_301, + 6, 195, :_reduce_302, + 6, 195, :_reduce_303, + 0, 235, :_reduce_304, + 0, 236, :_reduce_305, + 7, 195, :_reduce_306, + 0, 237, :_reduce_307, + 0, 238, :_reduce_308, + 7, 195, :_reduce_309, + 5, 195, :_reduce_310, + 4, 195, :_reduce_311, + 0, 239, :_reduce_312, + 0, 240, :_reduce_313, + 9, 195, :_reduce_314, + 0, 241, :_reduce_315, + 6, 195, :_reduce_316, + 0, 242, :_reduce_317, + 7, 195, :_reduce_318, + 0, 243, :_reduce_319, + 5, 195, :_reduce_320, + 0, 244, :_reduce_321, + 6, 195, :_reduce_322, + 0, 245, :_reduce_323, + 0, 246, :_reduce_324, + 9, 195, :_reduce_325, + 1, 195, :_reduce_326, + 1, 195, :_reduce_327, + 1, 195, :_reduce_328, + 1, 195, :_reduce_329, + 1, 158, :_reduce_none, + 1, 226, :_reduce_331, + 1, 229, :_reduce_332, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 2, 221, :_reduce_335, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 222, :_reduce_none, + 5, 222, :_reduce_339, + 1, 148, :_reduce_none, + 2, 148, :_reduce_341, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 247, :_reduce_none, + 3, 247, :_reduce_345, + 1, 250, :_reduce_346, + 3, 250, :_reduce_347, + 1, 249, :_reduce_none, + 4, 249, :_reduce_349, + 6, 249, :_reduce_350, + 3, 249, :_reduce_351, + 5, 249, :_reduce_352, + 2, 249, :_reduce_353, + 4, 249, :_reduce_354, + 1, 249, :_reduce_355, + 3, 249, :_reduce_356, + 6, 251, :_reduce_357, + 8, 251, :_reduce_358, + 4, 251, :_reduce_359, + 6, 251, :_reduce_360, + 4, 251, :_reduce_361, + 2, 251, :_reduce_none, + 6, 251, :_reduce_363, + 2, 251, :_reduce_364, + 4, 251, :_reduce_365, + 6, 251, :_reduce_366, + 2, 251, :_reduce_367, + 4, 251, :_reduce_368, + 2, 251, :_reduce_369, + 4, 251, :_reduce_370, + 1, 251, :_reduce_371, + 0, 174, :_reduce_372, + 1, 174, :_reduce_373, + 3, 257, :_reduce_374, + 1, 257, :_reduce_375, + 4, 257, :_reduce_376, + 0, 258, :_reduce_377, + 2, 258, :_reduce_378, + 1, 259, :_reduce_379, + 3, 259, :_reduce_380, + 1, 260, :_reduce_381, + 1, 260, :_reduce_none, + 0, 264, :_reduce_383, + 3, 220, :_reduce_384, + 4, 262, :_reduce_385, + 1, 262, :_reduce_386, + 0, 267, :_reduce_387, + 4, 263, :_reduce_388, + 0, 268, :_reduce_389, + 4, 263, :_reduce_390, + 0, 269, :_reduce_391, + 5, 266, :_reduce_392, + 2, 170, :_reduce_393, + 4, 170, :_reduce_394, + 4, 170, :_reduce_395, + 2, 219, :_reduce_396, + 4, 219, :_reduce_397, + 4, 219, :_reduce_398, + 3, 219, :_reduce_399, + 3, 219, :_reduce_400, + 3, 219, :_reduce_401, + 2, 219, :_reduce_402, + 1, 219, :_reduce_403, + 4, 219, :_reduce_404, + 0, 271, :_reduce_405, + 5, 218, :_reduce_406, + 0, 272, :_reduce_407, + 5, 218, :_reduce_408, + 5, 224, :_reduce_409, + 1, 273, :_reduce_410, + 1, 273, :_reduce_none, + 6, 147, :_reduce_412, + 0, 147, :_reduce_413, + 1, 274, :_reduce_414, + 1, 274, :_reduce_none, + 1, 274, :_reduce_none, + 2, 275, :_reduce_417, + 1, 275, :_reduce_none, + 2, 149, :_reduce_419, + 1, 149, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 211, :_reduce_424, + 1, 277, :_reduce_425, + 2, 277, :_reduce_426, + 3, 278, :_reduce_427, + 1, 278, :_reduce_428, + 1, 278, :_reduce_429, + 3, 212, :_reduce_430, + 4, 213, :_reduce_431, + 3, 214, :_reduce_432, + 0, 282, :_reduce_433, + 3, 282, :_reduce_434, + 1, 283, :_reduce_435, + 2, 283, :_reduce_436, + 3, 215, :_reduce_437, + 0, 285, :_reduce_438, + 3, 285, :_reduce_439, + 0, 279, :_reduce_440, + 2, 279, :_reduce_441, + 0, 280, :_reduce_442, + 2, 280, :_reduce_443, + 0, 281, :_reduce_444, + 2, 281, :_reduce_445, + 1, 284, :_reduce_446, + 2, 284, :_reduce_447, + 0, 287, :_reduce_448, + 4, 284, :_reduce_449, + 1, 286, :_reduce_450, + 1, 286, :_reduce_451, + 1, 286, :_reduce_452, + 1, 286, :_reduce_none, + 1, 192, :_reduce_454, + 3, 193, :_reduce_455, + 1, 276, :_reduce_456, + 1, 276, :_reduce_457, + 2, 276, :_reduce_458, + 2, 276, :_reduce_459, + 1, 185, :_reduce_460, + 1, 185, :_reduce_461, + 1, 185, :_reduce_462, + 1, 185, :_reduce_463, + 1, 185, :_reduce_464, + 1, 185, :_reduce_465, + 1, 185, :_reduce_466, + 1, 185, :_reduce_467, + 1, 185, :_reduce_468, + 1, 185, :_reduce_469, + 1, 185, :_reduce_470, + 1, 185, :_reduce_471, + 1, 216, :_reduce_472, + 1, 157, :_reduce_473, + 1, 161, :_reduce_474, + 1, 161, :_reduce_475, + 1, 227, :_reduce_476, + 3, 227, :_reduce_477, + 2, 227, :_reduce_478, + 3, 230, :_reduce_479, + 2, 230, :_reduce_480, + 6, 265, :_reduce_481, + 8, 265, :_reduce_482, + 4, 265, :_reduce_483, + 6, 265, :_reduce_484, + 4, 265, :_reduce_485, + 6, 265, :_reduce_486, + 2, 265, :_reduce_487, + 4, 265, :_reduce_488, + 6, 265, :_reduce_489, + 2, 265, :_reduce_490, + 4, 265, :_reduce_491, + 2, 265, :_reduce_492, + 4, 265, :_reduce_493, + 1, 265, :_reduce_494, + 0, 265, :_reduce_495, + 1, 261, :_reduce_496, + 1, 261, :_reduce_497, + 1, 261, :_reduce_498, + 1, 261, :_reduce_499, + 1, 248, :_reduce_none, + 1, 248, :_reduce_501, + 3, 248, :_reduce_502, + 2, 248, :_reduce_503, + 1, 289, :_reduce_none, + 3, 289, :_reduce_505, + 1, 252, :_reduce_506, + 3, 252, :_reduce_507, + 3, 290, :_reduce_508, + 3, 291, :_reduce_509, + 1, 253, :_reduce_510, + 3, 253, :_reduce_511, + 1, 288, :_reduce_512, + 3, 288, :_reduce_513, + 1, 292, :_reduce_none, + 1, 292, :_reduce_none, + 2, 254, :_reduce_516, + 1, 254, :_reduce_517, + 1, 293, :_reduce_none, + 1, 293, :_reduce_none, + 2, 256, :_reduce_520, + 2, 255, :_reduce_521, + 0, 255, :_reduce_522, + 1, 231, :_reduce_none, + 3, 231, :_reduce_524, + 0, 217, :_reduce_525, + 2, 217, :_reduce_none, + 1, 200, :_reduce_527, + 3, 200, :_reduce_528, + 3, 294, :_reduce_529, + 2, 294, :_reduce_530, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 171, :_reduce_none, + 1, 171, :_reduce_none, + 1, 171, :_reduce_none, + 1, 171, :_reduce_none, + 1, 270, :_reduce_none, + 1, 270, :_reduce_none, + 1, 270, :_reduce_none, + 1, 232, :_reduce_none, + 1, 232, :_reduce_none, + 0, 141, :_reduce_none, + 1, 141, :_reduce_none, + 0, 166, :_reduce_none, + 1, 166, :_reduce_none, + 2, 180, :_reduce_547, + 2, 160, :_reduce_548, + 0, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 228, :_reduce_552, + 1, 228, :_reduce_none, + 1, 143, :_reduce_none, + 2, 143, :_reduce_none, + 0, 197, :_reduce_556 ] + +racc_reduce_n = 557 + +racc_shift_n = 972 + +racc_token_table = { + false => 0, + :error => 1, + :kCLASS => 2, + :kMODULE => 3, + :kDEF => 4, + :kUNDEF => 5, + :kBEGIN => 6, + :kRESCUE => 7, + :kENSURE => 8, + :kEND => 9, + :kIF => 10, + :kUNLESS => 11, + :kTHEN => 12, + :kELSIF => 13, + :kELSE => 14, + :kCASE => 15, + :kWHEN => 16, + :kWHILE => 17, + :kUNTIL => 18, + :kFOR => 19, + :kBREAK => 20, + :kNEXT => 21, + :kREDO => 22, + :kRETRY => 23, + :kIN => 24, + :kDO => 25, + :kDO_COND => 26, + :kDO_BLOCK => 27, + :kDO_LAMBDA => 28, + :kRETURN => 29, + :kYIELD => 30, + :kSUPER => 31, + :kSELF => 32, + :kNIL => 33, + :kTRUE => 34, + :kFALSE => 35, + :kAND => 36, + :kOR => 37, + :kNOT => 38, + :kIF_MOD => 39, + :kUNLESS_MOD => 40, + :kWHILE_MOD => 41, + :kUNTIL_MOD => 42, + :kRESCUE_MOD => 43, + :kALIAS => 44, + :kDEFINED => 45, + :klBEGIN => 46, + :klEND => 47, + :k__LINE__ => 48, + :k__FILE__ => 49, + :k__ENCODING__ => 50, + :tIDENTIFIER => 51, + :tFID => 52, + :tGVAR => 53, + :tIVAR => 54, + :tCONSTANT => 55, + :tLABEL => 56, + :tCVAR => 57, + :tNTH_REF => 58, + :tBACK_REF => 59, + :tSTRING_CONTENT => 60, + :tINTEGER => 61, + :tFLOAT => 62, + :tUPLUS => 63, + :tUMINUS => 64, + :tUNARY_NUM => 65, + :tPOW => 66, + :tCMP => 67, + :tEQ => 68, + :tEQQ => 69, + :tNEQ => 70, + :tGEQ => 71, + :tLEQ => 72, + :tANDOP => 73, + :tOROP => 74, + :tMATCH => 75, + :tNMATCH => 76, + :tDOT => 77, + :tDOT2 => 78, + :tDOT3 => 79, + :tAREF => 80, + :tASET => 81, + :tLSHFT => 82, + :tRSHFT => 83, + :tCOLON2 => 84, + :tCOLON3 => 85, + :tOP_ASGN => 86, + :tASSOC => 87, + :tLPAREN => 88, + :tLPAREN2 => 89, + :tRPAREN => 90, + :tLPAREN_ARG => 91, + :tLBRACK => 92, + :tLBRACK2 => 93, + :tRBRACK => 94, + :tLBRACE => 95, + :tLBRACE_ARG => 96, + :tSTAR => 97, + :tSTAR2 => 98, + :tAMPER => 99, + :tAMPER2 => 100, + :tTILDE => 101, + :tPERCENT => 102, + :tDIVIDE => 103, + :tPLUS => 104, + :tMINUS => 105, + :tLT => 106, + :tGT => 107, + :tPIPE => 108, + :tBANG => 109, + :tCARET => 110, + :tLCURLY => 111, + :tRCURLY => 112, + :tBACK_REF2 => 113, + :tSYMBEG => 114, + :tSTRING_BEG => 115, + :tXSTRING_BEG => 116, + :tREGEXP_BEG => 117, + :tREGEXP_OPT => 118, + :tWORDS_BEG => 119, + :tQWORDS_BEG => 120, + :tSTRING_DBEG => 121, + :tSTRING_DVAR => 122, + :tSTRING_END => 123, + :tSTRING => 124, + :tSYMBOL => 125, + :tNL => 126, + :tEH => 127, + :tCOLON => 128, + :tCOMMA => 129, + :tSPACE => 130, + :tSEMI => 131, + :tLAMBDA => 132, + :tLAMBEG => 133, + :tCHARACTER => 134, + :tEQL => 135, + :tLOWEST => 136 } + +racc_nt_base = 137 + +racc_use_result_var = true + +Racc_arg = [ + racc_action_table, + racc_action_check, + racc_action_default, + racc_action_pointer, + racc_goto_table, + racc_goto_check, + racc_goto_default, + racc_goto_pointer, + racc_nt_base, + racc_reduce_table, + racc_token_table, + racc_shift_n, + racc_reduce_n, + racc_use_result_var ] +Ractor.make_shareable(Racc_arg) if defined?(Ractor) + +Racc_token_to_s_table = [ + "$end", + "error", + "kCLASS", + "kMODULE", + "kDEF", + "kUNDEF", + "kBEGIN", + "kRESCUE", + "kENSURE", + "kEND", + "kIF", + "kUNLESS", + "kTHEN", + "kELSIF", + "kELSE", + "kCASE", + "kWHEN", + "kWHILE", + "kUNTIL", + "kFOR", + "kBREAK", + "kNEXT", + "kREDO", + "kRETRY", + "kIN", + "kDO", + "kDO_COND", + "kDO_BLOCK", + "kDO_LAMBDA", + "kRETURN", + "kYIELD", + "kSUPER", + "kSELF", + "kNIL", + "kTRUE", + "kFALSE", + "kAND", + "kOR", + "kNOT", + "kIF_MOD", + "kUNLESS_MOD", + "kWHILE_MOD", + "kUNTIL_MOD", + "kRESCUE_MOD", + "kALIAS", + "kDEFINED", + "klBEGIN", + "klEND", + "k__LINE__", + "k__FILE__", + "k__ENCODING__", + "tIDENTIFIER", + "tFID", + "tGVAR", + "tIVAR", + "tCONSTANT", + "tLABEL", + "tCVAR", + "tNTH_REF", + "tBACK_REF", + "tSTRING_CONTENT", + "tINTEGER", + "tFLOAT", + "tUPLUS", + "tUMINUS", + "tUNARY_NUM", + "tPOW", + "tCMP", + "tEQ", + "tEQQ", + "tNEQ", + "tGEQ", + "tLEQ", + "tANDOP", + "tOROP", + "tMATCH", + "tNMATCH", + "tDOT", + "tDOT2", + "tDOT3", + "tAREF", + "tASET", + "tLSHFT", + "tRSHFT", + "tCOLON2", + "tCOLON3", + "tOP_ASGN", + "tASSOC", + "tLPAREN", + "tLPAREN2", + "tRPAREN", + "tLPAREN_ARG", + "tLBRACK", + "tLBRACK2", + "tRBRACK", + "tLBRACE", + "tLBRACE_ARG", + "tSTAR", + "tSTAR2", + "tAMPER", + "tAMPER2", + "tTILDE", + "tPERCENT", + "tDIVIDE", + "tPLUS", + "tMINUS", + "tLT", + "tGT", + "tPIPE", + "tBANG", + "tCARET", + "tLCURLY", + "tRCURLY", + "tBACK_REF2", + "tSYMBEG", + "tSTRING_BEG", + "tXSTRING_BEG", + "tREGEXP_BEG", + "tREGEXP_OPT", + "tWORDS_BEG", + "tQWORDS_BEG", + "tSTRING_DBEG", + "tSTRING_DVAR", + "tSTRING_END", + "tSTRING", + "tSYMBOL", + "tNL", + "tEH", + "tCOLON", + "tCOMMA", + "tSPACE", + "tSEMI", + "tLAMBDA", + "tLAMBEG", + "tCHARACTER", + "tEQL", + "tLOWEST", + "$start", + "program", + "top_compstmt", + "top_stmts", + "opt_terms", + "top_stmt", + "terms", + "stmt", + "bodystmt", + "compstmt", + "opt_rescue", + "opt_else", + "opt_ensure", + "stmts", + "fitem", + "undef_list", + "expr_value", + "lhs", + "command_call", + "mlhs", + "var_lhs", + "primary_value", + "opt_call_args", + "rbracket", + "backref", + "mrhs", + "arg_value", + "expr", + "@1", + "opt_nl", + "arg", + "command", + "block_command", + "block_call", + "operation2", + "command_args", + "cmd_brace_block", + "opt_block_param", + "@2", + "operation", + "call_args", + "mlhs_basic", + "mlhs_inner", + "rparen", + "mlhs_head", + "mlhs_item", + "mlhs_node", + "mlhs_post", + "variable", + "cname", + "cpath", + "fname", + "op", + "reswords", + "fsym", + "symbol", + "dsym", + "@3", + "primary", + "aref_args", + "none", + "args", + "trailer", + "assocs", + "paren_args", + "opt_paren_args", + "opt_block_arg", + "block_arg", + "call_args2", + "open_args", + "@4", + "@5", + "@6", + "literal", + "strings", + "xstring", + "regexp", + "words", + "qwords", + "var_ref", + "assoc_list", + "brace_block", + "method_call", + "lambda", + "then", + "if_tail", + "do", + "case_body", + "for_var", + "k_class", + "superclass", + "term", + "k_module", + "f_arglist", + "singleton", + "dot_or_colon", + "@7", + "@8", + "@9", + "@10", + "@11", + "@12", + "@13", + "@14", + "@15", + "@16", + "@17", + "@18", + "@19", + "@20", + "f_marg", + "f_norm_arg", + "f_margs", + "f_marg_list", + "block_param", + "f_arg", + "f_block_optarg", + "f_rest_arg", + "opt_f_block_arg", + "f_block_arg", + "block_param_def", + "opt_bv_decl", + "bv_decls", + "bvar", + "f_bad_arg", + "f_larglist", + "lambda_body", + "@21", + "f_args", + "do_block", + "@22", + "@23", + "@24", + "operation3", + "@25", + "@26", + "cases", + "exc_list", + "exc_var", + "numeric", + "string", + "string1", + "string_contents", + "xstring_contents", + "regexp_contents", + "word_list", + "word", + "string_content", + "qword_list", + "string_dvar", + "@27", + "f_optarg", + "f_arg_item", + "f_opt", + "f_block_opt", + "restarg_mark", + "blkarg_mark", + "assoc" ] +Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) + +Racc_debug_parser = false + +##### State transition tables end ##### + +# reduce 0 omitted + +# reduce 1 omitted + +def _reduce_2(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_3(val, _values, result) + result = [] + + result +end + +def _reduce_4(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_5(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_6(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 7 omitted + +def _reduce_8(val, _values, result) + result = @builder.preexe(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_9(val, _values, result) + rescue_bodies = val[1] + else_t, else_ = val[2] + ensure_t, ensure_ = val[3] + + if rescue_bodies.empty? && !else_t.nil? + diagnostic :warning, :useless_else, nil, else_t + end + + result = @builder.begin_body(val[0], + rescue_bodies, + else_t, else_, + ensure_t, ensure_) + + result +end + +def _reduce_10(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_11(val, _values, result) + result = [] + + result +end + +def _reduce_12(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_13(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_14(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_15(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_16(val, _values, result) + result = @builder.alias(val[0], val[1], val[3]) + + result +end + +def _reduce_17(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.gvar(val[2])) + + result +end + +def _reduce_18(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.back_ref(val[2])) + + result +end + +def _reduce_19(val, _values, result) + diagnostic :error, :nth_ref_alias, nil, val[2] + + result +end + +def _reduce_20(val, _values, result) + result = @builder.undef_method(val[0], val[1]) + + result +end + +def _reduce_21(val, _values, result) + result = @builder.condition_mod(val[0], nil, + val[1], val[2]) + + result +end + +def _reduce_22(val, _values, result) + result = @builder.condition_mod(nil, val[0], + val[1], val[2]) + + result +end + +def _reduce_23(val, _values, result) + result = @builder.loop_mod(:while, val[0], val[1], val[2]) + + result +end + +def _reduce_24(val, _values, result) + result = @builder.loop_mod(:until, val[0], val[1], val[2]) + + result +end + +def _reduce_25(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_26(val, _values, result) + result = @builder.postexe(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_27(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_28(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_29(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_30(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_31(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_32(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_33(val, _values, result) + diagnostic :error, :const_reassignment, nil, val[3] + + result +end + +def _reduce_34(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_35(val, _values, result) + @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_36(val, _values, result) + result = @builder.assign(val[0], val[1], + @builder.array(nil, val[2], nil)) + + result +end + +def _reduce_37(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_38(val, _values, result) + result = @builder.multi_assign(val[0], val[1], + @builder.array(nil, val[2], nil)) + + result +end + +# reduce 39 omitted + +# reduce 40 omitted + +def _reduce_41(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_42(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_43(val, _values, result) + result = @builder.not_op(val[0], nil, val[2], nil) + + result +end + +def _reduce_44(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +# reduce 45 omitted + +# reduce 46 omitted + +# reduce 47 omitted + +# reduce 48 omitted + +# reduce 49 omitted + +def _reduce_50(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + *val[3]) + + result +end + +def _reduce_51(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + *val[3]) + + result +end + +def _reduce_52(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_53(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_54(val, _values, result) + result = @builder.call_method(nil, nil, val[0], + *val[1]) + + result +end + +def _reduce_55(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0], + *val[1]) + + begin_t, args, body, end_t = val[2] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_56(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + *val[3]) + + result +end + +def _reduce_57(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + *val[3]) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_58(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + *val[3]) + + result +end + +def _reduce_59(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + *val[3]) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_60(val, _values, result) + result = @builder.keyword_cmd(:super, val[0], + *val[1]) + + result +end + +def _reduce_61(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], + *val[1]) + + result +end + +def _reduce_62(val, _values, result) + result = @builder.keyword_cmd(:return, val[0], + nil, val[1], nil) + + result +end + +def _reduce_63(val, _values, result) + result = @builder.keyword_cmd(:break, val[0], + nil, val[1], nil) + + result +end + +def _reduce_64(val, _values, result) + result = @builder.keyword_cmd(:next, val[0], + nil, val[1], nil) + + result +end + +def _reduce_65(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_66(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_67(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_68(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +# reduce 69 omitted + +def _reduce_70(val, _values, result) + result = val[0]. + push(val[1]) + + result +end + +def _reduce_71(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])) + + result +end + +def _reduce_72(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])). + concat(val[4]) + + result +end + +def _reduce_73(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])) + + result +end + +def _reduce_74(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])). + concat(val[3]) + + result +end + +def _reduce_75(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_76(val, _values, result) + result = [ @builder.splat(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_77(val, _values, result) + result = [ @builder.splat(val[0]) ] + + result +end + +def _reduce_78(val, _values, result) + result = [ @builder.splat(val[0]), + *val[2] ] + + result +end + +# reduce 79 omitted + +def _reduce_80(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_81(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_82(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_83(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_84(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_85(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_86(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_87(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_88(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_89(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_90(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_91(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_92(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_93(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_94(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_95(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_96(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_97(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_98(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_99(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_100(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_101(val, _values, result) + diagnostic :error, :module_name_const, nil, val[0] + + result +end + +# reduce 102 omitted + +def _reduce_103(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_104(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_105(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +# reduce 106 omitted + +# reduce 107 omitted + +# reduce 108 omitted + +# reduce 109 omitted + +# reduce 110 omitted + +def _reduce_111(val, _values, result) + result = @builder.symbol_internal(val[0]) + + result +end + +# reduce 112 omitted + +# reduce 113 omitted + +# reduce 114 omitted + +def _reduce_115(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_116(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_117(val, _values, result) + result = val[0] << val[3] + + result +end + +# reduce 118 omitted + +# reduce 119 omitted + +# reduce 120 omitted + +# reduce 121 omitted + +# reduce 122 omitted + +# reduce 123 omitted + +# reduce 124 omitted + +# reduce 125 omitted + +# reduce 126 omitted + +# reduce 127 omitted + +# reduce 128 omitted + +# reduce 129 omitted + +# reduce 130 omitted + +# reduce 131 omitted + +# reduce 132 omitted + +# reduce 133 omitted + +# reduce 134 omitted + +# reduce 135 omitted + +# reduce 136 omitted + +# reduce 137 omitted + +# reduce 138 omitted + +# reduce 139 omitted + +# reduce 140 omitted + +# reduce 141 omitted + +# reduce 142 omitted + +# reduce 143 omitted + +# reduce 144 omitted + +# reduce 145 omitted + +# reduce 146 omitted + +# reduce 147 omitted + +# reduce 148 omitted + +# reduce 149 omitted + +# reduce 150 omitted + +# reduce 151 omitted + +# reduce 152 omitted + +# reduce 153 omitted + +# reduce 154 omitted + +# reduce 155 omitted + +# reduce 156 omitted + +# reduce 157 omitted + +# reduce 158 omitted + +# reduce 159 omitted + +# reduce 160 omitted + +# reduce 161 omitted + +# reduce 162 omitted + +# reduce 163 omitted + +# reduce 164 omitted + +# reduce 165 omitted + +# reduce 166 omitted + +# reduce 167 omitted + +# reduce 168 omitted + +# reduce 169 omitted + +# reduce 170 omitted + +# reduce 171 omitted + +# reduce 172 omitted + +# reduce 173 omitted + +# reduce 174 omitted + +# reduce 175 omitted + +# reduce 176 omitted + +# reduce 177 omitted + +# reduce 178 omitted + +# reduce 179 omitted + +# reduce 180 omitted + +# reduce 181 omitted + +# reduce 182 omitted + +# reduce 183 omitted + +# reduce 184 omitted + +# reduce 185 omitted + +# reduce 186 omitted + +# reduce 187 omitted + +def _reduce_188(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_189(val, _values, result) + rescue_body = @builder.rescue_body(val[3], + nil, nil, nil, + nil, val[4]) + + rescue_ = @builder.begin_body(val[2], [ rescue_body ]) + + result = @builder.assign(val[0], val[1], rescue_) + + result +end + +def _reduce_190(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_191(val, _values, result) + rescue_body = @builder.rescue_body(val[3], + nil, nil, nil, + nil, val[4]) + + rescue_ = @builder.begin_body(val[2], [ rescue_body ]) + + result = @builder.op_assign(val[0], val[1], rescue_) + + result +end + +def _reduce_192(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_193(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_194(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_195(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_196(val, _values, result) + diagnostic :error, :dynamic_const, nil, val[2], [ val[3] ] + + result +end + +def _reduce_197(val, _values, result) + diagnostic :error, :dynamic_const, nil, val[1], [ val[2] ] + + result +end + +def _reduce_198(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_199(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_200(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_201(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_202(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_203(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_204(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_205(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_206(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_207(val, _values, result) + result = @builder.unary_op(val[0], + @builder.binary_op( + @builder.integer(val[1]), + val[2], val[3])) + + result +end + +def _reduce_208(val, _values, result) + result = @builder.unary_op(val[0], + @builder.binary_op( + @builder.float(val[1]), + val[2], val[3])) + + result +end + +def _reduce_209(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_210(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_211(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_212(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_213(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_214(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_215(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_216(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_217(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_218(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_219(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_220(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_221(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_222(val, _values, result) + result = @builder.match_op(val[0], val[1], val[2]) + + result +end + +def _reduce_223(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_224(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +def _reduce_225(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_226(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_227(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_228(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_229(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_230(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil) + + result +end + +def _reduce_231(val, _values, result) + result = @builder.ternary(val[0], val[1], + val[2], val[4], val[5]) + + result +end + +# reduce 232 omitted + +# reduce 233 omitted + +# reduce 234 omitted + +# reduce 235 omitted + +def _reduce_236(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_237(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +def _reduce_238(val, _values, result) + result = val + + result +end + +def _reduce_239(val, _values, result) + result = [ nil, [], nil ] + + result +end + +# reduce 240 omitted + +def _reduce_241(val, _values, result) + result = [] + + result +end + +# reduce 242 omitted + +def _reduce_243(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_244(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_245(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + result.concat(val[1]) + + result +end + +def _reduce_246(val, _values, result) + assocs = @builder.associate(nil, val[2], nil) + result = val[0] << assocs + result.concat(val[3]) + + result +end + +def _reduce_247(val, _values, result) + val[2][-1] = @builder.objc_varargs(val[2][-1], val[4]) + assocs = @builder.associate(nil, val[2], nil) + result = val[0] << assocs + result.concat(val[5]) + + result +end + +def _reduce_248(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_249(val, _values, result) + result = [ val[0], *val[2].concat(val[3]) ] + + result +end + +def _reduce_250(val, _values, result) + result = [ val[0], val[2] ] + + result +end + +def _reduce_251(val, _values, result) + result = [ @builder.associate(nil, val[0], nil), + *val[1] ] + + result +end + +def _reduce_252(val, _values, result) + result = [ val[0], + @builder.associate(nil, val[2], nil), + *val[3] ] + + result +end + +def _reduce_253(val, _values, result) + result = [ val[0], + *val[2]. + push(@builder.associate(nil, val[4], nil)). + concat(val[5]) ] + + result +end + +def _reduce_254(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_255(val, _values, result) + result = @lexer.cmdarg.dup + @lexer.cmdarg.push(true) + + result +end + +def _reduce_256(val, _values, result) + @lexer.cmdarg = val[0] + + result = val[1] + + result +end + +def _reduce_257(val, _values, result) + result = [ nil, val[0], nil ] + + result +end + +def _reduce_258(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_259(val, _values, result) + result = [ val[0], [], val[2] ] + + result +end + +def _reduce_260(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_261(val, _values, result) + result = [ val[0], val[1], val[3] ] + + result +end + +def _reduce_262(val, _values, result) + result = @builder.block_pass(val[0], val[1]) + + result +end + +def _reduce_263(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_264(val, _values, result) + result = [] + + result +end + +def _reduce_265(val, _values, result) + result = [] + + result +end + +def _reduce_266(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_267(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_268(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_269(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_270(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_271(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_272(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +# reduce 273 omitted + +# reduce 274 omitted + +# reduce 275 omitted + +# reduce 276 omitted + +# reduce 277 omitted + +# reduce 278 omitted + +# reduce 279 omitted + +# reduce 280 omitted + +def _reduce_281(val, _values, result) + result = @builder.call_method(nil, nil, val[0]) + + result +end + +def _reduce_282(val, _values, result) + result = @builder.begin_keyword(val[0], val[1], val[2]) + + result +end + +def _reduce_283(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_284(val, _values, result) + result = @builder.begin(val[0], val[1], val[3]) + + result +end + +def _reduce_285(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_286(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +def _reduce_287(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_288(val, _values, result) + result = @builder.array(val[0], val[1], val[2]) + + result +end + +def _reduce_289(val, _values, result) + result = @builder.associate(val[0], val[1], val[2]) + + result +end + +def _reduce_290(val, _values, result) + result = @builder.keyword_cmd(:return, val[0]) + + result +end + +def _reduce_291(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_292(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2]) + + result +end + +def _reduce_293(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0]) + + result +end + +def _reduce_294(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], + val[2], [ val[3] ], val[4]) + + result +end + +def _reduce_295(val, _values, result) + result = @builder.not_op(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_296(val, _values, result) + result = @builder.not_op(val[0], val[1], nil, val[2]) + + result +end + +def _reduce_297(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0]) + + begin_t, args, body, end_t = val[1] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +# reduce 298 omitted + +def _reduce_299(val, _values, result) + begin_t, args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, args, body, end_t) + + result +end + +def _reduce_300(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_301(val, _values, result) + lambda_call = @builder.call_lambda(val[0]) + + args, (begin_t, body, end_t) = val[2] + result = @builder.block(lambda_call, + begin_t, args, body, end_t) + + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_302(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, val[5]) + + result +end + +def _reduce_303(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + else_, else_t, + val[3], val[5]) + + result +end + +def _reduce_304(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_305(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_306(val, _values, result) + result = @builder.loop(:while, val[0], val[2], val[3], + val[5], val[6]) + + result +end + +def _reduce_307(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_308(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_309(val, _values, result) + result = @builder.loop(:until, val[0], val[2], val[3], + val[5], val[6]) + + result +end + +def _reduce_310(val, _values, result) + *when_bodies, (else_t, else_body) = *val[3] + + result = @builder.case(val[0], val[1], + when_bodies, else_t, else_body, + val[4]) + + result +end + +def _reduce_311(val, _values, result) + *when_bodies, (else_t, else_body) = *val[2] + + result = @builder.case(val[0], nil, + when_bodies, else_t, else_body, + val[3]) + + result +end + +def _reduce_312(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_313(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_314(val, _values, result) + result = @builder.for(val[0], val[1], + val[2], val[4], + val[5], val[7], val[8]) + + result +end + +def _reduce_315(val, _values, result) + local_push + @context.in_class = true + + result +end + +def _reduce_316(val, _values, result) + k_class, ctx = val[0] + if @context.in_def + diagnostic :error, :class_in_def, nil, k_class + end + + lt_t, superclass = val[2] + result = @builder.def_class(k_class, val[1], + lt_t, superclass, + val[4], val[5]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_317(val, _values, result) + @context.in_def = false + @context.in_class = false + local_push + + result +end + +def _reduce_318(val, _values, result) + k_class, ctx = val[0] + result = @builder.def_sclass(k_class, val[1], val[2], + val[5], val[6]) + + local_pop + @context.in_def = ctx.in_def + @context.in_class = ctx.in_class + + result +end + +def _reduce_319(val, _values, result) + @context.in_class = true + local_push + + result +end + +def _reduce_320(val, _values, result) + k_mod, ctx = val[0] + if @context.in_def + diagnostic :error, :module_in_def, nil, k_mod + end + + result = @builder.def_module(k_mod, val[1], + val[3], val[4]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_321(val, _values, result) + local_push + result = context.dup + @context.in_def = true + + result +end + +def _reduce_322(val, _values, result) + result = @builder.def_method(val[0], val[1], + val[3], val[4], val[5]) + + local_pop + @context.in_def = val[2].in_def + + result +end + +def _reduce_323(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_324(val, _values, result) + local_push + result = context.dup + @context.in_def = true + + result +end + +def _reduce_325(val, _values, result) + result = @builder.def_singleton(val[0], val[1], val[2], + val[4], val[6], val[7], val[8]) + + local_pop + @context.in_def = val[5].in_def + + result +end + +def _reduce_326(val, _values, result) + result = @builder.keyword_cmd(:break, val[0]) + + result +end + +def _reduce_327(val, _values, result) + result = @builder.keyword_cmd(:next, val[0]) + + result +end + +def _reduce_328(val, _values, result) + result = @builder.keyword_cmd(:redo, val[0]) + + result +end + +def _reduce_329(val, _values, result) + result = @builder.keyword_cmd(:retry, val[0]) + + result +end + +# reduce 330 omitted + +def _reduce_331(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_332(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +# reduce 333 omitted + +# reduce 334 omitted + +def _reduce_335(val, _values, result) + result = val[1] + + result +end + +# reduce 336 omitted + +# reduce 337 omitted + +# reduce 338 omitted + +def _reduce_339(val, _values, result) + else_t, else_ = val[4] + result = [ val[0], + @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, nil), + ] + + result +end + +# reduce 340 omitted + +def _reduce_341(val, _values, result) + result = val + + result +end + +# reduce 342 omitted + +# reduce 343 omitted + +# reduce 344 omitted + +def _reduce_345(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_346(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_347(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 348 omitted + +def _reduce_349(val, _values, result) + result = val[0]. + push(@builder.objc_restarg(val[2], val[3])) + + result +end + +def _reduce_350(val, _values, result) + result = val[0]. + push(@builder.objc_restarg(val[2], val[3])). + concat(val[5]) + + result +end + +def _reduce_351(val, _values, result) + result = val[0]. + push(@builder.objc_restarg(val[2])) + + result +end + +def _reduce_352(val, _values, result) + result = val[0]. + push(@builder.objc_restarg(val[2])). + concat(val[4]) + + result +end + +def _reduce_353(val, _values, result) + result = [ @builder.objc_restarg(val[0], val[1]) ] + + result +end + +def _reduce_354(val, _values, result) + result = [ @builder.objc_restarg(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_355(val, _values, result) + result = [ @builder.objc_restarg(val[0]) ] + + result +end + +def _reduce_356(val, _values, result) + result = [ @builder.objc_restarg(val[0]), + *val[2] ] + + result +end + +def _reduce_357(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_358(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_359(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_360(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_361(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 362 omitted + +def _reduce_363(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_364(val, _values, result) + if val[1].empty? && val[0].size == 1 + result = [@builder.procarg0(val[0][0])] + else + result = val[0].concat(val[1]) + end + + result +end + +def _reduce_365(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_366(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_367(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_368(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_369(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_370(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_371(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_372(val, _values, result) + result = @builder.args(nil, [], nil) + + result +end + +def _reduce_373(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_374(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + result +end + +def _reduce_375(val, _values, result) + result = @builder.args(val[0], [], val[0]) + + result +end + +def _reduce_376(val, _values, result) + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_377(val, _values, result) + result = [] + + result +end + +def _reduce_378(val, _values, result) + result = val[1] + + result +end + +def _reduce_379(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_380(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_381(val, _values, result) + @static_env.declare val[0][0] + result = @builder.shadowarg(val[0]) + + result +end + +# reduce 382 omitted + +def _reduce_383(val, _values, result) + @static_env.extend_dynamic + + result +end + +def _reduce_384(val, _values, result) + result = [ val[1], val[2] ] + + @static_env.unextend + + result +end + +def _reduce_385(val, _values, result) + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_386(val, _values, result) + result = @builder.args(nil, val[0], nil) + + result +end + +def _reduce_387(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_388(val, _values, result) + result = [ val[0], val[2], val[3] ] + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_389(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_390(val, _values, result) + result = [ val[0], val[2], val[3] ] + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_391(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_392(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_393(val, _values, result) + begin_t, block_args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, block_args, body, end_t) + + result +end + +def _reduce_394(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_395(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_396(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.call_method(nil, nil, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_397(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_398(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_399(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2]) + + result +end + +def _reduce_400(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_401(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_402(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.keyword_cmd(:super, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_403(val, _values, result) + result = @builder.keyword_cmd(:zsuper, val[0]) + + result +end + +def _reduce_404(val, _values, result) + result = @builder.index(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_405(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_406(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_407(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_408(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_409(val, _values, result) + result = [ @builder.when(val[0], val[1], val[2], val[3]), + *val[4] ] + + result +end + +def _reduce_410(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 411 omitted + +def _reduce_412(val, _values, result) + assoc_t, exc_var = val[2] + + if val[1] + exc_list = @builder.array(nil, val[1], nil) + end + + result = [ @builder.rescue_body(val[0], + exc_list, assoc_t, exc_var, + val[3], val[4]), + *val[5] ] + + result +end + +def _reduce_413(val, _values, result) + result = [] + + result +end + +def _reduce_414(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 415 omitted + +# reduce 416 omitted + +def _reduce_417(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 418 omitted + +def _reduce_419(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 420 omitted + +# reduce 421 omitted + +# reduce 422 omitted + +# reduce 423 omitted + +def _reduce_424(val, _values, result) + result = @builder.string_compose(nil, val[0], nil) + + result +end + +def _reduce_425(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_426(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_427(val, _values, result) + result = @builder.string_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_428(val, _values, result) + result = @builder.string(val[0]) + + result +end + +def _reduce_429(val, _values, result) + result = @builder.character(val[0]) + + result +end + +def _reduce_430(val, _values, result) + result = @builder.xstring_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_431(val, _values, result) + opts = @builder.regexp_options(val[3]) + result = @builder.regexp_compose(val[0], val[1], val[2], opts) + + result +end + +def _reduce_432(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_433(val, _values, result) + result = [] + + result +end + +def _reduce_434(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_435(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_436(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_437(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_438(val, _values, result) + result = [] + + result +end + +def _reduce_439(val, _values, result) + result = val[0] << @builder.string_internal(val[1]) + + result +end + +def _reduce_440(val, _values, result) + result = [] + + result +end + +def _reduce_441(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_442(val, _values, result) + result = [] + + result +end + +def _reduce_443(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_444(val, _values, result) + result = [] + + result +end + +def _reduce_445(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_446(val, _values, result) + result = @builder.string_internal(val[0]) + + result +end + +def _reduce_447(val, _values, result) + result = val[1] + + result +end + +def _reduce_448(val, _values, result) + @lexer.cond.push(false) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_449(val, _values, result) + @lexer.cond.lexpop + @lexer.cmdarg.lexpop + + result = @builder.begin(val[0], val[2], val[3]) + + result +end + +def _reduce_450(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_451(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_452(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +# reduce 453 omitted + +def _reduce_454(val, _values, result) + result = @builder.symbol(val[0]) + + result +end + +def _reduce_455(val, _values, result) + result = @builder.symbol_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_456(val, _values, result) + result = @builder.integer(val[0]) + + result +end + +def _reduce_457(val, _values, result) + result = @builder.float(val[0]) + + result +end + +def _reduce_458(val, _values, result) + num = @builder.integer(val[1]) + if @builder.respond_to? :negate + # AST builder interface compatibility + result = @builder.negate(val[0], num) + else + result = @builder.unary_num(val[0], num) + end + + result +end + +def _reduce_459(val, _values, result) + num = @builder.float(val[1]) + if @builder.respond_to? :negate + # AST builder interface compatibility + result = @builder.negate(val[0], num) + else + result = @builder.unary_num(val[0], num) + end + + result +end + +def _reduce_460(val, _values, result) + result = @builder.ident(val[0]) + + result +end + +def _reduce_461(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_462(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_463(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_464(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +def _reduce_465(val, _values, result) + result = @builder.nil(val[0]) + + result +end + +def _reduce_466(val, _values, result) + result = @builder.self(val[0]) + + result +end + +def _reduce_467(val, _values, result) + result = @builder.true(val[0]) + + result +end + +def _reduce_468(val, _values, result) + result = @builder.false(val[0]) + + result +end + +def _reduce_469(val, _values, result) + result = @builder.__FILE__(val[0]) + + result +end + +def _reduce_470(val, _values, result) + result = @builder.__LINE__(val[0]) + + result +end + +def _reduce_471(val, _values, result) + result = @builder.__ENCODING__(val[0]) + + result +end + +def _reduce_472(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_473(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_474(val, _values, result) + result = @builder.nth_ref(val[0]) + + result +end + +def _reduce_475(val, _values, result) + result = @builder.back_ref(val[0]) + + result +end + +def _reduce_476(val, _values, result) + result = nil + + result +end + +def _reduce_477(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +def _reduce_478(val, _values, result) + yyerrok + result = nil + + result +end + +def _reduce_479(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + @lexer.state = :expr_value + + result +end + +def _reduce_480(val, _values, result) + result = @builder.args(nil, val[0], nil) + + result +end + +def _reduce_481(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_482(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_483(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_484(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_485(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_486(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_487(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_488(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_489(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_490(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_491(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_492(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_493(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_494(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_495(val, _values, result) + result = [] + + result +end + +def _reduce_496(val, _values, result) + diagnostic :error, :argument_const, nil, val[0] + + result +end + +def _reduce_497(val, _values, result) + diagnostic :error, :argument_ivar, nil, val[0] + + result +end + +def _reduce_498(val, _values, result) + diagnostic :error, :argument_gvar, nil, val[0] + + result +end + +def _reduce_499(val, _values, result) + diagnostic :error, :argument_cvar, nil, val[0] + + result +end + +# reduce 500 omitted + +def _reduce_501(val, _values, result) + @static_env.declare val[0][0] + + result = @builder.arg(val[0]) + + result +end + +def _reduce_502(val, _values, result) + @static_env.declare val[2][0] + + result = @builder.objc_kwarg(val[0], val[1], val[2]) + + result +end + +def _reduce_503(val, _values, result) + @static_env.declare val[1][0] + + result = @builder.objc_kwarg(val[0], nil, val[1]) + + result +end + +# reduce 504 omitted + +def _reduce_505(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_506(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_507(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_508(val, _values, result) + @static_env.declare val[0][0] + + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_509(val, _values, result) + @static_env.declare val[0][0] + + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_510(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_511(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_512(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_513(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 514 omitted + +# reduce 515 omitted + +def _reduce_516(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_517(val, _values, result) + result = [ @builder.restarg(val[0]) ] + + result +end + +# reduce 518 omitted + +# reduce 519 omitted + +def _reduce_520(val, _values, result) + @static_env.declare val[1][0] + + result = @builder.blockarg(val[0], val[1]) + + result +end + +def _reduce_521(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_522(val, _values, result) + result = [] + + result +end + +# reduce 523 omitted + +def _reduce_524(val, _values, result) + result = val[1] + + result +end + +def _reduce_525(val, _values, result) + result = [] + + result +end + +# reduce 526 omitted + +def _reduce_527(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_528(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_529(val, _values, result) + result = @builder.pair(val[0], val[1], val[2]) + + result +end + +def _reduce_530(val, _values, result) + result = @builder.pair_keyword(val[0], val[1]) + + result +end + +# reduce 531 omitted + +# reduce 532 omitted + +# reduce 533 omitted + +# reduce 534 omitted + +# reduce 535 omitted + +# reduce 536 omitted + +# reduce 537 omitted + +# reduce 538 omitted + +# reduce 539 omitted + +# reduce 540 omitted + +# reduce 541 omitted + +# reduce 542 omitted + +# reduce 543 omitted + +# reduce 544 omitted + +# reduce 545 omitted + +# reduce 546 omitted + +def _reduce_547(val, _values, result) + result = val[1] + + result +end + +def _reduce_548(val, _values, result) + result = val[1] + + result +end + +# reduce 549 omitted + +# reduce 550 omitted + +# reduce 551 omitted + +def _reduce_552(val, _values, result) + yyerrok + + result +end + +# reduce 553 omitted + +# reduce 554 omitted + +# reduce 555 omitted + +def _reduce_556(val, _values, result) + result = nil + + result +end + +def _reduce_none(val, _values, result) + val[0] +end + + end # class MacRuby +end # module Parser diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/max_numparam_stack.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/max_numparam_stack.rb new file mode 100644 index 00000000..9a741c72 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/max_numparam_stack.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +module Parser + + # Holds p->max_numparam from parse.y + # + # @api private + class MaxNumparamStack + attr_reader :stack + + ORDINARY_PARAMS = -1 + + def initialize + @stack = [] + end + + def empty? + @stack.size == 0 + end + + def has_ordinary_params! + set(ORDINARY_PARAMS) + end + + def has_ordinary_params? + top == ORDINARY_PARAMS + end + + def has_numparams? + top && top > 0 + end + + def register(numparam) + set( [top, numparam].max ) + end + + def top + @stack.last[:value] + end + + def push(static:) + @stack.push(value: 0, static: static) + end + + def pop + @stack.pop[:value] + end + + private + + def set(value) + @stack.last[:value] = value + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/messages.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/messages.rb new file mode 100644 index 00000000..c82c6343 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/messages.rb @@ -0,0 +1,125 @@ +# frozen_string_literal: true + +module Parser + ## + # Diagnostic messages (errors, warnings and notices) that can be generated. + # + # @see Diagnostic + # + # @api public + # + MESSAGES = { + # Lexer errors + :unicode_point_too_large => 'invalid Unicode codepoint (too large)', + :invalid_escape => 'invalid escape character syntax', + :incomplete_escape => 'incomplete character syntax', + :invalid_hex_escape => 'invalid hex escape', + :invalid_unicode_escape => 'invalid Unicode escape', + :unterminated_unicode => 'unterminated Unicode escape', + :escape_eof => 'escape sequence meets end of file', + :string_eof => 'unterminated string meets end of file', + :regexp_options => 'unknown regexp options: %{options}', + :cvar_name => "`%{name}' is not allowed as a class variable name", + :ivar_name => "`%{name}' is not allowed as an instance variable name", + :gvar_name => "`%{name}' is not allowed as a global variable name", + :trailing_in_number => "trailing `%{character}' in number", + :empty_numeric => 'numeric literal without digits', + :invalid_octal => 'invalid octal digit', + :no_dot_digit_literal => 'no . floating literal anymore; put 0 before dot', + :bare_backslash => 'bare backslash only allowed before newline', + :unexpected => "unexpected `%{character}'", + :embedded_document => 'embedded document meets end of file (and they embark on a romantic journey)', + :heredoc_id_has_newline => 'here document identifier across newlines, never match', + :heredoc_id_ends_with_nl => 'here document identifier ends with a newline', + :unterminated_heredoc_id => 'unterminated heredoc id', + + # Lexer warnings + :invalid_escape_use => 'invalid character syntax; use ?%{escape}', + :ambiguous_literal => 'ambiguous first argument; put parentheses or a space even after the operator', + :ambiguous_regexp => "ambiguity between regexp and two divisions: wrap regexp in parentheses or add a space after `/' operator", + :ambiguous_prefix => "`%{prefix}' interpreted as argument prefix", + :triple_dot_at_eol => '... at EOL, should be parenthesized', + + # Parser errors + :nth_ref_alias => 'cannot define an alias for a back-reference variable', + :begin_in_method => 'BEGIN in method', + :backref_assignment => 'cannot assign to a back-reference variable', + :invalid_assignment => 'cannot assign to a keyword', + :module_name_const => 'class or module name must be a constant literal', + :unexpected_token => 'unexpected token %{token}', + :argument_const => 'formal argument cannot be a constant', + :argument_ivar => 'formal argument cannot be an instance variable', + :argument_gvar => 'formal argument cannot be a global variable', + :argument_cvar => 'formal argument cannot be a class variable', + :duplicate_argument => 'duplicate argument name', + :empty_symbol => 'empty symbol literal', + :odd_hash => 'odd number of entries for a hash', + :singleton_literal => 'cannot define a singleton method for a literal', + :dynamic_const => 'dynamic constant assignment', + :const_reassignment => 'constant re-assignment', + :module_in_def => 'module definition in method body', + :class_in_def => 'class definition in method body', + :unexpected_percent_str => '%{type}: unknown type of percent-literal', + :block_and_blockarg => 'both block argument and literal block are passed', + :masgn_as_condition => 'multiple assignment in conditional context', + :block_given_to_yield => 'block given to yield', + :invalid_regexp => '%{message}', + :invalid_return => 'Invalid return in class/module body', + :csend_in_lhs_of_masgn => '&. inside multiple assignment destination', + :cant_assign_to_numparam => 'cannot assign to numbered parameter %{name}', + :reserved_for_numparam => '%{name} is reserved for numbered parameter', + :ordinary_param_defined => 'ordinary parameter is defined', + :numparam_used_in_outer_scope => 'numbered parameter is already used in an outer scope', + :circular_argument_reference => 'circular argument reference %{var_name}', + :pm_interp_in_var_name => 'symbol literal with interpolation is not allowed', + :lvar_name => "`%{name}' is not allowed as a local variable name", + :undefined_lvar => "no such local variable: `%{name}'", + :duplicate_variable_name => 'duplicate variable name %{name}', + :duplicate_pattern_key => 'duplicate hash pattern key %{name}', + :endless_setter => 'setter method cannot be defined in an endless method definition', + :invalid_id_to_get => 'identifier %{identifier} is not valid to get', + :forward_arg_after_restarg => '... after rest argument', + :no_anonymous_blockarg => 'no anonymous block parameter', + :no_anonymous_restarg => 'no anonymous rest parameter', + :no_anonymous_kwrestarg => 'no anonymous keyword rest parameter', + :ambiguous_anonymous_restarg => 'anonymous rest parameter is also used within block', + :ambiguous_anonymous_kwrestarg => 'anonymous keyword rest parameter is also used within block', + :ambiguous_anonymous_blockarg => 'anonymous block parameter is also used within block', + + # Parser warnings + :useless_else => 'else without rescue is useless', + :duplicate_hash_key => 'key is duplicated and overwritten', + :ambiguous_it_call => '`it` calls without arguments refers to the first block param', + + # Parser errors that are not Ruby errors + :invalid_encoding => 'literal contains escape sequences incompatible with UTF-8', + + # Rewriter diagnostics + :invalid_action => 'cannot %{action}', + :clobbered => 'clobbered by: %{action}', + + # Rewriter diagnostics + :different_replacements => 'different replacements: %{replacement} vs %{other_replacement}', + :swallowed_insertions => 'this replacement:', + :swallowed_insertions_conflict => 'swallows some inner rewriting actions:', + :crossing_deletions => 'the deletion of:', + :crossing_deletions_conflict => 'is crossing:', + :crossing_insertions => 'the rewriting action on:', + :crossing_insertions_conflict => 'is crossing that on:', + }.freeze + + # @api private + module Messages + # Formats the message, returns a raw template if there's nothing to interpolate + # + # Code like `format("", {})` gives a warning, and so this method tries interpolating + # only if `arguments` hash is not empty. + # + # @api private + def self.compile(reason, arguments) + template = MESSAGES[reason] + return template if Hash === arguments && arguments.empty? + format(template, arguments) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/meta.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/meta.rb new file mode 100644 index 00000000..fcbaff16 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/meta.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +module Parser + # Parser metadata + module Meta + + # These are node types required by `Prism::Translation::Parser`, + # which has advanced syntax support ahead of the Parser gem. + PRISM_TRANSLATION_PARSER_NODE_TYPES = %i( + itarg itblock + ).freeze + private_constant :PRISM_TRANSLATION_PARSER_NODE_TYPES + + # All node types that parser can produce. Not all parser versions + # will be able to produce every possible node. + # Includes node types that are only emitted by the prism parser translator. + NODE_TYPES = ( + %i( + true false nil int float str dstr + sym dsym xstr regopt regexp array splat + pair kwsplat hash irange erange self + lvar ivar cvar gvar const defined? lvasgn + ivasgn cvasgn gvasgn casgn mlhs masgn + op_asgn and_asgn ensure rescue arg_expr + or_asgn back_ref nth_ref + match_with_lvasgn match_current_line + module class sclass def defs undef alias args + cbase arg optarg restarg blockarg block_pass kwarg kwoptarg + kwrestarg kwnilarg send csend super zsuper yield block + and not or if when case while until while_post + until_post for break next redo return resbody + kwbegin begin retry preexe postexe iflipflop eflipflop + shadowarg complex rational __FILE__ __LINE__ __ENCODING__ + ident lambda indexasgn index procarg0 + restarg_expr blockarg_expr + objc_kwarg objc_restarg objc_varargs + numargs numblock forward_args forwarded_args forward_arg + case_match in_match in_pattern + match_var pin match_alt match_as match_rest + array_pattern match_with_trailing_comma array_pattern_with_tail + hash_pattern const_pattern if_guard unless_guard match_nil_pattern + empty_else find_pattern kwargs + match_pattern_p match_pattern + forwarded_restarg forwarded_kwrestarg + ) + PRISM_TRANSLATION_PARSER_NODE_TYPES + ).to_set.freeze + end # Meta +end # Parser diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/rewriter.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/rewriter.rb new file mode 100644 index 00000000..f81ebb18 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/rewriter.rb @@ -0,0 +1,105 @@ +# frozen_string_literal: true + +module Parser + + ## + # {Parser::Rewriter} is deprecated. Use {Parser::TreeRewriter} instead. + # It has a backwards compatible API and uses {Parser::Source::TreeRewriter} + # instead of {Parser::Source::Rewriter}. + # Please check the documentation for {Parser::Source::Rewriter} for details. + # + # @api public + # @deprecated Use {Parser::TreeRewriter} + # + class Rewriter < Parser::AST::Processor + ## + # Rewrites the AST/source buffer and returns a String containing the new + # version. + # + # @param [Parser::Source::Buffer] source_buffer + # @param [Parser::AST::Node] ast + # @return [String] + # + def rewrite(source_buffer, ast) + @source_rewriter = Source::Rewriter.new(source_buffer) + + process(ast) + + @source_rewriter.process + end + + ## + # Returns `true` if the specified node is an assignment node, returns false + # otherwise. + # + # @param [Parser::AST::Node] node + # @return [Boolean] + # + def assignment?(node) + [:lvasgn, :ivasgn, :gvasgn, :cvasgn, :casgn].include?(node.type) + end + + ## + # Removes the source range. + # + # @param [Parser::Source::Range] range + # + def remove(range) + @source_rewriter.remove(range) + end + + ## + # Wraps the given source range with the given values. + # + # @param [Parser::Source::Range] range + # @param [String] content + # + def wrap(range, before, after) + @source_rewriter.wrap(range, before, after) + end + + ## + # Inserts new code before the given source range. + # + # @param [Parser::Source::Range] range + # @param [String] content + # + def insert_before(range, content) + @source_rewriter.insert_before(range, content) + end + + ## + # Inserts new code after the given source range. + # + # @param [Parser::Source::Range] range + # @param [String] content + # + def insert_after(range, content) + @source_rewriter.insert_after(range, content) + end + + ## + # Replaces the code of the source range `range` with `content`. + # + # @param [Parser::Source::Range] range + # @param [String] content + # + def replace(range, content) + @source_rewriter.replace(range, content) + end + + DEPRECATION_WARNING = [ + 'Parser::Rewriter is deprecated.', + 'Please update your code to use Parser::TreeRewriter instead' + ].join("\n").freeze + + extend Deprecation + + def initialize(*) + self.class.warn_of_deprecation + Source::Rewriter.warned_of_deprecation = true + super + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby18.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby18.rb new file mode 100644 index 00000000..5b70ba25 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby18.rb @@ -0,0 +1,9272 @@ +# -*- encoding:utf-8; warn-indent:false; frozen_string_literal: true -*- +# +# DO NOT MODIFY!!!! +# This file is automatically generated by Racc 1.8.1 +# from Racc grammar file "ruby18.y". +# + +require 'racc/parser.rb' + + +require_relative '../parser' + +module Parser + class Ruby18 < Parser::Base + + + def version + 18 + end + + def default_encoding + Encoding::BINARY + end + + def local_push + @static_env.extend_static + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + end + + def local_pop + @static_env.unextend + @lexer.cmdarg.pop + @lexer.cond.pop + end +##### State transition tables begin ### + +racc_action_table = [ + -482, 197, 198, 197, 198, 491, 816, -482, -482, -482, + 513, 580, 580, -482, -482, -80, -482, 433, 581, 581, + 491, 560, 533, -87, 560, -482, 504, 491, -86, 97, + 505, -431, 397, 197, 198, -482, -482, -82, -482, -482, + -482, -482, -482, 491, 491, 497, 465, 498, -84, -83, + -81, 661, 660, 664, 663, 559, 188, -61, 559, 715, + 293, 293, 189, -482, -482, -482, -482, -482, -482, -482, + -482, -482, -482, -482, -482, -482, -482, -80, -87, -482, + -482, -482, 261, 548, 532, 724, -74, -482, 190, 101, + -482, 293, -86, 623, 100, -482, -69, -482, 191, -482, + -482, -482, -482, -482, -482, -482, -277, -482, -482, -482, + 192, -478, 512, -277, -277, -277, 101, -72, 490, -277, + -277, 100, -277, -482, -482, -79, -75, 236, -482, -83, + -78, 101, 101, 490, 623, -76, 100, 100, 101, -74, + 490, -277, -277, 100, -277, -277, -277, -277, -277, -74, + -76, -75, -73, 692, 101, 101, 490, 490, 623, 100, + 100, -85, 608, 560, 498, 260, 261, -74, 693, -277, + -277, -277, -277, -277, -277, -277, -277, -277, -277, -277, + -277, -277, -277, 261, 560, -277, -277, -277, -74, 551, + 101, -74, 622, -277, 74, 100, -277, 559, -76, -82, + 196, -277, 75, -277, 523, -277, -277, -277, -277, -277, + -277, -277, -272, -277, -84, -277, -76, 284, 559, -272, + -272, -272, 816, -479, -272, -272, -272, 256, -272, -277, + -277, 101, -77, 622, -277, -85, 100, -76, -272, -272, + -76, 197, 198, -79, 256, -475, -87, -272, -272, 260, + -272, -272, -272, -272, -272, 101, 101, 622, 286, 287, + 100, 100, 523, -77, 525, 524, 260, 661, 660, 664, + 663, 463, 464, 285, 675, -272, -272, -272, -272, -272, + -272, -272, -272, -272, -272, -272, -272, -272, -272, 293, + -476, -272, -272, -272, -419, 101, -272, 770, 351, -272, + 100, -419, -272, -272, -431, -272, -475, -272, 363, -272, + -419, -272, -272, -272, -272, -272, -272, -272, -226, -272, + 465, -272, 525, 524, 521, -226, -226, -226, -475, 543, + -226, -226, -226, -482, -226, -272, -272, -272, -272, -423, + -272, 523, 253, -81, -226, 194, -423, -72, 396, 254, + -80, -476, 195, -226, -226, -423, -226, -226, -226, -226, + -226, 193, -419, -78, 479, -482, -86, 478, -478, -419, + 398, -226, -74, -476, 523, -82, 544, 682, -226, -226, + -226, 399, -482, -226, -226, -226, -423, -226, -479, -482, + 428, 360, -226, -423, -478, 362, 361, -226, -482, -226, + 523, 525, 524, 526, 256, -226, -226, -226, 523, -226, + -226, -226, -226, -226, -482, 430, -482, -478, -482, -76, + -73, -482, -84, -81, -478, -429, -478, -226, 433, -478, + -482, -319, -429, -478, 525, 524, 528, -479, -319, 479, + 217, -226, 481, -226, -479, -226, -226, -319, -482, -479, + 101, -478, -226, -479, 438, 100, -428, 256, -226, 393, + 525, 524, 529, -428, 197, 198, 394, -482, 525, 524, + 534, -479, 214, 101, -482, 395, 216, 215, 100, -478, + -226, -427, 657, -482, 655, 654, 653, 656, -427, -478, + -478, -478, -60, -478, -226, 101, -226, -478, -478, -226, + 100, -482, -478, 453, -478, -478, -478, -478, -478, -478, + -478, 479, 197, 198, 484, -478, -478, -478, -478, -478, + -478, -478, 217, 736, 608, -424, -425, 661, 660, 664, + 663, -478, -424, -425, -478, -478, -478, -478, -478, -478, + -478, -478, -478, -478, -426, -478, -478, -478, -478, -478, + -430, -426, 664, 663, 214, 459, 518, -430, 216, 215, + 212, 213, 460, 519, 479, 454, -430, 481, 455, -478, + 694, 458, -478, -478, 461, -478, -478, 736, 608, -478, + -271, -478, 265, -478, 293, -478, 657, -271, 655, 654, + 653, 656, 256, -478, 466, 467, -271, 217, -478, -478, + -478, -478, -478, -478, 473, 474, 293, -478, -478, -479, + -479, -479, 217, -479, 483, 486, -83, -479, -479, 353, + 502, 503, -479, 647, -479, -479, -479, -479, -479, -479, + -479, 661, 660, 664, 663, -479, -479, -479, -479, -479, + -479, -479, 217, 537, 214, 538, 540, -259, 216, 215, + 542, -479, 256, 217, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, 217, -479, -479, -479, -479, -479, + 468, 217, 217, 570, 214, 500, 577, 469, 216, 215, + 212, 213, 501, 293, 582, 236, 395, 592, 593, -479, + 551, 499, -479, -479, -69, -479, -479, 594, 471, -479, + 509, -479, 608, -479, 293, -479, 657, 507, 655, 654, + 653, 656, 618, -479, 498, 626, 508, 674, -479, -479, + -479, -479, -479, -479, 677, -278, 438, -479, -479, 67, + 68, 64, -278, 51, 438, 695, -85, 56, 57, 706, + 433, -278, 60, 433, 58, 59, 61, 23, 24, 65, + 66, 661, 660, 664, 663, 22, 28, 27, 90, 89, + 91, 92, 669, 670, 17, 671, 95, 96, 245, 539, + 709, 41, 710, 717, 94, 93, 84, 50, 86, 85, + 88, 87, 95, 96, 719, 82, 83, 38, 39, 37, + 217, 221, 226, 227, 228, 223, 225, 233, 234, 229, + 230, -278, 210, 211, -279, 723, 231, 232, -278, 202, + 256, -279, 206, 256, 217, 52, 53, -278, 217, 54, + -279, 726, 214, -259, 220, 40, 216, 215, 212, 213, + 224, 222, 218, 18, 219, 730, 732, 608, 81, 74, + 76, 77, 78, 79, 740, 741, 742, 75, 80, 745, + 101, 235, 747, -215, -277, 100, 67, 68, 64, 7, + 51, -277, 751, 755, 56, 57, -479, 757, 760, 60, + -277, 58, 59, 61, 23, 24, 65, 66, 761, 762, + 763, 765, 22, 28, 27, 90, 89, 91, 92, -260, + 771, 17, 103, 104, 105, 106, 107, 6, 41, 8, + 9, 94, 93, 84, 50, 86, 85, 88, 87, 95, + 96, -277, 82, 83, 38, 39, 37, -430, -277, 825, + 779, -271, -278, -479, -430, -279, 826, -277, -271, -278, + 780, 570, -279, -430, 570, 824, 36, -271, -278, 30, + 256, -279, 52, 53, 256, 236, 54, -277, 32, 570, + 792, 793, 40, 657, -277, 655, 654, 653, 656, -479, + 18, 794, 799, -277, 801, 81, 74, 76, 77, 78, + 79, 807, 809, 293, 75, 80, 67, 68, 64, 820, + 51, 827, 353, 828, 56, 57, 829, 831, 832, 60, + 647, 58, 59, 61, 248, 249, 65, 66, 661, 660, + 664, 663, 247, 277, 281, 90, 89, 91, 92, 103, + 104, 105, 106, 107, 834, 837, 841, 842, 278, 848, + 849, 94, 93, 84, 50, 86, 85, 88, 87, 95, + 96, 850, 82, 83, 760, 760, 282, 217, 221, 226, + 227, 228, 223, 225, 233, 234, 229, 230, 761, -499, + -499, 863, 570, 231, 232, 570, 774, 473, 876, 206, + 877, 878, 52, 53, 882, 885, 54, 760, 887, 214, + 888, 220, 570, 216, 215, 212, 213, 224, 222, 218, + 570, 219, 570, nil, nil, 81, 74, 76, 77, 78, + 79, nil, nil, nil, 75, 80, nil, 67, 68, 64, + 777, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + 103, 104, 105, 106, 107, nil, nil, 539, nil, 278, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, nil, nil, 282, 217, 221, + 226, 227, 228, 223, 225, 233, 234, 229, 230, nil, + 210, 211, nil, nil, 231, 232, nil, 774, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + 214, nil, 220, nil, 216, 215, 212, 213, 224, 222, + 218, nil, 219, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, nil, nil, 235, + nil, 857, 5, 67, 68, 64, 7, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 23, 24, 65, 66, nil, nil, nil, nil, 22, + 28, 27, 90, 89, 91, 92, nil, nil, 17, nil, + nil, nil, nil, nil, 6, 41, 8, 9, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, 217, 221, 226, 227, 228, 223, + 225, 233, 234, 229, 230, nil, -499, -499, nil, nil, + 231, 232, nil, 36, nil, nil, 30, nil, nil, 52, + 53, nil, nil, 54, nil, 32, 214, nil, 220, 40, + 216, 215, 212, 213, 224, 222, 218, 18, 219, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 5, 67, 68, 64, 7, 51, nil, + nil, nil, 56, 57, nil, nil, nil, 60, nil, 58, + 59, 61, 23, 24, 65, 66, nil, nil, nil, nil, + 22, 28, 27, 90, 89, 91, 92, nil, nil, 17, + nil, nil, nil, nil, nil, 6, 41, 8, 9, 94, + 93, 84, 50, 86, 85, 88, 87, 95, 96, nil, + 82, 83, 38, 39, 37, 217, -499, -499, -499, -499, + 223, 225, nil, nil, -499, -499, nil, nil, nil, nil, + nil, 231, 232, nil, 36, nil, nil, 267, nil, nil, + 52, 53, nil, nil, 54, nil, 32, 214, nil, 220, + 40, 216, 215, 212, 213, 224, 222, 218, 18, 219, + nil, nil, nil, 81, 74, 76, 77, 78, 79, nil, + nil, nil, 75, 80, 5, 67, 68, 64, 7, 51, + nil, nil, nil, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 23, 24, 65, 66, nil, nil, nil, + nil, 22, 28, 27, 90, 89, 91, 92, nil, nil, + 17, nil, nil, nil, nil, nil, 6, 41, 8, 9, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, 217, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 231, 232, nil, 36, nil, nil, 30, nil, + nil, 52, 53, nil, nil, 54, nil, 32, 214, nil, + 220, 40, 216, 215, 212, 213, nil, nil, 218, 18, + 219, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, 5, 67, 68, 64, 7, + 51, nil, nil, nil, 56, 57, nil, nil, nil, 60, + nil, 58, 59, 61, 23, 24, 65, 66, nil, nil, + nil, nil, 22, 28, 27, 90, 89, 91, 92, nil, + nil, 17, nil, nil, nil, nil, nil, 6, 41, 8, + 9, 94, 93, 84, 50, 86, 85, 88, 87, 95, + 96, nil, 82, 83, 38, 39, 37, 217, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 231, 232, nil, 36, nil, nil, 30, + nil, nil, 52, 53, nil, nil, 54, nil, 32, 214, + nil, 220, 40, 216, 215, 212, 213, nil, nil, 218, + 18, 219, nil, nil, nil, 81, 74, 76, 77, 78, + 79, nil, nil, nil, 75, 80, 5, 67, 68, 64, + 7, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 23, 24, 65, 66, nil, + nil, nil, nil, 22, 28, 27, 90, 89, 91, 92, + nil, nil, 17, nil, nil, nil, nil, nil, 6, 41, + 8, 9, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, 217, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 231, 232, nil, 36, nil, nil, + 30, nil, nil, 52, 53, nil, nil, 54, nil, 32, + 214, nil, 220, 40, 216, 215, 212, 213, nil, nil, + 218, 18, 219, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 5, 67, 68, + 64, 7, 51, nil, nil, nil, 56, 57, nil, nil, + nil, 60, nil, 58, 59, 61, 23, 24, 65, 66, + nil, nil, nil, nil, 22, 28, 27, 90, 89, 91, + 92, nil, nil, 17, nil, nil, nil, nil, nil, 6, + 41, 8, 9, 94, 93, 84, 50, 86, 85, 88, + 87, 95, 96, nil, 82, 83, 38, 39, 37, 217, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 231, 232, nil, 36, nil, + nil, 30, nil, nil, 52, 53, nil, nil, 54, nil, + 32, 214, nil, 220, 40, 216, 215, 212, 213, nil, + nil, 218, 18, 219, nil, nil, nil, 81, 74, 76, + 77, 78, 79, nil, nil, nil, 75, 80, 5, 67, + 68, 64, 7, 51, nil, nil, nil, 56, 57, nil, + nil, nil, 60, nil, 58, 59, 61, 23, 24, 65, + 66, nil, nil, nil, nil, 22, 28, 27, 90, 89, + 91, 92, nil, nil, 17, nil, nil, nil, nil, nil, + 6, 41, 8, 9, 94, 93, 84, 50, 86, 85, + 88, 87, 95, 96, nil, 82, 83, 38, 39, 37, + 217, -499, -499, -499, -499, 223, 225, nil, nil, -499, + -499, nil, nil, nil, nil, nil, 231, 232, nil, 36, + nil, nil, 267, nil, nil, 52, 53, nil, nil, 54, + nil, 32, 214, nil, 220, 40, 216, 215, 212, 213, + 224, 222, 218, 18, 219, nil, nil, nil, 81, 74, + 76, 77, 78, 79, nil, nil, nil, 75, 80, 5, + 67, 68, 64, 7, 51, nil, nil, nil, 56, 57, + nil, nil, nil, 60, nil, 58, 59, 61, 23, 24, + 65, 66, nil, nil, nil, nil, 22, 28, 27, 90, + 89, 91, 92, nil, nil, 17, nil, nil, nil, nil, + nil, 6, 41, 8, 9, 94, 93, 84, 50, 86, + 85, 88, 87, 95, 96, nil, 82, 83, 38, 39, + 37, 217, -499, -499, -499, -499, 223, 225, nil, nil, + -499, -499, nil, nil, nil, nil, nil, 231, 232, nil, + 36, nil, nil, 267, nil, nil, 52, 53, nil, nil, + 54, nil, 32, 214, nil, 220, 40, 216, 215, 212, + 213, 224, 222, 218, 18, 219, nil, nil, nil, 81, + 74, 76, 77, 78, 79, nil, nil, nil, 75, 80, + 5, 67, 68, 64, 7, 51, nil, nil, nil, 56, + 57, nil, nil, nil, 60, nil, 58, 59, 61, 23, + 24, 65, 66, nil, nil, nil, nil, 22, 28, 27, + 90, 89, 91, 92, nil, nil, 17, nil, nil, nil, + nil, nil, 6, 41, 8, 9, 94, 93, 84, 50, + 86, 85, 88, 87, 95, 96, nil, 82, 83, 38, + 39, 37, 217, -499, -499, -499, -499, 223, 225, nil, + nil, -499, -499, nil, nil, nil, nil, nil, 231, 232, + nil, 36, nil, nil, 30, nil, nil, 52, 53, nil, + nil, 54, nil, 32, 214, nil, 220, 40, 216, 215, + 212, 213, 224, 222, 218, 18, 219, nil, nil, nil, + 81, 74, 76, 77, 78, 79, nil, nil, nil, 75, + 80, 5, 67, 68, 64, 7, 51, nil, nil, nil, + 56, 57, nil, nil, nil, 60, nil, 58, 59, 61, + 23, 24, 65, 66, nil, nil, nil, nil, 22, 28, + 27, 90, 89, 91, 92, nil, nil, 17, nil, nil, + nil, nil, nil, 6, 41, 8, 9, 94, 93, 84, + 50, 86, 85, 88, 87, 95, 96, nil, 82, 83, + 38, 39, 37, 217, -499, -499, -499, -499, 223, 225, + nil, nil, -499, -499, nil, nil, nil, nil, nil, 231, + 232, nil, 36, nil, nil, 30, nil, nil, 52, 53, + nil, nil, 54, nil, 32, 214, nil, 220, 40, 216, + 215, 212, 213, 224, 222, 218, 18, 219, nil, nil, + nil, 81, 74, 76, 77, 78, 79, nil, nil, nil, + 75, 80, 5, 67, 68, 64, 7, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 23, 24, 65, 66, nil, nil, nil, nil, 22, + 28, 27, 90, 89, 91, 92, nil, nil, 17, nil, + nil, nil, nil, nil, 6, 41, 8, 9, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, 217, -499, -499, -499, -499, 223, + 225, nil, nil, -499, -499, nil, nil, nil, nil, nil, + 231, 232, nil, 36, nil, nil, 30, nil, nil, 52, + 53, nil, nil, 54, nil, 32, 214, nil, 220, 40, + 216, 215, 212, 213, 224, 222, 218, 18, 219, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 5, 67, 68, 64, 7, 51, nil, + nil, nil, 56, 57, nil, nil, nil, 60, nil, 58, + 59, 61, 23, 24, 65, 66, nil, nil, nil, nil, + 22, 28, 27, 90, 89, 91, 92, nil, nil, 17, + nil, nil, nil, nil, nil, 6, 41, 8, 9, 94, + 93, 84, 50, 86, 85, 88, 87, 95, 96, nil, + 82, 83, 38, 39, 37, 217, 221, 226, 227, 228, + 223, 225, nil, nil, 229, 230, nil, nil, nil, nil, + nil, 231, 232, nil, 36, nil, nil, 30, nil, nil, + 52, 53, nil, nil, 54, nil, 32, 214, nil, 220, + 40, 216, 215, 212, 213, 224, 222, 218, 18, 219, + nil, nil, nil, 81, 74, 76, 77, 78, 79, nil, + nil, nil, 75, 80, 5, 67, 68, 64, 7, 51, + nil, nil, nil, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 23, 24, 65, 66, nil, nil, nil, + nil, 22, 28, 27, 90, 89, 91, 92, nil, nil, + 17, nil, nil, nil, nil, nil, 6, 41, 8, 9, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, 217, 221, 226, 227, + 228, 223, 225, 233, nil, 229, 230, nil, nil, nil, + nil, nil, 231, 232, nil, 36, nil, nil, 30, nil, + nil, 52, 53, nil, nil, 54, nil, 32, 214, nil, + 220, 40, 216, 215, 212, 213, 224, 222, 218, 18, + 219, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, 5, 67, 68, 64, 7, + 51, nil, nil, nil, 56, 57, nil, nil, nil, 60, + nil, 58, 59, 61, 23, 24, 65, 66, nil, nil, + nil, nil, 22, 28, 27, 90, 89, 91, 92, nil, + nil, 17, nil, nil, nil, nil, nil, 6, 41, 8, + 9, 94, 93, 84, 50, 86, 85, 88, 87, 95, + 96, nil, 82, 83, 38, 39, 37, 217, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 231, 232, nil, 36, nil, nil, 30, + nil, nil, 52, 53, nil, nil, 54, nil, 32, 214, + nil, 220, 40, 216, 215, 212, 213, nil, nil, nil, + 18, nil, nil, nil, nil, 81, 74, 76, 77, 78, + 79, nil, nil, nil, 75, 80, 5, 67, 68, 64, + 7, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 23, 24, 65, 66, nil, + nil, nil, nil, 22, 28, 27, 90, 89, 91, 92, + nil, nil, 17, nil, nil, nil, nil, nil, 6, 41, + 8, 9, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, 217, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 231, 232, nil, 36, nil, nil, + 30, nil, nil, 52, 53, nil, nil, 54, nil, 32, + 214, nil, 220, 40, 216, 215, 212, 213, nil, nil, + nil, 18, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 5, 67, 68, + 64, 7, 51, nil, nil, nil, 56, 57, nil, nil, + nil, 60, nil, 58, 59, 61, 23, 24, 65, 66, + nil, nil, nil, nil, 22, 28, 27, 90, 89, 91, + 92, nil, nil, 17, nil, nil, nil, nil, nil, 6, + 41, 8, 9, 94, 93, 84, 50, 86, 85, 88, + 87, 95, 96, nil, 82, 83, 38, 39, 37, 217, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 231, 232, nil, 36, nil, + nil, 30, nil, nil, 52, 53, nil, nil, 54, nil, + 32, 214, nil, nil, 40, 216, 215, 212, 213, nil, + nil, nil, 18, nil, nil, nil, nil, 81, 74, 76, + 77, 78, 79, nil, nil, nil, 75, 80, 5, 67, + 68, 64, 7, 51, nil, nil, nil, 56, 57, nil, + nil, nil, 60, nil, 58, 59, 61, 23, 24, 65, + 66, nil, nil, nil, nil, 22, 28, 27, 90, 89, + 91, 92, nil, nil, 17, nil, nil, nil, nil, nil, + 6, 41, 8, 9, 94, 93, 84, 50, 86, 85, + 88, 87, 95, 96, nil, 82, 83, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 36, + nil, nil, 30, nil, nil, 52, 53, nil, nil, 54, + nil, 32, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 18, nil, nil, nil, nil, 81, 74, + 76, 77, 78, 79, nil, nil, nil, 75, 80, 5, + 67, 68, 64, 7, 51, nil, nil, nil, 56, 57, + nil, nil, nil, 60, nil, 58, 59, 61, 23, 24, + 65, 66, nil, nil, nil, nil, 22, 28, 27, 90, + 89, 91, 92, nil, nil, 17, nil, nil, nil, nil, + nil, 6, 41, 8, 9, 94, 93, 84, 50, 86, + 85, 88, 87, 95, 96, nil, 82, 83, 38, 39, + 37, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 36, nil, nil, 30, nil, nil, 52, 53, nil, nil, + 54, nil, 32, nil, nil, nil, 40, nil, nil, nil, + nil, nil, nil, nil, 18, nil, nil, nil, nil, 81, + 74, 76, 77, 78, 79, nil, nil, nil, 75, 80, + 5, 67, 68, 64, 7, 51, nil, nil, nil, 56, + 57, nil, nil, nil, 60, nil, 58, 59, 61, 23, + 24, 65, 66, nil, nil, nil, nil, 22, 28, 27, + 90, 89, 91, 92, nil, nil, 17, nil, nil, nil, + nil, nil, 6, 41, 8, 9, 94, 93, 84, 50, + 86, 85, 88, 87, 95, 96, nil, 82, 83, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 36, nil, nil, 30, nil, nil, 52, 53, nil, + nil, 54, nil, 32, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 18, nil, nil, nil, nil, + 81, 74, 76, 77, 78, 79, nil, nil, nil, 75, + 80, 5, 67, 68, 64, 7, 51, nil, nil, nil, + 56, 57, nil, nil, nil, 60, nil, 58, 59, 61, + 23, 24, 65, 66, nil, nil, nil, nil, 22, 28, + 27, 90, 89, 91, 92, nil, nil, 17, nil, nil, + nil, nil, nil, 6, 41, 8, 9, 94, 93, 84, + 50, 86, 85, 88, 87, 95, 96, nil, 82, 83, + 38, 39, 37, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 36, nil, nil, 30, nil, nil, 52, 53, + nil, nil, 54, nil, 32, nil, nil, nil, 40, nil, + nil, nil, nil, nil, nil, nil, 18, nil, nil, nil, + nil, 81, 74, 76, 77, 78, 79, nil, nil, nil, + 75, 80, 5, 67, 68, 64, 7, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 23, 24, 65, 66, nil, nil, nil, nil, 22, + 28, 27, 90, 89, 91, 92, nil, nil, 17, nil, + nil, nil, nil, nil, 6, 41, 8, 9, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 36, nil, nil, 30, nil, nil, 52, + 53, nil, nil, 54, nil, 32, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 18, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 5, 67, 68, 64, 7, 51, nil, + nil, nil, 56, 57, nil, nil, nil, 60, nil, 58, + 59, 61, 23, 24, 65, 66, nil, nil, nil, nil, + 22, 28, 27, 90, 89, 91, 92, nil, nil, 17, + nil, nil, nil, nil, nil, 6, 41, 8, 9, 94, + 93, 84, 50, 86, 85, 88, 87, 95, 96, nil, + 82, 83, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 36, nil, nil, 30, nil, nil, + 52, 53, nil, nil, 54, nil, 32, nil, nil, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 18, nil, + nil, nil, nil, 81, 74, 76, 77, 78, 79, nil, + nil, nil, 75, 80, 5, 67, 68, 64, 7, 51, + nil, nil, nil, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 23, 24, 65, 66, nil, nil, nil, + nil, 22, 28, 27, 90, 89, 91, 92, nil, nil, + 17, nil, nil, nil, nil, nil, 6, 41, 8, 9, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 36, nil, nil, 30, nil, + nil, 52, 53, nil, nil, 54, nil, 32, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 18, + nil, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, 5, 67, 68, 64, 7, + 51, nil, nil, nil, 56, 57, nil, nil, nil, 60, + nil, 58, 59, 61, 23, 24, 65, 66, nil, nil, + nil, nil, 22, 28, 27, 90, 89, 91, 92, nil, + nil, 17, nil, nil, nil, nil, nil, 6, 41, 8, + 9, 94, 93, 84, 50, 86, 85, 88, 87, 95, + 96, nil, 82, 83, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 36, nil, nil, 30, + nil, nil, 52, 53, nil, nil, 54, nil, 32, nil, + nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 18, nil, nil, nil, nil, 81, 74, 76, 77, 78, + 79, nil, nil, nil, 75, 80, 5, 67, 68, 64, + 7, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 23, 24, 65, 66, nil, + nil, nil, nil, 22, 28, 27, 90, 89, 91, 92, + nil, nil, 17, nil, nil, nil, nil, nil, 6, 41, + 8, 9, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 36, nil, nil, + 30, nil, nil, 52, 53, nil, nil, 54, nil, 32, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 18, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 5, 67, 68, + 64, 7, 51, nil, nil, nil, 56, 57, nil, nil, + nil, 60, nil, 58, 59, 61, 23, 24, 65, 66, + nil, nil, nil, nil, 22, 28, 27, 90, 89, 91, + 92, nil, nil, 17, nil, nil, nil, nil, nil, 6, + 41, 8, 9, 94, 93, 84, 50, 86, 85, 88, + 87, 95, 96, nil, 82, 83, 38, 39, 37, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 36, nil, + nil, 30, nil, nil, 52, 53, nil, nil, 54, nil, + 32, nil, nil, nil, 40, nil, nil, nil, nil, nil, + nil, nil, 18, nil, nil, nil, nil, 81, 74, 76, + 77, 78, 79, nil, nil, nil, 75, 80, 5, 67, + 68, 64, 7, 51, nil, nil, nil, 56, 57, nil, + nil, nil, 60, nil, 58, 59, 61, 23, 24, 65, + 66, nil, nil, nil, nil, 22, 28, 27, 90, 89, + 91, 92, nil, nil, 17, nil, nil, nil, nil, nil, + 6, 41, 8, 9, 94, 93, 84, 50, 86, 85, + 88, 87, 95, 96, nil, 82, 83, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 36, + nil, nil, 30, nil, nil, 52, 53, nil, nil, 54, + nil, 32, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 18, nil, nil, nil, nil, 81, 74, + 76, 77, 78, 79, nil, nil, nil, 75, 80, 5, + 67, 68, 64, 7, 51, nil, nil, nil, 56, 57, + nil, nil, nil, 60, nil, 58, 59, 61, 23, 24, + 65, 66, nil, nil, nil, nil, 22, 28, 27, 90, + 89, 91, 92, nil, nil, 17, nil, nil, nil, nil, + nil, 6, 41, 8, 9, 94, 93, 84, 50, 86, + 85, 88, 87, 95, 96, nil, 82, 83, 38, 39, + 37, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 36, nil, nil, 30, nil, nil, 52, 53, nil, nil, + 54, nil, 32, nil, nil, nil, 40, nil, nil, nil, + nil, nil, nil, nil, 18, nil, nil, nil, nil, 81, + 74, 76, 77, 78, 79, nil, nil, nil, 75, 80, + 5, 67, 68, 64, 7, 51, nil, nil, nil, 56, + 57, nil, nil, nil, 60, nil, 58, 59, 61, 23, + 24, 65, 66, nil, nil, nil, nil, 22, 28, 27, + 90, 89, 91, 92, nil, nil, 17, nil, nil, nil, + nil, nil, 6, 41, 8, 9, 94, 93, 84, 50, + 86, 85, 88, 87, 95, 96, nil, 82, 83, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 36, nil, nil, 30, nil, nil, 52, 53, nil, + nil, 54, nil, 32, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 18, nil, nil, nil, nil, + 81, 74, 76, 77, 78, 79, nil, nil, nil, 75, + 80, 67, 68, 64, 7, 51, nil, nil, nil, 56, + 57, nil, nil, nil, 60, nil, 58, 59, 61, 23, + 24, 65, 66, nil, nil, nil, nil, 22, 28, 27, + 90, 89, 91, 92, nil, nil, 17, nil, nil, nil, + nil, nil, 6, 41, 8, 9, 94, 93, 84, 50, + 86, 85, 88, 87, 95, 96, nil, 82, 83, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 36, nil, nil, 30, nil, nil, 52, 53, nil, + nil, 54, nil, 32, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 18, nil, nil, nil, nil, + 81, 74, 76, 77, 78, 79, nil, nil, nil, 75, + 80, 155, 166, 156, 179, 152, 172, 162, 161, 182, + 183, 177, 160, 159, 154, 180, 184, 185, 164, 153, + 167, 171, 173, 165, 158, nil, nil, 174, 181, 176, + 175, 168, 178, 163, 151, 170, 169, nil, nil, nil, + nil, nil, 150, 157, 148, 149, 146, 147, 111, 113, + 110, nil, 112, nil, nil, nil, nil, nil, nil, 141, + 142, nil, 139, 123, 124, 125, nil, 128, 130, nil, + nil, 126, nil, nil, nil, nil, 143, 144, 131, 132, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 136, 135, nil, 122, 140, 138, 137, + 133, 134, 129, 127, 120, nil, 121, nil, nil, 145, + 81, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 80, 155, 166, 156, 179, 152, 172, 162, 161, 182, + 183, 177, 160, 159, 154, 180, 184, 185, 164, 153, + 167, 171, 173, 165, 158, nil, nil, 174, 181, 176, + 175, 168, 178, 163, 151, 170, 169, nil, nil, nil, + nil, nil, 150, 157, 148, 149, 146, 147, 111, 113, + nil, nil, 112, nil, nil, nil, nil, nil, nil, 141, + 142, nil, 139, 123, 124, 125, nil, 128, 130, nil, + nil, 126, nil, nil, nil, nil, 143, 144, 131, 132, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 136, 135, nil, 122, 140, 138, 137, + 133, 134, 129, 127, 120, nil, 121, nil, nil, 145, + 81, nil, nil, 67, 68, 64, nil, 51, nil, nil, + 80, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 23, 24, 65, 66, nil, nil, nil, nil, 22, + 28, 27, 90, 89, 91, 92, nil, nil, 17, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 18, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 23, 24, 65, 66, nil, nil, nil, nil, 22, + 28, 27, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 28, 27, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, 243, nil, 245, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 28, 27, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, 243, nil, 245, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 28, 27, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, 243, nil, 245, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, -249, -249, -249, nil, -249, nil, nil, + nil, -249, -249, nil, nil, nil, -249, nil, -249, -249, + -249, -249, -249, -249, -249, nil, nil, nil, nil, -249, + -249, -249, -249, -249, -249, -249, nil, nil, nil, nil, + nil, nil, nil, nil, nil, -249, nil, nil, -249, -249, + -249, -249, -249, -249, -249, -249, -249, -249, nil, -249, + -249, -249, -249, -249, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, -249, nil, nil, -249, 256, nil, -249, + -249, nil, nil, -249, nil, -249, nil, -249, nil, -249, + nil, nil, nil, nil, nil, nil, nil, -249, nil, nil, + nil, nil, -249, -249, -249, -249, -249, -249, nil, nil, + nil, -249, -249, -249, -249, -249, nil, -249, nil, nil, + nil, -249, -249, nil, nil, nil, -249, nil, -249, -249, + -249, -249, -249, -249, -249, nil, nil, nil, nil, -249, + -249, -249, -249, -249, -249, -249, nil, nil, nil, nil, + nil, nil, nil, nil, nil, -249, nil, nil, -249, -249, + -249, -249, -249, -249, -249, -249, -249, -249, nil, -249, + -249, -249, -249, -249, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, -249, nil, nil, -249, 265, nil, -249, + -249, nil, nil, -249, nil, -249, nil, -249, nil, -249, + nil, nil, nil, nil, nil, nil, nil, -249, nil, nil, + nil, nil, -249, -249, -249, -249, -249, -249, nil, nil, + nil, -249, -249, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 278, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, nil, nil, 282, nil, 217, 221, 226, 227, 228, + 223, 225, 233, 234, 229, 230, nil, 210, 211, nil, + nil, 231, 232, 275, nil, nil, 272, nil, nil, 52, + 53, nil, nil, 54, nil, 271, nil, 214, nil, 220, + nil, 216, 215, 212, 213, 224, 222, 218, nil, 219, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, 235, 51, 570, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 278, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, nil, nil, 282, nil, 217, 221, 226, 227, 228, + 223, 225, 233, 234, 229, 230, nil, 210, 211, nil, + nil, 231, 232, 275, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, 214, nil, 220, + nil, 216, 215, 212, 213, 224, 222, 218, nil, 219, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, 235, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 23, 24, 65, 66, nil, nil, nil, nil, 22, + 28, 27, 90, 89, 91, 92, nil, nil, 17, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 18, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 28, 27, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, 301, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 23, 24, 65, 66, nil, nil, nil, nil, 22, + 28, 27, 90, 89, 91, 92, nil, nil, 17, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 18, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 23, 24, 65, 66, nil, nil, nil, nil, 22, + 28, 27, 90, 89, 91, 92, nil, nil, 17, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 18, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 278, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, nil, nil, 282, nil, 217, 221, 226, 227, 228, + 223, 225, 233, 234, 229, 230, nil, 210, 211, nil, + nil, 231, 232, 317, nil, nil, 30, nil, nil, 52, + 53, nil, nil, 54, nil, 32, nil, 214, nil, 220, + nil, 216, 215, 212, 213, 224, 222, 218, nil, 219, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, 235, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 278, nil, nil, 94, 93, + 322, 50, 86, 85, 323, 87, 95, 96, nil, 82, + 83, nil, nil, 282, nil, 217, 221, 226, 227, 228, + 223, 225, 233, 234, 229, 230, nil, 210, 211, nil, + 329, 231, 232, 324, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, 214, nil, 220, + nil, 216, 215, 212, 213, 224, 222, 218, nil, 219, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, 235, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 278, nil, nil, 94, 93, + 322, 50, 86, 85, 323, 87, 95, 96, nil, 82, + 83, nil, nil, 282, nil, 217, 221, 226, 227, 228, + 223, 225, 233, 234, 229, 230, nil, 210, 211, nil, + nil, 231, 232, 324, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, 214, nil, 220, + nil, 216, 215, 212, 213, 224, 222, 218, nil, 219, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, -475, -475, -475, 235, -475, nil, nil, + nil, -475, -475, nil, nil, nil, -475, nil, -475, -475, + -475, -475, -475, -475, -475, nil, -475, nil, nil, -475, + -475, -475, -475, -475, -475, -475, nil, nil, nil, nil, + nil, nil, nil, nil, nil, -475, nil, nil, -475, -475, + -475, -475, -475, -475, -475, -475, -475, -475, nil, -475, + -475, -475, -475, -475, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, -475, nil, nil, -475, -475, nil, -475, + -475, nil, nil, -475, nil, -475, nil, -475, nil, -475, + nil, nil, nil, nil, nil, nil, nil, -475, nil, -475, + nil, nil, -475, -475, -475, -475, -475, -475, nil, nil, + nil, -475, -475, -476, -476, -476, nil, -476, nil, nil, + nil, -476, -476, nil, nil, nil, -476, nil, -476, -476, + -476, -476, -476, -476, -476, nil, -476, nil, nil, -476, + -476, -476, -476, -476, -476, -476, nil, nil, nil, nil, + nil, nil, nil, nil, nil, -476, nil, nil, -476, -476, + -476, -476, -476, -476, -476, -476, -476, -476, nil, -476, + -476, -476, -476, -476, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, -476, nil, nil, -476, -476, nil, -476, + -476, nil, nil, -476, nil, -476, nil, -476, nil, -476, + nil, nil, nil, nil, nil, nil, nil, -476, nil, -476, + nil, nil, -476, -476, -476, -476, -476, -476, nil, nil, + nil, -476, -476, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 23, 24, 65, 66, nil, nil, nil, nil, 22, + 28, 27, 90, 89, 91, 92, nil, nil, 17, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 18, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 23, 24, 65, 66, nil, nil, nil, nil, 22, + 28, 27, 90, 89, 91, 92, nil, nil, 17, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 18, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 23, 24, 65, 66, nil, nil, nil, nil, 22, + 28, 27, 90, 89, 91, 92, nil, nil, 17, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 18, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 23, 24, 65, 66, nil, nil, nil, nil, 22, + 28, 27, 90, 89, 91, 92, nil, nil, 17, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 18, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, 7, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 23, 24, 65, 66, nil, nil, nil, nil, 22, + 28, 27, 90, 89, 91, 92, nil, nil, 17, nil, + nil, nil, nil, nil, 6, 41, 8, 9, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 36, nil, nil, 30, nil, nil, 52, + 53, nil, nil, 54, nil, 32, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 18, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 23, 24, 65, 66, nil, nil, nil, nil, 22, + 28, 27, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, 371, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 23, 24, 65, 66, nil, nil, nil, nil, 22, + 28, 27, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, 371, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 23, 24, 65, 66, nil, nil, nil, nil, 22, + 28, 27, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 28, 27, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, 301, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 23, 24, 65, 66, nil, nil, nil, nil, 22, + 28, 27, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 23, 24, 65, 66, nil, nil, nil, nil, 22, + 28, 27, 90, 89, 91, 92, nil, nil, 17, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 18, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 23, 24, 65, 66, nil, nil, nil, nil, 22, + 28, 27, 90, 89, 91, 92, nil, nil, 17, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 18, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 28, 27, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, 243, nil, 245, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 28, 27, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 447, + 53, nil, nil, 54, nil, 243, nil, 245, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 28, 27, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, 451, 52, + 53, nil, nil, 54, nil, 243, nil, 245, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 278, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, nil, nil, 282, nil, 217, 221, 226, 227, 228, + 223, 225, 233, 234, 229, 230, nil, 210, 211, nil, + nil, 231, 232, 275, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, 214, nil, 220, + nil, 216, 215, 212, 213, 224, 222, 218, nil, 219, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, 235, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, 471, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 248, 249, 65, 66, nil, nil, nil, nil, 247, + 277, 281, 90, 89, 91, 92, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 23, 24, 65, 66, nil, nil, nil, nil, 22, + 28, 27, 90, 89, 91, 92, nil, nil, 17, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 18, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 23, 24, 65, 66, nil, nil, nil, nil, 22, + 28, 27, 90, 89, 91, 92, nil, nil, 17, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 18, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 23, 24, 65, 66, nil, nil, nil, nil, 22, + 28, 27, 90, 89, 91, 92, nil, nil, 17, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 18, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 67, 68, 64, nil, 51, nil, nil, + nil, 56, 57, nil, nil, nil, 60, nil, 58, 59, + 61, 23, 24, 65, 66, nil, nil, nil, nil, 22, + 28, 27, 90, 89, 91, 92, nil, nil, 17, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 94, 93, + 84, 50, 86, 85, 88, 87, 95, 96, nil, 82, + 83, 38, 39, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 206, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 18, nil, nil, + nil, nil, 81, 74, 76, 77, 78, 79, nil, nil, + nil, 75, 80, 155, 166, 156, 179, 152, 172, 162, + 161, 182, 183, 177, 160, 159, 154, 180, 184, 185, + 164, 153, 167, 171, 173, 165, 158, nil, nil, 174, + 181, 176, 175, 168, 178, 163, 151, 170, 169, nil, + nil, nil, nil, nil, 150, 157, 148, 149, 146, 147, + 111, 113, nil, nil, 112, nil, nil, nil, nil, nil, + nil, 141, 142, nil, 139, 123, 124, 125, nil, 128, + 130, nil, nil, 126, nil, nil, nil, nil, 143, 144, + 131, 132, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 136, 135, nil, 122, 140, + 138, 137, 133, 134, 129, 127, 120, nil, 121, nil, + nil, 145, 81, nil, nil, 67, 68, 64, nil, 51, + nil, nil, 80, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 248, 249, 65, 66, nil, nil, nil, + nil, 247, 277, 281, 90, 89, 91, 92, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 41, nil, nil, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 202, nil, nil, 206, nil, + nil, 52, 53, nil, nil, 54, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 209, + nil, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, -249, -249, -249, nil, -249, + nil, nil, nil, -249, -249, nil, nil, nil, -249, nil, + -249, -249, -249, -249, -249, -249, -249, nil, nil, nil, + nil, -249, -249, -249, -249, -249, -249, -249, nil, nil, + nil, nil, nil, nil, nil, nil, nil, -249, nil, nil, + -249, -249, -249, -249, -249, -249, -249, -249, -249, -249, + nil, -249, -249, -249, -249, -249, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, -249, nil, nil, -249, 256, + nil, -249, -249, nil, nil, -249, nil, -249, nil, -249, + nil, -249, nil, nil, nil, nil, nil, nil, nil, -249, + nil, nil, nil, nil, -249, -249, -249, -249, -249, -249, + nil, nil, nil, -249, -249, -480, -480, -480, nil, -480, + nil, nil, nil, -480, -480, nil, nil, nil, -480, nil, + -480, -480, -480, -480, -480, -480, -480, nil, nil, nil, + nil, -480, -480, -480, -480, -480, -480, -480, nil, nil, + nil, nil, nil, nil, nil, nil, nil, -480, nil, nil, + -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, + nil, -480, -480, -480, -480, -480, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, -480, nil, nil, -480, -480, + nil, -480, -480, nil, nil, -480, nil, -480, nil, -480, + nil, -480, nil, nil, nil, nil, nil, nil, nil, -480, + nil, nil, nil, nil, -480, -480, -480, -480, -480, -480, + nil, nil, nil, -480, -480, -481, -481, -481, nil, -481, + nil, nil, nil, -481, -481, nil, nil, nil, -481, nil, + -481, -481, -481, -481, -481, -481, -481, nil, nil, nil, + nil, -481, -481, -481, -481, -481, -481, -481, nil, nil, + nil, nil, nil, nil, nil, nil, nil, -481, nil, nil, + -481, -481, -481, -481, -481, -481, -481, -481, -481, -481, + nil, -481, -481, -481, -481, -481, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, -481, nil, nil, -481, -481, + nil, -481, -481, nil, nil, -481, nil, -481, nil, -481, + nil, -481, nil, nil, nil, nil, nil, nil, nil, -481, + nil, nil, nil, nil, -481, -481, -481, -481, -481, -481, + nil, nil, nil, -481, -481, 67, 68, 64, nil, 51, + nil, nil, nil, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 248, 249, 65, 66, nil, nil, nil, + nil, 247, 28, 27, 90, 89, 91, 92, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 41, nil, nil, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 202, nil, nil, 206, nil, + nil, 52, 53, nil, nil, 54, nil, 301, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 209, + nil, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, 67, 68, 64, nil, 51, + nil, nil, nil, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 248, 249, 65, 66, nil, nil, nil, + nil, 247, 277, 281, 90, 89, 91, 92, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 41, nil, nil, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 202, nil, nil, 206, nil, + nil, 52, 53, nil, nil, 54, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 209, + nil, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, 67, 68, 64, nil, 51, + nil, nil, nil, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 248, 249, 65, 66, nil, nil, nil, + nil, 247, 277, 281, 90, 89, 91, 92, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 41, nil, nil, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 202, nil, nil, 206, nil, + nil, 52, 53, nil, nil, 54, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 209, + nil, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, 67, 68, 64, nil, 51, + nil, nil, nil, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 248, 249, 65, 66, nil, nil, nil, + nil, 247, 277, 281, 90, 89, 91, 92, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 41, nil, nil, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 202, nil, nil, 206, nil, + nil, 52, 53, nil, nil, 54, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 209, + nil, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, 67, 68, 64, nil, 51, + nil, nil, nil, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 248, 249, 65, 66, nil, nil, nil, + nil, 247, 277, 281, 90, 89, 91, 92, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 41, nil, nil, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 202, nil, nil, 206, nil, + nil, 52, 53, nil, nil, 54, nil, 562, nil, 245, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 209, + nil, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, 67, 68, 64, nil, 51, + nil, nil, nil, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 248, 249, 65, 66, nil, nil, nil, + nil, 247, 277, 281, 90, 89, 91, 92, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 41, nil, nil, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 202, nil, nil, 206, nil, + nil, 52, 53, nil, nil, 54, nil, 566, nil, 245, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 209, + nil, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, 67, 68, 64, nil, 51, + nil, nil, nil, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 248, 249, 65, 66, nil, nil, nil, + nil, 247, 277, 281, 90, 89, 91, 92, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 41, nil, nil, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 202, nil, nil, 206, nil, + nil, 52, 53, nil, nil, 54, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 209, + nil, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, 67, 68, 64, nil, 51, + nil, nil, nil, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 23, 24, 65, 66, nil, nil, nil, + nil, 22, 28, 27, 90, 89, 91, 92, nil, nil, + 17, nil, nil, nil, nil, nil, nil, 41, nil, nil, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 202, nil, nil, 206, nil, + nil, 52, 53, nil, nil, 54, nil, 586, nil, 245, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 18, + nil, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, 67, 68, 64, nil, 51, + nil, nil, nil, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 248, 249, 65, 66, nil, nil, nil, + nil, 247, 28, 27, 90, 89, 91, 92, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 41, nil, nil, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 202, nil, nil, 206, nil, + nil, 52, 53, nil, nil, 54, nil, 301, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 209, + nil, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, 67, 68, 64, nil, 51, + nil, nil, nil, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 248, 249, 65, 66, nil, nil, nil, + nil, 247, 277, 281, 90, 89, 91, 92, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 41, nil, nil, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 202, nil, nil, 206, nil, + nil, 52, 53, nil, nil, 54, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 209, + nil, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, 67, 68, 64, nil, 51, + nil, nil, nil, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 248, 249, 65, 66, nil, nil, nil, + nil, 247, 277, 281, 90, 89, 91, 92, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 41, nil, nil, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 202, nil, nil, 206, nil, + nil, 52, 53, nil, nil, 54, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 209, + nil, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, 67, 68, 64, nil, 51, + nil, nil, nil, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 248, 249, 65, 66, nil, nil, nil, + nil, 247, 277, 281, 90, 89, 91, 92, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 41, nil, nil, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 202, nil, nil, 206, nil, + nil, 52, 53, nil, nil, 54, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 209, + nil, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, 67, 68, 64, nil, 51, + nil, nil, nil, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 23, 24, 65, 66, nil, nil, nil, + nil, 22, 28, 27, 90, 89, 91, 92, nil, nil, + 17, nil, nil, nil, nil, nil, nil, 41, nil, nil, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 202, nil, nil, 206, nil, + nil, 52, 53, nil, nil, 54, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 18, + nil, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, 67, 68, 64, nil, 51, + nil, nil, nil, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 248, 249, 65, 66, nil, nil, nil, + nil, 247, 277, 281, 90, 89, 91, 92, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 41, nil, nil, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 202, nil, nil, 206, nil, + nil, 52, 53, nil, nil, 54, nil, 371, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 209, + nil, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, 67, 68, 64, nil, 51, + nil, nil, nil, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 248, 249, 65, 66, nil, nil, nil, + nil, 247, 277, 281, 90, 89, 91, 92, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 41, nil, nil, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 202, nil, nil, 206, nil, + nil, 52, 53, nil, nil, 54, nil, 614, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 209, + nil, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, 67, 68, 64, nil, 51, + nil, nil, nil, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 248, 249, 65, 66, nil, nil, nil, + nil, 247, 277, 281, 90, 89, 91, 92, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 41, nil, nil, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 202, nil, nil, 206, nil, + nil, 52, 53, nil, nil, 54, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 209, + nil, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, 67, 68, 64, nil, 51, + nil, nil, nil, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 248, 249, 65, 66, nil, nil, nil, + nil, 247, 277, 281, 90, 89, 91, 92, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 41, nil, nil, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 202, nil, nil, 206, nil, + nil, 52, 53, nil, nil, 54, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 209, + nil, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, 67, 68, 64, nil, 51, + nil, nil, nil, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 248, 249, 65, 66, nil, nil, nil, + nil, 247, 277, 281, 90, 89, 91, 92, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 41, nil, nil, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 202, nil, nil, 206, nil, + nil, 52, 53, nil, nil, 54, nil, 630, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 209, + nil, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, 67, 68, 64, nil, 51, + nil, nil, nil, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 248, 249, 65, 66, nil, nil, nil, + nil, 247, 28, 27, 90, 89, 91, 92, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 41, nil, nil, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 202, nil, nil, 206, nil, + nil, 52, 53, nil, nil, 54, nil, 301, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 209, + nil, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, 67, 68, 64, nil, 51, + nil, nil, nil, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 248, 249, 65, 66, nil, nil, nil, + nil, 247, 28, 27, 90, 89, 91, 92, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 41, nil, nil, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 202, nil, nil, 206, nil, + nil, 52, 53, nil, nil, 54, nil, 301, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 209, + nil, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, 67, 68, 64, nil, 51, + nil, nil, nil, 56, 57, nil, nil, nil, 60, nil, + 58, 59, 61, 23, 24, 65, 66, nil, nil, nil, + nil, 22, 28, 27, 90, 89, 91, 92, nil, nil, + 17, nil, nil, nil, nil, nil, nil, 41, nil, nil, + 94, 93, 84, 50, 86, 85, 88, 87, 95, 96, + nil, 82, 83, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 202, nil, nil, 206, nil, + nil, 52, 53, nil, nil, 54, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 18, + nil, nil, nil, nil, 81, 74, 76, 77, 78, 79, + nil, nil, nil, 75, 80, 155, 166, 156, 179, 152, + 172, 162, 161, 182, 183, 177, 160, 159, 154, 180, + 184, 185, 164, 153, 167, 171, 173, 165, 158, nil, + nil, 174, 181, 176, 175, 168, 178, 163, 151, 170, + 169, nil, nil, nil, nil, nil, 150, 157, 148, 149, + 146, 147, 111, 113, nil, nil, 112, nil, nil, nil, + nil, nil, nil, 141, 142, nil, 139, 123, 124, 125, + nil, 128, 130, nil, nil, 126, nil, nil, nil, nil, + 143, 144, 131, 132, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 136, 135, nil, + 122, 140, 138, 137, 133, 134, 129, 127, 120, nil, + 121, nil, nil, 145, 81, nil, nil, 67, 68, 64, + nil, 51, nil, nil, 80, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, 681, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 23, 24, 65, 66, nil, + nil, nil, nil, 22, 28, 27, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 23, 24, 65, 66, nil, + nil, nil, nil, 22, 28, 27, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 23, 24, 65, 66, nil, + nil, nil, nil, 22, 28, 27, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 278, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, nil, nil, 282, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 275, nil, nil, + 272, nil, nil, 52, 53, nil, nil, 54, nil, 699, + nil, 700, nil, nil, nil, nil, nil, nil, nil, nil, + 701, nil, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 28, 27, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, 562, + nil, 245, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 23, 24, 65, 66, nil, + nil, nil, nil, 22, 28, 27, 90, 89, 91, 92, + nil, nil, 17, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 18, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 23, 24, 65, 66, nil, + nil, nil, nil, 22, 28, 27, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 278, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, nil, nil, 282, nil, 217, + 221, 226, 227, 228, 223, 225, 233, 234, 229, 230, + nil, 210, 211, nil, nil, 231, 232, 774, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, 214, nil, 220, nil, 216, 215, 212, 213, 224, + 222, 218, nil, 219, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + 235, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, 782, + nil, 245, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, 788, + nil, 245, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, 790, + nil, 245, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 278, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, nil, nil, 282, nil, 217, + 221, 226, 227, 228, 223, 225, 233, 234, 229, 230, + nil, 210, 211, nil, nil, 231, 232, 774, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, 214, nil, 220, nil, 216, 215, 212, 213, 224, + 222, 218, nil, 219, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + 235, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 23, 24, 65, 66, nil, + nil, nil, nil, 22, 28, 27, 90, 89, 91, 92, + nil, nil, 17, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 18, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, 804, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 278, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, nil, nil, 282, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 275, nil, nil, + 272, nil, nil, 52, 53, nil, nil, 54, nil, 823, + nil, 822, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 278, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, nil, nil, 282, nil, 217, + 221, 226, 227, 228, 223, 225, 233, 234, 229, 230, + nil, 210, 211, nil, nil, 231, 232, 774, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, 214, nil, 220, nil, 216, 215, 212, 213, 224, + 222, 218, nil, 219, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + 235, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 28, 27, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, 301, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 278, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, nil, nil, 282, nil, 217, + 221, 226, 227, 228, 223, 225, 233, 234, 229, 230, + nil, 210, 211, nil, nil, 231, 232, 774, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, 214, nil, 220, nil, 216, 215, 212, 213, 224, + 222, 218, nil, 219, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + 235, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, 866, + nil, 245, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, 869, + nil, 245, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 278, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, nil, nil, 282, nil, 217, + 221, 226, 227, 228, 223, 225, 233, 234, 229, 230, + nil, 210, 211, nil, nil, 231, 232, 774, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, 214, nil, 220, nil, 216, 215, 212, 213, 224, + 222, 218, nil, 219, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + 235, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 278, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, nil, nil, 282, nil, 217, + 221, 226, 227, 228, 223, 225, 233, 234, 229, 230, + nil, 210, 211, nil, nil, 231, 232, 774, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, 214, nil, 220, nil, 216, 215, 212, 213, 224, + 222, 218, nil, 219, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + 235, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, 891, + nil, 245, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + nil, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 278, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, nil, nil, 282, nil, 217, + 221, 226, 227, 228, 223, 225, 233, 234, 229, 230, + nil, 210, 211, nil, nil, 231, 232, 774, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, 214, nil, 220, nil, 216, 215, 212, 213, 224, + 222, 218, nil, 219, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 67, 68, 64, + 235, 51, nil, nil, nil, 56, 57, nil, nil, nil, + 60, nil, 58, 59, 61, 248, 249, 65, 66, nil, + nil, nil, nil, 247, 277, 281, 90, 89, 91, 92, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 94, 93, 84, 50, 86, 85, 88, 87, + 95, 96, nil, 82, 83, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + 206, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, nil, nil, 81, 74, 76, 77, + 78, 79, nil, nil, nil, 75, 80, 155, 166, 156, + 179, 152, 172, 162, 161, 182, 183, 177, 160, 159, + 154, 180, 184, 185, 164, 153, 167, 171, 173, 165, + 158, nil, nil, 174, 181, 176, 338, 337, 339, 336, + 151, 170, 169, nil, nil, nil, nil, nil, 150, 157, + 148, 149, 334, 335, 332, 113, 86, 85, 333, 87, + nil, nil, nil, nil, nil, 141, 142, nil, 139, 123, + 124, 125, nil, 128, 130, nil, nil, 126, nil, nil, + nil, nil, 143, 144, 131, 132, nil, nil, nil, nil, + nil, 343, nil, nil, nil, nil, nil, nil, nil, 136, + 135, nil, 122, 140, 138, 137, 133, 134, 129, 127, + 120, nil, 121, nil, nil, 145, 155, 166, 156, 179, + 152, 172, 162, 161, 182, 183, 177, 160, 159, 154, + 180, 184, 185, 164, 153, 167, 171, 173, 165, 158, + nil, nil, 174, 181, 176, 175, 168, 178, 163, 151, + 170, 169, nil, nil, nil, nil, nil, 150, 157, 148, + 149, 146, 147, 111, 113, nil, nil, 112, nil, nil, + nil, nil, nil, nil, 141, 142, nil, 139, 123, 124, + 125, nil, 128, 130, nil, nil, 126, nil, nil, nil, + nil, 143, 144, 131, 132, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 136, 135, + nil, 122, 140, 138, 137, 133, 134, 129, 127, 120, + nil, 121, nil, nil, 145, 217, 221, 226, 227, 228, + 223, 225, 233, 234, 229, 230, nil, 210, 211, nil, + nil, 231, 232, nil, nil, nil, -215, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 214, nil, 220, + nil, 216, 215, 212, 213, 224, 222, 218, nil, 219, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 235, nil, -215, 217, + 221, 226, 227, 228, 223, 225, 233, 234, 229, 230, + nil, 210, 211, nil, nil, 231, 232, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, 220, nil, 216, 215, 212, 213, 224, + 222, 218, nil, 219, nil, nil, nil, nil, nil, nil, + nil, 378, 381, nil, nil, 379, nil, nil, nil, nil, + 235, 558, 141, 142, nil, 139, 123, 124, 125, nil, + 128, 130, nil, nil, 126, nil, nil, nil, nil, 143, + 144, 131, 132, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 136, 135, nil, 122, + 140, 138, 137, 133, 134, 129, 127, 120, nil, 121, + 383, 387, 145, nil, 385, nil, nil, nil, nil, nil, + nil, 141, 142, nil, 139, 123, 124, 125, nil, 128, + 130, nil, nil, 126, nil, nil, nil, nil, 143, 144, + 131, 132, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 136, 135, nil, 122, 140, + 138, 137, 133, 134, 129, 127, 120, nil, 121, 435, + 381, 145, nil, 436, nil, nil, nil, nil, nil, nil, + 141, 142, nil, 139, 123, 124, 125, nil, 128, 130, + nil, nil, 126, nil, nil, nil, nil, 143, 144, 131, + 132, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 136, 135, nil, 122, 140, 138, + 137, 133, 134, 129, 127, 120, nil, 121, 435, 381, + 145, nil, 436, nil, nil, nil, nil, nil, nil, 141, + 142, nil, 139, 123, 124, 125, nil, 128, 130, nil, + nil, 126, nil, nil, nil, nil, 143, 144, 131, 132, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 136, 135, nil, 122, 140, 138, 137, + 133, 134, 129, 127, 120, nil, 121, 552, 381, 145, + nil, 553, nil, nil, nil, nil, nil, nil, 141, 142, + nil, 139, 123, 124, 125, nil, 128, 130, nil, nil, + 126, nil, nil, nil, nil, 143, 144, 131, 132, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 136, 135, nil, 122, 140, 138, 137, 133, + 134, 129, 127, 120, nil, 121, 554, 387, 145, nil, + 555, nil, nil, nil, nil, nil, nil, 141, 142, nil, + 139, 123, 124, 125, nil, 128, 130, nil, nil, 126, + nil, nil, nil, nil, 143, 144, 131, 132, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 136, 135, nil, 122, 140, 138, 137, 133, 134, + 129, 127, 120, nil, 121, 596, 381, 145, nil, 597, + nil, nil, nil, nil, nil, nil, 141, 142, nil, 139, + 123, 124, 125, nil, 128, 130, nil, nil, 126, nil, + nil, nil, nil, 143, 144, 131, 132, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 136, 135, nil, 122, 140, 138, 137, 133, 134, 129, + 127, 120, nil, 121, 599, 387, 145, nil, 600, nil, + nil, nil, nil, nil, nil, 141, 142, nil, 139, 123, + 124, 125, nil, 128, 130, nil, nil, 126, nil, nil, + nil, nil, 143, 144, 131, 132, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 136, + 135, nil, 122, 140, 138, 137, 133, 134, 129, 127, + 120, nil, 121, 552, 381, 145, nil, 553, nil, nil, + nil, nil, nil, nil, 141, 142, nil, 139, 123, 124, + 125, nil, 128, 130, nil, nil, 126, nil, nil, nil, + nil, 143, 144, 131, 132, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 136, 135, + nil, 122, 140, 138, 137, 133, 134, 129, 127, 120, + nil, 121, 554, 387, 145, nil, 555, nil, nil, nil, + nil, nil, nil, 141, 142, nil, 139, 123, 124, 125, + nil, 128, 130, nil, nil, 126, nil, nil, nil, nil, + 143, 144, 131, 132, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 136, 135, nil, + 122, 140, 138, 137, 133, 134, 129, 127, 120, nil, + 121, nil, nil, 145, 217, 221, 226, 227, 228, 223, + 225, 233, 234, 229, 230, nil, 210, 211, nil, nil, + 231, 232, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, 220, nil, + 216, 215, 212, 213, 224, 222, 218, nil, 219, nil, + nil, nil, nil, nil, nil, 632, 381, nil, nil, 633, + nil, nil, nil, nil, 293, 235, 141, 142, nil, 139, + 123, 124, 125, nil, 128, 130, nil, nil, 126, nil, + nil, nil, nil, 143, 144, 131, 132, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 136, 135, nil, 122, 140, 138, 137, 133, 134, 129, + 127, 120, nil, 121, 634, 387, 145, nil, 635, nil, + nil, nil, nil, nil, nil, 141, 142, nil, 139, 123, + 124, 125, nil, 128, 130, nil, nil, 126, nil, nil, + nil, nil, 143, 144, 131, 132, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 136, + 135, nil, 122, 140, 138, 137, 133, 134, 129, 127, + 120, nil, 121, 637, 387, 145, nil, 638, nil, nil, + nil, nil, nil, nil, 141, 142, nil, 139, 123, 124, + 125, nil, 128, 130, nil, nil, 126, nil, nil, nil, + nil, 143, 144, 131, 132, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 136, 135, + nil, 122, 140, 138, 137, 133, 134, 129, 127, 120, + nil, 121, 435, 381, 145, nil, 436, nil, nil, nil, + nil, nil, nil, 141, 142, nil, 139, 123, 124, 125, + nil, 128, 130, nil, nil, 126, nil, nil, nil, nil, + 143, 144, 131, 132, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 136, 135, nil, + 122, 140, 138, 137, 133, 134, 129, 127, 120, nil, + 121, 435, 381, 145, nil, 436, nil, nil, nil, nil, + nil, nil, 141, 142, nil, 139, 123, 124, 125, nil, + 128, 130, nil, nil, 126, nil, nil, nil, nil, 143, + 144, 131, 132, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 136, 135, nil, 122, + 140, 138, 137, 133, 134, 129, 127, 120, nil, 121, + 435, 381, 145, nil, 436, nil, nil, nil, nil, nil, + nil, 141, 142, nil, 139, 123, 124, 125, nil, 128, + 130, nil, nil, 126, nil, nil, nil, nil, 143, 144, + 131, 132, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 136, 135, nil, 122, 140, + 138, 137, 133, 134, 129, 127, 120, nil, 121, nil, + nil, 145, 217, 221, 226, 227, 228, 223, 225, 233, + 234, 229, 230, nil, 210, 211, nil, nil, 231, 232, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, 220, nil, 216, 215, + 212, 213, 224, 222, 218, nil, 219, nil, 217, 221, + 226, 227, 228, 223, 225, 233, 234, 229, 230, nil, + 210, 211, 293, 235, 231, 232, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 214, nil, 220, nil, 216, 215, 212, 213, 224, 222, + 218, nil, 219, nil, nil, nil, 859, 381, nil, nil, + 860, nil, nil, nil, nil, nil, nil, 141, 142, 235, + 139, 123, 124, 125, nil, 128, 130, nil, nil, 126, + nil, nil, nil, nil, 143, 144, 131, 132, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 136, 135, nil, 122, 140, 138, 137, 133, 134, + 129, 127, 120, nil, 121, 861, 387, 145, nil, 862, + nil, nil, nil, nil, nil, nil, 141, 142, nil, 139, + 123, 124, 125, nil, 128, 130, nil, nil, 126, nil, + nil, nil, nil, 143, 144, 131, 132, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 136, 135, nil, 122, 140, 138, 137, 133, 134, 129, + 127, 120, nil, 121, nil, nil, 145 ] + +racc_action_check = [ + 383, 514, 514, 520, 520, 308, 757, 383, 383, 383, + 328, 442, 713, 383, 383, 315, 383, 584, 442, 713, + 309, 426, 349, 318, 448, 383, 324, 629, 502, 1, + 324, 201, 203, 605, 605, 383, 383, 632, 383, 383, + 383, 383, 383, 729, 800, 313, 396, 313, 633, 634, + 745, 757, 757, 757, 757, 426, 8, 593, 448, 584, + 442, 713, 9, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 201, 203, 383, + 383, 383, 55, 383, 349, 605, 596, 383, 10, 514, + 383, 520, 396, 493, 514, 383, 593, 383, 11, 383, + 383, 383, 383, 383, 383, 383, 385, 383, 383, 383, + 12, 634, 328, 385, 385, 385, 308, 315, 308, 385, + 385, 308, 385, 383, 383, 318, 383, 20, 383, 383, + 502, 309, 328, 309, 494, 597, 309, 328, 629, 632, + 629, 385, 385, 629, 385, 385, 385, 385, 385, 596, + 633, 634, 745, 552, 729, 800, 729, 800, 746, 729, + 800, 635, 805, 449, 805, 55, 26, 596, 553, 385, + 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 279, 576, 385, 385, 385, 596, 385, + 493, 596, 493, 385, 72, 493, 385, 449, 597, 552, + 14, 385, 72, 385, 530, 385, 385, 385, 385, 385, + 385, 385, 50, 385, 553, 385, 597, 34, 576, 50, + 50, 50, 850, 635, 50, 50, 50, 26, 50, 385, + 385, 494, 385, 494, 385, 385, 494, 597, 50, 50, + 597, 15, 15, 14, 279, 322, 14, 50, 50, 26, + 50, 50, 50, 50, 50, 746, 3, 746, 37, 37, + 746, 3, 345, 635, 530, 530, 279, 850, 850, 850, + 850, 282, 282, 36, 530, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 41, + 323, 50, 50, 50, 322, 312, 50, 695, 97, 50, + 312, 322, 50, 50, 35, 50, 322, 50, 186, 50, + 322, 50, 50, 50, 50, 50, 50, 50, 434, 50, + 285, 50, 345, 345, 345, 434, 434, 434, 322, 378, + 434, 434, 434, 599, 434, 50, 50, 50, 50, 323, + 50, 346, 25, 695, 434, 13, 323, 35, 202, 25, + 35, 323, 13, 434, 434, 323, 434, 434, 434, 434, + 434, 13, 332, 285, 299, 637, 285, 299, 859, 332, + 204, 437, 378, 323, 347, 378, 379, 542, 437, 437, + 437, 205, 599, 437, 437, 437, 333, 437, 860, 599, + 241, 110, 434, 333, 599, 110, 110, 437, 599, 434, + 348, 346, 346, 346, 434, 434, 437, 437, 350, 437, + 437, 437, 437, 437, 637, 242, 599, 859, 861, 379, + 542, 637, 379, 542, 859, 334, 637, 434, 246, 859, + 637, 42, 334, 859, 347, 347, 347, 860, 42, 300, + 402, 434, 300, 434, 860, 437, 434, 42, 637, 860, + 513, 859, 437, 860, 255, 513, 335, 437, 437, 200, + 348, 348, 348, 335, 296, 296, 200, 861, 350, 350, + 350, 860, 402, 642, 861, 200, 402, 402, 642, 861, + 437, 336, 647, 861, 647, 647, 647, 647, 336, 554, + 554, 554, 266, 554, 437, 648, 437, 554, 554, 437, + 648, 861, 554, 268, 554, 554, 554, 554, 554, 554, + 554, 303, 307, 307, 303, 554, 554, 554, 554, 554, + 554, 554, 421, 617, 617, 337, 338, 647, 647, 647, + 647, 554, 337, 338, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 339, 554, 554, 554, 554, 554, + 273, 339, 760, 760, 421, 274, 341, 273, 421, 421, + 421, 421, 274, 341, 305, 269, 273, 305, 270, 554, + 554, 274, 554, 554, 275, 554, 554, 872, 872, 554, + 276, 554, 277, 554, 278, 554, 516, 276, 516, 516, + 516, 516, 281, 554, 286, 287, 276, 290, 554, 554, + 554, 554, 554, 554, 294, 295, 298, 554, 554, 555, + 555, 555, 403, 555, 302, 304, 554, 555, 555, 314, + 317, 319, 555, 516, 555, 555, 555, 555, 555, 555, + 555, 516, 516, 516, 516, 555, 555, 555, 555, 555, + 555, 555, 422, 364, 403, 365, 370, 373, 403, 403, + 377, 555, 384, 404, 555, 555, 555, 555, 555, 555, + 555, 555, 555, 555, 405, 555, 555, 555, 555, 555, + 288, 406, 407, 431, 422, 316, 440, 288, 422, 422, + 422, 422, 316, 441, 443, 444, 288, 450, 452, 555, + 555, 316, 555, 555, 453, 555, 555, 457, 462, 555, + 326, 555, 472, 555, 475, 555, 755, 326, 755, 755, + 755, 755, 489, 555, 495, 496, 326, 528, 555, 555, + 555, 555, 555, 555, 533, 461, 545, 555, 555, 60, + 60, 60, 461, 60, 549, 556, 555, 60, 60, 563, + 565, 461, 60, 568, 60, 60, 60, 60, 60, 60, + 60, 755, 755, 755, 755, 60, 60, 60, 60, 60, + 60, 60, 524, 524, 60, 524, 524, 524, 570, 368, + 578, 60, 579, 585, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 588, 60, 60, 60, 60, 60, + 368, 368, 368, 368, 368, 368, 368, 368, 368, 368, + 368, 505, 368, 368, 723, 595, 368, 368, 505, 60, + 598, 723, 60, 601, 603, 60, 60, 505, 604, 60, + 723, 606, 368, 609, 368, 60, 368, 368, 368, 368, + 368, 368, 368, 60, 368, 610, 613, 619, 60, 60, + 60, 60, 60, 60, 625, 627, 628, 60, 60, 631, + 60, 368, 640, 368, 600, 60, 99, 99, 99, 99, + 99, 600, 645, 649, 99, 99, 600, 650, 651, 99, + 600, 99, 99, 99, 99, 99, 99, 99, 657, 662, + 665, 667, 99, 99, 99, 99, 99, 99, 99, 680, + 698, 99, 4, 4, 4, 4, 4, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 99, 638, 99, 99, 99, 99, 99, 772, 638, 773, + 702, 775, 827, 638, 772, 878, 773, 638, 775, 827, + 703, 704, 878, 772, 707, 773, 99, 775, 827, 99, + 711, 878, 99, 99, 712, 714, 99, 862, 99, 718, + 720, 721, 99, 819, 862, 819, 819, 819, 819, 862, + 99, 722, 734, 862, 737, 99, 99, 99, 99, 99, + 99, 748, 752, 753, 99, 99, 699, 699, 699, 766, + 699, 774, 99, 776, 699, 699, 777, 784, 785, 699, + 819, 699, 699, 699, 699, 699, 699, 699, 819, 819, + 819, 819, 699, 699, 699, 699, 699, 699, 699, 108, + 108, 108, 108, 108, 786, 789, 802, 803, 699, 808, + 810, 699, 699, 699, 699, 699, 699, 699, 699, 699, + 699, 811, 699, 699, 812, 815, 699, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, 816, 400, + 400, 828, 835, 400, 400, 838, 699, 839, 856, 699, + 857, 858, 699, 699, 867, 873, 699, 874, 875, 400, + 876, 400, 880, 400, 400, 400, 400, 400, 400, 400, + 883, 400, 894, nil, nil, 699, 699, 699, 699, 699, + 699, nil, nil, nil, 699, 699, nil, 823, 823, 823, + 699, 823, nil, nil, nil, 823, 823, nil, nil, nil, + 823, nil, 823, 823, 823, 823, 823, 823, 823, nil, + nil, nil, nil, 823, 823, 823, 823, 823, 823, 823, + 352, 352, 352, 352, 352, nil, nil, 557, nil, 823, + nil, nil, 823, 823, 823, 823, 823, 823, 823, 823, + 823, 823, nil, 823, 823, nil, nil, 823, 557, 557, + 557, 557, 557, 557, 557, 557, 557, 557, 557, nil, + 557, 557, nil, nil, 557, 557, nil, 823, nil, nil, + 823, nil, nil, 823, 823, nil, nil, 823, nil, nil, + 557, nil, 557, nil, 557, 557, 557, 557, 557, 557, + 557, nil, 557, nil, nil, nil, 823, 823, 823, 823, + 823, 823, nil, nil, nil, 823, 823, nil, nil, 557, + nil, 823, 0, 0, 0, 0, 0, 0, nil, nil, + nil, 0, 0, nil, nil, nil, 0, nil, 0, 0, + 0, 0, 0, 0, 0, nil, nil, nil, nil, 0, + 0, 0, 0, 0, 0, 0, nil, nil, 0, nil, + nil, nil, nil, nil, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, nil, 0, + 0, 0, 0, 0, 401, 401, 401, 401, 401, 401, + 401, 401, 401, 401, 401, nil, 401, 401, nil, nil, + 401, 401, nil, 0, nil, nil, 0, nil, nil, 0, + 0, nil, nil, 0, nil, 0, 401, nil, 401, 0, + 401, 401, 401, 401, 401, 401, 401, 0, 401, nil, + nil, nil, 0, 0, 0, 0, 0, 0, nil, nil, + nil, 0, 0, 30, 30, 30, 30, 30, 30, nil, + nil, nil, 30, 30, nil, nil, nil, 30, nil, 30, + 30, 30, 30, 30, 30, 30, nil, nil, nil, nil, + 30, 30, 30, 30, 30, 30, 30, nil, nil, 30, + nil, nil, nil, nil, nil, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, nil, + 30, 30, 30, 30, 30, 411, 411, 411, 411, 411, + 411, 411, nil, nil, 411, 411, nil, nil, nil, nil, + nil, 411, 411, nil, 30, nil, nil, 30, nil, nil, + 30, 30, nil, nil, 30, nil, 30, 411, nil, 411, + 30, 411, 411, 411, 411, 411, 411, 411, 30, 411, + nil, nil, nil, 30, 30, 30, 30, 30, 30, nil, + nil, nil, 30, 30, 51, 51, 51, 51, 51, 51, + nil, nil, nil, 51, 51, nil, nil, nil, 51, nil, + 51, 51, 51, 51, 51, 51, 51, nil, nil, nil, + nil, 51, 51, 51, 51, 51, 51, 51, nil, nil, + 51, nil, nil, nil, nil, nil, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + nil, 51, 51, 51, 51, 51, 412, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 412, 412, nil, 51, nil, nil, 51, nil, + nil, 51, 51, nil, nil, 51, nil, 51, 412, nil, + 412, 51, 412, 412, 412, 412, nil, nil, 412, 51, + 412, nil, nil, nil, 51, 51, 51, 51, 51, 51, + nil, nil, nil, 51, 51, 188, 188, 188, 188, 188, + 188, nil, nil, nil, 188, 188, nil, nil, nil, 188, + nil, 188, 188, 188, 188, 188, 188, 188, nil, nil, + nil, nil, 188, 188, 188, 188, 188, 188, 188, nil, + nil, 188, nil, nil, nil, nil, nil, 188, 188, 188, + 188, 188, 188, 188, 188, 188, 188, 188, 188, 188, + 188, nil, 188, 188, 188, 188, 188, 413, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 413, 413, nil, 188, nil, nil, 188, + nil, nil, 188, 188, nil, nil, 188, nil, 188, 413, + nil, 413, 188, 413, 413, 413, 413, nil, nil, 413, + 188, 413, nil, nil, nil, 188, 188, 188, 188, 188, + 188, nil, nil, nil, 188, 188, 189, 189, 189, 189, + 189, 189, nil, nil, nil, 189, 189, nil, nil, nil, + 189, nil, 189, 189, 189, 189, 189, 189, 189, nil, + nil, nil, nil, 189, 189, 189, 189, 189, 189, 189, + nil, nil, 189, nil, nil, nil, nil, nil, 189, 189, + 189, 189, 189, 189, 189, 189, 189, 189, 189, 189, + 189, 189, nil, 189, 189, 189, 189, 189, 414, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 414, 414, nil, 189, nil, nil, + 189, nil, nil, 189, 189, nil, nil, 189, nil, 189, + 414, nil, 414, 189, 414, 414, 414, 414, nil, nil, + 414, 189, 414, nil, nil, nil, 189, 189, 189, 189, + 189, 189, nil, nil, nil, 189, 189, 206, 206, 206, + 206, 206, 206, nil, nil, nil, 206, 206, nil, nil, + nil, 206, nil, 206, 206, 206, 206, 206, 206, 206, + nil, nil, nil, nil, 206, 206, 206, 206, 206, 206, + 206, nil, nil, 206, nil, nil, nil, nil, nil, 206, + 206, 206, 206, 206, 206, 206, 206, 206, 206, 206, + 206, 206, 206, nil, 206, 206, 206, 206, 206, 415, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 415, 415, nil, 206, nil, + nil, 206, nil, nil, 206, 206, nil, nil, 206, nil, + 206, 415, nil, 415, 206, 415, 415, 415, 415, nil, + nil, 415, 206, 415, nil, nil, nil, 206, 206, 206, + 206, 206, 206, nil, nil, nil, 206, 206, 267, 267, + 267, 267, 267, 267, nil, nil, nil, 267, 267, nil, + nil, nil, 267, nil, 267, 267, 267, 267, 267, 267, + 267, nil, nil, nil, nil, 267, 267, 267, 267, 267, + 267, 267, nil, nil, 267, nil, nil, nil, nil, nil, + 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, + 267, 267, 267, 267, nil, 267, 267, 267, 267, 267, + 416, 416, 416, 416, 416, 416, 416, nil, nil, 416, + 416, nil, nil, nil, nil, nil, 416, 416, nil, 267, + nil, nil, 267, nil, nil, 267, 267, nil, nil, 267, + nil, 267, 416, nil, 416, 267, 416, 416, 416, 416, + 416, 416, 416, 267, 416, nil, nil, nil, 267, 267, + 267, 267, 267, 267, nil, nil, nil, 267, 267, 272, + 272, 272, 272, 272, 272, nil, nil, nil, 272, 272, + nil, nil, nil, 272, nil, 272, 272, 272, 272, 272, + 272, 272, nil, nil, nil, nil, 272, 272, 272, 272, + 272, 272, 272, nil, nil, 272, nil, nil, nil, nil, + nil, 272, 272, 272, 272, 272, 272, 272, 272, 272, + 272, 272, 272, 272, 272, nil, 272, 272, 272, 272, + 272, 417, 417, 417, 417, 417, 417, 417, nil, nil, + 417, 417, nil, nil, nil, nil, nil, 417, 417, nil, + 272, nil, nil, 272, nil, nil, 272, 272, nil, nil, + 272, nil, 272, 417, nil, 417, 272, 417, 417, 417, + 417, 417, 417, 417, 272, 417, nil, nil, nil, 272, + 272, 272, 272, 272, 272, nil, nil, nil, 272, 272, + 488, 488, 488, 488, 488, 488, nil, nil, nil, 488, + 488, nil, nil, nil, 488, nil, 488, 488, 488, 488, + 488, 488, 488, nil, nil, nil, nil, 488, 488, 488, + 488, 488, 488, 488, nil, nil, 488, nil, nil, nil, + nil, nil, 488, 488, 488, 488, 488, 488, 488, 488, + 488, 488, 488, 488, 488, 488, nil, 488, 488, 488, + 488, 488, 418, 418, 418, 418, 418, 418, 418, nil, + nil, 418, 418, nil, nil, nil, nil, nil, 418, 418, + nil, 488, nil, nil, 488, nil, nil, 488, 488, nil, + nil, 488, nil, 488, 418, nil, 418, 488, 418, 418, + 418, 418, 418, 418, 418, 488, 418, nil, nil, nil, + 488, 488, 488, 488, 488, 488, nil, nil, nil, 488, + 488, 492, 492, 492, 492, 492, 492, nil, nil, nil, + 492, 492, nil, nil, nil, 492, nil, 492, 492, 492, + 492, 492, 492, 492, nil, nil, nil, nil, 492, 492, + 492, 492, 492, 492, 492, nil, nil, 492, nil, nil, + nil, nil, nil, 492, 492, 492, 492, 492, 492, 492, + 492, 492, 492, 492, 492, 492, 492, nil, 492, 492, + 492, 492, 492, 419, 419, 419, 419, 419, 419, 419, + nil, nil, 419, 419, nil, nil, nil, nil, nil, 419, + 419, nil, 492, nil, nil, 492, nil, nil, 492, 492, + nil, nil, 492, nil, 492, 419, nil, 419, 492, 419, + 419, 419, 419, 419, 419, 419, 492, 419, nil, nil, + nil, 492, 492, 492, 492, 492, 492, nil, nil, nil, + 492, 492, 497, 497, 497, 497, 497, 497, nil, nil, + nil, 497, 497, nil, nil, nil, 497, nil, 497, 497, + 497, 497, 497, 497, 497, nil, nil, nil, nil, 497, + 497, 497, 497, 497, 497, 497, nil, nil, 497, nil, + nil, nil, nil, nil, 497, 497, 497, 497, 497, 497, + 497, 497, 497, 497, 497, 497, 497, 497, nil, 497, + 497, 497, 497, 497, 420, 420, 420, 420, 420, 420, + 420, nil, nil, 420, 420, nil, nil, nil, nil, nil, + 420, 420, nil, 497, nil, nil, 497, nil, nil, 497, + 497, nil, nil, 497, nil, 497, 420, nil, 420, 497, + 420, 420, 420, 420, 420, 420, 420, 497, 420, nil, + nil, nil, 497, 497, 497, 497, 497, 497, nil, nil, + nil, 497, 497, 515, 515, 515, 515, 515, 515, nil, + nil, nil, 515, 515, nil, nil, nil, 515, nil, 515, + 515, 515, 515, 515, 515, 515, nil, nil, nil, nil, + 515, 515, 515, 515, 515, 515, 515, nil, nil, 515, + nil, nil, nil, nil, nil, 515, 515, 515, 515, 515, + 515, 515, 515, 515, 515, 515, 515, 515, 515, nil, + 515, 515, 515, 515, 515, 423, 423, 423, 423, 423, + 423, 423, nil, nil, 423, 423, nil, nil, nil, nil, + nil, 423, 423, nil, 515, nil, nil, 515, nil, nil, + 515, 515, nil, nil, 515, nil, 515, 423, nil, 423, + 515, 423, 423, 423, 423, 423, 423, 423, 515, 423, + nil, nil, nil, 515, 515, 515, 515, 515, 515, nil, + nil, nil, 515, 515, 561, 561, 561, 561, 561, 561, + nil, nil, nil, 561, 561, nil, nil, nil, 561, nil, + 561, 561, 561, 561, 561, 561, 561, nil, nil, nil, + nil, 561, 561, 561, 561, 561, 561, 561, nil, nil, + 561, nil, nil, nil, nil, nil, 561, 561, 561, 561, + 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, + nil, 561, 561, 561, 561, 561, 424, 424, 424, 424, + 424, 424, 424, 424, nil, 424, 424, nil, nil, nil, + nil, nil, 424, 424, nil, 561, nil, nil, 561, nil, + nil, 561, 561, nil, nil, 561, nil, 561, 424, nil, + 424, 561, 424, 424, 424, 424, 424, 424, 424, 561, + 424, nil, nil, nil, 561, 561, 561, 561, 561, 561, + nil, nil, nil, 561, 561, 590, 590, 590, 590, 590, + 590, nil, nil, nil, 590, 590, nil, nil, nil, 590, + nil, 590, 590, 590, 590, 590, 590, 590, nil, nil, + nil, nil, 590, 590, 590, 590, 590, 590, 590, nil, + nil, 590, nil, nil, nil, nil, nil, 590, 590, 590, + 590, 590, 590, 590, 590, 590, 590, 590, 590, 590, + 590, nil, 590, 590, 590, 590, 590, 408, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 408, 408, nil, 590, nil, nil, 590, + nil, nil, 590, 590, nil, nil, 590, nil, 590, 408, + nil, 408, 590, 408, 408, 408, 408, nil, nil, nil, + 590, nil, nil, nil, nil, 590, 590, 590, 590, 590, + 590, nil, nil, nil, 590, 590, 591, 591, 591, 591, + 591, 591, nil, nil, nil, 591, 591, nil, nil, nil, + 591, nil, 591, 591, 591, 591, 591, 591, 591, nil, + nil, nil, nil, 591, 591, 591, 591, 591, 591, 591, + nil, nil, 591, nil, nil, nil, nil, nil, 591, 591, + 591, 591, 591, 591, 591, 591, 591, 591, 591, 591, + 591, 591, nil, 591, 591, 591, 591, 591, 409, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 409, 409, nil, 591, nil, nil, + 591, nil, nil, 591, 591, nil, nil, 591, nil, 591, + 409, nil, 409, 591, 409, 409, 409, 409, nil, nil, + nil, 591, nil, nil, nil, nil, 591, 591, 591, 591, + 591, 591, nil, nil, nil, 591, 591, 608, 608, 608, + 608, 608, 608, nil, nil, nil, 608, 608, nil, nil, + nil, 608, nil, 608, 608, 608, 608, 608, 608, 608, + nil, nil, nil, nil, 608, 608, 608, 608, 608, 608, + 608, nil, nil, 608, nil, nil, nil, nil, nil, 608, + 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, + 608, 608, 608, nil, 608, 608, 608, 608, 608, 410, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 410, 410, nil, 608, nil, + nil, 608, nil, nil, 608, 608, nil, nil, 608, nil, + 608, 410, nil, nil, 608, 410, 410, 410, 410, nil, + nil, nil, 608, nil, nil, nil, nil, 608, 608, 608, + 608, 608, 608, nil, nil, nil, 608, 608, 641, 641, + 641, 641, 641, 641, nil, nil, nil, 641, 641, nil, + nil, nil, 641, nil, 641, 641, 641, 641, 641, 641, + 641, nil, nil, nil, nil, 641, 641, 641, 641, 641, + 641, 641, nil, nil, 641, nil, nil, nil, nil, nil, + 641, 641, 641, 641, 641, 641, 641, 641, 641, 641, + 641, 641, 641, 641, nil, 641, 641, 641, 641, 641, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 641, + nil, nil, 641, nil, nil, 641, 641, nil, nil, 641, + nil, 641, nil, nil, nil, 641, nil, nil, nil, nil, + nil, nil, nil, 641, nil, nil, nil, nil, 641, 641, + 641, 641, 641, 641, nil, nil, nil, 641, 641, 646, + 646, 646, 646, 646, 646, nil, nil, nil, 646, 646, + nil, nil, nil, 646, nil, 646, 646, 646, 646, 646, + 646, 646, nil, nil, nil, nil, 646, 646, 646, 646, + 646, 646, 646, nil, nil, 646, nil, nil, nil, nil, + nil, 646, 646, 646, 646, 646, 646, 646, 646, 646, + 646, 646, 646, 646, 646, nil, 646, 646, 646, 646, + 646, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 646, nil, nil, 646, nil, nil, 646, 646, nil, nil, + 646, nil, 646, nil, nil, nil, 646, nil, nil, nil, + nil, nil, nil, nil, 646, nil, nil, nil, nil, 646, + 646, 646, 646, 646, 646, nil, nil, nil, 646, 646, + 673, 673, 673, 673, 673, 673, nil, nil, nil, 673, + 673, nil, nil, nil, 673, nil, 673, 673, 673, 673, + 673, 673, 673, nil, nil, nil, nil, 673, 673, 673, + 673, 673, 673, 673, nil, nil, 673, nil, nil, nil, + nil, nil, 673, 673, 673, 673, 673, 673, 673, 673, + 673, 673, 673, 673, 673, 673, nil, 673, 673, 673, + 673, 673, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 673, nil, nil, 673, nil, nil, 673, 673, nil, + nil, 673, nil, 673, nil, nil, nil, 673, nil, nil, + nil, nil, nil, nil, nil, 673, nil, nil, nil, nil, + 673, 673, 673, 673, 673, 673, nil, nil, nil, 673, + 673, 708, 708, 708, 708, 708, 708, nil, nil, nil, + 708, 708, nil, nil, nil, 708, nil, 708, 708, 708, + 708, 708, 708, 708, nil, nil, nil, nil, 708, 708, + 708, 708, 708, 708, 708, nil, nil, 708, nil, nil, + nil, nil, nil, 708, 708, 708, 708, 708, 708, 708, + 708, 708, 708, 708, 708, 708, 708, nil, 708, 708, + 708, 708, 708, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 708, nil, nil, 708, nil, nil, 708, 708, + nil, nil, 708, nil, 708, nil, nil, nil, 708, nil, + nil, nil, nil, nil, nil, nil, 708, nil, nil, nil, + nil, 708, 708, 708, 708, 708, 708, nil, nil, nil, + 708, 708, 726, 726, 726, 726, 726, 726, nil, nil, + nil, 726, 726, nil, nil, nil, 726, nil, 726, 726, + 726, 726, 726, 726, 726, nil, nil, nil, nil, 726, + 726, 726, 726, 726, 726, 726, nil, nil, 726, nil, + nil, nil, nil, nil, 726, 726, 726, 726, 726, 726, + 726, 726, 726, 726, 726, 726, 726, 726, nil, 726, + 726, 726, 726, 726, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 726, nil, nil, 726, nil, nil, 726, + 726, nil, nil, 726, nil, 726, nil, nil, nil, 726, + nil, nil, nil, nil, nil, nil, nil, 726, nil, nil, + nil, nil, 726, 726, 726, 726, 726, 726, nil, nil, + nil, 726, 726, 738, 738, 738, 738, 738, 738, nil, + nil, nil, 738, 738, nil, nil, nil, 738, nil, 738, + 738, 738, 738, 738, 738, 738, nil, nil, nil, nil, + 738, 738, 738, 738, 738, 738, 738, nil, nil, 738, + nil, nil, nil, nil, nil, 738, 738, 738, 738, 738, + 738, 738, 738, 738, 738, 738, 738, 738, 738, nil, + 738, 738, 738, 738, 738, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 738, nil, nil, 738, nil, nil, + 738, 738, nil, nil, 738, nil, 738, nil, nil, nil, + 738, nil, nil, nil, nil, nil, nil, nil, 738, nil, + nil, nil, nil, 738, 738, 738, 738, 738, 738, nil, + nil, nil, 738, 738, 739, 739, 739, 739, 739, 739, + nil, nil, nil, 739, 739, nil, nil, nil, 739, nil, + 739, 739, 739, 739, 739, 739, 739, nil, nil, nil, + nil, 739, 739, 739, 739, 739, 739, 739, nil, nil, + 739, nil, nil, nil, nil, nil, 739, 739, 739, 739, + 739, 739, 739, 739, 739, 739, 739, 739, 739, 739, + nil, 739, 739, 739, 739, 739, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 739, nil, nil, 739, nil, + nil, 739, 739, nil, nil, 739, nil, 739, nil, nil, + nil, 739, nil, nil, nil, nil, nil, nil, nil, 739, + nil, nil, nil, nil, 739, 739, 739, 739, 739, 739, + nil, nil, nil, 739, 739, 743, 743, 743, 743, 743, + 743, nil, nil, nil, 743, 743, nil, nil, nil, 743, + nil, 743, 743, 743, 743, 743, 743, 743, nil, nil, + nil, nil, 743, 743, 743, 743, 743, 743, 743, nil, + nil, 743, nil, nil, nil, nil, nil, 743, 743, 743, + 743, 743, 743, 743, 743, 743, 743, 743, 743, 743, + 743, nil, 743, 743, 743, 743, 743, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 743, nil, nil, 743, + nil, nil, 743, 743, nil, nil, 743, nil, 743, nil, + nil, nil, 743, nil, nil, nil, nil, nil, nil, nil, + 743, nil, nil, nil, nil, 743, 743, 743, 743, 743, + 743, nil, nil, nil, 743, 743, 750, 750, 750, 750, + 750, 750, nil, nil, nil, 750, 750, nil, nil, nil, + 750, nil, 750, 750, 750, 750, 750, 750, 750, nil, + nil, nil, nil, 750, 750, 750, 750, 750, 750, 750, + nil, nil, 750, nil, nil, nil, nil, nil, 750, 750, + 750, 750, 750, 750, 750, 750, 750, 750, 750, 750, + 750, 750, nil, 750, 750, 750, 750, 750, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 750, nil, nil, + 750, nil, nil, 750, 750, nil, nil, 750, nil, 750, + nil, nil, nil, 750, nil, nil, nil, nil, nil, nil, + nil, 750, nil, nil, nil, nil, 750, 750, 750, 750, + 750, 750, nil, nil, nil, 750, 750, 796, 796, 796, + 796, 796, 796, nil, nil, nil, 796, 796, nil, nil, + nil, 796, nil, 796, 796, 796, 796, 796, 796, 796, + nil, nil, nil, nil, 796, 796, 796, 796, 796, 796, + 796, nil, nil, 796, nil, nil, nil, nil, nil, 796, + 796, 796, 796, 796, 796, 796, 796, 796, 796, 796, + 796, 796, 796, nil, 796, 796, 796, 796, 796, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 796, nil, + nil, 796, nil, nil, 796, 796, nil, nil, 796, nil, + 796, nil, nil, nil, 796, nil, nil, nil, nil, nil, + nil, nil, 796, nil, nil, nil, nil, 796, 796, 796, + 796, 796, 796, nil, nil, nil, 796, 796, 840, 840, + 840, 840, 840, 840, nil, nil, nil, 840, 840, nil, + nil, nil, 840, nil, 840, 840, 840, 840, 840, 840, + 840, nil, nil, nil, nil, 840, 840, 840, 840, 840, + 840, 840, nil, nil, 840, nil, nil, nil, nil, nil, + 840, 840, 840, 840, 840, 840, 840, 840, 840, 840, + 840, 840, 840, 840, nil, 840, 840, 840, 840, 840, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 840, + nil, nil, 840, nil, nil, 840, 840, nil, nil, 840, + nil, 840, nil, nil, nil, 840, nil, nil, nil, nil, + nil, nil, nil, 840, nil, nil, nil, nil, 840, 840, + 840, 840, 840, 840, nil, nil, nil, 840, 840, 847, + 847, 847, 847, 847, 847, nil, nil, nil, 847, 847, + nil, nil, nil, 847, nil, 847, 847, 847, 847, 847, + 847, 847, nil, nil, nil, nil, 847, 847, 847, 847, + 847, 847, 847, nil, nil, 847, nil, nil, nil, nil, + nil, 847, 847, 847, 847, 847, 847, 847, 847, 847, + 847, 847, 847, 847, 847, nil, 847, 847, 847, 847, + 847, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 847, nil, nil, 847, nil, nil, 847, 847, nil, nil, + 847, nil, 847, nil, nil, nil, 847, nil, nil, nil, + nil, nil, nil, nil, 847, nil, nil, nil, nil, 847, + 847, 847, 847, 847, 847, nil, nil, nil, 847, 847, + 854, 854, 854, 854, 854, 854, nil, nil, nil, 854, + 854, nil, nil, nil, 854, nil, 854, 854, 854, 854, + 854, 854, 854, nil, nil, nil, nil, 854, 854, 854, + 854, 854, 854, 854, nil, nil, 854, nil, nil, nil, + nil, nil, 854, 854, 854, 854, 854, 854, 854, 854, + 854, 854, 854, 854, 854, 854, nil, 854, 854, 854, + 854, 854, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 854, nil, nil, 854, nil, nil, 854, 854, nil, + nil, 854, nil, 854, nil, nil, nil, 854, nil, nil, + nil, nil, nil, nil, nil, 854, nil, nil, nil, nil, + 854, 854, 854, 854, 854, 854, nil, nil, nil, 854, + 854, 5, 5, 5, 5, 5, nil, nil, nil, 5, + 5, nil, nil, nil, 5, nil, 5, 5, 5, 5, + 5, 5, 5, nil, nil, nil, nil, 5, 5, 5, + 5, 5, 5, 5, nil, nil, 5, nil, nil, nil, + nil, nil, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, nil, 5, 5, 5, + 5, 5, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 5, nil, nil, 5, nil, nil, 5, 5, nil, + nil, 5, nil, 5, nil, nil, nil, 5, nil, nil, + nil, nil, nil, nil, nil, 5, nil, nil, nil, nil, + 5, 5, 5, 5, 5, 5, nil, nil, nil, 5, + 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, nil, nil, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, nil, nil, nil, + nil, nil, 6, 6, 6, 6, 6, 6, 6, 6, + 6, nil, 6, nil, nil, nil, nil, nil, nil, 6, + 6, nil, 6, 6, 6, 6, nil, 6, 6, nil, + nil, 6, nil, nil, nil, nil, 6, 6, 6, 6, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 6, 6, nil, 6, 6, 6, 6, + 6, 6, 6, 6, 6, nil, 6, nil, nil, 6, + 6, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, nil, nil, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, nil, nil, nil, + nil, nil, 7, 7, 7, 7, 7, 7, 7, 7, + nil, nil, 7, nil, nil, nil, nil, nil, nil, 7, + 7, nil, 7, 7, 7, 7, nil, 7, 7, nil, + nil, 7, nil, nil, nil, nil, 7, 7, 7, 7, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 7, 7, nil, 7, 7, 7, 7, + 7, 7, 7, 7, 7, nil, 7, nil, nil, 7, + 7, nil, nil, 17, 17, 17, nil, 17, nil, nil, + 7, 17, 17, nil, nil, nil, 17, nil, 17, 17, + 17, 17, 17, 17, 17, nil, nil, nil, nil, 17, + 17, 17, 17, 17, 17, 17, nil, nil, 17, nil, + nil, nil, nil, nil, nil, 17, nil, nil, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, nil, 17, + 17, 17, 17, 17, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 17, nil, nil, 17, nil, nil, 17, + 17, nil, nil, 17, nil, nil, nil, nil, nil, 17, + nil, nil, nil, nil, nil, nil, nil, 17, nil, nil, + nil, nil, 17, 17, 17, 17, 17, 17, nil, nil, + nil, 17, 17, 18, 18, 18, nil, 18, nil, nil, + nil, 18, 18, nil, nil, nil, 18, nil, 18, 18, + 18, 18, 18, 18, 18, nil, nil, nil, nil, 18, + 18, 18, 18, 18, 18, 18, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 18, nil, nil, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, nil, 18, + 18, 18, 18, 18, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 18, nil, nil, 18, nil, nil, 18, + 18, nil, nil, 18, nil, nil, nil, nil, nil, 18, + nil, nil, nil, nil, nil, nil, nil, 18, nil, nil, + nil, nil, 18, 18, 18, 18, 18, 18, nil, nil, + nil, 18, 18, 22, 22, 22, nil, 22, nil, nil, + nil, 22, 22, nil, nil, nil, 22, nil, 22, 22, + 22, 22, 22, 22, 22, nil, nil, nil, nil, 22, + 22, 22, 22, 22, 22, 22, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 22, nil, nil, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, nil, 22, + 22, 22, 22, 22, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 22, nil, nil, 22, nil, nil, 22, + 22, nil, nil, 22, nil, 22, nil, 22, nil, 22, + nil, nil, nil, nil, nil, nil, nil, 22, nil, nil, + nil, nil, 22, 22, 22, 22, 22, 22, nil, nil, + nil, 22, 22, 23, 23, 23, nil, 23, nil, nil, + nil, 23, 23, nil, nil, nil, 23, nil, 23, 23, + 23, 23, 23, 23, 23, nil, nil, nil, nil, 23, + 23, 23, 23, 23, 23, 23, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 23, nil, nil, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, nil, 23, + 23, 23, 23, 23, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 23, nil, nil, 23, nil, nil, 23, + 23, nil, nil, 23, nil, 23, nil, 23, nil, 23, + nil, nil, nil, nil, nil, nil, nil, 23, nil, nil, + nil, nil, 23, 23, 23, 23, 23, 23, nil, nil, + nil, 23, 23, 24, 24, 24, nil, 24, nil, nil, + nil, 24, 24, nil, nil, nil, 24, nil, 24, 24, + 24, 24, 24, 24, 24, nil, nil, nil, nil, 24, + 24, 24, 24, 24, 24, 24, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 24, nil, nil, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, nil, 24, + 24, 24, 24, 24, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 24, nil, nil, 24, nil, nil, 24, + 24, nil, nil, 24, nil, 24, nil, 24, nil, 24, + nil, nil, nil, nil, nil, nil, nil, 24, nil, nil, + nil, nil, 24, 24, 24, 24, 24, 24, nil, nil, + nil, 24, 24, 27, 27, 27, nil, 27, nil, nil, + nil, 27, 27, nil, nil, nil, 27, nil, 27, 27, + 27, 27, 27, 27, 27, nil, nil, nil, nil, 27, + 27, 27, 27, 27, 27, 27, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 27, nil, nil, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, nil, 27, + 27, 27, 27, 27, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 27, nil, nil, 27, 27, nil, 27, + 27, nil, nil, 27, nil, 27, nil, 27, nil, 27, + nil, nil, nil, nil, nil, nil, nil, 27, nil, nil, + nil, nil, 27, 27, 27, 27, 27, 27, nil, nil, + nil, 27, 27, 28, 28, 28, nil, 28, nil, nil, + nil, 28, 28, nil, nil, nil, 28, nil, 28, 28, + 28, 28, 28, 28, 28, nil, nil, nil, nil, 28, + 28, 28, 28, 28, 28, 28, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 28, nil, nil, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, nil, 28, + 28, 28, 28, 28, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 28, nil, nil, 28, 28, nil, 28, + 28, nil, nil, 28, nil, 28, nil, 28, nil, 28, + nil, nil, nil, nil, nil, nil, nil, 28, nil, nil, + nil, nil, 28, 28, 28, 28, 28, 28, nil, nil, + nil, 28, 28, 31, 31, 31, nil, 31, nil, nil, + nil, 31, 31, nil, nil, nil, 31, nil, 31, 31, + 31, 31, 31, 31, 31, nil, nil, nil, nil, 31, + 31, 31, 31, 31, 31, 31, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 31, nil, nil, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, nil, 31, + 31, nil, nil, 31, nil, 830, 830, 830, 830, 830, + 830, 830, 830, 830, 830, 830, nil, 830, 830, nil, + nil, 830, 830, 31, nil, nil, 31, nil, nil, 31, + 31, nil, nil, 31, nil, 31, nil, 830, nil, 830, + nil, 830, 830, 830, 830, 830, 830, 830, nil, 830, + nil, nil, 31, 31, 31, 31, 31, 31, nil, nil, + nil, 31, 31, 32, 32, 32, 830, 32, 830, nil, + nil, 32, 32, nil, nil, nil, 32, nil, 32, 32, + 32, 32, 32, 32, 32, nil, nil, nil, nil, 32, + 32, 32, 32, 32, 32, 32, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 32, nil, nil, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, nil, 32, + 32, nil, nil, 32, nil, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, nil, 19, 19, nil, + nil, 19, 19, 32, nil, nil, 32, nil, nil, 32, + 32, nil, nil, 32, nil, nil, nil, 19, nil, 19, + nil, 19, 19, 19, 19, 19, 19, 19, nil, 19, + nil, nil, 32, 32, 32, 32, 32, 32, nil, nil, + nil, 32, 32, 38, 38, 38, 19, 38, nil, nil, + nil, 38, 38, nil, nil, nil, 38, nil, 38, 38, + 38, 38, 38, 38, 38, nil, nil, nil, nil, 38, + 38, 38, 38, 38, 38, 38, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 38, nil, nil, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, nil, 38, + 38, 38, 38, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 38, nil, nil, 38, nil, nil, 38, + 38, nil, nil, 38, nil, nil, nil, nil, nil, 38, + nil, nil, nil, nil, nil, nil, nil, 38, nil, nil, + nil, nil, 38, 38, 38, 38, 38, 38, nil, nil, + nil, 38, 38, 39, 39, 39, nil, 39, nil, nil, + nil, 39, 39, nil, nil, nil, 39, nil, 39, 39, + 39, 39, 39, 39, 39, nil, nil, nil, nil, 39, + 39, 39, 39, 39, 39, 39, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 39, nil, nil, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, nil, 39, + 39, 39, 39, 39, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 39, nil, nil, 39, nil, nil, 39, + 39, nil, nil, 39, nil, nil, nil, nil, nil, 39, + nil, nil, nil, nil, nil, nil, nil, 39, nil, nil, + nil, nil, 39, 39, 39, 39, 39, 39, nil, nil, + nil, 39, 39, 40, 40, 40, nil, 40, nil, nil, + nil, 40, 40, nil, nil, nil, 40, nil, 40, 40, + 40, 40, 40, 40, 40, nil, nil, nil, nil, 40, + 40, 40, 40, 40, 40, 40, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 40, nil, nil, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, nil, 40, + 40, 40, 40, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 40, nil, nil, 40, nil, nil, 40, + 40, nil, nil, 40, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, 40, 40, 40, 40, 40, 40, nil, nil, + nil, 40, 40, 52, 52, 52, nil, 52, nil, nil, + nil, 52, 52, nil, nil, nil, 52, nil, 52, 52, + 52, 52, 52, 52, 52, nil, nil, nil, nil, 52, + 52, 52, 52, 52, 52, 52, nil, nil, 52, nil, + nil, nil, nil, nil, nil, 52, nil, nil, 52, 52, + 52, 52, 52, 52, 52, 52, 52, 52, nil, 52, + 52, 52, 52, 52, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 52, nil, nil, 52, nil, nil, 52, + 52, nil, nil, 52, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, 52, 52, 52, 52, 52, 52, nil, nil, + nil, 52, 52, 53, 53, 53, nil, 53, nil, nil, + nil, 53, 53, nil, nil, nil, 53, nil, 53, 53, + 53, 53, 53, 53, 53, nil, nil, nil, nil, 53, + 53, 53, 53, 53, 53, 53, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, nil, 53, + 53, 53, 53, 53, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 53, nil, nil, 53, + 53, nil, nil, 53, nil, 53, nil, nil, nil, 53, + nil, nil, nil, nil, nil, nil, nil, 53, nil, nil, + nil, nil, 53, 53, 53, 53, 53, 53, nil, nil, + nil, 53, 53, 54, 54, 54, nil, 54, nil, nil, + nil, 54, 54, nil, nil, nil, 54, nil, 54, 54, + 54, 54, 54, 54, 54, nil, nil, nil, nil, 54, + 54, 54, 54, 54, 54, 54, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 54, nil, nil, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, nil, 54, + 54, 54, 54, 54, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 54, nil, nil, 54, nil, nil, 54, + 54, nil, nil, 54, nil, nil, nil, nil, nil, 54, + nil, nil, nil, nil, nil, nil, nil, 54, nil, nil, + nil, nil, 54, 54, 54, 54, 54, 54, nil, nil, + nil, 54, 54, 56, 56, 56, nil, 56, nil, nil, + nil, 56, 56, nil, nil, nil, 56, nil, 56, 56, + 56, 56, 56, 56, 56, nil, nil, nil, nil, 56, + 56, 56, 56, 56, 56, 56, nil, nil, 56, nil, + nil, nil, nil, nil, nil, 56, nil, nil, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, nil, 56, + 56, 56, 56, 56, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 56, nil, nil, 56, nil, nil, 56, + 56, nil, nil, 56, nil, nil, nil, nil, nil, 56, + nil, nil, nil, nil, nil, nil, nil, 56, nil, nil, + nil, nil, 56, 56, 56, 56, 56, 56, nil, nil, + nil, 56, 56, 57, 57, 57, nil, 57, nil, nil, + nil, 57, 57, nil, nil, nil, 57, nil, 57, 57, + 57, 57, 57, 57, 57, nil, nil, nil, nil, 57, + 57, 57, 57, 57, 57, 57, nil, nil, 57, nil, + nil, nil, nil, nil, nil, 57, nil, nil, 57, 57, + 57, 57, 57, 57, 57, 57, 57, 57, nil, 57, + 57, 57, 57, 57, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 57, nil, nil, 57, nil, nil, 57, + 57, nil, nil, 57, nil, nil, nil, nil, nil, 57, + nil, nil, nil, nil, nil, nil, nil, 57, nil, nil, + nil, nil, 57, 57, 57, 57, 57, 57, nil, nil, + nil, 57, 57, 61, 61, 61, nil, 61, nil, nil, + nil, 61, 61, nil, nil, nil, 61, nil, 61, 61, + 61, 61, 61, 61, 61, nil, nil, nil, nil, 61, + 61, 61, 61, 61, 61, 61, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 61, nil, nil, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, nil, 61, + 61, nil, nil, 61, nil, 239, 239, 239, 239, 239, + 239, 239, 239, 239, 239, 239, nil, 239, 239, nil, + nil, 239, 239, 61, nil, nil, 61, nil, nil, 61, + 61, nil, nil, 61, nil, 61, nil, 239, nil, 239, + nil, 239, 239, 239, 239, 239, 239, 239, nil, 239, + nil, nil, 61, 61, 61, 61, 61, 61, nil, nil, + nil, 61, 61, 62, 62, 62, 239, 62, nil, nil, + nil, 62, 62, nil, nil, nil, 62, nil, 62, 62, + 62, 62, 62, 62, 62, nil, nil, nil, nil, 62, + 62, 62, 62, 62, 62, 62, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 62, nil, nil, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, nil, 62, + 62, nil, nil, 62, nil, 376, 376, 376, 376, 376, + 376, 376, 376, 376, 376, 376, nil, 376, 376, nil, + 62, 376, 376, 62, nil, nil, 62, nil, nil, 62, + 62, nil, nil, 62, nil, nil, nil, 376, nil, 376, + nil, 376, 376, 376, 376, 376, 376, 376, nil, 376, + nil, nil, 62, 62, 62, 62, 62, 62, nil, nil, + nil, 62, 62, 63, 63, 63, 376, 63, nil, nil, + nil, 63, 63, nil, nil, nil, 63, nil, 63, 63, + 63, 63, 63, 63, 63, nil, nil, nil, nil, 63, + 63, 63, 63, 63, 63, 63, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 63, nil, nil, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, nil, 63, + 63, nil, nil, 63, nil, 390, 390, 390, 390, 390, + 390, 390, 390, 390, 390, 390, nil, 390, 390, nil, + nil, 390, 390, 63, nil, nil, 63, nil, nil, 63, + 63, nil, nil, 63, nil, nil, nil, 390, nil, 390, + nil, 390, 390, 390, 390, 390, 390, 390, nil, 390, + nil, nil, 63, 63, 63, 63, 63, 63, nil, nil, + nil, 63, 63, 84, 84, 84, 390, 84, nil, nil, + nil, 84, 84, nil, nil, nil, 84, nil, 84, 84, + 84, 84, 84, 84, 84, nil, 84, nil, nil, 84, + 84, 84, 84, 84, 84, 84, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 84, nil, nil, 84, 84, + 84, 84, 84, 84, 84, 84, 84, 84, nil, 84, + 84, 84, 84, 84, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 84, nil, nil, 84, 84, nil, 84, + 84, nil, nil, 84, nil, 84, nil, 84, nil, 84, + nil, nil, nil, nil, nil, nil, nil, 84, nil, 84, + nil, nil, 84, 84, 84, 84, 84, 84, nil, nil, + nil, 84, 84, 88, 88, 88, nil, 88, nil, nil, + nil, 88, 88, nil, nil, nil, 88, nil, 88, 88, + 88, 88, 88, 88, 88, nil, 88, nil, nil, 88, + 88, 88, 88, 88, 88, 88, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 88, nil, nil, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, nil, 88, + 88, 88, 88, 88, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 88, nil, nil, 88, 88, nil, 88, + 88, nil, nil, 88, nil, 88, nil, 88, nil, 88, + nil, nil, nil, nil, nil, nil, nil, 88, nil, 88, + nil, nil, 88, 88, 88, 88, 88, 88, nil, nil, + nil, 88, 88, 103, 103, 103, nil, 103, nil, nil, + nil, 103, 103, nil, nil, nil, 103, nil, 103, 103, + 103, 103, 103, 103, 103, nil, nil, nil, nil, 103, + 103, 103, 103, 103, 103, 103, nil, nil, 103, nil, + nil, nil, nil, nil, nil, 103, nil, nil, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, nil, 103, + 103, 103, 103, 103, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 103, nil, nil, 103, nil, nil, 103, + 103, nil, nil, 103, nil, nil, nil, nil, nil, 103, + nil, nil, nil, nil, nil, nil, nil, 103, nil, nil, + nil, nil, 103, 103, 103, 103, 103, 103, nil, nil, + nil, 103, 103, 104, 104, 104, nil, 104, nil, nil, + nil, 104, 104, nil, nil, nil, 104, nil, 104, 104, + 104, 104, 104, 104, 104, nil, nil, nil, nil, 104, + 104, 104, 104, 104, 104, 104, nil, nil, 104, nil, + nil, nil, nil, nil, nil, 104, nil, nil, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, nil, 104, + 104, 104, 104, 104, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 104, nil, nil, 104, nil, nil, 104, + 104, nil, nil, 104, nil, nil, nil, nil, nil, 104, + nil, nil, nil, nil, nil, nil, nil, 104, nil, nil, + nil, nil, 104, 104, 104, 104, 104, 104, nil, nil, + nil, 104, 104, 105, 105, 105, nil, 105, nil, nil, + nil, 105, 105, nil, nil, nil, 105, nil, 105, 105, + 105, 105, 105, 105, 105, nil, nil, nil, nil, 105, + 105, 105, 105, 105, 105, 105, nil, nil, 105, nil, + nil, nil, nil, nil, nil, 105, nil, nil, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, nil, 105, + 105, 105, 105, 105, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 105, nil, nil, 105, nil, nil, 105, + 105, nil, nil, 105, nil, nil, nil, nil, nil, 105, + nil, nil, nil, nil, nil, nil, nil, 105, nil, nil, + nil, nil, 105, 105, 105, 105, 105, 105, nil, nil, + nil, 105, 105, 106, 106, 106, nil, 106, nil, nil, + nil, 106, 106, nil, nil, nil, 106, nil, 106, 106, + 106, 106, 106, 106, 106, nil, nil, nil, nil, 106, + 106, 106, 106, 106, 106, 106, nil, nil, 106, nil, + nil, nil, nil, nil, nil, 106, nil, nil, 106, 106, + 106, 106, 106, 106, 106, 106, 106, 106, nil, 106, + 106, 106, 106, 106, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 106, nil, nil, 106, nil, nil, 106, + 106, nil, nil, 106, nil, nil, nil, nil, nil, 106, + nil, nil, nil, nil, nil, nil, nil, 106, nil, nil, + nil, nil, 106, 106, 106, 106, 106, 106, nil, nil, + nil, 106, 106, 107, 107, 107, 107, 107, nil, nil, + nil, 107, 107, nil, nil, nil, 107, nil, 107, 107, + 107, 107, 107, 107, 107, nil, nil, nil, nil, 107, + 107, 107, 107, 107, 107, 107, nil, nil, 107, nil, + nil, nil, nil, nil, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, nil, 107, + 107, 107, 107, 107, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 107, nil, nil, 107, nil, nil, 107, + 107, nil, nil, 107, nil, 107, nil, nil, nil, 107, + nil, nil, nil, nil, nil, nil, nil, 107, nil, nil, + nil, nil, 107, 107, 107, 107, 107, 107, nil, nil, + nil, 107, 107, 190, 190, 190, nil, 190, nil, nil, + nil, 190, 190, nil, nil, nil, 190, nil, 190, 190, + 190, 190, 190, 190, 190, nil, nil, nil, nil, 190, + 190, 190, 190, 190, 190, 190, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 190, nil, nil, 190, 190, + 190, 190, 190, 190, 190, 190, 190, 190, nil, 190, + 190, 190, 190, 190, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 190, nil, nil, 190, nil, nil, 190, + 190, nil, nil, 190, nil, 190, nil, nil, nil, 190, + nil, nil, nil, nil, nil, nil, nil, 190, nil, nil, + nil, nil, 190, 190, 190, 190, 190, 190, nil, nil, + nil, 190, 190, 191, 191, 191, nil, 191, nil, nil, + nil, 191, 191, nil, nil, nil, 191, nil, 191, 191, + 191, 191, 191, 191, 191, nil, nil, nil, nil, 191, + 191, 191, 191, 191, 191, 191, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 191, nil, nil, 191, 191, + 191, 191, 191, 191, 191, 191, 191, 191, nil, 191, + 191, 191, 191, 191, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 191, nil, nil, 191, nil, nil, 191, + 191, nil, nil, 191, nil, 191, nil, nil, nil, 191, + nil, nil, nil, nil, nil, nil, nil, 191, nil, nil, + nil, nil, 191, 191, 191, 191, 191, 191, nil, nil, + nil, 191, 191, 192, 192, 192, nil, 192, nil, nil, + nil, 192, 192, nil, nil, nil, 192, nil, 192, 192, + 192, 192, 192, 192, 192, nil, nil, nil, nil, 192, + 192, 192, 192, 192, 192, 192, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 192, nil, nil, 192, 192, + 192, 192, 192, 192, 192, 192, 192, 192, nil, 192, + 192, 192, 192, 192, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 192, nil, nil, 192, nil, nil, 192, + 192, nil, nil, 192, nil, nil, nil, nil, nil, 192, + nil, nil, nil, nil, nil, nil, nil, 192, nil, nil, + nil, nil, 192, 192, 192, 192, 192, 192, nil, nil, + nil, 192, 192, 193, 193, 193, nil, 193, nil, nil, + nil, 193, 193, nil, nil, nil, 193, nil, 193, 193, + 193, 193, 193, 193, 193, nil, nil, nil, nil, 193, + 193, 193, 193, 193, 193, 193, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 193, nil, nil, 193, 193, + 193, 193, 193, 193, 193, 193, 193, 193, nil, 193, + 193, 193, 193, 193, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 193, nil, nil, 193, nil, nil, 193, + 193, nil, nil, 193, nil, 193, nil, nil, nil, 193, + nil, nil, nil, nil, nil, nil, nil, 193, nil, nil, + nil, nil, 193, 193, 193, 193, 193, 193, nil, nil, + nil, 193, 193, 196, 196, 196, nil, 196, nil, nil, + nil, 196, 196, nil, nil, nil, 196, nil, 196, 196, + 196, 196, 196, 196, 196, nil, nil, nil, nil, 196, + 196, 196, 196, 196, 196, 196, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 196, nil, nil, 196, 196, + 196, 196, 196, 196, 196, 196, 196, 196, nil, 196, + 196, 196, 196, 196, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 196, nil, nil, 196, nil, nil, 196, + 196, nil, nil, 196, nil, nil, nil, nil, nil, 196, + nil, nil, nil, nil, nil, nil, nil, 196, nil, nil, + nil, nil, 196, 196, 196, 196, 196, 196, nil, nil, + nil, 196, 196, 197, 197, 197, nil, 197, nil, nil, + nil, 197, 197, nil, nil, nil, 197, nil, 197, 197, + 197, 197, 197, 197, 197, nil, nil, nil, nil, 197, + 197, 197, 197, 197, 197, 197, nil, nil, 197, nil, + nil, nil, nil, nil, nil, 197, nil, nil, 197, 197, + 197, 197, 197, 197, 197, 197, 197, 197, nil, 197, + 197, 197, 197, 197, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 197, nil, nil, 197, nil, nil, 197, + 197, nil, nil, 197, nil, nil, nil, nil, nil, 197, + nil, nil, nil, nil, nil, nil, nil, 197, nil, nil, + nil, nil, 197, 197, 197, 197, 197, 197, nil, nil, + nil, 197, 197, 198, 198, 198, nil, 198, nil, nil, + nil, 198, 198, nil, nil, nil, 198, nil, 198, 198, + 198, 198, 198, 198, 198, nil, nil, nil, nil, 198, + 198, 198, 198, 198, 198, 198, nil, nil, 198, nil, + nil, nil, nil, nil, nil, 198, nil, nil, 198, 198, + 198, 198, 198, 198, 198, 198, 198, 198, nil, 198, + 198, 198, 198, 198, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 198, nil, nil, 198, nil, nil, 198, + 198, nil, nil, 198, nil, nil, nil, nil, nil, 198, + nil, nil, nil, nil, nil, nil, nil, 198, nil, nil, + nil, nil, 198, 198, 198, 198, 198, 198, nil, nil, + nil, 198, 198, 209, 209, 209, nil, 209, nil, nil, + nil, 209, 209, nil, nil, nil, 209, nil, 209, 209, + 209, 209, 209, 209, 209, nil, nil, nil, nil, 209, + 209, 209, 209, 209, 209, 209, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 209, nil, nil, 209, 209, + 209, 209, 209, 209, 209, 209, 209, 209, nil, 209, + 209, 209, 209, 209, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 209, nil, nil, 209, nil, nil, 209, + 209, nil, nil, 209, nil, nil, nil, nil, nil, 209, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 209, 209, 209, 209, 209, 209, nil, nil, + nil, 209, 209, 210, 210, 210, nil, 210, nil, nil, + nil, 210, 210, nil, nil, nil, 210, nil, 210, 210, + 210, 210, 210, 210, 210, nil, nil, nil, nil, 210, + 210, 210, 210, 210, 210, 210, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 210, nil, nil, 210, 210, + 210, 210, 210, 210, 210, 210, 210, 210, nil, 210, + 210, 210, 210, 210, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 210, nil, nil, 210, nil, nil, 210, + 210, nil, nil, 210, nil, nil, nil, nil, nil, 210, + nil, nil, nil, nil, nil, nil, nil, 210, nil, nil, + nil, nil, 210, 210, 210, 210, 210, 210, nil, nil, + nil, 210, 210, 211, 211, 211, nil, 211, nil, nil, + nil, 211, 211, nil, nil, nil, 211, nil, 211, 211, + 211, 211, 211, 211, 211, nil, nil, nil, nil, 211, + 211, 211, 211, 211, 211, 211, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 211, nil, nil, 211, 211, + 211, 211, 211, 211, 211, 211, 211, 211, nil, 211, + 211, 211, 211, 211, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 211, nil, nil, 211, nil, nil, 211, + 211, nil, nil, 211, nil, nil, nil, nil, nil, 211, + nil, nil, nil, nil, nil, nil, nil, 211, nil, nil, + nil, nil, 211, 211, 211, 211, 211, 211, nil, nil, + nil, 211, 211, 212, 212, 212, nil, 212, nil, nil, + nil, 212, 212, nil, nil, nil, 212, nil, 212, 212, + 212, 212, 212, 212, 212, nil, nil, nil, nil, 212, + 212, 212, 212, 212, 212, 212, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 212, nil, nil, 212, 212, + 212, 212, 212, 212, 212, 212, 212, 212, nil, 212, + 212, 212, 212, 212, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 212, nil, nil, 212, nil, nil, 212, + 212, nil, nil, 212, nil, nil, nil, nil, nil, 212, + nil, nil, nil, nil, nil, nil, nil, 212, nil, nil, + nil, nil, 212, 212, 212, 212, 212, 212, nil, nil, + nil, 212, 212, 213, 213, 213, nil, 213, nil, nil, + nil, 213, 213, nil, nil, nil, 213, nil, 213, 213, + 213, 213, 213, 213, 213, nil, nil, nil, nil, 213, + 213, 213, 213, 213, 213, 213, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 213, nil, nil, 213, 213, + 213, 213, 213, 213, 213, 213, 213, 213, nil, 213, + 213, 213, 213, 213, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 213, nil, nil, 213, nil, nil, 213, + 213, nil, nil, 213, nil, nil, nil, nil, nil, 213, + nil, nil, nil, nil, nil, nil, nil, 213, nil, nil, + nil, nil, 213, 213, 213, 213, 213, 213, nil, nil, + nil, 213, 213, 214, 214, 214, nil, 214, nil, nil, + nil, 214, 214, nil, nil, nil, 214, nil, 214, 214, + 214, 214, 214, 214, 214, nil, nil, nil, nil, 214, + 214, 214, 214, 214, 214, 214, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 214, nil, nil, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, nil, 214, + 214, 214, 214, 214, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 214, nil, nil, 214, nil, nil, 214, + 214, nil, nil, 214, nil, nil, nil, nil, nil, 214, + nil, nil, nil, nil, nil, nil, nil, 214, nil, nil, + nil, nil, 214, 214, 214, 214, 214, 214, nil, nil, + nil, 214, 214, 215, 215, 215, nil, 215, nil, nil, + nil, 215, 215, nil, nil, nil, 215, nil, 215, 215, + 215, 215, 215, 215, 215, nil, nil, nil, nil, 215, + 215, 215, 215, 215, 215, 215, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 215, nil, nil, 215, 215, + 215, 215, 215, 215, 215, 215, 215, 215, nil, 215, + 215, 215, 215, 215, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 215, nil, nil, 215, nil, nil, 215, + 215, nil, nil, 215, nil, nil, nil, nil, nil, 215, + nil, nil, nil, nil, nil, nil, nil, 215, nil, nil, + nil, nil, 215, 215, 215, 215, 215, 215, nil, nil, + nil, 215, 215, 216, 216, 216, nil, 216, nil, nil, + nil, 216, 216, nil, nil, nil, 216, nil, 216, 216, + 216, 216, 216, 216, 216, nil, nil, nil, nil, 216, + 216, 216, 216, 216, 216, 216, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 216, nil, nil, 216, 216, + 216, 216, 216, 216, 216, 216, 216, 216, nil, 216, + 216, 216, 216, 216, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 216, nil, nil, 216, + 216, nil, nil, 216, nil, nil, nil, nil, nil, 216, + nil, nil, nil, nil, nil, nil, nil, 216, nil, nil, + nil, nil, 216, 216, 216, 216, 216, 216, nil, nil, + nil, 216, 216, 217, 217, 217, nil, 217, nil, nil, + nil, 217, 217, nil, nil, nil, 217, nil, 217, 217, + 217, 217, 217, 217, 217, nil, nil, nil, nil, 217, + 217, 217, 217, 217, 217, 217, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 217, nil, nil, 217, 217, + 217, 217, 217, 217, 217, 217, 217, 217, nil, 217, + 217, 217, 217, 217, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 217, nil, nil, 217, nil, nil, 217, + 217, nil, nil, 217, nil, nil, nil, nil, nil, 217, + nil, nil, nil, nil, nil, nil, nil, 217, nil, nil, + nil, nil, 217, 217, 217, 217, 217, 217, nil, nil, + nil, 217, 217, 218, 218, 218, nil, 218, nil, nil, + nil, 218, 218, nil, nil, nil, 218, nil, 218, 218, + 218, 218, 218, 218, 218, nil, nil, nil, nil, 218, + 218, 218, 218, 218, 218, 218, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 218, nil, nil, 218, 218, + 218, 218, 218, 218, 218, 218, 218, 218, nil, 218, + 218, 218, 218, 218, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 218, nil, nil, 218, nil, nil, 218, + 218, nil, nil, 218, nil, nil, nil, nil, nil, 218, + nil, nil, nil, nil, nil, nil, nil, 218, nil, nil, + nil, nil, 218, 218, 218, 218, 218, 218, nil, nil, + nil, 218, 218, 219, 219, 219, nil, 219, nil, nil, + nil, 219, 219, nil, nil, nil, 219, nil, 219, 219, + 219, 219, 219, 219, 219, nil, nil, nil, nil, 219, + 219, 219, 219, 219, 219, 219, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 219, nil, nil, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 219, nil, 219, + 219, 219, 219, 219, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 219, nil, nil, 219, nil, nil, 219, + 219, nil, nil, 219, nil, nil, nil, nil, nil, 219, + nil, nil, nil, nil, nil, nil, nil, 219, nil, nil, + nil, nil, 219, 219, 219, 219, 219, 219, nil, nil, + nil, 219, 219, 220, 220, 220, nil, 220, nil, nil, + nil, 220, 220, nil, nil, nil, 220, nil, 220, 220, + 220, 220, 220, 220, 220, nil, nil, nil, nil, 220, + 220, 220, 220, 220, 220, 220, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 220, nil, nil, 220, 220, + 220, 220, 220, 220, 220, 220, 220, 220, nil, 220, + 220, 220, 220, 220, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 220, nil, nil, 220, nil, nil, 220, + 220, nil, nil, 220, nil, nil, nil, nil, nil, 220, + nil, nil, nil, nil, nil, nil, nil, 220, nil, nil, + nil, nil, 220, 220, 220, 220, 220, 220, nil, nil, + nil, 220, 220, 221, 221, 221, nil, 221, nil, nil, + nil, 221, 221, nil, nil, nil, 221, nil, 221, 221, + 221, 221, 221, 221, 221, nil, nil, nil, nil, 221, + 221, 221, 221, 221, 221, 221, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 221, nil, nil, 221, 221, + 221, 221, 221, 221, 221, 221, 221, 221, nil, 221, + 221, 221, 221, 221, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 221, nil, nil, 221, nil, nil, 221, + 221, nil, nil, 221, nil, nil, nil, nil, nil, 221, + nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, + nil, nil, 221, 221, 221, 221, 221, 221, nil, nil, + nil, 221, 221, 222, 222, 222, nil, 222, nil, nil, + nil, 222, 222, nil, nil, nil, 222, nil, 222, 222, + 222, 222, 222, 222, 222, nil, nil, nil, nil, 222, + 222, 222, 222, 222, 222, 222, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 222, nil, nil, 222, 222, + 222, 222, 222, 222, 222, 222, 222, 222, nil, 222, + 222, 222, 222, 222, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 222, nil, nil, 222, nil, nil, 222, + 222, nil, nil, 222, nil, nil, nil, nil, nil, 222, + nil, nil, nil, nil, nil, nil, nil, 222, nil, nil, + nil, nil, 222, 222, 222, 222, 222, 222, nil, nil, + nil, 222, 222, 223, 223, 223, nil, 223, nil, nil, + nil, 223, 223, nil, nil, nil, 223, nil, 223, 223, + 223, 223, 223, 223, 223, nil, nil, nil, nil, 223, + 223, 223, 223, 223, 223, 223, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 223, nil, nil, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, nil, 223, + 223, 223, 223, 223, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 223, nil, nil, 223, nil, nil, 223, + 223, nil, nil, 223, nil, nil, nil, nil, nil, 223, + nil, nil, nil, nil, nil, nil, nil, 223, nil, nil, + nil, nil, 223, 223, 223, 223, 223, 223, nil, nil, + nil, 223, 223, 224, 224, 224, nil, 224, nil, nil, + nil, 224, 224, nil, nil, nil, 224, nil, 224, 224, + 224, 224, 224, 224, 224, nil, nil, nil, nil, 224, + 224, 224, 224, 224, 224, 224, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 224, nil, nil, 224, 224, + 224, 224, 224, 224, 224, 224, 224, 224, nil, 224, + 224, 224, 224, 224, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 224, nil, nil, 224, nil, nil, 224, + 224, nil, nil, 224, nil, nil, nil, nil, nil, 224, + nil, nil, nil, nil, nil, nil, nil, 224, nil, nil, + nil, nil, 224, 224, 224, 224, 224, 224, nil, nil, + nil, 224, 224, 225, 225, 225, nil, 225, nil, nil, + nil, 225, 225, nil, nil, nil, 225, nil, 225, 225, + 225, 225, 225, 225, 225, nil, nil, nil, nil, 225, + 225, 225, 225, 225, 225, 225, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, nil, 225, 225, + 225, 225, 225, 225, 225, 225, 225, 225, nil, 225, + 225, 225, 225, 225, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, nil, 225, nil, nil, 225, + 225, nil, nil, 225, nil, nil, nil, nil, nil, 225, + nil, nil, nil, nil, nil, nil, nil, 225, nil, nil, + nil, nil, 225, 225, 225, 225, 225, 225, nil, nil, + nil, 225, 225, 226, 226, 226, nil, 226, nil, nil, + nil, 226, 226, nil, nil, nil, 226, nil, 226, 226, + 226, 226, 226, 226, 226, nil, nil, nil, nil, 226, + 226, 226, 226, 226, 226, 226, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 226, nil, nil, 226, 226, + 226, 226, 226, 226, 226, 226, 226, 226, nil, 226, + 226, 226, 226, 226, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 226, nil, nil, 226, nil, nil, 226, + 226, nil, nil, 226, nil, nil, nil, nil, nil, 226, + nil, nil, nil, nil, nil, nil, nil, 226, nil, nil, + nil, nil, 226, 226, 226, 226, 226, 226, nil, nil, + nil, 226, 226, 227, 227, 227, nil, 227, nil, nil, + nil, 227, 227, nil, nil, nil, 227, nil, 227, 227, + 227, 227, 227, 227, 227, nil, nil, nil, nil, 227, + 227, 227, 227, 227, 227, 227, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, 227, 227, + 227, 227, 227, 227, 227, 227, 227, 227, nil, 227, + 227, 227, 227, 227, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, 227, nil, nil, 227, + 227, nil, nil, 227, nil, nil, nil, nil, nil, 227, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + nil, nil, 227, 227, 227, 227, 227, 227, nil, nil, + nil, 227, 227, 228, 228, 228, nil, 228, nil, nil, + nil, 228, 228, nil, nil, nil, 228, nil, 228, 228, + 228, 228, 228, 228, 228, nil, nil, nil, nil, 228, + 228, 228, 228, 228, 228, 228, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 228, nil, nil, 228, 228, + 228, 228, 228, 228, 228, 228, 228, 228, nil, 228, + 228, 228, 228, 228, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 228, nil, nil, 228, nil, nil, 228, + 228, nil, nil, 228, nil, nil, nil, nil, nil, 228, + nil, nil, nil, nil, nil, nil, nil, 228, nil, nil, + nil, nil, 228, 228, 228, 228, 228, 228, nil, nil, + nil, 228, 228, 229, 229, 229, nil, 229, nil, nil, + nil, 229, 229, nil, nil, nil, 229, nil, 229, 229, + 229, 229, 229, 229, 229, nil, nil, nil, nil, 229, + 229, 229, 229, 229, 229, 229, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 229, nil, nil, 229, 229, + 229, 229, 229, 229, 229, 229, 229, 229, nil, 229, + 229, 229, 229, 229, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 229, nil, nil, 229, nil, nil, 229, + 229, nil, nil, 229, nil, nil, nil, nil, nil, 229, + nil, nil, nil, nil, nil, nil, nil, 229, nil, nil, + nil, nil, 229, 229, 229, 229, 229, 229, nil, nil, + nil, 229, 229, 230, 230, 230, nil, 230, nil, nil, + nil, 230, 230, nil, nil, nil, 230, nil, 230, 230, + 230, 230, 230, 230, 230, nil, nil, nil, nil, 230, + 230, 230, 230, 230, 230, 230, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 230, nil, nil, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, nil, 230, + 230, 230, 230, 230, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, 230, nil, nil, 230, + 230, nil, nil, 230, nil, nil, nil, nil, nil, 230, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + nil, nil, 230, 230, 230, 230, 230, 230, nil, nil, + nil, 230, 230, 231, 231, 231, nil, 231, nil, nil, + nil, 231, 231, nil, nil, nil, 231, nil, 231, 231, + 231, 231, 231, 231, 231, nil, nil, nil, nil, 231, + 231, 231, 231, 231, 231, 231, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 231, nil, nil, 231, 231, + 231, 231, 231, 231, 231, 231, 231, 231, nil, 231, + 231, 231, 231, 231, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 231, nil, nil, 231, nil, nil, 231, + 231, nil, nil, 231, nil, nil, nil, nil, nil, 231, + nil, nil, nil, nil, nil, nil, nil, 231, nil, nil, + nil, nil, 231, 231, 231, 231, 231, 231, nil, nil, + nil, 231, 231, 232, 232, 232, nil, 232, nil, nil, + nil, 232, 232, nil, nil, nil, 232, nil, 232, 232, + 232, 232, 232, 232, 232, nil, nil, nil, nil, 232, + 232, 232, 232, 232, 232, 232, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 232, nil, nil, 232, 232, + 232, 232, 232, 232, 232, 232, 232, 232, nil, 232, + 232, 232, 232, 232, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 232, nil, nil, 232, nil, nil, 232, + 232, nil, nil, 232, nil, nil, nil, nil, nil, 232, + nil, nil, nil, nil, nil, nil, nil, 232, nil, nil, + nil, nil, 232, 232, 232, 232, 232, 232, nil, nil, + nil, 232, 232, 233, 233, 233, nil, 233, nil, nil, + nil, 233, 233, nil, nil, nil, 233, nil, 233, 233, + 233, 233, 233, 233, 233, nil, nil, nil, nil, 233, + 233, 233, 233, 233, 233, 233, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 233, nil, nil, 233, 233, + 233, 233, 233, 233, 233, 233, 233, 233, nil, 233, + 233, 233, 233, 233, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 233, nil, nil, 233, nil, nil, 233, + 233, nil, nil, 233, nil, nil, nil, nil, nil, 233, + nil, nil, nil, nil, nil, nil, nil, 233, nil, nil, + nil, nil, 233, 233, 233, 233, 233, 233, nil, nil, + nil, 233, 233, 234, 234, 234, nil, 234, nil, nil, + nil, 234, 234, nil, nil, nil, 234, nil, 234, 234, + 234, 234, 234, 234, 234, nil, nil, nil, nil, 234, + 234, 234, 234, 234, 234, 234, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 234, nil, nil, 234, 234, + 234, 234, 234, 234, 234, 234, 234, 234, nil, 234, + 234, 234, 234, 234, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 234, nil, nil, 234, nil, nil, 234, + 234, nil, nil, 234, nil, nil, nil, nil, nil, 234, + nil, nil, nil, nil, nil, nil, nil, 234, nil, nil, + nil, nil, 234, 234, 234, 234, 234, 234, nil, nil, + nil, 234, 234, 235, 235, 235, nil, 235, nil, nil, + nil, 235, 235, nil, nil, nil, 235, nil, 235, 235, + 235, 235, 235, 235, 235, nil, nil, nil, nil, 235, + 235, 235, 235, 235, 235, 235, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 235, nil, nil, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, nil, 235, + 235, 235, 235, 235, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 235, nil, nil, 235, nil, nil, 235, + 235, nil, nil, 235, nil, nil, nil, nil, nil, 235, + nil, nil, nil, nil, nil, nil, nil, 235, nil, nil, + nil, nil, 235, 235, 235, 235, 235, 235, nil, nil, + nil, 235, 235, 243, 243, 243, nil, 243, nil, nil, + nil, 243, 243, nil, nil, nil, 243, nil, 243, 243, + 243, 243, 243, 243, 243, nil, nil, nil, nil, 243, + 243, 243, 243, 243, 243, 243, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 243, nil, nil, 243, 243, + 243, 243, 243, 243, 243, 243, 243, 243, nil, 243, + 243, 243, 243, 243, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 243, nil, nil, 243, nil, nil, 243, + 243, nil, nil, 243, nil, nil, nil, nil, nil, 243, + nil, nil, nil, nil, nil, nil, nil, 243, nil, nil, + nil, nil, 243, 243, 243, 243, 243, 243, nil, nil, + nil, 243, 243, 245, 245, 245, nil, 245, nil, nil, + nil, 245, 245, nil, nil, nil, 245, nil, 245, 245, + 245, 245, 245, 245, 245, nil, nil, nil, nil, 245, + 245, 245, 245, 245, 245, 245, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 245, nil, nil, 245, 245, + 245, 245, 245, 245, 245, 245, 245, 245, nil, 245, + 245, 245, 245, 245, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 245, nil, nil, 245, nil, nil, 245, + 245, nil, nil, 245, nil, nil, nil, nil, nil, 245, + nil, nil, nil, nil, nil, nil, nil, 245, nil, nil, + nil, nil, 245, 245, 245, 245, 245, 245, nil, nil, + nil, 245, 245, 256, 256, 256, nil, 256, nil, nil, + nil, 256, 256, nil, nil, nil, 256, nil, 256, 256, + 256, 256, 256, 256, 256, nil, nil, nil, nil, 256, + 256, 256, 256, 256, 256, 256, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 256, nil, nil, 256, 256, + 256, 256, 256, 256, 256, 256, 256, 256, nil, 256, + 256, 256, 256, 256, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 256, nil, nil, 256, nil, nil, 256, + 256, nil, nil, 256, nil, 256, nil, 256, nil, 256, + nil, nil, nil, nil, nil, nil, nil, 256, nil, nil, + nil, nil, 256, 256, 256, 256, 256, 256, nil, nil, + nil, 256, 256, 257, 257, 257, nil, 257, nil, nil, + nil, 257, 257, nil, nil, nil, 257, nil, 257, 257, + 257, 257, 257, 257, 257, nil, nil, nil, nil, 257, + 257, 257, 257, 257, 257, 257, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 257, nil, nil, 257, 257, + 257, 257, 257, 257, 257, 257, 257, 257, nil, 257, + 257, 257, 257, 257, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 257, nil, nil, 257, nil, nil, 257, + 257, nil, nil, 257, nil, 257, nil, 257, nil, 257, + nil, nil, nil, nil, nil, nil, nil, 257, nil, nil, + nil, nil, 257, 257, 257, 257, 257, 257, nil, nil, + nil, 257, 257, 265, 265, 265, nil, 265, nil, nil, + nil, 265, 265, nil, nil, nil, 265, nil, 265, 265, + 265, 265, 265, 265, 265, nil, nil, nil, nil, 265, + 265, 265, 265, 265, 265, 265, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 265, nil, nil, 265, 265, + 265, 265, 265, 265, 265, 265, 265, 265, nil, 265, + 265, 265, 265, 265, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 265, nil, nil, 265, nil, 265, 265, + 265, nil, nil, 265, nil, 265, nil, 265, nil, 265, + nil, nil, nil, nil, nil, nil, nil, 265, nil, nil, + nil, nil, 265, 265, 265, 265, 265, 265, nil, nil, + nil, 265, 265, 271, 271, 271, nil, 271, nil, nil, + nil, 271, 271, nil, nil, nil, 271, nil, 271, 271, + 271, 271, 271, 271, 271, nil, nil, nil, nil, 271, + 271, 271, 271, 271, 271, 271, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 271, nil, nil, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, nil, 271, + 271, nil, nil, 271, nil, 470, 470, 470, 470, 470, + 470, 470, 470, 470, 470, 470, nil, 470, 470, nil, + nil, 470, 470, 271, nil, nil, 271, nil, nil, 271, + 271, nil, nil, 271, nil, nil, nil, 470, nil, 470, + nil, 470, 470, 470, 470, 470, 470, 470, nil, 470, + nil, nil, 271, 271, 271, 271, 271, 271, nil, nil, + nil, 271, 271, 292, 292, 292, 470, 292, nil, nil, + nil, 292, 292, nil, nil, nil, 292, nil, 292, 292, + 292, 292, 292, 292, 292, nil, nil, nil, nil, 292, + 292, 292, 292, 292, 292, 292, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 292, nil, nil, 292, 292, + 292, 292, 292, 292, 292, 292, 292, 292, nil, 292, + 292, 292, 292, 292, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 292, nil, nil, 292, 292, nil, 292, + 292, nil, nil, 292, nil, nil, nil, nil, nil, 292, + nil, nil, nil, nil, nil, nil, nil, 292, nil, nil, + nil, nil, 292, 292, 292, 292, 292, 292, nil, nil, + nil, 292, 292, 301, 301, 301, nil, 301, nil, nil, + nil, 301, 301, nil, nil, nil, 301, nil, 301, 301, + 301, 301, 301, 301, 301, nil, nil, nil, nil, 301, + 301, 301, 301, 301, 301, 301, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 301, nil, nil, 301, 301, + 301, 301, 301, 301, 301, 301, 301, 301, nil, 301, + 301, 301, 301, 301, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 301, nil, nil, 301, nil, nil, 301, + 301, nil, nil, 301, nil, nil, nil, nil, nil, 301, + nil, nil, nil, nil, nil, nil, nil, 301, nil, nil, + nil, nil, 301, 301, 301, 301, 301, 301, nil, nil, + nil, 301, 301, 310, 310, 310, nil, 310, nil, nil, + nil, 310, 310, nil, nil, nil, 310, nil, 310, 310, + 310, 310, 310, 310, 310, nil, nil, nil, nil, 310, + 310, 310, 310, 310, 310, 310, nil, nil, 310, nil, + nil, nil, nil, nil, nil, 310, nil, nil, 310, 310, + 310, 310, 310, 310, 310, 310, 310, 310, nil, 310, + 310, 310, 310, 310, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 310, nil, nil, 310, nil, nil, 310, + 310, nil, nil, 310, nil, nil, nil, nil, nil, 310, + nil, nil, nil, nil, nil, nil, nil, 310, nil, nil, + nil, nil, 310, 310, 310, 310, 310, 310, nil, nil, + nil, 310, 310, 311, 311, 311, nil, 311, nil, nil, + nil, 311, 311, nil, nil, nil, 311, nil, 311, 311, + 311, 311, 311, 311, 311, nil, nil, nil, nil, 311, + 311, 311, 311, 311, 311, 311, nil, nil, 311, nil, + nil, nil, nil, nil, nil, 311, nil, nil, 311, 311, + 311, 311, 311, 311, 311, 311, 311, 311, nil, 311, + 311, 311, 311, 311, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 311, nil, nil, 311, nil, nil, 311, + 311, nil, nil, 311, nil, nil, nil, nil, nil, 311, + nil, nil, nil, nil, nil, nil, nil, 311, nil, nil, + nil, nil, 311, 311, 311, 311, 311, 311, nil, nil, + nil, 311, 311, 329, 329, 329, nil, 329, nil, nil, + nil, 329, 329, nil, nil, nil, 329, nil, 329, 329, + 329, 329, 329, 329, 329, nil, nil, nil, nil, 329, + 329, 329, 329, 329, 329, 329, nil, nil, 329, nil, + nil, nil, nil, nil, nil, 329, nil, nil, 329, 329, + 329, 329, 329, 329, 329, 329, 329, 329, nil, 329, + 329, 329, 329, 329, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 329, nil, nil, 329, nil, nil, 329, + 329, nil, nil, 329, nil, nil, nil, nil, nil, 329, + nil, nil, nil, nil, nil, nil, nil, 329, nil, nil, + nil, nil, 329, 329, 329, 329, 329, 329, nil, nil, + nil, 329, 329, 343, 343, 343, nil, 343, nil, nil, + nil, 343, 343, nil, nil, nil, 343, nil, 343, 343, + 343, 343, 343, 343, 343, nil, nil, nil, nil, 343, + 343, 343, 343, 343, 343, 343, nil, nil, 343, nil, + nil, nil, nil, nil, nil, 343, nil, nil, 343, 343, + 343, 343, 343, 343, 343, 343, 343, 343, nil, 343, + 343, 343, 343, 343, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 343, nil, nil, 343, nil, nil, 343, + 343, nil, nil, 343, nil, nil, nil, nil, nil, 343, + nil, nil, nil, nil, nil, nil, nil, 343, nil, nil, + nil, nil, 343, 343, 343, 343, 343, 343, nil, nil, + nil, 343, 343, 359, 359, 359, 359, 359, 359, 359, + 359, 359, 359, 359, 359, 359, 359, 359, 359, 359, + 359, 359, 359, 359, 359, 359, 359, nil, nil, 359, + 359, 359, 359, 359, 359, 359, 359, 359, 359, nil, + nil, nil, nil, nil, 359, 359, 359, 359, 359, 359, + 359, 359, nil, nil, 359, nil, nil, nil, nil, nil, + nil, 359, 359, nil, 359, 359, 359, 359, nil, 359, + 359, nil, nil, 359, nil, nil, nil, nil, 359, 359, + 359, 359, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 359, 359, nil, 359, 359, + 359, 359, 359, 359, 359, 359, 359, nil, 359, nil, + nil, 359, 359, nil, nil, 371, 371, 371, nil, 371, + nil, nil, 359, 371, 371, nil, nil, nil, 371, nil, + 371, 371, 371, 371, 371, 371, 371, nil, nil, nil, + nil, 371, 371, 371, 371, 371, 371, 371, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 371, nil, nil, + 371, 371, 371, 371, 371, 371, 371, 371, 371, 371, + nil, 371, 371, 371, 371, 371, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 371, nil, nil, 371, nil, + nil, 371, 371, nil, nil, 371, nil, nil, nil, nil, + nil, 371, nil, nil, nil, nil, nil, nil, nil, 371, + nil, nil, nil, nil, 371, 371, 371, 371, 371, 371, + nil, nil, nil, 371, 371, 380, 380, 380, nil, 380, + nil, nil, nil, 380, 380, nil, nil, nil, 380, nil, + 380, 380, 380, 380, 380, 380, 380, nil, nil, nil, + nil, 380, 380, 380, 380, 380, 380, 380, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 380, nil, nil, + 380, 380, 380, 380, 380, 380, 380, 380, 380, 380, + nil, 380, 380, 380, 380, 380, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 380, nil, nil, 380, 380, + nil, 380, 380, nil, nil, 380, nil, 380, nil, 380, + nil, 380, nil, nil, nil, nil, nil, nil, nil, 380, + nil, nil, nil, nil, 380, 380, 380, 380, 380, 380, + nil, nil, nil, 380, 380, 387, 387, 387, nil, 387, + nil, nil, nil, 387, 387, nil, nil, nil, 387, nil, + 387, 387, 387, 387, 387, 387, 387, nil, nil, nil, + nil, 387, 387, 387, 387, 387, 387, 387, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 387, nil, nil, + 387, 387, 387, 387, 387, 387, 387, 387, 387, 387, + nil, 387, 387, 387, 387, 387, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 387, nil, nil, 387, 387, + nil, 387, 387, nil, nil, 387, nil, 387, nil, 387, + nil, 387, nil, nil, nil, nil, nil, nil, nil, 387, + nil, nil, nil, nil, 387, 387, 387, 387, 387, 387, + nil, nil, nil, 387, 387, 388, 388, 388, nil, 388, + nil, nil, nil, 388, 388, nil, nil, nil, 388, nil, + 388, 388, 388, 388, 388, 388, 388, nil, nil, nil, + nil, 388, 388, 388, 388, 388, 388, 388, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 388, nil, nil, + 388, 388, 388, 388, 388, 388, 388, 388, 388, 388, + nil, 388, 388, 388, 388, 388, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 388, nil, nil, 388, 388, + nil, 388, 388, nil, nil, 388, nil, 388, nil, 388, + nil, 388, nil, nil, nil, nil, nil, nil, nil, 388, + nil, nil, nil, nil, 388, 388, 388, 388, 388, 388, + nil, nil, nil, 388, 388, 395, 395, 395, nil, 395, + nil, nil, nil, 395, 395, nil, nil, nil, 395, nil, + 395, 395, 395, 395, 395, 395, 395, nil, nil, nil, + nil, 395, 395, 395, 395, 395, 395, 395, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 395, nil, nil, + 395, 395, 395, 395, 395, 395, 395, 395, 395, 395, + nil, 395, 395, 395, 395, 395, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 395, nil, nil, 395, nil, + nil, 395, 395, nil, nil, 395, nil, 395, nil, nil, + nil, 395, nil, nil, nil, nil, nil, nil, nil, 395, + nil, nil, nil, nil, 395, 395, 395, 395, 395, 395, + nil, nil, nil, 395, 395, 397, 397, 397, nil, 397, + nil, nil, nil, 397, 397, nil, nil, nil, 397, nil, + 397, 397, 397, 397, 397, 397, 397, nil, nil, nil, + nil, 397, 397, 397, 397, 397, 397, 397, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 397, nil, nil, + 397, 397, 397, 397, 397, 397, 397, 397, 397, 397, + nil, 397, 397, 397, 397, 397, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 397, nil, nil, 397, nil, + nil, 397, 397, nil, nil, 397, nil, nil, nil, nil, + nil, 397, nil, nil, nil, nil, nil, nil, nil, 397, + nil, nil, nil, nil, 397, 397, 397, 397, 397, 397, + nil, nil, nil, 397, 397, 398, 398, 398, nil, 398, + nil, nil, nil, 398, 398, nil, nil, nil, 398, nil, + 398, 398, 398, 398, 398, 398, 398, nil, nil, nil, + nil, 398, 398, 398, 398, 398, 398, 398, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 398, nil, nil, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + nil, 398, 398, 398, 398, 398, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 398, nil, nil, 398, nil, + nil, 398, 398, nil, nil, 398, nil, nil, nil, nil, + nil, 398, nil, nil, nil, nil, nil, nil, nil, 398, + nil, nil, nil, nil, 398, 398, 398, 398, 398, 398, + nil, nil, nil, 398, 398, 399, 399, 399, nil, 399, + nil, nil, nil, 399, 399, nil, nil, nil, 399, nil, + 399, 399, 399, 399, 399, 399, 399, nil, nil, nil, + nil, 399, 399, 399, 399, 399, 399, 399, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 399, nil, nil, + 399, 399, 399, 399, 399, 399, 399, 399, 399, 399, + nil, 399, 399, 399, 399, 399, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 399, nil, nil, 399, nil, + nil, 399, 399, nil, nil, 399, nil, nil, nil, nil, + nil, 399, nil, nil, nil, nil, nil, nil, nil, 399, + nil, nil, nil, nil, 399, 399, 399, 399, 399, 399, + nil, nil, nil, 399, 399, 428, 428, 428, nil, 428, + nil, nil, nil, 428, 428, nil, nil, nil, 428, nil, + 428, 428, 428, 428, 428, 428, 428, nil, nil, nil, + nil, 428, 428, 428, 428, 428, 428, 428, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 428, nil, nil, + 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, + nil, 428, 428, 428, 428, 428, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 428, nil, nil, 428, nil, + nil, 428, 428, nil, nil, 428, nil, 428, nil, 428, + nil, 428, nil, nil, nil, nil, nil, nil, nil, 428, + nil, nil, nil, nil, 428, 428, 428, 428, 428, 428, + nil, nil, nil, 428, 428, 430, 430, 430, nil, 430, + nil, nil, nil, 430, 430, nil, nil, nil, 430, nil, + 430, 430, 430, 430, 430, 430, 430, nil, nil, nil, + nil, 430, 430, 430, 430, 430, 430, 430, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 430, nil, nil, + 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, + nil, 430, 430, 430, 430, 430, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 430, nil, nil, 430, nil, + nil, 430, 430, nil, nil, 430, nil, 430, nil, 430, + nil, 430, nil, nil, nil, nil, nil, nil, nil, 430, + nil, nil, nil, nil, 430, 430, 430, 430, 430, 430, + nil, nil, nil, 430, 430, 433, 433, 433, nil, 433, + nil, nil, nil, 433, 433, nil, nil, nil, 433, nil, + 433, 433, 433, 433, 433, 433, 433, nil, nil, nil, + nil, 433, 433, 433, 433, 433, 433, 433, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 433, nil, nil, + 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, + nil, 433, 433, 433, 433, 433, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 433, nil, nil, 433, nil, + nil, 433, 433, nil, nil, 433, nil, nil, nil, nil, + nil, 433, nil, nil, nil, nil, nil, nil, nil, 433, + nil, nil, nil, nil, 433, 433, 433, 433, 433, 433, + nil, nil, nil, 433, 433, 447, 447, 447, nil, 447, + nil, nil, nil, 447, 447, nil, nil, nil, 447, nil, + 447, 447, 447, 447, 447, 447, 447, nil, nil, nil, + nil, 447, 447, 447, 447, 447, 447, 447, nil, nil, + 447, nil, nil, nil, nil, nil, nil, 447, nil, nil, + 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, + nil, 447, 447, 447, 447, 447, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 447, nil, nil, 447, nil, + nil, 447, 447, nil, nil, 447, nil, 447, nil, 447, + nil, 447, nil, nil, nil, nil, nil, nil, nil, 447, + nil, nil, nil, nil, 447, 447, 447, 447, 447, 447, + nil, nil, nil, 447, 447, 458, 458, 458, nil, 458, + nil, nil, nil, 458, 458, nil, nil, nil, 458, nil, + 458, 458, 458, 458, 458, 458, 458, nil, nil, nil, + nil, 458, 458, 458, 458, 458, 458, 458, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 458, nil, nil, + 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, + nil, 458, 458, 458, 458, 458, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 458, nil, nil, 458, nil, + nil, 458, 458, nil, nil, 458, nil, 458, nil, nil, + nil, 458, nil, nil, nil, nil, nil, nil, nil, 458, + nil, nil, nil, nil, 458, 458, 458, 458, 458, 458, + nil, nil, nil, 458, 458, 465, 465, 465, nil, 465, + nil, nil, nil, 465, 465, nil, nil, nil, 465, nil, + 465, 465, 465, 465, 465, 465, 465, nil, nil, nil, + nil, 465, 465, 465, 465, 465, 465, 465, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 465, nil, nil, + 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, + nil, 465, 465, 465, 465, 465, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 465, nil, nil, 465, nil, + nil, 465, 465, nil, nil, 465, nil, nil, nil, nil, + nil, 465, nil, nil, nil, nil, nil, nil, nil, 465, + nil, nil, nil, nil, 465, 465, 465, 465, 465, 465, + nil, nil, nil, 465, 465, 466, 466, 466, nil, 466, + nil, nil, nil, 466, 466, nil, nil, nil, 466, nil, + 466, 466, 466, 466, 466, 466, 466, nil, nil, nil, + nil, 466, 466, 466, 466, 466, 466, 466, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 466, nil, nil, + 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, + nil, 466, 466, 466, 466, 466, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 466, nil, nil, 466, nil, + nil, 466, 466, nil, nil, 466, nil, nil, nil, nil, + nil, 466, nil, nil, nil, nil, nil, nil, nil, 466, + nil, nil, nil, nil, 466, 466, 466, 466, 466, 466, + nil, nil, nil, 466, 466, 467, 467, 467, nil, 467, + nil, nil, nil, 467, 467, nil, nil, nil, 467, nil, + 467, 467, 467, 467, 467, 467, 467, nil, nil, nil, + nil, 467, 467, 467, 467, 467, 467, 467, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 467, nil, nil, + 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, + nil, 467, 467, 467, 467, 467, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 467, nil, nil, 467, nil, + nil, 467, 467, nil, nil, 467, nil, nil, nil, nil, + nil, 467, nil, nil, nil, nil, nil, nil, nil, 467, + nil, nil, nil, nil, 467, 467, 467, 467, 467, 467, + nil, nil, nil, 467, 467, 471, 471, 471, nil, 471, + nil, nil, nil, 471, 471, nil, nil, nil, 471, nil, + 471, 471, 471, 471, 471, 471, 471, nil, nil, nil, + nil, 471, 471, 471, 471, 471, 471, 471, nil, nil, + 471, nil, nil, nil, nil, nil, nil, 471, nil, nil, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + nil, 471, 471, 471, 471, 471, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 471, nil, nil, 471, nil, + nil, 471, 471, nil, nil, 471, nil, nil, nil, nil, + nil, 471, nil, nil, nil, nil, nil, nil, nil, 471, + nil, nil, nil, nil, 471, 471, 471, 471, 471, 471, + nil, nil, nil, 471, 471, 473, 473, 473, nil, 473, + nil, nil, nil, 473, 473, nil, nil, nil, 473, nil, + 473, 473, 473, 473, 473, 473, 473, nil, nil, nil, + nil, 473, 473, 473, 473, 473, 473, 473, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 473, nil, nil, + 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, + nil, 473, 473, 473, 473, 473, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 473, nil, nil, 473, nil, + nil, 473, 473, nil, nil, 473, nil, 473, nil, nil, + nil, 473, nil, nil, nil, nil, nil, nil, nil, 473, + nil, nil, nil, nil, 473, 473, 473, 473, 473, 473, + nil, nil, nil, 473, 473, 478, 478, 478, nil, 478, + nil, nil, nil, 478, 478, nil, nil, nil, 478, nil, + 478, 478, 478, 478, 478, 478, 478, nil, nil, nil, + nil, 478, 478, 478, 478, 478, 478, 478, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 478, nil, nil, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + nil, 478, 478, 478, 478, 478, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 478, nil, nil, 478, nil, + nil, 478, 478, nil, nil, 478, nil, 478, nil, nil, + nil, 478, nil, nil, nil, nil, nil, nil, nil, 478, + nil, nil, nil, nil, 478, 478, 478, 478, 478, 478, + nil, nil, nil, 478, 478, 481, 481, 481, nil, 481, + nil, nil, nil, 481, 481, nil, nil, nil, 481, nil, + 481, 481, 481, 481, 481, 481, 481, nil, nil, nil, + nil, 481, 481, 481, 481, 481, 481, 481, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 481, nil, nil, + 481, 481, 481, 481, 481, 481, 481, 481, 481, 481, + nil, 481, 481, 481, 481, 481, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 481, nil, nil, 481, nil, + nil, 481, 481, nil, nil, 481, nil, nil, nil, nil, + nil, 481, nil, nil, nil, nil, nil, nil, nil, 481, + nil, nil, nil, nil, 481, 481, 481, 481, 481, 481, + nil, nil, nil, 481, 481, 484, 484, 484, nil, 484, + nil, nil, nil, 484, 484, nil, nil, nil, 484, nil, + 484, 484, 484, 484, 484, 484, 484, nil, nil, nil, + nil, 484, 484, 484, 484, 484, 484, 484, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 484, nil, nil, + 484, 484, 484, 484, 484, 484, 484, 484, 484, 484, + nil, 484, 484, 484, 484, 484, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 484, nil, nil, 484, nil, + nil, 484, 484, nil, nil, 484, nil, nil, nil, nil, + nil, 484, nil, nil, nil, nil, nil, nil, nil, 484, + nil, nil, nil, nil, 484, 484, 484, 484, 484, 484, + nil, nil, nil, 484, 484, 498, 498, 498, nil, 498, + nil, nil, nil, 498, 498, nil, nil, nil, 498, nil, + 498, 498, 498, 498, 498, 498, 498, nil, nil, nil, + nil, 498, 498, 498, 498, 498, 498, 498, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 498, nil, nil, + 498, 498, 498, 498, 498, 498, 498, 498, 498, 498, + nil, 498, 498, 498, 498, 498, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 498, nil, nil, 498, nil, + nil, 498, 498, nil, nil, 498, nil, 498, nil, nil, + nil, 498, nil, nil, nil, nil, nil, nil, nil, 498, + nil, nil, nil, nil, 498, 498, 498, 498, 498, 498, + nil, nil, nil, 498, 498, 499, 499, 499, nil, 499, + nil, nil, nil, 499, 499, nil, nil, nil, 499, nil, + 499, 499, 499, 499, 499, 499, 499, nil, nil, nil, + nil, 499, 499, 499, 499, 499, 499, 499, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 499, nil, nil, + 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, + nil, 499, 499, 499, 499, 499, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 499, nil, nil, 499, nil, + nil, 499, 499, nil, nil, 499, nil, 499, nil, nil, + nil, 499, nil, nil, nil, nil, nil, nil, nil, 499, + nil, nil, nil, nil, 499, 499, 499, 499, 499, 499, + nil, nil, nil, 499, 499, 508, 508, 508, nil, 508, + nil, nil, nil, 508, 508, nil, nil, nil, 508, nil, + 508, 508, 508, 508, 508, 508, 508, nil, nil, nil, + nil, 508, 508, 508, 508, 508, 508, 508, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 508, nil, nil, + 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, + nil, 508, 508, 508, 508, 508, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 508, nil, nil, 508, nil, + nil, 508, 508, nil, nil, 508, nil, 508, nil, nil, + nil, 508, nil, nil, nil, nil, nil, nil, nil, 508, + nil, nil, nil, nil, 508, 508, 508, 508, 508, 508, + nil, nil, nil, 508, 508, 512, 512, 512, nil, 512, + nil, nil, nil, 512, 512, nil, nil, nil, 512, nil, + 512, 512, 512, 512, 512, 512, 512, nil, nil, nil, + nil, 512, 512, 512, 512, 512, 512, 512, nil, nil, + 512, nil, nil, nil, nil, nil, nil, 512, nil, nil, + 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, + nil, 512, 512, 512, 512, 512, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 512, nil, nil, 512, nil, + nil, 512, 512, nil, nil, 512, nil, nil, nil, nil, + nil, 512, nil, nil, nil, nil, nil, nil, nil, 512, + nil, nil, nil, nil, 512, 512, 512, 512, 512, 512, + nil, nil, nil, 512, 512, 536, 536, 536, 536, 536, + 536, 536, 536, 536, 536, 536, 536, 536, 536, 536, + 536, 536, 536, 536, 536, 536, 536, 536, 536, nil, + nil, 536, 536, 536, 536, 536, 536, 536, 536, 536, + 536, nil, nil, nil, nil, nil, 536, 536, 536, 536, + 536, 536, 536, 536, nil, nil, 536, nil, nil, nil, + nil, nil, nil, 536, 536, nil, 536, 536, 536, 536, + nil, 536, 536, nil, nil, 536, nil, nil, nil, nil, + 536, 536, 536, 536, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 536, 536, nil, + 536, 536, 536, 536, 536, 536, 536, 536, 536, nil, + 536, nil, nil, 536, 536, nil, nil, 539, 539, 539, + nil, 539, nil, nil, 536, 539, 539, nil, nil, nil, + 539, nil, 539, 539, 539, 539, 539, 539, 539, nil, + nil, nil, nil, 539, 539, 539, 539, 539, 539, 539, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 539, + nil, nil, 539, 539, 539, 539, 539, 539, 539, 539, + 539, 539, nil, 539, 539, 539, 539, 539, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 539, nil, nil, + 539, nil, nil, 539, 539, nil, nil, 539, nil, nil, + nil, nil, nil, 539, nil, nil, nil, nil, nil, nil, + nil, 539, nil, nil, nil, nil, 539, 539, 539, 539, + 539, 539, nil, nil, nil, 539, 539, 540, 540, 540, + nil, 540, nil, nil, nil, 540, 540, nil, nil, nil, + 540, nil, 540, 540, 540, 540, 540, 540, 540, nil, + nil, nil, nil, 540, 540, 540, 540, 540, 540, 540, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 540, + nil, nil, 540, 540, 540, 540, 540, 540, 540, 540, + 540, 540, nil, 540, 540, 540, 540, 540, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 540, nil, nil, + 540, nil, nil, 540, 540, nil, nil, 540, nil, 540, + nil, nil, nil, 540, nil, nil, nil, nil, nil, nil, + nil, 540, nil, nil, nil, nil, 540, 540, 540, 540, + 540, 540, nil, nil, nil, 540, 540, 543, 543, 543, + nil, 543, nil, nil, nil, 543, 543, nil, nil, nil, + 543, nil, 543, 543, 543, 543, 543, 543, 543, nil, + nil, nil, nil, 543, 543, 543, 543, 543, 543, 543, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 543, + nil, nil, 543, 543, 543, 543, 543, 543, 543, 543, + 543, 543, nil, 543, 543, 543, 543, 543, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 543, nil, nil, + 543, nil, nil, 543, 543, nil, nil, 543, nil, nil, + nil, nil, nil, 543, nil, nil, nil, nil, nil, nil, + nil, 543, nil, nil, nil, nil, 543, 543, 543, 543, + 543, 543, nil, nil, nil, 543, 543, 544, 544, 544, + nil, 544, nil, nil, nil, 544, 544, nil, nil, nil, + 544, nil, 544, 544, 544, 544, 544, 544, 544, nil, + nil, nil, nil, 544, 544, 544, 544, 544, 544, 544, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 544, + nil, nil, 544, 544, 544, 544, 544, 544, 544, 544, + 544, 544, nil, 544, 544, 544, 544, 544, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 544, nil, nil, + 544, nil, nil, 544, 544, nil, nil, 544, nil, nil, + nil, nil, nil, 544, nil, nil, nil, nil, nil, nil, + nil, 544, nil, nil, nil, nil, 544, 544, 544, 544, + 544, 544, nil, nil, nil, 544, 544, 548, 548, 548, + nil, 548, nil, nil, nil, 548, 548, nil, nil, nil, + 548, nil, 548, 548, 548, 548, 548, 548, 548, nil, + nil, nil, nil, 548, 548, 548, 548, 548, 548, 548, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 548, + nil, nil, 548, 548, 548, 548, 548, 548, 548, 548, + 548, 548, nil, 548, 548, 548, 548, 548, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 548, nil, nil, + 548, nil, nil, 548, 548, nil, nil, 548, nil, nil, + nil, nil, nil, 548, nil, nil, nil, nil, nil, nil, + nil, 548, nil, nil, nil, nil, 548, 548, 548, 548, + 548, 548, nil, nil, nil, 548, 548, 551, 551, 551, + nil, 551, nil, nil, nil, 551, 551, nil, nil, nil, + 551, nil, 551, 551, 551, 551, 551, 551, 551, nil, + nil, nil, nil, 551, 551, 551, 551, 551, 551, 551, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 551, + nil, nil, 551, 551, 551, 551, 551, 551, 551, 551, + 551, 551, nil, 551, 551, 551, 551, 551, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 551, nil, nil, + 551, nil, nil, 551, 551, nil, nil, 551, nil, nil, + nil, nil, nil, 551, nil, nil, nil, nil, nil, nil, + nil, 551, nil, nil, nil, nil, 551, 551, 551, 551, + 551, 551, nil, nil, nil, 551, 551, 558, 558, 558, + nil, 558, nil, nil, nil, 558, 558, nil, nil, nil, + 558, nil, 558, 558, 558, 558, 558, 558, 558, nil, + nil, nil, nil, 558, 558, 558, 558, 558, 558, 558, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 558, + nil, nil, 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, nil, 558, 558, 558, 558, 558, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 558, nil, nil, + 558, nil, nil, 558, 558, nil, nil, 558, nil, nil, + nil, nil, nil, 558, nil, nil, nil, nil, nil, nil, + nil, 558, nil, nil, nil, nil, 558, 558, 558, 558, + 558, 558, nil, nil, nil, 558, 558, 559, 559, 559, + nil, 559, nil, nil, nil, 559, 559, nil, nil, nil, + 559, nil, 559, 559, 559, 559, 559, 559, 559, nil, + nil, nil, nil, 559, 559, 559, 559, 559, 559, 559, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 559, + nil, nil, 559, 559, 559, 559, 559, 559, 559, 559, + 559, 559, nil, 559, 559, nil, nil, 559, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 559, nil, nil, + 559, nil, nil, 559, 559, nil, nil, 559, nil, 559, + nil, 559, nil, nil, nil, nil, nil, nil, nil, nil, + 559, nil, nil, nil, nil, nil, 559, 559, 559, 559, + 559, 559, nil, nil, nil, 559, 559, 562, 562, 562, + nil, 562, nil, nil, nil, 562, 562, nil, nil, nil, + 562, nil, 562, 562, 562, 562, 562, 562, 562, nil, + nil, nil, nil, 562, 562, 562, 562, 562, 562, 562, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 562, + nil, nil, 562, 562, 562, 562, 562, 562, 562, 562, + 562, 562, nil, 562, 562, 562, 562, 562, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 562, nil, nil, + 562, nil, nil, 562, 562, nil, nil, 562, nil, nil, + nil, nil, nil, 562, nil, nil, nil, nil, nil, nil, + nil, 562, nil, nil, nil, nil, 562, 562, 562, 562, + 562, 562, nil, nil, nil, 562, 562, 566, 566, 566, + nil, 566, nil, nil, nil, 566, 566, nil, nil, nil, + 566, nil, 566, 566, 566, 566, 566, 566, 566, nil, + nil, nil, nil, 566, 566, 566, 566, 566, 566, 566, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 566, + nil, nil, 566, 566, 566, 566, 566, 566, 566, 566, + 566, 566, nil, 566, 566, 566, 566, 566, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 566, nil, nil, + 566, nil, nil, 566, 566, nil, nil, 566, nil, nil, + nil, nil, nil, 566, nil, nil, nil, nil, nil, nil, + nil, 566, nil, nil, nil, nil, 566, 566, 566, 566, + 566, 566, nil, nil, nil, 566, 566, 582, 582, 582, + nil, 582, nil, nil, nil, 582, 582, nil, nil, nil, + 582, nil, 582, 582, 582, 582, 582, 582, 582, nil, + nil, nil, nil, 582, 582, 582, 582, 582, 582, 582, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 582, + nil, nil, 582, 582, 582, 582, 582, 582, 582, 582, + 582, 582, nil, 582, 582, 582, 582, 582, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 582, nil, nil, + 582, nil, nil, 582, 582, nil, nil, 582, nil, 582, + nil, 582, nil, 582, nil, nil, nil, nil, nil, nil, + nil, 582, nil, nil, nil, nil, 582, 582, 582, 582, + 582, 582, nil, nil, nil, 582, 582, 586, 586, 586, + nil, 586, nil, nil, nil, 586, 586, nil, nil, nil, + 586, nil, 586, 586, 586, 586, 586, 586, 586, nil, + nil, nil, nil, 586, 586, 586, 586, 586, 586, 586, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 586, + nil, nil, 586, 586, 586, 586, 586, 586, 586, 586, + 586, 586, nil, 586, 586, 586, 586, 586, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 586, nil, nil, + 586, nil, nil, 586, 586, nil, nil, 586, nil, nil, + nil, nil, nil, 586, nil, nil, nil, nil, nil, nil, + nil, 586, nil, nil, nil, nil, 586, 586, 586, 586, + 586, 586, nil, nil, nil, 586, 586, 614, 614, 614, + nil, 614, nil, nil, nil, 614, 614, nil, nil, nil, + 614, nil, 614, 614, 614, 614, 614, 614, 614, nil, + nil, nil, nil, 614, 614, 614, 614, 614, 614, 614, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 614, + nil, nil, 614, 614, 614, 614, 614, 614, 614, 614, + 614, 614, nil, 614, 614, 614, 614, 614, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 614, nil, nil, + 614, nil, nil, 614, 614, nil, nil, 614, nil, nil, + nil, nil, nil, 614, nil, nil, nil, nil, nil, nil, + nil, 614, nil, nil, nil, nil, 614, 614, 614, 614, + 614, 614, nil, nil, nil, 614, 614, 630, 630, 630, + nil, 630, nil, nil, nil, 630, 630, nil, nil, nil, + 630, nil, 630, 630, 630, 630, 630, 630, 630, nil, + nil, nil, nil, 630, 630, 630, 630, 630, 630, 630, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 630, + nil, nil, 630, 630, 630, 630, 630, 630, 630, 630, + 630, 630, nil, 630, 630, 630, 630, 630, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 630, nil, nil, + 630, nil, nil, 630, 630, nil, nil, 630, nil, nil, + nil, nil, nil, 630, nil, nil, nil, nil, nil, nil, + nil, 630, nil, nil, nil, nil, 630, 630, 630, 630, + 630, 630, nil, nil, nil, 630, 630, 636, 636, 636, + nil, 636, nil, nil, nil, 636, 636, nil, nil, nil, + 636, nil, 636, 636, 636, 636, 636, 636, 636, nil, + nil, nil, nil, 636, 636, 636, 636, 636, 636, 636, + nil, nil, 636, nil, nil, nil, nil, nil, nil, 636, + nil, nil, 636, 636, 636, 636, 636, 636, 636, 636, + 636, 636, nil, 636, 636, 636, 636, 636, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 636, nil, nil, + 636, nil, nil, 636, 636, nil, nil, 636, nil, nil, + nil, nil, nil, 636, nil, nil, nil, nil, nil, nil, + nil, 636, nil, nil, nil, nil, 636, 636, 636, 636, + 636, 636, nil, nil, nil, 636, 636, 681, 681, 681, + nil, 681, nil, nil, nil, 681, 681, nil, nil, nil, + 681, nil, 681, 681, 681, 681, 681, 681, 681, nil, + nil, nil, nil, 681, 681, 681, 681, 681, 681, 681, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 681, + nil, nil, 681, 681, 681, 681, 681, 681, 681, 681, + 681, 681, nil, 681, 681, 681, 681, 681, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 681, nil, nil, + 681, nil, nil, 681, 681, nil, nil, 681, nil, nil, + nil, nil, nil, 681, nil, nil, nil, nil, nil, nil, + nil, 681, nil, nil, nil, nil, 681, 681, 681, 681, + 681, 681, nil, nil, nil, 681, 681, 682, 682, 682, + nil, 682, nil, nil, nil, 682, 682, nil, nil, nil, + 682, nil, 682, 682, 682, 682, 682, 682, 682, nil, + nil, nil, nil, 682, 682, 682, 682, 682, 682, 682, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 682, + nil, nil, 682, 682, 682, 682, 682, 682, 682, 682, + 682, 682, nil, 682, 682, 682, 682, 682, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 682, nil, nil, + 682, nil, nil, 682, 682, nil, nil, 682, nil, nil, + nil, nil, nil, 682, nil, nil, nil, nil, nil, nil, + nil, 682, nil, nil, nil, nil, 682, 682, 682, 682, + 682, 682, nil, nil, nil, 682, 682, 692, 692, 692, + nil, 692, nil, nil, nil, 692, 692, nil, nil, nil, + 692, nil, 692, 692, 692, 692, 692, 692, 692, nil, + nil, nil, nil, 692, 692, 692, 692, 692, 692, 692, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 692, + nil, nil, 692, 692, 692, 692, 692, 692, 692, 692, + 692, 692, nil, 692, 692, 692, 692, 692, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 692, nil, nil, + 692, nil, nil, 692, 692, nil, nil, 692, nil, nil, + nil, nil, nil, 692, nil, nil, nil, nil, nil, nil, + nil, 692, nil, nil, nil, nil, 692, 692, 692, 692, + 692, 692, nil, nil, nil, 692, 692, 693, 693, 693, + nil, 693, nil, nil, nil, 693, 693, nil, nil, nil, + 693, nil, 693, 693, 693, 693, 693, 693, 693, nil, + nil, nil, nil, 693, 693, 693, 693, 693, 693, 693, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 693, + nil, nil, 693, 693, 693, 693, 693, 693, 693, 693, + 693, 693, nil, 693, 693, 693, 693, 693, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 693, nil, nil, + 693, nil, nil, 693, 693, nil, nil, 693, nil, nil, + nil, nil, nil, 693, nil, nil, nil, nil, nil, nil, + nil, 693, nil, nil, nil, nil, 693, 693, 693, 693, + 693, 693, nil, nil, nil, 693, 693, 694, 694, 694, + nil, 694, nil, nil, nil, 694, 694, nil, nil, nil, + 694, nil, 694, 694, 694, 694, 694, 694, 694, nil, + nil, nil, nil, 694, 694, 694, 694, 694, 694, 694, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 694, + nil, nil, 694, 694, 694, 694, 694, 694, 694, 694, + 694, 694, nil, 694, 694, 694, 694, 694, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 694, nil, nil, + 694, nil, nil, 694, 694, nil, nil, 694, nil, nil, + nil, nil, nil, 694, nil, nil, nil, nil, nil, nil, + nil, 694, nil, nil, nil, nil, 694, 694, 694, 694, + 694, 694, nil, nil, nil, 694, 694, 700, 700, 700, + nil, 700, nil, nil, nil, 700, 700, nil, nil, nil, + 700, nil, 700, 700, 700, 700, 700, 700, 700, nil, + nil, nil, nil, 700, 700, 700, 700, 700, 700, 700, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 700, + nil, nil, 700, 700, 700, 700, 700, 700, 700, 700, + 700, 700, nil, 700, 700, nil, nil, 700, nil, 602, + 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, + nil, 602, 602, nil, nil, 602, 602, 700, nil, nil, + 700, nil, nil, 700, 700, nil, nil, 700, nil, nil, + nil, 602, nil, 602, nil, 602, 602, 602, 602, 602, + 602, 602, nil, 602, nil, nil, 700, 700, 700, 700, + 700, 700, nil, nil, nil, 700, 700, 706, 706, 706, + 602, 706, nil, nil, nil, 706, 706, nil, nil, nil, + 706, nil, 706, 706, 706, 706, 706, 706, 706, nil, + nil, nil, nil, 706, 706, 706, 706, 706, 706, 706, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 706, + nil, nil, 706, 706, 706, 706, 706, 706, 706, 706, + 706, 706, nil, 706, 706, 706, 706, 706, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 706, nil, nil, + 706, nil, nil, 706, 706, nil, nil, 706, nil, 706, + nil, 706, nil, 706, nil, nil, nil, nil, nil, nil, + nil, 706, nil, nil, nil, nil, 706, 706, 706, 706, + 706, 706, nil, nil, nil, 706, 706, 715, 715, 715, + nil, 715, nil, nil, nil, 715, 715, nil, nil, nil, + 715, nil, 715, 715, 715, 715, 715, 715, 715, nil, + nil, nil, nil, 715, 715, 715, 715, 715, 715, 715, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 715, + nil, nil, 715, 715, 715, 715, 715, 715, 715, 715, + 715, 715, nil, 715, 715, 715, 715, 715, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 715, nil, nil, + 715, nil, nil, 715, 715, nil, nil, 715, nil, 715, + nil, 715, nil, 715, nil, nil, nil, nil, nil, nil, + nil, 715, nil, nil, nil, nil, 715, 715, 715, 715, + 715, 715, nil, nil, nil, 715, 715, 717, 717, 717, + nil, 717, nil, nil, nil, 717, 717, nil, nil, nil, + 717, nil, 717, 717, 717, 717, 717, 717, 717, nil, + nil, nil, nil, 717, 717, 717, 717, 717, 717, 717, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 717, + nil, nil, 717, 717, 717, 717, 717, 717, 717, 717, + 717, 717, nil, 717, 717, 717, 717, 717, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 717, nil, nil, + 717, nil, nil, 717, 717, nil, nil, 717, nil, 717, + nil, 717, nil, 717, nil, nil, nil, nil, nil, nil, + nil, 717, nil, nil, nil, nil, 717, 717, 717, 717, + 717, 717, nil, nil, nil, 717, 717, 730, 730, 730, + nil, 730, nil, nil, nil, 730, 730, nil, nil, nil, + 730, nil, 730, 730, 730, 730, 730, 730, 730, nil, + nil, nil, nil, 730, 730, 730, 730, 730, 730, 730, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 730, + nil, nil, 730, 730, 730, 730, 730, 730, 730, 730, + 730, 730, nil, 730, 730, nil, nil, 730, nil, 679, + 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, + nil, 679, 679, nil, nil, 679, 679, 730, nil, nil, + 730, nil, nil, 730, 730, nil, nil, 730, nil, nil, + nil, 679, nil, 679, nil, 679, 679, 679, 679, 679, + 679, 679, nil, 679, nil, nil, 730, 730, 730, 730, + 730, 730, nil, nil, nil, 730, 730, 736, 736, 736, + 679, 736, nil, nil, nil, 736, 736, nil, nil, nil, + 736, nil, 736, 736, 736, 736, 736, 736, 736, nil, + nil, nil, nil, 736, 736, 736, 736, 736, 736, 736, + nil, nil, 736, nil, nil, nil, nil, nil, nil, 736, + nil, nil, 736, 736, 736, 736, 736, 736, 736, 736, + 736, 736, nil, 736, 736, 736, 736, 736, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 736, nil, nil, + 736, nil, nil, 736, 736, nil, nil, 736, nil, nil, + nil, nil, nil, 736, nil, nil, nil, nil, nil, nil, + nil, 736, nil, nil, nil, nil, 736, 736, 736, 736, + 736, 736, nil, nil, nil, 736, 736, 742, 742, 742, + nil, 742, nil, nil, nil, 742, 742, nil, nil, nil, + 742, nil, 742, 742, 742, 742, 742, 742, 742, nil, + nil, nil, nil, 742, 742, 742, 742, 742, 742, 742, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 742, + nil, nil, 742, 742, 742, 742, 742, 742, 742, 742, + 742, 742, nil, 742, 742, 742, 742, 742, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 742, nil, nil, + 742, nil, nil, 742, 742, nil, nil, 742, nil, 742, + nil, nil, nil, 742, nil, nil, nil, nil, nil, nil, + nil, 742, nil, nil, nil, nil, 742, 742, 742, 742, + 742, 742, nil, nil, nil, 742, 742, 761, 761, 761, + nil, 761, nil, nil, nil, 761, 761, nil, nil, nil, + 761, nil, 761, 761, 761, 761, 761, 761, 761, nil, + nil, nil, nil, 761, 761, 761, 761, 761, 761, 761, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 761, + nil, nil, 761, 761, 761, 761, 761, 761, 761, 761, + 761, 761, nil, 761, 761, 761, 761, 761, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 761, nil, nil, + 761, nil, nil, 761, 761, nil, nil, 761, nil, nil, + nil, nil, nil, 761, nil, nil, nil, nil, nil, nil, + nil, 761, nil, nil, nil, nil, 761, 761, 761, 761, + 761, 761, nil, nil, nil, 761, 761, 770, 770, 770, + nil, 770, nil, nil, nil, 770, 770, nil, nil, nil, + 770, nil, 770, 770, 770, 770, 770, 770, 770, nil, + nil, nil, nil, 770, 770, 770, 770, 770, 770, 770, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 770, + nil, nil, 770, 770, 770, 770, 770, 770, 770, 770, + 770, 770, nil, 770, 770, 770, 770, 770, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 770, nil, nil, + 770, nil, nil, 770, 770, nil, nil, 770, nil, nil, + nil, nil, nil, 770, nil, nil, nil, nil, nil, nil, + nil, 770, nil, nil, nil, nil, 770, 770, 770, 770, + 770, 770, nil, nil, nil, 770, 770, 771, 771, 771, + nil, 771, nil, nil, nil, 771, 771, nil, nil, nil, + 771, nil, 771, 771, 771, 771, 771, 771, 771, nil, + nil, nil, nil, 771, 771, 771, 771, 771, 771, 771, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 771, + nil, nil, 771, 771, 771, 771, 771, 771, 771, 771, + 771, 771, nil, 771, 771, nil, nil, 771, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 771, nil, nil, + 771, nil, nil, 771, 771, nil, nil, 771, nil, 771, + nil, 771, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 771, 771, 771, 771, + 771, 771, nil, nil, nil, 771, 771, 782, 782, 782, + nil, 782, nil, nil, nil, 782, 782, nil, nil, nil, + 782, nil, 782, 782, 782, 782, 782, 782, 782, nil, + nil, nil, nil, 782, 782, 782, 782, 782, 782, 782, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 782, + nil, nil, 782, 782, 782, 782, 782, 782, 782, 782, + 782, 782, nil, 782, 782, 782, 782, 782, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 782, nil, nil, + 782, nil, nil, 782, 782, nil, nil, 782, nil, nil, + nil, nil, nil, 782, nil, nil, nil, nil, nil, nil, + nil, 782, nil, nil, nil, nil, 782, 782, 782, 782, + 782, 782, nil, nil, nil, 782, 782, 788, 788, 788, + nil, 788, nil, nil, nil, 788, 788, nil, nil, nil, + 788, nil, 788, 788, 788, 788, 788, 788, 788, nil, + nil, nil, nil, 788, 788, 788, 788, 788, 788, 788, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 788, + nil, nil, 788, 788, 788, 788, 788, 788, 788, 788, + 788, 788, nil, 788, 788, 788, 788, 788, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 788, nil, nil, + 788, nil, nil, 788, 788, nil, nil, 788, nil, nil, + nil, nil, nil, 788, nil, nil, nil, nil, nil, nil, + nil, 788, nil, nil, nil, nil, 788, 788, 788, 788, + 788, 788, nil, nil, nil, 788, 788, 790, 790, 790, + nil, 790, nil, nil, nil, 790, 790, nil, nil, nil, + 790, nil, 790, 790, 790, 790, 790, 790, 790, nil, + nil, nil, nil, 790, 790, 790, 790, 790, 790, 790, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 790, + nil, nil, 790, 790, 790, 790, 790, 790, 790, 790, + 790, 790, nil, 790, 790, 790, 790, 790, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 790, nil, nil, + 790, nil, nil, 790, 790, nil, nil, 790, nil, nil, + nil, nil, nil, 790, nil, nil, nil, nil, nil, nil, + nil, 790, nil, nil, nil, nil, 790, 790, 790, 790, + 790, 790, nil, nil, nil, 790, 790, 804, 804, 804, + nil, 804, nil, nil, nil, 804, 804, nil, nil, nil, + 804, nil, 804, 804, 804, 804, 804, 804, 804, nil, + nil, nil, nil, 804, 804, 804, 804, 804, 804, 804, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 804, + nil, nil, 804, 804, 804, 804, 804, 804, 804, 804, + 804, 804, nil, 804, 804, 804, 804, 804, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 804, nil, nil, + 804, nil, nil, 804, 804, nil, nil, 804, nil, nil, + nil, nil, nil, 804, nil, nil, nil, nil, nil, nil, + nil, 804, nil, nil, nil, nil, 804, 804, 804, 804, + 804, 804, nil, nil, nil, 804, 804, 822, 822, 822, + nil, 822, nil, nil, nil, 822, 822, nil, nil, nil, + 822, nil, 822, 822, 822, 822, 822, 822, 822, nil, + nil, nil, nil, 822, 822, 822, 822, 822, 822, 822, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 822, + nil, nil, 822, 822, 822, 822, 822, 822, 822, 822, + 822, 822, nil, 822, 822, nil, nil, 822, nil, 684, + 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, + nil, 684, 684, nil, nil, 684, 684, 822, nil, nil, + 822, nil, nil, 822, 822, nil, nil, 822, nil, nil, + nil, 684, nil, 684, nil, 684, 684, 684, 684, 684, + 684, 684, nil, 684, nil, nil, 822, 822, 822, 822, + 822, 822, nil, nil, nil, 822, 822, 824, 824, 824, + 684, 824, nil, nil, nil, 824, 824, nil, nil, nil, + 824, nil, 824, 824, 824, 824, 824, 824, 824, nil, + nil, nil, nil, 824, 824, 824, 824, 824, 824, 824, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 824, + nil, nil, 824, 824, 824, 824, 824, 824, 824, 824, + 824, 824, nil, 824, 824, 824, 824, 824, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 824, nil, nil, + 824, nil, nil, 824, 824, nil, nil, 824, nil, 824, + nil, nil, nil, 824, nil, nil, nil, nil, nil, nil, + nil, 824, nil, nil, nil, nil, 824, 824, 824, 824, + 824, 824, nil, nil, nil, 824, 824, 829, 829, 829, + nil, 829, nil, nil, nil, 829, 829, nil, nil, nil, + 829, nil, 829, 829, 829, 829, 829, 829, 829, nil, + nil, nil, nil, 829, 829, 829, 829, 829, 829, 829, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 829, + nil, nil, 829, 829, 829, 829, 829, 829, 829, 829, + 829, 829, nil, 829, 829, nil, nil, 829, nil, 686, + 686, 686, 686, 686, 686, 686, 686, 686, 686, 686, + nil, 686, 686, nil, nil, 686, 686, 829, nil, nil, + 829, nil, nil, 829, 829, nil, nil, 829, nil, nil, + nil, 686, nil, 686, nil, 686, 686, 686, 686, 686, + 686, 686, nil, 686, nil, nil, 829, 829, 829, 829, + 829, 829, nil, nil, nil, 829, 829, 834, 834, 834, + 686, 834, nil, nil, nil, 834, 834, nil, nil, nil, + 834, nil, 834, 834, 834, 834, 834, 834, 834, nil, + nil, nil, nil, 834, 834, 834, 834, 834, 834, 834, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 834, + nil, nil, 834, 834, 834, 834, 834, 834, 834, 834, + 834, 834, nil, 834, 834, 834, 834, 834, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 834, nil, nil, + 834, nil, nil, 834, 834, nil, nil, 834, nil, 834, + nil, 834, nil, 834, nil, nil, nil, nil, nil, nil, + nil, 834, nil, nil, nil, nil, 834, 834, 834, 834, + 834, 834, nil, nil, nil, 834, 834, 837, 837, 837, + nil, 837, nil, nil, nil, 837, 837, nil, nil, nil, + 837, nil, 837, 837, 837, 837, 837, 837, 837, nil, + nil, nil, nil, 837, 837, 837, 837, 837, 837, 837, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 837, + nil, nil, 837, 837, 837, 837, 837, 837, 837, 837, + 837, 837, nil, 837, 837, 837, 837, 837, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 837, nil, nil, + 837, nil, nil, 837, 837, nil, nil, 837, nil, 837, + nil, 837, nil, 837, nil, nil, nil, nil, nil, nil, + nil, 837, nil, nil, nil, nil, 837, 837, 837, 837, + 837, 837, nil, nil, nil, 837, 837, 863, 863, 863, + nil, 863, nil, nil, nil, 863, 863, nil, nil, nil, + 863, nil, 863, 863, 863, 863, 863, 863, 863, nil, + nil, nil, nil, 863, 863, 863, 863, 863, 863, 863, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 863, + nil, nil, 863, 863, 863, 863, 863, 863, 863, 863, + 863, 863, nil, 863, 863, nil, nil, 863, nil, 689, + 689, 689, 689, 689, 689, 689, 689, 689, 689, 689, + nil, 689, 689, nil, nil, 689, 689, 863, nil, nil, + 863, nil, nil, 863, 863, nil, nil, 863, nil, nil, + nil, 689, nil, 689, nil, 689, 689, 689, 689, 689, + 689, 689, nil, 689, nil, nil, 863, 863, 863, 863, + 863, 863, nil, nil, nil, 863, 863, 866, 866, 866, + 689, 866, nil, nil, nil, 866, 866, nil, nil, nil, + 866, nil, 866, 866, 866, 866, 866, 866, 866, nil, + nil, nil, nil, 866, 866, 866, 866, 866, 866, 866, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 866, + nil, nil, 866, 866, 866, 866, 866, 866, 866, 866, + 866, 866, nil, 866, 866, 866, 866, 866, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 866, nil, nil, + 866, nil, nil, 866, 866, nil, nil, 866, nil, nil, + nil, nil, nil, 866, nil, nil, nil, nil, nil, nil, + nil, 866, nil, nil, nil, nil, 866, 866, 866, 866, + 866, 866, nil, nil, nil, 866, 866, 869, 869, 869, + nil, 869, nil, nil, nil, 869, 869, nil, nil, nil, + 869, nil, 869, 869, 869, 869, 869, 869, 869, nil, + nil, nil, nil, 869, 869, 869, 869, 869, 869, 869, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 869, + nil, nil, 869, 869, 869, 869, 869, 869, 869, 869, + 869, 869, nil, 869, 869, 869, 869, 869, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 869, nil, nil, + 869, nil, nil, 869, 869, nil, nil, 869, nil, nil, + nil, nil, nil, 869, nil, nil, nil, nil, nil, nil, + nil, 869, nil, nil, nil, nil, 869, 869, 869, 869, + 869, 869, nil, nil, nil, 869, 869, 877, 877, 877, + nil, 877, nil, nil, nil, 877, 877, nil, nil, nil, + 877, nil, 877, 877, 877, 877, 877, 877, 877, nil, + nil, nil, nil, 877, 877, 877, 877, 877, 877, 877, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 877, + nil, nil, 877, 877, 877, 877, 877, 877, 877, 877, + 877, 877, nil, 877, 877, nil, nil, 877, nil, 691, + 691, 691, 691, 691, 691, 691, 691, 691, 691, 691, + nil, 691, 691, nil, nil, 691, 691, 877, nil, nil, + 877, nil, nil, 877, 877, nil, nil, 877, nil, nil, + nil, 691, nil, 691, nil, 691, 691, 691, 691, 691, + 691, 691, nil, 691, nil, nil, 877, 877, 877, 877, + 877, 877, nil, nil, nil, 877, 877, 882, 882, 882, + 691, 882, nil, nil, nil, 882, 882, nil, nil, nil, + 882, nil, 882, 882, 882, 882, 882, 882, 882, nil, + nil, nil, nil, 882, 882, 882, 882, 882, 882, 882, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 882, + nil, nil, 882, 882, 882, 882, 882, 882, 882, 882, + 882, 882, nil, 882, 882, 882, 882, 882, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 882, nil, nil, + 882, nil, nil, 882, 882, nil, nil, 882, nil, 882, + nil, 882, nil, 882, nil, nil, nil, nil, nil, nil, + nil, 882, nil, nil, nil, nil, 882, 882, 882, 882, + 882, 882, nil, nil, nil, 882, 882, 888, 888, 888, + nil, 888, nil, nil, nil, 888, 888, nil, nil, nil, + 888, nil, 888, 888, 888, 888, 888, 888, 888, nil, + nil, nil, nil, 888, 888, 888, 888, 888, 888, 888, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 888, + nil, nil, 888, 888, 888, 888, 888, 888, 888, 888, + 888, 888, nil, 888, 888, nil, nil, 888, nil, 696, + 696, 696, 696, 696, 696, 696, 696, 696, 696, 696, + nil, 696, 696, nil, nil, 696, 696, 888, nil, nil, + 888, nil, nil, 888, 888, nil, nil, 888, nil, nil, + nil, 696, nil, 696, nil, 696, 696, 696, 696, 696, + 696, 696, nil, 696, nil, nil, 888, 888, 888, 888, + 888, 888, nil, nil, nil, 888, 888, 891, 891, 891, + 696, 891, nil, nil, nil, 891, 891, nil, nil, nil, + 891, nil, 891, 891, 891, 891, 891, 891, 891, nil, + nil, nil, nil, 891, 891, 891, 891, 891, 891, 891, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 891, + nil, nil, 891, 891, 891, 891, 891, 891, 891, 891, + 891, 891, nil, 891, 891, 891, 891, 891, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 891, nil, nil, + 891, nil, nil, 891, 891, nil, nil, 891, nil, nil, + nil, nil, nil, 891, nil, nil, nil, nil, nil, nil, + nil, 891, nil, nil, nil, nil, 891, 891, 891, 891, + 891, 891, nil, nil, nil, 891, 891, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, nil, nil, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, nil, nil, nil, nil, nil, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + nil, nil, nil, nil, nil, 64, 64, nil, 64, 64, + 64, 64, nil, 64, 64, nil, nil, 64, nil, nil, + nil, nil, 64, 64, 64, 64, nil, nil, nil, nil, + nil, 64, nil, nil, nil, nil, nil, nil, nil, 64, + 64, nil, 64, 64, 64, 64, 64, 64, 64, 64, + 64, nil, 64, nil, nil, 64, 666, 666, 666, 666, + 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, + 666, 666, 666, 666, 666, 666, 666, 666, 666, 666, + nil, nil, 666, 666, 666, 666, 666, 666, 666, 666, + 666, 666, nil, nil, nil, nil, nil, 666, 666, 666, + 666, 666, 666, 666, 666, nil, nil, 666, nil, nil, + nil, nil, nil, nil, 666, 666, nil, 666, 666, 666, + 666, nil, 666, 666, nil, nil, 666, nil, nil, nil, + nil, 666, 666, 666, 666, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 666, 666, + nil, 666, 666, 666, 666, 666, 666, 666, 666, 666, + nil, 666, nil, nil, 666, 583, 583, 583, 583, 583, + 583, 583, 583, 583, 583, 583, nil, 583, 583, nil, + nil, 583, 583, nil, nil, nil, 583, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 583, nil, 583, + nil, 583, 583, 583, 583, 583, 583, 583, nil, 583, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 583, nil, 583, 425, + 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, + nil, 425, 425, nil, nil, 425, 425, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 425, nil, 425, nil, 425, 425, 425, 425, 425, + 425, 425, nil, 425, nil, nil, nil, nil, nil, nil, + nil, 194, 194, nil, nil, 194, nil, nil, nil, nil, + 425, 425, 194, 194, nil, 194, 194, 194, 194, nil, + 194, 194, nil, nil, 194, nil, nil, nil, nil, 194, + 194, 194, 194, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 194, 194, nil, 194, + 194, 194, 194, 194, 194, 194, 194, 194, nil, 194, + 195, 195, 194, nil, 195, nil, nil, nil, nil, nil, + nil, 195, 195, nil, 195, 195, 195, 195, nil, 195, + 195, nil, nil, 195, nil, nil, nil, nil, 195, 195, + 195, 195, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 195, 195, nil, 195, 195, + 195, 195, 195, 195, 195, 195, 195, nil, 195, 253, + 253, 195, nil, 253, nil, nil, nil, nil, nil, nil, + 253, 253, nil, 253, 253, 253, 253, nil, 253, 253, + nil, nil, 253, nil, nil, nil, nil, 253, 253, 253, + 253, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 253, 253, nil, 253, 253, 253, + 253, 253, 253, 253, 253, 253, nil, 253, 254, 254, + 253, nil, 254, nil, nil, nil, nil, nil, nil, 254, + 254, nil, 254, 254, 254, 254, nil, 254, 254, nil, + nil, 254, nil, nil, nil, nil, 254, 254, 254, 254, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 254, 254, nil, 254, 254, 254, 254, + 254, 254, 254, 254, 254, nil, 254, 393, 393, 254, + nil, 393, nil, nil, nil, nil, nil, nil, 393, 393, + nil, 393, 393, 393, 393, nil, 393, 393, nil, nil, + 393, nil, nil, nil, nil, 393, 393, 393, 393, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 393, 393, nil, 393, 393, 393, 393, 393, + 393, 393, 393, 393, nil, 393, 394, 394, 393, nil, + 394, nil, nil, nil, nil, nil, nil, 394, 394, nil, + 394, 394, 394, 394, nil, 394, 394, nil, nil, 394, + nil, nil, nil, nil, 394, 394, 394, 394, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 394, 394, nil, 394, 394, 394, 394, 394, 394, + 394, 394, 394, nil, 394, 459, 459, 394, nil, 459, + nil, nil, nil, nil, nil, nil, 459, 459, nil, 459, + 459, 459, 459, nil, 459, 459, nil, nil, 459, nil, + nil, nil, nil, 459, 459, 459, 459, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 459, 459, nil, 459, 459, 459, 459, 459, 459, 459, + 459, 459, nil, 459, 460, 460, 459, nil, 460, nil, + nil, nil, nil, nil, nil, 460, 460, nil, 460, 460, + 460, 460, nil, 460, 460, nil, nil, 460, nil, nil, + nil, nil, 460, 460, 460, 460, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 460, + 460, nil, 460, 460, 460, 460, 460, 460, 460, 460, + 460, nil, 460, 468, 468, 460, nil, 468, nil, nil, + nil, nil, nil, nil, 468, 468, nil, 468, 468, 468, + 468, nil, 468, 468, nil, nil, 468, nil, nil, nil, + nil, 468, 468, 468, 468, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 468, 468, + nil, 468, 468, 468, 468, 468, 468, 468, 468, 468, + nil, 468, 469, 469, 468, nil, 469, nil, nil, nil, + nil, nil, nil, 469, 469, nil, 469, 469, 469, 469, + nil, 469, 469, nil, nil, 469, nil, nil, nil, nil, + 469, 469, 469, 469, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 469, 469, nil, + 469, 469, 469, 469, 469, 469, 469, 469, 469, nil, + 469, nil, nil, 469, 482, 482, 482, 482, 482, 482, + 482, 482, 482, 482, 482, nil, 482, 482, nil, nil, + 482, 482, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 482, nil, 482, nil, + 482, 482, 482, 482, 482, 482, 482, nil, 482, nil, + nil, nil, nil, nil, nil, 500, 500, nil, nil, 500, + nil, nil, nil, nil, 482, 482, 500, 500, nil, 500, + 500, 500, 500, nil, 500, 500, nil, nil, 500, nil, + nil, nil, nil, 500, 500, 500, 500, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 500, 500, nil, 500, 500, 500, 500, 500, 500, 500, + 500, 500, nil, 500, 501, 501, 500, nil, 501, nil, + nil, nil, nil, nil, nil, 501, 501, nil, 501, 501, + 501, 501, nil, 501, 501, nil, nil, 501, nil, nil, + nil, nil, 501, 501, 501, 501, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 501, + 501, nil, 501, 501, 501, 501, 501, 501, 501, 501, + 501, nil, 501, 507, 507, 501, nil, 507, nil, nil, + nil, nil, nil, nil, 507, 507, nil, 507, 507, 507, + 507, nil, 507, 507, nil, nil, 507, nil, nil, nil, + nil, 507, 507, 507, 507, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 507, 507, + nil, 507, 507, 507, 507, 507, 507, 507, 507, 507, + nil, 507, 509, 509, 507, nil, 509, nil, nil, nil, + nil, nil, nil, 509, 509, nil, 509, 509, 509, 509, + nil, 509, 509, nil, nil, 509, nil, nil, nil, nil, + 509, 509, 509, 509, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 509, 509, nil, + 509, 509, 509, 509, 509, 509, 509, 509, 509, nil, + 509, 580, 580, 509, nil, 580, nil, nil, nil, nil, + nil, nil, 580, 580, nil, 580, 580, 580, 580, nil, + 580, 580, nil, nil, 580, nil, nil, nil, nil, 580, + 580, 580, 580, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 580, 580, nil, 580, + 580, 580, 580, 580, 580, 580, 580, 580, nil, 580, + 581, 581, 580, nil, 581, nil, nil, nil, nil, nil, + nil, 581, 581, nil, 581, 581, 581, 581, nil, 581, + 581, nil, nil, 581, nil, nil, nil, nil, 581, 581, + 581, 581, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 581, 581, nil, 581, 581, + 581, 581, 581, 581, 581, 581, 581, nil, 581, nil, + nil, 581, 733, 733, 733, 733, 733, 733, 733, 733, + 733, 733, 733, nil, 733, 733, nil, nil, 733, 733, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 733, nil, 733, nil, 733, 733, + 733, 733, 733, 733, 733, nil, 733, nil, 769, 769, + 769, 769, 769, 769, 769, 769, 769, 769, 769, nil, + 769, 769, 733, 733, 769, 769, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 769, nil, 769, nil, 769, 769, 769, 769, 769, 769, + 769, nil, 769, nil, nil, nil, 825, 825, nil, nil, + 825, nil, nil, nil, nil, nil, nil, 825, 825, 769, + 825, 825, 825, 825, nil, 825, 825, nil, nil, 825, + nil, nil, nil, nil, 825, 825, 825, 825, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 825, 825, nil, 825, 825, 825, 825, 825, 825, + 825, 825, 825, nil, 825, 826, 826, 825, nil, 826, + nil, nil, nil, nil, nil, nil, 826, 826, nil, 826, + 826, 826, 826, nil, 826, 826, nil, nil, 826, nil, + nil, nil, nil, 826, 826, 826, 826, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 826, 826, nil, 826, 826, 826, 826, 826, 826, 826, + 826, 826, nil, 826, nil, nil, 826 ] + +racc_action_pointer = [ + 1221, 29, nil, 133, 854, 4729, 4849, 4969, -52, -46, + -41, -31, 27, 271, 117, 206, nil, 5081, 5201, 6042, + 100, nil, 5321, 5441, 5561, 268, 141, 5681, 5801, nil, + 1342, 5921, 6041, nil, 91, 221, 220, 200, 6161, 6281, + 6401, 166, 357, nil, nil, nil, nil, nil, nil, nil, + 212, 1463, 6521, 6641, 6761, 57, 6881, 7001, nil, nil, + 727, 7121, 7241, 7361, 22585, nil, nil, nil, nil, nil, + nil, nil, 82, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 7481, nil, nil, nil, 7601, nil, + nil, nil, nil, nil, nil, nil, nil, 298, nil, 854, + nil, nil, nil, 7721, 7841, 7961, 8081, 8201, 971, nil, + 340, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 182, nil, 1584, 1705, + 8321, 8441, 8561, 8681, 22872, 22931, 8801, 8921, 9041, nil, + 385, -52, 295, -51, 241, 298, 1826, nil, nil, 9161, + 9281, 9401, 9521, 9641, 9761, 9881, 10001, 10121, 10241, 10361, + 10481, 10601, 10721, 10841, 10961, 11081, 11201, 11321, 11441, 11561, + 11681, 11801, 11921, 12041, 12161, 12281, nil, nil, nil, 7122, + nil, 264, 289, 12401, nil, 12521, 344, nil, nil, nil, + nil, nil, nil, 22990, 23049, 361, 12641, 12761, nil, nil, + nil, nil, nil, nil, nil, 12881, 405, 1947, 416, 478, + 442, 13001, 2068, 476, 481, 521, 506, 496, 461, 158, + nil, 506, 213, nil, nil, 237, 531, 532, 596, nil, + 534, nil, 13121, nil, 597, 596, 429, nil, 483, 241, + 316, 13241, 523, 388, 506, 441, nil, 477, -7, 8, + 13361, 13481, 172, 31, 491, -9, 601, 567, -1, 597, + nil, nil, 220, 265, -23, nil, 626, nil, 9, 13601, + nil, nil, 288, 312, 351, 382, 407, 451, 452, 470, + nil, 482, nil, 13721, nil, 205, 284, 317, 343, -35, + 351, nil, 1092, nil, nil, nil, nil, nil, nil, 13841, + nil, nil, nil, nil, 534, 536, nil, nil, 727, nil, + 520, 13953, nil, 521, nil, nil, 7242, 559, 246, 293, + 14073, nil, nil, 0, 566, 106, nil, 14193, 14313, nil, + 7362, nil, nil, 23108, 23167, 14433, -37, 14553, 14673, 14793, + 974, 1221, 377, 549, 590, 601, 608, 609, 2794, 2915, + 3036, 1342, 1463, 1584, 1705, 1826, 1947, 2068, 2189, 2310, + 2431, 459, 579, 2552, 2673, 22806, -50, nil, 14913, nil, + 15033, 547, nil, 15153, 318, nil, nil, 371, nil, nil, + 589, 560, -63, 558, 658, nil, nil, 15273, -47, 92, + 600, nil, 601, 568, nil, nil, nil, 610, 15393, 23226, + 23285, 651, 612, nil, nil, 15513, 15633, 15753, 23344, 23403, + 13002, 15873, 688, 15993, nil, 581, nil, nil, 16113, nil, + nil, 16233, 23451, nil, 16353, nil, nil, nil, 2189, 700, + nil, nil, 2310, 67, 108, 698, 706, 2431, 16473, 16593, + 23516, 23575, 4, nil, nil, 727, nil, 23634, 16713, 23693, + nil, nil, 16833, 327, -34, 2552, 537, nil, nil, nil, + -32, nil, nil, nil, 711, nil, nil, nil, 595, nil, + 147, nil, nil, 597, nil, nil, 16953, nil, nil, 17065, + 17185, nil, 294, 17305, 17425, 633, nil, nil, 17545, 641, + nil, 17665, 70, 85, 487, 607, 644, 1095, 17785, 17905, + nil, 2673, 18025, 613, nil, 656, 18145, nil, 659, nil, + 672, nil, nil, nil, nil, nil, 113, nil, 683, 685, + 23752, 23811, 18265, 22742, -67, 647, 18385, nil, 697, nil, + 2794, 2915, nil, -30, nil, 714, 62, 111, 724, 308, + 780, 727, 19466, 751, 755, -2, 813, nil, 3036, 697, + 751, nil, nil, 749, 18505, nil, nil, 510, nil, 823, + nil, nil, nil, nil, nil, 835, nil, 836, 720, 15, + 18625, 758, 13, 24, 25, 137, 18745, 340, 837, nil, + 761, 3157, 350, nil, nil, 853, 3278, 433, 372, 737, + 741, 742, nil, nil, nil, nil, nil, 749, nil, nil, + nil, nil, 830, nil, nil, 831, 22694, 794, nil, nil, + nil, nil, nil, 3399, nil, nil, nil, nil, nil, 19946, + 763, 18865, 18985, nil, 21146, nil, 21386, nil, nil, 21746, + nil, 22106, 19105, 19225, 19345, 214, 22346, nil, 764, 974, + 19465, nil, 815, 921, 805, nil, 19585, 808, 3520, nil, + nil, 854, 858, -62, 918, 19705, nil, 19825, 823, nil, + 863, 842, 952, 730, nil, nil, 3641, nil, nil, 31, + 19945, nil, nil, 23859, 953, nil, 20065, 955, 3762, 3883, + nil, nil, 20185, 4004, nil, 26, 132, nil, 962, nil, + 4125, nil, 963, 850, nil, 657, nil, -43, nil, nil, + 456, 20305, nil, nil, nil, nil, 870, nil, nil, 23905, + 20425, 20545, 843, 845, 928, 847, 857, 890, nil, nil, + nil, nil, 20665, nil, 878, 901, 888, nil, 20785, 889, + 20905, nil, nil, nil, nil, nil, 4246, nil, nil, nil, + 32, nil, 1007, 1008, 21025, 148, nil, nil, 1010, nil, + 933, 905, 908, nil, nil, 909, 919, nil, nil, 904, + nil, nil, 21145, 1095, 21265, 23967, 24026, 848, 955, 21385, + 5922, nil, nil, nil, 21505, 926, nil, 21625, 929, 1050, + 4367, nil, nil, nil, nil, nil, nil, 4488, nil, nil, + 173, nil, nil, nil, 4609, nil, 932, 964, 970, 343, + 363, 393, 873, 21745, nil, nil, 21865, 938, nil, 21985, + nil, nil, 564, 1056, 941, 1059, 974, 22105, 851, nil, + 946, nil, 22225, 954, nil, nil, nil, nil, 22345, nil, + nil, 22465, nil, nil, 956, nil ] + +racc_action_default = [ + -4, -499, -1, -487, -5, -499, -499, -499, -499, -499, + -499, -499, -499, -499, -271, -32, -33, -499, -499, -38, + -40, -41, -282, -315, -316, -45, -249, -363, -285, -58, + -4, -62, -67, -68, -499, -430, -499, -499, -499, -499, + -499, -489, -214, -264, -265, -266, -267, -268, -269, -270, + -477, -4, -499, -498, -469, -288, -499, -499, -292, -295, + -487, -499, -499, -499, -499, -317, -318, -320, -321, -383, + -384, -385, -386, -387, -401, -390, -403, -403, -394, -399, + -413, -403, -415, -416, -419, -420, -421, -422, -423, -424, + -425, -426, -427, -428, -429, -432, -433, -499, -3, -488, + -494, -495, -496, -499, -499, -499, -499, -499, -6, -8, + -499, -93, -94, -95, -96, -97, -98, -99, -100, -101, + -105, -106, -107, -108, -109, -110, -111, -112, -113, -114, + -115, -116, -117, -118, -119, -120, -121, -122, -123, -124, + -125, -126, -127, -128, -129, -130, -131, -132, -133, -134, + -135, -136, -137, -138, -139, -140, -141, -142, -143, -144, + -145, -146, -147, -148, -149, -150, -151, -152, -153, -154, + -155, -156, -157, -158, -159, -160, -161, -162, -163, -164, + -165, -166, -167, -168, -169, -170, -13, -102, -4, -4, + -499, -499, -499, -498, -499, -499, -499, -499, -499, -36, + -499, -430, -499, -271, -499, -499, -4, -37, -206, -499, + -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, + -499, -499, -499, -499, -499, -499, -499, -499, -499, -499, + -499, -499, -499, -499, -499, -499, -353, -355, -42, -215, + -228, -258, -258, -499, -236, -499, -259, -282, -315, -316, + -472, -43, -44, -499, -499, -50, -498, -499, -287, -358, + -364, -366, -56, -362, -57, -499, -58, -4, -499, -499, + -63, -65, -4, -72, -499, -499, -79, -285, -489, -499, + -319, -363, -499, -66, -70, -278, -417, -418, -499, -191, + -192, -207, -499, -490, -375, -499, -274, -216, -489, -491, + -491, -499, -499, -491, -499, -491, -289, -39, -499, -499, + -499, -499, -487, -499, -488, -430, -499, -499, -271, -499, + -333, -334, -88, -89, -499, -91, -499, -271, -499, -499, + -430, -308, -93, -94, -131, -132, -148, -153, -160, -163, + -310, -499, -467, -499, -388, -499, -499, -499, -499, -499, + -499, 896, -7, -497, -14, -15, -16, -17, -18, -499, + -10, -11, -12, -103, -499, -499, -21, -29, -171, -259, + -499, -499, -22, -30, -31, -23, -173, -499, -478, -479, + -226, -480, -481, -478, -249, -479, -361, -483, -484, -28, + -180, -34, -35, -499, -499, -498, -278, -499, -499, -499, + -181, -182, -183, -184, -185, -186, -187, -188, -193, -194, + -195, -196, -197, -198, -199, -200, -201, -202, -203, -204, + -205, -208, -209, -210, -211, -499, -349, -229, -499, -231, + -499, -258, -256, -499, -249, -478, -479, -249, -48, -51, + -499, -489, -489, -258, -228, -250, -251, -252, -349, -349, + -499, -284, -499, -59, -276, -71, -64, -499, -498, -499, + -499, -78, -499, -417, -418, -499, -499, -499, -499, -499, + -212, -499, -498, -498, -273, -489, -217, -218, -493, -492, + -220, -493, -489, -280, -493, -471, -281, -470, -4, -322, + -323, -324, -4, -499, -499, -499, -499, -4, -499, -498, + -499, -499, -278, -301, -88, -89, -90, -499, -498, -499, + -304, -434, -499, -499, -499, -4, -447, -312, -485, -486, + -489, -389, -402, -405, -499, -407, -391, -404, -499, -393, + -499, -396, -398, -499, -414, -9, -499, -19, -20, -499, + -499, -263, -279, -499, -499, -52, -227, -359, -499, -54, + -360, -499, -478, -479, -482, -277, -499, -171, -499, -499, + -351, -4, -499, -258, -257, -260, -499, -473, -499, -235, + -499, -474, -46, -356, -47, -357, -349, -222, -499, -499, + -499, -499, -499, -38, -499, -258, -499, -248, -499, -254, + -4, -4, -283, -59, -69, -499, -478, -479, -226, -75, + -77, -499, -179, -189, -190, -499, -498, -331, -4, -376, + -498, -377, -378, -499, -499, -260, -221, -498, -325, -498, + -293, -326, -327, -328, -296, -499, -299, -499, -369, -499, + -499, -499, -478, -479, -482, -277, -499, -88, -89, -92, + -499, -4, -499, -436, -306, -499, -4, -447, -499, -466, + -466, -466, -446, -448, -449, -450, -451, -452, -453, -456, + -458, -459, -461, -462, -463, -499, -499, -499, -406, -409, + -410, -411, -412, -4, -392, -395, -397, -400, -104, -172, + -261, -499, -499, -25, -175, -26, -176, -53, -27, -177, + -55, -178, -499, -499, -499, -279, -213, -335, -337, -347, + -499, -350, -499, -499, -258, -233, -499, -258, -4, -223, + -224, -226, -226, -489, -499, -499, -241, -499, -258, -253, + -499, -499, -499, -73, -286, -2, -4, -382, -332, -499, + -499, -380, -275, -489, -499, -329, -499, -499, -4, -4, + -298, -300, -499, -4, -371, -279, -499, -279, -499, -435, + -4, -309, -499, -489, -438, -499, -442, -499, -444, -445, + -499, -499, -460, -464, -313, -468, -499, -262, -24, -174, + -499, -338, -80, -499, -499, -87, -346, -499, -348, -352, + -354, -230, -499, -232, -499, -499, -258, -238, -499, -258, + -499, -247, -255, -365, -367, -381, -4, -379, -219, -290, + -499, -291, -499, -499, -499, -498, -302, -305, -499, -311, + -499, -466, -466, -454, -465, -466, -499, -457, -455, -447, + -408, -336, -499, -343, -498, -499, -499, -86, -499, -499, + -258, -49, -225, -237, -499, -258, -243, -499, -258, -375, + -4, -294, -297, -370, -368, -372, -373, -4, -307, -437, + -499, -440, -441, -443, -4, -339, -342, -499, -499, -82, + -84, -83, -85, -499, -345, -234, -499, -258, -239, -499, + -242, -374, -498, -499, -466, -499, -499, -499, -81, -344, + -258, -244, -499, -258, -330, -303, -439, -314, -499, -341, + -240, -499, -245, -340, -258, -246 ] + +racc_goto_table = [ + 10, 472, 242, 242, 242, 10, 270, 280, 280, 340, + 295, 259, 263, 302, 240, 240, 240, 244, 244, 244, + 102, 496, 114, 114, 109, 187, 606, 117, 117, 98, + 10, 442, 2, 646, 305, 119, 119, 280, 280, 280, + 255, 262, 264, 292, 573, 298, 652, 575, 734, 439, + 207, 10, 266, 199, 567, 1, 506, 367, 374, 620, + 624, 320, 269, 328, 331, 268, 283, 817, 522, 380, + 384, 531, 488, 492, 241, 241, 241, 102, 725, 561, + 114, 108, 99, 812, 186, 815, 313, 321, 296, 238, + 251, 252, 307, 307, 359, 13, 307, 576, 536, 10, + 13, 590, 591, 346, 347, 567, 303, 10, 350, 589, + 477, 480, 200, 200, 485, 445, 487, 200, 200, 200, + 588, 720, 342, 304, 306, 13, 274, 274, 434, 437, + 319, 510, 341, 517, 475, 310, 738, 311, 739, 307, + 307, 307, 307, 636, 847, 641, 13, 200, 200, 750, + 515, 200, 200, 377, 516, 200, 316, 326, 326, 666, + 817, 819, 698, 702, 426, 448, 449, 629, 308, 309, + 844, 610, 312, 737, 729, 352, 344, 652, 874, 345, + 348, 530, 349, 358, 668, 298, 673, 753, 10, 10, + 811, 813, nil, nil, 13, 440, nil, nil, 200, 200, + 200, 200, 13, 625, nil, nil, 10, nil, 756, 758, + 759, 388, nil, nil, nil, 354, 355, 356, 357, nil, + 364, 365, 366, 372, 375, nil, nil, nil, 389, 708, + nil, nil, nil, 391, 392, nil, 242, 242, 269, 639, + nil, nil, 370, 370, nil, 242, nil, 280, 444, 240, + nil, 244, 244, 676, nil, nil, nil, 240, nil, nil, + 244, nil, nil, nil, 259, 14, 263, 10, 380, 384, + 14, nil, 10, nil, nil, nil, nil, nil, nil, nil, + 462, nil, nil, 13, 13, 200, 200, 200, 200, 266, + nil, 200, 200, 200, 266, 14, 276, 276, nil, 269, + 476, 13, 452, 884, 269, 456, nil, 457, 443, 241, + nil, nil, 806, nil, nil, nil, 14, 241, nil, nil, + nil, 573, 575, 441, 446, nil, 318, 327, 327, 102, + 567, nil, 450, nil, nil, 601, 854, nil, 495, 687, + 611, 567, nil, 690, 601, 511, 307, 307, nil, 652, + nil, 200, 200, nil, nil, 556, nil, 713, nil, 845, + 200, nil, 13, nil, 14, 514, 274, 13, nil, 550, + 851, 852, 14, nil, 853, 114, 601, 535, nil, 520, + 117, 429, 601, nil, nil, nil, nil, 298, 119, nil, + nil, nil, nil, 743, 545, nil, nil, nil, 549, nil, + nil, nil, nil, nil, nil, 200, 200, nil, 563, nil, + 388, 607, 612, nil, nil, nil, nil, nil, 595, nil, + nil, nil, 493, 494, 200, nil, nil, 585, nil, nil, + nil, nil, nil, 886, nil, nil, nil, nil, 200, nil, + nil, nil, 587, 578, 579, nil, nil, nil, 572, nil, + 298, 574, nil, 14, 14, 711, 712, nil, nil, 631, + nil, 567, nil, nil, nil, nil, nil, nil, 640, nil, + nil, 14, nil, nil, 645, nil, 388, 613, nil, nil, + nil, nil, nil, 296, 616, 388, nil, nil, 10, nil, + 200, 298, 10, 796, nil, nil, nil, 10, nil, nil, + 298, nil, nil, nil, nil, nil, 567, 605, nil, nil, + 621, 621, nil, 846, nil, 10, nil, 388, nil, nil, + 617, nil, 667, 388, 619, 370, nil, nil, nil, 627, + 643, 644, 14, nil, 697, 280, 276, 14, nil, nil, + nil, nil, 200, nil, nil, 727, 871, nil, 307, 731, + 628, nil, 114, 200, 678, nil, 607, 117, 607, nil, + nil, 10, 563, nil, 840, 119, 200, nil, nil, nil, + 569, nil, nil, nil, 714, 683, 685, nil, nil, nil, + 688, nil, nil, 13, nil, nil, 550, 13, nil, nil, + 10, 10, 13, 703, 200, nil, nil, nil, nil, nil, + 748, nil, nil, 200, nil, 752, nil, 200, 10, nil, + 13, 764, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 721, 722, 642, nil, nil, nil, nil, nil, + 35, nil, nil, nil, nil, 35, nil, nil, 200, 200, + 728, 10, nil, 200, nil, nil, 10, nil, nil, nil, + nil, nil, nil, nil, 274, nil, 13, nil, nil, 749, + 35, 273, 273, nil, nil, 754, nil, nil, nil, nil, + nil, nil, 307, 10, nil, 280, 280, 200, nil, nil, + nil, 35, 114, nil, nil, 13, 13, nil, nil, nil, + nil, 315, 330, 330, 330, 789, nil, nil, nil, 776, + 778, 601, 705, 13, nil, 766, 280, nil, 10, 808, + 787, nil, nil, nil, 768, 785, nil, nil, nil, nil, + nil, nil, nil, nil, 716, nil, 10, nil, nil, 35, + 797, 200, nil, nil, nil, 798, 13, 35, 10, 10, + 784, 13, nil, 10, 607, nil, 821, 280, 746, nil, + 10, nil, nil, 14, nil, 810, nil, 14, 795, nil, + nil, nil, 14, 621, nil, nil, nil, 786, 13, nil, + 802, 803, 307, nil, nil, 805, nil, 200, nil, nil, + 14, nil, nil, nil, 858, nil, nil, nil, nil, 672, + nil, nil, nil, nil, 773, 773, 10, nil, 280, 280, + nil, nil, nil, 13, nil, 280, nil, nil, nil, nil, + nil, 607, nil, 875, 867, nil, 298, nil, 35, 35, + nil, 13, 855, 856, 276, 773, 14, nil, 839, 864, + nil, 200, nil, 13, 13, nil, 35, nil, 13, 280, + 10, nil, 388, 781, nil, 13, 783, 10, 800, nil, + nil, nil, nil, 280, 10, 14, 14, 791, nil, nil, + nil, nil, nil, 879, 280, nil, 274, nil, nil, nil, + nil, nil, 872, 14, nil, nil, nil, 889, nil, 873, + nil, nil, nil, nil, nil, nil, nil, nil, 893, nil, + nil, 13, nil, nil, nil, nil, nil, 35, nil, nil, + nil, 273, 35, nil, nil, nil, 14, nil, nil, nil, + nil, 14, nil, nil, nil, nil, nil, 773, 773, 200, + nil, nil, nil, nil, 773, 833, nil, nil, 836, nil, + nil, nil, nil, nil, nil, 13, nil, nil, 14, nil, + nil, nil, 13, nil, nil, nil, nil, nil, nil, 13, + nil, nil, nil, nil, nil, nil, nil, nil, 773, nil, + nil, nil, nil, nil, 775, 775, nil, nil, nil, 865, + nil, nil, 773, 14, 868, nil, nil, 870, nil, nil, + nil, nil, nil, 773, nil, nil, nil, nil, nil, nil, + nil, 14, nil, nil, nil, 775, nil, nil, nil, nil, + nil, nil, nil, 14, 14, nil, 881, nil, 14, nil, + nil, nil, nil, nil, nil, 14, nil, nil, nil, 890, + nil, nil, 892, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 895, nil, nil, 276, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 208, nil, nil, nil, 239, 239, 239, nil, nil, nil, + nil, 14, nil, nil, nil, nil, nil, nil, nil, nil, + 289, 290, 291, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 239, 239, 775, 775, nil, + nil, nil, nil, nil, 775, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 12, 14, nil, nil, nil, 12, + nil, nil, 14, nil, nil, nil, nil, nil, 35, 14, + nil, nil, 35, nil, nil, nil, nil, 35, 775, nil, + nil, nil, nil, nil, 12, nil, nil, nil, nil, nil, + nil, nil, 775, nil, nil, 35, nil, nil, nil, nil, + nil, nil, nil, 775, nil, 12, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 273, + nil, 35, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 12, nil, nil, nil, nil, nil, nil, + nil, 12, nil, nil, nil, nil, nil, nil, nil, nil, + 35, 35, 368, 239, 376, 239, nil, nil, 390, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 35, nil, + nil, 208, 400, 401, 402, 403, 404, 405, 406, 407, + 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, + 418, 419, 420, 421, 422, 423, 424, 425, nil, nil, + nil, 35, nil, nil, nil, 239, 35, 239, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 239, 239, + nil, nil, 12, 12, nil, nil, nil, 239, nil, nil, + nil, nil, nil, 35, nil, nil, nil, nil, nil, nil, + 12, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 470, nil, nil, nil, nil, 772, + 772, nil, nil, 482, nil, nil, nil, nil, 35, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 35, nil, nil, nil, + 772, nil, nil, nil, nil, nil, nil, nil, 35, 35, + nil, 12, nil, 35, nil, nil, 12, nil, nil, nil, + 35, nil, nil, 369, 373, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 273, nil, 239, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 35, 239, nil, 390, + 557, 376, nil, nil, nil, nil, 431, nil, 432, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 772, 772, nil, nil, nil, nil, nil, 772, + 239, nil, 239, nil, nil, 239, nil, nil, nil, nil, + 35, nil, nil, nil, nil, nil, nil, 35, nil, 583, + nil, nil, nil, nil, 35, nil, nil, nil, nil, nil, + 239, nil, nil, 772, nil, nil, nil, 602, 603, 604, + nil, nil, nil, nil, nil, 239, nil, 772, nil, nil, + 239, nil, nil, 239, nil, nil, 239, nil, 772, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 239, 239, nil, nil, nil, nil, nil, nil, nil, nil, + 239, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 541, nil, nil, nil, nil, nil, + nil, 679, 239, nil, nil, 684, 686, nil, nil, nil, + 689, nil, nil, 691, nil, nil, nil, nil, nil, nil, + 696, nil, 12, nil, 239, nil, 12, nil, 239, nil, + nil, 12, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 239, nil, nil, nil, 239, 12, + nil, 565, nil, 568, nil, nil, 571, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 584, nil, nil, nil, nil, nil, 733, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 239, nil, nil, 12, 609, nil, nil, nil, + nil, 615, nil, nil, 568, nil, nil, 615, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 369, nil, nil, 12, 12, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 12, 239, 769, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 684, 686, 689, nil, nil, nil, + nil, nil, nil, 680, nil, nil, nil, nil, 239, nil, + nil, nil, nil, nil, nil, 12, nil, 239, nil, 239, + 12, nil, nil, nil, nil, 704, nil, nil, nil, 707, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 239, 565, nil, 12, nil, 718, + nil, 26, nil, nil, nil, nil, 26, nil, nil, nil, + nil, nil, nil, 239, nil, nil, nil, nil, 26, 26, + nil, nil, 769, 26, 26, 26, nil, nil, nil, nil, + nil, 26, 12, nil, 830, nil, nil, nil, nil, nil, + 239, nil, 239, 744, nil, nil, nil, nil, nil, nil, + 12, nil, 26, 26, 26, nil, 239, 26, 26, nil, + nil, 26, 12, 12, nil, nil, nil, 12, nil, nil, + nil, nil, nil, nil, 12, nil, 239, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 239, nil, nil, 239, + nil, nil, nil, nil, 767, nil, nil, nil, nil, nil, + 26, nil, nil, nil, 26, 26, 26, 26, 26, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 239, 568, + 12, 239, nil, nil, nil, nil, nil, nil, nil, nil, + 568, nil, nil, nil, 239, nil, nil, nil, nil, nil, + nil, nil, nil, 239, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 615, nil, nil, nil, nil, + nil, nil, nil, nil, 12, nil, nil, nil, nil, nil, + nil, 12, nil, nil, 818, nil, nil, nil, 12, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 26, + 26, 26, 26, 26, 26, nil, nil, 26, 26, 26, + nil, 835, nil, 838, nil, nil, nil, 26, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 843, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 565, nil, nil, + 568, nil, nil, nil, nil, nil, nil, 26, 26, nil, + nil, nil, nil, nil, nil, nil, 26, nil, 26, nil, + nil, nil, nil, 26, nil, nil, nil, nil, nil, 880, + nil, nil, 883, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 568, nil, nil, nil, nil, + nil, nil, nil, nil, 894, nil, nil, nil, nil, nil, + nil, 26, 26, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 26, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 26, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 26, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 26, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 26, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 26, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 26, + nil, nil, nil, 26, nil, nil, nil, nil, 26, nil, + 26, nil, nil, nil, nil, nil, nil, nil, nil, 26, + nil, nil, nil, 26, nil, nil, 26, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 26, 26, nil, nil, nil, 26, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 26, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 26, nil, nil, nil, nil, nil, nil, + nil, 26, 26, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 26, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 26, nil, nil, + nil, nil, 26, nil, nil, nil, nil, 26, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 26, nil, nil, nil, nil, nil, + nil, nil, nil, 26, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 26, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 26, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 26, nil, 26, + 26, nil, nil, nil, 26, nil, nil, nil, nil, nil, + nil, 26, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 26, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 26, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 26, nil, nil, nil, nil, nil, nil, 26, nil, + nil, nil, nil, nil, nil, 26 ] + +racc_goto_check = [ + 14, 4, 56, 56, 56, 14, 39, 52, 52, 44, + 3, 57, 57, 19, 26, 26, 26, 60, 60, 60, + 83, 79, 45, 45, 11, 11, 5, 48, 48, 8, + 14, 29, 2, 85, 56, 49, 49, 52, 52, 52, + 31, 31, 31, 51, 58, 26, 128, 58, 77, 32, + 15, 14, 36, 23, 133, 1, 42, 21, 21, 78, + 78, 14, 2, 43, 43, 37, 40, 130, 119, 30, + 30, 119, 76, 76, 54, 54, 54, 83, 6, 33, + 45, 9, 10, 126, 12, 126, 8, 16, 23, 28, + 28, 28, 23, 23, 24, 18, 23, 34, 50, 14, + 18, 33, 33, 116, 116, 133, 54, 14, 116, 61, + 55, 55, 18, 18, 55, 62, 55, 18, 18, 18, + 64, 65, 72, 73, 74, 18, 18, 18, 30, 30, + 80, 82, 86, 87, 88, 89, 90, 91, 92, 23, + 23, 23, 23, 93, 94, 95, 18, 18, 18, 96, + 97, 18, 18, 19, 98, 18, 18, 18, 18, 99, + 130, 100, 101, 102, 104, 106, 107, 108, 13, 13, + 109, 110, 13, 5, 111, 9, 114, 128, 126, 115, + 117, 118, 120, 9, 121, 26, 122, 123, 14, 14, + 125, 129, nil, nil, 18, 53, nil, nil, 18, 18, + 18, 18, 18, 79, nil, nil, 14, nil, 127, 127, + 127, 45, nil, nil, nil, 13, 13, 13, 13, nil, + 2, 2, 15, 15, 15, nil, nil, nil, 15, 33, + nil, nil, nil, 23, 23, nil, 56, 56, 2, 42, + nil, nil, 54, 54, nil, 56, nil, 52, 26, 26, + nil, 60, 60, 119, nil, nil, nil, 26, nil, nil, + 60, nil, nil, nil, 57, 20, 57, 14, 30, 30, + 20, nil, 14, nil, nil, nil, nil, nil, nil, nil, + 51, nil, nil, 18, 18, 18, 18, 18, 18, 36, + nil, 18, 18, 18, 36, 20, 20, 20, nil, 2, + 51, 18, 37, 77, 2, 40, nil, 37, 54, 54, + nil, nil, 78, nil, nil, nil, 20, 54, nil, nil, + nil, 58, 58, 28, 28, nil, 20, 20, 20, 83, + 133, nil, 28, nil, nil, 30, 85, nil, 8, 32, + 21, 133, nil, 32, 30, 83, 23, 23, nil, 128, + nil, 18, 18, nil, nil, 19, nil, 29, nil, 5, + 18, nil, 18, nil, 20, 23, 18, 18, nil, 57, + 127, 127, 20, nil, 127, 45, 30, 11, nil, 23, + 48, 59, 30, nil, nil, nil, nil, 26, 49, nil, + nil, nil, nil, 76, 31, nil, nil, nil, 31, nil, + nil, nil, nil, nil, nil, 18, 18, nil, 56, nil, + 45, 53, 53, nil, nil, nil, nil, nil, 19, nil, + nil, nil, 13, 13, 18, nil, nil, 56, nil, nil, + nil, nil, nil, 127, nil, nil, nil, nil, 18, nil, + nil, nil, 60, 51, 51, nil, nil, nil, 31, nil, + 26, 31, nil, 20, 20, 30, 30, nil, nil, 19, + nil, 133, nil, nil, nil, nil, nil, nil, 19, nil, + nil, 20, nil, nil, 3, nil, 45, 51, nil, nil, + nil, nil, nil, 23, 51, 45, nil, nil, 14, nil, + 18, 26, 14, 76, nil, nil, nil, 14, nil, nil, + 26, nil, nil, nil, nil, nil, 133, 23, nil, nil, + 83, 83, nil, 79, nil, 14, nil, 45, nil, nil, + 2, nil, 51, 45, 2, 54, nil, nil, nil, 2, + 83, 83, 20, nil, 39, 52, 20, 20, nil, nil, + nil, nil, 18, nil, nil, 53, 4, nil, 23, 53, + 54, nil, 45, 18, 11, nil, 53, 48, 53, nil, + nil, 14, 56, nil, 76, 49, 18, nil, nil, nil, + 59, nil, nil, nil, 26, 15, 15, nil, nil, nil, + 15, nil, nil, 18, nil, nil, 57, 18, nil, nil, + 14, 14, 18, 2, 18, nil, nil, nil, nil, nil, + 3, nil, nil, 18, nil, 3, nil, 18, 14, nil, + 18, 44, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 2, 2, 13, nil, nil, nil, nil, nil, + 41, nil, nil, nil, nil, 41, nil, nil, 18, 18, + 2, 14, nil, 18, nil, nil, 14, nil, nil, nil, + nil, nil, nil, nil, 18, nil, 18, nil, nil, 83, + 41, 41, 41, nil, nil, 83, nil, nil, nil, nil, + nil, nil, 23, 14, nil, 52, 52, 18, nil, nil, + nil, 41, 45, nil, nil, 18, 18, nil, nil, nil, + nil, 41, 41, 41, 41, 56, nil, nil, nil, 14, + 14, 30, 59, 18, nil, 2, 52, nil, 14, 3, + 60, nil, nil, nil, 15, 51, nil, nil, nil, nil, + nil, nil, nil, nil, 59, nil, 14, nil, nil, 41, + 14, 18, nil, nil, nil, 51, 18, 41, 14, 14, + 2, 18, nil, 14, 53, nil, 39, 52, 13, nil, + 14, nil, nil, 20, nil, 51, nil, 20, 2, nil, + nil, nil, 20, 83, nil, nil, nil, 54, 18, nil, + 2, 2, 23, nil, nil, 2, nil, 18, nil, nil, + 20, nil, nil, nil, 19, nil, nil, nil, nil, 20, + nil, nil, nil, nil, 18, 18, 14, nil, 52, 52, + nil, nil, nil, 18, nil, 52, nil, nil, nil, nil, + nil, 53, nil, 3, 56, nil, 26, nil, 41, 41, + nil, 18, 14, 14, 20, 18, 20, nil, 2, 14, + nil, 18, nil, 18, 18, nil, 41, nil, 18, 52, + 14, nil, 45, 59, nil, 18, 59, 14, 13, nil, + nil, nil, nil, 52, 14, 20, 20, 59, nil, nil, + nil, nil, nil, 14, 52, nil, 18, nil, nil, nil, + nil, nil, 2, 20, nil, nil, nil, 14, nil, 2, + nil, nil, nil, nil, nil, nil, nil, nil, 14, nil, + nil, 18, nil, nil, nil, nil, nil, 41, nil, nil, + nil, 41, 41, nil, nil, nil, 20, nil, nil, nil, + nil, 20, nil, nil, nil, nil, nil, 18, 18, 18, + nil, nil, nil, nil, 18, 59, nil, nil, 59, nil, + nil, nil, nil, nil, nil, 18, nil, nil, 20, nil, + nil, nil, 18, nil, nil, nil, nil, nil, nil, 18, + nil, nil, nil, nil, nil, nil, nil, nil, 18, nil, + nil, nil, nil, nil, 20, 20, nil, nil, nil, 59, + nil, nil, 18, 20, 59, nil, nil, 59, nil, nil, + nil, nil, nil, 18, nil, nil, nil, nil, nil, nil, + nil, 20, nil, nil, nil, 20, nil, nil, nil, nil, + nil, nil, nil, 20, 20, nil, 59, nil, 20, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, 59, + nil, nil, 59, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 59, nil, nil, 20, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 25, nil, nil, nil, 25, 25, 25, nil, nil, nil, + nil, 20, nil, nil, nil, nil, nil, nil, nil, nil, + 25, 25, 25, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 25, 25, 20, 20, nil, + nil, nil, nil, nil, 20, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 17, 20, nil, nil, nil, 17, + nil, nil, 20, nil, nil, nil, nil, nil, 41, 20, + nil, nil, 41, nil, nil, nil, nil, 41, 20, nil, + nil, nil, nil, nil, 17, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, 41, nil, nil, nil, nil, + nil, nil, nil, 20, nil, 17, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 17, nil, nil, nil, nil, nil, nil, + nil, 17, nil, nil, nil, nil, nil, nil, nil, nil, + 41, 41, 25, 25, 25, 25, nil, nil, 25, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 41, nil, + nil, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, nil, nil, + nil, 41, nil, nil, nil, 25, 41, 25, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 25, 25, + nil, nil, 17, 17, nil, nil, nil, 25, nil, nil, + nil, nil, nil, 41, nil, nil, nil, nil, nil, nil, + 17, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 25, nil, nil, nil, nil, 41, + 41, nil, nil, 25, nil, nil, nil, nil, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 41, nil, nil, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 41, 41, + nil, 17, nil, 41, nil, nil, 17, nil, nil, nil, + 41, nil, nil, 22, 22, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 41, nil, 25, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 41, 25, nil, 25, + 25, 25, nil, nil, nil, nil, 22, nil, 22, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 41, 41, nil, nil, nil, nil, nil, 41, + 25, nil, 25, nil, nil, 25, nil, nil, nil, nil, + 41, nil, nil, nil, nil, nil, nil, 41, nil, 25, + nil, nil, nil, nil, 41, nil, nil, nil, nil, nil, + 25, nil, nil, 41, nil, nil, nil, 25, 25, 25, + nil, nil, nil, nil, nil, 25, nil, 41, nil, nil, + 25, nil, nil, 25, nil, nil, 25, nil, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 25, 25, nil, nil, nil, nil, nil, nil, nil, nil, + 25, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 22, nil, nil, nil, nil, nil, + nil, 25, 25, nil, nil, 25, 25, nil, nil, nil, + 25, nil, nil, 25, nil, nil, nil, nil, nil, nil, + 25, nil, 17, nil, 25, nil, 17, nil, 25, nil, + nil, 17, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 25, nil, nil, nil, 25, 17, + nil, 22, nil, 22, nil, nil, 22, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 22, nil, nil, nil, nil, nil, 25, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 25, nil, nil, 17, 22, nil, nil, nil, + nil, 22, nil, nil, 22, nil, nil, 22, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 22, nil, nil, 17, 17, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 17, 25, 25, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 25, 25, 25, nil, nil, nil, + nil, nil, nil, 22, nil, nil, nil, nil, 25, nil, + nil, nil, nil, nil, nil, 17, nil, 25, nil, 25, + 17, nil, nil, nil, nil, 22, nil, nil, nil, 22, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 25, 22, nil, 17, nil, 22, + nil, 35, nil, nil, nil, nil, 35, nil, nil, nil, + nil, nil, nil, 25, nil, nil, nil, nil, 35, 35, + nil, nil, 25, 35, 35, 35, nil, nil, nil, nil, + nil, 35, 17, nil, 25, nil, nil, nil, nil, nil, + 25, nil, 25, 22, nil, nil, nil, nil, nil, nil, + 17, nil, 35, 35, 35, nil, 25, 35, 35, nil, + nil, 35, 17, 17, nil, nil, nil, 17, nil, nil, + nil, nil, nil, nil, 17, nil, 25, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 25, nil, nil, 25, + nil, nil, nil, nil, 22, nil, nil, nil, nil, nil, + 35, nil, nil, nil, 35, 35, 35, 35, 35, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 25, 22, + 17, 25, nil, nil, nil, nil, nil, nil, nil, nil, + 22, nil, nil, nil, 25, nil, nil, nil, nil, nil, + nil, nil, nil, 25, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 22, nil, nil, nil, nil, + nil, nil, nil, nil, 17, nil, nil, nil, nil, nil, + nil, 17, nil, nil, 22, nil, nil, nil, 17, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 35, + 35, 35, 35, 35, 35, nil, nil, 35, 35, 35, + nil, 22, nil, 22, nil, nil, nil, 35, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 22, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 22, nil, nil, + 22, nil, nil, nil, nil, nil, nil, 35, 35, nil, + nil, nil, nil, nil, nil, nil, 35, nil, 35, nil, + nil, nil, nil, 35, nil, nil, nil, nil, nil, 22, + nil, nil, 22, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 22, nil, nil, nil, nil, + nil, nil, nil, nil, 22, nil, nil, nil, nil, nil, + nil, 35, 35, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 35, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 35, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 35, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 35, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 35, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 35, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 35, + nil, nil, nil, 35, nil, nil, nil, nil, 35, nil, + 35, nil, nil, nil, nil, nil, nil, nil, nil, 35, + nil, nil, nil, 35, nil, nil, 35, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 35, 35, nil, nil, nil, 35, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 35, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 35, nil, nil, nil, nil, nil, nil, + nil, 35, 35, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 35, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 35, nil, nil, + nil, nil, 35, nil, nil, nil, nil, 35, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 35, nil, nil, nil, nil, nil, + nil, nil, nil, 35, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 35, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 35, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 35, nil, 35, + 35, nil, nil, nil, 35, nil, nil, nil, nil, nil, + nil, 35, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 35, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 35, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 35, nil, nil, nil, nil, nil, nil, 35, nil, + nil, nil, nil, nil, nil, 35 ] + +racc_goto_pointer = [ + nil, 55, 32, -41, -293, -446, -528, nil, 26, 76, + 79, 18, 77, 112, 0, 32, 26, 1104, 95, -40, + 265, -133, 1193, 36, -15, 1032, -8, nil, 67, -225, + -125, 14, -206, -347, -341, 1781, 22, 35, nil, -25, + 34, 630, -268, 1, -55, 16, nil, nil, 21, 29, + -265, 2, -24, -61, 52, -189, -20, -15, -390, 139, + -5, -338, -142, nil, -327, -468, nil, nil, nil, nil, + nil, nil, 58, 69, 69, nil, -236, -569, -434, -292, + 69, nil, -197, 17, nil, -483, 68, -208, -162, 77, + -484, 78, -486, -360, -662, -365, -495, -181, -186, -358, + -603, -397, -396, nil, -72, nil, -95, -95, -331, -635, + -302, -436, nil, nil, 104, 105, 27, 102, -167, -277, + 103, -340, -339, -460, nil, -565, -672, -441, -470, -564, + -690, nil, nil, -376 ] + +racc_goto_default = [ + nil, nil, 294, nil, nil, 735, nil, 3, nil, 4, + 314, nil, nil, nil, 204, 16, 11, 205, 288, nil, + 203, nil, 246, 15, nil, 19, 20, 21, nil, 25, + 598, nil, nil, nil, nil, 279, 29, nil, 31, 34, + 33, 201, 325, nil, 116, 382, 115, 118, 70, 71, + nil, nil, 42, 297, 299, nil, 300, 546, 547, 427, + 564, nil, nil, 257, nil, nil, 43, 44, 45, 46, + 47, 48, 49, nil, 258, 55, nil, nil, nil, nil, + nil, 62, nil, 489, 63, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 237, nil, 386, nil, nil, nil, nil, + nil, nil, 69, 72, 73, nil, nil, nil, nil, 527, + nil, nil, nil, 648, 649, 650, 651, nil, 814, 658, + 659, 662, 665, 250 ] + +racc_reduce_table = [ + 0, 0, :racc_error, + 1, 132, :_reduce_1, + 4, 134, :_reduce_2, + 2, 133, :_reduce_3, + 0, 138, :_reduce_4, + 1, 138, :_reduce_5, + 2, 138, :_reduce_6, + 3, 138, :_reduce_7, + 0, 155, :_reduce_8, + 4, 140, :_reduce_9, + 3, 140, :_reduce_10, + 3, 140, :_reduce_11, + 3, 140, :_reduce_12, + 2, 140, :_reduce_13, + 3, 140, :_reduce_14, + 3, 140, :_reduce_15, + 3, 140, :_reduce_16, + 3, 140, :_reduce_17, + 3, 140, :_reduce_18, + 4, 140, :_reduce_19, + 4, 140, :_reduce_20, + 3, 140, :_reduce_21, + 3, 140, :_reduce_22, + 3, 140, :_reduce_23, + 6, 140, :_reduce_24, + 5, 140, :_reduce_25, + 5, 140, :_reduce_26, + 5, 140, :_reduce_27, + 3, 140, :_reduce_28, + 3, 140, :_reduce_29, + 3, 140, :_reduce_30, + 3, 140, :_reduce_31, + 1, 140, :_reduce_none, + 1, 154, :_reduce_none, + 3, 154, :_reduce_34, + 3, 154, :_reduce_35, + 2, 154, :_reduce_36, + 2, 154, :_reduce_37, + 1, 154, :_reduce_none, + 1, 144, :_reduce_none, + 1, 146, :_reduce_none, + 1, 146, :_reduce_none, + 2, 146, :_reduce_42, + 2, 146, :_reduce_43, + 2, 146, :_reduce_44, + 1, 158, :_reduce_none, + 4, 158, :_reduce_46, + 4, 158, :_reduce_47, + 0, 165, :_reduce_48, + 5, 163, :_reduce_49, + 2, 157, :_reduce_50, + 3, 157, :_reduce_51, + 4, 157, :_reduce_52, + 5, 157, :_reduce_53, + 4, 157, :_reduce_54, + 5, 157, :_reduce_55, + 2, 157, :_reduce_56, + 2, 157, :_reduce_57, + 1, 147, :_reduce_58, + 3, 147, :_reduce_59, + 1, 168, :_reduce_60, + 3, 168, :_reduce_61, + 1, 167, :_reduce_62, + 2, 167, :_reduce_63, + 3, 167, :_reduce_64, + 2, 167, :_reduce_65, + 2, 167, :_reduce_66, + 1, 167, :_reduce_67, + 1, 170, :_reduce_none, + 3, 170, :_reduce_69, + 2, 169, :_reduce_70, + 3, 169, :_reduce_71, + 1, 171, :_reduce_72, + 4, 171, :_reduce_73, + 3, 171, :_reduce_74, + 3, 171, :_reduce_75, + 3, 171, :_reduce_76, + 3, 171, :_reduce_77, + 2, 171, :_reduce_78, + 1, 171, :_reduce_79, + 1, 145, :_reduce_80, + 4, 145, :_reduce_81, + 3, 145, :_reduce_82, + 3, 145, :_reduce_83, + 3, 145, :_reduce_84, + 3, 145, :_reduce_85, + 2, 145, :_reduce_86, + 1, 145, :_reduce_87, + 1, 173, :_reduce_88, + 1, 173, :_reduce_none, + 2, 174, :_reduce_90, + 1, 174, :_reduce_91, + 3, 174, :_reduce_92, + 1, 175, :_reduce_none, + 1, 175, :_reduce_none, + 1, 175, :_reduce_none, + 1, 175, :_reduce_none, + 1, 175, :_reduce_none, + 1, 178, :_reduce_98, + 1, 178, :_reduce_none, + 1, 142, :_reduce_none, + 1, 142, :_reduce_none, + 1, 143, :_reduce_102, + 0, 181, :_reduce_103, + 4, 143, :_reduce_104, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 3, 156, :_reduce_171, + 5, 156, :_reduce_172, + 3, 156, :_reduce_173, + 6, 156, :_reduce_174, + 5, 156, :_reduce_175, + 5, 156, :_reduce_176, + 5, 156, :_reduce_177, + 5, 156, :_reduce_178, + 4, 156, :_reduce_179, + 3, 156, :_reduce_180, + 3, 156, :_reduce_181, + 3, 156, :_reduce_182, + 3, 156, :_reduce_183, + 3, 156, :_reduce_184, + 3, 156, :_reduce_185, + 3, 156, :_reduce_186, + 3, 156, :_reduce_187, + 3, 156, :_reduce_188, + 4, 156, :_reduce_189, + 4, 156, :_reduce_190, + 2, 156, :_reduce_191, + 2, 156, :_reduce_192, + 3, 156, :_reduce_193, + 3, 156, :_reduce_194, + 3, 156, :_reduce_195, + 3, 156, :_reduce_196, + 3, 156, :_reduce_197, + 3, 156, :_reduce_198, + 3, 156, :_reduce_199, + 3, 156, :_reduce_200, + 3, 156, :_reduce_201, + 3, 156, :_reduce_202, + 3, 156, :_reduce_203, + 3, 156, :_reduce_204, + 3, 156, :_reduce_205, + 2, 156, :_reduce_206, + 2, 156, :_reduce_207, + 3, 156, :_reduce_208, + 3, 156, :_reduce_209, + 3, 156, :_reduce_210, + 3, 156, :_reduce_211, + 3, 156, :_reduce_212, + 5, 156, :_reduce_213, + 1, 156, :_reduce_none, + 1, 153, :_reduce_none, + 1, 150, :_reduce_216, + 2, 150, :_reduce_217, + 2, 150, :_reduce_218, + 5, 150, :_reduce_219, + 2, 150, :_reduce_220, + 3, 150, :_reduce_221, + 3, 188, :_reduce_222, + 4, 188, :_reduce_223, + 4, 188, :_reduce_224, + 6, 188, :_reduce_225, + 0, 189, :_reduce_226, + 1, 189, :_reduce_none, + 1, 159, :_reduce_228, + 2, 159, :_reduce_229, + 5, 159, :_reduce_230, + 2, 159, :_reduce_231, + 5, 159, :_reduce_232, + 4, 159, :_reduce_233, + 7, 159, :_reduce_234, + 3, 159, :_reduce_235, + 1, 159, :_reduce_236, + 4, 192, :_reduce_237, + 3, 192, :_reduce_238, + 5, 192, :_reduce_239, + 7, 192, :_reduce_240, + 2, 192, :_reduce_241, + 5, 192, :_reduce_242, + 4, 192, :_reduce_243, + 6, 192, :_reduce_244, + 7, 192, :_reduce_245, + 9, 192, :_reduce_246, + 3, 192, :_reduce_247, + 1, 192, :_reduce_248, + 0, 194, :_reduce_249, + 2, 162, :_reduce_250, + 1, 193, :_reduce_251, + 0, 195, :_reduce_252, + 3, 193, :_reduce_253, + 0, 196, :_reduce_254, + 4, 193, :_reduce_255, + 2, 191, :_reduce_256, + 2, 190, :_reduce_257, + 0, 190, :_reduce_258, + 1, 185, :_reduce_259, + 3, 185, :_reduce_260, + 3, 152, :_reduce_261, + 4, 152, :_reduce_262, + 2, 152, :_reduce_263, + 1, 183, :_reduce_none, + 1, 183, :_reduce_none, + 1, 183, :_reduce_none, + 1, 183, :_reduce_none, + 1, 183, :_reduce_none, + 1, 183, :_reduce_none, + 1, 183, :_reduce_none, + 1, 183, :_reduce_none, + 1, 183, :_reduce_272, + 3, 183, :_reduce_273, + 0, 219, :_reduce_274, + 5, 183, :_reduce_275, + 3, 183, :_reduce_276, + 3, 183, :_reduce_277, + 2, 183, :_reduce_278, + 4, 183, :_reduce_279, + 3, 183, :_reduce_280, + 3, 183, :_reduce_281, + 1, 183, :_reduce_282, + 4, 183, :_reduce_283, + 3, 183, :_reduce_284, + 1, 183, :_reduce_285, + 5, 183, :_reduce_286, + 2, 183, :_reduce_287, + 1, 183, :_reduce_none, + 2, 183, :_reduce_289, + 6, 183, :_reduce_290, + 6, 183, :_reduce_291, + 0, 220, :_reduce_292, + 0, 221, :_reduce_293, + 7, 183, :_reduce_294, + 0, 222, :_reduce_295, + 0, 223, :_reduce_296, + 7, 183, :_reduce_297, + 5, 183, :_reduce_298, + 4, 183, :_reduce_299, + 5, 183, :_reduce_300, + 0, 224, :_reduce_301, + 0, 225, :_reduce_302, + 9, 183, :_reduce_303, + 0, 226, :_reduce_304, + 6, 183, :_reduce_305, + 0, 227, :_reduce_306, + 7, 183, :_reduce_307, + 0, 228, :_reduce_308, + 5, 183, :_reduce_309, + 0, 229, :_reduce_310, + 6, 183, :_reduce_311, + 0, 230, :_reduce_312, + 0, 231, :_reduce_313, + 9, 183, :_reduce_314, + 1, 183, :_reduce_315, + 1, 183, :_reduce_316, + 1, 183, :_reduce_317, + 1, 183, :_reduce_318, + 1, 149, :_reduce_none, + 1, 212, :_reduce_320, + 1, 215, :_reduce_321, + 1, 207, :_reduce_none, + 1, 207, :_reduce_none, + 1, 207, :_reduce_none, + 2, 207, :_reduce_325, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 208, :_reduce_none, + 5, 208, :_reduce_330, + 1, 136, :_reduce_none, + 2, 136, :_reduce_332, + 1, 211, :_reduce_none, + 1, 211, :_reduce_none, + 1, 232, :_reduce_335, + 3, 232, :_reduce_336, + 1, 233, :_reduce_none, + 2, 233, :_reduce_none, + 4, 233, :_reduce_339, + 7, 233, :_reduce_340, + 6, 233, :_reduce_341, + 4, 233, :_reduce_342, + 3, 233, :_reduce_343, + 5, 233, :_reduce_344, + 4, 233, :_reduce_345, + 2, 233, :_reduce_346, + 1, 233, :_reduce_347, + 2, 233, :_reduce_348, + 0, 164, :_reduce_349, + 2, 164, :_reduce_350, + 1, 164, :_reduce_351, + 3, 164, :_reduce_352, + 0, 235, :_reduce_353, + 5, 234, :_reduce_354, + 2, 160, :_reduce_355, + 4, 160, :_reduce_356, + 4, 160, :_reduce_357, + 2, 206, :_reduce_358, + 4, 206, :_reduce_359, + 4, 206, :_reduce_360, + 3, 206, :_reduce_361, + 2, 206, :_reduce_362, + 1, 206, :_reduce_363, + 0, 237, :_reduce_364, + 5, 205, :_reduce_365, + 0, 238, :_reduce_366, + 5, 205, :_reduce_367, + 5, 210, :_reduce_368, + 1, 239, :_reduce_none, + 4, 239, :_reduce_370, + 2, 239, :_reduce_371, + 1, 240, :_reduce_372, + 1, 240, :_reduce_none, + 6, 135, :_reduce_374, + 0, 135, :_reduce_375, + 1, 241, :_reduce_376, + 1, 241, :_reduce_none, + 1, 241, :_reduce_none, + 2, 242, :_reduce_379, + 1, 242, :_reduce_none, + 2, 137, :_reduce_381, + 1, 137, :_reduce_none, + 1, 197, :_reduce_none, + 1, 197, :_reduce_none, + 1, 197, :_reduce_none, + 1, 198, :_reduce_386, + 1, 244, :_reduce_387, + 2, 244, :_reduce_388, + 3, 245, :_reduce_389, + 1, 245, :_reduce_390, + 3, 199, :_reduce_391, + 4, 200, :_reduce_392, + 3, 201, :_reduce_393, + 0, 248, :_reduce_394, + 3, 248, :_reduce_395, + 1, 249, :_reduce_396, + 2, 249, :_reduce_397, + 3, 202, :_reduce_398, + 0, 251, :_reduce_399, + 3, 251, :_reduce_400, + 0, 246, :_reduce_401, + 2, 246, :_reduce_402, + 0, 247, :_reduce_403, + 2, 247, :_reduce_404, + 1, 250, :_reduce_405, + 2, 250, :_reduce_406, + 0, 253, :_reduce_407, + 4, 250, :_reduce_408, + 1, 252, :_reduce_409, + 1, 252, :_reduce_410, + 1, 252, :_reduce_411, + 1, 252, :_reduce_none, + 1, 179, :_reduce_413, + 3, 180, :_reduce_414, + 1, 243, :_reduce_415, + 1, 243, :_reduce_416, + 2, 243, :_reduce_417, + 2, 243, :_reduce_418, + 1, 172, :_reduce_419, + 1, 172, :_reduce_420, + 1, 172, :_reduce_421, + 1, 172, :_reduce_422, + 1, 172, :_reduce_423, + 1, 172, :_reduce_424, + 1, 172, :_reduce_425, + 1, 172, :_reduce_426, + 1, 172, :_reduce_427, + 1, 172, :_reduce_428, + 1, 172, :_reduce_429, + 1, 203, :_reduce_430, + 1, 148, :_reduce_431, + 1, 151, :_reduce_432, + 1, 151, :_reduce_433, + 1, 213, :_reduce_434, + 3, 213, :_reduce_435, + 2, 213, :_reduce_436, + 4, 216, :_reduce_437, + 2, 216, :_reduce_438, + 6, 254, :_reduce_439, + 4, 254, :_reduce_440, + 4, 254, :_reduce_441, + 2, 254, :_reduce_442, + 4, 254, :_reduce_443, + 2, 254, :_reduce_444, + 2, 254, :_reduce_445, + 1, 254, :_reduce_446, + 0, 254, :_reduce_447, + 1, 260, :_reduce_448, + 1, 260, :_reduce_449, + 1, 260, :_reduce_450, + 1, 260, :_reduce_451, + 1, 260, :_reduce_452, + 1, 255, :_reduce_453, + 3, 255, :_reduce_454, + 3, 261, :_reduce_455, + 1, 256, :_reduce_456, + 3, 256, :_reduce_457, + 1, 262, :_reduce_none, + 1, 262, :_reduce_none, + 2, 257, :_reduce_460, + 1, 257, :_reduce_461, + 1, 263, :_reduce_none, + 1, 263, :_reduce_none, + 2, 259, :_reduce_464, + 2, 258, :_reduce_465, + 0, 258, :_reduce_466, + 1, 217, :_reduce_none, + 4, 217, :_reduce_468, + 0, 204, :_reduce_469, + 2, 204, :_reduce_470, + 2, 204, :_reduce_471, + 1, 187, :_reduce_472, + 3, 187, :_reduce_473, + 3, 264, :_reduce_474, + 1, 166, :_reduce_none, + 1, 166, :_reduce_none, + 1, 166, :_reduce_none, + 1, 161, :_reduce_none, + 1, 161, :_reduce_none, + 1, 161, :_reduce_none, + 1, 161, :_reduce_none, + 1, 236, :_reduce_none, + 1, 236, :_reduce_none, + 1, 236, :_reduce_none, + 1, 218, :_reduce_none, + 1, 218, :_reduce_none, + 0, 139, :_reduce_none, + 1, 139, :_reduce_none, + 0, 182, :_reduce_none, + 1, 182, :_reduce_none, + 0, 186, :_reduce_none, + 1, 186, :_reduce_none, + 1, 186, :_reduce_none, + 1, 214, :_reduce_494, + 1, 214, :_reduce_none, + 1, 141, :_reduce_none, + 2, 141, :_reduce_none, + 0, 184, :_reduce_498 ] + +racc_reduce_n = 499 + +racc_shift_n = 896 + +racc_token_table = { + false => 0, + :error => 1, + :kCLASS => 2, + :kMODULE => 3, + :kDEF => 4, + :kUNDEF => 5, + :kBEGIN => 6, + :kRESCUE => 7, + :kENSURE => 8, + :kEND => 9, + :kIF => 10, + :kUNLESS => 11, + :kTHEN => 12, + :kELSIF => 13, + :kELSE => 14, + :kCASE => 15, + :kWHEN => 16, + :kWHILE => 17, + :kUNTIL => 18, + :kFOR => 19, + :kBREAK => 20, + :kNEXT => 21, + :kREDO => 22, + :kRETRY => 23, + :kIN => 24, + :kDO => 25, + :kDO_COND => 26, + :kDO_BLOCK => 27, + :kRETURN => 28, + :kYIELD => 29, + :kSUPER => 30, + :kSELF => 31, + :kNIL => 32, + :kTRUE => 33, + :kFALSE => 34, + :kAND => 35, + :kOR => 36, + :kNOT => 37, + :kIF_MOD => 38, + :kUNLESS_MOD => 39, + :kWHILE_MOD => 40, + :kUNTIL_MOD => 41, + :kRESCUE_MOD => 42, + :kALIAS => 43, + :kDEFINED => 44, + :klBEGIN => 45, + :klEND => 46, + :k__LINE__ => 47, + :k__FILE__ => 48, + :tIDENTIFIER => 49, + :tFID => 50, + :tGVAR => 51, + :tIVAR => 52, + :tCONSTANT => 53, + :tCVAR => 54, + :tNTH_REF => 55, + :tBACK_REF => 56, + :tSTRING_CONTENT => 57, + :tINTEGER => 58, + :tFLOAT => 59, + :tUPLUS => 60, + :tUMINUS => 61, + :tUNARY_NUM => 62, + :tPOW => 63, + :tCMP => 64, + :tEQ => 65, + :tEQQ => 66, + :tNEQ => 67, + :tGEQ => 68, + :tLEQ => 69, + :tANDOP => 70, + :tOROP => 71, + :tMATCH => 72, + :tNMATCH => 73, + :tDOT => 74, + :tDOT2 => 75, + :tDOT3 => 76, + :tAREF => 77, + :tASET => 78, + :tLSHFT => 79, + :tRSHFT => 80, + :tCOLON2 => 81, + :tCOLON3 => 82, + :tOP_ASGN => 83, + :tASSOC => 84, + :tLPAREN => 85, + :tLPAREN2 => 86, + :tRPAREN => 87, + :tLPAREN_ARG => 88, + :tLBRACK => 89, + :tLBRACK2 => 90, + :tRBRACK => 91, + :tLBRACE => 92, + :tLBRACE_ARG => 93, + :tSTAR => 94, + :tSTAR2 => 95, + :tAMPER => 96, + :tAMPER2 => 97, + :tTILDE => 98, + :tPERCENT => 99, + :tDIVIDE => 100, + :tPLUS => 101, + :tMINUS => 102, + :tLT => 103, + :tGT => 104, + :tPIPE => 105, + :tBANG => 106, + :tCARET => 107, + :tLCURLY => 108, + :tRCURLY => 109, + :tBACK_REF2 => 110, + :tSYMBEG => 111, + :tSTRING_BEG => 112, + :tXSTRING_BEG => 113, + :tREGEXP_BEG => 114, + :tWORDS_BEG => 115, + :tQWORDS_BEG => 116, + :tSTRING_DBEG => 117, + :tSTRING_DVAR => 118, + :tSTRING_END => 119, + :tSTRING => 120, + :tSYMBOL => 121, + :tREGEXP_OPT => 122, + :tNL => 123, + :tEH => 124, + :tCOLON => 125, + :tCOMMA => 126, + :tSPACE => 127, + :tSEMI => 128, + :tEQL => 129, + :tLOWEST => 130 } + +racc_nt_base = 131 + +racc_use_result_var = true + +Racc_arg = [ + racc_action_table, + racc_action_check, + racc_action_default, + racc_action_pointer, + racc_goto_table, + racc_goto_check, + racc_goto_default, + racc_goto_pointer, + racc_nt_base, + racc_reduce_table, + racc_token_table, + racc_shift_n, + racc_reduce_n, + racc_use_result_var ] +Ractor.make_shareable(Racc_arg) if defined?(Ractor) + +Racc_token_to_s_table = [ + "$end", + "error", + "kCLASS", + "kMODULE", + "kDEF", + "kUNDEF", + "kBEGIN", + "kRESCUE", + "kENSURE", + "kEND", + "kIF", + "kUNLESS", + "kTHEN", + "kELSIF", + "kELSE", + "kCASE", + "kWHEN", + "kWHILE", + "kUNTIL", + "kFOR", + "kBREAK", + "kNEXT", + "kREDO", + "kRETRY", + "kIN", + "kDO", + "kDO_COND", + "kDO_BLOCK", + "kRETURN", + "kYIELD", + "kSUPER", + "kSELF", + "kNIL", + "kTRUE", + "kFALSE", + "kAND", + "kOR", + "kNOT", + "kIF_MOD", + "kUNLESS_MOD", + "kWHILE_MOD", + "kUNTIL_MOD", + "kRESCUE_MOD", + "kALIAS", + "kDEFINED", + "klBEGIN", + "klEND", + "k__LINE__", + "k__FILE__", + "tIDENTIFIER", + "tFID", + "tGVAR", + "tIVAR", + "tCONSTANT", + "tCVAR", + "tNTH_REF", + "tBACK_REF", + "tSTRING_CONTENT", + "tINTEGER", + "tFLOAT", + "tUPLUS", + "tUMINUS", + "tUNARY_NUM", + "tPOW", + "tCMP", + "tEQ", + "tEQQ", + "tNEQ", + "tGEQ", + "tLEQ", + "tANDOP", + "tOROP", + "tMATCH", + "tNMATCH", + "tDOT", + "tDOT2", + "tDOT3", + "tAREF", + "tASET", + "tLSHFT", + "tRSHFT", + "tCOLON2", + "tCOLON3", + "tOP_ASGN", + "tASSOC", + "tLPAREN", + "tLPAREN2", + "tRPAREN", + "tLPAREN_ARG", + "tLBRACK", + "tLBRACK2", + "tRBRACK", + "tLBRACE", + "tLBRACE_ARG", + "tSTAR", + "tSTAR2", + "tAMPER", + "tAMPER2", + "tTILDE", + "tPERCENT", + "tDIVIDE", + "tPLUS", + "tMINUS", + "tLT", + "tGT", + "tPIPE", + "tBANG", + "tCARET", + "tLCURLY", + "tRCURLY", + "tBACK_REF2", + "tSYMBEG", + "tSTRING_BEG", + "tXSTRING_BEG", + "tREGEXP_BEG", + "tWORDS_BEG", + "tQWORDS_BEG", + "tSTRING_DBEG", + "tSTRING_DVAR", + "tSTRING_END", + "tSTRING", + "tSYMBOL", + "tREGEXP_OPT", + "tNL", + "tEH", + "tCOLON", + "tCOMMA", + "tSPACE", + "tSEMI", + "tEQL", + "tLOWEST", + "$start", + "program", + "compstmt", + "bodystmt", + "opt_rescue", + "opt_else", + "opt_ensure", + "stmts", + "opt_terms", + "stmt", + "terms", + "fitem", + "undef_list", + "expr_value", + "lhs", + "command_call", + "mlhs", + "var_lhs", + "primary_value", + "aref_args", + "backref", + "mrhs", + "arg_value", + "expr", + "@1", + "arg", + "command", + "block_command", + "call_args", + "block_call", + "operation2", + "command_args", + "cmd_brace_block", + "opt_block_var", + "@2", + "operation", + "mlhs_basic", + "mlhs_entry", + "mlhs_head", + "mlhs_item", + "mlhs_node", + "variable", + "cname", + "cpath", + "fname", + "op", + "reswords", + "fsym", + "symbol", + "dsym", + "@3", + "opt_nl", + "primary", + "none", + "args", + "trailer", + "assocs", + "paren_args", + "opt_paren_args", + "opt_block_arg", + "block_arg", + "call_args2", + "open_args", + "@4", + "@5", + "@6", + "literal", + "strings", + "xstring", + "regexp", + "words", + "qwords", + "var_ref", + "assoc_list", + "brace_block", + "method_call", + "then", + "if_tail", + "do", + "case_body", + "for_var", + "k_class", + "superclass", + "term", + "k_module", + "f_arglist", + "singleton", + "dot_or_colon", + "@7", + "@8", + "@9", + "@10", + "@11", + "@12", + "@13", + "@14", + "@15", + "@16", + "@17", + "@18", + "@19", + "block_par", + "block_var", + "do_block", + "@20", + "operation3", + "@21", + "@22", + "when_args", + "cases", + "exc_list", + "exc_var", + "numeric", + "string", + "string1", + "string_contents", + "xstring_contents", + "word_list", + "word", + "string_content", + "qword_list", + "string_dvar", + "@23", + "f_args", + "f_arg", + "f_optarg", + "f_rest_arg", + "opt_f_block_arg", + "f_block_arg", + "f_norm_arg", + "f_opt", + "restarg_mark", + "blkarg_mark", + "assoc" ] +Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) + +Racc_debug_parser = false + +##### State transition tables end ##### + +# reduce 0 omitted + +def _reduce_1(val, _values, result) + result = val[0] + + result +end + +def _reduce_2(val, _values, result) + rescue_bodies = val[1] + else_t, else_ = val[2] + ensure_t, ensure_ = val[3] + + if rescue_bodies.empty? && !else_t.nil? + diagnostic :warning, :useless_else, nil, else_t + end + + result = @builder.begin_body(val[0], + rescue_bodies, + else_t, else_, + ensure_t, ensure_) + + result +end + +def _reduce_3(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_4(val, _values, result) + result = [] + + result +end + +def _reduce_5(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_6(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_7(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_8(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_9(val, _values, result) + result = @builder.alias(val[0], val[1], val[3]) + + result +end + +def _reduce_10(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.gvar(val[2])) + + result +end + +def _reduce_11(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.back_ref(val[2])) + + result +end + +def _reduce_12(val, _values, result) + diagnostic :error, :nth_ref_alias, nil, val[2] + + result +end + +def _reduce_13(val, _values, result) + result = @builder.undef_method(val[0], val[1]) + + result +end + +def _reduce_14(val, _values, result) + result = @builder.condition_mod(val[0], nil, + val[1], val[2]) + + result +end + +def _reduce_15(val, _values, result) + result = @builder.condition_mod(nil, val[0], + val[1], val[2]) + + result +end + +def _reduce_16(val, _values, result) + result = @builder.loop_mod(:while, val[0], val[1], val[2]) + + result +end + +def _reduce_17(val, _values, result) + result = @builder.loop_mod(:until, val[0], val[1], val[2]) + + result +end + +def _reduce_18(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_19(val, _values, result) + if @context.in_def + diagnostic :error, :begin_in_method, nil, val[0] + end + + result = @builder.preexe(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_20(val, _values, result) + result = @builder.postexe(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_21(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_22(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_23(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_24(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_25(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_26(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_27(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_28(val, _values, result) + @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_29(val, _values, result) + result = @builder.assign(val[0], val[1], + @builder.array(nil, val[2], nil)) + + result +end + +def _reduce_30(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_31(val, _values, result) + result = @builder.multi_assign(val[0], val[1], + @builder.array(nil, val[2], nil)) + + result +end + +# reduce 32 omitted + +# reduce 33 omitted + +def _reduce_34(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_35(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_36(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +def _reduce_37(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +# reduce 38 omitted + +# reduce 39 omitted + +# reduce 40 omitted + +# reduce 41 omitted + +def _reduce_42(val, _values, result) + result = @builder.keyword_cmd(:return, val[0], + nil, val[1], nil) + + result +end + +def _reduce_43(val, _values, result) + result = @builder.keyword_cmd(:break, val[0], + nil, val[1], nil) + + result +end + +def _reduce_44(val, _values, result) + result = @builder.keyword_cmd(:next, val[0], + nil, val[1], nil) + + result +end + +# reduce 45 omitted + +def _reduce_46(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_47(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_48(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_49(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_50(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.call_method(nil, nil, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_51(val, _values, result) + lparen_t, args, rparen_t = val[1] + method_call = @builder.call_method(nil, nil, val[0], + lparen_t, args, rparen_t) + + begin_t, block_args, body, end_t = val[2] + result = @builder.block(method_call, + begin_t, block_args, body, end_t) + + result +end + +def _reduce_52(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + + result +end + +def _reduce_53(val, _values, result) + lparen_t, args, rparen_t = val[3] + method_call = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + begin_t, block_args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, block_args, body, end_t) + + result +end + +def _reduce_54(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_55(val, _values, result) + lparen_t, args, rparen_t = val[3] + method_call = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + begin_t, block_args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, block_args, body, end_t) + + result +end + +def _reduce_56(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.keyword_cmd(:super, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_57(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.keyword_cmd(:yield, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_58(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_59(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_60(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_61(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_62(val, _values, result) + result = val[0] + + result +end + +def _reduce_63(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_64(val, _values, result) + result = val[0] << @builder.splat(val[1], val[2]) + + result +end + +def _reduce_65(val, _values, result) + result = val[0] << @builder.splat(val[1]) + + result +end + +def _reduce_66(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_67(val, _values, result) + result = [ @builder.splat(val[0]) ] + + result +end + +# reduce 68 omitted + +def _reduce_69(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_70(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_71(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_72(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_73(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_74(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_75(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_76(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_77(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_78(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_79(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_80(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_81(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_82(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_83(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_84(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_85(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_86(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_87(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_88(val, _values, result) + diagnostic :error, :module_name_const, nil, val[0] + + result +end + +# reduce 89 omitted + +def _reduce_90(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_91(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_92(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +# reduce 93 omitted + +# reduce 94 omitted + +# reduce 95 omitted + +# reduce 96 omitted + +# reduce 97 omitted + +def _reduce_98(val, _values, result) + result = @builder.symbol_internal(val[0]) + + result +end + +# reduce 99 omitted + +# reduce 100 omitted + +# reduce 101 omitted + +def _reduce_102(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_103(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_104(val, _values, result) + result = val[0] << val[3] + + result +end + +# reduce 105 omitted + +# reduce 106 omitted + +# reduce 107 omitted + +# reduce 108 omitted + +# reduce 109 omitted + +# reduce 110 omitted + +# reduce 111 omitted + +# reduce 112 omitted + +# reduce 113 omitted + +# reduce 114 omitted + +# reduce 115 omitted + +# reduce 116 omitted + +# reduce 117 omitted + +# reduce 118 omitted + +# reduce 119 omitted + +# reduce 120 omitted + +# reduce 121 omitted + +# reduce 122 omitted + +# reduce 123 omitted + +# reduce 124 omitted + +# reduce 125 omitted + +# reduce 126 omitted + +# reduce 127 omitted + +# reduce 128 omitted + +# reduce 129 omitted + +# reduce 130 omitted + +# reduce 131 omitted + +# reduce 132 omitted + +# reduce 133 omitted + +# reduce 134 omitted + +# reduce 135 omitted + +# reduce 136 omitted + +# reduce 137 omitted + +# reduce 138 omitted + +# reduce 139 omitted + +# reduce 140 omitted + +# reduce 141 omitted + +# reduce 142 omitted + +# reduce 143 omitted + +# reduce 144 omitted + +# reduce 145 omitted + +# reduce 146 omitted + +# reduce 147 omitted + +# reduce 148 omitted + +# reduce 149 omitted + +# reduce 150 omitted + +# reduce 151 omitted + +# reduce 152 omitted + +# reduce 153 omitted + +# reduce 154 omitted + +# reduce 155 omitted + +# reduce 156 omitted + +# reduce 157 omitted + +# reduce 158 omitted + +# reduce 159 omitted + +# reduce 160 omitted + +# reduce 161 omitted + +# reduce 162 omitted + +# reduce 163 omitted + +# reduce 164 omitted + +# reduce 165 omitted + +# reduce 166 omitted + +# reduce 167 omitted + +# reduce 168 omitted + +# reduce 169 omitted + +# reduce 170 omitted + +def _reduce_171(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_172(val, _values, result) + rescue_body = @builder.rescue_body(val[3], + nil, nil, nil, + nil, val[4]) + + rescue_ = @builder.begin_body(val[2], [ rescue_body ]) + + result = @builder.assign(val[0], val[1], rescue_) + + result +end + +def _reduce_173(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_174(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_175(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_176(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_177(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_178(val, _values, result) + diagnostic :error, :dynamic_const, nil, val[2], [ val[3] ] + + result +end + +def _reduce_179(val, _values, result) + diagnostic :error, :dynamic_const, nil, val[1], [ val[2] ] + + result +end + +def _reduce_180(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_181(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_182(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_183(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_184(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_185(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_186(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_187(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_188(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_189(val, _values, result) + result = @builder.unary_op(val[0], + @builder.binary_op( + @builder.integer(val[1]), + val[2], val[3])) + + result +end + +def _reduce_190(val, _values, result) + result = @builder.unary_op(val[0], + @builder.binary_op( + @builder.float(val[1]), + val[2], val[3])) + + result +end + +def _reduce_191(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_192(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_193(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_194(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_195(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_196(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_197(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_198(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_199(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_200(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_201(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_202(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_203(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_204(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_205(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_206(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +def _reduce_207(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_208(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_209(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_210(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_211(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_212(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil) + + result +end + +def _reduce_213(val, _values, result) + result = @builder.ternary(val[0], val[1], + val[2], val[3], val[4]) + + result +end + +# reduce 214 omitted + +# reduce 215 omitted + +def _reduce_216(val, _values, result) + result = [] + + result +end + +def _reduce_217(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_218(val, _values, result) + result = val[0] + + result +end + +def _reduce_219(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_220(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +def _reduce_221(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_222(val, _values, result) + result = [ val[0], [], val[2] ] + + result +end + +def _reduce_223(val, _values, result) + result = [ val[0], val[1], val[3] ] + + result +end + +def _reduce_224(val, _values, result) + result = [ val[0], [ val[1] ], val[3] ] + + result +end + +def _reduce_225(val, _values, result) + result = [ val[0], val[1] << val[3], val[5] ] + + result +end + +def _reduce_226(val, _values, result) + result = [ nil, [], nil ] + + result +end + +# reduce 227 omitted + +def _reduce_228(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_229(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_230(val, _values, result) + result = val[0].concat( + [ @builder.splat(val[2], val[3]), + *val[4] ]) + + result +end + +def _reduce_231(val, _values, result) + result = [ @builder.associate(nil, val[0], nil), + *val[1] ] + + result +end + +def _reduce_232(val, _values, result) + result = [ @builder.associate(nil, val[0], nil), + @builder.splat(val[2], val[3]), + *val[4] ] + + result +end + +def _reduce_233(val, _values, result) + result = val[0].concat( + [ @builder.associate(nil, val[2], nil), + *val[3] ]) + + result +end + +def _reduce_234(val, _values, result) + result = val[0].concat( + [ @builder.associate(nil, val[2], nil), + @builder.splat(val[4], val[5]), + *val[6] ]) + + result +end + +def _reduce_235(val, _values, result) + result = [ @builder.splat(val[0], val[1]), + *val[2] ] + + result +end + +def _reduce_236(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_237(val, _values, result) + result = [ val[0], *val[2].concat(val[3]) ] + + result +end + +def _reduce_238(val, _values, result) + result = [ val[0], val[2] ] + + result +end + +def _reduce_239(val, _values, result) + result = [ val[0], + @builder.splat(val[2], val[3]), + *val[4] ] + + result +end + +def _reduce_240(val, _values, result) + result = [ val[0], + *val[2]. + push(@builder.splat(val[4], val[5])). + concat(val[6]) ] + + result +end + +def _reduce_241(val, _values, result) + result = [ @builder.associate(nil, val[0], nil), + *val[1] ] + + result +end + +def _reduce_242(val, _values, result) + result = [ @builder.associate(nil, val[0], nil), + @builder.splat(val[2], val[3]), + *val[4] ] + + result +end + +def _reduce_243(val, _values, result) + result = [ val[0], + @builder.associate(nil, val[2], nil), + *val[3] ] + + result +end + +def _reduce_244(val, _values, result) + result = [ val[0], + *val[2]. + push(@builder.associate(nil, val[4], nil)). + concat(val[5]) ] + + result +end + +def _reduce_245(val, _values, result) + result = [ val[0], + @builder.associate(nil, val[2], nil), + @builder.splat(val[4], val[5]), + *val[6] ] + + result +end + +def _reduce_246(val, _values, result) + result = [ val[0], + *val[2]. + push(@builder.associate(nil, val[4], nil)). + push(@builder.splat(val[6], val[7])). + concat(val[8]) ] + + result +end + +def _reduce_247(val, _values, result) + result = [ @builder.splat(val[0], val[1]), + *val[2] ] + + result +end + +def _reduce_248(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_249(val, _values, result) + result = @lexer.cmdarg.dup + @lexer.cmdarg.push(true) + + result +end + +def _reduce_250(val, _values, result) + @lexer.cmdarg = val[0] + + result = val[1] + + result +end + +def _reduce_251(val, _values, result) + result = [ nil, val[0], nil ] + + result +end + +def _reduce_252(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_253(val, _values, result) + result = [ val[0], [], val[2] ] + + result +end + +def _reduce_254(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_255(val, _values, result) + result = [ val[0], val[1], val[3] ] + + result +end + +def _reduce_256(val, _values, result) + result = @builder.block_pass(val[0], val[1]) + + result +end + +def _reduce_257(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_258(val, _values, result) + result = [] + + result +end + +def _reduce_259(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_260(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_261(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_262(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_263(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +# reduce 264 omitted + +# reduce 265 omitted + +# reduce 266 omitted + +# reduce 267 omitted + +# reduce 268 omitted + +# reduce 269 omitted + +# reduce 270 omitted + +# reduce 271 omitted + +def _reduce_272(val, _values, result) + result = @builder.call_method(nil, nil, val[0]) + + result +end + +def _reduce_273(val, _values, result) + result = @builder.begin_keyword(val[0], val[1], val[2]) + + result +end + +def _reduce_274(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_275(val, _values, result) + result = @builder.begin(val[0], val[1], val[4]) + + result +end + +def _reduce_276(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_277(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +def _reduce_278(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_279(val, _values, result) + result = @builder.index(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_280(val, _values, result) + result = @builder.array(val[0], val[1], val[2]) + + result +end + +def _reduce_281(val, _values, result) + result = @builder.associate(val[0], val[1], val[2]) + + result +end + +def _reduce_282(val, _values, result) + result = @builder.keyword_cmd(:return, val[0]) + + result +end + +def _reduce_283(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_284(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2]) + + result +end + +def _reduce_285(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0]) + + result +end + +def _reduce_286(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], + val[2], [ val[3] ], val[4]) + + result +end + +def _reduce_287(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0]) + + begin_t, args, body, end_t = val[1] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +# reduce 288 omitted + +def _reduce_289(val, _values, result) + begin_t, args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, args, body, end_t) + + result +end + +def _reduce_290(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, val[5]) + + result +end + +def _reduce_291(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + else_, else_t, + val[3], val[5]) + + result +end + +def _reduce_292(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_293(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_294(val, _values, result) + result = @builder.loop(:while, val[0], val[2], val[3], + val[5], val[6]) + + result +end + +def _reduce_295(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_296(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_297(val, _values, result) + result = @builder.loop(:until, val[0], val[2], val[3], + val[5], val[6]) + + result +end + +def _reduce_298(val, _values, result) + when_bodies = val[3][0..-2] + else_t, else_body = val[3][-1] + + result = @builder.case(val[0], val[1], + when_bodies, else_t, else_body, + val[4]) + + result +end + +def _reduce_299(val, _values, result) + when_bodies = val[2][0..-2] + else_t, else_body = val[2][-1] + + result = @builder.case(val[0], nil, + when_bodies, else_t, else_body, + val[3]) + + result +end + +def _reduce_300(val, _values, result) + result = @builder.case(val[0], nil, + [], val[2], val[3], + val[4]) + + result +end + +def _reduce_301(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_302(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_303(val, _values, result) + result = @builder.for(val[0], val[1], + val[2], val[4], + val[5], val[7], val[8]) + + result +end + +def _reduce_304(val, _values, result) + local_push + @context.in_class = true + + result +end + +def _reduce_305(val, _values, result) + k_class, ctx = val[0] + if @context.in_def + diagnostic :error, :class_in_def, nil, k_class + end + + lt_t, superclass = val[2] + result = @builder.def_class(k_class, val[1], + lt_t, superclass, + val[4], val[5]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_306(val, _values, result) + @context.in_def = false + @context.in_class = false + local_push + + result +end + +def _reduce_307(val, _values, result) + k_class, ctx = val[0] + result = @builder.def_sclass(k_class, val[1], val[2], + val[5], val[6]) + + local_pop + @context.in_def = ctx.in_def + @context.in_class = ctx.in_class + + result +end + +def _reduce_308(val, _values, result) + @context.in_class = true + local_push + + result +end + +def _reduce_309(val, _values, result) + k_mod, ctx = val[0] + if @context.in_def + diagnostic :error, :module_in_def, nil, k_mod + end + + result = @builder.def_module(k_mod, val[1], + val[3], val[4]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_310(val, _values, result) + local_push + result = context.dup + @context.in_def = true + + result +end + +def _reduce_311(val, _values, result) + result = @builder.def_method(val[0], val[1], + val[3], val[4], val[5]) + + local_pop + @context.in_def = val[2].in_def + + result +end + +def _reduce_312(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_313(val, _values, result) + local_push + result = context.dup + @context.in_def = true + + result +end + +def _reduce_314(val, _values, result) + result = @builder.def_singleton(val[0], val[1], val[2], + val[4], val[6], val[7], val[8]) + + local_pop + @context.in_def = val[5].in_def + + result +end + +def _reduce_315(val, _values, result) + result = @builder.keyword_cmd(:break, val[0]) + + result +end + +def _reduce_316(val, _values, result) + result = @builder.keyword_cmd(:next, val[0]) + + result +end + +def _reduce_317(val, _values, result) + result = @builder.keyword_cmd(:redo, val[0]) + + result +end + +def _reduce_318(val, _values, result) + result = @builder.keyword_cmd(:retry, val[0]) + + result +end + +# reduce 319 omitted + +def _reduce_320(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_321(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +# reduce 322 omitted + +# reduce 323 omitted + +# reduce 324 omitted + +def _reduce_325(val, _values, result) + result = val[1] + + result +end + +# reduce 326 omitted + +# reduce 327 omitted + +# reduce 328 omitted + +# reduce 329 omitted + +def _reduce_330(val, _values, result) + else_t, else_ = val[4] + result = [ val[0], + @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, nil), + ] + + result +end + +# reduce 331 omitted + +def _reduce_332(val, _values, result) + result = val + + result +end + +# reduce 333 omitted + +# reduce 334 omitted + +def _reduce_335(val, _values, result) + result = [ @builder.arg_expr(val[0]) ] + + result +end + +def _reduce_336(val, _values, result) + result = val[0] << @builder.arg_expr(val[2]) + + result +end + +# reduce 337 omitted + +# reduce 338 omitted + +def _reduce_339(val, _values, result) + result = val[0]. + push(@builder.blockarg_expr(val[2], val[3])) + + result +end + +def _reduce_340(val, _values, result) + result = val[0]. + push(@builder.restarg_expr(val[2], val[3])). + push(@builder.blockarg_expr(val[5], val[6])) + + result +end + +def _reduce_341(val, _values, result) + result = val[0]. + push(@builder.restarg_expr(val[2])). + push(@builder.blockarg_expr(val[4], val[5])) + + result +end + +def _reduce_342(val, _values, result) + result = val[0]. + push(@builder.restarg_expr(val[2], val[3])) + + result +end + +def _reduce_343(val, _values, result) + result = val[0]. + push(@builder.restarg_expr(val[2])) + + result +end + +def _reduce_344(val, _values, result) + result = [ @builder.restarg_expr(val[0], val[1]), + @builder.blockarg_expr(val[3], val[4]) ] + + result +end + +def _reduce_345(val, _values, result) + result = [ @builder.restarg_expr(val[0]), + @builder.blockarg_expr(val[2], val[3]) ] + + result +end + +def _reduce_346(val, _values, result) + result = [ @builder.restarg_expr(val[0], val[1]) ] + + result +end + +def _reduce_347(val, _values, result) + result = [ @builder.restarg_expr(val[0]) ] + + result +end + +def _reduce_348(val, _values, result) + result = [ @builder.blockarg_expr(val[0], val[1]) ] + + result +end + +def _reduce_349(val, _values, result) + result = @builder.args(nil, [], nil) + + result +end + +def _reduce_350(val, _values, result) + result = @builder.args(val[0], [], val[1]) + + result +end + +def _reduce_351(val, _values, result) + result = @builder.args(val[0], [], val[0]) + + result +end + +def _reduce_352(val, _values, result) + result = @builder.args(val[0], val[1], val[2], false) + + result +end + +def _reduce_353(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_354(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_355(val, _values, result) + begin_t, block_args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, block_args, body, end_t) + + result +end + +def _reduce_356(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_357(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_358(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.call_method(nil, nil, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_359(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_360(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_361(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2]) + + result +end + +def _reduce_362(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.keyword_cmd(:super, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_363(val, _values, result) + result = @builder.keyword_cmd(:zsuper, val[0]) + + result +end + +def _reduce_364(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_365(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_366(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_367(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_368(val, _values, result) + result = [ @builder.when(val[0], val[1], val[2], val[3]), + *val[4] ] + + result +end + +# reduce 369 omitted + +def _reduce_370(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_371(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_372(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 373 omitted + +def _reduce_374(val, _values, result) + assoc_t, exc_var = val[2] + + if val[1] + exc_list = @builder.array(nil, val[1], nil) + end + + result = [ @builder.rescue_body(val[0], + exc_list, assoc_t, exc_var, + val[3], val[4]), + *val[5] ] + + result +end + +def _reduce_375(val, _values, result) + result = [] + + result +end + +def _reduce_376(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 377 omitted + +# reduce 378 omitted + +def _reduce_379(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 380 omitted + +def _reduce_381(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 382 omitted + +# reduce 383 omitted + +# reduce 384 omitted + +# reduce 385 omitted + +def _reduce_386(val, _values, result) + result = @builder.string_compose(nil, val[0], nil) + + result +end + +def _reduce_387(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_388(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_389(val, _values, result) + result = @builder.string_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_390(val, _values, result) + result = @builder.string(val[0]) + + result +end + +def _reduce_391(val, _values, result) + result = @builder.xstring_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_392(val, _values, result) + opts = @builder.regexp_options(val[3]) + result = @builder.regexp_compose(val[0], val[1], val[2], opts) + + result +end + +def _reduce_393(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_394(val, _values, result) + result = [] + + result +end + +def _reduce_395(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_396(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_397(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_398(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_399(val, _values, result) + result = [] + + result +end + +def _reduce_400(val, _values, result) + result = val[0] << @builder.string_internal(val[1]) + + result +end + +def _reduce_401(val, _values, result) + result = [] + + result +end + +def _reduce_402(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_403(val, _values, result) + result = [] + + result +end + +def _reduce_404(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_405(val, _values, result) + result = @builder.string_internal(val[0]) + + result +end + +def _reduce_406(val, _values, result) + result = val[1] + + result +end + +def _reduce_407(val, _values, result) + @lexer.cond.push(false) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_408(val, _values, result) + @lexer.cond.lexpop + @lexer.cmdarg.lexpop + + result = @builder.begin(val[0], val[2], val[3]) + + result +end + +def _reduce_409(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_410(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_411(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +# reduce 412 omitted + +def _reduce_413(val, _values, result) + result = @builder.symbol(val[0]) + + result +end + +def _reduce_414(val, _values, result) + result = @builder.symbol_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_415(val, _values, result) + result = @builder.integer(val[0]) + + result +end + +def _reduce_416(val, _values, result) + result = @builder.float(val[0]) + + result +end + +def _reduce_417(val, _values, result) + num = @builder.integer(val[1]) + if @builder.respond_to? :negate + # AST builder interface compatibility + result = @builder.negate(val[0], num) + else + result = @builder.unary_num(val[0], num) + end + + result +end + +def _reduce_418(val, _values, result) + num = @builder.float(val[1]) + if @builder.respond_to? :negate + # AST builder interface compatibility + result = @builder.negate(val[0], num) + else + result = @builder.unary_num(val[0], num) + end + + result +end + +def _reduce_419(val, _values, result) + result = @builder.ident(val[0]) + + result +end + +def _reduce_420(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_421(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_422(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +def _reduce_423(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_424(val, _values, result) + result = @builder.nil(val[0]) + + result +end + +def _reduce_425(val, _values, result) + result = @builder.self(val[0]) + + result +end + +def _reduce_426(val, _values, result) + result = @builder.true(val[0]) + + result +end + +def _reduce_427(val, _values, result) + result = @builder.false(val[0]) + + result +end + +def _reduce_428(val, _values, result) + result = @builder.__FILE__(val[0]) + + result +end + +def _reduce_429(val, _values, result) + result = @builder.__LINE__(val[0]) + + result +end + +def _reduce_430(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_431(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_432(val, _values, result) + result = @builder.nth_ref(val[0]) + + result +end + +def _reduce_433(val, _values, result) + result = @builder.back_ref(val[0]) + + result +end + +def _reduce_434(val, _values, result) + result = nil + + result +end + +def _reduce_435(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +def _reduce_436(val, _values, result) + yyerrok + result = nil + + result +end + +def _reduce_437(val, _values, result) + result = @builder.args(val[0], val[1], val[3]) + + @lexer.state = :expr_beg + + result +end + +def _reduce_438(val, _values, result) + result = @builder.args(nil, val[0], nil) + + result +end + +def _reduce_439(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_440(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_441(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_442(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_443(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_444(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_445(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_446(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_447(val, _values, result) + result = [] + + result +end + +def _reduce_448(val, _values, result) + diagnostic :error, :argument_const, nil, val[0] + + result +end + +def _reduce_449(val, _values, result) + diagnostic :error, :argument_ivar, nil, val[0] + + result +end + +def _reduce_450(val, _values, result) + diagnostic :error, :argument_gvar, nil, val[0] + + result +end + +def _reduce_451(val, _values, result) + diagnostic :error, :argument_cvar, nil, val[0] + + result +end + +def _reduce_452(val, _values, result) + @static_env.declare val[0][0] + + result = @builder.arg(val[0]) + + result +end + +def _reduce_453(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_454(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_455(val, _values, result) + @static_env.declare val[0][0] + + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_456(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_457(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 458 omitted + +# reduce 459 omitted + +def _reduce_460(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_461(val, _values, result) + result = [ @builder.restarg(val[0]) ] + + result +end + +# reduce 462 omitted + +# reduce 463 omitted + +def _reduce_464(val, _values, result) + @static_env.declare val[1][0] + + result = @builder.blockarg(val[0], val[1]) + + result +end + +def _reduce_465(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_466(val, _values, result) + result = [] + + result +end + +# reduce 467 omitted + +def _reduce_468(val, _values, result) + result = val[1] + + result +end + +def _reduce_469(val, _values, result) + result = [] + + result +end + +def _reduce_470(val, _values, result) + result = val[0] + + result +end + +def _reduce_471(val, _values, result) + result = @builder.pair_list_18(val[0]) + + result +end + +def _reduce_472(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_473(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_474(val, _values, result) + result = @builder.pair(val[0], val[1], val[2]) + + result +end + +# reduce 475 omitted + +# reduce 476 omitted + +# reduce 477 omitted + +# reduce 478 omitted + +# reduce 479 omitted + +# reduce 480 omitted + +# reduce 481 omitted + +# reduce 482 omitted + +# reduce 483 omitted + +# reduce 484 omitted + +# reduce 485 omitted + +# reduce 486 omitted + +# reduce 487 omitted + +# reduce 488 omitted + +# reduce 489 omitted + +# reduce 490 omitted + +# reduce 491 omitted + +# reduce 492 omitted + +# reduce 493 omitted + +def _reduce_494(val, _values, result) + yyerrok + + result +end + +# reduce 495 omitted + +# reduce 496 omitted + +# reduce 497 omitted + +def _reduce_498(val, _values, result) + result = nil + + result +end + +def _reduce_none(val, _values, result) + val[0] +end + + end # class Ruby18 +end # module Parser diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby19.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby19.rb new file mode 100644 index 00000000..c68f5833 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby19.rb @@ -0,0 +1,9558 @@ +# -*- encoding:utf-8; warn-indent:false; frozen_string_literal: true -*- +# +# DO NOT MODIFY!!!! +# This file is automatically generated by Racc 1.8.1 +# from Racc grammar file "ruby19.y". +# + +require 'racc/parser.rb' + + +require_relative '../parser' + +module Parser + class Ruby19 < Parser::Base + + + def version + 19 + end + + def default_encoding + Encoding::BINARY + end + + def local_push + @static_env.extend_static + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + end + + def local_pop + @static_env.unextend + @lexer.cmdarg.pop + @lexer.cond.pop + end +##### State transition tables begin ### + +racc_action_table = [ + -455, 5, 71, 72, 68, 9, 54, -455, -455, -455, + 60, 61, -455, -455, -455, 64, -455, 62, 63, 65, + 29, 30, 69, 70, -455, 260, -455, -455, -455, 28, + 27, 26, 95, 94, 96, 97, -455, -455, 19, -455, + -455, -455, -455, -455, 8, 44, 7, 10, 99, 98, + 100, 89, 53, 91, 90, 92, 543, 93, 101, 102, + 522, 87, 88, 41, 42, 40, -455, -455, -455, -455, + -455, -455, -455, -455, -455, -455, -455, -455, -455, -455, + 103, 210, -455, -455, -455, 39, -455, -455, 32, -96, + -455, 55, 56, -455, -455, 57, -455, 34, -455, 564, + -455, 43, -455, -455, -455, -455, -455, -455, -455, 20, + -455, 259, -455, -97, 86, 78, 81, 82, 211, 83, + 84, 636, -104, 528, 79, 85, -455, -455, -455, -455, + -458, -455, 59, -455, 80, -455, -103, -458, -458, -458, + -469, 205, -458, -458, -458, 671, -458, 534, 522, -90, + 115, 535, 522, 252, -458, 231, -458, -458, -458, 760, + 253, 542, 563, 207, 208, -99, -458, -458, 671, -458, + -458, -458, -458, -458, 107, 522, 522, -99, -101, 106, + -101, 107, 207, 208, -95, -98, 106, 228, 107, -96, + -104, 230, 229, 106, -87, -98, -458, -458, -458, -458, + -458, -458, -458, -458, -458, -458, -458, -458, -458, -458, + 599, 199, -458, -458, -458, -90, -458, -458, -88, 200, + -458, -100, -92, -458, -458, -470, -458, -95, -458, 201, + -458, 671, -458, -458, -458, -458, -458, -458, -458, -281, + -458, -94, -458, 206, 598, 107, -281, -281, -281, 599, + 106, -90, -281, -281, -90, -281, -458, -458, -458, -458, + -90, -458, 107, -458, 759, -458, 107, 106, 107, 785, + -90, 106, 107, 106, -97, -281, -281, 106, -281, -281, + -281, -281, -281, 598, 250, -92, 260, -100, -92, 107, + 107, -99, -101, -102, 106, 106, -99, -101, -529, -98, + -89, 306, 307, 304, -98, -281, -281, -281, -281, -281, + -281, -281, -281, -281, -281, -281, -281, -281, -281, 207, + 208, -281, -281, -281, -92, 582, -469, -92, 305, -281, + 429, 107, -281, -92, 499, -100, 106, -281, 211, -281, + -100, -281, -281, -281, -281, -281, -281, -281, -533, -281, + 255, -281, -529, 207, 208, -533, -533, -533, -530, 207, + 208, -533, -533, 724, -533, -281, -281, 599, -93, -87, + -281, 260, 259, -533, -102, -96, 599, -399, 512, -104, + -82, 511, 372, -103, -533, -533, -68, -533, -533, -533, + -533, -533, -91, 774, 385, 652, 651, 650, -93, 653, + 774, 598, 652, 651, 650, 428, 653, 430, 107, 211, + 598, 431, -99, 106, -533, -533, -533, -533, -533, -533, + -533, -533, -533, -533, -533, -533, -533, -533, 210, -399, + -533, -533, -533, 553, 583, 255, -399, -455, -533, 725, + 463, -533, 803, 211, -455, -399, -533, -470, -533, 211, + -533, -533, -533, -533, -533, -533, -533, 259, -533, -533, + -533, 553, 499, -399, 472, -458, 474, -526, -527, -465, + 476, 846, -458, -533, -533, -533, -465, -91, 928, -533, + -533, -533, -533, -100, -67, -533, -533, -533, -101, -533, + -88, -98, 494, 495, 555, 554, -97, -464, -533, -533, + -533, -533, 382, 703, -464, -94, -533, 384, 383, -533, + -533, -103, -533, -533, -533, -533, -533, 211, 512, -455, + -458, 514, 555, 554, 551, 553, -455, -458, 553, 107, + -466, -526, -527, 553, 106, -455, -458, -466, 484, -533, + -533, -533, -533, -533, -533, -533, -533, -533, -533, -533, + -533, -533, -533, -526, -527, -533, -533, -533, -533, 726, + -533, 553, 485, -533, 577, -533, -533, -533, -533, -533, + -529, -533, 492, -533, -533, -533, -533, -533, -533, -533, + -533, -533, 264, -533, -533, -533, 555, 554, 556, 555, + 554, 558, -533, 211, 555, 554, 560, 255, 578, -533, + -533, -533, -533, -281, -533, 496, -533, -90, -100, 710, + -281, -281, -281, -99, 500, -281, -281, -281, 501, -281, + -533, 203, 555, 554, 565, 231, -463, -533, 204, -281, + -281, -281, -529, -463, 231, 512, -533, 202, 514, -281, + -281, -92, -281, -281, -281, -281, -281, -101, -460, -325, + 207, 208, -89, -461, -533, -460, -325, 228, -98, -462, + -461, 230, 229, 226, 227, -325, -462, 207, 208, -281, + -281, -281, -281, -281, -281, -281, -281, -281, -281, -281, + -281, -281, -281, 78, 425, -281, -281, -281, -467, 727, + -281, 426, 79, -281, 507, -467, -281, -281, 508, -281, + 427, -281, 80, -281, -467, -281, -281, -281, -281, -281, + -281, -281, 515, -281, 231, -281, 516, 655, 548, 652, + 651, 650, 107, 653, 476, 549, 528, 106, 107, -281, + -281, -281, -281, 106, -281, 374, -281, 532, -102, 280, + 71, 72, 68, 9, 54, 533, 228, 107, 60, 61, + 230, 229, 106, 64, 657, 62, 63, 65, 29, 30, + 69, 70, 566, 661, 660, 664, 663, 28, 27, 26, + 95, 94, 96, 97, 697, 698, 19, 569, 699, 101, + 102, 587, 8, 44, -260, 10, 99, 98, 100, 89, + 53, 91, 90, 92, 571, 93, 101, 102, 211, 87, + 88, 41, 42, 40, 231, 235, 240, 241, 242, 237, + 239, 247, 248, 243, 244, -468, 224, 225, 490, 575, + 245, 246, -468, 39, 512, 491, 282, 514, 576, 55, + 56, -468, 255, 57, 489, 34, 228, 586, 234, 43, + 230, 229, 226, 227, 238, 236, 232, 20, 233, 780, + 636, 589, 86, 78, 81, 82, 231, 83, 84, 231, + 231, -274, 79, 85, 231, 249, -275, -237, -274, 231, + 59, 211, 80, -275, -275, -275, 211, -274, -275, -275, + -275, 737, -275, 652, 651, 650, 211, 653, 780, 636, + -82, 228, -275, -275, -275, 230, 229, 226, 227, 618, + 211, 505, -275, -275, 629, -275, -275, -275, -275, -275, + 774, 636, 652, 651, 650, 502, 653, 774, 657, 652, + 651, 650, 503, 653, 667, 528, 674, 661, 660, 664, + 663, 427, -275, -275, -275, -275, -275, -275, -275, -275, + -275, -275, -275, -275, -275, -275, 702, 770, -275, -275, + -275, 530, 705, -275, 770, -261, -275, 711, 531, -275, + -275, 736, -275, 773, -275, 463, -275, 529, -275, -275, + -275, -275, -275, -275, -275, 538, -275, 463, -275, 211, + -282, 729, 537, 474, 476, 629, 211, -282, 255, 255, + 629, 539, -275, -275, -275, -275, -282, -275, 231, -275, + 280, 71, 72, 68, 9, 54, 231, 750, -282, 60, + 61, -260, 754, 211, 64, -282, 62, 63, 65, 29, + 30, 69, 70, 762, -282, 764, 767, 768, 28, 27, + 26, 95, 94, 96, 97, 776, 815, 19, 652, 651, + 650, 777, 653, 8, 44, 636, 10, 99, 98, 100, + 89, 53, 91, 90, 92, 784, 93, 101, 102, 211, + 87, 88, 41, 42, 40, 774, 211, 652, 651, 650, + 793, 653, -262, 774, 802, 652, 651, 650, 805, 653, + 807, 810, 811, 736, 39, 817, 818, 32, 820, 821, + 55, 56, 629, 830, 57, 774, 34, 652, 651, 650, + 43, 653, 770, 655, 736, 652, 651, 650, 20, 653, + 657, 773, 844, 86, 78, 81, 82, 211, 83, 84, + 848, 664, 663, 79, 85, 5, 71, 72, 68, 9, + 54, 59, 770, 80, 60, 61, 850, 856, 858, 64, + 657, 62, 63, 65, 29, 30, 69, 70, 211, 661, + 660, 664, 663, 28, 27, 26, 95, 94, 96, 97, + 861, 815, 19, 652, 651, 650, -263, 653, 8, 44, + 7, 10, 99, 98, 100, 89, 53, 91, 90, 92, + 868, 93, 101, 102, 869, 87, 88, 41, 42, 40, + 774, 872, 652, 651, 650, 877, 653, 211, 774, 881, + 652, 651, 650, 884, 653, 886, 888, 888, 211, 39, + 893, 896, 32, 897, 902, 55, 56, 904, 907, 57, + 774, 34, 652, 651, 650, 43, 653, 770, 655, 909, + 652, 651, 650, 20, 653, 657, 892, 888, 86, 78, + 81, 82, 888, 83, 84, 914, 664, 663, 79, 85, + 280, 71, 72, 68, 9, 54, 59, 770, 80, 60, + 61, 507, 921, 922, 64, 657, 62, 63, 65, 29, + 30, 69, 70, 930, 661, 660, 664, 663, 28, 27, + 26, 95, 94, 96, 97, 211, 942, 19, 110, 111, + 112, 113, 114, 8, 44, 888, 10, 99, 98, 100, + 89, 53, 91, 90, 92, 888, 93, 101, 102, 888, + 87, 88, 41, 42, 40, 774, 946, 652, 651, 650, + 930, 653, 949, 774, 950, 652, 651, 650, 952, 653, + 888, 888, 888, -530, 39, -529, 930, 32, 888, 930, + 55, 56, 888, nil, 57, 774, 34, 652, 651, 650, + 43, 653, 770, 655, -467, 652, 651, 650, 20, 653, + 657, -467, nil, 86, 78, 81, 82, nil, 83, 84, + -467, 664, 663, 79, 85, 280, 71, 72, 68, 9, + 54, 59, 770, 80, 60, 61, nil, nil, nil, 64, + 657, 62, 63, 65, 29, 30, 69, 70, nil, 661, + 660, 664, 663, 28, 27, 26, 95, 94, 96, 97, + nil, nil, 19, 110, 111, 112, 113, 114, 8, 44, + nil, 10, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, -468, 110, 111, 112, 113, 114, 774, -468, + 652, 651, 650, nil, 653, nil, -281, 875, -468, 39, + -274, nil, 32, -281, 876, 55, 56, -274, -530, 57, + 538, 34, -281, 874, nil, 43, -274, 913, 737, nil, + 652, 651, 650, 20, 653, 657, 539, nil, 86, 78, + 81, 82, nil, 83, 84, nil, 664, 663, 79, 85, + 280, 71, 72, 68, 9, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, 657, 62, 63, 65, 29, + 30, 69, 70, nil, 661, 660, 664, 663, 28, 27, + 26, 95, 94, 96, 97, nil, nil, 19, 110, 111, + 112, 113, 114, 8, 44, nil, 10, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, nil, nil, -282, nil, nil, + nil, nil, nil, 774, -282, 652, 651, 650, nil, 653, + nil, -281, nil, -282, 39, nil, nil, 282, -281, nil, + 55, 56, nil, -530, 57, nil, 34, -281, nil, nil, + 43, nil, nil, 737, nil, 652, 651, 650, 20, 653, + 657, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, 664, 663, 79, 85, 280, 71, 72, 68, 9, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + 657, 62, 63, 65, 29, 30, 69, 70, nil, 661, + 660, 664, 663, 28, 27, 26, 95, 94, 96, 97, + nil, nil, 19, nil, nil, nil, nil, 572, 8, 44, + nil, 10, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + 231, 235, 240, 241, 242, 237, 239, 247, 248, 243, + 244, -281, 224, 225, nil, nil, 245, 246, -281, 39, + nil, nil, 282, -530, nil, 55, 56, -281, nil, 57, + nil, 34, 228, nil, 234, 43, 230, 229, 226, 227, + 238, 236, 232, 20, 233, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 249, -534, nil, nil, nil, 59, nil, 80, -534, + -534, -534, nil, nil, -534, -534, -534, 655, -534, 652, + 651, 650, nil, 653, nil, nil, nil, -534, -534, -534, + -534, nil, nil, nil, nil, nil, nil, nil, -534, -534, + nil, -534, -534, -534, -534, -534, nil, nil, nil, nil, + nil, nil, nil, nil, 657, 644, nil, nil, nil, nil, + nil, nil, nil, 661, 660, 664, 663, nil, -534, -534, + -534, -534, -534, -534, -534, -534, -534, -534, -534, -534, + -534, -534, nil, nil, -534, -534, -534, nil, nil, -534, + nil, nil, -534, nil, nil, -534, -534, nil, -534, nil, + -534, nil, -534, nil, -534, -534, -534, -534, -534, -534, + -534, -535, -534, -534, -534, nil, nil, nil, -535, -535, + -535, nil, nil, -535, -535, -535, 231, -535, -534, -534, + -534, -534, nil, -534, nil, -534, -535, -535, -535, -535, + nil, nil, 245, 246, nil, nil, nil, -535, -535, nil, + -535, -535, -535, -535, -535, nil, nil, nil, 228, nil, + 234, nil, 230, 229, 226, 227, nil, nil, 232, nil, + 233, nil, nil, nil, nil, nil, nil, -535, -535, -535, + -535, -535, -535, -535, -535, -535, -535, -535, -535, -535, + -535, nil, nil, -535, -535, -535, nil, nil, -535, nil, + nil, -535, nil, nil, -535, -535, nil, -535, nil, -535, + nil, -535, nil, -535, -535, -535, -535, -535, -535, -535, + nil, -535, -535, -535, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, -535, -535, -535, + -535, nil, -535, nil, -535, 280, 71, 72, 68, 9, + 54, nil, nil, nil, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 29, 30, 69, 70, nil, nil, + nil, nil, nil, 28, 27, 26, 95, 94, 96, 97, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 44, + nil, 10, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, nil, nil, nil, nil, nil, nil, 774, nil, + 652, 651, 650, nil, 653, nil, nil, nil, nil, 39, + nil, nil, 32, nil, nil, 55, 56, nil, nil, 57, + nil, 34, nil, nil, nil, 43, nil, nil, 655, nil, + 652, 651, 650, 20, 653, 657, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, 664, 663, 79, 85, + 280, 71, 72, 68, 9, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, 657, 62, 63, 65, 29, + 30, 69, 70, nil, 661, 660, 664, 663, 28, 27, + 26, 95, 94, 96, 97, nil, nil, 19, nil, nil, + nil, nil, nil, 8, 44, nil, 10, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, nil, nil, nil, nil, nil, + nil, nil, nil, 774, nil, 652, 651, 650, nil, 653, + nil, nil, nil, nil, 39, nil, nil, 32, nil, nil, + 55, 56, nil, nil, 57, nil, 34, nil, nil, nil, + 43, nil, nil, 737, nil, 652, 651, 650, 20, 653, + 657, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, 664, 663, 79, 85, 280, 71, 72, 68, 9, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + 657, 62, 63, 65, 29, 30, 69, 70, nil, 661, + 660, 664, 663, 28, 27, 26, 95, 94, 96, 97, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 44, + nil, 10, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, nil, nil, nil, nil, nil, 774, nil, 652, + 651, 650, nil, 653, nil, nil, nil, nil, nil, 39, + nil, nil, 32, nil, nil, 55, 56, nil, nil, 57, + nil, 34, nil, nil, nil, 43, 774, nil, 652, 651, + 650, nil, 653, 20, 657, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, 664, 663, nil, 79, 85, + 280, 71, 72, 68, 9, 54, 59, nil, 80, 60, + 61, nil, nil, 657, 64, nil, 62, 63, 65, 29, + 30, 69, 70, nil, 664, 663, nil, nil, 28, 27, + 26, 95, 94, 96, 97, nil, nil, 19, nil, nil, + nil, nil, nil, 8, 44, nil, 10, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, 231, 235, 240, 241, 242, + 237, 239, 247, 248, 243, 244, nil, -552, -552, nil, + nil, 245, 246, nil, 39, nil, nil, 32, nil, nil, + 55, 56, nil, nil, 57, nil, 34, 228, nil, 234, + 43, 230, 229, 226, 227, 238, 236, 232, 20, 233, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, 280, 71, 72, 68, 9, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 29, 30, 69, 70, nil, nil, + nil, nil, nil, 28, 27, 26, 95, 94, 96, 97, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 44, + nil, 10, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + 231, 235, 240, 241, 242, 237, 239, 247, 248, 243, + 244, nil, -552, -552, nil, nil, 245, 246, nil, 39, + nil, nil, 32, nil, nil, 55, 56, nil, nil, 57, + nil, 34, 228, nil, 234, 43, 230, 229, 226, 227, + 238, 236, 232, 20, 233, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + 280, 71, 72, 68, 9, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 29, + 30, 69, 70, nil, nil, nil, nil, nil, 28, 27, + 26, 95, 94, 96, 97, nil, nil, 19, nil, nil, + nil, nil, nil, 8, 44, nil, 10, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, 231, -552, -552, -552, -552, + 237, 239, nil, nil, -552, -552, nil, nil, nil, nil, + nil, 245, 246, nil, 39, nil, nil, 32, nil, nil, + 55, 56, nil, nil, 57, nil, 34, 228, nil, 234, + 43, 230, 229, 226, 227, 238, 236, 232, 20, 233, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, 280, 71, 72, 68, 9, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 29, 30, 69, 70, nil, nil, + nil, nil, nil, 28, 27, 26, 95, 94, 96, 97, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 44, + nil, 10, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + 231, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 245, 246, nil, 39, + nil, nil, 32, nil, nil, 55, 56, nil, nil, 57, + nil, 34, 228, nil, 234, 43, 230, 229, 226, 227, + nil, nil, 232, 20, 233, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + 280, 71, 72, 68, 9, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 29, + 30, 69, 70, nil, nil, nil, nil, nil, 28, 27, + 26, 95, 94, 96, 97, nil, nil, 19, nil, nil, + nil, nil, nil, 8, 44, nil, 10, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, 231, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 245, 246, nil, 39, nil, nil, 32, nil, nil, + 55, 56, nil, nil, 57, nil, 34, 228, nil, 234, + 43, 230, 229, 226, 227, nil, nil, 232, 20, 233, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, 280, 71, 72, 68, 9, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 29, 30, 69, 70, nil, nil, + nil, nil, nil, 28, 27, 26, 95, 94, 96, 97, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 44, + nil, 10, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + 231, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 245, 246, nil, 39, + nil, nil, 32, nil, nil, 55, 56, nil, nil, 57, + nil, 34, 228, nil, 234, 43, 230, 229, 226, 227, + nil, nil, 232, 20, 233, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + 280, 71, 72, 68, 9, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 29, + 30, 69, 70, nil, nil, nil, nil, nil, 28, 27, + 26, 95, 94, 96, 97, nil, nil, 19, nil, nil, + nil, nil, nil, 8, 44, nil, 10, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, 231, -552, -552, -552, -552, + 237, 239, nil, nil, -552, -552, nil, nil, nil, nil, + nil, 245, 246, nil, 39, nil, nil, 32, nil, nil, + 55, 56, nil, nil, 57, nil, 34, 228, nil, 234, + 43, 230, 229, 226, 227, 238, 236, 232, 20, 233, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, 280, 71, 72, 68, 9, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 29, 30, 69, 70, nil, nil, + nil, nil, nil, 28, 27, 26, 95, 94, 96, 97, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 44, + nil, 10, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + 231, -552, -552, -552, -552, 237, 239, nil, nil, -552, + -552, nil, nil, nil, nil, nil, 245, 246, nil, 39, + nil, nil, 32, nil, nil, 55, 56, nil, nil, 57, + nil, 34, 228, nil, 234, 43, 230, 229, 226, 227, + 238, 236, 232, 20, 233, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + 280, 71, 72, 68, 9, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 29, + 30, 69, 70, nil, nil, nil, nil, nil, 28, 27, + 26, 95, 94, 96, 97, nil, nil, 19, nil, nil, + nil, nil, nil, 8, 44, nil, 10, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, 231, -552, -552, -552, -552, + 237, 239, nil, nil, -552, -552, nil, nil, nil, nil, + nil, 245, 246, nil, 39, nil, nil, 32, nil, nil, + 55, 56, nil, nil, 57, nil, 34, 228, nil, 234, + 43, 230, 229, 226, 227, 238, 236, 232, 20, 233, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, 280, 71, 72, 68, 9, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 29, 30, 69, 70, nil, nil, + nil, nil, nil, 28, 27, 26, 95, 94, 96, 97, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 44, + nil, 10, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + 231, -552, -552, -552, -552, 237, 239, nil, nil, -552, + -552, nil, nil, nil, nil, nil, 245, 246, nil, 39, + nil, nil, 32, nil, nil, 55, 56, nil, nil, 57, + nil, 34, 228, nil, 234, 43, 230, 229, 226, 227, + 238, 236, 232, 20, 233, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + 280, 71, 72, 68, 9, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 29, + 30, 69, 70, nil, nil, nil, nil, nil, 28, 27, + 26, 95, 94, 96, 97, nil, nil, 19, nil, nil, + nil, nil, nil, 8, 44, nil, 10, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, 231, -552, -552, -552, -552, + 237, 239, nil, nil, -552, -552, nil, nil, nil, nil, + nil, 245, 246, nil, 39, nil, nil, 32, nil, nil, + 55, 56, nil, nil, 57, nil, 34, 228, nil, 234, + 43, 230, 229, 226, 227, 238, 236, 232, 20, 233, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, 280, 71, 72, 68, 9, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 29, 30, 69, 70, nil, nil, + nil, nil, nil, 28, 27, 26, 95, 94, 96, 97, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 44, + nil, 10, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + 231, 235, 240, 241, 242, 237, 239, nil, nil, 243, + 244, nil, nil, nil, nil, nil, 245, 246, nil, 39, + nil, nil, 32, nil, nil, 55, 56, nil, nil, 57, + nil, 34, 228, nil, 234, 43, 230, 229, 226, 227, + 238, 236, 232, 20, 233, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + 280, 71, 72, 68, 9, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 29, + 30, 69, 70, nil, nil, nil, nil, nil, 28, 27, + 26, 95, 94, 96, 97, nil, nil, 19, nil, nil, + nil, nil, nil, 8, 44, nil, 10, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, 231, 235, 240, 241, 242, + 237, 239, 247, nil, 243, 244, nil, nil, nil, nil, + nil, 245, 246, nil, 39, nil, nil, 32, nil, nil, + 55, 56, nil, nil, 57, nil, 34, 228, nil, 234, + 43, 230, 229, 226, 227, 238, 236, 232, 20, 233, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, 280, 71, 72, 68, 9, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 29, 30, 69, 70, nil, nil, + nil, nil, nil, 28, 27, 26, 95, 94, 96, 97, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 44, + nil, 10, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + 231, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 245, 246, nil, 39, + nil, nil, 32, nil, nil, 55, 56, nil, nil, 57, + nil, 34, 228, nil, 234, 43, 230, 229, 226, 227, + nil, nil, nil, 20, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + 280, 71, 72, 68, 9, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 29, + 30, 69, 70, nil, nil, nil, nil, nil, 28, 27, + 26, 95, 94, 96, 97, nil, nil, 19, nil, nil, + nil, nil, nil, 8, 44, nil, 10, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, 231, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 245, 246, nil, 39, nil, nil, 32, nil, nil, + 55, 56, nil, nil, 57, nil, 34, 228, nil, 234, + 43, 230, 229, 226, 227, nil, nil, nil, 20, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, 280, 71, 72, 68, 9, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 29, 30, 69, 70, nil, nil, + nil, nil, nil, 28, 27, 26, 95, 94, 96, 97, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 44, + nil, 10, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + 231, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 245, 246, nil, 39, + nil, nil, 32, nil, nil, 55, 56, nil, nil, 57, + nil, 34, 228, nil, nil, 43, 230, 229, 226, 227, + nil, nil, nil, 20, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + 280, 71, 72, 68, 9, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 29, + 30, 69, 70, nil, nil, nil, nil, nil, 28, 27, + 26, 95, 94, 96, 97, nil, nil, 19, nil, nil, + nil, nil, nil, 8, 44, nil, 10, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 39, nil, nil, 32, nil, nil, + 55, 56, nil, nil, 57, nil, 34, nil, nil, nil, + 43, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, 280, 71, 72, 68, 9, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 29, 30, 69, 70, nil, nil, + nil, nil, nil, 28, 27, 26, 95, 94, 96, 97, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 44, + nil, 10, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 39, + nil, nil, 32, nil, nil, 55, 56, nil, nil, 57, + nil, 34, nil, nil, nil, 43, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + 280, 71, 72, 68, 9, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 29, + 30, 69, 70, nil, nil, nil, nil, nil, 28, 27, + 26, 95, 94, 96, 97, nil, nil, 19, nil, nil, + nil, nil, nil, 8, 44, nil, 10, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 39, nil, nil, 32, nil, nil, + 55, 56, nil, nil, 57, nil, 34, nil, nil, nil, + 43, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, 9, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 29, 30, 69, 70, nil, nil, + nil, nil, nil, 28, 27, 26, 95, 94, 96, 97, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 44, + 7, 10, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 39, + nil, nil, 32, nil, nil, 55, 56, nil, nil, 57, + nil, 34, nil, nil, nil, 43, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 71, 72, 68, nil, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 29, + 30, 69, 70, nil, nil, nil, nil, nil, 28, 27, + 26, 95, 94, 96, 97, nil, nil, 223, nil, nil, + nil, nil, nil, nil, 44, nil, nil, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 216, nil, nil, 222, nil, nil, + 55, 56, nil, nil, 57, nil, nil, nil, nil, nil, + 43, nil, nil, nil, nil, nil, nil, nil, 221, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, nil, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 29, 30, 69, 70, nil, nil, + nil, nil, nil, 28, 27, 26, 95, 94, 96, 97, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 44, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + 275, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 216, + nil, nil, 222, nil, nil, 55, 56, nil, nil, 57, + nil, 273, nil, 271, nil, 43, nil, nil, nil, nil, + nil, nil, nil, 221, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 71, 72, 68, nil, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 29, + 30, 69, 70, nil, nil, nil, nil, nil, 28, 27, + 26, 95, 94, 96, 97, nil, nil, 223, nil, nil, + nil, nil, nil, nil, 44, nil, nil, 99, 98, 100, + 89, 53, 91, 90, 92, 275, 93, 101, 102, nil, + 87, 88, 41, 42, 40, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 216, nil, nil, 222, nil, nil, + 55, 56, nil, nil, 57, nil, 273, nil, 271, nil, + 43, nil, nil, nil, nil, nil, nil, nil, 221, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, nil, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 29, 30, 69, 70, nil, nil, + nil, nil, nil, 28, 27, 26, 95, 94, 96, 97, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 44, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + 275, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 216, + nil, nil, 222, nil, nil, 55, 56, nil, nil, 57, + nil, 273, nil, 271, nil, 43, nil, nil, nil, nil, + nil, nil, nil, 221, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 71, 72, 68, nil, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 297, + 298, 69, 70, nil, nil, nil, nil, nil, 293, 294, + 300, 95, 94, 96, 97, nil, nil, 223, nil, nil, + nil, nil, nil, nil, 295, nil, nil, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, nil, 655, 301, 652, 651, 650, nil, 653, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 291, nil, nil, 287, nil, nil, + 55, 56, nil, nil, 57, nil, 286, nil, nil, nil, + 657, 692, nil, nil, nil, nil, nil, nil, nil, 661, + 660, 664, 663, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, nil, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 297, 298, 69, 70, nil, nil, + nil, nil, nil, 293, 294, 300, 95, 94, 96, 97, + nil, nil, 223, nil, nil, nil, nil, 587, nil, 295, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, nil, nil, 301, + 231, 235, 240, 241, 242, 237, 239, 247, 248, 243, + 244, nil, 224, 225, nil, nil, 245, 246, nil, 291, + nil, nil, 222, nil, nil, 55, 56, nil, nil, 57, + nil, nil, 228, nil, 234, nil, 230, 229, 226, 227, + 238, 236, 232, nil, 233, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 249, nil, 303, nil, nil, 59, nil, 80, 71, + 72, 68, nil, 54, nil, nil, nil, 60, 61, nil, + nil, nil, 64, nil, 62, 63, 65, 297, 298, 69, + 70, nil, nil, nil, nil, nil, 293, 294, 300, 95, + 94, 96, 97, nil, nil, 223, nil, nil, nil, nil, + nil, nil, 44, nil, nil, 99, 98, 100, 89, 53, + 91, 90, 92, nil, 93, 101, 102, nil, 87, 88, + 41, 42, 40, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 216, nil, nil, 222, nil, nil, 55, 56, + nil, nil, 57, nil, nil, nil, nil, nil, 43, nil, + nil, nil, nil, nil, nil, nil, 221, nil, nil, nil, + nil, 86, 78, 81, 82, nil, 83, 84, nil, nil, + nil, 79, 85, nil, 71, 72, 68, nil, 54, 59, + nil, 80, 60, 61, nil, nil, nil, 64, nil, 62, + 63, 65, 297, 298, 69, 70, nil, nil, nil, nil, + nil, 293, 294, 300, 95, 94, 96, 97, nil, nil, + 223, nil, nil, nil, nil, nil, nil, 44, nil, nil, + 99, 98, 100, 89, 53, 91, 90, 92, nil, 93, + 101, 102, nil, 87, 88, 41, 42, 40, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 216, nil, nil, + 222, nil, nil, 55, 56, nil, nil, 57, nil, nil, + nil, nil, nil, 43, nil, nil, nil, nil, nil, nil, + nil, 221, nil, nil, nil, nil, 86, 78, 81, 82, + nil, 83, 84, nil, nil, nil, 79, 85, nil, 71, + 72, 68, nil, 54, 59, nil, 80, 60, 61, nil, + nil, nil, 64, nil, 62, 63, 65, 297, 298, 69, + 70, nil, nil, nil, nil, nil, 293, 294, 300, 95, + 94, 96, 97, nil, nil, 223, nil, nil, nil, nil, + nil, nil, 44, nil, nil, 99, 98, 100, 89, 53, + 91, 90, 92, nil, 93, 101, 102, nil, 87, 88, + 41, 42, 40, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 216, nil, nil, 222, nil, nil, 55, 56, + nil, nil, 57, nil, nil, nil, nil, nil, 43, nil, + nil, nil, nil, nil, nil, nil, 221, nil, nil, nil, + nil, 86, 78, 81, 82, nil, 83, 84, nil, nil, + nil, 79, 85, nil, 71, 72, 68, nil, 54, 59, + nil, 80, 60, 61, nil, nil, nil, 64, nil, 62, + 63, 65, 297, 298, 69, 70, nil, nil, nil, nil, + nil, 293, 294, 300, 95, 94, 96, 97, nil, nil, + 223, nil, nil, nil, nil, nil, nil, 44, nil, nil, + 99, 98, 100, 89, 53, 91, 90, 92, 275, 93, + 101, 102, nil, 87, 88, 41, 42, 40, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 216, nil, nil, + 222, nil, nil, 55, 56, nil, nil, 57, nil, 273, + nil, nil, nil, 43, nil, nil, nil, nil, nil, nil, + nil, 221, nil, nil, nil, nil, 86, 78, 81, 82, + nil, 83, 84, nil, nil, nil, 79, 85, nil, 71, + 72, 68, nil, 54, 59, nil, 80, 60, 61, nil, + nil, nil, 64, nil, 62, 63, 65, 297, 298, 69, + 70, nil, nil, nil, nil, nil, 293, 294, 300, 95, + 94, 96, 97, nil, nil, 223, nil, nil, nil, nil, + nil, nil, 44, nil, nil, 99, 98, 100, 89, 53, + 91, 90, 92, 275, 93, 101, 102, nil, 87, 88, + 41, 42, 40, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 216, nil, nil, 222, nil, nil, 55, 56, + nil, nil, 57, nil, nil, nil, nil, nil, 43, nil, + nil, nil, nil, nil, nil, nil, 221, nil, nil, nil, + nil, 86, 78, 81, 82, nil, 83, 84, nil, nil, + nil, 79, 85, nil, 71, 72, 68, nil, 54, 59, + nil, 80, 60, 61, nil, nil, nil, 64, nil, 62, + 63, 65, 29, 30, 69, 70, nil, nil, nil, nil, + nil, 28, 27, 26, 95, 94, 96, 97, nil, nil, + 19, nil, nil, nil, nil, nil, nil, 44, nil, nil, + 99, 98, 100, 89, 53, 91, 90, 92, nil, 93, + 101, 102, nil, 87, 88, 41, 42, 40, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 216, nil, nil, + 222, nil, nil, 55, 56, nil, nil, 57, nil, nil, + nil, nil, nil, 43, nil, nil, nil, nil, nil, nil, + nil, 20, nil, nil, nil, nil, 86, 78, 81, 82, + nil, 83, 84, nil, nil, nil, 79, 85, nil, 71, + 72, 68, nil, 54, 59, nil, 80, 60, 61, nil, + nil, nil, 64, nil, 62, 63, 65, 29, 30, 69, + 70, nil, nil, nil, nil, nil, 28, 27, 26, 95, + 94, 96, 97, nil, nil, 19, nil, nil, nil, nil, + nil, nil, 44, nil, nil, 99, 98, 100, 89, 53, + 91, 90, 92, nil, 93, 101, 102, nil, 87, 88, + 41, 42, 40, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 216, nil, nil, 222, nil, nil, 55, 56, + nil, nil, 57, nil, nil, nil, nil, nil, 43, nil, + nil, nil, nil, nil, nil, nil, 20, nil, nil, nil, + nil, 86, 78, 81, 82, nil, 83, 84, nil, nil, + nil, 79, 85, nil, 71, 72, 68, nil, 54, 59, + nil, 80, 60, 61, nil, nil, nil, 64, nil, 62, + 63, 65, 29, 30, 69, 70, nil, nil, nil, nil, + nil, 28, 27, 26, 95, 94, 96, 97, nil, nil, + 19, nil, nil, nil, nil, nil, nil, 44, nil, nil, + 99, 98, 100, 89, 53, 91, 90, 92, nil, 93, + 101, 102, nil, 87, 88, 41, 42, 40, 231, 235, + 240, 241, 242, 237, 239, 247, 248, 243, 244, nil, + 224, 225, nil, nil, 245, 246, nil, 216, nil, nil, + 222, nil, nil, 55, 56, nil, nil, 57, nil, nil, + 228, nil, 234, 43, 230, 229, 226, 227, 238, 236, + 232, 20, 233, nil, nil, nil, 86, 78, 81, 82, + nil, 83, 84, nil, nil, nil, 79, 85, 107, 249, + nil, nil, nil, 106, 59, nil, 80, 71, 72, 68, + nil, 54, nil, nil, nil, 60, 61, nil, nil, nil, + 64, nil, 62, 63, 65, 297, 298, 69, 70, nil, + nil, nil, nil, nil, 293, 294, 300, 95, 94, 96, + 97, nil, nil, 223, nil, nil, nil, nil, nil, nil, + 295, nil, nil, 99, 98, 100, 89, 53, 91, 90, + 92, nil, 93, 101, 102, nil, 87, 88, nil, 655, + 301, 652, 651, 650, nil, 653, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 336, nil, nil, 32, nil, nil, 55, 56, nil, nil, + 57, nil, 34, nil, nil, nil, 657, 692, nil, nil, + nil, nil, nil, nil, nil, 661, 660, 664, 663, 86, + 78, 81, 82, nil, 83, 84, nil, nil, nil, 79, + 85, nil, 71, 72, 68, nil, 54, 59, nil, 80, + 60, 61, nil, nil, nil, 64, nil, 62, 63, 65, + 297, 298, 69, 70, nil, nil, nil, nil, nil, 293, + 294, 300, 95, 94, 96, 97, nil, nil, 223, nil, + nil, nil, nil, nil, nil, 295, nil, nil, 99, 98, + 100, 341, 53, 91, 90, 342, nil, 93, 101, 102, + nil, 87, 88, nil, nil, 301, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 348, nil, nil, 343, nil, nil, 222, nil, + nil, 55, 56, nil, nil, 57, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 86, 78, 81, 82, nil, 83, + 84, nil, nil, nil, 79, 85, nil, 71, 72, 68, + nil, 54, 59, nil, 80, 60, 61, nil, nil, nil, + 64, nil, 62, 63, 65, 297, 298, 69, 70, nil, + nil, nil, nil, nil, 293, 294, 300, 95, 94, 96, + 97, nil, nil, 223, nil, nil, nil, nil, nil, nil, + 295, nil, nil, 99, 98, 100, 341, 53, 91, 90, + 342, nil, 93, 101, 102, nil, 87, 88, nil, nil, + 301, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 343, nil, nil, 222, nil, nil, 55, 56, nil, nil, + 57, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 86, + 78, 81, 82, nil, 83, 84, nil, nil, nil, 79, + 85, nil, 71, 72, 68, 9, 54, 59, nil, 80, + 60, 61, nil, nil, nil, 64, nil, 62, 63, 65, + 29, 30, 69, 70, nil, nil, nil, nil, nil, 28, + 27, 26, 95, 94, 96, 97, nil, nil, 19, nil, + nil, nil, nil, nil, 8, 44, 7, 10, 99, 98, + 100, 89, 53, 91, 90, 92, nil, 93, 101, 102, + nil, 87, 88, 41, 42, 40, 231, 235, 240, 241, + 242, 237, 239, 247, 248, 243, 244, nil, 224, 225, + nil, nil, 245, 246, nil, 39, nil, nil, 32, nil, + nil, 55, 56, nil, nil, 57, nil, 34, 228, nil, + 234, 43, 230, 229, 226, 227, 238, 236, 232, 20, + 233, nil, nil, nil, 86, 78, 81, 82, nil, 83, + 84, nil, nil, nil, 79, 85, nil, 249, nil, nil, + nil, 374, 59, nil, 80, 71, 72, 68, nil, 54, + nil, nil, nil, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 29, 30, 69, 70, nil, nil, nil, + nil, nil, 28, 27, 26, 95, 94, 96, 97, nil, + nil, 19, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 99, 98, 100, 89, 53, 91, 90, 92, nil, + 93, 101, 102, nil, 87, 88, 41, 42, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 222, nil, nil, 55, 56, nil, nil, 57, nil, + nil, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 71, 72, 68, nil, 54, 59, nil, 80, 60, 61, + nil, nil, nil, 64, nil, 62, 63, 65, 29, 30, + 69, 70, nil, nil, nil, nil, nil, 28, 27, 26, + 95, 94, 96, 97, nil, nil, 19, nil, nil, nil, + nil, nil, nil, 44, nil, nil, 99, 98, 100, 89, + 53, 91, 90, 92, nil, 93, 101, 102, nil, 87, + 88, 41, 42, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 222, nil, nil, 55, + 56, nil, nil, 57, nil, nil, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 86, 78, 81, 82, nil, 83, 84, nil, + nil, nil, 79, 85, nil, 71, 72, 68, nil, 54, + 59, nil, 80, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 29, 30, 69, 70, nil, nil, nil, + nil, nil, 28, 27, 26, 95, 94, 96, 97, nil, + nil, 19, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 99, 98, 100, 89, 53, 91, 90, 92, nil, + 93, 101, 102, nil, 87, 88, 41, 42, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 222, nil, nil, 55, 56, nil, nil, 57, nil, + nil, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 71, 72, 68, nil, 54, 59, nil, 80, 60, 61, + nil, nil, nil, 64, nil, 62, 63, 65, 29, 30, + 69, 70, nil, nil, nil, nil, nil, 28, 27, 26, + 95, 94, 96, 97, nil, nil, 19, nil, nil, nil, + nil, nil, nil, 44, nil, nil, 99, 98, 100, 89, + 53, 91, 90, 92, nil, 93, 101, 102, nil, 87, + 88, 41, 42, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 222, nil, nil, 55, + 56, nil, nil, 57, nil, nil, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 86, 78, 81, 82, nil, 83, 84, nil, + nil, nil, 79, 85, nil, 71, 72, 68, 9, 54, + 59, nil, 80, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 29, 30, 69, 70, nil, nil, nil, + nil, nil, 28, 27, 26, 95, 94, 96, 97, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 44, nil, + 10, 99, 98, 100, 89, 53, 91, 90, 92, nil, + 93, 101, 102, nil, 87, 88, 41, 42, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 39, nil, + nil, 32, nil, nil, 55, 56, nil, nil, 57, nil, + 34, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 71, 72, 68, nil, 54, 59, nil, 80, 60, 61, + nil, nil, nil, 64, nil, 62, 63, 65, 29, 30, + 69, 70, nil, nil, nil, nil, nil, 28, 27, 26, + 95, 94, 96, 97, nil, nil, 223, nil, nil, nil, + nil, nil, nil, 44, nil, nil, 99, 98, 100, 89, + 53, 91, 90, 92, nil, 93, 101, 102, nil, 87, + 88, 41, 42, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 222, nil, nil, 55, + 56, nil, nil, 57, nil, 390, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, + nil, nil, 86, 78, 81, 82, nil, 83, 84, nil, + nil, nil, 79, 85, nil, 71, 72, 68, nil, 54, + 59, nil, 80, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 29, 30, 69, 70, nil, nil, nil, + nil, nil, 28, 27, 26, 95, 94, 96, 97, nil, + nil, 223, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 99, 98, 100, 89, 53, 91, 90, 92, nil, + 93, 101, 102, nil, 87, 88, 41, 42, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 222, nil, nil, 55, 56, nil, nil, 57, nil, + nil, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 221, nil, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 71, 72, 68, nil, 54, 59, nil, 80, 60, 61, + nil, nil, nil, 64, nil, 62, 63, 65, 29, 30, + 69, 70, nil, nil, nil, nil, nil, 28, 27, 26, + 95, 94, 96, 97, nil, nil, 223, nil, nil, nil, + nil, nil, nil, 44, nil, nil, 99, 98, 100, 89, + 53, 91, 90, 92, 275, 93, 101, 102, nil, 87, + 88, 41, 42, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 222, nil, nil, 55, + 56, nil, nil, 57, nil, 273, nil, 271, nil, 43, + nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, + nil, nil, 86, 78, 81, 82, nil, 83, 84, nil, + nil, nil, 79, 85, nil, 71, 72, 68, nil, 54, + 59, nil, 80, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 29, 30, 69, 70, nil, nil, nil, + nil, nil, 28, 27, 26, 95, 94, 96, 97, nil, + nil, 223, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 99, 98, 100, 89, 53, 91, 90, 92, nil, + 93, 101, 102, nil, 87, 88, 41, 42, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 222, nil, nil, 55, 56, nil, nil, 57, nil, + nil, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 221, nil, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 71, 72, 68, nil, 54, 59, nil, 80, 60, 61, + nil, nil, nil, 64, nil, 62, 63, 65, 29, 30, + 69, 70, nil, nil, nil, nil, nil, 28, 27, 26, + 95, 94, 96, 97, nil, nil, 223, nil, nil, nil, + nil, nil, nil, 44, nil, nil, 99, 98, 100, 89, + 53, 91, 90, 92, nil, 93, 101, 102, nil, 87, + 88, 41, 42, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 222, nil, nil, 55, + 56, nil, nil, 57, nil, 390, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, + nil, nil, 86, 78, 81, 82, nil, 83, 84, nil, + nil, nil, 79, 85, nil, 71, 72, 68, nil, 54, + 59, nil, 80, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 29, 30, 69, 70, nil, nil, nil, + nil, nil, 28, 27, 26, 95, 94, 96, 97, nil, + nil, 19, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 99, 98, 100, 89, 53, 91, 90, 92, nil, + 93, 101, 102, nil, 87, 88, 41, 42, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 222, nil, nil, 55, 56, nil, nil, 57, nil, + nil, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 71, 72, 68, nil, 54, 59, nil, 80, 60, 61, + nil, nil, nil, 64, nil, 62, 63, 65, 29, 30, + 69, 70, nil, nil, nil, nil, nil, 28, 27, 26, + 95, 94, 96, 97, nil, nil, 19, nil, nil, nil, + nil, nil, nil, 44, nil, nil, 99, 98, 100, 89, + 53, 91, 90, 92, nil, 93, 101, 102, nil, 87, + 88, 41, 42, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 222, nil, nil, 55, + 56, nil, nil, 57, nil, nil, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 86, 78, 81, 82, nil, 83, 84, nil, + nil, nil, 79, 85, nil, 71, 72, 68, nil, 54, + 59, nil, 80, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 29, 30, 69, 70, nil, nil, nil, + nil, nil, 28, 27, 26, 95, 94, 96, 97, nil, + nil, 19, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 99, 98, 100, 89, 53, 91, 90, 92, nil, + 93, 101, 102, nil, 87, 88, 41, 42, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 222, nil, nil, 55, 56, nil, nil, 57, nil, + nil, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 71, 72, 68, nil, 54, 59, nil, 80, 60, 61, + nil, nil, nil, 64, nil, 62, 63, 65, 29, 30, + 69, 70, nil, nil, nil, nil, nil, 28, 27, 26, + 95, 94, 96, 97, nil, nil, 19, nil, nil, nil, + nil, nil, nil, 44, nil, nil, 99, 98, 100, 89, + 53, 91, 90, 92, nil, 93, 101, 102, nil, 87, + 88, 41, 42, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 222, nil, nil, 55, + 56, nil, nil, 57, nil, nil, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 86, 78, 81, 82, nil, 83, 84, nil, + nil, nil, 79, 85, 211, 71, 72, 68, nil, 54, + 59, nil, 80, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 297, 298, 69, 70, nil, nil, nil, + nil, nil, 293, 294, 300, 95, 94, 96, 97, nil, + nil, 223, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 99, 98, 100, 89, 53, 91, 90, 92, nil, + 93, 101, 102, nil, 87, 88, 41, 42, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 222, nil, nil, 55, 56, nil, nil, 57, nil, + nil, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 221, nil, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 71, 72, 68, nil, 54, 59, nil, 80, 60, 61, + nil, nil, nil, 64, nil, 62, 63, 65, 297, 298, + 69, 70, nil, nil, nil, nil, nil, 293, 294, 300, + 95, 94, 96, 97, nil, nil, 223, nil, nil, nil, + nil, nil, nil, 44, nil, nil, 99, 98, 100, 89, + 53, 91, 90, 92, nil, 93, 101, 102, nil, 87, + 88, 41, 42, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 222, nil, nil, 55, + 56, nil, nil, 57, nil, nil, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, + nil, nil, 86, 78, 81, 82, nil, 83, 84, nil, + nil, nil, 79, 85, nil, 71, 72, 68, nil, 54, + 59, nil, 80, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 297, 298, 69, 70, nil, nil, nil, + nil, nil, 293, 294, 300, 95, 94, 96, 97, nil, + nil, 223, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 99, 98, 100, 89, 53, 91, 90, 92, nil, + 93, 101, 102, nil, 87, 88, 41, 42, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 222, nil, nil, 55, 56, nil, nil, 57, nil, + nil, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 221, nil, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 71, 72, 68, nil, 54, 59, nil, 80, 60, 61, + nil, nil, nil, 64, nil, 62, 63, 65, 297, 298, + 69, 70, nil, nil, nil, nil, nil, 293, 294, 300, + 95, 94, 96, 97, nil, nil, 223, nil, nil, nil, + nil, nil, nil, 44, nil, nil, 99, 98, 100, 89, + 53, 91, 90, 92, nil, 93, 101, 102, nil, 87, + 88, 41, 42, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 222, nil, nil, 55, + 56, nil, nil, 57, nil, nil, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, + nil, nil, 86, 78, 81, 82, nil, 83, 84, nil, + nil, nil, 79, 85, nil, 71, 72, 68, nil, 54, + 59, nil, 80, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 297, 298, 69, 70, nil, nil, nil, + nil, nil, 293, 294, 300, 95, 94, 96, 97, nil, + nil, 223, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 99, 98, 100, 89, 53, 91, 90, 92, nil, + 93, 101, 102, nil, 87, 88, 41, 42, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 222, nil, nil, 55, 56, nil, nil, 57, nil, + nil, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 221, nil, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 71, 72, 68, nil, 54, 59, nil, 80, 60, 61, + nil, nil, nil, 64, nil, 62, 63, 65, 297, 298, + 69, 70, nil, nil, nil, nil, nil, 293, 294, 300, + 95, 94, 96, 97, nil, nil, 223, nil, nil, nil, + nil, nil, nil, 44, nil, nil, 99, 98, 100, 89, + 53, 91, 90, 92, nil, 93, 101, 102, nil, 87, + 88, 41, 42, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 222, nil, nil, 55, + 56, nil, nil, 57, nil, nil, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, + nil, nil, 86, 78, 81, 82, nil, 83, 84, nil, + nil, nil, 79, 85, nil, 71, 72, 68, nil, 54, + 59, nil, 80, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 297, 298, 69, 70, nil, nil, nil, + nil, nil, 293, 294, 300, 95, 94, 96, 97, nil, + nil, 223, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 99, 98, 100, 89, 53, 91, 90, 92, nil, + 93, 101, 102, nil, 87, 88, 41, 42, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 222, nil, nil, 55, 56, nil, nil, 57, nil, + nil, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 221, nil, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 71, 72, 68, nil, 54, 59, nil, 80, 60, 61, + nil, nil, nil, 64, nil, 62, 63, 65, 297, 298, + 69, 70, nil, nil, nil, nil, nil, 293, 294, 300, + 95, 94, 96, 97, nil, nil, 223, nil, nil, nil, + nil, nil, nil, 44, nil, nil, 99, 98, 100, 89, + 53, 91, 90, 92, nil, 93, 101, 102, nil, 87, + 88, 41, 42, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 222, nil, nil, 55, + 56, nil, nil, 57, nil, nil, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, + nil, nil, 86, 78, 81, 82, nil, 83, 84, nil, + nil, nil, 79, 85, nil, 71, 72, 68, nil, 54, + 59, nil, 80, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 297, 298, 69, 70, nil, nil, nil, + nil, nil, 293, 294, 300, 95, 94, 96, 97, nil, + nil, 223, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 99, 98, 100, 89, 53, 91, 90, 92, nil, + 93, 101, 102, nil, 87, 88, 41, 42, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 222, nil, nil, 55, 56, nil, nil, 57, nil, + nil, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 221, nil, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 71, 72, 68, nil, 54, 59, nil, 80, 60, 61, + nil, nil, nil, 64, nil, 62, 63, 65, 297, 298, + 69, 70, nil, nil, nil, nil, nil, 293, 294, 300, + 95, 94, 96, 97, nil, nil, 223, nil, nil, nil, + nil, nil, nil, 44, nil, nil, 99, 98, 100, 89, + 53, 91, 90, 92, nil, 93, 101, 102, nil, 87, + 88, 41, 42, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 222, nil, nil, 55, + 56, nil, nil, 57, nil, nil, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, + nil, nil, 86, 78, 81, 82, nil, 83, 84, nil, + nil, nil, 79, 85, nil, 71, 72, 68, nil, 54, + 59, nil, 80, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 297, 298, 69, 70, nil, nil, nil, + nil, nil, 293, 294, 300, 95, 94, 96, 97, nil, + nil, 223, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 99, 98, 100, 89, 53, 91, 90, 92, nil, + 93, 101, 102, nil, 87, 88, 41, 42, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 222, nil, nil, 55, 56, nil, nil, 57, nil, + nil, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 221, nil, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 71, 72, 68, nil, 54, 59, nil, 80, 60, 61, + nil, nil, nil, 64, nil, 62, 63, 65, 297, 298, + 69, 70, nil, nil, nil, nil, nil, 293, 294, 300, + 95, 94, 96, 97, nil, nil, 223, nil, nil, nil, + nil, nil, nil, 44, nil, nil, 99, 98, 100, 89, + 53, 91, 90, 92, nil, 93, 101, 102, nil, 87, + 88, 41, 42, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 222, nil, nil, 55, + 56, nil, nil, 57, nil, nil, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, + nil, nil, 86, 78, 81, 82, nil, 83, 84, nil, + nil, nil, 79, 85, nil, 71, 72, 68, nil, 54, + 59, nil, 80, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 297, 298, 69, 70, nil, nil, nil, + nil, nil, 293, 294, 300, 95, 94, 96, 97, nil, + nil, 223, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 99, 98, 100, 89, 53, 91, 90, 92, nil, + 93, 101, 102, nil, 87, 88, 41, 42, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 222, nil, nil, 55, 56, nil, nil, 57, nil, + nil, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 221, nil, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 71, 72, 68, nil, 54, 59, nil, 80, 60, 61, + nil, nil, nil, 64, nil, 62, 63, 65, 297, 298, + 69, 70, nil, nil, nil, nil, nil, 293, 294, 300, + 95, 94, 96, 97, nil, nil, 223, nil, nil, nil, + nil, nil, nil, 44, nil, nil, 99, 98, 100, 89, + 53, 91, 90, 92, nil, 93, 101, 102, nil, 87, + 88, 41, 42, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 222, nil, nil, 55, + 56, nil, nil, 57, nil, nil, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, + nil, nil, 86, 78, 81, 82, nil, 83, 84, nil, + nil, nil, 79, 85, nil, 71, 72, 68, nil, 54, + 59, nil, 80, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 297, 298, 69, 70, nil, nil, nil, + nil, nil, 293, 294, 300, 95, 94, 96, 97, nil, + nil, 223, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 99, 98, 100, 89, 53, 91, 90, 92, nil, + 93, 101, 102, nil, 87, 88, 41, 42, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 222, nil, nil, 55, 56, nil, nil, 57, nil, + nil, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 221, nil, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 71, 72, 68, nil, 54, 59, nil, 80, 60, 61, + nil, nil, nil, 64, nil, 62, 63, 65, 297, 298, + 69, 70, nil, nil, nil, nil, nil, 293, 294, 300, + 95, 94, 96, 97, nil, nil, 223, nil, nil, nil, + nil, nil, nil, 44, nil, nil, 99, 98, 100, 89, + 53, 91, 90, 92, nil, 93, 101, 102, nil, 87, + 88, 41, 42, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 222, nil, nil, 55, + 56, nil, nil, 57, nil, nil, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, + nil, nil, 86, 78, 81, 82, nil, 83, 84, nil, + nil, nil, 79, 85, nil, 71, 72, 68, nil, 54, + 59, nil, 80, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 297, 298, 69, 70, nil, nil, nil, + nil, nil, 293, 294, 300, 95, 94, 96, 97, nil, + nil, 223, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 99, 98, 100, 89, 53, 91, 90, 92, nil, + 93, 101, 102, nil, 87, 88, 41, 42, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 222, nil, nil, 55, 56, nil, nil, 57, nil, + nil, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 221, nil, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 71, 72, 68, nil, 54, 59, nil, 80, 60, 61, + nil, nil, nil, 64, nil, 62, 63, 65, 297, 298, + 69, 70, nil, nil, nil, nil, nil, 293, 294, 300, + 95, 94, 96, 97, nil, nil, 223, nil, nil, nil, + nil, nil, nil, 44, nil, nil, 99, 98, 100, 89, + 53, 91, 90, 92, nil, 93, 101, 102, nil, 87, + 88, 41, 42, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 222, nil, nil, 55, + 56, nil, nil, 57, nil, nil, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, + nil, nil, 86, 78, 81, 82, nil, 83, 84, nil, + nil, nil, 79, 85, nil, 71, 72, 68, nil, 54, + 59, nil, 80, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 297, 298, 69, 70, nil, nil, nil, + nil, nil, 293, 294, 300, 95, 94, 96, 97, nil, + nil, 223, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 99, 98, 100, 89, 53, 91, 90, 92, nil, + 93, 101, 102, nil, 87, 88, 41, 42, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 222, nil, nil, 55, 56, nil, nil, 57, nil, + nil, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 221, nil, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 71, 72, 68, nil, 54, 59, nil, 80, 60, 61, + nil, nil, nil, 64, nil, 62, 63, 65, 297, 298, + 69, 70, nil, nil, nil, nil, nil, 293, 294, 300, + 95, 94, 96, 97, nil, nil, 223, nil, nil, nil, + nil, nil, nil, 44, nil, nil, 99, 98, 100, 89, + 53, 91, 90, 92, nil, 93, 101, 102, nil, 87, + 88, 41, 42, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 222, nil, nil, 55, + 56, nil, nil, 57, nil, nil, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, + nil, nil, 86, 78, 81, 82, nil, 83, 84, nil, + nil, nil, 79, 85, nil, 71, 72, 68, nil, 54, + 59, nil, 80, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 297, 298, 69, 70, nil, nil, nil, + nil, nil, 293, 294, 300, 95, 94, 96, 97, nil, + nil, 223, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 99, 98, 100, 89, 53, 91, 90, 92, nil, + 93, 101, 102, nil, 87, 88, 41, 42, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 222, nil, nil, 55, 56, nil, nil, 57, nil, + nil, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 221, nil, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 71, 72, 68, nil, 54, 59, nil, 80, 60, 61, + nil, nil, nil, 64, nil, 62, 63, 65, 297, 298, + 69, 70, nil, nil, nil, nil, nil, 293, 294, 300, + 95, 94, 96, 97, nil, nil, 223, nil, nil, nil, + nil, nil, nil, 44, nil, nil, 99, 98, 100, 89, + 53, 91, 90, 92, nil, 93, 101, 102, nil, 87, + 88, 41, 42, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 222, nil, nil, 55, + 56, nil, nil, 57, nil, nil, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, + nil, nil, 86, 78, 81, 82, nil, 83, 84, nil, + nil, nil, 79, 85, nil, 71, 72, 68, nil, 54, + 59, nil, 80, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 297, 298, 69, 70, nil, nil, nil, + nil, nil, 293, 294, 300, 95, 94, 96, 97, nil, + nil, 223, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 99, 98, 100, 89, 53, 91, 90, 92, nil, + 93, 101, 102, nil, 87, 88, 41, 42, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 222, nil, nil, 55, 56, nil, nil, 57, nil, + nil, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 221, nil, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 71, 72, 68, nil, 54, 59, nil, 80, 60, 61, + nil, nil, nil, 64, nil, 62, 63, 65, 297, 298, + 69, 70, nil, nil, nil, nil, nil, 293, 294, 300, + 95, 94, 96, 97, nil, nil, 223, nil, nil, nil, + nil, nil, nil, 44, nil, nil, 99, 98, 100, 89, + 53, 91, 90, 92, nil, 93, 101, 102, nil, 87, + 88, 41, 42, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 222, nil, nil, 55, + 56, nil, nil, 57, nil, nil, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, + nil, nil, 86, 78, 81, 82, nil, 83, 84, nil, + nil, nil, 79, 85, nil, 71, 72, 68, nil, 54, + 59, nil, 80, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 297, 298, 69, 70, nil, nil, nil, + nil, nil, 293, 294, 300, 95, 94, 96, 97, nil, + nil, 223, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 99, 98, 100, 89, 53, 91, 90, 92, nil, + 93, 101, 102, nil, 87, 88, 41, 42, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 222, nil, nil, 55, 56, nil, nil, 57, nil, + nil, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 221, nil, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 71, 72, 68, nil, 54, 59, nil, 80, 60, 61, + nil, nil, nil, 64, nil, 62, 63, 65, 297, 298, + 69, 70, nil, nil, nil, nil, nil, 293, 294, 300, + 95, 94, 96, 97, nil, nil, 223, nil, nil, nil, + nil, nil, nil, 44, nil, nil, 99, 98, 100, 89, + 53, 91, 90, 92, nil, 93, 101, 102, nil, 87, + 88, 41, 42, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 222, nil, nil, 55, + 56, nil, nil, 57, nil, nil, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, + nil, nil, 86, 78, 81, 82, nil, 83, 84, nil, + nil, nil, 79, 85, nil, 71, 72, 68, nil, 54, + 59, nil, 80, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 297, 298, 69, 70, nil, nil, nil, + nil, nil, 293, 294, 300, 95, 94, 96, 97, nil, + nil, 223, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 99, 98, 100, 89, 53, 91, 90, 92, nil, + 93, 101, 102, nil, 87, 88, 41, 42, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 222, nil, nil, 55, 56, nil, nil, 57, nil, + nil, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 221, nil, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 71, 72, 68, nil, 54, 59, nil, 80, 60, 61, + nil, nil, nil, 64, nil, 62, 63, 65, 29, 30, + 69, 70, nil, nil, nil, nil, nil, 28, 27, 26, + 95, 94, 96, 97, nil, nil, 223, nil, nil, nil, + nil, nil, nil, 44, nil, nil, 99, 98, 100, 89, + 53, 91, 90, 92, 275, 93, 101, 102, nil, 87, + 88, 41, 42, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 222, nil, nil, 55, + 56, nil, nil, 57, nil, 273, nil, 271, nil, 43, + nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, + nil, nil, 86, 78, 81, 82, nil, 83, 84, nil, + nil, nil, 79, 85, nil, 71, 72, 68, nil, 54, + 59, nil, 80, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 29, 30, 69, 70, nil, nil, nil, + nil, nil, 28, 27, 26, 95, 94, 96, 97, nil, + nil, 223, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 99, 98, 100, 89, 53, 91, 90, 92, 275, + 93, 101, 102, nil, 87, 88, 41, 42, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 222, nil, nil, 55, 56, nil, nil, 57, nil, + 273, nil, 271, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 221, nil, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 71, 72, 68, nil, 54, 59, nil, 80, 60, 61, + nil, nil, nil, 64, nil, 62, 63, 65, 29, 30, + 69, 70, nil, nil, nil, nil, nil, 28, 27, 26, + 95, 94, 96, 97, nil, nil, 223, nil, nil, nil, + nil, nil, nil, 44, nil, nil, 99, 98, 100, 89, + 53, 91, 90, 92, 275, 93, 101, 102, nil, 87, + 88, 41, 42, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 222, nil, nil, 55, + 56, nil, nil, 57, nil, 273, nil, 271, nil, 43, + nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, + nil, nil, 86, 78, 81, 82, nil, 83, 84, nil, + nil, nil, 79, 85, 211, 71, 72, 68, nil, 54, + 59, nil, 80, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 297, 298, 69, 70, nil, nil, nil, + nil, nil, 293, 294, 300, 95, 94, 96, 97, nil, + nil, 223, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 99, 98, 100, 89, 53, 91, 90, 92, nil, + 93, 101, 102, nil, 87, 88, 41, 42, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 222, nil, nil, 55, 56, nil, nil, 57, nil, + nil, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 221, nil, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 71, 72, 68, nil, 54, 59, nil, 80, 60, 61, + nil, nil, nil, 64, nil, 62, 63, 65, 297, 298, + 69, 70, nil, nil, nil, nil, nil, 293, 294, 300, + 95, 94, 96, 97, nil, nil, 223, nil, nil, nil, + nil, nil, nil, 44, nil, nil, 99, 98, 100, 89, + 53, 91, 90, 92, nil, 93, 101, 102, nil, 87, + 88, 41, 42, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 222, nil, nil, 55, + 56, nil, nil, 57, nil, nil, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, + nil, nil, 86, 78, 81, 82, nil, 83, 84, nil, + nil, nil, 79, 85, nil, 71, 72, 68, nil, 54, + 59, nil, 80, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 297, 298, 69, 70, nil, nil, nil, + nil, nil, 293, 294, 300, 95, 94, 96, 97, nil, + nil, 223, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 99, 98, 100, 89, 53, 91, 90, 92, nil, + 93, 101, 102, nil, 87, 88, 41, 42, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 222, nil, nil, 55, 56, nil, nil, 57, nil, + nil, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 221, nil, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 71, 72, 68, 9, 54, 59, nil, 80, 60, 61, + nil, nil, nil, 64, nil, 62, 63, 65, 29, 30, + 69, 70, nil, nil, nil, nil, nil, 28, 27, 26, + 95, 94, 96, 97, nil, nil, 19, nil, nil, nil, + nil, nil, 8, 44, nil, 10, 99, 98, 100, 89, + 53, 91, 90, 92, nil, 93, 101, 102, nil, 87, + 88, 41, 42, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 39, nil, nil, 32, nil, nil, 55, + 56, nil, nil, 57, nil, 34, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 86, 78, 81, 82, nil, 83, 84, nil, + nil, nil, 79, 85, nil, 71, 72, 68, nil, 54, + 59, nil, 80, 60, 61, nil, nil, nil, 64, nil, + 62, 63, 65, 297, 298, 69, 70, nil, nil, nil, + nil, nil, 293, 294, 300, 95, 94, 96, 97, nil, + nil, 223, nil, nil, nil, nil, nil, nil, 295, nil, + nil, 99, 98, 100, 89, 53, 91, 90, 92, nil, + 93, 101, 102, nil, 87, 88, nil, nil, 301, 231, + 235, 240, 241, 242, 237, 239, 247, 248, 243, 244, + nil, 224, 225, nil, nil, 245, 246, nil, 291, nil, + nil, 222, nil, nil, 55, 56, nil, nil, 57, nil, + nil, 228, nil, 234, nil, 230, 229, 226, 227, 238, + 236, 232, nil, 233, nil, nil, nil, 86, 78, 81, + 82, nil, 83, 84, nil, nil, nil, 79, 85, nil, + 249, nil, 487, nil, nil, 59, nil, 80, 71, 72, + 68, nil, 54, nil, nil, nil, 60, 61, nil, nil, + nil, 64, nil, 62, 63, 65, 297, 298, 69, 70, + nil, nil, nil, nil, nil, 293, 294, 300, 95, 94, + 96, 97, nil, nil, 223, nil, nil, nil, nil, nil, + nil, 295, nil, nil, 99, 98, 100, 89, 53, 91, + 90, 92, nil, 93, 101, 102, nil, 87, 88, nil, + nil, 301, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 291, nil, nil, 287, nil, nil, 55, 56, nil, + nil, 57, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 86, 78, 81, 82, nil, 83, 84, nil, nil, nil, + 79, 85, nil, 71, 72, 68, nil, 54, 59, nil, + 80, 60, 61, nil, nil, nil, 64, nil, 62, 63, + 65, 297, 298, 69, 70, nil, nil, nil, nil, nil, + 293, 294, 300, 95, 94, 96, 97, nil, nil, 223, + nil, nil, nil, nil, nil, nil, 44, nil, nil, 99, + 98, 100, 89, 53, 91, 90, 92, nil, 93, 101, + 102, nil, 87, 88, 41, 42, 40, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 216, nil, nil, 222, + 505, nil, 55, 56, nil, nil, 57, nil, nil, nil, + nil, nil, 43, nil, nil, nil, nil, nil, nil, nil, + 221, nil, nil, nil, nil, 86, 78, 81, 82, nil, + 83, 84, nil, nil, nil, 79, 85, nil, 71, 72, + 68, nil, 54, 59, nil, 80, 60, 61, nil, nil, + nil, 64, nil, 62, 63, 65, 29, 30, 69, 70, + nil, nil, nil, nil, nil, 28, 27, 26, 95, 94, + 96, 97, nil, nil, 19, nil, nil, nil, nil, nil, + nil, 44, nil, nil, 99, 98, 100, 89, 53, 91, + 90, 92, nil, 93, 101, 102, nil, 87, 88, 41, + 42, 40, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 216, nil, nil, 222, nil, nil, 55, 56, nil, + nil, 57, nil, nil, nil, nil, nil, 43, nil, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, nil, + 86, 78, 81, 82, nil, 83, 84, nil, nil, nil, + 79, 85, nil, 71, 72, 68, nil, 54, 59, nil, + 80, 60, 61, nil, nil, nil, 64, nil, 62, 63, + 65, 29, 30, 69, 70, nil, nil, nil, nil, nil, + 28, 27, 26, 95, 94, 96, 97, nil, nil, 19, + nil, nil, nil, nil, nil, nil, 44, nil, nil, 99, + 98, 100, 89, 53, 91, 90, 92, nil, 93, 101, + 102, nil, 87, 88, 41, 42, 40, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 216, nil, nil, 222, + nil, nil, 55, 56, nil, nil, 57, nil, nil, nil, + nil, nil, 43, nil, nil, nil, nil, nil, nil, nil, + 20, nil, nil, nil, nil, 86, 78, 81, 82, nil, + 83, 84, nil, nil, nil, 79, 85, nil, 71, 72, + 68, nil, 54, 59, nil, 80, 60, 61, nil, nil, + nil, 64, nil, 62, 63, 65, 29, 30, 69, 70, + nil, nil, nil, nil, nil, 28, 27, 26, 95, 94, + 96, 97, nil, nil, 19, nil, nil, nil, nil, nil, + nil, 44, nil, nil, 99, 98, 100, 89, 53, 91, + 90, 92, nil, 93, 101, 102, nil, 87, 88, 41, + 42, 40, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 216, nil, nil, 222, nil, nil, 55, 56, nil, + nil, 57, nil, nil, nil, nil, nil, 43, nil, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, nil, + 86, 78, 81, 82, nil, 83, 84, nil, nil, nil, + 79, 85, nil, 71, 72, 68, nil, 54, 59, nil, + 80, 60, 61, nil, nil, nil, 64, nil, 62, 63, + 65, 29, 30, 69, 70, nil, nil, nil, nil, nil, + 28, 27, 26, 95, 94, 96, 97, nil, nil, 19, + nil, nil, nil, nil, nil, nil, 44, nil, nil, 99, + 98, 100, 89, 53, 91, 90, 92, nil, 93, 101, + 102, nil, 87, 88, 41, 42, 40, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 216, nil, nil, 222, + nil, nil, 55, 56, nil, nil, 57, nil, nil, nil, + nil, nil, 43, nil, nil, nil, nil, nil, nil, nil, + 20, nil, nil, nil, nil, 86, 78, 81, 82, nil, + 83, 84, nil, nil, nil, 79, 85, nil, 71, 72, + 68, nil, 54, 59, nil, 80, 60, 61, nil, nil, + nil, 64, nil, 62, 63, 65, 29, 30, 69, 70, + nil, nil, nil, nil, nil, 28, 27, 26, 95, 94, + 96, 97, nil, nil, 19, nil, nil, nil, nil, nil, + nil, 44, nil, nil, 99, 98, 100, 89, 53, 91, + 90, 92, nil, 93, 101, 102, nil, 87, 88, 41, + 42, 40, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 216, nil, nil, 222, nil, nil, 55, 56, nil, + nil, 57, nil, nil, nil, nil, nil, 43, nil, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, nil, + 86, 78, 81, 82, nil, 83, 84, nil, nil, nil, + 79, 85, nil, 71, 72, 68, nil, 54, 59, nil, + 80, 60, 61, nil, nil, nil, 64, nil, 62, 63, + 65, 297, 298, 69, 70, nil, nil, nil, nil, nil, + 293, 294, 300, 95, 94, 96, 97, nil, nil, 223, + nil, nil, nil, nil, nil, nil, 44, nil, nil, 99, + 98, 100, 89, 53, 91, 90, 92, nil, 93, 101, + 102, nil, 87, 88, 41, 42, 40, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 216, nil, nil, 222, + nil, nil, 55, 56, nil, nil, 57, nil, nil, nil, + nil, nil, 43, nil, nil, nil, nil, nil, nil, nil, + 221, nil, nil, nil, nil, 86, 78, 81, 82, nil, + 83, 84, nil, nil, nil, 79, 85, nil, 71, 72, + 68, nil, 54, 59, nil, 80, 60, 61, nil, nil, + nil, 64, nil, 62, 63, 65, 29, 30, 69, 70, + nil, nil, nil, nil, nil, 28, 27, 26, 95, 94, + 96, 97, nil, nil, 223, nil, nil, nil, nil, nil, + nil, 44, nil, nil, 99, 98, 100, 89, 53, 91, + 90, 92, 275, 93, 101, 102, nil, 87, 88, 41, + 42, 40, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 216, nil, nil, 222, nil, nil, 55, 56, nil, + nil, 57, nil, 273, nil, 271, nil, 43, nil, nil, + nil, nil, nil, nil, nil, 221, nil, nil, nil, nil, + 86, 78, 81, 82, nil, 83, 84, nil, nil, nil, + 79, 85, nil, 71, 72, 68, nil, 54, 59, nil, + 80, 60, 61, nil, nil, nil, 64, nil, 62, 63, + 65, 297, 298, 69, 70, nil, nil, nil, nil, nil, + 293, 294, 300, 95, 94, 96, 97, nil, nil, 223, + nil, nil, nil, nil, nil, nil, 44, nil, nil, 99, + 98, 100, 89, 53, 91, 90, 92, nil, 93, 101, + 102, nil, 87, 88, 41, 42, 40, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 216, nil, nil, 222, + nil, nil, 55, 56, nil, nil, 57, nil, nil, nil, + nil, nil, 43, nil, nil, nil, nil, nil, nil, nil, + 221, nil, nil, nil, nil, 86, 78, 81, 82, nil, + 83, 84, nil, nil, nil, 79, 85, nil, 71, 72, + 68, nil, 54, 59, nil, 80, 60, 61, nil, nil, + nil, 64, nil, 62, 63, 65, 297, 298, 69, 70, + nil, nil, nil, nil, nil, 293, 294, 300, 95, 94, + 96, 97, nil, nil, 223, nil, nil, nil, nil, nil, + nil, 44, nil, nil, 99, 98, 100, 89, 53, 91, + 90, 92, nil, 93, 101, 102, nil, 87, 88, 41, + 42, 40, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 216, nil, nil, 222, nil, nil, 55, 56, nil, + nil, 57, nil, nil, nil, nil, nil, 43, nil, nil, + nil, nil, nil, nil, nil, 221, nil, nil, nil, nil, + 86, 78, 81, 82, nil, 83, 84, nil, nil, nil, + 79, 85, nil, 71, 72, 68, nil, 54, 59, nil, + 80, 60, 61, nil, nil, nil, 64, nil, 62, 63, + 65, 297, 298, 69, 70, nil, nil, nil, nil, nil, + 293, 294, 300, 95, 94, 96, 97, nil, nil, 223, + nil, nil, nil, nil, nil, nil, 44, nil, nil, 99, + 98, 100, 89, 53, 91, 90, 92, nil, 93, 101, + 102, nil, 87, 88, 41, 42, 40, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 216, nil, nil, 222, + nil, nil, 55, 56, nil, nil, 57, nil, nil, nil, + nil, nil, 43, nil, nil, nil, nil, nil, nil, nil, + 221, nil, nil, nil, nil, 86, 78, 81, 82, nil, + 83, 84, nil, nil, nil, 79, 85, nil, 71, 72, + 68, nil, 54, 59, nil, 80, 60, 61, nil, nil, + nil, 64, nil, 62, 63, 65, 297, 298, 69, 70, + nil, nil, nil, nil, nil, 293, 294, 300, 95, 94, + 96, 97, nil, nil, 223, nil, nil, nil, nil, nil, + nil, 44, nil, nil, 99, 98, 100, 89, 53, 91, + 90, 92, 275, 93, 101, 102, nil, 87, 88, 41, + 42, 40, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 216, nil, nil, 222, nil, nil, 55, 56, nil, + nil, 57, nil, 613, nil, 271, nil, 43, nil, nil, + nil, nil, nil, nil, nil, 221, nil, nil, nil, nil, + 86, 78, 81, 82, nil, 83, 84, nil, nil, nil, + 79, 85, nil, 71, 72, 68, nil, 54, 59, nil, + 80, 60, 61, nil, nil, nil, 64, nil, 62, 63, + 65, 297, 298, 69, 70, nil, nil, nil, nil, nil, + 293, 294, 300, 95, 94, 96, 97, nil, nil, 223, + nil, nil, nil, nil, nil, nil, 44, nil, nil, 99, + 98, 100, 89, 53, 91, 90, 92, 275, 93, 101, + 102, nil, 87, 88, 41, 42, 40, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 216, nil, nil, 222, + nil, nil, 55, 56, nil, nil, 57, nil, nil, nil, + 271, nil, 43, nil, nil, nil, nil, nil, nil, nil, + 221, nil, nil, nil, nil, 86, 78, 81, 82, nil, + 83, 84, nil, nil, nil, 79, 85, nil, 71, 72, + 68, nil, 54, 59, nil, 80, 60, 61, nil, nil, + nil, 64, nil, 62, 63, 65, 297, 298, 69, 70, + nil, nil, nil, nil, nil, 293, 294, 300, 95, 94, + 96, 97, nil, nil, 223, nil, nil, nil, nil, nil, + nil, 44, nil, nil, 99, 98, 100, 89, 53, 91, + 90, 92, nil, 93, 101, 102, nil, 87, 88, 41, + 42, 40, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 216, nil, nil, 222, nil, nil, 55, 56, nil, + nil, 57, nil, nil, nil, nil, nil, 43, nil, nil, + nil, nil, nil, nil, nil, 221, nil, nil, nil, nil, + 86, 78, 81, 82, nil, 83, 84, nil, nil, nil, + 79, 85, nil, 71, 72, 68, 9, 54, 59, nil, + 80, 60, 61, nil, nil, nil, 64, nil, 62, 63, + 65, 29, 30, 69, 70, nil, nil, nil, nil, nil, + 28, 27, 26, 95, 94, 96, 97, nil, nil, 19, + nil, nil, nil, nil, nil, 8, 44, nil, 10, 99, + 98, 100, 89, 53, 91, 90, 92, nil, 93, 101, + 102, nil, 87, 88, 41, 42, 40, 231, 235, 240, + 241, 242, 237, 239, 247, 248, 243, 244, nil, 224, + 225, nil, nil, 245, 246, nil, 39, nil, nil, 32, + nil, nil, 55, 56, nil, nil, 57, nil, 34, 228, + nil, 234, 43, 230, 229, 226, 227, 238, 236, 232, + 20, 233, nil, nil, nil, 86, 78, 81, 82, nil, + 83, 84, nil, nil, nil, 79, 85, 211, 249, nil, + nil, nil, 374, 59, nil, 80, 71, 72, 68, nil, + 54, nil, nil, nil, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 297, 298, 69, 70, nil, nil, + nil, nil, nil, 293, 294, 300, 95, 94, 96, 97, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 295, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, nil, nil, 301, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 291, + nil, nil, 287, nil, nil, 55, 56, nil, nil, 57, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 71, 72, 68, nil, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 29, + 30, 69, 70, nil, nil, nil, nil, nil, 28, 27, + 26, 95, 94, 96, 97, nil, nil, 223, nil, nil, + nil, nil, nil, nil, 44, nil, nil, 99, 98, 100, + 89, 53, 91, 90, 92, 275, 93, 101, 102, nil, + 87, 88, 41, 42, 40, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 216, nil, nil, 222, nil, nil, + 55, 56, nil, nil, 57, nil, 273, nil, 271, nil, + 43, nil, nil, nil, nil, nil, nil, nil, 221, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, nil, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 297, 298, 69, 70, nil, nil, + nil, nil, nil, 293, 294, 300, 95, 94, 96, 97, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 295, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, nil, nil, 301, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 291, + nil, nil, 287, nil, nil, 55, 56, nil, nil, 57, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 71, 72, 68, nil, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 297, + 298, 69, 70, nil, nil, nil, nil, nil, 293, 294, + 300, 95, 94, 96, 97, nil, nil, 223, nil, nil, + nil, nil, nil, nil, 44, nil, nil, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 216, nil, nil, 222, nil, nil, + 55, 56, nil, nil, 57, nil, nil, nil, nil, nil, + 43, nil, nil, nil, nil, nil, nil, nil, 221, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, nil, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 297, 298, 69, 70, nil, nil, + nil, nil, nil, 293, 294, 300, 95, 94, 96, 97, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 44, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 216, + nil, nil, 222, nil, nil, 55, 56, nil, nil, 57, + nil, nil, nil, nil, nil, 43, nil, nil, nil, nil, + nil, nil, nil, 221, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 71, 72, 68, nil, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 297, + 298, 69, 70, nil, nil, nil, nil, nil, 293, 294, + 300, 95, 94, 96, 97, nil, nil, 223, nil, nil, + nil, nil, nil, nil, 44, nil, nil, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 216, nil, nil, 222, nil, nil, + 55, 56, nil, nil, 57, nil, nil, nil, nil, nil, + 43, nil, nil, nil, nil, nil, nil, nil, 221, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, nil, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 29, 30, 69, 70, nil, nil, + nil, nil, nil, 28, 27, 26, 95, 94, 96, 97, + nil, nil, 19, nil, nil, nil, nil, nil, nil, 44, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 216, + nil, nil, 222, nil, nil, 55, 56, nil, nil, 57, + nil, nil, nil, nil, nil, 43, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 71, 72, 68, nil, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 297, + 298, 69, 70, nil, nil, nil, nil, nil, 293, 294, + 300, 95, 94, 96, 97, nil, nil, 223, nil, nil, + nil, nil, nil, nil, 44, nil, nil, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 216, nil, nil, 222, nil, nil, + 55, 56, nil, nil, 57, nil, 390, nil, nil, nil, + 43, nil, nil, nil, nil, nil, nil, nil, 221, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, nil, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 297, 298, 69, 70, nil, nil, + nil, nil, nil, 293, 294, 300, 95, 94, 96, 97, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 44, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + 275, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 216, + nil, nil, 222, nil, nil, 55, 56, nil, nil, 57, + nil, 613, nil, nil, nil, 43, nil, nil, nil, nil, + nil, nil, nil, 221, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 71, 72, 68, nil, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 297, + 298, 69, 70, nil, nil, nil, nil, nil, 293, 294, + 300, 95, 94, 96, 97, nil, nil, 223, nil, nil, + nil, nil, nil, nil, 44, nil, nil, 99, 98, 100, + 89, 53, 91, 90, 92, 275, 93, 101, 102, nil, + 87, 88, 41, 42, 40, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 216, nil, nil, 222, nil, nil, + 55, 56, nil, nil, 57, nil, nil, nil, nil, nil, + 43, nil, nil, nil, nil, nil, nil, nil, 221, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, nil, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 297, 298, 69, 70, nil, nil, + nil, nil, nil, 293, 294, 300, 95, 94, 96, 97, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 44, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 216, + nil, nil, 222, nil, nil, 55, 56, nil, nil, 57, + nil, 273, nil, nil, nil, 43, nil, nil, nil, nil, + nil, nil, nil, 221, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 71, 72, 68, nil, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 29, + 30, 69, 70, nil, nil, nil, nil, nil, 28, 27, + 26, 95, 94, 96, 97, nil, nil, 223, nil, nil, + nil, nil, nil, nil, 44, nil, nil, 99, 98, 100, + 89, 53, 91, 90, 92, 275, 93, 101, 102, nil, + 87, 88, 41, 42, 40, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 216, nil, nil, 222, nil, nil, + 55, 56, nil, nil, 57, nil, 273, nil, 271, nil, + 43, nil, nil, nil, nil, nil, nil, nil, 221, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, nil, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 29, 30, 69, 70, nil, nil, + nil, nil, nil, 28, 27, 26, 95, 94, 96, 97, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 44, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + 275, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 216, + nil, nil, 222, nil, nil, 55, 56, nil, nil, 57, + nil, 273, nil, 271, nil, 43, nil, nil, nil, nil, + nil, nil, nil, 221, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 71, 72, 68, nil, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 29, + 30, 69, 70, nil, nil, nil, nil, nil, 28, 27, + 26, 95, 94, 96, 97, nil, nil, 19, nil, nil, + nil, nil, nil, nil, 44, nil, nil, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 216, nil, nil, 222, nil, nil, + 55, 56, nil, nil, 57, nil, nil, nil, nil, nil, + 43, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, nil, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 297, 298, 69, 70, nil, nil, + nil, nil, nil, 293, 294, 300, 95, 94, 96, 97, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 44, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 216, + nil, nil, 222, nil, nil, 55, 56, nil, nil, 57, + nil, 708, nil, nil, nil, 43, nil, nil, nil, nil, + nil, nil, nil, 221, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 71, 72, 68, nil, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 297, + 298, 69, 70, nil, nil, nil, nil, nil, 293, 294, + 300, 95, 94, 96, 97, nil, nil, 223, nil, nil, + nil, nil, nil, nil, 44, nil, nil, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 216, nil, nil, 222, nil, nil, + 55, 56, nil, nil, 57, nil, nil, nil, nil, nil, + 43, nil, nil, nil, nil, nil, nil, nil, 221, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, nil, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 297, 298, 69, 70, nil, nil, + nil, nil, nil, 293, 294, 300, 95, 94, 96, 97, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 44, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + 275, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 216, + nil, nil, 222, nil, nil, 55, 56, nil, nil, 57, + nil, 613, nil, 271, nil, 43, nil, nil, nil, nil, + nil, nil, nil, 221, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 71, 72, 68, nil, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 297, + 298, 69, 70, nil, nil, nil, nil, nil, 293, 294, + 300, 95, 94, 96, 97, nil, nil, 223, nil, nil, + nil, nil, nil, nil, 44, nil, nil, 99, 98, 100, + 89, 53, 91, 90, 92, 275, 93, 101, 102, nil, + 87, 88, 41, 42, 40, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 216, nil, nil, 222, nil, nil, + 55, 56, nil, nil, 57, nil, nil, nil, 271, nil, + 43, nil, nil, nil, nil, nil, nil, nil, 221, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, nil, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 29, 30, 69, 70, nil, nil, + nil, nil, nil, 28, 27, 26, 95, 94, 96, 97, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 44, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 216, + nil, nil, 222, nil, nil, 55, 56, nil, nil, 57, + nil, nil, nil, nil, nil, 43, nil, nil, nil, nil, + nil, nil, nil, 221, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 71, 72, 68, nil, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 29, + 30, 69, 70, nil, nil, nil, nil, nil, 28, 27, + 26, 95, 94, 96, 97, nil, nil, 223, nil, nil, + nil, nil, nil, nil, 44, nil, nil, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 216, nil, nil, 222, nil, nil, + 55, 56, nil, nil, 57, nil, nil, nil, nil, nil, + 43, nil, nil, nil, nil, nil, nil, nil, 221, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, nil, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 29, 30, 69, 70, nil, nil, + nil, nil, nil, 28, 27, 26, 95, 94, 96, 97, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 44, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 216, + nil, nil, 222, nil, nil, 55, 56, nil, nil, 57, + nil, nil, nil, nil, nil, 43, nil, nil, nil, nil, + nil, nil, nil, 221, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 71, 72, 68, nil, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 29, + 30, 69, 70, nil, nil, nil, nil, nil, 28, 27, + 26, 95, 94, 96, 97, nil, nil, 223, nil, nil, + nil, nil, nil, nil, 44, nil, nil, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 216, nil, nil, 222, nil, nil, + 55, 56, nil, nil, 57, nil, nil, nil, nil, nil, + 43, nil, nil, nil, nil, nil, nil, nil, 221, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, nil, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 29, 30, 69, 70, nil, nil, + nil, nil, nil, 28, 27, 26, 95, 94, 96, 97, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 44, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 216, + nil, nil, 222, nil, nil, 55, 56, nil, nil, 57, + nil, nil, nil, nil, nil, 43, nil, nil, nil, nil, + nil, nil, nil, 221, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 71, 72, 68, nil, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 297, + 298, 69, 70, nil, nil, nil, nil, nil, 293, 294, + 300, 95, 94, 96, 97, nil, nil, 223, nil, nil, + nil, nil, nil, nil, 44, nil, nil, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 216, nil, nil, 222, nil, nil, + 55, 56, nil, nil, 57, nil, nil, nil, nil, nil, + 43, nil, nil, nil, nil, nil, nil, nil, 221, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, nil, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 297, 298, 69, 70, nil, nil, + nil, nil, nil, 293, 294, 300, 95, 94, 96, 97, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 44, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 216, + nil, nil, 222, nil, nil, 55, 56, nil, nil, 57, + nil, nil, nil, nil, nil, 43, nil, nil, nil, nil, + nil, nil, nil, 221, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 71, 72, 68, nil, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 297, + 298, 69, 70, nil, nil, nil, nil, nil, 293, 294, + 300, 95, 94, 96, 97, nil, nil, 223, nil, nil, + nil, nil, nil, nil, 295, nil, nil, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, nil, nil, 301, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 291, nil, nil, 287, nil, nil, + 55, 56, nil, nil, 57, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, nil, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 297, 298, 69, 70, nil, nil, + nil, nil, nil, 293, 294, 300, 95, 94, 96, 97, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 295, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, nil, nil, 301, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 291, + nil, nil, 287, nil, nil, 55, 56, nil, nil, 57, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 71, 72, 68, nil, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 29, + 30, 69, 70, nil, nil, nil, nil, nil, 28, 27, + 26, 95, 94, 96, 97, nil, nil, 19, nil, nil, + nil, nil, nil, nil, 44, nil, nil, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 216, nil, nil, 222, nil, nil, + 55, 56, nil, nil, 57, nil, nil, nil, nil, nil, + 43, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, nil, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 297, 298, 69, 70, nil, nil, + nil, nil, nil, 293, 294, 300, 95, 94, 96, 97, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 44, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 216, + nil, nil, 222, nil, nil, 55, 56, nil, nil, 57, + nil, nil, nil, nil, nil, 43, nil, nil, nil, nil, + nil, nil, nil, 221, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 71, 72, 68, nil, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 29, + 30, 69, 70, nil, nil, nil, nil, nil, 28, 27, + 26, 95, 94, 96, 97, nil, nil, 223, nil, nil, + nil, nil, nil, nil, 44, nil, nil, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 216, nil, nil, 222, nil, nil, + 55, 56, nil, nil, 57, nil, nil, nil, nil, nil, + 43, nil, nil, nil, nil, nil, nil, nil, 221, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, nil, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 297, 298, 69, 70, nil, nil, + nil, nil, nil, 293, 294, 300, 95, 94, 96, 97, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 44, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 216, + nil, nil, 222, nil, nil, 55, 56, nil, nil, 57, + nil, nil, nil, nil, nil, 43, nil, nil, nil, nil, + nil, nil, nil, 221, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 71, 72, 68, nil, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 297, + 298, 69, 70, nil, nil, nil, nil, nil, 293, 294, + 300, 95, 94, 96, 97, nil, nil, 223, nil, nil, + nil, nil, nil, nil, 44, nil, nil, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 216, nil, nil, 222, nil, nil, + 55, 56, nil, nil, 57, nil, nil, nil, nil, nil, + 43, nil, nil, nil, nil, nil, nil, nil, 221, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, nil, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 297, 298, 69, 70, nil, nil, + nil, nil, nil, 293, 294, 300, 95, 94, 96, 97, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 44, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 216, + nil, nil, 222, nil, nil, 55, 56, nil, nil, 57, + nil, nil, nil, nil, nil, 43, nil, nil, nil, nil, + nil, nil, nil, 221, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 71, 72, 68, nil, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 297, + 298, 69, 70, nil, nil, nil, nil, nil, 293, 294, + 300, 95, 94, 96, 97, nil, nil, 223, nil, nil, + nil, nil, nil, nil, 44, nil, nil, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 216, nil, nil, 222, nil, nil, + 55, 56, nil, nil, 57, nil, nil, nil, nil, nil, + 43, nil, nil, nil, nil, nil, nil, nil, 221, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, nil, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 297, 298, 69, 70, nil, nil, + nil, nil, nil, 293, 294, 300, 95, 94, 96, 97, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 44, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 216, + nil, nil, 222, nil, nil, 55, 56, nil, nil, 57, + nil, nil, nil, nil, nil, 43, nil, nil, nil, nil, + nil, nil, nil, 221, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 71, 72, 68, nil, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 297, + 298, 69, 70, nil, nil, nil, nil, nil, 293, 294, + 300, 95, 94, 96, 97, nil, nil, 223, nil, nil, + nil, nil, nil, nil, 295, nil, nil, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, nil, nil, 301, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 827, nil, nil, 222, nil, nil, + 55, 56, nil, nil, 57, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, nil, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 297, 298, 69, 70, nil, nil, + nil, nil, nil, 293, 294, 300, 95, 94, 96, 97, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 44, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 216, + nil, nil, 222, nil, nil, 55, 56, nil, nil, 57, + nil, nil, nil, nil, nil, 43, nil, nil, nil, nil, + nil, nil, nil, 221, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 71, 72, 68, nil, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 29, + 30, 69, 70, nil, nil, nil, nil, nil, 28, 27, + 26, 95, 94, 96, 97, nil, nil, 19, nil, nil, + nil, nil, nil, nil, 44, nil, nil, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, 41, 42, 40, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 216, nil, nil, 222, nil, nil, + 55, 56, nil, nil, 57, nil, nil, nil, nil, nil, + 43, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, nil, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 297, 298, 69, 70, nil, nil, + nil, nil, nil, 293, 294, 300, 95, 94, 96, 97, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 44, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 216, + nil, nil, 222, nil, nil, 55, 56, nil, nil, 57, + nil, 613, nil, nil, nil, 43, nil, nil, nil, nil, + nil, nil, nil, 221, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 71, 72, 68, nil, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 297, + 298, 69, 70, nil, nil, nil, nil, nil, 293, 294, + 300, 95, 94, 96, 97, nil, nil, 223, nil, nil, + nil, nil, nil, nil, 44, nil, nil, 99, 98, 100, + 89, 53, 91, 90, 92, 275, 93, 101, 102, nil, + 87, 88, 41, 42, 40, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 216, nil, nil, 222, nil, nil, + 55, 56, nil, nil, 57, nil, nil, nil, 271, nil, + 43, nil, nil, nil, nil, nil, nil, nil, 221, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, nil, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 297, 298, 69, 70, nil, nil, + nil, nil, nil, 293, 294, 300, 95, 94, 96, 97, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 44, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + nil, 93, 101, 102, nil, 87, 88, 41, 42, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 216, + nil, nil, 222, nil, nil, 55, 56, nil, nil, 57, + nil, nil, nil, nil, nil, 43, nil, nil, nil, nil, + nil, nil, nil, 221, nil, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 71, 72, 68, nil, 54, 59, nil, 80, 60, + 61, nil, nil, nil, 64, nil, 62, 63, 65, 297, + 298, 69, 70, nil, nil, nil, nil, nil, 293, 294, + 300, 95, 94, 96, 97, nil, nil, 223, nil, nil, + nil, nil, nil, nil, 295, nil, nil, 99, 98, 100, + 89, 53, 91, 90, 92, nil, 93, 101, 102, nil, + 87, 88, nil, nil, 301, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 871, nil, nil, 222, nil, nil, + 55, 56, nil, nil, 57, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 86, 78, 81, 82, nil, 83, 84, + nil, nil, nil, 79, 85, nil, 71, 72, 68, nil, + 54, 59, nil, 80, 60, 61, nil, nil, nil, 64, + nil, 62, 63, 65, 29, 30, 69, 70, nil, nil, + nil, nil, nil, 28, 27, 26, 95, 94, 96, 97, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 44, + nil, nil, 99, 98, 100, 89, 53, 91, 90, 92, + 275, 93, 101, 102, nil, 87, 88, 41, 42, 40, + 231, 235, 240, 241, 242, 237, 239, 247, 248, 243, + 244, nil, 224, 225, nil, nil, 245, 246, nil, 216, + nil, nil, 222, nil, nil, 55, 56, nil, nil, 57, + nil, 273, 228, 271, 234, 43, 230, 229, 226, 227, + 238, 236, 232, 221, 233, nil, nil, nil, 86, 78, + 81, 82, nil, 83, 84, nil, nil, nil, 79, 85, + nil, 249, -398, nil, nil, nil, 59, nil, 80, -398, + -398, -398, nil, nil, -398, -398, -398, nil, -398, nil, + nil, nil, nil, nil, nil, nil, nil, -398, -398, -398, + nil, nil, nil, nil, nil, nil, nil, nil, -398, -398, + nil, -398, -398, -398, -398, -398, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, -398, -398, + -398, -398, -398, -398, -398, -398, -398, -398, -398, -398, + -398, -398, nil, nil, -398, -398, -398, nil, nil, -398, + nil, 255, -398, nil, nil, -398, -398, nil, -398, nil, + -398, nil, -398, nil, -398, -398, -398, -398, -398, -398, + -398, -288, -398, -398, -398, nil, nil, nil, -288, -288, + -288, nil, nil, -288, -288, -288, nil, -288, -398, -398, + nil, -398, nil, -398, nil, nil, nil, -288, -288, nil, + nil, nil, nil, nil, nil, nil, nil, -288, -288, nil, + -288, -288, -288, -288, -288, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, -288, -288, -288, + -288, -288, -288, -288, -288, -288, -288, -288, -288, -288, + -288, nil, nil, -288, -288, -288, nil, nil, -288, nil, + 264, -288, nil, nil, -288, -288, nil, -288, nil, -288, + nil, -288, nil, -288, -288, -288, -288, -288, -288, -288, + -243, -288, nil, -288, nil, nil, nil, -243, -243, -243, + nil, nil, -243, -243, -243, nil, -243, -288, -288, nil, + -288, nil, -288, nil, nil, -243, -243, -243, nil, nil, + nil, nil, nil, nil, nil, nil, -243, -243, nil, -243, + -243, -243, -243, -243, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, -243, -243, -243, -243, + -243, -243, -243, -243, -243, -243, -243, -243, -243, -243, + nil, nil, -243, -243, -243, nil, nil, -243, nil, 255, + -243, nil, nil, -243, -243, nil, -243, nil, -243, nil, + -243, nil, -243, -243, -243, -243, -243, -243, -243, -243, + -243, -243, -243, nil, nil, nil, -243, -243, -243, nil, + nil, -243, -243, -243, nil, -243, -243, -243, nil, -243, + nil, -243, nil, nil, nil, -243, nil, nil, nil, nil, + nil, nil, nil, nil, nil, -243, -243, nil, -243, -243, + -243, -243, -243, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, -243, nil, nil, nil, nil, nil, + nil, -243, -243, -243, nil, nil, -243, -243, -243, nil, + -243, nil, nil, nil, nil, nil, -243, nil, nil, nil, + -243, nil, nil, -243, nil, nil, nil, nil, 255, -243, + -243, -243, nil, -243, -243, -243, -243, -243, nil, nil, + nil, nil, nil, 398, 402, nil, nil, 399, nil, nil, + nil, -243, nil, nil, nil, 151, 152, nil, 148, 130, + 131, 132, 139, 136, 138, -243, nil, 133, 134, nil, + -243, -243, 153, 154, 140, 141, nil, nil, -243, nil, + nil, 255, nil, 255, -243, nil, nil, nil, nil, 145, + 144, nil, 129, 150, 147, 146, 142, 143, 137, 135, + 127, 149, 128, nil, nil, 155, -243, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + -243, nil, nil, nil, nil, -243, 166, 177, 167, 190, + 163, 183, 173, 172, 193, 194, 188, 171, 170, 165, + 191, 195, 196, 175, 164, 178, 182, 184, 176, 169, + nil, nil, nil, 185, 192, 187, 186, 179, 189, 174, + 162, 181, 180, nil, nil, nil, nil, nil, 161, 168, + 159, 160, 156, 157, 158, 118, 120, 117, nil, 119, + nil, nil, nil, nil, nil, nil, nil, 151, 152, nil, + 148, 130, 131, 132, 139, 136, 138, nil, nil, 133, + 134, nil, nil, nil, 153, 154, 140, 141, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 145, 144, nil, 129, 150, 147, 146, 142, 143, + 137, 135, 127, 149, 128, nil, nil, 155, 86, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 85, + 166, 177, 167, 190, 163, 183, 173, 172, 193, 194, + 188, 171, 170, 165, 191, 195, 196, 175, 164, 178, + 182, 184, 176, 169, nil, nil, nil, 185, 192, 187, + 186, 179, 189, 174, 162, 181, 180, nil, nil, nil, + nil, nil, 161, 168, 159, 160, 156, 157, 158, 118, + 120, nil, nil, 119, nil, nil, nil, nil, nil, nil, + nil, 151, 152, nil, 148, 130, 131, 132, 139, 136, + 138, nil, nil, 133, 134, nil, nil, nil, 153, 154, + 140, 141, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 145, 144, nil, 129, 150, + 147, 146, 142, 143, 137, 135, 127, 149, 128, nil, + nil, 155, 86, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 85, 166, 177, 167, 190, 163, 183, + 173, 172, 193, 194, 188, 171, 170, 165, 191, 195, + 196, 175, 164, 178, 182, 184, 176, 169, nil, nil, + nil, 185, 192, 187, 186, 179, 189, 174, 162, 181, + 180, nil, nil, nil, nil, nil, 161, 168, 159, 160, + 156, 157, 158, 118, 120, nil, nil, 119, nil, nil, + nil, nil, nil, nil, nil, 151, 152, nil, 148, 130, + 131, 132, 139, 136, 138, nil, nil, 133, 134, nil, + nil, nil, 153, 154, 140, 141, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 145, + 144, nil, 129, 150, 147, 146, 142, 143, 137, 135, + 127, 149, 128, nil, nil, 155, 86, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 85, 166, 177, + 167, 190, 163, 183, 173, 172, 193, 194, 188, 171, + 170, 165, 191, 195, 196, 175, 164, 178, 182, 184, + 176, 169, nil, nil, nil, 185, 192, 187, 186, 179, + 189, 174, 162, 181, 180, nil, nil, nil, nil, nil, + 161, 168, 159, 160, 156, 157, 158, 118, 120, nil, + nil, 119, nil, nil, nil, nil, nil, nil, nil, 151, + 152, nil, 148, 130, 131, 132, 139, 136, 138, nil, + nil, 133, 134, nil, nil, nil, 153, 154, 140, 141, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 145, 144, nil, 129, 150, 147, 146, + 142, 143, 137, 135, 127, 149, 128, nil, nil, 155, + 86, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 85, 166, 177, 167, 190, 163, 183, 173, 172, + 193, 194, 188, 171, 170, 165, 191, 195, 196, 175, + 164, 178, 182, 184, 176, 169, nil, nil, nil, 185, + 192, 187, 359, 358, 360, 357, 162, 181, 180, nil, + nil, nil, nil, nil, 161, 168, 159, 160, 354, 355, + 356, 352, 120, 91, 90, 353, nil, 93, nil, nil, + nil, nil, nil, 151, 152, nil, 148, 130, 131, 132, + 139, 136, 138, nil, nil, 133, 134, nil, nil, nil, + 153, 154, 140, 141, nil, nil, nil, nil, nil, 364, + nil, nil, nil, nil, nil, nil, nil, 145, 144, nil, + 129, 150, 147, 146, 142, 143, 137, 135, 127, 149, + 128, nil, nil, 155, 166, 177, 167, 190, 163, 183, + 173, 172, 193, 194, 188, 171, 170, 165, 191, 195, + 196, 175, 164, 178, 182, 184, 176, 169, nil, nil, + nil, 185, 192, 187, 186, 179, 189, 174, 162, 181, + 180, nil, nil, nil, nil, nil, 161, 168, 159, 160, + 156, 157, 158, 118, 120, nil, nil, 119, nil, nil, + nil, nil, nil, nil, nil, 151, 152, nil, 148, 130, + 131, 132, 139, 136, 138, nil, nil, 133, 134, nil, + nil, nil, 153, 154, 140, 141, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 145, + 144, nil, 129, 150, 147, 146, 142, 143, 137, 135, + 127, 149, 128, 405, 409, 155, nil, 404, nil, nil, + nil, nil, nil, nil, nil, 151, 152, nil, 148, 130, + 131, 132, 139, 136, 138, nil, nil, 133, 134, nil, + nil, nil, 153, 154, 140, 141, nil, nil, nil, nil, + nil, 255, nil, nil, nil, nil, nil, nil, nil, 145, + 144, nil, 129, 150, 147, 146, 142, 143, 137, 135, + 127, 149, 128, 460, 402, 155, nil, 461, nil, nil, + nil, nil, nil, nil, nil, 151, 152, nil, 148, 130, + 131, 132, 139, 136, 138, nil, nil, 133, 134, nil, + nil, nil, 153, 154, 140, 141, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 145, + 144, nil, 129, 150, 147, 146, 142, 143, 137, 135, + 127, 149, 128, 460, 402, 155, nil, 461, nil, nil, + nil, nil, nil, nil, nil, 151, 152, nil, 148, 130, + 131, 132, 139, 136, 138, nil, nil, 133, 134, nil, + nil, nil, 153, 154, 140, 141, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 145, + 144, nil, 129, 150, 147, 146, 142, 143, 137, 135, + 127, 149, 128, 590, 402, 155, nil, 591, nil, nil, + nil, nil, nil, nil, nil, 151, 152, nil, 148, 130, + 131, 132, 139, 136, 138, nil, nil, 133, 134, nil, + nil, nil, 153, 154, 140, 141, nil, nil, nil, nil, + nil, 255, nil, nil, nil, nil, nil, nil, nil, 145, + 144, nil, 129, 150, 147, 146, 142, 143, 137, 135, + 127, 149, 128, 592, 409, 155, nil, 593, nil, nil, + nil, nil, nil, nil, nil, 151, 152, nil, 148, 130, + 131, 132, 139, 136, 138, nil, nil, 133, 134, nil, + nil, nil, 153, 154, 140, 141, nil, nil, nil, nil, + nil, 255, nil, nil, nil, nil, nil, nil, nil, 145, + 144, nil, 129, 150, 147, 146, 142, 143, 137, 135, + 127, 149, 128, 622, 402, 155, nil, 623, nil, nil, + nil, nil, nil, nil, nil, 151, 152, nil, 148, 130, + 131, 132, 139, 136, 138, nil, nil, 133, 134, nil, + nil, nil, 153, 154, 140, 141, nil, nil, nil, nil, + nil, 255, nil, nil, nil, nil, nil, nil, nil, 145, + 144, nil, 129, 150, 147, 146, 142, 143, 137, 135, + 127, 149, 128, 625, 409, 155, nil, 626, nil, nil, + nil, nil, nil, nil, nil, 151, 152, nil, 148, 130, + 131, 132, 139, 136, 138, nil, nil, 133, 134, nil, + nil, nil, 153, 154, 140, 141, nil, nil, nil, nil, + nil, 255, nil, nil, nil, nil, nil, nil, nil, 145, + 144, nil, 129, 150, 147, 146, 142, 143, 137, 135, + 127, 149, 128, 590, 402, 155, nil, 591, nil, nil, + nil, nil, nil, nil, nil, 151, 152, nil, 148, 130, + 131, 132, 139, 136, 138, nil, nil, 133, 134, nil, + nil, nil, 153, 154, 140, 141, nil, nil, nil, nil, + nil, 255, nil, nil, nil, nil, nil, nil, nil, 145, + 144, nil, 129, 150, 147, 146, 142, 143, 137, 135, + 127, 149, 128, 592, 409, 155, nil, 593, nil, nil, + nil, nil, nil, nil, nil, 151, 152, nil, 148, 130, + 131, 132, 139, 136, 138, nil, nil, 133, 134, nil, + nil, nil, 153, 154, 140, 141, nil, nil, nil, nil, + nil, 255, nil, nil, nil, nil, nil, nil, nil, 145, + 144, nil, 129, 150, 147, 146, 142, 143, 137, 135, + 127, 149, 128, 677, 402, 155, nil, 678, nil, nil, + nil, nil, nil, nil, nil, 151, 152, nil, 148, 130, + 131, 132, 139, 136, 138, nil, nil, 133, 134, nil, + nil, nil, 153, 154, 140, 141, nil, nil, nil, nil, + nil, 255, nil, nil, nil, nil, nil, nil, nil, 145, + 144, nil, 129, 150, 147, 146, 142, 143, 137, 135, + 127, 149, 128, 679, 409, 155, nil, 680, nil, nil, + nil, nil, nil, nil, nil, 151, 152, nil, 148, 130, + 131, 132, 139, 136, 138, nil, nil, 133, 134, nil, + nil, nil, 153, 154, 140, 141, nil, nil, nil, nil, + nil, 255, nil, nil, nil, nil, nil, nil, nil, 145, + 144, nil, 129, 150, 147, 146, 142, 143, 137, 135, + 127, 149, 128, 682, 409, 155, nil, 683, nil, nil, + nil, nil, nil, nil, nil, 151, 152, nil, 148, 130, + 131, 132, 139, 136, 138, nil, nil, 133, 134, nil, + nil, nil, 153, 154, 140, 141, nil, nil, nil, nil, + nil, 255, nil, nil, nil, nil, nil, nil, nil, 145, + 144, nil, 129, 150, 147, 146, 142, 143, 137, 135, + 127, 149, 128, 460, 402, 155, nil, 461, nil, nil, + nil, nil, nil, nil, nil, 151, 152, nil, 148, 130, + 131, 132, 139, 136, 138, nil, nil, 133, 134, nil, + nil, nil, 153, 154, 140, 141, nil, nil, nil, nil, + nil, 255, nil, nil, nil, nil, nil, nil, nil, 145, + 144, nil, 129, 150, 147, 146, 142, 143, 137, 135, + 127, 149, 128, 917, 402, 155, nil, 918, nil, nil, + nil, nil, nil, nil, nil, 151, 152, nil, 148, 130, + 131, 132, 139, 136, 138, nil, nil, 133, 134, nil, + nil, nil, 153, 154, 140, 141, nil, nil, nil, nil, + nil, 255, nil, nil, nil, nil, nil, nil, nil, 145, + 144, nil, 129, 150, 147, 146, 142, 143, 137, 135, + 127, 149, 128, 919, 409, 155, nil, 920, nil, nil, + nil, nil, nil, nil, nil, 151, 152, nil, 148, 130, + 131, 132, 139, 136, 138, nil, nil, 133, 134, nil, + nil, nil, 153, 154, 140, 141, nil, nil, nil, nil, + nil, 255, nil, nil, nil, nil, nil, nil, nil, 145, + 144, nil, 129, 150, 147, 146, 142, 143, 137, 135, + 127, 149, 128, 939, 409, 155, nil, 938, nil, nil, + nil, nil, nil, nil, nil, 151, 152, nil, 148, 130, + 131, 132, 139, 136, 138, nil, nil, 133, 134, nil, + nil, nil, 153, 154, 140, 141, nil, nil, nil, nil, + nil, 255, nil, nil, nil, nil, nil, nil, nil, 145, + 144, nil, 129, 150, 147, 146, 142, 143, 137, 135, + 127, 149, 128, nil, nil, 155, 231, 235, 240, 241, + 242, 237, 239, 247, 248, 243, 244, nil, 224, 225, + nil, nil, 245, 246, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 228, nil, + 234, nil, 230, 229, 226, 227, 238, 236, 232, nil, + 233, nil, 231, 235, 240, 241, 242, 237, 239, 247, + 248, 243, 244, nil, 224, 225, nil, 249, 245, 246, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 228, nil, 234, nil, 230, 229, + 226, 227, 238, 236, 232, nil, 233, nil, 231, 235, + 240, 241, 242, 237, 239, 247, 248, 243, 244, nil, + 224, 225, nil, 249, 245, 246, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 228, nil, 234, nil, 230, 229, 226, 227, 238, 236, + 232, nil, 233, nil, 231, 235, 240, 241, 242, 237, + 239, 247, 248, 243, 244, nil, 224, 225, nil, 249, + 245, 246, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 228, nil, 234, nil, + 230, 229, 226, 227, 238, 236, 232, nil, 233, nil, + 231, 235, 240, 241, 242, 237, 239, 247, 248, 243, + 244, nil, 224, 225, nil, 249, 245, 246, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 228, nil, 234, nil, 230, 229, 226, 227, + 238, 236, 232, nil, 233, nil, 231, 235, 240, 241, + 242, 237, 239, 247, 248, 243, 244, nil, 224, 225, + nil, 249, 245, 246, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 228, nil, + 234, nil, 230, 229, 226, 227, 238, 236, 232, nil, + 233, nil, 231, 235, 240, 241, 242, 237, 239, 247, + 248, 243, 244, nil, 224, 225, nil, 249, 245, 246, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 228, nil, 234, nil, 230, 229, + 226, 227, 238, 236, 232, nil, 233, nil, 231, 235, + 240, 241, 242, 237, 239, 247, 248, 243, 244, nil, + 224, 225, nil, 249, 245, 246, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 228, nil, 234, nil, 230, 229, 226, 227, 238, 236, + 232, nil, 233, nil, 231, 235, 240, 241, 242, 237, + 239, 247, 248, 243, 244, nil, 224, 225, nil, 249, + 245, 246, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 228, nil, 234, nil, + 230, 229, 226, 227, 238, 236, 232, nil, 233, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 249 ] + +racc_action_check = [ + 89, 0, 0, 0, 0, 0, 0, 89, 89, 89, + 0, 0, 89, 89, 89, 0, 89, 0, 0, 0, + 0, 0, 0, 0, 89, 58, 89, 89, 89, 0, + 0, 0, 0, 0, 0, 0, 89, 89, 0, 89, + 89, 89, 89, 89, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 347, 0, 0, 0, + 326, 0, 0, 0, 0, 0, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 1, 19, 89, 89, 89, 0, 89, 89, 0, 333, + 89, 0, 0, 89, 89, 0, 89, 0, 89, 370, + 89, 0, 89, 89, 89, 89, 89, 89, 89, 0, + 89, 58, 89, 334, 0, 0, 0, 0, 19, 0, + 0, 854, 337, 854, 0, 0, 89, 89, 89, 89, + 92, 89, 0, 89, 0, 89, 532, 92, 92, 92, + 214, 15, 92, 92, 92, 524, 92, 343, 327, 622, + 7, 343, 675, 24, 92, 434, 92, 92, 92, 643, + 24, 347, 370, 17, 17, 677, 92, 92, 525, 92, + 92, 92, 92, 92, 326, 753, 849, 917, 918, 326, + 678, 347, 544, 544, 15, 940, 347, 434, 3, 214, + 15, 434, 434, 3, 333, 787, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 458, 10, 92, 92, 92, 622, 92, 92, 334, 12, + 92, 919, 623, 92, 92, 215, 92, 337, 92, 13, + 92, 788, 92, 92, 92, 92, 92, 92, 92, 404, + 92, 532, 92, 16, 458, 524, 404, 404, 404, 467, + 524, 622, 404, 404, 622, 404, 92, 92, 92, 92, + 622, 92, 327, 92, 643, 92, 675, 327, 525, 675, + 677, 675, 544, 525, 215, 404, 404, 544, 404, 404, + 404, 404, 404, 467, 22, 678, 25, 679, 623, 753, + 849, 917, 918, 680, 753, 849, 917, 918, 919, 940, + 787, 40, 40, 36, 940, 404, 404, 404, 404, 404, + 404, 404, 404, 404, 404, 404, 404, 404, 404, 422, + 422, 404, 404, 404, 623, 404, 37, 623, 39, 404, + 217, 788, 404, 623, 428, 919, 788, 404, 44, 404, + 919, 404, 404, 404, 404, 404, 404, 404, 405, 404, + 25, 404, 679, 550, 550, 405, 405, 405, 680, 633, + 633, 405, 405, 590, 405, 404, 404, 468, 404, 37, + 404, 296, 25, 405, 404, 37, 605, 746, 317, 217, + 617, 317, 103, 428, 405, 405, 617, 405, 405, 405, + 405, 405, 679, 773, 197, 773, 773, 773, 680, 773, + 892, 468, 892, 892, 892, 216, 892, 218, 278, 422, + 605, 219, 590, 278, 405, 405, 405, 405, 405, 405, + 405, 405, 405, 405, 405, 405, 405, 405, 223, 746, + 405, 405, 405, 561, 405, 296, 746, 352, 405, 591, + 254, 405, 728, 550, 352, 746, 405, 38, 405, 633, + 405, 405, 405, 405, 405, 405, 405, 296, 405, 405, + 405, 366, 305, 746, 268, 353, 269, 341, 342, 354, + 272, 773, 353, 592, 405, 405, 354, 405, 892, 405, + 592, 592, 592, 405, 281, 592, 592, 592, 591, 592, + 38, 728, 301, 301, 561, 561, 38, 355, 592, 592, + 592, 592, 117, 561, 355, 305, 625, 117, 117, 592, + 592, 305, 592, 592, 592, 592, 592, 283, 318, 341, + 342, 318, 366, 366, 366, 367, 341, 342, 368, 330, + 356, 341, 342, 369, 330, 341, 342, 356, 284, 592, + 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, + 592, 592, 592, 341, 342, 592, 592, 592, 625, 592, + 592, 371, 285, 592, 398, 625, 592, 592, 682, 592, + 625, 592, 291, 592, 625, 592, 592, 592, 592, 592, + 592, 592, 294, 592, 592, 592, 367, 367, 367, 368, + 368, 368, 625, 295, 369, 369, 369, 300, 399, 592, + 592, 592, 592, 593, 592, 302, 592, 398, 592, 573, + 593, 593, 593, 398, 306, 593, 593, 593, 307, 593, + 682, 14, 371, 371, 371, 453, 357, 682, 14, 593, + 593, 593, 682, 357, 310, 321, 682, 14, 321, 593, + 593, 399, 593, 593, 593, 593, 593, 399, 358, 45, + 325, 325, 573, 359, 682, 358, 45, 453, 573, 360, + 359, 453, 453, 453, 453, 45, 360, 509, 509, 593, + 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, + 593, 593, 593, 76, 213, 593, 593, 593, 288, 593, + 593, 213, 76, 593, 313, 288, 593, 593, 314, 593, + 213, 593, 76, 593, 288, 593, 593, 593, 593, 593, + 593, 593, 319, 593, 435, 593, 320, 644, 362, 644, + 644, 644, 543, 644, 322, 362, 331, 543, 687, 593, + 593, 593, 593, 687, 593, 332, 593, 336, 593, 32, + 32, 32, 32, 32, 32, 338, 435, 693, 32, 32, + 435, 435, 693, 32, 644, 32, 32, 32, 32, 32, + 32, 32, 380, 644, 644, 644, 644, 32, 32, 32, + 32, 32, 32, 32, 554, 554, 32, 386, 554, 554, + 554, 417, 32, 32, 388, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 391, 32, 32, 32, 394, 32, + 32, 32, 32, 32, 417, 417, 417, 417, 417, 417, + 417, 417, 417, 417, 417, 289, 417, 417, 290, 396, + 417, 417, 289, 32, 642, 290, 32, 642, 397, 32, + 32, 289, 406, 32, 290, 32, 417, 414, 417, 32, + 417, 417, 417, 417, 417, 417, 417, 32, 417, 666, + 666, 424, 32, 32, 32, 32, 436, 32, 32, 454, + 437, 292, 32, 32, 438, 417, 53, 417, 292, 439, + 32, 465, 32, 53, 53, 53, 469, 292, 53, 53, + 53, 598, 53, 598, 598, 598, 482, 598, 931, 931, + 483, 454, 53, 53, 53, 454, 454, 454, 454, 486, + 488, 493, 53, 53, 497, 53, 53, 53, 53, 53, + 846, 506, 846, 846, 846, 308, 846, 657, 598, 657, + 657, 657, 308, 657, 521, 526, 527, 598, 598, 598, + 598, 308, 53, 53, 53, 53, 53, 53, 53, 53, + 53, 53, 53, 53, 53, 53, 558, 846, 53, 53, + 53, 335, 564, 53, 657, 570, 53, 574, 335, 53, + 53, 598, 53, 657, 53, 579, 53, 335, 53, 53, + 53, 53, 53, 53, 53, 345, 53, 584, 53, 594, + 492, 596, 345, 610, 612, 619, 621, 492, 624, 627, + 628, 345, 53, 53, 53, 53, 492, 53, 631, 53, + 54, 54, 54, 54, 54, 54, 632, 634, 535, 54, + 54, 637, 638, 641, 54, 535, 54, 54, 54, 54, + 54, 54, 54, 646, 535, 647, 648, 655, 54, 54, + 54, 54, 54, 54, 54, 662, 736, 54, 736, 736, + 736, 665, 736, 54, 54, 668, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 673, 54, 54, 54, 676, + 54, 54, 54, 54, 54, 770, 685, 770, 770, 770, + 690, 770, 707, 767, 712, 767, 767, 767, 730, 767, + 731, 732, 734, 735, 54, 737, 739, 54, 741, 742, + 54, 54, 745, 756, 54, 893, 54, 893, 893, 893, + 54, 893, 770, 692, 761, 692, 692, 692, 54, 692, + 767, 770, 772, 54, 54, 54, 54, 775, 54, 54, + 778, 767, 767, 54, 54, 115, 115, 115, 115, 115, + 115, 54, 893, 54, 115, 115, 781, 790, 794, 115, + 692, 115, 115, 115, 115, 115, 115, 115, 795, 692, + 692, 692, 692, 115, 115, 115, 115, 115, 115, 115, + 798, 869, 115, 869, 869, 869, 799, 869, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 812, 115, 115, 115, 813, 115, 115, 115, 115, 115, + 844, 819, 844, 844, 844, 827, 844, 833, 810, 834, + 810, 810, 810, 835, 810, 838, 839, 841, 843, 115, + 845, 851, 115, 852, 857, 115, 115, 862, 863, 115, + 928, 115, 928, 928, 928, 115, 928, 844, 762, 864, + 762, 762, 762, 115, 762, 810, 844, 865, 115, 115, + 115, 115, 867, 115, 115, 871, 810, 810, 115, 115, + 199, 199, 199, 199, 199, 199, 115, 928, 115, 199, + 199, 873, 878, 879, 199, 762, 199, 199, 199, 199, + 199, 199, 199, 894, 762, 762, 762, 762, 199, 199, + 199, 199, 199, 199, 199, 916, 923, 199, 6, 6, + 6, 6, 6, 199, 199, 924, 199, 199, 199, 199, + 199, 199, 199, 199, 199, 925, 199, 199, 199, 926, + 199, 199, 199, 199, 199, 930, 927, 930, 930, 930, + 929, 930, 932, 884, 933, 884, 884, 884, 934, 884, + 935, 936, 937, 938, 199, 939, 947, 199, 956, 957, + 199, 199, 958, nil, 199, 946, 199, 946, 946, 946, + 199, 946, 930, 764, 824, 764, 764, 764, 199, 764, + 884, 824, nil, 199, 199, 199, 199, nil, 199, 199, + 824, 884, 884, 199, 199, 222, 222, 222, 222, 222, + 222, 199, 946, 199, 222, 222, nil, nil, nil, 222, + 764, 222, 222, 222, 222, 222, 222, 222, nil, 764, + 764, 764, 764, 222, 222, 222, 222, 222, 222, 222, + nil, nil, 222, 279, 279, 279, 279, 279, 222, 222, + nil, 222, 222, 222, 222, 222, 222, 222, 222, 222, + nil, 222, 222, 222, nil, 222, 222, 222, 222, 222, + nil, nil, 825, 481, 481, 481, 481, 481, 886, 825, + 886, 886, 886, nil, 886, nil, 626, 826, 825, 222, + 828, nil, 222, 626, 826, 222, 222, 828, 626, 222, + 870, 222, 626, 826, nil, 222, 828, 870, 805, nil, + 805, 805, 805, 222, 805, 886, 870, nil, 222, 222, + 222, 222, nil, 222, 222, nil, 886, 886, 222, 222, + 282, 282, 282, 282, 282, 282, 222, nil, 222, 282, + 282, nil, nil, nil, 282, 805, 282, 282, 282, 282, + 282, 282, 282, nil, 805, 805, 805, 805, 282, 282, + 282, 282, 282, 282, 282, nil, nil, 282, 616, 616, + 616, 616, 616, 282, 282, nil, 282, 282, 282, 282, + 282, 282, 282, 282, 282, nil, 282, 282, 282, nil, + 282, 282, 282, 282, 282, nil, nil, 877, nil, nil, + nil, nil, nil, 888, 877, 888, 888, 888, nil, 888, + nil, 683, nil, 877, 282, nil, nil, 282, 683, nil, + 282, 282, nil, 683, 282, nil, 282, 683, nil, nil, + 282, nil, nil, 807, nil, 807, 807, 807, 282, 807, + 888, nil, nil, 282, 282, 282, 282, nil, 282, 282, + nil, 888, 888, 282, 282, 287, 287, 287, 287, 287, + 287, 282, nil, 282, 287, 287, nil, nil, nil, 287, + 807, 287, 287, 287, 287, 287, 287, 287, nil, 807, + 807, 807, 807, 287, 287, 287, 287, 287, 287, 287, + nil, nil, 287, nil, nil, nil, nil, 393, 287, 287, + nil, 287, 287, 287, 287, 287, 287, 287, 287, 287, + nil, 287, 287, 287, nil, 287, 287, 287, 287, 287, + 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, + 393, 920, 393, 393, nil, nil, 393, 393, 920, 287, + nil, nil, 287, 920, nil, 287, 287, 920, nil, 287, + nil, 287, 393, nil, 393, 287, 393, 393, 393, 393, + 393, 393, 393, 287, 393, nil, nil, nil, 287, 287, + 287, 287, nil, 287, 287, nil, nil, nil, 287, 287, + nil, 393, 409, nil, nil, nil, 287, nil, 287, 409, + 409, 409, nil, nil, 409, 409, 409, 519, 409, 519, + 519, 519, nil, 519, nil, nil, nil, 409, 409, 409, + 409, nil, nil, nil, nil, nil, nil, nil, 409, 409, + nil, 409, 409, 409, 409, 409, nil, nil, nil, nil, + nil, nil, nil, nil, 519, 519, nil, nil, nil, nil, + nil, nil, nil, 519, 519, 519, 519, nil, 409, 409, + 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, + 409, 409, nil, nil, 409, 409, 409, nil, nil, 409, + nil, nil, 409, nil, nil, 409, 409, nil, 409, nil, + 409, nil, 409, nil, 409, 409, 409, 409, 409, 409, + 409, 410, 409, 409, 409, nil, nil, nil, 410, 410, + 410, nil, nil, 410, 410, 410, 444, 410, 409, 409, + 409, 409, nil, 409, nil, 409, 410, 410, 410, 410, + nil, nil, 444, 444, nil, nil, nil, 410, 410, nil, + 410, 410, 410, 410, 410, nil, nil, nil, 444, nil, + 444, nil, 444, 444, 444, 444, nil, nil, 444, nil, + 444, nil, nil, nil, nil, nil, nil, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, nil, nil, 410, 410, 410, nil, nil, 410, nil, + nil, 410, nil, nil, 410, 410, nil, 410, nil, 410, + nil, 410, nil, 410, 410, 410, 410, 410, 410, 410, + nil, 410, 410, 410, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 410, 410, 410, + 410, nil, 410, nil, 410, 520, 520, 520, 520, 520, + 520, nil, nil, nil, 520, 520, nil, nil, nil, 520, + nil, 520, 520, 520, 520, 520, 520, 520, nil, nil, + nil, nil, nil, 520, 520, 520, 520, 520, 520, 520, + nil, nil, 520, nil, nil, nil, nil, nil, 520, 520, + nil, 520, 520, 520, 520, 520, 520, 520, 520, 520, + nil, 520, 520, 520, nil, 520, 520, 520, 520, 520, + nil, nil, nil, nil, nil, nil, nil, nil, 907, nil, + 907, 907, 907, nil, 907, nil, nil, nil, nil, 520, + nil, nil, 520, nil, nil, 520, 520, nil, nil, 520, + nil, 520, nil, nil, nil, 520, nil, nil, 881, nil, + 881, 881, 881, 520, 881, 907, nil, nil, 520, 520, + 520, 520, nil, 520, 520, nil, 907, 907, 520, 520, + 523, 523, 523, 523, 523, 523, 520, nil, 520, 523, + 523, nil, nil, nil, 523, 881, 523, 523, 523, 523, + 523, 523, 523, nil, 881, 881, 881, 881, 523, 523, + 523, 523, 523, 523, 523, nil, nil, 523, nil, nil, + nil, nil, nil, 523, 523, nil, 523, 523, 523, 523, + 523, 523, 523, 523, 523, nil, 523, 523, 523, nil, + 523, 523, 523, 523, 523, nil, nil, nil, nil, nil, + nil, nil, nil, 909, nil, 909, 909, 909, nil, 909, + nil, nil, nil, nil, 523, nil, nil, 523, nil, nil, + 523, 523, nil, nil, 523, nil, 523, nil, nil, nil, + 523, nil, nil, 904, nil, 904, 904, 904, 523, 904, + 909, nil, nil, 523, 523, 523, 523, nil, 523, 523, + nil, 909, 909, 523, 523, 545, 545, 545, 545, 545, + 545, 523, nil, 523, 545, 545, nil, nil, nil, 545, + 904, 545, 545, 545, 545, 545, 545, 545, nil, 904, + 904, 904, 904, 545, 545, 545, 545, 545, 545, 545, + nil, nil, 545, nil, nil, nil, nil, nil, 545, 545, + nil, 545, 545, 545, 545, 545, 545, 545, 545, 545, + nil, 545, 545, 545, nil, 545, 545, 545, 545, 545, + nil, nil, nil, nil, nil, nil, nil, 942, nil, 942, + 942, 942, nil, 942, nil, nil, nil, nil, nil, 545, + nil, nil, 545, nil, nil, 545, 545, nil, nil, 545, + nil, 545, nil, nil, nil, 545, 952, nil, 952, 952, + 952, nil, 952, 545, 942, nil, nil, nil, 545, 545, + 545, 545, nil, 545, 545, 942, 942, nil, 545, 545, + 600, 600, 600, 600, 600, 600, 545, nil, 545, 600, + 600, nil, nil, 952, 600, nil, 600, 600, 600, 600, + 600, 600, 600, nil, 952, 952, nil, nil, 600, 600, + 600, 600, 600, 600, 600, nil, nil, 600, nil, nil, + nil, nil, nil, 600, 600, nil, 600, 600, 600, 600, + 600, 600, 600, 600, 600, nil, 600, 600, 600, nil, + 600, 600, 600, 600, 600, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 432, 432, nil, 432, 432, nil, + nil, 432, 432, nil, 600, nil, nil, 600, nil, nil, + 600, 600, nil, nil, 600, nil, 600, 432, nil, 432, + 600, 432, 432, 432, 432, 432, 432, 432, 600, 432, + nil, nil, nil, 600, 600, 600, 600, nil, 600, 600, + nil, nil, nil, 600, 600, 607, 607, 607, 607, 607, + 607, 600, nil, 600, 607, 607, nil, nil, nil, 607, + nil, 607, 607, 607, 607, 607, 607, 607, nil, nil, + nil, nil, nil, 607, 607, 607, 607, 607, 607, 607, + nil, nil, 607, nil, nil, nil, nil, nil, 607, 607, + nil, 607, 607, 607, 607, 607, 607, 607, 607, 607, + nil, 607, 607, 607, nil, 607, 607, 607, 607, 607, + 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, + 433, nil, 433, 433, nil, nil, 433, 433, nil, 607, + nil, nil, 607, nil, nil, 607, 607, nil, nil, 607, + nil, 607, 433, nil, 433, 607, 433, 433, 433, 433, + 433, 433, 433, 607, 433, nil, nil, nil, 607, 607, + 607, 607, nil, 607, 607, nil, nil, nil, 607, 607, + 608, 608, 608, 608, 608, 608, 607, nil, 607, 608, + 608, nil, nil, nil, 608, nil, 608, 608, 608, 608, + 608, 608, 608, nil, nil, nil, nil, nil, 608, 608, + 608, 608, 608, 608, 608, nil, nil, 608, nil, nil, + nil, nil, nil, 608, 608, nil, 608, 608, 608, 608, + 608, 608, 608, 608, 608, nil, 608, 608, 608, nil, + 608, 608, 608, 608, 608, 443, 443, 443, 443, 443, + 443, 443, nil, nil, 443, 443, nil, nil, nil, nil, + nil, 443, 443, nil, 608, nil, nil, 608, nil, nil, + 608, 608, nil, nil, 608, nil, 608, 443, nil, 443, + 608, 443, 443, 443, 443, 443, 443, 443, 608, 443, + nil, nil, nil, 608, 608, 608, 608, nil, 608, 608, + nil, nil, nil, 608, 608, 636, 636, 636, 636, 636, + 636, 608, nil, 608, 636, 636, nil, nil, nil, 636, + nil, 636, 636, 636, 636, 636, 636, 636, nil, nil, + nil, nil, nil, 636, 636, 636, 636, 636, 636, 636, + nil, nil, 636, nil, nil, nil, nil, nil, 636, 636, + nil, 636, 636, 636, 636, 636, 636, 636, 636, 636, + nil, 636, 636, 636, nil, 636, 636, 636, 636, 636, + 445, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 445, 445, nil, 636, + nil, nil, 636, nil, nil, 636, 636, nil, nil, 636, + nil, 636, 445, nil, 445, 636, 445, 445, 445, 445, + nil, nil, 445, 636, 445, nil, nil, nil, 636, 636, + 636, 636, nil, 636, 636, nil, nil, nil, 636, 636, + 686, 686, 686, 686, 686, 686, 636, nil, 636, 686, + 686, nil, nil, nil, 686, nil, 686, 686, 686, 686, + 686, 686, 686, nil, nil, nil, nil, nil, 686, 686, + 686, 686, 686, 686, 686, nil, nil, 686, nil, nil, + nil, nil, nil, 686, 686, nil, 686, 686, 686, 686, + 686, 686, 686, 686, 686, nil, 686, 686, 686, nil, + 686, 686, 686, 686, 686, 446, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 446, 446, nil, 686, nil, nil, 686, nil, nil, + 686, 686, nil, nil, 686, nil, 686, 446, nil, 446, + 686, 446, 446, 446, 446, nil, nil, 446, 686, 446, + nil, nil, nil, 686, 686, 686, 686, nil, 686, 686, + nil, nil, nil, 686, 686, 691, 691, 691, 691, 691, + 691, 686, nil, 686, 691, 691, nil, nil, nil, 691, + nil, 691, 691, 691, 691, 691, 691, 691, nil, nil, + nil, nil, nil, 691, 691, 691, 691, 691, 691, 691, + nil, nil, 691, nil, nil, nil, nil, nil, 691, 691, + nil, 691, 691, 691, 691, 691, 691, 691, 691, 691, + nil, 691, 691, 691, nil, 691, 691, 691, 691, 691, + 447, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 447, 447, nil, 691, + nil, nil, 691, nil, nil, 691, 691, nil, nil, 691, + nil, 691, 447, nil, 447, 691, 447, 447, 447, 447, + nil, nil, 447, 691, 447, nil, nil, nil, 691, 691, + 691, 691, nil, 691, 691, nil, nil, nil, 691, 691, + 701, 701, 701, 701, 701, 701, 691, nil, 691, 701, + 701, nil, nil, nil, 701, nil, 701, 701, 701, 701, + 701, 701, 701, nil, nil, nil, nil, nil, 701, 701, + 701, 701, 701, 701, 701, nil, nil, 701, nil, nil, + nil, nil, nil, 701, 701, nil, 701, 701, 701, 701, + 701, 701, 701, 701, 701, nil, 701, 701, 701, nil, + 701, 701, 701, 701, 701, 448, 448, 448, 448, 448, + 448, 448, nil, nil, 448, 448, nil, nil, nil, nil, + nil, 448, 448, nil, 701, nil, nil, 701, nil, nil, + 701, 701, nil, nil, 701, nil, 701, 448, nil, 448, + 701, 448, 448, 448, 448, 448, 448, 448, 701, 448, + nil, nil, nil, 701, 701, 701, 701, nil, 701, 701, + nil, nil, nil, 701, 701, 740, 740, 740, 740, 740, + 740, 701, nil, 701, 740, 740, nil, nil, nil, 740, + nil, 740, 740, 740, 740, 740, 740, 740, nil, nil, + nil, nil, nil, 740, 740, 740, 740, 740, 740, 740, + nil, nil, 740, nil, nil, nil, nil, nil, 740, 740, + nil, 740, 740, 740, 740, 740, 740, 740, 740, 740, + nil, 740, 740, 740, nil, 740, 740, 740, 740, 740, + 449, 449, 449, 449, 449, 449, 449, nil, nil, 449, + 449, nil, nil, nil, nil, nil, 449, 449, nil, 740, + nil, nil, 740, nil, nil, 740, 740, nil, nil, 740, + nil, 740, 449, nil, 449, 740, 449, 449, 449, 449, + 449, 449, 449, 740, 449, nil, nil, nil, 740, 740, + 740, 740, nil, 740, 740, nil, nil, nil, 740, 740, + 750, 750, 750, 750, 750, 750, 740, nil, 740, 750, + 750, nil, nil, nil, 750, nil, 750, 750, 750, 750, + 750, 750, 750, nil, nil, nil, nil, nil, 750, 750, + 750, 750, 750, 750, 750, nil, nil, 750, nil, nil, + nil, nil, nil, 750, 750, nil, 750, 750, 750, 750, + 750, 750, 750, 750, 750, nil, 750, 750, 750, nil, + 750, 750, 750, 750, 750, 450, 450, 450, 450, 450, + 450, 450, nil, nil, 450, 450, nil, nil, nil, nil, + nil, 450, 450, nil, 750, nil, nil, 750, nil, nil, + 750, 750, nil, nil, 750, nil, 750, 450, nil, 450, + 750, 450, 450, 450, 450, 450, 450, 450, 750, 450, + nil, nil, nil, 750, 750, 750, 750, nil, 750, 750, + nil, nil, nil, 750, 750, 782, 782, 782, 782, 782, + 782, 750, nil, 750, 782, 782, nil, nil, nil, 782, + nil, 782, 782, 782, 782, 782, 782, 782, nil, nil, + nil, nil, nil, 782, 782, 782, 782, 782, 782, 782, + nil, nil, 782, nil, nil, nil, nil, nil, 782, 782, + nil, 782, 782, 782, 782, 782, 782, 782, 782, 782, + nil, 782, 782, 782, nil, 782, 782, 782, 782, 782, + 451, 451, 451, 451, 451, 451, 451, nil, nil, 451, + 451, nil, nil, nil, nil, nil, 451, 451, nil, 782, + nil, nil, 782, nil, nil, 782, 782, nil, nil, 782, + nil, 782, 451, nil, 451, 782, 451, 451, 451, 451, + 451, 451, 451, 782, 451, nil, nil, nil, 782, 782, + 782, 782, nil, 782, 782, nil, nil, nil, 782, 782, + 783, 783, 783, 783, 783, 783, 782, nil, 782, 783, + 783, nil, nil, nil, 783, nil, 783, 783, 783, 783, + 783, 783, 783, nil, nil, nil, nil, nil, 783, 783, + 783, 783, 783, 783, 783, nil, nil, 783, nil, nil, + nil, nil, nil, 783, 783, nil, 783, 783, 783, 783, + 783, 783, 783, 783, 783, nil, 783, 783, 783, nil, + 783, 783, 783, 783, 783, 452, 452, 452, 452, 452, + 452, 452, nil, nil, 452, 452, nil, nil, nil, nil, + nil, 452, 452, nil, 783, nil, nil, 783, nil, nil, + 783, 783, nil, nil, 783, nil, 783, 452, nil, 452, + 783, 452, 452, 452, 452, 452, 452, 452, 783, 452, + nil, nil, nil, 783, 783, 783, 783, nil, 783, 783, + nil, nil, nil, 783, 783, 786, 786, 786, 786, 786, + 786, 783, nil, 783, 786, 786, nil, nil, nil, 786, + nil, 786, 786, 786, 786, 786, 786, 786, nil, nil, + nil, nil, nil, 786, 786, 786, 786, 786, 786, 786, + nil, nil, 786, nil, nil, nil, nil, nil, 786, 786, + nil, 786, 786, 786, 786, 786, 786, 786, 786, 786, + nil, 786, 786, 786, nil, 786, 786, 786, 786, 786, + 455, 455, 455, 455, 455, 455, 455, nil, nil, 455, + 455, nil, nil, nil, nil, nil, 455, 455, nil, 786, + nil, nil, 786, nil, nil, 786, 786, nil, nil, 786, + nil, 786, 455, nil, 455, 786, 455, 455, 455, 455, + 455, 455, 455, 786, 455, nil, nil, nil, 786, 786, + 786, 786, nil, 786, 786, nil, nil, nil, 786, 786, + 792, 792, 792, 792, 792, 792, 786, nil, 786, 792, + 792, nil, nil, nil, 792, nil, 792, 792, 792, 792, + 792, 792, 792, nil, nil, nil, nil, nil, 792, 792, + 792, 792, 792, 792, 792, nil, nil, 792, nil, nil, + nil, nil, nil, 792, 792, nil, 792, 792, 792, 792, + 792, 792, 792, 792, 792, nil, 792, 792, 792, nil, + 792, 792, 792, 792, 792, 456, 456, 456, 456, 456, + 456, 456, 456, nil, 456, 456, nil, nil, nil, nil, + nil, 456, 456, nil, 792, nil, nil, 792, nil, nil, + 792, 792, nil, nil, 792, nil, 792, 456, nil, 456, + 792, 456, 456, 456, 456, 456, 456, 456, 792, 456, + nil, nil, nil, 792, 792, 792, 792, nil, 792, 792, + nil, nil, nil, 792, 792, 823, 823, 823, 823, 823, + 823, 792, nil, 792, 823, 823, nil, nil, nil, 823, + nil, 823, 823, 823, 823, 823, 823, 823, nil, nil, + nil, nil, nil, 823, 823, 823, 823, 823, 823, 823, + nil, nil, 823, nil, nil, nil, nil, nil, 823, 823, + nil, 823, 823, 823, 823, 823, 823, 823, 823, 823, + nil, 823, 823, 823, nil, 823, 823, 823, 823, 823, + 440, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 440, 440, nil, 823, + nil, nil, 823, nil, nil, 823, 823, nil, nil, 823, + nil, 823, 440, nil, 440, 823, 440, 440, 440, 440, + nil, nil, nil, 823, nil, nil, nil, nil, 823, 823, + 823, 823, nil, 823, 823, nil, nil, nil, 823, 823, + 831, 831, 831, 831, 831, 831, 823, nil, 823, 831, + 831, nil, nil, nil, 831, nil, 831, 831, 831, 831, + 831, 831, 831, nil, nil, nil, nil, nil, 831, 831, + 831, 831, 831, 831, 831, nil, nil, 831, nil, nil, + nil, nil, nil, 831, 831, nil, 831, 831, 831, 831, + 831, 831, 831, 831, 831, nil, 831, 831, 831, nil, + 831, 831, 831, 831, 831, 441, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 441, 441, nil, 831, nil, nil, 831, nil, nil, + 831, 831, nil, nil, 831, nil, 831, 441, nil, 441, + 831, 441, 441, 441, 441, nil, nil, nil, 831, nil, + nil, nil, nil, 831, 831, 831, 831, nil, 831, 831, + nil, nil, nil, 831, 831, 832, 832, 832, 832, 832, + 832, 831, nil, 831, 832, 832, nil, nil, nil, 832, + nil, 832, 832, 832, 832, 832, 832, 832, nil, nil, + nil, nil, nil, 832, 832, 832, 832, 832, 832, 832, + nil, nil, 832, nil, nil, nil, nil, nil, 832, 832, + nil, 832, 832, 832, 832, 832, 832, 832, 832, 832, + nil, 832, 832, 832, nil, 832, 832, 832, 832, 832, + 442, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 442, 442, nil, 832, + nil, nil, 832, nil, nil, 832, 832, nil, nil, 832, + nil, 832, 442, nil, nil, 832, 442, 442, 442, 442, + nil, nil, nil, 832, nil, nil, nil, nil, 832, 832, + 832, 832, nil, 832, 832, nil, nil, nil, 832, 832, + 895, 895, 895, 895, 895, 895, 832, nil, 832, 895, + 895, nil, nil, nil, 895, nil, 895, 895, 895, 895, + 895, 895, 895, nil, nil, nil, nil, nil, 895, 895, + 895, 895, 895, 895, 895, nil, nil, 895, nil, nil, + nil, nil, nil, 895, 895, nil, 895, 895, 895, 895, + 895, 895, 895, 895, 895, nil, 895, 895, 895, nil, + 895, 895, 895, 895, 895, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 895, nil, nil, 895, nil, nil, + 895, 895, nil, nil, 895, nil, 895, nil, nil, nil, + 895, nil, nil, nil, nil, nil, nil, nil, 895, nil, + nil, nil, nil, 895, 895, 895, 895, nil, 895, 895, + nil, nil, nil, 895, 895, 901, 901, 901, 901, 901, + 901, 895, nil, 895, 901, 901, nil, nil, nil, 901, + nil, 901, 901, 901, 901, 901, 901, 901, nil, nil, + nil, nil, nil, 901, 901, 901, 901, 901, 901, 901, + nil, nil, 901, nil, nil, nil, nil, nil, 901, 901, + nil, 901, 901, 901, 901, 901, 901, 901, 901, 901, + nil, 901, 901, 901, nil, 901, 901, 901, 901, 901, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 901, + nil, nil, 901, nil, nil, 901, 901, nil, nil, 901, + nil, 901, nil, nil, nil, 901, nil, nil, nil, nil, + nil, nil, nil, 901, nil, nil, nil, nil, 901, 901, + 901, 901, nil, 901, 901, nil, nil, nil, 901, 901, + 903, 903, 903, 903, 903, 903, 901, nil, 901, 903, + 903, nil, nil, nil, 903, nil, 903, 903, 903, 903, + 903, 903, 903, nil, nil, nil, nil, nil, 903, 903, + 903, 903, 903, 903, 903, nil, nil, 903, nil, nil, + nil, nil, nil, 903, 903, nil, 903, 903, 903, 903, + 903, 903, 903, 903, 903, nil, 903, 903, 903, nil, + 903, 903, 903, 903, 903, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 903, nil, nil, 903, nil, nil, + 903, 903, nil, nil, 903, nil, 903, nil, nil, nil, + 903, nil, nil, nil, nil, nil, nil, nil, 903, nil, + nil, nil, nil, 903, 903, 903, 903, nil, 903, 903, + nil, nil, nil, 903, 903, nil, 5, 5, 5, 5, + 5, 903, nil, 903, 5, 5, nil, nil, nil, 5, + nil, 5, 5, 5, 5, 5, 5, 5, nil, nil, + nil, nil, nil, 5, 5, 5, 5, 5, 5, 5, + nil, nil, 5, nil, nil, nil, nil, nil, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + nil, 5, 5, 5, nil, 5, 5, 5, 5, 5, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 5, + nil, nil, 5, nil, nil, 5, 5, nil, nil, 5, + nil, 5, nil, nil, nil, 5, nil, nil, nil, nil, + nil, nil, nil, 5, nil, nil, nil, nil, 5, 5, + 5, 5, nil, 5, 5, nil, nil, nil, 5, 5, + nil, 20, 20, 20, nil, 20, 5, nil, 5, 20, + 20, nil, nil, nil, 20, nil, 20, 20, 20, 20, + 20, 20, 20, nil, nil, nil, nil, nil, 20, 20, + 20, 20, 20, 20, 20, nil, nil, 20, nil, nil, + nil, nil, nil, nil, 20, nil, nil, 20, 20, 20, + 20, 20, 20, 20, 20, nil, 20, 20, 20, nil, + 20, 20, 20, 20, 20, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 20, nil, nil, 20, nil, nil, + 20, 20, nil, nil, 20, nil, nil, nil, nil, nil, + 20, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 20, 20, 20, 20, nil, 20, 20, + nil, nil, nil, 20, 20, nil, 28, 28, 28, nil, + 28, 20, nil, 20, 28, 28, nil, nil, nil, 28, + nil, 28, 28, 28, 28, 28, 28, 28, nil, nil, + nil, nil, nil, 28, 28, 28, 28, 28, 28, 28, + nil, nil, 28, nil, nil, nil, nil, nil, nil, 28, + nil, nil, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, nil, 28, 28, 28, 28, 28, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 28, + nil, nil, 28, nil, nil, 28, 28, nil, nil, 28, + nil, 28, nil, 28, nil, 28, nil, nil, nil, nil, + nil, nil, nil, 28, nil, nil, nil, nil, 28, 28, + 28, 28, nil, 28, 28, nil, nil, nil, 28, 28, + nil, 29, 29, 29, nil, 29, 28, nil, 28, 29, + 29, nil, nil, nil, 29, nil, 29, 29, 29, 29, + 29, 29, 29, nil, nil, nil, nil, nil, 29, 29, + 29, 29, 29, 29, 29, nil, nil, 29, nil, nil, + nil, nil, nil, nil, 29, nil, nil, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, nil, + 29, 29, 29, 29, 29, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 29, nil, nil, 29, nil, nil, + 29, 29, nil, nil, 29, nil, 29, nil, 29, nil, + 29, nil, nil, nil, nil, nil, nil, nil, 29, nil, + nil, nil, nil, 29, 29, 29, 29, nil, 29, 29, + nil, nil, nil, 29, 29, nil, 30, 30, 30, nil, + 30, 29, nil, 29, 30, 30, nil, nil, nil, 30, + nil, 30, 30, 30, 30, 30, 30, 30, nil, nil, + nil, nil, nil, 30, 30, 30, 30, 30, 30, 30, + nil, nil, 30, nil, nil, nil, nil, nil, nil, 30, + nil, nil, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, nil, 30, 30, 30, 30, 30, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 30, + nil, nil, 30, nil, nil, 30, 30, nil, nil, 30, + nil, 30, nil, 30, nil, 30, nil, nil, nil, nil, + nil, nil, nil, 30, nil, nil, nil, nil, 30, 30, + 30, 30, nil, 30, 30, nil, nil, nil, 30, 30, + nil, 33, 33, 33, nil, 33, 30, nil, 30, 33, + 33, nil, nil, nil, 33, nil, 33, 33, 33, 33, + 33, 33, 33, nil, nil, nil, nil, nil, 33, 33, + 33, 33, 33, 33, 33, nil, nil, 33, nil, nil, + nil, nil, nil, nil, 33, nil, nil, 33, 33, 33, + 33, 33, 33, 33, 33, nil, 33, 33, 33, nil, + 33, 33, nil, 546, 33, 546, 546, 546, nil, 546, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 33, nil, nil, 33, nil, nil, + 33, 33, nil, nil, 33, nil, 33, nil, nil, nil, + 546, 546, nil, nil, nil, nil, nil, nil, nil, 546, + 546, 546, 546, 33, 33, 33, 33, nil, 33, 33, + nil, nil, nil, 33, 33, nil, 34, 34, 34, nil, + 34, 33, nil, 33, 34, 34, nil, nil, nil, 34, + nil, 34, 34, 34, 34, 34, 34, 34, nil, nil, + nil, nil, nil, 34, 34, 34, 34, 34, 34, 34, + nil, nil, 34, nil, nil, nil, nil, 595, nil, 34, + nil, nil, 34, 34, 34, 34, 34, 34, 34, 34, + nil, 34, 34, 34, nil, 34, 34, nil, nil, 34, + 595, 595, 595, 595, 595, 595, 595, 595, 595, 595, + 595, nil, 595, 595, nil, nil, 595, 595, nil, 34, + nil, nil, 34, nil, nil, 34, 34, nil, nil, 34, + nil, nil, 595, nil, 595, nil, 595, 595, 595, 595, + 595, 595, 595, nil, 595, nil, nil, nil, 34, 34, + 34, 34, nil, 34, 34, nil, nil, nil, 34, 34, + nil, 595, nil, 34, nil, nil, 34, nil, 34, 41, + 41, 41, nil, 41, nil, nil, nil, 41, 41, nil, + nil, nil, 41, nil, 41, 41, 41, 41, 41, 41, + 41, nil, nil, nil, nil, nil, 41, 41, 41, 41, + 41, 41, 41, nil, nil, 41, nil, nil, nil, nil, + nil, nil, 41, nil, nil, 41, 41, 41, 41, 41, + 41, 41, 41, nil, 41, 41, 41, nil, 41, 41, + 41, 41, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 41, nil, nil, 41, nil, nil, 41, 41, + nil, nil, 41, nil, nil, nil, nil, nil, 41, nil, + nil, nil, nil, nil, nil, nil, 41, nil, nil, nil, + nil, 41, 41, 41, 41, nil, 41, 41, nil, nil, + nil, 41, 41, nil, 42, 42, 42, nil, 42, 41, + nil, 41, 42, 42, nil, nil, nil, 42, nil, 42, + 42, 42, 42, 42, 42, 42, nil, nil, nil, nil, + nil, 42, 42, 42, 42, 42, 42, 42, nil, nil, + 42, nil, nil, nil, nil, nil, nil, 42, nil, nil, + 42, 42, 42, 42, 42, 42, 42, 42, nil, 42, + 42, 42, nil, 42, 42, 42, 42, 42, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 42, nil, nil, + 42, nil, nil, 42, 42, nil, nil, 42, nil, nil, + nil, nil, nil, 42, nil, nil, nil, nil, nil, nil, + nil, 42, nil, nil, nil, nil, 42, 42, 42, 42, + nil, 42, 42, nil, nil, nil, 42, 42, nil, 43, + 43, 43, nil, 43, 42, nil, 42, 43, 43, nil, + nil, nil, 43, nil, 43, 43, 43, 43, 43, 43, + 43, nil, nil, nil, nil, nil, 43, 43, 43, 43, + 43, 43, 43, nil, nil, 43, nil, nil, nil, nil, + nil, nil, 43, nil, nil, 43, 43, 43, 43, 43, + 43, 43, 43, nil, 43, 43, 43, nil, 43, 43, + 43, 43, 43, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 43, nil, nil, 43, nil, nil, 43, 43, + nil, nil, 43, nil, nil, nil, nil, nil, 43, nil, + nil, nil, nil, nil, nil, nil, 43, nil, nil, nil, + nil, 43, 43, 43, 43, nil, 43, 43, nil, nil, + nil, 43, 43, nil, 56, 56, 56, nil, 56, 43, + nil, 43, 56, 56, nil, nil, nil, 56, nil, 56, + 56, 56, 56, 56, 56, 56, nil, nil, nil, nil, + nil, 56, 56, 56, 56, 56, 56, 56, nil, nil, + 56, nil, nil, nil, nil, nil, nil, 56, nil, nil, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, nil, 56, 56, 56, 56, 56, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 56, nil, nil, + 56, nil, nil, 56, 56, nil, nil, 56, nil, 56, + nil, nil, nil, 56, nil, nil, nil, nil, nil, nil, + nil, 56, nil, nil, nil, nil, 56, 56, 56, 56, + nil, 56, 56, nil, nil, nil, 56, 56, nil, 57, + 57, 57, nil, 57, 56, nil, 56, 57, 57, nil, + nil, nil, 57, nil, 57, 57, 57, 57, 57, 57, + 57, nil, nil, nil, nil, nil, 57, 57, 57, 57, + 57, 57, 57, nil, nil, 57, nil, nil, nil, nil, + nil, nil, 57, nil, nil, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 57, 57, 57, nil, 57, 57, + 57, 57, 57, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 57, nil, nil, 57, nil, nil, 57, 57, + nil, nil, 57, nil, nil, nil, nil, nil, 57, nil, + nil, nil, nil, nil, nil, nil, 57, nil, nil, nil, + nil, 57, 57, 57, 57, nil, 57, 57, nil, nil, + nil, 57, 57, nil, 60, 60, 60, nil, 60, 57, + nil, 57, 60, 60, nil, nil, nil, 60, nil, 60, + 60, 60, 60, 60, 60, 60, nil, nil, nil, nil, + nil, 60, 60, 60, 60, 60, 60, 60, nil, nil, + 60, nil, nil, nil, nil, nil, nil, 60, nil, nil, + 60, 60, 60, 60, 60, 60, 60, 60, nil, 60, + 60, 60, nil, 60, 60, 60, 60, 60, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 60, nil, nil, + 60, nil, nil, 60, 60, nil, nil, 60, nil, nil, + nil, nil, nil, 60, nil, nil, nil, nil, nil, nil, + nil, 60, nil, nil, nil, nil, 60, 60, 60, 60, + nil, 60, 60, nil, nil, nil, 60, 60, nil, 61, + 61, 61, nil, 61, 60, nil, 60, 61, 61, nil, + nil, nil, 61, nil, 61, 61, 61, 61, 61, 61, + 61, nil, nil, nil, nil, nil, 61, 61, 61, 61, + 61, 61, 61, nil, nil, 61, nil, nil, nil, nil, + nil, nil, 61, nil, nil, 61, 61, 61, 61, 61, + 61, 61, 61, nil, 61, 61, 61, nil, 61, 61, + 61, 61, 61, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 61, nil, nil, 61, nil, nil, 61, 61, + nil, nil, 61, nil, nil, nil, nil, nil, 61, nil, + nil, nil, nil, nil, nil, nil, 61, nil, nil, nil, + nil, 61, 61, 61, 61, nil, 61, 61, nil, nil, + nil, 61, 61, nil, 64, 64, 64, nil, 64, 61, + nil, 61, 64, 64, nil, nil, nil, 64, nil, 64, + 64, 64, 64, 64, 64, 64, nil, nil, nil, nil, + nil, 64, 64, 64, 64, 64, 64, 64, nil, nil, + 64, nil, nil, nil, nil, nil, nil, 64, nil, nil, + 64, 64, 64, 64, 64, 64, 64, 64, nil, 64, + 64, 64, nil, 64, 64, 64, 64, 64, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, nil, + 21, 21, nil, nil, 21, 21, nil, 64, nil, nil, + 64, nil, nil, 64, 64, nil, nil, 64, nil, nil, + 21, nil, 21, 64, 21, 21, 21, 21, 21, 21, + 21, 64, 21, nil, nil, nil, 64, 64, 64, 64, + nil, 64, 64, nil, nil, nil, 64, 64, 64, 21, + nil, nil, nil, 64, 64, nil, 64, 65, 65, 65, + nil, 65, nil, nil, nil, 65, 65, nil, nil, nil, + 65, nil, 65, 65, 65, 65, 65, 65, 65, nil, + nil, nil, nil, nil, 65, 65, 65, 65, 65, 65, + 65, nil, nil, 65, nil, nil, nil, nil, nil, nil, + 65, nil, nil, 65, 65, 65, 65, 65, 65, 65, + 65, nil, 65, 65, 65, nil, 65, 65, nil, 860, + 65, 860, 860, 860, nil, 860, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 65, nil, nil, 65, nil, nil, 65, 65, nil, nil, + 65, nil, 65, nil, nil, nil, 860, 860, nil, nil, + nil, nil, nil, nil, nil, 860, 860, 860, 860, 65, + 65, 65, 65, nil, 65, 65, nil, nil, nil, 65, + 65, nil, 66, 66, 66, nil, 66, 65, nil, 65, + 66, 66, nil, nil, nil, 66, nil, 66, 66, 66, + 66, 66, 66, 66, nil, nil, nil, nil, nil, 66, + 66, 66, 66, 66, 66, 66, nil, nil, 66, nil, + nil, nil, nil, nil, nil, 66, nil, nil, 66, 66, + 66, 66, 66, 66, 66, 66, nil, 66, 66, 66, + nil, 66, 66, nil, nil, 66, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 66, nil, nil, 66, nil, nil, 66, nil, + nil, 66, 66, nil, nil, 66, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 66, 66, 66, 66, nil, 66, + 66, nil, nil, nil, 66, 66, nil, 67, 67, 67, + nil, 67, 66, nil, 66, 67, 67, nil, nil, nil, + 67, nil, 67, 67, 67, 67, 67, 67, 67, nil, + nil, nil, nil, nil, 67, 67, 67, 67, 67, 67, + 67, nil, nil, 67, nil, nil, nil, nil, nil, nil, + 67, nil, nil, 67, 67, 67, 67, 67, 67, 67, + 67, nil, 67, 67, 67, nil, 67, 67, nil, nil, + 67, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 67, nil, nil, 67, nil, nil, 67, 67, nil, nil, + 67, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 67, + 67, 67, 67, nil, 67, 67, nil, nil, nil, 67, + 67, nil, 105, 105, 105, 105, 105, 67, nil, 67, + 105, 105, nil, nil, nil, 105, nil, 105, 105, 105, + 105, 105, 105, 105, nil, nil, nil, nil, nil, 105, + 105, 105, 105, 105, 105, 105, nil, nil, 105, nil, + nil, nil, nil, nil, 105, 105, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, nil, 105, 105, 105, + nil, 105, 105, 105, 105, 105, 266, 266, 266, 266, + 266, 266, 266, 266, 266, 266, 266, nil, 266, 266, + nil, nil, 266, 266, nil, 105, nil, nil, 105, nil, + nil, 105, 105, nil, nil, 105, nil, 105, 266, nil, + 266, 105, 266, 266, 266, 266, 266, 266, 266, 105, + 266, nil, nil, nil, 105, 105, 105, 105, nil, 105, + 105, nil, nil, nil, 105, 105, nil, 266, nil, nil, + nil, 105, 105, nil, 105, 110, 110, 110, nil, 110, + nil, nil, nil, 110, 110, nil, nil, nil, 110, nil, + 110, 110, 110, 110, 110, 110, 110, nil, nil, nil, + nil, nil, 110, 110, 110, 110, 110, 110, 110, nil, + nil, 110, nil, nil, nil, nil, nil, nil, 110, nil, + nil, 110, 110, 110, 110, 110, 110, 110, 110, nil, + 110, 110, 110, nil, 110, 110, 110, 110, 110, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 110, nil, + nil, 110, nil, nil, 110, 110, nil, nil, 110, nil, + nil, nil, nil, nil, 110, nil, nil, nil, nil, nil, + nil, nil, 110, nil, nil, nil, nil, 110, 110, 110, + 110, nil, 110, 110, nil, nil, nil, 110, 110, nil, + 111, 111, 111, nil, 111, 110, nil, 110, 111, 111, + nil, nil, nil, 111, nil, 111, 111, 111, 111, 111, + 111, 111, nil, nil, nil, nil, nil, 111, 111, 111, + 111, 111, 111, 111, nil, nil, 111, nil, nil, nil, + nil, nil, nil, 111, nil, nil, 111, 111, 111, 111, + 111, 111, 111, 111, nil, 111, 111, 111, nil, 111, + 111, 111, 111, 111, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 111, nil, nil, 111, nil, nil, 111, + 111, nil, nil, 111, nil, nil, nil, nil, nil, 111, + nil, nil, nil, nil, nil, nil, nil, 111, nil, nil, + nil, nil, 111, 111, 111, 111, nil, 111, 111, nil, + nil, nil, 111, 111, nil, 112, 112, 112, nil, 112, + 111, nil, 111, 112, 112, nil, nil, nil, 112, nil, + 112, 112, 112, 112, 112, 112, 112, nil, nil, nil, + nil, nil, 112, 112, 112, 112, 112, 112, 112, nil, + nil, 112, nil, nil, nil, nil, nil, nil, 112, nil, + nil, 112, 112, 112, 112, 112, 112, 112, 112, nil, + 112, 112, 112, nil, 112, 112, 112, 112, 112, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 112, nil, + nil, 112, nil, nil, 112, 112, nil, nil, 112, nil, + nil, nil, nil, nil, 112, nil, nil, nil, nil, nil, + nil, nil, 112, nil, nil, nil, nil, 112, 112, 112, + 112, nil, 112, 112, nil, nil, nil, 112, 112, nil, + 113, 113, 113, nil, 113, 112, nil, 112, 113, 113, + nil, nil, nil, 113, nil, 113, 113, 113, 113, 113, + 113, 113, nil, nil, nil, nil, nil, 113, 113, 113, + 113, 113, 113, 113, nil, nil, 113, nil, nil, nil, + nil, nil, nil, 113, nil, nil, 113, 113, 113, 113, + 113, 113, 113, 113, nil, 113, 113, 113, nil, 113, + 113, 113, 113, 113, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 113, nil, nil, 113, nil, nil, 113, + 113, nil, nil, 113, nil, nil, nil, nil, nil, 113, + nil, nil, nil, nil, nil, nil, nil, 113, nil, nil, + nil, nil, 113, 113, 113, 113, nil, 113, 113, nil, + nil, nil, 113, 113, nil, 114, 114, 114, 114, 114, + 113, nil, 113, 114, 114, nil, nil, nil, 114, nil, + 114, 114, 114, 114, 114, 114, 114, nil, nil, nil, + nil, nil, 114, 114, 114, 114, 114, 114, 114, nil, + nil, 114, nil, nil, nil, nil, nil, 114, 114, nil, + 114, 114, 114, 114, 114, 114, 114, 114, 114, nil, + 114, 114, 114, nil, 114, 114, 114, 114, 114, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 114, nil, + nil, 114, nil, nil, 114, 114, nil, nil, 114, nil, + 114, nil, nil, nil, 114, nil, nil, nil, nil, nil, + nil, nil, 114, nil, nil, nil, nil, 114, 114, 114, + 114, nil, 114, 114, nil, nil, nil, 114, 114, nil, + 200, 200, 200, nil, 200, 114, nil, 114, 200, 200, + nil, nil, nil, 200, nil, 200, 200, 200, 200, 200, + 200, 200, nil, nil, nil, nil, nil, 200, 200, 200, + 200, 200, 200, 200, nil, nil, 200, nil, nil, nil, + nil, nil, nil, 200, nil, nil, 200, 200, 200, 200, + 200, 200, 200, 200, nil, 200, 200, 200, nil, 200, + 200, 200, 200, 200, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 200, nil, nil, 200, nil, nil, 200, + 200, nil, nil, 200, nil, 200, nil, nil, nil, 200, + nil, nil, nil, nil, nil, nil, nil, 200, nil, nil, + nil, nil, 200, 200, 200, 200, nil, 200, 200, nil, + nil, nil, 200, 200, nil, 201, 201, 201, nil, 201, + 200, nil, 200, 201, 201, nil, nil, nil, 201, nil, + 201, 201, 201, 201, 201, 201, 201, nil, nil, nil, + nil, nil, 201, 201, 201, 201, 201, 201, 201, nil, + nil, 201, nil, nil, nil, nil, nil, nil, 201, nil, + nil, 201, 201, 201, 201, 201, 201, 201, 201, nil, + 201, 201, 201, nil, 201, 201, 201, 201, 201, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 201, nil, + nil, 201, nil, nil, 201, 201, nil, nil, 201, nil, + nil, nil, nil, nil, 201, nil, nil, nil, nil, nil, + nil, nil, 201, nil, nil, nil, nil, 201, 201, 201, + 201, nil, 201, 201, nil, nil, nil, 201, 201, nil, + 202, 202, 202, nil, 202, 201, nil, 201, 202, 202, + nil, nil, nil, 202, nil, 202, 202, 202, 202, 202, + 202, 202, nil, nil, nil, nil, nil, 202, 202, 202, + 202, 202, 202, 202, nil, nil, 202, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, nil, 202, + 202, 202, 202, 202, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 202, nil, nil, 202, nil, nil, 202, + 202, nil, nil, 202, nil, 202, nil, 202, nil, 202, + nil, nil, nil, nil, nil, nil, nil, 202, nil, nil, + nil, nil, 202, 202, 202, 202, nil, 202, 202, nil, + nil, nil, 202, 202, nil, 205, 205, 205, nil, 205, + 202, nil, 202, 205, 205, nil, nil, nil, 205, nil, + 205, 205, 205, 205, 205, 205, 205, nil, nil, nil, + nil, nil, 205, 205, 205, 205, 205, 205, 205, nil, + nil, 205, nil, nil, nil, nil, nil, nil, 205, nil, + nil, 205, 205, 205, 205, 205, 205, 205, 205, nil, + 205, 205, 205, nil, 205, 205, 205, 205, 205, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 205, nil, + nil, 205, nil, nil, 205, 205, nil, nil, 205, nil, + nil, nil, nil, nil, 205, nil, nil, nil, nil, nil, + nil, nil, 205, nil, nil, nil, nil, 205, 205, 205, + 205, nil, 205, 205, nil, nil, nil, 205, 205, nil, + 206, 206, 206, nil, 206, 205, nil, 205, 206, 206, + nil, nil, nil, 206, nil, 206, 206, 206, 206, 206, + 206, 206, nil, nil, nil, nil, nil, 206, 206, 206, + 206, 206, 206, 206, nil, nil, 206, nil, nil, nil, + nil, nil, nil, 206, nil, nil, 206, 206, 206, 206, + 206, 206, 206, 206, nil, 206, 206, 206, nil, 206, + 206, 206, 206, 206, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 206, nil, nil, 206, nil, nil, 206, + 206, nil, nil, 206, nil, 206, nil, nil, nil, 206, + nil, nil, nil, nil, nil, nil, nil, 206, nil, nil, + nil, nil, 206, 206, 206, 206, nil, 206, 206, nil, + nil, nil, 206, 206, nil, 207, 207, 207, nil, 207, + 206, nil, 206, 207, 207, nil, nil, nil, 207, nil, + 207, 207, 207, 207, 207, 207, 207, nil, nil, nil, + nil, nil, 207, 207, 207, 207, 207, 207, 207, nil, + nil, 207, nil, nil, nil, nil, nil, nil, 207, nil, + nil, 207, 207, 207, 207, 207, 207, 207, 207, nil, + 207, 207, 207, nil, 207, 207, 207, 207, 207, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 207, nil, + nil, 207, nil, nil, 207, 207, nil, nil, 207, nil, + nil, nil, nil, nil, 207, nil, nil, nil, nil, nil, + nil, nil, 207, nil, nil, nil, nil, 207, 207, 207, + 207, nil, 207, 207, nil, nil, nil, 207, 207, nil, + 208, 208, 208, nil, 208, 207, nil, 207, 208, 208, + nil, nil, nil, 208, nil, 208, 208, 208, 208, 208, + 208, 208, nil, nil, nil, nil, nil, 208, 208, 208, + 208, 208, 208, 208, nil, nil, 208, nil, nil, nil, + nil, nil, nil, 208, nil, nil, 208, 208, 208, 208, + 208, 208, 208, 208, nil, 208, 208, 208, nil, 208, + 208, 208, 208, 208, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 208, nil, nil, 208, nil, nil, 208, + 208, nil, nil, 208, nil, nil, nil, nil, nil, 208, + nil, nil, nil, nil, nil, nil, nil, 208, nil, nil, + nil, nil, 208, 208, 208, 208, nil, 208, 208, nil, + nil, nil, 208, 208, nil, 209, 209, 209, nil, 209, + 208, nil, 208, 209, 209, nil, nil, nil, 209, nil, + 209, 209, 209, 209, 209, 209, 209, nil, nil, nil, + nil, nil, 209, 209, 209, 209, 209, 209, 209, nil, + nil, 209, nil, nil, nil, nil, nil, nil, 209, nil, + nil, 209, 209, 209, 209, 209, 209, 209, 209, nil, + 209, 209, 209, nil, 209, 209, 209, 209, 209, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 209, nil, + nil, 209, nil, nil, 209, 209, nil, nil, 209, nil, + nil, nil, nil, nil, 209, nil, nil, nil, nil, nil, + nil, nil, 209, nil, nil, nil, nil, 209, 209, 209, + 209, nil, 209, 209, nil, nil, nil, 209, 209, nil, + 210, 210, 210, nil, 210, 209, nil, 209, 210, 210, + nil, nil, nil, 210, nil, 210, 210, 210, 210, 210, + 210, 210, nil, nil, nil, nil, nil, 210, 210, 210, + 210, 210, 210, 210, nil, nil, 210, nil, nil, nil, + nil, nil, nil, 210, nil, nil, 210, 210, 210, 210, + 210, 210, 210, 210, nil, 210, 210, 210, nil, 210, + 210, 210, 210, 210, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 210, nil, nil, 210, nil, nil, 210, + 210, nil, nil, 210, nil, nil, nil, nil, nil, 210, + nil, nil, nil, nil, nil, nil, nil, 210, nil, nil, + nil, nil, 210, 210, 210, 210, nil, 210, 210, nil, + nil, nil, 210, 210, 210, 221, 221, 221, nil, 221, + 210, nil, 210, 221, 221, nil, nil, nil, 221, nil, + 221, 221, 221, 221, 221, 221, 221, nil, nil, nil, + nil, nil, 221, 221, 221, 221, 221, 221, 221, nil, + nil, 221, nil, nil, nil, nil, nil, nil, 221, nil, + nil, 221, 221, 221, 221, 221, 221, 221, 221, nil, + 221, 221, 221, nil, 221, 221, 221, 221, 221, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 221, nil, + nil, 221, nil, nil, 221, 221, nil, nil, 221, nil, + nil, nil, nil, nil, 221, nil, nil, nil, nil, nil, + nil, nil, 221, nil, nil, nil, nil, 221, 221, 221, + 221, nil, 221, 221, nil, nil, nil, 221, 221, nil, + 224, 224, 224, nil, 224, 221, nil, 221, 224, 224, + nil, nil, nil, 224, nil, 224, 224, 224, 224, 224, + 224, 224, nil, nil, nil, nil, nil, 224, 224, 224, + 224, 224, 224, 224, nil, nil, 224, nil, nil, nil, + nil, nil, nil, 224, nil, nil, 224, 224, 224, 224, + 224, 224, 224, 224, nil, 224, 224, 224, nil, 224, + 224, 224, 224, 224, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 224, nil, nil, 224, nil, nil, 224, + 224, nil, nil, 224, nil, nil, nil, nil, nil, 224, + nil, nil, nil, nil, nil, nil, nil, 224, nil, nil, + nil, nil, 224, 224, 224, 224, nil, 224, 224, nil, + nil, nil, 224, 224, nil, 225, 225, 225, nil, 225, + 224, nil, 224, 225, 225, nil, nil, nil, 225, nil, + 225, 225, 225, 225, 225, 225, 225, nil, nil, nil, + nil, nil, 225, 225, 225, 225, 225, 225, 225, nil, + nil, 225, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 225, 225, 225, 225, 225, 225, 225, 225, nil, + 225, 225, 225, nil, 225, 225, 225, 225, 225, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 225, nil, nil, 225, 225, nil, nil, 225, nil, + nil, nil, nil, nil, 225, nil, nil, nil, nil, nil, + nil, nil, 225, nil, nil, nil, nil, 225, 225, 225, + 225, nil, 225, 225, nil, nil, nil, 225, 225, nil, + 226, 226, 226, nil, 226, 225, nil, 225, 226, 226, + nil, nil, nil, 226, nil, 226, 226, 226, 226, 226, + 226, 226, nil, nil, nil, nil, nil, 226, 226, 226, + 226, 226, 226, 226, nil, nil, 226, nil, nil, nil, + nil, nil, nil, 226, nil, nil, 226, 226, 226, 226, + 226, 226, 226, 226, nil, 226, 226, 226, nil, 226, + 226, 226, 226, 226, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 226, nil, nil, 226, nil, nil, 226, + 226, nil, nil, 226, nil, nil, nil, nil, nil, 226, + nil, nil, nil, nil, nil, nil, nil, 226, nil, nil, + nil, nil, 226, 226, 226, 226, nil, 226, 226, nil, + nil, nil, 226, 226, nil, 227, 227, 227, nil, 227, + 226, nil, 226, 227, 227, nil, nil, nil, 227, nil, + 227, 227, 227, 227, 227, 227, 227, nil, nil, nil, + nil, nil, 227, 227, 227, 227, 227, 227, 227, nil, + nil, 227, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 227, 227, 227, 227, 227, 227, 227, 227, nil, + 227, 227, 227, nil, 227, 227, 227, 227, 227, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 227, nil, nil, 227, 227, nil, nil, 227, nil, + nil, nil, nil, nil, 227, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, nil, nil, 227, 227, 227, + 227, nil, 227, 227, nil, nil, nil, 227, 227, nil, + 228, 228, 228, nil, 228, 227, nil, 227, 228, 228, + nil, nil, nil, 228, nil, 228, 228, 228, 228, 228, + 228, 228, nil, nil, nil, nil, nil, 228, 228, 228, + 228, 228, 228, 228, nil, nil, 228, nil, nil, nil, + nil, nil, nil, 228, nil, nil, 228, 228, 228, 228, + 228, 228, 228, 228, nil, 228, 228, 228, nil, 228, + 228, 228, 228, 228, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 228, nil, nil, 228, nil, nil, 228, + 228, nil, nil, 228, nil, nil, nil, nil, nil, 228, + nil, nil, nil, nil, nil, nil, nil, 228, nil, nil, + nil, nil, 228, 228, 228, 228, nil, 228, 228, nil, + nil, nil, 228, 228, nil, 229, 229, 229, nil, 229, + 228, nil, 228, 229, 229, nil, nil, nil, 229, nil, + 229, 229, 229, 229, 229, 229, 229, nil, nil, nil, + nil, nil, 229, 229, 229, 229, 229, 229, 229, nil, + nil, 229, nil, nil, nil, nil, nil, nil, 229, nil, + nil, 229, 229, 229, 229, 229, 229, 229, 229, nil, + 229, 229, 229, nil, 229, 229, 229, 229, 229, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 229, nil, + nil, 229, nil, nil, 229, 229, nil, nil, 229, nil, + nil, nil, nil, nil, 229, nil, nil, nil, nil, nil, + nil, nil, 229, nil, nil, nil, nil, 229, 229, 229, + 229, nil, 229, 229, nil, nil, nil, 229, 229, nil, + 230, 230, 230, nil, 230, 229, nil, 229, 230, 230, + nil, nil, nil, 230, nil, 230, 230, 230, 230, 230, + 230, 230, nil, nil, nil, nil, nil, 230, 230, 230, + 230, 230, 230, 230, nil, nil, 230, nil, nil, nil, + nil, nil, nil, 230, nil, nil, 230, 230, 230, 230, + 230, 230, 230, 230, nil, 230, 230, 230, nil, 230, + 230, 230, 230, 230, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, 230, nil, nil, 230, + 230, nil, nil, 230, nil, nil, nil, nil, nil, 230, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + nil, nil, 230, 230, 230, 230, nil, 230, 230, nil, + nil, nil, 230, 230, nil, 231, 231, 231, nil, 231, + 230, nil, 230, 231, 231, nil, nil, nil, 231, nil, + 231, 231, 231, 231, 231, 231, 231, nil, nil, nil, + nil, nil, 231, 231, 231, 231, 231, 231, 231, nil, + nil, 231, nil, nil, nil, nil, nil, nil, 231, nil, + nil, 231, 231, 231, 231, 231, 231, 231, 231, nil, + 231, 231, 231, nil, 231, 231, 231, 231, 231, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 231, nil, + nil, 231, nil, nil, 231, 231, nil, nil, 231, nil, + nil, nil, nil, nil, 231, nil, nil, nil, nil, nil, + nil, nil, 231, nil, nil, nil, nil, 231, 231, 231, + 231, nil, 231, 231, nil, nil, nil, 231, 231, nil, + 232, 232, 232, nil, 232, 231, nil, 231, 232, 232, + nil, nil, nil, 232, nil, 232, 232, 232, 232, 232, + 232, 232, nil, nil, nil, nil, nil, 232, 232, 232, + 232, 232, 232, 232, nil, nil, 232, nil, nil, nil, + nil, nil, nil, 232, nil, nil, 232, 232, 232, 232, + 232, 232, 232, 232, nil, 232, 232, 232, nil, 232, + 232, 232, 232, 232, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 232, nil, nil, 232, nil, nil, 232, + 232, nil, nil, 232, nil, nil, nil, nil, nil, 232, + nil, nil, nil, nil, nil, nil, nil, 232, nil, nil, + nil, nil, 232, 232, 232, 232, nil, 232, 232, nil, + nil, nil, 232, 232, nil, 233, 233, 233, nil, 233, + 232, nil, 232, 233, 233, nil, nil, nil, 233, nil, + 233, 233, 233, 233, 233, 233, 233, nil, nil, nil, + nil, nil, 233, 233, 233, 233, 233, 233, 233, nil, + nil, 233, nil, nil, nil, nil, nil, nil, 233, nil, + nil, 233, 233, 233, 233, 233, 233, 233, 233, nil, + 233, 233, 233, nil, 233, 233, 233, 233, 233, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 233, nil, + nil, 233, nil, nil, 233, 233, nil, nil, 233, nil, + nil, nil, nil, nil, 233, nil, nil, nil, nil, nil, + nil, nil, 233, nil, nil, nil, nil, 233, 233, 233, + 233, nil, 233, 233, nil, nil, nil, 233, 233, nil, + 234, 234, 234, nil, 234, 233, nil, 233, 234, 234, + nil, nil, nil, 234, nil, 234, 234, 234, 234, 234, + 234, 234, nil, nil, nil, nil, nil, 234, 234, 234, + 234, 234, 234, 234, nil, nil, 234, nil, nil, nil, + nil, nil, nil, 234, nil, nil, 234, 234, 234, 234, + 234, 234, 234, 234, nil, 234, 234, 234, nil, 234, + 234, 234, 234, 234, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 234, nil, nil, 234, nil, nil, 234, + 234, nil, nil, 234, nil, nil, nil, nil, nil, 234, + nil, nil, nil, nil, nil, nil, nil, 234, nil, nil, + nil, nil, 234, 234, 234, 234, nil, 234, 234, nil, + nil, nil, 234, 234, nil, 235, 235, 235, nil, 235, + 234, nil, 234, 235, 235, nil, nil, nil, 235, nil, + 235, 235, 235, 235, 235, 235, 235, nil, nil, nil, + nil, nil, 235, 235, 235, 235, 235, 235, 235, nil, + nil, 235, nil, nil, nil, nil, nil, nil, 235, nil, + nil, 235, 235, 235, 235, 235, 235, 235, 235, nil, + 235, 235, 235, nil, 235, 235, 235, 235, 235, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 235, nil, + nil, 235, nil, nil, 235, 235, nil, nil, 235, nil, + nil, nil, nil, nil, 235, nil, nil, nil, nil, nil, + nil, nil, 235, nil, nil, nil, nil, 235, 235, 235, + 235, nil, 235, 235, nil, nil, nil, 235, 235, nil, + 236, 236, 236, nil, 236, 235, nil, 235, 236, 236, + nil, nil, nil, 236, nil, 236, 236, 236, 236, 236, + 236, 236, nil, nil, nil, nil, nil, 236, 236, 236, + 236, 236, 236, 236, nil, nil, 236, nil, nil, nil, + nil, nil, nil, 236, nil, nil, 236, 236, 236, 236, + 236, 236, 236, 236, nil, 236, 236, 236, nil, 236, + 236, 236, 236, 236, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 236, nil, nil, 236, nil, nil, 236, + 236, nil, nil, 236, nil, nil, nil, nil, nil, 236, + nil, nil, nil, nil, nil, nil, nil, 236, nil, nil, + nil, nil, 236, 236, 236, 236, nil, 236, 236, nil, + nil, nil, 236, 236, nil, 237, 237, 237, nil, 237, + 236, nil, 236, 237, 237, nil, nil, nil, 237, nil, + 237, 237, 237, 237, 237, 237, 237, nil, nil, nil, + nil, nil, 237, 237, 237, 237, 237, 237, 237, nil, + nil, 237, nil, nil, nil, nil, nil, nil, 237, nil, + nil, 237, 237, 237, 237, 237, 237, 237, 237, nil, + 237, 237, 237, nil, 237, 237, 237, 237, 237, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 237, nil, + nil, 237, nil, nil, 237, 237, nil, nil, 237, nil, + nil, nil, nil, nil, 237, nil, nil, nil, nil, nil, + nil, nil, 237, nil, nil, nil, nil, 237, 237, 237, + 237, nil, 237, 237, nil, nil, nil, 237, 237, nil, + 238, 238, 238, nil, 238, 237, nil, 237, 238, 238, + nil, nil, nil, 238, nil, 238, 238, 238, 238, 238, + 238, 238, nil, nil, nil, nil, nil, 238, 238, 238, + 238, 238, 238, 238, nil, nil, 238, nil, nil, nil, + nil, nil, nil, 238, nil, nil, 238, 238, 238, 238, + 238, 238, 238, 238, nil, 238, 238, 238, nil, 238, + 238, 238, 238, 238, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 238, nil, nil, 238, nil, nil, 238, + 238, nil, nil, 238, nil, nil, nil, nil, nil, 238, + nil, nil, nil, nil, nil, nil, nil, 238, nil, nil, + nil, nil, 238, 238, 238, 238, nil, 238, 238, nil, + nil, nil, 238, 238, nil, 239, 239, 239, nil, 239, + 238, nil, 238, 239, 239, nil, nil, nil, 239, nil, + 239, 239, 239, 239, 239, 239, 239, nil, nil, nil, + nil, nil, 239, 239, 239, 239, 239, 239, 239, nil, + nil, 239, nil, nil, nil, nil, nil, nil, 239, nil, + nil, 239, 239, 239, 239, 239, 239, 239, 239, nil, + 239, 239, 239, nil, 239, 239, 239, 239, 239, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 239, nil, + nil, 239, nil, nil, 239, 239, nil, nil, 239, nil, + nil, nil, nil, nil, 239, nil, nil, nil, nil, nil, + nil, nil, 239, nil, nil, nil, nil, 239, 239, 239, + 239, nil, 239, 239, nil, nil, nil, 239, 239, nil, + 240, 240, 240, nil, 240, 239, nil, 239, 240, 240, + nil, nil, nil, 240, nil, 240, 240, 240, 240, 240, + 240, 240, nil, nil, nil, nil, nil, 240, 240, 240, + 240, 240, 240, 240, nil, nil, 240, nil, nil, nil, + nil, nil, nil, 240, nil, nil, 240, 240, 240, 240, + 240, 240, 240, 240, nil, 240, 240, 240, nil, 240, + 240, 240, 240, 240, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 240, nil, nil, 240, nil, nil, 240, + 240, nil, nil, 240, nil, nil, nil, nil, nil, 240, + nil, nil, nil, nil, nil, nil, nil, 240, nil, nil, + nil, nil, 240, 240, 240, 240, nil, 240, 240, nil, + nil, nil, 240, 240, nil, 241, 241, 241, nil, 241, + 240, nil, 240, 241, 241, nil, nil, nil, 241, nil, + 241, 241, 241, 241, 241, 241, 241, nil, nil, nil, + nil, nil, 241, 241, 241, 241, 241, 241, 241, nil, + nil, 241, nil, nil, nil, nil, nil, nil, 241, nil, + nil, 241, 241, 241, 241, 241, 241, 241, 241, nil, + 241, 241, 241, nil, 241, 241, 241, 241, 241, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 241, nil, + nil, 241, nil, nil, 241, 241, nil, nil, 241, nil, + nil, nil, nil, nil, 241, nil, nil, nil, nil, nil, + nil, nil, 241, nil, nil, nil, nil, 241, 241, 241, + 241, nil, 241, 241, nil, nil, nil, 241, 241, nil, + 242, 242, 242, nil, 242, 241, nil, 241, 242, 242, + nil, nil, nil, 242, nil, 242, 242, 242, 242, 242, + 242, 242, nil, nil, nil, nil, nil, 242, 242, 242, + 242, 242, 242, 242, nil, nil, 242, nil, nil, nil, + nil, nil, nil, 242, nil, nil, 242, 242, 242, 242, + 242, 242, 242, 242, nil, 242, 242, 242, nil, 242, + 242, 242, 242, 242, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 242, nil, nil, 242, nil, nil, 242, + 242, nil, nil, 242, nil, nil, nil, nil, nil, 242, + nil, nil, nil, nil, nil, nil, nil, 242, nil, nil, + nil, nil, 242, 242, 242, 242, nil, 242, 242, nil, + nil, nil, 242, 242, nil, 243, 243, 243, nil, 243, + 242, nil, 242, 243, 243, nil, nil, nil, 243, nil, + 243, 243, 243, 243, 243, 243, 243, nil, nil, nil, + nil, nil, 243, 243, 243, 243, 243, 243, 243, nil, + nil, 243, nil, nil, nil, nil, nil, nil, 243, nil, + nil, 243, 243, 243, 243, 243, 243, 243, 243, nil, + 243, 243, 243, nil, 243, 243, 243, 243, 243, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 243, nil, + nil, 243, nil, nil, 243, 243, nil, nil, 243, nil, + nil, nil, nil, nil, 243, nil, nil, nil, nil, nil, + nil, nil, 243, nil, nil, nil, nil, 243, 243, 243, + 243, nil, 243, 243, nil, nil, nil, 243, 243, nil, + 244, 244, 244, nil, 244, 243, nil, 243, 244, 244, + nil, nil, nil, 244, nil, 244, 244, 244, 244, 244, + 244, 244, nil, nil, nil, nil, nil, 244, 244, 244, + 244, 244, 244, 244, nil, nil, 244, nil, nil, nil, + nil, nil, nil, 244, nil, nil, 244, 244, 244, 244, + 244, 244, 244, 244, nil, 244, 244, 244, nil, 244, + 244, 244, 244, 244, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 244, nil, nil, 244, nil, nil, 244, + 244, nil, nil, 244, nil, nil, nil, nil, nil, 244, + nil, nil, nil, nil, nil, nil, nil, 244, nil, nil, + nil, nil, 244, 244, 244, 244, nil, 244, 244, nil, + nil, nil, 244, 244, nil, 245, 245, 245, nil, 245, + 244, nil, 244, 245, 245, nil, nil, nil, 245, nil, + 245, 245, 245, 245, 245, 245, 245, nil, nil, nil, + nil, nil, 245, 245, 245, 245, 245, 245, 245, nil, + nil, 245, nil, nil, nil, nil, nil, nil, 245, nil, + nil, 245, 245, 245, 245, 245, 245, 245, 245, nil, + 245, 245, 245, nil, 245, 245, 245, 245, 245, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 245, nil, + nil, 245, nil, nil, 245, 245, nil, nil, 245, nil, + nil, nil, nil, nil, 245, nil, nil, nil, nil, nil, + nil, nil, 245, nil, nil, nil, nil, 245, 245, 245, + 245, nil, 245, 245, nil, nil, nil, 245, 245, nil, + 246, 246, 246, nil, 246, 245, nil, 245, 246, 246, + nil, nil, nil, 246, nil, 246, 246, 246, 246, 246, + 246, 246, nil, nil, nil, nil, nil, 246, 246, 246, + 246, 246, 246, 246, nil, nil, 246, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 246, 246, 246, 246, + 246, 246, 246, 246, nil, 246, 246, 246, nil, 246, + 246, 246, 246, 246, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 246, nil, nil, 246, + 246, nil, nil, 246, nil, nil, nil, nil, nil, 246, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + nil, nil, 246, 246, 246, 246, nil, 246, 246, nil, + nil, nil, 246, 246, nil, 247, 247, 247, nil, 247, + 246, nil, 246, 247, 247, nil, nil, nil, 247, nil, + 247, 247, 247, 247, 247, 247, 247, nil, nil, nil, + nil, nil, 247, 247, 247, 247, 247, 247, 247, nil, + nil, 247, nil, nil, nil, nil, nil, nil, 247, nil, + nil, 247, 247, 247, 247, 247, 247, 247, 247, nil, + 247, 247, 247, nil, 247, 247, 247, 247, 247, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 247, nil, + nil, 247, nil, nil, 247, 247, nil, nil, 247, nil, + nil, nil, nil, nil, 247, nil, nil, nil, nil, nil, + nil, nil, 247, nil, nil, nil, nil, 247, 247, 247, + 247, nil, 247, 247, nil, nil, nil, 247, 247, nil, + 248, 248, 248, nil, 248, 247, nil, 247, 248, 248, + nil, nil, nil, 248, nil, 248, 248, 248, 248, 248, + 248, 248, nil, nil, nil, nil, nil, 248, 248, 248, + 248, 248, 248, 248, nil, nil, 248, nil, nil, nil, + nil, nil, nil, 248, nil, nil, 248, 248, 248, 248, + 248, 248, 248, 248, nil, 248, 248, 248, nil, 248, + 248, 248, 248, 248, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 248, nil, nil, 248, nil, nil, 248, + 248, nil, nil, 248, nil, nil, nil, nil, nil, 248, + nil, nil, nil, nil, nil, nil, nil, 248, nil, nil, + nil, nil, 248, 248, 248, 248, nil, 248, 248, nil, + nil, nil, 248, 248, nil, 249, 249, 249, nil, 249, + 248, nil, 248, 249, 249, nil, nil, nil, 249, nil, + 249, 249, 249, 249, 249, 249, 249, nil, nil, nil, + nil, nil, 249, 249, 249, 249, 249, 249, 249, nil, + nil, 249, nil, nil, nil, nil, nil, nil, 249, nil, + nil, 249, 249, 249, 249, 249, 249, 249, 249, nil, + 249, 249, 249, nil, 249, 249, 249, 249, 249, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 249, nil, + nil, 249, nil, nil, 249, 249, nil, nil, 249, nil, + nil, nil, nil, nil, 249, nil, nil, nil, nil, nil, + nil, nil, 249, nil, nil, nil, nil, 249, 249, 249, + 249, nil, 249, 249, nil, nil, nil, 249, 249, nil, + 255, 255, 255, nil, 255, 249, nil, 249, 255, 255, + nil, nil, nil, 255, nil, 255, 255, 255, 255, 255, + 255, 255, nil, nil, nil, nil, nil, 255, 255, 255, + 255, 255, 255, 255, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 255, nil, nil, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, nil, 255, + 255, 255, 255, 255, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 255, nil, nil, 255, nil, nil, 255, + 255, nil, nil, 255, nil, 255, nil, 255, nil, 255, + nil, nil, nil, nil, nil, nil, nil, 255, nil, nil, + nil, nil, 255, 255, 255, 255, nil, 255, 255, nil, + nil, nil, 255, 255, nil, 256, 256, 256, nil, 256, + 255, nil, 255, 256, 256, nil, nil, nil, 256, nil, + 256, 256, 256, 256, 256, 256, 256, nil, nil, nil, + nil, nil, 256, 256, 256, 256, 256, 256, 256, nil, + nil, 256, nil, nil, nil, nil, nil, nil, 256, nil, + nil, 256, 256, 256, 256, 256, 256, 256, 256, 256, + 256, 256, 256, nil, 256, 256, 256, 256, 256, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 256, nil, + nil, 256, nil, nil, 256, 256, nil, nil, 256, nil, + 256, nil, 256, nil, 256, nil, nil, nil, nil, nil, + nil, nil, 256, nil, nil, nil, nil, 256, 256, 256, + 256, nil, 256, 256, nil, nil, nil, 256, 256, nil, + 264, 264, 264, nil, 264, 256, nil, 256, 264, 264, + nil, nil, nil, 264, nil, 264, 264, 264, 264, 264, + 264, 264, nil, nil, nil, nil, nil, 264, 264, 264, + 264, 264, 264, 264, nil, nil, 264, nil, nil, nil, + nil, nil, nil, 264, nil, nil, 264, 264, 264, 264, + 264, 264, 264, 264, 264, 264, 264, 264, nil, 264, + 264, 264, 264, 264, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 264, nil, nil, 264, nil, nil, 264, + 264, nil, nil, 264, nil, 264, nil, 264, nil, 264, + nil, nil, nil, nil, nil, nil, nil, 264, nil, nil, + nil, nil, 264, 264, 264, 264, nil, 264, 264, nil, + nil, nil, 264, 264, 264, 271, 271, 271, nil, 271, + 264, nil, 264, 271, 271, nil, nil, nil, 271, nil, + 271, 271, 271, 271, 271, 271, 271, nil, nil, nil, + nil, nil, 271, 271, 271, 271, 271, 271, 271, nil, + nil, 271, nil, nil, nil, nil, nil, nil, 271, nil, + nil, 271, 271, 271, 271, 271, 271, 271, 271, nil, + 271, 271, 271, nil, 271, 271, 271, 271, 271, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 271, nil, + nil, 271, nil, nil, 271, 271, nil, nil, 271, nil, + nil, nil, nil, nil, 271, nil, nil, nil, nil, nil, + nil, nil, 271, nil, nil, nil, nil, 271, 271, 271, + 271, nil, 271, 271, nil, nil, nil, 271, 271, nil, + 273, 273, 273, nil, 273, 271, nil, 271, 273, 273, + nil, nil, nil, 273, nil, 273, 273, 273, 273, 273, + 273, 273, nil, nil, nil, nil, nil, 273, 273, 273, + 273, 273, 273, 273, nil, nil, 273, nil, nil, nil, + nil, nil, nil, 273, nil, nil, 273, 273, 273, 273, + 273, 273, 273, 273, nil, 273, 273, 273, nil, 273, + 273, 273, 273, 273, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 273, nil, nil, 273, nil, nil, 273, + 273, nil, nil, 273, nil, nil, nil, nil, nil, 273, + nil, nil, nil, nil, nil, nil, nil, 273, nil, nil, + nil, nil, 273, 273, 273, 273, nil, 273, 273, nil, + nil, nil, 273, 273, nil, 275, 275, 275, nil, 275, + 273, nil, 273, 275, 275, nil, nil, nil, 275, nil, + 275, 275, 275, 275, 275, 275, 275, nil, nil, nil, + nil, nil, 275, 275, 275, 275, 275, 275, 275, nil, + nil, 275, nil, nil, nil, nil, nil, nil, 275, nil, + nil, 275, 275, 275, 275, 275, 275, 275, 275, nil, + 275, 275, 275, nil, 275, 275, 275, 275, 275, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 275, nil, + nil, 275, nil, nil, 275, 275, nil, nil, 275, nil, + nil, nil, nil, nil, 275, nil, nil, nil, nil, nil, + nil, nil, 275, nil, nil, nil, nil, 275, 275, 275, + 275, nil, 275, 275, nil, nil, nil, 275, 275, nil, + 280, 280, 280, 280, 280, 275, nil, 275, 280, 280, + nil, nil, nil, 280, nil, 280, 280, 280, 280, 280, + 280, 280, nil, nil, nil, nil, nil, 280, 280, 280, + 280, 280, 280, 280, nil, nil, 280, nil, nil, nil, + nil, nil, 280, 280, nil, 280, 280, 280, 280, 280, + 280, 280, 280, 280, nil, 280, 280, 280, nil, 280, + 280, 280, 280, 280, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 280, nil, nil, 280, nil, nil, 280, + 280, nil, nil, 280, nil, 280, nil, nil, nil, 280, + nil, nil, nil, nil, nil, nil, nil, 280, nil, nil, + nil, nil, 280, 280, 280, 280, nil, 280, 280, nil, + nil, nil, 280, 280, nil, 286, 286, 286, nil, 286, + 280, nil, 280, 286, 286, nil, nil, nil, 286, nil, + 286, 286, 286, 286, 286, 286, 286, nil, nil, nil, + nil, nil, 286, 286, 286, 286, 286, 286, 286, nil, + nil, 286, nil, nil, nil, nil, nil, nil, 286, nil, + nil, 286, 286, 286, 286, 286, 286, 286, 286, nil, + 286, 286, 286, nil, 286, 286, nil, nil, 286, 412, + 412, 412, 412, 412, 412, 412, 412, 412, 412, 412, + nil, 412, 412, nil, nil, 412, 412, nil, 286, nil, + nil, 286, nil, nil, 286, 286, nil, nil, 286, nil, + nil, 412, nil, 412, nil, 412, 412, 412, 412, 412, + 412, 412, nil, 412, nil, nil, nil, 286, 286, 286, + 286, nil, 286, 286, nil, nil, nil, 286, 286, nil, + 412, nil, 286, nil, nil, 286, nil, 286, 303, 303, + 303, nil, 303, nil, nil, nil, 303, 303, nil, nil, + nil, 303, nil, 303, 303, 303, 303, 303, 303, 303, + nil, nil, nil, nil, nil, 303, 303, 303, 303, 303, + 303, 303, nil, nil, 303, nil, nil, nil, nil, nil, + nil, 303, nil, nil, 303, 303, 303, 303, 303, 303, + 303, 303, nil, 303, 303, 303, nil, 303, 303, nil, + nil, 303, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 303, nil, nil, 303, nil, nil, 303, 303, nil, + nil, 303, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 303, 303, 303, 303, nil, 303, 303, nil, nil, nil, + 303, 303, nil, 312, 312, 312, nil, 312, 303, nil, + 303, 312, 312, nil, nil, nil, 312, nil, 312, 312, + 312, 312, 312, 312, 312, nil, nil, nil, nil, nil, + 312, 312, 312, 312, 312, 312, 312, nil, nil, 312, + nil, nil, nil, nil, nil, nil, 312, nil, nil, 312, + 312, 312, 312, 312, 312, 312, 312, nil, 312, 312, + 312, nil, 312, 312, 312, 312, 312, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 312, nil, nil, 312, + 312, nil, 312, 312, nil, nil, 312, nil, nil, nil, + nil, nil, 312, nil, nil, nil, nil, nil, nil, nil, + 312, nil, nil, nil, nil, 312, 312, 312, 312, nil, + 312, 312, nil, nil, nil, 312, 312, nil, 315, 315, + 315, nil, 315, 312, nil, 312, 315, 315, nil, nil, + nil, 315, nil, 315, 315, 315, 315, 315, 315, 315, + nil, nil, nil, nil, nil, 315, 315, 315, 315, 315, + 315, 315, nil, nil, 315, nil, nil, nil, nil, nil, + nil, 315, nil, nil, 315, 315, 315, 315, 315, 315, + 315, 315, nil, 315, 315, 315, nil, 315, 315, 315, + 315, 315, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 315, nil, nil, 315, nil, nil, 315, 315, nil, + nil, 315, nil, nil, nil, nil, nil, 315, nil, nil, + nil, nil, nil, nil, nil, 315, nil, nil, nil, nil, + 315, 315, 315, 315, nil, 315, 315, nil, nil, nil, + 315, 315, nil, 328, 328, 328, nil, 328, 315, nil, + 315, 328, 328, nil, nil, nil, 328, nil, 328, 328, + 328, 328, 328, 328, 328, nil, nil, nil, nil, nil, + 328, 328, 328, 328, 328, 328, 328, nil, nil, 328, + nil, nil, nil, nil, nil, nil, 328, nil, nil, 328, + 328, 328, 328, 328, 328, 328, 328, nil, 328, 328, + 328, nil, 328, 328, 328, 328, 328, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 328, nil, nil, 328, + nil, nil, 328, 328, nil, nil, 328, nil, nil, nil, + nil, nil, 328, nil, nil, nil, nil, nil, nil, nil, + 328, nil, nil, nil, nil, 328, 328, 328, 328, nil, + 328, 328, nil, nil, nil, 328, 328, nil, 329, 329, + 329, nil, 329, 328, nil, 328, 329, 329, nil, nil, + nil, 329, nil, 329, 329, 329, 329, 329, 329, 329, + nil, nil, nil, nil, nil, 329, 329, 329, 329, 329, + 329, 329, nil, nil, 329, nil, nil, nil, nil, nil, + nil, 329, nil, nil, 329, 329, 329, 329, 329, 329, + 329, 329, nil, 329, 329, 329, nil, 329, 329, 329, + 329, 329, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 329, nil, nil, 329, nil, nil, 329, 329, nil, + nil, 329, nil, nil, nil, nil, nil, 329, nil, nil, + nil, nil, nil, nil, nil, 329, nil, nil, nil, nil, + 329, 329, 329, 329, nil, 329, 329, nil, nil, nil, + 329, 329, nil, 348, 348, 348, nil, 348, 329, nil, + 329, 348, 348, nil, nil, nil, 348, nil, 348, 348, + 348, 348, 348, 348, 348, nil, nil, nil, nil, nil, + 348, 348, 348, 348, 348, 348, 348, nil, nil, 348, + nil, nil, nil, nil, nil, nil, 348, nil, nil, 348, + 348, 348, 348, 348, 348, 348, 348, nil, 348, 348, + 348, nil, 348, 348, 348, 348, 348, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 348, nil, nil, 348, + nil, nil, 348, 348, nil, nil, 348, nil, nil, nil, + nil, nil, 348, nil, nil, nil, nil, nil, nil, nil, + 348, nil, nil, nil, nil, 348, 348, 348, 348, nil, + 348, 348, nil, nil, nil, 348, 348, nil, 364, 364, + 364, nil, 364, 348, nil, 348, 364, 364, nil, nil, + nil, 364, nil, 364, 364, 364, 364, 364, 364, 364, + nil, nil, nil, nil, nil, 364, 364, 364, 364, 364, + 364, 364, nil, nil, 364, nil, nil, nil, nil, nil, + nil, 364, nil, nil, 364, 364, 364, 364, 364, 364, + 364, 364, nil, 364, 364, 364, nil, 364, 364, 364, + 364, 364, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 364, nil, nil, 364, nil, nil, 364, 364, nil, + nil, 364, nil, nil, nil, nil, nil, 364, nil, nil, + nil, nil, nil, nil, nil, 364, nil, nil, nil, nil, + 364, 364, 364, 364, nil, 364, 364, nil, nil, nil, + 364, 364, nil, 390, 390, 390, nil, 390, 364, nil, + 364, 390, 390, nil, nil, nil, 390, nil, 390, 390, + 390, 390, 390, 390, 390, nil, nil, nil, nil, nil, + 390, 390, 390, 390, 390, 390, 390, nil, nil, 390, + nil, nil, nil, nil, nil, nil, 390, nil, nil, 390, + 390, 390, 390, 390, 390, 390, 390, nil, 390, 390, + 390, nil, 390, 390, 390, 390, 390, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 390, nil, nil, 390, + nil, nil, 390, 390, nil, nil, 390, nil, nil, nil, + nil, nil, 390, nil, nil, nil, nil, nil, nil, nil, + 390, nil, nil, nil, nil, 390, 390, 390, 390, nil, + 390, 390, nil, nil, nil, 390, 390, nil, 427, 427, + 427, nil, 427, 390, nil, 390, 427, 427, nil, nil, + nil, 427, nil, 427, 427, 427, 427, 427, 427, 427, + nil, nil, nil, nil, nil, 427, 427, 427, 427, 427, + 427, 427, nil, nil, 427, nil, nil, nil, nil, nil, + nil, 427, nil, nil, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, nil, 427, 427, 427, + 427, 427, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 427, nil, nil, 427, nil, nil, 427, 427, nil, + nil, 427, nil, 427, nil, 427, nil, 427, nil, nil, + nil, nil, nil, nil, nil, 427, nil, nil, nil, nil, + 427, 427, 427, 427, nil, 427, 427, nil, nil, nil, + 427, 427, nil, 429, 429, 429, nil, 429, 427, nil, + 427, 429, 429, nil, nil, nil, 429, nil, 429, 429, + 429, 429, 429, 429, 429, nil, nil, nil, nil, nil, + 429, 429, 429, 429, 429, 429, 429, nil, nil, 429, + nil, nil, nil, nil, nil, nil, 429, nil, nil, 429, + 429, 429, 429, 429, 429, 429, 429, nil, 429, 429, + 429, nil, 429, 429, 429, 429, 429, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 429, nil, nil, 429, + nil, nil, 429, 429, nil, nil, 429, nil, nil, nil, + nil, nil, 429, nil, nil, nil, nil, nil, nil, nil, + 429, nil, nil, nil, nil, 429, 429, 429, 429, nil, + 429, 429, nil, nil, nil, 429, 429, nil, 430, 430, + 430, nil, 430, 429, nil, 429, 430, 430, nil, nil, + nil, 430, nil, 430, 430, 430, 430, 430, 430, 430, + nil, nil, nil, nil, nil, 430, 430, 430, 430, 430, + 430, 430, nil, nil, 430, nil, nil, nil, nil, nil, + nil, 430, nil, nil, 430, 430, 430, 430, 430, 430, + 430, 430, nil, 430, 430, 430, nil, 430, 430, 430, + 430, 430, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 430, nil, nil, 430, nil, nil, 430, 430, nil, + nil, 430, nil, nil, nil, nil, nil, 430, nil, nil, + nil, nil, nil, nil, nil, 430, nil, nil, nil, nil, + 430, 430, 430, 430, nil, 430, 430, nil, nil, nil, + 430, 430, nil, 431, 431, 431, nil, 431, 430, nil, + 430, 431, 431, nil, nil, nil, 431, nil, 431, 431, + 431, 431, 431, 431, 431, nil, nil, nil, nil, nil, + 431, 431, 431, 431, 431, 431, 431, nil, nil, 431, + nil, nil, nil, nil, nil, nil, 431, nil, nil, 431, + 431, 431, 431, 431, 431, 431, 431, nil, 431, 431, + 431, nil, 431, 431, 431, 431, 431, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 431, nil, nil, 431, + nil, nil, 431, 431, nil, nil, 431, nil, nil, nil, + nil, nil, 431, nil, nil, nil, nil, nil, nil, nil, + 431, nil, nil, nil, nil, 431, 431, 431, 431, nil, + 431, 431, nil, nil, nil, 431, 431, nil, 472, 472, + 472, nil, 472, 431, nil, 431, 472, 472, nil, nil, + nil, 472, nil, 472, 472, 472, 472, 472, 472, 472, + nil, nil, nil, nil, nil, 472, 472, 472, 472, 472, + 472, 472, nil, nil, 472, nil, nil, nil, nil, nil, + nil, 472, nil, nil, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, nil, 472, 472, 472, + 472, 472, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 472, nil, nil, 472, nil, nil, 472, 472, nil, + nil, 472, nil, 472, nil, 472, nil, 472, nil, nil, + nil, nil, nil, nil, nil, 472, nil, nil, nil, nil, + 472, 472, 472, 472, nil, 472, 472, nil, nil, nil, + 472, 472, nil, 474, 474, 474, nil, 474, 472, nil, + 472, 474, 474, nil, nil, nil, 474, nil, 474, 474, + 474, 474, 474, 474, 474, nil, nil, nil, nil, nil, + 474, 474, 474, 474, 474, 474, 474, nil, nil, 474, + nil, nil, nil, nil, nil, nil, 474, nil, nil, 474, + 474, 474, 474, 474, 474, 474, 474, 474, 474, 474, + 474, nil, 474, 474, 474, 474, 474, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 474, nil, nil, 474, + nil, nil, 474, 474, nil, nil, 474, nil, nil, nil, + 474, nil, 474, nil, nil, nil, nil, nil, nil, nil, + 474, nil, nil, nil, nil, 474, 474, 474, 474, nil, + 474, 474, nil, nil, nil, 474, 474, nil, 476, 476, + 476, nil, 476, 474, nil, 474, 476, 476, nil, nil, + nil, 476, nil, 476, 476, 476, 476, 476, 476, 476, + nil, nil, nil, nil, nil, 476, 476, 476, 476, 476, + 476, 476, nil, nil, 476, nil, nil, nil, nil, nil, + nil, 476, nil, nil, 476, 476, 476, 476, 476, 476, + 476, 476, nil, 476, 476, 476, nil, 476, 476, 476, + 476, 476, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 476, nil, nil, 476, nil, nil, 476, 476, nil, + nil, 476, nil, nil, nil, nil, nil, 476, nil, nil, + nil, nil, nil, nil, nil, 476, nil, nil, nil, nil, + 476, 476, 476, 476, nil, 476, 476, nil, nil, nil, + 476, 476, nil, 480, 480, 480, 480, 480, 476, nil, + 476, 480, 480, nil, nil, nil, 480, nil, 480, 480, + 480, 480, 480, 480, 480, nil, nil, nil, nil, nil, + 480, 480, 480, 480, 480, 480, 480, nil, nil, 480, + nil, nil, nil, nil, nil, 480, 480, nil, 480, 480, + 480, 480, 480, 480, 480, 480, 480, nil, 480, 480, + 480, nil, 480, 480, 480, 480, 480, 457, 457, 457, + 457, 457, 457, 457, 457, 457, 457, 457, nil, 457, + 457, nil, nil, 457, 457, nil, 480, nil, nil, 480, + nil, nil, 480, 480, nil, nil, 480, nil, 480, 457, + nil, 457, 480, 457, 457, 457, 457, 457, 457, 457, + 480, 457, nil, nil, nil, 480, 480, 480, 480, nil, + 480, 480, nil, nil, nil, 480, 480, 457, 457, nil, + nil, nil, 480, 480, nil, 480, 487, 487, 487, nil, + 487, nil, nil, nil, 487, 487, nil, nil, nil, 487, + nil, 487, 487, 487, 487, 487, 487, 487, nil, nil, + nil, nil, nil, 487, 487, 487, 487, 487, 487, 487, + nil, nil, 487, nil, nil, nil, nil, nil, nil, 487, + nil, nil, 487, 487, 487, 487, 487, 487, 487, 487, + nil, 487, 487, 487, nil, 487, 487, nil, nil, 487, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 487, + nil, nil, 487, nil, nil, 487, 487, nil, nil, 487, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 487, 487, + 487, 487, nil, 487, 487, nil, nil, nil, 487, 487, + nil, 489, 489, 489, nil, 489, 487, nil, 487, 489, + 489, nil, nil, nil, 489, nil, 489, 489, 489, 489, + 489, 489, 489, nil, nil, nil, nil, nil, 489, 489, + 489, 489, 489, 489, 489, nil, nil, 489, nil, nil, + nil, nil, nil, nil, 489, nil, nil, 489, 489, 489, + 489, 489, 489, 489, 489, 489, 489, 489, 489, nil, + 489, 489, 489, 489, 489, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 489, nil, nil, 489, nil, nil, + 489, 489, nil, nil, 489, nil, 489, nil, 489, nil, + 489, nil, nil, nil, nil, nil, nil, nil, 489, nil, + nil, nil, nil, 489, 489, 489, 489, nil, 489, 489, + nil, nil, nil, 489, 489, nil, 496, 496, 496, nil, + 496, 489, nil, 489, 496, 496, nil, nil, nil, 496, + nil, 496, 496, 496, 496, 496, 496, 496, nil, nil, + nil, nil, nil, 496, 496, 496, 496, 496, 496, 496, + nil, nil, 496, nil, nil, nil, nil, nil, nil, 496, + nil, nil, 496, 496, 496, 496, 496, 496, 496, 496, + nil, 496, 496, 496, nil, 496, 496, nil, nil, 496, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 496, + nil, nil, 496, nil, nil, 496, 496, nil, nil, 496, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 496, 496, + 496, 496, nil, 496, 496, nil, nil, nil, 496, 496, + nil, 499, 499, 499, nil, 499, 496, nil, 496, 499, + 499, nil, nil, nil, 499, nil, 499, 499, 499, 499, + 499, 499, 499, nil, nil, nil, nil, nil, 499, 499, + 499, 499, 499, 499, 499, nil, nil, 499, nil, nil, + nil, nil, nil, nil, 499, nil, nil, 499, 499, 499, + 499, 499, 499, 499, 499, nil, 499, 499, 499, nil, + 499, 499, 499, 499, 499, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 499, nil, nil, 499, nil, nil, + 499, 499, nil, nil, 499, nil, nil, nil, nil, nil, + 499, nil, nil, nil, nil, nil, nil, nil, 499, nil, + nil, nil, nil, 499, 499, 499, 499, nil, 499, 499, + nil, nil, nil, 499, 499, nil, 500, 500, 500, nil, + 500, 499, nil, 499, 500, 500, nil, nil, nil, 500, + nil, 500, 500, 500, 500, 500, 500, 500, nil, nil, + nil, nil, nil, 500, 500, 500, 500, 500, 500, 500, + nil, nil, 500, nil, nil, nil, nil, nil, nil, 500, + nil, nil, 500, 500, 500, 500, 500, 500, 500, 500, + nil, 500, 500, 500, nil, 500, 500, 500, 500, 500, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 500, + nil, nil, 500, nil, nil, 500, 500, nil, nil, 500, + nil, nil, nil, nil, nil, 500, nil, nil, nil, nil, + nil, nil, nil, 500, nil, nil, nil, nil, 500, 500, + 500, 500, nil, 500, 500, nil, nil, nil, 500, 500, + nil, 501, 501, 501, nil, 501, 500, nil, 500, 501, + 501, nil, nil, nil, 501, nil, 501, 501, 501, 501, + 501, 501, 501, nil, nil, nil, nil, nil, 501, 501, + 501, 501, 501, 501, 501, nil, nil, 501, nil, nil, + nil, nil, nil, nil, 501, nil, nil, 501, 501, 501, + 501, 501, 501, 501, 501, nil, 501, 501, 501, nil, + 501, 501, 501, 501, 501, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 501, nil, nil, 501, nil, nil, + 501, 501, nil, nil, 501, nil, nil, nil, nil, nil, + 501, nil, nil, nil, nil, nil, nil, nil, 501, nil, + nil, nil, nil, 501, 501, 501, 501, nil, 501, 501, + nil, nil, nil, 501, 501, nil, 505, 505, 505, nil, + 505, 501, nil, 501, 505, 505, nil, nil, nil, 505, + nil, 505, 505, 505, 505, 505, 505, 505, nil, nil, + nil, nil, nil, 505, 505, 505, 505, 505, 505, 505, + nil, nil, 505, nil, nil, nil, nil, nil, nil, 505, + nil, nil, 505, 505, 505, 505, 505, 505, 505, 505, + nil, 505, 505, 505, nil, 505, 505, 505, 505, 505, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 505, + nil, nil, 505, nil, nil, 505, 505, nil, nil, 505, + nil, nil, nil, nil, nil, 505, nil, nil, nil, nil, + nil, nil, nil, 505, nil, nil, nil, nil, 505, 505, + 505, 505, nil, 505, 505, nil, nil, nil, 505, 505, + nil, 507, 507, 507, nil, 507, 505, nil, 505, 507, + 507, nil, nil, nil, 507, nil, 507, 507, 507, 507, + 507, 507, 507, nil, nil, nil, nil, nil, 507, 507, + 507, 507, 507, 507, 507, nil, nil, 507, nil, nil, + nil, nil, nil, nil, 507, nil, nil, 507, 507, 507, + 507, 507, 507, 507, 507, nil, 507, 507, 507, nil, + 507, 507, 507, 507, 507, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 507, nil, nil, 507, nil, nil, + 507, 507, nil, nil, 507, nil, 507, nil, nil, nil, + 507, nil, nil, nil, nil, nil, nil, nil, 507, nil, + nil, nil, nil, 507, 507, 507, 507, nil, 507, 507, + nil, nil, nil, 507, 507, nil, 511, 511, 511, nil, + 511, 507, nil, 507, 511, 511, nil, nil, nil, 511, + nil, 511, 511, 511, 511, 511, 511, 511, nil, nil, + nil, nil, nil, 511, 511, 511, 511, 511, 511, 511, + nil, nil, 511, nil, nil, nil, nil, nil, nil, 511, + nil, nil, 511, 511, 511, 511, 511, 511, 511, 511, + 511, 511, 511, 511, nil, 511, 511, 511, 511, 511, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 511, + nil, nil, 511, nil, nil, 511, 511, nil, nil, 511, + nil, 511, nil, nil, nil, 511, nil, nil, nil, nil, + nil, nil, nil, 511, nil, nil, nil, nil, 511, 511, + 511, 511, nil, 511, 511, nil, nil, nil, 511, 511, + nil, 514, 514, 514, nil, 514, 511, nil, 511, 514, + 514, nil, nil, nil, 514, nil, 514, 514, 514, 514, + 514, 514, 514, nil, nil, nil, nil, nil, 514, 514, + 514, 514, 514, 514, 514, nil, nil, 514, nil, nil, + nil, nil, nil, nil, 514, nil, nil, 514, 514, 514, + 514, 514, 514, 514, 514, 514, 514, 514, 514, nil, + 514, 514, 514, 514, 514, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 514, nil, nil, 514, nil, nil, + 514, 514, nil, nil, 514, nil, nil, nil, nil, nil, + 514, nil, nil, nil, nil, nil, nil, nil, 514, nil, + nil, nil, nil, 514, 514, 514, 514, nil, 514, 514, + nil, nil, nil, 514, 514, nil, 528, 528, 528, nil, + 528, 514, nil, 514, 528, 528, nil, nil, nil, 528, + nil, 528, 528, 528, 528, 528, 528, 528, nil, nil, + nil, nil, nil, 528, 528, 528, 528, 528, 528, 528, + nil, nil, 528, nil, nil, nil, nil, nil, nil, 528, + nil, nil, 528, 528, 528, 528, 528, 528, 528, 528, + nil, 528, 528, 528, nil, 528, 528, 528, 528, 528, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 528, + nil, nil, 528, nil, nil, 528, 528, nil, nil, 528, + nil, 528, nil, nil, nil, 528, nil, nil, nil, nil, + nil, nil, nil, 528, nil, nil, nil, nil, 528, 528, + 528, 528, nil, 528, 528, nil, nil, nil, 528, 528, + nil, 529, 529, 529, nil, 529, 528, nil, 528, 529, + 529, nil, nil, nil, 529, nil, 529, 529, 529, 529, + 529, 529, 529, nil, nil, nil, nil, nil, 529, 529, + 529, 529, 529, 529, 529, nil, nil, 529, nil, nil, + nil, nil, nil, nil, 529, nil, nil, 529, 529, 529, + 529, 529, 529, 529, 529, 529, 529, 529, 529, nil, + 529, 529, 529, 529, 529, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 529, nil, nil, 529, nil, nil, + 529, 529, nil, nil, 529, nil, 529, nil, 529, nil, + 529, nil, nil, nil, nil, nil, nil, nil, 529, nil, + nil, nil, nil, 529, 529, 529, 529, nil, 529, 529, + nil, nil, nil, 529, 529, nil, 539, 539, 539, nil, + 539, 529, nil, 529, 539, 539, nil, nil, nil, 539, + nil, 539, 539, 539, 539, 539, 539, 539, nil, nil, + nil, nil, nil, 539, 539, 539, 539, 539, 539, 539, + nil, nil, 539, nil, nil, nil, nil, nil, nil, 539, + nil, nil, 539, 539, 539, 539, 539, 539, 539, 539, + 539, 539, 539, 539, nil, 539, 539, 539, 539, 539, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 539, + nil, nil, 539, nil, nil, 539, 539, nil, nil, 539, + nil, 539, nil, 539, nil, 539, nil, nil, nil, nil, + nil, nil, nil, 539, nil, nil, nil, nil, 539, 539, + 539, 539, nil, 539, 539, nil, nil, nil, 539, 539, + nil, 542, 542, 542, nil, 542, 539, nil, 539, 542, + 542, nil, nil, nil, 542, nil, 542, 542, 542, 542, + 542, 542, 542, nil, nil, nil, nil, nil, 542, 542, + 542, 542, 542, 542, 542, nil, nil, 542, nil, nil, + nil, nil, nil, nil, 542, nil, nil, 542, 542, 542, + 542, 542, 542, 542, 542, nil, 542, 542, 542, nil, + 542, 542, 542, 542, 542, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 542, nil, nil, 542, nil, nil, + 542, 542, nil, nil, 542, nil, nil, nil, nil, nil, + 542, nil, nil, nil, nil, nil, nil, nil, 542, nil, + nil, nil, nil, 542, 542, 542, 542, nil, 542, 542, + nil, nil, nil, 542, 542, nil, 571, 571, 571, nil, + 571, 542, nil, 542, 571, 571, nil, nil, nil, 571, + nil, 571, 571, 571, 571, 571, 571, 571, nil, nil, + nil, nil, nil, 571, 571, 571, 571, 571, 571, 571, + nil, nil, 571, nil, nil, nil, nil, nil, nil, 571, + nil, nil, 571, 571, 571, 571, 571, 571, 571, 571, + nil, 571, 571, 571, nil, 571, 571, 571, 571, 571, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 571, + nil, nil, 571, nil, nil, 571, 571, nil, nil, 571, + nil, 571, nil, nil, nil, 571, nil, nil, nil, nil, + nil, nil, nil, 571, nil, nil, nil, nil, 571, 571, + 571, 571, nil, 571, 571, nil, nil, nil, 571, 571, + nil, 572, 572, 572, nil, 572, 571, nil, 571, 572, + 572, nil, nil, nil, 572, nil, 572, 572, 572, 572, + 572, 572, 572, nil, nil, nil, nil, nil, 572, 572, + 572, 572, 572, 572, 572, nil, nil, 572, nil, nil, + nil, nil, nil, nil, 572, nil, nil, 572, 572, 572, + 572, 572, 572, 572, 572, nil, 572, 572, 572, nil, + 572, 572, 572, 572, 572, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 572, nil, nil, 572, nil, nil, + 572, 572, nil, nil, 572, nil, nil, nil, nil, nil, + 572, nil, nil, nil, nil, nil, nil, nil, 572, nil, + nil, nil, nil, 572, 572, 572, 572, nil, 572, 572, + nil, nil, nil, 572, 572, nil, 575, 575, 575, nil, + 575, 572, nil, 572, 575, 575, nil, nil, nil, 575, + nil, 575, 575, 575, 575, 575, 575, 575, nil, nil, + nil, nil, nil, 575, 575, 575, 575, 575, 575, 575, + nil, nil, 575, nil, nil, nil, nil, nil, nil, 575, + nil, nil, 575, 575, 575, 575, 575, 575, 575, 575, + 575, 575, 575, 575, nil, 575, 575, 575, 575, 575, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 575, + nil, nil, 575, nil, nil, 575, 575, nil, nil, 575, + nil, 575, nil, 575, nil, 575, nil, nil, nil, nil, + nil, nil, nil, 575, nil, nil, nil, nil, 575, 575, + 575, 575, nil, 575, 575, nil, nil, nil, 575, 575, + nil, 576, 576, 576, nil, 576, 575, nil, 575, 576, + 576, nil, nil, nil, 576, nil, 576, 576, 576, 576, + 576, 576, 576, nil, nil, nil, nil, nil, 576, 576, + 576, 576, 576, 576, 576, nil, nil, 576, nil, nil, + nil, nil, nil, nil, 576, nil, nil, 576, 576, 576, + 576, 576, 576, 576, 576, 576, 576, 576, 576, nil, + 576, 576, 576, 576, 576, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 576, nil, nil, 576, nil, nil, + 576, 576, nil, nil, 576, nil, nil, nil, 576, nil, + 576, nil, nil, nil, nil, nil, nil, nil, 576, nil, + nil, nil, nil, 576, 576, 576, 576, nil, 576, 576, + nil, nil, nil, 576, 576, nil, 577, 577, 577, nil, + 577, 576, nil, 576, 577, 577, nil, nil, nil, 577, + nil, 577, 577, 577, 577, 577, 577, 577, nil, nil, + nil, nil, nil, 577, 577, 577, 577, 577, 577, 577, + nil, nil, 577, nil, nil, nil, nil, nil, nil, 577, + nil, nil, 577, 577, 577, 577, 577, 577, 577, 577, + nil, 577, 577, 577, nil, 577, 577, 577, 577, 577, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 577, + nil, nil, 577, nil, nil, 577, 577, nil, nil, 577, + nil, nil, nil, nil, nil, 577, nil, nil, nil, nil, + nil, nil, nil, 577, nil, nil, nil, nil, 577, 577, + 577, 577, nil, 577, 577, nil, nil, nil, 577, 577, + nil, 578, 578, 578, nil, 578, 577, nil, 577, 578, + 578, nil, nil, nil, 578, nil, 578, 578, 578, 578, + 578, 578, 578, nil, nil, nil, nil, nil, 578, 578, + 578, 578, 578, 578, 578, nil, nil, 578, nil, nil, + nil, nil, nil, nil, 578, nil, nil, 578, 578, 578, + 578, 578, 578, 578, 578, nil, 578, 578, 578, nil, + 578, 578, 578, 578, 578, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 578, nil, nil, 578, nil, nil, + 578, 578, nil, nil, 578, nil, nil, nil, nil, nil, + 578, nil, nil, nil, nil, nil, nil, nil, 578, nil, + nil, nil, nil, 578, 578, 578, 578, nil, 578, 578, + nil, nil, nil, 578, 578, nil, 582, 582, 582, nil, + 582, 578, nil, 578, 582, 582, nil, nil, nil, 582, + nil, 582, 582, 582, 582, 582, 582, 582, nil, nil, + nil, nil, nil, 582, 582, 582, 582, 582, 582, 582, + nil, nil, 582, nil, nil, nil, nil, nil, nil, 582, + nil, nil, 582, 582, 582, 582, 582, 582, 582, 582, + nil, 582, 582, 582, nil, 582, 582, 582, 582, 582, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 582, + nil, nil, 582, nil, nil, 582, 582, nil, nil, 582, + nil, nil, nil, nil, nil, 582, nil, nil, nil, nil, + nil, nil, nil, 582, nil, nil, nil, nil, 582, 582, + 582, 582, nil, 582, 582, nil, nil, nil, 582, 582, + nil, 583, 583, 583, nil, 583, 582, nil, 582, 583, + 583, nil, nil, nil, 583, nil, 583, 583, 583, 583, + 583, 583, 583, nil, nil, nil, nil, nil, 583, 583, + 583, 583, 583, 583, 583, nil, nil, 583, nil, nil, + nil, nil, nil, nil, 583, nil, nil, 583, 583, 583, + 583, 583, 583, 583, 583, nil, 583, 583, 583, nil, + 583, 583, 583, 583, 583, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 583, nil, nil, 583, nil, nil, + 583, 583, nil, nil, 583, nil, nil, nil, nil, nil, + 583, nil, nil, nil, nil, nil, nil, nil, 583, nil, + nil, nil, nil, 583, 583, 583, 583, nil, 583, 583, + nil, nil, nil, 583, 583, nil, 586, 586, 586, nil, + 586, 583, nil, 583, 586, 586, nil, nil, nil, 586, + nil, 586, 586, 586, 586, 586, 586, 586, nil, nil, + nil, nil, nil, 586, 586, 586, 586, 586, 586, 586, + nil, nil, 586, nil, nil, nil, nil, nil, nil, 586, + nil, nil, 586, 586, 586, 586, 586, 586, 586, 586, + nil, 586, 586, 586, nil, 586, 586, 586, 586, 586, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 586, + nil, nil, 586, nil, nil, 586, 586, nil, nil, 586, + nil, nil, nil, nil, nil, 586, nil, nil, nil, nil, + nil, nil, nil, 586, nil, nil, nil, nil, 586, 586, + 586, 586, nil, 586, 586, nil, nil, nil, 586, 586, + nil, 587, 587, 587, nil, 587, 586, nil, 586, 587, + 587, nil, nil, nil, 587, nil, 587, 587, 587, 587, + 587, 587, 587, nil, nil, nil, nil, nil, 587, 587, + 587, 587, 587, 587, 587, nil, nil, 587, nil, nil, + nil, nil, nil, nil, 587, nil, nil, 587, 587, 587, + 587, 587, 587, 587, 587, nil, 587, 587, 587, nil, + 587, 587, 587, 587, 587, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 587, nil, nil, 587, nil, nil, + 587, 587, nil, nil, 587, nil, nil, nil, nil, nil, + 587, nil, nil, nil, nil, nil, nil, nil, 587, nil, + nil, nil, nil, 587, 587, 587, 587, nil, 587, 587, + nil, nil, nil, 587, 587, nil, 613, 613, 613, nil, + 613, 587, nil, 587, 613, 613, nil, nil, nil, 613, + nil, 613, 613, 613, 613, 613, 613, 613, nil, nil, + nil, nil, nil, 613, 613, 613, 613, 613, 613, 613, + nil, nil, 613, nil, nil, nil, nil, nil, nil, 613, + nil, nil, 613, 613, 613, 613, 613, 613, 613, 613, + nil, 613, 613, 613, nil, 613, 613, 613, 613, 613, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 613, + nil, nil, 613, nil, nil, 613, 613, nil, nil, 613, + nil, nil, nil, nil, nil, 613, nil, nil, nil, nil, + nil, nil, nil, 613, nil, nil, nil, nil, 613, 613, + 613, 613, nil, 613, 613, nil, nil, nil, 613, 613, + nil, 618, 618, 618, nil, 618, 613, nil, 613, 618, + 618, nil, nil, nil, 618, nil, 618, 618, 618, 618, + 618, 618, 618, nil, nil, nil, nil, nil, 618, 618, + 618, 618, 618, 618, 618, nil, nil, 618, nil, nil, + nil, nil, nil, nil, 618, nil, nil, 618, 618, 618, + 618, 618, 618, 618, 618, nil, 618, 618, 618, nil, + 618, 618, nil, nil, 618, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 618, nil, nil, 618, nil, nil, + 618, 618, nil, nil, 618, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 618, 618, 618, 618, nil, 618, 618, + nil, nil, nil, 618, 618, nil, 629, 629, 629, nil, + 629, 618, nil, 618, 629, 629, nil, nil, nil, 629, + nil, 629, 629, 629, 629, 629, 629, 629, nil, nil, + nil, nil, nil, 629, 629, 629, 629, 629, 629, 629, + nil, nil, 629, nil, nil, nil, nil, nil, nil, 629, + nil, nil, 629, 629, 629, 629, 629, 629, 629, 629, + nil, 629, 629, 629, nil, 629, 629, nil, nil, 629, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 629, + nil, nil, 629, nil, nil, 629, 629, nil, nil, 629, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 629, 629, + 629, 629, nil, 629, 629, nil, nil, nil, 629, 629, + nil, 681, 681, 681, nil, 681, 629, nil, 629, 681, + 681, nil, nil, nil, 681, nil, 681, 681, 681, 681, + 681, 681, 681, nil, nil, nil, nil, nil, 681, 681, + 681, 681, 681, 681, 681, nil, nil, 681, nil, nil, + nil, nil, nil, nil, 681, nil, nil, 681, 681, 681, + 681, 681, 681, 681, 681, nil, 681, 681, 681, nil, + 681, 681, 681, 681, 681, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 681, nil, nil, 681, nil, nil, + 681, 681, nil, nil, 681, nil, nil, nil, nil, nil, + 681, nil, nil, nil, nil, nil, nil, nil, 681, nil, + nil, nil, nil, 681, 681, 681, 681, nil, 681, 681, + nil, nil, nil, 681, 681, nil, 708, 708, 708, nil, + 708, 681, nil, 681, 708, 708, nil, nil, nil, 708, + nil, 708, 708, 708, 708, 708, 708, 708, nil, nil, + nil, nil, nil, 708, 708, 708, 708, 708, 708, 708, + nil, nil, 708, nil, nil, nil, nil, nil, nil, 708, + nil, nil, 708, 708, 708, 708, 708, 708, 708, 708, + nil, 708, 708, 708, nil, 708, 708, 708, 708, 708, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 708, + nil, nil, 708, nil, nil, 708, 708, nil, nil, 708, + nil, nil, nil, nil, nil, 708, nil, nil, nil, nil, + nil, nil, nil, 708, nil, nil, nil, nil, 708, 708, + 708, 708, nil, 708, 708, nil, nil, nil, 708, 708, + nil, 710, 710, 710, nil, 710, 708, nil, 708, 710, + 710, nil, nil, nil, 710, nil, 710, 710, 710, 710, + 710, 710, 710, nil, nil, nil, nil, nil, 710, 710, + 710, 710, 710, 710, 710, nil, nil, 710, nil, nil, + nil, nil, nil, nil, 710, nil, nil, 710, 710, 710, + 710, 710, 710, 710, 710, nil, 710, 710, 710, nil, + 710, 710, 710, 710, 710, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 710, nil, nil, 710, nil, nil, + 710, 710, nil, nil, 710, nil, nil, nil, nil, nil, + 710, nil, nil, nil, nil, nil, nil, nil, 710, nil, + nil, nil, nil, 710, 710, 710, 710, nil, 710, 710, + nil, nil, nil, 710, 710, nil, 724, 724, 724, nil, + 724, 710, nil, 710, 724, 724, nil, nil, nil, 724, + nil, 724, 724, 724, 724, 724, 724, 724, nil, nil, + nil, nil, nil, 724, 724, 724, 724, 724, 724, 724, + nil, nil, 724, nil, nil, nil, nil, nil, nil, 724, + nil, nil, 724, 724, 724, 724, 724, 724, 724, 724, + nil, 724, 724, 724, nil, 724, 724, 724, 724, 724, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 724, + nil, nil, 724, nil, nil, 724, 724, nil, nil, 724, + nil, nil, nil, nil, nil, 724, nil, nil, nil, nil, + nil, nil, nil, 724, nil, nil, nil, nil, 724, 724, + 724, 724, nil, 724, 724, nil, nil, nil, 724, 724, + nil, 725, 725, 725, nil, 725, 724, nil, 724, 725, + 725, nil, nil, nil, 725, nil, 725, 725, 725, 725, + 725, 725, 725, nil, nil, nil, nil, nil, 725, 725, + 725, 725, 725, 725, 725, nil, nil, 725, nil, nil, + nil, nil, nil, nil, 725, nil, nil, 725, 725, 725, + 725, 725, 725, 725, 725, nil, 725, 725, 725, nil, + 725, 725, 725, 725, 725, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 725, nil, nil, 725, nil, nil, + 725, 725, nil, nil, 725, nil, nil, nil, nil, nil, + 725, nil, nil, nil, nil, nil, nil, nil, 725, nil, + nil, nil, nil, 725, 725, 725, 725, nil, 725, 725, + nil, nil, nil, 725, 725, nil, 726, 726, 726, nil, + 726, 725, nil, 725, 726, 726, nil, nil, nil, 726, + nil, 726, 726, 726, 726, 726, 726, 726, nil, nil, + nil, nil, nil, 726, 726, 726, 726, 726, 726, 726, + nil, nil, 726, nil, nil, nil, nil, nil, nil, 726, + nil, nil, 726, 726, 726, 726, 726, 726, 726, 726, + nil, 726, 726, 726, nil, 726, 726, 726, 726, 726, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 726, + nil, nil, 726, nil, nil, 726, 726, nil, nil, 726, + nil, nil, nil, nil, nil, 726, nil, nil, nil, nil, + nil, nil, nil, 726, nil, nil, nil, nil, 726, 726, + 726, 726, nil, 726, 726, nil, nil, nil, 726, 726, + nil, 727, 727, 727, nil, 727, 726, nil, 726, 727, + 727, nil, nil, nil, 727, nil, 727, 727, 727, 727, + 727, 727, 727, nil, nil, nil, nil, nil, 727, 727, + 727, 727, 727, 727, 727, nil, nil, 727, nil, nil, + nil, nil, nil, nil, 727, nil, nil, 727, 727, 727, + 727, 727, 727, 727, 727, nil, 727, 727, 727, nil, + 727, 727, 727, 727, 727, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 727, nil, nil, 727, nil, nil, + 727, 727, nil, nil, 727, nil, nil, nil, nil, nil, + 727, nil, nil, nil, nil, nil, nil, nil, 727, nil, + nil, nil, nil, 727, 727, 727, 727, nil, 727, 727, + nil, nil, nil, 727, 727, nil, 729, 729, 729, nil, + 729, 727, nil, 727, 729, 729, nil, nil, nil, 729, + nil, 729, 729, 729, 729, 729, 729, 729, nil, nil, + nil, nil, nil, 729, 729, 729, 729, 729, 729, 729, + nil, nil, 729, nil, nil, nil, nil, nil, nil, 729, + nil, nil, 729, 729, 729, 729, 729, 729, 729, 729, + nil, 729, 729, 729, nil, 729, 729, 729, 729, 729, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 729, + nil, nil, 729, nil, nil, 729, 729, nil, nil, 729, + nil, nil, nil, nil, nil, 729, nil, nil, nil, nil, + nil, nil, nil, 729, nil, nil, nil, nil, 729, 729, + 729, 729, nil, 729, 729, nil, nil, nil, 729, 729, + nil, 754, 754, 754, nil, 754, 729, nil, 729, 754, + 754, nil, nil, nil, 754, nil, 754, 754, 754, 754, + 754, 754, 754, nil, nil, nil, nil, nil, 754, 754, + 754, 754, 754, 754, 754, nil, nil, 754, nil, nil, + nil, nil, nil, nil, 754, nil, nil, 754, 754, 754, + 754, 754, 754, 754, 754, nil, 754, 754, 754, nil, + 754, 754, nil, nil, 754, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 754, nil, nil, 754, nil, nil, + 754, 754, nil, nil, 754, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 754, 754, 754, 754, nil, 754, 754, + nil, nil, nil, 754, 754, nil, 768, 768, 768, nil, + 768, 754, nil, 754, 768, 768, nil, nil, nil, 768, + nil, 768, 768, 768, 768, 768, 768, 768, nil, nil, + nil, nil, nil, 768, 768, 768, 768, 768, 768, 768, + nil, nil, 768, nil, nil, nil, nil, nil, nil, 768, + nil, nil, 768, 768, 768, 768, 768, 768, 768, 768, + nil, 768, 768, 768, nil, 768, 768, 768, 768, 768, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 768, + nil, nil, 768, nil, nil, 768, 768, nil, nil, 768, + nil, nil, nil, nil, nil, 768, nil, nil, nil, nil, + nil, nil, nil, 768, nil, nil, nil, nil, 768, 768, + 768, 768, nil, 768, 768, nil, nil, nil, 768, 768, + nil, 780, 780, 780, nil, 780, 768, nil, 768, 780, + 780, nil, nil, nil, 780, nil, 780, 780, 780, 780, + 780, 780, 780, nil, nil, nil, nil, nil, 780, 780, + 780, 780, 780, 780, 780, nil, nil, 780, nil, nil, + nil, nil, nil, nil, 780, nil, nil, 780, 780, 780, + 780, 780, 780, 780, 780, nil, 780, 780, 780, nil, + 780, 780, 780, 780, 780, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 780, nil, nil, 780, nil, nil, + 780, 780, nil, nil, 780, nil, nil, nil, nil, nil, + 780, nil, nil, nil, nil, nil, nil, nil, 780, nil, + nil, nil, nil, 780, 780, 780, 780, nil, 780, 780, + nil, nil, nil, 780, 780, nil, 785, 785, 785, nil, + 785, 780, nil, 780, 785, 785, nil, nil, nil, 785, + nil, 785, 785, 785, 785, 785, 785, 785, nil, nil, + nil, nil, nil, 785, 785, 785, 785, 785, 785, 785, + nil, nil, 785, nil, nil, nil, nil, nil, nil, 785, + nil, nil, 785, 785, 785, 785, 785, 785, 785, 785, + nil, 785, 785, 785, nil, 785, 785, 785, 785, 785, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 785, + nil, nil, 785, nil, nil, 785, 785, nil, nil, 785, + nil, 785, nil, nil, nil, 785, nil, nil, nil, nil, + nil, nil, nil, 785, nil, nil, nil, nil, 785, 785, + 785, 785, nil, 785, 785, nil, nil, nil, 785, 785, + nil, 802, 802, 802, nil, 802, 785, nil, 785, 802, + 802, nil, nil, nil, 802, nil, 802, 802, 802, 802, + 802, 802, 802, nil, nil, nil, nil, nil, 802, 802, + 802, 802, 802, 802, 802, nil, nil, 802, nil, nil, + nil, nil, nil, nil, 802, nil, nil, 802, 802, 802, + 802, 802, 802, 802, 802, 802, 802, 802, 802, nil, + 802, 802, 802, 802, 802, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 802, nil, nil, 802, nil, nil, + 802, 802, nil, nil, 802, nil, nil, nil, 802, nil, + 802, nil, nil, nil, nil, nil, nil, nil, 802, nil, + nil, nil, nil, 802, 802, 802, 802, nil, 802, 802, + nil, nil, nil, 802, 802, nil, 803, 803, 803, nil, + 803, 802, nil, 802, 803, 803, nil, nil, nil, 803, + nil, 803, 803, 803, 803, 803, 803, 803, nil, nil, + nil, nil, nil, 803, 803, 803, 803, 803, 803, 803, + nil, nil, 803, nil, nil, nil, nil, nil, nil, 803, + nil, nil, 803, 803, 803, 803, 803, 803, 803, 803, + nil, 803, 803, 803, nil, 803, 803, 803, 803, 803, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 803, + nil, nil, 803, nil, nil, 803, 803, nil, nil, 803, + nil, nil, nil, nil, nil, 803, nil, nil, nil, nil, + nil, nil, nil, 803, nil, nil, nil, nil, 803, 803, + 803, 803, nil, 803, 803, nil, nil, nil, 803, 803, + nil, 817, 817, 817, nil, 817, 803, nil, 803, 817, + 817, nil, nil, nil, 817, nil, 817, 817, 817, 817, + 817, 817, 817, nil, nil, nil, nil, nil, 817, 817, + 817, 817, 817, 817, 817, nil, nil, 817, nil, nil, + nil, nil, nil, nil, 817, nil, nil, 817, 817, 817, + 817, 817, 817, 817, 817, nil, 817, 817, 817, nil, + 817, 817, nil, nil, 817, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 817, nil, nil, 817, nil, nil, + 817, 817, nil, nil, 817, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 817, 817, 817, 817, nil, 817, 817, + nil, nil, nil, 817, 817, nil, 874, 874, 874, nil, + 874, 817, nil, 817, 874, 874, nil, nil, nil, 874, + nil, 874, 874, 874, 874, 874, 874, 874, nil, nil, + nil, nil, nil, 874, 874, 874, 874, 874, 874, 874, + nil, nil, 874, nil, nil, nil, nil, nil, nil, 874, + nil, nil, 874, 874, 874, 874, 874, 874, 874, 874, + 874, 874, 874, 874, nil, 874, 874, 874, 874, 874, + 504, 504, 504, 504, 504, 504, 504, 504, 504, 504, + 504, nil, 504, 504, nil, nil, 504, 504, nil, 874, + nil, nil, 874, nil, nil, 874, 874, nil, nil, 874, + nil, 874, 504, 874, 504, 874, 504, 504, 504, 504, + 504, 504, 504, 874, 504, nil, nil, nil, 874, 874, + 874, 874, nil, 874, 874, nil, nil, nil, 874, 874, + nil, 504, 26, nil, nil, nil, 874, nil, 874, 26, + 26, 26, nil, nil, 26, 26, 26, nil, 26, nil, + nil, nil, nil, nil, nil, nil, nil, 26, 26, 26, + nil, nil, nil, nil, nil, nil, nil, nil, 26, 26, + nil, 26, 26, 26, 26, 26, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, nil, nil, 26, 26, 26, nil, nil, 26, + nil, 26, 26, nil, nil, 26, 26, nil, 26, nil, + 26, nil, 26, nil, 26, 26, 26, 26, 26, 26, + 26, 27, 26, 26, 26, nil, nil, nil, 27, 27, + 27, nil, nil, 27, 27, 27, nil, 27, 26, 26, + nil, 26, nil, 26, nil, nil, nil, 27, 27, nil, + nil, nil, nil, nil, nil, nil, nil, 27, 27, nil, + 27, 27, 27, 27, 27, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, nil, nil, 27, 27, 27, nil, nil, 27, nil, + 27, 27, nil, nil, 27, 27, nil, 27, nil, 27, + nil, 27, nil, 27, 27, 27, 27, 27, 27, 27, + 400, 27, nil, 27, nil, nil, nil, 400, 400, 400, + nil, nil, 400, 400, 400, nil, 400, 27, 27, nil, + 27, nil, 27, nil, nil, 400, 400, 400, nil, nil, + nil, nil, nil, nil, nil, nil, 400, 400, nil, 400, + 400, 400, 400, 400, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, + nil, nil, 400, 400, 400, nil, nil, 400, nil, 400, + 400, nil, nil, 400, 400, nil, 400, nil, 400, nil, + 400, nil, 400, 400, 400, 400, 400, 400, 400, 459, + 400, 400, 400, nil, nil, nil, 459, 459, 459, nil, + nil, 459, 459, 459, nil, 459, 400, 400, nil, 400, + nil, 400, nil, nil, nil, 459, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 459, 459, nil, 459, 459, + 459, 459, 459, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 462, nil, nil, nil, nil, nil, + nil, 462, 462, 462, nil, nil, 462, 462, 462, nil, + 462, nil, nil, nil, nil, nil, 459, nil, nil, nil, + 462, nil, nil, 459, nil, nil, nil, nil, 459, 459, + 462, 462, nil, 462, 462, 462, 462, 462, nil, nil, + nil, nil, nil, 203, 203, nil, nil, 203, nil, nil, + nil, 459, nil, nil, nil, 203, 203, nil, 203, 203, + 203, 203, 203, 203, 203, 459, nil, 203, 203, nil, + 459, 462, 203, 203, 203, 203, nil, nil, 462, nil, + nil, 203, nil, 462, 462, nil, nil, nil, nil, 203, + 203, nil, 203, 203, 203, 203, 203, 203, 203, 203, + 203, 203, 203, nil, nil, 203, 462, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 462, nil, nil, nil, nil, 462, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + nil, nil, nil, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, nil, nil, nil, nil, nil, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, nil, 8, + nil, nil, nil, nil, nil, nil, nil, 8, 8, nil, + 8, 8, 8, 8, 8, 8, 8, nil, nil, 8, + 8, nil, nil, nil, 8, 8, 8, 8, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 8, 8, nil, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, nil, nil, 8, 8, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, nil, nil, nil, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, nil, nil, nil, + nil, nil, 9, 9, 9, 9, 9, 9, 9, 9, + 9, nil, nil, 9, nil, nil, nil, nil, nil, nil, + nil, 9, 9, nil, 9, 9, 9, 9, 9, 9, + 9, nil, nil, 9, 9, nil, nil, nil, 9, 9, + 9, 9, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 9, 9, nil, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, nil, + nil, 9, 9, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 9, 381, 381, 381, 381, 381, 381, + 381, 381, 381, 381, 381, 381, 381, 381, 381, 381, + 381, 381, 381, 381, 381, 381, 381, 381, nil, nil, + nil, 381, 381, 381, 381, 381, 381, 381, 381, 381, + 381, nil, nil, nil, nil, nil, 381, 381, 381, 381, + 381, 381, 381, 381, 381, nil, nil, 381, nil, nil, + nil, nil, nil, nil, nil, 381, 381, nil, 381, 381, + 381, 381, 381, 381, 381, nil, nil, 381, 381, nil, + nil, nil, 381, 381, 381, 381, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 381, + 381, nil, 381, 381, 381, 381, 381, 381, 381, 381, + 381, 381, 381, nil, nil, 381, 381, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 381, 568, 568, + 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, + 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, + 568, 568, nil, nil, nil, 568, 568, 568, 568, 568, + 568, 568, 568, 568, 568, nil, nil, nil, nil, nil, + 568, 568, 568, 568, 568, 568, 568, 568, 568, nil, + nil, 568, nil, nil, nil, nil, nil, nil, nil, 568, + 568, nil, 568, 568, 568, 568, 568, 568, 568, nil, + nil, 568, 568, nil, nil, nil, 568, 568, 568, 568, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 568, 568, nil, 568, 568, 568, 568, + 568, 568, 568, 568, 568, 568, 568, nil, nil, 568, + 568, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 568, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, nil, nil, nil, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, nil, + nil, nil, nil, nil, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, nil, 68, nil, nil, + nil, nil, nil, 68, 68, nil, 68, 68, 68, 68, + 68, 68, 68, nil, nil, 68, 68, nil, nil, nil, + 68, 68, 68, 68, nil, nil, nil, nil, nil, 68, + nil, nil, nil, nil, nil, nil, nil, 68, 68, nil, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, nil, nil, 68, 694, 694, 694, 694, 694, 694, + 694, 694, 694, 694, 694, 694, 694, 694, 694, 694, + 694, 694, 694, 694, 694, 694, 694, 694, nil, nil, + nil, 694, 694, 694, 694, 694, 694, 694, 694, 694, + 694, nil, nil, nil, nil, nil, 694, 694, 694, 694, + 694, 694, 694, 694, 694, nil, nil, 694, nil, nil, + nil, nil, nil, nil, nil, 694, 694, nil, 694, 694, + 694, 694, 694, 694, 694, nil, nil, 694, 694, nil, + nil, nil, 694, 694, 694, 694, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 694, + 694, nil, 694, 694, 694, 694, 694, 694, 694, 694, + 694, 694, 694, 204, 204, 694, nil, 204, nil, nil, + nil, nil, nil, nil, nil, 204, 204, nil, 204, 204, + 204, 204, 204, 204, 204, nil, nil, 204, 204, nil, + nil, nil, 204, 204, 204, 204, nil, nil, nil, nil, + nil, 204, nil, nil, nil, nil, nil, nil, nil, 204, + 204, nil, 204, 204, 204, 204, 204, 204, 204, 204, + 204, 204, 204, 252, 252, 204, nil, 252, nil, nil, + nil, nil, nil, nil, nil, 252, 252, nil, 252, 252, + 252, 252, 252, 252, 252, nil, nil, 252, 252, nil, + nil, nil, 252, 252, 252, 252, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 252, + 252, nil, 252, 252, 252, 252, 252, 252, 252, 252, + 252, 252, 252, 253, 253, 252, nil, 253, nil, nil, + nil, nil, nil, nil, nil, 253, 253, nil, 253, 253, + 253, 253, 253, 253, 253, nil, nil, 253, 253, nil, + nil, nil, 253, 253, 253, 253, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 253, + 253, nil, 253, 253, 253, 253, 253, 253, 253, 253, + 253, 253, 253, 425, 425, 253, nil, 425, nil, nil, + nil, nil, nil, nil, nil, 425, 425, nil, 425, 425, + 425, 425, 425, 425, 425, nil, nil, 425, 425, nil, + nil, nil, 425, 425, 425, 425, nil, nil, nil, nil, + nil, 425, nil, nil, nil, nil, nil, nil, nil, 425, + 425, nil, 425, 425, 425, 425, 425, 425, 425, 425, + 425, 425, 425, 426, 426, 425, nil, 426, nil, nil, + nil, nil, nil, nil, nil, 426, 426, nil, 426, 426, + 426, 426, 426, 426, 426, nil, nil, 426, 426, nil, + nil, nil, 426, 426, 426, 426, nil, nil, nil, nil, + nil, 426, nil, nil, nil, nil, nil, nil, nil, 426, + 426, nil, 426, 426, 426, 426, 426, 426, 426, 426, + 426, 426, 426, 490, 490, 426, nil, 490, nil, nil, + nil, nil, nil, nil, nil, 490, 490, nil, 490, 490, + 490, 490, 490, 490, 490, nil, nil, 490, 490, nil, + nil, nil, 490, 490, 490, 490, nil, nil, nil, nil, + nil, 490, nil, nil, nil, nil, nil, nil, nil, 490, + 490, nil, 490, 490, 490, 490, 490, 490, 490, 490, + 490, 490, 490, 491, 491, 490, nil, 491, nil, nil, + nil, nil, nil, nil, nil, 491, 491, nil, 491, 491, + 491, 491, 491, 491, 491, nil, nil, 491, 491, nil, + nil, nil, 491, 491, 491, 491, nil, nil, nil, nil, + nil, 491, nil, nil, nil, nil, nil, nil, nil, 491, + 491, nil, 491, 491, 491, 491, 491, 491, 491, 491, + 491, 491, 491, 502, 502, 491, nil, 502, nil, nil, + nil, nil, nil, nil, nil, 502, 502, nil, 502, 502, + 502, 502, 502, 502, 502, nil, nil, 502, 502, nil, + nil, nil, 502, 502, 502, 502, nil, nil, nil, nil, + nil, 502, nil, nil, nil, nil, nil, nil, nil, 502, + 502, nil, 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 503, 503, 502, nil, 503, nil, nil, + nil, nil, nil, nil, nil, 503, 503, nil, 503, 503, + 503, 503, 503, 503, 503, nil, nil, 503, 503, nil, + nil, nil, 503, 503, 503, 503, nil, nil, nil, nil, + nil, 503, nil, nil, nil, nil, nil, nil, nil, 503, + 503, nil, 503, 503, 503, 503, 503, 503, 503, 503, + 503, 503, 503, 530, 530, 503, nil, 530, nil, nil, + nil, nil, nil, nil, nil, 530, 530, nil, 530, 530, + 530, 530, 530, 530, 530, nil, nil, 530, 530, nil, + nil, nil, 530, 530, 530, 530, nil, nil, nil, nil, + nil, 530, nil, nil, nil, nil, nil, nil, nil, 530, + 530, nil, 530, 530, 530, 530, 530, 530, 530, 530, + 530, 530, 530, 531, 531, 530, nil, 531, nil, nil, + nil, nil, nil, nil, nil, 531, 531, nil, 531, 531, + 531, 531, 531, 531, 531, nil, nil, 531, 531, nil, + nil, nil, 531, 531, 531, 531, nil, nil, nil, nil, + nil, 531, nil, nil, nil, nil, nil, nil, nil, 531, + 531, nil, 531, 531, 531, 531, 531, 531, 531, 531, + 531, 531, 531, 537, 537, 531, nil, 537, nil, nil, + nil, nil, nil, nil, nil, 537, 537, nil, 537, 537, + 537, 537, 537, 537, 537, nil, nil, 537, 537, nil, + nil, nil, 537, 537, 537, 537, nil, nil, nil, nil, + nil, 537, nil, nil, nil, nil, nil, nil, nil, 537, + 537, nil, 537, 537, 537, 537, 537, 537, 537, 537, + 537, 537, 537, 538, 538, 537, nil, 538, nil, nil, + nil, nil, nil, nil, nil, 538, 538, nil, 538, 538, + 538, 538, 538, 538, 538, nil, nil, 538, 538, nil, + nil, nil, 538, 538, 538, 538, nil, nil, nil, nil, + nil, 538, nil, nil, nil, nil, nil, nil, nil, 538, + 538, nil, 538, 538, 538, 538, 538, 538, 538, 538, + 538, 538, 538, 875, 875, 538, nil, 875, nil, nil, + nil, nil, nil, nil, nil, 875, 875, nil, 875, 875, + 875, 875, 875, 875, 875, nil, nil, 875, 875, nil, + nil, nil, 875, 875, 875, 875, nil, nil, nil, nil, + nil, 875, nil, nil, nil, nil, nil, nil, nil, 875, + 875, nil, 875, 875, 875, 875, 875, 875, 875, 875, + 875, 875, 875, 876, 876, 875, nil, 876, nil, nil, + nil, nil, nil, nil, nil, 876, 876, nil, 876, 876, + 876, 876, 876, 876, 876, nil, nil, 876, 876, nil, + nil, nil, 876, 876, 876, 876, nil, nil, nil, nil, + nil, 876, nil, nil, nil, nil, nil, nil, nil, 876, + 876, nil, 876, 876, 876, 876, 876, 876, 876, 876, + 876, 876, 876, 913, 913, 876, nil, 913, nil, nil, + nil, nil, nil, nil, nil, 913, 913, nil, 913, 913, + 913, 913, 913, 913, 913, nil, nil, 913, 913, nil, + nil, nil, 913, 913, 913, 913, nil, nil, nil, nil, + nil, 913, nil, nil, nil, nil, nil, nil, nil, 913, + 913, nil, 913, 913, 913, 913, 913, 913, 913, 913, + 913, 913, 913, nil, nil, 913, 630, 630, 630, 630, + 630, 630, 630, 630, 630, 630, 630, nil, 630, 630, + nil, nil, 630, 630, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 630, nil, + 630, nil, 630, 630, 630, 630, 630, 630, 630, nil, + 630, nil, 709, 709, 709, 709, 709, 709, 709, 709, + 709, 709, 709, nil, 709, 709, nil, 630, 709, 709, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 709, nil, 709, nil, 709, 709, + 709, 709, 709, 709, 709, nil, 709, nil, 714, 714, + 714, 714, 714, 714, 714, 714, 714, 714, 714, nil, + 714, 714, nil, 709, 714, 714, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 714, nil, 714, nil, 714, 714, 714, 714, 714, 714, + 714, nil, 714, nil, 716, 716, 716, 716, 716, 716, + 716, 716, 716, 716, 716, nil, 716, 716, nil, 714, + 716, 716, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 716, nil, 716, nil, + 716, 716, 716, 716, 716, 716, 716, nil, 716, nil, + 719, 719, 719, 719, 719, 719, 719, 719, 719, 719, + 719, nil, 719, 719, nil, 716, 719, 719, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 719, nil, 719, nil, 719, 719, 719, 719, + 719, 719, 719, nil, 719, nil, 721, 721, 721, 721, + 721, 721, 721, 721, 721, 721, 721, nil, 721, 721, + nil, 719, 721, 721, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 721, nil, + 721, nil, 721, 721, 721, 721, 721, 721, 721, nil, + 721, nil, 723, 723, 723, 723, 723, 723, 723, 723, + 723, 723, 723, nil, 723, 723, nil, 721, 723, 723, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 723, nil, 723, nil, 723, 723, + 723, 723, 723, 723, 723, nil, 723, nil, 801, 801, + 801, 801, 801, 801, 801, 801, 801, 801, 801, nil, + 801, 801, nil, 723, 801, 801, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 801, nil, 801, nil, 801, 801, 801, 801, 801, 801, + 801, nil, 801, nil, 804, 804, 804, 804, 804, 804, + 804, 804, 804, 804, 804, nil, 804, 804, nil, 801, + 804, 804, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 804, nil, 804, nil, + 804, 804, 804, 804, 804, 804, 804, nil, 804, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 804 ] + +racc_action_pointer = [ + 0, 80, nil, 62, nil, 4744, 1249, 39, 21174, 21298, + 100, nil, 84, 143, 544, 55, 108, 127, nil, -8, + 4869, 6502, 257, nil, 76, 261, 20662, 20771, 4994, 5119, + 5244, nil, 738, 5369, 5494, nil, 174, 240, 361, 273, + 240, 5627, 5752, 5877, 212, 572, nil, nil, nil, nil, + nil, nil, nil, 866, 999, nil, 6002, 6127, 0, nil, + 6252, 6377, nil, nil, 6502, 6635, 6760, 6885, 21670, nil, + nil, nil, nil, nil, nil, nil, 568, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, + nil, nil, 130, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 382, nil, 7010, nil, nil, nil, nil, + 7143, 7268, 7393, 7518, 7643, 1124, nil, 449, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 265, nil, 1249, + 7768, 7893, 8018, 21042, 21842, 8143, 8268, 8393, 8518, 8643, + 8768, nil, nil, 607, 54, 139, 350, 244, 272, 325, + nil, 8893, 1374, 339, 9018, 9143, 9268, 9393, 9518, 9643, + 9768, 9893, 10018, 10143, 10268, 10393, 10518, 10643, 10768, 10893, + 11018, 11143, 11268, 11393, 11518, 11643, 11768, 11893, 12018, 12143, + nil, nil, 21902, 21962, 344, 12268, 12393, nil, nil, nil, + nil, nil, nil, nil, 12518, nil, 7010, nil, 335, 337, + nil, 12643, 383, 12768, nil, 12893, nil, nil, 282, 1374, + 13018, 349, 1499, 391, 448, 433, 13143, 1624, 611, 738, + 741, 517, 784, nil, 493, 467, 346, nil, nil, nil, + 508, 431, 476, 13276, nil, 376, 548, 552, 838, nil, + 568, nil, 13401, 687, 689, 13526, nil, 252, 392, 618, + 604, 509, 637, nil, nil, 614, 48, 136, 13651, 13776, + 403, 710, 604, 65, 89, 874, 682, 98, 721, nil, + nil, 442, 443, 96, nil, 898, nil, 55, 13901, nil, + nil, nil, 360, 388, 392, 420, 453, 549, 571, 576, + 582, nil, 641, nil, 14026, nil, 401, 465, 468, 473, + 39, 501, nil, nil, nil, nil, nil, nil, nil, nil, + 650, 21422, nil, nil, nil, nil, 665, nil, 655, nil, + 14151, 665, nil, 1624, 672, nil, 690, 699, 478, 512, + 20880, nil, nil, nil, 239, 348, 743, nil, nil, 1752, + 1861, nil, 13143, nil, 702, nil, nil, 738, nil, nil, + nil, nil, 283, nil, 761, 22022, 22082, 14276, 248, 14401, + 14526, 14651, 2369, 2494, 89, 648, 790, 794, 798, 803, + 3994, 4119, 4244, 2619, 1810, 2744, 2869, 2994, 3119, 3244, + 3369, 3494, 3619, 559, 793, 3744, 3869, 15151, 136, 20989, + nil, nil, 21044, nil, nil, 745, nil, 175, 293, 750, + nil, nil, 14776, nil, 14901, nil, 15026, nil, nil, nil, + 15151, 1404, 760, 761, nil, nil, 770, 15284, 774, 15409, + 22142, 22202, 903, 812, nil, nil, 15534, 775, nil, 15659, + 15784, 15909, 22262, 22322, 20534, 16034, 897, 16159, nil, 631, + nil, 16284, nil, nil, 16409, nil, nil, nil, nil, 1716, + 1994, 912, nil, 2119, 119, 142, 909, 917, 16534, 16659, + 22382, 22442, 112, nil, nil, 931, nil, 22502, 22562, 16784, + nil, nil, 16909, 596, 146, 2244, 5382, nil, nil, nil, + 317, nil, nil, nil, 721, nil, nil, nil, 828, nil, + nil, 373, nil, nil, 822, nil, nil, nil, 21546, nil, + 826, 17034, 17159, 523, 863, 17284, 17409, 17534, 17659, 869, + nil, nil, 17784, 17909, 881, nil, 18034, 18159, nil, nil, + 277, 353, 473, 603, 853, 5494, 853, nil, 830, nil, + 2369, nil, nil, nil, nil, 302, nil, 2494, 2619, nil, + 854, nil, 897, 18284, nil, nil, 1499, 251, 18409, 856, + nil, 860, 125, 198, 899, 481, 1379, 900, 861, 18534, + 22790, 932, 940, 323, 999, nil, 2744, 882, 925, nil, + nil, 887, 698, 131, 666, nil, 894, 896, 897, nil, + nil, nil, nil, nil, nil, 892, nil, 866, nil, nil, + nil, nil, 984, nil, nil, 990, 836, nil, 1031, nil, + nil, nil, nil, 1046, nil, 140, 933, 141, 156, 263, + 269, 18659, 543, 1504, nil, 940, 2869, 602, nil, nil, + 1061, 2994, 1052, 621, 21782, nil, nil, nil, nil, nil, + nil, 3119, nil, nil, nil, nil, nil, 943, 18784, 22836, + 18909, nil, 945, nil, 22882, nil, 22928, nil, nil, 22974, + nil, 23020, nil, 23066, 19034, 19159, 19284, 19409, 356, 19534, + 949, 951, 952, nil, 974, 952, 985, 950, nil, 1077, + 3244, 976, 1080, nil, nil, 963, 352, nil, nil, nil, + 3369, nil, nil, 163, 19659, nil, 1003, nil, nil, nil, + nil, 973, 1177, nil, 1302, nil, nil, 1022, 19784, nil, + 1014, nil, 983, 342, nil, 991, nil, nil, 1111, nil, + 19909, 1127, 3494, 3619, nil, 20034, 3744, 171, 205, nil, + 1128, nil, 3869, nil, 1129, 1022, nil, nil, 1048, 1037, + nil, 23112, 20159, 20284, 23158, 1427, nil, 1552, nil, nil, + 1147, nil, 1072, 1055, nil, nil, nil, 20409, nil, 1079, + nil, nil, nil, 3994, 1277, 1365, 1380, 1140, 1383, nil, + nil, 4119, 4244, 1071, 1070, 1074, nil, nil, 1076, 1077, + nil, 1078, nil, 1082, 1139, 1081, 859, nil, nil, 164, + nil, 1202, 1204, nil, 107, nil, nil, 1205, nil, nil, + 6648, nil, 1088, 1089, 1100, 1108, nil, 1113, nil, 1110, + 1393, 1190, nil, 1254, 20534, 22622, 22682, 1490, 1150, 1254, + nil, 2047, nil, nil, 1272, nil, 1397, nil, 1522, nil, + nil, nil, 349, 1044, 1144, 4369, nil, nil, nil, nil, + nil, 4494, nil, 4619, 2172, nil, nil, 2017, nil, 2142, + nil, nil, nil, 22742, nil, nil, 1159, 165, 166, 209, + 1624, nil, nil, 1157, 1166, 1176, 1180, 1187, 1169, 1191, + 1264, 875, 1313, 1315, 1199, 1201, 1202, 1203, 1244, 1246, + 173, nil, 2266, nil, nil, nil, 1294, 1207, nil, nil, + nil, nil, 2295, nil, nil, nil, 1209, 1210, 1213, nil, + nil ] + +racc_action_default = [ + -3, -552, -1, -538, -4, -552, -7, -552, -552, -552, + -552, -27, -552, -552, -552, -274, -552, -39, -42, -540, + -552, -47, -49, -50, -51, -255, -255, -255, -285, -321, + -322, -67, -11, -71, -79, -81, -552, -467, -468, -552, + -552, -552, -552, -552, -540, -236, -267, -268, -269, -270, + -271, -272, -273, -528, -11, -277, -551, -520, -293, -295, + -552, -552, -299, -302, -538, -552, -552, -552, -552, -323, + -324, -326, -327, -416, -417, -418, -419, -420, -435, -423, + -424, -437, -439, -428, -433, -449, -437, -451, -452, -526, + -456, -457, -527, -459, -460, -461, -462, -463, -464, -465, + -466, -471, -472, -552, -2, -539, -547, -548, -549, -6, + -552, -552, -552, -552, -552, -3, -15, -552, -110, -111, + -112, -113, -114, -115, -116, -117, -118, -122, -123, -124, + -125, -126, -127, -128, -129, -130, -131, -132, -133, -134, + -135, -136, -137, -138, -139, -140, -141, -142, -143, -144, + -145, -146, -147, -148, -149, -150, -151, -152, -153, -154, + -155, -156, -157, -158, -159, -160, -161, -162, -163, -164, + -165, -166, -167, -168, -169, -170, -171, -172, -173, -174, + -175, -176, -177, -178, -179, -180, -181, -182, -183, -184, + -185, -186, -187, -188, -189, -190, -191, -20, -119, -11, + -552, -552, -245, -552, -552, -552, -552, -552, -552, -552, + -540, -541, -46, -552, -467, -468, -552, -274, -552, -552, + -228, -552, -11, -552, -552, -552, -552, -552, -552, -552, + -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, + -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, + -386, -388, -552, -552, -56, -245, -552, -292, -391, -400, + -402, -62, -397, -63, -540, -64, -237, -250, -259, -259, + -254, -552, -260, -552, -522, -552, -65, -66, -538, -12, + -552, -69, -11, -540, -552, -72, -75, -11, -87, -88, + -552, -552, -95, -285, -288, -540, -552, -321, -322, -325, + -398, -552, -77, -552, -83, -282, -453, -454, -552, -213, + -214, -229, -552, -408, -552, -552, -238, -544, -544, -552, + -552, -544, -552, -294, -378, -48, -552, -552, -552, -552, + -538, -552, -539, -467, -468, -552, -552, -274, -552, -337, + -338, -105, -106, -552, -108, -552, -274, -552, -552, -467, + -468, -314, -110, -111, -151, -152, -153, -169, -174, -181, + -184, -316, -552, -518, -552, -421, -552, -552, -552, -552, + -552, -552, 961, -5, -550, -21, -22, -23, -24, -25, + -552, -552, -17, -18, -19, -120, -552, -28, -37, -38, + -552, -552, -29, -194, -540, -246, -259, -259, -529, -530, + -255, -395, -531, -532, -530, -529, -255, -394, -396, -531, + -532, -35, -202, -36, -552, -40, -41, -192, -260, -43, + -44, -45, -540, -291, -552, -552, -552, -245, -282, -552, + -552, -552, -203, -204, -205, -206, -207, -208, -209, -210, + -215, -216, -217, -218, -219, -220, -221, -222, -223, -224, + -225, -226, -227, -230, -231, -232, -233, -540, -367, -255, + -529, -530, -255, -54, -57, -540, -256, -367, -367, -540, + -287, -251, -552, -252, -552, -257, -552, -261, -525, -10, + -539, -14, -540, -68, -280, -84, -73, -552, -540, -245, + -552, -552, -94, -552, -453, -454, -552, -80, -85, -552, + -552, -552, -552, -552, -234, -552, -551, -551, -276, -278, + -239, -546, -545, -241, -546, -283, -284, -521, -296, -492, + -11, -328, -329, -11, -552, -552, -552, -552, -552, -245, + -552, -552, -282, -307, -105, -106, -107, -552, -552, -245, + -310, -473, -552, -552, -552, -11, -492, -318, -536, -537, + -540, -422, -436, -441, -552, -443, -425, -438, -552, -440, + -427, -552, -430, -432, -552, -450, -8, -16, -552, -26, + -266, -552, -552, -399, -552, -247, -249, -552, -552, -58, + -244, -392, -552, -552, -60, -393, -552, -552, -290, -542, + -529, -530, -529, -530, -540, -192, -552, -368, -372, -370, + -11, -52, -389, -53, -390, -367, -242, -11, -11, -286, + -259, -258, -262, -552, -523, -524, -13, -70, -552, -76, + -82, -540, -529, -530, -243, -91, -93, -552, -78, -552, + -201, -211, -212, -540, -551, -335, -11, -409, -551, -410, + -411, -540, -544, -552, -492, -381, -517, -517, -517, -491, + -493, -494, -495, -496, -497, -498, -499, -552, -501, -507, + -509, -510, -512, -513, -514, -552, -551, -330, -551, -300, + -331, -332, -303, -552, -306, -552, -540, -529, -530, -533, + -281, -552, -105, -106, -109, -540, -11, -552, -475, -312, + -552, -11, -492, -552, -552, -519, -442, -445, -446, -447, + -448, -11, -426, -429, -431, -434, -121, -264, -552, -195, + -552, -543, -259, -31, -197, -32, -198, -59, -33, -200, + -34, -199, -61, -193, -552, -552, -552, -552, -399, -552, + -517, -517, -517, -366, -552, -372, -552, -498, -505, -552, + -11, -552, -552, -253, -263, -74, -89, -86, -289, -9, + -11, -415, -336, -552, -552, -413, -552, -240, -379, -382, + -384, -372, -552, -484, -552, -487, -489, -552, -552, -339, + -552, -341, -343, -350, -498, -540, -511, -515, -552, -333, + -552, -552, -11, -11, -305, -552, -11, -399, -552, -399, + -552, -474, -11, -315, -552, -540, -477, -319, -552, -265, + -30, -196, -248, -552, -235, -357, -359, -552, -362, -364, + -552, -369, -552, -373, -374, -376, -377, -552, -387, -552, + -401, -403, -414, -11, -96, -97, -552, -552, -104, -412, + -279, -11, -11, -540, -517, -517, -502, -516, -517, -517, + -508, -517, -503, -540, -552, -348, -552, -500, -297, -552, + -298, -552, -552, -262, -551, -308, -311, -552, -317, -476, + -492, -444, -517, -517, -517, -517, -506, -517, -371, -552, + -504, -552, -55, -408, -245, -552, -552, -103, -552, -552, + -380, -552, -480, -482, -552, -485, -552, -488, -552, -490, + -340, -342, -346, -552, -351, -11, -301, -304, -404, -405, + -406, -11, -313, -11, -552, -354, -356, -552, -360, -552, + -363, -365, -375, -552, -282, -407, -540, -529, -530, -533, + -102, -383, -385, -517, -517, -517, -517, -344, -552, -349, + -552, -551, -552, -552, -517, -517, -517, -517, -281, -533, + -399, -478, -552, -481, -483, -486, -552, -347, -334, -309, + -320, -352, -552, -355, -358, -361, -517, -345, -517, -479, + -353 ] + +racc_goto_table = [ + 121, 121, 361, 506, 285, 13, 316, 209, 116, 198, + 13, 314, 394, 573, 124, 124, 14, 126, 126, 527, + 473, 14, 416, 299, 299, 108, 105, 634, 731, 281, + 302, 283, 312, 691, 520, 523, 213, 13, 734, 400, + 406, 389, 464, 814, 213, 213, 213, 413, 14, 290, + 290, 778, 536, 669, 672, 299, 299, 299, 614, 13, + 121, 497, 611, 284, 611, 465, 645, 254, 261, 263, + 14, 2, 816, 6, 109, 649, 213, 213, 6, 775, + 213, 335, 345, 345, 600, 840, 108, 866, 459, 462, + 104, 326, 327, 607, 608, 330, 510, 513, 614, 891, + 517, 1, 649, 836, 269, 269, 269, 367, 602, 749, + 13, 604, 371, 347, 351, 552, 197, 559, 562, 13, + 13, 14, 265, 276, 277, 340, 213, 213, 213, 213, + 14, 14, 318, 321, 381, 267, 267, 267, 605, 568, + 319, 375, 376, 377, 378, 363, 836, 320, 473, 258, + 262, 331, 894, 323, 733, 518, 212, 338, 325, 325, + 614, 540, 325, 362, 547, 611, 611, 315, 641, 324, + 328, 782, 329, 783, 373, 812, 912, 681, 6, 268, + 268, 268, 901, 686, 866, 891, 380, 379, 6, 781, + 792, 761, 843, 545, 546, 694, 410, 423, 860, 929, + 649, 833, 840, 735, 13, 816, 813, 317, 325, 325, + 325, 325, 643, 728, 673, 14, 213, 213, 213, 758, + 519, 213, 213, 213, 213, 213, 213, 13, 251, 836, + 386, 740, 732, 831, 947, 862, 832, 594, 14, 795, + 746, 458, 467, 468, 898, 619, 684, 638, 649, 753, + 365, 470, 957, 284, 628, 366, 368, 369, 561, 370, + 696, 400, 406, 701, 834, nil, nil, nil, nil, nil, + 483, 213, 213, nil, 498, nil, 299, nil, nil, 281, + 213, 482, 486, 493, 281, 13, 488, 13, nil, 15, + nil, nil, 13, 299, 15, 787, 14, nil, 14, 621, + 108, 480, 290, 14, 789, 419, 420, 421, 422, 267, + 704, nil, nil, 284, nil, nil, 948, 855, 284, 290, + nil, 15, 292, 292, nil, nil, 624, 401, nil, nil, + nil, 213, 269, nil, nil, nil, 387, 392, 624, 676, + 269, 411, 415, 15, 213, 213, nil, 903, 639, 685, + 466, 391, 108, 481, 337, 346, 346, 391, 469, 524, + 525, 743, 267, 267, 213, 479, 624, 717, nil, 541, + nil, 267, 722, 121, 624, 899, 745, nil, nil, 16, + 213, 567, 574, 786, 16, nil, 614, 124, nil, nil, + 126, nil, 611, nil, 15, nil, 835, nil, 838, nil, + nil, nil, 416, 15, 15, nil, nil, 268, nil, 588, + nil, 16, nil, 509, nil, 268, 649, 526, 410, nil, + 258, 757, nil, nil, 262, nil, 325, 325, nil, nil, + nil, nil, nil, 16, nil, nil, nil, nil, nil, 863, + nil, 864, 579, 213, 339, 596, 544, nil, 584, nil, + nil, nil, 606, nil, nil, nil, 609, 640, 498, nil, + nil, 823, 550, 743, nil, nil, nil, 498, nil, 617, + nil, nil, nil, nil, nil, 620, nil, 299, nil, nil, + nil, nil, nil, 410, 16, 13, 299, nil, 15, nil, + nil, nil, nil, 16, 16, 410, 14, nil, nil, nil, + nil, 601, 690, 290, 603, 213, nil, nil, nil, nil, + nil, 15, 290, nil, nil, 923, nil, nil, nil, nil, + nil, 213, nil, 410, 580, 13, nil, nil, 13, 410, + 585, nil, nil, nil, 267, 940, 14, 695, 934, 14, + nil, nil, 900, nil, nil, 213, 670, 670, 610, 401, + 13, 666, nil, 616, 668, 213, nil, 895, 213, nil, + 121, 14, nil, 915, nil, 688, 689, nil, 706, 15, + nil, 15, nil, 687, 124, 292, 15, 126, 16, nil, + nil, nil, 574, 580, 751, 414, 580, 642, 755, 498, + nil, nil, 292, 213, 213, nil, 267, nil, 213, 213, + 747, 16, 213, 633, nil, 13, nil, nil, 299, 574, + nil, nil, 13, 13, 401, nil, 14, nil, nil, 299, + 748, nil, nil, 14, 14, nil, 401, nil, 797, 756, + nil, 739, nil, nil, 290, nil, 267, nil, 741, 742, + 325, 13, nil, 790, nil, 290, 267, nil, 794, nil, + nil, 712, 14, nil, 401, nil, nil, nil, 391, 16, + nil, 16, 401, nil, 574, nil, 16, 752, nil, nil, + nil, nil, nil, 574, nil, nil, nil, 769, nil, 675, + nil, nil, nil, nil, 916, nil, 121, nil, nil, nil, + nil, 13, nil, nil, nil, nil, 13, 213, nil, nil, + nil, nil, 14, nil, nil, nil, 13, 14, nil, 791, + nil, 624, 788, 713, 715, 796, nil, 14, 718, 720, + nil, nil, 415, nil, nil, 730, 213, nil, nil, nil, + nil, nil, 798, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 299, 13, nil, nil, 580, 857, + nil, 585, nil, nil, nil, 13, 14, nil, nil, nil, + nil, nil, 847, nil, nil, nil, 14, nil, nil, 15, + 826, 819, nil, nil, nil, nil, 292, nil, nil, 325, + nil, 822, 859, nil, nil, 292, nil, 13, 13, nil, + 769, 13, nil, 845, nil, nil, 213, 13, 14, 14, + nil, nil, 14, nil, nil, nil, nil, 299, 14, 15, + 670, 849, 15, 851, 852, nil, nil, 854, nil, nil, + 880, nil, nil, nil, nil, nil, nil, nil, 13, nil, + 890, nil, nil, 870, 15, nil, 13, 13, nil, 14, + nil, nil, nil, 700, nil, nil, 800, 14, 14, nil, + nil, nil, nil, nil, 873, nil, nil, nil, nil, 16, + 933, nil, 878, 879, 769, nil, 769, nil, 410, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 325, nil, + nil, nil, nil, nil, 322, nil, nil, nil, nil, 15, + 213, 839, nil, nil, 841, nil, 15, 15, nil, 16, + 13, nil, 16, nil, 574, 410, 13, 292, 13, nil, + nil, 14, 927, 769, nil, nil, nil, 14, 292, 14, + nil, nil, nil, nil, 16, 15, 931, nil, nil, nil, + nil, nil, 932, nil, 865, nil, nil, 867, nil, nil, + nil, 25, nil, nil, nil, nil, 25, nil, 769, nil, + 769, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 25, nil, nil, nil, 414, 769, nil, nil, 25, + 25, 25, nil, 25, nil, 15, nil, nil, nil, 16, + 15, 267, nil, nil, nil, nil, 16, 16, nil, nil, + 15, nil, nil, nil, nil, 25, nil, nil, nil, 401, + nil, 25, 25, nil, nil, 25, nil, nil, 924, nil, + nil, 925, nil, 926, nil, 16, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 388, nil, 15, + nil, 935, nil, 418, 936, nil, 937, nil, nil, 15, + nil, nil, nil, 828, nil, nil, 25, nil, nil, nil, + nil, 25, 25, 25, 25, 25, 25, nil, nil, nil, + nil, nil, nil, nil, nil, 16, nil, nil, nil, 956, + 16, 15, 15, nil, nil, 15, nil, nil, nil, 958, + 16, 15, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 475, nil, + 477, nil, 478, nil, nil, nil, 346, nil, nil, nil, + nil, nil, 15, nil, nil, nil, nil, nil, nil, 16, + 15, 15, nil, nil, nil, nil, nil, nil, nil, 16, + nil, nil, nil, 829, nil, nil, nil, nil, nil, nil, + 25, 25, 25, 25, nil, nil, 25, 25, 25, 25, + 25, 25, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 16, 16, 25, nil, 16, nil, nil, nil, nil, + nil, 16, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 15, nil, nil, nil, nil, nil, + 15, nil, 15, nil, nil, nil, 25, 25, nil, nil, + nil, nil, 16, nil, nil, 25, nil, nil, nil, nil, + 16, 16, nil, nil, nil, nil, nil, 570, nil, nil, + nil, 25, nil, 25, nil, nil, nil, nil, 25, nil, + 37, nil, nil, nil, nil, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 25, nil, nil, nil, + 38, nil, 37, 288, 288, 38, nil, nil, nil, 25, + 25, nil, nil, nil, 16, nil, nil, nil, nil, nil, + 16, nil, 16, nil, 37, nil, nil, nil, nil, 25, + nil, nil, 38, 289, 289, 333, 349, 349, 349, 612, + nil, 322, nil, 615, nil, 25, nil, nil, nil, nil, + nil, nil, nil, nil, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 334, 350, 350, 350, nil, + nil, nil, nil, nil, 637, 37, nil, nil, 612, nil, + nil, 322, nil, nil, 37, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 418, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 38, nil, nil, 25, nil, + nil, nil, nil, nil, 38, 38, nil, nil, nil, nil, + nil, nil, nil, 763, 765, 766, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 707, nil, + nil, nil, 612, 322, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 25, nil, nil, nil, nil, nil, nil, nil, 37, + 25, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 744, nil, nil, nil, nil, nil, 25, nil, nil, nil, + nil, nil, 37, nil, nil, nil, nil, nil, nil, 38, + nil, 25, nil, nil, 25, nil, nil, 806, 808, 809, + 25, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 25, nil, 38, 25, nil, nil, 25, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 37, nil, 37, nil, nil, nil, 288, 37, 25, 25, + nil, nil, nil, 25, 25, nil, nil, 25, nil, nil, + nil, nil, nil, 288, nil, 799, nil, nil, nil, nil, + 38, 25, 38, nil, nil, nil, 289, 38, 25, 25, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 289, nil, nil, nil, nil, nil, nil, + nil, 882, 883, nil, nil, 885, 887, 25, 889, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 842, nil, nil, nil, 905, + 906, 908, 910, nil, 911, nil, nil, nil, nil, nil, + nil, nil, 853, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 25, nil, nil, nil, nil, 25, nil, 322, + nil, nil, 25, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 25, nil, nil, nil, nil, nil, nil, nil, + nil, 25, nil, nil, nil, nil, nil, nil, nil, nil, + 941, 943, 944, 945, nil, nil, nil, nil, nil, nil, + nil, 951, 953, 954, 955, nil, nil, nil, nil, nil, + nil, 25, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 25, nil, 959, nil, 960, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 37, nil, nil, nil, nil, nil, nil, 288, nil, nil, + nil, 25, nil, 25, 25, nil, 288, 25, nil, nil, + nil, nil, nil, 25, nil, nil, nil, nil, nil, nil, + 38, nil, nil, nil, nil, nil, nil, 289, nil, nil, + 37, nil, nil, 37, nil, nil, 289, nil, nil, nil, + nil, nil, nil, nil, 25, nil, nil, nil, nil, nil, + nil, nil, 25, 25, nil, 37, nil, nil, nil, nil, + 38, nil, nil, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 38, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 25, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 37, nil, nil, nil, nil, nil, 25, 37, 37, nil, + nil, nil, 25, nil, 25, nil, nil, nil, 288, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 288, + 38, nil, nil, nil, nil, nil, 37, 38, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 289, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 289, + nil, nil, nil, nil, nil, nil, 38, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 37, nil, nil, nil, + nil, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 38, nil, nil, nil, + nil, 38, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 38, nil, nil, nil, 220, nil, nil, nil, nil, + 37, nil, nil, 266, 266, 266, nil, nil, nil, nil, + 37, nil, nil, nil, 824, nil, 309, 310, 311, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 38, 266, 266, nil, nil, nil, nil, nil, nil, nil, + 38, nil, 37, 37, 825, nil, 37, nil, nil, nil, + nil, nil, 37, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 38, 38, nil, nil, 38, 349, nil, nil, + nil, nil, 38, 37, nil, nil, nil, nil, nil, nil, + nil, 37, 37, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 350, nil, nil, + nil, nil, nil, 38, nil, nil, nil, nil, nil, nil, + nil, 38, 38, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 37, nil, nil, nil, nil, + nil, 37, nil, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 266, 393, 266, nil, nil, + 412, 417, nil, nil, nil, 38, nil, nil, nil, nil, + nil, 38, nil, 38, nil, nil, 220, nil, nil, 432, + 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, + 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, + 453, 454, 455, 456, 457, nil, nil, nil, nil, nil, + 266, 266, nil, nil, nil, nil, nil, nil, nil, 266, + nil, nil, nil, nil, nil, nil, 266, nil, 266, nil, + 266, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 504, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 266, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 266, nil, 412, 595, 393, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 266, nil, 266, + nil, 266, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 266, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 630, 631, 632, nil, nil, nil, + nil, nil, 266, nil, nil, nil, 266, nil, nil, 266, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 266, 266, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 266, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 266, 709, nil, nil, + 266, 266, 714, 716, nil, nil, nil, 719, 721, nil, + nil, 595, 723, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 266, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 266, nil, 801, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 714, + 716, 721, 719, nil, 804, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 266, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 266, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 266, 801, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 266 ] + +racc_goto_check = [ + 54, 54, 53, 10, 46, 20, 62, 30, 14, 14, + 20, 8, 22, 23, 57, 57, 21, 58, 58, 85, + 68, 21, 17, 60, 60, 89, 6, 11, 115, 42, + 47, 43, 30, 91, 82, 82, 21, 20, 120, 35, + 35, 26, 37, 122, 21, 21, 21, 26, 21, 21, + 21, 83, 51, 84, 84, 60, 60, 60, 156, 20, + 54, 48, 69, 9, 69, 22, 127, 36, 36, 36, + 21, 2, 123, 7, 5, 118, 21, 21, 7, 111, + 21, 21, 21, 21, 38, 152, 89, 153, 35, 35, + 4, 16, 16, 38, 38, 16, 64, 64, 156, 109, + 64, 1, 118, 151, 65, 65, 65, 142, 67, 12, + 20, 67, 142, 52, 52, 146, 15, 146, 146, 20, + 20, 21, 41, 41, 41, 18, 21, 21, 21, 21, + 21, 21, 65, 65, 29, 32, 32, 32, 39, 59, + 61, 16, 16, 16, 16, 77, 151, 78, 68, 66, + 66, 4, 112, 79, 118, 81, 19, 86, 28, 28, + 156, 88, 28, 92, 93, 69, 69, 94, 95, 96, + 97, 98, 99, 100, 5, 120, 122, 101, 7, 63, + 63, 63, 102, 103, 153, 109, 2, 7, 7, 11, + 104, 127, 111, 105, 106, 107, 54, 44, 108, 112, + 118, 120, 152, 113, 20, 123, 121, 63, 28, 28, + 28, 28, 124, 23, 85, 21, 21, 21, 21, 125, + 126, 21, 21, 21, 21, 21, 21, 20, 128, 151, + 9, 38, 116, 129, 112, 115, 130, 22, 21, 127, + 23, 131, 133, 134, 135, 48, 51, 136, 118, 137, + 140, 44, 112, 9, 48, 141, 143, 144, 145, 147, + 148, 35, 35, 149, 150, nil, nil, nil, nil, nil, + 44, 21, 21, nil, 46, nil, 60, nil, nil, 42, + 21, 43, 47, 30, 42, 20, 43, 20, nil, 24, + nil, nil, 20, 60, 24, 23, 21, nil, 21, 22, + 89, 6, 21, 21, 23, 28, 28, 28, 28, 32, + 146, nil, nil, 9, nil, nil, 83, 84, 9, 21, + nil, 24, 24, 24, nil, nil, 35, 66, nil, nil, + nil, 21, 65, nil, nil, nil, 19, 19, 35, 22, + 65, 19, 19, 24, 21, 21, nil, 91, 26, 22, + 41, 63, 89, 7, 24, 24, 24, 63, 41, 16, + 16, 68, 32, 32, 21, 4, 35, 37, nil, 89, + nil, 32, 37, 54, 35, 11, 48, nil, nil, 25, + 21, 14, 30, 82, 25, nil, 156, 57, nil, nil, + 58, nil, 69, nil, 24, nil, 116, nil, 116, nil, + nil, nil, 17, 24, 24, nil, nil, 63, nil, 44, + nil, 25, nil, 28, nil, 63, 118, 4, 54, nil, + 66, 64, nil, nil, 66, nil, 28, 28, nil, nil, + nil, nil, nil, 25, nil, nil, nil, nil, nil, 116, + nil, 116, 36, 21, 25, 30, 28, nil, 36, nil, + nil, nil, 44, nil, nil, nil, 44, 62, 46, nil, + nil, 82, 28, 68, nil, nil, nil, 46, nil, 44, + nil, nil, nil, nil, nil, 44, nil, 60, nil, nil, + nil, nil, nil, 54, 25, 20, 60, nil, 24, nil, + nil, nil, nil, 25, 25, 54, 21, nil, nil, nil, + nil, 36, 8, 21, 36, 21, nil, nil, nil, nil, + nil, 24, 21, nil, nil, 116, nil, nil, nil, nil, + nil, 21, nil, 54, 66, 20, nil, nil, 20, 54, + 66, nil, nil, nil, 32, 23, 21, 44, 116, 21, + nil, nil, 85, nil, nil, 21, 89, 89, 65, 66, + 20, 9, nil, 7, 9, 21, nil, 82, 21, nil, + 54, 21, nil, 10, nil, 89, 89, nil, 14, 24, + nil, 24, nil, 16, 57, 24, 24, 58, 25, nil, + nil, nil, 30, 66, 62, 25, 66, 65, 62, 46, + nil, nil, 24, 21, 21, nil, 32, nil, 21, 21, + 46, 25, 21, 28, nil, 20, nil, nil, 60, 30, + nil, nil, 20, 20, 66, nil, 21, nil, nil, 60, + 44, nil, nil, 21, 21, nil, 66, nil, 53, 30, + nil, 9, nil, nil, 21, nil, 32, nil, 9, 9, + 28, 20, nil, 8, nil, 21, 32, nil, 8, nil, + nil, 65, 21, nil, 66, nil, nil, nil, 63, 25, + nil, 25, 66, nil, 30, nil, 25, 9, nil, nil, + nil, nil, nil, 30, nil, nil, nil, 110, nil, 63, + nil, nil, nil, nil, 22, nil, 54, nil, nil, nil, + nil, 20, nil, nil, nil, nil, 20, 21, nil, nil, + nil, nil, 21, nil, nil, nil, 20, 21, nil, 89, + nil, 35, 16, 19, 19, 89, nil, 21, 19, 19, + nil, nil, 19, nil, nil, 114, 21, nil, nil, nil, + nil, nil, 9, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 60, 20, nil, nil, 66, 8, + nil, 66, nil, nil, nil, 20, 21, nil, nil, nil, + nil, nil, 44, nil, nil, nil, 21, nil, nil, 24, + 21, 9, nil, nil, nil, nil, 24, nil, nil, 28, + nil, 9, 44, nil, nil, 24, nil, 20, 20, nil, + 110, 20, nil, 110, nil, nil, 21, 20, 21, 21, + nil, nil, 21, nil, nil, nil, nil, 60, 21, 24, + 89, 16, 24, 9, 9, nil, nil, 9, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, 20, nil, + 44, nil, nil, 21, 24, nil, 20, 20, nil, 21, + nil, nil, nil, 24, nil, nil, 19, 21, 21, nil, + nil, nil, nil, nil, 9, nil, nil, nil, nil, 25, + 8, nil, 9, 9, 110, nil, 110, nil, 54, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 28, nil, + nil, nil, nil, nil, 27, nil, nil, nil, nil, 24, + 21, 114, nil, nil, 114, nil, 24, 24, nil, 25, + 20, nil, 25, nil, 30, 54, 20, 24, 20, nil, + nil, 21, 110, 110, nil, nil, nil, 21, 24, 21, + nil, nil, nil, nil, 25, 24, 9, nil, nil, nil, + nil, nil, 9, nil, 114, nil, nil, 114, nil, nil, + nil, 40, nil, nil, nil, nil, 40, nil, 110, nil, + 110, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 40, nil, nil, nil, 25, 110, nil, nil, 40, + 40, 40, nil, 40, nil, 24, nil, nil, nil, 25, + 24, 32, nil, nil, nil, nil, 25, 25, nil, nil, + 24, nil, nil, nil, nil, 40, nil, nil, nil, 66, + nil, 40, 40, nil, nil, 40, nil, nil, 114, nil, + nil, 114, nil, 114, nil, 25, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 27, nil, 24, + nil, 114, nil, 27, 114, nil, 114, nil, nil, 24, + nil, nil, nil, 24, nil, nil, 40, nil, nil, nil, + nil, 40, 40, 40, 40, 40, 40, nil, nil, nil, + nil, nil, nil, nil, nil, 25, nil, nil, nil, 114, + 25, 24, 24, nil, nil, 24, nil, nil, nil, 114, + 25, 24, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 27, nil, + 27, nil, 27, nil, nil, nil, 24, nil, nil, nil, + nil, nil, 24, nil, nil, nil, nil, nil, nil, 25, + 24, 24, nil, nil, nil, nil, nil, nil, nil, 25, + nil, nil, nil, 25, nil, nil, nil, nil, nil, nil, + 40, 40, 40, 40, nil, nil, 40, 40, 40, 40, + 40, 40, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 25, 25, 40, nil, 25, nil, nil, nil, nil, + nil, 25, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 24, nil, nil, nil, nil, nil, + 24, nil, 24, nil, nil, nil, 40, 40, nil, nil, + nil, nil, 25, nil, nil, 40, nil, nil, nil, nil, + 25, 25, nil, nil, nil, nil, nil, 27, nil, nil, + nil, 40, nil, 40, nil, nil, nil, nil, 40, nil, + 49, nil, nil, nil, nil, 49, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 40, nil, nil, nil, + 50, nil, 49, 49, 49, 50, nil, nil, nil, 40, + 40, nil, nil, nil, 25, nil, nil, nil, nil, nil, + 25, nil, 25, nil, 49, nil, nil, nil, nil, 40, + nil, nil, 50, 50, 50, 49, 49, 49, 49, 27, + nil, 27, nil, 27, nil, 40, nil, nil, nil, nil, + nil, nil, nil, nil, 50, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 50, 50, 50, 50, nil, + nil, nil, nil, nil, 27, 49, nil, nil, 27, nil, + nil, 27, nil, nil, 49, 49, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 27, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 50, nil, nil, 40, nil, + nil, nil, nil, nil, 50, 50, nil, nil, nil, nil, + nil, nil, nil, 117, 117, 117, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 27, nil, + nil, nil, 27, 27, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 49, + 40, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 27, nil, nil, nil, nil, nil, 40, nil, nil, nil, + nil, nil, 49, nil, nil, nil, nil, nil, nil, 50, + nil, 40, nil, nil, 40, nil, nil, 117, 117, 117, + 40, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 40, nil, 50, 40, nil, nil, 40, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 49, nil, 49, nil, nil, nil, 49, 49, 40, 40, + nil, nil, nil, 40, 40, nil, nil, 40, nil, nil, + nil, nil, nil, 49, nil, 27, nil, nil, nil, nil, + 50, 40, 50, nil, nil, nil, 50, 50, 40, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 50, nil, nil, nil, nil, nil, nil, + nil, 117, 117, nil, nil, 117, 117, 40, 117, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 27, nil, nil, nil, 117, + 117, 117, 117, nil, 117, nil, nil, nil, nil, nil, + nil, nil, 27, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 40, nil, nil, nil, nil, 40, nil, 27, + nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, nil, + 117, 117, 117, 117, nil, nil, nil, nil, nil, nil, + nil, 117, 117, 117, 117, nil, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 40, nil, 117, nil, 117, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 49, nil, nil, nil, nil, nil, nil, 49, nil, nil, + nil, 40, nil, 40, 40, nil, 49, 40, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + 50, nil, nil, nil, nil, nil, nil, 50, nil, nil, + 49, nil, nil, 49, nil, nil, 50, nil, nil, nil, + nil, nil, nil, nil, 40, nil, nil, nil, nil, nil, + nil, nil, 40, 40, nil, 49, nil, nil, nil, nil, + 50, nil, nil, 50, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 50, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 49, nil, nil, nil, nil, nil, 40, 49, 49, nil, + nil, nil, 40, nil, 40, nil, nil, nil, 49, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 49, + 50, nil, nil, nil, nil, nil, 49, 50, 50, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 50, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 50, + nil, nil, nil, nil, nil, nil, 50, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 49, nil, nil, nil, + nil, 49, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 49, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 50, nil, nil, nil, + nil, 50, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 50, nil, nil, nil, 31, nil, nil, nil, nil, + 49, nil, nil, 31, 31, 31, nil, nil, nil, nil, + 49, nil, nil, nil, 49, nil, 31, 31, 31, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 50, 31, 31, nil, nil, nil, nil, nil, nil, nil, + 50, nil, 49, 49, 50, nil, 49, nil, nil, nil, + nil, nil, 49, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 50, 50, nil, nil, 50, 49, nil, nil, + nil, nil, 50, 49, nil, nil, nil, nil, nil, nil, + nil, 49, 49, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 50, nil, nil, + nil, nil, nil, 50, nil, nil, nil, nil, nil, nil, + nil, 50, 50, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 49, nil, nil, nil, nil, + nil, 49, nil, 49, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 31, 31, 31, nil, nil, + 31, 31, nil, nil, nil, 50, nil, nil, nil, nil, + nil, 50, nil, 50, nil, nil, 31, nil, nil, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, nil, nil, nil, nil, nil, + 31, 31, nil, nil, nil, nil, nil, nil, nil, 31, + nil, nil, nil, nil, nil, nil, 31, nil, 31, nil, + 31, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 31, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 31, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 31, nil, 31, 31, 31, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 31, nil, 31, + nil, 31, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 31, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 31, 31, 31, nil, nil, nil, + nil, nil, 31, nil, nil, nil, 31, nil, nil, 31, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 31, 31, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 31, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 31, 31, nil, nil, + 31, 31, 31, 31, nil, nil, nil, 31, 31, nil, + nil, 31, 31, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 31, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 31, nil, 31, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 31, + 31, 31, 31, nil, 31, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 31, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 31, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 31, 31, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 31 ] + +racc_goto_pointer = [ + nil, 101, 71, nil, 87, 69, 23, 73, -43, 31, + -310, -479, -525, nil, 0, 107, 31, -184, 60, 136, + 5, 16, -190, -381, 289, 379, -159, 827, 98, 18, + -12, 1945, 107, nil, nil, -164, 42, -212, -374, -325, + 941, 94, -3, -1, -13, nil, -29, -4, -242, 1230, + 1260, -291, 47, -66, -8, nil, nil, 6, 9, -246, + -10, 84, -50, 151, -221, 76, 124, -351, -249, -410, + nil, nil, nil, nil, nil, nil, nil, 77, 90, 95, + nil, -169, -292, -615, -471, -312, 92, nil, -186, 22, + nil, -513, 95, -198, 112, -341, 110, 108, -498, 109, + -499, -356, -673, -357, -499, -158, -167, -352, -599, -745, + 20, -578, -694, -395, 127, -570, -366, 737, -444, nil, + -560, -530, -693, -664, -307, -424, -104, -453, 206, -526, + -524, -9, nil, -17, -17, -610, -260, -389, nil, nil, + 174, 177, 26, 174, 174, -111, -251, 175, -294, -292, + -498, -659, -679, -720, nil, nil, -416 ] + +racc_goto_default = [ + nil, nil, nil, 3, nil, 4, 332, 279, nil, 313, + nil, 779, nil, 278, nil, nil, nil, 11, 12, 18, + 219, 308, nil, nil, 217, 218, nil, 272, 17, nil, + 424, 21, 22, 23, 24, 627, nil, nil, nil, nil, + 296, 395, 31, nil, nil, 33, 36, 35, nil, 214, + 215, 344, nil, 123, 403, 122, 125, 74, 75, nil, + 45, nil, 635, 396, nil, 397, 408, 581, 471, 270, + 256, 46, 47, 48, 49, 50, 51, 52, nil, 257, + 58, nil, nil, nil, nil, nil, nil, 66, nil, 521, + 67, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 771, + 656, nil, 772, nil, 646, nil, 648, nil, 837, 597, + nil, nil, nil, 654, nil, nil, nil, 693, nil, nil, + nil, nil, 407, nil, nil, nil, nil, nil, 73, 76, + 77, nil, nil, nil, nil, nil, 557, nil, nil, nil, + 647, 658, 659, 738, 662, 665, 274 ] + +racc_reduce_table = [ + 0, 0, :racc_error, + 1, 138, :_reduce_none, + 2, 139, :_reduce_2, + 0, 140, :_reduce_3, + 1, 140, :_reduce_4, + 3, 140, :_reduce_5, + 2, 140, :_reduce_6, + 1, 142, :_reduce_none, + 4, 142, :_reduce_8, + 4, 145, :_reduce_9, + 2, 146, :_reduce_10, + 0, 150, :_reduce_11, + 1, 150, :_reduce_12, + 3, 150, :_reduce_13, + 2, 150, :_reduce_14, + 0, 166, :_reduce_15, + 4, 144, :_reduce_16, + 3, 144, :_reduce_17, + 3, 144, :_reduce_18, + 3, 144, :_reduce_19, + 2, 144, :_reduce_20, + 3, 144, :_reduce_21, + 3, 144, :_reduce_22, + 3, 144, :_reduce_23, + 3, 144, :_reduce_24, + 3, 144, :_reduce_25, + 4, 144, :_reduce_26, + 1, 144, :_reduce_none, + 3, 144, :_reduce_28, + 3, 144, :_reduce_29, + 6, 144, :_reduce_30, + 5, 144, :_reduce_31, + 5, 144, :_reduce_32, + 5, 144, :_reduce_33, + 5, 144, :_reduce_34, + 3, 144, :_reduce_35, + 3, 144, :_reduce_36, + 3, 144, :_reduce_37, + 3, 144, :_reduce_38, + 1, 144, :_reduce_none, + 3, 154, :_reduce_40, + 3, 154, :_reduce_41, + 1, 165, :_reduce_none, + 3, 165, :_reduce_43, + 3, 165, :_reduce_44, + 3, 165, :_reduce_45, + 2, 165, :_reduce_46, + 1, 165, :_reduce_none, + 1, 153, :_reduce_none, + 1, 156, :_reduce_none, + 1, 156, :_reduce_none, + 1, 170, :_reduce_none, + 4, 170, :_reduce_52, + 4, 170, :_reduce_53, + 0, 176, :_reduce_54, + 5, 174, :_reduce_55, + 2, 169, :_reduce_56, + 3, 169, :_reduce_57, + 4, 169, :_reduce_58, + 5, 169, :_reduce_59, + 4, 169, :_reduce_60, + 5, 169, :_reduce_61, + 2, 169, :_reduce_62, + 2, 169, :_reduce_63, + 2, 169, :_reduce_64, + 2, 169, :_reduce_65, + 2, 169, :_reduce_66, + 1, 155, :_reduce_67, + 3, 155, :_reduce_68, + 1, 180, :_reduce_69, + 3, 180, :_reduce_70, + 1, 179, :_reduce_none, + 2, 179, :_reduce_72, + 3, 179, :_reduce_73, + 5, 179, :_reduce_74, + 2, 179, :_reduce_75, + 4, 179, :_reduce_76, + 2, 179, :_reduce_77, + 4, 179, :_reduce_78, + 1, 179, :_reduce_79, + 3, 179, :_reduce_80, + 1, 183, :_reduce_none, + 3, 183, :_reduce_82, + 2, 182, :_reduce_83, + 3, 182, :_reduce_84, + 1, 185, :_reduce_85, + 3, 185, :_reduce_86, + 1, 184, :_reduce_87, + 1, 184, :_reduce_88, + 4, 184, :_reduce_89, + 3, 184, :_reduce_90, + 3, 184, :_reduce_91, + 3, 184, :_reduce_92, + 3, 184, :_reduce_93, + 2, 184, :_reduce_94, + 1, 184, :_reduce_95, + 1, 162, :_reduce_96, + 1, 162, :_reduce_97, + 4, 162, :_reduce_98, + 3, 162, :_reduce_99, + 3, 162, :_reduce_100, + 3, 162, :_reduce_101, + 3, 162, :_reduce_102, + 2, 162, :_reduce_103, + 1, 162, :_reduce_104, + 1, 188, :_reduce_105, + 1, 188, :_reduce_none, + 2, 189, :_reduce_107, + 1, 189, :_reduce_108, + 3, 189, :_reduce_109, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 193, :_reduce_115, + 1, 193, :_reduce_none, + 1, 151, :_reduce_none, + 1, 151, :_reduce_none, + 1, 152, :_reduce_119, + 0, 196, :_reduce_120, + 4, 152, :_reduce_121, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 3, 168, :_reduce_192, + 5, 168, :_reduce_193, + 3, 168, :_reduce_194, + 5, 168, :_reduce_195, + 6, 168, :_reduce_196, + 5, 168, :_reduce_197, + 5, 168, :_reduce_198, + 5, 168, :_reduce_199, + 5, 168, :_reduce_200, + 4, 168, :_reduce_201, + 3, 168, :_reduce_202, + 3, 168, :_reduce_203, + 3, 168, :_reduce_204, + 3, 168, :_reduce_205, + 3, 168, :_reduce_206, + 3, 168, :_reduce_207, + 3, 168, :_reduce_208, + 3, 168, :_reduce_209, + 3, 168, :_reduce_210, + 4, 168, :_reduce_211, + 4, 168, :_reduce_212, + 2, 168, :_reduce_213, + 2, 168, :_reduce_214, + 3, 168, :_reduce_215, + 3, 168, :_reduce_216, + 3, 168, :_reduce_217, + 3, 168, :_reduce_218, + 3, 168, :_reduce_219, + 3, 168, :_reduce_220, + 3, 168, :_reduce_221, + 3, 168, :_reduce_222, + 3, 168, :_reduce_223, + 3, 168, :_reduce_224, + 3, 168, :_reduce_225, + 3, 168, :_reduce_226, + 3, 168, :_reduce_227, + 2, 168, :_reduce_228, + 2, 168, :_reduce_229, + 3, 168, :_reduce_230, + 3, 168, :_reduce_231, + 3, 168, :_reduce_232, + 3, 168, :_reduce_233, + 3, 168, :_reduce_234, + 6, 168, :_reduce_235, + 1, 168, :_reduce_none, + 1, 164, :_reduce_none, + 1, 198, :_reduce_none, + 2, 198, :_reduce_none, + 4, 198, :_reduce_240, + 2, 198, :_reduce_241, + 3, 203, :_reduce_242, + 0, 204, :_reduce_243, + 1, 204, :_reduce_none, + 0, 159, :_reduce_245, + 1, 159, :_reduce_none, + 2, 159, :_reduce_none, + 4, 159, :_reduce_248, + 2, 159, :_reduce_249, + 1, 178, :_reduce_250, + 2, 178, :_reduce_251, + 2, 178, :_reduce_252, + 4, 178, :_reduce_253, + 1, 178, :_reduce_254, + 0, 207, :_reduce_255, + 2, 173, :_reduce_256, + 2, 206, :_reduce_257, + 2, 205, :_reduce_258, + 0, 205, :_reduce_259, + 1, 200, :_reduce_260, + 2, 200, :_reduce_261, + 3, 200, :_reduce_262, + 4, 200, :_reduce_263, + 3, 163, :_reduce_264, + 4, 163, :_reduce_265, + 2, 163, :_reduce_266, + 1, 197, :_reduce_none, + 1, 197, :_reduce_none, + 1, 197, :_reduce_none, + 1, 197, :_reduce_none, + 1, 197, :_reduce_none, + 1, 197, :_reduce_none, + 1, 197, :_reduce_none, + 1, 197, :_reduce_none, + 1, 197, :_reduce_275, + 3, 197, :_reduce_276, + 0, 231, :_reduce_277, + 0, 232, :_reduce_278, + 6, 197, :_reduce_279, + 3, 197, :_reduce_280, + 3, 197, :_reduce_281, + 2, 197, :_reduce_282, + 3, 197, :_reduce_283, + 3, 197, :_reduce_284, + 1, 197, :_reduce_285, + 4, 197, :_reduce_286, + 3, 197, :_reduce_287, + 1, 197, :_reduce_288, + 5, 197, :_reduce_289, + 4, 197, :_reduce_290, + 3, 197, :_reduce_291, + 2, 197, :_reduce_292, + 1, 197, :_reduce_none, + 2, 197, :_reduce_294, + 0, 233, :_reduce_295, + 3, 197, :_reduce_296, + 6, 197, :_reduce_297, + 6, 197, :_reduce_298, + 0, 234, :_reduce_299, + 0, 235, :_reduce_300, + 7, 197, :_reduce_301, + 0, 236, :_reduce_302, + 0, 237, :_reduce_303, + 7, 197, :_reduce_304, + 5, 197, :_reduce_305, + 4, 197, :_reduce_306, + 0, 238, :_reduce_307, + 0, 239, :_reduce_308, + 9, 197, :_reduce_309, + 0, 240, :_reduce_310, + 6, 197, :_reduce_311, + 0, 241, :_reduce_312, + 7, 197, :_reduce_313, + 0, 242, :_reduce_314, + 5, 197, :_reduce_315, + 0, 243, :_reduce_316, + 6, 197, :_reduce_317, + 0, 244, :_reduce_318, + 0, 245, :_reduce_319, + 9, 197, :_reduce_320, + 1, 197, :_reduce_321, + 1, 197, :_reduce_322, + 1, 197, :_reduce_323, + 1, 197, :_reduce_324, + 1, 158, :_reduce_none, + 1, 224, :_reduce_326, + 1, 227, :_reduce_327, + 1, 219, :_reduce_none, + 1, 219, :_reduce_none, + 2, 219, :_reduce_330, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 220, :_reduce_none, + 5, 220, :_reduce_334, + 1, 148, :_reduce_none, + 2, 148, :_reduce_336, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 246, :_reduce_339, + 3, 246, :_reduce_340, + 1, 249, :_reduce_341, + 3, 249, :_reduce_342, + 1, 248, :_reduce_none, + 4, 248, :_reduce_344, + 6, 248, :_reduce_345, + 3, 248, :_reduce_346, + 5, 248, :_reduce_347, + 2, 248, :_reduce_348, + 4, 248, :_reduce_349, + 1, 248, :_reduce_350, + 3, 248, :_reduce_351, + 6, 250, :_reduce_352, + 8, 250, :_reduce_353, + 4, 250, :_reduce_354, + 6, 250, :_reduce_355, + 4, 250, :_reduce_356, + 2, 250, :_reduce_none, + 6, 250, :_reduce_358, + 2, 250, :_reduce_359, + 4, 250, :_reduce_360, + 6, 250, :_reduce_361, + 2, 250, :_reduce_362, + 4, 250, :_reduce_363, + 2, 250, :_reduce_364, + 4, 250, :_reduce_365, + 1, 250, :_reduce_366, + 0, 175, :_reduce_367, + 1, 175, :_reduce_368, + 3, 256, :_reduce_369, + 1, 256, :_reduce_370, + 4, 256, :_reduce_371, + 0, 257, :_reduce_372, + 2, 257, :_reduce_373, + 1, 258, :_reduce_374, + 3, 258, :_reduce_375, + 1, 259, :_reduce_376, + 1, 259, :_reduce_none, + 0, 263, :_reduce_378, + 3, 218, :_reduce_379, + 4, 261, :_reduce_380, + 1, 261, :_reduce_381, + 0, 266, :_reduce_382, + 4, 262, :_reduce_383, + 0, 267, :_reduce_384, + 4, 262, :_reduce_385, + 0, 268, :_reduce_386, + 5, 265, :_reduce_387, + 2, 171, :_reduce_388, + 4, 171, :_reduce_389, + 4, 171, :_reduce_390, + 2, 217, :_reduce_391, + 4, 217, :_reduce_392, + 4, 217, :_reduce_393, + 3, 217, :_reduce_394, + 3, 217, :_reduce_395, + 3, 217, :_reduce_396, + 2, 217, :_reduce_397, + 1, 217, :_reduce_398, + 4, 217, :_reduce_399, + 0, 270, :_reduce_400, + 5, 216, :_reduce_401, + 0, 271, :_reduce_402, + 5, 216, :_reduce_403, + 5, 222, :_reduce_404, + 1, 272, :_reduce_405, + 1, 272, :_reduce_none, + 6, 147, :_reduce_407, + 0, 147, :_reduce_408, + 1, 273, :_reduce_409, + 1, 273, :_reduce_none, + 1, 273, :_reduce_none, + 2, 274, :_reduce_412, + 1, 274, :_reduce_none, + 2, 149, :_reduce_414, + 1, 149, :_reduce_none, + 1, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 209, :_reduce_419, + 1, 276, :_reduce_420, + 2, 276, :_reduce_421, + 3, 277, :_reduce_422, + 1, 277, :_reduce_423, + 1, 277, :_reduce_424, + 3, 210, :_reduce_425, + 4, 211, :_reduce_426, + 3, 212, :_reduce_427, + 0, 281, :_reduce_428, + 3, 281, :_reduce_429, + 1, 282, :_reduce_430, + 2, 282, :_reduce_431, + 3, 213, :_reduce_432, + 0, 284, :_reduce_433, + 3, 284, :_reduce_434, + 0, 278, :_reduce_435, + 2, 278, :_reduce_436, + 0, 279, :_reduce_437, + 2, 279, :_reduce_438, + 0, 280, :_reduce_439, + 2, 280, :_reduce_440, + 1, 283, :_reduce_441, + 2, 283, :_reduce_442, + 0, 286, :_reduce_443, + 4, 283, :_reduce_444, + 1, 285, :_reduce_445, + 1, 285, :_reduce_446, + 1, 285, :_reduce_447, + 1, 285, :_reduce_none, + 1, 194, :_reduce_449, + 3, 195, :_reduce_450, + 1, 275, :_reduce_451, + 1, 275, :_reduce_452, + 2, 275, :_reduce_453, + 2, 275, :_reduce_454, + 1, 186, :_reduce_455, + 1, 186, :_reduce_456, + 1, 186, :_reduce_457, + 1, 186, :_reduce_458, + 1, 186, :_reduce_459, + 1, 187, :_reduce_460, + 1, 187, :_reduce_461, + 1, 187, :_reduce_462, + 1, 187, :_reduce_463, + 1, 187, :_reduce_464, + 1, 187, :_reduce_465, + 1, 187, :_reduce_466, + 1, 214, :_reduce_467, + 1, 214, :_reduce_468, + 1, 157, :_reduce_469, + 1, 157, :_reduce_470, + 1, 161, :_reduce_471, + 1, 161, :_reduce_472, + 1, 225, :_reduce_473, + 3, 225, :_reduce_474, + 2, 225, :_reduce_475, + 3, 228, :_reduce_476, + 2, 228, :_reduce_477, + 6, 264, :_reduce_478, + 8, 264, :_reduce_479, + 4, 264, :_reduce_480, + 6, 264, :_reduce_481, + 4, 264, :_reduce_482, + 6, 264, :_reduce_483, + 2, 264, :_reduce_484, + 4, 264, :_reduce_485, + 6, 264, :_reduce_486, + 2, 264, :_reduce_487, + 4, 264, :_reduce_488, + 2, 264, :_reduce_489, + 4, 264, :_reduce_490, + 1, 264, :_reduce_491, + 0, 264, :_reduce_492, + 1, 260, :_reduce_493, + 1, 260, :_reduce_494, + 1, 260, :_reduce_495, + 1, 260, :_reduce_496, + 1, 247, :_reduce_none, + 1, 247, :_reduce_none, + 1, 288, :_reduce_499, + 3, 288, :_reduce_500, + 1, 251, :_reduce_501, + 3, 251, :_reduce_502, + 3, 289, :_reduce_503, + 3, 290, :_reduce_504, + 1, 252, :_reduce_505, + 3, 252, :_reduce_506, + 1, 287, :_reduce_507, + 3, 287, :_reduce_508, + 1, 291, :_reduce_none, + 1, 291, :_reduce_none, + 2, 253, :_reduce_511, + 1, 253, :_reduce_512, + 1, 292, :_reduce_none, + 1, 292, :_reduce_none, + 2, 255, :_reduce_515, + 2, 254, :_reduce_516, + 0, 254, :_reduce_517, + 1, 229, :_reduce_none, + 3, 229, :_reduce_519, + 0, 215, :_reduce_520, + 2, 215, :_reduce_none, + 1, 202, :_reduce_522, + 3, 202, :_reduce_523, + 3, 293, :_reduce_524, + 2, 293, :_reduce_525, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 1, 172, :_reduce_none, + 1, 172, :_reduce_none, + 1, 172, :_reduce_none, + 1, 172, :_reduce_none, + 1, 269, :_reduce_none, + 1, 269, :_reduce_none, + 1, 269, :_reduce_none, + 1, 230, :_reduce_none, + 1, 230, :_reduce_none, + 0, 141, :_reduce_none, + 1, 141, :_reduce_none, + 0, 167, :_reduce_none, + 1, 167, :_reduce_none, + 2, 181, :_reduce_542, + 2, 160, :_reduce_543, + 0, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 226, :_reduce_547, + 1, 226, :_reduce_none, + 1, 143, :_reduce_none, + 2, 143, :_reduce_none, + 0, 199, :_reduce_551 ] + +racc_reduce_n = 552 + +racc_shift_n = 961 + +racc_token_table = { + false => 0, + :error => 1, + :kCLASS => 2, + :kMODULE => 3, + :kDEF => 4, + :kUNDEF => 5, + :kBEGIN => 6, + :kRESCUE => 7, + :kENSURE => 8, + :kEND => 9, + :kIF => 10, + :kUNLESS => 11, + :kTHEN => 12, + :kELSIF => 13, + :kELSE => 14, + :kCASE => 15, + :kWHEN => 16, + :kWHILE => 17, + :kUNTIL => 18, + :kFOR => 19, + :kBREAK => 20, + :kNEXT => 21, + :kREDO => 22, + :kRETRY => 23, + :kIN => 24, + :kDO => 25, + :kDO_COND => 26, + :kDO_BLOCK => 27, + :kDO_LAMBDA => 28, + :kRETURN => 29, + :kYIELD => 30, + :kSUPER => 31, + :kSELF => 32, + :kNIL => 33, + :kTRUE => 34, + :kFALSE => 35, + :kAND => 36, + :kOR => 37, + :kNOT => 38, + :kIF_MOD => 39, + :kUNLESS_MOD => 40, + :kWHILE_MOD => 41, + :kUNTIL_MOD => 42, + :kRESCUE_MOD => 43, + :kALIAS => 44, + :kDEFINED => 45, + :klBEGIN => 46, + :klEND => 47, + :k__LINE__ => 48, + :k__FILE__ => 49, + :k__ENCODING__ => 50, + :tIDENTIFIER => 51, + :tFID => 52, + :tGVAR => 53, + :tIVAR => 54, + :tCONSTANT => 55, + :tLABEL => 56, + :tCVAR => 57, + :tNTH_REF => 58, + :tBACK_REF => 59, + :tSTRING_CONTENT => 60, + :tINTEGER => 61, + :tFLOAT => 62, + :tUPLUS => 63, + :tUMINUS => 64, + :tUNARY_NUM => 65, + :tPOW => 66, + :tCMP => 67, + :tEQ => 68, + :tEQQ => 69, + :tNEQ => 70, + :tGEQ => 71, + :tLEQ => 72, + :tANDOP => 73, + :tOROP => 74, + :tMATCH => 75, + :tNMATCH => 76, + :tDOT => 77, + :tDOT2 => 78, + :tDOT3 => 79, + :tAREF => 80, + :tASET => 81, + :tLSHFT => 82, + :tRSHFT => 83, + :tCOLON2 => 84, + :tCOLON3 => 85, + :tOP_ASGN => 86, + :tASSOC => 87, + :tLPAREN => 88, + :tLPAREN2 => 89, + :tRPAREN => 90, + :tLPAREN_ARG => 91, + :tLBRACK => 92, + :tLBRACK2 => 93, + :tRBRACK => 94, + :tLBRACE => 95, + :tLBRACE_ARG => 96, + :tSTAR => 97, + :tSTAR2 => 98, + :tAMPER => 99, + :tAMPER2 => 100, + :tTILDE => 101, + :tPERCENT => 102, + :tDIVIDE => 103, + :tPLUS => 104, + :tMINUS => 105, + :tLT => 106, + :tGT => 107, + :tPIPE => 108, + :tBANG => 109, + :tCARET => 110, + :tLCURLY => 111, + :tRCURLY => 112, + :tBACK_REF2 => 113, + :tSYMBEG => 114, + :tSTRING_BEG => 115, + :tXSTRING_BEG => 116, + :tREGEXP_BEG => 117, + :tREGEXP_OPT => 118, + :tWORDS_BEG => 119, + :tQWORDS_BEG => 120, + :tSTRING_DBEG => 121, + :tSTRING_DVAR => 122, + :tSTRING_END => 123, + :tSTRING => 124, + :tSYMBOL => 125, + :tNL => 126, + :tEH => 127, + :tCOLON => 128, + :tCOMMA => 129, + :tSPACE => 130, + :tSEMI => 131, + :tLAMBDA => 132, + :tLAMBEG => 133, + :tCHARACTER => 134, + :tEQL => 135, + :tLOWEST => 136 } + +racc_nt_base = 137 + +racc_use_result_var = true + +Racc_arg = [ + racc_action_table, + racc_action_check, + racc_action_default, + racc_action_pointer, + racc_goto_table, + racc_goto_check, + racc_goto_default, + racc_goto_pointer, + racc_nt_base, + racc_reduce_table, + racc_token_table, + racc_shift_n, + racc_reduce_n, + racc_use_result_var ] +Ractor.make_shareable(Racc_arg) if defined?(Ractor) + +Racc_token_to_s_table = [ + "$end", + "error", + "kCLASS", + "kMODULE", + "kDEF", + "kUNDEF", + "kBEGIN", + "kRESCUE", + "kENSURE", + "kEND", + "kIF", + "kUNLESS", + "kTHEN", + "kELSIF", + "kELSE", + "kCASE", + "kWHEN", + "kWHILE", + "kUNTIL", + "kFOR", + "kBREAK", + "kNEXT", + "kREDO", + "kRETRY", + "kIN", + "kDO", + "kDO_COND", + "kDO_BLOCK", + "kDO_LAMBDA", + "kRETURN", + "kYIELD", + "kSUPER", + "kSELF", + "kNIL", + "kTRUE", + "kFALSE", + "kAND", + "kOR", + "kNOT", + "kIF_MOD", + "kUNLESS_MOD", + "kWHILE_MOD", + "kUNTIL_MOD", + "kRESCUE_MOD", + "kALIAS", + "kDEFINED", + "klBEGIN", + "klEND", + "k__LINE__", + "k__FILE__", + "k__ENCODING__", + "tIDENTIFIER", + "tFID", + "tGVAR", + "tIVAR", + "tCONSTANT", + "tLABEL", + "tCVAR", + "tNTH_REF", + "tBACK_REF", + "tSTRING_CONTENT", + "tINTEGER", + "tFLOAT", + "tUPLUS", + "tUMINUS", + "tUNARY_NUM", + "tPOW", + "tCMP", + "tEQ", + "tEQQ", + "tNEQ", + "tGEQ", + "tLEQ", + "tANDOP", + "tOROP", + "tMATCH", + "tNMATCH", + "tDOT", + "tDOT2", + "tDOT3", + "tAREF", + "tASET", + "tLSHFT", + "tRSHFT", + "tCOLON2", + "tCOLON3", + "tOP_ASGN", + "tASSOC", + "tLPAREN", + "tLPAREN2", + "tRPAREN", + "tLPAREN_ARG", + "tLBRACK", + "tLBRACK2", + "tRBRACK", + "tLBRACE", + "tLBRACE_ARG", + "tSTAR", + "tSTAR2", + "tAMPER", + "tAMPER2", + "tTILDE", + "tPERCENT", + "tDIVIDE", + "tPLUS", + "tMINUS", + "tLT", + "tGT", + "tPIPE", + "tBANG", + "tCARET", + "tLCURLY", + "tRCURLY", + "tBACK_REF2", + "tSYMBEG", + "tSTRING_BEG", + "tXSTRING_BEG", + "tREGEXP_BEG", + "tREGEXP_OPT", + "tWORDS_BEG", + "tQWORDS_BEG", + "tSTRING_DBEG", + "tSTRING_DVAR", + "tSTRING_END", + "tSTRING", + "tSYMBOL", + "tNL", + "tEH", + "tCOLON", + "tCOMMA", + "tSPACE", + "tSEMI", + "tLAMBDA", + "tLAMBEG", + "tCHARACTER", + "tEQL", + "tLOWEST", + "$start", + "program", + "top_compstmt", + "top_stmts", + "opt_terms", + "top_stmt", + "terms", + "stmt", + "bodystmt", + "compstmt", + "opt_rescue", + "opt_else", + "opt_ensure", + "stmts", + "fitem", + "undef_list", + "expr_value", + "command_asgn", + "mlhs", + "command_call", + "var_lhs", + "primary_value", + "opt_call_args", + "rbracket", + "backref", + "lhs", + "mrhs", + "arg_value", + "expr", + "@1", + "opt_nl", + "arg", + "command", + "block_command", + "block_call", + "operation2", + "command_args", + "cmd_brace_block", + "opt_block_param", + "@2", + "operation", + "call_args", + "mlhs_basic", + "mlhs_inner", + "rparen", + "mlhs_head", + "mlhs_item", + "mlhs_node", + "mlhs_post", + "user_variable", + "keyword_variable", + "cname", + "cpath", + "fname", + "op", + "reswords", + "fsym", + "symbol", + "dsym", + "@3", + "primary", + "aref_args", + "none", + "args", + "trailer", + "assocs", + "paren_args", + "opt_paren_args", + "opt_block_arg", + "block_arg", + "@4", + "literal", + "strings", + "xstring", + "regexp", + "words", + "qwords", + "var_ref", + "assoc_list", + "brace_block", + "method_call", + "lambda", + "then", + "if_tail", + "do", + "case_body", + "for_var", + "k_class", + "superclass", + "term", + "k_module", + "f_arglist", + "singleton", + "dot_or_colon", + "@5", + "@6", + "@7", + "@8", + "@9", + "@10", + "@11", + "@12", + "@13", + "@14", + "@15", + "@16", + "@17", + "@18", + "@19", + "f_marg", + "f_norm_arg", + "f_margs", + "f_marg_list", + "block_param", + "f_arg", + "f_block_optarg", + "f_rest_arg", + "opt_f_block_arg", + "f_block_arg", + "block_param_def", + "opt_bv_decl", + "bv_decls", + "bvar", + "f_bad_arg", + "f_larglist", + "lambda_body", + "@20", + "f_args", + "do_block", + "@21", + "@22", + "@23", + "operation3", + "@24", + "@25", + "cases", + "exc_list", + "exc_var", + "numeric", + "string", + "string1", + "string_contents", + "xstring_contents", + "regexp_contents", + "word_list", + "word", + "string_content", + "qword_list", + "string_dvar", + "@26", + "f_optarg", + "f_arg_item", + "f_opt", + "f_block_opt", + "restarg_mark", + "blkarg_mark", + "assoc" ] +Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) + +Racc_debug_parser = false + +##### State transition tables end ##### + +# reduce 0 omitted + +# reduce 1 omitted + +def _reduce_2(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_3(val, _values, result) + result = [] + + result +end + +def _reduce_4(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_5(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_6(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 7 omitted + +def _reduce_8(val, _values, result) + result = @builder.preexe(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_9(val, _values, result) + rescue_bodies = val[1] + else_t, else_ = val[2] + ensure_t, ensure_ = val[3] + + if rescue_bodies.empty? && !else_t.nil? + diagnostic :warning, :useless_else, nil, else_t + end + + result = @builder.begin_body(val[0], + rescue_bodies, + else_t, else_, + ensure_t, ensure_) + + result +end + +def _reduce_10(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_11(val, _values, result) + result = [] + + result +end + +def _reduce_12(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_13(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_14(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_15(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_16(val, _values, result) + result = @builder.alias(val[0], val[1], val[3]) + + result +end + +def _reduce_17(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.gvar(val[2])) + + result +end + +def _reduce_18(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.back_ref(val[2])) + + result +end + +def _reduce_19(val, _values, result) + diagnostic :error, :nth_ref_alias, nil, val[2] + + result +end + +def _reduce_20(val, _values, result) + result = @builder.undef_method(val[0], val[1]) + + result +end + +def _reduce_21(val, _values, result) + result = @builder.condition_mod(val[0], nil, + val[1], val[2]) + + result +end + +def _reduce_22(val, _values, result) + result = @builder.condition_mod(nil, val[0], + val[1], val[2]) + + result +end + +def _reduce_23(val, _values, result) + result = @builder.loop_mod(:while, val[0], val[1], val[2]) + + result +end + +def _reduce_24(val, _values, result) + result = @builder.loop_mod(:until, val[0], val[1], val[2]) + + result +end + +def _reduce_25(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_26(val, _values, result) + result = @builder.postexe(val[0], val[1], val[2], val[3]) + + result +end + +# reduce 27 omitted + +def _reduce_28(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_29(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_30(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_31(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_32(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_33(val, _values, result) + diagnostic :error, :const_reassignment, nil, val[3] + + result +end + +def _reduce_34(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_35(val, _values, result) + @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_36(val, _values, result) + result = @builder.assign(val[0], val[1], + @builder.array(nil, val[2], nil)) + + result +end + +def _reduce_37(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_38(val, _values, result) + result = @builder.multi_assign(val[0], val[1], + @builder.array(nil, val[2], nil)) + + result +end + +# reduce 39 omitted + +def _reduce_40(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_41(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +# reduce 42 omitted + +def _reduce_43(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_44(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_45(val, _values, result) + result = @builder.not_op(val[0], nil, val[2], nil) + + result +end + +def _reduce_46(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +# reduce 47 omitted + +# reduce 48 omitted + +# reduce 49 omitted + +# reduce 50 omitted + +# reduce 51 omitted + +def _reduce_52(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_53(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_54(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_55(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_56(val, _values, result) + result = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + result +end + +def _reduce_57(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + begin_t, args, body, end_t = val[2] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_58(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_59(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_60(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_61(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_62(val, _values, result) + result = @builder.keyword_cmd(:super, val[0], + nil, val[1], nil) + + result +end + +def _reduce_63(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], + nil, val[1], nil) + + result +end + +def _reduce_64(val, _values, result) + result = @builder.keyword_cmd(:return, val[0], + nil, val[1], nil) + + result +end + +def _reduce_65(val, _values, result) + result = @builder.keyword_cmd(:break, val[0], + nil, val[1], nil) + + result +end + +def _reduce_66(val, _values, result) + result = @builder.keyword_cmd(:next, val[0], + nil, val[1], nil) + + result +end + +def _reduce_67(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_68(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_69(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_70(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +# reduce 71 omitted + +def _reduce_72(val, _values, result) + result = val[0]. + push(val[1]) + + result +end + +def _reduce_73(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])) + + result +end + +def _reduce_74(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])). + concat(val[4]) + + result +end + +def _reduce_75(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])) + + result +end + +def _reduce_76(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])). + concat(val[3]) + + result +end + +def _reduce_77(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_78(val, _values, result) + result = [ @builder.splat(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_79(val, _values, result) + result = [ @builder.splat(val[0]) ] + + result +end + +def _reduce_80(val, _values, result) + result = [ @builder.splat(val[0]), + *val[2] ] + + result +end + +# reduce 81 omitted + +def _reduce_82(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_83(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_84(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_85(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_86(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_87(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_88(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_89(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_90(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_91(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_92(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_93(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_94(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_95(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_96(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_97(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_98(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_99(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_100(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_101(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_102(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_103(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_104(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_105(val, _values, result) + diagnostic :error, :module_name_const, nil, val[0] + + result +end + +# reduce 106 omitted + +def _reduce_107(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_108(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_109(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +# reduce 110 omitted + +# reduce 111 omitted + +# reduce 112 omitted + +# reduce 113 omitted + +# reduce 114 omitted + +def _reduce_115(val, _values, result) + result = @builder.symbol_internal(val[0]) + + result +end + +# reduce 116 omitted + +# reduce 117 omitted + +# reduce 118 omitted + +def _reduce_119(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_120(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_121(val, _values, result) + result = val[0] << val[3] + + result +end + +# reduce 122 omitted + +# reduce 123 omitted + +# reduce 124 omitted + +# reduce 125 omitted + +# reduce 126 omitted + +# reduce 127 omitted + +# reduce 128 omitted + +# reduce 129 omitted + +# reduce 130 omitted + +# reduce 131 omitted + +# reduce 132 omitted + +# reduce 133 omitted + +# reduce 134 omitted + +# reduce 135 omitted + +# reduce 136 omitted + +# reduce 137 omitted + +# reduce 138 omitted + +# reduce 139 omitted + +# reduce 140 omitted + +# reduce 141 omitted + +# reduce 142 omitted + +# reduce 143 omitted + +# reduce 144 omitted + +# reduce 145 omitted + +# reduce 146 omitted + +# reduce 147 omitted + +# reduce 148 omitted + +# reduce 149 omitted + +# reduce 150 omitted + +# reduce 151 omitted + +# reduce 152 omitted + +# reduce 153 omitted + +# reduce 154 omitted + +# reduce 155 omitted + +# reduce 156 omitted + +# reduce 157 omitted + +# reduce 158 omitted + +# reduce 159 omitted + +# reduce 160 omitted + +# reduce 161 omitted + +# reduce 162 omitted + +# reduce 163 omitted + +# reduce 164 omitted + +# reduce 165 omitted + +# reduce 166 omitted + +# reduce 167 omitted + +# reduce 168 omitted + +# reduce 169 omitted + +# reduce 170 omitted + +# reduce 171 omitted + +# reduce 172 omitted + +# reduce 173 omitted + +# reduce 174 omitted + +# reduce 175 omitted + +# reduce 176 omitted + +# reduce 177 omitted + +# reduce 178 omitted + +# reduce 179 omitted + +# reduce 180 omitted + +# reduce 181 omitted + +# reduce 182 omitted + +# reduce 183 omitted + +# reduce 184 omitted + +# reduce 185 omitted + +# reduce 186 omitted + +# reduce 187 omitted + +# reduce 188 omitted + +# reduce 189 omitted + +# reduce 190 omitted + +# reduce 191 omitted + +def _reduce_192(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_193(val, _values, result) + rescue_body = @builder.rescue_body(val[3], + nil, nil, nil, + nil, val[4]) + + rescue_ = @builder.begin_body(val[2], [ rescue_body ]) + + result = @builder.assign(val[0], val[1], rescue_) + + result +end + +def _reduce_194(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_195(val, _values, result) + rescue_body = @builder.rescue_body(val[3], + nil, nil, nil, + nil, val[4]) + + rescue_ = @builder.begin_body(val[2], [ rescue_body ]) + + result = @builder.op_assign(val[0], val[1], rescue_) + + result +end + +def _reduce_196(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_197(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_198(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_199(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_200(val, _values, result) + diagnostic :error, :dynamic_const, nil, val[2], [ val[3] ] + + result +end + +def _reduce_201(val, _values, result) + diagnostic :error, :dynamic_const, nil, val[1], [ val[2] ] + + result +end + +def _reduce_202(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_203(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_204(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_205(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_206(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_207(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_208(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_209(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_210(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_211(val, _values, result) + result = @builder.unary_op(val[0], + @builder.binary_op( + @builder.integer(val[1]), + val[2], val[3])) + + result +end + +def _reduce_212(val, _values, result) + result = @builder.unary_op(val[0], + @builder.binary_op( + @builder.float(val[1]), + val[2], val[3])) + + result +end + +def _reduce_213(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_214(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_215(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_216(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_217(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_218(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_219(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_220(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_221(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_222(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_223(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_224(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_225(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_226(val, _values, result) + result = @builder.match_op(val[0], val[1], val[2]) + + result +end + +def _reduce_227(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_228(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +def _reduce_229(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_230(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_231(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_232(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_233(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_234(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil) + + result +end + +def _reduce_235(val, _values, result) + result = @builder.ternary(val[0], val[1], + val[2], val[4], val[5]) + + result +end + +# reduce 236 omitted + +# reduce 237 omitted + +# reduce 238 omitted + +# reduce 239 omitted + +def _reduce_240(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_241(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +def _reduce_242(val, _values, result) + result = val + + result +end + +def _reduce_243(val, _values, result) + result = [ nil, [], nil ] + + result +end + +# reduce 244 omitted + +def _reduce_245(val, _values, result) + result = [] + + result +end + +# reduce 246 omitted + +# reduce 247 omitted + +def _reduce_248(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_249(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +def _reduce_250(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_251(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_252(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + result.concat(val[1]) + + result +end + +def _reduce_253(val, _values, result) + assocs = @builder.associate(nil, val[2], nil) + result = val[0] << assocs + result.concat(val[3]) + + result +end + +def _reduce_254(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_255(val, _values, result) + result = @lexer.cmdarg.dup + @lexer.cmdarg.push(true) + + result +end + +def _reduce_256(val, _values, result) + @lexer.cmdarg = val[0] + + result = val[1] + + result +end + +def _reduce_257(val, _values, result) + result = @builder.block_pass(val[0], val[1]) + + result +end + +def _reduce_258(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_259(val, _values, result) + result = [] + + result +end + +def _reduce_260(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_261(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_262(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_263(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_264(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_265(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_266(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +# reduce 267 omitted + +# reduce 268 omitted + +# reduce 269 omitted + +# reduce 270 omitted + +# reduce 271 omitted + +# reduce 272 omitted + +# reduce 273 omitted + +# reduce 274 omitted + +def _reduce_275(val, _values, result) + result = @builder.call_method(nil, nil, val[0]) + + result +end + +def _reduce_276(val, _values, result) + result = @builder.begin_keyword(val[0], val[1], val[2]) + + result +end + +def _reduce_277(val, _values, result) + result = @lexer.cmdarg.dup + @lexer.cmdarg.clear + + result +end + +def _reduce_278(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_279(val, _values, result) + @lexer.cmdarg = val[1] + + result = @builder.begin(val[0], val[2], val[5]) + + result +end + +def _reduce_280(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_281(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +def _reduce_282(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_283(val, _values, result) + result = @builder.array(val[0], val[1], val[2]) + + result +end + +def _reduce_284(val, _values, result) + result = @builder.associate(val[0], val[1], val[2]) + + result +end + +def _reduce_285(val, _values, result) + result = @builder.keyword_cmd(:return, val[0]) + + result +end + +def _reduce_286(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_287(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2]) + + result +end + +def _reduce_288(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0]) + + result +end + +def _reduce_289(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], + val[2], [ val[3] ], val[4]) + + result +end + +def _reduce_290(val, _values, result) + result = @builder.not_op(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_291(val, _values, result) + result = @builder.not_op(val[0], val[1], nil, val[2]) + + result +end + +def _reduce_292(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0]) + + begin_t, args, body, end_t = val[1] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +# reduce 293 omitted + +def _reduce_294(val, _values, result) + begin_t, args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, args, body, end_t) + + result +end + +def _reduce_295(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_296(val, _values, result) + lambda_call = @builder.call_lambda(val[0]) + + args, (begin_t, body, end_t) = val[2] + result = @builder.block(lambda_call, + begin_t, args, body, end_t) + + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_297(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, val[5]) + + result +end + +def _reduce_298(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + else_, else_t, + val[3], val[5]) + + result +end + +def _reduce_299(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_300(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_301(val, _values, result) + result = @builder.loop(:while, val[0], val[2], val[3], + val[5], val[6]) + + result +end + +def _reduce_302(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_303(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_304(val, _values, result) + result = @builder.loop(:until, val[0], val[2], val[3], + val[5], val[6]) + + result +end + +def _reduce_305(val, _values, result) + *when_bodies, (else_t, else_body) = *val[3] + + result = @builder.case(val[0], val[1], + when_bodies, else_t, else_body, + val[4]) + + result +end + +def _reduce_306(val, _values, result) + *when_bodies, (else_t, else_body) = *val[2] + + result = @builder.case(val[0], nil, + when_bodies, else_t, else_body, + val[3]) + + result +end + +def _reduce_307(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_308(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_309(val, _values, result) + result = @builder.for(val[0], val[1], + val[2], val[4], + val[5], val[7], val[8]) + + result +end + +def _reduce_310(val, _values, result) + local_push + @context.in_class = true + + result +end + +def _reduce_311(val, _values, result) + k_class, ctx = val[0] + if @context.in_def + diagnostic :error, :class_in_def, nil, k_class + end + + lt_t, superclass = val[2] + result = @builder.def_class(k_class, val[1], + lt_t, superclass, + val[4], val[5]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_312(val, _values, result) + @context.in_def = false + @context.in_class = false + local_push + + result +end + +def _reduce_313(val, _values, result) + k_class, ctx = val[0] + result = @builder.def_sclass(k_class, val[1], val[2], + val[5], val[6]) + + local_pop + @context.in_def = ctx.in_def + @context.in_class = ctx.in_class + + result +end + +def _reduce_314(val, _values, result) + @context.in_class = true + local_push + + result +end + +def _reduce_315(val, _values, result) + k_mod, ctx = val[0] + if @context.in_def + diagnostic :error, :module_in_def, nil, k_mod + end + + result = @builder.def_module(k_mod, val[1], + val[3], val[4]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_316(val, _values, result) + local_push + result = context.dup + @context.in_def = true + + result +end + +def _reduce_317(val, _values, result) + result = @builder.def_method(val[0], val[1], + val[3], val[4], val[5]) + + local_pop + @context.in_def = val[2].in_def + + result +end + +def _reduce_318(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_319(val, _values, result) + local_push + result = context.dup + @context.in_def = true + + result +end + +def _reduce_320(val, _values, result) + result = @builder.def_singleton(val[0], val[1], val[2], + val[4], val[6], val[7], val[8]) + + local_pop + @context.in_def = val[5].in_def + + result +end + +def _reduce_321(val, _values, result) + result = @builder.keyword_cmd(:break, val[0]) + + result +end + +def _reduce_322(val, _values, result) + result = @builder.keyword_cmd(:next, val[0]) + + result +end + +def _reduce_323(val, _values, result) + result = @builder.keyword_cmd(:redo, val[0]) + + result +end + +def _reduce_324(val, _values, result) + result = @builder.keyword_cmd(:retry, val[0]) + + result +end + +# reduce 325 omitted + +def _reduce_326(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_327(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +# reduce 328 omitted + +# reduce 329 omitted + +def _reduce_330(val, _values, result) + result = val[1] + + result +end + +# reduce 331 omitted + +# reduce 332 omitted + +# reduce 333 omitted + +def _reduce_334(val, _values, result) + else_t, else_ = val[4] + result = [ val[0], + @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, nil), + ] + + result +end + +# reduce 335 omitted + +def _reduce_336(val, _values, result) + result = val + + result +end + +# reduce 337 omitted + +# reduce 338 omitted + +def _reduce_339(val, _values, result) + @static_env.declare val[0][0] + + result = @builder.arg(val[0]) + + result +end + +def _reduce_340(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_341(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_342(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 343 omitted + +def _reduce_344(val, _values, result) + @static_env.declare val[3][0] + + result = val[0]. + push(@builder.restarg(val[2], val[3])) + + result +end + +def _reduce_345(val, _values, result) + @static_env.declare val[3][0] + + result = val[0]. + push(@builder.restarg(val[2], val[3])). + concat(val[5]) + + result +end + +def _reduce_346(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2])) + + result +end + +def _reduce_347(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2])). + concat(val[4]) + + result +end + +def _reduce_348(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_349(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.restarg(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_350(val, _values, result) + result = [ @builder.restarg(val[0]) ] + + result +end + +def _reduce_351(val, _values, result) + result = [ @builder.restarg(val[0]), + *val[2] ] + + result +end + +def _reduce_352(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_353(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_354(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_355(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_356(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 357 omitted + +def _reduce_358(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_359(val, _values, result) + if val[1].empty? && val[0].size == 1 + result = [@builder.procarg0(val[0][0])] + else + result = val[0].concat(val[1]) + end + + result +end + +def _reduce_360(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_361(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_362(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_363(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_364(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_365(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_366(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_367(val, _values, result) + result = @builder.args(nil, [], nil) + + result +end + +def _reduce_368(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_369(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + result +end + +def _reduce_370(val, _values, result) + result = @builder.args(val[0], [], val[0]) + + result +end + +def _reduce_371(val, _values, result) + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_372(val, _values, result) + result = [] + + result +end + +def _reduce_373(val, _values, result) + result = val[1] + + result +end + +def _reduce_374(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_375(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_376(val, _values, result) + @static_env.declare val[0][0] + result = @builder.shadowarg(val[0]) + + result +end + +# reduce 377 omitted + +def _reduce_378(val, _values, result) + @static_env.extend_dynamic + + result +end + +def _reduce_379(val, _values, result) + result = [ val[1], val[2] ] + + @static_env.unextend + + result +end + +def _reduce_380(val, _values, result) + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_381(val, _values, result) + result = @builder.args(nil, val[0], nil) + + result +end + +def _reduce_382(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_383(val, _values, result) + result = [ val[0], val[2], val[3] ] + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_384(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_385(val, _values, result) + result = [ val[0], val[2], val[3] ] + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_386(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_387(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_388(val, _values, result) + begin_t, block_args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, block_args, body, end_t) + + result +end + +def _reduce_389(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_390(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_391(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.call_method(nil, nil, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_392(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_393(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_394(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2]) + + result +end + +def _reduce_395(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_396(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_397(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.keyword_cmd(:super, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_398(val, _values, result) + result = @builder.keyword_cmd(:zsuper, val[0]) + + result +end + +def _reduce_399(val, _values, result) + result = @builder.index(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_400(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_401(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_402(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_403(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_404(val, _values, result) + result = [ @builder.when(val[0], val[1], val[2], val[3]), + *val[4] ] + + result +end + +def _reduce_405(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 406 omitted + +def _reduce_407(val, _values, result) + assoc_t, exc_var = val[2] + + if val[1] + exc_list = @builder.array(nil, val[1], nil) + end + + result = [ @builder.rescue_body(val[0], + exc_list, assoc_t, exc_var, + val[3], val[4]), + *val[5] ] + + result +end + +def _reduce_408(val, _values, result) + result = [] + + result +end + +def _reduce_409(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 410 omitted + +# reduce 411 omitted + +def _reduce_412(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 413 omitted + +def _reduce_414(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 415 omitted + +# reduce 416 omitted + +# reduce 417 omitted + +# reduce 418 omitted + +def _reduce_419(val, _values, result) + result = @builder.string_compose(nil, val[0], nil) + + result +end + +def _reduce_420(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_421(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_422(val, _values, result) + result = @builder.string_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_423(val, _values, result) + result = @builder.string(val[0]) + + result +end + +def _reduce_424(val, _values, result) + result = @builder.character(val[0]) + + result +end + +def _reduce_425(val, _values, result) + result = @builder.xstring_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_426(val, _values, result) + opts = @builder.regexp_options(val[3]) + result = @builder.regexp_compose(val[0], val[1], val[2], opts) + + result +end + +def _reduce_427(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_428(val, _values, result) + result = [] + + result +end + +def _reduce_429(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_430(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_431(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_432(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_433(val, _values, result) + result = [] + + result +end + +def _reduce_434(val, _values, result) + result = val[0] << @builder.string_internal(val[1]) + + result +end + +def _reduce_435(val, _values, result) + result = [] + + result +end + +def _reduce_436(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_437(val, _values, result) + result = [] + + result +end + +def _reduce_438(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_439(val, _values, result) + result = [] + + result +end + +def _reduce_440(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_441(val, _values, result) + result = @builder.string_internal(val[0]) + + result +end + +def _reduce_442(val, _values, result) + result = val[1] + + result +end + +def _reduce_443(val, _values, result) + @lexer.cond.push(false) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_444(val, _values, result) + @lexer.cond.lexpop + @lexer.cmdarg.lexpop + + result = @builder.begin(val[0], val[2], val[3]) + + result +end + +def _reduce_445(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_446(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_447(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +# reduce 448 omitted + +def _reduce_449(val, _values, result) + result = @builder.symbol(val[0]) + + result +end + +def _reduce_450(val, _values, result) + result = @builder.symbol_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_451(val, _values, result) + result = @builder.integer(val[0]) + + result +end + +def _reduce_452(val, _values, result) + result = @builder.float(val[0]) + + result +end + +def _reduce_453(val, _values, result) + num = @builder.integer(val[1]) + if @builder.respond_to? :negate + # AST builder interface compatibility + result = @builder.negate(val[0], num) + else + result = @builder.unary_num(val[0], num) + end + + result +end + +def _reduce_454(val, _values, result) + num = @builder.float(val[1]) + if @builder.respond_to? :negate + # AST builder interface compatibility + result = @builder.negate(val[0], num) + else + result = @builder.unary_num(val[0], num) + end + + result +end + +def _reduce_455(val, _values, result) + result = @builder.ident(val[0]) + + result +end + +def _reduce_456(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_457(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_458(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_459(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +def _reduce_460(val, _values, result) + result = @builder.nil(val[0]) + + result +end + +def _reduce_461(val, _values, result) + result = @builder.self(val[0]) + + result +end + +def _reduce_462(val, _values, result) + result = @builder.true(val[0]) + + result +end + +def _reduce_463(val, _values, result) + result = @builder.false(val[0]) + + result +end + +def _reduce_464(val, _values, result) + result = @builder.__FILE__(val[0]) + + result +end + +def _reduce_465(val, _values, result) + result = @builder.__LINE__(val[0]) + + result +end + +def _reduce_466(val, _values, result) + result = @builder.__ENCODING__(val[0]) + + result +end + +def _reduce_467(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_468(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_469(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_470(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_471(val, _values, result) + result = @builder.nth_ref(val[0]) + + result +end + +def _reduce_472(val, _values, result) + result = @builder.back_ref(val[0]) + + result +end + +def _reduce_473(val, _values, result) + result = nil + + result +end + +def _reduce_474(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +def _reduce_475(val, _values, result) + yyerrok + result = nil + + result +end + +def _reduce_476(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + @lexer.state = :expr_value + + result +end + +def _reduce_477(val, _values, result) + result = @builder.args(nil, val[0], nil) + + result +end + +def _reduce_478(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_479(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_480(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_481(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_482(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_483(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_484(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_485(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_486(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_487(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_488(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_489(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_490(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_491(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_492(val, _values, result) + result = [] + + result +end + +def _reduce_493(val, _values, result) + diagnostic :error, :argument_const, nil, val[0] + + result +end + +def _reduce_494(val, _values, result) + diagnostic :error, :argument_ivar, nil, val[0] + + result +end + +def _reduce_495(val, _values, result) + diagnostic :error, :argument_gvar, nil, val[0] + + result +end + +def _reduce_496(val, _values, result) + diagnostic :error, :argument_cvar, nil, val[0] + + result +end + +# reduce 497 omitted + +# reduce 498 omitted + +def _reduce_499(val, _values, result) + @static_env.declare val[0][0] + + result = @builder.arg(val[0]) + + result +end + +def _reduce_500(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_501(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_502(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_503(val, _values, result) + @static_env.declare val[0][0] + + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_504(val, _values, result) + @static_env.declare val[0][0] + + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_505(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_506(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_507(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_508(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 509 omitted + +# reduce 510 omitted + +def _reduce_511(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_512(val, _values, result) + result = [ @builder.restarg(val[0]) ] + + result +end + +# reduce 513 omitted + +# reduce 514 omitted + +def _reduce_515(val, _values, result) + @static_env.declare val[1][0] + + result = @builder.blockarg(val[0], val[1]) + + result +end + +def _reduce_516(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_517(val, _values, result) + result = [] + + result +end + +# reduce 518 omitted + +def _reduce_519(val, _values, result) + result = val[1] + + result +end + +def _reduce_520(val, _values, result) + result = [] + + result +end + +# reduce 521 omitted + +def _reduce_522(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_523(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_524(val, _values, result) + result = @builder.pair(val[0], val[1], val[2]) + + result +end + +def _reduce_525(val, _values, result) + result = @builder.pair_keyword(val[0], val[1]) + + result +end + +# reduce 526 omitted + +# reduce 527 omitted + +# reduce 528 omitted + +# reduce 529 omitted + +# reduce 530 omitted + +# reduce 531 omitted + +# reduce 532 omitted + +# reduce 533 omitted + +# reduce 534 omitted + +# reduce 535 omitted + +# reduce 536 omitted + +# reduce 537 omitted + +# reduce 538 omitted + +# reduce 539 omitted + +# reduce 540 omitted + +# reduce 541 omitted + +def _reduce_542(val, _values, result) + result = val[1] + + result +end + +def _reduce_543(val, _values, result) + result = val[1] + + result +end + +# reduce 544 omitted + +# reduce 545 omitted + +# reduce 546 omitted + +def _reduce_547(val, _values, result) + yyerrok + + result +end + +# reduce 548 omitted + +# reduce 549 omitted + +# reduce 550 omitted + +def _reduce_551(val, _values, result) + result = nil + + result +end + +def _reduce_none(val, _values, result) + val[0] +end + + end # class Ruby19 +end # module Parser diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby20.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby20.rb new file mode 100644 index 00000000..3ed28c10 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby20.rb @@ -0,0 +1,10229 @@ +# -*- encoding:utf-8; warn-indent:false; frozen_string_literal: true -*- +# +# DO NOT MODIFY!!!! +# This file is automatically generated by Racc 1.8.1 +# from Racc grammar file "ruby20.y". +# + +require 'racc/parser.rb' + + +require_relative '../parser' + +module Parser + class Ruby20 < Parser::Base + + + def version + 20 + end + + def default_encoding + Encoding::UTF_8 + end + + def local_push + @static_env.extend_static + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + end + + def local_pop + @static_env.unextend + @lexer.cmdarg.pop + @lexer.cond.pop + end +##### State transition tables begin ### + +racc_action_table = [ + -476, 5, 74, 75, 71, 9, 57, -476, -476, -476, + 63, 64, -476, -476, -476, 67, -476, 65, 66, 68, + 30, 31, 72, 73, -476, 267, -476, -476, -476, 29, + 28, 27, 100, 99, 101, 102, -476, -476, 19, -476, + -476, -476, -476, -476, 8, 45, 7, 10, 104, 103, + 105, 94, 56, 96, 95, 97, -98, 98, 106, 107, + 556, 92, 93, 42, 43, 41, -476, -476, -476, -476, + -476, -476, -476, -476, -476, -476, -476, -476, -476, -476, + 267, -99, -476, -476, -476, 40, -476, -476, 33, -106, + -476, 58, 59, -476, -476, 60, -476, 35, -476, 267, + -476, 44, -476, -476, 267, -476, -476, -476, -476, -476, + 20, -476, 266, -476, 216, 91, 81, 84, 85, 577, + 86, 88, 87, 89, -105, 108, 789, -476, 82, 90, + -476, -476, -476, -476, -479, -476, 62, -476, 83, -476, + -101, -479, -479, -479, 262, 535, -479, -479, -479, 579, + -479, 120, 535, -103, 112, 217, 535, -286, -479, 111, + -479, -479, -479, -100, 614, -89, 555, 266, 262, -490, + -479, -479, 535, -479, -479, -479, -479, -479, 535, -101, + -103, -100, -102, -102, 690, 576, 266, 112, 259, 112, + -90, 266, 111, -491, 111, 260, 205, -286, -97, 613, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + -479, -479, -479, -479, 206, 578, -479, -479, -479, -476, + -479, -479, -98, -92, -479, 441, -476, -479, -479, 512, + -479, 690, -479, -96, -479, 788, -479, -479, 745, -479, + -479, -479, -479, -479, -289, -479, -99, -479, -568, -92, + 690, -289, -289, -289, 213, 214, 746, -289, -289, -568, + -289, -479, -94, 112, -479, -479, -479, -479, 111, -479, + 112, -479, -91, -479, 112, 111, -104, 820, -106, 111, + -289, -289, -105, -289, -289, -289, -289, -289, 112, -92, + 112, -101, -93, 111, -94, 111, 112, -101, -103, -100, + -102, 111, -101, -103, -100, -102, 207, 213, 214, -103, + -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, + -289, -289, -289, -289, 213, 214, -289, -289, -289, -92, + 597, 212, -92, 211, -289, 112, 838, -289, -92, -84, + 111, -569, -289, 614, -289, -70, -289, -289, 217, -289, + -289, -289, -289, -289, 112, -289, -572, -289, 256, 111, + -94, 213, 214, -572, -572, -572, -490, 614, -491, -572, + -572, -289, -572, 525, -289, -289, 524, -95, 613, -289, + -97, -572, 614, -104, -565, -95, -106, -479, 525, -100, + 314, 527, -572, -572, -479, -572, -572, -572, -572, -572, + -94, 112, 613, -94, 512, 780, 111, 541, 807, -94, + 666, 665, 664, -89, 667, -90, 564, 613, 217, -98, + -566, -99, -572, -572, -572, -572, -572, -572, -572, -572, + -572, -572, -572, -572, -572, -572, -476, 209, -572, -572, + -572, 564, 598, -476, 210, 315, -572, 217, -565, -572, + -572, -96, -476, 208, -572, 217, -572, -105, -572, -572, + 384, -572, -572, -572, -572, -572, 564, -572, -572, -572, + 592, -565, -479, 112, 525, 213, 214, 527, 111, -479, + 566, 565, 562, -572, -566, -572, -572, -572, -479, -93, + 885, -572, -572, -572, -572, -102, -486, -572, -572, -572, + 547, -572, -572, -486, 548, 566, 565, -566, 397, -572, + -572, -572, -572, -572, -568, 722, 525, -92, -572, 527, + 440, -572, -572, -101, -572, -572, -572, -572, -572, 442, + 566, 565, 807, 593, 666, 665, 664, -572, 667, 564, + 724, -485, -487, -572, 564, 112, 316, 317, -485, -487, + 111, -572, -572, -572, -572, -572, -572, -572, -572, -572, + -572, -572, -572, -572, -572, 507, 508, -572, -572, -572, + -484, 747, -572, 564, 443, -572, 731, -484, -572, -572, + -94, -572, -414, -572, 112, -572, -103, -572, -572, 111, + -572, -572, -572, -572, -572, -572, -572, -572, -572, 564, + 213, 214, -572, 566, 565, 567, 564, -568, 566, 565, + 569, -572, -572, 216, 981, -572, -572, -572, -572, -289, + -572, 474, -572, -91, -102, 483, -289, -289, -289, -100, + -572, -289, -289, -289, -414, -289, -333, 566, 565, 571, + 485, -414, -481, -333, -482, -289, -289, -289, 394, -481, + -414, -482, -333, 396, 395, -289, -289, 487, -289, -289, + -289, -289, -289, 566, 565, 575, 437, 494, -488, -414, + 566, 565, 580, 438, 807, -488, 666, 665, 664, -69, + 667, 217, 439, 497, -488, -289, -289, -289, -289, -289, + -289, -289, -289, -289, -289, -289, -289, -289, -289, 237, + 673, -289, -289, -289, 498, 748, -289, -483, 505, -289, + 675, 803, -289, -289, -483, -289, 271, -289, 217, -289, + 806, -289, -289, 762, -289, -289, -289, -289, -289, 262, + -289, 234, -289, 675, 259, 236, 235, 112, 232, 233, + 509, 260, 111, 683, 682, 513, -289, 514, 676, -289, + -289, -289, -289, 237, -289, 217, -289, 528, -104, 288, + 74, 75, 71, 9, 57, 529, 683, 682, 63, 64, + 487, 676, 81, 67, 541, 65, 66, 68, 30, 31, + 72, 73, 217, 386, 82, 966, 545, 29, 28, 27, + 100, 99, 101, 102, 83, 546, 19, 213, 214, 815, + 780, 602, 8, 45, 290, 10, 104, 103, 105, 94, + 56, 96, 95, 97, 581, 98, 106, 107, 584, 92, + 93, 42, 43, 41, 237, 241, 246, 247, 248, 243, + 245, 253, 254, 249, 250, -489, 230, 231, 503, -263, + 251, 252, -489, 40, 586, 504, 292, 683, 682, 58, + 59, -489, 217, 60, 502, 35, 234, 590, 240, 44, + 236, 235, 591, 232, 233, 244, 242, 238, 20, 239, + 815, 780, 262, 91, 81, 84, 85, -279, 86, 88, + 87, 89, 601, 237, -279, 515, 82, 90, 604, 255, + -280, -240, 516, -279, 62, 237, 83, -280, -280, -280, + 237, 439, -280, -280, -280, 807, -280, 666, 665, 664, + 237, 667, 237, 217, 217, 234, -280, -280, -280, 236, + 235, 543, 232, 233, 217, -84, -280, -280, 544, -280, + -280, -280, -280, -280, 632, 217, 518, 542, 643, 237, + 649, 807, 803, 666, 665, 664, 650, 667, 716, 717, + 652, 806, 718, 106, 107, 686, -280, -280, -280, -280, + -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, + 237, 234, -280, -280, -280, 236, 235, -280, 803, 541, + -280, 693, 721, -280, -280, 725, -280, 943, -280, 726, + -280, -264, -280, -280, 732, -280, -280, -280, -280, -280, + 474, -280, 234, -280, 474, 217, 236, 235, 551, 750, + 914, 256, 666, 665, 664, 550, 667, -280, 485, -290, + -280, -280, -280, -280, 552, -280, -290, -280, 5, 74, + 75, 71, 9, 57, 487, -290, -290, 63, 64, 773, + 643, 217, 67, -290, 65, 66, 68, 30, 31, 72, + 73, 262, -290, 262, 643, 237, 29, 28, 27, 100, + 99, 101, 102, 237, 914, 19, 666, 665, 664, 780, + 667, 8, 45, 7, 10, 104, 103, 105, 94, 56, + 96, 95, 97, 217, 98, 106, 107, 791, 92, 93, + 42, 43, 41, 237, 241, 246, 247, 248, 243, 245, + 253, 254, 249, 250, -289, -591, -591, 551, 794, 251, + 252, -289, 40, 795, 917, 33, -569, 797, 58, 59, + -289, 799, 60, 552, 35, 234, 801, 240, 44, 236, + 235, 810, 232, 233, 244, 242, 238, 20, 239, 811, + 812, 780, 91, 81, 84, 85, 819, 86, 88, 87, + 89, 217, 217, 828, -265, 82, 90, 288, 74, 75, + 71, 9, 57, 62, 837, 83, 63, 64, 840, 794, + 843, 67, 845, 65, 66, 68, 30, 31, 72, 73, + 115, 116, 117, 118, 119, 29, 28, 27, 100, 99, + 101, 102, 847, 849, 19, 115, 116, 117, 118, 119, + 8, 45, 290, 10, 104, 103, 105, 94, 56, 96, + 95, 97, 217, 98, 106, 107, 851, 92, 93, 42, + 43, 41, 237, 241, 246, 247, 248, 243, 245, 253, + 254, 249, 250, -289, -591, -591, 551, 852, 251, 252, + -289, 40, 855, 917, 33, -569, 857, 58, 59, -289, + 858, 60, 552, 35, 234, 643, 240, 44, 236, 235, + 860, 232, 233, 244, 242, 238, 20, 239, -263, 864, + 866, 91, 81, 84, 85, 217, 86, 88, 87, 89, + 883, 217, 887, 889, 82, 90, 288, 74, 75, 71, + 9, 57, 62, 895, 83, 63, 64, 898, 217, 901, + 67, -266, 65, 66, 68, 30, 31, 72, 73, 115, + 116, 117, 118, 119, 29, 28, 27, 100, 99, 101, + 102, 911, 807, 19, 666, 665, 664, 918, 667, 8, + 45, 290, 10, 104, 103, 105, 94, 56, 96, 95, + 97, 919, 98, 106, 107, 930, 92, 93, 42, 43, + 41, 237, -591, -591, -591, -591, 243, 245, -488, 803, + -591, -591, -489, 794, 932, -488, 934, 251, 252, -489, + 40, 936, 938, 33, -488, 938, 58, 59, -489, 217, + 60, 944, 35, 234, 947, 240, 44, 236, 235, 948, + 232, 233, 244, 242, 238, 20, 239, 953, 794, 956, + 91, 81, 84, 85, 958, 86, 88, 87, 89, 960, + 962, 962, 973, 82, 90, 288, 74, 75, 71, 9, + 57, 62, 974, 83, 63, 64, 975, 983, -569, 67, + -568, 65, 66, 68, 30, 31, 72, 73, 649, 998, + 938, 938, 938, 29, 28, 27, 100, 99, 101, 102, + 1003, 807, 19, 666, 665, 664, 983, 667, 8, 45, + 290, 10, 104, 103, 105, 94, 56, 96, 95, 97, + 1006, 98, 106, 107, 1007, 92, 93, 42, 43, 41, + 237, 807, 1008, 666, 665, 664, 962, 667, 803, 807, + 962, 666, 665, 664, 971, 667, 251, 252, 962, 40, + 217, 972, 292, 983, 938, 58, 59, 983, 962, 60, + 970, 35, 234, nil, 240, 44, 236, 235, 803, 232, + 233, nil, nil, 238, 20, 239, 803, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, 288, 74, 75, 71, 9, 57, + 62, nil, 83, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 100, 99, 101, 102, nil, + 807, 19, 666, 665, 664, nil, 667, 8, 45, 290, + 10, 104, 103, 105, 94, 56, 96, 95, 97, nil, + 98, 106, 107, -279, 92, 93, 42, 43, 41, 237, + -279, -290, nil, nil, nil, nil, nil, 803, -290, -279, + nil, nil, nil, nil, nil, 251, 252, -290, 40, nil, + nil, 292, nil, nil, 58, 59, nil, nil, 60, nil, + 35, 234, nil, 240, 44, 236, 235, nil, 232, 233, + nil, nil, 238, 20, 239, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, 288, 74, 75, 71, 9, 57, 62, + nil, 83, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 30, 31, 72, 73, nil, nil, nil, nil, + nil, 29, 28, 27, 100, 99, 101, 102, nil, nil, + 19, nil, nil, nil, nil, 587, 8, 45, 290, 10, + 104, 103, 105, 94, 56, 96, 95, 97, nil, 98, + 106, 107, nil, 92, 93, 42, 43, 41, 237, 241, + 246, 247, 248, 243, 245, 253, 254, 249, 250, -289, + 230, 231, nil, nil, 251, 252, -289, 40, nil, nil, + 33, -569, nil, 58, 59, -289, nil, 60, nil, 35, + 234, nil, 240, 44, 236, 235, nil, 232, 233, 244, + 242, 238, 20, 239, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, 255, -573, nil, nil, nil, 62, nil, + 83, -573, -573, -573, nil, nil, -573, -573, -573, 237, + -573, nil, nil, nil, nil, nil, nil, nil, nil, -573, + -573, -573, -573, nil, nil, 251, 252, nil, nil, nil, + -573, -573, nil, -573, -573, -573, -573, -573, nil, nil, + nil, 234, nil, 240, nil, 236, 235, nil, 232, 233, + nil, nil, 238, nil, 239, nil, nil, nil, nil, nil, + -573, -573, -573, -573, -573, -573, -573, -573, -573, -573, + -573, -573, -573, -573, nil, nil, -573, -573, -573, nil, + nil, -573, nil, nil, -573, nil, nil, -573, -573, nil, + -573, nil, -573, nil, -573, nil, -573, -573, nil, -573, + -573, -573, -573, -573, nil, -573, -573, -573, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, -573, nil, nil, -573, -573, -573, -573, -574, -573, + nil, -573, nil, nil, nil, -574, -574, -574, nil, nil, + -574, -574, -574, 237, -574, nil, nil, nil, nil, nil, + nil, nil, nil, -574, -574, -574, -574, nil, nil, 251, + 252, nil, nil, nil, -574, -574, nil, -574, -574, -574, + -574, -574, nil, nil, nil, 234, nil, 240, nil, 236, + 235, nil, 232, 233, nil, nil, 238, nil, 239, nil, + nil, nil, nil, nil, -574, -574, -574, -574, -574, -574, + -574, -574, -574, -574, -574, -574, -574, -574, nil, nil, + -574, -574, -574, nil, nil, -574, nil, nil, -574, nil, + nil, -574, -574, nil, -574, nil, -574, nil, -574, nil, + -574, -574, nil, -574, -574, -574, -574, -574, nil, -574, + -574, -574, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, -574, nil, nil, -574, -574, + -574, -574, nil, -574, nil, -574, 5, 74, 75, 71, + 9, 57, nil, nil, nil, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 100, 99, 101, + 102, nil, nil, 19, nil, nil, nil, nil, nil, 8, + 45, 7, 10, 104, 103, 105, 94, 56, 96, 95, + 97, nil, 98, 106, 107, nil, 92, 93, 42, 43, + 41, 237, -591, -591, -591, -591, 243, 245, nil, nil, + -591, -591, nil, nil, nil, nil, nil, 251, 252, nil, + 40, nil, nil, 33, nil, nil, 58, 59, nil, nil, + 60, nil, 35, 234, nil, 240, 44, 236, 235, nil, + 232, 233, 244, 242, 238, 20, 239, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, 288, 74, 75, 71, 9, + 57, 62, nil, 83, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 100, 99, 101, 102, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 290, 10, 104, 103, 105, 94, 56, 96, 95, 97, + nil, 98, 106, 107, nil, 92, 93, 42, 43, 41, + 237, -591, -591, -591, -591, 243, 245, nil, nil, -591, + -591, nil, nil, nil, nil, nil, 251, 252, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 234, nil, 240, 44, 236, 235, nil, 232, + 233, 244, 242, 238, 20, 239, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, 288, 74, 75, 71, 9, 57, + 62, nil, 83, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 100, 99, 101, 102, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 290, + 10, 104, 103, 105, 94, 56, 96, 95, 97, nil, + 98, 106, 107, nil, 92, 93, 42, 43, 41, 237, + -591, -591, -591, -591, 243, 245, nil, nil, -591, -591, + nil, nil, nil, nil, nil, 251, 252, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, 234, nil, 240, 44, 236, 235, nil, 232, 233, + 244, 242, 238, 20, 239, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, 288, 74, 75, 71, 9, 57, 62, + nil, 83, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 30, 31, 72, 73, nil, nil, nil, nil, + nil, 29, 28, 27, 100, 99, 101, 102, nil, nil, + 19, nil, nil, nil, nil, nil, 8, 45, 290, 10, + 104, 103, 105, 94, 56, 96, 95, 97, nil, 98, + 106, 107, nil, 92, 93, 42, 43, 41, 237, -591, + -591, -591, -591, 243, 245, nil, nil, -591, -591, nil, + nil, nil, nil, nil, 251, 252, nil, 40, nil, nil, + 33, nil, nil, 58, 59, nil, nil, 60, nil, 35, + 234, nil, 240, 44, 236, 235, nil, 232, 233, 244, + 242, 238, 20, 239, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, 288, 74, 75, 71, 9, 57, 62, nil, + 83, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 30, 31, 72, 73, nil, nil, nil, nil, nil, + 29, 28, 27, 100, 99, 101, 102, nil, nil, 19, + nil, nil, nil, nil, nil, 8, 45, 290, 10, 104, + 103, 105, 94, 56, 96, 95, 97, nil, 98, 106, + 107, nil, 92, 93, 42, 43, 41, 237, -591, -591, + -591, -591, 243, 245, nil, nil, -591, -591, nil, nil, + nil, nil, nil, 251, 252, nil, 40, nil, nil, 33, + nil, nil, 58, 59, nil, nil, 60, nil, 35, 234, + nil, 240, 44, 236, 235, nil, 232, 233, 244, 242, + 238, 20, 239, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, 288, 74, 75, 71, 9, 57, 62, nil, 83, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 100, 99, 101, 102, nil, nil, 19, nil, + nil, nil, nil, nil, 8, 45, 290, 10, 104, 103, + 105, 94, 56, 96, 95, 97, nil, 98, 106, 107, + nil, 92, 93, 42, 43, 41, 237, 241, 246, 247, + 248, 243, 245, nil, nil, 249, 250, nil, nil, nil, + nil, nil, 251, 252, nil, 40, nil, nil, 33, nil, + nil, 58, 59, nil, nil, 60, nil, 35, 234, nil, + 240, 44, 236, 235, nil, 232, 233, 244, 242, 238, + 20, 239, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + 288, 74, 75, 71, 9, 57, 62, nil, 83, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 100, 99, 101, 102, nil, nil, 19, nil, nil, + nil, nil, nil, 8, 45, 290, 10, 104, 103, 105, + 94, 56, 96, 95, 97, nil, 98, 106, 107, nil, + 92, 93, 42, 43, 41, 237, 241, 246, 247, 248, + 243, 245, 253, nil, 249, 250, nil, nil, nil, nil, + nil, 251, 252, nil, 40, nil, nil, 33, nil, nil, + 58, 59, nil, nil, 60, nil, 35, 234, nil, 240, + 44, 236, 235, nil, 232, 233, 244, 242, 238, 20, + 239, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, 288, + 74, 75, 71, 9, 57, 62, nil, 83, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 100, 99, 101, 102, nil, nil, 19, nil, nil, nil, + nil, nil, 8, 45, 290, 10, 104, 103, 105, 94, + 56, 96, 95, 97, nil, 98, 106, 107, nil, 92, + 93, 42, 43, 41, 237, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 251, 252, nil, 40, nil, nil, 33, nil, nil, 58, + 59, nil, nil, 60, nil, 35, 234, nil, 240, 44, + 236, 235, nil, 232, 233, nil, nil, nil, 20, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, 288, 74, + 75, 71, 9, 57, 62, nil, 83, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 100, + 99, 101, 102, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 290, 10, 104, 103, 105, 94, 56, + 96, 95, 97, nil, 98, 106, 107, nil, 92, 93, + 42, 43, 41, 237, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 251, + 252, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 234, nil, 240, 44, 236, + 235, nil, 232, 233, nil, nil, nil, 20, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, 288, 74, 75, + 71, 9, 57, 62, nil, 83, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 100, 99, + 101, 102, nil, nil, 19, nil, nil, nil, nil, nil, + 8, 45, 290, 10, 104, 103, 105, 94, 56, 96, + 95, 97, nil, 98, 106, 107, nil, 92, 93, 42, + 43, 41, 237, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 251, 252, + nil, 40, nil, nil, 33, nil, nil, 58, 59, nil, + nil, 60, nil, 35, 234, nil, nil, 44, 236, 235, + nil, 232, 233, nil, nil, nil, 20, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, 288, 74, 75, 71, + 9, 57, 62, nil, 83, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 100, 99, 101, + 102, nil, nil, 19, nil, nil, nil, nil, nil, 8, + 45, 290, 10, 104, 103, 105, 94, 56, 96, 95, + 97, nil, 98, 106, 107, nil, 92, 93, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 40, nil, nil, 33, nil, nil, 58, 59, nil, nil, + 60, nil, 35, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, 288, 74, 75, 71, 9, + 57, 62, nil, 83, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 100, 99, 101, 102, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 290, 10, 104, 103, 105, 94, 56, 96, 95, 97, + nil, 98, 106, 107, nil, 92, 93, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 20, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, 288, 74, 75, 71, 9, 57, + 62, nil, 83, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 100, 99, 101, 102, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 290, + 10, 104, 103, 105, 94, 56, 96, 95, 97, nil, + 98, 106, 107, nil, 92, 93, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, 288, 74, 75, 71, 9, 57, 62, + nil, 83, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 30, 31, 72, 73, nil, nil, nil, nil, + nil, 29, 28, 27, 100, 99, 101, 102, nil, nil, + 19, nil, nil, nil, nil, nil, 8, 45, 290, 10, + 104, 103, 105, 94, 56, 96, 95, 97, nil, 98, + 106, 107, nil, 92, 93, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 40, nil, nil, + 33, nil, nil, 58, 59, nil, nil, 60, nil, 35, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, 288, 74, 75, 71, 9, 57, 62, nil, + 83, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 30, 31, 72, 73, nil, nil, nil, nil, nil, + 29, 28, 27, 100, 99, 101, 102, nil, nil, 19, + nil, nil, nil, nil, nil, 8, 45, 290, 10, 104, + 103, 105, 94, 56, 96, 95, 97, nil, 98, 106, + 107, nil, 92, 93, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 40, nil, nil, 33, + nil, nil, 58, 59, nil, nil, 60, nil, 35, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 20, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, 288, 74, 75, 71, 9, 57, 62, nil, 83, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 100, 99, 101, 102, nil, nil, 19, nil, + nil, nil, nil, nil, 8, 45, 290, 10, 104, 103, + 105, 94, 56, 96, 95, 97, nil, 98, 106, 107, + nil, 92, 93, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 40, nil, nil, 33, nil, + nil, 58, 59, nil, nil, 60, nil, 35, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 20, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + 288, 74, 75, 71, 9, 57, 62, nil, 83, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 100, 99, 101, 102, nil, nil, 19, nil, nil, + nil, nil, nil, 8, 45, 290, 10, 104, 103, 105, + 94, 56, 96, 95, 97, nil, 98, 106, 107, nil, + 92, 93, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 40, nil, nil, 33, nil, nil, + 58, 59, nil, nil, 60, nil, 35, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 20, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, 288, + 74, 75, 71, 9, 57, 62, nil, 83, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 100, 99, 101, 102, nil, nil, 19, nil, nil, nil, + nil, nil, 8, 45, 290, 10, 104, 103, 105, 94, + 56, 96, 95, 97, nil, 98, 106, 107, nil, 92, + 93, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 40, nil, nil, 33, nil, nil, 58, + 59, nil, nil, 60, nil, 35, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, 288, 74, + 75, 71, 9, 57, 62, nil, 83, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 100, + 99, 101, 102, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 290, 10, 104, 103, 105, 94, 56, + 96, 95, 97, nil, 98, 106, 107, nil, 92, 93, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, 288, 74, 75, + 71, 9, 57, 62, nil, 83, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 100, 99, + 101, 102, nil, nil, 19, nil, nil, nil, nil, nil, + 8, 45, 290, 10, 104, 103, 105, 94, 56, 96, + 95, 97, nil, 98, 106, 107, nil, 92, 93, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 40, nil, nil, 33, nil, nil, 58, 59, nil, + nil, 60, nil, 35, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 20, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, 288, 74, 75, 71, + 9, 57, 62, nil, 83, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 100, 99, 101, + 102, nil, nil, 19, nil, nil, nil, nil, nil, 8, + 45, 290, 10, 104, 103, 105, 94, 56, 96, 95, + 97, nil, 98, 106, 107, nil, 92, 93, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 40, nil, nil, 33, nil, nil, 58, 59, nil, nil, + 60, nil, 35, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, 288, 74, 75, 71, 9, + 57, 62, nil, 83, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 100, 99, 101, 102, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 290, 10, 104, 103, 105, 94, 56, 96, 95, 97, + nil, 98, 106, 107, nil, 92, 93, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 20, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, 288, 74, 75, 71, 9, 57, + 62, nil, 83, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 100, 99, 101, 102, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 290, + 10, 104, 103, 105, 94, 56, 96, 95, 97, nil, + 98, 106, 107, nil, 92, 93, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, 74, 75, 71, 9, 57, 62, + nil, 83, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 30, 31, 72, 73, nil, nil, nil, nil, + nil, 29, 28, 27, 100, 99, 101, 102, nil, nil, + 19, nil, nil, nil, nil, nil, 8, 45, 7, 10, + 104, 103, 105, 94, 56, 96, 95, 97, nil, 98, + 106, 107, nil, 92, 93, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 40, nil, nil, + 33, nil, nil, 58, 59, nil, nil, 60, nil, 35, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, 74, 75, 71, nil, 57, 62, nil, + 83, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 30, 31, 72, 73, nil, nil, nil, nil, nil, + 29, 28, 27, 100, 99, 101, 102, nil, nil, 229, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 104, + 103, 105, 94, 56, 96, 95, 97, nil, 98, 106, + 107, nil, 92, 93, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 222, nil, nil, 228, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, 74, 75, 71, nil, 57, 62, nil, 83, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 100, 99, 101, 102, nil, nil, 229, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 104, 103, + 105, 94, 56, 96, 95, 97, 282, 98, 106, 107, + nil, 92, 93, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 222, nil, nil, 228, nil, + nil, 58, 59, nil, nil, 60, nil, 280, nil, 278, + nil, 44, nil, nil, 283, nil, nil, nil, nil, nil, + 227, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, 74, 75, 71, nil, 57, 62, nil, 83, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 100, 99, 101, 102, nil, nil, 229, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 104, 103, 105, + 94, 56, 96, 95, 97, 282, 98, 106, 107, nil, + 92, 93, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 222, nil, nil, 228, nil, nil, + 58, 59, nil, nil, 60, nil, 280, nil, 278, nil, + 44, nil, nil, 283, nil, nil, nil, nil, nil, 227, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + 74, 75, 71, nil, 57, 62, nil, 83, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 100, 99, 101, 102, nil, nil, 229, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 104, 103, 105, 94, + 56, 96, 95, 97, 282, 98, 106, 107, nil, 92, + 93, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 222, nil, nil, 228, nil, nil, 58, + 59, nil, nil, 60, nil, 280, nil, 278, nil, 44, + nil, nil, 283, nil, nil, nil, nil, nil, 227, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, 74, + 75, 71, nil, 57, 62, nil, 83, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 307, 308, 72, + 73, nil, nil, nil, nil, nil, 303, 304, 310, 100, + 99, 101, 102, nil, nil, 229, nil, nil, nil, nil, + nil, nil, 305, nil, nil, 104, 103, 105, 94, 56, + 96, 95, 97, nil, 98, 106, 107, nil, 92, 93, + nil, nil, 311, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 301, nil, nil, 297, nil, nil, 58, 59, + nil, nil, 60, nil, 296, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 74, 75, + 71, nil, 57, 62, nil, 83, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 307, 308, 72, 73, + nil, nil, nil, nil, nil, 303, 304, 310, 100, 99, + 101, 102, nil, nil, 229, nil, nil, nil, nil, 602, + nil, 305, nil, nil, 104, 103, 105, 94, 56, 96, + 95, 97, nil, 98, 106, 107, nil, 92, 93, nil, + nil, 311, 237, 241, 246, 247, 248, 243, 245, 253, + 254, 249, 250, nil, 230, 231, nil, nil, 251, 252, + nil, 301, nil, nil, 228, nil, nil, 58, 59, nil, + nil, 60, nil, nil, 234, nil, 240, nil, 236, 235, + nil, 232, 233, 244, 242, 238, nil, 239, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, 255, nil, 313, + nil, nil, 62, nil, 83, 74, 75, 71, nil, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 307, 308, 72, 73, nil, nil, nil, + nil, nil, 303, 304, 310, 100, 99, 101, 102, nil, + nil, 229, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 104, 103, 105, 94, 56, 96, 95, 97, nil, + 98, 106, 107, nil, 92, 93, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 222, nil, + nil, 228, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, 74, 75, 71, nil, 57, 62, + nil, 83, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 307, 308, 72, 73, nil, nil, nil, nil, + nil, 303, 304, 310, 100, 99, 101, 102, nil, nil, + 229, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 104, 103, 105, 94, 56, 96, 95, 97, nil, 98, + 106, 107, nil, 92, 93, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 222, nil, nil, + 228, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, 74, 75, 71, nil, 57, 62, nil, + 83, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 307, 308, 72, 73, nil, nil, nil, nil, nil, + 303, 304, 310, 100, 99, 101, 102, nil, nil, 229, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 104, + 103, 105, 94, 56, 96, 95, 97, nil, 98, 106, + 107, nil, 92, 93, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 222, nil, nil, 228, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, 74, 75, 71, nil, 57, 62, nil, 83, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 307, 308, 72, 73, nil, nil, nil, nil, nil, 303, + 304, 310, 100, 99, 101, 102, nil, nil, 229, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 104, 103, + 105, 94, 56, 96, 95, 97, 282, 98, 106, 107, + nil, 92, 93, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 222, nil, nil, 228, nil, + nil, 58, 59, nil, nil, 60, nil, 280, nil, nil, + nil, 44, nil, nil, 283, nil, nil, nil, nil, nil, + 227, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, 74, 75, 71, nil, 57, 62, nil, 83, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 307, + 308, 72, 73, nil, nil, nil, nil, nil, 303, 304, + 310, 100, 99, 101, 102, nil, nil, 229, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 104, 103, 105, + 94, 56, 96, 95, 97, 282, 98, 106, 107, nil, + 92, 93, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 222, nil, nil, 228, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, 283, nil, nil, nil, nil, nil, 227, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + 74, 75, 71, nil, 57, 62, nil, 83, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 100, 99, 101, 102, nil, nil, 19, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 104, 103, 105, 94, + 56, 96, 95, 97, nil, 98, 106, 107, nil, 92, + 93, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 222, nil, nil, 228, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, 74, + 75, 71, nil, 57, 62, nil, 83, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 100, + 99, 101, 102, nil, nil, 19, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 104, 103, 105, 94, 56, + 96, 95, 97, nil, 98, 106, 107, nil, 92, 93, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 222, nil, nil, 228, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 74, 75, + 71, nil, 57, 62, nil, 83, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 100, 99, + 101, 102, nil, nil, 19, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 104, 103, 105, 94, 56, 96, + 95, 97, nil, 98, 106, 107, nil, 92, 93, 42, + 43, 41, 237, 241, 246, 247, 248, 243, 245, 253, + 254, 249, 250, nil, 230, 231, nil, nil, 251, 252, + nil, 222, nil, nil, 228, nil, nil, 58, 59, nil, + nil, 60, nil, nil, 234, nil, 240, 44, 236, 235, + nil, 232, 233, 244, 242, 238, 20, 239, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, 112, 255, nil, nil, + nil, 111, 62, nil, 83, 74, 75, 71, nil, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 307, 308, 72, 73, nil, nil, nil, + nil, nil, 303, 304, 310, 100, 99, 101, 102, nil, + nil, 229, nil, nil, nil, nil, nil, nil, 305, nil, + nil, 104, 103, 105, 94, 56, 96, 95, 97, nil, + 98, 106, 107, nil, 92, 93, nil, nil, 311, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 346, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, 74, 75, 71, nil, 57, 62, + nil, 83, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 307, 308, 72, 73, nil, nil, nil, nil, + nil, 303, 304, 310, 100, 99, 101, 102, nil, nil, + 229, nil, nil, nil, nil, nil, nil, 305, nil, nil, + 104, 103, 105, 351, 56, 96, 95, 352, nil, 98, + 106, 107, nil, 92, 93, nil, nil, 311, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 358, nil, nil, 353, nil, nil, + 228, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, 74, 75, 71, nil, 57, 62, nil, + 83, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 307, 308, 72, 73, nil, nil, nil, nil, nil, + 303, 304, 310, 100, 99, 101, 102, nil, nil, 229, + nil, nil, nil, nil, nil, nil, 305, nil, nil, 104, + 103, 105, 351, 56, 96, 95, 352, nil, 98, 106, + 107, nil, 92, 93, nil, nil, 311, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 353, nil, nil, 228, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, 74, 75, 71, 9, 57, 62, nil, 83, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 100, 99, 101, 102, nil, nil, 19, nil, + nil, nil, nil, nil, 8, 45, 7, 10, 104, 103, + 105, 94, 56, 96, 95, 97, nil, 98, 106, 107, + nil, 92, 93, 42, 43, 41, 237, 241, 246, 247, + 248, 243, 245, 253, 254, 249, 250, nil, 230, 231, + nil, nil, 251, 252, nil, 40, nil, nil, 33, nil, + nil, 58, 59, nil, nil, 60, nil, 35, 234, nil, + 240, 44, 236, 235, nil, 232, 233, 244, 242, 238, + 20, 239, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, 255, nil, nil, nil, 386, 62, nil, 83, 74, + 75, 71, nil, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 100, + 99, 101, 102, nil, nil, 19, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 104, 103, 105, 94, 56, + 96, 95, 97, nil, 98, 106, 107, nil, 92, 93, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 222, nil, nil, 228, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 74, 75, + 71, nil, 57, 62, nil, 83, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 100, 99, + 101, 102, nil, nil, 19, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 104, 103, 105, 94, 56, 96, + 95, 97, nil, 98, 106, 107, nil, 92, 93, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 222, nil, nil, 228, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 20, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, 74, 75, 71, + nil, 57, 62, nil, 83, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 100, 99, 101, + 102, nil, nil, 19, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 104, 103, 105, 94, 56, 96, 95, + 97, nil, 98, 106, 107, nil, 92, 93, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 222, nil, nil, 228, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, 74, 75, 71, nil, + 57, 62, nil, 83, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 100, 99, 101, 102, + nil, nil, 19, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 104, 103, 105, 94, 56, 96, 95, 97, + nil, 98, 106, 107, nil, 92, 93, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 222, + nil, nil, 228, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 20, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, 74, 75, 71, 9, 57, + 62, nil, 83, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 100, 99, 101, 102, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, nil, + 10, 104, 103, 105, 94, 56, 96, 95, 97, nil, + 98, 106, 107, nil, 92, 93, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, 74, 75, 71, nil, 57, 62, + nil, 83, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 30, 31, 72, 73, nil, nil, nil, nil, + nil, 29, 28, 27, 100, 99, 101, 102, nil, nil, + 229, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 104, 103, 105, 94, 56, 96, 95, 97, nil, 98, + 106, 107, nil, 92, 93, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 222, nil, nil, + 228, nil, nil, 58, 59, nil, nil, 60, nil, 402, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, 74, 75, 71, nil, 57, 62, nil, + 83, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 30, 31, 72, 73, nil, nil, nil, nil, nil, + 29, 28, 27, 100, 99, 101, 102, nil, nil, 229, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 104, + 103, 105, 94, 56, 96, 95, 97, nil, 98, 106, + 107, nil, 92, 93, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 222, nil, nil, 228, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, 74, 75, 71, nil, 57, 62, nil, 83, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 100, 99, 101, 102, nil, nil, 229, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 104, 103, + 105, 94, 56, 96, 95, 97, 282, 98, 106, 107, + nil, 92, 93, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 222, nil, nil, 228, nil, + nil, 58, 59, nil, nil, 60, nil, 280, nil, 278, + nil, 44, nil, nil, 283, nil, nil, nil, nil, nil, + 227, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, 74, 75, 71, nil, 57, 62, nil, 83, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 100, 99, 101, 102, nil, nil, 229, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 104, 103, 105, + 94, 56, 96, 95, 97, nil, 98, 106, 107, nil, + 92, 93, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 222, nil, nil, 228, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + 74, 75, 71, nil, 57, 62, nil, 83, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 100, 99, 101, 102, nil, nil, 229, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 104, 103, 105, 94, + 56, 96, 95, 97, nil, 98, 106, 107, nil, 92, + 93, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 222, nil, nil, 228, nil, nil, 58, + 59, nil, nil, 60, nil, 402, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, 74, + 75, 71, nil, 57, 62, nil, 83, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 100, + 99, 101, 102, nil, nil, 19, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 104, 103, 105, 94, 56, + 96, 95, 97, nil, 98, 106, 107, nil, 92, 93, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 222, nil, nil, 228, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 74, 75, + 71, nil, 57, 62, nil, 83, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 100, 99, + 101, 102, nil, nil, 19, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 104, 103, 105, 94, 56, 96, + 95, 97, nil, 98, 106, 107, nil, 92, 93, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 222, nil, nil, 228, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 20, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, 74, 75, 71, + nil, 57, 62, nil, 83, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 100, 99, 101, + 102, nil, nil, 19, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 104, 103, 105, 94, 56, 96, 95, + 97, nil, 98, 106, 107, nil, 92, 93, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 222, nil, nil, 228, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, 74, 75, 71, nil, + 57, 62, nil, 83, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 100, 99, 101, 102, + nil, nil, 19, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 104, 103, 105, 94, 56, 96, 95, 97, + nil, 98, 106, 107, nil, 92, 93, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 222, + nil, nil, 228, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 20, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, 217, 74, 75, 71, nil, 57, + 62, nil, 83, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 307, 308, 72, 73, nil, nil, nil, + nil, nil, 303, 304, 310, 100, 99, 101, 102, nil, + nil, 229, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 104, 103, 105, 94, 56, 96, 95, 97, nil, + 98, 106, 107, nil, 92, 93, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 222, nil, + nil, 228, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, 74, 75, 71, nil, 57, 62, + nil, 83, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 307, 308, 72, 73, nil, nil, nil, nil, + nil, 303, 304, 310, 100, 99, 101, 102, nil, nil, + 229, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 104, 103, 105, 94, 56, 96, 95, 97, nil, 98, + 106, 107, nil, 92, 93, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 222, nil, nil, + 228, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, 74, 75, 71, nil, 57, 62, nil, + 83, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 307, 308, 72, 73, nil, nil, nil, nil, nil, + 303, 304, 310, 100, 99, 101, 102, nil, nil, 229, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 104, + 103, 105, 94, 56, 96, 95, 97, nil, 98, 106, + 107, nil, 92, 93, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 222, nil, nil, 228, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, 74, 75, 71, nil, 57, 62, nil, 83, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 307, 308, 72, 73, nil, nil, nil, nil, nil, 303, + 304, 310, 100, 99, 101, 102, nil, nil, 229, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 104, 103, + 105, 94, 56, 96, 95, 97, nil, 98, 106, 107, + nil, 92, 93, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 222, nil, nil, 228, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, 74, 75, 71, nil, 57, 62, nil, 83, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 307, + 308, 72, 73, nil, nil, nil, nil, nil, 303, 304, + 310, 100, 99, 101, 102, nil, nil, 229, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 104, 103, 105, + 94, 56, 96, 95, 97, nil, 98, 106, 107, nil, + 92, 93, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 222, nil, nil, 228, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + 74, 75, 71, nil, 57, 62, nil, 83, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 307, 308, + 72, 73, nil, nil, nil, nil, nil, 303, 304, 310, + 100, 99, 101, 102, nil, nil, 229, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 104, 103, 105, 94, + 56, 96, 95, 97, nil, 98, 106, 107, nil, 92, + 93, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 222, nil, nil, 228, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, 74, + 75, 71, nil, 57, 62, nil, 83, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 307, 308, 72, + 73, nil, nil, nil, nil, nil, 303, 304, 310, 100, + 99, 101, 102, nil, nil, 229, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 104, 103, 105, 94, 56, + 96, 95, 97, nil, 98, 106, 107, nil, 92, 93, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 222, nil, nil, 228, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 74, 75, + 71, nil, 57, 62, nil, 83, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 307, 308, 72, 73, + nil, nil, nil, nil, nil, 303, 304, 310, 100, 99, + 101, 102, nil, nil, 229, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 104, 103, 105, 94, 56, 96, + 95, 97, nil, 98, 106, 107, nil, 92, 93, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 222, nil, nil, 228, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, 74, 75, 71, + nil, 57, 62, nil, 83, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 307, 308, 72, 73, nil, + nil, nil, nil, nil, 303, 304, 310, 100, 99, 101, + 102, nil, nil, 229, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 104, 103, 105, 94, 56, 96, 95, + 97, nil, 98, 106, 107, nil, 92, 93, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 222, nil, nil, 228, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, 74, 75, 71, nil, + 57, 62, nil, 83, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 307, 308, 72, 73, nil, nil, + nil, nil, nil, 303, 304, 310, 100, 99, 101, 102, + nil, nil, 229, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 104, 103, 105, 94, 56, 96, 95, 97, + nil, 98, 106, 107, nil, 92, 93, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 222, + nil, nil, 228, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, 74, 75, 71, nil, 57, + 62, nil, 83, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 307, 308, 72, 73, nil, nil, nil, + nil, nil, 303, 304, 310, 100, 99, 101, 102, nil, + nil, 229, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 104, 103, 105, 94, 56, 96, 95, 97, nil, + 98, 106, 107, nil, 92, 93, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 222, nil, + nil, 228, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, 74, 75, 71, nil, 57, 62, + nil, 83, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 307, 308, 72, 73, nil, nil, nil, nil, + nil, 303, 304, 310, 100, 99, 101, 102, nil, nil, + 229, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 104, 103, 105, 94, 56, 96, 95, 97, nil, 98, + 106, 107, nil, 92, 93, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 222, nil, nil, + 228, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, 74, 75, 71, nil, 57, 62, nil, + 83, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 307, 308, 72, 73, nil, nil, nil, nil, nil, + 303, 304, 310, 100, 99, 101, 102, nil, nil, 229, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 104, + 103, 105, 94, 56, 96, 95, 97, nil, 98, 106, + 107, nil, 92, 93, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 222, nil, nil, 228, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, 74, 75, 71, nil, 57, 62, nil, 83, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 307, 308, 72, 73, nil, nil, nil, nil, nil, 303, + 304, 310, 100, 99, 101, 102, nil, nil, 229, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 104, 103, + 105, 94, 56, 96, 95, 97, nil, 98, 106, 107, + nil, 92, 93, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 222, nil, nil, 228, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, 74, 75, 71, nil, 57, 62, nil, 83, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 307, + 308, 72, 73, nil, nil, nil, nil, nil, 303, 304, + 310, 100, 99, 101, 102, nil, nil, 229, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 104, 103, 105, + 94, 56, 96, 95, 97, nil, 98, 106, 107, nil, + 92, 93, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 222, nil, nil, 228, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + 74, 75, 71, nil, 57, 62, nil, 83, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 307, 308, + 72, 73, nil, nil, nil, nil, nil, 303, 304, 310, + 100, 99, 101, 102, nil, nil, 229, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 104, 103, 105, 94, + 56, 96, 95, 97, nil, 98, 106, 107, nil, 92, + 93, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 222, nil, nil, 228, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, 74, + 75, 71, nil, 57, 62, nil, 83, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 307, 308, 72, + 73, nil, nil, nil, nil, nil, 303, 304, 310, 100, + 99, 101, 102, nil, nil, 229, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 104, 103, 105, 94, 56, + 96, 95, 97, nil, 98, 106, 107, nil, 92, 93, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 222, nil, nil, 228, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 74, 75, + 71, nil, 57, 62, nil, 83, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 307, 308, 72, 73, + nil, nil, nil, nil, nil, 303, 304, 310, 100, 99, + 101, 102, nil, nil, 229, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 104, 103, 105, 94, 56, 96, + 95, 97, nil, 98, 106, 107, nil, 92, 93, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 222, nil, nil, 228, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, 74, 75, 71, + nil, 57, 62, nil, 83, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 307, 308, 72, 73, nil, + nil, nil, nil, nil, 303, 304, 310, 100, 99, 101, + 102, nil, nil, 229, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 104, 103, 105, 94, 56, 96, 95, + 97, nil, 98, 106, 107, nil, 92, 93, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 222, nil, nil, 228, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, 74, 75, 71, nil, + 57, 62, nil, 83, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 307, 308, 72, 73, nil, nil, + nil, nil, nil, 303, 304, 310, 100, 99, 101, 102, + nil, nil, 229, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 104, 103, 105, 94, 56, 96, 95, 97, + nil, 98, 106, 107, nil, 92, 93, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 222, + nil, nil, 228, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, 74, 75, 71, nil, 57, + 62, nil, 83, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 307, 308, 72, 73, nil, nil, nil, + nil, nil, 303, 304, 310, 100, 99, 101, 102, nil, + nil, 229, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 104, 103, 105, 94, 56, 96, 95, 97, nil, + 98, 106, 107, nil, 92, 93, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 222, nil, + nil, 228, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, 74, 75, 71, nil, 57, 62, + nil, 83, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 307, 308, 72, 73, nil, nil, nil, nil, + nil, 303, 304, 310, 100, 99, 101, 102, nil, nil, + 229, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 104, 103, 105, 94, 56, 96, 95, 97, nil, 98, + 106, 107, nil, 92, 93, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 222, nil, nil, + 228, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, 74, 75, 71, nil, 57, 62, nil, + 83, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 307, 308, 72, 73, nil, nil, nil, nil, nil, + 303, 304, 310, 100, 99, 101, 102, nil, nil, 229, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 104, + 103, 105, 94, 56, 96, 95, 97, nil, 98, 106, + 107, nil, 92, 93, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 222, nil, nil, 228, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, 74, 75, 71, nil, 57, 62, nil, 83, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 307, 308, 72, 73, nil, nil, nil, nil, nil, 303, + 304, 310, 100, 99, 101, 102, nil, nil, 229, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 104, 103, + 105, 94, 56, 96, 95, 97, nil, 98, 106, 107, + nil, 92, 93, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 222, nil, nil, 228, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, 74, 75, 71, nil, 57, 62, nil, 83, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 307, + 308, 72, 73, nil, nil, nil, nil, nil, 303, 304, + 310, 100, 99, 101, 102, nil, nil, 229, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 104, 103, 105, + 94, 56, 96, 95, 97, nil, 98, 106, 107, nil, + 92, 93, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 222, nil, nil, 228, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + 74, 75, 71, nil, 57, 62, nil, 83, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 307, 308, + 72, 73, nil, nil, nil, nil, nil, 303, 304, 310, + 100, 99, 101, 102, nil, nil, 229, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 104, 103, 105, 94, + 56, 96, 95, 97, nil, 98, 106, 107, nil, 92, + 93, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 222, nil, nil, 228, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, 74, + 75, 71, nil, 57, 62, nil, 83, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 307, 308, 72, + 73, nil, nil, nil, nil, nil, 303, 304, 310, 100, + 99, 101, 102, nil, nil, 229, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 104, 103, 105, 94, 56, + 96, 95, 97, nil, 98, 106, 107, nil, 92, 93, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 222, nil, nil, 228, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 74, 75, + 71, nil, 57, 62, nil, 83, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 100, 99, + 101, 102, nil, nil, 229, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 104, 103, 105, 94, 56, 96, + 95, 97, 282, 98, 106, 107, nil, 92, 93, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 222, nil, nil, 228, nil, nil, 58, 59, nil, + nil, 60, nil, 280, nil, 278, nil, 44, nil, nil, + 283, nil, nil, nil, nil, nil, 227, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, 74, 75, 71, + nil, 57, 62, nil, 83, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 100, 99, 101, + 102, nil, nil, 229, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 104, 103, 105, 94, 56, 96, 95, + 97, 282, 98, 106, 107, nil, 92, 93, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 222, nil, nil, 228, nil, nil, 58, 59, nil, nil, + 60, nil, 280, nil, 278, nil, 44, nil, nil, 283, + nil, nil, nil, nil, nil, 227, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, 74, 75, 71, nil, + 57, 62, nil, 83, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 100, 99, 101, 102, + nil, nil, 229, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 104, 103, 105, 94, 56, 96, 95, 97, + 282, 98, 106, 107, nil, 92, 93, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 222, + nil, nil, 228, nil, nil, 58, 59, nil, nil, 60, + nil, 280, nil, 278, nil, 44, nil, nil, 283, nil, + nil, nil, nil, nil, 227, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, 217, 74, 75, 71, nil, 57, + 62, nil, 83, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 307, 308, 72, 73, nil, nil, nil, + nil, nil, 303, 304, 310, 100, 99, 101, 102, nil, + nil, 229, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 104, 103, 105, 94, 56, 96, 95, 97, nil, + 98, 106, 107, nil, 92, 93, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 222, nil, + nil, 228, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, 74, 75, 71, nil, 57, 62, + nil, 83, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 307, 308, 72, 73, nil, nil, nil, nil, + nil, 303, 304, 310, 100, 99, 101, 102, nil, nil, + 229, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 104, 103, 105, 94, 56, 96, 95, 97, nil, 98, + 106, 107, nil, 92, 93, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 222, nil, nil, + 228, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, 74, 75, 71, nil, 57, 62, nil, + 83, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 307, 308, 72, 73, nil, nil, nil, nil, nil, + 303, 304, 310, 100, 99, 101, 102, nil, nil, 229, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 104, + 103, 105, 94, 56, 96, 95, 97, nil, 98, 106, + 107, nil, 92, 93, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 222, nil, nil, 228, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, 74, 75, 71, nil, 57, 62, nil, 83, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 307, 308, 72, 73, nil, nil, nil, nil, nil, 303, + 304, 310, 100, 99, 101, 102, nil, nil, 229, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 104, 103, + 105, 94, 56, 96, 95, 97, nil, 98, 106, 107, + nil, 92, 93, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 222, nil, nil, 228, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, 74, 75, 71, 9, 57, 62, nil, 83, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 100, 99, 101, 102, nil, nil, 19, nil, nil, + nil, nil, nil, 8, 45, nil, 10, 104, 103, 105, + 94, 56, 96, 95, 97, nil, 98, 106, 107, nil, + 92, 93, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 40, nil, nil, 33, nil, nil, + 58, 59, nil, nil, 60, nil, 35, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 20, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + 74, 75, 71, nil, 57, 62, nil, 83, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 307, 308, + 72, 73, nil, nil, nil, nil, nil, 303, 304, 310, + 100, 99, 101, 102, nil, nil, 229, nil, nil, nil, + nil, nil, nil, 305, nil, nil, 104, 103, 105, 94, + 56, 96, 95, 97, nil, 98, 106, 107, nil, 92, + 93, nil, nil, 311, 237, 241, 246, 247, 248, 243, + 245, 253, 254, 249, 250, nil, 230, 231, nil, nil, + 251, 252, nil, 301, nil, nil, 228, nil, nil, 58, + 59, nil, nil, 60, nil, nil, 234, nil, 240, nil, + 236, 235, nil, 232, 233, 244, 242, 238, nil, 239, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, 255, + nil, 500, nil, nil, 62, nil, 83, 74, 75, 71, + nil, 57, nil, nil, nil, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 307, 308, 72, 73, nil, + nil, nil, nil, nil, 303, 304, 310, 100, 99, 101, + 102, nil, nil, 229, nil, nil, nil, nil, nil, nil, + 305, nil, nil, 104, 103, 105, 94, 56, 96, 95, + 97, nil, 98, 106, 107, nil, 92, 93, nil, nil, + 311, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 301, nil, nil, 297, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, 74, 75, 71, nil, + 57, 62, nil, 83, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 307, 308, 72, 73, nil, nil, + nil, nil, nil, 303, 304, 310, 100, 99, 101, 102, + nil, nil, 229, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 104, 103, 105, 94, 56, 96, 95, 97, + nil, 98, 106, 107, nil, 92, 93, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 222, + nil, nil, 228, 518, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, 74, 75, 71, nil, 57, + 62, nil, 83, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 100, 99, 101, 102, nil, + nil, 19, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 104, 103, 105, 94, 56, 96, 95, 97, nil, + 98, 106, 107, nil, 92, 93, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 222, nil, + nil, 228, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, 74, 75, 71, nil, 57, 62, + nil, 83, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 30, 31, 72, 73, nil, nil, nil, nil, + nil, 29, 28, 27, 100, 99, 101, 102, nil, nil, + 19, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 104, 103, 105, 94, 56, 96, 95, 97, nil, 98, + 106, 107, nil, 92, 93, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 222, nil, nil, + 228, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, 74, 75, 71, nil, 57, 62, nil, + 83, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 30, 31, 72, 73, nil, nil, nil, nil, nil, + 29, 28, 27, 100, 99, 101, 102, nil, nil, 19, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 104, + 103, 105, 94, 56, 96, 95, 97, nil, 98, 106, + 107, nil, 92, 93, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 222, nil, nil, 228, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 20, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, 74, 75, 71, nil, 57, 62, nil, 83, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 100, 99, 101, 102, nil, nil, 19, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 104, 103, + 105, 94, 56, 96, 95, 97, nil, 98, 106, 107, + nil, 92, 93, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 222, nil, nil, 228, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 20, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, 74, 75, 71, nil, 57, 62, nil, 83, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 100, 99, 101, 102, nil, nil, 19, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 104, 103, 105, + 94, 56, 96, 95, 97, nil, 98, 106, 107, nil, + 92, 93, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 222, nil, nil, 228, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 20, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + 74, 75, 71, nil, 57, 62, nil, 83, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 307, 308, + 72, 73, nil, nil, nil, nil, nil, 303, 304, 310, + 100, 99, 101, 102, nil, nil, 229, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 104, 103, 105, 94, + 56, 96, 95, 97, nil, 98, 106, 107, nil, 92, + 93, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 222, nil, nil, 228, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, 74, + 75, 71, nil, 57, 62, nil, 83, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 100, + 99, 101, 102, nil, nil, 229, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 104, 103, 105, 94, 56, + 96, 95, 97, 282, 98, 106, 107, nil, 92, 93, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 222, nil, nil, 228, nil, nil, 58, 59, + nil, nil, 60, nil, 280, nil, 278, nil, 44, nil, + nil, 283, nil, nil, nil, nil, nil, 227, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 74, 75, + 71, nil, 57, 62, nil, 83, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 307, 308, 72, 73, + nil, nil, nil, nil, nil, 303, 304, 310, 100, 99, + 101, 102, nil, nil, 229, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 104, 103, 105, 94, 56, 96, + 95, 97, nil, 98, 106, 107, nil, 92, 93, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 222, nil, nil, 228, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, 74, 75, 71, + nil, 57, 62, nil, 83, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 307, 308, 72, 73, nil, + nil, nil, nil, nil, 303, 304, 310, 100, 99, 101, + 102, nil, nil, 229, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 104, 103, 105, 94, 56, 96, 95, + 97, nil, 98, 106, 107, nil, 92, 93, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 222, nil, nil, 228, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, 74, 75, 71, nil, + 57, 62, nil, 83, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 307, 308, 72, 73, nil, nil, + nil, nil, nil, 303, 304, 310, 100, 99, 101, 102, + nil, nil, 229, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 104, 103, 105, 94, 56, 96, 95, 97, + nil, 98, 106, 107, nil, 92, 93, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 222, + nil, nil, 228, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, 74, 75, 71, nil, 57, + 62, nil, 83, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 307, 308, 72, 73, nil, nil, nil, + nil, nil, 303, 304, 310, 100, 99, 101, 102, nil, + nil, 229, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 104, 103, 105, 94, 56, 96, 95, 97, 282, + 98, 106, 107, nil, 92, 93, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 222, nil, + nil, 228, nil, nil, 58, 59, nil, nil, 60, nil, + 626, nil, 278, nil, 44, nil, nil, 283, nil, nil, + nil, nil, nil, 227, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, 74, 75, 71, nil, 57, 62, + nil, 83, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 307, 308, 72, 73, nil, nil, nil, nil, + nil, 303, 304, 310, 100, 99, 101, 102, nil, nil, + 229, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 104, 103, 105, 94, 56, 96, 95, 97, 282, 98, + 106, 107, nil, 92, 93, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 222, nil, nil, + 228, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, 278, nil, 44, nil, nil, 283, nil, nil, nil, + nil, nil, 227, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, 74, 75, 71, nil, 57, 62, nil, + 83, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 307, 308, 72, 73, nil, nil, nil, nil, nil, + 303, 304, 310, 100, 99, 101, 102, nil, nil, 229, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 104, + 103, 105, 94, 56, 96, 95, 97, nil, 98, 106, + 107, nil, 92, 93, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 222, nil, nil, 228, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, 74, 75, 71, 9, 57, 62, nil, 83, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 100, 99, 101, 102, nil, nil, 19, nil, + nil, nil, nil, nil, 8, 45, 290, 10, 104, 103, + 105, 94, 56, 96, 95, 97, nil, 98, 106, 107, + nil, 92, 93, 42, 43, 41, 237, 241, 246, 247, + 248, 243, 245, 253, 254, 249, 250, nil, 230, 231, + nil, nil, 251, 252, nil, 40, nil, nil, 33, nil, + nil, 58, 59, nil, nil, 60, nil, 35, 234, nil, + 240, 44, 236, 235, nil, 232, 233, 244, 242, 238, + 20, 239, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + 217, 255, nil, nil, nil, 386, 62, nil, 83, 74, + 75, 71, nil, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 307, 308, 72, + 73, nil, nil, nil, nil, nil, 303, 304, 310, 100, + 99, 101, 102, nil, nil, 229, nil, nil, nil, nil, + nil, nil, 305, nil, nil, 104, 103, 105, 94, 56, + 96, 95, 97, nil, 98, 106, 107, nil, 92, 93, + nil, nil, 311, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 301, nil, nil, 297, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 74, 75, + 71, nil, 57, 62, nil, 83, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 100, 99, + 101, 102, nil, nil, 229, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 104, 103, 105, 94, 56, 96, + 95, 97, 282, 98, 106, 107, nil, 92, 93, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 222, nil, nil, 228, nil, nil, 58, 59, nil, + nil, 60, nil, 280, nil, 278, nil, 44, nil, nil, + 283, nil, nil, nil, nil, nil, 227, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, 74, 75, 71, + nil, 57, 62, nil, 83, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 307, 308, 72, 73, nil, + nil, nil, nil, nil, 303, 304, 310, 100, 99, 101, + 102, nil, nil, 229, nil, nil, nil, nil, nil, nil, + 305, nil, nil, 104, 103, 105, 94, 56, 96, 95, + 97, nil, 98, 106, 107, nil, 92, 93, nil, nil, + 311, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 301, nil, nil, 297, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, 74, 75, 71, nil, + 57, 62, nil, 83, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 307, 308, 72, 73, nil, nil, + nil, nil, nil, 303, 304, 310, 100, 99, 101, 102, + nil, nil, 229, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 104, 103, 105, 94, 56, 96, 95, 97, + nil, 98, 106, 107, nil, 92, 93, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 222, + nil, nil, 228, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, 74, 75, 71, nil, 57, + 62, nil, 83, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 307, 308, 72, 73, nil, nil, nil, + nil, nil, 303, 304, 310, 100, 99, 101, 102, nil, + nil, 229, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 104, 103, 105, 94, 56, 96, 95, 97, nil, + 98, 106, 107, nil, 92, 93, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 222, nil, + nil, 228, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, 74, 75, 71, nil, 57, 62, + nil, 83, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 307, 308, 72, 73, nil, nil, nil, nil, + nil, 303, 304, 310, 100, 99, 101, 102, nil, nil, + 229, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 104, 103, 105, 94, 56, 96, 95, 97, nil, 98, + 106, 107, nil, 92, 93, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 222, nil, nil, + 228, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, 74, 75, 71, nil, 57, 62, nil, + 83, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 30, 31, 72, 73, nil, nil, nil, nil, nil, + 29, 28, 27, 100, 99, 101, 102, nil, nil, 19, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 104, + 103, 105, 94, 56, 96, 95, 97, nil, 98, 106, + 107, nil, 92, 93, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 222, nil, nil, 228, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 20, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, 74, 75, 71, nil, 57, 62, nil, 83, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 307, 308, 72, 73, nil, nil, nil, nil, nil, 303, + 304, 310, 100, 99, 101, 102, nil, nil, 229, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 104, 103, + 105, 94, 56, 96, 95, 97, 282, 98, 106, 107, + nil, 92, 93, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 222, nil, nil, 228, nil, + nil, 58, 59, nil, nil, 60, nil, 626, nil, nil, + nil, 44, nil, nil, 283, nil, nil, nil, nil, nil, + 227, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, 74, 75, 71, nil, 57, 62, nil, 83, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 307, + 308, 72, 73, nil, nil, nil, nil, nil, 303, 304, + 310, 100, 99, 101, 102, nil, nil, 229, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 104, 103, 105, + 94, 56, 96, 95, 97, 282, 98, 106, 107, nil, + 92, 93, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 222, nil, nil, 228, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, 283, nil, nil, nil, nil, nil, 227, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + 74, 75, 71, nil, 57, 62, nil, 83, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 307, 308, + 72, 73, nil, nil, nil, nil, nil, 303, 304, 310, + 100, 99, 101, 102, nil, nil, 229, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 104, 103, 105, 94, + 56, 96, 95, 97, nil, 98, 106, 107, nil, 92, + 93, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 222, nil, nil, 228, nil, nil, 58, + 59, nil, nil, 60, nil, 280, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, 74, + 75, 71, nil, 57, 62, nil, 83, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 100, + 99, 101, 102, nil, nil, 229, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 104, 103, 105, 94, 56, + 96, 95, 97, 282, 98, 106, 107, nil, 92, 93, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 222, nil, nil, 228, nil, nil, 58, 59, + nil, nil, 60, nil, 280, nil, 278, nil, 44, nil, + nil, 283, nil, nil, nil, nil, nil, 227, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 74, 75, + 71, nil, 57, 62, nil, 83, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 100, 99, + 101, 102, nil, nil, 229, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 104, 103, 105, 94, 56, 96, + 95, 97, 282, 98, 106, 107, nil, 92, 93, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 222, nil, nil, 228, nil, nil, 58, 59, nil, + nil, 60, nil, 280, nil, 278, nil, 44, nil, nil, + 283, nil, nil, nil, nil, nil, 227, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, 74, 75, 71, + nil, 57, 62, nil, 83, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 307, 308, 72, 73, nil, + nil, nil, nil, nil, 303, 304, 310, 100, 99, 101, + 102, nil, nil, 229, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 104, 103, 105, 94, 56, 96, 95, + 97, nil, 98, 106, 107, nil, 92, 93, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 222, nil, nil, 228, nil, nil, 58, 59, nil, nil, + 60, nil, 729, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, 74, 75, 71, nil, + 57, 62, nil, 83, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 307, 308, 72, 73, nil, nil, + nil, nil, nil, 303, 304, 310, 100, 99, 101, 102, + nil, nil, 229, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 104, 103, 105, 94, 56, 96, 95, 97, + nil, 98, 106, 107, nil, 92, 93, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 222, + nil, nil, 228, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, 74, 75, 71, nil, 57, + 62, nil, 83, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 307, 308, 72, 73, nil, nil, nil, + nil, nil, 303, 304, 310, 100, 99, 101, 102, nil, + nil, 229, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 104, 103, 105, 94, 56, 96, 95, 97, 282, + 98, 106, 107, nil, 92, 93, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 222, nil, + nil, 228, nil, nil, 58, 59, nil, nil, 60, nil, + 626, nil, 278, nil, 44, nil, nil, 283, nil, nil, + nil, nil, nil, 227, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, 74, 75, 71, nil, 57, 62, + nil, 83, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 307, 308, 72, 73, nil, nil, nil, nil, + nil, 303, 304, 310, 100, 99, 101, 102, nil, nil, + 229, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 104, 103, 105, 94, 56, 96, 95, 97, 282, 98, + 106, 107, nil, 92, 93, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 222, nil, nil, + 228, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, 278, nil, 44, nil, nil, 283, nil, nil, nil, + nil, nil, 227, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, 74, 75, 71, nil, 57, 62, nil, + 83, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 30, 31, 72, 73, nil, nil, nil, nil, nil, + 29, 28, 27, 100, 99, 101, 102, nil, nil, 229, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 104, + 103, 105, 94, 56, 96, 95, 97, nil, 98, 106, + 107, nil, 92, 93, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 222, nil, nil, 228, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, 74, 75, 71, nil, 57, 62, nil, 83, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 100, 99, 101, 102, nil, nil, 229, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 104, 103, + 105, 94, 56, 96, 95, 97, nil, 98, 106, 107, + nil, 92, 93, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 222, nil, nil, 228, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, 74, 75, 71, nil, 57, 62, nil, 83, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 100, 99, 101, 102, nil, nil, 229, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 104, 103, 105, + 94, 56, 96, 95, 97, nil, 98, 106, 107, nil, + 92, 93, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 222, nil, nil, 228, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + 74, 75, 71, nil, 57, 62, nil, 83, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 100, 99, 101, 102, nil, nil, 229, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 104, 103, 105, 94, + 56, 96, 95, 97, nil, 98, 106, 107, nil, 92, + 93, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 222, nil, nil, 228, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, 74, + 75, 71, nil, 57, 62, nil, 83, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 100, + 99, 101, 102, nil, nil, 229, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 104, 103, 105, 94, 56, + 96, 95, 97, nil, 98, 106, 107, nil, 92, 93, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 222, nil, nil, 228, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 74, 75, + 71, nil, 57, 62, nil, 83, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 307, 308, 72, 73, + nil, nil, nil, nil, nil, 303, 304, 310, 100, 99, + 101, 102, nil, nil, 229, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 104, 103, 105, 94, 56, 96, + 95, 97, nil, 98, 106, 107, nil, 92, 93, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 222, nil, nil, 228, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, 74, 75, 71, + nil, 57, 62, nil, 83, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 307, 308, 72, 73, nil, + nil, nil, nil, nil, 303, 304, 310, 100, 99, 101, + 102, nil, nil, 229, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 104, 103, 105, 94, 56, 96, 95, + 97, nil, 98, 106, 107, nil, 92, 93, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 222, nil, nil, 228, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, 74, 75, 71, nil, + 57, 62, nil, 83, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 307, 308, 72, 73, nil, nil, + nil, nil, nil, 303, 304, 310, 100, 99, 101, 102, + nil, nil, 229, nil, nil, nil, nil, nil, nil, 305, + nil, nil, 104, 103, 105, 94, 56, 96, 95, 97, + nil, 98, 106, 107, nil, 92, 93, nil, nil, 311, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 301, + nil, nil, 297, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, 74, 75, 71, nil, 57, + 62, nil, 83, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 307, 308, 72, 73, nil, nil, nil, + nil, nil, 303, 304, 310, 100, 99, 101, 102, nil, + nil, 229, nil, nil, nil, nil, nil, nil, 305, nil, + nil, 104, 103, 105, 94, 56, 96, 95, 97, nil, + 98, 106, 107, nil, 92, 93, nil, nil, 311, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 301, nil, + nil, 297, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, 74, 75, 71, nil, 57, 62, + nil, 83, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 307, 308, 72, 73, nil, nil, nil, nil, + nil, 303, 304, 310, 100, 99, 101, 102, nil, nil, + 229, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 104, 103, 105, 94, 56, 96, 95, 97, nil, 98, + 106, 107, nil, 92, 93, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 222, nil, nil, + 228, nil, nil, 58, 59, nil, nil, 60, nil, 402, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, 74, 75, 71, nil, 57, 62, nil, + 83, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 307, 308, 72, 73, nil, nil, nil, nil, nil, + 303, 304, 310, 100, 99, 101, 102, nil, nil, 229, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 104, + 103, 105, 94, 56, 96, 95, 97, nil, 98, 106, + 107, nil, 92, 93, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 222, nil, nil, 228, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, 74, 75, 71, nil, 57, 62, nil, 83, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 100, 99, 101, 102, nil, nil, 19, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 104, 103, + 105, 94, 56, 96, 95, 97, nil, 98, 106, 107, + nil, 92, 93, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 222, nil, nil, 228, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 20, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, 74, 75, 71, nil, 57, 62, nil, 83, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 100, 99, 101, 102, nil, nil, 19, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 104, 103, 105, + 94, 56, 96, 95, 97, nil, 98, 106, 107, nil, + 92, 93, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 222, nil, nil, 228, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 20, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + 74, 75, 71, nil, 57, 62, nil, 83, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 307, 308, + 72, 73, nil, nil, nil, nil, nil, 303, 304, 310, + 100, 99, 101, 102, nil, nil, 229, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 104, 103, 105, 94, + 56, 96, 95, 97, nil, 98, 106, 107, nil, 92, + 93, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 222, nil, nil, 228, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, 74, + 75, 71, nil, 57, 62, nil, 83, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 100, + 99, 101, 102, nil, nil, 229, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 104, 103, 105, 94, 56, + 96, 95, 97, nil, 98, 106, 107, nil, 92, 93, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 222, nil, nil, 228, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 74, 75, + 71, nil, 57, 62, nil, 83, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 307, 308, 72, 73, + nil, nil, nil, nil, nil, 303, 304, 310, 100, 99, + 101, 102, nil, nil, 229, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 104, 103, 105, 94, 56, 96, + 95, 97, nil, 98, 106, 107, nil, 92, 93, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 222, nil, nil, 228, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, 74, 75, 71, + nil, 57, 62, nil, 83, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 307, 308, 72, 73, nil, + nil, nil, nil, nil, 303, 304, 310, 100, 99, 101, + 102, nil, nil, 229, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 104, 103, 105, 94, 56, 96, 95, + 97, nil, 98, 106, 107, nil, 92, 93, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 222, nil, nil, 228, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, 74, 75, 71, nil, + 57, 62, nil, 83, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 307, 308, 72, 73, nil, nil, + nil, nil, nil, 303, 304, 310, 100, 99, 101, 102, + nil, nil, 229, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 104, 103, 105, 94, 56, 96, 95, 97, + nil, 98, 106, 107, nil, 92, 93, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 222, + nil, nil, 228, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, 74, 75, 71, nil, 57, + 62, nil, 83, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 307, 308, 72, 73, nil, nil, nil, + nil, nil, 303, 304, 310, 100, 99, 101, 102, nil, + nil, 229, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 104, 103, 105, 94, 56, 96, 95, 97, nil, + 98, 106, 107, nil, 92, 93, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 222, nil, + nil, 228, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, 74, 75, 71, nil, 57, 62, + nil, 83, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 307, 308, 72, 73, nil, nil, nil, nil, + nil, 303, 304, 310, 100, 99, 101, 102, nil, nil, + 229, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 104, 103, 105, 94, 56, 96, 95, 97, nil, 98, + 106, 107, nil, 92, 93, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 222, nil, nil, + 228, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, 74, 75, 71, nil, 57, 62, nil, + 83, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 307, 308, 72, 73, nil, nil, nil, nil, nil, + 303, 304, 310, 100, 99, 101, 102, nil, nil, 229, + nil, nil, nil, nil, nil, nil, 305, nil, nil, 104, + 103, 105, 94, 56, 96, 95, 97, nil, 98, 106, + 107, nil, 92, 93, nil, nil, 311, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 854, nil, nil, 228, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, 74, 75, 71, nil, 57, 62, nil, 83, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 307, 308, 72, 73, nil, nil, nil, nil, nil, 303, + 304, 310, 100, 99, 101, 102, nil, nil, 229, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 104, 103, + 105, 94, 56, 96, 95, 97, nil, 98, 106, 107, + nil, 92, 93, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 222, nil, nil, 228, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, 74, 75, 71, nil, 57, 62, nil, 83, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 100, 99, 101, 102, nil, nil, 19, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 104, 103, 105, + 94, 56, 96, 95, 97, nil, 98, 106, 107, nil, + 92, 93, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 222, nil, nil, 228, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 20, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + 74, 75, 71, nil, 57, 62, nil, 83, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 307, 308, + 72, 73, nil, nil, nil, nil, nil, 303, 304, 310, + 100, 99, 101, 102, nil, nil, 229, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 104, 103, 105, 94, + 56, 96, 95, 97, nil, 98, 106, 107, nil, 92, + 93, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 222, nil, nil, 228, nil, nil, 58, + 59, nil, nil, 60, nil, 626, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, 74, + 75, 71, nil, 57, 62, nil, 83, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 307, 308, 72, + 73, nil, nil, nil, nil, nil, 303, 304, 310, 100, + 99, 101, 102, nil, nil, 229, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 104, 103, 105, 94, 56, + 96, 95, 97, 282, 98, 106, 107, nil, 92, 93, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 222, nil, nil, 228, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, 278, nil, 44, nil, + nil, 283, nil, nil, nil, nil, nil, 227, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 74, 75, + 71, nil, 57, 62, nil, 83, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 307, 308, 72, 73, + nil, nil, nil, nil, nil, 303, 304, 310, 100, 99, + 101, 102, nil, nil, 229, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 104, 103, 105, 94, 56, 96, + 95, 97, nil, 98, 106, 107, nil, 92, 93, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 222, nil, nil, 228, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, 74, 75, 71, + nil, 57, 62, nil, 83, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 307, 308, 72, 73, nil, + nil, nil, nil, nil, 303, 304, 310, 100, 99, 101, + 102, nil, nil, 229, nil, nil, nil, nil, nil, nil, + 305, nil, nil, 104, 103, 105, 94, 56, 96, 95, + 97, nil, 98, 106, 107, nil, 92, 93, nil, nil, + 311, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 854, nil, nil, 228, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, 74, 75, 71, nil, + 57, 62, nil, 83, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 307, 308, 72, 73, nil, nil, + nil, nil, nil, 303, 304, 310, 100, 99, 101, 102, + nil, nil, 229, nil, nil, nil, nil, nil, nil, 305, + nil, nil, 104, 103, 105, 94, 56, 96, 95, 97, + nil, 98, 106, 107, nil, 92, 93, nil, nil, 311, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 925, + nil, nil, 228, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, 74, 75, 71, nil, 57, + 62, nil, 83, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 100, 99, 101, 102, nil, + nil, 229, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 104, 103, 105, 94, 56, 96, 95, 97, 282, + 98, 106, 107, nil, 92, 93, 42, 43, 41, 237, + 241, 246, 247, 248, 243, 245, 253, 254, 249, 250, + nil, 230, 231, nil, nil, 251, 252, nil, 222, nil, + nil, 228, nil, nil, 58, 59, nil, nil, 60, nil, + 280, 234, 278, 240, 44, 236, 235, 283, 232, 233, + 244, 242, 238, 227, 239, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, 255, -413, nil, nil, nil, 62, + nil, 83, -413, -413, -413, nil, nil, -413, -413, -413, + nil, -413, nil, nil, nil, nil, nil, nil, nil, nil, + -413, -413, -413, nil, nil, nil, nil, nil, nil, nil, + nil, -413, -413, nil, -413, -413, -413, -413, -413, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, -413, -413, -413, -413, -413, -413, -413, -413, -413, + -413, -413, -413, -413, -413, nil, nil, -413, -413, -413, + nil, nil, -413, nil, 262, -413, nil, nil, -413, -413, + nil, -413, nil, -413, nil, -413, nil, -413, -413, nil, + -413, -413, -413, -413, -413, -296, -413, -413, -413, nil, + nil, nil, -296, -296, -296, nil, nil, -296, -296, -296, + nil, -296, -413, nil, nil, -413, -413, nil, -413, nil, + -413, -296, -296, nil, nil, nil, nil, nil, nil, nil, + nil, -296, -296, nil, -296, -296, -296, -296, -296, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, -296, -296, -296, -296, -296, -296, -296, -296, -296, + -296, -296, -296, -296, -296, nil, nil, -296, -296, -296, + nil, nil, -296, nil, 271, -296, nil, nil, -296, -296, + nil, -296, nil, -296, nil, -296, nil, -296, -296, nil, + -296, -296, -296, -296, -296, nil, -296, -246, -296, nil, + nil, nil, nil, nil, -246, -246, -246, nil, nil, -246, + -246, -246, -296, -246, nil, -296, -296, nil, -296, nil, + -296, nil, -246, -246, -246, nil, nil, nil, nil, nil, + nil, nil, nil, -246, -246, nil, -246, -246, -246, -246, + -246, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, -246, -246, -246, -246, -246, -246, -246, + -246, -246, -246, -246, -246, -246, -246, nil, nil, -246, + -246, -246, nil, nil, -246, nil, 262, -246, nil, nil, + -246, -246, nil, -246, nil, -246, nil, -246, nil, -246, + -246, nil, -246, -246, -246, -246, -246, nil, -246, -246, + -246, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, -246, nil, -246, -246, -246, nil, + -246, nil, -246, -246, -246, -246, nil, nil, -246, -246, + -246, 761, -246, 666, 665, 664, 762, 667, nil, nil, + nil, -246, -246, nil, nil, nil, 675, nil, nil, nil, + nil, nil, -246, -246, nil, -246, -246, -246, -246, -246, + nil, nil, nil, nil, nil, nil, nil, nil, 671, nil, + 669, nil, 666, 665, 664, 673, 667, 680, 679, 683, + 682, nil, nil, nil, 676, 675, nil, nil, nil, nil, + nil, nil, nil, -246, nil, nil, nil, nil, nil, nil, + -246, nil, nil, nil, nil, 262, -246, 671, 655, nil, + 217, nil, nil, nil, nil, nil, 680, 679, 683, 682, + nil, nil, nil, 676, nil, nil, nil, nil, -246, -246, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, -246, nil, nil, -246, nil, nil, nil, + nil, -246, 172, 183, 173, 196, 169, 189, 179, 178, + 199, 200, 194, 177, 176, 171, 197, 201, 202, 181, + 170, 184, 188, 190, 182, 175, nil, nil, nil, 191, + 198, 193, 192, 185, 195, 180, 168, 187, 186, nil, + nil, nil, nil, nil, 167, 174, 165, 166, 162, 163, + 164, 123, 125, 122, nil, 124, nil, nil, nil, nil, + nil, nil, nil, 156, 157, nil, 153, 135, 136, 137, + 144, 141, 143, nil, nil, 138, 139, nil, nil, nil, + 158, 159, 145, 146, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 150, 149, nil, + 134, 155, 152, 151, 160, 147, 148, 142, 140, 132, + 154, 133, nil, nil, 161, 91, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 90, + 172, 183, 173, 196, 169, 189, 179, 178, 199, 200, + 194, 177, 176, 171, 197, 201, 202, 181, 170, 184, + 188, 190, 182, 175, nil, nil, nil, 191, 198, 193, + 192, 185, 195, 180, 168, 187, 186, nil, nil, nil, + nil, nil, 167, 174, 165, 166, 162, 163, 164, 123, + 125, nil, nil, 124, nil, nil, nil, nil, nil, nil, + nil, 156, 157, nil, 153, 135, 136, 137, 144, 141, + 143, nil, nil, 138, 139, nil, nil, nil, 158, 159, + 145, 146, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 150, 149, nil, 134, 155, + 152, 151, 160, 147, 148, 142, 140, 132, 154, 133, + nil, nil, 161, 91, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 90, 172, 183, + 173, 196, 169, 189, 179, 178, 199, 200, 194, 177, + 176, 171, 197, 201, 202, 181, 170, 184, 188, 190, + 182, 175, nil, nil, nil, 191, 198, 193, 192, 185, + 195, 180, 168, 187, 186, nil, nil, nil, nil, nil, + 167, 174, 165, 166, 162, 163, 164, 123, 125, nil, + nil, 124, nil, nil, nil, nil, nil, nil, nil, 156, + 157, nil, 153, 135, 136, 137, 144, 141, 143, nil, + nil, 138, 139, nil, nil, nil, 158, 159, 145, 146, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 150, 149, nil, 134, 155, 152, 151, + 160, 147, 148, 142, 140, 132, 154, 133, nil, nil, + 161, 91, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 90, 172, 183, 173, 196, + 169, 189, 179, 178, 199, 200, 194, 177, 176, 171, + 197, 201, 202, 181, 170, 184, 188, 190, 182, 175, + nil, nil, nil, 191, 198, 193, 192, 185, 195, 180, + 168, 187, 186, nil, nil, nil, nil, nil, 167, 174, + 165, 166, 162, 163, 164, 123, 125, nil, nil, 124, + nil, nil, nil, nil, nil, nil, nil, 156, 157, nil, + 153, 135, 136, 137, 144, 141, 143, nil, nil, 138, + 139, nil, nil, nil, 158, 159, 145, 146, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 150, 149, nil, 134, 155, 152, 151, 160, 147, + 148, 142, 140, 132, 154, 133, nil, nil, 161, 91, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 90, 172, 183, 173, 196, 169, 189, + 179, 178, 199, 200, 194, 177, 176, 171, 197, 201, + 202, 181, 170, 184, 188, 190, 182, 175, nil, nil, + nil, 191, 198, 193, 369, 368, 370, 367, 168, 187, + 186, nil, nil, nil, nil, nil, 167, 174, 165, 166, + 364, 365, 366, 362, 125, 96, 95, 363, nil, 98, + nil, nil, nil, nil, nil, 156, 157, nil, 153, 135, + 136, 137, 144, 141, 143, nil, nil, 138, 139, nil, + nil, nil, 158, 159, 145, 146, nil, nil, nil, nil, + nil, 374, nil, nil, nil, nil, nil, nil, nil, 150, + 149, nil, 134, 155, 152, 151, 160, 147, 148, 142, + 140, 132, 154, 133, nil, nil, 161, 172, 183, 173, + 196, 169, 189, 179, 178, 199, 200, 194, 177, 176, + 171, 197, 201, 202, 181, 170, 184, 188, 190, 182, + 175, nil, nil, nil, 191, 198, 193, 192, 185, 195, + 180, 168, 187, 186, nil, nil, nil, nil, nil, 167, + 174, 165, 166, 162, 163, 164, 123, 125, nil, nil, + 124, nil, nil, nil, nil, nil, nil, nil, 156, 157, + nil, 153, 135, 136, 137, 144, 141, 143, nil, nil, + 138, 139, nil, nil, nil, 158, 159, 145, 146, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 150, 149, nil, 134, 155, 152, 151, 160, + 147, 148, 142, 140, 132, 154, 133, nil, nil, 161, + 237, 241, 246, 247, 248, 243, 245, 253, 254, 249, + 250, nil, 230, 231, nil, nil, 251, 252, nil, nil, + nil, nil, nil, 669, nil, 666, 665, 664, 673, 667, + nil, nil, 234, nil, 240, nil, 236, 235, 675, 232, + 233, 244, 242, 238, nil, 239, 237, 241, 246, 247, + 248, 243, 245, 253, 254, 249, 250, nil, 230, 231, + 671, 711, 251, 252, nil, 255, nil, nil, nil, 680, + 679, 683, 682, nil, nil, nil, 676, nil, 234, nil, + 240, nil, 236, 235, nil, 232, 233, 244, 242, 238, + nil, 239, 237, 241, 246, 247, 248, 243, 245, 253, + 254, 249, 250, nil, 230, 231, nil, nil, 251, 252, + nil, 255, 669, nil, 666, 665, 664, 673, 667, nil, + nil, nil, nil, nil, 234, nil, 240, 675, 236, 235, + nil, 232, 233, 244, 242, 238, nil, 239, 237, 241, + 246, 247, 248, 243, 245, 253, 254, 249, 250, 671, + 230, 231, nil, nil, 251, 252, nil, 255, 680, 679, + 683, 682, nil, nil, nil, 676, nil, nil, nil, nil, + 234, nil, 240, nil, 236, 235, nil, 232, 233, 244, + 242, 238, nil, 239, 237, 241, 246, 247, 248, 243, + 245, 253, 254, 249, 250, nil, 230, 231, nil, nil, + 251, 252, nil, 255, 669, nil, 666, 665, 664, 673, + 667, nil, nil, nil, nil, nil, 234, nil, 240, 675, + 236, 235, nil, 232, 233, 244, 242, 238, nil, 239, + 237, 241, 246, 247, 248, 243, 245, 253, 254, 249, + 250, 671, 230, 231, nil, nil, 251, 252, nil, 255, + 680, 679, 683, 682, nil, nil, nil, 676, nil, nil, + nil, nil, 234, nil, 240, nil, 236, 235, nil, 232, + 233, 244, 242, 238, nil, 239, 237, 241, 246, 247, + 248, 243, 245, 253, 254, 249, 250, nil, 230, 231, + nil, nil, 251, 252, nil, 255, 669, nil, 666, 665, + 664, 673, 667, nil, nil, nil, nil, nil, 234, nil, + 240, 675, 236, 235, nil, 232, 233, 244, 242, 238, + nil, 239, 237, 241, 246, 247, 248, 243, 245, 253, + 254, 249, 250, 671, 230, 231, nil, nil, 251, 252, + nil, 255, 680, 679, 683, 682, nil, nil, nil, 676, + nil, nil, nil, nil, 234, nil, 240, nil, 236, 235, + nil, 232, 233, 244, 242, 238, nil, 239, 237, 241, + 246, 247, 248, 243, 245, 253, 254, 249, 250, nil, + 230, 231, nil, nil, 251, 252, nil, 255, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 234, nil, 240, nil, 236, 235, nil, 232, 233, 244, + 242, 238, nil, 239, nil, nil, nil, nil, nil, 410, + 414, nil, nil, 411, nil, nil, nil, nil, nil, nil, + nil, 156, 157, 255, 153, 135, 136, 137, 144, 141, + 143, nil, nil, 138, 139, nil, nil, nil, 158, 159, + 145, 146, nil, nil, nil, nil, nil, 262, nil, nil, + nil, nil, nil, nil, nil, 150, 149, nil, 134, 155, + 152, 151, 160, 147, 148, 142, 140, 132, 154, 133, + 417, 421, 161, nil, 416, nil, nil, nil, nil, nil, + nil, nil, 156, 157, nil, 153, 135, 136, 137, 144, + 141, 143, nil, nil, 138, 139, nil, nil, nil, 158, + 159, 145, 146, nil, nil, nil, nil, nil, 262, nil, + nil, nil, nil, nil, nil, nil, 150, 149, nil, 134, + 155, 152, 151, 160, 147, 148, 142, 140, 132, 154, + 133, 472, 414, 161, nil, 473, nil, nil, nil, nil, + nil, nil, nil, 156, 157, nil, 153, 135, 136, 137, + 144, 141, 143, nil, nil, 138, 139, nil, nil, nil, + 158, 159, 145, 146, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 150, 149, nil, + 134, 155, 152, 151, 160, 147, 148, 142, 140, 132, + 154, 133, 605, 414, 161, nil, 606, nil, nil, nil, + nil, nil, nil, nil, 156, 157, nil, 153, 135, 136, + 137, 144, 141, 143, nil, nil, 138, 139, nil, nil, + nil, 158, 159, 145, 146, nil, nil, nil, nil, nil, + 262, nil, nil, nil, nil, nil, nil, nil, 150, 149, + nil, 134, 155, 152, 151, 160, 147, 148, 142, 140, + 132, 154, 133, 607, 421, 161, nil, 608, nil, nil, + nil, nil, nil, nil, nil, 156, 157, nil, 153, 135, + 136, 137, 144, 141, 143, nil, nil, 138, 139, nil, + nil, nil, 158, 159, 145, 146, nil, nil, nil, nil, + nil, 262, nil, nil, nil, nil, nil, nil, nil, 150, + 149, nil, 134, 155, 152, 151, 160, 147, 148, 142, + 140, 132, 154, 133, 636, 414, 161, nil, 637, nil, + nil, nil, nil, nil, nil, nil, 156, 157, nil, 153, + 135, 136, 137, 144, 141, 143, nil, nil, 138, 139, + nil, nil, nil, 158, 159, 145, 146, nil, nil, nil, + nil, nil, 262, nil, nil, nil, nil, nil, nil, nil, + 150, 149, nil, 134, 155, 152, 151, 160, 147, 148, + 142, 140, 132, 154, 133, 639, 421, 161, nil, 640, + nil, nil, nil, nil, nil, nil, nil, 156, 157, nil, + 153, 135, 136, 137, 144, 141, 143, nil, nil, 138, + 139, nil, nil, nil, 158, 159, 145, 146, nil, nil, + nil, nil, nil, 262, nil, nil, nil, nil, nil, nil, + nil, 150, 149, nil, 134, 155, 152, 151, 160, 147, + 148, 142, 140, 132, 154, 133, 605, 414, 161, nil, + 606, nil, nil, nil, nil, nil, nil, nil, 156, 157, + nil, 153, 135, 136, 137, 144, 141, 143, nil, nil, + 138, 139, nil, nil, nil, 158, 159, 145, 146, nil, + nil, nil, nil, nil, 262, nil, nil, nil, nil, nil, + nil, nil, 150, 149, nil, 134, 155, 152, 151, 160, + 147, 148, 142, 140, 132, 154, 133, 607, 421, 161, + nil, 608, nil, nil, nil, nil, nil, nil, nil, 156, + 157, nil, 153, 135, 136, 137, 144, 141, 143, nil, + nil, 138, 139, nil, nil, nil, 158, 159, 145, 146, + nil, nil, nil, nil, nil, 262, nil, nil, nil, nil, + nil, nil, nil, 150, 149, nil, 134, 155, 152, 151, + 160, 147, 148, 142, 140, 132, 154, 133, 696, 414, + 161, nil, 697, nil, nil, nil, nil, nil, nil, nil, + 156, 157, nil, 153, 135, 136, 137, 144, 141, 143, + nil, nil, 138, 139, nil, nil, nil, 158, 159, 145, + 146, nil, nil, nil, nil, nil, 262, nil, nil, nil, + nil, nil, nil, nil, 150, 149, nil, 134, 155, 152, + 151, 160, 147, 148, 142, 140, 132, 154, 133, 698, + 421, 161, nil, 699, nil, nil, nil, nil, nil, nil, + nil, 156, 157, nil, 153, 135, 136, 137, 144, 141, + 143, nil, nil, 138, 139, nil, nil, nil, 158, 159, + 145, 146, nil, nil, nil, nil, nil, 262, nil, nil, + nil, nil, nil, nil, nil, 150, 149, nil, 134, 155, + 152, 151, 160, 147, 148, 142, 140, 132, 154, 133, + 701, 421, 161, nil, 702, nil, nil, nil, nil, nil, + nil, nil, 156, 157, nil, 153, 135, 136, 137, 144, + 141, 143, nil, nil, 138, 139, nil, nil, nil, 158, + 159, 145, 146, nil, nil, nil, nil, nil, 262, nil, + nil, nil, nil, nil, nil, nil, 150, 149, nil, 134, + 155, 152, 151, 160, 147, 148, 142, 140, 132, 154, + 133, 472, 414, 161, nil, 473, nil, nil, nil, nil, + nil, nil, nil, 156, 157, nil, 153, 135, 136, 137, + 144, 141, 143, nil, nil, 138, 139, nil, nil, nil, + 158, 159, 145, 146, nil, nil, nil, nil, nil, 262, + nil, nil, nil, nil, nil, nil, nil, 150, 149, nil, + 134, 155, 152, 151, 160, 147, 148, 142, 140, 132, + 154, 133, 968, 421, 161, nil, 967, nil, nil, nil, + nil, nil, nil, nil, 156, 157, nil, 153, 135, 136, + 137, 144, 141, 143, nil, nil, 138, 139, nil, nil, + nil, 158, 159, 145, 146, nil, nil, nil, nil, nil, + 262, nil, nil, nil, nil, nil, nil, nil, 150, 149, + nil, 134, 155, 152, 151, 160, 147, 148, 142, 140, + 132, 154, 133, 994, 414, 161, nil, 995, nil, nil, + nil, nil, nil, nil, nil, 156, 157, nil, 153, 135, + 136, 137, 144, 141, 143, nil, nil, 138, 139, nil, + nil, nil, 158, 159, 145, 146, nil, nil, nil, nil, + nil, 262, nil, nil, nil, nil, nil, nil, nil, 150, + 149, nil, 134, 155, 152, 151, 160, 147, 148, 142, + 140, 132, 154, 133, 996, 421, 161, nil, 997, nil, + nil, nil, nil, nil, nil, nil, 156, 157, nil, 153, + 135, 136, 137, 144, 141, 143, nil, nil, 138, 139, + nil, nil, nil, 158, 159, 145, 146, nil, nil, nil, + nil, nil, 262, nil, nil, nil, nil, nil, nil, nil, + 150, 149, nil, 134, 155, 152, 151, 160, 147, 148, + 142, 140, 132, 154, 133, nil, 669, 161, 666, 665, + 664, 673, 667, 807, nil, 666, 665, 664, 673, 667, + nil, 675, nil, nil, nil, nil, nil, 761, 675, 666, + 665, 664, 762, 667, nil, nil, nil, nil, nil, nil, + nil, nil, 675, 671, nil, nil, nil, nil, nil, nil, + 671, nil, 680, 679, 683, 682, nil, nil, nil, 676, + nil, 683, 682, nil, 671, nil, 676, nil, nil, nil, + nil, nil, nil, 680, 679, 683, 682, nil, nil, 761, + 676, 666, 665, 664, 762, 667, 807, nil, 666, 665, + 664, 762, 667, nil, 675, nil, nil, nil, nil, nil, + 669, 675, 666, 665, 664, 673, 667, nil, nil, nil, + nil, nil, nil, nil, nil, 675, 671, nil, nil, nil, + nil, nil, nil, 671, nil, 680, 679, 683, 682, nil, + nil, nil, 676, nil, 683, 682, nil, 671, 711, 676, + nil, nil, nil, nil, nil, nil, 680, 679, 683, 682, + nil, nil, 669, 676, 666, 665, 664, 673, 667, 807, + nil, 666, 665, 664, 673, 667, 807, 675, 666, 665, + 664, 673, 667, 807, 675, 666, 665, 664, 673, 667, + nil, 675, nil, nil, nil, nil, nil, nil, 675, 671, + nil, nil, nil, nil, nil, nil, 671, nil, 680, 679, + 683, 682, nil, 671, nil, 676, nil, 683, 682, nil, + 671, nil, 676, nil, 683, 682, nil, nil, nil, 676, + nil, 683, 682, nil, nil, 761, 676, 666, 665, 664, + 762, 667, 807, nil, 666, 665, 664, 762, 667, 807, + 675, 666, 665, 664, 762, 667, 807, 675, 666, 665, + 664, 762, 667, 807, 675, 666, 665, 664, 673, 667, + nil, 675, 671, nil, nil, nil, nil, nil, 675, 671, + nil, 680, 679, 683, 682, nil, 671, nil, 676, nil, + 683, 682, nil, 671, nil, 676, nil, 683, 682, nil, + 671, nil, 676, nil, 683, 682, nil, nil, nil, 676, + nil, 683, 682, nil, nil, 807, 676, 666, 665, 664, + 762, 667, nil, nil, nil, nil, nil, nil, nil, nil, + 675, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 671, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 683, 682, nil, nil, nil, 676 ] + +racc_action_check = [ + 94, 0, 0, 0, 0, 0, 0, 94, 94, 94, + 0, 0, 94, 94, 94, 0, 94, 0, 0, 0, + 0, 0, 0, 0, 94, 61, 94, 94, 94, 0, + 0, 0, 0, 0, 0, 0, 94, 94, 0, 94, + 94, 94, 94, 94, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 343, 0, 0, 0, + 357, 0, 0, 0, 0, 0, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, + 26, 344, 94, 94, 94, 0, 94, 94, 0, 347, + 94, 0, 0, 94, 94, 0, 94, 0, 94, 617, + 94, 0, 94, 94, 306, 94, 94, 94, 94, 94, + 0, 94, 61, 94, 19, 0, 0, 0, 0, 381, + 0, 0, 0, 0, 545, 1, 654, 94, 0, 0, + 94, 94, 94, 94, 97, 94, 0, 94, 0, 94, + 696, 97, 97, 97, 26, 336, 97, 97, 97, 382, + 97, 7, 337, 697, 3, 19, 694, 58, 97, 3, + 97, 97, 97, 822, 470, 343, 357, 26, 306, 220, + 97, 97, 863, 97, 97, 97, 97, 97, 888, 994, + 995, 1013, 996, 698, 537, 381, 617, 286, 24, 357, + 344, 306, 286, 221, 357, 24, 10, 58, 347, 470, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 12, 382, 97, 97, 97, 362, + 97, 97, 220, 636, 97, 223, 362, 97, 97, 440, + 97, 538, 97, 545, 97, 654, 97, 97, 605, 97, + 97, 97, 97, 97, 416, 97, 221, 97, 698, 696, + 823, 416, 416, 416, 434, 434, 606, 416, 416, 996, + 416, 97, 697, 336, 97, 97, 97, 97, 336, 97, + 337, 97, 822, 97, 694, 337, 699, 694, 223, 694, + 416, 416, 440, 416, 416, 416, 416, 416, 537, 636, + 863, 605, 698, 537, 637, 863, 888, 994, 995, 1013, + 996, 888, 994, 995, 1013, 996, 13, 557, 557, 606, + 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, 416, 416, 561, 561, 416, 416, 416, 636, + 416, 16, 636, 15, 416, 538, 749, 416, 636, 631, + 538, 699, 416, 478, 416, 631, 416, 416, 434, 416, + 416, 416, 416, 416, 823, 416, 417, 416, 22, 823, + 637, 647, 647, 417, 417, 417, 38, 479, 39, 417, + 417, 416, 417, 327, 416, 416, 327, 416, 478, 416, + 15, 417, 618, 416, 351, 699, 15, 363, 328, 749, + 37, 328, 417, 417, 363, 417, 417, 417, 417, 417, + 637, 557, 479, 637, 315, 893, 557, 893, 806, 637, + 806, 806, 806, 38, 806, 39, 376, 618, 561, 38, + 352, 39, 417, 417, 417, 417, 417, 417, 417, 417, + 417, 417, 417, 417, 417, 417, 351, 14, 417, 417, + 417, 572, 417, 351, 14, 40, 417, 45, 351, 417, + 639, 315, 351, 14, 417, 647, 417, 315, 417, 417, + 108, 417, 417, 417, 417, 417, 574, 417, 417, 417, + 410, 351, 352, 340, 331, 17, 17, 331, 340, 352, + 376, 376, 376, 417, 352, 607, 417, 417, 352, 417, + 806, 417, 607, 607, 607, 417, 364, 607, 607, 607, + 353, 607, 639, 364, 353, 572, 572, 352, 203, 639, + 607, 607, 607, 607, 639, 572, 653, 410, 639, 653, + 222, 607, 607, 410, 607, 607, 607, 607, 607, 224, + 574, 574, 943, 411, 943, 943, 943, 639, 943, 377, + 574, 365, 366, 701, 378, 556, 41, 41, 365, 366, + 556, 607, 607, 607, 607, 607, 607, 607, 607, 607, + 607, 607, 607, 607, 607, 311, 311, 607, 607, 607, + 367, 607, 607, 379, 225, 607, 588, 367, 607, 607, + 411, 607, 775, 607, 712, 607, 411, 607, 607, 712, + 607, 607, 607, 607, 607, 701, 607, 607, 607, 380, + 335, 335, 701, 377, 377, 377, 383, 701, 378, 378, + 378, 701, 607, 229, 943, 607, 607, 607, 607, 608, + 607, 261, 607, 588, 607, 275, 608, 608, 608, 588, + 701, 608, 608, 608, 775, 608, 46, 379, 379, 379, + 276, 775, 368, 46, 369, 608, 608, 608, 122, 368, + 775, 369, 46, 122, 122, 608, 608, 279, 608, 608, + 608, 608, 608, 380, 380, 380, 219, 290, 298, 775, + 383, 383, 383, 219, 671, 298, 671, 671, 671, 291, + 671, 293, 219, 294, 298, 608, 608, 608, 608, 608, + 608, 608, 608, 608, 608, 608, 608, 608, 608, 465, + 791, 608, 608, 608, 295, 608, 608, 370, 301, 608, + 791, 671, 608, 608, 370, 608, 304, 608, 305, 608, + 671, 608, 608, 840, 608, 608, 608, 608, 608, 310, + 608, 465, 608, 840, 372, 465, 465, 826, 465, 465, + 312, 372, 826, 791, 791, 316, 608, 317, 791, 608, + 608, 608, 608, 320, 608, 325, 608, 329, 608, 33, + 33, 33, 33, 33, 33, 330, 840, 840, 33, 33, + 332, 840, 79, 33, 341, 33, 33, 33, 33, 33, + 33, 33, 912, 342, 79, 912, 346, 33, 33, 33, + 33, 33, 33, 33, 79, 348, 33, 521, 521, 685, + 685, 429, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 392, 33, 33, 33, 398, 33, + 33, 33, 33, 33, 429, 429, 429, 429, 429, 429, + 429, 429, 429, 429, 429, 299, 429, 429, 300, 400, + 429, 429, 299, 33, 403, 300, 33, 794, 794, 33, + 33, 299, 406, 33, 300, 33, 429, 408, 429, 33, + 429, 429, 409, 429, 429, 429, 429, 429, 33, 429, + 984, 984, 418, 33, 33, 33, 33, 302, 33, 33, + 33, 33, 426, 466, 302, 318, 33, 33, 436, 429, + 56, 429, 318, 302, 33, 448, 33, 56, 56, 56, + 449, 318, 56, 56, 56, 803, 56, 803, 803, 803, + 450, 803, 451, 476, 480, 466, 56, 56, 56, 466, + 466, 345, 466, 466, 495, 496, 56, 56, 345, 56, + 56, 56, 56, 56, 499, 501, 506, 345, 510, 446, + 519, 883, 803, 883, 883, 883, 520, 883, 565, 565, + 522, 803, 565, 565, 565, 534, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 447, 446, 56, 56, 56, 446, 446, 56, 883, 539, + 56, 540, 569, 56, 56, 577, 56, 883, 56, 579, + 56, 585, 56, 56, 589, 56, 56, 56, 56, 56, + 594, 56, 447, 56, 599, 609, 447, 447, 355, 611, + 851, 616, 851, 851, 851, 355, 851, 56, 623, 505, + 56, 56, 56, 56, 355, 56, 505, 56, 120, 120, + 120, 120, 120, 120, 625, 505, 548, 120, 120, 630, + 633, 635, 120, 548, 120, 120, 120, 120, 120, 120, + 120, 638, 548, 641, 642, 645, 120, 120, 120, 120, + 120, 120, 120, 646, 966, 120, 966, 966, 966, 648, + 966, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 651, 120, 120, 120, 657, 120, 120, + 120, 120, 120, 444, 444, 444, 444, 444, 444, 444, + 444, 444, 444, 444, 640, 444, 444, 853, 658, 444, + 444, 640, 120, 660, 853, 120, 640, 661, 120, 120, + 640, 662, 120, 853, 120, 444, 669, 444, 120, 444, + 444, 677, 444, 444, 444, 444, 444, 120, 444, 681, + 684, 687, 120, 120, 120, 120, 692, 120, 120, 120, + 120, 695, 704, 709, 728, 120, 120, 205, 205, 205, + 205, 205, 205, 120, 733, 120, 205, 205, 751, 752, + 754, 205, 755, 205, 205, 205, 205, 205, 205, 205, + 6, 6, 6, 6, 6, 205, 205, 205, 205, 205, + 205, 205, 756, 758, 205, 289, 289, 289, 289, 289, + 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, + 205, 205, 759, 205, 205, 205, 760, 205, 205, 205, + 205, 205, 445, 445, 445, 445, 445, 445, 445, 445, + 445, 445, 445, 702, 445, 445, 916, 761, 445, 445, + 702, 205, 765, 916, 205, 702, 769, 205, 205, 702, + 770, 205, 916, 205, 445, 774, 445, 205, 445, 445, + 778, 445, 445, 445, 445, 445, 205, 445, 781, 782, + 785, 205, 205, 205, 205, 790, 205, 205, 205, 205, + 805, 808, 813, 816, 205, 205, 228, 228, 228, 228, + 228, 228, 205, 825, 205, 228, 228, 829, 830, 833, + 228, 834, 228, 228, 228, 228, 228, 228, 228, 493, + 493, 493, 493, 493, 228, 228, 228, 228, 228, 228, + 228, 850, 885, 228, 885, 885, 885, 854, 885, 228, + 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, + 228, 856, 228, 228, 228, 869, 228, 228, 228, 228, + 228, 455, 455, 455, 455, 455, 455, 455, 922, 885, + 455, 455, 923, 870, 874, 922, 875, 455, 455, 923, + 228, 877, 878, 228, 922, 880, 228, 228, 923, 882, + 228, 884, 228, 455, 890, 455, 228, 455, 455, 891, + 455, 455, 455, 455, 455, 228, 455, 897, 902, 905, + 228, 228, 228, 228, 906, 228, 228, 228, 228, 907, + 908, 910, 925, 228, 228, 292, 292, 292, 292, 292, + 292, 228, 928, 228, 292, 292, 929, 945, 967, 292, + 968, 292, 292, 292, 292, 292, 292, 292, 969, 976, + 977, 978, 979, 292, 292, 292, 292, 292, 292, 292, + 980, 944, 292, 944, 944, 944, 982, 944, 292, 292, + 292, 292, 292, 292, 292, 292, 292, 292, 292, 292, + 985, 292, 292, 292, 986, 292, 292, 292, 292, 292, + 456, 981, 987, 981, 981, 981, 988, 981, 944, 983, + 989, 983, 983, 983, 924, 983, 456, 456, 990, 292, + 993, 924, 292, 1004, 1014, 292, 292, 1015, 1016, 292, + 924, 292, 456, nil, 456, 292, 456, 456, 981, 456, + 456, nil, nil, 456, 292, 456, 983, nil, nil, 292, + 292, 292, 292, nil, 292, 292, 292, 292, nil, nil, + nil, nil, 292, 292, 297, 297, 297, 297, 297, 297, + 292, nil, 292, 297, 297, nil, nil, nil, 297, nil, + 297, 297, 297, 297, 297, 297, 297, nil, nil, nil, + nil, nil, 297, 297, 297, 297, 297, 297, 297, nil, + 1003, 297, 1003, 1003, 1003, nil, 1003, 297, 297, 297, + 297, 297, 297, 297, 297, 297, 297, 297, 297, nil, + 297, 297, 297, 926, 297, 297, 297, 297, 297, 457, + 926, 973, nil, nil, nil, nil, nil, 1003, 973, 926, + nil, nil, nil, nil, nil, 457, 457, 973, 297, nil, + nil, 297, nil, nil, 297, 297, nil, nil, 297, nil, + 297, 457, nil, 457, 297, 457, 457, nil, 457, 457, + nil, nil, 457, 297, 457, nil, nil, nil, 297, 297, + 297, 297, nil, 297, 297, 297, 297, nil, nil, nil, + nil, 297, 297, 323, 323, 323, 323, 323, 323, 297, + nil, 297, 323, 323, nil, nil, nil, 323, nil, 323, + 323, 323, 323, 323, 323, 323, nil, nil, nil, nil, + nil, 323, 323, 323, 323, 323, 323, 323, nil, nil, + 323, nil, nil, nil, nil, 405, 323, 323, 323, 323, + 323, 323, 323, 323, 323, 323, 323, 323, nil, 323, + 323, 323, nil, 323, 323, 323, 323, 323, 405, 405, + 405, 405, 405, 405, 405, 405, 405, 405, 405, 997, + 405, 405, nil, nil, 405, 405, 997, 323, nil, nil, + 323, 997, nil, 323, 323, 997, nil, 323, nil, 323, + 405, nil, 405, 323, 405, 405, nil, 405, 405, 405, + 405, 405, 323, 405, nil, nil, nil, 323, 323, 323, + 323, nil, 323, 323, 323, 323, nil, nil, nil, nil, + 323, 323, nil, 405, 421, nil, nil, nil, 323, nil, + 323, 421, 421, 421, nil, nil, 421, 421, 421, 458, + 421, nil, nil, nil, nil, nil, nil, nil, nil, 421, + 421, 421, 421, nil, nil, 458, 458, nil, nil, nil, + 421, 421, nil, 421, 421, 421, 421, 421, nil, nil, + nil, 458, nil, 458, nil, 458, 458, nil, 458, 458, + nil, nil, 458, nil, 458, nil, nil, nil, nil, nil, + 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, nil, nil, 421, 421, 421, nil, + nil, 421, nil, nil, 421, nil, nil, 421, 421, nil, + 421, nil, 421, nil, 421, nil, 421, 421, nil, 421, + 421, 421, 421, 421, nil, 421, 421, 421, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 421, nil, nil, 421, 421, 421, 421, 422, 421, + nil, 421, nil, nil, nil, 422, 422, 422, nil, nil, + 422, 422, 422, 459, 422, nil, nil, nil, nil, nil, + nil, nil, nil, 422, 422, 422, 422, nil, nil, 459, + 459, nil, nil, nil, 422, 422, nil, 422, 422, 422, + 422, 422, nil, nil, nil, 459, nil, 459, nil, 459, + 459, nil, 459, 459, nil, nil, 459, nil, 459, nil, + nil, nil, nil, nil, 422, 422, 422, 422, 422, 422, + 422, 422, 422, 422, 422, 422, 422, 422, nil, nil, + 422, 422, 422, nil, nil, 422, nil, nil, 422, nil, + nil, 422, 422, nil, 422, nil, 422, nil, 422, nil, + 422, 422, nil, 422, 422, 422, 422, 422, nil, 422, + 422, 422, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 422, nil, nil, 422, 422, + 422, 422, nil, 422, nil, 422, 494, 494, 494, 494, + 494, 494, nil, nil, nil, 494, 494, nil, nil, nil, + 494, nil, 494, 494, 494, 494, 494, 494, 494, nil, + nil, nil, nil, nil, 494, 494, 494, 494, 494, 494, + 494, nil, nil, 494, nil, nil, nil, nil, nil, 494, + 494, 494, 494, 494, 494, 494, 494, 494, 494, 494, + 494, nil, 494, 494, 494, nil, 494, 494, 494, 494, + 494, 460, 460, 460, 460, 460, 460, 460, nil, nil, + 460, 460, nil, nil, nil, nil, nil, 460, 460, nil, + 494, nil, nil, 494, nil, nil, 494, 494, nil, nil, + 494, nil, 494, 460, nil, 460, 494, 460, 460, nil, + 460, 460, 460, 460, 460, 494, 460, nil, nil, nil, + 494, 494, 494, 494, nil, 494, 494, 494, 494, nil, + nil, nil, nil, 494, 494, 533, 533, 533, 533, 533, + 533, 494, nil, 494, 533, 533, nil, nil, nil, 533, + nil, 533, 533, 533, 533, 533, 533, 533, nil, nil, + nil, nil, nil, 533, 533, 533, 533, 533, 533, 533, + nil, nil, 533, nil, nil, nil, nil, nil, 533, 533, + 533, 533, 533, 533, 533, 533, 533, 533, 533, 533, + nil, 533, 533, 533, nil, 533, 533, 533, 533, 533, + 461, 461, 461, 461, 461, 461, 461, nil, nil, 461, + 461, nil, nil, nil, nil, nil, 461, 461, nil, 533, + nil, nil, 533, nil, nil, 533, 533, nil, nil, 533, + nil, 533, 461, nil, 461, 533, 461, 461, nil, 461, + 461, 461, 461, 461, 533, 461, nil, nil, nil, 533, + 533, 533, 533, nil, 533, 533, 533, 533, nil, nil, + nil, nil, 533, 533, 536, 536, 536, 536, 536, 536, + 533, nil, 533, 536, 536, nil, nil, nil, 536, nil, + 536, 536, 536, 536, 536, 536, 536, nil, nil, nil, + nil, nil, 536, 536, 536, 536, 536, 536, 536, nil, + nil, 536, nil, nil, nil, nil, nil, 536, 536, 536, + 536, 536, 536, 536, 536, 536, 536, 536, 536, nil, + 536, 536, 536, nil, 536, 536, 536, 536, 536, 462, + 462, 462, 462, 462, 462, 462, nil, nil, 462, 462, + nil, nil, nil, nil, nil, 462, 462, nil, 536, nil, + nil, 536, nil, nil, 536, 536, nil, nil, 536, nil, + 536, 462, nil, 462, 536, 462, 462, nil, 462, 462, + 462, 462, 462, 536, 462, nil, nil, nil, 536, 536, + 536, 536, nil, 536, 536, 536, 536, nil, nil, nil, + nil, 536, 536, 558, 558, 558, 558, 558, 558, 536, + nil, 536, 558, 558, nil, nil, nil, 558, nil, 558, + 558, 558, 558, 558, 558, 558, nil, nil, nil, nil, + nil, 558, 558, 558, 558, 558, 558, 558, nil, nil, + 558, nil, nil, nil, nil, nil, 558, 558, 558, 558, + 558, 558, 558, 558, 558, 558, 558, 558, nil, 558, + 558, 558, nil, 558, 558, 558, 558, 558, 463, 463, + 463, 463, 463, 463, 463, nil, nil, 463, 463, nil, + nil, nil, nil, nil, 463, 463, nil, 558, nil, nil, + 558, nil, nil, 558, 558, nil, nil, 558, nil, 558, + 463, nil, 463, 558, 463, 463, nil, 463, 463, 463, + 463, 463, 558, 463, nil, nil, nil, 558, 558, 558, + 558, nil, 558, 558, 558, 558, nil, nil, nil, nil, + 558, 558, 615, 615, 615, 615, 615, 615, 558, nil, + 558, 615, 615, nil, nil, nil, 615, nil, 615, 615, + 615, 615, 615, 615, 615, nil, nil, nil, nil, nil, + 615, 615, 615, 615, 615, 615, 615, nil, nil, 615, + nil, nil, nil, nil, nil, 615, 615, 615, 615, 615, + 615, 615, 615, 615, 615, 615, 615, nil, 615, 615, + 615, nil, 615, 615, 615, 615, 615, 464, 464, 464, + 464, 464, 464, 464, nil, nil, 464, 464, nil, nil, + nil, nil, nil, 464, 464, nil, 615, nil, nil, 615, + nil, nil, 615, 615, nil, nil, 615, nil, 615, 464, + nil, 464, 615, 464, 464, nil, 464, 464, 464, 464, + 464, 615, 464, nil, nil, nil, 615, 615, 615, 615, + nil, 615, 615, 615, 615, nil, nil, nil, nil, 615, + 615, 620, 620, 620, 620, 620, 620, 615, nil, 615, + 620, 620, nil, nil, nil, 620, nil, 620, 620, 620, + 620, 620, 620, 620, nil, nil, nil, nil, nil, 620, + 620, 620, 620, 620, 620, 620, nil, nil, 620, nil, + nil, nil, nil, nil, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, 620, 620, nil, 620, 620, 620, + nil, 620, 620, 620, 620, 620, 467, 467, 467, 467, + 467, 467, 467, nil, nil, 467, 467, nil, nil, nil, + nil, nil, 467, 467, nil, 620, nil, nil, 620, nil, + nil, 620, 620, nil, nil, 620, nil, 620, 467, nil, + 467, 620, 467, 467, nil, 467, 467, 467, 467, 467, + 620, 467, nil, nil, nil, 620, 620, 620, 620, nil, + 620, 620, 620, 620, nil, nil, nil, nil, 620, 620, + 621, 621, 621, 621, 621, 621, 620, nil, 620, 621, + 621, nil, nil, nil, 621, nil, 621, 621, 621, 621, + 621, 621, 621, nil, nil, nil, nil, nil, 621, 621, + 621, 621, 621, 621, 621, nil, nil, 621, nil, nil, + nil, nil, nil, 621, 621, 621, 621, 621, 621, 621, + 621, 621, 621, 621, 621, nil, 621, 621, 621, nil, + 621, 621, 621, 621, 621, 468, 468, 468, 468, 468, + 468, 468, 468, nil, 468, 468, nil, nil, nil, nil, + nil, 468, 468, nil, 621, nil, nil, 621, nil, nil, + 621, 621, nil, nil, 621, nil, 621, 468, nil, 468, + 621, 468, 468, nil, 468, 468, 468, 468, 468, 621, + 468, nil, nil, nil, 621, 621, 621, 621, nil, 621, + 621, 621, 621, nil, nil, nil, nil, 621, 621, 705, + 705, 705, 705, 705, 705, 621, nil, 621, 705, 705, + nil, nil, nil, 705, nil, 705, 705, 705, 705, 705, + 705, 705, nil, nil, nil, nil, nil, 705, 705, 705, + 705, 705, 705, 705, nil, nil, 705, nil, nil, nil, + nil, nil, 705, 705, 705, 705, 705, 705, 705, 705, + 705, 705, 705, 705, nil, 705, 705, 705, nil, 705, + 705, 705, 705, 705, 452, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 452, 452, nil, 705, nil, nil, 705, nil, nil, 705, + 705, nil, nil, 705, nil, 705, 452, nil, 452, 705, + 452, 452, nil, 452, 452, nil, nil, nil, 705, nil, + nil, nil, nil, 705, 705, 705, 705, nil, 705, 705, + 705, 705, nil, nil, nil, nil, 705, 705, 710, 710, + 710, 710, 710, 710, 705, nil, 705, 710, 710, nil, + nil, nil, 710, nil, 710, 710, 710, 710, 710, 710, + 710, nil, nil, nil, nil, nil, 710, 710, 710, 710, + 710, 710, 710, nil, nil, 710, nil, nil, nil, nil, + nil, 710, 710, 710, 710, 710, 710, 710, 710, 710, + 710, 710, 710, nil, 710, 710, 710, nil, 710, 710, + 710, 710, 710, 453, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 453, + 453, nil, 710, nil, nil, 710, nil, nil, 710, 710, + nil, nil, 710, nil, 710, 453, nil, 453, 710, 453, + 453, nil, 453, 453, nil, nil, nil, 710, nil, nil, + nil, nil, 710, 710, 710, 710, nil, 710, 710, 710, + 710, nil, nil, nil, nil, 710, 710, 720, 720, 720, + 720, 720, 720, 710, nil, 710, 720, 720, nil, nil, + nil, 720, nil, 720, 720, 720, 720, 720, 720, 720, + nil, nil, nil, nil, nil, 720, 720, 720, 720, 720, + 720, 720, nil, nil, 720, nil, nil, nil, nil, nil, + 720, 720, 720, 720, 720, 720, 720, 720, 720, 720, + 720, 720, nil, 720, 720, 720, nil, 720, 720, 720, + 720, 720, 454, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 454, 454, + nil, 720, nil, nil, 720, nil, nil, 720, 720, nil, + nil, 720, nil, 720, 454, nil, nil, 720, 454, 454, + nil, 454, 454, nil, nil, nil, 720, nil, nil, nil, + nil, 720, 720, 720, 720, nil, 720, 720, 720, 720, + nil, nil, nil, nil, 720, 720, 768, 768, 768, 768, + 768, 768, 720, nil, 720, 768, 768, nil, nil, nil, + 768, nil, 768, 768, 768, 768, 768, 768, 768, nil, + nil, nil, nil, nil, 768, 768, 768, 768, 768, 768, + 768, nil, nil, 768, nil, nil, nil, nil, nil, 768, + 768, 768, 768, 768, 768, 768, 768, 768, 768, 768, + 768, nil, 768, 768, 768, nil, 768, 768, 768, 768, + 768, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 768, nil, nil, 768, nil, nil, 768, 768, nil, nil, + 768, nil, 768, nil, nil, nil, 768, nil, nil, nil, + nil, nil, nil, nil, nil, 768, nil, nil, nil, nil, + 768, 768, 768, 768, nil, 768, 768, 768, 768, nil, + nil, nil, nil, 768, 768, 780, 780, 780, 780, 780, + 780, 768, nil, 768, 780, 780, nil, nil, nil, 780, + nil, 780, 780, 780, 780, 780, 780, 780, nil, nil, + nil, nil, nil, 780, 780, 780, 780, 780, 780, 780, + nil, nil, 780, nil, nil, nil, nil, nil, 780, 780, + 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, + nil, 780, 780, 780, nil, 780, 780, 780, 780, 780, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 780, + nil, nil, 780, nil, nil, 780, 780, nil, nil, 780, + nil, 780, nil, nil, nil, 780, nil, nil, nil, nil, + nil, nil, nil, nil, 780, nil, nil, nil, nil, 780, + 780, 780, 780, nil, 780, 780, 780, 780, nil, nil, + nil, nil, 780, 780, 817, 817, 817, 817, 817, 817, + 780, nil, 780, 817, 817, nil, nil, nil, 817, nil, + 817, 817, 817, 817, 817, 817, 817, nil, nil, nil, + nil, nil, 817, 817, 817, 817, 817, 817, 817, nil, + nil, 817, nil, nil, nil, nil, nil, 817, 817, 817, + 817, 817, 817, 817, 817, 817, 817, 817, 817, nil, + 817, 817, 817, nil, 817, 817, 817, 817, 817, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 817, nil, + nil, 817, nil, nil, 817, 817, nil, nil, 817, nil, + 817, nil, nil, nil, 817, nil, nil, nil, nil, nil, + nil, nil, nil, 817, nil, nil, nil, nil, 817, 817, + 817, 817, nil, 817, 817, 817, 817, nil, nil, nil, + nil, 817, 817, 818, 818, 818, 818, 818, 818, 817, + nil, 817, 818, 818, nil, nil, nil, 818, nil, 818, + 818, 818, 818, 818, 818, 818, nil, nil, nil, nil, + nil, 818, 818, 818, 818, 818, 818, 818, nil, nil, + 818, nil, nil, nil, nil, nil, 818, 818, 818, 818, + 818, 818, 818, 818, 818, 818, 818, 818, nil, 818, + 818, 818, nil, 818, 818, 818, 818, 818, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 818, nil, nil, + 818, nil, nil, 818, 818, nil, nil, 818, nil, 818, + nil, nil, nil, 818, nil, nil, nil, nil, nil, nil, + nil, nil, 818, nil, nil, nil, nil, 818, 818, 818, + 818, nil, 818, 818, 818, 818, nil, nil, nil, nil, + 818, 818, 821, 821, 821, 821, 821, 821, 818, nil, + 818, 821, 821, nil, nil, nil, 821, nil, 821, 821, + 821, 821, 821, 821, 821, nil, nil, nil, nil, nil, + 821, 821, 821, 821, 821, 821, 821, nil, nil, 821, + nil, nil, nil, nil, nil, 821, 821, 821, 821, 821, + 821, 821, 821, 821, 821, 821, 821, nil, 821, 821, + 821, nil, 821, 821, 821, 821, 821, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 821, nil, nil, 821, + nil, nil, 821, 821, nil, nil, 821, nil, 821, nil, + nil, nil, 821, nil, nil, nil, nil, nil, nil, nil, + nil, 821, nil, nil, nil, nil, 821, 821, 821, 821, + nil, 821, 821, 821, 821, nil, nil, nil, nil, 821, + 821, 827, 827, 827, 827, 827, 827, 821, nil, 821, + 827, 827, nil, nil, nil, 827, nil, 827, 827, 827, + 827, 827, 827, 827, nil, nil, nil, nil, nil, 827, + 827, 827, 827, 827, 827, 827, nil, nil, 827, nil, + nil, nil, nil, nil, 827, 827, 827, 827, 827, 827, + 827, 827, 827, 827, 827, 827, nil, 827, 827, 827, + nil, 827, 827, 827, 827, 827, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 827, nil, nil, 827, nil, + nil, 827, 827, nil, nil, 827, nil, 827, nil, nil, + nil, 827, nil, nil, nil, nil, nil, nil, nil, nil, + 827, nil, nil, nil, nil, 827, 827, 827, 827, nil, + 827, 827, 827, 827, nil, nil, nil, nil, 827, 827, + 860, 860, 860, 860, 860, 860, 827, nil, 827, 860, + 860, nil, nil, nil, 860, nil, 860, 860, 860, 860, + 860, 860, 860, nil, nil, nil, nil, nil, 860, 860, + 860, 860, 860, 860, 860, nil, nil, 860, nil, nil, + nil, nil, nil, 860, 860, 860, 860, 860, 860, 860, + 860, 860, 860, 860, 860, nil, 860, 860, 860, nil, + 860, 860, 860, 860, 860, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 860, nil, nil, 860, nil, nil, + 860, 860, nil, nil, 860, nil, 860, nil, nil, nil, + 860, nil, nil, nil, nil, nil, nil, nil, nil, 860, + nil, nil, nil, nil, 860, 860, 860, 860, nil, 860, + 860, 860, 860, nil, nil, nil, nil, 860, 860, 867, + 867, 867, 867, 867, 867, 860, nil, 860, 867, 867, + nil, nil, nil, 867, nil, 867, 867, 867, 867, 867, + 867, 867, nil, nil, nil, nil, nil, 867, 867, 867, + 867, 867, 867, 867, nil, nil, 867, nil, nil, nil, + nil, nil, 867, 867, 867, 867, 867, 867, 867, 867, + 867, 867, 867, 867, nil, 867, 867, 867, nil, 867, + 867, 867, 867, 867, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 867, nil, nil, 867, nil, nil, 867, + 867, nil, nil, 867, nil, 867, nil, nil, nil, 867, + nil, nil, nil, nil, nil, nil, nil, nil, 867, nil, + nil, nil, nil, 867, 867, 867, 867, nil, 867, 867, + 867, 867, nil, nil, nil, nil, 867, 867, 868, 868, + 868, 868, 868, 868, 867, nil, 867, 868, 868, nil, + nil, nil, 868, nil, 868, 868, 868, 868, 868, 868, + 868, nil, nil, nil, nil, nil, 868, 868, 868, 868, + 868, 868, 868, nil, nil, 868, nil, nil, nil, nil, + nil, 868, 868, 868, 868, 868, 868, 868, 868, 868, + 868, 868, 868, nil, 868, 868, 868, nil, 868, 868, + 868, 868, 868, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 868, nil, nil, 868, nil, nil, 868, 868, + nil, nil, 868, nil, 868, nil, nil, nil, 868, nil, + nil, nil, nil, nil, nil, nil, nil, 868, nil, nil, + nil, nil, 868, 868, 868, 868, nil, 868, 868, 868, + 868, nil, nil, nil, nil, 868, 868, 921, 921, 921, + 921, 921, 921, 868, nil, 868, 921, 921, nil, nil, + nil, 921, nil, 921, 921, 921, 921, 921, 921, 921, + nil, nil, nil, nil, nil, 921, 921, 921, 921, 921, + 921, 921, nil, nil, 921, nil, nil, nil, nil, nil, + 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, + 921, 921, nil, 921, 921, 921, nil, 921, 921, 921, + 921, 921, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 921, nil, nil, 921, nil, nil, 921, 921, nil, + nil, 921, nil, 921, nil, nil, nil, 921, nil, nil, + nil, nil, nil, nil, nil, nil, 921, nil, nil, nil, + nil, 921, 921, 921, 921, nil, 921, 921, 921, 921, + nil, nil, nil, nil, 921, 921, 946, 946, 946, 946, + 946, 946, 921, nil, 921, 946, 946, nil, nil, nil, + 946, nil, 946, 946, 946, 946, 946, 946, 946, nil, + nil, nil, nil, nil, 946, 946, 946, 946, 946, 946, + 946, nil, nil, 946, nil, nil, nil, nil, nil, 946, + 946, 946, 946, 946, 946, 946, 946, 946, 946, 946, + 946, nil, 946, 946, 946, nil, 946, 946, 946, 946, + 946, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 946, nil, nil, 946, nil, nil, 946, 946, nil, nil, + 946, nil, 946, nil, nil, nil, 946, nil, nil, nil, + nil, nil, nil, nil, nil, 946, nil, nil, nil, nil, + 946, 946, 946, 946, nil, 946, 946, 946, 946, nil, + nil, nil, nil, 946, 946, 952, 952, 952, 952, 952, + 952, 946, nil, 946, 952, 952, nil, nil, nil, 952, + nil, 952, 952, 952, 952, 952, 952, 952, nil, nil, + nil, nil, nil, 952, 952, 952, 952, 952, 952, 952, + nil, nil, 952, nil, nil, nil, nil, nil, 952, 952, + 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, + nil, 952, 952, 952, nil, 952, 952, 952, 952, 952, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 952, + nil, nil, 952, nil, nil, 952, 952, nil, nil, 952, + nil, 952, nil, nil, nil, 952, nil, nil, nil, nil, + nil, nil, nil, nil, 952, nil, nil, nil, nil, 952, + 952, 952, 952, nil, 952, 952, 952, 952, nil, nil, + nil, nil, 952, 952, 954, 954, 954, 954, 954, 954, + 952, nil, 952, 954, 954, nil, nil, nil, 954, nil, + 954, 954, 954, 954, 954, 954, 954, nil, nil, nil, + nil, nil, 954, 954, 954, 954, 954, 954, 954, nil, + nil, 954, nil, nil, nil, nil, nil, 954, 954, 954, + 954, 954, 954, 954, 954, 954, 954, 954, 954, nil, + 954, 954, 954, nil, 954, 954, 954, 954, 954, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 954, nil, + nil, 954, nil, nil, 954, 954, nil, nil, 954, nil, + 954, nil, nil, nil, 954, nil, nil, nil, nil, nil, + nil, nil, nil, 954, nil, nil, nil, nil, 954, 954, + 954, 954, nil, 954, 954, 954, 954, nil, nil, nil, + nil, 954, 954, nil, 5, 5, 5, 5, 5, 954, + nil, 954, 5, 5, nil, nil, nil, 5, nil, 5, + 5, 5, 5, 5, 5, 5, nil, nil, nil, nil, + nil, 5, 5, 5, 5, 5, 5, 5, nil, nil, + 5, nil, nil, nil, nil, nil, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, nil, 5, + 5, 5, nil, 5, 5, 5, 5, 5, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 5, nil, nil, + 5, nil, nil, 5, 5, nil, nil, 5, nil, 5, + nil, nil, nil, 5, nil, nil, nil, nil, nil, nil, + nil, nil, 5, nil, nil, nil, nil, 5, 5, 5, + 5, nil, 5, 5, 5, 5, nil, nil, nil, nil, + 5, 5, nil, 20, 20, 20, nil, 20, 5, nil, + 5, 20, 20, nil, nil, nil, 20, nil, 20, 20, + 20, 20, 20, 20, 20, nil, nil, nil, nil, nil, + 20, 20, 20, 20, 20, 20, 20, nil, nil, 20, + nil, nil, nil, nil, nil, nil, 20, nil, nil, 20, + 20, 20, 20, 20, 20, 20, 20, nil, 20, 20, + 20, nil, 20, 20, 20, 20, 20, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 20, nil, nil, 20, + nil, nil, 20, 20, nil, nil, 20, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, nil, nil, nil, + nil, 20, nil, nil, nil, nil, 20, 20, 20, 20, + nil, 20, 20, 20, 20, nil, nil, nil, nil, 20, + 20, nil, 29, 29, 29, nil, 29, 20, nil, 20, + 29, 29, nil, nil, nil, 29, nil, 29, 29, 29, + 29, 29, 29, 29, nil, nil, nil, nil, nil, 29, + 29, 29, 29, 29, 29, 29, nil, nil, 29, nil, + nil, nil, nil, nil, nil, 29, nil, nil, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + nil, 29, 29, 29, 29, 29, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 29, nil, nil, 29, nil, + nil, 29, 29, nil, nil, 29, nil, 29, nil, 29, + nil, 29, nil, nil, 29, nil, nil, nil, nil, nil, + 29, nil, nil, nil, nil, 29, 29, 29, 29, nil, + 29, 29, 29, 29, nil, nil, nil, nil, 29, 29, + nil, 30, 30, 30, nil, 30, 29, nil, 29, 30, + 30, nil, nil, nil, 30, nil, 30, 30, 30, 30, + 30, 30, 30, nil, nil, nil, nil, nil, 30, 30, + 30, 30, 30, 30, 30, nil, nil, 30, nil, nil, + nil, nil, nil, nil, 30, nil, nil, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, nil, + 30, 30, 30, 30, 30, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 30, nil, nil, 30, nil, nil, + 30, 30, nil, nil, 30, nil, 30, nil, 30, nil, + 30, nil, nil, 30, nil, nil, nil, nil, nil, 30, + nil, nil, nil, nil, 30, 30, 30, 30, nil, 30, + 30, 30, 30, nil, nil, nil, nil, 30, 30, nil, + 31, 31, 31, nil, 31, 30, nil, 30, 31, 31, + nil, nil, nil, 31, nil, 31, 31, 31, 31, 31, + 31, 31, nil, nil, nil, nil, nil, 31, 31, 31, + 31, 31, 31, 31, nil, nil, 31, nil, nil, nil, + nil, nil, nil, 31, nil, nil, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, nil, 31, + 31, 31, 31, 31, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 31, nil, nil, 31, nil, nil, 31, + 31, nil, nil, 31, nil, 31, nil, 31, nil, 31, + nil, nil, 31, nil, nil, nil, nil, nil, 31, nil, + nil, nil, nil, 31, 31, 31, 31, nil, 31, 31, + 31, 31, nil, nil, nil, nil, 31, 31, nil, 34, + 34, 34, nil, 34, 31, nil, 31, 34, 34, nil, + nil, nil, 34, nil, 34, 34, 34, 34, 34, 34, + 34, nil, nil, nil, nil, nil, 34, 34, 34, 34, + 34, 34, 34, nil, nil, 34, nil, nil, nil, nil, + nil, nil, 34, nil, nil, 34, 34, 34, 34, 34, + 34, 34, 34, nil, 34, 34, 34, nil, 34, 34, + nil, nil, 34, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 34, nil, nil, 34, nil, nil, 34, 34, + nil, nil, 34, nil, 34, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 34, 34, 34, 34, nil, 34, 34, 34, + 34, nil, nil, nil, nil, 34, 34, nil, 35, 35, + 35, nil, 35, 34, nil, 34, 35, 35, nil, nil, + nil, 35, nil, 35, 35, 35, 35, 35, 35, 35, + nil, nil, nil, nil, nil, 35, 35, 35, 35, 35, + 35, 35, nil, nil, 35, nil, nil, nil, nil, 610, + nil, 35, nil, nil, 35, 35, 35, 35, 35, 35, + 35, 35, nil, 35, 35, 35, nil, 35, 35, nil, + nil, 35, 610, 610, 610, 610, 610, 610, 610, 610, + 610, 610, 610, nil, 610, 610, nil, nil, 610, 610, + nil, 35, nil, nil, 35, nil, nil, 35, 35, nil, + nil, 35, nil, nil, 610, nil, 610, nil, 610, 610, + nil, 610, 610, 610, 610, 610, nil, 610, nil, nil, + nil, 35, 35, 35, 35, nil, 35, 35, 35, 35, + nil, nil, nil, nil, 35, 35, nil, 610, nil, 35, + nil, nil, 35, nil, 35, 42, 42, 42, nil, 42, + nil, nil, nil, 42, 42, nil, nil, nil, 42, nil, + 42, 42, 42, 42, 42, 42, 42, nil, nil, nil, + nil, nil, 42, 42, 42, 42, 42, 42, 42, nil, + nil, 42, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 42, 42, 42, 42, 42, 42, 42, 42, nil, + 42, 42, 42, nil, 42, 42, 42, 42, 42, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 42, nil, + nil, 42, nil, nil, 42, 42, nil, nil, 42, nil, + nil, nil, nil, nil, 42, nil, nil, nil, nil, nil, + nil, nil, nil, 42, nil, nil, nil, nil, 42, 42, + 42, 42, nil, 42, 42, 42, 42, nil, nil, nil, + nil, 42, 42, nil, 43, 43, 43, nil, 43, 42, + nil, 42, 43, 43, nil, nil, nil, 43, nil, 43, + 43, 43, 43, 43, 43, 43, nil, nil, nil, nil, + nil, 43, 43, 43, 43, 43, 43, 43, nil, nil, + 43, nil, nil, nil, nil, nil, nil, 43, nil, nil, + 43, 43, 43, 43, 43, 43, 43, 43, nil, 43, + 43, 43, nil, 43, 43, 43, 43, 43, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 43, nil, nil, + 43, nil, nil, 43, 43, nil, nil, 43, nil, nil, + nil, nil, nil, 43, nil, nil, nil, nil, nil, nil, + nil, nil, 43, nil, nil, nil, nil, 43, 43, 43, + 43, nil, 43, 43, 43, 43, nil, nil, nil, nil, + 43, 43, nil, 44, 44, 44, nil, 44, 43, nil, + 43, 44, 44, nil, nil, nil, 44, nil, 44, 44, + 44, 44, 44, 44, 44, nil, nil, nil, nil, nil, + 44, 44, 44, 44, 44, 44, 44, nil, nil, 44, + nil, nil, nil, nil, nil, nil, 44, nil, nil, 44, + 44, 44, 44, 44, 44, 44, 44, nil, 44, 44, + 44, nil, 44, 44, 44, 44, 44, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 44, nil, nil, 44, + nil, nil, 44, 44, nil, nil, 44, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, 44, 44, 44, 44, + nil, 44, 44, 44, 44, nil, nil, nil, nil, 44, + 44, nil, 59, 59, 59, nil, 59, 44, nil, 44, + 59, 59, nil, nil, nil, 59, nil, 59, 59, 59, + 59, 59, 59, 59, nil, nil, nil, nil, nil, 59, + 59, 59, 59, 59, 59, 59, nil, nil, 59, nil, + nil, nil, nil, nil, nil, 59, nil, nil, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, + nil, 59, 59, 59, 59, 59, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 59, nil, nil, 59, nil, + nil, 59, 59, nil, nil, 59, nil, 59, nil, nil, + nil, 59, nil, nil, 59, nil, nil, nil, nil, nil, + 59, nil, nil, nil, nil, 59, 59, 59, 59, nil, + 59, 59, 59, 59, nil, nil, nil, nil, 59, 59, + nil, 60, 60, 60, nil, 60, 59, nil, 59, 60, + 60, nil, nil, nil, 60, nil, 60, 60, 60, 60, + 60, 60, 60, nil, nil, nil, nil, nil, 60, 60, + 60, 60, 60, 60, 60, nil, nil, 60, nil, nil, + nil, nil, nil, nil, 60, nil, nil, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, nil, + 60, 60, 60, 60, 60, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 60, nil, nil, 60, nil, nil, + 60, 60, nil, nil, 60, nil, nil, nil, nil, nil, + 60, nil, nil, 60, nil, nil, nil, nil, nil, 60, + nil, nil, nil, nil, 60, 60, 60, 60, nil, 60, + 60, 60, 60, nil, nil, nil, nil, 60, 60, nil, + 63, 63, 63, nil, 63, 60, nil, 60, 63, 63, + nil, nil, nil, 63, nil, 63, 63, 63, 63, 63, + 63, 63, nil, nil, nil, nil, nil, 63, 63, 63, + 63, 63, 63, 63, nil, nil, 63, nil, nil, nil, + nil, nil, nil, 63, nil, nil, 63, 63, 63, 63, + 63, 63, 63, 63, nil, 63, 63, 63, nil, 63, + 63, 63, 63, 63, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 63, nil, nil, 63, nil, nil, 63, + 63, nil, nil, 63, nil, nil, nil, nil, nil, 63, + nil, nil, nil, nil, nil, nil, nil, nil, 63, nil, + nil, nil, nil, 63, 63, 63, 63, nil, 63, 63, + 63, 63, nil, nil, nil, nil, 63, 63, nil, 64, + 64, 64, nil, 64, 63, nil, 63, 64, 64, nil, + nil, nil, 64, nil, 64, 64, 64, 64, 64, 64, + 64, nil, nil, nil, nil, nil, 64, 64, 64, 64, + 64, 64, 64, nil, nil, 64, nil, nil, nil, nil, + nil, nil, 64, nil, nil, 64, 64, 64, 64, 64, + 64, 64, 64, nil, 64, 64, 64, nil, 64, 64, + 64, 64, 64, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 64, nil, nil, 64, nil, nil, 64, 64, + nil, nil, 64, nil, nil, nil, nil, nil, 64, nil, + nil, nil, nil, nil, nil, nil, nil, 64, nil, nil, + nil, nil, 64, 64, 64, 64, nil, 64, 64, 64, + 64, nil, nil, nil, nil, 64, 64, nil, 67, 67, + 67, nil, 67, 64, nil, 64, 67, 67, nil, nil, + nil, 67, nil, 67, 67, 67, 67, 67, 67, 67, + nil, nil, nil, nil, nil, 67, 67, 67, 67, 67, + 67, 67, nil, nil, 67, nil, nil, nil, nil, nil, + nil, 67, nil, nil, 67, 67, 67, 67, 67, 67, + 67, 67, nil, 67, 67, 67, nil, 67, 67, 67, + 67, 67, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, nil, 21, 21, nil, nil, 21, 21, + nil, 67, nil, nil, 67, nil, nil, 67, 67, nil, + nil, 67, nil, nil, 21, nil, 21, 67, 21, 21, + nil, 21, 21, 21, 21, 21, 67, 21, nil, nil, + nil, 67, 67, 67, 67, nil, 67, 67, 67, 67, + nil, nil, nil, nil, 67, 67, 67, 21, nil, nil, + nil, 67, 67, nil, 67, 68, 68, 68, nil, 68, + nil, nil, nil, 68, 68, nil, nil, nil, 68, nil, + 68, 68, 68, 68, 68, 68, 68, nil, nil, nil, + nil, nil, 68, 68, 68, 68, 68, 68, 68, nil, + nil, 68, nil, nil, nil, nil, nil, nil, 68, nil, + nil, 68, 68, 68, 68, 68, 68, 68, 68, nil, + 68, 68, 68, nil, 68, 68, nil, nil, 68, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 68, nil, + nil, 68, nil, nil, 68, 68, nil, nil, 68, nil, + 68, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 68, 68, + 68, 68, nil, 68, 68, 68, 68, nil, nil, nil, + nil, 68, 68, nil, 69, 69, 69, nil, 69, 68, + nil, 68, 69, 69, nil, nil, nil, 69, nil, 69, + 69, 69, 69, 69, 69, 69, nil, nil, nil, nil, + nil, 69, 69, 69, 69, 69, 69, 69, nil, nil, + 69, nil, nil, nil, nil, nil, nil, 69, nil, nil, + 69, 69, 69, 69, 69, 69, 69, 69, nil, 69, + 69, 69, nil, 69, 69, nil, nil, 69, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 69, nil, nil, 69, nil, nil, + 69, nil, nil, 69, 69, nil, nil, 69, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 69, 69, 69, + 69, nil, 69, 69, 69, 69, nil, nil, nil, nil, + 69, 69, nil, 70, 70, 70, nil, 70, 69, nil, + 69, 70, 70, nil, nil, nil, 70, nil, 70, 70, + 70, 70, 70, 70, 70, nil, nil, nil, nil, nil, + 70, 70, 70, 70, 70, 70, 70, nil, nil, 70, + nil, nil, nil, nil, nil, nil, 70, nil, nil, 70, + 70, 70, 70, 70, 70, 70, 70, nil, 70, 70, + 70, nil, 70, 70, nil, nil, 70, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 70, nil, nil, 70, + nil, nil, 70, 70, nil, nil, 70, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 70, 70, 70, 70, + nil, 70, 70, 70, 70, nil, nil, nil, nil, 70, + 70, nil, 110, 110, 110, 110, 110, 70, nil, 70, + 110, 110, nil, nil, nil, 110, nil, 110, 110, 110, + 110, 110, 110, 110, nil, nil, nil, nil, nil, 110, + 110, 110, 110, 110, 110, 110, nil, nil, 110, nil, + nil, nil, nil, nil, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, nil, 110, 110, 110, + nil, 110, 110, 110, 110, 110, 273, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, nil, 273, 273, + nil, nil, 273, 273, nil, 110, nil, nil, 110, nil, + nil, 110, 110, nil, nil, 110, nil, 110, 273, nil, + 273, 110, 273, 273, nil, 273, 273, 273, 273, 273, + 110, 273, nil, nil, nil, 110, 110, 110, 110, nil, + 110, 110, 110, 110, nil, nil, nil, nil, 110, 110, + nil, 273, nil, nil, nil, 110, 110, nil, 110, 115, + 115, 115, nil, 115, nil, nil, nil, 115, 115, nil, + nil, nil, 115, nil, 115, 115, 115, 115, 115, 115, + 115, nil, nil, nil, nil, nil, 115, 115, 115, 115, + 115, 115, 115, nil, nil, 115, nil, nil, nil, nil, + nil, nil, 115, nil, nil, 115, 115, 115, 115, 115, + 115, 115, 115, nil, 115, 115, 115, nil, 115, 115, + 115, 115, 115, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 115, nil, nil, 115, nil, nil, 115, 115, + nil, nil, 115, nil, nil, nil, nil, nil, 115, nil, + nil, nil, nil, nil, nil, nil, nil, 115, nil, nil, + nil, nil, 115, 115, 115, 115, nil, 115, 115, 115, + 115, nil, nil, nil, nil, 115, 115, nil, 116, 116, + 116, nil, 116, 115, nil, 115, 116, 116, nil, nil, + nil, 116, nil, 116, 116, 116, 116, 116, 116, 116, + nil, nil, nil, nil, nil, 116, 116, 116, 116, 116, + 116, 116, nil, nil, 116, nil, nil, nil, nil, nil, + nil, 116, nil, nil, 116, 116, 116, 116, 116, 116, + 116, 116, nil, 116, 116, 116, nil, 116, 116, 116, + 116, 116, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 116, nil, nil, 116, nil, nil, 116, 116, nil, + nil, 116, nil, nil, nil, nil, nil, 116, nil, nil, + nil, nil, nil, nil, nil, nil, 116, nil, nil, nil, + nil, 116, 116, 116, 116, nil, 116, 116, 116, 116, + nil, nil, nil, nil, 116, 116, nil, 117, 117, 117, + nil, 117, 116, nil, 116, 117, 117, nil, nil, nil, + 117, nil, 117, 117, 117, 117, 117, 117, 117, nil, + nil, nil, nil, nil, 117, 117, 117, 117, 117, 117, + 117, nil, nil, 117, nil, nil, nil, nil, nil, nil, + 117, nil, nil, 117, 117, 117, 117, 117, 117, 117, + 117, nil, 117, 117, 117, nil, 117, 117, 117, 117, + 117, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 117, nil, nil, 117, nil, nil, 117, 117, nil, nil, + 117, nil, nil, nil, nil, nil, 117, nil, nil, nil, + nil, nil, nil, nil, nil, 117, nil, nil, nil, nil, + 117, 117, 117, 117, nil, 117, 117, 117, 117, nil, + nil, nil, nil, 117, 117, nil, 118, 118, 118, nil, + 118, 117, nil, 117, 118, 118, nil, nil, nil, 118, + nil, 118, 118, 118, 118, 118, 118, 118, nil, nil, + nil, nil, nil, 118, 118, 118, 118, 118, 118, 118, + nil, nil, 118, nil, nil, nil, nil, nil, nil, 118, + nil, nil, 118, 118, 118, 118, 118, 118, 118, 118, + nil, 118, 118, 118, nil, 118, 118, 118, 118, 118, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 118, + nil, nil, 118, nil, nil, 118, 118, nil, nil, 118, + nil, nil, nil, nil, nil, 118, nil, nil, nil, nil, + nil, nil, nil, nil, 118, nil, nil, nil, nil, 118, + 118, 118, 118, nil, 118, 118, 118, 118, nil, nil, + nil, nil, 118, 118, nil, 119, 119, 119, 119, 119, + 118, nil, 118, 119, 119, nil, nil, nil, 119, nil, + 119, 119, 119, 119, 119, 119, 119, nil, nil, nil, + nil, nil, 119, 119, 119, 119, 119, 119, 119, nil, + nil, 119, nil, nil, nil, nil, nil, 119, 119, nil, + 119, 119, 119, 119, 119, 119, 119, 119, 119, nil, + 119, 119, 119, nil, 119, 119, 119, 119, 119, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 119, nil, + nil, 119, nil, nil, 119, 119, nil, nil, 119, nil, + 119, nil, nil, nil, 119, nil, nil, nil, nil, nil, + nil, nil, nil, 119, nil, nil, nil, nil, 119, 119, + 119, 119, nil, 119, 119, 119, 119, nil, nil, nil, + nil, 119, 119, nil, 206, 206, 206, nil, 206, 119, + nil, 119, 206, 206, nil, nil, nil, 206, nil, 206, + 206, 206, 206, 206, 206, 206, nil, nil, nil, nil, + nil, 206, 206, 206, 206, 206, 206, 206, nil, nil, + 206, nil, nil, nil, nil, nil, nil, 206, nil, nil, + 206, 206, 206, 206, 206, 206, 206, 206, nil, 206, + 206, 206, nil, 206, 206, 206, 206, 206, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 206, nil, nil, + 206, nil, nil, 206, 206, nil, nil, 206, nil, 206, + nil, nil, nil, 206, nil, nil, nil, nil, nil, nil, + nil, nil, 206, nil, nil, nil, nil, 206, 206, 206, + 206, nil, 206, 206, 206, 206, nil, nil, nil, nil, + 206, 206, nil, 207, 207, 207, nil, 207, 206, nil, + 206, 207, 207, nil, nil, nil, 207, nil, 207, 207, + 207, 207, 207, 207, 207, nil, nil, nil, nil, nil, + 207, 207, 207, 207, 207, 207, 207, nil, nil, 207, + nil, nil, nil, nil, nil, nil, 207, nil, nil, 207, + 207, 207, 207, 207, 207, 207, 207, nil, 207, 207, + 207, nil, 207, 207, 207, 207, 207, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 207, nil, nil, 207, + nil, nil, 207, 207, nil, nil, 207, nil, nil, nil, + nil, nil, 207, nil, nil, nil, nil, nil, nil, nil, + nil, 207, nil, nil, nil, nil, 207, 207, 207, 207, + nil, 207, 207, 207, 207, nil, nil, nil, nil, 207, + 207, nil, 208, 208, 208, nil, 208, 207, nil, 207, + 208, 208, nil, nil, nil, 208, nil, 208, 208, 208, + 208, 208, 208, 208, nil, nil, nil, nil, nil, 208, + 208, 208, 208, 208, 208, 208, nil, nil, 208, nil, + nil, nil, nil, nil, nil, 208, nil, nil, 208, 208, + 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, + nil, 208, 208, 208, 208, 208, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 208, nil, nil, 208, nil, + nil, 208, 208, nil, nil, 208, nil, 208, nil, 208, + nil, 208, nil, nil, 208, nil, nil, nil, nil, nil, + 208, nil, nil, nil, nil, 208, 208, 208, 208, nil, + 208, 208, 208, 208, nil, nil, nil, nil, 208, 208, + nil, 211, 211, 211, nil, 211, 208, nil, 208, 211, + 211, nil, nil, nil, 211, nil, 211, 211, 211, 211, + 211, 211, 211, nil, nil, nil, nil, nil, 211, 211, + 211, 211, 211, 211, 211, nil, nil, 211, nil, nil, + nil, nil, nil, nil, 211, nil, nil, 211, 211, 211, + 211, 211, 211, 211, 211, nil, 211, 211, 211, nil, + 211, 211, 211, 211, 211, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 211, nil, nil, 211, nil, nil, + 211, 211, nil, nil, 211, nil, nil, nil, nil, nil, + 211, nil, nil, nil, nil, nil, nil, nil, nil, 211, + nil, nil, nil, nil, 211, 211, 211, 211, nil, 211, + 211, 211, 211, nil, nil, nil, nil, 211, 211, nil, + 212, 212, 212, nil, 212, 211, nil, 211, 212, 212, + nil, nil, nil, 212, nil, 212, 212, 212, 212, 212, + 212, 212, nil, nil, nil, nil, nil, 212, 212, 212, + 212, 212, 212, 212, nil, nil, 212, nil, nil, nil, + nil, nil, nil, 212, nil, nil, 212, 212, 212, 212, + 212, 212, 212, 212, nil, 212, 212, 212, nil, 212, + 212, 212, 212, 212, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 212, nil, nil, 212, nil, nil, 212, + 212, nil, nil, 212, nil, 212, nil, nil, nil, 212, + nil, nil, nil, nil, nil, nil, nil, nil, 212, nil, + nil, nil, nil, 212, 212, 212, 212, nil, 212, 212, + 212, 212, nil, nil, nil, nil, 212, 212, nil, 213, + 213, 213, nil, 213, 212, nil, 212, 213, 213, nil, + nil, nil, 213, nil, 213, 213, 213, 213, 213, 213, + 213, nil, nil, nil, nil, nil, 213, 213, 213, 213, + 213, 213, 213, nil, nil, 213, nil, nil, nil, nil, + nil, nil, 213, nil, nil, 213, 213, 213, 213, 213, + 213, 213, 213, nil, 213, 213, 213, nil, 213, 213, + 213, 213, 213, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 213, nil, nil, 213, nil, nil, 213, 213, + nil, nil, 213, nil, nil, nil, nil, nil, 213, nil, + nil, nil, nil, nil, nil, nil, nil, 213, nil, nil, + nil, nil, 213, 213, 213, 213, nil, 213, 213, 213, + 213, nil, nil, nil, nil, 213, 213, nil, 214, 214, + 214, nil, 214, 213, nil, 213, 214, 214, nil, nil, + nil, 214, nil, 214, 214, 214, 214, 214, 214, 214, + nil, nil, nil, nil, nil, 214, 214, 214, 214, 214, + 214, 214, nil, nil, 214, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 214, 214, 214, 214, 214, 214, + 214, 214, nil, 214, 214, 214, nil, 214, 214, 214, + 214, 214, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 214, nil, nil, 214, 214, nil, + nil, 214, nil, nil, nil, nil, nil, 214, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, nil, + nil, 214, 214, 214, 214, nil, 214, 214, 214, 214, + nil, nil, nil, nil, 214, 214, nil, 215, 215, 215, + nil, 215, 214, nil, 214, 215, 215, nil, nil, nil, + 215, nil, 215, 215, 215, 215, 215, 215, 215, nil, + nil, nil, nil, nil, 215, 215, 215, 215, 215, 215, + 215, nil, nil, 215, nil, nil, nil, nil, nil, nil, + 215, nil, nil, 215, 215, 215, 215, 215, 215, 215, + 215, nil, 215, 215, 215, nil, 215, 215, 215, 215, + 215, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 215, nil, nil, 215, nil, nil, 215, 215, nil, nil, + 215, nil, nil, nil, nil, nil, 215, nil, nil, nil, + nil, nil, nil, nil, nil, 215, nil, nil, nil, nil, + 215, 215, 215, 215, nil, 215, 215, 215, 215, nil, + nil, nil, nil, 215, 215, nil, 216, 216, 216, nil, + 216, 215, nil, 215, 216, 216, nil, nil, nil, 216, + nil, 216, 216, 216, 216, 216, 216, 216, nil, nil, + nil, nil, nil, 216, 216, 216, 216, 216, 216, 216, + nil, nil, 216, nil, nil, nil, nil, nil, nil, 216, + nil, nil, 216, 216, 216, 216, 216, 216, 216, 216, + nil, 216, 216, 216, nil, 216, 216, 216, 216, 216, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 216, + nil, nil, 216, nil, nil, 216, 216, nil, nil, 216, + nil, nil, nil, nil, nil, 216, nil, nil, nil, nil, + nil, nil, nil, nil, 216, nil, nil, nil, nil, 216, + 216, 216, 216, nil, 216, 216, 216, 216, nil, nil, + nil, nil, 216, 216, 216, 227, 227, 227, nil, 227, + 216, nil, 216, 227, 227, nil, nil, nil, 227, nil, + 227, 227, 227, 227, 227, 227, 227, nil, nil, nil, + nil, nil, 227, 227, 227, 227, 227, 227, 227, nil, + nil, 227, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 227, 227, 227, 227, 227, 227, 227, 227, nil, + 227, 227, 227, nil, 227, 227, 227, 227, 227, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 227, nil, nil, 227, 227, nil, nil, 227, nil, + nil, nil, nil, nil, 227, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, nil, nil, 227, 227, + 227, 227, nil, 227, 227, 227, 227, nil, nil, nil, + nil, 227, 227, nil, 230, 230, 230, nil, 230, 227, + nil, 227, 230, 230, nil, nil, nil, 230, nil, 230, + 230, 230, 230, 230, 230, 230, nil, nil, nil, nil, + nil, 230, 230, 230, 230, 230, 230, 230, nil, nil, + 230, nil, nil, nil, nil, nil, nil, 230, nil, nil, + 230, 230, 230, 230, 230, 230, 230, 230, nil, 230, + 230, 230, nil, 230, 230, 230, 230, 230, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + 230, nil, nil, 230, 230, nil, nil, 230, nil, nil, + nil, nil, nil, 230, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, nil, nil, 230, 230, 230, + 230, nil, 230, 230, 230, 230, nil, nil, nil, nil, + 230, 230, nil, 231, 231, 231, nil, 231, 230, nil, + 230, 231, 231, nil, nil, nil, 231, nil, 231, 231, + 231, 231, 231, 231, 231, nil, nil, nil, nil, nil, + 231, 231, 231, 231, 231, 231, 231, nil, nil, 231, + nil, nil, nil, nil, nil, nil, 231, nil, nil, 231, + 231, 231, 231, 231, 231, 231, 231, nil, 231, 231, + 231, nil, 231, 231, 231, 231, 231, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 231, nil, nil, 231, + nil, nil, 231, 231, nil, nil, 231, nil, nil, nil, + nil, nil, 231, nil, nil, nil, nil, nil, nil, nil, + nil, 231, nil, nil, nil, nil, 231, 231, 231, 231, + nil, 231, 231, 231, 231, nil, nil, nil, nil, 231, + 231, nil, 232, 232, 232, nil, 232, 231, nil, 231, + 232, 232, nil, nil, nil, 232, nil, 232, 232, 232, + 232, 232, 232, 232, nil, nil, nil, nil, nil, 232, + 232, 232, 232, 232, 232, 232, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 232, nil, nil, 232, 232, + 232, 232, 232, 232, 232, 232, nil, 232, 232, 232, + nil, 232, 232, 232, 232, 232, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 232, nil, nil, 232, nil, + nil, 232, 232, nil, nil, 232, nil, nil, nil, nil, + nil, 232, nil, nil, nil, nil, nil, nil, nil, nil, + 232, nil, nil, nil, nil, 232, 232, 232, 232, nil, + 232, 232, 232, 232, nil, nil, nil, nil, 232, 232, + nil, 233, 233, 233, nil, 233, 232, nil, 232, 233, + 233, nil, nil, nil, 233, nil, 233, 233, 233, 233, + 233, 233, 233, nil, nil, nil, nil, nil, 233, 233, + 233, 233, 233, 233, 233, nil, nil, 233, nil, nil, + nil, nil, nil, nil, 233, nil, nil, 233, 233, 233, + 233, 233, 233, 233, 233, nil, 233, 233, 233, nil, + 233, 233, 233, 233, 233, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 233, nil, nil, 233, nil, nil, + 233, 233, nil, nil, 233, nil, nil, nil, nil, nil, + 233, nil, nil, nil, nil, nil, nil, nil, nil, 233, + nil, nil, nil, nil, 233, 233, 233, 233, nil, 233, + 233, 233, 233, nil, nil, nil, nil, 233, 233, nil, + 234, 234, 234, nil, 234, 233, nil, 233, 234, 234, + nil, nil, nil, 234, nil, 234, 234, 234, 234, 234, + 234, 234, nil, nil, nil, nil, nil, 234, 234, 234, + 234, 234, 234, 234, nil, nil, 234, nil, nil, nil, + nil, nil, nil, 234, nil, nil, 234, 234, 234, 234, + 234, 234, 234, 234, nil, 234, 234, 234, nil, 234, + 234, 234, 234, 234, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 234, nil, nil, 234, nil, nil, 234, + 234, nil, nil, 234, nil, nil, nil, nil, nil, 234, + nil, nil, nil, nil, nil, nil, nil, nil, 234, nil, + nil, nil, nil, 234, 234, 234, 234, nil, 234, 234, + 234, 234, nil, nil, nil, nil, 234, 234, nil, 235, + 235, 235, nil, 235, 234, nil, 234, 235, 235, nil, + nil, nil, 235, nil, 235, 235, 235, 235, 235, 235, + 235, nil, nil, nil, nil, nil, 235, 235, 235, 235, + 235, 235, 235, nil, nil, 235, nil, nil, nil, nil, + nil, nil, 235, nil, nil, 235, 235, 235, 235, 235, + 235, 235, 235, nil, 235, 235, 235, nil, 235, 235, + 235, 235, 235, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 235, nil, nil, 235, nil, nil, 235, 235, + nil, nil, 235, nil, nil, nil, nil, nil, 235, nil, + nil, nil, nil, nil, nil, nil, nil, 235, nil, nil, + nil, nil, 235, 235, 235, 235, nil, 235, 235, 235, + 235, nil, nil, nil, nil, 235, 235, nil, 236, 236, + 236, nil, 236, 235, nil, 235, 236, 236, nil, nil, + nil, 236, nil, 236, 236, 236, 236, 236, 236, 236, + nil, nil, nil, nil, nil, 236, 236, 236, 236, 236, + 236, 236, nil, nil, 236, nil, nil, nil, nil, nil, + nil, 236, nil, nil, 236, 236, 236, 236, 236, 236, + 236, 236, nil, 236, 236, 236, nil, 236, 236, 236, + 236, 236, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 236, nil, nil, 236, nil, nil, 236, 236, nil, + nil, 236, nil, nil, nil, nil, nil, 236, nil, nil, + nil, nil, nil, nil, nil, nil, 236, nil, nil, nil, + nil, 236, 236, 236, 236, nil, 236, 236, 236, 236, + nil, nil, nil, nil, 236, 236, nil, 237, 237, 237, + nil, 237, 236, nil, 236, 237, 237, nil, nil, nil, + 237, nil, 237, 237, 237, 237, 237, 237, 237, nil, + nil, nil, nil, nil, 237, 237, 237, 237, 237, 237, + 237, nil, nil, 237, nil, nil, nil, nil, nil, nil, + 237, nil, nil, 237, 237, 237, 237, 237, 237, 237, + 237, nil, 237, 237, 237, nil, 237, 237, 237, 237, + 237, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 237, nil, nil, 237, nil, nil, 237, 237, nil, nil, + 237, nil, nil, nil, nil, nil, 237, nil, nil, nil, + nil, nil, nil, nil, nil, 237, nil, nil, nil, nil, + 237, 237, 237, 237, nil, 237, 237, 237, 237, nil, + nil, nil, nil, 237, 237, nil, 238, 238, 238, nil, + 238, 237, nil, 237, 238, 238, nil, nil, nil, 238, + nil, 238, 238, 238, 238, 238, 238, 238, nil, nil, + nil, nil, nil, 238, 238, 238, 238, 238, 238, 238, + nil, nil, 238, nil, nil, nil, nil, nil, nil, 238, + nil, nil, 238, 238, 238, 238, 238, 238, 238, 238, + nil, 238, 238, 238, nil, 238, 238, 238, 238, 238, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 238, + nil, nil, 238, nil, nil, 238, 238, nil, nil, 238, + nil, nil, nil, nil, nil, 238, nil, nil, nil, nil, + nil, nil, nil, nil, 238, nil, nil, nil, nil, 238, + 238, 238, 238, nil, 238, 238, 238, 238, nil, nil, + nil, nil, 238, 238, nil, 239, 239, 239, nil, 239, + 238, nil, 238, 239, 239, nil, nil, nil, 239, nil, + 239, 239, 239, 239, 239, 239, 239, nil, nil, nil, + nil, nil, 239, 239, 239, 239, 239, 239, 239, nil, + nil, 239, nil, nil, nil, nil, nil, nil, 239, nil, + nil, 239, 239, 239, 239, 239, 239, 239, 239, nil, + 239, 239, 239, nil, 239, 239, 239, 239, 239, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 239, nil, + nil, 239, nil, nil, 239, 239, nil, nil, 239, nil, + nil, nil, nil, nil, 239, nil, nil, nil, nil, nil, + nil, nil, nil, 239, nil, nil, nil, nil, 239, 239, + 239, 239, nil, 239, 239, 239, 239, nil, nil, nil, + nil, 239, 239, nil, 240, 240, 240, nil, 240, 239, + nil, 239, 240, 240, nil, nil, nil, 240, nil, 240, + 240, 240, 240, 240, 240, 240, nil, nil, nil, nil, + nil, 240, 240, 240, 240, 240, 240, 240, nil, nil, + 240, nil, nil, nil, nil, nil, nil, 240, nil, nil, + 240, 240, 240, 240, 240, 240, 240, 240, nil, 240, + 240, 240, nil, 240, 240, 240, 240, 240, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 240, nil, nil, + 240, nil, nil, 240, 240, nil, nil, 240, nil, nil, + nil, nil, nil, 240, nil, nil, nil, nil, nil, nil, + nil, nil, 240, nil, nil, nil, nil, 240, 240, 240, + 240, nil, 240, 240, 240, 240, nil, nil, nil, nil, + 240, 240, nil, 241, 241, 241, nil, 241, 240, nil, + 240, 241, 241, nil, nil, nil, 241, nil, 241, 241, + 241, 241, 241, 241, 241, nil, nil, nil, nil, nil, + 241, 241, 241, 241, 241, 241, 241, nil, nil, 241, + nil, nil, nil, nil, nil, nil, 241, nil, nil, 241, + 241, 241, 241, 241, 241, 241, 241, nil, 241, 241, + 241, nil, 241, 241, 241, 241, 241, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 241, nil, nil, 241, + nil, nil, 241, 241, nil, nil, 241, nil, nil, nil, + nil, nil, 241, nil, nil, nil, nil, nil, nil, nil, + nil, 241, nil, nil, nil, nil, 241, 241, 241, 241, + nil, 241, 241, 241, 241, nil, nil, nil, nil, 241, + 241, nil, 242, 242, 242, nil, 242, 241, nil, 241, + 242, 242, nil, nil, nil, 242, nil, 242, 242, 242, + 242, 242, 242, 242, nil, nil, nil, nil, nil, 242, + 242, 242, 242, 242, 242, 242, nil, nil, 242, nil, + nil, nil, nil, nil, nil, 242, nil, nil, 242, 242, + 242, 242, 242, 242, 242, 242, nil, 242, 242, 242, + nil, 242, 242, 242, 242, 242, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 242, nil, nil, 242, nil, + nil, 242, 242, nil, nil, 242, nil, nil, nil, nil, + nil, 242, nil, nil, nil, nil, nil, nil, nil, nil, + 242, nil, nil, nil, nil, 242, 242, 242, 242, nil, + 242, 242, 242, 242, nil, nil, nil, nil, 242, 242, + nil, 243, 243, 243, nil, 243, 242, nil, 242, 243, + 243, nil, nil, nil, 243, nil, 243, 243, 243, 243, + 243, 243, 243, nil, nil, nil, nil, nil, 243, 243, + 243, 243, 243, 243, 243, nil, nil, 243, nil, nil, + nil, nil, nil, nil, 243, nil, nil, 243, 243, 243, + 243, 243, 243, 243, 243, nil, 243, 243, 243, nil, + 243, 243, 243, 243, 243, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 243, nil, nil, 243, nil, nil, + 243, 243, nil, nil, 243, nil, nil, nil, nil, nil, + 243, nil, nil, nil, nil, nil, nil, nil, nil, 243, + nil, nil, nil, nil, 243, 243, 243, 243, nil, 243, + 243, 243, 243, nil, nil, nil, nil, 243, 243, nil, + 244, 244, 244, nil, 244, 243, nil, 243, 244, 244, + nil, nil, nil, 244, nil, 244, 244, 244, 244, 244, + 244, 244, nil, nil, nil, nil, nil, 244, 244, 244, + 244, 244, 244, 244, nil, nil, 244, nil, nil, nil, + nil, nil, nil, 244, nil, nil, 244, 244, 244, 244, + 244, 244, 244, 244, nil, 244, 244, 244, nil, 244, + 244, 244, 244, 244, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 244, nil, nil, 244, nil, nil, 244, + 244, nil, nil, 244, nil, nil, nil, nil, nil, 244, + nil, nil, nil, nil, nil, nil, nil, nil, 244, nil, + nil, nil, nil, 244, 244, 244, 244, nil, 244, 244, + 244, 244, nil, nil, nil, nil, 244, 244, nil, 245, + 245, 245, nil, 245, 244, nil, 244, 245, 245, nil, + nil, nil, 245, nil, 245, 245, 245, 245, 245, 245, + 245, nil, nil, nil, nil, nil, 245, 245, 245, 245, + 245, 245, 245, nil, nil, 245, nil, nil, nil, nil, + nil, nil, 245, nil, nil, 245, 245, 245, 245, 245, + 245, 245, 245, nil, 245, 245, 245, nil, 245, 245, + 245, 245, 245, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 245, nil, nil, 245, nil, nil, 245, 245, + nil, nil, 245, nil, nil, nil, nil, nil, 245, nil, + nil, nil, nil, nil, nil, nil, nil, 245, nil, nil, + nil, nil, 245, 245, 245, 245, nil, 245, 245, 245, + 245, nil, nil, nil, nil, 245, 245, nil, 246, 246, + 246, nil, 246, 245, nil, 245, 246, 246, nil, nil, + nil, 246, nil, 246, 246, 246, 246, 246, 246, 246, + nil, nil, nil, nil, nil, 246, 246, 246, 246, 246, + 246, 246, nil, nil, 246, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 246, 246, 246, 246, 246, 246, + 246, 246, nil, 246, 246, 246, nil, 246, 246, 246, + 246, 246, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 246, nil, nil, 246, 246, nil, + nil, 246, nil, nil, nil, nil, nil, 246, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, nil, + nil, 246, 246, 246, 246, nil, 246, 246, 246, 246, + nil, nil, nil, nil, 246, 246, nil, 247, 247, 247, + nil, 247, 246, nil, 246, 247, 247, nil, nil, nil, + 247, nil, 247, 247, 247, 247, 247, 247, 247, nil, + nil, nil, nil, nil, 247, 247, 247, 247, 247, 247, + 247, nil, nil, 247, nil, nil, nil, nil, nil, nil, + 247, nil, nil, 247, 247, 247, 247, 247, 247, 247, + 247, nil, 247, 247, 247, nil, 247, 247, 247, 247, + 247, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 247, nil, nil, 247, nil, nil, 247, 247, nil, nil, + 247, nil, nil, nil, nil, nil, 247, nil, nil, nil, + nil, nil, nil, nil, nil, 247, nil, nil, nil, nil, + 247, 247, 247, 247, nil, 247, 247, 247, 247, nil, + nil, nil, nil, 247, 247, nil, 248, 248, 248, nil, + 248, 247, nil, 247, 248, 248, nil, nil, nil, 248, + nil, 248, 248, 248, 248, 248, 248, 248, nil, nil, + nil, nil, nil, 248, 248, 248, 248, 248, 248, 248, + nil, nil, 248, nil, nil, nil, nil, nil, nil, 248, + nil, nil, 248, 248, 248, 248, 248, 248, 248, 248, + nil, 248, 248, 248, nil, 248, 248, 248, 248, 248, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 248, + nil, nil, 248, nil, nil, 248, 248, nil, nil, 248, + nil, nil, nil, nil, nil, 248, nil, nil, nil, nil, + nil, nil, nil, nil, 248, nil, nil, nil, nil, 248, + 248, 248, 248, nil, 248, 248, 248, 248, nil, nil, + nil, nil, 248, 248, nil, 249, 249, 249, nil, 249, + 248, nil, 248, 249, 249, nil, nil, nil, 249, nil, + 249, 249, 249, 249, 249, 249, 249, nil, nil, nil, + nil, nil, 249, 249, 249, 249, 249, 249, 249, nil, + nil, 249, nil, nil, nil, nil, nil, nil, 249, nil, + nil, 249, 249, 249, 249, 249, 249, 249, 249, nil, + 249, 249, 249, nil, 249, 249, 249, 249, 249, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 249, nil, + nil, 249, nil, nil, 249, 249, nil, nil, 249, nil, + nil, nil, nil, nil, 249, nil, nil, nil, nil, nil, + nil, nil, nil, 249, nil, nil, nil, nil, 249, 249, + 249, 249, nil, 249, 249, 249, 249, nil, nil, nil, + nil, 249, 249, nil, 250, 250, 250, nil, 250, 249, + nil, 249, 250, 250, nil, nil, nil, 250, nil, 250, + 250, 250, 250, 250, 250, 250, nil, nil, nil, nil, + nil, 250, 250, 250, 250, 250, 250, 250, nil, nil, + 250, nil, nil, nil, nil, nil, nil, 250, nil, nil, + 250, 250, 250, 250, 250, 250, 250, 250, nil, 250, + 250, 250, nil, 250, 250, 250, 250, 250, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 250, nil, nil, + 250, nil, nil, 250, 250, nil, nil, 250, nil, nil, + nil, nil, nil, 250, nil, nil, nil, nil, nil, nil, + nil, nil, 250, nil, nil, nil, nil, 250, 250, 250, + 250, nil, 250, 250, 250, 250, nil, nil, nil, nil, + 250, 250, nil, 251, 251, 251, nil, 251, 250, nil, + 250, 251, 251, nil, nil, nil, 251, nil, 251, 251, + 251, 251, 251, 251, 251, nil, nil, nil, nil, nil, + 251, 251, 251, 251, 251, 251, 251, nil, nil, 251, + nil, nil, nil, nil, nil, nil, 251, nil, nil, 251, + 251, 251, 251, 251, 251, 251, 251, nil, 251, 251, + 251, nil, 251, 251, 251, 251, 251, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, 251, + nil, nil, 251, 251, nil, nil, 251, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 251, 251, 251, 251, + nil, 251, 251, 251, 251, nil, nil, nil, nil, 251, + 251, nil, 252, 252, 252, nil, 252, 251, nil, 251, + 252, 252, nil, nil, nil, 252, nil, 252, 252, 252, + 252, 252, 252, 252, nil, nil, nil, nil, nil, 252, + 252, 252, 252, 252, 252, 252, nil, nil, 252, nil, + nil, nil, nil, nil, nil, 252, nil, nil, 252, 252, + 252, 252, 252, 252, 252, 252, nil, 252, 252, 252, + nil, 252, 252, 252, 252, 252, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 252, nil, nil, 252, nil, + nil, 252, 252, nil, nil, 252, nil, nil, nil, nil, + nil, 252, nil, nil, nil, nil, nil, nil, nil, nil, + 252, nil, nil, nil, nil, 252, 252, 252, 252, nil, + 252, 252, 252, 252, nil, nil, nil, nil, 252, 252, + nil, 253, 253, 253, nil, 253, 252, nil, 252, 253, + 253, nil, nil, nil, 253, nil, 253, 253, 253, 253, + 253, 253, 253, nil, nil, nil, nil, nil, 253, 253, + 253, 253, 253, 253, 253, nil, nil, 253, nil, nil, + nil, nil, nil, nil, 253, nil, nil, 253, 253, 253, + 253, 253, 253, 253, 253, nil, 253, 253, 253, nil, + 253, 253, 253, 253, 253, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 253, nil, nil, 253, nil, nil, + 253, 253, nil, nil, 253, nil, nil, nil, nil, nil, + 253, nil, nil, nil, nil, nil, nil, nil, nil, 253, + nil, nil, nil, nil, 253, 253, 253, 253, nil, 253, + 253, 253, 253, nil, nil, nil, nil, 253, 253, nil, + 254, 254, 254, nil, 254, 253, nil, 253, 254, 254, + nil, nil, nil, 254, nil, 254, 254, 254, 254, 254, + 254, 254, nil, nil, nil, nil, nil, 254, 254, 254, + 254, 254, 254, 254, nil, nil, 254, nil, nil, nil, + nil, nil, nil, 254, nil, nil, 254, 254, 254, 254, + 254, 254, 254, 254, nil, 254, 254, 254, nil, 254, + 254, 254, 254, 254, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 254, nil, nil, 254, nil, nil, 254, + 254, nil, nil, 254, nil, nil, nil, nil, nil, 254, + nil, nil, nil, nil, nil, nil, nil, nil, 254, nil, + nil, nil, nil, 254, 254, 254, 254, nil, 254, 254, + 254, 254, nil, nil, nil, nil, 254, 254, nil, 255, + 255, 255, nil, 255, 254, nil, 254, 255, 255, nil, + nil, nil, 255, nil, 255, 255, 255, 255, 255, 255, + 255, nil, nil, nil, nil, nil, 255, 255, 255, 255, + 255, 255, 255, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 255, nil, nil, 255, 255, 255, 255, 255, + 255, 255, 255, nil, 255, 255, 255, nil, 255, 255, + 255, 255, 255, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 255, nil, nil, 255, nil, nil, 255, 255, + nil, nil, 255, nil, nil, nil, nil, nil, 255, nil, + nil, nil, nil, nil, nil, nil, nil, 255, nil, nil, + nil, nil, 255, 255, 255, 255, nil, 255, 255, 255, + 255, nil, nil, nil, nil, 255, 255, nil, 262, 262, + 262, nil, 262, 255, nil, 255, 262, 262, nil, nil, + nil, 262, nil, 262, 262, 262, 262, 262, 262, 262, + nil, nil, nil, nil, nil, 262, 262, 262, 262, 262, + 262, 262, nil, nil, 262, nil, nil, nil, nil, nil, + nil, 262, nil, nil, 262, 262, 262, 262, 262, 262, + 262, 262, 262, 262, 262, 262, nil, 262, 262, 262, + 262, 262, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 262, nil, nil, 262, nil, nil, 262, 262, nil, + nil, 262, nil, 262, nil, 262, nil, 262, nil, nil, + 262, nil, nil, nil, nil, nil, 262, nil, nil, nil, + nil, 262, 262, 262, 262, nil, 262, 262, 262, 262, + nil, nil, nil, nil, 262, 262, nil, 263, 263, 263, + nil, 263, 262, nil, 262, 263, 263, nil, nil, nil, + 263, nil, 263, 263, 263, 263, 263, 263, 263, nil, + nil, nil, nil, nil, 263, 263, 263, 263, 263, 263, + 263, nil, nil, 263, nil, nil, nil, nil, nil, nil, + 263, nil, nil, 263, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, nil, 263, 263, 263, 263, + 263, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 263, nil, nil, 263, nil, nil, 263, 263, nil, nil, + 263, nil, 263, nil, 263, nil, 263, nil, nil, 263, + nil, nil, nil, nil, nil, 263, nil, nil, nil, nil, + 263, 263, 263, 263, nil, 263, 263, 263, 263, nil, + nil, nil, nil, 263, 263, nil, 271, 271, 271, nil, + 271, 263, nil, 263, 271, 271, nil, nil, nil, 271, + nil, 271, 271, 271, 271, 271, 271, 271, nil, nil, + nil, nil, nil, 271, 271, 271, 271, 271, 271, 271, + nil, nil, 271, nil, nil, nil, nil, nil, nil, 271, + nil, nil, 271, 271, 271, 271, 271, 271, 271, 271, + 271, 271, 271, 271, nil, 271, 271, 271, 271, 271, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 271, + nil, nil, 271, nil, nil, 271, 271, nil, nil, 271, + nil, 271, nil, 271, nil, 271, nil, nil, 271, nil, + nil, nil, nil, nil, 271, nil, nil, nil, nil, 271, + 271, 271, 271, nil, 271, 271, 271, 271, nil, nil, + nil, nil, 271, 271, 271, 278, 278, 278, nil, 278, + 271, nil, 271, 278, 278, nil, nil, nil, 278, nil, + 278, 278, 278, 278, 278, 278, 278, nil, nil, nil, + nil, nil, 278, 278, 278, 278, 278, 278, 278, nil, + nil, 278, nil, nil, nil, nil, nil, nil, 278, nil, + nil, 278, 278, 278, 278, 278, 278, 278, 278, nil, + 278, 278, 278, nil, 278, 278, 278, 278, 278, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 278, nil, + nil, 278, nil, nil, 278, 278, nil, nil, 278, nil, + nil, nil, nil, nil, 278, nil, nil, nil, nil, nil, + nil, nil, nil, 278, nil, nil, nil, nil, 278, 278, + 278, 278, nil, 278, 278, 278, 278, nil, nil, nil, + nil, 278, 278, nil, 280, 280, 280, nil, 280, 278, + nil, 278, 280, 280, nil, nil, nil, 280, nil, 280, + 280, 280, 280, 280, 280, 280, nil, nil, nil, nil, + nil, 280, 280, 280, 280, 280, 280, 280, nil, nil, + 280, nil, nil, nil, nil, nil, nil, 280, nil, nil, + 280, 280, 280, 280, 280, 280, 280, 280, nil, 280, + 280, 280, nil, 280, 280, 280, 280, 280, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 280, nil, nil, + 280, nil, nil, 280, 280, nil, nil, 280, nil, nil, + nil, nil, nil, 280, nil, nil, nil, nil, nil, nil, + nil, nil, 280, nil, nil, nil, nil, 280, 280, 280, + 280, nil, 280, 280, 280, 280, nil, nil, nil, nil, + 280, 280, nil, 282, 282, 282, nil, 282, 280, nil, + 280, 282, 282, nil, nil, nil, 282, nil, 282, 282, + 282, 282, 282, 282, 282, nil, nil, nil, nil, nil, + 282, 282, 282, 282, 282, 282, 282, nil, nil, 282, + nil, nil, nil, nil, nil, nil, 282, nil, nil, 282, + 282, 282, 282, 282, 282, 282, 282, nil, 282, 282, + 282, nil, 282, 282, 282, 282, 282, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 282, nil, nil, 282, + nil, nil, 282, 282, nil, nil, 282, nil, nil, nil, + nil, nil, 282, nil, nil, nil, nil, nil, nil, nil, + nil, 282, nil, nil, nil, nil, 282, 282, 282, 282, + nil, 282, 282, 282, 282, nil, nil, nil, nil, 282, + 282, nil, 283, 283, 283, nil, 283, 282, nil, 282, + 283, 283, nil, nil, nil, 283, nil, 283, 283, 283, + 283, 283, 283, 283, nil, nil, nil, nil, nil, 283, + 283, 283, 283, 283, 283, 283, nil, nil, 283, nil, + nil, nil, nil, nil, nil, 283, nil, nil, 283, 283, + 283, 283, 283, 283, 283, 283, nil, 283, 283, 283, + nil, 283, 283, 283, 283, 283, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 283, nil, nil, 283, nil, + nil, 283, 283, nil, nil, 283, nil, nil, nil, nil, + nil, 283, nil, nil, nil, nil, nil, nil, nil, nil, + 283, nil, nil, nil, nil, 283, 283, 283, 283, nil, + 283, 283, 283, 283, nil, nil, nil, nil, 283, 283, + nil, 288, 288, 288, 288, 288, 283, nil, 283, 288, + 288, nil, nil, nil, 288, nil, 288, 288, 288, 288, + 288, 288, 288, nil, nil, nil, nil, nil, 288, 288, + 288, 288, 288, 288, 288, nil, nil, 288, nil, nil, + nil, nil, nil, 288, 288, nil, 288, 288, 288, 288, + 288, 288, 288, 288, 288, nil, 288, 288, 288, nil, + 288, 288, 288, 288, 288, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 288, nil, nil, 288, nil, nil, + 288, 288, nil, nil, 288, nil, 288, nil, nil, nil, + 288, nil, nil, nil, nil, nil, nil, nil, nil, 288, + nil, nil, nil, nil, 288, 288, 288, 288, nil, 288, + 288, 288, 288, nil, nil, nil, nil, 288, 288, nil, + 296, 296, 296, nil, 296, 288, nil, 288, 296, 296, + nil, nil, nil, 296, nil, 296, 296, 296, 296, 296, + 296, 296, nil, nil, nil, nil, nil, 296, 296, 296, + 296, 296, 296, 296, nil, nil, 296, nil, nil, nil, + nil, nil, nil, 296, nil, nil, 296, 296, 296, 296, + 296, 296, 296, 296, nil, 296, 296, 296, nil, 296, + 296, nil, nil, 296, 424, 424, 424, 424, 424, 424, + 424, 424, 424, 424, 424, nil, 424, 424, nil, nil, + 424, 424, nil, 296, nil, nil, 296, nil, nil, 296, + 296, nil, nil, 296, nil, nil, 424, nil, 424, nil, + 424, 424, nil, 424, 424, 424, 424, 424, nil, 424, + nil, nil, nil, 296, 296, 296, 296, nil, 296, 296, + 296, 296, nil, nil, nil, nil, 296, 296, nil, 424, + nil, 296, nil, nil, 296, nil, 296, 313, 313, 313, + nil, 313, nil, nil, nil, 313, 313, nil, nil, nil, + 313, nil, 313, 313, 313, 313, 313, 313, 313, nil, + nil, nil, nil, nil, 313, 313, 313, 313, 313, 313, + 313, nil, nil, 313, nil, nil, nil, nil, nil, nil, + 313, nil, nil, 313, 313, 313, 313, 313, 313, 313, + 313, nil, 313, 313, 313, nil, 313, 313, nil, nil, + 313, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 313, nil, nil, 313, nil, nil, 313, 313, nil, nil, + 313, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 313, 313, 313, 313, nil, 313, 313, 313, 313, nil, + nil, nil, nil, 313, 313, nil, 322, 322, 322, nil, + 322, 313, nil, 313, 322, 322, nil, nil, nil, 322, + nil, 322, 322, 322, 322, 322, 322, 322, nil, nil, + nil, nil, nil, 322, 322, 322, 322, 322, 322, 322, + nil, nil, 322, nil, nil, nil, nil, nil, nil, 322, + nil, nil, 322, 322, 322, 322, 322, 322, 322, 322, + nil, 322, 322, 322, nil, 322, 322, 322, 322, 322, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 322, + nil, nil, 322, 322, nil, 322, 322, nil, nil, 322, + nil, nil, nil, nil, nil, 322, nil, nil, nil, nil, + nil, nil, nil, nil, 322, nil, nil, nil, nil, 322, + 322, 322, 322, nil, 322, 322, 322, 322, nil, nil, + nil, nil, 322, 322, nil, 324, 324, 324, nil, 324, + 322, nil, 322, 324, 324, nil, nil, nil, 324, nil, + 324, 324, 324, 324, 324, 324, 324, nil, nil, nil, + nil, nil, 324, 324, 324, 324, 324, 324, 324, nil, + nil, 324, nil, nil, nil, nil, nil, nil, 324, nil, + nil, 324, 324, 324, 324, 324, 324, 324, 324, nil, + 324, 324, 324, nil, 324, 324, 324, 324, 324, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 324, nil, + nil, 324, nil, nil, 324, 324, nil, nil, 324, nil, + nil, nil, nil, nil, 324, nil, nil, nil, nil, nil, + nil, nil, nil, 324, nil, nil, nil, nil, 324, 324, + 324, 324, nil, 324, 324, 324, 324, nil, nil, nil, + nil, 324, 324, nil, 338, 338, 338, nil, 338, 324, + nil, 324, 338, 338, nil, nil, nil, 338, nil, 338, + 338, 338, 338, 338, 338, 338, nil, nil, nil, nil, + nil, 338, 338, 338, 338, 338, 338, 338, nil, nil, + 338, nil, nil, nil, nil, nil, nil, 338, nil, nil, + 338, 338, 338, 338, 338, 338, 338, 338, nil, 338, + 338, 338, nil, 338, 338, 338, 338, 338, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 338, nil, nil, + 338, nil, nil, 338, 338, nil, nil, 338, nil, nil, + nil, nil, nil, 338, nil, nil, nil, nil, nil, nil, + nil, nil, 338, nil, nil, nil, nil, 338, 338, 338, + 338, nil, 338, 338, 338, 338, nil, nil, nil, nil, + 338, 338, nil, 339, 339, 339, nil, 339, 338, nil, + 338, 339, 339, nil, nil, nil, 339, nil, 339, 339, + 339, 339, 339, 339, 339, nil, nil, nil, nil, nil, + 339, 339, 339, 339, 339, 339, 339, nil, nil, 339, + nil, nil, nil, nil, nil, nil, 339, nil, nil, 339, + 339, 339, 339, 339, 339, 339, 339, nil, 339, 339, + 339, nil, 339, 339, 339, 339, 339, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 339, nil, nil, 339, + nil, nil, 339, 339, nil, nil, 339, nil, nil, nil, + nil, nil, 339, nil, nil, nil, nil, nil, nil, nil, + nil, 339, nil, nil, nil, nil, 339, 339, 339, 339, + nil, 339, 339, 339, 339, nil, nil, nil, nil, 339, + 339, nil, 358, 358, 358, nil, 358, 339, nil, 339, + 358, 358, nil, nil, nil, 358, nil, 358, 358, 358, + 358, 358, 358, 358, nil, nil, nil, nil, nil, 358, + 358, 358, 358, 358, 358, 358, nil, nil, 358, nil, + nil, nil, nil, nil, nil, 358, nil, nil, 358, 358, + 358, 358, 358, 358, 358, 358, nil, 358, 358, 358, + nil, 358, 358, 358, 358, 358, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 358, nil, nil, 358, nil, + nil, 358, 358, nil, nil, 358, nil, nil, nil, nil, + nil, 358, nil, nil, nil, nil, nil, nil, nil, nil, + 358, nil, nil, nil, nil, 358, 358, 358, 358, nil, + 358, 358, 358, 358, nil, nil, nil, nil, 358, 358, + nil, 374, 374, 374, nil, 374, 358, nil, 358, 374, + 374, nil, nil, nil, 374, nil, 374, 374, 374, 374, + 374, 374, 374, nil, nil, nil, nil, nil, 374, 374, + 374, 374, 374, 374, 374, nil, nil, 374, nil, nil, + nil, nil, nil, nil, 374, nil, nil, 374, 374, 374, + 374, 374, 374, 374, 374, nil, 374, 374, 374, nil, + 374, 374, 374, 374, 374, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 374, nil, nil, 374, nil, nil, + 374, 374, nil, nil, 374, nil, nil, nil, nil, nil, + 374, nil, nil, nil, nil, nil, nil, nil, nil, 374, + nil, nil, nil, nil, 374, 374, 374, 374, nil, 374, + 374, 374, 374, nil, nil, nil, nil, 374, 374, nil, + 402, 402, 402, nil, 402, 374, nil, 374, 402, 402, + nil, nil, nil, 402, nil, 402, 402, 402, 402, 402, + 402, 402, nil, nil, nil, nil, nil, 402, 402, 402, + 402, 402, 402, 402, nil, nil, 402, nil, nil, nil, + nil, nil, nil, 402, nil, nil, 402, 402, 402, 402, + 402, 402, 402, 402, nil, 402, 402, 402, nil, 402, + 402, 402, 402, 402, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 402, nil, nil, 402, nil, nil, 402, + 402, nil, nil, 402, nil, nil, nil, nil, nil, 402, + nil, nil, nil, nil, nil, nil, nil, nil, 402, nil, + nil, nil, nil, 402, 402, 402, 402, nil, 402, 402, + 402, 402, nil, nil, nil, nil, 402, 402, nil, 439, + 439, 439, nil, 439, 402, nil, 402, 439, 439, nil, + nil, nil, 439, nil, 439, 439, 439, 439, 439, 439, + 439, nil, nil, nil, nil, nil, 439, 439, 439, 439, + 439, 439, 439, nil, nil, 439, nil, nil, nil, nil, + nil, nil, 439, nil, nil, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, nil, 439, 439, + 439, 439, 439, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 439, nil, nil, 439, nil, nil, 439, 439, + nil, nil, 439, nil, 439, nil, 439, nil, 439, nil, + nil, 439, nil, nil, nil, nil, nil, 439, nil, nil, + nil, nil, 439, 439, 439, 439, nil, 439, 439, 439, + 439, nil, nil, nil, nil, 439, 439, nil, 441, 441, + 441, nil, 441, 439, nil, 439, 441, 441, nil, nil, + nil, 441, nil, 441, 441, 441, 441, 441, 441, 441, + nil, nil, nil, nil, nil, 441, 441, 441, 441, 441, + 441, 441, nil, nil, 441, nil, nil, nil, nil, nil, + nil, 441, nil, nil, 441, 441, 441, 441, 441, 441, + 441, 441, nil, 441, 441, 441, nil, 441, 441, 441, + 441, 441, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 441, nil, nil, 441, nil, nil, 441, 441, nil, + nil, 441, nil, nil, nil, nil, nil, 441, nil, nil, + nil, nil, nil, nil, nil, nil, 441, nil, nil, nil, + nil, 441, 441, 441, 441, nil, 441, 441, 441, 441, + nil, nil, nil, nil, 441, 441, nil, 442, 442, 442, + nil, 442, 441, nil, 441, 442, 442, nil, nil, nil, + 442, nil, 442, 442, 442, 442, 442, 442, 442, nil, + nil, nil, nil, nil, 442, 442, 442, 442, 442, 442, + 442, nil, nil, 442, nil, nil, nil, nil, nil, nil, + 442, nil, nil, 442, 442, 442, 442, 442, 442, 442, + 442, nil, 442, 442, 442, nil, 442, 442, 442, 442, + 442, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 442, nil, nil, 442, nil, nil, 442, 442, nil, nil, + 442, nil, nil, nil, nil, nil, 442, nil, nil, nil, + nil, nil, nil, nil, nil, 442, nil, nil, nil, nil, + 442, 442, 442, 442, nil, 442, 442, 442, 442, nil, + nil, nil, nil, 442, 442, nil, 443, 443, 443, nil, + 443, 442, nil, 442, 443, 443, nil, nil, nil, 443, + nil, 443, 443, 443, 443, 443, 443, 443, nil, nil, + nil, nil, nil, 443, 443, 443, 443, 443, 443, 443, + nil, nil, 443, nil, nil, nil, nil, nil, nil, 443, + nil, nil, 443, 443, 443, 443, 443, 443, 443, 443, + nil, 443, 443, 443, nil, 443, 443, 443, 443, 443, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 443, + nil, nil, 443, nil, nil, 443, 443, nil, nil, 443, + nil, nil, nil, nil, nil, 443, nil, nil, nil, nil, + nil, nil, nil, nil, 443, nil, nil, nil, nil, 443, + 443, 443, 443, nil, 443, 443, 443, 443, nil, nil, + nil, nil, 443, 443, nil, 483, 483, 483, nil, 483, + 443, nil, 443, 483, 483, nil, nil, nil, 483, nil, + 483, 483, 483, 483, 483, 483, 483, nil, nil, nil, + nil, nil, 483, 483, 483, 483, 483, 483, 483, nil, + nil, 483, nil, nil, nil, nil, nil, nil, 483, nil, + nil, 483, 483, 483, 483, 483, 483, 483, 483, 483, + 483, 483, 483, nil, 483, 483, 483, 483, 483, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 483, nil, + nil, 483, nil, nil, 483, 483, nil, nil, 483, nil, + 483, nil, 483, nil, 483, nil, nil, 483, nil, nil, + nil, nil, nil, 483, nil, nil, nil, nil, 483, 483, + 483, 483, nil, 483, 483, 483, 483, nil, nil, nil, + nil, 483, 483, nil, 485, 485, 485, nil, 485, 483, + nil, 483, 485, 485, nil, nil, nil, 485, nil, 485, + 485, 485, 485, 485, 485, 485, nil, nil, nil, nil, + nil, 485, 485, 485, 485, 485, 485, 485, nil, nil, + 485, nil, nil, nil, nil, nil, nil, 485, nil, nil, + 485, 485, 485, 485, 485, 485, 485, 485, 485, 485, + 485, 485, nil, 485, 485, 485, 485, 485, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 485, nil, nil, + 485, nil, nil, 485, 485, nil, nil, 485, nil, nil, + nil, 485, nil, 485, nil, nil, 485, nil, nil, nil, + nil, nil, 485, nil, nil, nil, nil, 485, 485, 485, + 485, nil, 485, 485, 485, 485, nil, nil, nil, nil, + 485, 485, nil, 487, 487, 487, nil, 487, 485, nil, + 485, 487, 487, nil, nil, nil, 487, nil, 487, 487, + 487, 487, 487, 487, 487, nil, nil, nil, nil, nil, + 487, 487, 487, 487, 487, 487, 487, nil, nil, 487, + nil, nil, nil, nil, nil, nil, 487, nil, nil, 487, + 487, 487, 487, 487, 487, 487, 487, nil, 487, 487, + 487, nil, 487, 487, 487, 487, 487, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 487, nil, nil, 487, + nil, nil, 487, 487, nil, nil, 487, nil, nil, nil, + nil, nil, 487, nil, nil, nil, nil, nil, nil, nil, + nil, 487, nil, nil, nil, nil, 487, 487, 487, 487, + nil, 487, 487, 487, 487, nil, nil, nil, nil, 487, + 487, nil, 492, 492, 492, 492, 492, 487, nil, 487, + 492, 492, nil, nil, nil, 492, nil, 492, 492, 492, + 492, 492, 492, 492, nil, nil, nil, nil, nil, 492, + 492, 492, 492, 492, 492, 492, nil, nil, 492, nil, + nil, nil, nil, nil, 492, 492, 492, 492, 492, 492, + 492, 492, 492, 492, 492, 492, nil, 492, 492, 492, + nil, 492, 492, 492, 492, 492, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, nil, 469, 469, + nil, nil, 469, 469, nil, 492, nil, nil, 492, nil, + nil, 492, 492, nil, nil, 492, nil, 492, 469, nil, + 469, 492, 469, 469, nil, 469, 469, 469, 469, 469, + 492, 469, nil, nil, nil, 492, 492, 492, 492, nil, + 492, 492, 492, 492, nil, nil, nil, nil, 492, 492, + 469, 469, nil, nil, nil, 492, 492, nil, 492, 500, + 500, 500, nil, 500, nil, nil, nil, 500, 500, nil, + nil, nil, 500, nil, 500, 500, 500, 500, 500, 500, + 500, nil, nil, nil, nil, nil, 500, 500, 500, 500, + 500, 500, 500, nil, nil, 500, nil, nil, nil, nil, + nil, nil, 500, nil, nil, 500, 500, 500, 500, 500, + 500, 500, 500, nil, 500, 500, 500, nil, 500, 500, + nil, nil, 500, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 500, nil, nil, 500, nil, nil, 500, 500, + nil, nil, 500, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 500, 500, 500, 500, nil, 500, 500, 500, + 500, nil, nil, nil, nil, 500, 500, nil, 502, 502, + 502, nil, 502, 500, nil, 500, 502, 502, nil, nil, + nil, 502, nil, 502, 502, 502, 502, 502, 502, 502, + nil, nil, nil, nil, nil, 502, 502, 502, 502, 502, + 502, 502, nil, nil, 502, nil, nil, nil, nil, nil, + nil, 502, nil, nil, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, nil, 502, 502, 502, + 502, 502, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 502, nil, nil, 502, nil, nil, 502, 502, nil, + nil, 502, nil, 502, nil, 502, nil, 502, nil, nil, + 502, nil, nil, nil, nil, nil, 502, nil, nil, nil, + nil, 502, 502, 502, 502, nil, 502, 502, 502, 502, + nil, nil, nil, nil, 502, 502, nil, 509, 509, 509, + nil, 509, 502, nil, 502, 509, 509, nil, nil, nil, + 509, nil, 509, 509, 509, 509, 509, 509, 509, nil, + nil, nil, nil, nil, 509, 509, 509, 509, 509, 509, + 509, nil, nil, 509, nil, nil, nil, nil, nil, nil, + 509, nil, nil, 509, 509, 509, 509, 509, 509, 509, + 509, nil, 509, 509, 509, nil, 509, 509, nil, nil, + 509, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 509, nil, nil, 509, nil, nil, 509, 509, nil, nil, + 509, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 509, 509, 509, 509, nil, 509, 509, 509, 509, nil, + nil, nil, nil, 509, 509, nil, 512, 512, 512, nil, + 512, 509, nil, 509, 512, 512, nil, nil, nil, 512, + nil, 512, 512, 512, 512, 512, 512, 512, nil, nil, + nil, nil, nil, 512, 512, 512, 512, 512, 512, 512, + nil, nil, 512, nil, nil, nil, nil, nil, nil, 512, + nil, nil, 512, 512, 512, 512, 512, 512, 512, 512, + nil, 512, 512, 512, nil, 512, 512, 512, 512, 512, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 512, + nil, nil, 512, nil, nil, 512, 512, nil, nil, 512, + nil, nil, nil, nil, nil, 512, nil, nil, nil, nil, + nil, nil, nil, nil, 512, nil, nil, nil, nil, 512, + 512, 512, 512, nil, 512, 512, 512, 512, nil, nil, + nil, nil, 512, 512, nil, 513, 513, 513, nil, 513, + 512, nil, 512, 513, 513, nil, nil, nil, 513, nil, + 513, 513, 513, 513, 513, 513, 513, nil, nil, nil, + nil, nil, 513, 513, 513, 513, 513, 513, 513, nil, + nil, 513, nil, nil, nil, nil, nil, nil, 513, nil, + nil, 513, 513, 513, 513, 513, 513, 513, 513, nil, + 513, 513, 513, nil, 513, 513, 513, 513, 513, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 513, nil, + nil, 513, nil, nil, 513, 513, nil, nil, 513, nil, + nil, nil, nil, nil, 513, nil, nil, nil, nil, nil, + nil, nil, nil, 513, nil, nil, nil, nil, 513, 513, + 513, 513, nil, 513, 513, 513, 513, nil, nil, nil, + nil, 513, 513, nil, 514, 514, 514, nil, 514, 513, + nil, 513, 514, 514, nil, nil, nil, 514, nil, 514, + 514, 514, 514, 514, 514, 514, nil, nil, nil, nil, + nil, 514, 514, 514, 514, 514, 514, 514, nil, nil, + 514, nil, nil, nil, nil, nil, nil, 514, nil, nil, + 514, 514, 514, 514, 514, 514, 514, 514, nil, 514, + 514, 514, nil, 514, 514, 514, 514, 514, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 514, nil, nil, + 514, nil, nil, 514, 514, nil, nil, 514, nil, nil, + nil, nil, nil, 514, nil, nil, nil, nil, nil, nil, + nil, nil, 514, nil, nil, nil, nil, 514, 514, 514, + 514, nil, 514, 514, 514, 514, nil, nil, nil, nil, + 514, 514, nil, 518, 518, 518, nil, 518, 514, nil, + 514, 518, 518, nil, nil, nil, 518, nil, 518, 518, + 518, 518, 518, 518, 518, nil, nil, nil, nil, nil, + 518, 518, 518, 518, 518, 518, 518, nil, nil, 518, + nil, nil, nil, nil, nil, nil, 518, nil, nil, 518, + 518, 518, 518, 518, 518, 518, 518, nil, 518, 518, + 518, nil, 518, 518, 518, 518, 518, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 518, nil, nil, 518, + nil, nil, 518, 518, nil, nil, 518, nil, nil, nil, + nil, nil, 518, nil, nil, nil, nil, nil, nil, nil, + nil, 518, nil, nil, nil, nil, 518, 518, 518, 518, + nil, 518, 518, 518, 518, nil, nil, nil, nil, 518, + 518, nil, 524, 524, 524, nil, 524, 518, nil, 518, + 524, 524, nil, nil, nil, 524, nil, 524, 524, 524, + 524, 524, 524, 524, nil, nil, nil, nil, nil, 524, + 524, 524, 524, 524, 524, 524, nil, nil, 524, nil, + nil, nil, nil, nil, nil, 524, nil, nil, 524, 524, + 524, 524, 524, 524, 524, 524, 524, 524, 524, 524, + nil, 524, 524, 524, 524, 524, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 524, nil, nil, 524, nil, + nil, 524, 524, nil, nil, 524, nil, 524, nil, nil, + nil, 524, nil, nil, 524, nil, nil, nil, nil, nil, + 524, nil, nil, nil, nil, 524, 524, 524, 524, nil, + 524, 524, 524, 524, nil, nil, nil, nil, 524, 524, + nil, 527, 527, 527, nil, 527, 524, nil, 524, 527, + 527, nil, nil, nil, 527, nil, 527, 527, 527, 527, + 527, 527, 527, nil, nil, nil, nil, nil, 527, 527, + 527, 527, 527, 527, 527, nil, nil, 527, nil, nil, + nil, nil, nil, nil, 527, nil, nil, 527, 527, 527, + 527, 527, 527, 527, 527, 527, 527, 527, 527, nil, + 527, 527, 527, 527, 527, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 527, nil, nil, 527, nil, nil, + 527, 527, nil, nil, 527, nil, nil, nil, nil, nil, + 527, nil, nil, 527, nil, nil, nil, nil, nil, 527, + nil, nil, nil, nil, 527, 527, 527, 527, nil, 527, + 527, 527, 527, nil, nil, nil, nil, 527, 527, nil, + 541, 541, 541, nil, 541, 527, nil, 527, 541, 541, + nil, nil, nil, 541, nil, 541, 541, 541, 541, 541, + 541, 541, nil, nil, nil, nil, nil, 541, 541, 541, + 541, 541, 541, 541, nil, nil, 541, nil, nil, nil, + nil, nil, nil, 541, nil, nil, 541, 541, 541, 541, + 541, 541, 541, 541, nil, 541, 541, 541, nil, 541, + 541, 541, 541, 541, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 541, nil, nil, 541, nil, nil, 541, + 541, nil, nil, 541, nil, 541, nil, nil, nil, 541, + nil, nil, nil, nil, nil, nil, nil, nil, 541, nil, + nil, nil, nil, 541, 541, 541, 541, nil, 541, 541, + 541, 541, nil, nil, nil, nil, 541, 541, nil, 542, + 542, 542, nil, 542, 541, nil, 541, 542, 542, nil, + nil, nil, 542, nil, 542, 542, 542, 542, 542, 542, + 542, nil, nil, nil, nil, nil, 542, 542, 542, 542, + 542, 542, 542, nil, nil, 542, nil, nil, nil, nil, + nil, nil, 542, nil, nil, 542, 542, 542, 542, 542, + 542, 542, 542, 542, 542, 542, 542, nil, 542, 542, + 542, 542, 542, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 542, nil, nil, 542, nil, nil, 542, 542, + nil, nil, 542, nil, 542, nil, 542, nil, 542, nil, + nil, 542, nil, nil, nil, nil, nil, 542, nil, nil, + nil, nil, 542, 542, 542, 542, nil, 542, 542, 542, + 542, nil, nil, nil, nil, 542, 542, nil, 552, 552, + 552, nil, 552, 542, nil, 542, 552, 552, nil, nil, + nil, 552, nil, 552, 552, 552, 552, 552, 552, 552, + nil, nil, nil, nil, nil, 552, 552, 552, 552, 552, + 552, 552, nil, nil, 552, nil, nil, nil, nil, nil, + nil, 552, nil, nil, 552, 552, 552, 552, 552, 552, + 552, 552, 552, 552, 552, 552, nil, 552, 552, 552, + 552, 552, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 552, nil, nil, 552, nil, nil, 552, 552, nil, + nil, 552, nil, 552, nil, 552, nil, 552, nil, nil, + 552, nil, nil, nil, nil, nil, 552, nil, nil, nil, + nil, 552, 552, 552, 552, nil, 552, 552, 552, 552, + nil, nil, nil, nil, 552, 552, nil, 586, 586, 586, + nil, 586, 552, nil, 552, 586, 586, nil, nil, nil, + 586, nil, 586, 586, 586, 586, 586, 586, 586, nil, + nil, nil, nil, nil, 586, 586, 586, 586, 586, 586, + 586, nil, nil, 586, nil, nil, nil, nil, nil, nil, + 586, nil, nil, 586, 586, 586, 586, 586, 586, 586, + 586, nil, 586, 586, 586, nil, 586, 586, 586, 586, + 586, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 586, nil, nil, 586, nil, nil, 586, 586, nil, nil, + 586, nil, 586, nil, nil, nil, 586, nil, nil, nil, + nil, nil, nil, nil, nil, 586, nil, nil, nil, nil, + 586, 586, 586, 586, nil, 586, 586, 586, 586, nil, + nil, nil, nil, 586, 586, nil, 587, 587, 587, nil, + 587, 586, nil, 586, 587, 587, nil, nil, nil, 587, + nil, 587, 587, 587, 587, 587, 587, 587, nil, nil, + nil, nil, nil, 587, 587, 587, 587, 587, 587, 587, + nil, nil, 587, nil, nil, nil, nil, nil, nil, 587, + nil, nil, 587, 587, 587, 587, 587, 587, 587, 587, + nil, 587, 587, 587, nil, 587, 587, 587, 587, 587, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 587, + nil, nil, 587, nil, nil, 587, 587, nil, nil, 587, + nil, nil, nil, nil, nil, 587, nil, nil, nil, nil, + nil, nil, nil, nil, 587, nil, nil, nil, nil, 587, + 587, 587, 587, nil, 587, 587, 587, 587, nil, nil, + nil, nil, 587, 587, nil, 590, 590, 590, nil, 590, + 587, nil, 587, 590, 590, nil, nil, nil, 590, nil, + 590, 590, 590, 590, 590, 590, 590, nil, nil, nil, + nil, nil, 590, 590, 590, 590, 590, 590, 590, nil, + nil, 590, nil, nil, nil, nil, nil, nil, 590, nil, + nil, 590, 590, 590, 590, 590, 590, 590, 590, 590, + 590, 590, 590, nil, 590, 590, 590, 590, 590, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 590, nil, + nil, 590, nil, nil, 590, 590, nil, nil, 590, nil, + 590, nil, 590, nil, 590, nil, nil, 590, nil, nil, + nil, nil, nil, 590, nil, nil, nil, nil, 590, 590, + 590, 590, nil, 590, 590, 590, 590, nil, nil, nil, + nil, 590, 590, nil, 591, 591, 591, nil, 591, 590, + nil, 590, 591, 591, nil, nil, nil, 591, nil, 591, + 591, 591, 591, 591, 591, 591, nil, nil, nil, nil, + nil, 591, 591, 591, 591, 591, 591, 591, nil, nil, + 591, nil, nil, nil, nil, nil, nil, 591, nil, nil, + 591, 591, 591, 591, 591, 591, 591, 591, 591, 591, + 591, 591, nil, 591, 591, 591, 591, 591, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 591, nil, nil, + 591, nil, nil, 591, 591, nil, nil, 591, nil, nil, + nil, 591, nil, 591, nil, nil, 591, nil, nil, nil, + nil, nil, 591, nil, nil, nil, nil, 591, 591, 591, + 591, nil, 591, 591, 591, 591, nil, nil, nil, nil, + 591, 591, nil, 592, 592, 592, nil, 592, 591, nil, + 591, 592, 592, nil, nil, nil, 592, nil, 592, 592, + 592, 592, 592, 592, 592, nil, nil, nil, nil, nil, + 592, 592, 592, 592, 592, 592, 592, nil, nil, 592, + nil, nil, nil, nil, nil, nil, 592, nil, nil, 592, + 592, 592, 592, 592, 592, 592, 592, nil, 592, 592, + 592, nil, 592, 592, 592, 592, 592, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 592, nil, nil, 592, + nil, nil, 592, 592, nil, nil, 592, nil, nil, nil, + nil, nil, 592, nil, nil, nil, nil, nil, nil, nil, + nil, 592, nil, nil, nil, nil, 592, 592, 592, 592, + nil, 592, 592, 592, 592, nil, nil, nil, nil, 592, + 592, nil, 593, 593, 593, nil, 593, 592, nil, 592, + 593, 593, nil, nil, nil, 593, nil, 593, 593, 593, + 593, 593, 593, 593, nil, nil, nil, nil, nil, 593, + 593, 593, 593, 593, 593, 593, nil, nil, 593, nil, + nil, nil, nil, nil, nil, 593, nil, nil, 593, 593, + 593, 593, 593, 593, 593, 593, nil, 593, 593, 593, + nil, 593, 593, 593, 593, 593, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 593, nil, nil, 593, nil, + nil, 593, 593, nil, nil, 593, nil, nil, nil, nil, + nil, 593, nil, nil, nil, nil, nil, nil, nil, nil, + 593, nil, nil, nil, nil, 593, 593, 593, 593, nil, + 593, 593, 593, 593, nil, nil, nil, nil, 593, 593, + nil, 597, 597, 597, nil, 597, 593, nil, 593, 597, + 597, nil, nil, nil, 597, nil, 597, 597, 597, 597, + 597, 597, 597, nil, nil, nil, nil, nil, 597, 597, + 597, 597, 597, 597, 597, nil, nil, 597, nil, nil, + nil, nil, nil, nil, 597, nil, nil, 597, 597, 597, + 597, 597, 597, 597, 597, nil, 597, 597, 597, nil, + 597, 597, 597, 597, 597, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 597, nil, nil, 597, nil, nil, + 597, 597, nil, nil, 597, nil, nil, nil, nil, nil, + 597, nil, nil, nil, nil, nil, nil, nil, nil, 597, + nil, nil, nil, nil, 597, 597, 597, 597, nil, 597, + 597, 597, 597, nil, nil, nil, nil, 597, 597, nil, + 598, 598, 598, nil, 598, 597, nil, 597, 598, 598, + nil, nil, nil, 598, nil, 598, 598, 598, 598, 598, + 598, 598, nil, nil, nil, nil, nil, 598, 598, 598, + 598, 598, 598, 598, nil, nil, 598, nil, nil, nil, + nil, nil, nil, 598, nil, nil, 598, 598, 598, 598, + 598, 598, 598, 598, nil, 598, 598, 598, nil, 598, + 598, 598, 598, 598, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 598, nil, nil, 598, nil, nil, 598, + 598, nil, nil, 598, nil, nil, nil, nil, nil, 598, + nil, nil, nil, nil, nil, nil, nil, nil, 598, nil, + nil, nil, nil, 598, 598, 598, 598, nil, 598, 598, + 598, 598, nil, nil, nil, nil, 598, 598, nil, 601, + 601, 601, nil, 601, 598, nil, 598, 601, 601, nil, + nil, nil, 601, nil, 601, 601, 601, 601, 601, 601, + 601, nil, nil, nil, nil, nil, 601, 601, 601, 601, + 601, 601, 601, nil, nil, 601, nil, nil, nil, nil, + nil, nil, 601, nil, nil, 601, 601, 601, 601, 601, + 601, 601, 601, nil, 601, 601, 601, nil, 601, 601, + 601, 601, 601, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 601, nil, nil, 601, nil, nil, 601, 601, + nil, nil, 601, nil, nil, nil, nil, nil, 601, nil, + nil, nil, nil, nil, nil, nil, nil, 601, nil, nil, + nil, nil, 601, 601, 601, 601, nil, 601, 601, 601, + 601, nil, nil, nil, nil, 601, 601, nil, 602, 602, + 602, nil, 602, 601, nil, 601, 602, 602, nil, nil, + nil, 602, nil, 602, 602, 602, 602, 602, 602, 602, + nil, nil, nil, nil, nil, 602, 602, 602, 602, 602, + 602, 602, nil, nil, 602, nil, nil, nil, nil, nil, + nil, 602, nil, nil, 602, 602, 602, 602, 602, 602, + 602, 602, nil, 602, 602, 602, nil, 602, 602, 602, + 602, 602, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 602, nil, nil, 602, nil, nil, 602, 602, nil, + nil, 602, nil, nil, nil, nil, nil, 602, nil, nil, + nil, nil, nil, nil, nil, nil, 602, nil, nil, nil, + nil, 602, 602, 602, 602, nil, 602, 602, 602, 602, + nil, nil, nil, nil, 602, 602, nil, 626, 626, 626, + nil, 626, 602, nil, 602, 626, 626, nil, nil, nil, + 626, nil, 626, 626, 626, 626, 626, 626, 626, nil, + nil, nil, nil, nil, 626, 626, 626, 626, 626, 626, + 626, nil, nil, 626, nil, nil, nil, nil, nil, nil, + 626, nil, nil, 626, 626, 626, 626, 626, 626, 626, + 626, nil, 626, 626, 626, nil, 626, 626, 626, 626, + 626, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 626, nil, nil, 626, nil, nil, 626, 626, nil, nil, + 626, nil, nil, nil, nil, nil, 626, nil, nil, nil, + nil, nil, nil, nil, nil, 626, nil, nil, nil, nil, + 626, 626, 626, 626, nil, 626, 626, 626, 626, nil, + nil, nil, nil, 626, 626, nil, 632, 632, 632, nil, + 632, 626, nil, 626, 632, 632, nil, nil, nil, 632, + nil, 632, 632, 632, 632, 632, 632, 632, nil, nil, + nil, nil, nil, 632, 632, 632, 632, 632, 632, 632, + nil, nil, 632, nil, nil, nil, nil, nil, nil, 632, + nil, nil, 632, 632, 632, 632, 632, 632, 632, 632, + nil, 632, 632, 632, nil, 632, 632, nil, nil, 632, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 632, + nil, nil, 632, nil, nil, 632, 632, nil, nil, 632, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 632, + 632, 632, 632, nil, 632, 632, 632, 632, nil, nil, + nil, nil, 632, 632, nil, 643, 643, 643, nil, 643, + 632, nil, 632, 643, 643, nil, nil, nil, 643, nil, + 643, 643, 643, 643, 643, 643, 643, nil, nil, nil, + nil, nil, 643, 643, 643, 643, 643, 643, 643, nil, + nil, 643, nil, nil, nil, nil, nil, nil, 643, nil, + nil, 643, 643, 643, 643, 643, 643, 643, 643, nil, + 643, 643, 643, nil, 643, 643, nil, nil, 643, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 643, nil, + nil, 643, nil, nil, 643, 643, nil, nil, 643, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 643, 643, + 643, 643, nil, 643, 643, 643, 643, nil, nil, nil, + nil, 643, 643, nil, 649, 649, 649, nil, 649, 643, + nil, 643, 649, 649, nil, nil, nil, 649, nil, 649, + 649, 649, 649, 649, 649, 649, nil, nil, nil, nil, + nil, 649, 649, 649, 649, 649, 649, 649, nil, nil, + 649, nil, nil, nil, nil, nil, nil, 649, nil, nil, + 649, 649, 649, 649, 649, 649, 649, 649, nil, 649, + 649, 649, nil, 649, 649, 649, 649, 649, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 649, nil, nil, + 649, nil, nil, 649, 649, nil, nil, 649, nil, 649, + nil, nil, nil, 649, nil, nil, nil, nil, nil, nil, + nil, nil, 649, nil, nil, nil, nil, 649, 649, 649, + 649, nil, 649, 649, 649, 649, nil, nil, nil, nil, + 649, 649, nil, 673, 673, 673, nil, 673, 649, nil, + 649, 673, 673, nil, nil, nil, 673, nil, 673, 673, + 673, 673, 673, 673, 673, nil, nil, nil, nil, nil, + 673, 673, 673, 673, 673, 673, 673, nil, nil, 673, + nil, nil, nil, nil, nil, nil, 673, nil, nil, 673, + 673, 673, 673, 673, 673, 673, 673, nil, 673, 673, + 673, nil, 673, 673, 673, 673, 673, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 673, nil, nil, 673, + nil, nil, 673, 673, nil, nil, 673, nil, nil, nil, + nil, nil, 673, nil, nil, nil, nil, nil, nil, nil, + nil, 673, nil, nil, nil, nil, 673, 673, 673, 673, + nil, 673, 673, 673, 673, nil, nil, nil, nil, 673, + 673, nil, 700, 700, 700, nil, 700, 673, nil, 673, + 700, 700, nil, nil, nil, 700, nil, 700, 700, 700, + 700, 700, 700, 700, nil, nil, nil, nil, nil, 700, + 700, 700, 700, 700, 700, 700, nil, nil, 700, nil, + nil, nil, nil, nil, nil, 700, nil, nil, 700, 700, + 700, 700, 700, 700, 700, 700, nil, 700, 700, 700, + nil, 700, 700, 700, 700, 700, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 700, nil, nil, 700, nil, + nil, 700, 700, nil, nil, 700, nil, nil, nil, nil, + nil, 700, nil, nil, nil, nil, nil, nil, nil, nil, + 700, nil, nil, nil, nil, 700, 700, 700, 700, nil, + 700, 700, 700, 700, nil, nil, nil, nil, 700, 700, + nil, 706, 706, 706, nil, 706, 700, nil, 700, 706, + 706, nil, nil, nil, 706, nil, 706, 706, 706, 706, + 706, 706, 706, nil, nil, nil, nil, nil, 706, 706, + 706, 706, 706, 706, 706, nil, nil, 706, nil, nil, + nil, nil, nil, nil, 706, nil, nil, 706, 706, 706, + 706, 706, 706, 706, 706, nil, 706, 706, 706, nil, + 706, 706, 706, 706, 706, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 706, nil, nil, 706, nil, nil, + 706, 706, nil, nil, 706, nil, nil, nil, nil, nil, + 706, nil, nil, nil, nil, nil, nil, nil, nil, 706, + nil, nil, nil, nil, 706, 706, 706, 706, nil, 706, + 706, 706, 706, nil, nil, nil, nil, 706, 706, nil, + 729, 729, 729, nil, 729, 706, nil, 706, 729, 729, + nil, nil, nil, 729, nil, 729, 729, 729, 729, 729, + 729, 729, nil, nil, nil, nil, nil, 729, 729, 729, + 729, 729, 729, 729, nil, nil, 729, nil, nil, nil, + nil, nil, nil, 729, nil, nil, 729, 729, 729, 729, + 729, 729, 729, 729, nil, 729, 729, 729, nil, 729, + 729, 729, 729, 729, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 729, nil, nil, 729, nil, nil, 729, + 729, nil, nil, 729, nil, nil, nil, nil, nil, 729, + nil, nil, nil, nil, nil, nil, nil, nil, 729, nil, + nil, nil, nil, 729, 729, 729, 729, nil, 729, 729, + 729, 729, nil, nil, nil, nil, 729, 729, nil, 731, + 731, 731, nil, 731, 729, nil, 729, 731, 731, nil, + nil, nil, 731, nil, 731, 731, 731, 731, 731, 731, + 731, nil, nil, nil, nil, nil, 731, 731, 731, 731, + 731, 731, 731, nil, nil, 731, nil, nil, nil, nil, + nil, nil, 731, nil, nil, 731, 731, 731, 731, 731, + 731, 731, 731, nil, 731, 731, 731, nil, 731, 731, + 731, 731, 731, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 731, nil, nil, 731, nil, nil, 731, 731, + nil, nil, 731, nil, nil, nil, nil, nil, 731, nil, + nil, nil, nil, nil, nil, nil, nil, 731, nil, nil, + nil, nil, 731, 731, 731, 731, nil, 731, 731, 731, + 731, nil, nil, nil, nil, 731, 731, nil, 745, 745, + 745, nil, 745, 731, nil, 731, 745, 745, nil, nil, + nil, 745, nil, 745, 745, 745, 745, 745, 745, 745, + nil, nil, nil, nil, nil, 745, 745, 745, 745, 745, + 745, 745, nil, nil, 745, nil, nil, nil, nil, nil, + nil, 745, nil, nil, 745, 745, 745, 745, 745, 745, + 745, 745, nil, 745, 745, 745, nil, 745, 745, 745, + 745, 745, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 745, nil, nil, 745, nil, nil, 745, 745, nil, + nil, 745, nil, nil, nil, nil, nil, 745, nil, nil, + nil, nil, nil, nil, nil, nil, 745, nil, nil, nil, + nil, 745, 745, 745, 745, nil, 745, 745, 745, 745, + nil, nil, nil, nil, 745, 745, nil, 746, 746, 746, + nil, 746, 745, nil, 745, 746, 746, nil, nil, nil, + 746, nil, 746, 746, 746, 746, 746, 746, 746, nil, + nil, nil, nil, nil, 746, 746, 746, 746, 746, 746, + 746, nil, nil, 746, nil, nil, nil, nil, nil, nil, + 746, nil, nil, 746, 746, 746, 746, 746, 746, 746, + 746, nil, 746, 746, 746, nil, 746, 746, 746, 746, + 746, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 746, nil, nil, 746, nil, nil, 746, 746, nil, nil, + 746, nil, nil, nil, nil, nil, 746, nil, nil, nil, + nil, nil, nil, nil, nil, 746, nil, nil, nil, nil, + 746, 746, 746, 746, nil, 746, 746, 746, 746, nil, + nil, nil, nil, 746, 746, nil, 747, 747, 747, nil, + 747, 746, nil, 746, 747, 747, nil, nil, nil, 747, + nil, 747, 747, 747, 747, 747, 747, 747, nil, nil, + nil, nil, nil, 747, 747, 747, 747, 747, 747, 747, + nil, nil, 747, nil, nil, nil, nil, nil, nil, 747, + nil, nil, 747, 747, 747, 747, 747, 747, 747, 747, + nil, 747, 747, 747, nil, 747, 747, 747, 747, 747, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 747, + nil, nil, 747, nil, nil, 747, 747, nil, nil, 747, + nil, nil, nil, nil, nil, 747, nil, nil, nil, nil, + nil, nil, nil, nil, 747, nil, nil, nil, nil, 747, + 747, 747, 747, nil, 747, 747, 747, 747, nil, nil, + nil, nil, 747, 747, nil, 748, 748, 748, nil, 748, + 747, nil, 747, 748, 748, nil, nil, nil, 748, nil, + 748, 748, 748, 748, 748, 748, 748, nil, nil, nil, + nil, nil, 748, 748, 748, 748, 748, 748, 748, nil, + nil, 748, nil, nil, nil, nil, nil, nil, 748, nil, + nil, 748, 748, 748, 748, 748, 748, 748, 748, nil, + 748, 748, 748, nil, 748, 748, 748, 748, 748, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 748, nil, + nil, 748, nil, nil, 748, 748, nil, nil, 748, nil, + nil, nil, nil, nil, 748, nil, nil, nil, nil, nil, + nil, nil, nil, 748, nil, nil, nil, nil, 748, 748, + 748, 748, nil, 748, 748, 748, 748, nil, nil, nil, + nil, 748, 748, nil, 750, 750, 750, nil, 750, 748, + nil, 748, 750, 750, nil, nil, nil, 750, nil, 750, + 750, 750, 750, 750, 750, 750, nil, nil, nil, nil, + nil, 750, 750, 750, 750, 750, 750, 750, nil, nil, + 750, nil, nil, nil, nil, nil, nil, 750, nil, nil, + 750, 750, 750, 750, 750, 750, 750, 750, nil, 750, + 750, 750, nil, 750, 750, 750, 750, 750, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 750, nil, nil, + 750, nil, nil, 750, 750, nil, nil, 750, nil, nil, + nil, nil, nil, 750, nil, nil, nil, nil, nil, nil, + nil, nil, 750, nil, nil, nil, nil, 750, 750, 750, + 750, nil, 750, 750, 750, 750, nil, nil, nil, nil, + 750, 750, nil, 762, 762, 762, nil, 762, 750, nil, + 750, 762, 762, nil, nil, nil, 762, nil, 762, 762, + 762, 762, 762, 762, 762, nil, nil, nil, nil, nil, + 762, 762, 762, 762, 762, 762, 762, nil, nil, 762, + nil, nil, nil, nil, nil, nil, 762, nil, nil, 762, + 762, 762, 762, 762, 762, 762, 762, nil, 762, 762, + 762, nil, 762, 762, nil, nil, 762, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 762, nil, nil, 762, + nil, nil, 762, 762, nil, nil, 762, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 762, 762, 762, 762, + nil, 762, 762, 762, 762, nil, nil, nil, nil, 762, + 762, nil, 801, 801, 801, nil, 801, 762, nil, 762, + 801, 801, nil, nil, nil, 801, nil, 801, 801, 801, + 801, 801, 801, 801, nil, nil, nil, nil, nil, 801, + 801, 801, 801, 801, 801, 801, nil, nil, 801, nil, + nil, nil, nil, nil, nil, 801, nil, nil, 801, 801, + 801, 801, 801, 801, 801, 801, nil, 801, 801, 801, + nil, 801, 801, 801, 801, 801, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 801, nil, nil, 801, nil, + nil, 801, 801, nil, nil, 801, nil, nil, nil, nil, + nil, 801, nil, nil, nil, nil, nil, nil, nil, nil, + 801, nil, nil, nil, nil, 801, 801, 801, 801, nil, + 801, 801, 801, 801, nil, nil, nil, nil, 801, 801, + nil, 815, 815, 815, nil, 815, 801, nil, 801, 815, + 815, nil, nil, nil, 815, nil, 815, 815, 815, 815, + 815, 815, 815, nil, nil, nil, nil, nil, 815, 815, + 815, 815, 815, 815, 815, nil, nil, 815, nil, nil, + nil, nil, nil, nil, 815, nil, nil, 815, 815, 815, + 815, 815, 815, 815, 815, nil, 815, 815, 815, nil, + 815, 815, 815, 815, 815, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 815, nil, nil, 815, nil, nil, + 815, 815, nil, nil, 815, nil, nil, nil, nil, nil, + 815, nil, nil, nil, nil, nil, nil, nil, nil, 815, + nil, nil, nil, nil, 815, 815, 815, 815, nil, 815, + 815, 815, 815, nil, nil, nil, nil, 815, 815, nil, + 820, 820, 820, nil, 820, 815, nil, 815, 820, 820, + nil, nil, nil, 820, nil, 820, 820, 820, 820, 820, + 820, 820, nil, nil, nil, nil, nil, 820, 820, 820, + 820, 820, 820, 820, nil, nil, 820, nil, nil, nil, + nil, nil, nil, 820, nil, nil, 820, 820, 820, 820, + 820, 820, 820, 820, nil, 820, 820, 820, nil, 820, + 820, 820, 820, 820, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 820, nil, nil, 820, nil, nil, 820, + 820, nil, nil, 820, nil, 820, nil, nil, nil, 820, + nil, nil, nil, nil, nil, nil, nil, nil, 820, nil, + nil, nil, nil, 820, 820, 820, 820, nil, 820, 820, + 820, 820, nil, nil, nil, nil, 820, 820, nil, 837, + 837, 837, nil, 837, 820, nil, 820, 837, 837, nil, + nil, nil, 837, nil, 837, 837, 837, 837, 837, 837, + 837, nil, nil, nil, nil, nil, 837, 837, 837, 837, + 837, 837, 837, nil, nil, 837, nil, nil, nil, nil, + nil, nil, 837, nil, nil, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, nil, 837, 837, + 837, 837, 837, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 837, nil, nil, 837, nil, nil, 837, 837, + nil, nil, 837, nil, nil, nil, 837, nil, 837, nil, + nil, 837, nil, nil, nil, nil, nil, 837, nil, nil, + nil, nil, 837, 837, 837, 837, nil, 837, 837, 837, + 837, nil, nil, nil, nil, 837, 837, nil, 838, 838, + 838, nil, 838, 837, nil, 837, 838, 838, nil, nil, + nil, 838, nil, 838, 838, 838, 838, 838, 838, 838, + nil, nil, nil, nil, nil, 838, 838, 838, 838, 838, + 838, 838, nil, nil, 838, nil, nil, nil, nil, nil, + nil, 838, nil, nil, 838, 838, 838, 838, 838, 838, + 838, 838, nil, 838, 838, 838, nil, 838, 838, 838, + 838, 838, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 838, nil, nil, 838, nil, nil, 838, 838, nil, + nil, 838, nil, nil, nil, nil, nil, 838, nil, nil, + nil, nil, nil, nil, nil, nil, 838, nil, nil, nil, + nil, 838, 838, 838, 838, nil, 838, 838, 838, 838, + nil, nil, nil, nil, 838, 838, nil, 852, 852, 852, + nil, 852, 838, nil, 838, 852, 852, nil, nil, nil, + 852, nil, 852, 852, 852, 852, 852, 852, 852, nil, + nil, nil, nil, nil, 852, 852, 852, 852, 852, 852, + 852, nil, nil, 852, nil, nil, nil, nil, nil, nil, + 852, nil, nil, 852, 852, 852, 852, 852, 852, 852, + 852, nil, 852, 852, 852, nil, 852, 852, nil, nil, + 852, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 852, nil, nil, 852, nil, nil, 852, 852, nil, nil, + 852, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 852, 852, 852, 852, nil, 852, 852, 852, 852, nil, + nil, nil, nil, 852, 852, nil, 864, 864, 864, nil, + 864, 852, nil, 852, 864, 864, nil, nil, nil, 864, + nil, 864, 864, 864, 864, 864, 864, 864, nil, nil, + nil, nil, nil, 864, 864, 864, 864, 864, 864, 864, + nil, nil, 864, nil, nil, nil, nil, nil, nil, 864, + nil, nil, 864, 864, 864, 864, 864, 864, 864, 864, + nil, 864, 864, 864, nil, 864, 864, nil, nil, 864, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 864, + nil, nil, 864, nil, nil, 864, 864, nil, nil, 864, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 864, + 864, 864, 864, nil, 864, 864, 864, 864, nil, nil, + nil, nil, 864, 864, nil, 970, 970, 970, nil, 970, + 864, nil, 864, 970, 970, nil, nil, nil, 970, nil, + 970, 970, 970, 970, 970, 970, 970, nil, nil, nil, + nil, nil, 970, 970, 970, 970, 970, 970, 970, nil, + nil, 970, nil, nil, nil, nil, nil, nil, 970, nil, + nil, 970, 970, 970, 970, 970, 970, 970, 970, 970, + 970, 970, 970, nil, 970, 970, 970, 970, 970, 517, + 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, + nil, 517, 517, nil, nil, 517, 517, nil, 970, nil, + nil, 970, nil, nil, 970, 970, nil, nil, 970, nil, + 970, 517, 970, 517, 970, 517, 517, 970, 517, 517, + 517, 517, 517, 970, 517, nil, nil, nil, 970, 970, + 970, 970, nil, 970, 970, 970, 970, nil, nil, nil, + nil, 970, 970, nil, 517, 27, nil, nil, nil, 970, + nil, 970, 27, 27, 27, nil, nil, 27, 27, 27, + nil, 27, nil, nil, nil, nil, nil, nil, nil, nil, + 27, 27, 27, nil, nil, nil, nil, nil, nil, nil, + nil, 27, 27, nil, 27, 27, 27, 27, 27, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, nil, nil, 27, 27, 27, + nil, nil, 27, nil, 27, 27, nil, nil, 27, 27, + nil, 27, nil, 27, nil, 27, nil, 27, 27, nil, + 27, 27, 27, 27, 27, 28, 27, 27, 27, nil, + nil, nil, 28, 28, 28, nil, nil, 28, 28, 28, + nil, 28, 27, nil, nil, 27, 27, nil, 27, nil, + 27, 28, 28, nil, nil, nil, nil, nil, nil, nil, + nil, 28, 28, nil, 28, 28, 28, 28, 28, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, nil, nil, 28, 28, 28, + nil, nil, 28, nil, 28, 28, nil, nil, 28, 28, + nil, 28, nil, 28, nil, 28, nil, 28, 28, nil, + 28, 28, 28, 28, 28, nil, 28, 412, 28, nil, + nil, nil, nil, nil, 412, 412, 412, nil, nil, 412, + 412, 412, 28, 412, nil, 28, 28, nil, 28, nil, + 28, nil, 412, 412, 412, nil, nil, nil, nil, nil, + nil, nil, nil, 412, 412, nil, 412, 412, 412, 412, + 412, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 412, 412, 412, 412, 412, 412, 412, + 412, 412, 412, 412, 412, 412, 412, nil, nil, 412, + 412, 412, nil, nil, 412, nil, 412, 412, nil, nil, + 412, 412, nil, 412, nil, 412, nil, 412, nil, 412, + 412, nil, 412, 412, 412, 412, 412, nil, 412, 412, + 412, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 412, nil, 471, 412, 412, nil, + 412, nil, 412, 471, 471, 471, nil, nil, 471, 471, + 471, 613, 471, 613, 613, 613, 613, 613, nil, nil, + nil, 471, 471, nil, nil, nil, 613, nil, nil, nil, + nil, nil, 471, 471, nil, 471, 471, 471, 471, 471, + nil, nil, nil, nil, nil, nil, nil, nil, 613, nil, + 532, nil, 532, 532, 532, 532, 532, 613, 613, 613, + 613, nil, nil, nil, 613, 532, nil, nil, nil, nil, + nil, nil, nil, 471, nil, nil, nil, nil, nil, nil, + 471, nil, nil, nil, nil, 471, 471, 532, 532, nil, + 613, nil, nil, nil, nil, nil, 532, 532, 532, 532, + nil, nil, nil, 532, nil, nil, nil, nil, 471, 471, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 471, nil, nil, 471, nil, nil, nil, + nil, 471, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, nil, nil, nil, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, nil, + nil, nil, nil, nil, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, nil, 8, nil, nil, nil, nil, + nil, nil, nil, 8, 8, nil, 8, 8, 8, 8, + 8, 8, 8, nil, nil, 8, 8, nil, nil, nil, + 8, 8, 8, 8, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 8, 8, nil, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, nil, nil, 8, 8, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, nil, nil, nil, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, nil, nil, nil, + nil, nil, 9, 9, 9, 9, 9, 9, 9, 9, + 9, nil, nil, 9, nil, nil, nil, nil, nil, nil, + nil, 9, 9, nil, 9, 9, 9, 9, 9, 9, + 9, nil, nil, 9, 9, nil, nil, nil, 9, 9, + 9, 9, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 9, 9, nil, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + nil, nil, 9, 9, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 9, 393, 393, + 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, + 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, + 393, 393, nil, nil, nil, 393, 393, 393, 393, 393, + 393, 393, 393, 393, 393, nil, nil, nil, nil, nil, + 393, 393, 393, 393, 393, 393, 393, 393, 393, nil, + nil, 393, nil, nil, nil, nil, nil, nil, nil, 393, + 393, nil, 393, 393, 393, 393, 393, 393, 393, nil, + nil, 393, 393, nil, nil, nil, 393, 393, 393, 393, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 393, 393, nil, 393, 393, 393, 393, + 393, 393, 393, 393, 393, 393, 393, 393, nil, nil, + 393, 393, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 393, 583, 583, 583, 583, + 583, 583, 583, 583, 583, 583, 583, 583, 583, 583, + 583, 583, 583, 583, 583, 583, 583, 583, 583, 583, + nil, nil, nil, 583, 583, 583, 583, 583, 583, 583, + 583, 583, 583, nil, nil, nil, nil, nil, 583, 583, + 583, 583, 583, 583, 583, 583, 583, nil, nil, 583, + nil, nil, nil, nil, nil, nil, nil, 583, 583, nil, + 583, 583, 583, 583, 583, 583, 583, nil, nil, 583, + 583, nil, nil, nil, 583, 583, 583, 583, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 583, 583, nil, 583, 583, 583, 583, 583, 583, + 583, 583, 583, 583, 583, 583, nil, nil, 583, 583, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 583, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, nil, nil, + nil, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, nil, nil, nil, nil, nil, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, nil, 71, + nil, nil, nil, nil, nil, 71, 71, nil, 71, 71, + 71, 71, 71, 71, 71, nil, nil, 71, 71, nil, + nil, nil, 71, 71, 71, 71, nil, nil, nil, nil, + nil, 71, nil, nil, nil, nil, nil, nil, nil, 71, + 71, nil, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, nil, nil, 71, 713, 713, 713, + 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, + 713, 713, 713, 713, 713, 713, 713, 713, 713, 713, + 713, nil, nil, nil, 713, 713, 713, 713, 713, 713, + 713, 713, 713, 713, nil, nil, nil, nil, nil, 713, + 713, 713, 713, 713, 713, 713, 713, 713, nil, nil, + 713, nil, nil, nil, nil, nil, nil, nil, 713, 713, + nil, 713, 713, 713, 713, 713, 713, 713, nil, nil, + 713, 713, nil, nil, nil, 713, 713, 713, 713, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 713, 713, nil, 713, 713, 713, 713, 713, + 713, 713, 713, 713, 713, 713, 713, nil, nil, 713, + 644, 644, 644, 644, 644, 644, 644, 644, 644, 644, + 644, nil, 644, 644, nil, nil, 644, 644, nil, nil, + nil, nil, nil, 559, nil, 559, 559, 559, 559, 559, + nil, nil, 644, nil, 644, nil, 644, 644, 559, 644, + 644, 644, 644, 644, nil, 644, 730, 730, 730, 730, + 730, 730, 730, 730, 730, 730, 730, nil, 730, 730, + 559, 559, 730, 730, nil, 644, nil, nil, nil, 559, + 559, 559, 559, nil, nil, nil, 559, nil, 730, nil, + 730, nil, 730, 730, nil, 730, 730, 730, 730, 730, + nil, 730, 735, 735, 735, 735, 735, 735, 735, 735, + 735, 735, 735, nil, 735, 735, nil, nil, 735, 735, + nil, 730, 655, nil, 655, 655, 655, 655, 655, nil, + nil, nil, nil, nil, 735, nil, 735, 655, 735, 735, + nil, 735, 735, 735, 735, 735, nil, 735, 737, 737, + 737, 737, 737, 737, 737, 737, 737, 737, 737, 655, + 737, 737, nil, nil, 737, 737, nil, 735, 655, 655, + 655, 655, nil, nil, nil, 655, nil, nil, nil, nil, + 737, nil, 737, nil, 737, 737, nil, 737, 737, 737, + 737, 737, nil, 737, 740, 740, 740, 740, 740, 740, + 740, 740, 740, 740, 740, nil, 740, 740, nil, nil, + 740, 740, nil, 737, 711, nil, 711, 711, 711, 711, + 711, nil, nil, nil, nil, nil, 740, nil, 740, 711, + 740, 740, nil, 740, 740, 740, 740, 740, nil, 740, + 742, 742, 742, 742, 742, 742, 742, 742, 742, 742, + 742, 711, 742, 742, nil, nil, 742, 742, nil, 740, + 711, 711, 711, 711, nil, nil, nil, 711, nil, nil, + nil, nil, 742, nil, 742, nil, 742, 742, nil, 742, + 742, 742, 742, 742, nil, 742, 744, 744, 744, 744, + 744, 744, 744, 744, 744, 744, 744, nil, 744, 744, + nil, nil, 744, 744, nil, 742, 795, nil, 795, 795, + 795, 795, 795, nil, nil, nil, nil, nil, 744, nil, + 744, 795, 744, 744, nil, 744, 744, 744, 744, 744, + nil, 744, 836, 836, 836, 836, 836, 836, 836, 836, + 836, 836, 836, 795, 836, 836, nil, nil, 836, 836, + nil, 744, 795, 795, 795, 795, nil, nil, nil, 795, + nil, nil, nil, nil, 836, nil, 836, nil, 836, 836, + nil, 836, 836, 836, 836, 836, nil, 836, 839, 839, + 839, 839, 839, 839, 839, 839, 839, 839, 839, nil, + 839, 839, nil, nil, 839, 839, nil, 836, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 839, nil, 839, nil, 839, 839, nil, 839, 839, 839, + 839, 839, nil, 839, nil, nil, nil, nil, nil, 209, + 209, nil, nil, 209, nil, nil, nil, nil, nil, nil, + nil, 209, 209, 839, 209, 209, 209, 209, 209, 209, + 209, nil, nil, 209, 209, nil, nil, nil, 209, 209, + 209, 209, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, nil, nil, nil, 209, 209, nil, 209, 209, + 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, + 210, 210, 209, nil, 210, nil, nil, nil, nil, nil, + nil, nil, 210, 210, nil, 210, 210, 210, 210, 210, + 210, 210, nil, nil, 210, 210, nil, nil, nil, 210, + 210, 210, 210, nil, nil, nil, nil, nil, 210, nil, + nil, nil, nil, nil, nil, nil, 210, 210, nil, 210, + 210, 210, 210, 210, 210, 210, 210, 210, 210, 210, + 210, 258, 258, 210, nil, 258, nil, nil, nil, nil, + nil, nil, nil, 258, 258, nil, 258, 258, 258, 258, + 258, 258, 258, nil, nil, 258, 258, nil, nil, nil, + 258, 258, 258, 258, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 258, 258, nil, + 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, + 258, 258, 437, 437, 258, nil, 437, nil, nil, nil, + nil, nil, nil, nil, 437, 437, nil, 437, 437, 437, + 437, 437, 437, 437, nil, nil, 437, 437, nil, nil, + nil, 437, 437, 437, 437, nil, nil, nil, nil, nil, + 437, nil, nil, nil, nil, nil, nil, nil, 437, 437, + nil, 437, 437, 437, 437, 437, 437, 437, 437, 437, + 437, 437, 437, 438, 438, 437, nil, 438, nil, nil, + nil, nil, nil, nil, nil, 438, 438, nil, 438, 438, + 438, 438, 438, 438, 438, nil, nil, 438, 438, nil, + nil, nil, 438, 438, 438, 438, nil, nil, nil, nil, + nil, 438, nil, nil, nil, nil, nil, nil, nil, 438, + 438, nil, 438, 438, 438, 438, 438, 438, 438, 438, + 438, 438, 438, 438, 503, 503, 438, nil, 503, nil, + nil, nil, nil, nil, nil, nil, 503, 503, nil, 503, + 503, 503, 503, 503, 503, 503, nil, nil, 503, 503, + nil, nil, nil, 503, 503, 503, 503, nil, nil, nil, + nil, nil, 503, nil, nil, nil, nil, nil, nil, nil, + 503, 503, nil, 503, 503, 503, 503, 503, 503, 503, + 503, 503, 503, 503, 503, 504, 504, 503, nil, 504, + nil, nil, nil, nil, nil, nil, nil, 504, 504, nil, + 504, 504, 504, 504, 504, 504, 504, nil, nil, 504, + 504, nil, nil, nil, 504, 504, 504, 504, nil, nil, + nil, nil, nil, 504, nil, nil, nil, nil, nil, nil, + nil, 504, 504, nil, 504, 504, 504, 504, 504, 504, + 504, 504, 504, 504, 504, 504, 515, 515, 504, nil, + 515, nil, nil, nil, nil, nil, nil, nil, 515, 515, + nil, 515, 515, 515, 515, 515, 515, 515, nil, nil, + 515, 515, nil, nil, nil, 515, 515, 515, 515, nil, + nil, nil, nil, nil, 515, nil, nil, nil, nil, nil, + nil, nil, 515, 515, nil, 515, 515, 515, 515, 515, + 515, 515, 515, 515, 515, 515, 515, 516, 516, 515, + nil, 516, nil, nil, nil, nil, nil, nil, nil, 516, + 516, nil, 516, 516, 516, 516, 516, 516, 516, nil, + nil, 516, 516, nil, nil, nil, 516, 516, 516, 516, + nil, nil, nil, nil, nil, 516, nil, nil, nil, nil, + nil, nil, nil, 516, 516, nil, 516, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 543, 543, + 516, nil, 543, nil, nil, nil, nil, nil, nil, nil, + 543, 543, nil, 543, 543, 543, 543, 543, 543, 543, + nil, nil, 543, 543, nil, nil, nil, 543, 543, 543, + 543, nil, nil, nil, nil, nil, 543, nil, nil, nil, + nil, nil, nil, nil, 543, 543, nil, 543, 543, 543, + 543, 543, 543, 543, 543, 543, 543, 543, 543, 544, + 544, 543, nil, 544, nil, nil, nil, nil, nil, nil, + nil, 544, 544, nil, 544, 544, 544, 544, 544, 544, + 544, nil, nil, 544, 544, nil, nil, nil, 544, 544, + 544, 544, nil, nil, nil, nil, nil, 544, nil, nil, + nil, nil, nil, nil, nil, 544, 544, nil, 544, 544, + 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, + 550, 550, 544, nil, 550, nil, nil, nil, nil, nil, + nil, nil, 550, 550, nil, 550, 550, 550, 550, 550, + 550, 550, nil, nil, 550, 550, nil, nil, nil, 550, + 550, 550, 550, nil, nil, nil, nil, nil, 550, nil, + nil, nil, nil, nil, nil, nil, 550, 550, nil, 550, + 550, 550, 550, 550, 550, 550, 550, 550, 550, 550, + 550, 551, 551, 550, nil, 551, nil, nil, nil, nil, + nil, nil, nil, 551, 551, nil, 551, 551, 551, 551, + 551, 551, 551, nil, nil, 551, 551, nil, nil, nil, + 551, 551, 551, 551, nil, nil, nil, nil, nil, 551, + nil, nil, nil, nil, nil, nil, nil, 551, 551, nil, + 551, 551, 551, 551, 551, 551, 551, 551, 551, 551, + 551, 551, 917, 917, 551, nil, 917, nil, nil, nil, + nil, nil, nil, nil, 917, 917, nil, 917, 917, 917, + 917, 917, 917, 917, nil, nil, 917, 917, nil, nil, + nil, 917, 917, 917, 917, nil, nil, nil, nil, nil, + 917, nil, nil, nil, nil, nil, nil, nil, 917, 917, + nil, 917, 917, 917, 917, 917, 917, 917, 917, 917, + 917, 917, 917, 971, 971, 917, nil, 971, nil, nil, + nil, nil, nil, nil, nil, 971, 971, nil, 971, 971, + 971, 971, 971, 971, 971, nil, nil, 971, 971, nil, + nil, nil, 971, 971, 971, 971, nil, nil, nil, nil, + nil, 971, nil, nil, nil, nil, nil, nil, nil, 971, + 971, nil, 971, 971, 971, 971, 971, 971, 971, 971, + 971, 971, 971, 971, 972, 972, 971, nil, 972, nil, + nil, nil, nil, nil, nil, nil, 972, 972, nil, 972, + 972, 972, 972, 972, 972, 972, nil, nil, 972, 972, + nil, nil, nil, 972, 972, 972, 972, nil, nil, nil, + nil, nil, 972, nil, nil, nil, nil, nil, nil, nil, + 972, 972, nil, 972, 972, 972, 972, 972, 972, 972, + 972, 972, 972, 972, 972, nil, 797, 972, 797, 797, + 797, 797, 797, 799, nil, 799, 799, 799, 799, 799, + nil, 797, nil, nil, nil, nil, nil, 843, 799, 843, + 843, 843, 843, 843, nil, nil, nil, nil, nil, nil, + nil, nil, 843, 797, nil, nil, nil, nil, nil, nil, + 799, nil, 797, 797, 797, 797, nil, nil, nil, 797, + nil, 799, 799, nil, 843, nil, 799, nil, nil, nil, + nil, nil, nil, 843, 843, 843, 843, nil, nil, 845, + 843, 845, 845, 845, 845, 845, 847, nil, 847, 847, + 847, 847, 847, nil, 845, nil, nil, nil, nil, nil, + 900, 847, 900, 900, 900, 900, 900, nil, nil, nil, + nil, nil, nil, nil, nil, 900, 845, nil, nil, nil, + nil, nil, nil, 847, nil, 845, 845, 845, 845, nil, + nil, nil, 845, nil, 847, 847, nil, 900, 900, 847, + nil, nil, nil, nil, nil, nil, 900, 900, 900, 900, + nil, nil, 932, 900, 932, 932, 932, 932, 932, 934, + nil, 934, 934, 934, 934, 934, 936, 932, 936, 936, + 936, 936, 936, 938, 934, 938, 938, 938, 938, 938, + nil, 936, nil, nil, nil, nil, nil, nil, 938, 932, + nil, nil, nil, nil, nil, nil, 934, nil, 932, 932, + 932, 932, nil, 936, nil, 932, nil, 934, 934, nil, + 938, nil, 934, nil, 936, 936, nil, nil, nil, 936, + nil, 938, 938, nil, nil, 956, 938, 956, 956, 956, + 956, 956, 958, nil, 958, 958, 958, 958, 958, 960, + 956, 960, 960, 960, 960, 960, 962, 958, 962, 962, + 962, 962, 962, 998, 960, 998, 998, 998, 998, 998, + nil, 962, 956, nil, nil, nil, nil, nil, 998, 958, + nil, 956, 956, 956, 956, nil, 960, nil, 956, nil, + 958, 958, nil, 962, nil, 958, nil, 960, 960, nil, + 998, nil, 960, nil, 962, 962, nil, nil, nil, 962, + nil, 998, 998, nil, nil, 1008, 998, 1008, 1008, 1008, + 1008, 1008, nil, nil, nil, nil, nil, nil, nil, nil, + 1008, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1008, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 1008, 1008, nil, nil, nil, 1008 ] + +racc_action_pointer = [ + 0, 125, nil, 24, nil, 5042, 1141, 39, 22340, 22468, + 84, nil, 75, 220, 360, 247, 192, 439, nil, 25, + 5171, 6856, 331, nil, 111, nil, 55, 21855, 21965, 5300, + 5429, 5558, nil, 758, 5687, 5816, nil, 257, 280, 282, + 390, 485, 5953, 6082, 6211, 317, 559, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 890, nil, 67, 6340, + 6469, 0, nil, 6598, 6727, nil, nil, 6856, 6993, 7122, + 7251, 22852, nil, nil, nil, nil, nil, nil, nil, 656, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 0, nil, nil, 134, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 460, nil, + 7380, nil, nil, nil, nil, 7517, 7646, 7775, 7904, 8033, + 1027, nil, 595, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 375, nil, 1156, 8162, 8291, 8420, 23448, + 23509, 8549, 8678, 8807, 8936, 9065, 9194, nil, nil, 589, + 83, 107, 465, 139, 390, 488, nil, 9323, 1285, 524, + 9452, 9581, 9710, 9839, 9968, 10097, 10226, 10355, 10484, 10613, + 10742, 10871, 11000, 11129, 11258, 11387, 11516, 11645, 11774, 11903, + 12032, 12161, 12290, 12419, 12548, 12677, nil, nil, 23570, nil, + nil, 525, 12806, 12935, nil, nil, nil, nil, nil, nil, + nil, 13064, nil, 7380, nil, 492, 507, nil, 13193, 570, + 13322, nil, 13451, 13580, nil, nil, 57, nil, 13709, 1156, + 555, 540, 1414, 551, 593, 571, 13838, 1543, 591, 758, + 761, 653, 800, nil, 627, 588, 79, nil, nil, nil, + 640, 504, 607, 13975, nil, 318, 679, 681, 808, nil, + 687, nil, 14104, 1672, 14233, 625, nil, 243, 258, 663, + 652, 344, 683, nil, nil, 564, 133, 140, 14362, 14491, + 343, 758, 648, 32, 57, 844, 731, 65, 771, nil, + nil, 359, 395, 449, nil, 931, nil, 59, 14620, nil, + nil, nil, 142, 310, 419, 464, 465, 493, 565, 567, + 630, nil, 657, nil, 14749, nil, 356, 479, 484, 513, + 539, 59, 89, 546, nil, nil, nil, nil, nil, nil, + nil, nil, 701, 22596, nil, nil, nil, nil, 705, nil, + 706, nil, 14878, 711, nil, 1672, 722, nil, 724, 729, + 384, 447, 22077, nil, nil, nil, 244, 356, 783, nil, + nil, 1804, 1938, nil, 13838, nil, 743, nil, nil, 758, + nil, nil, nil, nil, 218, nil, 798, 23631, 23692, 15007, + 143, 15136, 15265, 15394, 1027, 1156, 873, 904, 829, 834, + 844, 846, 2978, 3107, 3236, 1285, 1414, 1543, 1753, 1887, + 2075, 2204, 2333, 2462, 2591, 633, 817, 2720, 2849, 15910, + 90, 22206, nil, nil, nil, nil, 783, nil, 269, 293, + 784, nil, nil, 15523, nil, 15652, nil, 15781, nil, nil, + nil, nil, 15910, 1270, 2075, 794, 792, nil, nil, 801, + 16047, 805, 16176, 23753, 23814, 942, 847, nil, nil, 16305, + 805, nil, 16434, 16563, 16692, 23875, 23936, 21723, 16821, 933, + 937, 761, 860, nil, 16950, nil, nil, 17079, nil, nil, + nil, nil, 22209, 2204, 943, nil, 2333, 158, 205, 963, + 972, 17208, 17337, 23997, 24058, 100, nil, nil, 959, nil, + 24119, 24180, 17466, nil, nil, nil, 415, 271, 2462, 23052, + nil, 288, nil, nil, nil, 895, nil, nil, nil, 863, + nil, nil, 381, nil, 406, nil, nil, 851, nil, 855, + nil, nil, nil, 22724, nil, 858, 17595, 17724, 490, 900, + 17853, 17982, 18111, 18240, 904, nil, nil, 18369, 18498, 908, + nil, 18627, 18756, nil, nil, 152, 170, 485, 619, 875, + 5816, 877, nil, 22170, nil, 2591, 984, 74, 308, nil, + 2720, 2849, nil, 885, nil, 947, 18885, nil, nil, nil, + 926, 206, 19014, 907, nil, 911, 199, 270, 962, 425, + 1027, 964, 921, 19143, 23014, 989, 997, 325, 1055, 19272, + nil, 953, nil, 386, 98, 23141, nil, 954, 975, nil, + 980, 984, 988, nil, nil, nil, nil, nil, nil, 987, + nil, 623, nil, 19401, nil, nil, nil, 1080, nil, nil, + nil, 1088, nil, nil, 1089, 786, nil, 1127, nil, nil, + nil, nil, 1137, nil, 144, 1021, 116, 129, 159, 252, + 19530, 518, 1156, nil, 1022, 2978, 19659, nil, nil, 1144, + 3107, 23233, 454, 22965, nil, nil, nil, nil, nil, nil, + 3236, nil, nil, nil, nil, nil, nil, nil, 1021, 19788, + 23060, 19917, nil, 1031, nil, 23106, nil, 23152, nil, nil, + 23198, nil, 23244, nil, 23290, 20046, 20175, 20304, 20433, 250, + 20562, 1035, 1036, nil, 1037, 1039, 1059, nil, 1084, 1082, + 1081, 1098, 20691, nil, nil, 1233, nil, nil, 3365, 1133, + 1241, nil, nil, nil, 1122, 557, nil, nil, 1252, nil, + 3494, 1135, 1182, nil, nil, 1180, nil, nil, nil, nil, + 1145, 644, nil, nil, 748, 23325, nil, 24425, nil, 24432, + nil, 20820, nil, 854, nil, 1147, 357, nil, 1151, nil, + nil, nil, nil, 1273, nil, 20949, 1274, 3623, 3752, nil, + 21078, 3881, 139, 224, nil, 1284, 607, 4010, nil, 1288, + 1168, nil, nil, 1172, 1168, nil, 23336, 21207, 21336, 23382, + 667, nil, nil, 24446, nil, 24498, nil, 24505, nil, nil, + 1212, 959, 21465, 1030, 1272, nil, 1228, nil, nil, nil, + 4139, nil, nil, 160, 21594, nil, nil, 4268, 4397, 1255, + 1230, nil, nil, nil, 1231, 1233, nil, 1238, 1239, nil, + 1242, nil, 1249, 890, 1248, 1271, nil, nil, 166, nil, + 1375, 1380, nil, 391, nil, nil, nil, 1388, nil, nil, + 24519, nil, 1265, nil, nil, 1266, 1271, 1276, 1277, nil, + 1278, nil, 652, nil, nil, nil, 1159, 24241, nil, nil, + nil, 4526, 1281, 1285, 1417, 1357, 1526, nil, 1309, 1417, + nil, nil, 24571, nil, 24578, nil, 24585, nil, 24592, nil, + nil, nil, nil, 481, 1400, 1294, 4655, nil, nil, nil, + nil, nil, 4784, nil, 4913, nil, 24644, nil, 24651, nil, + 24658, nil, 24665, nil, nil, nil, 1013, 1339, 1341, 1431, + 21723, 24302, 24363, 1534, nil, nil, 1306, 1307, 1308, 1309, + 1317, 1430, 1323, 1438, 857, 1461, 1465, 1349, 1353, 1357, + 1365, nil, nil, 1370, 167, 168, 170, 1672, 24672, nil, + nil, nil, nil, 1529, 1370, nil, nil, nil, 24724, nil, + nil, nil, nil, 169, 1371, 1374, 1375, nil, nil ] + +racc_action_default = [ + -3, -591, -1, -577, -4, -591, -7, -591, -591, -591, + -591, -29, -591, -591, -591, -279, -591, -41, -44, -579, + -591, -49, -51, -52, -53, -57, -258, -258, -258, -293, + -329, -330, -69, -11, -73, -81, -83, -591, -488, -489, + -591, -591, -591, -591, -591, -579, -239, -270, -271, -272, + -273, -274, -275, -276, -277, -278, -567, -281, -283, -590, + -558, -301, -303, -591, -591, -307, -310, -577, -591, -591, + -591, -591, -331, -332, -334, -335, -431, -432, -433, -434, + -435, -456, -438, -439, -458, -460, -443, -448, -452, -454, + -470, -458, -472, -473, -565, -477, -478, -566, -480, -481, + -482, -483, -484, -485, -486, -487, -492, -493, -591, -2, + -578, -586, -587, -588, -6, -591, -591, -591, -591, -591, + -3, -17, -591, -112, -113, -114, -115, -116, -117, -118, + -119, -120, -124, -125, -126, -127, -128, -129, -130, -131, + -132, -133, -134, -135, -136, -137, -138, -139, -140, -141, + -142, -143, -144, -145, -146, -147, -148, -149, -150, -151, + -152, -153, -154, -155, -156, -157, -158, -159, -160, -161, + -162, -163, -164, -165, -166, -167, -168, -169, -170, -171, + -172, -173, -174, -175, -176, -177, -178, -179, -180, -181, + -182, -183, -184, -185, -186, -187, -188, -189, -190, -191, + -192, -193, -194, -22, -121, -11, -591, -591, -248, -591, + -591, -591, -591, -591, -591, -591, -579, -580, -48, -591, + -488, -489, -591, -279, -591, -591, -231, -591, -11, -591, + -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, + -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, + -591, -591, -591, -591, -591, -591, -400, -402, -591, -575, + -576, -58, -248, -591, -300, -406, -415, -417, -64, -412, + -65, -579, -66, -240, -253, -262, -262, -257, -591, -263, + -591, -560, -591, -591, -67, -68, -577, -12, -591, -15, + -591, -71, -11, -579, -591, -74, -77, -11, -89, -90, + -591, -591, -97, -293, -296, -579, -591, -329, -330, -333, + -413, -591, -79, -591, -85, -290, -474, -475, -591, -216, + -217, -232, -591, -11, -591, -579, -241, -583, -583, -591, + -591, -583, -591, -302, -392, -50, -591, -591, -591, -591, + -577, -591, -578, -488, -489, -591, -591, -279, -591, -345, + -346, -107, -108, -591, -110, -591, -279, -591, -591, -488, + -489, -322, -112, -113, -154, -155, -156, -172, -177, -184, + -187, -324, -591, -556, -591, -436, -591, -591, -591, -591, + -591, -591, -591, -591, 1019, -5, -589, -23, -24, -25, + -26, -27, -591, -591, -19, -20, -21, -122, -591, -30, + -39, -40, -591, -591, -31, -197, -579, -249, -262, -262, + -568, -569, -258, -410, -570, -571, -569, -568, -258, -409, + -411, -570, -571, -37, -205, -38, -591, -42, -43, -195, + -263, -45, -46, -47, -579, -299, -591, -591, -591, -248, + -290, -591, -591, -591, -206, -207, -208, -209, -210, -211, + -212, -213, -218, -219, -220, -221, -222, -223, -224, -225, + -226, -227, -228, -229, -230, -233, -234, -235, -236, -579, + -381, -258, -568, -569, -55, -59, -579, -259, -381, -381, + -579, -295, -254, -591, -255, -591, -260, -591, -264, -563, + -564, -10, -578, -14, -3, -579, -70, -288, -86, -75, + -591, -579, -248, -591, -591, -96, -591, -474, -475, -591, + -82, -87, -591, -591, -591, -591, -591, -237, -591, -423, + -591, -284, -591, -242, -585, -584, -244, -585, -291, -292, + -559, -304, -520, -11, -336, -337, -11, -591, -591, -591, + -591, -591, -248, -591, -591, -290, -315, -107, -108, -109, + -591, -591, -248, -318, -494, -495, -591, -591, -11, -520, + -326, -579, -437, -457, -462, -591, -464, -440, -459, -591, + -461, -442, -591, -445, -591, -447, -450, -591, -451, -591, + -471, -8, -18, -591, -28, -269, -591, -591, -414, -591, + -250, -252, -591, -591, -60, -247, -407, -591, -591, -62, + -408, -591, -591, -298, -581, -568, -569, -568, -569, -579, + -195, -591, -382, -579, -384, -11, -54, -403, -381, -245, + -11, -11, -294, -262, -261, -265, -591, -561, -562, -13, + -591, -72, -591, -78, -84, -579, -568, -569, -246, -93, + -95, -591, -80, -591, -204, -214, -215, -579, -590, -590, + -282, -579, -287, -583, -591, -520, -395, -555, -555, -503, + -505, -505, -505, -519, -521, -522, -523, -524, -525, -526, + -527, -591, -529, -591, -535, -537, -538, -540, -545, -547, + -548, -550, -551, -552, -591, -590, -338, -590, -308, -339, + -340, -311, -591, -314, -591, -579, -568, -569, -572, -289, + -591, -107, -108, -111, -579, -11, -591, -497, -320, -591, + -11, -520, -591, -591, -557, -463, -466, -467, -468, -469, + -11, -441, -444, -446, -449, -453, -455, -123, -267, -591, + -198, -591, -582, -262, -33, -200, -34, -201, -61, -35, + -203, -36, -202, -63, -196, -591, -591, -591, -591, -414, + -591, -555, -555, -363, -365, -365, -365, -380, -591, -579, + -386, -526, -591, -533, -543, -591, -405, -404, -11, -591, + -591, -256, -266, -16, -76, -91, -88, -297, -590, -343, + -11, -424, -590, -425, -426, -591, -243, -393, -396, -398, + -579, -591, -501, -502, -591, -591, -512, -591, -515, -591, + -517, -591, -347, -591, -349, -351, -358, -526, -579, -531, + -539, -549, -553, -591, -341, -591, -591, -11, -11, -313, + -591, -11, -414, -591, -414, -591, -591, -11, -323, -591, + -579, -499, -327, -591, -268, -32, -199, -251, -591, -238, + -591, -361, -362, -371, -373, -591, -376, -591, -378, -383, + -591, -591, -591, -532, -591, -401, -591, -416, -418, -9, + -11, -430, -344, -591, -591, -428, -285, -11, -11, -591, + -555, -536, -554, -504, -505, -505, -530, -505, -505, -546, + -505, -541, -579, -591, -356, -591, -528, -305, -591, -306, + -591, -591, -265, -590, -316, -319, -496, -591, -325, -498, + -520, -465, -555, -534, -364, -365, -365, -365, -365, -544, + -365, -385, -579, -388, -390, -391, -542, -591, -290, -56, + -429, -11, -98, -99, -591, -591, -106, -427, -591, -591, + -394, -500, -591, -508, -591, -510, -591, -513, -591, -516, + -518, -348, -350, -354, -591, -359, -11, -309, -312, -419, + -420, -421, -11, -321, -11, -360, -591, -368, -591, -370, + -591, -374, -591, -377, -379, -387, -591, -289, -572, -423, + -248, -591, -591, -105, -397, -399, -505, -505, -505, -505, + -352, -591, -357, -591, -590, -591, -591, -365, -365, -365, + -365, -389, -422, -579, -568, -569, -572, -104, -591, -506, + -509, -511, -514, -591, -355, -342, -317, -328, -591, -366, + -369, -372, -375, -414, -505, -353, -365, -507, -367 ] + +racc_goto_table = [ + 215, 406, 295, 265, 269, 14, 333, 126, 126, 326, + 14, 218, 274, 274, 274, 371, 257, 540, 520, 2, + 113, 121, 204, 533, 536, 219, 322, 401, 648, 428, + 484, 412, 418, 425, 219, 219, 219, 258, 14, 300, + 300, 710, 129, 129, 336, 337, 131, 131, 340, 627, + 110, 435, 309, 309, 778, 476, 663, 261, 268, 270, + 475, 624, 6, 624, 752, 813, 312, 6, 219, 219, + 126, 588, 219, 345, 355, 355, 549, 335, 335, 755, + 471, 335, 808, 663, 113, 656, 309, 309, 309, 879, + 909, 627, 913, 816, 758, 109, 387, 388, 389, 390, + 523, 526, 1, 291, 530, 876, 481, 275, 275, 275, + 792, 793, 276, 276, 276, 14, 915, 510, 688, 691, + 219, 219, 219, 219, 14, 14, 756, 293, 496, 335, + 335, 335, 335, 114, 942, 357, 361, 327, 377, 392, + 945, 859, 328, 331, 563, 383, 570, 573, 573, 572, + 574, 629, 203, 876, 350, 627, 393, 615, 618, 341, + 272, 284, 285, 484, 583, 620, 621, 329, 624, 624, + 617, 373, 6, 330, 531, 348, 553, 372, 323, 663, + 324, 391, 6, 651, 325, 334, 413, 338, 817, 339, + 818, 274, 700, 952, 705, 827, 558, 399, 404, 982, + 559, 909, 423, 427, 841, 842, 713, 991, 790, 422, + 14, 219, 219, 219, 882, 692, 219, 219, 219, 219, + 219, 219, 900, 757, 879, 759, 912, 431, 432, 433, + 434, 915, 609, 14, 942, 663, 1004, 654, 385, 787, + 850, 532, 870, 867, 868, 274, 274, 470, 876, 478, + 479, 949, 782, 709, 274, 863, 13, 375, 1015, 412, + 418, 13, 376, 378, 830, 379, 380, 219, 219, 603, + 381, 869, 876, 703, 749, 382, 219, 715, 720, 706, + 874, 511, 871, 265, 403, 903, 506, 269, nil, 13, + 403, 902, nil, 14, 752, 635, 752, 14, 752, 950, + 775, 300, 14, 113, 633, 768, 522, nil, 875, 905, + 877, 619, nil, 642, 309, 622, nil, nil, 300, 537, + 538, nil, nil, 931, nil, 638, nil, 499, 14, 219, + 631, 309, nil, 492, nil, 695, 634, 638, 521, nil, + 723, 275, 723, 219, 219, 704, 276, nil, nil, 275, + 493, nil, 335, 335, 276, 955, 906, 113, 907, nil, + 822, nil, 291, 219, 1005, 638, 13, 291, nil, 824, + nil, nil, 557, 638, 554, 13, 13, 771, 491, 219, + nil, 821, 954, nil, nil, 560, 495, 589, 561, 595, + nil, 501, 126, 738, 477, 600, 714, nil, 743, nil, + 825, 627, 480, nil, 894, 829, 582, 752, nil, 752, + nil, 752, nil, 752, 413, 624, nil, nil, 428, nil, + nil, nil, 274, nil, 663, nil, 786, 129, nil, nil, + nil, 131, 539, nil, nil, nil, 774, 422, nil, nil, + nil, nil, nil, 594, 219, 976, nil, nil, 595, 599, + 611, nil, nil, nil, nil, nil, nil, nil, nil, 752, + nil, 13, nil, nil, nil, nil, nil, nil, 511, 987, + 783, nil, nil, nil, nil, nil, nil, 511, 992, nil, + 413, nil, 777, nil, 13, 274, nil, 771, nil, nil, + nil, nil, 413, nil, nil, nil, nil, 14, nil, 14, + nil, nil, 616, 422, nil, 300, nil, 219, nil, nil, + nil, nil, nil, 630, 300, 422, nil, nil, 309, nil, + 413, nil, 897, 219, nil, 274, nil, 309, 413, nil, + nil, nil, 647, nil, nil, 274, nil, nil, 14, nil, + nil, 14, nil, 422, 13, nil, nil, 219, 13, 422, + 921, nil, 294, 13, 689, 689, 6, 219, nil, nil, + nil, nil, 767, 14, nil, nil, 623, nil, nil, 951, + nil, nil, nil, 707, 708, 946, nil, nil, nil, 13, + nil, nil, 126, 734, 736, nil, nil, nil, 739, 741, + 589, nil, 427, nil, 760, nil, 727, 219, 219, 784, + 511, nil, 219, 219, nil, nil, 219, 653, nil, nil, + 766, 776, nil, nil, nil, 595, 589, 129, 600, 694, + 14, 131, nil, nil, nil, 14, 14, nil, nil, nil, + nil, nil, 785, nil, nil, nil, nil, 300, nil, 26, + nil, nil, nil, 886, 26, nil, nil, nil, 300, 986, + 309, nil, nil, 753, nil, nil, nil, 832, 1013, 26, + nil, 309, nil, nil, nil, 899, nil, nil, 26, 26, + 26, nil, 26, 733, nil, nil, 589, nil, nil, nil, + 754, 823, nil, nil, nil, 589, nil, 826, nil, 796, + 798, 800, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 26, 26, nil, 219, 26, 802, nil, nil, + 14, 219, 126, nil, 335, 14, nil, 941, nil, nil, + 335, nil, 835, nil, 398, 14, nil, 403, 861, 831, + nil, nil, 865, nil, nil, nil, 219, nil, nil, nil, + 760, nil, nil, nil, nil, nil, nil, 294, 13, 26, + 13, nil, nil, nil, 26, 26, 26, 26, 26, 26, + nil, nil, nil, 993, nil, nil, nil, 853, nil, nil, + nil, 760, nil, 14, nil, nil, nil, nil, nil, nil, + 309, nil, nil, nil, nil, 14, nil, nil, nil, 13, + nil, nil, 13, 638, nil, nil, 888, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 294, nil, nil, 13, nil, 294, nil, nil, nil, + 219, nil, 14, 14, nil, nil, 14, nil, nil, 335, + 16, 872, 14, nil, 872, 16, 844, 846, 848, 802, + 689, nil, 884, 896, 26, 26, 26, 26, nil, nil, + 26, 26, 26, 26, 26, 26, nil, 916, nil, nil, + nil, nil, nil, 16, 878, 14, 880, 26, nil, 924, + 309, 13, 14, 14, nil, nil, 13, 13, nil, nil, + 872, nil, 309, 753, nil, 753, nil, 753, nil, nil, + nil, nil, nil, 965, nil, nil, nil, nil, 349, nil, + nil, 26, 26, 933, 935, nil, 937, 939, nil, 940, + 26, nil, 908, nil, 910, nil, 422, nil, nil, 802, + nil, 802, nil, nil, nil, nil, 14, 26, nil, nil, + nil, 26, nil, nil, nil, nil, 26, nil, nil, nil, + 16, nil, nil, nil, nil, nil, nil, nil, 413, 16, + 16, 14, nil, 274, nil, nil, nil, 14, nil, 14, + nil, 13, 26, 26, nil, nil, 13, nil, nil, nil, + nil, 422, nil, nil, 589, 219, 13, 26, 26, 980, + 802, 15, nil, nil, nil, nil, 15, 957, 959, 961, + 963, nil, 964, nil, nil, nil, 753, 26, 753, 977, + 753, 978, 753, 979, nil, 999, 1000, 1001, 1002, nil, + nil, nil, nil, 26, 15, 302, 302, 802, nil, 802, + nil, nil, nil, 988, 13, 989, nil, 990, nil, nil, + nil, nil, nil, nil, nil, 16, 13, nil, nil, 802, + nil, nil, 426, 1017, nil, nil, nil, nil, 753, 347, + 356, 356, 685, nil, nil, 687, nil, nil, 16, nil, + nil, nil, nil, nil, nil, 1014, nil, nil, nil, 1009, + 1010, 1011, 1012, 13, 13, 1016, nil, 13, 26, nil, + nil, nil, nil, 13, nil, nil, nil, nil, nil, nil, + nil, 15, nil, nil, nil, nil, nil, nil, 1018, nil, + 15, 15, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 13, nil, 16, nil, + nil, nil, 16, 13, 13, nil, nil, 16, nil, nil, + nil, 26, nil, 26, 765, nil, nil, nil, nil, 769, + 770, 26, nil, nil, nil, 38, nil, nil, nil, nil, + 38, nil, nil, 16, nil, nil, nil, 26, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 26, nil, nil, 26, nil, 13, 38, 298, + 298, 26, nil, nil, nil, nil, 15, nil, nil, nil, + nil, 26, nil, nil, nil, nil, nil, 26, nil, nil, + nil, nil, 13, nil, nil, nil, nil, nil, 13, 15, + 13, nil, nil, 343, 359, 359, 359, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 26, 26, nil, nil, nil, 26, 26, nil, 833, + 26, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 26, 38, nil, nil, nil, 26, + 26, nil, nil, nil, 38, 38, nil, nil, nil, 15, + nil, nil, nil, 15, nil, nil, nil, 302, 15, nil, + nil, nil, nil, nil, nil, nil, nil, 856, nil, nil, + nil, nil, nil, nil, 302, nil, nil, nil, nil, 862, + nil, nil, nil, nil, 15, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 16, nil, 16, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 890, 891, nil, 26, + 893, nil, nil, nil, 26, 26, nil, nil, nil, 26, + 38, nil, nil, nil, nil, nil, nil, nil, nil, 26, + nil, nil, nil, 16, nil, nil, 16, nil, nil, nil, + 26, nil, nil, 38, nil, nil, nil, nil, nil, 920, + nil, nil, nil, nil, nil, nil, 928, 929, 16, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 26, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 26, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 426, nil, 38, nil, nil, nil, 38, nil, nil, + 969, 298, 38, nil, nil, 16, nil, nil, nil, nil, + 16, 16, nil, nil, 26, nil, 26, 26, 298, nil, + 26, nil, nil, nil, nil, 984, 26, nil, 38, nil, + nil, 985, nil, 15, nil, 15, nil, nil, nil, nil, + nil, 302, nil, nil, nil, nil, nil, nil, nil, nil, + 302, nil, nil, nil, nil, nil, nil, nil, nil, 26, + nil, nil, nil, nil, nil, nil, 26, 26, nil, nil, + nil, nil, nil, nil, 15, nil, nil, 15, nil, 332, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 16, nil, nil, nil, 15, + 16, nil, nil, nil, nil, nil, 719, nil, nil, nil, + 16, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 26, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 26, nil, nil, nil, nil, + nil, 26, 39, 26, nil, nil, 15, 39, 16, nil, + nil, 15, 15, nil, nil, nil, nil, nil, nil, 26, + 16, nil, nil, 302, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 302, 39, 299, 299, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 38, nil, 38, + nil, nil, nil, nil, nil, 298, nil, 16, 16, nil, + nil, 16, nil, nil, 298, nil, nil, 16, nil, nil, + 344, 360, 360, 360, nil, 400, nil, nil, nil, nil, + nil, 430, nil, nil, nil, nil, nil, nil, 38, nil, + nil, 38, nil, nil, nil, nil, 15, nil, nil, nil, + 16, 15, nil, nil, 927, nil, nil, 16, 16, nil, + nil, 15, 39, 38, nil, nil, nil, nil, nil, nil, + nil, 39, 39, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 486, nil, 488, + nil, 489, 490, 356, nil, nil, nil, nil, nil, 15, + nil, 16, nil, nil, nil, nil, nil, nil, nil, nil, + 38, 15, nil, nil, nil, 38, 38, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 16, 298, nil, nil, + nil, nil, 16, nil, 16, nil, nil, nil, 298, nil, + nil, nil, nil, nil, nil, nil, nil, 39, 15, 15, + nil, nil, 15, nil, nil, nil, nil, nil, 15, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 39, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 356, nil, nil, nil, nil, nil, nil, + nil, 15, nil, nil, nil, 926, nil, nil, 15, 15, + 38, nil, nil, nil, nil, 38, nil, nil, nil, nil, + nil, 585, nil, nil, nil, 38, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 39, nil, nil, nil, 39, nil, nil, nil, 299, 39, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 15, nil, nil, 299, nil, 359, nil, nil, + nil, nil, nil, 38, nil, 39, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 38, nil, 15, nil, nil, + nil, nil, nil, 15, nil, 15, nil, nil, nil, nil, + nil, nil, 625, nil, 332, nil, 628, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 38, 38, nil, nil, 38, nil, nil, nil, + nil, nil, 38, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 625, nil, nil, 332, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 359, nil, nil, + 430, nil, nil, nil, nil, 38, nil, nil, nil, 922, + nil, nil, 38, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 728, nil, nil, nil, 625, + 332, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 38, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 39, 772, 39, nil, nil, nil, + nil, 38, 299, nil, nil, nil, nil, 38, nil, 38, + nil, 299, nil, nil, nil, nil, nil, nil, 781, nil, + nil, nil, nil, 226, nil, nil, nil, nil, nil, nil, + nil, nil, 273, 273, 273, 39, nil, nil, 39, nil, + nil, nil, 809, nil, nil, 319, 320, 321, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 39, nil, 273, 273, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 834, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 39, nil, nil, + nil, nil, 39, 39, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 299, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 299, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 881, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 892, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 332, 39, nil, 273, + 405, 273, 39, nil, 424, 429, nil, nil, nil, nil, + nil, nil, 39, nil, nil, nil, nil, nil, nil, nil, + 226, nil, nil, 444, 445, 446, 447, 448, 449, 450, + 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, + 461, 462, 463, 464, 465, 466, 467, 468, 469, nil, + nil, nil, nil, nil, 360, 273, 273, nil, nil, nil, + 39, nil, nil, nil, 273, nil, nil, nil, nil, nil, + nil, 273, 39, 273, nil, 273, 273, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 39, + 39, nil, nil, 39, nil, 517, nil, nil, nil, 39, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 360, nil, nil, nil, nil, nil, + nil, nil, 39, nil, nil, nil, 923, nil, nil, 39, + 39, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 273, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 39, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 273, nil, 424, 610, 405, nil, 39, nil, + nil, nil, nil, nil, 39, nil, 39, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 273, nil, 273, nil, + 273, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 273, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 644, 645, 646, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 273, nil, nil, + 273, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 273, 273, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 273, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 273, + 730, nil, nil, 273, 273, 735, 737, nil, nil, nil, + 740, 742, nil, nil, 610, 744, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 273, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 273, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 273, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 273, nil, 836, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 735, 737, + 742, 740, nil, 839, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 273, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 273, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 273, 836, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 273 ] + +racc_goto_check = [ + 31, 23, 49, 69, 69, 22, 84, 57, 57, 65, + 22, 20, 33, 33, 33, 56, 138, 90, 8, 2, + 94, 15, 15, 87, 87, 22, 31, 27, 10, 18, + 71, 37, 37, 27, 22, 22, 22, 36, 22, 22, + 22, 96, 60, 60, 17, 17, 61, 61, 17, 175, + 6, 47, 63, 63, 11, 23, 163, 38, 38, 38, + 39, 72, 7, 72, 121, 88, 50, 7, 22, 22, + 57, 24, 22, 22, 22, 22, 54, 29, 29, 127, + 37, 29, 117, 163, 94, 137, 63, 63, 63, 171, + 172, 175, 132, 11, 130, 4, 17, 17, 17, 17, + 67, 67, 1, 45, 67, 167, 47, 66, 66, 66, + 122, 122, 68, 68, 68, 22, 133, 51, 89, 89, + 22, 22, 22, 22, 22, 22, 128, 46, 47, 29, + 29, 29, 29, 5, 115, 55, 55, 66, 152, 2, + 118, 12, 68, 68, 156, 152, 156, 156, 156, 155, + 155, 14, 16, 167, 19, 175, 30, 40, 42, 4, + 44, 44, 44, 71, 62, 40, 40, 64, 72, 72, + 70, 82, 7, 83, 86, 91, 93, 97, 98, 163, + 99, 7, 7, 100, 101, 102, 69, 103, 104, 105, + 106, 33, 107, 108, 109, 110, 111, 20, 20, 118, + 112, 172, 20, 20, 122, 122, 113, 132, 137, 57, + 22, 22, 22, 22, 117, 90, 22, 22, 22, 22, + 22, 22, 114, 119, 171, 125, 131, 29, 29, 29, + 29, 133, 23, 22, 115, 163, 118, 134, 5, 135, + 130, 136, 121, 139, 140, 33, 33, 141, 167, 143, + 144, 145, 146, 8, 33, 147, 21, 150, 118, 37, + 37, 21, 151, 153, 137, 154, 157, 22, 22, 47, + 158, 130, 167, 54, 24, 159, 22, 160, 161, 162, + 166, 49, 168, 69, 66, 169, 31, 69, nil, 21, + 66, 121, nil, 22, 121, 23, 121, 22, 121, 11, + 24, 22, 22, 94, 51, 40, 31, nil, 128, 127, + 128, 47, nil, 51, 63, 47, nil, nil, 22, 17, + 17, nil, nil, 122, nil, 37, nil, 50, 22, 22, + 47, 63, nil, 6, nil, 23, 47, 37, 29, nil, + 156, 66, 156, 22, 22, 23, 68, nil, nil, 66, + 7, nil, 29, 29, 68, 122, 128, 94, 128, nil, + 24, nil, 45, 22, 88, 37, 21, 45, nil, 24, + nil, nil, 29, 37, 94, 21, 21, 71, 4, 22, + nil, 87, 96, nil, nil, 36, 46, 31, 29, 69, + nil, 46, 57, 39, 44, 69, 47, nil, 39, nil, + 8, 175, 44, nil, 89, 8, 15, 121, nil, 121, + nil, 121, nil, 121, 69, 72, nil, nil, 18, nil, + nil, nil, 33, nil, 163, nil, 67, 60, nil, nil, + nil, 61, 4, nil, nil, nil, 51, 57, nil, nil, + nil, nil, nil, 38, 22, 128, nil, nil, 69, 38, + 31, nil, nil, nil, nil, nil, nil, nil, nil, 121, + nil, 21, nil, nil, nil, nil, nil, nil, 49, 128, + 27, nil, nil, nil, nil, nil, nil, 49, 10, nil, + 69, nil, 47, nil, 21, 33, nil, 71, nil, nil, + nil, nil, 69, nil, nil, nil, nil, 22, nil, 22, + nil, nil, 38, 57, nil, 22, nil, 22, nil, nil, + nil, nil, nil, 2, 22, 57, nil, nil, 63, nil, + 69, nil, 8, 22, nil, 33, nil, 63, 69, nil, + nil, nil, 29, nil, nil, 33, nil, nil, 22, nil, + nil, 22, nil, 57, 21, nil, nil, 22, 21, 57, + 87, nil, 9, 21, 94, 94, 7, 22, nil, nil, + nil, nil, 84, 22, nil, nil, 68, nil, nil, 90, + nil, nil, nil, 94, 94, 87, nil, nil, nil, 21, + nil, nil, 57, 20, 20, nil, nil, nil, 20, 20, + 31, nil, 20, nil, 31, nil, 15, 22, 22, 65, + 49, nil, 22, 22, nil, nil, 22, 68, nil, nil, + 138, 49, nil, nil, nil, 69, 31, 60, 69, 66, + 22, 61, nil, nil, nil, 22, 22, nil, nil, nil, + nil, nil, 31, nil, nil, nil, nil, 22, nil, 41, + nil, nil, nil, 47, 41, nil, nil, nil, 22, 8, + 63, nil, nil, 123, nil, nil, nil, 56, 24, 41, + nil, 63, nil, nil, nil, 47, nil, nil, 41, 41, + 41, nil, 41, 68, nil, nil, 31, nil, nil, nil, + 126, 17, nil, nil, nil, 31, nil, 17, nil, 165, + 165, 165, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 41, 41, nil, 22, 41, 116, nil, nil, + 22, 22, 57, nil, 29, 22, nil, 47, nil, nil, + 29, nil, 20, nil, 9, 22, nil, 66, 65, 94, + nil, nil, 65, nil, nil, nil, 22, nil, nil, nil, + 31, nil, nil, nil, nil, nil, nil, 9, 21, 41, + 21, nil, nil, nil, 41, 41, 41, 41, 41, 41, + nil, nil, nil, 23, nil, nil, nil, 22, nil, nil, + nil, 31, nil, 22, nil, nil, nil, nil, nil, nil, + 63, nil, nil, nil, nil, 22, nil, nil, nil, 21, + nil, nil, 21, 37, nil, nil, 17, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 9, nil, nil, 21, nil, 9, nil, nil, nil, + 22, nil, 22, 22, nil, nil, 22, nil, nil, 29, + 26, 123, 22, nil, 123, 26, 124, 124, 124, 116, + 94, nil, 116, 94, 41, 41, 41, 41, nil, nil, + 41, 41, 41, 41, 41, 41, nil, 22, nil, nil, + nil, nil, nil, 26, 126, 22, 126, 41, nil, 22, + 63, 21, 22, 22, nil, nil, 21, 21, nil, nil, + 123, nil, 63, 123, nil, 123, nil, 123, nil, nil, + nil, nil, nil, 31, nil, nil, nil, nil, 26, nil, + nil, 41, 41, 165, 165, nil, 165, 165, nil, 165, + 41, nil, 126, nil, 126, nil, 57, nil, nil, 116, + nil, 116, nil, nil, nil, nil, 22, 41, nil, nil, + nil, 41, nil, nil, nil, nil, 41, nil, nil, nil, + 26, nil, nil, nil, nil, nil, nil, nil, 69, 26, + 26, 22, nil, 33, nil, nil, nil, 22, nil, 22, + nil, 21, 41, 41, nil, nil, 21, nil, nil, nil, + nil, 57, nil, nil, 31, 22, 21, 41, 41, 116, + 116, 25, nil, nil, nil, nil, 25, 124, 124, 124, + 124, nil, 124, nil, nil, nil, 123, 41, 123, 126, + 123, 126, 123, 126, nil, 165, 165, 165, 165, nil, + nil, nil, nil, 41, 25, 25, 25, 116, nil, 116, + nil, nil, nil, 126, 21, 126, nil, 126, nil, nil, + nil, nil, nil, nil, nil, 26, 21, nil, nil, 116, + nil, nil, 26, 165, nil, nil, nil, nil, 123, 25, + 25, 25, 9, nil, nil, 9, nil, nil, 26, nil, + nil, nil, nil, nil, nil, 126, nil, nil, nil, 124, + 124, 124, 124, 21, 21, 126, nil, 21, 41, nil, + nil, nil, nil, 21, nil, nil, nil, nil, nil, nil, + nil, 25, nil, nil, nil, nil, nil, nil, 124, nil, + 25, 25, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 21, nil, 26, nil, + nil, nil, 26, 21, 21, nil, nil, 26, nil, nil, + nil, 41, nil, 41, 9, nil, nil, nil, nil, 9, + 9, 41, nil, nil, nil, 52, nil, nil, nil, nil, + 52, nil, nil, 26, nil, nil, nil, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 41, nil, nil, 41, nil, 21, 52, 52, + 52, 41, nil, nil, nil, nil, 25, nil, nil, nil, + nil, 41, nil, nil, nil, nil, nil, 41, nil, nil, + nil, nil, 21, nil, nil, nil, nil, nil, 21, 25, + 21, nil, nil, 52, 52, 52, 52, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 41, 41, nil, nil, nil, 41, 41, nil, 9, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 41, 52, nil, nil, nil, 41, + 41, nil, nil, nil, 52, 52, nil, nil, nil, 25, + nil, nil, nil, 25, nil, nil, nil, 25, 25, nil, + nil, nil, nil, nil, nil, nil, nil, 9, nil, nil, + nil, nil, nil, nil, 25, nil, nil, nil, nil, 9, + nil, nil, nil, nil, 25, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 26, nil, 26, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 9, 9, nil, 41, + 9, nil, nil, nil, 41, 41, nil, nil, nil, 41, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, nil, 26, nil, nil, 26, nil, nil, nil, + 41, nil, nil, 52, nil, nil, nil, nil, nil, 9, + nil, nil, nil, nil, nil, nil, 9, 9, 26, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 26, nil, 52, nil, nil, nil, 52, nil, nil, + 9, 52, 52, nil, nil, 26, nil, nil, nil, nil, + 26, 26, nil, nil, 41, nil, 41, 41, 52, nil, + 41, nil, nil, nil, nil, 9, 41, nil, 52, nil, + nil, 9, nil, 25, nil, 25, nil, nil, nil, nil, + nil, 25, nil, nil, nil, nil, nil, nil, nil, nil, + 25, nil, nil, nil, nil, nil, nil, nil, nil, 41, + nil, nil, nil, nil, nil, nil, 41, 41, nil, nil, + nil, nil, nil, nil, 25, nil, nil, 25, nil, 28, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 26, nil, nil, nil, 25, + 26, nil, nil, nil, nil, nil, 25, nil, nil, nil, + 26, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 41, nil, nil, nil, nil, + nil, 41, 53, 41, nil, nil, 25, 53, 26, nil, + nil, 25, 25, nil, nil, nil, nil, nil, nil, 41, + 26, nil, nil, 25, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 25, 53, 53, 53, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 52, nil, 52, + nil, nil, nil, nil, nil, 52, nil, 26, 26, nil, + nil, 26, nil, nil, 52, nil, nil, 26, nil, nil, + 53, 53, 53, 53, nil, 28, nil, nil, nil, nil, + nil, 28, nil, nil, nil, nil, nil, nil, 52, nil, + nil, 52, nil, nil, nil, nil, 25, nil, nil, nil, + 26, 25, nil, nil, 26, nil, nil, 26, 26, nil, + nil, 25, 53, 52, nil, nil, nil, nil, nil, nil, + nil, 53, 53, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 28, nil, 28, + nil, 28, 28, 25, nil, nil, nil, nil, nil, 25, + nil, 26, nil, nil, nil, nil, nil, nil, nil, nil, + 52, 25, nil, nil, nil, 52, 52, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 26, 52, nil, nil, + nil, nil, 26, nil, 26, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 53, 25, 25, + nil, nil, 25, nil, nil, nil, nil, nil, 25, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 53, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 25, nil, nil, nil, nil, nil, nil, + nil, 25, nil, nil, nil, 25, nil, nil, 25, 25, + 52, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, 28, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 53, nil, nil, nil, 53, nil, nil, nil, 53, 53, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 25, nil, nil, 53, nil, 52, nil, nil, + nil, nil, nil, 52, nil, 53, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 52, nil, 25, nil, nil, + nil, nil, nil, 25, nil, 25, nil, nil, nil, nil, + nil, nil, 28, nil, 28, nil, 28, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 52, 52, nil, nil, 52, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 28, nil, nil, 28, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 52, nil, nil, + 28, nil, nil, nil, nil, 52, nil, nil, nil, 52, + nil, nil, 52, 52, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 28, nil, nil, nil, 28, + 28, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 53, 28, 53, nil, nil, nil, + nil, 52, 53, nil, nil, nil, nil, 52, nil, 52, + nil, 53, nil, nil, nil, nil, nil, nil, 28, nil, + nil, nil, nil, 32, nil, nil, nil, nil, nil, nil, + nil, nil, 32, 32, 32, 53, nil, nil, 53, nil, + nil, nil, 28, nil, nil, 32, 32, 32, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 53, nil, 32, 32, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 28, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 53, nil, nil, + nil, nil, 53, 53, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 53, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 53, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 28, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 28, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 28, 53, nil, 32, + 32, 32, 53, nil, 32, 32, nil, nil, nil, nil, + nil, nil, 53, nil, nil, nil, nil, nil, nil, nil, + 32, nil, nil, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, nil, + nil, nil, nil, nil, 53, 32, 32, nil, nil, nil, + 53, nil, nil, nil, 32, nil, nil, nil, nil, nil, + nil, 32, 53, 32, nil, 32, 32, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 53, + 53, nil, nil, 53, nil, 32, nil, nil, nil, 53, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 53, nil, nil, nil, nil, nil, + nil, nil, 53, nil, nil, nil, 53, nil, nil, 53, + 53, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 32, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 53, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 32, nil, 32, 32, 32, nil, 53, nil, + nil, nil, nil, nil, 53, nil, 53, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 32, nil, 32, nil, + 32, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 32, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 32, 32, 32, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 32, nil, nil, + 32, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 32, 32, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 32, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 32, + 32, nil, nil, 32, 32, 32, 32, nil, nil, nil, + 32, 32, nil, nil, 32, 32, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 32, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 32, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 32, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 32, nil, 32, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 32, 32, + 32, 32, nil, 32, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 32, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 32, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 32, 32, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 32 ] + +racc_goto_pointer = [ + nil, 102, 19, nil, 92, 128, 47, 62, -305, 519, + -491, -594, -637, nil, -341, 13, 143, -19, -183, 86, + -9, 256, 5, -207, -335, 981, 830, -179, 1459, 14, + 35, -19, 2093, -17, nil, nil, 13, -178, 31, -201, + -313, 639, -316, nil, 131, 70, 94, -165, nil, -32, + 31, -196, 1145, 1592, -277, 66, -56, -1, nil, nil, + 34, 38, -233, 18, 108, -50, 78, -227, 83, -23, + -301, -246, -422, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 100, 113, -55, nil, -160, -313, -620, -419, + -324, 107, nil, -181, 17, nil, -518, 106, 121, 122, + -338, 126, 123, 122, -500, 123, -501, -354, -701, -359, + -513, -165, -171, -354, -610, -749, 36, -589, -745, -390, + nil, -549, -547, 40, 82, -388, 67, -534, -487, nil, + -519, -625, -759, -735, -295, -415, -93, -447, -6, -545, + -545, -9, nil, -17, -17, -642, -397, -527, nil, nil, + 178, 181, 54, 178, 179, -230, -232, 179, 182, 186, + -288, -288, -276, -476, nil, 29, -515, -690, -509, -555, + nil, -708, -755, nil, nil, -436 ] + +racc_goto_default = [ + nil, nil, nil, 3, nil, 4, 342, 289, nil, 519, + nil, 814, nil, 286, 287, nil, nil, nil, 11, 12, + 18, 225, 318, nil, nil, 223, 224, nil, 279, 17, + nil, 436, 21, 22, 23, 24, nil, 641, nil, nil, + nil, 306, nil, 25, 407, 32, nil, nil, 34, 37, + 36, nil, 220, 221, 354, nil, 128, 415, 127, 130, + 77, 78, nil, 46, nil, 779, 408, nil, 409, 420, + 596, 482, 277, 263, 47, 48, 49, 50, 51, 52, + 53, 54, 55, nil, 264, 61, nil, nil, nil, nil, + nil, nil, 69, nil, 534, 70, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 804, 670, nil, 805, 904, + 751, 658, nil, 659, nil, nil, 660, nil, 662, 612, + nil, nil, nil, 668, nil, nil, nil, 712, nil, nil, + nil, nil, 419, nil, nil, nil, nil, nil, 76, 79, + 80, nil, nil, nil, nil, nil, 568, nil, nil, nil, + nil, nil, nil, 873, 657, nil, 661, 672, 674, 763, + 677, 678, 764, 681, 684, 281 ] + +racc_reduce_table = [ + 0, 0, :racc_error, + 1, 142, :_reduce_none, + 2, 143, :_reduce_2, + 0, 144, :_reduce_3, + 1, 144, :_reduce_4, + 3, 144, :_reduce_5, + 2, 144, :_reduce_6, + 1, 146, :_reduce_none, + 4, 146, :_reduce_8, + 4, 149, :_reduce_9, + 2, 150, :_reduce_10, + 0, 154, :_reduce_11, + 1, 154, :_reduce_12, + 3, 154, :_reduce_13, + 2, 154, :_reduce_14, + 1, 155, :_reduce_none, + 4, 155, :_reduce_16, + 0, 171, :_reduce_17, + 4, 148, :_reduce_18, + 3, 148, :_reduce_19, + 3, 148, :_reduce_20, + 3, 148, :_reduce_21, + 2, 148, :_reduce_22, + 3, 148, :_reduce_23, + 3, 148, :_reduce_24, + 3, 148, :_reduce_25, + 3, 148, :_reduce_26, + 3, 148, :_reduce_27, + 4, 148, :_reduce_28, + 1, 148, :_reduce_none, + 3, 148, :_reduce_30, + 3, 148, :_reduce_31, + 6, 148, :_reduce_32, + 5, 148, :_reduce_33, + 5, 148, :_reduce_34, + 5, 148, :_reduce_35, + 5, 148, :_reduce_36, + 3, 148, :_reduce_37, + 3, 148, :_reduce_38, + 3, 148, :_reduce_39, + 3, 148, :_reduce_40, + 1, 148, :_reduce_none, + 3, 159, :_reduce_42, + 3, 159, :_reduce_43, + 1, 170, :_reduce_none, + 3, 170, :_reduce_45, + 3, 170, :_reduce_46, + 3, 170, :_reduce_47, + 2, 170, :_reduce_48, + 1, 170, :_reduce_none, + 1, 158, :_reduce_none, + 1, 161, :_reduce_none, + 1, 161, :_reduce_none, + 1, 175, :_reduce_none, + 4, 175, :_reduce_54, + 0, 183, :_reduce_55, + 5, 180, :_reduce_56, + 1, 182, :_reduce_none, + 2, 174, :_reduce_58, + 3, 174, :_reduce_59, + 4, 174, :_reduce_60, + 5, 174, :_reduce_61, + 4, 174, :_reduce_62, + 5, 174, :_reduce_63, + 2, 174, :_reduce_64, + 2, 174, :_reduce_65, + 2, 174, :_reduce_66, + 2, 174, :_reduce_67, + 2, 174, :_reduce_68, + 1, 160, :_reduce_69, + 3, 160, :_reduce_70, + 1, 187, :_reduce_71, + 3, 187, :_reduce_72, + 1, 186, :_reduce_none, + 2, 186, :_reduce_74, + 3, 186, :_reduce_75, + 5, 186, :_reduce_76, + 2, 186, :_reduce_77, + 4, 186, :_reduce_78, + 2, 186, :_reduce_79, + 4, 186, :_reduce_80, + 1, 186, :_reduce_81, + 3, 186, :_reduce_82, + 1, 190, :_reduce_none, + 3, 190, :_reduce_84, + 2, 189, :_reduce_85, + 3, 189, :_reduce_86, + 1, 192, :_reduce_87, + 3, 192, :_reduce_88, + 1, 191, :_reduce_89, + 1, 191, :_reduce_90, + 4, 191, :_reduce_91, + 3, 191, :_reduce_92, + 3, 191, :_reduce_93, + 3, 191, :_reduce_94, + 3, 191, :_reduce_95, + 2, 191, :_reduce_96, + 1, 191, :_reduce_97, + 1, 167, :_reduce_98, + 1, 167, :_reduce_99, + 4, 167, :_reduce_100, + 3, 167, :_reduce_101, + 3, 167, :_reduce_102, + 3, 167, :_reduce_103, + 3, 167, :_reduce_104, + 2, 167, :_reduce_105, + 1, 167, :_reduce_106, + 1, 195, :_reduce_107, + 1, 195, :_reduce_none, + 2, 196, :_reduce_109, + 1, 196, :_reduce_110, + 3, 196, :_reduce_111, + 1, 197, :_reduce_none, + 1, 197, :_reduce_none, + 1, 197, :_reduce_none, + 1, 197, :_reduce_none, + 1, 197, :_reduce_none, + 1, 200, :_reduce_117, + 1, 200, :_reduce_none, + 1, 156, :_reduce_none, + 1, 156, :_reduce_none, + 1, 157, :_reduce_121, + 0, 203, :_reduce_122, + 4, 157, :_reduce_123, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 3, 173, :_reduce_195, + 5, 173, :_reduce_196, + 3, 173, :_reduce_197, + 5, 173, :_reduce_198, + 6, 173, :_reduce_199, + 5, 173, :_reduce_200, + 5, 173, :_reduce_201, + 5, 173, :_reduce_202, + 5, 173, :_reduce_203, + 4, 173, :_reduce_204, + 3, 173, :_reduce_205, + 3, 173, :_reduce_206, + 3, 173, :_reduce_207, + 3, 173, :_reduce_208, + 3, 173, :_reduce_209, + 3, 173, :_reduce_210, + 3, 173, :_reduce_211, + 3, 173, :_reduce_212, + 3, 173, :_reduce_213, + 4, 173, :_reduce_214, + 4, 173, :_reduce_215, + 2, 173, :_reduce_216, + 2, 173, :_reduce_217, + 3, 173, :_reduce_218, + 3, 173, :_reduce_219, + 3, 173, :_reduce_220, + 3, 173, :_reduce_221, + 3, 173, :_reduce_222, + 3, 173, :_reduce_223, + 3, 173, :_reduce_224, + 3, 173, :_reduce_225, + 3, 173, :_reduce_226, + 3, 173, :_reduce_227, + 3, 173, :_reduce_228, + 3, 173, :_reduce_229, + 3, 173, :_reduce_230, + 2, 173, :_reduce_231, + 2, 173, :_reduce_232, + 3, 173, :_reduce_233, + 3, 173, :_reduce_234, + 3, 173, :_reduce_235, + 3, 173, :_reduce_236, + 3, 173, :_reduce_237, + 6, 173, :_reduce_238, + 1, 173, :_reduce_none, + 1, 169, :_reduce_none, + 1, 205, :_reduce_none, + 2, 205, :_reduce_none, + 4, 205, :_reduce_243, + 2, 205, :_reduce_244, + 3, 210, :_reduce_245, + 0, 211, :_reduce_246, + 1, 211, :_reduce_none, + 0, 164, :_reduce_248, + 1, 164, :_reduce_none, + 2, 164, :_reduce_none, + 4, 164, :_reduce_251, + 2, 164, :_reduce_252, + 1, 185, :_reduce_253, + 2, 185, :_reduce_254, + 2, 185, :_reduce_255, + 4, 185, :_reduce_256, + 1, 185, :_reduce_257, + 0, 214, :_reduce_258, + 2, 179, :_reduce_259, + 2, 213, :_reduce_260, + 2, 212, :_reduce_261, + 0, 212, :_reduce_262, + 1, 207, :_reduce_263, + 2, 207, :_reduce_264, + 3, 207, :_reduce_265, + 4, 207, :_reduce_266, + 3, 168, :_reduce_267, + 4, 168, :_reduce_268, + 2, 168, :_reduce_269, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_280, + 0, 239, :_reduce_281, + 4, 204, :_reduce_282, + 0, 240, :_reduce_283, + 0, 241, :_reduce_284, + 6, 204, :_reduce_285, + 0, 242, :_reduce_286, + 4, 204, :_reduce_287, + 3, 204, :_reduce_288, + 3, 204, :_reduce_289, + 2, 204, :_reduce_290, + 3, 204, :_reduce_291, + 3, 204, :_reduce_292, + 1, 204, :_reduce_293, + 4, 204, :_reduce_294, + 3, 204, :_reduce_295, + 1, 204, :_reduce_296, + 5, 204, :_reduce_297, + 4, 204, :_reduce_298, + 3, 204, :_reduce_299, + 2, 204, :_reduce_300, + 1, 204, :_reduce_none, + 2, 204, :_reduce_302, + 0, 243, :_reduce_303, + 3, 204, :_reduce_304, + 6, 204, :_reduce_305, + 6, 204, :_reduce_306, + 0, 244, :_reduce_307, + 0, 245, :_reduce_308, + 7, 204, :_reduce_309, + 0, 246, :_reduce_310, + 0, 247, :_reduce_311, + 7, 204, :_reduce_312, + 5, 204, :_reduce_313, + 4, 204, :_reduce_314, + 0, 248, :_reduce_315, + 0, 249, :_reduce_316, + 9, 204, :_reduce_317, + 0, 250, :_reduce_318, + 6, 204, :_reduce_319, + 0, 251, :_reduce_320, + 7, 204, :_reduce_321, + 0, 252, :_reduce_322, + 5, 204, :_reduce_323, + 0, 253, :_reduce_324, + 6, 204, :_reduce_325, + 0, 254, :_reduce_326, + 0, 255, :_reduce_327, + 9, 204, :_reduce_328, + 1, 204, :_reduce_329, + 1, 204, :_reduce_330, + 1, 204, :_reduce_331, + 1, 204, :_reduce_332, + 1, 163, :_reduce_none, + 1, 233, :_reduce_334, + 1, 236, :_reduce_335, + 1, 228, :_reduce_none, + 1, 228, :_reduce_none, + 2, 228, :_reduce_338, + 1, 230, :_reduce_none, + 1, 230, :_reduce_none, + 1, 229, :_reduce_none, + 5, 229, :_reduce_342, + 1, 152, :_reduce_none, + 2, 152, :_reduce_344, + 1, 232, :_reduce_none, + 1, 232, :_reduce_none, + 1, 256, :_reduce_347, + 3, 256, :_reduce_348, + 1, 259, :_reduce_349, + 3, 259, :_reduce_350, + 1, 258, :_reduce_none, + 4, 258, :_reduce_352, + 6, 258, :_reduce_353, + 3, 258, :_reduce_354, + 5, 258, :_reduce_355, + 2, 258, :_reduce_356, + 4, 258, :_reduce_357, + 1, 258, :_reduce_358, + 3, 258, :_reduce_359, + 4, 260, :_reduce_360, + 2, 260, :_reduce_361, + 2, 260, :_reduce_362, + 1, 260, :_reduce_363, + 2, 265, :_reduce_364, + 0, 265, :_reduce_365, + 6, 266, :_reduce_366, + 8, 266, :_reduce_367, + 4, 266, :_reduce_368, + 6, 266, :_reduce_369, + 4, 266, :_reduce_370, + 2, 266, :_reduce_none, + 6, 266, :_reduce_372, + 2, 266, :_reduce_373, + 4, 266, :_reduce_374, + 6, 266, :_reduce_375, + 2, 266, :_reduce_376, + 4, 266, :_reduce_377, + 2, 266, :_reduce_378, + 4, 266, :_reduce_379, + 1, 266, :_reduce_none, + 0, 181, :_reduce_381, + 1, 181, :_reduce_382, + 3, 270, :_reduce_383, + 1, 270, :_reduce_384, + 4, 270, :_reduce_385, + 1, 271, :_reduce_386, + 4, 271, :_reduce_387, + 1, 272, :_reduce_388, + 3, 272, :_reduce_389, + 1, 273, :_reduce_390, + 1, 273, :_reduce_none, + 0, 277, :_reduce_392, + 3, 227, :_reduce_393, + 4, 275, :_reduce_394, + 1, 275, :_reduce_395, + 0, 280, :_reduce_396, + 4, 276, :_reduce_397, + 0, 281, :_reduce_398, + 4, 276, :_reduce_399, + 0, 282, :_reduce_400, + 5, 279, :_reduce_401, + 2, 176, :_reduce_402, + 4, 176, :_reduce_403, + 5, 176, :_reduce_404, + 5, 176, :_reduce_405, + 2, 226, :_reduce_406, + 4, 226, :_reduce_407, + 4, 226, :_reduce_408, + 3, 226, :_reduce_409, + 3, 226, :_reduce_410, + 3, 226, :_reduce_411, + 2, 226, :_reduce_412, + 1, 226, :_reduce_413, + 4, 226, :_reduce_414, + 0, 284, :_reduce_415, + 5, 225, :_reduce_416, + 0, 285, :_reduce_417, + 5, 225, :_reduce_418, + 5, 231, :_reduce_419, + 1, 286, :_reduce_420, + 1, 286, :_reduce_none, + 6, 151, :_reduce_422, + 0, 151, :_reduce_423, + 1, 287, :_reduce_424, + 1, 287, :_reduce_none, + 1, 287, :_reduce_none, + 2, 288, :_reduce_427, + 1, 288, :_reduce_none, + 2, 153, :_reduce_429, + 1, 153, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 216, :_reduce_434, + 1, 290, :_reduce_435, + 2, 290, :_reduce_436, + 3, 291, :_reduce_437, + 1, 291, :_reduce_438, + 1, 291, :_reduce_439, + 3, 217, :_reduce_440, + 4, 218, :_reduce_441, + 3, 219, :_reduce_442, + 0, 295, :_reduce_443, + 3, 295, :_reduce_444, + 1, 296, :_reduce_445, + 2, 296, :_reduce_446, + 3, 221, :_reduce_447, + 0, 298, :_reduce_448, + 3, 298, :_reduce_449, + 3, 220, :_reduce_450, + 3, 222, :_reduce_451, + 0, 299, :_reduce_452, + 3, 299, :_reduce_453, + 0, 300, :_reduce_454, + 3, 300, :_reduce_455, + 0, 292, :_reduce_456, + 2, 292, :_reduce_457, + 0, 293, :_reduce_458, + 2, 293, :_reduce_459, + 0, 294, :_reduce_460, + 2, 294, :_reduce_461, + 1, 297, :_reduce_462, + 2, 297, :_reduce_463, + 0, 302, :_reduce_464, + 4, 297, :_reduce_465, + 1, 301, :_reduce_466, + 1, 301, :_reduce_467, + 1, 301, :_reduce_468, + 1, 301, :_reduce_none, + 1, 201, :_reduce_470, + 3, 202, :_reduce_471, + 1, 289, :_reduce_472, + 1, 289, :_reduce_473, + 2, 289, :_reduce_474, + 2, 289, :_reduce_475, + 1, 193, :_reduce_476, + 1, 193, :_reduce_477, + 1, 193, :_reduce_478, + 1, 193, :_reduce_479, + 1, 193, :_reduce_480, + 1, 194, :_reduce_481, + 1, 194, :_reduce_482, + 1, 194, :_reduce_483, + 1, 194, :_reduce_484, + 1, 194, :_reduce_485, + 1, 194, :_reduce_486, + 1, 194, :_reduce_487, + 1, 223, :_reduce_488, + 1, 223, :_reduce_489, + 1, 162, :_reduce_490, + 1, 162, :_reduce_491, + 1, 166, :_reduce_492, + 1, 166, :_reduce_493, + 1, 234, :_reduce_494, + 0, 303, :_reduce_495, + 4, 234, :_reduce_496, + 2, 234, :_reduce_497, + 3, 237, :_reduce_498, + 2, 237, :_reduce_499, + 4, 304, :_reduce_500, + 2, 304, :_reduce_501, + 2, 304, :_reduce_502, + 1, 304, :_reduce_503, + 2, 306, :_reduce_504, + 0, 306, :_reduce_505, + 6, 278, :_reduce_506, + 8, 278, :_reduce_507, + 4, 278, :_reduce_508, + 6, 278, :_reduce_509, + 4, 278, :_reduce_510, + 6, 278, :_reduce_511, + 2, 278, :_reduce_512, + 4, 278, :_reduce_513, + 6, 278, :_reduce_514, + 2, 278, :_reduce_515, + 4, 278, :_reduce_516, + 2, 278, :_reduce_517, + 4, 278, :_reduce_518, + 1, 278, :_reduce_519, + 0, 278, :_reduce_520, + 1, 274, :_reduce_521, + 1, 274, :_reduce_522, + 1, 274, :_reduce_523, + 1, 274, :_reduce_524, + 1, 257, :_reduce_none, + 1, 257, :_reduce_none, + 1, 308, :_reduce_527, + 3, 308, :_reduce_528, + 1, 267, :_reduce_529, + 3, 267, :_reduce_530, + 2, 309, :_reduce_531, + 2, 310, :_reduce_532, + 1, 261, :_reduce_533, + 3, 261, :_reduce_534, + 1, 305, :_reduce_535, + 3, 305, :_reduce_536, + 1, 311, :_reduce_none, + 1, 311, :_reduce_none, + 2, 262, :_reduce_539, + 1, 262, :_reduce_540, + 3, 312, :_reduce_541, + 3, 313, :_reduce_542, + 1, 268, :_reduce_543, + 3, 268, :_reduce_544, + 1, 307, :_reduce_545, + 3, 307, :_reduce_546, + 1, 314, :_reduce_none, + 1, 314, :_reduce_none, + 2, 269, :_reduce_549, + 1, 269, :_reduce_550, + 1, 315, :_reduce_none, + 1, 315, :_reduce_none, + 2, 264, :_reduce_553, + 2, 263, :_reduce_554, + 0, 263, :_reduce_555, + 1, 238, :_reduce_none, + 3, 238, :_reduce_557, + 0, 224, :_reduce_558, + 2, 224, :_reduce_none, + 1, 209, :_reduce_560, + 3, 209, :_reduce_561, + 3, 316, :_reduce_562, + 2, 316, :_reduce_563, + 2, 316, :_reduce_564, + 1, 184, :_reduce_none, + 1, 184, :_reduce_none, + 1, 184, :_reduce_none, + 1, 178, :_reduce_none, + 1, 178, :_reduce_none, + 1, 178, :_reduce_none, + 1, 178, :_reduce_none, + 1, 283, :_reduce_none, + 1, 283, :_reduce_none, + 1, 283, :_reduce_none, + 1, 177, :_reduce_none, + 1, 177, :_reduce_none, + 0, 145, :_reduce_none, + 1, 145, :_reduce_none, + 0, 172, :_reduce_none, + 1, 172, :_reduce_none, + 2, 188, :_reduce_581, + 2, 165, :_reduce_582, + 0, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 235, :_reduce_586, + 1, 235, :_reduce_none, + 1, 147, :_reduce_none, + 2, 147, :_reduce_none, + 0, 206, :_reduce_590 ] + +racc_reduce_n = 591 + +racc_shift_n = 1019 + +racc_token_table = { + false => 0, + :error => 1, + :kCLASS => 2, + :kMODULE => 3, + :kDEF => 4, + :kUNDEF => 5, + :kBEGIN => 6, + :kRESCUE => 7, + :kENSURE => 8, + :kEND => 9, + :kIF => 10, + :kUNLESS => 11, + :kTHEN => 12, + :kELSIF => 13, + :kELSE => 14, + :kCASE => 15, + :kWHEN => 16, + :kWHILE => 17, + :kUNTIL => 18, + :kFOR => 19, + :kBREAK => 20, + :kNEXT => 21, + :kREDO => 22, + :kRETRY => 23, + :kIN => 24, + :kDO => 25, + :kDO_COND => 26, + :kDO_BLOCK => 27, + :kDO_LAMBDA => 28, + :kRETURN => 29, + :kYIELD => 30, + :kSUPER => 31, + :kSELF => 32, + :kNIL => 33, + :kTRUE => 34, + :kFALSE => 35, + :kAND => 36, + :kOR => 37, + :kNOT => 38, + :kIF_MOD => 39, + :kUNLESS_MOD => 40, + :kWHILE_MOD => 41, + :kUNTIL_MOD => 42, + :kRESCUE_MOD => 43, + :kALIAS => 44, + :kDEFINED => 45, + :klBEGIN => 46, + :klEND => 47, + :k__LINE__ => 48, + :k__FILE__ => 49, + :k__ENCODING__ => 50, + :tIDENTIFIER => 51, + :tFID => 52, + :tGVAR => 53, + :tIVAR => 54, + :tCONSTANT => 55, + :tLABEL => 56, + :tCVAR => 57, + :tNTH_REF => 58, + :tBACK_REF => 59, + :tSTRING_CONTENT => 60, + :tINTEGER => 61, + :tFLOAT => 62, + :tUPLUS => 63, + :tUMINUS => 64, + :tUNARY_NUM => 65, + :tPOW => 66, + :tCMP => 67, + :tEQ => 68, + :tEQQ => 69, + :tNEQ => 70, + :tGEQ => 71, + :tLEQ => 72, + :tANDOP => 73, + :tOROP => 74, + :tMATCH => 75, + :tNMATCH => 76, + :tDOT => 77, + :tDOT2 => 78, + :tDOT3 => 79, + :tAREF => 80, + :tASET => 81, + :tLSHFT => 82, + :tRSHFT => 83, + :tCOLON2 => 84, + :tCOLON3 => 85, + :tOP_ASGN => 86, + :tASSOC => 87, + :tLPAREN => 88, + :tLPAREN2 => 89, + :tRPAREN => 90, + :tLPAREN_ARG => 91, + :tLBRACK => 92, + :tLBRACK2 => 93, + :tRBRACK => 94, + :tLBRACE => 95, + :tLBRACE_ARG => 96, + :tSTAR => 97, + :tSTAR2 => 98, + :tAMPER => 99, + :tAMPER2 => 100, + :tTILDE => 101, + :tPERCENT => 102, + :tDIVIDE => 103, + :tDSTAR => 104, + :tPLUS => 105, + :tMINUS => 106, + :tLT => 107, + :tGT => 108, + :tPIPE => 109, + :tBANG => 110, + :tCARET => 111, + :tLCURLY => 112, + :tRCURLY => 113, + :tBACK_REF2 => 114, + :tSYMBEG => 115, + :tSTRING_BEG => 116, + :tXSTRING_BEG => 117, + :tREGEXP_BEG => 118, + :tREGEXP_OPT => 119, + :tWORDS_BEG => 120, + :tQWORDS_BEG => 121, + :tSYMBOLS_BEG => 122, + :tQSYMBOLS_BEG => 123, + :tSTRING_DBEG => 124, + :tSTRING_DVAR => 125, + :tSTRING_END => 126, + :tSTRING_DEND => 127, + :tSTRING => 128, + :tSYMBOL => 129, + :tNL => 130, + :tEH => 131, + :tCOLON => 132, + :tCOMMA => 133, + :tSPACE => 134, + :tSEMI => 135, + :tLAMBDA => 136, + :tLAMBEG => 137, + :tCHARACTER => 138, + :tEQL => 139, + :tLOWEST => 140 } + +racc_nt_base = 141 + +racc_use_result_var = true + +Racc_arg = [ + racc_action_table, + racc_action_check, + racc_action_default, + racc_action_pointer, + racc_goto_table, + racc_goto_check, + racc_goto_default, + racc_goto_pointer, + racc_nt_base, + racc_reduce_table, + racc_token_table, + racc_shift_n, + racc_reduce_n, + racc_use_result_var ] +Ractor.make_shareable(Racc_arg) if defined?(Ractor) + +Racc_token_to_s_table = [ + "$end", + "error", + "kCLASS", + "kMODULE", + "kDEF", + "kUNDEF", + "kBEGIN", + "kRESCUE", + "kENSURE", + "kEND", + "kIF", + "kUNLESS", + "kTHEN", + "kELSIF", + "kELSE", + "kCASE", + "kWHEN", + "kWHILE", + "kUNTIL", + "kFOR", + "kBREAK", + "kNEXT", + "kREDO", + "kRETRY", + "kIN", + "kDO", + "kDO_COND", + "kDO_BLOCK", + "kDO_LAMBDA", + "kRETURN", + "kYIELD", + "kSUPER", + "kSELF", + "kNIL", + "kTRUE", + "kFALSE", + "kAND", + "kOR", + "kNOT", + "kIF_MOD", + "kUNLESS_MOD", + "kWHILE_MOD", + "kUNTIL_MOD", + "kRESCUE_MOD", + "kALIAS", + "kDEFINED", + "klBEGIN", + "klEND", + "k__LINE__", + "k__FILE__", + "k__ENCODING__", + "tIDENTIFIER", + "tFID", + "tGVAR", + "tIVAR", + "tCONSTANT", + "tLABEL", + "tCVAR", + "tNTH_REF", + "tBACK_REF", + "tSTRING_CONTENT", + "tINTEGER", + "tFLOAT", + "tUPLUS", + "tUMINUS", + "tUNARY_NUM", + "tPOW", + "tCMP", + "tEQ", + "tEQQ", + "tNEQ", + "tGEQ", + "tLEQ", + "tANDOP", + "tOROP", + "tMATCH", + "tNMATCH", + "tDOT", + "tDOT2", + "tDOT3", + "tAREF", + "tASET", + "tLSHFT", + "tRSHFT", + "tCOLON2", + "tCOLON3", + "tOP_ASGN", + "tASSOC", + "tLPAREN", + "tLPAREN2", + "tRPAREN", + "tLPAREN_ARG", + "tLBRACK", + "tLBRACK2", + "tRBRACK", + "tLBRACE", + "tLBRACE_ARG", + "tSTAR", + "tSTAR2", + "tAMPER", + "tAMPER2", + "tTILDE", + "tPERCENT", + "tDIVIDE", + "tDSTAR", + "tPLUS", + "tMINUS", + "tLT", + "tGT", + "tPIPE", + "tBANG", + "tCARET", + "tLCURLY", + "tRCURLY", + "tBACK_REF2", + "tSYMBEG", + "tSTRING_BEG", + "tXSTRING_BEG", + "tREGEXP_BEG", + "tREGEXP_OPT", + "tWORDS_BEG", + "tQWORDS_BEG", + "tSYMBOLS_BEG", + "tQSYMBOLS_BEG", + "tSTRING_DBEG", + "tSTRING_DVAR", + "tSTRING_END", + "tSTRING_DEND", + "tSTRING", + "tSYMBOL", + "tNL", + "tEH", + "tCOLON", + "tCOMMA", + "tSPACE", + "tSEMI", + "tLAMBDA", + "tLAMBEG", + "tCHARACTER", + "tEQL", + "tLOWEST", + "$start", + "program", + "top_compstmt", + "top_stmts", + "opt_terms", + "top_stmt", + "terms", + "stmt", + "bodystmt", + "compstmt", + "opt_rescue", + "opt_else", + "opt_ensure", + "stmts", + "stmt_or_begin", + "fitem", + "undef_list", + "expr_value", + "command_asgn", + "mlhs", + "command_call", + "var_lhs", + "primary_value", + "opt_call_args", + "rbracket", + "backref", + "lhs", + "mrhs", + "arg_value", + "expr", + "@1", + "opt_nl", + "arg", + "command", + "block_command", + "block_call", + "dot_or_colon", + "operation2", + "command_args", + "cmd_brace_block", + "opt_block_param", + "fcall", + "@2", + "operation", + "call_args", + "mlhs_basic", + "mlhs_inner", + "rparen", + "mlhs_head", + "mlhs_item", + "mlhs_node", + "mlhs_post", + "user_variable", + "keyword_variable", + "cname", + "cpath", + "fname", + "op", + "reswords", + "fsym", + "symbol", + "dsym", + "@3", + "primary", + "aref_args", + "none", + "args", + "trailer", + "assocs", + "paren_args", + "opt_paren_args", + "opt_block_arg", + "block_arg", + "@4", + "literal", + "strings", + "xstring", + "regexp", + "words", + "qwords", + "symbols", + "qsymbols", + "var_ref", + "assoc_list", + "brace_block", + "method_call", + "lambda", + "then", + "if_tail", + "do", + "case_body", + "for_var", + "k_class", + "superclass", + "term", + "k_module", + "f_arglist", + "singleton", + "@5", + "@6", + "@7", + "@8", + "@9", + "@10", + "@11", + "@12", + "@13", + "@14", + "@15", + "@16", + "@17", + "@18", + "@19", + "@20", + "@21", + "f_marg", + "f_norm_arg", + "f_margs", + "f_marg_list", + "block_args_tail", + "f_block_kwarg", + "f_kwrest", + "opt_f_block_arg", + "f_block_arg", + "opt_block_args_tail", + "block_param", + "f_arg", + "f_block_optarg", + "f_rest_arg", + "block_param_def", + "opt_bv_decl", + "bv_decls", + "bvar", + "f_bad_arg", + "f_larglist", + "lambda_body", + "@22", + "f_args", + "do_block", + "@23", + "@24", + "@25", + "operation3", + "@26", + "@27", + "cases", + "exc_list", + "exc_var", + "numeric", + "string", + "string1", + "string_contents", + "xstring_contents", + "regexp_contents", + "word_list", + "word", + "string_content", + "symbol_list", + "qword_list", + "qsym_list", + "string_dvar", + "@28", + "@29", + "args_tail", + "f_kwarg", + "opt_args_tail", + "f_optarg", + "f_arg_item", + "f_kw", + "f_block_kw", + "kwrest_mark", + "f_opt", + "f_block_opt", + "restarg_mark", + "blkarg_mark", + "assoc" ] +Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) + +Racc_debug_parser = false + +##### State transition tables end ##### + +# reduce 0 omitted + +# reduce 1 omitted + +def _reduce_2(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_3(val, _values, result) + result = [] + + result +end + +def _reduce_4(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_5(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_6(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 7 omitted + +def _reduce_8(val, _values, result) + result = @builder.preexe(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_9(val, _values, result) + rescue_bodies = val[1] + else_t, else_ = val[2] + ensure_t, ensure_ = val[3] + + if rescue_bodies.empty? && !else_t.nil? + diagnostic :warning, :useless_else, nil, else_t + end + + result = @builder.begin_body(val[0], + rescue_bodies, + else_t, else_, + ensure_t, ensure_) + + result +end + +def _reduce_10(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_11(val, _values, result) + result = [] + + result +end + +def _reduce_12(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_13(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_14(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 15 omitted + +def _reduce_16(val, _values, result) + if @context.in_def + diagnostic :error, :begin_in_method, nil, val[0] + end + + result = @builder.preexe(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_17(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_18(val, _values, result) + result = @builder.alias(val[0], val[1], val[3]) + + result +end + +def _reduce_19(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.gvar(val[2])) + + result +end + +def _reduce_20(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.back_ref(val[2])) + + result +end + +def _reduce_21(val, _values, result) + diagnostic :error, :nth_ref_alias, nil, val[2] + + result +end + +def _reduce_22(val, _values, result) + result = @builder.undef_method(val[0], val[1]) + + result +end + +def _reduce_23(val, _values, result) + result = @builder.condition_mod(val[0], nil, + val[1], val[2]) + + result +end + +def _reduce_24(val, _values, result) + result = @builder.condition_mod(nil, val[0], + val[1], val[2]) + + result +end + +def _reduce_25(val, _values, result) + result = @builder.loop_mod(:while, val[0], val[1], val[2]) + + result +end + +def _reduce_26(val, _values, result) + result = @builder.loop_mod(:until, val[0], val[1], val[2]) + + result +end + +def _reduce_27(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_28(val, _values, result) + result = @builder.postexe(val[0], val[1], val[2], val[3]) + + result +end + +# reduce 29 omitted + +def _reduce_30(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_31(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_32(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_33(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_34(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_35(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_36(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_37(val, _values, result) + @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_38(val, _values, result) + result = @builder.assign(val[0], val[1], + @builder.array(nil, val[2], nil)) + + result +end + +def _reduce_39(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_40(val, _values, result) + result = @builder.multi_assign(val[0], val[1], + @builder.array(nil, val[2], nil)) + + result +end + +# reduce 41 omitted + +def _reduce_42(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_43(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +# reduce 44 omitted + +def _reduce_45(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_46(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_47(val, _values, result) + result = @builder.not_op(val[0], nil, val[2], nil) + + result +end + +def _reduce_48(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +# reduce 49 omitted + +# reduce 50 omitted + +# reduce 51 omitted + +# reduce 52 omitted + +# reduce 53 omitted + +def _reduce_54(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_55(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_56(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +# reduce 57 omitted + +def _reduce_58(val, _values, result) + result = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + result +end + +def _reduce_59(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + begin_t, args, body, end_t = val[2] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_60(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_61(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_62(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_63(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_64(val, _values, result) + result = @builder.keyword_cmd(:super, val[0], + nil, val[1], nil) + + result +end + +def _reduce_65(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], + nil, val[1], nil) + + result +end + +def _reduce_66(val, _values, result) + result = @builder.keyword_cmd(:return, val[0], + nil, val[1], nil) + + result +end + +def _reduce_67(val, _values, result) + result = @builder.keyword_cmd(:break, val[0], + nil, val[1], nil) + + result +end + +def _reduce_68(val, _values, result) + result = @builder.keyword_cmd(:next, val[0], + nil, val[1], nil) + + result +end + +def _reduce_69(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_70(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_71(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_72(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +# reduce 73 omitted + +def _reduce_74(val, _values, result) + result = val[0]. + push(val[1]) + + result +end + +def _reduce_75(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])) + + result +end + +def _reduce_76(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])). + concat(val[4]) + + result +end + +def _reduce_77(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])) + + result +end + +def _reduce_78(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])). + concat(val[3]) + + result +end + +def _reduce_79(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_80(val, _values, result) + result = [ @builder.splat(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_81(val, _values, result) + result = [ @builder.splat(val[0]) ] + + result +end + +def _reduce_82(val, _values, result) + result = [ @builder.splat(val[0]), + *val[2] ] + + result +end + +# reduce 83 omitted + +def _reduce_84(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_85(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_86(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_87(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_88(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_89(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_90(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_91(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_92(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_93(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_94(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_95(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_96(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_97(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_98(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_99(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_100(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_101(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_102(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_103(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_104(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_105(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_106(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_107(val, _values, result) + diagnostic :error, :module_name_const, nil, val[0] + + result +end + +# reduce 108 omitted + +def _reduce_109(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_110(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_111(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +# reduce 112 omitted + +# reduce 113 omitted + +# reduce 114 omitted + +# reduce 115 omitted + +# reduce 116 omitted + +def _reduce_117(val, _values, result) + result = @builder.symbol_internal(val[0]) + + result +end + +# reduce 118 omitted + +# reduce 119 omitted + +# reduce 120 omitted + +def _reduce_121(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_122(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_123(val, _values, result) + result = val[0] << val[3] + + result +end + +# reduce 124 omitted + +# reduce 125 omitted + +# reduce 126 omitted + +# reduce 127 omitted + +# reduce 128 omitted + +# reduce 129 omitted + +# reduce 130 omitted + +# reduce 131 omitted + +# reduce 132 omitted + +# reduce 133 omitted + +# reduce 134 omitted + +# reduce 135 omitted + +# reduce 136 omitted + +# reduce 137 omitted + +# reduce 138 omitted + +# reduce 139 omitted + +# reduce 140 omitted + +# reduce 141 omitted + +# reduce 142 omitted + +# reduce 143 omitted + +# reduce 144 omitted + +# reduce 145 omitted + +# reduce 146 omitted + +# reduce 147 omitted + +# reduce 148 omitted + +# reduce 149 omitted + +# reduce 150 omitted + +# reduce 151 omitted + +# reduce 152 omitted + +# reduce 153 omitted + +# reduce 154 omitted + +# reduce 155 omitted + +# reduce 156 omitted + +# reduce 157 omitted + +# reduce 158 omitted + +# reduce 159 omitted + +# reduce 160 omitted + +# reduce 161 omitted + +# reduce 162 omitted + +# reduce 163 omitted + +# reduce 164 omitted + +# reduce 165 omitted + +# reduce 166 omitted + +# reduce 167 omitted + +# reduce 168 omitted + +# reduce 169 omitted + +# reduce 170 omitted + +# reduce 171 omitted + +# reduce 172 omitted + +# reduce 173 omitted + +# reduce 174 omitted + +# reduce 175 omitted + +# reduce 176 omitted + +# reduce 177 omitted + +# reduce 178 omitted + +# reduce 179 omitted + +# reduce 180 omitted + +# reduce 181 omitted + +# reduce 182 omitted + +# reduce 183 omitted + +# reduce 184 omitted + +# reduce 185 omitted + +# reduce 186 omitted + +# reduce 187 omitted + +# reduce 188 omitted + +# reduce 189 omitted + +# reduce 190 omitted + +# reduce 191 omitted + +# reduce 192 omitted + +# reduce 193 omitted + +# reduce 194 omitted + +def _reduce_195(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_196(val, _values, result) + rescue_body = @builder.rescue_body(val[3], + nil, nil, nil, + nil, val[4]) + + rescue_ = @builder.begin_body(val[2], [ rescue_body ]) + + result = @builder.assign(val[0], val[1], rescue_) + + result +end + +def _reduce_197(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_198(val, _values, result) + rescue_body = @builder.rescue_body(val[3], + nil, nil, nil, + nil, val[4]) + + rescue_ = @builder.begin_body(val[2], [ rescue_body ]) + + result = @builder.op_assign(val[0], val[1], rescue_) + + result +end + +def _reduce_199(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_200(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_201(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_202(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_203(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_204(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_global(val[0], val[1])) + result = @builder.op_assign(const, val[2], val[3]) + + result +end + +def _reduce_205(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_206(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_207(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_208(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_209(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_210(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_211(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_212(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_213(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_214(val, _values, result) + result = @builder.unary_op(val[0], + @builder.binary_op( + @builder.integer(val[1]), + val[2], val[3])) + + result +end + +def _reduce_215(val, _values, result) + result = @builder.unary_op(val[0], + @builder.binary_op( + @builder.float(val[1]), + val[2], val[3])) + + result +end + +def _reduce_216(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_217(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_218(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_219(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_220(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_221(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_222(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_223(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_224(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_225(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_226(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_227(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_228(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_229(val, _values, result) + result = @builder.match_op(val[0], val[1], val[2]) + + result +end + +def _reduce_230(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_231(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +def _reduce_232(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_233(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_234(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_235(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_236(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_237(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil) + + result +end + +def _reduce_238(val, _values, result) + result = @builder.ternary(val[0], val[1], + val[2], val[4], val[5]) + + result +end + +# reduce 239 omitted + +# reduce 240 omitted + +# reduce 241 omitted + +# reduce 242 omitted + +def _reduce_243(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_244(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +def _reduce_245(val, _values, result) + result = val + + result +end + +def _reduce_246(val, _values, result) + result = [ nil, [], nil ] + + result +end + +# reduce 247 omitted + +def _reduce_248(val, _values, result) + result = [] + + result +end + +# reduce 249 omitted + +# reduce 250 omitted + +def _reduce_251(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_252(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +def _reduce_253(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_254(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_255(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + result.concat(val[1]) + + result +end + +def _reduce_256(val, _values, result) + assocs = @builder.associate(nil, val[2], nil) + result = val[0] << assocs + result.concat(val[3]) + + result +end + +def _reduce_257(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_258(val, _values, result) + result = @lexer.cmdarg.dup + @lexer.cmdarg.push(true) + + result +end + +def _reduce_259(val, _values, result) + @lexer.cmdarg = val[0] + + result = val[1] + + result +end + +def _reduce_260(val, _values, result) + result = @builder.block_pass(val[0], val[1]) + + result +end + +def _reduce_261(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_262(val, _values, result) + result = [] + + result +end + +def _reduce_263(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_264(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_265(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_266(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_267(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_268(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_269(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +# reduce 270 omitted + +# reduce 271 omitted + +# reduce 272 omitted + +# reduce 273 omitted + +# reduce 274 omitted + +# reduce 275 omitted + +# reduce 276 omitted + +# reduce 277 omitted + +# reduce 278 omitted + +# reduce 279 omitted + +def _reduce_280(val, _values, result) + result = @builder.call_method(nil, nil, val[0]) + + result +end + +def _reduce_281(val, _values, result) + result = @lexer.cmdarg.dup + @lexer.cmdarg.clear + + result +end + +def _reduce_282(val, _values, result) + @lexer.cmdarg = val[1] + + result = @builder.begin_keyword(val[0], val[2], val[3]) + + result +end + +def _reduce_283(val, _values, result) + result = @lexer.cmdarg.dup + @lexer.cmdarg.clear + + result +end + +def _reduce_284(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_285(val, _values, result) + @lexer.cmdarg = val[1] + + result = @builder.begin(val[0], val[2], val[5]) + + result +end + +def _reduce_286(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_287(val, _values, result) + result = @builder.begin(val[0], nil, val[3]) + + result +end + +def _reduce_288(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_289(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +def _reduce_290(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_291(val, _values, result) + result = @builder.array(val[0], val[1], val[2]) + + result +end + +def _reduce_292(val, _values, result) + result = @builder.associate(val[0], val[1], val[2]) + + result +end + +def _reduce_293(val, _values, result) + result = @builder.keyword_cmd(:return, val[0]) + + result +end + +def _reduce_294(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_295(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2]) + + result +end + +def _reduce_296(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0]) + + result +end + +def _reduce_297(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], + val[2], [ val[3] ], val[4]) + + result +end + +def _reduce_298(val, _values, result) + result = @builder.not_op(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_299(val, _values, result) + result = @builder.not_op(val[0], val[1], nil, val[2]) + + result +end + +def _reduce_300(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0]) + + begin_t, args, body, end_t = val[1] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +# reduce 301 omitted + +def _reduce_302(val, _values, result) + begin_t, args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, args, body, end_t) + + result +end + +def _reduce_303(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_304(val, _values, result) + lambda_call = @builder.call_lambda(val[0]) + + args, (begin_t, body, end_t) = val[2] + result = @builder.block(lambda_call, + begin_t, args, body, end_t) + + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_305(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, val[5]) + + result +end + +def _reduce_306(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + else_, else_t, + val[3], val[5]) + + result +end + +def _reduce_307(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_308(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_309(val, _values, result) + result = @builder.loop(:while, val[0], val[2], val[3], + val[5], val[6]) + + result +end + +def _reduce_310(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_311(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_312(val, _values, result) + result = @builder.loop(:until, val[0], val[2], val[3], + val[5], val[6]) + + result +end + +def _reduce_313(val, _values, result) + *when_bodies, (else_t, else_body) = *val[3] + + result = @builder.case(val[0], val[1], + when_bodies, else_t, else_body, + val[4]) + + result +end + +def _reduce_314(val, _values, result) + *when_bodies, (else_t, else_body) = *val[2] + + result = @builder.case(val[0], nil, + when_bodies, else_t, else_body, + val[3]) + + result +end + +def _reduce_315(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_316(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_317(val, _values, result) + result = @builder.for(val[0], val[1], + val[2], val[4], + val[5], val[7], val[8]) + + result +end + +def _reduce_318(val, _values, result) + local_push + @context.in_class = true + + result +end + +def _reduce_319(val, _values, result) + k_class, ctx = val[0] + if @context.in_def + diagnostic :error, :class_in_def, nil, k_class + end + + lt_t, superclass = val[2] + result = @builder.def_class(k_class, val[1], + lt_t, superclass, + val[4], val[5]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_320(val, _values, result) + @context.in_def = false + @context.in_class = false + local_push + + result +end + +def _reduce_321(val, _values, result) + k_class, ctx = val[0] + result = @builder.def_sclass(k_class, val[1], val[2], + val[5], val[6]) + + local_pop + @context.in_def = ctx.in_def + @context.in_class = ctx.in_class + + result +end + +def _reduce_322(val, _values, result) + @context.in_class = true + local_push + + result +end + +def _reduce_323(val, _values, result) + k_mod, ctx = val[0] + if @context.in_def + diagnostic :error, :module_in_def, nil, k_mod + end + + result = @builder.def_module(k_mod, val[1], + val[3], val[4]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_324(val, _values, result) + local_push + result = context.dup + @context.in_def = true + + result +end + +def _reduce_325(val, _values, result) + result = @builder.def_method(val[0], val[1], + val[3], val[4], val[5]) + + local_pop + @context.in_def = val[2].in_def + + result +end + +def _reduce_326(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_327(val, _values, result) + local_push + result = context.dup + @context.in_def = true + + result +end + +def _reduce_328(val, _values, result) + result = @builder.def_singleton(val[0], val[1], val[2], + val[4], val[6], val[7], val[8]) + + local_pop + @context.in_def = val[5].in_def + + result +end + +def _reduce_329(val, _values, result) + result = @builder.keyword_cmd(:break, val[0]) + + result +end + +def _reduce_330(val, _values, result) + result = @builder.keyword_cmd(:next, val[0]) + + result +end + +def _reduce_331(val, _values, result) + result = @builder.keyword_cmd(:redo, val[0]) + + result +end + +def _reduce_332(val, _values, result) + result = @builder.keyword_cmd(:retry, val[0]) + + result +end + +# reduce 333 omitted + +def _reduce_334(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_335(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +# reduce 336 omitted + +# reduce 337 omitted + +def _reduce_338(val, _values, result) + result = val[1] + + result +end + +# reduce 339 omitted + +# reduce 340 omitted + +# reduce 341 omitted + +def _reduce_342(val, _values, result) + else_t, else_ = val[4] + result = [ val[0], + @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, nil), + ] + + result +end + +# reduce 343 omitted + +def _reduce_344(val, _values, result) + result = val + + result +end + +# reduce 345 omitted + +# reduce 346 omitted + +def _reduce_347(val, _values, result) + @static_env.declare val[0][0] + + result = @builder.arg(val[0]) + + result +end + +def _reduce_348(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_349(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_350(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 351 omitted + +def _reduce_352(val, _values, result) + @static_env.declare val[3][0] + + result = val[0]. + push(@builder.restarg(val[2], val[3])) + + result +end + +def _reduce_353(val, _values, result) + @static_env.declare val[3][0] + + result = val[0]. + push(@builder.restarg(val[2], val[3])). + concat(val[5]) + + result +end + +def _reduce_354(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2])) + + result +end + +def _reduce_355(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2])). + concat(val[4]) + + result +end + +def _reduce_356(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_357(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.restarg(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_358(val, _values, result) + result = [ @builder.restarg(val[0]) ] + + result +end + +def _reduce_359(val, _values, result) + result = [ @builder.restarg(val[0]), + *val[2] ] + + result +end + +def _reduce_360(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_361(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_362(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_363(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_364(val, _values, result) + result = val[1] + + result +end + +def _reduce_365(val, _values, result) + result = [] + + result +end + +def _reduce_366(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_367(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_368(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_369(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_370(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 371 omitted + +def _reduce_372(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_373(val, _values, result) + if val[1].empty? && val[0].size == 1 + result = [@builder.procarg0(val[0][0])] + else + result = val[0].concat(val[1]) + end + + result +end + +def _reduce_374(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_375(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_376(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_377(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_378(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_379(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 380 omitted + +def _reduce_381(val, _values, result) + result = @builder.args(nil, [], nil) + + result +end + +def _reduce_382(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_383(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + result +end + +def _reduce_384(val, _values, result) + result = @builder.args(val[0], [], val[0]) + + result +end + +def _reduce_385(val, _values, result) + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_386(val, _values, result) + result = [] + + result +end + +def _reduce_387(val, _values, result) + result = val[2] + + result +end + +def _reduce_388(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_389(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_390(val, _values, result) + @static_env.declare val[0][0] + result = @builder.shadowarg(val[0]) + + result +end + +# reduce 391 omitted + +def _reduce_392(val, _values, result) + @static_env.extend_dynamic + + result +end + +def _reduce_393(val, _values, result) + result = [ val[1], val[2] ] + + @static_env.unextend + + result +end + +def _reduce_394(val, _values, result) + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_395(val, _values, result) + result = @builder.args(nil, val[0], nil) + + result +end + +def _reduce_396(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_397(val, _values, result) + result = [ val[0], val[2], val[3] ] + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_398(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_399(val, _values, result) + result = [ val[0], val[2], val[3] ] + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_400(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_401(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_402(val, _values, result) + begin_t, block_args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, block_args, body, end_t) + + result +end + +def _reduce_403(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_404(val, _values, result) + lparen_t, args, rparen_t = val[3] + method_call = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_405(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_406(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.call_method(nil, nil, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_407(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_408(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_409(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2]) + + result +end + +def _reduce_410(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_411(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_412(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.keyword_cmd(:super, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_413(val, _values, result) + result = @builder.keyword_cmd(:zsuper, val[0]) + + result +end + +def _reduce_414(val, _values, result) + result = @builder.index(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_415(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_416(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_417(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_418(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_419(val, _values, result) + result = [ @builder.when(val[0], val[1], val[2], val[3]), + *val[4] ] + + result +end + +def _reduce_420(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 421 omitted + +def _reduce_422(val, _values, result) + assoc_t, exc_var = val[2] + + if val[1] + exc_list = @builder.array(nil, val[1], nil) + end + + result = [ @builder.rescue_body(val[0], + exc_list, assoc_t, exc_var, + val[3], val[4]), + *val[5] ] + + result +end + +def _reduce_423(val, _values, result) + result = [] + + result +end + +def _reduce_424(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 425 omitted + +# reduce 426 omitted + +def _reduce_427(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 428 omitted + +def _reduce_429(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 430 omitted + +# reduce 431 omitted + +# reduce 432 omitted + +# reduce 433 omitted + +def _reduce_434(val, _values, result) + result = @builder.string_compose(nil, val[0], nil) + + result +end + +def _reduce_435(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_436(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_437(val, _values, result) + result = @builder.string_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_438(val, _values, result) + result = @builder.string(val[0]) + + result +end + +def _reduce_439(val, _values, result) + result = @builder.character(val[0]) + + result +end + +def _reduce_440(val, _values, result) + result = @builder.xstring_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_441(val, _values, result) + opts = @builder.regexp_options(val[3]) + result = @builder.regexp_compose(val[0], val[1], val[2], opts) + + result +end + +def _reduce_442(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_443(val, _values, result) + result = [] + + result +end + +def _reduce_444(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_445(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_446(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_447(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_448(val, _values, result) + result = [] + + result +end + +def _reduce_449(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_450(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_451(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_452(val, _values, result) + result = [] + + result +end + +def _reduce_453(val, _values, result) + result = val[0] << @builder.string_internal(val[1]) + + result +end + +def _reduce_454(val, _values, result) + result = [] + + result +end + +def _reduce_455(val, _values, result) + result = val[0] << @builder.symbol_internal(val[1]) + + result +end + +def _reduce_456(val, _values, result) + result = [] + + result +end + +def _reduce_457(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_458(val, _values, result) + result = [] + + result +end + +def _reduce_459(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_460(val, _values, result) + result = [] + + result +end + +def _reduce_461(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_462(val, _values, result) + result = @builder.string_internal(val[0]) + + result +end + +def _reduce_463(val, _values, result) + result = val[1] + + result +end + +def _reduce_464(val, _values, result) + @lexer.cond.push(false) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_465(val, _values, result) + @lexer.cond.lexpop + @lexer.cmdarg.lexpop + + result = @builder.begin(val[0], val[2], val[3]) + + result +end + +def _reduce_466(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_467(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_468(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +# reduce 469 omitted + +def _reduce_470(val, _values, result) + result = @builder.symbol(val[0]) + + result +end + +def _reduce_471(val, _values, result) + result = @builder.symbol_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_472(val, _values, result) + result = @builder.integer(val[0]) + + result +end + +def _reduce_473(val, _values, result) + result = @builder.float(val[0]) + + result +end + +def _reduce_474(val, _values, result) + num = @builder.integer(val[1]) + if @builder.respond_to? :negate + # AST builder interface compatibility + result = @builder.negate(val[0], num) + else + result = @builder.unary_num(val[0], num) + end + + result +end + +def _reduce_475(val, _values, result) + num = @builder.float(val[1]) + if @builder.respond_to? :negate + # AST builder interface compatibility + result = @builder.negate(val[0], num) + else + result = @builder.unary_num(val[0], num) + end + + result +end + +def _reduce_476(val, _values, result) + result = @builder.ident(val[0]) + + result +end + +def _reduce_477(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_478(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_479(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_480(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +def _reduce_481(val, _values, result) + result = @builder.nil(val[0]) + + result +end + +def _reduce_482(val, _values, result) + result = @builder.self(val[0]) + + result +end + +def _reduce_483(val, _values, result) + result = @builder.true(val[0]) + + result +end + +def _reduce_484(val, _values, result) + result = @builder.false(val[0]) + + result +end + +def _reduce_485(val, _values, result) + result = @builder.__FILE__(val[0]) + + result +end + +def _reduce_486(val, _values, result) + result = @builder.__LINE__(val[0]) + + result +end + +def _reduce_487(val, _values, result) + result = @builder.__ENCODING__(val[0]) + + result +end + +def _reduce_488(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_489(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_490(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_491(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_492(val, _values, result) + result = @builder.nth_ref(val[0]) + + result +end + +def _reduce_493(val, _values, result) + result = @builder.back_ref(val[0]) + + result +end + +def _reduce_494(val, _values, result) + result = nil + + result +end + +def _reduce_495(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_496(val, _values, result) + result = [ val[0], val[2] ] + + result +end + +def _reduce_497(val, _values, result) + yyerrok + result = nil + + result +end + +def _reduce_498(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + @lexer.state = :expr_value + + result +end + +def _reduce_499(val, _values, result) + result = @builder.args(nil, val[0], nil) + + result +end + +def _reduce_500(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_501(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_502(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_503(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_504(val, _values, result) + result = val[1] + + result +end + +def _reduce_505(val, _values, result) + result = [] + + result +end + +def _reduce_506(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_507(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_508(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_509(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_510(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_511(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_512(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_513(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_514(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_515(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_516(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_517(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_518(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_519(val, _values, result) + result = val[0] + + result +end + +def _reduce_520(val, _values, result) + result = [] + + result +end + +def _reduce_521(val, _values, result) + diagnostic :error, :argument_const, nil, val[0] + + result +end + +def _reduce_522(val, _values, result) + diagnostic :error, :argument_ivar, nil, val[0] + + result +end + +def _reduce_523(val, _values, result) + diagnostic :error, :argument_gvar, nil, val[0] + + result +end + +def _reduce_524(val, _values, result) + diagnostic :error, :argument_cvar, nil, val[0] + + result +end + +# reduce 525 omitted + +# reduce 526 omitted + +def _reduce_527(val, _values, result) + @static_env.declare val[0][0] + + result = @builder.arg(val[0]) + + result +end + +def _reduce_528(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_529(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_530(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_531(val, _values, result) + check_kwarg_name(val[0]) + + @static_env.declare val[0][0] + + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_532(val, _values, result) + check_kwarg_name(val[0]) + + @static_env.declare val[0][0] + + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_533(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_534(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_535(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_536(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 537 omitted + +# reduce 538 omitted + +def _reduce_539(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.kwrestarg(val[0], val[1]) ] + + result +end + +def _reduce_540(val, _values, result) + result = [ @builder.kwrestarg(val[0]) ] + + result +end + +def _reduce_541(val, _values, result) + @static_env.declare val[0][0] + + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_542(val, _values, result) + @static_env.declare val[0][0] + + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_543(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_544(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_545(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_546(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 547 omitted + +# reduce 548 omitted + +def _reduce_549(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_550(val, _values, result) + result = [ @builder.restarg(val[0]) ] + + result +end + +# reduce 551 omitted + +# reduce 552 omitted + +def _reduce_553(val, _values, result) + @static_env.declare val[1][0] + + result = @builder.blockarg(val[0], val[1]) + + result +end + +def _reduce_554(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_555(val, _values, result) + result = [] + + result +end + +# reduce 556 omitted + +def _reduce_557(val, _values, result) + result = val[1] + + result +end + +def _reduce_558(val, _values, result) + result = [] + + result +end + +# reduce 559 omitted + +def _reduce_560(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_561(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_562(val, _values, result) + result = @builder.pair(val[0], val[1], val[2]) + + result +end + +def _reduce_563(val, _values, result) + result = @builder.pair_keyword(val[0], val[1]) + + result +end + +def _reduce_564(val, _values, result) + result = @builder.kwsplat(val[0], val[1]) + + result +end + +# reduce 565 omitted + +# reduce 566 omitted + +# reduce 567 omitted + +# reduce 568 omitted + +# reduce 569 omitted + +# reduce 570 omitted + +# reduce 571 omitted + +# reduce 572 omitted + +# reduce 573 omitted + +# reduce 574 omitted + +# reduce 575 omitted + +# reduce 576 omitted + +# reduce 577 omitted + +# reduce 578 omitted + +# reduce 579 omitted + +# reduce 580 omitted + +def _reduce_581(val, _values, result) + result = val[1] + + result +end + +def _reduce_582(val, _values, result) + result = val[1] + + result +end + +# reduce 583 omitted + +# reduce 584 omitted + +# reduce 585 omitted + +def _reduce_586(val, _values, result) + yyerrok + + result +end + +# reduce 587 omitted + +# reduce 588 omitted + +# reduce 589 omitted + +def _reduce_590(val, _values, result) + result = nil + + result +end + +def _reduce_none(val, _values, result) + val[0] +end + + end # class Ruby20 +end # module Parser diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby21.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby21.rb new file mode 100644 index 00000000..8ace577c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby21.rb @@ -0,0 +1,10203 @@ +# -*- encoding:utf-8; warn-indent:false; frozen_string_literal: true -*- +# +# DO NOT MODIFY!!!! +# This file is automatically generated by Racc 1.8.1 +# from Racc grammar file "ruby21.y". +# + +require 'racc/parser.rb' + + +require_relative '../parser' + +module Parser + class Ruby21 < Parser::Base + + + def version + 21 + end + + def default_encoding + Encoding::UTF_8 + end + + def local_push + @static_env.extend_static + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + end + + def local_pop + @static_env.unextend + @lexer.cmdarg.pop + @lexer.cond.pop + end +##### State transition tables begin ### + +racc_action_table = [ + -479, 216, 217, 216, 217, 270, -97, -479, -479, -479, + 219, 536, -479, -479, -479, 615, -479, 270, -286, 578, + 111, 615, 216, 217, -479, 580, -479, -479, -479, 526, + 270, 123, 525, -98, -105, 270, -479, -479, 557, -479, + -479, -479, -479, -479, 208, 536, -493, 536, 536, -104, + 614, 220, -100, 691, 615, 691, 614, 115, -286, 781, + 209, 542, 114, -494, -102, 867, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + 210, 265, -479, -479, -479, 577, -479, -479, -99, 614, + -479, 579, 269, -479, -479, 220, -479, 220, -479, 265, + -479, -97, -479, -479, 269, -479, -479, -479, -479, -479, + 536, -479, -482, -479, -100, -88, 220, 269, -98, -482, + -482, -482, 269, -102, -482, -482, -482, -479, -482, 115, + -479, -479, -479, -479, 114, -479, -482, -479, -482, -482, + -482, -479, -89, -96, 556, 214, -101, 691, -482, -482, + -101, -482, -482, -482, -482, -482, -99, 115, -95, 115, + -91, -91, 114, 115, 114, 115, 115, 115, 114, 818, + 114, 114, 114, -93, 866, -103, 216, 217, -482, -482, + -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, + -482, -482, -96, 444, -482, -482, -482, -90, -482, -482, + -105, -93, -482, 93, 94, -482, -482, 215, -482, 548, + -482, -575, -482, 549, -482, -482, 514, -482, -482, -482, + -482, -482, -289, -482, 259, -482, -91, -575, 115, -289, + -289, -289, -100, 114, 317, -289, -289, -100, -289, -482, + -576, -102, -482, -482, -482, -482, -102, -482, -105, -482, + 262, 115, 565, -482, 746, -92, 114, 263, -289, -289, + 318, -289, -289, -289, -289, -289, -91, -93, -101, -91, + 115, -104, 565, -101, -99, 114, 615, -91, 115, -99, + 220, 95, 96, 114, -94, -493, 93, 94, -289, -289, + -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, + -289, -289, 565, 747, -289, -289, -289, -93, 598, -100, + -93, 614, -289, -83, -494, -289, 567, 566, -93, 386, + -289, -69, -289, 399, -289, -289, 723, -289, -289, -289, + -289, -289, -88, -289, -579, -289, 567, 566, 514, 836, + -97, -579, -579, -579, 593, 443, 725, -579, -579, -289, + -579, 115, -289, -289, 445, -94, 114, -289, -102, -579, + 446, -89, -572, -103, 95, 96, 567, 566, 563, -98, + -579, -579, -479, -579, -579, -579, -579, -579, 669, -479, + 666, 665, 664, 219, 667, -95, 669, 565, 666, 665, + 664, -91, 667, -104, -99, 216, 217, 477, -573, -100, + -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, + -579, -579, -579, -579, -479, 212, -579, -579, -579, 486, + 599, -479, 213, 488, -579, 565, -572, -579, 673, 490, + -479, 211, -579, 594, -579, -579, -579, -579, 676, -579, + -579, -579, -579, -579, 497, -579, -579, -579, -482, -572, + -482, 567, 566, 568, 565, -482, -68, -482, 220, 565, + 885, -579, -573, 565, -579, -579, -482, -92, 982, -579, + -579, 684, 683, 500, -489, -101, 677, -579, -579, -579, + -93, -489, -579, -579, -579, -573, -579, -579, -102, 567, + 566, 570, 501, 81, -579, -579, -579, -579, -579, -575, + 508, -333, 274, -579, 732, 82, -579, -579, -333, -579, + -579, -579, -579, -579, 440, 83, 220, -333, 567, 566, + 572, 441, -579, 567, 566, 576, -488, 567, 566, 581, + 442, 526, 526, -488, 528, 528, -579, -579, -579, -579, + -579, -579, -579, -579, -579, -579, -579, -579, -579, -579, + 265, -90, -579, -579, -579, 240, 748, -579, -491, -99, + -579, 511, -490, -579, -579, -491, -579, 515, -579, -490, + -579, 240, -579, -579, -491, -579, -579, -579, -579, -579, + 115, -579, -579, -579, 220, 114, -487, 237, 529, -484, + 530, 239, 238, -487, 235, 236, -484, -579, 490, 115, + -579, -579, -579, -579, 114, -579, -289, -579, 74, 75, + 71, -101, 57, -289, -289, -289, 63, 64, -289, -289, + -289, 67, -289, 65, 66, 68, 30, 31, 72, 73, + 216, 217, -289, -289, -289, 29, 28, 27, 103, 102, + 104, 105, -289, -289, 232, -289, -289, -289, -289, -289, + 526, 45, 542, 528, 107, 106, 108, 97, 56, 99, + 98, 100, 388, 101, 109, 110, 546, 93, 94, 42, + 43, 41, -289, -289, -289, -289, -289, -289, -289, -289, + -289, -289, -289, -289, -289, -289, 216, 217, -289, -289, + -289, 225, 749, -289, 231, 547, -289, 58, 59, -289, + -289, 60, -289, -485, -289, 582, -289, 44, -289, -289, + -485, -289, -289, -289, -289, -289, 230, -289, -486, -289, + 585, 91, 81, 84, 85, -486, 86, 88, 87, 89, + 813, 781, -261, -289, 82, 90, -289, -289, -289, -289, + 587, -289, 62, -289, 83, 95, 96, -103, 5, 74, + 75, 71, 9, 57, 262, 115, 220, 63, 64, 967, + 114, 263, 67, 220, 65, 66, 68, 30, 31, 72, + 73, 591, -579, 684, 683, 592, 29, 28, 27, 103, + 102, 104, 105, 396, 265, 19, 813, 781, 398, 397, + 603, 8, 45, 7, 10, 107, 106, 108, 97, 56, + 99, 98, 100, 602, 101, 109, 110, 605, 93, 94, + 42, 43, 41, 240, 244, 249, 250, 251, 246, 248, + 256, 257, 252, 253, -579, 233, 234, -492, 240, 254, + 255, -579, 40, 240, -492, 33, -575, 240, 58, 59, + -579, 240, 60, -492, 35, 237, 220, 243, 44, 239, + 238, 673, 235, 236, 247, 245, 241, 20, 242, -579, + 220, 676, 91, 81, 84, 85, 506, 86, 88, 87, + 89, 220, -83, 507, 633, 82, 90, 220, 258, 519, + -238, 644, 505, 62, 649, 83, 95, 96, 291, 74, + 75, 71, 9, 57, 684, 683, 650, 63, 64, 677, + 652, 687, 67, 542, 65, 66, 68, 30, 31, 72, + 73, 694, -415, 712, 722, 726, 29, 28, 27, 103, + 102, 104, 105, 717, 718, 19, 727, 719, 109, 110, + 588, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, -262, 101, 109, 110, 733, 93, 94, + 42, 43, 41, 240, 244, 249, 250, 251, 246, 248, + 256, 257, 252, 253, -415, 233, 234, -279, 477, 254, + 255, -415, 40, 477, -279, 295, 220, 751, 58, 59, + -415, 259, 60, -279, 35, 237, 488, 243, 44, 239, + 238, 490, 235, 236, 247, 245, 241, 20, 242, -415, + 774, 644, 91, 81, 84, 85, 516, 86, 88, 87, + 89, 220, 265, 517, 265, 82, 90, 644, 258, 240, + 781, 220, 442, 62, 790, 83, 95, 96, 5, 74, + 75, 71, 9, 57, 793, 794, 544, 63, 64, 796, + 798, 800, 67, 545, 65, 66, 68, 30, 31, 72, + 73, 808, 543, 809, 810, 781, 29, 28, 27, 103, + 102, 104, 105, 817, 220, 19, 220, 826, -263, 835, + 603, 8, 45, 7, 10, 107, 106, 108, 97, 56, + 99, 98, 100, 838, 101, 109, 110, 793, 93, 94, + 42, 43, 41, 240, 244, 249, 250, 251, 246, 248, + 256, 257, 252, 253, 552, 233, 234, -290, 841, 254, + 255, 551, 40, 843, -290, 33, 845, 847, 58, 59, + 553, 220, 60, -290, 35, 237, 849, 243, 44, 239, + 238, 850, 235, 236, 247, 245, 241, 20, 242, 853, + 855, 856, 91, 81, 84, 85, -290, 86, 88, 87, + 89, 644, 858, -290, -261, 82, 90, 862, 258, 864, + 220, 883, -290, 62, 220, 83, 95, 96, 291, 74, + 75, 71, 9, 57, 887, 889, 552, 63, 64, 895, + 898, 220, 67, 918, 65, 66, 68, 30, 31, 72, + 73, 902, 553, -264, 912, 919, 29, 28, 27, 103, + 102, 104, 105, 920, 915, 19, 666, 665, 664, 931, + 667, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, 793, 101, 109, 110, 933, 93, 94, + 42, 43, 41, 240, 244, 249, 250, 251, 246, 248, + 256, 257, 252, 253, -289, 233, 234, 552, 935, 254, + 255, -289, 40, 937, 918, 33, -576, 939, 58, 59, + -289, 939, 60, 553, 35, 237, 220, 243, 44, 239, + 238, 945, 235, 236, 247, 245, 241, 20, 242, 948, + 949, 954, 91, 81, 84, 85, -491, 86, 88, 87, + 89, 712, 793, -491, 957, 82, 90, 959, 258, 961, + 963, 963, -491, 62, 974, 83, 95, 96, 291, 74, + 75, 71, 9, 57, 984, -576, -492, 63, 64, -575, + 649, 999, 67, -492, 65, 66, 68, 30, 31, 72, + 73, 1000, -492, 1001, 939, 939, 29, 28, 27, 103, + 102, 104, 105, 939, 915, 19, 666, 665, 664, 1006, + 667, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, 984, 101, 109, 110, 1009, 93, 94, + 42, 43, 41, 240, 244, 249, 250, 251, 246, 248, + 256, 257, 252, 253, -289, 233, 234, 972, 1010, 254, + 255, -289, 40, 1011, 973, 33, -576, 963, 58, 59, + -289, 963, 60, 971, 35, 237, 963, 243, 44, 239, + 238, 220, 235, 236, 247, 245, 241, 20, 242, 984, + 939, 984, 91, 81, 84, 85, -279, 86, 88, 87, + 89, 963, nil, -279, nil, 82, 90, nil, 258, nil, + nil, nil, -279, 62, nil, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, -290, 63, 64, nil, + nil, nil, 67, -290, 65, 66, 68, 30, 31, 72, + 73, nil, -290, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, 118, 119, 120, 121, + 122, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, 244, 249, 250, 251, 246, 248, + 256, 257, 252, 253, -289, 233, 234, nil, nil, 254, + 255, -289, 40, nil, nil, 295, -576, nil, 58, 59, + -289, nil, 60, nil, 35, 237, nil, 243, 44, 239, + 238, nil, 235, 236, 247, 245, 241, 20, 242, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 258, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, 118, 119, 120, 121, 122, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, 118, 119, 120, 121, + 122, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, 244, 249, 250, 251, 246, 248, + 256, 257, 252, 253, nil, 233, 234, nil, nil, 254, + 255, nil, 40, nil, nil, 295, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 237, nil, 243, 44, 239, + 238, nil, 235, 236, 247, 245, 241, 20, 242, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, 220, 258, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, 244, 249, 250, 251, 246, 248, + 256, 257, 252, 253, nil, 233, 234, nil, nil, 254, + 255, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 237, nil, 243, 44, 239, + 238, nil, 235, 236, 247, 245, 241, 20, 242, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 258, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 5, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 7, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, 244, 249, 250, 251, 246, 248, + 256, 257, 252, 253, nil, 233, 234, nil, nil, 254, + 255, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 237, nil, 243, 44, 239, + 238, nil, 235, 236, 247, 245, 241, 20, 242, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 258, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, 244, 249, 250, 251, 246, 248, + 256, 257, 252, 253, nil, 233, 234, nil, nil, 254, + 255, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 237, nil, 243, 44, 239, + 238, nil, 235, 236, 247, 245, 241, 20, 242, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 258, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, 244, 249, 250, 251, 246, 248, + 256, 257, 252, 253, nil, 233, 234, nil, nil, 254, + 255, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 237, nil, 243, 44, 239, + 238, nil, 235, 236, 247, 245, 241, 20, 242, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 258, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, 244, 249, 250, 251, 246, 248, + 256, 257, 252, 253, nil, 233, 234, nil, nil, 254, + 255, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 237, nil, 243, 44, 239, + 238, nil, 235, 236, 247, 245, 241, 20, 242, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 258, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, 244, 249, 250, 251, 246, 248, + 256, 257, 252, 253, nil, 233, 234, nil, nil, 254, + 255, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 237, nil, 243, 44, 239, + 238, nil, 235, 236, 247, 245, 241, 20, 242, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 258, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, 244, 249, 250, 251, 246, 248, + 256, 257, 252, 253, nil, 233, 234, nil, nil, 254, + 255, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 237, nil, 243, 44, 239, + 238, nil, 235, 236, 247, 245, 241, 20, 242, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 258, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, 244, 249, 250, 251, 246, 248, + 256, 257, 252, 253, nil, 233, 234, nil, nil, 254, + 255, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 237, nil, 243, 44, 239, + 238, nil, 235, 236, 247, 245, 241, 20, 242, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 258, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, 244, 249, 250, 251, 246, 248, + 256, 257, 252, 253, nil, 233, 234, nil, nil, 254, + 255, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 237, nil, 243, 44, 239, + 238, nil, 235, 236, 247, 245, 241, 20, 242, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 258, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, 244, 249, 250, 251, 246, 248, + 256, 257, 252, 253, nil, 233, 234, nil, nil, 254, + 255, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 237, nil, 243, 44, 239, + 238, nil, 235, 236, 247, 245, 241, 20, 242, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 258, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, 669, 19, 666, 665, 664, nil, + 667, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 669, nil, 666, 665, 664, nil, 667, + nil, 802, nil, nil, 240, nil, nil, nil, nil, nil, + 805, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, nil, nil, nil, 44, nil, + 802, nil, nil, nil, nil, nil, 237, 20, nil, 805, + 239, 238, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 669, nil, + 666, 665, 664, 62, 667, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, 802, 29, 28, 27, 103, + 102, 104, 105, nil, 944, 19, nil, nil, nil, nil, + nil, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, 244, 249, 250, 251, 246, 248, + 256, 257, 252, 253, nil, -598, -598, nil, nil, 254, + 255, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, 240, 60, nil, 35, 237, nil, 243, 44, 239, + 238, nil, 235, 236, 247, 245, 241, 20, 242, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, 237, nil, 82, 90, 239, 238, nil, + 235, 236, nil, 62, nil, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, 244, 249, 250, 251, 246, 248, + 256, 257, 252, 253, nil, -598, -598, nil, nil, 254, + 255, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, 240, 60, nil, 35, 237, nil, 243, 44, 239, + 238, nil, 235, 236, 247, 245, 241, 20, 242, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, 237, nil, 82, 90, 239, 238, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, 669, 19, 666, 665, 664, nil, + 667, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, -598, -598, -598, -598, 246, 248, + nil, 802, -598, -598, nil, nil, nil, nil, nil, 254, + 255, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 237, nil, 243, 44, 239, + 238, nil, 235, 236, 247, 245, 241, 20, 242, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 669, nil, + 666, 665, 664, 62, 667, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, 802, 29, 28, 27, 103, + 102, 104, 105, nil, 669, 19, 666, 665, 664, nil, + 667, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, 669, nil, 666, 665, 664, nil, + 667, 802, 669, nil, 666, 665, 664, nil, 667, 254, + 255, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 237, nil, 243, 44, 239, + 238, 802, 235, 236, nil, nil, 241, 20, 242, 802, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 254, + 255, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 237, nil, 243, 44, 239, + 238, nil, 235, 236, nil, nil, 241, 20, 242, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 254, + 255, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 237, nil, 243, 44, 239, + 238, nil, 235, 236, nil, nil, 241, 20, 242, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 254, + 255, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 237, nil, 243, 44, 239, + 238, nil, 235, 236, nil, nil, 241, 20, 242, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, -598, -598, -598, -598, 246, 248, + nil, nil, -598, -598, nil, nil, nil, nil, nil, 254, + 255, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 237, nil, 243, 44, 239, + 238, nil, 235, 236, 247, 245, 241, 20, 242, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, -598, -598, -598, -598, 246, 248, + nil, nil, -598, -598, nil, nil, nil, nil, nil, 254, + 255, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 237, nil, 243, 44, 239, + 238, nil, 235, 236, 247, 245, 241, 20, 242, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, -598, -598, -598, -598, 246, 248, + nil, nil, -598, -598, nil, nil, nil, nil, nil, 254, + 255, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 237, nil, 243, 44, 239, + 238, nil, 235, 236, 247, 245, 241, 20, 242, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, -598, -598, -598, -598, 246, 248, + nil, nil, -598, -598, nil, nil, nil, nil, nil, 254, + 255, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 237, nil, 243, 44, 239, + 238, nil, 235, 236, 247, 245, 241, 20, 242, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, -598, -598, -598, -598, 246, 248, + nil, nil, -598, -598, nil, nil, nil, nil, nil, 254, + 255, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 237, nil, 243, 44, 239, + 238, nil, 235, 236, 247, 245, 241, 20, 242, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 291, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 293, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, 244, 249, 250, 251, 246, 248, + nil, nil, 252, 253, nil, nil, nil, nil, nil, 254, + 255, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 237, nil, 243, 44, 239, + 238, nil, 235, 236, 247, 245, 241, 20, 242, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 74, 75, + 71, 9, 57, nil, nil, nil, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 103, 102, + 104, 105, nil, nil, 19, nil, nil, nil, nil, nil, + 8, 45, 7, 10, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, 240, 244, 249, 250, 251, 246, 248, 256, + nil, 252, 253, nil, nil, nil, nil, nil, 254, 255, + nil, 40, nil, nil, 33, nil, nil, 58, 59, nil, + nil, 60, nil, 35, 237, nil, 243, 44, 239, 238, + nil, 235, 236, 247, 245, 241, 20, 242, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 232, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, 285, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 240, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 254, + 255, nil, 225, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, 283, 237, 281, 243, 44, 239, + 238, 286, 235, 236, nil, nil, nil, 230, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 103, 102, 104, 105, nil, nil, 232, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, 285, 101, 109, 110, nil, 93, + 94, 42, 43, 41, 240, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 254, 255, nil, 225, nil, nil, 231, nil, nil, 58, + 59, nil, nil, 60, nil, 283, 237, 281, 243, 44, + 239, 238, 286, 235, 236, nil, nil, nil, 230, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 103, 102, 104, 105, nil, nil, 232, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, 285, 101, 109, 110, nil, + 93, 94, 42, 43, 41, 240, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 254, 255, nil, 225, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, 283, 237, 281, nil, + 44, 239, 238, 286, 235, 236, nil, nil, nil, 230, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 310, 311, 72, 73, nil, nil, nil, nil, nil, 306, + 307, 313, 103, 102, 104, 105, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 308, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, nil, nil, 314, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 304, nil, nil, 300, nil, + nil, 58, 59, nil, nil, 60, nil, 299, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 310, 311, 72, 73, nil, nil, nil, nil, nil, + 306, 307, 313, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 308, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, nil, nil, 314, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 304, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, nil, 669, + nil, 666, 665, 664, 673, 667, nil, nil, nil, nil, + nil, nil, nil, nil, 676, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 316, nil, 671, 62, nil, 83, + 95, 96, 74, 75, 71, nil, 57, 684, 683, nil, + 63, 64, 677, nil, nil, 67, nil, 65, 66, 68, + 310, 311, 72, 73, nil, nil, nil, nil, nil, 306, + 307, 313, 103, 102, 104, 105, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, nil, 231, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 310, 311, 72, 73, nil, nil, nil, nil, nil, + 306, 307, 313, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 310, 311, 72, 73, nil, nil, nil, nil, + nil, 306, 307, 313, 103, 102, 104, 105, nil, nil, + 232, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 225, nil, nil, + 231, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 310, 311, 72, 73, nil, nil, nil, + nil, nil, 306, 307, 313, 103, 102, 104, 105, nil, + nil, 232, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, 285, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 231, nil, nil, 58, 59, nil, nil, 60, nil, + 283, nil, nil, nil, 44, nil, nil, 286, nil, nil, + nil, nil, nil, 230, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 310, 311, 72, 73, nil, nil, + nil, nil, nil, 306, 307, 313, 103, 102, 104, 105, + nil, nil, 232, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + 285, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 225, + nil, nil, 231, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, 286, nil, + nil, nil, nil, nil, 230, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 103, 102, 104, + 105, nil, nil, 19, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 225, nil, nil, 231, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 103, 102, + 104, 105, nil, nil, 19, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 225, nil, nil, 231, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 20, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 225, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, 115, nil, nil, + nil, nil, 114, 62, nil, 83, 95, 96, 74, 75, + 71, nil, 57, nil, nil, nil, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 310, 311, 72, 73, + nil, nil, nil, nil, nil, 306, 307, 313, 103, 102, + 104, 105, nil, nil, 232, nil, nil, nil, nil, nil, + nil, 308, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, nil, + nil, 314, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 348, nil, nil, 33, nil, nil, 58, 59, nil, + nil, 60, nil, 35, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 310, 311, 72, + 73, nil, nil, nil, nil, nil, 306, 307, 313, 103, + 102, 104, 105, nil, nil, 232, nil, nil, nil, nil, + nil, nil, 308, nil, nil, 107, 106, 108, 353, 56, + 99, 98, 354, nil, 101, 109, 110, nil, 93, 94, + nil, nil, 314, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 360, + nil, nil, 355, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 310, 311, + 72, 73, nil, nil, nil, nil, nil, 306, 307, 313, + 103, 102, 104, 105, nil, nil, 232, nil, nil, nil, + nil, nil, nil, 308, nil, nil, 107, 106, 108, 353, + 56, 99, 98, 354, nil, 101, 109, 110, nil, 93, + 94, nil, nil, 314, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 355, nil, nil, 231, nil, nil, 58, + 59, nil, nil, 60, nil, nil, 669, nil, 666, 665, + 664, 673, 667, nil, nil, nil, nil, nil, nil, nil, + nil, 676, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, nil, nil, 671, 62, nil, 83, 95, 96, 74, + 75, 71, 9, 57, 684, 683, nil, 63, 64, 677, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 7, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, 388, 62, nil, 83, 95, 96, 74, 75, + 71, nil, 57, nil, nil, nil, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 103, 102, + 104, 105, nil, nil, 19, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 225, nil, nil, 231, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 20, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 225, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 103, 102, 104, 105, nil, nil, 19, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, nil, 231, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 103, 102, 104, 105, nil, nil, 19, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 225, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 20, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, nil, nil, nil, 62, nil, 83, 95, 96, + 74, 75, 71, 9, 57, nil, nil, nil, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 103, 102, 104, 105, nil, nil, 19, nil, nil, nil, + nil, nil, 8, 45, nil, 10, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 40, nil, nil, 33, nil, nil, 58, + 59, nil, nil, 60, nil, 35, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 103, 102, 104, 105, nil, nil, 232, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 225, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, 404, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 103, 102, 104, 105, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, nil, 231, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 30, 31, 72, 73, nil, nil, nil, nil, nil, + 29, 28, 27, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, 285, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, 283, nil, + 281, nil, 44, nil, nil, 286, nil, nil, nil, nil, + nil, 230, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 30, 31, 72, 73, nil, nil, nil, nil, + nil, 29, 28, 27, 103, 102, 104, 105, nil, nil, + 232, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 225, nil, nil, + 231, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 232, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 231, nil, nil, 58, 59, nil, nil, 60, nil, + 404, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 225, + nil, nil, 231, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 20, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 103, 102, 104, + 105, nil, nil, 19, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 225, nil, nil, 231, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 103, 102, + 104, 105, nil, nil, 19, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 225, nil, nil, 231, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 20, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 225, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, 220, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 310, 311, + 72, 73, nil, nil, nil, nil, nil, 306, 307, 313, + 103, 102, 104, 105, nil, nil, 232, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, nil, 231, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 310, + 311, 72, 73, nil, nil, nil, nil, nil, 306, 307, + 313, 103, 102, 104, 105, nil, nil, 232, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 225, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 310, 311, 72, 73, nil, nil, nil, nil, nil, 306, + 307, 313, 103, 102, 104, 105, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, nil, 231, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 310, 311, 72, 73, nil, nil, nil, nil, nil, + 306, 307, 313, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 310, 311, 72, 73, nil, nil, nil, nil, + nil, 306, 307, 313, 103, 102, 104, 105, nil, nil, + 232, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 225, nil, nil, + 231, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 310, 311, 72, 73, nil, nil, nil, + nil, nil, 306, 307, 313, 103, 102, 104, 105, nil, + nil, 232, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 231, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 310, 311, 72, 73, nil, nil, + nil, nil, nil, 306, 307, 313, 103, 102, 104, 105, + nil, nil, 232, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 225, + nil, nil, 231, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 230, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 310, 311, 72, 73, nil, + nil, nil, nil, nil, 306, 307, 313, 103, 102, 104, + 105, nil, nil, 232, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 225, nil, nil, 231, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 230, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 310, 311, 72, 73, + nil, nil, nil, nil, nil, 306, 307, 313, 103, 102, + 104, 105, nil, nil, 232, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 225, nil, nil, 231, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 230, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 310, 311, 72, + 73, nil, nil, nil, nil, nil, 306, 307, 313, 103, + 102, 104, 105, nil, nil, 232, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 225, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 310, 311, + 72, 73, nil, nil, nil, nil, nil, 306, 307, 313, + 103, 102, 104, 105, nil, nil, 232, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, nil, 231, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 310, + 311, 72, 73, nil, nil, nil, nil, nil, 306, 307, + 313, 103, 102, 104, 105, nil, nil, 232, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 225, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 310, 311, 72, 73, nil, nil, nil, nil, nil, 306, + 307, 313, 103, 102, 104, 105, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, nil, 231, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 310, 311, 72, 73, nil, nil, nil, nil, nil, + 306, 307, 313, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 310, 311, 72, 73, nil, nil, nil, nil, + nil, 306, 307, 313, 103, 102, 104, 105, nil, nil, + 232, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 225, nil, nil, + 231, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 310, 311, 72, 73, nil, nil, nil, + nil, nil, 306, 307, 313, 103, 102, 104, 105, nil, + nil, 232, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 231, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 310, 311, 72, 73, nil, nil, + nil, nil, nil, 306, 307, 313, 103, 102, 104, 105, + nil, nil, 232, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 225, + nil, nil, 231, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 230, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 310, 311, 72, 73, nil, + nil, nil, nil, nil, 306, 307, 313, 103, 102, 104, + 105, nil, nil, 232, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 225, nil, nil, 231, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 230, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 310, 311, 72, 73, + nil, nil, nil, nil, nil, 306, 307, 313, 103, 102, + 104, 105, nil, nil, 232, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 225, nil, nil, 231, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 230, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 310, 311, 72, + 73, nil, nil, nil, nil, nil, 306, 307, 313, 103, + 102, 104, 105, nil, nil, 232, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 225, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 310, 311, + 72, 73, nil, nil, nil, nil, nil, 306, 307, 313, + 103, 102, 104, 105, nil, nil, 232, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, nil, 231, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 310, + 311, 72, 73, nil, nil, nil, nil, nil, 306, 307, + 313, 103, 102, 104, 105, nil, nil, 232, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 225, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 310, 311, 72, 73, nil, nil, nil, nil, nil, 306, + 307, 313, 103, 102, 104, 105, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, nil, 231, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 310, 311, 72, 73, nil, nil, nil, nil, nil, + 306, 307, 313, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 310, 311, 72, 73, nil, nil, nil, nil, + nil, 306, 307, 313, 103, 102, 104, 105, nil, nil, + 232, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 225, nil, nil, + 231, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 310, 311, 72, 73, nil, nil, nil, + nil, nil, 306, 307, 313, 103, 102, 104, 105, nil, + nil, 232, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 231, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 310, 311, 72, 73, nil, nil, + nil, nil, nil, 306, 307, 313, 103, 102, 104, 105, + nil, nil, 232, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 225, + nil, nil, 231, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 230, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 103, 102, 104, + 105, nil, nil, 232, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, 285, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 225, nil, nil, 231, nil, nil, 58, 59, nil, nil, + 60, nil, 283, nil, 281, nil, 44, nil, nil, 286, + nil, nil, nil, nil, nil, 230, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 103, 102, + 104, 105, nil, nil, 232, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, 285, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 225, nil, nil, 231, nil, nil, 58, 59, nil, + nil, 60, nil, 283, nil, 281, nil, 44, nil, nil, + 286, nil, nil, nil, nil, nil, 230, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 232, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, 285, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 225, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, 283, nil, 281, nil, 44, nil, + nil, 286, nil, nil, nil, nil, nil, 230, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, 220, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 310, 311, + 72, 73, nil, nil, nil, nil, nil, 306, 307, 313, + 103, 102, 104, 105, nil, nil, 232, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, nil, 231, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 310, + 311, 72, 73, nil, nil, nil, nil, nil, 306, 307, + 313, 103, 102, 104, 105, nil, nil, 232, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 225, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 310, 311, 72, 73, nil, nil, nil, nil, nil, 306, + 307, 313, 103, 102, 104, 105, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, nil, 231, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 310, 311, 72, 73, nil, nil, nil, nil, nil, + 306, 307, 313, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, nil, nil, nil, 62, nil, 83, + 95, 96, 74, 75, 71, 9, 57, nil, nil, nil, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 103, 102, 104, 105, nil, nil, 19, nil, + nil, nil, nil, nil, 8, 45, nil, 10, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 40, nil, nil, 33, nil, + nil, 58, 59, nil, nil, 60, nil, 35, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 20, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 310, 311, 72, 73, nil, nil, nil, nil, nil, + 306, 307, 313, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 308, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, nil, nil, 314, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 304, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, nil, 669, + nil, 666, 665, 664, 673, 667, nil, nil, nil, nil, + nil, nil, nil, nil, 676, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 503, nil, 671, 62, nil, 83, + 95, 96, 74, 75, 71, nil, 57, 684, 683, nil, + 63, 64, 677, nil, nil, 67, nil, 65, 66, 68, + 310, 311, 72, 73, nil, nil, nil, nil, nil, 306, + 307, 313, 103, 102, 104, 105, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 308, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, nil, nil, 314, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 304, nil, nil, 300, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 310, 311, 72, 73, nil, nil, nil, nil, nil, + 306, 307, 313, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 231, + 519, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 30, 31, 72, 73, nil, nil, nil, nil, + nil, 29, 28, 27, 103, 102, 104, 105, nil, nil, + 19, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 225, nil, nil, + 231, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 231, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 225, + nil, nil, 231, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 20, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 103, 102, 104, + 105, nil, nil, 19, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 225, nil, nil, 231, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 103, 102, + 104, 105, nil, nil, 19, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 225, nil, nil, 231, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 20, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 310, 311, 72, + 73, nil, nil, nil, nil, nil, 306, 307, 313, 103, + 102, 104, 105, nil, nil, 232, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 225, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 103, 102, 104, 105, nil, nil, 232, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, 285, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, nil, 231, nil, nil, 58, + 59, nil, nil, 60, nil, 283, nil, 281, nil, 44, + nil, nil, 286, nil, nil, nil, nil, nil, 230, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 310, + 311, 72, 73, nil, nil, nil, nil, nil, 306, 307, + 313, 103, 102, 104, 105, nil, nil, 232, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 225, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 310, 311, 72, 73, nil, nil, nil, nil, nil, 306, + 307, 313, 103, 102, 104, 105, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, nil, 231, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 310, 311, 72, 73, nil, nil, nil, nil, nil, + 306, 307, 313, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 310, 311, 72, 73, nil, nil, nil, nil, + nil, 306, 307, 313, 103, 102, 104, 105, nil, nil, + 232, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, 285, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 225, nil, nil, + 231, nil, nil, 58, 59, nil, nil, 60, nil, 627, + nil, 281, nil, 44, nil, nil, 286, nil, nil, nil, + nil, nil, 230, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 310, 311, 72, 73, nil, nil, nil, + nil, nil, 306, 307, 313, 103, 102, 104, 105, nil, + nil, 232, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, 285, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 231, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, 281, nil, 44, nil, nil, 286, nil, nil, + nil, nil, nil, 230, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 310, 311, 72, 73, nil, nil, + nil, nil, nil, 306, 307, 313, 103, 102, 104, 105, + nil, nil, 232, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 225, + nil, nil, 231, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 230, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 293, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, nil, nil, 388, 62, + nil, 83, 95, 96, 74, 75, 71, nil, 57, nil, + nil, nil, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 310, 311, 72, 73, nil, nil, nil, nil, + nil, 306, 307, 313, 103, 102, 104, 105, nil, nil, + 232, nil, nil, nil, nil, nil, nil, 308, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, nil, nil, 314, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 304, nil, nil, + 300, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 232, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, 285, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 231, nil, nil, 58, 59, nil, nil, 60, nil, + 283, nil, 281, nil, 44, nil, nil, 286, nil, nil, + nil, nil, nil, 230, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 310, 311, 72, 73, nil, nil, + nil, nil, nil, 306, 307, 313, 103, 102, 104, 105, + nil, nil, 232, nil, nil, nil, nil, nil, nil, 308, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, nil, nil, 314, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 304, + nil, nil, 300, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 310, 311, 72, 73, nil, + nil, nil, nil, nil, 306, 307, 313, 103, 102, 104, + 105, nil, nil, 232, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 225, nil, nil, 231, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 230, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 310, 311, 72, 73, + nil, nil, nil, nil, nil, 306, 307, 313, 103, 102, + 104, 105, nil, nil, 232, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 225, nil, nil, 231, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 230, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 225, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 310, 311, + 72, 73, nil, nil, nil, nil, nil, 306, 307, 313, + 103, 102, 104, 105, nil, nil, 232, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, 285, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, nil, 231, nil, nil, 58, + 59, nil, nil, 60, nil, 627, nil, nil, nil, 44, + nil, nil, 286, nil, nil, nil, nil, nil, 230, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 310, + 311, 72, 73, nil, nil, nil, nil, nil, 306, 307, + 313, 103, 102, 104, 105, nil, nil, 232, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, 285, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 225, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, 286, nil, nil, nil, nil, nil, 230, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 310, 311, 72, 73, nil, nil, nil, nil, nil, 306, + 307, 313, 103, 102, 104, 105, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, nil, 231, nil, + nil, 58, 59, nil, nil, 60, nil, 283, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 30, 31, 72, 73, nil, nil, nil, nil, nil, + 29, 28, 27, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, 285, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, 283, nil, + 281, nil, 44, nil, nil, 286, nil, nil, nil, nil, + nil, 230, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 30, 31, 72, 73, nil, nil, nil, nil, + nil, 29, 28, 27, 103, 102, 104, 105, nil, nil, + 232, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, 285, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 225, nil, nil, + 231, nil, nil, 58, 59, nil, nil, 60, nil, 283, + nil, 281, nil, 44, nil, nil, 286, nil, nil, nil, + nil, nil, 230, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 310, 311, 72, 73, nil, nil, nil, + nil, nil, 306, 307, 313, 103, 102, 104, 105, nil, + nil, 232, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 231, nil, nil, 58, 59, nil, nil, 60, nil, + 730, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 310, 311, 72, 73, nil, nil, + nil, nil, nil, 306, 307, 313, 103, 102, 104, 105, + nil, nil, 232, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 225, + nil, nil, 231, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 230, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 310, 311, 72, 73, nil, + nil, nil, nil, nil, 306, 307, 313, 103, 102, 104, + 105, nil, nil, 232, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, 285, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 225, nil, nil, 231, nil, nil, 58, 59, nil, nil, + 60, nil, 627, nil, 281, nil, 44, nil, nil, 286, + nil, nil, nil, nil, nil, 230, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 310, 311, 72, 73, + nil, nil, nil, nil, nil, 306, 307, 313, 103, 102, + 104, 105, nil, nil, 232, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, 285, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 225, nil, nil, 231, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, 281, nil, 44, nil, nil, + 286, nil, nil, nil, nil, nil, 230, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 232, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 225, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 103, 102, 104, 105, nil, nil, 232, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, nil, 231, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 103, 102, 104, 105, nil, nil, 232, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 225, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 103, 102, 104, 105, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, nil, 231, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 30, 31, 72, 73, nil, nil, nil, nil, nil, + 29, 28, 27, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 310, 311, 72, 73, nil, nil, nil, nil, + nil, 306, 307, 313, 103, 102, 104, 105, nil, nil, + 232, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 225, nil, nil, + 231, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 310, 311, 72, 73, nil, nil, nil, + nil, nil, 306, 307, 313, 103, 102, 104, 105, nil, + nil, 232, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 231, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 310, 311, 72, 73, nil, nil, + nil, nil, nil, 306, 307, 313, 103, 102, 104, 105, + nil, nil, 232, nil, nil, nil, nil, nil, nil, 308, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, nil, nil, 314, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 304, + nil, nil, 300, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 310, 311, 72, 73, nil, + nil, nil, nil, nil, 306, 307, 313, 103, 102, 104, + 105, nil, nil, 232, nil, nil, nil, nil, nil, nil, + 308, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, nil, nil, + 314, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 304, nil, nil, 300, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 310, 311, 72, 73, + nil, nil, nil, nil, nil, 306, 307, 313, 103, 102, + 104, 105, nil, nil, 232, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 225, nil, nil, 231, nil, nil, 58, 59, nil, + nil, 60, nil, 404, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 230, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 310, 311, 72, + 73, nil, nil, nil, nil, nil, 306, 307, 313, 103, + 102, 104, 105, nil, nil, 232, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 225, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 103, 102, 104, 105, nil, nil, 19, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, nil, 231, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 103, 102, 104, 105, nil, nil, 19, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 225, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 20, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 310, 311, 72, 73, nil, nil, nil, nil, nil, 306, + 307, 313, 103, 102, 104, 105, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, nil, 231, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 30, 31, 72, 73, nil, nil, nil, nil, nil, + 29, 28, 27, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 310, 311, 72, 73, nil, nil, nil, nil, + nil, 306, 307, 313, 103, 102, 104, 105, nil, nil, + 232, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 225, nil, nil, + 231, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 310, 311, 72, 73, nil, nil, nil, + nil, nil, 306, 307, 313, 103, 102, 104, 105, nil, + nil, 232, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 231, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 310, 311, 72, 73, nil, nil, + nil, nil, nil, 306, 307, 313, 103, 102, 104, 105, + nil, nil, 232, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 225, + nil, nil, 231, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 230, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 310, 311, 72, 73, nil, + nil, nil, nil, nil, 306, 307, 313, 103, 102, 104, + 105, nil, nil, 232, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 225, nil, nil, 231, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 230, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 310, 311, 72, 73, + nil, nil, nil, nil, nil, 306, 307, 313, 103, 102, + 104, 105, nil, nil, 232, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 225, nil, nil, 231, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 230, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 310, 311, 72, + 73, nil, nil, nil, nil, nil, 306, 307, 313, 103, + 102, 104, 105, nil, nil, 232, nil, nil, nil, nil, + nil, nil, 308, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + nil, nil, 314, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 852, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 310, 311, + 72, 73, nil, nil, nil, nil, nil, 306, 307, 313, + 103, 102, 104, 105, nil, nil, 232, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, nil, 231, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 103, 102, 104, 105, nil, nil, 19, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 225, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 20, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 310, 311, 72, 73, nil, nil, nil, nil, nil, 306, + 307, 313, 103, 102, 104, 105, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, nil, 231, nil, + nil, 58, 59, nil, nil, 60, nil, 627, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 310, 311, 72, 73, nil, nil, nil, nil, nil, + 306, 307, 313, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, 285, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + 281, nil, 44, nil, nil, 286, nil, nil, nil, nil, + nil, 230, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 310, 311, 72, 73, nil, nil, nil, nil, + nil, 306, 307, 313, 103, 102, 104, 105, nil, nil, + 232, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 225, nil, nil, + 231, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 310, 311, 72, 73, nil, nil, nil, + nil, nil, 306, 307, 313, 103, 102, 104, 105, nil, + nil, 232, nil, nil, nil, nil, nil, nil, 308, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, nil, nil, 314, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 852, nil, + nil, 231, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 310, 311, 72, 73, nil, nil, + nil, nil, nil, 306, 307, 313, 103, 102, 104, 105, + nil, nil, 232, nil, nil, nil, nil, nil, nil, 308, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, nil, nil, 314, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 926, + nil, nil, 231, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 103, 102, 104, + 105, nil, nil, 232, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, 285, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 225, nil, nil, 231, nil, nil, 58, 59, nil, nil, + 60, nil, 283, nil, 281, nil, 44, nil, nil, 286, + nil, nil, nil, nil, nil, 230, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, nil, -280, + nil, 62, nil, 83, 95, 96, -280, -280, -280, nil, + nil, -280, -280, -280, nil, -280, nil, nil, nil, nil, + nil, nil, nil, nil, nil, -280, -280, -280, nil, nil, + nil, nil, nil, nil, nil, -280, -280, nil, -280, -280, + -280, -280, -280, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, -280, -280, -280, -280, -280, + -280, -280, -280, -280, -280, -280, -280, -280, -280, nil, + nil, -280, -280, -280, nil, nil, -280, nil, nil, -280, + nil, nil, -280, -280, nil, -280, nil, -280, nil, -280, + nil, -280, -280, nil, -280, -280, -280, -280, -280, nil, + -280, nil, -280, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, -280, nil, nil, -280, + -280, -280, -280, -580, -280, nil, -280, nil, nil, nil, + -580, -580, -580, nil, nil, -580, -580, -580, nil, -580, + nil, nil, nil, nil, nil, nil, nil, nil, -580, -580, + -580, -580, nil, nil, nil, nil, nil, nil, nil, -580, + -580, nil, -580, -580, -580, -580, -580, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, -580, + -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, + -580, -580, -580, nil, nil, -580, -580, -580, nil, nil, + -580, nil, nil, -580, nil, nil, -580, -580, nil, -580, + nil, -580, nil, -580, nil, -580, -580, nil, -580, -580, + -580, -580, -580, nil, -580, -580, -580, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + -580, nil, nil, -580, -580, -580, -580, -581, -580, nil, + -580, nil, nil, nil, -581, -581, -581, nil, nil, -581, + -581, -581, nil, -581, nil, nil, nil, nil, nil, nil, + nil, nil, -581, -581, -581, -581, nil, nil, nil, nil, + nil, nil, nil, -581, -581, nil, -581, -581, -581, -581, + -581, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, -581, -581, -581, -581, -581, -581, -581, + -581, -581, -581, -581, -581, -581, -581, nil, nil, -581, + -581, -581, nil, nil, -581, nil, nil, -581, nil, nil, + -581, -581, nil, -581, nil, -581, nil, -581, nil, -581, + -581, nil, -581, -581, -581, -581, -581, nil, -581, -581, + -581, 669, nil, 666, 665, 664, 673, 667, nil, nil, + nil, nil, nil, nil, -581, nil, 676, -581, -581, -581, + -581, -414, -581, nil, -581, nil, nil, nil, -414, -414, + -414, nil, nil, -414, -414, -414, nil, -414, 671, nil, + nil, nil, nil, nil, nil, nil, -414, -414, -414, 684, + 683, nil, nil, nil, 677, nil, nil, -414, -414, nil, + -414, -414, -414, -414, -414, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, -414, -414, -414, + -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, + -414, nil, nil, -414, -414, -414, nil, nil, -414, nil, + 265, -414, nil, nil, -414, -414, nil, -414, nil, -414, + nil, -414, nil, -414, -414, nil, -414, -414, -414, -414, + -414, -296, -414, -414, -414, nil, nil, nil, -296, -296, + -296, nil, nil, -296, -296, -296, nil, -296, -414, nil, + nil, -414, -414, nil, -414, nil, -414, -296, -296, nil, + nil, nil, nil, nil, nil, nil, nil, -296, -296, nil, + -296, -296, -296, -296, -296, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, -296, -296, -296, + -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, + -296, nil, nil, -296, -296, -296, nil, nil, -296, nil, + 274, -296, nil, nil, -296, -296, nil, -296, nil, -296, + nil, -296, nil, -296, -296, nil, -296, -296, -296, -296, + -296, nil, -296, -244, -296, nil, nil, nil, nil, nil, + -244, -244, -244, nil, nil, -244, -244, -244, -296, -244, + nil, -296, -296, nil, -296, nil, -296, nil, -244, -244, + -244, nil, nil, nil, nil, nil, nil, nil, nil, -244, + -244, nil, -244, -244, -244, -244, -244, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, -244, + -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, + -244, -244, -244, nil, nil, -244, -244, -244, nil, nil, + -244, nil, 265, -244, nil, nil, -244, -244, nil, -244, + nil, -244, nil, -244, nil, -244, -244, nil, -244, -244, + -244, -244, -244, nil, -244, -244, -244, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + -244, nil, -244, -244, -244, nil, -244, nil, -244, -244, + -244, -244, nil, nil, -244, -244, -244, 669, -244, 666, + 665, 664, 673, 667, nil, nil, nil, -244, -244, nil, + nil, nil, 676, nil, nil, nil, nil, nil, -244, -244, + nil, -244, -244, -244, -244, -244, nil, nil, nil, nil, + nil, nil, nil, nil, 671, nil, 669, nil, 666, 665, + 664, 673, 667, 681, 680, 684, 683, nil, nil, nil, + 677, 676, nil, nil, nil, nil, nil, nil, nil, -244, + nil, nil, nil, nil, nil, nil, -244, nil, nil, nil, + nil, 265, -244, 671, 655, nil, 220, nil, nil, nil, + nil, nil, 681, 680, 684, 683, nil, nil, nil, 677, + nil, nil, nil, nil, -244, -244, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, -244, + nil, nil, -244, nil, nil, nil, nil, -244, 175, 186, + 176, 199, 172, 192, 182, 181, 202, 203, 197, 180, + 179, 174, 200, 204, 205, 184, 173, 187, 191, 193, + 185, 178, nil, nil, nil, 194, 201, 196, 195, 188, + 198, 183, 171, 190, 189, nil, nil, nil, nil, nil, + 170, 177, 168, 169, 165, 166, 167, 126, 128, 125, + nil, 127, nil, nil, nil, nil, nil, nil, nil, 159, + 160, nil, 156, 138, 139, 140, 147, 144, 146, nil, + nil, 141, 142, nil, nil, nil, 161, 162, 148, 149, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 153, 152, nil, 137, 158, 155, 154, + 163, 150, 151, 145, 143, 135, 157, 136, nil, nil, + 164, 91, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 90, 175, 186, 176, 199, + 172, 192, 182, 181, 202, 203, 197, 180, 179, 174, + 200, 204, 205, 184, 173, 187, 191, 193, 185, 178, + nil, nil, nil, 194, 201, 196, 195, 188, 198, 183, + 171, 190, 189, nil, nil, nil, nil, nil, 170, 177, + 168, 169, 165, 166, 167, 126, 128, nil, nil, 127, + nil, nil, nil, nil, nil, nil, nil, 159, 160, nil, + 156, 138, 139, 140, 147, 144, 146, nil, nil, 141, + 142, nil, nil, nil, 161, 162, 148, 149, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 153, 152, nil, 137, 158, 155, 154, 163, 150, + 151, 145, 143, 135, 157, 136, nil, nil, 164, 91, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 90, 175, 186, 176, 199, 172, 192, + 182, 181, 202, 203, 197, 180, 179, 174, 200, 204, + 205, 184, 173, 187, 191, 193, 185, 178, nil, nil, + nil, 194, 201, 196, 195, 188, 198, 183, 171, 190, + 189, nil, nil, nil, nil, nil, 170, 177, 168, 169, + 165, 166, 167, 126, 128, nil, nil, 127, nil, nil, + nil, nil, nil, nil, nil, 159, 160, nil, 156, 138, + 139, 140, 147, 144, 146, nil, nil, 141, 142, nil, + nil, nil, 161, 162, 148, 149, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 153, + 152, nil, 137, 158, 155, 154, 163, 150, 151, 145, + 143, 135, 157, 136, nil, nil, 164, 91, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 90, 175, 186, 176, 199, 172, 192, 182, 181, + 202, 203, 197, 180, 179, 174, 200, 204, 205, 184, + 173, 187, 191, 193, 185, 178, nil, nil, nil, 194, + 201, 196, 195, 188, 198, 183, 171, 190, 189, nil, + nil, nil, nil, nil, 170, 177, 168, 169, 165, 166, + 167, 126, 128, nil, nil, 127, nil, nil, nil, nil, + nil, nil, nil, 159, 160, nil, 156, 138, 139, 140, + 147, 144, 146, nil, nil, 141, 142, nil, nil, nil, + 161, 162, 148, 149, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 153, 152, nil, + 137, 158, 155, 154, 163, 150, 151, 145, 143, 135, + 157, 136, nil, nil, 164, 91, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 90, + 175, 186, 176, 199, 172, 192, 182, 181, 202, 203, + 197, 180, 179, 174, 200, 204, 205, 184, 173, 187, + 191, 193, 185, 178, nil, nil, nil, 194, 201, 196, + 371, 370, 372, 369, 171, 190, 189, nil, nil, nil, + nil, nil, 170, 177, 168, 169, 366, 367, 368, 364, + 128, 99, 98, 365, nil, 101, nil, nil, nil, nil, + nil, 159, 160, nil, 156, 138, 139, 140, 147, 144, + 146, nil, nil, 141, 142, nil, nil, nil, 161, 162, + 148, 149, nil, nil, nil, nil, nil, 376, nil, nil, + nil, nil, nil, nil, nil, 153, 152, nil, 137, 158, + 155, 154, 163, 150, 151, 145, 143, 135, 157, 136, + nil, nil, 164, 175, 186, 176, 199, 172, 192, 182, + 181, 202, 203, 197, 180, 179, 174, 200, 204, 205, + 184, 173, 187, 191, 193, 185, 178, nil, nil, nil, + 194, 201, 196, 195, 188, 198, 183, 171, 190, 189, + nil, nil, nil, nil, nil, 170, 177, 168, 169, 165, + 166, 167, 126, 128, nil, nil, 127, nil, nil, nil, + nil, nil, nil, nil, 159, 160, nil, 156, 138, 139, + 140, 147, 144, 146, nil, nil, 141, 142, nil, nil, + nil, 161, 162, 148, 149, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 153, 152, + nil, 137, 158, 155, 154, 163, 150, 151, 145, 143, + 135, 157, 136, 413, 417, 164, nil, 414, nil, nil, + nil, nil, nil, nil, nil, 159, 160, nil, 156, 138, + 139, 140, 147, 144, 146, nil, nil, 141, 142, nil, + nil, nil, 161, 162, 148, 149, nil, nil, nil, nil, + nil, 265, nil, nil, nil, nil, nil, nil, nil, 153, + 152, nil, 137, 158, 155, 154, 163, 150, 151, 145, + 143, 135, 157, 136, 420, 424, 164, nil, 419, nil, + nil, nil, nil, nil, nil, nil, 159, 160, nil, 156, + 138, 139, 140, 147, 144, 146, nil, nil, 141, 142, + nil, nil, nil, 161, 162, 148, 149, nil, nil, nil, + nil, nil, 265, nil, nil, nil, nil, nil, nil, nil, + 153, 152, nil, 137, 158, 155, 154, 163, 150, 151, + 145, 143, 135, 157, 136, 475, 417, 164, nil, 476, + nil, nil, nil, nil, nil, nil, nil, 159, 160, nil, + 156, 138, 139, 140, 147, 144, 146, nil, nil, 141, + 142, nil, nil, nil, 161, 162, 148, 149, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 153, 152, nil, 137, 158, 155, 154, 163, 150, + 151, 145, 143, 135, 157, 136, 606, 417, 164, nil, + 607, nil, nil, nil, nil, nil, nil, nil, 159, 160, + nil, 156, 138, 139, 140, 147, 144, 146, nil, nil, + 141, 142, nil, nil, nil, 161, 162, 148, 149, nil, + nil, nil, nil, nil, 265, nil, nil, nil, nil, nil, + nil, nil, 153, 152, nil, 137, 158, 155, 154, 163, + 150, 151, 145, 143, 135, 157, 136, 608, 424, 164, + nil, 609, nil, nil, nil, nil, nil, nil, nil, 159, + 160, nil, 156, 138, 139, 140, 147, 144, 146, nil, + nil, 141, 142, nil, nil, nil, 161, 162, 148, 149, + nil, nil, nil, nil, nil, 265, nil, nil, nil, nil, + nil, nil, nil, 153, 152, nil, 137, 158, 155, 154, + 163, 150, 151, 145, 143, 135, 157, 136, 637, 417, + 164, nil, 638, nil, nil, nil, nil, nil, nil, nil, + 159, 160, nil, 156, 138, 139, 140, 147, 144, 146, + nil, nil, 141, 142, nil, nil, nil, 161, 162, 148, + 149, nil, nil, nil, nil, nil, 265, nil, nil, nil, + nil, nil, nil, nil, 153, 152, nil, 137, 158, 155, + 154, 163, 150, 151, 145, 143, 135, 157, 136, 640, + 424, 164, nil, 641, nil, nil, nil, nil, nil, nil, + nil, 159, 160, nil, 156, 138, 139, 140, 147, 144, + 146, nil, nil, 141, 142, nil, nil, nil, 161, 162, + 148, 149, nil, nil, nil, nil, nil, 265, nil, nil, + nil, nil, nil, nil, nil, 153, 152, nil, 137, 158, + 155, 154, 163, 150, 151, 145, 143, 135, 157, 136, + 606, 417, 164, nil, 607, nil, nil, nil, nil, nil, + nil, nil, 159, 160, nil, 156, 138, 139, 140, 147, + 144, 146, nil, nil, 141, 142, nil, nil, nil, 161, + 162, 148, 149, nil, nil, nil, nil, nil, 265, nil, + nil, nil, nil, nil, nil, nil, 153, 152, nil, 137, + 158, 155, 154, 163, 150, 151, 145, 143, 135, 157, + 136, 608, 424, 164, nil, 609, nil, nil, nil, nil, + nil, nil, nil, 159, 160, nil, 156, 138, 139, 140, + 147, 144, 146, nil, nil, 141, 142, nil, nil, nil, + 161, 162, 148, 149, nil, nil, nil, nil, nil, 265, + nil, nil, nil, nil, nil, nil, nil, 153, 152, nil, + 137, 158, 155, 154, 163, 150, 151, 145, 143, 135, + 157, 136, 697, 417, 164, nil, 698, nil, nil, nil, + nil, nil, nil, nil, 159, 160, nil, 156, 138, 139, + 140, 147, 144, 146, nil, nil, 141, 142, nil, nil, + nil, 161, 162, 148, 149, nil, nil, nil, nil, nil, + 265, nil, nil, nil, nil, nil, nil, nil, 153, 152, + nil, 137, 158, 155, 154, 163, 150, 151, 145, 143, + 135, 157, 136, 699, 424, 164, nil, 700, nil, nil, + nil, nil, nil, nil, nil, 159, 160, nil, 156, 138, + 139, 140, 147, 144, 146, nil, nil, 141, 142, nil, + nil, nil, 161, 162, 148, 149, nil, nil, nil, nil, + nil, 265, nil, nil, nil, nil, nil, nil, nil, 153, + 152, nil, 137, 158, 155, 154, 163, 150, 151, 145, + 143, 135, 157, 136, 702, 424, 164, nil, 703, nil, + nil, nil, nil, nil, nil, nil, 159, 160, nil, 156, + 138, 139, 140, 147, 144, 146, nil, nil, 141, 142, + nil, nil, nil, 161, 162, 148, 149, nil, nil, nil, + nil, nil, 265, nil, nil, nil, nil, nil, nil, nil, + 153, 152, nil, 137, 158, 155, 154, 163, 150, 151, + 145, 143, 135, 157, 136, 475, 417, 164, nil, 476, + nil, nil, nil, nil, nil, nil, nil, 159, 160, nil, + 156, 138, 139, 140, 147, 144, 146, nil, nil, 141, + 142, nil, nil, nil, 161, 162, 148, 149, nil, nil, + nil, nil, nil, 265, nil, nil, nil, nil, nil, nil, + nil, 153, 152, nil, 137, 158, 155, 154, 163, 150, + 151, 145, 143, 135, 157, 136, 969, 424, 164, nil, + 968, nil, nil, nil, nil, nil, nil, nil, 159, 160, + nil, 156, 138, 139, 140, 147, 144, 146, nil, nil, + 141, 142, nil, nil, nil, 161, 162, 148, 149, nil, + nil, nil, nil, nil, 265, nil, nil, nil, nil, nil, + nil, nil, 153, 152, nil, 137, 158, 155, 154, 163, + 150, 151, 145, 143, 135, 157, 136, 995, 417, 164, + nil, 996, nil, nil, nil, nil, nil, nil, nil, 159, + 160, nil, 156, 138, 139, 140, 147, 144, 146, nil, + nil, 141, 142, nil, nil, nil, 161, 162, 148, 149, + nil, nil, nil, nil, nil, 265, nil, nil, nil, nil, + nil, nil, nil, 153, 152, nil, 137, 158, 155, 154, + 163, 150, 151, 145, 143, 135, 157, 136, 997, 424, + 164, nil, 998, nil, nil, nil, nil, nil, nil, nil, + 159, 160, nil, 156, 138, 139, 140, 147, 144, 146, + nil, nil, 141, 142, nil, nil, nil, 161, 162, 148, + 149, nil, nil, nil, nil, nil, 265, nil, nil, nil, + nil, nil, nil, nil, 153, 152, nil, 137, 158, 155, + 154, 163, 150, 151, 145, 143, 135, 157, 136, nil, + 669, 164, 666, 665, 664, 673, 667, nil, 669, nil, + 666, 665, 664, 673, 667, 676, nil, nil, nil, nil, + nil, nil, nil, 676, nil, 669, nil, 666, 665, 664, + 673, 667, nil, nil, nil, nil, nil, 671, nil, nil, + 676, nil, nil, nil, nil, 671, 681, 680, 684, 683, + nil, nil, nil, 677, 681, 680, 684, 683, nil, nil, + nil, 677, 671, nil, 669, nil, 666, 665, 664, 673, + 667, 681, 680, 684, 683, nil, nil, nil, 677, 676, + nil, 669, nil, 666, 665, 664, 673, 667, nil, 669, + nil, 666, 665, 664, 673, 667, 676, nil, nil, nil, + nil, 671, nil, nil, 676, nil, nil, nil, nil, nil, + 681, 680, 684, 683, nil, nil, nil, 677, 671, nil, + nil, nil, nil, nil, nil, nil, 671, 681, 680, 684, + 683, nil, nil, nil, 677, 681, 680, 684, 683, nil, + nil, 669, 677, 666, 665, 664, 673, 667, nil, 669, + nil, 666, 665, 664, 673, 667, 676, nil, nil, nil, + nil, nil, nil, nil, 676, nil, 669, nil, 666, 665, + 664, 673, 667, nil, nil, nil, nil, nil, 671, nil, + nil, 676, nil, nil, nil, nil, 671, 681, 680, 684, + 683, nil, nil, nil, 677, 681, 680, 684, 683, nil, + nil, nil, 677, 671, nil, 669, nil, 666, 665, 664, + 673, 667, nil, nil, 684, 683, nil, nil, nil, 677, + 676, nil, 669, nil, 666, 665, 664, 673, 667, 669, + nil, 666, 665, 664, 673, 667, nil, 676, nil, nil, + nil, nil, 671, nil, 676, nil, nil, nil, nil, nil, + nil, 681, 680, 684, 683, nil, nil, nil, 677, 671, + nil, nil, nil, nil, nil, nil, 671, nil, nil, nil, + 684, 683, nil, nil, nil, 677, nil, 684, 683, nil, + nil, 669, 677, 666, 665, 664, 673, 667, 669, nil, + 666, 665, 664, 673, 667, 669, 676, 666, 665, 664, + 673, 667, nil, 676, nil, nil, nil, nil, nil, nil, + 676, nil, nil, nil, nil, nil, nil, nil, 671, nil, + nil, nil, nil, nil, nil, 671, nil, nil, nil, 684, + 683, nil, 671, nil, 677, nil, 684, 683, nil, nil, + nil, 677, nil, 684, 683, nil, nil, nil, 677 ] + +racc_action_check = [ + 97, 437, 437, 562, 562, 61, 345, 97, 97, 97, + 19, 338, 97, 97, 97, 473, 97, 26, 58, 383, + 1, 481, 647, 647, 97, 384, 97, 97, 97, 329, + 618, 7, 329, 346, 349, 309, 97, 97, 359, 97, + 97, 97, 97, 97, 10, 339, 223, 861, 695, 546, + 473, 19, 697, 538, 482, 539, 481, 3, 58, 893, + 12, 893, 3, 224, 698, 788, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 13, 26, 97, 97, 97, 383, 97, 97, 820, 482, + 97, 384, 61, 97, 97, 437, 97, 562, 97, 309, + 97, 223, 97, 97, 26, 97, 97, 97, 97, 97, + 888, 97, 100, 97, 995, 345, 647, 618, 224, 100, + 100, 100, 309, 996, 100, 100, 100, 97, 100, 338, + 97, 97, 97, 97, 338, 97, 100, 97, 100, 100, + 100, 97, 346, 349, 359, 15, 699, 821, 100, 100, + 997, 100, 100, 100, 100, 100, 1016, 538, 546, 539, + 637, 697, 538, 339, 539, 861, 695, 359, 339, 695, + 861, 695, 359, 698, 788, 700, 558, 558, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 15, 226, 100, 100, 100, 820, 100, 100, + 15, 638, 100, 41, 41, 100, 100, 16, 100, 355, + 100, 699, 100, 355, 100, 100, 443, 100, 100, 100, + 100, 100, 419, 100, 22, 100, 637, 997, 888, 419, + 419, 419, 995, 888, 37, 419, 419, 995, 419, 100, + 700, 996, 100, 100, 100, 100, 996, 100, 226, 100, + 24, 821, 573, 100, 606, 699, 821, 24, 419, 419, + 40, 419, 419, 419, 419, 419, 637, 638, 997, 637, + 558, 443, 575, 997, 1016, 558, 619, 637, 289, 1016, + 45, 41, 41, 289, 700, 38, 314, 314, 419, 419, + 419, 419, 419, 419, 419, 419, 419, 419, 419, 419, + 419, 419, 378, 607, 419, 419, 419, 638, 419, 606, + 638, 619, 419, 632, 39, 419, 573, 573, 638, 111, + 419, 632, 419, 206, 419, 419, 573, 419, 419, 419, + 419, 419, 38, 419, 420, 419, 575, 575, 318, 750, + 38, 420, 420, 420, 413, 225, 575, 420, 420, 419, + 420, 342, 419, 419, 227, 419, 342, 419, 607, 420, + 228, 39, 353, 419, 314, 314, 378, 378, 378, 39, + 420, 420, 364, 420, 420, 420, 420, 420, 805, 364, + 805, 805, 805, 232, 805, 318, 944, 379, 944, 944, + 944, 413, 944, 318, 750, 17, 17, 264, 354, 413, + 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, + 420, 420, 420, 420, 353, 14, 420, 420, 420, 278, + 420, 353, 14, 279, 420, 380, 353, 420, 790, 282, + 353, 14, 420, 414, 420, 640, 420, 420, 790, 420, + 420, 420, 420, 420, 293, 420, 420, 420, 365, 353, + 354, 379, 379, 379, 381, 365, 294, 354, 296, 382, + 805, 420, 354, 385, 420, 420, 354, 420, 944, 420, + 608, 790, 790, 297, 366, 420, 790, 608, 608, 608, + 414, 366, 608, 608, 608, 354, 608, 640, 414, 380, + 380, 380, 298, 79, 640, 608, 608, 608, 608, 640, + 304, 46, 307, 640, 589, 79, 608, 608, 46, 608, + 608, 608, 608, 608, 222, 79, 308, 46, 381, 381, + 381, 222, 640, 382, 382, 382, 367, 385, 385, 385, + 222, 330, 333, 367, 330, 333, 608, 608, 608, 608, + 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, + 313, 589, 608, 608, 608, 468, 608, 608, 301, 589, + 608, 315, 368, 608, 608, 301, 608, 319, 608, 368, + 608, 322, 608, 608, 301, 608, 608, 608, 608, 608, + 557, 608, 608, 608, 327, 557, 369, 468, 331, 370, + 332, 468, 468, 369, 468, 468, 370, 608, 334, 824, + 608, 608, 608, 608, 824, 608, 609, 608, 20, 20, + 20, 608, 20, 609, 609, 609, 20, 20, 609, 609, + 609, 20, 609, 20, 20, 20, 20, 20, 20, 20, + 337, 337, 609, 609, 609, 20, 20, 20, 20, 20, + 20, 20, 609, 609, 20, 609, 609, 609, 609, 609, + 653, 20, 343, 653, 20, 20, 20, 20, 20, 20, + 20, 20, 344, 20, 20, 20, 348, 20, 20, 20, + 20, 20, 609, 609, 609, 609, 609, 609, 609, 609, + 609, 609, 609, 609, 609, 609, 522, 522, 609, 609, + 609, 20, 609, 609, 20, 350, 609, 20, 20, 609, + 609, 20, 609, 371, 609, 394, 609, 20, 609, 609, + 371, 609, 609, 609, 609, 609, 20, 609, 372, 609, + 400, 20, 20, 20, 20, 372, 20, 20, 20, 20, + 686, 686, 403, 609, 20, 20, 609, 609, 609, 609, + 405, 609, 20, 609, 20, 20, 20, 609, 0, 0, + 0, 0, 0, 0, 374, 829, 913, 0, 0, 913, + 829, 374, 0, 409, 0, 0, 0, 0, 0, 0, + 0, 411, 702, 793, 793, 412, 0, 0, 0, 0, + 0, 0, 0, 125, 421, 0, 985, 985, 125, 125, + 432, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 429, 0, 0, 0, 439, 0, 0, + 0, 0, 0, 432, 432, 432, 432, 432, 432, 432, + 432, 432, 432, 432, 702, 432, 432, 302, 451, 432, + 432, 702, 0, 452, 302, 0, 702, 453, 0, 0, + 702, 454, 0, 302, 0, 432, 479, 432, 0, 432, + 432, 838, 432, 432, 432, 432, 432, 0, 432, 702, + 483, 838, 0, 0, 0, 0, 303, 0, 0, 0, + 0, 498, 499, 303, 502, 0, 0, 504, 432, 509, + 432, 512, 303, 0, 520, 0, 0, 0, 33, 33, + 33, 33, 33, 33, 838, 838, 521, 33, 33, 838, + 523, 535, 33, 540, 33, 33, 33, 33, 33, 33, + 33, 541, 776, 560, 570, 578, 33, 33, 33, 33, + 33, 33, 33, 566, 566, 33, 580, 566, 566, 566, + 408, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 586, 33, 33, 33, 590, 33, 33, + 33, 33, 33, 408, 408, 408, 408, 408, 408, 408, + 408, 408, 408, 408, 776, 408, 408, 305, 595, 408, + 408, 776, 33, 600, 305, 33, 610, 612, 33, 33, + 776, 617, 33, 305, 33, 408, 624, 408, 33, 408, + 408, 626, 408, 408, 408, 408, 408, 33, 408, 776, + 631, 634, 33, 33, 33, 33, 320, 33, 33, 33, + 33, 636, 639, 320, 642, 33, 33, 643, 408, 646, + 648, 651, 320, 33, 657, 33, 33, 33, 123, 123, + 123, 123, 123, 123, 658, 660, 347, 123, 123, 661, + 662, 670, 123, 347, 123, 123, 123, 123, 123, 123, + 123, 678, 347, 682, 685, 688, 123, 123, 123, 123, + 123, 123, 123, 693, 696, 123, 705, 710, 729, 734, + 611, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, 752, 123, 123, 123, 753, 123, 123, + 123, 123, 123, 611, 611, 611, 611, 611, 611, 611, + 611, 611, 611, 611, 357, 611, 611, 508, 755, 611, + 611, 357, 123, 756, 508, 123, 757, 759, 123, 123, + 357, 760, 123, 508, 123, 611, 761, 611, 123, 611, + 611, 762, 611, 611, 611, 611, 611, 123, 611, 766, + 770, 771, 123, 123, 123, 123, 549, 123, 123, 123, + 123, 775, 779, 549, 782, 123, 123, 783, 611, 786, + 789, 804, 549, 123, 806, 123, 123, 123, 208, 208, + 208, 208, 208, 208, 811, 814, 851, 208, 208, 823, + 827, 828, 208, 851, 208, 208, 208, 208, 208, 208, + 208, 831, 851, 832, 848, 852, 208, 208, 208, 208, + 208, 208, 208, 854, 849, 208, 849, 849, 849, 868, + 849, 208, 208, 208, 208, 208, 208, 208, 208, 208, + 208, 208, 208, 869, 208, 208, 208, 873, 208, 208, + 208, 208, 208, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 641, 21, 21, 917, 874, 21, + 21, 641, 208, 876, 917, 208, 641, 877, 208, 208, + 641, 879, 208, 917, 208, 21, 882, 21, 208, 21, + 21, 884, 21, 21, 21, 21, 21, 208, 21, 890, + 891, 897, 208, 208, 208, 208, 923, 208, 208, 208, + 208, 901, 903, 923, 906, 208, 208, 907, 21, 908, + 909, 911, 923, 208, 926, 208, 208, 208, 231, 231, + 231, 231, 231, 231, 946, 968, 924, 231, 231, 969, + 970, 975, 231, 924, 231, 231, 231, 231, 231, 231, + 231, 976, 924, 977, 978, 979, 231, 231, 231, 231, + 231, 231, 231, 980, 967, 231, 967, 967, 967, 981, + 967, 231, 231, 231, 231, 231, 231, 231, 231, 231, + 231, 231, 231, 983, 231, 231, 231, 986, 231, 231, + 231, 231, 231, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, 276, 703, 276, 276, 925, 987, 276, + 276, 703, 231, 988, 925, 231, 703, 989, 231, 231, + 703, 990, 231, 925, 231, 276, 991, 276, 231, 276, + 276, 994, 276, 276, 276, 276, 276, 231, 276, 1007, + 1017, 1018, 231, 231, 231, 231, 927, 231, 231, 231, + 231, 1019, nil, 927, nil, 231, 231, nil, 276, nil, + nil, nil, 927, 231, nil, 231, 231, 231, 295, 295, + 295, 295, 295, 295, nil, nil, 974, 295, 295, nil, + nil, nil, 295, 974, 295, 295, 295, 295, 295, 295, + 295, nil, 974, nil, nil, nil, 295, 295, 295, 295, + 295, 295, 295, nil, nil, 295, 6, 6, 6, 6, + 6, 295, 295, 295, 295, 295, 295, 295, 295, 295, + 295, 295, 295, nil, 295, 295, 295, nil, 295, 295, + 295, 295, 295, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 998, 427, 427, nil, nil, 427, + 427, 998, 295, nil, nil, 295, 998, nil, 295, 295, + 998, nil, 295, nil, 295, 427, nil, 427, 295, 427, + 427, nil, 427, 427, 427, 427, 427, 295, 427, nil, + nil, nil, 295, 295, 295, 295, nil, 295, 295, 295, + 295, nil, nil, nil, nil, 295, 295, nil, 427, nil, + nil, nil, nil, 295, nil, 295, 295, 295, 300, 300, + 300, 300, 300, 300, nil, nil, nil, 300, 300, nil, + nil, nil, 300, nil, 300, 300, 300, 300, 300, 300, + 300, 292, 292, 292, 292, 292, 300, 300, 300, 300, + 300, 300, 300, nil, nil, 300, 496, 496, 496, 496, + 496, 300, 300, 300, 300, 300, 300, 300, 300, 300, + 300, 300, 300, nil, 300, 300, 300, nil, 300, 300, + 300, 300, 300, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, nil, 472, 472, nil, nil, 472, + 472, nil, 300, nil, nil, 300, nil, nil, 300, 300, + nil, nil, 300, nil, 300, 472, nil, 472, 300, 472, + 472, nil, 472, 472, 472, 472, 472, 300, 472, nil, + nil, nil, 300, 300, 300, 300, nil, 300, 300, 300, + 300, nil, nil, nil, nil, 300, 300, 472, 472, nil, + nil, nil, nil, 300, nil, 300, 300, 300, 325, 325, + 325, 325, 325, 325, nil, nil, nil, 325, 325, nil, + nil, nil, 325, nil, 325, 325, 325, 325, 325, 325, + 325, nil, nil, nil, nil, nil, 325, 325, 325, 325, + 325, 325, 325, nil, nil, 325, nil, nil, nil, nil, + nil, 325, 325, 325, 325, 325, 325, 325, 325, 325, + 325, 325, 325, nil, 325, 325, 325, nil, 325, 325, + 325, 325, 325, 518, 518, 518, 518, 518, 518, 518, + 518, 518, 518, 518, nil, 518, 518, nil, nil, 518, + 518, nil, 325, nil, nil, 325, nil, nil, 325, 325, + nil, nil, 325, nil, 325, 518, nil, 518, 325, 518, + 518, nil, 518, 518, 518, 518, 518, 325, 518, nil, + nil, nil, 325, 325, 325, 325, nil, 325, 325, 325, + 325, nil, nil, nil, nil, 325, 325, nil, 518, nil, + nil, nil, nil, 325, nil, 325, 325, 325, 497, 497, + 497, 497, 497, 497, nil, nil, nil, 497, 497, nil, + nil, nil, 497, nil, 497, 497, 497, 497, 497, 497, + 497, nil, nil, nil, nil, nil, 497, 497, 497, 497, + 497, 497, 497, nil, nil, 497, nil, nil, nil, nil, + nil, 497, 497, 497, 497, 497, 497, 497, 497, 497, + 497, 497, 497, nil, 497, 497, 497, nil, 497, 497, + 497, 497, 497, 645, 645, 645, 645, 645, 645, 645, + 645, 645, 645, 645, nil, 645, 645, nil, nil, 645, + 645, nil, 497, nil, nil, 497, nil, nil, 497, 497, + nil, nil, 497, nil, 497, 645, nil, 645, 497, 645, + 645, nil, 645, 645, 645, 645, 645, 497, 645, nil, + nil, nil, 497, 497, 497, 497, nil, 497, 497, 497, + 497, nil, nil, nil, nil, 497, 497, nil, 645, nil, + nil, nil, nil, 497, nil, 497, 497, 497, 534, 534, + 534, 534, 534, 534, nil, nil, nil, 534, 534, nil, + nil, nil, 534, nil, 534, 534, 534, 534, 534, 534, + 534, nil, nil, nil, nil, nil, 534, 534, 534, 534, + 534, 534, 534, nil, nil, 534, nil, nil, nil, nil, + nil, 534, 534, 534, 534, 534, 534, 534, 534, 534, + 534, 534, 534, nil, 534, 534, 534, nil, 534, 534, + 534, 534, 534, 731, 731, 731, 731, 731, 731, 731, + 731, 731, 731, 731, nil, 731, 731, nil, nil, 731, + 731, nil, 534, nil, nil, 534, nil, nil, 534, 534, + nil, nil, 534, nil, 534, 731, nil, 731, 534, 731, + 731, nil, 731, 731, 731, 731, 731, 534, 731, nil, + nil, nil, 534, 534, 534, 534, nil, 534, 534, 534, + 534, nil, nil, nil, nil, 534, 534, nil, 731, nil, + nil, nil, nil, 534, nil, 534, 534, 534, 537, 537, + 537, 537, 537, 537, nil, nil, nil, 537, 537, nil, + nil, nil, 537, nil, 537, 537, 537, 537, 537, 537, + 537, nil, nil, nil, nil, nil, 537, 537, 537, 537, + 537, 537, 537, nil, nil, 537, nil, nil, nil, nil, + nil, 537, 537, 537, 537, 537, 537, 537, 537, 537, + 537, 537, 537, nil, 537, 537, 537, nil, 537, 537, + 537, 537, 537, 736, 736, 736, 736, 736, 736, 736, + 736, 736, 736, 736, nil, 736, 736, nil, nil, 736, + 736, nil, 537, nil, nil, 537, nil, nil, 537, 537, + nil, nil, 537, nil, 537, 736, nil, 736, 537, 736, + 736, nil, 736, 736, 736, 736, 736, 537, 736, nil, + nil, nil, 537, 537, 537, 537, nil, 537, 537, 537, + 537, nil, nil, nil, nil, 537, 537, nil, 736, nil, + nil, nil, nil, 537, nil, 537, 537, 537, 559, 559, + 559, 559, 559, 559, nil, nil, nil, 559, 559, nil, + nil, nil, 559, nil, 559, 559, 559, 559, 559, 559, + 559, nil, nil, nil, nil, nil, 559, 559, 559, 559, + 559, 559, 559, nil, nil, 559, nil, nil, nil, nil, + nil, 559, 559, 559, 559, 559, 559, 559, 559, 559, + 559, 559, 559, nil, 559, 559, 559, nil, 559, 559, + 559, 559, 559, 738, 738, 738, 738, 738, 738, 738, + 738, 738, 738, 738, nil, 738, 738, nil, nil, 738, + 738, nil, 559, nil, nil, 559, nil, nil, 559, 559, + nil, nil, 559, nil, 559, 738, nil, 738, 559, 738, + 738, nil, 738, 738, 738, 738, 738, 559, 738, nil, + nil, nil, 559, 559, 559, 559, nil, 559, 559, 559, + 559, nil, nil, nil, nil, 559, 559, nil, 738, nil, + nil, nil, nil, 559, nil, 559, 559, 559, 616, 616, + 616, 616, 616, 616, nil, nil, nil, 616, 616, nil, + nil, nil, 616, nil, 616, 616, 616, 616, 616, 616, + 616, nil, nil, nil, nil, nil, 616, 616, 616, 616, + 616, 616, 616, nil, nil, 616, nil, nil, nil, nil, + nil, 616, 616, 616, 616, 616, 616, 616, 616, 616, + 616, 616, 616, nil, 616, 616, 616, nil, 616, 616, + 616, 616, 616, 741, 741, 741, 741, 741, 741, 741, + 741, 741, 741, 741, nil, 741, 741, nil, nil, 741, + 741, nil, 616, nil, nil, 616, nil, nil, 616, 616, + nil, nil, 616, nil, 616, 741, nil, 741, 616, 741, + 741, nil, 741, 741, 741, 741, 741, 616, 741, nil, + nil, nil, 616, 616, 616, 616, nil, 616, 616, 616, + 616, nil, nil, nil, nil, 616, 616, nil, 741, nil, + nil, nil, nil, 616, nil, 616, 616, 616, 621, 621, + 621, 621, 621, 621, nil, nil, nil, 621, 621, nil, + nil, nil, 621, nil, 621, 621, 621, 621, 621, 621, + 621, nil, nil, nil, nil, nil, 621, 621, 621, 621, + 621, 621, 621, nil, nil, 621, nil, nil, nil, nil, + nil, 621, 621, 621, 621, 621, 621, 621, 621, 621, + 621, 621, 621, nil, 621, 621, 621, nil, 621, 621, + 621, 621, 621, 743, 743, 743, 743, 743, 743, 743, + 743, 743, 743, 743, nil, 743, 743, nil, nil, 743, + 743, nil, 621, nil, nil, 621, nil, nil, 621, 621, + nil, nil, 621, nil, 621, 743, nil, 743, 621, 743, + 743, nil, 743, 743, 743, 743, 743, 621, 743, nil, + nil, nil, 621, 621, 621, 621, nil, 621, 621, 621, + 621, nil, nil, nil, nil, 621, 621, nil, 743, nil, + nil, nil, nil, 621, nil, 621, 621, 621, 622, 622, + 622, 622, 622, 622, nil, nil, nil, 622, 622, nil, + nil, nil, 622, nil, 622, 622, 622, 622, 622, 622, + 622, nil, nil, nil, nil, nil, 622, 622, 622, 622, + 622, 622, 622, nil, nil, 622, nil, nil, nil, nil, + nil, 622, 622, 622, 622, 622, 622, 622, 622, 622, + 622, 622, 622, nil, 622, 622, 622, nil, 622, 622, + 622, 622, 622, 745, 745, 745, 745, 745, 745, 745, + 745, 745, 745, 745, nil, 745, 745, nil, nil, 745, + 745, nil, 622, nil, nil, 622, nil, nil, 622, 622, + nil, nil, 622, nil, 622, 745, nil, 745, 622, 745, + 745, nil, 745, 745, 745, 745, 745, 622, 745, nil, + nil, nil, 622, 622, 622, 622, nil, 622, 622, 622, + 622, nil, nil, nil, nil, 622, 622, nil, 745, nil, + nil, nil, nil, 622, nil, 622, 622, 622, 706, 706, + 706, 706, 706, 706, nil, nil, nil, 706, 706, nil, + nil, nil, 706, nil, 706, 706, 706, 706, 706, 706, + 706, nil, nil, nil, nil, nil, 706, 706, 706, 706, + 706, 706, 706, nil, nil, 706, nil, nil, nil, nil, + nil, 706, 706, 706, 706, 706, 706, 706, 706, 706, + 706, 706, 706, nil, 706, 706, 706, nil, 706, 706, + 706, 706, 706, 834, 834, 834, 834, 834, 834, 834, + 834, 834, 834, 834, nil, 834, 834, nil, nil, 834, + 834, nil, 706, nil, nil, 706, nil, nil, 706, 706, + nil, nil, 706, nil, 706, 834, nil, 834, 706, 834, + 834, nil, 834, 834, 834, 834, 834, 706, 834, nil, + nil, nil, 706, 706, 706, 706, nil, 706, 706, 706, + 706, nil, nil, nil, nil, 706, 706, nil, 834, nil, + nil, nil, nil, 706, nil, 706, 706, 706, 711, 711, + 711, 711, 711, 711, nil, nil, nil, 711, 711, nil, + nil, nil, 711, nil, 711, 711, 711, 711, 711, 711, + 711, nil, nil, nil, nil, nil, 711, 711, 711, 711, + 711, 711, 711, nil, nil, 711, nil, nil, nil, nil, + nil, 711, 711, 711, 711, 711, 711, 711, 711, 711, + 711, 711, 711, nil, 711, 711, 711, nil, 711, 711, + 711, 711, 711, 837, 837, 837, 837, 837, 837, 837, + 837, 837, 837, 837, nil, 837, 837, nil, nil, 837, + 837, nil, 711, nil, nil, 711, nil, nil, 711, 711, + nil, nil, 711, nil, 711, 837, nil, 837, 711, 837, + 837, nil, 837, 837, 837, 837, 837, 711, 837, nil, + nil, nil, 711, 711, 711, 711, nil, 711, 711, 711, + 711, nil, nil, nil, nil, 711, 711, nil, 837, nil, + nil, nil, nil, 711, nil, 711, 711, 711, 721, 721, + 721, 721, 721, 721, nil, nil, nil, 721, 721, nil, + nil, nil, 721, nil, 721, 721, 721, 721, 721, 721, + 721, nil, nil, nil, nil, nil, 721, 721, 721, 721, + 721, 721, 721, nil, 671, 721, 671, 671, 671, nil, + 671, 721, 721, 721, 721, 721, 721, 721, 721, 721, + 721, 721, 721, nil, 721, 721, 721, nil, 721, 721, + 721, 721, 721, 802, nil, 802, 802, 802, nil, 802, + nil, 671, nil, nil, 449, nil, nil, nil, nil, nil, + 671, nil, 721, nil, nil, 721, nil, nil, 721, 721, + nil, nil, 721, nil, 721, nil, nil, nil, 721, nil, + 802, nil, nil, nil, nil, nil, 449, 721, nil, 802, + 449, 449, 721, 721, 721, 721, nil, 721, 721, 721, + 721, nil, nil, nil, nil, 721, 721, nil, 883, nil, + 883, 883, 883, 721, 883, 721, 721, 721, 769, 769, + 769, 769, 769, 769, nil, nil, nil, 769, 769, nil, + nil, nil, 769, nil, 769, 769, 769, 769, 769, 769, + 769, nil, nil, nil, nil, 883, 769, 769, 769, 769, + 769, 769, 769, nil, 883, 769, nil, nil, nil, nil, + nil, 769, 769, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, nil, 769, 769, 769, nil, 769, 769, + 769, 769, 769, 447, 447, 447, 447, 447, 447, 447, + 447, 447, 447, 447, nil, 447, 447, nil, nil, 447, + 447, nil, 769, nil, nil, 769, nil, nil, 769, 769, + nil, 469, 769, nil, 769, 447, nil, 447, 769, 447, + 447, nil, 447, 447, 447, 447, 447, 769, 447, nil, + nil, nil, 769, 769, 769, 769, nil, 769, 769, 769, + 769, nil, nil, 469, nil, 769, 769, 469, 469, nil, + 469, 469, nil, 769, nil, 769, 769, 769, 781, 781, + 781, 781, 781, 781, nil, nil, nil, 781, 781, nil, + nil, nil, 781, nil, 781, 781, 781, 781, 781, 781, + 781, nil, nil, nil, nil, nil, 781, 781, 781, 781, + 781, 781, 781, nil, nil, 781, nil, nil, nil, nil, + nil, 781, 781, 781, 781, 781, 781, 781, 781, 781, + 781, 781, 781, nil, 781, 781, 781, nil, 781, 781, + 781, 781, 781, 448, 448, 448, 448, 448, 448, 448, + 448, 448, 448, 448, nil, 448, 448, nil, nil, 448, + 448, nil, 781, nil, nil, 781, nil, nil, 781, 781, + nil, 450, 781, nil, 781, 448, nil, 448, 781, 448, + 448, nil, 448, 448, 448, 448, 448, 781, 448, nil, + nil, nil, 781, 781, 781, 781, nil, 781, 781, 781, + 781, nil, nil, 450, nil, 781, 781, 450, 450, nil, + nil, nil, nil, 781, nil, 781, 781, 781, 815, 815, + 815, 815, 815, 815, nil, nil, nil, 815, 815, nil, + nil, nil, 815, nil, 815, 815, 815, 815, 815, 815, + 815, nil, nil, nil, nil, nil, 815, 815, 815, 815, + 815, 815, 815, nil, 885, 815, 885, 885, 885, nil, + 885, 815, 815, 815, 815, 815, 815, 815, 815, 815, + 815, 815, 815, nil, 815, 815, 815, nil, 815, 815, + 815, 815, 815, 458, 458, 458, 458, 458, 458, 458, + nil, 885, 458, 458, nil, nil, nil, nil, nil, 458, + 458, nil, 815, nil, nil, 815, nil, nil, 815, 815, + nil, nil, 815, nil, 815, 458, nil, 458, 815, 458, + 458, nil, 458, 458, 458, 458, 458, 815, 458, nil, + nil, nil, 815, 815, 815, 815, nil, 815, 815, 815, + 815, nil, nil, nil, nil, 815, 815, nil, 945, nil, + 945, 945, 945, 815, 945, 815, 815, 815, 816, 816, + 816, 816, 816, 816, nil, nil, nil, 816, 816, nil, + nil, nil, 816, nil, 816, 816, 816, 816, 816, 816, + 816, nil, nil, nil, nil, 945, 816, 816, 816, 816, + 816, 816, 816, nil, 982, 816, 982, 982, 982, nil, + 982, 816, 816, 816, 816, 816, 816, 816, 816, 816, + 816, 816, 816, nil, 816, 816, 816, nil, 816, 816, + 816, 816, 816, 459, 984, nil, 984, 984, 984, nil, + 984, 982, 1006, nil, 1006, 1006, 1006, nil, 1006, 459, + 459, nil, 816, nil, nil, 816, nil, nil, 816, 816, + nil, nil, 816, nil, 816, 459, nil, 459, 816, 459, + 459, 984, 459, 459, nil, nil, 459, 816, 459, 1006, + nil, nil, 816, 816, 816, 816, nil, 816, 816, 816, + 816, nil, nil, nil, nil, 816, 816, nil, nil, nil, + nil, nil, nil, 816, nil, 816, 816, 816, 819, 819, + 819, 819, 819, 819, nil, nil, nil, 819, 819, nil, + nil, nil, 819, nil, 819, 819, 819, 819, 819, 819, + 819, nil, nil, nil, nil, nil, 819, 819, 819, 819, + 819, 819, 819, nil, nil, 819, nil, nil, nil, nil, + nil, 819, 819, 819, 819, 819, 819, 819, 819, 819, + 819, 819, 819, nil, 819, 819, 819, nil, 819, 819, + 819, 819, 819, 460, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 460, + 460, nil, 819, nil, nil, 819, nil, nil, 819, 819, + nil, nil, 819, nil, 819, 460, nil, 460, 819, 460, + 460, nil, 460, 460, nil, nil, 460, 819, 460, nil, + nil, nil, 819, 819, 819, 819, nil, 819, 819, 819, + 819, nil, nil, nil, nil, 819, 819, nil, nil, nil, + nil, nil, nil, 819, nil, 819, 819, 819, 825, 825, + 825, 825, 825, 825, nil, nil, nil, 825, 825, nil, + nil, nil, 825, nil, 825, 825, 825, 825, 825, 825, + 825, nil, nil, nil, nil, nil, 825, 825, 825, 825, + 825, 825, 825, nil, nil, 825, nil, nil, nil, nil, + nil, 825, 825, 825, 825, 825, 825, 825, 825, 825, + 825, 825, 825, nil, 825, 825, 825, nil, 825, 825, + 825, 825, 825, 461, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 461, + 461, nil, 825, nil, nil, 825, nil, nil, 825, 825, + nil, nil, 825, nil, 825, 461, nil, 461, 825, 461, + 461, nil, 461, 461, nil, nil, 461, 825, 461, nil, + nil, nil, 825, 825, 825, 825, nil, 825, 825, 825, + 825, nil, nil, nil, nil, 825, 825, nil, nil, nil, + nil, nil, nil, 825, nil, 825, 825, 825, 858, 858, + 858, 858, 858, 858, nil, nil, nil, 858, 858, nil, + nil, nil, 858, nil, 858, 858, 858, 858, 858, 858, + 858, nil, nil, nil, nil, nil, 858, 858, 858, 858, + 858, 858, 858, nil, nil, 858, nil, nil, nil, nil, + nil, 858, 858, 858, 858, 858, 858, 858, 858, 858, + 858, 858, 858, nil, 858, 858, 858, nil, 858, 858, + 858, 858, 858, 462, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 462, + 462, nil, 858, nil, nil, 858, nil, nil, 858, 858, + nil, nil, 858, nil, 858, 462, nil, 462, 858, 462, + 462, nil, 462, 462, nil, nil, 462, 858, 462, nil, + nil, nil, 858, 858, 858, 858, nil, 858, 858, 858, + 858, nil, nil, nil, nil, 858, 858, nil, nil, nil, + nil, nil, nil, 858, nil, 858, 858, 858, 922, 922, + 922, 922, 922, 922, nil, nil, nil, 922, 922, nil, + nil, nil, 922, nil, 922, 922, 922, 922, 922, 922, + 922, nil, nil, nil, nil, nil, 922, 922, 922, 922, + 922, 922, 922, nil, nil, 922, nil, nil, nil, nil, + nil, 922, 922, 922, 922, 922, 922, 922, 922, 922, + 922, 922, 922, nil, 922, 922, 922, nil, 922, 922, + 922, 922, 922, 463, 463, 463, 463, 463, 463, 463, + nil, nil, 463, 463, nil, nil, nil, nil, nil, 463, + 463, nil, 922, nil, nil, 922, nil, nil, 922, 922, + nil, nil, 922, nil, 922, 463, nil, 463, 922, 463, + 463, nil, 463, 463, 463, 463, 463, 922, 463, nil, + nil, nil, 922, 922, 922, 922, nil, 922, 922, 922, + 922, nil, nil, nil, nil, 922, 922, nil, nil, nil, + nil, nil, nil, 922, nil, 922, 922, 922, 929, 929, + 929, 929, 929, 929, nil, nil, nil, 929, 929, nil, + nil, nil, 929, nil, 929, 929, 929, 929, 929, 929, + 929, nil, nil, nil, nil, nil, 929, 929, 929, 929, + 929, 929, 929, nil, nil, 929, nil, nil, nil, nil, + nil, 929, 929, 929, 929, 929, 929, 929, 929, 929, + 929, 929, 929, nil, 929, 929, 929, nil, 929, 929, + 929, 929, 929, 464, 464, 464, 464, 464, 464, 464, + nil, nil, 464, 464, nil, nil, nil, nil, nil, 464, + 464, nil, 929, nil, nil, 929, nil, nil, 929, 929, + nil, nil, 929, nil, 929, 464, nil, 464, 929, 464, + 464, nil, 464, 464, 464, 464, 464, 929, 464, nil, + nil, nil, 929, 929, 929, 929, nil, 929, 929, 929, + 929, nil, nil, nil, nil, 929, 929, nil, nil, nil, + nil, nil, nil, 929, nil, 929, 929, 929, 930, 930, + 930, 930, 930, 930, nil, nil, nil, 930, 930, nil, + nil, nil, 930, nil, 930, 930, 930, 930, 930, 930, + 930, nil, nil, nil, nil, nil, 930, 930, 930, 930, + 930, 930, 930, nil, nil, 930, nil, nil, nil, nil, + nil, 930, 930, 930, 930, 930, 930, 930, 930, 930, + 930, 930, 930, nil, 930, 930, 930, nil, 930, 930, + 930, 930, 930, 465, 465, 465, 465, 465, 465, 465, + nil, nil, 465, 465, nil, nil, nil, nil, nil, 465, + 465, nil, 930, nil, nil, 930, nil, nil, 930, 930, + nil, nil, 930, nil, 930, 465, nil, 465, 930, 465, + 465, nil, 465, 465, 465, 465, 465, 930, 465, nil, + nil, nil, 930, 930, 930, 930, nil, 930, 930, 930, + 930, nil, nil, nil, nil, 930, 930, nil, nil, nil, + nil, nil, nil, 930, nil, 930, 930, 930, 947, 947, + 947, 947, 947, 947, nil, nil, nil, 947, 947, nil, + nil, nil, 947, nil, 947, 947, 947, 947, 947, 947, + 947, nil, nil, nil, nil, nil, 947, 947, 947, 947, + 947, 947, 947, nil, nil, 947, nil, nil, nil, nil, + nil, 947, 947, 947, 947, 947, 947, 947, 947, 947, + 947, 947, 947, nil, 947, 947, 947, nil, 947, 947, + 947, 947, 947, 466, 466, 466, 466, 466, 466, 466, + nil, nil, 466, 466, nil, nil, nil, nil, nil, 466, + 466, nil, 947, nil, nil, 947, nil, nil, 947, 947, + nil, nil, 947, nil, 947, 466, nil, 466, 947, 466, + 466, nil, 466, 466, 466, 466, 466, 947, 466, nil, + nil, nil, 947, 947, 947, 947, nil, 947, 947, 947, + 947, nil, nil, nil, nil, 947, 947, nil, nil, nil, + nil, nil, nil, 947, nil, 947, 947, 947, 953, 953, + 953, 953, 953, 953, nil, nil, nil, 953, 953, nil, + nil, nil, 953, nil, 953, 953, 953, 953, 953, 953, + 953, nil, nil, nil, nil, nil, 953, 953, 953, 953, + 953, 953, 953, nil, nil, 953, nil, nil, nil, nil, + nil, 953, 953, 953, 953, 953, 953, 953, 953, 953, + 953, 953, 953, nil, 953, 953, 953, nil, 953, 953, + 953, 953, 953, 467, 467, 467, 467, 467, 467, 467, + nil, nil, 467, 467, nil, nil, nil, nil, nil, 467, + 467, nil, 953, nil, nil, 953, nil, nil, 953, 953, + nil, nil, 953, nil, 953, 467, nil, 467, 953, 467, + 467, nil, 467, 467, 467, 467, 467, 953, 467, nil, + nil, nil, 953, 953, 953, 953, nil, 953, 953, 953, + 953, nil, nil, nil, nil, 953, 953, nil, nil, nil, + nil, nil, nil, 953, nil, 953, 953, 953, 955, 955, + 955, 955, 955, 955, nil, nil, nil, 955, 955, nil, + nil, nil, 955, nil, 955, 955, 955, 955, 955, 955, + 955, nil, nil, nil, nil, nil, 955, 955, 955, 955, + 955, 955, 955, nil, nil, 955, nil, nil, nil, nil, + nil, 955, 955, 955, 955, 955, 955, 955, 955, 955, + 955, 955, 955, nil, 955, 955, 955, nil, 955, 955, + 955, 955, 955, 470, 470, 470, 470, 470, 470, 470, + nil, nil, 470, 470, nil, nil, nil, nil, nil, 470, + 470, nil, 955, nil, nil, 955, nil, nil, 955, 955, + nil, nil, 955, nil, 955, 470, nil, 470, 955, 470, + 470, nil, 470, 470, 470, 470, 470, 955, 470, nil, + nil, nil, 955, 955, 955, 955, nil, 955, 955, 955, + 955, nil, nil, nil, nil, 955, 955, nil, nil, nil, + nil, nil, nil, 955, nil, 955, 955, 955, 5, 5, + 5, 5, 5, nil, nil, nil, 5, 5, nil, nil, + nil, 5, nil, 5, 5, 5, 5, 5, 5, 5, + nil, nil, nil, nil, nil, 5, 5, 5, 5, 5, + 5, 5, nil, nil, 5, nil, nil, nil, nil, nil, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, nil, 5, 5, 5, nil, 5, 5, 5, + 5, 5, 471, 471, 471, 471, 471, 471, 471, 471, + nil, 471, 471, nil, nil, nil, nil, nil, 471, 471, + nil, 5, nil, nil, 5, nil, nil, 5, 5, nil, + nil, 5, nil, 5, 471, nil, 471, 5, 471, 471, + nil, 471, 471, 471, 471, 471, 5, 471, nil, nil, + nil, 5, 5, 5, 5, nil, 5, 5, 5, 5, + nil, nil, nil, nil, 5, 5, nil, nil, nil, 29, + 29, 29, 5, 29, 5, 5, 5, 29, 29, nil, + nil, nil, 29, nil, 29, 29, 29, 29, 29, 29, + 29, nil, nil, nil, nil, nil, 29, 29, 29, 29, + 29, 29, 29, nil, nil, 29, nil, nil, nil, nil, + nil, nil, 29, nil, nil, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, nil, 29, 29, + 29, 29, 29, 455, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 455, + 455, nil, 29, nil, nil, 29, nil, nil, 29, 29, + nil, nil, 29, nil, 29, 455, 29, 455, 29, 455, + 455, 29, 455, 455, nil, nil, nil, 29, nil, nil, + nil, nil, 29, 29, 29, 29, nil, 29, 29, 29, + 29, nil, nil, nil, nil, 29, 29, nil, nil, nil, + 30, 30, 30, 29, 30, 29, 29, 29, 30, 30, + nil, nil, nil, 30, nil, 30, 30, 30, 30, 30, + 30, 30, nil, nil, nil, nil, nil, 30, 30, 30, + 30, 30, 30, 30, nil, nil, 30, nil, nil, nil, + nil, nil, nil, 30, nil, nil, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, nil, 30, + 30, 30, 30, 30, 456, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 456, 456, nil, 30, nil, nil, 30, nil, nil, 30, + 30, nil, nil, 30, nil, 30, 456, 30, 456, 30, + 456, 456, 30, 456, 456, nil, nil, nil, 30, nil, + nil, nil, nil, 30, 30, 30, 30, nil, 30, 30, + 30, 30, nil, nil, nil, nil, 30, 30, nil, nil, + nil, 31, 31, 31, 30, 31, 30, 30, 30, 31, + 31, nil, nil, nil, 31, nil, 31, 31, 31, 31, + 31, 31, 31, nil, nil, nil, nil, nil, 31, 31, + 31, 31, 31, 31, 31, nil, nil, 31, nil, nil, + nil, nil, nil, nil, 31, nil, nil, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, nil, + 31, 31, 31, 31, 31, 457, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 457, 457, nil, 31, nil, nil, 31, nil, nil, + 31, 31, nil, nil, 31, nil, 31, 457, 31, nil, + 31, 457, 457, 31, 457, 457, nil, nil, nil, 31, + nil, nil, nil, nil, 31, 31, 31, 31, nil, 31, + 31, 31, 31, nil, nil, nil, nil, 31, 31, nil, + nil, nil, 34, 34, 34, 31, 34, 31, 31, 31, + 34, 34, nil, nil, nil, 34, nil, 34, 34, 34, + 34, 34, 34, 34, nil, nil, nil, nil, nil, 34, + 34, 34, 34, 34, 34, 34, nil, nil, 34, nil, + nil, nil, nil, nil, nil, 34, nil, nil, 34, 34, + 34, 34, 34, 34, 34, 34, nil, 34, 34, 34, + nil, 34, 34, nil, nil, 34, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 34, nil, nil, 34, nil, + nil, 34, 34, nil, nil, 34, nil, 34, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 34, 34, 34, 34, nil, + 34, 34, 34, 34, nil, nil, nil, nil, 34, 34, + nil, nil, nil, 35, 35, 35, 34, 35, 34, 34, + 34, 35, 35, nil, nil, nil, 35, nil, 35, 35, + 35, 35, 35, 35, 35, nil, nil, nil, nil, nil, + 35, 35, 35, 35, 35, 35, 35, nil, nil, 35, + nil, nil, nil, nil, nil, nil, 35, nil, nil, 35, + 35, 35, 35, 35, 35, 35, 35, nil, 35, 35, + 35, nil, 35, 35, nil, nil, 35, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 35, nil, nil, 35, + nil, nil, 35, 35, nil, nil, 35, nil, nil, 798, + nil, 798, 798, 798, 798, 798, nil, nil, nil, nil, + nil, nil, nil, nil, 798, nil, 35, 35, 35, 35, + nil, 35, 35, 35, 35, nil, nil, nil, nil, 35, + 35, nil, nil, nil, 35, nil, 798, 35, nil, 35, + 35, 35, 42, 42, 42, nil, 42, 798, 798, nil, + 42, 42, 798, nil, nil, 42, nil, 42, 42, 42, + 42, 42, 42, 42, nil, nil, nil, nil, nil, 42, + 42, 42, 42, 42, 42, 42, nil, nil, 42, nil, + nil, nil, nil, nil, nil, 42, nil, nil, 42, 42, + 42, 42, 42, 42, 42, 42, nil, 42, 42, 42, + nil, 42, 42, 42, 42, 42, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 42, nil, nil, 42, nil, + nil, 42, 42, nil, nil, 42, nil, nil, nil, nil, + nil, 42, nil, nil, nil, nil, nil, nil, nil, nil, + 42, nil, nil, nil, nil, 42, 42, 42, 42, nil, + 42, 42, 42, 42, nil, nil, nil, nil, 42, 42, + nil, nil, nil, 43, 43, 43, 42, 43, 42, 42, + 42, 43, 43, nil, nil, nil, 43, nil, 43, 43, + 43, 43, 43, 43, 43, nil, nil, nil, nil, nil, + 43, 43, 43, 43, 43, 43, 43, nil, nil, 43, + nil, nil, nil, nil, nil, nil, 43, nil, nil, 43, + 43, 43, 43, 43, 43, 43, 43, nil, 43, 43, + 43, nil, 43, 43, 43, 43, 43, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 43, nil, nil, 43, + nil, nil, 43, 43, nil, nil, 43, nil, nil, nil, + nil, nil, 43, nil, nil, nil, nil, nil, nil, nil, + nil, 43, nil, nil, nil, nil, 43, 43, 43, 43, + nil, 43, 43, 43, 43, nil, nil, nil, nil, 43, + 43, nil, nil, nil, 44, 44, 44, 43, 44, 43, + 43, 43, 44, 44, nil, nil, nil, 44, nil, 44, + 44, 44, 44, 44, 44, 44, nil, nil, nil, nil, + nil, 44, 44, 44, 44, 44, 44, 44, nil, nil, + 44, nil, nil, nil, nil, nil, nil, 44, nil, nil, + 44, 44, 44, 44, 44, 44, 44, 44, nil, 44, + 44, 44, nil, 44, 44, 44, 44, 44, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 44, nil, nil, + 44, nil, nil, 44, 44, nil, nil, 44, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, 44, 44, 44, + 44, nil, 44, 44, 44, 44, nil, nil, nil, nil, + 44, 44, nil, nil, nil, 59, 59, 59, 44, 59, + 44, 44, 44, 59, 59, nil, nil, nil, 59, nil, + 59, 59, 59, 59, 59, 59, 59, nil, nil, nil, + nil, nil, 59, 59, 59, 59, 59, 59, 59, nil, + nil, 59, nil, nil, nil, nil, nil, nil, 59, nil, + nil, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, nil, 59, 59, 59, 59, 59, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 59, nil, + nil, 59, nil, nil, 59, 59, nil, nil, 59, nil, + 59, nil, nil, nil, 59, nil, nil, 59, nil, nil, + nil, nil, nil, 59, nil, nil, nil, nil, 59, 59, + 59, 59, nil, 59, 59, 59, 59, nil, nil, nil, + nil, 59, 59, nil, nil, nil, 60, 60, 60, 59, + 60, 59, 59, 59, 60, 60, nil, nil, nil, 60, + nil, 60, 60, 60, 60, 60, 60, 60, nil, nil, + nil, nil, nil, 60, 60, 60, 60, 60, 60, 60, + nil, nil, 60, nil, nil, nil, nil, nil, nil, 60, + nil, nil, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, nil, 60, 60, 60, 60, 60, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 60, + nil, nil, 60, nil, nil, 60, 60, nil, nil, 60, + nil, nil, nil, nil, nil, 60, nil, nil, 60, nil, + nil, nil, nil, nil, 60, nil, nil, nil, nil, 60, + 60, 60, 60, nil, 60, 60, 60, 60, nil, nil, + nil, nil, 60, 60, nil, nil, nil, 63, 63, 63, + 60, 63, 60, 60, 60, 63, 63, nil, nil, nil, + 63, nil, 63, 63, 63, 63, 63, 63, 63, nil, + nil, nil, nil, nil, 63, 63, 63, 63, 63, 63, + 63, nil, nil, 63, nil, nil, nil, nil, nil, nil, + 63, nil, nil, 63, 63, 63, 63, 63, 63, 63, + 63, nil, 63, 63, 63, nil, 63, 63, 63, 63, + 63, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 63, nil, nil, 63, nil, nil, 63, 63, nil, nil, + 63, nil, nil, nil, nil, nil, 63, nil, nil, nil, + nil, nil, nil, nil, nil, 63, nil, nil, nil, nil, + 63, 63, 63, 63, nil, 63, 63, 63, 63, nil, + nil, nil, nil, 63, 63, nil, nil, nil, 64, 64, + 64, 63, 64, 63, 63, 63, 64, 64, nil, nil, + nil, 64, nil, 64, 64, 64, 64, 64, 64, 64, + nil, nil, nil, nil, nil, 64, 64, 64, 64, 64, + 64, 64, nil, nil, 64, nil, nil, nil, nil, nil, + nil, 64, nil, nil, 64, 64, 64, 64, 64, 64, + 64, 64, nil, 64, 64, 64, nil, 64, 64, 64, + 64, 64, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 64, nil, nil, 64, nil, nil, 64, 64, nil, + nil, 64, nil, nil, nil, nil, nil, 64, nil, nil, + nil, nil, nil, nil, nil, nil, 64, nil, nil, nil, + nil, 64, 64, 64, 64, nil, 64, 64, 64, 64, + nil, nil, nil, nil, 64, 64, nil, nil, nil, 67, + 67, 67, 64, 67, 64, 64, 64, 67, 67, nil, + nil, nil, 67, nil, 67, 67, 67, 67, 67, 67, + 67, nil, nil, nil, nil, nil, 67, 67, 67, 67, + 67, 67, 67, nil, nil, 67, nil, nil, nil, nil, + nil, nil, 67, nil, nil, 67, 67, 67, 67, 67, + 67, 67, 67, nil, 67, 67, 67, nil, 67, 67, + 67, 67, 67, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 67, nil, nil, 67, nil, nil, 67, 67, + nil, nil, 67, nil, nil, nil, nil, nil, 67, nil, + nil, nil, nil, nil, nil, nil, nil, 67, nil, nil, + nil, nil, 67, 67, 67, 67, nil, 67, 67, 67, + 67, nil, nil, nil, nil, 67, 67, 67, nil, nil, + nil, nil, 67, 67, nil, 67, 67, 67, 68, 68, + 68, nil, 68, nil, nil, nil, 68, 68, nil, nil, + nil, 68, nil, 68, 68, 68, 68, 68, 68, 68, + nil, nil, nil, nil, nil, 68, 68, 68, 68, 68, + 68, 68, nil, nil, 68, nil, nil, nil, nil, nil, + nil, 68, nil, nil, 68, 68, 68, 68, 68, 68, + 68, 68, nil, 68, 68, 68, nil, 68, 68, nil, + nil, 68, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 68, nil, nil, 68, nil, nil, 68, 68, nil, + nil, 68, nil, 68, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 68, 68, 68, 68, nil, 68, 68, 68, 68, + nil, nil, nil, nil, 68, 68, nil, nil, nil, 69, + 69, 69, 68, 69, 68, 68, 68, 69, 69, nil, + nil, nil, 69, nil, 69, 69, 69, 69, 69, 69, + 69, nil, nil, nil, nil, nil, 69, 69, 69, 69, + 69, 69, 69, nil, nil, 69, nil, nil, nil, nil, + nil, nil, 69, nil, nil, 69, 69, 69, 69, 69, + 69, 69, 69, nil, 69, 69, 69, nil, 69, 69, + nil, nil, 69, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 69, + nil, nil, 69, nil, nil, 69, nil, nil, 69, 69, + nil, nil, 69, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 69, 69, 69, 69, nil, 69, 69, 69, + 69, nil, nil, nil, nil, 69, 69, nil, nil, nil, + 70, 70, 70, 69, 70, 69, 69, 69, 70, 70, + nil, nil, nil, 70, nil, 70, 70, 70, 70, 70, + 70, 70, nil, nil, nil, nil, nil, 70, 70, 70, + 70, 70, 70, 70, nil, nil, 70, nil, nil, nil, + nil, nil, nil, 70, nil, nil, 70, 70, 70, 70, + 70, 70, 70, 70, nil, 70, 70, 70, nil, 70, + 70, nil, nil, 70, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 70, nil, nil, 70, nil, nil, 70, + 70, nil, nil, 70, nil, nil, 845, nil, 845, 845, + 845, 845, 845, nil, nil, nil, nil, nil, nil, nil, + nil, 845, nil, 70, 70, 70, 70, nil, 70, 70, + 70, 70, nil, nil, nil, nil, 70, 70, nil, nil, + nil, nil, nil, 845, 70, nil, 70, 70, 70, 113, + 113, 113, 113, 113, 845, 845, nil, 113, 113, 845, + nil, nil, 113, nil, 113, 113, 113, 113, 113, 113, + 113, nil, nil, nil, nil, nil, 113, 113, 113, 113, + 113, 113, 113, nil, nil, 113, nil, nil, nil, nil, + nil, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, nil, 113, 113, 113, nil, 113, 113, + 113, 113, 113, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 113, nil, nil, 113, nil, nil, 113, 113, + nil, nil, 113, nil, 113, nil, nil, nil, 113, nil, + nil, nil, nil, nil, nil, nil, nil, 113, nil, nil, + nil, nil, 113, 113, 113, 113, nil, 113, 113, 113, + 113, nil, nil, nil, nil, 113, 113, nil, nil, nil, + nil, nil, 113, 113, nil, 113, 113, 113, 118, 118, + 118, nil, 118, nil, nil, nil, 118, 118, nil, nil, + nil, 118, nil, 118, 118, 118, 118, 118, 118, 118, + nil, nil, nil, nil, nil, 118, 118, 118, 118, 118, + 118, 118, nil, nil, 118, nil, nil, nil, nil, nil, + nil, 118, nil, nil, 118, 118, 118, 118, 118, 118, + 118, 118, nil, 118, 118, 118, nil, 118, 118, 118, + 118, 118, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 118, nil, nil, 118, nil, nil, 118, 118, nil, + nil, 118, nil, nil, nil, nil, nil, 118, nil, nil, + nil, nil, nil, nil, nil, nil, 118, nil, nil, nil, + nil, 118, 118, 118, 118, nil, 118, 118, 118, 118, + nil, nil, nil, nil, 118, 118, nil, nil, nil, 119, + 119, 119, 118, 119, 118, 118, 118, 119, 119, nil, + nil, nil, 119, nil, 119, 119, 119, 119, 119, 119, + 119, nil, nil, nil, nil, nil, 119, 119, 119, 119, + 119, 119, 119, nil, nil, 119, nil, nil, nil, nil, + nil, nil, 119, nil, nil, 119, 119, 119, 119, 119, + 119, 119, 119, nil, 119, 119, 119, nil, 119, 119, + 119, 119, 119, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 119, nil, nil, 119, nil, nil, 119, 119, + nil, nil, 119, nil, nil, nil, nil, nil, 119, nil, + nil, nil, nil, nil, nil, nil, nil, 119, nil, nil, + nil, nil, 119, 119, 119, 119, nil, 119, 119, 119, + 119, nil, nil, nil, nil, 119, 119, nil, nil, nil, + 120, 120, 120, 119, 120, 119, 119, 119, 120, 120, + nil, nil, nil, 120, nil, 120, 120, 120, 120, 120, + 120, 120, nil, nil, nil, nil, nil, 120, 120, 120, + 120, 120, 120, 120, nil, nil, 120, nil, nil, nil, + nil, nil, nil, 120, nil, nil, 120, 120, 120, 120, + 120, 120, 120, 120, nil, 120, 120, 120, nil, 120, + 120, 120, 120, 120, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 120, nil, nil, 120, nil, nil, 120, + 120, nil, nil, 120, nil, nil, nil, nil, nil, 120, + nil, nil, nil, nil, nil, nil, nil, nil, 120, nil, + nil, nil, nil, 120, 120, 120, 120, nil, 120, 120, + 120, 120, nil, nil, nil, nil, 120, 120, nil, nil, + nil, 121, 121, 121, 120, 121, 120, 120, 120, 121, + 121, nil, nil, nil, 121, nil, 121, 121, 121, 121, + 121, 121, 121, nil, nil, nil, nil, nil, 121, 121, + 121, 121, 121, 121, 121, nil, nil, 121, nil, nil, + nil, nil, nil, nil, 121, nil, nil, 121, 121, 121, + 121, 121, 121, 121, 121, nil, 121, 121, 121, nil, + 121, 121, 121, 121, 121, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 121, nil, nil, 121, nil, nil, + 121, 121, nil, nil, 121, nil, nil, nil, nil, nil, + 121, nil, nil, nil, nil, nil, nil, nil, nil, 121, + nil, nil, nil, nil, 121, 121, 121, 121, nil, 121, + 121, 121, 121, nil, nil, nil, nil, 121, 121, nil, + nil, nil, nil, nil, nil, 121, nil, 121, 121, 121, + 122, 122, 122, 122, 122, nil, nil, nil, 122, 122, + nil, nil, nil, 122, nil, 122, 122, 122, 122, 122, + 122, 122, nil, nil, nil, nil, nil, 122, 122, 122, + 122, 122, 122, 122, nil, nil, 122, nil, nil, nil, + nil, nil, 122, 122, nil, 122, 122, 122, 122, 122, + 122, 122, 122, 122, nil, 122, 122, 122, nil, 122, + 122, 122, 122, 122, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 122, nil, nil, 122, nil, nil, 122, + 122, nil, nil, 122, nil, 122, nil, nil, nil, 122, + nil, nil, nil, nil, nil, nil, nil, nil, 122, nil, + nil, nil, nil, 122, 122, 122, 122, nil, 122, 122, + 122, 122, nil, nil, nil, nil, 122, 122, nil, nil, + nil, 209, 209, 209, 122, 209, 122, 122, 122, 209, + 209, nil, nil, nil, 209, nil, 209, 209, 209, 209, + 209, 209, 209, nil, nil, nil, nil, nil, 209, 209, + 209, 209, 209, 209, 209, nil, nil, 209, nil, nil, + nil, nil, nil, nil, 209, nil, nil, 209, 209, 209, + 209, 209, 209, 209, 209, nil, 209, 209, 209, nil, + 209, 209, 209, 209, 209, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 209, nil, nil, 209, nil, nil, + 209, 209, nil, nil, 209, nil, 209, nil, nil, nil, + 209, nil, nil, nil, nil, nil, nil, nil, nil, 209, + nil, nil, nil, nil, 209, 209, 209, 209, nil, 209, + 209, 209, 209, nil, nil, nil, nil, 209, 209, nil, + nil, nil, 210, 210, 210, 209, 210, 209, 209, 209, + 210, 210, nil, nil, nil, 210, nil, 210, 210, 210, + 210, 210, 210, 210, nil, nil, nil, nil, nil, 210, + 210, 210, 210, 210, 210, 210, nil, nil, 210, nil, + nil, nil, nil, nil, nil, 210, nil, nil, 210, 210, + 210, 210, 210, 210, 210, 210, nil, 210, 210, 210, + nil, 210, 210, 210, 210, 210, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 210, nil, nil, 210, nil, + nil, 210, 210, nil, nil, 210, nil, nil, nil, nil, + nil, 210, nil, nil, nil, nil, nil, nil, nil, nil, + 210, nil, nil, nil, nil, 210, 210, 210, 210, nil, + 210, 210, 210, 210, nil, nil, nil, nil, 210, 210, + nil, nil, nil, 211, 211, 211, 210, 211, 210, 210, + 210, 211, 211, nil, nil, nil, 211, nil, 211, 211, + 211, 211, 211, 211, 211, nil, nil, nil, nil, nil, + 211, 211, 211, 211, 211, 211, 211, nil, nil, 211, + nil, nil, nil, nil, nil, nil, 211, nil, nil, 211, + 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, + 211, nil, 211, 211, 211, 211, 211, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 211, nil, nil, 211, + nil, nil, 211, 211, nil, nil, 211, nil, 211, nil, + 211, nil, 211, nil, nil, 211, nil, nil, nil, nil, + nil, 211, nil, nil, nil, nil, 211, 211, 211, 211, + nil, 211, 211, 211, 211, nil, nil, nil, nil, 211, + 211, nil, nil, nil, 214, 214, 214, 211, 214, 211, + 211, 211, 214, 214, nil, nil, nil, 214, nil, 214, + 214, 214, 214, 214, 214, 214, nil, nil, nil, nil, + nil, 214, 214, 214, 214, 214, 214, 214, nil, nil, + 214, nil, nil, nil, nil, nil, nil, 214, nil, nil, + 214, 214, 214, 214, 214, 214, 214, 214, nil, 214, + 214, 214, nil, 214, 214, 214, 214, 214, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 214, nil, nil, + 214, nil, nil, 214, 214, nil, nil, 214, nil, nil, + nil, nil, nil, 214, nil, nil, nil, nil, nil, nil, + nil, nil, 214, nil, nil, nil, nil, 214, 214, 214, + 214, nil, 214, 214, 214, 214, nil, nil, nil, nil, + 214, 214, nil, nil, nil, 215, 215, 215, 214, 215, + 214, 214, 214, 215, 215, nil, nil, nil, 215, nil, + 215, 215, 215, 215, 215, 215, 215, nil, nil, nil, + nil, nil, 215, 215, 215, 215, 215, 215, 215, nil, + nil, 215, nil, nil, nil, nil, nil, nil, 215, nil, + nil, 215, 215, 215, 215, 215, 215, 215, 215, nil, + 215, 215, 215, nil, 215, 215, 215, 215, 215, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 215, nil, + nil, 215, nil, nil, 215, 215, nil, nil, 215, nil, + 215, nil, nil, nil, 215, nil, nil, nil, nil, nil, + nil, nil, nil, 215, nil, nil, nil, nil, 215, 215, + 215, 215, nil, 215, 215, 215, 215, nil, nil, nil, + nil, 215, 215, nil, nil, nil, 216, 216, 216, 215, + 216, 215, 215, 215, 216, 216, nil, nil, nil, 216, + nil, 216, 216, 216, 216, 216, 216, 216, nil, nil, + nil, nil, nil, 216, 216, 216, 216, 216, 216, 216, + nil, nil, 216, nil, nil, nil, nil, nil, nil, 216, + nil, nil, 216, 216, 216, 216, 216, 216, 216, 216, + nil, 216, 216, 216, nil, 216, 216, 216, 216, 216, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 216, + nil, nil, 216, nil, nil, 216, 216, nil, nil, 216, + nil, nil, nil, nil, nil, 216, nil, nil, nil, nil, + nil, nil, nil, nil, 216, nil, nil, nil, nil, 216, + 216, 216, 216, nil, 216, 216, 216, 216, nil, nil, + nil, nil, 216, 216, nil, nil, nil, 217, 217, 217, + 216, 217, 216, 216, 216, 217, 217, nil, nil, nil, + 217, nil, 217, 217, 217, 217, 217, 217, 217, nil, + nil, nil, nil, nil, 217, 217, 217, 217, 217, 217, + 217, nil, nil, 217, nil, nil, nil, nil, nil, nil, + 217, nil, nil, 217, 217, 217, 217, 217, 217, 217, + 217, nil, 217, 217, 217, nil, 217, 217, 217, 217, + 217, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 217, nil, nil, 217, nil, nil, 217, 217, nil, nil, + 217, nil, nil, nil, nil, nil, 217, nil, nil, nil, + nil, nil, nil, nil, nil, 217, nil, nil, nil, nil, + 217, 217, 217, 217, nil, 217, 217, 217, 217, nil, + nil, nil, nil, 217, 217, nil, nil, nil, 218, 218, + 218, 217, 218, 217, 217, 217, 218, 218, nil, nil, + nil, 218, nil, 218, 218, 218, 218, 218, 218, 218, + nil, nil, nil, nil, nil, 218, 218, 218, 218, 218, + 218, 218, nil, nil, 218, nil, nil, nil, nil, nil, + nil, 218, nil, nil, 218, 218, 218, 218, 218, 218, + 218, 218, nil, 218, 218, 218, nil, 218, 218, 218, + 218, 218, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 218, nil, nil, 218, nil, nil, 218, 218, nil, + nil, 218, nil, nil, nil, nil, nil, 218, nil, nil, + nil, nil, nil, nil, nil, nil, 218, nil, nil, nil, + nil, 218, 218, 218, 218, nil, 218, 218, 218, 218, + nil, nil, nil, nil, 218, 218, nil, nil, nil, 219, + 219, 219, 218, 219, 218, 218, 218, 219, 219, nil, + nil, nil, 219, nil, 219, 219, 219, 219, 219, 219, + 219, nil, nil, nil, nil, nil, 219, 219, 219, 219, + 219, 219, 219, nil, nil, 219, nil, nil, nil, nil, + nil, nil, 219, nil, nil, 219, 219, 219, 219, 219, + 219, 219, 219, nil, 219, 219, 219, nil, 219, 219, + 219, 219, 219, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 219, nil, nil, 219, nil, nil, 219, 219, + nil, nil, 219, nil, nil, nil, nil, nil, 219, nil, + nil, nil, nil, nil, nil, nil, nil, 219, nil, nil, + nil, nil, 219, 219, 219, 219, nil, 219, 219, 219, + 219, nil, nil, nil, nil, 219, 219, 219, nil, nil, + 230, 230, 230, 219, 230, 219, 219, 219, 230, 230, + nil, nil, nil, 230, nil, 230, 230, 230, 230, 230, + 230, 230, nil, nil, nil, nil, nil, 230, 230, 230, + 230, 230, 230, 230, nil, nil, 230, nil, nil, nil, + nil, nil, nil, 230, nil, nil, 230, 230, 230, 230, + 230, 230, 230, 230, nil, 230, 230, 230, nil, 230, + 230, 230, 230, 230, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, 230, nil, nil, 230, + 230, nil, nil, 230, nil, nil, nil, nil, nil, 230, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, nil, nil, 230, 230, 230, 230, nil, 230, 230, + 230, 230, nil, nil, nil, nil, 230, 230, nil, nil, + nil, 233, 233, 233, 230, 233, 230, 230, 230, 233, + 233, nil, nil, nil, 233, nil, 233, 233, 233, 233, + 233, 233, 233, nil, nil, nil, nil, nil, 233, 233, + 233, 233, 233, 233, 233, nil, nil, 233, nil, nil, + nil, nil, nil, nil, 233, nil, nil, 233, 233, 233, + 233, 233, 233, 233, 233, nil, 233, 233, 233, nil, + 233, 233, 233, 233, 233, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 233, nil, nil, 233, nil, nil, + 233, 233, nil, nil, 233, nil, nil, nil, nil, nil, + 233, nil, nil, nil, nil, nil, nil, nil, nil, 233, + nil, nil, nil, nil, 233, 233, 233, 233, nil, 233, + 233, 233, 233, nil, nil, nil, nil, 233, 233, nil, + nil, nil, 234, 234, 234, 233, 234, 233, 233, 233, + 234, 234, nil, nil, nil, 234, nil, 234, 234, 234, + 234, 234, 234, 234, nil, nil, nil, nil, nil, 234, + 234, 234, 234, 234, 234, 234, nil, nil, 234, nil, + nil, nil, nil, nil, nil, 234, nil, nil, 234, 234, + 234, 234, 234, 234, 234, 234, nil, 234, 234, 234, + nil, 234, 234, 234, 234, 234, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 234, nil, nil, 234, nil, + nil, 234, 234, nil, nil, 234, nil, nil, nil, nil, + nil, 234, nil, nil, nil, nil, nil, nil, nil, nil, + 234, nil, nil, nil, nil, 234, 234, 234, 234, nil, + 234, 234, 234, 234, nil, nil, nil, nil, 234, 234, + nil, nil, nil, 235, 235, 235, 234, 235, 234, 234, + 234, 235, 235, nil, nil, nil, 235, nil, 235, 235, + 235, 235, 235, 235, 235, nil, nil, nil, nil, nil, + 235, 235, 235, 235, 235, 235, 235, nil, nil, 235, + nil, nil, nil, nil, nil, nil, 235, nil, nil, 235, + 235, 235, 235, 235, 235, 235, 235, nil, 235, 235, + 235, nil, 235, 235, 235, 235, 235, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 235, nil, nil, 235, + nil, nil, 235, 235, nil, nil, 235, nil, nil, nil, + nil, nil, 235, nil, nil, nil, nil, nil, nil, nil, + nil, 235, nil, nil, nil, nil, 235, 235, 235, 235, + nil, 235, 235, 235, 235, nil, nil, nil, nil, 235, + 235, nil, nil, nil, 236, 236, 236, 235, 236, 235, + 235, 235, 236, 236, nil, nil, nil, 236, nil, 236, + 236, 236, 236, 236, 236, 236, nil, nil, nil, nil, + nil, 236, 236, 236, 236, 236, 236, 236, nil, nil, + 236, nil, nil, nil, nil, nil, nil, 236, nil, nil, + 236, 236, 236, 236, 236, 236, 236, 236, nil, 236, + 236, 236, nil, 236, 236, 236, 236, 236, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 236, nil, nil, + 236, nil, nil, 236, 236, nil, nil, 236, nil, nil, + nil, nil, nil, 236, nil, nil, nil, nil, nil, nil, + nil, nil, 236, nil, nil, nil, nil, 236, 236, 236, + 236, nil, 236, 236, 236, 236, nil, nil, nil, nil, + 236, 236, nil, nil, nil, 237, 237, 237, 236, 237, + 236, 236, 236, 237, 237, nil, nil, nil, 237, nil, + 237, 237, 237, 237, 237, 237, 237, nil, nil, nil, + nil, nil, 237, 237, 237, 237, 237, 237, 237, nil, + nil, 237, nil, nil, nil, nil, nil, nil, 237, nil, + nil, 237, 237, 237, 237, 237, 237, 237, 237, nil, + 237, 237, 237, nil, 237, 237, 237, 237, 237, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 237, nil, + nil, 237, nil, nil, 237, 237, nil, nil, 237, nil, + nil, nil, nil, nil, 237, nil, nil, nil, nil, nil, + nil, nil, nil, 237, nil, nil, nil, nil, 237, 237, + 237, 237, nil, 237, 237, 237, 237, nil, nil, nil, + nil, 237, 237, nil, nil, nil, 238, 238, 238, 237, + 238, 237, 237, 237, 238, 238, nil, nil, nil, 238, + nil, 238, 238, 238, 238, 238, 238, 238, nil, nil, + nil, nil, nil, 238, 238, 238, 238, 238, 238, 238, + nil, nil, 238, nil, nil, nil, nil, nil, nil, 238, + nil, nil, 238, 238, 238, 238, 238, 238, 238, 238, + nil, 238, 238, 238, nil, 238, 238, 238, 238, 238, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 238, + nil, nil, 238, nil, nil, 238, 238, nil, nil, 238, + nil, nil, nil, nil, nil, 238, nil, nil, nil, nil, + nil, nil, nil, nil, 238, nil, nil, nil, nil, 238, + 238, 238, 238, nil, 238, 238, 238, 238, nil, nil, + nil, nil, 238, 238, nil, nil, nil, 239, 239, 239, + 238, 239, 238, 238, 238, 239, 239, nil, nil, nil, + 239, nil, 239, 239, 239, 239, 239, 239, 239, nil, + nil, nil, nil, nil, 239, 239, 239, 239, 239, 239, + 239, nil, nil, 239, nil, nil, nil, nil, nil, nil, + 239, nil, nil, 239, 239, 239, 239, 239, 239, 239, + 239, nil, 239, 239, 239, nil, 239, 239, 239, 239, + 239, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 239, nil, nil, 239, nil, nil, 239, 239, nil, nil, + 239, nil, nil, nil, nil, nil, 239, nil, nil, nil, + nil, nil, nil, nil, nil, 239, nil, nil, nil, nil, + 239, 239, 239, 239, nil, 239, 239, 239, 239, nil, + nil, nil, nil, 239, 239, nil, nil, nil, 240, 240, + 240, 239, 240, 239, 239, 239, 240, 240, nil, nil, + nil, 240, nil, 240, 240, 240, 240, 240, 240, 240, + nil, nil, nil, nil, nil, 240, 240, 240, 240, 240, + 240, 240, nil, nil, 240, nil, nil, nil, nil, nil, + nil, 240, nil, nil, 240, 240, 240, 240, 240, 240, + 240, 240, nil, 240, 240, 240, nil, 240, 240, 240, + 240, 240, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 240, nil, nil, 240, nil, nil, 240, 240, nil, + nil, 240, nil, nil, nil, nil, nil, 240, nil, nil, + nil, nil, nil, nil, nil, nil, 240, nil, nil, nil, + nil, 240, 240, 240, 240, nil, 240, 240, 240, 240, + nil, nil, nil, nil, 240, 240, nil, nil, nil, 241, + 241, 241, 240, 241, 240, 240, 240, 241, 241, nil, + nil, nil, 241, nil, 241, 241, 241, 241, 241, 241, + 241, nil, nil, nil, nil, nil, 241, 241, 241, 241, + 241, 241, 241, nil, nil, 241, nil, nil, nil, nil, + nil, nil, 241, nil, nil, 241, 241, 241, 241, 241, + 241, 241, 241, nil, 241, 241, 241, nil, 241, 241, + 241, 241, 241, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 241, nil, nil, 241, nil, nil, 241, 241, + nil, nil, 241, nil, nil, nil, nil, nil, 241, nil, + nil, nil, nil, nil, nil, nil, nil, 241, nil, nil, + nil, nil, 241, 241, 241, 241, nil, 241, 241, 241, + 241, nil, nil, nil, nil, 241, 241, nil, nil, nil, + 242, 242, 242, 241, 242, 241, 241, 241, 242, 242, + nil, nil, nil, 242, nil, 242, 242, 242, 242, 242, + 242, 242, nil, nil, nil, nil, nil, 242, 242, 242, + 242, 242, 242, 242, nil, nil, 242, nil, nil, nil, + nil, nil, nil, 242, nil, nil, 242, 242, 242, 242, + 242, 242, 242, 242, nil, 242, 242, 242, nil, 242, + 242, 242, 242, 242, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 242, nil, nil, 242, nil, nil, 242, + 242, nil, nil, 242, nil, nil, nil, nil, nil, 242, + nil, nil, nil, nil, nil, nil, nil, nil, 242, nil, + nil, nil, nil, 242, 242, 242, 242, nil, 242, 242, + 242, 242, nil, nil, nil, nil, 242, 242, nil, nil, + nil, 243, 243, 243, 242, 243, 242, 242, 242, 243, + 243, nil, nil, nil, 243, nil, 243, 243, 243, 243, + 243, 243, 243, nil, nil, nil, nil, nil, 243, 243, + 243, 243, 243, 243, 243, nil, nil, 243, nil, nil, + nil, nil, nil, nil, 243, nil, nil, 243, 243, 243, + 243, 243, 243, 243, 243, nil, 243, 243, 243, nil, + 243, 243, 243, 243, 243, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 243, nil, nil, 243, nil, nil, + 243, 243, nil, nil, 243, nil, nil, nil, nil, nil, + 243, nil, nil, nil, nil, nil, nil, nil, nil, 243, + nil, nil, nil, nil, 243, 243, 243, 243, nil, 243, + 243, 243, 243, nil, nil, nil, nil, 243, 243, nil, + nil, nil, 244, 244, 244, 243, 244, 243, 243, 243, + 244, 244, nil, nil, nil, 244, nil, 244, 244, 244, + 244, 244, 244, 244, nil, nil, nil, nil, nil, 244, + 244, 244, 244, 244, 244, 244, nil, nil, 244, nil, + nil, nil, nil, nil, nil, 244, nil, nil, 244, 244, + 244, 244, 244, 244, 244, 244, nil, 244, 244, 244, + nil, 244, 244, 244, 244, 244, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 244, nil, nil, 244, nil, + nil, 244, 244, nil, nil, 244, nil, nil, nil, nil, + nil, 244, nil, nil, nil, nil, nil, nil, nil, nil, + 244, nil, nil, nil, nil, 244, 244, 244, 244, nil, + 244, 244, 244, 244, nil, nil, nil, nil, 244, 244, + nil, nil, nil, 245, 245, 245, 244, 245, 244, 244, + 244, 245, 245, nil, nil, nil, 245, nil, 245, 245, + 245, 245, 245, 245, 245, nil, nil, nil, nil, nil, + 245, 245, 245, 245, 245, 245, 245, nil, nil, 245, + nil, nil, nil, nil, nil, nil, 245, nil, nil, 245, + 245, 245, 245, 245, 245, 245, 245, nil, 245, 245, + 245, nil, 245, 245, 245, 245, 245, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 245, nil, nil, 245, + nil, nil, 245, 245, nil, nil, 245, nil, nil, nil, + nil, nil, 245, nil, nil, nil, nil, nil, nil, nil, + nil, 245, nil, nil, nil, nil, 245, 245, 245, 245, + nil, 245, 245, 245, 245, nil, nil, nil, nil, 245, + 245, nil, nil, nil, 246, 246, 246, 245, 246, 245, + 245, 245, 246, 246, nil, nil, nil, 246, nil, 246, + 246, 246, 246, 246, 246, 246, nil, nil, nil, nil, + nil, 246, 246, 246, 246, 246, 246, 246, nil, nil, + 246, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 246, 246, 246, 246, 246, 246, 246, 246, nil, 246, + 246, 246, nil, 246, 246, 246, 246, 246, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 246, nil, nil, 246, 246, nil, nil, 246, nil, nil, + nil, nil, nil, 246, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, nil, nil, 246, 246, 246, + 246, nil, 246, 246, 246, 246, nil, nil, nil, nil, + 246, 246, nil, nil, nil, 247, 247, 247, 246, 247, + 246, 246, 246, 247, 247, nil, nil, nil, 247, nil, + 247, 247, 247, 247, 247, 247, 247, nil, nil, nil, + nil, nil, 247, 247, 247, 247, 247, 247, 247, nil, + nil, 247, nil, nil, nil, nil, nil, nil, 247, nil, + nil, 247, 247, 247, 247, 247, 247, 247, 247, nil, + 247, 247, 247, nil, 247, 247, 247, 247, 247, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 247, nil, + nil, 247, nil, nil, 247, 247, nil, nil, 247, nil, + nil, nil, nil, nil, 247, nil, nil, nil, nil, nil, + nil, nil, nil, 247, nil, nil, nil, nil, 247, 247, + 247, 247, nil, 247, 247, 247, 247, nil, nil, nil, + nil, 247, 247, nil, nil, nil, 248, 248, 248, 247, + 248, 247, 247, 247, 248, 248, nil, nil, nil, 248, + nil, 248, 248, 248, 248, 248, 248, 248, nil, nil, + nil, nil, nil, 248, 248, 248, 248, 248, 248, 248, + nil, nil, 248, nil, nil, nil, nil, nil, nil, 248, + nil, nil, 248, 248, 248, 248, 248, 248, 248, 248, + nil, 248, 248, 248, nil, 248, 248, 248, 248, 248, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 248, + nil, nil, 248, nil, nil, 248, 248, nil, nil, 248, + nil, nil, nil, nil, nil, 248, nil, nil, nil, nil, + nil, nil, nil, nil, 248, nil, nil, nil, nil, 248, + 248, 248, 248, nil, 248, 248, 248, 248, nil, nil, + nil, nil, 248, 248, nil, nil, nil, 249, 249, 249, + 248, 249, 248, 248, 248, 249, 249, nil, nil, nil, + 249, nil, 249, 249, 249, 249, 249, 249, 249, nil, + nil, nil, nil, nil, 249, 249, 249, 249, 249, 249, + 249, nil, nil, 249, nil, nil, nil, nil, nil, nil, + 249, nil, nil, 249, 249, 249, 249, 249, 249, 249, + 249, nil, 249, 249, 249, nil, 249, 249, 249, 249, + 249, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 249, nil, nil, 249, nil, nil, 249, 249, nil, nil, + 249, nil, nil, nil, nil, nil, 249, nil, nil, nil, + nil, nil, nil, nil, nil, 249, nil, nil, nil, nil, + 249, 249, 249, 249, nil, 249, 249, 249, 249, nil, + nil, nil, nil, 249, 249, nil, nil, nil, 250, 250, + 250, 249, 250, 249, 249, 249, 250, 250, nil, nil, + nil, 250, nil, 250, 250, 250, 250, 250, 250, 250, + nil, nil, nil, nil, nil, 250, 250, 250, 250, 250, + 250, 250, nil, nil, 250, nil, nil, nil, nil, nil, + nil, 250, nil, nil, 250, 250, 250, 250, 250, 250, + 250, 250, nil, 250, 250, 250, nil, 250, 250, 250, + 250, 250, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 250, nil, nil, 250, nil, nil, 250, 250, nil, + nil, 250, nil, nil, nil, nil, nil, 250, nil, nil, + nil, nil, nil, nil, nil, nil, 250, nil, nil, nil, + nil, 250, 250, 250, 250, nil, 250, 250, 250, 250, + nil, nil, nil, nil, 250, 250, nil, nil, nil, 251, + 251, 251, 250, 251, 250, 250, 250, 251, 251, nil, + nil, nil, 251, nil, 251, 251, 251, 251, 251, 251, + 251, nil, nil, nil, nil, nil, 251, 251, 251, 251, + 251, 251, 251, nil, nil, 251, nil, nil, nil, nil, + nil, nil, 251, nil, nil, 251, 251, 251, 251, 251, + 251, 251, 251, nil, 251, 251, 251, nil, 251, 251, + 251, 251, 251, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, 251, nil, nil, 251, 251, + nil, nil, 251, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 251, 251, 251, 251, nil, 251, 251, 251, + 251, nil, nil, nil, nil, 251, 251, nil, nil, nil, + 252, 252, 252, 251, 252, 251, 251, 251, 252, 252, + nil, nil, nil, 252, nil, 252, 252, 252, 252, 252, + 252, 252, nil, nil, nil, nil, nil, 252, 252, 252, + 252, 252, 252, 252, nil, nil, 252, nil, nil, nil, + nil, nil, nil, 252, nil, nil, 252, 252, 252, 252, + 252, 252, 252, 252, nil, 252, 252, 252, nil, 252, + 252, 252, 252, 252, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 252, nil, nil, 252, nil, nil, 252, + 252, nil, nil, 252, nil, nil, nil, nil, nil, 252, + nil, nil, nil, nil, nil, nil, nil, nil, 252, nil, + nil, nil, nil, 252, 252, 252, 252, nil, 252, 252, + 252, 252, nil, nil, nil, nil, 252, 252, nil, nil, + nil, 253, 253, 253, 252, 253, 252, 252, 252, 253, + 253, nil, nil, nil, 253, nil, 253, 253, 253, 253, + 253, 253, 253, nil, nil, nil, nil, nil, 253, 253, + 253, 253, 253, 253, 253, nil, nil, 253, nil, nil, + nil, nil, nil, nil, 253, nil, nil, 253, 253, 253, + 253, 253, 253, 253, 253, nil, 253, 253, 253, nil, + 253, 253, 253, 253, 253, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 253, nil, nil, 253, nil, nil, + 253, 253, nil, nil, 253, nil, nil, nil, nil, nil, + 253, nil, nil, nil, nil, nil, nil, nil, nil, 253, + nil, nil, nil, nil, 253, 253, 253, 253, nil, 253, + 253, 253, 253, nil, nil, nil, nil, 253, 253, nil, + nil, nil, 254, 254, 254, 253, 254, 253, 253, 253, + 254, 254, nil, nil, nil, 254, nil, 254, 254, 254, + 254, 254, 254, 254, nil, nil, nil, nil, nil, 254, + 254, 254, 254, 254, 254, 254, nil, nil, 254, nil, + nil, nil, nil, nil, nil, 254, nil, nil, 254, 254, + 254, 254, 254, 254, 254, 254, nil, 254, 254, 254, + nil, 254, 254, 254, 254, 254, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 254, nil, nil, 254, nil, + nil, 254, 254, nil, nil, 254, nil, nil, nil, nil, + nil, 254, nil, nil, nil, nil, nil, nil, nil, nil, + 254, nil, nil, nil, nil, 254, 254, 254, 254, nil, + 254, 254, 254, 254, nil, nil, nil, nil, 254, 254, + nil, nil, nil, 255, 255, 255, 254, 255, 254, 254, + 254, 255, 255, nil, nil, nil, 255, nil, 255, 255, + 255, 255, 255, 255, 255, nil, nil, nil, nil, nil, + 255, 255, 255, 255, 255, 255, 255, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 255, nil, nil, 255, + 255, 255, 255, 255, 255, 255, 255, nil, 255, 255, + 255, nil, 255, 255, 255, 255, 255, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 255, nil, nil, 255, + nil, nil, 255, 255, nil, nil, 255, nil, nil, nil, + nil, nil, 255, nil, nil, nil, nil, nil, nil, nil, + nil, 255, nil, nil, nil, nil, 255, 255, 255, 255, + nil, 255, 255, 255, 255, nil, nil, nil, nil, 255, + 255, nil, nil, nil, 256, 256, 256, 255, 256, 255, + 255, 255, 256, 256, nil, nil, nil, 256, nil, 256, + 256, 256, 256, 256, 256, 256, nil, nil, nil, nil, + nil, 256, 256, 256, 256, 256, 256, 256, nil, nil, + 256, nil, nil, nil, nil, nil, nil, 256, nil, nil, + 256, 256, 256, 256, 256, 256, 256, 256, nil, 256, + 256, 256, nil, 256, 256, 256, 256, 256, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 256, nil, nil, + 256, nil, nil, 256, 256, nil, nil, 256, nil, nil, + nil, nil, nil, 256, nil, nil, nil, nil, nil, nil, + nil, nil, 256, nil, nil, nil, nil, 256, 256, 256, + 256, nil, 256, 256, 256, 256, nil, nil, nil, nil, + 256, 256, nil, nil, nil, 257, 257, 257, 256, 257, + 256, 256, 256, 257, 257, nil, nil, nil, 257, nil, + 257, 257, 257, 257, 257, 257, 257, nil, nil, nil, + nil, nil, 257, 257, 257, 257, 257, 257, 257, nil, + nil, 257, nil, nil, nil, nil, nil, nil, 257, nil, + nil, 257, 257, 257, 257, 257, 257, 257, 257, nil, + 257, 257, 257, nil, 257, 257, 257, 257, 257, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 257, nil, + nil, 257, nil, nil, 257, 257, nil, nil, 257, nil, + nil, nil, nil, nil, 257, nil, nil, nil, nil, nil, + nil, nil, nil, 257, nil, nil, nil, nil, 257, 257, + 257, 257, nil, 257, 257, 257, 257, nil, nil, nil, + nil, 257, 257, nil, nil, nil, 258, 258, 258, 257, + 258, 257, 257, 257, 258, 258, nil, nil, nil, 258, + nil, 258, 258, 258, 258, 258, 258, 258, nil, nil, + nil, nil, nil, 258, 258, 258, 258, 258, 258, 258, + nil, nil, 258, nil, nil, nil, nil, nil, nil, 258, + nil, nil, 258, 258, 258, 258, 258, 258, 258, 258, + nil, 258, 258, 258, nil, 258, 258, 258, 258, 258, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 258, + nil, nil, 258, nil, nil, 258, 258, nil, nil, 258, + nil, nil, nil, nil, nil, 258, nil, nil, nil, nil, + nil, nil, nil, nil, 258, nil, nil, nil, nil, 258, + 258, 258, 258, nil, 258, 258, 258, 258, nil, nil, + nil, nil, 258, 258, nil, nil, nil, 265, 265, 265, + 258, 265, 258, 258, 258, 265, 265, nil, nil, nil, + 265, nil, 265, 265, 265, 265, 265, 265, 265, nil, + nil, nil, nil, nil, 265, 265, 265, 265, 265, 265, + 265, nil, nil, 265, nil, nil, nil, nil, nil, nil, + 265, nil, nil, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, 265, 265, nil, 265, 265, 265, 265, + 265, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 265, nil, nil, 265, nil, nil, 265, 265, nil, nil, + 265, nil, 265, nil, 265, nil, 265, nil, nil, 265, + nil, nil, nil, nil, nil, 265, nil, nil, nil, nil, + 265, 265, 265, 265, nil, 265, 265, 265, 265, nil, + nil, nil, nil, 265, 265, nil, nil, nil, 266, 266, + 266, 265, 266, 265, 265, 265, 266, 266, nil, nil, + nil, 266, nil, 266, 266, 266, 266, 266, 266, 266, + nil, nil, nil, nil, nil, 266, 266, 266, 266, 266, + 266, 266, nil, nil, 266, nil, nil, nil, nil, nil, + nil, 266, nil, nil, 266, 266, 266, 266, 266, 266, + 266, 266, 266, 266, 266, 266, nil, 266, 266, 266, + 266, 266, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 266, nil, nil, 266, nil, nil, 266, 266, nil, + nil, 266, nil, 266, nil, 266, nil, 266, nil, nil, + 266, nil, nil, nil, nil, nil, 266, nil, nil, nil, + nil, 266, 266, 266, 266, nil, 266, 266, 266, 266, + nil, nil, nil, nil, 266, 266, nil, nil, nil, 274, + 274, 274, 266, 274, 266, 266, 266, 274, 274, nil, + nil, nil, 274, nil, 274, 274, 274, 274, 274, 274, + 274, nil, nil, nil, nil, nil, 274, 274, 274, 274, + 274, 274, 274, nil, nil, 274, nil, nil, nil, nil, + nil, nil, 274, nil, nil, 274, 274, 274, 274, 274, + 274, 274, 274, 274, 274, 274, 274, nil, 274, 274, + 274, 274, 274, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 274, nil, nil, 274, nil, nil, 274, 274, + nil, nil, 274, nil, 274, nil, 274, nil, 274, nil, + nil, 274, nil, nil, nil, nil, nil, 274, nil, nil, + nil, nil, 274, 274, 274, 274, nil, 274, 274, 274, + 274, nil, nil, nil, nil, 274, 274, 274, nil, nil, + 281, 281, 281, 274, 281, 274, 274, 274, 281, 281, + nil, nil, nil, 281, nil, 281, 281, 281, 281, 281, + 281, 281, nil, nil, nil, nil, nil, 281, 281, 281, + 281, 281, 281, 281, nil, nil, 281, nil, nil, nil, + nil, nil, nil, 281, nil, nil, 281, 281, 281, 281, + 281, 281, 281, 281, nil, 281, 281, 281, nil, 281, + 281, 281, 281, 281, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 281, nil, nil, 281, nil, nil, 281, + 281, nil, nil, 281, nil, nil, nil, nil, nil, 281, + nil, nil, nil, nil, nil, nil, nil, nil, 281, nil, + nil, nil, nil, 281, 281, 281, 281, nil, 281, 281, + 281, 281, nil, nil, nil, nil, 281, 281, nil, nil, + nil, 283, 283, 283, 281, 283, 281, 281, 281, 283, + 283, nil, nil, nil, 283, nil, 283, 283, 283, 283, + 283, 283, 283, nil, nil, nil, nil, nil, 283, 283, + 283, 283, 283, 283, 283, nil, nil, 283, nil, nil, + nil, nil, nil, nil, 283, nil, nil, 283, 283, 283, + 283, 283, 283, 283, 283, nil, 283, 283, 283, nil, + 283, 283, 283, 283, 283, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 283, nil, nil, 283, nil, nil, + 283, 283, nil, nil, 283, nil, nil, nil, nil, nil, + 283, nil, nil, nil, nil, nil, nil, nil, nil, 283, + nil, nil, nil, nil, 283, 283, 283, 283, nil, 283, + 283, 283, 283, nil, nil, nil, nil, 283, 283, nil, + nil, nil, 285, 285, 285, 283, 285, 283, 283, 283, + 285, 285, nil, nil, nil, 285, nil, 285, 285, 285, + 285, 285, 285, 285, nil, nil, nil, nil, nil, 285, + 285, 285, 285, 285, 285, 285, nil, nil, 285, nil, + nil, nil, nil, nil, nil, 285, nil, nil, 285, 285, + 285, 285, 285, 285, 285, 285, nil, 285, 285, 285, + nil, 285, 285, 285, 285, 285, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 285, nil, nil, 285, nil, + nil, 285, 285, nil, nil, 285, nil, nil, nil, nil, + nil, 285, nil, nil, nil, nil, nil, nil, nil, nil, + 285, nil, nil, nil, nil, 285, 285, 285, 285, nil, + 285, 285, 285, 285, nil, nil, nil, nil, 285, 285, + nil, nil, nil, 286, 286, 286, 285, 286, 285, 285, + 285, 286, 286, nil, nil, nil, 286, nil, 286, 286, + 286, 286, 286, 286, 286, nil, nil, nil, nil, nil, + 286, 286, 286, 286, 286, 286, 286, nil, nil, 286, + nil, nil, nil, nil, nil, nil, 286, nil, nil, 286, + 286, 286, 286, 286, 286, 286, 286, nil, 286, 286, + 286, nil, 286, 286, 286, 286, 286, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 286, nil, nil, 286, + nil, nil, 286, 286, nil, nil, 286, nil, nil, nil, + nil, nil, 286, nil, nil, nil, nil, nil, nil, nil, + nil, 286, nil, nil, nil, nil, 286, 286, 286, 286, + nil, 286, 286, 286, 286, nil, nil, nil, nil, 286, + 286, nil, nil, nil, nil, nil, nil, 286, nil, 286, + 286, 286, 291, 291, 291, 291, 291, nil, nil, nil, + 291, 291, nil, nil, nil, 291, nil, 291, 291, 291, + 291, 291, 291, 291, nil, nil, nil, nil, nil, 291, + 291, 291, 291, 291, 291, 291, nil, nil, 291, nil, + nil, nil, nil, nil, 291, 291, nil, 291, 291, 291, + 291, 291, 291, 291, 291, 291, nil, 291, 291, 291, + nil, 291, 291, 291, 291, 291, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 291, nil, nil, 291, nil, + nil, 291, 291, nil, nil, 291, nil, 291, nil, nil, + nil, 291, nil, nil, nil, nil, nil, nil, nil, nil, + 291, nil, nil, nil, nil, 291, 291, 291, 291, nil, + 291, 291, 291, 291, nil, nil, nil, nil, 291, 291, + nil, nil, nil, 299, 299, 299, 291, 299, 291, 291, + 291, 299, 299, nil, nil, nil, 299, nil, 299, 299, + 299, 299, 299, 299, 299, nil, nil, nil, nil, nil, + 299, 299, 299, 299, 299, 299, 299, nil, nil, 299, + nil, nil, nil, nil, nil, nil, 299, nil, nil, 299, + 299, 299, 299, 299, 299, 299, 299, nil, 299, 299, + 299, nil, 299, 299, nil, nil, 299, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 299, nil, nil, 299, + nil, nil, 299, 299, nil, nil, 299, nil, nil, 935, + nil, 935, 935, 935, 935, 935, nil, nil, nil, nil, + nil, nil, nil, nil, 935, nil, 299, 299, 299, 299, + nil, 299, 299, 299, 299, nil, nil, nil, nil, 299, + 299, nil, nil, nil, 299, nil, 935, 299, nil, 299, + 299, 299, 316, 316, 316, nil, 316, 935, 935, nil, + 316, 316, 935, nil, nil, 316, nil, 316, 316, 316, + 316, 316, 316, 316, nil, nil, nil, nil, nil, 316, + 316, 316, 316, 316, 316, 316, nil, nil, 316, nil, + nil, nil, nil, nil, nil, 316, nil, nil, 316, 316, + 316, 316, 316, 316, 316, 316, nil, 316, 316, 316, + nil, 316, 316, nil, nil, 316, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 316, nil, nil, 316, nil, + nil, 316, 316, nil, nil, 316, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 316, 316, 316, 316, nil, + 316, 316, 316, 316, nil, nil, nil, nil, 316, 316, + nil, nil, nil, 324, 324, 324, 316, 324, 316, 316, + 316, 324, 324, nil, nil, nil, 324, nil, 324, 324, + 324, 324, 324, 324, 324, nil, nil, nil, nil, nil, + 324, 324, 324, 324, 324, 324, 324, nil, nil, 324, + nil, nil, nil, nil, nil, nil, 324, nil, nil, 324, + 324, 324, 324, 324, 324, 324, 324, nil, 324, 324, + 324, nil, 324, 324, 324, 324, 324, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 324, nil, nil, 324, + 324, nil, 324, 324, nil, nil, 324, nil, nil, nil, + nil, nil, 324, nil, nil, nil, nil, nil, nil, nil, + nil, 324, nil, nil, nil, nil, 324, 324, 324, 324, + nil, 324, 324, 324, 324, nil, nil, nil, nil, 324, + 324, nil, nil, nil, 326, 326, 326, 324, 326, 324, + 324, 324, 326, 326, nil, nil, nil, 326, nil, 326, + 326, 326, 326, 326, 326, 326, nil, nil, nil, nil, + nil, 326, 326, 326, 326, 326, 326, 326, nil, nil, + 326, nil, nil, nil, nil, nil, nil, 326, nil, nil, + 326, 326, 326, 326, 326, 326, 326, 326, nil, 326, + 326, 326, nil, 326, 326, 326, 326, 326, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 326, nil, nil, + 326, nil, nil, 326, 326, nil, nil, 326, nil, nil, + nil, nil, nil, 326, nil, nil, nil, nil, nil, nil, + nil, nil, 326, nil, nil, nil, nil, 326, 326, 326, + 326, nil, 326, 326, 326, 326, nil, nil, nil, nil, + 326, 326, nil, nil, nil, 340, 340, 340, 326, 340, + 326, 326, 326, 340, 340, nil, nil, nil, 340, nil, + 340, 340, 340, 340, 340, 340, 340, nil, nil, nil, + nil, nil, 340, 340, 340, 340, 340, 340, 340, nil, + nil, 340, nil, nil, nil, nil, nil, nil, 340, nil, + nil, 340, 340, 340, 340, 340, 340, 340, 340, nil, + 340, 340, 340, nil, 340, 340, 340, 340, 340, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 340, nil, + nil, 340, nil, nil, 340, 340, nil, nil, 340, nil, + nil, nil, nil, nil, 340, nil, nil, nil, nil, nil, + nil, nil, nil, 340, nil, nil, nil, nil, 340, 340, + 340, 340, nil, 340, 340, 340, 340, nil, nil, nil, + nil, 340, 340, nil, nil, nil, 341, 341, 341, 340, + 341, 340, 340, 340, 341, 341, nil, nil, nil, 341, + nil, 341, 341, 341, 341, 341, 341, 341, nil, nil, + nil, nil, nil, 341, 341, 341, 341, 341, 341, 341, + nil, nil, 341, nil, nil, nil, nil, nil, nil, 341, + nil, nil, 341, 341, 341, 341, 341, 341, 341, 341, + nil, 341, 341, 341, nil, 341, 341, 341, 341, 341, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 341, + nil, nil, 341, nil, nil, 341, 341, nil, nil, 341, + nil, nil, nil, nil, nil, 341, nil, nil, nil, nil, + nil, nil, nil, nil, 341, nil, nil, nil, nil, 341, + 341, 341, 341, nil, 341, 341, 341, 341, nil, nil, + nil, nil, 341, 341, nil, nil, nil, 360, 360, 360, + 341, 360, 341, 341, 341, 360, 360, nil, nil, nil, + 360, nil, 360, 360, 360, 360, 360, 360, 360, nil, + nil, nil, nil, nil, 360, 360, 360, 360, 360, 360, + 360, nil, nil, 360, nil, nil, nil, nil, nil, nil, + 360, nil, nil, 360, 360, 360, 360, 360, 360, 360, + 360, nil, 360, 360, 360, nil, 360, 360, 360, 360, + 360, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 360, nil, nil, 360, nil, nil, 360, 360, nil, nil, + 360, nil, nil, nil, nil, nil, 360, nil, nil, nil, + nil, nil, nil, nil, nil, 360, nil, nil, nil, nil, + 360, 360, 360, 360, nil, 360, 360, 360, 360, nil, + nil, nil, nil, 360, 360, nil, nil, nil, 376, 376, + 376, 360, 376, 360, 360, 360, 376, 376, nil, nil, + nil, 376, nil, 376, 376, 376, 376, 376, 376, 376, + nil, nil, nil, nil, nil, 376, 376, 376, 376, 376, + 376, 376, nil, nil, 376, nil, nil, nil, nil, nil, + nil, 376, nil, nil, 376, 376, 376, 376, 376, 376, + 376, 376, nil, 376, 376, 376, nil, 376, 376, 376, + 376, 376, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 376, nil, nil, 376, nil, nil, 376, 376, nil, + nil, 376, nil, nil, nil, nil, nil, 376, nil, nil, + nil, nil, nil, nil, nil, nil, 376, nil, nil, nil, + nil, 376, 376, 376, 376, nil, 376, 376, 376, 376, + nil, nil, nil, nil, 376, 376, nil, nil, nil, 404, + 404, 404, 376, 404, 376, 376, 376, 404, 404, nil, + nil, nil, 404, nil, 404, 404, 404, 404, 404, 404, + 404, nil, nil, nil, nil, nil, 404, 404, 404, 404, + 404, 404, 404, nil, nil, 404, nil, nil, nil, nil, + nil, nil, 404, nil, nil, 404, 404, 404, 404, 404, + 404, 404, 404, nil, 404, 404, 404, nil, 404, 404, + 404, 404, 404, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 404, nil, nil, 404, nil, nil, 404, 404, + nil, nil, 404, nil, nil, nil, nil, nil, 404, nil, + nil, nil, nil, nil, nil, nil, nil, 404, nil, nil, + nil, nil, 404, 404, 404, 404, nil, 404, 404, 404, + 404, nil, nil, nil, nil, 404, 404, nil, nil, nil, + 442, 442, 442, 404, 442, 404, 404, 404, 442, 442, + nil, nil, nil, 442, nil, 442, 442, 442, 442, 442, + 442, 442, nil, nil, nil, nil, nil, 442, 442, 442, + 442, 442, 442, 442, nil, nil, 442, nil, nil, nil, + nil, nil, nil, 442, nil, nil, 442, 442, 442, 442, + 442, 442, 442, 442, 442, 442, 442, 442, nil, 442, + 442, 442, 442, 442, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 442, nil, nil, 442, nil, nil, 442, + 442, nil, nil, 442, nil, 442, nil, 442, nil, 442, + nil, nil, 442, nil, nil, nil, nil, nil, 442, nil, + nil, nil, nil, 442, 442, 442, 442, nil, 442, 442, + 442, 442, nil, nil, nil, nil, 442, 442, nil, nil, + nil, 444, 444, 444, 442, 444, 442, 442, 442, 444, + 444, nil, nil, nil, 444, nil, 444, 444, 444, 444, + 444, 444, 444, nil, nil, nil, nil, nil, 444, 444, + 444, 444, 444, 444, 444, nil, nil, 444, nil, nil, + nil, nil, nil, nil, 444, nil, nil, 444, 444, 444, + 444, 444, 444, 444, 444, nil, 444, 444, 444, nil, + 444, 444, 444, 444, 444, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 444, nil, nil, 444, nil, nil, + 444, 444, nil, nil, 444, nil, nil, nil, nil, nil, + 444, nil, nil, nil, nil, nil, nil, nil, nil, 444, + nil, nil, nil, nil, 444, 444, 444, 444, nil, 444, + 444, 444, 444, nil, nil, nil, nil, 444, 444, nil, + nil, nil, 445, 445, 445, 444, 445, 444, 444, 444, + 445, 445, nil, nil, nil, 445, nil, 445, 445, 445, + 445, 445, 445, 445, nil, nil, nil, nil, nil, 445, + 445, 445, 445, 445, 445, 445, nil, nil, 445, nil, + nil, nil, nil, nil, nil, 445, nil, nil, 445, 445, + 445, 445, 445, 445, 445, 445, nil, 445, 445, 445, + nil, 445, 445, 445, 445, 445, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 445, nil, nil, 445, nil, + nil, 445, 445, nil, nil, 445, nil, nil, nil, nil, + nil, 445, nil, nil, nil, nil, nil, nil, nil, nil, + 445, nil, nil, nil, nil, 445, 445, 445, 445, nil, + 445, 445, 445, 445, nil, nil, nil, nil, 445, 445, + nil, nil, nil, 446, 446, 446, 445, 446, 445, 445, + 445, 446, 446, nil, nil, nil, 446, nil, 446, 446, + 446, 446, 446, 446, 446, nil, nil, nil, nil, nil, + 446, 446, 446, 446, 446, 446, 446, nil, nil, 446, + nil, nil, nil, nil, nil, nil, 446, nil, nil, 446, + 446, 446, 446, 446, 446, 446, 446, nil, 446, 446, + 446, nil, 446, 446, 446, 446, 446, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 446, nil, nil, 446, + nil, nil, 446, 446, nil, nil, 446, nil, nil, nil, + nil, nil, 446, nil, nil, nil, nil, nil, nil, nil, + nil, 446, nil, nil, nil, nil, 446, 446, 446, 446, + nil, 446, 446, 446, 446, nil, nil, nil, nil, 446, + 446, nil, nil, nil, 486, 486, 486, 446, 486, 446, + 446, 446, 486, 486, nil, nil, nil, 486, nil, 486, + 486, 486, 486, 486, 486, 486, nil, nil, nil, nil, + nil, 486, 486, 486, 486, 486, 486, 486, nil, nil, + 486, nil, nil, nil, nil, nil, nil, 486, nil, nil, + 486, 486, 486, 486, 486, 486, 486, 486, 486, 486, + 486, 486, nil, 486, 486, 486, 486, 486, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 486, nil, nil, + 486, nil, nil, 486, 486, nil, nil, 486, nil, 486, + nil, 486, nil, 486, nil, nil, 486, nil, nil, nil, + nil, nil, 486, nil, nil, nil, nil, 486, 486, 486, + 486, nil, 486, 486, 486, 486, nil, nil, nil, nil, + 486, 486, nil, nil, nil, 488, 488, 488, 486, 488, + 486, 486, 486, 488, 488, nil, nil, nil, 488, nil, + 488, 488, 488, 488, 488, 488, 488, nil, nil, nil, + nil, nil, 488, 488, 488, 488, 488, 488, 488, nil, + nil, 488, nil, nil, nil, nil, nil, nil, 488, nil, + nil, 488, 488, 488, 488, 488, 488, 488, 488, 488, + 488, 488, 488, nil, 488, 488, 488, 488, 488, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 488, nil, + nil, 488, nil, nil, 488, 488, nil, nil, 488, nil, + nil, nil, 488, nil, 488, nil, nil, 488, nil, nil, + nil, nil, nil, 488, nil, nil, nil, nil, 488, 488, + 488, 488, nil, 488, 488, 488, 488, nil, nil, nil, + nil, 488, 488, nil, nil, nil, 490, 490, 490, 488, + 490, 488, 488, 488, 490, 490, nil, nil, nil, 490, + nil, 490, 490, 490, 490, 490, 490, 490, nil, nil, + nil, nil, nil, 490, 490, 490, 490, 490, 490, 490, + nil, nil, 490, nil, nil, nil, nil, nil, nil, 490, + nil, nil, 490, 490, 490, 490, 490, 490, 490, 490, + nil, 490, 490, 490, nil, 490, 490, 490, 490, 490, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 490, + nil, nil, 490, nil, nil, 490, 490, nil, nil, 490, + nil, nil, nil, nil, nil, 490, nil, nil, nil, nil, + nil, nil, nil, nil, 490, nil, nil, nil, nil, 490, + 490, 490, 490, nil, 490, 490, 490, 490, nil, nil, + nil, nil, 490, 490, nil, nil, nil, nil, nil, nil, + 490, nil, 490, 490, 490, 495, 495, 495, 495, 495, + nil, nil, nil, 495, 495, nil, nil, nil, 495, nil, + 495, 495, 495, 495, 495, 495, 495, nil, nil, nil, + nil, nil, 495, 495, 495, 495, 495, 495, 495, nil, + nil, 495, nil, nil, nil, nil, nil, 495, 495, 495, + 495, 495, 495, 495, 495, 495, 495, 495, 495, nil, + 495, 495, 495, nil, 495, 495, 495, 495, 495, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 495, nil, + nil, 495, nil, nil, 495, 495, nil, nil, 495, nil, + 495, nil, nil, nil, 495, nil, nil, nil, nil, nil, + nil, nil, nil, 495, nil, nil, nil, nil, 495, 495, + 495, 495, nil, 495, 495, 495, 495, nil, nil, nil, + nil, 495, 495, nil, nil, nil, nil, nil, 495, 495, + nil, 495, 495, 495, 503, 503, 503, nil, 503, nil, + nil, nil, 503, 503, nil, nil, nil, 503, nil, 503, + 503, 503, 503, 503, 503, 503, nil, nil, nil, nil, + nil, 503, 503, 503, 503, 503, 503, 503, nil, nil, + 503, nil, nil, nil, nil, nil, nil, 503, nil, nil, + 503, 503, 503, 503, 503, 503, 503, 503, nil, 503, + 503, 503, nil, 503, 503, nil, nil, 503, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 503, nil, nil, + 503, nil, nil, 503, 503, nil, nil, 503, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 503, 503, 503, + 503, nil, 503, 503, 503, 503, nil, nil, nil, nil, + 503, 503, nil, nil, nil, 505, 505, 505, 503, 505, + 503, 503, 503, 505, 505, nil, nil, nil, 505, nil, + 505, 505, 505, 505, 505, 505, 505, nil, nil, nil, + nil, nil, 505, 505, 505, 505, 505, 505, 505, nil, + nil, 505, nil, nil, nil, nil, nil, nil, 505, nil, + nil, 505, 505, 505, 505, 505, 505, 505, 505, 505, + 505, 505, 505, nil, 505, 505, 505, 505, 505, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 505, nil, + nil, 505, nil, nil, 505, 505, nil, nil, 505, nil, + 505, nil, 505, nil, 505, nil, nil, 505, nil, nil, + nil, nil, nil, 505, nil, nil, nil, nil, 505, 505, + 505, 505, nil, 505, 505, 505, 505, nil, nil, nil, + nil, 505, 505, nil, nil, nil, 511, 511, 511, 505, + 511, 505, 505, 505, 511, 511, nil, nil, nil, 511, + nil, 511, 511, 511, 511, 511, 511, 511, nil, nil, + nil, nil, nil, 511, 511, 511, 511, 511, 511, 511, + nil, nil, 511, nil, nil, nil, nil, nil, nil, 511, + nil, nil, 511, 511, 511, 511, 511, 511, 511, 511, + nil, 511, 511, 511, nil, 511, 511, nil, nil, 511, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 511, + nil, nil, 511, nil, nil, 511, 511, nil, nil, 511, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 511, + 511, 511, 511, nil, 511, 511, 511, 511, nil, nil, + nil, nil, 511, 511, nil, nil, nil, 514, 514, 514, + 511, 514, 511, 511, 511, 514, 514, nil, nil, nil, + 514, nil, 514, 514, 514, 514, 514, 514, 514, nil, + nil, nil, nil, nil, 514, 514, 514, 514, 514, 514, + 514, nil, nil, 514, nil, nil, nil, nil, nil, nil, + 514, nil, nil, 514, 514, 514, 514, 514, 514, 514, + 514, nil, 514, 514, 514, nil, 514, 514, 514, 514, + 514, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 514, nil, nil, 514, nil, nil, 514, 514, nil, nil, + 514, nil, nil, nil, nil, nil, 514, nil, nil, nil, + nil, nil, nil, nil, nil, 514, nil, nil, nil, nil, + 514, 514, 514, 514, nil, 514, 514, 514, 514, nil, + nil, nil, nil, 514, 514, nil, nil, nil, 515, 515, + 515, 514, 515, 514, 514, 514, 515, 515, nil, nil, + nil, 515, nil, 515, 515, 515, 515, 515, 515, 515, + nil, nil, nil, nil, nil, 515, 515, 515, 515, 515, + 515, 515, nil, nil, 515, nil, nil, nil, nil, nil, + nil, 515, nil, nil, 515, 515, 515, 515, 515, 515, + 515, 515, nil, 515, 515, 515, nil, 515, 515, 515, + 515, 515, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 515, nil, nil, 515, nil, nil, 515, 515, nil, + nil, 515, nil, nil, nil, nil, nil, 515, nil, nil, + nil, nil, nil, nil, nil, nil, 515, nil, nil, nil, + nil, 515, 515, 515, 515, nil, 515, 515, 515, 515, + nil, nil, nil, nil, 515, 515, nil, nil, nil, 519, + 519, 519, 515, 519, 515, 515, 515, 519, 519, nil, + nil, nil, 519, nil, 519, 519, 519, 519, 519, 519, + 519, nil, nil, nil, nil, nil, 519, 519, 519, 519, + 519, 519, 519, nil, nil, 519, nil, nil, nil, nil, + nil, nil, 519, nil, nil, 519, 519, 519, 519, 519, + 519, 519, 519, nil, 519, 519, 519, nil, 519, 519, + 519, 519, 519, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 519, nil, nil, 519, nil, nil, 519, 519, + nil, nil, 519, nil, nil, nil, nil, nil, 519, nil, + nil, nil, nil, nil, nil, nil, nil, 519, nil, nil, + nil, nil, 519, 519, 519, 519, nil, 519, 519, 519, + 519, nil, nil, nil, nil, 519, 519, nil, nil, nil, + 525, 525, 525, 519, 525, 519, 519, 519, 525, 525, + nil, nil, nil, 525, nil, 525, 525, 525, 525, 525, + 525, 525, nil, nil, nil, nil, nil, 525, 525, 525, + 525, 525, 525, 525, nil, nil, 525, nil, nil, nil, + nil, nil, nil, 525, nil, nil, 525, 525, 525, 525, + 525, 525, 525, 525, 525, 525, 525, 525, nil, 525, + 525, 525, 525, 525, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 525, nil, nil, 525, nil, nil, 525, + 525, nil, nil, 525, nil, 525, nil, nil, nil, 525, + nil, nil, 525, nil, nil, nil, nil, nil, 525, nil, + nil, nil, nil, 525, 525, 525, 525, nil, 525, 525, + 525, 525, nil, nil, nil, nil, 525, 525, nil, nil, + nil, 528, 528, 528, 525, 528, 525, 525, 525, 528, + 528, nil, nil, nil, 528, nil, 528, 528, 528, 528, + 528, 528, 528, nil, nil, nil, nil, nil, 528, 528, + 528, 528, 528, 528, 528, nil, nil, 528, nil, nil, + nil, nil, nil, nil, 528, nil, nil, 528, 528, 528, + 528, 528, 528, 528, 528, 528, 528, 528, 528, nil, + 528, 528, 528, 528, 528, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 528, nil, nil, 528, nil, nil, + 528, 528, nil, nil, 528, nil, nil, nil, nil, nil, + 528, nil, nil, 528, nil, nil, nil, nil, nil, 528, + nil, nil, nil, nil, 528, 528, 528, 528, nil, 528, + 528, 528, 528, nil, nil, nil, nil, 528, 528, nil, + nil, nil, 542, 542, 542, 528, 542, 528, 528, 528, + 542, 542, nil, nil, nil, 542, nil, 542, 542, 542, + 542, 542, 542, 542, nil, nil, nil, nil, nil, 542, + 542, 542, 542, 542, 542, 542, nil, nil, 542, nil, + nil, nil, nil, nil, nil, 542, nil, nil, 542, 542, + 542, 542, 542, 542, 542, 542, nil, 542, 542, 542, + nil, 542, 542, 542, 542, 542, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 542, nil, nil, 542, nil, + nil, 542, 542, nil, nil, 542, nil, 542, nil, nil, + nil, 542, nil, nil, nil, nil, nil, nil, nil, nil, + 542, nil, nil, nil, nil, 542, 542, 542, 542, nil, + 542, 542, 542, 542, nil, nil, nil, nil, 542, 542, + nil, nil, nil, 543, 543, 543, 542, 543, 542, 542, + 542, 543, 543, nil, nil, nil, 543, nil, 543, 543, + 543, 543, 543, 543, 543, nil, nil, nil, nil, nil, + 543, 543, 543, 543, 543, 543, 543, nil, nil, 543, + nil, nil, nil, nil, nil, nil, 543, nil, nil, 543, + 543, 543, 543, 543, 543, 543, 543, 543, 543, 543, + 543, nil, 543, 543, 543, 543, 543, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 543, nil, nil, 543, + nil, nil, 543, 543, nil, nil, 543, nil, 543, nil, + 543, nil, 543, nil, nil, 543, nil, nil, nil, nil, + nil, 543, nil, nil, nil, nil, 543, 543, 543, 543, + nil, 543, 543, 543, 543, nil, nil, nil, nil, 543, + 543, nil, nil, nil, 553, 553, 553, 543, 553, 543, + 543, 543, 553, 553, nil, nil, nil, 553, nil, 553, + 553, 553, 553, 553, 553, 553, nil, nil, nil, nil, + nil, 553, 553, 553, 553, 553, 553, 553, nil, nil, + 553, nil, nil, nil, nil, nil, nil, 553, nil, nil, + 553, 553, 553, 553, 553, 553, 553, 553, 553, 553, + 553, 553, nil, 553, 553, 553, 553, 553, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 553, nil, nil, + 553, nil, nil, 553, 553, nil, nil, 553, nil, 553, + nil, 553, nil, 553, nil, nil, 553, nil, nil, nil, + nil, nil, 553, nil, nil, nil, nil, 553, 553, 553, + 553, nil, 553, 553, 553, 553, nil, nil, nil, nil, + 553, 553, nil, nil, nil, 587, 587, 587, 553, 587, + 553, 553, 553, 587, 587, nil, nil, nil, 587, nil, + 587, 587, 587, 587, 587, 587, 587, nil, nil, nil, + nil, nil, 587, 587, 587, 587, 587, 587, 587, nil, + nil, 587, nil, nil, nil, nil, nil, nil, 587, nil, + nil, 587, 587, 587, 587, 587, 587, 587, 587, nil, + 587, 587, 587, nil, 587, 587, 587, 587, 587, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 587, nil, + nil, 587, nil, nil, 587, 587, nil, nil, 587, nil, + 587, nil, nil, nil, 587, nil, nil, nil, nil, nil, + nil, nil, nil, 587, nil, nil, nil, nil, 587, 587, + 587, 587, nil, 587, 587, 587, 587, nil, nil, nil, + nil, 587, 587, nil, nil, nil, 588, 588, 588, 587, + 588, 587, 587, 587, 588, 588, nil, nil, nil, 588, + nil, 588, 588, 588, 588, 588, 588, 588, nil, nil, + nil, nil, nil, 588, 588, 588, 588, 588, 588, 588, + nil, nil, 588, nil, nil, nil, nil, nil, nil, 588, + nil, nil, 588, 588, 588, 588, 588, 588, 588, 588, + nil, 588, 588, 588, nil, 588, 588, 588, 588, 588, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 588, + nil, nil, 588, nil, nil, 588, 588, nil, nil, 588, + nil, nil, nil, nil, nil, 588, nil, nil, nil, nil, + nil, nil, nil, nil, 588, nil, nil, nil, nil, 588, + 588, 588, 588, nil, 588, 588, 588, 588, nil, nil, + nil, nil, 588, 588, nil, nil, nil, 591, 591, 591, + 588, 591, 588, 588, 588, 591, 591, nil, nil, nil, + 591, nil, 591, 591, 591, 591, 591, 591, 591, nil, + nil, nil, nil, nil, 591, 591, 591, 591, 591, 591, + 591, nil, nil, 591, nil, nil, nil, nil, nil, nil, + 591, nil, nil, 591, 591, 591, 591, 591, 591, 591, + 591, 591, 591, 591, 591, nil, 591, 591, 591, 591, + 591, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 591, nil, nil, 591, nil, nil, 591, 591, nil, nil, + 591, nil, 591, nil, 591, nil, 591, nil, nil, 591, + nil, nil, nil, nil, nil, 591, nil, nil, nil, nil, + 591, 591, 591, 591, nil, 591, 591, 591, 591, nil, + nil, nil, nil, 591, 591, nil, nil, nil, 592, 592, + 592, 591, 592, 591, 591, 591, 592, 592, nil, nil, + nil, 592, nil, 592, 592, 592, 592, 592, 592, 592, + nil, nil, nil, nil, nil, 592, 592, 592, 592, 592, + 592, 592, nil, nil, 592, nil, nil, nil, nil, nil, + nil, 592, nil, nil, 592, 592, 592, 592, 592, 592, + 592, 592, 592, 592, 592, 592, nil, 592, 592, 592, + 592, 592, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 592, nil, nil, 592, nil, nil, 592, 592, nil, + nil, 592, nil, nil, nil, 592, nil, 592, nil, nil, + 592, nil, nil, nil, nil, nil, 592, nil, nil, nil, + nil, 592, 592, 592, 592, nil, 592, 592, 592, 592, + nil, nil, nil, nil, 592, 592, nil, nil, nil, 593, + 593, 593, 592, 593, 592, 592, 592, 593, 593, nil, + nil, nil, 593, nil, 593, 593, 593, 593, 593, 593, + 593, nil, nil, nil, nil, nil, 593, 593, 593, 593, + 593, 593, 593, nil, nil, 593, nil, nil, nil, nil, + nil, nil, 593, nil, nil, 593, 593, 593, 593, 593, + 593, 593, 593, nil, 593, 593, 593, nil, 593, 593, + 593, 593, 593, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 593, nil, nil, 593, nil, nil, 593, 593, + nil, nil, 593, nil, nil, nil, nil, nil, 593, nil, + nil, nil, nil, nil, nil, nil, nil, 593, nil, nil, + nil, nil, 593, 593, 593, 593, nil, 593, 593, 593, + 593, nil, nil, nil, nil, 593, 593, nil, nil, nil, + 594, 594, 594, 593, 594, 593, 593, 593, 594, 594, + nil, nil, nil, 594, nil, 594, 594, 594, 594, 594, + 594, 594, nil, nil, nil, nil, nil, 594, 594, 594, + 594, 594, 594, 594, nil, nil, 594, nil, nil, nil, + nil, nil, nil, 594, nil, nil, 594, 594, 594, 594, + 594, 594, 594, 594, nil, 594, 594, 594, nil, 594, + 594, 594, 594, 594, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 594, nil, nil, 594, nil, nil, 594, + 594, nil, nil, 594, nil, nil, nil, nil, nil, 594, + nil, nil, nil, nil, nil, nil, nil, nil, 594, nil, + nil, nil, nil, 594, 594, 594, 594, nil, 594, 594, + 594, 594, nil, nil, nil, nil, 594, 594, nil, nil, + nil, 598, 598, 598, 594, 598, 594, 594, 594, 598, + 598, nil, nil, nil, 598, nil, 598, 598, 598, 598, + 598, 598, 598, nil, nil, nil, nil, nil, 598, 598, + 598, 598, 598, 598, 598, nil, nil, 598, nil, nil, + nil, nil, nil, nil, 598, nil, nil, 598, 598, 598, + 598, 598, 598, 598, 598, nil, 598, 598, 598, nil, + 598, 598, 598, 598, 598, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 598, nil, nil, 598, nil, nil, + 598, 598, nil, nil, 598, nil, nil, nil, nil, nil, + 598, nil, nil, nil, nil, nil, nil, nil, nil, 598, + nil, nil, nil, nil, 598, 598, 598, 598, nil, 598, + 598, 598, 598, nil, nil, nil, nil, 598, 598, nil, + nil, nil, 599, 599, 599, 598, 599, 598, 598, 598, + 599, 599, nil, nil, nil, 599, nil, 599, 599, 599, + 599, 599, 599, 599, nil, nil, nil, nil, nil, 599, + 599, 599, 599, 599, 599, 599, nil, nil, 599, nil, + nil, nil, nil, nil, nil, 599, nil, nil, 599, 599, + 599, 599, 599, 599, 599, 599, nil, 599, 599, 599, + nil, 599, 599, 599, 599, 599, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 599, nil, nil, 599, nil, + nil, 599, 599, nil, nil, 599, nil, nil, nil, nil, + nil, 599, nil, nil, nil, nil, nil, nil, nil, nil, + 599, nil, nil, nil, nil, 599, 599, 599, 599, nil, + 599, 599, 599, 599, nil, nil, nil, nil, 599, 599, + nil, nil, nil, 602, 602, 602, 599, 602, 599, 599, + 599, 602, 602, nil, nil, nil, 602, nil, 602, 602, + 602, 602, 602, 602, 602, nil, nil, nil, nil, nil, + 602, 602, 602, 602, 602, 602, 602, nil, nil, 602, + nil, nil, nil, nil, nil, nil, 602, nil, nil, 602, + 602, 602, 602, 602, 602, 602, 602, nil, 602, 602, + 602, nil, 602, 602, 602, 602, 602, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 602, nil, nil, 602, + nil, nil, 602, 602, nil, nil, 602, nil, nil, nil, + nil, nil, 602, nil, nil, nil, nil, nil, nil, nil, + nil, 602, nil, nil, nil, nil, 602, 602, 602, 602, + nil, 602, 602, 602, 602, nil, nil, nil, nil, 602, + 602, nil, nil, nil, 603, 603, 603, 602, 603, 602, + 602, 602, 603, 603, nil, nil, nil, 603, nil, 603, + 603, 603, 603, 603, 603, 603, nil, nil, nil, nil, + nil, 603, 603, 603, 603, 603, 603, 603, nil, nil, + 603, nil, nil, nil, nil, nil, nil, 603, nil, nil, + 603, 603, 603, 603, 603, 603, 603, 603, nil, 603, + 603, 603, nil, 603, 603, 603, 603, 603, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 603, nil, nil, + 603, nil, nil, 603, 603, nil, nil, 603, nil, nil, + nil, nil, nil, 603, nil, nil, nil, nil, nil, nil, + nil, nil, 603, nil, nil, nil, nil, 603, 603, 603, + 603, nil, 603, 603, 603, 603, nil, nil, nil, nil, + 603, 603, nil, nil, nil, 627, 627, 627, 603, 627, + 603, 603, 603, 627, 627, nil, nil, nil, 627, nil, + 627, 627, 627, 627, 627, 627, 627, nil, nil, nil, + nil, nil, 627, 627, 627, 627, 627, 627, 627, nil, + nil, 627, nil, nil, nil, nil, nil, nil, 627, nil, + nil, 627, 627, 627, 627, 627, 627, 627, 627, nil, + 627, 627, 627, nil, 627, 627, 627, 627, 627, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 627, nil, + nil, 627, nil, nil, 627, 627, nil, nil, 627, nil, + nil, nil, nil, nil, 627, nil, nil, nil, nil, nil, + nil, nil, nil, 627, nil, nil, nil, nil, 627, 627, + 627, 627, nil, 627, 627, 627, 627, nil, nil, nil, + nil, 627, 627, nil, nil, nil, 633, 633, 633, 627, + 633, 627, 627, 627, 633, 633, nil, nil, nil, 633, + nil, 633, 633, 633, 633, 633, 633, 633, nil, nil, + nil, nil, nil, 633, 633, 633, 633, 633, 633, 633, + nil, nil, 633, nil, nil, nil, nil, nil, nil, 633, + nil, nil, 633, 633, 633, 633, 633, 633, 633, 633, + nil, 633, 633, 633, nil, 633, 633, nil, nil, 633, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 633, + nil, nil, 633, nil, nil, 633, 633, nil, nil, 633, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 633, + 633, 633, 633, nil, 633, 633, 633, 633, nil, nil, + nil, nil, 633, 633, nil, nil, nil, 644, 644, 644, + 633, 644, 633, 633, 633, 644, 644, nil, nil, nil, + 644, nil, 644, 644, 644, 644, 644, 644, 644, nil, + nil, nil, nil, nil, 644, 644, 644, 644, 644, 644, + 644, nil, nil, 644, nil, nil, nil, nil, nil, nil, + 644, nil, nil, 644, 644, 644, 644, 644, 644, 644, + 644, nil, 644, 644, 644, nil, 644, 644, nil, nil, + 644, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 644, nil, nil, 644, nil, nil, 644, 644, nil, nil, + 644, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 644, 644, 644, 644, nil, 644, 644, 644, 644, nil, + nil, nil, nil, 644, 644, nil, nil, nil, 649, 649, + 649, 644, 649, 644, 644, 644, 649, 649, nil, nil, + nil, 649, nil, 649, 649, 649, 649, 649, 649, 649, + nil, nil, nil, nil, nil, 649, 649, 649, 649, 649, + 649, 649, nil, nil, 649, nil, nil, nil, nil, nil, + nil, 649, nil, nil, 649, 649, 649, 649, 649, 649, + 649, 649, nil, 649, 649, 649, nil, 649, 649, 649, + 649, 649, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 649, nil, nil, 649, nil, nil, 649, 649, nil, + nil, 649, nil, 649, nil, nil, nil, 649, nil, nil, + nil, nil, nil, nil, nil, nil, 649, nil, nil, nil, + nil, 649, 649, 649, 649, nil, 649, 649, 649, 649, + nil, nil, nil, nil, 649, 649, nil, nil, nil, 674, + 674, 674, 649, 674, 649, 649, 649, 674, 674, nil, + nil, nil, 674, nil, 674, 674, 674, 674, 674, 674, + 674, nil, nil, nil, nil, nil, 674, 674, 674, 674, + 674, 674, 674, nil, nil, 674, nil, nil, nil, nil, + nil, nil, 674, nil, nil, 674, 674, 674, 674, 674, + 674, 674, 674, nil, 674, 674, 674, nil, 674, 674, + 674, 674, 674, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 674, nil, nil, 674, nil, nil, 674, 674, + nil, nil, 674, nil, nil, nil, nil, nil, 674, nil, + nil, nil, nil, nil, nil, nil, nil, 674, nil, nil, + nil, nil, 674, 674, 674, 674, nil, 674, 674, 674, + 674, nil, nil, nil, nil, 674, 674, nil, nil, nil, + 701, 701, 701, 674, 701, 674, 674, 674, 701, 701, + nil, nil, nil, 701, nil, 701, 701, 701, 701, 701, + 701, 701, nil, nil, nil, nil, nil, 701, 701, 701, + 701, 701, 701, 701, nil, nil, 701, nil, nil, nil, + nil, nil, nil, 701, nil, nil, 701, 701, 701, 701, + 701, 701, 701, 701, nil, 701, 701, 701, nil, 701, + 701, 701, 701, 701, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 701, nil, nil, 701, nil, nil, 701, + 701, nil, nil, 701, nil, nil, nil, nil, nil, 701, + nil, nil, nil, nil, nil, nil, nil, nil, 701, nil, + nil, nil, nil, 701, 701, 701, 701, nil, 701, 701, + 701, 701, nil, nil, nil, nil, 701, 701, nil, nil, + nil, 707, 707, 707, 701, 707, 701, 701, 701, 707, + 707, nil, nil, nil, 707, nil, 707, 707, 707, 707, + 707, 707, 707, nil, nil, nil, nil, nil, 707, 707, + 707, 707, 707, 707, 707, nil, nil, 707, nil, nil, + nil, nil, nil, nil, 707, nil, nil, 707, 707, 707, + 707, 707, 707, 707, 707, nil, 707, 707, 707, nil, + 707, 707, 707, 707, 707, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 707, nil, nil, 707, nil, nil, + 707, 707, nil, nil, 707, nil, nil, nil, nil, nil, + 707, nil, nil, nil, nil, nil, nil, nil, nil, 707, + nil, nil, nil, nil, 707, 707, 707, 707, nil, 707, + 707, 707, 707, nil, nil, nil, nil, 707, 707, nil, + nil, nil, 730, 730, 730, 707, 730, 707, 707, 707, + 730, 730, nil, nil, nil, 730, nil, 730, 730, 730, + 730, 730, 730, 730, nil, nil, nil, nil, nil, 730, + 730, 730, 730, 730, 730, 730, nil, nil, 730, nil, + nil, nil, nil, nil, nil, 730, nil, nil, 730, 730, + 730, 730, 730, 730, 730, 730, nil, 730, 730, 730, + nil, 730, 730, 730, 730, 730, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 730, nil, nil, 730, nil, + nil, 730, 730, nil, nil, 730, nil, nil, nil, nil, + nil, 730, nil, nil, nil, nil, nil, nil, nil, nil, + 730, nil, nil, nil, nil, 730, 730, 730, 730, nil, + 730, 730, 730, 730, nil, nil, nil, nil, 730, 730, + nil, nil, nil, 732, 732, 732, 730, 732, 730, 730, + 730, 732, 732, nil, nil, nil, 732, nil, 732, 732, + 732, 732, 732, 732, 732, nil, nil, nil, nil, nil, + 732, 732, 732, 732, 732, 732, 732, nil, nil, 732, + nil, nil, nil, nil, nil, nil, 732, nil, nil, 732, + 732, 732, 732, 732, 732, 732, 732, nil, 732, 732, + 732, nil, 732, 732, 732, 732, 732, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 732, nil, nil, 732, + nil, nil, 732, 732, nil, nil, 732, nil, nil, nil, + nil, nil, 732, nil, nil, nil, nil, nil, nil, nil, + nil, 732, nil, nil, nil, nil, 732, 732, 732, 732, + nil, 732, 732, 732, 732, nil, nil, nil, nil, 732, + 732, nil, nil, nil, 746, 746, 746, 732, 746, 732, + 732, 732, 746, 746, nil, nil, nil, 746, nil, 746, + 746, 746, 746, 746, 746, 746, nil, nil, nil, nil, + nil, 746, 746, 746, 746, 746, 746, 746, nil, nil, + 746, nil, nil, nil, nil, nil, nil, 746, nil, nil, + 746, 746, 746, 746, 746, 746, 746, 746, nil, 746, + 746, 746, nil, 746, 746, 746, 746, 746, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 746, nil, nil, + 746, nil, nil, 746, 746, nil, nil, 746, nil, nil, + nil, nil, nil, 746, nil, nil, nil, nil, nil, nil, + nil, nil, 746, nil, nil, nil, nil, 746, 746, 746, + 746, nil, 746, 746, 746, 746, nil, nil, nil, nil, + 746, 746, nil, nil, nil, 747, 747, 747, 746, 747, + 746, 746, 746, 747, 747, nil, nil, nil, 747, nil, + 747, 747, 747, 747, 747, 747, 747, nil, nil, nil, + nil, nil, 747, 747, 747, 747, 747, 747, 747, nil, + nil, 747, nil, nil, nil, nil, nil, nil, 747, nil, + nil, 747, 747, 747, 747, 747, 747, 747, 747, nil, + 747, 747, 747, nil, 747, 747, 747, 747, 747, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 747, nil, + nil, 747, nil, nil, 747, 747, nil, nil, 747, nil, + nil, nil, nil, nil, 747, nil, nil, nil, nil, nil, + nil, nil, nil, 747, nil, nil, nil, nil, 747, 747, + 747, 747, nil, 747, 747, 747, 747, nil, nil, nil, + nil, 747, 747, nil, nil, nil, 748, 748, 748, 747, + 748, 747, 747, 747, 748, 748, nil, nil, nil, 748, + nil, 748, 748, 748, 748, 748, 748, 748, nil, nil, + nil, nil, nil, 748, 748, 748, 748, 748, 748, 748, + nil, nil, 748, nil, nil, nil, nil, nil, nil, 748, + nil, nil, 748, 748, 748, 748, 748, 748, 748, 748, + nil, 748, 748, 748, nil, 748, 748, 748, 748, 748, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 748, + nil, nil, 748, nil, nil, 748, 748, nil, nil, 748, + nil, nil, nil, nil, nil, 748, nil, nil, nil, nil, + nil, nil, nil, nil, 748, nil, nil, nil, nil, 748, + 748, 748, 748, nil, 748, 748, 748, 748, nil, nil, + nil, nil, 748, 748, nil, nil, nil, 749, 749, 749, + 748, 749, 748, 748, 748, 749, 749, nil, nil, nil, + 749, nil, 749, 749, 749, 749, 749, 749, 749, nil, + nil, nil, nil, nil, 749, 749, 749, 749, 749, 749, + 749, nil, nil, 749, nil, nil, nil, nil, nil, nil, + 749, nil, nil, 749, 749, 749, 749, 749, 749, 749, + 749, nil, 749, 749, 749, nil, 749, 749, 749, 749, + 749, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 749, nil, nil, 749, nil, nil, 749, 749, nil, nil, + 749, nil, nil, nil, nil, nil, 749, nil, nil, nil, + nil, nil, nil, nil, nil, 749, nil, nil, nil, nil, + 749, 749, 749, 749, nil, 749, 749, 749, 749, nil, + nil, nil, nil, 749, 749, nil, nil, nil, 751, 751, + 751, 749, 751, 749, 749, 749, 751, 751, nil, nil, + nil, 751, nil, 751, 751, 751, 751, 751, 751, 751, + nil, nil, nil, nil, nil, 751, 751, 751, 751, 751, + 751, 751, nil, nil, 751, nil, nil, nil, nil, nil, + nil, 751, nil, nil, 751, 751, 751, 751, 751, 751, + 751, 751, nil, 751, 751, 751, nil, 751, 751, 751, + 751, 751, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 751, nil, nil, 751, nil, nil, 751, 751, nil, + nil, 751, nil, nil, nil, nil, nil, 751, nil, nil, + nil, nil, nil, nil, nil, nil, 751, nil, nil, nil, + nil, 751, 751, 751, 751, nil, 751, 751, 751, 751, + nil, nil, nil, nil, 751, 751, nil, nil, nil, 763, + 763, 763, 751, 763, 751, 751, 751, 763, 763, nil, + nil, nil, 763, nil, 763, 763, 763, 763, 763, 763, + 763, nil, nil, nil, nil, nil, 763, 763, 763, 763, + 763, 763, 763, nil, nil, 763, nil, nil, nil, nil, + nil, nil, 763, nil, nil, 763, 763, 763, 763, 763, + 763, 763, 763, nil, 763, 763, 763, nil, 763, 763, + nil, nil, 763, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 763, nil, nil, 763, nil, nil, 763, 763, + nil, nil, 763, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 763, 763, 763, 763, nil, 763, 763, 763, + 763, nil, nil, nil, nil, 763, 763, nil, nil, nil, + 800, 800, 800, 763, 800, 763, 763, 763, 800, 800, + nil, nil, nil, 800, nil, 800, 800, 800, 800, 800, + 800, 800, nil, nil, nil, nil, nil, 800, 800, 800, + 800, 800, 800, 800, nil, nil, 800, nil, nil, nil, + nil, nil, nil, 800, nil, nil, 800, 800, 800, 800, + 800, 800, 800, 800, nil, 800, 800, 800, nil, 800, + 800, 800, 800, 800, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 800, nil, nil, 800, nil, nil, 800, + 800, nil, nil, 800, nil, nil, nil, nil, nil, 800, + nil, nil, nil, nil, nil, nil, nil, nil, 800, nil, + nil, nil, nil, 800, 800, 800, 800, nil, 800, 800, + 800, 800, nil, nil, nil, nil, 800, 800, nil, nil, + nil, 813, 813, 813, 800, 813, 800, 800, 800, 813, + 813, nil, nil, nil, 813, nil, 813, 813, 813, 813, + 813, 813, 813, nil, nil, nil, nil, nil, 813, 813, + 813, 813, 813, 813, 813, nil, nil, 813, nil, nil, + nil, nil, nil, nil, 813, nil, nil, 813, 813, 813, + 813, 813, 813, 813, 813, nil, 813, 813, 813, nil, + 813, 813, 813, 813, 813, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 813, nil, nil, 813, nil, nil, + 813, 813, nil, nil, 813, nil, nil, nil, nil, nil, + 813, nil, nil, nil, nil, nil, nil, nil, nil, 813, + nil, nil, nil, nil, 813, 813, 813, 813, nil, 813, + 813, 813, 813, nil, nil, nil, nil, 813, 813, nil, + nil, nil, 818, 818, 818, 813, 818, 813, 813, 813, + 818, 818, nil, nil, nil, 818, nil, 818, 818, 818, + 818, 818, 818, 818, nil, nil, nil, nil, nil, 818, + 818, 818, 818, 818, 818, 818, nil, nil, 818, nil, + nil, nil, nil, nil, nil, 818, nil, nil, 818, 818, + 818, 818, 818, 818, 818, 818, nil, 818, 818, 818, + nil, 818, 818, 818, 818, 818, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 818, nil, nil, 818, nil, + nil, 818, 818, nil, nil, 818, nil, 818, nil, nil, + nil, 818, nil, nil, nil, nil, nil, nil, nil, nil, + 818, nil, nil, nil, nil, 818, 818, 818, 818, nil, + 818, 818, 818, 818, nil, nil, nil, nil, 818, 818, + nil, nil, nil, 835, 835, 835, 818, 835, 818, 818, + 818, 835, 835, nil, nil, nil, 835, nil, 835, 835, + 835, 835, 835, 835, 835, nil, nil, nil, nil, nil, + 835, 835, 835, 835, 835, 835, 835, nil, nil, 835, + nil, nil, nil, nil, nil, nil, 835, nil, nil, 835, + 835, 835, 835, 835, 835, 835, 835, 835, 835, 835, + 835, nil, 835, 835, 835, 835, 835, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 835, nil, nil, 835, + nil, nil, 835, 835, nil, nil, 835, nil, nil, nil, + 835, nil, 835, nil, nil, 835, nil, nil, nil, nil, + nil, 835, nil, nil, nil, nil, 835, 835, 835, 835, + nil, 835, 835, 835, 835, nil, nil, nil, nil, 835, + 835, nil, nil, nil, 836, 836, 836, 835, 836, 835, + 835, 835, 836, 836, nil, nil, nil, 836, nil, 836, + 836, 836, 836, 836, 836, 836, nil, nil, nil, nil, + nil, 836, 836, 836, 836, 836, 836, 836, nil, nil, + 836, nil, nil, nil, nil, nil, nil, 836, nil, nil, + 836, 836, 836, 836, 836, 836, 836, 836, nil, 836, + 836, 836, nil, 836, 836, 836, 836, 836, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 836, nil, nil, + 836, nil, nil, 836, 836, nil, nil, 836, nil, nil, + nil, nil, nil, 836, nil, nil, nil, nil, nil, nil, + nil, nil, 836, nil, nil, nil, nil, 836, 836, 836, + 836, nil, 836, 836, 836, 836, nil, nil, nil, nil, + 836, 836, nil, nil, nil, 850, 850, 850, 836, 850, + 836, 836, 836, 850, 850, nil, nil, nil, 850, nil, + 850, 850, 850, 850, 850, 850, 850, nil, nil, nil, + nil, nil, 850, 850, 850, 850, 850, 850, 850, nil, + nil, 850, nil, nil, nil, nil, nil, nil, 850, nil, + nil, 850, 850, 850, 850, 850, 850, 850, 850, nil, + 850, 850, 850, nil, 850, 850, nil, nil, 850, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 850, nil, + nil, 850, nil, nil, 850, 850, nil, nil, 850, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 850, 850, + 850, 850, nil, 850, 850, 850, 850, nil, nil, nil, + nil, 850, 850, nil, nil, nil, 862, 862, 862, 850, + 862, 850, 850, 850, 862, 862, nil, nil, nil, 862, + nil, 862, 862, 862, 862, 862, 862, 862, nil, nil, + nil, nil, nil, 862, 862, 862, 862, 862, 862, 862, + nil, nil, 862, nil, nil, nil, nil, nil, nil, 862, + nil, nil, 862, 862, 862, 862, 862, 862, 862, 862, + nil, 862, 862, 862, nil, 862, 862, nil, nil, 862, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 862, + nil, nil, 862, nil, nil, 862, 862, nil, nil, 862, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 862, + 862, 862, 862, nil, 862, 862, 862, 862, nil, nil, + nil, nil, 862, 862, nil, nil, nil, 971, 971, 971, + 862, 971, 862, 862, 862, 971, 971, nil, nil, nil, + 971, nil, 971, 971, 971, 971, 971, 971, 971, nil, + nil, nil, nil, nil, 971, 971, 971, 971, 971, 971, + 971, nil, nil, 971, nil, nil, nil, nil, nil, nil, + 971, nil, nil, 971, 971, 971, 971, 971, 971, 971, + 971, 971, 971, 971, 971, nil, 971, 971, 971, 971, + 971, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 971, nil, nil, 971, nil, nil, 971, 971, nil, nil, + 971, nil, 971, nil, 971, nil, 971, nil, nil, 971, + nil, nil, nil, nil, nil, 971, nil, nil, nil, nil, + 971, 971, 971, 971, nil, 971, 971, 971, 971, nil, + nil, nil, nil, 971, 971, nil, nil, nil, nil, 56, + nil, 971, nil, 971, 971, 971, 56, 56, 56, nil, + nil, 56, 56, 56, nil, 56, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 56, 56, 56, nil, nil, + nil, nil, nil, nil, nil, 56, 56, nil, 56, 56, + 56, 56, 56, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, nil, + nil, 56, 56, 56, nil, nil, 56, nil, nil, 56, + nil, nil, 56, 56, nil, 56, nil, 56, nil, 56, + nil, 56, 56, nil, 56, 56, 56, 56, 56, nil, + 56, nil, 56, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 56, nil, nil, 56, + 56, 56, 56, 424, 56, nil, 56, nil, nil, nil, + 424, 424, 424, nil, nil, 424, 424, 424, nil, 424, + nil, nil, nil, nil, nil, nil, nil, nil, 424, 424, + 424, 424, nil, nil, nil, nil, nil, nil, nil, 424, + 424, nil, 424, 424, 424, 424, 424, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 424, + 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, + 424, 424, 424, nil, nil, 424, 424, 424, nil, nil, + 424, nil, nil, 424, nil, nil, 424, 424, nil, 424, + nil, 424, nil, 424, nil, 424, 424, nil, 424, 424, + 424, 424, 424, nil, 424, 424, 424, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 424, nil, nil, 424, 424, 424, 424, 425, 424, nil, + 424, nil, nil, nil, 425, 425, 425, nil, nil, 425, + 425, 425, nil, 425, nil, nil, nil, nil, nil, nil, + nil, nil, 425, 425, 425, 425, nil, nil, nil, nil, + nil, nil, nil, 425, 425, nil, 425, 425, 425, 425, + 425, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 425, 425, 425, 425, 425, 425, 425, + 425, 425, 425, 425, 425, 425, 425, nil, nil, 425, + 425, 425, nil, nil, 425, nil, nil, 425, nil, nil, + 425, 425, nil, 425, nil, 425, nil, 425, nil, 425, + 425, nil, 425, 425, 425, 425, 425, nil, 425, 425, + 425, 937, nil, 937, 937, 937, 937, 937, nil, nil, + nil, nil, nil, nil, 425, nil, 937, 425, 425, 425, + 425, 27, 425, nil, 425, nil, nil, nil, 27, 27, + 27, nil, nil, 27, 27, 27, nil, 27, 937, nil, + nil, nil, nil, nil, nil, nil, 27, 27, 27, 937, + 937, nil, nil, nil, 937, nil, nil, 27, 27, nil, + 27, 27, 27, 27, 27, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, nil, nil, 27, 27, 27, nil, nil, 27, nil, + 27, 27, nil, nil, 27, 27, nil, 27, nil, 27, + nil, 27, nil, 27, 27, nil, 27, 27, 27, 27, + 27, 28, 27, 27, 27, nil, nil, nil, 28, 28, + 28, nil, nil, 28, 28, 28, nil, 28, 27, nil, + nil, 27, 27, nil, 27, nil, 27, 28, 28, nil, + nil, nil, nil, nil, nil, nil, nil, 28, 28, nil, + 28, 28, 28, 28, 28, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, nil, nil, 28, 28, 28, nil, nil, 28, nil, + 28, 28, nil, nil, 28, 28, nil, 28, nil, 28, + nil, 28, nil, 28, 28, nil, 28, 28, 28, 28, + 28, nil, 28, 415, 28, nil, nil, nil, nil, nil, + 415, 415, 415, nil, nil, 415, 415, 415, 28, 415, + nil, 28, 28, nil, 28, nil, 28, nil, 415, 415, + 415, nil, nil, nil, nil, nil, nil, nil, nil, 415, + 415, nil, 415, 415, 415, 415, 415, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 415, + 415, 415, 415, 415, 415, 415, 415, 415, 415, 415, + 415, 415, 415, nil, nil, 415, 415, 415, nil, nil, + 415, nil, 415, 415, nil, nil, 415, 415, nil, 415, + nil, 415, nil, 415, nil, 415, 415, nil, 415, 415, + 415, 415, 415, nil, 415, 415, 415, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 415, nil, 474, 415, 415, nil, 415, nil, 415, 474, + 474, 474, nil, nil, 474, 474, 474, 614, 474, 614, + 614, 614, 614, 614, nil, nil, nil, 474, 474, nil, + nil, nil, 614, nil, nil, nil, nil, nil, 474, 474, + nil, 474, 474, 474, 474, 474, nil, nil, nil, nil, + nil, nil, nil, nil, 614, nil, 533, nil, 533, 533, + 533, 533, 533, 614, 614, 614, 614, nil, nil, nil, + 614, 533, nil, nil, nil, nil, nil, nil, nil, 474, + nil, nil, nil, nil, nil, nil, 474, nil, nil, nil, + nil, 474, 474, 533, 533, nil, 614, nil, nil, nil, + nil, nil, 533, 533, 533, 533, nil, nil, nil, 533, + nil, nil, nil, nil, 474, 474, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 474, + nil, nil, 474, nil, nil, nil, nil, 474, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, nil, nil, nil, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, nil, nil, nil, nil, nil, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + nil, 8, nil, nil, nil, nil, nil, nil, nil, 8, + 8, nil, 8, 8, 8, 8, 8, 8, 8, nil, + nil, 8, 8, nil, nil, nil, 8, 8, 8, 8, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 8, 8, nil, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, nil, nil, + 8, 8, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + nil, nil, nil, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, nil, nil, nil, nil, nil, 9, 9, + 9, 9, 9, 9, 9, 9, 9, nil, nil, 9, + nil, nil, nil, nil, nil, nil, nil, 9, 9, nil, + 9, 9, 9, 9, 9, 9, 9, nil, nil, 9, + 9, nil, nil, nil, 9, 9, 9, 9, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 9, 9, nil, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, nil, nil, 9, 9, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 9, 395, 395, 395, 395, 395, 395, + 395, 395, 395, 395, 395, 395, 395, 395, 395, 395, + 395, 395, 395, 395, 395, 395, 395, 395, nil, nil, + nil, 395, 395, 395, 395, 395, 395, 395, 395, 395, + 395, nil, nil, nil, nil, nil, 395, 395, 395, 395, + 395, 395, 395, 395, 395, nil, nil, 395, nil, nil, + nil, nil, nil, nil, nil, 395, 395, nil, 395, 395, + 395, 395, 395, 395, 395, nil, nil, 395, 395, nil, + nil, nil, 395, 395, 395, 395, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 395, + 395, nil, 395, 395, 395, 395, 395, 395, 395, 395, + 395, 395, 395, 395, nil, nil, 395, 395, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 395, 584, 584, 584, 584, 584, 584, 584, 584, + 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, + 584, 584, 584, 584, 584, 584, nil, nil, nil, 584, + 584, 584, 584, 584, 584, 584, 584, 584, 584, nil, + nil, nil, nil, nil, 584, 584, 584, 584, 584, 584, + 584, 584, 584, nil, nil, 584, nil, nil, nil, nil, + nil, nil, nil, 584, 584, nil, 584, 584, 584, 584, + 584, 584, 584, nil, nil, 584, 584, nil, nil, nil, + 584, 584, 584, 584, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 584, 584, nil, + 584, 584, 584, 584, 584, 584, 584, 584, 584, 584, + 584, 584, nil, nil, 584, 584, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 584, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, nil, nil, nil, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, nil, nil, nil, + nil, nil, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, nil, 71, nil, nil, nil, nil, + nil, 71, 71, nil, 71, 71, 71, 71, 71, 71, + 71, nil, nil, 71, 71, nil, nil, nil, 71, 71, + 71, 71, nil, nil, nil, nil, nil, 71, nil, nil, + nil, nil, nil, nil, nil, 71, 71, nil, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + nil, nil, 71, 714, 714, 714, 714, 714, 714, 714, + 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, + 714, 714, 714, 714, 714, 714, 714, nil, nil, nil, + 714, 714, 714, 714, 714, 714, 714, 714, 714, 714, + nil, nil, nil, nil, nil, 714, 714, 714, 714, 714, + 714, 714, 714, 714, nil, nil, 714, nil, nil, nil, + nil, nil, nil, nil, 714, 714, nil, 714, 714, 714, + 714, 714, 714, 714, nil, nil, 714, 714, nil, nil, + nil, 714, 714, 714, 714, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 714, 714, + nil, 714, 714, 714, 714, 714, 714, 714, 714, 714, + 714, 714, 714, 212, 212, 714, nil, 212, nil, nil, + nil, nil, nil, nil, nil, 212, 212, nil, 212, 212, + 212, 212, 212, 212, 212, nil, nil, 212, 212, nil, + nil, nil, 212, 212, 212, 212, nil, nil, nil, nil, + nil, 212, nil, nil, nil, nil, nil, nil, nil, 212, + 212, nil, 212, 212, 212, 212, 212, 212, 212, 212, + 212, 212, 212, 212, 213, 213, 212, nil, 213, nil, + nil, nil, nil, nil, nil, nil, 213, 213, nil, 213, + 213, 213, 213, 213, 213, 213, nil, nil, 213, 213, + nil, nil, nil, 213, 213, 213, 213, nil, nil, nil, + nil, nil, 213, nil, nil, nil, nil, nil, nil, nil, + 213, 213, nil, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 261, 261, 213, nil, 261, + nil, nil, nil, nil, nil, nil, nil, 261, 261, nil, + 261, 261, 261, 261, 261, 261, 261, nil, nil, 261, + 261, nil, nil, nil, 261, 261, 261, 261, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 261, 261, nil, 261, 261, 261, 261, 261, 261, + 261, 261, 261, 261, 261, 261, 440, 440, 261, nil, + 440, nil, nil, nil, nil, nil, nil, nil, 440, 440, + nil, 440, 440, 440, 440, 440, 440, 440, nil, nil, + 440, 440, nil, nil, nil, 440, 440, 440, 440, nil, + nil, nil, nil, nil, 440, nil, nil, nil, nil, nil, + nil, nil, 440, 440, nil, 440, 440, 440, 440, 440, + 440, 440, 440, 440, 440, 440, 440, 441, 441, 440, + nil, 441, nil, nil, nil, nil, nil, nil, nil, 441, + 441, nil, 441, 441, 441, 441, 441, 441, 441, nil, + nil, 441, 441, nil, nil, nil, 441, 441, 441, 441, + nil, nil, nil, nil, nil, 441, nil, nil, nil, nil, + nil, nil, nil, 441, 441, nil, 441, 441, 441, 441, + 441, 441, 441, 441, 441, 441, 441, 441, 506, 506, + 441, nil, 506, nil, nil, nil, nil, nil, nil, nil, + 506, 506, nil, 506, 506, 506, 506, 506, 506, 506, + nil, nil, 506, 506, nil, nil, nil, 506, 506, 506, + 506, nil, nil, nil, nil, nil, 506, nil, nil, nil, + nil, nil, nil, nil, 506, 506, nil, 506, 506, 506, + 506, 506, 506, 506, 506, 506, 506, 506, 506, 507, + 507, 506, nil, 507, nil, nil, nil, nil, nil, nil, + nil, 507, 507, nil, 507, 507, 507, 507, 507, 507, + 507, nil, nil, 507, 507, nil, nil, nil, 507, 507, + 507, 507, nil, nil, nil, nil, nil, 507, nil, nil, + nil, nil, nil, nil, nil, 507, 507, nil, 507, 507, + 507, 507, 507, 507, 507, 507, 507, 507, 507, 507, + 516, 516, 507, nil, 516, nil, nil, nil, nil, nil, + nil, nil, 516, 516, nil, 516, 516, 516, 516, 516, + 516, 516, nil, nil, 516, 516, nil, nil, nil, 516, + 516, 516, 516, nil, nil, nil, nil, nil, 516, nil, + nil, nil, nil, nil, nil, nil, 516, 516, nil, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 517, 517, 516, nil, 517, nil, nil, nil, nil, + nil, nil, nil, 517, 517, nil, 517, 517, 517, 517, + 517, 517, 517, nil, nil, 517, 517, nil, nil, nil, + 517, 517, 517, 517, nil, nil, nil, nil, nil, 517, + nil, nil, nil, nil, nil, nil, nil, 517, 517, nil, + 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, + 517, 517, 544, 544, 517, nil, 544, nil, nil, nil, + nil, nil, nil, nil, 544, 544, nil, 544, 544, 544, + 544, 544, 544, 544, nil, nil, 544, 544, nil, nil, + nil, 544, 544, 544, 544, nil, nil, nil, nil, nil, + 544, nil, nil, nil, nil, nil, nil, nil, 544, 544, + nil, 544, 544, 544, 544, 544, 544, 544, 544, 544, + 544, 544, 544, 545, 545, 544, nil, 545, nil, nil, + nil, nil, nil, nil, nil, 545, 545, nil, 545, 545, + 545, 545, 545, 545, 545, nil, nil, 545, 545, nil, + nil, nil, 545, 545, 545, 545, nil, nil, nil, nil, + nil, 545, nil, nil, nil, nil, nil, nil, nil, 545, + 545, nil, 545, 545, 545, 545, 545, 545, 545, 545, + 545, 545, 545, 545, 551, 551, 545, nil, 551, nil, + nil, nil, nil, nil, nil, nil, 551, 551, nil, 551, + 551, 551, 551, 551, 551, 551, nil, nil, 551, 551, + nil, nil, nil, 551, 551, 551, 551, nil, nil, nil, + nil, nil, 551, nil, nil, nil, nil, nil, nil, nil, + 551, 551, nil, 551, 551, 551, 551, 551, 551, 551, + 551, 551, 551, 551, 551, 552, 552, 551, nil, 552, + nil, nil, nil, nil, nil, nil, nil, 552, 552, nil, + 552, 552, 552, 552, 552, 552, 552, nil, nil, 552, + 552, nil, nil, nil, 552, 552, 552, 552, nil, nil, + nil, nil, nil, 552, nil, nil, nil, nil, nil, nil, + nil, 552, 552, nil, 552, 552, 552, 552, 552, 552, + 552, 552, 552, 552, 552, 552, 918, 918, 552, nil, + 918, nil, nil, nil, nil, nil, nil, nil, 918, 918, + nil, 918, 918, 918, 918, 918, 918, 918, nil, nil, + 918, 918, nil, nil, nil, 918, 918, 918, 918, nil, + nil, nil, nil, nil, 918, nil, nil, nil, nil, nil, + nil, nil, 918, 918, nil, 918, 918, 918, 918, 918, + 918, 918, 918, 918, 918, 918, 918, 972, 972, 918, + nil, 972, nil, nil, nil, nil, nil, nil, nil, 972, + 972, nil, 972, 972, 972, 972, 972, 972, 972, nil, + nil, 972, 972, nil, nil, nil, 972, 972, 972, 972, + nil, nil, nil, nil, nil, 972, nil, nil, nil, nil, + nil, nil, nil, 972, 972, nil, 972, 972, 972, 972, + 972, 972, 972, 972, 972, 972, 972, 972, 973, 973, + 972, nil, 973, nil, nil, nil, nil, nil, nil, nil, + 973, 973, nil, 973, 973, 973, 973, 973, 973, 973, + nil, nil, 973, 973, nil, nil, nil, 973, 973, 973, + 973, nil, nil, nil, nil, nil, 973, nil, nil, nil, + nil, nil, nil, nil, 973, 973, nil, 973, 973, 973, + 973, 973, 973, 973, 973, 973, 973, 973, 973, nil, + 655, 973, 655, 655, 655, 655, 655, nil, 712, nil, + 712, 712, 712, 712, 712, 655, nil, nil, nil, nil, + nil, nil, nil, 712, nil, 713, nil, 713, 713, 713, + 713, 713, nil, nil, nil, nil, nil, 655, nil, nil, + 713, nil, nil, nil, nil, 712, 655, 655, 655, 655, + nil, nil, nil, 655, 712, 712, 712, 712, nil, nil, + nil, 712, 713, nil, 794, nil, 794, 794, 794, 794, + 794, 713, 713, 713, 713, nil, nil, nil, 713, 794, + nil, 796, nil, 796, 796, 796, 796, 796, nil, 841, + nil, 841, 841, 841, 841, 841, 796, nil, nil, nil, + nil, 794, nil, nil, 841, nil, nil, nil, nil, nil, + 794, 794, 794, 794, nil, nil, nil, 794, 796, nil, + nil, nil, nil, nil, nil, nil, 841, 796, 796, 796, + 796, nil, nil, nil, 796, 841, 841, 841, 841, nil, + nil, 843, 841, 843, 843, 843, 843, 843, nil, 933, + nil, 933, 933, 933, 933, 933, 843, nil, nil, nil, + nil, nil, nil, nil, 933, nil, 939, nil, 939, 939, + 939, 939, 939, nil, nil, nil, nil, nil, 843, nil, + nil, 939, nil, nil, nil, nil, 933, 843, 843, 843, + 843, nil, nil, nil, 843, 933, 933, 933, 933, nil, + nil, nil, 933, 939, nil, 957, nil, 957, 957, 957, + 957, 957, nil, nil, 939, 939, nil, nil, nil, 939, + 957, nil, 959, nil, 959, 959, 959, 959, 959, 961, + nil, 961, 961, 961, 961, 961, nil, 959, nil, nil, + nil, nil, 957, nil, 961, nil, nil, nil, nil, nil, + nil, 957, 957, 957, 957, nil, nil, nil, 957, 959, + nil, nil, nil, nil, nil, nil, 961, nil, nil, nil, + 959, 959, nil, nil, nil, 959, nil, 961, 961, nil, + nil, 963, 961, 963, 963, 963, 963, 963, 1001, nil, + 1001, 1001, 1001, 1001, 1001, 1011, 963, 1011, 1011, 1011, + 1011, 1011, nil, 1001, nil, nil, nil, nil, nil, nil, + 1011, nil, nil, nil, nil, nil, nil, nil, 963, nil, + nil, nil, nil, nil, nil, 1001, nil, nil, nil, 963, + 963, nil, 1011, nil, 963, nil, 1001, 1001, nil, nil, + nil, 1001, nil, 1011, 1011, nil, nil, nil, 1011 ] + +racc_action_pointer = [ + 747, 20, nil, -73, nil, 5086, 1447, -81, 22816, 22944, + -68, nil, -81, -6, 338, 59, 66, 359, nil, -79, + 606, 1167, 197, nil, 173, nil, -8, 22331, 22441, 5217, + 5348, 5479, nil, 887, 5610, 5741, nil, 101, 199, 228, + 205, 142, 5880, 6011, 6142, 150, 424, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 21929, nil, -72, 6273, + 6404, -20, nil, 6535, 6666, nil, nil, 6797, 6936, 7067, + 7198, 23328, nil, nil, nil, nil, nil, nil, nil, 377, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 0, nil, nil, + 112, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 319, nil, 7337, nil, nil, nil, nil, 7476, 7607, + 7738, 7869, 8008, 1027, nil, 730, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 190, nil, 1167, 8139, + 8270, 8401, 23502, 23563, 8532, 8663, 8794, 8925, 9056, 9187, + nil, nil, 437, -40, -23, 290, 107, 213, 274, nil, + 9318, 1307, 294, 9449, 9580, 9711, 9842, 9973, 10104, 10235, + 10366, 10497, 10628, 10759, 10890, 11021, 11152, 11283, 11414, 11545, + 11676, 11807, 11938, 12069, 12200, 12331, 12462, 12593, 12724, nil, + nil, 23624, nil, nil, 301, 12855, 12986, nil, nil, nil, + nil, nil, nil, nil, 13117, nil, 1307, nil, 286, 290, + nil, 13248, 342, 13379, nil, 13510, 13641, nil, nil, 148, + nil, 13780, 1572, 332, 315, 1447, 328, 383, 359, 13911, + 1587, 481, 750, 789, 445, 890, nil, 413, 386, 10, + nil, nil, nil, 461, 225, 428, 14050, nil, 252, 501, + 929, nil, 505, nil, 14181, 1727, 14312, 454, nil, -101, + 401, 494, 477, 402, 511, nil, nil, 594, -1, 33, + 14443, 14574, 221, 636, 527, -18, 9, 959, 611, 10, + 671, nil, nil, 337, 373, 158, nil, 1027, nil, 37, + 14705, nil, nil, nil, 295, 371, 397, 449, 485, 509, + 512, 626, 641, nil, 677, nil, 14836, nil, 242, 327, + 365, 394, 399, -41, -35, 403, nil, nil, nil, nil, + nil, nil, nil, nil, 592, 23072, nil, nil, nil, nil, + 607, nil, nil, 599, 14967, 607, nil, nil, 887, 633, + nil, 638, 642, 258, 347, 22553, nil, nil, nil, 222, + 334, 695, nil, nil, 22063, 22197, nil, 1447, nil, 662, + nil, nil, 747, nil, nil, nil, nil, -35, nil, 717, + 23685, 23746, 15098, 130, 15229, 15360, 15491, 3267, 3407, 3138, + 3435, 762, 767, 771, 775, 5217, 5348, 5479, 3547, 3687, + 3827, 3967, 4107, 4247, 4387, 4527, 4667, 4807, 489, 3295, + 4947, 5086, 1587, -59, 22682, nil, nil, nil, nil, 716, + nil, -53, -20, 730, nil, nil, 15622, nil, 15753, nil, + 15884, nil, nil, nil, nil, 16023, 1587, 1867, 741, 739, + nil, nil, 741, 16162, 747, 16293, 23807, 23868, 1030, 790, + nil, 16424, 748, nil, 16555, 16686, 23929, 23990, 1727, 16817, + 877, 887, 650, 810, nil, 16948, nil, nil, 17079, nil, + nil, nil, nil, 22685, 2007, 889, nil, 2147, 27, 29, + 887, 902, 17210, 17341, 24051, 24112, 25, nil, nil, 1069, + nil, 24173, 24234, 17472, nil, nil, nil, 450, 140, 2287, + 824, nil, -33, nil, nil, nil, 870, nil, nil, nil, + 795, nil, nil, 192, nil, 212, nil, nil, 781, nil, + 792, nil, nil, nil, 23200, nil, 810, 17603, 17734, 418, + 853, 17865, 17996, 18127, 18258, 872, nil, nil, 18389, 18520, + 877, nil, 18651, 18782, nil, nil, 168, 217, 470, 606, + 846, 1027, 845, nil, 22646, nil, 2427, 954, 5, 202, + nil, 2567, 2707, nil, 853, nil, 904, 18913, nil, nil, + nil, 887, 180, 19044, 868, nil, 881, 136, 177, 923, + 410, 1167, 925, 884, 19175, 1867, 953, -14, 1006, 19306, + nil, 891, nil, 520, nil, 24479, nil, 891, 901, nil, + 902, 906, 907, nil, nil, nil, nil, nil, nil, nil, + 900, 3113, nil, nil, 19437, nil, nil, nil, 1000, nil, + nil, nil, 1002, nil, nil, 1003, 717, nil, 1041, nil, + nil, nil, nil, 1054, nil, 36, 934, 28, 40, 122, + 151, 19568, 747, 1307, nil, 936, 2847, 19699, nil, nil, + 1058, 2987, 24487, 24504, 23441, nil, nil, nil, nil, nil, + nil, 3127, nil, nil, nil, nil, nil, nil, nil, 935, + 19830, 2007, 19961, nil, 936, nil, 2147, nil, 2287, nil, + nil, 2427, nil, 2567, nil, 2707, 20092, 20223, 20354, 20485, + 253, 20616, 950, 954, nil, 975, 980, 983, nil, 1008, + 991, 991, 990, 20747, nil, nil, 1130, nil, nil, 3267, + 1027, 1132, nil, nil, nil, 1018, 887, nil, nil, 1144, + nil, 3407, 1021, 1070, nil, nil, 1069, nil, 37, 1030, + 372, nil, nil, 674, 24543, nil, 24560, nil, 5788, nil, + 20878, nil, 3142, nil, 1028, 327, 1034, nil, nil, nil, + nil, 1165, nil, 21009, 1166, 3547, 3687, nil, 21140, 3827, + 64, 121, nil, 1170, 469, 3967, nil, 1171, 1051, 625, + nil, 1064, 1060, nil, 2847, 21271, 21402, 2987, 795, nil, + nil, 24568, nil, 24620, nil, 7245, nil, nil, 1085, 1153, + 21533, 1099, 1140, nil, 1090, nil, nil, nil, 4107, nil, + nil, 35, 21664, nil, nil, nil, nil, nil, 1119, 1090, + nil, nil, nil, 1094, 1115, nil, 1120, 1124, nil, 1128, + nil, nil, 1136, 3207, 1138, 3533, nil, nil, 98, nil, + 1270, 1271, nil, 45, nil, nil, nil, 1272, nil, nil, + nil, 1202, nil, 1159, nil, nil, 1161, 1164, 1166, 1167, + nil, 1168, nil, 626, nil, nil, nil, 1170, 24295, nil, + nil, nil, 4247, 1209, 1239, 1310, 1249, 1349, nil, 4387, + 4527, nil, nil, 24628, nil, 13958, nil, 22260, nil, 24645, + nil, nil, nil, nil, 335, 3627, 1181, 4667, nil, nil, + nil, nil, nil, 4807, nil, 4947, nil, 24684, nil, 24701, + nil, 24708, nil, 24760, nil, nil, nil, 1293, 1226, 1230, + 1313, 21795, 24356, 24417, 1379, 1208, 1322, 1200, 1201, 1202, + 1210, 1216, 3673, 1230, 3703, 773, 1358, 1379, 1260, 1264, + 1268, 1273, nil, nil, 1281, 102, 111, 138, 1447, nil, + nil, 24767, nil, nil, nil, nil, 3711, 1286, nil, nil, + nil, 24774, nil, nil, nil, nil, 144, 1287, 1288, 1298, + nil, nil ] + +racc_action_default = [ + -3, -598, -1, -584, -4, -598, -7, -598, -598, -598, + -598, -29, -598, -598, -598, -279, -598, -40, -43, -586, + -598, -48, -50, -51, -52, -56, -256, -256, -256, -293, + -329, -330, -68, -11, -72, -80, -82, -598, -491, -492, + -598, -598, -598, -598, -598, -586, -237, -270, -271, -272, + -273, -274, -275, -276, -277, -278, -574, -281, -283, -597, + -565, -301, -303, -598, -598, -307, -310, -584, -598, -598, + -598, -598, -331, -332, -334, -335, -432, -433, -434, -435, + -436, -457, -439, -440, -459, -461, -444, -449, -453, -455, + -471, -459, -473, -475, -476, -477, -478, -572, -480, -481, + -573, -483, -484, -485, -486, -487, -488, -489, -490, -495, + -496, -598, -2, -585, -593, -594, -595, -6, -598, -598, + -598, -598, -598, -3, -17, -598, -111, -112, -113, -114, + -115, -116, -117, -118, -119, -123, -124, -125, -126, -127, + -128, -129, -130, -131, -132, -133, -134, -135, -136, -137, + -138, -139, -140, -141, -142, -143, -144, -145, -146, -147, + -148, -149, -150, -151, -152, -153, -154, -155, -156, -157, + -158, -159, -160, -161, -162, -163, -164, -165, -166, -167, + -168, -169, -170, -171, -172, -173, -174, -175, -176, -177, + -178, -179, -180, -181, -182, -183, -184, -185, -186, -187, + -188, -189, -190, -191, -192, -193, -22, -120, -11, -598, + -598, -246, -598, -598, -598, -598, -598, -598, -598, -586, + -587, -47, -598, -491, -492, -598, -279, -598, -598, -229, + -598, -11, -598, -598, -598, -598, -598, -598, -598, -598, + -598, -598, -598, -598, -598, -598, -598, -598, -598, -598, + -598, -598, -598, -598, -598, -598, -598, -598, -598, -401, + -403, -598, -582, -583, -57, -246, -598, -300, -407, -416, + -418, -63, -413, -64, -586, -65, -238, -251, -260, -260, + -255, -598, -261, -598, -567, -598, -598, -66, -67, -584, + -12, -598, -15, -598, -70, -11, -586, -598, -73, -76, + -11, -88, -89, -598, -598, -96, -293, -296, -586, -598, + -329, -330, -333, -414, -598, -78, -598, -84, -290, -474, + -598, -214, -215, -230, -598, -11, -598, -586, -239, -590, + -590, -598, -598, -590, -598, -302, -392, -49, -598, -598, + -598, -598, -584, -598, -585, -491, -492, -598, -598, -279, + -598, -345, -346, -106, -107, -598, -109, -598, -279, -598, + -598, -491, -492, -322, -111, -112, -153, -154, -155, -171, + -176, -183, -186, -324, -598, -563, -598, -437, -598, -598, + -598, -598, -598, -598, -598, -598, 1022, -5, -596, -23, + -24, -25, -26, -27, -598, -598, -19, -20, -21, -121, + -598, -30, -39, -266, -598, -598, -265, -31, -196, -586, + -247, -260, -260, -575, -576, -256, -411, -577, -578, -576, + -575, -256, -410, -412, -577, -578, -37, -204, -38, -598, + -41, -42, -194, -261, -44, -45, -46, -586, -299, -598, + -598, -598, -246, -290, -598, -598, -598, -205, -206, -207, + -208, -209, -210, -211, -212, -216, -217, -218, -219, -220, + -221, -222, -223, -224, -225, -226, -227, -228, -231, -232, + -233, -234, -586, -381, -256, -575, -576, -54, -58, -586, + -257, -381, -381, -586, -295, -252, -598, -253, -598, -258, + -598, -262, -570, -571, -10, -585, -14, -3, -586, -69, + -288, -85, -74, -598, -586, -246, -598, -598, -95, -598, + -474, -598, -81, -86, -598, -598, -598, -598, -235, -598, + -424, -598, -284, -598, -240, -592, -591, -242, -592, -291, + -292, -566, -304, -524, -11, -336, -337, -11, -598, -598, + -598, -598, -598, -246, -598, -598, -290, -315, -106, -107, + -108, -598, -598, -246, -318, -497, -498, -598, -598, -11, + -502, -326, -586, -438, -458, -463, -598, -465, -441, -460, + -598, -462, -443, -598, -446, -598, -448, -451, -598, -452, + -598, -472, -8, -18, -598, -28, -269, -598, -598, -415, + -598, -248, -250, -598, -598, -59, -245, -408, -598, -598, + -61, -409, -598, -598, -298, -588, -575, -576, -575, -576, + -586, -194, -598, -382, -586, -384, -11, -53, -404, -381, + -243, -11, -11, -294, -260, -259, -263, -598, -568, -569, + -13, -598, -71, -598, -77, -83, -586, -575, -576, -244, + -92, -94, -598, -79, -598, -203, -213, -586, -597, -597, + -282, -586, -287, -590, -393, -524, -396, -562, -562, -507, + -509, -509, -509, -523, -525, -526, -527, -528, -529, -530, + -531, -598, -533, -535, -537, -542, -544, -545, -547, -552, + -554, -555, -557, -558, -559, -598, -597, -338, -597, -308, + -339, -340, -311, -598, -314, -598, -586, -575, -576, -579, + -289, -598, -106, -107, -110, -586, -11, -598, -500, -320, + -598, -11, -524, -524, -598, -564, -464, -467, -468, -469, + -470, -11, -442, -445, -447, -450, -454, -456, -122, -267, + -598, -197, -598, -589, -260, -33, -199, -34, -200, -60, + -35, -202, -36, -201, -62, -195, -598, -598, -598, -598, + -415, -598, -562, -562, -363, -365, -365, -365, -380, -598, + -586, -386, -531, -539, -540, -550, -598, -406, -405, -11, + -598, -598, -254, -264, -16, -75, -90, -87, -297, -597, + -343, -11, -425, -597, -426, -427, -598, -241, -598, -586, + -598, -505, -506, -598, -598, -516, -598, -519, -598, -521, + -598, -347, -598, -349, -351, -358, -586, -536, -546, -556, + -560, -598, -341, -598, -598, -11, -11, -313, -598, -11, + -415, -598, -415, -598, -598, -11, -323, -598, -586, -598, + -327, -598, -268, -32, -198, -249, -598, -236, -598, -361, + -362, -371, -373, -598, -376, -598, -378, -383, -598, -598, + -598, -538, -598, -402, -598, -417, -419, -9, -11, -431, + -344, -598, -598, -429, -285, -394, -397, -399, -598, -562, + -543, -561, -508, -509, -509, -534, -509, -509, -553, -509, + -531, -548, -586, -598, -356, -598, -532, -305, -598, -306, + -598, -598, -263, -597, -316, -319, -499, -598, -325, -501, + -503, -502, -466, -562, -541, -364, -365, -365, -365, -365, + -551, -365, -385, -586, -388, -390, -391, -549, -598, -290, + -55, -430, -11, -97, -98, -598, -598, -105, -428, -11, + -11, -395, -504, -598, -512, -598, -514, -598, -517, -598, + -520, -522, -348, -350, -354, -598, -359, -11, -309, -312, + -420, -421, -422, -11, -321, -11, -360, -598, -368, -598, + -370, -598, -374, -598, -377, -379, -387, -598, -289, -579, + -424, -246, -598, -598, -104, -598, -598, -509, -509, -509, + -509, -352, -598, -357, -598, -597, -598, -598, -365, -365, + -365, -365, -389, -423, -586, -575, -576, -579, -103, -398, + -400, -598, -510, -513, -515, -518, -598, -355, -342, -317, + -328, -598, -366, -369, -372, -375, -415, -509, -353, -365, + -511, -367 ] + +racc_goto_table = [ + 218, 541, 328, 14, 260, 409, 221, 487, 14, 373, + 277, 277, 277, 124, 207, 2, 415, 421, 521, 335, + 648, 438, 431, 222, 129, 129, 324, 312, 312, 589, + 261, 112, 222, 222, 222, 478, 14, 303, 303, 811, + 132, 132, 134, 134, 113, 338, 339, 315, 628, 342, + 298, 406, 711, 264, 271, 273, 512, 428, 319, 479, + 759, 312, 312, 312, 756, 474, 222, 222, 689, 692, + 222, 347, 357, 357, 550, 625, 484, 625, 878, 294, + 875, 278, 278, 278, 534, 537, 656, 129, 628, 524, + 527, 296, 806, 531, 779, 343, 910, 117, 499, 1, + 389, 390, 391, 392, 337, 337, 946, 857, 337, 630, + 914, 329, 206, 757, 916, 943, 14, 275, 287, 288, + 352, 222, 222, 222, 222, 14, 14, 875, 616, 359, + 363, 402, 379, 395, 814, 619, 621, 622, 394, 385, + 487, 573, 575, 584, 331, 753, 279, 279, 279, 618, + 375, 332, 628, 532, 663, 350, 554, 374, 325, 337, + 337, 337, 337, 326, 268, 272, 983, 651, 327, 336, + 340, 815, 341, 816, 6, 701, 330, 333, 953, 6, + 625, 625, 706, 825, 791, 792, 559, 560, 714, 901, + 758, 760, 277, 913, 654, 401, 407, 865, 693, 533, + 426, 430, 788, 1007, 929, 387, 848, 930, 789, 473, + 910, 14, 222, 222, 222, 878, 943, 222, 222, 222, + 222, 222, 222, 882, 481, 875, 482, 1018, 992, 425, + 750, 950, 916, 783, 14, 868, 610, 861, 564, 604, + 571, 574, 574, 634, 415, 421, 277, 277, 377, 875, + 378, 643, 710, 380, 381, 277, 776, 434, 435, 436, + 437, 405, 382, 383, 384, 828, 829, 405, 222, 222, + 704, 716, 116, 721, 769, 707, 663, 222, 873, 839, + 840, 620, 870, 904, nil, 623, nil, 6, nil, 509, + nil, 906, 312, 874, 14, 876, 393, 6, 14, 636, + 632, nil, 303, 14, nil, nil, 635, nil, 523, 312, + 639, 502, nil, nil, 763, nil, 820, 494, 278, 303, + 639, 869, 538, 539, nil, 822, 278, nil, 14, 222, + 495, 510, 513, 663, 663, nil, 116, 696, 1008, 951, + 907, 294, 908, 222, 222, nil, 294, 705, 639, nil, + 416, 894, 772, 498, 480, 26, 639, nil, 504, nil, + 26, nil, 483, 222, 715, nil, 739, 522, nil, 903, + 540, 744, 753, 775, 753, 26, 753, nil, nil, 222, + 561, 337, 337, 279, 26, 26, 26, nil, 26, nil, + 590, 279, nil, 955, nil, 628, 932, nil, nil, 823, + 583, 558, nil, nil, 827, nil, nil, 13, 297, 431, + nil, 129, 13, 787, nil, nil, nil, 562, 26, 26, + nil, nil, 26, 277, 625, nil, nil, 132, nil, 134, + 956, nil, 977, 724, nil, 724, nil, nil, nil, nil, + 13, 819, 595, nil, nil, 222, nil, 268, 600, 778, + nil, 272, nil, 612, nil, nil, 988, 425, nil, nil, + nil, nil, 772, nil, nil, 496, nil, nil, 26, nil, + 993, nil, nil, 26, 26, 26, 26, 26, 26, nil, + nil, nil, nil, nil, nil, nil, 277, nil, 753, nil, + 753, 784, 753, nil, 753, nil, 312, nil, 14, nil, + 14, 617, nil, nil, 312, nil, 303, nil, 222, nil, + nil, nil, 631, nil, 303, nil, nil, nil, 897, 513, + 13, nil, 222, 425, 277, nil, nil, 513, nil, 13, + 13, nil, nil, 425, 277, nil, nil, 14, 763, nil, + 14, 763, 753, 763, nil, 763, 222, nil, nil, nil, + nil, 952, nil, 596, nil, nil, 222, nil, 116, 601, + 647, 425, 14, 26, 26, 26, 26, 425, nil, 26, + 26, 26, 26, 26, 26, nil, 768, nil, 416, 735, + 737, nil, nil, 400, 740, 742, 26, nil, 430, 728, + nil, 590, 785, nil, 695, 761, 222, 222, nil, 767, + 129, 222, 222, 624, nil, 222, 297, 922, 886, nil, + nil, 116, 596, nil, 1016, 13, 132, 590, 134, 14, + 26, 26, nil, nil, 14, 14, 312, nil, 555, 26, + 899, nil, 786, nil, 947, nil, 303, 312, 13, nil, + nil, nil, 653, nil, 416, nil, 26, 303, 987, 513, + 26, nil, 830, nil, 416, 26, 754, 763, nil, 763, + 777, 763, nil, 763, nil, nil, nil, nil, nil, nil, + 297, 6, nil, nil, nil, 297, nil, 590, nil, nil, + 26, 26, 416, 821, 942, nil, 590, 755, nil, 824, + 416, nil, nil, nil, nil, 26, 26, nil, 13, nil, + nil, 405, 13, nil, 222, nil, nil, 13, 734, 14, + 222, 763, nil, nil, 14, 26, nil, nil, 833, nil, + nil, nil, 859, nil, 14, nil, 863, nil, nil, nil, + 129, 26, 13, nil, nil, 222, nil, nil, nil, nil, + nil, 761, 337, nil, nil, nil, nil, nil, 337, nil, + nil, nil, nil, nil, nil, 15, 312, nil, nil, nil, + 15, nil, nil, nil, nil, 994, 851, nil, nil, nil, + 761, nil, 14, nil, nil, nil, 639, 596, nil, nil, + 601, nil, nil, nil, 14, nil, nil, nil, 15, 305, + 305, nil, nil, nil, nil, 888, nil, 26, nil, nil, + nil, nil, nil, nil, 16, nil, nil, 690, 690, 16, + nil, nil, nil, nil, nil, nil, 222, nil, 14, 14, + nil, nil, 14, 349, 358, 358, 708, 709, 14, nil, + nil, nil, 871, nil, nil, 871, nil, 16, nil, nil, + nil, nil, nil, 312, nil, nil, nil, nil, nil, nil, + 26, nil, 26, 917, 337, 312, nil, nil, nil, nil, + 26, 14, nil, nil, nil, 925, nil, nil, 15, 877, + nil, 879, 351, nil, 26, nil, nil, 15, 15, nil, + 871, nil, nil, 754, nil, 754, nil, 754, nil, 26, + nil, nil, 26, nil, 966, nil, nil, nil, 26, nil, + nil, nil, 13, nil, 13, nil, nil, nil, 26, 686, + nil, nil, 688, nil, 26, nil, 909, 16, 911, nil, + nil, nil, nil, nil, nil, 14, 16, 16, nil, nil, + nil, nil, 14, 14, 425, nil, 795, 797, 799, nil, + nil, 13, nil, nil, 13, nil, 38, nil, 26, 26, + 14, 38, 277, 26, 26, nil, 14, 26, 14, nil, + nil, nil, nil, 15, nil, nil, 13, nil, nil, nil, + nil, 26, nil, nil, 222, 590, 26, 26, nil, 38, + 301, 301, nil, nil, nil, nil, 15, nil, nil, 425, + nil, 766, nil, nil, nil, nil, 770, 771, nil, 754, + nil, 754, nil, 754, nil, 754, 978, nil, 979, nil, + 980, nil, 16, nil, 345, 361, 361, 361, nil, 429, + nil, nil, nil, 13, nil, nil, nil, nil, 13, 13, + 989, nil, 990, nil, 991, 16, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 15, 842, 844, 846, + 15, nil, nil, 754, 305, 15, 26, nil, nil, 38, + nil, 26, 26, nil, nil, nil, 26, nil, 38, 38, + nil, 305, nil, nil, 1017, nil, 26, nil, nil, nil, + 15, nil, nil, nil, 1019, nil, nil, 26, nil, nil, + 690, nil, nil, 896, nil, 16, 831, nil, 900, 16, + nil, nil, nil, nil, 16, nil, nil, nil, nil, nil, + 416, nil, nil, 13, nil, nil, nil, nil, 13, nil, + nil, nil, nil, nil, 26, nil, nil, nil, 13, 16, + nil, nil, nil, nil, nil, nil, 26, nil, nil, nil, + nil, nil, nil, nil, 854, nil, nil, nil, nil, 934, + 936, nil, 938, 940, 38, 941, 860, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 26, 334, + 26, 26, nil, nil, 26, nil, 13, 38, nil, nil, + 26, nil, nil, nil, nil, nil, nil, nil, 13, nil, + 890, 891, nil, nil, 893, nil, nil, nil, 958, 960, + 962, 964, nil, 965, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 26, nil, nil, nil, nil, nil, nil, + nil, nil, 13, 13, nil, nil, 13, nil, nil, nil, + nil, nil, 13, 921, nil, nil, nil, 38, nil, nil, + nil, 38, nil, nil, nil, 301, 38, nil, nil, nil, + 15, nil, 15, 1002, 1003, 1004, 1005, nil, 305, nil, + nil, nil, 301, nil, nil, 13, 305, nil, nil, nil, + nil, 38, nil, nil, nil, nil, nil, 26, nil, nil, + 1012, 1013, 1014, 1015, 26, 26, nil, nil, nil, 15, + nil, nil, 15, 1020, 670, nil, nil, 970, nil, 16, + nil, 16, 26, nil, 975, 976, nil, nil, 26, nil, + 26, 1021, nil, nil, 15, 39, nil, nil, 403, nil, + 39, 720, 985, nil, 433, nil, 26, nil, 986, 13, + nil, nil, nil, nil, nil, nil, 13, 13, 16, nil, + nil, 16, nil, nil, nil, nil, nil, nil, 39, 302, + 302, nil, nil, nil, 13, nil, nil, nil, nil, nil, + 13, nil, 13, 16, nil, nil, nil, nil, nil, nil, + nil, 15, nil, nil, nil, 762, 15, 15, nil, nil, + nil, nil, nil, 346, 362, 362, 362, nil, 305, nil, + 489, nil, 491, nil, 492, 493, nil, nil, nil, 305, + nil, nil, nil, nil, nil, nil, 429, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 670, nil, nil, nil, + 16, nil, nil, nil, nil, 16, 16, nil, 39, nil, + nil, nil, 801, nil, nil, nil, nil, 39, 39, nil, + nil, 38, nil, 38, nil, nil, nil, nil, nil, 301, + nil, nil, nil, nil, nil, nil, nil, 301, nil, nil, + nil, 15, nil, nil, nil, nil, 15, nil, nil, nil, + nil, nil, nil, 670, 670, nil, 15, nil, nil, nil, + 38, nil, nil, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 38, nil, nil, nil, nil, + 16, nil, nil, 586, nil, 16, nil, nil, 358, nil, + nil, nil, nil, 39, 15, 16, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 15, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 39, nil, nil, nil, + nil, nil, nil, nil, nil, 670, nil, 670, nil, nil, + nil, nil, 38, 801, nil, nil, 884, 38, 38, nil, + 15, 15, nil, 16, 15, nil, nil, nil, nil, 301, + 15, nil, nil, nil, nil, 16, nil, nil, nil, nil, + 301, nil, nil, nil, nil, 626, nil, 334, nil, 629, + nil, nil, 762, nil, 762, 358, 39, nil, nil, nil, + 39, nil, nil, 15, 302, 39, nil, 927, nil, 16, + 16, nil, nil, 16, nil, nil, nil, nil, nil, 16, + nil, 302, nil, nil, 626, nil, nil, 334, nil, nil, + 39, nil, nil, nil, 801, nil, 801, nil, nil, nil, + nil, 433, 38, nil, nil, nil, nil, 38, nil, nil, + nil, nil, 16, nil, nil, nil, 928, 38, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 15, nil, nil, + nil, nil, nil, nil, 15, 15, nil, nil, nil, nil, + nil, nil, nil, nil, 670, nil, 729, nil, nil, nil, + 626, 334, 15, nil, nil, 981, 801, nil, 15, 361, + 15, nil, nil, nil, nil, 38, nil, nil, 762, nil, + nil, nil, nil, nil, nil, nil, 16, 38, nil, nil, + nil, nil, nil, 16, 16, nil, 773, nil, nil, nil, + nil, nil, nil, 801, nil, 801, nil, nil, nil, nil, + nil, 16, nil, nil, nil, nil, nil, 16, 782, 16, + nil, 38, 38, nil, nil, 38, 229, 801, nil, nil, + nil, 38, nil, nil, nil, 276, 276, 276, nil, nil, + nil, nil, nil, 807, nil, nil, nil, nil, 321, 322, + 323, nil, nil, nil, nil, nil, 361, nil, nil, nil, + nil, nil, nil, nil, 38, 276, 276, nil, 923, nil, + 39, nil, 39, nil, nil, nil, nil, nil, 302, nil, + nil, nil, nil, nil, nil, nil, 302, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 832, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 39, + nil, nil, 39, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 38, nil, + nil, nil, nil, nil, 39, 38, 38, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 38, nil, nil, nil, nil, nil, 38, + nil, 38, nil, nil, nil, nil, nil, nil, nil, 881, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 892, nil, nil, + nil, 39, nil, nil, nil, nil, 39, 39, nil, nil, + nil, nil, nil, nil, 334, nil, nil, nil, 302, nil, + nil, nil, nil, nil, nil, 276, 408, 276, nil, 302, + 427, 432, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 229, nil, nil, 447, + 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, + 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, + 468, 469, 470, 471, 472, nil, nil, nil, nil, nil, + nil, 276, 276, nil, nil, nil, nil, nil, nil, nil, + 276, 39, nil, nil, nil, nil, 39, 276, nil, 276, + nil, 276, 276, nil, nil, nil, 39, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 518, nil, nil, nil, nil, nil, nil, nil, 362, nil, + nil, nil, nil, nil, 39, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 39, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 39, 39, nil, nil, 39, nil, nil, nil, nil, nil, + 39, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 276, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 362, nil, nil, nil, nil, + nil, nil, nil, 39, nil, nil, nil, 924, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 276, nil, + 427, 611, 408, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 276, nil, 276, nil, 276, 39, nil, nil, + nil, nil, nil, nil, 39, 39, nil, nil, nil, nil, + nil, 276, nil, nil, nil, nil, nil, nil, nil, nil, + 645, 646, 39, nil, nil, nil, nil, nil, 39, nil, + 39, 276, nil, nil, 276, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 276, 276, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 276, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 276, 731, nil, nil, 276, 276, 736, + 738, nil, nil, nil, 741, 743, nil, nil, 611, 745, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 276, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 276, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 276, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 276, nil, 834, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 736, 738, 743, 741, nil, 837, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 276, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 276, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 276, 834, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 276 ] + +racc_goto_check = [ + 31, 92, 67, 22, 141, 23, 20, 73, 22, 56, + 33, 33, 33, 15, 15, 2, 37, 37, 8, 86, + 10, 47, 18, 22, 57, 57, 31, 64, 64, 24, + 36, 4, 22, 22, 22, 39, 22, 22, 22, 90, + 60, 60, 61, 61, 6, 17, 17, 50, 180, 17, + 49, 27, 98, 38, 38, 38, 51, 27, 63, 23, + 132, 64, 64, 64, 129, 37, 22, 22, 91, 91, + 22, 22, 22, 22, 54, 74, 47, 74, 176, 45, + 171, 68, 68, 68, 89, 89, 140, 57, 180, 69, + 69, 46, 119, 69, 11, 4, 177, 5, 47, 1, + 17, 17, 17, 17, 29, 29, 120, 12, 29, 14, + 134, 68, 16, 130, 135, 117, 22, 44, 44, 44, + 19, 22, 22, 22, 22, 22, 22, 171, 40, 55, + 55, 28, 155, 30, 11, 42, 40, 40, 2, 155, + 73, 158, 158, 62, 66, 123, 70, 70, 70, 72, + 84, 85, 180, 88, 166, 93, 95, 99, 100, 29, + 29, 29, 29, 101, 71, 71, 120, 102, 103, 104, + 105, 106, 107, 108, 7, 109, 70, 70, 110, 7, + 74, 74, 111, 112, 124, 124, 113, 114, 115, 116, + 121, 127, 33, 133, 136, 20, 20, 137, 92, 138, + 20, 20, 139, 120, 142, 5, 132, 143, 140, 144, + 177, 22, 22, 22, 22, 176, 117, 22, 22, 22, + 22, 22, 22, 119, 146, 171, 147, 120, 134, 57, + 24, 148, 135, 149, 22, 132, 23, 150, 159, 47, + 159, 159, 159, 51, 37, 37, 33, 33, 153, 171, + 154, 51, 8, 156, 157, 33, 24, 29, 29, 29, + 29, 68, 160, 161, 162, 140, 140, 68, 22, 22, + 54, 163, 96, 164, 40, 165, 166, 22, 170, 124, + 124, 47, 173, 174, nil, 47, nil, 7, nil, 31, + nil, 129, 64, 130, 22, 130, 7, 7, 22, 23, + 47, nil, 22, 22, nil, nil, 47, nil, 31, 64, + 37, 50, nil, nil, 172, nil, 24, 4, 68, 22, + 37, 123, 17, 17, nil, 24, 68, nil, 22, 22, + 6, 63, 49, 166, 166, nil, 96, 23, 90, 11, + 130, 45, 130, 22, 22, nil, 45, 23, 37, nil, + 71, 91, 73, 46, 44, 41, 37, nil, 46, nil, + 41, nil, 44, 22, 47, nil, 39, 29, nil, 123, + 4, 39, 123, 51, 123, 41, 123, nil, nil, 22, + 36, 29, 29, 70, 41, 41, 41, nil, 41, nil, + 31, 70, nil, 98, nil, 180, 124, nil, nil, 8, + 15, 29, nil, nil, 8, nil, nil, 21, 9, 18, + nil, 57, 21, 69, nil, nil, nil, 29, 41, 41, + nil, nil, 41, 33, 74, nil, nil, 60, nil, 61, + 124, nil, 130, 159, nil, 159, nil, nil, nil, nil, + 21, 89, 38, nil, nil, 22, nil, 71, 38, 47, + nil, 71, nil, 31, nil, nil, 130, 57, nil, nil, + nil, nil, 73, nil, nil, 7, nil, nil, 41, nil, + 10, nil, nil, 41, 41, 41, 41, 41, 41, nil, + nil, nil, nil, nil, nil, nil, 33, nil, 123, nil, + 123, 27, 123, nil, 123, nil, 64, nil, 22, nil, + 22, 38, nil, nil, 64, nil, 22, nil, 22, nil, + nil, nil, 2, nil, 22, nil, nil, nil, 8, 49, + 21, nil, 22, 57, 33, nil, nil, 49, nil, 21, + 21, nil, nil, 57, 33, nil, nil, 22, 172, nil, + 22, 172, 123, 172, nil, 172, 22, nil, nil, nil, + nil, 92, nil, 71, nil, nil, 22, nil, 96, 71, + 29, 57, 22, 41, 41, 41, 41, 57, nil, 41, + 41, 41, 41, 41, 41, nil, 86, nil, 71, 20, + 20, nil, nil, 9, 20, 20, 41, nil, 20, 15, + nil, 31, 67, nil, 68, 31, 22, 22, nil, 141, + 57, 22, 22, 70, nil, 22, 9, 89, 47, nil, + nil, 96, 71, nil, 24, 21, 60, 31, 61, 22, + 41, 41, nil, nil, 22, 22, 64, nil, 96, 41, + 47, nil, 31, nil, 89, nil, 22, 64, 21, nil, + nil, nil, 70, nil, 71, nil, 41, 22, 8, 49, + 41, nil, 56, nil, 71, 41, 125, 172, nil, 172, + 49, 172, nil, 172, nil, nil, nil, nil, nil, nil, + 9, 7, nil, nil, nil, 9, nil, 31, nil, nil, + 41, 41, 71, 17, 47, nil, 31, 128, nil, 17, + 71, nil, nil, nil, nil, 41, 41, nil, 21, nil, + nil, 68, 21, nil, 22, nil, nil, 21, 70, 22, + 22, 172, nil, nil, 22, 41, nil, nil, 20, nil, + nil, nil, 67, nil, 22, nil, 67, nil, nil, nil, + 57, 41, 21, nil, nil, 22, nil, nil, nil, nil, + nil, 31, 29, nil, nil, nil, nil, nil, 29, nil, + nil, nil, nil, nil, nil, 25, 64, nil, nil, nil, + 25, nil, nil, nil, nil, 23, 22, nil, nil, nil, + 31, nil, 22, nil, nil, nil, 37, 71, nil, nil, + 71, nil, nil, nil, 22, nil, nil, nil, 25, 25, + 25, nil, nil, nil, nil, 17, nil, 41, nil, nil, + nil, nil, nil, nil, 26, nil, nil, 96, 96, 26, + nil, nil, nil, nil, nil, nil, 22, nil, 22, 22, + nil, nil, 22, 25, 25, 25, 96, 96, 22, nil, + nil, nil, 125, nil, nil, 125, nil, 26, nil, nil, + nil, nil, nil, 64, nil, nil, nil, nil, nil, nil, + 41, nil, 41, 22, 29, 64, nil, nil, nil, nil, + 41, 22, nil, nil, nil, 22, nil, nil, 25, 128, + nil, 128, 26, nil, 41, nil, nil, 25, 25, nil, + 125, nil, nil, 125, nil, 125, nil, 125, nil, 41, + nil, nil, 41, nil, 31, nil, nil, nil, 41, nil, + nil, nil, 21, nil, 21, nil, nil, nil, 41, 9, + nil, nil, 9, nil, 41, nil, 128, 26, 128, nil, + nil, nil, nil, nil, nil, 22, 26, 26, nil, nil, + nil, nil, 22, 22, 57, nil, 169, 169, 169, nil, + nil, 21, nil, nil, 21, nil, 52, nil, 41, 41, + 22, 52, 33, 41, 41, nil, 22, 41, 22, nil, + nil, nil, nil, 25, nil, nil, 21, nil, nil, nil, + nil, 41, nil, nil, 22, 31, 41, 41, nil, 52, + 52, 52, nil, nil, nil, nil, 25, nil, nil, 57, + nil, 9, nil, nil, nil, nil, 9, 9, nil, 125, + nil, 125, nil, 125, nil, 125, 128, nil, 128, nil, + 128, nil, 26, nil, 52, 52, 52, 52, nil, 26, + nil, nil, nil, 21, nil, nil, nil, nil, 21, 21, + 128, nil, 128, nil, 128, 26, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 25, 126, 126, 126, + 25, nil, nil, 125, 25, 25, 41, nil, nil, 52, + nil, 41, 41, nil, nil, nil, 41, nil, 52, 52, + nil, 25, nil, nil, 128, nil, 41, nil, nil, nil, + 25, nil, nil, nil, 128, nil, nil, 41, nil, nil, + 96, nil, nil, 96, nil, 26, 9, nil, 96, 26, + nil, nil, nil, nil, 26, nil, nil, nil, nil, nil, + 71, nil, nil, 21, nil, nil, nil, nil, 21, nil, + nil, nil, nil, nil, 41, nil, nil, nil, 21, 26, + nil, nil, nil, nil, nil, nil, 41, nil, nil, nil, + nil, nil, nil, nil, 9, nil, nil, nil, nil, 169, + 169, nil, 169, 169, 52, 169, 9, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 41, 65, + 41, 41, nil, nil, 41, nil, 21, 52, nil, nil, + 41, nil, nil, nil, nil, nil, nil, nil, 21, nil, + 9, 9, nil, nil, 9, nil, nil, nil, 126, 126, + 126, 126, nil, 126, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 41, nil, nil, nil, nil, nil, nil, + nil, nil, 21, 21, nil, nil, 21, nil, nil, nil, + nil, nil, 21, 9, nil, nil, nil, 52, nil, nil, + nil, 52, nil, nil, nil, 52, 52, nil, nil, nil, + 25, nil, 25, 169, 169, 169, 169, nil, 25, nil, + nil, nil, 52, nil, nil, 21, 25, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, 41, nil, nil, + 126, 126, 126, 126, 41, 41, nil, nil, nil, 25, + nil, nil, 25, 169, 118, nil, nil, 9, nil, 26, + nil, 26, 41, nil, 9, 9, nil, nil, 41, nil, + 41, 126, nil, nil, 25, 53, nil, nil, 65, nil, + 53, 25, 9, nil, 65, nil, 41, nil, 9, 21, + nil, nil, nil, nil, nil, nil, 21, 21, 26, nil, + nil, 26, nil, nil, nil, nil, nil, nil, 53, 53, + 53, nil, nil, nil, 21, nil, nil, nil, nil, nil, + 21, nil, 21, 26, nil, nil, nil, nil, nil, nil, + nil, 25, nil, nil, nil, 118, 25, 25, nil, nil, + nil, nil, nil, 53, 53, 53, 53, nil, 25, nil, + 65, nil, 65, nil, 65, 65, nil, nil, nil, 25, + nil, nil, nil, nil, nil, nil, 26, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 118, nil, nil, nil, + 26, nil, nil, nil, nil, 26, 26, nil, 53, nil, + nil, nil, 118, nil, nil, nil, nil, 53, 53, nil, + nil, 52, nil, 52, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, 52, nil, nil, + nil, 25, nil, nil, nil, nil, 25, nil, nil, nil, + nil, nil, nil, 118, 118, nil, 25, nil, nil, nil, + 52, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + 26, nil, nil, 65, nil, 26, nil, nil, 25, nil, + nil, nil, nil, 53, 25, 26, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 25, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 53, nil, nil, nil, + nil, nil, nil, nil, nil, 118, nil, 118, nil, nil, + nil, nil, 52, 118, nil, nil, 118, 52, 52, nil, + 25, 25, nil, 26, 25, nil, nil, nil, nil, 52, + 25, nil, nil, nil, nil, 26, nil, nil, nil, nil, + 52, nil, nil, nil, nil, 65, nil, 65, nil, 65, + nil, nil, 118, nil, 118, 25, 53, nil, nil, nil, + 53, nil, nil, 25, 53, 53, nil, 25, nil, 26, + 26, nil, nil, 26, nil, nil, nil, nil, nil, 26, + nil, 53, nil, nil, 65, nil, nil, 65, nil, nil, + 53, nil, nil, nil, 118, nil, 118, nil, nil, nil, + nil, 65, 52, nil, nil, nil, nil, 52, nil, nil, + nil, nil, 26, nil, nil, nil, 26, 52, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 25, nil, nil, + nil, nil, nil, nil, 25, 25, nil, nil, nil, nil, + nil, nil, nil, nil, 118, nil, 65, nil, nil, nil, + 65, 65, 25, nil, nil, 118, 118, nil, 25, 52, + 25, nil, nil, nil, nil, 52, nil, nil, 118, nil, + nil, nil, nil, nil, nil, nil, 26, 52, nil, nil, + nil, nil, nil, 26, 26, nil, 65, nil, nil, nil, + nil, nil, nil, 118, nil, 118, nil, nil, nil, nil, + nil, 26, nil, nil, nil, nil, nil, 26, 65, 26, + nil, 52, 52, nil, nil, 52, 32, 118, nil, nil, + nil, 52, nil, nil, nil, 32, 32, 32, nil, nil, + nil, nil, nil, 65, nil, nil, nil, nil, 32, 32, + 32, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, 52, 32, 32, nil, 52, nil, + 53, nil, 53, nil, nil, nil, nil, nil, 53, nil, + nil, nil, nil, nil, nil, nil, 53, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 65, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 53, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, 53, 52, 52, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, 52, + nil, 52, nil, nil, nil, nil, nil, nil, nil, 65, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 65, nil, nil, + nil, 53, nil, nil, nil, nil, 53, 53, nil, nil, + nil, nil, nil, nil, 65, nil, nil, nil, 53, nil, + nil, nil, nil, nil, nil, 32, 32, 32, nil, 53, + 32, 32, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 32, nil, nil, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, nil, nil, nil, nil, nil, + nil, 32, 32, nil, nil, nil, nil, nil, nil, nil, + 32, 53, nil, nil, nil, nil, 53, 32, nil, 32, + nil, 32, 32, nil, nil, nil, 53, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 32, nil, nil, nil, nil, nil, nil, nil, 53, nil, + nil, nil, nil, nil, 53, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 53, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 53, 53, nil, nil, 53, nil, nil, nil, nil, nil, + 53, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 32, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 53, nil, nil, nil, nil, + nil, nil, nil, 53, nil, nil, nil, 53, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 32, nil, + 32, 32, 32, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 32, nil, 32, nil, 32, 53, nil, nil, + nil, nil, nil, nil, 53, 53, nil, nil, nil, nil, + nil, 32, nil, nil, nil, nil, nil, nil, nil, nil, + 32, 32, 53, nil, nil, nil, nil, nil, 53, nil, + 53, 32, nil, nil, 32, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 32, 32, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 32, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 32, 32, nil, nil, 32, 32, 32, + 32, nil, nil, nil, 32, 32, nil, nil, 32, 32, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 32, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 32, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 32, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 32, nil, 32, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 32, 32, 32, 32, nil, 32, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 32, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 32, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 32, 32, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 32 ] + +racc_goto_pointer = [ + nil, 99, 15, nil, 28, 92, 41, 174, -307, 375, + -500, -554, -672, nil, -386, 5, 103, -18, -193, 52, + -14, 407, 3, -206, -380, 755, 804, -158, -78, 41, + 9, -19, 1746, -19, nil, nil, 6, -196, 27, -229, + -345, 355, -342, nil, 88, 46, 58, -198, nil, 16, + 12, -260, 946, 1315, -281, 60, -62, 16, nil, nil, + 32, 34, -256, 17, -7, 1109, 85, -57, 52, -240, + 117, 138, -325, -272, -411, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 79, 91, -42, nil, -183, -254, + -647, -470, -342, 87, nil, -203, 269, nil, -508, 86, + 101, 105, -355, 110, 107, 105, -518, 106, -519, -372, + -716, -372, -526, -177, -186, -373, -641, -768, 761, -579, + -779, -424, nil, -469, -473, 42, 292, -423, 73, -550, + -501, nil, -554, -656, -739, -735, -339, -591, -137, -452, + -447, -18, -662, -660, -50, nil, -45, -44, -662, -416, + -546, nil, nil, 169, 169, 48, 168, 168, -240, -140, + 175, 175, 175, -295, -294, -281, -379, nil, nil, 276, + -516, -714, -300, -508, -555, nil, -718, -747, nil, nil, + -440 ] + +racc_goto_default = [ + nil, nil, nil, 3, nil, 4, 344, 292, nil, 520, + nil, 812, nil, 289, 290, nil, nil, nil, 11, 12, + 18, 228, 320, nil, nil, 226, 227, nil, nil, 17, + nil, 439, 21, 22, 23, 24, nil, 642, nil, nil, + nil, 309, nil, 25, 410, 32, nil, nil, 34, 37, + 36, nil, 223, 224, 356, nil, 131, 418, 130, 133, + 77, 78, nil, 92, 46, 282, nil, 780, 411, nil, + 412, 423, 597, 485, 280, 266, 47, 48, 49, 50, + 51, 52, 53, 54, 55, nil, 267, 61, nil, nil, + nil, nil, nil, nil, 69, nil, 535, 70, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 803, 880, nil, + 804, 905, 752, 658, nil, 659, nil, nil, 660, nil, + 662, 613, nil, nil, nil, 668, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 422, nil, nil, nil, nil, + nil, 76, 79, 80, nil, nil, nil, nil, nil, 569, + nil, nil, nil, nil, nil, nil, 872, 713, 657, nil, + 661, 672, 674, 675, 764, 678, 679, 765, 682, 685, + 284 ] + +racc_reduce_table = [ + 0, 0, :racc_error, + 1, 144, :_reduce_none, + 2, 145, :_reduce_2, + 0, 146, :_reduce_3, + 1, 146, :_reduce_4, + 3, 146, :_reduce_5, + 2, 146, :_reduce_6, + 1, 148, :_reduce_none, + 4, 148, :_reduce_8, + 4, 151, :_reduce_9, + 2, 152, :_reduce_10, + 0, 156, :_reduce_11, + 1, 156, :_reduce_12, + 3, 156, :_reduce_13, + 2, 156, :_reduce_14, + 1, 157, :_reduce_none, + 4, 157, :_reduce_16, + 0, 173, :_reduce_17, + 4, 150, :_reduce_18, + 3, 150, :_reduce_19, + 3, 150, :_reduce_20, + 3, 150, :_reduce_21, + 2, 150, :_reduce_22, + 3, 150, :_reduce_23, + 3, 150, :_reduce_24, + 3, 150, :_reduce_25, + 3, 150, :_reduce_26, + 3, 150, :_reduce_27, + 4, 150, :_reduce_28, + 1, 150, :_reduce_none, + 3, 150, :_reduce_30, + 3, 150, :_reduce_31, + 6, 150, :_reduce_32, + 5, 150, :_reduce_33, + 5, 150, :_reduce_34, + 5, 150, :_reduce_35, + 5, 150, :_reduce_36, + 3, 150, :_reduce_37, + 3, 150, :_reduce_38, + 3, 150, :_reduce_39, + 1, 150, :_reduce_none, + 3, 161, :_reduce_41, + 3, 161, :_reduce_42, + 1, 172, :_reduce_none, + 3, 172, :_reduce_44, + 3, 172, :_reduce_45, + 3, 172, :_reduce_46, + 2, 172, :_reduce_47, + 1, 172, :_reduce_none, + 1, 160, :_reduce_none, + 1, 163, :_reduce_none, + 1, 163, :_reduce_none, + 1, 177, :_reduce_none, + 4, 177, :_reduce_53, + 0, 185, :_reduce_54, + 5, 182, :_reduce_55, + 1, 184, :_reduce_none, + 2, 176, :_reduce_57, + 3, 176, :_reduce_58, + 4, 176, :_reduce_59, + 5, 176, :_reduce_60, + 4, 176, :_reduce_61, + 5, 176, :_reduce_62, + 2, 176, :_reduce_63, + 2, 176, :_reduce_64, + 2, 176, :_reduce_65, + 2, 176, :_reduce_66, + 2, 176, :_reduce_67, + 1, 162, :_reduce_68, + 3, 162, :_reduce_69, + 1, 189, :_reduce_70, + 3, 189, :_reduce_71, + 1, 188, :_reduce_none, + 2, 188, :_reduce_73, + 3, 188, :_reduce_74, + 5, 188, :_reduce_75, + 2, 188, :_reduce_76, + 4, 188, :_reduce_77, + 2, 188, :_reduce_78, + 4, 188, :_reduce_79, + 1, 188, :_reduce_80, + 3, 188, :_reduce_81, + 1, 192, :_reduce_none, + 3, 192, :_reduce_83, + 2, 191, :_reduce_84, + 3, 191, :_reduce_85, + 1, 194, :_reduce_86, + 3, 194, :_reduce_87, + 1, 193, :_reduce_88, + 1, 193, :_reduce_89, + 4, 193, :_reduce_90, + 3, 193, :_reduce_91, + 3, 193, :_reduce_92, + 3, 193, :_reduce_93, + 3, 193, :_reduce_94, + 2, 193, :_reduce_95, + 1, 193, :_reduce_96, + 1, 169, :_reduce_97, + 1, 169, :_reduce_98, + 4, 169, :_reduce_99, + 3, 169, :_reduce_100, + 3, 169, :_reduce_101, + 3, 169, :_reduce_102, + 3, 169, :_reduce_103, + 2, 169, :_reduce_104, + 1, 169, :_reduce_105, + 1, 197, :_reduce_106, + 1, 197, :_reduce_none, + 2, 198, :_reduce_108, + 1, 198, :_reduce_109, + 3, 198, :_reduce_110, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 202, :_reduce_116, + 1, 202, :_reduce_none, + 1, 158, :_reduce_none, + 1, 158, :_reduce_none, + 1, 159, :_reduce_120, + 0, 205, :_reduce_121, + 4, 159, :_reduce_122, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 3, 175, :_reduce_194, + 5, 175, :_reduce_195, + 3, 175, :_reduce_196, + 5, 175, :_reduce_197, + 6, 175, :_reduce_198, + 5, 175, :_reduce_199, + 5, 175, :_reduce_200, + 5, 175, :_reduce_201, + 5, 175, :_reduce_202, + 4, 175, :_reduce_203, + 3, 175, :_reduce_204, + 3, 175, :_reduce_205, + 3, 175, :_reduce_206, + 3, 175, :_reduce_207, + 3, 175, :_reduce_208, + 3, 175, :_reduce_209, + 3, 175, :_reduce_210, + 3, 175, :_reduce_211, + 3, 175, :_reduce_212, + 4, 175, :_reduce_213, + 2, 175, :_reduce_214, + 2, 175, :_reduce_215, + 3, 175, :_reduce_216, + 3, 175, :_reduce_217, + 3, 175, :_reduce_218, + 3, 175, :_reduce_219, + 3, 175, :_reduce_220, + 3, 175, :_reduce_221, + 3, 175, :_reduce_222, + 3, 175, :_reduce_223, + 3, 175, :_reduce_224, + 3, 175, :_reduce_225, + 3, 175, :_reduce_226, + 3, 175, :_reduce_227, + 3, 175, :_reduce_228, + 2, 175, :_reduce_229, + 2, 175, :_reduce_230, + 3, 175, :_reduce_231, + 3, 175, :_reduce_232, + 3, 175, :_reduce_233, + 3, 175, :_reduce_234, + 3, 175, :_reduce_235, + 6, 175, :_reduce_236, + 1, 175, :_reduce_none, + 1, 208, :_reduce_none, + 1, 209, :_reduce_none, + 2, 209, :_reduce_none, + 4, 209, :_reduce_241, + 2, 209, :_reduce_242, + 3, 214, :_reduce_243, + 0, 215, :_reduce_244, + 1, 215, :_reduce_none, + 0, 166, :_reduce_246, + 1, 166, :_reduce_none, + 2, 166, :_reduce_none, + 4, 166, :_reduce_249, + 2, 166, :_reduce_250, + 1, 187, :_reduce_251, + 2, 187, :_reduce_252, + 2, 187, :_reduce_253, + 4, 187, :_reduce_254, + 1, 187, :_reduce_255, + 0, 218, :_reduce_256, + 2, 181, :_reduce_257, + 2, 217, :_reduce_258, + 2, 216, :_reduce_259, + 0, 216, :_reduce_260, + 1, 211, :_reduce_261, + 2, 211, :_reduce_262, + 3, 211, :_reduce_263, + 4, 211, :_reduce_264, + 1, 171, :_reduce_265, + 1, 171, :_reduce_none, + 3, 170, :_reduce_267, + 4, 170, :_reduce_268, + 2, 170, :_reduce_269, + 1, 207, :_reduce_none, + 1, 207, :_reduce_none, + 1, 207, :_reduce_none, + 1, 207, :_reduce_none, + 1, 207, :_reduce_none, + 1, 207, :_reduce_none, + 1, 207, :_reduce_none, + 1, 207, :_reduce_none, + 1, 207, :_reduce_none, + 1, 207, :_reduce_none, + 1, 207, :_reduce_280, + 0, 243, :_reduce_281, + 4, 207, :_reduce_282, + 0, 244, :_reduce_283, + 0, 245, :_reduce_284, + 6, 207, :_reduce_285, + 0, 246, :_reduce_286, + 4, 207, :_reduce_287, + 3, 207, :_reduce_288, + 3, 207, :_reduce_289, + 2, 207, :_reduce_290, + 3, 207, :_reduce_291, + 3, 207, :_reduce_292, + 1, 207, :_reduce_293, + 4, 207, :_reduce_294, + 3, 207, :_reduce_295, + 1, 207, :_reduce_296, + 5, 207, :_reduce_297, + 4, 207, :_reduce_298, + 3, 207, :_reduce_299, + 2, 207, :_reduce_300, + 1, 207, :_reduce_none, + 2, 207, :_reduce_302, + 0, 247, :_reduce_303, + 3, 207, :_reduce_304, + 6, 207, :_reduce_305, + 6, 207, :_reduce_306, + 0, 248, :_reduce_307, + 0, 249, :_reduce_308, + 7, 207, :_reduce_309, + 0, 250, :_reduce_310, + 0, 251, :_reduce_311, + 7, 207, :_reduce_312, + 5, 207, :_reduce_313, + 4, 207, :_reduce_314, + 0, 252, :_reduce_315, + 0, 253, :_reduce_316, + 9, 207, :_reduce_317, + 0, 254, :_reduce_318, + 6, 207, :_reduce_319, + 0, 255, :_reduce_320, + 7, 207, :_reduce_321, + 0, 256, :_reduce_322, + 5, 207, :_reduce_323, + 0, 257, :_reduce_324, + 6, 207, :_reduce_325, + 0, 258, :_reduce_326, + 0, 259, :_reduce_327, + 9, 207, :_reduce_328, + 1, 207, :_reduce_329, + 1, 207, :_reduce_330, + 1, 207, :_reduce_331, + 1, 207, :_reduce_332, + 1, 165, :_reduce_none, + 1, 237, :_reduce_334, + 1, 240, :_reduce_335, + 1, 232, :_reduce_none, + 1, 232, :_reduce_none, + 2, 232, :_reduce_338, + 1, 234, :_reduce_none, + 1, 234, :_reduce_none, + 1, 233, :_reduce_none, + 5, 233, :_reduce_342, + 1, 154, :_reduce_none, + 2, 154, :_reduce_344, + 1, 236, :_reduce_none, + 1, 236, :_reduce_none, + 1, 260, :_reduce_347, + 3, 260, :_reduce_348, + 1, 263, :_reduce_349, + 3, 263, :_reduce_350, + 1, 262, :_reduce_none, + 4, 262, :_reduce_352, + 6, 262, :_reduce_353, + 3, 262, :_reduce_354, + 5, 262, :_reduce_355, + 2, 262, :_reduce_356, + 4, 262, :_reduce_357, + 1, 262, :_reduce_358, + 3, 262, :_reduce_359, + 4, 264, :_reduce_360, + 2, 264, :_reduce_361, + 2, 264, :_reduce_362, + 1, 264, :_reduce_363, + 2, 269, :_reduce_364, + 0, 269, :_reduce_365, + 6, 270, :_reduce_366, + 8, 270, :_reduce_367, + 4, 270, :_reduce_368, + 6, 270, :_reduce_369, + 4, 270, :_reduce_370, + 2, 270, :_reduce_none, + 6, 270, :_reduce_372, + 2, 270, :_reduce_373, + 4, 270, :_reduce_374, + 6, 270, :_reduce_375, + 2, 270, :_reduce_376, + 4, 270, :_reduce_377, + 2, 270, :_reduce_378, + 4, 270, :_reduce_379, + 1, 270, :_reduce_none, + 0, 183, :_reduce_381, + 1, 183, :_reduce_382, + 3, 274, :_reduce_383, + 1, 274, :_reduce_384, + 4, 274, :_reduce_385, + 1, 275, :_reduce_386, + 4, 275, :_reduce_387, + 1, 276, :_reduce_388, + 3, 276, :_reduce_389, + 1, 277, :_reduce_390, + 1, 277, :_reduce_none, + 0, 281, :_reduce_392, + 0, 282, :_reduce_393, + 4, 231, :_reduce_394, + 4, 279, :_reduce_395, + 1, 279, :_reduce_396, + 0, 285, :_reduce_397, + 4, 280, :_reduce_398, + 0, 286, :_reduce_399, + 4, 280, :_reduce_400, + 0, 287, :_reduce_401, + 5, 284, :_reduce_402, + 2, 178, :_reduce_403, + 4, 178, :_reduce_404, + 5, 178, :_reduce_405, + 5, 178, :_reduce_406, + 2, 230, :_reduce_407, + 4, 230, :_reduce_408, + 4, 230, :_reduce_409, + 3, 230, :_reduce_410, + 3, 230, :_reduce_411, + 3, 230, :_reduce_412, + 2, 230, :_reduce_413, + 1, 230, :_reduce_414, + 4, 230, :_reduce_415, + 0, 289, :_reduce_416, + 5, 229, :_reduce_417, + 0, 290, :_reduce_418, + 5, 229, :_reduce_419, + 5, 235, :_reduce_420, + 1, 291, :_reduce_421, + 1, 291, :_reduce_none, + 6, 153, :_reduce_423, + 0, 153, :_reduce_424, + 1, 292, :_reduce_425, + 1, 292, :_reduce_none, + 1, 292, :_reduce_none, + 2, 293, :_reduce_428, + 1, 293, :_reduce_none, + 2, 155, :_reduce_430, + 1, 155, :_reduce_none, + 1, 219, :_reduce_none, + 1, 219, :_reduce_none, + 1, 219, :_reduce_none, + 1, 220, :_reduce_435, + 1, 295, :_reduce_436, + 2, 295, :_reduce_437, + 3, 296, :_reduce_438, + 1, 296, :_reduce_439, + 1, 296, :_reduce_440, + 3, 221, :_reduce_441, + 4, 222, :_reduce_442, + 3, 223, :_reduce_443, + 0, 300, :_reduce_444, + 3, 300, :_reduce_445, + 1, 301, :_reduce_446, + 2, 301, :_reduce_447, + 3, 225, :_reduce_448, + 0, 303, :_reduce_449, + 3, 303, :_reduce_450, + 3, 224, :_reduce_451, + 3, 226, :_reduce_452, + 0, 304, :_reduce_453, + 3, 304, :_reduce_454, + 0, 305, :_reduce_455, + 3, 305, :_reduce_456, + 0, 297, :_reduce_457, + 2, 297, :_reduce_458, + 0, 298, :_reduce_459, + 2, 298, :_reduce_460, + 0, 299, :_reduce_461, + 2, 299, :_reduce_462, + 1, 302, :_reduce_463, + 2, 302, :_reduce_464, + 0, 307, :_reduce_465, + 4, 302, :_reduce_466, + 1, 306, :_reduce_467, + 1, 306, :_reduce_468, + 1, 306, :_reduce_469, + 1, 306, :_reduce_none, + 1, 203, :_reduce_471, + 3, 204, :_reduce_472, + 1, 294, :_reduce_473, + 2, 294, :_reduce_474, + 1, 206, :_reduce_475, + 1, 206, :_reduce_476, + 1, 206, :_reduce_477, + 1, 206, :_reduce_478, + 1, 195, :_reduce_479, + 1, 195, :_reduce_480, + 1, 195, :_reduce_481, + 1, 195, :_reduce_482, + 1, 195, :_reduce_483, + 1, 196, :_reduce_484, + 1, 196, :_reduce_485, + 1, 196, :_reduce_486, + 1, 196, :_reduce_487, + 1, 196, :_reduce_488, + 1, 196, :_reduce_489, + 1, 196, :_reduce_490, + 1, 227, :_reduce_491, + 1, 227, :_reduce_492, + 1, 164, :_reduce_493, + 1, 164, :_reduce_494, + 1, 168, :_reduce_495, + 1, 168, :_reduce_496, + 1, 238, :_reduce_497, + 0, 308, :_reduce_498, + 4, 238, :_reduce_499, + 2, 238, :_reduce_500, + 3, 241, :_reduce_501, + 0, 310, :_reduce_502, + 3, 241, :_reduce_503, + 4, 309, :_reduce_504, + 2, 309, :_reduce_505, + 2, 309, :_reduce_506, + 1, 309, :_reduce_507, + 2, 312, :_reduce_508, + 0, 312, :_reduce_509, + 6, 283, :_reduce_510, + 8, 283, :_reduce_511, + 4, 283, :_reduce_512, + 6, 283, :_reduce_513, + 4, 283, :_reduce_514, + 6, 283, :_reduce_515, + 2, 283, :_reduce_516, + 4, 283, :_reduce_517, + 6, 283, :_reduce_518, + 2, 283, :_reduce_519, + 4, 283, :_reduce_520, + 2, 283, :_reduce_521, + 4, 283, :_reduce_522, + 1, 283, :_reduce_523, + 0, 283, :_reduce_524, + 1, 278, :_reduce_525, + 1, 278, :_reduce_526, + 1, 278, :_reduce_527, + 1, 278, :_reduce_528, + 1, 261, :_reduce_none, + 1, 261, :_reduce_530, + 1, 314, :_reduce_531, + 3, 314, :_reduce_532, + 1, 271, :_reduce_533, + 3, 271, :_reduce_534, + 1, 315, :_reduce_535, + 2, 316, :_reduce_536, + 1, 316, :_reduce_537, + 2, 317, :_reduce_538, + 1, 317, :_reduce_539, + 1, 265, :_reduce_540, + 3, 265, :_reduce_541, + 1, 311, :_reduce_542, + 3, 311, :_reduce_543, + 1, 318, :_reduce_none, + 1, 318, :_reduce_none, + 2, 266, :_reduce_546, + 1, 266, :_reduce_547, + 3, 319, :_reduce_548, + 3, 320, :_reduce_549, + 1, 272, :_reduce_550, + 3, 272, :_reduce_551, + 1, 313, :_reduce_552, + 3, 313, :_reduce_553, + 1, 321, :_reduce_none, + 1, 321, :_reduce_none, + 2, 273, :_reduce_556, + 1, 273, :_reduce_557, + 1, 322, :_reduce_none, + 1, 322, :_reduce_none, + 2, 268, :_reduce_560, + 2, 267, :_reduce_561, + 0, 267, :_reduce_562, + 1, 242, :_reduce_none, + 3, 242, :_reduce_564, + 0, 228, :_reduce_565, + 2, 228, :_reduce_none, + 1, 213, :_reduce_567, + 3, 213, :_reduce_568, + 3, 323, :_reduce_569, + 2, 323, :_reduce_570, + 2, 323, :_reduce_571, + 1, 186, :_reduce_none, + 1, 186, :_reduce_none, + 1, 186, :_reduce_none, + 1, 180, :_reduce_none, + 1, 180, :_reduce_none, + 1, 180, :_reduce_none, + 1, 180, :_reduce_none, + 1, 288, :_reduce_none, + 1, 288, :_reduce_none, + 1, 288, :_reduce_none, + 1, 179, :_reduce_none, + 1, 179, :_reduce_none, + 0, 147, :_reduce_none, + 1, 147, :_reduce_none, + 0, 174, :_reduce_none, + 1, 174, :_reduce_none, + 2, 190, :_reduce_588, + 2, 167, :_reduce_589, + 0, 212, :_reduce_none, + 1, 212, :_reduce_none, + 1, 212, :_reduce_none, + 1, 239, :_reduce_593, + 1, 239, :_reduce_none, + 1, 149, :_reduce_none, + 2, 149, :_reduce_none, + 0, 210, :_reduce_597 ] + +racc_reduce_n = 598 + +racc_shift_n = 1022 + +racc_token_table = { + false => 0, + :error => 1, + :kCLASS => 2, + :kMODULE => 3, + :kDEF => 4, + :kUNDEF => 5, + :kBEGIN => 6, + :kRESCUE => 7, + :kENSURE => 8, + :kEND => 9, + :kIF => 10, + :kUNLESS => 11, + :kTHEN => 12, + :kELSIF => 13, + :kELSE => 14, + :kCASE => 15, + :kWHEN => 16, + :kWHILE => 17, + :kUNTIL => 18, + :kFOR => 19, + :kBREAK => 20, + :kNEXT => 21, + :kREDO => 22, + :kRETRY => 23, + :kIN => 24, + :kDO => 25, + :kDO_COND => 26, + :kDO_BLOCK => 27, + :kDO_LAMBDA => 28, + :kRETURN => 29, + :kYIELD => 30, + :kSUPER => 31, + :kSELF => 32, + :kNIL => 33, + :kTRUE => 34, + :kFALSE => 35, + :kAND => 36, + :kOR => 37, + :kNOT => 38, + :kIF_MOD => 39, + :kUNLESS_MOD => 40, + :kWHILE_MOD => 41, + :kUNTIL_MOD => 42, + :kRESCUE_MOD => 43, + :kALIAS => 44, + :kDEFINED => 45, + :klBEGIN => 46, + :klEND => 47, + :k__LINE__ => 48, + :k__FILE__ => 49, + :k__ENCODING__ => 50, + :tIDENTIFIER => 51, + :tFID => 52, + :tGVAR => 53, + :tIVAR => 54, + :tCONSTANT => 55, + :tLABEL => 56, + :tCVAR => 57, + :tNTH_REF => 58, + :tBACK_REF => 59, + :tSTRING_CONTENT => 60, + :tINTEGER => 61, + :tFLOAT => 62, + :tUPLUS => 63, + :tUMINUS => 64, + :tUNARY_NUM => 65, + :tPOW => 66, + :tCMP => 67, + :tEQ => 68, + :tEQQ => 69, + :tNEQ => 70, + :tGEQ => 71, + :tLEQ => 72, + :tANDOP => 73, + :tOROP => 74, + :tMATCH => 75, + :tNMATCH => 76, + :tDOT => 77, + :tDOT2 => 78, + :tDOT3 => 79, + :tAREF => 80, + :tASET => 81, + :tLSHFT => 82, + :tRSHFT => 83, + :tCOLON2 => 84, + :tCOLON3 => 85, + :tOP_ASGN => 86, + :tASSOC => 87, + :tLPAREN => 88, + :tLPAREN2 => 89, + :tRPAREN => 90, + :tLPAREN_ARG => 91, + :tLBRACK => 92, + :tLBRACK2 => 93, + :tRBRACK => 94, + :tLBRACE => 95, + :tLBRACE_ARG => 96, + :tSTAR => 97, + :tSTAR2 => 98, + :tAMPER => 99, + :tAMPER2 => 100, + :tTILDE => 101, + :tPERCENT => 102, + :tDIVIDE => 103, + :tDSTAR => 104, + :tPLUS => 105, + :tMINUS => 106, + :tLT => 107, + :tGT => 108, + :tPIPE => 109, + :tBANG => 110, + :tCARET => 111, + :tLCURLY => 112, + :tRCURLY => 113, + :tBACK_REF2 => 114, + :tSYMBEG => 115, + :tSTRING_BEG => 116, + :tXSTRING_BEG => 117, + :tREGEXP_BEG => 118, + :tREGEXP_OPT => 119, + :tWORDS_BEG => 120, + :tQWORDS_BEG => 121, + :tSYMBOLS_BEG => 122, + :tQSYMBOLS_BEG => 123, + :tSTRING_DBEG => 124, + :tSTRING_DVAR => 125, + :tSTRING_END => 126, + :tSTRING_DEND => 127, + :tSTRING => 128, + :tSYMBOL => 129, + :tNL => 130, + :tEH => 131, + :tCOLON => 132, + :tCOMMA => 133, + :tSPACE => 134, + :tSEMI => 135, + :tLAMBDA => 136, + :tLAMBEG => 137, + :tCHARACTER => 138, + :tRATIONAL => 139, + :tIMAGINARY => 140, + :tEQL => 141, + :tLOWEST => 142 } + +racc_nt_base = 143 + +racc_use_result_var = true + +Racc_arg = [ + racc_action_table, + racc_action_check, + racc_action_default, + racc_action_pointer, + racc_goto_table, + racc_goto_check, + racc_goto_default, + racc_goto_pointer, + racc_nt_base, + racc_reduce_table, + racc_token_table, + racc_shift_n, + racc_reduce_n, + racc_use_result_var ] +Ractor.make_shareable(Racc_arg) if defined?(Ractor) + +Racc_token_to_s_table = [ + "$end", + "error", + "kCLASS", + "kMODULE", + "kDEF", + "kUNDEF", + "kBEGIN", + "kRESCUE", + "kENSURE", + "kEND", + "kIF", + "kUNLESS", + "kTHEN", + "kELSIF", + "kELSE", + "kCASE", + "kWHEN", + "kWHILE", + "kUNTIL", + "kFOR", + "kBREAK", + "kNEXT", + "kREDO", + "kRETRY", + "kIN", + "kDO", + "kDO_COND", + "kDO_BLOCK", + "kDO_LAMBDA", + "kRETURN", + "kYIELD", + "kSUPER", + "kSELF", + "kNIL", + "kTRUE", + "kFALSE", + "kAND", + "kOR", + "kNOT", + "kIF_MOD", + "kUNLESS_MOD", + "kWHILE_MOD", + "kUNTIL_MOD", + "kRESCUE_MOD", + "kALIAS", + "kDEFINED", + "klBEGIN", + "klEND", + "k__LINE__", + "k__FILE__", + "k__ENCODING__", + "tIDENTIFIER", + "tFID", + "tGVAR", + "tIVAR", + "tCONSTANT", + "tLABEL", + "tCVAR", + "tNTH_REF", + "tBACK_REF", + "tSTRING_CONTENT", + "tINTEGER", + "tFLOAT", + "tUPLUS", + "tUMINUS", + "tUNARY_NUM", + "tPOW", + "tCMP", + "tEQ", + "tEQQ", + "tNEQ", + "tGEQ", + "tLEQ", + "tANDOP", + "tOROP", + "tMATCH", + "tNMATCH", + "tDOT", + "tDOT2", + "tDOT3", + "tAREF", + "tASET", + "tLSHFT", + "tRSHFT", + "tCOLON2", + "tCOLON3", + "tOP_ASGN", + "tASSOC", + "tLPAREN", + "tLPAREN2", + "tRPAREN", + "tLPAREN_ARG", + "tLBRACK", + "tLBRACK2", + "tRBRACK", + "tLBRACE", + "tLBRACE_ARG", + "tSTAR", + "tSTAR2", + "tAMPER", + "tAMPER2", + "tTILDE", + "tPERCENT", + "tDIVIDE", + "tDSTAR", + "tPLUS", + "tMINUS", + "tLT", + "tGT", + "tPIPE", + "tBANG", + "tCARET", + "tLCURLY", + "tRCURLY", + "tBACK_REF2", + "tSYMBEG", + "tSTRING_BEG", + "tXSTRING_BEG", + "tREGEXP_BEG", + "tREGEXP_OPT", + "tWORDS_BEG", + "tQWORDS_BEG", + "tSYMBOLS_BEG", + "tQSYMBOLS_BEG", + "tSTRING_DBEG", + "tSTRING_DVAR", + "tSTRING_END", + "tSTRING_DEND", + "tSTRING", + "tSYMBOL", + "tNL", + "tEH", + "tCOLON", + "tCOMMA", + "tSPACE", + "tSEMI", + "tLAMBDA", + "tLAMBEG", + "tCHARACTER", + "tRATIONAL", + "tIMAGINARY", + "tEQL", + "tLOWEST", + "$start", + "program", + "top_compstmt", + "top_stmts", + "opt_terms", + "top_stmt", + "terms", + "stmt", + "bodystmt", + "compstmt", + "opt_rescue", + "opt_else", + "opt_ensure", + "stmts", + "stmt_or_begin", + "fitem", + "undef_list", + "expr_value", + "command_asgn", + "mlhs", + "command_call", + "var_lhs", + "primary_value", + "opt_call_args", + "rbracket", + "backref", + "lhs", + "mrhs", + "mrhs_arg", + "expr", + "@1", + "opt_nl", + "arg", + "command", + "block_command", + "block_call", + "dot_or_colon", + "operation2", + "command_args", + "cmd_brace_block", + "opt_block_param", + "fcall", + "@2", + "operation", + "call_args", + "mlhs_basic", + "mlhs_inner", + "rparen", + "mlhs_head", + "mlhs_item", + "mlhs_node", + "mlhs_post", + "user_variable", + "keyword_variable", + "cname", + "cpath", + "fname", + "op", + "reswords", + "fsym", + "symbol", + "dsym", + "@3", + "simple_numeric", + "primary", + "arg_value", + "aref_args", + "none", + "args", + "trailer", + "assocs", + "paren_args", + "opt_paren_args", + "opt_block_arg", + "block_arg", + "@4", + "literal", + "strings", + "xstring", + "regexp", + "words", + "qwords", + "symbols", + "qsymbols", + "var_ref", + "assoc_list", + "brace_block", + "method_call", + "lambda", + "then", + "if_tail", + "do", + "case_body", + "for_var", + "k_class", + "superclass", + "term", + "k_module", + "f_arglist", + "singleton", + "@5", + "@6", + "@7", + "@8", + "@9", + "@10", + "@11", + "@12", + "@13", + "@14", + "@15", + "@16", + "@17", + "@18", + "@19", + "@20", + "@21", + "f_marg", + "f_norm_arg", + "f_margs", + "f_marg_list", + "block_args_tail", + "f_block_kwarg", + "f_kwrest", + "opt_f_block_arg", + "f_block_arg", + "opt_block_args_tail", + "block_param", + "f_arg", + "f_block_optarg", + "f_rest_arg", + "block_param_def", + "opt_bv_decl", + "bv_decls", + "bvar", + "f_bad_arg", + "f_larglist", + "lambda_body", + "@22", + "@23", + "f_args", + "do_block", + "@24", + "@25", + "@26", + "operation3", + "@27", + "@28", + "cases", + "exc_list", + "exc_var", + "numeric", + "string", + "string1", + "string_contents", + "xstring_contents", + "regexp_contents", + "word_list", + "word", + "string_content", + "symbol_list", + "qword_list", + "qsym_list", + "string_dvar", + "@29", + "@30", + "args_tail", + "@31", + "f_kwarg", + "opt_args_tail", + "f_optarg", + "f_arg_item", + "f_label", + "f_kw", + "f_block_kw", + "kwrest_mark", + "f_opt", + "f_block_opt", + "restarg_mark", + "blkarg_mark", + "assoc" ] +Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) + +Racc_debug_parser = false + +##### State transition tables end ##### + +# reduce 0 omitted + +# reduce 1 omitted + +def _reduce_2(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_3(val, _values, result) + result = [] + + result +end + +def _reduce_4(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_5(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_6(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 7 omitted + +def _reduce_8(val, _values, result) + result = @builder.preexe(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_9(val, _values, result) + rescue_bodies = val[1] + else_t, else_ = val[2] + ensure_t, ensure_ = val[3] + + if rescue_bodies.empty? && !else_t.nil? + diagnostic :warning, :useless_else, nil, else_t + end + + result = @builder.begin_body(val[0], + rescue_bodies, + else_t, else_, + ensure_t, ensure_) + + result +end + +def _reduce_10(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_11(val, _values, result) + result = [] + + result +end + +def _reduce_12(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_13(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_14(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 15 omitted + +def _reduce_16(val, _values, result) + diagnostic :error, :begin_in_method, nil, val[0] + + result +end + +def _reduce_17(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_18(val, _values, result) + result = @builder.alias(val[0], val[1], val[3]) + + result +end + +def _reduce_19(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.gvar(val[2])) + + result +end + +def _reduce_20(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.back_ref(val[2])) + + result +end + +def _reduce_21(val, _values, result) + diagnostic :error, :nth_ref_alias, nil, val[2] + + result +end + +def _reduce_22(val, _values, result) + result = @builder.undef_method(val[0], val[1]) + + result +end + +def _reduce_23(val, _values, result) + result = @builder.condition_mod(val[0], nil, + val[1], val[2]) + + result +end + +def _reduce_24(val, _values, result) + result = @builder.condition_mod(nil, val[0], + val[1], val[2]) + + result +end + +def _reduce_25(val, _values, result) + result = @builder.loop_mod(:while, val[0], val[1], val[2]) + + result +end + +def _reduce_26(val, _values, result) + result = @builder.loop_mod(:until, val[0], val[1], val[2]) + + result +end + +def _reduce_27(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_28(val, _values, result) + result = @builder.postexe(val[0], val[1], val[2], val[3]) + + result +end + +# reduce 29 omitted + +def _reduce_30(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_31(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_32(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_33(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_34(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_35(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_36(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_37(val, _values, result) + @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_38(val, _values, result) + result = @builder.assign(val[0], val[1], + @builder.array(nil, val[2], nil)) + + result +end + +def _reduce_39(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +# reduce 40 omitted + +def _reduce_41(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_42(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +# reduce 43 omitted + +def _reduce_44(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_45(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_46(val, _values, result) + result = @builder.not_op(val[0], nil, val[2], nil) + + result +end + +def _reduce_47(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +# reduce 48 omitted + +# reduce 49 omitted + +# reduce 50 omitted + +# reduce 51 omitted + +# reduce 52 omitted + +def _reduce_53(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_54(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_55(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +# reduce 56 omitted + +def _reduce_57(val, _values, result) + result = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + result +end + +def _reduce_58(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + begin_t, args, body, end_t = val[2] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_59(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_60(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_61(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_62(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_63(val, _values, result) + result = @builder.keyword_cmd(:super, val[0], + nil, val[1], nil) + + result +end + +def _reduce_64(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], + nil, val[1], nil) + + result +end + +def _reduce_65(val, _values, result) + result = @builder.keyword_cmd(:return, val[0], + nil, val[1], nil) + + result +end + +def _reduce_66(val, _values, result) + result = @builder.keyword_cmd(:break, val[0], + nil, val[1], nil) + + result +end + +def _reduce_67(val, _values, result) + result = @builder.keyword_cmd(:next, val[0], + nil, val[1], nil) + + result +end + +def _reduce_68(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_69(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_70(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_71(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +# reduce 72 omitted + +def _reduce_73(val, _values, result) + result = val[0]. + push(val[1]) + + result +end + +def _reduce_74(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])) + + result +end + +def _reduce_75(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])). + concat(val[4]) + + result +end + +def _reduce_76(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])) + + result +end + +def _reduce_77(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])). + concat(val[3]) + + result +end + +def _reduce_78(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_79(val, _values, result) + result = [ @builder.splat(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_80(val, _values, result) + result = [ @builder.splat(val[0]) ] + + result +end + +def _reduce_81(val, _values, result) + result = [ @builder.splat(val[0]), + *val[2] ] + + result +end + +# reduce 82 omitted + +def _reduce_83(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_84(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_85(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_86(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_87(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_88(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_89(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_90(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_91(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_92(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_93(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_94(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_95(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_96(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_97(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_98(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_99(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_100(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_101(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_102(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_103(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_104(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_105(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_106(val, _values, result) + diagnostic :error, :module_name_const, nil, val[0] + + result +end + +# reduce 107 omitted + +def _reduce_108(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_109(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_110(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +# reduce 111 omitted + +# reduce 112 omitted + +# reduce 113 omitted + +# reduce 114 omitted + +# reduce 115 omitted + +def _reduce_116(val, _values, result) + result = @builder.symbol_internal(val[0]) + + result +end + +# reduce 117 omitted + +# reduce 118 omitted + +# reduce 119 omitted + +def _reduce_120(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_121(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_122(val, _values, result) + result = val[0] << val[3] + + result +end + +# reduce 123 omitted + +# reduce 124 omitted + +# reduce 125 omitted + +# reduce 126 omitted + +# reduce 127 omitted + +# reduce 128 omitted + +# reduce 129 omitted + +# reduce 130 omitted + +# reduce 131 omitted + +# reduce 132 omitted + +# reduce 133 omitted + +# reduce 134 omitted + +# reduce 135 omitted + +# reduce 136 omitted + +# reduce 137 omitted + +# reduce 138 omitted + +# reduce 139 omitted + +# reduce 140 omitted + +# reduce 141 omitted + +# reduce 142 omitted + +# reduce 143 omitted + +# reduce 144 omitted + +# reduce 145 omitted + +# reduce 146 omitted + +# reduce 147 omitted + +# reduce 148 omitted + +# reduce 149 omitted + +# reduce 150 omitted + +# reduce 151 omitted + +# reduce 152 omitted + +# reduce 153 omitted + +# reduce 154 omitted + +# reduce 155 omitted + +# reduce 156 omitted + +# reduce 157 omitted + +# reduce 158 omitted + +# reduce 159 omitted + +# reduce 160 omitted + +# reduce 161 omitted + +# reduce 162 omitted + +# reduce 163 omitted + +# reduce 164 omitted + +# reduce 165 omitted + +# reduce 166 omitted + +# reduce 167 omitted + +# reduce 168 omitted + +# reduce 169 omitted + +# reduce 170 omitted + +# reduce 171 omitted + +# reduce 172 omitted + +# reduce 173 omitted + +# reduce 174 omitted + +# reduce 175 omitted + +# reduce 176 omitted + +# reduce 177 omitted + +# reduce 178 omitted + +# reduce 179 omitted + +# reduce 180 omitted + +# reduce 181 omitted + +# reduce 182 omitted + +# reduce 183 omitted + +# reduce 184 omitted + +# reduce 185 omitted + +# reduce 186 omitted + +# reduce 187 omitted + +# reduce 188 omitted + +# reduce 189 omitted + +# reduce 190 omitted + +# reduce 191 omitted + +# reduce 192 omitted + +# reduce 193 omitted + +def _reduce_194(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_195(val, _values, result) + rescue_body = @builder.rescue_body(val[3], + nil, nil, nil, + nil, val[4]) + + rescue_ = @builder.begin_body(val[2], [ rescue_body ]) + + result = @builder.assign(val[0], val[1], rescue_) + + result +end + +def _reduce_196(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_197(val, _values, result) + rescue_body = @builder.rescue_body(val[3], + nil, nil, nil, + nil, val[4]) + + rescue_ = @builder.begin_body(val[2], [ rescue_body ]) + + result = @builder.op_assign(val[0], val[1], rescue_) + + result +end + +def _reduce_198(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_199(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_200(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_201(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_202(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_203(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_global(val[0], val[1])) + result = @builder.op_assign(const, val[2], val[3]) + + result +end + +def _reduce_204(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_205(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_206(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_207(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_208(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_209(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_210(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_211(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_212(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_213(val, _values, result) + result = @builder.unary_op(val[0], + @builder.binary_op( + val[1], val[2], val[3])) + + result +end + +def _reduce_214(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_215(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_216(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_217(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_218(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_219(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_220(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_221(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_222(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_223(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_224(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_225(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_226(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_227(val, _values, result) + result = @builder.match_op(val[0], val[1], val[2]) + + result +end + +def _reduce_228(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_229(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +def _reduce_230(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_231(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_232(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_233(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_234(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_235(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil) + + result +end + +def _reduce_236(val, _values, result) + result = @builder.ternary(val[0], val[1], + val[2], val[4], val[5]) + + result +end + +# reduce 237 omitted + +# reduce 238 omitted + +# reduce 239 omitted + +# reduce 240 omitted + +def _reduce_241(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_242(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +def _reduce_243(val, _values, result) + result = val + + result +end + +def _reduce_244(val, _values, result) + result = [ nil, [], nil ] + + result +end + +# reduce 245 omitted + +def _reduce_246(val, _values, result) + result = [] + + result +end + +# reduce 247 omitted + +# reduce 248 omitted + +def _reduce_249(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_250(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +def _reduce_251(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_252(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_253(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + result.concat(val[1]) + + result +end + +def _reduce_254(val, _values, result) + assocs = @builder.associate(nil, val[2], nil) + result = val[0] << assocs + result.concat(val[3]) + + result +end + +def _reduce_255(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_256(val, _values, result) + result = @lexer.cmdarg.dup + @lexer.cmdarg.push(true) + + result +end + +def _reduce_257(val, _values, result) + @lexer.cmdarg = val[0] + + result = val[1] + + result +end + +def _reduce_258(val, _values, result) + result = @builder.block_pass(val[0], val[1]) + + result +end + +def _reduce_259(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_260(val, _values, result) + result = [] + + result +end + +def _reduce_261(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_262(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_263(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_264(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_265(val, _values, result) + result = @builder.array(nil, val[0], nil) + + result +end + +# reduce 266 omitted + +def _reduce_267(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_268(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_269(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +# reduce 270 omitted + +# reduce 271 omitted + +# reduce 272 omitted + +# reduce 273 omitted + +# reduce 274 omitted + +# reduce 275 omitted + +# reduce 276 omitted + +# reduce 277 omitted + +# reduce 278 omitted + +# reduce 279 omitted + +def _reduce_280(val, _values, result) + result = @builder.call_method(nil, nil, val[0]) + + result +end + +def _reduce_281(val, _values, result) + result = @lexer.cmdarg.dup + @lexer.cmdarg.clear + + result +end + +def _reduce_282(val, _values, result) + @lexer.cmdarg = val[1] + + result = @builder.begin_keyword(val[0], val[2], val[3]) + + result +end + +def _reduce_283(val, _values, result) + result = @lexer.cmdarg.dup + @lexer.cmdarg.clear + + result +end + +def _reduce_284(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_285(val, _values, result) + @lexer.cmdarg = val[1] + + result = @builder.begin(val[0], val[2], val[5]) + + result +end + +def _reduce_286(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_287(val, _values, result) + result = @builder.begin(val[0], nil, val[3]) + + result +end + +def _reduce_288(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_289(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +def _reduce_290(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_291(val, _values, result) + result = @builder.array(val[0], val[1], val[2]) + + result +end + +def _reduce_292(val, _values, result) + result = @builder.associate(val[0], val[1], val[2]) + + result +end + +def _reduce_293(val, _values, result) + result = @builder.keyword_cmd(:return, val[0]) + + result +end + +def _reduce_294(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_295(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2]) + + result +end + +def _reduce_296(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0]) + + result +end + +def _reduce_297(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], + val[2], [ val[3] ], val[4]) + + result +end + +def _reduce_298(val, _values, result) + result = @builder.not_op(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_299(val, _values, result) + result = @builder.not_op(val[0], val[1], nil, val[2]) + + result +end + +def _reduce_300(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0]) + + begin_t, args, body, end_t = val[1] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +# reduce 301 omitted + +def _reduce_302(val, _values, result) + begin_t, args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, args, body, end_t) + + result +end + +def _reduce_303(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_304(val, _values, result) + lambda_call = @builder.call_lambda(val[0]) + + args, (begin_t, body, end_t) = val[2] + result = @builder.block(lambda_call, + begin_t, args, body, end_t) + + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_305(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, val[5]) + + result +end + +def _reduce_306(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + else_, else_t, + val[3], val[5]) + + result +end + +def _reduce_307(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_308(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_309(val, _values, result) + result = @builder.loop(:while, val[0], val[2], val[3], + val[5], val[6]) + + result +end + +def _reduce_310(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_311(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_312(val, _values, result) + result = @builder.loop(:until, val[0], val[2], val[3], + val[5], val[6]) + + result +end + +def _reduce_313(val, _values, result) + *when_bodies, (else_t, else_body) = *val[3] + + result = @builder.case(val[0], val[1], + when_bodies, else_t, else_body, + val[4]) + + result +end + +def _reduce_314(val, _values, result) + *when_bodies, (else_t, else_body) = *val[2] + + result = @builder.case(val[0], nil, + when_bodies, else_t, else_body, + val[3]) + + result +end + +def _reduce_315(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_316(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_317(val, _values, result) + result = @builder.for(val[0], val[1], + val[2], val[4], + val[5], val[7], val[8]) + + result +end + +def _reduce_318(val, _values, result) + local_push + @context.in_class = true + + result +end + +def _reduce_319(val, _values, result) + k_class, ctx = val[0] + if @context.in_def + diagnostic :error, :class_in_def, nil, k_class + end + + lt_t, superclass = val[2] + result = @builder.def_class(k_class, val[1], + lt_t, superclass, + val[4], val[5]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_320(val, _values, result) + @context.in_def = false + @context.in_class = false + local_push + + result +end + +def _reduce_321(val, _values, result) + k_class, ctx = val[0] + result = @builder.def_sclass(k_class, val[1], val[2], + val[5], val[6]) + + local_pop + @context.in_def = ctx.in_def + @context.in_class = ctx.in_class + + result +end + +def _reduce_322(val, _values, result) + @context.in_class = true + local_push + + result +end + +def _reduce_323(val, _values, result) + k_mod, ctx = val[0] + if @context.in_def + diagnostic :error, :module_in_def, nil, k_mod + end + + result = @builder.def_module(k_mod, val[1], + val[3], val[4]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_324(val, _values, result) + local_push + result = context.dup + @context.in_def = true + + result +end + +def _reduce_325(val, _values, result) + result = @builder.def_method(val[0], val[1], + val[3], val[4], val[5]) + + local_pop + @context.in_def = val[2].in_def + + result +end + +def _reduce_326(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_327(val, _values, result) + local_push + result = context.dup + @context.in_def = true + + result +end + +def _reduce_328(val, _values, result) + result = @builder.def_singleton(val[0], val[1], val[2], + val[4], val[6], val[7], val[8]) + + local_pop + @context.in_def = val[5].in_def + + result +end + +def _reduce_329(val, _values, result) + result = @builder.keyword_cmd(:break, val[0]) + + result +end + +def _reduce_330(val, _values, result) + result = @builder.keyword_cmd(:next, val[0]) + + result +end + +def _reduce_331(val, _values, result) + result = @builder.keyword_cmd(:redo, val[0]) + + result +end + +def _reduce_332(val, _values, result) + result = @builder.keyword_cmd(:retry, val[0]) + + result +end + +# reduce 333 omitted + +def _reduce_334(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_335(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +# reduce 336 omitted + +# reduce 337 omitted + +def _reduce_338(val, _values, result) + result = val[1] + + result +end + +# reduce 339 omitted + +# reduce 340 omitted + +# reduce 341 omitted + +def _reduce_342(val, _values, result) + else_t, else_ = val[4] + result = [ val[0], + @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, nil), + ] + + result +end + +# reduce 343 omitted + +def _reduce_344(val, _values, result) + result = val + + result +end + +# reduce 345 omitted + +# reduce 346 omitted + +def _reduce_347(val, _values, result) + result = @builder.arg(val[0]) + + result +end + +def _reduce_348(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_349(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_350(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 351 omitted + +def _reduce_352(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2], val[3])) + + result +end + +def _reduce_353(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2], val[3])). + concat(val[5]) + + result +end + +def _reduce_354(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2])) + + result +end + +def _reduce_355(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2])). + concat(val[4]) + + result +end + +def _reduce_356(val, _values, result) + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_357(val, _values, result) + result = [ @builder.restarg(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_358(val, _values, result) + result = [ @builder.restarg(val[0]) ] + + result +end + +def _reduce_359(val, _values, result) + result = [ @builder.restarg(val[0]), + *val[2] ] + + result +end + +def _reduce_360(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_361(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_362(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_363(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_364(val, _values, result) + result = val[1] + + result +end + +def _reduce_365(val, _values, result) + result = [] + + result +end + +def _reduce_366(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_367(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_368(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_369(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_370(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 371 omitted + +def _reduce_372(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_373(val, _values, result) + if val[1].empty? && val[0].size == 1 + result = [@builder.procarg0(val[0][0])] + else + result = val[0].concat(val[1]) + end + + result +end + +def _reduce_374(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_375(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_376(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_377(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_378(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_379(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 380 omitted + +def _reduce_381(val, _values, result) + result = @builder.args(nil, [], nil) + + result +end + +def _reduce_382(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_383(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + result +end + +def _reduce_384(val, _values, result) + result = @builder.args(val[0], [], val[0]) + + result +end + +def _reduce_385(val, _values, result) + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_386(val, _values, result) + result = [] + + result +end + +def _reduce_387(val, _values, result) + result = val[2] + + result +end + +def _reduce_388(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_389(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_390(val, _values, result) + @static_env.declare val[0][0] + result = @builder.shadowarg(val[0]) + + result +end + +# reduce 391 omitted + +def _reduce_392(val, _values, result) + @static_env.extend_dynamic + + result +end + +def _reduce_393(val, _values, result) + result = @lexer.cmdarg.dup + @lexer.cmdarg.clear + + result +end + +def _reduce_394(val, _values, result) + @lexer.cmdarg = val[2] + @lexer.cmdarg.lexpop + + result = [ val[1], val[3] ] + + @static_env.unextend + + result +end + +def _reduce_395(val, _values, result) + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_396(val, _values, result) + result = @builder.args(nil, val[0], nil) + + result +end + +def _reduce_397(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_398(val, _values, result) + result = [ val[0], val[2], val[3] ] + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_399(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_400(val, _values, result) + result = [ val[0], val[2], val[3] ] + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_401(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_402(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_403(val, _values, result) + begin_t, block_args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, block_args, body, end_t) + + result +end + +def _reduce_404(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_405(val, _values, result) + lparen_t, args, rparen_t = val[3] + method_call = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_406(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_407(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.call_method(nil, nil, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_408(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_409(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_410(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2]) + + result +end + +def _reduce_411(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_412(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_413(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.keyword_cmd(:super, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_414(val, _values, result) + result = @builder.keyword_cmd(:zsuper, val[0]) + + result +end + +def _reduce_415(val, _values, result) + result = @builder.index(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_416(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_417(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_418(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_419(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_420(val, _values, result) + result = [ @builder.when(val[0], val[1], val[2], val[3]), + *val[4] ] + + result +end + +def _reduce_421(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 422 omitted + +def _reduce_423(val, _values, result) + assoc_t, exc_var = val[2] + + if val[1] + exc_list = @builder.array(nil, val[1], nil) + end + + result = [ @builder.rescue_body(val[0], + exc_list, assoc_t, exc_var, + val[3], val[4]), + *val[5] ] + + result +end + +def _reduce_424(val, _values, result) + result = [] + + result +end + +def _reduce_425(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 426 omitted + +# reduce 427 omitted + +def _reduce_428(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 429 omitted + +def _reduce_430(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 431 omitted + +# reduce 432 omitted + +# reduce 433 omitted + +# reduce 434 omitted + +def _reduce_435(val, _values, result) + result = @builder.string_compose(nil, val[0], nil) + + result +end + +def _reduce_436(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_437(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_438(val, _values, result) + result = @builder.string_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_439(val, _values, result) + result = @builder.string(val[0]) + + result +end + +def _reduce_440(val, _values, result) + result = @builder.character(val[0]) + + result +end + +def _reduce_441(val, _values, result) + result = @builder.xstring_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_442(val, _values, result) + opts = @builder.regexp_options(val[3]) + result = @builder.regexp_compose(val[0], val[1], val[2], opts) + + result +end + +def _reduce_443(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_444(val, _values, result) + result = [] + + result +end + +def _reduce_445(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_446(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_447(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_448(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_449(val, _values, result) + result = [] + + result +end + +def _reduce_450(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_451(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_452(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_453(val, _values, result) + result = [] + + result +end + +def _reduce_454(val, _values, result) + result = val[0] << @builder.string_internal(val[1]) + + result +end + +def _reduce_455(val, _values, result) + result = [] + + result +end + +def _reduce_456(val, _values, result) + result = val[0] << @builder.symbol_internal(val[1]) + + result +end + +def _reduce_457(val, _values, result) + result = [] + + result +end + +def _reduce_458(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_459(val, _values, result) + result = [] + + result +end + +def _reduce_460(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_461(val, _values, result) + result = [] + + result +end + +def _reduce_462(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_463(val, _values, result) + result = @builder.string_internal(val[0]) + + result +end + +def _reduce_464(val, _values, result) + result = val[1] + + result +end + +def _reduce_465(val, _values, result) + @lexer.cond.push(false) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_466(val, _values, result) + @lexer.cond.lexpop + @lexer.cmdarg.lexpop + + result = @builder.begin(val[0], val[2], val[3]) + + result +end + +def _reduce_467(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_468(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_469(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +# reduce 470 omitted + +def _reduce_471(val, _values, result) + result = @builder.symbol(val[0]) + + result +end + +def _reduce_472(val, _values, result) + result = @builder.symbol_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_473(val, _values, result) + result = val[0] + + result +end + +def _reduce_474(val, _values, result) + if @builder.respond_to? :negate + # AST builder interface compatibility + result = @builder.negate(val[0], val[1]) + else + result = @builder.unary_num(val[0], val[1]) + end + + result +end + +def _reduce_475(val, _values, result) + result = @builder.integer(val[0]) + + result +end + +def _reduce_476(val, _values, result) + result = @builder.float(val[0]) + + result +end + +def _reduce_477(val, _values, result) + result = @builder.rational(val[0]) + + result +end + +def _reduce_478(val, _values, result) + result = @builder.complex(val[0]) + + result +end + +def _reduce_479(val, _values, result) + result = @builder.ident(val[0]) + + result +end + +def _reduce_480(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_481(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_482(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_483(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +def _reduce_484(val, _values, result) + result = @builder.nil(val[0]) + + result +end + +def _reduce_485(val, _values, result) + result = @builder.self(val[0]) + + result +end + +def _reduce_486(val, _values, result) + result = @builder.true(val[0]) + + result +end + +def _reduce_487(val, _values, result) + result = @builder.false(val[0]) + + result +end + +def _reduce_488(val, _values, result) + result = @builder.__FILE__(val[0]) + + result +end + +def _reduce_489(val, _values, result) + result = @builder.__LINE__(val[0]) + + result +end + +def _reduce_490(val, _values, result) + result = @builder.__ENCODING__(val[0]) + + result +end + +def _reduce_491(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_492(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_493(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_494(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_495(val, _values, result) + result = @builder.nth_ref(val[0]) + + result +end + +def _reduce_496(val, _values, result) + result = @builder.back_ref(val[0]) + + result +end + +def _reduce_497(val, _values, result) + result = nil + + result +end + +def _reduce_498(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_499(val, _values, result) + result = [ val[0], val[2] ] + + result +end + +def _reduce_500(val, _values, result) + yyerrok + result = nil + + result +end + +def _reduce_501(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + @lexer.state = :expr_value + + result +end + +def _reduce_502(val, _values, result) + result = @context.in_kwarg + @context.in_kwarg = true + + result +end + +def _reduce_503(val, _values, result) + @context.in_kwarg = val[0] + result = @builder.args(nil, val[1], nil) + + result +end + +def _reduce_504(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_505(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_506(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_507(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_508(val, _values, result) + result = val[1] + + result +end + +def _reduce_509(val, _values, result) + result = [] + + result +end + +def _reduce_510(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_511(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_512(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_513(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_514(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_515(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_516(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_517(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_518(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_519(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_520(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_521(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_522(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_523(val, _values, result) + result = val[0] + + result +end + +def _reduce_524(val, _values, result) + result = [] + + result +end + +def _reduce_525(val, _values, result) + diagnostic :error, :argument_const, nil, val[0] + + result +end + +def _reduce_526(val, _values, result) + diagnostic :error, :argument_ivar, nil, val[0] + + result +end + +def _reduce_527(val, _values, result) + diagnostic :error, :argument_gvar, nil, val[0] + + result +end + +def _reduce_528(val, _values, result) + diagnostic :error, :argument_cvar, nil, val[0] + + result +end + +# reduce 529 omitted + +def _reduce_530(val, _values, result) + @static_env.declare val[0][0] + + result = val[0] + + result +end + +def _reduce_531(val, _values, result) + result = @builder.arg(val[0]) + + result +end + +def _reduce_532(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_533(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_534(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_535(val, _values, result) + check_kwarg_name(val[0]) + + @static_env.declare val[0][0] + + result = val[0] + + result +end + +def _reduce_536(val, _values, result) + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_537(val, _values, result) + result = @builder.kwarg(val[0]) + + result +end + +def _reduce_538(val, _values, result) + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_539(val, _values, result) + result = @builder.kwarg(val[0]) + + result +end + +def _reduce_540(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_541(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_542(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_543(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 544 omitted + +# reduce 545 omitted + +def _reduce_546(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.kwrestarg(val[0], val[1]) ] + + result +end + +def _reduce_547(val, _values, result) + result = [ @builder.kwrestarg(val[0]) ] + + result +end + +def _reduce_548(val, _values, result) + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_549(val, _values, result) + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_550(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_551(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_552(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_553(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 554 omitted + +# reduce 555 omitted + +def _reduce_556(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_557(val, _values, result) + result = [ @builder.restarg(val[0]) ] + + result +end + +# reduce 558 omitted + +# reduce 559 omitted + +def _reduce_560(val, _values, result) + @static_env.declare val[1][0] + + result = @builder.blockarg(val[0], val[1]) + + result +end + +def _reduce_561(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_562(val, _values, result) + result = [] + + result +end + +# reduce 563 omitted + +def _reduce_564(val, _values, result) + result = val[1] + + result +end + +def _reduce_565(val, _values, result) + result = [] + + result +end + +# reduce 566 omitted + +def _reduce_567(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_568(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_569(val, _values, result) + result = @builder.pair(val[0], val[1], val[2]) + + result +end + +def _reduce_570(val, _values, result) + result = @builder.pair_keyword(val[0], val[1]) + + result +end + +def _reduce_571(val, _values, result) + result = @builder.kwsplat(val[0], val[1]) + + result +end + +# reduce 572 omitted + +# reduce 573 omitted + +# reduce 574 omitted + +# reduce 575 omitted + +# reduce 576 omitted + +# reduce 577 omitted + +# reduce 578 omitted + +# reduce 579 omitted + +# reduce 580 omitted + +# reduce 581 omitted + +# reduce 582 omitted + +# reduce 583 omitted + +# reduce 584 omitted + +# reduce 585 omitted + +# reduce 586 omitted + +# reduce 587 omitted + +def _reduce_588(val, _values, result) + result = val[1] + + result +end + +def _reduce_589(val, _values, result) + result = val[1] + + result +end + +# reduce 590 omitted + +# reduce 591 omitted + +# reduce 592 omitted + +def _reduce_593(val, _values, result) + yyerrok + + result +end + +# reduce 594 omitted + +# reduce 595 omitted + +# reduce 596 omitted + +def _reduce_597(val, _values, result) + result = nil + + result +end + +def _reduce_none(val, _values, result) + val[0] +end + + end # class Ruby21 +end # module Parser diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby22.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby22.rb new file mode 100644 index 00000000..86c67b8c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby22.rb @@ -0,0 +1,10302 @@ +# -*- encoding:utf-8; warn-indent:false; frozen_string_literal: true -*- +# +# DO NOT MODIFY!!!! +# This file is automatically generated by Racc 1.8.1 +# from Racc grammar file "ruby22.y". +# + +require 'racc/parser.rb' + + +require_relative '../parser' + +module Parser + class Ruby22 < Parser::Base + + + def version + 22 + end + + def default_encoding + Encoding::UTF_8 + end + + def local_push + @static_env.extend_static + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + end + + def local_pop + @static_env.unextend + @lexer.cmdarg.pop + @lexer.cond.pop + end +##### State transition tables begin ### + +racc_action_table = [ + -479, 111, 270, 216, 217, -97, -98, -479, -479, -479, + 219, 538, -479, -479, -479, -286, -479, 270, 617, 580, + -83, 123, 216, 217, -479, 582, -479, -479, -479, -69, + 270, 786, 208, 544, -105, 559, -479, -479, 538, -479, + -479, -479, -479, -479, 538, 538, 216, 217, 538, -104, + -100, 220, -100, 616, -102, -286, 216, 217, 270, 550, + 216, 217, -493, 551, -102, 872, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + 209, 265, -479, -479, -479, 579, -479, -479, 695, 269, + -479, 581, 262, -479, -479, -99, -479, 220, -479, 263, + -479, -494, -479, -479, 269, -479, -479, -479, -479, -479, + -99, -479, -482, -479, -88, -89, 220, 269, -97, -482, + -482, -482, 265, -101, -482, -482, -482, -479, -482, 115, + -479, -479, -479, -479, 114, -479, -482, -479, -482, -482, + -482, 558, -479, -96, 695, 269, -101, 695, -482, -482, + 220, -482, -482, -482, -482, -482, 115, -98, -95, -91, + -91, 114, 115, 115, 115, 823, 115, 114, 114, 114, + -100, 114, -102, -93, 871, -100, 445, -102, -482, -482, + -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, + -482, -482, 115, 210, -482, -482, -482, 114, -482, -482, + -577, -93, -482, 215, -90, -482, -482, -103, -482, 259, + -482, -577, -482, 318, -482, -482, -574, -482, -482, -482, + -482, -482, -289, -482, 319, -482, -91, -479, -99, -289, + -289, -289, -105, -99, -479, -289, -289, 528, -289, -482, + 527, -101, -482, -482, -482, -482, -101, -482, 115, -482, + -575, 115, 617, 114, -482, -92, 114, 528, -289, -289, + 530, -289, -289, -289, -289, -289, -91, -93, -479, -91, + 214, 220, -578, 216, 217, -479, -493, 387, -91, 672, + -574, 669, 668, 667, -479, 670, 400, 616, -289, -289, + -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, + -289, -289, -482, -574, -289, -289, -289, -93, 600, -482, + -93, 617, -289, -494, -575, -289, -94, -96, -482, -93, + -289, 567, -289, -88, -289, -289, -105, -289, -289, -289, + -289, -289, -97, -289, -581, -289, 528, -575, 516, 530, + 750, -581, -581, -581, 93, 94, 616, -581, -581, -289, + -581, -482, -289, -289, 617, -94, 444, -289, -482, -581, + -89, 890, -581, 751, -103, 528, 446, 115, 530, -98, + -581, -581, 114, -581, -581, -581, -581, -581, 672, 447, + 669, 668, 667, 219, 670, 569, 568, 567, 516, 616, + 567, 478, 93, 94, -104, 727, -100, 487, 567, 489, + -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, + -581, -581, -581, -581, -581, 491, -581, -581, -581, -102, + 601, -581, 95, 96, -581, 499, -577, -581, 841, -415, + -581, -581, -581, 115, -581, -95, -581, -581, 114, -581, + -581, -581, -581, -581, -104, -581, -581, -581, 567, -581, + -68, 569, 568, 565, 569, 568, 565, 567, 216, 217, + 987, -581, 569, 568, -581, -581, -581, -92, 632, -581, + 95, 96, 729, -581, -581, -581, -101, 220, -581, -581, + -581, -415, -581, -581, -99, 818, 786, 502, -415, -489, + -581, -581, -581, -581, -581, -577, -489, -415, 220, -581, + 503, 972, -581, -581, 510, -581, -581, -581, -581, -581, + 115, 595, 569, 568, 570, 114, -415, 567, -581, -488, + 567, 569, 568, 572, 567, 397, -488, 688, 687, 274, + 399, 398, -581, -581, -581, -581, -581, -581, -581, -581, + -581, -581, -581, -581, -581, -581, 115, 212, -581, -581, + -581, 114, 752, -581, 213, 240, -581, 596, -91, -581, + -581, 220, -581, 211, -581, 736, -581, -100, -581, -581, + 265, -581, -581, -581, -581, -581, 513, -581, -581, -581, + 517, 569, 568, 574, 569, 568, 578, 237, 569, 568, + 583, 239, 238, -581, 235, 236, -581, -581, -581, -581, + 240, -581, -289, -581, -93, 818, 786, 677, -101, -289, + -289, -289, -90, -102, -289, -289, -289, 680, -289, 240, + 672, -99, 669, 668, 667, 220, 670, 240, -289, -289, + -289, 531, 237, -333, 81, 532, 239, 238, -289, -289, + -333, -289, -289, -289, -289, -289, 82, -490, 491, -333, + 688, 687, 544, -487, -490, 681, 83, 807, -484, 237, + -487, 389, 115, 239, 238, -484, 810, 114, -289, -289, + -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, + -289, -289, 548, 677, -289, -289, -289, 441, 753, -289, + -491, 549, -289, 680, 442, -289, -289, -491, -289, 584, + -289, 587, -289, 443, -289, -289, -491, -289, -289, -289, + -289, -289, -261, -289, 672, -289, 669, 668, 667, 672, + 670, 669, 668, 667, 589, 670, 688, 687, 220, -289, + 593, 681, -289, -289, -289, -289, -492, -289, 594, -289, + 265, 604, 607, -492, -103, 5, 74, 75, 71, 9, + 57, 807, -492, 115, 63, 64, 807, 240, 114, 67, + 810, 65, 66, 68, 30, 31, 72, 73, 118, 119, + 120, 121, 122, 29, 28, 27, 103, 102, 104, 105, + 721, 722, 19, 240, 723, 109, 110, 605, 8, 45, + 7, 10, 107, 106, 108, 97, 56, 99, 98, 100, + 240, 101, 109, 110, 240, 93, 94, 42, 43, 41, + 240, 244, 249, 250, 251, 246, 248, 256, 257, 252, + 253, 508, 233, 234, -279, 115, 254, 255, 509, 40, + 114, -279, 33, 220, 220, 58, 59, 507, 220, 60, + -279, 35, 237, -83, 243, 44, 239, 238, 636, 235, + 236, 247, 245, 241, 20, 242, 220, 521, 647, 91, + 81, 84, 85, 518, 86, 88, 87, 89, 652, -485, + 519, -486, 82, 90, 262, 258, -485, -238, -486, 443, + 62, 263, 83, 95, 96, 292, 74, 75, 71, 9, + 57, 653, 655, 546, 63, 64, 691, 544, 698, 67, + 547, 65, 66, 68, 30, 31, 72, 73, 716, 545, + 726, 730, 731, 29, 28, 27, 103, 102, 104, 105, + -262, 737, 19, 478, 478, 220, 755, 590, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + 259, 101, 109, 110, 489, 93, 94, 42, 43, 41, + 240, 244, 249, 250, 251, 246, 248, 256, 257, 252, + 253, 554, 233, 234, -290, 491, 254, 255, 553, 40, + 779, -290, 296, 647, 220, 58, 59, 555, 265, 60, + -290, 35, 237, 265, 243, 44, 239, 238, 647, 235, + 236, 247, 245, 241, 20, 242, 240, 786, 220, 91, + 81, 84, 85, -290, 86, 88, 87, 89, 795, 798, + -290, 799, 82, 90, 801, 258, 803, 805, 813, -290, + 62, 814, 83, 95, 96, 5, 74, 75, 71, 9, + 57, 815, 786, 554, 63, 64, 822, 220, 220, 67, + 923, 65, 66, 68, 30, 31, 72, 73, 831, 555, + -263, 840, 843, 29, 28, 27, 103, 102, 104, 105, + 798, 846, 19, 848, 850, 852, 220, 605, 8, 45, + 7, 10, 107, 106, 108, 97, 56, 99, 98, 100, + 854, 101, 109, 110, 855, 93, 94, 42, 43, 41, + 240, 244, 249, 250, 251, 246, 248, 256, 257, 252, + 253, -289, 233, 234, 554, 858, 254, 255, -289, 40, + 860, 923, 33, -578, 861, 58, 59, -289, 647, 60, + 555, 35, 237, 863, 243, 44, 239, 238, -261, 235, + 236, 247, 245, 241, 20, 242, 867, 869, 220, 91, + 81, 84, 85, -491, 86, 88, 87, 89, 888, 220, + -491, 892, 82, 90, 894, 258, 900, 903, 220, -491, + 62, 907, 83, 95, 96, 292, 74, 75, 71, 9, + 57, -264, 917, -492, 63, 64, 924, 925, 936, 67, + -492, 65, 66, 68, 30, 31, 72, 73, 798, -492, + 938, 940, 942, 29, 28, 27, 103, 102, 104, 105, + 944, 920, 19, 669, 668, 667, 944, 670, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + 220, 101, 109, 110, 950, 93, 94, 42, 43, 41, + 240, 244, 249, 250, 251, 246, 248, 256, 257, 252, + 253, -289, 233, 234, 977, 953, 254, 255, -289, 40, + 954, 978, 33, -578, 959, 58, 59, -289, 716, 60, + 976, 35, 237, 798, 243, 44, 239, 238, 962, 235, + 236, 247, 245, 241, 20, 242, 964, 966, 968, 91, + 81, 84, 85, -279, 86, 88, 87, 89, 968, 979, + -279, 989, 82, 90, -578, 258, -577, 652, 1004, -279, + 62, 1005, 83, 95, 96, 292, 74, 75, 71, 9, + 57, 1006, 944, -290, 63, 64, 944, 944, 1011, 67, + -290, 65, 66, 68, 30, 31, 72, 73, 989, -290, + 1014, 1015, 1016, 29, 28, 27, 103, 102, 104, 105, + 968, 920, 19, 669, 668, 667, 968, 670, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + 968, 101, 109, 110, 220, 93, 94, 42, 43, 41, + 240, 244, 249, 250, 251, 246, 248, 256, 257, 252, + 253, -289, 233, 234, 989, 944, 254, 255, -289, 40, + 989, 968, 33, -578, nil, 58, 59, -289, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, 247, 245, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, 258, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, 118, 119, + 120, 121, 122, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, 118, 119, 120, 121, 122, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, 244, 249, 250, 251, 246, 248, 256, 257, 252, + 253, nil, 233, 234, nil, nil, 254, 255, nil, 40, + nil, nil, 296, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, 247, 245, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, 258, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, 244, 249, 250, 251, 246, 248, 256, 257, 252, + 253, nil, 233, 234, nil, nil, 254, 255, nil, 40, + nil, nil, 296, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, 247, 245, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, 220, 258, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, 244, 249, 250, 251, 246, 248, 256, 257, 252, + 253, nil, 233, 234, nil, nil, 254, 255, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, 247, 245, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, 258, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 5, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 7, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, 244, 249, 250, 251, 246, 248, 256, 257, 252, + 253, nil, 233, 234, nil, nil, 254, 255, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, 247, 245, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, 258, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, 244, 249, 250, 251, 246, 248, 256, 257, 252, + 253, nil, 233, 234, nil, nil, 254, 255, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, 247, 245, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, 258, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, 244, 249, 250, 251, 246, 248, 256, 257, 252, + 253, nil, 233, 234, nil, nil, 254, 255, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, 247, 245, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, 258, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, 244, 249, 250, 251, 246, 248, 256, 257, 252, + 253, nil, 233, 234, nil, nil, 254, 255, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, 247, 245, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, 258, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, 244, 249, 250, 251, 246, 248, 256, 257, 252, + 253, nil, 233, 234, nil, nil, 254, 255, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, 247, 245, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, 258, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, 244, 249, 250, 251, 246, 248, 256, 257, 252, + 253, nil, 233, 234, nil, nil, 254, 255, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, 247, 245, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, 258, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, 244, 249, 250, 251, 246, 248, 256, 257, 252, + 253, nil, 233, 234, nil, nil, 254, 255, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, 247, 245, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, 258, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, 244, 249, 250, 251, 246, 248, 256, 257, 252, + 253, nil, 233, 234, nil, nil, 254, 255, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, 247, 245, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, 258, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, 244, 249, 250, 251, 246, 248, 256, 257, 252, + 253, nil, 233, 234, nil, nil, 254, 255, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, 247, 245, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, 258, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + 240, 672, 19, 669, 668, 667, nil, 670, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, 237, nil, nil, nil, 239, 238, 807, 235, + 236, nil, nil, nil, nil, nil, nil, 949, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + 672, 35, 669, 668, 667, 44, 670, nil, nil, nil, + nil, nil, nil, nil, 20, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 807, nil, nil, + 62, nil, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, 244, 249, 250, 251, 246, 248, 256, 257, 252, + 253, nil, -600, -600, nil, nil, 254, 255, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, 247, 245, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, 672, nil, 669, 668, 667, + 62, 670, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, 807, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, 244, 249, 250, 251, 246, 248, 256, 257, 252, + 253, nil, -600, -600, nil, nil, 254, 255, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, 247, 245, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, 672, nil, 669, 668, 667, + 62, 670, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, 807, 29, 28, 27, 103, 102, 104, 105, + nil, 672, 19, 669, 668, 667, nil, 670, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, -600, -600, -600, -600, 246, 248, nil, 807, -600, + -600, nil, nil, nil, nil, nil, 254, 255, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, 247, 245, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 254, 255, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, nil, nil, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 254, 255, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, nil, nil, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 254, 255, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, nil, nil, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 254, 255, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, nil, nil, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, -600, -600, -600, -600, 246, 248, nil, nil, -600, + -600, nil, nil, nil, nil, nil, 254, 255, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, 247, 245, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, -600, -600, -600, -600, 246, 248, nil, nil, -600, + -600, nil, nil, nil, nil, nil, 254, 255, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, 247, 245, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, -600, -600, -600, -600, 246, 248, nil, nil, -600, + -600, nil, nil, nil, nil, nil, 254, 255, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, 247, 245, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, -600, -600, -600, -600, 246, 248, nil, nil, -600, + -600, nil, nil, nil, nil, nil, 254, 255, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, 247, 245, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, -600, -600, -600, -600, 246, 248, nil, nil, -600, + -600, nil, nil, nil, nil, nil, 254, 255, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, 247, 245, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 292, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 294, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, 244, 249, 250, 251, 246, 248, nil, nil, 252, + 253, nil, nil, nil, nil, nil, 254, 255, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, 237, nil, 243, 44, 239, 238, nil, 235, + 236, 247, 245, 241, 20, 242, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, nil, nil, nil, + 62, nil, 83, 95, 96, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 7, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, 240, + 244, 249, 250, 251, 246, 248, 256, nil, 252, 253, + nil, nil, nil, nil, nil, 254, 255, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, 237, nil, 243, 44, 239, 238, nil, 235, 236, + 247, 245, 241, 20, 242, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 232, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + 240, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 254, 255, nil, 225, + nil, nil, 231, nil, nil, 58, 59, nil, nil, 60, + nil, nil, 237, nil, 243, 44, 239, 238, nil, 235, + 236, nil, nil, nil, 230, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 103, 102, 104, + 105, nil, nil, 232, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, 286, 101, 109, 110, nil, 93, 94, 42, 43, + 41, 240, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 254, 255, nil, + 225, nil, nil, 231, nil, nil, 58, 59, nil, nil, + 60, nil, 283, 237, 281, 243, 44, 239, 238, 287, + 235, 236, nil, nil, nil, 230, nil, nil, nil, nil, + 91, 284, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 103, 102, + 104, 105, nil, nil, 232, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, 286, 101, 109, 110, nil, 93, 94, 42, + 43, 41, 240, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 254, 255, + nil, 225, nil, nil, 231, nil, nil, 58, 59, nil, + nil, 60, nil, 283, 237, 281, nil, 44, 239, 238, + 287, 235, 236, nil, nil, nil, 230, nil, nil, nil, + nil, 91, 284, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 232, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, 286, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 225, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, 283, nil, 281, nil, 44, nil, + nil, 287, nil, nil, nil, nil, nil, 230, nil, nil, + nil, nil, 91, 284, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 311, 312, + 72, 73, nil, nil, nil, nil, nil, 307, 308, 314, + 103, 102, 104, 105, nil, nil, 232, nil, nil, nil, + nil, nil, nil, 309, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, nil, nil, 315, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 305, nil, nil, 301, nil, nil, 58, + 59, nil, nil, 60, nil, 300, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 311, + 312, 72, 73, nil, nil, nil, nil, nil, 307, 308, + 314, 103, 102, 104, 105, nil, nil, 232, nil, nil, + nil, nil, nil, nil, 309, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, nil, nil, 315, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 305, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, nil, 672, nil, 669, + 668, 667, 677, 670, nil, nil, nil, nil, nil, nil, + nil, nil, 680, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 317, nil, 675, 62, nil, 83, 95, 96, + 74, 75, 71, nil, 57, 688, 687, nil, 63, 64, + 681, nil, nil, 67, nil, 65, 66, 68, 311, 312, + 72, 73, nil, nil, nil, nil, nil, 307, 308, 314, + 103, 102, 104, 105, nil, nil, 232, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, nil, 231, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 311, + 312, 72, 73, nil, nil, nil, nil, nil, 307, 308, + 314, 103, 102, 104, 105, nil, nil, 232, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 225, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 311, 312, 72, 73, nil, nil, nil, nil, nil, 307, + 308, 314, 103, 102, 104, 105, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, nil, 231, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 311, 312, 72, 73, nil, nil, nil, nil, nil, + 307, 308, 314, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, 286, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, 283, nil, + nil, nil, 44, nil, nil, 287, nil, nil, nil, nil, + nil, 230, nil, nil, nil, nil, 91, 284, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 311, 312, 72, 73, nil, nil, nil, nil, + nil, 307, 308, 314, 103, 102, 104, 105, nil, nil, + 232, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, 286, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 225, nil, nil, + 231, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, 287, nil, nil, nil, + nil, nil, 230, nil, nil, nil, nil, 91, 284, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 231, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 225, + nil, nil, 231, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 20, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 103, 102, 104, + 105, nil, nil, 19, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 225, nil, nil, 231, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, 115, nil, nil, nil, nil, + 114, 62, nil, 83, 95, 96, 74, 75, 71, nil, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 311, 312, 72, 73, nil, nil, + nil, nil, nil, 307, 308, 314, 103, 102, 104, 105, + nil, nil, 232, nil, nil, nil, nil, nil, nil, 309, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, nil, nil, 315, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 349, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 311, 312, 72, 73, nil, + nil, nil, nil, nil, 307, 308, 314, 103, 102, 104, + 105, nil, nil, 232, nil, nil, nil, nil, nil, nil, + 309, nil, nil, 107, 106, 108, 354, 56, 99, 98, + 355, nil, 101, 109, 110, nil, 93, 94, nil, nil, + 315, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 361, nil, nil, + 356, nil, nil, 231, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 311, 312, 72, 73, + nil, nil, nil, nil, nil, 307, 308, 314, 103, 102, + 104, 105, nil, nil, 232, nil, nil, nil, nil, nil, + nil, 309, nil, nil, 107, 106, 108, 354, 56, 99, + 98, 355, nil, 101, 109, 110, nil, 93, 94, nil, + nil, 315, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 356, nil, nil, 231, nil, nil, 58, 59, nil, + nil, 60, nil, nil, 672, nil, 669, 668, 667, 677, + 670, nil, nil, nil, nil, nil, nil, nil, nil, 680, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, nil, + nil, 675, 62, nil, 83, 95, 96, 74, 75, 71, + 9, 57, 688, 687, nil, 63, 64, 681, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 103, 102, 104, + 105, nil, nil, 19, nil, nil, nil, nil, nil, 8, + 45, 7, 10, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 40, nil, nil, 33, nil, nil, 58, 59, nil, nil, + 60, nil, 35, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, nil, nil, + 389, 62, nil, 83, 95, 96, 74, 75, 71, nil, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 225, + nil, nil, 231, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 20, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 103, 102, 104, + 105, nil, nil, 19, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 225, nil, nil, 231, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 103, 102, + 104, 105, nil, nil, 19, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 225, nil, nil, 231, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 20, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 225, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 74, 75, + 71, 9, 57, nil, nil, nil, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 103, 102, + 104, 105, nil, nil, 19, nil, nil, nil, nil, nil, + 8, 45, nil, 10, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 40, nil, nil, 33, nil, nil, 58, 59, nil, + nil, 60, nil, 35, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 20, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 232, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 225, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, 405, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 103, 102, 104, 105, nil, nil, 232, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, nil, 231, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 103, 102, 104, 105, nil, nil, 232, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, 286, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 225, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, 283, nil, 281, nil, + 44, nil, nil, 287, nil, nil, nil, nil, nil, 230, + nil, nil, nil, nil, 91, 284, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 103, 102, 104, 105, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, nil, 231, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 30, 31, 72, 73, nil, nil, nil, nil, nil, + 29, 28, 27, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, 405, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 30, 31, 72, 73, nil, nil, nil, nil, + nil, 29, 28, 27, 103, 102, 104, 105, nil, nil, + 19, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 225, nil, nil, + 231, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 231, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 225, + nil, nil, 231, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 20, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 103, 102, 104, + 105, nil, nil, 19, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 225, nil, nil, 231, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, 220, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 311, 312, 72, 73, + nil, nil, nil, nil, nil, 307, 308, 314, 103, 102, + 104, 105, nil, nil, 232, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 225, nil, nil, 231, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 230, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 311, 312, 72, + 73, nil, nil, nil, nil, nil, 307, 308, 314, 103, + 102, 104, 105, nil, nil, 232, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 225, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 311, 312, + 72, 73, nil, nil, nil, nil, nil, 307, 308, 314, + 103, 102, 104, 105, nil, nil, 232, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, nil, 231, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 311, + 312, 72, 73, nil, nil, nil, nil, nil, 307, 308, + 314, 103, 102, 104, 105, nil, nil, 232, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 225, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 311, 312, 72, 73, nil, nil, nil, nil, nil, 307, + 308, 314, 103, 102, 104, 105, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, nil, 231, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 311, 312, 72, 73, nil, nil, nil, nil, nil, + 307, 308, 314, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 311, 312, 72, 73, nil, nil, nil, nil, + nil, 307, 308, 314, 103, 102, 104, 105, nil, nil, + 232, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 225, nil, nil, + 231, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 311, 312, 72, 73, nil, nil, nil, + nil, nil, 307, 308, 314, 103, 102, 104, 105, nil, + nil, 232, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 231, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 311, 312, 72, 73, nil, nil, + nil, nil, nil, 307, 308, 314, 103, 102, 104, 105, + nil, nil, 232, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 225, + nil, nil, 231, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 230, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 311, 312, 72, 73, nil, + nil, nil, nil, nil, 307, 308, 314, 103, 102, 104, + 105, nil, nil, 232, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 225, nil, nil, 231, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 230, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 311, 312, 72, 73, + nil, nil, nil, nil, nil, 307, 308, 314, 103, 102, + 104, 105, nil, nil, 232, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 225, nil, nil, 231, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 230, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 311, 312, 72, + 73, nil, nil, nil, nil, nil, 307, 308, 314, 103, + 102, 104, 105, nil, nil, 232, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 225, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 311, 312, + 72, 73, nil, nil, nil, nil, nil, 307, 308, 314, + 103, 102, 104, 105, nil, nil, 232, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, nil, 231, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 311, + 312, 72, 73, nil, nil, nil, nil, nil, 307, 308, + 314, 103, 102, 104, 105, nil, nil, 232, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 225, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 311, 312, 72, 73, nil, nil, nil, nil, nil, 307, + 308, 314, 103, 102, 104, 105, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, nil, 231, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 311, 312, 72, 73, nil, nil, nil, nil, nil, + 307, 308, 314, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 311, 312, 72, 73, nil, nil, nil, nil, + nil, 307, 308, 314, 103, 102, 104, 105, nil, nil, + 232, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 225, nil, nil, + 231, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 311, 312, 72, 73, nil, nil, nil, + nil, nil, 307, 308, 314, 103, 102, 104, 105, nil, + nil, 232, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 231, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 311, 312, 72, 73, nil, nil, + nil, nil, nil, 307, 308, 314, 103, 102, 104, 105, + nil, nil, 232, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 225, + nil, nil, 231, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 230, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 311, 312, 72, 73, nil, + nil, nil, nil, nil, 307, 308, 314, 103, 102, 104, + 105, nil, nil, 232, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 225, nil, nil, 231, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 230, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 311, 312, 72, 73, + nil, nil, nil, nil, nil, 307, 308, 314, 103, 102, + 104, 105, nil, nil, 232, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 225, nil, nil, 231, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 230, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 311, 312, 72, + 73, nil, nil, nil, nil, nil, 307, 308, 314, 103, + 102, 104, 105, nil, nil, 232, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 225, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 311, 312, + 72, 73, nil, nil, nil, nil, nil, 307, 308, 314, + 103, 102, 104, 105, nil, nil, 232, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, nil, 231, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 311, + 312, 72, 73, nil, nil, nil, nil, nil, 307, 308, + 314, 103, 102, 104, 105, nil, nil, 232, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 225, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 311, 312, 72, 73, nil, nil, nil, nil, nil, 307, + 308, 314, 103, 102, 104, 105, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, nil, 231, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 311, 312, 72, 73, nil, nil, nil, nil, nil, + 307, 308, 314, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 311, 312, 72, 73, nil, nil, nil, nil, + nil, 307, 308, 314, 103, 102, 104, 105, nil, nil, + 232, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 225, nil, nil, + 231, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 232, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, 286, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 231, nil, nil, 58, 59, nil, nil, 60, nil, + 283, nil, 281, nil, 44, nil, nil, 287, nil, nil, + nil, nil, nil, 230, nil, nil, nil, nil, 91, 284, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 232, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + 286, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 225, + nil, nil, 231, nil, nil, 58, 59, nil, nil, 60, + nil, 283, nil, 281, nil, 44, nil, nil, 287, nil, + nil, nil, nil, nil, 230, nil, nil, nil, nil, 91, + 284, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 103, 102, 104, + 105, nil, nil, 232, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, 286, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 225, nil, nil, 231, nil, nil, 58, 59, nil, nil, + 60, nil, 283, nil, 281, nil, 44, nil, nil, 287, + nil, nil, nil, nil, nil, 230, nil, nil, nil, nil, + 91, 284, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, 220, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 311, 312, 72, 73, + nil, nil, nil, nil, nil, 307, 308, 314, 103, 102, + 104, 105, nil, nil, 232, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 225, nil, nil, 231, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 230, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 311, 312, 72, + 73, nil, nil, nil, nil, nil, 307, 308, 314, 103, + 102, 104, 105, nil, nil, 232, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 225, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 311, 312, + 72, 73, nil, nil, nil, nil, nil, 307, 308, 314, + 103, 102, 104, 105, nil, nil, 232, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, nil, 231, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 311, + 312, 72, 73, nil, nil, nil, nil, nil, 307, 308, + 314, 103, 102, 104, 105, nil, nil, 232, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 225, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, nil, nil, nil, 62, nil, 83, 95, 96, + 74, 75, 71, 9, 57, nil, nil, nil, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 103, 102, 104, 105, nil, nil, 19, nil, nil, nil, + nil, nil, 8, 45, nil, 10, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 40, nil, nil, 33, nil, nil, 58, + 59, nil, nil, 60, nil, 35, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 311, + 312, 72, 73, nil, nil, nil, nil, nil, 307, 308, + 314, 103, 102, 104, 105, nil, nil, 232, nil, nil, + nil, nil, nil, nil, 309, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, nil, nil, 315, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 305, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, nil, 672, nil, 669, + 668, 667, 677, 670, nil, nil, nil, nil, nil, nil, + nil, nil, 680, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 505, nil, 675, 62, nil, 83, 95, 96, + 74, 75, 71, nil, 57, 688, 687, nil, 63, 64, + 681, nil, nil, 67, nil, 65, 66, 68, 311, 312, + 72, 73, nil, nil, nil, nil, nil, 307, 308, 314, + 103, 102, 104, 105, nil, nil, 232, nil, nil, nil, + nil, nil, nil, 309, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, nil, nil, 315, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 305, nil, nil, 301, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 311, + 312, 72, 73, nil, nil, nil, nil, nil, 307, 308, + 314, 103, 102, 104, 105, nil, nil, 232, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 225, nil, nil, 231, 521, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 103, 102, 104, 105, nil, nil, 19, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, nil, 231, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 20, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 30, 31, 72, 73, nil, nil, nil, nil, nil, + 29, 28, 27, 103, 102, 104, 105, nil, nil, 19, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 20, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 30, 31, 72, 73, nil, nil, nil, nil, + nil, 29, 28, 27, 103, 102, 104, 105, nil, nil, + 19, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 225, nil, nil, + 231, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 231, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 225, + nil, nil, 231, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 20, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 311, 312, 72, 73, nil, + nil, nil, nil, nil, 307, 308, 314, 103, 102, 104, + 105, nil, nil, 232, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 225, nil, nil, 231, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 230, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 103, 102, + 104, 105, nil, nil, 232, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, 286, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 225, nil, nil, 231, nil, nil, 58, 59, nil, + nil, 60, nil, 283, nil, 281, nil, 44, nil, nil, + 287, nil, nil, nil, nil, nil, 230, nil, nil, nil, + nil, 91, 284, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 311, 312, 72, + 73, nil, nil, nil, nil, nil, 307, 308, 314, 103, + 102, 104, 105, nil, nil, 232, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 225, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 311, 312, + 72, 73, nil, nil, nil, nil, nil, 307, 308, 314, + 103, 102, 104, 105, nil, nil, 232, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, nil, 231, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 311, + 312, 72, 73, nil, nil, nil, nil, nil, 307, 308, + 314, 103, 102, 104, 105, nil, nil, 232, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 225, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 311, 312, 72, 73, nil, nil, nil, nil, nil, 307, + 308, 314, 103, 102, 104, 105, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, 286, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, nil, 231, nil, + nil, 58, 59, nil, nil, 60, nil, 629, nil, 281, + nil, 44, nil, nil, 287, nil, nil, nil, nil, nil, + 230, nil, nil, nil, nil, 91, 284, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 311, 312, 72, 73, nil, nil, nil, nil, nil, + 307, 308, 314, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, 286, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + 281, nil, 44, nil, nil, 287, nil, nil, nil, nil, + nil, 230, nil, nil, nil, nil, 91, 284, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 311, 312, 72, 73, nil, nil, nil, nil, + nil, 307, 308, 314, 103, 102, 104, 105, nil, nil, + 232, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 225, nil, nil, + 231, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, nil, nil, nil, 62, nil, + 83, 95, 96, 74, 75, 71, 9, 57, nil, nil, + nil, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 30, 31, 72, 73, nil, nil, nil, nil, nil, + 29, 28, 27, 103, 102, 104, 105, nil, nil, 19, + nil, nil, nil, nil, nil, 8, 45, 294, 10, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 40, nil, nil, 33, + nil, nil, 58, 59, nil, nil, 60, nil, 35, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 20, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, nil, nil, 389, 62, nil, 83, + 95, 96, 74, 75, 71, nil, 57, nil, nil, nil, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 311, 312, 72, 73, nil, nil, nil, nil, nil, 307, + 308, 314, 103, 102, 104, 105, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 309, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, nil, nil, 315, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 305, nil, nil, 301, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 30, 31, 72, 73, nil, nil, nil, nil, nil, + 29, 28, 27, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, 286, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, 283, nil, + 281, nil, 44, nil, nil, 287, nil, nil, nil, nil, + nil, 230, nil, nil, nil, nil, 91, 284, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 311, 312, 72, 73, nil, nil, nil, nil, + nil, 307, 308, 314, 103, 102, 104, 105, nil, nil, + 232, nil, nil, nil, nil, nil, nil, 309, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, nil, nil, 315, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 305, nil, nil, + 301, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 311, 312, 72, 73, nil, nil, nil, + nil, nil, 307, 308, 314, 103, 102, 104, 105, nil, + nil, 232, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 231, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 311, 312, 72, 73, nil, nil, + nil, nil, nil, 307, 308, 314, 103, 102, 104, 105, + nil, nil, 232, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 225, + nil, nil, 231, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 230, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 103, 102, 104, + 105, nil, nil, 19, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 225, nil, nil, 231, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 311, 312, 72, 73, + nil, nil, nil, nil, nil, 307, 308, 314, 103, 102, + 104, 105, nil, nil, 232, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, 286, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 225, nil, nil, 231, nil, nil, 58, 59, nil, + nil, 60, nil, 629, nil, nil, nil, 44, nil, nil, + 287, nil, nil, nil, nil, nil, 230, nil, nil, nil, + nil, 91, 284, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 311, 312, 72, + 73, nil, nil, nil, nil, nil, 307, 308, 314, 103, + 102, 104, 105, nil, nil, 232, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, 286, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 225, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, 287, nil, nil, nil, nil, nil, 230, nil, nil, + nil, nil, 91, 284, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 311, 312, + 72, 73, nil, nil, nil, nil, nil, 307, 308, 314, + 103, 102, 104, 105, nil, nil, 232, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, nil, 231, nil, nil, 58, + 59, nil, nil, 60, nil, 283, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 103, 102, 104, 105, nil, nil, 232, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, 286, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 225, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, 283, nil, 281, nil, + 44, nil, nil, 287, nil, nil, nil, nil, nil, 230, + nil, nil, nil, nil, 91, 284, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 103, 102, 104, 105, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, 286, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, nil, 231, nil, + nil, 58, 59, nil, nil, 60, nil, 283, nil, 281, + nil, 44, nil, nil, 287, nil, nil, nil, nil, nil, + 230, nil, nil, nil, nil, 91, 284, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 311, 312, 72, 73, nil, nil, nil, nil, nil, + 307, 308, 314, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, 734, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 311, 312, 72, 73, nil, nil, nil, nil, + nil, 307, 308, 314, 103, 102, 104, 105, nil, nil, + 232, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 225, nil, nil, + 231, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 311, 312, 72, 73, nil, nil, nil, + nil, nil, 307, 308, 314, 103, 102, 104, 105, nil, + nil, 232, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, 286, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 231, nil, nil, 58, 59, nil, nil, 60, nil, + 629, nil, 281, nil, 44, nil, nil, 287, nil, nil, + nil, nil, nil, 230, nil, nil, nil, nil, 91, 284, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 311, 312, 72, 73, nil, nil, + nil, nil, nil, 307, 308, 314, 103, 102, 104, 105, + nil, nil, 232, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + 286, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 225, + nil, nil, 231, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, 281, nil, 44, nil, nil, 287, nil, + nil, nil, nil, nil, 230, nil, nil, nil, nil, 91, + 284, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 103, 102, 104, + 105, nil, nil, 232, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 225, nil, nil, 231, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 230, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 103, 102, + 104, 105, nil, nil, 232, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 225, nil, nil, 231, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 230, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 232, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 225, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 103, 102, 104, 105, nil, nil, 232, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, nil, 231, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 103, 102, 104, 105, nil, nil, 232, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 225, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 311, 312, 72, 73, nil, nil, nil, nil, nil, 307, + 308, 314, 103, 102, 104, 105, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, nil, 231, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 311, 312, 72, 73, nil, nil, nil, nil, nil, + 307, 308, 314, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 311, 312, 72, 73, nil, nil, nil, nil, + nil, 307, 308, 314, 103, 102, 104, 105, nil, nil, + 232, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 225, nil, nil, + 231, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 311, 312, 72, 73, nil, nil, nil, + nil, nil, 307, 308, 314, 103, 102, 104, 105, nil, + nil, 232, nil, nil, nil, nil, nil, nil, 309, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, nil, nil, 315, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 305, nil, + nil, 301, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 311, 312, 72, 73, nil, nil, + nil, nil, nil, 307, 308, 314, 103, 102, 104, 105, + nil, nil, 232, nil, nil, nil, nil, nil, nil, 309, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, nil, nil, 315, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 305, + nil, nil, 301, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 311, 312, 72, 73, nil, + nil, nil, nil, nil, 307, 308, 314, 103, 102, 104, + 105, nil, nil, 232, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 225, nil, nil, 231, nil, nil, 58, 59, nil, nil, + 60, nil, 405, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 230, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 311, 312, 72, 73, + nil, nil, nil, nil, nil, 307, 308, 314, 103, 102, + 104, 105, nil, nil, 232, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 225, nil, nil, 231, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 230, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 225, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 103, 102, 104, 105, nil, nil, 19, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, nil, 231, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 311, + 312, 72, 73, nil, nil, nil, nil, nil, 307, 308, + 314, 103, 102, 104, 105, nil, nil, 232, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 225, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 103, 102, 104, 105, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, nil, 231, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 311, 312, 72, 73, nil, nil, nil, nil, nil, + 307, 308, 314, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 311, 312, 72, 73, nil, nil, nil, nil, + nil, 307, 308, 314, 103, 102, 104, 105, nil, nil, + 232, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 225, nil, nil, + 231, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 311, 312, 72, 73, nil, nil, nil, + nil, nil, 307, 308, 314, 103, 102, 104, 105, nil, + nil, 232, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 231, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 311, 312, 72, 73, nil, nil, + nil, nil, nil, 307, 308, 314, 103, 102, 104, 105, + nil, nil, 232, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 225, + nil, nil, 231, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 230, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 311, 312, 72, 73, nil, + nil, nil, nil, nil, 307, 308, 314, 103, 102, 104, + 105, nil, nil, 232, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 225, nil, nil, 231, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 230, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 311, 312, 72, 73, + nil, nil, nil, nil, nil, 307, 308, 314, 103, 102, + 104, 105, nil, nil, 232, nil, nil, nil, nil, nil, + nil, 309, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, nil, + nil, 315, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 857, nil, nil, 231, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 311, 312, 72, + 73, nil, nil, nil, nil, nil, 307, 308, 314, 103, + 102, 104, 105, nil, nil, 232, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 225, nil, nil, 231, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 103, 102, 104, 105, nil, nil, 19, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, nil, 231, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 311, + 312, 72, 73, nil, nil, nil, nil, nil, 307, 308, + 314, 103, 102, 104, 105, nil, nil, 232, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 225, nil, nil, 231, nil, nil, + 58, 59, nil, nil, 60, nil, 629, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 311, 312, 72, 73, nil, nil, nil, nil, nil, 307, + 308, 314, 103, 102, 104, 105, nil, nil, 232, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, 286, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 225, nil, nil, 231, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, 281, + nil, 44, nil, nil, 287, nil, nil, nil, nil, nil, + 230, nil, nil, nil, nil, 91, 284, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 311, 312, 72, 73, nil, nil, nil, nil, nil, + 307, 308, 314, 103, 102, 104, 105, nil, nil, 232, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 231, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 311, 312, 72, 73, nil, nil, nil, nil, + nil, 307, 308, 314, 103, 102, 104, 105, nil, nil, + 232, nil, nil, nil, nil, nil, nil, 309, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, nil, nil, 315, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 857, nil, nil, + 231, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 311, 312, 72, 73, nil, nil, nil, + nil, nil, 307, 308, 314, 103, 102, 104, 105, nil, + nil, 232, nil, nil, nil, nil, nil, nil, 309, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, nil, nil, 315, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 931, nil, + nil, 231, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 232, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + 286, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 225, + nil, nil, 231, nil, nil, 58, 59, nil, nil, 60, + nil, 283, nil, 281, nil, 44, nil, nil, 287, nil, + nil, nil, nil, nil, 230, nil, nil, nil, nil, 91, + 284, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, nil, -280, nil, + 62, nil, 83, 95, 96, -280, -280, -280, nil, nil, + -280, -280, -280, nil, -280, nil, nil, nil, nil, nil, + nil, nil, nil, nil, -280, -280, -280, nil, nil, nil, + nil, nil, nil, nil, -280, -280, nil, -280, -280, -280, + -280, -280, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, -280, -280, -280, -280, -280, -280, + -280, -280, -280, -280, -280, -280, -280, -280, nil, nil, + -280, -280, -280, nil, nil, -280, nil, nil, -280, nil, + nil, -280, -280, nil, -280, nil, -280, nil, -280, nil, + -280, -280, nil, -280, -280, -280, -280, -280, nil, -280, + nil, -280, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, -280, nil, nil, -280, -280, + -280, -280, -582, -280, nil, -280, nil, nil, nil, -582, + -582, -582, nil, nil, -582, -582, -582, nil, -582, nil, + nil, nil, nil, nil, nil, nil, nil, -582, -582, -582, + -582, nil, nil, nil, nil, nil, nil, nil, -582, -582, + nil, -582, -582, -582, -582, -582, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, -582, -582, + -582, -582, -582, -582, -582, -582, -582, -582, -582, -582, + -582, -582, nil, nil, -582, -582, -582, nil, nil, -582, + nil, nil, -582, nil, nil, -582, -582, nil, -582, nil, + -582, nil, -582, nil, -582, -582, nil, -582, -582, -582, + -582, -582, nil, -582, -582, -582, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, -582, + nil, nil, -582, -582, -582, -582, -583, -582, nil, -582, + nil, nil, nil, -583, -583, -583, nil, nil, -583, -583, + -583, nil, -583, nil, nil, nil, nil, nil, nil, nil, + nil, -583, -583, -583, -583, nil, nil, nil, nil, nil, + nil, nil, -583, -583, nil, -583, -583, -583, -583, -583, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, -583, -583, -583, -583, -583, -583, -583, -583, + -583, -583, -583, -583, -583, -583, nil, nil, -583, -583, + -583, nil, nil, -583, nil, nil, -583, nil, nil, -583, + -583, nil, -583, nil, -583, nil, -583, nil, -583, -583, + nil, -583, -583, -583, -583, -583, nil, -583, -583, -583, + 672, nil, 669, 668, 667, 677, 670, nil, nil, nil, + nil, nil, nil, -583, nil, 680, -583, -583, -583, -583, + -414, -583, nil, -583, nil, nil, nil, -414, -414, -414, + nil, nil, -414, -414, -414, nil, -414, 675, nil, nil, + nil, nil, nil, nil, nil, -414, -414, -414, 688, 687, + nil, nil, nil, 681, nil, nil, -414, -414, nil, -414, + -414, -414, -414, -414, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, -414, -414, -414, -414, + -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, + nil, nil, -414, -414, -414, nil, nil, -414, nil, 265, + -414, nil, nil, -414, -414, nil, -414, nil, -414, nil, + -414, nil, -414, -414, nil, -414, -414, -414, -414, -414, + -296, -414, -414, -414, nil, nil, nil, -296, -296, -296, + nil, nil, -296, -296, -296, nil, -296, -414, nil, nil, + -414, -414, nil, -414, nil, -414, -296, -296, nil, nil, + nil, nil, nil, nil, nil, nil, -296, -296, nil, -296, + -296, -296, -296, -296, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, -296, -296, -296, -296, + -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, + nil, nil, -296, -296, -296, nil, nil, -296, nil, 274, + -296, nil, nil, -296, -296, nil, -296, nil, -296, nil, + -296, nil, -296, -296, nil, -296, -296, -296, -296, -296, + nil, -296, -244, -296, nil, nil, nil, nil, nil, -244, + -244, -244, nil, nil, -244, -244, -244, -296, -244, nil, + -296, -296, nil, -296, nil, -296, nil, -244, -244, -244, + nil, nil, nil, nil, nil, nil, nil, nil, -244, -244, + nil, -244, -244, -244, -244, -244, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, -244, -244, + -244, -244, -244, -244, -244, -244, -244, -244, -244, -244, + -244, -244, nil, nil, -244, -244, -244, nil, nil, -244, + nil, 265, -244, nil, nil, -244, -244, nil, -244, nil, + -244, nil, -244, nil, -244, -244, nil, -244, -244, -244, + -244, -244, nil, -244, -244, -244, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, -244, + nil, -244, -244, -244, nil, -244, nil, -244, -244, -244, + -244, nil, nil, -244, -244, -244, 672, -244, 669, 668, + 667, 677, 670, nil, nil, nil, -244, -244, nil, nil, + nil, 680, nil, nil, nil, nil, nil, -244, -244, nil, + -244, -244, -244, -244, -244, nil, nil, nil, nil, nil, + nil, nil, nil, 675, nil, 672, nil, 669, 668, 667, + 677, 670, 685, 684, 688, 687, nil, nil, nil, 681, + 680, nil, nil, nil, nil, nil, nil, nil, -244, nil, + nil, nil, nil, nil, nil, -244, nil, nil, nil, nil, + 265, -244, 675, 658, nil, 220, nil, nil, nil, nil, + nil, 685, 684, 688, 687, nil, nil, nil, 681, nil, + nil, nil, nil, -244, -244, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, -244, nil, + nil, -244, nil, nil, nil, nil, -244, 175, 186, 176, + 199, 172, 192, 182, 181, 202, 203, 197, 180, 179, + 174, 200, 204, 205, 184, 173, 187, 191, 193, 185, + 178, nil, nil, nil, 194, 201, 196, 195, 188, 198, + 183, 171, 190, 189, nil, nil, nil, nil, nil, 170, + 177, 168, 169, 165, 166, 167, 126, 128, 125, nil, + 127, nil, nil, nil, nil, nil, nil, nil, 159, 160, + nil, 156, 138, 139, 140, 147, 144, 146, nil, nil, + 141, 142, nil, nil, nil, 161, 162, 148, 149, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 153, 152, nil, 137, 158, 155, 154, 163, + 150, 151, 145, 143, 135, 157, 136, nil, nil, 164, + 91, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 90, 175, 186, 176, 199, 172, + 192, 182, 181, 202, 203, 197, 180, 179, 174, 200, + 204, 205, 184, 173, 187, 191, 193, 185, 178, nil, + nil, nil, 194, 201, 196, 195, 188, 198, 183, 171, + 190, 189, nil, nil, nil, nil, nil, 170, 177, 168, + 169, 165, 166, 167, 126, 128, nil, nil, 127, nil, + nil, nil, nil, nil, nil, nil, 159, 160, nil, 156, + 138, 139, 140, 147, 144, 146, nil, nil, 141, 142, + nil, nil, nil, 161, 162, 148, 149, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 153, 152, nil, 137, 158, 155, 154, 163, 150, 151, + 145, 143, 135, 157, 136, nil, nil, 164, 91, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 90, 175, 186, 176, 199, 172, 192, 182, + 181, 202, 203, 197, 180, 179, 174, 200, 204, 205, + 184, 173, 187, 191, 193, 185, 178, nil, nil, nil, + 194, 201, 196, 195, 188, 198, 183, 171, 190, 189, + nil, nil, nil, nil, nil, 170, 177, 168, 169, 165, + 166, 167, 126, 128, nil, nil, 127, nil, nil, nil, + nil, nil, nil, nil, 159, 160, nil, 156, 138, 139, + 140, 147, 144, 146, nil, nil, 141, 142, nil, nil, + nil, 161, 162, 148, 149, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 153, 152, + nil, 137, 158, 155, 154, 163, 150, 151, 145, 143, + 135, 157, 136, nil, nil, 164, 91, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 90, 175, 186, 176, 199, 172, 192, 182, 181, 202, + 203, 197, 180, 179, 174, 200, 204, 205, 184, 173, + 187, 191, 193, 185, 178, nil, nil, nil, 194, 201, + 196, 195, 188, 198, 183, 171, 190, 189, nil, nil, + nil, nil, nil, 170, 177, 168, 169, 165, 166, 167, + 126, 128, nil, nil, 127, nil, nil, nil, nil, nil, + nil, nil, 159, 160, nil, 156, 138, 139, 140, 147, + 144, 146, nil, nil, 141, 142, nil, nil, nil, 161, + 162, 148, 149, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 153, 152, nil, 137, + 158, 155, 154, 163, 150, 151, 145, 143, 135, 157, + 136, nil, nil, 164, 91, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 90, 175, + 186, 176, 199, 172, 192, 182, 181, 202, 203, 197, + 180, 179, 174, 200, 204, 205, 184, 173, 187, 191, + 193, 185, 178, nil, nil, nil, 194, 201, 196, 372, + 371, 373, 370, 171, 190, 189, nil, nil, nil, nil, + nil, 170, 177, 168, 169, 367, 368, 369, 365, 128, + 99, 98, 366, nil, 101, nil, nil, nil, nil, nil, + 159, 160, nil, 156, 138, 139, 140, 147, 144, 146, + nil, nil, 141, 142, nil, nil, nil, 161, 162, 148, + 149, nil, nil, nil, nil, nil, 377, nil, nil, nil, + nil, nil, nil, nil, 153, 152, nil, 137, 158, 155, + 154, 163, 150, 151, 145, 143, 135, 157, 136, nil, + nil, 164, 175, 186, 176, 199, 172, 192, 182, 181, + 202, 203, 197, 180, 179, 174, 200, 204, 205, 184, + 173, 187, 191, 193, 185, 178, nil, nil, nil, 194, + 201, 196, 195, 188, 198, 183, 171, 190, 189, nil, + nil, nil, nil, nil, 170, 177, 168, 169, 165, 166, + 167, 126, 128, nil, nil, 127, nil, nil, nil, nil, + nil, nil, nil, 159, 160, nil, 156, 138, 139, 140, + 147, 144, 146, nil, nil, 141, 142, nil, nil, nil, + 161, 162, 148, 149, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 153, 152, nil, + 137, 158, 155, 154, 163, 150, 151, 145, 143, 135, + 157, 136, 414, 418, 164, nil, 415, nil, nil, nil, + nil, nil, nil, nil, 159, 160, nil, 156, 138, 139, + 140, 147, 144, 146, nil, nil, 141, 142, nil, nil, + nil, 161, 162, 148, 149, nil, nil, nil, nil, nil, + 265, nil, nil, nil, nil, nil, nil, nil, 153, 152, + nil, 137, 158, 155, 154, 163, 150, 151, 145, 143, + 135, 157, 136, 421, 425, 164, nil, 420, nil, nil, + nil, nil, nil, nil, nil, 159, 160, nil, 156, 138, + 139, 140, 147, 144, 146, nil, nil, 141, 142, nil, + nil, nil, 161, 162, 148, 149, nil, nil, nil, nil, + nil, 265, nil, nil, nil, nil, nil, nil, nil, 153, + 152, nil, 137, 158, 155, 154, 163, 150, 151, 145, + 143, 135, 157, 136, 476, 418, 164, nil, 477, nil, + nil, nil, nil, nil, nil, nil, 159, 160, nil, 156, + 138, 139, 140, 147, 144, 146, nil, nil, 141, 142, + nil, nil, nil, 161, 162, 148, 149, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 153, 152, nil, 137, 158, 155, 154, 163, 150, 151, + 145, 143, 135, 157, 136, 608, 418, 164, nil, 609, + nil, nil, nil, nil, nil, nil, nil, 159, 160, nil, + 156, 138, 139, 140, 147, 144, 146, nil, nil, 141, + 142, nil, nil, nil, 161, 162, 148, 149, nil, nil, + nil, nil, nil, 265, nil, nil, nil, nil, nil, nil, + nil, 153, 152, nil, 137, 158, 155, 154, 163, 150, + 151, 145, 143, 135, 157, 136, 610, 425, 164, nil, + 611, nil, nil, nil, nil, nil, nil, nil, 159, 160, + nil, 156, 138, 139, 140, 147, 144, 146, nil, nil, + 141, 142, nil, nil, nil, 161, 162, 148, 149, nil, + nil, nil, nil, nil, 265, nil, nil, nil, nil, nil, + nil, nil, 153, 152, nil, 137, 158, 155, 154, 163, + 150, 151, 145, 143, 135, 157, 136, 640, 418, 164, + nil, 641, nil, nil, nil, nil, nil, nil, nil, 159, + 160, nil, 156, 138, 139, 140, 147, 144, 146, nil, + nil, 141, 142, nil, nil, nil, 161, 162, 148, 149, + nil, nil, nil, nil, nil, 265, nil, nil, nil, nil, + nil, nil, nil, 153, 152, nil, 137, 158, 155, 154, + 163, 150, 151, 145, 143, 135, 157, 136, 643, 425, + 164, nil, 644, nil, nil, nil, nil, nil, nil, nil, + 159, 160, nil, 156, 138, 139, 140, 147, 144, 146, + nil, nil, 141, 142, nil, nil, nil, 161, 162, 148, + 149, nil, nil, nil, nil, nil, 265, nil, nil, nil, + nil, nil, nil, nil, 153, 152, nil, 137, 158, 155, + 154, 163, 150, 151, 145, 143, 135, 157, 136, 608, + 418, 164, nil, 609, nil, nil, nil, nil, nil, nil, + nil, 159, 160, nil, 156, 138, 139, 140, 147, 144, + 146, nil, nil, 141, 142, nil, nil, nil, 161, 162, + 148, 149, nil, nil, nil, nil, nil, 265, nil, nil, + nil, nil, nil, nil, nil, 153, 152, nil, 137, 158, + 155, 154, 163, 150, 151, 145, 143, 135, 157, 136, + 610, 425, 164, nil, 611, nil, nil, nil, nil, nil, + nil, nil, 159, 160, nil, 156, 138, 139, 140, 147, + 144, 146, nil, nil, 141, 142, nil, nil, nil, 161, + 162, 148, 149, nil, nil, nil, nil, nil, 265, nil, + nil, nil, nil, nil, nil, nil, 153, 152, nil, 137, + 158, 155, 154, 163, 150, 151, 145, 143, 135, 157, + 136, 701, 418, 164, nil, 702, nil, nil, nil, nil, + nil, nil, nil, 159, 160, nil, 156, 138, 139, 140, + 147, 144, 146, nil, nil, 141, 142, nil, nil, nil, + 161, 162, 148, 149, nil, nil, nil, nil, nil, 265, + nil, nil, nil, nil, nil, nil, nil, 153, 152, nil, + 137, 158, 155, 154, 163, 150, 151, 145, 143, 135, + 157, 136, 703, 425, 164, nil, 704, nil, nil, nil, + nil, nil, nil, nil, 159, 160, nil, 156, 138, 139, + 140, 147, 144, 146, nil, nil, 141, 142, nil, nil, + nil, 161, 162, 148, 149, nil, nil, nil, nil, nil, + 265, nil, nil, nil, nil, nil, nil, nil, 153, 152, + nil, 137, 158, 155, 154, 163, 150, 151, 145, 143, + 135, 157, 136, 706, 425, 164, nil, 707, nil, nil, + nil, nil, nil, nil, nil, 159, 160, nil, 156, 138, + 139, 140, 147, 144, 146, nil, nil, 141, 142, nil, + nil, nil, 161, 162, 148, 149, nil, nil, nil, nil, + nil, 265, nil, nil, nil, nil, nil, nil, nil, 153, + 152, nil, 137, 158, 155, 154, 163, 150, 151, 145, + 143, 135, 157, 136, 476, 418, 164, nil, 477, nil, + nil, nil, nil, nil, nil, nil, 159, 160, nil, 156, + 138, 139, 140, 147, 144, 146, nil, nil, 141, 142, + nil, nil, nil, 161, 162, 148, 149, nil, nil, nil, + nil, nil, 265, nil, nil, nil, nil, nil, nil, nil, + 153, 152, nil, 137, 158, 155, 154, 163, 150, 151, + 145, 143, 135, 157, 136, 974, 425, 164, nil, 973, + nil, nil, nil, nil, nil, nil, nil, 159, 160, nil, + 156, 138, 139, 140, 147, 144, 146, nil, nil, 141, + 142, nil, nil, nil, 161, 162, 148, 149, nil, nil, + nil, nil, nil, 265, nil, nil, nil, nil, nil, nil, + nil, 153, 152, nil, 137, 158, 155, 154, 163, 150, + 151, 145, 143, 135, 157, 136, 1000, 418, 164, nil, + 1001, nil, nil, nil, nil, nil, nil, nil, 159, 160, + nil, 156, 138, 139, 140, 147, 144, 146, nil, nil, + 141, 142, nil, nil, nil, 161, 162, 148, 149, nil, + nil, nil, nil, nil, 265, nil, nil, nil, nil, nil, + nil, nil, 153, 152, nil, 137, 158, 155, 154, 163, + 150, 151, 145, 143, 135, 157, 136, 1002, 425, 164, + nil, 1003, nil, nil, nil, nil, nil, nil, nil, 159, + 160, nil, 156, 138, 139, 140, 147, 144, 146, nil, + nil, 141, 142, nil, nil, nil, 161, 162, 148, 149, + nil, nil, nil, nil, nil, 265, nil, nil, nil, nil, + nil, nil, nil, 153, 152, nil, 137, 158, 155, 154, + 163, 150, 151, 145, 143, 135, 157, 136, nil, 672, + 164, 669, 668, 667, 677, 670, nil, 672, nil, 669, + 668, 667, 677, 670, 680, nil, nil, nil, nil, nil, + nil, nil, 680, nil, 672, nil, 669, 668, 667, 677, + 670, nil, nil, nil, nil, nil, 675, nil, nil, 680, + nil, nil, nil, nil, 675, 685, 684, 688, 687, nil, + nil, nil, 681, 685, 684, 688, 687, nil, nil, nil, + 681, 675, nil, 672, nil, 669, 668, 667, 677, 670, + 685, 684, 688, 687, nil, nil, nil, 681, 680, nil, + 672, nil, 669, 668, 667, 677, 670, nil, 672, nil, + 669, 668, 667, 677, 670, 680, nil, nil, nil, nil, + 675, nil, nil, 680, nil, nil, nil, nil, nil, 685, + 684, 688, 687, nil, nil, nil, 681, 675, nil, nil, + nil, nil, nil, nil, nil, 675, 685, 684, 688, 687, + nil, nil, nil, 681, 685, 684, 688, 687, nil, nil, + 672, 681, 669, 668, 667, 677, 670, nil, 672, nil, + 669, 668, 667, 677, 670, 680, nil, nil, nil, nil, + nil, nil, nil, 680, nil, 672, nil, 669, 668, 667, + 677, 670, nil, nil, nil, nil, nil, 675, nil, nil, + 680, nil, nil, nil, nil, 675, 685, 684, 688, 687, + nil, nil, nil, 681, 685, 684, 688, 687, nil, nil, + nil, 681, 675, nil, 672, nil, 669, 668, 667, 677, + 670, nil, nil, 688, 687, nil, nil, nil, 681, 680, + nil, 672, nil, 669, 668, 667, 677, 670, 672, nil, + 669, 668, 667, 677, 670, nil, 680, nil, nil, nil, + nil, 675, nil, 680, nil, nil, nil, nil, nil, nil, + 685, 684, 688, 687, nil, nil, nil, 681, 675, nil, + nil, nil, nil, nil, nil, 675, nil, nil, nil, 688, + 687, nil, nil, nil, 681, nil, 688, 687, nil, nil, + 672, 681, 669, 668, 667, 677, 670, 672, nil, 669, + 668, 667, 677, 670, 672, 680, 669, 668, 667, 677, + 670, nil, 680, nil, nil, nil, nil, nil, nil, 680, + nil, nil, nil, nil, nil, nil, nil, 675, nil, nil, + nil, nil, nil, nil, 675, nil, nil, nil, 688, 687, + nil, 675, nil, 681, nil, 688, 687, nil, nil, nil, + 681, nil, 688, 687, nil, nil, nil, 681 ] + +racc_action_check = [ + 97, 1, 61, 438, 438, 346, 347, 97, 97, 97, + 19, 339, 97, 97, 97, 58, 97, 26, 474, 384, + 635, 7, 564, 564, 97, 385, 97, 97, 97, 635, + 620, 898, 10, 898, 350, 360, 97, 97, 340, 97, + 97, 97, 97, 97, 699, 866, 17, 17, 893, 548, + 701, 19, 1000, 474, 1001, 58, 650, 650, 310, 356, + 338, 338, 223, 356, 702, 793, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 12, 26, 97, 97, 97, 384, 97, 97, 540, 61, + 97, 385, 24, 97, 97, 825, 97, 438, 97, 24, + 97, 224, 97, 97, 26, 97, 97, 97, 97, 97, + 1021, 97, 100, 97, 346, 347, 564, 620, 223, 100, + 100, 100, 310, 1002, 100, 100, 100, 97, 100, 339, + 97, 97, 97, 97, 339, 97, 100, 97, 100, 100, + 100, 360, 97, 350, 541, 310, 703, 826, 100, 100, + 650, 100, 100, 100, 100, 100, 340, 224, 548, 701, + 640, 340, 699, 866, 360, 699, 893, 699, 866, 360, + 1000, 893, 1001, 702, 793, 1000, 226, 1001, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 540, 13, 100, 100, 100, 540, 100, 100, + 1002, 641, 100, 16, 825, 100, 100, 704, 100, 22, + 100, 703, 100, 37, 100, 100, 354, 100, 100, 100, + 100, 100, 420, 100, 40, 100, 640, 365, 1021, 420, + 420, 420, 226, 1021, 365, 420, 420, 330, 420, 100, + 330, 1002, 100, 100, 100, 100, 1002, 100, 541, 100, + 355, 826, 482, 541, 100, 703, 826, 331, 420, 420, + 331, 420, 420, 420, 420, 420, 640, 641, 354, 640, + 15, 45, 704, 560, 560, 354, 38, 111, 640, 810, + 354, 810, 810, 810, 354, 810, 206, 482, 420, 420, + 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, + 420, 420, 355, 354, 420, 420, 420, 641, 420, 355, + 641, 483, 420, 39, 355, 420, 704, 15, 355, 641, + 420, 575, 420, 38, 420, 420, 15, 420, 420, 420, + 420, 420, 38, 420, 421, 420, 334, 355, 444, 334, + 608, 421, 421, 421, 41, 41, 483, 421, 421, 420, + 421, 366, 420, 420, 621, 420, 225, 420, 366, 421, + 39, 810, 643, 609, 420, 656, 227, 560, 656, 39, + 421, 421, 560, 421, 421, 421, 421, 421, 949, 228, + 949, 949, 949, 232, 949, 575, 575, 493, 319, 621, + 379, 264, 315, 315, 444, 575, 608, 278, 577, 279, + 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 643, 282, 421, 421, 421, 609, + 421, 643, 41, 41, 421, 294, 643, 421, 754, 781, + 643, 706, 421, 3, 421, 319, 421, 421, 3, 421, + 421, 421, 421, 421, 319, 421, 421, 421, 380, 643, + 295, 493, 493, 493, 379, 379, 379, 381, 524, 524, + 949, 421, 577, 577, 421, 421, 610, 421, 493, 421, + 315, 315, 577, 610, 610, 610, 421, 297, 610, 610, + 610, 781, 610, 706, 754, 690, 690, 298, 781, 367, + 706, 610, 610, 610, 610, 706, 367, 781, 918, 706, + 299, 918, 610, 610, 305, 610, 610, 610, 610, 610, + 290, 414, 380, 380, 380, 290, 781, 382, 706, 368, + 383, 381, 381, 381, 386, 125, 368, 798, 798, 308, + 125, 125, 610, 610, 610, 610, 610, 610, 610, 610, + 610, 610, 610, 610, 610, 610, 343, 14, 610, 610, + 610, 343, 610, 610, 14, 469, 610, 415, 414, 610, + 610, 309, 610, 14, 610, 591, 610, 414, 610, 610, + 314, 610, 610, 610, 610, 610, 316, 610, 610, 610, + 320, 382, 382, 382, 383, 383, 383, 469, 386, 386, + 386, 469, 469, 610, 469, 469, 610, 610, 610, 610, + 450, 610, 611, 610, 415, 990, 990, 795, 610, 611, + 611, 611, 591, 415, 611, 611, 611, 795, 611, 323, + 675, 591, 675, 675, 675, 328, 675, 451, 611, 611, + 611, 332, 450, 46, 79, 333, 450, 450, 611, 611, + 46, 611, 611, 611, 611, 611, 79, 369, 335, 46, + 795, 795, 344, 370, 369, 795, 79, 675, 371, 451, + 370, 345, 559, 451, 451, 371, 675, 559, 611, 611, + 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, + 611, 611, 349, 843, 611, 611, 611, 222, 611, 611, + 302, 351, 611, 843, 222, 611, 611, 302, 611, 395, + 611, 401, 611, 222, 611, 611, 302, 611, 611, 611, + 611, 611, 404, 611, 807, 611, 807, 807, 807, 890, + 807, 890, 890, 890, 406, 890, 843, 843, 410, 611, + 412, 843, 611, 611, 611, 611, 303, 611, 413, 611, + 422, 430, 440, 303, 611, 0, 0, 0, 0, 0, + 0, 807, 303, 829, 0, 0, 890, 452, 829, 0, + 807, 0, 0, 0, 0, 0, 0, 0, 6, 6, + 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, + 568, 568, 0, 453, 568, 568, 568, 433, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 454, 0, 0, 0, 455, 0, 0, 0, 0, 0, + 433, 433, 433, 433, 433, 433, 433, 433, 433, 433, + 433, 304, 433, 433, 306, 834, 433, 433, 304, 0, + 834, 306, 0, 480, 484, 0, 0, 304, 500, 0, + 306, 0, 433, 501, 433, 0, 433, 433, 504, 433, + 433, 433, 433, 433, 0, 433, 506, 511, 514, 0, + 0, 0, 0, 321, 0, 0, 0, 0, 522, 372, + 321, 373, 0, 0, 375, 433, 372, 433, 373, 321, + 0, 375, 0, 0, 0, 33, 33, 33, 33, 33, + 33, 523, 525, 348, 33, 33, 537, 542, 543, 33, + 348, 33, 33, 33, 33, 33, 33, 33, 562, 348, + 572, 580, 582, 33, 33, 33, 33, 33, 33, 33, + 588, 592, 33, 597, 602, 612, 614, 409, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 619, 33, 33, 33, 626, 33, 33, 33, 33, 33, + 409, 409, 409, 409, 409, 409, 409, 409, 409, 409, + 409, 358, 409, 409, 510, 628, 409, 409, 358, 33, + 634, 510, 33, 637, 639, 33, 33, 358, 642, 33, + 510, 33, 409, 645, 409, 33, 409, 409, 646, 409, + 409, 409, 409, 409, 33, 409, 649, 651, 654, 33, + 33, 33, 33, 551, 33, 33, 33, 33, 660, 661, + 551, 663, 33, 33, 664, 409, 665, 674, 682, 551, + 33, 686, 33, 33, 33, 123, 123, 123, 123, 123, + 123, 689, 692, 856, 123, 123, 697, 700, 709, 123, + 856, 123, 123, 123, 123, 123, 123, 123, 714, 856, + 733, 738, 756, 123, 123, 123, 123, 123, 123, 123, + 757, 759, 123, 760, 761, 763, 764, 613, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 765, 123, 123, 123, 766, 123, 123, 123, 123, 123, + 613, 613, 613, 613, 613, 613, 613, 613, 613, 613, + 613, 644, 613, 613, 922, 770, 613, 613, 644, 123, + 774, 922, 123, 644, 775, 123, 123, 644, 780, 123, + 922, 123, 613, 784, 613, 123, 613, 613, 787, 613, + 613, 613, 613, 613, 123, 613, 788, 791, 794, 123, + 123, 123, 123, 928, 123, 123, 123, 123, 809, 811, + 928, 816, 123, 123, 819, 613, 828, 832, 833, 928, + 123, 836, 123, 123, 123, 208, 208, 208, 208, 208, + 208, 837, 853, 929, 208, 208, 857, 859, 873, 208, + 929, 208, 208, 208, 208, 208, 208, 208, 874, 929, + 878, 879, 881, 208, 208, 208, 208, 208, 208, 208, + 882, 854, 208, 854, 854, 854, 884, 854, 208, 208, + 208, 208, 208, 208, 208, 208, 208, 208, 208, 208, + 887, 208, 208, 208, 889, 208, 208, 208, 208, 208, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 707, 21, 21, 930, 895, 21, 21, 707, 208, + 896, 930, 208, 707, 902, 208, 208, 707, 906, 208, + 930, 208, 21, 908, 21, 208, 21, 21, 911, 21, + 21, 21, 21, 21, 208, 21, 912, 913, 914, 208, + 208, 208, 208, 932, 208, 208, 208, 208, 916, 931, + 932, 951, 208, 208, 973, 21, 974, 975, 980, 932, + 208, 981, 208, 208, 208, 231, 231, 231, 231, 231, + 231, 982, 983, 979, 231, 231, 984, 985, 986, 231, + 979, 231, 231, 231, 231, 231, 231, 231, 988, 979, + 991, 992, 993, 231, 231, 231, 231, 231, 231, 231, + 994, 972, 231, 972, 972, 972, 995, 972, 231, 231, + 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, + 996, 231, 231, 231, 999, 231, 231, 231, 231, 231, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 1003, 276, 276, 1012, 1022, 276, 276, 1003, 231, + 1023, 1024, 231, 1003, nil, 231, 231, 1003, nil, 231, + nil, 231, 276, nil, 276, 231, 276, 276, nil, 276, + 276, 276, 276, 276, 231, 276, nil, nil, nil, 231, + 231, 231, 231, nil, 231, 231, 231, 231, nil, nil, + nil, nil, 231, 231, nil, 276, nil, nil, nil, nil, + 231, nil, 231, 231, 231, 296, 296, 296, 296, 296, + 296, nil, nil, nil, 296, 296, nil, nil, nil, 296, + nil, 296, 296, 296, 296, 296, 296, 296, 293, 293, + 293, 293, 293, 296, 296, 296, 296, 296, 296, 296, + nil, nil, 296, 498, 498, 498, 498, 498, 296, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + nil, 296, 296, 296, nil, 296, 296, 296, 296, 296, + 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, + 428, nil, 428, 428, nil, nil, 428, 428, nil, 296, + nil, nil, 296, nil, nil, 296, 296, nil, nil, 296, + nil, 296, 428, nil, 428, 296, 428, 428, nil, 428, + 428, 428, 428, 428, 296, 428, nil, nil, nil, 296, + 296, 296, 296, nil, 296, 296, 296, 296, nil, nil, + nil, nil, 296, 296, nil, 428, nil, nil, nil, nil, + 296, nil, 296, 296, 296, 301, 301, 301, 301, 301, + 301, nil, nil, nil, 301, 301, nil, nil, nil, 301, + nil, 301, 301, 301, 301, 301, 301, 301, nil, nil, + nil, nil, nil, 301, 301, 301, 301, 301, 301, 301, + nil, nil, 301, nil, nil, nil, nil, nil, 301, 301, + 301, 301, 301, 301, 301, 301, 301, 301, 301, 301, + nil, 301, 301, 301, nil, 301, 301, 301, 301, 301, + 473, 473, 473, 473, 473, 473, 473, 473, 473, 473, + 473, nil, 473, 473, nil, nil, 473, 473, nil, 301, + nil, nil, 301, nil, nil, 301, 301, nil, nil, 301, + nil, 301, 473, nil, 473, 301, 473, 473, nil, 473, + 473, 473, 473, 473, 301, 473, nil, nil, nil, 301, + 301, 301, 301, nil, 301, 301, 301, 301, nil, nil, + nil, nil, 301, 301, 473, 473, nil, nil, nil, nil, + 301, nil, 301, 301, 301, 326, 326, 326, 326, 326, + 326, nil, nil, nil, 326, 326, nil, nil, nil, 326, + nil, 326, 326, 326, 326, 326, 326, 326, nil, nil, + nil, nil, nil, 326, 326, 326, 326, 326, 326, 326, + nil, nil, 326, nil, nil, nil, nil, nil, 326, 326, + 326, 326, 326, 326, 326, 326, 326, 326, 326, 326, + nil, 326, 326, 326, nil, 326, 326, 326, 326, 326, + 520, 520, 520, 520, 520, 520, 520, 520, 520, 520, + 520, nil, 520, 520, nil, nil, 520, 520, nil, 326, + nil, nil, 326, nil, nil, 326, 326, nil, nil, 326, + nil, 326, 520, nil, 520, 326, 520, 520, nil, 520, + 520, 520, 520, 520, 326, 520, nil, nil, nil, 326, + 326, 326, 326, nil, 326, 326, 326, 326, nil, nil, + nil, nil, 326, 326, nil, 520, nil, nil, nil, nil, + 326, nil, 326, 326, 326, 499, 499, 499, 499, 499, + 499, nil, nil, nil, 499, 499, nil, nil, nil, 499, + nil, 499, 499, 499, 499, 499, 499, 499, nil, nil, + nil, nil, nil, 499, 499, 499, 499, 499, 499, 499, + nil, nil, 499, nil, nil, nil, nil, nil, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, + nil, 499, 499, 499, nil, 499, 499, 499, 499, 499, + 648, 648, 648, 648, 648, 648, 648, 648, 648, 648, + 648, nil, 648, 648, nil, nil, 648, 648, nil, 499, + nil, nil, 499, nil, nil, 499, 499, nil, nil, 499, + nil, 499, 648, nil, 648, 499, 648, 648, nil, 648, + 648, 648, 648, 648, 499, 648, nil, nil, nil, 499, + 499, 499, 499, nil, 499, 499, 499, 499, nil, nil, + nil, nil, 499, 499, nil, 648, nil, nil, nil, nil, + 499, nil, 499, 499, 499, 536, 536, 536, 536, 536, + 536, nil, nil, nil, 536, 536, nil, nil, nil, 536, + nil, 536, 536, 536, 536, 536, 536, 536, nil, nil, + nil, nil, nil, 536, 536, 536, 536, 536, 536, 536, + nil, nil, 536, nil, nil, nil, nil, nil, 536, 536, + 536, 536, 536, 536, 536, 536, 536, 536, 536, 536, + nil, 536, 536, 536, nil, 536, 536, 536, 536, 536, + 735, 735, 735, 735, 735, 735, 735, 735, 735, 735, + 735, nil, 735, 735, nil, nil, 735, 735, nil, 536, + nil, nil, 536, nil, nil, 536, 536, nil, nil, 536, + nil, 536, 735, nil, 735, 536, 735, 735, nil, 735, + 735, 735, 735, 735, 536, 735, nil, nil, nil, 536, + 536, 536, 536, nil, 536, 536, 536, 536, nil, nil, + nil, nil, 536, 536, nil, 735, nil, nil, nil, nil, + 536, nil, 536, 536, 536, 539, 539, 539, 539, 539, + 539, nil, nil, nil, 539, 539, nil, nil, nil, 539, + nil, 539, 539, 539, 539, 539, 539, 539, nil, nil, + nil, nil, nil, 539, 539, 539, 539, 539, 539, 539, + nil, nil, 539, nil, nil, nil, nil, nil, 539, 539, + 539, 539, 539, 539, 539, 539, 539, 539, 539, 539, + nil, 539, 539, 539, nil, 539, 539, 539, 539, 539, + 740, 740, 740, 740, 740, 740, 740, 740, 740, 740, + 740, nil, 740, 740, nil, nil, 740, 740, nil, 539, + nil, nil, 539, nil, nil, 539, 539, nil, nil, 539, + nil, 539, 740, nil, 740, 539, 740, 740, nil, 740, + 740, 740, 740, 740, 539, 740, nil, nil, nil, 539, + 539, 539, 539, nil, 539, 539, 539, 539, nil, nil, + nil, nil, 539, 539, nil, 740, nil, nil, nil, nil, + 539, nil, 539, 539, 539, 561, 561, 561, 561, 561, + 561, nil, nil, nil, 561, 561, nil, nil, nil, 561, + nil, 561, 561, 561, 561, 561, 561, 561, nil, nil, + nil, nil, nil, 561, 561, 561, 561, 561, 561, 561, + nil, nil, 561, nil, nil, nil, nil, nil, 561, 561, + 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, + nil, 561, 561, 561, nil, 561, 561, 561, 561, 561, + 742, 742, 742, 742, 742, 742, 742, 742, 742, 742, + 742, nil, 742, 742, nil, nil, 742, 742, nil, 561, + nil, nil, 561, nil, nil, 561, 561, nil, nil, 561, + nil, 561, 742, nil, 742, 561, 742, 742, nil, 742, + 742, 742, 742, 742, 561, 742, nil, nil, nil, 561, + 561, 561, 561, nil, 561, 561, 561, 561, nil, nil, + nil, nil, 561, 561, nil, 742, nil, nil, nil, nil, + 561, nil, 561, 561, 561, 618, 618, 618, 618, 618, + 618, nil, nil, nil, 618, 618, nil, nil, nil, 618, + nil, 618, 618, 618, 618, 618, 618, 618, nil, nil, + nil, nil, nil, 618, 618, 618, 618, 618, 618, 618, + nil, nil, 618, nil, nil, nil, nil, nil, 618, 618, + 618, 618, 618, 618, 618, 618, 618, 618, 618, 618, + nil, 618, 618, 618, nil, 618, 618, 618, 618, 618, + 745, 745, 745, 745, 745, 745, 745, 745, 745, 745, + 745, nil, 745, 745, nil, nil, 745, 745, nil, 618, + nil, nil, 618, nil, nil, 618, 618, nil, nil, 618, + nil, 618, 745, nil, 745, 618, 745, 745, nil, 745, + 745, 745, 745, 745, 618, 745, nil, nil, nil, 618, + 618, 618, 618, nil, 618, 618, 618, 618, nil, nil, + nil, nil, 618, 618, nil, 745, nil, nil, nil, nil, + 618, nil, 618, 618, 618, 623, 623, 623, 623, 623, + 623, nil, nil, nil, 623, 623, nil, nil, nil, 623, + nil, 623, 623, 623, 623, 623, 623, 623, nil, nil, + nil, nil, nil, 623, 623, 623, 623, 623, 623, 623, + nil, nil, 623, nil, nil, nil, nil, nil, 623, 623, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, + nil, 623, 623, 623, nil, 623, 623, 623, 623, 623, + 747, 747, 747, 747, 747, 747, 747, 747, 747, 747, + 747, nil, 747, 747, nil, nil, 747, 747, nil, 623, + nil, nil, 623, nil, nil, 623, 623, nil, nil, 623, + nil, 623, 747, nil, 747, 623, 747, 747, nil, 747, + 747, 747, 747, 747, 623, 747, nil, nil, nil, 623, + 623, 623, 623, nil, 623, 623, 623, 623, nil, nil, + nil, nil, 623, 623, nil, 747, nil, nil, nil, nil, + 623, nil, 623, 623, 623, 624, 624, 624, 624, 624, + 624, nil, nil, nil, 624, 624, nil, nil, nil, 624, + nil, 624, 624, 624, 624, 624, 624, 624, nil, nil, + nil, nil, nil, 624, 624, 624, 624, 624, 624, 624, + nil, nil, 624, nil, nil, nil, nil, nil, 624, 624, + 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, + nil, 624, 624, 624, nil, 624, 624, 624, 624, 624, + 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, + 749, nil, 749, 749, nil, nil, 749, 749, nil, 624, + nil, nil, 624, nil, nil, 624, 624, nil, nil, 624, + nil, 624, 749, nil, 749, 624, 749, 749, nil, 749, + 749, 749, 749, 749, 624, 749, nil, nil, nil, 624, + 624, 624, 624, nil, 624, 624, 624, 624, nil, nil, + nil, nil, 624, 624, nil, 749, nil, nil, nil, nil, + 624, nil, 624, 624, 624, 710, 710, 710, 710, 710, + 710, nil, nil, nil, 710, 710, nil, nil, nil, 710, + nil, 710, 710, 710, 710, 710, 710, 710, nil, nil, + nil, nil, nil, 710, 710, 710, 710, 710, 710, 710, + nil, nil, 710, nil, nil, nil, nil, nil, 710, 710, + 710, 710, 710, 710, 710, 710, 710, 710, 710, 710, + nil, 710, 710, 710, nil, 710, 710, 710, 710, 710, + 839, 839, 839, 839, 839, 839, 839, 839, 839, 839, + 839, nil, 839, 839, nil, nil, 839, 839, nil, 710, + nil, nil, 710, nil, nil, 710, 710, nil, nil, 710, + nil, 710, 839, nil, 839, 710, 839, 839, nil, 839, + 839, 839, 839, 839, 710, 839, nil, nil, nil, 710, + 710, 710, 710, nil, 710, 710, 710, 710, nil, nil, + nil, nil, 710, 710, nil, 839, nil, nil, nil, nil, + 710, nil, 710, 710, 710, 715, 715, 715, 715, 715, + 715, nil, nil, nil, 715, 715, nil, nil, nil, 715, + nil, 715, 715, 715, 715, 715, 715, 715, nil, nil, + nil, nil, nil, 715, 715, 715, 715, 715, 715, 715, + nil, nil, 715, nil, nil, nil, nil, nil, 715, 715, + 715, 715, 715, 715, 715, 715, 715, 715, 715, 715, + nil, 715, 715, 715, nil, 715, 715, 715, 715, 715, + 842, 842, 842, 842, 842, 842, 842, 842, 842, 842, + 842, nil, 842, 842, nil, nil, 842, 842, nil, 715, + nil, nil, 715, nil, nil, 715, 715, nil, nil, 715, + nil, 715, 842, nil, 842, 715, 842, 842, nil, 842, + 842, 842, 842, 842, 715, 842, nil, nil, nil, 715, + 715, 715, 715, nil, 715, 715, 715, 715, nil, nil, + nil, nil, 715, 715, nil, 842, nil, nil, nil, nil, + 715, nil, 715, 715, 715, 725, 725, 725, 725, 725, + 725, nil, nil, nil, 725, 725, nil, nil, nil, 725, + nil, 725, 725, 725, 725, 725, 725, 725, nil, nil, + nil, nil, nil, 725, 725, 725, 725, 725, 725, 725, + 470, 888, 725, 888, 888, 888, nil, 888, 725, 725, + 725, 725, 725, 725, 725, 725, 725, 725, 725, 725, + nil, 725, 725, 725, nil, 725, 725, 725, 725, 725, + nil, nil, 470, nil, nil, nil, 470, 470, 888, 470, + 470, nil, nil, nil, nil, nil, nil, 888, nil, 725, + nil, nil, 725, nil, nil, 725, 725, nil, nil, 725, + 950, 725, 950, 950, 950, 725, 950, nil, nil, nil, + nil, nil, nil, nil, 725, nil, nil, nil, nil, 725, + 725, 725, 725, nil, 725, 725, 725, 725, nil, nil, + nil, nil, 725, 725, nil, nil, nil, 950, nil, nil, + 725, nil, 725, 725, 725, 773, 773, 773, 773, 773, + 773, nil, nil, nil, 773, 773, nil, nil, nil, 773, + nil, 773, 773, 773, 773, 773, 773, 773, nil, nil, + nil, nil, nil, 773, 773, 773, 773, 773, 773, 773, + nil, nil, 773, nil, nil, nil, nil, nil, 773, 773, + 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, + nil, 773, 773, 773, nil, 773, 773, 773, 773, 773, + 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, + 448, nil, 448, 448, nil, nil, 448, 448, nil, 773, + nil, nil, 773, nil, nil, 773, 773, nil, nil, 773, + nil, 773, 448, nil, 448, 773, 448, 448, nil, 448, + 448, 448, 448, 448, 773, 448, nil, nil, nil, 773, + 773, 773, 773, nil, 773, 773, 773, 773, nil, nil, + nil, nil, 773, 773, nil, 987, nil, 987, 987, 987, + 773, 987, 773, 773, 773, 786, 786, 786, 786, 786, + 786, nil, nil, nil, 786, 786, nil, nil, nil, 786, + nil, 786, 786, 786, 786, 786, 786, 786, nil, nil, + nil, nil, 987, 786, 786, 786, 786, 786, 786, 786, + nil, nil, 786, nil, nil, nil, nil, nil, 786, 786, + 786, 786, 786, 786, 786, 786, 786, 786, 786, 786, + nil, 786, 786, 786, nil, 786, 786, 786, 786, 786, + 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, + 449, nil, 449, 449, nil, nil, 449, 449, nil, 786, + nil, nil, 786, nil, nil, 786, 786, nil, nil, 786, + nil, 786, 449, nil, 449, 786, 449, 449, nil, 449, + 449, 449, 449, 449, 786, 449, nil, nil, nil, 786, + 786, 786, 786, nil, 786, 786, 786, 786, nil, nil, + nil, nil, 786, 786, nil, 989, nil, 989, 989, 989, + 786, 989, 786, 786, 786, 820, 820, 820, 820, 820, + 820, nil, nil, nil, 820, 820, nil, nil, nil, 820, + nil, 820, 820, 820, 820, 820, 820, 820, nil, nil, + nil, nil, 989, 820, 820, 820, 820, 820, 820, 820, + nil, 1011, 820, 1011, 1011, 1011, nil, 1011, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, 820, + nil, 820, 820, 820, nil, 820, 820, 820, 820, 820, + 459, 459, 459, 459, 459, 459, 459, nil, 1011, 459, + 459, nil, nil, nil, nil, nil, 459, 459, nil, 820, + nil, nil, 820, nil, nil, 820, 820, nil, nil, 820, + nil, 820, 459, nil, 459, 820, 459, 459, nil, 459, + 459, 459, 459, 459, 820, 459, nil, nil, nil, 820, + 820, 820, 820, nil, 820, 820, 820, 820, nil, nil, + nil, nil, 820, 820, nil, nil, nil, nil, nil, nil, + 820, nil, 820, 820, 820, 821, 821, 821, 821, 821, + 821, nil, nil, nil, 821, 821, nil, nil, nil, 821, + nil, 821, 821, 821, 821, 821, 821, 821, nil, nil, + nil, nil, nil, 821, 821, 821, 821, 821, 821, 821, + nil, nil, 821, nil, nil, nil, nil, nil, 821, 821, + 821, 821, 821, 821, 821, 821, 821, 821, 821, 821, + nil, 821, 821, 821, nil, 821, 821, 821, 821, 821, + 460, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 460, 460, nil, 821, + nil, nil, 821, nil, nil, 821, 821, nil, nil, 821, + nil, 821, 460, nil, 460, 821, 460, 460, nil, 460, + 460, nil, nil, 460, 821, 460, nil, nil, nil, 821, + 821, 821, 821, nil, 821, 821, 821, 821, nil, nil, + nil, nil, 821, 821, nil, nil, nil, nil, nil, nil, + 821, nil, 821, 821, 821, 824, 824, 824, 824, 824, + 824, nil, nil, nil, 824, 824, nil, nil, nil, 824, + nil, 824, 824, 824, 824, 824, 824, 824, nil, nil, + nil, nil, nil, 824, 824, 824, 824, 824, 824, 824, + nil, nil, 824, nil, nil, nil, nil, nil, 824, 824, + 824, 824, 824, 824, 824, 824, 824, 824, 824, 824, + nil, 824, 824, 824, nil, 824, 824, 824, 824, 824, + 461, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 461, 461, nil, 824, + nil, nil, 824, nil, nil, 824, 824, nil, nil, 824, + nil, 824, 461, nil, 461, 824, 461, 461, nil, 461, + 461, nil, nil, 461, 824, 461, nil, nil, nil, 824, + 824, 824, 824, nil, 824, 824, 824, 824, nil, nil, + nil, nil, 824, 824, nil, nil, nil, nil, nil, nil, + 824, nil, 824, 824, 824, 830, 830, 830, 830, 830, + 830, nil, nil, nil, 830, 830, nil, nil, nil, 830, + nil, 830, 830, 830, 830, 830, 830, 830, nil, nil, + nil, nil, nil, 830, 830, 830, 830, 830, 830, 830, + nil, nil, 830, nil, nil, nil, nil, nil, 830, 830, + 830, 830, 830, 830, 830, 830, 830, 830, 830, 830, + nil, 830, 830, 830, nil, 830, 830, 830, 830, 830, + 462, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 462, 462, nil, 830, + nil, nil, 830, nil, nil, 830, 830, nil, nil, 830, + nil, 830, 462, nil, 462, 830, 462, 462, nil, 462, + 462, nil, nil, 462, 830, 462, nil, nil, nil, 830, + 830, 830, 830, nil, 830, 830, 830, 830, nil, nil, + nil, nil, 830, 830, nil, nil, nil, nil, nil, nil, + 830, nil, 830, 830, 830, 863, 863, 863, 863, 863, + 863, nil, nil, nil, 863, 863, nil, nil, nil, 863, + nil, 863, 863, 863, 863, 863, 863, 863, nil, nil, + nil, nil, nil, 863, 863, 863, 863, 863, 863, 863, + nil, nil, 863, nil, nil, nil, nil, nil, 863, 863, + 863, 863, 863, 863, 863, 863, 863, 863, 863, 863, + nil, 863, 863, 863, nil, 863, 863, 863, 863, 863, + 463, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 463, 463, nil, 863, + nil, nil, 863, nil, nil, 863, 863, nil, nil, 863, + nil, 863, 463, nil, 463, 863, 463, 463, nil, 463, + 463, nil, nil, 463, 863, 463, nil, nil, nil, 863, + 863, 863, 863, nil, 863, 863, 863, 863, nil, nil, + nil, nil, 863, 863, nil, nil, nil, nil, nil, nil, + 863, nil, 863, 863, 863, 927, 927, 927, 927, 927, + 927, nil, nil, nil, 927, 927, nil, nil, nil, 927, + nil, 927, 927, 927, 927, 927, 927, 927, nil, nil, + nil, nil, nil, 927, 927, 927, 927, 927, 927, 927, + nil, nil, 927, nil, nil, nil, nil, nil, 927, 927, + 927, 927, 927, 927, 927, 927, 927, 927, 927, 927, + nil, 927, 927, 927, nil, 927, 927, 927, 927, 927, + 464, 464, 464, 464, 464, 464, 464, nil, nil, 464, + 464, nil, nil, nil, nil, nil, 464, 464, nil, 927, + nil, nil, 927, nil, nil, 927, 927, nil, nil, 927, + nil, 927, 464, nil, 464, 927, 464, 464, nil, 464, + 464, 464, 464, 464, 927, 464, nil, nil, nil, 927, + 927, 927, 927, nil, 927, 927, 927, 927, nil, nil, + nil, nil, 927, 927, nil, nil, nil, nil, nil, nil, + 927, nil, 927, 927, 927, 934, 934, 934, 934, 934, + 934, nil, nil, nil, 934, 934, nil, nil, nil, 934, + nil, 934, 934, 934, 934, 934, 934, 934, nil, nil, + nil, nil, nil, 934, 934, 934, 934, 934, 934, 934, + nil, nil, 934, nil, nil, nil, nil, nil, 934, 934, + 934, 934, 934, 934, 934, 934, 934, 934, 934, 934, + nil, 934, 934, 934, nil, 934, 934, 934, 934, 934, + 465, 465, 465, 465, 465, 465, 465, nil, nil, 465, + 465, nil, nil, nil, nil, nil, 465, 465, nil, 934, + nil, nil, 934, nil, nil, 934, 934, nil, nil, 934, + nil, 934, 465, nil, 465, 934, 465, 465, nil, 465, + 465, 465, 465, 465, 934, 465, nil, nil, nil, 934, + 934, 934, 934, nil, 934, 934, 934, 934, nil, nil, + nil, nil, 934, 934, nil, nil, nil, nil, nil, nil, + 934, nil, 934, 934, 934, 935, 935, 935, 935, 935, + 935, nil, nil, nil, 935, 935, nil, nil, nil, 935, + nil, 935, 935, 935, 935, 935, 935, 935, nil, nil, + nil, nil, nil, 935, 935, 935, 935, 935, 935, 935, + nil, nil, 935, nil, nil, nil, nil, nil, 935, 935, + 935, 935, 935, 935, 935, 935, 935, 935, 935, 935, + nil, 935, 935, 935, nil, 935, 935, 935, 935, 935, + 466, 466, 466, 466, 466, 466, 466, nil, nil, 466, + 466, nil, nil, nil, nil, nil, 466, 466, nil, 935, + nil, nil, 935, nil, nil, 935, 935, nil, nil, 935, + nil, 935, 466, nil, 466, 935, 466, 466, nil, 466, + 466, 466, 466, 466, 935, 466, nil, nil, nil, 935, + 935, 935, 935, nil, 935, 935, 935, 935, nil, nil, + nil, nil, 935, 935, nil, nil, nil, nil, nil, nil, + 935, nil, 935, 935, 935, 952, 952, 952, 952, 952, + 952, nil, nil, nil, 952, 952, nil, nil, nil, 952, + nil, 952, 952, 952, 952, 952, 952, 952, nil, nil, + nil, nil, nil, 952, 952, 952, 952, 952, 952, 952, + nil, nil, 952, nil, nil, nil, nil, nil, 952, 952, + 952, 952, 952, 952, 952, 952, 952, 952, 952, 952, + nil, 952, 952, 952, nil, 952, 952, 952, 952, 952, + 467, 467, 467, 467, 467, 467, 467, nil, nil, 467, + 467, nil, nil, nil, nil, nil, 467, 467, nil, 952, + nil, nil, 952, nil, nil, 952, 952, nil, nil, 952, + nil, 952, 467, nil, 467, 952, 467, 467, nil, 467, + 467, 467, 467, 467, 952, 467, nil, nil, nil, 952, + 952, 952, 952, nil, 952, 952, 952, 952, nil, nil, + nil, nil, 952, 952, nil, nil, nil, nil, nil, nil, + 952, nil, 952, 952, 952, 958, 958, 958, 958, 958, + 958, nil, nil, nil, 958, 958, nil, nil, nil, 958, + nil, 958, 958, 958, 958, 958, 958, 958, nil, nil, + nil, nil, nil, 958, 958, 958, 958, 958, 958, 958, + nil, nil, 958, nil, nil, nil, nil, nil, 958, 958, + 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, + nil, 958, 958, 958, nil, 958, 958, 958, 958, 958, + 468, 468, 468, 468, 468, 468, 468, nil, nil, 468, + 468, nil, nil, nil, nil, nil, 468, 468, nil, 958, + nil, nil, 958, nil, nil, 958, 958, nil, nil, 958, + nil, 958, 468, nil, 468, 958, 468, 468, nil, 468, + 468, 468, 468, 468, 958, 468, nil, nil, nil, 958, + 958, 958, 958, nil, 958, 958, 958, 958, nil, nil, + nil, nil, 958, 958, nil, nil, nil, nil, nil, nil, + 958, nil, 958, 958, 958, 960, 960, 960, 960, 960, + 960, nil, nil, nil, 960, 960, nil, nil, nil, 960, + nil, 960, 960, 960, 960, 960, 960, 960, nil, nil, + nil, nil, nil, 960, 960, 960, 960, 960, 960, 960, + nil, nil, 960, nil, nil, nil, nil, nil, 960, 960, + 960, 960, 960, 960, 960, 960, 960, 960, 960, 960, + nil, 960, 960, 960, nil, 960, 960, 960, 960, 960, + 471, 471, 471, 471, 471, 471, 471, nil, nil, 471, + 471, nil, nil, nil, nil, nil, 471, 471, nil, 960, + nil, nil, 960, nil, nil, 960, 960, nil, nil, 960, + nil, 960, 471, nil, 471, 960, 471, 471, nil, 471, + 471, 471, 471, 471, 960, 471, nil, nil, nil, 960, + 960, 960, 960, nil, 960, 960, 960, 960, nil, nil, + nil, nil, 960, 960, nil, nil, nil, nil, nil, nil, + 960, nil, 960, 960, 960, 5, 5, 5, 5, 5, + nil, nil, nil, 5, 5, nil, nil, nil, 5, nil, + 5, 5, 5, 5, 5, 5, 5, nil, nil, nil, + nil, nil, 5, 5, 5, 5, 5, 5, 5, nil, + nil, 5, nil, nil, nil, nil, nil, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, nil, + 5, 5, 5, nil, 5, 5, 5, 5, 5, 472, + 472, 472, 472, 472, 472, 472, 472, nil, 472, 472, + nil, nil, nil, nil, nil, 472, 472, nil, 5, nil, + nil, 5, nil, nil, 5, 5, nil, nil, 5, nil, + 5, 472, nil, 472, 5, 472, 472, nil, 472, 472, + 472, 472, 472, 5, 472, nil, nil, nil, 5, 5, + 5, 5, nil, 5, 5, 5, 5, nil, nil, nil, + nil, 5, 5, nil, nil, nil, 20, 20, 20, 5, + 20, 5, 5, 5, 20, 20, nil, nil, nil, 20, + nil, 20, 20, 20, 20, 20, 20, 20, nil, nil, + nil, nil, nil, 20, 20, 20, 20, 20, 20, 20, + nil, nil, 20, nil, nil, nil, nil, nil, nil, 20, + nil, nil, 20, 20, 20, 20, 20, 20, 20, 20, + nil, 20, 20, 20, nil, 20, 20, 20, 20, 20, + 456, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 456, 456, nil, 20, + nil, nil, 20, nil, nil, 20, 20, nil, nil, 20, + nil, nil, 456, nil, 456, 20, 456, 456, nil, 456, + 456, nil, nil, nil, 20, nil, nil, nil, nil, 20, + 20, 20, 20, nil, 20, 20, 20, 20, nil, nil, + nil, nil, 20, 20, nil, nil, nil, 29, 29, 29, + 20, 29, 20, 20, 20, 29, 29, nil, nil, nil, + 29, nil, 29, 29, 29, 29, 29, 29, 29, nil, + nil, nil, nil, nil, 29, 29, 29, 29, 29, 29, + 29, nil, nil, 29, nil, nil, nil, nil, nil, nil, + 29, nil, nil, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, nil, 29, 29, 29, 29, + 29, 457, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 457, 457, nil, + 29, nil, nil, 29, nil, nil, 29, 29, nil, nil, + 29, nil, 29, 457, 29, 457, 29, 457, 457, 29, + 457, 457, nil, nil, nil, 29, nil, nil, nil, nil, + 29, 29, 29, 29, nil, 29, 29, 29, 29, nil, + nil, nil, nil, 29, 29, nil, nil, nil, 30, 30, + 30, 29, 30, 29, 29, 29, 30, 30, nil, nil, + nil, 30, nil, 30, 30, 30, 30, 30, 30, 30, + nil, nil, nil, nil, nil, 30, 30, 30, 30, 30, + 30, 30, nil, nil, 30, nil, nil, nil, nil, nil, + nil, 30, nil, nil, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, nil, 30, 30, 30, + 30, 30, 458, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 458, 458, + nil, 30, nil, nil, 30, nil, nil, 30, 30, nil, + nil, 30, nil, 30, 458, 30, nil, 30, 458, 458, + 30, 458, 458, nil, nil, nil, 30, nil, nil, nil, + nil, 30, 30, 30, 30, nil, 30, 30, 30, 30, + nil, nil, nil, nil, 30, 30, nil, nil, nil, 31, + 31, 31, 30, 31, 30, 30, 30, 31, 31, nil, + nil, nil, 31, nil, 31, 31, 31, 31, 31, 31, + 31, nil, nil, nil, nil, nil, 31, 31, 31, 31, + 31, 31, 31, nil, nil, 31, nil, nil, nil, nil, + nil, nil, 31, nil, nil, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, nil, 31, 31, + 31, 31, 31, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 31, nil, nil, 31, nil, nil, 31, 31, + nil, nil, 31, nil, 31, nil, 31, nil, 31, nil, + nil, 31, nil, nil, nil, nil, nil, 31, nil, nil, + nil, nil, 31, 31, 31, 31, nil, 31, 31, 31, + 31, nil, nil, nil, nil, 31, 31, nil, nil, nil, + 34, 34, 34, 31, 34, 31, 31, 31, 34, 34, + nil, nil, nil, 34, nil, 34, 34, 34, 34, 34, + 34, 34, nil, nil, nil, nil, nil, 34, 34, 34, + 34, 34, 34, 34, nil, nil, 34, nil, nil, nil, + nil, nil, nil, 34, nil, nil, 34, 34, 34, 34, + 34, 34, 34, 34, nil, 34, 34, 34, nil, 34, + 34, nil, nil, 34, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 34, nil, nil, 34, nil, nil, 34, + 34, nil, nil, 34, nil, 34, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 34, 34, 34, 34, nil, 34, 34, + 34, 34, nil, nil, nil, nil, 34, 34, nil, nil, + nil, 35, 35, 35, 34, 35, 34, 34, 34, 35, + 35, nil, nil, nil, 35, nil, 35, 35, 35, 35, + 35, 35, 35, nil, nil, nil, nil, nil, 35, 35, + 35, 35, 35, 35, 35, nil, nil, 35, nil, nil, + nil, nil, nil, nil, 35, nil, nil, 35, 35, 35, + 35, 35, 35, 35, 35, nil, 35, 35, 35, nil, + 35, 35, nil, nil, 35, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 35, nil, nil, 35, nil, nil, + 35, 35, nil, nil, 35, nil, nil, 803, nil, 803, + 803, 803, 803, 803, nil, nil, nil, nil, nil, nil, + nil, nil, 803, nil, 35, 35, 35, 35, nil, 35, + 35, 35, 35, nil, nil, nil, nil, 35, 35, nil, + nil, nil, 35, nil, 803, 35, nil, 35, 35, 35, + 42, 42, 42, nil, 42, 803, 803, nil, 42, 42, + 803, nil, nil, 42, nil, 42, 42, 42, 42, 42, + 42, 42, nil, nil, nil, nil, nil, 42, 42, 42, + 42, 42, 42, 42, nil, nil, 42, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 42, 42, 42, 42, + 42, 42, 42, 42, nil, 42, 42, 42, nil, 42, + 42, 42, 42, 42, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 42, nil, nil, 42, nil, nil, 42, + 42, nil, nil, 42, nil, nil, nil, nil, nil, 42, + nil, nil, nil, nil, nil, nil, nil, nil, 42, nil, + nil, nil, nil, 42, 42, 42, 42, nil, 42, 42, + 42, 42, nil, nil, nil, nil, 42, 42, nil, nil, + nil, 43, 43, 43, 42, 43, 42, 42, 42, 43, + 43, nil, nil, nil, 43, nil, 43, 43, 43, 43, + 43, 43, 43, nil, nil, nil, nil, nil, 43, 43, + 43, 43, 43, 43, 43, nil, nil, 43, nil, nil, + nil, nil, nil, nil, 43, nil, nil, 43, 43, 43, + 43, 43, 43, 43, 43, nil, 43, 43, 43, nil, + 43, 43, 43, 43, 43, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 43, nil, nil, 43, nil, nil, + 43, 43, nil, nil, 43, nil, nil, nil, nil, nil, + 43, nil, nil, nil, nil, nil, nil, nil, nil, 43, + nil, nil, nil, nil, 43, 43, 43, 43, nil, 43, + 43, 43, 43, nil, nil, nil, nil, 43, 43, nil, + nil, nil, 44, 44, 44, 43, 44, 43, 43, 43, + 44, 44, nil, nil, nil, 44, nil, 44, 44, 44, + 44, 44, 44, 44, nil, nil, nil, nil, nil, 44, + 44, 44, 44, 44, 44, 44, nil, nil, 44, nil, + nil, nil, nil, nil, nil, 44, nil, nil, 44, 44, + 44, 44, 44, 44, 44, 44, nil, 44, 44, 44, + nil, 44, 44, 44, 44, 44, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 44, nil, nil, 44, nil, + nil, 44, 44, nil, nil, 44, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, 44, 44, 44, 44, nil, + 44, 44, 44, 44, nil, nil, nil, nil, 44, 44, + nil, nil, nil, 59, 59, 59, 44, 59, 44, 44, + 44, 59, 59, nil, nil, nil, 59, nil, 59, 59, + 59, 59, 59, 59, 59, nil, nil, nil, nil, nil, + 59, 59, 59, 59, 59, 59, 59, nil, nil, 59, + nil, nil, nil, nil, nil, nil, 59, nil, nil, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 59, nil, 59, 59, 59, 59, 59, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 59, nil, nil, 59, + nil, nil, 59, 59, nil, nil, 59, nil, 59, nil, + nil, nil, 59, nil, nil, 59, nil, nil, nil, nil, + nil, 59, nil, nil, nil, nil, 59, 59, 59, 59, + nil, 59, 59, 59, 59, nil, nil, nil, nil, 59, + 59, nil, nil, nil, 60, 60, 60, 59, 60, 59, + 59, 59, 60, 60, nil, nil, nil, 60, nil, 60, + 60, 60, 60, 60, 60, 60, nil, nil, nil, nil, + nil, 60, 60, 60, 60, 60, 60, 60, nil, nil, + 60, nil, nil, nil, nil, nil, nil, 60, nil, nil, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, nil, 60, 60, 60, 60, 60, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 60, nil, nil, + 60, nil, nil, 60, 60, nil, nil, 60, nil, nil, + nil, nil, nil, 60, nil, nil, 60, nil, nil, nil, + nil, nil, 60, nil, nil, nil, nil, 60, 60, 60, + 60, nil, 60, 60, 60, 60, nil, nil, nil, nil, + 60, 60, nil, nil, nil, 63, 63, 63, 60, 63, + 60, 60, 60, 63, 63, nil, nil, nil, 63, nil, + 63, 63, 63, 63, 63, 63, 63, nil, nil, nil, + nil, nil, 63, 63, 63, 63, 63, 63, 63, nil, + nil, 63, nil, nil, nil, nil, nil, nil, 63, nil, + nil, 63, 63, 63, 63, 63, 63, 63, 63, nil, + 63, 63, 63, nil, 63, 63, 63, 63, 63, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 63, nil, + nil, 63, nil, nil, 63, 63, nil, nil, 63, nil, + nil, nil, nil, nil, 63, nil, nil, nil, nil, nil, + nil, nil, nil, 63, nil, nil, nil, nil, 63, 63, + 63, 63, nil, 63, 63, 63, 63, nil, nil, nil, + nil, 63, 63, nil, nil, nil, 64, 64, 64, 63, + 64, 63, 63, 63, 64, 64, nil, nil, nil, 64, + nil, 64, 64, 64, 64, 64, 64, 64, nil, nil, + nil, nil, nil, 64, 64, 64, 64, 64, 64, 64, + nil, nil, 64, nil, nil, nil, nil, nil, nil, 64, + nil, nil, 64, 64, 64, 64, 64, 64, 64, 64, + nil, 64, 64, 64, nil, 64, 64, 64, 64, 64, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 64, + nil, nil, 64, nil, nil, 64, 64, nil, nil, 64, + nil, nil, nil, nil, nil, 64, nil, nil, nil, nil, + nil, nil, nil, nil, 64, nil, nil, nil, nil, 64, + 64, 64, 64, nil, 64, 64, 64, 64, nil, nil, + nil, nil, 64, 64, nil, nil, nil, 67, 67, 67, + 64, 67, 64, 64, 64, 67, 67, nil, nil, nil, + 67, nil, 67, 67, 67, 67, 67, 67, 67, nil, + nil, nil, nil, nil, 67, 67, 67, 67, 67, 67, + 67, nil, nil, 67, nil, nil, nil, nil, nil, nil, + 67, nil, nil, 67, 67, 67, 67, 67, 67, 67, + 67, nil, 67, 67, 67, nil, 67, 67, 67, 67, + 67, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 67, nil, nil, 67, nil, nil, 67, 67, nil, nil, + 67, nil, nil, nil, nil, nil, 67, nil, nil, nil, + nil, nil, nil, nil, nil, 67, nil, nil, nil, nil, + 67, 67, 67, 67, nil, 67, 67, 67, 67, nil, + nil, nil, nil, 67, 67, 67, nil, nil, nil, nil, + 67, 67, nil, 67, 67, 67, 68, 68, 68, nil, + 68, nil, nil, nil, 68, 68, nil, nil, nil, 68, + nil, 68, 68, 68, 68, 68, 68, 68, nil, nil, + nil, nil, nil, 68, 68, 68, 68, 68, 68, 68, + nil, nil, 68, nil, nil, nil, nil, nil, nil, 68, + nil, nil, 68, 68, 68, 68, 68, 68, 68, 68, + nil, 68, 68, 68, nil, 68, 68, nil, nil, 68, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 68, + nil, nil, 68, nil, nil, 68, 68, nil, nil, 68, + nil, 68, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 68, + 68, 68, 68, nil, 68, 68, 68, 68, nil, nil, + nil, nil, 68, 68, nil, nil, nil, 69, 69, 69, + 68, 69, 68, 68, 68, 69, 69, nil, nil, nil, + 69, nil, 69, 69, 69, 69, 69, 69, 69, nil, + nil, nil, nil, nil, 69, 69, 69, 69, 69, 69, + 69, nil, nil, 69, nil, nil, nil, nil, nil, nil, + 69, nil, nil, 69, 69, 69, 69, 69, 69, 69, + 69, nil, 69, 69, 69, nil, 69, 69, nil, nil, + 69, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 69, nil, nil, + 69, nil, nil, 69, nil, nil, 69, 69, nil, nil, + 69, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 69, 69, 69, 69, nil, 69, 69, 69, 69, nil, + nil, nil, nil, 69, 69, nil, nil, nil, 70, 70, + 70, 69, 70, 69, 69, 69, 70, 70, nil, nil, + nil, 70, nil, 70, 70, 70, 70, 70, 70, 70, + nil, nil, nil, nil, nil, 70, 70, 70, 70, 70, + 70, 70, nil, nil, 70, nil, nil, nil, nil, nil, + nil, 70, nil, nil, 70, 70, 70, 70, 70, 70, + 70, 70, nil, 70, 70, 70, nil, 70, 70, nil, + nil, 70, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 70, nil, nil, 70, nil, nil, 70, 70, nil, + nil, 70, nil, nil, 850, nil, 850, 850, 850, 850, + 850, nil, nil, nil, nil, nil, nil, nil, nil, 850, + nil, 70, 70, 70, 70, nil, 70, 70, 70, 70, + nil, nil, nil, nil, 70, 70, nil, nil, nil, nil, + nil, 850, 70, nil, 70, 70, 70, 113, 113, 113, + 113, 113, 850, 850, nil, 113, 113, 850, nil, nil, + 113, nil, 113, 113, 113, 113, 113, 113, 113, nil, + nil, nil, nil, nil, 113, 113, 113, 113, 113, 113, + 113, nil, nil, 113, nil, nil, nil, nil, nil, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, nil, 113, 113, 113, nil, 113, 113, 113, 113, + 113, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 113, nil, nil, 113, nil, nil, 113, 113, nil, nil, + 113, nil, 113, nil, nil, nil, 113, nil, nil, nil, + nil, nil, nil, nil, nil, 113, nil, nil, nil, nil, + 113, 113, 113, 113, nil, 113, 113, 113, 113, nil, + nil, nil, nil, 113, 113, nil, nil, nil, nil, nil, + 113, 113, nil, 113, 113, 113, 118, 118, 118, nil, + 118, nil, nil, nil, 118, 118, nil, nil, nil, 118, + nil, 118, 118, 118, 118, 118, 118, 118, nil, nil, + nil, nil, nil, 118, 118, 118, 118, 118, 118, 118, + nil, nil, 118, nil, nil, nil, nil, nil, nil, 118, + nil, nil, 118, 118, 118, 118, 118, 118, 118, 118, + nil, 118, 118, 118, nil, 118, 118, 118, 118, 118, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 118, + nil, nil, 118, nil, nil, 118, 118, nil, nil, 118, + nil, nil, nil, nil, nil, 118, nil, nil, nil, nil, + nil, nil, nil, nil, 118, nil, nil, nil, nil, 118, + 118, 118, 118, nil, 118, 118, 118, 118, nil, nil, + nil, nil, 118, 118, nil, nil, nil, 119, 119, 119, + 118, 119, 118, 118, 118, 119, 119, nil, nil, nil, + 119, nil, 119, 119, 119, 119, 119, 119, 119, nil, + nil, nil, nil, nil, 119, 119, 119, 119, 119, 119, + 119, nil, nil, 119, nil, nil, nil, nil, nil, nil, + 119, nil, nil, 119, 119, 119, 119, 119, 119, 119, + 119, nil, 119, 119, 119, nil, 119, 119, 119, 119, + 119, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 119, nil, nil, 119, nil, nil, 119, 119, nil, nil, + 119, nil, nil, nil, nil, nil, 119, nil, nil, nil, + nil, nil, nil, nil, nil, 119, nil, nil, nil, nil, + 119, 119, 119, 119, nil, 119, 119, 119, 119, nil, + nil, nil, nil, 119, 119, nil, nil, nil, 120, 120, + 120, 119, 120, 119, 119, 119, 120, 120, nil, nil, + nil, 120, nil, 120, 120, 120, 120, 120, 120, 120, + nil, nil, nil, nil, nil, 120, 120, 120, 120, 120, + 120, 120, nil, nil, 120, nil, nil, nil, nil, nil, + nil, 120, nil, nil, 120, 120, 120, 120, 120, 120, + 120, 120, nil, 120, 120, 120, nil, 120, 120, 120, + 120, 120, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 120, nil, nil, 120, nil, nil, 120, 120, nil, + nil, 120, nil, nil, nil, nil, nil, 120, nil, nil, + nil, nil, nil, nil, nil, nil, 120, nil, nil, nil, + nil, 120, 120, 120, 120, nil, 120, 120, 120, 120, + nil, nil, nil, nil, 120, 120, nil, nil, nil, 121, + 121, 121, 120, 121, 120, 120, 120, 121, 121, nil, + nil, nil, 121, nil, 121, 121, 121, 121, 121, 121, + 121, nil, nil, nil, nil, nil, 121, 121, 121, 121, + 121, 121, 121, nil, nil, 121, nil, nil, nil, nil, + nil, nil, 121, nil, nil, 121, 121, 121, 121, 121, + 121, 121, 121, nil, 121, 121, 121, nil, 121, 121, + 121, 121, 121, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 121, nil, nil, 121, nil, nil, 121, 121, + nil, nil, 121, nil, nil, nil, nil, nil, 121, nil, + nil, nil, nil, nil, nil, nil, nil, 121, nil, nil, + nil, nil, 121, 121, 121, 121, nil, 121, 121, 121, + 121, nil, nil, nil, nil, 121, 121, nil, nil, nil, + nil, nil, nil, 121, nil, 121, 121, 121, 122, 122, + 122, 122, 122, nil, nil, nil, 122, 122, nil, nil, + nil, 122, nil, 122, 122, 122, 122, 122, 122, 122, + nil, nil, nil, nil, nil, 122, 122, 122, 122, 122, + 122, 122, nil, nil, 122, nil, nil, nil, nil, nil, + 122, 122, nil, 122, 122, 122, 122, 122, 122, 122, + 122, 122, nil, 122, 122, 122, nil, 122, 122, 122, + 122, 122, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 122, nil, nil, 122, nil, nil, 122, 122, nil, + nil, 122, nil, 122, nil, nil, nil, 122, nil, nil, + nil, nil, nil, nil, nil, nil, 122, nil, nil, nil, + nil, 122, 122, 122, 122, nil, 122, 122, 122, 122, + nil, nil, nil, nil, 122, 122, nil, nil, nil, 209, + 209, 209, 122, 209, 122, 122, 122, 209, 209, nil, + nil, nil, 209, nil, 209, 209, 209, 209, 209, 209, + 209, nil, nil, nil, nil, nil, 209, 209, 209, 209, + 209, 209, 209, nil, nil, 209, nil, nil, nil, nil, + nil, nil, 209, nil, nil, 209, 209, 209, 209, 209, + 209, 209, 209, nil, 209, 209, 209, nil, 209, 209, + 209, 209, 209, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 209, nil, nil, 209, nil, nil, 209, 209, + nil, nil, 209, nil, 209, nil, nil, nil, 209, nil, + nil, nil, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, 209, 209, 209, 209, nil, 209, 209, 209, + 209, nil, nil, nil, nil, 209, 209, nil, nil, nil, + 210, 210, 210, 209, 210, 209, 209, 209, 210, 210, + nil, nil, nil, 210, nil, 210, 210, 210, 210, 210, + 210, 210, nil, nil, nil, nil, nil, 210, 210, 210, + 210, 210, 210, 210, nil, nil, 210, nil, nil, nil, + nil, nil, nil, 210, nil, nil, 210, 210, 210, 210, + 210, 210, 210, 210, nil, 210, 210, 210, nil, 210, + 210, 210, 210, 210, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 210, nil, nil, 210, nil, nil, 210, + 210, nil, nil, 210, nil, nil, nil, nil, nil, 210, + nil, nil, nil, nil, nil, nil, nil, nil, 210, nil, + nil, nil, nil, 210, 210, 210, 210, nil, 210, 210, + 210, 210, nil, nil, nil, nil, 210, 210, nil, nil, + nil, 211, 211, 211, 210, 211, 210, 210, 210, 211, + 211, nil, nil, nil, 211, nil, 211, 211, 211, 211, + 211, 211, 211, nil, nil, nil, nil, nil, 211, 211, + 211, 211, 211, 211, 211, nil, nil, 211, nil, nil, + nil, nil, nil, nil, 211, nil, nil, 211, 211, 211, + 211, 211, 211, 211, 211, 211, 211, 211, 211, nil, + 211, 211, 211, 211, 211, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 211, nil, nil, 211, nil, nil, + 211, 211, nil, nil, 211, nil, 211, nil, 211, nil, + 211, nil, nil, 211, nil, nil, nil, nil, nil, 211, + nil, nil, nil, nil, 211, 211, 211, 211, nil, 211, + 211, 211, 211, nil, nil, nil, nil, 211, 211, nil, + nil, nil, 214, 214, 214, 211, 214, 211, 211, 211, + 214, 214, nil, nil, nil, 214, nil, 214, 214, 214, + 214, 214, 214, 214, nil, nil, nil, nil, nil, 214, + 214, 214, 214, 214, 214, 214, nil, nil, 214, nil, + nil, nil, nil, nil, nil, 214, nil, nil, 214, 214, + 214, 214, 214, 214, 214, 214, nil, 214, 214, 214, + nil, 214, 214, 214, 214, 214, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 214, nil, nil, 214, nil, + nil, 214, 214, nil, nil, 214, nil, nil, nil, nil, + nil, 214, nil, nil, nil, nil, nil, nil, nil, nil, + 214, nil, nil, nil, nil, 214, 214, 214, 214, nil, + 214, 214, 214, 214, nil, nil, nil, nil, 214, 214, + nil, nil, nil, 215, 215, 215, 214, 215, 214, 214, + 214, 215, 215, nil, nil, nil, 215, nil, 215, 215, + 215, 215, 215, 215, 215, nil, nil, nil, nil, nil, + 215, 215, 215, 215, 215, 215, 215, nil, nil, 215, + nil, nil, nil, nil, nil, nil, 215, nil, nil, 215, + 215, 215, 215, 215, 215, 215, 215, nil, 215, 215, + 215, nil, 215, 215, 215, 215, 215, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 215, nil, nil, 215, + nil, nil, 215, 215, nil, nil, 215, nil, 215, nil, + nil, nil, 215, nil, nil, nil, nil, nil, nil, nil, + nil, 215, nil, nil, nil, nil, 215, 215, 215, 215, + nil, 215, 215, 215, 215, nil, nil, nil, nil, 215, + 215, nil, nil, nil, 216, 216, 216, 215, 216, 215, + 215, 215, 216, 216, nil, nil, nil, 216, nil, 216, + 216, 216, 216, 216, 216, 216, nil, nil, nil, nil, + nil, 216, 216, 216, 216, 216, 216, 216, nil, nil, + 216, nil, nil, nil, nil, nil, nil, 216, nil, nil, + 216, 216, 216, 216, 216, 216, 216, 216, nil, 216, + 216, 216, nil, 216, 216, 216, 216, 216, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 216, nil, nil, + 216, nil, nil, 216, 216, nil, nil, 216, nil, nil, + nil, nil, nil, 216, nil, nil, nil, nil, nil, nil, + nil, nil, 216, nil, nil, nil, nil, 216, 216, 216, + 216, nil, 216, 216, 216, 216, nil, nil, nil, nil, + 216, 216, nil, nil, nil, 217, 217, 217, 216, 217, + 216, 216, 216, 217, 217, nil, nil, nil, 217, nil, + 217, 217, 217, 217, 217, 217, 217, nil, nil, nil, + nil, nil, 217, 217, 217, 217, 217, 217, 217, nil, + nil, 217, nil, nil, nil, nil, nil, nil, 217, nil, + nil, 217, 217, 217, 217, 217, 217, 217, 217, nil, + 217, 217, 217, nil, 217, 217, 217, 217, 217, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 217, nil, + nil, 217, nil, nil, 217, 217, nil, nil, 217, nil, + nil, nil, nil, nil, 217, nil, nil, nil, nil, nil, + nil, nil, nil, 217, nil, nil, nil, nil, 217, 217, + 217, 217, nil, 217, 217, 217, 217, nil, nil, nil, + nil, 217, 217, nil, nil, nil, 218, 218, 218, 217, + 218, 217, 217, 217, 218, 218, nil, nil, nil, 218, + nil, 218, 218, 218, 218, 218, 218, 218, nil, nil, + nil, nil, nil, 218, 218, 218, 218, 218, 218, 218, + nil, nil, 218, nil, nil, nil, nil, nil, nil, 218, + nil, nil, 218, 218, 218, 218, 218, 218, 218, 218, + nil, 218, 218, 218, nil, 218, 218, 218, 218, 218, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 218, + nil, nil, 218, nil, nil, 218, 218, nil, nil, 218, + nil, nil, nil, nil, nil, 218, nil, nil, nil, nil, + nil, nil, nil, nil, 218, nil, nil, nil, nil, 218, + 218, 218, 218, nil, 218, 218, 218, 218, nil, nil, + nil, nil, 218, 218, nil, nil, nil, 219, 219, 219, + 218, 219, 218, 218, 218, 219, 219, nil, nil, nil, + 219, nil, 219, 219, 219, 219, 219, 219, 219, nil, + nil, nil, nil, nil, 219, 219, 219, 219, 219, 219, + 219, nil, nil, 219, nil, nil, nil, nil, nil, nil, + 219, nil, nil, 219, 219, 219, 219, 219, 219, 219, + 219, nil, 219, 219, 219, nil, 219, 219, 219, 219, + 219, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 219, nil, nil, 219, nil, nil, 219, 219, nil, nil, + 219, nil, nil, nil, nil, nil, 219, nil, nil, nil, + nil, nil, nil, nil, nil, 219, nil, nil, nil, nil, + 219, 219, 219, 219, nil, 219, 219, 219, 219, nil, + nil, nil, nil, 219, 219, 219, nil, nil, 230, 230, + 230, 219, 230, 219, 219, 219, 230, 230, nil, nil, + nil, 230, nil, 230, 230, 230, 230, 230, 230, 230, + nil, nil, nil, nil, nil, 230, 230, 230, 230, 230, + 230, 230, nil, nil, 230, nil, nil, nil, nil, nil, + nil, 230, nil, nil, 230, 230, 230, 230, 230, 230, + 230, 230, nil, 230, 230, 230, nil, 230, 230, 230, + 230, 230, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, 230, nil, nil, 230, 230, nil, + nil, 230, nil, nil, nil, nil, nil, 230, nil, nil, + nil, nil, nil, nil, nil, nil, 230, nil, nil, nil, + nil, 230, 230, 230, 230, nil, 230, 230, 230, 230, + nil, nil, nil, nil, 230, 230, nil, nil, nil, 233, + 233, 233, 230, 233, 230, 230, 230, 233, 233, nil, + nil, nil, 233, nil, 233, 233, 233, 233, 233, 233, + 233, nil, nil, nil, nil, nil, 233, 233, 233, 233, + 233, 233, 233, nil, nil, 233, nil, nil, nil, nil, + nil, nil, 233, nil, nil, 233, 233, 233, 233, 233, + 233, 233, 233, nil, 233, 233, 233, nil, 233, 233, + 233, 233, 233, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 233, nil, nil, 233, nil, nil, 233, 233, + nil, nil, 233, nil, nil, nil, nil, nil, 233, nil, + nil, nil, nil, nil, nil, nil, nil, 233, nil, nil, + nil, nil, 233, 233, 233, 233, nil, 233, 233, 233, + 233, nil, nil, nil, nil, 233, 233, nil, nil, nil, + 234, 234, 234, 233, 234, 233, 233, 233, 234, 234, + nil, nil, nil, 234, nil, 234, 234, 234, 234, 234, + 234, 234, nil, nil, nil, nil, nil, 234, 234, 234, + 234, 234, 234, 234, nil, nil, 234, nil, nil, nil, + nil, nil, nil, 234, nil, nil, 234, 234, 234, 234, + 234, 234, 234, 234, nil, 234, 234, 234, nil, 234, + 234, 234, 234, 234, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 234, nil, nil, 234, nil, nil, 234, + 234, nil, nil, 234, nil, nil, nil, nil, nil, 234, + nil, nil, nil, nil, nil, nil, nil, nil, 234, nil, + nil, nil, nil, 234, 234, 234, 234, nil, 234, 234, + 234, 234, nil, nil, nil, nil, 234, 234, nil, nil, + nil, 235, 235, 235, 234, 235, 234, 234, 234, 235, + 235, nil, nil, nil, 235, nil, 235, 235, 235, 235, + 235, 235, 235, nil, nil, nil, nil, nil, 235, 235, + 235, 235, 235, 235, 235, nil, nil, 235, nil, nil, + nil, nil, nil, nil, 235, nil, nil, 235, 235, 235, + 235, 235, 235, 235, 235, nil, 235, 235, 235, nil, + 235, 235, 235, 235, 235, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 235, nil, nil, 235, nil, nil, + 235, 235, nil, nil, 235, nil, nil, nil, nil, nil, + 235, nil, nil, nil, nil, nil, nil, nil, nil, 235, + nil, nil, nil, nil, 235, 235, 235, 235, nil, 235, + 235, 235, 235, nil, nil, nil, nil, 235, 235, nil, + nil, nil, 236, 236, 236, 235, 236, 235, 235, 235, + 236, 236, nil, nil, nil, 236, nil, 236, 236, 236, + 236, 236, 236, 236, nil, nil, nil, nil, nil, 236, + 236, 236, 236, 236, 236, 236, nil, nil, 236, nil, + nil, nil, nil, nil, nil, 236, nil, nil, 236, 236, + 236, 236, 236, 236, 236, 236, nil, 236, 236, 236, + nil, 236, 236, 236, 236, 236, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 236, nil, nil, 236, nil, + nil, 236, 236, nil, nil, 236, nil, nil, nil, nil, + nil, 236, nil, nil, nil, nil, nil, nil, nil, nil, + 236, nil, nil, nil, nil, 236, 236, 236, 236, nil, + 236, 236, 236, 236, nil, nil, nil, nil, 236, 236, + nil, nil, nil, 237, 237, 237, 236, 237, 236, 236, + 236, 237, 237, nil, nil, nil, 237, nil, 237, 237, + 237, 237, 237, 237, 237, nil, nil, nil, nil, nil, + 237, 237, 237, 237, 237, 237, 237, nil, nil, 237, + nil, nil, nil, nil, nil, nil, 237, nil, nil, 237, + 237, 237, 237, 237, 237, 237, 237, nil, 237, 237, + 237, nil, 237, 237, 237, 237, 237, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 237, nil, nil, 237, + nil, nil, 237, 237, nil, nil, 237, nil, nil, nil, + nil, nil, 237, nil, nil, nil, nil, nil, nil, nil, + nil, 237, nil, nil, nil, nil, 237, 237, 237, 237, + nil, 237, 237, 237, 237, nil, nil, nil, nil, 237, + 237, nil, nil, nil, 238, 238, 238, 237, 238, 237, + 237, 237, 238, 238, nil, nil, nil, 238, nil, 238, + 238, 238, 238, 238, 238, 238, nil, nil, nil, nil, + nil, 238, 238, 238, 238, 238, 238, 238, nil, nil, + 238, nil, nil, nil, nil, nil, nil, 238, nil, nil, + 238, 238, 238, 238, 238, 238, 238, 238, nil, 238, + 238, 238, nil, 238, 238, 238, 238, 238, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 238, nil, nil, + 238, nil, nil, 238, 238, nil, nil, 238, nil, nil, + nil, nil, nil, 238, nil, nil, nil, nil, nil, nil, + nil, nil, 238, nil, nil, nil, nil, 238, 238, 238, + 238, nil, 238, 238, 238, 238, nil, nil, nil, nil, + 238, 238, nil, nil, nil, 239, 239, 239, 238, 239, + 238, 238, 238, 239, 239, nil, nil, nil, 239, nil, + 239, 239, 239, 239, 239, 239, 239, nil, nil, nil, + nil, nil, 239, 239, 239, 239, 239, 239, 239, nil, + nil, 239, nil, nil, nil, nil, nil, nil, 239, nil, + nil, 239, 239, 239, 239, 239, 239, 239, 239, nil, + 239, 239, 239, nil, 239, 239, 239, 239, 239, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 239, nil, + nil, 239, nil, nil, 239, 239, nil, nil, 239, nil, + nil, nil, nil, nil, 239, nil, nil, nil, nil, nil, + nil, nil, nil, 239, nil, nil, nil, nil, 239, 239, + 239, 239, nil, 239, 239, 239, 239, nil, nil, nil, + nil, 239, 239, nil, nil, nil, 240, 240, 240, 239, + 240, 239, 239, 239, 240, 240, nil, nil, nil, 240, + nil, 240, 240, 240, 240, 240, 240, 240, nil, nil, + nil, nil, nil, 240, 240, 240, 240, 240, 240, 240, + nil, nil, 240, nil, nil, nil, nil, nil, nil, 240, + nil, nil, 240, 240, 240, 240, 240, 240, 240, 240, + nil, 240, 240, 240, nil, 240, 240, 240, 240, 240, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 240, + nil, nil, 240, nil, nil, 240, 240, nil, nil, 240, + nil, nil, nil, nil, nil, 240, nil, nil, nil, nil, + nil, nil, nil, nil, 240, nil, nil, nil, nil, 240, + 240, 240, 240, nil, 240, 240, 240, 240, nil, nil, + nil, nil, 240, 240, nil, nil, nil, 241, 241, 241, + 240, 241, 240, 240, 240, 241, 241, nil, nil, nil, + 241, nil, 241, 241, 241, 241, 241, 241, 241, nil, + nil, nil, nil, nil, 241, 241, 241, 241, 241, 241, + 241, nil, nil, 241, nil, nil, nil, nil, nil, nil, + 241, nil, nil, 241, 241, 241, 241, 241, 241, 241, + 241, nil, 241, 241, 241, nil, 241, 241, 241, 241, + 241, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 241, nil, nil, 241, nil, nil, 241, 241, nil, nil, + 241, nil, nil, nil, nil, nil, 241, nil, nil, nil, + nil, nil, nil, nil, nil, 241, nil, nil, nil, nil, + 241, 241, 241, 241, nil, 241, 241, 241, 241, nil, + nil, nil, nil, 241, 241, nil, nil, nil, 242, 242, + 242, 241, 242, 241, 241, 241, 242, 242, nil, nil, + nil, 242, nil, 242, 242, 242, 242, 242, 242, 242, + nil, nil, nil, nil, nil, 242, 242, 242, 242, 242, + 242, 242, nil, nil, 242, nil, nil, nil, nil, nil, + nil, 242, nil, nil, 242, 242, 242, 242, 242, 242, + 242, 242, nil, 242, 242, 242, nil, 242, 242, 242, + 242, 242, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 242, nil, nil, 242, nil, nil, 242, 242, nil, + nil, 242, nil, nil, nil, nil, nil, 242, nil, nil, + nil, nil, nil, nil, nil, nil, 242, nil, nil, nil, + nil, 242, 242, 242, 242, nil, 242, 242, 242, 242, + nil, nil, nil, nil, 242, 242, nil, nil, nil, 243, + 243, 243, 242, 243, 242, 242, 242, 243, 243, nil, + nil, nil, 243, nil, 243, 243, 243, 243, 243, 243, + 243, nil, nil, nil, nil, nil, 243, 243, 243, 243, + 243, 243, 243, nil, nil, 243, nil, nil, nil, nil, + nil, nil, 243, nil, nil, 243, 243, 243, 243, 243, + 243, 243, 243, nil, 243, 243, 243, nil, 243, 243, + 243, 243, 243, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 243, nil, nil, 243, nil, nil, 243, 243, + nil, nil, 243, nil, nil, nil, nil, nil, 243, nil, + nil, nil, nil, nil, nil, nil, nil, 243, nil, nil, + nil, nil, 243, 243, 243, 243, nil, 243, 243, 243, + 243, nil, nil, nil, nil, 243, 243, nil, nil, nil, + 244, 244, 244, 243, 244, 243, 243, 243, 244, 244, + nil, nil, nil, 244, nil, 244, 244, 244, 244, 244, + 244, 244, nil, nil, nil, nil, nil, 244, 244, 244, + 244, 244, 244, 244, nil, nil, 244, nil, nil, nil, + nil, nil, nil, 244, nil, nil, 244, 244, 244, 244, + 244, 244, 244, 244, nil, 244, 244, 244, nil, 244, + 244, 244, 244, 244, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 244, nil, nil, 244, nil, nil, 244, + 244, nil, nil, 244, nil, nil, nil, nil, nil, 244, + nil, nil, nil, nil, nil, nil, nil, nil, 244, nil, + nil, nil, nil, 244, 244, 244, 244, nil, 244, 244, + 244, 244, nil, nil, nil, nil, 244, 244, nil, nil, + nil, 245, 245, 245, 244, 245, 244, 244, 244, 245, + 245, nil, nil, nil, 245, nil, 245, 245, 245, 245, + 245, 245, 245, nil, nil, nil, nil, nil, 245, 245, + 245, 245, 245, 245, 245, nil, nil, 245, nil, nil, + nil, nil, nil, nil, 245, nil, nil, 245, 245, 245, + 245, 245, 245, 245, 245, nil, 245, 245, 245, nil, + 245, 245, 245, 245, 245, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 245, nil, nil, 245, nil, nil, + 245, 245, nil, nil, 245, nil, nil, nil, nil, nil, + 245, nil, nil, nil, nil, nil, nil, nil, nil, 245, + nil, nil, nil, nil, 245, 245, 245, 245, nil, 245, + 245, 245, 245, nil, nil, nil, nil, 245, 245, nil, + nil, nil, 246, 246, 246, 245, 246, 245, 245, 245, + 246, 246, nil, nil, nil, 246, nil, 246, 246, 246, + 246, 246, 246, 246, nil, nil, nil, nil, nil, 246, + 246, 246, 246, 246, 246, 246, nil, nil, 246, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 246, 246, + 246, 246, 246, 246, 246, 246, nil, 246, 246, 246, + nil, 246, 246, 246, 246, 246, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 246, nil, + nil, 246, 246, nil, nil, 246, nil, nil, nil, nil, + nil, 246, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, nil, nil, 246, 246, 246, 246, nil, + 246, 246, 246, 246, nil, nil, nil, nil, 246, 246, + nil, nil, nil, 247, 247, 247, 246, 247, 246, 246, + 246, 247, 247, nil, nil, nil, 247, nil, 247, 247, + 247, 247, 247, 247, 247, nil, nil, nil, nil, nil, + 247, 247, 247, 247, 247, 247, 247, nil, nil, 247, + nil, nil, nil, nil, nil, nil, 247, nil, nil, 247, + 247, 247, 247, 247, 247, 247, 247, nil, 247, 247, + 247, nil, 247, 247, 247, 247, 247, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 247, nil, nil, 247, + nil, nil, 247, 247, nil, nil, 247, nil, nil, nil, + nil, nil, 247, nil, nil, nil, nil, nil, nil, nil, + nil, 247, nil, nil, nil, nil, 247, 247, 247, 247, + nil, 247, 247, 247, 247, nil, nil, nil, nil, 247, + 247, nil, nil, nil, 248, 248, 248, 247, 248, 247, + 247, 247, 248, 248, nil, nil, nil, 248, nil, 248, + 248, 248, 248, 248, 248, 248, nil, nil, nil, nil, + nil, 248, 248, 248, 248, 248, 248, 248, nil, nil, + 248, nil, nil, nil, nil, nil, nil, 248, nil, nil, + 248, 248, 248, 248, 248, 248, 248, 248, nil, 248, + 248, 248, nil, 248, 248, 248, 248, 248, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 248, nil, nil, + 248, nil, nil, 248, 248, nil, nil, 248, nil, nil, + nil, nil, nil, 248, nil, nil, nil, nil, nil, nil, + nil, nil, 248, nil, nil, nil, nil, 248, 248, 248, + 248, nil, 248, 248, 248, 248, nil, nil, nil, nil, + 248, 248, nil, nil, nil, 249, 249, 249, 248, 249, + 248, 248, 248, 249, 249, nil, nil, nil, 249, nil, + 249, 249, 249, 249, 249, 249, 249, nil, nil, nil, + nil, nil, 249, 249, 249, 249, 249, 249, 249, nil, + nil, 249, nil, nil, nil, nil, nil, nil, 249, nil, + nil, 249, 249, 249, 249, 249, 249, 249, 249, nil, + 249, 249, 249, nil, 249, 249, 249, 249, 249, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 249, nil, + nil, 249, nil, nil, 249, 249, nil, nil, 249, nil, + nil, nil, nil, nil, 249, nil, nil, nil, nil, nil, + nil, nil, nil, 249, nil, nil, nil, nil, 249, 249, + 249, 249, nil, 249, 249, 249, 249, nil, nil, nil, + nil, 249, 249, nil, nil, nil, 250, 250, 250, 249, + 250, 249, 249, 249, 250, 250, nil, nil, nil, 250, + nil, 250, 250, 250, 250, 250, 250, 250, nil, nil, + nil, nil, nil, 250, 250, 250, 250, 250, 250, 250, + nil, nil, 250, nil, nil, nil, nil, nil, nil, 250, + nil, nil, 250, 250, 250, 250, 250, 250, 250, 250, + nil, 250, 250, 250, nil, 250, 250, 250, 250, 250, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 250, + nil, nil, 250, nil, nil, 250, 250, nil, nil, 250, + nil, nil, nil, nil, nil, 250, nil, nil, nil, nil, + nil, nil, nil, nil, 250, nil, nil, nil, nil, 250, + 250, 250, 250, nil, 250, 250, 250, 250, nil, nil, + nil, nil, 250, 250, nil, nil, nil, 251, 251, 251, + 250, 251, 250, 250, 250, 251, 251, nil, nil, nil, + 251, nil, 251, 251, 251, 251, 251, 251, 251, nil, + nil, nil, nil, nil, 251, 251, 251, 251, 251, 251, + 251, nil, nil, 251, nil, nil, nil, nil, nil, nil, + 251, nil, nil, 251, 251, 251, 251, 251, 251, 251, + 251, nil, 251, 251, 251, nil, 251, 251, 251, 251, + 251, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 251, nil, nil, 251, nil, nil, 251, 251, nil, nil, + 251, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 251, 251, 251, 251, nil, 251, 251, 251, 251, nil, + nil, nil, nil, 251, 251, nil, nil, nil, 252, 252, + 252, 251, 252, 251, 251, 251, 252, 252, nil, nil, + nil, 252, nil, 252, 252, 252, 252, 252, 252, 252, + nil, nil, nil, nil, nil, 252, 252, 252, 252, 252, + 252, 252, nil, nil, 252, nil, nil, nil, nil, nil, + nil, 252, nil, nil, 252, 252, 252, 252, 252, 252, + 252, 252, nil, 252, 252, 252, nil, 252, 252, 252, + 252, 252, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 252, nil, nil, 252, nil, nil, 252, 252, nil, + nil, 252, nil, nil, nil, nil, nil, 252, nil, nil, + nil, nil, nil, nil, nil, nil, 252, nil, nil, nil, + nil, 252, 252, 252, 252, nil, 252, 252, 252, 252, + nil, nil, nil, nil, 252, 252, nil, nil, nil, 253, + 253, 253, 252, 253, 252, 252, 252, 253, 253, nil, + nil, nil, 253, nil, 253, 253, 253, 253, 253, 253, + 253, nil, nil, nil, nil, nil, 253, 253, 253, 253, + 253, 253, 253, nil, nil, 253, nil, nil, nil, nil, + nil, nil, 253, nil, nil, 253, 253, 253, 253, 253, + 253, 253, 253, nil, 253, 253, 253, nil, 253, 253, + 253, 253, 253, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 253, nil, nil, 253, nil, nil, 253, 253, + nil, nil, 253, nil, nil, nil, nil, nil, 253, nil, + nil, nil, nil, nil, nil, nil, nil, 253, nil, nil, + nil, nil, 253, 253, 253, 253, nil, 253, 253, 253, + 253, nil, nil, nil, nil, 253, 253, nil, nil, nil, + 254, 254, 254, 253, 254, 253, 253, 253, 254, 254, + nil, nil, nil, 254, nil, 254, 254, 254, 254, 254, + 254, 254, nil, nil, nil, nil, nil, 254, 254, 254, + 254, 254, 254, 254, nil, nil, 254, nil, nil, nil, + nil, nil, nil, 254, nil, nil, 254, 254, 254, 254, + 254, 254, 254, 254, nil, 254, 254, 254, nil, 254, + 254, 254, 254, 254, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 254, nil, nil, 254, nil, nil, 254, + 254, nil, nil, 254, nil, nil, nil, nil, nil, 254, + nil, nil, nil, nil, nil, nil, nil, nil, 254, nil, + nil, nil, nil, 254, 254, 254, 254, nil, 254, 254, + 254, 254, nil, nil, nil, nil, 254, 254, nil, nil, + nil, 255, 255, 255, 254, 255, 254, 254, 254, 255, + 255, nil, nil, nil, 255, nil, 255, 255, 255, 255, + 255, 255, 255, nil, nil, nil, nil, nil, 255, 255, + 255, 255, 255, 255, 255, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 255, nil, nil, 255, 255, 255, + 255, 255, 255, 255, 255, nil, 255, 255, 255, nil, + 255, 255, 255, 255, 255, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 255, nil, nil, 255, nil, nil, + 255, 255, nil, nil, 255, nil, nil, nil, nil, nil, + 255, nil, nil, nil, nil, nil, nil, nil, nil, 255, + nil, nil, nil, nil, 255, 255, 255, 255, nil, 255, + 255, 255, 255, nil, nil, nil, nil, 255, 255, nil, + nil, nil, 256, 256, 256, 255, 256, 255, 255, 255, + 256, 256, nil, nil, nil, 256, nil, 256, 256, 256, + 256, 256, 256, 256, nil, nil, nil, nil, nil, 256, + 256, 256, 256, 256, 256, 256, nil, nil, 256, nil, + nil, nil, nil, nil, nil, 256, nil, nil, 256, 256, + 256, 256, 256, 256, 256, 256, nil, 256, 256, 256, + nil, 256, 256, 256, 256, 256, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 256, nil, nil, 256, nil, + nil, 256, 256, nil, nil, 256, nil, nil, nil, nil, + nil, 256, nil, nil, nil, nil, nil, nil, nil, nil, + 256, nil, nil, nil, nil, 256, 256, 256, 256, nil, + 256, 256, 256, 256, nil, nil, nil, nil, 256, 256, + nil, nil, nil, 257, 257, 257, 256, 257, 256, 256, + 256, 257, 257, nil, nil, nil, 257, nil, 257, 257, + 257, 257, 257, 257, 257, nil, nil, nil, nil, nil, + 257, 257, 257, 257, 257, 257, 257, nil, nil, 257, + nil, nil, nil, nil, nil, nil, 257, nil, nil, 257, + 257, 257, 257, 257, 257, 257, 257, nil, 257, 257, + 257, nil, 257, 257, 257, 257, 257, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 257, nil, nil, 257, + nil, nil, 257, 257, nil, nil, 257, nil, nil, nil, + nil, nil, 257, nil, nil, nil, nil, nil, nil, nil, + nil, 257, nil, nil, nil, nil, 257, 257, 257, 257, + nil, 257, 257, 257, 257, nil, nil, nil, nil, 257, + 257, nil, nil, nil, 258, 258, 258, 257, 258, 257, + 257, 257, 258, 258, nil, nil, nil, 258, nil, 258, + 258, 258, 258, 258, 258, 258, nil, nil, nil, nil, + nil, 258, 258, 258, 258, 258, 258, 258, nil, nil, + 258, nil, nil, nil, nil, nil, nil, 258, nil, nil, + 258, 258, 258, 258, 258, 258, 258, 258, nil, 258, + 258, 258, nil, 258, 258, 258, 258, 258, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 258, nil, nil, + 258, nil, nil, 258, 258, nil, nil, 258, nil, nil, + nil, nil, nil, 258, nil, nil, nil, nil, nil, nil, + nil, nil, 258, nil, nil, nil, nil, 258, 258, 258, + 258, nil, 258, 258, 258, 258, nil, nil, nil, nil, + 258, 258, nil, nil, nil, 265, 265, 265, 258, 265, + 258, 258, 258, 265, 265, nil, nil, nil, 265, nil, + 265, 265, 265, 265, 265, 265, 265, nil, nil, nil, + nil, nil, 265, 265, 265, 265, 265, 265, 265, nil, + nil, 265, nil, nil, nil, nil, nil, nil, 265, nil, + nil, 265, 265, 265, 265, 265, 265, 265, 265, 265, + 265, 265, 265, nil, 265, 265, 265, 265, 265, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 265, nil, + nil, 265, nil, nil, 265, 265, nil, nil, 265, nil, + 265, nil, 265, nil, 265, nil, nil, 265, nil, nil, + nil, nil, nil, 265, nil, nil, nil, nil, 265, 265, + 265, 265, nil, 265, 265, 265, 265, nil, nil, nil, + nil, 265, 265, nil, nil, nil, 266, 266, 266, 265, + 266, 265, 265, 265, 266, 266, nil, nil, nil, 266, + nil, 266, 266, 266, 266, 266, 266, 266, nil, nil, + nil, nil, nil, 266, 266, 266, 266, 266, 266, 266, + nil, nil, 266, nil, nil, nil, nil, nil, nil, 266, + nil, nil, 266, 266, 266, 266, 266, 266, 266, 266, + 266, 266, 266, 266, nil, 266, 266, 266, 266, 266, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 266, + nil, nil, 266, nil, nil, 266, 266, nil, nil, 266, + nil, 266, nil, 266, nil, 266, nil, nil, 266, nil, + nil, nil, nil, nil, 266, nil, nil, nil, nil, 266, + 266, 266, 266, nil, 266, 266, 266, 266, nil, nil, + nil, nil, 266, 266, nil, nil, nil, 274, 274, 274, + 266, 274, 266, 266, 266, 274, 274, nil, nil, nil, + 274, nil, 274, 274, 274, 274, 274, 274, 274, nil, + nil, nil, nil, nil, 274, 274, 274, 274, 274, 274, + 274, nil, nil, 274, nil, nil, nil, nil, nil, nil, + 274, nil, nil, 274, 274, 274, 274, 274, 274, 274, + 274, 274, 274, 274, 274, nil, 274, 274, 274, 274, + 274, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 274, nil, nil, 274, nil, nil, 274, 274, nil, nil, + 274, nil, 274, nil, 274, nil, 274, nil, nil, 274, + nil, nil, nil, nil, nil, 274, nil, nil, nil, nil, + 274, 274, 274, 274, nil, 274, 274, 274, 274, nil, + nil, nil, nil, 274, 274, 274, nil, nil, 281, 281, + 281, 274, 281, 274, 274, 274, 281, 281, nil, nil, + nil, 281, nil, 281, 281, 281, 281, 281, 281, 281, + nil, nil, nil, nil, nil, 281, 281, 281, 281, 281, + 281, 281, nil, nil, 281, nil, nil, nil, nil, nil, + nil, 281, nil, nil, 281, 281, 281, 281, 281, 281, + 281, 281, nil, 281, 281, 281, nil, 281, 281, 281, + 281, 281, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 281, nil, nil, 281, nil, nil, 281, 281, nil, + nil, 281, nil, nil, nil, nil, nil, 281, nil, nil, + nil, nil, nil, nil, nil, nil, 281, nil, nil, nil, + nil, 281, 281, 281, 281, nil, 281, 281, 281, 281, + nil, nil, nil, nil, 281, 281, nil, nil, nil, 283, + 283, 283, 281, 283, 281, 281, 281, 283, 283, nil, + nil, nil, 283, nil, 283, 283, 283, 283, 283, 283, + 283, nil, nil, nil, nil, nil, 283, 283, 283, 283, + 283, 283, 283, nil, nil, 283, nil, nil, nil, nil, + nil, nil, 283, nil, nil, 283, 283, 283, 283, 283, + 283, 283, 283, nil, 283, 283, 283, nil, 283, 283, + 283, 283, 283, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 283, nil, nil, 283, nil, nil, 283, 283, + nil, nil, 283, nil, nil, nil, nil, nil, 283, nil, + nil, nil, nil, nil, nil, nil, nil, 283, nil, nil, + nil, nil, 283, 283, 283, 283, nil, 283, 283, 283, + 283, nil, nil, nil, nil, 283, 283, nil, nil, nil, + 286, 286, 286, 283, 286, 283, 283, 283, 286, 286, + nil, nil, nil, 286, nil, 286, 286, 286, 286, 286, + 286, 286, nil, nil, nil, nil, nil, 286, 286, 286, + 286, 286, 286, 286, nil, nil, 286, nil, nil, nil, + nil, nil, nil, 286, nil, nil, 286, 286, 286, 286, + 286, 286, 286, 286, nil, 286, 286, 286, nil, 286, + 286, 286, 286, 286, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 286, nil, nil, 286, nil, nil, 286, + 286, nil, nil, 286, nil, nil, nil, nil, nil, 286, + nil, nil, nil, nil, nil, nil, nil, nil, 286, nil, + nil, nil, nil, 286, 286, 286, 286, nil, 286, 286, + 286, 286, nil, nil, nil, nil, 286, 286, nil, nil, + nil, 287, 287, 287, 286, 287, 286, 286, 286, 287, + 287, nil, nil, nil, 287, nil, 287, 287, 287, 287, + 287, 287, 287, nil, nil, nil, nil, nil, 287, 287, + 287, 287, 287, 287, 287, nil, nil, 287, nil, nil, + nil, nil, nil, nil, 287, nil, nil, 287, 287, 287, + 287, 287, 287, 287, 287, nil, 287, 287, 287, nil, + 287, 287, 287, 287, 287, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 287, nil, nil, 287, nil, nil, + 287, 287, nil, nil, 287, nil, nil, nil, nil, nil, + 287, nil, nil, nil, nil, nil, nil, nil, nil, 287, + nil, nil, nil, nil, 287, 287, 287, 287, nil, 287, + 287, 287, 287, nil, nil, nil, nil, 287, 287, nil, + nil, nil, nil, nil, nil, 287, nil, 287, 287, 287, + 292, 292, 292, 292, 292, nil, nil, nil, 292, 292, + nil, nil, nil, 292, nil, 292, 292, 292, 292, 292, + 292, 292, nil, nil, nil, nil, nil, 292, 292, 292, + 292, 292, 292, 292, nil, nil, 292, nil, nil, nil, + nil, nil, 292, 292, nil, 292, 292, 292, 292, 292, + 292, 292, 292, 292, nil, 292, 292, 292, nil, 292, + 292, 292, 292, 292, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 292, nil, nil, 292, nil, nil, 292, + 292, nil, nil, 292, nil, 292, nil, nil, nil, 292, + nil, nil, nil, nil, nil, nil, nil, nil, 292, nil, + nil, nil, nil, 292, 292, 292, 292, nil, 292, 292, + 292, 292, nil, nil, nil, nil, 292, 292, nil, nil, + nil, 300, 300, 300, 292, 300, 292, 292, 292, 300, + 300, nil, nil, nil, 300, nil, 300, 300, 300, 300, + 300, 300, 300, nil, nil, nil, nil, nil, 300, 300, + 300, 300, 300, 300, 300, nil, nil, 300, nil, nil, + nil, nil, nil, nil, 300, nil, nil, 300, 300, 300, + 300, 300, 300, 300, 300, nil, 300, 300, 300, nil, + 300, 300, nil, nil, 300, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 300, nil, nil, 300, nil, nil, + 300, 300, nil, nil, 300, nil, nil, 940, nil, 940, + 940, 940, 940, 940, nil, nil, nil, nil, nil, nil, + nil, nil, 940, nil, 300, 300, 300, 300, nil, 300, + 300, 300, 300, nil, nil, nil, nil, 300, 300, nil, + nil, nil, 300, nil, 940, 300, nil, 300, 300, 300, + 317, 317, 317, nil, 317, 940, 940, nil, 317, 317, + 940, nil, nil, 317, nil, 317, 317, 317, 317, 317, + 317, 317, nil, nil, nil, nil, nil, 317, 317, 317, + 317, 317, 317, 317, nil, nil, 317, nil, nil, nil, + nil, nil, nil, 317, nil, nil, 317, 317, 317, 317, + 317, 317, 317, 317, nil, 317, 317, 317, nil, 317, + 317, nil, nil, 317, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 317, nil, nil, 317, nil, nil, 317, + 317, nil, nil, 317, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 317, 317, 317, 317, nil, 317, 317, + 317, 317, nil, nil, nil, nil, 317, 317, nil, nil, + nil, 325, 325, 325, 317, 325, 317, 317, 317, 325, + 325, nil, nil, nil, 325, nil, 325, 325, 325, 325, + 325, 325, 325, nil, nil, nil, nil, nil, 325, 325, + 325, 325, 325, 325, 325, nil, nil, 325, nil, nil, + nil, nil, nil, nil, 325, nil, nil, 325, 325, 325, + 325, 325, 325, 325, 325, nil, 325, 325, 325, nil, + 325, 325, 325, 325, 325, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 325, nil, nil, 325, 325, nil, + 325, 325, nil, nil, 325, nil, nil, nil, nil, nil, + 325, nil, nil, nil, nil, nil, nil, nil, nil, 325, + nil, nil, nil, nil, 325, 325, 325, 325, nil, 325, + 325, 325, 325, nil, nil, nil, nil, 325, 325, nil, + nil, nil, 327, 327, 327, 325, 327, 325, 325, 325, + 327, 327, nil, nil, nil, 327, nil, 327, 327, 327, + 327, 327, 327, 327, nil, nil, nil, nil, nil, 327, + 327, 327, 327, 327, 327, 327, nil, nil, 327, nil, + nil, nil, nil, nil, nil, 327, nil, nil, 327, 327, + 327, 327, 327, 327, 327, 327, nil, 327, 327, 327, + nil, 327, 327, 327, 327, 327, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 327, nil, nil, 327, nil, + nil, 327, 327, nil, nil, 327, nil, nil, nil, nil, + nil, 327, nil, nil, nil, nil, nil, nil, nil, nil, + 327, nil, nil, nil, nil, 327, 327, 327, 327, nil, + 327, 327, 327, 327, nil, nil, nil, nil, 327, 327, + nil, nil, nil, 341, 341, 341, 327, 341, 327, 327, + 327, 341, 341, nil, nil, nil, 341, nil, 341, 341, + 341, 341, 341, 341, 341, nil, nil, nil, nil, nil, + 341, 341, 341, 341, 341, 341, 341, nil, nil, 341, + nil, nil, nil, nil, nil, nil, 341, nil, nil, 341, + 341, 341, 341, 341, 341, 341, 341, nil, 341, 341, + 341, nil, 341, 341, 341, 341, 341, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 341, nil, nil, 341, + nil, nil, 341, 341, nil, nil, 341, nil, nil, nil, + nil, nil, 341, nil, nil, nil, nil, nil, nil, nil, + nil, 341, nil, nil, nil, nil, 341, 341, 341, 341, + nil, 341, 341, 341, 341, nil, nil, nil, nil, 341, + 341, nil, nil, nil, 342, 342, 342, 341, 342, 341, + 341, 341, 342, 342, nil, nil, nil, 342, nil, 342, + 342, 342, 342, 342, 342, 342, nil, nil, nil, nil, + nil, 342, 342, 342, 342, 342, 342, 342, nil, nil, + 342, nil, nil, nil, nil, nil, nil, 342, nil, nil, + 342, 342, 342, 342, 342, 342, 342, 342, nil, 342, + 342, 342, nil, 342, 342, 342, 342, 342, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 342, nil, nil, + 342, nil, nil, 342, 342, nil, nil, 342, nil, nil, + nil, nil, nil, 342, nil, nil, nil, nil, nil, nil, + nil, nil, 342, nil, nil, nil, nil, 342, 342, 342, + 342, nil, 342, 342, 342, 342, nil, nil, nil, nil, + 342, 342, nil, nil, nil, 361, 361, 361, 342, 361, + 342, 342, 342, 361, 361, nil, nil, nil, 361, nil, + 361, 361, 361, 361, 361, 361, 361, nil, nil, nil, + nil, nil, 361, 361, 361, 361, 361, 361, 361, nil, + nil, 361, nil, nil, nil, nil, nil, nil, 361, nil, + nil, 361, 361, 361, 361, 361, 361, 361, 361, nil, + 361, 361, 361, nil, 361, 361, 361, 361, 361, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 361, nil, + nil, 361, nil, nil, 361, 361, nil, nil, 361, nil, + nil, nil, nil, nil, 361, nil, nil, nil, nil, nil, + nil, nil, nil, 361, nil, nil, nil, nil, 361, 361, + 361, 361, nil, 361, 361, 361, 361, nil, nil, nil, + nil, 361, 361, nil, nil, nil, 377, 377, 377, 361, + 377, 361, 361, 361, 377, 377, nil, nil, nil, 377, + nil, 377, 377, 377, 377, 377, 377, 377, nil, nil, + nil, nil, nil, 377, 377, 377, 377, 377, 377, 377, + nil, nil, 377, nil, nil, nil, nil, nil, nil, 377, + nil, nil, 377, 377, 377, 377, 377, 377, 377, 377, + nil, 377, 377, 377, nil, 377, 377, 377, 377, 377, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 377, + nil, nil, 377, nil, nil, 377, 377, nil, nil, 377, + nil, nil, nil, nil, nil, 377, nil, nil, nil, nil, + nil, nil, nil, nil, 377, nil, nil, nil, nil, 377, + 377, 377, 377, nil, 377, 377, 377, 377, nil, nil, + nil, nil, 377, 377, nil, nil, nil, 405, 405, 405, + 377, 405, 377, 377, 377, 405, 405, nil, nil, nil, + 405, nil, 405, 405, 405, 405, 405, 405, 405, nil, + nil, nil, nil, nil, 405, 405, 405, 405, 405, 405, + 405, nil, nil, 405, nil, nil, nil, nil, nil, nil, + 405, nil, nil, 405, 405, 405, 405, 405, 405, 405, + 405, nil, 405, 405, 405, nil, 405, 405, 405, 405, + 405, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 405, nil, nil, 405, nil, nil, 405, 405, nil, nil, + 405, nil, nil, nil, nil, nil, 405, nil, nil, nil, + nil, nil, nil, nil, nil, 405, nil, nil, nil, nil, + 405, 405, 405, 405, nil, 405, 405, 405, 405, nil, + nil, nil, nil, 405, 405, nil, nil, nil, 443, 443, + 443, 405, 443, 405, 405, 405, 443, 443, nil, nil, + nil, 443, nil, 443, 443, 443, 443, 443, 443, 443, + nil, nil, nil, nil, nil, 443, 443, 443, 443, 443, + 443, 443, nil, nil, 443, nil, nil, nil, nil, nil, + nil, 443, nil, nil, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, nil, 443, 443, 443, + 443, 443, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 443, nil, nil, 443, nil, nil, 443, 443, nil, + nil, 443, nil, 443, nil, 443, nil, 443, nil, nil, + 443, nil, nil, nil, nil, nil, 443, nil, nil, nil, + nil, 443, 443, 443, 443, nil, 443, 443, 443, 443, + nil, nil, nil, nil, 443, 443, nil, nil, nil, 445, + 445, 445, 443, 445, 443, 443, 443, 445, 445, nil, + nil, nil, 445, nil, 445, 445, 445, 445, 445, 445, + 445, nil, nil, nil, nil, nil, 445, 445, 445, 445, + 445, 445, 445, nil, nil, 445, nil, nil, nil, nil, + nil, nil, 445, nil, nil, 445, 445, 445, 445, 445, + 445, 445, 445, nil, 445, 445, 445, nil, 445, 445, + 445, 445, 445, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 445, nil, nil, 445, nil, nil, 445, 445, + nil, nil, 445, nil, nil, nil, nil, nil, 445, nil, + nil, nil, nil, nil, nil, nil, nil, 445, nil, nil, + nil, nil, 445, 445, 445, 445, nil, 445, 445, 445, + 445, nil, nil, nil, nil, 445, 445, nil, nil, nil, + 446, 446, 446, 445, 446, 445, 445, 445, 446, 446, + nil, nil, nil, 446, nil, 446, 446, 446, 446, 446, + 446, 446, nil, nil, nil, nil, nil, 446, 446, 446, + 446, 446, 446, 446, nil, nil, 446, nil, nil, nil, + nil, nil, nil, 446, nil, nil, 446, 446, 446, 446, + 446, 446, 446, 446, nil, 446, 446, 446, nil, 446, + 446, 446, 446, 446, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 446, nil, nil, 446, nil, nil, 446, + 446, nil, nil, 446, nil, nil, nil, nil, nil, 446, + nil, nil, nil, nil, nil, nil, nil, nil, 446, nil, + nil, nil, nil, 446, 446, 446, 446, nil, 446, 446, + 446, 446, nil, nil, nil, nil, 446, 446, nil, nil, + nil, 447, 447, 447, 446, 447, 446, 446, 446, 447, + 447, nil, nil, nil, 447, nil, 447, 447, 447, 447, + 447, 447, 447, nil, nil, nil, nil, nil, 447, 447, + 447, 447, 447, 447, 447, nil, nil, 447, nil, nil, + nil, nil, nil, nil, 447, nil, nil, 447, 447, 447, + 447, 447, 447, 447, 447, nil, 447, 447, 447, nil, + 447, 447, 447, 447, 447, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 447, nil, nil, 447, nil, nil, + 447, 447, nil, nil, 447, nil, nil, nil, nil, nil, + 447, nil, nil, nil, nil, nil, nil, nil, nil, 447, + nil, nil, nil, nil, 447, 447, 447, 447, nil, 447, + 447, 447, 447, nil, nil, nil, nil, 447, 447, nil, + nil, nil, 487, 487, 487, 447, 487, 447, 447, 447, + 487, 487, nil, nil, nil, 487, nil, 487, 487, 487, + 487, 487, 487, 487, nil, nil, nil, nil, nil, 487, + 487, 487, 487, 487, 487, 487, nil, nil, 487, nil, + nil, nil, nil, nil, nil, 487, nil, nil, 487, 487, + 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, + nil, 487, 487, 487, 487, 487, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 487, nil, nil, 487, nil, + nil, 487, 487, nil, nil, 487, nil, 487, nil, 487, + nil, 487, nil, nil, 487, nil, nil, nil, nil, nil, + 487, nil, nil, nil, nil, 487, 487, 487, 487, nil, + 487, 487, 487, 487, nil, nil, nil, nil, 487, 487, + nil, nil, nil, 489, 489, 489, 487, 489, 487, 487, + 487, 489, 489, nil, nil, nil, 489, nil, 489, 489, + 489, 489, 489, 489, 489, nil, nil, nil, nil, nil, + 489, 489, 489, 489, 489, 489, 489, nil, nil, 489, + nil, nil, nil, nil, nil, nil, 489, nil, nil, 489, + 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, + 489, nil, 489, 489, 489, 489, 489, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 489, nil, nil, 489, + nil, nil, 489, 489, nil, nil, 489, nil, nil, nil, + 489, nil, 489, nil, nil, 489, nil, nil, nil, nil, + nil, 489, nil, nil, nil, nil, 489, 489, 489, 489, + nil, 489, 489, 489, 489, nil, nil, nil, nil, 489, + 489, nil, nil, nil, 491, 491, 491, 489, 491, 489, + 489, 489, 491, 491, nil, nil, nil, 491, nil, 491, + 491, 491, 491, 491, 491, 491, nil, nil, nil, nil, + nil, 491, 491, 491, 491, 491, 491, 491, nil, nil, + 491, nil, nil, nil, nil, nil, nil, 491, nil, nil, + 491, 491, 491, 491, 491, 491, 491, 491, nil, 491, + 491, 491, nil, 491, 491, 491, 491, 491, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 491, nil, nil, + 491, nil, nil, 491, 491, nil, nil, 491, nil, nil, + nil, nil, nil, 491, nil, nil, nil, nil, nil, nil, + nil, nil, 491, nil, nil, nil, nil, 491, 491, 491, + 491, nil, 491, 491, 491, 491, nil, nil, nil, nil, + 491, 491, nil, nil, nil, nil, nil, nil, 491, nil, + 491, 491, 491, 497, 497, 497, 497, 497, nil, nil, + nil, 497, 497, nil, nil, nil, 497, nil, 497, 497, + 497, 497, 497, 497, 497, nil, nil, nil, nil, nil, + 497, 497, 497, 497, 497, 497, 497, nil, nil, 497, + nil, nil, nil, nil, nil, 497, 497, 497, 497, 497, + 497, 497, 497, 497, 497, 497, 497, nil, 497, 497, + 497, nil, 497, 497, 497, 497, 497, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 497, nil, nil, 497, + nil, nil, 497, 497, nil, nil, 497, nil, 497, nil, + nil, nil, 497, nil, nil, nil, nil, nil, nil, nil, + nil, 497, nil, nil, nil, nil, 497, 497, 497, 497, + nil, 497, 497, 497, 497, nil, nil, nil, nil, 497, + 497, nil, nil, nil, nil, nil, 497, 497, nil, 497, + 497, 497, 505, 505, 505, nil, 505, nil, nil, nil, + 505, 505, nil, nil, nil, 505, nil, 505, 505, 505, + 505, 505, 505, 505, nil, nil, nil, nil, nil, 505, + 505, 505, 505, 505, 505, 505, nil, nil, 505, nil, + nil, nil, nil, nil, nil, 505, nil, nil, 505, 505, + 505, 505, 505, 505, 505, 505, nil, 505, 505, 505, + nil, 505, 505, nil, nil, 505, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 505, nil, nil, 505, nil, + nil, 505, 505, nil, nil, 505, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 505, 505, 505, 505, nil, + 505, 505, 505, 505, nil, nil, nil, nil, 505, 505, + nil, nil, nil, 507, 507, 507, 505, 507, 505, 505, + 505, 507, 507, nil, nil, nil, 507, nil, 507, 507, + 507, 507, 507, 507, 507, nil, nil, nil, nil, nil, + 507, 507, 507, 507, 507, 507, 507, nil, nil, 507, + nil, nil, nil, nil, nil, nil, 507, nil, nil, 507, + 507, 507, 507, 507, 507, 507, 507, 507, 507, 507, + 507, nil, 507, 507, 507, 507, 507, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 507, nil, nil, 507, + nil, nil, 507, 507, nil, nil, 507, nil, 507, nil, + 507, nil, 507, nil, nil, 507, nil, nil, nil, nil, + nil, 507, nil, nil, nil, nil, 507, 507, 507, 507, + nil, 507, 507, 507, 507, nil, nil, nil, nil, 507, + 507, nil, nil, nil, 513, 513, 513, 507, 513, 507, + 507, 507, 513, 513, nil, nil, nil, 513, nil, 513, + 513, 513, 513, 513, 513, 513, nil, nil, nil, nil, + nil, 513, 513, 513, 513, 513, 513, 513, nil, nil, + 513, nil, nil, nil, nil, nil, nil, 513, nil, nil, + 513, 513, 513, 513, 513, 513, 513, 513, nil, 513, + 513, 513, nil, 513, 513, nil, nil, 513, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 513, nil, nil, + 513, nil, nil, 513, 513, nil, nil, 513, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 513, 513, 513, + 513, nil, 513, 513, 513, 513, nil, nil, nil, nil, + 513, 513, nil, nil, nil, 516, 516, 516, 513, 516, + 513, 513, 513, 516, 516, nil, nil, nil, 516, nil, + 516, 516, 516, 516, 516, 516, 516, nil, nil, nil, + nil, nil, 516, 516, 516, 516, 516, 516, 516, nil, + nil, 516, nil, nil, nil, nil, nil, nil, 516, nil, + nil, 516, 516, 516, 516, 516, 516, 516, 516, nil, + 516, 516, 516, nil, 516, 516, 516, 516, 516, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 516, nil, + nil, 516, nil, nil, 516, 516, nil, nil, 516, nil, + nil, nil, nil, nil, 516, nil, nil, nil, nil, nil, + nil, nil, nil, 516, nil, nil, nil, nil, 516, 516, + 516, 516, nil, 516, 516, 516, 516, nil, nil, nil, + nil, 516, 516, nil, nil, nil, 517, 517, 517, 516, + 517, 516, 516, 516, 517, 517, nil, nil, nil, 517, + nil, 517, 517, 517, 517, 517, 517, 517, nil, nil, + nil, nil, nil, 517, 517, 517, 517, 517, 517, 517, + nil, nil, 517, nil, nil, nil, nil, nil, nil, 517, + nil, nil, 517, 517, 517, 517, 517, 517, 517, 517, + nil, 517, 517, 517, nil, 517, 517, 517, 517, 517, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 517, + nil, nil, 517, nil, nil, 517, 517, nil, nil, 517, + nil, nil, nil, nil, nil, 517, nil, nil, nil, nil, + nil, nil, nil, nil, 517, nil, nil, nil, nil, 517, + 517, 517, 517, nil, 517, 517, 517, 517, nil, nil, + nil, nil, 517, 517, nil, nil, nil, 521, 521, 521, + 517, 521, 517, 517, 517, 521, 521, nil, nil, nil, + 521, nil, 521, 521, 521, 521, 521, 521, 521, nil, + nil, nil, nil, nil, 521, 521, 521, 521, 521, 521, + 521, nil, nil, 521, nil, nil, nil, nil, nil, nil, + 521, nil, nil, 521, 521, 521, 521, 521, 521, 521, + 521, nil, 521, 521, 521, nil, 521, 521, 521, 521, + 521, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 521, nil, nil, 521, nil, nil, 521, 521, nil, nil, + 521, nil, nil, nil, nil, nil, 521, nil, nil, nil, + nil, nil, nil, nil, nil, 521, nil, nil, nil, nil, + 521, 521, 521, 521, nil, 521, 521, 521, 521, nil, + nil, nil, nil, 521, 521, nil, nil, nil, 527, 527, + 527, 521, 527, 521, 521, 521, 527, 527, nil, nil, + nil, 527, nil, 527, 527, 527, 527, 527, 527, 527, + nil, nil, nil, nil, nil, 527, 527, 527, 527, 527, + 527, 527, nil, nil, 527, nil, nil, nil, nil, nil, + nil, 527, nil, nil, 527, 527, 527, 527, 527, 527, + 527, 527, 527, 527, 527, 527, nil, 527, 527, 527, + 527, 527, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 527, nil, nil, 527, nil, nil, 527, 527, nil, + nil, 527, nil, 527, nil, nil, nil, 527, nil, nil, + 527, nil, nil, nil, nil, nil, 527, nil, nil, nil, + nil, 527, 527, 527, 527, nil, 527, 527, 527, 527, + nil, nil, nil, nil, 527, 527, nil, nil, nil, 530, + 530, 530, 527, 530, 527, 527, 527, 530, 530, nil, + nil, nil, 530, nil, 530, 530, 530, 530, 530, 530, + 530, nil, nil, nil, nil, nil, 530, 530, 530, 530, + 530, 530, 530, nil, nil, 530, nil, nil, nil, nil, + nil, nil, 530, nil, nil, 530, 530, 530, 530, 530, + 530, 530, 530, 530, 530, 530, 530, nil, 530, 530, + 530, 530, 530, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 530, nil, nil, 530, nil, nil, 530, 530, + nil, nil, 530, nil, nil, nil, nil, nil, 530, nil, + nil, 530, nil, nil, nil, nil, nil, 530, nil, nil, + nil, nil, 530, 530, 530, 530, nil, 530, 530, 530, + 530, nil, nil, nil, nil, 530, 530, nil, nil, nil, + 544, 544, 544, 530, 544, 530, 530, 530, 544, 544, + nil, nil, nil, 544, nil, 544, 544, 544, 544, 544, + 544, 544, nil, nil, nil, nil, nil, 544, 544, 544, + 544, 544, 544, 544, nil, nil, 544, nil, nil, nil, + nil, nil, nil, 544, nil, nil, 544, 544, 544, 544, + 544, 544, 544, 544, nil, 544, 544, 544, nil, 544, + 544, 544, 544, 544, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 544, nil, nil, 544, nil, nil, 544, + 544, nil, nil, 544, nil, 544, nil, nil, nil, 544, + nil, nil, nil, nil, nil, nil, nil, nil, 544, nil, + nil, nil, nil, 544, 544, 544, 544, nil, 544, 544, + 544, 544, nil, nil, nil, nil, 544, 544, nil, nil, + nil, 545, 545, 545, 544, 545, 544, 544, 544, 545, + 545, nil, nil, nil, 545, nil, 545, 545, 545, 545, + 545, 545, 545, nil, nil, nil, nil, nil, 545, 545, + 545, 545, 545, 545, 545, nil, nil, 545, nil, nil, + nil, nil, nil, nil, 545, nil, nil, 545, 545, 545, + 545, 545, 545, 545, 545, 545, 545, 545, 545, nil, + 545, 545, 545, 545, 545, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 545, nil, nil, 545, nil, nil, + 545, 545, nil, nil, 545, nil, 545, nil, 545, nil, + 545, nil, nil, 545, nil, nil, nil, nil, nil, 545, + nil, nil, nil, nil, 545, 545, 545, 545, nil, 545, + 545, 545, 545, nil, nil, nil, nil, 545, 545, nil, + nil, nil, 555, 555, 555, 545, 555, 545, 545, 545, + 555, 555, nil, nil, nil, 555, nil, 555, 555, 555, + 555, 555, 555, 555, nil, nil, nil, nil, nil, 555, + 555, 555, 555, 555, 555, 555, nil, nil, 555, nil, + nil, nil, nil, nil, nil, 555, nil, nil, 555, 555, + 555, 555, 555, 555, 555, 555, 555, 555, 555, 555, + nil, 555, 555, 555, 555, 555, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 555, nil, nil, 555, nil, + nil, 555, 555, nil, nil, 555, nil, 555, nil, 555, + nil, 555, nil, nil, 555, nil, nil, nil, nil, nil, + 555, nil, nil, nil, nil, 555, 555, 555, 555, nil, + 555, 555, 555, 555, nil, nil, nil, nil, 555, 555, + nil, nil, nil, 589, 589, 589, 555, 589, 555, 555, + 555, 589, 589, nil, nil, nil, 589, nil, 589, 589, + 589, 589, 589, 589, 589, nil, nil, nil, nil, nil, + 589, 589, 589, 589, 589, 589, 589, nil, nil, 589, + nil, nil, nil, nil, nil, nil, 589, nil, nil, 589, + 589, 589, 589, 589, 589, 589, 589, nil, 589, 589, + 589, nil, 589, 589, 589, 589, 589, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 589, nil, nil, 589, + nil, nil, 589, 589, nil, nil, 589, nil, 589, nil, + nil, nil, 589, nil, nil, nil, nil, nil, nil, nil, + nil, 589, nil, nil, nil, nil, 589, 589, 589, 589, + nil, 589, 589, 589, 589, nil, nil, nil, nil, 589, + 589, nil, nil, nil, 590, 590, 590, 589, 590, 589, + 589, 589, 590, 590, nil, nil, nil, 590, nil, 590, + 590, 590, 590, 590, 590, 590, nil, nil, nil, nil, + nil, 590, 590, 590, 590, 590, 590, 590, nil, nil, + 590, nil, nil, nil, nil, nil, nil, 590, nil, nil, + 590, 590, 590, 590, 590, 590, 590, 590, nil, 590, + 590, 590, nil, 590, 590, 590, 590, 590, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 590, nil, nil, + 590, nil, nil, 590, 590, nil, nil, 590, nil, nil, + nil, nil, nil, 590, nil, nil, nil, nil, nil, nil, + nil, nil, 590, nil, nil, nil, nil, 590, 590, 590, + 590, nil, 590, 590, 590, 590, nil, nil, nil, nil, + 590, 590, nil, nil, nil, 593, 593, 593, 590, 593, + 590, 590, 590, 593, 593, nil, nil, nil, 593, nil, + 593, 593, 593, 593, 593, 593, 593, nil, nil, nil, + nil, nil, 593, 593, 593, 593, 593, 593, 593, nil, + nil, 593, nil, nil, nil, nil, nil, nil, 593, nil, + nil, 593, 593, 593, 593, 593, 593, 593, 593, 593, + 593, 593, 593, nil, 593, 593, 593, 593, 593, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 593, nil, + nil, 593, nil, nil, 593, 593, nil, nil, 593, nil, + 593, nil, 593, nil, 593, nil, nil, 593, nil, nil, + nil, nil, nil, 593, nil, nil, nil, nil, 593, 593, + 593, 593, nil, 593, 593, 593, 593, nil, nil, nil, + nil, 593, 593, nil, nil, nil, 594, 594, 594, 593, + 594, 593, 593, 593, 594, 594, nil, nil, nil, 594, + nil, 594, 594, 594, 594, 594, 594, 594, nil, nil, + nil, nil, nil, 594, 594, 594, 594, 594, 594, 594, + nil, nil, 594, nil, nil, nil, nil, nil, nil, 594, + nil, nil, 594, 594, 594, 594, 594, 594, 594, 594, + 594, 594, 594, 594, nil, 594, 594, 594, 594, 594, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 594, + nil, nil, 594, nil, nil, 594, 594, nil, nil, 594, + nil, nil, nil, 594, nil, 594, nil, nil, 594, nil, + nil, nil, nil, nil, 594, nil, nil, nil, nil, 594, + 594, 594, 594, nil, 594, 594, 594, 594, nil, nil, + nil, nil, 594, 594, nil, nil, nil, 595, 595, 595, + 594, 595, 594, 594, 594, 595, 595, nil, nil, nil, + 595, nil, 595, 595, 595, 595, 595, 595, 595, nil, + nil, nil, nil, nil, 595, 595, 595, 595, 595, 595, + 595, nil, nil, 595, nil, nil, nil, nil, nil, nil, + 595, nil, nil, 595, 595, 595, 595, 595, 595, 595, + 595, nil, 595, 595, 595, nil, 595, 595, 595, 595, + 595, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 595, nil, nil, 595, nil, nil, 595, 595, nil, nil, + 595, nil, nil, nil, nil, nil, 595, nil, nil, nil, + nil, nil, nil, nil, nil, 595, nil, nil, nil, nil, + 595, 595, 595, 595, nil, 595, 595, 595, 595, nil, + nil, nil, nil, 595, 595, nil, nil, nil, 596, 596, + 596, 595, 596, 595, 595, 595, 596, 596, nil, nil, + nil, 596, nil, 596, 596, 596, 596, 596, 596, 596, + nil, nil, nil, nil, nil, 596, 596, 596, 596, 596, + 596, 596, nil, nil, 596, nil, nil, nil, nil, nil, + nil, 596, nil, nil, 596, 596, 596, 596, 596, 596, + 596, 596, nil, 596, 596, 596, nil, 596, 596, 596, + 596, 596, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 596, nil, nil, 596, nil, nil, 596, 596, nil, + nil, 596, nil, nil, nil, nil, nil, 596, nil, nil, + nil, nil, nil, nil, nil, nil, 596, nil, nil, nil, + nil, 596, 596, 596, 596, nil, 596, 596, 596, 596, + nil, nil, nil, nil, 596, 596, nil, nil, nil, 600, + 600, 600, 596, 600, 596, 596, 596, 600, 600, nil, + nil, nil, 600, nil, 600, 600, 600, 600, 600, 600, + 600, nil, nil, nil, nil, nil, 600, 600, 600, 600, + 600, 600, 600, nil, nil, 600, nil, nil, nil, nil, + nil, nil, 600, nil, nil, 600, 600, 600, 600, 600, + 600, 600, 600, nil, 600, 600, 600, nil, 600, 600, + 600, 600, 600, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 600, nil, nil, 600, nil, nil, 600, 600, + nil, nil, 600, nil, nil, nil, nil, nil, 600, nil, + nil, nil, nil, nil, nil, nil, nil, 600, nil, nil, + nil, nil, 600, 600, 600, 600, nil, 600, 600, 600, + 600, nil, nil, nil, nil, 600, 600, nil, nil, nil, + 601, 601, 601, 600, 601, 600, 600, 600, 601, 601, + nil, nil, nil, 601, nil, 601, 601, 601, 601, 601, + 601, 601, nil, nil, nil, nil, nil, 601, 601, 601, + 601, 601, 601, 601, nil, nil, 601, nil, nil, nil, + nil, nil, nil, 601, nil, nil, 601, 601, 601, 601, + 601, 601, 601, 601, nil, 601, 601, 601, nil, 601, + 601, 601, 601, 601, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 601, nil, nil, 601, nil, nil, 601, + 601, nil, nil, 601, nil, nil, nil, nil, nil, 601, + nil, nil, nil, nil, nil, nil, nil, nil, 601, nil, + nil, nil, nil, 601, 601, 601, 601, nil, 601, 601, + 601, 601, nil, nil, nil, nil, 601, 601, nil, nil, + nil, 604, 604, 604, 601, 604, 601, 601, 601, 604, + 604, nil, nil, nil, 604, nil, 604, 604, 604, 604, + 604, 604, 604, nil, nil, nil, nil, nil, 604, 604, + 604, 604, 604, 604, 604, nil, nil, 604, nil, nil, + nil, nil, nil, nil, 604, nil, nil, 604, 604, 604, + 604, 604, 604, 604, 604, nil, 604, 604, 604, nil, + 604, 604, 604, 604, 604, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 604, nil, nil, 604, nil, nil, + 604, 604, nil, nil, 604, nil, nil, nil, nil, nil, + 604, nil, nil, nil, nil, nil, nil, nil, nil, 604, + nil, nil, nil, nil, 604, 604, 604, 604, nil, 604, + 604, 604, 604, nil, nil, nil, nil, 604, 604, nil, + nil, nil, 605, 605, 605, 604, 605, 604, 604, 604, + 605, 605, nil, nil, nil, 605, nil, 605, 605, 605, + 605, 605, 605, 605, nil, nil, nil, nil, nil, 605, + 605, 605, 605, 605, 605, 605, nil, nil, 605, nil, + nil, nil, nil, nil, nil, 605, nil, nil, 605, 605, + 605, 605, 605, 605, 605, 605, nil, 605, 605, 605, + nil, 605, 605, 605, 605, 605, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 605, nil, nil, 605, nil, + nil, 605, 605, nil, nil, 605, nil, nil, nil, nil, + nil, 605, nil, nil, nil, nil, nil, nil, nil, nil, + 605, nil, nil, nil, nil, 605, 605, 605, 605, nil, + 605, 605, 605, 605, nil, nil, nil, nil, 605, 605, + nil, nil, nil, 629, 629, 629, 605, 629, 605, 605, + 605, 629, 629, nil, nil, nil, 629, nil, 629, 629, + 629, 629, 629, 629, 629, nil, nil, nil, nil, nil, + 629, 629, 629, 629, 629, 629, 629, nil, nil, 629, + nil, nil, nil, nil, nil, nil, 629, nil, nil, 629, + 629, 629, 629, 629, 629, 629, 629, nil, 629, 629, + 629, nil, 629, 629, 629, 629, 629, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 629, nil, nil, 629, + nil, nil, 629, 629, nil, nil, 629, nil, nil, nil, + nil, nil, 629, nil, nil, nil, nil, nil, nil, nil, + nil, 629, nil, nil, nil, nil, 629, 629, 629, 629, + nil, 629, 629, 629, 629, nil, nil, nil, nil, 629, + 629, nil, nil, nil, 632, 632, 632, 629, 632, 629, + 629, 629, 632, 632, nil, nil, nil, 632, nil, 632, + 632, 632, 632, 632, 632, 632, nil, nil, nil, nil, + nil, 632, 632, 632, 632, 632, 632, 632, nil, nil, + 632, nil, nil, nil, nil, nil, nil, 632, nil, nil, + 632, 632, 632, 632, 632, 632, 632, 632, nil, 632, + 632, 632, nil, 632, 632, 632, 632, 632, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 632, nil, nil, + 632, nil, nil, 632, 632, nil, nil, 632, nil, nil, + nil, nil, nil, 632, nil, nil, nil, nil, nil, nil, + nil, nil, 632, nil, nil, nil, nil, 632, 632, 632, + 632, nil, 632, 632, 632, 632, nil, nil, nil, nil, + 632, 632, nil, nil, nil, 636, 636, 636, 632, 636, + 632, 632, 632, 636, 636, nil, nil, nil, 636, nil, + 636, 636, 636, 636, 636, 636, 636, nil, nil, nil, + nil, nil, 636, 636, 636, 636, 636, 636, 636, nil, + nil, 636, nil, nil, nil, nil, nil, nil, 636, nil, + nil, 636, 636, 636, 636, 636, 636, 636, 636, nil, + 636, 636, 636, nil, 636, 636, nil, nil, 636, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 636, nil, + nil, 636, nil, nil, 636, 636, nil, nil, 636, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 636, 636, + 636, 636, nil, 636, 636, 636, 636, nil, nil, nil, + nil, 636, 636, nil, nil, nil, 647, 647, 647, 636, + 647, 636, 636, 636, 647, 647, nil, nil, nil, 647, + nil, 647, 647, 647, 647, 647, 647, 647, nil, nil, + nil, nil, nil, 647, 647, 647, 647, 647, 647, 647, + nil, nil, 647, nil, nil, nil, nil, nil, nil, 647, + nil, nil, 647, 647, 647, 647, 647, 647, 647, 647, + nil, 647, 647, 647, nil, 647, 647, nil, nil, 647, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 647, + nil, nil, 647, nil, nil, 647, 647, nil, nil, 647, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 647, + 647, 647, 647, nil, 647, 647, 647, 647, nil, nil, + nil, nil, 647, 647, nil, nil, nil, 652, 652, 652, + 647, 652, 647, 647, 647, 652, 652, nil, nil, nil, + 652, nil, 652, 652, 652, 652, 652, 652, 652, nil, + nil, nil, nil, nil, 652, 652, 652, 652, 652, 652, + 652, nil, nil, 652, nil, nil, nil, nil, nil, nil, + 652, nil, nil, 652, 652, 652, 652, 652, 652, 652, + 652, nil, 652, 652, 652, nil, 652, 652, 652, 652, + 652, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 652, nil, nil, 652, nil, nil, 652, 652, nil, nil, + 652, nil, 652, nil, nil, nil, 652, nil, nil, nil, + nil, nil, nil, nil, nil, 652, nil, nil, nil, nil, + 652, 652, 652, 652, nil, 652, 652, 652, 652, nil, + nil, nil, nil, 652, 652, nil, nil, nil, 678, 678, + 678, 652, 678, 652, 652, 652, 678, 678, nil, nil, + nil, 678, nil, 678, 678, 678, 678, 678, 678, 678, + nil, nil, nil, nil, nil, 678, 678, 678, 678, 678, + 678, 678, nil, nil, 678, nil, nil, nil, nil, nil, + nil, 678, nil, nil, 678, 678, 678, 678, 678, 678, + 678, 678, nil, 678, 678, 678, nil, 678, 678, 678, + 678, 678, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 678, nil, nil, 678, nil, nil, 678, 678, nil, + nil, 678, nil, nil, nil, nil, nil, 678, nil, nil, + nil, nil, nil, nil, nil, nil, 678, nil, nil, nil, + nil, 678, 678, 678, 678, nil, 678, 678, 678, 678, + nil, nil, nil, nil, 678, 678, nil, nil, nil, 705, + 705, 705, 678, 705, 678, 678, 678, 705, 705, nil, + nil, nil, 705, nil, 705, 705, 705, 705, 705, 705, + 705, nil, nil, nil, nil, nil, 705, 705, 705, 705, + 705, 705, 705, nil, nil, 705, nil, nil, nil, nil, + nil, nil, 705, nil, nil, 705, 705, 705, 705, 705, + 705, 705, 705, nil, 705, 705, 705, nil, 705, 705, + 705, 705, 705, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 705, nil, nil, 705, nil, nil, 705, 705, + nil, nil, 705, nil, nil, nil, nil, nil, 705, nil, + nil, nil, nil, nil, nil, nil, nil, 705, nil, nil, + nil, nil, 705, 705, 705, 705, nil, 705, 705, 705, + 705, nil, nil, nil, nil, 705, 705, nil, nil, nil, + 711, 711, 711, 705, 711, 705, 705, 705, 711, 711, + nil, nil, nil, 711, nil, 711, 711, 711, 711, 711, + 711, 711, nil, nil, nil, nil, nil, 711, 711, 711, + 711, 711, 711, 711, nil, nil, 711, nil, nil, nil, + nil, nil, nil, 711, nil, nil, 711, 711, 711, 711, + 711, 711, 711, 711, nil, 711, 711, 711, nil, 711, + 711, 711, 711, 711, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 711, nil, nil, 711, nil, nil, 711, + 711, nil, nil, 711, nil, nil, nil, nil, nil, 711, + nil, nil, nil, nil, nil, nil, nil, nil, 711, nil, + nil, nil, nil, 711, 711, 711, 711, nil, 711, 711, + 711, 711, nil, nil, nil, nil, 711, 711, nil, nil, + nil, 734, 734, 734, 711, 734, 711, 711, 711, 734, + 734, nil, nil, nil, 734, nil, 734, 734, 734, 734, + 734, 734, 734, nil, nil, nil, nil, nil, 734, 734, + 734, 734, 734, 734, 734, nil, nil, 734, nil, nil, + nil, nil, nil, nil, 734, nil, nil, 734, 734, 734, + 734, 734, 734, 734, 734, nil, 734, 734, 734, nil, + 734, 734, 734, 734, 734, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 734, nil, nil, 734, nil, nil, + 734, 734, nil, nil, 734, nil, nil, nil, nil, nil, + 734, nil, nil, nil, nil, nil, nil, nil, nil, 734, + nil, nil, nil, nil, 734, 734, 734, 734, nil, 734, + 734, 734, 734, nil, nil, nil, nil, 734, 734, nil, + nil, nil, 736, 736, 736, 734, 736, 734, 734, 734, + 736, 736, nil, nil, nil, 736, nil, 736, 736, 736, + 736, 736, 736, 736, nil, nil, nil, nil, nil, 736, + 736, 736, 736, 736, 736, 736, nil, nil, 736, nil, + nil, nil, nil, nil, nil, 736, nil, nil, 736, 736, + 736, 736, 736, 736, 736, 736, nil, 736, 736, 736, + nil, 736, 736, 736, 736, 736, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 736, nil, nil, 736, nil, + nil, 736, 736, nil, nil, 736, nil, nil, nil, nil, + nil, 736, nil, nil, nil, nil, nil, nil, nil, nil, + 736, nil, nil, nil, nil, 736, 736, 736, 736, nil, + 736, 736, 736, 736, nil, nil, nil, nil, 736, 736, + nil, nil, nil, 750, 750, 750, 736, 750, 736, 736, + 736, 750, 750, nil, nil, nil, 750, nil, 750, 750, + 750, 750, 750, 750, 750, nil, nil, nil, nil, nil, + 750, 750, 750, 750, 750, 750, 750, nil, nil, 750, + nil, nil, nil, nil, nil, nil, 750, nil, nil, 750, + 750, 750, 750, 750, 750, 750, 750, nil, 750, 750, + 750, nil, 750, 750, 750, 750, 750, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 750, nil, nil, 750, + nil, nil, 750, 750, nil, nil, 750, nil, nil, nil, + nil, nil, 750, nil, nil, nil, nil, nil, nil, nil, + nil, 750, nil, nil, nil, nil, 750, 750, 750, 750, + nil, 750, 750, 750, 750, nil, nil, nil, nil, 750, + 750, nil, nil, nil, 751, 751, 751, 750, 751, 750, + 750, 750, 751, 751, nil, nil, nil, 751, nil, 751, + 751, 751, 751, 751, 751, 751, nil, nil, nil, nil, + nil, 751, 751, 751, 751, 751, 751, 751, nil, nil, + 751, nil, nil, nil, nil, nil, nil, 751, nil, nil, + 751, 751, 751, 751, 751, 751, 751, 751, nil, 751, + 751, 751, nil, 751, 751, 751, 751, 751, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 751, nil, nil, + 751, nil, nil, 751, 751, nil, nil, 751, nil, nil, + nil, nil, nil, 751, nil, nil, nil, nil, nil, nil, + nil, nil, 751, nil, nil, nil, nil, 751, 751, 751, + 751, nil, 751, 751, 751, 751, nil, nil, nil, nil, + 751, 751, nil, nil, nil, 752, 752, 752, 751, 752, + 751, 751, 751, 752, 752, nil, nil, nil, 752, nil, + 752, 752, 752, 752, 752, 752, 752, nil, nil, nil, + nil, nil, 752, 752, 752, 752, 752, 752, 752, nil, + nil, 752, nil, nil, nil, nil, nil, nil, 752, nil, + nil, 752, 752, 752, 752, 752, 752, 752, 752, nil, + 752, 752, 752, nil, 752, 752, 752, 752, 752, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 752, nil, + nil, 752, nil, nil, 752, 752, nil, nil, 752, nil, + nil, nil, nil, nil, 752, nil, nil, nil, nil, nil, + nil, nil, nil, 752, nil, nil, nil, nil, 752, 752, + 752, 752, nil, 752, 752, 752, 752, nil, nil, nil, + nil, 752, 752, nil, nil, nil, 753, 753, 753, 752, + 753, 752, 752, 752, 753, 753, nil, nil, nil, 753, + nil, 753, 753, 753, 753, 753, 753, 753, nil, nil, + nil, nil, nil, 753, 753, 753, 753, 753, 753, 753, + nil, nil, 753, nil, nil, nil, nil, nil, nil, 753, + nil, nil, 753, 753, 753, 753, 753, 753, 753, 753, + nil, 753, 753, 753, nil, 753, 753, 753, 753, 753, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 753, + nil, nil, 753, nil, nil, 753, 753, nil, nil, 753, + nil, nil, nil, nil, nil, 753, nil, nil, nil, nil, + nil, nil, nil, nil, 753, nil, nil, nil, nil, 753, + 753, 753, 753, nil, 753, 753, 753, 753, nil, nil, + nil, nil, 753, 753, nil, nil, nil, 755, 755, 755, + 753, 755, 753, 753, 753, 755, 755, nil, nil, nil, + 755, nil, 755, 755, 755, 755, 755, 755, 755, nil, + nil, nil, nil, nil, 755, 755, 755, 755, 755, 755, + 755, nil, nil, 755, nil, nil, nil, nil, nil, nil, + 755, nil, nil, 755, 755, 755, 755, 755, 755, 755, + 755, nil, 755, 755, 755, nil, 755, 755, 755, 755, + 755, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 755, nil, nil, 755, nil, nil, 755, 755, nil, nil, + 755, nil, nil, nil, nil, nil, 755, nil, nil, nil, + nil, nil, nil, nil, nil, 755, nil, nil, nil, nil, + 755, 755, 755, 755, nil, 755, 755, 755, 755, nil, + nil, nil, nil, 755, 755, nil, nil, nil, 767, 767, + 767, 755, 767, 755, 755, 755, 767, 767, nil, nil, + nil, 767, nil, 767, 767, 767, 767, 767, 767, 767, + nil, nil, nil, nil, nil, 767, 767, 767, 767, 767, + 767, 767, nil, nil, 767, nil, nil, nil, nil, nil, + nil, 767, nil, nil, 767, 767, 767, 767, 767, 767, + 767, 767, nil, 767, 767, 767, nil, 767, 767, nil, + nil, 767, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 767, nil, nil, 767, nil, nil, 767, 767, nil, + nil, 767, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 767, 767, 767, 767, nil, 767, 767, 767, 767, + nil, nil, nil, nil, 767, 767, nil, nil, nil, 805, + 805, 805, 767, 805, 767, 767, 767, 805, 805, nil, + nil, nil, 805, nil, 805, 805, 805, 805, 805, 805, + 805, nil, nil, nil, nil, nil, 805, 805, 805, 805, + 805, 805, 805, nil, nil, 805, nil, nil, nil, nil, + nil, nil, 805, nil, nil, 805, 805, 805, 805, 805, + 805, 805, 805, nil, 805, 805, 805, nil, 805, 805, + 805, 805, 805, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 805, nil, nil, 805, nil, nil, 805, 805, + nil, nil, 805, nil, nil, nil, nil, nil, 805, nil, + nil, nil, nil, nil, nil, nil, nil, 805, nil, nil, + nil, nil, 805, 805, 805, 805, nil, 805, 805, 805, + 805, nil, nil, nil, nil, 805, 805, nil, nil, nil, + 818, 818, 818, 805, 818, 805, 805, 805, 818, 818, + nil, nil, nil, 818, nil, 818, 818, 818, 818, 818, + 818, 818, nil, nil, nil, nil, nil, 818, 818, 818, + 818, 818, 818, 818, nil, nil, 818, nil, nil, nil, + nil, nil, nil, 818, nil, nil, 818, 818, 818, 818, + 818, 818, 818, 818, nil, 818, 818, 818, nil, 818, + 818, 818, 818, 818, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 818, nil, nil, 818, nil, nil, 818, + 818, nil, nil, 818, nil, nil, nil, nil, nil, 818, + nil, nil, nil, nil, nil, nil, nil, nil, 818, nil, + nil, nil, nil, 818, 818, 818, 818, nil, 818, 818, + 818, 818, nil, nil, nil, nil, 818, 818, nil, nil, + nil, 823, 823, 823, 818, 823, 818, 818, 818, 823, + 823, nil, nil, nil, 823, nil, 823, 823, 823, 823, + 823, 823, 823, nil, nil, nil, nil, nil, 823, 823, + 823, 823, 823, 823, 823, nil, nil, 823, nil, nil, + nil, nil, nil, nil, 823, nil, nil, 823, 823, 823, + 823, 823, 823, 823, 823, nil, 823, 823, 823, nil, + 823, 823, 823, 823, 823, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 823, nil, nil, 823, nil, nil, + 823, 823, nil, nil, 823, nil, 823, nil, nil, nil, + 823, nil, nil, nil, nil, nil, nil, nil, nil, 823, + nil, nil, nil, nil, 823, 823, 823, 823, nil, 823, + 823, 823, 823, nil, nil, nil, nil, 823, 823, nil, + nil, nil, 840, 840, 840, 823, 840, 823, 823, 823, + 840, 840, nil, nil, nil, 840, nil, 840, 840, 840, + 840, 840, 840, 840, nil, nil, nil, nil, nil, 840, + 840, 840, 840, 840, 840, 840, nil, nil, 840, nil, + nil, nil, nil, nil, nil, 840, nil, nil, 840, 840, + 840, 840, 840, 840, 840, 840, 840, 840, 840, 840, + nil, 840, 840, 840, 840, 840, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 840, nil, nil, 840, nil, + nil, 840, 840, nil, nil, 840, nil, nil, nil, 840, + nil, 840, nil, nil, 840, nil, nil, nil, nil, nil, + 840, nil, nil, nil, nil, 840, 840, 840, 840, nil, + 840, 840, 840, 840, nil, nil, nil, nil, 840, 840, + nil, nil, nil, 841, 841, 841, 840, 841, 840, 840, + 840, 841, 841, nil, nil, nil, 841, nil, 841, 841, + 841, 841, 841, 841, 841, nil, nil, nil, nil, nil, + 841, 841, 841, 841, 841, 841, 841, nil, nil, 841, + nil, nil, nil, nil, nil, nil, 841, nil, nil, 841, + 841, 841, 841, 841, 841, 841, 841, nil, 841, 841, + 841, nil, 841, 841, 841, 841, 841, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 841, nil, nil, 841, + nil, nil, 841, 841, nil, nil, 841, nil, nil, nil, + nil, nil, 841, nil, nil, nil, nil, nil, nil, nil, + nil, 841, nil, nil, nil, nil, 841, 841, 841, 841, + nil, 841, 841, 841, 841, nil, nil, nil, nil, 841, + 841, nil, nil, nil, 855, 855, 855, 841, 855, 841, + 841, 841, 855, 855, nil, nil, nil, 855, nil, 855, + 855, 855, 855, 855, 855, 855, nil, nil, nil, nil, + nil, 855, 855, 855, 855, 855, 855, 855, nil, nil, + 855, nil, nil, nil, nil, nil, nil, 855, nil, nil, + 855, 855, 855, 855, 855, 855, 855, 855, nil, 855, + 855, 855, nil, 855, 855, nil, nil, 855, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 855, nil, nil, + 855, nil, nil, 855, 855, nil, nil, 855, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 855, 855, 855, + 855, nil, 855, 855, 855, 855, nil, nil, nil, nil, + 855, 855, nil, nil, nil, 867, 867, 867, 855, 867, + 855, 855, 855, 867, 867, nil, nil, nil, 867, nil, + 867, 867, 867, 867, 867, 867, 867, nil, nil, nil, + nil, nil, 867, 867, 867, 867, 867, 867, 867, nil, + nil, 867, nil, nil, nil, nil, nil, nil, 867, nil, + nil, 867, 867, 867, 867, 867, 867, 867, 867, nil, + 867, 867, 867, nil, 867, 867, nil, nil, 867, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 867, nil, + nil, 867, nil, nil, 867, 867, nil, nil, 867, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 867, 867, + 867, 867, nil, 867, 867, 867, 867, nil, nil, nil, + nil, 867, 867, nil, nil, nil, 976, 976, 976, 867, + 976, 867, 867, 867, 976, 976, nil, nil, nil, 976, + nil, 976, 976, 976, 976, 976, 976, 976, nil, nil, + nil, nil, nil, 976, 976, 976, 976, 976, 976, 976, + nil, nil, 976, nil, nil, nil, nil, nil, nil, 976, + nil, nil, 976, 976, 976, 976, 976, 976, 976, 976, + 976, 976, 976, 976, nil, 976, 976, 976, 976, 976, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 976, + nil, nil, 976, nil, nil, 976, 976, nil, nil, 976, + nil, 976, nil, 976, nil, 976, nil, nil, 976, nil, + nil, nil, nil, nil, 976, nil, nil, nil, nil, 976, + 976, 976, 976, nil, 976, 976, 976, 976, nil, nil, + nil, nil, 976, 976, nil, nil, nil, nil, 56, nil, + 976, nil, 976, 976, 976, 56, 56, 56, nil, nil, + 56, 56, 56, nil, 56, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 56, 56, 56, nil, nil, nil, + nil, nil, nil, nil, 56, 56, nil, 56, 56, 56, + 56, 56, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, nil, nil, + 56, 56, 56, nil, nil, 56, nil, nil, 56, nil, + nil, 56, 56, nil, 56, nil, 56, nil, 56, nil, + 56, 56, nil, 56, 56, 56, 56, 56, nil, 56, + nil, 56, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 56, nil, nil, 56, 56, + 56, 56, 425, 56, nil, 56, nil, nil, nil, 425, + 425, 425, nil, nil, 425, 425, 425, nil, 425, nil, + nil, nil, nil, nil, nil, nil, nil, 425, 425, 425, + 425, nil, nil, nil, nil, nil, nil, nil, 425, 425, + nil, 425, 425, 425, 425, 425, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 425, 425, + 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, + 425, 425, nil, nil, 425, 425, 425, nil, nil, 425, + nil, nil, 425, nil, nil, 425, 425, nil, 425, nil, + 425, nil, 425, nil, 425, 425, nil, 425, 425, 425, + 425, 425, nil, 425, 425, 425, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 425, + nil, nil, 425, 425, 425, 425, 426, 425, nil, 425, + nil, nil, nil, 426, 426, 426, nil, nil, 426, 426, + 426, nil, 426, nil, nil, nil, nil, nil, nil, nil, + nil, 426, 426, 426, 426, nil, nil, nil, nil, nil, + nil, nil, 426, 426, nil, 426, 426, 426, 426, 426, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 426, 426, 426, 426, 426, 426, 426, 426, + 426, 426, 426, 426, 426, 426, nil, nil, 426, 426, + 426, nil, nil, 426, nil, nil, 426, nil, nil, 426, + 426, nil, 426, nil, 426, nil, 426, nil, 426, 426, + nil, 426, 426, 426, 426, 426, nil, 426, 426, 426, + 942, nil, 942, 942, 942, 942, 942, nil, nil, nil, + nil, nil, nil, 426, nil, 942, 426, 426, 426, 426, + 27, 426, nil, 426, nil, nil, nil, 27, 27, 27, + nil, nil, 27, 27, 27, nil, 27, 942, nil, nil, + nil, nil, nil, nil, nil, 27, 27, 27, 942, 942, + nil, nil, nil, 942, nil, nil, 27, 27, nil, 27, + 27, 27, 27, 27, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + nil, nil, 27, 27, 27, nil, nil, 27, nil, 27, + 27, nil, nil, 27, 27, nil, 27, nil, 27, nil, + 27, nil, 27, 27, nil, 27, 27, 27, 27, 27, + 28, 27, 27, 27, nil, nil, nil, 28, 28, 28, + nil, nil, 28, 28, 28, nil, 28, 27, nil, nil, + 27, 27, nil, 27, nil, 27, 28, 28, nil, nil, + nil, nil, nil, nil, nil, nil, 28, 28, nil, 28, + 28, 28, 28, 28, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + nil, nil, 28, 28, 28, nil, nil, 28, nil, 28, + 28, nil, nil, 28, 28, nil, 28, nil, 28, nil, + 28, nil, 28, 28, nil, 28, 28, 28, 28, 28, + nil, 28, 416, 28, nil, nil, nil, nil, nil, 416, + 416, 416, nil, nil, 416, 416, 416, 28, 416, nil, + 28, 28, nil, 28, nil, 28, nil, 416, 416, 416, + nil, nil, nil, nil, nil, nil, nil, nil, 416, 416, + nil, 416, 416, 416, 416, 416, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 416, 416, + 416, 416, 416, 416, 416, 416, 416, 416, 416, 416, + 416, 416, nil, nil, 416, 416, 416, nil, nil, 416, + nil, 416, 416, nil, nil, 416, 416, nil, 416, nil, + 416, nil, 416, nil, 416, 416, nil, 416, 416, 416, + 416, 416, nil, 416, 416, 416, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 416, + nil, 475, 416, 416, nil, 416, nil, 416, 475, 475, + 475, nil, nil, 475, 475, 475, 616, 475, 616, 616, + 616, 616, 616, nil, nil, nil, 475, 475, nil, nil, + nil, 616, nil, nil, nil, nil, nil, 475, 475, nil, + 475, 475, 475, 475, 475, nil, nil, nil, nil, nil, + nil, nil, nil, 616, nil, 535, nil, 535, 535, 535, + 535, 535, 616, 616, 616, 616, nil, nil, nil, 616, + 535, nil, nil, nil, nil, nil, nil, nil, 475, nil, + nil, nil, nil, nil, nil, 475, nil, nil, nil, nil, + 475, 475, 535, 535, nil, 616, nil, nil, nil, nil, + nil, 535, 535, 535, 535, nil, nil, nil, 535, nil, + nil, nil, nil, 475, 475, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 475, nil, + nil, 475, nil, nil, nil, nil, 475, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, nil, nil, nil, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, nil, nil, nil, nil, nil, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, nil, + 8, nil, nil, nil, nil, nil, nil, nil, 8, 8, + nil, 8, 8, 8, 8, 8, 8, 8, nil, nil, + 8, 8, nil, nil, nil, 8, 8, 8, 8, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 8, 8, nil, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, nil, nil, 8, + 8, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, nil, + nil, nil, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, nil, nil, nil, nil, nil, 9, 9, 9, + 9, 9, 9, 9, 9, 9, nil, nil, 9, nil, + nil, nil, nil, nil, nil, nil, 9, 9, nil, 9, + 9, 9, 9, 9, 9, 9, nil, nil, 9, 9, + nil, nil, nil, 9, 9, 9, 9, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 9, 9, nil, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, nil, nil, 9, 9, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 9, 396, 396, 396, 396, 396, 396, 396, + 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, + 396, 396, 396, 396, 396, 396, 396, nil, nil, nil, + 396, 396, 396, 396, 396, 396, 396, 396, 396, 396, + nil, nil, nil, nil, nil, 396, 396, 396, 396, 396, + 396, 396, 396, 396, nil, nil, 396, nil, nil, nil, + nil, nil, nil, nil, 396, 396, nil, 396, 396, 396, + 396, 396, 396, 396, nil, nil, 396, 396, nil, nil, + nil, 396, 396, 396, 396, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 396, 396, + nil, 396, 396, 396, 396, 396, 396, 396, 396, 396, + 396, 396, 396, nil, nil, 396, 396, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 396, 586, 586, 586, 586, 586, 586, 586, 586, 586, + 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, + 586, 586, 586, 586, 586, nil, nil, nil, 586, 586, + 586, 586, 586, 586, 586, 586, 586, 586, nil, nil, + nil, nil, nil, 586, 586, 586, 586, 586, 586, 586, + 586, 586, nil, nil, 586, nil, nil, nil, nil, nil, + nil, nil, 586, 586, nil, 586, 586, 586, 586, 586, + 586, 586, nil, nil, 586, 586, nil, nil, nil, 586, + 586, 586, 586, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 586, 586, nil, 586, + 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, + 586, nil, nil, 586, 586, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 586, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, nil, nil, nil, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, nil, nil, nil, nil, + nil, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, nil, 71, nil, nil, nil, nil, nil, + 71, 71, nil, 71, 71, 71, 71, 71, 71, 71, + nil, nil, 71, 71, nil, nil, nil, 71, 71, 71, + 71, nil, nil, nil, nil, nil, 71, nil, nil, nil, + nil, nil, nil, nil, 71, 71, nil, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, nil, + nil, 71, 718, 718, 718, 718, 718, 718, 718, 718, + 718, 718, 718, 718, 718, 718, 718, 718, 718, 718, + 718, 718, 718, 718, 718, 718, nil, nil, nil, 718, + 718, 718, 718, 718, 718, 718, 718, 718, 718, nil, + nil, nil, nil, nil, 718, 718, 718, 718, 718, 718, + 718, 718, 718, nil, nil, 718, nil, nil, nil, nil, + nil, nil, nil, 718, 718, nil, 718, 718, 718, 718, + 718, 718, 718, nil, nil, 718, 718, nil, nil, nil, + 718, 718, 718, 718, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 718, 718, nil, + 718, 718, 718, 718, 718, 718, 718, 718, 718, 718, + 718, 718, 212, 212, 718, nil, 212, nil, nil, nil, + nil, nil, nil, nil, 212, 212, nil, 212, 212, 212, + 212, 212, 212, 212, nil, nil, 212, 212, nil, nil, + nil, 212, 212, 212, 212, nil, nil, nil, nil, nil, + 212, nil, nil, nil, nil, nil, nil, nil, 212, 212, + nil, 212, 212, 212, 212, 212, 212, 212, 212, 212, + 212, 212, 212, 213, 213, 212, nil, 213, nil, nil, + nil, nil, nil, nil, nil, 213, 213, nil, 213, 213, + 213, 213, 213, 213, 213, nil, nil, 213, 213, nil, + nil, nil, 213, 213, 213, 213, nil, nil, nil, nil, + nil, 213, nil, nil, nil, nil, nil, nil, nil, 213, + 213, nil, 213, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 261, 261, 213, nil, 261, nil, + nil, nil, nil, nil, nil, nil, 261, 261, nil, 261, + 261, 261, 261, 261, 261, 261, nil, nil, 261, 261, + nil, nil, nil, 261, 261, 261, 261, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 261, 261, nil, 261, 261, 261, 261, 261, 261, 261, + 261, 261, 261, 261, 261, 441, 441, 261, nil, 441, + nil, nil, nil, nil, nil, nil, nil, 441, 441, nil, + 441, 441, 441, 441, 441, 441, 441, nil, nil, 441, + 441, nil, nil, nil, 441, 441, 441, 441, nil, nil, + nil, nil, nil, 441, nil, nil, nil, nil, nil, nil, + nil, 441, 441, nil, 441, 441, 441, 441, 441, 441, + 441, 441, 441, 441, 441, 441, 442, 442, 441, nil, + 442, nil, nil, nil, nil, nil, nil, nil, 442, 442, + nil, 442, 442, 442, 442, 442, 442, 442, nil, nil, + 442, 442, nil, nil, nil, 442, 442, 442, 442, nil, + nil, nil, nil, nil, 442, nil, nil, nil, nil, nil, + nil, nil, 442, 442, nil, 442, 442, 442, 442, 442, + 442, 442, 442, 442, 442, 442, 442, 508, 508, 442, + nil, 508, nil, nil, nil, nil, nil, nil, nil, 508, + 508, nil, 508, 508, 508, 508, 508, 508, 508, nil, + nil, 508, 508, nil, nil, nil, 508, 508, 508, 508, + nil, nil, nil, nil, nil, 508, nil, nil, nil, nil, + nil, nil, nil, 508, 508, nil, 508, 508, 508, 508, + 508, 508, 508, 508, 508, 508, 508, 508, 509, 509, + 508, nil, 509, nil, nil, nil, nil, nil, nil, nil, + 509, 509, nil, 509, 509, 509, 509, 509, 509, 509, + nil, nil, 509, 509, nil, nil, nil, 509, 509, 509, + 509, nil, nil, nil, nil, nil, 509, nil, nil, nil, + nil, nil, nil, nil, 509, 509, nil, 509, 509, 509, + 509, 509, 509, 509, 509, 509, 509, 509, 509, 518, + 518, 509, nil, 518, nil, nil, nil, nil, nil, nil, + nil, 518, 518, nil, 518, 518, 518, 518, 518, 518, + 518, nil, nil, 518, 518, nil, nil, nil, 518, 518, + 518, 518, nil, nil, nil, nil, nil, 518, nil, nil, + nil, nil, nil, nil, nil, 518, 518, nil, 518, 518, + 518, 518, 518, 518, 518, 518, 518, 518, 518, 518, + 519, 519, 518, nil, 519, nil, nil, nil, nil, nil, + nil, nil, 519, 519, nil, 519, 519, 519, 519, 519, + 519, 519, nil, nil, 519, 519, nil, nil, nil, 519, + 519, 519, 519, nil, nil, nil, nil, nil, 519, nil, + nil, nil, nil, nil, nil, nil, 519, 519, nil, 519, + 519, 519, 519, 519, 519, 519, 519, 519, 519, 519, + 519, 546, 546, 519, nil, 546, nil, nil, nil, nil, + nil, nil, nil, 546, 546, nil, 546, 546, 546, 546, + 546, 546, 546, nil, nil, 546, 546, nil, nil, nil, + 546, 546, 546, 546, nil, nil, nil, nil, nil, 546, + nil, nil, nil, nil, nil, nil, nil, 546, 546, nil, + 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, + 546, 546, 547, 547, 546, nil, 547, nil, nil, nil, + nil, nil, nil, nil, 547, 547, nil, 547, 547, 547, + 547, 547, 547, 547, nil, nil, 547, 547, nil, nil, + nil, 547, 547, 547, 547, nil, nil, nil, nil, nil, + 547, nil, nil, nil, nil, nil, nil, nil, 547, 547, + nil, 547, 547, 547, 547, 547, 547, 547, 547, 547, + 547, 547, 547, 553, 553, 547, nil, 553, nil, nil, + nil, nil, nil, nil, nil, 553, 553, nil, 553, 553, + 553, 553, 553, 553, 553, nil, nil, 553, 553, nil, + nil, nil, 553, 553, 553, 553, nil, nil, nil, nil, + nil, 553, nil, nil, nil, nil, nil, nil, nil, 553, + 553, nil, 553, 553, 553, 553, 553, 553, 553, 553, + 553, 553, 553, 553, 554, 554, 553, nil, 554, nil, + nil, nil, nil, nil, nil, nil, 554, 554, nil, 554, + 554, 554, 554, 554, 554, 554, nil, nil, 554, 554, + nil, nil, nil, 554, 554, 554, 554, nil, nil, nil, + nil, nil, 554, nil, nil, nil, nil, nil, nil, nil, + 554, 554, nil, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 923, 923, 554, nil, 923, + nil, nil, nil, nil, nil, nil, nil, 923, 923, nil, + 923, 923, 923, 923, 923, 923, 923, nil, nil, 923, + 923, nil, nil, nil, 923, 923, 923, 923, nil, nil, + nil, nil, nil, 923, nil, nil, nil, nil, nil, nil, + nil, 923, 923, nil, 923, 923, 923, 923, 923, 923, + 923, 923, 923, 923, 923, 923, 977, 977, 923, nil, + 977, nil, nil, nil, nil, nil, nil, nil, 977, 977, + nil, 977, 977, 977, 977, 977, 977, 977, nil, nil, + 977, 977, nil, nil, nil, 977, 977, 977, 977, nil, + nil, nil, nil, nil, 977, nil, nil, nil, nil, nil, + nil, nil, 977, 977, nil, 977, 977, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 978, 978, 977, + nil, 978, nil, nil, nil, nil, nil, nil, nil, 978, + 978, nil, 978, 978, 978, 978, 978, 978, 978, nil, + nil, 978, 978, nil, nil, nil, 978, 978, 978, 978, + nil, nil, nil, nil, nil, 978, nil, nil, nil, nil, + nil, nil, nil, 978, 978, nil, 978, 978, 978, 978, + 978, 978, 978, 978, 978, 978, 978, 978, nil, 658, + 978, 658, 658, 658, 658, 658, nil, 716, nil, 716, + 716, 716, 716, 716, 658, nil, nil, nil, nil, nil, + nil, nil, 716, nil, 717, nil, 717, 717, 717, 717, + 717, nil, nil, nil, nil, nil, 658, nil, nil, 717, + nil, nil, nil, nil, 716, 658, 658, 658, 658, nil, + nil, nil, 658, 716, 716, 716, 716, nil, nil, nil, + 716, 717, nil, 799, nil, 799, 799, 799, 799, 799, + 717, 717, 717, 717, nil, nil, nil, 717, 799, nil, + 801, nil, 801, 801, 801, 801, 801, nil, 846, nil, + 846, 846, 846, 846, 846, 801, nil, nil, nil, nil, + 799, nil, nil, 846, nil, nil, nil, nil, nil, 799, + 799, 799, 799, nil, nil, nil, 799, 801, nil, nil, + nil, nil, nil, nil, nil, 846, 801, 801, 801, 801, + nil, nil, nil, 801, 846, 846, 846, 846, nil, nil, + 848, 846, 848, 848, 848, 848, 848, nil, 938, nil, + 938, 938, 938, 938, 938, 848, nil, nil, nil, nil, + nil, nil, nil, 938, nil, 944, nil, 944, 944, 944, + 944, 944, nil, nil, nil, nil, nil, 848, nil, nil, + 944, nil, nil, nil, nil, 938, 848, 848, 848, 848, + nil, nil, nil, 848, 938, 938, 938, 938, nil, nil, + nil, 938, 944, nil, 962, nil, 962, 962, 962, 962, + 962, nil, nil, 944, 944, nil, nil, nil, 944, 962, + nil, 964, nil, 964, 964, 964, 964, 964, 966, nil, + 966, 966, 966, 966, 966, nil, 964, nil, nil, nil, + nil, 962, nil, 966, nil, nil, nil, nil, nil, nil, + 962, 962, 962, 962, nil, nil, nil, 962, 964, nil, + nil, nil, nil, nil, nil, 966, nil, nil, nil, 964, + 964, nil, nil, nil, 964, nil, 966, 966, nil, nil, + 968, 966, 968, 968, 968, 968, 968, 1006, nil, 1006, + 1006, 1006, 1006, 1006, 1016, 968, 1016, 1016, 1016, 1016, + 1016, nil, 1006, nil, nil, nil, nil, nil, nil, 1016, + nil, nil, nil, nil, nil, nil, nil, 968, nil, nil, + nil, nil, nil, nil, 1006, nil, nil, nil, 968, 968, + nil, 1016, nil, 968, nil, 1006, 1006, nil, nil, nil, + 1006, nil, 1016, 1016, nil, nil, nil, 1016 ] + +racc_action_pointer = [ + 744, 1, nil, 303, nil, 5083, 729, -91, 23075, 23203, + -80, nil, -62, 107, 470, 184, 61, 10, nil, -79, + 5214, 1164, 182, nil, 15, nil, -8, 22590, 22700, 5345, + 5476, 5607, nil, 884, 5738, 5869, nil, 80, 190, 227, + 169, 283, 6008, 6139, 6270, 141, 556, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 22188, nil, -75, 6401, + 6532, -23, nil, 6663, 6794, nil, nil, 6925, 7064, 7195, + 7326, 23587, nil, nil, nil, nil, nil, nil, nil, 518, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 0, nil, nil, + 112, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 277, nil, 7465, nil, nil, nil, nil, 7604, 7735, + 7866, 7997, 8136, 1024, nil, 472, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 153, nil, 1164, 8267, + 8398, 8529, 23761, 23822, 8660, 8791, 8922, 9053, 9184, 9315, + nil, nil, 610, -24, 15, 301, 90, 224, 293, nil, + 9446, 1304, 294, 9577, 9708, 9839, 9970, 10101, 10232, 10363, + 10494, 10625, 10756, 10887, 11018, 11149, 11280, 11411, 11542, 11673, + 11804, 11935, 12066, 12197, 12328, 12459, 12590, 12721, 12852, nil, + nil, 23883, nil, nil, 295, 12983, 13114, nil, nil, nil, + nil, nil, nil, nil, 13245, nil, 1304, nil, 264, 266, + nil, 13376, 328, 13507, nil, nil, 13638, 13769, nil, nil, + 380, nil, 13908, 1429, 313, 308, 1444, 347, 397, 367, + 14039, 1584, 613, 659, 744, 449, 747, nil, 440, 431, + 33, nil, nil, nil, 481, 331, 443, 14178, nil, 302, + 514, 786, nil, 553, nil, 14309, 1724, 14440, 495, nil, + 107, 127, 537, 522, 206, 561, nil, nil, 24, -1, + 26, 14571, 14702, 416, 636, 526, -19, -18, 816, 627, + 10, 667, nil, nil, 191, 225, 8, nil, 884, nil, + 34, 14833, nil, nil, nil, 150, 274, 412, 442, 570, + 576, 581, 792, 794, nil, 797, nil, 14964, nil, 330, + 388, 397, 457, 460, -41, -35, 464, nil, nil, nil, + nil, nil, nil, nil, nil, 586, 23331, nil, nil, nil, + nil, 588, nil, nil, 579, 15095, 591, nil, nil, 884, + 598, nil, 597, 605, 425, 471, 22812, nil, nil, nil, + 222, 334, 651, nil, nil, 22322, 22456, nil, 1444, nil, + 599, nil, nil, 744, nil, nil, nil, nil, -33, nil, + 652, 23944, 24005, 15226, 252, 15357, 15488, 15619, 3264, 3404, + 534, 561, 691, 717, 734, 738, 5214, 5345, 5476, 3544, + 3684, 3824, 3964, 4104, 4244, 4384, 4524, 4664, 4804, 489, + 3094, 4944, 5083, 1584, -56, 22941, nil, nil, nil, nil, + 703, nil, 178, 237, 704, nil, nil, 15750, nil, 15881, + nil, 16012, nil, 327, nil, nil, nil, 16151, 1444, 1864, + 708, 710, nil, nil, 715, 16290, 726, 16421, 24066, 24127, + 887, 768, nil, 16552, 725, nil, 16683, 16814, 24188, 24249, + 1724, 16945, 861, 882, 422, 802, nil, 17076, nil, nil, + 17207, nil, nil, nil, nil, 22944, 2004, 884, nil, 2144, + 62, 118, 881, 889, 17338, 17469, 24310, 24371, 25, nil, + nil, 926, nil, 24432, 24493, 17600, nil, nil, nil, 532, + 237, 2284, 819, nil, -14, nil, nil, nil, 727, nil, + nil, nil, 791, nil, nil, 261, nil, 338, nil, nil, + 777, nil, 778, nil, nil, nil, 23459, nil, 787, 17731, + 17862, 479, 827, 17993, 18124, 18255, 18386, 827, nil, nil, + 18517, 18648, 828, nil, 18779, 18910, nil, nil, 254, 277, + 466, 602, 795, 1024, 794, nil, 22905, nil, 2424, 913, + 5, 280, nil, 2564, 2704, nil, 811, nil, 878, 19041, + nil, nil, 19172, nil, 857, -113, 19303, 840, nil, 844, + 136, 177, 889, 337, 1024, 894, 855, 19434, 1864, 930, + 20, 983, 19565, nil, 868, nil, 235, nil, 24738, nil, + 875, 876, nil, 878, 881, 883, nil, nil, nil, nil, + nil, nil, nil, nil, 875, 569, nil, nil, 19696, nil, + nil, nil, 967, nil, nil, nil, 970, nil, nil, 980, + 472, nil, 1018, nil, nil, nil, nil, 1027, nil, 32, + 907, 26, 40, 122, 183, 19827, 406, 1164, nil, 908, + 2844, 19958, nil, nil, 1039, 2984, 24746, 24763, 23700, nil, + nil, nil, nil, nil, nil, 3124, nil, nil, nil, nil, + nil, nil, nil, 917, 20089, 2004, 20220, nil, 918, nil, + 2144, nil, 2284, nil, nil, 2424, nil, 2564, nil, 2704, + 20351, 20482, 20613, 20744, 342, 20875, 919, 927, nil, 928, + 930, 931, nil, 956, 936, 945, 942, 21006, nil, nil, + 1096, nil, nil, 3264, 997, 1105, nil, nil, nil, nil, + 985, 404, nil, nil, 1115, nil, 3404, 995, 1049, nil, + nil, 1047, nil, 37, 1008, 551, nil, nil, 428, 24802, + nil, 24819, nil, 5916, nil, 21137, nil, 663, nil, 1015, + 228, 1019, nil, nil, nil, nil, 1142, nil, 21268, 1145, + 3544, 3684, nil, 21399, 3824, 71, 121, nil, 1147, 623, + 3964, nil, 1148, 1028, 695, nil, 1034, 1038, nil, 2844, + 21530, 21661, 2984, 627, nil, nil, 24827, nil, 24879, nil, + 7373, nil, nil, 1063, 1150, 21792, 956, 1121, nil, 1064, + nil, nil, nil, 4104, nil, nil, 33, 21923, nil, nil, + nil, nil, nil, 1088, 1055, nil, nil, nil, 1057, 1058, + nil, 1059, 1067, nil, 1073, nil, nil, 1090, 3110, 1091, + 668, nil, nil, 36, nil, 1236, 1241, nil, 17, nil, + nil, nil, 1245, nil, nil, nil, 1169, nil, 1130, nil, + nil, 1135, 1143, 1144, 1145, nil, 1155, nil, 368, nil, + nil, nil, 1027, 24554, nil, nil, nil, 4244, 1066, 1096, + 1167, 1234, 1206, nil, 4384, 4524, nil, nil, 24887, nil, + 14086, nil, 22519, nil, 24904, nil, nil, nil, nil, 327, + 3169, 1158, 4664, nil, nil, nil, nil, nil, 4804, nil, + 4944, nil, 24943, nil, 24960, nil, 24967, nil, 25019, nil, + nil, nil, 1290, 1205, 1207, 1290, 22054, 24615, 24676, 1236, + 1185, 1292, 1178, 1179, 1183, 1184, 1185, 3344, 1195, 3484, + 592, 1321, 1322, 1199, 1207, 1213, 1227, nil, nil, 1234, + 40, 42, 111, 1304, nil, nil, 25026, nil, nil, nil, + nil, 3530, 1251, nil, nil, nil, 25033, nil, nil, nil, + nil, 98, 1252, 1257, 1258, nil, nil ] + +racc_action_default = [ + -3, -600, -1, -586, -4, -600, -7, -600, -600, -600, + -600, -29, -600, -600, -600, -279, -600, -40, -43, -588, + -600, -48, -50, -51, -52, -56, -256, -256, -256, -293, + -329, -330, -68, -11, -72, -80, -82, -600, -491, -492, + -600, -600, -600, -600, -600, -588, -237, -270, -271, -272, + -273, -274, -275, -276, -277, -278, -576, -281, -283, -599, + -566, -301, -303, -600, -600, -307, -310, -586, -600, -600, + -600, -600, -331, -332, -334, -335, -432, -433, -434, -435, + -436, -457, -439, -440, -459, -461, -444, -449, -453, -455, + -471, -459, -473, -475, -476, -477, -478, -574, -480, -481, + -575, -483, -484, -485, -486, -487, -488, -489, -490, -495, + -496, -600, -2, -587, -595, -596, -597, -6, -600, -600, + -600, -600, -600, -3, -17, -600, -111, -112, -113, -114, + -115, -116, -117, -118, -119, -123, -124, -125, -126, -127, + -128, -129, -130, -131, -132, -133, -134, -135, -136, -137, + -138, -139, -140, -141, -142, -143, -144, -145, -146, -147, + -148, -149, -150, -151, -152, -153, -154, -155, -156, -157, + -158, -159, -160, -161, -162, -163, -164, -165, -166, -167, + -168, -169, -170, -171, -172, -173, -174, -175, -176, -177, + -178, -179, -180, -181, -182, -183, -184, -185, -186, -187, + -188, -189, -190, -191, -192, -193, -22, -120, -11, -600, + -600, -246, -600, -600, -600, -600, -600, -600, -600, -588, + -589, -47, -600, -491, -492, -600, -279, -600, -600, -229, + -600, -11, -600, -600, -600, -600, -600, -600, -600, -600, + -600, -600, -600, -600, -600, -600, -600, -600, -600, -600, + -600, -600, -600, -600, -600, -600, -600, -600, -600, -401, + -403, -600, -584, -585, -57, -246, -600, -300, -407, -416, + -418, -63, -413, -64, -588, -65, -238, -251, -260, -260, + -255, -600, -261, -600, -457, -568, -600, -600, -66, -67, + -586, -12, -600, -15, -600, -70, -11, -588, -600, -73, + -76, -11, -88, -89, -600, -600, -96, -293, -296, -588, + -600, -329, -330, -333, -414, -600, -78, -600, -84, -290, + -474, -600, -214, -215, -230, -600, -11, -600, -588, -239, + -592, -592, -600, -600, -592, -600, -302, -392, -49, -600, + -600, -600, -600, -586, -600, -587, -491, -492, -600, -600, + -279, -600, -345, -346, -106, -107, -600, -109, -600, -279, + -600, -600, -491, -492, -322, -111, -112, -153, -154, -155, + -171, -176, -183, -186, -324, -600, -564, -600, -437, -600, + -600, -600, -600, -600, -600, -600, -600, 1027, -5, -598, + -23, -24, -25, -26, -27, -600, -600, -19, -20, -21, + -121, -600, -30, -39, -266, -600, -600, -265, -31, -196, + -588, -247, -260, -260, -577, -578, -256, -411, -579, -580, + -578, -577, -256, -410, -412, -579, -580, -37, -204, -38, + -600, -41, -42, -194, -261, -44, -45, -46, -588, -299, + -600, -600, -600, -246, -290, -600, -600, -600, -205, -206, + -207, -208, -209, -210, -211, -212, -216, -217, -218, -219, + -220, -221, -222, -223, -224, -225, -226, -227, -228, -231, + -232, -233, -234, -588, -381, -256, -577, -578, -54, -58, + -588, -257, -381, -381, -588, -295, -252, -600, -253, -600, + -258, -600, -262, -600, -571, -573, -10, -587, -14, -3, + -588, -69, -288, -85, -74, -600, -588, -246, -600, -600, + -95, -600, -474, -600, -81, -86, -600, -600, -600, -600, + -235, -600, -424, -600, -284, -600, -240, -594, -593, -242, + -594, -291, -292, -567, -304, -524, -11, -336, -337, -11, + -600, -600, -600, -600, -600, -246, -600, -600, -290, -315, + -106, -107, -108, -600, -600, -246, -318, -497, -498, -600, + -600, -11, -502, -326, -588, -438, -458, -463, -600, -465, + -441, -460, -600, -462, -443, -600, -446, -600, -448, -451, + -600, -452, -600, -472, -8, -18, -600, -28, -269, -600, + -600, -415, -600, -248, -250, -600, -600, -59, -245, -408, + -600, -600, -61, -409, -600, -600, -298, -590, -577, -578, + -577, -578, -588, -194, -600, -382, -588, -384, -11, -53, + -404, -381, -243, -11, -11, -294, -260, -259, -263, -600, + -569, -570, -600, -13, -600, -71, -600, -77, -83, -588, + -577, -578, -244, -92, -94, -600, -79, -600, -203, -213, + -588, -599, -599, -282, -588, -287, -592, -393, -524, -396, + -563, -563, -507, -509, -509, -509, -523, -525, -526, -527, + -528, -529, -530, -531, -532, -600, -534, -536, -538, -543, + -545, -546, -548, -553, -555, -556, -558, -559, -560, -600, + -599, -338, -599, -308, -339, -340, -311, -600, -314, -600, + -588, -577, -578, -581, -289, -600, -106, -107, -110, -588, + -11, -600, -500, -320, -600, -11, -524, -524, -600, -565, + -464, -467, -468, -469, -470, -11, -442, -445, -447, -450, + -454, -456, -122, -267, -600, -197, -600, -591, -260, -33, + -199, -34, -200, -60, -35, -202, -36, -201, -62, -195, + -600, -600, -600, -600, -415, -600, -563, -563, -363, -365, + -365, -365, -380, -600, -588, -386, -532, -540, -541, -551, + -600, -406, -405, -11, -600, -600, -254, -264, -572, -16, + -75, -90, -87, -297, -599, -343, -11, -425, -599, -426, + -427, -600, -241, -600, -588, -600, -505, -506, -600, -600, + -516, -600, -519, -600, -521, -600, -347, -600, -349, -351, + -358, -588, -537, -547, -557, -561, -600, -341, -600, -600, + -11, -11, -313, -600, -11, -415, -600, -415, -600, -600, + -11, -323, -600, -588, -600, -327, -600, -268, -32, -198, + -249, -600, -236, -600, -361, -362, -371, -373, -600, -376, + -600, -378, -383, -600, -600, -600, -539, -600, -402, -600, + -417, -419, -9, -11, -431, -344, -600, -600, -429, -285, + -394, -397, -399, -600, -563, -544, -562, -508, -509, -509, + -535, -509, -509, -554, -509, -532, -549, -588, -600, -356, + -600, -533, -305, -600, -306, -600, -600, -263, -599, -316, + -319, -499, -600, -325, -501, -503, -502, -466, -563, -542, + -364, -365, -365, -365, -365, -552, -365, -385, -588, -388, + -390, -391, -550, -600, -290, -55, -430, -11, -97, -98, + -600, -600, -105, -428, -11, -11, -395, -504, -600, -512, + -600, -514, -600, -517, -600, -520, -522, -348, -350, -354, + -600, -359, -11, -309, -312, -420, -421, -422, -11, -321, + -11, -360, -600, -368, -600, -370, -600, -374, -600, -377, + -379, -387, -600, -289, -581, -424, -246, -600, -600, -104, + -600, -600, -509, -509, -509, -509, -352, -600, -357, -600, + -599, -600, -600, -365, -365, -365, -365, -389, -423, -588, + -577, -578, -581, -103, -398, -400, -600, -510, -513, -515, + -518, -600, -355, -342, -317, -328, -600, -366, -369, -372, + -375, -415, -509, -353, -365, -511, -367 ] + +racc_goto_table = [ + 218, 329, 374, 14, 277, 277, 277, 543, 14, 313, + 313, 260, 336, 523, 2, 410, 416, 422, 488, 536, + 539, 261, 715, 222, 407, 651, 325, 339, 340, 379, + 429, 343, 222, 222, 222, 479, 14, 304, 304, 129, + 129, 124, 207, 313, 313, 313, 132, 132, 432, 268, + 272, 278, 278, 278, 627, 816, 627, 806, 295, 113, + 297, 221, 134, 134, 299, 475, 222, 222, 630, 480, + 222, 348, 358, 358, 320, 439, 264, 271, 273, 552, + 760, 330, 390, 391, 392, 393, 6, 948, 316, 117, + 112, 6, 784, 883, 1, 116, 591, 279, 279, 279, + 659, 811, 129, 862, 693, 696, 275, 288, 289, 630, + 338, 338, 380, 763, 338, 915, 14, 360, 364, 386, + 919, 222, 222, 222, 222, 14, 14, 331, 334, 633, + 485, 526, 529, 819, 921, 533, 206, 395, 880, 514, + 618, 575, 577, 353, 403, 396, 796, 797, 623, 624, + 621, 586, 488, 501, 344, 332, 620, 376, 333, 116, + 627, 627, 534, 351, 556, 338, 338, 338, 338, 375, + 326, 327, 654, 630, 328, 337, 951, 341, 820, 342, + 821, 705, 958, 710, 830, 880, 277, 561, 948, 806, + 562, 718, 889, 906, 762, 26, 764, 388, 918, 6, + 26, 571, 573, 576, 576, 697, 657, 571, 394, 6, + 870, 14, 222, 222, 222, 26, 535, 222, 222, 222, + 222, 222, 222, 794, 26, 26, 26, 793, 26, 915, + 883, 406, 493, 887, 14, 417, 988, 406, 997, 934, + 277, 277, 844, 845, 426, 416, 422, 612, 714, 277, + 402, 408, 921, 935, 474, 427, 431, 482, 26, 26, + 666, 853, 26, 435, 436, 437, 438, 483, 222, 222, + 806, 955, 806, 1012, 788, 313, 708, 222, 866, 378, + 381, 833, 834, 880, 382, 383, 384, 773, 278, 385, + 511, 873, 313, 720, 606, 14, 278, 1023, 754, 14, + 725, 711, 878, 304, 14, 540, 541, 880, 26, 525, + 911, 639, 642, 26, 26, 26, 26, 26, 26, 875, + 304, 295, 642, 500, 909, 781, 295, 637, 506, 14, + 222, 986, 806, 268, 279, 646, 622, 272, nil, 956, + 625, nil, 279, 481, 222, 222, 497, 515, 512, 700, + 642, 484, 13, 504, nil, 1013, 635, 13, 642, 709, + 937, nil, 638, nil, 222, 776, 960, nil, 743, 806, + nil, 806, 563, 748, 524, nil, nil, 496, 498, 824, + 222, nil, 116, 666, nil, 13, 825, nil, 338, 338, + 899, 592, nil, 806, 961, 827, 728, 828, 728, nil, + nil, nil, 832, 26, 26, 26, 26, 627, 560, 26, + 26, 26, 26, 26, 26, nil, nil, nil, 277, 630, + 719, nil, nil, nil, 564, nil, 26, 129, nil, 585, + 542, nil, nil, nil, 132, 116, nil, 432, nil, 598, + nil, 666, 666, nil, nil, 603, 222, nil, nil, nil, + 134, nil, 557, nil, 614, nil, nil, 792, 780, 298, + 26, 26, nil, nil, 417, 13, 597, 789, nil, 26, + nil, 761, 602, 426, 13, 13, nil, 776, 998, nil, + 313, nil, 277, nil, nil, nil, nil, 26, 313, nil, + nil, 26, nil, nil, nil, nil, 26, nil, 598, nil, + 14, nil, 14, nil, nil, nil, 783, nil, 304, nil, + 222, nil, nil, 634, nil, nil, 304, 902, nil, nil, + 277, 26, 26, nil, 222, 619, nil, nil, nil, nil, + 277, 417, 757, nil, nil, 515, 26, 26, nil, 14, + 426, 417, 14, 515, nil, nil, 927, nil, 222, nil, + 426, nil, nil, nil, nil, 626, 26, nil, 222, nil, + 13, 957, nil, nil, 14, nil, 699, nil, 650, 417, + nil, 772, 26, 952, nil, nil, nil, 417, 426, nil, + nil, nil, nil, 13, 426, 6, nil, nil, nil, nil, + nil, nil, nil, 592, 790, 656, nil, 765, 222, 222, + nil, nil, nil, 222, 222, nil, nil, 222, 771, nil, + nil, 313, nil, nil, nil, nil, nil, 129, nil, 732, + 592, 14, 313, nil, 132, nil, 14, 14, nil, nil, + nil, nil, 694, 694, 401, 791, 739, 741, 26, 304, + 134, 744, 746, nil, 13, 431, nil, 992, 13, 835, + 304, 712, 713, 13, 879, nil, 881, 298, nil, nil, + nil, 738, nil, nil, nil, 598, 515, 891, 603, 826, + nil, nil, nil, nil, 406, 829, nil, 782, 13, nil, + nil, 592, 674, nil, nil, 1021, nil, nil, nil, 904, + 592, nil, 26, nil, 26, nil, nil, nil, nil, nil, + nil, 912, 26, 913, nil, nil, nil, nil, 222, nil, + nil, 874, nil, 14, 222, nil, 26, nil, 14, nil, + nil, nil, 298, nil, nil, nil, 864, 298, 14, nil, + 868, 26, nil, nil, 26, nil, nil, nil, nil, 222, + 26, nil, 313, 947, nil, 765, nil, nil, nil, 129, + 26, nil, 338, nil, nil, nil, 26, nil, 338, 908, + nil, nil, 757, 766, 757, nil, 757, nil, nil, 767, + 856, nil, nil, nil, nil, 765, 14, 838, nil, 16, + 999, 642, 893, nil, 16, nil, nil, nil, nil, 14, + 26, 26, nil, 982, nil, 26, 26, nil, nil, 26, + nil, nil, nil, nil, 758, 674, 15, nil, nil, nil, + nil, 15, 16, 26, nil, nil, nil, 993, 26, 26, + 759, 222, nil, 14, 14, nil, nil, 14, nil, nil, + 313, nil, nil, 14, nil, nil, nil, nil, nil, 15, + 306, 306, 313, nil, nil, nil, nil, 352, nil, 13, + nil, 13, nil, nil, nil, nil, nil, nil, 922, nil, + nil, nil, nil, 674, 674, 338, 14, nil, nil, nil, + 930, nil, nil, nil, 350, 359, 359, nil, 757, nil, + 757, nil, 757, nil, 757, nil, nil, nil, 13, nil, + nil, 13, 16, nil, nil, nil, nil, nil, nil, 971, + 26, 16, 16, nil, nil, 26, 26, nil, nil, nil, + 26, nil, nil, 13, nil, nil, nil, nil, 694, 15, + 26, 901, nil, nil, nil, nil, 905, nil, 15, 15, + 14, 26, 757, nil, nil, nil, nil, 14, 14, nil, + nil, nil, nil, nil, nil, nil, 674, nil, 674, nil, + nil, 277, nil, nil, 426, 14, nil, nil, nil, nil, + nil, 14, 690, 14, nil, 692, nil, nil, 26, nil, + 13, nil, nil, nil, nil, 13, 13, nil, nil, 222, + 592, 26, nil, 876, nil, nil, 876, 16, nil, nil, + 335, nil, nil, 766, 430, 766, 767, nil, nil, 767, + 417, 767, nil, 767, nil, 882, nil, 884, nil, 426, + 16, nil, nil, 26, 15, 26, 26, nil, nil, 26, + nil, nil, nil, nil, nil, 26, 847, 849, 851, nil, + nil, 876, nil, nil, 758, nil, 758, 15, 758, nil, + nil, nil, nil, nil, 770, nil, nil, nil, nil, 774, + 775, nil, 914, nil, 916, nil, nil, nil, 26, nil, + nil, nil, 13, nil, nil, nil, nil, 13, nil, nil, + nil, 16, nil, nil, nil, 16, nil, 13, nil, nil, + 16, nil, nil, nil, nil, 674, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 15, nil, + nil, nil, 15, nil, nil, 16, 306, 15, nil, 766, + nil, nil, 800, 802, 804, 767, nil, 767, nil, 767, + nil, 767, 26, 306, nil, 13, 38, nil, nil, 26, + 26, 38, 15, nil, nil, nil, nil, nil, 13, 404, + nil, nil, 983, nil, 984, 434, 985, 26, nil, nil, + 758, 836, 758, 26, 758, 26, 758, nil, 39, 38, + 302, 302, nil, 39, nil, nil, 994, nil, 995, 767, + 996, 26, 13, 13, nil, nil, 13, nil, 963, 965, + 967, 969, 13, 970, nil, nil, nil, nil, nil, nil, + nil, 39, 303, 303, 346, 362, 362, 362, nil, 859, + nil, nil, nil, nil, 758, nil, nil, nil, nil, nil, + 1022, 490, 865, 492, nil, 13, 494, 495, nil, nil, + 1024, nil, nil, nil, nil, nil, 347, 363, 363, 363, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 38, + nil, nil, nil, nil, nil, nil, 895, 896, 38, 38, + 898, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1017, 1018, 1019, 1020, nil, nil, nil, nil, nil, nil, + nil, 39, nil, nil, nil, nil, 16, nil, 16, 13, + 39, 39, nil, nil, nil, nil, 13, 13, nil, 926, + nil, 1026, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 15, 13, 15, nil, nil, nil, nil, + 13, 306, 13, nil, nil, 16, nil, nil, 16, 306, + nil, nil, nil, nil, nil, nil, nil, 939, 941, nil, + 943, 945, nil, 946, 38, 588, nil, nil, nil, nil, + 16, nil, 15, nil, nil, 15, nil, nil, nil, nil, + nil, nil, nil, 975, nil, nil, nil, 38, nil, nil, + 980, 981, nil, nil, nil, nil, 39, 15, nil, nil, + nil, nil, nil, nil, 724, nil, nil, nil, 990, nil, + nil, nil, nil, 430, 991, nil, nil, nil, nil, 39, + nil, nil, nil, nil, nil, nil, nil, 16, nil, nil, + nil, nil, 16, 16, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 628, 38, 335, + nil, 631, 38, nil, 15, nil, 302, 38, nil, 15, + 15, 1007, 1008, 1009, 1010, nil, nil, nil, nil, nil, + nil, nil, 306, 302, nil, nil, nil, nil, nil, nil, + 39, nil, 38, 306, 39, nil, nil, 628, 303, 39, + 335, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 1025, nil, nil, 434, 303, nil, nil, nil, nil, + nil, nil, nil, nil, 39, nil, nil, nil, nil, 16, + nil, nil, nil, nil, 16, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 16, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 15, nil, nil, 733, + nil, 15, nil, 628, 335, nil, nil, nil, nil, nil, + nil, 15, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 16, nil, nil, nil, nil, nil, nil, 777, + nil, nil, 778, nil, nil, 16, nil, nil, nil, nil, + nil, nil, nil, 359, nil, nil, nil, nil, nil, 15, + nil, nil, 787, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 15, nil, nil, nil, nil, nil, nil, 16, + 16, nil, nil, 16, nil, nil, nil, nil, 812, 16, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 38, nil, 38, 15, 15, nil, nil, + 15, 302, nil, nil, nil, nil, 15, nil, nil, 302, + nil, nil, 16, nil, nil, nil, 933, nil, nil, nil, + nil, nil, nil, nil, nil, 39, nil, 39, nil, nil, + nil, 359, 38, 303, 837, 38, nil, nil, nil, 15, + nil, 303, nil, 932, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 38, nil, nil, + nil, nil, nil, nil, 39, nil, nil, 39, nil, nil, + nil, nil, nil, nil, nil, nil, 16, nil, nil, nil, + nil, nil, nil, 16, 16, nil, nil, nil, nil, 39, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 16, nil, 15, nil, 886, nil, 16, nil, 16, + 15, 15, nil, nil, 38, nil, nil, nil, nil, 38, + 38, nil, nil, 897, nil, nil, nil, nil, 15, nil, + nil, nil, 302, nil, 15, nil, 15, nil, nil, nil, + 335, nil, nil, 302, nil, nil, 39, nil, nil, nil, + nil, 39, 39, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 303, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 303, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 38, nil, nil, nil, + nil, 38, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 38, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 39, nil, + nil, nil, nil, 39, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 39, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 362, nil, nil, nil, nil, nil, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 38, 229, nil, nil, nil, nil, nil, nil, + nil, nil, 276, 276, 276, 363, nil, nil, nil, nil, + nil, 39, nil, nil, nil, 322, 323, 324, nil, nil, + nil, nil, nil, nil, 39, nil, 38, 38, nil, nil, + 38, nil, 276, 276, nil, nil, 38, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 39, 39, + nil, 362, 39, nil, nil, nil, nil, nil, 39, 38, + nil, nil, nil, 928, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 363, nil, nil, nil, nil, nil, nil, + nil, 39, nil, nil, nil, 929, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 38, nil, nil, nil, nil, nil, nil, + 38, 38, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 38, nil, + nil, nil, nil, nil, 38, 39, 38, nil, nil, nil, + nil, nil, 39, 39, nil, nil, nil, nil, nil, nil, + nil, nil, 276, 409, 276, nil, nil, 428, 433, nil, + 39, nil, nil, nil, nil, nil, 39, nil, 39, nil, + nil, nil, nil, 229, nil, nil, 448, 449, 450, 451, + 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 473, nil, nil, nil, nil, nil, nil, 276, 276, + nil, nil, nil, nil, nil, nil, nil, 276, nil, nil, + nil, nil, nil, nil, 276, nil, 276, nil, nil, 276, + 276, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 520, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 276, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 276, nil, 428, 613, + 409, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 276, nil, 276, nil, 276, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 276, nil, nil, nil, nil, nil, nil, nil, nil, 648, + 649, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 276, nil, nil, 276, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 276, 276, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 276, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 276, 735, nil, nil, 276, 276, 740, 742, + nil, nil, nil, 745, 747, nil, nil, 613, 749, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 276, nil, nil, 276, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 276, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 276, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 276, nil, 839, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 740, 742, 747, 745, nil, 842, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 276, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 276, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 276, 839, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 276 ] + +racc_goto_check = [ + 31, 67, 56, 22, 33, 33, 33, 92, 22, 64, + 64, 141, 86, 8, 2, 23, 37, 37, 73, 89, + 89, 36, 98, 22, 27, 10, 31, 17, 17, 154, + 27, 17, 22, 22, 22, 39, 22, 22, 22, 57, + 57, 15, 15, 64, 64, 64, 60, 60, 18, 71, + 71, 68, 68, 68, 74, 90, 74, 118, 45, 6, + 46, 20, 61, 61, 49, 37, 22, 22, 181, 23, + 22, 22, 22, 22, 63, 47, 38, 38, 38, 54, + 129, 68, 17, 17, 17, 17, 7, 117, 50, 5, + 4, 7, 11, 177, 1, 96, 24, 70, 70, 70, + 140, 119, 57, 12, 91, 91, 44, 44, 44, 181, + 29, 29, 155, 132, 29, 178, 22, 55, 55, 155, + 134, 22, 22, 22, 22, 22, 22, 70, 70, 14, + 47, 69, 69, 11, 135, 69, 16, 2, 172, 51, + 40, 158, 158, 19, 28, 30, 124, 124, 40, 40, + 42, 62, 73, 47, 4, 66, 72, 84, 85, 96, + 74, 74, 88, 93, 95, 29, 29, 29, 29, 99, + 100, 101, 102, 181, 103, 104, 120, 105, 106, 107, + 108, 109, 110, 111, 112, 172, 33, 113, 117, 118, + 114, 115, 118, 116, 121, 41, 127, 5, 133, 7, + 41, 159, 159, 159, 159, 92, 136, 159, 7, 7, + 137, 22, 22, 22, 22, 41, 138, 22, 22, 22, + 22, 22, 22, 140, 41, 41, 41, 139, 41, 178, + 177, 68, 154, 119, 22, 71, 120, 68, 134, 142, + 33, 33, 124, 124, 57, 37, 37, 23, 8, 33, + 20, 20, 135, 143, 144, 20, 20, 146, 41, 41, + 166, 132, 41, 29, 29, 29, 29, 147, 22, 22, + 118, 148, 118, 120, 149, 64, 54, 22, 150, 153, + 156, 140, 140, 172, 157, 160, 161, 40, 68, 162, + 31, 132, 64, 163, 47, 22, 68, 120, 24, 22, + 164, 165, 170, 22, 22, 17, 17, 172, 41, 31, + 129, 23, 37, 41, 41, 41, 41, 41, 41, 174, + 22, 45, 37, 46, 175, 24, 45, 51, 46, 22, + 22, 118, 118, 71, 70, 51, 47, 71, nil, 11, + 47, nil, 70, 44, 22, 22, 6, 49, 63, 23, + 37, 44, 21, 50, nil, 90, 47, 21, 37, 23, + 124, nil, 47, nil, 22, 73, 98, nil, 39, 118, + nil, 118, 36, 39, 29, nil, nil, 4, 7, 89, + 22, nil, 96, 166, nil, 21, 24, nil, 29, 29, + 91, 31, nil, 118, 124, 24, 159, 8, 159, nil, + nil, nil, 8, 41, 41, 41, 41, 74, 29, 41, + 41, 41, 41, 41, 41, nil, nil, nil, 33, 181, + 47, nil, nil, nil, 29, nil, 41, 57, nil, 15, + 4, nil, nil, nil, 60, 96, nil, 18, nil, 71, + nil, 166, 166, nil, nil, 71, 22, nil, nil, nil, + 61, nil, 96, nil, 31, nil, nil, 69, 51, 9, + 41, 41, nil, nil, 71, 21, 38, 27, nil, 41, + nil, 130, 38, 57, 21, 21, nil, 73, 10, nil, + 64, nil, 33, nil, nil, nil, nil, 41, 64, nil, + nil, 41, nil, nil, nil, nil, 41, nil, 71, nil, + 22, nil, 22, nil, nil, nil, 47, nil, 22, nil, + 22, nil, nil, 2, nil, nil, 22, 8, nil, nil, + 33, 41, 41, nil, 22, 38, nil, nil, nil, nil, + 33, 71, 123, nil, nil, 49, 41, 41, nil, 22, + 57, 71, 22, 49, nil, nil, 89, nil, 22, nil, + 57, nil, nil, nil, nil, 70, 41, nil, 22, nil, + 21, 92, nil, nil, 22, nil, 68, nil, 29, 71, + nil, 86, 41, 89, nil, nil, nil, 71, 57, nil, + nil, nil, nil, 21, 57, 7, nil, nil, nil, nil, + nil, nil, nil, 31, 67, 70, nil, 31, 22, 22, + nil, nil, nil, 22, 22, nil, nil, 22, 141, nil, + nil, 64, nil, nil, nil, nil, nil, 57, nil, 15, + 31, 22, 64, nil, 60, nil, 22, 22, nil, nil, + nil, nil, 96, 96, 9, 31, 20, 20, 41, 22, + 61, 20, 20, nil, 21, 20, nil, 8, 21, 56, + 22, 96, 96, 21, 130, nil, 130, 9, nil, nil, + nil, 70, nil, nil, nil, 71, 49, 47, 71, 17, + nil, nil, nil, nil, 68, 17, nil, 49, 21, nil, + nil, 31, 171, nil, nil, 24, nil, nil, nil, 47, + 31, nil, 41, nil, 41, nil, nil, nil, nil, nil, + nil, 130, 41, 130, nil, nil, nil, nil, 22, nil, + nil, 123, nil, 22, 22, nil, 41, nil, 22, nil, + nil, nil, 9, nil, nil, nil, 67, 9, 22, nil, + 67, 41, nil, nil, 41, nil, nil, nil, nil, 22, + 41, nil, 64, 47, nil, 31, nil, nil, nil, 57, + 41, nil, 29, nil, nil, nil, 41, nil, 29, 123, + nil, nil, 123, 171, 123, nil, 123, nil, nil, 173, + 22, nil, nil, nil, nil, 31, 22, 20, nil, 26, + 23, 37, 17, nil, 26, nil, nil, nil, nil, 22, + 41, 41, nil, 130, nil, 41, 41, nil, nil, 41, + nil, nil, nil, nil, 125, 171, 25, nil, nil, nil, + nil, 25, 26, 41, nil, nil, nil, 130, 41, 41, + 128, 22, nil, 22, 22, nil, nil, 22, nil, nil, + 64, nil, nil, 22, nil, nil, nil, nil, nil, 25, + 25, 25, 64, nil, nil, nil, nil, 26, nil, 21, + nil, 21, nil, nil, nil, nil, nil, nil, 22, nil, + nil, nil, nil, 171, 171, 29, 22, nil, nil, nil, + 22, nil, nil, nil, 25, 25, 25, nil, 123, nil, + 123, nil, 123, nil, 123, nil, nil, nil, 21, nil, + nil, 21, 26, nil, nil, nil, nil, nil, nil, 31, + 41, 26, 26, nil, nil, 41, 41, nil, nil, nil, + 41, nil, nil, 21, nil, nil, nil, nil, 96, 25, + 41, 96, nil, nil, nil, nil, 96, nil, 25, 25, + 22, 41, 123, nil, nil, nil, nil, 22, 22, nil, + nil, nil, nil, nil, nil, nil, 171, nil, 171, nil, + nil, 33, nil, nil, 57, 22, nil, nil, nil, nil, + nil, 22, 9, 22, nil, 9, nil, nil, 41, nil, + 21, nil, nil, nil, nil, 21, 21, nil, nil, 22, + 31, 41, nil, 125, nil, nil, 125, 26, nil, nil, + 65, nil, nil, 171, 26, 171, 173, nil, nil, 173, + 71, 173, nil, 173, nil, 128, nil, 128, nil, 57, + 26, nil, nil, 41, 25, 41, 41, nil, nil, 41, + nil, nil, nil, nil, nil, 41, 126, 126, 126, nil, + nil, 125, nil, nil, 125, nil, 125, 25, 125, nil, + nil, nil, nil, nil, 9, nil, nil, nil, nil, 9, + 9, nil, 128, nil, 128, nil, nil, nil, 41, nil, + nil, nil, 21, nil, nil, nil, nil, 21, nil, nil, + nil, 26, nil, nil, nil, 26, nil, 21, nil, nil, + 26, nil, nil, nil, nil, 171, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 25, nil, + nil, nil, 25, nil, nil, 26, 25, 25, nil, 171, + nil, nil, 169, 169, 169, 173, nil, 173, nil, 173, + nil, 173, 41, 25, nil, 21, 52, nil, nil, 41, + 41, 52, 25, nil, nil, nil, nil, nil, 21, 65, + nil, nil, 128, nil, 128, 65, 128, 41, nil, nil, + 125, 9, 125, 41, 125, 41, 125, nil, 53, 52, + 52, 52, nil, 53, nil, nil, 128, nil, 128, 173, + 128, 41, 21, 21, nil, nil, 21, nil, 126, 126, + 126, 126, 21, 126, nil, nil, nil, nil, nil, nil, + nil, 53, 53, 53, 52, 52, 52, 52, nil, 9, + nil, nil, nil, nil, 125, nil, nil, nil, nil, nil, + 128, 65, 9, 65, nil, 21, 65, 65, nil, nil, + 128, nil, nil, nil, nil, nil, 53, 53, 53, 53, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, 9, 9, 52, 52, + 9, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 126, 126, 126, 126, nil, nil, nil, nil, nil, nil, + nil, 53, nil, nil, nil, nil, 26, nil, 26, 21, + 53, 53, nil, nil, nil, nil, 21, 21, nil, 9, + nil, 126, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 25, 21, 25, nil, nil, nil, nil, + 21, 25, 21, nil, nil, 26, nil, nil, 26, 25, + nil, nil, nil, nil, nil, nil, nil, 169, 169, nil, + 169, 169, nil, 169, 52, 65, nil, nil, nil, nil, + 26, nil, 25, nil, nil, 25, nil, nil, nil, nil, + nil, nil, nil, 9, nil, nil, nil, 52, nil, nil, + 9, 9, nil, nil, nil, nil, 53, 25, nil, nil, + nil, nil, nil, nil, 25, nil, nil, nil, 9, nil, + nil, nil, nil, 26, 9, nil, nil, nil, nil, 53, + nil, nil, nil, nil, nil, nil, nil, 26, nil, nil, + nil, nil, 26, 26, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 65, 52, 65, + nil, 65, 52, nil, 25, nil, 52, 52, nil, 25, + 25, 169, 169, 169, 169, nil, nil, nil, nil, nil, + nil, nil, 25, 52, nil, nil, nil, nil, nil, nil, + 53, nil, 52, 25, 53, nil, nil, 65, 53, 53, + 65, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 169, nil, nil, 65, 53, nil, nil, nil, nil, + nil, nil, nil, nil, 53, nil, nil, nil, nil, 26, + nil, nil, nil, nil, 26, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 26, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 25, nil, nil, 65, + nil, 25, nil, 65, 65, nil, nil, nil, nil, nil, + nil, 25, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 26, nil, nil, nil, nil, nil, nil, 65, + nil, nil, 65, nil, nil, 26, nil, nil, nil, nil, + nil, nil, nil, 25, nil, nil, nil, nil, nil, 25, + nil, nil, 65, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 25, nil, nil, nil, nil, nil, nil, 26, + 26, nil, nil, 26, nil, nil, nil, nil, 65, 26, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 52, nil, 52, 25, 25, nil, nil, + 25, 52, nil, nil, nil, nil, 25, nil, nil, 52, + nil, nil, 26, nil, nil, nil, 26, nil, nil, nil, + nil, nil, nil, nil, nil, 53, nil, 53, nil, nil, + nil, 25, 52, 53, 65, 52, nil, nil, nil, 25, + nil, 53, nil, 25, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 53, nil, nil, + nil, nil, nil, nil, nil, nil, 26, nil, nil, nil, + nil, nil, nil, 26, 26, nil, nil, nil, nil, 53, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 26, nil, 25, nil, 65, nil, 26, nil, 26, + 25, 25, nil, nil, 52, nil, nil, nil, nil, 52, + 52, nil, nil, 65, nil, nil, nil, nil, 25, nil, + nil, nil, 52, nil, 25, nil, 25, nil, nil, nil, + 65, nil, nil, 52, nil, nil, 53, nil, nil, nil, + nil, 53, 53, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 53, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 53, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 53, nil, + nil, nil, nil, 53, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 53, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 52, 32, nil, nil, nil, nil, nil, nil, + nil, nil, 32, 32, 32, 53, nil, nil, nil, nil, + nil, 53, nil, nil, nil, 32, 32, 32, nil, nil, + nil, nil, nil, nil, 53, nil, 52, 52, nil, nil, + 52, nil, 32, 32, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 53, 53, + nil, 52, 53, nil, nil, nil, nil, nil, 53, 52, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 53, nil, nil, nil, nil, nil, nil, + nil, 53, nil, nil, nil, 53, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + 52, 52, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, 52, 53, 52, nil, nil, nil, + nil, nil, 53, 53, nil, nil, nil, nil, nil, nil, + nil, nil, 32, 32, 32, nil, nil, 32, 32, nil, + 53, nil, nil, nil, nil, nil, 53, nil, 53, nil, + nil, nil, nil, 32, nil, nil, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, nil, nil, nil, nil, nil, nil, 32, 32, + nil, nil, nil, nil, nil, nil, nil, 32, nil, nil, + nil, nil, nil, nil, 32, nil, 32, nil, nil, 32, + 32, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 32, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 32, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 32, nil, 32, 32, + 32, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 32, nil, 32, nil, 32, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 32, nil, nil, nil, nil, nil, nil, nil, nil, 32, + 32, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 32, nil, nil, 32, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 32, 32, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 32, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 32, 32, nil, nil, 32, 32, 32, 32, + nil, nil, nil, 32, 32, nil, nil, 32, 32, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 32, nil, nil, 32, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 32, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 32, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 32, nil, 32, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 32, 32, 32, 32, nil, 32, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 32, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 32, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 32, 32, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 32 ] + +racc_goto_pointer = [ + nil, 94, 14, nil, 87, 84, 56, 86, -313, 426, + -497, -559, -681, nil, -368, 33, 127, -36, -167, 75, + 41, 352, 3, -196, -314, 806, 779, -185, -65, 47, + 21, -19, 1893, -25, nil, nil, -3, -196, 50, -229, + -334, 195, -328, nil, 77, 25, 27, -144, nil, 30, + 53, -178, 1126, 1158, -277, 48, -69, 31, nil, nil, + 38, 54, -249, 33, -25, 930, 96, -58, 22, -199, + 68, 23, -319, -261, -433, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 86, 98, -49, nil, -175, -320, + -635, -436, -337, 95, nil, -196, 92, nil, -540, 98, + 113, 113, -352, 116, 113, 112, -515, 113, -516, -368, + -717, -373, -529, -177, -184, -372, -642, -801, -618, -574, + -714, -422, nil, -84, -514, 188, 267, -420, 204, -536, + -145, nil, -503, -656, -734, -720, -329, -583, -121, -430, + -435, -11, -632, -619, -5, nil, -12, -3, -627, -378, + -510, nil, nil, 200, -52, 28, 195, 198, -241, -179, + 198, 198, 200, -275, -269, -257, -275, nil, nil, 449, + -497, 147, -661, 153, -476, -519, nil, -708, -733, nil, + nil, -421 ] + +racc_goto_default = [ + nil, nil, nil, 3, nil, 4, 345, 293, nil, 522, + nil, 817, nil, 290, 291, nil, nil, nil, 11, 12, + 18, 228, 321, nil, nil, 226, 227, nil, nil, 17, + nil, 440, 21, 22, 23, 24, nil, 645, nil, nil, + nil, 310, nil, 25, 411, 32, nil, nil, 34, 37, + 36, nil, 223, 224, 357, nil, 131, 419, 130, 133, + 77, 78, nil, 92, 46, 282, nil, 785, 412, nil, + 413, 424, 599, 486, 280, 266, 47, 48, 49, 50, + 51, 52, 53, 54, 55, nil, 267, 61, nil, nil, + nil, nil, nil, nil, 69, nil, 537, 70, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 808, 673, nil, + 809, 910, 756, 661, nil, 662, nil, nil, 663, nil, + 665, 615, nil, nil, nil, 671, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 423, nil, nil, nil, nil, + nil, 76, 79, 80, nil, nil, nil, nil, nil, 566, + nil, nil, nil, nil, nil, nil, 877, 717, 660, nil, + 664, 885, 676, 678, 679, 768, 682, 683, 769, 686, + 689, 285 ] + +racc_reduce_table = [ + 0, 0, :racc_error, + 1, 145, :_reduce_none, + 2, 146, :_reduce_2, + 0, 147, :_reduce_3, + 1, 147, :_reduce_4, + 3, 147, :_reduce_5, + 2, 147, :_reduce_6, + 1, 149, :_reduce_none, + 4, 149, :_reduce_8, + 4, 152, :_reduce_9, + 2, 153, :_reduce_10, + 0, 157, :_reduce_11, + 1, 157, :_reduce_12, + 3, 157, :_reduce_13, + 2, 157, :_reduce_14, + 1, 158, :_reduce_none, + 4, 158, :_reduce_16, + 0, 174, :_reduce_17, + 4, 151, :_reduce_18, + 3, 151, :_reduce_19, + 3, 151, :_reduce_20, + 3, 151, :_reduce_21, + 2, 151, :_reduce_22, + 3, 151, :_reduce_23, + 3, 151, :_reduce_24, + 3, 151, :_reduce_25, + 3, 151, :_reduce_26, + 3, 151, :_reduce_27, + 4, 151, :_reduce_28, + 1, 151, :_reduce_none, + 3, 151, :_reduce_30, + 3, 151, :_reduce_31, + 6, 151, :_reduce_32, + 5, 151, :_reduce_33, + 5, 151, :_reduce_34, + 5, 151, :_reduce_35, + 5, 151, :_reduce_36, + 3, 151, :_reduce_37, + 3, 151, :_reduce_38, + 3, 151, :_reduce_39, + 1, 151, :_reduce_none, + 3, 162, :_reduce_41, + 3, 162, :_reduce_42, + 1, 173, :_reduce_none, + 3, 173, :_reduce_44, + 3, 173, :_reduce_45, + 3, 173, :_reduce_46, + 2, 173, :_reduce_47, + 1, 173, :_reduce_none, + 1, 161, :_reduce_none, + 1, 164, :_reduce_none, + 1, 164, :_reduce_none, + 1, 178, :_reduce_none, + 4, 178, :_reduce_53, + 0, 186, :_reduce_54, + 5, 183, :_reduce_55, + 1, 185, :_reduce_none, + 2, 177, :_reduce_57, + 3, 177, :_reduce_58, + 4, 177, :_reduce_59, + 5, 177, :_reduce_60, + 4, 177, :_reduce_61, + 5, 177, :_reduce_62, + 2, 177, :_reduce_63, + 2, 177, :_reduce_64, + 2, 177, :_reduce_65, + 2, 177, :_reduce_66, + 2, 177, :_reduce_67, + 1, 163, :_reduce_68, + 3, 163, :_reduce_69, + 1, 190, :_reduce_70, + 3, 190, :_reduce_71, + 1, 189, :_reduce_none, + 2, 189, :_reduce_73, + 3, 189, :_reduce_74, + 5, 189, :_reduce_75, + 2, 189, :_reduce_76, + 4, 189, :_reduce_77, + 2, 189, :_reduce_78, + 4, 189, :_reduce_79, + 1, 189, :_reduce_80, + 3, 189, :_reduce_81, + 1, 193, :_reduce_none, + 3, 193, :_reduce_83, + 2, 192, :_reduce_84, + 3, 192, :_reduce_85, + 1, 195, :_reduce_86, + 3, 195, :_reduce_87, + 1, 194, :_reduce_88, + 1, 194, :_reduce_89, + 4, 194, :_reduce_90, + 3, 194, :_reduce_91, + 3, 194, :_reduce_92, + 3, 194, :_reduce_93, + 3, 194, :_reduce_94, + 2, 194, :_reduce_95, + 1, 194, :_reduce_96, + 1, 170, :_reduce_97, + 1, 170, :_reduce_98, + 4, 170, :_reduce_99, + 3, 170, :_reduce_100, + 3, 170, :_reduce_101, + 3, 170, :_reduce_102, + 3, 170, :_reduce_103, + 2, 170, :_reduce_104, + 1, 170, :_reduce_105, + 1, 198, :_reduce_106, + 1, 198, :_reduce_none, + 2, 199, :_reduce_108, + 1, 199, :_reduce_109, + 3, 199, :_reduce_110, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 203, :_reduce_116, + 1, 203, :_reduce_none, + 1, 159, :_reduce_none, + 1, 159, :_reduce_none, + 1, 160, :_reduce_120, + 0, 206, :_reduce_121, + 4, 160, :_reduce_122, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 3, 176, :_reduce_194, + 5, 176, :_reduce_195, + 3, 176, :_reduce_196, + 5, 176, :_reduce_197, + 6, 176, :_reduce_198, + 5, 176, :_reduce_199, + 5, 176, :_reduce_200, + 5, 176, :_reduce_201, + 5, 176, :_reduce_202, + 4, 176, :_reduce_203, + 3, 176, :_reduce_204, + 3, 176, :_reduce_205, + 3, 176, :_reduce_206, + 3, 176, :_reduce_207, + 3, 176, :_reduce_208, + 3, 176, :_reduce_209, + 3, 176, :_reduce_210, + 3, 176, :_reduce_211, + 3, 176, :_reduce_212, + 4, 176, :_reduce_213, + 2, 176, :_reduce_214, + 2, 176, :_reduce_215, + 3, 176, :_reduce_216, + 3, 176, :_reduce_217, + 3, 176, :_reduce_218, + 3, 176, :_reduce_219, + 3, 176, :_reduce_220, + 3, 176, :_reduce_221, + 3, 176, :_reduce_222, + 3, 176, :_reduce_223, + 3, 176, :_reduce_224, + 3, 176, :_reduce_225, + 3, 176, :_reduce_226, + 3, 176, :_reduce_227, + 3, 176, :_reduce_228, + 2, 176, :_reduce_229, + 2, 176, :_reduce_230, + 3, 176, :_reduce_231, + 3, 176, :_reduce_232, + 3, 176, :_reduce_233, + 3, 176, :_reduce_234, + 3, 176, :_reduce_235, + 6, 176, :_reduce_236, + 1, 176, :_reduce_none, + 1, 209, :_reduce_none, + 1, 210, :_reduce_none, + 2, 210, :_reduce_none, + 4, 210, :_reduce_241, + 2, 210, :_reduce_242, + 3, 215, :_reduce_243, + 0, 216, :_reduce_244, + 1, 216, :_reduce_none, + 0, 167, :_reduce_246, + 1, 167, :_reduce_none, + 2, 167, :_reduce_none, + 4, 167, :_reduce_249, + 2, 167, :_reduce_250, + 1, 188, :_reduce_251, + 2, 188, :_reduce_252, + 2, 188, :_reduce_253, + 4, 188, :_reduce_254, + 1, 188, :_reduce_255, + 0, 219, :_reduce_256, + 2, 182, :_reduce_257, + 2, 218, :_reduce_258, + 2, 217, :_reduce_259, + 0, 217, :_reduce_260, + 1, 212, :_reduce_261, + 2, 212, :_reduce_262, + 3, 212, :_reduce_263, + 4, 212, :_reduce_264, + 1, 172, :_reduce_265, + 1, 172, :_reduce_none, + 3, 171, :_reduce_267, + 4, 171, :_reduce_268, + 2, 171, :_reduce_269, + 1, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 208, :_reduce_280, + 0, 244, :_reduce_281, + 4, 208, :_reduce_282, + 0, 245, :_reduce_283, + 0, 246, :_reduce_284, + 6, 208, :_reduce_285, + 0, 247, :_reduce_286, + 4, 208, :_reduce_287, + 3, 208, :_reduce_288, + 3, 208, :_reduce_289, + 2, 208, :_reduce_290, + 3, 208, :_reduce_291, + 3, 208, :_reduce_292, + 1, 208, :_reduce_293, + 4, 208, :_reduce_294, + 3, 208, :_reduce_295, + 1, 208, :_reduce_296, + 5, 208, :_reduce_297, + 4, 208, :_reduce_298, + 3, 208, :_reduce_299, + 2, 208, :_reduce_300, + 1, 208, :_reduce_none, + 2, 208, :_reduce_302, + 0, 248, :_reduce_303, + 3, 208, :_reduce_304, + 6, 208, :_reduce_305, + 6, 208, :_reduce_306, + 0, 249, :_reduce_307, + 0, 250, :_reduce_308, + 7, 208, :_reduce_309, + 0, 251, :_reduce_310, + 0, 252, :_reduce_311, + 7, 208, :_reduce_312, + 5, 208, :_reduce_313, + 4, 208, :_reduce_314, + 0, 253, :_reduce_315, + 0, 254, :_reduce_316, + 9, 208, :_reduce_317, + 0, 255, :_reduce_318, + 6, 208, :_reduce_319, + 0, 256, :_reduce_320, + 7, 208, :_reduce_321, + 0, 257, :_reduce_322, + 5, 208, :_reduce_323, + 0, 258, :_reduce_324, + 6, 208, :_reduce_325, + 0, 259, :_reduce_326, + 0, 260, :_reduce_327, + 9, 208, :_reduce_328, + 1, 208, :_reduce_329, + 1, 208, :_reduce_330, + 1, 208, :_reduce_331, + 1, 208, :_reduce_332, + 1, 166, :_reduce_none, + 1, 238, :_reduce_334, + 1, 241, :_reduce_335, + 1, 233, :_reduce_none, + 1, 233, :_reduce_none, + 2, 233, :_reduce_338, + 1, 235, :_reduce_none, + 1, 235, :_reduce_none, + 1, 234, :_reduce_none, + 5, 234, :_reduce_342, + 1, 155, :_reduce_none, + 2, 155, :_reduce_344, + 1, 237, :_reduce_none, + 1, 237, :_reduce_none, + 1, 261, :_reduce_347, + 3, 261, :_reduce_348, + 1, 264, :_reduce_349, + 3, 264, :_reduce_350, + 1, 263, :_reduce_none, + 4, 263, :_reduce_352, + 6, 263, :_reduce_353, + 3, 263, :_reduce_354, + 5, 263, :_reduce_355, + 2, 263, :_reduce_356, + 4, 263, :_reduce_357, + 1, 263, :_reduce_358, + 3, 263, :_reduce_359, + 4, 265, :_reduce_360, + 2, 265, :_reduce_361, + 2, 265, :_reduce_362, + 1, 265, :_reduce_363, + 2, 270, :_reduce_364, + 0, 270, :_reduce_365, + 6, 271, :_reduce_366, + 8, 271, :_reduce_367, + 4, 271, :_reduce_368, + 6, 271, :_reduce_369, + 4, 271, :_reduce_370, + 2, 271, :_reduce_none, + 6, 271, :_reduce_372, + 2, 271, :_reduce_373, + 4, 271, :_reduce_374, + 6, 271, :_reduce_375, + 2, 271, :_reduce_376, + 4, 271, :_reduce_377, + 2, 271, :_reduce_378, + 4, 271, :_reduce_379, + 1, 271, :_reduce_none, + 0, 184, :_reduce_381, + 1, 184, :_reduce_382, + 3, 275, :_reduce_383, + 1, 275, :_reduce_384, + 4, 275, :_reduce_385, + 1, 276, :_reduce_386, + 4, 276, :_reduce_387, + 1, 277, :_reduce_388, + 3, 277, :_reduce_389, + 1, 278, :_reduce_390, + 1, 278, :_reduce_none, + 0, 282, :_reduce_392, + 0, 283, :_reduce_393, + 4, 232, :_reduce_394, + 4, 280, :_reduce_395, + 1, 280, :_reduce_396, + 0, 286, :_reduce_397, + 4, 281, :_reduce_398, + 0, 287, :_reduce_399, + 4, 281, :_reduce_400, + 0, 288, :_reduce_401, + 5, 285, :_reduce_402, + 2, 179, :_reduce_403, + 4, 179, :_reduce_404, + 5, 179, :_reduce_405, + 5, 179, :_reduce_406, + 2, 231, :_reduce_407, + 4, 231, :_reduce_408, + 4, 231, :_reduce_409, + 3, 231, :_reduce_410, + 3, 231, :_reduce_411, + 3, 231, :_reduce_412, + 2, 231, :_reduce_413, + 1, 231, :_reduce_414, + 4, 231, :_reduce_415, + 0, 290, :_reduce_416, + 5, 230, :_reduce_417, + 0, 291, :_reduce_418, + 5, 230, :_reduce_419, + 5, 236, :_reduce_420, + 1, 292, :_reduce_421, + 1, 292, :_reduce_none, + 6, 154, :_reduce_423, + 0, 154, :_reduce_424, + 1, 293, :_reduce_425, + 1, 293, :_reduce_none, + 1, 293, :_reduce_none, + 2, 294, :_reduce_428, + 1, 294, :_reduce_none, + 2, 156, :_reduce_430, + 1, 156, :_reduce_none, + 1, 220, :_reduce_none, + 1, 220, :_reduce_none, + 1, 220, :_reduce_none, + 1, 221, :_reduce_435, + 1, 296, :_reduce_436, + 2, 296, :_reduce_437, + 3, 297, :_reduce_438, + 1, 297, :_reduce_439, + 1, 297, :_reduce_440, + 3, 222, :_reduce_441, + 4, 223, :_reduce_442, + 3, 224, :_reduce_443, + 0, 301, :_reduce_444, + 3, 301, :_reduce_445, + 1, 302, :_reduce_446, + 2, 302, :_reduce_447, + 3, 226, :_reduce_448, + 0, 304, :_reduce_449, + 3, 304, :_reduce_450, + 3, 225, :_reduce_451, + 3, 227, :_reduce_452, + 0, 305, :_reduce_453, + 3, 305, :_reduce_454, + 0, 306, :_reduce_455, + 3, 306, :_reduce_456, + 0, 298, :_reduce_457, + 2, 298, :_reduce_458, + 0, 299, :_reduce_459, + 2, 299, :_reduce_460, + 0, 300, :_reduce_461, + 2, 300, :_reduce_462, + 1, 303, :_reduce_463, + 2, 303, :_reduce_464, + 0, 308, :_reduce_465, + 4, 303, :_reduce_466, + 1, 307, :_reduce_467, + 1, 307, :_reduce_468, + 1, 307, :_reduce_469, + 1, 307, :_reduce_none, + 1, 204, :_reduce_471, + 3, 205, :_reduce_472, + 1, 295, :_reduce_473, + 2, 295, :_reduce_474, + 1, 207, :_reduce_475, + 1, 207, :_reduce_476, + 1, 207, :_reduce_477, + 1, 207, :_reduce_478, + 1, 196, :_reduce_479, + 1, 196, :_reduce_480, + 1, 196, :_reduce_481, + 1, 196, :_reduce_482, + 1, 196, :_reduce_483, + 1, 197, :_reduce_484, + 1, 197, :_reduce_485, + 1, 197, :_reduce_486, + 1, 197, :_reduce_487, + 1, 197, :_reduce_488, + 1, 197, :_reduce_489, + 1, 197, :_reduce_490, + 1, 228, :_reduce_491, + 1, 228, :_reduce_492, + 1, 165, :_reduce_493, + 1, 165, :_reduce_494, + 1, 169, :_reduce_495, + 1, 169, :_reduce_496, + 1, 239, :_reduce_497, + 0, 309, :_reduce_498, + 4, 239, :_reduce_499, + 2, 239, :_reduce_500, + 3, 242, :_reduce_501, + 0, 311, :_reduce_502, + 3, 242, :_reduce_503, + 4, 310, :_reduce_504, + 2, 310, :_reduce_505, + 2, 310, :_reduce_506, + 1, 310, :_reduce_507, + 2, 313, :_reduce_508, + 0, 313, :_reduce_509, + 6, 284, :_reduce_510, + 8, 284, :_reduce_511, + 4, 284, :_reduce_512, + 6, 284, :_reduce_513, + 4, 284, :_reduce_514, + 6, 284, :_reduce_515, + 2, 284, :_reduce_516, + 4, 284, :_reduce_517, + 6, 284, :_reduce_518, + 2, 284, :_reduce_519, + 4, 284, :_reduce_520, + 2, 284, :_reduce_521, + 4, 284, :_reduce_522, + 1, 284, :_reduce_523, + 0, 284, :_reduce_524, + 1, 279, :_reduce_525, + 1, 279, :_reduce_526, + 1, 279, :_reduce_527, + 1, 279, :_reduce_528, + 1, 262, :_reduce_none, + 1, 262, :_reduce_530, + 1, 315, :_reduce_531, + 1, 316, :_reduce_532, + 3, 316, :_reduce_533, + 1, 272, :_reduce_534, + 3, 272, :_reduce_535, + 1, 317, :_reduce_536, + 2, 318, :_reduce_537, + 1, 318, :_reduce_538, + 2, 319, :_reduce_539, + 1, 319, :_reduce_540, + 1, 266, :_reduce_541, + 3, 266, :_reduce_542, + 1, 312, :_reduce_543, + 3, 312, :_reduce_544, + 1, 320, :_reduce_none, + 1, 320, :_reduce_none, + 2, 267, :_reduce_547, + 1, 267, :_reduce_548, + 3, 321, :_reduce_549, + 3, 322, :_reduce_550, + 1, 273, :_reduce_551, + 3, 273, :_reduce_552, + 1, 314, :_reduce_553, + 3, 314, :_reduce_554, + 1, 323, :_reduce_none, + 1, 323, :_reduce_none, + 2, 274, :_reduce_557, + 1, 274, :_reduce_558, + 1, 324, :_reduce_none, + 1, 324, :_reduce_none, + 2, 269, :_reduce_561, + 2, 268, :_reduce_562, + 0, 268, :_reduce_563, + 1, 243, :_reduce_none, + 3, 243, :_reduce_565, + 0, 229, :_reduce_566, + 2, 229, :_reduce_none, + 1, 214, :_reduce_568, + 3, 214, :_reduce_569, + 3, 325, :_reduce_570, + 2, 325, :_reduce_571, + 4, 325, :_reduce_572, + 2, 325, :_reduce_573, + 1, 187, :_reduce_none, + 1, 187, :_reduce_none, + 1, 187, :_reduce_none, + 1, 181, :_reduce_none, + 1, 181, :_reduce_none, + 1, 181, :_reduce_none, + 1, 181, :_reduce_none, + 1, 289, :_reduce_none, + 1, 289, :_reduce_none, + 1, 289, :_reduce_none, + 1, 180, :_reduce_none, + 1, 180, :_reduce_none, + 0, 148, :_reduce_none, + 1, 148, :_reduce_none, + 0, 175, :_reduce_none, + 1, 175, :_reduce_none, + 2, 191, :_reduce_590, + 2, 168, :_reduce_591, + 0, 213, :_reduce_none, + 1, 213, :_reduce_none, + 1, 213, :_reduce_none, + 1, 240, :_reduce_595, + 1, 240, :_reduce_none, + 1, 150, :_reduce_none, + 2, 150, :_reduce_none, + 0, 211, :_reduce_599 ] + +racc_reduce_n = 600 + +racc_shift_n = 1027 + +racc_token_table = { + false => 0, + :error => 1, + :kCLASS => 2, + :kMODULE => 3, + :kDEF => 4, + :kUNDEF => 5, + :kBEGIN => 6, + :kRESCUE => 7, + :kENSURE => 8, + :kEND => 9, + :kIF => 10, + :kUNLESS => 11, + :kTHEN => 12, + :kELSIF => 13, + :kELSE => 14, + :kCASE => 15, + :kWHEN => 16, + :kWHILE => 17, + :kUNTIL => 18, + :kFOR => 19, + :kBREAK => 20, + :kNEXT => 21, + :kREDO => 22, + :kRETRY => 23, + :kIN => 24, + :kDO => 25, + :kDO_COND => 26, + :kDO_BLOCK => 27, + :kDO_LAMBDA => 28, + :kRETURN => 29, + :kYIELD => 30, + :kSUPER => 31, + :kSELF => 32, + :kNIL => 33, + :kTRUE => 34, + :kFALSE => 35, + :kAND => 36, + :kOR => 37, + :kNOT => 38, + :kIF_MOD => 39, + :kUNLESS_MOD => 40, + :kWHILE_MOD => 41, + :kUNTIL_MOD => 42, + :kRESCUE_MOD => 43, + :kALIAS => 44, + :kDEFINED => 45, + :klBEGIN => 46, + :klEND => 47, + :k__LINE__ => 48, + :k__FILE__ => 49, + :k__ENCODING__ => 50, + :tIDENTIFIER => 51, + :tFID => 52, + :tGVAR => 53, + :tIVAR => 54, + :tCONSTANT => 55, + :tLABEL => 56, + :tCVAR => 57, + :tNTH_REF => 58, + :tBACK_REF => 59, + :tSTRING_CONTENT => 60, + :tINTEGER => 61, + :tFLOAT => 62, + :tUPLUS => 63, + :tUMINUS => 64, + :tUNARY_NUM => 65, + :tPOW => 66, + :tCMP => 67, + :tEQ => 68, + :tEQQ => 69, + :tNEQ => 70, + :tGEQ => 71, + :tLEQ => 72, + :tANDOP => 73, + :tOROP => 74, + :tMATCH => 75, + :tNMATCH => 76, + :tDOT => 77, + :tDOT2 => 78, + :tDOT3 => 79, + :tAREF => 80, + :tASET => 81, + :tLSHFT => 82, + :tRSHFT => 83, + :tCOLON2 => 84, + :tCOLON3 => 85, + :tOP_ASGN => 86, + :tASSOC => 87, + :tLPAREN => 88, + :tLPAREN2 => 89, + :tRPAREN => 90, + :tLPAREN_ARG => 91, + :tLBRACK => 92, + :tLBRACK2 => 93, + :tRBRACK => 94, + :tLBRACE => 95, + :tLBRACE_ARG => 96, + :tSTAR => 97, + :tSTAR2 => 98, + :tAMPER => 99, + :tAMPER2 => 100, + :tTILDE => 101, + :tPERCENT => 102, + :tDIVIDE => 103, + :tDSTAR => 104, + :tPLUS => 105, + :tMINUS => 106, + :tLT => 107, + :tGT => 108, + :tPIPE => 109, + :tBANG => 110, + :tCARET => 111, + :tLCURLY => 112, + :tRCURLY => 113, + :tBACK_REF2 => 114, + :tSYMBEG => 115, + :tSTRING_BEG => 116, + :tXSTRING_BEG => 117, + :tREGEXP_BEG => 118, + :tREGEXP_OPT => 119, + :tWORDS_BEG => 120, + :tQWORDS_BEG => 121, + :tSYMBOLS_BEG => 122, + :tQSYMBOLS_BEG => 123, + :tSTRING_DBEG => 124, + :tSTRING_DVAR => 125, + :tSTRING_END => 126, + :tSTRING_DEND => 127, + :tSTRING => 128, + :tSYMBOL => 129, + :tNL => 130, + :tEH => 131, + :tCOLON => 132, + :tCOMMA => 133, + :tSPACE => 134, + :tSEMI => 135, + :tLAMBDA => 136, + :tLAMBEG => 137, + :tCHARACTER => 138, + :tRATIONAL => 139, + :tIMAGINARY => 140, + :tLABEL_END => 141, + :tEQL => 142, + :tLOWEST => 143 } + +racc_nt_base = 144 + +racc_use_result_var = true + +Racc_arg = [ + racc_action_table, + racc_action_check, + racc_action_default, + racc_action_pointer, + racc_goto_table, + racc_goto_check, + racc_goto_default, + racc_goto_pointer, + racc_nt_base, + racc_reduce_table, + racc_token_table, + racc_shift_n, + racc_reduce_n, + racc_use_result_var ] +Ractor.make_shareable(Racc_arg) if defined?(Ractor) + +Racc_token_to_s_table = [ + "$end", + "error", + "kCLASS", + "kMODULE", + "kDEF", + "kUNDEF", + "kBEGIN", + "kRESCUE", + "kENSURE", + "kEND", + "kIF", + "kUNLESS", + "kTHEN", + "kELSIF", + "kELSE", + "kCASE", + "kWHEN", + "kWHILE", + "kUNTIL", + "kFOR", + "kBREAK", + "kNEXT", + "kREDO", + "kRETRY", + "kIN", + "kDO", + "kDO_COND", + "kDO_BLOCK", + "kDO_LAMBDA", + "kRETURN", + "kYIELD", + "kSUPER", + "kSELF", + "kNIL", + "kTRUE", + "kFALSE", + "kAND", + "kOR", + "kNOT", + "kIF_MOD", + "kUNLESS_MOD", + "kWHILE_MOD", + "kUNTIL_MOD", + "kRESCUE_MOD", + "kALIAS", + "kDEFINED", + "klBEGIN", + "klEND", + "k__LINE__", + "k__FILE__", + "k__ENCODING__", + "tIDENTIFIER", + "tFID", + "tGVAR", + "tIVAR", + "tCONSTANT", + "tLABEL", + "tCVAR", + "tNTH_REF", + "tBACK_REF", + "tSTRING_CONTENT", + "tINTEGER", + "tFLOAT", + "tUPLUS", + "tUMINUS", + "tUNARY_NUM", + "tPOW", + "tCMP", + "tEQ", + "tEQQ", + "tNEQ", + "tGEQ", + "tLEQ", + "tANDOP", + "tOROP", + "tMATCH", + "tNMATCH", + "tDOT", + "tDOT2", + "tDOT3", + "tAREF", + "tASET", + "tLSHFT", + "tRSHFT", + "tCOLON2", + "tCOLON3", + "tOP_ASGN", + "tASSOC", + "tLPAREN", + "tLPAREN2", + "tRPAREN", + "tLPAREN_ARG", + "tLBRACK", + "tLBRACK2", + "tRBRACK", + "tLBRACE", + "tLBRACE_ARG", + "tSTAR", + "tSTAR2", + "tAMPER", + "tAMPER2", + "tTILDE", + "tPERCENT", + "tDIVIDE", + "tDSTAR", + "tPLUS", + "tMINUS", + "tLT", + "tGT", + "tPIPE", + "tBANG", + "tCARET", + "tLCURLY", + "tRCURLY", + "tBACK_REF2", + "tSYMBEG", + "tSTRING_BEG", + "tXSTRING_BEG", + "tREGEXP_BEG", + "tREGEXP_OPT", + "tWORDS_BEG", + "tQWORDS_BEG", + "tSYMBOLS_BEG", + "tQSYMBOLS_BEG", + "tSTRING_DBEG", + "tSTRING_DVAR", + "tSTRING_END", + "tSTRING_DEND", + "tSTRING", + "tSYMBOL", + "tNL", + "tEH", + "tCOLON", + "tCOMMA", + "tSPACE", + "tSEMI", + "tLAMBDA", + "tLAMBEG", + "tCHARACTER", + "tRATIONAL", + "tIMAGINARY", + "tLABEL_END", + "tEQL", + "tLOWEST", + "$start", + "program", + "top_compstmt", + "top_stmts", + "opt_terms", + "top_stmt", + "terms", + "stmt", + "bodystmt", + "compstmt", + "opt_rescue", + "opt_else", + "opt_ensure", + "stmts", + "stmt_or_begin", + "fitem", + "undef_list", + "expr_value", + "command_asgn", + "mlhs", + "command_call", + "var_lhs", + "primary_value", + "opt_call_args", + "rbracket", + "backref", + "lhs", + "mrhs", + "mrhs_arg", + "expr", + "@1", + "opt_nl", + "arg", + "command", + "block_command", + "block_call", + "dot_or_colon", + "operation2", + "command_args", + "cmd_brace_block", + "opt_block_param", + "fcall", + "@2", + "operation", + "call_args", + "mlhs_basic", + "mlhs_inner", + "rparen", + "mlhs_head", + "mlhs_item", + "mlhs_node", + "mlhs_post", + "user_variable", + "keyword_variable", + "cname", + "cpath", + "fname", + "op", + "reswords", + "fsym", + "symbol", + "dsym", + "@3", + "simple_numeric", + "primary", + "arg_value", + "aref_args", + "none", + "args", + "trailer", + "assocs", + "paren_args", + "opt_paren_args", + "opt_block_arg", + "block_arg", + "@4", + "literal", + "strings", + "xstring", + "regexp", + "words", + "qwords", + "symbols", + "qsymbols", + "var_ref", + "assoc_list", + "brace_block", + "method_call", + "lambda", + "then", + "if_tail", + "do", + "case_body", + "for_var", + "k_class", + "superclass", + "term", + "k_module", + "f_arglist", + "singleton", + "@5", + "@6", + "@7", + "@8", + "@9", + "@10", + "@11", + "@12", + "@13", + "@14", + "@15", + "@16", + "@17", + "@18", + "@19", + "@20", + "@21", + "f_marg", + "f_norm_arg", + "f_margs", + "f_marg_list", + "block_args_tail", + "f_block_kwarg", + "f_kwrest", + "opt_f_block_arg", + "f_block_arg", + "opt_block_args_tail", + "block_param", + "f_arg", + "f_block_optarg", + "f_rest_arg", + "block_param_def", + "opt_bv_decl", + "bv_decls", + "bvar", + "f_bad_arg", + "f_larglist", + "lambda_body", + "@22", + "@23", + "f_args", + "do_block", + "@24", + "@25", + "@26", + "operation3", + "@27", + "@28", + "cases", + "exc_list", + "exc_var", + "numeric", + "string", + "string1", + "string_contents", + "xstring_contents", + "regexp_contents", + "word_list", + "word", + "string_content", + "symbol_list", + "qword_list", + "qsym_list", + "string_dvar", + "@29", + "@30", + "args_tail", + "@31", + "f_kwarg", + "opt_args_tail", + "f_optarg", + "f_arg_asgn", + "f_arg_item", + "f_label", + "f_kw", + "f_block_kw", + "kwrest_mark", + "f_opt", + "f_block_opt", + "restarg_mark", + "blkarg_mark", + "assoc" ] +Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) + +Racc_debug_parser = false + +##### State transition tables end ##### + +# reduce 0 omitted + +# reduce 1 omitted + +def _reduce_2(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_3(val, _values, result) + result = [] + + result +end + +def _reduce_4(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_5(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_6(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 7 omitted + +def _reduce_8(val, _values, result) + result = @builder.preexe(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_9(val, _values, result) + rescue_bodies = val[1] + else_t, else_ = val[2] + ensure_t, ensure_ = val[3] + + if rescue_bodies.empty? && !else_t.nil? + diagnostic :warning, :useless_else, nil, else_t + end + + result = @builder.begin_body(val[0], + rescue_bodies, + else_t, else_, + ensure_t, ensure_) + + result +end + +def _reduce_10(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_11(val, _values, result) + result = [] + + result +end + +def _reduce_12(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_13(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_14(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 15 omitted + +def _reduce_16(val, _values, result) + diagnostic :error, :begin_in_method, nil, val[0] + + result +end + +def _reduce_17(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_18(val, _values, result) + result = @builder.alias(val[0], val[1], val[3]) + + result +end + +def _reduce_19(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.gvar(val[2])) + + result +end + +def _reduce_20(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.back_ref(val[2])) + + result +end + +def _reduce_21(val, _values, result) + diagnostic :error, :nth_ref_alias, nil, val[2] + + result +end + +def _reduce_22(val, _values, result) + result = @builder.undef_method(val[0], val[1]) + + result +end + +def _reduce_23(val, _values, result) + result = @builder.condition_mod(val[0], nil, + val[1], val[2]) + + result +end + +def _reduce_24(val, _values, result) + result = @builder.condition_mod(nil, val[0], + val[1], val[2]) + + result +end + +def _reduce_25(val, _values, result) + result = @builder.loop_mod(:while, val[0], val[1], val[2]) + + result +end + +def _reduce_26(val, _values, result) + result = @builder.loop_mod(:until, val[0], val[1], val[2]) + + result +end + +def _reduce_27(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_28(val, _values, result) + result = @builder.postexe(val[0], val[1], val[2], val[3]) + + result +end + +# reduce 29 omitted + +def _reduce_30(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_31(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_32(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_33(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_34(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_35(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_36(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_37(val, _values, result) + @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_38(val, _values, result) + result = @builder.assign(val[0], val[1], + @builder.array(nil, val[2], nil)) + + result +end + +def _reduce_39(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +# reduce 40 omitted + +def _reduce_41(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_42(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +# reduce 43 omitted + +def _reduce_44(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_45(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_46(val, _values, result) + result = @builder.not_op(val[0], nil, val[2], nil) + + result +end + +def _reduce_47(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +# reduce 48 omitted + +# reduce 49 omitted + +# reduce 50 omitted + +# reduce 51 omitted + +# reduce 52 omitted + +def _reduce_53(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_54(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_55(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +# reduce 56 omitted + +def _reduce_57(val, _values, result) + result = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + result +end + +def _reduce_58(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + begin_t, args, body, end_t = val[2] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_59(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_60(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_61(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_62(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_63(val, _values, result) + result = @builder.keyword_cmd(:super, val[0], + nil, val[1], nil) + + result +end + +def _reduce_64(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], + nil, val[1], nil) + + result +end + +def _reduce_65(val, _values, result) + result = @builder.keyword_cmd(:return, val[0], + nil, val[1], nil) + + result +end + +def _reduce_66(val, _values, result) + result = @builder.keyword_cmd(:break, val[0], + nil, val[1], nil) + + result +end + +def _reduce_67(val, _values, result) + result = @builder.keyword_cmd(:next, val[0], + nil, val[1], nil) + + result +end + +def _reduce_68(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_69(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_70(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_71(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +# reduce 72 omitted + +def _reduce_73(val, _values, result) + result = val[0]. + push(val[1]) + + result +end + +def _reduce_74(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])) + + result +end + +def _reduce_75(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])). + concat(val[4]) + + result +end + +def _reduce_76(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])) + + result +end + +def _reduce_77(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])). + concat(val[3]) + + result +end + +def _reduce_78(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_79(val, _values, result) + result = [ @builder.splat(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_80(val, _values, result) + result = [ @builder.splat(val[0]) ] + + result +end + +def _reduce_81(val, _values, result) + result = [ @builder.splat(val[0]), + *val[2] ] + + result +end + +# reduce 82 omitted + +def _reduce_83(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_84(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_85(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_86(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_87(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_88(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_89(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_90(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_91(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_92(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_93(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_94(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_95(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_96(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_97(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_98(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_99(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_100(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_101(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_102(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_103(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_104(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_105(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_106(val, _values, result) + diagnostic :error, :module_name_const, nil, val[0] + + result +end + +# reduce 107 omitted + +def _reduce_108(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_109(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_110(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +# reduce 111 omitted + +# reduce 112 omitted + +# reduce 113 omitted + +# reduce 114 omitted + +# reduce 115 omitted + +def _reduce_116(val, _values, result) + result = @builder.symbol_internal(val[0]) + + result +end + +# reduce 117 omitted + +# reduce 118 omitted + +# reduce 119 omitted + +def _reduce_120(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_121(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_122(val, _values, result) + result = val[0] << val[3] + + result +end + +# reduce 123 omitted + +# reduce 124 omitted + +# reduce 125 omitted + +# reduce 126 omitted + +# reduce 127 omitted + +# reduce 128 omitted + +# reduce 129 omitted + +# reduce 130 omitted + +# reduce 131 omitted + +# reduce 132 omitted + +# reduce 133 omitted + +# reduce 134 omitted + +# reduce 135 omitted + +# reduce 136 omitted + +# reduce 137 omitted + +# reduce 138 omitted + +# reduce 139 omitted + +# reduce 140 omitted + +# reduce 141 omitted + +# reduce 142 omitted + +# reduce 143 omitted + +# reduce 144 omitted + +# reduce 145 omitted + +# reduce 146 omitted + +# reduce 147 omitted + +# reduce 148 omitted + +# reduce 149 omitted + +# reduce 150 omitted + +# reduce 151 omitted + +# reduce 152 omitted + +# reduce 153 omitted + +# reduce 154 omitted + +# reduce 155 omitted + +# reduce 156 omitted + +# reduce 157 omitted + +# reduce 158 omitted + +# reduce 159 omitted + +# reduce 160 omitted + +# reduce 161 omitted + +# reduce 162 omitted + +# reduce 163 omitted + +# reduce 164 omitted + +# reduce 165 omitted + +# reduce 166 omitted + +# reduce 167 omitted + +# reduce 168 omitted + +# reduce 169 omitted + +# reduce 170 omitted + +# reduce 171 omitted + +# reduce 172 omitted + +# reduce 173 omitted + +# reduce 174 omitted + +# reduce 175 omitted + +# reduce 176 omitted + +# reduce 177 omitted + +# reduce 178 omitted + +# reduce 179 omitted + +# reduce 180 omitted + +# reduce 181 omitted + +# reduce 182 omitted + +# reduce 183 omitted + +# reduce 184 omitted + +# reduce 185 omitted + +# reduce 186 omitted + +# reduce 187 omitted + +# reduce 188 omitted + +# reduce 189 omitted + +# reduce 190 omitted + +# reduce 191 omitted + +# reduce 192 omitted + +# reduce 193 omitted + +def _reduce_194(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_195(val, _values, result) + rescue_body = @builder.rescue_body(val[3], + nil, nil, nil, + nil, val[4]) + + rescue_ = @builder.begin_body(val[2], [ rescue_body ]) + + result = @builder.assign(val[0], val[1], rescue_) + + result +end + +def _reduce_196(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_197(val, _values, result) + rescue_body = @builder.rescue_body(val[3], + nil, nil, nil, + nil, val[4]) + + rescue_ = @builder.begin_body(val[2], [ rescue_body ]) + + result = @builder.op_assign(val[0], val[1], rescue_) + + result +end + +def _reduce_198(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_199(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_200(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_201(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_202(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_203(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_global(val[0], val[1])) + result = @builder.op_assign(const, val[2], val[3]) + + result +end + +def _reduce_204(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_205(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_206(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_207(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_208(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_209(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_210(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_211(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_212(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_213(val, _values, result) + result = @builder.unary_op(val[0], + @builder.binary_op( + val[1], val[2], val[3])) + + result +end + +def _reduce_214(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_215(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_216(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_217(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_218(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_219(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_220(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_221(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_222(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_223(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_224(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_225(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_226(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_227(val, _values, result) + result = @builder.match_op(val[0], val[1], val[2]) + + result +end + +def _reduce_228(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_229(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +def _reduce_230(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_231(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_232(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_233(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_234(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_235(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil) + + result +end + +def _reduce_236(val, _values, result) + result = @builder.ternary(val[0], val[1], + val[2], val[4], val[5]) + + result +end + +# reduce 237 omitted + +# reduce 238 omitted + +# reduce 239 omitted + +# reduce 240 omitted + +def _reduce_241(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_242(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +def _reduce_243(val, _values, result) + result = val + + result +end + +def _reduce_244(val, _values, result) + result = [ nil, [], nil ] + + result +end + +# reduce 245 omitted + +def _reduce_246(val, _values, result) + result = [] + + result +end + +# reduce 247 omitted + +# reduce 248 omitted + +def _reduce_249(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_250(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +def _reduce_251(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_252(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_253(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + result.concat(val[1]) + + result +end + +def _reduce_254(val, _values, result) + assocs = @builder.associate(nil, val[2], nil) + result = val[0] << assocs + result.concat(val[3]) + + result +end + +def _reduce_255(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_256(val, _values, result) + result = @lexer.cmdarg.dup + @lexer.cmdarg.push(true) + + result +end + +def _reduce_257(val, _values, result) + @lexer.cmdarg = val[0] + + result = val[1] + + result +end + +def _reduce_258(val, _values, result) + result = @builder.block_pass(val[0], val[1]) + + result +end + +def _reduce_259(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_260(val, _values, result) + result = [] + + result +end + +def _reduce_261(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_262(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_263(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_264(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_265(val, _values, result) + result = @builder.array(nil, val[0], nil) + + result +end + +# reduce 266 omitted + +def _reduce_267(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_268(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_269(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +# reduce 270 omitted + +# reduce 271 omitted + +# reduce 272 omitted + +# reduce 273 omitted + +# reduce 274 omitted + +# reduce 275 omitted + +# reduce 276 omitted + +# reduce 277 omitted + +# reduce 278 omitted + +# reduce 279 omitted + +def _reduce_280(val, _values, result) + result = @builder.call_method(nil, nil, val[0]) + + result +end + +def _reduce_281(val, _values, result) + result = @lexer.cmdarg.dup + @lexer.cmdarg.clear + + result +end + +def _reduce_282(val, _values, result) + @lexer.cmdarg = val[1] + + result = @builder.begin_keyword(val[0], val[2], val[3]) + + result +end + +def _reduce_283(val, _values, result) + result = @lexer.cmdarg.dup + @lexer.cmdarg.clear + + result +end + +def _reduce_284(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_285(val, _values, result) + @lexer.cmdarg = val[1] + + result = @builder.begin(val[0], val[2], val[5]) + + result +end + +def _reduce_286(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_287(val, _values, result) + result = @builder.begin(val[0], nil, val[3]) + + result +end + +def _reduce_288(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_289(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +def _reduce_290(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_291(val, _values, result) + result = @builder.array(val[0], val[1], val[2]) + + result +end + +def _reduce_292(val, _values, result) + result = @builder.associate(val[0], val[1], val[2]) + + result +end + +def _reduce_293(val, _values, result) + result = @builder.keyword_cmd(:return, val[0]) + + result +end + +def _reduce_294(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_295(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2]) + + result +end + +def _reduce_296(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0]) + + result +end + +def _reduce_297(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], + val[2], [ val[3] ], val[4]) + + result +end + +def _reduce_298(val, _values, result) + result = @builder.not_op(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_299(val, _values, result) + result = @builder.not_op(val[0], val[1], nil, val[2]) + + result +end + +def _reduce_300(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0]) + + begin_t, args, body, end_t = val[1] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +# reduce 301 omitted + +def _reduce_302(val, _values, result) + begin_t, args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, args, body, end_t) + + result +end + +def _reduce_303(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_304(val, _values, result) + lambda_call = @builder.call_lambda(val[0]) + + args, (begin_t, body, end_t) = val[2] + result = @builder.block(lambda_call, + begin_t, args, body, end_t) + + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_305(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, val[5]) + + result +end + +def _reduce_306(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + else_, else_t, + val[3], val[5]) + + result +end + +def _reduce_307(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_308(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_309(val, _values, result) + result = @builder.loop(:while, val[0], val[2], val[3], + val[5], val[6]) + + result +end + +def _reduce_310(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_311(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_312(val, _values, result) + result = @builder.loop(:until, val[0], val[2], val[3], + val[5], val[6]) + + result +end + +def _reduce_313(val, _values, result) + *when_bodies, (else_t, else_body) = *val[3] + + result = @builder.case(val[0], val[1], + when_bodies, else_t, else_body, + val[4]) + + result +end + +def _reduce_314(val, _values, result) + *when_bodies, (else_t, else_body) = *val[2] + + result = @builder.case(val[0], nil, + when_bodies, else_t, else_body, + val[3]) + + result +end + +def _reduce_315(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_316(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_317(val, _values, result) + result = @builder.for(val[0], val[1], + val[2], val[4], + val[5], val[7], val[8]) + + result +end + +def _reduce_318(val, _values, result) + local_push + @context.in_class = true + + result +end + +def _reduce_319(val, _values, result) + k_class, ctx = val[0] + if @context.in_def + diagnostic :error, :class_in_def, nil, k_class + end + + lt_t, superclass = val[2] + result = @builder.def_class(k_class, val[1], + lt_t, superclass, + val[4], val[5]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_320(val, _values, result) + @context.in_def = false + @context.in_class = false + local_push + + result +end + +def _reduce_321(val, _values, result) + k_class, ctx = val[0] + result = @builder.def_sclass(k_class, val[1], val[2], + val[5], val[6]) + + local_pop + @context.in_def = ctx.in_def + @context.in_class = ctx.in_class + + result +end + +def _reduce_322(val, _values, result) + @context.in_class = true + local_push + + result +end + +def _reduce_323(val, _values, result) + k_mod, ctx = val[0] + if @context.in_def + diagnostic :error, :module_in_def, nil, k_mod + end + + result = @builder.def_module(k_mod, val[1], + val[3], val[4]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_324(val, _values, result) + local_push + result = context.dup + @context.in_def = true + + result +end + +def _reduce_325(val, _values, result) + result = @builder.def_method(val[0], val[1], + val[3], val[4], val[5]) + + local_pop + @context.in_def = val[2].in_def + + result +end + +def _reduce_326(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_327(val, _values, result) + local_push + result = context.dup + @context.in_def = true + + result +end + +def _reduce_328(val, _values, result) + result = @builder.def_singleton(val[0], val[1], val[2], + val[4], val[6], val[7], val[8]) + + local_pop + @context.in_def = val[5].in_def + + result +end + +def _reduce_329(val, _values, result) + result = @builder.keyword_cmd(:break, val[0]) + + result +end + +def _reduce_330(val, _values, result) + result = @builder.keyword_cmd(:next, val[0]) + + result +end + +def _reduce_331(val, _values, result) + result = @builder.keyword_cmd(:redo, val[0]) + + result +end + +def _reduce_332(val, _values, result) + result = @builder.keyword_cmd(:retry, val[0]) + + result +end + +# reduce 333 omitted + +def _reduce_334(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_335(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +# reduce 336 omitted + +# reduce 337 omitted + +def _reduce_338(val, _values, result) + result = val[1] + + result +end + +# reduce 339 omitted + +# reduce 340 omitted + +# reduce 341 omitted + +def _reduce_342(val, _values, result) + else_t, else_ = val[4] + result = [ val[0], + @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, nil), + ] + + result +end + +# reduce 343 omitted + +def _reduce_344(val, _values, result) + result = val + + result +end + +# reduce 345 omitted + +# reduce 346 omitted + +def _reduce_347(val, _values, result) + result = @builder.arg(val[0]) + + result +end + +def _reduce_348(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_349(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_350(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 351 omitted + +def _reduce_352(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2], val[3])) + + result +end + +def _reduce_353(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2], val[3])). + concat(val[5]) + + result +end + +def _reduce_354(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2])) + + result +end + +def _reduce_355(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2])). + concat(val[4]) + + result +end + +def _reduce_356(val, _values, result) + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_357(val, _values, result) + result = [ @builder.restarg(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_358(val, _values, result) + result = [ @builder.restarg(val[0]) ] + + result +end + +def _reduce_359(val, _values, result) + result = [ @builder.restarg(val[0]), + *val[2] ] + + result +end + +def _reduce_360(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_361(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_362(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_363(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_364(val, _values, result) + result = val[1] + + result +end + +def _reduce_365(val, _values, result) + result = [] + + result +end + +def _reduce_366(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_367(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_368(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_369(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_370(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 371 omitted + +def _reduce_372(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_373(val, _values, result) + if val[1].empty? && val[0].size == 1 + result = [@builder.procarg0(val[0][0])] + else + result = val[0].concat(val[1]) + end + + result +end + +def _reduce_374(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_375(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_376(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_377(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_378(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_379(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 380 omitted + +def _reduce_381(val, _values, result) + result = @builder.args(nil, [], nil) + + result +end + +def _reduce_382(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_383(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + result +end + +def _reduce_384(val, _values, result) + result = @builder.args(val[0], [], val[0]) + + result +end + +def _reduce_385(val, _values, result) + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_386(val, _values, result) + result = [] + + result +end + +def _reduce_387(val, _values, result) + result = val[2] + + result +end + +def _reduce_388(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_389(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_390(val, _values, result) + @static_env.declare val[0][0] + result = @builder.shadowarg(val[0]) + + result +end + +# reduce 391 omitted + +def _reduce_392(val, _values, result) + @static_env.extend_dynamic + + result +end + +def _reduce_393(val, _values, result) + result = @lexer.cmdarg.dup + @lexer.cmdarg.clear + + result +end + +def _reduce_394(val, _values, result) + @lexer.cmdarg = val[2] + @lexer.cmdarg.lexpop + + result = [ val[1], val[3] ] + + @static_env.unextend + + result +end + +def _reduce_395(val, _values, result) + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_396(val, _values, result) + result = @builder.args(nil, val[0], nil) + + result +end + +def _reduce_397(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_398(val, _values, result) + result = [ val[0], val[2], val[3] ] + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_399(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_400(val, _values, result) + result = [ val[0], val[2], val[3] ] + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_401(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_402(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_403(val, _values, result) + begin_t, block_args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, block_args, body, end_t) + + result +end + +def _reduce_404(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_405(val, _values, result) + lparen_t, args, rparen_t = val[3] + method_call = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_406(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_407(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.call_method(nil, nil, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_408(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_409(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_410(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2]) + + result +end + +def _reduce_411(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_412(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_413(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.keyword_cmd(:super, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_414(val, _values, result) + result = @builder.keyword_cmd(:zsuper, val[0]) + + result +end + +def _reduce_415(val, _values, result) + result = @builder.index(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_416(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_417(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_418(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_419(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_420(val, _values, result) + result = [ @builder.when(val[0], val[1], val[2], val[3]), + *val[4] ] + + result +end + +def _reduce_421(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 422 omitted + +def _reduce_423(val, _values, result) + assoc_t, exc_var = val[2] + + if val[1] + exc_list = @builder.array(nil, val[1], nil) + end + + result = [ @builder.rescue_body(val[0], + exc_list, assoc_t, exc_var, + val[3], val[4]), + *val[5] ] + + result +end + +def _reduce_424(val, _values, result) + result = [] + + result +end + +def _reduce_425(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 426 omitted + +# reduce 427 omitted + +def _reduce_428(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 429 omitted + +def _reduce_430(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 431 omitted + +# reduce 432 omitted + +# reduce 433 omitted + +# reduce 434 omitted + +def _reduce_435(val, _values, result) + result = @builder.string_compose(nil, val[0], nil) + + result +end + +def _reduce_436(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_437(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_438(val, _values, result) + result = @builder.string_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_439(val, _values, result) + result = @builder.string(val[0]) + + result +end + +def _reduce_440(val, _values, result) + result = @builder.character(val[0]) + + result +end + +def _reduce_441(val, _values, result) + result = @builder.xstring_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_442(val, _values, result) + opts = @builder.regexp_options(val[3]) + result = @builder.regexp_compose(val[0], val[1], val[2], opts) + + result +end + +def _reduce_443(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_444(val, _values, result) + result = [] + + result +end + +def _reduce_445(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_446(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_447(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_448(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_449(val, _values, result) + result = [] + + result +end + +def _reduce_450(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_451(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_452(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_453(val, _values, result) + result = [] + + result +end + +def _reduce_454(val, _values, result) + result = val[0] << @builder.string_internal(val[1]) + + result +end + +def _reduce_455(val, _values, result) + result = [] + + result +end + +def _reduce_456(val, _values, result) + result = val[0] << @builder.symbol_internal(val[1]) + + result +end + +def _reduce_457(val, _values, result) + result = [] + + result +end + +def _reduce_458(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_459(val, _values, result) + result = [] + + result +end + +def _reduce_460(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_461(val, _values, result) + result = [] + + result +end + +def _reduce_462(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_463(val, _values, result) + result = @builder.string_internal(val[0]) + + result +end + +def _reduce_464(val, _values, result) + result = val[1] + + result +end + +def _reduce_465(val, _values, result) + @lexer.cond.push(false) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_466(val, _values, result) + @lexer.cond.lexpop + @lexer.cmdarg.lexpop + + result = @builder.begin(val[0], val[2], val[3]) + + result +end + +def _reduce_467(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_468(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_469(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +# reduce 470 omitted + +def _reduce_471(val, _values, result) + result = @builder.symbol(val[0]) + + result +end + +def _reduce_472(val, _values, result) + result = @builder.symbol_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_473(val, _values, result) + result = val[0] + + result +end + +def _reduce_474(val, _values, result) + if @builder.respond_to? :negate + # AST builder interface compatibility + result = @builder.negate(val[0], val[1]) + else + result = @builder.unary_num(val[0], val[1]) + end + + result +end + +def _reduce_475(val, _values, result) + result = @builder.integer(val[0]) + + result +end + +def _reduce_476(val, _values, result) + result = @builder.float(val[0]) + + result +end + +def _reduce_477(val, _values, result) + result = @builder.rational(val[0]) + + result +end + +def _reduce_478(val, _values, result) + result = @builder.complex(val[0]) + + result +end + +def _reduce_479(val, _values, result) + result = @builder.ident(val[0]) + + result +end + +def _reduce_480(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_481(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_482(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_483(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +def _reduce_484(val, _values, result) + result = @builder.nil(val[0]) + + result +end + +def _reduce_485(val, _values, result) + result = @builder.self(val[0]) + + result +end + +def _reduce_486(val, _values, result) + result = @builder.true(val[0]) + + result +end + +def _reduce_487(val, _values, result) + result = @builder.false(val[0]) + + result +end + +def _reduce_488(val, _values, result) + result = @builder.__FILE__(val[0]) + + result +end + +def _reduce_489(val, _values, result) + result = @builder.__LINE__(val[0]) + + result +end + +def _reduce_490(val, _values, result) + result = @builder.__ENCODING__(val[0]) + + result +end + +def _reduce_491(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_492(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_493(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_494(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_495(val, _values, result) + result = @builder.nth_ref(val[0]) + + result +end + +def _reduce_496(val, _values, result) + result = @builder.back_ref(val[0]) + + result +end + +def _reduce_497(val, _values, result) + result = nil + + result +end + +def _reduce_498(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_499(val, _values, result) + result = [ val[0], val[2] ] + + result +end + +def _reduce_500(val, _values, result) + yyerrok + result = nil + + result +end + +def _reduce_501(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + @lexer.state = :expr_value + + result +end + +def _reduce_502(val, _values, result) + result = @context.in_kwarg + @context.in_kwarg = true + + result +end + +def _reduce_503(val, _values, result) + @context.in_kwarg = val[0] + result = @builder.args(nil, val[1], nil) + + result +end + +def _reduce_504(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_505(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_506(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_507(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_508(val, _values, result) + result = val[1] + + result +end + +def _reduce_509(val, _values, result) + result = [] + + result +end + +def _reduce_510(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_511(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_512(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_513(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_514(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_515(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_516(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_517(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_518(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_519(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_520(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_521(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_522(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_523(val, _values, result) + result = val[0] + + result +end + +def _reduce_524(val, _values, result) + result = [] + + result +end + +def _reduce_525(val, _values, result) + diagnostic :error, :argument_const, nil, val[0] + + result +end + +def _reduce_526(val, _values, result) + diagnostic :error, :argument_ivar, nil, val[0] + + result +end + +def _reduce_527(val, _values, result) + diagnostic :error, :argument_gvar, nil, val[0] + + result +end + +def _reduce_528(val, _values, result) + diagnostic :error, :argument_cvar, nil, val[0] + + result +end + +# reduce 529 omitted + +def _reduce_530(val, _values, result) + @static_env.declare val[0][0] + + result = val[0] + + result +end + +def _reduce_531(val, _values, result) + result = val[0] + + result +end + +def _reduce_532(val, _values, result) + result = @builder.arg(val[0]) + + result +end + +def _reduce_533(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_534(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_535(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_536(val, _values, result) + check_kwarg_name(val[0]) + + @static_env.declare val[0][0] + + result = val[0] + + result +end + +def _reduce_537(val, _values, result) + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_538(val, _values, result) + result = @builder.kwarg(val[0]) + + result +end + +def _reduce_539(val, _values, result) + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_540(val, _values, result) + result = @builder.kwarg(val[0]) + + result +end + +def _reduce_541(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_542(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_543(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_544(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 545 omitted + +# reduce 546 omitted + +def _reduce_547(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.kwrestarg(val[0], val[1]) ] + + result +end + +def _reduce_548(val, _values, result) + result = [ @builder.kwrestarg(val[0]) ] + + result +end + +def _reduce_549(val, _values, result) + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_550(val, _values, result) + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_551(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_552(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_553(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_554(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 555 omitted + +# reduce 556 omitted + +def _reduce_557(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_558(val, _values, result) + result = [ @builder.restarg(val[0]) ] + + result +end + +# reduce 559 omitted + +# reduce 560 omitted + +def _reduce_561(val, _values, result) + @static_env.declare val[1][0] + + result = @builder.blockarg(val[0], val[1]) + + result +end + +def _reduce_562(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_563(val, _values, result) + result = [] + + result +end + +# reduce 564 omitted + +def _reduce_565(val, _values, result) + result = val[1] + + result +end + +def _reduce_566(val, _values, result) + result = [] + + result +end + +# reduce 567 omitted + +def _reduce_568(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_569(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_570(val, _values, result) + result = @builder.pair(val[0], val[1], val[2]) + + result +end + +def _reduce_571(val, _values, result) + result = @builder.pair_keyword(val[0], val[1]) + + result +end + +def _reduce_572(val, _values, result) + result = @builder.pair_quoted(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_573(val, _values, result) + result = @builder.kwsplat(val[0], val[1]) + + result +end + +# reduce 574 omitted + +# reduce 575 omitted + +# reduce 576 omitted + +# reduce 577 omitted + +# reduce 578 omitted + +# reduce 579 omitted + +# reduce 580 omitted + +# reduce 581 omitted + +# reduce 582 omitted + +# reduce 583 omitted + +# reduce 584 omitted + +# reduce 585 omitted + +# reduce 586 omitted + +# reduce 587 omitted + +# reduce 588 omitted + +# reduce 589 omitted + +def _reduce_590(val, _values, result) + result = val[1] + + result +end + +def _reduce_591(val, _values, result) + result = val[1] + + result +end + +# reduce 592 omitted + +# reduce 593 omitted + +# reduce 594 omitted + +def _reduce_595(val, _values, result) + yyerrok + + result +end + +# reduce 596 omitted + +# reduce 597 omitted + +# reduce 598 omitted + +def _reduce_599(val, _values, result) + result = nil + + result +end + +def _reduce_none(val, _values, result) + val[0] +end + + end # class Ruby22 +end # module Parser diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby23.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby23.rb new file mode 100644 index 00000000..e3942e92 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby23.rb @@ -0,0 +1,10322 @@ +# -*- encoding:utf-8; warn-indent:false; frozen_string_literal: true -*- +# +# DO NOT MODIFY!!!! +# This file is automatically generated by Racc 1.8.1 +# from Racc grammar file "ruby23.y". +# + +require 'racc/parser.rb' + + +require_relative '../parser' + +module Parser + class Ruby23 < Parser::Base + + + def version + 23 + end + + def default_encoding + Encoding::UTF_8 + end + + def local_push + @static_env.extend_static + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + end + + def local_pop + @static_env.unextend + @lexer.cmdarg.pop + @lexer.cond.pop + end +##### State transition tables begin ### + +racc_action_table = [ + -479, 218, 219, 218, 219, 216, -97, -479, -479, -479, + -286, 540, -479, -479, -479, 214, -479, 272, 221, 580, + 617, 617, 265, 540, -479, 582, -479, -479, -479, 272, + 552, 272, -493, 111, 553, -98, -479, -479, 540, -479, + -479, -479, -479, -479, 540, 540, -97, -98, -105, -105, + -286, -104, -96, -83, -104, 616, 616, 530, 272, 222, + 529, 123, -105, -69, 617, -100, -479, -479, -479, -479, + -479, -479, -479, -479, -479, -479, -479, -479, -479, -479, + 215, 267, -479, -479, -479, 579, -479, -479, 695, -97, + -479, 581, -102, -479, -479, 222, -479, 222, -479, 616, + -479, 208, -479, -479, 271, -479, -479, -479, -479, -479, + -100, -479, -482, -479, -102, -88, 271, 871, 271, -482, + -482, -482, 267, -101, -482, -482, -482, -479, -482, 115, + -479, -479, -479, -479, 114, -479, -482, -479, -482, -482, + -482, 115, -479, -479, -89, 271, 114, -91, -482, -482, + -103, -482, -482, -482, -482, -482, 115, -99, -96, 822, + -95, 114, 115, 115, -97, -98, -105, 114, 114, -97, + -98, -105, -104, 695, -91, -101, -99, -104, -482, -482, + -482, -482, -482, -482, -482, -482, -482, -482, -482, -482, + -482, -482, 115, 209, -482, -482, -482, 114, -482, -482, + -576, -93, -482, 210, -93, -482, -482, 695, -482, -103, + -482, 115, -482, -91, -482, -482, 114, -482, -482, -482, + -482, -482, -289, -482, -494, -482, 870, -577, -100, -289, + -289, -289, -102, -100, 617, -289, -289, -102, -289, -482, + -576, -101, -482, -482, -482, -482, -101, -482, 217, -482, + 218, 219, 447, -91, -482, -482, -91, 261, -289, -289, + -90, -289, -289, -289, -289, -289, -91, 320, -103, 616, + -93, -479, -92, -103, -577, -99, 530, 115, -479, 532, + -99, -98, 114, 518, -92, -90, 218, 219, -289, -289, + -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, + -289, -289, 321, 749, -289, -289, -289, -482, 600, -105, + -93, 115, -289, -93, -482, -289, 114, 785, -94, 546, + -289, 222, -289, -93, -289, -289, -90, -289, -289, -289, + -289, -289, 567, -289, -580, -289, -479, -576, -92, 81, + -104, -580, -580, -580, 222, 218, 219, -580, -580, -289, + -580, 82, -289, -289, 389, -94, 402, -289, 115, -580, + -100, 83, 446, 114, -289, -103, -90, -573, -493, -90, + -580, -580, -482, -580, -580, -580, -580, -580, -92, -90, + 115, -92, 218, 219, 448, 114, 672, 750, 669, 668, + 667, -92, 670, 93, 94, 449, 569, 568, 565, 221, + -580, -580, -580, -580, -580, -580, -580, -580, -580, -580, + -580, -580, -580, -580, 480, -88, -580, -580, -580, -479, + 601, 93, 94, 567, -580, -97, -479, -580, 115, 840, + 489, -573, -580, 114, -580, -479, -580, -580, -494, -580, + -580, -580, -580, -580, -102, -580, -580, -580, 567, 672, + 567, 669, 668, 667, -573, 670, -489, 115, 491, -574, + 493, -580, 114, -489, -580, -580, -580, -92, 889, -580, + 501, 95, 96, -580, -580, -580, -580, -101, -580, -580, + -580, -68, -580, 222, -479, -89, -99, 569, 568, 565, + -488, -580, -580, -580, -580, -98, 115, -488, 504, 95, + 96, 114, -580, -580, 632, -580, -580, -580, -580, -580, + 505, -482, 569, 568, 569, 568, 567, 530, -482, 567, + 532, -489, 726, -574, 728, 567, 530, -482, 512, 532, + 276, 986, -580, -580, -580, -580, -580, -580, -580, -580, + -580, -580, -580, -580, -580, -580, -574, 222, -580, -580, + -580, 222, 751, -580, 971, -488, -580, 567, 518, -580, + -580, 567, -580, -490, -580, 267, -580, 595, -580, -580, + -490, -580, -580, -580, -580, -580, -482, -580, -580, -580, + 569, 568, 570, 569, 568, 572, 515, -487, 519, 569, + 568, 574, 242, -580, -487, 222, -580, -580, -580, -580, + 533, -580, 534, -580, -289, -95, 218, 219, -580, -101, + 493, -289, -289, -289, -91, -104, -289, -289, -289, 546, + -289, 569, 568, 578, -100, 569, 568, 583, -490, 399, + -289, -289, -289, 391, 401, 400, 817, 785, 596, 550, + -289, -289, 551, -289, -289, -289, -289, -289, 559, 214, + 584, -333, -487, 214, -484, -485, 213, 587, -333, -486, + 444, -484, -485, 688, 687, 211, -486, -333, -261, 445, + -289, -289, -289, -289, -289, -289, -289, -289, -289, -289, + -289, -289, -289, -289, 589, -93, -289, -289, -289, 242, + 752, -289, -491, 222, -289, -102, 214, -289, -289, -491, + -289, 593, -289, 265, -289, 735, -289, -289, -491, -289, + -289, -289, -289, -289, 215, -289, -333, -289, 215, -484, + -485, 239, -492, 594, -486, 241, 240, 267, 242, -492, + 604, -289, 817, 785, -289, -289, -289, -289, -492, -289, + 607, -289, -414, 242, 242, 242, -289, -103, 242, -414, + -414, -414, -90, 677, -414, -414, -414, -491, -414, 222, + 239, 215, -99, 680, 241, 240, 222, -414, -414, -414, + 720, 721, 222, -83, 722, 109, 110, 636, -414, -414, + 222, -414, -414, -414, -414, -414, 672, -492, 669, 668, + 667, 214, 670, 523, 647, 652, 688, 687, 511, 653, + 672, 681, 669, 668, 667, 655, 670, 509, -414, -414, + -414, -414, -414, -414, -414, -414, -414, -414, -414, -414, + -414, -414, 691, 806, -414, -414, -414, 546, 698, -414, + 715, 267, -414, 725, 729, -414, -414, 806, -414, 730, + -414, -262, -414, 736, -414, -414, 809, -414, -414, -414, + -414, -414, -296, -414, -414, -414, 215, 480, 480, -296, + -296, -296, 222, 754, -296, -296, -296, -279, -296, -414, + 261, 491, -414, -414, -279, -414, 493, -414, -296, -296, + 778, 647, 222, -279, -414, 267, 267, 647, -296, -296, + 242, -296, -296, -296, -296, -296, 785, 222, 794, 214, + 797, 214, 798, 800, 802, 804, 521, 672, 549, 669, + 668, 667, 812, 670, 813, 445, 814, 547, -296, -296, + -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, + -296, -296, -279, 785, -296, -296, -296, 821, 222, -296, + 222, 276, -296, 830, 806, -296, -296, -263, -296, 839, + -296, 842, -296, 809, -296, -296, 797, -296, -296, -296, + -296, -296, -280, -296, 215, -296, 215, 845, 847, -280, + -280, -280, 849, 851, -280, -280, -280, 214, -280, -296, + 222, 853, -296, -296, 555, -296, 854, -296, -280, -280, + -280, 857, 859, 557, -296, 860, 647, 862, -280, -280, + -261, -280, -280, -280, -280, -280, 866, -290, 868, -290, + 222, 214, 887, 222, -290, 891, -290, 893, 922, 899, + 902, 222, 906, -290, -264, -290, 916, 557, -280, -280, + -280, -280, -280, -280, -280, -280, -280, -280, -280, -280, + -280, -280, 215, 214, -280, -280, -280, 923, 924, -280, + 922, 935, -280, 797, 937, -280, -280, 939, -280, 557, + -280, 941, -280, 943, -280, -280, 943, -280, -280, -280, + -280, -280, -290, -280, -290, -280, 215, 222, 677, 672, + 214, 669, 668, 667, 949, 670, 952, 977, 680, -280, + 953, -580, -280, -280, -280, -280, 975, -280, -244, -280, + 958, 715, 797, 961, -280, -244, -244, -244, 215, 963, + -244, -244, -244, 965, -244, 967, 806, 242, 967, 978, + 988, 688, 687, -244, -244, -244, 681, 919, -577, 669, + 668, 667, -576, 670, -244, -244, 652, -244, -244, -244, + -244, -244, 1003, -580, 1004, 215, 1005, 943, 943, 239, + -580, 943, 1010, 241, 240, -576, 237, 238, 988, -580, + 1013, 1014, 1015, 967, -244, -244, -244, -244, -244, -244, + -244, -244, -244, -244, -244, -244, -244, -244, -580, 967, + -244, -244, -244, -289, 967, -244, 222, 267, -244, 988, + -289, -244, -244, 943, -244, -577, -244, 988, -244, -289, + -244, -244, 967, -244, -244, -244, -244, -244, -580, -244, + -244, -244, nil, 672, nil, 669, 668, 667, nil, 670, + -289, nil, nil, nil, nil, -244, nil, -289, -244, -244, + -581, -244, -577, -244, nil, nil, -289, -581, -581, -581, + -244, nil, -581, -581, -581, nil, -581, 242, -289, nil, + 806, nil, nil, nil, nil, -581, -581, -581, -581, 948, + nil, nil, nil, 256, 257, nil, -581, -581, nil, -581, + -581, -581, -581, -581, 672, nil, 669, 668, 667, 239, + 670, 245, nil, 241, 240, -289, 237, 238, nil, nil, + 243, nil, 244, nil, nil, nil, -581, -581, -581, -581, + -581, -581, -581, -581, -581, -581, -581, -581, -581, -581, + nil, 806, -581, -581, -581, 242, nil, -581, nil, nil, + -581, nil, nil, -581, -581, nil, -581, nil, -581, nil, + -581, nil, -581, -581, nil, -581, -581, -581, -581, -581, + nil, -581, -581, -581, nil, nil, nil, 239, nil, nil, + nil, 241, 240, nil, 237, 238, nil, -581, nil, nil, + -581, -581, -581, -581, nil, -581, -582, -581, nil, nil, + nil, nil, -581, -582, -582, -582, nil, nil, -582, -582, + -582, 242, -582, 919, nil, 669, 668, 667, nil, 670, + nil, -582, -582, -582, -582, nil, nil, 256, 257, nil, + nil, nil, -582, -582, nil, -582, -582, -582, -582, -582, + nil, nil, nil, 239, nil, 245, nil, 241, 240, nil, + 237, 238, nil, nil, 243, nil, 244, 118, 119, 120, + 121, 122, -582, -582, -582, -582, -582, -582, -582, -582, + -582, -582, -582, -582, -582, -582, nil, nil, -582, -582, + -582, nil, nil, -582, nil, nil, -582, nil, nil, -582, + -582, nil, -582, nil, -582, nil, -582, nil, -582, -582, + nil, -582, -582, -582, -582, -582, nil, -582, -582, -582, + 118, 119, 120, 121, 122, nil, nil, nil, 672, nil, + 669, 668, 667, -582, 670, nil, -582, -582, -582, -582, + nil, -582, -244, -582, nil, nil, nil, nil, -582, -244, + -244, -244, nil, nil, -244, -244, -244, 672, -244, 669, + 668, 667, 677, 670, nil, 806, nil, -244, -244, nil, + nil, nil, 680, nil, nil, nil, 242, nil, -244, -244, + nil, -244, -244, -244, -244, -244, 118, 119, 120, 121, + 122, nil, 256, 257, 675, nil, 672, nil, 669, 668, + 667, 677, 670, 685, 684, 688, 687, nil, 239, nil, + 681, 680, 241, 240, nil, 237, 238, nil, nil, -244, + nil, nil, nil, nil, 242, nil, -244, nil, nil, nil, + nil, 267, -244, 675, 658, nil, 222, nil, nil, nil, + 256, 257, 685, 684, 688, 687, nil, nil, nil, 681, + nil, nil, nil, nil, -244, -244, 239, nil, 245, nil, + 241, 240, nil, 237, 238, nil, nil, nil, nil, -244, + nil, nil, -244, nil, nil, nil, nil, -244, 5, 74, + 75, 71, 9, 57, -244, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + 605, 8, 45, 7, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, 246, 251, 252, 253, 248, 250, + 258, 259, 254, 255, nil, 235, 236, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 260, nil, + -238, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + 590, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, 246, 251, 252, 253, 248, 250, + 258, 259, 254, 255, nil, 235, 236, nil, nil, 256, + 257, nil, 40, nil, nil, 298, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 260, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 5, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + 605, 8, 45, 7, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, 246, 251, 252, 253, 248, 250, + 258, 259, 254, 255, nil, 235, 236, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 260, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, 246, 251, 252, 253, 248, 250, + 258, 259, 254, 255, nil, 235, 236, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 260, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, 246, 251, 252, 253, 248, 250, + 258, 259, 254, 255, nil, 235, 236, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 260, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, 246, 251, 252, 253, 248, 250, + 258, 259, 254, 255, nil, 235, 236, nil, nil, 256, + 257, nil, 40, nil, nil, 298, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 260, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, 246, 251, 252, 253, 248, 250, + 258, 259, 254, 255, nil, 235, 236, nil, nil, 256, + 257, nil, 40, nil, nil, 298, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, 222, 260, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, 246, 251, 252, 253, 248, 250, + 258, 259, 254, 255, nil, 235, 236, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 260, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 5, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 7, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, 246, 251, 252, 253, 248, 250, + 258, 259, 254, 255, nil, 235, 236, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 260, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, 246, 251, 252, 253, 248, 250, + 258, 259, 254, 255, nil, 235, 236, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 260, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, 246, 251, 252, 253, 248, 250, + 258, 259, 254, 255, nil, 235, 236, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 260, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, 246, 251, 252, 253, 248, 250, + 258, 259, 254, 255, nil, 235, 236, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 260, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, 246, 251, 252, 253, 248, 250, + 258, 259, 254, 255, nil, 235, 236, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 260, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, 246, 251, 252, 253, 248, 250, + 258, 259, 254, 255, nil, 235, 236, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 260, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, 246, 251, 252, 253, 248, 250, + 258, 259, 254, 255, nil, 235, 236, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 260, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, 246, 251, 252, 253, 248, 250, + 258, 259, 254, 255, nil, 235, 236, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 260, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, 246, 251, 252, 253, 248, 250, + 258, 259, 254, 255, nil, 235, 236, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 260, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, 246, 251, 252, 253, 248, 250, + 258, 259, 254, 255, nil, -601, -601, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, 672, nil, + 669, 668, 667, 62, 670, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, 806, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, 246, 251, 252, 253, 248, 250, + 258, 259, 254, 255, nil, -601, -601, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, -601, -601, -601, -601, 248, 250, + nil, nil, -601, -601, nil, nil, nil, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, nil, nil, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, nil, nil, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, -601, -601, -601, -601, 248, 250, + nil, nil, -601, -601, nil, nil, nil, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, -601, -601, -601, -601, 248, 250, + nil, nil, -601, -601, nil, nil, nil, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, -601, -601, -601, -601, 248, 250, + nil, nil, -601, -601, nil, nil, nil, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, -601, -601, -601, -601, 248, 250, + nil, nil, -601, -601, nil, nil, nil, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, -601, -601, -601, -601, 248, 250, + nil, nil, -601, -601, nil, nil, nil, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, 246, 251, 252, 253, 248, 250, + nil, nil, 254, 255, nil, nil, nil, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, 246, 251, 252, 253, 248, 250, + 258, nil, 254, 255, nil, nil, nil, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, 249, 247, 243, 20, 244, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, 242, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 256, + 257, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, 239, nil, 245, 44, 241, + 240, nil, 237, 238, nil, nil, nil, 20, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 294, 74, + 75, 71, 9, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, 8, 45, 296, 10, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 40, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 74, 75, + 71, 9, 57, nil, nil, nil, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 103, 102, + 104, 105, nil, nil, 19, nil, nil, nil, nil, nil, + 8, 45, 7, 10, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 40, nil, nil, 33, nil, nil, 58, 59, nil, + nil, 60, nil, 35, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 20, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 234, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, 233, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 232, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 103, 102, 104, 105, nil, nil, 234, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, 288, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, 285, nil, 283, nil, 44, + nil, nil, 289, nil, nil, nil, nil, nil, 232, nil, + nil, nil, nil, 91, 286, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 103, 102, 104, 105, nil, nil, 234, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, 288, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, 233, nil, nil, + 58, 59, nil, nil, 60, nil, 285, nil, 283, nil, + 44, nil, nil, 289, nil, nil, nil, nil, nil, 232, + nil, nil, nil, nil, 91, 286, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 103, 102, 104, 105, nil, nil, 234, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, 288, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, 233, nil, + nil, 58, 59, nil, nil, 60, nil, 285, nil, 283, + nil, 44, nil, nil, 289, nil, nil, nil, nil, nil, + 232, nil, nil, nil, nil, 91, 286, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 313, 314, 72, 73, nil, nil, nil, nil, nil, + 309, 310, 316, 103, 102, 104, 105, nil, nil, 234, + nil, nil, nil, nil, nil, nil, 311, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, nil, nil, 317, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 307, nil, nil, 303, + nil, nil, 58, 59, nil, nil, 60, nil, 302, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 313, 314, 72, 73, nil, nil, nil, nil, + nil, 309, 310, 316, 103, 102, 104, 105, nil, nil, + 234, nil, nil, nil, nil, nil, nil, 311, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, nil, nil, 317, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 307, nil, nil, + 233, nil, nil, 58, 59, nil, nil, 60, nil, nil, + 672, nil, 669, 668, 667, 677, 670, nil, nil, nil, + nil, nil, nil, nil, nil, 680, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 319, nil, 675, 62, nil, + 83, 95, 96, 74, 75, 71, nil, 57, 688, 687, + nil, 63, 64, 681, nil, nil, 67, nil, 65, 66, + 68, 313, 314, 72, 73, nil, nil, nil, nil, nil, + 309, 310, 316, 103, 102, 104, 105, nil, nil, 234, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, 233, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 232, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 313, 314, 72, 73, nil, nil, nil, nil, + nil, 309, 310, 316, 103, 102, 104, 105, nil, nil, + 234, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + 233, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 232, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 313, 314, 72, 73, nil, nil, nil, + nil, nil, 309, 310, 316, 103, 102, 104, 105, nil, + nil, 234, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 233, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 232, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 313, 314, 72, 73, nil, nil, + nil, nil, nil, 309, 310, 316, 103, 102, 104, 105, + nil, nil, 234, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + 288, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 233, nil, nil, 58, 59, nil, nil, 60, + nil, 285, nil, nil, nil, 44, nil, nil, 289, nil, + nil, nil, nil, nil, 232, nil, nil, nil, nil, 91, + 286, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 313, 314, 72, 73, nil, + nil, nil, nil, nil, 309, 310, 316, 103, 102, 104, + 105, nil, nil, 234, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, 288, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, 233, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, 289, + nil, nil, nil, nil, nil, 232, nil, nil, nil, nil, + 91, 286, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 103, 102, + 104, 105, nil, nil, 19, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, 233, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 20, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, 233, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 103, 102, 104, 105, nil, nil, 19, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, 115, nil, + nil, nil, nil, 114, 62, nil, 83, 95, 96, 74, + 75, 71, nil, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 313, 314, 72, + 73, nil, nil, nil, nil, nil, 309, 310, 316, 103, + 102, 104, 105, nil, nil, 234, nil, nil, nil, nil, + nil, nil, 311, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + nil, nil, 317, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 351, nil, nil, 33, nil, nil, 58, 59, + nil, nil, 60, nil, 35, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 313, 314, + 72, 73, nil, nil, nil, nil, nil, 309, 310, 316, + 103, 102, 104, 105, nil, nil, 234, nil, nil, nil, + nil, nil, nil, 311, nil, nil, 107, 106, 108, 356, + 56, 99, 98, 357, nil, 101, 109, 110, nil, 93, + 94, nil, nil, 317, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 363, nil, nil, 358, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 313, + 314, 72, 73, nil, nil, nil, nil, nil, 309, 310, + 316, 103, 102, 104, 105, nil, nil, 234, nil, nil, + nil, nil, nil, nil, 311, nil, nil, 107, 106, 108, + 356, 56, 99, 98, 357, nil, 101, 109, 110, nil, + 93, 94, nil, nil, 317, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 358, nil, nil, 233, nil, nil, + 58, 59, nil, nil, 60, nil, nil, 672, nil, 669, + 668, 667, 677, 670, nil, nil, nil, nil, nil, nil, + nil, nil, 680, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, nil, nil, 675, 62, nil, 83, 95, 96, + 74, 75, 71, 9, 57, 688, 687, nil, 63, 64, + 681, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 103, 102, 104, 105, nil, nil, 19, nil, nil, nil, + nil, nil, 8, 45, 7, 10, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 40, nil, nil, 33, nil, nil, 58, + 59, nil, nil, 60, nil, 35, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, nil, nil, 391, 62, nil, 83, 95, 96, 74, + 75, 71, nil, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, 233, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 103, 102, 104, 105, nil, nil, 19, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 103, 102, 104, 105, nil, nil, 19, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, 233, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 20, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 103, 102, 104, 105, nil, nil, 19, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, 233, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 20, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, nil, nil, nil, 62, nil, 83, 95, + 96, 74, 75, 71, 9, 57, nil, nil, nil, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 103, 102, 104, 105, nil, nil, 19, nil, nil, + nil, nil, nil, 8, 45, nil, 10, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 40, nil, nil, 33, nil, nil, + 58, 59, nil, nil, 60, nil, 35, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 20, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 103, 102, 104, 105, nil, nil, 234, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, 233, nil, + nil, 58, 59, nil, nil, 60, nil, 407, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 232, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 30, 31, 72, 73, nil, nil, nil, nil, nil, + 29, 28, 27, 103, 102, 104, 105, nil, nil, 234, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, 233, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 232, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 30, 31, 72, 73, nil, nil, nil, nil, + nil, 29, 28, 27, 103, 102, 104, 105, nil, nil, + 234, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, 288, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + 233, nil, nil, 58, 59, nil, nil, 60, nil, 285, + nil, 283, nil, 44, nil, nil, 289, nil, nil, nil, + nil, nil, 232, nil, nil, nil, nil, 91, 286, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 234, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 233, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 232, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 234, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 233, nil, nil, 58, 59, nil, nil, 60, + nil, 407, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 232, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 103, 102, 104, + 105, nil, nil, 19, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, 233, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 103, 102, + 104, 105, nil, nil, 19, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, 233, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 20, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, 233, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 103, 102, 104, 105, nil, nil, 19, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, 222, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 313, + 314, 72, 73, nil, nil, nil, nil, nil, 309, 310, + 316, 103, 102, 104, 105, nil, nil, 234, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, 233, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 232, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 313, 314, 72, 73, nil, nil, nil, nil, nil, 309, + 310, 316, 103, 102, 104, 105, nil, nil, 234, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, 233, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 232, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 313, 314, 72, 73, nil, nil, nil, nil, nil, + 309, 310, 316, 103, 102, 104, 105, nil, nil, 234, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, 233, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 232, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 313, 314, 72, 73, nil, nil, nil, nil, + nil, 309, 310, 316, 103, 102, 104, 105, nil, nil, + 234, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + 233, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 232, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 313, 314, 72, 73, nil, nil, nil, + nil, nil, 309, 310, 316, 103, 102, 104, 105, nil, + nil, 234, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 233, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 232, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 313, 314, 72, 73, nil, nil, + nil, nil, nil, 309, 310, 316, 103, 102, 104, 105, + nil, nil, 234, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 233, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 232, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 313, 314, 72, 73, nil, + nil, nil, nil, nil, 309, 310, 316, 103, 102, 104, + 105, nil, nil, 234, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, 233, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 232, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 313, 314, 72, 73, + nil, nil, nil, nil, nil, 309, 310, 316, 103, 102, + 104, 105, nil, nil, 234, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, 233, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 232, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 313, 314, 72, + 73, nil, nil, nil, nil, nil, 309, 310, 316, 103, + 102, 104, 105, nil, nil, 234, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, 233, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 232, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 313, 314, + 72, 73, nil, nil, nil, nil, nil, 309, 310, 316, + 103, 102, 104, 105, nil, nil, 234, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 232, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 313, + 314, 72, 73, nil, nil, nil, nil, nil, 309, 310, + 316, 103, 102, 104, 105, nil, nil, 234, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, 233, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 232, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 313, 314, 72, 73, nil, nil, nil, nil, nil, 309, + 310, 316, 103, 102, 104, 105, nil, nil, 234, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, 233, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 232, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 313, 314, 72, 73, nil, nil, nil, nil, nil, + 309, 310, 316, 103, 102, 104, 105, nil, nil, 234, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, 233, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 232, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 313, 314, 72, 73, nil, nil, nil, nil, + nil, 309, 310, 316, 103, 102, 104, 105, nil, nil, + 234, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + 233, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 232, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 313, 314, 72, 73, nil, nil, nil, + nil, nil, 309, 310, 316, 103, 102, 104, 105, nil, + nil, 234, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 233, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 232, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 313, 314, 72, 73, nil, nil, + nil, nil, nil, 309, 310, 316, 103, 102, 104, 105, + nil, nil, 234, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 233, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 232, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 313, 314, 72, 73, nil, + nil, nil, nil, nil, 309, 310, 316, 103, 102, 104, + 105, nil, nil, 234, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, 233, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 232, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 313, 314, 72, 73, + nil, nil, nil, nil, nil, 309, 310, 316, 103, 102, + 104, 105, nil, nil, 234, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, 233, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 232, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 313, 314, 72, + 73, nil, nil, nil, nil, nil, 309, 310, 316, 103, + 102, 104, 105, nil, nil, 234, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, 233, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 232, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 313, 314, + 72, 73, nil, nil, nil, nil, nil, 309, 310, 316, + 103, 102, 104, 105, nil, nil, 234, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 232, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 313, + 314, 72, 73, nil, nil, nil, nil, nil, 309, 310, + 316, 103, 102, 104, 105, nil, nil, 234, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, 233, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 232, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 313, 314, 72, 73, nil, nil, nil, nil, nil, 309, + 310, 316, 103, 102, 104, 105, nil, nil, 234, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, 233, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 232, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 313, 314, 72, 73, nil, nil, nil, nil, nil, + 309, 310, 316, 103, 102, 104, 105, nil, nil, 234, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, 233, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 232, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 313, 314, 72, 73, nil, nil, nil, nil, + nil, 309, 310, 316, 103, 102, 104, 105, nil, nil, + 234, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + 233, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 232, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 313, 314, 72, 73, nil, nil, nil, + nil, nil, 309, 310, 316, 103, 102, 104, 105, nil, + nil, 234, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 233, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 232, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 313, 314, 72, 73, nil, nil, + nil, nil, nil, 309, 310, 316, 103, 102, 104, 105, + nil, nil, 234, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 233, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 232, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 313, 314, 72, 73, nil, + nil, nil, nil, nil, 309, 310, 316, 103, 102, 104, + 105, nil, nil, 234, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, 233, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 232, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 103, 102, + 104, 105, nil, nil, 234, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, 288, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, 233, nil, nil, 58, 59, nil, + nil, 60, nil, 285, nil, 283, nil, 44, nil, nil, + 289, nil, nil, nil, nil, nil, 232, nil, nil, nil, + nil, 91, 286, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 234, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, 288, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, 233, nil, nil, 58, 59, + nil, nil, 60, nil, 285, nil, 283, nil, 44, nil, + nil, 289, nil, nil, nil, nil, nil, 232, nil, nil, + nil, nil, 91, 286, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 103, 102, 104, 105, nil, nil, 234, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, 288, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, 285, nil, 283, nil, 44, + nil, nil, 289, nil, nil, nil, nil, nil, 232, nil, + nil, nil, nil, 91, 286, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, 222, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 313, + 314, 72, 73, nil, nil, nil, nil, nil, 309, 310, + 316, 103, 102, 104, 105, nil, nil, 234, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, 233, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 232, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 313, 314, 72, 73, nil, nil, nil, nil, nil, 309, + 310, 316, 103, 102, 104, 105, nil, nil, 234, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, 233, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 232, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 313, 314, 72, 73, nil, nil, nil, nil, nil, + 309, 310, 316, 103, 102, 104, 105, nil, nil, 234, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, 233, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 232, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 313, 314, 72, 73, nil, nil, nil, nil, + nil, 309, 310, 316, 103, 102, 104, 105, nil, nil, + 234, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + 233, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 232, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, nil, nil, nil, 62, nil, + 83, 95, 96, 74, 75, 71, 9, 57, nil, nil, + nil, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 30, 31, 72, 73, nil, nil, nil, nil, nil, + 29, 28, 27, 103, 102, 104, 105, nil, nil, 19, + nil, nil, nil, nil, nil, 8, 45, nil, 10, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 40, nil, nil, 33, + nil, nil, 58, 59, nil, nil, 60, nil, 35, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 20, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 313, 314, 72, 73, nil, nil, nil, nil, + nil, 309, 310, 316, 103, 102, 104, 105, nil, nil, + 234, nil, nil, nil, nil, nil, nil, 311, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, nil, nil, 317, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 307, nil, nil, + 233, nil, nil, 58, 59, nil, nil, 60, nil, nil, + 672, nil, 669, 668, 667, 677, 670, nil, nil, nil, + nil, nil, nil, nil, nil, 680, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 507, nil, 675, 62, nil, + 83, 95, 96, 74, 75, 71, nil, 57, 688, 687, + nil, 63, 64, 681, nil, nil, 67, nil, 65, 66, + 68, 313, 314, 72, 73, nil, nil, nil, nil, nil, + 309, 310, 316, 103, 102, 104, 105, nil, nil, 234, + nil, nil, nil, nil, nil, nil, 311, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, nil, nil, 317, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 307, nil, nil, 303, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 313, 314, 72, 73, nil, nil, nil, nil, + nil, 309, 310, 316, 103, 102, 104, 105, nil, nil, + 234, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + 233, 523, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 232, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 233, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 233, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 20, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 103, 102, 104, + 105, nil, nil, 19, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, 233, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 103, 102, + 104, 105, nil, nil, 19, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, 233, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 20, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, 233, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 313, 314, + 72, 73, nil, nil, nil, nil, nil, 309, 310, 316, + 103, 102, 104, 105, nil, nil, 234, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 232, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 103, 102, 104, 105, nil, nil, 234, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, 288, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, 233, nil, nil, + 58, 59, nil, nil, 60, nil, 285, nil, 283, nil, + 44, nil, nil, 289, nil, nil, nil, nil, nil, 232, + nil, nil, nil, nil, 91, 286, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 313, 314, 72, 73, nil, nil, nil, nil, nil, 309, + 310, 316, 103, 102, 104, 105, nil, nil, 234, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, 233, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 232, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 313, 314, 72, 73, nil, nil, nil, nil, nil, + 309, 310, 316, 103, 102, 104, 105, nil, nil, 234, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, 233, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 232, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 313, 314, 72, 73, nil, nil, nil, nil, + nil, 309, 310, 316, 103, 102, 104, 105, nil, nil, + 234, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + 233, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 232, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 313, 314, 72, 73, nil, nil, nil, + nil, nil, 309, 310, 316, 103, 102, 104, 105, nil, + nil, 234, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, 288, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 233, nil, nil, 58, 59, nil, nil, 60, nil, + 629, nil, 283, nil, 44, nil, nil, 289, nil, nil, + nil, nil, nil, 232, nil, nil, nil, nil, 91, 286, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 313, 314, 72, 73, nil, nil, + nil, nil, nil, 309, 310, 316, 103, 102, 104, 105, + nil, nil, 234, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + 288, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 233, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, 283, nil, 44, nil, nil, 289, nil, + nil, nil, nil, nil, 232, nil, nil, nil, nil, 91, + 286, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 313, 314, 72, 73, nil, + nil, nil, nil, nil, 309, 310, 316, 103, 102, 104, + 105, nil, nil, 234, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, 233, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 232, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, nil, nil, + nil, 62, nil, 83, 95, 96, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + 296, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 20, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, nil, nil, 391, + 62, nil, 83, 95, 96, 74, 75, 71, nil, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 313, 314, 72, 73, nil, nil, nil, + nil, nil, 309, 310, 316, 103, 102, 104, 105, nil, + nil, 234, nil, nil, nil, nil, nil, nil, 311, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, nil, nil, 317, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 307, nil, + nil, 303, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 234, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + 288, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 233, nil, nil, 58, 59, nil, nil, 60, + nil, 285, nil, 283, nil, 44, nil, nil, 289, nil, + nil, nil, nil, nil, 232, nil, nil, nil, nil, 91, + 286, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 313, 314, 72, 73, nil, + nil, nil, nil, nil, 309, 310, 316, 103, 102, 104, + 105, nil, nil, 234, nil, nil, nil, nil, nil, nil, + 311, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, nil, nil, + 317, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 307, nil, nil, 303, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 313, 314, 72, 73, + nil, nil, nil, nil, nil, 309, 310, 316, 103, 102, + 104, 105, nil, nil, 234, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, 233, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 232, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 313, 314, 72, + 73, nil, nil, nil, nil, nil, 309, 310, 316, 103, + 102, 104, 105, nil, nil, 234, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, 233, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 232, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 103, 102, 104, 105, nil, nil, 19, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 313, + 314, 72, 73, nil, nil, nil, nil, nil, 309, 310, + 316, 103, 102, 104, 105, nil, nil, 234, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, 288, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, 233, nil, nil, + 58, 59, nil, nil, 60, nil, 629, nil, nil, nil, + 44, nil, nil, 289, nil, nil, nil, nil, nil, 232, + nil, nil, nil, nil, 91, 286, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 313, 314, 72, 73, nil, nil, nil, nil, nil, 309, + 310, 316, 103, 102, 104, 105, nil, nil, 234, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, 288, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, 233, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, 289, nil, nil, nil, nil, nil, + 232, nil, nil, nil, nil, 91, 286, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 313, 314, 72, 73, nil, nil, nil, nil, nil, + 309, 310, 316, 103, 102, 104, 105, nil, nil, 234, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, 233, + nil, nil, 58, 59, nil, nil, 60, nil, 285, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 232, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 30, 31, 72, 73, nil, nil, nil, nil, + nil, 29, 28, 27, 103, 102, 104, 105, nil, nil, + 234, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, 288, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + 233, nil, nil, 58, 59, nil, nil, 60, nil, 285, + nil, 283, nil, 44, nil, nil, 289, nil, nil, nil, + nil, nil, 232, nil, nil, nil, nil, 91, 286, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 234, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, 288, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 233, nil, nil, 58, 59, nil, nil, 60, nil, + 285, nil, 283, nil, 44, nil, nil, 289, nil, nil, + nil, nil, nil, 232, nil, nil, nil, nil, 91, 286, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 313, 314, 72, 73, nil, nil, + nil, nil, nil, 309, 310, 316, 103, 102, 104, 105, + nil, nil, 234, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 233, nil, nil, 58, 59, nil, nil, 60, + nil, 733, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 232, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 313, 314, 72, 73, nil, + nil, nil, nil, nil, 309, 310, 316, 103, 102, 104, + 105, nil, nil, 234, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, 233, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 232, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 313, 314, 72, 73, + nil, nil, nil, nil, nil, 309, 310, 316, 103, 102, + 104, 105, nil, nil, 234, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, 288, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, 233, nil, nil, 58, 59, nil, + nil, 60, nil, 629, nil, 283, nil, 44, nil, nil, + 289, nil, nil, nil, nil, nil, 232, nil, nil, nil, + nil, 91, 286, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 313, 314, 72, + 73, nil, nil, nil, nil, nil, 309, 310, 316, 103, + 102, 104, 105, nil, nil, 234, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, 288, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, 233, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, 283, nil, 44, nil, + nil, 289, nil, nil, nil, nil, nil, 232, nil, nil, + nil, nil, 91, 286, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 103, 102, 104, 105, nil, nil, 234, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 232, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 103, 102, 104, 105, nil, nil, 234, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, 233, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 232, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 103, 102, 104, 105, nil, nil, 234, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, 233, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 232, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 30, 31, 72, 73, nil, nil, nil, nil, nil, + 29, 28, 27, 103, 102, 104, 105, nil, nil, 234, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, 233, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 232, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 30, 31, 72, 73, nil, nil, nil, nil, + nil, 29, 28, 27, 103, 102, 104, 105, nil, nil, + 234, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + 233, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 232, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 313, 314, 72, 73, nil, nil, nil, + nil, nil, 309, 310, 316, 103, 102, 104, 105, nil, + nil, 234, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 233, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 232, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 313, 314, 72, 73, nil, nil, + nil, nil, nil, 309, 310, 316, 103, 102, 104, 105, + nil, nil, 234, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 233, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 232, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 313, 314, 72, 73, nil, + nil, nil, nil, nil, 309, 310, 316, 103, 102, 104, + 105, nil, nil, 234, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, 233, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 232, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 313, 314, 72, 73, + nil, nil, nil, nil, nil, 309, 310, 316, 103, 102, + 104, 105, nil, nil, 234, nil, nil, nil, nil, nil, + nil, 311, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, nil, + nil, 317, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 307, nil, nil, 303, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 313, 314, 72, + 73, nil, nil, nil, nil, nil, 309, 310, 316, 103, + 102, 104, 105, nil, nil, 234, nil, nil, nil, nil, + nil, nil, 311, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + nil, nil, 317, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 307, nil, nil, 303, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 313, 314, + 72, 73, nil, nil, nil, nil, nil, 309, 310, 316, + 103, 102, 104, 105, nil, nil, 234, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, 407, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 232, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 313, + 314, 72, 73, nil, nil, nil, nil, nil, 309, 310, + 316, 103, 102, 104, 105, nil, nil, 234, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, 233, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 232, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 103, 102, 104, 105, nil, nil, 19, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, 233, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 20, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 30, 31, 72, 73, nil, nil, nil, nil, nil, + 29, 28, 27, 103, 102, 104, 105, nil, nil, 19, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, 233, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 20, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 313, 314, 72, 73, nil, nil, nil, nil, + nil, 309, 310, 316, 103, 102, 104, 105, nil, nil, + 234, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + 233, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 232, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 234, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 233, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 232, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 313, 314, 72, 73, nil, nil, + nil, nil, nil, 309, 310, 316, 103, 102, 104, 105, + nil, nil, 234, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 233, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 232, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 313, 314, 72, 73, nil, + nil, nil, nil, nil, 309, 310, 316, 103, 102, 104, + 105, nil, nil, 234, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, 233, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 232, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 313, 314, 72, 73, + nil, nil, nil, nil, nil, 309, 310, 316, 103, 102, + 104, 105, nil, nil, 234, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, 233, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 232, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 313, 314, 72, + 73, nil, nil, nil, nil, nil, 309, 310, 316, 103, + 102, 104, 105, nil, nil, 234, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, 233, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 232, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 313, 314, + 72, 73, nil, nil, nil, nil, nil, 309, 310, 316, + 103, 102, 104, 105, nil, nil, 234, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 232, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 313, + 314, 72, 73, nil, nil, nil, nil, nil, 309, 310, + 316, 103, 102, 104, 105, nil, nil, 234, nil, nil, + nil, nil, nil, nil, 311, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, nil, nil, 317, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 856, nil, nil, 233, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 313, 314, 72, 73, nil, nil, nil, nil, nil, 309, + 310, 316, 103, 102, 104, 105, nil, nil, 234, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, 233, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 232, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 30, 31, 72, 73, nil, nil, nil, nil, nil, + 29, 28, 27, 103, 102, 104, 105, nil, nil, 19, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, 233, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 20, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 313, 314, 72, 73, nil, nil, nil, nil, + nil, 309, 310, 316, 103, 102, 104, 105, nil, nil, + 234, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + 233, nil, nil, 58, 59, nil, nil, 60, nil, 629, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 232, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 313, 314, 72, 73, nil, nil, nil, + nil, nil, 309, 310, 316, 103, 102, 104, 105, nil, + nil, 234, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, 288, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 233, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, 283, nil, 44, nil, nil, 289, nil, nil, + nil, nil, nil, 232, nil, nil, nil, nil, 91, 286, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 313, 314, 72, 73, nil, nil, + nil, nil, nil, 309, 310, 316, 103, 102, 104, 105, + nil, nil, 234, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 233, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 232, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 313, 314, 72, 73, nil, + nil, nil, nil, nil, 309, 310, 316, 103, 102, 104, + 105, nil, nil, 234, nil, nil, nil, nil, nil, nil, + 311, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, nil, nil, + 317, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 856, nil, nil, 233, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 313, 314, 72, 73, + nil, nil, nil, nil, nil, 309, 310, 316, 103, 102, + 104, 105, nil, nil, 234, nil, nil, nil, nil, nil, + nil, 311, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, nil, + nil, 317, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 930, nil, nil, 233, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 234, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, 288, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, 233, nil, nil, 58, 59, + nil, nil, 60, nil, 285, nil, 283, nil, 44, nil, + nil, 289, nil, nil, nil, nil, nil, 232, nil, nil, + nil, nil, 91, 286, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 175, 186, + 176, 199, 172, 192, 182, 181, 202, 203, 197, 180, + 179, 174, 200, 204, 205, 184, 173, 187, 191, 193, + 185, 178, nil, nil, nil, 194, 201, 196, 195, 188, + 198, 183, 171, 190, 189, nil, nil, nil, nil, nil, + 170, 177, 168, 169, 165, 166, 167, 126, 128, 125, + nil, 127, nil, nil, nil, nil, nil, nil, nil, 159, + 160, nil, 156, 138, 139, 140, 147, 144, 146, nil, + nil, 141, 142, nil, nil, nil, 161, 162, 148, 149, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 153, 152, nil, 137, 158, 155, 154, + 163, 150, 151, 145, 143, 135, 157, 136, nil, nil, + 164, 91, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 90, 175, 186, 176, 199, + 172, 192, 182, 181, 202, 203, 197, 180, 179, 174, + 200, 204, 205, 184, 173, 187, 191, 193, 185, 178, + nil, nil, nil, 194, 201, 196, 195, 188, 198, 183, + 171, 190, 189, nil, nil, nil, nil, nil, 170, 177, + 168, 169, 165, 166, 167, 126, 128, nil, nil, 127, + nil, nil, nil, nil, nil, nil, nil, 159, 160, nil, + 156, 138, 139, 140, 147, 144, 146, nil, nil, 141, + 142, nil, nil, nil, 161, 162, 148, 149, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 153, 152, nil, 137, 158, 155, 154, 163, 150, + 151, 145, 143, 135, 157, 136, nil, nil, 164, 91, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 90, 175, 186, 176, 199, 172, 192, + 182, 181, 202, 203, 197, 180, 179, 174, 200, 204, + 205, 184, 173, 187, 191, 193, 185, 178, nil, nil, + nil, 194, 201, 196, 195, 188, 198, 183, 171, 190, + 189, nil, nil, nil, nil, nil, 170, 177, 168, 169, + 165, 166, 167, 126, 128, nil, nil, 127, nil, nil, + nil, nil, nil, nil, nil, 159, 160, nil, 156, 138, + 139, 140, 147, 144, 146, nil, nil, 141, 142, nil, + nil, nil, 161, 162, 148, 149, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 153, + 152, nil, 137, 158, 155, 154, 163, 150, 151, 145, + 143, 135, 157, 136, nil, nil, 164, 91, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 90, 175, 186, 176, 199, 172, 192, 182, 181, + 202, 203, 197, 180, 179, 174, 200, 204, 205, 184, + 173, 187, 191, 193, 185, 178, nil, nil, nil, 194, + 201, 196, 195, 188, 198, 183, 171, 190, 189, nil, + nil, nil, nil, nil, 170, 177, 168, 169, 165, 166, + 167, 126, 128, nil, nil, 127, nil, nil, nil, nil, + nil, nil, nil, 159, 160, nil, 156, 138, 139, 140, + 147, 144, 146, nil, nil, 141, 142, nil, nil, nil, + 161, 162, 148, 149, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 153, 152, nil, + 137, 158, 155, 154, 163, 150, 151, 145, 143, 135, + 157, 136, nil, nil, 164, 91, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 90, + 175, 186, 176, 199, 172, 192, 182, 181, 202, 203, + 197, 180, 179, 174, 200, 204, 205, 184, 173, 187, + 191, 193, 185, 178, nil, nil, nil, 194, 201, 196, + 374, 373, 375, 372, 171, 190, 189, nil, nil, nil, + nil, nil, 170, 177, 168, 169, 369, 370, 371, 367, + 128, 99, 98, 368, nil, 101, nil, nil, nil, nil, + nil, 159, 160, nil, 156, 138, 139, 140, 147, 144, + 146, nil, nil, 141, 142, nil, nil, nil, 161, 162, + 148, 149, nil, nil, nil, nil, nil, 379, nil, nil, + nil, nil, nil, nil, nil, 153, 152, nil, 137, 158, + 155, 154, 163, 150, 151, 145, 143, 135, 157, 136, + nil, nil, 164, 175, 186, 176, 199, 172, 192, 182, + 181, 202, 203, 197, 180, 179, 174, 200, 204, 205, + 184, 173, 187, 191, 193, 185, 178, nil, nil, nil, + 194, 201, 196, 195, 188, 198, 183, 171, 190, 189, + nil, nil, nil, nil, nil, 170, 177, 168, 169, 165, + 166, 167, 126, 128, nil, nil, 127, nil, nil, nil, + nil, nil, nil, nil, 159, 160, nil, 156, 138, 139, + 140, 147, 144, 146, nil, nil, 141, 142, nil, nil, + nil, 161, 162, 148, 149, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 153, 152, + nil, 137, 158, 155, 154, 163, 150, 151, 145, 143, + 135, 157, 136, 416, 420, 164, nil, 417, nil, nil, + nil, nil, nil, nil, nil, 159, 160, nil, 156, 138, + 139, 140, 147, 144, 146, nil, nil, 141, 142, nil, + nil, nil, 161, 162, 148, 149, nil, nil, nil, nil, + nil, 267, nil, nil, nil, nil, nil, nil, nil, 153, + 152, nil, 137, 158, 155, 154, 163, 150, 151, 145, + 143, 135, 157, 136, 423, 427, 164, nil, 422, nil, + nil, nil, nil, nil, nil, nil, 159, 160, nil, 156, + 138, 139, 140, 147, 144, 146, nil, nil, 141, 142, + nil, nil, nil, 161, 162, 148, 149, nil, nil, nil, + nil, nil, 267, nil, nil, nil, nil, nil, nil, nil, + 153, 152, nil, 137, 158, 155, 154, 163, 150, 151, + 145, 143, 135, 157, 136, 478, 420, 164, nil, 479, + nil, nil, nil, nil, nil, nil, nil, 159, 160, nil, + 156, 138, 139, 140, 147, 144, 146, nil, nil, 141, + 142, nil, nil, nil, 161, 162, 148, 149, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 153, 152, nil, 137, 158, 155, 154, 163, 150, + 151, 145, 143, 135, 157, 136, 608, 420, 164, nil, + 609, nil, nil, nil, nil, nil, nil, nil, 159, 160, + nil, 156, 138, 139, 140, 147, 144, 146, nil, nil, + 141, 142, nil, nil, nil, 161, 162, 148, 149, nil, + nil, nil, nil, nil, 267, nil, nil, nil, nil, nil, + nil, nil, 153, 152, nil, 137, 158, 155, 154, 163, + 150, 151, 145, 143, 135, 157, 136, 610, 427, 164, + nil, 611, nil, nil, nil, nil, nil, nil, nil, 159, + 160, nil, 156, 138, 139, 140, 147, 144, 146, nil, + nil, 141, 142, nil, nil, nil, 161, 162, 148, 149, + nil, nil, nil, nil, nil, 267, nil, nil, nil, nil, + nil, nil, nil, 153, 152, nil, 137, 158, 155, 154, + 163, 150, 151, 145, 143, 135, 157, 136, 640, 420, + 164, nil, 641, nil, nil, nil, nil, nil, nil, nil, + 159, 160, nil, 156, 138, 139, 140, 147, 144, 146, + nil, nil, 141, 142, nil, nil, nil, 161, 162, 148, + 149, nil, nil, nil, nil, nil, 267, nil, nil, nil, + nil, nil, nil, nil, 153, 152, nil, 137, 158, 155, + 154, 163, 150, 151, 145, 143, 135, 157, 136, 643, + 427, 164, nil, 644, nil, nil, nil, nil, nil, nil, + nil, 159, 160, nil, 156, 138, 139, 140, 147, 144, + 146, nil, nil, 141, 142, nil, nil, nil, 161, 162, + 148, 149, nil, nil, nil, nil, nil, 267, nil, nil, + nil, nil, nil, nil, nil, 153, 152, nil, 137, 158, + 155, 154, 163, 150, 151, 145, 143, 135, 157, 136, + 608, 420, 164, nil, 609, nil, nil, nil, nil, nil, + nil, nil, 159, 160, nil, 156, 138, 139, 140, 147, + 144, 146, nil, nil, 141, 142, nil, nil, nil, 161, + 162, 148, 149, nil, nil, nil, nil, nil, 267, nil, + nil, nil, nil, nil, nil, nil, 153, 152, nil, 137, + 158, 155, 154, 163, 150, 151, 145, 143, 135, 157, + 136, 610, 427, 164, nil, 611, nil, nil, nil, nil, + nil, nil, nil, 159, 160, nil, 156, 138, 139, 140, + 147, 144, 146, nil, nil, 141, 142, nil, nil, nil, + 161, 162, 148, 149, nil, nil, nil, nil, nil, 267, + nil, nil, nil, nil, nil, nil, nil, 153, 152, nil, + 137, 158, 155, 154, 163, 150, 151, 145, 143, 135, + 157, 136, 701, 420, 164, nil, 702, nil, nil, nil, + nil, nil, nil, nil, 159, 160, nil, 156, 138, 139, + 140, 147, 144, 146, nil, nil, 141, 142, nil, nil, + nil, 161, 162, 148, 149, nil, nil, nil, nil, nil, + 267, nil, nil, nil, nil, nil, nil, nil, 153, 152, + nil, 137, 158, 155, 154, 163, 150, 151, 145, 143, + 135, 157, 136, 703, 427, 164, nil, 704, nil, nil, + nil, nil, nil, nil, nil, 159, 160, nil, 156, 138, + 139, 140, 147, 144, 146, nil, nil, 141, 142, nil, + nil, nil, 161, 162, 148, 149, nil, nil, nil, nil, + nil, 267, nil, nil, nil, nil, nil, nil, nil, 153, + 152, nil, 137, 158, 155, 154, 163, 150, 151, 145, + 143, 135, 157, 136, 706, 427, 164, nil, 707, nil, + nil, nil, nil, nil, nil, nil, 159, 160, nil, 156, + 138, 139, 140, 147, 144, 146, nil, nil, 141, 142, + nil, nil, nil, 161, 162, 148, 149, nil, nil, nil, + nil, nil, 267, nil, nil, nil, nil, nil, nil, nil, + 153, 152, nil, 137, 158, 155, 154, 163, 150, 151, + 145, 143, 135, 157, 136, 478, 420, 164, nil, 479, + nil, nil, nil, nil, nil, nil, nil, 159, 160, nil, + 156, 138, 139, 140, 147, 144, 146, nil, nil, 141, + 142, nil, nil, nil, 161, 162, 148, 149, nil, nil, + nil, nil, nil, 267, nil, nil, nil, nil, nil, nil, + nil, 153, 152, nil, 137, 158, 155, 154, 163, 150, + 151, 145, 143, 135, 157, 136, 973, 427, 164, nil, + 972, nil, nil, nil, nil, nil, nil, nil, 159, 160, + nil, 156, 138, 139, 140, 147, 144, 146, nil, nil, + 141, 142, nil, nil, nil, 161, 162, 148, 149, nil, + nil, nil, nil, nil, 267, nil, nil, nil, nil, nil, + nil, nil, 153, 152, nil, 137, 158, 155, 154, 163, + 150, 151, 145, 143, 135, 157, 136, 999, 420, 164, + nil, 1000, nil, nil, nil, nil, nil, nil, nil, 159, + 160, nil, 156, 138, 139, 140, 147, 144, 146, nil, + nil, 141, 142, nil, nil, nil, 161, 162, 148, 149, + nil, nil, nil, nil, nil, 267, nil, nil, nil, nil, + nil, nil, nil, 153, 152, nil, 137, 158, 155, 154, + 163, 150, 151, 145, 143, 135, 157, 136, 1001, 427, + 164, nil, 1002, nil, nil, nil, nil, nil, nil, nil, + 159, 160, nil, 156, 138, 139, 140, 147, 144, 146, + nil, nil, 141, 142, nil, nil, nil, 161, 162, 148, + 149, nil, nil, nil, nil, nil, 267, nil, nil, nil, + nil, nil, nil, nil, 153, 152, nil, 137, 158, 155, + 154, 163, 150, 151, 145, 143, 135, 157, 136, nil, + 672, 164, 669, 668, 667, 677, 670, nil, 672, nil, + 669, 668, 667, 677, 670, 680, nil, nil, nil, nil, + nil, nil, nil, 680, nil, 672, nil, 669, 668, 667, + 677, 670, nil, nil, nil, nil, nil, 675, nil, nil, + 680, nil, nil, nil, nil, 675, 685, 684, 688, 687, + nil, nil, nil, 681, 685, 684, 688, 687, nil, nil, + nil, 681, 675, nil, 672, nil, 669, 668, 667, 677, + 670, 685, 684, 688, 687, nil, nil, nil, 681, 680, + nil, 672, nil, 669, 668, 667, 677, 670, nil, 672, + nil, 669, 668, 667, 677, 670, 680, nil, nil, nil, + nil, 675, nil, nil, 680, nil, nil, nil, nil, nil, + 685, 684, 688, 687, nil, nil, nil, 681, 675, nil, + nil, nil, nil, nil, nil, nil, 675, 685, 684, 688, + 687, nil, nil, nil, 681, 685, 684, 688, 687, nil, + nil, 672, 681, 669, 668, 667, 677, 670, nil, 672, + nil, 669, 668, 667, 677, 670, 680, nil, nil, nil, + nil, nil, nil, nil, 680, nil, 672, nil, 669, 668, + 667, 677, 670, nil, nil, nil, nil, nil, 675, nil, + nil, 680, nil, nil, nil, nil, 675, 685, 684, 688, + 687, nil, nil, nil, 681, 685, 684, 688, 687, nil, + nil, nil, 681, 675, nil, 672, nil, 669, 668, 667, + 677, 670, nil, nil, 688, 687, nil, nil, nil, 681, + 680, nil, 672, nil, 669, 668, 667, 677, 670, 672, + nil, 669, 668, 667, 677, 670, nil, 680, nil, nil, + nil, nil, 675, nil, 680, nil, 672, nil, 669, 668, + 667, 677, 670, 688, 687, nil, nil, nil, 681, 675, + nil, 680, nil, nil, nil, nil, 675, nil, 685, 684, + 688, 687, nil, nil, nil, 681, nil, 688, 687, nil, + nil, nil, 681, 675, nil, 672, nil, 669, 668, 667, + 677, 670, nil, nil, 688, 687, nil, nil, nil, 681, + 680, nil, 672, nil, 669, 668, 667, 677, 670, 672, + nil, 669, 668, 667, 677, 670, nil, 680, nil, nil, + nil, nil, 675, nil, 680, nil, nil, nil, nil, nil, + nil, nil, nil, 688, 687, nil, nil, nil, 681, 675, + nil, nil, nil, nil, nil, nil, 675, nil, nil, nil, + 688, 687, nil, nil, nil, 681, nil, 688, 687, nil, + nil, nil, 681 ] + +racc_action_check = [ + 97, 440, 440, 564, 564, 15, 348, 97, 97, 97, + 58, 341, 97, 97, 97, 24, 97, 26, 19, 386, + 476, 484, 24, 342, 97, 387, 97, 97, 97, 61, + 358, 620, 225, 1, 358, 349, 97, 97, 699, 97, + 97, 97, 97, 97, 865, 892, 927, 928, 931, 352, + 58, 550, 15, 635, 978, 476, 484, 332, 312, 19, + 332, 7, 15, 635, 485, 701, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 24, 26, 97, 97, 97, 386, 97, 97, 542, 225, + 97, 387, 702, 97, 97, 440, 97, 564, 97, 485, + 97, 10, 97, 97, 26, 97, 97, 97, 97, 97, + 999, 97, 100, 97, 1000, 348, 61, 792, 620, 100, + 100, 100, 312, 1001, 100, 100, 100, 97, 100, 341, + 97, 97, 97, 97, 341, 97, 100, 97, 100, 100, + 100, 342, 97, 97, 349, 312, 342, 640, 100, 100, + 1002, 100, 100, 100, 100, 100, 699, 1020, 352, 699, + 550, 699, 865, 892, 927, 928, 931, 865, 892, 927, + 928, 931, 978, 543, 701, 703, 824, 978, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 542, 12, 100, 100, 100, 542, 100, 100, + 1001, 702, 100, 13, 641, 100, 100, 825, 100, 704, + 100, 3, 100, 640, 100, 100, 3, 100, 100, 100, + 100, 100, 422, 100, 226, 100, 792, 1002, 999, 422, + 422, 422, 1000, 999, 621, 422, 422, 1000, 422, 100, + 703, 1001, 100, 100, 100, 100, 1001, 100, 16, 100, + 650, 650, 228, 640, 100, 100, 640, 22, 422, 422, + 780, 422, 422, 422, 422, 422, 640, 37, 1002, 621, + 641, 367, 643, 1002, 704, 1020, 333, 543, 367, 333, + 1020, 226, 543, 446, 703, 824, 560, 560, 422, 422, + 422, 422, 422, 422, 422, 422, 422, 422, 422, 422, + 422, 422, 40, 608, 422, 422, 422, 368, 422, 228, + 641, 825, 422, 641, 368, 422, 825, 897, 704, 897, + 422, 45, 422, 641, 422, 422, 780, 422, 422, 422, + 422, 422, 381, 422, 423, 422, 367, 643, 643, 79, + 446, 423, 423, 423, 650, 17, 17, 423, 423, 422, + 423, 79, 422, 422, 111, 422, 206, 422, 292, 423, + 608, 79, 227, 292, 422, 422, 780, 356, 38, 780, + 423, 423, 368, 423, 423, 423, 423, 423, 643, 780, + 560, 643, 340, 340, 229, 560, 809, 609, 809, 809, + 809, 643, 809, 41, 41, 230, 381, 381, 381, 234, + 423, 423, 423, 423, 423, 423, 423, 423, 423, 423, + 423, 423, 423, 423, 266, 38, 423, 423, 423, 356, + 423, 317, 317, 495, 423, 38, 356, 423, 345, 753, + 280, 356, 423, 345, 423, 356, 423, 423, 39, 423, + 423, 423, 423, 423, 609, 423, 423, 423, 575, 948, + 577, 948, 948, 948, 356, 948, 369, 828, 281, 357, + 284, 423, 828, 369, 423, 423, 610, 423, 809, 423, + 296, 41, 41, 610, 610, 610, 423, 423, 610, 610, + 610, 297, 610, 299, 356, 39, 753, 495, 495, 495, + 370, 610, 610, 610, 610, 39, 833, 370, 300, 317, + 317, 833, 610, 610, 495, 610, 610, 610, 610, 610, + 301, 357, 575, 575, 577, 577, 382, 336, 357, 383, + 336, 369, 575, 357, 577, 384, 656, 357, 307, 656, + 310, 948, 610, 610, 610, 610, 610, 610, 610, 610, + 610, 610, 610, 610, 610, 610, 357, 311, 610, 610, + 610, 917, 610, 610, 917, 370, 610, 385, 321, 610, + 610, 388, 610, 371, 610, 316, 610, 416, 610, 610, + 371, 610, 610, 610, 610, 610, 357, 610, 610, 610, + 382, 382, 382, 383, 383, 383, 318, 372, 322, 384, + 384, 384, 325, 610, 372, 330, 610, 610, 610, 610, + 334, 610, 335, 610, 611, 321, 526, 526, 610, 610, + 337, 611, 611, 611, 416, 321, 611, 611, 611, 346, + 611, 385, 385, 385, 416, 388, 388, 388, 371, 125, + 611, 611, 611, 347, 125, 125, 690, 690, 417, 351, + 611, 611, 353, 611, 611, 611, 611, 611, 362, 14, + 397, 46, 372, 224, 373, 374, 14, 403, 46, 375, + 224, 373, 374, 797, 797, 14, 375, 46, 406, 224, + 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, + 611, 611, 611, 611, 408, 417, 611, 611, 611, 452, + 611, 611, 304, 412, 611, 417, 377, 611, 611, 304, + 611, 414, 611, 377, 611, 591, 611, 611, 304, 611, + 611, 611, 611, 611, 14, 611, 46, 611, 224, 373, + 374, 452, 305, 415, 375, 452, 452, 424, 453, 305, + 432, 611, 989, 989, 611, 611, 611, 611, 305, 611, + 442, 611, 27, 454, 455, 456, 611, 611, 457, 27, + 27, 27, 591, 794, 27, 27, 27, 304, 27, 482, + 453, 377, 591, 794, 453, 453, 486, 27, 27, 27, + 568, 568, 502, 503, 568, 568, 568, 506, 27, 27, + 508, 27, 27, 27, 27, 27, 889, 305, 889, 889, + 889, 306, 889, 513, 516, 524, 794, 794, 306, 525, + 675, 794, 675, 675, 675, 527, 675, 306, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 539, 889, 27, 27, 27, 544, 545, 27, + 562, 27, 27, 572, 580, 27, 27, 675, 27, 582, + 27, 588, 27, 592, 27, 27, 675, 27, 27, 27, + 27, 27, 28, 27, 27, 27, 306, 597, 602, 28, + 28, 28, 612, 614, 28, 28, 28, 308, 28, 27, + 619, 626, 27, 27, 308, 27, 628, 27, 28, 28, + 634, 637, 639, 308, 27, 642, 645, 646, 28, 28, + 649, 28, 28, 28, 28, 28, 651, 654, 660, 323, + 661, 350, 663, 664, 665, 674, 323, 806, 350, 806, + 806, 806, 682, 806, 686, 323, 689, 350, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 308, 692, 28, 28, 28, 697, 700, 28, + 709, 28, 28, 713, 806, 28, 28, 732, 28, 737, + 28, 755, 28, 806, 28, 28, 756, 28, 28, 28, + 28, 28, 56, 28, 323, 28, 350, 758, 759, 56, + 56, 56, 760, 762, 56, 56, 56, 360, 56, 28, + 763, 764, 28, 28, 360, 28, 765, 28, 56, 56, + 56, 769, 773, 360, 28, 774, 779, 783, 56, 56, + 786, 56, 56, 56, 56, 56, 787, 512, 790, 553, + 793, 855, 808, 810, 512, 815, 553, 818, 855, 827, + 831, 832, 835, 512, 836, 553, 852, 855, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 360, 921, 56, 56, 56, 856, 858, 56, + 921, 872, 56, 873, 877, 56, 56, 878, 56, 921, + 56, 880, 56, 881, 56, 56, 883, 56, 56, 56, + 56, 56, 512, 56, 553, 56, 855, 886, 842, 949, + 929, 949, 949, 949, 888, 949, 894, 929, 842, 56, + 895, 706, 56, 56, 56, 56, 929, 56, 418, 56, + 901, 905, 907, 910, 56, 418, 418, 418, 921, 911, + 418, 418, 418, 912, 418, 913, 949, 471, 915, 930, + 950, 842, 842, 418, 418, 418, 842, 853, 972, 853, + 853, 853, 973, 853, 418, 418, 974, 418, 418, 418, + 418, 418, 979, 706, 980, 929, 981, 982, 983, 471, + 706, 984, 985, 471, 471, 706, 471, 471, 987, 706, + 990, 991, 992, 993, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 706, 994, + 418, 418, 418, 644, 995, 418, 998, 418, 418, 1011, + 644, 418, 418, 1021, 418, 644, 418, 1022, 418, 644, + 418, 418, 1023, 418, 418, 418, 418, 418, 706, 418, + 418, 418, nil, 887, nil, 887, 887, 887, nil, 887, + 707, nil, nil, nil, nil, 418, nil, 707, 418, 418, + 427, 418, 707, 418, nil, nil, 707, 427, 427, 427, + 418, nil, 427, 427, 427, nil, 427, 462, 644, nil, + 887, nil, nil, nil, nil, 427, 427, 427, 427, 887, + nil, nil, nil, 462, 462, nil, 427, 427, nil, 427, + 427, 427, 427, 427, 986, nil, 986, 986, 986, 462, + 986, 462, nil, 462, 462, 707, 462, 462, nil, nil, + 462, nil, 462, nil, nil, nil, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + nil, 986, 427, 427, 427, 472, nil, 427, nil, nil, + 427, nil, nil, 427, 427, nil, 427, nil, 427, nil, + 427, nil, 427, 427, nil, 427, 427, 427, 427, 427, + nil, 427, 427, 427, nil, nil, nil, 472, nil, nil, + nil, 472, 472, nil, 472, 472, nil, 427, nil, nil, + 427, 427, 427, 427, nil, 427, 428, 427, nil, nil, + nil, nil, 427, 428, 428, 428, nil, nil, 428, 428, + 428, 463, 428, 971, nil, 971, 971, 971, nil, 971, + nil, 428, 428, 428, 428, nil, nil, 463, 463, nil, + nil, nil, 428, 428, nil, 428, 428, 428, 428, 428, + nil, nil, nil, 463, nil, 463, nil, 463, 463, nil, + 463, 463, nil, nil, 463, nil, 463, 6, 6, 6, + 6, 6, 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, nil, nil, 428, 428, + 428, nil, nil, 428, nil, nil, 428, nil, nil, 428, + 428, nil, 428, nil, 428, nil, 428, nil, 428, 428, + nil, 428, 428, 428, 428, 428, nil, 428, 428, 428, + 295, 295, 295, 295, 295, nil, nil, nil, 988, nil, + 988, 988, 988, 428, 988, nil, 428, 428, 428, 428, + nil, 428, 477, 428, nil, nil, nil, nil, 428, 477, + 477, 477, nil, nil, 477, 477, 477, 616, 477, 616, + 616, 616, 616, 616, nil, 988, nil, 477, 477, nil, + nil, nil, 616, nil, nil, nil, 460, nil, 477, 477, + nil, 477, 477, 477, 477, 477, 500, 500, 500, 500, + 500, nil, 460, 460, 616, nil, 537, nil, 537, 537, + 537, 537, 537, 616, 616, 616, 616, nil, 460, nil, + 616, 537, 460, 460, nil, 460, 460, nil, nil, 477, + nil, nil, nil, nil, 458, nil, 477, nil, nil, nil, + nil, 477, 477, 537, 537, nil, 616, nil, nil, nil, + 458, 458, 537, 537, 537, 537, nil, nil, nil, 537, + nil, nil, nil, nil, 477, 477, 458, nil, 458, nil, + 458, 458, nil, 458, 458, nil, nil, nil, nil, 477, + nil, nil, 477, nil, nil, nil, nil, 477, 0, 0, + 0, 0, 0, 0, 477, nil, nil, 0, 0, nil, + nil, nil, 0, nil, 0, 0, 0, 0, 0, 0, + 0, nil, nil, nil, nil, nil, 0, 0, 0, 0, + 0, 0, 0, nil, nil, 0, nil, nil, nil, nil, + 435, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, nil, 0, 0, 0, nil, 0, 0, + 0, 0, 0, 435, 435, 435, 435, 435, 435, 435, + 435, 435, 435, 435, nil, 435, 435, nil, nil, 435, + 435, nil, 0, nil, nil, 0, nil, nil, 0, 0, + nil, nil, 0, nil, 0, 435, nil, 435, 0, 435, + 435, nil, 435, 435, 435, 435, 435, 0, 435, nil, + nil, nil, 0, 0, 0, 0, nil, 0, 0, 0, + 0, nil, nil, nil, nil, 0, 0, nil, 435, nil, + 435, nil, nil, 0, nil, 0, 0, 0, 33, 33, + 33, 33, 33, 33, nil, nil, nil, 33, 33, nil, + nil, nil, 33, nil, 33, 33, 33, 33, 33, 33, + 33, nil, nil, nil, nil, nil, 33, 33, 33, 33, + 33, 33, 33, nil, nil, 33, nil, nil, nil, nil, + 411, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, nil, 33, 33, 33, nil, 33, 33, + 33, 33, 33, 411, 411, 411, 411, 411, 411, 411, + 411, 411, 411, 411, nil, 411, 411, nil, nil, 411, + 411, nil, 33, nil, nil, 33, nil, nil, 33, 33, + nil, nil, 33, nil, 33, 411, nil, 411, 33, 411, + 411, nil, 411, 411, 411, 411, 411, 33, 411, nil, + nil, nil, 33, 33, 33, 33, nil, 33, 33, 33, + 33, nil, nil, nil, nil, 33, 33, nil, 411, nil, + nil, nil, nil, 33, nil, 33, 33, 33, 123, 123, + 123, 123, 123, 123, nil, nil, nil, 123, 123, nil, + nil, nil, 123, nil, 123, 123, 123, 123, 123, 123, + 123, nil, nil, nil, nil, nil, 123, 123, 123, 123, + 123, 123, 123, nil, nil, 123, nil, nil, nil, nil, + 613, 123, 123, 123, 123, 123, 123, 123, 123, 123, + 123, 123, 123, nil, 123, 123, 123, nil, 123, 123, + 123, 123, 123, 613, 613, 613, 613, 613, 613, 613, + 613, 613, 613, 613, nil, 613, 613, nil, nil, 613, + 613, nil, 123, nil, nil, 123, nil, nil, 123, 123, + nil, nil, 123, nil, 123, 613, nil, 613, 123, 613, + 613, nil, 613, 613, 613, 613, 613, 123, 613, nil, + nil, nil, 123, 123, 123, 123, nil, 123, 123, 123, + 123, nil, nil, nil, nil, 123, 123, nil, 613, nil, + nil, nil, nil, 123, nil, 123, 123, 123, 208, 208, + 208, 208, 208, 208, nil, nil, nil, 208, 208, nil, + nil, nil, 208, nil, 208, 208, 208, 208, 208, 208, + 208, nil, nil, nil, nil, nil, 208, 208, 208, 208, + 208, 208, 208, nil, nil, 208, nil, nil, nil, nil, + nil, 208, 208, 208, 208, 208, 208, 208, 208, 208, + 208, 208, 208, nil, 208, 208, 208, nil, 208, 208, + 208, 208, 208, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, nil, 21, 21, nil, nil, 21, + 21, nil, 208, nil, nil, 208, nil, nil, 208, 208, + nil, nil, 208, nil, 208, 21, nil, 21, 208, 21, + 21, nil, 21, 21, 21, 21, 21, 208, 21, nil, + nil, nil, 208, 208, 208, 208, nil, 208, 208, 208, + 208, nil, nil, nil, nil, 208, 208, nil, 21, nil, + nil, nil, nil, 208, nil, 208, 208, 208, 233, 233, + 233, 233, 233, 233, nil, nil, nil, 233, 233, nil, + nil, nil, 233, nil, 233, 233, 233, 233, 233, 233, + 233, nil, nil, nil, nil, nil, 233, 233, 233, 233, + 233, 233, 233, nil, nil, 233, nil, nil, nil, nil, + nil, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 233, nil, 233, 233, 233, nil, 233, 233, + 233, 233, 233, 278, 278, 278, 278, 278, 278, 278, + 278, 278, 278, 278, nil, 278, 278, nil, nil, 278, + 278, nil, 233, nil, nil, 233, nil, nil, 233, 233, + nil, nil, 233, nil, 233, 278, nil, 278, 233, 278, + 278, nil, 278, 278, 278, 278, 278, 233, 278, nil, + nil, nil, 233, 233, 233, 233, nil, 233, 233, 233, + 233, nil, nil, nil, nil, 233, 233, nil, 278, nil, + nil, nil, nil, 233, nil, 233, 233, 233, 298, 298, + 298, 298, 298, 298, nil, nil, nil, 298, 298, nil, + nil, nil, 298, nil, 298, 298, 298, 298, 298, 298, + 298, nil, nil, nil, nil, nil, 298, 298, 298, 298, + 298, 298, 298, nil, nil, 298, nil, nil, nil, nil, + nil, 298, 298, 298, 298, 298, 298, 298, 298, 298, + 298, 298, 298, nil, 298, 298, 298, nil, 298, 298, + 298, 298, 298, 430, 430, 430, 430, 430, 430, 430, + 430, 430, 430, 430, nil, 430, 430, nil, nil, 430, + 430, nil, 298, nil, nil, 298, nil, nil, 298, 298, + nil, nil, 298, nil, 298, 430, nil, 430, 298, 430, + 430, nil, 430, 430, 430, 430, 430, 298, 430, nil, + nil, nil, 298, 298, 298, 298, nil, 298, 298, 298, + 298, nil, nil, nil, nil, 298, 298, nil, 430, nil, + nil, nil, nil, 298, nil, 298, 298, 298, 303, 303, + 303, 303, 303, 303, nil, nil, nil, 303, 303, nil, + nil, nil, 303, nil, 303, 303, 303, 303, 303, 303, + 303, nil, nil, nil, nil, nil, 303, 303, 303, 303, + 303, 303, 303, nil, nil, 303, nil, nil, nil, nil, + nil, 303, 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, nil, 303, 303, 303, nil, 303, 303, + 303, 303, 303, 475, 475, 475, 475, 475, 475, 475, + 475, 475, 475, 475, nil, 475, 475, nil, nil, 475, + 475, nil, 303, nil, nil, 303, nil, nil, 303, 303, + nil, nil, 303, nil, 303, 475, nil, 475, 303, 475, + 475, nil, 475, 475, 475, 475, 475, 303, 475, nil, + nil, nil, 303, 303, 303, 303, nil, 303, 303, 303, + 303, nil, nil, nil, nil, 303, 303, 475, 475, nil, + nil, nil, nil, 303, nil, 303, 303, 303, 328, 328, + 328, 328, 328, 328, nil, nil, nil, 328, 328, nil, + nil, nil, 328, nil, 328, 328, 328, 328, 328, 328, + 328, nil, nil, nil, nil, nil, 328, 328, 328, 328, + 328, 328, 328, nil, nil, 328, nil, nil, nil, nil, + nil, 328, 328, 328, 328, 328, 328, 328, 328, 328, + 328, 328, 328, nil, 328, 328, 328, nil, 328, 328, + 328, 328, 328, 522, 522, 522, 522, 522, 522, 522, + 522, 522, 522, 522, nil, 522, 522, nil, nil, 522, + 522, nil, 328, nil, nil, 328, nil, nil, 328, 328, + nil, nil, 328, nil, 328, 522, nil, 522, 328, 522, + 522, nil, 522, 522, 522, 522, 522, 328, 522, nil, + nil, nil, 328, 328, 328, 328, nil, 328, 328, 328, + 328, nil, nil, nil, nil, 328, 328, nil, 522, nil, + nil, nil, nil, 328, nil, 328, 328, 328, 501, 501, + 501, 501, 501, 501, nil, nil, nil, 501, 501, nil, + nil, nil, 501, nil, 501, 501, 501, 501, 501, 501, + 501, nil, nil, nil, nil, nil, 501, 501, 501, 501, + 501, 501, 501, nil, nil, 501, nil, nil, nil, nil, + nil, 501, 501, 501, 501, 501, 501, 501, 501, 501, + 501, 501, 501, nil, 501, 501, 501, nil, 501, 501, + 501, 501, 501, 648, 648, 648, 648, 648, 648, 648, + 648, 648, 648, 648, nil, 648, 648, nil, nil, 648, + 648, nil, 501, nil, nil, 501, nil, nil, 501, 501, + nil, nil, 501, nil, 501, 648, nil, 648, 501, 648, + 648, nil, 648, 648, 648, 648, 648, 501, 648, nil, + nil, nil, 501, 501, 501, 501, nil, 501, 501, 501, + 501, nil, nil, nil, nil, 501, 501, nil, 648, nil, + nil, nil, nil, 501, nil, 501, 501, 501, 538, 538, + 538, 538, 538, 538, nil, nil, nil, 538, 538, nil, + nil, nil, 538, nil, 538, 538, 538, 538, 538, 538, + 538, nil, nil, nil, nil, nil, 538, 538, 538, 538, + 538, 538, 538, nil, nil, 538, nil, nil, nil, nil, + nil, 538, 538, 538, 538, 538, 538, 538, 538, 538, + 538, 538, 538, nil, 538, 538, 538, nil, 538, 538, + 538, 538, 538, 734, 734, 734, 734, 734, 734, 734, + 734, 734, 734, 734, nil, 734, 734, nil, nil, 734, + 734, nil, 538, nil, nil, 538, nil, nil, 538, 538, + nil, nil, 538, nil, 538, 734, nil, 734, 538, 734, + 734, nil, 734, 734, 734, 734, 734, 538, 734, nil, + nil, nil, 538, 538, 538, 538, nil, 538, 538, 538, + 538, nil, nil, nil, nil, 538, 538, nil, 734, nil, + nil, nil, nil, 538, nil, 538, 538, 538, 541, 541, + 541, 541, 541, 541, nil, nil, nil, 541, 541, nil, + nil, nil, 541, nil, 541, 541, 541, 541, 541, 541, + 541, nil, nil, nil, nil, nil, 541, 541, 541, 541, + 541, 541, 541, nil, nil, 541, nil, nil, nil, nil, + nil, 541, 541, 541, 541, 541, 541, 541, 541, 541, + 541, 541, 541, nil, 541, 541, 541, nil, 541, 541, + 541, 541, 541, 739, 739, 739, 739, 739, 739, 739, + 739, 739, 739, 739, nil, 739, 739, nil, nil, 739, + 739, nil, 541, nil, nil, 541, nil, nil, 541, 541, + nil, nil, 541, nil, 541, 739, nil, 739, 541, 739, + 739, nil, 739, 739, 739, 739, 739, 541, 739, nil, + nil, nil, 541, 541, 541, 541, nil, 541, 541, 541, + 541, nil, nil, nil, nil, 541, 541, nil, 739, nil, + nil, nil, nil, 541, nil, 541, 541, 541, 561, 561, + 561, 561, 561, 561, nil, nil, nil, 561, 561, nil, + nil, nil, 561, nil, 561, 561, 561, 561, 561, 561, + 561, nil, nil, nil, nil, nil, 561, 561, 561, 561, + 561, 561, 561, nil, nil, 561, nil, nil, nil, nil, + nil, 561, 561, 561, 561, 561, 561, 561, 561, 561, + 561, 561, 561, nil, 561, 561, 561, nil, 561, 561, + 561, 561, 561, 741, 741, 741, 741, 741, 741, 741, + 741, 741, 741, 741, nil, 741, 741, nil, nil, 741, + 741, nil, 561, nil, nil, 561, nil, nil, 561, 561, + nil, nil, 561, nil, 561, 741, nil, 741, 561, 741, + 741, nil, 741, 741, 741, 741, 741, 561, 741, nil, + nil, nil, 561, 561, 561, 561, nil, 561, 561, 561, + 561, nil, nil, nil, nil, 561, 561, nil, 741, nil, + nil, nil, nil, 561, nil, 561, 561, 561, 618, 618, + 618, 618, 618, 618, nil, nil, nil, 618, 618, nil, + nil, nil, 618, nil, 618, 618, 618, 618, 618, 618, + 618, nil, nil, nil, nil, nil, 618, 618, 618, 618, + 618, 618, 618, nil, nil, 618, nil, nil, nil, nil, + nil, 618, 618, 618, 618, 618, 618, 618, 618, 618, + 618, 618, 618, nil, 618, 618, 618, nil, 618, 618, + 618, 618, 618, 744, 744, 744, 744, 744, 744, 744, + 744, 744, 744, 744, nil, 744, 744, nil, nil, 744, + 744, nil, 618, nil, nil, 618, nil, nil, 618, 618, + nil, nil, 618, nil, 618, 744, nil, 744, 618, 744, + 744, nil, 744, 744, 744, 744, 744, 618, 744, nil, + nil, nil, 618, 618, 618, 618, nil, 618, 618, 618, + 618, nil, nil, nil, nil, 618, 618, nil, 744, nil, + nil, nil, nil, 618, nil, 618, 618, 618, 623, 623, + 623, 623, 623, 623, nil, nil, nil, 623, 623, nil, + nil, nil, 623, nil, 623, 623, 623, 623, 623, 623, + 623, nil, nil, nil, nil, nil, 623, 623, 623, 623, + 623, 623, 623, nil, nil, 623, nil, nil, nil, nil, + nil, 623, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, nil, 623, 623, 623, nil, 623, 623, + 623, 623, 623, 746, 746, 746, 746, 746, 746, 746, + 746, 746, 746, 746, nil, 746, 746, nil, nil, 746, + 746, nil, 623, nil, nil, 623, nil, nil, 623, 623, + nil, nil, 623, nil, 623, 746, nil, 746, 623, 746, + 746, nil, 746, 746, 746, 746, 746, 623, 746, nil, + nil, nil, 623, 623, 623, 623, nil, 623, 623, 623, + 623, nil, nil, nil, nil, 623, 623, nil, 746, nil, + nil, nil, nil, 623, nil, 623, 623, 623, 624, 624, + 624, 624, 624, 624, nil, nil, nil, 624, 624, nil, + nil, nil, 624, nil, 624, 624, 624, 624, 624, 624, + 624, nil, nil, nil, nil, nil, 624, 624, 624, 624, + 624, 624, 624, nil, nil, 624, nil, nil, nil, nil, + nil, 624, 624, 624, 624, 624, 624, 624, 624, 624, + 624, 624, 624, nil, 624, 624, 624, nil, 624, 624, + 624, 624, 624, 748, 748, 748, 748, 748, 748, 748, + 748, 748, 748, 748, nil, 748, 748, nil, nil, 748, + 748, nil, 624, nil, nil, 624, nil, nil, 624, 624, + nil, nil, 624, nil, 624, 748, nil, 748, 624, 748, + 748, nil, 748, 748, 748, 748, 748, 624, 748, nil, + nil, nil, 624, 624, 624, 624, nil, 624, 624, 624, + 624, nil, nil, nil, nil, 624, 624, nil, 748, nil, + nil, nil, nil, 624, nil, 624, 624, 624, 710, 710, + 710, 710, 710, 710, nil, nil, nil, 710, 710, nil, + nil, nil, 710, nil, 710, 710, 710, 710, 710, 710, + 710, nil, nil, nil, nil, nil, 710, 710, 710, 710, + 710, 710, 710, nil, nil, 710, nil, nil, nil, nil, + nil, 710, 710, 710, 710, 710, 710, 710, 710, 710, + 710, 710, 710, nil, 710, 710, 710, nil, 710, 710, + 710, 710, 710, 838, 838, 838, 838, 838, 838, 838, + 838, 838, 838, 838, nil, 838, 838, nil, nil, 838, + 838, nil, 710, nil, nil, 710, nil, nil, 710, 710, + nil, nil, 710, nil, 710, 838, nil, 838, 710, 838, + 838, nil, 838, 838, 838, 838, 838, 710, 838, nil, + nil, nil, 710, 710, 710, 710, nil, 710, 710, 710, + 710, nil, nil, nil, nil, 710, 710, nil, 838, nil, + nil, nil, nil, 710, nil, 710, 710, 710, 714, 714, + 714, 714, 714, 714, nil, nil, nil, 714, 714, nil, + nil, nil, 714, nil, 714, 714, 714, 714, 714, 714, + 714, nil, nil, nil, nil, nil, 714, 714, 714, 714, + 714, 714, 714, nil, nil, 714, nil, nil, nil, nil, + nil, 714, 714, 714, 714, 714, 714, 714, 714, 714, + 714, 714, 714, nil, 714, 714, 714, nil, 714, 714, + 714, 714, 714, 841, 841, 841, 841, 841, 841, 841, + 841, 841, 841, 841, nil, 841, 841, nil, nil, 841, + 841, nil, 714, nil, nil, 714, nil, nil, 714, 714, + nil, nil, 714, nil, 714, 841, nil, 841, 714, 841, + 841, nil, 841, 841, 841, 841, 841, 714, 841, nil, + nil, nil, 714, 714, 714, 714, nil, 714, 714, 714, + 714, nil, nil, nil, nil, 714, 714, nil, 841, nil, + nil, nil, nil, 714, nil, 714, 714, 714, 724, 724, + 724, 724, 724, 724, nil, nil, nil, 724, 724, nil, + nil, nil, 724, nil, 724, 724, 724, 724, 724, 724, + 724, nil, nil, nil, nil, nil, 724, 724, 724, 724, + 724, 724, 724, nil, nil, 724, nil, nil, nil, nil, + nil, 724, 724, 724, 724, 724, 724, 724, 724, 724, + 724, 724, 724, nil, 724, 724, 724, nil, 724, 724, + 724, 724, 724, 450, 450, 450, 450, 450, 450, 450, + 450, 450, 450, 450, nil, 450, 450, nil, nil, 450, + 450, nil, 724, nil, nil, 724, nil, nil, 724, 724, + nil, nil, 724, nil, 724, 450, nil, 450, 724, 450, + 450, nil, 450, 450, 450, 450, 450, 724, 450, nil, + nil, nil, 724, 724, 724, 724, nil, 724, 724, 724, + 724, nil, nil, nil, nil, 724, 724, nil, 1010, nil, + 1010, 1010, 1010, 724, 1010, 724, 724, 724, 772, 772, + 772, 772, 772, 772, nil, nil, nil, 772, 772, nil, + nil, nil, 772, nil, 772, 772, 772, 772, 772, 772, + 772, nil, nil, nil, nil, 1010, 772, 772, 772, 772, + 772, 772, 772, nil, nil, 772, nil, nil, nil, nil, + nil, 772, 772, 772, 772, 772, 772, 772, 772, 772, + 772, 772, 772, nil, 772, 772, 772, nil, 772, 772, + 772, 772, 772, 451, 451, 451, 451, 451, 451, 451, + 451, 451, 451, 451, nil, 451, 451, nil, nil, 451, + 451, nil, 772, nil, nil, 772, nil, nil, 772, 772, + nil, nil, 772, nil, 772, 451, nil, 451, 772, 451, + 451, nil, 451, 451, 451, 451, 451, 772, 451, nil, + nil, nil, 772, 772, 772, 772, nil, 772, 772, 772, + 772, nil, nil, nil, nil, 772, 772, nil, nil, nil, + nil, nil, nil, 772, nil, 772, 772, 772, 785, 785, + 785, 785, 785, 785, nil, nil, nil, 785, 785, nil, + nil, nil, 785, nil, 785, 785, 785, 785, 785, 785, + 785, nil, nil, nil, nil, nil, 785, 785, 785, 785, + 785, 785, 785, nil, nil, 785, nil, nil, nil, nil, + nil, 785, 785, 785, 785, 785, 785, 785, 785, 785, + 785, 785, 785, nil, 785, 785, 785, nil, 785, 785, + 785, 785, 785, 461, 461, 461, 461, 461, 461, 461, + nil, nil, 461, 461, nil, nil, nil, nil, nil, 461, + 461, nil, 785, nil, nil, 785, nil, nil, 785, 785, + nil, nil, 785, nil, 785, 461, nil, 461, 785, 461, + 461, nil, 461, 461, 461, 461, 461, 785, 461, nil, + nil, nil, 785, 785, 785, 785, nil, 785, 785, 785, + 785, nil, nil, nil, nil, 785, 785, nil, nil, nil, + nil, nil, nil, 785, nil, 785, 785, 785, 819, 819, + 819, 819, 819, 819, nil, nil, nil, 819, 819, nil, + nil, nil, 819, nil, 819, 819, 819, 819, 819, 819, + 819, nil, nil, nil, nil, nil, 819, 819, 819, 819, + 819, 819, 819, nil, nil, 819, nil, nil, nil, nil, + nil, 819, 819, 819, 819, 819, 819, 819, 819, 819, + 819, 819, 819, nil, 819, 819, 819, nil, 819, 819, + 819, 819, 819, 464, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 464, + 464, nil, 819, nil, nil, 819, nil, nil, 819, 819, + nil, nil, 819, nil, 819, 464, nil, 464, 819, 464, + 464, nil, 464, 464, nil, nil, 464, 819, 464, nil, + nil, nil, 819, 819, 819, 819, nil, 819, 819, 819, + 819, nil, nil, nil, nil, 819, 819, nil, nil, nil, + nil, nil, nil, 819, nil, 819, 819, 819, 820, 820, + 820, 820, 820, 820, nil, nil, nil, 820, 820, nil, + nil, nil, 820, nil, 820, 820, 820, 820, 820, 820, + 820, nil, nil, nil, nil, nil, 820, 820, 820, 820, + 820, 820, 820, nil, nil, 820, nil, nil, nil, nil, + nil, 820, 820, 820, 820, 820, 820, 820, 820, 820, + 820, 820, 820, nil, 820, 820, 820, nil, 820, 820, + 820, 820, 820, 465, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 465, + 465, nil, 820, nil, nil, 820, nil, nil, 820, 820, + nil, nil, 820, nil, 820, 465, nil, 465, 820, 465, + 465, nil, 465, 465, nil, nil, 465, 820, 465, nil, + nil, nil, 820, 820, 820, 820, nil, 820, 820, 820, + 820, nil, nil, nil, nil, 820, 820, nil, nil, nil, + nil, nil, nil, 820, nil, 820, 820, 820, 823, 823, + 823, 823, 823, 823, nil, nil, nil, 823, 823, nil, + nil, nil, 823, nil, 823, 823, 823, 823, 823, 823, + 823, nil, nil, nil, nil, nil, 823, 823, 823, 823, + 823, 823, 823, nil, nil, 823, nil, nil, nil, nil, + nil, 823, 823, 823, 823, 823, 823, 823, 823, 823, + 823, 823, 823, nil, 823, 823, 823, nil, 823, 823, + 823, 823, 823, 466, 466, 466, 466, 466, 466, 466, + nil, nil, 466, 466, nil, nil, nil, nil, nil, 466, + 466, nil, 823, nil, nil, 823, nil, nil, 823, 823, + nil, nil, 823, nil, 823, 466, nil, 466, 823, 466, + 466, nil, 466, 466, 466, 466, 466, 823, 466, nil, + nil, nil, 823, 823, 823, 823, nil, 823, 823, 823, + 823, nil, nil, nil, nil, 823, 823, nil, nil, nil, + nil, nil, nil, 823, nil, 823, 823, 823, 829, 829, + 829, 829, 829, 829, nil, nil, nil, 829, 829, nil, + nil, nil, 829, nil, 829, 829, 829, 829, 829, 829, + 829, nil, nil, nil, nil, nil, 829, 829, 829, 829, + 829, 829, 829, nil, nil, 829, nil, nil, nil, nil, + nil, 829, 829, 829, 829, 829, 829, 829, 829, 829, + 829, 829, 829, nil, 829, 829, 829, nil, 829, 829, + 829, 829, 829, 467, 467, 467, 467, 467, 467, 467, + nil, nil, 467, 467, nil, nil, nil, nil, nil, 467, + 467, nil, 829, nil, nil, 829, nil, nil, 829, 829, + nil, nil, 829, nil, 829, 467, nil, 467, 829, 467, + 467, nil, 467, 467, 467, 467, 467, 829, 467, nil, + nil, nil, 829, 829, 829, 829, nil, 829, 829, 829, + 829, nil, nil, nil, nil, 829, 829, nil, nil, nil, + nil, nil, nil, 829, nil, 829, 829, 829, 862, 862, + 862, 862, 862, 862, nil, nil, nil, 862, 862, nil, + nil, nil, 862, nil, 862, 862, 862, 862, 862, 862, + 862, nil, nil, nil, nil, nil, 862, 862, 862, 862, + 862, 862, 862, nil, nil, 862, nil, nil, nil, nil, + nil, 862, 862, 862, 862, 862, 862, 862, 862, 862, + 862, 862, 862, nil, 862, 862, 862, nil, 862, 862, + 862, 862, 862, 468, 468, 468, 468, 468, 468, 468, + nil, nil, 468, 468, nil, nil, nil, nil, nil, 468, + 468, nil, 862, nil, nil, 862, nil, nil, 862, 862, + nil, nil, 862, nil, 862, 468, nil, 468, 862, 468, + 468, nil, 468, 468, 468, 468, 468, 862, 468, nil, + nil, nil, 862, 862, 862, 862, nil, 862, 862, 862, + 862, nil, nil, nil, nil, 862, 862, nil, nil, nil, + nil, nil, nil, 862, nil, 862, 862, 862, 926, 926, + 926, 926, 926, 926, nil, nil, nil, 926, 926, nil, + nil, nil, 926, nil, 926, 926, 926, 926, 926, 926, + 926, nil, nil, nil, nil, nil, 926, 926, 926, 926, + 926, 926, 926, nil, nil, 926, nil, nil, nil, nil, + nil, 926, 926, 926, 926, 926, 926, 926, 926, 926, + 926, 926, 926, nil, 926, 926, 926, nil, 926, 926, + 926, 926, 926, 469, 469, 469, 469, 469, 469, 469, + nil, nil, 469, 469, nil, nil, nil, nil, nil, 469, + 469, nil, 926, nil, nil, 926, nil, nil, 926, 926, + nil, nil, 926, nil, 926, 469, nil, 469, 926, 469, + 469, nil, 469, 469, 469, 469, 469, 926, 469, nil, + nil, nil, 926, 926, 926, 926, nil, 926, 926, 926, + 926, nil, nil, nil, nil, 926, 926, nil, nil, nil, + nil, nil, nil, 926, nil, 926, 926, 926, 933, 933, + 933, 933, 933, 933, nil, nil, nil, 933, 933, nil, + nil, nil, 933, nil, 933, 933, 933, 933, 933, 933, + 933, nil, nil, nil, nil, nil, 933, 933, 933, 933, + 933, 933, 933, nil, nil, 933, nil, nil, nil, nil, + nil, 933, 933, 933, 933, 933, 933, 933, 933, 933, + 933, 933, 933, nil, 933, 933, 933, nil, 933, 933, + 933, 933, 933, 470, 470, 470, 470, 470, 470, 470, + nil, nil, 470, 470, nil, nil, nil, nil, nil, 470, + 470, nil, 933, nil, nil, 933, nil, nil, 933, 933, + nil, nil, 933, nil, 933, 470, nil, 470, 933, 470, + 470, nil, 470, 470, 470, 470, 470, 933, 470, nil, + nil, nil, 933, 933, 933, 933, nil, 933, 933, 933, + 933, nil, nil, nil, nil, 933, 933, nil, nil, nil, + nil, nil, nil, 933, nil, 933, 933, 933, 934, 934, + 934, 934, 934, 934, nil, nil, nil, 934, 934, nil, + nil, nil, 934, nil, 934, 934, 934, 934, 934, 934, + 934, nil, nil, nil, nil, nil, 934, 934, 934, 934, + 934, 934, 934, nil, nil, 934, nil, nil, nil, nil, + nil, 934, 934, 934, 934, 934, 934, 934, 934, 934, + 934, 934, 934, nil, 934, 934, 934, nil, 934, 934, + 934, 934, 934, 473, 473, 473, 473, 473, 473, 473, + nil, nil, 473, 473, nil, nil, nil, nil, nil, 473, + 473, nil, 934, nil, nil, 934, nil, nil, 934, 934, + nil, nil, 934, nil, 934, 473, nil, 473, 934, 473, + 473, nil, 473, 473, 473, 473, 473, 934, 473, nil, + nil, nil, 934, 934, 934, 934, nil, 934, 934, 934, + 934, nil, nil, nil, nil, 934, 934, nil, nil, nil, + nil, nil, nil, 934, nil, 934, 934, 934, 951, 951, + 951, 951, 951, 951, nil, nil, nil, 951, 951, nil, + nil, nil, 951, nil, 951, 951, 951, 951, 951, 951, + 951, nil, nil, nil, nil, nil, 951, 951, 951, 951, + 951, 951, 951, nil, nil, 951, nil, nil, nil, nil, + nil, 951, 951, 951, 951, 951, 951, 951, 951, 951, + 951, 951, 951, nil, 951, 951, 951, nil, 951, 951, + 951, 951, 951, 474, 474, 474, 474, 474, 474, 474, + 474, nil, 474, 474, nil, nil, nil, nil, nil, 474, + 474, nil, 951, nil, nil, 951, nil, nil, 951, 951, + nil, nil, 951, nil, 951, 474, nil, 474, 951, 474, + 474, nil, 474, 474, 474, 474, 474, 951, 474, nil, + nil, nil, 951, 951, 951, 951, nil, 951, 951, 951, + 951, nil, nil, nil, nil, 951, 951, nil, nil, nil, + nil, nil, nil, 951, nil, 951, 951, 951, 957, 957, + 957, 957, 957, 957, nil, nil, nil, 957, 957, nil, + nil, nil, 957, nil, 957, 957, 957, 957, 957, 957, + 957, nil, nil, nil, nil, nil, 957, 957, 957, 957, + 957, 957, 957, nil, nil, 957, nil, nil, nil, nil, + nil, 957, 957, 957, 957, 957, 957, 957, 957, 957, + 957, 957, 957, nil, 957, 957, 957, nil, 957, 957, + 957, 957, 957, 459, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 459, + 459, nil, 957, nil, nil, 957, nil, nil, 957, 957, + nil, nil, 957, nil, 957, 459, nil, 459, 957, 459, + 459, nil, 459, 459, nil, nil, nil, 957, nil, nil, + nil, nil, 957, 957, 957, 957, nil, 957, 957, 957, + 957, nil, nil, nil, nil, 957, 957, nil, nil, nil, + nil, nil, nil, 957, nil, 957, 957, 957, 959, 959, + 959, 959, 959, 959, nil, nil, nil, 959, 959, nil, + nil, nil, 959, nil, 959, 959, 959, 959, 959, 959, + 959, nil, nil, nil, nil, nil, 959, 959, 959, 959, + 959, 959, 959, nil, nil, 959, nil, nil, nil, nil, + nil, 959, 959, 959, 959, 959, 959, 959, 959, 959, + 959, 959, 959, nil, 959, 959, 959, nil, 959, 959, + 959, 959, 959, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 959, nil, nil, 959, nil, nil, 959, 959, + nil, nil, 959, nil, 959, nil, nil, nil, 959, nil, + nil, nil, nil, nil, nil, nil, nil, 959, nil, nil, + nil, nil, 959, 959, 959, 959, nil, 959, 959, 959, + 959, nil, nil, nil, nil, 959, 959, nil, nil, nil, + nil, nil, nil, 959, nil, 959, 959, 959, 5, 5, + 5, 5, 5, nil, nil, nil, 5, 5, nil, nil, + nil, 5, nil, 5, 5, 5, 5, 5, 5, 5, + nil, nil, nil, nil, nil, 5, 5, 5, 5, 5, + 5, 5, nil, nil, 5, nil, nil, nil, nil, nil, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, nil, 5, 5, 5, nil, 5, 5, 5, + 5, 5, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 5, nil, nil, 5, nil, nil, 5, 5, nil, + nil, 5, nil, 5, nil, nil, nil, 5, nil, nil, + nil, nil, nil, nil, nil, nil, 5, nil, nil, nil, + nil, 5, 5, 5, 5, nil, 5, 5, 5, 5, + nil, nil, nil, nil, 5, 5, nil, nil, nil, 20, + 20, 20, 5, 20, 5, 5, 5, 20, 20, nil, + nil, nil, 20, nil, 20, 20, 20, 20, 20, 20, + 20, nil, nil, nil, nil, nil, 20, 20, 20, 20, + 20, 20, 20, nil, nil, 20, nil, nil, nil, nil, + nil, nil, 20, nil, nil, 20, 20, 20, 20, 20, + 20, 20, 20, nil, 20, 20, 20, nil, 20, 20, + 20, 20, 20, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, 20, nil, nil, 20, 20, + nil, nil, 20, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 20, 20, 20, 20, nil, 20, 20, 20, + 20, nil, nil, nil, nil, 20, 20, nil, nil, nil, + 29, 29, 29, 20, 29, 20, 20, 20, 29, 29, + nil, nil, nil, 29, nil, 29, 29, 29, 29, 29, + 29, 29, nil, nil, nil, nil, nil, 29, 29, 29, + 29, 29, 29, 29, nil, nil, 29, nil, nil, nil, + nil, nil, nil, 29, nil, nil, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, nil, 29, + 29, 29, 29, 29, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 29, nil, nil, 29, nil, nil, 29, + 29, nil, nil, 29, nil, 29, nil, 29, nil, 29, + nil, nil, 29, nil, nil, nil, nil, nil, 29, nil, + nil, nil, nil, 29, 29, 29, 29, nil, 29, 29, + 29, 29, nil, nil, nil, nil, 29, 29, nil, nil, + nil, 30, 30, 30, 29, 30, 29, 29, 29, 30, + 30, nil, nil, nil, 30, nil, 30, 30, 30, 30, + 30, 30, 30, nil, nil, nil, nil, nil, 30, 30, + 30, 30, 30, 30, 30, nil, nil, 30, nil, nil, + nil, nil, nil, nil, 30, nil, nil, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, 30, nil, + 30, 30, 30, 30, 30, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 30, nil, nil, 30, nil, nil, + 30, 30, nil, nil, 30, nil, 30, nil, 30, nil, + 30, nil, nil, 30, nil, nil, nil, nil, nil, 30, + nil, nil, nil, nil, 30, 30, 30, 30, nil, 30, + 30, 30, 30, nil, nil, nil, nil, 30, 30, nil, + nil, nil, 31, 31, 31, 30, 31, 30, 30, 30, + 31, 31, nil, nil, nil, 31, nil, 31, 31, 31, + 31, 31, 31, 31, nil, nil, nil, nil, nil, 31, + 31, 31, 31, 31, 31, 31, nil, nil, 31, nil, + nil, nil, nil, nil, nil, 31, nil, nil, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + nil, 31, 31, 31, 31, 31, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 31, nil, nil, 31, nil, + nil, 31, 31, nil, nil, 31, nil, 31, nil, 31, + nil, 31, nil, nil, 31, nil, nil, nil, nil, nil, + 31, nil, nil, nil, nil, 31, 31, 31, 31, nil, + 31, 31, 31, 31, nil, nil, nil, nil, 31, 31, + nil, nil, nil, 34, 34, 34, 31, 34, 31, 31, + 31, 34, 34, nil, nil, nil, 34, nil, 34, 34, + 34, 34, 34, 34, 34, nil, nil, nil, nil, nil, + 34, 34, 34, 34, 34, 34, 34, nil, nil, 34, + nil, nil, nil, nil, nil, nil, 34, nil, nil, 34, + 34, 34, 34, 34, 34, 34, 34, nil, 34, 34, + 34, nil, 34, 34, nil, nil, 34, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 34, nil, nil, 34, + nil, nil, 34, 34, nil, nil, 34, nil, 34, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 34, 34, 34, 34, + nil, 34, 34, 34, 34, nil, nil, nil, nil, 34, + 34, nil, nil, nil, 35, 35, 35, 34, 35, 34, + 34, 34, 35, 35, nil, nil, nil, 35, nil, 35, + 35, 35, 35, 35, 35, 35, nil, nil, nil, nil, + nil, 35, 35, 35, 35, 35, 35, 35, nil, nil, + 35, nil, nil, nil, nil, nil, nil, 35, nil, nil, + 35, 35, 35, 35, 35, 35, 35, 35, nil, 35, + 35, 35, nil, 35, 35, nil, nil, 35, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 35, nil, nil, + 35, nil, nil, 35, 35, nil, nil, 35, nil, nil, + 802, nil, 802, 802, 802, 802, 802, nil, nil, nil, + nil, nil, nil, nil, nil, 802, nil, 35, 35, 35, + 35, nil, 35, 35, 35, 35, nil, nil, nil, nil, + 35, 35, nil, nil, nil, 35, nil, 802, 35, nil, + 35, 35, 35, 42, 42, 42, nil, 42, 802, 802, + nil, 42, 42, 802, nil, nil, 42, nil, 42, 42, + 42, 42, 42, 42, 42, nil, nil, nil, nil, nil, + 42, 42, 42, 42, 42, 42, 42, nil, nil, 42, + nil, nil, nil, nil, nil, nil, 42, nil, nil, 42, + 42, 42, 42, 42, 42, 42, 42, nil, 42, 42, + 42, nil, 42, 42, 42, 42, 42, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 42, nil, nil, 42, + nil, nil, 42, 42, nil, nil, 42, nil, nil, nil, + nil, nil, 42, nil, nil, nil, nil, nil, nil, nil, + nil, 42, nil, nil, nil, nil, 42, 42, 42, 42, + nil, 42, 42, 42, 42, nil, nil, nil, nil, 42, + 42, nil, nil, nil, 43, 43, 43, 42, 43, 42, + 42, 42, 43, 43, nil, nil, nil, 43, nil, 43, + 43, 43, 43, 43, 43, 43, nil, nil, nil, nil, + nil, 43, 43, 43, 43, 43, 43, 43, nil, nil, + 43, nil, nil, nil, nil, nil, nil, 43, nil, nil, + 43, 43, 43, 43, 43, 43, 43, 43, nil, 43, + 43, 43, nil, 43, 43, 43, 43, 43, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 43, nil, nil, + 43, nil, nil, 43, 43, nil, nil, 43, nil, nil, + nil, nil, nil, 43, nil, nil, nil, nil, nil, nil, + nil, nil, 43, nil, nil, nil, nil, 43, 43, 43, + 43, nil, 43, 43, 43, 43, nil, nil, nil, nil, + 43, 43, nil, nil, nil, 44, 44, 44, 43, 44, + 43, 43, 43, 44, 44, nil, nil, nil, 44, nil, + 44, 44, 44, 44, 44, 44, 44, nil, nil, nil, + nil, nil, 44, 44, 44, 44, 44, 44, 44, nil, + nil, 44, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 44, 44, 44, 44, 44, 44, 44, 44, nil, + 44, 44, 44, nil, 44, 44, 44, 44, 44, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 44, nil, nil, 44, 44, nil, nil, 44, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, 44, 44, + 44, 44, nil, 44, 44, 44, 44, nil, nil, nil, + nil, 44, 44, nil, nil, nil, 59, 59, 59, 44, + 59, 44, 44, 44, 59, 59, nil, nil, nil, 59, + nil, 59, 59, 59, 59, 59, 59, 59, nil, nil, + nil, nil, nil, 59, 59, 59, 59, 59, 59, 59, + nil, nil, 59, nil, nil, nil, nil, nil, nil, 59, + nil, nil, 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, nil, 59, 59, 59, 59, 59, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 59, + nil, nil, 59, nil, nil, 59, 59, nil, nil, 59, + nil, 59, nil, nil, nil, 59, nil, nil, 59, nil, + nil, nil, nil, nil, 59, nil, nil, nil, nil, 59, + 59, 59, 59, nil, 59, 59, 59, 59, nil, nil, + nil, nil, 59, 59, nil, nil, nil, 60, 60, 60, + 59, 60, 59, 59, 59, 60, 60, nil, nil, nil, + 60, nil, 60, 60, 60, 60, 60, 60, 60, nil, + nil, nil, nil, nil, 60, 60, 60, 60, 60, 60, + 60, nil, nil, 60, nil, nil, nil, nil, nil, nil, + 60, nil, nil, 60, 60, 60, 60, 60, 60, 60, + 60, 60, 60, 60, 60, nil, 60, 60, 60, 60, + 60, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 60, nil, nil, 60, nil, nil, 60, 60, nil, nil, + 60, nil, nil, nil, nil, nil, 60, nil, nil, 60, + nil, nil, nil, nil, nil, 60, nil, nil, nil, nil, + 60, 60, 60, 60, nil, 60, 60, 60, 60, nil, + nil, nil, nil, 60, 60, nil, nil, nil, 63, 63, + 63, 60, 63, 60, 60, 60, 63, 63, nil, nil, + nil, 63, nil, 63, 63, 63, 63, 63, 63, 63, + nil, nil, nil, nil, nil, 63, 63, 63, 63, 63, + 63, 63, nil, nil, 63, nil, nil, nil, nil, nil, + nil, 63, nil, nil, 63, 63, 63, 63, 63, 63, + 63, 63, nil, 63, 63, 63, nil, 63, 63, 63, + 63, 63, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 63, nil, nil, 63, nil, nil, 63, 63, nil, + nil, 63, nil, nil, nil, nil, nil, 63, nil, nil, + nil, nil, nil, nil, nil, nil, 63, nil, nil, nil, + nil, 63, 63, 63, 63, nil, 63, 63, 63, 63, + nil, nil, nil, nil, 63, 63, nil, nil, nil, 64, + 64, 64, 63, 64, 63, 63, 63, 64, 64, nil, + nil, nil, 64, nil, 64, 64, 64, 64, 64, 64, + 64, nil, nil, nil, nil, nil, 64, 64, 64, 64, + 64, 64, 64, nil, nil, 64, nil, nil, nil, nil, + nil, nil, 64, nil, nil, 64, 64, 64, 64, 64, + 64, 64, 64, nil, 64, 64, 64, nil, 64, 64, + 64, 64, 64, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 64, nil, nil, 64, nil, nil, 64, 64, + nil, nil, 64, nil, nil, nil, nil, nil, 64, nil, + nil, nil, nil, nil, nil, nil, nil, 64, nil, nil, + nil, nil, 64, 64, 64, 64, nil, 64, 64, 64, + 64, nil, nil, nil, nil, 64, 64, nil, nil, nil, + 67, 67, 67, 64, 67, 64, 64, 64, 67, 67, + nil, nil, nil, 67, nil, 67, 67, 67, 67, 67, + 67, 67, nil, nil, nil, nil, nil, 67, 67, 67, + 67, 67, 67, 67, nil, nil, 67, nil, nil, nil, + nil, nil, nil, 67, nil, nil, 67, 67, 67, 67, + 67, 67, 67, 67, nil, 67, 67, 67, nil, 67, + 67, 67, 67, 67, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 67, nil, nil, 67, nil, nil, 67, + 67, nil, nil, 67, nil, nil, nil, nil, nil, 67, + nil, nil, nil, nil, nil, nil, nil, nil, 67, nil, + nil, nil, nil, 67, 67, 67, 67, nil, 67, 67, + 67, 67, nil, nil, nil, nil, 67, 67, 67, nil, + nil, nil, nil, 67, 67, nil, 67, 67, 67, 68, + 68, 68, nil, 68, nil, nil, nil, 68, 68, nil, + nil, nil, 68, nil, 68, 68, 68, 68, 68, 68, + 68, nil, nil, nil, nil, nil, 68, 68, 68, 68, + 68, 68, 68, nil, nil, 68, nil, nil, nil, nil, + nil, nil, 68, nil, nil, 68, 68, 68, 68, 68, + 68, 68, 68, nil, 68, 68, 68, nil, 68, 68, + nil, nil, 68, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 68, nil, nil, 68, nil, nil, 68, 68, + nil, nil, 68, nil, 68, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 68, 68, 68, 68, nil, 68, 68, 68, + 68, nil, nil, nil, nil, 68, 68, nil, nil, nil, + 69, 69, 69, 68, 69, 68, 68, 68, 69, 69, + nil, nil, nil, 69, nil, 69, 69, 69, 69, 69, + 69, 69, nil, nil, nil, nil, nil, 69, 69, 69, + 69, 69, 69, 69, nil, nil, 69, nil, nil, nil, + nil, nil, nil, 69, nil, nil, 69, 69, 69, 69, + 69, 69, 69, 69, nil, 69, 69, 69, nil, 69, + 69, nil, nil, 69, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 69, nil, nil, 69, nil, nil, 69, nil, nil, 69, + 69, nil, nil, 69, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 69, 69, 69, 69, nil, 69, 69, + 69, 69, nil, nil, nil, nil, 69, 69, nil, nil, + nil, 70, 70, 70, 69, 70, 69, 69, 69, 70, + 70, nil, nil, nil, 70, nil, 70, 70, 70, 70, + 70, 70, 70, nil, nil, nil, nil, nil, 70, 70, + 70, 70, 70, 70, 70, nil, nil, 70, nil, nil, + nil, nil, nil, nil, 70, nil, nil, 70, 70, 70, + 70, 70, 70, 70, 70, nil, 70, 70, 70, nil, + 70, 70, nil, nil, 70, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 70, nil, nil, 70, nil, nil, + 70, 70, nil, nil, 70, nil, nil, 849, nil, 849, + 849, 849, 849, 849, nil, nil, nil, nil, nil, nil, + nil, nil, 849, nil, 70, 70, 70, 70, nil, 70, + 70, 70, 70, nil, nil, nil, nil, 70, 70, nil, + nil, nil, nil, nil, 849, 70, nil, 70, 70, 70, + 113, 113, 113, 113, 113, 849, 849, nil, 113, 113, + 849, nil, nil, 113, nil, 113, 113, 113, 113, 113, + 113, 113, nil, nil, nil, nil, nil, 113, 113, 113, + 113, 113, 113, 113, nil, nil, 113, nil, nil, nil, + nil, nil, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, nil, 113, 113, 113, nil, 113, + 113, 113, 113, 113, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 113, nil, nil, 113, nil, nil, 113, + 113, nil, nil, 113, nil, 113, nil, nil, nil, 113, + nil, nil, nil, nil, nil, nil, nil, nil, 113, nil, + nil, nil, nil, 113, 113, 113, 113, nil, 113, 113, + 113, 113, nil, nil, nil, nil, 113, 113, nil, nil, + nil, nil, nil, 113, 113, nil, 113, 113, 113, 118, + 118, 118, nil, 118, nil, nil, nil, 118, 118, nil, + nil, nil, 118, nil, 118, 118, 118, 118, 118, 118, + 118, nil, nil, nil, nil, nil, 118, 118, 118, 118, + 118, 118, 118, nil, nil, 118, nil, nil, nil, nil, + nil, nil, 118, nil, nil, 118, 118, 118, 118, 118, + 118, 118, 118, nil, 118, 118, 118, nil, 118, 118, + 118, 118, 118, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 118, nil, nil, 118, nil, nil, 118, 118, + nil, nil, 118, nil, nil, nil, nil, nil, 118, nil, + nil, nil, nil, nil, nil, nil, nil, 118, nil, nil, + nil, nil, 118, 118, 118, 118, nil, 118, 118, 118, + 118, nil, nil, nil, nil, 118, 118, nil, nil, nil, + 119, 119, 119, 118, 119, 118, 118, 118, 119, 119, + nil, nil, nil, 119, nil, 119, 119, 119, 119, 119, + 119, 119, nil, nil, nil, nil, nil, 119, 119, 119, + 119, 119, 119, 119, nil, nil, 119, nil, nil, nil, + nil, nil, nil, 119, nil, nil, 119, 119, 119, 119, + 119, 119, 119, 119, nil, 119, 119, 119, nil, 119, + 119, 119, 119, 119, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 119, nil, nil, 119, nil, nil, 119, + 119, nil, nil, 119, nil, nil, nil, nil, nil, 119, + nil, nil, nil, nil, nil, nil, nil, nil, 119, nil, + nil, nil, nil, 119, 119, 119, 119, nil, 119, 119, + 119, 119, nil, nil, nil, nil, 119, 119, nil, nil, + nil, 120, 120, 120, 119, 120, 119, 119, 119, 120, + 120, nil, nil, nil, 120, nil, 120, 120, 120, 120, + 120, 120, 120, nil, nil, nil, nil, nil, 120, 120, + 120, 120, 120, 120, 120, nil, nil, 120, nil, nil, + nil, nil, nil, nil, 120, nil, nil, 120, 120, 120, + 120, 120, 120, 120, 120, nil, 120, 120, 120, nil, + 120, 120, 120, 120, 120, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 120, nil, nil, 120, nil, nil, + 120, 120, nil, nil, 120, nil, nil, nil, nil, nil, + 120, nil, nil, nil, nil, nil, nil, nil, nil, 120, + nil, nil, nil, nil, 120, 120, 120, 120, nil, 120, + 120, 120, 120, nil, nil, nil, nil, 120, 120, nil, + nil, nil, 121, 121, 121, 120, 121, 120, 120, 120, + 121, 121, nil, nil, nil, 121, nil, 121, 121, 121, + 121, 121, 121, 121, nil, nil, nil, nil, nil, 121, + 121, 121, 121, 121, 121, 121, nil, nil, 121, nil, + nil, nil, nil, nil, nil, 121, nil, nil, 121, 121, + 121, 121, 121, 121, 121, 121, nil, 121, 121, 121, + nil, 121, 121, 121, 121, 121, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 121, nil, nil, 121, nil, + nil, 121, 121, nil, nil, 121, nil, nil, nil, nil, + nil, 121, nil, nil, nil, nil, nil, nil, nil, nil, + 121, nil, nil, nil, nil, 121, 121, 121, 121, nil, + 121, 121, 121, 121, nil, nil, nil, nil, 121, 121, + nil, nil, nil, nil, nil, nil, 121, nil, 121, 121, + 121, 122, 122, 122, 122, 122, nil, nil, nil, 122, + 122, nil, nil, nil, 122, nil, 122, 122, 122, 122, + 122, 122, 122, nil, nil, nil, nil, nil, 122, 122, + 122, 122, 122, 122, 122, nil, nil, 122, nil, nil, + nil, nil, nil, 122, 122, nil, 122, 122, 122, 122, + 122, 122, 122, 122, 122, nil, 122, 122, 122, nil, + 122, 122, 122, 122, 122, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 122, nil, nil, 122, nil, nil, + 122, 122, nil, nil, 122, nil, 122, nil, nil, nil, + 122, nil, nil, nil, nil, nil, nil, nil, nil, 122, + nil, nil, nil, nil, 122, 122, 122, 122, nil, 122, + 122, 122, 122, nil, nil, nil, nil, 122, 122, nil, + nil, nil, 209, 209, 209, 122, 209, 122, 122, 122, + 209, 209, nil, nil, nil, 209, nil, 209, 209, 209, + 209, 209, 209, 209, nil, nil, nil, nil, nil, 209, + 209, 209, 209, 209, 209, 209, nil, nil, 209, nil, + nil, nil, nil, nil, nil, 209, nil, nil, 209, 209, + 209, 209, 209, 209, 209, 209, nil, 209, 209, 209, + nil, 209, 209, 209, 209, 209, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 209, nil, nil, 209, nil, + nil, 209, 209, nil, nil, 209, nil, 209, nil, nil, + nil, 209, nil, nil, nil, nil, nil, nil, nil, nil, + 209, nil, nil, nil, nil, 209, 209, 209, 209, nil, + 209, 209, 209, 209, nil, nil, nil, nil, 209, 209, + nil, nil, nil, 210, 210, 210, 209, 210, 209, 209, + 209, 210, 210, nil, nil, nil, 210, nil, 210, 210, + 210, 210, 210, 210, 210, nil, nil, nil, nil, nil, + 210, 210, 210, 210, 210, 210, 210, nil, nil, 210, + nil, nil, nil, nil, nil, nil, 210, nil, nil, 210, + 210, 210, 210, 210, 210, 210, 210, nil, 210, 210, + 210, nil, 210, 210, 210, 210, 210, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 210, nil, nil, 210, + nil, nil, 210, 210, nil, nil, 210, nil, nil, nil, + nil, nil, 210, nil, nil, nil, nil, nil, nil, nil, + nil, 210, nil, nil, nil, nil, 210, 210, 210, 210, + nil, 210, 210, 210, 210, nil, nil, nil, nil, 210, + 210, nil, nil, nil, 211, 211, 211, 210, 211, 210, + 210, 210, 211, 211, nil, nil, nil, 211, nil, 211, + 211, 211, 211, 211, 211, 211, nil, nil, nil, nil, + nil, 211, 211, 211, 211, 211, 211, 211, nil, nil, + 211, nil, nil, nil, nil, nil, nil, 211, nil, nil, + 211, 211, 211, 211, 211, 211, 211, 211, 211, 211, + 211, 211, nil, 211, 211, 211, 211, 211, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 211, nil, nil, + 211, nil, nil, 211, 211, nil, nil, 211, nil, 211, + nil, 211, nil, 211, nil, nil, 211, nil, nil, nil, + nil, nil, 211, nil, nil, nil, nil, 211, 211, 211, + 211, nil, 211, 211, 211, 211, nil, nil, nil, nil, + 211, 211, nil, nil, nil, 216, 216, 216, 211, 216, + 211, 211, 211, 216, 216, nil, nil, nil, 216, nil, + 216, 216, 216, 216, 216, 216, 216, nil, nil, nil, + nil, nil, 216, 216, 216, 216, 216, 216, 216, nil, + nil, 216, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 216, 216, 216, 216, 216, 216, 216, 216, nil, + 216, 216, 216, nil, 216, 216, 216, 216, 216, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, 216, nil, nil, 216, 216, nil, nil, 216, nil, + nil, nil, nil, nil, 216, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, nil, nil, 216, 216, + 216, 216, nil, 216, 216, 216, 216, nil, nil, nil, + nil, 216, 216, nil, nil, nil, 217, 217, 217, 216, + 217, 216, 216, 216, 217, 217, nil, nil, nil, 217, + nil, 217, 217, 217, 217, 217, 217, 217, nil, nil, + nil, nil, nil, 217, 217, 217, 217, 217, 217, 217, + nil, nil, 217, nil, nil, nil, nil, nil, nil, 217, + nil, nil, 217, 217, 217, 217, 217, 217, 217, 217, + nil, 217, 217, 217, nil, 217, 217, 217, 217, 217, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 217, + nil, nil, 217, nil, nil, 217, 217, nil, nil, 217, + nil, 217, nil, nil, nil, 217, nil, nil, nil, nil, + nil, nil, nil, nil, 217, nil, nil, nil, nil, 217, + 217, 217, 217, nil, 217, 217, 217, 217, nil, nil, + nil, nil, 217, 217, nil, nil, nil, 218, 218, 218, + 217, 218, 217, 217, 217, 218, 218, nil, nil, nil, + 218, nil, 218, 218, 218, 218, 218, 218, 218, nil, + nil, nil, nil, nil, 218, 218, 218, 218, 218, 218, + 218, nil, nil, 218, nil, nil, nil, nil, nil, nil, + 218, nil, nil, 218, 218, 218, 218, 218, 218, 218, + 218, nil, 218, 218, 218, nil, 218, 218, 218, 218, + 218, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 218, nil, nil, 218, nil, nil, 218, 218, nil, nil, + 218, nil, nil, nil, nil, nil, 218, nil, nil, nil, + nil, nil, nil, nil, nil, 218, nil, nil, nil, nil, + 218, 218, 218, 218, nil, 218, 218, 218, 218, nil, + nil, nil, nil, 218, 218, nil, nil, nil, 219, 219, + 219, 218, 219, 218, 218, 218, 219, 219, nil, nil, + nil, 219, nil, 219, 219, 219, 219, 219, 219, 219, + nil, nil, nil, nil, nil, 219, 219, 219, 219, 219, + 219, 219, nil, nil, 219, nil, nil, nil, nil, nil, + nil, 219, nil, nil, 219, 219, 219, 219, 219, 219, + 219, 219, nil, 219, 219, 219, nil, 219, 219, 219, + 219, 219, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 219, nil, nil, 219, nil, nil, 219, 219, nil, + nil, 219, nil, nil, nil, nil, nil, 219, nil, nil, + nil, nil, nil, nil, nil, nil, 219, nil, nil, nil, + nil, 219, 219, 219, 219, nil, 219, 219, 219, 219, + nil, nil, nil, nil, 219, 219, nil, nil, nil, 220, + 220, 220, 219, 220, 219, 219, 219, 220, 220, nil, + nil, nil, 220, nil, 220, 220, 220, 220, 220, 220, + 220, nil, nil, nil, nil, nil, 220, 220, 220, 220, + 220, 220, 220, nil, nil, 220, nil, nil, nil, nil, + nil, nil, 220, nil, nil, 220, 220, 220, 220, 220, + 220, 220, 220, nil, 220, 220, 220, nil, 220, 220, + 220, 220, 220, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 220, nil, nil, 220, nil, nil, 220, 220, + nil, nil, 220, nil, nil, nil, nil, nil, 220, nil, + nil, nil, nil, nil, nil, nil, nil, 220, nil, nil, + nil, nil, 220, 220, 220, 220, nil, 220, 220, 220, + 220, nil, nil, nil, nil, 220, 220, nil, nil, nil, + 221, 221, 221, 220, 221, 220, 220, 220, 221, 221, + nil, nil, nil, 221, nil, 221, 221, 221, 221, 221, + 221, 221, nil, nil, nil, nil, nil, 221, 221, 221, + 221, 221, 221, 221, nil, nil, 221, nil, nil, nil, + nil, nil, nil, 221, nil, nil, 221, 221, 221, 221, + 221, 221, 221, 221, nil, 221, 221, 221, nil, 221, + 221, 221, 221, 221, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 221, nil, nil, 221, nil, nil, 221, + 221, nil, nil, 221, nil, nil, nil, nil, nil, 221, + nil, nil, nil, nil, nil, nil, nil, nil, 221, nil, + nil, nil, nil, 221, 221, 221, 221, nil, 221, 221, + 221, 221, nil, nil, nil, nil, 221, 221, 221, nil, + nil, 232, 232, 232, 221, 232, 221, 221, 221, 232, + 232, nil, nil, nil, 232, nil, 232, 232, 232, 232, + 232, 232, 232, nil, nil, nil, nil, nil, 232, 232, + 232, 232, 232, 232, 232, nil, nil, 232, nil, nil, + nil, nil, nil, nil, 232, nil, nil, 232, 232, 232, + 232, 232, 232, 232, 232, nil, 232, 232, 232, nil, + 232, 232, 232, 232, 232, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 232, nil, nil, 232, nil, nil, + 232, 232, nil, nil, 232, nil, nil, nil, nil, nil, + 232, nil, nil, nil, nil, nil, nil, nil, nil, 232, + nil, nil, nil, nil, 232, 232, 232, 232, nil, 232, + 232, 232, 232, nil, nil, nil, nil, 232, 232, nil, + nil, nil, 235, 235, 235, 232, 235, 232, 232, 232, + 235, 235, nil, nil, nil, 235, nil, 235, 235, 235, + 235, 235, 235, 235, nil, nil, nil, nil, nil, 235, + 235, 235, 235, 235, 235, 235, nil, nil, 235, nil, + nil, nil, nil, nil, nil, 235, nil, nil, 235, 235, + 235, 235, 235, 235, 235, 235, nil, 235, 235, 235, + nil, 235, 235, 235, 235, 235, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 235, nil, nil, 235, nil, + nil, 235, 235, nil, nil, 235, nil, nil, nil, nil, + nil, 235, nil, nil, nil, nil, nil, nil, nil, nil, + 235, nil, nil, nil, nil, 235, 235, 235, 235, nil, + 235, 235, 235, 235, nil, nil, nil, nil, 235, 235, + nil, nil, nil, 236, 236, 236, 235, 236, 235, 235, + 235, 236, 236, nil, nil, nil, 236, nil, 236, 236, + 236, 236, 236, 236, 236, nil, nil, nil, nil, nil, + 236, 236, 236, 236, 236, 236, 236, nil, nil, 236, + nil, nil, nil, nil, nil, nil, 236, nil, nil, 236, + 236, 236, 236, 236, 236, 236, 236, nil, 236, 236, + 236, nil, 236, 236, 236, 236, 236, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 236, nil, nil, 236, + nil, nil, 236, 236, nil, nil, 236, nil, nil, nil, + nil, nil, 236, nil, nil, nil, nil, nil, nil, nil, + nil, 236, nil, nil, nil, nil, 236, 236, 236, 236, + nil, 236, 236, 236, 236, nil, nil, nil, nil, 236, + 236, nil, nil, nil, 237, 237, 237, 236, 237, 236, + 236, 236, 237, 237, nil, nil, nil, 237, nil, 237, + 237, 237, 237, 237, 237, 237, nil, nil, nil, nil, + nil, 237, 237, 237, 237, 237, 237, 237, nil, nil, + 237, nil, nil, nil, nil, nil, nil, 237, nil, nil, + 237, 237, 237, 237, 237, 237, 237, 237, nil, 237, + 237, 237, nil, 237, 237, 237, 237, 237, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 237, nil, nil, + 237, nil, nil, 237, 237, nil, nil, 237, nil, nil, + nil, nil, nil, 237, nil, nil, nil, nil, nil, nil, + nil, nil, 237, nil, nil, nil, nil, 237, 237, 237, + 237, nil, 237, 237, 237, 237, nil, nil, nil, nil, + 237, 237, nil, nil, nil, 238, 238, 238, 237, 238, + 237, 237, 237, 238, 238, nil, nil, nil, 238, nil, + 238, 238, 238, 238, 238, 238, 238, nil, nil, nil, + nil, nil, 238, 238, 238, 238, 238, 238, 238, nil, + nil, 238, nil, nil, nil, nil, nil, nil, 238, nil, + nil, 238, 238, 238, 238, 238, 238, 238, 238, nil, + 238, 238, 238, nil, 238, 238, 238, 238, 238, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 238, nil, + nil, 238, nil, nil, 238, 238, nil, nil, 238, nil, + nil, nil, nil, nil, 238, nil, nil, nil, nil, nil, + nil, nil, nil, 238, nil, nil, nil, nil, 238, 238, + 238, 238, nil, 238, 238, 238, 238, nil, nil, nil, + nil, 238, 238, nil, nil, nil, 239, 239, 239, 238, + 239, 238, 238, 238, 239, 239, nil, nil, nil, 239, + nil, 239, 239, 239, 239, 239, 239, 239, nil, nil, + nil, nil, nil, 239, 239, 239, 239, 239, 239, 239, + nil, nil, 239, nil, nil, nil, nil, nil, nil, 239, + nil, nil, 239, 239, 239, 239, 239, 239, 239, 239, + nil, 239, 239, 239, nil, 239, 239, 239, 239, 239, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 239, + nil, nil, 239, nil, nil, 239, 239, nil, nil, 239, + nil, nil, nil, nil, nil, 239, nil, nil, nil, nil, + nil, nil, nil, nil, 239, nil, nil, nil, nil, 239, + 239, 239, 239, nil, 239, 239, 239, 239, nil, nil, + nil, nil, 239, 239, nil, nil, nil, 240, 240, 240, + 239, 240, 239, 239, 239, 240, 240, nil, nil, nil, + 240, nil, 240, 240, 240, 240, 240, 240, 240, nil, + nil, nil, nil, nil, 240, 240, 240, 240, 240, 240, + 240, nil, nil, 240, nil, nil, nil, nil, nil, nil, + 240, nil, nil, 240, 240, 240, 240, 240, 240, 240, + 240, nil, 240, 240, 240, nil, 240, 240, 240, 240, + 240, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 240, nil, nil, 240, nil, nil, 240, 240, nil, nil, + 240, nil, nil, nil, nil, nil, 240, nil, nil, nil, + nil, nil, nil, nil, nil, 240, nil, nil, nil, nil, + 240, 240, 240, 240, nil, 240, 240, 240, 240, nil, + nil, nil, nil, 240, 240, nil, nil, nil, 241, 241, + 241, 240, 241, 240, 240, 240, 241, 241, nil, nil, + nil, 241, nil, 241, 241, 241, 241, 241, 241, 241, + nil, nil, nil, nil, nil, 241, 241, 241, 241, 241, + 241, 241, nil, nil, 241, nil, nil, nil, nil, nil, + nil, 241, nil, nil, 241, 241, 241, 241, 241, 241, + 241, 241, nil, 241, 241, 241, nil, 241, 241, 241, + 241, 241, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 241, nil, nil, 241, nil, nil, 241, 241, nil, + nil, 241, nil, nil, nil, nil, nil, 241, nil, nil, + nil, nil, nil, nil, nil, nil, 241, nil, nil, nil, + nil, 241, 241, 241, 241, nil, 241, 241, 241, 241, + nil, nil, nil, nil, 241, 241, nil, nil, nil, 242, + 242, 242, 241, 242, 241, 241, 241, 242, 242, nil, + nil, nil, 242, nil, 242, 242, 242, 242, 242, 242, + 242, nil, nil, nil, nil, nil, 242, 242, 242, 242, + 242, 242, 242, nil, nil, 242, nil, nil, nil, nil, + nil, nil, 242, nil, nil, 242, 242, 242, 242, 242, + 242, 242, 242, nil, 242, 242, 242, nil, 242, 242, + 242, 242, 242, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 242, nil, nil, 242, nil, nil, 242, 242, + nil, nil, 242, nil, nil, nil, nil, nil, 242, nil, + nil, nil, nil, nil, nil, nil, nil, 242, nil, nil, + nil, nil, 242, 242, 242, 242, nil, 242, 242, 242, + 242, nil, nil, nil, nil, 242, 242, nil, nil, nil, + 243, 243, 243, 242, 243, 242, 242, 242, 243, 243, + nil, nil, nil, 243, nil, 243, 243, 243, 243, 243, + 243, 243, nil, nil, nil, nil, nil, 243, 243, 243, + 243, 243, 243, 243, nil, nil, 243, nil, nil, nil, + nil, nil, nil, 243, nil, nil, 243, 243, 243, 243, + 243, 243, 243, 243, nil, 243, 243, 243, nil, 243, + 243, 243, 243, 243, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 243, nil, nil, 243, nil, nil, 243, + 243, nil, nil, 243, nil, nil, nil, nil, nil, 243, + nil, nil, nil, nil, nil, nil, nil, nil, 243, nil, + nil, nil, nil, 243, 243, 243, 243, nil, 243, 243, + 243, 243, nil, nil, nil, nil, 243, 243, nil, nil, + nil, 244, 244, 244, 243, 244, 243, 243, 243, 244, + 244, nil, nil, nil, 244, nil, 244, 244, 244, 244, + 244, 244, 244, nil, nil, nil, nil, nil, 244, 244, + 244, 244, 244, 244, 244, nil, nil, 244, nil, nil, + nil, nil, nil, nil, 244, nil, nil, 244, 244, 244, + 244, 244, 244, 244, 244, nil, 244, 244, 244, nil, + 244, 244, 244, 244, 244, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 244, nil, nil, 244, nil, nil, + 244, 244, nil, nil, 244, nil, nil, nil, nil, nil, + 244, nil, nil, nil, nil, nil, nil, nil, nil, 244, + nil, nil, nil, nil, 244, 244, 244, 244, nil, 244, + 244, 244, 244, nil, nil, nil, nil, 244, 244, nil, + nil, nil, 245, 245, 245, 244, 245, 244, 244, 244, + 245, 245, nil, nil, nil, 245, nil, 245, 245, 245, + 245, 245, 245, 245, nil, nil, nil, nil, nil, 245, + 245, 245, 245, 245, 245, 245, nil, nil, 245, nil, + nil, nil, nil, nil, nil, 245, nil, nil, 245, 245, + 245, 245, 245, 245, 245, 245, nil, 245, 245, 245, + nil, 245, 245, 245, 245, 245, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 245, nil, nil, 245, nil, + nil, 245, 245, nil, nil, 245, nil, nil, nil, nil, + nil, 245, nil, nil, nil, nil, nil, nil, nil, nil, + 245, nil, nil, nil, nil, 245, 245, 245, 245, nil, + 245, 245, 245, 245, nil, nil, nil, nil, 245, 245, + nil, nil, nil, 246, 246, 246, 245, 246, 245, 245, + 245, 246, 246, nil, nil, nil, 246, nil, 246, 246, + 246, 246, 246, 246, 246, nil, nil, nil, nil, nil, + 246, 246, 246, 246, 246, 246, 246, nil, nil, 246, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 246, + 246, 246, 246, 246, 246, 246, 246, nil, 246, 246, + 246, nil, 246, 246, 246, 246, 246, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 246, + nil, nil, 246, 246, nil, nil, 246, nil, nil, nil, + nil, nil, 246, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, nil, nil, 246, 246, 246, 246, + nil, 246, 246, 246, 246, nil, nil, nil, nil, 246, + 246, nil, nil, nil, 247, 247, 247, 246, 247, 246, + 246, 246, 247, 247, nil, nil, nil, 247, nil, 247, + 247, 247, 247, 247, 247, 247, nil, nil, nil, nil, + nil, 247, 247, 247, 247, 247, 247, 247, nil, nil, + 247, nil, nil, nil, nil, nil, nil, 247, nil, nil, + 247, 247, 247, 247, 247, 247, 247, 247, nil, 247, + 247, 247, nil, 247, 247, 247, 247, 247, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 247, nil, nil, + 247, nil, nil, 247, 247, nil, nil, 247, nil, nil, + nil, nil, nil, 247, nil, nil, nil, nil, nil, nil, + nil, nil, 247, nil, nil, nil, nil, 247, 247, 247, + 247, nil, 247, 247, 247, 247, nil, nil, nil, nil, + 247, 247, nil, nil, nil, 248, 248, 248, 247, 248, + 247, 247, 247, 248, 248, nil, nil, nil, 248, nil, + 248, 248, 248, 248, 248, 248, 248, nil, nil, nil, + nil, nil, 248, 248, 248, 248, 248, 248, 248, nil, + nil, 248, nil, nil, nil, nil, nil, nil, 248, nil, + nil, 248, 248, 248, 248, 248, 248, 248, 248, nil, + 248, 248, 248, nil, 248, 248, 248, 248, 248, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 248, nil, + nil, 248, nil, nil, 248, 248, nil, nil, 248, nil, + nil, nil, nil, nil, 248, nil, nil, nil, nil, nil, + nil, nil, nil, 248, nil, nil, nil, nil, 248, 248, + 248, 248, nil, 248, 248, 248, 248, nil, nil, nil, + nil, 248, 248, nil, nil, nil, 249, 249, 249, 248, + 249, 248, 248, 248, 249, 249, nil, nil, nil, 249, + nil, 249, 249, 249, 249, 249, 249, 249, nil, nil, + nil, nil, nil, 249, 249, 249, 249, 249, 249, 249, + nil, nil, 249, nil, nil, nil, nil, nil, nil, 249, + nil, nil, 249, 249, 249, 249, 249, 249, 249, 249, + nil, 249, 249, 249, nil, 249, 249, 249, 249, 249, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 249, + nil, nil, 249, nil, nil, 249, 249, nil, nil, 249, + nil, nil, nil, nil, nil, 249, nil, nil, nil, nil, + nil, nil, nil, nil, 249, nil, nil, nil, nil, 249, + 249, 249, 249, nil, 249, 249, 249, 249, nil, nil, + nil, nil, 249, 249, nil, nil, nil, 250, 250, 250, + 249, 250, 249, 249, 249, 250, 250, nil, nil, nil, + 250, nil, 250, 250, 250, 250, 250, 250, 250, nil, + nil, nil, nil, nil, 250, 250, 250, 250, 250, 250, + 250, nil, nil, 250, nil, nil, nil, nil, nil, nil, + 250, nil, nil, 250, 250, 250, 250, 250, 250, 250, + 250, nil, 250, 250, 250, nil, 250, 250, 250, 250, + 250, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 250, nil, nil, 250, nil, nil, 250, 250, nil, nil, + 250, nil, nil, nil, nil, nil, 250, nil, nil, nil, + nil, nil, nil, nil, nil, 250, nil, nil, nil, nil, + 250, 250, 250, 250, nil, 250, 250, 250, 250, nil, + nil, nil, nil, 250, 250, nil, nil, nil, 251, 251, + 251, 250, 251, 250, 250, 250, 251, 251, nil, nil, + nil, 251, nil, 251, 251, 251, 251, 251, 251, 251, + nil, nil, nil, nil, nil, 251, 251, 251, 251, 251, + 251, 251, nil, nil, 251, nil, nil, nil, nil, nil, + nil, 251, nil, nil, 251, 251, 251, 251, 251, 251, + 251, 251, nil, 251, 251, 251, nil, 251, 251, 251, + 251, 251, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, 251, nil, nil, 251, 251, nil, + nil, 251, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 251, 251, 251, 251, nil, 251, 251, 251, 251, + nil, nil, nil, nil, 251, 251, nil, nil, nil, 252, + 252, 252, 251, 252, 251, 251, 251, 252, 252, nil, + nil, nil, 252, nil, 252, 252, 252, 252, 252, 252, + 252, nil, nil, nil, nil, nil, 252, 252, 252, 252, + 252, 252, 252, nil, nil, 252, nil, nil, nil, nil, + nil, nil, 252, nil, nil, 252, 252, 252, 252, 252, + 252, 252, 252, nil, 252, 252, 252, nil, 252, 252, + 252, 252, 252, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 252, nil, nil, 252, nil, nil, 252, 252, + nil, nil, 252, nil, nil, nil, nil, nil, 252, nil, + nil, nil, nil, nil, nil, nil, nil, 252, nil, nil, + nil, nil, 252, 252, 252, 252, nil, 252, 252, 252, + 252, nil, nil, nil, nil, 252, 252, nil, nil, nil, + 253, 253, 253, 252, 253, 252, 252, 252, 253, 253, + nil, nil, nil, 253, nil, 253, 253, 253, 253, 253, + 253, 253, nil, nil, nil, nil, nil, 253, 253, 253, + 253, 253, 253, 253, nil, nil, 253, nil, nil, nil, + nil, nil, nil, 253, nil, nil, 253, 253, 253, 253, + 253, 253, 253, 253, nil, 253, 253, 253, nil, 253, + 253, 253, 253, 253, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 253, nil, nil, 253, nil, nil, 253, + 253, nil, nil, 253, nil, nil, nil, nil, nil, 253, + nil, nil, nil, nil, nil, nil, nil, nil, 253, nil, + nil, nil, nil, 253, 253, 253, 253, nil, 253, 253, + 253, 253, nil, nil, nil, nil, 253, 253, nil, nil, + nil, 254, 254, 254, 253, 254, 253, 253, 253, 254, + 254, nil, nil, nil, 254, nil, 254, 254, 254, 254, + 254, 254, 254, nil, nil, nil, nil, nil, 254, 254, + 254, 254, 254, 254, 254, nil, nil, 254, nil, nil, + nil, nil, nil, nil, 254, nil, nil, 254, 254, 254, + 254, 254, 254, 254, 254, nil, 254, 254, 254, nil, + 254, 254, 254, 254, 254, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 254, nil, nil, 254, nil, nil, + 254, 254, nil, nil, 254, nil, nil, nil, nil, nil, + 254, nil, nil, nil, nil, nil, nil, nil, nil, 254, + nil, nil, nil, nil, 254, 254, 254, 254, nil, 254, + 254, 254, 254, nil, nil, nil, nil, 254, 254, nil, + nil, nil, 255, 255, 255, 254, 255, 254, 254, 254, + 255, 255, nil, nil, nil, 255, nil, 255, 255, 255, + 255, 255, 255, 255, nil, nil, nil, nil, nil, 255, + 255, 255, 255, 255, 255, 255, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 255, nil, nil, 255, 255, + 255, 255, 255, 255, 255, 255, nil, 255, 255, 255, + nil, 255, 255, 255, 255, 255, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 255, nil, nil, 255, nil, + nil, 255, 255, nil, nil, 255, nil, nil, nil, nil, + nil, 255, nil, nil, nil, nil, nil, nil, nil, nil, + 255, nil, nil, nil, nil, 255, 255, 255, 255, nil, + 255, 255, 255, 255, nil, nil, nil, nil, 255, 255, + nil, nil, nil, 256, 256, 256, 255, 256, 255, 255, + 255, 256, 256, nil, nil, nil, 256, nil, 256, 256, + 256, 256, 256, 256, 256, nil, nil, nil, nil, nil, + 256, 256, 256, 256, 256, 256, 256, nil, nil, 256, + nil, nil, nil, nil, nil, nil, 256, nil, nil, 256, + 256, 256, 256, 256, 256, 256, 256, nil, 256, 256, + 256, nil, 256, 256, 256, 256, 256, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 256, nil, nil, 256, + nil, nil, 256, 256, nil, nil, 256, nil, nil, nil, + nil, nil, 256, nil, nil, nil, nil, nil, nil, nil, + nil, 256, nil, nil, nil, nil, 256, 256, 256, 256, + nil, 256, 256, 256, 256, nil, nil, nil, nil, 256, + 256, nil, nil, nil, 257, 257, 257, 256, 257, 256, + 256, 256, 257, 257, nil, nil, nil, 257, nil, 257, + 257, 257, 257, 257, 257, 257, nil, nil, nil, nil, + nil, 257, 257, 257, 257, 257, 257, 257, nil, nil, + 257, nil, nil, nil, nil, nil, nil, 257, nil, nil, + 257, 257, 257, 257, 257, 257, 257, 257, nil, 257, + 257, 257, nil, 257, 257, 257, 257, 257, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 257, nil, nil, + 257, nil, nil, 257, 257, nil, nil, 257, nil, nil, + nil, nil, nil, 257, nil, nil, nil, nil, nil, nil, + nil, nil, 257, nil, nil, nil, nil, 257, 257, 257, + 257, nil, 257, 257, 257, 257, nil, nil, nil, nil, + 257, 257, nil, nil, nil, 258, 258, 258, 257, 258, + 257, 257, 257, 258, 258, nil, nil, nil, 258, nil, + 258, 258, 258, 258, 258, 258, 258, nil, nil, nil, + nil, nil, 258, 258, 258, 258, 258, 258, 258, nil, + nil, 258, nil, nil, nil, nil, nil, nil, 258, nil, + nil, 258, 258, 258, 258, 258, 258, 258, 258, nil, + 258, 258, 258, nil, 258, 258, 258, 258, 258, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 258, nil, + nil, 258, nil, nil, 258, 258, nil, nil, 258, nil, + nil, nil, nil, nil, 258, nil, nil, nil, nil, nil, + nil, nil, nil, 258, nil, nil, nil, nil, 258, 258, + 258, 258, nil, 258, 258, 258, 258, nil, nil, nil, + nil, 258, 258, nil, nil, nil, 259, 259, 259, 258, + 259, 258, 258, 258, 259, 259, nil, nil, nil, 259, + nil, 259, 259, 259, 259, 259, 259, 259, nil, nil, + nil, nil, nil, 259, 259, 259, 259, 259, 259, 259, + nil, nil, 259, nil, nil, nil, nil, nil, nil, 259, + nil, nil, 259, 259, 259, 259, 259, 259, 259, 259, + nil, 259, 259, 259, nil, 259, 259, 259, 259, 259, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 259, + nil, nil, 259, nil, nil, 259, 259, nil, nil, 259, + nil, nil, nil, nil, nil, 259, nil, nil, nil, nil, + nil, nil, nil, nil, 259, nil, nil, nil, nil, 259, + 259, 259, 259, nil, 259, 259, 259, 259, nil, nil, + nil, nil, 259, 259, nil, nil, nil, 260, 260, 260, + 259, 260, 259, 259, 259, 260, 260, nil, nil, nil, + 260, nil, 260, 260, 260, 260, 260, 260, 260, nil, + nil, nil, nil, nil, 260, 260, 260, 260, 260, 260, + 260, nil, nil, 260, nil, nil, nil, nil, nil, nil, + 260, nil, nil, 260, 260, 260, 260, 260, 260, 260, + 260, nil, 260, 260, 260, nil, 260, 260, 260, 260, + 260, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 260, nil, nil, 260, nil, nil, 260, 260, nil, nil, + 260, nil, nil, nil, nil, nil, 260, nil, nil, nil, + nil, nil, nil, nil, nil, 260, nil, nil, nil, nil, + 260, 260, 260, 260, nil, 260, 260, 260, 260, nil, + nil, nil, nil, 260, 260, nil, nil, nil, 267, 267, + 267, 260, 267, 260, 260, 260, 267, 267, nil, nil, + nil, 267, nil, 267, 267, 267, 267, 267, 267, 267, + nil, nil, nil, nil, nil, 267, 267, 267, 267, 267, + 267, 267, nil, nil, 267, nil, nil, nil, nil, nil, + nil, 267, nil, nil, 267, 267, 267, 267, 267, 267, + 267, 267, 267, 267, 267, 267, nil, 267, 267, 267, + 267, 267, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 267, nil, nil, 267, nil, nil, 267, 267, nil, + nil, 267, nil, 267, nil, 267, nil, 267, nil, nil, + 267, nil, nil, nil, nil, nil, 267, nil, nil, nil, + nil, 267, 267, 267, 267, nil, 267, 267, 267, 267, + nil, nil, nil, nil, 267, 267, nil, nil, nil, 268, + 268, 268, 267, 268, 267, 267, 267, 268, 268, nil, + nil, nil, 268, nil, 268, 268, 268, 268, 268, 268, + 268, nil, nil, nil, nil, nil, 268, 268, 268, 268, + 268, 268, 268, nil, nil, 268, nil, nil, nil, nil, + nil, nil, 268, nil, nil, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 268, 268, nil, 268, 268, + 268, 268, 268, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 268, nil, nil, 268, nil, nil, 268, 268, + nil, nil, 268, nil, 268, nil, 268, nil, 268, nil, + nil, 268, nil, nil, nil, nil, nil, 268, nil, nil, + nil, nil, 268, 268, 268, 268, nil, 268, 268, 268, + 268, nil, nil, nil, nil, 268, 268, nil, nil, nil, + 276, 276, 276, 268, 276, 268, 268, 268, 276, 276, + nil, nil, nil, 276, nil, 276, 276, 276, 276, 276, + 276, 276, nil, nil, nil, nil, nil, 276, 276, 276, + 276, 276, 276, 276, nil, nil, 276, nil, nil, nil, + nil, nil, nil, 276, nil, nil, 276, 276, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, nil, 276, + 276, 276, 276, 276, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 276, nil, nil, 276, nil, nil, 276, + 276, nil, nil, 276, nil, 276, nil, 276, nil, 276, + nil, nil, 276, nil, nil, nil, nil, nil, 276, nil, + nil, nil, nil, 276, 276, 276, 276, nil, 276, 276, + 276, 276, nil, nil, nil, nil, 276, 276, 276, nil, + nil, 283, 283, 283, 276, 283, 276, 276, 276, 283, + 283, nil, nil, nil, 283, nil, 283, 283, 283, 283, + 283, 283, 283, nil, nil, nil, nil, nil, 283, 283, + 283, 283, 283, 283, 283, nil, nil, 283, nil, nil, + nil, nil, nil, nil, 283, nil, nil, 283, 283, 283, + 283, 283, 283, 283, 283, nil, 283, 283, 283, nil, + 283, 283, 283, 283, 283, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 283, nil, nil, 283, nil, nil, + 283, 283, nil, nil, 283, nil, nil, nil, nil, nil, + 283, nil, nil, nil, nil, nil, nil, nil, nil, 283, + nil, nil, nil, nil, 283, 283, 283, 283, nil, 283, + 283, 283, 283, nil, nil, nil, nil, 283, 283, nil, + nil, nil, 285, 285, 285, 283, 285, 283, 283, 283, + 285, 285, nil, nil, nil, 285, nil, 285, 285, 285, + 285, 285, 285, 285, nil, nil, nil, nil, nil, 285, + 285, 285, 285, 285, 285, 285, nil, nil, 285, nil, + nil, nil, nil, nil, nil, 285, nil, nil, 285, 285, + 285, 285, 285, 285, 285, 285, nil, 285, 285, 285, + nil, 285, 285, 285, 285, 285, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 285, nil, nil, 285, nil, + nil, 285, 285, nil, nil, 285, nil, nil, nil, nil, + nil, 285, nil, nil, nil, nil, nil, nil, nil, nil, + 285, nil, nil, nil, nil, 285, 285, 285, 285, nil, + 285, 285, 285, 285, nil, nil, nil, nil, 285, 285, + nil, nil, nil, 288, 288, 288, 285, 288, 285, 285, + 285, 288, 288, nil, nil, nil, 288, nil, 288, 288, + 288, 288, 288, 288, 288, nil, nil, nil, nil, nil, + 288, 288, 288, 288, 288, 288, 288, nil, nil, 288, + nil, nil, nil, nil, nil, nil, 288, nil, nil, 288, + 288, 288, 288, 288, 288, 288, 288, nil, 288, 288, + 288, nil, 288, 288, 288, 288, 288, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 288, nil, nil, 288, + nil, nil, 288, 288, nil, nil, 288, nil, nil, nil, + nil, nil, 288, nil, nil, nil, nil, nil, nil, nil, + nil, 288, nil, nil, nil, nil, 288, 288, 288, 288, + nil, 288, 288, 288, 288, nil, nil, nil, nil, 288, + 288, nil, nil, nil, 289, 289, 289, 288, 289, 288, + 288, 288, 289, 289, nil, nil, nil, 289, nil, 289, + 289, 289, 289, 289, 289, 289, nil, nil, nil, nil, + nil, 289, 289, 289, 289, 289, 289, 289, nil, nil, + 289, nil, nil, nil, nil, nil, nil, 289, nil, nil, + 289, 289, 289, 289, 289, 289, 289, 289, nil, 289, + 289, 289, nil, 289, 289, 289, 289, 289, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 289, nil, nil, + 289, nil, nil, 289, 289, nil, nil, 289, nil, nil, + nil, nil, nil, 289, nil, nil, nil, nil, nil, nil, + nil, nil, 289, nil, nil, nil, nil, 289, 289, 289, + 289, nil, 289, 289, 289, 289, nil, nil, nil, nil, + 289, 289, nil, nil, nil, nil, nil, nil, 289, nil, + 289, 289, 289, 294, 294, 294, 294, 294, nil, nil, + nil, 294, 294, nil, nil, nil, 294, nil, 294, 294, + 294, 294, 294, 294, 294, nil, nil, nil, nil, nil, + 294, 294, 294, 294, 294, 294, 294, nil, nil, 294, + nil, nil, nil, nil, nil, 294, 294, nil, 294, 294, + 294, 294, 294, 294, 294, 294, 294, nil, 294, 294, + 294, nil, 294, 294, 294, 294, 294, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 294, nil, nil, 294, + nil, nil, 294, 294, nil, nil, 294, nil, 294, nil, + nil, nil, 294, nil, nil, nil, nil, nil, nil, nil, + nil, 294, nil, nil, nil, nil, 294, 294, 294, 294, + nil, 294, 294, 294, 294, nil, nil, nil, nil, 294, + 294, nil, nil, nil, 302, 302, 302, 294, 302, 294, + 294, 294, 302, 302, nil, nil, nil, 302, nil, 302, + 302, 302, 302, 302, 302, 302, nil, nil, nil, nil, + nil, 302, 302, 302, 302, 302, 302, 302, nil, nil, + 302, nil, nil, nil, nil, nil, nil, 302, nil, nil, + 302, 302, 302, 302, 302, 302, 302, 302, nil, 302, + 302, 302, nil, 302, 302, nil, nil, 302, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 302, nil, nil, + 302, nil, nil, 302, 302, nil, nil, 302, nil, nil, + 939, nil, 939, 939, 939, 939, 939, nil, nil, nil, + nil, nil, nil, nil, nil, 939, nil, 302, 302, 302, + 302, nil, 302, 302, 302, 302, nil, nil, nil, nil, + 302, 302, nil, nil, nil, 302, nil, 939, 302, nil, + 302, 302, 302, 319, 319, 319, nil, 319, 939, 939, + nil, 319, 319, 939, nil, nil, 319, nil, 319, 319, + 319, 319, 319, 319, 319, nil, nil, nil, nil, nil, + 319, 319, 319, 319, 319, 319, 319, nil, nil, 319, + nil, nil, nil, nil, nil, nil, 319, nil, nil, 319, + 319, 319, 319, 319, 319, 319, 319, nil, 319, 319, + 319, nil, 319, 319, nil, nil, 319, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 319, nil, nil, 319, + nil, nil, 319, 319, nil, nil, 319, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 319, 319, 319, 319, + nil, 319, 319, 319, 319, nil, nil, nil, nil, 319, + 319, nil, nil, nil, 327, 327, 327, 319, 327, 319, + 319, 319, 327, 327, nil, nil, nil, 327, nil, 327, + 327, 327, 327, 327, 327, 327, nil, nil, nil, nil, + nil, 327, 327, 327, 327, 327, 327, 327, nil, nil, + 327, nil, nil, nil, nil, nil, nil, 327, nil, nil, + 327, 327, 327, 327, 327, 327, 327, 327, nil, 327, + 327, 327, nil, 327, 327, 327, 327, 327, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 327, nil, nil, + 327, 327, nil, 327, 327, nil, nil, 327, nil, nil, + nil, nil, nil, 327, nil, nil, nil, nil, nil, nil, + nil, nil, 327, nil, nil, nil, nil, 327, 327, 327, + 327, nil, 327, 327, 327, 327, nil, nil, nil, nil, + 327, 327, nil, nil, nil, 329, 329, 329, 327, 329, + 327, 327, 327, 329, 329, nil, nil, nil, 329, nil, + 329, 329, 329, 329, 329, 329, 329, nil, nil, nil, + nil, nil, 329, 329, 329, 329, 329, 329, 329, nil, + nil, 329, nil, nil, nil, nil, nil, nil, 329, nil, + nil, 329, 329, 329, 329, 329, 329, 329, 329, nil, + 329, 329, 329, nil, 329, 329, 329, 329, 329, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 329, nil, + nil, 329, nil, nil, 329, 329, nil, nil, 329, nil, + nil, nil, nil, nil, 329, nil, nil, nil, nil, nil, + nil, nil, nil, 329, nil, nil, nil, nil, 329, 329, + 329, 329, nil, 329, 329, 329, 329, nil, nil, nil, + nil, 329, 329, nil, nil, nil, 343, 343, 343, 329, + 343, 329, 329, 329, 343, 343, nil, nil, nil, 343, + nil, 343, 343, 343, 343, 343, 343, 343, nil, nil, + nil, nil, nil, 343, 343, 343, 343, 343, 343, 343, + nil, nil, 343, nil, nil, nil, nil, nil, nil, 343, + nil, nil, 343, 343, 343, 343, 343, 343, 343, 343, + nil, 343, 343, 343, nil, 343, 343, 343, 343, 343, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 343, + nil, nil, 343, nil, nil, 343, 343, nil, nil, 343, + nil, nil, nil, nil, nil, 343, nil, nil, nil, nil, + nil, nil, nil, nil, 343, nil, nil, nil, nil, 343, + 343, 343, 343, nil, 343, 343, 343, 343, nil, nil, + nil, nil, 343, 343, nil, nil, nil, 344, 344, 344, + 343, 344, 343, 343, 343, 344, 344, nil, nil, nil, + 344, nil, 344, 344, 344, 344, 344, 344, 344, nil, + nil, nil, nil, nil, 344, 344, 344, 344, 344, 344, + 344, nil, nil, 344, nil, nil, nil, nil, nil, nil, + 344, nil, nil, 344, 344, 344, 344, 344, 344, 344, + 344, nil, 344, 344, 344, nil, 344, 344, 344, 344, + 344, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 344, nil, nil, 344, nil, nil, 344, 344, nil, nil, + 344, nil, nil, nil, nil, nil, 344, nil, nil, nil, + nil, nil, nil, nil, nil, 344, nil, nil, nil, nil, + 344, 344, 344, 344, nil, 344, 344, 344, 344, nil, + nil, nil, nil, 344, 344, nil, nil, nil, 363, 363, + 363, 344, 363, 344, 344, 344, 363, 363, nil, nil, + nil, 363, nil, 363, 363, 363, 363, 363, 363, 363, + nil, nil, nil, nil, nil, 363, 363, 363, 363, 363, + 363, 363, nil, nil, 363, nil, nil, nil, nil, nil, + nil, 363, nil, nil, 363, 363, 363, 363, 363, 363, + 363, 363, nil, 363, 363, 363, nil, 363, 363, 363, + 363, 363, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 363, nil, nil, 363, nil, nil, 363, 363, nil, + nil, 363, nil, nil, nil, nil, nil, 363, nil, nil, + nil, nil, nil, nil, nil, nil, 363, nil, nil, nil, + nil, 363, 363, 363, 363, nil, 363, 363, 363, 363, + nil, nil, nil, nil, 363, 363, nil, nil, nil, 379, + 379, 379, 363, 379, 363, 363, 363, 379, 379, nil, + nil, nil, 379, nil, 379, 379, 379, 379, 379, 379, + 379, nil, nil, nil, nil, nil, 379, 379, 379, 379, + 379, 379, 379, nil, nil, 379, nil, nil, nil, nil, + nil, nil, 379, nil, nil, 379, 379, 379, 379, 379, + 379, 379, 379, nil, 379, 379, 379, nil, 379, 379, + 379, 379, 379, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 379, nil, nil, 379, nil, nil, 379, 379, + nil, nil, 379, nil, nil, nil, nil, nil, 379, nil, + nil, nil, nil, nil, nil, nil, nil, 379, nil, nil, + nil, nil, 379, 379, 379, 379, nil, 379, 379, 379, + 379, nil, nil, nil, nil, 379, 379, nil, nil, nil, + 407, 407, 407, 379, 407, 379, 379, 379, 407, 407, + nil, nil, nil, 407, nil, 407, 407, 407, 407, 407, + 407, 407, nil, nil, nil, nil, nil, 407, 407, 407, + 407, 407, 407, 407, nil, nil, 407, nil, nil, nil, + nil, nil, nil, 407, nil, nil, 407, 407, 407, 407, + 407, 407, 407, 407, nil, 407, 407, 407, nil, 407, + 407, 407, 407, 407, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 407, nil, nil, 407, nil, nil, 407, + 407, nil, nil, 407, nil, nil, nil, nil, nil, 407, + nil, nil, nil, nil, nil, nil, nil, nil, 407, nil, + nil, nil, nil, 407, 407, 407, 407, nil, 407, 407, + 407, 407, nil, nil, nil, nil, 407, 407, nil, nil, + nil, 445, 445, 445, 407, 445, 407, 407, 407, 445, + 445, nil, nil, nil, 445, nil, 445, 445, 445, 445, + 445, 445, 445, nil, nil, nil, nil, nil, 445, 445, + 445, 445, 445, 445, 445, nil, nil, 445, nil, nil, + nil, nil, nil, nil, 445, nil, nil, 445, 445, 445, + 445, 445, 445, 445, 445, 445, 445, 445, 445, nil, + 445, 445, 445, 445, 445, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 445, nil, nil, 445, nil, nil, + 445, 445, nil, nil, 445, nil, 445, nil, 445, nil, + 445, nil, nil, 445, nil, nil, nil, nil, nil, 445, + nil, nil, nil, nil, 445, 445, 445, 445, nil, 445, + 445, 445, 445, nil, nil, nil, nil, 445, 445, nil, + nil, nil, 447, 447, 447, 445, 447, 445, 445, 445, + 447, 447, nil, nil, nil, 447, nil, 447, 447, 447, + 447, 447, 447, 447, nil, nil, nil, nil, nil, 447, + 447, 447, 447, 447, 447, 447, nil, nil, 447, nil, + nil, nil, nil, nil, nil, 447, nil, nil, 447, 447, + 447, 447, 447, 447, 447, 447, nil, 447, 447, 447, + nil, 447, 447, 447, 447, 447, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 447, nil, nil, 447, nil, + nil, 447, 447, nil, nil, 447, nil, nil, nil, nil, + nil, 447, nil, nil, nil, nil, nil, nil, nil, nil, + 447, nil, nil, nil, nil, 447, 447, 447, 447, nil, + 447, 447, 447, 447, nil, nil, nil, nil, 447, 447, + nil, nil, nil, 448, 448, 448, 447, 448, 447, 447, + 447, 448, 448, nil, nil, nil, 448, nil, 448, 448, + 448, 448, 448, 448, 448, nil, nil, nil, nil, nil, + 448, 448, 448, 448, 448, 448, 448, nil, nil, 448, + nil, nil, nil, nil, nil, nil, 448, nil, nil, 448, + 448, 448, 448, 448, 448, 448, 448, nil, 448, 448, + 448, nil, 448, 448, 448, 448, 448, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 448, nil, nil, 448, + nil, nil, 448, 448, nil, nil, 448, nil, nil, nil, + nil, nil, 448, nil, nil, nil, nil, nil, nil, nil, + nil, 448, nil, nil, nil, nil, 448, 448, 448, 448, + nil, 448, 448, 448, 448, nil, nil, nil, nil, 448, + 448, nil, nil, nil, 449, 449, 449, 448, 449, 448, + 448, 448, 449, 449, nil, nil, nil, 449, nil, 449, + 449, 449, 449, 449, 449, 449, nil, nil, nil, nil, + nil, 449, 449, 449, 449, 449, 449, 449, nil, nil, + 449, nil, nil, nil, nil, nil, nil, 449, nil, nil, + 449, 449, 449, 449, 449, 449, 449, 449, nil, 449, + 449, 449, nil, 449, 449, 449, 449, 449, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 449, nil, nil, + 449, nil, nil, 449, 449, nil, nil, 449, nil, nil, + nil, nil, nil, 449, nil, nil, nil, nil, nil, nil, + nil, nil, 449, nil, nil, nil, nil, 449, 449, 449, + 449, nil, 449, 449, 449, 449, nil, nil, nil, nil, + 449, 449, nil, nil, nil, 489, 489, 489, 449, 489, + 449, 449, 449, 489, 489, nil, nil, nil, 489, nil, + 489, 489, 489, 489, 489, 489, 489, nil, nil, nil, + nil, nil, 489, 489, 489, 489, 489, 489, 489, nil, + nil, 489, nil, nil, nil, nil, nil, nil, 489, nil, + nil, 489, 489, 489, 489, 489, 489, 489, 489, 489, + 489, 489, 489, nil, 489, 489, 489, 489, 489, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 489, nil, + nil, 489, nil, nil, 489, 489, nil, nil, 489, nil, + 489, nil, 489, nil, 489, nil, nil, 489, nil, nil, + nil, nil, nil, 489, nil, nil, nil, nil, 489, 489, + 489, 489, nil, 489, 489, 489, 489, nil, nil, nil, + nil, 489, 489, nil, nil, nil, 491, 491, 491, 489, + 491, 489, 489, 489, 491, 491, nil, nil, nil, 491, + nil, 491, 491, 491, 491, 491, 491, 491, nil, nil, + nil, nil, nil, 491, 491, 491, 491, 491, 491, 491, + nil, nil, 491, nil, nil, nil, nil, nil, nil, 491, + nil, nil, 491, 491, 491, 491, 491, 491, 491, 491, + 491, 491, 491, 491, nil, 491, 491, 491, 491, 491, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 491, + nil, nil, 491, nil, nil, 491, 491, nil, nil, 491, + nil, nil, nil, 491, nil, 491, nil, nil, 491, nil, + nil, nil, nil, nil, 491, nil, nil, nil, nil, 491, + 491, 491, 491, nil, 491, 491, 491, 491, nil, nil, + nil, nil, 491, 491, nil, nil, nil, 493, 493, 493, + 491, 493, 491, 491, 491, 493, 493, nil, nil, nil, + 493, nil, 493, 493, 493, 493, 493, 493, 493, nil, + nil, nil, nil, nil, 493, 493, 493, 493, 493, 493, + 493, nil, nil, 493, nil, nil, nil, nil, nil, nil, + 493, nil, nil, 493, 493, 493, 493, 493, 493, 493, + 493, nil, 493, 493, 493, nil, 493, 493, 493, 493, + 493, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 493, nil, nil, 493, nil, nil, 493, 493, nil, nil, + 493, nil, nil, nil, nil, nil, 493, nil, nil, nil, + nil, nil, nil, nil, nil, 493, nil, nil, nil, nil, + 493, 493, 493, 493, nil, 493, 493, 493, 493, nil, + nil, nil, nil, 493, 493, nil, nil, nil, nil, nil, + nil, 493, nil, 493, 493, 493, 499, 499, 499, 499, + 499, nil, nil, nil, 499, 499, nil, nil, nil, 499, + nil, 499, 499, 499, 499, 499, 499, 499, nil, nil, + nil, nil, nil, 499, 499, 499, 499, 499, 499, 499, + nil, nil, 499, nil, nil, nil, nil, nil, 499, 499, + 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, + nil, 499, 499, 499, nil, 499, 499, 499, 499, 499, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 499, + nil, nil, 499, nil, nil, 499, 499, nil, nil, 499, + nil, 499, nil, nil, nil, 499, nil, nil, nil, nil, + nil, nil, nil, nil, 499, nil, nil, nil, nil, 499, + 499, 499, 499, nil, 499, 499, 499, 499, nil, nil, + nil, nil, 499, 499, nil, nil, nil, nil, nil, 499, + 499, nil, 499, 499, 499, 507, 507, 507, nil, 507, + nil, nil, nil, 507, 507, nil, nil, nil, 507, nil, + 507, 507, 507, 507, 507, 507, 507, nil, nil, nil, + nil, nil, 507, 507, 507, 507, 507, 507, 507, nil, + nil, 507, nil, nil, nil, nil, nil, nil, 507, nil, + nil, 507, 507, 507, 507, 507, 507, 507, 507, nil, + 507, 507, 507, nil, 507, 507, nil, nil, 507, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 507, nil, + nil, 507, nil, nil, 507, 507, nil, nil, 507, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 507, 507, + 507, 507, nil, 507, 507, 507, 507, nil, nil, nil, + nil, 507, 507, nil, nil, nil, 509, 509, 509, 507, + 509, 507, 507, 507, 509, 509, nil, nil, nil, 509, + nil, 509, 509, 509, 509, 509, 509, 509, nil, nil, + nil, nil, nil, 509, 509, 509, 509, 509, 509, 509, + nil, nil, 509, nil, nil, nil, nil, nil, nil, 509, + nil, nil, 509, 509, 509, 509, 509, 509, 509, 509, + 509, 509, 509, 509, nil, 509, 509, 509, 509, 509, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 509, + nil, nil, 509, nil, nil, 509, 509, nil, nil, 509, + nil, 509, nil, 509, nil, 509, nil, nil, 509, nil, + nil, nil, nil, nil, 509, nil, nil, nil, nil, 509, + 509, 509, 509, nil, 509, 509, 509, 509, nil, nil, + nil, nil, 509, 509, nil, nil, nil, 515, 515, 515, + 509, 515, 509, 509, 509, 515, 515, nil, nil, nil, + 515, nil, 515, 515, 515, 515, 515, 515, 515, nil, + nil, nil, nil, nil, 515, 515, 515, 515, 515, 515, + 515, nil, nil, 515, nil, nil, nil, nil, nil, nil, + 515, nil, nil, 515, 515, 515, 515, 515, 515, 515, + 515, nil, 515, 515, 515, nil, 515, 515, nil, nil, + 515, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 515, nil, nil, 515, nil, nil, 515, 515, nil, nil, + 515, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 515, 515, 515, 515, nil, 515, 515, 515, 515, nil, + nil, nil, nil, 515, 515, nil, nil, nil, 518, 518, + 518, 515, 518, 515, 515, 515, 518, 518, nil, nil, + nil, 518, nil, 518, 518, 518, 518, 518, 518, 518, + nil, nil, nil, nil, nil, 518, 518, 518, 518, 518, + 518, 518, nil, nil, 518, nil, nil, nil, nil, nil, + nil, 518, nil, nil, 518, 518, 518, 518, 518, 518, + 518, 518, nil, 518, 518, 518, nil, 518, 518, 518, + 518, 518, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 518, nil, nil, 518, nil, nil, 518, 518, nil, + nil, 518, nil, nil, nil, nil, nil, 518, nil, nil, + nil, nil, nil, nil, nil, nil, 518, nil, nil, nil, + nil, 518, 518, 518, 518, nil, 518, 518, 518, 518, + nil, nil, nil, nil, 518, 518, nil, nil, nil, 519, + 519, 519, 518, 519, 518, 518, 518, 519, 519, nil, + nil, nil, 519, nil, 519, 519, 519, 519, 519, 519, + 519, nil, nil, nil, nil, nil, 519, 519, 519, 519, + 519, 519, 519, nil, nil, 519, nil, nil, nil, nil, + nil, nil, 519, nil, nil, 519, 519, 519, 519, 519, + 519, 519, 519, nil, 519, 519, 519, nil, 519, 519, + 519, 519, 519, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 519, nil, nil, 519, nil, nil, 519, 519, + nil, nil, 519, nil, nil, nil, nil, nil, 519, nil, + nil, nil, nil, nil, nil, nil, nil, 519, nil, nil, + nil, nil, 519, 519, 519, 519, nil, 519, 519, 519, + 519, nil, nil, nil, nil, 519, 519, nil, nil, nil, + 523, 523, 523, 519, 523, 519, 519, 519, 523, 523, + nil, nil, nil, 523, nil, 523, 523, 523, 523, 523, + 523, 523, nil, nil, nil, nil, nil, 523, 523, 523, + 523, 523, 523, 523, nil, nil, 523, nil, nil, nil, + nil, nil, nil, 523, nil, nil, 523, 523, 523, 523, + 523, 523, 523, 523, nil, 523, 523, 523, nil, 523, + 523, 523, 523, 523, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 523, nil, nil, 523, nil, nil, 523, + 523, nil, nil, 523, nil, nil, nil, nil, nil, 523, + nil, nil, nil, nil, nil, nil, nil, nil, 523, nil, + nil, nil, nil, 523, 523, 523, 523, nil, 523, 523, + 523, 523, nil, nil, nil, nil, 523, 523, nil, nil, + nil, 529, 529, 529, 523, 529, 523, 523, 523, 529, + 529, nil, nil, nil, 529, nil, 529, 529, 529, 529, + 529, 529, 529, nil, nil, nil, nil, nil, 529, 529, + 529, 529, 529, 529, 529, nil, nil, 529, nil, nil, + nil, nil, nil, nil, 529, nil, nil, 529, 529, 529, + 529, 529, 529, 529, 529, 529, 529, 529, 529, nil, + 529, 529, 529, 529, 529, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 529, nil, nil, 529, nil, nil, + 529, 529, nil, nil, 529, nil, 529, nil, nil, nil, + 529, nil, nil, 529, nil, nil, nil, nil, nil, 529, + nil, nil, nil, nil, 529, 529, 529, 529, nil, 529, + 529, 529, 529, nil, nil, nil, nil, 529, 529, nil, + nil, nil, 532, 532, 532, 529, 532, 529, 529, 529, + 532, 532, nil, nil, nil, 532, nil, 532, 532, 532, + 532, 532, 532, 532, nil, nil, nil, nil, nil, 532, + 532, 532, 532, 532, 532, 532, nil, nil, 532, nil, + nil, nil, nil, nil, nil, 532, nil, nil, 532, 532, + 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, + nil, 532, 532, 532, 532, 532, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 532, nil, nil, 532, nil, + nil, 532, 532, nil, nil, 532, nil, nil, nil, nil, + nil, 532, nil, nil, 532, nil, nil, nil, nil, nil, + 532, nil, nil, nil, nil, 532, 532, 532, 532, nil, + 532, 532, 532, 532, nil, nil, nil, nil, 532, 532, + nil, nil, nil, 546, 546, 546, 532, 546, 532, 532, + 532, 546, 546, nil, nil, nil, 546, nil, 546, 546, + 546, 546, 546, 546, 546, nil, nil, nil, nil, nil, + 546, 546, 546, 546, 546, 546, 546, nil, nil, 546, + nil, nil, nil, nil, nil, nil, 546, nil, nil, 546, + 546, 546, 546, 546, 546, 546, 546, nil, 546, 546, + 546, nil, 546, 546, 546, 546, 546, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 546, nil, nil, 546, + nil, nil, 546, 546, nil, nil, 546, nil, 546, nil, + nil, nil, 546, nil, nil, nil, nil, nil, nil, nil, + nil, 546, nil, nil, nil, nil, 546, 546, 546, 546, + nil, 546, 546, 546, 546, nil, nil, nil, nil, 546, + 546, nil, nil, nil, 547, 547, 547, 546, 547, 546, + 546, 546, 547, 547, nil, nil, nil, 547, nil, 547, + 547, 547, 547, 547, 547, 547, nil, nil, nil, nil, + nil, 547, 547, 547, 547, 547, 547, 547, nil, nil, + 547, nil, nil, nil, nil, nil, nil, 547, nil, nil, + 547, 547, 547, 547, 547, 547, 547, 547, 547, 547, + 547, 547, nil, 547, 547, 547, 547, 547, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 547, nil, nil, + 547, nil, nil, 547, 547, nil, nil, 547, nil, 547, + nil, 547, nil, 547, nil, nil, 547, nil, nil, nil, + nil, nil, 547, nil, nil, nil, nil, 547, 547, 547, + 547, nil, 547, 547, 547, 547, nil, nil, nil, nil, + 547, 547, nil, nil, nil, 557, 557, 557, 547, 557, + 547, 547, 547, 557, 557, nil, nil, nil, 557, nil, + 557, 557, 557, 557, 557, 557, 557, nil, nil, nil, + nil, nil, 557, 557, 557, 557, 557, 557, 557, nil, + nil, 557, nil, nil, nil, nil, nil, nil, 557, nil, + nil, 557, 557, 557, 557, 557, 557, 557, 557, 557, + 557, 557, 557, nil, 557, 557, 557, 557, 557, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 557, nil, + nil, 557, nil, nil, 557, 557, nil, nil, 557, nil, + 557, nil, 557, nil, 557, nil, nil, 557, nil, nil, + nil, nil, nil, 557, nil, nil, nil, nil, 557, 557, + 557, 557, nil, 557, 557, 557, 557, nil, nil, nil, + nil, 557, 557, nil, nil, nil, 589, 589, 589, 557, + 589, 557, 557, 557, 589, 589, nil, nil, nil, 589, + nil, 589, 589, 589, 589, 589, 589, 589, nil, nil, + nil, nil, nil, 589, 589, 589, 589, 589, 589, 589, + nil, nil, 589, nil, nil, nil, nil, nil, nil, 589, + nil, nil, 589, 589, 589, 589, 589, 589, 589, 589, + nil, 589, 589, 589, nil, 589, 589, 589, 589, 589, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 589, + nil, nil, 589, nil, nil, 589, 589, nil, nil, 589, + nil, 589, nil, nil, nil, 589, nil, nil, nil, nil, + nil, nil, nil, nil, 589, nil, nil, nil, nil, 589, + 589, 589, 589, nil, 589, 589, 589, 589, nil, nil, + nil, nil, 589, 589, nil, nil, nil, 590, 590, 590, + 589, 590, 589, 589, 589, 590, 590, nil, nil, nil, + 590, nil, 590, 590, 590, 590, 590, 590, 590, nil, + nil, nil, nil, nil, 590, 590, 590, 590, 590, 590, + 590, nil, nil, 590, nil, nil, nil, nil, nil, nil, + 590, nil, nil, 590, 590, 590, 590, 590, 590, 590, + 590, nil, 590, 590, 590, nil, 590, 590, 590, 590, + 590, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 590, nil, nil, 590, nil, nil, 590, 590, nil, nil, + 590, nil, nil, nil, nil, nil, 590, nil, nil, nil, + nil, nil, nil, nil, nil, 590, nil, nil, nil, nil, + 590, 590, 590, 590, nil, 590, 590, 590, 590, nil, + nil, nil, nil, 590, 590, nil, nil, nil, 593, 593, + 593, 590, 593, 590, 590, 590, 593, 593, nil, nil, + nil, 593, nil, 593, 593, 593, 593, 593, 593, 593, + nil, nil, nil, nil, nil, 593, 593, 593, 593, 593, + 593, 593, nil, nil, 593, nil, nil, nil, nil, nil, + nil, 593, nil, nil, 593, 593, 593, 593, 593, 593, + 593, 593, 593, 593, 593, 593, nil, 593, 593, 593, + 593, 593, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 593, nil, nil, 593, nil, nil, 593, 593, nil, + nil, 593, nil, 593, nil, 593, nil, 593, nil, nil, + 593, nil, nil, nil, nil, nil, 593, nil, nil, nil, + nil, 593, 593, 593, 593, nil, 593, 593, 593, 593, + nil, nil, nil, nil, 593, 593, nil, nil, nil, 594, + 594, 594, 593, 594, 593, 593, 593, 594, 594, nil, + nil, nil, 594, nil, 594, 594, 594, 594, 594, 594, + 594, nil, nil, nil, nil, nil, 594, 594, 594, 594, + 594, 594, 594, nil, nil, 594, nil, nil, nil, nil, + nil, nil, 594, nil, nil, 594, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, nil, 594, 594, + 594, 594, 594, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 594, nil, nil, 594, nil, nil, 594, 594, + nil, nil, 594, nil, nil, nil, 594, nil, 594, nil, + nil, 594, nil, nil, nil, nil, nil, 594, nil, nil, + nil, nil, 594, 594, 594, 594, nil, 594, 594, 594, + 594, nil, nil, nil, nil, 594, 594, nil, nil, nil, + 595, 595, 595, 594, 595, 594, 594, 594, 595, 595, + nil, nil, nil, 595, nil, 595, 595, 595, 595, 595, + 595, 595, nil, nil, nil, nil, nil, 595, 595, 595, + 595, 595, 595, 595, nil, nil, 595, nil, nil, nil, + nil, nil, nil, 595, nil, nil, 595, 595, 595, 595, + 595, 595, 595, 595, nil, 595, 595, 595, nil, 595, + 595, 595, 595, 595, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 595, nil, nil, 595, nil, nil, 595, + 595, nil, nil, 595, nil, nil, nil, nil, nil, 595, + nil, nil, nil, nil, nil, nil, nil, nil, 595, nil, + nil, nil, nil, 595, 595, 595, 595, nil, 595, 595, + 595, 595, nil, nil, nil, nil, 595, 595, nil, nil, + nil, 596, 596, 596, 595, 596, 595, 595, 595, 596, + 596, nil, nil, nil, 596, nil, 596, 596, 596, 596, + 596, 596, 596, nil, nil, nil, nil, nil, 596, 596, + 596, 596, 596, 596, 596, nil, nil, 596, nil, nil, + nil, nil, nil, nil, 596, nil, nil, 596, 596, 596, + 596, 596, 596, 596, 596, nil, 596, 596, 596, nil, + 596, 596, 596, 596, 596, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 596, nil, nil, 596, nil, nil, + 596, 596, nil, nil, 596, nil, nil, nil, nil, nil, + 596, nil, nil, nil, nil, nil, nil, nil, nil, 596, + nil, nil, nil, nil, 596, 596, 596, 596, nil, 596, + 596, 596, 596, nil, nil, nil, nil, 596, 596, nil, + nil, nil, 600, 600, 600, 596, 600, 596, 596, 596, + 600, 600, nil, nil, nil, 600, nil, 600, 600, 600, + 600, 600, 600, 600, nil, nil, nil, nil, nil, 600, + 600, 600, 600, 600, 600, 600, nil, nil, 600, nil, + nil, nil, nil, nil, nil, 600, nil, nil, 600, 600, + 600, 600, 600, 600, 600, 600, nil, 600, 600, 600, + nil, 600, 600, 600, 600, 600, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 600, nil, nil, 600, nil, + nil, 600, 600, nil, nil, 600, nil, nil, nil, nil, + nil, 600, nil, nil, nil, nil, nil, nil, nil, nil, + 600, nil, nil, nil, nil, 600, 600, 600, 600, nil, + 600, 600, 600, 600, nil, nil, nil, nil, 600, 600, + nil, nil, nil, 601, 601, 601, 600, 601, 600, 600, + 600, 601, 601, nil, nil, nil, 601, nil, 601, 601, + 601, 601, 601, 601, 601, nil, nil, nil, nil, nil, + 601, 601, 601, 601, 601, 601, 601, nil, nil, 601, + nil, nil, nil, nil, nil, nil, 601, nil, nil, 601, + 601, 601, 601, 601, 601, 601, 601, nil, 601, 601, + 601, nil, 601, 601, 601, 601, 601, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 601, nil, nil, 601, + nil, nil, 601, 601, nil, nil, 601, nil, nil, nil, + nil, nil, 601, nil, nil, nil, nil, nil, nil, nil, + nil, 601, nil, nil, nil, nil, 601, 601, 601, 601, + nil, 601, 601, 601, 601, nil, nil, nil, nil, 601, + 601, nil, nil, nil, 604, 604, 604, 601, 604, 601, + 601, 601, 604, 604, nil, nil, nil, 604, nil, 604, + 604, 604, 604, 604, 604, 604, nil, nil, nil, nil, + nil, 604, 604, 604, 604, 604, 604, 604, nil, nil, + 604, nil, nil, nil, nil, nil, nil, 604, nil, nil, + 604, 604, 604, 604, 604, 604, 604, 604, nil, 604, + 604, 604, nil, 604, 604, 604, 604, 604, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 604, nil, nil, + 604, nil, nil, 604, 604, nil, nil, 604, nil, nil, + nil, nil, nil, 604, nil, nil, nil, nil, nil, nil, + nil, nil, 604, nil, nil, nil, nil, 604, 604, 604, + 604, nil, 604, 604, 604, 604, nil, nil, nil, nil, + 604, 604, nil, nil, nil, 605, 605, 605, 604, 605, + 604, 604, 604, 605, 605, nil, nil, nil, 605, nil, + 605, 605, 605, 605, 605, 605, 605, nil, nil, nil, + nil, nil, 605, 605, 605, 605, 605, 605, 605, nil, + nil, 605, nil, nil, nil, nil, nil, nil, 605, nil, + nil, 605, 605, 605, 605, 605, 605, 605, 605, nil, + 605, 605, 605, nil, 605, 605, 605, 605, 605, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 605, nil, + nil, 605, nil, nil, 605, 605, nil, nil, 605, nil, + nil, nil, nil, nil, 605, nil, nil, nil, nil, nil, + nil, nil, nil, 605, nil, nil, nil, nil, 605, 605, + 605, 605, nil, 605, 605, 605, 605, nil, nil, nil, + nil, 605, 605, nil, nil, nil, 629, 629, 629, 605, + 629, 605, 605, 605, 629, 629, nil, nil, nil, 629, + nil, 629, 629, 629, 629, 629, 629, 629, nil, nil, + nil, nil, nil, 629, 629, 629, 629, 629, 629, 629, + nil, nil, 629, nil, nil, nil, nil, nil, nil, 629, + nil, nil, 629, 629, 629, 629, 629, 629, 629, 629, + nil, 629, 629, 629, nil, 629, 629, 629, 629, 629, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 629, + nil, nil, 629, nil, nil, 629, 629, nil, nil, 629, + nil, nil, nil, nil, nil, 629, nil, nil, nil, nil, + nil, nil, nil, nil, 629, nil, nil, nil, nil, 629, + 629, 629, 629, nil, 629, 629, 629, 629, nil, nil, + nil, nil, 629, 629, nil, nil, nil, 632, 632, 632, + 629, 632, 629, 629, 629, 632, 632, nil, nil, nil, + 632, nil, 632, 632, 632, 632, 632, 632, 632, nil, + nil, nil, nil, nil, 632, 632, 632, 632, 632, 632, + 632, nil, nil, 632, nil, nil, nil, nil, nil, nil, + 632, nil, nil, 632, 632, 632, 632, 632, 632, 632, + 632, nil, 632, 632, 632, nil, 632, 632, 632, 632, + 632, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 632, nil, nil, 632, nil, nil, 632, 632, nil, nil, + 632, nil, nil, nil, nil, nil, 632, nil, nil, nil, + nil, nil, nil, nil, nil, 632, nil, nil, nil, nil, + 632, 632, 632, 632, nil, 632, 632, 632, 632, nil, + nil, nil, nil, 632, 632, nil, nil, nil, 636, 636, + 636, 632, 636, 632, 632, 632, 636, 636, nil, nil, + nil, 636, nil, 636, 636, 636, 636, 636, 636, 636, + nil, nil, nil, nil, nil, 636, 636, 636, 636, 636, + 636, 636, nil, nil, 636, nil, nil, nil, nil, nil, + nil, 636, nil, nil, 636, 636, 636, 636, 636, 636, + 636, 636, nil, 636, 636, 636, nil, 636, 636, nil, + nil, 636, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 636, nil, nil, 636, nil, nil, 636, 636, nil, + nil, 636, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 636, 636, 636, 636, nil, 636, 636, 636, 636, + nil, nil, nil, nil, 636, 636, nil, nil, nil, 647, + 647, 647, 636, 647, 636, 636, 636, 647, 647, nil, + nil, nil, 647, nil, 647, 647, 647, 647, 647, 647, + 647, nil, nil, nil, nil, nil, 647, 647, 647, 647, + 647, 647, 647, nil, nil, 647, nil, nil, nil, nil, + nil, nil, 647, nil, nil, 647, 647, 647, 647, 647, + 647, 647, 647, nil, 647, 647, 647, nil, 647, 647, + nil, nil, 647, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 647, nil, nil, 647, nil, nil, 647, 647, + nil, nil, 647, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 647, 647, 647, 647, nil, 647, 647, 647, + 647, nil, nil, nil, nil, 647, 647, nil, nil, nil, + 652, 652, 652, 647, 652, 647, 647, 647, 652, 652, + nil, nil, nil, 652, nil, 652, 652, 652, 652, 652, + 652, 652, nil, nil, nil, nil, nil, 652, 652, 652, + 652, 652, 652, 652, nil, nil, 652, nil, nil, nil, + nil, nil, nil, 652, nil, nil, 652, 652, 652, 652, + 652, 652, 652, 652, nil, 652, 652, 652, nil, 652, + 652, 652, 652, 652, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 652, nil, nil, 652, nil, nil, 652, + 652, nil, nil, 652, nil, 652, nil, nil, nil, 652, + nil, nil, nil, nil, nil, nil, nil, nil, 652, nil, + nil, nil, nil, 652, 652, 652, 652, nil, 652, 652, + 652, 652, nil, nil, nil, nil, 652, 652, nil, nil, + nil, 678, 678, 678, 652, 678, 652, 652, 652, 678, + 678, nil, nil, nil, 678, nil, 678, 678, 678, 678, + 678, 678, 678, nil, nil, nil, nil, nil, 678, 678, + 678, 678, 678, 678, 678, nil, nil, 678, nil, nil, + nil, nil, nil, nil, 678, nil, nil, 678, 678, 678, + 678, 678, 678, 678, 678, nil, 678, 678, 678, nil, + 678, 678, 678, 678, 678, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 678, nil, nil, 678, nil, nil, + 678, 678, nil, nil, 678, nil, nil, nil, nil, nil, + 678, nil, nil, nil, nil, nil, nil, nil, nil, 678, + nil, nil, nil, nil, 678, 678, 678, 678, nil, 678, + 678, 678, 678, nil, nil, nil, nil, 678, 678, nil, + nil, nil, 705, 705, 705, 678, 705, 678, 678, 678, + 705, 705, nil, nil, nil, 705, nil, 705, 705, 705, + 705, 705, 705, 705, nil, nil, nil, nil, nil, 705, + 705, 705, 705, 705, 705, 705, nil, nil, 705, nil, + nil, nil, nil, nil, nil, 705, nil, nil, 705, 705, + 705, 705, 705, 705, 705, 705, nil, 705, 705, 705, + nil, 705, 705, 705, 705, 705, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 705, nil, nil, 705, nil, + nil, 705, 705, nil, nil, 705, nil, nil, nil, nil, + nil, 705, nil, nil, nil, nil, nil, nil, nil, nil, + 705, nil, nil, nil, nil, 705, 705, 705, 705, nil, + 705, 705, 705, 705, nil, nil, nil, nil, 705, 705, + nil, nil, nil, 711, 711, 711, 705, 711, 705, 705, + 705, 711, 711, nil, nil, nil, 711, nil, 711, 711, + 711, 711, 711, 711, 711, nil, nil, nil, nil, nil, + 711, 711, 711, 711, 711, 711, 711, nil, nil, 711, + nil, nil, nil, nil, nil, nil, 711, nil, nil, 711, + 711, 711, 711, 711, 711, 711, 711, nil, 711, 711, + 711, nil, 711, 711, 711, 711, 711, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 711, nil, nil, 711, + nil, nil, 711, 711, nil, nil, 711, nil, nil, nil, + nil, nil, 711, nil, nil, nil, nil, nil, nil, nil, + nil, 711, nil, nil, nil, nil, 711, 711, 711, 711, + nil, 711, 711, 711, 711, nil, nil, nil, nil, 711, + 711, nil, nil, nil, 733, 733, 733, 711, 733, 711, + 711, 711, 733, 733, nil, nil, nil, 733, nil, 733, + 733, 733, 733, 733, 733, 733, nil, nil, nil, nil, + nil, 733, 733, 733, 733, 733, 733, 733, nil, nil, + 733, nil, nil, nil, nil, nil, nil, 733, nil, nil, + 733, 733, 733, 733, 733, 733, 733, 733, nil, 733, + 733, 733, nil, 733, 733, 733, 733, 733, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 733, nil, nil, + 733, nil, nil, 733, 733, nil, nil, 733, nil, nil, + nil, nil, nil, 733, nil, nil, nil, nil, nil, nil, + nil, nil, 733, nil, nil, nil, nil, 733, 733, 733, + 733, nil, 733, 733, 733, 733, nil, nil, nil, nil, + 733, 733, nil, nil, nil, 735, 735, 735, 733, 735, + 733, 733, 733, 735, 735, nil, nil, nil, 735, nil, + 735, 735, 735, 735, 735, 735, 735, nil, nil, nil, + nil, nil, 735, 735, 735, 735, 735, 735, 735, nil, + nil, 735, nil, nil, nil, nil, nil, nil, 735, nil, + nil, 735, 735, 735, 735, 735, 735, 735, 735, nil, + 735, 735, 735, nil, 735, 735, 735, 735, 735, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 735, nil, + nil, 735, nil, nil, 735, 735, nil, nil, 735, nil, + nil, nil, nil, nil, 735, nil, nil, nil, nil, nil, + nil, nil, nil, 735, nil, nil, nil, nil, 735, 735, + 735, 735, nil, 735, 735, 735, 735, nil, nil, nil, + nil, 735, 735, nil, nil, nil, 749, 749, 749, 735, + 749, 735, 735, 735, 749, 749, nil, nil, nil, 749, + nil, 749, 749, 749, 749, 749, 749, 749, nil, nil, + nil, nil, nil, 749, 749, 749, 749, 749, 749, 749, + nil, nil, 749, nil, nil, nil, nil, nil, nil, 749, + nil, nil, 749, 749, 749, 749, 749, 749, 749, 749, + nil, 749, 749, 749, nil, 749, 749, 749, 749, 749, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 749, + nil, nil, 749, nil, nil, 749, 749, nil, nil, 749, + nil, nil, nil, nil, nil, 749, nil, nil, nil, nil, + nil, nil, nil, nil, 749, nil, nil, nil, nil, 749, + 749, 749, 749, nil, 749, 749, 749, 749, nil, nil, + nil, nil, 749, 749, nil, nil, nil, 750, 750, 750, + 749, 750, 749, 749, 749, 750, 750, nil, nil, nil, + 750, nil, 750, 750, 750, 750, 750, 750, 750, nil, + nil, nil, nil, nil, 750, 750, 750, 750, 750, 750, + 750, nil, nil, 750, nil, nil, nil, nil, nil, nil, + 750, nil, nil, 750, 750, 750, 750, 750, 750, 750, + 750, nil, 750, 750, 750, nil, 750, 750, 750, 750, + 750, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 750, nil, nil, 750, nil, nil, 750, 750, nil, nil, + 750, nil, nil, nil, nil, nil, 750, nil, nil, nil, + nil, nil, nil, nil, nil, 750, nil, nil, nil, nil, + 750, 750, 750, 750, nil, 750, 750, 750, 750, nil, + nil, nil, nil, 750, 750, nil, nil, nil, 751, 751, + 751, 750, 751, 750, 750, 750, 751, 751, nil, nil, + nil, 751, nil, 751, 751, 751, 751, 751, 751, 751, + nil, nil, nil, nil, nil, 751, 751, 751, 751, 751, + 751, 751, nil, nil, 751, nil, nil, nil, nil, nil, + nil, 751, nil, nil, 751, 751, 751, 751, 751, 751, + 751, 751, nil, 751, 751, 751, nil, 751, 751, 751, + 751, 751, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 751, nil, nil, 751, nil, nil, 751, 751, nil, + nil, 751, nil, nil, nil, nil, nil, 751, nil, nil, + nil, nil, nil, nil, nil, nil, 751, nil, nil, nil, + nil, 751, 751, 751, 751, nil, 751, 751, 751, 751, + nil, nil, nil, nil, 751, 751, nil, nil, nil, 752, + 752, 752, 751, 752, 751, 751, 751, 752, 752, nil, + nil, nil, 752, nil, 752, 752, 752, 752, 752, 752, + 752, nil, nil, nil, nil, nil, 752, 752, 752, 752, + 752, 752, 752, nil, nil, 752, nil, nil, nil, nil, + nil, nil, 752, nil, nil, 752, 752, 752, 752, 752, + 752, 752, 752, nil, 752, 752, 752, nil, 752, 752, + 752, 752, 752, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 752, nil, nil, 752, nil, nil, 752, 752, + nil, nil, 752, nil, nil, nil, nil, nil, 752, nil, + nil, nil, nil, nil, nil, nil, nil, 752, nil, nil, + nil, nil, 752, 752, 752, 752, nil, 752, 752, 752, + 752, nil, nil, nil, nil, 752, 752, nil, nil, nil, + 754, 754, 754, 752, 754, 752, 752, 752, 754, 754, + nil, nil, nil, 754, nil, 754, 754, 754, 754, 754, + 754, 754, nil, nil, nil, nil, nil, 754, 754, 754, + 754, 754, 754, 754, nil, nil, 754, nil, nil, nil, + nil, nil, nil, 754, nil, nil, 754, 754, 754, 754, + 754, 754, 754, 754, nil, 754, 754, 754, nil, 754, + 754, 754, 754, 754, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 754, nil, nil, 754, nil, nil, 754, + 754, nil, nil, 754, nil, nil, nil, nil, nil, 754, + nil, nil, nil, nil, nil, nil, nil, nil, 754, nil, + nil, nil, nil, 754, 754, 754, 754, nil, 754, 754, + 754, 754, nil, nil, nil, nil, 754, 754, nil, nil, + nil, 766, 766, 766, 754, 766, 754, 754, 754, 766, + 766, nil, nil, nil, 766, nil, 766, 766, 766, 766, + 766, 766, 766, nil, nil, nil, nil, nil, 766, 766, + 766, 766, 766, 766, 766, nil, nil, 766, nil, nil, + nil, nil, nil, nil, 766, nil, nil, 766, 766, 766, + 766, 766, 766, 766, 766, nil, 766, 766, 766, nil, + 766, 766, nil, nil, 766, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 766, nil, nil, 766, nil, nil, + 766, 766, nil, nil, 766, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 766, 766, 766, 766, nil, 766, + 766, 766, 766, nil, nil, nil, nil, 766, 766, nil, + nil, nil, 804, 804, 804, 766, 804, 766, 766, 766, + 804, 804, nil, nil, nil, 804, nil, 804, 804, 804, + 804, 804, 804, 804, nil, nil, nil, nil, nil, 804, + 804, 804, 804, 804, 804, 804, nil, nil, 804, nil, + nil, nil, nil, nil, nil, 804, nil, nil, 804, 804, + 804, 804, 804, 804, 804, 804, nil, 804, 804, 804, + nil, 804, 804, 804, 804, 804, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 804, nil, nil, 804, nil, + nil, 804, 804, nil, nil, 804, nil, nil, nil, nil, + nil, 804, nil, nil, nil, nil, nil, nil, nil, nil, + 804, nil, nil, nil, nil, 804, 804, 804, 804, nil, + 804, 804, 804, 804, nil, nil, nil, nil, 804, 804, + nil, nil, nil, 817, 817, 817, 804, 817, 804, 804, + 804, 817, 817, nil, nil, nil, 817, nil, 817, 817, + 817, 817, 817, 817, 817, nil, nil, nil, nil, nil, + 817, 817, 817, 817, 817, 817, 817, nil, nil, 817, + nil, nil, nil, nil, nil, nil, 817, nil, nil, 817, + 817, 817, 817, 817, 817, 817, 817, nil, 817, 817, + 817, nil, 817, 817, 817, 817, 817, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 817, nil, nil, 817, + nil, nil, 817, 817, nil, nil, 817, nil, nil, nil, + nil, nil, 817, nil, nil, nil, nil, nil, nil, nil, + nil, 817, nil, nil, nil, nil, 817, 817, 817, 817, + nil, 817, 817, 817, 817, nil, nil, nil, nil, 817, + 817, nil, nil, nil, 822, 822, 822, 817, 822, 817, + 817, 817, 822, 822, nil, nil, nil, 822, nil, 822, + 822, 822, 822, 822, 822, 822, nil, nil, nil, nil, + nil, 822, 822, 822, 822, 822, 822, 822, nil, nil, + 822, nil, nil, nil, nil, nil, nil, 822, nil, nil, + 822, 822, 822, 822, 822, 822, 822, 822, nil, 822, + 822, 822, nil, 822, 822, 822, 822, 822, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 822, nil, nil, + 822, nil, nil, 822, 822, nil, nil, 822, nil, 822, + nil, nil, nil, 822, nil, nil, nil, nil, nil, nil, + nil, nil, 822, nil, nil, nil, nil, 822, 822, 822, + 822, nil, 822, 822, 822, 822, nil, nil, nil, nil, + 822, 822, nil, nil, nil, 839, 839, 839, 822, 839, + 822, 822, 822, 839, 839, nil, nil, nil, 839, nil, + 839, 839, 839, 839, 839, 839, 839, nil, nil, nil, + nil, nil, 839, 839, 839, 839, 839, 839, 839, nil, + nil, 839, nil, nil, nil, nil, nil, nil, 839, nil, + nil, 839, 839, 839, 839, 839, 839, 839, 839, 839, + 839, 839, 839, nil, 839, 839, 839, 839, 839, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 839, nil, + nil, 839, nil, nil, 839, 839, nil, nil, 839, nil, + nil, nil, 839, nil, 839, nil, nil, 839, nil, nil, + nil, nil, nil, 839, nil, nil, nil, nil, 839, 839, + 839, 839, nil, 839, 839, 839, 839, nil, nil, nil, + nil, 839, 839, nil, nil, nil, 840, 840, 840, 839, + 840, 839, 839, 839, 840, 840, nil, nil, nil, 840, + nil, 840, 840, 840, 840, 840, 840, 840, nil, nil, + nil, nil, nil, 840, 840, 840, 840, 840, 840, 840, + nil, nil, 840, nil, nil, nil, nil, nil, nil, 840, + nil, nil, 840, 840, 840, 840, 840, 840, 840, 840, + nil, 840, 840, 840, nil, 840, 840, 840, 840, 840, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 840, + nil, nil, 840, nil, nil, 840, 840, nil, nil, 840, + nil, nil, nil, nil, nil, 840, nil, nil, nil, nil, + nil, nil, nil, nil, 840, nil, nil, nil, nil, 840, + 840, 840, 840, nil, 840, 840, 840, 840, nil, nil, + nil, nil, 840, 840, nil, nil, nil, 854, 854, 854, + 840, 854, 840, 840, 840, 854, 854, nil, nil, nil, + 854, nil, 854, 854, 854, 854, 854, 854, 854, nil, + nil, nil, nil, nil, 854, 854, 854, 854, 854, 854, + 854, nil, nil, 854, nil, nil, nil, nil, nil, nil, + 854, nil, nil, 854, 854, 854, 854, 854, 854, 854, + 854, nil, 854, 854, 854, nil, 854, 854, nil, nil, + 854, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 854, nil, nil, 854, nil, nil, 854, 854, nil, nil, + 854, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 854, 854, 854, 854, nil, 854, 854, 854, 854, nil, + nil, nil, nil, 854, 854, nil, nil, nil, 866, 866, + 866, 854, 866, 854, 854, 854, 866, 866, nil, nil, + nil, 866, nil, 866, 866, 866, 866, 866, 866, 866, + nil, nil, nil, nil, nil, 866, 866, 866, 866, 866, + 866, 866, nil, nil, 866, nil, nil, nil, nil, nil, + nil, 866, nil, nil, 866, 866, 866, 866, 866, 866, + 866, 866, nil, 866, 866, 866, nil, 866, 866, nil, + nil, 866, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 866, nil, nil, 866, nil, nil, 866, 866, nil, + nil, 866, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 866, 866, 866, 866, nil, 866, 866, 866, 866, + nil, nil, nil, nil, 866, 866, nil, nil, nil, 975, + 975, 975, 866, 975, 866, 866, 866, 975, 975, nil, + nil, nil, 975, nil, 975, 975, 975, 975, 975, 975, + 975, nil, nil, nil, nil, nil, 975, 975, 975, 975, + 975, 975, 975, nil, nil, 975, nil, nil, nil, nil, + nil, nil, 975, nil, nil, 975, 975, 975, 975, 975, + 975, 975, 975, 975, 975, 975, 975, nil, 975, 975, + 975, 975, 975, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 975, nil, nil, 975, nil, nil, 975, 975, + nil, nil, 975, nil, 975, nil, 975, nil, 975, nil, + nil, 975, nil, nil, nil, nil, nil, 975, nil, nil, + nil, nil, 975, 975, 975, 975, nil, 975, 975, 975, + 975, nil, nil, nil, nil, 975, 975, nil, nil, nil, + nil, nil, nil, 975, nil, 975, 975, 975, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, nil, nil, nil, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, nil, nil, nil, nil, nil, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + nil, 8, nil, nil, nil, nil, nil, nil, nil, 8, + 8, nil, 8, 8, 8, 8, 8, 8, 8, nil, + nil, 8, 8, nil, nil, nil, 8, 8, 8, 8, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 8, 8, nil, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, nil, nil, + 8, 8, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + nil, nil, nil, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, nil, nil, nil, nil, nil, 9, 9, + 9, 9, 9, 9, 9, 9, 9, nil, nil, 9, + nil, nil, nil, nil, nil, nil, nil, 9, 9, nil, + 9, 9, 9, 9, 9, 9, 9, nil, nil, 9, + 9, nil, nil, nil, 9, 9, 9, 9, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 9, 9, nil, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, nil, nil, 9, 9, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 9, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, nil, nil, + nil, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, nil, nil, nil, nil, nil, 398, 398, 398, 398, + 398, 398, 398, 398, 398, nil, nil, 398, nil, nil, + nil, nil, nil, nil, nil, 398, 398, nil, 398, 398, + 398, 398, 398, 398, 398, nil, nil, 398, 398, nil, + nil, nil, 398, 398, 398, 398, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 398, + 398, nil, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, nil, nil, 398, 398, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 398, 586, 586, 586, 586, 586, 586, 586, 586, + 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, + 586, 586, 586, 586, 586, 586, nil, nil, nil, 586, + 586, 586, 586, 586, 586, 586, 586, 586, 586, nil, + nil, nil, nil, nil, 586, 586, 586, 586, 586, 586, + 586, 586, 586, nil, nil, 586, nil, nil, nil, nil, + nil, nil, nil, 586, 586, nil, 586, 586, 586, 586, + 586, 586, 586, nil, nil, 586, 586, nil, nil, nil, + 586, 586, 586, 586, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 586, 586, nil, + 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, + 586, 586, nil, nil, 586, 586, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 586, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, nil, nil, nil, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, nil, nil, nil, + nil, nil, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, nil, 71, nil, nil, nil, nil, + nil, 71, 71, nil, 71, 71, 71, 71, 71, 71, + 71, nil, nil, 71, 71, nil, nil, nil, 71, 71, + 71, 71, nil, nil, nil, nil, nil, 71, nil, nil, + nil, nil, nil, nil, nil, 71, 71, nil, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + nil, nil, 71, 717, 717, 717, 717, 717, 717, 717, + 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, + 717, 717, 717, 717, 717, 717, 717, nil, nil, nil, + 717, 717, 717, 717, 717, 717, 717, 717, 717, 717, + nil, nil, nil, nil, nil, 717, 717, 717, 717, 717, + 717, 717, 717, 717, nil, nil, 717, nil, nil, nil, + nil, nil, nil, nil, 717, 717, nil, 717, 717, 717, + 717, 717, 717, 717, nil, nil, 717, 717, nil, nil, + nil, 717, 717, 717, 717, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 717, 717, + nil, 717, 717, 717, 717, 717, 717, 717, 717, 717, + 717, 717, 717, 212, 212, 717, nil, 212, nil, nil, + nil, nil, nil, nil, nil, 212, 212, nil, 212, 212, + 212, 212, 212, 212, 212, nil, nil, 212, 212, nil, + nil, nil, 212, 212, 212, 212, nil, nil, nil, nil, + nil, 212, nil, nil, nil, nil, nil, nil, nil, 212, + 212, nil, 212, 212, 212, 212, 212, 212, 212, 212, + 212, 212, 212, 212, 213, 213, 212, nil, 213, nil, + nil, nil, nil, nil, nil, nil, 213, 213, nil, 213, + 213, 213, 213, 213, 213, 213, nil, nil, 213, 213, + nil, nil, nil, 213, 213, 213, 213, nil, nil, nil, + nil, nil, 213, nil, nil, nil, nil, nil, nil, nil, + 213, 213, nil, 213, 213, 213, 213, 213, 213, 213, + 213, 213, 213, 213, 213, 263, 263, 213, nil, 263, + nil, nil, nil, nil, nil, nil, nil, 263, 263, nil, + 263, 263, 263, 263, 263, 263, 263, nil, nil, 263, + 263, nil, nil, nil, 263, 263, 263, 263, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 263, 263, nil, 263, 263, 263, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 443, 443, 263, nil, + 443, nil, nil, nil, nil, nil, nil, nil, 443, 443, + nil, 443, 443, 443, 443, 443, 443, 443, nil, nil, + 443, 443, nil, nil, nil, 443, 443, 443, 443, nil, + nil, nil, nil, nil, 443, nil, nil, nil, nil, nil, + nil, nil, 443, 443, nil, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, 443, 444, 444, 443, + nil, 444, nil, nil, nil, nil, nil, nil, nil, 444, + 444, nil, 444, 444, 444, 444, 444, 444, 444, nil, + nil, 444, 444, nil, nil, nil, 444, 444, 444, 444, + nil, nil, nil, nil, nil, 444, nil, nil, nil, nil, + nil, nil, nil, 444, 444, nil, 444, 444, 444, 444, + 444, 444, 444, 444, 444, 444, 444, 444, 510, 510, + 444, nil, 510, nil, nil, nil, nil, nil, nil, nil, + 510, 510, nil, 510, 510, 510, 510, 510, 510, 510, + nil, nil, 510, 510, nil, nil, nil, 510, 510, 510, + 510, nil, nil, nil, nil, nil, 510, nil, nil, nil, + nil, nil, nil, nil, 510, 510, nil, 510, 510, 510, + 510, 510, 510, 510, 510, 510, 510, 510, 510, 511, + 511, 510, nil, 511, nil, nil, nil, nil, nil, nil, + nil, 511, 511, nil, 511, 511, 511, 511, 511, 511, + 511, nil, nil, 511, 511, nil, nil, nil, 511, 511, + 511, 511, nil, nil, nil, nil, nil, 511, nil, nil, + nil, nil, nil, nil, nil, 511, 511, nil, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 511, 511, + 520, 520, 511, nil, 520, nil, nil, nil, nil, nil, + nil, nil, 520, 520, nil, 520, 520, 520, 520, 520, + 520, 520, nil, nil, 520, 520, nil, nil, nil, 520, + 520, 520, 520, nil, nil, nil, nil, nil, 520, nil, + nil, nil, nil, nil, nil, nil, 520, 520, nil, 520, + 520, 520, 520, 520, 520, 520, 520, 520, 520, 520, + 520, 521, 521, 520, nil, 521, nil, nil, nil, nil, + nil, nil, nil, 521, 521, nil, 521, 521, 521, 521, + 521, 521, 521, nil, nil, 521, 521, nil, nil, nil, + 521, 521, 521, 521, nil, nil, nil, nil, nil, 521, + nil, nil, nil, nil, nil, nil, nil, 521, 521, nil, + 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, + 521, 521, 548, 548, 521, nil, 548, nil, nil, nil, + nil, nil, nil, nil, 548, 548, nil, 548, 548, 548, + 548, 548, 548, 548, nil, nil, 548, 548, nil, nil, + nil, 548, 548, 548, 548, nil, nil, nil, nil, nil, + 548, nil, nil, nil, nil, nil, nil, nil, 548, 548, + nil, 548, 548, 548, 548, 548, 548, 548, 548, 548, + 548, 548, 548, 549, 549, 548, nil, 549, nil, nil, + nil, nil, nil, nil, nil, 549, 549, nil, 549, 549, + 549, 549, 549, 549, 549, nil, nil, 549, 549, nil, + nil, nil, 549, 549, 549, 549, nil, nil, nil, nil, + nil, 549, nil, nil, nil, nil, nil, nil, nil, 549, + 549, nil, 549, 549, 549, 549, 549, 549, 549, 549, + 549, 549, 549, 549, 555, 555, 549, nil, 555, nil, + nil, nil, nil, nil, nil, nil, 555, 555, nil, 555, + 555, 555, 555, 555, 555, 555, nil, nil, 555, 555, + nil, nil, nil, 555, 555, 555, 555, nil, nil, nil, + nil, nil, 555, nil, nil, nil, nil, nil, nil, nil, + 555, 555, nil, 555, 555, 555, 555, 555, 555, 555, + 555, 555, 555, 555, 555, 556, 556, 555, nil, 556, + nil, nil, nil, nil, nil, nil, nil, 556, 556, nil, + 556, 556, 556, 556, 556, 556, 556, nil, nil, 556, + 556, nil, nil, nil, 556, 556, 556, 556, nil, nil, + nil, nil, nil, 556, nil, nil, nil, nil, nil, nil, + nil, 556, 556, nil, 556, 556, 556, 556, 556, 556, + 556, 556, 556, 556, 556, 556, 922, 922, 556, nil, + 922, nil, nil, nil, nil, nil, nil, nil, 922, 922, + nil, 922, 922, 922, 922, 922, 922, 922, nil, nil, + 922, 922, nil, nil, nil, 922, 922, 922, 922, nil, + nil, nil, nil, nil, 922, nil, nil, nil, nil, nil, + nil, nil, 922, 922, nil, 922, 922, 922, 922, 922, + 922, 922, 922, 922, 922, 922, 922, 976, 976, 922, + nil, 976, nil, nil, nil, nil, nil, nil, nil, 976, + 976, nil, 976, 976, 976, 976, 976, 976, 976, nil, + nil, 976, 976, nil, nil, nil, 976, 976, 976, 976, + nil, nil, nil, nil, nil, 976, nil, nil, nil, nil, + nil, nil, nil, 976, 976, nil, 976, 976, 976, 976, + 976, 976, 976, 976, 976, 976, 976, 976, 977, 977, + 976, nil, 977, nil, nil, nil, nil, nil, nil, nil, + 977, 977, nil, 977, 977, 977, 977, 977, 977, 977, + nil, nil, 977, 977, nil, nil, nil, 977, 977, 977, + 977, nil, nil, nil, nil, nil, 977, nil, nil, nil, + nil, nil, nil, nil, 977, 977, nil, 977, 977, 977, + 977, 977, 977, 977, 977, 977, 977, 977, 977, nil, + 658, 977, 658, 658, 658, 658, 658, nil, 715, nil, + 715, 715, 715, 715, 715, 658, nil, nil, nil, nil, + nil, nil, nil, 715, nil, 716, nil, 716, 716, 716, + 716, 716, nil, nil, nil, nil, nil, 658, nil, nil, + 716, nil, nil, nil, nil, 715, 658, 658, 658, 658, + nil, nil, nil, 658, 715, 715, 715, 715, nil, nil, + nil, 715, 716, nil, 798, nil, 798, 798, 798, 798, + 798, 716, 716, 716, 716, nil, nil, nil, 716, 798, + nil, 800, nil, 800, 800, 800, 800, 800, nil, 845, + nil, 845, 845, 845, 845, 845, 800, nil, nil, nil, + nil, 798, nil, nil, 845, nil, nil, nil, nil, nil, + 798, 798, 798, 798, nil, nil, nil, 798, 800, nil, + nil, nil, nil, nil, nil, nil, 845, 800, 800, 800, + 800, nil, nil, nil, 800, 845, 845, 845, 845, nil, + nil, 847, 845, 847, 847, 847, 847, 847, nil, 937, + nil, 937, 937, 937, 937, 937, 847, nil, nil, nil, + nil, nil, nil, nil, 937, nil, 941, nil, 941, 941, + 941, 941, 941, nil, nil, nil, nil, nil, 847, nil, + nil, 941, nil, nil, nil, nil, 937, 847, 847, 847, + 847, nil, nil, nil, 847, 937, 937, 937, 937, nil, + nil, nil, 937, 941, nil, 943, nil, 943, 943, 943, + 943, 943, nil, nil, 941, 941, nil, nil, nil, 941, + 943, nil, 961, nil, 961, 961, 961, 961, 961, 963, + nil, 963, 963, 963, 963, 963, nil, 961, nil, nil, + nil, nil, 943, nil, 963, nil, 965, nil, 965, 965, + 965, 965, 965, 943, 943, nil, nil, nil, 943, 961, + nil, 965, nil, nil, nil, nil, 963, nil, 961, 961, + 961, 961, nil, nil, nil, 961, nil, 963, 963, nil, + nil, nil, 963, 965, nil, 967, nil, 967, 967, 967, + 967, 967, nil, nil, 965, 965, nil, nil, nil, 965, + 967, nil, 1005, nil, 1005, 1005, 1005, 1005, 1005, 1015, + nil, 1015, 1015, 1015, 1015, 1015, nil, 1005, nil, nil, + nil, nil, 967, nil, 1015, nil, nil, nil, nil, nil, + nil, nil, nil, 967, 967, nil, nil, nil, 967, 1005, + nil, nil, nil, nil, nil, nil, 1015, nil, nil, nil, + 1005, 1005, nil, nil, nil, 1005, nil, 1015, 1015, nil, + nil, nil, 1015 ] + +racc_action_pointer = [ + 1637, 33, nil, 81, nil, 5976, 1388, -51, 23086, 23214, + -11, nil, 50, 117, 572, -81, 105, 309, nil, -71, + 6107, 2057, 230, nil, -62, nil, -8, 742, 852, 6238, + 6369, 6500, nil, 1777, 6631, 6762, nil, 134, 282, 352, + 247, 332, 6901, 7032, 7163, 191, 574, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 962, nil, -80, 7294, + 7425, 4, nil, 7556, 7687, nil, nil, 7818, 7957, 8088, + 8219, 23598, nil, nil, nil, nil, nil, nil, nil, 223, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 0, nil, nil, + 112, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 354, nil, 8358, nil, nil, nil, nil, 8497, 8628, + 8759, 8890, 9029, 1917, nil, 576, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 223, nil, 2057, 9160, + 9291, 9422, 23772, 23833, nil, nil, 9553, 9684, 9815, 9946, + 10077, 10208, nil, nil, 576, -54, 138, 307, 166, 241, + 309, nil, 10339, 2197, 310, 10470, 10601, 10732, 10863, 10994, + 11125, 11256, 11387, 11518, 11649, 11780, 11911, 12042, 12173, 12304, + 12435, 12566, 12697, 12828, 12959, 13090, 13221, 13352, 13483, 13614, + 13745, nil, nil, 23894, nil, nil, 318, 13876, 14007, nil, + nil, nil, nil, nil, nil, nil, 14138, nil, 2197, nil, + 297, 325, nil, 14269, 373, 14400, nil, nil, 14531, 14662, + nil, nil, 228, nil, 14801, 1441, 358, 338, 2337, 353, + 408, 377, 14932, 2477, 615, 645, 714, 473, 790, nil, + 441, 417, 33, nil, nil, nil, 476, 360, 453, 15071, + nil, 472, 522, 822, nil, 526, nil, 15202, 2617, 15333, + 465, nil, -73, 146, 506, 489, 387, 523, nil, nil, + 346, -1, 11, 15464, 15595, 298, 603, 498, -18, 11, + 824, 584, 25, 618, nil, nil, 342, 434, -21, nil, + 900, nil, 541, 15726, nil, nil, nil, 194, 230, 379, + 413, 486, 510, 577, 578, 582, nil, 619, nil, 15857, + nil, 272, 456, 459, 465, 497, -41, -35, 501, nil, + nil, nil, nil, nil, nil, nil, nil, 537, 23342, nil, + nil, nil, nil, 544, nil, nil, 535, 15988, 551, nil, + nil, 1777, 563, nil, 568, 590, 481, 552, 1098, nil, + nil, nil, 222, 334, 638, nil, nil, 1230, 1366, nil, + 2337, nil, 587, nil, nil, 1637, nil, nil, nil, nil, + -35, nil, 650, 23955, 24016, 16119, 197, 16250, 16381, 16512, + 4017, 4157, 623, 662, 677, 678, 679, 682, 1518, 5697, + 1470, 4297, 1181, 1315, 4437, 4577, 4717, 4857, 4997, 5137, + 5277, 1051, 1249, 5417, 5557, 2477, -54, 1502, nil, nil, + nil, nil, 629, nil, -53, -10, 636, nil, nil, 16643, + nil, 16774, nil, 16905, nil, 363, nil, nil, nil, 17044, + 1507, 2757, 642, 640, nil, nil, 644, 17183, 650, 17314, + 24077, 24138, 930, 704, nil, 17445, 661, nil, 17576, 17707, + 24199, 24260, 2617, 17838, 788, 790, 570, 715, nil, 17969, + nil, nil, 18100, nil, nil, nil, nil, 1505, 2897, 810, + nil, 3037, 62, 147, 811, 819, 18231, 18362, 24321, 24382, + 27, nil, nil, 932, nil, 24443, 24504, 18493, nil, nil, + 250, 3177, 741, nil, -33, nil, nil, nil, 717, nil, + nil, nil, 714, nil, nil, 388, nil, 390, nil, nil, + 700, nil, 705, nil, nil, nil, 23470, nil, 708, 18624, + 18755, 619, 749, 18886, 19017, 19148, 19279, 761, nil, nil, + 19410, 19541, 762, nil, 19672, 19803, nil, nil, 217, 301, + 466, 604, 732, 1917, 731, nil, 1466, nil, 3317, 843, + 6, 160, nil, 3457, 3597, nil, 738, nil, 789, 19934, + nil, nil, 20065, nil, 767, -80, 20196, 748, nil, 752, + 123, 180, 796, 248, 1106, 797, 754, 20327, 2757, 824, + 214, 882, 20458, nil, 767, nil, 396, nil, 24749, nil, + 765, 767, nil, 769, 770, 771, nil, nil, nil, nil, + nil, nil, nil, nil, 762, 749, nil, nil, 20589, nil, + nil, nil, 861, nil, nil, nil, 863, nil, nil, 865, + 623, nil, 919, nil, nil, nil, nil, 928, nil, 26, + 808, 41, 68, 151, 185, 20720, 1066, 1143, nil, 810, + 3737, 20851, nil, 934, 3877, 24757, 24774, 23711, nil, nil, + nil, nil, nil, nil, 4017, nil, nil, nil, nil, nil, + nil, nil, 814, 20982, 2897, 21113, nil, 816, nil, 3037, + nil, 3177, nil, nil, 3317, nil, 3457, nil, 3597, 21244, + 21375, 21506, 21637, 343, 21768, 818, 823, nil, 834, 835, + 839, nil, 864, 850, 846, 843, 21899, nil, nil, 982, + nil, nil, 4157, 879, 986, nil, nil, nil, nil, 863, + 236, nil, nil, 989, nil, 4297, 867, 919, nil, nil, + 918, nil, 89, 880, 697, nil, nil, 564, 24813, nil, + 24830, nil, 6809, nil, 22030, nil, 856, nil, 879, 335, + 883, nil, nil, nil, nil, 1006, nil, 22161, 1008, 4437, + 4577, nil, 22292, 4717, 152, 181, nil, 1010, 327, 4857, + nil, 1011, 891, 366, nil, 895, 891, nil, 3737, 22423, + 22554, 3877, 1022, nil, nil, 24838, nil, 24890, nil, 8266, + nil, nil, 917, 1076, 22685, 934, 992, nil, 935, nil, + nil, nil, 4997, nil, nil, 32, 22816, nil, nil, nil, + nil, nil, 961, 920, nil, nil, nil, 921, 924, nil, + 928, 930, nil, 933, nil, nil, 947, 1162, 951, 735, + nil, nil, 33, nil, 1077, 1081, nil, 303, nil, nil, + nil, 1091, nil, nil, nil, 1012, nil, 969, nil, nil, + 970, 976, 980, 982, nil, 985, nil, 421, nil, nil, + nil, 966, 24565, nil, nil, nil, 5137, 34, 35, 1003, + 1064, 36, nil, 5277, 5417, nil, nil, 24898, nil, 14979, + nil, 24915, nil, 24954, nil, nil, nil, nil, 398, 1028, + 987, 5557, nil, nil, nil, nil, nil, 5697, nil, 5837, + nil, 24971, nil, 24978, nil, 24995, nil, 25034, nil, nil, + nil, 1332, 1039, 1043, 1129, 22947, 24626, 24687, 42, 1029, + 1135, 1013, 1014, 1015, 1018, 1019, 1223, 1025, 1437, 719, + 1151, 1152, 1029, 1030, 1046, 1051, nil, nil, 1056, 98, + 102, 111, 138, nil, nil, 25051, nil, nil, nil, nil, + 4097, 1056, nil, nil, nil, 25058, nil, nil, nil, nil, + 145, 1060, 1064, 1069, nil, nil ] + +racc_action_default = [ + -3, -601, -1, -587, -4, -601, -7, -601, -601, -601, + -601, -29, -601, -601, -601, -279, -601, -40, -43, -589, + -601, -48, -50, -51, -52, -56, -256, -256, -256, -293, + -329, -330, -68, -11, -72, -80, -82, -601, -491, -492, + -601, -601, -601, -601, -601, -589, -237, -270, -271, -272, + -273, -274, -275, -276, -277, -278, -575, -281, -283, -600, + -565, -301, -303, -601, -601, -307, -310, -587, -601, -601, + -601, -601, -331, -332, -334, -335, -432, -433, -434, -435, + -436, -457, -439, -440, -459, -461, -444, -449, -453, -455, + -471, -459, -473, -475, -476, -477, -478, -573, -480, -481, + -574, -483, -484, -485, -486, -487, -488, -489, -490, -495, + -496, -601, -2, -588, -596, -597, -598, -6, -601, -601, + -601, -601, -601, -3, -17, -601, -111, -112, -113, -114, + -115, -116, -117, -118, -119, -123, -124, -125, -126, -127, + -128, -129, -130, -131, -132, -133, -134, -135, -136, -137, + -138, -139, -140, -141, -142, -143, -144, -145, -146, -147, + -148, -149, -150, -151, -152, -153, -154, -155, -156, -157, + -158, -159, -160, -161, -162, -163, -164, -165, -166, -167, + -168, -169, -170, -171, -172, -173, -174, -175, -176, -177, + -178, -179, -180, -181, -182, -183, -184, -185, -186, -187, + -188, -189, -190, -191, -192, -193, -22, -120, -11, -601, + -601, -246, -601, -601, -585, -586, -601, -601, -601, -601, + -601, -589, -590, -47, -601, -491, -492, -601, -279, -601, + -601, -229, -601, -11, -601, -601, -601, -601, -601, -601, + -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, + -601, -601, -601, -601, -601, -601, -601, -601, -601, -601, + -601, -401, -403, -601, -583, -584, -57, -246, -601, -300, + -407, -416, -418, -63, -413, -64, -589, -65, -238, -251, + -260, -260, -255, -601, -261, -601, -457, -567, -601, -601, + -66, -67, -587, -12, -601, -15, -601, -70, -11, -589, + -601, -73, -76, -11, -88, -89, -601, -601, -96, -293, + -296, -589, -601, -329, -330, -333, -414, -601, -78, -601, + -84, -290, -474, -601, -214, -215, -230, -601, -11, -601, + -589, -239, -593, -593, -601, -601, -593, -601, -302, -392, + -49, -601, -601, -601, -601, -587, -601, -588, -491, -492, + -601, -601, -279, -601, -345, -346, -106, -107, -601, -109, + -601, -279, -499, -601, -491, -492, -322, -111, -112, -153, + -154, -155, -171, -176, -183, -186, -324, -601, -563, -601, + -437, -601, -601, -601, -601, -601, -601, -601, -601, 1026, + -5, -599, -23, -24, -25, -26, -27, -601, -601, -19, + -20, -21, -121, -601, -30, -39, -266, -601, -601, -265, + -31, -196, -589, -247, -260, -260, -576, -577, -256, -411, + -578, -579, -577, -576, -256, -410, -412, -578, -579, -37, + -204, -38, -601, -41, -42, -194, -261, -44, -45, -46, + -589, -299, -601, -601, -601, -246, -290, -601, -601, -601, + -205, -206, -207, -208, -209, -210, -211, -212, -216, -217, + -218, -219, -220, -221, -222, -223, -224, -225, -226, -227, + -228, -231, -232, -233, -234, -589, -381, -256, -576, -577, + -54, -58, -589, -257, -381, -381, -589, -295, -252, -601, + -253, -601, -258, -601, -262, -601, -570, -572, -10, -588, + -14, -3, -589, -69, -288, -85, -74, -601, -589, -246, + -601, -601, -95, -601, -474, -601, -81, -86, -601, -601, + -601, -601, -235, -601, -424, -601, -284, -601, -240, -595, + -594, -242, -595, -291, -292, -566, -304, -523, -11, -336, + -337, -11, -601, -601, -601, -601, -601, -246, -601, -601, + -290, -315, -106, -107, -108, -601, -601, -246, -318, -497, + -601, -11, -501, -326, -589, -438, -458, -463, -601, -465, + -441, -460, -601, -462, -443, -601, -446, -601, -448, -451, + -601, -452, -601, -472, -8, -18, -601, -28, -269, -601, + -601, -415, -601, -248, -250, -601, -601, -59, -245, -408, + -601, -601, -61, -409, -601, -601, -298, -591, -576, -577, + -576, -577, -589, -194, -601, -382, -589, -384, -11, -53, + -404, -381, -243, -11, -11, -294, -260, -259, -263, -601, + -568, -569, -601, -13, -601, -71, -601, -77, -83, -589, + -576, -577, -244, -580, -94, -601, -79, -601, -203, -213, + -589, -600, -600, -282, -589, -287, -593, -393, -523, -396, + -562, -562, -506, -508, -508, -508, -522, -524, -525, -526, + -527, -528, -529, -530, -531, -601, -533, -535, -537, -542, + -544, -545, -547, -552, -554, -555, -557, -558, -559, -601, + -600, -338, -600, -308, -339, -340, -311, -601, -314, -601, + -589, -576, -577, -580, -289, -601, -106, -107, -110, -589, + -11, -601, -320, -601, -11, -523, -523, -601, -564, -464, + -467, -468, -469, -470, -11, -442, -445, -447, -450, -454, + -456, -122, -267, -601, -197, -601, -592, -260, -33, -199, + -34, -200, -60, -35, -202, -36, -201, -62, -195, -601, + -601, -601, -601, -415, -601, -562, -562, -363, -365, -365, + -365, -380, -601, -589, -386, -531, -539, -540, -550, -601, + -406, -405, -11, -601, -601, -254, -264, -571, -16, -75, + -415, -87, -297, -600, -343, -11, -425, -600, -426, -427, + -601, -241, -601, -589, -601, -504, -505, -601, -601, -515, + -601, -518, -601, -520, -601, -347, -601, -349, -351, -358, + -589, -536, -546, -556, -560, -601, -341, -601, -601, -11, + -11, -313, -601, -11, -415, -601, -415, -601, -601, -11, + -323, -601, -589, -601, -327, -601, -268, -32, -198, -249, + -601, -236, -601, -361, -362, -371, -373, -601, -376, -601, + -378, -383, -601, -601, -601, -538, -601, -402, -601, -417, + -419, -9, -11, -431, -344, -601, -601, -429, -285, -394, + -397, -399, -601, -562, -543, -561, -507, -508, -508, -534, + -508, -508, -553, -508, -531, -548, -589, -601, -356, -601, + -532, -305, -601, -306, -601, -601, -263, -600, -316, -319, + -498, -601, -325, -500, -502, -501, -466, -562, -541, -364, + -365, -365, -365, -365, -551, -365, -385, -589, -388, -390, + -391, -549, -601, -290, -55, -430, -11, -491, -492, -601, + -601, -279, -428, -11, -11, -395, -503, -601, -511, -601, + -513, -601, -516, -601, -519, -521, -348, -350, -354, -601, + -359, -11, -309, -312, -420, -421, -422, -11, -321, -11, + -360, -601, -368, -601, -370, -601, -374, -601, -377, -379, + -387, -601, -289, -580, -424, -246, -601, -601, -290, -601, + -601, -508, -508, -508, -508, -352, -601, -357, -601, -600, + -601, -601, -365, -365, -365, -365, -389, -423, -589, -576, + -577, -580, -289, -398, -400, -601, -509, -512, -514, -517, + -601, -355, -342, -317, -328, -601, -366, -369, -372, -375, + -415, -508, -353, -365, -510, -367 ] + +racc_goto_table = [ + 220, 376, 525, 14, 279, 279, 279, 212, 14, 338, + 591, 262, 124, 207, 490, 315, 315, 264, 538, 541, + 481, 412, 263, 224, 2, 331, 327, 301, 545, 418, + 424, 409, 224, 224, 224, 434, 14, 306, 306, 431, + 341, 342, 651, 714, 345, 116, 132, 132, 322, 315, + 315, 315, 134, 134, 129, 129, 815, 516, 6, 113, + 766, 759, 627, 6, 627, 630, 224, 224, 223, 381, + 224, 350, 360, 360, 297, 693, 696, 482, 318, 112, + 477, 554, 117, 340, 340, 762, 918, 340, 882, 280, + 280, 280, 914, 947, 783, 392, 393, 394, 395, 810, + 920, 362, 366, 266, 273, 275, 630, 528, 531, 116, + 1, 535, 950, 575, 577, 861, 14, 129, 879, 332, + 299, 224, 224, 224, 224, 14, 14, 633, 618, 270, + 274, 659, 277, 290, 291, 818, 623, 624, 340, 340, + 340, 340, 382, 346, 206, 355, 405, 397, 490, 388, + 398, 666, 621, 586, 334, 620, 378, 335, 536, 353, + 558, 377, 328, 329, 654, 879, 627, 627, 630, 330, + 339, 6, 987, 343, 819, 344, 820, 281, 281, 281, + 396, 6, 705, 957, 710, 829, 279, 561, 562, 717, + 390, 905, 761, 763, 947, 13, 571, 573, 576, 576, + 13, 917, 571, 657, 996, 869, 914, 333, 336, 1011, + 753, 14, 224, 224, 224, 537, 760, 443, 920, 224, + 224, 224, 224, 224, 224, 882, 697, 792, 13, 933, + 886, 934, 852, 1022, 476, 713, 14, 780, 437, 438, + 439, 440, 279, 279, 484, 637, 485, 954, 787, 865, + 380, 279, 793, 646, 383, 612, 384, 404, 410, 428, + 418, 424, 872, 879, 429, 433, 795, 796, 300, 408, + 224, 224, 666, 772, 495, 385, 386, 408, 708, 224, + 387, 719, 724, 315, 711, 877, 766, 879, 874, 766, + 910, 766, 513, 766, 908, nil, nil, 14, 824, 510, + 315, 14, nil, nil, nil, 306, 14, 826, 13, 832, + 833, 527, 517, nil, nil, 419, 520, 13, 13, 639, + 542, 543, 306, nil, 514, nil, nil, 642, 280, 666, + 666, 14, 224, nil, 116, nil, 280, 642, nil, 297, + 955, nil, nil, 548, 297, 506, 224, 224, 499, 526, + nil, 742, 500, nil, nil, 1012, 747, 700, 898, 775, + nil, 843, 844, 340, 340, 642, 224, 709, 498, nil, + 264, 483, nil, 642, 779, 563, 823, nil, nil, 486, + 805, nil, 224, 560, 827, 502, 959, 116, 831, 727, + 508, 727, nil, 592, nil, nil, nil, nil, 878, 564, + 880, nil, 585, 13, nil, 766, nil, 766, nil, 766, + nil, 766, 627, 630, nil, 270, 281, nil, nil, 274, + 279, 544, 434, nil, 281, nil, nil, nil, 13, nil, + nil, 791, nil, nil, nil, nil, 132, nil, nil, nil, + nil, nil, 134, 403, 129, 911, nil, 912, 224, nil, + nil, nil, 26, nil, nil, nil, 614, 26, nil, 766, + nil, nil, nil, nil, nil, nil, nil, nil, 300, nil, + 775, nil, 26, nil, 788, nil, nil, nil, nil, 936, + nil, 26, 26, 26, 279, 26, nil, nil, 315, 13, + 428, nil, 997, 13, nil, 597, 315, nil, 13, nil, + 517, 602, 14, 901, 14, nil, nil, nil, 517, nil, + 306, 805, 224, 960, 888, 26, 26, nil, 306, 26, + nil, 598, 279, 13, nil, 634, 224, 603, nil, nil, + nil, 756, 279, 300, nil, nil, nil, 981, 300, nil, + nil, 14, 926, 650, 14, nil, 419, nil, nil, nil, + 224, nil, nil, nil, 619, nil, nil, 428, nil, 6, + 224, 992, nil, nil, 14, 26, nil, 428, 771, 951, + 26, 26, 26, 26, 26, 26, nil, nil, nil, 956, + 598, nil, nil, nil, 694, 694, nil, nil, nil, nil, + 731, nil, 805, 592, 805, 428, 1020, 764, 224, 224, + nil, 428, 712, 224, 224, nil, 699, 224, 770, nil, + nil, nil, nil, 419, nil, nil, nil, 315, 789, nil, + 592, 14, nil, 419, 132, nil, 14, 14, 315, 517, + 134, nil, 129, 991, nil, 790, nil, 626, nil, 306, + 781, nil, nil, 738, 740, nil, nil, 834, 743, 745, + 306, 419, 433, 985, 805, 846, 848, 850, nil, 419, + 26, 26, 26, 26, nil, nil, nil, nil, 26, 26, + 26, 26, 26, 26, nil, nil, nil, 656, nil, nil, + nil, 592, 825, nil, nil, 26, nil, nil, 828, nil, + 592, 805, nil, 805, 13, nil, 13, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 224, 873, + nil, nil, 408, 14, 224, 805, nil, 14, nil, 26, + 26, nil, nil, nil, nil, 340, nil, 14, 26, nil, + nil, 340, 15, 13, nil, 674, 13, 15, 224, nil, + nil, 737, nil, nil, 764, 598, 26, 315, 603, 863, + 26, 441, nil, 867, nil, 26, 13, 907, nil, nil, + 756, nil, 756, 129, 756, 15, 308, 308, nil, 855, + nil, 757, nil, 690, 764, 14, 692, nil, nil, nil, + 26, 26, nil, 837, nil, 998, nil, nil, 14, nil, + nil, nil, nil, 642, 892, 26, 26, nil, nil, nil, + 352, 361, 361, nil, nil, nil, 487, 962, 964, 966, + 968, 16, 969, 13, 765, 26, 16, nil, 13, 13, + 224, nil, 14, 14, nil, nil, 14, nil, nil, 503, + nil, 26, 14, nil, nil, 315, nil, 340, nil, nil, + nil, nil, nil, nil, 16, 15, nil, 315, nil, nil, + nil, nil, nil, 769, 15, 15, 674, 921, 773, 774, + nil, nil, nil, nil, nil, 14, nil, 694, nil, 929, + 900, nil, nil, nil, nil, 904, 756, nil, 756, 354, + 756, nil, 756, nil, 799, 801, 803, nil, nil, 1016, + 1017, 1018, 1019, nil, nil, nil, nil, 26, 970, nil, + nil, nil, nil, nil, nil, 13, nil, nil, nil, 13, + nil, nil, nil, 674, 674, nil, nil, nil, nil, 13, + 1025, nil, 976, nil, 16, nil, nil, nil, nil, 14, + 756, nil, nil, 16, 16, nil, 14, 14, nil, nil, + 15, nil, nil, nil, nil, nil, nil, nil, nil, 875, + 279, 26, 875, 26, 14, nil, nil, nil, nil, 835, + 14, 26, 14, nil, nil, 15, nil, 13, 428, nil, + 606, nil, nil, nil, nil, 26, nil, nil, 224, 592, + 13, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 26, nil, nil, 26, nil, nil, 674, 875, 674, 26, + 757, nil, 757, nil, 757, nil, nil, 858, nil, 26, + nil, nil, 622, 26, 13, 13, 625, nil, 13, 16, + 864, nil, nil, 428, 13, nil, 15, nil, 432, nil, + 15, nil, 635, nil, 308, 15, nil, nil, 638, nil, + nil, nil, nil, 765, 16, 765, nil, 26, 26, nil, + nil, 308, 26, 26, 894, 895, 26, 13, 897, nil, + 15, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 26, nil, nil, nil, nil, 26, 26, nil, nil, 419, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 718, nil, 758, 925, 938, 940, + nil, 942, 944, 38, 945, 16, nil, nil, 38, 16, + nil, nil, nil, nil, 16, nil, 757, nil, 757, nil, + 757, 13, 757, nil, nil, nil, nil, nil, 13, 13, + nil, nil, nil, nil, nil, 674, 38, 304, 304, 16, + nil, nil, 337, nil, nil, nil, 13, nil, nil, nil, + nil, nil, 13, nil, 13, nil, nil, 26, nil, 765, + nil, 974, 26, 26, nil, nil, 26, nil, 979, 980, + 757, 348, 364, 364, 364, nil, 26, nil, nil, nil, + 782, nil, nil, nil, nil, nil, 989, 26, nil, nil, + nil, nil, 990, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1006, 1007, 1008, 1009, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 38, nil, nil, nil, + nil, nil, nil, nil, 26, 38, 38, nil, nil, nil, + nil, 15, nil, 15, nil, nil, nil, 26, nil, 308, + nil, nil, 1024, nil, nil, nil, nil, 308, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 26, + 15, 26, 26, 15, nil, 26, nil, nil, nil, nil, + 881, 26, 883, nil, nil, nil, nil, nil, nil, nil, + nil, 406, nil, 15, nil, nil, nil, nil, nil, 436, + 723, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 16, 38, 16, nil, 26, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 913, nil, 915, + nil, nil, nil, nil, nil, nil, 38, nil, nil, nil, + 890, nil, nil, nil, nil, nil, nil, nil, nil, 16, + 15, nil, 16, nil, nil, 15, 15, nil, nil, nil, + nil, nil, 903, nil, nil, 492, nil, 494, 308, nil, + 496, 497, 16, nil, nil, nil, nil, nil, 26, 308, + nil, nil, nil, nil, nil, 26, 26, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 38, nil, nil, + nil, 38, nil, 26, nil, 304, 38, nil, nil, 26, + nil, 26, nil, nil, nil, 432, 946, 982, nil, 983, + nil, 984, 304, nil, nil, nil, nil, 26, nil, 16, + nil, 38, nil, nil, 16, 16, nil, nil, nil, nil, + nil, 993, 15, 994, nil, 995, 15, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 15, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 39, nil, nil, + nil, nil, 39, nil, nil, 1021, nil, nil, nil, 588, + nil, nil, nil, nil, nil, 1023, nil, nil, 361, nil, + nil, nil, nil, nil, 15, nil, nil, nil, nil, nil, + 39, 305, 305, nil, nil, nil, nil, 15, nil, nil, + nil, 16, nil, nil, nil, 16, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 16, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 349, 365, 365, 365, nil, + nil, 15, 15, nil, nil, 15, nil, nil, nil, nil, + nil, 15, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 628, nil, 337, nil, 631, nil, nil, nil, nil, + nil, nil, nil, 16, nil, nil, 361, nil, nil, nil, + 39, nil, nil, nil, 15, nil, 16, nil, 931, 39, + 39, nil, 38, nil, 38, nil, nil, nil, nil, nil, + 304, 628, nil, nil, 337, nil, nil, nil, 304, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 436, nil, + 16, 16, nil, nil, 16, nil, nil, nil, nil, nil, + 16, 38, nil, nil, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 15, nil, + nil, nil, nil, nil, 38, 15, 15, nil, nil, nil, + nil, 732, nil, 16, nil, 628, 337, 932, nil, nil, + nil, nil, nil, 15, nil, 39, nil, nil, nil, 15, + nil, 15, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 39, 776, nil, nil, 777, nil, nil, nil, nil, nil, + nil, 38, nil, nil, nil, nil, 38, 38, nil, nil, + nil, nil, nil, nil, 786, nil, nil, 16, nil, 304, + nil, nil, nil, nil, 16, 16, nil, nil, nil, nil, + 304, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 811, nil, 16, nil, nil, nil, nil, nil, 16, nil, + 16, 39, nil, nil, nil, 39, nil, nil, nil, 305, + 39, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 305, nil, nil, nil, + nil, nil, nil, nil, nil, 39, nil, nil, nil, nil, + nil, nil, nil, 38, nil, 836, nil, 38, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 38, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 364, + nil, nil, nil, nil, nil, 38, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 885, nil, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 896, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 231, 337, 38, 38, nil, nil, 38, nil, nil, 278, + 278, 278, 38, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 324, 325, 326, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 364, nil, 278, + 278, nil, nil, nil, nil, 38, nil, nil, nil, 927, + nil, nil, nil, nil, nil, nil, 39, nil, 39, nil, + nil, nil, nil, nil, 305, nil, nil, nil, nil, nil, + nil, nil, 305, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 39, nil, nil, 39, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 38, + nil, nil, nil, nil, nil, nil, 38, 38, 39, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 38, nil, nil, nil, nil, nil, + 38, nil, 38, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 39, nil, nil, nil, nil, + 39, 39, nil, nil, nil, nil, nil, nil, nil, 278, + 411, 278, nil, 305, nil, nil, 430, 435, nil, nil, + nil, nil, nil, nil, 305, nil, nil, nil, nil, nil, + nil, nil, 231, nil, nil, 450, 451, 452, 453, 454, + 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, + 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, + 475, nil, nil, nil, nil, nil, nil, 278, 278, nil, + nil, nil, nil, nil, nil, nil, 278, nil, nil, nil, + nil, nil, nil, 278, nil, 278, nil, 39, 278, 278, + nil, 39, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 39, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 522, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 365, nil, nil, nil, nil, nil, 39, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 39, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 39, 39, nil, nil, + 39, nil, nil, nil, nil, nil, 39, 278, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 365, nil, nil, nil, nil, nil, nil, nil, 39, + nil, nil, nil, 928, nil, 278, nil, 430, 613, 411, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 278, + nil, 278, nil, 278, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 39, nil, nil, nil, nil, nil, 278, + 39, 39, nil, nil, nil, nil, nil, nil, 648, 649, + nil, nil, nil, nil, nil, nil, nil, nil, 39, 278, + nil, nil, 278, nil, 39, nil, 39, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 278, 278, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 278, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 278, + 734, nil, nil, 278, 278, 739, 741, nil, nil, nil, + 744, 746, nil, nil, 613, 748, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 278, + nil, nil, 278, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 278, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 278, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 278, nil, 838, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 739, + 741, 746, 744, nil, 841, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 278, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 278, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 278, + 838, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 278 ] + +racc_goto_check = [ + 32, 57, 8, 22, 34, 34, 34, 25, 22, 87, + 24, 142, 15, 15, 74, 65, 65, 25, 90, 90, + 40, 23, 37, 22, 2, 68, 32, 50, 93, 38, + 38, 28, 22, 22, 22, 18, 22, 22, 22, 28, + 17, 17, 10, 99, 17, 97, 61, 61, 64, 65, + 65, 65, 62, 62, 58, 58, 91, 52, 7, 6, + 174, 130, 75, 7, 75, 182, 22, 22, 20, 155, + 22, 22, 22, 22, 46, 92, 92, 23, 51, 4, + 38, 55, 5, 30, 30, 133, 135, 30, 178, 69, + 69, 69, 179, 118, 11, 17, 17, 17, 17, 120, + 136, 56, 56, 39, 39, 39, 182, 70, 70, 97, + 1, 70, 121, 159, 159, 12, 22, 58, 173, 69, + 47, 22, 22, 22, 22, 22, 22, 14, 41, 72, + 72, 141, 45, 45, 45, 11, 41, 41, 30, 30, + 30, 30, 156, 4, 16, 19, 29, 2, 74, 156, + 31, 167, 43, 63, 67, 73, 85, 86, 89, 94, + 96, 100, 101, 102, 103, 173, 75, 75, 182, 104, + 105, 7, 121, 106, 107, 108, 109, 71, 71, 71, + 7, 7, 110, 111, 112, 113, 34, 114, 115, 116, + 5, 117, 122, 128, 118, 21, 160, 160, 160, 160, + 21, 134, 160, 137, 135, 138, 179, 71, 71, 121, + 24, 22, 22, 22, 22, 139, 131, 25, 136, 22, + 22, 22, 22, 22, 22, 178, 93, 140, 21, 143, + 120, 144, 133, 121, 145, 8, 22, 24, 30, 30, + 30, 30, 34, 34, 147, 52, 148, 149, 150, 151, + 154, 34, 141, 52, 157, 23, 158, 20, 20, 58, + 38, 38, 133, 173, 20, 20, 125, 125, 9, 69, + 22, 22, 167, 41, 155, 161, 162, 69, 55, 22, + 163, 164, 165, 65, 166, 171, 174, 173, 175, 174, + 130, 174, 32, 174, 176, nil, nil, 22, 24, 25, + 65, 22, nil, nil, nil, 22, 22, 24, 21, 141, + 141, 32, 50, nil, nil, 72, 25, 21, 21, 23, + 17, 17, 22, nil, 64, nil, nil, 38, 69, 167, + 167, 22, 22, nil, 97, nil, 69, 38, nil, 46, + 11, nil, nil, 25, 46, 51, 22, 22, 6, 30, + nil, 40, 7, nil, nil, 91, 40, 23, 92, 74, + nil, 125, 125, 30, 30, 38, 22, 23, 4, nil, + 25, 45, nil, 38, 52, 37, 90, nil, nil, 45, + 119, nil, 22, 30, 8, 47, 99, 97, 8, 160, + 47, 160, nil, 32, nil, nil, nil, nil, 131, 30, + 131, nil, 15, 21, nil, 174, nil, 174, nil, 174, + nil, 174, 75, 182, nil, 72, 71, nil, nil, 72, + 34, 4, 18, nil, 71, nil, nil, nil, 21, nil, + nil, 70, nil, nil, nil, nil, 61, nil, nil, nil, + nil, nil, 62, 9, 58, 131, nil, 131, 22, nil, + nil, nil, 42, nil, nil, nil, 32, 42, nil, 174, + nil, nil, nil, nil, nil, nil, nil, nil, 9, nil, + 74, nil, 42, nil, 28, nil, nil, nil, nil, 125, + nil, 42, 42, 42, 34, 42, nil, nil, 65, 21, + 58, nil, 10, 21, nil, 39, 65, nil, 21, nil, + 50, 39, 22, 8, 22, nil, nil, nil, 50, nil, + 22, 119, 22, 125, 119, 42, 42, nil, 22, 42, + nil, 72, 34, 21, nil, 2, 22, 72, nil, nil, + nil, 124, 34, 9, nil, nil, nil, 131, 9, nil, + nil, 22, 90, 30, 22, nil, 72, nil, nil, nil, + 22, nil, nil, nil, 39, nil, nil, 58, nil, 7, + 22, 131, nil, nil, 22, 42, nil, 58, 87, 90, + 42, 42, 42, 42, 42, 42, nil, nil, nil, 93, + 72, nil, nil, nil, 97, 97, nil, nil, nil, nil, + 15, nil, 119, 32, 119, 58, 24, 32, 22, 22, + nil, 58, 97, 22, 22, nil, 69, 22, 142, nil, + nil, nil, nil, 72, nil, nil, nil, 65, 68, nil, + 32, 22, nil, 72, 61, nil, 22, 22, 65, 50, + 62, nil, 58, 8, nil, 32, nil, 71, nil, 22, + 50, nil, nil, 20, 20, nil, nil, 57, 20, 20, + 22, 72, 20, 119, 119, 127, 127, 127, nil, 72, + 42, 42, 42, 42, nil, nil, nil, nil, 42, 42, + 42, 42, 42, 42, nil, nil, nil, 71, nil, nil, + nil, 32, 17, nil, nil, 42, nil, nil, 17, nil, + 32, 119, nil, 119, 21, nil, 21, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 22, 124, + nil, nil, 69, 22, 22, 119, nil, 22, nil, 42, + 42, nil, nil, nil, nil, 30, nil, 22, 42, nil, + nil, 30, 26, 21, nil, 172, 21, 26, 22, nil, + nil, 71, nil, nil, 32, 72, 42, 65, 72, 68, + 42, 48, nil, 68, nil, 42, 21, 124, nil, nil, + 124, nil, 124, 58, 124, 26, 26, 26, nil, 22, + nil, 126, nil, 9, 32, 22, 9, nil, nil, nil, + 42, 42, nil, 20, nil, 23, nil, nil, 22, nil, + nil, nil, nil, 38, 17, 42, 42, nil, nil, nil, + 26, 26, 26, nil, nil, nil, 48, 127, 127, 127, + 127, 27, 127, 21, 172, 42, 27, nil, 21, 21, + 22, nil, 22, 22, nil, nil, 22, nil, nil, 48, + nil, 42, 22, nil, nil, 65, nil, 30, nil, nil, + nil, nil, nil, nil, 27, 26, nil, 65, nil, nil, + nil, nil, nil, 9, 26, 26, 172, 22, 9, 9, + nil, nil, nil, nil, nil, 22, nil, 97, nil, 22, + 97, nil, nil, nil, nil, 97, 124, nil, 124, 27, + 124, nil, 124, nil, 170, 170, 170, nil, nil, 127, + 127, 127, 127, nil, nil, nil, nil, 42, 32, nil, + nil, nil, nil, nil, nil, 21, nil, nil, nil, 21, + nil, nil, nil, 172, 172, nil, nil, nil, nil, 21, + 127, nil, 25, nil, 27, nil, nil, nil, nil, 22, + 124, nil, nil, 27, 27, nil, 22, 22, nil, nil, + 26, nil, nil, nil, nil, nil, nil, nil, nil, 126, + 34, 42, 126, 42, 22, nil, nil, nil, nil, 9, + 22, 42, 22, nil, nil, 26, nil, 21, 58, nil, + 48, nil, nil, nil, nil, 42, nil, nil, 22, 32, + 21, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 42, nil, nil, 42, nil, nil, 172, 126, 172, 42, + 126, nil, 126, nil, 126, nil, nil, 9, nil, 42, + nil, nil, 48, 42, 21, 21, 48, nil, 21, 27, + 9, nil, nil, 58, 21, nil, 26, nil, 27, nil, + 26, nil, 48, nil, 26, 26, nil, nil, 48, nil, + nil, nil, nil, 172, 27, 172, nil, 42, 42, nil, + nil, 26, 42, 42, 9, 9, 42, 21, 9, nil, + 26, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 42, nil, nil, nil, nil, 42, 42, nil, nil, 72, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 48, nil, 129, 9, 170, 170, + nil, 170, 170, 53, 170, 27, nil, nil, 53, 27, + nil, nil, nil, nil, 27, nil, 126, nil, 126, nil, + 126, 21, 126, nil, nil, nil, nil, nil, 21, 21, + nil, nil, nil, nil, nil, 172, 53, 53, 53, 27, + nil, nil, 66, nil, nil, nil, 21, nil, nil, nil, + nil, nil, 21, nil, 21, nil, nil, 42, nil, 172, + nil, 9, 42, 42, nil, nil, 42, nil, 9, 9, + 126, 53, 53, 53, 53, nil, 42, nil, nil, nil, + 48, nil, nil, nil, nil, nil, 9, 42, nil, nil, + nil, nil, 9, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 170, 170, 170, 170, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 53, nil, nil, nil, + nil, nil, nil, nil, 42, 53, 53, nil, nil, nil, + nil, 26, nil, 26, nil, nil, nil, 42, nil, 26, + nil, nil, 170, nil, nil, nil, nil, 26, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 42, + 26, 42, 42, 26, nil, 42, nil, nil, nil, nil, + 129, 42, 129, nil, nil, nil, nil, nil, nil, nil, + nil, 66, nil, 26, nil, nil, nil, nil, nil, 66, + 26, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 27, 53, 27, nil, 42, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 129, nil, 129, + nil, nil, nil, nil, nil, nil, 53, nil, nil, nil, + 48, nil, nil, nil, nil, nil, nil, nil, nil, 27, + 26, nil, 27, nil, nil, 26, 26, nil, nil, nil, + nil, nil, 48, nil, nil, 66, nil, 66, 26, nil, + 66, 66, 27, nil, nil, nil, nil, nil, 42, 26, + nil, nil, nil, nil, nil, 42, 42, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 53, nil, nil, + nil, 53, nil, 42, nil, 53, 53, nil, nil, 42, + nil, 42, nil, nil, nil, 27, 48, 129, nil, 129, + nil, 129, 53, nil, nil, nil, nil, 42, nil, 27, + nil, 53, nil, nil, 27, 27, nil, nil, nil, nil, + nil, 129, 26, 129, nil, 129, 26, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 26, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 54, nil, nil, + nil, nil, 54, nil, nil, 129, nil, nil, nil, 66, + nil, nil, nil, nil, nil, 129, nil, nil, 26, nil, + nil, nil, nil, nil, 26, nil, nil, nil, nil, nil, + 54, 54, 54, nil, nil, nil, nil, 26, nil, nil, + nil, 27, nil, nil, nil, 27, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 27, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 54, 54, 54, 54, nil, + nil, 26, 26, nil, nil, 26, nil, nil, nil, nil, + nil, 26, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 66, nil, 66, nil, 66, nil, nil, nil, nil, + nil, nil, nil, 27, nil, nil, 26, nil, nil, nil, + 54, nil, nil, nil, 26, nil, 27, nil, 26, 54, + 54, nil, 53, nil, 53, nil, nil, nil, nil, nil, + 53, 66, nil, nil, 66, nil, nil, nil, 53, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 66, nil, + 27, 27, nil, nil, 27, nil, nil, nil, nil, nil, + 27, 53, nil, nil, 53, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 26, nil, + nil, nil, nil, nil, 53, 26, 26, nil, nil, nil, + nil, 66, nil, 27, nil, 66, 66, 27, nil, nil, + nil, nil, nil, 26, nil, 54, nil, nil, nil, 26, + nil, 26, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 54, 66, nil, nil, 66, nil, nil, nil, nil, nil, + nil, 53, nil, nil, nil, nil, 53, 53, nil, nil, + nil, nil, nil, nil, 66, nil, nil, 27, nil, 53, + nil, nil, nil, nil, 27, 27, nil, nil, nil, nil, + 53, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 66, nil, 27, nil, nil, nil, nil, nil, 27, nil, + 27, 54, nil, nil, nil, 54, nil, nil, nil, 54, + 54, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 54, nil, nil, nil, + nil, nil, nil, nil, nil, 54, nil, nil, nil, nil, + nil, nil, nil, 53, nil, 66, nil, 53, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 53, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 53, + nil, nil, nil, nil, nil, 53, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 66, nil, 53, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 66, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 33, 66, 53, 53, nil, nil, 53, nil, nil, 33, + 33, 33, 53, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 33, 33, 33, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 53, nil, 33, + 33, nil, nil, nil, nil, 53, nil, nil, nil, 53, + nil, nil, nil, nil, nil, nil, 54, nil, 54, nil, + nil, nil, nil, nil, 54, nil, nil, nil, nil, nil, + nil, nil, 54, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 54, nil, nil, 54, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 53, + nil, nil, nil, nil, nil, nil, 53, 53, 54, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 53, nil, nil, nil, nil, nil, + 53, nil, 53, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 54, nil, nil, nil, nil, + 54, 54, nil, nil, nil, nil, nil, nil, nil, 33, + 33, 33, nil, 54, nil, nil, 33, 33, nil, nil, + nil, nil, nil, nil, 54, nil, nil, nil, nil, nil, + nil, nil, 33, nil, nil, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, nil, nil, nil, nil, nil, nil, 33, 33, nil, + nil, nil, nil, nil, nil, nil, 33, nil, nil, nil, + nil, nil, nil, 33, nil, 33, nil, 54, 33, 33, + nil, 54, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 54, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 33, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 54, nil, nil, nil, nil, nil, 54, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 54, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 54, 54, nil, nil, + 54, nil, nil, nil, nil, nil, 54, 33, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 54, nil, nil, nil, nil, nil, nil, nil, 54, + nil, nil, nil, 54, nil, 33, nil, 33, 33, 33, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 33, + nil, 33, nil, 33, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 54, nil, nil, nil, nil, nil, 33, + 54, 54, nil, nil, nil, nil, nil, nil, 33, 33, + nil, nil, nil, nil, nil, nil, nil, nil, 54, 33, + nil, nil, 33, nil, 54, nil, 54, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 33, 33, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 33, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 33, + 33, nil, nil, 33, 33, 33, 33, nil, nil, nil, + 33, 33, nil, nil, 33, 33, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 33, + nil, nil, 33, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 33, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 33, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 33, nil, 33, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 33, + 33, 33, 33, nil, 33, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 33, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 33, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 33, + 33, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 33 ] + +racc_goto_pointer = [ + nil, 110, 24, nil, 76, 77, 56, 58, -326, 235, + -482, -557, -668, nil, -372, 4, 135, -23, -182, 77, + 48, 195, 3, -190, -402, -7, 732, 811, -178, -63, + 20, 26, -19, 1900, -25, nil, nil, -2, -183, 77, + -246, -348, 452, -328, nil, 103, 41, 87, 530, nil, + -7, 43, -262, 1103, 1477, -277, 32, -70, 46, nil, + nil, 38, 44, -249, 7, -19, 1082, 95, -34, 60, + -225, 148, 103, -322, -267, -427, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 85, 97, -52, nil, -181, + -323, -634, -467, -318, 91, nil, -202, 42, nil, -519, + 90, 105, 105, -362, 111, 108, 108, -519, 109, -520, + -369, -715, -374, -527, -179, -188, -374, -643, -794, -295, + -576, -777, -424, nil, -85, -394, 155, -103, -423, 480, + -555, -400, nil, -531, -652, -767, -753, -334, -587, -124, + -430, -406, -11, -641, -640, -27, nil, -27, -26, -650, + -404, -538, nil, nil, 171, -12, 58, 169, 170, -271, + -186, 188, 188, 191, -287, -287, -275, -386, nil, nil, + 221, -513, 198, -680, -556, -506, -548, nil, -712, -755, + nil, nil, -426 ] + +racc_goto_default = [ + nil, nil, nil, 3, nil, 4, 347, 295, nil, 524, + nil, 816, nil, 292, 293, nil, nil, nil, 11, 12, + 18, 230, 323, nil, nil, 556, 228, 229, nil, nil, + 17, nil, 442, 21, 22, 23, 24, nil, 645, nil, + nil, nil, 312, nil, 25, 413, 32, nil, nil, 34, + 37, 36, nil, 225, 226, 359, nil, 131, 421, 130, + 133, 77, 78, nil, 92, 46, 284, nil, 784, 414, + nil, 415, 426, 599, 488, 282, 268, 47, 48, 49, + 50, 51, 52, 53, 54, 55, nil, 269, 61, nil, + nil, nil, nil, nil, nil, 69, nil, 539, 70, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 807, 673, + nil, 808, 909, 755, 661, nil, 662, nil, nil, 663, + nil, 665, 615, nil, nil, nil, 671, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 425, nil, nil, nil, + nil, nil, 76, 79, 80, nil, nil, nil, nil, nil, + 566, nil, nil, nil, nil, nil, nil, 876, 716, 660, + nil, 664, 884, 676, 678, 679, 767, 682, 683, 768, + 686, 689, 287 ] + +racc_reduce_table = [ + 0, 0, :racc_error, + 1, 146, :_reduce_none, + 2, 147, :_reduce_2, + 0, 148, :_reduce_3, + 1, 148, :_reduce_4, + 3, 148, :_reduce_5, + 2, 148, :_reduce_6, + 1, 150, :_reduce_none, + 4, 150, :_reduce_8, + 4, 153, :_reduce_9, + 2, 154, :_reduce_10, + 0, 158, :_reduce_11, + 1, 158, :_reduce_12, + 3, 158, :_reduce_13, + 2, 158, :_reduce_14, + 1, 159, :_reduce_none, + 4, 159, :_reduce_16, + 0, 176, :_reduce_17, + 4, 152, :_reduce_18, + 3, 152, :_reduce_19, + 3, 152, :_reduce_20, + 3, 152, :_reduce_21, + 2, 152, :_reduce_22, + 3, 152, :_reduce_23, + 3, 152, :_reduce_24, + 3, 152, :_reduce_25, + 3, 152, :_reduce_26, + 3, 152, :_reduce_27, + 4, 152, :_reduce_28, + 1, 152, :_reduce_none, + 3, 152, :_reduce_30, + 3, 152, :_reduce_31, + 6, 152, :_reduce_32, + 5, 152, :_reduce_33, + 5, 152, :_reduce_34, + 5, 152, :_reduce_35, + 5, 152, :_reduce_36, + 3, 152, :_reduce_37, + 3, 152, :_reduce_38, + 3, 152, :_reduce_39, + 1, 152, :_reduce_none, + 3, 163, :_reduce_41, + 3, 163, :_reduce_42, + 1, 175, :_reduce_none, + 3, 175, :_reduce_44, + 3, 175, :_reduce_45, + 3, 175, :_reduce_46, + 2, 175, :_reduce_47, + 1, 175, :_reduce_none, + 1, 162, :_reduce_none, + 1, 165, :_reduce_none, + 1, 165, :_reduce_none, + 1, 180, :_reduce_none, + 4, 180, :_reduce_53, + 0, 188, :_reduce_54, + 5, 185, :_reduce_55, + 1, 187, :_reduce_none, + 2, 179, :_reduce_57, + 3, 179, :_reduce_58, + 4, 179, :_reduce_59, + 5, 179, :_reduce_60, + 4, 179, :_reduce_61, + 5, 179, :_reduce_62, + 2, 179, :_reduce_63, + 2, 179, :_reduce_64, + 2, 179, :_reduce_65, + 2, 179, :_reduce_66, + 2, 179, :_reduce_67, + 1, 164, :_reduce_68, + 3, 164, :_reduce_69, + 1, 192, :_reduce_70, + 3, 192, :_reduce_71, + 1, 191, :_reduce_none, + 2, 191, :_reduce_73, + 3, 191, :_reduce_74, + 5, 191, :_reduce_75, + 2, 191, :_reduce_76, + 4, 191, :_reduce_77, + 2, 191, :_reduce_78, + 4, 191, :_reduce_79, + 1, 191, :_reduce_80, + 3, 191, :_reduce_81, + 1, 195, :_reduce_none, + 3, 195, :_reduce_83, + 2, 194, :_reduce_84, + 3, 194, :_reduce_85, + 1, 197, :_reduce_86, + 3, 197, :_reduce_87, + 1, 196, :_reduce_88, + 1, 196, :_reduce_89, + 4, 196, :_reduce_90, + 3, 196, :_reduce_91, + 3, 196, :_reduce_92, + 3, 196, :_reduce_93, + 3, 196, :_reduce_94, + 2, 196, :_reduce_95, + 1, 196, :_reduce_96, + 1, 172, :_reduce_97, + 1, 172, :_reduce_98, + 4, 172, :_reduce_99, + 3, 172, :_reduce_100, + 3, 172, :_reduce_101, + 3, 172, :_reduce_102, + 3, 172, :_reduce_103, + 2, 172, :_reduce_104, + 1, 172, :_reduce_105, + 1, 200, :_reduce_106, + 1, 200, :_reduce_none, + 2, 201, :_reduce_108, + 1, 201, :_reduce_109, + 3, 201, :_reduce_110, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 205, :_reduce_116, + 1, 205, :_reduce_none, + 1, 160, :_reduce_none, + 1, 160, :_reduce_none, + 1, 161, :_reduce_120, + 0, 208, :_reduce_121, + 4, 161, :_reduce_122, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 3, 178, :_reduce_194, + 5, 178, :_reduce_195, + 3, 178, :_reduce_196, + 5, 178, :_reduce_197, + 6, 178, :_reduce_198, + 5, 178, :_reduce_199, + 5, 178, :_reduce_200, + 5, 178, :_reduce_201, + 5, 178, :_reduce_202, + 4, 178, :_reduce_203, + 3, 178, :_reduce_204, + 3, 178, :_reduce_205, + 3, 178, :_reduce_206, + 3, 178, :_reduce_207, + 3, 178, :_reduce_208, + 3, 178, :_reduce_209, + 3, 178, :_reduce_210, + 3, 178, :_reduce_211, + 3, 178, :_reduce_212, + 4, 178, :_reduce_213, + 2, 178, :_reduce_214, + 2, 178, :_reduce_215, + 3, 178, :_reduce_216, + 3, 178, :_reduce_217, + 3, 178, :_reduce_218, + 3, 178, :_reduce_219, + 3, 178, :_reduce_220, + 3, 178, :_reduce_221, + 3, 178, :_reduce_222, + 3, 178, :_reduce_223, + 3, 178, :_reduce_224, + 3, 178, :_reduce_225, + 3, 178, :_reduce_226, + 3, 178, :_reduce_227, + 3, 178, :_reduce_228, + 2, 178, :_reduce_229, + 2, 178, :_reduce_230, + 3, 178, :_reduce_231, + 3, 178, :_reduce_232, + 3, 178, :_reduce_233, + 3, 178, :_reduce_234, + 3, 178, :_reduce_235, + 6, 178, :_reduce_236, + 1, 178, :_reduce_none, + 1, 211, :_reduce_none, + 1, 212, :_reduce_none, + 2, 212, :_reduce_none, + 4, 212, :_reduce_241, + 2, 212, :_reduce_242, + 3, 217, :_reduce_243, + 0, 218, :_reduce_244, + 1, 218, :_reduce_none, + 0, 168, :_reduce_246, + 1, 168, :_reduce_none, + 2, 168, :_reduce_none, + 4, 168, :_reduce_249, + 2, 168, :_reduce_250, + 1, 190, :_reduce_251, + 2, 190, :_reduce_252, + 2, 190, :_reduce_253, + 4, 190, :_reduce_254, + 1, 190, :_reduce_255, + 0, 221, :_reduce_256, + 2, 184, :_reduce_257, + 2, 220, :_reduce_258, + 2, 219, :_reduce_259, + 0, 219, :_reduce_260, + 1, 214, :_reduce_261, + 2, 214, :_reduce_262, + 3, 214, :_reduce_263, + 4, 214, :_reduce_264, + 1, 174, :_reduce_265, + 1, 174, :_reduce_none, + 3, 173, :_reduce_267, + 4, 173, :_reduce_268, + 2, 173, :_reduce_269, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_280, + 0, 246, :_reduce_281, + 4, 210, :_reduce_282, + 0, 247, :_reduce_283, + 0, 248, :_reduce_284, + 6, 210, :_reduce_285, + 0, 249, :_reduce_286, + 4, 210, :_reduce_287, + 3, 210, :_reduce_288, + 3, 210, :_reduce_289, + 2, 210, :_reduce_290, + 3, 210, :_reduce_291, + 3, 210, :_reduce_292, + 1, 210, :_reduce_293, + 4, 210, :_reduce_294, + 3, 210, :_reduce_295, + 1, 210, :_reduce_296, + 5, 210, :_reduce_297, + 4, 210, :_reduce_298, + 3, 210, :_reduce_299, + 2, 210, :_reduce_300, + 1, 210, :_reduce_none, + 2, 210, :_reduce_302, + 0, 250, :_reduce_303, + 3, 210, :_reduce_304, + 6, 210, :_reduce_305, + 6, 210, :_reduce_306, + 0, 251, :_reduce_307, + 0, 252, :_reduce_308, + 7, 210, :_reduce_309, + 0, 253, :_reduce_310, + 0, 254, :_reduce_311, + 7, 210, :_reduce_312, + 5, 210, :_reduce_313, + 4, 210, :_reduce_314, + 0, 255, :_reduce_315, + 0, 256, :_reduce_316, + 9, 210, :_reduce_317, + 0, 257, :_reduce_318, + 6, 210, :_reduce_319, + 0, 258, :_reduce_320, + 7, 210, :_reduce_321, + 0, 259, :_reduce_322, + 5, 210, :_reduce_323, + 0, 260, :_reduce_324, + 6, 210, :_reduce_325, + 0, 261, :_reduce_326, + 0, 262, :_reduce_327, + 9, 210, :_reduce_328, + 1, 210, :_reduce_329, + 1, 210, :_reduce_330, + 1, 210, :_reduce_331, + 1, 210, :_reduce_332, + 1, 167, :_reduce_none, + 1, 240, :_reduce_334, + 1, 243, :_reduce_335, + 1, 235, :_reduce_none, + 1, 235, :_reduce_none, + 2, 235, :_reduce_338, + 1, 237, :_reduce_none, + 1, 237, :_reduce_none, + 1, 236, :_reduce_none, + 5, 236, :_reduce_342, + 1, 156, :_reduce_none, + 2, 156, :_reduce_344, + 1, 239, :_reduce_none, + 1, 239, :_reduce_none, + 1, 263, :_reduce_347, + 3, 263, :_reduce_348, + 1, 266, :_reduce_349, + 3, 266, :_reduce_350, + 1, 265, :_reduce_none, + 4, 265, :_reduce_352, + 6, 265, :_reduce_353, + 3, 265, :_reduce_354, + 5, 265, :_reduce_355, + 2, 265, :_reduce_356, + 4, 265, :_reduce_357, + 1, 265, :_reduce_358, + 3, 265, :_reduce_359, + 4, 267, :_reduce_360, + 2, 267, :_reduce_361, + 2, 267, :_reduce_362, + 1, 267, :_reduce_363, + 2, 272, :_reduce_364, + 0, 272, :_reduce_365, + 6, 273, :_reduce_366, + 8, 273, :_reduce_367, + 4, 273, :_reduce_368, + 6, 273, :_reduce_369, + 4, 273, :_reduce_370, + 2, 273, :_reduce_none, + 6, 273, :_reduce_372, + 2, 273, :_reduce_373, + 4, 273, :_reduce_374, + 6, 273, :_reduce_375, + 2, 273, :_reduce_376, + 4, 273, :_reduce_377, + 2, 273, :_reduce_378, + 4, 273, :_reduce_379, + 1, 273, :_reduce_none, + 0, 186, :_reduce_381, + 1, 186, :_reduce_382, + 3, 277, :_reduce_383, + 1, 277, :_reduce_384, + 4, 277, :_reduce_385, + 1, 278, :_reduce_386, + 4, 278, :_reduce_387, + 1, 279, :_reduce_388, + 3, 279, :_reduce_389, + 1, 280, :_reduce_390, + 1, 280, :_reduce_none, + 0, 284, :_reduce_392, + 0, 285, :_reduce_393, + 4, 234, :_reduce_394, + 4, 282, :_reduce_395, + 1, 282, :_reduce_396, + 0, 288, :_reduce_397, + 4, 283, :_reduce_398, + 0, 289, :_reduce_399, + 4, 283, :_reduce_400, + 0, 290, :_reduce_401, + 5, 287, :_reduce_402, + 2, 181, :_reduce_403, + 4, 181, :_reduce_404, + 5, 181, :_reduce_405, + 5, 181, :_reduce_406, + 2, 233, :_reduce_407, + 4, 233, :_reduce_408, + 4, 233, :_reduce_409, + 3, 233, :_reduce_410, + 3, 233, :_reduce_411, + 3, 233, :_reduce_412, + 2, 233, :_reduce_413, + 1, 233, :_reduce_414, + 4, 233, :_reduce_415, + 0, 292, :_reduce_416, + 5, 232, :_reduce_417, + 0, 293, :_reduce_418, + 5, 232, :_reduce_419, + 5, 238, :_reduce_420, + 1, 294, :_reduce_421, + 1, 294, :_reduce_none, + 6, 155, :_reduce_423, + 0, 155, :_reduce_424, + 1, 295, :_reduce_425, + 1, 295, :_reduce_none, + 1, 295, :_reduce_none, + 2, 296, :_reduce_428, + 1, 296, :_reduce_none, + 2, 157, :_reduce_430, + 1, 157, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 223, :_reduce_435, + 1, 298, :_reduce_436, + 2, 298, :_reduce_437, + 3, 299, :_reduce_438, + 1, 299, :_reduce_439, + 1, 299, :_reduce_440, + 3, 224, :_reduce_441, + 4, 225, :_reduce_442, + 3, 226, :_reduce_443, + 0, 303, :_reduce_444, + 3, 303, :_reduce_445, + 1, 304, :_reduce_446, + 2, 304, :_reduce_447, + 3, 228, :_reduce_448, + 0, 306, :_reduce_449, + 3, 306, :_reduce_450, + 3, 227, :_reduce_451, + 3, 229, :_reduce_452, + 0, 307, :_reduce_453, + 3, 307, :_reduce_454, + 0, 308, :_reduce_455, + 3, 308, :_reduce_456, + 0, 300, :_reduce_457, + 2, 300, :_reduce_458, + 0, 301, :_reduce_459, + 2, 301, :_reduce_460, + 0, 302, :_reduce_461, + 2, 302, :_reduce_462, + 1, 305, :_reduce_463, + 2, 305, :_reduce_464, + 0, 310, :_reduce_465, + 4, 305, :_reduce_466, + 1, 309, :_reduce_467, + 1, 309, :_reduce_468, + 1, 309, :_reduce_469, + 1, 309, :_reduce_none, + 1, 206, :_reduce_471, + 3, 207, :_reduce_472, + 1, 297, :_reduce_473, + 2, 297, :_reduce_474, + 1, 209, :_reduce_475, + 1, 209, :_reduce_476, + 1, 209, :_reduce_477, + 1, 209, :_reduce_478, + 1, 198, :_reduce_479, + 1, 198, :_reduce_480, + 1, 198, :_reduce_481, + 1, 198, :_reduce_482, + 1, 198, :_reduce_483, + 1, 199, :_reduce_484, + 1, 199, :_reduce_485, + 1, 199, :_reduce_486, + 1, 199, :_reduce_487, + 1, 199, :_reduce_488, + 1, 199, :_reduce_489, + 1, 199, :_reduce_490, + 1, 230, :_reduce_491, + 1, 230, :_reduce_492, + 1, 166, :_reduce_493, + 1, 166, :_reduce_494, + 1, 171, :_reduce_495, + 1, 171, :_reduce_496, + 0, 311, :_reduce_497, + 4, 241, :_reduce_498, + 0, 241, :_reduce_499, + 3, 244, :_reduce_500, + 0, 313, :_reduce_501, + 3, 244, :_reduce_502, + 4, 312, :_reduce_503, + 2, 312, :_reduce_504, + 2, 312, :_reduce_505, + 1, 312, :_reduce_506, + 2, 315, :_reduce_507, + 0, 315, :_reduce_508, + 6, 286, :_reduce_509, + 8, 286, :_reduce_510, + 4, 286, :_reduce_511, + 6, 286, :_reduce_512, + 4, 286, :_reduce_513, + 6, 286, :_reduce_514, + 2, 286, :_reduce_515, + 4, 286, :_reduce_516, + 6, 286, :_reduce_517, + 2, 286, :_reduce_518, + 4, 286, :_reduce_519, + 2, 286, :_reduce_520, + 4, 286, :_reduce_521, + 1, 286, :_reduce_522, + 0, 286, :_reduce_523, + 1, 281, :_reduce_524, + 1, 281, :_reduce_525, + 1, 281, :_reduce_526, + 1, 281, :_reduce_527, + 1, 264, :_reduce_none, + 1, 264, :_reduce_529, + 1, 317, :_reduce_530, + 1, 318, :_reduce_531, + 3, 318, :_reduce_532, + 1, 274, :_reduce_533, + 3, 274, :_reduce_534, + 1, 319, :_reduce_535, + 2, 320, :_reduce_536, + 1, 320, :_reduce_537, + 2, 321, :_reduce_538, + 1, 321, :_reduce_539, + 1, 268, :_reduce_540, + 3, 268, :_reduce_541, + 1, 314, :_reduce_542, + 3, 314, :_reduce_543, + 1, 322, :_reduce_none, + 1, 322, :_reduce_none, + 2, 269, :_reduce_546, + 1, 269, :_reduce_547, + 3, 323, :_reduce_548, + 3, 324, :_reduce_549, + 1, 275, :_reduce_550, + 3, 275, :_reduce_551, + 1, 316, :_reduce_552, + 3, 316, :_reduce_553, + 1, 325, :_reduce_none, + 1, 325, :_reduce_none, + 2, 276, :_reduce_556, + 1, 276, :_reduce_557, + 1, 326, :_reduce_none, + 1, 326, :_reduce_none, + 2, 271, :_reduce_560, + 2, 270, :_reduce_561, + 0, 270, :_reduce_562, + 1, 245, :_reduce_none, + 3, 245, :_reduce_564, + 0, 231, :_reduce_565, + 2, 231, :_reduce_none, + 1, 216, :_reduce_567, + 3, 216, :_reduce_568, + 3, 327, :_reduce_569, + 2, 327, :_reduce_570, + 4, 327, :_reduce_571, + 2, 327, :_reduce_572, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 183, :_reduce_none, + 1, 183, :_reduce_none, + 1, 183, :_reduce_none, + 1, 183, :_reduce_none, + 1, 291, :_reduce_none, + 1, 291, :_reduce_none, + 1, 291, :_reduce_none, + 1, 182, :_reduce_none, + 1, 182, :_reduce_none, + 1, 170, :_reduce_585, + 1, 170, :_reduce_586, + 0, 149, :_reduce_none, + 1, 149, :_reduce_none, + 0, 177, :_reduce_none, + 1, 177, :_reduce_none, + 2, 193, :_reduce_591, + 2, 169, :_reduce_592, + 0, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 242, :_reduce_596, + 1, 242, :_reduce_none, + 1, 151, :_reduce_none, + 2, 151, :_reduce_none, + 0, 213, :_reduce_600 ] + +racc_reduce_n = 601 + +racc_shift_n = 1026 + +racc_token_table = { + false => 0, + :error => 1, + :kCLASS => 2, + :kMODULE => 3, + :kDEF => 4, + :kUNDEF => 5, + :kBEGIN => 6, + :kRESCUE => 7, + :kENSURE => 8, + :kEND => 9, + :kIF => 10, + :kUNLESS => 11, + :kTHEN => 12, + :kELSIF => 13, + :kELSE => 14, + :kCASE => 15, + :kWHEN => 16, + :kWHILE => 17, + :kUNTIL => 18, + :kFOR => 19, + :kBREAK => 20, + :kNEXT => 21, + :kREDO => 22, + :kRETRY => 23, + :kIN => 24, + :kDO => 25, + :kDO_COND => 26, + :kDO_BLOCK => 27, + :kDO_LAMBDA => 28, + :kRETURN => 29, + :kYIELD => 30, + :kSUPER => 31, + :kSELF => 32, + :kNIL => 33, + :kTRUE => 34, + :kFALSE => 35, + :kAND => 36, + :kOR => 37, + :kNOT => 38, + :kIF_MOD => 39, + :kUNLESS_MOD => 40, + :kWHILE_MOD => 41, + :kUNTIL_MOD => 42, + :kRESCUE_MOD => 43, + :kALIAS => 44, + :kDEFINED => 45, + :klBEGIN => 46, + :klEND => 47, + :k__LINE__ => 48, + :k__FILE__ => 49, + :k__ENCODING__ => 50, + :tIDENTIFIER => 51, + :tFID => 52, + :tGVAR => 53, + :tIVAR => 54, + :tCONSTANT => 55, + :tLABEL => 56, + :tCVAR => 57, + :tNTH_REF => 58, + :tBACK_REF => 59, + :tSTRING_CONTENT => 60, + :tINTEGER => 61, + :tFLOAT => 62, + :tUPLUS => 63, + :tUMINUS => 64, + :tUNARY_NUM => 65, + :tPOW => 66, + :tCMP => 67, + :tEQ => 68, + :tEQQ => 69, + :tNEQ => 70, + :tGEQ => 71, + :tLEQ => 72, + :tANDOP => 73, + :tOROP => 74, + :tMATCH => 75, + :tNMATCH => 76, + :tDOT => 77, + :tDOT2 => 78, + :tDOT3 => 79, + :tAREF => 80, + :tASET => 81, + :tLSHFT => 82, + :tRSHFT => 83, + :tCOLON2 => 84, + :tCOLON3 => 85, + :tOP_ASGN => 86, + :tASSOC => 87, + :tLPAREN => 88, + :tLPAREN2 => 89, + :tRPAREN => 90, + :tLPAREN_ARG => 91, + :tLBRACK => 92, + :tLBRACK2 => 93, + :tRBRACK => 94, + :tLBRACE => 95, + :tLBRACE_ARG => 96, + :tSTAR => 97, + :tSTAR2 => 98, + :tAMPER => 99, + :tAMPER2 => 100, + :tTILDE => 101, + :tPERCENT => 102, + :tDIVIDE => 103, + :tDSTAR => 104, + :tPLUS => 105, + :tMINUS => 106, + :tLT => 107, + :tGT => 108, + :tPIPE => 109, + :tBANG => 110, + :tCARET => 111, + :tLCURLY => 112, + :tRCURLY => 113, + :tBACK_REF2 => 114, + :tSYMBEG => 115, + :tSTRING_BEG => 116, + :tXSTRING_BEG => 117, + :tREGEXP_BEG => 118, + :tREGEXP_OPT => 119, + :tWORDS_BEG => 120, + :tQWORDS_BEG => 121, + :tSYMBOLS_BEG => 122, + :tQSYMBOLS_BEG => 123, + :tSTRING_DBEG => 124, + :tSTRING_DVAR => 125, + :tSTRING_END => 126, + :tSTRING_DEND => 127, + :tSTRING => 128, + :tSYMBOL => 129, + :tNL => 130, + :tEH => 131, + :tCOLON => 132, + :tCOMMA => 133, + :tSPACE => 134, + :tSEMI => 135, + :tLAMBDA => 136, + :tLAMBEG => 137, + :tCHARACTER => 138, + :tRATIONAL => 139, + :tIMAGINARY => 140, + :tLABEL_END => 141, + :tANDDOT => 142, + :tEQL => 143, + :tLOWEST => 144 } + +racc_nt_base = 145 + +racc_use_result_var = true + +Racc_arg = [ + racc_action_table, + racc_action_check, + racc_action_default, + racc_action_pointer, + racc_goto_table, + racc_goto_check, + racc_goto_default, + racc_goto_pointer, + racc_nt_base, + racc_reduce_table, + racc_token_table, + racc_shift_n, + racc_reduce_n, + racc_use_result_var ] +Ractor.make_shareable(Racc_arg) if defined?(Ractor) + +Racc_token_to_s_table = [ + "$end", + "error", + "kCLASS", + "kMODULE", + "kDEF", + "kUNDEF", + "kBEGIN", + "kRESCUE", + "kENSURE", + "kEND", + "kIF", + "kUNLESS", + "kTHEN", + "kELSIF", + "kELSE", + "kCASE", + "kWHEN", + "kWHILE", + "kUNTIL", + "kFOR", + "kBREAK", + "kNEXT", + "kREDO", + "kRETRY", + "kIN", + "kDO", + "kDO_COND", + "kDO_BLOCK", + "kDO_LAMBDA", + "kRETURN", + "kYIELD", + "kSUPER", + "kSELF", + "kNIL", + "kTRUE", + "kFALSE", + "kAND", + "kOR", + "kNOT", + "kIF_MOD", + "kUNLESS_MOD", + "kWHILE_MOD", + "kUNTIL_MOD", + "kRESCUE_MOD", + "kALIAS", + "kDEFINED", + "klBEGIN", + "klEND", + "k__LINE__", + "k__FILE__", + "k__ENCODING__", + "tIDENTIFIER", + "tFID", + "tGVAR", + "tIVAR", + "tCONSTANT", + "tLABEL", + "tCVAR", + "tNTH_REF", + "tBACK_REF", + "tSTRING_CONTENT", + "tINTEGER", + "tFLOAT", + "tUPLUS", + "tUMINUS", + "tUNARY_NUM", + "tPOW", + "tCMP", + "tEQ", + "tEQQ", + "tNEQ", + "tGEQ", + "tLEQ", + "tANDOP", + "tOROP", + "tMATCH", + "tNMATCH", + "tDOT", + "tDOT2", + "tDOT3", + "tAREF", + "tASET", + "tLSHFT", + "tRSHFT", + "tCOLON2", + "tCOLON3", + "tOP_ASGN", + "tASSOC", + "tLPAREN", + "tLPAREN2", + "tRPAREN", + "tLPAREN_ARG", + "tLBRACK", + "tLBRACK2", + "tRBRACK", + "tLBRACE", + "tLBRACE_ARG", + "tSTAR", + "tSTAR2", + "tAMPER", + "tAMPER2", + "tTILDE", + "tPERCENT", + "tDIVIDE", + "tDSTAR", + "tPLUS", + "tMINUS", + "tLT", + "tGT", + "tPIPE", + "tBANG", + "tCARET", + "tLCURLY", + "tRCURLY", + "tBACK_REF2", + "tSYMBEG", + "tSTRING_BEG", + "tXSTRING_BEG", + "tREGEXP_BEG", + "tREGEXP_OPT", + "tWORDS_BEG", + "tQWORDS_BEG", + "tSYMBOLS_BEG", + "tQSYMBOLS_BEG", + "tSTRING_DBEG", + "tSTRING_DVAR", + "tSTRING_END", + "tSTRING_DEND", + "tSTRING", + "tSYMBOL", + "tNL", + "tEH", + "tCOLON", + "tCOMMA", + "tSPACE", + "tSEMI", + "tLAMBDA", + "tLAMBEG", + "tCHARACTER", + "tRATIONAL", + "tIMAGINARY", + "tLABEL_END", + "tANDDOT", + "tEQL", + "tLOWEST", + "$start", + "program", + "top_compstmt", + "top_stmts", + "opt_terms", + "top_stmt", + "terms", + "stmt", + "bodystmt", + "compstmt", + "opt_rescue", + "opt_else", + "opt_ensure", + "stmts", + "stmt_or_begin", + "fitem", + "undef_list", + "expr_value", + "command_asgn", + "mlhs", + "command_call", + "var_lhs", + "primary_value", + "opt_call_args", + "rbracket", + "call_op", + "backref", + "lhs", + "mrhs", + "mrhs_arg", + "expr", + "@1", + "opt_nl", + "arg", + "command", + "block_command", + "block_call", + "dot_or_colon", + "operation2", + "command_args", + "cmd_brace_block", + "opt_block_param", + "fcall", + "@2", + "operation", + "call_args", + "mlhs_basic", + "mlhs_inner", + "rparen", + "mlhs_head", + "mlhs_item", + "mlhs_node", + "mlhs_post", + "user_variable", + "keyword_variable", + "cname", + "cpath", + "fname", + "op", + "reswords", + "fsym", + "symbol", + "dsym", + "@3", + "simple_numeric", + "primary", + "arg_value", + "aref_args", + "none", + "args", + "trailer", + "assocs", + "paren_args", + "opt_paren_args", + "opt_block_arg", + "block_arg", + "@4", + "literal", + "strings", + "xstring", + "regexp", + "words", + "qwords", + "symbols", + "qsymbols", + "var_ref", + "assoc_list", + "brace_block", + "method_call", + "lambda", + "then", + "if_tail", + "do", + "case_body", + "for_var", + "k_class", + "superclass", + "term", + "k_module", + "f_arglist", + "singleton", + "@5", + "@6", + "@7", + "@8", + "@9", + "@10", + "@11", + "@12", + "@13", + "@14", + "@15", + "@16", + "@17", + "@18", + "@19", + "@20", + "@21", + "f_marg", + "f_norm_arg", + "f_margs", + "f_marg_list", + "block_args_tail", + "f_block_kwarg", + "f_kwrest", + "opt_f_block_arg", + "f_block_arg", + "opt_block_args_tail", + "block_param", + "f_arg", + "f_block_optarg", + "f_rest_arg", + "block_param_def", + "opt_bv_decl", + "bv_decls", + "bvar", + "f_bad_arg", + "f_larglist", + "lambda_body", + "@22", + "@23", + "f_args", + "do_block", + "@24", + "@25", + "@26", + "operation3", + "@27", + "@28", + "cases", + "exc_list", + "exc_var", + "numeric", + "string", + "string1", + "string_contents", + "xstring_contents", + "regexp_contents", + "word_list", + "word", + "string_content", + "symbol_list", + "qword_list", + "qsym_list", + "string_dvar", + "@29", + "@30", + "args_tail", + "@31", + "f_kwarg", + "opt_args_tail", + "f_optarg", + "f_arg_asgn", + "f_arg_item", + "f_label", + "f_kw", + "f_block_kw", + "kwrest_mark", + "f_opt", + "f_block_opt", + "restarg_mark", + "blkarg_mark", + "assoc" ] +Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) + +Racc_debug_parser = false + +##### State transition tables end ##### + +# reduce 0 omitted + +# reduce 1 omitted + +def _reduce_2(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_3(val, _values, result) + result = [] + + result +end + +def _reduce_4(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_5(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_6(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 7 omitted + +def _reduce_8(val, _values, result) + result = @builder.preexe(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_9(val, _values, result) + rescue_bodies = val[1] + else_t, else_ = val[2] + ensure_t, ensure_ = val[3] + + if rescue_bodies.empty? && !else_t.nil? + diagnostic :warning, :useless_else, nil, else_t + end + + result = @builder.begin_body(val[0], + rescue_bodies, + else_t, else_, + ensure_t, ensure_) + + result +end + +def _reduce_10(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_11(val, _values, result) + result = [] + + result +end + +def _reduce_12(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_13(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_14(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 15 omitted + +def _reduce_16(val, _values, result) + diagnostic :error, :begin_in_method, nil, val[0] + + result +end + +def _reduce_17(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_18(val, _values, result) + result = @builder.alias(val[0], val[1], val[3]) + + result +end + +def _reduce_19(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.gvar(val[2])) + + result +end + +def _reduce_20(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.back_ref(val[2])) + + result +end + +def _reduce_21(val, _values, result) + diagnostic :error, :nth_ref_alias, nil, val[2] + + result +end + +def _reduce_22(val, _values, result) + result = @builder.undef_method(val[0], val[1]) + + result +end + +def _reduce_23(val, _values, result) + result = @builder.condition_mod(val[0], nil, + val[1], val[2]) + + result +end + +def _reduce_24(val, _values, result) + result = @builder.condition_mod(nil, val[0], + val[1], val[2]) + + result +end + +def _reduce_25(val, _values, result) + result = @builder.loop_mod(:while, val[0], val[1], val[2]) + + result +end + +def _reduce_26(val, _values, result) + result = @builder.loop_mod(:until, val[0], val[1], val[2]) + + result +end + +def _reduce_27(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_28(val, _values, result) + result = @builder.postexe(val[0], val[1], val[2], val[3]) + + result +end + +# reduce 29 omitted + +def _reduce_30(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_31(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_32(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_33(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_34(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_35(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_36(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_37(val, _values, result) + @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_38(val, _values, result) + result = @builder.assign(val[0], val[1], + @builder.array(nil, val[2], nil)) + + result +end + +def _reduce_39(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +# reduce 40 omitted + +def _reduce_41(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_42(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +# reduce 43 omitted + +def _reduce_44(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_45(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_46(val, _values, result) + result = @builder.not_op(val[0], nil, val[2], nil) + + result +end + +def _reduce_47(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +# reduce 48 omitted + +# reduce 49 omitted + +# reduce 50 omitted + +# reduce 51 omitted + +# reduce 52 omitted + +def _reduce_53(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_54(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_55(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +# reduce 56 omitted + +def _reduce_57(val, _values, result) + result = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + result +end + +def _reduce_58(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + begin_t, args, body, end_t = val[2] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_59(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_60(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_61(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_62(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_63(val, _values, result) + result = @builder.keyword_cmd(:super, val[0], + nil, val[1], nil) + + result +end + +def _reduce_64(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], + nil, val[1], nil) + + result +end + +def _reduce_65(val, _values, result) + result = @builder.keyword_cmd(:return, val[0], + nil, val[1], nil) + + result +end + +def _reduce_66(val, _values, result) + result = @builder.keyword_cmd(:break, val[0], + nil, val[1], nil) + + result +end + +def _reduce_67(val, _values, result) + result = @builder.keyword_cmd(:next, val[0], + nil, val[1], nil) + + result +end + +def _reduce_68(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_69(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_70(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_71(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +# reduce 72 omitted + +def _reduce_73(val, _values, result) + result = val[0]. + push(val[1]) + + result +end + +def _reduce_74(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])) + + result +end + +def _reduce_75(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])). + concat(val[4]) + + result +end + +def _reduce_76(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])) + + result +end + +def _reduce_77(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])). + concat(val[3]) + + result +end + +def _reduce_78(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_79(val, _values, result) + result = [ @builder.splat(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_80(val, _values, result) + result = [ @builder.splat(val[0]) ] + + result +end + +def _reduce_81(val, _values, result) + result = [ @builder.splat(val[0]), + *val[2] ] + + result +end + +# reduce 82 omitted + +def _reduce_83(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_84(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_85(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_86(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_87(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_88(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_89(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_90(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_91(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_92(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_93(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_94(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_95(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_96(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_97(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_98(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_99(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_100(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_101(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_102(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_103(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_104(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_105(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_106(val, _values, result) + diagnostic :error, :module_name_const, nil, val[0] + + result +end + +# reduce 107 omitted + +def _reduce_108(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_109(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_110(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +# reduce 111 omitted + +# reduce 112 omitted + +# reduce 113 omitted + +# reduce 114 omitted + +# reduce 115 omitted + +def _reduce_116(val, _values, result) + result = @builder.symbol_internal(val[0]) + + result +end + +# reduce 117 omitted + +# reduce 118 omitted + +# reduce 119 omitted + +def _reduce_120(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_121(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_122(val, _values, result) + result = val[0] << val[3] + + result +end + +# reduce 123 omitted + +# reduce 124 omitted + +# reduce 125 omitted + +# reduce 126 omitted + +# reduce 127 omitted + +# reduce 128 omitted + +# reduce 129 omitted + +# reduce 130 omitted + +# reduce 131 omitted + +# reduce 132 omitted + +# reduce 133 omitted + +# reduce 134 omitted + +# reduce 135 omitted + +# reduce 136 omitted + +# reduce 137 omitted + +# reduce 138 omitted + +# reduce 139 omitted + +# reduce 140 omitted + +# reduce 141 omitted + +# reduce 142 omitted + +# reduce 143 omitted + +# reduce 144 omitted + +# reduce 145 omitted + +# reduce 146 omitted + +# reduce 147 omitted + +# reduce 148 omitted + +# reduce 149 omitted + +# reduce 150 omitted + +# reduce 151 omitted + +# reduce 152 omitted + +# reduce 153 omitted + +# reduce 154 omitted + +# reduce 155 omitted + +# reduce 156 omitted + +# reduce 157 omitted + +# reduce 158 omitted + +# reduce 159 omitted + +# reduce 160 omitted + +# reduce 161 omitted + +# reduce 162 omitted + +# reduce 163 omitted + +# reduce 164 omitted + +# reduce 165 omitted + +# reduce 166 omitted + +# reduce 167 omitted + +# reduce 168 omitted + +# reduce 169 omitted + +# reduce 170 omitted + +# reduce 171 omitted + +# reduce 172 omitted + +# reduce 173 omitted + +# reduce 174 omitted + +# reduce 175 omitted + +# reduce 176 omitted + +# reduce 177 omitted + +# reduce 178 omitted + +# reduce 179 omitted + +# reduce 180 omitted + +# reduce 181 omitted + +# reduce 182 omitted + +# reduce 183 omitted + +# reduce 184 omitted + +# reduce 185 omitted + +# reduce 186 omitted + +# reduce 187 omitted + +# reduce 188 omitted + +# reduce 189 omitted + +# reduce 190 omitted + +# reduce 191 omitted + +# reduce 192 omitted + +# reduce 193 omitted + +def _reduce_194(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_195(val, _values, result) + rescue_body = @builder.rescue_body(val[3], + nil, nil, nil, + nil, val[4]) + + rescue_ = @builder.begin_body(val[2], [ rescue_body ]) + + result = @builder.assign(val[0], val[1], rescue_) + + result +end + +def _reduce_196(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_197(val, _values, result) + rescue_body = @builder.rescue_body(val[3], + nil, nil, nil, + nil, val[4]) + + rescue_ = @builder.begin_body(val[2], [ rescue_body ]) + + result = @builder.op_assign(val[0], val[1], rescue_) + + result +end + +def _reduce_198(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_199(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_200(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_201(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_202(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_203(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_global(val[0], val[1])) + result = @builder.op_assign(const, val[2], val[3]) + + result +end + +def _reduce_204(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_205(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_206(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_207(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_208(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_209(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_210(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_211(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_212(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_213(val, _values, result) + result = @builder.unary_op(val[0], + @builder.binary_op( + val[1], val[2], val[3])) + + result +end + +def _reduce_214(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_215(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_216(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_217(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_218(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_219(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_220(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_221(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_222(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_223(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_224(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_225(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_226(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_227(val, _values, result) + result = @builder.match_op(val[0], val[1], val[2]) + + result +end + +def _reduce_228(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_229(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +def _reduce_230(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_231(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_232(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_233(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_234(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_235(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil) + + result +end + +def _reduce_236(val, _values, result) + result = @builder.ternary(val[0], val[1], + val[2], val[4], val[5]) + + result +end + +# reduce 237 omitted + +# reduce 238 omitted + +# reduce 239 omitted + +# reduce 240 omitted + +def _reduce_241(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_242(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +def _reduce_243(val, _values, result) + result = val + + result +end + +def _reduce_244(val, _values, result) + result = [ nil, [], nil ] + + result +end + +# reduce 245 omitted + +def _reduce_246(val, _values, result) + result = [] + + result +end + +# reduce 247 omitted + +# reduce 248 omitted + +def _reduce_249(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_250(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +def _reduce_251(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_252(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_253(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + result.concat(val[1]) + + result +end + +def _reduce_254(val, _values, result) + assocs = @builder.associate(nil, val[2], nil) + result = val[0] << assocs + result.concat(val[3]) + + result +end + +def _reduce_255(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_256(val, _values, result) + result = @lexer.cmdarg.dup + @lexer.cmdarg.push(true) + + result +end + +def _reduce_257(val, _values, result) + @lexer.cmdarg = val[0] + + result = val[1] + + result +end + +def _reduce_258(val, _values, result) + result = @builder.block_pass(val[0], val[1]) + + result +end + +def _reduce_259(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_260(val, _values, result) + result = [] + + result +end + +def _reduce_261(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_262(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_263(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_264(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_265(val, _values, result) + result = @builder.array(nil, val[0], nil) + + result +end + +# reduce 266 omitted + +def _reduce_267(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_268(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_269(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +# reduce 270 omitted + +# reduce 271 omitted + +# reduce 272 omitted + +# reduce 273 omitted + +# reduce 274 omitted + +# reduce 275 omitted + +# reduce 276 omitted + +# reduce 277 omitted + +# reduce 278 omitted + +# reduce 279 omitted + +def _reduce_280(val, _values, result) + result = @builder.call_method(nil, nil, val[0]) + + result +end + +def _reduce_281(val, _values, result) + result = @lexer.cmdarg.dup + @lexer.cmdarg.clear + + result +end + +def _reduce_282(val, _values, result) + @lexer.cmdarg = val[1] + + result = @builder.begin_keyword(val[0], val[2], val[3]) + + result +end + +def _reduce_283(val, _values, result) + result = @lexer.cmdarg.dup + @lexer.cmdarg.clear + + result +end + +def _reduce_284(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_285(val, _values, result) + @lexer.cmdarg = val[1] + + result = @builder.begin(val[0], val[2], val[5]) + + result +end + +def _reduce_286(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_287(val, _values, result) + result = @builder.begin(val[0], nil, val[3]) + + result +end + +def _reduce_288(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_289(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +def _reduce_290(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_291(val, _values, result) + result = @builder.array(val[0], val[1], val[2]) + + result +end + +def _reduce_292(val, _values, result) + result = @builder.associate(val[0], val[1], val[2]) + + result +end + +def _reduce_293(val, _values, result) + result = @builder.keyword_cmd(:return, val[0]) + + result +end + +def _reduce_294(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_295(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2]) + + result +end + +def _reduce_296(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0]) + + result +end + +def _reduce_297(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], + val[2], [ val[3] ], val[4]) + + result +end + +def _reduce_298(val, _values, result) + result = @builder.not_op(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_299(val, _values, result) + result = @builder.not_op(val[0], val[1], nil, val[2]) + + result +end + +def _reduce_300(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0]) + + begin_t, args, body, end_t = val[1] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +# reduce 301 omitted + +def _reduce_302(val, _values, result) + begin_t, args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, args, body, end_t) + + result +end + +def _reduce_303(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_304(val, _values, result) + lambda_call = @builder.call_lambda(val[0]) + + args, (begin_t, body, end_t) = val[2] + result = @builder.block(lambda_call, + begin_t, args, body, end_t) + + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_305(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, val[5]) + + result +end + +def _reduce_306(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + else_, else_t, + val[3], val[5]) + + result +end + +def _reduce_307(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_308(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_309(val, _values, result) + result = @builder.loop(:while, val[0], val[2], val[3], + val[5], val[6]) + + result +end + +def _reduce_310(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_311(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_312(val, _values, result) + result = @builder.loop(:until, val[0], val[2], val[3], + val[5], val[6]) + + result +end + +def _reduce_313(val, _values, result) + *when_bodies, (else_t, else_body) = *val[3] + + result = @builder.case(val[0], val[1], + when_bodies, else_t, else_body, + val[4]) + + result +end + +def _reduce_314(val, _values, result) + *when_bodies, (else_t, else_body) = *val[2] + + result = @builder.case(val[0], nil, + when_bodies, else_t, else_body, + val[3]) + + result +end + +def _reduce_315(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_316(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_317(val, _values, result) + result = @builder.for(val[0], val[1], + val[2], val[4], + val[5], val[7], val[8]) + + result +end + +def _reduce_318(val, _values, result) + local_push + @context.in_class = true + + result +end + +def _reduce_319(val, _values, result) + k_class, ctx = val[0] + if @context.in_def + diagnostic :error, :class_in_def, nil, k_class + end + + lt_t, superclass = val[2] + result = @builder.def_class(k_class, val[1], + lt_t, superclass, + val[4], val[5]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_320(val, _values, result) + @context.in_def = false + @context.in_class = false + local_push + + result +end + +def _reduce_321(val, _values, result) + k_class, ctx = val[0] + result = @builder.def_sclass(k_class, val[1], val[2], + val[5], val[6]) + + local_pop + @context.in_def = ctx.in_def + @context.in_class = ctx.in_class + + result +end + +def _reduce_322(val, _values, result) + @context.in_class = true + local_push + + result +end + +def _reduce_323(val, _values, result) + k_mod, ctx = val[0] + if @context.in_def + diagnostic :error, :module_in_def, nil, k_mod + end + + result = @builder.def_module(k_mod, val[1], + val[3], val[4]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_324(val, _values, result) + local_push + result = context.dup + @context.in_def = true + + result +end + +def _reduce_325(val, _values, result) + result = @builder.def_method(val[0], val[1], + val[3], val[4], val[5]) + + local_pop + @context.in_def = val[2].in_def + + result +end + +def _reduce_326(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_327(val, _values, result) + local_push + result = context.dup + @context.in_def = true + + result +end + +def _reduce_328(val, _values, result) + result = @builder.def_singleton(val[0], val[1], val[2], + val[4], val[6], val[7], val[8]) + + local_pop + @context.in_def = val[5].in_def + + result +end + +def _reduce_329(val, _values, result) + result = @builder.keyword_cmd(:break, val[0]) + + result +end + +def _reduce_330(val, _values, result) + result = @builder.keyword_cmd(:next, val[0]) + + result +end + +def _reduce_331(val, _values, result) + result = @builder.keyword_cmd(:redo, val[0]) + + result +end + +def _reduce_332(val, _values, result) + result = @builder.keyword_cmd(:retry, val[0]) + + result +end + +# reduce 333 omitted + +def _reduce_334(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_335(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +# reduce 336 omitted + +# reduce 337 omitted + +def _reduce_338(val, _values, result) + result = val[1] + + result +end + +# reduce 339 omitted + +# reduce 340 omitted + +# reduce 341 omitted + +def _reduce_342(val, _values, result) + else_t, else_ = val[4] + result = [ val[0], + @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, nil), + ] + + result +end + +# reduce 343 omitted + +def _reduce_344(val, _values, result) + result = val + + result +end + +# reduce 345 omitted + +# reduce 346 omitted + +def _reduce_347(val, _values, result) + result = @builder.arg(val[0]) + + result +end + +def _reduce_348(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_349(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_350(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 351 omitted + +def _reduce_352(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2], val[3])) + + result +end + +def _reduce_353(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2], val[3])). + concat(val[5]) + + result +end + +def _reduce_354(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2])) + + result +end + +def _reduce_355(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2])). + concat(val[4]) + + result +end + +def _reduce_356(val, _values, result) + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_357(val, _values, result) + result = [ @builder.restarg(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_358(val, _values, result) + result = [ @builder.restarg(val[0]) ] + + result +end + +def _reduce_359(val, _values, result) + result = [ @builder.restarg(val[0]), + *val[2] ] + + result +end + +def _reduce_360(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_361(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_362(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_363(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_364(val, _values, result) + result = val[1] + + result +end + +def _reduce_365(val, _values, result) + result = [] + + result +end + +def _reduce_366(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_367(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_368(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_369(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_370(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 371 omitted + +def _reduce_372(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_373(val, _values, result) + if val[1].empty? && val[0].size == 1 + result = [@builder.procarg0(val[0][0])] + else + result = val[0].concat(val[1]) + end + + result +end + +def _reduce_374(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_375(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_376(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_377(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_378(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_379(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 380 omitted + +def _reduce_381(val, _values, result) + result = @builder.args(nil, [], nil) + + result +end + +def _reduce_382(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_383(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + result +end + +def _reduce_384(val, _values, result) + result = @builder.args(val[0], [], val[0]) + + result +end + +def _reduce_385(val, _values, result) + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_386(val, _values, result) + result = [] + + result +end + +def _reduce_387(val, _values, result) + result = val[2] + + result +end + +def _reduce_388(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_389(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_390(val, _values, result) + @static_env.declare val[0][0] + result = @builder.shadowarg(val[0]) + + result +end + +# reduce 391 omitted + +def _reduce_392(val, _values, result) + @static_env.extend_dynamic + + result +end + +def _reduce_393(val, _values, result) + result = @lexer.cmdarg.dup + @lexer.cmdarg.clear + + result +end + +def _reduce_394(val, _values, result) + @lexer.cmdarg = val[2] + @lexer.cmdarg.lexpop + + result = [ val[1], val[3] ] + + @static_env.unextend + + result +end + +def _reduce_395(val, _values, result) + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_396(val, _values, result) + result = @builder.args(nil, val[0], nil) + + result +end + +def _reduce_397(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_398(val, _values, result) + result = [ val[0], val[2], val[3] ] + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_399(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_400(val, _values, result) + result = [ val[0], val[2], val[3] ] + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_401(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_402(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_403(val, _values, result) + begin_t, block_args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, block_args, body, end_t) + + result +end + +def _reduce_404(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_405(val, _values, result) + lparen_t, args, rparen_t = val[3] + method_call = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_406(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_407(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.call_method(nil, nil, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_408(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_409(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_410(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2]) + + result +end + +def _reduce_411(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_412(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_413(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.keyword_cmd(:super, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_414(val, _values, result) + result = @builder.keyword_cmd(:zsuper, val[0]) + + result +end + +def _reduce_415(val, _values, result) + result = @builder.index(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_416(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_417(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_418(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_419(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_420(val, _values, result) + result = [ @builder.when(val[0], val[1], val[2], val[3]), + *val[4] ] + + result +end + +def _reduce_421(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 422 omitted + +def _reduce_423(val, _values, result) + assoc_t, exc_var = val[2] + + if val[1] + exc_list = @builder.array(nil, val[1], nil) + end + + result = [ @builder.rescue_body(val[0], + exc_list, assoc_t, exc_var, + val[3], val[4]), + *val[5] ] + + result +end + +def _reduce_424(val, _values, result) + result = [] + + result +end + +def _reduce_425(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 426 omitted + +# reduce 427 omitted + +def _reduce_428(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 429 omitted + +def _reduce_430(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 431 omitted + +# reduce 432 omitted + +# reduce 433 omitted + +# reduce 434 omitted + +def _reduce_435(val, _values, result) + result = @builder.string_compose(nil, val[0], nil) + + result +end + +def _reduce_436(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_437(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_438(val, _values, result) + string = @builder.string_compose(val[0], val[1], val[2]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_439(val, _values, result) + string = @builder.string(val[0]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_440(val, _values, result) + result = @builder.character(val[0]) + + result +end + +def _reduce_441(val, _values, result) + string = @builder.xstring_compose(val[0], val[1], val[2]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_442(val, _values, result) + opts = @builder.regexp_options(val[3]) + result = @builder.regexp_compose(val[0], val[1], val[2], opts) + + result +end + +def _reduce_443(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_444(val, _values, result) + result = [] + + result +end + +def _reduce_445(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_446(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_447(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_448(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_449(val, _values, result) + result = [] + + result +end + +def _reduce_450(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_451(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_452(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_453(val, _values, result) + result = [] + + result +end + +def _reduce_454(val, _values, result) + result = val[0] << @builder.string_internal(val[1]) + + result +end + +def _reduce_455(val, _values, result) + result = [] + + result +end + +def _reduce_456(val, _values, result) + result = val[0] << @builder.symbol_internal(val[1]) + + result +end + +def _reduce_457(val, _values, result) + result = [] + + result +end + +def _reduce_458(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_459(val, _values, result) + result = [] + + result +end + +def _reduce_460(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_461(val, _values, result) + result = [] + + result +end + +def _reduce_462(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_463(val, _values, result) + result = @builder.string_internal(val[0]) + + result +end + +def _reduce_464(val, _values, result) + result = val[1] + + result +end + +def _reduce_465(val, _values, result) + @lexer.cond.push(false) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_466(val, _values, result) + @lexer.cond.lexpop + @lexer.cmdarg.lexpop + + result = @builder.begin(val[0], val[2], val[3]) + + result +end + +def _reduce_467(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_468(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_469(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +# reduce 470 omitted + +def _reduce_471(val, _values, result) + result = @builder.symbol(val[0]) + + result +end + +def _reduce_472(val, _values, result) + result = @builder.symbol_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_473(val, _values, result) + result = val[0] + + result +end + +def _reduce_474(val, _values, result) + if @builder.respond_to? :negate + # AST builder interface compatibility + result = @builder.negate(val[0], val[1]) + else + result = @builder.unary_num(val[0], val[1]) + end + + result +end + +def _reduce_475(val, _values, result) + result = @builder.integer(val[0]) + + result +end + +def _reduce_476(val, _values, result) + result = @builder.float(val[0]) + + result +end + +def _reduce_477(val, _values, result) + result = @builder.rational(val[0]) + + result +end + +def _reduce_478(val, _values, result) + result = @builder.complex(val[0]) + + result +end + +def _reduce_479(val, _values, result) + result = @builder.ident(val[0]) + + result +end + +def _reduce_480(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_481(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_482(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_483(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +def _reduce_484(val, _values, result) + result = @builder.nil(val[0]) + + result +end + +def _reduce_485(val, _values, result) + result = @builder.self(val[0]) + + result +end + +def _reduce_486(val, _values, result) + result = @builder.true(val[0]) + + result +end + +def _reduce_487(val, _values, result) + result = @builder.false(val[0]) + + result +end + +def _reduce_488(val, _values, result) + result = @builder.__FILE__(val[0]) + + result +end + +def _reduce_489(val, _values, result) + result = @builder.__LINE__(val[0]) + + result +end + +def _reduce_490(val, _values, result) + result = @builder.__ENCODING__(val[0]) + + result +end + +def _reduce_491(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_492(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_493(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_494(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_495(val, _values, result) + result = @builder.nth_ref(val[0]) + + result +end + +def _reduce_496(val, _values, result) + result = @builder.back_ref(val[0]) + + result +end + +def _reduce_497(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_498(val, _values, result) + result = [ val[0], val[2] ] + + result +end + +def _reduce_499(val, _values, result) + result = nil + + result +end + +def _reduce_500(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + @lexer.state = :expr_value + + result +end + +def _reduce_501(val, _values, result) + result = @context.in_kwarg + @context.in_kwarg = true + + result +end + +def _reduce_502(val, _values, result) + @context.in_kwarg = val[0] + result = @builder.args(nil, val[1], nil) + + result +end + +def _reduce_503(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_504(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_505(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_506(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_507(val, _values, result) + result = val[1] + + result +end + +def _reduce_508(val, _values, result) + result = [] + + result +end + +def _reduce_509(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_510(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_511(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_512(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_513(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_514(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_515(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_516(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_517(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_518(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_519(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_520(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_521(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_522(val, _values, result) + result = val[0] + + result +end + +def _reduce_523(val, _values, result) + result = [] + + result +end + +def _reduce_524(val, _values, result) + diagnostic :error, :argument_const, nil, val[0] + + result +end + +def _reduce_525(val, _values, result) + diagnostic :error, :argument_ivar, nil, val[0] + + result +end + +def _reduce_526(val, _values, result) + diagnostic :error, :argument_gvar, nil, val[0] + + result +end + +def _reduce_527(val, _values, result) + diagnostic :error, :argument_cvar, nil, val[0] + + result +end + +# reduce 528 omitted + +def _reduce_529(val, _values, result) + @static_env.declare val[0][0] + + result = val[0] + + result +end + +def _reduce_530(val, _values, result) + result = val[0] + + result +end + +def _reduce_531(val, _values, result) + result = @builder.arg(val[0]) + + result +end + +def _reduce_532(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_533(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_534(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_535(val, _values, result) + check_kwarg_name(val[0]) + + @static_env.declare val[0][0] + + result = val[0] + + result +end + +def _reduce_536(val, _values, result) + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_537(val, _values, result) + result = @builder.kwarg(val[0]) + + result +end + +def _reduce_538(val, _values, result) + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_539(val, _values, result) + result = @builder.kwarg(val[0]) + + result +end + +def _reduce_540(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_541(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_542(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_543(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 544 omitted + +# reduce 545 omitted + +def _reduce_546(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.kwrestarg(val[0], val[1]) ] + + result +end + +def _reduce_547(val, _values, result) + result = [ @builder.kwrestarg(val[0]) ] + + result +end + +def _reduce_548(val, _values, result) + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_549(val, _values, result) + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_550(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_551(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_552(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_553(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 554 omitted + +# reduce 555 omitted + +def _reduce_556(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_557(val, _values, result) + result = [ @builder.restarg(val[0]) ] + + result +end + +# reduce 558 omitted + +# reduce 559 omitted + +def _reduce_560(val, _values, result) + @static_env.declare val[1][0] + + result = @builder.blockarg(val[0], val[1]) + + result +end + +def _reduce_561(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_562(val, _values, result) + result = [] + + result +end + +# reduce 563 omitted + +def _reduce_564(val, _values, result) + result = val[1] + + result +end + +def _reduce_565(val, _values, result) + result = [] + + result +end + +# reduce 566 omitted + +def _reduce_567(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_568(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_569(val, _values, result) + result = @builder.pair(val[0], val[1], val[2]) + + result +end + +def _reduce_570(val, _values, result) + result = @builder.pair_keyword(val[0], val[1]) + + result +end + +def _reduce_571(val, _values, result) + result = @builder.pair_quoted(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_572(val, _values, result) + result = @builder.kwsplat(val[0], val[1]) + + result +end + +# reduce 573 omitted + +# reduce 574 omitted + +# reduce 575 omitted + +# reduce 576 omitted + +# reduce 577 omitted + +# reduce 578 omitted + +# reduce 579 omitted + +# reduce 580 omitted + +# reduce 581 omitted + +# reduce 582 omitted + +# reduce 583 omitted + +# reduce 584 omitted + +def _reduce_585(val, _values, result) + result = [:dot, val[0][1]] + + result +end + +def _reduce_586(val, _values, result) + result = [:anddot, val[0][1]] + + result +end + +# reduce 587 omitted + +# reduce 588 omitted + +# reduce 589 omitted + +# reduce 590 omitted + +def _reduce_591(val, _values, result) + result = val[1] + + result +end + +def _reduce_592(val, _values, result) + result = val[1] + + result +end + +# reduce 593 omitted + +# reduce 594 omitted + +# reduce 595 omitted + +def _reduce_596(val, _values, result) + yyerrok + + result +end + +# reduce 597 omitted + +# reduce 598 omitted + +# reduce 599 omitted + +def _reduce_600(val, _values, result) + result = nil + + result +end + +def _reduce_none(val, _values, result) + val[0] +end + + end # class Ruby23 +end # module Parser diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby24.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby24.rb new file mode 100644 index 00000000..87fa8f3b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby24.rb @@ -0,0 +1,10454 @@ +# -*- encoding:utf-8; warn-indent:false; frozen_string_literal: true -*- +# +# DO NOT MODIFY!!!! +# This file is automatically generated by Racc 1.8.1 +# from Racc grammar file "ruby24.y". +# + +require 'racc/parser.rb' + + +require_relative '../parser' + +module Parser + class Ruby24 < Parser::Base + + + def version + 24 + end + + def default_encoding + Encoding::UTF_8 + end + + def local_push + @static_env.extend_static + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + end + + def local_pop + @static_env.unextend + @lexer.cmdarg.pop + @lexer.cond.pop + end +##### State transition tables begin ### + +racc_action_table = [ + -485, 211, 212, 211, 212, 219, -99, -485, -485, -485, + 111, 545, -485, -485, -485, 217, -485, 272, 221, 585, + 774, 774, 265, 545, -485, 587, -485, -485, -485, 272, + 557, 272, -499, 123, 558, -100, -485, -485, 545, -485, + -485, -485, -485, -485, 545, 545, -99, -100, -107, -107, + -85, -106, -98, 208, -106, 773, 773, 209, 272, 222, + -71, 535, -107, 210, 534, -102, -485, -485, -485, -485, + -485, -485, -485, -485, -485, -485, -485, -485, -485, -485, + 218, 267, -485, -485, -485, 584, -485, -485, 701, -99, + -485, 586, -104, -485, -485, 222, -485, 222, -485, 787, + -485, 551, -485, -485, 271, -485, -485, -485, -485, -485, + -102, -485, -488, -485, -104, -90, 271, 870, 271, -488, + -488, -488, 267, -103, -488, -488, -488, -485, -488, 115, + -485, -485, -485, -485, 114, -485, -488, -485, -488, -488, + -488, 115, -485, -485, -91, 271, 114, -93, -488, -488, + -105, -488, -488, -488, -488, -488, 115, -101, -98, 823, + -97, 114, 115, 115, -99, -100, -107, 114, 114, -99, + -100, -107, -106, 701, -93, -103, -101, -106, -488, -488, + -488, -488, -488, -488, -488, -488, -488, -488, -488, -488, + -488, -488, 115, 213, -488, -488, -488, 114, -488, -488, + -582, -95, -488, 261, -95, -488, -488, 701, -488, -105, + -488, 115, -488, -93, -488, -488, 114, -488, -488, -488, + -488, -488, -290, -488, -500, -488, 869, -583, -102, -290, + -290, -290, -104, -102, 320, -290, -290, -104, -290, -488, + -582, -103, -488, -488, -488, -488, -103, -488, 321, -488, + 211, 212, 452, -93, -488, -488, -93, 81, -290, -290, + -92, -290, -290, -290, -290, -290, -93, 222, -105, 82, + -95, -485, -94, -105, -583, -101, 389, 115, -485, 83, + -101, -100, 114, 219, -94, -92, 211, 212, -290, -290, + -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, + -290, -290, 402, 523, -290, -290, -290, -488, 610, -107, + -95, 115, -290, -95, -488, -290, 114, 451, -96, 453, + -290, 454, -290, -95, -290, -290, -92, -290, -290, -290, + -290, -290, 572, -290, -586, -290, -485, -582, -94, 221, + -107, -586, -586, -586, 222, 485, 115, -586, -586, -290, + -586, 114, -290, -290, 494, -96, 399, -290, 115, -586, + -106, 401, 400, 114, -290, -105, -92, -579, -499, -92, + -586, -586, -488, -586, -586, -586, -586, -586, -94, -92, + 115, -94, 211, 212, 496, 114, 678, 760, 675, 674, + 673, -94, 676, 93, 94, 498, 574, 573, 570, 506, + -586, -586, -586, -586, -586, -586, -586, -586, -586, -586, + -586, -586, -586, -586, -70, -90, -586, -586, -586, -485, + 611, 93, 94, 572, -586, -99, -485, -586, 115, 761, + 222, -579, -586, 114, -586, -485, -586, -586, -500, -586, + -586, -586, -586, -586, -102, -586, -586, -586, 572, 678, + 572, 675, 674, 673, -579, 676, -495, 115, 509, -580, + 605, -586, 114, -495, -586, -586, -586, -94, 888, -586, + 510, 95, 96, -586, -586, -586, -586, -103, -586, -586, + -586, 517, -586, 276, -485, -91, -104, 574, 573, 570, + -494, -586, -586, -586, -586, -100, 222, -494, 535, 95, + 96, 537, -586, -586, 638, -586, -586, -586, -586, -586, + 267, -488, 574, 573, 574, 573, 572, -102, -488, 572, + 520, -495, 732, -580, 734, 572, 524, -488, 242, 606, + 222, 986, -586, -586, -586, -586, -586, -586, -586, -586, + -586, -586, -586, -586, -586, -586, -580, 538, -586, -586, + -586, 535, 762, -586, 537, -494, -586, 572, 523, -586, + -586, 572, -586, -496, -586, 539, -586, 605, -586, -586, + -496, -586, -586, -586, -586, -586, -488, -586, -586, -586, + 574, 573, 575, 574, 573, 577, -104, -493, 498, 574, + 573, 579, 606, -586, -493, 551, -586, -586, -586, -586, + -490, -586, 391, -586, -290, -97, 842, -490, -586, -103, + 555, -290, -290, -290, -93, -106, -290, -290, -290, 556, + -290, 574, 573, 583, -102, 574, 573, 588, -496, 564, + -290, -290, -290, 535, 222, 747, 537, 1003, 747, -95, + -290, -290, 589, -290, -290, -290, -290, -290, 592, -104, + -263, 217, -493, -334, -491, -492, 211, 212, 216, 217, + -334, -491, -492, -101, 594, -490, 265, 214, 595, -334, + -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, + -290, -290, -290, -290, 599, -92, -290, -290, -290, 222, + 763, -290, -101, 603, -290, -101, 604, -290, -290, 267, + -290, 615, -290, 242, -290, 242, -290, -290, 242, -290, + -290, -290, -290, -290, -290, -290, 218, -290, -334, -491, + -492, -290, -290, -290, 218, 818, 787, -290, -290, 242, + -290, -290, 242, 242, -290, -290, -290, -290, 222, -290, + 239, -290, -586, 222, 241, 240, -290, -105, 256, 257, + -290, -290, 222, -290, -290, -290, -290, -290, -85, 217, + 694, 693, 642, -497, 239, 222, 449, 528, 241, 240, + -497, 237, 238, 818, 787, 450, 653, 658, 659, -497, + -290, -290, -290, -290, -290, -290, -290, -290, -290, -290, + -290, -290, -290, -290, -586, -498, -290, -290, -290, 222, + 610, -586, -498, 661, -290, 697, -582, -290, 551, 704, + -586, -498, -290, 721, -290, 731, -290, -290, 735, -290, + -290, -290, -290, -290, 218, -290, -586, -290, -497, -586, + 736, -264, 748, -586, -586, -586, 683, 485, 242, -586, + -586, -290, -586, 485, -290, -290, 686, -290, 217, -290, + 222, -586, 765, 766, 261, 516, -290, -105, 771, -586, + -498, 776, -586, -586, 514, -586, -586, -586, -586, -586, + 239, -281, 496, 498, 241, 240, 780, 653, -281, 694, + 693, 222, 267, 267, 687, 726, 727, -281, 653, 728, + 109, 110, -586, -586, -586, -586, -586, -586, -586, -586, + -586, -586, -586, -586, -586, -586, 242, 787, -586, -586, + -586, 217, 611, 218, 217, 795, -586, 798, 526, -586, + 799, 554, 801, 803, -586, 805, -586, 450, -586, -586, + 552, -586, -586, -586, -586, -586, -281, -586, -586, -586, + 678, 813, 675, 674, 673, 683, 676, 217, 118, 119, + 120, 121, 122, -586, 560, 686, -586, -586, -415, -586, + 814, -586, 815, 562, 787, -415, -415, -415, -586, -103, + -415, -415, -415, 822, -415, 222, 218, 681, 222, 218, + 831, 242, -265, -415, -415, -415, 691, 690, 694, 693, + 222, 841, 845, 687, -415, -415, 653, -415, -415, -415, + -415, -415, 678, 862, 675, 674, 673, 217, 676, -263, + 866, 222, 218, 239, 598, 886, 222, 241, 240, 222, + 237, 238, 890, 596, -415, -415, -415, -415, -415, -415, + -415, -415, -415, -415, -415, -415, -415, -415, 892, 807, + -415, -415, -415, 898, 901, -415, 222, 267, -415, 905, + -266, -415, -415, 907, -415, 798, -415, 910, -415, 912, + -415, -415, 914, -415, -415, -415, -415, -415, -297, -415, + -415, -415, 218, 916, 222, -297, -297, -297, 918, 919, + -297, -297, -297, -291, -297, -415, 932, 798, -415, -415, + -291, -415, 934, -415, -297, -297, 936, 938, 940, -291, + -415, 940, 222, 946, -297, -297, 949, -297, -297, -297, + -297, -297, 950, 955, 721, -291, 966, -290, 973, 978, + 988, 798, -291, 993, -290, 995, 997, 999, 999, -583, + 658, -291, 1012, -290, -297, -297, -297, -297, -297, -297, + -297, -297, -297, -297, -297, -297, -297, -297, -291, 1013, + -297, -297, -297, 1014, 940, -297, 940, 276, -297, 940, + 1019, -297, -297, 988, -297, 1022, -297, 1023, -297, -583, + -297, -297, -582, -297, -297, -297, -297, -297, -282, -297, + -291, -297, -290, 222, 988, -282, -282, -282, 1032, 999, + -282, -282, -282, 217, -282, -297, 999, 999, -297, -297, + 972, -297, 940, -297, -282, -282, -282, 988, 999, 562, + -297, nil, nil, nil, -282, -282, nil, -282, -282, -282, + -282, -282, nil, -290, nil, 217, nil, 217, nil, nil, + -290, nil, 977, nil, 972, -583, nil, nil, nil, -290, + nil, 975, nil, 562, -282, -282, -282, -282, -282, -282, + -282, -282, -282, -282, -282, -282, -282, -282, 218, 683, + -282, -282, -282, nil, nil, -282, nil, nil, -282, 686, + nil, -282, -282, nil, -282, nil, -282, nil, -282, nil, + -282, -282, nil, -282, -282, -282, -282, -282, -290, -282, + 218, -282, 218, 969, nil, 675, 674, 673, nil, 676, + nil, nil, 694, 693, nil, -282, 242, 687, -282, -282, + -282, -282, nil, -282, -246, -282, nil, nil, nil, nil, + -282, -246, -246, -246, nil, nil, -246, -246, -246, 678, + -246, 675, 674, 673, nil, 676, nil, nil, 239, -246, + -246, -246, 241, 240, nil, 237, 238, nil, nil, nil, + -246, -246, nil, -246, -246, -246, -246, -246, 678, nil, + 675, 674, 673, nil, 676, 678, 807, 675, 674, 673, + 969, 676, 675, 674, 673, 810, 676, nil, nil, nil, + -246, -246, -246, -246, -246, -246, -246, -246, -246, -246, + -246, -246, -246, -246, nil, 807, -246, -246, -246, nil, + nil, -246, 807, 267, -246, nil, nil, -246, -246, nil, + -246, 810, -246, nil, -246, nil, -246, -246, nil, -246, + -246, -246, -246, -246, nil, -246, -246, -246, 678, nil, + 675, 674, 673, 683, 676, 118, 119, 120, 121, 122, + nil, -246, nil, 686, -246, -246, -587, -246, nil, -246, + nil, nil, nil, -587, -587, -587, -246, nil, -587, -587, + -587, nil, -587, 242, 678, 681, 675, 674, 673, nil, + 676, -587, -587, -587, -587, nil, 694, 693, nil, 256, + 257, 687, -587, -587, nil, -587, -587, -587, -587, -587, + 678, nil, 675, 674, 673, 239, 676, 245, nil, 241, + 240, 807, 237, 238, nil, nil, 243, nil, 244, nil, + 945, nil, -587, -587, -587, -587, -587, -587, -587, -587, + -587, -587, -587, -587, -587, -587, nil, 807, -587, -587, + -587, nil, nil, -587, nil, nil, -587, nil, nil, -587, + -587, nil, -587, nil, -587, nil, -587, nil, -587, -587, + nil, -587, -587, -587, -587, -587, nil, -587, -587, -587, + nil, nil, 678, nil, 675, 674, 673, nil, 676, nil, + nil, nil, nil, -587, nil, nil, -587, -587, -587, -587, + nil, -587, -588, -587, nil, nil, nil, nil, -587, -588, + -588, -588, nil, nil, -588, -588, -588, 242, -588, 807, + 118, 119, 120, 121, 122, nil, nil, -588, -588, -588, + -588, nil, nil, 256, 257, nil, nil, nil, -588, -588, + nil, -588, -588, -588, -588, -588, nil, nil, nil, 239, + nil, 245, nil, 241, 240, nil, 237, 238, nil, nil, + 243, nil, 244, 118, 119, 120, 121, 122, -588, -588, + -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, + -588, -588, nil, nil, -588, -588, -588, nil, nil, -588, + nil, nil, -588, nil, nil, -588, -588, nil, -588, nil, + -588, nil, -588, nil, -588, -588, nil, -588, -588, -588, + -588, -588, nil, -588, -588, -588, nil, nil, 678, nil, + 675, 674, 673, nil, 676, nil, nil, nil, nil, -588, + nil, nil, -588, -588, -588, -588, nil, -588, -246, -588, + nil, nil, nil, nil, -588, -246, -246, -246, nil, nil, + -246, -246, -246, 242, -246, 807, nil, nil, nil, nil, + nil, nil, nil, -246, -246, nil, nil, nil, nil, 256, + 257, nil, nil, nil, -246, -246, nil, -246, -246, -246, + -246, -246, nil, nil, nil, 239, nil, 245, nil, 241, + 240, nil, 237, 238, nil, nil, nil, 242, 246, 251, + 252, 253, 248, 250, 258, 259, 254, 255, nil, 235, + 236, nil, nil, 256, 257, -246, nil, nil, nil, nil, + nil, nil, -246, nil, nil, nil, nil, 267, -246, 239, + nil, 245, nil, 241, 240, nil, 237, 238, 249, 247, + 243, nil, 244, nil, nil, nil, nil, nil, nil, nil, + -246, -246, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 260, nil, nil, -246, nil, nil, -246, nil, + nil, nil, nil, -246, 5, 74, 75, 71, 9, 57, + -246, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, 600, 8, 45, 7, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, 242, + 246, 251, 252, 253, 248, 250, 258, 259, 254, 255, + nil, 235, 236, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, 239, nil, 245, 44, 241, 240, nil, 237, 238, + 249, 247, 243, 20, 244, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, 260, nil, -238, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, 600, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, 242, + 246, 251, 252, 253, 248, 250, 258, 259, 254, 255, + nil, 235, 236, nil, nil, 256, 257, nil, 40, nil, + nil, 298, nil, nil, 58, 59, nil, nil, 60, nil, + 35, 239, nil, 245, 44, 241, 240, nil, 237, 238, + 249, 247, 243, 20, 244, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, 260, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 5, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 7, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, 242, + 246, 251, 252, 253, 248, 250, 258, 259, 254, 255, + nil, 235, 236, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, 239, nil, 245, 44, 241, 240, nil, 237, 238, + 249, 247, 243, 20, 244, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, 260, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, 242, + 246, 251, 252, 253, 248, 250, 258, 259, 254, 255, + nil, 235, 236, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, 239, nil, 245, 44, 241, 240, nil, 237, 238, + 249, 247, 243, 20, 244, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, 222, 260, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, 242, + 246, 251, 252, 253, 248, 250, 258, 259, 254, 255, + nil, 235, 236, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, 239, nil, 245, 44, 241, 240, nil, 237, 238, + 249, 247, 243, 20, 244, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, 260, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, 242, + 246, 251, 252, 253, 248, 250, 258, 259, 254, 255, + nil, 235, 236, nil, nil, 256, 257, nil, 40, nil, + nil, 298, nil, nil, 58, 59, nil, nil, 60, nil, + 35, 239, nil, 245, 44, 241, 240, nil, 237, 238, + 249, 247, 243, 20, 244, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, 260, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, 242, + 246, 251, 252, 253, 248, 250, 258, 259, 254, 255, + nil, 235, 236, nil, nil, 256, 257, nil, 40, nil, + nil, 298, nil, nil, 58, 59, nil, nil, 60, nil, + 35, 239, nil, 245, 44, 241, 240, nil, 237, 238, + 249, 247, 243, 20, 244, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, 260, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, 242, + 246, 251, 252, 253, 248, 250, 258, 259, 254, 255, + nil, -607, -607, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, 239, nil, 245, 44, 241, 240, nil, 237, 238, + 249, 247, 243, 20, 244, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 5, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 7, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, 242, + 246, 251, 252, 253, 248, 250, 258, 259, 254, 255, + nil, -607, -607, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, 239, nil, 245, 44, 241, 240, nil, 237, 238, + 249, 247, 243, 20, 244, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, 242, + -607, -607, -607, -607, 248, 250, nil, nil, -607, -607, + nil, nil, nil, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, 239, nil, 245, 44, 241, 240, nil, 237, 238, + 249, 247, 243, 20, 244, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, 242, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, 239, nil, 245, 44, 241, 240, nil, 237, 238, + nil, nil, 243, 20, 244, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, 242, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, 239, nil, 245, 44, 241, 240, nil, 237, 238, + nil, nil, 243, 20, 244, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, 242, + -607, -607, -607, -607, 248, 250, nil, nil, -607, -607, + nil, nil, nil, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, 239, nil, 245, 44, 241, 240, nil, 237, 238, + 249, 247, 243, 20, 244, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, 242, + -607, -607, -607, -607, 248, 250, nil, nil, -607, -607, + nil, nil, nil, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, 239, nil, 245, 44, 241, 240, nil, 237, 238, + 249, 247, 243, 20, 244, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, 242, + -607, -607, -607, -607, 248, 250, nil, nil, -607, -607, + nil, nil, nil, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, 239, nil, 245, 44, 241, 240, nil, 237, 238, + 249, 247, 243, 20, 244, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, 242, + -607, -607, -607, -607, 248, 250, nil, nil, -607, -607, + nil, nil, nil, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, 239, nil, 245, 44, 241, 240, nil, 237, 238, + 249, 247, 243, 20, 244, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, 242, + -607, -607, -607, -607, 248, 250, nil, nil, -607, -607, + nil, nil, nil, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, 239, nil, 245, 44, 241, 240, nil, 237, 238, + 249, 247, 243, 20, 244, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, 242, + 246, 251, 252, 253, 248, 250, nil, nil, 254, 255, + nil, nil, nil, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, 239, nil, 245, 44, 241, 240, nil, 237, 238, + 249, 247, 243, 20, 244, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, 242, + 246, 251, 252, 253, 248, 250, 258, nil, 254, 255, + nil, nil, nil, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, 239, nil, 245, 44, 241, 240, nil, 237, 238, + 249, 247, 243, 20, 244, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, 242, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, 239, nil, 245, 44, 241, 240, nil, 237, 238, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 294, 74, 75, 71, 9, 57, + nil, nil, nil, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 296, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, nil, nil, nil, 62, + nil, 83, 95, 96, 74, 75, 71, 9, 57, nil, + nil, nil, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 30, 31, 72, 73, nil, nil, nil, nil, + nil, 29, 28, 27, 103, 102, 104, 105, nil, nil, + 19, nil, nil, nil, nil, nil, 8, 45, 7, 10, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 40, nil, nil, + 33, nil, nil, 58, 59, nil, nil, 60, nil, 35, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 234, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 233, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 232, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 234, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + 288, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 233, nil, nil, 58, 59, nil, nil, 60, + nil, 285, nil, 283, nil, 44, nil, nil, 289, nil, + nil, nil, nil, nil, 232, nil, nil, nil, nil, 91, + 286, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 103, 102, 104, + 105, nil, nil, 234, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, 288, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, 233, nil, nil, 58, 59, nil, nil, + 60, nil, 285, nil, 283, nil, 44, nil, nil, 289, + nil, nil, nil, nil, nil, 232, nil, nil, nil, nil, + 91, 286, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 103, 102, + 104, 105, nil, nil, 234, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, 288, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, 233, nil, nil, 58, 59, nil, + nil, 60, nil, 285, nil, 283, nil, 44, nil, nil, + 289, nil, nil, nil, nil, nil, 232, nil, nil, nil, + nil, 91, 286, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 313, 314, 72, + 73, nil, nil, nil, nil, nil, 309, 310, 316, 103, + 102, 104, 105, nil, nil, 234, nil, nil, nil, nil, + nil, nil, 311, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + nil, nil, 317, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 307, nil, nil, 303, nil, nil, 58, 59, + nil, nil, 60, nil, 302, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 313, 314, + 72, 73, nil, nil, nil, nil, nil, 309, 310, 316, + 103, 102, 104, 105, nil, nil, 234, nil, nil, nil, + nil, nil, nil, 311, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, nil, nil, 317, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 307, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, nil, 678, nil, 675, 674, + 673, 683, 676, nil, nil, nil, nil, nil, nil, nil, + nil, 686, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 319, nil, 681, 62, nil, 83, 95, 96, 74, + 75, 71, nil, 57, 694, 693, nil, 63, 64, 687, + nil, nil, 67, nil, 65, 66, 68, 313, 314, 72, + 73, nil, nil, nil, nil, nil, 309, 310, 316, 103, + 102, 104, 105, nil, nil, 234, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, 233, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 232, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 313, 314, + 72, 73, nil, nil, nil, nil, nil, 309, 310, 316, + 103, 102, 104, 105, nil, nil, 234, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 232, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 313, + 314, 72, 73, nil, nil, nil, nil, nil, 309, 310, + 316, 103, 102, 104, 105, nil, nil, 234, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, 233, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 232, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, nil, nil, nil, 62, nil, 83, 95, 96, + 74, 75, 71, 9, 57, nil, nil, nil, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 103, 102, 104, 105, nil, nil, 19, nil, nil, nil, + nil, nil, 8, 45, nil, 10, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 40, nil, nil, 33, nil, nil, 58, + 59, nil, nil, 60, nil, 35, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 313, + 314, 72, 73, nil, nil, nil, nil, nil, 309, 310, + 316, 103, 102, 104, 105, nil, nil, 234, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, 288, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, 233, nil, nil, + 58, 59, nil, nil, 60, nil, 285, nil, nil, nil, + 44, nil, nil, 289, nil, nil, nil, nil, nil, 232, + nil, nil, nil, nil, 91, 286, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 313, 314, 72, 73, nil, nil, nil, nil, nil, 309, + 310, 316, 103, 102, 104, 105, nil, nil, 234, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, 288, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, 233, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, 289, nil, nil, nil, nil, nil, + 232, nil, nil, nil, nil, 91, 286, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 30, 31, 72, 73, nil, nil, nil, nil, nil, + 29, 28, 27, 103, 102, 104, 105, nil, nil, 19, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, 233, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 20, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 30, 31, 72, 73, nil, nil, nil, nil, + nil, 29, 28, 27, 103, 102, 104, 105, nil, nil, + 19, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + 233, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 233, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, 115, nil, nil, nil, nil, 114, 62, + nil, 83, 95, 96, 74, 75, 71, nil, 57, nil, + nil, nil, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 313, 314, 72, 73, nil, nil, nil, nil, + nil, 309, 310, 316, 103, 102, 104, 105, nil, nil, + 234, nil, nil, nil, nil, nil, nil, 311, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, nil, nil, 317, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 351, nil, nil, + 33, nil, nil, 58, 59, nil, nil, 60, nil, 35, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 313, 314, 72, 73, nil, nil, nil, + nil, nil, 309, 310, 316, 103, 102, 104, 105, nil, + nil, 234, nil, nil, nil, nil, nil, nil, 311, nil, + nil, 107, 106, 108, 356, 56, 99, 98, 357, nil, + 101, 109, 110, nil, 93, 94, nil, nil, 317, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 363, nil, nil, 358, nil, + nil, 233, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 313, 314, 72, 73, nil, nil, + nil, nil, nil, 309, 310, 316, 103, 102, 104, 105, + nil, nil, 234, nil, nil, nil, nil, nil, nil, 311, + nil, nil, 107, 106, 108, 356, 56, 99, 98, 357, + nil, 101, 109, 110, nil, 93, 94, nil, nil, 317, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 358, + nil, nil, 233, nil, nil, 58, 59, nil, nil, 60, + nil, nil, 678, nil, 675, 674, 673, 683, 676, nil, + nil, nil, nil, nil, nil, nil, nil, 686, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, nil, nil, 681, + 62, nil, 83, 95, 96, 74, 75, 71, 9, 57, + 694, 693, nil, 63, 64, 687, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 45, 7, + 10, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 58, 59, nil, nil, 60, nil, + 35, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, nil, nil, 391, 62, + nil, 83, 95, 96, 74, 75, 71, nil, 57, nil, + nil, nil, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 30, 31, 72, 73, nil, nil, nil, nil, + nil, 29, 28, 27, 103, 102, 104, 105, nil, nil, + 19, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + 233, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 233, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 233, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 20, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 103, 102, 104, + 105, nil, nil, 19, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, 233, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, nil, nil, + nil, 62, nil, 83, 95, 96, 74, 75, 71, 9, + 57, nil, nil, nil, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 45, + nil, 10, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 40, + nil, nil, 33, nil, nil, 58, 59, nil, nil, 60, + nil, 35, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 20, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 103, 102, 104, + 105, nil, nil, 234, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, 233, nil, nil, 58, 59, nil, nil, + 60, nil, 407, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 232, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 103, 102, + 104, 105, nil, nil, 234, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, 233, nil, nil, 58, 59, nil, + nil, 60, nil, 407, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 232, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 19, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, 233, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 103, 102, 104, 105, nil, nil, 19, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 103, 102, 104, 105, nil, nil, 234, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, 233, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 232, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 103, 102, 104, 105, nil, nil, 234, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, 288, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, 233, nil, + nil, 58, 59, nil, nil, 60, nil, 285, nil, 283, + nil, 44, nil, nil, 289, nil, nil, nil, nil, nil, + 232, nil, nil, nil, nil, 91, 286, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 30, 31, 72, 73, nil, nil, nil, nil, nil, + 29, 28, 27, 103, 102, 104, 105, nil, nil, 234, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, 233, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 232, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 30, 31, 72, 73, nil, nil, nil, nil, + nil, 29, 28, 27, 103, 102, 104, 105, nil, nil, + 19, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + 233, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 233, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, 222, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 313, 314, 72, 73, nil, nil, + nil, nil, nil, 309, 310, 316, 103, 102, 104, 105, + nil, nil, 234, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 233, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 232, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 313, 314, 72, 73, nil, + nil, nil, nil, nil, 309, 310, 316, 103, 102, 104, + 105, nil, nil, 234, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, 233, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 232, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 313, 314, 72, 73, + nil, nil, nil, nil, nil, 309, 310, 316, 103, 102, + 104, 105, nil, nil, 234, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, 233, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 232, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 313, 314, 72, + 73, nil, nil, nil, nil, nil, 309, 310, 316, 103, + 102, 104, 105, nil, nil, 234, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, 233, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 232, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 313, 314, + 72, 73, nil, nil, nil, nil, nil, 309, 310, 316, + 103, 102, 104, 105, nil, nil, 234, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 232, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 313, + 314, 72, 73, nil, nil, nil, nil, nil, 309, 310, + 316, 103, 102, 104, 105, nil, nil, 234, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, 233, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 232, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 313, 314, 72, 73, nil, nil, nil, nil, nil, 309, + 310, 316, 103, 102, 104, 105, nil, nil, 234, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, 233, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 232, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 313, 314, 72, 73, nil, nil, nil, nil, nil, + 309, 310, 316, 103, 102, 104, 105, nil, nil, 234, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, 233, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 232, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 313, 314, 72, 73, nil, nil, nil, nil, + nil, 309, 310, 316, 103, 102, 104, 105, nil, nil, + 234, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + 233, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 232, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 313, 314, 72, 73, nil, nil, nil, + nil, nil, 309, 310, 316, 103, 102, 104, 105, nil, + nil, 234, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 233, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 232, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 313, 314, 72, 73, nil, nil, + nil, nil, nil, 309, 310, 316, 103, 102, 104, 105, + nil, nil, 234, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 233, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 232, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 313, 314, 72, 73, nil, + nil, nil, nil, nil, 309, 310, 316, 103, 102, 104, + 105, nil, nil, 234, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, 233, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 232, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 313, 314, 72, 73, + nil, nil, nil, nil, nil, 309, 310, 316, 103, 102, + 104, 105, nil, nil, 234, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, 233, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 232, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 313, 314, 72, + 73, nil, nil, nil, nil, nil, 309, 310, 316, 103, + 102, 104, 105, nil, nil, 234, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, 233, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 232, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 313, 314, + 72, 73, nil, nil, nil, nil, nil, 309, 310, 316, + 103, 102, 104, 105, nil, nil, 234, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 232, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 313, + 314, 72, 73, nil, nil, nil, nil, nil, 309, 310, + 316, 103, 102, 104, 105, nil, nil, 234, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, 233, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 232, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 313, 314, 72, 73, nil, nil, nil, nil, nil, 309, + 310, 316, 103, 102, 104, 105, nil, nil, 234, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, 233, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 232, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 313, 314, 72, 73, nil, nil, nil, nil, nil, + 309, 310, 316, 103, 102, 104, 105, nil, nil, 234, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, 233, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 232, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 313, 314, 72, 73, nil, nil, nil, nil, + nil, 309, 310, 316, 103, 102, 104, 105, nil, nil, + 234, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + 233, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 232, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 313, 314, 72, 73, nil, nil, nil, + nil, nil, 309, 310, 316, 103, 102, 104, 105, nil, + nil, 234, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 233, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 232, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 313, 314, 72, 73, nil, nil, + nil, nil, nil, 309, 310, 316, 103, 102, 104, 105, + nil, nil, 234, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 233, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 232, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 313, 314, 72, 73, nil, + nil, nil, nil, nil, 309, 310, 316, 103, 102, 104, + 105, nil, nil, 234, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, 233, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 232, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 313, 314, 72, 73, + nil, nil, nil, nil, nil, 309, 310, 316, 103, 102, + 104, 105, nil, nil, 234, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, 233, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 232, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 313, 314, 72, + 73, nil, nil, nil, nil, nil, 309, 310, 316, 103, + 102, 104, 105, nil, nil, 234, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, 233, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 232, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 313, 314, + 72, 73, nil, nil, nil, nil, nil, 309, 310, 316, + 103, 102, 104, 105, nil, nil, 234, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 232, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 313, + 314, 72, 73, nil, nil, nil, nil, nil, 309, 310, + 316, 103, 102, 104, 105, nil, nil, 234, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, 233, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 232, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 313, 314, 72, 73, nil, nil, nil, nil, nil, 309, + 310, 316, 103, 102, 104, 105, nil, nil, 234, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, 233, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 232, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 30, 31, 72, 73, nil, nil, nil, nil, nil, + 29, 28, 27, 103, 102, 104, 105, nil, nil, 234, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, 288, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, 233, + nil, nil, 58, 59, nil, nil, 60, nil, 285, nil, + 283, nil, 44, nil, nil, 289, nil, nil, nil, nil, + nil, 232, nil, nil, nil, nil, 91, 286, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 30, 31, 72, 73, nil, nil, nil, nil, + nil, 29, 28, 27, 103, 102, 104, 105, nil, nil, + 234, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, 288, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + 233, nil, nil, 58, 59, nil, nil, 60, nil, 285, + nil, 283, nil, 44, nil, nil, 289, nil, nil, nil, + nil, nil, 232, nil, nil, nil, nil, 91, 286, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 234, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, 288, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 233, nil, nil, 58, 59, nil, nil, 60, nil, + 285, nil, 283, nil, 44, nil, nil, 289, nil, nil, + nil, nil, nil, 232, nil, nil, nil, nil, 91, 286, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, 222, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 313, 314, 72, 73, nil, nil, + nil, nil, nil, 309, 310, 316, 103, 102, 104, 105, + nil, nil, 234, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 233, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 232, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 313, 314, 72, 73, nil, + nil, nil, nil, nil, 309, 310, 316, 103, 102, 104, + 105, nil, nil, 234, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, 233, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 232, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 313, 314, 72, 73, + nil, nil, nil, nil, nil, 309, 310, 316, 103, 102, + 104, 105, nil, nil, 234, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, 233, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 232, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 313, 314, 72, + 73, nil, nil, nil, nil, nil, 309, 310, 316, 103, + 102, 104, 105, nil, nil, 234, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, 233, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 232, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + nil, nil, nil, 62, nil, 83, 95, 96, 74, 75, + 71, 9, 57, nil, nil, nil, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 103, 102, + 104, 105, nil, nil, 19, nil, nil, nil, nil, nil, + 8, 45, nil, 10, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 40, nil, nil, 33, nil, nil, 58, 59, nil, + nil, 60, nil, 35, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 20, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 313, 314, 72, + 73, nil, nil, nil, nil, nil, 309, 310, 316, 103, + 102, 104, 105, nil, nil, 234, nil, nil, nil, nil, + nil, nil, 311, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + nil, nil, 317, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 307, nil, nil, 233, nil, nil, 58, 59, + nil, nil, 60, nil, nil, 678, nil, 675, 674, 673, + 683, 676, nil, nil, nil, nil, nil, nil, nil, nil, + 686, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 512, nil, 681, 62, nil, 83, 95, 96, 74, 75, + 71, nil, 57, 694, 693, nil, 63, 64, 687, nil, + nil, 67, nil, 65, 66, 68, 313, 314, 72, 73, + nil, nil, nil, nil, nil, 309, 310, 316, 103, 102, + 104, 105, nil, nil, 234, nil, nil, nil, nil, nil, + nil, 311, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, nil, + nil, 317, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 307, nil, nil, 303, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 313, 314, 72, + 73, nil, nil, nil, nil, nil, 309, 310, 316, 103, + 102, 104, 105, nil, nil, 234, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, 233, 528, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 232, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 103, 102, 104, 105, nil, nil, 19, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 103, 102, 104, 105, nil, nil, 19, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, 233, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 20, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 103, 102, 104, 105, nil, nil, 19, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, 233, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 20, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 30, 31, 72, 73, nil, nil, nil, nil, nil, + 29, 28, 27, 103, 102, 104, 105, nil, nil, 19, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, 233, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 20, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 313, 314, 72, 73, nil, nil, nil, nil, + nil, 309, 310, 316, 103, 102, 104, 105, nil, nil, + 234, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + 233, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 232, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 234, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, 288, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 233, nil, nil, 58, 59, nil, nil, 60, nil, + 285, nil, 283, nil, 44, nil, nil, 289, nil, nil, + nil, nil, nil, 232, nil, nil, nil, nil, 91, 286, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 313, 314, 72, 73, nil, nil, + nil, nil, nil, 309, 310, 316, 103, 102, 104, 105, + nil, nil, 234, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 233, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 232, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 313, 314, 72, 73, nil, + nil, nil, nil, nil, 309, 310, 316, 103, 102, 104, + 105, nil, nil, 234, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, 233, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 232, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 313, 314, 72, 73, + nil, nil, nil, nil, nil, 309, 310, 316, 103, 102, + 104, 105, nil, nil, 234, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, 233, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 232, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 313, 314, 72, + 73, nil, nil, nil, nil, nil, 309, 310, 316, 103, + 102, 104, 105, nil, nil, 234, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, 288, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, 233, nil, nil, 58, 59, + nil, nil, 60, nil, 635, nil, 283, nil, 44, nil, + nil, 289, nil, nil, nil, nil, nil, 232, nil, nil, + nil, nil, 91, 286, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 313, 314, + 72, 73, nil, nil, nil, nil, nil, 309, 310, 316, + 103, 102, 104, 105, nil, nil, 234, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, 288, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, 283, nil, 44, + nil, nil, 289, nil, nil, nil, nil, nil, 232, nil, + nil, nil, nil, 91, 286, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 313, + 314, 72, 73, nil, nil, nil, nil, nil, 309, 310, + 316, 103, 102, 104, 105, nil, nil, 234, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, 233, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 232, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, nil, nil, nil, 62, nil, 83, 95, 96, + 74, 75, 71, 9, 57, nil, nil, nil, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 103, 102, 104, 105, nil, nil, 19, nil, nil, nil, + nil, nil, 8, 45, 296, 10, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 40, nil, nil, 33, nil, nil, 58, + 59, nil, nil, 60, nil, 35, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, nil, nil, 391, 62, nil, 83, 95, 96, 74, + 75, 71, nil, 57, nil, nil, nil, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 313, 314, 72, + 73, nil, nil, nil, nil, nil, 309, 310, 316, 103, + 102, 104, 105, nil, nil, 234, nil, nil, nil, nil, + nil, nil, 311, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + nil, nil, 317, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 307, nil, nil, 303, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 30, 31, + 72, 73, nil, nil, nil, nil, nil, 29, 28, 27, + 103, 102, 104, 105, nil, nil, 234, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, 288, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, 285, nil, 283, nil, 44, + nil, nil, 289, nil, nil, nil, nil, nil, 232, nil, + nil, nil, nil, 91, 286, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 313, + 314, 72, 73, nil, nil, nil, nil, nil, 309, 310, + 316, 103, 102, 104, 105, nil, nil, 234, nil, nil, + nil, nil, nil, nil, 311, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, nil, nil, 317, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 307, nil, nil, 303, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 313, 314, 72, 73, nil, nil, nil, nil, nil, 309, + 310, 316, 103, 102, 104, 105, nil, nil, 234, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, 233, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 232, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 313, 314, 72, 73, nil, nil, nil, nil, nil, + 309, 310, 316, 103, 102, 104, 105, nil, nil, 234, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, 233, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 232, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 30, 31, 72, 73, nil, nil, nil, nil, + nil, 29, 28, 27, 103, 102, 104, 105, nil, nil, + 19, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + 233, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 313, 314, 72, 73, nil, nil, nil, + nil, nil, 309, 310, 316, 103, 102, 104, 105, nil, + nil, 234, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, 288, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 233, nil, nil, 58, 59, nil, nil, 60, nil, + 635, nil, nil, nil, 44, nil, nil, 289, nil, nil, + nil, nil, nil, 232, nil, nil, nil, nil, 91, 286, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 313, 314, 72, 73, nil, nil, + nil, nil, nil, 309, 310, 316, 103, 102, 104, 105, + nil, nil, 234, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + 288, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 233, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, 289, nil, + nil, nil, nil, nil, 232, nil, nil, nil, nil, 91, + 286, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 313, 314, 72, 73, nil, + nil, nil, nil, nil, 309, 310, 316, 103, 102, 104, + 105, nil, nil, 234, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, 233, nil, nil, 58, 59, nil, nil, + 60, nil, 285, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 232, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 103, 102, + 104, 105, nil, nil, 234, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, 288, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, 233, nil, nil, 58, 59, nil, + nil, 60, nil, 285, nil, 283, nil, 44, nil, nil, + 289, nil, nil, nil, nil, nil, 232, nil, nil, nil, + nil, 91, 286, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 30, 31, 72, + 73, nil, nil, nil, nil, nil, 29, 28, 27, 103, + 102, 104, 105, nil, nil, 234, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, 288, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, 233, nil, nil, 58, 59, + nil, nil, 60, nil, 285, nil, 283, nil, 44, nil, + nil, 289, nil, nil, nil, nil, nil, 232, nil, nil, + nil, nil, 91, 286, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 313, 314, + 72, 73, nil, nil, nil, nil, nil, 309, 310, 316, + 103, 102, 104, 105, nil, nil, 234, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, 739, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 232, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 103, 102, 104, 105, nil, nil, 234, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, 233, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 232, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 103, 102, 104, 105, nil, nil, 234, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, 288, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, 233, nil, + nil, 58, 59, nil, nil, 60, nil, 285, nil, 283, + nil, 44, nil, nil, 289, nil, nil, nil, nil, nil, + 232, nil, nil, nil, nil, 91, 286, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, nil, nil, nil, 62, nil, 83, 95, + 96, 74, 75, 71, 9, 57, nil, nil, nil, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 30, + 31, 72, 73, nil, nil, nil, nil, nil, 29, 28, + 27, 103, 102, 104, 105, nil, nil, 19, nil, nil, + nil, nil, nil, 8, 45, nil, 10, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 40, nil, nil, 33, nil, nil, + 58, 59, nil, nil, 60, nil, 35, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 20, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 313, 314, 72, 73, nil, nil, nil, nil, nil, 309, + 310, 316, 103, 102, 104, 105, nil, nil, 234, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, 233, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 232, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 313, 314, 72, 73, nil, nil, nil, nil, nil, + 309, 310, 316, 103, 102, 104, 105, nil, nil, 234, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, 288, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, 233, + nil, nil, 58, 59, nil, nil, 60, nil, 635, nil, + 283, nil, 44, nil, nil, 289, nil, nil, nil, nil, + nil, 232, nil, nil, nil, nil, 91, 286, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 313, 314, 72, 73, nil, nil, nil, nil, + nil, 309, 310, 316, 103, 102, 104, 105, nil, nil, + 234, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, 288, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + 233, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, 283, nil, 44, nil, nil, 289, nil, nil, nil, + nil, nil, 232, nil, nil, nil, nil, 91, 286, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 234, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 233, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 232, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 234, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 233, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 232, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 30, 31, 72, 73, nil, + nil, nil, nil, nil, 29, 28, 27, 103, 102, 104, + 105, nil, nil, 234, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, 233, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 232, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 103, 102, + 104, 105, nil, nil, 234, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, 233, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 232, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 313, 314, 72, + 73, nil, nil, nil, nil, nil, 309, 310, 316, 103, + 102, 104, 105, nil, nil, 234, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, 233, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 232, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 313, 314, + 72, 73, nil, nil, nil, nil, nil, 309, 310, 316, + 103, 102, 104, 105, nil, nil, 234, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 232, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 313, + 314, 72, 73, nil, nil, nil, nil, nil, 309, 310, + 316, 103, 102, 104, 105, nil, nil, 234, nil, nil, + nil, nil, nil, nil, 311, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, nil, nil, 317, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 307, nil, nil, 303, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 313, 314, 72, 73, nil, nil, nil, nil, nil, 309, + 310, 316, 103, 102, 104, 105, nil, nil, 234, nil, + nil, nil, nil, nil, nil, 311, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, nil, nil, 317, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 307, nil, nil, 303, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 313, 314, 72, 73, nil, nil, nil, nil, nil, + 309, 310, 316, 103, 102, 104, 105, nil, nil, 234, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, 233, + nil, nil, 58, 59, nil, nil, 60, nil, 407, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 232, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 313, 314, 72, 73, nil, nil, nil, nil, + nil, 309, 310, 316, 103, 102, 104, 105, nil, nil, + 234, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + 233, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 232, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 233, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 30, 31, 72, 73, nil, nil, + nil, nil, nil, 29, 28, 27, 103, 102, 104, 105, + nil, nil, 19, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 233, nil, nil, 58, 59, nil, nil, 60, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 20, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 313, 314, 72, 73, nil, + nil, nil, nil, nil, 309, 310, 316, 103, 102, 104, + 105, nil, nil, 234, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, nil, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, 233, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, nil, nil, nil, nil, 232, nil, nil, nil, nil, + 91, 81, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 30, 31, 72, 73, + nil, nil, nil, nil, nil, 29, 28, 27, 103, 102, + 104, 105, nil, nil, 234, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, 233, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 232, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 313, 314, 72, + 73, nil, nil, nil, nil, nil, 309, 310, 316, 103, + 102, 104, 105, nil, nil, 234, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 227, nil, nil, 233, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, 44, nil, + nil, nil, nil, nil, nil, nil, nil, 232, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 313, 314, + 72, 73, nil, nil, nil, nil, nil, 309, 310, 316, + 103, 102, 104, 105, nil, nil, 234, nil, nil, nil, + nil, nil, nil, 45, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 227, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, nil, nil, nil, nil, 232, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 313, + 314, 72, 73, nil, nil, nil, nil, nil, 309, 310, + 316, 103, 102, 104, 105, nil, nil, 234, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, 233, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 232, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 313, 314, 72, 73, nil, nil, nil, nil, nil, 309, + 310, 316, 103, 102, 104, 105, nil, nil, 234, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, nil, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, 233, nil, + nil, 58, 59, nil, nil, 60, nil, nil, nil, nil, + nil, 44, nil, nil, nil, nil, nil, nil, nil, nil, + 232, nil, nil, nil, nil, 91, 81, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, 74, 75, 71, 62, 57, 83, 95, + 96, 63, 64, nil, nil, nil, 67, nil, 65, 66, + 68, 313, 314, 72, 73, nil, nil, nil, nil, nil, + 309, 310, 316, 103, 102, 104, 105, nil, nil, 234, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 107, + 106, 108, 97, 56, 99, 98, 100, nil, 101, 109, + 110, nil, 93, 94, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, 233, + nil, nil, 58, 59, nil, nil, 60, nil, nil, nil, + nil, nil, 44, nil, nil, nil, nil, nil, nil, nil, + nil, 232, nil, nil, nil, nil, 91, 81, 84, 85, + nil, 86, 88, 87, 89, nil, nil, nil, nil, 82, + 90, nil, nil, nil, 74, 75, 71, 62, 57, 83, + 95, 96, 63, 64, nil, nil, nil, 67, nil, 65, + 66, 68, 313, 314, 72, 73, nil, nil, nil, nil, + nil, 309, 310, 316, 103, 102, 104, 105, nil, nil, + 234, nil, nil, nil, nil, nil, nil, 45, nil, nil, + 107, 106, 108, 97, 56, 99, 98, 100, nil, 101, + 109, 110, nil, 93, 94, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 227, nil, nil, + 233, nil, nil, 58, 59, nil, nil, 60, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, nil, nil, + nil, nil, 232, nil, nil, nil, nil, 91, 81, 84, + 85, nil, 86, 88, 87, 89, nil, nil, nil, nil, + 82, 90, nil, nil, nil, 74, 75, 71, 62, 57, + 83, 95, 96, 63, 64, nil, nil, nil, 67, nil, + 65, 66, 68, 30, 31, 72, 73, nil, nil, nil, + nil, nil, 29, 28, 27, 103, 102, 104, 105, nil, + nil, 19, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 107, 106, 108, 97, 56, 99, 98, 100, nil, + 101, 109, 110, nil, 93, 94, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 227, nil, + nil, 233, nil, nil, 58, 59, nil, nil, 60, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 91, 81, + 84, 85, nil, 86, 88, 87, 89, nil, nil, nil, + nil, 82, 90, nil, nil, nil, 74, 75, 71, 62, + 57, 83, 95, 96, 63, 64, nil, nil, nil, 67, + nil, 65, 66, 68, 313, 314, 72, 73, nil, nil, + nil, nil, nil, 309, 310, 316, 103, 102, 104, 105, + nil, nil, 234, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 107, 106, 108, 97, 56, 99, 98, 100, + nil, 101, 109, 110, nil, 93, 94, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 233, nil, nil, 58, 59, nil, nil, 60, + nil, 635, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 232, nil, nil, nil, nil, 91, + 81, 84, 85, nil, 86, 88, 87, 89, nil, nil, + nil, nil, 82, 90, nil, nil, nil, 74, 75, 71, + 62, 57, 83, 95, 96, 63, 64, nil, nil, nil, + 67, nil, 65, 66, 68, 313, 314, 72, 73, nil, + nil, nil, nil, nil, 309, 310, 316, 103, 102, 104, + 105, nil, nil, 234, nil, nil, nil, nil, nil, nil, + 45, nil, nil, 107, 106, 108, 97, 56, 99, 98, + 100, 288, 101, 109, 110, nil, 93, 94, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, 233, nil, nil, 58, 59, nil, nil, + 60, nil, nil, nil, 283, nil, 44, nil, nil, 289, + nil, nil, nil, nil, nil, 232, nil, nil, nil, nil, + 91, 286, 84, 85, nil, 86, 88, 87, 89, nil, + nil, nil, nil, 82, 90, nil, nil, nil, 74, 75, + 71, 62, 57, 83, 95, 96, 63, 64, nil, nil, + nil, 67, nil, 65, 66, 68, 313, 314, 72, 73, + nil, nil, nil, nil, nil, 309, 310, 316, 103, 102, + 104, 105, nil, nil, 234, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 107, 106, 108, 97, 56, 99, + 98, 100, nil, 101, 109, 110, nil, 93, 94, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 227, nil, nil, 233, nil, nil, 58, 59, nil, + nil, 60, nil, nil, nil, nil, nil, 44, nil, nil, + nil, nil, nil, nil, nil, nil, 232, nil, nil, nil, + nil, 91, 81, 84, 85, nil, 86, 88, 87, 89, + nil, nil, nil, nil, 82, 90, nil, nil, nil, 74, + 75, 71, 62, 57, 83, 95, 96, 63, 64, nil, + nil, nil, 67, nil, 65, 66, 68, 313, 314, 72, + 73, nil, nil, nil, nil, nil, 309, 310, 316, 103, + 102, 104, 105, nil, nil, 234, nil, nil, nil, nil, + nil, nil, 311, nil, nil, 107, 106, 108, 97, 56, + 99, 98, 100, nil, 101, 109, 110, nil, 93, 94, + nil, nil, 317, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 921, nil, nil, 233, nil, nil, 58, 59, + nil, nil, 60, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 91, 81, 84, 85, nil, 86, 88, 87, + 89, nil, nil, nil, nil, 82, 90, nil, nil, nil, + 74, 75, 71, 62, 57, 83, 95, 96, 63, 64, + nil, nil, nil, 67, nil, 65, 66, 68, 313, 314, + 72, 73, nil, nil, nil, nil, nil, 309, 310, 316, + 103, 102, 104, 105, nil, nil, 234, nil, nil, nil, + nil, nil, nil, 311, nil, nil, 107, 106, 108, 97, + 56, 99, 98, 100, nil, 101, 109, 110, nil, 93, + 94, nil, nil, 317, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 927, nil, nil, 233, nil, nil, 58, + 59, nil, nil, 60, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 91, 81, 84, 85, nil, 86, 88, + 87, 89, nil, nil, nil, nil, 82, 90, nil, nil, + nil, 74, 75, 71, 62, 57, 83, 95, 96, 63, + 64, nil, nil, nil, 67, nil, 65, 66, 68, 313, + 314, 72, 73, nil, nil, nil, nil, nil, 309, 310, + 316, 103, 102, 104, 105, nil, nil, 234, nil, nil, + nil, nil, nil, nil, 311, nil, nil, 107, 106, 108, + 97, 56, 99, 98, 100, nil, 101, 109, 110, nil, + 93, 94, nil, nil, 317, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 921, nil, nil, 233, nil, nil, + 58, 59, nil, nil, 60, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 91, 81, 84, 85, nil, 86, + 88, 87, 89, nil, nil, nil, nil, 82, 90, nil, + nil, nil, 74, 75, 71, 62, 57, 83, 95, 96, + 63, 64, nil, nil, nil, 67, nil, 65, 66, 68, + 30, 31, 72, 73, nil, nil, nil, nil, nil, 29, + 28, 27, 103, 102, 104, 105, nil, nil, 234, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 107, 106, + 108, 97, 56, 99, 98, 100, 288, 101, 109, 110, + nil, 93, 94, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 227, nil, nil, 233, nil, + nil, 58, 59, nil, nil, 60, nil, 285, nil, 283, + nil, 44, nil, nil, 289, nil, nil, nil, nil, nil, + 232, nil, nil, nil, nil, 91, 286, 84, 85, nil, + 86, 88, 87, 89, nil, nil, nil, nil, 82, 90, + nil, nil, nil, nil, nil, nil, 62, nil, 83, 95, + 96, 175, 186, 176, 199, 172, 192, 182, 181, 202, + 203, 197, 180, 179, 174, 200, 204, 205, 184, 173, + 187, 191, 193, 185, 178, nil, nil, nil, 194, 201, + 196, 195, 188, 198, 183, 171, 190, 189, nil, nil, + nil, nil, nil, 170, 177, 168, 169, 165, 166, 167, + 126, 128, 125, nil, 127, nil, nil, nil, nil, nil, + nil, nil, 159, 160, nil, 156, 138, 139, 140, 147, + 144, 146, nil, nil, 141, 142, nil, nil, nil, 161, + 162, 148, 149, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 153, 152, nil, 137, + 158, 155, 154, 163, 150, 151, 145, 143, 135, 157, + 136, nil, nil, 164, 91, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 90, 175, + 186, 176, 199, 172, 192, 182, 181, 202, 203, 197, + 180, 179, 174, 200, 204, 205, 184, 173, 187, 191, + 193, 185, 178, nil, nil, nil, 194, 201, 196, 195, + 188, 198, 183, 171, 190, 189, nil, nil, nil, nil, + nil, 170, 177, 168, 169, 165, 166, 167, 126, 128, + nil, nil, 127, nil, nil, nil, nil, nil, nil, nil, + 159, 160, nil, 156, 138, 139, 140, 147, 144, 146, + nil, nil, 141, 142, nil, nil, nil, 161, 162, 148, + 149, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 153, 152, nil, 137, 158, 155, + 154, 163, 150, 151, 145, 143, 135, 157, 136, nil, + nil, 164, 91, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 90, 175, 186, 176, + 199, 172, 192, 182, 181, 202, 203, 197, 180, 179, + 174, 200, 204, 205, 184, 173, 187, 191, 193, 185, + 178, nil, nil, nil, 194, 201, 196, 195, 188, 198, + 183, 171, 190, 189, nil, nil, nil, nil, nil, 170, + 177, 168, 169, 165, 166, 167, 126, 128, nil, nil, + 127, nil, nil, nil, nil, nil, nil, nil, 159, 160, + nil, 156, 138, 139, 140, 147, 144, 146, nil, nil, + 141, 142, nil, nil, nil, 161, 162, 148, 149, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 153, 152, nil, 137, 158, 155, 154, 163, + 150, 151, 145, 143, 135, 157, 136, nil, nil, 164, + 91, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 90, 175, 186, 176, 199, 172, + 192, 182, 181, 202, 203, 197, 180, 179, 174, 200, + 204, 205, 184, 173, 187, 191, 193, 185, 178, nil, + nil, nil, 194, 201, 196, 195, 188, 198, 183, 171, + 190, 189, nil, nil, nil, nil, nil, 170, 177, 168, + 169, 165, 166, 167, 126, 128, nil, nil, 127, nil, + nil, nil, nil, nil, nil, nil, 159, 160, nil, 156, + 138, 139, 140, 147, 144, 146, nil, nil, 141, 142, + nil, nil, nil, 161, 162, 148, 149, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 153, 152, nil, 137, 158, 155, 154, 163, 150, 151, + 145, 143, 135, 157, 136, nil, nil, 164, 91, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 90, 175, 186, 176, 199, 172, 192, 182, + 181, 202, 203, 197, 180, 179, 174, 200, 204, 205, + 184, 173, 187, 191, 193, 185, 178, nil, nil, nil, + 194, 201, 196, 374, 373, 375, 372, 171, 190, 189, + nil, nil, nil, nil, nil, 170, 177, 168, 169, 369, + 370, 371, 367, 128, 99, 98, 368, nil, 101, nil, + nil, nil, nil, nil, 159, 160, nil, 156, 138, 139, + 140, 147, 144, 146, nil, nil, 141, 142, nil, nil, + nil, 161, 162, 148, 149, nil, nil, nil, nil, nil, + 379, nil, nil, nil, nil, nil, nil, nil, 153, 152, + nil, 137, 158, 155, 154, 163, 150, 151, 145, 143, + 135, 157, 136, nil, nil, 164, 175, 186, 176, 199, + 172, 192, 182, 181, 202, 203, 197, 180, 179, 174, + 200, 204, 205, 184, 173, 187, 191, 193, 185, 178, + nil, nil, nil, 194, 201, 196, 195, 188, 198, 183, + 171, 190, 189, nil, nil, nil, nil, nil, 170, 177, + 168, 169, 165, 166, 167, 126, 128, nil, nil, 127, + nil, nil, nil, nil, nil, nil, nil, 159, 160, nil, + 156, 138, 139, 140, 147, 144, 146, nil, nil, 141, + 142, nil, nil, nil, 161, 162, 148, 149, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 153, 152, nil, 137, 158, 155, 154, 163, 150, + 151, 145, 143, 135, 157, 136, 429, 433, 164, nil, + 430, nil, nil, nil, nil, nil, nil, nil, 159, 160, + nil, 156, 138, 139, 140, 147, 144, 146, nil, nil, + 141, 142, nil, nil, nil, 161, 162, 148, 149, nil, + nil, nil, nil, nil, 267, nil, nil, nil, nil, nil, + nil, nil, 153, 152, nil, 137, 158, 155, 154, 163, + 150, 151, 145, 143, 135, 157, 136, 436, 440, 164, + nil, 435, nil, nil, nil, nil, nil, nil, nil, 159, + 160, nil, 156, 138, 139, 140, 147, 144, 146, nil, + nil, 141, 142, nil, nil, nil, 161, 162, 148, 149, + nil, nil, nil, nil, nil, 267, nil, nil, nil, nil, + nil, nil, nil, 153, 152, nil, 137, 158, 155, 154, + 163, 150, 151, 145, 143, 135, 157, 136, 483, 433, + 164, nil, 484, nil, nil, nil, nil, nil, nil, nil, + 159, 160, nil, 156, 138, 139, 140, 147, 144, 146, + nil, nil, 141, 142, nil, nil, nil, 161, 162, 148, + 149, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 153, 152, nil, 137, 158, 155, + 154, 163, 150, 151, 145, 143, 135, 157, 136, 616, + 433, 164, nil, 617, nil, nil, nil, nil, nil, nil, + nil, 159, 160, nil, 156, 138, 139, 140, 147, 144, + 146, nil, nil, 141, 142, nil, nil, nil, 161, 162, + 148, 149, nil, nil, nil, nil, nil, 267, nil, nil, + nil, nil, nil, nil, nil, 153, 152, nil, 137, 158, + 155, 154, 163, 150, 151, 145, 143, 135, 157, 136, + 618, 440, 164, nil, 619, nil, nil, nil, nil, nil, + nil, nil, 159, 160, nil, 156, 138, 139, 140, 147, + 144, 146, nil, nil, 141, 142, nil, nil, nil, 161, + 162, 148, 149, nil, nil, nil, nil, nil, 267, nil, + nil, nil, nil, nil, nil, nil, 153, 152, nil, 137, + 158, 155, 154, 163, 150, 151, 145, 143, 135, 157, + 136, 646, 433, 164, nil, 647, nil, nil, nil, nil, + nil, nil, nil, 159, 160, nil, 156, 138, 139, 140, + 147, 144, 146, nil, nil, 141, 142, nil, nil, nil, + 161, 162, 148, 149, nil, nil, nil, nil, nil, 267, + nil, nil, nil, nil, nil, nil, nil, 153, 152, nil, + 137, 158, 155, 154, 163, 150, 151, 145, 143, 135, + 157, 136, 649, 440, 164, nil, 650, nil, nil, nil, + nil, nil, nil, nil, 159, 160, nil, 156, 138, 139, + 140, 147, 144, 146, nil, nil, 141, 142, nil, nil, + nil, 161, 162, 148, 149, nil, nil, nil, nil, nil, + 267, nil, nil, nil, nil, nil, nil, nil, 153, 152, + nil, 137, 158, 155, 154, 163, 150, 151, 145, 143, + 135, 157, 136, 616, 433, 164, nil, 617, nil, nil, + nil, nil, nil, nil, nil, 159, 160, nil, 156, 138, + 139, 140, 147, 144, 146, nil, nil, 141, 142, nil, + nil, nil, 161, 162, 148, 149, nil, nil, nil, nil, + nil, 267, nil, nil, nil, nil, nil, nil, nil, 153, + 152, nil, 137, 158, 155, 154, 163, 150, 151, 145, + 143, 135, 157, 136, 618, 440, 164, nil, 619, nil, + nil, nil, nil, nil, nil, nil, 159, 160, nil, 156, + 138, 139, 140, 147, 144, 146, nil, nil, 141, 142, + nil, nil, nil, 161, 162, 148, 149, nil, nil, nil, + nil, nil, 267, nil, nil, nil, nil, nil, nil, nil, + 153, 152, nil, 137, 158, 155, 154, 163, 150, 151, + 145, 143, 135, 157, 136, 707, 433, 164, nil, 708, + nil, nil, nil, nil, nil, nil, nil, 159, 160, nil, + 156, 138, 139, 140, 147, 144, 146, nil, nil, 141, + 142, nil, nil, nil, 161, 162, 148, 149, nil, nil, + nil, nil, nil, 267, nil, nil, nil, nil, nil, nil, + nil, 153, 152, nil, 137, 158, 155, 154, 163, 150, + 151, 145, 143, 135, 157, 136, 709, 440, 164, nil, + 710, nil, nil, nil, nil, nil, nil, nil, 159, 160, + nil, 156, 138, 139, 140, 147, 144, 146, nil, nil, + 141, 142, nil, nil, nil, 161, 162, 148, 149, nil, + nil, nil, nil, nil, 267, nil, nil, nil, nil, nil, + nil, nil, 153, 152, nil, 137, 158, 155, 154, 163, + 150, 151, 145, 143, 135, 157, 136, 712, 440, 164, + nil, 713, nil, nil, nil, nil, nil, nil, nil, 159, + 160, nil, 156, 138, 139, 140, 147, 144, 146, nil, + nil, 141, 142, nil, nil, nil, 161, 162, 148, 149, + nil, nil, nil, nil, nil, 267, nil, nil, nil, nil, + nil, nil, nil, 153, 152, nil, 137, 158, 155, 154, + 163, 150, 151, 145, 143, 135, 157, 136, 483, 433, + 164, nil, 484, nil, nil, nil, nil, nil, nil, nil, + 159, 160, nil, 156, 138, 139, 140, 147, 144, 146, + nil, nil, 141, 142, nil, nil, nil, 161, 162, 148, + 149, nil, nil, nil, nil, nil, 267, nil, nil, nil, + nil, nil, nil, nil, 153, 152, nil, 137, 158, 155, + 154, 163, 150, 151, 145, 143, 135, 157, 136, 741, + 433, 164, nil, 742, nil, nil, nil, nil, nil, nil, + nil, 159, 160, nil, 156, 138, 139, 140, 147, 144, + 146, nil, nil, 141, 142, nil, nil, nil, 161, 162, + 148, 149, nil, nil, nil, nil, nil, 267, nil, nil, + nil, nil, nil, nil, nil, 153, 152, nil, 137, 158, + 155, 154, 163, 150, 151, 145, 143, 135, 157, 136, + 744, 440, 164, nil, 743, nil, nil, nil, nil, nil, + nil, nil, 159, 160, nil, 156, 138, 139, 140, 147, + 144, 146, nil, nil, 141, 142, nil, nil, nil, 161, + 162, 148, 149, nil, nil, nil, nil, nil, 267, nil, + nil, nil, nil, nil, nil, nil, 153, 152, nil, 137, + 158, 155, 154, 163, 150, 151, 145, 143, 135, 157, + 136, 1005, 440, 164, nil, 1004, nil, nil, nil, nil, + nil, nil, nil, 159, 160, nil, 156, 138, 139, 140, + 147, 144, 146, nil, nil, 141, 142, nil, nil, nil, + 161, 162, 148, 149, nil, nil, nil, nil, nil, 267, + nil, nil, nil, nil, nil, nil, nil, 153, 152, nil, + 137, 158, 155, 154, 163, 150, 151, 145, 143, 135, + 157, 136, 1008, 433, 164, nil, 1009, nil, nil, nil, + nil, nil, nil, nil, 159, 160, nil, 156, 138, 139, + 140, 147, 144, 146, nil, nil, 141, 142, nil, nil, + nil, 161, 162, 148, 149, nil, nil, nil, nil, nil, + 267, nil, nil, nil, nil, nil, nil, nil, 153, 152, + nil, 137, 158, 155, 154, 163, 150, 151, 145, 143, + 135, 157, 136, 1010, 440, 164, nil, 1011, nil, nil, + nil, nil, nil, nil, nil, 159, 160, nil, 156, 138, + 139, 140, 147, 144, 146, nil, nil, 141, 142, nil, + nil, nil, 161, 162, 148, 149, nil, nil, nil, nil, + nil, 267, nil, nil, nil, nil, nil, nil, nil, 153, + 152, nil, 137, 158, 155, 154, 163, 150, 151, 145, + 143, 135, 157, 136, nil, 678, 164, 675, 674, 673, + 683, 676, nil, 678, nil, 675, 674, 673, 683, 676, + 686, nil, nil, nil, nil, nil, nil, nil, 686, nil, + 678, nil, 675, 674, 673, 683, 676, nil, nil, nil, + nil, nil, 681, 664, nil, 686, nil, nil, nil, nil, + 681, 691, 690, 694, 693, nil, nil, nil, 687, 691, + 690, 694, 693, nil, nil, nil, 687, 681, nil, 678, + nil, 675, 674, 673, 683, 676, 691, 690, 694, 693, + nil, nil, nil, 687, 686, nil, 678, nil, 675, 674, + 673, 683, 676, nil, 678, nil, 675, 674, 673, 683, + 676, 686, nil, nil, nil, nil, 681, nil, nil, 686, + nil, nil, nil, nil, nil, 691, 690, 694, 693, nil, + nil, nil, 687, 681, nil, nil, nil, nil, nil, nil, + nil, 681, 691, 690, 694, 693, nil, nil, nil, 687, + 691, 690, 694, 693, nil, nil, 678, 687, 675, 674, + 673, 683, 676, nil, 678, nil, 675, 674, 673, 683, + 676, 686, nil, nil, nil, nil, nil, nil, nil, 686, + nil, 678, nil, 675, 674, 673, 683, 676, nil, nil, + nil, nil, nil, 681, nil, nil, 686, nil, nil, nil, + nil, 681, 691, 690, 694, 693, nil, nil, nil, 687, + 691, 690, 694, 693, nil, nil, nil, 687, 681, nil, + 678, nil, 675, 674, 673, 683, 676, 691, 690, 694, + 693, nil, nil, nil, 687, 686, nil, 678, nil, 675, + 674, 673, 683, 676, 678, nil, 675, 674, 673, 683, + 676, nil, 686, nil, nil, nil, nil, 681, nil, 686, + nil, 678, nil, 675, 674, 673, 683, 676, 694, 693, + nil, nil, nil, 687, 681, nil, 686, nil, nil, nil, + nil, 681, nil, 691, 690, 694, 693, nil, nil, nil, + 687, nil, 694, 693, nil, nil, nil, 687, 681, nil, + 678, nil, 675, 674, 673, 683, 676, nil, nil, 694, + 693, nil, nil, nil, 687, 686, nil, 678, nil, 675, + 674, 673, 683, 676, 678, nil, 675, 674, 673, 683, + 676, nil, 686, nil, nil, nil, nil, 681, nil, 686, + nil, nil, nil, nil, nil, nil, nil, nil, 694, 693, + nil, nil, nil, 687, 681, nil, nil, nil, nil, nil, + nil, 681, nil, nil, nil, 694, 693, nil, nil, nil, + 687, nil, 694, 693, nil, nil, nil, 687 ] + +racc_action_check = [ + 97, 445, 445, 569, 569, 17, 348, 97, 97, 97, + 1, 341, 97, 97, 97, 24, 97, 26, 19, 386, + 629, 767, 24, 342, 97, 387, 97, 97, 97, 61, + 358, 625, 225, 7, 358, 349, 97, 97, 705, 97, + 97, 97, 97, 97, 865, 891, 924, 925, 928, 352, + 641, 555, 17, 10, 978, 629, 767, 12, 312, 19, + 641, 332, 17, 13, 332, 707, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 24, 26, 97, 97, 97, 386, 97, 97, 547, 225, + 97, 387, 708, 97, 97, 445, 97, 569, 97, 896, + 97, 896, 97, 97, 26, 97, 97, 97, 97, 97, + 1008, 97, 100, 97, 1009, 348, 61, 793, 625, 100, + 100, 100, 312, 1010, 100, 100, 100, 97, 100, 341, + 97, 97, 97, 97, 341, 97, 100, 97, 100, 100, + 100, 342, 97, 97, 349, 312, 342, 646, 100, 100, + 1011, 100, 100, 100, 100, 100, 705, 1029, 352, 705, + 555, 705, 865, 891, 924, 925, 928, 865, 891, 924, + 925, 928, 978, 548, 707, 709, 825, 978, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 100, 100, 547, 15, 100, 100, 100, 547, 100, 100, + 1010, 708, 100, 22, 647, 100, 100, 826, 100, 710, + 100, 3, 100, 646, 100, 100, 3, 100, 100, 100, + 100, 100, 435, 100, 226, 100, 793, 1011, 1008, 435, + 435, 435, 1009, 1008, 37, 435, 435, 1009, 435, 100, + 709, 1010, 100, 100, 100, 100, 1010, 100, 40, 100, + 656, 656, 228, 646, 100, 100, 646, 79, 435, 435, + 782, 435, 435, 435, 435, 435, 646, 45, 1011, 79, + 647, 367, 649, 1011, 710, 1029, 111, 548, 367, 79, + 1029, 226, 548, 414, 709, 825, 565, 565, 435, 435, + 435, 435, 435, 435, 435, 435, 435, 435, 435, 435, + 435, 435, 206, 451, 435, 435, 435, 368, 435, 228, + 647, 826, 435, 647, 368, 435, 826, 227, 710, 229, + 435, 230, 435, 647, 435, 435, 782, 435, 435, 435, + 435, 435, 381, 435, 436, 435, 367, 649, 649, 234, + 414, 436, 436, 436, 656, 266, 292, 436, 436, 435, + 436, 292, 435, 435, 280, 435, 125, 435, 345, 436, + 451, 125, 125, 345, 435, 435, 782, 356, 38, 782, + 436, 436, 368, 436, 436, 436, 436, 436, 649, 782, + 565, 649, 14, 14, 281, 565, 810, 616, 810, 810, + 810, 649, 810, 41, 41, 284, 381, 381, 381, 296, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 436, 436, 436, 436, 297, 38, 436, 436, 436, 356, + 436, 317, 317, 500, 436, 38, 356, 436, 829, 617, + 299, 356, 436, 829, 436, 356, 436, 436, 39, 436, + 436, 436, 436, 436, 616, 436, 436, 436, 580, 945, + 582, 945, 945, 945, 356, 945, 369, 834, 300, 357, + 741, 436, 834, 369, 436, 436, 618, 436, 810, 436, + 301, 41, 41, 618, 618, 618, 436, 436, 618, 618, + 618, 307, 618, 310, 356, 39, 617, 500, 500, 500, + 370, 618, 618, 618, 618, 39, 311, 370, 333, 317, + 317, 333, 618, 618, 500, 618, 618, 618, 618, 618, + 316, 357, 580, 580, 582, 582, 382, 741, 357, 383, + 318, 369, 580, 357, 582, 384, 322, 357, 325, 742, + 330, 945, 618, 618, 618, 618, 618, 618, 618, 618, + 618, 618, 618, 618, 618, 618, 357, 334, 618, 618, + 618, 336, 618, 618, 336, 370, 618, 385, 321, 618, + 618, 388, 618, 371, 618, 335, 618, 429, 618, 618, + 371, 618, 618, 618, 618, 618, 357, 618, 618, 618, + 382, 382, 382, 383, 383, 383, 742, 372, 337, 384, + 384, 384, 430, 618, 372, 346, 618, 618, 618, 618, + 373, 618, 347, 618, 619, 321, 764, 373, 618, 618, + 351, 619, 619, 619, 429, 321, 619, 619, 619, 353, + 619, 385, 385, 385, 429, 388, 388, 388, 371, 362, + 619, 619, 619, 662, 967, 838, 662, 967, 601, 430, + 619, 619, 397, 619, 619, 619, 619, 619, 403, 430, + 406, 16, 372, 46, 374, 375, 340, 340, 16, 377, + 46, 374, 375, 764, 408, 373, 377, 16, 411, 46, + 619, 619, 619, 619, 619, 619, 619, 619, 619, 619, + 619, 619, 619, 619, 415, 601, 619, 619, 619, 425, + 619, 619, 838, 427, 619, 601, 428, 619, 619, 437, + 619, 447, 619, 459, 619, 460, 619, 619, 457, 619, + 619, 619, 619, 619, 743, 619, 16, 619, 46, 374, + 375, 743, 743, 743, 377, 696, 696, 743, 743, 461, + 743, 619, 465, 462, 619, 619, 619, 619, 487, 619, + 457, 619, 712, 491, 457, 457, 619, 619, 465, 465, + 743, 743, 507, 743, 743, 743, 743, 743, 508, 224, + 798, 798, 511, 304, 465, 513, 224, 518, 465, 465, + 304, 465, 465, 989, 989, 224, 521, 529, 530, 304, + 743, 743, 743, 743, 743, 743, 743, 743, 743, 743, + 743, 743, 743, 743, 712, 305, 743, 743, 743, 531, + 743, 712, 305, 532, 743, 544, 712, 743, 549, 550, + 712, 305, 743, 567, 743, 577, 743, 743, 585, 743, + 743, 743, 743, 743, 224, 743, 744, 743, 304, 712, + 587, 593, 602, 744, 744, 744, 795, 607, 458, 744, + 744, 743, 744, 612, 743, 743, 795, 743, 306, 743, + 620, 744, 621, 622, 624, 306, 743, 743, 628, 712, + 305, 630, 744, 744, 306, 744, 744, 744, 744, 744, + 458, 308, 632, 634, 458, 458, 640, 643, 308, 795, + 795, 645, 648, 651, 795, 573, 573, 308, 652, 573, + 573, 573, 744, 744, 744, 744, 744, 744, 744, 744, + 744, 744, 744, 744, 744, 744, 655, 657, 744, 744, + 744, 323, 744, 306, 350, 666, 744, 667, 323, 744, + 669, 350, 670, 671, 744, 680, 744, 323, 744, 744, + 350, 744, 744, 744, 744, 744, 308, 744, 744, 744, + 773, 688, 773, 773, 773, 773, 773, 360, 6, 6, + 6, 6, 6, 744, 360, 773, 744, 744, 27, 744, + 692, 744, 695, 360, 698, 27, 27, 27, 744, 744, + 27, 27, 27, 703, 27, 706, 323, 773, 715, 350, + 719, 476, 738, 27, 27, 27, 773, 773, 773, 773, + 740, 749, 770, 773, 27, 27, 781, 27, 27, 27, + 27, 27, 888, 785, 888, 888, 888, 413, 888, 788, + 789, 794, 360, 476, 413, 809, 811, 476, 476, 773, + 476, 476, 816, 413, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 819, 888, + 27, 27, 27, 828, 832, 27, 833, 27, 27, 836, + 837, 27, 27, 846, 27, 847, 27, 849, 27, 850, + 27, 27, 851, 27, 27, 27, 27, 27, 28, 27, + 27, 27, 413, 853, 854, 28, 28, 28, 855, 856, + 28, 28, 28, 517, 28, 27, 871, 872, 27, 27, + 517, 27, 876, 27, 28, 28, 877, 879, 880, 517, + 27, 882, 885, 887, 28, 28, 893, 28, 28, 28, + 28, 28, 894, 900, 904, 558, 917, 650, 921, 927, + 947, 957, 558, 960, 650, 961, 962, 963, 965, 650, + 974, 558, 979, 650, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 517, 980, + 28, 28, 28, 981, 982, 28, 983, 28, 28, 984, + 985, 28, 28, 987, 28, 990, 28, 991, 28, 1004, + 28, 28, 1005, 28, 28, 28, 28, 28, 56, 28, + 558, 28, 650, 1007, 1020, 56, 56, 56, 1024, 1025, + 56, 56, 56, 920, 56, 28, 1026, 1027, 28, 28, + 920, 28, 1030, 28, 56, 56, 56, 1031, 1038, 920, + 28, nil, nil, nil, 56, 56, nil, 56, 56, 56, + 56, 56, nil, 713, nil, 926, nil, 971, nil, nil, + 713, nil, 926, nil, 971, 713, nil, nil, nil, 713, + nil, 926, nil, 971, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 920, 907, + 56, 56, 56, nil, nil, 56, nil, nil, 56, 907, + nil, 56, 56, nil, 56, nil, 56, nil, 56, nil, + 56, 56, nil, 56, 56, 56, 56, 56, 713, 56, + 926, 56, 971, 918, nil, 918, 918, 918, nil, 918, + nil, nil, 907, 907, nil, 56, 477, 907, 56, 56, + 56, 56, nil, 56, 431, 56, nil, nil, nil, nil, + 56, 431, 431, 431, nil, nil, 431, 431, 431, 681, + 431, 681, 681, 681, nil, 681, nil, nil, 477, 431, + 431, 431, 477, 477, nil, 477, 477, nil, nil, nil, + 431, 431, nil, 431, 431, 431, 431, 431, 946, nil, + 946, 946, 946, nil, 946, 807, 681, 807, 807, 807, + 1003, 807, 1003, 1003, 1003, 681, 1003, nil, nil, nil, + 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, + 431, 431, 431, 431, nil, 946, 431, 431, 431, nil, + nil, 431, 807, 431, 431, nil, nil, 431, 431, nil, + 431, 807, 431, nil, 431, nil, 431, 431, nil, 431, + 431, 431, 431, 431, nil, 431, 431, 431, 803, nil, + 803, 803, 803, 803, 803, 295, 295, 295, 295, 295, + nil, 431, nil, 803, 431, 431, 440, 431, nil, 431, + nil, nil, nil, 440, 440, 440, 431, nil, 440, 440, + 440, nil, 440, 467, 886, 803, 886, 886, 886, nil, + 886, 440, 440, 440, 440, nil, 803, 803, nil, 467, + 467, 803, 440, 440, nil, 440, 440, 440, 440, 440, + 986, nil, 986, 986, 986, 467, 986, 467, nil, 467, + 467, 886, 467, 467, nil, nil, 467, nil, 467, nil, + 886, nil, 440, 440, 440, 440, 440, 440, 440, 440, + 440, 440, 440, 440, 440, 440, nil, 986, 440, 440, + 440, nil, nil, 440, nil, nil, 440, nil, nil, 440, + 440, nil, 440, nil, 440, nil, 440, nil, 440, 440, + nil, 440, 440, 440, 440, 440, nil, 440, 440, 440, + nil, nil, 988, nil, 988, 988, 988, nil, 988, nil, + nil, nil, nil, 440, nil, nil, 440, 440, 440, 440, + nil, 440, 441, 440, nil, nil, nil, nil, 440, 441, + 441, 441, nil, nil, 441, 441, 441, 468, 441, 988, + 329, 329, 329, 329, 329, nil, nil, 441, 441, 441, + 441, nil, nil, 468, 468, nil, nil, nil, 441, 441, + nil, 441, 441, 441, 441, 441, nil, nil, nil, 468, + nil, 468, nil, 468, 468, nil, 468, 468, nil, nil, + 468, nil, 468, 505, 505, 505, 505, 505, 441, 441, + 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, + 441, 441, nil, nil, 441, 441, 441, nil, nil, 441, + nil, nil, 441, nil, nil, 441, 441, nil, 441, nil, + 441, nil, 441, nil, 441, 441, nil, 441, 441, 441, + 441, 441, nil, 441, 441, 441, nil, nil, 1019, nil, + 1019, 1019, 1019, nil, 1019, nil, nil, nil, nil, 441, + nil, nil, 441, 441, 441, 441, nil, 441, 482, 441, + nil, nil, nil, nil, 441, 482, 482, 482, nil, nil, + 482, 482, 482, 463, 482, 1019, nil, nil, nil, nil, + nil, nil, nil, 482, 482, nil, nil, nil, nil, 463, + 463, nil, nil, nil, 482, 482, nil, 482, 482, 482, + 482, 482, nil, nil, nil, 463, nil, 463, nil, 463, + 463, nil, 463, 463, nil, nil, nil, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, nil, 21, + 21, nil, nil, 21, 21, 482, nil, nil, nil, nil, + nil, nil, 482, nil, nil, nil, nil, 482, 482, 21, + nil, 21, nil, 21, 21, nil, 21, 21, 21, 21, + 21, nil, 21, nil, nil, nil, nil, nil, nil, nil, + 482, 482, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 21, nil, nil, 482, nil, nil, 482, nil, + nil, nil, nil, 482, 0, 0, 0, 0, 0, 0, + 482, nil, nil, 0, 0, nil, nil, nil, 0, nil, + 0, 0, 0, 0, 0, 0, 0, nil, nil, nil, + nil, nil, 0, 0, 0, 0, 0, 0, 0, nil, + nil, 0, nil, nil, nil, nil, 418, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, nil, + 0, 0, 0, nil, 0, 0, 0, 0, 0, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + nil, 418, 418, nil, nil, 418, 418, nil, 0, nil, + nil, 0, nil, nil, 0, 0, nil, nil, 0, nil, + 0, 418, nil, 418, 0, 418, 418, nil, 418, 418, + 418, 418, 418, 0, 418, nil, nil, nil, 0, 0, + 0, 0, nil, 0, 0, 0, 0, nil, nil, nil, + nil, 0, 0, nil, 418, nil, 418, nil, nil, 0, + nil, 0, 0, 0, 33, 33, 33, 33, 33, 33, + nil, nil, nil, 33, 33, nil, nil, nil, 33, nil, + 33, 33, 33, 33, 33, 33, 33, nil, nil, nil, + nil, nil, 33, 33, 33, 33, 33, 33, 33, nil, + nil, 33, nil, nil, nil, nil, 424, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, nil, + 33, 33, 33, nil, 33, 33, 33, 33, 33, 424, + 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, + nil, 424, 424, nil, nil, 424, 424, nil, 33, nil, + nil, 33, nil, nil, 33, 33, nil, nil, 33, nil, + 33, 424, nil, 424, 33, 424, 424, nil, 424, 424, + 424, 424, 424, 33, 424, nil, nil, nil, 33, 33, + 33, 33, nil, 33, 33, 33, 33, nil, nil, nil, + nil, 33, 33, nil, 424, nil, nil, nil, nil, 33, + nil, 33, 33, 33, 123, 123, 123, 123, 123, 123, + nil, nil, nil, 123, 123, nil, nil, nil, 123, nil, + 123, 123, 123, 123, 123, 123, 123, nil, nil, nil, + nil, nil, 123, 123, 123, 123, 123, 123, 123, nil, + nil, 123, nil, nil, nil, nil, nil, 123, 123, 123, + 123, 123, 123, 123, 123, 123, 123, 123, 123, nil, + 123, 123, 123, nil, 123, 123, 123, 123, 123, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + nil, 278, 278, nil, nil, 278, 278, nil, 123, nil, + nil, 123, nil, nil, 123, 123, nil, nil, 123, nil, + 123, 278, nil, 278, 123, 278, 278, nil, 278, 278, + 278, 278, 278, 123, 278, nil, nil, nil, 123, 123, + 123, 123, nil, 123, 123, 123, 123, nil, nil, nil, + nil, 123, 123, nil, 278, nil, nil, nil, nil, 123, + nil, 123, 123, 123, 208, 208, 208, 208, 208, 208, + nil, nil, nil, 208, 208, nil, nil, nil, 208, nil, + 208, 208, 208, 208, 208, 208, 208, nil, nil, nil, + nil, nil, 208, 208, 208, 208, 208, 208, 208, nil, + nil, 208, nil, nil, nil, nil, nil, 208, 208, 208, + 208, 208, 208, 208, 208, 208, 208, 208, 208, nil, + 208, 208, 208, nil, 208, 208, 208, 208, 208, 480, + 480, 480, 480, 480, 480, 480, 480, 480, 480, 480, + nil, 480, 480, nil, nil, 480, 480, nil, 208, nil, + nil, 208, nil, nil, 208, 208, nil, nil, 208, nil, + 208, 480, nil, 480, 208, 480, 480, nil, 480, 480, + 480, 480, 480, 208, 480, nil, nil, nil, 208, 208, + 208, 208, nil, 208, 208, 208, 208, nil, nil, nil, + nil, 208, 208, 480, 480, nil, nil, nil, nil, 208, + nil, 208, 208, 208, 233, 233, 233, 233, 233, 233, + nil, nil, nil, 233, 233, nil, nil, nil, 233, nil, + 233, 233, 233, 233, 233, 233, 233, nil, nil, nil, + nil, nil, 233, 233, 233, 233, 233, 233, 233, nil, + nil, 233, nil, nil, nil, nil, nil, 233, 233, 233, + 233, 233, 233, 233, 233, 233, 233, 233, 233, nil, + 233, 233, 233, nil, 233, 233, 233, 233, 233, 527, + 527, 527, 527, 527, 527, 527, 527, 527, 527, 527, + nil, 527, 527, nil, nil, 527, 527, nil, 233, nil, + nil, 233, nil, nil, 233, 233, nil, nil, 233, nil, + 233, 527, nil, 527, 233, 527, 527, nil, 527, 527, + 527, 527, 527, 233, 527, nil, nil, nil, 233, 233, + 233, 233, nil, 233, 233, 233, 233, nil, nil, nil, + nil, 233, 233, nil, 527, nil, nil, nil, nil, 233, + nil, 233, 233, 233, 298, 298, 298, 298, 298, 298, + nil, nil, nil, 298, 298, nil, nil, nil, 298, nil, + 298, 298, 298, 298, 298, 298, 298, nil, nil, nil, + nil, nil, 298, 298, 298, 298, 298, 298, 298, nil, + nil, 298, nil, nil, nil, nil, nil, 298, 298, 298, + 298, 298, 298, 298, 298, 298, 298, 298, 298, nil, + 298, 298, 298, nil, 298, 298, 298, 298, 298, 746, + 746, 746, 746, 746, 746, 746, 746, 746, 746, 746, + nil, 746, 746, nil, nil, 746, 746, nil, 298, nil, + nil, 298, nil, nil, 298, 298, nil, nil, 298, nil, + 298, 746, nil, 746, 298, 746, 746, nil, 746, 746, + 746, 746, 746, 298, 746, nil, nil, nil, 298, 298, + 298, 298, nil, 298, 298, 298, 298, nil, nil, nil, + nil, 298, 298, nil, 746, nil, nil, nil, nil, 298, + nil, 298, 298, 298, 303, 303, 303, 303, 303, 303, + nil, nil, nil, 303, 303, nil, nil, nil, 303, nil, + 303, 303, 303, 303, 303, 303, 303, nil, nil, nil, + nil, nil, 303, 303, 303, 303, 303, 303, 303, nil, + nil, 303, nil, nil, nil, nil, nil, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, 303, nil, + 303, 303, 303, nil, 303, 303, 303, 303, 303, 843, + 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, + nil, 843, 843, nil, nil, 843, 843, nil, 303, nil, + nil, 303, nil, nil, 303, 303, nil, nil, 303, nil, + 303, 843, nil, 843, 303, 843, 843, nil, 843, 843, + 843, 843, 843, 303, 843, nil, nil, nil, 303, 303, + 303, 303, nil, 303, 303, 303, 303, nil, nil, nil, + nil, 303, 303, nil, 843, nil, nil, nil, nil, 303, + nil, 303, 303, 303, 328, 328, 328, 328, 328, 328, + nil, nil, nil, 328, 328, nil, nil, nil, 328, nil, + 328, 328, 328, 328, 328, 328, 328, nil, nil, nil, + nil, nil, 328, 328, 328, 328, 328, 328, 328, nil, + nil, 328, nil, nil, nil, nil, nil, 328, 328, 328, + 328, 328, 328, 328, 328, 328, 328, 328, 328, nil, + 328, 328, 328, nil, 328, 328, 328, 328, 328, 455, + 455, 455, 455, 455, 455, 455, 455, 455, 455, 455, + nil, 455, 455, nil, nil, 455, 455, nil, 328, nil, + nil, 328, nil, nil, 328, 328, nil, nil, 328, nil, + 328, 455, nil, 455, 328, 455, 455, nil, 455, 455, + 455, 455, 455, 328, 455, nil, nil, nil, 328, 328, + 328, 328, nil, 328, 328, 328, 328, nil, nil, nil, + nil, 328, 328, nil, nil, nil, nil, nil, nil, 328, + nil, 328, 328, 328, 506, 506, 506, 506, 506, 506, + nil, nil, nil, 506, 506, nil, nil, nil, 506, nil, + 506, 506, 506, 506, 506, 506, 506, nil, nil, nil, + nil, nil, 506, 506, 506, 506, 506, 506, 506, nil, + nil, 506, nil, nil, nil, nil, nil, 506, 506, 506, + 506, 506, 506, 506, 506, 506, 506, 506, 506, nil, + 506, 506, 506, nil, 506, 506, 506, 506, 506, 456, + 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, + nil, 456, 456, nil, nil, 456, 456, nil, 506, nil, + nil, 506, nil, nil, 506, 506, nil, nil, 506, nil, + 506, 456, nil, 456, 506, 456, 456, nil, 456, 456, + 456, 456, 456, 506, 456, nil, nil, nil, 506, 506, + 506, 506, nil, 506, 506, 506, 506, nil, nil, nil, + nil, 506, 506, nil, nil, nil, nil, nil, nil, 506, + nil, 506, 506, 506, 543, 543, 543, 543, 543, 543, + nil, nil, nil, 543, 543, nil, nil, nil, 543, nil, + 543, 543, 543, 543, 543, 543, 543, nil, nil, nil, + nil, nil, 543, 543, 543, 543, 543, 543, 543, nil, + nil, 543, nil, nil, nil, nil, nil, 543, 543, 543, + 543, 543, 543, 543, 543, 543, 543, 543, 543, nil, + 543, 543, 543, nil, 543, 543, 543, 543, 543, 466, + 466, 466, 466, 466, 466, 466, nil, nil, 466, 466, + nil, nil, nil, nil, nil, 466, 466, nil, 543, nil, + nil, 543, nil, nil, 543, 543, nil, nil, 543, nil, + 543, 466, nil, 466, 543, 466, 466, nil, 466, 466, + 466, 466, 466, 543, 466, nil, nil, nil, 543, 543, + 543, 543, nil, 543, 543, 543, 543, nil, nil, nil, + nil, 543, 543, nil, nil, nil, nil, nil, nil, 543, + nil, 543, 543, 543, 546, 546, 546, 546, 546, 546, + nil, nil, nil, 546, 546, nil, nil, nil, 546, nil, + 546, 546, 546, 546, 546, 546, 546, nil, nil, nil, + nil, nil, 546, 546, 546, 546, 546, 546, 546, nil, + nil, 546, nil, nil, nil, nil, nil, 546, 546, 546, + 546, 546, 546, 546, 546, 546, 546, 546, 546, nil, + 546, 546, 546, nil, 546, 546, 546, 546, 546, 469, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 469, 469, nil, 546, nil, + nil, 546, nil, nil, 546, 546, nil, nil, 546, nil, + 546, 469, nil, 469, 546, 469, 469, nil, 469, 469, + nil, nil, 469, 546, 469, nil, nil, nil, 546, 546, + 546, 546, nil, 546, 546, 546, 546, nil, nil, nil, + nil, 546, 546, nil, nil, nil, nil, nil, nil, 546, + nil, 546, 546, 546, 566, 566, 566, 566, 566, 566, + nil, nil, nil, 566, 566, nil, nil, nil, 566, nil, + 566, 566, 566, 566, 566, 566, 566, nil, nil, nil, + nil, nil, 566, 566, 566, 566, 566, 566, 566, nil, + nil, 566, nil, nil, nil, nil, nil, 566, 566, 566, + 566, 566, 566, 566, 566, 566, 566, 566, 566, nil, + 566, 566, 566, nil, 566, 566, 566, 566, 566, 470, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 470, 470, nil, 566, nil, + nil, 566, nil, nil, 566, 566, nil, nil, 566, nil, + 566, 470, nil, 470, 566, 470, 470, nil, 470, 470, + nil, nil, 470, 566, 470, nil, nil, nil, 566, 566, + 566, 566, nil, 566, 566, 566, 566, nil, nil, nil, + nil, 566, 566, nil, nil, nil, nil, nil, nil, 566, + nil, 566, 566, 566, 716, 716, 716, 716, 716, 716, + nil, nil, nil, 716, 716, nil, nil, nil, 716, nil, + 716, 716, 716, 716, 716, 716, 716, nil, nil, nil, + nil, nil, 716, 716, 716, 716, 716, 716, 716, nil, + nil, 716, nil, nil, nil, nil, nil, 716, 716, 716, + 716, 716, 716, 716, 716, 716, 716, 716, 716, nil, + 716, 716, 716, nil, 716, 716, 716, 716, 716, 471, + 471, 471, 471, 471, 471, 471, nil, nil, 471, 471, + nil, nil, nil, nil, nil, 471, 471, nil, 716, nil, + nil, 716, nil, nil, 716, 716, nil, nil, 716, nil, + 716, 471, nil, 471, 716, 471, 471, nil, 471, 471, + 471, 471, 471, 716, 471, nil, nil, nil, 716, 716, + 716, 716, nil, 716, 716, 716, 716, nil, nil, nil, + nil, 716, 716, nil, nil, nil, nil, nil, nil, 716, + nil, 716, 716, 716, 720, 720, 720, 720, 720, 720, + nil, nil, nil, 720, 720, nil, nil, nil, 720, nil, + 720, 720, 720, 720, 720, 720, 720, nil, nil, nil, + nil, nil, 720, 720, 720, 720, 720, 720, 720, nil, + nil, 720, nil, nil, nil, nil, nil, 720, 720, 720, + 720, 720, 720, 720, 720, 720, 720, 720, 720, nil, + 720, 720, 720, nil, 720, 720, 720, 720, 720, 472, + 472, 472, 472, 472, 472, 472, nil, nil, 472, 472, + nil, nil, nil, nil, nil, 472, 472, nil, 720, nil, + nil, 720, nil, nil, 720, 720, nil, nil, 720, nil, + 720, 472, nil, 472, 720, 472, 472, nil, 472, 472, + 472, 472, 472, 720, 472, nil, nil, nil, 720, 720, + 720, 720, nil, 720, 720, 720, 720, nil, nil, nil, + nil, 720, 720, nil, nil, nil, nil, nil, nil, 720, + nil, 720, 720, 720, 730, 730, 730, 730, 730, 730, + nil, nil, nil, 730, 730, nil, nil, nil, 730, nil, + 730, 730, 730, 730, 730, 730, 730, nil, nil, nil, + nil, nil, 730, 730, 730, 730, 730, 730, 730, nil, + nil, 730, nil, nil, nil, nil, nil, 730, 730, 730, + 730, 730, 730, 730, 730, 730, 730, 730, 730, nil, + 730, 730, 730, nil, 730, 730, 730, 730, 730, 473, + 473, 473, 473, 473, 473, 473, nil, nil, 473, 473, + nil, nil, nil, nil, nil, 473, 473, nil, 730, nil, + nil, 730, nil, nil, 730, 730, nil, nil, 730, nil, + 730, 473, nil, 473, 730, 473, 473, nil, 473, 473, + 473, 473, 473, 730, 473, nil, nil, nil, 730, 730, + 730, 730, nil, 730, 730, 730, 730, nil, nil, nil, + nil, 730, 730, nil, nil, nil, nil, nil, nil, 730, + nil, 730, 730, 730, 775, 775, 775, 775, 775, 775, + nil, nil, nil, 775, 775, nil, nil, nil, 775, nil, + 775, 775, 775, 775, 775, 775, 775, nil, nil, nil, + nil, nil, 775, 775, 775, 775, 775, 775, 775, nil, + nil, 775, nil, nil, nil, nil, nil, 775, 775, 775, + 775, 775, 775, 775, 775, 775, 775, 775, 775, nil, + 775, 775, 775, nil, 775, 775, 775, 775, 775, 474, + 474, 474, 474, 474, 474, 474, nil, nil, 474, 474, + nil, nil, nil, nil, nil, 474, 474, nil, 775, nil, + nil, 775, nil, nil, 775, 775, nil, nil, 775, nil, + 775, 474, nil, 474, 775, 474, 474, nil, 474, 474, + 474, 474, 474, 775, 474, nil, nil, nil, 775, 775, + 775, 775, nil, 775, 775, 775, 775, nil, nil, nil, + nil, 775, 775, nil, nil, nil, nil, nil, nil, 775, + nil, 775, 775, 775, 787, 787, 787, 787, 787, 787, + nil, nil, nil, 787, 787, nil, nil, nil, 787, nil, + 787, 787, 787, 787, 787, 787, 787, nil, nil, nil, + nil, nil, 787, 787, 787, 787, 787, 787, 787, nil, + nil, 787, nil, nil, nil, nil, nil, 787, 787, 787, + 787, 787, 787, 787, 787, 787, 787, 787, 787, nil, + 787, 787, 787, nil, 787, 787, 787, 787, 787, 475, + 475, 475, 475, 475, 475, 475, nil, nil, 475, 475, + nil, nil, nil, nil, nil, 475, 475, nil, 787, nil, + nil, 787, nil, nil, 787, 787, nil, nil, 787, nil, + 787, 475, nil, 475, 787, 475, 475, nil, 475, 475, + 475, 475, 475, 787, 475, nil, nil, nil, 787, 787, + 787, 787, nil, 787, 787, 787, 787, nil, nil, nil, + nil, 787, 787, nil, nil, nil, nil, nil, nil, 787, + nil, 787, 787, 787, 820, 820, 820, 820, 820, 820, + nil, nil, nil, 820, 820, nil, nil, nil, 820, nil, + 820, 820, 820, 820, 820, 820, 820, nil, nil, nil, + nil, nil, 820, 820, 820, 820, 820, 820, 820, nil, + nil, 820, nil, nil, nil, nil, nil, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, 820, nil, + 820, 820, 820, nil, 820, 820, 820, 820, 820, 478, + 478, 478, 478, 478, 478, 478, nil, nil, 478, 478, + nil, nil, nil, nil, nil, 478, 478, nil, 820, nil, + nil, 820, nil, nil, 820, 820, nil, nil, 820, nil, + 820, 478, nil, 478, 820, 478, 478, nil, 478, 478, + 478, 478, 478, 820, 478, nil, nil, nil, 820, 820, + 820, 820, nil, 820, 820, 820, 820, nil, nil, nil, + nil, 820, 820, nil, nil, nil, nil, nil, nil, 820, + nil, 820, 820, 820, 821, 821, 821, 821, 821, 821, + nil, nil, nil, 821, 821, nil, nil, nil, 821, nil, + 821, 821, 821, 821, 821, 821, 821, nil, nil, nil, + nil, nil, 821, 821, 821, 821, 821, 821, 821, nil, + nil, 821, nil, nil, nil, nil, nil, 821, 821, 821, + 821, 821, 821, 821, 821, 821, 821, 821, 821, nil, + 821, 821, 821, nil, 821, 821, 821, 821, 821, 479, + 479, 479, 479, 479, 479, 479, 479, nil, 479, 479, + nil, nil, nil, nil, nil, 479, 479, nil, 821, nil, + nil, 821, nil, nil, 821, 821, nil, nil, 821, nil, + 821, 479, nil, 479, 821, 479, 479, nil, 479, 479, + 479, 479, 479, 821, 479, nil, nil, nil, 821, 821, + 821, 821, nil, 821, 821, 821, 821, nil, nil, nil, + nil, 821, 821, nil, nil, nil, nil, nil, nil, 821, + nil, 821, 821, 821, 824, 824, 824, 824, 824, 824, + nil, nil, nil, 824, 824, nil, nil, nil, 824, nil, + 824, 824, 824, 824, 824, 824, 824, nil, nil, nil, + nil, nil, 824, 824, 824, 824, 824, 824, 824, nil, + nil, 824, nil, nil, nil, nil, nil, 824, 824, 824, + 824, 824, 824, 824, 824, 824, 824, 824, 824, nil, + 824, 824, 824, nil, 824, 824, 824, 824, 824, 464, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 464, 464, nil, 824, nil, + nil, 824, nil, nil, 824, 824, nil, nil, 824, nil, + 824, 464, nil, 464, 824, 464, 464, nil, 464, 464, + nil, nil, nil, 824, nil, nil, nil, nil, 824, 824, + 824, 824, nil, 824, 824, 824, 824, nil, nil, nil, + nil, 824, 824, nil, nil, nil, nil, nil, nil, 824, + nil, 824, 824, 824, 830, 830, 830, 830, 830, 830, + nil, nil, nil, 830, 830, nil, nil, nil, 830, nil, + 830, 830, 830, 830, 830, 830, 830, nil, nil, nil, + nil, nil, 830, 830, 830, 830, 830, 830, 830, nil, + nil, 830, nil, nil, nil, nil, nil, 830, 830, 830, + 830, 830, 830, 830, 830, 830, 830, 830, 830, nil, + 830, 830, 830, nil, 830, 830, 830, 830, 830, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 830, nil, + nil, 830, nil, nil, 830, 830, nil, nil, 830, nil, + 830, nil, nil, nil, 830, nil, nil, nil, nil, nil, + nil, nil, nil, 830, nil, nil, nil, nil, 830, 830, + 830, 830, nil, 830, 830, 830, 830, nil, nil, nil, + nil, 830, 830, nil, nil, nil, nil, nil, nil, 830, + nil, 830, 830, 830, 844, 844, 844, 844, 844, 844, + nil, nil, nil, 844, 844, nil, nil, nil, 844, nil, + 844, 844, 844, 844, 844, 844, 844, nil, nil, nil, + nil, nil, 844, 844, 844, 844, 844, 844, 844, nil, + nil, 844, nil, nil, nil, nil, nil, 844, 844, 844, + 844, 844, 844, 844, 844, 844, 844, 844, 844, nil, + 844, 844, 844, nil, 844, 844, 844, 844, 844, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 844, nil, + nil, 844, nil, nil, 844, 844, nil, nil, 844, nil, + 844, nil, nil, nil, 844, nil, nil, nil, nil, nil, + nil, nil, nil, 844, nil, nil, nil, nil, 844, 844, + 844, 844, nil, 844, 844, 844, 844, nil, nil, nil, + nil, 844, 844, nil, nil, nil, nil, nil, nil, 844, + nil, 844, 844, 844, 862, 862, 862, 862, 862, 862, + nil, nil, nil, 862, 862, nil, nil, nil, 862, nil, + 862, 862, 862, 862, 862, 862, 862, nil, nil, nil, + nil, nil, 862, 862, 862, 862, 862, 862, 862, nil, + nil, 862, nil, nil, nil, nil, nil, 862, 862, 862, + 862, 862, 862, 862, 862, 862, 862, 862, 862, nil, + 862, 862, 862, nil, 862, 862, 862, 862, 862, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 862, nil, + nil, 862, nil, nil, 862, 862, nil, nil, 862, nil, + 862, nil, nil, nil, 862, nil, nil, nil, nil, nil, + nil, nil, nil, 862, nil, nil, nil, nil, 862, 862, + 862, 862, nil, 862, 862, 862, 862, nil, nil, nil, + nil, 862, 862, nil, nil, nil, nil, nil, nil, 862, + nil, 862, 862, 862, 923, 923, 923, 923, 923, 923, + nil, nil, nil, 923, 923, nil, nil, nil, 923, nil, + 923, 923, 923, 923, 923, 923, 923, nil, nil, nil, + nil, nil, 923, 923, 923, 923, 923, 923, 923, nil, + nil, 923, nil, nil, nil, nil, nil, 923, 923, 923, + 923, 923, 923, 923, 923, 923, 923, 923, 923, nil, + 923, 923, 923, nil, 923, 923, 923, 923, 923, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 923, nil, + nil, 923, nil, nil, 923, 923, nil, nil, 923, nil, + 923, nil, nil, nil, 923, nil, nil, nil, nil, nil, + nil, nil, nil, 923, nil, nil, nil, nil, 923, 923, + 923, 923, nil, 923, 923, 923, 923, nil, nil, nil, + nil, 923, 923, nil, nil, nil, nil, nil, nil, 923, + nil, 923, 923, 923, 930, 930, 930, 930, 930, 930, + nil, nil, nil, 930, 930, nil, nil, nil, 930, nil, + 930, 930, 930, 930, 930, 930, 930, nil, nil, nil, + nil, nil, 930, 930, 930, 930, 930, 930, 930, nil, + nil, 930, nil, nil, nil, nil, nil, 930, 930, 930, + 930, 930, 930, 930, 930, 930, 930, 930, 930, nil, + 930, 930, 930, nil, 930, 930, 930, 930, 930, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 930, nil, + nil, 930, nil, nil, 930, 930, nil, nil, 930, nil, + 930, nil, nil, nil, 930, nil, nil, nil, nil, nil, + nil, nil, nil, 930, nil, nil, nil, nil, 930, 930, + 930, 930, nil, 930, 930, 930, 930, nil, nil, nil, + nil, 930, 930, nil, nil, nil, nil, nil, nil, 930, + nil, 930, 930, 930, 931, 931, 931, 931, 931, 931, + nil, nil, nil, 931, 931, nil, nil, nil, 931, nil, + 931, 931, 931, 931, 931, 931, 931, nil, nil, nil, + nil, nil, 931, 931, 931, 931, 931, 931, 931, nil, + nil, 931, nil, nil, nil, nil, nil, 931, 931, 931, + 931, 931, 931, 931, 931, 931, 931, 931, 931, nil, + 931, 931, 931, nil, 931, 931, 931, 931, 931, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 931, nil, + nil, 931, nil, nil, 931, 931, nil, nil, 931, nil, + 931, nil, nil, nil, 931, nil, nil, nil, nil, nil, + nil, nil, nil, 931, nil, nil, nil, nil, 931, 931, + 931, 931, nil, 931, 931, 931, 931, nil, nil, nil, + nil, 931, 931, nil, nil, nil, nil, nil, nil, 931, + nil, 931, 931, 931, 948, 948, 948, 948, 948, 948, + nil, nil, nil, 948, 948, nil, nil, nil, 948, nil, + 948, 948, 948, 948, 948, 948, 948, nil, nil, nil, + nil, nil, 948, 948, 948, 948, 948, 948, 948, nil, + nil, 948, nil, nil, nil, nil, nil, 948, 948, 948, + 948, 948, 948, 948, 948, 948, 948, 948, 948, nil, + 948, 948, 948, nil, 948, 948, 948, 948, 948, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 948, nil, + nil, 948, nil, nil, 948, 948, nil, nil, 948, nil, + 948, nil, nil, nil, 948, nil, nil, nil, nil, nil, + nil, nil, nil, 948, nil, nil, nil, nil, 948, 948, + 948, 948, nil, 948, 948, 948, 948, nil, nil, nil, + nil, 948, 948, nil, nil, nil, nil, nil, nil, 948, + nil, 948, 948, 948, 954, 954, 954, 954, 954, 954, + nil, nil, nil, 954, 954, nil, nil, nil, 954, nil, + 954, 954, 954, 954, 954, 954, 954, nil, nil, nil, + nil, nil, 954, 954, 954, 954, 954, 954, 954, nil, + nil, 954, nil, nil, nil, nil, nil, 954, 954, 954, + 954, 954, 954, 954, 954, 954, 954, 954, 954, nil, + 954, 954, 954, nil, 954, 954, 954, 954, 954, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 954, nil, + nil, 954, nil, nil, 954, 954, nil, nil, 954, nil, + 954, nil, nil, nil, 954, nil, nil, nil, nil, nil, + nil, nil, nil, 954, nil, nil, nil, nil, 954, 954, + 954, 954, nil, 954, 954, 954, 954, nil, nil, nil, + nil, 954, 954, nil, nil, nil, nil, nil, nil, 954, + nil, 954, 954, 954, 956, 956, 956, 956, 956, 956, + nil, nil, nil, 956, 956, nil, nil, nil, 956, nil, + 956, 956, 956, 956, 956, 956, 956, nil, nil, nil, + nil, nil, 956, 956, 956, 956, 956, 956, 956, nil, + nil, 956, nil, nil, nil, nil, nil, 956, 956, 956, + 956, 956, 956, 956, 956, 956, 956, 956, 956, nil, + 956, 956, 956, nil, 956, 956, 956, 956, 956, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 956, nil, + nil, 956, nil, nil, 956, 956, nil, nil, 956, nil, + 956, nil, nil, nil, 956, nil, nil, nil, nil, nil, + nil, nil, nil, 956, nil, nil, nil, nil, 956, 956, + 956, 956, nil, 956, 956, 956, 956, nil, nil, nil, + nil, 956, 956, nil, nil, nil, nil, nil, nil, 956, + nil, 956, 956, 956, 5, 5, 5, 5, 5, nil, + nil, nil, 5, 5, nil, nil, nil, 5, nil, 5, + 5, 5, 5, 5, 5, 5, nil, nil, nil, nil, + nil, 5, 5, 5, 5, 5, 5, 5, nil, nil, + 5, nil, nil, nil, nil, nil, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, nil, 5, + 5, 5, nil, 5, 5, 5, 5, 5, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 5, nil, nil, + 5, nil, nil, 5, 5, nil, nil, 5, nil, 5, + nil, nil, nil, 5, nil, nil, nil, nil, nil, nil, + nil, nil, 5, nil, nil, nil, nil, 5, 5, 5, + 5, nil, 5, 5, 5, 5, nil, nil, nil, nil, + 5, 5, nil, nil, nil, 20, 20, 20, 5, 20, + 5, 5, 5, 20, 20, nil, nil, nil, 20, nil, + 20, 20, 20, 20, 20, 20, 20, nil, nil, nil, + nil, nil, 20, 20, 20, 20, 20, 20, 20, nil, + nil, 20, nil, nil, nil, nil, nil, nil, 20, nil, + nil, 20, 20, 20, 20, 20, 20, 20, 20, nil, + 20, 20, 20, nil, 20, 20, 20, 20, 20, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, 20, nil, nil, 20, 20, nil, nil, 20, nil, + nil, nil, nil, nil, 20, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 20, 20, + 20, 20, nil, 20, 20, 20, 20, nil, nil, nil, + nil, 20, 20, nil, nil, nil, 29, 29, 29, 20, + 29, 20, 20, 20, 29, 29, nil, nil, nil, 29, + nil, 29, 29, 29, 29, 29, 29, 29, nil, nil, + nil, nil, nil, 29, 29, 29, 29, 29, 29, 29, + nil, nil, 29, nil, nil, nil, nil, nil, nil, 29, + nil, nil, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, nil, 29, 29, 29, 29, 29, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 29, + nil, nil, 29, nil, nil, 29, 29, nil, nil, 29, + nil, 29, nil, 29, nil, 29, nil, nil, 29, nil, + nil, nil, nil, nil, 29, nil, nil, nil, nil, 29, + 29, 29, 29, nil, 29, 29, 29, 29, nil, nil, + nil, nil, 29, 29, nil, nil, nil, 30, 30, 30, + 29, 30, 29, 29, 29, 30, 30, nil, nil, nil, + 30, nil, 30, 30, 30, 30, 30, 30, 30, nil, + nil, nil, nil, nil, 30, 30, 30, 30, 30, 30, + 30, nil, nil, 30, nil, nil, nil, nil, nil, nil, + 30, nil, nil, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, nil, 30, 30, 30, 30, + 30, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 30, nil, nil, 30, nil, nil, 30, 30, nil, nil, + 30, nil, 30, nil, 30, nil, 30, nil, nil, 30, + nil, nil, nil, nil, nil, 30, nil, nil, nil, nil, + 30, 30, 30, 30, nil, 30, 30, 30, 30, nil, + nil, nil, nil, 30, 30, nil, nil, nil, 31, 31, + 31, 30, 31, 30, 30, 30, 31, 31, nil, nil, + nil, 31, nil, 31, 31, 31, 31, 31, 31, 31, + nil, nil, nil, nil, nil, 31, 31, 31, 31, 31, + 31, 31, nil, nil, 31, nil, nil, nil, nil, nil, + nil, 31, nil, nil, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, nil, 31, 31, 31, + 31, 31, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 31, nil, nil, 31, nil, nil, 31, 31, nil, + nil, 31, nil, 31, nil, 31, nil, 31, nil, nil, + 31, nil, nil, nil, nil, nil, 31, nil, nil, nil, + nil, 31, 31, 31, 31, nil, 31, 31, 31, 31, + nil, nil, nil, nil, 31, 31, nil, nil, nil, 34, + 34, 34, 31, 34, 31, 31, 31, 34, 34, nil, + nil, nil, 34, nil, 34, 34, 34, 34, 34, 34, + 34, nil, nil, nil, nil, nil, 34, 34, 34, 34, + 34, 34, 34, nil, nil, 34, nil, nil, nil, nil, + nil, nil, 34, nil, nil, 34, 34, 34, 34, 34, + 34, 34, 34, nil, 34, 34, 34, nil, 34, 34, + nil, nil, 34, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 34, nil, nil, 34, nil, nil, 34, 34, + nil, nil, 34, nil, 34, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 34, 34, 34, 34, nil, 34, 34, 34, + 34, nil, nil, nil, nil, 34, 34, nil, nil, nil, + 35, 35, 35, 34, 35, 34, 34, 34, 35, 35, + nil, nil, nil, 35, nil, 35, 35, 35, 35, 35, + 35, 35, nil, nil, nil, nil, nil, 35, 35, 35, + 35, 35, 35, 35, nil, nil, 35, nil, nil, nil, + nil, nil, nil, 35, nil, nil, 35, 35, 35, 35, + 35, 35, 35, 35, nil, 35, 35, 35, nil, 35, + 35, nil, nil, 35, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 35, nil, nil, 35, nil, nil, 35, + 35, nil, nil, 35, nil, nil, 914, nil, 914, 914, + 914, 914, 914, nil, nil, nil, nil, nil, nil, nil, + nil, 914, nil, 35, 35, 35, 35, nil, 35, 35, + 35, 35, nil, nil, nil, nil, 35, 35, nil, nil, + nil, 35, nil, 914, 35, nil, 35, 35, 35, 42, + 42, 42, nil, 42, 914, 914, nil, 42, 42, 914, + nil, nil, 42, nil, 42, 42, 42, 42, 42, 42, + 42, nil, nil, nil, nil, nil, 42, 42, 42, 42, + 42, 42, 42, nil, nil, 42, nil, nil, nil, nil, + nil, nil, 42, nil, nil, 42, 42, 42, 42, 42, + 42, 42, 42, nil, 42, 42, 42, nil, 42, 42, + 42, 42, 42, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 42, nil, nil, 42, nil, nil, 42, 42, + nil, nil, 42, nil, nil, nil, nil, nil, 42, nil, + nil, nil, nil, nil, nil, nil, nil, 42, nil, nil, + nil, nil, 42, 42, 42, 42, nil, 42, 42, 42, + 42, nil, nil, nil, nil, 42, 42, nil, nil, nil, + 43, 43, 43, 42, 43, 42, 42, 42, 43, 43, + nil, nil, nil, 43, nil, 43, 43, 43, 43, 43, + 43, 43, nil, nil, nil, nil, nil, 43, 43, 43, + 43, 43, 43, 43, nil, nil, 43, nil, nil, nil, + nil, nil, nil, 43, nil, nil, 43, 43, 43, 43, + 43, 43, 43, 43, nil, 43, 43, 43, nil, 43, + 43, 43, 43, 43, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 43, nil, nil, 43, nil, nil, 43, + 43, nil, nil, 43, nil, nil, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, nil, 43, nil, + nil, nil, nil, 43, 43, 43, 43, nil, 43, 43, + 43, 43, nil, nil, nil, nil, 43, 43, nil, nil, + nil, 44, 44, 44, 43, 44, 43, 43, 43, 44, + 44, nil, nil, nil, 44, nil, 44, 44, 44, 44, + 44, 44, 44, nil, nil, nil, nil, nil, 44, 44, + 44, 44, 44, 44, 44, nil, nil, 44, nil, nil, + nil, nil, nil, nil, 44, nil, nil, 44, 44, 44, + 44, 44, 44, 44, 44, nil, 44, 44, 44, nil, + 44, 44, 44, 44, 44, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 44, nil, nil, 44, nil, nil, + 44, 44, nil, nil, 44, nil, nil, nil, nil, nil, + 44, nil, nil, nil, nil, nil, nil, nil, nil, 44, + nil, nil, nil, nil, 44, 44, 44, 44, nil, 44, + 44, 44, 44, nil, nil, nil, nil, 44, 44, nil, + nil, nil, nil, nil, nil, 44, nil, 44, 44, 44, + 58, 58, 58, 58, 58, nil, nil, nil, 58, 58, + nil, nil, nil, 58, nil, 58, 58, 58, 58, 58, + 58, 58, nil, nil, nil, nil, nil, 58, 58, 58, + 58, 58, 58, 58, nil, nil, 58, nil, nil, nil, + nil, nil, 58, 58, nil, 58, 58, 58, 58, 58, + 58, 58, 58, 58, nil, 58, 58, 58, nil, 58, + 58, 58, 58, 58, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 58, nil, nil, 58, nil, nil, 58, + 58, nil, nil, 58, nil, 58, nil, nil, nil, 58, + nil, nil, nil, nil, nil, nil, nil, nil, 58, nil, + nil, nil, nil, 58, 58, 58, 58, nil, 58, 58, + 58, 58, nil, nil, nil, nil, 58, 58, nil, nil, + nil, 59, 59, 59, 58, 59, 58, 58, 58, 59, + 59, nil, nil, nil, 59, nil, 59, 59, 59, 59, + 59, 59, 59, nil, nil, nil, nil, nil, 59, 59, + 59, 59, 59, 59, 59, nil, nil, 59, nil, nil, + nil, nil, nil, nil, 59, nil, nil, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, nil, + 59, 59, 59, 59, 59, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 59, nil, nil, 59, nil, nil, + 59, 59, nil, nil, 59, nil, 59, nil, nil, nil, + 59, nil, nil, 59, nil, nil, nil, nil, nil, 59, + nil, nil, nil, nil, 59, 59, 59, 59, nil, 59, + 59, 59, 59, nil, nil, nil, nil, 59, 59, nil, + nil, nil, 60, 60, 60, 59, 60, 59, 59, 59, + 60, 60, nil, nil, nil, 60, nil, 60, 60, 60, + 60, 60, 60, 60, nil, nil, nil, nil, nil, 60, + 60, 60, 60, 60, 60, 60, nil, nil, 60, nil, + nil, nil, nil, nil, nil, 60, nil, nil, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + nil, 60, 60, 60, 60, 60, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 60, nil, nil, 60, nil, + nil, 60, 60, nil, nil, 60, nil, nil, nil, nil, + nil, 60, nil, nil, 60, nil, nil, nil, nil, nil, + 60, nil, nil, nil, nil, 60, 60, 60, 60, nil, + 60, 60, 60, 60, nil, nil, nil, nil, 60, 60, + nil, nil, nil, 63, 63, 63, 60, 63, 60, 60, + 60, 63, 63, nil, nil, nil, 63, nil, 63, 63, + 63, 63, 63, 63, 63, nil, nil, nil, nil, nil, + 63, 63, 63, 63, 63, 63, 63, nil, nil, 63, + nil, nil, nil, nil, nil, nil, 63, nil, nil, 63, + 63, 63, 63, 63, 63, 63, 63, nil, 63, 63, + 63, nil, 63, 63, 63, 63, 63, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 63, nil, nil, 63, + nil, nil, 63, 63, nil, nil, 63, nil, nil, nil, + nil, nil, 63, nil, nil, nil, nil, nil, nil, nil, + nil, 63, nil, nil, nil, nil, 63, 63, 63, 63, + nil, 63, 63, 63, 63, nil, nil, nil, nil, 63, + 63, nil, nil, nil, 64, 64, 64, 63, 64, 63, + 63, 63, 64, 64, nil, nil, nil, 64, nil, 64, + 64, 64, 64, 64, 64, 64, nil, nil, nil, nil, + nil, 64, 64, 64, 64, 64, 64, 64, nil, nil, + 64, nil, nil, nil, nil, nil, nil, 64, nil, nil, + 64, 64, 64, 64, 64, 64, 64, 64, nil, 64, + 64, 64, nil, 64, 64, 64, 64, 64, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 64, nil, nil, + 64, nil, nil, 64, 64, nil, nil, 64, nil, nil, + nil, nil, nil, 64, nil, nil, nil, nil, nil, nil, + nil, nil, 64, nil, nil, nil, nil, 64, 64, 64, + 64, nil, 64, 64, 64, 64, nil, nil, nil, nil, + 64, 64, nil, nil, nil, 67, 67, 67, 64, 67, + 64, 64, 64, 67, 67, nil, nil, nil, 67, nil, + 67, 67, 67, 67, 67, 67, 67, nil, nil, nil, + nil, nil, 67, 67, 67, 67, 67, 67, 67, nil, + nil, 67, nil, nil, nil, nil, nil, nil, 67, nil, + nil, 67, 67, 67, 67, 67, 67, 67, 67, nil, + 67, 67, 67, nil, 67, 67, 67, 67, 67, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 67, nil, + nil, 67, nil, nil, 67, 67, nil, nil, 67, nil, + nil, nil, nil, nil, 67, nil, nil, nil, nil, nil, + nil, nil, nil, 67, nil, nil, nil, nil, 67, 67, + 67, 67, nil, 67, 67, 67, 67, nil, nil, nil, + nil, 67, 67, 67, nil, nil, nil, nil, 67, 67, + nil, 67, 67, 67, 68, 68, 68, nil, 68, nil, + nil, nil, 68, 68, nil, nil, nil, 68, nil, 68, + 68, 68, 68, 68, 68, 68, nil, nil, nil, nil, + nil, 68, 68, 68, 68, 68, 68, 68, nil, nil, + 68, nil, nil, nil, nil, nil, nil, 68, nil, nil, + 68, 68, 68, 68, 68, 68, 68, 68, nil, 68, + 68, 68, nil, 68, 68, nil, nil, 68, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 68, nil, nil, + 68, nil, nil, 68, 68, nil, nil, 68, nil, 68, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 68, 68, 68, + 68, nil, 68, 68, 68, 68, nil, nil, nil, nil, + 68, 68, nil, nil, nil, 69, 69, 69, 68, 69, + 68, 68, 68, 69, 69, nil, nil, nil, 69, nil, + 69, 69, 69, 69, 69, 69, 69, nil, nil, nil, + nil, nil, 69, 69, 69, 69, 69, 69, 69, nil, + nil, 69, nil, nil, nil, nil, nil, nil, 69, nil, + nil, 69, 69, 69, 69, 69, 69, 69, 69, nil, + 69, 69, 69, nil, 69, 69, nil, nil, 69, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 69, nil, nil, 69, nil, + nil, 69, nil, nil, 69, 69, nil, nil, 69, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 69, 69, + 69, 69, nil, 69, 69, 69, 69, nil, nil, nil, + nil, 69, 69, nil, nil, nil, 70, 70, 70, 69, + 70, 69, 69, 69, 70, 70, nil, nil, nil, 70, + nil, 70, 70, 70, 70, 70, 70, 70, nil, nil, + nil, nil, nil, 70, 70, 70, 70, 70, 70, 70, + nil, nil, 70, nil, nil, nil, nil, nil, nil, 70, + nil, nil, 70, 70, 70, 70, 70, 70, 70, 70, + nil, 70, 70, 70, nil, 70, 70, nil, nil, 70, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 70, + nil, nil, 70, nil, nil, 70, 70, nil, nil, 70, + nil, nil, 936, nil, 936, 936, 936, 936, 936, nil, + nil, nil, nil, nil, nil, nil, nil, 936, nil, 70, + 70, 70, 70, nil, 70, 70, 70, 70, nil, nil, + nil, nil, 70, 70, nil, nil, nil, nil, nil, 936, + 70, nil, 70, 70, 70, 113, 113, 113, 113, 113, + 936, 936, nil, 113, 113, 936, nil, nil, 113, nil, + 113, 113, 113, 113, 113, 113, 113, nil, nil, nil, + nil, nil, 113, 113, 113, 113, 113, 113, 113, nil, + nil, 113, nil, nil, nil, nil, nil, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, nil, + 113, 113, 113, nil, 113, 113, 113, 113, 113, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 113, nil, + nil, 113, nil, nil, 113, 113, nil, nil, 113, nil, + 113, nil, nil, nil, 113, nil, nil, nil, nil, nil, + nil, nil, nil, 113, nil, nil, nil, nil, 113, 113, + 113, 113, nil, 113, 113, 113, 113, nil, nil, nil, + nil, 113, 113, nil, nil, nil, nil, nil, 113, 113, + nil, 113, 113, 113, 118, 118, 118, nil, 118, nil, + nil, nil, 118, 118, nil, nil, nil, 118, nil, 118, + 118, 118, 118, 118, 118, 118, nil, nil, nil, nil, + nil, 118, 118, 118, 118, 118, 118, 118, nil, nil, + 118, nil, nil, nil, nil, nil, nil, 118, nil, nil, + 118, 118, 118, 118, 118, 118, 118, 118, nil, 118, + 118, 118, nil, 118, 118, 118, 118, 118, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 118, nil, nil, + 118, nil, nil, 118, 118, nil, nil, 118, nil, nil, + nil, nil, nil, 118, nil, nil, nil, nil, nil, nil, + nil, nil, 118, nil, nil, nil, nil, 118, 118, 118, + 118, nil, 118, 118, 118, 118, nil, nil, nil, nil, + 118, 118, nil, nil, nil, 119, 119, 119, 118, 119, + 118, 118, 118, 119, 119, nil, nil, nil, 119, nil, + 119, 119, 119, 119, 119, 119, 119, nil, nil, nil, + nil, nil, 119, 119, 119, 119, 119, 119, 119, nil, + nil, 119, nil, nil, nil, nil, nil, nil, 119, nil, + nil, 119, 119, 119, 119, 119, 119, 119, 119, nil, + 119, 119, 119, nil, 119, 119, 119, 119, 119, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 119, nil, + nil, 119, nil, nil, 119, 119, nil, nil, 119, nil, + nil, nil, nil, nil, 119, nil, nil, nil, nil, nil, + nil, nil, nil, 119, nil, nil, nil, nil, 119, 119, + 119, 119, nil, 119, 119, 119, 119, nil, nil, nil, + nil, 119, 119, nil, nil, nil, 120, 120, 120, 119, + 120, 119, 119, 119, 120, 120, nil, nil, nil, 120, + nil, 120, 120, 120, 120, 120, 120, 120, nil, nil, + nil, nil, nil, 120, 120, 120, 120, 120, 120, 120, + nil, nil, 120, nil, nil, nil, nil, nil, nil, 120, + nil, nil, 120, 120, 120, 120, 120, 120, 120, 120, + nil, 120, 120, 120, nil, 120, 120, 120, 120, 120, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 120, + nil, nil, 120, nil, nil, 120, 120, nil, nil, 120, + nil, nil, nil, nil, nil, 120, nil, nil, nil, nil, + nil, nil, nil, nil, 120, nil, nil, nil, nil, 120, + 120, 120, 120, nil, 120, 120, 120, 120, nil, nil, + nil, nil, 120, 120, nil, nil, nil, 121, 121, 121, + 120, 121, 120, 120, 120, 121, 121, nil, nil, nil, + 121, nil, 121, 121, 121, 121, 121, 121, 121, nil, + nil, nil, nil, nil, 121, 121, 121, 121, 121, 121, + 121, nil, nil, 121, nil, nil, nil, nil, nil, nil, + 121, nil, nil, 121, 121, 121, 121, 121, 121, 121, + 121, nil, 121, 121, 121, nil, 121, 121, 121, 121, + 121, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 121, nil, nil, 121, nil, nil, 121, 121, nil, nil, + 121, nil, nil, nil, nil, nil, 121, nil, nil, nil, + nil, nil, nil, nil, nil, 121, nil, nil, nil, nil, + 121, 121, 121, 121, nil, 121, 121, 121, 121, nil, + nil, nil, nil, 121, 121, nil, nil, nil, nil, nil, + nil, 121, nil, 121, 121, 121, 122, 122, 122, 122, + 122, nil, nil, nil, 122, 122, nil, nil, nil, 122, + nil, 122, 122, 122, 122, 122, 122, 122, nil, nil, + nil, nil, nil, 122, 122, 122, 122, 122, 122, 122, + nil, nil, 122, nil, nil, nil, nil, nil, 122, 122, + nil, 122, 122, 122, 122, 122, 122, 122, 122, 122, + nil, 122, 122, 122, nil, 122, 122, 122, 122, 122, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 122, + nil, nil, 122, nil, nil, 122, 122, nil, nil, 122, + nil, 122, nil, nil, nil, 122, nil, nil, nil, nil, + nil, nil, nil, nil, 122, nil, nil, nil, nil, 122, + 122, 122, 122, nil, 122, 122, 122, 122, nil, nil, + nil, nil, 122, 122, nil, nil, nil, 209, 209, 209, + 122, 209, 122, 122, 122, 209, 209, nil, nil, nil, + 209, nil, 209, 209, 209, 209, 209, 209, 209, nil, + nil, nil, nil, nil, 209, 209, 209, 209, 209, 209, + 209, nil, nil, 209, nil, nil, nil, nil, nil, nil, + 209, nil, nil, 209, 209, 209, 209, 209, 209, 209, + 209, nil, 209, 209, 209, nil, 209, 209, 209, 209, + 209, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 209, nil, nil, 209, nil, nil, 209, 209, nil, nil, + 209, nil, 209, nil, nil, nil, 209, nil, nil, nil, + nil, nil, nil, nil, nil, 209, nil, nil, nil, nil, + 209, 209, 209, 209, nil, 209, 209, 209, 209, nil, + nil, nil, nil, 209, 209, nil, nil, nil, 210, 210, + 210, 209, 210, 209, 209, 209, 210, 210, nil, nil, + nil, 210, nil, 210, 210, 210, 210, 210, 210, 210, + nil, nil, nil, nil, nil, 210, 210, 210, 210, 210, + 210, 210, nil, nil, 210, nil, nil, nil, nil, nil, + nil, 210, nil, nil, 210, 210, 210, 210, 210, 210, + 210, 210, nil, 210, 210, 210, nil, 210, 210, 210, + 210, 210, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 210, nil, nil, 210, nil, nil, 210, 210, nil, + nil, 210, nil, 210, nil, nil, nil, 210, nil, nil, + nil, nil, nil, nil, nil, nil, 210, nil, nil, nil, + nil, 210, 210, 210, 210, nil, 210, 210, 210, 210, + nil, nil, nil, nil, 210, 210, nil, nil, nil, 211, + 211, 211, 210, 211, 210, 210, 210, 211, 211, nil, + nil, nil, 211, nil, 211, 211, 211, 211, 211, 211, + 211, nil, nil, nil, nil, nil, 211, 211, 211, 211, + 211, 211, 211, nil, nil, 211, nil, nil, nil, nil, + nil, nil, 211, nil, nil, 211, 211, 211, 211, 211, + 211, 211, 211, nil, 211, 211, 211, nil, 211, 211, + 211, 211, 211, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 211, nil, nil, 211, nil, nil, 211, 211, + nil, nil, 211, nil, nil, nil, nil, nil, 211, nil, + nil, nil, nil, nil, nil, nil, nil, 211, nil, nil, + nil, nil, 211, 211, 211, 211, nil, 211, 211, 211, + 211, nil, nil, nil, nil, 211, 211, nil, nil, nil, + 212, 212, 212, 211, 212, 211, 211, 211, 212, 212, + nil, nil, nil, 212, nil, 212, 212, 212, 212, 212, + 212, 212, nil, nil, nil, nil, nil, 212, 212, 212, + 212, 212, 212, 212, nil, nil, 212, nil, nil, nil, + nil, nil, nil, 212, nil, nil, 212, 212, 212, 212, + 212, 212, 212, 212, nil, 212, 212, 212, nil, 212, + 212, 212, 212, 212, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 212, nil, nil, 212, nil, nil, 212, + 212, nil, nil, 212, nil, nil, nil, nil, nil, 212, + nil, nil, nil, nil, nil, nil, nil, nil, 212, nil, + nil, nil, nil, 212, 212, 212, 212, nil, 212, 212, + 212, 212, nil, nil, nil, nil, 212, 212, nil, nil, + nil, 213, 213, 213, 212, 213, 212, 212, 212, 213, + 213, nil, nil, nil, 213, nil, 213, 213, 213, 213, + 213, 213, 213, nil, nil, nil, nil, nil, 213, 213, + 213, 213, 213, 213, 213, nil, nil, 213, nil, nil, + nil, nil, nil, nil, 213, nil, nil, 213, 213, 213, + 213, 213, 213, 213, 213, nil, 213, 213, 213, nil, + 213, 213, 213, 213, 213, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 213, nil, nil, 213, nil, nil, + 213, 213, nil, nil, 213, nil, nil, nil, nil, nil, + 213, nil, nil, nil, nil, nil, nil, nil, nil, 213, + nil, nil, nil, nil, 213, 213, 213, 213, nil, 213, + 213, 213, 213, nil, nil, nil, nil, 213, 213, nil, + nil, nil, 214, 214, 214, 213, 214, 213, 213, 213, + 214, 214, nil, nil, nil, 214, nil, 214, 214, 214, + 214, 214, 214, 214, nil, nil, nil, nil, nil, 214, + 214, 214, 214, 214, 214, 214, nil, nil, 214, nil, + nil, nil, nil, nil, nil, 214, nil, nil, 214, 214, + 214, 214, 214, 214, 214, 214, 214, 214, 214, 214, + nil, 214, 214, 214, 214, 214, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 214, nil, nil, 214, nil, + nil, 214, 214, nil, nil, 214, nil, 214, nil, 214, + nil, 214, nil, nil, 214, nil, nil, nil, nil, nil, + 214, nil, nil, nil, nil, 214, 214, 214, 214, nil, + 214, 214, 214, 214, nil, nil, nil, nil, 214, 214, + nil, nil, nil, 219, 219, 219, 214, 219, 214, 214, + 214, 219, 219, nil, nil, nil, 219, nil, 219, 219, + 219, 219, 219, 219, 219, nil, nil, nil, nil, nil, + 219, 219, 219, 219, 219, 219, 219, nil, nil, 219, + nil, nil, nil, nil, nil, nil, 219, nil, nil, 219, + 219, 219, 219, 219, 219, 219, 219, nil, 219, 219, + 219, nil, 219, 219, 219, 219, 219, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 219, nil, nil, 219, + nil, nil, 219, 219, nil, nil, 219, nil, nil, nil, + nil, nil, 219, nil, nil, nil, nil, nil, nil, nil, + nil, 219, nil, nil, nil, nil, 219, 219, 219, 219, + nil, 219, 219, 219, 219, nil, nil, nil, nil, 219, + 219, nil, nil, nil, 220, 220, 220, 219, 220, 219, + 219, 219, 220, 220, nil, nil, nil, 220, nil, 220, + 220, 220, 220, 220, 220, 220, nil, nil, nil, nil, + nil, 220, 220, 220, 220, 220, 220, 220, nil, nil, + 220, nil, nil, nil, nil, nil, nil, 220, nil, nil, + 220, 220, 220, 220, 220, 220, 220, 220, nil, 220, + 220, 220, nil, 220, 220, 220, 220, 220, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 220, nil, nil, + 220, nil, nil, 220, 220, nil, nil, 220, nil, nil, + nil, nil, nil, 220, nil, nil, nil, nil, nil, nil, + nil, nil, 220, nil, nil, nil, nil, 220, 220, 220, + 220, nil, 220, 220, 220, 220, nil, nil, nil, nil, + 220, 220, nil, nil, nil, 221, 221, 221, 220, 221, + 220, 220, 220, 221, 221, nil, nil, nil, 221, nil, + 221, 221, 221, 221, 221, 221, 221, nil, nil, nil, + nil, nil, 221, 221, 221, 221, 221, 221, 221, nil, + nil, 221, nil, nil, nil, nil, nil, nil, 221, nil, + nil, 221, 221, 221, 221, 221, 221, 221, 221, nil, + 221, 221, 221, nil, 221, 221, 221, 221, 221, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 221, nil, + nil, 221, nil, nil, 221, 221, nil, nil, 221, nil, + nil, nil, nil, nil, 221, nil, nil, nil, nil, nil, + nil, nil, nil, 221, nil, nil, nil, nil, 221, 221, + 221, 221, nil, 221, 221, 221, 221, nil, nil, nil, + nil, 221, 221, 221, nil, nil, 232, 232, 232, 221, + 232, 221, 221, 221, 232, 232, nil, nil, nil, 232, + nil, 232, 232, 232, 232, 232, 232, 232, nil, nil, + nil, nil, nil, 232, 232, 232, 232, 232, 232, 232, + nil, nil, 232, nil, nil, nil, nil, nil, nil, 232, + nil, nil, 232, 232, 232, 232, 232, 232, 232, 232, + nil, 232, 232, 232, nil, 232, 232, 232, 232, 232, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 232, + nil, nil, 232, nil, nil, 232, 232, nil, nil, 232, + nil, nil, nil, nil, nil, 232, nil, nil, nil, nil, + nil, nil, nil, nil, 232, nil, nil, nil, nil, 232, + 232, 232, 232, nil, 232, 232, 232, 232, nil, nil, + nil, nil, 232, 232, nil, nil, nil, 235, 235, 235, + 232, 235, 232, 232, 232, 235, 235, nil, nil, nil, + 235, nil, 235, 235, 235, 235, 235, 235, 235, nil, + nil, nil, nil, nil, 235, 235, 235, 235, 235, 235, + 235, nil, nil, 235, nil, nil, nil, nil, nil, nil, + 235, nil, nil, 235, 235, 235, 235, 235, 235, 235, + 235, nil, 235, 235, 235, nil, 235, 235, 235, 235, + 235, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 235, nil, nil, 235, nil, nil, 235, 235, nil, nil, + 235, nil, nil, nil, nil, nil, 235, nil, nil, nil, + nil, nil, nil, nil, nil, 235, nil, nil, nil, nil, + 235, 235, 235, 235, nil, 235, 235, 235, 235, nil, + nil, nil, nil, 235, 235, nil, nil, nil, 236, 236, + 236, 235, 236, 235, 235, 235, 236, 236, nil, nil, + nil, 236, nil, 236, 236, 236, 236, 236, 236, 236, + nil, nil, nil, nil, nil, 236, 236, 236, 236, 236, + 236, 236, nil, nil, 236, nil, nil, nil, nil, nil, + nil, 236, nil, nil, 236, 236, 236, 236, 236, 236, + 236, 236, nil, 236, 236, 236, nil, 236, 236, 236, + 236, 236, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 236, nil, nil, 236, nil, nil, 236, 236, nil, + nil, 236, nil, nil, nil, nil, nil, 236, nil, nil, + nil, nil, nil, nil, nil, nil, 236, nil, nil, nil, + nil, 236, 236, 236, 236, nil, 236, 236, 236, 236, + nil, nil, nil, nil, 236, 236, nil, nil, nil, 237, + 237, 237, 236, 237, 236, 236, 236, 237, 237, nil, + nil, nil, 237, nil, 237, 237, 237, 237, 237, 237, + 237, nil, nil, nil, nil, nil, 237, 237, 237, 237, + 237, 237, 237, nil, nil, 237, nil, nil, nil, nil, + nil, nil, 237, nil, nil, 237, 237, 237, 237, 237, + 237, 237, 237, nil, 237, 237, 237, nil, 237, 237, + 237, 237, 237, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 237, nil, nil, 237, nil, nil, 237, 237, + nil, nil, 237, nil, nil, nil, nil, nil, 237, nil, + nil, nil, nil, nil, nil, nil, nil, 237, nil, nil, + nil, nil, 237, 237, 237, 237, nil, 237, 237, 237, + 237, nil, nil, nil, nil, 237, 237, nil, nil, nil, + 238, 238, 238, 237, 238, 237, 237, 237, 238, 238, + nil, nil, nil, 238, nil, 238, 238, 238, 238, 238, + 238, 238, nil, nil, nil, nil, nil, 238, 238, 238, + 238, 238, 238, 238, nil, nil, 238, nil, nil, nil, + nil, nil, nil, 238, nil, nil, 238, 238, 238, 238, + 238, 238, 238, 238, nil, 238, 238, 238, nil, 238, + 238, 238, 238, 238, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 238, nil, nil, 238, nil, nil, 238, + 238, nil, nil, 238, nil, nil, nil, nil, nil, 238, + nil, nil, nil, nil, nil, nil, nil, nil, 238, nil, + nil, nil, nil, 238, 238, 238, 238, nil, 238, 238, + 238, 238, nil, nil, nil, nil, 238, 238, nil, nil, + nil, 239, 239, 239, 238, 239, 238, 238, 238, 239, + 239, nil, nil, nil, 239, nil, 239, 239, 239, 239, + 239, 239, 239, nil, nil, nil, nil, nil, 239, 239, + 239, 239, 239, 239, 239, nil, nil, 239, nil, nil, + nil, nil, nil, nil, 239, nil, nil, 239, 239, 239, + 239, 239, 239, 239, 239, nil, 239, 239, 239, nil, + 239, 239, 239, 239, 239, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 239, nil, nil, 239, nil, nil, + 239, 239, nil, nil, 239, nil, nil, nil, nil, nil, + 239, nil, nil, nil, nil, nil, nil, nil, nil, 239, + nil, nil, nil, nil, 239, 239, 239, 239, nil, 239, + 239, 239, 239, nil, nil, nil, nil, 239, 239, nil, + nil, nil, 240, 240, 240, 239, 240, 239, 239, 239, + 240, 240, nil, nil, nil, 240, nil, 240, 240, 240, + 240, 240, 240, 240, nil, nil, nil, nil, nil, 240, + 240, 240, 240, 240, 240, 240, nil, nil, 240, nil, + nil, nil, nil, nil, nil, 240, nil, nil, 240, 240, + 240, 240, 240, 240, 240, 240, nil, 240, 240, 240, + nil, 240, 240, 240, 240, 240, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 240, nil, nil, 240, nil, + nil, 240, 240, nil, nil, 240, nil, nil, nil, nil, + nil, 240, nil, nil, nil, nil, nil, nil, nil, nil, + 240, nil, nil, nil, nil, 240, 240, 240, 240, nil, + 240, 240, 240, 240, nil, nil, nil, nil, 240, 240, + nil, nil, nil, 241, 241, 241, 240, 241, 240, 240, + 240, 241, 241, nil, nil, nil, 241, nil, 241, 241, + 241, 241, 241, 241, 241, nil, nil, nil, nil, nil, + 241, 241, 241, 241, 241, 241, 241, nil, nil, 241, + nil, nil, nil, nil, nil, nil, 241, nil, nil, 241, + 241, 241, 241, 241, 241, 241, 241, nil, 241, 241, + 241, nil, 241, 241, 241, 241, 241, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 241, nil, nil, 241, + nil, nil, 241, 241, nil, nil, 241, nil, nil, nil, + nil, nil, 241, nil, nil, nil, nil, nil, nil, nil, + nil, 241, nil, nil, nil, nil, 241, 241, 241, 241, + nil, 241, 241, 241, 241, nil, nil, nil, nil, 241, + 241, nil, nil, nil, 242, 242, 242, 241, 242, 241, + 241, 241, 242, 242, nil, nil, nil, 242, nil, 242, + 242, 242, 242, 242, 242, 242, nil, nil, nil, nil, + nil, 242, 242, 242, 242, 242, 242, 242, nil, nil, + 242, nil, nil, nil, nil, nil, nil, 242, nil, nil, + 242, 242, 242, 242, 242, 242, 242, 242, nil, 242, + 242, 242, nil, 242, 242, 242, 242, 242, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 242, nil, nil, + 242, nil, nil, 242, 242, nil, nil, 242, nil, nil, + nil, nil, nil, 242, nil, nil, nil, nil, nil, nil, + nil, nil, 242, nil, nil, nil, nil, 242, 242, 242, + 242, nil, 242, 242, 242, 242, nil, nil, nil, nil, + 242, 242, nil, nil, nil, 243, 243, 243, 242, 243, + 242, 242, 242, 243, 243, nil, nil, nil, 243, nil, + 243, 243, 243, 243, 243, 243, 243, nil, nil, nil, + nil, nil, 243, 243, 243, 243, 243, 243, 243, nil, + nil, 243, nil, nil, nil, nil, nil, nil, 243, nil, + nil, 243, 243, 243, 243, 243, 243, 243, 243, nil, + 243, 243, 243, nil, 243, 243, 243, 243, 243, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 243, nil, + nil, 243, nil, nil, 243, 243, nil, nil, 243, nil, + nil, nil, nil, nil, 243, nil, nil, nil, nil, nil, + nil, nil, nil, 243, nil, nil, nil, nil, 243, 243, + 243, 243, nil, 243, 243, 243, 243, nil, nil, nil, + nil, 243, 243, nil, nil, nil, 244, 244, 244, 243, + 244, 243, 243, 243, 244, 244, nil, nil, nil, 244, + nil, 244, 244, 244, 244, 244, 244, 244, nil, nil, + nil, nil, nil, 244, 244, 244, 244, 244, 244, 244, + nil, nil, 244, nil, nil, nil, nil, nil, nil, 244, + nil, nil, 244, 244, 244, 244, 244, 244, 244, 244, + nil, 244, 244, 244, nil, 244, 244, 244, 244, 244, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 244, + nil, nil, 244, nil, nil, 244, 244, nil, nil, 244, + nil, nil, nil, nil, nil, 244, nil, nil, nil, nil, + nil, nil, nil, nil, 244, nil, nil, nil, nil, 244, + 244, 244, 244, nil, 244, 244, 244, 244, nil, nil, + nil, nil, 244, 244, nil, nil, nil, 245, 245, 245, + 244, 245, 244, 244, 244, 245, 245, nil, nil, nil, + 245, nil, 245, 245, 245, 245, 245, 245, 245, nil, + nil, nil, nil, nil, 245, 245, 245, 245, 245, 245, + 245, nil, nil, 245, nil, nil, nil, nil, nil, nil, + 245, nil, nil, 245, 245, 245, 245, 245, 245, 245, + 245, nil, 245, 245, 245, nil, 245, 245, 245, 245, + 245, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 245, nil, nil, 245, nil, nil, 245, 245, nil, nil, + 245, nil, nil, nil, nil, nil, 245, nil, nil, nil, + nil, nil, nil, nil, nil, 245, nil, nil, nil, nil, + 245, 245, 245, 245, nil, 245, 245, 245, 245, nil, + nil, nil, nil, 245, 245, nil, nil, nil, 246, 246, + 246, 245, 246, 245, 245, 245, 246, 246, nil, nil, + nil, 246, nil, 246, 246, 246, 246, 246, 246, 246, + nil, nil, nil, nil, nil, 246, 246, 246, 246, 246, + 246, 246, nil, nil, 246, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 246, 246, 246, 246, 246, 246, + 246, 246, nil, 246, 246, 246, nil, 246, 246, 246, + 246, 246, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 246, nil, nil, 246, 246, nil, + nil, 246, nil, nil, nil, nil, nil, 246, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, nil, + nil, 246, 246, 246, 246, nil, 246, 246, 246, 246, + nil, nil, nil, nil, 246, 246, nil, nil, nil, 247, + 247, 247, 246, 247, 246, 246, 246, 247, 247, nil, + nil, nil, 247, nil, 247, 247, 247, 247, 247, 247, + 247, nil, nil, nil, nil, nil, 247, 247, 247, 247, + 247, 247, 247, nil, nil, 247, nil, nil, nil, nil, + nil, nil, 247, nil, nil, 247, 247, 247, 247, 247, + 247, 247, 247, nil, 247, 247, 247, nil, 247, 247, + 247, 247, 247, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 247, nil, nil, 247, nil, nil, 247, 247, + nil, nil, 247, nil, nil, nil, nil, nil, 247, nil, + nil, nil, nil, nil, nil, nil, nil, 247, nil, nil, + nil, nil, 247, 247, 247, 247, nil, 247, 247, 247, + 247, nil, nil, nil, nil, 247, 247, nil, nil, nil, + 248, 248, 248, 247, 248, 247, 247, 247, 248, 248, + nil, nil, nil, 248, nil, 248, 248, 248, 248, 248, + 248, 248, nil, nil, nil, nil, nil, 248, 248, 248, + 248, 248, 248, 248, nil, nil, 248, nil, nil, nil, + nil, nil, nil, 248, nil, nil, 248, 248, 248, 248, + 248, 248, 248, 248, nil, 248, 248, 248, nil, 248, + 248, 248, 248, 248, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 248, nil, nil, 248, nil, nil, 248, + 248, nil, nil, 248, nil, nil, nil, nil, nil, 248, + nil, nil, nil, nil, nil, nil, nil, nil, 248, nil, + nil, nil, nil, 248, 248, 248, 248, nil, 248, 248, + 248, 248, nil, nil, nil, nil, 248, 248, nil, nil, + nil, 249, 249, 249, 248, 249, 248, 248, 248, 249, + 249, nil, nil, nil, 249, nil, 249, 249, 249, 249, + 249, 249, 249, nil, nil, nil, nil, nil, 249, 249, + 249, 249, 249, 249, 249, nil, nil, 249, nil, nil, + nil, nil, nil, nil, 249, nil, nil, 249, 249, 249, + 249, 249, 249, 249, 249, nil, 249, 249, 249, nil, + 249, 249, 249, 249, 249, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 249, nil, nil, 249, nil, nil, + 249, 249, nil, nil, 249, nil, nil, nil, nil, nil, + 249, nil, nil, nil, nil, nil, nil, nil, nil, 249, + nil, nil, nil, nil, 249, 249, 249, 249, nil, 249, + 249, 249, 249, nil, nil, nil, nil, 249, 249, nil, + nil, nil, 250, 250, 250, 249, 250, 249, 249, 249, + 250, 250, nil, nil, nil, 250, nil, 250, 250, 250, + 250, 250, 250, 250, nil, nil, nil, nil, nil, 250, + 250, 250, 250, 250, 250, 250, nil, nil, 250, nil, + nil, nil, nil, nil, nil, 250, nil, nil, 250, 250, + 250, 250, 250, 250, 250, 250, nil, 250, 250, 250, + nil, 250, 250, 250, 250, 250, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 250, nil, nil, 250, nil, + nil, 250, 250, nil, nil, 250, nil, nil, nil, nil, + nil, 250, nil, nil, nil, nil, nil, nil, nil, nil, + 250, nil, nil, nil, nil, 250, 250, 250, 250, nil, + 250, 250, 250, 250, nil, nil, nil, nil, 250, 250, + nil, nil, nil, 251, 251, 251, 250, 251, 250, 250, + 250, 251, 251, nil, nil, nil, 251, nil, 251, 251, + 251, 251, 251, 251, 251, nil, nil, nil, nil, nil, + 251, 251, 251, 251, 251, 251, 251, nil, nil, 251, + nil, nil, nil, nil, nil, nil, 251, nil, nil, 251, + 251, 251, 251, 251, 251, 251, 251, nil, 251, 251, + 251, nil, 251, 251, 251, 251, 251, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, 251, + nil, nil, 251, 251, nil, nil, 251, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 251, 251, 251, 251, + nil, 251, 251, 251, 251, nil, nil, nil, nil, 251, + 251, nil, nil, nil, 252, 252, 252, 251, 252, 251, + 251, 251, 252, 252, nil, nil, nil, 252, nil, 252, + 252, 252, 252, 252, 252, 252, nil, nil, nil, nil, + nil, 252, 252, 252, 252, 252, 252, 252, nil, nil, + 252, nil, nil, nil, nil, nil, nil, 252, nil, nil, + 252, 252, 252, 252, 252, 252, 252, 252, nil, 252, + 252, 252, nil, 252, 252, 252, 252, 252, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 252, nil, nil, + 252, nil, nil, 252, 252, nil, nil, 252, nil, nil, + nil, nil, nil, 252, nil, nil, nil, nil, nil, nil, + nil, nil, 252, nil, nil, nil, nil, 252, 252, 252, + 252, nil, 252, 252, 252, 252, nil, nil, nil, nil, + 252, 252, nil, nil, nil, 253, 253, 253, 252, 253, + 252, 252, 252, 253, 253, nil, nil, nil, 253, nil, + 253, 253, 253, 253, 253, 253, 253, nil, nil, nil, + nil, nil, 253, 253, 253, 253, 253, 253, 253, nil, + nil, 253, nil, nil, nil, nil, nil, nil, 253, nil, + nil, 253, 253, 253, 253, 253, 253, 253, 253, nil, + 253, 253, 253, nil, 253, 253, 253, 253, 253, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 253, nil, + nil, 253, nil, nil, 253, 253, nil, nil, 253, nil, + nil, nil, nil, nil, 253, nil, nil, nil, nil, nil, + nil, nil, nil, 253, nil, nil, nil, nil, 253, 253, + 253, 253, nil, 253, 253, 253, 253, nil, nil, nil, + nil, 253, 253, nil, nil, nil, 254, 254, 254, 253, + 254, 253, 253, 253, 254, 254, nil, nil, nil, 254, + nil, 254, 254, 254, 254, 254, 254, 254, nil, nil, + nil, nil, nil, 254, 254, 254, 254, 254, 254, 254, + nil, nil, 254, nil, nil, nil, nil, nil, nil, 254, + nil, nil, 254, 254, 254, 254, 254, 254, 254, 254, + nil, 254, 254, 254, nil, 254, 254, 254, 254, 254, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 254, + nil, nil, 254, nil, nil, 254, 254, nil, nil, 254, + nil, nil, nil, nil, nil, 254, nil, nil, nil, nil, + nil, nil, nil, nil, 254, nil, nil, nil, nil, 254, + 254, 254, 254, nil, 254, 254, 254, 254, nil, nil, + nil, nil, 254, 254, nil, nil, nil, 255, 255, 255, + 254, 255, 254, 254, 254, 255, 255, nil, nil, nil, + 255, nil, 255, 255, 255, 255, 255, 255, 255, nil, + nil, nil, nil, nil, 255, 255, 255, 255, 255, 255, + 255, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 255, nil, nil, 255, 255, 255, 255, 255, 255, 255, + 255, nil, 255, 255, 255, nil, 255, 255, 255, 255, + 255, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 255, nil, nil, 255, nil, nil, 255, 255, nil, nil, + 255, nil, nil, nil, nil, nil, 255, nil, nil, nil, + nil, nil, nil, nil, nil, 255, nil, nil, nil, nil, + 255, 255, 255, 255, nil, 255, 255, 255, 255, nil, + nil, nil, nil, 255, 255, nil, nil, nil, 256, 256, + 256, 255, 256, 255, 255, 255, 256, 256, nil, nil, + nil, 256, nil, 256, 256, 256, 256, 256, 256, 256, + nil, nil, nil, nil, nil, 256, 256, 256, 256, 256, + 256, 256, nil, nil, 256, nil, nil, nil, nil, nil, + nil, 256, nil, nil, 256, 256, 256, 256, 256, 256, + 256, 256, nil, 256, 256, 256, nil, 256, 256, 256, + 256, 256, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 256, nil, nil, 256, nil, nil, 256, 256, nil, + nil, 256, nil, nil, nil, nil, nil, 256, nil, nil, + nil, nil, nil, nil, nil, nil, 256, nil, nil, nil, + nil, 256, 256, 256, 256, nil, 256, 256, 256, 256, + nil, nil, nil, nil, 256, 256, nil, nil, nil, 257, + 257, 257, 256, 257, 256, 256, 256, 257, 257, nil, + nil, nil, 257, nil, 257, 257, 257, 257, 257, 257, + 257, nil, nil, nil, nil, nil, 257, 257, 257, 257, + 257, 257, 257, nil, nil, 257, nil, nil, nil, nil, + nil, nil, 257, nil, nil, 257, 257, 257, 257, 257, + 257, 257, 257, nil, 257, 257, 257, nil, 257, 257, + 257, 257, 257, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 257, nil, nil, 257, nil, nil, 257, 257, + nil, nil, 257, nil, nil, nil, nil, nil, 257, nil, + nil, nil, nil, nil, nil, nil, nil, 257, nil, nil, + nil, nil, 257, 257, 257, 257, nil, 257, 257, 257, + 257, nil, nil, nil, nil, 257, 257, nil, nil, nil, + 258, 258, 258, 257, 258, 257, 257, 257, 258, 258, + nil, nil, nil, 258, nil, 258, 258, 258, 258, 258, + 258, 258, nil, nil, nil, nil, nil, 258, 258, 258, + 258, 258, 258, 258, nil, nil, 258, nil, nil, nil, + nil, nil, nil, 258, nil, nil, 258, 258, 258, 258, + 258, 258, 258, 258, nil, 258, 258, 258, nil, 258, + 258, 258, 258, 258, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 258, nil, nil, 258, nil, nil, 258, + 258, nil, nil, 258, nil, nil, nil, nil, nil, 258, + nil, nil, nil, nil, nil, nil, nil, nil, 258, nil, + nil, nil, nil, 258, 258, 258, 258, nil, 258, 258, + 258, 258, nil, nil, nil, nil, 258, 258, nil, nil, + nil, 259, 259, 259, 258, 259, 258, 258, 258, 259, + 259, nil, nil, nil, 259, nil, 259, 259, 259, 259, + 259, 259, 259, nil, nil, nil, nil, nil, 259, 259, + 259, 259, 259, 259, 259, nil, nil, 259, nil, nil, + nil, nil, nil, nil, 259, nil, nil, 259, 259, 259, + 259, 259, 259, 259, 259, nil, 259, 259, 259, nil, + 259, 259, 259, 259, 259, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 259, nil, nil, 259, nil, nil, + 259, 259, nil, nil, 259, nil, nil, nil, nil, nil, + 259, nil, nil, nil, nil, nil, nil, nil, nil, 259, + nil, nil, nil, nil, 259, 259, 259, 259, nil, 259, + 259, 259, 259, nil, nil, nil, nil, 259, 259, nil, + nil, nil, 260, 260, 260, 259, 260, 259, 259, 259, + 260, 260, nil, nil, nil, 260, nil, 260, 260, 260, + 260, 260, 260, 260, nil, nil, nil, nil, nil, 260, + 260, 260, 260, 260, 260, 260, nil, nil, 260, nil, + nil, nil, nil, nil, nil, 260, nil, nil, 260, 260, + 260, 260, 260, 260, 260, 260, nil, 260, 260, 260, + nil, 260, 260, 260, 260, 260, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 260, nil, nil, 260, nil, + nil, 260, 260, nil, nil, 260, nil, nil, nil, nil, + nil, 260, nil, nil, nil, nil, nil, nil, nil, nil, + 260, nil, nil, nil, nil, 260, 260, 260, 260, nil, + 260, 260, 260, 260, nil, nil, nil, nil, 260, 260, + nil, nil, nil, 267, 267, 267, 260, 267, 260, 260, + 260, 267, 267, nil, nil, nil, 267, nil, 267, 267, + 267, 267, 267, 267, 267, nil, nil, nil, nil, nil, + 267, 267, 267, 267, 267, 267, 267, nil, nil, 267, + nil, nil, nil, nil, nil, nil, 267, nil, nil, 267, + 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, + 267, nil, 267, 267, 267, 267, 267, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 267, nil, nil, 267, + nil, nil, 267, 267, nil, nil, 267, nil, 267, nil, + 267, nil, 267, nil, nil, 267, nil, nil, nil, nil, + nil, 267, nil, nil, nil, nil, 267, 267, 267, 267, + nil, 267, 267, 267, 267, nil, nil, nil, nil, 267, + 267, nil, nil, nil, 268, 268, 268, 267, 268, 267, + 267, 267, 268, 268, nil, nil, nil, 268, nil, 268, + 268, 268, 268, 268, 268, 268, nil, nil, nil, nil, + nil, 268, 268, 268, 268, 268, 268, 268, nil, nil, + 268, nil, nil, nil, nil, nil, nil, 268, nil, nil, + 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, + 268, 268, nil, 268, 268, 268, 268, 268, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 268, nil, nil, + 268, nil, nil, 268, 268, nil, nil, 268, nil, 268, + nil, 268, nil, 268, nil, nil, 268, nil, nil, nil, + nil, nil, 268, nil, nil, nil, nil, 268, 268, 268, + 268, nil, 268, 268, 268, 268, nil, nil, nil, nil, + 268, 268, nil, nil, nil, 276, 276, 276, 268, 276, + 268, 268, 268, 276, 276, nil, nil, nil, 276, nil, + 276, 276, 276, 276, 276, 276, 276, nil, nil, nil, + nil, nil, 276, 276, 276, 276, 276, 276, 276, nil, + nil, 276, nil, nil, nil, nil, nil, nil, 276, nil, + nil, 276, 276, 276, 276, 276, 276, 276, 276, 276, + 276, 276, 276, nil, 276, 276, 276, 276, 276, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 276, nil, + nil, 276, nil, nil, 276, 276, nil, nil, 276, nil, + 276, nil, 276, nil, 276, nil, nil, 276, nil, nil, + nil, nil, nil, 276, nil, nil, nil, nil, 276, 276, + 276, 276, nil, 276, 276, 276, 276, nil, nil, nil, + nil, 276, 276, 276, nil, nil, 283, 283, 283, 276, + 283, 276, 276, 276, 283, 283, nil, nil, nil, 283, + nil, 283, 283, 283, 283, 283, 283, 283, nil, nil, + nil, nil, nil, 283, 283, 283, 283, 283, 283, 283, + nil, nil, 283, nil, nil, nil, nil, nil, nil, 283, + nil, nil, 283, 283, 283, 283, 283, 283, 283, 283, + nil, 283, 283, 283, nil, 283, 283, 283, 283, 283, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 283, + nil, nil, 283, nil, nil, 283, 283, nil, nil, 283, + nil, nil, nil, nil, nil, 283, nil, nil, nil, nil, + nil, nil, nil, nil, 283, nil, nil, nil, nil, 283, + 283, 283, 283, nil, 283, 283, 283, 283, nil, nil, + nil, nil, 283, 283, nil, nil, nil, 285, 285, 285, + 283, 285, 283, 283, 283, 285, 285, nil, nil, nil, + 285, nil, 285, 285, 285, 285, 285, 285, 285, nil, + nil, nil, nil, nil, 285, 285, 285, 285, 285, 285, + 285, nil, nil, 285, nil, nil, nil, nil, nil, nil, + 285, nil, nil, 285, 285, 285, 285, 285, 285, 285, + 285, nil, 285, 285, 285, nil, 285, 285, 285, 285, + 285, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 285, nil, nil, 285, nil, nil, 285, 285, nil, nil, + 285, nil, nil, nil, nil, nil, 285, nil, nil, nil, + nil, nil, nil, nil, nil, 285, nil, nil, nil, nil, + 285, 285, 285, 285, nil, 285, 285, 285, 285, nil, + nil, nil, nil, 285, 285, nil, nil, nil, 288, 288, + 288, 285, 288, 285, 285, 285, 288, 288, nil, nil, + nil, 288, nil, 288, 288, 288, 288, 288, 288, 288, + nil, nil, nil, nil, nil, 288, 288, 288, 288, 288, + 288, 288, nil, nil, 288, nil, nil, nil, nil, nil, + nil, 288, nil, nil, 288, 288, 288, 288, 288, 288, + 288, 288, nil, 288, 288, 288, nil, 288, 288, 288, + 288, 288, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 288, nil, nil, 288, nil, nil, 288, 288, nil, + nil, 288, nil, nil, nil, nil, nil, 288, nil, nil, + nil, nil, nil, nil, nil, nil, 288, nil, nil, nil, + nil, 288, 288, 288, 288, nil, 288, 288, 288, 288, + nil, nil, nil, nil, 288, 288, nil, nil, nil, 289, + 289, 289, 288, 289, 288, 288, 288, 289, 289, nil, + nil, nil, 289, nil, 289, 289, 289, 289, 289, 289, + 289, nil, nil, nil, nil, nil, 289, 289, 289, 289, + 289, 289, 289, nil, nil, 289, nil, nil, nil, nil, + nil, nil, 289, nil, nil, 289, 289, 289, 289, 289, + 289, 289, 289, nil, 289, 289, 289, nil, 289, 289, + 289, 289, 289, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 289, nil, nil, 289, nil, nil, 289, 289, + nil, nil, 289, nil, nil, nil, nil, nil, 289, nil, + nil, nil, nil, nil, nil, nil, nil, 289, nil, nil, + nil, nil, 289, 289, 289, 289, nil, 289, 289, 289, + 289, nil, nil, nil, nil, 289, 289, nil, nil, nil, + nil, nil, nil, 289, nil, 289, 289, 289, 294, 294, + 294, 294, 294, nil, nil, nil, 294, 294, nil, nil, + nil, 294, nil, 294, 294, 294, 294, 294, 294, 294, + nil, nil, nil, nil, nil, 294, 294, 294, 294, 294, + 294, 294, nil, nil, 294, nil, nil, nil, nil, nil, + 294, 294, nil, 294, 294, 294, 294, 294, 294, 294, + 294, 294, nil, 294, 294, 294, nil, 294, 294, 294, + 294, 294, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 294, nil, nil, 294, nil, nil, 294, 294, nil, + nil, 294, nil, 294, nil, nil, nil, 294, nil, nil, + nil, nil, nil, nil, nil, nil, 294, nil, nil, nil, + nil, 294, 294, 294, 294, nil, 294, 294, 294, 294, + nil, nil, nil, nil, 294, 294, nil, nil, nil, 302, + 302, 302, 294, 302, 294, 294, 294, 302, 302, nil, + nil, nil, 302, nil, 302, 302, 302, 302, 302, 302, + 302, nil, nil, nil, nil, nil, 302, 302, 302, 302, + 302, 302, 302, nil, nil, 302, nil, nil, nil, nil, + nil, nil, 302, nil, nil, 302, 302, 302, 302, 302, + 302, 302, 302, nil, 302, 302, 302, nil, 302, 302, + nil, nil, 302, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 302, nil, nil, 302, nil, nil, 302, 302, + nil, nil, 302, nil, nil, 938, nil, 938, 938, 938, + 938, 938, nil, nil, nil, nil, nil, nil, nil, nil, + 938, nil, 302, 302, 302, 302, nil, 302, 302, 302, + 302, nil, nil, nil, nil, 302, 302, nil, nil, nil, + 302, nil, 938, 302, nil, 302, 302, 302, 319, 319, + 319, nil, 319, 938, 938, nil, 319, 319, 938, nil, + nil, 319, nil, 319, 319, 319, 319, 319, 319, 319, + nil, nil, nil, nil, nil, 319, 319, 319, 319, 319, + 319, 319, nil, nil, 319, nil, nil, nil, nil, nil, + nil, 319, nil, nil, 319, 319, 319, 319, 319, 319, + 319, 319, nil, 319, 319, 319, nil, 319, 319, nil, + nil, 319, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 319, nil, nil, 319, nil, nil, 319, 319, nil, + nil, 319, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 319, 319, 319, 319, nil, 319, 319, 319, 319, + nil, nil, nil, nil, 319, 319, nil, nil, nil, 327, + 327, 327, 319, 327, 319, 319, 319, 327, 327, nil, + nil, nil, 327, nil, 327, 327, 327, 327, 327, 327, + 327, nil, nil, nil, nil, nil, 327, 327, 327, 327, + 327, 327, 327, nil, nil, 327, nil, nil, nil, nil, + nil, nil, 327, nil, nil, 327, 327, 327, 327, 327, + 327, 327, 327, nil, 327, 327, 327, nil, 327, 327, + 327, 327, 327, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 327, nil, nil, 327, 327, nil, 327, 327, + nil, nil, 327, nil, nil, nil, nil, nil, 327, nil, + nil, nil, nil, nil, nil, nil, nil, 327, nil, nil, + nil, nil, 327, 327, 327, 327, nil, 327, 327, 327, + 327, nil, nil, nil, nil, 327, 327, nil, nil, nil, + 343, 343, 343, 327, 343, 327, 327, 327, 343, 343, + nil, nil, nil, 343, nil, 343, 343, 343, 343, 343, + 343, 343, nil, nil, nil, nil, nil, 343, 343, 343, + 343, 343, 343, 343, nil, nil, 343, nil, nil, nil, + nil, nil, nil, 343, nil, nil, 343, 343, 343, 343, + 343, 343, 343, 343, nil, 343, 343, 343, nil, 343, + 343, 343, 343, 343, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 343, nil, nil, 343, nil, nil, 343, + 343, nil, nil, 343, nil, nil, nil, nil, nil, 343, + nil, nil, nil, nil, nil, nil, nil, nil, 343, nil, + nil, nil, nil, 343, 343, 343, 343, nil, 343, 343, + 343, 343, nil, nil, nil, nil, 343, 343, nil, nil, + nil, 344, 344, 344, 343, 344, 343, 343, 343, 344, + 344, nil, nil, nil, 344, nil, 344, 344, 344, 344, + 344, 344, 344, nil, nil, nil, nil, nil, 344, 344, + 344, 344, 344, 344, 344, nil, nil, 344, nil, nil, + nil, nil, nil, nil, 344, nil, nil, 344, 344, 344, + 344, 344, 344, 344, 344, nil, 344, 344, 344, nil, + 344, 344, 344, 344, 344, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 344, nil, nil, 344, nil, nil, + 344, 344, nil, nil, 344, nil, nil, nil, nil, nil, + 344, nil, nil, nil, nil, nil, nil, nil, nil, 344, + nil, nil, nil, nil, 344, 344, 344, 344, nil, 344, + 344, 344, 344, nil, nil, nil, nil, 344, 344, nil, + nil, nil, 363, 363, 363, 344, 363, 344, 344, 344, + 363, 363, nil, nil, nil, 363, nil, 363, 363, 363, + 363, 363, 363, 363, nil, nil, nil, nil, nil, 363, + 363, 363, 363, 363, 363, 363, nil, nil, 363, nil, + nil, nil, nil, nil, nil, 363, nil, nil, 363, 363, + 363, 363, 363, 363, 363, 363, nil, 363, 363, 363, + nil, 363, 363, 363, 363, 363, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 363, nil, nil, 363, nil, + nil, 363, 363, nil, nil, 363, nil, nil, nil, nil, + nil, 363, nil, nil, nil, nil, nil, nil, nil, nil, + 363, nil, nil, nil, nil, 363, 363, 363, 363, nil, + 363, 363, 363, 363, nil, nil, nil, nil, 363, 363, + nil, nil, nil, 379, 379, 379, 363, 379, 363, 363, + 363, 379, 379, nil, nil, nil, 379, nil, 379, 379, + 379, 379, 379, 379, 379, nil, nil, nil, nil, nil, + 379, 379, 379, 379, 379, 379, 379, nil, nil, 379, + nil, nil, nil, nil, nil, nil, 379, nil, nil, 379, + 379, 379, 379, 379, 379, 379, 379, nil, 379, 379, + 379, nil, 379, 379, 379, 379, 379, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 379, nil, nil, 379, + nil, nil, 379, 379, nil, nil, 379, nil, nil, nil, + nil, nil, 379, nil, nil, nil, nil, nil, nil, nil, + nil, 379, nil, nil, nil, nil, 379, 379, 379, 379, + nil, 379, 379, 379, 379, nil, nil, nil, nil, 379, + 379, nil, nil, nil, 407, 407, 407, 379, 407, 379, + 379, 379, 407, 407, nil, nil, nil, 407, nil, 407, + 407, 407, 407, 407, 407, 407, nil, nil, nil, nil, + nil, 407, 407, 407, 407, 407, 407, 407, nil, nil, + 407, nil, nil, nil, nil, nil, nil, 407, nil, nil, + 407, 407, 407, 407, 407, 407, 407, 407, nil, 407, + 407, 407, nil, 407, 407, 407, 407, 407, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 407, nil, nil, + 407, nil, nil, 407, 407, nil, nil, 407, nil, nil, + nil, nil, nil, 407, nil, nil, nil, nil, nil, nil, + nil, nil, 407, nil, nil, nil, nil, 407, 407, 407, + 407, nil, 407, 407, 407, 407, nil, nil, nil, nil, + 407, 407, nil, nil, nil, 450, 450, 450, 407, 450, + 407, 407, 407, 450, 450, nil, nil, nil, 450, nil, + 450, 450, 450, 450, 450, 450, 450, nil, nil, nil, + nil, nil, 450, 450, 450, 450, 450, 450, 450, nil, + nil, 450, nil, nil, nil, nil, nil, nil, 450, nil, + nil, 450, 450, 450, 450, 450, 450, 450, 450, 450, + 450, 450, 450, nil, 450, 450, 450, 450, 450, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 450, nil, + nil, 450, nil, nil, 450, 450, nil, nil, 450, nil, + 450, nil, 450, nil, 450, nil, nil, 450, nil, nil, + nil, nil, nil, 450, nil, nil, nil, nil, 450, 450, + 450, 450, nil, 450, 450, 450, 450, nil, nil, nil, + nil, 450, 450, nil, nil, nil, 452, 452, 452, 450, + 452, 450, 450, 450, 452, 452, nil, nil, nil, 452, + nil, 452, 452, 452, 452, 452, 452, 452, nil, nil, + nil, nil, nil, 452, 452, 452, 452, 452, 452, 452, + nil, nil, 452, nil, nil, nil, nil, nil, nil, 452, + nil, nil, 452, 452, 452, 452, 452, 452, 452, 452, + nil, 452, 452, 452, nil, 452, 452, 452, 452, 452, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 452, + nil, nil, 452, nil, nil, 452, 452, nil, nil, 452, + nil, nil, nil, nil, nil, 452, nil, nil, nil, nil, + nil, nil, nil, nil, 452, nil, nil, nil, nil, 452, + 452, 452, 452, nil, 452, 452, 452, 452, nil, nil, + nil, nil, 452, 452, nil, nil, nil, 453, 453, 453, + 452, 453, 452, 452, 452, 453, 453, nil, nil, nil, + 453, nil, 453, 453, 453, 453, 453, 453, 453, nil, + nil, nil, nil, nil, 453, 453, 453, 453, 453, 453, + 453, nil, nil, 453, nil, nil, nil, nil, nil, nil, + 453, nil, nil, 453, 453, 453, 453, 453, 453, 453, + 453, nil, 453, 453, 453, nil, 453, 453, 453, 453, + 453, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 453, nil, nil, 453, nil, nil, 453, 453, nil, nil, + 453, nil, nil, nil, nil, nil, 453, nil, nil, nil, + nil, nil, nil, nil, nil, 453, nil, nil, nil, nil, + 453, 453, 453, 453, nil, 453, 453, 453, 453, nil, + nil, nil, nil, 453, 453, nil, nil, nil, 454, 454, + 454, 453, 454, 453, 453, 453, 454, 454, nil, nil, + nil, 454, nil, 454, 454, 454, 454, 454, 454, 454, + nil, nil, nil, nil, nil, 454, 454, 454, 454, 454, + 454, 454, nil, nil, 454, nil, nil, nil, nil, nil, + nil, 454, nil, nil, 454, 454, 454, 454, 454, 454, + 454, 454, nil, 454, 454, 454, nil, 454, 454, 454, + 454, 454, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 454, nil, nil, 454, nil, nil, 454, 454, nil, + nil, 454, nil, nil, nil, nil, nil, 454, nil, nil, + nil, nil, nil, nil, nil, nil, 454, nil, nil, nil, + nil, 454, 454, 454, 454, nil, 454, 454, 454, 454, + nil, nil, nil, nil, 454, 454, nil, nil, nil, 494, + 494, 494, 454, 494, 454, 454, 454, 494, 494, nil, + nil, nil, 494, nil, 494, 494, 494, 494, 494, 494, + 494, nil, nil, nil, nil, nil, 494, 494, 494, 494, + 494, 494, 494, nil, nil, 494, nil, nil, nil, nil, + nil, nil, 494, nil, nil, 494, 494, 494, 494, 494, + 494, 494, 494, 494, 494, 494, 494, nil, 494, 494, + 494, 494, 494, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 494, nil, nil, 494, nil, nil, 494, 494, + nil, nil, 494, nil, 494, nil, 494, nil, 494, nil, + nil, 494, nil, nil, nil, nil, nil, 494, nil, nil, + nil, nil, 494, 494, 494, 494, nil, 494, 494, 494, + 494, nil, nil, nil, nil, 494, 494, nil, nil, nil, + 496, 496, 496, 494, 496, 494, 494, 494, 496, 496, + nil, nil, nil, 496, nil, 496, 496, 496, 496, 496, + 496, 496, nil, nil, nil, nil, nil, 496, 496, 496, + 496, 496, 496, 496, nil, nil, 496, nil, nil, nil, + nil, nil, nil, 496, nil, nil, 496, 496, 496, 496, + 496, 496, 496, 496, 496, 496, 496, 496, nil, 496, + 496, 496, 496, 496, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 496, nil, nil, 496, nil, nil, 496, + 496, nil, nil, 496, nil, nil, nil, 496, nil, 496, + nil, nil, 496, nil, nil, nil, nil, nil, 496, nil, + nil, nil, nil, 496, 496, 496, 496, nil, 496, 496, + 496, 496, nil, nil, nil, nil, 496, 496, nil, nil, + nil, 498, 498, 498, 496, 498, 496, 496, 496, 498, + 498, nil, nil, nil, 498, nil, 498, 498, 498, 498, + 498, 498, 498, nil, nil, nil, nil, nil, 498, 498, + 498, 498, 498, 498, 498, nil, nil, 498, nil, nil, + nil, nil, nil, nil, 498, nil, nil, 498, 498, 498, + 498, 498, 498, 498, 498, nil, 498, 498, 498, nil, + 498, 498, 498, 498, 498, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 498, nil, nil, 498, nil, nil, + 498, 498, nil, nil, 498, nil, nil, nil, nil, nil, + 498, nil, nil, nil, nil, nil, nil, nil, nil, 498, + nil, nil, nil, nil, 498, 498, 498, 498, nil, 498, + 498, 498, 498, nil, nil, nil, nil, 498, 498, nil, + nil, nil, nil, nil, nil, 498, nil, 498, 498, 498, + 504, 504, 504, 504, 504, nil, nil, nil, 504, 504, + nil, nil, nil, 504, nil, 504, 504, 504, 504, 504, + 504, 504, nil, nil, nil, nil, nil, 504, 504, 504, + 504, 504, 504, 504, nil, nil, 504, nil, nil, nil, + nil, nil, 504, 504, 504, 504, 504, 504, 504, 504, + 504, 504, 504, 504, nil, 504, 504, 504, nil, 504, + 504, 504, 504, 504, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 504, nil, nil, 504, nil, nil, 504, + 504, nil, nil, 504, nil, 504, nil, nil, nil, 504, + nil, nil, nil, nil, nil, nil, nil, nil, 504, nil, + nil, nil, nil, 504, 504, 504, 504, nil, 504, 504, + 504, 504, nil, nil, nil, nil, 504, 504, nil, nil, + nil, nil, nil, 504, 504, nil, 504, 504, 504, 512, + 512, 512, nil, 512, nil, nil, nil, 512, 512, nil, + nil, nil, 512, nil, 512, 512, 512, 512, 512, 512, + 512, nil, nil, nil, nil, nil, 512, 512, 512, 512, + 512, 512, 512, nil, nil, 512, nil, nil, nil, nil, + nil, nil, 512, nil, nil, 512, 512, 512, 512, 512, + 512, 512, 512, nil, 512, 512, 512, nil, 512, 512, + nil, nil, 512, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 512, nil, nil, 512, nil, nil, 512, 512, + nil, nil, 512, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 512, 512, 512, 512, nil, 512, 512, 512, + 512, nil, nil, nil, nil, 512, 512, nil, nil, nil, + 514, 514, 514, 512, 514, 512, 512, 512, 514, 514, + nil, nil, nil, 514, nil, 514, 514, 514, 514, 514, + 514, 514, nil, nil, nil, nil, nil, 514, 514, 514, + 514, 514, 514, 514, nil, nil, 514, nil, nil, nil, + nil, nil, nil, 514, nil, nil, 514, 514, 514, 514, + 514, 514, 514, 514, 514, 514, 514, 514, nil, 514, + 514, 514, 514, 514, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 514, nil, nil, 514, nil, nil, 514, + 514, nil, nil, 514, nil, 514, nil, 514, nil, 514, + nil, nil, 514, nil, nil, nil, nil, nil, 514, nil, + nil, nil, nil, 514, 514, 514, 514, nil, 514, 514, + 514, 514, nil, nil, nil, nil, 514, 514, nil, nil, + nil, 520, 520, 520, 514, 520, 514, 514, 514, 520, + 520, nil, nil, nil, 520, nil, 520, 520, 520, 520, + 520, 520, 520, nil, nil, nil, nil, nil, 520, 520, + 520, 520, 520, 520, 520, nil, nil, 520, nil, nil, + nil, nil, nil, nil, 520, nil, nil, 520, 520, 520, + 520, 520, 520, 520, 520, nil, 520, 520, 520, nil, + 520, 520, nil, nil, 520, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 520, nil, nil, 520, nil, nil, + 520, 520, nil, nil, 520, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 520, 520, 520, 520, nil, 520, + 520, 520, 520, nil, nil, nil, nil, 520, 520, nil, + nil, nil, 523, 523, 523, 520, 523, 520, 520, 520, + 523, 523, nil, nil, nil, 523, nil, 523, 523, 523, + 523, 523, 523, 523, nil, nil, nil, nil, nil, 523, + 523, 523, 523, 523, 523, 523, nil, nil, 523, nil, + nil, nil, nil, nil, nil, 523, nil, nil, 523, 523, + 523, 523, 523, 523, 523, 523, nil, 523, 523, 523, + nil, 523, 523, 523, 523, 523, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 523, nil, nil, 523, nil, + nil, 523, 523, nil, nil, 523, nil, nil, nil, nil, + nil, 523, nil, nil, nil, nil, nil, nil, nil, nil, + 523, nil, nil, nil, nil, 523, 523, 523, 523, nil, + 523, 523, 523, 523, nil, nil, nil, nil, 523, 523, + nil, nil, nil, 524, 524, 524, 523, 524, 523, 523, + 523, 524, 524, nil, nil, nil, 524, nil, 524, 524, + 524, 524, 524, 524, 524, nil, nil, nil, nil, nil, + 524, 524, 524, 524, 524, 524, 524, nil, nil, 524, + nil, nil, nil, nil, nil, nil, 524, nil, nil, 524, + 524, 524, 524, 524, 524, 524, 524, nil, 524, 524, + 524, nil, 524, 524, 524, 524, 524, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 524, nil, nil, 524, + nil, nil, 524, 524, nil, nil, 524, nil, nil, nil, + nil, nil, 524, nil, nil, nil, nil, nil, nil, nil, + nil, 524, nil, nil, nil, nil, 524, 524, 524, 524, + nil, 524, 524, 524, 524, nil, nil, nil, nil, 524, + 524, nil, nil, nil, 528, 528, 528, 524, 528, 524, + 524, 524, 528, 528, nil, nil, nil, 528, nil, 528, + 528, 528, 528, 528, 528, 528, nil, nil, nil, nil, + nil, 528, 528, 528, 528, 528, 528, 528, nil, nil, + 528, nil, nil, nil, nil, nil, nil, 528, nil, nil, + 528, 528, 528, 528, 528, 528, 528, 528, nil, 528, + 528, 528, nil, 528, 528, 528, 528, 528, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 528, nil, nil, + 528, nil, nil, 528, 528, nil, nil, 528, nil, nil, + nil, nil, nil, 528, nil, nil, nil, nil, nil, nil, + nil, nil, 528, nil, nil, nil, nil, 528, 528, 528, + 528, nil, 528, 528, 528, 528, nil, nil, nil, nil, + 528, 528, nil, nil, nil, 534, 534, 534, 528, 534, + 528, 528, 528, 534, 534, nil, nil, nil, 534, nil, + 534, 534, 534, 534, 534, 534, 534, nil, nil, nil, + nil, nil, 534, 534, 534, 534, 534, 534, 534, nil, + nil, 534, nil, nil, nil, nil, nil, nil, 534, nil, + nil, 534, 534, 534, 534, 534, 534, 534, 534, 534, + 534, 534, 534, nil, 534, 534, 534, 534, 534, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 534, nil, + nil, 534, nil, nil, 534, 534, nil, nil, 534, nil, + 534, nil, nil, nil, 534, nil, nil, 534, nil, nil, + nil, nil, nil, 534, nil, nil, nil, nil, 534, 534, + 534, 534, nil, 534, 534, 534, 534, nil, nil, nil, + nil, 534, 534, nil, nil, nil, 537, 537, 537, 534, + 537, 534, 534, 534, 537, 537, nil, nil, nil, 537, + nil, 537, 537, 537, 537, 537, 537, 537, nil, nil, + nil, nil, nil, 537, 537, 537, 537, 537, 537, 537, + nil, nil, 537, nil, nil, nil, nil, nil, nil, 537, + nil, nil, 537, 537, 537, 537, 537, 537, 537, 537, + 537, 537, 537, 537, nil, 537, 537, 537, 537, 537, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 537, + nil, nil, 537, nil, nil, 537, 537, nil, nil, 537, + nil, nil, nil, nil, nil, 537, nil, nil, 537, nil, + nil, nil, nil, nil, 537, nil, nil, nil, nil, 537, + 537, 537, 537, nil, 537, 537, 537, 537, nil, nil, + nil, nil, 537, 537, nil, nil, nil, 551, 551, 551, + 537, 551, 537, 537, 537, 551, 551, nil, nil, nil, + 551, nil, 551, 551, 551, 551, 551, 551, 551, nil, + nil, nil, nil, nil, 551, 551, 551, 551, 551, 551, + 551, nil, nil, 551, nil, nil, nil, nil, nil, nil, + 551, nil, nil, 551, 551, 551, 551, 551, 551, 551, + 551, nil, 551, 551, 551, nil, 551, 551, 551, 551, + 551, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 551, nil, nil, 551, nil, nil, 551, 551, nil, nil, + 551, nil, 551, nil, nil, nil, 551, nil, nil, nil, + nil, nil, nil, nil, nil, 551, nil, nil, nil, nil, + 551, 551, 551, 551, nil, 551, 551, 551, 551, nil, + nil, nil, nil, 551, 551, nil, nil, nil, 552, 552, + 552, 551, 552, 551, 551, 551, 552, 552, nil, nil, + nil, 552, nil, 552, 552, 552, 552, 552, 552, 552, + nil, nil, nil, nil, nil, 552, 552, 552, 552, 552, + 552, 552, nil, nil, 552, nil, nil, nil, nil, nil, + nil, 552, nil, nil, 552, 552, 552, 552, 552, 552, + 552, 552, 552, 552, 552, 552, nil, 552, 552, 552, + 552, 552, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 552, nil, nil, 552, nil, nil, 552, 552, nil, + nil, 552, nil, 552, nil, 552, nil, 552, nil, nil, + 552, nil, nil, nil, nil, nil, 552, nil, nil, nil, + nil, 552, 552, 552, 552, nil, 552, 552, 552, 552, + nil, nil, nil, nil, 552, 552, nil, nil, nil, 562, + 562, 562, 552, 562, 552, 552, 552, 562, 562, nil, + nil, nil, 562, nil, 562, 562, 562, 562, 562, 562, + 562, nil, nil, nil, nil, nil, 562, 562, 562, 562, + 562, 562, 562, nil, nil, 562, nil, nil, nil, nil, + nil, nil, 562, nil, nil, 562, 562, 562, 562, 562, + 562, 562, 562, 562, 562, 562, 562, nil, 562, 562, + 562, 562, 562, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 562, nil, nil, 562, nil, nil, 562, 562, + nil, nil, 562, nil, 562, nil, 562, nil, 562, nil, + nil, 562, nil, nil, nil, nil, nil, 562, nil, nil, + nil, nil, 562, 562, 562, 562, nil, 562, 562, 562, + 562, nil, nil, nil, nil, 562, 562, nil, nil, nil, + 594, 594, 594, 562, 594, 562, 562, 562, 594, 594, + nil, nil, nil, 594, nil, 594, 594, 594, 594, 594, + 594, 594, nil, nil, nil, nil, nil, 594, 594, 594, + 594, 594, 594, 594, nil, nil, 594, nil, nil, nil, + nil, nil, nil, 594, nil, nil, 594, 594, 594, 594, + 594, 594, 594, 594, nil, 594, 594, 594, nil, 594, + 594, 594, 594, 594, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 594, nil, nil, 594, nil, nil, 594, + 594, nil, nil, 594, nil, 594, nil, nil, nil, 594, + nil, nil, nil, nil, nil, nil, nil, nil, 594, nil, + nil, nil, nil, 594, 594, 594, 594, nil, 594, 594, + 594, 594, nil, nil, nil, nil, 594, 594, nil, nil, + nil, 595, 595, 595, 594, 595, 594, 594, 594, 595, + 595, nil, nil, nil, 595, nil, 595, 595, 595, 595, + 595, 595, 595, nil, nil, nil, nil, nil, 595, 595, + 595, 595, 595, 595, 595, nil, nil, 595, nil, nil, + nil, nil, nil, nil, 595, nil, nil, 595, 595, 595, + 595, 595, 595, 595, 595, nil, 595, 595, 595, nil, + 595, 595, 595, 595, 595, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 595, nil, nil, 595, nil, nil, + 595, 595, nil, nil, 595, nil, nil, nil, nil, nil, + 595, nil, nil, nil, nil, nil, nil, nil, nil, 595, + nil, nil, nil, nil, 595, 595, 595, 595, nil, 595, + 595, 595, 595, nil, nil, nil, nil, 595, 595, nil, + nil, nil, 596, 596, 596, 595, 596, 595, 595, 595, + 596, 596, nil, nil, nil, 596, nil, 596, 596, 596, + 596, 596, 596, 596, nil, nil, nil, nil, nil, 596, + 596, 596, 596, 596, 596, 596, nil, nil, 596, nil, + nil, nil, nil, nil, nil, 596, nil, nil, 596, 596, + 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, + nil, 596, 596, 596, 596, 596, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 596, nil, nil, 596, nil, + nil, 596, 596, nil, nil, 596, nil, 596, nil, 596, + nil, 596, nil, nil, 596, nil, nil, nil, nil, nil, + 596, nil, nil, nil, nil, 596, 596, 596, 596, nil, + 596, 596, 596, 596, nil, nil, nil, nil, 596, 596, + nil, nil, nil, nil, nil, nil, 596, nil, 596, 596, + 596, 599, 599, 599, 599, 599, nil, nil, nil, 599, + 599, nil, nil, nil, 599, nil, 599, 599, 599, 599, + 599, 599, 599, nil, nil, nil, nil, nil, 599, 599, + 599, 599, 599, 599, 599, nil, nil, 599, nil, nil, + nil, nil, nil, 599, 599, nil, 599, 599, 599, 599, + 599, 599, 599, 599, 599, nil, 599, 599, 599, nil, + 599, 599, 599, 599, 599, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 599, nil, nil, 599, nil, nil, + 599, 599, nil, nil, 599, nil, 599, nil, nil, nil, + 599, nil, nil, nil, nil, nil, nil, nil, nil, 599, + nil, nil, nil, nil, 599, 599, 599, 599, nil, 599, + 599, 599, 599, nil, nil, nil, nil, 599, 599, nil, + nil, nil, 600, 600, 600, 599, 600, 599, 599, 599, + 600, 600, nil, nil, nil, 600, nil, 600, 600, 600, + 600, 600, 600, 600, nil, nil, nil, nil, nil, 600, + 600, 600, 600, 600, 600, 600, nil, nil, 600, nil, + nil, nil, nil, nil, nil, 600, nil, nil, 600, 600, + 600, 600, 600, 600, 600, 600, nil, 600, 600, 600, + nil, 600, 600, 600, 600, 600, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 600, nil, nil, 600, nil, + nil, 600, 600, nil, nil, 600, nil, nil, nil, nil, + nil, 600, nil, nil, nil, nil, nil, nil, nil, nil, + 600, nil, nil, nil, nil, 600, 600, 600, 600, nil, + 600, 600, 600, 600, nil, nil, nil, nil, 600, 600, + nil, nil, nil, 603, 603, 603, 600, 603, 600, 600, + 600, 603, 603, nil, nil, nil, 603, nil, 603, 603, + 603, 603, 603, 603, 603, nil, nil, nil, nil, nil, + 603, 603, 603, 603, 603, 603, 603, nil, nil, 603, + nil, nil, nil, nil, nil, nil, 603, nil, nil, 603, + 603, 603, 603, 603, 603, 603, 603, 603, 603, 603, + 603, nil, 603, 603, 603, 603, 603, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 603, nil, nil, 603, + nil, nil, 603, 603, nil, nil, 603, nil, 603, nil, + 603, nil, 603, nil, nil, 603, nil, nil, nil, nil, + nil, 603, nil, nil, nil, nil, 603, 603, 603, 603, + nil, 603, 603, 603, 603, nil, nil, nil, nil, 603, + 603, nil, nil, nil, 604, 604, 604, 603, 604, 603, + 603, 603, 604, 604, nil, nil, nil, 604, nil, 604, + 604, 604, 604, 604, 604, 604, nil, nil, nil, nil, + nil, 604, 604, 604, 604, 604, 604, 604, nil, nil, + 604, nil, nil, nil, nil, nil, nil, 604, nil, nil, + 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, + 604, 604, nil, 604, 604, 604, 604, 604, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 604, nil, nil, + 604, nil, nil, 604, 604, nil, nil, 604, nil, nil, + nil, 604, nil, 604, nil, nil, 604, nil, nil, nil, + nil, nil, 604, nil, nil, nil, nil, 604, 604, 604, + 604, nil, 604, 604, 604, 604, nil, nil, nil, nil, + 604, 604, nil, nil, nil, 605, 605, 605, 604, 605, + 604, 604, 604, 605, 605, nil, nil, nil, 605, nil, + 605, 605, 605, 605, 605, 605, 605, nil, nil, nil, + nil, nil, 605, 605, 605, 605, 605, 605, 605, nil, + nil, 605, nil, nil, nil, nil, nil, nil, 605, nil, + nil, 605, 605, 605, 605, 605, 605, 605, 605, nil, + 605, 605, 605, nil, 605, 605, 605, 605, 605, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 605, nil, + nil, 605, nil, nil, 605, 605, nil, nil, 605, nil, + nil, nil, nil, nil, 605, nil, nil, nil, nil, nil, + nil, nil, nil, 605, nil, nil, nil, nil, 605, 605, + 605, 605, nil, 605, 605, 605, 605, nil, nil, nil, + nil, 605, 605, nil, nil, nil, 606, 606, 606, 605, + 606, 605, 605, 605, 606, 606, nil, nil, nil, 606, + nil, 606, 606, 606, 606, 606, 606, 606, nil, nil, + nil, nil, nil, 606, 606, 606, 606, 606, 606, 606, + nil, nil, 606, nil, nil, nil, nil, nil, nil, 606, + nil, nil, 606, 606, 606, 606, 606, 606, 606, 606, + nil, 606, 606, 606, nil, 606, 606, 606, 606, 606, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 606, + nil, nil, 606, nil, nil, 606, 606, nil, nil, 606, + nil, nil, nil, nil, nil, 606, nil, nil, nil, nil, + nil, nil, nil, nil, 606, nil, nil, nil, nil, 606, + 606, 606, 606, nil, 606, 606, 606, 606, nil, nil, + nil, nil, 606, 606, nil, nil, nil, 610, 610, 610, + 606, 610, 606, 606, 606, 610, 610, nil, nil, nil, + 610, nil, 610, 610, 610, 610, 610, 610, 610, nil, + nil, nil, nil, nil, 610, 610, 610, 610, 610, 610, + 610, nil, nil, 610, nil, nil, nil, nil, nil, nil, + 610, nil, nil, 610, 610, 610, 610, 610, 610, 610, + 610, nil, 610, 610, 610, nil, 610, 610, 610, 610, + 610, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 610, nil, nil, 610, nil, nil, 610, 610, nil, nil, + 610, nil, nil, nil, nil, nil, 610, nil, nil, nil, + nil, nil, nil, nil, nil, 610, nil, nil, nil, nil, + 610, 610, 610, 610, nil, 610, 610, 610, 610, nil, + nil, nil, nil, 610, 610, nil, nil, nil, 611, 611, + 611, 610, 611, 610, 610, 610, 611, 611, nil, nil, + nil, 611, nil, 611, 611, 611, 611, 611, 611, 611, + nil, nil, nil, nil, nil, 611, 611, 611, 611, 611, + 611, 611, nil, nil, 611, nil, nil, nil, nil, nil, + nil, 611, nil, nil, 611, 611, 611, 611, 611, 611, + 611, 611, nil, 611, 611, 611, nil, 611, 611, 611, + 611, 611, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 611, nil, nil, 611, nil, nil, 611, 611, nil, + nil, 611, nil, nil, nil, nil, nil, 611, nil, nil, + nil, nil, nil, nil, nil, nil, 611, nil, nil, nil, + nil, 611, 611, 611, 611, nil, 611, 611, 611, 611, + nil, nil, nil, nil, 611, 611, nil, nil, nil, 635, + 635, 635, 611, 635, 611, 611, 611, 635, 635, nil, + nil, nil, 635, nil, 635, 635, 635, 635, 635, 635, + 635, nil, nil, nil, nil, nil, 635, 635, 635, 635, + 635, 635, 635, nil, nil, 635, nil, nil, nil, nil, + nil, nil, 635, nil, nil, 635, 635, 635, 635, 635, + 635, 635, 635, nil, 635, 635, 635, nil, 635, 635, + 635, 635, 635, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 635, nil, nil, 635, nil, nil, 635, 635, + nil, nil, 635, nil, nil, nil, nil, nil, 635, nil, + nil, nil, nil, nil, nil, nil, nil, 635, nil, nil, + nil, nil, 635, 635, 635, 635, nil, 635, 635, 635, + 635, nil, nil, nil, nil, 635, 635, nil, nil, nil, + 638, 638, 638, 635, 638, 635, 635, 635, 638, 638, + nil, nil, nil, 638, nil, 638, 638, 638, 638, 638, + 638, 638, nil, nil, nil, nil, nil, 638, 638, 638, + 638, 638, 638, 638, nil, nil, 638, nil, nil, nil, + nil, nil, nil, 638, nil, nil, 638, 638, 638, 638, + 638, 638, 638, 638, nil, 638, 638, 638, nil, 638, + 638, 638, 638, 638, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 638, nil, nil, 638, nil, nil, 638, + 638, nil, nil, 638, nil, nil, nil, nil, nil, 638, + nil, nil, nil, nil, nil, nil, nil, nil, 638, nil, + nil, nil, nil, 638, 638, 638, 638, nil, 638, 638, + 638, 638, nil, nil, nil, nil, 638, 638, nil, nil, + nil, 642, 642, 642, 638, 642, 638, 638, 638, 642, + 642, nil, nil, nil, 642, nil, 642, 642, 642, 642, + 642, 642, 642, nil, nil, nil, nil, nil, 642, 642, + 642, 642, 642, 642, 642, nil, nil, 642, nil, nil, + nil, nil, nil, nil, 642, nil, nil, 642, 642, 642, + 642, 642, 642, 642, 642, nil, 642, 642, 642, nil, + 642, 642, nil, nil, 642, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 642, nil, nil, 642, nil, nil, + 642, 642, nil, nil, 642, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 642, 642, 642, 642, nil, 642, + 642, 642, 642, nil, nil, nil, nil, 642, 642, nil, + nil, nil, 653, 653, 653, 642, 653, 642, 642, 642, + 653, 653, nil, nil, nil, 653, nil, 653, 653, 653, + 653, 653, 653, 653, nil, nil, nil, nil, nil, 653, + 653, 653, 653, 653, 653, 653, nil, nil, 653, nil, + nil, nil, nil, nil, nil, 653, nil, nil, 653, 653, + 653, 653, 653, 653, 653, 653, nil, 653, 653, 653, + nil, 653, 653, nil, nil, 653, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 653, nil, nil, 653, nil, + nil, 653, 653, nil, nil, 653, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 653, 653, 653, 653, nil, + 653, 653, 653, 653, nil, nil, nil, nil, 653, 653, + nil, nil, nil, 658, 658, 658, 653, 658, 653, 653, + 653, 658, 658, nil, nil, nil, 658, nil, 658, 658, + 658, 658, 658, 658, 658, nil, nil, nil, nil, nil, + 658, 658, 658, 658, 658, 658, 658, nil, nil, 658, + nil, nil, nil, nil, nil, nil, 658, nil, nil, 658, + 658, 658, 658, 658, 658, 658, 658, nil, 658, 658, + 658, nil, 658, 658, 658, 658, 658, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 658, nil, nil, 658, + nil, nil, 658, 658, nil, nil, 658, nil, 658, nil, + nil, nil, 658, nil, nil, nil, nil, nil, nil, nil, + nil, 658, nil, nil, nil, nil, 658, 658, 658, 658, + nil, 658, 658, 658, 658, nil, nil, nil, nil, 658, + 658, nil, nil, nil, 684, 684, 684, 658, 684, 658, + 658, 658, 684, 684, nil, nil, nil, 684, nil, 684, + 684, 684, 684, 684, 684, 684, nil, nil, nil, nil, + nil, 684, 684, 684, 684, 684, 684, 684, nil, nil, + 684, nil, nil, nil, nil, nil, nil, 684, nil, nil, + 684, 684, 684, 684, 684, 684, 684, 684, nil, 684, + 684, 684, nil, 684, 684, 684, 684, 684, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 684, nil, nil, + 684, nil, nil, 684, 684, nil, nil, 684, nil, nil, + nil, nil, nil, 684, nil, nil, nil, nil, nil, nil, + nil, nil, 684, nil, nil, nil, nil, 684, 684, 684, + 684, nil, 684, 684, 684, 684, nil, nil, nil, nil, + 684, 684, nil, nil, nil, 711, 711, 711, 684, 711, + 684, 684, 684, 711, 711, nil, nil, nil, 711, nil, + 711, 711, 711, 711, 711, 711, 711, nil, nil, nil, + nil, nil, 711, 711, 711, 711, 711, 711, 711, nil, + nil, 711, nil, nil, nil, nil, nil, nil, 711, nil, + nil, 711, 711, 711, 711, 711, 711, 711, 711, nil, + 711, 711, 711, nil, 711, 711, 711, 711, 711, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 711, nil, + nil, 711, nil, nil, 711, 711, nil, nil, 711, nil, + nil, nil, nil, nil, 711, nil, nil, nil, nil, nil, + nil, nil, nil, 711, nil, nil, nil, nil, 711, 711, + 711, 711, nil, 711, 711, 711, 711, nil, nil, nil, + nil, 711, 711, nil, nil, nil, 717, 717, 717, 711, + 717, 711, 711, 711, 717, 717, nil, nil, nil, 717, + nil, 717, 717, 717, 717, 717, 717, 717, nil, nil, + nil, nil, nil, 717, 717, 717, 717, 717, 717, 717, + nil, nil, 717, nil, nil, nil, nil, nil, nil, 717, + nil, nil, 717, 717, 717, 717, 717, 717, 717, 717, + nil, 717, 717, 717, nil, 717, 717, 717, 717, 717, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 717, + nil, nil, 717, nil, nil, 717, 717, nil, nil, 717, + nil, nil, nil, nil, nil, 717, nil, nil, nil, nil, + nil, nil, nil, nil, 717, nil, nil, nil, nil, 717, + 717, 717, 717, nil, 717, 717, 717, 717, nil, nil, + nil, nil, 717, 717, nil, nil, nil, 739, 739, 739, + 717, 739, 717, 717, 717, 739, 739, nil, nil, nil, + 739, nil, 739, 739, 739, 739, 739, 739, 739, nil, + nil, nil, nil, nil, 739, 739, 739, 739, 739, 739, + 739, nil, nil, 739, nil, nil, nil, nil, nil, nil, + 739, nil, nil, 739, 739, 739, 739, 739, 739, 739, + 739, nil, 739, 739, 739, nil, 739, 739, 739, 739, + 739, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 739, nil, nil, 739, nil, nil, 739, 739, nil, nil, + 739, nil, nil, nil, nil, nil, 739, nil, nil, nil, + nil, nil, nil, nil, nil, 739, nil, nil, nil, nil, + 739, 739, 739, 739, nil, 739, 739, 739, 739, nil, + nil, nil, nil, 739, 739, nil, nil, nil, 747, 747, + 747, 739, 747, 739, 739, 739, 747, 747, nil, nil, + nil, 747, nil, 747, 747, 747, 747, 747, 747, 747, + nil, nil, nil, nil, nil, 747, 747, 747, 747, 747, + 747, 747, nil, nil, 747, nil, nil, nil, nil, nil, + nil, 747, nil, nil, 747, 747, 747, 747, 747, 747, + 747, 747, nil, 747, 747, 747, nil, 747, 747, 747, + 747, 747, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 747, nil, nil, 747, nil, nil, 747, 747, nil, + nil, 747, nil, nil, nil, nil, nil, 747, nil, nil, + nil, nil, nil, nil, nil, nil, 747, nil, nil, nil, + nil, 747, 747, 747, 747, nil, 747, 747, 747, 747, + nil, nil, nil, nil, 747, 747, nil, nil, nil, 760, + 760, 760, 747, 760, 747, 747, 747, 760, 760, nil, + nil, nil, 760, nil, 760, 760, 760, 760, 760, 760, + 760, nil, nil, nil, nil, nil, 760, 760, 760, 760, + 760, 760, 760, nil, nil, 760, nil, nil, nil, nil, + nil, nil, 760, nil, nil, 760, 760, 760, 760, 760, + 760, 760, 760, nil, 760, 760, 760, nil, 760, 760, + 760, 760, 760, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 760, nil, nil, 760, nil, nil, 760, 760, + nil, nil, 760, nil, nil, nil, nil, nil, 760, nil, + nil, nil, nil, nil, nil, nil, nil, 760, nil, nil, + nil, nil, 760, 760, 760, 760, nil, 760, 760, 760, + 760, nil, nil, nil, nil, 760, 760, nil, nil, nil, + 761, 761, 761, 760, 761, 760, 760, 760, 761, 761, + nil, nil, nil, 761, nil, 761, 761, 761, 761, 761, + 761, 761, nil, nil, nil, nil, nil, 761, 761, 761, + 761, 761, 761, 761, nil, nil, 761, nil, nil, nil, + nil, nil, nil, 761, nil, nil, 761, 761, 761, 761, + 761, 761, 761, 761, nil, 761, 761, 761, nil, 761, + 761, 761, 761, 761, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 761, nil, nil, 761, nil, nil, 761, + 761, nil, nil, 761, nil, nil, nil, nil, nil, 761, + nil, nil, nil, nil, nil, nil, nil, nil, 761, nil, + nil, nil, nil, 761, 761, 761, 761, nil, 761, 761, + 761, 761, nil, nil, nil, nil, 761, 761, nil, nil, + nil, 762, 762, 762, 761, 762, 761, 761, 761, 762, + 762, nil, nil, nil, 762, nil, 762, 762, 762, 762, + 762, 762, 762, nil, nil, nil, nil, nil, 762, 762, + 762, 762, 762, 762, 762, nil, nil, 762, nil, nil, + nil, nil, nil, nil, 762, nil, nil, 762, 762, 762, + 762, 762, 762, 762, 762, nil, 762, 762, 762, nil, + 762, 762, 762, 762, 762, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 762, nil, nil, 762, nil, nil, + 762, 762, nil, nil, 762, nil, nil, nil, nil, nil, + 762, nil, nil, nil, nil, nil, nil, nil, nil, 762, + nil, nil, nil, nil, 762, 762, 762, 762, nil, 762, + 762, 762, 762, nil, nil, nil, nil, 762, 762, nil, + nil, nil, 763, 763, 763, 762, 763, 762, 762, 762, + 763, 763, nil, nil, nil, 763, nil, 763, 763, 763, + 763, 763, 763, 763, nil, nil, nil, nil, nil, 763, + 763, 763, 763, 763, 763, 763, nil, nil, 763, nil, + nil, nil, nil, nil, nil, 763, nil, nil, 763, 763, + 763, 763, 763, 763, 763, 763, nil, 763, 763, 763, + nil, 763, 763, 763, 763, 763, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 763, nil, nil, 763, nil, + nil, 763, 763, nil, nil, 763, nil, nil, nil, nil, + nil, 763, nil, nil, nil, nil, nil, nil, nil, nil, + 763, nil, nil, nil, nil, 763, 763, 763, 763, nil, + 763, 763, 763, 763, nil, nil, nil, nil, 763, 763, + nil, nil, nil, 765, 765, 765, 763, 765, 763, 763, + 763, 765, 765, nil, nil, nil, 765, nil, 765, 765, + 765, 765, 765, 765, 765, nil, nil, nil, nil, nil, + 765, 765, 765, 765, 765, 765, 765, nil, nil, 765, + nil, nil, nil, nil, nil, nil, 765, nil, nil, 765, + 765, 765, 765, 765, 765, 765, 765, nil, 765, 765, + 765, nil, 765, 765, 765, 765, 765, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 765, nil, nil, 765, + nil, nil, 765, 765, nil, nil, 765, nil, nil, nil, + nil, nil, 765, nil, nil, nil, nil, nil, nil, nil, + nil, 765, nil, nil, nil, nil, 765, 765, 765, 765, + nil, 765, 765, 765, 765, nil, nil, nil, nil, 765, + 765, nil, nil, nil, 805, 805, 805, 765, 805, 765, + 765, 765, 805, 805, nil, nil, nil, 805, nil, 805, + 805, 805, 805, 805, 805, 805, nil, nil, nil, nil, + nil, 805, 805, 805, 805, 805, 805, 805, nil, nil, + 805, nil, nil, nil, nil, nil, nil, 805, nil, nil, + 805, 805, 805, 805, 805, 805, 805, 805, nil, 805, + 805, 805, nil, 805, 805, 805, 805, 805, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 805, nil, nil, + 805, nil, nil, 805, 805, nil, nil, 805, nil, nil, + nil, nil, nil, 805, nil, nil, nil, nil, nil, nil, + nil, nil, 805, nil, nil, nil, nil, 805, 805, 805, + 805, nil, 805, 805, 805, 805, nil, nil, nil, nil, + 805, 805, nil, nil, nil, 818, 818, 818, 805, 818, + 805, 805, 805, 818, 818, nil, nil, nil, 818, nil, + 818, 818, 818, 818, 818, 818, 818, nil, nil, nil, + nil, nil, 818, 818, 818, 818, 818, 818, 818, nil, + nil, 818, nil, nil, nil, nil, nil, nil, 818, nil, + nil, 818, 818, 818, 818, 818, 818, 818, 818, nil, + 818, 818, 818, nil, 818, 818, 818, 818, 818, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 818, nil, + nil, 818, nil, nil, 818, 818, nil, nil, 818, nil, + nil, nil, nil, nil, 818, nil, nil, nil, nil, nil, + nil, nil, nil, 818, nil, nil, nil, nil, 818, 818, + 818, 818, nil, 818, 818, 818, 818, nil, nil, nil, + nil, 818, 818, nil, nil, nil, 823, 823, 823, 818, + 823, 818, 818, 818, 823, 823, nil, nil, nil, 823, + nil, 823, 823, 823, 823, 823, 823, 823, nil, nil, + nil, nil, nil, 823, 823, 823, 823, 823, 823, 823, + nil, nil, 823, nil, nil, nil, nil, nil, nil, 823, + nil, nil, 823, 823, 823, 823, 823, 823, 823, 823, + nil, 823, 823, 823, nil, 823, 823, 823, 823, 823, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 823, + nil, nil, 823, nil, nil, 823, 823, nil, nil, 823, + nil, 823, nil, nil, nil, 823, nil, nil, nil, nil, + nil, nil, nil, nil, 823, nil, nil, nil, nil, 823, + 823, 823, 823, nil, 823, 823, 823, 823, nil, nil, + nil, nil, 823, 823, nil, nil, nil, 841, 841, 841, + 823, 841, 823, 823, 823, 841, 841, nil, nil, nil, + 841, nil, 841, 841, 841, 841, 841, 841, 841, nil, + nil, nil, nil, nil, 841, 841, 841, 841, 841, 841, + 841, nil, nil, 841, nil, nil, nil, nil, nil, nil, + 841, nil, nil, 841, 841, 841, 841, 841, 841, 841, + 841, 841, 841, 841, 841, nil, 841, 841, 841, 841, + 841, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 841, nil, nil, 841, nil, nil, 841, 841, nil, nil, + 841, nil, nil, nil, 841, nil, 841, nil, nil, 841, + nil, nil, nil, nil, nil, 841, nil, nil, nil, nil, + 841, 841, 841, 841, nil, 841, 841, 841, 841, nil, + nil, nil, nil, 841, 841, nil, nil, nil, 842, 842, + 842, 841, 842, 841, 841, 841, 842, 842, nil, nil, + nil, 842, nil, 842, 842, 842, 842, 842, 842, 842, + nil, nil, nil, nil, nil, 842, 842, 842, 842, 842, + 842, 842, nil, nil, 842, nil, nil, nil, nil, nil, + nil, 842, nil, nil, 842, 842, 842, 842, 842, 842, + 842, 842, nil, 842, 842, 842, nil, 842, 842, 842, + 842, 842, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 842, nil, nil, 842, nil, nil, 842, 842, nil, + nil, 842, nil, nil, nil, nil, nil, 842, nil, nil, + nil, nil, nil, nil, nil, nil, 842, nil, nil, nil, + nil, 842, 842, 842, 842, nil, 842, 842, 842, 842, + nil, nil, nil, nil, 842, 842, nil, nil, nil, 857, + 857, 857, 842, 857, 842, 842, 842, 857, 857, nil, + nil, nil, 857, nil, 857, 857, 857, 857, 857, 857, + 857, nil, nil, nil, nil, nil, 857, 857, 857, 857, + 857, 857, 857, nil, nil, 857, nil, nil, nil, nil, + nil, nil, 857, nil, nil, 857, 857, 857, 857, 857, + 857, 857, 857, nil, 857, 857, 857, nil, 857, 857, + nil, nil, 857, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 857, nil, nil, 857, nil, nil, 857, 857, + nil, nil, 857, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 857, 857, 857, 857, nil, 857, 857, 857, + 857, nil, nil, nil, nil, 857, 857, nil, nil, nil, + 866, 866, 866, 857, 866, 857, 857, 857, 866, 866, + nil, nil, nil, 866, nil, 866, 866, 866, 866, 866, + 866, 866, nil, nil, nil, nil, nil, 866, 866, 866, + 866, 866, 866, 866, nil, nil, 866, nil, nil, nil, + nil, nil, nil, 866, nil, nil, 866, 866, 866, 866, + 866, 866, 866, 866, nil, 866, 866, 866, nil, 866, + 866, nil, nil, 866, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 866, nil, nil, 866, nil, nil, 866, + 866, nil, nil, 866, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 866, 866, 866, 866, nil, 866, 866, + 866, 866, nil, nil, nil, nil, 866, 866, nil, nil, + nil, 919, 919, 919, 866, 919, 866, 866, 866, 919, + 919, nil, nil, nil, 919, nil, 919, 919, 919, 919, + 919, 919, 919, nil, nil, nil, nil, nil, 919, 919, + 919, 919, 919, 919, 919, nil, nil, 919, nil, nil, + nil, nil, nil, nil, 919, nil, nil, 919, 919, 919, + 919, 919, 919, 919, 919, nil, 919, 919, 919, nil, + 919, 919, nil, nil, 919, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 919, nil, nil, 919, nil, nil, + 919, 919, nil, nil, 919, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 919, 919, 919, 919, nil, 919, + 919, 919, 919, nil, nil, nil, nil, 919, 919, nil, + nil, nil, 975, 975, 975, 919, 975, 919, 919, 919, + 975, 975, nil, nil, nil, 975, nil, 975, 975, 975, + 975, 975, 975, 975, nil, nil, nil, nil, nil, 975, + 975, 975, 975, 975, 975, 975, nil, nil, 975, nil, + nil, nil, nil, nil, nil, 975, nil, nil, 975, 975, + 975, 975, 975, 975, 975, 975, 975, 975, 975, 975, + nil, 975, 975, 975, 975, 975, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 975, nil, nil, 975, nil, + nil, 975, 975, nil, nil, 975, nil, 975, nil, 975, + nil, 975, nil, nil, 975, nil, nil, nil, nil, nil, + 975, nil, nil, nil, nil, 975, 975, 975, 975, nil, + 975, 975, 975, 975, nil, nil, nil, nil, 975, 975, + nil, nil, nil, nil, nil, nil, 975, nil, 975, 975, + 975, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, nil, nil, nil, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, nil, nil, + nil, nil, nil, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, nil, 8, nil, nil, nil, nil, nil, + nil, nil, 8, 8, nil, 8, 8, 8, 8, 8, + 8, 8, nil, nil, 8, 8, nil, nil, nil, 8, + 8, 8, 8, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 8, 8, nil, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, nil, nil, 8, 8, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 8, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, nil, nil, nil, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, nil, nil, nil, nil, + nil, 9, 9, 9, 9, 9, 9, 9, 9, 9, + nil, nil, 9, nil, nil, nil, nil, nil, nil, nil, + 9, 9, nil, 9, 9, 9, 9, 9, 9, 9, + nil, nil, 9, 9, nil, nil, nil, 9, 9, 9, + 9, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 9, 9, nil, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, nil, + nil, 9, 9, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 9, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, + 398, nil, nil, nil, 398, 398, 398, 398, 398, 398, + 398, 398, 398, 398, nil, nil, nil, nil, nil, 398, + 398, 398, 398, 398, 398, 398, 398, 398, nil, nil, + 398, nil, nil, nil, nil, nil, nil, nil, 398, 398, + nil, 398, 398, 398, 398, 398, 398, 398, nil, nil, + 398, 398, nil, nil, nil, 398, 398, 398, 398, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 398, 398, nil, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, nil, nil, 398, + 398, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 398, 591, 591, 591, 591, 591, + 591, 591, 591, 591, 591, 591, 591, 591, 591, 591, + 591, 591, 591, 591, 591, 591, 591, 591, 591, nil, + nil, nil, 591, 591, 591, 591, 591, 591, 591, 591, + 591, 591, nil, nil, nil, nil, nil, 591, 591, 591, + 591, 591, 591, 591, 591, 591, nil, nil, 591, nil, + nil, nil, nil, nil, nil, nil, 591, 591, nil, 591, + 591, 591, 591, 591, 591, 591, nil, nil, 591, 591, + nil, nil, nil, 591, 591, 591, 591, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 591, 591, nil, 591, 591, 591, 591, 591, 591, 591, + 591, 591, 591, 591, 591, nil, nil, 591, 591, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 591, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, nil, nil, nil, + 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, + nil, nil, nil, nil, nil, 71, 71, 71, 71, 71, + 71, 71, 71, 71, 71, 71, 71, nil, 71, nil, + nil, nil, nil, nil, 71, 71, nil, 71, 71, 71, + 71, 71, 71, 71, nil, nil, 71, 71, nil, nil, + nil, 71, 71, 71, 71, nil, nil, nil, nil, nil, + 71, nil, nil, nil, nil, nil, nil, nil, 71, 71, + nil, 71, 71, 71, 71, 71, 71, 71, 71, 71, + 71, 71, 71, nil, nil, 71, 723, 723, 723, 723, + 723, 723, 723, 723, 723, 723, 723, 723, 723, 723, + 723, 723, 723, 723, 723, 723, 723, 723, 723, 723, + nil, nil, nil, 723, 723, 723, 723, 723, 723, 723, + 723, 723, 723, nil, nil, nil, nil, nil, 723, 723, + 723, 723, 723, 723, 723, 723, 723, nil, nil, 723, + nil, nil, nil, nil, nil, nil, nil, 723, 723, nil, + 723, 723, 723, 723, 723, 723, 723, nil, nil, 723, + 723, nil, nil, nil, 723, 723, 723, 723, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 723, 723, nil, 723, 723, 723, 723, 723, 723, + 723, 723, 723, 723, 723, 723, 215, 215, 723, nil, + 215, nil, nil, nil, nil, nil, nil, nil, 215, 215, + nil, 215, 215, 215, 215, 215, 215, 215, nil, nil, + 215, 215, nil, nil, nil, 215, 215, 215, 215, nil, + nil, nil, nil, nil, 215, nil, nil, nil, nil, nil, + nil, nil, 215, 215, nil, 215, 215, 215, 215, 215, + 215, 215, 215, 215, 215, 215, 215, 216, 216, 215, + nil, 216, nil, nil, nil, nil, nil, nil, nil, 216, + 216, nil, 216, 216, 216, 216, 216, 216, 216, nil, + nil, 216, 216, nil, nil, nil, 216, 216, 216, 216, + nil, nil, nil, nil, nil, 216, nil, nil, nil, nil, + nil, nil, nil, 216, 216, nil, 216, 216, 216, 216, + 216, 216, 216, 216, 216, 216, 216, 216, 263, 263, + 216, nil, 263, nil, nil, nil, nil, nil, nil, nil, + 263, 263, nil, 263, 263, 263, 263, 263, 263, 263, + nil, nil, 263, 263, nil, nil, nil, 263, 263, 263, + 263, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 263, 263, nil, 263, 263, 263, + 263, 263, 263, 263, 263, 263, 263, 263, 263, 448, + 448, 263, nil, 448, nil, nil, nil, nil, nil, nil, + nil, 448, 448, nil, 448, 448, 448, 448, 448, 448, + 448, nil, nil, 448, 448, nil, nil, nil, 448, 448, + 448, 448, nil, nil, nil, nil, nil, 448, nil, nil, + nil, nil, nil, nil, nil, 448, 448, nil, 448, 448, + 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, + 449, 449, 448, nil, 449, nil, nil, nil, nil, nil, + nil, nil, 449, 449, nil, 449, 449, 449, 449, 449, + 449, 449, nil, nil, 449, 449, nil, nil, nil, 449, + 449, 449, 449, nil, nil, nil, nil, nil, 449, nil, + nil, nil, nil, nil, nil, nil, 449, 449, nil, 449, + 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, + 449, 515, 515, 449, nil, 515, nil, nil, nil, nil, + nil, nil, nil, 515, 515, nil, 515, 515, 515, 515, + 515, 515, 515, nil, nil, 515, 515, nil, nil, nil, + 515, 515, 515, 515, nil, nil, nil, nil, nil, 515, + nil, nil, nil, nil, nil, nil, nil, 515, 515, nil, + 515, 515, 515, 515, 515, 515, 515, 515, 515, 515, + 515, 515, 516, 516, 515, nil, 516, nil, nil, nil, + nil, nil, nil, nil, 516, 516, nil, 516, 516, 516, + 516, 516, 516, 516, nil, nil, 516, 516, nil, nil, + nil, 516, 516, 516, 516, nil, nil, nil, nil, nil, + 516, nil, nil, nil, nil, nil, nil, nil, 516, 516, + nil, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 516, 516, 516, 525, 525, 516, nil, 525, nil, nil, + nil, nil, nil, nil, nil, 525, 525, nil, 525, 525, + 525, 525, 525, 525, 525, nil, nil, 525, 525, nil, + nil, nil, 525, 525, 525, 525, nil, nil, nil, nil, + nil, 525, nil, nil, nil, nil, nil, nil, nil, 525, + 525, nil, 525, 525, 525, 525, 525, 525, 525, 525, + 525, 525, 525, 525, 526, 526, 525, nil, 526, nil, + nil, nil, nil, nil, nil, nil, 526, 526, nil, 526, + 526, 526, 526, 526, 526, 526, nil, nil, 526, 526, + nil, nil, nil, 526, 526, 526, 526, nil, nil, nil, + nil, nil, 526, nil, nil, nil, nil, nil, nil, nil, + 526, 526, nil, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 553, 553, 526, nil, 553, + nil, nil, nil, nil, nil, nil, nil, 553, 553, nil, + 553, 553, 553, 553, 553, 553, 553, nil, nil, 553, + 553, nil, nil, nil, 553, 553, 553, 553, nil, nil, + nil, nil, nil, 553, nil, nil, nil, nil, nil, nil, + nil, 553, 553, nil, 553, 553, 553, 553, 553, 553, + 553, 553, 553, 553, 553, 553, 554, 554, 553, nil, + 554, nil, nil, nil, nil, nil, nil, nil, 554, 554, + nil, 554, 554, 554, 554, 554, 554, 554, nil, nil, + 554, 554, nil, nil, nil, 554, 554, 554, 554, nil, + nil, nil, nil, nil, 554, nil, nil, nil, nil, nil, + nil, nil, 554, 554, nil, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 560, 560, 554, + nil, 560, nil, nil, nil, nil, nil, nil, nil, 560, + 560, nil, 560, 560, 560, 560, 560, 560, 560, nil, + nil, 560, 560, nil, nil, nil, 560, 560, 560, 560, + nil, nil, nil, nil, nil, 560, nil, nil, nil, nil, + nil, nil, nil, 560, 560, nil, 560, 560, 560, 560, + 560, 560, 560, 560, 560, 560, 560, 560, 561, 561, + 560, nil, 561, nil, nil, nil, nil, nil, nil, nil, + 561, 561, nil, 561, 561, 561, 561, 561, 561, 561, + nil, nil, 561, 561, nil, nil, nil, 561, 561, 561, + 561, nil, nil, nil, nil, nil, 561, nil, nil, nil, + nil, nil, nil, nil, 561, 561, nil, 561, 561, 561, + 561, 561, 561, 561, 561, 561, 561, 561, 561, 597, + 597, 561, nil, 597, nil, nil, nil, nil, nil, nil, + nil, 597, 597, nil, 597, 597, 597, 597, 597, 597, + 597, nil, nil, 597, 597, nil, nil, nil, 597, 597, + 597, 597, nil, nil, nil, nil, nil, 597, nil, nil, + nil, nil, nil, nil, nil, 597, 597, nil, 597, 597, + 597, 597, 597, 597, 597, 597, 597, 597, 597, 597, + 598, 598, 597, nil, 598, nil, nil, nil, nil, nil, + nil, nil, 598, 598, nil, 598, 598, 598, 598, 598, + 598, 598, nil, nil, 598, 598, nil, nil, nil, 598, + 598, 598, 598, nil, nil, nil, nil, nil, 598, nil, + nil, nil, nil, nil, nil, nil, 598, 598, nil, 598, + 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, + 598, 972, 972, 598, nil, 972, nil, nil, nil, nil, + nil, nil, nil, 972, 972, nil, 972, 972, 972, 972, + 972, 972, 972, nil, nil, 972, 972, nil, nil, nil, + 972, 972, 972, 972, nil, nil, nil, nil, nil, 972, + nil, nil, nil, nil, nil, nil, nil, 972, 972, nil, + 972, 972, 972, 972, 972, 972, 972, 972, 972, 972, + 972, 972, 976, 976, 972, nil, 976, nil, nil, nil, + nil, nil, nil, nil, 976, 976, nil, 976, 976, 976, + 976, 976, 976, 976, nil, nil, 976, 976, nil, nil, + nil, 976, 976, 976, 976, nil, nil, nil, nil, nil, + 976, nil, nil, nil, nil, nil, nil, nil, 976, 976, + nil, 976, 976, 976, 976, 976, 976, 976, 976, 976, + 976, 976, 976, 977, 977, 976, nil, 977, nil, nil, + nil, nil, nil, nil, nil, 977, 977, nil, 977, 977, + 977, 977, 977, 977, 977, nil, nil, 977, 977, nil, + nil, nil, 977, 977, 977, 977, nil, nil, nil, nil, + nil, 977, nil, nil, nil, nil, nil, nil, nil, 977, + 977, nil, 977, 977, 977, 977, 977, 977, 977, 977, + 977, 977, 977, 977, nil, 542, 977, 542, 542, 542, + 542, 542, nil, 664, nil, 664, 664, 664, 664, 664, + 542, nil, nil, nil, nil, nil, nil, nil, 664, nil, + 721, nil, 721, 721, 721, 721, 721, nil, nil, nil, + nil, nil, 542, 542, nil, 721, nil, nil, nil, nil, + 664, 542, 542, 542, 542, nil, nil, nil, 542, 664, + 664, 664, 664, nil, nil, nil, 664, 721, nil, 722, + nil, 722, 722, 722, 722, 722, 721, 721, 721, 721, + nil, nil, nil, 721, 722, nil, 799, nil, 799, 799, + 799, 799, 799, nil, 801, nil, 801, 801, 801, 801, + 801, 799, nil, nil, nil, nil, 722, nil, nil, 801, + nil, nil, nil, nil, nil, 722, 722, 722, 722, nil, + nil, nil, 722, 799, nil, nil, nil, nil, nil, nil, + nil, 801, 799, 799, 799, 799, nil, nil, nil, 799, + 801, 801, 801, 801, nil, nil, 910, 801, 910, 910, + 910, 910, 910, nil, 912, nil, 912, 912, 912, 912, + 912, 910, nil, nil, nil, nil, nil, nil, nil, 912, + nil, 934, nil, 934, 934, 934, 934, 934, nil, nil, + nil, nil, nil, 910, nil, nil, 934, nil, nil, nil, + nil, 912, 910, 910, 910, 910, nil, nil, nil, 910, + 912, 912, 912, 912, nil, nil, nil, 912, 934, nil, + 940, nil, 940, 940, 940, 940, 940, 934, 934, 934, + 934, nil, nil, nil, 934, 940, nil, 993, nil, 993, + 993, 993, 993, 993, 995, nil, 995, 995, 995, 995, + 995, nil, 993, nil, nil, nil, nil, 940, nil, 995, + nil, 997, nil, 997, 997, 997, 997, 997, 940, 940, + nil, nil, nil, 940, 993, nil, 997, nil, nil, nil, + nil, 995, nil, 993, 993, 993, 993, nil, nil, nil, + 993, nil, 995, 995, nil, nil, nil, 995, 997, nil, + 999, nil, 999, 999, 999, 999, 999, nil, nil, 997, + 997, nil, nil, nil, 997, 999, nil, 1014, nil, 1014, + 1014, 1014, 1014, 1014, 1032, nil, 1032, 1032, 1032, 1032, + 1032, nil, 1014, nil, nil, nil, nil, 999, nil, 1032, + nil, nil, nil, nil, nil, nil, nil, nil, 999, 999, + nil, nil, nil, 999, 1014, nil, nil, nil, nil, nil, + nil, 1032, nil, nil, nil, 1014, 1014, nil, nil, nil, + 1014, nil, 1032, 1032, nil, nil, nil, 1032 ] + +racc_action_pointer = [ + 1853, 10, nil, 81, nil, 5912, 909, -79, 23169, 23297, + -59, nil, -86, -80, 346, 107, 574, -81, nil, -71, + 6043, 1711, 176, nil, -62, nil, -8, 958, 1068, 6174, + 6305, 6436, nil, 1993, 6567, 6698, nil, 101, 282, 352, + 193, 332, 6837, 6968, 7099, 137, 576, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1178, nil, 7238, 7369, + 7500, 4, nil, 7631, 7762, nil, nil, 7893, 8032, 8163, + 8294, 23681, nil, nil, nil, nil, nil, nil, nil, 141, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 0, nil, nil, + 112, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 276, nil, 8433, nil, nil, nil, nil, 8572, 8703, + 8834, 8965, 9104, 2133, nil, 303, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 169, nil, 2273, 9235, + 9366, 9497, 9628, 9759, 9890, 23855, 23916, nil, nil, 10021, + 10152, 10283, nil, nil, 682, -54, 138, 262, 166, 176, + 235, nil, 10414, 2413, 250, 10545, 10676, 10807, 10938, 11069, + 11200, 11331, 11462, 11593, 11724, 11855, 11986, 12117, 12248, 12379, + 12510, 12641, 12772, 12903, 13034, 13165, 13296, 13427, 13558, 13689, + 13820, nil, nil, 23977, nil, nil, 249, 13951, 14082, nil, + nil, nil, nil, nil, nil, nil, 14213, nil, 2133, nil, + 221, 251, nil, 14344, 308, 14475, nil, nil, 14606, 14737, + nil, nil, 216, nil, 14876, 1396, 287, 271, 2553, 300, + 368, 337, 15007, 2693, 686, 718, 771, 426, 794, nil, + 394, 366, 33, nil, nil, nil, 421, 360, 387, 15146, + nil, 472, 460, 834, nil, 462, nil, 15277, 2833, 1561, + 400, nil, -69, 368, 453, 452, 421, 501, nil, nil, + 620, -1, 11, 15408, 15539, 228, 579, 467, -18, 11, + 837, 555, 25, 595, nil, nil, 342, 434, -21, nil, + 870, nil, 522, 15670, nil, nil, nil, 194, 230, 379, + 413, 486, 510, 523, 577, 578, nil, 582, nil, 15801, + nil, 272, 456, 459, 465, 497, -41, -35, 501, nil, + nil, nil, nil, nil, nil, nil, nil, 529, 23425, nil, + nil, nil, nil, 535, nil, nil, 517, 15932, 531, nil, + nil, 525, nil, 930, 197, 641, nil, nil, 1853, nil, + nil, nil, nil, nil, 1993, 559, nil, 560, 563, 481, + 506, 1314, nil, nil, nil, 222, 334, 610, nil, nil, + 1446, 1582, nil, nil, nil, -35, nil, 611, 24038, 24099, + 16063, 217, 16194, 16325, 16456, 2833, 2973, 642, 772, 637, + 639, 663, 667, 1667, 4513, 666, 3113, 1397, 1531, 3253, + 3393, 3533, 3673, 3813, 3953, 4093, 915, 1240, 4233, 4373, + 2273, nil, 1718, nil, nil, nil, nil, 608, nil, nil, + nil, 613, nil, nil, 16587, nil, 16718, nil, 16849, nil, + 363, nil, nil, nil, 16988, 1604, 2973, 622, 625, nil, + nil, 629, 17127, 635, 17258, 24160, 24221, 1006, 678, nil, + 17389, 643, nil, 17520, 17651, 24282, 24343, 2413, 17782, 770, + 769, 669, 713, nil, 17913, nil, nil, 18044, nil, nil, + nil, nil, 24954, 3113, 793, nil, 3253, 62, 147, 792, + 800, 18175, 18306, 24404, 24465, 27, nil, nil, 1038, nil, + 24526, 24587, 18437, nil, nil, 250, 3393, 724, nil, -33, + nil, nil, nil, 832, nil, nil, nil, 696, nil, nil, + 388, nil, 390, nil, nil, 684, nil, 696, nil, nil, + nil, 23553, nil, 698, 18568, 18699, 18830, 24648, 24709, 18969, + 19100, 552, 738, 19231, 19362, 19493, 19624, 741, nil, nil, + 19755, 19886, 747, nil, nil, nil, 301, 343, 466, 604, + 720, 720, 844, nil, 827, 6, nil, nil, 745, -54, + 852, nil, 739, nil, 786, 20017, nil, nil, 20148, nil, + 763, -83, 20279, 744, nil, 751, 123, 180, 793, 248, + 1040, 794, 755, 20410, nil, 840, 214, 893, 20541, nil, + nil, nil, 503, nil, 24962, nil, 782, 784, nil, 787, + 789, 790, nil, nil, nil, nil, nil, nil, nil, nil, + 782, 1278, nil, nil, 20672, nil, nil, nil, 890, nil, + nil, nil, 909, nil, nil, 911, 712, nil, 950, nil, + nil, nil, nil, 964, nil, 26, 845, 41, 68, 151, + 185, 20803, 717, 1146, nil, 848, 3533, 20934, nil, 971, + 3673, 24979, 25018, 23794, nil, nil, nil, nil, nil, nil, + 3813, nil, nil, nil, nil, nil, nil, nil, 849, 21065, + 860, 374, 443, 714, 826, nil, 2553, 21196, nil, 858, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 21327, 21458, 21589, 21720, 520, 21851, nil, -53, nil, nil, + 879, nil, nil, 889, nil, 3953, nil, nil, nil, nil, + nil, 863, 236, nil, nil, 995, nil, 4093, 876, 923, + nil, nil, nil, 89, 881, 780, nil, nil, 661, 25035, + nil, 25043, nil, 1377, nil, 21982, nil, 1314, nil, 882, + 335, 886, nil, nil, nil, nil, 1013, nil, 22113, 1029, + 4233, 4373, nil, 22244, 4513, 152, 181, nil, 1034, 298, + 4653, nil, 1035, 916, 327, nil, 922, 917, 549, nil, + nil, 22375, 22506, 2693, 4793, nil, 920, 922, nil, 924, + 926, 929, nil, 964, 944, 943, 936, 22637, nil, nil, + nil, nil, 4933, nil, nil, 32, 22768, nil, nil, nil, + nil, 996, 954, nil, nil, nil, 959, 963, nil, 964, + 965, nil, 968, nil, nil, 972, 1413, 970, 951, nil, + nil, 33, nil, 1097, 1103, nil, 85, nil, nil, nil, + 1104, nil, nil, nil, 1025, nil, nil, 1203, nil, nil, + 25095, nil, 25103, nil, 6745, nil, nil, 1007, 1242, 22899, + 1116, 1063, nil, 5073, 34, 35, 1148, 1064, 36, nil, + 5213, 5353, nil, nil, 25120, nil, 8341, nil, 15054, nil, + 25159, nil, nil, nil, nil, 398, 1307, 987, 5493, nil, + nil, nil, nil, nil, 5633, nil, 5773, 988, nil, nil, + 990, 992, 993, 994, nil, 995, nil, 504, nil, nil, + nil, 1150, 24770, nil, 1123, 23030, 24831, 24892, 42, 1019, + 1140, 1020, 1021, 1023, 1026, 1027, 1439, 1030, 1511, 760, + 1156, 1158, nil, 25176, nil, 25183, nil, 25200, nil, 25239, + nil, nil, nil, 1319, 1080, 1083, nil, 1053, 98, 102, + 111, 138, nil, nil, 25256, nil, nil, nil, nil, 1647, + 1051, nil, nil, nil, 1055, 1056, 1063, 1064, nil, 145, + 1069, 1074, 25263, nil, nil, nil, nil, nil, 1075, nil ] + +racc_action_default = [ + -3, -607, -1, -593, -4, -607, -7, -607, -607, -607, + -607, -29, -607, -607, -33, -607, -607, -281, -45, -595, + -607, -50, -52, -53, -54, -58, -258, -258, -258, -294, + -330, -331, -70, -11, -74, -82, -84, -607, -497, -498, + -607, -607, -607, -607, -607, -595, -237, -272, -273, -274, + -275, -276, -277, -278, -279, -280, -581, -283, -287, -606, + -571, -302, -304, -607, -607, -308, -311, -593, -607, -607, + -607, -607, -332, -333, -335, -336, -438, -439, -440, -441, + -442, -463, -445, -446, -465, -467, -450, -455, -459, -461, + -477, -465, -479, -481, -482, -483, -484, -579, -486, -487, + -580, -489, -490, -491, -492, -493, -494, -495, -496, -501, + -502, -607, -2, -594, -602, -603, -604, -6, -607, -607, + -607, -607, -607, -3, -17, -607, -113, -114, -115, -116, + -117, -118, -119, -120, -121, -125, -126, -127, -128, -129, + -130, -131, -132, -133, -134, -135, -136, -137, -138, -139, + -140, -141, -142, -143, -144, -145, -146, -147, -148, -149, + -150, -151, -152, -153, -154, -155, -156, -157, -158, -159, + -160, -161, -162, -163, -164, -165, -166, -167, -168, -169, + -170, -171, -172, -173, -174, -175, -176, -177, -178, -179, + -180, -181, -182, -183, -184, -185, -186, -187, -188, -189, + -190, -191, -192, -193, -194, -195, -22, -122, -11, -607, + -607, -607, -607, -607, -248, -607, -607, -591, -592, -607, + -607, -595, -596, -49, -607, -497, -498, -607, -281, -607, + -607, -229, -607, -11, -607, -607, -607, -607, -607, -607, + -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, + -607, -607, -607, -607, -607, -607, -607, -607, -607, -607, + -607, -402, -404, -607, -589, -590, -59, -248, -607, -301, + -408, -417, -419, -65, -414, -66, -595, -67, -238, -253, + -262, -262, -257, -607, -263, -607, -463, -573, -607, -607, + -68, -69, -593, -12, -607, -15, -607, -72, -11, -595, + -607, -75, -78, -11, -90, -91, -607, -607, -98, -294, + -297, -595, -607, -330, -331, -334, -415, -607, -80, -607, + -86, -291, -480, -607, -214, -215, -230, -607, -11, -285, + -595, -239, -599, -599, -607, -607, -599, -607, -303, -393, + -51, -607, -607, -607, -607, -593, -607, -594, -497, -498, + -607, -607, -281, -607, -346, -347, -108, -109, -607, -111, + -607, -281, -505, -607, -497, -498, -323, -113, -114, -155, + -156, -157, -173, -178, -185, -188, -325, -607, -569, -607, + -443, -607, -607, -607, -607, -607, -607, -607, -607, 1040, + -5, -605, -23, -24, -25, -26, -27, -607, -607, -19, + -20, -21, -123, -607, -30, -32, -268, -607, -607, -267, + -31, -607, -34, -607, -281, -42, -44, -196, -243, -263, + -46, -47, -35, -197, -243, -595, -249, -262, -262, -582, + -583, -258, -412, -584, -585, -583, -582, -258, -411, -413, + -584, -585, -41, -204, -48, -595, -300, -607, -607, -607, + -248, -291, -607, -607, -607, -205, -206, -207, -208, -209, + -210, -211, -212, -216, -217, -218, -219, -220, -221, -222, + -223, -224, -225, -226, -227, -228, -231, -232, -233, -234, + -595, -423, -258, -582, -583, -56, -60, -595, -259, -421, + -423, -595, -296, -254, -607, -255, -607, -260, -607, -264, + -607, -576, -578, -10, -594, -14, -3, -595, -71, -289, + -87, -76, -607, -595, -248, -607, -607, -97, -607, -480, + -607, -83, -88, -607, -607, -607, -607, -235, -607, -430, + -607, -595, -607, -240, -601, -600, -242, -601, -292, -293, + -572, -305, -529, -11, -337, -338, -11, -607, -607, -607, + -607, -607, -248, -607, -607, -291, -316, -108, -109, -110, + -607, -607, -248, -319, -503, -607, -11, -507, -327, -595, + -444, -464, -469, -607, -471, -447, -466, -607, -468, -449, + -607, -452, -607, -454, -457, -607, -458, -607, -478, -8, + -18, -607, -28, -271, -607, -607, -248, -607, -607, -607, + -607, -416, -607, -250, -252, -607, -607, -61, -247, -409, + -607, -607, -63, -410, -299, -597, -582, -583, -582, -583, + -595, -607, -607, -424, -55, -405, -421, -245, -607, -382, + -607, -295, -262, -261, -265, -607, -574, -575, -607, -13, + -607, -73, -607, -79, -85, -595, -582, -583, -246, -586, + -96, -607, -81, -607, -203, -213, -595, -606, -606, -284, + -286, -288, -599, -394, -529, -397, -568, -568, -512, -514, + -514, -514, -528, -530, -531, -532, -533, -534, -535, -536, + -537, -607, -539, -541, -543, -548, -550, -551, -553, -558, + -560, -561, -563, -564, -565, -607, -606, -339, -606, -309, + -340, -341, -312, -607, -315, -607, -595, -582, -583, -586, + -290, -607, -108, -109, -112, -595, -11, -607, -321, -607, + -11, -529, -529, -607, -570, -470, -473, -474, -475, -476, + -11, -448, -451, -453, -456, -460, -462, -124, -269, -607, + -595, -582, -583, -583, -582, -43, -244, -607, -598, -262, + -37, -199, -38, -200, -62, -39, -202, -40, -201, -64, + -607, -607, -607, -607, -416, -607, -403, -382, -407, -406, + -607, -418, -383, -595, -385, -11, -420, -256, -266, -577, + -16, -77, -416, -89, -298, -606, -344, -11, -431, -606, + -432, -433, -241, -607, -595, -607, -510, -511, -607, -607, + -521, -607, -524, -607, -526, -607, -348, -607, -350, -352, + -359, -595, -542, -552, -562, -566, -607, -342, -607, -607, + -11, -11, -314, -607, -11, -416, -607, -416, -607, -607, + -11, -324, -607, -595, -607, -328, -607, -270, -416, -36, + -198, -251, -607, -236, -11, -57, -568, -568, -364, -366, + -366, -366, -381, -607, -595, -387, -537, -545, -546, -556, + -422, -9, -11, -437, -345, -607, -607, -435, -395, -398, + -400, -607, -568, -549, -567, -513, -514, -514, -540, -514, + -514, -559, -514, -537, -554, -595, -607, -357, -607, -538, + -306, -607, -307, -607, -607, -265, -606, -317, -320, -504, + -607, -326, -506, -508, -507, -472, -425, -607, -362, -363, + -372, -374, -607, -377, -607, -379, -384, -607, -607, -607, + -544, -607, -436, -11, -497, -498, -607, -607, -281, -434, + -11, -11, -396, -509, -607, -517, -607, -519, -607, -522, + -607, -525, -527, -349, -351, -355, -607, -360, -11, -310, + -313, -426, -427, -428, -11, -322, -11, -568, -547, -365, + -366, -366, -366, -366, -557, -366, -386, -595, -389, -391, + -392, -555, -607, -291, -430, -248, -607, -607, -291, -607, + -607, -514, -514, -514, -514, -353, -607, -358, -607, -606, + -607, -607, -361, -607, -369, -607, -371, -607, -375, -607, + -378, -380, -388, -607, -290, -586, -429, -595, -582, -583, + -586, -290, -399, -401, -607, -515, -518, -520, -523, -607, + -356, -343, -318, -329, -366, -366, -366, -366, -390, -416, + -514, -354, -607, -367, -370, -373, -376, -516, -366, -368 ] + +racc_goto_table = [ + 220, 341, 342, 16, 262, 345, 376, 338, 16, 495, + 425, 263, 530, 331, 657, 116, 550, 270, 274, 215, + 2, 129, 129, 224, 6, 112, 327, 264, 720, 6, + 543, 546, 224, 224, 224, 301, 16, 306, 306, 124, + 207, 132, 132, 486, 409, 410, 636, 601, 521, 113, + 134, 134, 266, 273, 275, 381, 392, 393, 394, 395, + 633, 16, 633, 487, 322, 297, 224, 224, 816, 299, + 224, 350, 360, 360, 318, 26, 223, 699, 702, 116, + 26, 628, 329, 665, 129, 944, 964, 636, 559, 346, + 775, 878, 881, 785, 422, 26, 850, 280, 280, 280, + 442, 117, 1, 947, 26, 26, 26, 968, 26, 811, + 382, 533, 536, 861, 970, 540, 16, 388, 796, 797, + 639, 224, 224, 224, 224, 16, 16, 332, 206, 281, + 281, 281, 622, 26, 819, 355, 672, 6, 26, 26, + 405, 630, 26, 397, 398, 853, 396, 6, 277, 290, + 291, 362, 366, 626, 636, 591, 495, 580, 582, 333, + 336, 987, 416, 334, 625, 416, 871, 964, 378, 633, + 633, 416, 335, 541, 279, 279, 279, 576, 578, 581, + 581, 353, 563, 576, 377, 328, 531, 944, 26, 330, + 446, 339, 1028, 26, 26, 26, 26, 26, 26, 970, + 343, 1020, 878, 820, 344, 794, 432, 821, 711, 390, + 954, 16, 224, 413, 224, 224, 413, 224, 770, 703, + 315, 315, 413, 224, 224, 881, 917, 448, 844, 441, + 716, 830, 878, 960, 1031, 885, 16, 566, 567, 723, + 904, 643, 764, 852, 854, 492, 620, 967, 663, 652, + 719, 868, 542, 793, 315, 315, 315, 930, 672, 931, + 500, 481, 833, 834, 489, 404, 415, 782, 508, 415, + 224, 224, 300, 490, 767, 415, 951, 408, 408, 224, + 789, 547, 548, 26, 26, 26, 26, 26, 26, 26, + 714, 878, 518, 865, 26, 26, 26, 16, 908, 909, + 380, 16, 383, 270, 116, 306, 16, 274, 26, 515, + 645, 532, 384, 385, 503, 672, 672, 386, 505, 387, + 522, 725, 306, 730, 933, 717, 525, 876, 825, 873, + 297, 16, 952, 958, 507, 297, 280, 827, 504, 513, + 519, 511, 26, 26, 280, nil, 224, 224, 706, nil, + nil, 26, nil, 553, nil, nil, 897, 116, 715, 279, + 777, 1021, 838, nil, 568, 956, 224, 549, 281, 26, + nil, 781, nil, 26, nil, 733, 281, 733, 26, nil, + 264, nil, 224, nil, 754, nil, nil, 488, nil, 759, + nil, 636, 740, nil, 824, 491, nil, 13, nil, nil, + 828, nil, 13, 26, 832, nil, 602, 633, nil, 992, + nil, 129, 279, 279, 614, nil, 597, nil, 26, 26, + nil, 279, 608, nil, nil, nil, nil, nil, 613, 590, + 13, 132, nil, nil, nil, 431, 437, nil, 26, 432, + 134, 792, nil, nil, nil, nil, nil, 403, nil, nil, + nil, nil, nil, 224, 26, 13, 627, 607, nil, 1006, + 631, 621, 441, 612, nil, 354, nil, nil, nil, 15, + nil, nil, 300, 608, 15, nil, 641, 777, nil, nil, + nil, nil, 644, 482, nil, nil, 750, 752, 315, nil, + nil, 755, 757, 790, nil, nil, nil, nil, nil, nil, + 660, nil, 15, nil, nil, 315, 432, 16, 624, 16, + 13, nil, nil, 522, 900, 306, 432, 224, nil, 13, + 13, 522, nil, 306, nil, 26, 640, 15, nil, 441, + 6, 224, nil, nil, nil, nil, nil, 300, 724, 441, + nil, nil, 300, nil, 432, nil, 16, 416, nil, 16, + nil, nil, 432, nil, 923, 224, nil, 416, 416, 700, + 700, nil, 416, 416, nil, 224, 953, 441, nil, 16, + nil, 769, nil, 441, nil, nil, nil, 718, nil, 26, + 948, 26, 15, nil, nil, nil, nil, nil, 432, 26, + 857, 15, 15, nil, 632, 279, nil, nil, 413, 224, + nil, 602, 16, 26, 129, 13, 768, 411, 413, 413, + 411, 441, 791, 413, 413, nil, 411, nil, 26, 705, + nil, 26, 737, 745, 132, 784, 602, 26, 839, 1029, + 13, nil, nil, 134, 662, 849, nil, 26, nil, 608, + 991, 26, 613, 522, nil, 306, nil, nil, nil, 826, + 851, 415, nil, nil, 783, 829, 306, nil, 835, 279, + nil, 415, 415, 880, nil, 882, 415, 415, 431, 437, + 26, 26, nil, nil, 26, nil, 877, 15, 879, 15, + 26, 26, 15, nil, nil, 26, 26, 602, 15, nil, + nil, 13, nil, nil, nil, 13, 602, 279, 315, 416, + 13, nil, 15, 749, nil, nil, 315, 279, nil, nil, + nil, nil, nil, nil, 224, nil, nil, nil, nil, 16, + 224, 602, nil, 16, 857, 13, 408, 857, nil, 857, + nil, 857, nil, 16, nil, 648, 129, nil, 423, 863, + nil, 279, nil, 867, 443, 648, nil, nil, nil, nil, + 413, nil, nil, nil, 855, nil, 891, nil, nil, nil, + nil, nil, nil, 15, nil, nil, nil, 15, nil, nil, + nil, 1007, 15, 648, 963, 855, 965, nil, 16, nil, + 889, 648, 696, nil, nil, 698, 26, 961, nil, 962, + 16, 26, 26, nil, nil, 26, 982, 15, 983, nil, + 984, nil, 902, 415, nil, 26, nil, nil, nil, nil, + 857, 981, 857, nil, 857, nil, 857, 431, 437, nil, + nil, 224, 26, 16, 16, nil, nil, 16, 315, nil, + nil, nil, nil, 16, nil, 855, nil, nil, 700, 315, + nil, 899, nil, nil, nil, nil, 903, 16, 17, 857, + 26, nil, nil, 17, 943, 1025, nil, 1026, nil, 1027, + 920, nil, 26, nil, nil, 16, nil, nil, nil, 926, + 1024, nil, nil, nil, nil, 680, 1030, nil, nil, nil, + nil, 17, 308, 308, nil, nil, nil, nil, nil, 800, + 802, 804, nil, 26, 1038, 26, 26, nil, nil, 26, + nil, 13, nil, 13, nil, 26, 17, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 352, 361, 361, 26, + nil, nil, 971, nil, nil, nil, 16, nil, nil, 976, + nil, nil, 847, 16, 16, nil, nil, 26, nil, nil, + 13, nil, nil, 13, nil, nil, nil, nil, 1002, nil, + nil, 16, nil, nil, 872, nil, nil, 16, nil, 16, + nil, 17, nil, 13, nil, nil, 806, 432, nil, 836, + 17, 17, nil, 15, nil, 15, nil, 443, 224, 423, + nil, nil, nil, nil, nil, 441, nil, nil, 602, nil, + 441, nil, 411, nil, nil, nil, 13, 680, 26, nil, + nil, nil, 411, 411, nil, 26, 26, 411, 411, nil, + nil, nil, 15, nil, 860, 15, nil, nil, nil, nil, + nil, nil, nil, 26, nil, nil, 864, nil, nil, 26, + nil, 26, nil, nil, nil, 15, nil, nil, nil, nil, + nil, nil, nil, 315, nil, nil, nil, nil, 654, nil, + 26, nil, 315, nil, 680, 680, 17, nil, 414, 893, + 894, 414, nil, 896, 15, nil, 957, 414, 15, 847, + nil, 847, nil, 847, 15, 15, nil, nil, nil, 15, + 15, 17, nil, 906, nil, nil, nil, nil, nil, nil, + nil, nil, 806, nil, nil, 887, 935, 937, nil, 939, + 941, 922, 942, nil, nil, 315, 856, nil, nil, nil, + nil, nil, nil, 13, nil, nil, nil, 13, nil, 337, + 279, nil, nil, nil, nil, nil, nil, 13, nil, nil, + 751, 753, 680, nil, 680, 756, 758, nil, nil, nil, + nil, nil, 17, nil, 411, nil, 17, nil, nil, nil, + 308, 17, 847, nil, 847, nil, 847, nil, 847, nil, + nil, nil, 974, nil, nil, nil, nil, 308, nil, 979, + 980, 806, 13, 806, nil, nil, 17, nil, 38, nil, + nil, nil, nil, 38, 13, 15, nil, 989, nil, 15, + nil, 847, nil, 990, nil, nil, 648, nil, 848, 15, + nil, 1015, 1016, 1017, 1018, nil, nil, nil, nil, nil, + nil, 38, 304, 304, nil, nil, 15, 13, 13, nil, + 874, 13, nil, 874, nil, nil, nil, 13, nil, nil, + 985, 806, nil, nil, nil, nil, 38, nil, nil, nil, + nil, 13, nil, 856, 15, 856, 348, 364, 364, 364, + 1037, nil, nil, nil, nil, nil, 15, nil, nil, 13, + nil, nil, nil, 929, nil, nil, nil, 680, 406, 419, + nil, 806, 840, 806, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 751, 753, 758, 756, 15, + 15, 38, nil, 15, nil, nil, nil, nil, nil, 15, + 38, 38, nil, nil, 806, nil, nil, nil, nil, nil, + nil, nil, nil, 15, nil, nil, 911, 913, 915, nil, + 13, 340, 340, nil, nil, 340, 856, 13, 13, nil, + nil, 15, 874, nil, nil, 848, nil, 848, 39, 848, + nil, nil, 497, 39, 499, 13, nil, 501, 502, nil, + nil, 13, 17, 13, 17, nil, nil, nil, nil, nil, + 308, nil, nil, nil, nil, nil, nil, 840, 308, nil, + nil, 39, 305, 305, nil, nil, 340, 340, 340, 340, + nil, nil, nil, nil, nil, nil, 38, nil, nil, nil, + nil, 17, 15, nil, 17, nil, 39, nil, nil, 15, + 15, nil, nil, nil, nil, nil, 349, 365, 365, 365, + nil, 38, nil, nil, 17, nil, nil, 15, 848, nil, + 848, 729, 848, 15, 848, 15, nil, 994, 996, 998, + 1000, nil, 1001, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 414, nil, nil, nil, 17, nil, nil, + nil, 39, nil, 414, 414, nil, nil, 848, 414, 414, + 39, 39, nil, nil, nil, nil, 593, nil, nil, 420, + 421, nil, 38, nil, nil, nil, 38, nil, 444, 445, + 304, 38, nil, nil, nil, nil, nil, nil, nil, nil, + 308, 1033, 1034, 1035, 1036, nil, nil, 304, nil, nil, + nil, 308, nil, nil, nil, 1039, 38, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 39, nil, nil, nil, + nil, nil, nil, 634, nil, 337, nil, 637, nil, nil, + nil, nil, nil, nil, 17, nil, nil, nil, 17, nil, + nil, 39, nil, nil, nil, nil, nil, nil, 17, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 634, nil, 414, 337, nil, nil, nil, + nil, 340, 340, nil, nil, nil, nil, nil, nil, nil, + 419, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 565, nil, 17, nil, nil, nil, nil, nil, nil, + nil, nil, 39, nil, nil, 17, 39, 569, nil, nil, + 305, 39, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 738, nil, nil, nil, 305, nil, nil, + nil, nil, 634, 337, nil, nil, 39, nil, 17, 17, + nil, nil, 17, nil, nil, nil, nil, nil, 17, nil, + nil, nil, 38, nil, 38, nil, nil, nil, nil, nil, + 304, nil, 17, nil, 778, nil, nil, 779, 304, nil, + nil, nil, nil, nil, nil, 361, nil, nil, nil, nil, + 17, nil, nil, nil, 928, nil, nil, 788, nil, nil, + nil, 38, nil, nil, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 812, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 361, nil, nil, + nil, 17, nil, nil, nil, nil, nil, 38, 17, 17, + nil, nil, nil, nil, nil, nil, 656, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 17, nil, 837, nil, + nil, nil, 17, nil, 17, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 304, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 304, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 39, nil, 39, nil, nil, nil, nil, nil, + 305, nil, nil, nil, nil, nil, nil, nil, 305, nil, + nil, nil, nil, nil, 884, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 39, 895, nil, 39, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 38, nil, nil, nil, 38, nil, + 337, nil, nil, nil, 39, nil, nil, nil, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 39, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 38, nil, nil, nil, 340, + nil, nil, nil, nil, nil, 340, nil, nil, nil, nil, + 305, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 305, nil, nil, nil, nil, nil, nil, 38, 38, + nil, nil, 38, nil, nil, nil, nil, nil, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 38, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 364, nil, nil, nil, nil, + 38, nil, nil, nil, 924, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 39, nil, nil, nil, 39, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 39, nil, + nil, nil, nil, nil, nil, nil, 340, nil, nil, nil, + nil, 231, nil, nil, nil, nil, nil, nil, nil, nil, + 278, 278, 278, nil, nil, nil, nil, 364, nil, nil, + nil, 38, nil, 324, 325, 326, nil, nil, 38, 38, + nil, nil, nil, 39, nil, nil, nil, nil, nil, nil, + 278, 278, nil, nil, nil, 39, 38, nil, nil, nil, + nil, nil, 38, nil, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 39, 39, + nil, nil, 39, nil, nil, nil, nil, nil, 39, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 39, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 365, nil, nil, nil, nil, + 39, nil, nil, nil, 925, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 365, nil, nil, + nil, 39, nil, nil, nil, nil, nil, nil, 39, 39, + 278, 418, nil, nil, 424, 278, nil, nil, nil, nil, + 424, nil, nil, nil, nil, nil, 39, nil, nil, nil, + nil, nil, 39, 231, 39, nil, 455, 456, 457, 458, + 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, + 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, + 479, 480, nil, nil, nil, nil, nil, nil, 278, 278, + nil, nil, nil, nil, nil, nil, nil, 278, nil, nil, + nil, nil, nil, nil, 278, nil, 278, nil, nil, 278, + 278, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 527, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 278, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 278, nil, 424, 424, 424, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 278, nil, 278, nil, 278, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 278, nil, nil, nil, nil, + nil, nil, nil, nil, 424, 655, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 278, nil, nil, 278, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 278, 278, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 278, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 278, 424, 278, nil, nil, + nil, 746, nil, nil, 278, 278, 424, 424, nil, nil, + nil, 424, 424, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 278, nil, nil, 278, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 278, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 278, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 278, nil, nil, nil, nil, nil, nil, nil, 424, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 424, 424, 424, 424, nil, 843, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 278, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 278, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 278, 424, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 278 ] + +racc_goto_check = [ + 33, 17, 17, 28, 144, 17, 58, 89, 28, 76, + 29, 38, 8, 70, 10, 99, 95, 74, 74, 31, + 2, 59, 59, 28, 7, 4, 33, 31, 101, 7, + 92, 92, 28, 28, 28, 51, 28, 28, 28, 15, + 15, 62, 62, 41, 22, 22, 188, 30, 53, 6, + 63, 63, 40, 40, 40, 161, 17, 17, 17, 17, + 77, 28, 77, 29, 66, 47, 28, 28, 93, 48, + 28, 28, 28, 28, 52, 43, 20, 94, 94, 99, + 43, 42, 7, 143, 59, 119, 185, 188, 56, 4, + 133, 179, 184, 11, 26, 43, 131, 71, 71, 71, + 26, 5, 1, 122, 43, 43, 43, 137, 43, 121, + 162, 72, 72, 12, 138, 72, 28, 162, 126, 126, + 14, 28, 28, 28, 28, 28, 28, 71, 16, 73, + 73, 73, 147, 43, 11, 19, 173, 7, 43, 43, + 23, 147, 43, 2, 25, 135, 7, 7, 46, 46, + 46, 57, 57, 44, 188, 64, 76, 165, 165, 73, + 73, 122, 18, 69, 75, 18, 135, 185, 87, 77, + 77, 18, 88, 91, 35, 35, 35, 166, 166, 166, + 166, 96, 98, 166, 102, 103, 104, 119, 43, 105, + 49, 106, 137, 43, 43, 43, 43, 43, 43, 138, + 107, 122, 179, 108, 109, 143, 74, 110, 111, 5, + 112, 28, 28, 28, 28, 28, 28, 28, 42, 95, + 67, 67, 28, 28, 28, 184, 135, 31, 133, 59, + 113, 114, 179, 131, 122, 121, 28, 115, 116, 117, + 118, 53, 30, 123, 129, 49, 29, 136, 139, 53, + 8, 140, 141, 142, 67, 67, 67, 145, 173, 146, + 161, 148, 143, 143, 150, 20, 20, 30, 49, 20, + 28, 28, 9, 151, 154, 20, 155, 71, 71, 28, + 156, 17, 17, 43, 43, 43, 43, 43, 43, 43, + 56, 179, 33, 157, 43, 43, 43, 28, 126, 126, + 160, 28, 163, 74, 99, 28, 28, 74, 43, 31, + 29, 33, 164, 167, 4, 173, 173, 168, 7, 169, + 51, 170, 28, 171, 126, 172, 31, 177, 30, 181, + 47, 28, 11, 182, 48, 47, 71, 30, 6, 48, + 66, 52, 43, 43, 71, nil, 28, 28, 29, nil, + nil, 43, nil, 31, nil, nil, 94, 99, 29, 35, + 76, 93, 30, nil, 38, 101, 28, 4, 73, 43, + nil, 53, nil, 43, nil, 166, 73, 166, 43, nil, + 31, nil, 28, nil, 41, nil, nil, 46, nil, 41, + nil, 188, 29, nil, 92, 46, nil, 21, nil, nil, + 8, nil, 21, 43, 8, nil, 33, 77, nil, 126, + nil, 59, 35, 35, 49, nil, 31, nil, 43, 43, + nil, 35, 74, nil, nil, nil, nil, nil, 74, 15, + 21, 62, nil, nil, nil, 39, 39, nil, 43, 74, + 63, 72, nil, nil, nil, nil, nil, 9, nil, nil, + nil, nil, nil, 28, 43, 21, 49, 40, nil, 10, + 49, 33, 59, 40, nil, 21, nil, nil, nil, 27, + nil, nil, 9, 74, 27, nil, 49, 76, nil, nil, + nil, nil, 49, 39, nil, nil, 26, 26, 67, nil, + nil, 26, 26, 22, nil, nil, nil, nil, nil, nil, + 49, nil, 27, nil, nil, 67, 74, 28, 40, 28, + 21, nil, nil, 51, 8, 28, 74, 28, nil, 21, + 21, 51, nil, 28, nil, 43, 2, 27, nil, 59, + 7, 28, nil, nil, nil, nil, nil, 9, 49, 59, + nil, nil, 9, nil, 74, nil, 28, 18, nil, 28, + nil, nil, 74, nil, 92, 28, nil, 18, 18, 99, + 99, nil, 18, 18, nil, 28, 95, 59, nil, 28, + nil, 89, nil, 59, nil, nil, nil, 99, nil, 43, + 92, 43, 27, nil, nil, nil, nil, nil, 74, 43, + 180, 27, 27, nil, 73, 35, nil, nil, 28, 28, + nil, 33, 28, 43, 59, 21, 144, 21, 28, 28, + 21, 59, 70, 28, 28, nil, 21, nil, 43, 71, + nil, 43, 15, 7, 62, 49, 33, 43, 26, 30, + 21, nil, nil, 63, 73, 130, nil, 43, nil, 74, + 8, 43, 74, 51, nil, 28, nil, nil, nil, 17, + 132, 20, nil, nil, 51, 17, 28, nil, 58, 35, + nil, 20, 20, 130, nil, 130, 20, 20, 39, 39, + 43, 43, nil, nil, 43, nil, 132, 27, 132, 27, + 43, 43, 27, nil, nil, 43, 43, 33, 27, nil, + nil, 21, nil, nil, nil, 21, 33, 35, 67, 18, + 21, nil, 27, 73, nil, nil, 67, 35, nil, nil, + nil, nil, nil, nil, 28, nil, nil, nil, nil, 28, + 28, 33, nil, 28, 180, 21, 71, 180, nil, 180, + nil, 180, nil, 28, nil, 39, 59, nil, 65, 70, + nil, 35, nil, 70, 65, 39, nil, nil, nil, nil, + 28, nil, nil, nil, 33, nil, 17, nil, nil, nil, + nil, nil, nil, 27, nil, nil, nil, 27, nil, nil, + nil, 29, 27, 39, 130, 33, 130, nil, 28, nil, + 49, 39, 9, nil, nil, 9, 43, 132, nil, 132, + 28, 43, 43, nil, nil, 43, 130, 27, 130, nil, + 130, nil, 49, 20, nil, 43, nil, nil, nil, nil, + 180, 132, 180, nil, 180, nil, 180, 39, 39, nil, + nil, 28, 43, 28, 28, nil, nil, 28, 67, nil, + nil, nil, nil, 28, nil, 33, nil, nil, 99, 67, + nil, 99, nil, nil, nil, nil, 99, 28, 32, 180, + 43, nil, nil, 32, 49, 130, nil, 130, nil, 130, + 28, nil, 43, nil, nil, 28, nil, nil, nil, 28, + 132, nil, nil, nil, nil, 178, 130, nil, nil, nil, + nil, 32, 32, 32, nil, nil, nil, nil, nil, 176, + 176, 176, nil, 43, 130, 43, 43, nil, nil, 43, + nil, 21, nil, 21, nil, 43, 32, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 32, 32, 32, 43, + nil, nil, 28, nil, nil, nil, 28, nil, nil, 31, + nil, nil, 125, 28, 28, nil, nil, 43, nil, nil, + 21, nil, nil, 21, nil, nil, nil, nil, 33, nil, + nil, 28, nil, nil, 125, nil, nil, 28, nil, 28, + nil, 32, nil, 21, nil, nil, 120, 74, nil, 9, + 32, 32, nil, 27, nil, 27, nil, 65, 28, 65, + nil, nil, nil, nil, nil, 59, nil, nil, 33, nil, + 59, nil, 21, nil, nil, nil, 21, 178, 43, nil, + nil, nil, 21, 21, nil, 43, 43, 21, 21, nil, + nil, nil, 27, nil, 9, 27, nil, nil, nil, nil, + nil, nil, nil, 43, nil, nil, 9, nil, nil, 43, + nil, 43, nil, nil, nil, 27, nil, nil, nil, nil, + nil, nil, nil, 67, nil, nil, nil, nil, 65, nil, + 43, nil, 67, nil, 178, 178, 32, nil, 32, 9, + 9, 32, nil, 9, 27, nil, 125, 32, 27, 125, + nil, 125, nil, 125, 27, 27, nil, nil, nil, 27, + 27, 32, nil, 9, nil, nil, nil, nil, nil, nil, + nil, nil, 120, nil, nil, 120, 176, 176, nil, 176, + 176, 9, 176, nil, nil, 67, 178, nil, nil, nil, + nil, nil, nil, 21, nil, nil, nil, 21, nil, 68, + 35, nil, nil, nil, nil, nil, nil, 21, nil, nil, + 65, 65, 178, nil, 178, 65, 65, nil, nil, nil, + nil, nil, 32, nil, 21, nil, 32, nil, nil, nil, + 32, 32, 125, nil, 125, nil, 125, nil, 125, nil, + nil, nil, 9, nil, nil, nil, nil, 32, nil, 9, + 9, 120, 21, 120, nil, nil, 32, nil, 54, nil, + nil, nil, nil, 54, 21, 27, nil, 9, nil, 27, + nil, 125, nil, 9, nil, nil, 39, nil, 127, 27, + nil, 176, 176, 176, 176, nil, nil, nil, nil, nil, + nil, 54, 54, 54, nil, nil, 27, 21, 21, nil, + 127, 21, nil, 127, nil, nil, nil, 21, nil, nil, + 120, 120, nil, nil, nil, nil, 54, nil, nil, nil, + nil, 21, nil, 178, 27, 178, 54, 54, 54, 54, + 176, nil, nil, nil, nil, nil, 27, nil, nil, 21, + nil, nil, nil, 21, nil, nil, nil, 178, 68, 68, + nil, 120, 65, 120, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 65, 65, 65, 65, 27, + 27, 54, nil, 27, nil, nil, nil, nil, nil, 27, + 54, 54, nil, nil, 120, nil, nil, nil, nil, nil, + nil, nil, nil, 27, nil, nil, 128, 128, 128, nil, + 21, 24, 24, nil, nil, 24, 178, 21, 21, nil, + nil, 27, 127, nil, nil, 127, nil, 127, 55, 127, + nil, nil, 68, 55, 68, 21, nil, 68, 68, nil, + nil, 21, 32, 21, 32, nil, nil, nil, nil, nil, + 32, nil, nil, nil, nil, nil, nil, 65, 32, nil, + nil, 55, 55, 55, nil, nil, 24, 24, 24, 24, + nil, nil, nil, nil, nil, nil, 54, nil, nil, nil, + nil, 32, 27, nil, 32, nil, 55, nil, nil, 27, + 27, nil, nil, nil, nil, nil, 55, 55, 55, 55, + nil, 54, nil, nil, 32, nil, nil, 27, 127, nil, + 127, 32, 127, 27, 127, 27, nil, 128, 128, 128, + 128, nil, 128, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 32, nil, nil, nil, 32, nil, nil, + nil, 55, nil, 32, 32, nil, nil, 127, 32, 32, + 55, 55, nil, nil, nil, nil, 68, nil, nil, 24, + 24, nil, 54, nil, nil, nil, 54, nil, 24, 24, + 54, 54, nil, nil, nil, nil, nil, nil, nil, nil, + 32, 128, 128, 128, 128, nil, nil, 54, nil, nil, + nil, 32, nil, nil, nil, 128, 54, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 55, nil, nil, nil, + nil, nil, nil, 68, nil, 68, nil, 68, nil, nil, + nil, nil, nil, nil, 32, nil, nil, nil, 32, nil, + nil, 55, nil, nil, nil, nil, nil, nil, 32, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 68, nil, 32, 68, nil, nil, nil, + nil, 24, 24, nil, nil, nil, nil, nil, nil, nil, + 68, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 24, nil, 32, nil, nil, nil, nil, nil, nil, + nil, nil, 55, nil, nil, 32, 55, 24, nil, nil, + 55, 55, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 68, nil, nil, nil, 55, nil, nil, + nil, nil, 68, 68, nil, nil, 55, nil, 32, 32, + nil, nil, 32, nil, nil, nil, nil, nil, 32, nil, + nil, nil, 54, nil, 54, nil, nil, nil, nil, nil, + 54, nil, 32, nil, 68, nil, nil, 68, 54, nil, + nil, nil, nil, nil, nil, 32, nil, nil, nil, nil, + 32, nil, nil, nil, 32, nil, nil, 68, nil, nil, + nil, 54, nil, nil, 54, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 68, 54, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 32, nil, nil, + nil, 32, nil, nil, nil, nil, nil, 54, 32, 32, + nil, nil, nil, nil, nil, nil, 24, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 32, nil, 68, nil, + nil, nil, 32, nil, 32, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 54, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 54, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 55, nil, 55, nil, nil, nil, nil, nil, + 55, nil, nil, nil, nil, nil, nil, nil, 55, nil, + nil, nil, nil, nil, 68, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 55, 68, nil, 55, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 54, nil, nil, nil, 54, nil, + 68, nil, nil, nil, 55, nil, nil, nil, 54, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 55, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 54, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 54, nil, nil, nil, 24, + nil, nil, nil, nil, nil, 24, nil, nil, nil, nil, + 55, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 55, nil, nil, nil, nil, nil, nil, 54, 54, + nil, nil, 54, nil, nil, nil, nil, nil, 54, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 54, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 54, nil, nil, nil, nil, + 54, nil, nil, nil, 54, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 55, nil, nil, nil, 55, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 55, nil, + nil, nil, nil, nil, nil, nil, 24, nil, nil, nil, + nil, 34, nil, nil, nil, nil, nil, nil, nil, nil, + 34, 34, 34, nil, nil, nil, nil, 54, nil, nil, + nil, 54, nil, 34, 34, 34, nil, nil, 54, 54, + nil, nil, nil, 55, nil, nil, nil, nil, nil, nil, + 34, 34, nil, nil, nil, 55, 54, nil, nil, nil, + nil, nil, 54, nil, 54, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 55, 55, + nil, nil, 55, nil, nil, nil, nil, nil, 55, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 55, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 55, nil, nil, nil, nil, + 55, nil, nil, nil, 55, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 55, nil, nil, + nil, 55, nil, nil, nil, nil, nil, nil, 55, 55, + 34, 34, nil, nil, 34, 34, nil, nil, nil, nil, + 34, nil, nil, nil, nil, nil, 55, nil, nil, nil, + nil, nil, 55, 34, 55, nil, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, nil, nil, nil, nil, nil, nil, 34, 34, + nil, nil, nil, nil, nil, nil, nil, 34, nil, nil, + nil, nil, nil, nil, 34, nil, 34, nil, nil, 34, + 34, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 34, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 34, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 34, nil, 34, 34, 34, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 34, nil, 34, nil, 34, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 34, nil, nil, nil, nil, + nil, nil, nil, nil, 34, 34, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 34, nil, nil, 34, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 34, 34, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 34, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 34, 34, 34, nil, nil, + nil, 34, nil, nil, 34, 34, 34, 34, nil, nil, + nil, 34, 34, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 34, nil, nil, 34, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 34, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 34, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 34, nil, nil, nil, nil, nil, nil, nil, 34, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 34, 34, 34, 34, nil, 34, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 34, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 34, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 34, 34, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 34 ] + +racc_goto_pointer = [ + nil, 102, 20, nil, 22, 96, 46, 24, -316, 239, + -515, -564, -672, nil, -384, 31, 119, -62, -48, 67, + 56, 397, -165, -69, 1258, 20, -119, 469, 3, -204, + -378, 3, 848, -19, 2061, 145, nil, nil, -13, 220, + 26, -223, -408, 75, -332, nil, 119, 32, 36, -31, + nil, 1, 39, -271, 1178, 1338, -270, 82, -65, 13, + nil, nil, 33, 42, -247, 525, 23, 186, 1059, 104, + -46, 68, -221, 100, -9, -318, -272, -434, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 97, 112, -54, + nil, -166, -311, -628, -470, -330, 113, nil, -180, 12, + nil, -539, 113, 128, -143, 131, 129, 135, -496, 138, + -495, -348, -687, -333, -487, -129, -138, -329, -595, -801, + 285, -572, -785, -530, nil, 159, -548, 425, 467, -529, + -138, -677, -123, -539, nil, -628, -671, -811, -804, -294, + -542, -87, -410, -459, -18, -612, -611, -349, 0, nil, + -7, 1, nil, nil, -349, -620, -378, -496, nil, nil, + 221, -26, 26, 217, 226, -227, -205, 226, 229, 230, + -252, -251, -239, -406, nil, nil, 220, -472, 333, -708, + -183, -466, -574, nil, -709, -826, nil, nil, -450 ] + +racc_goto_default = [ + nil, nil, nil, 3, nil, 4, 347, 295, nil, 529, + nil, 817, nil, 292, 293, nil, nil, nil, 11, 12, + 18, 229, nil, nil, 14, nil, 412, 230, 323, nil, + nil, 561, 228, 447, 21, 22, 23, 24, nil, 651, + nil, nil, nil, 312, nil, 25, 426, 32, nil, nil, + 34, 37, 36, nil, 225, 226, 359, nil, 131, 434, + 130, 133, 77, 78, nil, 417, 92, 46, 284, nil, + 786, 427, nil, 428, 439, 609, 493, 282, 268, 47, + 48, 49, 50, 51, 52, 53, 54, 55, nil, 269, + 61, nil, nil, nil, nil, nil, nil, 69, nil, 544, + 70, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 808, + 679, nil, 809, 959, 846, 667, nil, 668, nil, nil, + 669, nil, 671, nil, 772, nil, nil, nil, 677, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 438, + nil, nil, 629, 623, nil, nil, nil, nil, 76, 79, + 80, nil, nil, nil, nil, nil, 571, nil, nil, nil, + nil, nil, nil, 875, 722, 666, nil, 670, 883, 682, + 684, 685, 858, 688, 689, 859, 692, 695, 287 ] + +racc_reduce_table = [ + 0, 0, :racc_error, + 1, 146, :_reduce_none, + 2, 147, :_reduce_2, + 0, 148, :_reduce_3, + 1, 148, :_reduce_4, + 3, 148, :_reduce_5, + 2, 148, :_reduce_6, + 1, 150, :_reduce_none, + 4, 150, :_reduce_8, + 4, 153, :_reduce_9, + 2, 154, :_reduce_10, + 0, 158, :_reduce_11, + 1, 158, :_reduce_12, + 3, 158, :_reduce_13, + 2, 158, :_reduce_14, + 1, 159, :_reduce_none, + 4, 159, :_reduce_16, + 0, 170, :_reduce_17, + 4, 152, :_reduce_18, + 3, 152, :_reduce_19, + 3, 152, :_reduce_20, + 3, 152, :_reduce_21, + 2, 152, :_reduce_22, + 3, 152, :_reduce_23, + 3, 152, :_reduce_24, + 3, 152, :_reduce_25, + 3, 152, :_reduce_26, + 3, 152, :_reduce_27, + 4, 152, :_reduce_28, + 1, 152, :_reduce_none, + 3, 152, :_reduce_30, + 3, 152, :_reduce_31, + 3, 152, :_reduce_32, + 1, 152, :_reduce_none, + 3, 163, :_reduce_34, + 3, 163, :_reduce_35, + 6, 163, :_reduce_36, + 5, 163, :_reduce_37, + 5, 163, :_reduce_38, + 5, 163, :_reduce_39, + 5, 163, :_reduce_40, + 3, 163, :_reduce_41, + 1, 171, :_reduce_none, + 3, 171, :_reduce_43, + 1, 171, :_reduce_none, + 1, 169, :_reduce_none, + 3, 169, :_reduce_46, + 3, 169, :_reduce_47, + 3, 169, :_reduce_48, + 2, 169, :_reduce_49, + 1, 169, :_reduce_none, + 1, 162, :_reduce_none, + 1, 165, :_reduce_none, + 1, 165, :_reduce_none, + 1, 181, :_reduce_none, + 4, 181, :_reduce_55, + 0, 189, :_reduce_56, + 4, 186, :_reduce_57, + 1, 188, :_reduce_none, + 2, 180, :_reduce_59, + 3, 180, :_reduce_60, + 4, 180, :_reduce_61, + 5, 180, :_reduce_62, + 4, 180, :_reduce_63, + 5, 180, :_reduce_64, + 2, 180, :_reduce_65, + 2, 180, :_reduce_66, + 2, 180, :_reduce_67, + 2, 180, :_reduce_68, + 2, 180, :_reduce_69, + 1, 164, :_reduce_70, + 3, 164, :_reduce_71, + 1, 193, :_reduce_72, + 3, 193, :_reduce_73, + 1, 192, :_reduce_none, + 2, 192, :_reduce_75, + 3, 192, :_reduce_76, + 5, 192, :_reduce_77, + 2, 192, :_reduce_78, + 4, 192, :_reduce_79, + 2, 192, :_reduce_80, + 4, 192, :_reduce_81, + 1, 192, :_reduce_82, + 3, 192, :_reduce_83, + 1, 196, :_reduce_none, + 3, 196, :_reduce_85, + 2, 195, :_reduce_86, + 3, 195, :_reduce_87, + 1, 198, :_reduce_88, + 3, 198, :_reduce_89, + 1, 197, :_reduce_90, + 1, 197, :_reduce_91, + 4, 197, :_reduce_92, + 3, 197, :_reduce_93, + 3, 197, :_reduce_94, + 3, 197, :_reduce_95, + 3, 197, :_reduce_96, + 2, 197, :_reduce_97, + 1, 197, :_reduce_98, + 1, 166, :_reduce_99, + 1, 166, :_reduce_100, + 4, 166, :_reduce_101, + 3, 166, :_reduce_102, + 3, 166, :_reduce_103, + 3, 166, :_reduce_104, + 3, 166, :_reduce_105, + 2, 166, :_reduce_106, + 1, 166, :_reduce_107, + 1, 201, :_reduce_108, + 1, 201, :_reduce_none, + 2, 202, :_reduce_110, + 1, 202, :_reduce_111, + 3, 202, :_reduce_112, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 203, :_reduce_none, + 1, 206, :_reduce_118, + 1, 206, :_reduce_none, + 1, 160, :_reduce_none, + 1, 160, :_reduce_none, + 1, 161, :_reduce_122, + 0, 209, :_reduce_123, + 4, 161, :_reduce_124, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 1, 205, :_reduce_none, + 3, 179, :_reduce_196, + 3, 179, :_reduce_197, + 6, 179, :_reduce_198, + 5, 179, :_reduce_199, + 5, 179, :_reduce_200, + 5, 179, :_reduce_201, + 5, 179, :_reduce_202, + 4, 179, :_reduce_203, + 3, 179, :_reduce_204, + 3, 179, :_reduce_205, + 3, 179, :_reduce_206, + 3, 179, :_reduce_207, + 3, 179, :_reduce_208, + 3, 179, :_reduce_209, + 3, 179, :_reduce_210, + 3, 179, :_reduce_211, + 3, 179, :_reduce_212, + 4, 179, :_reduce_213, + 2, 179, :_reduce_214, + 2, 179, :_reduce_215, + 3, 179, :_reduce_216, + 3, 179, :_reduce_217, + 3, 179, :_reduce_218, + 3, 179, :_reduce_219, + 3, 179, :_reduce_220, + 3, 179, :_reduce_221, + 3, 179, :_reduce_222, + 3, 179, :_reduce_223, + 3, 179, :_reduce_224, + 3, 179, :_reduce_225, + 3, 179, :_reduce_226, + 3, 179, :_reduce_227, + 3, 179, :_reduce_228, + 2, 179, :_reduce_229, + 2, 179, :_reduce_230, + 3, 179, :_reduce_231, + 3, 179, :_reduce_232, + 3, 179, :_reduce_233, + 3, 179, :_reduce_234, + 3, 179, :_reduce_235, + 6, 179, :_reduce_236, + 1, 179, :_reduce_none, + 1, 213, :_reduce_none, + 1, 214, :_reduce_none, + 2, 214, :_reduce_none, + 4, 214, :_reduce_241, + 2, 214, :_reduce_242, + 1, 210, :_reduce_none, + 3, 210, :_reduce_244, + 3, 219, :_reduce_245, + 0, 220, :_reduce_246, + 1, 220, :_reduce_none, + 0, 174, :_reduce_248, + 1, 174, :_reduce_none, + 2, 174, :_reduce_none, + 4, 174, :_reduce_251, + 2, 174, :_reduce_252, + 1, 191, :_reduce_253, + 2, 191, :_reduce_254, + 2, 191, :_reduce_255, + 4, 191, :_reduce_256, + 1, 191, :_reduce_257, + 0, 223, :_reduce_258, + 2, 185, :_reduce_259, + 2, 222, :_reduce_260, + 2, 221, :_reduce_261, + 0, 221, :_reduce_262, + 1, 216, :_reduce_263, + 2, 216, :_reduce_264, + 3, 216, :_reduce_265, + 4, 216, :_reduce_266, + 1, 168, :_reduce_267, + 1, 168, :_reduce_none, + 3, 167, :_reduce_269, + 4, 167, :_reduce_270, + 2, 167, :_reduce_271, + 1, 212, :_reduce_none, + 1, 212, :_reduce_none, + 1, 212, :_reduce_none, + 1, 212, :_reduce_none, + 1, 212, :_reduce_none, + 1, 212, :_reduce_none, + 1, 212, :_reduce_none, + 1, 212, :_reduce_none, + 1, 212, :_reduce_none, + 1, 212, :_reduce_none, + 1, 212, :_reduce_282, + 0, 248, :_reduce_283, + 4, 212, :_reduce_284, + 0, 249, :_reduce_285, + 4, 212, :_reduce_286, + 0, 250, :_reduce_287, + 4, 212, :_reduce_288, + 3, 212, :_reduce_289, + 3, 212, :_reduce_290, + 2, 212, :_reduce_291, + 3, 212, :_reduce_292, + 3, 212, :_reduce_293, + 1, 212, :_reduce_294, + 4, 212, :_reduce_295, + 3, 212, :_reduce_296, + 1, 212, :_reduce_297, + 5, 212, :_reduce_298, + 4, 212, :_reduce_299, + 3, 212, :_reduce_300, + 2, 212, :_reduce_301, + 1, 212, :_reduce_none, + 2, 212, :_reduce_303, + 0, 251, :_reduce_304, + 3, 212, :_reduce_305, + 6, 212, :_reduce_306, + 6, 212, :_reduce_307, + 0, 252, :_reduce_308, + 0, 253, :_reduce_309, + 7, 212, :_reduce_310, + 0, 254, :_reduce_311, + 0, 255, :_reduce_312, + 7, 212, :_reduce_313, + 5, 212, :_reduce_314, + 4, 212, :_reduce_315, + 0, 256, :_reduce_316, + 0, 257, :_reduce_317, + 9, 212, :_reduce_318, + 0, 258, :_reduce_319, + 6, 212, :_reduce_320, + 0, 259, :_reduce_321, + 7, 212, :_reduce_322, + 0, 260, :_reduce_323, + 5, 212, :_reduce_324, + 0, 261, :_reduce_325, + 6, 212, :_reduce_326, + 0, 262, :_reduce_327, + 0, 263, :_reduce_328, + 9, 212, :_reduce_329, + 1, 212, :_reduce_330, + 1, 212, :_reduce_331, + 1, 212, :_reduce_332, + 1, 212, :_reduce_333, + 1, 173, :_reduce_none, + 1, 242, :_reduce_335, + 1, 245, :_reduce_336, + 1, 237, :_reduce_none, + 1, 237, :_reduce_none, + 2, 237, :_reduce_339, + 1, 239, :_reduce_none, + 1, 239, :_reduce_none, + 1, 238, :_reduce_none, + 5, 238, :_reduce_343, + 1, 156, :_reduce_none, + 2, 156, :_reduce_345, + 1, 241, :_reduce_none, + 1, 241, :_reduce_none, + 1, 264, :_reduce_348, + 3, 264, :_reduce_349, + 1, 267, :_reduce_350, + 3, 267, :_reduce_351, + 1, 266, :_reduce_none, + 4, 266, :_reduce_353, + 6, 266, :_reduce_354, + 3, 266, :_reduce_355, + 5, 266, :_reduce_356, + 2, 266, :_reduce_357, + 4, 266, :_reduce_358, + 1, 266, :_reduce_359, + 3, 266, :_reduce_360, + 4, 268, :_reduce_361, + 2, 268, :_reduce_362, + 2, 268, :_reduce_363, + 1, 268, :_reduce_364, + 2, 273, :_reduce_365, + 0, 273, :_reduce_366, + 6, 274, :_reduce_367, + 8, 274, :_reduce_368, + 4, 274, :_reduce_369, + 6, 274, :_reduce_370, + 4, 274, :_reduce_371, + 2, 274, :_reduce_none, + 6, 274, :_reduce_373, + 2, 274, :_reduce_374, + 4, 274, :_reduce_375, + 6, 274, :_reduce_376, + 2, 274, :_reduce_377, + 4, 274, :_reduce_378, + 2, 274, :_reduce_379, + 4, 274, :_reduce_380, + 1, 274, :_reduce_none, + 0, 278, :_reduce_382, + 1, 278, :_reduce_383, + 3, 279, :_reduce_384, + 1, 279, :_reduce_385, + 4, 279, :_reduce_386, + 1, 280, :_reduce_387, + 4, 280, :_reduce_388, + 1, 281, :_reduce_389, + 3, 281, :_reduce_390, + 1, 282, :_reduce_391, + 1, 282, :_reduce_none, + 0, 286, :_reduce_393, + 0, 287, :_reduce_394, + 4, 236, :_reduce_395, + 4, 284, :_reduce_396, + 1, 284, :_reduce_397, + 0, 290, :_reduce_398, + 4, 285, :_reduce_399, + 0, 291, :_reduce_400, + 4, 285, :_reduce_401, + 0, 293, :_reduce_402, + 4, 289, :_reduce_403, + 2, 182, :_reduce_404, + 4, 182, :_reduce_405, + 5, 182, :_reduce_406, + 5, 182, :_reduce_407, + 2, 235, :_reduce_408, + 4, 235, :_reduce_409, + 4, 235, :_reduce_410, + 3, 235, :_reduce_411, + 3, 235, :_reduce_412, + 3, 235, :_reduce_413, + 2, 235, :_reduce_414, + 1, 235, :_reduce_415, + 4, 235, :_reduce_416, + 0, 295, :_reduce_417, + 4, 234, :_reduce_418, + 0, 296, :_reduce_419, + 4, 234, :_reduce_420, + 0, 297, :_reduce_421, + 3, 187, :_reduce_422, + 0, 298, :_reduce_423, + 0, 299, :_reduce_424, + 4, 292, :_reduce_425, + 5, 240, :_reduce_426, + 1, 300, :_reduce_427, + 1, 300, :_reduce_none, + 6, 155, :_reduce_429, + 0, 155, :_reduce_430, + 1, 301, :_reduce_431, + 1, 301, :_reduce_none, + 1, 301, :_reduce_none, + 2, 302, :_reduce_434, + 1, 302, :_reduce_none, + 2, 157, :_reduce_436, + 1, 157, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 225, :_reduce_441, + 1, 304, :_reduce_442, + 2, 304, :_reduce_443, + 3, 305, :_reduce_444, + 1, 305, :_reduce_445, + 1, 305, :_reduce_446, + 3, 226, :_reduce_447, + 4, 227, :_reduce_448, + 3, 228, :_reduce_449, + 0, 309, :_reduce_450, + 3, 309, :_reduce_451, + 1, 310, :_reduce_452, + 2, 310, :_reduce_453, + 3, 230, :_reduce_454, + 0, 312, :_reduce_455, + 3, 312, :_reduce_456, + 3, 229, :_reduce_457, + 3, 231, :_reduce_458, + 0, 313, :_reduce_459, + 3, 313, :_reduce_460, + 0, 314, :_reduce_461, + 3, 314, :_reduce_462, + 0, 306, :_reduce_463, + 2, 306, :_reduce_464, + 0, 307, :_reduce_465, + 2, 307, :_reduce_466, + 0, 308, :_reduce_467, + 2, 308, :_reduce_468, + 1, 311, :_reduce_469, + 2, 311, :_reduce_470, + 0, 316, :_reduce_471, + 4, 311, :_reduce_472, + 1, 315, :_reduce_473, + 1, 315, :_reduce_474, + 1, 315, :_reduce_475, + 1, 315, :_reduce_none, + 1, 207, :_reduce_477, + 3, 208, :_reduce_478, + 1, 303, :_reduce_479, + 2, 303, :_reduce_480, + 1, 211, :_reduce_481, + 1, 211, :_reduce_482, + 1, 211, :_reduce_483, + 1, 211, :_reduce_484, + 1, 199, :_reduce_485, + 1, 199, :_reduce_486, + 1, 199, :_reduce_487, + 1, 199, :_reduce_488, + 1, 199, :_reduce_489, + 1, 200, :_reduce_490, + 1, 200, :_reduce_491, + 1, 200, :_reduce_492, + 1, 200, :_reduce_493, + 1, 200, :_reduce_494, + 1, 200, :_reduce_495, + 1, 200, :_reduce_496, + 1, 232, :_reduce_497, + 1, 232, :_reduce_498, + 1, 172, :_reduce_499, + 1, 172, :_reduce_500, + 1, 177, :_reduce_501, + 1, 177, :_reduce_502, + 0, 317, :_reduce_503, + 4, 243, :_reduce_504, + 0, 243, :_reduce_505, + 3, 246, :_reduce_506, + 0, 319, :_reduce_507, + 3, 246, :_reduce_508, + 4, 318, :_reduce_509, + 2, 318, :_reduce_510, + 2, 318, :_reduce_511, + 1, 318, :_reduce_512, + 2, 321, :_reduce_513, + 0, 321, :_reduce_514, + 6, 288, :_reduce_515, + 8, 288, :_reduce_516, + 4, 288, :_reduce_517, + 6, 288, :_reduce_518, + 4, 288, :_reduce_519, + 6, 288, :_reduce_520, + 2, 288, :_reduce_521, + 4, 288, :_reduce_522, + 6, 288, :_reduce_523, + 2, 288, :_reduce_524, + 4, 288, :_reduce_525, + 2, 288, :_reduce_526, + 4, 288, :_reduce_527, + 1, 288, :_reduce_528, + 0, 288, :_reduce_529, + 1, 283, :_reduce_530, + 1, 283, :_reduce_531, + 1, 283, :_reduce_532, + 1, 283, :_reduce_533, + 1, 265, :_reduce_none, + 1, 265, :_reduce_535, + 1, 323, :_reduce_536, + 1, 324, :_reduce_537, + 3, 324, :_reduce_538, + 1, 275, :_reduce_539, + 3, 275, :_reduce_540, + 1, 325, :_reduce_541, + 2, 326, :_reduce_542, + 1, 326, :_reduce_543, + 2, 327, :_reduce_544, + 1, 327, :_reduce_545, + 1, 269, :_reduce_546, + 3, 269, :_reduce_547, + 1, 320, :_reduce_548, + 3, 320, :_reduce_549, + 1, 328, :_reduce_none, + 1, 328, :_reduce_none, + 2, 270, :_reduce_552, + 1, 270, :_reduce_553, + 3, 329, :_reduce_554, + 3, 330, :_reduce_555, + 1, 276, :_reduce_556, + 3, 276, :_reduce_557, + 1, 322, :_reduce_558, + 3, 322, :_reduce_559, + 1, 331, :_reduce_none, + 1, 331, :_reduce_none, + 2, 277, :_reduce_562, + 1, 277, :_reduce_563, + 1, 332, :_reduce_none, + 1, 332, :_reduce_none, + 2, 272, :_reduce_566, + 2, 271, :_reduce_567, + 0, 271, :_reduce_568, + 1, 247, :_reduce_none, + 3, 247, :_reduce_570, + 0, 233, :_reduce_571, + 2, 233, :_reduce_none, + 1, 218, :_reduce_573, + 3, 218, :_reduce_574, + 3, 333, :_reduce_575, + 2, 333, :_reduce_576, + 4, 333, :_reduce_577, + 2, 333, :_reduce_578, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 190, :_reduce_none, + 1, 184, :_reduce_none, + 1, 184, :_reduce_none, + 1, 184, :_reduce_none, + 1, 184, :_reduce_none, + 1, 294, :_reduce_none, + 1, 294, :_reduce_none, + 1, 294, :_reduce_none, + 1, 183, :_reduce_none, + 1, 183, :_reduce_none, + 1, 176, :_reduce_591, + 1, 176, :_reduce_592, + 0, 149, :_reduce_none, + 1, 149, :_reduce_none, + 0, 178, :_reduce_none, + 1, 178, :_reduce_none, + 2, 194, :_reduce_597, + 2, 175, :_reduce_598, + 0, 217, :_reduce_none, + 1, 217, :_reduce_none, + 1, 217, :_reduce_none, + 1, 244, :_reduce_602, + 1, 244, :_reduce_none, + 1, 151, :_reduce_none, + 2, 151, :_reduce_none, + 0, 215, :_reduce_606 ] + +racc_reduce_n = 607 + +racc_shift_n = 1040 + +racc_token_table = { + false => 0, + :error => 1, + :kCLASS => 2, + :kMODULE => 3, + :kDEF => 4, + :kUNDEF => 5, + :kBEGIN => 6, + :kRESCUE => 7, + :kENSURE => 8, + :kEND => 9, + :kIF => 10, + :kUNLESS => 11, + :kTHEN => 12, + :kELSIF => 13, + :kELSE => 14, + :kCASE => 15, + :kWHEN => 16, + :kWHILE => 17, + :kUNTIL => 18, + :kFOR => 19, + :kBREAK => 20, + :kNEXT => 21, + :kREDO => 22, + :kRETRY => 23, + :kIN => 24, + :kDO => 25, + :kDO_COND => 26, + :kDO_BLOCK => 27, + :kDO_LAMBDA => 28, + :kRETURN => 29, + :kYIELD => 30, + :kSUPER => 31, + :kSELF => 32, + :kNIL => 33, + :kTRUE => 34, + :kFALSE => 35, + :kAND => 36, + :kOR => 37, + :kNOT => 38, + :kIF_MOD => 39, + :kUNLESS_MOD => 40, + :kWHILE_MOD => 41, + :kUNTIL_MOD => 42, + :kRESCUE_MOD => 43, + :kALIAS => 44, + :kDEFINED => 45, + :klBEGIN => 46, + :klEND => 47, + :k__LINE__ => 48, + :k__FILE__ => 49, + :k__ENCODING__ => 50, + :tIDENTIFIER => 51, + :tFID => 52, + :tGVAR => 53, + :tIVAR => 54, + :tCONSTANT => 55, + :tLABEL => 56, + :tCVAR => 57, + :tNTH_REF => 58, + :tBACK_REF => 59, + :tSTRING_CONTENT => 60, + :tINTEGER => 61, + :tFLOAT => 62, + :tUPLUS => 63, + :tUMINUS => 64, + :tUNARY_NUM => 65, + :tPOW => 66, + :tCMP => 67, + :tEQ => 68, + :tEQQ => 69, + :tNEQ => 70, + :tGEQ => 71, + :tLEQ => 72, + :tANDOP => 73, + :tOROP => 74, + :tMATCH => 75, + :tNMATCH => 76, + :tDOT => 77, + :tDOT2 => 78, + :tDOT3 => 79, + :tAREF => 80, + :tASET => 81, + :tLSHFT => 82, + :tRSHFT => 83, + :tCOLON2 => 84, + :tCOLON3 => 85, + :tOP_ASGN => 86, + :tASSOC => 87, + :tLPAREN => 88, + :tLPAREN2 => 89, + :tRPAREN => 90, + :tLPAREN_ARG => 91, + :tLBRACK => 92, + :tLBRACK2 => 93, + :tRBRACK => 94, + :tLBRACE => 95, + :tLBRACE_ARG => 96, + :tSTAR => 97, + :tSTAR2 => 98, + :tAMPER => 99, + :tAMPER2 => 100, + :tTILDE => 101, + :tPERCENT => 102, + :tDIVIDE => 103, + :tDSTAR => 104, + :tPLUS => 105, + :tMINUS => 106, + :tLT => 107, + :tGT => 108, + :tPIPE => 109, + :tBANG => 110, + :tCARET => 111, + :tLCURLY => 112, + :tRCURLY => 113, + :tBACK_REF2 => 114, + :tSYMBEG => 115, + :tSTRING_BEG => 116, + :tXSTRING_BEG => 117, + :tREGEXP_BEG => 118, + :tREGEXP_OPT => 119, + :tWORDS_BEG => 120, + :tQWORDS_BEG => 121, + :tSYMBOLS_BEG => 122, + :tQSYMBOLS_BEG => 123, + :tSTRING_DBEG => 124, + :tSTRING_DVAR => 125, + :tSTRING_END => 126, + :tSTRING_DEND => 127, + :tSTRING => 128, + :tSYMBOL => 129, + :tNL => 130, + :tEH => 131, + :tCOLON => 132, + :tCOMMA => 133, + :tSPACE => 134, + :tSEMI => 135, + :tLAMBDA => 136, + :tLAMBEG => 137, + :tCHARACTER => 138, + :tRATIONAL => 139, + :tIMAGINARY => 140, + :tLABEL_END => 141, + :tANDDOT => 142, + :tEQL => 143, + :tLOWEST => 144 } + +racc_nt_base = 145 + +racc_use_result_var = true + +Racc_arg = [ + racc_action_table, + racc_action_check, + racc_action_default, + racc_action_pointer, + racc_goto_table, + racc_goto_check, + racc_goto_default, + racc_goto_pointer, + racc_nt_base, + racc_reduce_table, + racc_token_table, + racc_shift_n, + racc_reduce_n, + racc_use_result_var ] +Ractor.make_shareable(Racc_arg) if defined?(Ractor) + +Racc_token_to_s_table = [ + "$end", + "error", + "kCLASS", + "kMODULE", + "kDEF", + "kUNDEF", + "kBEGIN", + "kRESCUE", + "kENSURE", + "kEND", + "kIF", + "kUNLESS", + "kTHEN", + "kELSIF", + "kELSE", + "kCASE", + "kWHEN", + "kWHILE", + "kUNTIL", + "kFOR", + "kBREAK", + "kNEXT", + "kREDO", + "kRETRY", + "kIN", + "kDO", + "kDO_COND", + "kDO_BLOCK", + "kDO_LAMBDA", + "kRETURN", + "kYIELD", + "kSUPER", + "kSELF", + "kNIL", + "kTRUE", + "kFALSE", + "kAND", + "kOR", + "kNOT", + "kIF_MOD", + "kUNLESS_MOD", + "kWHILE_MOD", + "kUNTIL_MOD", + "kRESCUE_MOD", + "kALIAS", + "kDEFINED", + "klBEGIN", + "klEND", + "k__LINE__", + "k__FILE__", + "k__ENCODING__", + "tIDENTIFIER", + "tFID", + "tGVAR", + "tIVAR", + "tCONSTANT", + "tLABEL", + "tCVAR", + "tNTH_REF", + "tBACK_REF", + "tSTRING_CONTENT", + "tINTEGER", + "tFLOAT", + "tUPLUS", + "tUMINUS", + "tUNARY_NUM", + "tPOW", + "tCMP", + "tEQ", + "tEQQ", + "tNEQ", + "tGEQ", + "tLEQ", + "tANDOP", + "tOROP", + "tMATCH", + "tNMATCH", + "tDOT", + "tDOT2", + "tDOT3", + "tAREF", + "tASET", + "tLSHFT", + "tRSHFT", + "tCOLON2", + "tCOLON3", + "tOP_ASGN", + "tASSOC", + "tLPAREN", + "tLPAREN2", + "tRPAREN", + "tLPAREN_ARG", + "tLBRACK", + "tLBRACK2", + "tRBRACK", + "tLBRACE", + "tLBRACE_ARG", + "tSTAR", + "tSTAR2", + "tAMPER", + "tAMPER2", + "tTILDE", + "tPERCENT", + "tDIVIDE", + "tDSTAR", + "tPLUS", + "tMINUS", + "tLT", + "tGT", + "tPIPE", + "tBANG", + "tCARET", + "tLCURLY", + "tRCURLY", + "tBACK_REF2", + "tSYMBEG", + "tSTRING_BEG", + "tXSTRING_BEG", + "tREGEXP_BEG", + "tREGEXP_OPT", + "tWORDS_BEG", + "tQWORDS_BEG", + "tSYMBOLS_BEG", + "tQSYMBOLS_BEG", + "tSTRING_DBEG", + "tSTRING_DVAR", + "tSTRING_END", + "tSTRING_DEND", + "tSTRING", + "tSYMBOL", + "tNL", + "tEH", + "tCOLON", + "tCOMMA", + "tSPACE", + "tSEMI", + "tLAMBDA", + "tLAMBEG", + "tCHARACTER", + "tRATIONAL", + "tIMAGINARY", + "tLABEL_END", + "tANDDOT", + "tEQL", + "tLOWEST", + "$start", + "program", + "top_compstmt", + "top_stmts", + "opt_terms", + "top_stmt", + "terms", + "stmt", + "bodystmt", + "compstmt", + "opt_rescue", + "opt_else", + "opt_ensure", + "stmts", + "stmt_or_begin", + "fitem", + "undef_list", + "expr_value", + "command_asgn", + "mlhs", + "command_call", + "lhs", + "mrhs", + "mrhs_arg", + "expr", + "@1", + "command_rhs", + "var_lhs", + "primary_value", + "opt_call_args", + "rbracket", + "call_op", + "backref", + "opt_nl", + "arg", + "command", + "block_command", + "block_call", + "dot_or_colon", + "operation2", + "command_args", + "cmd_brace_block", + "brace_body", + "fcall", + "@2", + "operation", + "call_args", + "mlhs_basic", + "mlhs_inner", + "rparen", + "mlhs_head", + "mlhs_item", + "mlhs_node", + "mlhs_post", + "user_variable", + "keyword_variable", + "cname", + "cpath", + "fname", + "op", + "reswords", + "fsym", + "symbol", + "dsym", + "@3", + "arg_rhs", + "simple_numeric", + "primary", + "arg_value", + "aref_args", + "none", + "args", + "trailer", + "assocs", + "paren_args", + "opt_paren_args", + "opt_block_arg", + "block_arg", + "@4", + "literal", + "strings", + "xstring", + "regexp", + "words", + "qwords", + "symbols", + "qsymbols", + "var_ref", + "assoc_list", + "brace_block", + "method_call", + "lambda", + "then", + "if_tail", + "do", + "case_body", + "for_var", + "k_class", + "superclass", + "term", + "k_module", + "f_arglist", + "singleton", + "@5", + "@6", + "@7", + "@8", + "@9", + "@10", + "@11", + "@12", + "@13", + "@14", + "@15", + "@16", + "@17", + "@18", + "@19", + "@20", + "f_marg", + "f_norm_arg", + "f_margs", + "f_marg_list", + "block_args_tail", + "f_block_kwarg", + "f_kwrest", + "opt_f_block_arg", + "f_block_arg", + "opt_block_args_tail", + "block_param", + "f_arg", + "f_block_optarg", + "f_rest_arg", + "opt_block_param", + "block_param_def", + "opt_bv_decl", + "bv_decls", + "bvar", + "f_bad_arg", + "f_larglist", + "lambda_body", + "@21", + "@22", + "f_args", + "do_block", + "@23", + "@24", + "do_body", + "@25", + "operation3", + "@26", + "@27", + "@28", + "@29", + "@30", + "cases", + "exc_list", + "exc_var", + "numeric", + "string", + "string1", + "string_contents", + "xstring_contents", + "regexp_contents", + "word_list", + "word", + "string_content", + "symbol_list", + "qword_list", + "qsym_list", + "string_dvar", + "@31", + "@32", + "args_tail", + "@33", + "f_kwarg", + "opt_args_tail", + "f_optarg", + "f_arg_asgn", + "f_arg_item", + "f_label", + "f_kw", + "f_block_kw", + "kwrest_mark", + "f_opt", + "f_block_opt", + "restarg_mark", + "blkarg_mark", + "assoc" ] +Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) + +Racc_debug_parser = false + +##### State transition tables end ##### + +# reduce 0 omitted + +# reduce 1 omitted + +def _reduce_2(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_3(val, _values, result) + result = [] + + result +end + +def _reduce_4(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_5(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_6(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 7 omitted + +def _reduce_8(val, _values, result) + result = @builder.preexe(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_9(val, _values, result) + rescue_bodies = val[1] + else_t, else_ = val[2] + ensure_t, ensure_ = val[3] + + if rescue_bodies.empty? && !else_t.nil? + diagnostic :warning, :useless_else, nil, else_t + end + + result = @builder.begin_body(val[0], + rescue_bodies, + else_t, else_, + ensure_t, ensure_) + + result +end + +def _reduce_10(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_11(val, _values, result) + result = [] + + result +end + +def _reduce_12(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_13(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_14(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 15 omitted + +def _reduce_16(val, _values, result) + diagnostic :error, :begin_in_method, nil, val[0] + + result +end + +def _reduce_17(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_18(val, _values, result) + result = @builder.alias(val[0], val[1], val[3]) + + result +end + +def _reduce_19(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.gvar(val[2])) + + result +end + +def _reduce_20(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.back_ref(val[2])) + + result +end + +def _reduce_21(val, _values, result) + diagnostic :error, :nth_ref_alias, nil, val[2] + + result +end + +def _reduce_22(val, _values, result) + result = @builder.undef_method(val[0], val[1]) + + result +end + +def _reduce_23(val, _values, result) + result = @builder.condition_mod(val[0], nil, + val[1], val[2]) + + result +end + +def _reduce_24(val, _values, result) + result = @builder.condition_mod(nil, val[0], + val[1], val[2]) + + result +end + +def _reduce_25(val, _values, result) + result = @builder.loop_mod(:while, val[0], val[1], val[2]) + + result +end + +def _reduce_26(val, _values, result) + result = @builder.loop_mod(:until, val[0], val[1], val[2]) + + result +end + +def _reduce_27(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_28(val, _values, result) + result = @builder.postexe(val[0], val[1], val[2], val[3]) + + result +end + +# reduce 29 omitted + +def _reduce_30(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_31(val, _values, result) + result = @builder.assign(val[0], val[1], + @builder.array(nil, val[2], nil)) + + result +end + +def _reduce_32(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +# reduce 33 omitted + +def _reduce_34(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_35(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_36(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_37(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_38(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_39(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_40(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_41(val, _values, result) + @builder.op_assign(val[0], val[1], val[2]) + + result +end + +# reduce 42 omitted + +def _reduce_43(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +# reduce 44 omitted + +# reduce 45 omitted + +def _reduce_46(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_47(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_48(val, _values, result) + result = @builder.not_op(val[0], nil, val[2], nil) + + result +end + +def _reduce_49(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +# reduce 50 omitted + +# reduce 51 omitted + +# reduce 52 omitted + +# reduce 53 omitted + +# reduce 54 omitted + +def _reduce_55(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_56(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_57(val, _values, result) + result = [ val[0], *val[2], val[3] ] + @context.in_block = val[1].in_block + + result +end + +# reduce 58 omitted + +def _reduce_59(val, _values, result) + result = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + result +end + +def _reduce_60(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + begin_t, args, body, end_t = val[2] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_61(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_62(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_63(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_64(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_65(val, _values, result) + result = @builder.keyword_cmd(:super, val[0], + nil, val[1], nil) + + result +end + +def _reduce_66(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], + nil, val[1], nil) + + result +end + +def _reduce_67(val, _values, result) + result = @builder.keyword_cmd(:return, val[0], + nil, val[1], nil) + + result +end + +def _reduce_68(val, _values, result) + result = @builder.keyword_cmd(:break, val[0], + nil, val[1], nil) + + result +end + +def _reduce_69(val, _values, result) + result = @builder.keyword_cmd(:next, val[0], + nil, val[1], nil) + + result +end + +def _reduce_70(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_71(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_72(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_73(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +# reduce 74 omitted + +def _reduce_75(val, _values, result) + result = val[0]. + push(val[1]) + + result +end + +def _reduce_76(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])) + + result +end + +def _reduce_77(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])). + concat(val[4]) + + result +end + +def _reduce_78(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])) + + result +end + +def _reduce_79(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])). + concat(val[3]) + + result +end + +def _reduce_80(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_81(val, _values, result) + result = [ @builder.splat(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_82(val, _values, result) + result = [ @builder.splat(val[0]) ] + + result +end + +def _reduce_83(val, _values, result) + result = [ @builder.splat(val[0]), + *val[2] ] + + result +end + +# reduce 84 omitted + +def _reduce_85(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_86(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_87(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_88(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_89(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_90(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_91(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_92(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_93(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_94(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_95(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_96(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_97(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_98(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_99(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_100(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_101(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_102(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_103(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_104(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_105(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_106(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_107(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_108(val, _values, result) + diagnostic :error, :module_name_const, nil, val[0] + + result +end + +# reduce 109 omitted + +def _reduce_110(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_111(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_112(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +# reduce 113 omitted + +# reduce 114 omitted + +# reduce 115 omitted + +# reduce 116 omitted + +# reduce 117 omitted + +def _reduce_118(val, _values, result) + result = @builder.symbol_internal(val[0]) + + result +end + +# reduce 119 omitted + +# reduce 120 omitted + +# reduce 121 omitted + +def _reduce_122(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_123(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_124(val, _values, result) + result = val[0] << val[3] + + result +end + +# reduce 125 omitted + +# reduce 126 omitted + +# reduce 127 omitted + +# reduce 128 omitted + +# reduce 129 omitted + +# reduce 130 omitted + +# reduce 131 omitted + +# reduce 132 omitted + +# reduce 133 omitted + +# reduce 134 omitted + +# reduce 135 omitted + +# reduce 136 omitted + +# reduce 137 omitted + +# reduce 138 omitted + +# reduce 139 omitted + +# reduce 140 omitted + +# reduce 141 omitted + +# reduce 142 omitted + +# reduce 143 omitted + +# reduce 144 omitted + +# reduce 145 omitted + +# reduce 146 omitted + +# reduce 147 omitted + +# reduce 148 omitted + +# reduce 149 omitted + +# reduce 150 omitted + +# reduce 151 omitted + +# reduce 152 omitted + +# reduce 153 omitted + +# reduce 154 omitted + +# reduce 155 omitted + +# reduce 156 omitted + +# reduce 157 omitted + +# reduce 158 omitted + +# reduce 159 omitted + +# reduce 160 omitted + +# reduce 161 omitted + +# reduce 162 omitted + +# reduce 163 omitted + +# reduce 164 omitted + +# reduce 165 omitted + +# reduce 166 omitted + +# reduce 167 omitted + +# reduce 168 omitted + +# reduce 169 omitted + +# reduce 170 omitted + +# reduce 171 omitted + +# reduce 172 omitted + +# reduce 173 omitted + +# reduce 174 omitted + +# reduce 175 omitted + +# reduce 176 omitted + +# reduce 177 omitted + +# reduce 178 omitted + +# reduce 179 omitted + +# reduce 180 omitted + +# reduce 181 omitted + +# reduce 182 omitted + +# reduce 183 omitted + +# reduce 184 omitted + +# reduce 185 omitted + +# reduce 186 omitted + +# reduce 187 omitted + +# reduce 188 omitted + +# reduce 189 omitted + +# reduce 190 omitted + +# reduce 191 omitted + +# reduce 192 omitted + +# reduce 193 omitted + +# reduce 194 omitted + +# reduce 195 omitted + +def _reduce_196(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_197(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_198(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_199(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_200(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_201(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_202(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_203(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_global(val[0], val[1])) + result = @builder.op_assign(const, val[2], val[3]) + + result +end + +def _reduce_204(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_205(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_206(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_207(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_208(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_209(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_210(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_211(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_212(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_213(val, _values, result) + result = @builder.unary_op(val[0], + @builder.binary_op( + val[1], val[2], val[3])) + + result +end + +def _reduce_214(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_215(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_216(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_217(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_218(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_219(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_220(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_221(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_222(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_223(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_224(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_225(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_226(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_227(val, _values, result) + result = @builder.match_op(val[0], val[1], val[2]) + + result +end + +def _reduce_228(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_229(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +def _reduce_230(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_231(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_232(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_233(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_234(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_235(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil) + + result +end + +def _reduce_236(val, _values, result) + result = @builder.ternary(val[0], val[1], + val[2], val[4], val[5]) + + result +end + +# reduce 237 omitted + +# reduce 238 omitted + +# reduce 239 omitted + +# reduce 240 omitted + +def _reduce_241(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_242(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +# reduce 243 omitted + +def _reduce_244(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_245(val, _values, result) + result = val + + result +end + +def _reduce_246(val, _values, result) + result = [ nil, [], nil ] + + result +end + +# reduce 247 omitted + +def _reduce_248(val, _values, result) + result = [] + + result +end + +# reduce 249 omitted + +# reduce 250 omitted + +def _reduce_251(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_252(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +def _reduce_253(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_254(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_255(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + result.concat(val[1]) + + result +end + +def _reduce_256(val, _values, result) + assocs = @builder.associate(nil, val[2], nil) + result = val[0] << assocs + result.concat(val[3]) + + result +end + +def _reduce_257(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_258(val, _values, result) + # When branch gets invoked by RACC's lookahead + # and command args start with '[' or '(' + # we need to put `true` to the cmdarg stack + # **before** `false` pushed by lexer + # m [], n + # ^ + # Right here we have cmdarg [...0] because + # lexer pushed it on '[' + # We need to modify cmdarg stack to [...10] + # + # For all other cases (like `m n` or `m n, []`) we simply put 1 to the stack + # and later lexer pushes corresponding bits on top of it. + last_token = @last_token[0] + lookahead = last_token == :tLBRACK || last_token == :tLPAREN_ARG + + if lookahead + top = @lexer.cmdarg.pop + @lexer.cmdarg.push(true) + @lexer.cmdarg.push(top) + else + @lexer.cmdarg.push(true) + end + + result +end + +def _reduce_259(val, _values, result) + # call_args can be followed by tLBRACE_ARG (that does cmdarg.push(0) in the lexer) + # but the push must be done after cmdarg.pop() in the parser. + # So this code does cmdarg.pop() to pop 0 pushed by tLBRACE_ARG, + # cmdarg.pop() to pop 1 pushed by command_args, + # and cmdarg.push(0) to restore back the flag set by tLBRACE_ARG. + last_token = @last_token[0] + lookahead = last_token == :tLBRACE_ARG + if lookahead + top = @lexer.cmdarg.pop + @lexer.cmdarg.pop + @lexer.cmdarg.push(top) + else + @lexer.cmdarg.pop + end + + result = val[1] + + result +end + +def _reduce_260(val, _values, result) + result = @builder.block_pass(val[0], val[1]) + + result +end + +def _reduce_261(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_262(val, _values, result) + result = [] + + result +end + +def _reduce_263(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_264(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_265(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_266(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_267(val, _values, result) + result = @builder.array(nil, val[0], nil) + + result +end + +# reduce 268 omitted + +def _reduce_269(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_270(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_271(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +# reduce 272 omitted + +# reduce 273 omitted + +# reduce 274 omitted + +# reduce 275 omitted + +# reduce 276 omitted + +# reduce 277 omitted + +# reduce 278 omitted + +# reduce 279 omitted + +# reduce 280 omitted + +# reduce 281 omitted + +def _reduce_282(val, _values, result) + result = @builder.call_method(nil, nil, val[0]) + + result +end + +def _reduce_283(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_284(val, _values, result) + @lexer.cmdarg.pop + + result = @builder.begin_keyword(val[0], val[2], val[3]) + + result +end + +def _reduce_285(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_286(val, _values, result) + result = @builder.begin(val[0], val[1], val[3]) + + result +end + +def _reduce_287(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_288(val, _values, result) + result = @builder.begin(val[0], nil, val[3]) + + result +end + +def _reduce_289(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_290(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +def _reduce_291(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_292(val, _values, result) + result = @builder.array(val[0], val[1], val[2]) + + result +end + +def _reduce_293(val, _values, result) + result = @builder.associate(val[0], val[1], val[2]) + + result +end + +def _reduce_294(val, _values, result) + result = @builder.keyword_cmd(:return, val[0]) + + result +end + +def _reduce_295(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_296(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2]) + + result +end + +def _reduce_297(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0]) + + result +end + +def _reduce_298(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], + val[2], [ val[3] ], val[4]) + + result +end + +def _reduce_299(val, _values, result) + result = @builder.not_op(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_300(val, _values, result) + result = @builder.not_op(val[0], val[1], nil, val[2]) + + result +end + +def _reduce_301(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0]) + + begin_t, args, body, end_t = val[1] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +# reduce 302 omitted + +def _reduce_303(val, _values, result) + begin_t, args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, args, body, end_t) + + result +end + +def _reduce_304(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_305(val, _values, result) + lambda_call = @builder.call_lambda(val[0]) + + args, (begin_t, body, end_t) = val[2] + result = @builder.block(lambda_call, + begin_t, args, body, end_t) + + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_306(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, val[5]) + + result +end + +def _reduce_307(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + else_, else_t, + val[3], val[5]) + + result +end + +def _reduce_308(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_309(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_310(val, _values, result) + result = @builder.loop(:while, val[0], val[2], val[3], + val[5], val[6]) + + result +end + +def _reduce_311(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_312(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_313(val, _values, result) + result = @builder.loop(:until, val[0], val[2], val[3], + val[5], val[6]) + + result +end + +def _reduce_314(val, _values, result) + *when_bodies, (else_t, else_body) = *val[3] + + result = @builder.case(val[0], val[1], + when_bodies, else_t, else_body, + val[4]) + + result +end + +def _reduce_315(val, _values, result) + *when_bodies, (else_t, else_body) = *val[2] + + result = @builder.case(val[0], nil, + when_bodies, else_t, else_body, + val[3]) + + result +end + +def _reduce_316(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_317(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_318(val, _values, result) + result = @builder.for(val[0], val[1], + val[2], val[4], + val[5], val[7], val[8]) + + result +end + +def _reduce_319(val, _values, result) + local_push + @context.in_class = true + + result +end + +def _reduce_320(val, _values, result) + k_class, ctx = val[0] + if @context.in_def + diagnostic :error, :class_in_def, nil, k_class + end + + lt_t, superclass = val[2] + result = @builder.def_class(k_class, val[1], + lt_t, superclass, + val[4], val[5]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_321(val, _values, result) + @context.in_def = false + @context.in_class = false + local_push + + result +end + +def _reduce_322(val, _values, result) + k_class, ctx = val[0] + result = @builder.def_sclass(k_class, val[1], val[2], + val[5], val[6]) + + local_pop + @context.in_def = ctx.in_def + @context.in_class = ctx.in_class + + result +end + +def _reduce_323(val, _values, result) + @context.in_class = true + local_push + + result +end + +def _reduce_324(val, _values, result) + k_mod, ctx = val[0] + if @context.in_def + diagnostic :error, :module_in_def, nil, k_mod + end + + result = @builder.def_module(k_mod, val[1], + val[3], val[4]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_325(val, _values, result) + local_push + result = context.dup + @context.in_def = true + + result +end + +def _reduce_326(val, _values, result) + result = @builder.def_method(val[0], val[1], + val[3], val[4], val[5]) + + local_pop + @context.in_def = val[2].in_def + + result +end + +def _reduce_327(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_328(val, _values, result) + local_push + result = context.dup + @context.in_def = true + + result +end + +def _reduce_329(val, _values, result) + result = @builder.def_singleton(val[0], val[1], val[2], + val[4], val[6], val[7], val[8]) + + local_pop + @context.in_def = val[5].in_def + + result +end + +def _reduce_330(val, _values, result) + result = @builder.keyword_cmd(:break, val[0]) + + result +end + +def _reduce_331(val, _values, result) + result = @builder.keyword_cmd(:next, val[0]) + + result +end + +def _reduce_332(val, _values, result) + result = @builder.keyword_cmd(:redo, val[0]) + + result +end + +def _reduce_333(val, _values, result) + result = @builder.keyword_cmd(:retry, val[0]) + + result +end + +# reduce 334 omitted + +def _reduce_335(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_336(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +# reduce 337 omitted + +# reduce 338 omitted + +def _reduce_339(val, _values, result) + result = val[1] + + result +end + +# reduce 340 omitted + +# reduce 341 omitted + +# reduce 342 omitted + +def _reduce_343(val, _values, result) + else_t, else_ = val[4] + result = [ val[0], + @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, nil), + ] + + result +end + +# reduce 344 omitted + +def _reduce_345(val, _values, result) + result = val + + result +end + +# reduce 346 omitted + +# reduce 347 omitted + +def _reduce_348(val, _values, result) + result = @builder.arg(val[0]) + + result +end + +def _reduce_349(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_350(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_351(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 352 omitted + +def _reduce_353(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2], val[3])) + + result +end + +def _reduce_354(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2], val[3])). + concat(val[5]) + + result +end + +def _reduce_355(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2])) + + result +end + +def _reduce_356(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2])). + concat(val[4]) + + result +end + +def _reduce_357(val, _values, result) + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_358(val, _values, result) + result = [ @builder.restarg(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_359(val, _values, result) + result = [ @builder.restarg(val[0]) ] + + result +end + +def _reduce_360(val, _values, result) + result = [ @builder.restarg(val[0]), + *val[2] ] + + result +end + +def _reduce_361(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_362(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_363(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_364(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_365(val, _values, result) + result = val[1] + + result +end + +def _reduce_366(val, _values, result) + result = [] + + result +end + +def _reduce_367(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_368(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_369(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_370(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_371(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 372 omitted + +def _reduce_373(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_374(val, _values, result) + if val[1].empty? && val[0].size == 1 + result = [@builder.procarg0(val[0][0])] + else + result = val[0].concat(val[1]) + end + + result +end + +def _reduce_375(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_376(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_377(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_378(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_379(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_380(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 381 omitted + +def _reduce_382(val, _values, result) + result = @builder.args(nil, [], nil) + + result +end + +def _reduce_383(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_384(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + result +end + +def _reduce_385(val, _values, result) + result = @builder.args(val[0], [], val[0]) + + result +end + +def _reduce_386(val, _values, result) + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_387(val, _values, result) + result = [] + + result +end + +def _reduce_388(val, _values, result) + result = val[2] + + result +end + +def _reduce_389(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_390(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_391(val, _values, result) + @static_env.declare val[0][0] + result = @builder.shadowarg(val[0]) + + result +end + +# reduce 392 omitted + +def _reduce_393(val, _values, result) + @static_env.extend_dynamic + + result +end + +def _reduce_394(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_395(val, _values, result) + @lexer.cmdarg.pop + + result = [ val[1], val[3] ] + + @static_env.unextend + + result +end + +def _reduce_396(val, _values, result) + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_397(val, _values, result) + result = @builder.args(nil, val[0], nil) + + result +end + +def _reduce_398(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_399(val, _values, result) + result = [ val[0], val[2], val[3] ] + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_400(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_401(val, _values, result) + result = [ val[0], val[2], val[3] ] + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_402(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_403(val, _values, result) + result = [ val[0], *val[2], val[3] ] + @context.in_block = val[1].in_block + + result +end + +def _reduce_404(val, _values, result) + begin_t, block_args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, block_args, body, end_t) + + result +end + +def _reduce_405(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_406(val, _values, result) + lparen_t, args, rparen_t = val[3] + method_call = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_407(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_408(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.call_method(nil, nil, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_409(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_410(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_411(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2]) + + result +end + +def _reduce_412(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_413(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_414(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.keyword_cmd(:super, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_415(val, _values, result) + result = @builder.keyword_cmd(:zsuper, val[0]) + + result +end + +def _reduce_416(val, _values, result) + result = @builder.index(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_417(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_418(val, _values, result) + result = [ val[0], *val[2], val[3] ] + @context.in_block = val[1].in_block + + result +end + +def _reduce_419(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_420(val, _values, result) + result = [ val[0], *val[2], val[3] ] + @context.in_block = val[1].in_block + + result +end + +def _reduce_421(val, _values, result) + @static_env.extend_dynamic + + result +end + +def _reduce_422(val, _values, result) + result = [ val[1], val[2] ] + + @static_env.unextend + + result +end + +def _reduce_423(val, _values, result) + @static_env.extend_dynamic + + result +end + +def _reduce_424(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_425(val, _values, result) + result = [ val[2], val[3] ] + + @static_env.unextend + @lexer.cmdarg.pop + + result +end + +def _reduce_426(val, _values, result) + result = [ @builder.when(val[0], val[1], val[2], val[3]), + *val[4] ] + + result +end + +def _reduce_427(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 428 omitted + +def _reduce_429(val, _values, result) + assoc_t, exc_var = val[2] + + if val[1] + exc_list = @builder.array(nil, val[1], nil) + end + + result = [ @builder.rescue_body(val[0], + exc_list, assoc_t, exc_var, + val[3], val[4]), + *val[5] ] + + result +end + +def _reduce_430(val, _values, result) + result = [] + + result +end + +def _reduce_431(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 432 omitted + +# reduce 433 omitted + +def _reduce_434(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 435 omitted + +def _reduce_436(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 437 omitted + +# reduce 438 omitted + +# reduce 439 omitted + +# reduce 440 omitted + +def _reduce_441(val, _values, result) + result = @builder.string_compose(nil, val[0], nil) + + result +end + +def _reduce_442(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_443(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_444(val, _values, result) + string = @builder.string_compose(val[0], val[1], val[2]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_445(val, _values, result) + string = @builder.string(val[0]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_446(val, _values, result) + result = @builder.character(val[0]) + + result +end + +def _reduce_447(val, _values, result) + string = @builder.xstring_compose(val[0], val[1], val[2]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_448(val, _values, result) + opts = @builder.regexp_options(val[3]) + result = @builder.regexp_compose(val[0], val[1], val[2], opts) + + result +end + +def _reduce_449(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_450(val, _values, result) + result = [] + + result +end + +def _reduce_451(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_452(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_453(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_454(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_455(val, _values, result) + result = [] + + result +end + +def _reduce_456(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_457(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_458(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_459(val, _values, result) + result = [] + + result +end + +def _reduce_460(val, _values, result) + result = val[0] << @builder.string_internal(val[1]) + + result +end + +def _reduce_461(val, _values, result) + result = [] + + result +end + +def _reduce_462(val, _values, result) + result = val[0] << @builder.symbol_internal(val[1]) + + result +end + +def _reduce_463(val, _values, result) + result = [] + + result +end + +def _reduce_464(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_465(val, _values, result) + result = [] + + result +end + +def _reduce_466(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_467(val, _values, result) + result = [] + + result +end + +def _reduce_468(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_469(val, _values, result) + result = @builder.string_internal(val[0]) + + result +end + +def _reduce_470(val, _values, result) + result = val[1] + + result +end + +def _reduce_471(val, _values, result) + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + + result +end + +def _reduce_472(val, _values, result) + @lexer.cmdarg.pop + @lexer.cond.pop + + result = @builder.begin(val[0], val[2], val[3]) + + result +end + +def _reduce_473(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_474(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_475(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +# reduce 476 omitted + +def _reduce_477(val, _values, result) + @lexer.state = :expr_end + result = @builder.symbol(val[0]) + + result +end + +def _reduce_478(val, _values, result) + @lexer.state = :expr_end + result = @builder.symbol_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_479(val, _values, result) + result = val[0] + + result +end + +def _reduce_480(val, _values, result) + if @builder.respond_to? :negate + # AST builder interface compatibility + result = @builder.negate(val[0], val[1]) + else + result = @builder.unary_num(val[0], val[1]) + end + + result +end + +def _reduce_481(val, _values, result) + @lexer.state = :expr_end + result = @builder.integer(val[0]) + + result +end + +def _reduce_482(val, _values, result) + @lexer.state = :expr_end + result = @builder.float(val[0]) + + result +end + +def _reduce_483(val, _values, result) + @lexer.state = :expr_end + result = @builder.rational(val[0]) + + result +end + +def _reduce_484(val, _values, result) + @lexer.state = :expr_end + result = @builder.complex(val[0]) + + result +end + +def _reduce_485(val, _values, result) + result = @builder.ident(val[0]) + + result +end + +def _reduce_486(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_487(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_488(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_489(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +def _reduce_490(val, _values, result) + result = @builder.nil(val[0]) + + result +end + +def _reduce_491(val, _values, result) + result = @builder.self(val[0]) + + result +end + +def _reduce_492(val, _values, result) + result = @builder.true(val[0]) + + result +end + +def _reduce_493(val, _values, result) + result = @builder.false(val[0]) + + result +end + +def _reduce_494(val, _values, result) + result = @builder.__FILE__(val[0]) + + result +end + +def _reduce_495(val, _values, result) + result = @builder.__LINE__(val[0]) + + result +end + +def _reduce_496(val, _values, result) + result = @builder.__ENCODING__(val[0]) + + result +end + +def _reduce_497(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_498(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_499(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_500(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_501(val, _values, result) + result = @builder.nth_ref(val[0]) + + result +end + +def _reduce_502(val, _values, result) + result = @builder.back_ref(val[0]) + + result +end + +def _reduce_503(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_504(val, _values, result) + result = [ val[0], val[2] ] + + result +end + +def _reduce_505(val, _values, result) + result = nil + + result +end + +def _reduce_506(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + @lexer.state = :expr_value + + result +end + +def _reduce_507(val, _values, result) + result = @context.in_kwarg + @context.in_kwarg = true + + result +end + +def _reduce_508(val, _values, result) + @context.in_kwarg = val[0] + result = @builder.args(nil, val[1], nil) + + result +end + +def _reduce_509(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_510(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_511(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_512(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_513(val, _values, result) + result = val[1] + + result +end + +def _reduce_514(val, _values, result) + result = [] + + result +end + +def _reduce_515(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_516(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_517(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_518(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_519(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_520(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_521(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_522(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_523(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_524(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_525(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_526(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_527(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_528(val, _values, result) + result = val[0] + + result +end + +def _reduce_529(val, _values, result) + result = [] + + result +end + +def _reduce_530(val, _values, result) + diagnostic :error, :argument_const, nil, val[0] + + result +end + +def _reduce_531(val, _values, result) + diagnostic :error, :argument_ivar, nil, val[0] + + result +end + +def _reduce_532(val, _values, result) + diagnostic :error, :argument_gvar, nil, val[0] + + result +end + +def _reduce_533(val, _values, result) + diagnostic :error, :argument_cvar, nil, val[0] + + result +end + +# reduce 534 omitted + +def _reduce_535(val, _values, result) + @static_env.declare val[0][0] + + result = val[0] + + result +end + +def _reduce_536(val, _values, result) + result = val[0] + + result +end + +def _reduce_537(val, _values, result) + result = @builder.arg(val[0]) + + result +end + +def _reduce_538(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_539(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_540(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_541(val, _values, result) + check_kwarg_name(val[0]) + + @static_env.declare val[0][0] + + result = val[0] + + result +end + +def _reduce_542(val, _values, result) + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_543(val, _values, result) + result = @builder.kwarg(val[0]) + + result +end + +def _reduce_544(val, _values, result) + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_545(val, _values, result) + result = @builder.kwarg(val[0]) + + result +end + +def _reduce_546(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_547(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_548(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_549(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 550 omitted + +# reduce 551 omitted + +def _reduce_552(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.kwrestarg(val[0], val[1]) ] + + result +end + +def _reduce_553(val, _values, result) + result = [ @builder.kwrestarg(val[0]) ] + + result +end + +def _reduce_554(val, _values, result) + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_555(val, _values, result) + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_556(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_557(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_558(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_559(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 560 omitted + +# reduce 561 omitted + +def _reduce_562(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_563(val, _values, result) + result = [ @builder.restarg(val[0]) ] + + result +end + +# reduce 564 omitted + +# reduce 565 omitted + +def _reduce_566(val, _values, result) + @static_env.declare val[1][0] + + result = @builder.blockarg(val[0], val[1]) + + result +end + +def _reduce_567(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_568(val, _values, result) + result = [] + + result +end + +# reduce 569 omitted + +def _reduce_570(val, _values, result) + result = val[1] + + result +end + +def _reduce_571(val, _values, result) + result = [] + + result +end + +# reduce 572 omitted + +def _reduce_573(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_574(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_575(val, _values, result) + result = @builder.pair(val[0], val[1], val[2]) + + result +end + +def _reduce_576(val, _values, result) + result = @builder.pair_keyword(val[0], val[1]) + + result +end + +def _reduce_577(val, _values, result) + result = @builder.pair_quoted(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_578(val, _values, result) + result = @builder.kwsplat(val[0], val[1]) + + result +end + +# reduce 579 omitted + +# reduce 580 omitted + +# reduce 581 omitted + +# reduce 582 omitted + +# reduce 583 omitted + +# reduce 584 omitted + +# reduce 585 omitted + +# reduce 586 omitted + +# reduce 587 omitted + +# reduce 588 omitted + +# reduce 589 omitted + +# reduce 590 omitted + +def _reduce_591(val, _values, result) + result = [:dot, val[0][1]] + + result +end + +def _reduce_592(val, _values, result) + result = [:anddot, val[0][1]] + + result +end + +# reduce 593 omitted + +# reduce 594 omitted + +# reduce 595 omitted + +# reduce 596 omitted + +def _reduce_597(val, _values, result) + result = val[1] + + result +end + +def _reduce_598(val, _values, result) + result = val[1] + + result +end + +# reduce 599 omitted + +# reduce 600 omitted + +# reduce 601 omitted + +def _reduce_602(val, _values, result) + yyerrok + + result +end + +# reduce 603 omitted + +# reduce 604 omitted + +# reduce 605 omitted + +def _reduce_606(val, _values, result) + result = nil + + result +end + +def _reduce_none(val, _values, result) + val[0] +end + + end # class Ruby24 +end # module Parser diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby25.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby25.rb new file mode 100644 index 00000000..ab3937c7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby25.rb @@ -0,0 +1,10374 @@ +# -*- encoding:utf-8; warn-indent:false; frozen_string_literal: true -*- +# +# DO NOT MODIFY!!!! +# This file is automatically generated by Racc 1.8.1 +# from Racc grammar file "ruby25.y". +# + +require 'racc/parser.rb' + + +require_relative '../parser' + +module Parser + class Ruby25 < Parser::Base + + + def version + 25 + end + + def default_encoding + Encoding::UTF_8 + end + + def local_push + @static_env.extend_static + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + end + + def local_pop + @static_env.unextend + @lexer.cmdarg.pop + @lexer.cond.pop + end +##### State transition tables begin ### + +racc_action_table = [ + -486, 214, 215, 214, 215, 222, -102, -486, -486, -486, + 113, 549, -486, -486, -486, 220, -486, 276, 224, 590, + 262, 263, 269, 549, -486, 592, -486, -486, -486, 276, + 562, 276, -500, 126, 563, -103, -486, -486, 549, -486, + -486, -486, -486, -486, 549, 549, -102, -103, -110, -110, + -88, -109, -101, 791, -109, 556, 261, 260, 276, 225, + -74, 211, -110, 212, -105, -107, -486, -486, -486, -486, + -486, -486, -486, -486, -486, -486, -486, -486, -486, -486, + 221, 271, -486, -486, -486, 589, -486, -486, 705, -102, + -486, 591, 872, -486, -486, 225, -486, 225, -486, 213, + -486, 216, -486, -486, 275, -486, -486, -486, -486, -486, + -105, -486, -489, -486, -107, -93, 275, -104, 275, -489, + -489, -489, 271, -106, -489, -489, -489, -486, -489, 117, + -486, -486, -486, -486, 116, -486, -489, -486, -489, -489, + -489, 117, -486, -486, -94, 275, 116, -96, -489, -489, + -108, -489, -489, -489, -489, -489, 117, -104, -101, 825, + -100, 116, 117, 117, -102, -103, -110, 116, 116, -102, + -103, -110, -109, -96, -98, -106, 779, -109, -489, -489, + -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, + -489, -489, 117, 265, -489, -489, -489, 116, -489, -489, + -583, 871, -489, 324, -98, -489, -489, 325, -489, -108, + -489, 778, -489, -96, -489, -489, 225, -489, -489, -489, + -489, -489, -296, -489, 395, -489, -95, -584, -105, -296, + -296, -296, -107, -105, 779, -296, -296, -107, -296, -489, + -583, -106, -489, -489, -489, -489, -106, -489, 408, -489, + 214, 215, -501, -96, -489, -489, -96, 457, -296, -296, + -95, -296, -296, -296, -296, -296, -96, 459, -108, 778, + -98, -486, -97, -108, -584, -104, 214, 215, -486, 682, + -104, 679, 678, 677, -97, 680, 214, 215, -296, -296, + -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, + -296, -296, 460, 458, -296, -296, -296, -489, 615, -103, + -98, -500, -296, -98, -489, -296, 95, 96, -99, 577, + -296, 224, -296, -98, -296, -296, -95, -296, -296, -296, + -296, -296, -496, -296, -587, -296, -486, -583, -97, -496, + 405, -587, -587, -587, 225, 407, 406, -587, -587, -296, + -587, 117, -296, -296, 488, -99, 116, -296, -93, -587, + -110, 890, 214, 215, -296, -108, -95, -580, -102, -95, + -587, -587, -489, -587, -587, -587, -587, -587, -97, -95, + 117, -97, 497, 579, 578, 116, 682, 577, 679, 678, + 677, -97, 680, 737, 97, 98, 499, -496, 577, 222, + -587, -587, -587, -587, -587, -587, -587, -587, -587, -587, + -587, -587, -587, -587, 526, 501, -587, -587, -587, -486, + 616, 95, 96, 577, -587, 117, -486, -587, 117, 765, + 116, -580, -587, 116, -587, -486, -587, -587, -501, -587, + -587, -587, -587, -587, 766, -587, -587, -587, 577, 126, + -495, 579, 578, 575, -580, 577, -110, -495, -73, -581, + 577, -587, 579, 578, -587, -587, -587, -97, 983, -587, + 225, -109, 739, -587, -587, -587, -587, -106, -587, -587, + -587, 512, -587, 513, -486, -94, -105, 579, 578, 575, + -497, -587, -587, -587, -587, -103, 520, -497, 280, 97, + 98, -107, -587, -587, 643, -587, -587, -587, -587, -587, + 526, -489, 579, 578, 580, -495, 577, 225, -489, 579, + 578, 582, 577, -581, 579, 578, 584, -489, 539, 822, + 791, 538, -587, -587, -587, -587, -587, -587, -587, -587, + -587, -587, -587, -587, -587, -587, -581, 271, -587, -587, + -587, 523, 767, -587, 220, -497, -587, -100, -494, -587, + -587, 219, -587, 527, -587, -494, -587, -109, -587, -587, + 217, -587, -587, -587, -587, -587, -489, -587, -587, -587, + 579, 578, 588, -491, -334, -492, 579, 578, 593, 245, + -491, -334, -492, -587, 245, 610, -587, -587, -587, -587, + -334, -587, 610, -587, -296, 611, 844, 611, -587, -106, + 117, -296, -296, -296, 225, 116, -296, -296, -296, 221, + -296, 242, 542, -494, 543, 244, 243, -493, 220, 245, + -296, -296, -296, 539, -493, 269, 541, 501, 752, 752, + -296, -296, -96, -296, -296, -296, -296, -296, -491, -334, + -492, 220, -105, -498, -98, 698, 697, 556, 455, -105, + -498, 242, -107, -104, -107, 244, 243, 456, 397, -498, + -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, + -296, -296, -296, -296, 117, -95, -296, -296, -296, 116, + 768, -296, -493, 221, -296, -104, -104, -296, -296, 560, + -296, 561, -296, 569, -296, 539, -296, -296, 541, -296, + -296, -296, -296, -296, -296, -296, 221, -296, -498, 822, + 791, -296, -296, -296, 594, 597, 539, -296, -296, 541, + -296, -296, 245, -269, -296, -296, -296, -296, 599, -296, + 83, -296, -587, 600, 604, 225, -296, -108, 255, 256, + -296, -296, 84, -296, -296, -296, -296, -296, 225, -499, + 608, 999, 85, 220, 242, 609, -499, 271, 244, 243, + 519, 240, 241, 620, 245, -499, 245, 245, 245, 517, + -296, -296, -296, -296, -296, -296, -296, -296, -296, -296, + -296, -296, -296, -296, -587, -287, -296, -296, -296, 225, + 615, -587, -287, 225, -296, 225, -583, -296, -88, 646, + -587, -287, -296, 225, -296, 532, -296, -296, 657, -296, + -296, -296, -296, -296, -499, -296, -587, -296, 221, -587, + 662, 663, 225, -587, -587, -587, 687, 665, 701, -587, + -587, -296, -587, 706, -296, -296, 690, -296, 220, -296, + 707, -587, 556, 709, 726, 529, -296, -108, 736, -587, + -287, 740, -587, -587, 456, -587, -587, -587, -587, -587, + 682, 220, 679, 678, 677, 741, 680, -270, 559, 698, + 697, 753, 488, 488, 691, 731, 732, 557, 225, 733, + 111, 112, -587, -587, -587, -587, -587, -587, -587, -587, + -587, -587, -587, -587, -587, -587, 770, 811, -587, -587, + -587, 220, 616, 221, 220, 771, -587, 265, 565, -587, + 776, 603, 781, 499, -587, 501, -587, 567, -587, -587, + 601, -587, -587, -587, -587, -587, 221, -587, -587, -587, + 682, 657, 679, 678, 677, 687, 680, -297, 120, 121, + 122, 123, 124, -587, -297, 690, -587, -587, -416, -587, + 225, -587, 271, -297, 271, -416, -416, -416, -587, -106, + -416, -416, -416, 657, -416, 245, 221, 685, 791, 221, + 799, 245, 802, -416, -416, -416, 695, 694, 698, 697, + 803, 805, 807, 691, -416, -416, 809, -416, -416, -416, + -416, -416, 682, 817, 679, 678, 677, -297, 680, 818, + 819, 791, -297, 242, -297, 824, 225, 244, 243, 225, + 240, 241, 225, -297, -416, -416, -416, -416, -416, -416, + -416, -416, -416, -416, -416, -416, -416, -416, 833, 811, + -416, -416, -416, -271, 225, -416, 843, 271, -416, 847, + 657, -416, -416, 864, -416, -269, -416, 868, -416, 225, + -416, -416, 888, -416, -416, -416, -416, -416, -303, -416, + -416, -416, -297, 225, 892, -303, -303, -303, 894, 897, + -303, -303, -303, 220, -303, -416, 898, 901, -416, -416, + 969, -416, 225, -416, -303, -303, 905, -272, 907, 567, + -416, 802, 910, 912, -303, -303, 914, -303, -303, -303, + -303, -303, 916, 225, 918, -296, 919, -296, 932, 802, + 934, 936, -296, 938, -296, 940, 940, -584, 225, -584, + 946, -296, 952, -296, -303, -303, -303, -303, -303, -303, + -303, -303, -303, -303, -303, -303, -303, -303, 221, 726, + -303, -303, -303, 963, 970, -303, 975, 280, -303, 985, + 802, -303, -303, 989, -303, 991, -303, 993, -303, 995, + -303, -303, 995, -303, -303, -303, -303, -303, -288, -303, + -296, -303, -296, 662, 1008, -288, -288, -288, 1009, 1010, + -288, -288, -288, 220, -288, -303, 940, 940, -303, -303, + 974, -303, 940, -303, -288, -288, -288, 1015, 985, 972, + -303, 1018, -584, -583, -288, -288, 225, -288, -288, -288, + -288, -288, 966, 220, 679, 678, 677, 985, 680, 682, + 969, 679, 678, 677, 966, 680, 679, 678, 677, 567, + 680, 1027, 995, 995, -288, -288, -288, -288, -288, -288, + -288, -288, -288, -288, -288, -288, -288, -288, 221, 687, + -288, -288, -288, 995, 940, -288, 811, 985, -288, 690, + 995, -288, -288, nil, -288, 814, -288, nil, -288, nil, + -288, -288, nil, -288, -288, -288, -288, -288, 221, -288, + nil, -288, 682, nil, 679, 678, 677, nil, 680, nil, + nil, nil, 698, 697, nil, -288, nil, 691, -288, -288, + -288, -288, nil, -288, -252, -288, nil, nil, nil, nil, + -288, -252, -252, -252, nil, nil, -252, -252, -252, 811, + -252, 682, nil, 679, 678, 677, nil, 680, 814, -252, + -252, -252, 682, nil, 679, 678, 677, nil, 680, nil, + -252, -252, nil, -252, -252, -252, -252, -252, 682, nil, + 679, 678, 677, 682, 680, 679, 678, 677, 811, 680, + 120, 121, 122, 123, 124, nil, nil, 945, nil, 811, + -252, -252, -252, -252, -252, -252, -252, -252, -252, -252, + -252, -252, -252, -252, nil, 811, -252, -252, -252, nil, + 811, -252, nil, 271, -252, nil, nil, -252, -252, nil, + -252, nil, -252, nil, -252, nil, -252, -252, nil, -252, + -252, -252, -252, -252, nil, -252, -252, -252, 682, nil, + 679, 678, 677, 687, 680, 120, 121, 122, 123, 124, + nil, -252, nil, 690, -252, -252, -588, -252, nil, -252, + nil, nil, nil, -588, -588, -588, -252, nil, -588, -588, + -588, nil, -588, 245, nil, 685, 120, 121, 122, 123, + 124, -588, -588, -588, -588, nil, 698, 697, nil, 255, + 256, 691, -588, -588, nil, -588, -588, -588, -588, -588, + nil, nil, nil, nil, nil, 242, nil, 248, nil, 244, + 243, nil, 240, 241, nil, nil, 246, nil, 247, nil, + nil, nil, -588, -588, -588, -588, -588, -588, -588, -588, + -588, -588, -588, -588, -588, -588, nil, nil, -588, -588, + -588, 245, nil, -588, nil, nil, -588, nil, nil, -588, + -588, nil, -588, nil, -588, nil, -588, nil, -588, -588, + nil, -588, -588, -588, -588, -588, nil, -588, -588, -588, + nil, nil, nil, 242, nil, nil, nil, 244, 243, nil, + 240, 241, nil, -588, nil, nil, -588, -588, -588, -588, + nil, -588, -589, -588, nil, nil, nil, nil, -588, -589, + -589, -589, nil, nil, -589, -589, -589, 245, -589, nil, + nil, nil, nil, nil, nil, nil, nil, -589, -589, -589, + -589, nil, nil, 255, 256, nil, nil, nil, -589, -589, + nil, -589, -589, -589, -589, -589, nil, nil, nil, 242, + nil, 248, nil, 244, 243, nil, 240, 241, nil, nil, + 246, nil, 247, nil, nil, nil, nil, nil, -589, -589, + -589, -589, -589, -589, -589, -589, -589, -589, -589, -589, + -589, -589, nil, nil, -589, -589, -589, nil, nil, -589, + nil, nil, -589, nil, nil, -589, -589, nil, -589, nil, + -589, nil, -589, nil, -589, -589, nil, -589, -589, -589, + -589, -589, nil, -589, -589, -589, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, -589, + nil, nil, -589, -589, -589, -589, nil, -589, -252, -589, + nil, nil, nil, nil, -589, -252, -252, -252, nil, nil, + -252, -252, -252, 245, -252, nil, nil, nil, nil, nil, + nil, nil, nil, -252, -252, nil, nil, nil, nil, 255, + 256, nil, nil, nil, -252, -252, nil, -252, -252, -252, + -252, -252, nil, nil, nil, 242, nil, 248, nil, 244, + 243, nil, 240, 241, nil, nil, nil, 245, 249, 250, + 251, 252, 262, 263, 257, 258, 253, 254, nil, 238, + 239, nil, nil, 255, 256, -252, nil, nil, nil, nil, + nil, nil, -252, nil, nil, nil, nil, 271, -252, 242, + nil, 248, nil, 244, 243, nil, 240, 241, 261, 260, + 246, nil, 247, nil, nil, nil, nil, nil, nil, nil, + -252, -252, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 259, nil, nil, -252, nil, nil, -252, nil, + nil, nil, nil, -252, 5, 75, 76, 72, 9, 58, + -252, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, 605, 8, 46, 7, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, 245, + 249, 250, 251, 252, 262, 263, 257, 258, 253, 254, + nil, 238, 239, nil, nil, 255, 256, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 242, nil, 248, 45, 244, 243, nil, 240, 241, + 261, 260, 246, 20, 247, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, 259, nil, -244, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, 605, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, 245, + 249, 250, 251, 252, 262, 263, 257, 258, 253, 254, + nil, 238, 239, nil, nil, 255, 256, nil, 40, nil, + nil, 302, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 242, nil, 248, 45, 244, 243, nil, 240, 241, + 261, 260, 246, 20, 247, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, 259, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 5, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 7, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, 245, + 249, 250, 251, 252, 262, 263, 257, 258, 253, 254, + nil, 238, 239, nil, nil, 255, 256, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 242, nil, 248, 45, 244, 243, nil, 240, 241, + 261, 260, 246, 20, 247, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, 259, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, 245, + 249, 250, 251, 252, 262, 263, 257, 258, 253, 254, + nil, 238, 239, nil, nil, 255, 256, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 242, nil, 248, 45, 244, 243, nil, 240, 241, + 261, 260, 246, 20, 247, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, 225, 259, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, 245, + 249, 250, 251, 252, 262, 263, 257, 258, 253, 254, + nil, 238, 239, nil, nil, 255, 256, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 242, nil, 248, 45, 244, 243, nil, 240, 241, + 261, 260, 246, 20, 247, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, 259, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, 245, + 249, 250, 251, 252, 262, 263, 257, 258, 253, 254, + nil, 238, 239, nil, nil, 255, 256, nil, 40, nil, + nil, 302, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 242, nil, 248, 45, 244, 243, nil, 240, 241, + 261, 260, 246, 20, 247, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, 259, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, 245, + 249, 250, 251, 252, 262, 263, 257, 258, 253, 254, + nil, 238, 239, nil, nil, 255, 256, nil, 40, nil, + nil, 302, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 242, nil, 248, 45, 244, 243, nil, 240, 241, + 261, 260, 246, 20, 247, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, 259, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, 245, + 249, 250, 251, 252, 262, 263, 257, 258, 253, 254, + nil, -608, -608, nil, nil, 255, 256, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 242, nil, 248, 45, 244, 243, nil, 240, 241, + 261, 260, 246, 20, 247, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, 245, + 249, 250, 251, 252, 262, 263, 257, 258, 253, 254, + nil, -608, -608, nil, nil, 255, 256, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 242, nil, 248, 45, 244, 243, nil, 240, 241, + 261, 260, 246, 20, 247, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, 245, + -608, -608, -608, -608, 262, 263, nil, nil, -608, -608, + nil, nil, nil, nil, nil, 255, 256, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 242, nil, 248, 45, 244, 243, nil, 240, 241, + 261, 260, 246, 20, 247, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, 245, + -608, -608, -608, -608, 262, 263, nil, nil, -608, -608, + nil, nil, nil, nil, nil, 255, 256, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 242, nil, 248, 45, 244, 243, nil, 240, 241, + 261, 260, 246, 20, 247, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, 245, + -608, -608, -608, -608, 262, 263, nil, nil, -608, -608, + nil, nil, nil, nil, nil, 255, 256, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 242, nil, 248, 45, 244, 243, nil, 240, 241, + 261, 260, 246, 20, 247, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, 245, + -608, -608, -608, -608, 262, 263, nil, nil, -608, -608, + nil, nil, nil, nil, nil, 255, 256, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 242, nil, 248, 45, 244, 243, nil, 240, 241, + 261, 260, 246, 20, 247, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, 245, + -608, -608, -608, -608, 262, 263, nil, nil, -608, -608, + nil, nil, nil, nil, nil, 255, 256, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 242, nil, 248, 45, 244, 243, nil, 240, 241, + 261, 260, 246, 20, 247, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, 245, + -608, -608, -608, -608, 262, 263, nil, nil, -608, -608, + nil, nil, nil, nil, nil, 255, 256, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 242, nil, 248, 45, 244, 243, nil, 240, 241, + 261, 260, 246, 20, 247, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, 245, + 249, 250, 251, 252, 262, 263, nil, nil, 253, 254, + nil, nil, nil, nil, nil, 255, 256, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 242, nil, 248, 45, 244, 243, nil, 240, 241, + 261, 260, 246, 20, 247, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, 245, + 249, 250, 251, 252, 262, 263, 257, nil, 253, 254, + nil, nil, nil, nil, nil, 255, 256, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 242, nil, 248, 45, 244, 243, nil, 240, 241, + 261, 260, 246, 20, 247, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, 245, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 255, 256, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 242, nil, 248, 45, 244, 243, nil, 240, 241, + nil, nil, nil, 20, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 298, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 300, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, nil, nil, nil, 63, + nil, 85, 97, 98, 75, 76, 72, 9, 58, nil, + nil, nil, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 30, 31, 73, 74, nil, nil, nil, nil, + nil, 77, 28, 27, 105, 104, 106, 107, nil, nil, + 19, nil, nil, nil, nil, nil, 8, 46, 7, 10, + 109, 108, 110, 99, 57, 101, 100, 102, nil, 103, + 111, 112, nil, 95, 96, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 40, nil, nil, + 33, nil, nil, 59, 60, nil, nil, 61, nil, 35, + nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 93, 83, 86, + 87, nil, 88, 90, 89, 91, nil, nil, nil, nil, + 84, 92, nil, nil, nil, 75, 76, 72, 63, 58, + 85, 97, 98, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 237, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, 236, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 235, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, 75, 76, 72, 63, + 58, 85, 97, 98, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 30, 31, 73, 74, nil, nil, + nil, nil, nil, 77, 28, 27, 105, 104, 106, 107, + nil, nil, 237, nil, nil, nil, nil, nil, nil, 46, + nil, nil, 109, 108, 110, 99, 57, 101, 100, 102, + 292, 103, 111, 112, nil, 95, 96, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, 236, nil, nil, 59, 60, nil, nil, 61, + nil, 289, nil, 287, nil, 45, nil, nil, 293, nil, + nil, nil, nil, nil, 235, nil, nil, nil, nil, 93, + 290, 86, 87, nil, 88, 90, 89, 91, nil, nil, + nil, nil, 84, 92, nil, nil, nil, 75, 76, 72, + 63, 58, 85, 97, 98, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 30, 31, 73, 74, nil, + nil, nil, nil, nil, 77, 28, 27, 105, 104, 106, + 107, nil, nil, 237, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 109, 108, 110, 99, 57, 101, 100, + 102, 292, 103, 111, 112, nil, 95, 96, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, 236, nil, nil, 59, 60, nil, nil, + 61, nil, 289, nil, 287, nil, 45, nil, nil, 293, + nil, nil, nil, nil, nil, 235, nil, nil, nil, nil, + 93, 290, 86, 87, nil, 88, 90, 89, 91, nil, + nil, nil, nil, 84, 92, nil, nil, nil, 75, 76, + 72, 63, 58, 85, 97, 98, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 30, 31, 73, 74, + nil, nil, nil, nil, nil, 77, 28, 27, 105, 104, + 106, 107, nil, nil, 237, nil, nil, nil, nil, nil, + nil, 46, nil, nil, 109, 108, 110, 99, 57, 101, + 100, 102, 292, 103, 111, 112, nil, 95, 96, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, 236, nil, nil, 59, 60, nil, + nil, 61, nil, 289, nil, 287, nil, 45, nil, nil, + 293, nil, nil, nil, nil, nil, 235, nil, nil, nil, + nil, 93, 290, 86, 87, nil, 88, 90, 89, 91, + nil, nil, nil, nil, 84, 92, nil, nil, nil, 75, + 76, 72, 63, 58, 85, 97, 98, 64, 65, nil, + nil, nil, 68, nil, 66, 67, 69, 317, 318, 73, + 74, nil, nil, nil, nil, nil, 77, 314, 320, 105, + 104, 106, 107, nil, nil, 237, nil, nil, nil, nil, + nil, nil, 315, nil, nil, 109, 108, 110, 99, 57, + 101, 100, 102, nil, 103, 111, 112, nil, 95, 96, + nil, nil, 321, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 311, nil, nil, 307, nil, nil, 59, 60, + nil, nil, 61, nil, 306, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 93, 83, 86, 87, nil, 88, 90, 89, + 91, nil, nil, nil, nil, 84, 92, nil, nil, nil, + 75, 76, 72, 63, 58, 85, 97, 98, 64, 65, + nil, nil, nil, 68, nil, 66, 67, 69, 317, 318, + 73, 74, nil, nil, nil, nil, nil, 77, 314, 320, + 105, 104, 106, 107, nil, nil, 237, nil, nil, nil, + nil, nil, nil, 315, nil, nil, 109, 108, 110, 99, + 57, 101, 100, 102, nil, 103, 111, 112, nil, 95, + 96, nil, nil, 321, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 311, nil, nil, 236, nil, nil, 59, + 60, nil, nil, 61, nil, nil, 682, nil, 679, 678, + 677, 687, 680, nil, nil, nil, nil, nil, nil, nil, + nil, 690, nil, 93, 83, 86, 87, nil, 88, 90, + 89, 91, nil, nil, nil, nil, 84, 92, nil, nil, + nil, 323, nil, 685, 63, nil, 85, 97, 98, 75, + 76, 72, nil, 58, 698, 697, nil, 64, 65, 691, + nil, nil, 68, nil, 66, 67, 69, 317, 318, 73, + 74, nil, nil, nil, nil, nil, 77, 314, 320, 105, + 104, 106, 107, nil, nil, 237, nil, nil, nil, nil, + nil, nil, 46, nil, nil, 109, 108, 110, 99, 57, + 101, 100, 102, nil, 103, 111, 112, nil, 95, 96, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, 236, nil, nil, 59, 60, + nil, nil, 61, nil, nil, nil, nil, nil, 45, nil, + nil, nil, nil, nil, nil, nil, nil, 235, nil, nil, + nil, nil, 93, 83, 86, 87, nil, 88, 90, 89, + 91, nil, nil, nil, nil, 84, 92, nil, nil, nil, + 75, 76, 72, 63, 58, 85, 97, 98, 64, 65, + nil, nil, nil, 68, nil, 66, 67, 69, 317, 318, + 73, 74, nil, nil, nil, nil, nil, 77, 314, 320, + 105, 104, 106, 107, nil, nil, 237, nil, nil, nil, + nil, nil, nil, 46, nil, nil, 109, 108, 110, 99, + 57, 101, 100, 102, nil, 103, 111, 112, nil, 95, + 96, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, 236, nil, nil, 59, + 60, nil, nil, 61, nil, nil, nil, nil, nil, 45, + nil, nil, nil, nil, nil, nil, nil, nil, 235, nil, + nil, nil, nil, 93, 83, 86, 87, nil, 88, 90, + 89, 91, nil, nil, nil, nil, 84, 92, nil, nil, + nil, 75, 76, 72, 63, 58, 85, 97, 98, 64, + 65, nil, nil, nil, 68, nil, 66, 67, 69, 317, + 318, 73, 74, nil, nil, nil, nil, nil, 77, 314, + 320, 105, 104, 106, 107, nil, nil, 237, nil, nil, + nil, nil, nil, nil, 46, nil, nil, 109, 108, 110, + 99, 57, 101, 100, 102, nil, 103, 111, 112, nil, + 95, 96, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 230, nil, nil, 236, nil, nil, + 59, 60, nil, nil, 61, nil, nil, nil, nil, nil, + 45, nil, nil, nil, nil, nil, nil, nil, nil, 235, + nil, nil, nil, nil, 93, 83, 86, 87, nil, 88, + 90, 89, 91, nil, nil, nil, nil, 84, 92, nil, + nil, nil, nil, nil, nil, 63, nil, 85, 97, 98, + 75, 76, 72, 9, 58, nil, nil, nil, 64, 65, + nil, nil, nil, 68, nil, 66, 67, 69, 30, 31, + 73, 74, nil, nil, nil, nil, nil, 77, 28, 27, + 105, 104, 106, 107, nil, nil, 19, nil, nil, nil, + nil, nil, 8, 46, nil, 10, 109, 108, 110, 99, + 57, 101, 100, 102, nil, 103, 111, 112, nil, 95, + 96, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 40, nil, nil, 33, nil, nil, 59, + 60, nil, nil, 61, nil, 35, nil, nil, nil, 45, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 93, 83, 86, 87, nil, 88, 90, + 89, 91, nil, nil, nil, nil, 84, 92, nil, nil, + nil, 75, 76, 72, 63, 58, 85, 97, 98, 64, + 65, nil, nil, nil, 68, nil, 66, 67, 69, 317, + 318, 73, 74, nil, nil, nil, nil, nil, 77, 314, + 320, 105, 104, 106, 107, nil, nil, 237, nil, nil, + nil, nil, nil, nil, 46, nil, nil, 109, 108, 110, + 99, 57, 101, 100, 102, 292, 103, 111, 112, nil, + 95, 96, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 230, nil, nil, 236, nil, nil, + 59, 60, nil, nil, 61, nil, 289, nil, nil, nil, + 45, nil, nil, 293, nil, nil, nil, nil, nil, 235, + nil, nil, nil, nil, 93, 290, 86, 87, nil, 88, + 90, 89, 91, nil, nil, nil, nil, 84, 92, nil, + nil, nil, 75, 76, 72, 63, 58, 85, 97, 98, + 64, 65, nil, nil, nil, 68, nil, 66, 67, 69, + 317, 318, 73, 74, nil, nil, nil, nil, nil, 77, + 314, 320, 105, 104, 106, 107, nil, nil, 237, nil, + nil, nil, nil, nil, nil, 46, nil, nil, 109, 108, + 110, 99, 57, 101, 100, 102, 292, 103, 111, 112, + nil, 95, 96, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 230, nil, nil, 236, nil, + nil, 59, 60, nil, nil, 61, nil, nil, nil, nil, + nil, 45, nil, nil, 293, nil, nil, nil, nil, nil, + 235, nil, nil, nil, nil, 93, 290, 86, 87, nil, + 88, 90, 89, 91, nil, nil, nil, nil, 84, 92, + nil, nil, nil, 75, 76, 72, 63, 58, 85, 97, + 98, 64, 65, nil, nil, nil, 68, nil, 66, 67, + 69, 30, 31, 73, 74, nil, nil, nil, nil, nil, + 77, 28, 27, 105, 104, 106, 107, nil, nil, 19, + nil, nil, nil, nil, nil, nil, 46, nil, nil, 109, + 108, 110, 99, 57, 101, 100, 102, nil, 103, 111, + 112, nil, 95, 96, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 230, nil, nil, 236, + nil, nil, 59, 60, nil, nil, 61, nil, nil, nil, + nil, nil, 45, nil, nil, nil, nil, nil, nil, nil, + nil, 20, nil, nil, nil, nil, 93, 83, 86, 87, + nil, 88, 90, 89, 91, nil, nil, nil, nil, 84, + 92, nil, nil, nil, 75, 76, 72, 63, 58, 85, + 97, 98, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 30, 31, 73, 74, nil, nil, nil, nil, + nil, 77, 28, 27, 105, 104, 106, 107, nil, nil, + 19, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 109, 108, 110, 99, 57, 101, 100, 102, nil, 103, + 111, 112, nil, 95, 96, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + 236, nil, nil, 59, 60, nil, nil, 61, nil, nil, + nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 93, 83, 86, + 87, nil, 88, 90, 89, 91, nil, nil, nil, nil, + 84, 92, nil, nil, nil, 75, 76, 72, 63, 58, + 85, 97, 98, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, 236, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, 117, nil, nil, nil, nil, 116, 63, + nil, 85, 97, 98, 75, 76, 72, nil, 58, nil, + nil, nil, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 317, 318, 73, 74, nil, nil, nil, nil, + nil, 77, 314, 320, 105, 104, 106, 107, nil, nil, + 237, nil, nil, nil, nil, nil, nil, 315, nil, nil, + 109, 108, 110, 99, 57, 101, 100, 102, nil, 103, + 111, 112, nil, 95, 96, nil, nil, 321, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 357, nil, nil, + 33, nil, nil, 59, 60, nil, nil, 61, nil, 35, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 93, 83, 86, + 87, nil, 88, 90, 89, 91, nil, nil, nil, nil, + 84, 92, nil, nil, nil, 75, 76, 72, 63, 58, + 85, 97, 98, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 317, 318, 73, 74, nil, nil, nil, + nil, nil, 77, 314, 320, 105, 104, 106, 107, nil, + nil, 237, nil, nil, nil, nil, nil, nil, 315, nil, + nil, 109, 108, 110, 362, 57, 101, 100, 363, nil, + 103, 111, 112, nil, 95, 96, nil, nil, 321, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 369, nil, nil, 364, nil, + nil, 236, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, 75, 76, 72, 63, + 58, 85, 97, 98, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 317, 318, 73, 74, nil, nil, + nil, nil, nil, 77, 314, 320, 105, 104, 106, 107, + nil, nil, 237, nil, nil, nil, nil, nil, nil, 315, + nil, nil, 109, 108, 110, 362, 57, 101, 100, 363, + nil, 103, 111, 112, nil, 95, 96, nil, nil, 321, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 364, + nil, nil, 236, nil, nil, 59, 60, nil, nil, 61, + nil, nil, 682, nil, 679, 678, 677, 687, 680, nil, + nil, nil, nil, nil, nil, nil, nil, 690, nil, 93, + 83, 86, 87, nil, 88, 90, 89, 91, nil, nil, + nil, nil, 84, 92, nil, nil, nil, nil, nil, 685, + 63, nil, 85, 97, 98, 75, 76, 72, 9, 58, + 698, 697, nil, 64, 65, 691, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 7, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, nil, nil, 397, 63, + nil, 85, 97, 98, 75, 76, 72, nil, 58, nil, + nil, nil, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 30, 31, 73, 74, nil, nil, nil, nil, + nil, 77, 28, 27, 105, 104, 106, 107, nil, nil, + 19, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 109, 108, 110, 99, 57, 101, 100, 102, nil, 103, + 111, 112, nil, 95, 96, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + 236, nil, nil, 59, 60, nil, nil, 61, nil, nil, + nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 93, 83, 86, + 87, nil, 88, 90, 89, 91, nil, nil, nil, nil, + 84, 92, nil, nil, nil, 75, 76, 72, 63, 58, + 85, 97, 98, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, 236, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, 75, 76, 72, 63, + 58, 85, 97, 98, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 30, 31, 73, 74, nil, nil, + nil, nil, nil, 77, 28, 27, 105, 104, 106, 107, + nil, nil, 19, nil, nil, nil, nil, nil, nil, 46, + nil, nil, 109, 108, 110, 99, 57, 101, 100, 102, + nil, 103, 111, 112, nil, 95, 96, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, 236, nil, nil, 59, 60, nil, nil, 61, + nil, nil, nil, nil, nil, 45, nil, nil, nil, nil, + nil, nil, nil, nil, 20, nil, nil, nil, nil, 93, + 83, 86, 87, nil, 88, 90, 89, 91, nil, nil, + nil, nil, 84, 92, nil, nil, nil, 75, 76, 72, + 63, 58, 85, 97, 98, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 30, 31, 73, 74, nil, + nil, nil, nil, nil, 77, 28, 27, 105, 104, 106, + 107, nil, nil, 19, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 109, 108, 110, 99, 57, 101, 100, + 102, nil, 103, 111, 112, nil, 95, 96, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, 236, nil, nil, 59, 60, nil, nil, + 61, nil, nil, nil, nil, nil, 45, nil, nil, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, nil, + 93, 83, 86, 87, nil, 88, 90, 89, 91, nil, + nil, nil, nil, 84, 92, nil, nil, nil, nil, nil, + nil, 63, nil, 85, 97, 98, 75, 76, 72, 9, + 58, nil, nil, nil, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 30, 31, 73, 74, nil, nil, + nil, nil, nil, 77, 28, 27, 105, 104, 106, 107, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 46, + nil, 10, 109, 108, 110, 99, 57, 101, 100, 102, + nil, 103, 111, 112, nil, 95, 96, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 40, + nil, nil, 33, nil, nil, 59, 60, nil, nil, 61, + nil, 35, nil, nil, nil, 45, nil, nil, nil, nil, + nil, nil, nil, nil, 20, nil, nil, nil, nil, 93, + 83, 86, 87, nil, 88, 90, 89, 91, nil, nil, + nil, nil, 84, 92, nil, nil, nil, 75, 76, 72, + 63, 58, 85, 97, 98, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 30, 31, 73, 74, nil, + nil, nil, nil, nil, 77, 28, 27, 105, 104, 106, + 107, nil, nil, 237, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 109, 108, 110, 99, 57, 101, 100, + 102, nil, 103, 111, 112, nil, 95, 96, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, 236, nil, nil, 59, 60, nil, nil, + 61, nil, 413, nil, nil, nil, 45, nil, nil, nil, + nil, nil, nil, nil, nil, 235, nil, nil, nil, nil, + 93, 83, 86, 87, nil, 88, 90, 89, 91, nil, + nil, nil, nil, 84, 92, nil, nil, nil, 75, 76, + 72, 63, 58, 85, 97, 98, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 30, 31, 73, 74, + nil, nil, nil, nil, nil, 77, 28, 27, 105, 104, + 106, 107, nil, nil, 237, nil, nil, nil, nil, nil, + nil, 46, nil, nil, 109, 108, 110, 99, 57, 101, + 100, 102, nil, 103, 111, 112, nil, 95, 96, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, 236, nil, nil, 59, 60, nil, + nil, 61, nil, 413, nil, nil, nil, 45, nil, nil, + nil, nil, nil, nil, nil, nil, 235, nil, nil, nil, + nil, 93, 83, 86, 87, nil, 88, 90, 89, 91, + nil, nil, nil, nil, 84, 92, nil, nil, nil, 75, + 76, 72, 63, 58, 85, 97, 98, 64, 65, nil, + nil, nil, 68, nil, 66, 67, 69, 30, 31, 73, + 74, nil, nil, nil, nil, nil, 77, 28, 27, 105, + 104, 106, 107, nil, nil, 19, nil, nil, nil, nil, + nil, nil, 46, nil, nil, 109, 108, 110, 99, 57, + 101, 100, 102, nil, 103, 111, 112, nil, 95, 96, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, 236, nil, nil, 59, 60, + nil, nil, 61, nil, nil, nil, nil, nil, 45, nil, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 93, 83, 86, 87, nil, 88, 90, 89, + 91, nil, nil, nil, nil, 84, 92, nil, nil, nil, + 75, 76, 72, 63, 58, 85, 97, 98, 64, 65, + nil, nil, nil, 68, nil, 66, 67, 69, 30, 31, + 73, 74, nil, nil, nil, nil, nil, 77, 28, 27, + 105, 104, 106, 107, nil, nil, 19, nil, nil, nil, + nil, nil, nil, 46, nil, nil, 109, 108, 110, 99, + 57, 101, 100, 102, nil, 103, 111, 112, nil, 95, + 96, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, 236, nil, nil, 59, + 60, nil, nil, 61, nil, nil, nil, nil, nil, 45, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 93, 83, 86, 87, nil, 88, 90, + 89, 91, nil, nil, nil, nil, 84, 92, nil, nil, + nil, 75, 76, 72, 63, 58, 85, 97, 98, 64, + 65, nil, nil, nil, 68, nil, 66, 67, 69, 30, + 31, 73, 74, nil, nil, nil, nil, nil, 77, 28, + 27, 105, 104, 106, 107, nil, nil, 237, nil, nil, + nil, nil, nil, nil, 46, nil, nil, 109, 108, 110, + 99, 57, 101, 100, 102, nil, 103, 111, 112, nil, + 95, 96, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 230, nil, nil, 236, nil, nil, + 59, 60, nil, nil, 61, nil, nil, nil, nil, nil, + 45, nil, nil, nil, nil, nil, nil, nil, nil, 235, + nil, nil, nil, nil, 93, 83, 86, 87, nil, 88, + 90, 89, 91, nil, nil, nil, nil, 84, 92, nil, + nil, nil, 75, 76, 72, 63, 58, 85, 97, 98, + 64, 65, nil, nil, nil, 68, nil, 66, 67, 69, + 30, 31, 73, 74, nil, nil, nil, nil, nil, 77, + 28, 27, 105, 104, 106, 107, nil, nil, 237, nil, + nil, nil, nil, nil, nil, 46, nil, nil, 109, 108, + 110, 99, 57, 101, 100, 102, 292, 103, 111, 112, + nil, 95, 96, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 230, nil, nil, 236, nil, + nil, 59, 60, nil, nil, 61, nil, 289, nil, 287, + nil, 45, nil, nil, 293, nil, nil, nil, nil, nil, + 235, nil, nil, nil, nil, 93, 290, 86, 87, nil, + 88, 90, 89, 91, nil, nil, nil, nil, 84, 92, + nil, nil, nil, 75, 76, 72, 63, 58, 85, 97, + 98, 64, 65, nil, nil, nil, 68, nil, 66, 67, + 69, 30, 31, 73, 74, nil, nil, nil, nil, nil, + 77, 28, 27, 105, 104, 106, 107, nil, nil, 237, + nil, nil, nil, nil, nil, nil, 46, nil, nil, 109, + 108, 110, 99, 57, 101, 100, 102, nil, 103, 111, + 112, nil, 95, 96, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 230, nil, nil, 236, + nil, nil, 59, 60, nil, nil, 61, nil, nil, nil, + nil, nil, 45, nil, nil, nil, nil, nil, nil, nil, + nil, 235, nil, nil, nil, nil, 93, 83, 86, 87, + nil, 88, 90, 89, 91, nil, nil, nil, nil, 84, + 92, nil, nil, nil, 75, 76, 72, 63, 58, 85, + 97, 98, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 30, 31, 73, 74, nil, nil, nil, nil, + nil, 77, 28, 27, 105, 104, 106, 107, nil, nil, + 19, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 109, 108, 110, 99, 57, 101, 100, 102, nil, 103, + 111, 112, nil, 95, 96, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + 236, nil, nil, 59, 60, nil, nil, 61, nil, nil, + nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 93, 83, 86, + 87, nil, 88, 90, 89, 91, nil, nil, nil, nil, + 84, 92, nil, nil, nil, 75, 76, 72, 63, 58, + 85, 97, 98, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, 236, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, 225, nil, nil, 75, 76, 72, 63, + 58, 85, 97, 98, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 317, 318, 73, 74, nil, nil, + nil, nil, nil, 77, 314, 320, 105, 104, 106, 107, + nil, nil, 237, nil, nil, nil, nil, nil, nil, 46, + nil, nil, 109, 108, 110, 99, 57, 101, 100, 102, + nil, 103, 111, 112, nil, 95, 96, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, 236, nil, nil, 59, 60, nil, nil, 61, + nil, nil, nil, nil, nil, 45, nil, nil, nil, nil, + nil, nil, nil, nil, 235, nil, nil, nil, nil, 93, + 83, 86, 87, nil, 88, 90, 89, 91, nil, nil, + nil, nil, 84, 92, nil, nil, nil, 75, 76, 72, + 63, 58, 85, 97, 98, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 317, 318, 73, 74, nil, + nil, nil, nil, nil, 77, 314, 320, 105, 104, 106, + 107, nil, nil, 237, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 109, 108, 110, 99, 57, 101, 100, + 102, nil, 103, 111, 112, nil, 95, 96, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, 236, nil, nil, 59, 60, nil, nil, + 61, nil, nil, nil, nil, nil, 45, nil, nil, nil, + nil, nil, nil, nil, nil, 235, nil, nil, nil, nil, + 93, 83, 86, 87, nil, 88, 90, 89, 91, nil, + nil, nil, nil, 84, 92, nil, nil, nil, 75, 76, + 72, 63, 58, 85, 97, 98, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 317, 318, 73, 74, + nil, nil, nil, nil, nil, 77, 314, 320, 105, 104, + 106, 107, nil, nil, 237, nil, nil, nil, nil, nil, + nil, 46, nil, nil, 109, 108, 110, 99, 57, 101, + 100, 102, nil, 103, 111, 112, nil, 95, 96, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, 236, nil, nil, 59, 60, nil, + nil, 61, nil, nil, nil, nil, nil, 45, nil, nil, + nil, nil, nil, nil, nil, nil, 235, nil, nil, nil, + nil, 93, 83, 86, 87, nil, 88, 90, 89, 91, + nil, nil, nil, nil, 84, 92, nil, nil, nil, 75, + 76, 72, 63, 58, 85, 97, 98, 64, 65, nil, + nil, nil, 68, nil, 66, 67, 69, 317, 318, 73, + 74, nil, nil, nil, nil, nil, 77, 314, 320, 105, + 104, 106, 107, nil, nil, 237, nil, nil, nil, nil, + nil, nil, 46, nil, nil, 109, 108, 110, 99, 57, + 101, 100, 102, nil, 103, 111, 112, nil, 95, 96, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, 236, nil, nil, 59, 60, + nil, nil, 61, nil, nil, nil, nil, nil, 45, nil, + nil, nil, nil, nil, nil, nil, nil, 235, nil, nil, + nil, nil, 93, 83, 86, 87, nil, 88, 90, 89, + 91, nil, nil, nil, nil, 84, 92, nil, nil, nil, + 75, 76, 72, 63, 58, 85, 97, 98, 64, 65, + nil, nil, nil, 68, nil, 66, 67, 69, 317, 318, + 73, 74, nil, nil, nil, nil, nil, 77, 314, 320, + 105, 104, 106, 107, nil, nil, 237, nil, nil, nil, + nil, nil, nil, 46, nil, nil, 109, 108, 110, 99, + 57, 101, 100, 102, nil, 103, 111, 112, nil, 95, + 96, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, 236, nil, nil, 59, + 60, nil, nil, 61, nil, nil, nil, nil, nil, 45, + nil, nil, nil, nil, nil, nil, nil, nil, 235, nil, + nil, nil, nil, 93, 83, 86, 87, nil, 88, 90, + 89, 91, nil, nil, nil, nil, 84, 92, nil, nil, + nil, 75, 76, 72, 63, 58, 85, 97, 98, 64, + 65, nil, nil, nil, 68, nil, 66, 67, 69, 317, + 318, 73, 74, nil, nil, nil, nil, nil, 77, 314, + 320, 105, 104, 106, 107, nil, nil, 237, nil, nil, + nil, nil, nil, nil, 46, nil, nil, 109, 108, 110, + 99, 57, 101, 100, 102, nil, 103, 111, 112, nil, + 95, 96, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 230, nil, nil, 236, nil, nil, + 59, 60, nil, nil, 61, nil, nil, nil, nil, nil, + 45, nil, nil, nil, nil, nil, nil, nil, nil, 235, + nil, nil, nil, nil, 93, 83, 86, 87, nil, 88, + 90, 89, 91, nil, nil, nil, nil, 84, 92, nil, + nil, nil, 75, 76, 72, 63, 58, 85, 97, 98, + 64, 65, nil, nil, nil, 68, nil, 66, 67, 69, + 317, 318, 73, 74, nil, nil, nil, nil, nil, 77, + 314, 320, 105, 104, 106, 107, nil, nil, 237, nil, + nil, nil, nil, nil, nil, 46, nil, nil, 109, 108, + 110, 99, 57, 101, 100, 102, nil, 103, 111, 112, + nil, 95, 96, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 230, nil, nil, 236, nil, + nil, 59, 60, nil, nil, 61, nil, nil, nil, nil, + nil, 45, nil, nil, nil, nil, nil, nil, nil, nil, + 235, nil, nil, nil, nil, 93, 83, 86, 87, nil, + 88, 90, 89, 91, nil, nil, nil, nil, 84, 92, + nil, nil, nil, 75, 76, 72, 63, 58, 85, 97, + 98, 64, 65, nil, nil, nil, 68, nil, 66, 67, + 69, 317, 318, 73, 74, nil, nil, nil, nil, nil, + 77, 314, 320, 105, 104, 106, 107, nil, nil, 237, + nil, nil, nil, nil, nil, nil, 46, nil, nil, 109, + 108, 110, 99, 57, 101, 100, 102, nil, 103, 111, + 112, nil, 95, 96, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 230, nil, nil, 236, + nil, nil, 59, 60, nil, nil, 61, nil, nil, nil, + nil, nil, 45, nil, nil, nil, nil, nil, nil, nil, + nil, 235, nil, nil, nil, nil, 93, 83, 86, 87, + nil, 88, 90, 89, 91, nil, nil, nil, nil, 84, + 92, nil, nil, nil, 75, 76, 72, 63, 58, 85, + 97, 98, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 317, 318, 73, 74, nil, nil, nil, nil, + nil, 77, 314, 320, 105, 104, 106, 107, nil, nil, + 237, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 109, 108, 110, 99, 57, 101, 100, 102, nil, 103, + 111, 112, nil, 95, 96, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + 236, nil, nil, 59, 60, nil, nil, 61, nil, nil, + nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, + nil, nil, 235, nil, nil, nil, nil, 93, 83, 86, + 87, nil, 88, 90, 89, 91, nil, nil, nil, nil, + 84, 92, nil, nil, nil, 75, 76, 72, 63, 58, + 85, 97, 98, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 317, 318, 73, 74, nil, nil, nil, + nil, nil, 77, 314, 320, 105, 104, 106, 107, nil, + nil, 237, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, 236, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 235, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, 75, 76, 72, 63, + 58, 85, 97, 98, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 317, 318, 73, 74, nil, nil, + nil, nil, nil, 77, 314, 320, 105, 104, 106, 107, + nil, nil, 237, nil, nil, nil, nil, nil, nil, 46, + nil, nil, 109, 108, 110, 99, 57, 101, 100, 102, + nil, 103, 111, 112, nil, 95, 96, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, 236, nil, nil, 59, 60, nil, nil, 61, + nil, nil, nil, nil, nil, 45, nil, nil, nil, nil, + nil, nil, nil, nil, 235, nil, nil, nil, nil, 93, + 83, 86, 87, nil, 88, 90, 89, 91, nil, nil, + nil, nil, 84, 92, nil, nil, nil, 75, 76, 72, + 63, 58, 85, 97, 98, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 317, 318, 73, 74, nil, + nil, nil, nil, nil, 77, 314, 320, 105, 104, 106, + 107, nil, nil, 237, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 109, 108, 110, 99, 57, 101, 100, + 102, nil, 103, 111, 112, nil, 95, 96, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, 236, nil, nil, 59, 60, nil, nil, + 61, nil, nil, nil, nil, nil, 45, nil, nil, nil, + nil, nil, nil, nil, nil, 235, nil, nil, nil, nil, + 93, 83, 86, 87, nil, 88, 90, 89, 91, nil, + nil, nil, nil, 84, 92, nil, nil, nil, 75, 76, + 72, 63, 58, 85, 97, 98, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 317, 318, 73, 74, + nil, nil, nil, nil, nil, 77, 314, 320, 105, 104, + 106, 107, nil, nil, 237, nil, nil, nil, nil, nil, + nil, 46, nil, nil, 109, 108, 110, 99, 57, 101, + 100, 102, nil, 103, 111, 112, nil, 95, 96, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, 236, nil, nil, 59, 60, nil, + nil, 61, nil, nil, nil, nil, nil, 45, nil, nil, + nil, nil, nil, nil, nil, nil, 235, nil, nil, nil, + nil, 93, 83, 86, 87, nil, 88, 90, 89, 91, + nil, nil, nil, nil, 84, 92, nil, nil, nil, 75, + 76, 72, 63, 58, 85, 97, 98, 64, 65, nil, + nil, nil, 68, nil, 66, 67, 69, 317, 318, 73, + 74, nil, nil, nil, nil, nil, 77, 314, 320, 105, + 104, 106, 107, nil, nil, 237, nil, nil, nil, nil, + nil, nil, 46, nil, nil, 109, 108, 110, 99, 57, + 101, 100, 102, nil, 103, 111, 112, nil, 95, 96, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, 236, nil, nil, 59, 60, + nil, nil, 61, nil, nil, nil, nil, nil, 45, nil, + nil, nil, nil, nil, nil, nil, nil, 235, nil, nil, + nil, nil, 93, 83, 86, 87, nil, 88, 90, 89, + 91, nil, nil, nil, nil, 84, 92, nil, nil, nil, + 75, 76, 72, 63, 58, 85, 97, 98, 64, 65, + nil, nil, nil, 68, nil, 66, 67, 69, 317, 318, + 73, 74, nil, nil, nil, nil, nil, 77, 314, 320, + 105, 104, 106, 107, nil, nil, 237, nil, nil, nil, + nil, nil, nil, 46, nil, nil, 109, 108, 110, 99, + 57, 101, 100, 102, nil, 103, 111, 112, nil, 95, + 96, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, 236, nil, nil, 59, + 60, nil, nil, 61, nil, nil, nil, nil, nil, 45, + nil, nil, nil, nil, nil, nil, nil, nil, 235, nil, + nil, nil, nil, 93, 83, 86, 87, nil, 88, 90, + 89, 91, nil, nil, nil, nil, 84, 92, nil, nil, + nil, 75, 76, 72, 63, 58, 85, 97, 98, 64, + 65, nil, nil, nil, 68, nil, 66, 67, 69, 317, + 318, 73, 74, nil, nil, nil, nil, nil, 77, 314, + 320, 105, 104, 106, 107, nil, nil, 237, nil, nil, + nil, nil, nil, nil, 46, nil, nil, 109, 108, 110, + 99, 57, 101, 100, 102, nil, 103, 111, 112, nil, + 95, 96, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 230, nil, nil, 236, nil, nil, + 59, 60, nil, nil, 61, nil, nil, nil, nil, nil, + 45, nil, nil, nil, nil, nil, nil, nil, nil, 235, + nil, nil, nil, nil, 93, 83, 86, 87, nil, 88, + 90, 89, 91, nil, nil, nil, nil, 84, 92, nil, + nil, nil, 75, 76, 72, 63, 58, 85, 97, 98, + 64, 65, nil, nil, nil, 68, nil, 66, 67, 69, + 317, 318, 73, 74, nil, nil, nil, nil, nil, 77, + 314, 320, 105, 104, 106, 107, nil, nil, 237, nil, + nil, nil, nil, nil, nil, 46, nil, nil, 109, 108, + 110, 99, 57, 101, 100, 102, nil, 103, 111, 112, + nil, 95, 96, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 230, nil, nil, 236, nil, + nil, 59, 60, nil, nil, 61, nil, nil, nil, nil, + nil, 45, nil, nil, nil, nil, nil, nil, nil, nil, + 235, nil, nil, nil, nil, 93, 83, 86, 87, nil, + 88, 90, 89, 91, nil, nil, nil, nil, 84, 92, + nil, nil, nil, 75, 76, 72, 63, 58, 85, 97, + 98, 64, 65, nil, nil, nil, 68, nil, 66, 67, + 69, 317, 318, 73, 74, nil, nil, nil, nil, nil, + 77, 314, 320, 105, 104, 106, 107, nil, nil, 237, + nil, nil, nil, nil, nil, nil, 46, nil, nil, 109, + 108, 110, 99, 57, 101, 100, 102, nil, 103, 111, + 112, nil, 95, 96, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 230, nil, nil, 236, + nil, nil, 59, 60, nil, nil, 61, nil, nil, nil, + nil, nil, 45, nil, nil, nil, nil, nil, nil, nil, + nil, 235, nil, nil, nil, nil, 93, 83, 86, 87, + nil, 88, 90, 89, 91, nil, nil, nil, nil, 84, + 92, nil, nil, nil, 75, 76, 72, 63, 58, 85, + 97, 98, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 317, 318, 73, 74, nil, nil, nil, nil, + nil, 77, 314, 320, 105, 104, 106, 107, nil, nil, + 237, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 109, 108, 110, 99, 57, 101, 100, 102, nil, 103, + 111, 112, nil, 95, 96, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + 236, nil, nil, 59, 60, nil, nil, 61, nil, nil, + nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, + nil, nil, 235, nil, nil, nil, nil, 93, 83, 86, + 87, nil, 88, 90, 89, 91, nil, nil, nil, nil, + 84, 92, nil, nil, nil, 75, 76, 72, 63, 58, + 85, 97, 98, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 317, 318, 73, 74, nil, nil, nil, + nil, nil, 77, 314, 320, 105, 104, 106, 107, nil, + nil, 237, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, 236, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 235, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, 75, 76, 72, 63, + 58, 85, 97, 98, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 317, 318, 73, 74, nil, nil, + nil, nil, nil, 77, 314, 320, 105, 104, 106, 107, + nil, nil, 237, nil, nil, nil, nil, nil, nil, 46, + nil, nil, 109, 108, 110, 99, 57, 101, 100, 102, + nil, 103, 111, 112, nil, 95, 96, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, 236, nil, nil, 59, 60, nil, nil, 61, + nil, nil, nil, nil, nil, 45, nil, nil, nil, nil, + nil, nil, nil, nil, 235, nil, nil, nil, nil, 93, + 83, 86, 87, nil, 88, 90, 89, 91, nil, nil, + nil, nil, 84, 92, nil, nil, nil, 75, 76, 72, + 63, 58, 85, 97, 98, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 317, 318, 73, 74, nil, + nil, nil, nil, nil, 77, 314, 320, 105, 104, 106, + 107, nil, nil, 237, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 109, 108, 110, 99, 57, 101, 100, + 102, nil, 103, 111, 112, nil, 95, 96, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, 236, nil, nil, 59, 60, nil, nil, + 61, nil, nil, nil, nil, nil, 45, nil, nil, nil, + nil, nil, nil, nil, nil, 235, nil, nil, nil, nil, + 93, 83, 86, 87, nil, 88, 90, 89, 91, nil, + nil, nil, nil, 84, 92, nil, nil, nil, 75, 76, + 72, 63, 58, 85, 97, 98, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 317, 318, 73, 74, + nil, nil, nil, nil, nil, 77, 314, 320, 105, 104, + 106, 107, nil, nil, 237, nil, nil, nil, nil, nil, + nil, 46, nil, nil, 109, 108, 110, 99, 57, 101, + 100, 102, nil, 103, 111, 112, nil, 95, 96, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, 236, nil, nil, 59, 60, nil, + nil, 61, nil, nil, nil, nil, nil, 45, nil, nil, + nil, nil, nil, nil, nil, nil, 235, nil, nil, nil, + nil, 93, 83, 86, 87, nil, 88, 90, 89, 91, + nil, nil, nil, nil, 84, 92, nil, nil, nil, 75, + 76, 72, 63, 58, 85, 97, 98, 64, 65, nil, + nil, nil, 68, nil, 66, 67, 69, 317, 318, 73, + 74, nil, nil, nil, nil, nil, 77, 314, 320, 105, + 104, 106, 107, nil, nil, 237, nil, nil, nil, nil, + nil, nil, 46, nil, nil, 109, 108, 110, 99, 57, + 101, 100, 102, nil, 103, 111, 112, nil, 95, 96, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, 236, nil, nil, 59, 60, + nil, nil, 61, nil, nil, nil, nil, nil, 45, nil, + nil, nil, nil, nil, nil, nil, nil, 235, nil, nil, + nil, nil, 93, 83, 86, 87, nil, 88, 90, 89, + 91, nil, nil, nil, nil, 84, 92, nil, nil, nil, + 75, 76, 72, 63, 58, 85, 97, 98, 64, 65, + nil, nil, nil, 68, nil, 66, 67, 69, 30, 31, + 73, 74, nil, nil, nil, nil, nil, 77, 28, 27, + 105, 104, 106, 107, nil, nil, 237, nil, nil, nil, + nil, nil, nil, 46, nil, nil, 109, 108, 110, 99, + 57, 101, 100, 102, 292, 103, 111, 112, nil, 95, + 96, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, 236, nil, nil, 59, + 60, nil, nil, 61, nil, 289, nil, 287, nil, 45, + nil, nil, 293, nil, nil, nil, nil, nil, 235, nil, + nil, nil, nil, 93, 290, 86, 87, nil, 88, 90, + 89, 91, nil, nil, nil, nil, 84, 92, nil, nil, + nil, 75, 76, 72, 63, 58, 85, 97, 98, 64, + 65, nil, nil, nil, 68, nil, 66, 67, 69, 30, + 31, 73, 74, nil, nil, nil, nil, nil, 77, 28, + 27, 105, 104, 106, 107, nil, nil, 237, nil, nil, + nil, nil, nil, nil, 46, nil, nil, 109, 108, 110, + 99, 57, 101, 100, 102, 292, 103, 111, 112, nil, + 95, 96, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 230, nil, nil, 236, nil, nil, + 59, 60, nil, nil, 61, nil, 289, nil, 287, nil, + 45, nil, nil, 293, nil, nil, nil, nil, nil, 235, + nil, nil, nil, nil, 93, 290, 86, 87, nil, 88, + 90, 89, 91, nil, nil, nil, nil, 84, 92, nil, + nil, nil, 75, 76, 72, 63, 58, 85, 97, 98, + 64, 65, nil, nil, nil, 68, nil, 66, 67, 69, + 30, 31, 73, 74, nil, nil, nil, nil, nil, 77, + 28, 27, 105, 104, 106, 107, nil, nil, 237, nil, + nil, nil, nil, nil, nil, 46, nil, nil, 109, 108, + 110, 99, 57, 101, 100, 102, 292, 103, 111, 112, + nil, 95, 96, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 230, nil, nil, 236, nil, + nil, 59, 60, nil, nil, 61, nil, 289, nil, 287, + nil, 45, nil, nil, 293, nil, nil, nil, nil, nil, + 235, nil, nil, nil, nil, 93, 290, 86, 87, nil, + 88, 90, 89, 91, nil, nil, nil, nil, 84, 92, + 225, nil, nil, 75, 76, 72, 63, 58, 85, 97, + 98, 64, 65, nil, nil, nil, 68, nil, 66, 67, + 69, 317, 318, 73, 74, nil, nil, nil, nil, nil, + 77, 314, 320, 105, 104, 106, 107, nil, nil, 237, + nil, nil, nil, nil, nil, nil, 46, nil, nil, 109, + 108, 110, 99, 57, 101, 100, 102, nil, 103, 111, + 112, nil, 95, 96, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 230, nil, nil, 236, + nil, nil, 59, 60, nil, nil, 61, nil, nil, nil, + nil, nil, 45, nil, nil, nil, nil, nil, nil, nil, + nil, 235, nil, nil, nil, nil, 93, 83, 86, 87, + nil, 88, 90, 89, 91, nil, nil, nil, nil, 84, + 92, nil, nil, nil, 75, 76, 72, 63, 58, 85, + 97, 98, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 317, 318, 73, 74, nil, nil, nil, nil, + nil, 77, 314, 320, 105, 104, 106, 107, nil, nil, + 237, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 109, 108, 110, 99, 57, 101, 100, 102, nil, 103, + 111, 112, nil, 95, 96, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + 236, nil, nil, 59, 60, nil, nil, 61, nil, nil, + nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, + nil, nil, 235, nil, nil, nil, nil, 93, 83, 86, + 87, nil, 88, 90, 89, 91, nil, nil, nil, nil, + 84, 92, nil, nil, nil, 75, 76, 72, 63, 58, + 85, 97, 98, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 317, 318, 73, 74, nil, nil, nil, + nil, nil, 77, 314, 320, 105, 104, 106, 107, nil, + nil, 237, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, 236, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 235, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, 75, 76, 72, 63, + 58, 85, 97, 98, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 317, 318, 73, 74, nil, nil, + nil, nil, nil, 77, 314, 320, 105, 104, 106, 107, + nil, nil, 237, nil, nil, nil, nil, nil, nil, 46, + nil, nil, 109, 108, 110, 99, 57, 101, 100, 102, + nil, 103, 111, 112, nil, 95, 96, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, 236, nil, nil, 59, 60, nil, nil, 61, + nil, nil, nil, nil, nil, 45, nil, nil, nil, nil, + nil, nil, nil, nil, 235, nil, nil, nil, nil, 93, + 83, 86, 87, nil, 88, 90, 89, 91, nil, nil, + nil, nil, 84, 92, nil, nil, nil, nil, nil, nil, + 63, nil, 85, 97, 98, 75, 76, 72, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, nil, + 10, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, 75, 76, 72, 63, + 58, 85, 97, 98, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 317, 318, 73, 74, nil, nil, + nil, nil, nil, 77, 314, 320, 105, 104, 106, 107, + nil, nil, 237, nil, nil, nil, nil, nil, nil, 315, + nil, nil, 109, 108, 110, 99, 57, 101, 100, 102, + nil, 103, 111, 112, nil, 95, 96, nil, nil, 321, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 311, + nil, nil, 236, nil, nil, 59, 60, nil, nil, 61, + nil, nil, 682, nil, 679, 678, 677, 687, 680, nil, + nil, nil, nil, nil, nil, nil, nil, 690, nil, 93, + 83, 86, 87, nil, 88, 90, 89, 91, nil, nil, + nil, nil, 84, 92, nil, nil, nil, 515, nil, 685, + 63, nil, 85, 97, 98, 75, 76, 72, nil, 58, + 698, 697, nil, 64, 65, 691, nil, nil, 68, nil, + 66, 67, 69, 317, 318, 73, 74, nil, nil, nil, + nil, nil, 77, 314, 320, 105, 104, 106, 107, nil, + nil, 237, nil, nil, nil, nil, nil, nil, 315, nil, + nil, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, nil, nil, 321, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 311, nil, + nil, 307, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, 75, 76, 72, 63, + 58, 85, 97, 98, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 317, 318, 73, 74, nil, nil, + nil, nil, nil, 77, 314, 320, 105, 104, 106, 107, + nil, nil, 237, nil, nil, nil, nil, nil, nil, 46, + nil, nil, 109, 108, 110, 99, 57, 101, 100, 102, + nil, 103, 111, 112, nil, 95, 96, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, 236, nil, nil, 59, 60, nil, nil, 61, + nil, nil, nil, nil, nil, 45, nil, nil, nil, nil, + nil, nil, nil, nil, 235, nil, nil, nil, nil, 93, + 83, 86, 87, nil, 88, 90, 89, 91, nil, nil, + nil, nil, 84, 92, nil, nil, nil, 75, 76, 72, + 63, 58, 85, 97, 98, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 317, 318, 73, 74, nil, + nil, nil, nil, nil, 77, 314, 320, 105, 104, 106, + 107, nil, nil, 237, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 109, 108, 110, 99, 57, 101, 100, + 102, nil, 103, 111, 112, nil, 95, 96, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, 236, 532, nil, 59, 60, nil, nil, + 61, nil, nil, nil, nil, nil, 45, nil, nil, nil, + nil, nil, nil, nil, nil, 235, nil, nil, nil, nil, + 93, 83, 86, 87, nil, 88, 90, 89, 91, nil, + nil, nil, nil, 84, 92, nil, nil, nil, 75, 76, + 72, 63, 58, 85, 97, 98, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 30, 31, 73, 74, + nil, nil, nil, nil, nil, 77, 28, 27, 105, 104, + 106, 107, nil, nil, 19, nil, nil, nil, nil, nil, + nil, 46, nil, nil, 109, 108, 110, 99, 57, 101, + 100, 102, nil, 103, 111, 112, nil, 95, 96, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, 236, nil, nil, 59, 60, nil, + nil, 61, nil, nil, nil, nil, nil, 45, nil, nil, + nil, nil, nil, nil, nil, nil, 20, nil, nil, nil, + nil, 93, 83, 86, 87, nil, 88, 90, 89, 91, + nil, nil, nil, nil, 84, 92, nil, nil, nil, 75, + 76, 72, 63, 58, 85, 97, 98, 64, 65, nil, + nil, nil, 68, nil, 66, 67, 69, 30, 31, 73, + 74, nil, nil, nil, nil, nil, 77, 28, 27, 105, + 104, 106, 107, nil, nil, 19, nil, nil, nil, nil, + nil, nil, 46, nil, nil, 109, 108, 110, 99, 57, + 101, 100, 102, nil, 103, 111, 112, nil, 95, 96, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, 236, nil, nil, 59, 60, + nil, nil, 61, nil, nil, nil, nil, nil, 45, nil, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 93, 83, 86, 87, nil, 88, 90, 89, + 91, nil, nil, nil, nil, 84, 92, nil, nil, nil, + 75, 76, 72, 63, 58, 85, 97, 98, 64, 65, + nil, nil, nil, 68, nil, 66, 67, 69, 30, 31, + 73, 74, nil, nil, nil, nil, nil, 77, 28, 27, + 105, 104, 106, 107, nil, nil, 19, nil, nil, nil, + nil, nil, nil, 46, nil, nil, 109, 108, 110, 99, + 57, 101, 100, 102, nil, 103, 111, 112, nil, 95, + 96, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, 236, nil, nil, 59, + 60, nil, nil, 61, nil, nil, nil, nil, nil, 45, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 93, 83, 86, 87, nil, 88, 90, + 89, 91, nil, nil, nil, nil, 84, 92, nil, nil, + nil, 75, 76, 72, 63, 58, 85, 97, 98, 64, + 65, nil, nil, nil, 68, nil, 66, 67, 69, 317, + 318, 73, 74, nil, nil, nil, nil, nil, 77, 314, + 320, 105, 104, 106, 107, nil, nil, 237, nil, nil, + nil, nil, nil, nil, 46, nil, nil, 109, 108, 110, + 99, 57, 101, 100, 102, nil, 103, 111, 112, nil, + 95, 96, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 230, nil, nil, 236, nil, nil, + 59, 60, nil, nil, 61, nil, nil, nil, nil, nil, + 45, nil, nil, nil, nil, nil, nil, nil, nil, 235, + nil, nil, nil, nil, 93, 83, 86, 87, nil, 88, + 90, 89, 91, nil, nil, nil, nil, 84, 92, nil, + nil, nil, 75, 76, 72, 63, 58, 85, 97, 98, + 64, 65, nil, nil, nil, 68, nil, 66, 67, 69, + 30, 31, 73, 74, nil, nil, nil, nil, nil, 77, + 28, 27, 105, 104, 106, 107, nil, nil, 237, nil, + nil, nil, nil, nil, nil, 46, nil, nil, 109, 108, + 110, 99, 57, 101, 100, 102, 292, 103, 111, 112, + nil, 95, 96, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 230, nil, nil, 236, nil, + nil, 59, 60, nil, nil, 61, nil, 289, nil, 287, + nil, 45, nil, nil, 293, nil, nil, nil, nil, nil, + 235, nil, nil, nil, nil, 93, 290, 86, 87, nil, + 88, 90, 89, 91, nil, nil, nil, nil, 84, 92, + nil, nil, nil, 75, 76, 72, 63, 58, 85, 97, + 98, 64, 65, nil, nil, nil, 68, nil, 66, 67, + 69, 317, 318, 73, 74, nil, nil, nil, nil, nil, + 77, 314, 320, 105, 104, 106, 107, nil, nil, 237, + nil, nil, nil, nil, nil, nil, 46, nil, nil, 109, + 108, 110, 99, 57, 101, 100, 102, nil, 103, 111, + 112, nil, 95, 96, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 230, nil, nil, 236, + nil, nil, 59, 60, nil, nil, 61, nil, nil, nil, + nil, nil, 45, nil, nil, nil, nil, nil, nil, nil, + nil, 235, nil, nil, nil, nil, 93, 83, 86, 87, + nil, 88, 90, 89, 91, nil, nil, nil, nil, 84, + 92, nil, nil, nil, 75, 76, 72, 63, 58, 85, + 97, 98, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 317, 318, 73, 74, nil, nil, nil, nil, + nil, 77, 314, 320, 105, 104, 106, 107, nil, nil, + 237, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 109, 108, 110, 99, 57, 101, 100, 102, nil, 103, + 111, 112, nil, 95, 96, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + 236, nil, nil, 59, 60, nil, nil, 61, nil, nil, + nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, + nil, nil, 235, nil, nil, nil, nil, 93, 83, 86, + 87, nil, 88, 90, 89, 91, nil, nil, nil, nil, + 84, 92, nil, nil, nil, 75, 76, 72, 63, 58, + 85, 97, 98, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 317, 318, 73, 74, nil, nil, nil, + nil, nil, 77, 314, 320, 105, 104, 106, 107, nil, + nil, 237, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, 236, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 235, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, 75, 76, 72, 63, + 58, 85, 97, 98, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 317, 318, 73, 74, nil, nil, + nil, nil, nil, 77, 314, 320, 105, 104, 106, 107, + nil, nil, 237, nil, nil, nil, nil, nil, nil, 46, + nil, nil, 109, 108, 110, 99, 57, 101, 100, 102, + 292, 103, 111, 112, nil, 95, 96, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, 236, nil, nil, 59, 60, nil, nil, 61, + nil, 640, nil, 287, nil, 45, nil, nil, 293, nil, + nil, nil, nil, nil, 235, nil, nil, nil, nil, 93, + 290, 86, 87, nil, 88, 90, 89, 91, nil, nil, + nil, nil, 84, 92, nil, nil, nil, 75, 76, 72, + 63, 58, 85, 97, 98, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 317, 318, 73, 74, nil, + nil, nil, nil, nil, 77, 314, 320, 105, 104, 106, + 107, nil, nil, 237, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 109, 108, 110, 99, 57, 101, 100, + 102, 292, 103, 111, 112, nil, 95, 96, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, 236, nil, nil, 59, 60, nil, nil, + 61, nil, nil, nil, 287, nil, 45, nil, nil, 293, + nil, nil, nil, nil, nil, 235, nil, nil, nil, nil, + 93, 290, 86, 87, nil, 88, 90, 89, 91, nil, + nil, nil, nil, 84, 92, nil, nil, nil, 75, 76, + 72, 63, 58, 85, 97, 98, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 317, 318, 73, 74, + nil, nil, nil, nil, nil, 77, 314, 320, 105, 104, + 106, 107, nil, nil, 237, nil, nil, nil, nil, nil, + nil, 46, nil, nil, 109, 108, 110, 99, 57, 101, + 100, 102, nil, 103, 111, 112, nil, 95, 96, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, 236, nil, nil, 59, 60, nil, + nil, 61, nil, nil, nil, nil, nil, 45, nil, nil, + nil, nil, nil, nil, nil, nil, 235, nil, nil, nil, + nil, 93, 83, 86, 87, nil, 88, 90, 89, 91, + nil, nil, nil, nil, 84, 92, nil, nil, nil, nil, + nil, nil, 63, nil, 85, 97, 98, 75, 76, 72, + 9, 58, nil, nil, nil, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 30, 31, 73, 74, nil, + nil, nil, nil, nil, 77, 28, 27, 105, 104, 106, + 107, nil, nil, 19, nil, nil, nil, nil, nil, 8, + 46, 300, 10, 109, 108, 110, 99, 57, 101, 100, + 102, nil, 103, 111, 112, nil, 95, 96, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 40, nil, nil, 33, nil, nil, 59, 60, nil, nil, + 61, nil, 35, nil, nil, nil, 45, nil, nil, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, nil, + 93, 83, 86, 87, nil, 88, 90, 89, 91, nil, + nil, nil, nil, 84, 92, nil, nil, nil, nil, nil, + 397, 63, nil, 85, 97, 98, 75, 76, 72, nil, + 58, nil, nil, nil, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 317, 318, 73, 74, nil, nil, + nil, nil, nil, 77, 314, 320, 105, 104, 106, 107, + nil, nil, 237, nil, nil, nil, nil, nil, nil, 315, + nil, nil, 109, 108, 110, 99, 57, 101, 100, 102, + nil, 103, 111, 112, nil, 95, 96, nil, nil, 321, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 311, + nil, nil, 307, nil, nil, 59, 60, nil, nil, 61, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 93, + 83, 86, 87, nil, 88, 90, 89, 91, nil, nil, + nil, nil, 84, 92, nil, nil, nil, 75, 76, 72, + 63, 58, 85, 97, 98, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 30, 31, 73, 74, nil, + nil, nil, nil, nil, 77, 28, 27, 105, 104, 106, + 107, nil, nil, 237, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 109, 108, 110, 99, 57, 101, 100, + 102, 292, 103, 111, 112, nil, 95, 96, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, 236, nil, nil, 59, 60, nil, nil, + 61, nil, 289, nil, 287, nil, 45, nil, nil, 293, + nil, nil, nil, nil, nil, 235, nil, nil, nil, nil, + 93, 290, 86, 87, nil, 88, 90, 89, 91, nil, + nil, nil, nil, 84, 92, nil, nil, nil, 75, 76, + 72, 63, 58, 85, 97, 98, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 317, 318, 73, 74, + nil, nil, nil, nil, nil, 77, 314, 320, 105, 104, + 106, 107, nil, nil, 237, nil, nil, nil, nil, nil, + nil, 315, nil, nil, 109, 108, 110, 99, 57, 101, + 100, 102, nil, 103, 111, 112, nil, 95, 96, nil, + nil, 321, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 311, nil, nil, 307, nil, nil, 59, 60, nil, + nil, 61, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 93, 83, 86, 87, nil, 88, 90, 89, 91, + nil, nil, nil, nil, 84, 92, nil, nil, nil, 75, + 76, 72, 63, 58, 85, 97, 98, 64, 65, nil, + nil, nil, 68, nil, 66, 67, 69, 317, 318, 73, + 74, nil, nil, nil, nil, nil, 77, 314, 320, 105, + 104, 106, 107, nil, nil, 237, nil, nil, nil, nil, + nil, nil, 46, nil, nil, 109, 108, 110, 99, 57, + 101, 100, 102, nil, 103, 111, 112, nil, 95, 96, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, 236, nil, nil, 59, 60, + nil, nil, 61, nil, nil, nil, nil, nil, 45, nil, + nil, nil, nil, nil, nil, nil, nil, 235, nil, nil, + nil, nil, 93, 83, 86, 87, nil, 88, 90, 89, + 91, nil, nil, nil, nil, 84, 92, nil, nil, nil, + 75, 76, 72, 63, 58, 85, 97, 98, 64, 65, + nil, nil, nil, 68, nil, 66, 67, 69, 317, 318, + 73, 74, nil, nil, nil, nil, nil, 77, 314, 320, + 105, 104, 106, 107, nil, nil, 237, nil, nil, nil, + nil, nil, nil, 46, nil, nil, 109, 108, 110, 99, + 57, 101, 100, 102, nil, 103, 111, 112, nil, 95, + 96, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, 236, nil, nil, 59, + 60, nil, nil, 61, nil, nil, nil, nil, nil, 45, + nil, nil, nil, nil, nil, nil, nil, nil, 235, nil, + nil, nil, nil, 93, 83, 86, 87, nil, 88, 90, + 89, 91, nil, nil, nil, nil, 84, 92, nil, nil, + nil, 75, 76, 72, 63, 58, 85, 97, 98, 64, + 65, nil, nil, nil, 68, nil, 66, 67, 69, 30, + 31, 73, 74, nil, nil, nil, nil, nil, 77, 28, + 27, 105, 104, 106, 107, nil, nil, 19, nil, nil, + nil, nil, nil, nil, 46, nil, nil, 109, 108, 110, + 99, 57, 101, 100, 102, nil, 103, 111, 112, nil, + 95, 96, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 230, nil, nil, 236, nil, nil, + 59, 60, nil, nil, 61, nil, nil, nil, nil, nil, + 45, nil, nil, nil, nil, nil, nil, nil, nil, 20, + nil, nil, nil, nil, 93, 83, 86, 87, nil, 88, + 90, 89, 91, nil, nil, nil, nil, 84, 92, nil, + nil, nil, 75, 76, 72, 63, 58, 85, 97, 98, + 64, 65, nil, nil, nil, 68, nil, 66, 67, 69, + 317, 318, 73, 74, nil, nil, nil, nil, nil, 77, + 314, 320, 105, 104, 106, 107, nil, nil, 237, nil, + nil, nil, nil, nil, nil, 46, nil, nil, 109, 108, + 110, 99, 57, 101, 100, 102, 292, 103, 111, 112, + nil, 95, 96, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 230, nil, nil, 236, nil, + nil, 59, 60, nil, nil, 61, nil, 640, nil, nil, + nil, 45, nil, nil, 293, nil, nil, nil, nil, nil, + 235, nil, nil, nil, nil, 93, 290, 86, 87, nil, + 88, 90, 89, 91, nil, nil, nil, nil, 84, 92, + nil, nil, nil, 75, 76, 72, 63, 58, 85, 97, + 98, 64, 65, nil, nil, nil, 68, nil, 66, 67, + 69, 317, 318, 73, 74, nil, nil, nil, nil, nil, + 77, 314, 320, 105, 104, 106, 107, nil, nil, 237, + nil, nil, nil, nil, nil, nil, 46, nil, nil, 109, + 108, 110, 99, 57, 101, 100, 102, 292, 103, 111, + 112, nil, 95, 96, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 230, nil, nil, 236, + nil, nil, 59, 60, nil, nil, 61, nil, nil, nil, + nil, nil, 45, nil, nil, 293, nil, nil, nil, nil, + nil, 235, nil, nil, nil, nil, 93, 290, 86, 87, + nil, 88, 90, 89, 91, nil, nil, nil, nil, 84, + 92, nil, nil, nil, 75, 76, 72, 63, 58, 85, + 97, 98, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 317, 318, 73, 74, nil, nil, nil, nil, + nil, 77, 314, 320, 105, 104, 106, 107, nil, nil, + 237, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 109, 108, 110, 99, 57, 101, 100, 102, nil, 103, + 111, 112, nil, 95, 96, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + 236, nil, nil, 59, 60, nil, nil, 61, nil, 289, + nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, + nil, nil, 235, nil, nil, nil, nil, 93, 83, 86, + 87, nil, 88, 90, 89, 91, nil, nil, nil, nil, + 84, 92, nil, nil, nil, 75, 76, 72, 63, 58, + 85, 97, 98, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 237, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 109, 108, 110, 99, 57, 101, 100, 102, 292, + 103, 111, 112, nil, 95, 96, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, 236, nil, nil, 59, 60, nil, nil, 61, nil, + 289, nil, 287, nil, 45, nil, nil, 293, nil, nil, + nil, nil, nil, 235, nil, nil, nil, nil, 93, 290, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, 75, 76, 72, 63, + 58, 85, 97, 98, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 30, 31, 73, 74, nil, nil, + nil, nil, nil, 77, 28, 27, 105, 104, 106, 107, + nil, nil, 237, nil, nil, nil, nil, nil, nil, 46, + nil, nil, 109, 108, 110, 99, 57, 101, 100, 102, + 292, 103, 111, 112, nil, 95, 96, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, 236, nil, nil, 59, 60, nil, nil, 61, + nil, 289, nil, 287, nil, 45, nil, nil, 293, nil, + nil, nil, nil, nil, 235, nil, nil, nil, nil, 93, + 290, 86, 87, nil, 88, 90, 89, 91, nil, nil, + nil, nil, 84, 92, nil, nil, nil, 75, 76, 72, + 63, 58, 85, 97, 98, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 317, 318, 73, 74, nil, + nil, nil, nil, nil, 77, 314, 320, 105, 104, 106, + 107, nil, nil, 237, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 109, 108, 110, 99, 57, 101, 100, + 102, nil, 103, 111, 112, nil, 95, 96, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, 236, nil, nil, 59, 60, nil, nil, + 61, nil, 744, nil, nil, nil, 45, nil, nil, nil, + nil, nil, nil, nil, nil, 235, nil, nil, nil, nil, + 93, 83, 86, 87, nil, 88, 90, 89, 91, nil, + nil, nil, nil, 84, 92, nil, nil, nil, 75, 76, + 72, 63, 58, 85, 97, 98, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 30, 31, 73, 74, + nil, nil, nil, nil, nil, 77, 28, 27, 105, 104, + 106, 107, nil, nil, 237, nil, nil, nil, nil, nil, + nil, 46, nil, nil, 109, 108, 110, 99, 57, 101, + 100, 102, nil, 103, 111, 112, nil, 95, 96, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, 236, nil, nil, 59, 60, nil, + nil, 61, nil, nil, nil, nil, nil, 45, nil, nil, + nil, nil, nil, nil, nil, nil, 235, nil, nil, nil, + nil, 93, 83, 86, 87, nil, 88, 90, 89, 91, + nil, nil, nil, nil, 84, 92, nil, nil, nil, 75, + 76, 72, 63, 58, 85, 97, 98, 64, 65, nil, + nil, nil, 68, nil, 66, 67, 69, 30, 31, 73, + 74, nil, nil, nil, nil, nil, 77, 28, 27, 105, + 104, 106, 107, nil, nil, 237, nil, nil, nil, nil, + nil, nil, 46, nil, nil, 109, 108, 110, 99, 57, + 101, 100, 102, 292, 103, 111, 112, nil, 95, 96, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, 236, nil, nil, 59, 60, + nil, nil, 61, nil, 289, nil, 287, nil, 45, nil, + nil, 293, nil, nil, nil, nil, nil, 235, nil, nil, + nil, nil, 93, 290, 86, 87, nil, 88, 90, 89, + 91, nil, nil, nil, nil, 84, 92, nil, nil, nil, + nil, nil, nil, 63, nil, 85, 97, 98, 75, 76, + 72, 9, 58, nil, nil, nil, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 30, 31, 73, 74, + nil, nil, nil, nil, nil, 77, 28, 27, 105, 104, + 106, 107, nil, nil, 19, nil, nil, nil, nil, nil, + 8, 46, nil, 10, 109, 108, 110, 99, 57, 101, + 100, 102, nil, 103, 111, 112, nil, 95, 96, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 40, nil, nil, 33, nil, nil, 59, 60, nil, + nil, 61, nil, 35, nil, nil, nil, 45, nil, nil, + nil, nil, nil, nil, nil, nil, 20, nil, nil, nil, + nil, 93, 83, 86, 87, nil, 88, 90, 89, 91, + nil, nil, nil, nil, 84, 92, nil, nil, nil, 75, + 76, 72, 63, 58, 85, 97, 98, 64, 65, nil, + nil, nil, 68, nil, 66, 67, 69, 317, 318, 73, + 74, nil, nil, nil, nil, nil, 77, 314, 320, 105, + 104, 106, 107, nil, nil, 237, nil, nil, nil, nil, + nil, nil, 46, nil, nil, 109, 108, 110, 99, 57, + 101, 100, 102, nil, 103, 111, 112, nil, 95, 96, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, 236, nil, nil, 59, 60, + nil, nil, 61, nil, nil, nil, nil, nil, 45, nil, + nil, nil, nil, nil, nil, nil, nil, 235, nil, nil, + nil, nil, 93, 83, 86, 87, nil, 88, 90, 89, + 91, nil, nil, nil, nil, 84, 92, nil, nil, nil, + 75, 76, 72, 63, 58, 85, 97, 98, 64, 65, + nil, nil, nil, 68, nil, 66, 67, 69, 317, 318, + 73, 74, nil, nil, nil, nil, nil, 77, 314, 320, + 105, 104, 106, 107, nil, nil, 237, nil, nil, nil, + nil, nil, nil, 46, nil, nil, 109, 108, 110, 99, + 57, 101, 100, 102, 292, 103, 111, 112, nil, 95, + 96, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, 236, nil, nil, 59, + 60, nil, nil, 61, nil, 640, nil, 287, nil, 45, + nil, nil, 293, nil, nil, nil, nil, nil, 235, nil, + nil, nil, nil, 93, 290, 86, 87, nil, 88, 90, + 89, 91, nil, nil, nil, nil, 84, 92, nil, nil, + nil, 75, 76, 72, 63, 58, 85, 97, 98, 64, + 65, nil, nil, nil, 68, nil, 66, 67, 69, 317, + 318, 73, 74, nil, nil, nil, nil, nil, 77, 314, + 320, 105, 104, 106, 107, nil, nil, 237, nil, nil, + nil, nil, nil, nil, 46, nil, nil, 109, 108, 110, + 99, 57, 101, 100, 102, 292, 103, 111, 112, nil, + 95, 96, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 230, nil, nil, 236, nil, nil, + 59, 60, nil, nil, 61, nil, nil, nil, 287, nil, + 45, nil, nil, 293, nil, nil, nil, nil, nil, 235, + nil, nil, nil, nil, 93, 290, 86, 87, nil, 88, + 90, 89, 91, nil, nil, nil, nil, 84, 92, nil, + nil, nil, 75, 76, 72, 63, 58, 85, 97, 98, + 64, 65, nil, nil, nil, 68, nil, 66, 67, 69, + 30, 31, 73, 74, nil, nil, nil, nil, nil, 77, + 28, 27, 105, 104, 106, 107, nil, nil, 237, nil, + nil, nil, nil, nil, nil, 46, nil, nil, 109, 108, + 110, 99, 57, 101, 100, 102, nil, 103, 111, 112, + nil, 95, 96, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 230, nil, nil, 236, nil, + nil, 59, 60, nil, nil, 61, nil, nil, nil, nil, + nil, 45, nil, nil, nil, nil, nil, nil, nil, nil, + 235, nil, nil, nil, nil, 93, 83, 86, 87, nil, + 88, 90, 89, 91, nil, nil, nil, nil, 84, 92, + nil, nil, nil, 75, 76, 72, 63, 58, 85, 97, + 98, 64, 65, nil, nil, nil, 68, nil, 66, 67, + 69, 30, 31, 73, 74, nil, nil, nil, nil, nil, + 77, 28, 27, 105, 104, 106, 107, nil, nil, 237, + nil, nil, nil, nil, nil, nil, 46, nil, nil, 109, + 108, 110, 99, 57, 101, 100, 102, nil, 103, 111, + 112, nil, 95, 96, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 230, nil, nil, 236, + nil, nil, 59, 60, nil, nil, 61, nil, nil, nil, + nil, nil, 45, nil, nil, nil, nil, nil, nil, nil, + nil, 235, nil, nil, nil, nil, 93, 83, 86, 87, + nil, 88, 90, 89, 91, nil, nil, nil, nil, 84, + 92, nil, nil, nil, 75, 76, 72, 63, 58, 85, + 97, 98, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 30, 31, 73, 74, nil, nil, nil, nil, + nil, 77, 28, 27, 105, 104, 106, 107, nil, nil, + 237, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 109, 108, 110, 99, 57, 101, 100, 102, nil, 103, + 111, 112, nil, 95, 96, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + 236, nil, nil, 59, 60, nil, nil, 61, nil, nil, + nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, + nil, nil, 235, nil, nil, nil, nil, 93, 83, 86, + 87, nil, 88, 90, 89, 91, nil, nil, nil, nil, + 84, 92, nil, nil, nil, 75, 76, 72, 63, 58, + 85, 97, 98, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 77, 28, 27, 105, 104, 106, 107, nil, + nil, 237, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, 236, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 235, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, 75, 76, 72, 63, + 58, 85, 97, 98, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 317, 318, 73, 74, nil, nil, + nil, nil, nil, 77, 314, 320, 105, 104, 106, 107, + nil, nil, 237, nil, nil, nil, nil, nil, nil, 46, + nil, nil, 109, 108, 110, 99, 57, 101, 100, 102, + nil, 103, 111, 112, nil, 95, 96, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, 236, nil, nil, 59, 60, nil, nil, 61, + nil, nil, nil, nil, nil, 45, nil, nil, nil, nil, + nil, nil, nil, nil, 235, nil, nil, nil, nil, 93, + 83, 86, 87, nil, 88, 90, 89, 91, nil, nil, + nil, nil, 84, 92, nil, nil, nil, 75, 76, 72, + 63, 58, 85, 97, 98, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 317, 318, 73, 74, nil, + nil, nil, nil, nil, 77, 314, 320, 105, 104, 106, + 107, nil, nil, 237, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 109, 108, 110, 99, 57, 101, 100, + 102, nil, 103, 111, 112, nil, 95, 96, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, 236, nil, nil, 59, 60, nil, nil, + 61, nil, nil, nil, nil, nil, 45, nil, nil, nil, + nil, nil, nil, nil, nil, 235, nil, nil, nil, nil, + 93, 83, 86, 87, nil, 88, 90, 89, 91, nil, + nil, nil, nil, 84, 92, nil, nil, nil, 75, 76, + 72, 63, 58, 85, 97, 98, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 317, 318, 73, 74, + nil, nil, nil, nil, nil, 77, 314, 320, 105, 104, + 106, 107, nil, nil, 237, nil, nil, nil, nil, nil, + nil, 315, nil, nil, 109, 108, 110, 99, 57, 101, + 100, 102, nil, 103, 111, 112, nil, 95, 96, nil, + nil, 321, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 311, nil, nil, 307, nil, nil, 59, 60, nil, + nil, 61, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 93, 83, 86, 87, nil, 88, 90, 89, 91, + nil, nil, nil, nil, 84, 92, nil, nil, nil, 75, + 76, 72, 63, 58, 85, 97, 98, 64, 65, nil, + nil, nil, 68, nil, 66, 67, 69, 317, 318, 73, + 74, nil, nil, nil, nil, nil, 77, 314, 320, 105, + 104, 106, 107, nil, nil, 237, nil, nil, nil, nil, + nil, nil, 315, nil, nil, 109, 108, 110, 99, 57, + 101, 100, 102, nil, 103, 111, 112, nil, 95, 96, + nil, nil, 321, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 311, nil, nil, 307, nil, nil, 59, 60, + nil, nil, 61, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 93, 83, 86, 87, nil, 88, 90, 89, + 91, nil, nil, nil, nil, 84, 92, nil, nil, nil, + 75, 76, 72, 63, 58, 85, 97, 98, 64, 65, + nil, nil, nil, 68, nil, 66, 67, 69, 317, 318, + 73, 74, nil, nil, nil, nil, nil, 77, 314, 320, + 105, 104, 106, 107, nil, nil, 237, nil, nil, nil, + nil, nil, nil, 46, nil, nil, 109, 108, 110, 99, + 57, 101, 100, 102, nil, 103, 111, 112, nil, 95, + 96, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, 236, nil, nil, 59, + 60, nil, nil, 61, nil, 413, nil, nil, nil, 45, + nil, nil, nil, nil, nil, nil, nil, nil, 235, nil, + nil, nil, nil, 93, 83, 86, 87, nil, 88, 90, + 89, 91, nil, nil, nil, nil, 84, 92, nil, nil, + nil, 75, 76, 72, 63, 58, 85, 97, 98, 64, + 65, nil, nil, nil, 68, nil, 66, 67, 69, 317, + 318, 73, 74, nil, nil, nil, nil, nil, 77, 314, + 320, 105, 104, 106, 107, nil, nil, 237, nil, nil, + nil, nil, nil, nil, 46, nil, nil, 109, 108, 110, + 99, 57, 101, 100, 102, nil, 103, 111, 112, nil, + 95, 96, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 230, nil, nil, 236, nil, nil, + 59, 60, nil, nil, 61, nil, nil, nil, nil, nil, + 45, nil, nil, nil, nil, nil, nil, nil, nil, 235, + nil, nil, nil, nil, 93, 83, 86, 87, nil, 88, + 90, 89, 91, nil, nil, nil, nil, 84, 92, nil, + nil, nil, 75, 76, 72, 63, 58, 85, 97, 98, + 64, 65, nil, nil, nil, 68, nil, 66, 67, 69, + 30, 31, 73, 74, nil, nil, nil, nil, nil, 77, + 28, 27, 105, 104, 106, 107, nil, nil, 19, nil, + nil, nil, nil, nil, nil, 46, nil, nil, 109, 108, + 110, 99, 57, 101, 100, 102, nil, 103, 111, 112, + nil, 95, 96, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 230, nil, nil, 236, nil, + nil, 59, 60, nil, nil, 61, nil, nil, nil, nil, + nil, 45, nil, nil, nil, nil, nil, nil, nil, nil, + 20, nil, nil, nil, nil, 93, 83, 86, 87, nil, + 88, 90, 89, 91, nil, nil, nil, nil, 84, 92, + nil, nil, nil, 75, 76, 72, 63, 58, 85, 97, + 98, 64, 65, nil, nil, nil, 68, nil, 66, 67, + 69, 317, 318, 73, 74, nil, nil, nil, nil, nil, + 77, 314, 320, 105, 104, 106, 107, nil, nil, 237, + nil, nil, nil, nil, nil, nil, 46, nil, nil, 109, + 108, 110, 99, 57, 101, 100, 102, nil, 103, 111, + 112, nil, 95, 96, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 230, nil, nil, 236, + nil, nil, 59, 60, nil, nil, 61, nil, nil, nil, + nil, nil, 45, nil, nil, nil, nil, nil, nil, nil, + nil, 235, nil, nil, nil, nil, 93, 83, 86, 87, + nil, 88, 90, 89, 91, nil, nil, nil, nil, 84, + 92, nil, nil, nil, 75, 76, 72, 63, 58, 85, + 97, 98, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 30, 31, 73, 74, nil, nil, nil, nil, + nil, 77, 28, 27, 105, 104, 106, 107, nil, nil, + 237, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 109, 108, 110, 99, 57, 101, 100, 102, nil, 103, + 111, 112, nil, 95, 96, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + 236, nil, nil, 59, 60, nil, nil, 61, nil, nil, + nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, + nil, nil, 235, nil, nil, nil, nil, 93, 83, 86, + 87, nil, 88, 90, 89, 91, nil, nil, nil, nil, + 84, 92, nil, nil, nil, 75, 76, 72, 63, 58, + 85, 97, 98, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 317, 318, 73, 74, nil, nil, nil, + nil, nil, 77, 314, 320, 105, 104, 106, 107, nil, + nil, 237, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 230, nil, + nil, 236, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 235, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, 75, 76, 72, 63, + 58, 85, 97, 98, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 317, 318, 73, 74, nil, nil, + nil, nil, nil, 77, 314, 320, 105, 104, 106, 107, + nil, nil, 237, nil, nil, nil, nil, nil, nil, 46, + nil, nil, 109, 108, 110, 99, 57, 101, 100, 102, + nil, 103, 111, 112, nil, 95, 96, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, 236, nil, nil, 59, 60, nil, nil, 61, + nil, nil, nil, nil, nil, 45, nil, nil, nil, nil, + nil, nil, nil, nil, 235, nil, nil, nil, nil, 93, + 83, 86, 87, nil, 88, 90, 89, 91, nil, nil, + nil, nil, 84, 92, nil, nil, nil, 75, 76, 72, + 63, 58, 85, 97, 98, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 317, 318, 73, 74, nil, + nil, nil, nil, nil, 77, 314, 320, 105, 104, 106, + 107, nil, nil, 237, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 109, 108, 110, 99, 57, 101, 100, + 102, nil, 103, 111, 112, nil, 95, 96, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 230, nil, nil, 236, nil, nil, 59, 60, nil, nil, + 61, nil, nil, nil, nil, nil, 45, nil, nil, nil, + nil, nil, nil, nil, nil, 235, nil, nil, nil, nil, + 93, 83, 86, 87, nil, 88, 90, 89, 91, nil, + nil, nil, nil, 84, 92, nil, nil, nil, 75, 76, + 72, 63, 58, 85, 97, 98, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 317, 318, 73, 74, + nil, nil, nil, nil, nil, 77, 314, 320, 105, 104, + 106, 107, nil, nil, 237, nil, nil, nil, nil, nil, + nil, 46, nil, nil, 109, 108, 110, 99, 57, 101, + 100, 102, nil, 103, 111, 112, nil, 95, 96, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, 236, nil, nil, 59, 60, nil, + nil, 61, nil, nil, nil, nil, nil, 45, nil, nil, + nil, nil, nil, nil, nil, nil, 235, nil, nil, nil, + nil, 93, 83, 86, 87, nil, 88, 90, 89, 91, + nil, nil, nil, nil, 84, 92, nil, nil, nil, 75, + 76, 72, 63, 58, 85, 97, 98, 64, 65, nil, + nil, nil, 68, nil, 66, 67, 69, 317, 318, 73, + 74, nil, nil, nil, nil, nil, 77, 314, 320, 105, + 104, 106, 107, nil, nil, 237, nil, nil, nil, nil, + nil, nil, 46, nil, nil, 109, 108, 110, 99, 57, + 101, 100, 102, nil, 103, 111, 112, nil, 95, 96, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 230, nil, nil, 236, nil, nil, 59, 60, + nil, nil, 61, nil, nil, nil, nil, nil, 45, nil, + nil, nil, nil, nil, nil, nil, nil, 235, nil, nil, + nil, nil, 93, 83, 86, 87, nil, 88, 90, 89, + 91, nil, nil, nil, nil, 84, 92, nil, nil, nil, + 75, 76, 72, 63, 58, 85, 97, 98, 64, 65, + nil, nil, nil, 68, nil, 66, 67, 69, 317, 318, + 73, 74, nil, nil, nil, nil, nil, 77, 314, 320, + 105, 104, 106, 107, nil, nil, 237, nil, nil, nil, + nil, nil, nil, 46, nil, nil, 109, 108, 110, 99, + 57, 101, 100, 102, nil, 103, 111, 112, nil, 95, + 96, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 230, nil, nil, 236, nil, nil, 59, + 60, nil, nil, 61, nil, nil, nil, nil, nil, 45, + nil, nil, nil, nil, nil, nil, nil, nil, 235, nil, + nil, nil, nil, 93, 83, 86, 87, nil, 88, 90, + 89, 91, nil, nil, nil, nil, 84, 92, nil, nil, + nil, 75, 76, 72, 63, 58, 85, 97, 98, 64, + 65, nil, nil, nil, 68, nil, 66, 67, 69, 30, + 31, 73, 74, nil, nil, nil, nil, nil, 77, 28, + 27, 105, 104, 106, 107, nil, nil, 19, nil, nil, + nil, nil, nil, nil, 46, nil, nil, 109, 108, 110, + 99, 57, 101, 100, 102, nil, 103, 111, 112, nil, + 95, 96, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 230, nil, nil, 236, nil, nil, + 59, 60, nil, nil, 61, nil, nil, nil, nil, nil, + 45, nil, nil, nil, nil, nil, nil, nil, nil, 20, + nil, nil, nil, nil, 93, 83, 86, 87, nil, 88, + 90, 89, 91, nil, nil, nil, nil, 84, 92, nil, + nil, nil, 75, 76, 72, 63, 58, 85, 97, 98, + 64, 65, nil, nil, nil, 68, nil, 66, 67, 69, + 317, 318, 73, 74, nil, nil, nil, nil, nil, 77, + 314, 320, 105, 104, 106, 107, nil, nil, 237, nil, + nil, nil, nil, nil, nil, 46, nil, nil, 109, 108, + 110, 99, 57, 101, 100, 102, nil, 103, 111, 112, + nil, 95, 96, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 230, nil, nil, 236, nil, + nil, 59, 60, nil, nil, 61, nil, 640, nil, nil, + nil, 45, nil, nil, nil, nil, nil, nil, nil, nil, + 235, nil, nil, nil, nil, 93, 83, 86, 87, nil, + 88, 90, 89, 91, nil, nil, nil, nil, 84, 92, + nil, nil, nil, 75, 76, 72, 63, 58, 85, 97, + 98, 64, 65, nil, nil, nil, 68, nil, 66, 67, + 69, 317, 318, 73, 74, nil, nil, nil, nil, nil, + 77, 314, 320, 105, 104, 106, 107, nil, nil, 237, + nil, nil, nil, nil, nil, nil, 46, nil, nil, 109, + 108, 110, 99, 57, 101, 100, 102, 292, 103, 111, + 112, nil, 95, 96, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 230, nil, nil, 236, + nil, nil, 59, 60, nil, nil, 61, nil, nil, nil, + 287, nil, 45, nil, nil, 293, nil, nil, nil, nil, + nil, 235, nil, nil, nil, nil, 93, 290, 86, 87, + nil, 88, 90, 89, 91, nil, nil, nil, nil, 84, + 92, nil, nil, nil, 75, 76, 72, 63, 58, 85, + 97, 98, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 317, 318, 73, 74, nil, nil, nil, nil, + nil, 77, 314, 320, 105, 104, 106, 107, nil, nil, + 237, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 109, 108, 110, 99, 57, 101, 100, 102, nil, 103, + 111, 112, nil, 95, 96, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 230, nil, nil, + 236, nil, nil, 59, 60, nil, nil, 61, nil, nil, + nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, + nil, nil, 235, nil, nil, nil, nil, 93, 83, 86, + 87, nil, 88, 90, 89, 91, nil, nil, nil, nil, + 84, 92, nil, nil, nil, 75, 76, 72, 63, 58, + 85, 97, 98, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 317, 318, 73, 74, nil, nil, nil, + nil, nil, 77, 314, 320, 105, 104, 106, 107, nil, + nil, 237, nil, nil, nil, nil, nil, nil, 315, nil, + nil, 109, 108, 110, 99, 57, 101, 100, 102, nil, + 103, 111, 112, nil, 95, 96, nil, nil, 321, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 921, nil, + nil, 236, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 93, 83, + 86, 87, nil, 88, 90, 89, 91, nil, nil, nil, + nil, 84, 92, nil, nil, nil, 75, 76, 72, 63, + 58, 85, 97, 98, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 317, 318, 73, 74, nil, nil, + nil, nil, nil, 77, 314, 320, 105, 104, 106, 107, + nil, nil, 237, nil, nil, nil, nil, nil, nil, 315, + nil, nil, 109, 108, 110, 99, 57, 101, 100, 102, + nil, 103, 111, 112, nil, 95, 96, nil, nil, 321, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 927, + nil, nil, 236, nil, nil, 59, 60, nil, nil, 61, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 93, + 83, 86, 87, nil, 88, 90, 89, 91, nil, nil, + nil, nil, 84, 92, nil, nil, nil, 75, 76, 72, + 63, 58, 85, 97, 98, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 317, 318, 73, 74, nil, + nil, nil, nil, nil, 77, 314, 320, 105, 104, 106, + 107, nil, nil, 237, nil, nil, nil, nil, nil, nil, + 315, nil, nil, 109, 108, 110, 99, 57, 101, 100, + 102, nil, 103, 111, 112, nil, 95, 96, nil, nil, + 321, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 921, nil, nil, 236, nil, nil, 59, 60, nil, nil, + 61, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 93, 83, 86, 87, nil, 88, 90, 89, 91, nil, + nil, nil, nil, 84, 92, nil, nil, nil, 75, 76, + 72, 63, 58, 85, 97, 98, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 30, 31, 73, 74, + nil, nil, nil, nil, nil, 77, 28, 27, 105, 104, + 106, 107, nil, nil, 237, nil, nil, nil, nil, nil, + nil, 46, nil, nil, 109, 108, 110, 99, 57, 101, + 100, 102, 292, 103, 111, 112, nil, 95, 96, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, 236, nil, nil, 59, 60, nil, + nil, 61, nil, 289, nil, 287, nil, 45, nil, nil, + 293, nil, nil, nil, nil, nil, 235, nil, nil, nil, + nil, 93, 290, 86, 87, nil, 88, 90, 89, 91, + nil, nil, nil, nil, 84, 92, nil, nil, nil, nil, + nil, nil, 63, nil, 85, 97, 98, 178, 189, 179, + 202, 175, 195, 185, 184, 205, 206, 200, 183, 182, + 177, 203, 207, 208, 187, 176, 190, 194, 196, 188, + 181, nil, nil, nil, 197, 204, 199, 198, 191, 201, + 186, 174, 193, 192, nil, nil, nil, nil, nil, 173, + 180, 171, 172, 168, 169, 170, 129, 131, 128, nil, + 130, nil, nil, nil, nil, nil, nil, nil, 162, 163, + nil, 159, 141, 142, 143, 150, 147, 149, nil, nil, + 144, 145, nil, nil, nil, 164, 165, 151, 152, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 156, 155, nil, 140, 161, 158, 157, 166, + 153, 154, 148, 146, 138, 160, 139, nil, nil, 167, + 93, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 92, 178, 189, 179, 202, 175, + 195, 185, 184, 205, 206, 200, 183, 182, 177, 203, + 207, 208, 187, 176, 190, 194, 196, 188, 181, nil, + nil, nil, 197, 204, 199, 198, 191, 201, 186, 174, + 193, 192, nil, nil, nil, nil, nil, 173, 180, 171, + 172, 168, 169, 170, 129, 131, nil, nil, 130, nil, + nil, nil, nil, nil, nil, nil, 162, 163, nil, 159, + 141, 142, 143, 150, 147, 149, nil, nil, 144, 145, + nil, nil, nil, 164, 165, 151, 152, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 156, 155, nil, 140, 161, 158, 157, 166, 153, 154, + 148, 146, 138, 160, 139, nil, nil, 167, 93, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 92, 178, 189, 179, 202, 175, 195, 185, + 184, 205, 206, 200, 183, 182, 177, 203, 207, 208, + 187, 176, 190, 194, 196, 188, 181, nil, nil, nil, + 197, 204, 199, 198, 191, 201, 186, 174, 193, 192, + nil, nil, nil, nil, nil, 173, 180, 171, 172, 168, + 169, 170, 129, 131, nil, nil, 130, nil, nil, nil, + nil, nil, nil, nil, 162, 163, nil, 159, 141, 142, + 143, 150, 147, 149, nil, nil, 144, 145, nil, nil, + nil, 164, 165, 151, 152, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 156, 155, + nil, 140, 161, 158, 157, 166, 153, 154, 148, 146, + 138, 160, 139, nil, nil, 167, 93, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 92, 178, 189, 179, 202, 175, 195, 185, 184, 205, + 206, 200, 183, 182, 177, 203, 207, 208, 187, 176, + 190, 194, 196, 188, 181, nil, nil, nil, 197, 204, + 199, 198, 191, 201, 186, 174, 193, 192, nil, nil, + nil, nil, nil, 173, 180, 171, 172, 168, 169, 170, + 129, 131, nil, nil, 130, nil, nil, nil, nil, nil, + nil, nil, 162, 163, nil, 159, 141, 142, 143, 150, + 147, 149, nil, nil, 144, 145, nil, nil, nil, 164, + 165, 151, 152, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 156, 155, nil, 140, + 161, 158, 157, 166, 153, 154, 148, 146, 138, 160, + 139, nil, nil, 167, 93, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 92, 178, + 189, 179, 202, 175, 195, 185, 184, 205, 206, 200, + 183, 182, 177, 203, 207, 208, 187, 176, 190, 194, + 196, 188, 181, nil, nil, nil, 197, 204, 199, 380, + 379, 381, 378, 174, 193, 192, nil, nil, nil, nil, + nil, 173, 180, 171, 172, 375, 376, 377, 373, 131, + 101, 100, 374, nil, 103, nil, nil, nil, nil, nil, + 162, 163, nil, 159, 141, 142, 143, 150, 147, 149, + nil, nil, 144, 145, nil, nil, nil, 164, 165, 151, + 152, nil, nil, nil, nil, nil, 385, nil, nil, nil, + nil, nil, nil, nil, 156, 155, nil, 140, 161, 158, + 157, 166, 153, 154, 148, 146, 138, 160, 139, nil, + nil, 167, 178, 189, 179, 202, 175, 195, 185, 184, + 205, 206, 200, 183, 182, 177, 203, 207, 208, 187, + 176, 190, 194, 196, 188, 181, nil, nil, nil, 197, + 204, 199, 198, 191, 201, 186, 174, 193, 192, nil, + nil, nil, nil, nil, 173, 180, 171, 172, 168, 169, + 170, 129, 131, nil, nil, 130, nil, nil, nil, nil, + nil, nil, nil, 162, 163, nil, 159, 141, 142, 143, + 150, 147, 149, nil, nil, 144, 145, nil, nil, nil, + 164, 165, 151, 152, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 156, 155, nil, + 140, 161, 158, 157, 166, 153, 154, 148, 146, 138, + 160, 139, 435, 439, 167, nil, 436, nil, nil, nil, + nil, nil, nil, nil, 162, 163, nil, 159, 141, 142, + 143, 150, 147, 149, nil, nil, 144, 145, nil, nil, + nil, 164, 165, 151, 152, nil, nil, nil, nil, nil, + 271, nil, nil, nil, nil, nil, nil, nil, 156, 155, + nil, 140, 161, 158, 157, 166, 153, 154, 148, 146, + 138, 160, 139, 442, 446, 167, nil, 441, nil, nil, + nil, nil, nil, nil, nil, 162, 163, nil, 159, 141, + 142, 143, 150, 147, 149, nil, nil, 144, 145, nil, + nil, nil, 164, 165, 151, 152, nil, nil, nil, nil, + nil, 271, nil, nil, nil, nil, nil, nil, nil, 156, + 155, nil, 140, 161, 158, 157, 166, 153, 154, 148, + 146, 138, 160, 139, 486, 439, 167, nil, 487, nil, + nil, nil, nil, nil, nil, nil, 162, 163, nil, 159, + 141, 142, 143, 150, 147, 149, nil, nil, 144, 145, + nil, nil, nil, 164, 165, 151, 152, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 156, 155, nil, 140, 161, 158, 157, 166, 153, 154, + 148, 146, 138, 160, 139, 621, 439, 167, nil, 622, + nil, nil, nil, nil, nil, nil, nil, 162, 163, nil, + 159, 141, 142, 143, 150, 147, 149, nil, nil, 144, + 145, nil, nil, nil, 164, 165, 151, 152, nil, nil, + nil, nil, nil, 271, nil, nil, nil, nil, nil, nil, + nil, 156, 155, nil, 140, 161, 158, 157, 166, 153, + 154, 148, 146, 138, 160, 139, 623, 446, 167, nil, + 624, nil, nil, nil, nil, nil, nil, nil, 162, 163, + nil, 159, 141, 142, 143, 150, 147, 149, nil, nil, + 144, 145, nil, nil, nil, 164, 165, 151, 152, nil, + nil, nil, nil, nil, 271, nil, nil, nil, nil, nil, + nil, nil, 156, 155, nil, 140, 161, 158, 157, 166, + 153, 154, 148, 146, 138, 160, 139, 650, 439, 167, + nil, 651, nil, nil, nil, nil, nil, nil, nil, 162, + 163, nil, 159, 141, 142, 143, 150, 147, 149, nil, + nil, 144, 145, nil, nil, nil, 164, 165, 151, 152, + nil, nil, nil, nil, nil, 271, nil, nil, nil, nil, + nil, nil, nil, 156, 155, nil, 140, 161, 158, 157, + 166, 153, 154, 148, 146, 138, 160, 139, 653, 446, + 167, nil, 654, nil, nil, nil, nil, nil, nil, nil, + 162, 163, nil, 159, 141, 142, 143, 150, 147, 149, + nil, nil, 144, 145, nil, nil, nil, 164, 165, 151, + 152, nil, nil, nil, nil, nil, 271, nil, nil, nil, + nil, nil, nil, nil, 156, 155, nil, 140, 161, 158, + 157, 166, 153, 154, 148, 146, 138, 160, 139, 621, + 439, 167, nil, 622, nil, nil, nil, nil, nil, nil, + nil, 162, 163, nil, 159, 141, 142, 143, 150, 147, + 149, nil, nil, 144, 145, nil, nil, nil, 164, 165, + 151, 152, nil, nil, nil, nil, nil, 271, nil, nil, + nil, nil, nil, nil, nil, 156, 155, nil, 140, 161, + 158, 157, 166, 153, 154, 148, 146, 138, 160, 139, + 623, 446, 167, nil, 624, nil, nil, nil, nil, nil, + nil, nil, 162, 163, nil, 159, 141, 142, 143, 150, + 147, 149, nil, nil, 144, 145, nil, nil, nil, 164, + 165, 151, 152, nil, nil, nil, nil, nil, 271, nil, + nil, nil, nil, nil, nil, nil, 156, 155, nil, 140, + 161, 158, 157, 166, 153, 154, 148, 146, 138, 160, + 139, 712, 439, 167, nil, 713, nil, nil, nil, nil, + nil, nil, nil, 162, 163, nil, 159, 141, 142, 143, + 150, 147, 149, nil, nil, 144, 145, nil, nil, nil, + 164, 165, 151, 152, nil, nil, nil, nil, nil, 271, + nil, nil, nil, nil, nil, nil, nil, 156, 155, nil, + 140, 161, 158, 157, 166, 153, 154, 148, 146, 138, + 160, 139, 714, 446, 167, nil, 715, nil, nil, nil, + nil, nil, nil, nil, 162, 163, nil, 159, 141, 142, + 143, 150, 147, 149, nil, nil, 144, 145, nil, nil, + nil, 164, 165, 151, 152, nil, nil, nil, nil, nil, + 271, nil, nil, nil, nil, nil, nil, nil, 156, 155, + nil, 140, 161, 158, 157, 166, 153, 154, 148, 146, + 138, 160, 139, 717, 446, 167, nil, 718, nil, nil, + nil, nil, nil, nil, nil, 162, 163, nil, 159, 141, + 142, 143, 150, 147, 149, nil, nil, 144, 145, nil, + nil, nil, 164, 165, 151, 152, nil, nil, nil, nil, + nil, 271, nil, nil, nil, nil, nil, nil, nil, 156, + 155, nil, 140, 161, 158, 157, 166, 153, 154, 148, + 146, 138, 160, 139, 486, 439, 167, nil, 487, nil, + nil, nil, nil, nil, nil, nil, 162, 163, nil, 159, + 141, 142, 143, 150, 147, 149, nil, nil, 144, 145, + nil, nil, nil, 164, 165, 151, 152, nil, nil, nil, + nil, nil, 271, nil, nil, nil, nil, nil, nil, nil, + 156, 155, nil, 140, 161, 158, 157, 166, 153, 154, + 148, 146, 138, 160, 139, 746, 439, 167, nil, 747, + nil, nil, nil, nil, nil, nil, nil, 162, 163, nil, + 159, 141, 142, 143, 150, 147, 149, nil, nil, 144, + 145, nil, nil, nil, 164, 165, 151, 152, nil, nil, + nil, nil, nil, 271, nil, nil, nil, nil, nil, nil, + nil, 156, 155, nil, 140, 161, 158, 157, 166, 153, + 154, 148, 146, 138, 160, 139, 749, 446, 167, nil, + 748, nil, nil, nil, nil, nil, nil, nil, 162, 163, + nil, 159, 141, 142, 143, 150, 147, 149, nil, nil, + 144, 145, nil, nil, nil, 164, 165, 151, 152, nil, + nil, nil, nil, nil, 271, nil, nil, nil, nil, nil, + nil, nil, 156, 155, nil, 140, 161, 158, 157, 166, + 153, 154, 148, 146, 138, 160, 139, 1001, 446, 167, + nil, 1000, nil, nil, nil, nil, nil, nil, nil, 162, + 163, nil, 159, 141, 142, 143, 150, 147, 149, nil, + nil, 144, 145, nil, nil, nil, 164, 165, 151, 152, + nil, nil, nil, nil, nil, 271, nil, nil, nil, nil, + nil, nil, nil, 156, 155, nil, 140, 161, 158, 157, + 166, 153, 154, 148, 146, 138, 160, 139, 1004, 439, + 167, nil, 1005, nil, nil, nil, nil, nil, nil, nil, + 162, 163, nil, 159, 141, 142, 143, 150, 147, 149, + nil, nil, 144, 145, nil, nil, nil, 164, 165, 151, + 152, nil, nil, nil, nil, nil, 271, nil, nil, nil, + nil, nil, nil, nil, 156, 155, nil, 140, 161, 158, + 157, 166, 153, 154, 148, 146, 138, 160, 139, 1006, + 446, 167, nil, 1007, nil, nil, nil, nil, nil, nil, + nil, 162, 163, nil, 159, 141, 142, 143, 150, 147, + 149, nil, nil, 144, 145, nil, nil, nil, 164, 165, + 151, 152, nil, nil, nil, nil, nil, 271, nil, nil, + nil, nil, nil, nil, nil, 156, 155, nil, 140, 161, + 158, 157, 166, 153, 154, 148, 146, 138, 160, 139, + nil, 682, 167, 679, 678, 677, 687, 680, nil, 682, + nil, 679, 678, 677, 687, 680, 690, nil, nil, nil, + nil, nil, nil, nil, 690, nil, 682, nil, 679, 678, + 677, 687, 680, nil, nil, nil, nil, nil, 685, 668, + nil, 690, nil, nil, nil, nil, 685, 695, 694, 698, + 697, nil, nil, nil, 691, 695, 694, 698, 697, nil, + nil, nil, 691, 685, nil, 682, nil, 679, 678, 677, + 687, 680, 695, 694, 698, 697, nil, nil, nil, 691, + 690, nil, 682, nil, 679, 678, 677, 687, 680, nil, + 682, nil, 679, 678, 677, 687, 680, 690, nil, nil, + nil, nil, 685, nil, nil, 690, nil, nil, nil, nil, + nil, 695, 694, 698, 697, nil, nil, nil, 691, 685, + nil, nil, nil, nil, nil, nil, nil, 685, 695, 694, + 698, 697, nil, nil, nil, 691, 695, 694, 698, 697, + nil, nil, 682, 691, 679, 678, 677, 687, 680, nil, + 682, nil, 679, 678, 677, 687, 680, 690, nil, nil, + nil, nil, nil, nil, nil, 690, nil, 682, nil, 679, + 678, 677, 687, 680, nil, nil, nil, nil, nil, 685, + nil, nil, 690, nil, nil, nil, nil, 685, 695, 694, + 698, 697, nil, nil, nil, 691, 695, 694, 698, 697, + nil, nil, nil, 691, 685, nil, 682, nil, 679, 678, + 677, 687, 680, 695, 694, 698, 697, nil, nil, nil, + 691, 690, nil, 682, nil, 679, 678, 677, 687, 680, + 682, nil, 679, 678, 677, 687, 680, nil, 690, nil, + nil, nil, nil, 685, nil, 690, nil, 682, nil, 679, + 678, 677, 687, 680, 698, 697, nil, nil, nil, 691, + 685, nil, 690, nil, nil, nil, nil, 685, nil, 695, + 694, 698, 697, nil, nil, nil, 691, nil, 698, 697, + nil, nil, nil, 691, 685, nil, 682, nil, 679, 678, + 677, 687, 680, nil, nil, 698, 697, nil, nil, nil, + 691, 690, nil, 682, nil, 679, 678, 677, 687, 680, + 682, nil, 679, 678, 677, 687, 680, nil, 690, nil, + nil, nil, nil, 685, nil, 690, nil, nil, nil, nil, + nil, nil, nil, nil, 698, 697, nil, nil, nil, 691, + 685, nil, nil, nil, nil, nil, nil, 685, nil, nil, + nil, 698, 697, nil, nil, nil, 691, nil, 698, 697, + nil, nil, nil, 691 ] + +racc_action_check = [ + 99, 451, 451, 574, 574, 17, 354, 99, 99, 99, + 1, 346, 99, 99, 99, 24, 99, 26, 19, 392, + 44, 44, 24, 347, 99, 393, 99, 99, 99, 62, + 364, 630, 228, 7, 364, 355, 99, 99, 710, 99, + 99, 99, 99, 99, 867, 893, 924, 925, 928, 358, + 645, 560, 17, 896, 975, 896, 44, 44, 316, 19, + 645, 10, 17, 12, 712, 713, 99, 99, 99, 99, + 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, + 24, 26, 99, 99, 99, 392, 99, 99, 551, 228, + 99, 393, 797, 99, 99, 451, 99, 574, 99, 13, + 99, 15, 99, 99, 26, 99, 99, 99, 99, 99, + 1004, 99, 102, 99, 1005, 354, 62, 827, 630, 102, + 102, 102, 316, 1006, 102, 102, 102, 99, 102, 346, + 99, 99, 99, 99, 346, 99, 102, 99, 102, 102, + 102, 347, 99, 99, 355, 316, 347, 650, 102, 102, + 1007, 102, 102, 102, 102, 102, 710, 1024, 358, 710, + 560, 710, 867, 893, 924, 925, 928, 867, 893, 924, + 925, 928, 975, 712, 713, 714, 634, 975, 102, 102, + 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 551, 22, 102, 102, 102, 551, 102, 102, + 1006, 797, 102, 37, 651, 102, 102, 40, 102, 715, + 102, 634, 102, 650, 102, 102, 46, 102, 102, 102, + 102, 102, 441, 102, 113, 102, 827, 1007, 1004, 441, + 441, 441, 1005, 1004, 772, 441, 441, 1005, 441, 102, + 714, 1006, 102, 102, 102, 102, 1006, 102, 209, 102, + 660, 660, 229, 650, 102, 102, 650, 230, 441, 441, + 786, 441, 441, 441, 441, 441, 650, 232, 1007, 772, + 651, 373, 653, 1007, 715, 1024, 14, 14, 373, 814, + 1024, 814, 814, 814, 714, 814, 570, 570, 441, 441, + 441, 441, 441, 441, 441, 441, 441, 441, 441, 441, + 441, 441, 233, 231, 441, 441, 441, 374, 441, 229, + 651, 38, 441, 651, 374, 441, 41, 41, 715, 585, + 441, 237, 441, 651, 441, 441, 786, 441, 441, 441, + 441, 441, 375, 441, 442, 441, 373, 653, 653, 375, + 128, 442, 442, 442, 660, 128, 128, 442, 442, 441, + 442, 3, 441, 441, 270, 441, 3, 441, 38, 442, + 231, 814, 345, 345, 441, 441, 786, 362, 38, 786, + 442, 442, 374, 442, 442, 442, 442, 442, 653, 786, + 570, 653, 284, 585, 585, 570, 945, 387, 945, 945, + 945, 653, 945, 585, 41, 41, 285, 375, 587, 420, + 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, + 442, 442, 442, 442, 457, 288, 442, 442, 442, 362, + 442, 321, 321, 503, 442, 296, 362, 442, 351, 621, + 296, 362, 442, 351, 442, 362, 442, 442, 39, 442, + 442, 442, 442, 442, 622, 442, 442, 442, 388, 300, + 376, 387, 387, 387, 362, 389, 420, 376, 301, 363, + 390, 442, 587, 587, 442, 442, 623, 442, 945, 442, + 303, 457, 587, 623, 623, 623, 442, 442, 623, 623, + 623, 304, 623, 305, 362, 39, 621, 503, 503, 503, + 377, 623, 623, 623, 623, 39, 311, 377, 314, 321, + 321, 622, 623, 623, 503, 623, 623, 623, 623, 623, + 325, 363, 388, 388, 388, 376, 391, 315, 363, 389, + 389, 389, 394, 363, 390, 390, 390, 363, 337, 700, + 700, 337, 623, 623, 623, 623, 623, 623, 623, 623, + 623, 623, 623, 623, 623, 623, 363, 320, 623, 623, + 623, 322, 623, 623, 16, 377, 623, 325, 378, 623, + 623, 16, 623, 326, 623, 378, 623, 325, 623, 623, + 16, 623, 623, 623, 623, 623, 363, 623, 623, 623, + 391, 391, 391, 379, 47, 380, 394, 394, 394, 463, + 379, 47, 380, 623, 329, 435, 623, 623, 623, 623, + 47, 623, 746, 623, 624, 747, 769, 436, 623, 623, + 831, 624, 624, 624, 335, 831, 624, 624, 624, 16, + 624, 463, 339, 378, 340, 463, 463, 381, 383, 464, + 624, 624, 624, 338, 381, 383, 338, 342, 606, 840, + 624, 624, 435, 624, 624, 624, 624, 624, 379, 47, + 380, 227, 435, 308, 436, 802, 802, 352, 227, 746, + 308, 464, 747, 769, 436, 464, 464, 227, 353, 308, + 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, + 624, 624, 624, 624, 836, 606, 624, 624, 624, 836, + 624, 624, 381, 383, 624, 606, 840, 624, 624, 357, + 624, 359, 624, 368, 624, 341, 624, 624, 341, 624, + 624, 624, 624, 624, 748, 624, 227, 624, 308, 986, + 986, 748, 748, 748, 403, 409, 666, 748, 748, 666, + 748, 624, 471, 412, 624, 624, 624, 624, 414, 624, + 81, 624, 717, 417, 421, 431, 624, 624, 471, 471, + 748, 748, 81, 748, 748, 748, 748, 748, 964, 309, + 433, 964, 81, 310, 471, 434, 309, 443, 471, 471, + 310, 471, 471, 453, 465, 309, 466, 467, 468, 310, + 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, + 748, 748, 748, 748, 717, 312, 748, 748, 748, 490, + 748, 717, 312, 494, 748, 510, 717, 748, 511, 514, + 717, 312, 748, 516, 748, 521, 748, 748, 524, 748, + 748, 748, 748, 748, 309, 748, 749, 748, 310, 717, + 533, 534, 535, 749, 749, 749, 799, 536, 548, 749, + 749, 748, 749, 552, 748, 748, 799, 748, 327, 748, + 553, 749, 554, 555, 572, 327, 748, 748, 582, 717, + 312, 590, 749, 749, 327, 749, 749, 749, 749, 749, + 890, 356, 890, 890, 890, 592, 890, 598, 356, 799, + 799, 607, 612, 617, 799, 578, 578, 356, 625, 578, + 578, 578, 749, 749, 749, 749, 749, 749, 749, 749, + 749, 749, 749, 749, 749, 749, 626, 890, 749, 749, + 749, 366, 749, 327, 419, 627, 749, 629, 366, 749, + 633, 419, 635, 637, 749, 639, 749, 366, 749, 749, + 419, 749, 749, 749, 749, 749, 356, 749, 749, 749, + 778, 647, 778, 778, 778, 778, 778, 520, 6, 6, + 6, 6, 6, 749, 520, 778, 749, 749, 27, 749, + 649, 749, 652, 520, 655, 27, 27, 27, 749, 749, + 27, 27, 27, 656, 27, 659, 366, 778, 661, 419, + 670, 478, 671, 27, 27, 27, 778, 778, 778, 778, + 673, 674, 675, 778, 27, 27, 684, 27, 27, 27, + 27, 27, 946, 692, 946, 946, 946, 563, 946, 696, + 699, 702, 520, 478, 563, 708, 711, 478, 478, 778, + 478, 478, 720, 563, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 724, 946, + 27, 27, 27, 743, 745, 27, 754, 27, 27, 775, + 785, 27, 27, 789, 27, 792, 27, 793, 27, 798, + 27, 27, 813, 27, 27, 27, 27, 27, 28, 27, + 27, 27, 563, 815, 820, 28, 28, 28, 823, 828, + 28, 28, 28, 920, 28, 27, 830, 834, 27, 27, + 920, 27, 835, 27, 28, 28, 838, 839, 848, 920, + 27, 849, 851, 852, 28, 28, 853, 28, 28, 28, + 28, 28, 855, 856, 857, 654, 858, 718, 873, 874, + 878, 879, 654, 881, 718, 882, 884, 654, 887, 718, + 889, 654, 900, 718, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 920, 904, + 28, 28, 28, 917, 921, 28, 927, 28, 28, 947, + 954, 28, 28, 957, 28, 958, 28, 959, 28, 960, + 28, 28, 962, 28, 28, 28, 28, 28, 57, 28, + 654, 28, 718, 971, 976, 57, 57, 57, 977, 978, + 57, 57, 57, 926, 57, 28, 979, 980, 28, 28, + 926, 28, 981, 28, 57, 57, 57, 982, 984, 926, + 28, 987, 1000, 1001, 57, 57, 1003, 57, 57, 57, + 57, 57, 918, 968, 918, 918, 918, 1016, 918, 685, + 968, 685, 685, 685, 999, 685, 999, 999, 999, 968, + 999, 1019, 1020, 1021, 57, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 57, 57, 57, 57, 926, 907, + 57, 57, 57, 1022, 1025, 57, 685, 1026, 57, 907, + 1033, 57, 57, nil, 57, 685, 57, nil, 57, nil, + 57, 57, nil, 57, 57, 57, 57, 57, 968, 57, + nil, 57, 811, nil, 811, 811, 811, nil, 811, nil, + nil, nil, 907, 907, nil, 57, nil, 907, 57, 57, + 57, 57, nil, 57, 437, 57, nil, nil, nil, nil, + 57, 437, 437, 437, nil, nil, 437, 437, 437, 811, + 437, 888, nil, 888, 888, 888, nil, 888, 811, 437, + 437, 437, 983, nil, 983, 983, 983, nil, 983, nil, + 437, 437, nil, 437, 437, 437, 437, 437, 985, nil, + 985, 985, 985, 1015, 985, 1015, 1015, 1015, 888, 1015, + 299, 299, 299, 299, 299, nil, nil, 888, nil, 983, + 437, 437, 437, 437, 437, 437, 437, 437, 437, 437, + 437, 437, 437, 437, nil, 985, 437, 437, 437, nil, + 1015, 437, nil, 437, 437, nil, nil, 437, 437, nil, + 437, nil, 437, nil, 437, nil, 437, 437, nil, 437, + 437, 437, 437, 437, nil, 437, 437, 437, 807, nil, + 807, 807, 807, 807, 807, 334, 334, 334, 334, 334, + nil, 437, nil, 807, 437, 437, 446, 437, nil, 437, + nil, nil, nil, 446, 446, 446, 437, nil, 446, 446, + 446, nil, 446, 483, nil, 807, 508, 508, 508, 508, + 508, 446, 446, 446, 446, nil, 807, 807, nil, 483, + 483, 807, 446, 446, nil, 446, 446, 446, 446, 446, + nil, nil, nil, nil, nil, 483, nil, 483, nil, 483, + 483, nil, 483, 483, nil, nil, 483, nil, 483, nil, + nil, nil, 446, 446, 446, 446, 446, 446, 446, 446, + 446, 446, 446, 446, 446, 446, nil, nil, 446, 446, + 446, 479, nil, 446, nil, nil, 446, nil, nil, 446, + 446, nil, 446, nil, 446, nil, 446, nil, 446, 446, + nil, 446, 446, 446, 446, 446, nil, 446, 446, 446, + nil, nil, nil, 479, nil, nil, nil, 479, 479, nil, + 479, 479, nil, 446, nil, nil, 446, 446, 446, 446, + nil, 446, 447, 446, nil, nil, nil, nil, 446, 447, + 447, 447, nil, nil, 447, 447, 447, 530, 447, nil, + nil, nil, nil, nil, nil, nil, nil, 447, 447, 447, + 447, nil, nil, 530, 530, nil, nil, nil, 447, 447, + nil, 447, 447, 447, 447, 447, nil, nil, nil, 530, + nil, 530, nil, 530, 530, nil, 530, 530, nil, nil, + 530, nil, 530, nil, nil, nil, nil, nil, 447, 447, + 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, + 447, 447, nil, nil, 447, 447, 447, nil, nil, 447, + nil, nil, 447, nil, nil, 447, 447, nil, 447, nil, + 447, nil, 447, nil, 447, 447, nil, 447, 447, 447, + 447, 447, nil, 447, 447, 447, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 447, + nil, nil, 447, 447, 447, 447, nil, 447, 485, 447, + nil, nil, nil, nil, 447, 485, 485, 485, nil, nil, + 485, 485, 485, 469, 485, nil, nil, nil, nil, nil, + nil, nil, nil, 485, 485, nil, nil, nil, nil, 469, + 469, nil, nil, nil, 485, 485, nil, 485, 485, 485, + 485, 485, nil, nil, nil, 469, nil, 469, nil, 469, + 469, nil, 469, 469, nil, nil, nil, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, nil, 21, + 21, nil, nil, 21, 21, 485, nil, nil, nil, nil, + nil, nil, 485, nil, nil, nil, nil, 485, 485, 21, + nil, 21, nil, 21, 21, nil, 21, 21, 21, 21, + 21, nil, 21, nil, nil, nil, nil, nil, nil, nil, + 485, 485, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 21, nil, nil, 485, nil, nil, 485, nil, + nil, nil, nil, 485, 0, 0, 0, 0, 0, 0, + 485, nil, nil, 0, 0, nil, nil, nil, 0, nil, + 0, 0, 0, 0, 0, 0, 0, nil, nil, nil, + nil, nil, 0, 0, 0, 0, 0, 0, 0, nil, + nil, 0, nil, nil, nil, nil, 424, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, nil, + 0, 0, 0, nil, 0, 0, 0, 0, 0, 424, + 424, 424, 424, 424, 424, 424, 424, 424, 424, 424, + nil, 424, 424, nil, nil, 424, 424, nil, 0, nil, + nil, 0, nil, nil, 0, 0, nil, nil, 0, nil, + 0, 424, nil, 424, 0, 424, 424, nil, 424, 424, + 424, 424, 424, 0, 424, nil, nil, nil, 0, 0, + 0, 0, nil, 0, 0, 0, 0, nil, nil, nil, + nil, 0, 0, nil, 424, nil, 424, nil, nil, 0, + nil, 0, 0, 0, 33, 33, 33, 33, 33, 33, + nil, nil, nil, 33, 33, nil, nil, nil, 33, nil, + 33, 33, 33, 33, 33, 33, 33, nil, nil, nil, + nil, nil, 33, 33, 33, 33, 33, 33, 33, nil, + nil, 33, nil, nil, nil, nil, 430, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, nil, + 33, 33, 33, nil, 33, 33, 33, 33, 33, 430, + 430, 430, 430, 430, 430, 430, 430, 430, 430, 430, + nil, 430, 430, nil, nil, 430, 430, nil, 33, nil, + nil, 33, nil, nil, 33, 33, nil, nil, 33, nil, + 33, 430, nil, 430, 33, 430, 430, nil, 430, 430, + 430, 430, 430, 33, 430, nil, nil, nil, 33, 33, + 33, 33, nil, 33, 33, 33, 33, nil, nil, nil, + nil, 33, 33, nil, 430, nil, nil, nil, nil, 33, + nil, 33, 33, 33, 126, 126, 126, 126, 126, 126, + nil, nil, nil, 126, 126, nil, nil, nil, 126, nil, + 126, 126, 126, 126, 126, 126, 126, nil, nil, nil, + nil, nil, 126, 126, 126, 126, 126, 126, 126, nil, + nil, 126, nil, nil, nil, nil, nil, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, nil, + 126, 126, 126, nil, 126, 126, 126, 126, 126, 282, + 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, + nil, 282, 282, nil, nil, 282, 282, nil, 126, nil, + nil, 126, nil, nil, 126, 126, nil, nil, 126, nil, + 126, 282, nil, 282, 126, 282, 282, nil, 282, 282, + 282, 282, 282, 126, 282, nil, nil, nil, 126, 126, + 126, 126, nil, 126, 126, 126, 126, nil, nil, nil, + nil, 126, 126, nil, 282, nil, nil, nil, nil, 126, + nil, 126, 126, 126, 211, 211, 211, 211, 211, 211, + nil, nil, nil, 211, 211, nil, nil, nil, 211, nil, + 211, 211, 211, 211, 211, 211, 211, nil, nil, nil, + nil, nil, 211, 211, 211, 211, 211, 211, 211, nil, + nil, 211, nil, nil, nil, nil, nil, 211, 211, 211, + 211, 211, 211, 211, 211, 211, 211, 211, 211, nil, + 211, 211, 211, nil, 211, 211, 211, 211, 211, 482, + 482, 482, 482, 482, 482, 482, 482, 482, 482, 482, + nil, 482, 482, nil, nil, 482, 482, nil, 211, nil, + nil, 211, nil, nil, 211, 211, nil, nil, 211, nil, + 211, 482, nil, 482, 211, 482, 482, nil, 482, 482, + 482, 482, 482, 211, 482, nil, nil, nil, 211, 211, + 211, 211, nil, 211, 211, 211, 211, nil, nil, nil, + nil, 211, 211, 482, 482, nil, nil, nil, nil, 211, + nil, 211, 211, 211, 236, 236, 236, 236, 236, 236, + nil, nil, nil, 236, 236, nil, nil, nil, 236, nil, + 236, 236, 236, 236, 236, 236, 236, nil, nil, nil, + nil, nil, 236, 236, 236, 236, 236, 236, 236, nil, + nil, 236, nil, nil, nil, nil, nil, 236, 236, 236, + 236, 236, 236, 236, 236, 236, 236, 236, 236, nil, + 236, 236, 236, nil, 236, 236, 236, 236, 236, 531, + 531, 531, 531, 531, 531, 531, 531, 531, 531, 531, + nil, 531, 531, nil, nil, 531, 531, nil, 236, nil, + nil, 236, nil, nil, 236, 236, nil, nil, 236, nil, + 236, 531, nil, 531, 236, 531, 531, nil, 531, 531, + 531, 531, 531, 236, 531, nil, nil, nil, 236, 236, + 236, 236, nil, 236, 236, 236, 236, nil, nil, nil, + nil, 236, 236, nil, 531, nil, nil, nil, nil, 236, + nil, 236, 236, 236, 302, 302, 302, 302, 302, 302, + nil, nil, nil, 302, 302, nil, nil, nil, 302, nil, + 302, 302, 302, 302, 302, 302, 302, nil, nil, nil, + nil, nil, 302, 302, 302, 302, 302, 302, 302, nil, + nil, 302, nil, nil, nil, nil, nil, 302, 302, 302, + 302, 302, 302, 302, 302, 302, 302, 302, 302, nil, + 302, 302, 302, nil, 302, 302, 302, 302, 302, 751, + 751, 751, 751, 751, 751, 751, 751, 751, 751, 751, + nil, 751, 751, nil, nil, 751, 751, nil, 302, nil, + nil, 302, nil, nil, 302, 302, nil, nil, 302, nil, + 302, 751, nil, 751, 302, 751, 751, nil, 751, 751, + 751, 751, 751, 302, 751, nil, nil, nil, 302, 302, + 302, 302, nil, 302, 302, 302, 302, nil, nil, nil, + nil, 302, 302, nil, 751, nil, nil, nil, nil, 302, + nil, 302, 302, 302, 307, 307, 307, 307, 307, 307, + nil, nil, nil, 307, 307, nil, nil, nil, 307, nil, + 307, 307, 307, 307, 307, 307, 307, nil, nil, nil, + nil, nil, 307, 307, 307, 307, 307, 307, 307, nil, + nil, 307, nil, nil, nil, nil, nil, 307, 307, 307, + 307, 307, 307, 307, 307, 307, 307, 307, 307, nil, + 307, 307, 307, nil, 307, 307, 307, 307, 307, 845, + 845, 845, 845, 845, 845, 845, 845, 845, 845, 845, + nil, 845, 845, nil, nil, 845, 845, nil, 307, nil, + nil, 307, nil, nil, 307, 307, nil, nil, 307, nil, + 307, 845, nil, 845, 307, 845, 845, nil, 845, 845, + 845, 845, 845, 307, 845, nil, nil, nil, 307, 307, + 307, 307, nil, 307, 307, 307, 307, nil, nil, nil, + nil, 307, 307, nil, 845, nil, nil, nil, nil, 307, + nil, 307, 307, 307, 333, 333, 333, 333, 333, 333, + nil, nil, nil, 333, 333, nil, nil, nil, 333, nil, + 333, 333, 333, 333, 333, 333, 333, nil, nil, nil, + nil, nil, 333, 333, 333, 333, 333, 333, 333, nil, + nil, 333, nil, nil, nil, nil, nil, 333, 333, 333, + 333, 333, 333, 333, 333, 333, 333, 333, 333, nil, + 333, 333, 333, nil, 333, 333, 333, 333, 333, 461, + 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, + nil, 461, 461, nil, nil, 461, 461, nil, 333, nil, + nil, 333, nil, nil, 333, 333, nil, nil, 333, nil, + 333, 461, nil, 461, 333, 461, 461, nil, 461, 461, + 461, 461, 461, 333, 461, nil, nil, nil, 333, 333, + 333, 333, nil, 333, 333, 333, 333, nil, nil, nil, + nil, 333, 333, nil, nil, nil, nil, nil, nil, 333, + nil, 333, 333, 333, 349, 349, 349, 349, 349, 349, + nil, nil, nil, 349, 349, nil, nil, nil, 349, nil, + 349, 349, 349, 349, 349, 349, 349, nil, nil, nil, + nil, nil, 349, 349, 349, 349, 349, 349, 349, nil, + nil, 349, nil, nil, nil, nil, nil, 349, 349, 349, + 349, 349, 349, 349, 349, 349, 349, 349, 349, nil, + 349, 349, 349, nil, 349, 349, 349, 349, 349, 462, + 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, + nil, 462, 462, nil, nil, 462, 462, nil, 349, nil, + nil, 349, nil, nil, 349, 349, nil, nil, 349, nil, + 349, 462, nil, 462, 349, 462, 462, nil, 462, 462, + 462, 462, 462, 349, 462, nil, nil, nil, 349, 349, + 349, 349, nil, 349, 349, 349, 349, nil, nil, nil, + nil, 349, 349, nil, nil, nil, nil, nil, nil, 349, + nil, 349, 349, 349, 350, 350, 350, 350, 350, 350, + nil, nil, nil, 350, 350, nil, nil, nil, 350, nil, + 350, 350, 350, 350, 350, 350, 350, nil, nil, nil, + nil, nil, 350, 350, 350, 350, 350, 350, 350, nil, + nil, 350, nil, nil, nil, nil, nil, 350, 350, 350, + 350, 350, 350, 350, 350, 350, 350, 350, 350, nil, + 350, 350, 350, nil, 350, 350, 350, 350, 350, 472, + 472, 472, 472, 472, 472, 472, nil, nil, 472, 472, + nil, nil, nil, nil, nil, 472, 472, nil, 350, nil, + nil, 350, nil, nil, 350, 350, nil, nil, 350, nil, + 350, 472, nil, 472, 350, 472, 472, nil, 472, 472, + 472, 472, 472, 350, 472, nil, nil, nil, 350, 350, + 350, 350, nil, 350, 350, 350, 350, nil, nil, nil, + nil, 350, 350, nil, nil, nil, nil, nil, nil, 350, + nil, 350, 350, 350, 547, 547, 547, 547, 547, 547, + nil, nil, nil, 547, 547, nil, nil, nil, 547, nil, + 547, 547, 547, 547, 547, 547, 547, nil, nil, nil, + nil, nil, 547, 547, 547, 547, 547, 547, 547, nil, + nil, 547, nil, nil, nil, nil, nil, 547, 547, 547, + 547, 547, 547, 547, 547, 547, 547, 547, 547, nil, + 547, 547, 547, nil, 547, 547, 547, 547, 547, 473, + 473, 473, 473, 473, 473, 473, nil, nil, 473, 473, + nil, nil, nil, nil, nil, 473, 473, nil, 547, nil, + nil, 547, nil, nil, 547, 547, nil, nil, 547, nil, + 547, 473, nil, 473, 547, 473, 473, nil, 473, 473, + 473, 473, 473, 547, 473, nil, nil, nil, 547, 547, + 547, 547, nil, 547, 547, 547, 547, nil, nil, nil, + nil, 547, 547, nil, nil, nil, nil, nil, nil, 547, + nil, 547, 547, 547, 550, 550, 550, 550, 550, 550, + nil, nil, nil, 550, 550, nil, nil, nil, 550, nil, + 550, 550, 550, 550, 550, 550, 550, nil, nil, nil, + nil, nil, 550, 550, 550, 550, 550, 550, 550, nil, + nil, 550, nil, nil, nil, nil, nil, 550, 550, 550, + 550, 550, 550, 550, 550, 550, 550, 550, 550, nil, + 550, 550, 550, nil, 550, 550, 550, 550, 550, 474, + 474, 474, 474, 474, 474, 474, nil, nil, 474, 474, + nil, nil, nil, nil, nil, 474, 474, nil, 550, nil, + nil, 550, nil, nil, 550, 550, nil, nil, 550, nil, + 550, 474, nil, 474, 550, 474, 474, nil, 474, 474, + 474, 474, 474, 550, 474, nil, nil, nil, 550, 550, + 550, 550, nil, 550, 550, 550, 550, nil, nil, nil, + nil, 550, 550, nil, nil, nil, nil, nil, nil, 550, + nil, 550, 550, 550, 571, 571, 571, 571, 571, 571, + nil, nil, nil, 571, 571, nil, nil, nil, 571, nil, + 571, 571, 571, 571, 571, 571, 571, nil, nil, nil, + nil, nil, 571, 571, 571, 571, 571, 571, 571, nil, + nil, 571, nil, nil, nil, nil, nil, 571, 571, 571, + 571, 571, 571, 571, 571, 571, 571, 571, 571, nil, + 571, 571, 571, nil, 571, 571, 571, 571, 571, 475, + 475, 475, 475, 475, 475, 475, nil, nil, 475, 475, + nil, nil, nil, nil, nil, 475, 475, nil, 571, nil, + nil, 571, nil, nil, 571, 571, nil, nil, 571, nil, + 571, 475, nil, 475, 571, 475, 475, nil, 475, 475, + 475, 475, 475, 571, 475, nil, nil, nil, 571, 571, + 571, 571, nil, 571, 571, 571, 571, nil, nil, nil, + nil, 571, 571, nil, nil, nil, nil, nil, nil, 571, + nil, 571, 571, 571, 716, 716, 716, 716, 716, 716, + nil, nil, nil, 716, 716, nil, nil, nil, 716, nil, + 716, 716, 716, 716, 716, 716, 716, nil, nil, nil, + nil, nil, 716, 716, 716, 716, 716, 716, 716, nil, + nil, 716, nil, nil, nil, nil, nil, 716, 716, 716, + 716, 716, 716, 716, 716, 716, 716, 716, 716, nil, + 716, 716, 716, nil, 716, 716, 716, 716, 716, 476, + 476, 476, 476, 476, 476, 476, nil, nil, 476, 476, + nil, nil, nil, nil, nil, 476, 476, nil, 716, nil, + nil, 716, nil, nil, 716, 716, nil, nil, 716, nil, + 716, 476, nil, 476, 716, 476, 476, nil, 476, 476, + 476, 476, 476, 716, 476, nil, nil, nil, 716, 716, + 716, 716, nil, 716, 716, 716, 716, nil, nil, nil, + nil, 716, 716, nil, nil, nil, nil, nil, nil, 716, + nil, 716, 716, 716, 721, 721, 721, 721, 721, 721, + nil, nil, nil, 721, 721, nil, nil, nil, 721, nil, + 721, 721, 721, 721, 721, 721, 721, nil, nil, nil, + nil, nil, 721, 721, 721, 721, 721, 721, 721, nil, + nil, 721, nil, nil, nil, nil, nil, 721, 721, 721, + 721, 721, 721, 721, 721, 721, 721, 721, 721, nil, + 721, 721, 721, nil, 721, 721, 721, 721, 721, 477, + 477, 477, 477, 477, 477, 477, nil, nil, 477, 477, + nil, nil, nil, nil, nil, 477, 477, nil, 721, nil, + nil, 721, nil, nil, 721, 721, nil, nil, 721, nil, + 721, 477, nil, 477, 721, 477, 477, nil, 477, 477, + 477, 477, 477, 721, 477, nil, nil, nil, 721, 721, + 721, 721, nil, 721, 721, 721, 721, nil, nil, nil, + nil, 721, 721, nil, nil, nil, nil, nil, nil, 721, + nil, 721, 721, 721, 725, 725, 725, 725, 725, 725, + nil, nil, nil, 725, 725, nil, nil, nil, 725, nil, + 725, 725, 725, 725, 725, 725, 725, nil, nil, nil, + nil, nil, 725, 725, 725, 725, 725, 725, 725, nil, + nil, 725, nil, nil, nil, nil, nil, 725, 725, 725, + 725, 725, 725, 725, 725, 725, 725, 725, 725, nil, + 725, 725, 725, nil, 725, 725, 725, 725, 725, 480, + 480, 480, 480, 480, 480, 480, nil, nil, 480, 480, + nil, nil, nil, nil, nil, 480, 480, nil, 725, nil, + nil, 725, nil, nil, 725, 725, nil, nil, 725, nil, + 725, 480, nil, 480, 725, 480, 480, nil, 480, 480, + 480, 480, 480, 725, 480, nil, nil, nil, 725, 725, + 725, 725, nil, 725, 725, 725, 725, nil, nil, nil, + nil, 725, 725, nil, nil, nil, nil, nil, nil, 725, + nil, 725, 725, 725, 735, 735, 735, 735, 735, 735, + nil, nil, nil, 735, 735, nil, nil, nil, 735, nil, + 735, 735, 735, 735, 735, 735, 735, nil, nil, nil, + nil, nil, 735, 735, 735, 735, 735, 735, 735, nil, + nil, 735, nil, nil, nil, nil, nil, 735, 735, 735, + 735, 735, 735, 735, 735, 735, 735, 735, 735, nil, + 735, 735, 735, nil, 735, 735, 735, 735, 735, 481, + 481, 481, 481, 481, 481, 481, 481, nil, 481, 481, + nil, nil, nil, nil, nil, 481, 481, nil, 735, nil, + nil, 735, nil, nil, 735, 735, nil, nil, 735, nil, + 735, 481, nil, 481, 735, 481, 481, nil, 481, 481, + 481, 481, 481, 735, 481, nil, nil, nil, 735, 735, + 735, 735, nil, 735, 735, 735, 735, nil, nil, nil, + nil, 735, 735, nil, nil, nil, nil, nil, nil, 735, + nil, 735, 735, 735, 780, 780, 780, 780, 780, 780, + nil, nil, nil, 780, 780, nil, nil, nil, 780, nil, + 780, 780, 780, 780, 780, 780, 780, nil, nil, nil, + nil, nil, 780, 780, 780, 780, 780, 780, 780, nil, + nil, 780, nil, nil, nil, nil, nil, 780, 780, 780, + 780, 780, 780, 780, 780, 780, 780, 780, 780, nil, + 780, 780, 780, nil, 780, 780, 780, 780, 780, 470, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 470, 470, nil, 780, nil, + nil, 780, nil, nil, 780, 780, nil, nil, 780, nil, + 780, 470, nil, 470, 780, 470, 470, nil, 470, 470, + nil, nil, nil, 780, nil, nil, nil, nil, 780, 780, + 780, 780, nil, 780, 780, 780, 780, nil, nil, nil, + nil, 780, 780, nil, nil, nil, nil, nil, nil, 780, + nil, 780, 780, 780, 791, 791, 791, 791, 791, 791, + nil, nil, nil, 791, 791, nil, nil, nil, 791, nil, + 791, 791, 791, 791, 791, 791, 791, nil, nil, nil, + nil, nil, 791, 791, 791, 791, 791, 791, 791, nil, + nil, 791, nil, nil, nil, nil, nil, 791, 791, 791, + 791, 791, 791, 791, 791, 791, 791, 791, 791, nil, + 791, 791, 791, nil, 791, 791, 791, 791, 791, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 791, nil, + nil, 791, nil, nil, 791, 791, nil, nil, 791, nil, + 791, nil, nil, nil, 791, nil, nil, nil, nil, nil, + nil, nil, nil, 791, nil, nil, nil, nil, 791, 791, + 791, 791, nil, 791, 791, 791, 791, nil, nil, nil, + nil, 791, 791, nil, nil, nil, nil, nil, nil, 791, + nil, 791, 791, 791, 826, 826, 826, 826, 826, 826, + nil, nil, nil, 826, 826, nil, nil, nil, 826, nil, + 826, 826, 826, 826, 826, 826, 826, nil, nil, nil, + nil, nil, 826, 826, 826, 826, 826, 826, 826, nil, + nil, 826, nil, nil, nil, nil, nil, 826, 826, 826, + 826, 826, 826, 826, 826, 826, 826, 826, 826, nil, + 826, 826, 826, nil, 826, 826, 826, 826, 826, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 826, nil, + nil, 826, nil, nil, 826, 826, nil, nil, 826, nil, + 826, nil, nil, nil, 826, nil, nil, nil, nil, nil, + nil, nil, nil, 826, nil, nil, nil, nil, 826, 826, + 826, 826, nil, 826, 826, 826, 826, nil, nil, nil, + nil, 826, 826, nil, nil, nil, nil, nil, nil, 826, + nil, 826, 826, 826, 832, 832, 832, 832, 832, 832, + nil, nil, nil, 832, 832, nil, nil, nil, 832, nil, + 832, 832, 832, 832, 832, 832, 832, nil, nil, nil, + nil, nil, 832, 832, 832, 832, 832, 832, 832, nil, + nil, 832, nil, nil, nil, nil, nil, 832, 832, 832, + 832, 832, 832, 832, 832, 832, 832, 832, 832, nil, + 832, 832, 832, nil, 832, 832, 832, 832, 832, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 832, nil, + nil, 832, nil, nil, 832, 832, nil, nil, 832, nil, + 832, nil, nil, nil, 832, nil, nil, nil, nil, nil, + nil, nil, nil, 832, nil, nil, nil, nil, 832, 832, + 832, 832, nil, 832, 832, 832, 832, nil, nil, nil, + nil, 832, 832, nil, nil, nil, nil, nil, nil, 832, + nil, 832, 832, 832, 846, 846, 846, 846, 846, 846, + nil, nil, nil, 846, 846, nil, nil, nil, 846, nil, + 846, 846, 846, 846, 846, 846, 846, nil, nil, nil, + nil, nil, 846, 846, 846, 846, 846, 846, 846, nil, + nil, 846, nil, nil, nil, nil, nil, 846, 846, 846, + 846, 846, 846, 846, 846, 846, 846, 846, 846, nil, + 846, 846, 846, nil, 846, 846, 846, 846, 846, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 846, nil, + nil, 846, nil, nil, 846, 846, nil, nil, 846, nil, + 846, nil, nil, nil, 846, nil, nil, nil, nil, nil, + nil, nil, nil, 846, nil, nil, nil, nil, 846, 846, + 846, 846, nil, 846, 846, 846, 846, nil, nil, nil, + nil, 846, 846, nil, nil, nil, nil, nil, nil, 846, + nil, 846, 846, 846, 864, 864, 864, 864, 864, 864, + nil, nil, nil, 864, 864, nil, nil, nil, 864, nil, + 864, 864, 864, 864, 864, 864, 864, nil, nil, nil, + nil, nil, 864, 864, 864, 864, 864, 864, 864, nil, + nil, 864, nil, nil, nil, nil, nil, 864, 864, 864, + 864, 864, 864, 864, 864, 864, 864, 864, 864, nil, + 864, 864, 864, nil, 864, 864, 864, 864, 864, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 864, nil, + nil, 864, nil, nil, 864, 864, nil, nil, 864, nil, + 864, nil, nil, nil, 864, nil, nil, nil, nil, nil, + nil, nil, nil, 864, nil, nil, nil, nil, 864, 864, + 864, 864, nil, 864, 864, 864, 864, nil, nil, nil, + nil, 864, 864, nil, nil, nil, nil, nil, nil, 864, + nil, 864, 864, 864, 923, 923, 923, 923, 923, 923, + nil, nil, nil, 923, 923, nil, nil, nil, 923, nil, + 923, 923, 923, 923, 923, 923, 923, nil, nil, nil, + nil, nil, 923, 923, 923, 923, 923, 923, 923, nil, + nil, 923, nil, nil, nil, nil, nil, 923, 923, 923, + 923, 923, 923, 923, 923, 923, 923, 923, 923, nil, + 923, 923, 923, nil, 923, 923, 923, 923, 923, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 923, nil, + nil, 923, nil, nil, 923, 923, nil, nil, 923, nil, + 923, nil, nil, nil, 923, nil, nil, nil, nil, nil, + nil, nil, nil, 923, nil, nil, nil, nil, 923, 923, + 923, 923, nil, 923, 923, 923, 923, nil, nil, nil, + nil, 923, 923, nil, nil, nil, nil, nil, nil, 923, + nil, 923, 923, 923, 930, 930, 930, 930, 930, 930, + nil, nil, nil, 930, 930, nil, nil, nil, 930, nil, + 930, 930, 930, 930, 930, 930, 930, nil, nil, nil, + nil, nil, 930, 930, 930, 930, 930, 930, 930, nil, + nil, 930, nil, nil, nil, nil, nil, 930, 930, 930, + 930, 930, 930, 930, 930, 930, 930, 930, 930, nil, + 930, 930, 930, nil, 930, 930, 930, 930, 930, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 930, nil, + nil, 930, nil, nil, 930, 930, nil, nil, 930, nil, + 930, nil, nil, nil, 930, nil, nil, nil, nil, nil, + nil, nil, nil, 930, nil, nil, nil, nil, 930, 930, + 930, 930, nil, 930, 930, 930, 930, nil, nil, nil, + nil, 930, 930, nil, nil, nil, nil, nil, nil, 930, + nil, 930, 930, 930, 931, 931, 931, 931, 931, 931, + nil, nil, nil, 931, 931, nil, nil, nil, 931, nil, + 931, 931, 931, 931, 931, 931, 931, nil, nil, nil, + nil, nil, 931, 931, 931, 931, 931, 931, 931, nil, + nil, 931, nil, nil, nil, nil, nil, 931, 931, 931, + 931, 931, 931, 931, 931, 931, 931, 931, 931, nil, + 931, 931, 931, nil, 931, 931, 931, 931, 931, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 931, nil, + nil, 931, nil, nil, 931, 931, nil, nil, 931, nil, + 931, nil, nil, nil, 931, nil, nil, nil, nil, nil, + nil, nil, nil, 931, nil, nil, nil, nil, 931, 931, + 931, 931, nil, 931, 931, 931, 931, nil, nil, nil, + nil, 931, 931, nil, nil, nil, nil, nil, nil, 931, + nil, 931, 931, 931, 948, 948, 948, 948, 948, 948, + nil, nil, nil, 948, 948, nil, nil, nil, 948, nil, + 948, 948, 948, 948, 948, 948, 948, nil, nil, nil, + nil, nil, 948, 948, 948, 948, 948, 948, 948, nil, + nil, 948, nil, nil, nil, nil, nil, 948, 948, 948, + 948, 948, 948, 948, 948, 948, 948, 948, 948, nil, + 948, 948, 948, nil, 948, 948, 948, 948, 948, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 948, nil, + nil, 948, nil, nil, 948, 948, nil, nil, 948, nil, + 948, nil, nil, nil, 948, nil, nil, nil, nil, nil, + nil, nil, nil, 948, nil, nil, nil, nil, 948, 948, + 948, 948, nil, 948, 948, 948, 948, nil, nil, nil, + nil, 948, 948, nil, nil, nil, nil, nil, nil, 948, + nil, 948, 948, 948, 953, 953, 953, 953, 953, 953, + nil, nil, nil, 953, 953, nil, nil, nil, 953, nil, + 953, 953, 953, 953, 953, 953, 953, nil, nil, nil, + nil, nil, 953, 953, 953, 953, 953, 953, 953, nil, + nil, 953, nil, nil, nil, nil, nil, 953, 953, 953, + 953, 953, 953, 953, 953, 953, 953, 953, 953, nil, + 953, 953, 953, nil, 953, 953, 953, 953, 953, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 953, nil, + nil, 953, nil, nil, 953, 953, nil, nil, 953, nil, + 953, nil, nil, nil, 953, nil, nil, nil, nil, nil, + nil, nil, nil, 953, nil, nil, nil, nil, 953, 953, + 953, 953, nil, 953, 953, 953, 953, nil, nil, nil, + nil, 953, 953, nil, nil, nil, nil, nil, nil, 953, + nil, 953, 953, 953, 5, 5, 5, 5, 5, nil, + nil, nil, 5, 5, nil, nil, nil, 5, nil, 5, + 5, 5, 5, 5, 5, 5, nil, nil, nil, nil, + nil, 5, 5, 5, 5, 5, 5, 5, nil, nil, + 5, nil, nil, nil, nil, nil, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, nil, 5, + 5, 5, nil, 5, 5, 5, 5, 5, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 5, nil, nil, + 5, nil, nil, 5, 5, nil, nil, 5, nil, 5, + nil, nil, nil, 5, nil, nil, nil, nil, nil, nil, + nil, nil, 5, nil, nil, nil, nil, 5, 5, 5, + 5, nil, 5, 5, 5, 5, nil, nil, nil, nil, + 5, 5, nil, nil, nil, 20, 20, 20, 5, 20, + 5, 5, 5, 20, 20, nil, nil, nil, 20, nil, + 20, 20, 20, 20, 20, 20, 20, nil, nil, nil, + nil, nil, 20, 20, 20, 20, 20, 20, 20, nil, + nil, 20, nil, nil, nil, nil, nil, nil, 20, nil, + nil, 20, 20, 20, 20, 20, 20, 20, 20, nil, + 20, 20, 20, nil, 20, 20, 20, 20, 20, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, 20, nil, nil, 20, 20, nil, nil, 20, nil, + nil, nil, nil, nil, 20, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 20, 20, + 20, 20, nil, 20, 20, 20, 20, nil, nil, nil, + nil, 20, 20, nil, nil, nil, 29, 29, 29, 20, + 29, 20, 20, 20, 29, 29, nil, nil, nil, 29, + nil, 29, 29, 29, 29, 29, 29, 29, nil, nil, + nil, nil, nil, 29, 29, 29, 29, 29, 29, 29, + nil, nil, 29, nil, nil, nil, nil, nil, nil, 29, + nil, nil, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, nil, 29, 29, 29, 29, 29, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 29, + nil, nil, 29, nil, nil, 29, 29, nil, nil, 29, + nil, 29, nil, 29, nil, 29, nil, nil, 29, nil, + nil, nil, nil, nil, 29, nil, nil, nil, nil, 29, + 29, 29, 29, nil, 29, 29, 29, 29, nil, nil, + nil, nil, 29, 29, nil, nil, nil, 30, 30, 30, + 29, 30, 29, 29, 29, 30, 30, nil, nil, nil, + 30, nil, 30, 30, 30, 30, 30, 30, 30, nil, + nil, nil, nil, nil, 30, 30, 30, 30, 30, 30, + 30, nil, nil, 30, nil, nil, nil, nil, nil, nil, + 30, nil, nil, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, nil, 30, 30, 30, 30, + 30, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 30, nil, nil, 30, nil, nil, 30, 30, nil, nil, + 30, nil, 30, nil, 30, nil, 30, nil, nil, 30, + nil, nil, nil, nil, nil, 30, nil, nil, nil, nil, + 30, 30, 30, 30, nil, 30, 30, 30, 30, nil, + nil, nil, nil, 30, 30, nil, nil, nil, 31, 31, + 31, 30, 31, 30, 30, 30, 31, 31, nil, nil, + nil, 31, nil, 31, 31, 31, 31, 31, 31, 31, + nil, nil, nil, nil, nil, 31, 31, 31, 31, 31, + 31, 31, nil, nil, 31, nil, nil, nil, nil, nil, + nil, 31, nil, nil, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, nil, 31, 31, 31, + 31, 31, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 31, nil, nil, 31, nil, nil, 31, 31, nil, + nil, 31, nil, 31, nil, 31, nil, 31, nil, nil, + 31, nil, nil, nil, nil, nil, 31, nil, nil, nil, + nil, 31, 31, 31, 31, nil, 31, 31, 31, 31, + nil, nil, nil, nil, 31, 31, nil, nil, nil, 34, + 34, 34, 31, 34, 31, 31, 31, 34, 34, nil, + nil, nil, 34, nil, 34, 34, 34, 34, 34, 34, + 34, nil, nil, nil, nil, nil, 34, 34, 34, 34, + 34, 34, 34, nil, nil, 34, nil, nil, nil, nil, + nil, nil, 34, nil, nil, 34, 34, 34, 34, 34, + 34, 34, 34, nil, 34, 34, 34, nil, 34, 34, + nil, nil, 34, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 34, nil, nil, 34, nil, nil, 34, 34, + nil, nil, 34, nil, 34, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 34, 34, 34, 34, nil, 34, 34, 34, + 34, nil, nil, nil, nil, 34, 34, nil, nil, nil, + 35, 35, 35, 34, 35, 34, 34, 34, 35, 35, + nil, nil, nil, 35, nil, 35, 35, 35, 35, 35, + 35, 35, nil, nil, nil, nil, nil, 35, 35, 35, + 35, 35, 35, 35, nil, nil, 35, nil, nil, nil, + nil, nil, nil, 35, nil, nil, 35, 35, 35, 35, + 35, 35, 35, 35, nil, 35, 35, 35, nil, 35, + 35, nil, nil, 35, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 35, nil, nil, 35, nil, nil, 35, + 35, nil, nil, 35, nil, nil, 914, nil, 914, 914, + 914, 914, 914, nil, nil, nil, nil, nil, nil, nil, + nil, 914, nil, 35, 35, 35, 35, nil, 35, 35, + 35, 35, nil, nil, nil, nil, 35, 35, nil, nil, + nil, 35, nil, 914, 35, nil, 35, 35, 35, 42, + 42, 42, nil, 42, 914, 914, nil, 42, 42, 914, + nil, nil, 42, nil, 42, 42, 42, 42, 42, 42, + 42, nil, nil, nil, nil, nil, 42, 42, 42, 42, + 42, 42, 42, nil, nil, 42, nil, nil, nil, nil, + nil, nil, 42, nil, nil, 42, 42, 42, 42, 42, + 42, 42, 42, nil, 42, 42, 42, nil, 42, 42, + 42, 42, 42, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 42, nil, nil, 42, nil, nil, 42, 42, + nil, nil, 42, nil, nil, nil, nil, nil, 42, nil, + nil, nil, nil, nil, nil, nil, nil, 42, nil, nil, + nil, nil, 42, 42, 42, 42, nil, 42, 42, 42, + 42, nil, nil, nil, nil, 42, 42, nil, nil, nil, + 43, 43, 43, 42, 43, 42, 42, 42, 43, 43, + nil, nil, nil, 43, nil, 43, 43, 43, 43, 43, + 43, 43, nil, nil, nil, nil, nil, 43, 43, 43, + 43, 43, 43, 43, nil, nil, 43, nil, nil, nil, + nil, nil, nil, 43, nil, nil, 43, 43, 43, 43, + 43, 43, 43, 43, nil, 43, 43, 43, nil, 43, + 43, 43, 43, 43, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 43, nil, nil, 43, nil, nil, 43, + 43, nil, nil, 43, nil, nil, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, nil, 43, nil, + nil, nil, nil, 43, 43, 43, 43, nil, 43, 43, + 43, 43, nil, nil, nil, nil, 43, 43, nil, nil, + nil, 45, 45, 45, 43, 45, 43, 43, 43, 45, + 45, nil, nil, nil, 45, nil, 45, 45, 45, 45, + 45, 45, 45, nil, nil, nil, nil, nil, 45, 45, + 45, 45, 45, 45, 45, nil, nil, 45, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 45, 45, 45, + 45, 45, 45, 45, 45, nil, 45, 45, 45, nil, + 45, 45, 45, 45, 45, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 45, nil, nil, + 45, 45, nil, nil, 45, nil, nil, nil, nil, nil, + 45, nil, nil, nil, nil, nil, nil, nil, nil, 45, + nil, nil, nil, nil, 45, 45, 45, 45, nil, 45, + 45, 45, 45, nil, nil, nil, nil, 45, 45, nil, + nil, nil, nil, nil, nil, 45, nil, 45, 45, 45, + 59, 59, 59, 59, 59, nil, nil, nil, 59, 59, + nil, nil, nil, 59, nil, 59, 59, 59, 59, 59, + 59, 59, nil, nil, nil, nil, nil, 59, 59, 59, + 59, 59, 59, 59, nil, nil, 59, nil, nil, nil, + nil, nil, 59, 59, nil, 59, 59, 59, 59, 59, + 59, 59, 59, 59, nil, 59, 59, 59, nil, 59, + 59, 59, 59, 59, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 59, nil, nil, 59, nil, nil, 59, + 59, nil, nil, 59, nil, 59, nil, nil, nil, 59, + nil, nil, nil, nil, nil, nil, nil, nil, 59, nil, + nil, nil, nil, 59, 59, 59, 59, nil, 59, 59, + 59, 59, nil, nil, nil, nil, 59, 59, nil, nil, + nil, 60, 60, 60, 59, 60, 59, 59, 59, 60, + 60, nil, nil, nil, 60, nil, 60, 60, 60, 60, + 60, 60, 60, nil, nil, nil, nil, nil, 60, 60, + 60, 60, 60, 60, 60, nil, nil, 60, nil, nil, + nil, nil, nil, nil, 60, nil, nil, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, nil, + 60, 60, 60, 60, 60, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 60, nil, nil, 60, nil, nil, + 60, 60, nil, nil, 60, nil, 60, nil, nil, nil, + 60, nil, nil, 60, nil, nil, nil, nil, nil, 60, + nil, nil, nil, nil, 60, 60, 60, 60, nil, 60, + 60, 60, 60, nil, nil, nil, nil, 60, 60, nil, + nil, nil, 61, 61, 61, 60, 61, 60, 60, 60, + 61, 61, nil, nil, nil, 61, nil, 61, 61, 61, + 61, 61, 61, 61, nil, nil, nil, nil, nil, 61, + 61, 61, 61, 61, 61, 61, nil, nil, 61, nil, + nil, nil, nil, nil, nil, 61, nil, nil, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + nil, 61, 61, 61, 61, 61, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 61, nil, nil, 61, nil, + nil, 61, 61, nil, nil, 61, nil, nil, nil, nil, + nil, 61, nil, nil, 61, nil, nil, nil, nil, nil, + 61, nil, nil, nil, nil, 61, 61, 61, 61, nil, + 61, 61, 61, 61, nil, nil, nil, nil, 61, 61, + nil, nil, nil, 64, 64, 64, 61, 64, 61, 61, + 61, 64, 64, nil, nil, nil, 64, nil, 64, 64, + 64, 64, 64, 64, 64, nil, nil, nil, nil, nil, + 64, 64, 64, 64, 64, 64, 64, nil, nil, 64, + nil, nil, nil, nil, nil, nil, 64, nil, nil, 64, + 64, 64, 64, 64, 64, 64, 64, nil, 64, 64, + 64, nil, 64, 64, 64, 64, 64, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 64, nil, nil, 64, + nil, nil, 64, 64, nil, nil, 64, nil, nil, nil, + nil, nil, 64, nil, nil, nil, nil, nil, nil, nil, + nil, 64, nil, nil, nil, nil, 64, 64, 64, 64, + nil, 64, 64, 64, 64, nil, nil, nil, nil, 64, + 64, nil, nil, nil, 65, 65, 65, 64, 65, 64, + 64, 64, 65, 65, nil, nil, nil, 65, nil, 65, + 65, 65, 65, 65, 65, 65, nil, nil, nil, nil, + nil, 65, 65, 65, 65, 65, 65, 65, nil, nil, + 65, nil, nil, nil, nil, nil, nil, 65, nil, nil, + 65, 65, 65, 65, 65, 65, 65, 65, nil, 65, + 65, 65, nil, 65, 65, 65, 65, 65, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 65, nil, nil, + 65, nil, nil, 65, 65, nil, nil, 65, nil, nil, + nil, nil, nil, 65, nil, nil, nil, nil, nil, nil, + nil, nil, 65, nil, nil, nil, nil, 65, 65, 65, + 65, nil, 65, 65, 65, 65, nil, nil, nil, nil, + 65, 65, nil, nil, nil, 68, 68, 68, 65, 68, + 65, 65, 65, 68, 68, nil, nil, nil, 68, nil, + 68, 68, 68, 68, 68, 68, 68, nil, nil, nil, + nil, nil, 68, 68, 68, 68, 68, 68, 68, nil, + nil, 68, nil, nil, nil, nil, nil, nil, 68, nil, + nil, 68, 68, 68, 68, 68, 68, 68, 68, nil, + 68, 68, 68, nil, 68, 68, 68, 68, 68, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 68, nil, + nil, 68, nil, nil, 68, 68, nil, nil, 68, nil, + nil, nil, nil, nil, 68, nil, nil, nil, nil, nil, + nil, nil, nil, 68, nil, nil, nil, nil, 68, 68, + 68, 68, nil, 68, 68, 68, 68, nil, nil, nil, + nil, 68, 68, 68, nil, nil, nil, nil, 68, 68, + nil, 68, 68, 68, 69, 69, 69, nil, 69, nil, + nil, nil, 69, 69, nil, nil, nil, 69, nil, 69, + 69, 69, 69, 69, 69, 69, nil, nil, nil, nil, + nil, 69, 69, 69, 69, 69, 69, 69, nil, nil, + 69, nil, nil, nil, nil, nil, nil, 69, nil, nil, + 69, 69, 69, 69, 69, 69, 69, 69, nil, 69, + 69, 69, nil, 69, 69, nil, nil, 69, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 69, nil, nil, + 69, nil, nil, 69, 69, nil, nil, 69, nil, 69, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 69, 69, 69, + 69, nil, 69, 69, 69, 69, nil, nil, nil, nil, + 69, 69, nil, nil, nil, 70, 70, 70, 69, 70, + 69, 69, 69, 70, 70, nil, nil, nil, 70, nil, + 70, 70, 70, 70, 70, 70, 70, nil, nil, nil, + nil, nil, 70, 70, 70, 70, 70, 70, 70, nil, + nil, 70, nil, nil, nil, nil, nil, nil, 70, nil, + nil, 70, 70, 70, 70, 70, 70, 70, 70, nil, + 70, 70, 70, nil, 70, 70, nil, nil, 70, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 70, nil, nil, 70, nil, + nil, 70, nil, nil, 70, 70, nil, nil, 70, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 70, 70, + 70, 70, nil, 70, 70, 70, 70, nil, nil, nil, + nil, 70, 70, nil, nil, nil, 71, 71, 71, 70, + 71, 70, 70, 70, 71, 71, nil, nil, nil, 71, + nil, 71, 71, 71, 71, 71, 71, 71, nil, nil, + nil, nil, nil, 71, 71, 71, 71, 71, 71, 71, + nil, nil, 71, nil, nil, nil, nil, nil, nil, 71, + nil, nil, 71, 71, 71, 71, 71, 71, 71, 71, + nil, 71, 71, 71, nil, 71, 71, nil, nil, 71, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 71, + nil, nil, 71, nil, nil, 71, 71, nil, nil, 71, + nil, nil, 936, nil, 936, 936, 936, 936, 936, nil, + nil, nil, nil, nil, nil, nil, nil, 936, nil, 71, + 71, 71, 71, nil, 71, 71, 71, 71, nil, nil, + nil, nil, 71, 71, nil, nil, nil, nil, nil, 936, + 71, nil, 71, 71, 71, 115, 115, 115, 115, 115, + 936, 936, nil, 115, 115, 936, nil, nil, 115, nil, + 115, 115, 115, 115, 115, 115, 115, nil, nil, nil, + nil, nil, 115, 115, 115, 115, 115, 115, 115, nil, + nil, 115, nil, nil, nil, nil, nil, 115, 115, 115, + 115, 115, 115, 115, 115, 115, 115, 115, 115, nil, + 115, 115, 115, nil, 115, 115, 115, 115, 115, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 115, nil, + nil, 115, nil, nil, 115, 115, nil, nil, 115, nil, + 115, nil, nil, nil, 115, nil, nil, nil, nil, nil, + nil, nil, nil, 115, nil, nil, nil, nil, 115, 115, + 115, 115, nil, 115, 115, 115, 115, nil, nil, nil, + nil, 115, 115, nil, nil, nil, nil, nil, 115, 115, + nil, 115, 115, 115, 120, 120, 120, nil, 120, nil, + nil, nil, 120, 120, nil, nil, nil, 120, nil, 120, + 120, 120, 120, 120, 120, 120, nil, nil, nil, nil, + nil, 120, 120, 120, 120, 120, 120, 120, nil, nil, + 120, nil, nil, nil, nil, nil, nil, 120, nil, nil, + 120, 120, 120, 120, 120, 120, 120, 120, nil, 120, + 120, 120, nil, 120, 120, 120, 120, 120, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 120, nil, nil, + 120, nil, nil, 120, 120, nil, nil, 120, nil, nil, + nil, nil, nil, 120, nil, nil, nil, nil, nil, nil, + nil, nil, 120, nil, nil, nil, nil, 120, 120, 120, + 120, nil, 120, 120, 120, 120, nil, nil, nil, nil, + 120, 120, nil, nil, nil, 121, 121, 121, 120, 121, + 120, 120, 120, 121, 121, nil, nil, nil, 121, nil, + 121, 121, 121, 121, 121, 121, 121, nil, nil, nil, + nil, nil, 121, 121, 121, 121, 121, 121, 121, nil, + nil, 121, nil, nil, nil, nil, nil, nil, 121, nil, + nil, 121, 121, 121, 121, 121, 121, 121, 121, nil, + 121, 121, 121, nil, 121, 121, 121, 121, 121, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 121, nil, + nil, 121, nil, nil, 121, 121, nil, nil, 121, nil, + nil, nil, nil, nil, 121, nil, nil, nil, nil, nil, + nil, nil, nil, 121, nil, nil, nil, nil, 121, 121, + 121, 121, nil, 121, 121, 121, 121, nil, nil, nil, + nil, 121, 121, nil, nil, nil, 122, 122, 122, 121, + 122, 121, 121, 121, 122, 122, nil, nil, nil, 122, + nil, 122, 122, 122, 122, 122, 122, 122, nil, nil, + nil, nil, nil, 122, 122, 122, 122, 122, 122, 122, + nil, nil, 122, nil, nil, nil, nil, nil, nil, 122, + nil, nil, 122, 122, 122, 122, 122, 122, 122, 122, + nil, 122, 122, 122, nil, 122, 122, 122, 122, 122, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 122, + nil, nil, 122, nil, nil, 122, 122, nil, nil, 122, + nil, nil, nil, nil, nil, 122, nil, nil, nil, nil, + nil, nil, nil, nil, 122, nil, nil, nil, nil, 122, + 122, 122, 122, nil, 122, 122, 122, 122, nil, nil, + nil, nil, 122, 122, nil, nil, nil, 123, 123, 123, + 122, 123, 122, 122, 122, 123, 123, nil, nil, nil, + 123, nil, 123, 123, 123, 123, 123, 123, 123, nil, + nil, nil, nil, nil, 123, 123, 123, 123, 123, 123, + 123, nil, nil, 123, nil, nil, nil, nil, nil, nil, + 123, nil, nil, 123, 123, 123, 123, 123, 123, 123, + 123, nil, 123, 123, 123, nil, 123, 123, 123, 123, + 123, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 123, nil, nil, 123, nil, nil, 123, 123, nil, nil, + 123, nil, nil, nil, nil, nil, 123, nil, nil, nil, + nil, nil, nil, nil, nil, 123, nil, nil, nil, nil, + 123, 123, 123, 123, nil, 123, 123, 123, 123, nil, + nil, nil, nil, 123, 123, nil, nil, nil, nil, nil, + nil, 123, nil, 123, 123, 123, 124, 124, 124, 124, + 124, nil, nil, nil, 124, 124, nil, nil, nil, 124, + nil, 124, 124, 124, 124, 124, 124, 124, nil, nil, + nil, nil, nil, 124, 124, 124, 124, 124, 124, 124, + nil, nil, 124, nil, nil, nil, nil, nil, 124, 124, + nil, 124, 124, 124, 124, 124, 124, 124, 124, 124, + nil, 124, 124, 124, nil, 124, 124, 124, 124, 124, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 124, + nil, nil, 124, nil, nil, 124, 124, nil, nil, 124, + nil, 124, nil, nil, nil, 124, nil, nil, nil, nil, + nil, nil, nil, nil, 124, nil, nil, nil, nil, 124, + 124, 124, 124, nil, 124, 124, 124, 124, nil, nil, + nil, nil, 124, 124, nil, nil, nil, 212, 212, 212, + 124, 212, 124, 124, 124, 212, 212, nil, nil, nil, + 212, nil, 212, 212, 212, 212, 212, 212, 212, nil, + nil, nil, nil, nil, 212, 212, 212, 212, 212, 212, + 212, nil, nil, 212, nil, nil, nil, nil, nil, nil, + 212, nil, nil, 212, 212, 212, 212, 212, 212, 212, + 212, nil, 212, 212, 212, nil, 212, 212, 212, 212, + 212, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 212, nil, nil, 212, nil, nil, 212, 212, nil, nil, + 212, nil, 212, nil, nil, nil, 212, nil, nil, nil, + nil, nil, nil, nil, nil, 212, nil, nil, nil, nil, + 212, 212, 212, 212, nil, 212, 212, 212, 212, nil, + nil, nil, nil, 212, 212, nil, nil, nil, 213, 213, + 213, 212, 213, 212, 212, 212, 213, 213, nil, nil, + nil, 213, nil, 213, 213, 213, 213, 213, 213, 213, + nil, nil, nil, nil, nil, 213, 213, 213, 213, 213, + 213, 213, nil, nil, 213, nil, nil, nil, nil, nil, + nil, 213, nil, nil, 213, 213, 213, 213, 213, 213, + 213, 213, nil, 213, 213, 213, nil, 213, 213, 213, + 213, 213, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 213, nil, nil, 213, nil, nil, 213, 213, nil, + nil, 213, nil, 213, nil, nil, nil, 213, nil, nil, + nil, nil, nil, nil, nil, nil, 213, nil, nil, nil, + nil, 213, 213, 213, 213, nil, 213, 213, 213, 213, + nil, nil, nil, nil, 213, 213, nil, nil, nil, 214, + 214, 214, 213, 214, 213, 213, 213, 214, 214, nil, + nil, nil, 214, nil, 214, 214, 214, 214, 214, 214, + 214, nil, nil, nil, nil, nil, 214, 214, 214, 214, + 214, 214, 214, nil, nil, 214, nil, nil, nil, nil, + nil, nil, 214, nil, nil, 214, 214, 214, 214, 214, + 214, 214, 214, nil, 214, 214, 214, nil, 214, 214, + 214, 214, 214, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 214, nil, nil, 214, nil, nil, 214, 214, + nil, nil, 214, nil, nil, nil, nil, nil, 214, nil, + nil, nil, nil, nil, nil, nil, nil, 214, nil, nil, + nil, nil, 214, 214, 214, 214, nil, 214, 214, 214, + 214, nil, nil, nil, nil, 214, 214, nil, nil, nil, + 215, 215, 215, 214, 215, 214, 214, 214, 215, 215, + nil, nil, nil, 215, nil, 215, 215, 215, 215, 215, + 215, 215, nil, nil, nil, nil, nil, 215, 215, 215, + 215, 215, 215, 215, nil, nil, 215, nil, nil, nil, + nil, nil, nil, 215, nil, nil, 215, 215, 215, 215, + 215, 215, 215, 215, nil, 215, 215, 215, nil, 215, + 215, 215, 215, 215, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 215, nil, nil, 215, nil, nil, 215, + 215, nil, nil, 215, nil, nil, nil, nil, nil, 215, + nil, nil, nil, nil, nil, nil, nil, nil, 215, nil, + nil, nil, nil, 215, 215, 215, 215, nil, 215, 215, + 215, 215, nil, nil, nil, nil, 215, 215, nil, nil, + nil, 216, 216, 216, 215, 216, 215, 215, 215, 216, + 216, nil, nil, nil, 216, nil, 216, 216, 216, 216, + 216, 216, 216, nil, nil, nil, nil, nil, 216, 216, + 216, 216, 216, 216, 216, nil, nil, 216, nil, nil, + nil, nil, nil, nil, 216, nil, nil, 216, 216, 216, + 216, 216, 216, 216, 216, nil, 216, 216, 216, nil, + 216, 216, 216, 216, 216, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 216, nil, nil, 216, nil, nil, + 216, 216, nil, nil, 216, nil, nil, nil, nil, nil, + 216, nil, nil, nil, nil, nil, nil, nil, nil, 216, + nil, nil, nil, nil, 216, 216, 216, 216, nil, 216, + 216, 216, 216, nil, nil, nil, nil, 216, 216, nil, + nil, nil, 217, 217, 217, 216, 217, 216, 216, 216, + 217, 217, nil, nil, nil, 217, nil, 217, 217, 217, + 217, 217, 217, 217, nil, nil, nil, nil, nil, 217, + 217, 217, 217, 217, 217, 217, nil, nil, 217, nil, + nil, nil, nil, nil, nil, 217, nil, nil, 217, 217, + 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, + nil, 217, 217, 217, 217, 217, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 217, nil, nil, 217, nil, + nil, 217, 217, nil, nil, 217, nil, 217, nil, 217, + nil, 217, nil, nil, 217, nil, nil, nil, nil, nil, + 217, nil, nil, nil, nil, 217, 217, 217, 217, nil, + 217, 217, 217, 217, nil, nil, nil, nil, 217, 217, + nil, nil, nil, 222, 222, 222, 217, 222, 217, 217, + 217, 222, 222, nil, nil, nil, 222, nil, 222, 222, + 222, 222, 222, 222, 222, nil, nil, nil, nil, nil, + 222, 222, 222, 222, 222, 222, 222, nil, nil, 222, + nil, nil, nil, nil, nil, nil, 222, nil, nil, 222, + 222, 222, 222, 222, 222, 222, 222, nil, 222, 222, + 222, nil, 222, 222, 222, 222, 222, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 222, nil, nil, 222, + nil, nil, 222, 222, nil, nil, 222, nil, nil, nil, + nil, nil, 222, nil, nil, nil, nil, nil, nil, nil, + nil, 222, nil, nil, nil, nil, 222, 222, 222, 222, + nil, 222, 222, 222, 222, nil, nil, nil, nil, 222, + 222, nil, nil, nil, 223, 223, 223, 222, 223, 222, + 222, 222, 223, 223, nil, nil, nil, 223, nil, 223, + 223, 223, 223, 223, 223, 223, nil, nil, nil, nil, + nil, 223, 223, 223, 223, 223, 223, 223, nil, nil, + 223, nil, nil, nil, nil, nil, nil, 223, nil, nil, + 223, 223, 223, 223, 223, 223, 223, 223, nil, 223, + 223, 223, nil, 223, 223, 223, 223, 223, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 223, nil, nil, + 223, nil, nil, 223, 223, nil, nil, 223, nil, nil, + nil, nil, nil, 223, nil, nil, nil, nil, nil, nil, + nil, nil, 223, nil, nil, nil, nil, 223, 223, 223, + 223, nil, 223, 223, 223, 223, nil, nil, nil, nil, + 223, 223, nil, nil, nil, 224, 224, 224, 223, 224, + 223, 223, 223, 224, 224, nil, nil, nil, 224, nil, + 224, 224, 224, 224, 224, 224, 224, nil, nil, nil, + nil, nil, 224, 224, 224, 224, 224, 224, 224, nil, + nil, 224, nil, nil, nil, nil, nil, nil, 224, nil, + nil, 224, 224, 224, 224, 224, 224, 224, 224, nil, + 224, 224, 224, nil, 224, 224, 224, 224, 224, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 224, nil, + nil, 224, nil, nil, 224, 224, nil, nil, 224, nil, + nil, nil, nil, nil, 224, nil, nil, nil, nil, nil, + nil, nil, nil, 224, nil, nil, nil, nil, 224, 224, + 224, 224, nil, 224, 224, 224, 224, nil, nil, nil, + nil, 224, 224, 224, nil, nil, 235, 235, 235, 224, + 235, 224, 224, 224, 235, 235, nil, nil, nil, 235, + nil, 235, 235, 235, 235, 235, 235, 235, nil, nil, + nil, nil, nil, 235, 235, 235, 235, 235, 235, 235, + nil, nil, 235, nil, nil, nil, nil, nil, nil, 235, + nil, nil, 235, 235, 235, 235, 235, 235, 235, 235, + nil, 235, 235, 235, nil, 235, 235, 235, 235, 235, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 235, + nil, nil, 235, nil, nil, 235, 235, nil, nil, 235, + nil, nil, nil, nil, nil, 235, nil, nil, nil, nil, + nil, nil, nil, nil, 235, nil, nil, nil, nil, 235, + 235, 235, 235, nil, 235, 235, 235, 235, nil, nil, + nil, nil, 235, 235, nil, nil, nil, 238, 238, 238, + 235, 238, 235, 235, 235, 238, 238, nil, nil, nil, + 238, nil, 238, 238, 238, 238, 238, 238, 238, nil, + nil, nil, nil, nil, 238, 238, 238, 238, 238, 238, + 238, nil, nil, 238, nil, nil, nil, nil, nil, nil, + 238, nil, nil, 238, 238, 238, 238, 238, 238, 238, + 238, nil, 238, 238, 238, nil, 238, 238, 238, 238, + 238, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 238, nil, nil, 238, nil, nil, 238, 238, nil, nil, + 238, nil, nil, nil, nil, nil, 238, nil, nil, nil, + nil, nil, nil, nil, nil, 238, nil, nil, nil, nil, + 238, 238, 238, 238, nil, 238, 238, 238, 238, nil, + nil, nil, nil, 238, 238, nil, nil, nil, 239, 239, + 239, 238, 239, 238, 238, 238, 239, 239, nil, nil, + nil, 239, nil, 239, 239, 239, 239, 239, 239, 239, + nil, nil, nil, nil, nil, 239, 239, 239, 239, 239, + 239, 239, nil, nil, 239, nil, nil, nil, nil, nil, + nil, 239, nil, nil, 239, 239, 239, 239, 239, 239, + 239, 239, nil, 239, 239, 239, nil, 239, 239, 239, + 239, 239, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 239, nil, nil, 239, nil, nil, 239, 239, nil, + nil, 239, nil, nil, nil, nil, nil, 239, nil, nil, + nil, nil, nil, nil, nil, nil, 239, nil, nil, nil, + nil, 239, 239, 239, 239, nil, 239, 239, 239, 239, + nil, nil, nil, nil, 239, 239, nil, nil, nil, 240, + 240, 240, 239, 240, 239, 239, 239, 240, 240, nil, + nil, nil, 240, nil, 240, 240, 240, 240, 240, 240, + 240, nil, nil, nil, nil, nil, 240, 240, 240, 240, + 240, 240, 240, nil, nil, 240, nil, nil, nil, nil, + nil, nil, 240, nil, nil, 240, 240, 240, 240, 240, + 240, 240, 240, nil, 240, 240, 240, nil, 240, 240, + 240, 240, 240, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 240, nil, nil, 240, nil, nil, 240, 240, + nil, nil, 240, nil, nil, nil, nil, nil, 240, nil, + nil, nil, nil, nil, nil, nil, nil, 240, nil, nil, + nil, nil, 240, 240, 240, 240, nil, 240, 240, 240, + 240, nil, nil, nil, nil, 240, 240, nil, nil, nil, + 241, 241, 241, 240, 241, 240, 240, 240, 241, 241, + nil, nil, nil, 241, nil, 241, 241, 241, 241, 241, + 241, 241, nil, nil, nil, nil, nil, 241, 241, 241, + 241, 241, 241, 241, nil, nil, 241, nil, nil, nil, + nil, nil, nil, 241, nil, nil, 241, 241, 241, 241, + 241, 241, 241, 241, nil, 241, 241, 241, nil, 241, + 241, 241, 241, 241, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 241, nil, nil, 241, nil, nil, 241, + 241, nil, nil, 241, nil, nil, nil, nil, nil, 241, + nil, nil, nil, nil, nil, nil, nil, nil, 241, nil, + nil, nil, nil, 241, 241, 241, 241, nil, 241, 241, + 241, 241, nil, nil, nil, nil, 241, 241, nil, nil, + nil, 242, 242, 242, 241, 242, 241, 241, 241, 242, + 242, nil, nil, nil, 242, nil, 242, 242, 242, 242, + 242, 242, 242, nil, nil, nil, nil, nil, 242, 242, + 242, 242, 242, 242, 242, nil, nil, 242, nil, nil, + nil, nil, nil, nil, 242, nil, nil, 242, 242, 242, + 242, 242, 242, 242, 242, nil, 242, 242, 242, nil, + 242, 242, 242, 242, 242, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 242, nil, nil, 242, nil, nil, + 242, 242, nil, nil, 242, nil, nil, nil, nil, nil, + 242, nil, nil, nil, nil, nil, nil, nil, nil, 242, + nil, nil, nil, nil, 242, 242, 242, 242, nil, 242, + 242, 242, 242, nil, nil, nil, nil, 242, 242, nil, + nil, nil, 243, 243, 243, 242, 243, 242, 242, 242, + 243, 243, nil, nil, nil, 243, nil, 243, 243, 243, + 243, 243, 243, 243, nil, nil, nil, nil, nil, 243, + 243, 243, 243, 243, 243, 243, nil, nil, 243, nil, + nil, nil, nil, nil, nil, 243, nil, nil, 243, 243, + 243, 243, 243, 243, 243, 243, nil, 243, 243, 243, + nil, 243, 243, 243, 243, 243, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 243, nil, nil, 243, nil, + nil, 243, 243, nil, nil, 243, nil, nil, nil, nil, + nil, 243, nil, nil, nil, nil, nil, nil, nil, nil, + 243, nil, nil, nil, nil, 243, 243, 243, 243, nil, + 243, 243, 243, 243, nil, nil, nil, nil, 243, 243, + nil, nil, nil, 244, 244, 244, 243, 244, 243, 243, + 243, 244, 244, nil, nil, nil, 244, nil, 244, 244, + 244, 244, 244, 244, 244, nil, nil, nil, nil, nil, + 244, 244, 244, 244, 244, 244, 244, nil, nil, 244, + nil, nil, nil, nil, nil, nil, 244, nil, nil, 244, + 244, 244, 244, 244, 244, 244, 244, nil, 244, 244, + 244, nil, 244, 244, 244, 244, 244, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 244, nil, nil, 244, + nil, nil, 244, 244, nil, nil, 244, nil, nil, nil, + nil, nil, 244, nil, nil, nil, nil, nil, nil, nil, + nil, 244, nil, nil, nil, nil, 244, 244, 244, 244, + nil, 244, 244, 244, 244, nil, nil, nil, nil, 244, + 244, nil, nil, nil, 245, 245, 245, 244, 245, 244, + 244, 244, 245, 245, nil, nil, nil, 245, nil, 245, + 245, 245, 245, 245, 245, 245, nil, nil, nil, nil, + nil, 245, 245, 245, 245, 245, 245, 245, nil, nil, + 245, nil, nil, nil, nil, nil, nil, 245, nil, nil, + 245, 245, 245, 245, 245, 245, 245, 245, nil, 245, + 245, 245, nil, 245, 245, 245, 245, 245, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 245, nil, nil, + 245, nil, nil, 245, 245, nil, nil, 245, nil, nil, + nil, nil, nil, 245, nil, nil, nil, nil, nil, nil, + nil, nil, 245, nil, nil, nil, nil, 245, 245, 245, + 245, nil, 245, 245, 245, 245, nil, nil, nil, nil, + 245, 245, nil, nil, nil, 246, 246, 246, 245, 246, + 245, 245, 245, 246, 246, nil, nil, nil, 246, nil, + 246, 246, 246, 246, 246, 246, 246, nil, nil, nil, + nil, nil, 246, 246, 246, 246, 246, 246, 246, nil, + nil, 246, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 246, 246, 246, 246, 246, 246, 246, 246, nil, + 246, 246, 246, nil, 246, 246, 246, 246, 246, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 246, nil, nil, 246, 246, nil, nil, 246, nil, + nil, nil, nil, nil, 246, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, nil, nil, 246, 246, + 246, 246, nil, 246, 246, 246, 246, nil, nil, nil, + nil, 246, 246, nil, nil, nil, 247, 247, 247, 246, + 247, 246, 246, 246, 247, 247, nil, nil, nil, 247, + nil, 247, 247, 247, 247, 247, 247, 247, nil, nil, + nil, nil, nil, 247, 247, 247, 247, 247, 247, 247, + nil, nil, 247, nil, nil, nil, nil, nil, nil, 247, + nil, nil, 247, 247, 247, 247, 247, 247, 247, 247, + nil, 247, 247, 247, nil, 247, 247, 247, 247, 247, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 247, + nil, nil, 247, nil, nil, 247, 247, nil, nil, 247, + nil, nil, nil, nil, nil, 247, nil, nil, nil, nil, + nil, nil, nil, nil, 247, nil, nil, nil, nil, 247, + 247, 247, 247, nil, 247, 247, 247, 247, nil, nil, + nil, nil, 247, 247, nil, nil, nil, 248, 248, 248, + 247, 248, 247, 247, 247, 248, 248, nil, nil, nil, + 248, nil, 248, 248, 248, 248, 248, 248, 248, nil, + nil, nil, nil, nil, 248, 248, 248, 248, 248, 248, + 248, nil, nil, 248, nil, nil, nil, nil, nil, nil, + 248, nil, nil, 248, 248, 248, 248, 248, 248, 248, + 248, nil, 248, 248, 248, nil, 248, 248, 248, 248, + 248, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 248, nil, nil, 248, nil, nil, 248, 248, nil, nil, + 248, nil, nil, nil, nil, nil, 248, nil, nil, nil, + nil, nil, nil, nil, nil, 248, nil, nil, nil, nil, + 248, 248, 248, 248, nil, 248, 248, 248, 248, nil, + nil, nil, nil, 248, 248, nil, nil, nil, 249, 249, + 249, 248, 249, 248, 248, 248, 249, 249, nil, nil, + nil, 249, nil, 249, 249, 249, 249, 249, 249, 249, + nil, nil, nil, nil, nil, 249, 249, 249, 249, 249, + 249, 249, nil, nil, 249, nil, nil, nil, nil, nil, + nil, 249, nil, nil, 249, 249, 249, 249, 249, 249, + 249, 249, nil, 249, 249, 249, nil, 249, 249, 249, + 249, 249, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 249, nil, nil, 249, nil, nil, 249, 249, nil, + nil, 249, nil, nil, nil, nil, nil, 249, nil, nil, + nil, nil, nil, nil, nil, nil, 249, nil, nil, nil, + nil, 249, 249, 249, 249, nil, 249, 249, 249, 249, + nil, nil, nil, nil, 249, 249, nil, nil, nil, 250, + 250, 250, 249, 250, 249, 249, 249, 250, 250, nil, + nil, nil, 250, nil, 250, 250, 250, 250, 250, 250, + 250, nil, nil, nil, nil, nil, 250, 250, 250, 250, + 250, 250, 250, nil, nil, 250, nil, nil, nil, nil, + nil, nil, 250, nil, nil, 250, 250, 250, 250, 250, + 250, 250, 250, nil, 250, 250, 250, nil, 250, 250, + 250, 250, 250, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 250, nil, nil, 250, nil, nil, 250, 250, + nil, nil, 250, nil, nil, nil, nil, nil, 250, nil, + nil, nil, nil, nil, nil, nil, nil, 250, nil, nil, + nil, nil, 250, 250, 250, 250, nil, 250, 250, 250, + 250, nil, nil, nil, nil, 250, 250, nil, nil, nil, + 251, 251, 251, 250, 251, 250, 250, 250, 251, 251, + nil, nil, nil, 251, nil, 251, 251, 251, 251, 251, + 251, 251, nil, nil, nil, nil, nil, 251, 251, 251, + 251, 251, 251, 251, nil, nil, 251, nil, nil, nil, + nil, nil, nil, 251, nil, nil, 251, 251, 251, 251, + 251, 251, 251, 251, nil, 251, 251, 251, nil, 251, + 251, 251, 251, 251, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, 251, nil, nil, 251, + 251, nil, nil, 251, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 251, 251, 251, 251, nil, 251, 251, + 251, 251, nil, nil, nil, nil, 251, 251, nil, nil, + nil, 252, 252, 252, 251, 252, 251, 251, 251, 252, + 252, nil, nil, nil, 252, nil, 252, 252, 252, 252, + 252, 252, 252, nil, nil, nil, nil, nil, 252, 252, + 252, 252, 252, 252, 252, nil, nil, 252, nil, nil, + nil, nil, nil, nil, 252, nil, nil, 252, 252, 252, + 252, 252, 252, 252, 252, nil, 252, 252, 252, nil, + 252, 252, 252, 252, 252, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 252, nil, nil, 252, nil, nil, + 252, 252, nil, nil, 252, nil, nil, nil, nil, nil, + 252, nil, nil, nil, nil, nil, nil, nil, nil, 252, + nil, nil, nil, nil, 252, 252, 252, 252, nil, 252, + 252, 252, 252, nil, nil, nil, nil, 252, 252, nil, + nil, nil, 253, 253, 253, 252, 253, 252, 252, 252, + 253, 253, nil, nil, nil, 253, nil, 253, 253, 253, + 253, 253, 253, 253, nil, nil, nil, nil, nil, 253, + 253, 253, 253, 253, 253, 253, nil, nil, 253, nil, + nil, nil, nil, nil, nil, 253, nil, nil, 253, 253, + 253, 253, 253, 253, 253, 253, nil, 253, 253, 253, + nil, 253, 253, 253, 253, 253, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 253, nil, nil, 253, nil, + nil, 253, 253, nil, nil, 253, nil, nil, nil, nil, + nil, 253, nil, nil, nil, nil, nil, nil, nil, nil, + 253, nil, nil, nil, nil, 253, 253, 253, 253, nil, + 253, 253, 253, 253, nil, nil, nil, nil, 253, 253, + nil, nil, nil, 254, 254, 254, 253, 254, 253, 253, + 253, 254, 254, nil, nil, nil, 254, nil, 254, 254, + 254, 254, 254, 254, 254, nil, nil, nil, nil, nil, + 254, 254, 254, 254, 254, 254, 254, nil, nil, 254, + nil, nil, nil, nil, nil, nil, 254, nil, nil, 254, + 254, 254, 254, 254, 254, 254, 254, nil, 254, 254, + 254, nil, 254, 254, 254, 254, 254, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 254, nil, nil, 254, + nil, nil, 254, 254, nil, nil, 254, nil, nil, nil, + nil, nil, 254, nil, nil, nil, nil, nil, nil, nil, + nil, 254, nil, nil, nil, nil, 254, 254, 254, 254, + nil, 254, 254, 254, 254, nil, nil, nil, nil, 254, + 254, nil, nil, nil, 255, 255, 255, 254, 255, 254, + 254, 254, 255, 255, nil, nil, nil, 255, nil, 255, + 255, 255, 255, 255, 255, 255, nil, nil, nil, nil, + nil, 255, 255, 255, 255, 255, 255, 255, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 255, nil, nil, + 255, 255, 255, 255, 255, 255, 255, 255, nil, 255, + 255, 255, nil, 255, 255, 255, 255, 255, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 255, nil, nil, + 255, nil, nil, 255, 255, nil, nil, 255, nil, nil, + nil, nil, nil, 255, nil, nil, nil, nil, nil, nil, + nil, nil, 255, nil, nil, nil, nil, 255, 255, 255, + 255, nil, 255, 255, 255, 255, nil, nil, nil, nil, + 255, 255, nil, nil, nil, 256, 256, 256, 255, 256, + 255, 255, 255, 256, 256, nil, nil, nil, 256, nil, + 256, 256, 256, 256, 256, 256, 256, nil, nil, nil, + nil, nil, 256, 256, 256, 256, 256, 256, 256, nil, + nil, 256, nil, nil, nil, nil, nil, nil, 256, nil, + nil, 256, 256, 256, 256, 256, 256, 256, 256, nil, + 256, 256, 256, nil, 256, 256, 256, 256, 256, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 256, nil, + nil, 256, nil, nil, 256, 256, nil, nil, 256, nil, + nil, nil, nil, nil, 256, nil, nil, nil, nil, nil, + nil, nil, nil, 256, nil, nil, nil, nil, 256, 256, + 256, 256, nil, 256, 256, 256, 256, nil, nil, nil, + nil, 256, 256, nil, nil, nil, 257, 257, 257, 256, + 257, 256, 256, 256, 257, 257, nil, nil, nil, 257, + nil, 257, 257, 257, 257, 257, 257, 257, nil, nil, + nil, nil, nil, 257, 257, 257, 257, 257, 257, 257, + nil, nil, 257, nil, nil, nil, nil, nil, nil, 257, + nil, nil, 257, 257, 257, 257, 257, 257, 257, 257, + nil, 257, 257, 257, nil, 257, 257, 257, 257, 257, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 257, + nil, nil, 257, nil, nil, 257, 257, nil, nil, 257, + nil, nil, nil, nil, nil, 257, nil, nil, nil, nil, + nil, nil, nil, nil, 257, nil, nil, nil, nil, 257, + 257, 257, 257, nil, 257, 257, 257, 257, nil, nil, + nil, nil, 257, 257, nil, nil, nil, 258, 258, 258, + 257, 258, 257, 257, 257, 258, 258, nil, nil, nil, + 258, nil, 258, 258, 258, 258, 258, 258, 258, nil, + nil, nil, nil, nil, 258, 258, 258, 258, 258, 258, + 258, nil, nil, 258, nil, nil, nil, nil, nil, nil, + 258, nil, nil, 258, 258, 258, 258, 258, 258, 258, + 258, nil, 258, 258, 258, nil, 258, 258, 258, 258, + 258, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 258, nil, nil, 258, nil, nil, 258, 258, nil, nil, + 258, nil, nil, nil, nil, nil, 258, nil, nil, nil, + nil, nil, nil, nil, nil, 258, nil, nil, nil, nil, + 258, 258, 258, 258, nil, 258, 258, 258, 258, nil, + nil, nil, nil, 258, 258, nil, nil, nil, 259, 259, + 259, 258, 259, 258, 258, 258, 259, 259, nil, nil, + nil, 259, nil, 259, 259, 259, 259, 259, 259, 259, + nil, nil, nil, nil, nil, 259, 259, 259, 259, 259, + 259, 259, nil, nil, 259, nil, nil, nil, nil, nil, + nil, 259, nil, nil, 259, 259, 259, 259, 259, 259, + 259, 259, nil, 259, 259, 259, nil, 259, 259, 259, + 259, 259, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 259, nil, nil, 259, nil, nil, 259, 259, nil, + nil, 259, nil, nil, nil, nil, nil, 259, nil, nil, + nil, nil, nil, nil, nil, nil, 259, nil, nil, nil, + nil, 259, 259, 259, 259, nil, 259, 259, 259, 259, + nil, nil, nil, nil, 259, 259, nil, nil, nil, 264, + 264, 264, 259, 264, 259, 259, 259, 264, 264, nil, + nil, nil, 264, nil, 264, 264, 264, 264, 264, 264, + 264, nil, nil, nil, nil, nil, 264, 264, 264, 264, + 264, 264, 264, nil, nil, 264, nil, nil, nil, nil, + nil, nil, 264, nil, nil, 264, 264, 264, 264, 264, + 264, 264, 264, nil, 264, 264, 264, nil, 264, 264, + 264, 264, 264, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 264, nil, nil, 264, nil, nil, 264, 264, + nil, nil, 264, nil, nil, nil, nil, nil, 264, nil, + nil, nil, nil, nil, nil, nil, nil, 264, nil, nil, + nil, nil, 264, 264, 264, 264, nil, 264, 264, 264, + 264, nil, nil, nil, nil, 264, 264, nil, nil, nil, + 271, 271, 271, 264, 271, 264, 264, 264, 271, 271, + nil, nil, nil, 271, nil, 271, 271, 271, 271, 271, + 271, 271, nil, nil, nil, nil, nil, 271, 271, 271, + 271, 271, 271, 271, nil, nil, 271, nil, nil, nil, + nil, nil, nil, 271, nil, nil, 271, 271, 271, 271, + 271, 271, 271, 271, 271, 271, 271, 271, nil, 271, + 271, 271, 271, 271, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 271, nil, nil, 271, nil, nil, 271, + 271, nil, nil, 271, nil, 271, nil, 271, nil, 271, + nil, nil, 271, nil, nil, nil, nil, nil, 271, nil, + nil, nil, nil, 271, 271, 271, 271, nil, 271, 271, + 271, 271, nil, nil, nil, nil, 271, 271, nil, nil, + nil, 272, 272, 272, 271, 272, 271, 271, 271, 272, + 272, nil, nil, nil, 272, nil, 272, 272, 272, 272, + 272, 272, 272, nil, nil, nil, nil, nil, 272, 272, + 272, 272, 272, 272, 272, nil, nil, 272, nil, nil, + nil, nil, nil, nil, 272, nil, nil, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, nil, + 272, 272, 272, 272, 272, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 272, nil, nil, 272, nil, nil, + 272, 272, nil, nil, 272, nil, 272, nil, 272, nil, + 272, nil, nil, 272, nil, nil, nil, nil, nil, 272, + nil, nil, nil, nil, 272, 272, 272, 272, nil, 272, + 272, 272, 272, nil, nil, nil, nil, 272, 272, nil, + nil, nil, 280, 280, 280, 272, 280, 272, 272, 272, + 280, 280, nil, nil, nil, 280, nil, 280, 280, 280, + 280, 280, 280, 280, nil, nil, nil, nil, nil, 280, + 280, 280, 280, 280, 280, 280, nil, nil, 280, nil, + nil, nil, nil, nil, nil, 280, nil, nil, 280, 280, + 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, + nil, 280, 280, 280, 280, 280, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 280, nil, nil, 280, nil, + nil, 280, 280, nil, nil, 280, nil, 280, nil, 280, + nil, 280, nil, nil, 280, nil, nil, nil, nil, nil, + 280, nil, nil, nil, nil, 280, 280, 280, 280, nil, + 280, 280, 280, 280, nil, nil, nil, nil, 280, 280, + 280, nil, nil, 287, 287, 287, 280, 287, 280, 280, + 280, 287, 287, nil, nil, nil, 287, nil, 287, 287, + 287, 287, 287, 287, 287, nil, nil, nil, nil, nil, + 287, 287, 287, 287, 287, 287, 287, nil, nil, 287, + nil, nil, nil, nil, nil, nil, 287, nil, nil, 287, + 287, 287, 287, 287, 287, 287, 287, nil, 287, 287, + 287, nil, 287, 287, 287, 287, 287, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 287, nil, nil, 287, + nil, nil, 287, 287, nil, nil, 287, nil, nil, nil, + nil, nil, 287, nil, nil, nil, nil, nil, nil, nil, + nil, 287, nil, nil, nil, nil, 287, 287, 287, 287, + nil, 287, 287, 287, 287, nil, nil, nil, nil, 287, + 287, nil, nil, nil, 289, 289, 289, 287, 289, 287, + 287, 287, 289, 289, nil, nil, nil, 289, nil, 289, + 289, 289, 289, 289, 289, 289, nil, nil, nil, nil, + nil, 289, 289, 289, 289, 289, 289, 289, nil, nil, + 289, nil, nil, nil, nil, nil, nil, 289, nil, nil, + 289, 289, 289, 289, 289, 289, 289, 289, nil, 289, + 289, 289, nil, 289, 289, 289, 289, 289, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 289, nil, nil, + 289, nil, nil, 289, 289, nil, nil, 289, nil, nil, + nil, nil, nil, 289, nil, nil, nil, nil, nil, nil, + nil, nil, 289, nil, nil, nil, nil, 289, 289, 289, + 289, nil, 289, 289, 289, 289, nil, nil, nil, nil, + 289, 289, nil, nil, nil, 292, 292, 292, 289, 292, + 289, 289, 289, 292, 292, nil, nil, nil, 292, nil, + 292, 292, 292, 292, 292, 292, 292, nil, nil, nil, + nil, nil, 292, 292, 292, 292, 292, 292, 292, nil, + nil, 292, nil, nil, nil, nil, nil, nil, 292, nil, + nil, 292, 292, 292, 292, 292, 292, 292, 292, nil, + 292, 292, 292, nil, 292, 292, 292, 292, 292, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 292, nil, + nil, 292, nil, nil, 292, 292, nil, nil, 292, nil, + nil, nil, nil, nil, 292, nil, nil, nil, nil, nil, + nil, nil, nil, 292, nil, nil, nil, nil, 292, 292, + 292, 292, nil, 292, 292, 292, 292, nil, nil, nil, + nil, 292, 292, nil, nil, nil, 293, 293, 293, 292, + 293, 292, 292, 292, 293, 293, nil, nil, nil, 293, + nil, 293, 293, 293, 293, 293, 293, 293, nil, nil, + nil, nil, nil, 293, 293, 293, 293, 293, 293, 293, + nil, nil, 293, nil, nil, nil, nil, nil, nil, 293, + nil, nil, 293, 293, 293, 293, 293, 293, 293, 293, + nil, 293, 293, 293, nil, 293, 293, 293, 293, 293, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 293, + nil, nil, 293, nil, nil, 293, 293, nil, nil, 293, + nil, nil, nil, nil, nil, 293, nil, nil, nil, nil, + nil, nil, nil, nil, 293, nil, nil, nil, nil, 293, + 293, 293, 293, nil, 293, 293, 293, 293, nil, nil, + nil, nil, 293, 293, nil, nil, nil, nil, nil, nil, + 293, nil, 293, 293, 293, 298, 298, 298, 298, 298, + nil, nil, nil, 298, 298, nil, nil, nil, 298, nil, + 298, 298, 298, 298, 298, 298, 298, nil, nil, nil, + nil, nil, 298, 298, 298, 298, 298, 298, 298, nil, + nil, 298, nil, nil, nil, nil, nil, 298, 298, nil, + 298, 298, 298, 298, 298, 298, 298, 298, 298, nil, + 298, 298, 298, nil, 298, 298, 298, 298, 298, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 298, nil, + nil, 298, nil, nil, 298, 298, nil, nil, 298, nil, + 298, nil, nil, nil, 298, nil, nil, nil, nil, nil, + nil, nil, nil, 298, nil, nil, nil, nil, 298, 298, + 298, 298, nil, 298, 298, 298, 298, nil, nil, nil, + nil, 298, 298, nil, nil, nil, 306, 306, 306, 298, + 306, 298, 298, 298, 306, 306, nil, nil, nil, 306, + nil, 306, 306, 306, 306, 306, 306, 306, nil, nil, + nil, nil, nil, 306, 306, 306, 306, 306, 306, 306, + nil, nil, 306, nil, nil, nil, nil, nil, nil, 306, + nil, nil, 306, 306, 306, 306, 306, 306, 306, 306, + nil, 306, 306, 306, nil, 306, 306, nil, nil, 306, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 306, + nil, nil, 306, nil, nil, 306, 306, nil, nil, 306, + nil, nil, 938, nil, 938, 938, 938, 938, 938, nil, + nil, nil, nil, nil, nil, nil, nil, 938, nil, 306, + 306, 306, 306, nil, 306, 306, 306, 306, nil, nil, + nil, nil, 306, 306, nil, nil, nil, 306, nil, 938, + 306, nil, 306, 306, 306, 323, 323, 323, nil, 323, + 938, 938, nil, 323, 323, 938, nil, nil, 323, nil, + 323, 323, 323, 323, 323, 323, 323, nil, nil, nil, + nil, nil, 323, 323, 323, 323, 323, 323, 323, nil, + nil, 323, nil, nil, nil, nil, nil, nil, 323, nil, + nil, 323, 323, 323, 323, 323, 323, 323, 323, nil, + 323, 323, 323, nil, 323, 323, nil, nil, 323, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 323, nil, + nil, 323, nil, nil, 323, 323, nil, nil, 323, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 323, 323, + 323, 323, nil, 323, 323, 323, 323, nil, nil, nil, + nil, 323, 323, nil, nil, nil, 330, 330, 330, 323, + 330, 323, 323, 323, 330, 330, nil, nil, nil, 330, + nil, 330, 330, 330, 330, 330, 330, 330, nil, nil, + nil, nil, nil, 330, 330, 330, 330, 330, 330, 330, + nil, nil, 330, nil, nil, nil, nil, nil, nil, 330, + nil, nil, 330, 330, 330, 330, 330, 330, 330, 330, + nil, 330, 330, 330, nil, 330, 330, 330, 330, 330, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 330, + nil, nil, 330, nil, nil, 330, 330, nil, nil, 330, + nil, nil, nil, nil, nil, 330, nil, nil, nil, nil, + nil, nil, nil, nil, 330, nil, nil, nil, nil, 330, + 330, 330, 330, nil, 330, 330, 330, 330, nil, nil, + nil, nil, 330, 330, nil, nil, nil, 332, 332, 332, + 330, 332, 330, 330, 330, 332, 332, nil, nil, nil, + 332, nil, 332, 332, 332, 332, 332, 332, 332, nil, + nil, nil, nil, nil, 332, 332, 332, 332, 332, 332, + 332, nil, nil, 332, nil, nil, nil, nil, nil, nil, + 332, nil, nil, 332, 332, 332, 332, 332, 332, 332, + 332, nil, 332, 332, 332, nil, 332, 332, 332, 332, + 332, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 332, nil, nil, 332, 332, nil, 332, 332, nil, nil, + 332, nil, nil, nil, nil, nil, 332, nil, nil, nil, + nil, nil, nil, nil, nil, 332, nil, nil, nil, nil, + 332, 332, 332, 332, nil, 332, 332, 332, 332, nil, + nil, nil, nil, 332, 332, nil, nil, nil, 348, 348, + 348, 332, 348, 332, 332, 332, 348, 348, nil, nil, + nil, 348, nil, 348, 348, 348, 348, 348, 348, 348, + nil, nil, nil, nil, nil, 348, 348, 348, 348, 348, + 348, 348, nil, nil, 348, nil, nil, nil, nil, nil, + nil, 348, nil, nil, 348, 348, 348, 348, 348, 348, + 348, 348, nil, 348, 348, 348, nil, 348, 348, 348, + 348, 348, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 348, nil, nil, 348, nil, nil, 348, 348, nil, + nil, 348, nil, nil, nil, nil, nil, 348, nil, nil, + nil, nil, nil, nil, nil, nil, 348, nil, nil, nil, + nil, 348, 348, 348, 348, nil, 348, 348, 348, 348, + nil, nil, nil, nil, 348, 348, nil, nil, nil, 369, + 369, 369, 348, 369, 348, 348, 348, 369, 369, nil, + nil, nil, 369, nil, 369, 369, 369, 369, 369, 369, + 369, nil, nil, nil, nil, nil, 369, 369, 369, 369, + 369, 369, 369, nil, nil, 369, nil, nil, nil, nil, + nil, nil, 369, nil, nil, 369, 369, 369, 369, 369, + 369, 369, 369, nil, 369, 369, 369, nil, 369, 369, + 369, 369, 369, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 369, nil, nil, 369, nil, nil, 369, 369, + nil, nil, 369, nil, nil, nil, nil, nil, 369, nil, + nil, nil, nil, nil, nil, nil, nil, 369, nil, nil, + nil, nil, 369, 369, 369, 369, nil, 369, 369, 369, + 369, nil, nil, nil, nil, 369, 369, nil, nil, nil, + 385, 385, 385, 369, 385, 369, 369, 369, 385, 385, + nil, nil, nil, 385, nil, 385, 385, 385, 385, 385, + 385, 385, nil, nil, nil, nil, nil, 385, 385, 385, + 385, 385, 385, 385, nil, nil, 385, nil, nil, nil, + nil, nil, nil, 385, nil, nil, 385, 385, 385, 385, + 385, 385, 385, 385, nil, 385, 385, 385, nil, 385, + 385, 385, 385, 385, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 385, nil, nil, 385, nil, nil, 385, + 385, nil, nil, 385, nil, nil, nil, nil, nil, 385, + nil, nil, nil, nil, nil, nil, nil, nil, 385, nil, + nil, nil, nil, 385, 385, 385, 385, nil, 385, 385, + 385, 385, nil, nil, nil, nil, 385, 385, nil, nil, + nil, 413, 413, 413, 385, 413, 385, 385, 385, 413, + 413, nil, nil, nil, 413, nil, 413, 413, 413, 413, + 413, 413, 413, nil, nil, nil, nil, nil, 413, 413, + 413, 413, 413, 413, 413, nil, nil, 413, nil, nil, + nil, nil, nil, nil, 413, nil, nil, 413, 413, 413, + 413, 413, 413, 413, 413, nil, 413, 413, 413, nil, + 413, 413, 413, 413, 413, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 413, nil, nil, 413, nil, nil, + 413, 413, nil, nil, 413, nil, nil, nil, nil, nil, + 413, nil, nil, nil, nil, nil, nil, nil, nil, 413, + nil, nil, nil, nil, 413, 413, 413, 413, nil, 413, + 413, 413, 413, nil, nil, nil, nil, 413, 413, nil, + nil, nil, 456, 456, 456, 413, 456, 413, 413, 413, + 456, 456, nil, nil, nil, 456, nil, 456, 456, 456, + 456, 456, 456, 456, nil, nil, nil, nil, nil, 456, + 456, 456, 456, 456, 456, 456, nil, nil, 456, nil, + nil, nil, nil, nil, nil, 456, nil, nil, 456, 456, + 456, 456, 456, 456, 456, 456, 456, 456, 456, 456, + nil, 456, 456, 456, 456, 456, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 456, nil, nil, 456, nil, + nil, 456, 456, nil, nil, 456, nil, 456, nil, 456, + nil, 456, nil, nil, 456, nil, nil, nil, nil, nil, + 456, nil, nil, nil, nil, 456, 456, 456, 456, nil, + 456, 456, 456, 456, nil, nil, nil, nil, 456, 456, + nil, nil, nil, 458, 458, 458, 456, 458, 456, 456, + 456, 458, 458, nil, nil, nil, 458, nil, 458, 458, + 458, 458, 458, 458, 458, nil, nil, nil, nil, nil, + 458, 458, 458, 458, 458, 458, 458, nil, nil, 458, + nil, nil, nil, nil, nil, nil, 458, nil, nil, 458, + 458, 458, 458, 458, 458, 458, 458, nil, 458, 458, + 458, nil, 458, 458, 458, 458, 458, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 458, nil, nil, 458, + nil, nil, 458, 458, nil, nil, 458, nil, nil, nil, + nil, nil, 458, nil, nil, nil, nil, nil, nil, nil, + nil, 458, nil, nil, nil, nil, 458, 458, 458, 458, + nil, 458, 458, 458, 458, nil, nil, nil, nil, 458, + 458, nil, nil, nil, 459, 459, 459, 458, 459, 458, + 458, 458, 459, 459, nil, nil, nil, 459, nil, 459, + 459, 459, 459, 459, 459, 459, nil, nil, nil, nil, + nil, 459, 459, 459, 459, 459, 459, 459, nil, nil, + 459, nil, nil, nil, nil, nil, nil, 459, nil, nil, + 459, 459, 459, 459, 459, 459, 459, 459, nil, 459, + 459, 459, nil, 459, 459, 459, 459, 459, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 459, nil, nil, + 459, nil, nil, 459, 459, nil, nil, 459, nil, nil, + nil, nil, nil, 459, nil, nil, nil, nil, nil, nil, + nil, nil, 459, nil, nil, nil, nil, 459, 459, 459, + 459, nil, 459, 459, 459, 459, nil, nil, nil, nil, + 459, 459, nil, nil, nil, 460, 460, 460, 459, 460, + 459, 459, 459, 460, 460, nil, nil, nil, 460, nil, + 460, 460, 460, 460, 460, 460, 460, nil, nil, nil, + nil, nil, 460, 460, 460, 460, 460, 460, 460, nil, + nil, 460, nil, nil, nil, nil, nil, nil, 460, nil, + nil, 460, 460, 460, 460, 460, 460, 460, 460, nil, + 460, 460, 460, nil, 460, 460, 460, 460, 460, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 460, nil, + nil, 460, nil, nil, 460, 460, nil, nil, 460, nil, + nil, nil, nil, nil, 460, nil, nil, nil, nil, nil, + nil, nil, nil, 460, nil, nil, nil, nil, 460, 460, + 460, 460, nil, 460, 460, 460, 460, nil, nil, nil, + nil, 460, 460, nil, nil, nil, 497, 497, 497, 460, + 497, 460, 460, 460, 497, 497, nil, nil, nil, 497, + nil, 497, 497, 497, 497, 497, 497, 497, nil, nil, + nil, nil, nil, 497, 497, 497, 497, 497, 497, 497, + nil, nil, 497, nil, nil, nil, nil, nil, nil, 497, + nil, nil, 497, 497, 497, 497, 497, 497, 497, 497, + 497, 497, 497, 497, nil, 497, 497, 497, 497, 497, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 497, + nil, nil, 497, nil, nil, 497, 497, nil, nil, 497, + nil, 497, nil, 497, nil, 497, nil, nil, 497, nil, + nil, nil, nil, nil, 497, nil, nil, nil, nil, 497, + 497, 497, 497, nil, 497, 497, 497, 497, nil, nil, + nil, nil, 497, 497, nil, nil, nil, 499, 499, 499, + 497, 499, 497, 497, 497, 499, 499, nil, nil, nil, + 499, nil, 499, 499, 499, 499, 499, 499, 499, nil, + nil, nil, nil, nil, 499, 499, 499, 499, 499, 499, + 499, nil, nil, 499, nil, nil, nil, nil, nil, nil, + 499, nil, nil, 499, 499, 499, 499, 499, 499, 499, + 499, 499, 499, 499, 499, nil, 499, 499, 499, 499, + 499, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 499, nil, nil, 499, nil, nil, 499, 499, nil, nil, + 499, nil, nil, nil, 499, nil, 499, nil, nil, 499, + nil, nil, nil, nil, nil, 499, nil, nil, nil, nil, + 499, 499, 499, 499, nil, 499, 499, 499, 499, nil, + nil, nil, nil, 499, 499, nil, nil, nil, 501, 501, + 501, 499, 501, 499, 499, 499, 501, 501, nil, nil, + nil, 501, nil, 501, 501, 501, 501, 501, 501, 501, + nil, nil, nil, nil, nil, 501, 501, 501, 501, 501, + 501, 501, nil, nil, 501, nil, nil, nil, nil, nil, + nil, 501, nil, nil, 501, 501, 501, 501, 501, 501, + 501, 501, nil, 501, 501, 501, nil, 501, 501, 501, + 501, 501, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 501, nil, nil, 501, nil, nil, 501, 501, nil, + nil, 501, nil, nil, nil, nil, nil, 501, nil, nil, + nil, nil, nil, nil, nil, nil, 501, nil, nil, nil, + nil, 501, 501, 501, 501, nil, 501, 501, 501, 501, + nil, nil, nil, nil, 501, 501, nil, nil, nil, nil, + nil, nil, 501, nil, 501, 501, 501, 507, 507, 507, + 507, 507, nil, nil, nil, 507, 507, nil, nil, nil, + 507, nil, 507, 507, 507, 507, 507, 507, 507, nil, + nil, nil, nil, nil, 507, 507, 507, 507, 507, 507, + 507, nil, nil, 507, nil, nil, nil, nil, nil, 507, + 507, 507, 507, 507, 507, 507, 507, 507, 507, 507, + 507, nil, 507, 507, 507, nil, 507, 507, 507, 507, + 507, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 507, nil, nil, 507, nil, nil, 507, 507, nil, nil, + 507, nil, 507, nil, nil, nil, 507, nil, nil, nil, + nil, nil, nil, nil, nil, 507, nil, nil, nil, nil, + 507, 507, 507, 507, nil, 507, 507, 507, 507, nil, + nil, nil, nil, 507, 507, nil, nil, nil, nil, nil, + 507, 507, nil, 507, 507, 507, 515, 515, 515, nil, + 515, nil, nil, nil, 515, 515, nil, nil, nil, 515, + nil, 515, 515, 515, 515, 515, 515, 515, nil, nil, + nil, nil, nil, 515, 515, 515, 515, 515, 515, 515, + nil, nil, 515, nil, nil, nil, nil, nil, nil, 515, + nil, nil, 515, 515, 515, 515, 515, 515, 515, 515, + nil, 515, 515, 515, nil, 515, 515, nil, nil, 515, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 515, + nil, nil, 515, nil, nil, 515, 515, nil, nil, 515, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 515, + 515, 515, 515, nil, 515, 515, 515, 515, nil, nil, + nil, nil, 515, 515, nil, nil, nil, 517, 517, 517, + 515, 517, 515, 515, 515, 517, 517, nil, nil, nil, + 517, nil, 517, 517, 517, 517, 517, 517, 517, nil, + nil, nil, nil, nil, 517, 517, 517, 517, 517, 517, + 517, nil, nil, 517, nil, nil, nil, nil, nil, nil, + 517, nil, nil, 517, 517, 517, 517, 517, 517, 517, + 517, 517, 517, 517, 517, nil, 517, 517, 517, 517, + 517, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 517, nil, nil, 517, nil, nil, 517, 517, nil, nil, + 517, nil, 517, nil, 517, nil, 517, nil, nil, 517, + nil, nil, nil, nil, nil, 517, nil, nil, nil, nil, + 517, 517, 517, 517, nil, 517, 517, 517, 517, nil, + nil, nil, nil, 517, 517, nil, nil, nil, 523, 523, + 523, 517, 523, 517, 517, 517, 523, 523, nil, nil, + nil, 523, nil, 523, 523, 523, 523, 523, 523, 523, + nil, nil, nil, nil, nil, 523, 523, 523, 523, 523, + 523, 523, nil, nil, 523, nil, nil, nil, nil, nil, + nil, 523, nil, nil, 523, 523, 523, 523, 523, 523, + 523, 523, nil, 523, 523, 523, nil, 523, 523, nil, + nil, 523, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 523, nil, nil, 523, nil, nil, 523, 523, nil, + nil, 523, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 523, 523, 523, 523, nil, 523, 523, 523, 523, + nil, nil, nil, nil, 523, 523, nil, nil, nil, 526, + 526, 526, 523, 526, 523, 523, 523, 526, 526, nil, + nil, nil, 526, nil, 526, 526, 526, 526, 526, 526, + 526, nil, nil, nil, nil, nil, 526, 526, 526, 526, + 526, 526, 526, nil, nil, 526, nil, nil, nil, nil, + nil, nil, 526, nil, nil, 526, 526, 526, 526, 526, + 526, 526, 526, nil, 526, 526, 526, nil, 526, 526, + 526, 526, 526, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 526, nil, nil, 526, nil, nil, 526, 526, + nil, nil, 526, nil, nil, nil, nil, nil, 526, nil, + nil, nil, nil, nil, nil, nil, nil, 526, nil, nil, + nil, nil, 526, 526, 526, 526, nil, 526, 526, 526, + 526, nil, nil, nil, nil, 526, 526, nil, nil, nil, + 527, 527, 527, 526, 527, 526, 526, 526, 527, 527, + nil, nil, nil, 527, nil, 527, 527, 527, 527, 527, + 527, 527, nil, nil, nil, nil, nil, 527, 527, 527, + 527, 527, 527, 527, nil, nil, 527, nil, nil, nil, + nil, nil, nil, 527, nil, nil, 527, 527, 527, 527, + 527, 527, 527, 527, nil, 527, 527, 527, nil, 527, + 527, 527, 527, 527, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 527, nil, nil, 527, nil, nil, 527, + 527, nil, nil, 527, nil, nil, nil, nil, nil, 527, + nil, nil, nil, nil, nil, nil, nil, nil, 527, nil, + nil, nil, nil, 527, 527, 527, 527, nil, 527, 527, + 527, 527, nil, nil, nil, nil, 527, 527, nil, nil, + nil, 532, 532, 532, 527, 532, 527, 527, 527, 532, + 532, nil, nil, nil, 532, nil, 532, 532, 532, 532, + 532, 532, 532, nil, nil, nil, nil, nil, 532, 532, + 532, 532, 532, 532, 532, nil, nil, 532, nil, nil, + nil, nil, nil, nil, 532, nil, nil, 532, 532, 532, + 532, 532, 532, 532, 532, nil, 532, 532, 532, nil, + 532, 532, 532, 532, 532, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 532, nil, nil, 532, nil, nil, + 532, 532, nil, nil, 532, nil, nil, nil, nil, nil, + 532, nil, nil, nil, nil, nil, nil, nil, nil, 532, + nil, nil, nil, nil, 532, 532, 532, 532, nil, 532, + 532, 532, 532, nil, nil, nil, nil, 532, 532, nil, + nil, nil, 538, 538, 538, 532, 538, 532, 532, 532, + 538, 538, nil, nil, nil, 538, nil, 538, 538, 538, + 538, 538, 538, 538, nil, nil, nil, nil, nil, 538, + 538, 538, 538, 538, 538, 538, nil, nil, 538, nil, + nil, nil, nil, nil, nil, 538, nil, nil, 538, 538, + 538, 538, 538, 538, 538, 538, 538, 538, 538, 538, + nil, 538, 538, 538, 538, 538, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 538, nil, nil, 538, nil, + nil, 538, 538, nil, nil, 538, nil, 538, nil, nil, + nil, 538, nil, nil, 538, nil, nil, nil, nil, nil, + 538, nil, nil, nil, nil, 538, 538, 538, 538, nil, + 538, 538, 538, 538, nil, nil, nil, nil, 538, 538, + nil, nil, nil, 541, 541, 541, 538, 541, 538, 538, + 538, 541, 541, nil, nil, nil, 541, nil, 541, 541, + 541, 541, 541, 541, 541, nil, nil, nil, nil, nil, + 541, 541, 541, 541, 541, 541, 541, nil, nil, 541, + nil, nil, nil, nil, nil, nil, 541, nil, nil, 541, + 541, 541, 541, 541, 541, 541, 541, 541, 541, 541, + 541, nil, 541, 541, 541, 541, 541, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 541, nil, nil, 541, + nil, nil, 541, 541, nil, nil, 541, nil, nil, nil, + nil, nil, 541, nil, nil, 541, nil, nil, nil, nil, + nil, 541, nil, nil, nil, nil, 541, 541, 541, 541, + nil, 541, 541, 541, 541, nil, nil, nil, nil, 541, + 541, nil, nil, nil, 556, 556, 556, 541, 556, 541, + 541, 541, 556, 556, nil, nil, nil, 556, nil, 556, + 556, 556, 556, 556, 556, 556, nil, nil, nil, nil, + nil, 556, 556, 556, 556, 556, 556, 556, nil, nil, + 556, nil, nil, nil, nil, nil, nil, 556, nil, nil, + 556, 556, 556, 556, 556, 556, 556, 556, nil, 556, + 556, 556, nil, 556, 556, 556, 556, 556, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 556, nil, nil, + 556, nil, nil, 556, 556, nil, nil, 556, nil, 556, + nil, nil, nil, 556, nil, nil, nil, nil, nil, nil, + nil, nil, 556, nil, nil, nil, nil, 556, 556, 556, + 556, nil, 556, 556, 556, 556, nil, nil, nil, nil, + 556, 556, nil, nil, nil, 557, 557, 557, 556, 557, + 556, 556, 556, 557, 557, nil, nil, nil, 557, nil, + 557, 557, 557, 557, 557, 557, 557, nil, nil, nil, + nil, nil, 557, 557, 557, 557, 557, 557, 557, nil, + nil, 557, nil, nil, nil, nil, nil, nil, 557, nil, + nil, 557, 557, 557, 557, 557, 557, 557, 557, 557, + 557, 557, 557, nil, 557, 557, 557, 557, 557, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 557, nil, + nil, 557, nil, nil, 557, 557, nil, nil, 557, nil, + 557, nil, 557, nil, 557, nil, nil, 557, nil, nil, + nil, nil, nil, 557, nil, nil, nil, nil, 557, 557, + 557, 557, nil, 557, 557, 557, 557, nil, nil, nil, + nil, 557, 557, nil, nil, nil, 567, 567, 567, 557, + 567, 557, 557, 557, 567, 567, nil, nil, nil, 567, + nil, 567, 567, 567, 567, 567, 567, 567, nil, nil, + nil, nil, nil, 567, 567, 567, 567, 567, 567, 567, + nil, nil, 567, nil, nil, nil, nil, nil, nil, 567, + nil, nil, 567, 567, 567, 567, 567, 567, 567, 567, + 567, 567, 567, 567, nil, 567, 567, 567, 567, 567, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 567, + nil, nil, 567, nil, nil, 567, 567, nil, nil, 567, + nil, 567, nil, 567, nil, 567, nil, nil, 567, nil, + nil, nil, nil, nil, 567, nil, nil, nil, nil, 567, + 567, 567, 567, nil, 567, 567, 567, 567, nil, nil, + nil, nil, 567, 567, nil, nil, nil, 599, 599, 599, + 567, 599, 567, 567, 567, 599, 599, nil, nil, nil, + 599, nil, 599, 599, 599, 599, 599, 599, 599, nil, + nil, nil, nil, nil, 599, 599, 599, 599, 599, 599, + 599, nil, nil, 599, nil, nil, nil, nil, nil, nil, + 599, nil, nil, 599, 599, 599, 599, 599, 599, 599, + 599, nil, 599, 599, 599, nil, 599, 599, 599, 599, + 599, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 599, nil, nil, 599, nil, nil, 599, 599, nil, nil, + 599, nil, 599, nil, nil, nil, 599, nil, nil, nil, + nil, nil, nil, nil, nil, 599, nil, nil, nil, nil, + 599, 599, 599, 599, nil, 599, 599, 599, 599, nil, + nil, nil, nil, 599, 599, nil, nil, nil, 600, 600, + 600, 599, 600, 599, 599, 599, 600, 600, nil, nil, + nil, 600, nil, 600, 600, 600, 600, 600, 600, 600, + nil, nil, nil, nil, nil, 600, 600, 600, 600, 600, + 600, 600, nil, nil, 600, nil, nil, nil, nil, nil, + nil, 600, nil, nil, 600, 600, 600, 600, 600, 600, + 600, 600, nil, 600, 600, 600, nil, 600, 600, 600, + 600, 600, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 600, nil, nil, 600, nil, nil, 600, 600, nil, + nil, 600, nil, nil, nil, nil, nil, 600, nil, nil, + nil, nil, nil, nil, nil, nil, 600, nil, nil, nil, + nil, 600, 600, 600, 600, nil, 600, 600, 600, 600, + nil, nil, nil, nil, 600, 600, nil, nil, nil, 601, + 601, 601, 600, 601, 600, 600, 600, 601, 601, nil, + nil, nil, 601, nil, 601, 601, 601, 601, 601, 601, + 601, nil, nil, nil, nil, nil, 601, 601, 601, 601, + 601, 601, 601, nil, nil, 601, nil, nil, nil, nil, + nil, nil, 601, nil, nil, 601, 601, 601, 601, 601, + 601, 601, 601, 601, 601, 601, 601, nil, 601, 601, + 601, 601, 601, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 601, nil, nil, 601, nil, nil, 601, 601, + nil, nil, 601, nil, 601, nil, 601, nil, 601, nil, + nil, 601, nil, nil, nil, nil, nil, 601, nil, nil, + nil, nil, 601, 601, 601, 601, nil, 601, 601, 601, + 601, nil, nil, nil, nil, 601, 601, nil, nil, nil, + nil, nil, nil, 601, nil, 601, 601, 601, 604, 604, + 604, 604, 604, nil, nil, nil, 604, 604, nil, nil, + nil, 604, nil, 604, 604, 604, 604, 604, 604, 604, + nil, nil, nil, nil, nil, 604, 604, 604, 604, 604, + 604, 604, nil, nil, 604, nil, nil, nil, nil, nil, + 604, 604, nil, 604, 604, 604, 604, 604, 604, 604, + 604, 604, nil, 604, 604, 604, nil, 604, 604, 604, + 604, 604, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 604, nil, nil, 604, nil, nil, 604, 604, nil, + nil, 604, nil, 604, nil, nil, nil, 604, nil, nil, + nil, nil, nil, nil, nil, nil, 604, nil, nil, nil, + nil, 604, 604, 604, 604, nil, 604, 604, 604, 604, + nil, nil, nil, nil, 604, 604, nil, nil, nil, 605, + 605, 605, 604, 605, 604, 604, 604, 605, 605, nil, + nil, nil, 605, nil, 605, 605, 605, 605, 605, 605, + 605, nil, nil, nil, nil, nil, 605, 605, 605, 605, + 605, 605, 605, nil, nil, 605, nil, nil, nil, nil, + nil, nil, 605, nil, nil, 605, 605, 605, 605, 605, + 605, 605, 605, nil, 605, 605, 605, nil, 605, 605, + 605, 605, 605, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 605, nil, nil, 605, nil, nil, 605, 605, + nil, nil, 605, nil, nil, nil, nil, nil, 605, nil, + nil, nil, nil, nil, nil, nil, nil, 605, nil, nil, + nil, nil, 605, 605, 605, 605, nil, 605, 605, 605, + 605, nil, nil, nil, nil, 605, 605, nil, nil, nil, + 608, 608, 608, 605, 608, 605, 605, 605, 608, 608, + nil, nil, nil, 608, nil, 608, 608, 608, 608, 608, + 608, 608, nil, nil, nil, nil, nil, 608, 608, 608, + 608, 608, 608, 608, nil, nil, 608, nil, nil, nil, + nil, nil, nil, 608, nil, nil, 608, 608, 608, 608, + 608, 608, 608, 608, 608, 608, 608, 608, nil, 608, + 608, 608, 608, 608, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 608, nil, nil, 608, nil, nil, 608, + 608, nil, nil, 608, nil, 608, nil, 608, nil, 608, + nil, nil, 608, nil, nil, nil, nil, nil, 608, nil, + nil, nil, nil, 608, 608, 608, 608, nil, 608, 608, + 608, 608, nil, nil, nil, nil, 608, 608, nil, nil, + nil, 609, 609, 609, 608, 609, 608, 608, 608, 609, + 609, nil, nil, nil, 609, nil, 609, 609, 609, 609, + 609, 609, 609, nil, nil, nil, nil, nil, 609, 609, + 609, 609, 609, 609, 609, nil, nil, 609, nil, nil, + nil, nil, nil, nil, 609, nil, nil, 609, 609, 609, + 609, 609, 609, 609, 609, 609, 609, 609, 609, nil, + 609, 609, 609, 609, 609, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 609, nil, nil, 609, nil, nil, + 609, 609, nil, nil, 609, nil, nil, nil, 609, nil, + 609, nil, nil, 609, nil, nil, nil, nil, nil, 609, + nil, nil, nil, nil, 609, 609, 609, 609, nil, 609, + 609, 609, 609, nil, nil, nil, nil, 609, 609, nil, + nil, nil, 610, 610, 610, 609, 610, 609, 609, 609, + 610, 610, nil, nil, nil, 610, nil, 610, 610, 610, + 610, 610, 610, 610, nil, nil, nil, nil, nil, 610, + 610, 610, 610, 610, 610, 610, nil, nil, 610, nil, + nil, nil, nil, nil, nil, 610, nil, nil, 610, 610, + 610, 610, 610, 610, 610, 610, nil, 610, 610, 610, + nil, 610, 610, 610, 610, 610, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 610, nil, nil, 610, nil, + nil, 610, 610, nil, nil, 610, nil, nil, nil, nil, + nil, 610, nil, nil, nil, nil, nil, nil, nil, nil, + 610, nil, nil, nil, nil, 610, 610, 610, 610, nil, + 610, 610, 610, 610, nil, nil, nil, nil, 610, 610, + nil, nil, nil, 611, 611, 611, 610, 611, 610, 610, + 610, 611, 611, nil, nil, nil, 611, nil, 611, 611, + 611, 611, 611, 611, 611, nil, nil, nil, nil, nil, + 611, 611, 611, 611, 611, 611, 611, nil, nil, 611, + nil, nil, nil, nil, nil, nil, 611, nil, nil, 611, + 611, 611, 611, 611, 611, 611, 611, nil, 611, 611, + 611, nil, 611, 611, 611, 611, 611, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 611, nil, nil, 611, + nil, nil, 611, 611, nil, nil, 611, nil, nil, nil, + nil, nil, 611, nil, nil, nil, nil, nil, nil, nil, + nil, 611, nil, nil, nil, nil, 611, 611, 611, 611, + nil, 611, 611, 611, 611, nil, nil, nil, nil, 611, + 611, nil, nil, nil, 615, 615, 615, 611, 615, 611, + 611, 611, 615, 615, nil, nil, nil, 615, nil, 615, + 615, 615, 615, 615, 615, 615, nil, nil, nil, nil, + nil, 615, 615, 615, 615, 615, 615, 615, nil, nil, + 615, nil, nil, nil, nil, nil, nil, 615, nil, nil, + 615, 615, 615, 615, 615, 615, 615, 615, nil, 615, + 615, 615, nil, 615, 615, 615, 615, 615, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 615, nil, nil, + 615, nil, nil, 615, 615, nil, nil, 615, nil, nil, + nil, nil, nil, 615, nil, nil, nil, nil, nil, nil, + nil, nil, 615, nil, nil, nil, nil, 615, 615, 615, + 615, nil, 615, 615, 615, 615, nil, nil, nil, nil, + 615, 615, nil, nil, nil, 616, 616, 616, 615, 616, + 615, 615, 615, 616, 616, nil, nil, nil, 616, nil, + 616, 616, 616, 616, 616, 616, 616, nil, nil, nil, + nil, nil, 616, 616, 616, 616, 616, 616, 616, nil, + nil, 616, nil, nil, nil, nil, nil, nil, 616, nil, + nil, 616, 616, 616, 616, 616, 616, 616, 616, nil, + 616, 616, 616, nil, 616, 616, 616, 616, 616, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 616, nil, + nil, 616, nil, nil, 616, 616, nil, nil, 616, nil, + nil, nil, nil, nil, 616, nil, nil, nil, nil, nil, + nil, nil, nil, 616, nil, nil, nil, nil, 616, 616, + 616, 616, nil, 616, 616, 616, 616, nil, nil, nil, + nil, 616, 616, nil, nil, nil, 640, 640, 640, 616, + 640, 616, 616, 616, 640, 640, nil, nil, nil, 640, + nil, 640, 640, 640, 640, 640, 640, 640, nil, nil, + nil, nil, nil, 640, 640, 640, 640, 640, 640, 640, + nil, nil, 640, nil, nil, nil, nil, nil, nil, 640, + nil, nil, 640, 640, 640, 640, 640, 640, 640, 640, + nil, 640, 640, 640, nil, 640, 640, 640, 640, 640, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 640, + nil, nil, 640, nil, nil, 640, 640, nil, nil, 640, + nil, nil, nil, nil, nil, 640, nil, nil, nil, nil, + nil, nil, nil, nil, 640, nil, nil, nil, nil, 640, + 640, 640, 640, nil, 640, 640, 640, 640, nil, nil, + nil, nil, 640, 640, nil, nil, nil, 643, 643, 643, + 640, 643, 640, 640, 640, 643, 643, nil, nil, nil, + 643, nil, 643, 643, 643, 643, 643, 643, 643, nil, + nil, nil, nil, nil, 643, 643, 643, 643, 643, 643, + 643, nil, nil, 643, nil, nil, nil, nil, nil, nil, + 643, nil, nil, 643, 643, 643, 643, 643, 643, 643, + 643, nil, 643, 643, 643, nil, 643, 643, 643, 643, + 643, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 643, nil, nil, 643, nil, nil, 643, 643, nil, nil, + 643, nil, nil, nil, nil, nil, 643, nil, nil, nil, + nil, nil, nil, nil, nil, 643, nil, nil, nil, nil, + 643, 643, 643, 643, nil, 643, 643, 643, 643, nil, + nil, nil, nil, 643, 643, nil, nil, nil, 646, 646, + 646, 643, 646, 643, 643, 643, 646, 646, nil, nil, + nil, 646, nil, 646, 646, 646, 646, 646, 646, 646, + nil, nil, nil, nil, nil, 646, 646, 646, 646, 646, + 646, 646, nil, nil, 646, nil, nil, nil, nil, nil, + nil, 646, nil, nil, 646, 646, 646, 646, 646, 646, + 646, 646, nil, 646, 646, 646, nil, 646, 646, nil, + nil, 646, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 646, nil, nil, 646, nil, nil, 646, 646, nil, + nil, 646, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 646, 646, 646, 646, nil, 646, 646, 646, 646, + nil, nil, nil, nil, 646, 646, nil, nil, nil, 657, + 657, 657, 646, 657, 646, 646, 646, 657, 657, nil, + nil, nil, 657, nil, 657, 657, 657, 657, 657, 657, + 657, nil, nil, nil, nil, nil, 657, 657, 657, 657, + 657, 657, 657, nil, nil, 657, nil, nil, nil, nil, + nil, nil, 657, nil, nil, 657, 657, 657, 657, 657, + 657, 657, 657, nil, 657, 657, 657, nil, 657, 657, + nil, nil, 657, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 657, nil, nil, 657, nil, nil, 657, 657, + nil, nil, 657, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 657, 657, 657, 657, nil, 657, 657, 657, + 657, nil, nil, nil, nil, 657, 657, nil, nil, nil, + 662, 662, 662, 657, 662, 657, 657, 657, 662, 662, + nil, nil, nil, 662, nil, 662, 662, 662, 662, 662, + 662, 662, nil, nil, nil, nil, nil, 662, 662, 662, + 662, 662, 662, 662, nil, nil, 662, nil, nil, nil, + nil, nil, nil, 662, nil, nil, 662, 662, 662, 662, + 662, 662, 662, 662, nil, 662, 662, 662, nil, 662, + 662, 662, 662, 662, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 662, nil, nil, 662, nil, nil, 662, + 662, nil, nil, 662, nil, 662, nil, nil, nil, 662, + nil, nil, nil, nil, nil, nil, nil, nil, 662, nil, + nil, nil, nil, 662, 662, 662, 662, nil, 662, 662, + 662, 662, nil, nil, nil, nil, 662, 662, nil, nil, + nil, 688, 688, 688, 662, 688, 662, 662, 662, 688, + 688, nil, nil, nil, 688, nil, 688, 688, 688, 688, + 688, 688, 688, nil, nil, nil, nil, nil, 688, 688, + 688, 688, 688, 688, 688, nil, nil, 688, nil, nil, + nil, nil, nil, nil, 688, nil, nil, 688, 688, 688, + 688, 688, 688, 688, 688, nil, 688, 688, 688, nil, + 688, 688, 688, 688, 688, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 688, nil, nil, 688, nil, nil, + 688, 688, nil, nil, 688, nil, nil, nil, nil, nil, + 688, nil, nil, nil, nil, nil, nil, nil, nil, 688, + nil, nil, nil, nil, 688, 688, 688, 688, nil, 688, + 688, 688, 688, nil, nil, nil, nil, 688, 688, nil, + nil, nil, 722, 722, 722, 688, 722, 688, 688, 688, + 722, 722, nil, nil, nil, 722, nil, 722, 722, 722, + 722, 722, 722, 722, nil, nil, nil, nil, nil, 722, + 722, 722, 722, 722, 722, 722, nil, nil, 722, nil, + nil, nil, nil, nil, nil, 722, nil, nil, 722, 722, + 722, 722, 722, 722, 722, 722, nil, 722, 722, 722, + nil, 722, 722, 722, 722, 722, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 722, nil, nil, 722, nil, + nil, 722, 722, nil, nil, 722, nil, nil, nil, nil, + nil, 722, nil, nil, nil, nil, nil, nil, nil, nil, + 722, nil, nil, nil, nil, 722, 722, 722, 722, nil, + 722, 722, 722, 722, nil, nil, nil, nil, 722, 722, + nil, nil, nil, 744, 744, 744, 722, 744, 722, 722, + 722, 744, 744, nil, nil, nil, 744, nil, 744, 744, + 744, 744, 744, 744, 744, nil, nil, nil, nil, nil, + 744, 744, 744, 744, 744, 744, 744, nil, nil, 744, + nil, nil, nil, nil, nil, nil, 744, nil, nil, 744, + 744, 744, 744, 744, 744, 744, 744, nil, 744, 744, + 744, nil, 744, 744, 744, 744, 744, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 744, nil, nil, 744, + nil, nil, 744, 744, nil, nil, 744, nil, nil, nil, + nil, nil, 744, nil, nil, nil, nil, nil, nil, nil, + nil, 744, nil, nil, nil, nil, 744, 744, 744, 744, + nil, 744, 744, 744, 744, nil, nil, nil, nil, 744, + 744, nil, nil, nil, 752, 752, 752, 744, 752, 744, + 744, 744, 752, 752, nil, nil, nil, 752, nil, 752, + 752, 752, 752, 752, 752, 752, nil, nil, nil, nil, + nil, 752, 752, 752, 752, 752, 752, 752, nil, nil, + 752, nil, nil, nil, nil, nil, nil, 752, nil, nil, + 752, 752, 752, 752, 752, 752, 752, 752, nil, 752, + 752, 752, nil, 752, 752, 752, 752, 752, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 752, nil, nil, + 752, nil, nil, 752, 752, nil, nil, 752, nil, nil, + nil, nil, nil, 752, nil, nil, nil, nil, nil, nil, + nil, nil, 752, nil, nil, nil, nil, 752, 752, 752, + 752, nil, 752, 752, 752, 752, nil, nil, nil, nil, + 752, 752, nil, nil, nil, 765, 765, 765, 752, 765, + 752, 752, 752, 765, 765, nil, nil, nil, 765, nil, + 765, 765, 765, 765, 765, 765, 765, nil, nil, nil, + nil, nil, 765, 765, 765, 765, 765, 765, 765, nil, + nil, 765, nil, nil, nil, nil, nil, nil, 765, nil, + nil, 765, 765, 765, 765, 765, 765, 765, 765, nil, + 765, 765, 765, nil, 765, 765, 765, 765, 765, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 765, nil, + nil, 765, nil, nil, 765, 765, nil, nil, 765, nil, + nil, nil, nil, nil, 765, nil, nil, nil, nil, nil, + nil, nil, nil, 765, nil, nil, nil, nil, 765, 765, + 765, 765, nil, 765, 765, 765, 765, nil, nil, nil, + nil, 765, 765, nil, nil, nil, 766, 766, 766, 765, + 766, 765, 765, 765, 766, 766, nil, nil, nil, 766, + nil, 766, 766, 766, 766, 766, 766, 766, nil, nil, + nil, nil, nil, 766, 766, 766, 766, 766, 766, 766, + nil, nil, 766, nil, nil, nil, nil, nil, nil, 766, + nil, nil, 766, 766, 766, 766, 766, 766, 766, 766, + nil, 766, 766, 766, nil, 766, 766, 766, 766, 766, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 766, + nil, nil, 766, nil, nil, 766, 766, nil, nil, 766, + nil, nil, nil, nil, nil, 766, nil, nil, nil, nil, + nil, nil, nil, nil, 766, nil, nil, nil, nil, 766, + 766, 766, 766, nil, 766, 766, 766, 766, nil, nil, + nil, nil, 766, 766, nil, nil, nil, 767, 767, 767, + 766, 767, 766, 766, 766, 767, 767, nil, nil, nil, + 767, nil, 767, 767, 767, 767, 767, 767, 767, nil, + nil, nil, nil, nil, 767, 767, 767, 767, 767, 767, + 767, nil, nil, 767, nil, nil, nil, nil, nil, nil, + 767, nil, nil, 767, 767, 767, 767, 767, 767, 767, + 767, nil, 767, 767, 767, nil, 767, 767, 767, 767, + 767, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 767, nil, nil, 767, nil, nil, 767, 767, nil, nil, + 767, nil, nil, nil, nil, nil, 767, nil, nil, nil, + nil, nil, nil, nil, nil, 767, nil, nil, nil, nil, + 767, 767, 767, 767, nil, 767, 767, 767, 767, nil, + nil, nil, nil, 767, 767, nil, nil, nil, 768, 768, + 768, 767, 768, 767, 767, 767, 768, 768, nil, nil, + nil, 768, nil, 768, 768, 768, 768, 768, 768, 768, + nil, nil, nil, nil, nil, 768, 768, 768, 768, 768, + 768, 768, nil, nil, 768, nil, nil, nil, nil, nil, + nil, 768, nil, nil, 768, 768, 768, 768, 768, 768, + 768, 768, nil, 768, 768, 768, nil, 768, 768, 768, + 768, 768, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 768, nil, nil, 768, nil, nil, 768, 768, nil, + nil, 768, nil, nil, nil, nil, nil, 768, nil, nil, + nil, nil, nil, nil, nil, nil, 768, nil, nil, nil, + nil, 768, 768, 768, 768, nil, 768, 768, 768, 768, + nil, nil, nil, nil, 768, 768, nil, nil, nil, 770, + 770, 770, 768, 770, 768, 768, 768, 770, 770, nil, + nil, nil, 770, nil, 770, 770, 770, 770, 770, 770, + 770, nil, nil, nil, nil, nil, 770, 770, 770, 770, + 770, 770, 770, nil, nil, 770, nil, nil, nil, nil, + nil, nil, 770, nil, nil, 770, 770, 770, 770, 770, + 770, 770, 770, nil, 770, 770, 770, nil, 770, 770, + 770, 770, 770, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 770, nil, nil, 770, nil, nil, 770, 770, + nil, nil, 770, nil, nil, nil, nil, nil, 770, nil, + nil, nil, nil, nil, nil, nil, nil, 770, nil, nil, + nil, nil, 770, 770, 770, 770, nil, 770, 770, 770, + 770, nil, nil, nil, nil, 770, 770, nil, nil, nil, + 809, 809, 809, 770, 809, 770, 770, 770, 809, 809, + nil, nil, nil, 809, nil, 809, 809, 809, 809, 809, + 809, 809, nil, nil, nil, nil, nil, 809, 809, 809, + 809, 809, 809, 809, nil, nil, 809, nil, nil, nil, + nil, nil, nil, 809, nil, nil, 809, 809, 809, 809, + 809, 809, 809, 809, nil, 809, 809, 809, nil, 809, + 809, 809, 809, 809, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 809, nil, nil, 809, nil, nil, 809, + 809, nil, nil, 809, nil, nil, nil, nil, nil, 809, + nil, nil, nil, nil, nil, nil, nil, nil, 809, nil, + nil, nil, nil, 809, 809, 809, 809, nil, 809, 809, + 809, 809, nil, nil, nil, nil, 809, 809, nil, nil, + nil, 822, 822, 822, 809, 822, 809, 809, 809, 822, + 822, nil, nil, nil, 822, nil, 822, 822, 822, 822, + 822, 822, 822, nil, nil, nil, nil, nil, 822, 822, + 822, 822, 822, 822, 822, nil, nil, 822, nil, nil, + nil, nil, nil, nil, 822, nil, nil, 822, 822, 822, + 822, 822, 822, 822, 822, nil, 822, 822, 822, nil, + 822, 822, 822, 822, 822, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 822, nil, nil, 822, nil, nil, + 822, 822, nil, nil, 822, nil, nil, nil, nil, nil, + 822, nil, nil, nil, nil, nil, nil, nil, nil, 822, + nil, nil, nil, nil, 822, 822, 822, 822, nil, 822, + 822, 822, 822, nil, nil, nil, nil, 822, 822, nil, + nil, nil, 825, 825, 825, 822, 825, 822, 822, 822, + 825, 825, nil, nil, nil, 825, nil, 825, 825, 825, + 825, 825, 825, 825, nil, nil, nil, nil, nil, 825, + 825, 825, 825, 825, 825, 825, nil, nil, 825, nil, + nil, nil, nil, nil, nil, 825, nil, nil, 825, 825, + 825, 825, 825, 825, 825, 825, nil, 825, 825, 825, + nil, 825, 825, 825, 825, 825, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 825, nil, nil, 825, nil, + nil, 825, 825, nil, nil, 825, nil, 825, nil, nil, + nil, 825, nil, nil, nil, nil, nil, nil, nil, nil, + 825, nil, nil, nil, nil, 825, 825, 825, 825, nil, + 825, 825, 825, 825, nil, nil, nil, nil, 825, 825, + nil, nil, nil, 843, 843, 843, 825, 843, 825, 825, + 825, 843, 843, nil, nil, nil, 843, nil, 843, 843, + 843, 843, 843, 843, 843, nil, nil, nil, nil, nil, + 843, 843, 843, 843, 843, 843, 843, nil, nil, 843, + nil, nil, nil, nil, nil, nil, 843, nil, nil, 843, + 843, 843, 843, 843, 843, 843, 843, 843, 843, 843, + 843, nil, 843, 843, 843, 843, 843, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 843, nil, nil, 843, + nil, nil, 843, 843, nil, nil, 843, nil, nil, nil, + 843, nil, 843, nil, nil, 843, nil, nil, nil, nil, + nil, 843, nil, nil, nil, nil, 843, 843, 843, 843, + nil, 843, 843, 843, 843, nil, nil, nil, nil, 843, + 843, nil, nil, nil, 844, 844, 844, 843, 844, 843, + 843, 843, 844, 844, nil, nil, nil, 844, nil, 844, + 844, 844, 844, 844, 844, 844, nil, nil, nil, nil, + nil, 844, 844, 844, 844, 844, 844, 844, nil, nil, + 844, nil, nil, nil, nil, nil, nil, 844, nil, nil, + 844, 844, 844, 844, 844, 844, 844, 844, nil, 844, + 844, 844, nil, 844, 844, 844, 844, 844, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 844, nil, nil, + 844, nil, nil, 844, 844, nil, nil, 844, nil, nil, + nil, nil, nil, 844, nil, nil, nil, nil, nil, nil, + nil, nil, 844, nil, nil, nil, nil, 844, 844, 844, + 844, nil, 844, 844, 844, 844, nil, nil, nil, nil, + 844, 844, nil, nil, nil, 859, 859, 859, 844, 859, + 844, 844, 844, 859, 859, nil, nil, nil, 859, nil, + 859, 859, 859, 859, 859, 859, 859, nil, nil, nil, + nil, nil, 859, 859, 859, 859, 859, 859, 859, nil, + nil, 859, nil, nil, nil, nil, nil, nil, 859, nil, + nil, 859, 859, 859, 859, 859, 859, 859, 859, nil, + 859, 859, 859, nil, 859, 859, nil, nil, 859, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 859, nil, + nil, 859, nil, nil, 859, 859, nil, nil, 859, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 859, 859, + 859, 859, nil, 859, 859, 859, 859, nil, nil, nil, + nil, 859, 859, nil, nil, nil, 868, 868, 868, 859, + 868, 859, 859, 859, 868, 868, nil, nil, nil, 868, + nil, 868, 868, 868, 868, 868, 868, 868, nil, nil, + nil, nil, nil, 868, 868, 868, 868, 868, 868, 868, + nil, nil, 868, nil, nil, nil, nil, nil, nil, 868, + nil, nil, 868, 868, 868, 868, 868, 868, 868, 868, + nil, 868, 868, 868, nil, 868, 868, nil, nil, 868, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 868, + nil, nil, 868, nil, nil, 868, 868, nil, nil, 868, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 868, + 868, 868, 868, nil, 868, 868, 868, 868, nil, nil, + nil, nil, 868, 868, nil, nil, nil, 919, 919, 919, + 868, 919, 868, 868, 868, 919, 919, nil, nil, nil, + 919, nil, 919, 919, 919, 919, 919, 919, 919, nil, + nil, nil, nil, nil, 919, 919, 919, 919, 919, 919, + 919, nil, nil, 919, nil, nil, nil, nil, nil, nil, + 919, nil, nil, 919, 919, 919, 919, 919, 919, 919, + 919, nil, 919, 919, 919, nil, 919, 919, nil, nil, + 919, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 919, nil, nil, 919, nil, nil, 919, 919, nil, nil, + 919, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 919, 919, 919, 919, nil, 919, 919, 919, 919, nil, + nil, nil, nil, 919, 919, nil, nil, nil, 972, 972, + 972, 919, 972, 919, 919, 919, 972, 972, nil, nil, + nil, 972, nil, 972, 972, 972, 972, 972, 972, 972, + nil, nil, nil, nil, nil, 972, 972, 972, 972, 972, + 972, 972, nil, nil, 972, nil, nil, nil, nil, nil, + nil, 972, nil, nil, 972, 972, 972, 972, 972, 972, + 972, 972, 972, 972, 972, 972, nil, 972, 972, 972, + 972, 972, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 972, nil, nil, 972, nil, nil, 972, 972, nil, + nil, 972, nil, 972, nil, 972, nil, 972, nil, nil, + 972, nil, nil, nil, nil, nil, 972, nil, nil, nil, + nil, 972, 972, 972, 972, nil, 972, 972, 972, 972, + nil, nil, nil, nil, 972, 972, nil, nil, nil, nil, + nil, nil, 972, nil, 972, 972, 972, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, nil, nil, nil, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, nil, nil, nil, nil, nil, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, nil, + 8, nil, nil, nil, nil, nil, nil, nil, 8, 8, + nil, 8, 8, 8, 8, 8, 8, 8, nil, nil, + 8, 8, nil, nil, nil, 8, 8, 8, 8, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 8, 8, nil, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, nil, nil, 8, + 8, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, nil, + nil, nil, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, nil, nil, nil, nil, nil, 9, 9, 9, + 9, 9, 9, 9, 9, 9, nil, nil, 9, nil, + nil, nil, nil, nil, nil, nil, 9, 9, nil, 9, + 9, 9, 9, 9, 9, 9, nil, nil, 9, 9, + nil, nil, nil, 9, 9, 9, 9, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 9, 9, nil, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, nil, nil, 9, 9, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 9, 404, 404, 404, 404, 404, 404, 404, + 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, + 404, 404, 404, 404, 404, 404, 404, nil, nil, nil, + 404, 404, 404, 404, 404, 404, 404, 404, 404, 404, + nil, nil, nil, nil, nil, 404, 404, 404, 404, 404, + 404, 404, 404, 404, nil, nil, 404, nil, nil, nil, + nil, nil, nil, nil, 404, 404, nil, 404, 404, 404, + 404, 404, 404, 404, nil, nil, 404, 404, nil, nil, + nil, 404, 404, 404, 404, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 404, 404, + nil, 404, 404, 404, 404, 404, 404, 404, 404, 404, + 404, 404, 404, nil, nil, 404, 404, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 404, 596, 596, 596, 596, 596, 596, 596, 596, 596, + 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, + 596, 596, 596, 596, 596, nil, nil, nil, 596, 596, + 596, 596, 596, 596, 596, 596, 596, 596, nil, nil, + nil, nil, nil, 596, 596, 596, 596, 596, 596, 596, + 596, 596, nil, nil, 596, nil, nil, nil, nil, nil, + nil, nil, 596, 596, nil, 596, 596, 596, 596, 596, + 596, 596, nil, nil, 596, 596, nil, nil, nil, 596, + 596, 596, 596, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 596, 596, nil, 596, + 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, + 596, nil, nil, 596, 596, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 596, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, nil, nil, nil, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, nil, nil, nil, nil, + nil, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, nil, 72, nil, nil, nil, nil, nil, + 72, 72, nil, 72, 72, 72, 72, 72, 72, 72, + nil, nil, 72, 72, nil, nil, nil, 72, 72, 72, + 72, nil, nil, nil, nil, nil, 72, nil, nil, nil, + nil, nil, nil, nil, 72, 72, nil, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, nil, + nil, 72, 728, 728, 728, 728, 728, 728, 728, 728, + 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, + 728, 728, 728, 728, 728, 728, nil, nil, nil, 728, + 728, 728, 728, 728, 728, 728, 728, 728, 728, nil, + nil, nil, nil, nil, 728, 728, 728, 728, 728, 728, + 728, 728, 728, nil, nil, 728, nil, nil, nil, nil, + nil, nil, nil, 728, 728, nil, 728, 728, 728, 728, + 728, 728, 728, nil, nil, 728, 728, nil, nil, nil, + 728, 728, 728, 728, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 728, 728, nil, + 728, 728, 728, 728, 728, 728, 728, 728, 728, 728, + 728, 728, 218, 218, 728, nil, 218, nil, nil, nil, + nil, nil, nil, nil, 218, 218, nil, 218, 218, 218, + 218, 218, 218, 218, nil, nil, 218, 218, nil, nil, + nil, 218, 218, 218, 218, nil, nil, nil, nil, nil, + 218, nil, nil, nil, nil, nil, nil, nil, 218, 218, + nil, 218, 218, 218, 218, 218, 218, 218, 218, 218, + 218, 218, 218, 219, 219, 218, nil, 219, nil, nil, + nil, nil, nil, nil, nil, 219, 219, nil, 219, 219, + 219, 219, 219, 219, 219, nil, nil, 219, 219, nil, + nil, nil, 219, 219, 219, 219, nil, nil, nil, nil, + nil, 219, nil, nil, nil, nil, nil, nil, nil, 219, + 219, nil, 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 267, 267, 219, nil, 267, nil, + nil, nil, nil, nil, nil, nil, 267, 267, nil, 267, + 267, 267, 267, 267, 267, 267, nil, nil, 267, 267, + nil, nil, nil, 267, 267, 267, 267, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 267, 267, nil, 267, 267, 267, 267, 267, 267, 267, + 267, 267, 267, 267, 267, 454, 454, 267, nil, 454, + nil, nil, nil, nil, nil, nil, nil, 454, 454, nil, + 454, 454, 454, 454, 454, 454, 454, nil, nil, 454, + 454, nil, nil, nil, 454, 454, 454, 454, nil, nil, + nil, nil, nil, 454, nil, nil, nil, nil, nil, nil, + nil, 454, 454, nil, 454, 454, 454, 454, 454, 454, + 454, 454, 454, 454, 454, 454, 455, 455, 454, nil, + 455, nil, nil, nil, nil, nil, nil, nil, 455, 455, + nil, 455, 455, 455, 455, 455, 455, 455, nil, nil, + 455, 455, nil, nil, nil, 455, 455, 455, 455, nil, + nil, nil, nil, nil, 455, nil, nil, nil, nil, nil, + nil, nil, 455, 455, nil, 455, 455, 455, 455, 455, + 455, 455, 455, 455, 455, 455, 455, 518, 518, 455, + nil, 518, nil, nil, nil, nil, nil, nil, nil, 518, + 518, nil, 518, 518, 518, 518, 518, 518, 518, nil, + nil, 518, 518, nil, nil, nil, 518, 518, 518, 518, + nil, nil, nil, nil, nil, 518, nil, nil, nil, nil, + nil, nil, nil, 518, 518, nil, 518, 518, 518, 518, + 518, 518, 518, 518, 518, 518, 518, 518, 519, 519, + 518, nil, 519, nil, nil, nil, nil, nil, nil, nil, + 519, 519, nil, 519, 519, 519, 519, 519, 519, 519, + nil, nil, 519, 519, nil, nil, nil, 519, 519, 519, + 519, nil, nil, nil, nil, nil, 519, nil, nil, nil, + nil, nil, nil, nil, 519, 519, nil, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, 519, 528, + 528, 519, nil, 528, nil, nil, nil, nil, nil, nil, + nil, 528, 528, nil, 528, 528, 528, 528, 528, 528, + 528, nil, nil, 528, 528, nil, nil, nil, 528, 528, + 528, 528, nil, nil, nil, nil, nil, 528, nil, nil, + nil, nil, nil, nil, nil, 528, 528, nil, 528, 528, + 528, 528, 528, 528, 528, 528, 528, 528, 528, 528, + 529, 529, 528, nil, 529, nil, nil, nil, nil, nil, + nil, nil, 529, 529, nil, 529, 529, 529, 529, 529, + 529, 529, nil, nil, 529, 529, nil, nil, nil, 529, + 529, 529, 529, nil, nil, nil, nil, nil, 529, nil, + nil, nil, nil, nil, nil, nil, 529, 529, nil, 529, + 529, 529, 529, 529, 529, 529, 529, 529, 529, 529, + 529, 558, 558, 529, nil, 558, nil, nil, nil, nil, + nil, nil, nil, 558, 558, nil, 558, 558, 558, 558, + 558, 558, 558, nil, nil, 558, 558, nil, nil, nil, + 558, 558, 558, 558, nil, nil, nil, nil, nil, 558, + nil, nil, nil, nil, nil, nil, nil, 558, 558, nil, + 558, 558, 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 559, 559, 558, nil, 559, nil, nil, nil, + nil, nil, nil, nil, 559, 559, nil, 559, 559, 559, + 559, 559, 559, 559, nil, nil, 559, 559, nil, nil, + nil, 559, 559, 559, 559, nil, nil, nil, nil, nil, + 559, nil, nil, nil, nil, nil, nil, nil, 559, 559, + nil, 559, 559, 559, 559, 559, 559, 559, 559, 559, + 559, 559, 559, 565, 565, 559, nil, 565, nil, nil, + nil, nil, nil, nil, nil, 565, 565, nil, 565, 565, + 565, 565, 565, 565, 565, nil, nil, 565, 565, nil, + nil, nil, 565, 565, 565, 565, nil, nil, nil, nil, + nil, 565, nil, nil, nil, nil, nil, nil, nil, 565, + 565, nil, 565, 565, 565, 565, 565, 565, 565, 565, + 565, 565, 565, 565, 566, 566, 565, nil, 566, nil, + nil, nil, nil, nil, nil, nil, 566, 566, nil, 566, + 566, 566, 566, 566, 566, 566, nil, nil, 566, 566, + nil, nil, nil, 566, 566, 566, 566, nil, nil, nil, + nil, nil, 566, nil, nil, nil, nil, nil, nil, nil, + 566, 566, nil, 566, 566, 566, 566, 566, 566, 566, + 566, 566, 566, 566, 566, 602, 602, 566, nil, 602, + nil, nil, nil, nil, nil, nil, nil, 602, 602, nil, + 602, 602, 602, 602, 602, 602, 602, nil, nil, 602, + 602, nil, nil, nil, 602, 602, 602, 602, nil, nil, + nil, nil, nil, 602, nil, nil, nil, nil, nil, nil, + nil, 602, 602, nil, 602, 602, 602, 602, 602, 602, + 602, 602, 602, 602, 602, 602, 603, 603, 602, nil, + 603, nil, nil, nil, nil, nil, nil, nil, 603, 603, + nil, 603, 603, 603, 603, 603, 603, 603, nil, nil, + 603, 603, nil, nil, nil, 603, 603, 603, 603, nil, + nil, nil, nil, nil, 603, nil, nil, nil, nil, nil, + nil, nil, 603, 603, nil, 603, 603, 603, 603, 603, + 603, 603, 603, 603, 603, 603, 603, 969, 969, 603, + nil, 969, nil, nil, nil, nil, nil, nil, nil, 969, + 969, nil, 969, 969, 969, 969, 969, 969, 969, nil, + nil, 969, 969, nil, nil, nil, 969, 969, 969, 969, + nil, nil, nil, nil, nil, 969, nil, nil, nil, nil, + nil, nil, nil, 969, 969, nil, 969, 969, 969, 969, + 969, 969, 969, 969, 969, 969, 969, 969, 973, 973, + 969, nil, 973, nil, nil, nil, nil, nil, nil, nil, + 973, 973, nil, 973, 973, 973, 973, 973, 973, 973, + nil, nil, 973, 973, nil, nil, nil, 973, 973, 973, + 973, nil, nil, nil, nil, nil, 973, nil, nil, nil, + nil, nil, nil, nil, 973, 973, nil, 973, 973, 973, + 973, 973, 973, 973, 973, 973, 973, 973, 973, 974, + 974, 973, nil, 974, nil, nil, nil, nil, nil, nil, + nil, 974, 974, nil, 974, 974, 974, 974, 974, 974, + 974, nil, nil, 974, 974, nil, nil, nil, 974, 974, + 974, 974, nil, nil, nil, nil, nil, 974, nil, nil, + nil, nil, nil, nil, nil, 974, 974, nil, 974, 974, + 974, 974, 974, 974, 974, 974, 974, 974, 974, 974, + nil, 546, 974, 546, 546, 546, 546, 546, nil, 668, + nil, 668, 668, 668, 668, 668, 546, nil, nil, nil, + nil, nil, nil, nil, 668, nil, 726, nil, 726, 726, + 726, 726, 726, nil, nil, nil, nil, nil, 546, 546, + nil, 726, nil, nil, nil, nil, 668, 546, 546, 546, + 546, nil, nil, nil, 546, 668, 668, 668, 668, nil, + nil, nil, 668, 726, nil, 727, nil, 727, 727, 727, + 727, 727, 726, 726, 726, 726, nil, nil, nil, 726, + 727, nil, 803, nil, 803, 803, 803, 803, 803, nil, + 805, nil, 805, 805, 805, 805, 805, 803, nil, nil, + nil, nil, 727, nil, nil, 805, nil, nil, nil, nil, + nil, 727, 727, 727, 727, nil, nil, nil, 727, 803, + nil, nil, nil, nil, nil, nil, nil, 805, 803, 803, + 803, 803, nil, nil, nil, 803, 805, 805, 805, 805, + nil, nil, 910, 805, 910, 910, 910, 910, 910, nil, + 912, nil, 912, 912, 912, 912, 912, 910, nil, nil, + nil, nil, nil, nil, nil, 912, nil, 934, nil, 934, + 934, 934, 934, 934, nil, nil, nil, nil, nil, 910, + nil, nil, 934, nil, nil, nil, nil, 912, 910, 910, + 910, 910, nil, nil, nil, 910, 912, 912, 912, 912, + nil, nil, nil, 912, 934, nil, 940, nil, 940, 940, + 940, 940, 940, 934, 934, 934, 934, nil, nil, nil, + 934, 940, nil, 989, nil, 989, 989, 989, 989, 989, + 991, nil, 991, 991, 991, 991, 991, nil, 989, nil, + nil, nil, nil, 940, nil, 991, nil, 993, nil, 993, + 993, 993, 993, 993, 940, 940, nil, nil, nil, 940, + 989, nil, 993, nil, nil, nil, nil, 991, nil, 989, + 989, 989, 989, nil, nil, nil, 989, nil, 991, 991, + nil, nil, nil, 991, 993, nil, 995, nil, 995, 995, + 995, 995, 995, nil, nil, 993, 993, nil, nil, nil, + 993, 995, nil, 1010, nil, 1010, 1010, 1010, 1010, 1010, + 1027, nil, 1027, 1027, 1027, 1027, 1027, nil, 1010, nil, + nil, nil, nil, 995, nil, 1027, nil, nil, nil, nil, + nil, nil, nil, nil, 995, 995, nil, nil, nil, 995, + 1010, nil, nil, nil, nil, nil, nil, 1027, nil, nil, + nil, 1010, 1010, nil, nil, nil, 1010, nil, 1027, 1027, + nil, nil, nil, 1027 ] + +racc_action_pointer = [ + 1853, 10, nil, 221, nil, 5772, 909, -79, 22505, 22633, + -51, nil, -80, -44, 240, 15, 477, -81, nil, -71, + 5903, 1711, 166, nil, -62, nil, -8, 958, 1068, 6034, + 6165, 6296, nil, 1993, 6427, 6558, nil, 70, 225, 352, + 152, 255, 6697, 6828, -51, 6959, 86, 507, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 1178, nil, 7098, + 7229, 7360, 4, nil, 7491, 7622, nil, nil, 7753, 7892, + 8023, 8154, 23017, nil, nil, nil, nil, nil, nil, nil, + nil, 624, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 0, + nil, nil, 112, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 224, nil, 8293, nil, nil, nil, nil, + 8432, 8563, 8694, 8825, 8964, nil, 2133, nil, 287, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 115, + nil, 2273, 9095, 9226, 9357, 9488, 9619, 9750, 23191, 23252, + nil, nil, 9881, 10012, 10143, nil, nil, 574, -54, 166, + 202, 217, 124, 216, nil, 10274, 2413, 232, 10405, 10536, + 10667, 10798, 10929, 11060, 11191, 11322, 11453, 11584, 11715, 11846, + 11977, 12108, 12239, 12370, 12501, 12632, 12763, 12894, 13025, 13156, + nil, nil, nil, nil, 13287, nil, nil, 23313, nil, nil, + 258, 13418, 13549, nil, nil, nil, nil, nil, nil, nil, + 13680, nil, 2133, nil, 249, 263, nil, 13811, 328, 13942, + nil, nil, 14073, 14204, nil, nil, 295, nil, 14343, 1331, + 337, 315, 2553, 340, 391, 350, 14474, 2693, 576, 682, + 686, 441, 718, nil, 409, 387, 33, nil, nil, nil, + 458, 360, 418, 14613, nil, 424, 497, 771, nil, 528, + 14744, nil, 14875, 2833, 1396, 484, nil, 398, 503, 528, + 511, 575, 550, nil, nil, 326, -1, 11, 15006, 2973, + 3113, 298, 641, 533, -18, 11, 794, 644, 25, 677, + nil, nil, 342, 434, -21, nil, 834, nil, 596, 15137, + nil, nil, nil, 194, 230, 255, 373, 413, 481, 506, + 508, 550, nil, 551, nil, 15268, nil, 327, 388, 395, + 400, 456, -41, -35, 462, nil, nil, nil, nil, nil, + nil, nil, nil, 611, 22761, nil, nil, nil, nil, 612, + nil, nil, 600, 15399, 605, nil, nil, 600, nil, 837, + 313, 701, nil, nil, 1853, nil, nil, nil, nil, nil, + 1993, 615, nil, 627, 632, 509, 521, 1314, nil, nil, + nil, 222, 334, 678, nil, nil, 1446, 1582, nil, nil, + nil, -35, nil, 683, 23374, 23435, 15530, 328, 15661, 15792, + 15923, 2833, 2973, 523, 563, 708, 710, 711, 712, 1667, + 4233, 666, 3113, 3253, 3393, 3533, 3673, 3813, 915, 1465, + 3953, 4093, 2273, 1397, nil, 1718, nil, nil, nil, nil, + 669, nil, nil, nil, 673, nil, nil, 16054, nil, 16185, + nil, 16316, nil, 363, nil, nil, nil, 16455, 1427, nil, + 675, 675, nil, nil, 676, 16594, 683, 16725, 23496, 23557, + 870, 726, nil, 16856, 685, nil, 16987, 17118, 23618, 23679, + 1531, 2413, 17249, 823, 822, 702, 747, nil, 17380, nil, + nil, 17511, nil, nil, nil, nil, 24290, 3253, 826, nil, + 3393, 62, 834, 841, 836, 844, 17642, 17773, 23740, 23801, + 27, nil, nil, 930, nil, 23862, 23923, 17904, nil, nil, + 250, 3533, 765, nil, -33, nil, nil, nil, 832, nil, + nil, nil, 739, nil, nil, 259, nil, 338, nil, nil, + 727, nil, 741, nil, nil, nil, 22889, nil, 744, 18035, + 18166, 18297, 23984, 24045, 18436, 18567, 552, 787, 18698, 18829, + 18960, 19091, 786, nil, nil, 19222, 19353, 787, nil, nil, + nil, 343, 358, 466, 604, 758, 774, 906, nil, 890, + 6, nil, nil, 807, 102, 913, nil, 790, nil, 838, + 19484, nil, nil, 19615, nil, -83, 19746, 808, nil, 830, + 123, 180, 873, 248, 1038, 875, 840, 19877, nil, 909, + 214, 964, 20008, nil, nil, nil, 596, nil, 24298, nil, + 847, 849, nil, 857, 858, 859, nil, nil, nil, nil, + nil, nil, nil, nil, 853, 1178, nil, nil, 20139, nil, + nil, nil, 952, nil, nil, nil, 958, nil, nil, 959, + 516, nil, 997, nil, nil, nil, nil, nil, 1006, nil, + 26, 886, 40, 41, 151, 185, 3673, 717, 1040, nil, + 892, 3813, 20270, nil, 1029, 3953, 24315, 24354, 23130, nil, + nil, nil, nil, nil, nil, 4093, nil, nil, nil, nil, + nil, nil, nil, 910, 20401, 914, 516, 519, 714, 826, + nil, 2553, 20532, nil, 913, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 20663, 20794, 20925, 21056, 520, + 21187, nil, 160, nil, nil, 936, nil, nil, 889, nil, + 4233, nil, nil, nil, nil, 917, 236, nil, nil, 1045, + nil, 4373, 922, 970, nil, nil, nil, 64, 929, 780, + nil, nil, 556, 24371, nil, 24379, nil, 1377, nil, 21318, + nil, 1241, nil, 929, 228, 943, nil, nil, nil, nil, + 1065, nil, 21449, 1069, nil, 21580, 4513, 93, 1070, nil, + 1077, 480, 4653, nil, 1078, 962, 554, nil, 969, 964, + 553, nil, nil, 21711, 21842, 2693, 4793, nil, 965, 968, + nil, 969, 970, 973, nil, 1003, 983, 979, 973, 21973, + nil, nil, nil, nil, 4933, nil, nil, 32, 22104, nil, + nil, nil, nil, 1028, 986, nil, nil, nil, 987, 988, + nil, 990, 992, nil, 993, nil, nil, 998, 1280, 997, + 819, nil, nil, 33, nil, nil, 39, nil, nil, nil, + 1123, nil, nil, nil, 1060, nil, nil, 1203, nil, nil, + 24431, nil, 24439, nil, 6605, nil, nil, 1044, 1171, 22235, + 1006, 1099, nil, 5073, 34, 35, 1116, 1101, 36, nil, + 5213, 5353, nil, nil, 24456, nil, 8201, nil, 14521, nil, + 24495, nil, nil, nil, nil, 335, 951, 1026, 5493, nil, + nil, nil, nil, 5633, 1027, nil, nil, 1030, 1032, 1034, + 1036, nil, 1039, nil, 628, nil, nil, nil, 1146, 24106, + nil, 1176, 22366, 24167, 24228, 42, 1071, 1179, 1056, 1063, + 1064, 1069, 1074, 1291, 1075, 1307, 706, 1202, nil, 24512, + nil, 24519, nil, 24536, nil, 24575, nil, nil, nil, 1183, + 1123, 1124, nil, 1086, 98, 102, 111, 138, nil, nil, + 24592, nil, nil, nil, nil, 1312, 1094, nil, nil, 1108, + 1109, 1110, 1130, nil, 145, 1131, 1134, 24599, nil, nil, + nil, nil, nil, 1137, nil ] + +racc_action_default = [ + -3, -608, -1, -594, -4, -608, -7, -608, -608, -608, + -608, -30, -608, -608, -34, -608, -608, -287, -46, -596, + -608, -51, -55, -56, -57, -61, -264, -264, -264, -300, + -330, -331, -73, -12, -77, -85, -87, -608, -498, -499, + -608, -608, -608, -608, -223, -608, -596, -237, -278, -279, + -280, -281, -282, -283, -284, -285, -286, -582, -289, -293, + -607, -572, -308, -310, -608, -608, -53, -53, -594, -608, + -608, -608, -608, -332, -333, -335, -336, -337, -439, -440, + -441, -442, -443, -464, -446, -447, -466, -468, -451, -456, + -460, -462, -478, -464, -480, -482, -483, -484, -485, -580, + -487, -488, -581, -490, -491, -492, -493, -494, -495, -496, + -497, -502, -503, -608, -2, -595, -603, -604, -605, -6, + -608, -608, -608, -608, -608, -8, -3, -18, -608, -116, + -117, -118, -119, -120, -121, -122, -123, -124, -128, -129, + -130, -131, -132, -133, -134, -135, -136, -137, -138, -139, + -140, -141, -142, -143, -144, -145, -146, -147, -148, -149, + -150, -151, -152, -153, -154, -155, -156, -157, -158, -159, + -160, -161, -162, -163, -164, -165, -166, -167, -168, -169, + -170, -171, -172, -173, -174, -175, -176, -177, -178, -179, + -180, -181, -182, -183, -184, -185, -186, -187, -188, -189, + -190, -191, -192, -193, -194, -195, -196, -197, -198, -23, + -125, -12, -608, -608, -608, -608, -608, -254, -608, -608, + -592, -593, -608, -608, -596, -597, -50, -608, -498, -499, + -608, -287, -608, -608, -229, -608, -12, -608, -608, -608, + -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, + -608, -608, -608, -608, -608, -608, -608, -608, -608, -608, + -238, -239, -240, -241, -608, -403, -405, -608, -590, -591, + -62, -254, -608, -307, -409, -418, -420, -68, -415, -69, + -596, -70, -244, -259, -268, -268, -263, -608, -269, -608, + -464, -574, -608, -608, -71, -72, -594, -13, -608, -16, + -608, -75, -12, -596, -608, -78, -81, -12, -93, -94, + -608, -608, -101, -300, -303, -596, -608, -330, -331, -334, + -416, -608, -83, -608, -89, -297, -481, -608, -217, -218, + -608, -230, -608, -12, -291, -596, -245, -600, -600, -608, + -608, -600, -608, -309, -394, -52, -608, -608, -608, -12, + -12, -594, -608, -595, -498, -499, -608, -608, -287, -608, + -347, -348, -111, -112, -608, -114, -608, -287, -506, -608, + -498, -499, -323, -116, -117, -158, -159, -160, -176, -181, + -188, -191, -325, -608, -570, -608, -444, -608, -608, -608, + -608, -608, -608, -608, -608, 1035, -5, -606, -24, -25, + -26, -27, -28, -608, -608, -20, -21, -22, -126, -608, + -31, -33, -274, -608, -608, -273, -32, -608, -35, -608, + -287, -43, -45, -199, -249, -269, -47, -48, -36, -200, + -249, -596, -255, -268, -268, -583, -584, -264, -413, -585, + -586, -584, -583, -264, -412, -414, -585, -586, -42, -207, + -49, -596, -306, -608, -608, -608, -254, -297, -608, -608, + -608, -208, -209, -210, -211, -212, -213, -214, -215, -219, + -220, -221, -222, -224, -225, -226, -227, -228, -231, -232, + -233, -234, -596, -242, -424, -264, -583, -584, -59, -63, + -596, -265, -422, -424, -596, -302, -260, -608, -261, -608, + -266, -608, -270, -608, -577, -579, -11, -595, -15, -17, + -596, -74, -295, -90, -79, -608, -596, -254, -608, -608, + -100, -608, -481, -608, -86, -91, -608, -608, -608, -608, + -243, -235, -608, -431, -608, -596, -608, -246, -602, -601, + -248, -602, -298, -299, -573, -311, -530, -12, -338, -339, + -12, -608, -608, -608, -608, -608, -608, -254, -608, -608, + -297, -53, -111, -112, -113, -608, -608, -254, -319, -504, + -608, -12, -508, -327, -596, -445, -465, -470, -608, -472, + -448, -467, -608, -469, -450, -608, -453, -608, -455, -458, + -608, -459, -608, -479, -9, -19, -608, -29, -277, -608, + -608, -254, -608, -608, -608, -608, -417, -608, -256, -258, + -608, -608, -64, -253, -410, -608, -608, -66, -411, -305, + -598, -583, -584, -583, -584, -596, -608, -608, -425, -58, + -406, -422, -251, -608, -383, -608, -301, -268, -267, -271, + -608, -575, -576, -608, -14, -76, -608, -82, -88, -596, + -583, -584, -252, -587, -99, -608, -84, -608, -206, -216, + -596, -607, -607, -290, -292, -294, -600, -395, -530, -398, + -569, -569, -513, -515, -515, -515, -529, -531, -532, -533, + -534, -535, -536, -537, -538, -608, -540, -542, -544, -549, + -551, -552, -554, -559, -561, -562, -564, -565, -566, -608, + -607, -340, -607, -54, -341, -342, -314, -315, -608, -317, + -608, -596, -583, -584, -587, -296, -12, -111, -112, -115, + -596, -12, -608, -321, -608, -12, -530, -530, -608, -571, + -471, -474, -475, -476, -477, -12, -449, -452, -454, -457, + -461, -463, -127, -275, -608, -596, -583, -584, -584, -583, + -44, -250, -608, -599, -268, -38, -202, -39, -203, -65, + -40, -205, -41, -204, -67, -608, -608, -608, -608, -417, + -608, -404, -383, -408, -407, -608, -419, -384, -596, -386, + -12, -421, -262, -272, -578, -80, -417, -92, -304, -607, + -345, -12, -432, -607, -433, -434, -247, -608, -596, -608, + -511, -512, -608, -608, -522, -608, -525, -608, -527, -608, + -349, -608, -351, -353, -360, -596, -543, -553, -563, -567, + -608, -343, -608, -608, -316, -608, -12, -417, -608, -417, + -608, -608, -12, -324, -608, -596, -608, -328, -608, -276, + -417, -37, -201, -257, -608, -236, -12, -60, -569, -569, + -365, -367, -367, -367, -382, -608, -596, -388, -538, -546, + -547, -557, -423, -10, -12, -438, -346, -608, -608, -436, + -396, -399, -401, -608, -569, -550, -568, -514, -515, -515, + -541, -515, -515, -560, -515, -538, -555, -596, -608, -358, + -608, -539, -312, -608, -313, -271, -607, -318, -320, -505, + -608, -326, -507, -509, -508, -473, -426, -608, -363, -364, + -373, -375, -608, -378, -608, -380, -385, -608, -608, -608, + -545, -608, -437, -12, -498, -499, -608, -608, -287, -435, + -12, -12, -397, -510, -608, -518, -608, -520, -608, -523, + -608, -526, -528, -350, -352, -356, -608, -361, -12, -427, + -428, -429, -322, -12, -569, -548, -366, -367, -367, -367, + -367, -558, -367, -387, -596, -390, -392, -393, -556, -608, + -297, -431, -254, -608, -608, -297, -608, -608, -515, -515, + -515, -515, -354, -608, -359, -608, -607, -608, -362, -608, + -370, -608, -372, -608, -376, -608, -379, -381, -389, -608, + -296, -587, -430, -596, -583, -584, -587, -296, -400, -402, + -608, -516, -519, -521, -524, -608, -357, -344, -329, -367, + -367, -367, -367, -391, -417, -515, -355, -608, -368, -371, + -374, -377, -517, -367, -369 ] + +racc_goto_table = [ + 223, 343, 304, 16, 534, 382, 127, 210, 16, 283, + 283, 283, 498, 319, 319, 431, 266, 218, 336, 267, + 132, 132, 555, 227, 661, 268, 489, 332, 118, 437, + 443, 114, 227, 227, 227, 725, 16, 310, 310, 6, + 274, 278, 326, 524, 6, 115, 135, 135, 319, 319, + 319, 346, 347, 137, 137, 351, 349, 350, 638, 305, + 638, 606, 16, 547, 550, 415, 416, 227, 227, 490, + 820, 227, 356, 366, 366, 270, 277, 279, 485, 537, + 540, 125, 633, 544, 132, 428, 345, 345, 226, 641, + 345, 448, 789, 118, 564, 780, 352, 880, 334, 119, + 581, 583, 586, 586, 2, 944, 387, 398, 399, 400, + 401, 322, 301, 800, 801, 852, 394, 855, 16, 452, + 284, 284, 284, 227, 227, 227, 227, 16, 883, 16, + 815, 641, 965, 823, 961, 1, 947, 873, 368, 372, + 863, 303, 345, 345, 345, 345, 627, 281, 294, 295, + 644, 337, 585, 587, 6, 635, 209, 967, 285, 285, + 285, 498, 361, 402, 669, 6, 411, 404, 703, 638, + 638, 631, 596, 330, 339, 495, 630, 384, 676, 340, + 409, 545, 359, 568, 383, 333, 535, 335, 344, 338, + 341, 721, 984, 832, 571, 917, 572, 283, 511, 641, + 728, 904, 944, 854, 880, 304, 856, 964, 667, 396, + 870, 961, 546, 1023, 16, 227, 419, 227, 227, 419, + 227, 775, 797, 930, 708, 419, 227, 227, 454, 1016, + 403, 447, 438, 846, 880, 647, 426, 427, 967, 16, + 931, 484, 724, 656, 492, 450, 451, 957, 493, 772, + 949, 283, 283, 793, 625, 769, 887, 883, 867, 386, + 283, 1026, 388, 389, 390, 437, 443, 391, 392, 393, + 730, 304, 735, 722, 227, 227, 304, 878, 875, 786, + 410, 421, 955, 227, 421, 319, 798, 853, nil, 880, + 421, 908, 909, nil, nil, 719, 521, 738, nil, 738, + 676, 16, 319, 414, 414, 16, nil, nil, nil, 310, + 16, 518, 879, 503, 881, 649, 536, 933, 552, 553, + nil, 118, 522, nil, 506, nil, 310, 950, 528, 652, + 274, nil, nil, nil, 278, 551, 16, 508, 507, 652, + nil, 827, nil, nil, 835, 836, 619, nil, 525, nil, + 829, 227, 16, 16, nil, 711, 1017, 558, 676, 676, + nil, nil, nil, 284, 782, 720, 785, 953, 759, 652, + 345, 284, 227, 764, 509, 840, 118, 652, 573, 554, + nil, 301, 514, nil, 268, 632, 301, nil, 227, 636, + 491, 570, 830, nil, nil, nil, 834, 988, 494, 745, + nil, 285, 595, nil, 638, 645, nil, 574, 796, 285, + 510, 648, 607, 437, 443, 516, 132, nil, nil, 958, + 602, 959, nil, nil, nil, 422, nil, 826, 422, nil, + 664, nil, nil, 641, 422, nil, 283, nil, nil, nil, + nil, 26, 135, 978, nil, nil, 26, nil, nil, 137, + nil, 613, nil, nil, nil, nil, nil, 618, nil, 227, + nil, 26, 1002, 626, nil, nil, nil, 447, 438, 729, + 26, 26, 26, nil, 26, nil, nil, nil, nil, 755, + 757, 782, nil, nil, 760, 762, 612, nil, nil, nil, + nil, nil, 617, nil, 319, nil, nil, 283, 1019, 613, + 26, nil, 319, 900, nil, 26, 26, nil, nil, 26, + 16, nil, nil, nil, nil, 794, 700, 906, 310, 702, + 227, nil, nil, nil, nil, nil, 310, nil, nil, nil, + nil, 447, 438, nil, 629, 227, nil, 283, nil, nil, + 525, 447, 438, nil, nil, nil, nil, 283, 525, nil, + 16, 716, nil, 16, 660, 788, 26, nil, nil, nil, + 227, 26, 26, 26, 26, 26, 951, 26, nil, 774, + 227, 447, 438, nil, 16, nil, 704, 447, nil, nil, + 438, 283, nil, nil, 923, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 742, 723, nil, nil, nil, nil, + nil, nil, nil, 419, 227, nil, 607, 16, 132, nil, + 948, nil, nil, 419, 419, 447, 438, nil, 419, 419, + 795, 841, nil, 773, 987, 319, 637, nil, nil, nil, + 607, nil, nil, 1024, 135, nil, 319, nil, nil, nil, + nil, 137, nil, 750, nil, nil, nil, 710, nil, 310, + nil, nil, 26, 26, 26, 26, 26, 26, 26, nil, + 310, 837, nil, 26, 26, 26, 613, 666, 421, 618, + nil, 525, nil, nil, nil, nil, nil, 26, 421, 421, + nil, nil, 787, 421, 421, 828, nil, 429, nil, nil, + nil, nil, 607, 449, nil, nil, nil, nil, nil, nil, + nil, 607, nil, nil, 838, 810, nil, nil, nil, 831, + 891, nil, 26, 26, nil, nil, nil, nil, nil, 16, + nil, 26, nil, nil, 16, 227, 607, nil, 16, nil, + 902, nil, nil, nil, nil, nil, nil, 754, 16, 26, + 132, nil, nil, 26, 345, nil, nil, 865, 26, 862, + nil, 869, nil, 414, nil, 419, nil, nil, nil, 857, + 866, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1003, 804, 806, 808, 26, nil, nil, nil, nil, 857, + nil, 684, 943, 16, 652, nil, nil, nil, nil, 26, + 26, 26, nil, nil, 16, 896, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 893, + 26, nil, 422, nil, nil, nil, nil, nil, nil, nil, + 421, nil, 422, 422, nil, 227, 26, 422, 422, 16, + nil, 810, nil, 922, 889, 16, nil, 857, 319, nil, + nil, nil, nil, nil, 345, nil, nil, 319, 29, 16, + nil, nil, nil, 29, nil, nil, 899, nil, nil, nil, + nil, 903, 920, nil, nil, nil, nil, 16, 29, nil, + nil, 926, nil, nil, nil, nil, nil, 29, 29, 29, + nil, 29, nil, nil, nil, 13, nil, nil, nil, nil, + 13, nil, 971, 849, nil, nil, nil, 26, 319, 976, + 977, nil, nil, 684, nil, nil, nil, 29, 810, nil, + 810, nil, 29, 29, 874, nil, 29, 986, 13, nil, + nil, nil, 968, nil, nil, nil, 16, 973, nil, 449, + nil, 429, nil, 16, 16, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 13, 998, nil, nil, 26, nil, + nil, 16, 283, nil, 360, nil, 16, nil, 26, nil, + nil, 684, 684, 29, 422, 982, 810, nil, 29, 29, + 29, 29, 29, 26, 29, 227, 935, 937, nil, 939, + 941, 447, 942, nil, 607, nil, 447, 438, 26, nil, + nil, 26, nil, 850, nil, nil, nil, 658, 26, nil, + 13, nil, nil, 810, nil, 810, nil, nil, 26, 13, + nil, 13, 26, 858, 876, nil, nil, 876, nil, nil, + nil, nil, 954, nil, nil, 849, nil, 849, nil, 849, + nil, nil, nil, nil, 15, 810, nil, nil, 684, 15, + 684, 26, 26, nil, nil, 26, nil, nil, nil, nil, + nil, 26, 26, nil, nil, nil, 26, 26, nil, 29, + 29, 29, 29, 29, 29, 29, nil, 15, nil, nil, + 29, 29, 29, nil, nil, nil, 1011, 1012, 1013, 1014, + 859, 756, 758, nil, 29, nil, 761, 763, nil, nil, + nil, nil, nil, 15, nil, nil, 13, nil, 417, nil, + nil, 417, nil, nil, 849, nil, 849, 417, 849, nil, + 849, nil, nil, nil, nil, nil, nil, nil, nil, 29, + 29, 13, 876, 1032, 851, 850, nil, 850, 29, 850, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 849, nil, nil, 858, 29, 858, nil, 15, + 29, 882, nil, 884, nil, 29, nil, 26, 15, nil, + 15, nil, 26, 26, nil, nil, 26, nil, nil, 684, + nil, nil, nil, nil, nil, nil, 26, nil, nil, nil, + nil, 29, nil, 13, nil, nil, nil, 13, nil, nil, + nil, nil, 13, 26, nil, nil, 29, 29, 29, nil, + nil, nil, nil, nil, 850, nil, 850, nil, 850, 859, + 850, nil, 859, nil, 859, nil, 859, 29, 13, nil, + nil, 26, nil, 842, 858, nil, nil, nil, nil, nil, + nil, nil, 26, 29, 13, 13, 756, 758, 763, 761, + nil, nil, 850, nil, nil, 15, nil, 15, nil, nil, + 15, nil, 911, 913, 915, nil, 15, nil, 960, nil, + 962, nil, nil, 26, nil, nil, nil, 26, nil, nil, + 15, nil, nil, 26, nil, nil, nil, nil, nil, nil, + 979, nil, 980, nil, 981, nil, nil, 26, nil, nil, + nil, 859, nil, 859, nil, 859, nil, 859, nil, nil, + nil, nil, nil, nil, 29, 26, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 842, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 859, + nil, nil, 15, nil, nil, 1020, 15, 1021, nil, 1022, + nil, 15, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 29, 1025, nil, 990, 992, + 994, 996, nil, 997, 26, 29, nil, 15, nil, nil, + nil, 26, 26, 1033, nil, nil, nil, nil, nil, nil, + 29, nil, nil, 15, 15, nil, nil, nil, nil, 26, + nil, nil, 13, nil, 26, 29, nil, nil, 29, nil, + nil, nil, nil, nil, nil, 29, nil, nil, nil, nil, + nil, nil, nil, 26, nil, 29, nil, nil, nil, 29, + 1028, 1029, 1030, 1031, nil, nil, nil, nil, nil, nil, + nil, nil, 13, nil, 1034, 13, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 29, 29, + nil, nil, 29, nil, nil, nil, 13, nil, 29, 29, + nil, nil, nil, 29, 29, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 417, nil, nil, nil, 13, + nil, nil, nil, nil, nil, 417, 417, nil, nil, nil, + 417, 417, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 15, nil, nil, nil, 17, nil, nil, nil, nil, + 17, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 29, nil, nil, nil, nil, 29, + 29, nil, nil, 29, nil, nil, nil, nil, 17, 312, + 312, 15, nil, 29, 15, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 29, 13, nil, nil, 17, 15, 13, nil, nil, nil, + 13, nil, nil, nil, 358, 367, 367, nil, nil, 38, + 13, nil, nil, nil, 38, nil, nil, nil, 29, nil, + nil, nil, nil, nil, 15, nil, nil, 417, 15, 29, + nil, nil, nil, nil, 15, 15, nil, nil, nil, 15, + 15, nil, 38, 308, 308, nil, nil, nil, nil, nil, + 17, nil, nil, nil, nil, 13, nil, nil, nil, 17, + 29, 17, nil, nil, 29, nil, 13, nil, 38, nil, + 29, nil, nil, nil, nil, nil, nil, nil, 354, 370, + 370, 370, nil, nil, 29, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 13, 29, nil, nil, nil, nil, 13, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 13, nil, nil, 38, nil, nil, nil, nil, nil, + nil, nil, nil, 38, nil, 38, nil, nil, nil, 13, + 15, nil, nil, 929, nil, 15, 17, nil, 420, 15, + nil, 420, nil, 342, nil, nil, nil, 420, nil, 15, + nil, 29, nil, nil, nil, nil, nil, nil, 29, 29, + nil, 17, nil, nil, nil, nil, 15, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 29, nil, nil, nil, + nil, 29, nil, nil, nil, nil, nil, nil, 13, nil, + nil, nil, nil, nil, 15, 13, 13, nil, nil, nil, + 29, nil, nil, nil, nil, 15, nil, nil, nil, nil, + 38, nil, nil, 13, nil, nil, nil, nil, 13, nil, + nil, nil, nil, 17, nil, nil, nil, 17, nil, nil, + nil, 312, 17, nil, nil, 38, nil, nil, nil, nil, + 15, nil, nil, nil, nil, nil, 15, nil, 312, nil, + nil, nil, nil, nil, nil, nil, nil, 39, 17, nil, + 15, nil, 39, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 17, 17, nil, nil, 15, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 39, 309, 309, nil, 412, 425, nil, 38, nil, nil, + nil, 38, nil, nil, nil, 308, 38, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 39, nil, nil, nil, + nil, nil, 308, nil, nil, nil, 355, 371, 371, 371, + nil, nil, 38, nil, nil, nil, nil, 15, nil, nil, + nil, nil, nil, nil, 15, 15, nil, nil, 38, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 15, nil, nil, nil, nil, 15, nil, 500, + nil, 502, 39, nil, 504, 505, nil, nil, nil, nil, + nil, 39, nil, 39, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 17, nil, nil, nil, nil, nil, nil, nil, + 312, nil, nil, nil, nil, nil, nil, nil, 312, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 39, nil, + nil, nil, 17, nil, nil, 17, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 39, nil, 598, 17, nil, nil, nil, + nil, nil, nil, 734, nil, nil, 38, nil, nil, nil, + nil, nil, nil, nil, 308, nil, nil, nil, nil, nil, + nil, nil, 308, nil, nil, 420, nil, nil, nil, 17, + nil, nil, nil, nil, nil, 420, 420, nil, nil, nil, + 420, 420, nil, nil, nil, nil, 38, nil, nil, 38, + nil, nil, nil, nil, nil, 39, nil, nil, nil, 39, + nil, nil, nil, 309, 39, nil, nil, nil, nil, nil, + 38, 312, nil, nil, nil, nil, nil, nil, nil, 639, + 309, 342, 312, 642, nil, nil, nil, nil, nil, nil, + 39, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 38, nil, nil, 39, 39, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 639, nil, nil, 342, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 425, nil, + nil, 17, nil, nil, nil, 308, 17, nil, nil, nil, + 17, nil, nil, nil, nil, nil, 308, nil, nil, nil, + 17, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 420, nil, nil, + nil, 743, nil, nil, nil, nil, nil, nil, nil, nil, + 639, 342, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 17, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 38, 17, nil, nil, nil, + 38, nil, 783, nil, 38, 784, nil, nil, nil, nil, + nil, nil, nil, nil, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 792, nil, nil, nil, nil, nil, + nil, 17, nil, nil, nil, nil, nil, 17, nil, nil, + nil, nil, nil, nil, 39, nil, nil, nil, nil, nil, + 816, 17, 309, nil, nil, nil, nil, nil, nil, 38, + 309, nil, nil, nil, 367, nil, nil, nil, nil, 17, + 38, nil, 234, 928, nil, nil, nil, nil, nil, nil, + nil, 282, 282, 282, 39, nil, nil, 39, nil, nil, + nil, nil, nil, nil, 328, 329, nil, 331, nil, nil, + nil, nil, nil, nil, nil, 38, 839, nil, 39, nil, + nil, 38, 282, 282, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 367, 38, nil, nil, 17, nil, + nil, nil, nil, nil, nil, 17, 17, nil, 370, nil, + nil, 39, nil, 38, nil, nil, nil, 924, nil, nil, + nil, nil, nil, 17, nil, nil, nil, nil, 17, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 886, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 309, nil, nil, nil, 895, nil, nil, + nil, nil, nil, nil, 309, nil, nil, nil, 370, nil, + nil, nil, 38, nil, nil, 342, nil, nil, nil, 38, + 38, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 38, nil, nil, + nil, nil, 38, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 39, nil, nil, nil, nil, 39, nil, + nil, nil, 39, nil, 282, 424, nil, nil, 430, 282, + nil, nil, 39, nil, 430, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 234, nil, nil, + 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, + 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, + 481, 482, nil, nil, nil, nil, 483, 39, nil, nil, + nil, nil, nil, 282, 282, nil, nil, nil, 39, nil, + nil, nil, 282, nil, nil, nil, nil, nil, nil, 282, + nil, 282, nil, nil, 282, 282, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 39, nil, nil, nil, nil, nil, 39, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 530, 39, 531, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 371, nil, nil, nil, + nil, 39, nil, nil, nil, 925, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 371, nil, nil, nil, + 39, nil, nil, nil, nil, 282, nil, 39, 39, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 39, nil, nil, nil, nil, + 39, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 282, nil, + 430, 430, 430, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 282, + nil, 282, nil, 282, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 282, + nil, nil, nil, nil, nil, nil, nil, nil, 430, 659, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 282, nil, nil, 282, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 282, 282, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 282, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 282, 430, 282, nil, nil, nil, 751, nil, nil, + 282, 282, 430, 430, nil, nil, nil, 430, 430, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 282, nil, nil, 282, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 282, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 282, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 282, nil, nil, nil, + nil, nil, nil, nil, 430, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 430, 430, 430, + 430, nil, 845, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 282, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 282, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 282, 430, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 282 ] + +racc_goto_check = [ + 34, 96, 10, 29, 9, 63, 16, 16, 29, 39, + 39, 39, 83, 73, 73, 30, 144, 32, 77, 42, + 64, 64, 101, 29, 11, 32, 45, 34, 105, 43, + 43, 4, 29, 29, 29, 107, 29, 29, 29, 7, + 81, 81, 71, 58, 7, 6, 67, 67, 73, 73, + 73, 18, 18, 68, 68, 18, 36, 36, 84, 56, + 84, 31, 29, 99, 99, 23, 23, 29, 29, 30, + 100, 29, 29, 29, 29, 44, 44, 44, 43, 79, + 79, 8, 46, 79, 64, 27, 25, 25, 21, 188, + 25, 27, 12, 105, 61, 133, 4, 179, 7, 5, + 166, 166, 166, 166, 2, 119, 161, 18, 18, 18, + 18, 57, 52, 126, 126, 131, 161, 135, 29, 54, + 78, 78, 78, 29, 29, 29, 29, 29, 184, 29, + 121, 188, 137, 12, 185, 1, 122, 135, 62, 62, + 13, 53, 25, 25, 25, 25, 147, 51, 51, 51, + 15, 78, 165, 165, 7, 147, 17, 138, 80, 80, + 80, 83, 20, 7, 143, 7, 24, 26, 37, 84, + 84, 48, 69, 74, 76, 54, 82, 94, 173, 95, + 10, 98, 102, 104, 108, 109, 110, 111, 112, 80, + 80, 113, 122, 114, 115, 135, 116, 39, 54, 188, + 117, 118, 119, 123, 179, 10, 129, 136, 139, 5, + 140, 185, 141, 137, 29, 29, 29, 29, 29, 29, + 29, 46, 142, 145, 101, 29, 29, 29, 32, 122, + 2, 64, 81, 133, 179, 58, 25, 25, 138, 29, + 146, 148, 9, 58, 150, 25, 25, 131, 151, 154, + 155, 39, 39, 156, 30, 31, 121, 184, 157, 160, + 39, 122, 162, 163, 164, 43, 43, 167, 168, 169, + 170, 10, 171, 172, 29, 29, 10, 177, 181, 31, + 21, 21, 182, 29, 21, 73, 143, 132, nil, 179, + 21, 126, 126, nil, nil, 61, 34, 166, nil, 166, + 173, 29, 73, 78, 78, 29, nil, nil, nil, 29, + 29, 32, 132, 161, 132, 30, 34, 126, 10, 10, + nil, 105, 71, nil, 4, nil, 29, 12, 32, 43, + 81, nil, nil, nil, 81, 18, 29, 7, 6, 43, + nil, 31, nil, nil, 143, 143, 54, nil, 56, nil, + 31, 29, 29, 29, nil, 30, 100, 32, 173, 173, + nil, nil, nil, 78, 83, 30, 58, 107, 45, 43, + 25, 78, 29, 45, 8, 31, 105, 43, 42, 4, + nil, 52, 57, nil, 32, 54, 52, nil, 29, 54, + 51, 25, 9, nil, nil, nil, 9, 126, 51, 30, + nil, 80, 16, nil, 84, 54, nil, 25, 79, 80, + 53, 54, 34, 43, 43, 53, 64, nil, nil, 132, + 32, 132, nil, nil, nil, 19, nil, 99, 19, nil, + 54, nil, nil, 188, 19, nil, 39, nil, nil, nil, + nil, 47, 67, 132, nil, nil, 47, nil, nil, 68, + nil, 81, nil, nil, nil, nil, nil, 81, nil, 29, + nil, 47, 11, 34, nil, nil, nil, 64, 81, 54, + 47, 47, 47, nil, 47, nil, nil, nil, nil, 27, + 27, 83, nil, nil, 27, 27, 44, nil, nil, nil, + nil, nil, 44, nil, 73, nil, nil, 39, 132, 81, + 47, nil, 73, 9, nil, 47, 47, nil, nil, 47, + 29, nil, nil, nil, nil, 23, 10, 9, 29, 10, + 29, nil, nil, nil, nil, nil, 29, nil, nil, nil, + nil, 64, 81, nil, 44, 29, nil, 39, nil, nil, + 56, 64, 81, nil, nil, nil, nil, 39, 56, nil, + 29, 36, nil, 29, 25, 54, 47, nil, nil, nil, + 29, 47, 47, 47, 47, 47, 101, 47, nil, 96, + 29, 64, 81, nil, 29, nil, 105, 64, nil, nil, + 81, 39, nil, nil, 99, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 16, 105, nil, nil, nil, nil, + nil, nil, nil, 29, 29, nil, 34, 29, 64, nil, + 99, nil, nil, 29, 29, 64, 81, nil, 29, 29, + 77, 27, nil, 144, 9, 73, 80, nil, nil, nil, + 34, nil, nil, 31, 67, nil, 73, nil, nil, nil, + nil, 68, nil, 7, nil, nil, nil, 78, nil, 29, + nil, nil, 47, 47, 47, 47, 47, 47, 47, nil, + 29, 63, nil, 47, 47, 47, 81, 80, 21, 81, + nil, 56, nil, nil, nil, nil, nil, 47, 21, 21, + nil, nil, 56, 21, 21, 10, nil, 70, nil, nil, + nil, nil, 34, 70, nil, nil, nil, nil, nil, nil, + nil, 34, nil, nil, 10, 120, nil, nil, nil, 18, + 54, nil, 47, 47, nil, nil, nil, nil, nil, 29, + nil, 47, nil, nil, 29, 29, 34, nil, 29, nil, + 54, nil, nil, nil, nil, nil, nil, 80, 29, 47, + 64, nil, nil, 47, 25, nil, nil, 77, 47, 10, + nil, 77, nil, 78, nil, 29, nil, nil, nil, 34, + 10, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 30, 176, 176, 176, 47, nil, nil, nil, nil, 34, + nil, 178, 54, 29, 43, nil, nil, nil, nil, 47, + 47, 47, nil, nil, 29, 10, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 18, + 47, nil, 19, nil, nil, nil, nil, nil, nil, nil, + 21, nil, 19, 19, nil, 29, 47, 19, 19, 29, + nil, 120, nil, 10, 120, 29, nil, 34, 73, nil, + nil, nil, nil, nil, 25, nil, nil, 73, 50, 29, + nil, nil, nil, 50, nil, nil, 105, nil, nil, nil, + nil, 105, 29, nil, nil, nil, nil, 29, 50, nil, + nil, 29, nil, nil, nil, nil, nil, 50, 50, 50, + nil, 50, nil, nil, nil, 22, nil, nil, nil, nil, + 22, nil, 10, 125, nil, nil, nil, 47, 73, 10, + 10, nil, nil, 178, nil, nil, nil, 50, 120, nil, + 120, nil, 50, 50, 125, nil, 50, 10, 22, nil, + nil, nil, 29, nil, nil, nil, 29, 32, nil, 70, + nil, 70, nil, 29, 29, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 22, 34, nil, nil, 47, nil, + nil, 29, 39, nil, 22, nil, 29, nil, 47, nil, + nil, 178, 178, 50, 19, 120, 120, nil, 50, 50, + 50, 50, 50, 47, 50, 29, 176, 176, nil, 176, + 176, 64, 176, nil, 34, nil, 64, 81, 47, nil, + nil, 47, nil, 127, nil, nil, nil, 70, 47, nil, + 22, nil, nil, 120, nil, 120, nil, nil, 47, 22, + nil, 22, 47, 178, 127, nil, nil, 127, nil, nil, + nil, nil, 125, nil, nil, 125, nil, 125, nil, 125, + nil, nil, nil, nil, 28, 120, nil, nil, 178, 28, + 178, 47, 47, nil, nil, 47, nil, nil, nil, nil, + nil, 47, 47, nil, nil, nil, 47, 47, nil, 50, + 50, 50, 50, 50, 50, 50, nil, 28, nil, nil, + 50, 50, 50, nil, nil, nil, 176, 176, 176, 176, + 180, 70, 70, nil, 50, nil, 70, 70, nil, nil, + nil, nil, nil, 28, nil, nil, 22, nil, 22, nil, + nil, 22, nil, nil, 125, nil, 125, 22, 125, nil, + 125, nil, nil, nil, nil, nil, nil, nil, nil, 50, + 50, 22, 127, 176, 130, 127, nil, 127, 50, 127, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 125, nil, nil, 178, 50, 178, nil, 28, + 50, 130, nil, 130, nil, 50, nil, 47, 28, nil, + 28, nil, 47, 47, nil, nil, 47, nil, nil, 178, + nil, nil, nil, nil, nil, nil, 47, nil, nil, nil, + nil, 50, nil, 22, nil, nil, nil, 22, nil, nil, + nil, nil, 22, 47, nil, nil, 50, 50, 50, nil, + nil, nil, nil, nil, 127, nil, 127, nil, 127, 180, + 127, nil, 180, nil, 180, nil, 180, 50, 22, nil, + nil, 47, nil, 70, 178, nil, nil, nil, nil, nil, + nil, nil, 47, 50, 22, 22, 70, 70, 70, 70, + nil, nil, 127, nil, nil, 28, nil, 28, nil, nil, + 28, nil, 128, 128, 128, nil, 28, nil, 130, nil, + 130, nil, nil, 47, nil, nil, nil, 47, nil, nil, + 28, nil, nil, 47, nil, nil, nil, nil, nil, nil, + 130, nil, 130, nil, 130, nil, nil, 47, nil, nil, + nil, 180, nil, 180, nil, 180, nil, 180, nil, nil, + nil, nil, nil, nil, 50, 47, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 70, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 180, + nil, nil, 28, nil, nil, 130, 28, 130, nil, 130, + nil, 28, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 50, 130, nil, 128, 128, + 128, 128, nil, 128, 47, 50, nil, 28, nil, nil, + nil, 47, 47, 130, nil, nil, nil, nil, nil, nil, + 50, nil, nil, 28, 28, nil, nil, nil, nil, 47, + nil, nil, 22, nil, 47, 50, nil, nil, 50, nil, + nil, nil, nil, nil, nil, 50, nil, nil, nil, nil, + nil, nil, nil, 47, nil, 50, nil, nil, nil, 50, + 128, 128, 128, 128, nil, nil, nil, nil, nil, nil, + nil, nil, 22, nil, 128, 22, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 50, 50, + nil, nil, 50, nil, nil, nil, 22, nil, 50, 50, + nil, nil, nil, 50, 50, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 22, nil, nil, nil, 22, + nil, nil, nil, nil, nil, 22, 22, nil, nil, nil, + 22, 22, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 28, nil, nil, nil, 33, nil, nil, nil, nil, + 33, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 50, nil, nil, nil, nil, 50, + 50, nil, nil, 50, nil, nil, nil, nil, 33, 33, + 33, 28, nil, 50, 28, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 50, 22, nil, nil, 33, 28, 22, nil, nil, nil, + 22, nil, nil, nil, 33, 33, 33, nil, nil, 59, + 22, nil, nil, nil, 59, nil, nil, nil, 50, nil, + nil, nil, nil, nil, 28, nil, nil, 22, 28, 50, + nil, nil, nil, nil, 28, 28, nil, nil, nil, 28, + 28, nil, 59, 59, 59, nil, nil, nil, nil, nil, + 33, nil, nil, nil, nil, 22, nil, nil, nil, 33, + 50, 33, nil, nil, 50, nil, 22, nil, 59, nil, + 50, nil, nil, nil, nil, nil, nil, nil, 59, 59, + 59, 59, nil, nil, 50, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 22, 50, nil, nil, nil, nil, 22, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 22, nil, nil, 59, nil, nil, nil, nil, nil, + nil, nil, nil, 59, nil, 59, nil, nil, nil, 22, + 28, nil, nil, 22, nil, 28, 33, nil, 33, 28, + nil, 33, nil, 75, nil, nil, nil, 33, nil, 28, + nil, 50, nil, nil, nil, nil, nil, nil, 50, 50, + nil, 33, nil, nil, nil, nil, 28, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 50, nil, nil, nil, + nil, 50, nil, nil, nil, nil, nil, nil, 22, nil, + nil, nil, nil, nil, 28, 22, 22, nil, nil, nil, + 50, nil, nil, nil, nil, 28, nil, nil, nil, nil, + 59, nil, nil, 22, nil, nil, nil, nil, 22, nil, + nil, nil, nil, 33, nil, nil, nil, 33, nil, nil, + nil, 33, 33, nil, nil, 59, nil, nil, nil, nil, + 28, nil, nil, nil, nil, nil, 28, nil, 33, nil, + nil, nil, nil, nil, nil, nil, nil, 60, 33, nil, + 28, nil, 60, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 33, 33, nil, nil, 28, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 60, 60, 60, nil, 75, 75, nil, 59, nil, nil, + nil, 59, nil, nil, nil, 59, 59, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 60, nil, nil, nil, + nil, nil, 59, nil, nil, nil, 60, 60, 60, 60, + nil, nil, 59, nil, nil, nil, nil, 28, nil, nil, + nil, nil, nil, nil, 28, 28, nil, nil, 59, 59, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 28, nil, nil, nil, nil, 28, nil, 75, + nil, 75, 60, nil, 75, 75, nil, nil, nil, nil, + nil, 60, nil, 60, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 33, nil, nil, nil, nil, nil, nil, nil, + 33, nil, nil, nil, nil, nil, nil, nil, 33, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 60, nil, + nil, nil, 33, nil, nil, 33, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 60, nil, 75, 33, nil, nil, nil, + nil, nil, nil, 33, nil, nil, 59, nil, nil, nil, + nil, nil, nil, nil, 59, nil, nil, nil, nil, nil, + nil, nil, 59, nil, nil, 33, nil, nil, nil, 33, + nil, nil, nil, nil, nil, 33, 33, nil, nil, nil, + 33, 33, nil, nil, nil, nil, 59, nil, nil, 59, + nil, nil, nil, nil, nil, 60, nil, nil, nil, 60, + nil, nil, nil, 60, 60, nil, nil, nil, nil, nil, + 59, 33, nil, nil, nil, nil, nil, nil, nil, 75, + 60, 75, 33, 75, nil, nil, nil, nil, nil, nil, + 60, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 59, nil, nil, 60, 60, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 75, nil, nil, 75, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 75, nil, + nil, 33, nil, nil, nil, 59, 33, nil, nil, nil, + 33, nil, nil, nil, nil, nil, 59, nil, nil, nil, + 33, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 33, nil, nil, + nil, 75, nil, nil, nil, nil, nil, nil, nil, nil, + 75, 75, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 33, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 59, 33, nil, nil, nil, + 59, nil, 75, nil, 59, 75, nil, nil, nil, nil, + nil, nil, nil, nil, 59, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 75, nil, nil, nil, nil, nil, + nil, 33, nil, nil, nil, nil, nil, 33, nil, nil, + nil, nil, nil, nil, 60, nil, nil, nil, nil, nil, + 75, 33, 60, nil, nil, nil, nil, nil, nil, 59, + 60, nil, nil, nil, 33, nil, nil, nil, nil, 33, + 59, nil, 35, 33, nil, nil, nil, nil, nil, nil, + nil, 35, 35, 35, 60, nil, nil, 60, nil, nil, + nil, nil, nil, nil, 35, 35, nil, 35, nil, nil, + nil, nil, nil, nil, nil, 59, 75, nil, 60, nil, + nil, 59, 35, 35, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 33, 59, nil, nil, 33, nil, + nil, nil, nil, nil, nil, 33, 33, nil, 59, nil, + nil, 60, nil, 59, nil, nil, nil, 59, nil, nil, + nil, nil, nil, 33, nil, nil, nil, nil, 33, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 75, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 60, nil, nil, nil, 75, nil, nil, + nil, nil, nil, nil, 60, nil, nil, nil, 59, nil, + nil, nil, 59, nil, nil, 75, nil, nil, nil, 59, + 59, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 59, nil, nil, + nil, nil, 59, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 60, nil, nil, nil, nil, 60, nil, + nil, nil, 60, nil, 35, 35, nil, nil, 35, 35, + nil, nil, 60, nil, 35, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 35, nil, nil, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, nil, nil, nil, nil, 35, 60, nil, nil, + nil, nil, nil, 35, 35, nil, nil, nil, 60, nil, + nil, nil, 35, nil, nil, nil, nil, nil, nil, 35, + nil, 35, nil, nil, 35, 35, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 60, nil, nil, nil, nil, nil, 60, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 35, 60, 35, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 60, nil, nil, nil, + nil, 60, nil, nil, nil, 60, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 60, nil, nil, nil, + 60, nil, nil, nil, nil, 35, nil, 60, 60, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 60, nil, nil, nil, nil, + 60, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 35, nil, + 35, 35, 35, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 35, + nil, 35, nil, 35, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 35, + nil, nil, nil, nil, nil, nil, nil, nil, 35, 35, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 35, nil, nil, 35, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 35, 35, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 35, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 35, 35, 35, nil, nil, nil, 35, nil, nil, + 35, 35, 35, 35, nil, nil, nil, 35, 35, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 35, nil, nil, 35, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 35, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 35, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 35, nil, nil, nil, + nil, nil, nil, nil, 35, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 35, 35, 35, + 35, nil, 35, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 35, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 35, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 35, 35, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 35 ] + +racc_goto_pointer = [ + nil, 135, 104, nil, 28, 94, 42, 39, 74, -329, + -31, -509, -569, -649, nil, -357, -2, 147, -13, 212, + 93, 68, 885, -147, -46, 22, 40, -131, 1034, 3, + -202, -370, 1, 1545, -19, 2392, -10, -383, nil, -20, + nil, nil, -5, -189, 49, -244, -410, 441, -317, nil, + 848, 118, 79, 108, -105, nil, 25, 76, -280, 1619, + 1877, -270, 68, -67, 12, nil, nil, 38, 45, -236, + 471, 1, nil, -21, 129, 1702, 114, -42, 91, -258, + 129, 14, -309, -273, -439, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 105, 118, -61, nil, -163, -283, + -630, -330, 113, nil, -185, 25, nil, -537, 112, 127, + -148, 128, 125, -377, -530, -178, -186, -373, -636, -783, + 20, -555, -754, -575, nil, 115, -557, 215, 401, -572, + 346, -663, -491, -539, nil, -661, -711, -786, -761, -338, + -587, -132, -445, -382, -6, -648, -632, -338, -24, nil, + -31, -28, nil, nil, -379, -646, -409, -535, nil, nil, + 178, 23, 176, 176, 176, -238, -288, 178, 178, 178, + -308, -307, -296, -368, nil, nil, 98, -526, 235, -706, + 302, -521, -625, nil, -677, -778, nil, nil, -410 ] + +racc_goto_default = [ + nil, nil, nil, 3, nil, 4, 353, 299, nil, nil, + 533, nil, 821, nil, 296, 297, nil, nil, nil, 11, + 12, 18, 232, nil, nil, 14, nil, 418, 233, 327, + nil, nil, 566, 231, 453, 21, nil, nil, 348, 22, + 23, 24, nil, 655, nil, nil, nil, 316, nil, 25, + 313, 432, 32, nil, nil, 34, 37, 36, nil, 228, + 229, 365, nil, 134, 440, 133, 136, 79, 80, nil, + 423, 94, 44, 47, 264, 288, nil, 790, 433, nil, + 434, 445, 614, 496, 286, 272, 48, 49, 50, 51, + 52, 53, 54, 55, 56, nil, 273, 62, nil, nil, + nil, nil, nil, 70, nil, 548, 71, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 812, + 683, nil, 813, 956, 848, 671, nil, 672, nil, nil, + 673, nil, 675, nil, 777, nil, nil, nil, 681, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 444, + nil, nil, 634, 628, nil, nil, nil, nil, 78, 81, + 82, nil, nil, nil, nil, nil, 576, nil, nil, nil, + nil, nil, nil, 877, 727, 670, nil, 674, 885, 686, + 688, 689, 860, 692, 693, 861, 696, 699, 291 ] + +racc_reduce_table = [ + 0, 0, :racc_error, + 1, 146, :_reduce_none, + 2, 147, :_reduce_2, + 0, 148, :_reduce_3, + 1, 148, :_reduce_4, + 3, 148, :_reduce_5, + 2, 148, :_reduce_6, + 1, 150, :_reduce_none, + 2, 150, :_reduce_8, + 3, 153, :_reduce_9, + 4, 154, :_reduce_10, + 2, 155, :_reduce_11, + 0, 159, :_reduce_12, + 1, 159, :_reduce_13, + 3, 159, :_reduce_14, + 2, 159, :_reduce_15, + 1, 160, :_reduce_none, + 2, 160, :_reduce_17, + 0, 171, :_reduce_18, + 4, 152, :_reduce_19, + 3, 152, :_reduce_20, + 3, 152, :_reduce_21, + 3, 152, :_reduce_22, + 2, 152, :_reduce_23, + 3, 152, :_reduce_24, + 3, 152, :_reduce_25, + 3, 152, :_reduce_26, + 3, 152, :_reduce_27, + 3, 152, :_reduce_28, + 4, 152, :_reduce_29, + 1, 152, :_reduce_none, + 3, 152, :_reduce_31, + 3, 152, :_reduce_32, + 3, 152, :_reduce_33, + 1, 152, :_reduce_none, + 3, 164, :_reduce_35, + 3, 164, :_reduce_36, + 6, 164, :_reduce_37, + 5, 164, :_reduce_38, + 5, 164, :_reduce_39, + 5, 164, :_reduce_40, + 5, 164, :_reduce_41, + 3, 164, :_reduce_42, + 1, 172, :_reduce_none, + 3, 172, :_reduce_44, + 1, 172, :_reduce_none, + 1, 170, :_reduce_none, + 3, 170, :_reduce_47, + 3, 170, :_reduce_48, + 3, 170, :_reduce_49, + 2, 170, :_reduce_50, + 1, 170, :_reduce_none, + 1, 163, :_reduce_none, + 0, 183, :_reduce_53, + 3, 181, :_reduce_54, + 1, 166, :_reduce_none, + 1, 166, :_reduce_none, + 1, 185, :_reduce_none, + 4, 185, :_reduce_58, + 0, 193, :_reduce_59, + 4, 190, :_reduce_60, + 1, 192, :_reduce_none, + 2, 184, :_reduce_62, + 3, 184, :_reduce_63, + 4, 184, :_reduce_64, + 5, 184, :_reduce_65, + 4, 184, :_reduce_66, + 5, 184, :_reduce_67, + 2, 184, :_reduce_68, + 2, 184, :_reduce_69, + 2, 184, :_reduce_70, + 2, 184, :_reduce_71, + 2, 184, :_reduce_72, + 1, 165, :_reduce_73, + 3, 165, :_reduce_74, + 1, 198, :_reduce_75, + 3, 198, :_reduce_76, + 1, 197, :_reduce_none, + 2, 197, :_reduce_78, + 3, 197, :_reduce_79, + 5, 197, :_reduce_80, + 2, 197, :_reduce_81, + 4, 197, :_reduce_82, + 2, 197, :_reduce_83, + 4, 197, :_reduce_84, + 1, 197, :_reduce_85, + 3, 197, :_reduce_86, + 1, 201, :_reduce_none, + 3, 201, :_reduce_88, + 2, 200, :_reduce_89, + 3, 200, :_reduce_90, + 1, 203, :_reduce_91, + 3, 203, :_reduce_92, + 1, 202, :_reduce_93, + 1, 202, :_reduce_94, + 4, 202, :_reduce_95, + 3, 202, :_reduce_96, + 3, 202, :_reduce_97, + 3, 202, :_reduce_98, + 3, 202, :_reduce_99, + 2, 202, :_reduce_100, + 1, 202, :_reduce_101, + 1, 167, :_reduce_102, + 1, 167, :_reduce_103, + 4, 167, :_reduce_104, + 3, 167, :_reduce_105, + 3, 167, :_reduce_106, + 3, 167, :_reduce_107, + 3, 167, :_reduce_108, + 2, 167, :_reduce_109, + 1, 167, :_reduce_110, + 1, 206, :_reduce_111, + 1, 206, :_reduce_none, + 2, 207, :_reduce_113, + 1, 207, :_reduce_114, + 3, 207, :_reduce_115, + 1, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 211, :_reduce_121, + 1, 211, :_reduce_none, + 1, 161, :_reduce_none, + 1, 161, :_reduce_none, + 1, 162, :_reduce_125, + 0, 214, :_reduce_126, + 4, 162, :_reduce_127, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 3, 180, :_reduce_199, + 3, 180, :_reduce_200, + 6, 180, :_reduce_201, + 5, 180, :_reduce_202, + 5, 180, :_reduce_203, + 5, 180, :_reduce_204, + 5, 180, :_reduce_205, + 4, 180, :_reduce_206, + 3, 180, :_reduce_207, + 3, 180, :_reduce_208, + 3, 180, :_reduce_209, + 3, 180, :_reduce_210, + 3, 180, :_reduce_211, + 3, 180, :_reduce_212, + 3, 180, :_reduce_213, + 3, 180, :_reduce_214, + 3, 180, :_reduce_215, + 4, 180, :_reduce_216, + 2, 180, :_reduce_217, + 2, 180, :_reduce_218, + 3, 180, :_reduce_219, + 3, 180, :_reduce_220, + 3, 180, :_reduce_221, + 3, 180, :_reduce_222, + 1, 180, :_reduce_none, + 3, 180, :_reduce_224, + 3, 180, :_reduce_225, + 3, 180, :_reduce_226, + 3, 180, :_reduce_227, + 3, 180, :_reduce_228, + 2, 180, :_reduce_229, + 2, 180, :_reduce_230, + 3, 180, :_reduce_231, + 3, 180, :_reduce_232, + 3, 180, :_reduce_233, + 3, 180, :_reduce_234, + 3, 180, :_reduce_235, + 6, 180, :_reduce_236, + 1, 180, :_reduce_none, + 1, 219, :_reduce_none, + 1, 219, :_reduce_none, + 1, 219, :_reduce_none, + 1, 219, :_reduce_none, + 3, 217, :_reduce_242, + 3, 217, :_reduce_243, + 1, 220, :_reduce_none, + 1, 221, :_reduce_none, + 2, 221, :_reduce_none, + 4, 221, :_reduce_247, + 2, 221, :_reduce_248, + 1, 215, :_reduce_none, + 3, 215, :_reduce_250, + 3, 226, :_reduce_251, + 0, 227, :_reduce_252, + 1, 227, :_reduce_none, + 0, 175, :_reduce_254, + 1, 175, :_reduce_none, + 2, 175, :_reduce_none, + 4, 175, :_reduce_257, + 2, 175, :_reduce_258, + 1, 196, :_reduce_259, + 2, 196, :_reduce_260, + 2, 196, :_reduce_261, + 4, 196, :_reduce_262, + 1, 196, :_reduce_263, + 0, 230, :_reduce_264, + 2, 189, :_reduce_265, + 2, 229, :_reduce_266, + 2, 228, :_reduce_267, + 0, 228, :_reduce_268, + 1, 223, :_reduce_269, + 2, 223, :_reduce_270, + 3, 223, :_reduce_271, + 4, 223, :_reduce_272, + 1, 169, :_reduce_273, + 1, 169, :_reduce_none, + 3, 168, :_reduce_275, + 4, 168, :_reduce_276, + 2, 168, :_reduce_277, + 1, 218, :_reduce_none, + 1, 218, :_reduce_none, + 1, 218, :_reduce_none, + 1, 218, :_reduce_none, + 1, 218, :_reduce_none, + 1, 218, :_reduce_none, + 1, 218, :_reduce_none, + 1, 218, :_reduce_none, + 1, 218, :_reduce_none, + 1, 218, :_reduce_none, + 1, 218, :_reduce_288, + 0, 254, :_reduce_289, + 4, 218, :_reduce_290, + 0, 255, :_reduce_291, + 4, 218, :_reduce_292, + 0, 256, :_reduce_293, + 4, 218, :_reduce_294, + 3, 218, :_reduce_295, + 3, 218, :_reduce_296, + 2, 218, :_reduce_297, + 3, 218, :_reduce_298, + 3, 218, :_reduce_299, + 1, 218, :_reduce_300, + 4, 218, :_reduce_301, + 3, 218, :_reduce_302, + 1, 218, :_reduce_303, + 5, 218, :_reduce_304, + 4, 218, :_reduce_305, + 3, 218, :_reduce_306, + 2, 218, :_reduce_307, + 1, 218, :_reduce_none, + 2, 218, :_reduce_309, + 0, 257, :_reduce_310, + 3, 218, :_reduce_311, + 6, 218, :_reduce_312, + 6, 218, :_reduce_313, + 4, 218, :_reduce_314, + 4, 218, :_reduce_315, + 5, 218, :_reduce_316, + 4, 218, :_reduce_317, + 6, 218, :_reduce_318, + 0, 258, :_reduce_319, + 6, 218, :_reduce_320, + 0, 259, :_reduce_321, + 7, 218, :_reduce_322, + 0, 260, :_reduce_323, + 5, 218, :_reduce_324, + 0, 261, :_reduce_325, + 6, 218, :_reduce_326, + 0, 262, :_reduce_327, + 0, 263, :_reduce_328, + 9, 218, :_reduce_329, + 1, 218, :_reduce_330, + 1, 218, :_reduce_331, + 1, 218, :_reduce_332, + 1, 218, :_reduce_333, + 1, 174, :_reduce_none, + 1, 248, :_reduce_335, + 1, 251, :_reduce_336, + 1, 195, :_reduce_337, + 1, 244, :_reduce_none, + 1, 244, :_reduce_none, + 2, 244, :_reduce_340, + 1, 182, :_reduce_none, + 1, 182, :_reduce_none, + 1, 245, :_reduce_none, + 5, 245, :_reduce_344, + 1, 157, :_reduce_none, + 2, 157, :_reduce_346, + 1, 247, :_reduce_none, + 1, 247, :_reduce_none, + 1, 264, :_reduce_349, + 3, 264, :_reduce_350, + 1, 267, :_reduce_351, + 3, 267, :_reduce_352, + 1, 266, :_reduce_none, + 4, 266, :_reduce_354, + 6, 266, :_reduce_355, + 3, 266, :_reduce_356, + 5, 266, :_reduce_357, + 2, 266, :_reduce_358, + 4, 266, :_reduce_359, + 1, 266, :_reduce_360, + 3, 266, :_reduce_361, + 4, 268, :_reduce_362, + 2, 268, :_reduce_363, + 2, 268, :_reduce_364, + 1, 268, :_reduce_365, + 2, 273, :_reduce_366, + 0, 273, :_reduce_367, + 6, 274, :_reduce_368, + 8, 274, :_reduce_369, + 4, 274, :_reduce_370, + 6, 274, :_reduce_371, + 4, 274, :_reduce_372, + 2, 274, :_reduce_none, + 6, 274, :_reduce_374, + 2, 274, :_reduce_375, + 4, 274, :_reduce_376, + 6, 274, :_reduce_377, + 2, 274, :_reduce_378, + 4, 274, :_reduce_379, + 2, 274, :_reduce_380, + 4, 274, :_reduce_381, + 1, 274, :_reduce_none, + 0, 278, :_reduce_383, + 1, 278, :_reduce_384, + 3, 279, :_reduce_385, + 1, 279, :_reduce_386, + 4, 279, :_reduce_387, + 1, 280, :_reduce_388, + 4, 280, :_reduce_389, + 1, 281, :_reduce_390, + 3, 281, :_reduce_391, + 1, 282, :_reduce_392, + 1, 282, :_reduce_none, + 0, 286, :_reduce_394, + 0, 287, :_reduce_395, + 4, 243, :_reduce_396, + 4, 284, :_reduce_397, + 1, 284, :_reduce_398, + 0, 290, :_reduce_399, + 4, 285, :_reduce_400, + 0, 291, :_reduce_401, + 4, 285, :_reduce_402, + 0, 293, :_reduce_403, + 4, 289, :_reduce_404, + 2, 186, :_reduce_405, + 4, 186, :_reduce_406, + 5, 186, :_reduce_407, + 5, 186, :_reduce_408, + 2, 242, :_reduce_409, + 4, 242, :_reduce_410, + 4, 242, :_reduce_411, + 3, 242, :_reduce_412, + 3, 242, :_reduce_413, + 3, 242, :_reduce_414, + 2, 242, :_reduce_415, + 1, 242, :_reduce_416, + 4, 242, :_reduce_417, + 0, 295, :_reduce_418, + 4, 241, :_reduce_419, + 0, 296, :_reduce_420, + 4, 241, :_reduce_421, + 0, 297, :_reduce_422, + 3, 191, :_reduce_423, + 0, 298, :_reduce_424, + 0, 299, :_reduce_425, + 4, 292, :_reduce_426, + 5, 246, :_reduce_427, + 1, 300, :_reduce_428, + 1, 300, :_reduce_none, + 6, 156, :_reduce_430, + 0, 156, :_reduce_431, + 1, 301, :_reduce_432, + 1, 301, :_reduce_none, + 1, 301, :_reduce_none, + 2, 302, :_reduce_435, + 1, 302, :_reduce_none, + 2, 158, :_reduce_437, + 1, 158, :_reduce_none, + 1, 231, :_reduce_none, + 1, 231, :_reduce_none, + 1, 231, :_reduce_none, + 1, 232, :_reduce_442, + 1, 304, :_reduce_443, + 2, 304, :_reduce_444, + 3, 305, :_reduce_445, + 1, 305, :_reduce_446, + 1, 305, :_reduce_447, + 3, 233, :_reduce_448, + 4, 234, :_reduce_449, + 3, 235, :_reduce_450, + 0, 309, :_reduce_451, + 3, 309, :_reduce_452, + 1, 310, :_reduce_453, + 2, 310, :_reduce_454, + 3, 237, :_reduce_455, + 0, 312, :_reduce_456, + 3, 312, :_reduce_457, + 3, 236, :_reduce_458, + 3, 238, :_reduce_459, + 0, 313, :_reduce_460, + 3, 313, :_reduce_461, + 0, 314, :_reduce_462, + 3, 314, :_reduce_463, + 0, 306, :_reduce_464, + 2, 306, :_reduce_465, + 0, 307, :_reduce_466, + 2, 307, :_reduce_467, + 0, 308, :_reduce_468, + 2, 308, :_reduce_469, + 1, 311, :_reduce_470, + 2, 311, :_reduce_471, + 0, 316, :_reduce_472, + 4, 311, :_reduce_473, + 1, 315, :_reduce_474, + 1, 315, :_reduce_475, + 1, 315, :_reduce_476, + 1, 315, :_reduce_none, + 1, 212, :_reduce_478, + 3, 213, :_reduce_479, + 1, 303, :_reduce_480, + 2, 303, :_reduce_481, + 1, 216, :_reduce_482, + 1, 216, :_reduce_483, + 1, 216, :_reduce_484, + 1, 216, :_reduce_485, + 1, 204, :_reduce_486, + 1, 204, :_reduce_487, + 1, 204, :_reduce_488, + 1, 204, :_reduce_489, + 1, 204, :_reduce_490, + 1, 205, :_reduce_491, + 1, 205, :_reduce_492, + 1, 205, :_reduce_493, + 1, 205, :_reduce_494, + 1, 205, :_reduce_495, + 1, 205, :_reduce_496, + 1, 205, :_reduce_497, + 1, 239, :_reduce_498, + 1, 239, :_reduce_499, + 1, 173, :_reduce_500, + 1, 173, :_reduce_501, + 1, 178, :_reduce_502, + 1, 178, :_reduce_503, + 0, 317, :_reduce_504, + 4, 249, :_reduce_505, + 0, 249, :_reduce_506, + 3, 252, :_reduce_507, + 0, 319, :_reduce_508, + 3, 252, :_reduce_509, + 4, 318, :_reduce_510, + 2, 318, :_reduce_511, + 2, 318, :_reduce_512, + 1, 318, :_reduce_513, + 2, 321, :_reduce_514, + 0, 321, :_reduce_515, + 6, 288, :_reduce_516, + 8, 288, :_reduce_517, + 4, 288, :_reduce_518, + 6, 288, :_reduce_519, + 4, 288, :_reduce_520, + 6, 288, :_reduce_521, + 2, 288, :_reduce_522, + 4, 288, :_reduce_523, + 6, 288, :_reduce_524, + 2, 288, :_reduce_525, + 4, 288, :_reduce_526, + 2, 288, :_reduce_527, + 4, 288, :_reduce_528, + 1, 288, :_reduce_529, + 0, 288, :_reduce_530, + 1, 283, :_reduce_531, + 1, 283, :_reduce_532, + 1, 283, :_reduce_533, + 1, 283, :_reduce_534, + 1, 265, :_reduce_none, + 1, 265, :_reduce_536, + 1, 323, :_reduce_537, + 1, 324, :_reduce_538, + 3, 324, :_reduce_539, + 1, 275, :_reduce_540, + 3, 275, :_reduce_541, + 1, 325, :_reduce_542, + 2, 326, :_reduce_543, + 1, 326, :_reduce_544, + 2, 327, :_reduce_545, + 1, 327, :_reduce_546, + 1, 269, :_reduce_547, + 3, 269, :_reduce_548, + 1, 320, :_reduce_549, + 3, 320, :_reduce_550, + 1, 328, :_reduce_none, + 1, 328, :_reduce_none, + 2, 270, :_reduce_553, + 1, 270, :_reduce_554, + 3, 329, :_reduce_555, + 3, 330, :_reduce_556, + 1, 276, :_reduce_557, + 3, 276, :_reduce_558, + 1, 322, :_reduce_559, + 3, 322, :_reduce_560, + 1, 331, :_reduce_none, + 1, 331, :_reduce_none, + 2, 277, :_reduce_563, + 1, 277, :_reduce_564, + 1, 332, :_reduce_none, + 1, 332, :_reduce_none, + 2, 272, :_reduce_567, + 2, 271, :_reduce_568, + 0, 271, :_reduce_569, + 1, 253, :_reduce_none, + 3, 253, :_reduce_571, + 0, 240, :_reduce_572, + 2, 240, :_reduce_none, + 1, 225, :_reduce_574, + 3, 225, :_reduce_575, + 3, 333, :_reduce_576, + 2, 333, :_reduce_577, + 4, 333, :_reduce_578, + 2, 333, :_reduce_579, + 1, 194, :_reduce_none, + 1, 194, :_reduce_none, + 1, 194, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 294, :_reduce_none, + 1, 294, :_reduce_none, + 1, 294, :_reduce_none, + 1, 187, :_reduce_none, + 1, 187, :_reduce_none, + 1, 177, :_reduce_592, + 1, 177, :_reduce_593, + 0, 149, :_reduce_none, + 1, 149, :_reduce_none, + 0, 179, :_reduce_none, + 1, 179, :_reduce_none, + 2, 199, :_reduce_598, + 2, 176, :_reduce_599, + 0, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 250, :_reduce_603, + 1, 250, :_reduce_none, + 1, 151, :_reduce_none, + 2, 151, :_reduce_none, + 0, 222, :_reduce_607 ] + +racc_reduce_n = 608 + +racc_shift_n = 1035 + +racc_token_table = { + false => 0, + :error => 1, + :kCLASS => 2, + :kMODULE => 3, + :kDEF => 4, + :kUNDEF => 5, + :kBEGIN => 6, + :kRESCUE => 7, + :kENSURE => 8, + :kEND => 9, + :kIF => 10, + :kUNLESS => 11, + :kTHEN => 12, + :kELSIF => 13, + :kELSE => 14, + :kCASE => 15, + :kWHEN => 16, + :kWHILE => 17, + :kUNTIL => 18, + :kFOR => 19, + :kBREAK => 20, + :kNEXT => 21, + :kREDO => 22, + :kRETRY => 23, + :kIN => 24, + :kDO => 25, + :kDO_COND => 26, + :kDO_BLOCK => 27, + :kDO_LAMBDA => 28, + :kRETURN => 29, + :kYIELD => 30, + :kSUPER => 31, + :kSELF => 32, + :kNIL => 33, + :kTRUE => 34, + :kFALSE => 35, + :kAND => 36, + :kOR => 37, + :kNOT => 38, + :kIF_MOD => 39, + :kUNLESS_MOD => 40, + :kWHILE_MOD => 41, + :kUNTIL_MOD => 42, + :kRESCUE_MOD => 43, + :kALIAS => 44, + :kDEFINED => 45, + :klBEGIN => 46, + :klEND => 47, + :k__LINE__ => 48, + :k__FILE__ => 49, + :k__ENCODING__ => 50, + :tIDENTIFIER => 51, + :tFID => 52, + :tGVAR => 53, + :tIVAR => 54, + :tCONSTANT => 55, + :tLABEL => 56, + :tCVAR => 57, + :tNTH_REF => 58, + :tBACK_REF => 59, + :tSTRING_CONTENT => 60, + :tINTEGER => 61, + :tFLOAT => 62, + :tUPLUS => 63, + :tUMINUS => 64, + :tUNARY_NUM => 65, + :tPOW => 66, + :tCMP => 67, + :tEQ => 68, + :tEQQ => 69, + :tNEQ => 70, + :tGEQ => 71, + :tLEQ => 72, + :tANDOP => 73, + :tOROP => 74, + :tMATCH => 75, + :tNMATCH => 76, + :tDOT => 77, + :tDOT2 => 78, + :tDOT3 => 79, + :tAREF => 80, + :tASET => 81, + :tLSHFT => 82, + :tRSHFT => 83, + :tCOLON2 => 84, + :tCOLON3 => 85, + :tOP_ASGN => 86, + :tASSOC => 87, + :tLPAREN => 88, + :tLPAREN2 => 89, + :tRPAREN => 90, + :tLPAREN_ARG => 91, + :tLBRACK => 92, + :tLBRACK2 => 93, + :tRBRACK => 94, + :tLBRACE => 95, + :tLBRACE_ARG => 96, + :tSTAR => 97, + :tSTAR2 => 98, + :tAMPER => 99, + :tAMPER2 => 100, + :tTILDE => 101, + :tPERCENT => 102, + :tDIVIDE => 103, + :tDSTAR => 104, + :tPLUS => 105, + :tMINUS => 106, + :tLT => 107, + :tGT => 108, + :tPIPE => 109, + :tBANG => 110, + :tCARET => 111, + :tLCURLY => 112, + :tRCURLY => 113, + :tBACK_REF2 => 114, + :tSYMBEG => 115, + :tSTRING_BEG => 116, + :tXSTRING_BEG => 117, + :tREGEXP_BEG => 118, + :tREGEXP_OPT => 119, + :tWORDS_BEG => 120, + :tQWORDS_BEG => 121, + :tSYMBOLS_BEG => 122, + :tQSYMBOLS_BEG => 123, + :tSTRING_DBEG => 124, + :tSTRING_DVAR => 125, + :tSTRING_END => 126, + :tSTRING_DEND => 127, + :tSTRING => 128, + :tSYMBOL => 129, + :tNL => 130, + :tEH => 131, + :tCOLON => 132, + :tCOMMA => 133, + :tSPACE => 134, + :tSEMI => 135, + :tLAMBDA => 136, + :tLAMBEG => 137, + :tCHARACTER => 138, + :tRATIONAL => 139, + :tIMAGINARY => 140, + :tLABEL_END => 141, + :tANDDOT => 142, + :tEQL => 143, + :tLOWEST => 144 } + +racc_nt_base = 145 + +racc_use_result_var = true + +Racc_arg = [ + racc_action_table, + racc_action_check, + racc_action_default, + racc_action_pointer, + racc_goto_table, + racc_goto_check, + racc_goto_default, + racc_goto_pointer, + racc_nt_base, + racc_reduce_table, + racc_token_table, + racc_shift_n, + racc_reduce_n, + racc_use_result_var ] +Ractor.make_shareable(Racc_arg) if defined?(Ractor) + +Racc_token_to_s_table = [ + "$end", + "error", + "kCLASS", + "kMODULE", + "kDEF", + "kUNDEF", + "kBEGIN", + "kRESCUE", + "kENSURE", + "kEND", + "kIF", + "kUNLESS", + "kTHEN", + "kELSIF", + "kELSE", + "kCASE", + "kWHEN", + "kWHILE", + "kUNTIL", + "kFOR", + "kBREAK", + "kNEXT", + "kREDO", + "kRETRY", + "kIN", + "kDO", + "kDO_COND", + "kDO_BLOCK", + "kDO_LAMBDA", + "kRETURN", + "kYIELD", + "kSUPER", + "kSELF", + "kNIL", + "kTRUE", + "kFALSE", + "kAND", + "kOR", + "kNOT", + "kIF_MOD", + "kUNLESS_MOD", + "kWHILE_MOD", + "kUNTIL_MOD", + "kRESCUE_MOD", + "kALIAS", + "kDEFINED", + "klBEGIN", + "klEND", + "k__LINE__", + "k__FILE__", + "k__ENCODING__", + "tIDENTIFIER", + "tFID", + "tGVAR", + "tIVAR", + "tCONSTANT", + "tLABEL", + "tCVAR", + "tNTH_REF", + "tBACK_REF", + "tSTRING_CONTENT", + "tINTEGER", + "tFLOAT", + "tUPLUS", + "tUMINUS", + "tUNARY_NUM", + "tPOW", + "tCMP", + "tEQ", + "tEQQ", + "tNEQ", + "tGEQ", + "tLEQ", + "tANDOP", + "tOROP", + "tMATCH", + "tNMATCH", + "tDOT", + "tDOT2", + "tDOT3", + "tAREF", + "tASET", + "tLSHFT", + "tRSHFT", + "tCOLON2", + "tCOLON3", + "tOP_ASGN", + "tASSOC", + "tLPAREN", + "tLPAREN2", + "tRPAREN", + "tLPAREN_ARG", + "tLBRACK", + "tLBRACK2", + "tRBRACK", + "tLBRACE", + "tLBRACE_ARG", + "tSTAR", + "tSTAR2", + "tAMPER", + "tAMPER2", + "tTILDE", + "tPERCENT", + "tDIVIDE", + "tDSTAR", + "tPLUS", + "tMINUS", + "tLT", + "tGT", + "tPIPE", + "tBANG", + "tCARET", + "tLCURLY", + "tRCURLY", + "tBACK_REF2", + "tSYMBEG", + "tSTRING_BEG", + "tXSTRING_BEG", + "tREGEXP_BEG", + "tREGEXP_OPT", + "tWORDS_BEG", + "tQWORDS_BEG", + "tSYMBOLS_BEG", + "tQSYMBOLS_BEG", + "tSTRING_DBEG", + "tSTRING_DVAR", + "tSTRING_END", + "tSTRING_DEND", + "tSTRING", + "tSYMBOL", + "tNL", + "tEH", + "tCOLON", + "tCOMMA", + "tSPACE", + "tSEMI", + "tLAMBDA", + "tLAMBEG", + "tCHARACTER", + "tRATIONAL", + "tIMAGINARY", + "tLABEL_END", + "tANDDOT", + "tEQL", + "tLOWEST", + "$start", + "program", + "top_compstmt", + "top_stmts", + "opt_terms", + "top_stmt", + "terms", + "stmt", + "begin_block", + "bodystmt", + "compstmt", + "opt_rescue", + "opt_else", + "opt_ensure", + "stmts", + "stmt_or_begin", + "fitem", + "undef_list", + "expr_value", + "command_asgn", + "mlhs", + "command_call", + "lhs", + "mrhs", + "mrhs_arg", + "expr", + "@1", + "command_rhs", + "var_lhs", + "primary_value", + "opt_call_args", + "rbracket", + "call_op", + "backref", + "opt_nl", + "arg", + "expr_value_do", + "do", + "@2", + "command", + "block_command", + "block_call", + "dot_or_colon", + "operation2", + "command_args", + "cmd_brace_block", + "brace_body", + "fcall", + "@3", + "operation", + "k_return", + "call_args", + "mlhs_basic", + "mlhs_inner", + "rparen", + "mlhs_head", + "mlhs_item", + "mlhs_node", + "mlhs_post", + "user_variable", + "keyword_variable", + "cname", + "cpath", + "fname", + "op", + "reswords", + "fsym", + "symbol", + "dsym", + "@4", + "arg_rhs", + "simple_numeric", + "rel_expr", + "primary", + "relop", + "arg_value", + "aref_args", + "none", + "args", + "trailer", + "assocs", + "paren_args", + "opt_paren_args", + "opt_block_arg", + "block_arg", + "@5", + "literal", + "strings", + "xstring", + "regexp", + "words", + "qwords", + "symbols", + "qsymbols", + "var_ref", + "assoc_list", + "brace_block", + "method_call", + "lambda", + "then", + "if_tail", + "case_body", + "for_var", + "k_class", + "superclass", + "term", + "k_module", + "f_arglist", + "singleton", + "@6", + "@7", + "@8", + "@9", + "@10", + "@11", + "@12", + "@13", + "@14", + "@15", + "f_marg", + "f_norm_arg", + "f_margs", + "f_marg_list", + "block_args_tail", + "f_block_kwarg", + "f_kwrest", + "opt_f_block_arg", + "f_block_arg", + "opt_block_args_tail", + "block_param", + "f_arg", + "f_block_optarg", + "f_rest_arg", + "opt_block_param", + "block_param_def", + "opt_bv_decl", + "bv_decls", + "bvar", + "f_bad_arg", + "f_larglist", + "lambda_body", + "@16", + "@17", + "f_args", + "do_block", + "@18", + "@19", + "do_body", + "@20", + "operation3", + "@21", + "@22", + "@23", + "@24", + "@25", + "cases", + "exc_list", + "exc_var", + "numeric", + "string", + "string1", + "string_contents", + "xstring_contents", + "regexp_contents", + "word_list", + "word", + "string_content", + "symbol_list", + "qword_list", + "qsym_list", + "string_dvar", + "@26", + "@27", + "args_tail", + "@28", + "f_kwarg", + "opt_args_tail", + "f_optarg", + "f_arg_asgn", + "f_arg_item", + "f_label", + "f_kw", + "f_block_kw", + "kwrest_mark", + "f_opt", + "f_block_opt", + "restarg_mark", + "blkarg_mark", + "assoc" ] +Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) + +Racc_debug_parser = false + +##### State transition tables end ##### + +# reduce 0 omitted + +# reduce 1 omitted + +def _reduce_2(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_3(val, _values, result) + result = [] + + result +end + +def _reduce_4(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_5(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_6(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 7 omitted + +def _reduce_8(val, _values, result) + result = @builder.preexe(val[0], *val[1]) + + result +end + +def _reduce_9(val, _values, result) + result = val + + result +end + +def _reduce_10(val, _values, result) + rescue_bodies = val[1] + else_t, else_ = val[2] + ensure_t, ensure_ = val[3] + + if rescue_bodies.empty? && !else_t.nil? + diagnostic :warning, :useless_else, nil, else_t + end + + result = @builder.begin_body(val[0], + rescue_bodies, + else_t, else_, + ensure_t, ensure_) + + result +end + +def _reduce_11(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_12(val, _values, result) + result = [] + + result +end + +def _reduce_13(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_14(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_15(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 16 omitted + +def _reduce_17(val, _values, result) + diagnostic :error, :begin_in_method, nil, val[0] + + result +end + +def _reduce_18(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_19(val, _values, result) + result = @builder.alias(val[0], val[1], val[3]) + + result +end + +def _reduce_20(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.gvar(val[2])) + + result +end + +def _reduce_21(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.back_ref(val[2])) + + result +end + +def _reduce_22(val, _values, result) + diagnostic :error, :nth_ref_alias, nil, val[2] + + result +end + +def _reduce_23(val, _values, result) + result = @builder.undef_method(val[0], val[1]) + + result +end + +def _reduce_24(val, _values, result) + result = @builder.condition_mod(val[0], nil, + val[1], val[2]) + + result +end + +def _reduce_25(val, _values, result) + result = @builder.condition_mod(nil, val[0], + val[1], val[2]) + + result +end + +def _reduce_26(val, _values, result) + result = @builder.loop_mod(:while, val[0], val[1], val[2]) + + result +end + +def _reduce_27(val, _values, result) + result = @builder.loop_mod(:until, val[0], val[1], val[2]) + + result +end + +def _reduce_28(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_29(val, _values, result) + result = @builder.postexe(val[0], val[1], val[2], val[3]) + + result +end + +# reduce 30 omitted + +def _reduce_31(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_32(val, _values, result) + result = @builder.assign(val[0], val[1], + @builder.array(nil, val[2], nil)) + + result +end + +def _reduce_33(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +# reduce 34 omitted + +def _reduce_35(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_36(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_37(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_38(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_39(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_40(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_41(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_42(val, _values, result) + @builder.op_assign(val[0], val[1], val[2]) + + result +end + +# reduce 43 omitted + +def _reduce_44(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +# reduce 45 omitted + +# reduce 46 omitted + +def _reduce_47(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_48(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_49(val, _values, result) + result = @builder.not_op(val[0], nil, val[2], nil) + + result +end + +def _reduce_50(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +# reduce 51 omitted + +# reduce 52 omitted + +def _reduce_53(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_54(val, _values, result) + @lexer.cond.pop + result = [ val[1], val[2] ] + + result +end + +# reduce 55 omitted + +# reduce 56 omitted + +# reduce 57 omitted + +def _reduce_58(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_59(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_60(val, _values, result) + result = [ val[0], *val[2], val[3] ] + @context.in_block = val[1].in_block + + result +end + +# reduce 61 omitted + +def _reduce_62(val, _values, result) + result = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + result +end + +def _reduce_63(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + begin_t, args, body, end_t = val[2] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_64(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_65(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_66(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_67(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_68(val, _values, result) + result = @builder.keyword_cmd(:super, val[0], + nil, val[1], nil) + + result +end + +def _reduce_69(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], + nil, val[1], nil) + + result +end + +def _reduce_70(val, _values, result) + result = @builder.keyword_cmd(:return, val[0], + nil, val[1], nil) + + result +end + +def _reduce_71(val, _values, result) + result = @builder.keyword_cmd(:break, val[0], + nil, val[1], nil) + + result +end + +def _reduce_72(val, _values, result) + result = @builder.keyword_cmd(:next, val[0], + nil, val[1], nil) + + result +end + +def _reduce_73(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_74(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_75(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_76(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +# reduce 77 omitted + +def _reduce_78(val, _values, result) + result = val[0]. + push(val[1]) + + result +end + +def _reduce_79(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])) + + result +end + +def _reduce_80(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])). + concat(val[4]) + + result +end + +def _reduce_81(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])) + + result +end + +def _reduce_82(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])). + concat(val[3]) + + result +end + +def _reduce_83(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_84(val, _values, result) + result = [ @builder.splat(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_85(val, _values, result) + result = [ @builder.splat(val[0]) ] + + result +end + +def _reduce_86(val, _values, result) + result = [ @builder.splat(val[0]), + *val[2] ] + + result +end + +# reduce 87 omitted + +def _reduce_88(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_89(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_90(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_91(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_92(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_93(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_94(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_95(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_96(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_97(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_98(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_99(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_100(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_101(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_102(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_103(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_104(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_105(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_106(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_107(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_108(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_109(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_110(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_111(val, _values, result) + diagnostic :error, :module_name_const, nil, val[0] + + result +end + +# reduce 112 omitted + +def _reduce_113(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_114(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_115(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +# reduce 116 omitted + +# reduce 117 omitted + +# reduce 118 omitted + +# reduce 119 omitted + +# reduce 120 omitted + +def _reduce_121(val, _values, result) + result = @builder.symbol_internal(val[0]) + + result +end + +# reduce 122 omitted + +# reduce 123 omitted + +# reduce 124 omitted + +def _reduce_125(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_126(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_127(val, _values, result) + result = val[0] << val[3] + + result +end + +# reduce 128 omitted + +# reduce 129 omitted + +# reduce 130 omitted + +# reduce 131 omitted + +# reduce 132 omitted + +# reduce 133 omitted + +# reduce 134 omitted + +# reduce 135 omitted + +# reduce 136 omitted + +# reduce 137 omitted + +# reduce 138 omitted + +# reduce 139 omitted + +# reduce 140 omitted + +# reduce 141 omitted + +# reduce 142 omitted + +# reduce 143 omitted + +# reduce 144 omitted + +# reduce 145 omitted + +# reduce 146 omitted + +# reduce 147 omitted + +# reduce 148 omitted + +# reduce 149 omitted + +# reduce 150 omitted + +# reduce 151 omitted + +# reduce 152 omitted + +# reduce 153 omitted + +# reduce 154 omitted + +# reduce 155 omitted + +# reduce 156 omitted + +# reduce 157 omitted + +# reduce 158 omitted + +# reduce 159 omitted + +# reduce 160 omitted + +# reduce 161 omitted + +# reduce 162 omitted + +# reduce 163 omitted + +# reduce 164 omitted + +# reduce 165 omitted + +# reduce 166 omitted + +# reduce 167 omitted + +# reduce 168 omitted + +# reduce 169 omitted + +# reduce 170 omitted + +# reduce 171 omitted + +# reduce 172 omitted + +# reduce 173 omitted + +# reduce 174 omitted + +# reduce 175 omitted + +# reduce 176 omitted + +# reduce 177 omitted + +# reduce 178 omitted + +# reduce 179 omitted + +# reduce 180 omitted + +# reduce 181 omitted + +# reduce 182 omitted + +# reduce 183 omitted + +# reduce 184 omitted + +# reduce 185 omitted + +# reduce 186 omitted + +# reduce 187 omitted + +# reduce 188 omitted + +# reduce 189 omitted + +# reduce 190 omitted + +# reduce 191 omitted + +# reduce 192 omitted + +# reduce 193 omitted + +# reduce 194 omitted + +# reduce 195 omitted + +# reduce 196 omitted + +# reduce 197 omitted + +# reduce 198 omitted + +def _reduce_199(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_200(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_201(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_202(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_203(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_204(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_205(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_206(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_global(val[0], val[1])) + result = @builder.op_assign(const, val[2], val[3]) + + result +end + +def _reduce_207(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_208(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_209(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_210(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_211(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_212(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_213(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_214(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_215(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_216(val, _values, result) + result = @builder.unary_op(val[0], + @builder.binary_op( + val[1], val[2], val[3])) + + result +end + +def _reduce_217(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_218(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_219(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_220(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_221(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_222(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +# reduce 223 omitted + +def _reduce_224(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_225(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_226(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_227(val, _values, result) + result = @builder.match_op(val[0], val[1], val[2]) + + result +end + +def _reduce_228(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_229(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +def _reduce_230(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_231(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_232(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_233(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_234(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_235(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil) + + result +end + +def _reduce_236(val, _values, result) + result = @builder.ternary(val[0], val[1], + val[2], val[4], val[5]) + + result +end + +# reduce 237 omitted + +# reduce 238 omitted + +# reduce 239 omitted + +# reduce 240 omitted + +# reduce 241 omitted + +def _reduce_242(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_243(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +# reduce 244 omitted + +# reduce 245 omitted + +# reduce 246 omitted + +def _reduce_247(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_248(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +# reduce 249 omitted + +def _reduce_250(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_251(val, _values, result) + result = val + + result +end + +def _reduce_252(val, _values, result) + result = [ nil, [], nil ] + + result +end + +# reduce 253 omitted + +def _reduce_254(val, _values, result) + result = [] + + result +end + +# reduce 255 omitted + +# reduce 256 omitted + +def _reduce_257(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_258(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +def _reduce_259(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_260(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_261(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + result.concat(val[1]) + + result +end + +def _reduce_262(val, _values, result) + assocs = @builder.associate(nil, val[2], nil) + result = val[0] << assocs + result.concat(val[3]) + + result +end + +def _reduce_263(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_264(val, _values, result) + # When branch gets invoked by RACC's lookahead + # and command args start with '[' or '(' + # we need to put `true` to the cmdarg stack + # **before** `false` pushed by lexer + # m [], n + # ^ + # Right here we have cmdarg [...0] because + # lexer pushed it on '[' + # We need to modify cmdarg stack to [...10] + # + # For all other cases (like `m n` or `m n, []`) we simply put 1 to the stack + # and later lexer pushes corresponding bits on top of it. + last_token = @last_token[0] + lookahead = last_token == :tLBRACK || last_token == :tLPAREN_ARG + + if lookahead + top = @lexer.cmdarg.pop + @lexer.cmdarg.push(true) + @lexer.cmdarg.push(top) + else + @lexer.cmdarg.push(true) + end + + result +end + +def _reduce_265(val, _values, result) + # call_args can be followed by tLBRACE_ARG (that does cmdarg.push(0) in the lexer) + # but the push must be done after cmdarg.pop() in the parser. + # So this code does cmdarg.pop() to pop 0 pushed by tLBRACE_ARG, + # cmdarg.pop() to pop 1 pushed by command_args, + # and cmdarg.push(0) to restore back the flag set by tLBRACE_ARG. + last_token = @last_token[0] + lookahead = last_token == :tLBRACE_ARG + if lookahead + top = @lexer.cmdarg.pop + @lexer.cmdarg.pop + @lexer.cmdarg.push(top) + else + @lexer.cmdarg.pop + end + + result = val[1] + + result +end + +def _reduce_266(val, _values, result) + result = @builder.block_pass(val[0], val[1]) + + result +end + +def _reduce_267(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_268(val, _values, result) + result = [] + + result +end + +def _reduce_269(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_270(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_271(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_272(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_273(val, _values, result) + result = @builder.array(nil, val[0], nil) + + result +end + +# reduce 274 omitted + +def _reduce_275(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_276(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_277(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +# reduce 278 omitted + +# reduce 279 omitted + +# reduce 280 omitted + +# reduce 281 omitted + +# reduce 282 omitted + +# reduce 283 omitted + +# reduce 284 omitted + +# reduce 285 omitted + +# reduce 286 omitted + +# reduce 287 omitted + +def _reduce_288(val, _values, result) + result = @builder.call_method(nil, nil, val[0]) + + result +end + +def _reduce_289(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_290(val, _values, result) + @lexer.cmdarg.pop + + result = @builder.begin_keyword(val[0], val[2], val[3]) + + result +end + +def _reduce_291(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_292(val, _values, result) + result = @builder.begin(val[0], val[1], val[3]) + + result +end + +def _reduce_293(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_294(val, _values, result) + result = @builder.begin(val[0], nil, val[3]) + + result +end + +def _reduce_295(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_296(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +def _reduce_297(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_298(val, _values, result) + result = @builder.array(val[0], val[1], val[2]) + + result +end + +def _reduce_299(val, _values, result) + result = @builder.associate(val[0], val[1], val[2]) + + result +end + +def _reduce_300(val, _values, result) + result = @builder.keyword_cmd(:return, val[0]) + + result +end + +def _reduce_301(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_302(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2]) + + result +end + +def _reduce_303(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0]) + + result +end + +def _reduce_304(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], + val[2], [ val[3] ], val[4]) + + result +end + +def _reduce_305(val, _values, result) + result = @builder.not_op(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_306(val, _values, result) + result = @builder.not_op(val[0], val[1], nil, val[2]) + + result +end + +def _reduce_307(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0]) + + begin_t, args, body, end_t = val[1] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +# reduce 308 omitted + +def _reduce_309(val, _values, result) + begin_t, args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, args, body, end_t) + + result +end + +def _reduce_310(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_311(val, _values, result) + lambda_call = @builder.call_lambda(val[0]) + + args, (begin_t, body, end_t) = val[2] + result = @builder.block(lambda_call, + begin_t, args, body, end_t) + + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_312(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, val[5]) + + result +end + +def _reduce_313(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + else_, else_t, + val[3], val[5]) + + result +end + +def _reduce_314(val, _values, result) + result = @builder.loop(:while, val[0], *val[1], val[2], val[3]) + + result +end + +def _reduce_315(val, _values, result) + result = @builder.loop(:until, val[0], *val[1], val[2], val[3]) + + result +end + +def _reduce_316(val, _values, result) + *when_bodies, (else_t, else_body) = *val[3] + + result = @builder.case(val[0], val[1], + when_bodies, else_t, else_body, + val[4]) + + result +end + +def _reduce_317(val, _values, result) + *when_bodies, (else_t, else_body) = *val[2] + + result = @builder.case(val[0], nil, + when_bodies, else_t, else_body, + val[3]) + + result +end + +def _reduce_318(val, _values, result) + result = @builder.for(val[0], val[1], val[2], *val[3], val[4], val[5]) + + result +end + +def _reduce_319(val, _values, result) + local_push + @context.in_class = true + + result +end + +def _reduce_320(val, _values, result) + k_class, ctx = val[0] + if @context.in_def + diagnostic :error, :class_in_def, nil, k_class + end + + lt_t, superclass = val[2] + result = @builder.def_class(k_class, val[1], + lt_t, superclass, + val[4], val[5]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_321(val, _values, result) + @context.in_def = false + @context.in_class = false + local_push + + result +end + +def _reduce_322(val, _values, result) + k_class, ctx = val[0] + result = @builder.def_sclass(k_class, val[1], val[2], + val[5], val[6]) + + local_pop + @context.in_def = ctx.in_def + @context.in_class = ctx.in_class + + result +end + +def _reduce_323(val, _values, result) + @context.in_class = true + local_push + + result +end + +def _reduce_324(val, _values, result) + k_mod, ctx = val[0] + if @context.in_def + diagnostic :error, :module_in_def, nil, k_mod + end + + result = @builder.def_module(k_mod, val[1], + val[3], val[4]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_325(val, _values, result) + local_push + result = context.dup + @context.in_def = true + + result +end + +def _reduce_326(val, _values, result) + result = @builder.def_method(val[0], val[1], + val[3], val[4], val[5]) + + local_pop + @context.in_def = val[2].in_def + + result +end + +def _reduce_327(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_328(val, _values, result) + local_push + result = context.dup + @context.in_def = true + + result +end + +def _reduce_329(val, _values, result) + result = @builder.def_singleton(val[0], val[1], val[2], + val[4], val[6], val[7], val[8]) + + local_pop + @context.in_def = val[5].in_def + + result +end + +def _reduce_330(val, _values, result) + result = @builder.keyword_cmd(:break, val[0]) + + result +end + +def _reduce_331(val, _values, result) + result = @builder.keyword_cmd(:next, val[0]) + + result +end + +def _reduce_332(val, _values, result) + result = @builder.keyword_cmd(:redo, val[0]) + + result +end + +def _reduce_333(val, _values, result) + result = @builder.keyword_cmd(:retry, val[0]) + + result +end + +# reduce 334 omitted + +def _reduce_335(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_336(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_337(val, _values, result) + if @context.in_class && !@context.in_def && !(context.in_block || context.in_lambda) + diagnostic :error, :invalid_return, nil, val[0] + end + + result +end + +# reduce 338 omitted + +# reduce 339 omitted + +def _reduce_340(val, _values, result) + result = val[1] + + result +end + +# reduce 341 omitted + +# reduce 342 omitted + +# reduce 343 omitted + +def _reduce_344(val, _values, result) + else_t, else_ = val[4] + result = [ val[0], + @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, nil), + ] + + result +end + +# reduce 345 omitted + +def _reduce_346(val, _values, result) + result = val + + result +end + +# reduce 347 omitted + +# reduce 348 omitted + +def _reduce_349(val, _values, result) + result = @builder.arg(val[0]) + + result +end + +def _reduce_350(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_351(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_352(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 353 omitted + +def _reduce_354(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2], val[3])) + + result +end + +def _reduce_355(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2], val[3])). + concat(val[5]) + + result +end + +def _reduce_356(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2])) + + result +end + +def _reduce_357(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2])). + concat(val[4]) + + result +end + +def _reduce_358(val, _values, result) + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_359(val, _values, result) + result = [ @builder.restarg(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_360(val, _values, result) + result = [ @builder.restarg(val[0]) ] + + result +end + +def _reduce_361(val, _values, result) + result = [ @builder.restarg(val[0]), + *val[2] ] + + result +end + +def _reduce_362(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_363(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_364(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_365(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_366(val, _values, result) + result = val[1] + + result +end + +def _reduce_367(val, _values, result) + result = [] + + result +end + +def _reduce_368(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_369(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_370(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_371(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_372(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 373 omitted + +def _reduce_374(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_375(val, _values, result) + if val[1].empty? && val[0].size == 1 + result = [@builder.procarg0(val[0][0])] + else + result = val[0].concat(val[1]) + end + + result +end + +def _reduce_376(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_377(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_378(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_379(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_380(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_381(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 382 omitted + +def _reduce_383(val, _values, result) + result = @builder.args(nil, [], nil) + + result +end + +def _reduce_384(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_385(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + result +end + +def _reduce_386(val, _values, result) + result = @builder.args(val[0], [], val[0]) + + result +end + +def _reduce_387(val, _values, result) + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_388(val, _values, result) + result = [] + + result +end + +def _reduce_389(val, _values, result) + result = val[2] + + result +end + +def _reduce_390(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_391(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_392(val, _values, result) + @static_env.declare val[0][0] + result = @builder.shadowarg(val[0]) + + result +end + +# reduce 393 omitted + +def _reduce_394(val, _values, result) + @static_env.extend_dynamic + + result +end + +def _reduce_395(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_396(val, _values, result) + @lexer.cmdarg.pop + + result = [ val[1], val[3] ] + + @static_env.unextend + + result +end + +def _reduce_397(val, _values, result) + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_398(val, _values, result) + result = @builder.args(nil, val[0], nil) + + result +end + +def _reduce_399(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_400(val, _values, result) + result = [ val[0], val[2], val[3] ] + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_401(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_402(val, _values, result) + result = [ val[0], val[2], val[3] ] + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_403(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_404(val, _values, result) + result = [ val[0], *val[2], val[3] ] + @context.in_block = val[1].in_block + + result +end + +def _reduce_405(val, _values, result) + begin_t, block_args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, block_args, body, end_t) + + result +end + +def _reduce_406(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_407(val, _values, result) + lparen_t, args, rparen_t = val[3] + method_call = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_408(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_409(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.call_method(nil, nil, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_410(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_411(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_412(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2]) + + result +end + +def _reduce_413(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_414(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_415(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.keyword_cmd(:super, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_416(val, _values, result) + result = @builder.keyword_cmd(:zsuper, val[0]) + + result +end + +def _reduce_417(val, _values, result) + result = @builder.index(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_418(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_419(val, _values, result) + result = [ val[0], *val[2], val[3] ] + @context.in_block = val[1].in_block + + result +end + +def _reduce_420(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_421(val, _values, result) + result = [ val[0], *val[2], val[3] ] + @context.in_block = val[1].in_block + + result +end + +def _reduce_422(val, _values, result) + @static_env.extend_dynamic + + result +end + +def _reduce_423(val, _values, result) + result = [ val[1], val[2] ] + + @static_env.unextend + + result +end + +def _reduce_424(val, _values, result) + @static_env.extend_dynamic + + result +end + +def _reduce_425(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_426(val, _values, result) + result = [ val[2], val[3] ] + + @static_env.unextend + @lexer.cmdarg.pop + + result +end + +def _reduce_427(val, _values, result) + result = [ @builder.when(val[0], val[1], val[2], val[3]), + *val[4] ] + + result +end + +def _reduce_428(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 429 omitted + +def _reduce_430(val, _values, result) + assoc_t, exc_var = val[2] + + if val[1] + exc_list = @builder.array(nil, val[1], nil) + end + + result = [ @builder.rescue_body(val[0], + exc_list, assoc_t, exc_var, + val[3], val[4]), + *val[5] ] + + result +end + +def _reduce_431(val, _values, result) + result = [] + + result +end + +def _reduce_432(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 433 omitted + +# reduce 434 omitted + +def _reduce_435(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 436 omitted + +def _reduce_437(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 438 omitted + +# reduce 439 omitted + +# reduce 440 omitted + +# reduce 441 omitted + +def _reduce_442(val, _values, result) + result = @builder.string_compose(nil, val[0], nil) + + result +end + +def _reduce_443(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_444(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_445(val, _values, result) + string = @builder.string_compose(val[0], val[1], val[2]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_446(val, _values, result) + string = @builder.string(val[0]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_447(val, _values, result) + result = @builder.character(val[0]) + + result +end + +def _reduce_448(val, _values, result) + string = @builder.xstring_compose(val[0], val[1], val[2]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_449(val, _values, result) + opts = @builder.regexp_options(val[3]) + result = @builder.regexp_compose(val[0], val[1], val[2], opts) + + result +end + +def _reduce_450(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_451(val, _values, result) + result = [] + + result +end + +def _reduce_452(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_453(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_454(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_455(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_456(val, _values, result) + result = [] + + result +end + +def _reduce_457(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_458(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_459(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_460(val, _values, result) + result = [] + + result +end + +def _reduce_461(val, _values, result) + result = val[0] << @builder.string_internal(val[1]) + + result +end + +def _reduce_462(val, _values, result) + result = [] + + result +end + +def _reduce_463(val, _values, result) + result = val[0] << @builder.symbol_internal(val[1]) + + result +end + +def _reduce_464(val, _values, result) + result = [] + + result +end + +def _reduce_465(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_466(val, _values, result) + result = [] + + result +end + +def _reduce_467(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_468(val, _values, result) + result = [] + + result +end + +def _reduce_469(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_470(val, _values, result) + result = @builder.string_internal(val[0]) + + result +end + +def _reduce_471(val, _values, result) + result = val[1] + + result +end + +def _reduce_472(val, _values, result) + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + + result +end + +def _reduce_473(val, _values, result) + @lexer.cmdarg.pop + @lexer.cond.pop + + result = @builder.begin(val[0], val[2], val[3]) + + result +end + +def _reduce_474(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_475(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_476(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +# reduce 477 omitted + +def _reduce_478(val, _values, result) + @lexer.state = :expr_end + result = @builder.symbol(val[0]) + + result +end + +def _reduce_479(val, _values, result) + @lexer.state = :expr_end + result = @builder.symbol_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_480(val, _values, result) + result = val[0] + + result +end + +def _reduce_481(val, _values, result) + if @builder.respond_to? :negate + # AST builder interface compatibility + result = @builder.negate(val[0], val[1]) + else + result = @builder.unary_num(val[0], val[1]) + end + + result +end + +def _reduce_482(val, _values, result) + @lexer.state = :expr_end + result = @builder.integer(val[0]) + + result +end + +def _reduce_483(val, _values, result) + @lexer.state = :expr_end + result = @builder.float(val[0]) + + result +end + +def _reduce_484(val, _values, result) + @lexer.state = :expr_end + result = @builder.rational(val[0]) + + result +end + +def _reduce_485(val, _values, result) + @lexer.state = :expr_end + result = @builder.complex(val[0]) + + result +end + +def _reduce_486(val, _values, result) + result = @builder.ident(val[0]) + + result +end + +def _reduce_487(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_488(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_489(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_490(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +def _reduce_491(val, _values, result) + result = @builder.nil(val[0]) + + result +end + +def _reduce_492(val, _values, result) + result = @builder.self(val[0]) + + result +end + +def _reduce_493(val, _values, result) + result = @builder.true(val[0]) + + result +end + +def _reduce_494(val, _values, result) + result = @builder.false(val[0]) + + result +end + +def _reduce_495(val, _values, result) + result = @builder.__FILE__(val[0]) + + result +end + +def _reduce_496(val, _values, result) + result = @builder.__LINE__(val[0]) + + result +end + +def _reduce_497(val, _values, result) + result = @builder.__ENCODING__(val[0]) + + result +end + +def _reduce_498(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_499(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_500(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_501(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_502(val, _values, result) + result = @builder.nth_ref(val[0]) + + result +end + +def _reduce_503(val, _values, result) + result = @builder.back_ref(val[0]) + + result +end + +def _reduce_504(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_505(val, _values, result) + result = [ val[0], val[2] ] + + result +end + +def _reduce_506(val, _values, result) + result = nil + + result +end + +def _reduce_507(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + @lexer.state = :expr_value + + result +end + +def _reduce_508(val, _values, result) + result = @context.in_kwarg + @context.in_kwarg = true + + result +end + +def _reduce_509(val, _values, result) + @context.in_kwarg = val[0] + result = @builder.args(nil, val[1], nil) + + result +end + +def _reduce_510(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_511(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_512(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_513(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_514(val, _values, result) + result = val[1] + + result +end + +def _reduce_515(val, _values, result) + result = [] + + result +end + +def _reduce_516(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_517(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_518(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_519(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_520(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_521(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_522(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_523(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_524(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_525(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_526(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_527(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_528(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_529(val, _values, result) + result = val[0] + + result +end + +def _reduce_530(val, _values, result) + result = [] + + result +end + +def _reduce_531(val, _values, result) + diagnostic :error, :argument_const, nil, val[0] + + result +end + +def _reduce_532(val, _values, result) + diagnostic :error, :argument_ivar, nil, val[0] + + result +end + +def _reduce_533(val, _values, result) + diagnostic :error, :argument_gvar, nil, val[0] + + result +end + +def _reduce_534(val, _values, result) + diagnostic :error, :argument_cvar, nil, val[0] + + result +end + +# reduce 535 omitted + +def _reduce_536(val, _values, result) + @static_env.declare val[0][0] + + result = val[0] + + result +end + +def _reduce_537(val, _values, result) + result = val[0] + + result +end + +def _reduce_538(val, _values, result) + result = @builder.arg(val[0]) + + result +end + +def _reduce_539(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_540(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_541(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_542(val, _values, result) + check_kwarg_name(val[0]) + + @static_env.declare val[0][0] + + result = val[0] + + result +end + +def _reduce_543(val, _values, result) + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_544(val, _values, result) + result = @builder.kwarg(val[0]) + + result +end + +def _reduce_545(val, _values, result) + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_546(val, _values, result) + result = @builder.kwarg(val[0]) + + result +end + +def _reduce_547(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_548(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_549(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_550(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 551 omitted + +# reduce 552 omitted + +def _reduce_553(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.kwrestarg(val[0], val[1]) ] + + result +end + +def _reduce_554(val, _values, result) + result = [ @builder.kwrestarg(val[0]) ] + + result +end + +def _reduce_555(val, _values, result) + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_556(val, _values, result) + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_557(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_558(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_559(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_560(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 561 omitted + +# reduce 562 omitted + +def _reduce_563(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_564(val, _values, result) + result = [ @builder.restarg(val[0]) ] + + result +end + +# reduce 565 omitted + +# reduce 566 omitted + +def _reduce_567(val, _values, result) + @static_env.declare val[1][0] + + result = @builder.blockarg(val[0], val[1]) + + result +end + +def _reduce_568(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_569(val, _values, result) + result = [] + + result +end + +# reduce 570 omitted + +def _reduce_571(val, _values, result) + result = val[1] + + result +end + +def _reduce_572(val, _values, result) + result = [] + + result +end + +# reduce 573 omitted + +def _reduce_574(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_575(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_576(val, _values, result) + result = @builder.pair(val[0], val[1], val[2]) + + result +end + +def _reduce_577(val, _values, result) + result = @builder.pair_keyword(val[0], val[1]) + + result +end + +def _reduce_578(val, _values, result) + result = @builder.pair_quoted(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_579(val, _values, result) + result = @builder.kwsplat(val[0], val[1]) + + result +end + +# reduce 580 omitted + +# reduce 581 omitted + +# reduce 582 omitted + +# reduce 583 omitted + +# reduce 584 omitted + +# reduce 585 omitted + +# reduce 586 omitted + +# reduce 587 omitted + +# reduce 588 omitted + +# reduce 589 omitted + +# reduce 590 omitted + +# reduce 591 omitted + +def _reduce_592(val, _values, result) + result = [:dot, val[0][1]] + + result +end + +def _reduce_593(val, _values, result) + result = [:anddot, val[0][1]] + + result +end + +# reduce 594 omitted + +# reduce 595 omitted + +# reduce 596 omitted + +# reduce 597 omitted + +def _reduce_598(val, _values, result) + result = val[1] + + result +end + +def _reduce_599(val, _values, result) + result = val[1] + + result +end + +# reduce 600 omitted + +# reduce 601 omitted + +# reduce 602 omitted + +def _reduce_603(val, _values, result) + yyerrok + + result +end + +# reduce 604 omitted + +# reduce 605 omitted + +# reduce 606 omitted + +def _reduce_607(val, _values, result) + result = nil + + result +end + +def _reduce_none(val, _values, result) + val[0] +end + + end # class Ruby25 +end # module Parser diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby26.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby26.rb new file mode 100644 index 00000000..1e681f4b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby26.rb @@ -0,0 +1,10352 @@ +# -*- encoding:utf-8; warn-indent:false; frozen_string_literal: true -*- +# +# DO NOT MODIFY!!!! +# This file is automatically generated by Racc 1.8.1 +# from Racc grammar file "ruby26.y". +# + +require 'racc/parser.rb' + + +require_relative '../parser' + +module Parser + class Ruby26 < Parser::Base + + + def version + 26 + end + + def default_encoding + Encoding::UTF_8 + end + + def local_push + @static_env.extend_static + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + end + + def local_pop + @static_env.unextend + @lexer.cmdarg.pop + @lexer.cond.pop + end +##### State transition tables begin ### + +racc_action_table = [ + -489, 215, 216, 215, 216, 223, -102, -489, -489, -489, + 114, 550, -489, -489, -489, 221, -489, 277, 225, 591, + 263, 264, 270, 550, -489, 593, -489, -489, -489, 277, + 563, 277, -503, 127, 564, -103, -489, -489, 550, -489, + -489, -489, -489, -489, 550, 550, -102, -103, -110, -110, + -88, -109, -101, 792, -109, 557, 262, 261, 277, 226, + -74, 212, -110, 213, -105, -107, -489, -489, -489, -489, + -489, -489, -489, -489, -489, -489, -489, -489, -489, -489, + 222, 272, -489, -489, -489, 590, -489, -489, 706, -102, + -489, 592, 873, -489, -489, 226, -489, 226, -489, 214, + -489, 217, -489, -489, 276, -489, -489, -489, -489, -489, + -105, -489, -492, -489, -107, -93, 276, -104, 276, -492, + -492, -492, 272, -106, -492, -492, -492, -489, -492, 118, + -489, -489, -489, -489, 117, -489, -492, -489, -492, -492, + -492, 118, -489, -489, -94, 276, 117, -96, -492, -492, + -108, -492, -492, -492, -492, -492, 118, -104, -101, 826, + -100, 117, 118, 118, -102, -103, -110, 117, 117, -102, + -103, -110, -109, -96, -98, -106, 780, -109, -492, -492, + -492, -492, -492, -492, -492, -492, -492, -492, -492, -492, + -492, -492, 118, 266, -492, -492, -492, 117, -492, -492, + -586, 872, -492, 325, -98, -492, -492, 326, -492, -108, + -492, 779, -492, -96, -492, -492, 226, -492, -492, -492, + -492, -492, -298, -492, 396, -492, -95, -587, -105, -298, + -298, -298, -107, -105, 780, -298, -298, -107, -298, -492, + -586, -106, -492, -492, -492, -492, -106, -492, 409, -492, + 215, 216, -504, -96, -492, -492, -96, 458, -298, -298, + -95, -298, -298, -298, -298, -298, -96, 460, -108, 779, + -98, -489, -97, -108, -587, -104, 215, 216, -489, 683, + -104, 680, 679, 678, -97, 681, 215, 216, -298, -298, + -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, + -298, -298, 461, 459, -298, -298, -298, -492, 616, -103, + -98, -503, -298, -98, -492, -298, 96, 97, -99, 578, + -298, 225, -298, -98, -298, -298, -95, -298, -298, -298, + -298, -298, -499, -298, -590, -298, -489, -586, -97, -499, + 406, -590, -590, -590, 226, 408, 407, -590, -590, -298, + -590, 118, -298, -298, 489, -99, 117, -298, -93, -590, + -110, 891, 215, 216, -298, -108, -95, -583, -102, -95, + -590, -590, -492, -590, -590, -590, -590, -590, -97, -95, + 118, -97, 498, 580, 579, 117, 683, 578, 680, 679, + 678, -97, 681, 738, 98, 99, 500, -499, 578, 223, + -590, -590, -590, -590, -590, -590, -590, -590, -590, -590, + -590, -590, -590, -590, 527, 502, -590, -590, -590, -489, + 617, 96, 97, 578, -590, 118, -489, -590, 118, 766, + 117, -583, -590, 117, -590, -489, -590, -590, -504, -590, + -590, -590, -590, -590, 767, -590, -590, -590, 578, 127, + -498, 580, 579, 576, -583, 578, -110, -498, -73, -584, + 578, -590, 580, 579, -590, -590, -590, -97, 984, -590, + 226, -109, 740, -590, -590, -590, -590, -106, -590, -590, + -590, 513, -590, 514, -489, -94, -105, 580, 579, 576, + -500, -590, -590, -590, -590, -103, 521, -500, 281, 98, + 99, -107, -590, -590, 644, -590, -590, -590, -590, -590, + 527, -492, 580, 579, 581, -498, 578, 226, -492, 580, + 579, 583, 578, -584, 580, 579, 585, -492, 540, 823, + 792, 539, -590, -590, -590, -590, -590, -590, -590, -590, + -590, -590, -590, -590, -590, -590, -584, 272, -590, -590, + -590, 524, 768, -590, 221, -500, -590, -100, -497, -590, + -590, 220, -590, 528, -590, -497, -590, -109, -590, -590, + 218, -590, -590, -590, -590, -590, -492, -590, -590, -590, + 580, 579, 589, -494, -336, -495, 580, 579, 594, 246, + -494, -336, -495, -590, 246, 611, -590, -590, -590, -590, + -336, -590, 611, -590, -298, 612, 845, 612, -590, -106, + 118, -298, -298, -298, 226, 117, -298, -298, -298, 222, + -298, 243, 543, -497, 544, 245, 244, -496, 221, 246, + -298, -298, -298, 540, -496, 270, 542, 502, 753, 753, + -298, -298, -96, -298, -298, -298, -298, -298, -494, -336, + -495, 221, -105, -501, -98, 699, 698, 557, 456, -105, + -501, 243, -107, -104, -107, 245, 244, 457, 398, -501, + -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, + -298, -298, -298, -298, 118, -95, -298, -298, -298, 117, + 769, -298, -496, 222, -298, -104, -104, -298, -298, 561, + -298, 562, -298, 570, -298, 540, -298, -298, 542, -298, + -298, -298, -298, -298, -298, -298, 222, -298, -501, 823, + 792, -298, -298, -298, 595, 598, 540, -298, -298, 542, + -298, -298, 246, -271, -298, -298, -298, -298, 600, -298, + 84, -298, -590, 601, 605, 226, -298, -108, 256, 257, + -298, -298, 85, -298, -298, -298, -298, -298, 226, -502, + 609, 1000, 86, 221, 243, 610, -502, 272, 245, 244, + 520, 241, 242, 621, 246, -502, 246, 246, 246, 518, + -298, -298, -298, -298, -298, -298, -298, -298, -298, -298, + -298, -298, -298, -298, -590, -289, -298, -298, -298, 226, + 616, -590, -289, 226, -298, 226, -586, -298, -88, 647, + -590, -289, -298, 226, -298, 533, -298, -298, 658, -298, + -298, -298, -298, -298, -502, -298, -590, -298, 222, -590, + 663, 664, 226, -590, -590, -590, 688, 666, 702, -590, + -590, -298, -590, 707, -298, -298, 691, -298, 221, -298, + 708, -590, 557, 710, 727, 530, -298, -108, 737, -590, + -289, 741, -590, -590, 457, -590, -590, -590, -590, -590, + 683, 221, 680, 679, 678, 742, 681, -272, 560, 699, + 698, 754, 489, 489, 692, 732, 733, 558, 226, 734, + 112, 113, -590, -590, -590, -590, -590, -590, -590, -590, + -590, -590, -590, -590, -590, -590, 771, 812, -590, -590, + -590, 221, 617, 222, 221, 772, -590, 266, 566, -590, + 777, 604, 782, 500, -590, 502, -590, 568, -590, -590, + 602, -590, -590, -590, -590, -590, 222, -590, -590, -590, + 683, 658, 680, 679, 678, 688, 681, -299, 121, 122, + 123, 124, 125, -590, -299, 691, -590, -590, -419, -590, + 226, -590, 272, -299, 272, -419, -419, -419, -590, -106, + -419, -419, -419, 658, -419, 246, 222, 686, 792, 222, + 800, 246, 803, -419, -419, -419, 696, 695, 699, 698, + 804, 806, 808, 692, -419, -419, 810, -419, -419, -419, + -419, -419, 683, 818, 680, 679, 678, -299, 681, 819, + 820, 792, -299, 243, -299, 825, 226, 245, 244, 226, + 241, 242, 226, -299, -419, -419, -419, -419, -419, -419, + -419, -419, -419, -419, -419, -419, -419, -419, 834, 812, + -419, -419, -419, -273, 226, -419, 844, 272, -419, 848, + 658, -419, -419, 865, -419, -271, -419, 869, -419, 226, + -419, -419, 889, -419, -419, -419, -419, -419, -305, -419, + -419, -419, -299, 226, 893, -305, -305, -305, 895, 898, + -305, -305, -305, 221, -305, -419, 899, 902, -419, -419, + 970, -419, 226, -419, -305, -305, 906, -274, 908, 568, + -419, 803, 911, 913, -305, -305, 915, -305, -305, -305, + -305, -305, 917, 226, 919, -298, 920, -298, 933, 803, + 935, 937, -298, 939, -298, 941, 941, -587, 226, -587, + 947, -298, 953, -298, -305, -305, -305, -305, -305, -305, + -305, -305, -305, -305, -305, -305, -305, -305, 222, 727, + -305, -305, -305, 964, 971, -305, 976, 281, -305, 986, + 803, -305, -305, 990, -305, 992, -305, 994, -305, 996, + -305, -305, 996, -305, -305, -305, -305, -305, -290, -305, + -298, -305, -298, 663, 1009, -290, -290, -290, 1010, 1011, + -290, -290, -290, 221, -290, -305, 941, 941, -305, -305, + 975, -305, 941, -305, -290, -290, -290, 1016, 986, 973, + -305, 1019, -587, -586, -290, -290, 226, -290, -290, -290, + -290, -290, 967, 221, 680, 679, 678, 986, 681, 683, + 970, 680, 679, 678, 967, 681, 680, 679, 678, 568, + 681, 1028, 996, 996, -290, -290, -290, -290, -290, -290, + -290, -290, -290, -290, -290, -290, -290, -290, 222, 688, + -290, -290, -290, 996, 941, -290, 812, 986, -290, 691, + 996, -290, -290, nil, -290, 815, -290, nil, -290, nil, + -290, -290, nil, -290, -290, -290, -290, -290, 222, -290, + nil, -290, 683, nil, 680, 679, 678, nil, 681, nil, + nil, nil, 699, 698, nil, -290, nil, 692, -290, -290, + -290, -290, nil, -290, -254, -290, nil, nil, nil, nil, + -290, -254, -254, -254, nil, nil, -254, -254, -254, 812, + -254, 683, nil, 680, 679, 678, nil, 681, 815, -254, + -254, -254, 683, nil, 680, 679, 678, nil, 681, nil, + -254, -254, nil, -254, -254, -254, -254, -254, 683, nil, + 680, 679, 678, 683, 681, 680, 679, 678, 812, 681, + 121, 122, 123, 124, 125, nil, nil, 946, nil, 812, + -254, -254, -254, -254, -254, -254, -254, -254, -254, -254, + -254, -254, -254, -254, nil, 812, -254, -254, -254, nil, + 812, -254, nil, 272, -254, nil, nil, -254, -254, nil, + -254, nil, -254, nil, -254, nil, -254, -254, nil, -254, + -254, -254, -254, -254, nil, -254, -254, -254, 683, nil, + 680, 679, 678, 688, 681, 121, 122, 123, 124, 125, + nil, -254, nil, 691, -254, -254, -591, -254, nil, -254, + nil, nil, nil, -591, -591, -591, -254, nil, -591, -591, + -591, nil, -591, 246, nil, 686, 121, 122, 123, 124, + 125, -591, -591, -591, -591, nil, 699, 698, nil, 256, + 257, 692, -591, -591, nil, -591, -591, -591, -591, -591, + nil, nil, nil, nil, nil, 243, nil, 249, nil, 245, + 244, nil, 241, 242, nil, nil, 247, nil, 248, nil, + nil, nil, -591, -591, -591, -591, -591, -591, -591, -591, + -591, -591, -591, -591, -591, -591, nil, nil, -591, -591, + -591, 246, nil, -591, nil, nil, -591, nil, nil, -591, + -591, nil, -591, nil, -591, nil, -591, nil, -591, -591, + nil, -591, -591, -591, -591, -591, nil, -591, -591, -591, + nil, nil, nil, 243, nil, nil, nil, 245, 244, nil, + 241, 242, nil, -591, nil, nil, -591, -591, -591, -591, + nil, -591, -592, -591, nil, nil, nil, nil, -591, -592, + -592, -592, nil, nil, -592, -592, -592, 246, -592, nil, + nil, nil, nil, nil, nil, nil, nil, -592, -592, -592, + -592, nil, nil, 256, 257, nil, nil, nil, -592, -592, + nil, -592, -592, -592, -592, -592, nil, nil, nil, 243, + nil, 249, nil, 245, 244, nil, 241, 242, nil, nil, + 247, nil, 248, nil, nil, nil, nil, nil, -592, -592, + -592, -592, -592, -592, -592, -592, -592, -592, -592, -592, + -592, -592, nil, nil, -592, -592, -592, nil, nil, -592, + nil, nil, -592, nil, nil, -592, -592, nil, -592, nil, + -592, nil, -592, nil, -592, -592, nil, -592, -592, -592, + -592, -592, nil, -592, -592, -592, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, -592, + nil, nil, -592, -592, -592, -592, nil, -592, -254, -592, + nil, nil, nil, nil, -592, -254, -254, -254, nil, nil, + -254, -254, -254, 246, -254, nil, nil, nil, nil, nil, + nil, nil, nil, -254, -254, nil, nil, nil, nil, 256, + 257, nil, nil, nil, -254, -254, nil, -254, -254, -254, + -254, -254, nil, nil, nil, 243, nil, 249, nil, 245, + 244, nil, 241, 242, nil, nil, nil, 246, 250, 251, + 252, 253, 263, 264, 258, 259, 254, 255, nil, 239, + 240, nil, nil, 256, 257, -254, nil, nil, nil, nil, + nil, nil, -254, nil, nil, nil, nil, 272, -254, 243, + nil, 249, nil, 245, 244, nil, 241, 242, 262, 261, + 247, nil, 248, nil, nil, nil, nil, nil, nil, nil, + -254, -254, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 260, nil, nil, -254, nil, nil, -254, nil, + nil, nil, nil, -254, 5, 75, 76, 77, 9, 58, + -254, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, 606, 8, 46, 7, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, 246, + 250, 251, 252, 253, 263, 264, 258, 259, 254, 255, + nil, 239, 240, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 243, nil, 249, 45, 245, 244, nil, 241, 242, + 262, 261, 247, 20, 248, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, 260, nil, -246, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, 606, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, 246, + 250, 251, 252, 253, 263, 264, 258, 259, 254, 255, + nil, 239, 240, nil, nil, 256, 257, nil, 40, nil, + nil, 303, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 243, nil, 249, 45, 245, 244, nil, 241, 242, + 262, 261, 247, 20, 248, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, 260, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 5, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 7, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, 246, + 250, 251, 252, 253, 263, 264, 258, 259, 254, 255, + nil, 239, 240, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 243, nil, 249, 45, 245, 244, nil, 241, 242, + 262, 261, 247, 20, 248, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, 260, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, 246, + 250, 251, 252, 253, 263, 264, 258, 259, 254, 255, + nil, 239, 240, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 243, nil, 249, 45, 245, 244, nil, 241, 242, + 262, 261, 247, 20, 248, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, 226, 260, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, 246, + 250, 251, 252, 253, 263, 264, 258, 259, 254, 255, + nil, 239, 240, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 243, nil, 249, 45, 245, 244, nil, 241, 242, + 262, 261, 247, 20, 248, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, 260, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, 246, + 250, 251, 252, 253, 263, 264, 258, 259, 254, 255, + nil, 239, 240, nil, nil, 256, 257, nil, 40, nil, + nil, 303, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 243, nil, 249, 45, 245, 244, nil, 241, 242, + 262, 261, 247, 20, 248, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, 260, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, 246, + 250, 251, 252, 253, 263, 264, 258, 259, 254, 255, + nil, 239, 240, nil, nil, 256, 257, nil, 40, nil, + nil, 303, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 243, nil, 249, 45, 245, 244, nil, 241, 242, + 262, 261, 247, 20, 248, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, 260, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, 246, + 250, 251, 252, 253, 263, 264, 258, 259, 254, 255, + nil, -611, -611, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 243, nil, 249, 45, 245, 244, nil, 241, 242, + 262, 261, 247, 20, 248, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, 246, + 250, 251, 252, 253, 263, 264, 258, 259, 254, 255, + nil, -611, -611, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 243, nil, 249, 45, 245, 244, nil, 241, 242, + 262, 261, 247, 20, 248, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, 246, + -611, -611, -611, -611, 263, 264, nil, nil, -611, -611, + nil, nil, nil, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 243, nil, 249, 45, 245, 244, nil, 241, 242, + 262, 261, 247, 20, 248, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, 246, + -611, -611, -611, -611, 263, 264, nil, nil, -611, -611, + nil, nil, nil, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 243, nil, 249, 45, 245, 244, nil, 241, 242, + 262, 261, 247, 20, 248, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, 246, + -611, -611, -611, -611, 263, 264, nil, nil, -611, -611, + nil, nil, nil, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 243, nil, 249, 45, 245, 244, nil, 241, 242, + 262, 261, 247, 20, 248, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, 246, + -611, -611, -611, -611, 263, 264, nil, nil, -611, -611, + nil, nil, nil, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 243, nil, 249, 45, 245, 244, nil, 241, 242, + 262, 261, 247, 20, 248, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, 246, + -611, -611, -611, -611, 263, 264, nil, nil, -611, -611, + nil, nil, nil, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 243, nil, 249, 45, 245, 244, nil, 241, 242, + 262, 261, 247, 20, 248, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, 246, + -611, -611, -611, -611, 263, 264, nil, nil, -611, -611, + nil, nil, nil, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 243, nil, 249, 45, 245, 244, nil, 241, 242, + 262, 261, 247, 20, 248, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, 246, + 250, 251, 252, 253, 263, 264, nil, nil, 254, 255, + nil, nil, nil, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 243, nil, 249, 45, 245, 244, nil, 241, 242, + 262, 261, 247, 20, 248, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, 246, + 250, 251, 252, 253, 263, 264, 258, nil, 254, 255, + nil, nil, nil, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 243, nil, 249, 45, 245, 244, nil, 241, 242, + 262, 261, 247, 20, 248, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, 246, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 256, 257, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, 243, nil, 249, 45, 245, 244, nil, 241, 242, + nil, nil, nil, 20, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 299, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 301, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, nil, nil, nil, 63, + nil, 86, 98, 99, 75, 76, 77, 9, 58, nil, + nil, nil, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 30, 31, 73, 74, nil, nil, nil, nil, + nil, 78, 28, 27, 106, 105, 107, 108, nil, nil, + 19, nil, nil, nil, nil, nil, 8, 46, 7, 10, + 110, 109, 111, 100, 57, 102, 101, 103, nil, 104, + 112, 113, nil, 96, 97, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 40, nil, nil, + 33, nil, nil, 59, 60, nil, nil, 61, nil, 35, + nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 94, 84, 87, + 88, nil, 89, 91, 90, 92, nil, nil, nil, nil, + 85, 93, nil, nil, nil, 75, 76, 77, 63, 58, + 86, 98, 99, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 238, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 231, nil, + nil, 237, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 236, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, 75, 76, 77, 63, + 58, 86, 98, 99, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 30, 31, 73, 74, nil, nil, + nil, nil, nil, 78, 28, 27, 106, 105, 107, 108, + nil, nil, 238, nil, nil, nil, nil, nil, nil, 46, + nil, nil, 110, 109, 111, 100, 57, 102, 101, 103, + 293, 104, 112, 113, nil, 96, 97, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 231, + nil, nil, 237, nil, nil, 59, 60, nil, nil, 61, + nil, 290, nil, 288, nil, 45, nil, nil, 294, nil, + nil, nil, nil, nil, 236, nil, nil, nil, nil, 94, + 291, 87, 88, nil, 89, 91, 90, 92, nil, nil, + nil, nil, 85, 93, nil, nil, nil, 75, 76, 77, + 63, 58, 86, 98, 99, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 30, 31, 73, 74, nil, + nil, nil, nil, nil, 78, 28, 27, 106, 105, 107, + 108, nil, nil, 238, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 110, 109, 111, 100, 57, 102, 101, + 103, 293, 104, 112, 113, nil, 96, 97, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 231, nil, nil, 237, nil, nil, 59, 60, nil, nil, + 61, nil, 290, nil, 288, nil, 45, nil, nil, 294, + nil, nil, nil, nil, nil, 236, nil, nil, nil, nil, + 94, 291, 87, 88, nil, 89, 91, 90, 92, nil, + nil, nil, nil, 85, 93, nil, nil, nil, 75, 76, + 77, 63, 58, 86, 98, 99, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 30, 31, 73, 74, + nil, nil, nil, nil, nil, 78, 28, 27, 106, 105, + 107, 108, nil, nil, 238, nil, nil, nil, nil, nil, + nil, 46, nil, nil, 110, 109, 111, 100, 57, 102, + 101, 103, 293, 104, 112, 113, nil, 96, 97, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 231, nil, nil, 237, nil, nil, 59, 60, nil, + nil, 61, nil, 290, nil, 288, nil, 45, nil, nil, + 294, nil, nil, nil, nil, nil, 236, nil, nil, nil, + nil, 94, 291, 87, 88, nil, 89, 91, 90, 92, + nil, nil, nil, nil, 85, 93, nil, nil, nil, 75, + 76, 77, 63, 58, 86, 98, 99, 64, 65, nil, + nil, nil, 68, nil, 66, 67, 69, 318, 319, 73, + 74, nil, nil, nil, nil, nil, 78, 315, 321, 106, + 105, 107, 108, nil, nil, 238, nil, nil, nil, nil, + nil, nil, 316, nil, nil, 110, 109, 111, 100, 57, + 102, 101, 103, nil, 104, 112, 113, nil, 96, 97, + nil, nil, 322, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 312, nil, nil, 308, nil, nil, 59, 60, + nil, nil, 61, nil, 307, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 94, 84, 87, 88, nil, 89, 91, 90, + 92, nil, nil, nil, nil, 85, 93, nil, nil, nil, + 75, 76, 77, 63, 58, 86, 98, 99, 64, 65, + nil, nil, nil, 68, nil, 66, 67, 69, 318, 319, + 73, 74, nil, nil, nil, nil, nil, 78, 315, 321, + 106, 105, 107, 108, nil, nil, 238, nil, nil, nil, + nil, nil, nil, 316, nil, nil, 110, 109, 111, 100, + 57, 102, 101, 103, nil, 104, 112, 113, nil, 96, + 97, nil, nil, 322, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 312, nil, nil, 237, nil, nil, 59, + 60, nil, nil, 61, nil, nil, 683, nil, 680, 679, + 678, 688, 681, nil, nil, nil, nil, nil, nil, nil, + nil, 691, nil, 94, 84, 87, 88, nil, 89, 91, + 90, 92, nil, nil, nil, nil, 85, 93, nil, nil, + nil, 324, nil, 686, 63, nil, 86, 98, 99, 75, + 76, 77, nil, 58, 699, 698, nil, 64, 65, 692, + nil, nil, 68, nil, 66, 67, 69, 318, 319, 73, + 74, nil, nil, nil, nil, nil, 78, 315, 321, 106, + 105, 107, 108, nil, nil, 238, nil, nil, nil, nil, + nil, nil, 46, nil, nil, 110, 109, 111, 100, 57, + 102, 101, 103, nil, 104, 112, 113, nil, 96, 97, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 231, nil, nil, 237, nil, nil, 59, 60, + nil, nil, 61, nil, nil, nil, nil, nil, 45, nil, + nil, nil, nil, nil, nil, nil, nil, 236, nil, nil, + nil, nil, 94, 84, 87, 88, nil, 89, 91, 90, + 92, nil, nil, nil, nil, 85, 93, nil, nil, nil, + 75, 76, 77, 63, 58, 86, 98, 99, 64, 65, + nil, nil, nil, 68, nil, 66, 67, 69, 318, 319, + 73, 74, nil, nil, nil, nil, nil, 78, 315, 321, + 106, 105, 107, 108, nil, nil, 238, nil, nil, nil, + nil, nil, nil, 46, nil, nil, 110, 109, 111, 100, + 57, 102, 101, 103, nil, 104, 112, 113, nil, 96, + 97, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 231, nil, nil, 237, nil, nil, 59, + 60, nil, nil, 61, nil, nil, nil, nil, nil, 45, + nil, nil, nil, nil, nil, nil, nil, nil, 236, nil, + nil, nil, nil, 94, 84, 87, 88, nil, 89, 91, + 90, 92, nil, nil, nil, nil, 85, 93, nil, nil, + nil, 75, 76, 77, 63, 58, 86, 98, 99, 64, + 65, nil, nil, nil, 68, nil, 66, 67, 69, 318, + 319, 73, 74, nil, nil, nil, nil, nil, 78, 315, + 321, 106, 105, 107, 108, nil, nil, 238, nil, nil, + nil, nil, nil, nil, 46, nil, nil, 110, 109, 111, + 100, 57, 102, 101, 103, nil, 104, 112, 113, nil, + 96, 97, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 231, nil, nil, 237, nil, nil, + 59, 60, nil, nil, 61, nil, nil, nil, nil, nil, + 45, nil, nil, nil, nil, nil, nil, nil, nil, 236, + nil, nil, nil, nil, 94, 84, 87, 88, nil, 89, + 91, 90, 92, nil, nil, nil, nil, 85, 93, nil, + nil, nil, nil, nil, nil, 63, nil, 86, 98, 99, + 75, 76, 77, 9, 58, nil, nil, nil, 64, 65, + nil, nil, nil, 68, nil, 66, 67, 69, 30, 31, + 73, 74, nil, nil, nil, nil, nil, 78, 28, 27, + 106, 105, 107, 108, nil, nil, 19, nil, nil, nil, + nil, nil, 8, 46, nil, 10, 110, 109, 111, 100, + 57, 102, 101, 103, nil, 104, 112, 113, nil, 96, + 97, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 40, nil, nil, 33, nil, nil, 59, + 60, nil, nil, 61, nil, 35, nil, nil, nil, 45, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 94, 84, 87, 88, nil, 89, 91, + 90, 92, nil, nil, nil, nil, 85, 93, nil, nil, + nil, 75, 76, 77, 63, 58, 86, 98, 99, 64, + 65, nil, nil, nil, 68, nil, 66, 67, 69, 318, + 319, 73, 74, nil, nil, nil, nil, nil, 78, 315, + 321, 106, 105, 107, 108, nil, nil, 238, nil, nil, + nil, nil, nil, nil, 46, nil, nil, 110, 109, 111, + 100, 57, 102, 101, 103, 293, 104, 112, 113, nil, + 96, 97, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 231, nil, nil, 237, nil, nil, + 59, 60, nil, nil, 61, nil, 290, nil, nil, nil, + 45, nil, nil, 294, nil, nil, nil, nil, nil, 236, + nil, nil, nil, nil, 94, 291, 87, 88, nil, 89, + 91, 90, 92, nil, nil, nil, nil, 85, 93, nil, + nil, nil, 75, 76, 77, 63, 58, 86, 98, 99, + 64, 65, nil, nil, nil, 68, nil, 66, 67, 69, + 318, 319, 73, 74, nil, nil, nil, nil, nil, 78, + 315, 321, 106, 105, 107, 108, nil, nil, 238, nil, + nil, nil, nil, nil, nil, 46, nil, nil, 110, 109, + 111, 100, 57, 102, 101, 103, 293, 104, 112, 113, + nil, 96, 97, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 231, nil, nil, 237, nil, + nil, 59, 60, nil, nil, 61, nil, nil, nil, nil, + nil, 45, nil, nil, 294, nil, nil, nil, nil, nil, + 236, nil, nil, nil, nil, 94, 291, 87, 88, nil, + 89, 91, 90, 92, nil, nil, nil, nil, 85, 93, + nil, nil, nil, 75, 76, 77, 63, 58, 86, 98, + 99, 64, 65, nil, nil, nil, 68, nil, 66, 67, + 69, 30, 31, 73, 74, nil, nil, nil, nil, nil, + 78, 28, 27, 106, 105, 107, 108, nil, nil, 19, + nil, nil, nil, nil, nil, nil, 46, nil, nil, 110, + 109, 111, 100, 57, 102, 101, 103, nil, 104, 112, + 113, nil, 96, 97, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 231, nil, nil, 237, + nil, nil, 59, 60, nil, nil, 61, nil, nil, nil, + nil, nil, 45, nil, nil, nil, nil, nil, nil, nil, + nil, 20, nil, nil, nil, nil, 94, 84, 87, 88, + nil, 89, 91, 90, 92, nil, nil, nil, nil, 85, + 93, nil, nil, nil, 75, 76, 77, 63, 58, 86, + 98, 99, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 30, 31, 73, 74, nil, nil, nil, nil, + nil, 78, 28, 27, 106, 105, 107, 108, nil, nil, + 19, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 110, 109, 111, 100, 57, 102, 101, 103, nil, 104, + 112, 113, nil, 96, 97, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 231, nil, nil, + 237, nil, nil, 59, 60, nil, nil, 61, nil, nil, + nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 94, 84, 87, + 88, nil, 89, 91, 90, 92, nil, nil, nil, nil, + 85, 93, nil, nil, nil, 75, 76, 77, 63, 58, + 86, 98, 99, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 231, nil, + nil, 237, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, 118, nil, nil, nil, nil, 117, 63, + nil, 86, 98, 99, 75, 76, 77, nil, 58, nil, + nil, nil, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 318, 319, 73, 74, nil, nil, nil, nil, + nil, 78, 315, 321, 106, 105, 107, 108, nil, nil, + 238, nil, nil, nil, nil, nil, nil, 316, nil, nil, + 110, 109, 111, 100, 57, 102, 101, 103, nil, 104, + 112, 113, nil, 96, 97, nil, nil, 322, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 358, nil, nil, + 33, nil, nil, 59, 60, nil, nil, 61, nil, 35, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 94, 84, 87, + 88, nil, 89, 91, 90, 92, nil, nil, nil, nil, + 85, 93, nil, nil, nil, 75, 76, 77, 63, 58, + 86, 98, 99, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 318, 319, 73, 74, nil, nil, nil, + nil, nil, 78, 315, 321, 106, 105, 107, 108, nil, + nil, 238, nil, nil, nil, nil, nil, nil, 316, nil, + nil, 110, 109, 111, 363, 57, 102, 101, 364, nil, + 104, 112, 113, nil, 96, 97, nil, nil, 322, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 370, nil, nil, 365, nil, + nil, 237, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, 75, 76, 77, 63, + 58, 86, 98, 99, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 318, 319, 73, 74, nil, nil, + nil, nil, nil, 78, 315, 321, 106, 105, 107, 108, + nil, nil, 238, nil, nil, nil, nil, nil, nil, 316, + nil, nil, 110, 109, 111, 363, 57, 102, 101, 364, + nil, 104, 112, 113, nil, 96, 97, nil, nil, 322, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 365, + nil, nil, 237, nil, nil, 59, 60, nil, nil, 61, + nil, nil, 683, nil, 680, 679, 678, 688, 681, nil, + nil, nil, nil, nil, nil, nil, nil, 691, nil, 94, + 84, 87, 88, nil, 89, 91, 90, 92, nil, nil, + nil, nil, 85, 93, nil, nil, nil, nil, nil, 686, + 63, nil, 86, 98, 99, 75, 76, 77, 9, 58, + 699, 698, nil, 64, 65, 692, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, 7, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, nil, nil, 398, 63, + nil, 86, 98, 99, 75, 76, 77, nil, 58, nil, + nil, nil, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 30, 31, 73, 74, nil, nil, nil, nil, + nil, 78, 28, 27, 106, 105, 107, 108, nil, nil, + 19, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 110, 109, 111, 100, 57, 102, 101, 103, nil, 104, + 112, 113, nil, 96, 97, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 231, nil, nil, + 237, nil, nil, 59, 60, nil, nil, 61, nil, nil, + nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 94, 84, 87, + 88, nil, 89, 91, 90, 92, nil, nil, nil, nil, + 85, 93, nil, nil, nil, 75, 76, 77, 63, 58, + 86, 98, 99, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 231, nil, + nil, 237, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, 75, 76, 77, 63, + 58, 86, 98, 99, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 30, 31, 73, 74, nil, nil, + nil, nil, nil, 78, 28, 27, 106, 105, 107, 108, + nil, nil, 19, nil, nil, nil, nil, nil, nil, 46, + nil, nil, 110, 109, 111, 100, 57, 102, 101, 103, + nil, 104, 112, 113, nil, 96, 97, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 231, + nil, nil, 237, nil, nil, 59, 60, nil, nil, 61, + nil, nil, nil, nil, nil, 45, nil, nil, nil, nil, + nil, nil, nil, nil, 20, nil, nil, nil, nil, 94, + 84, 87, 88, nil, 89, 91, 90, 92, nil, nil, + nil, nil, 85, 93, nil, nil, nil, 75, 76, 77, + 63, 58, 86, 98, 99, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 30, 31, 73, 74, nil, + nil, nil, nil, nil, 78, 28, 27, 106, 105, 107, + 108, nil, nil, 19, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 110, 109, 111, 100, 57, 102, 101, + 103, nil, 104, 112, 113, nil, 96, 97, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 231, nil, nil, 237, nil, nil, 59, 60, nil, nil, + 61, nil, nil, nil, nil, nil, 45, nil, nil, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, nil, + 94, 84, 87, 88, nil, 89, 91, 90, 92, nil, + nil, nil, nil, 85, 93, nil, nil, nil, nil, nil, + nil, 63, nil, 86, 98, 99, 75, 76, 77, 9, + 58, nil, nil, nil, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 30, 31, 73, 74, nil, nil, + nil, nil, nil, 78, 28, 27, 106, 105, 107, 108, + nil, nil, 19, nil, nil, nil, nil, nil, 8, 46, + nil, 10, 110, 109, 111, 100, 57, 102, 101, 103, + nil, 104, 112, 113, nil, 96, 97, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 40, + nil, nil, 33, nil, nil, 59, 60, nil, nil, 61, + nil, 35, nil, nil, nil, 45, nil, nil, nil, nil, + nil, nil, nil, nil, 20, nil, nil, nil, nil, 94, + 84, 87, 88, nil, 89, 91, 90, 92, nil, nil, + nil, nil, 85, 93, nil, nil, nil, 75, 76, 77, + 63, 58, 86, 98, 99, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 30, 31, 73, 74, nil, + nil, nil, nil, nil, 78, 28, 27, 106, 105, 107, + 108, nil, nil, 238, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 110, 109, 111, 100, 57, 102, 101, + 103, nil, 104, 112, 113, nil, 96, 97, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 231, nil, nil, 237, nil, nil, 59, 60, nil, nil, + 61, nil, 414, nil, nil, nil, 45, nil, nil, nil, + nil, nil, nil, nil, nil, 236, nil, nil, nil, nil, + 94, 84, 87, 88, nil, 89, 91, 90, 92, nil, + nil, nil, nil, 85, 93, nil, nil, nil, 75, 76, + 77, 63, 58, 86, 98, 99, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 30, 31, 73, 74, + nil, nil, nil, nil, nil, 78, 28, 27, 106, 105, + 107, 108, nil, nil, 238, nil, nil, nil, nil, nil, + nil, 46, nil, nil, 110, 109, 111, 100, 57, 102, + 101, 103, nil, 104, 112, 113, nil, 96, 97, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 231, nil, nil, 237, nil, nil, 59, 60, nil, + nil, 61, nil, 414, nil, nil, nil, 45, nil, nil, + nil, nil, nil, nil, nil, nil, 236, nil, nil, nil, + nil, 94, 84, 87, 88, nil, 89, 91, 90, 92, + nil, nil, nil, nil, 85, 93, nil, nil, nil, 75, + 76, 77, 63, 58, 86, 98, 99, 64, 65, nil, + nil, nil, 68, nil, 66, 67, 69, 30, 31, 73, + 74, nil, nil, nil, nil, nil, 78, 28, 27, 106, + 105, 107, 108, nil, nil, 19, nil, nil, nil, nil, + nil, nil, 46, nil, nil, 110, 109, 111, 100, 57, + 102, 101, 103, nil, 104, 112, 113, nil, 96, 97, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 231, nil, nil, 237, nil, nil, 59, 60, + nil, nil, 61, nil, nil, nil, nil, nil, 45, nil, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 94, 84, 87, 88, nil, 89, 91, 90, + 92, nil, nil, nil, nil, 85, 93, nil, nil, nil, + 75, 76, 77, 63, 58, 86, 98, 99, 64, 65, + nil, nil, nil, 68, nil, 66, 67, 69, 30, 31, + 73, 74, nil, nil, nil, nil, nil, 78, 28, 27, + 106, 105, 107, 108, nil, nil, 19, nil, nil, nil, + nil, nil, nil, 46, nil, nil, 110, 109, 111, 100, + 57, 102, 101, 103, nil, 104, 112, 113, nil, 96, + 97, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 231, nil, nil, 237, nil, nil, 59, + 60, nil, nil, 61, nil, nil, nil, nil, nil, 45, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 94, 84, 87, 88, nil, 89, 91, + 90, 92, nil, nil, nil, nil, 85, 93, nil, nil, + nil, 75, 76, 77, 63, 58, 86, 98, 99, 64, + 65, nil, nil, nil, 68, nil, 66, 67, 69, 30, + 31, 73, 74, nil, nil, nil, nil, nil, 78, 28, + 27, 106, 105, 107, 108, nil, nil, 238, nil, nil, + nil, nil, nil, nil, 46, nil, nil, 110, 109, 111, + 100, 57, 102, 101, 103, nil, 104, 112, 113, nil, + 96, 97, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 231, nil, nil, 237, nil, nil, + 59, 60, nil, nil, 61, nil, nil, nil, nil, nil, + 45, nil, nil, nil, nil, nil, nil, nil, nil, 236, + nil, nil, nil, nil, 94, 84, 87, 88, nil, 89, + 91, 90, 92, nil, nil, nil, nil, 85, 93, nil, + nil, nil, 75, 76, 77, 63, 58, 86, 98, 99, + 64, 65, nil, nil, nil, 68, nil, 66, 67, 69, + 30, 31, 73, 74, nil, nil, nil, nil, nil, 78, + 28, 27, 106, 105, 107, 108, nil, nil, 238, nil, + nil, nil, nil, nil, nil, 46, nil, nil, 110, 109, + 111, 100, 57, 102, 101, 103, 293, 104, 112, 113, + nil, 96, 97, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 231, nil, nil, 237, nil, + nil, 59, 60, nil, nil, 61, nil, 290, nil, 288, + nil, 45, nil, nil, 294, nil, nil, nil, nil, nil, + 236, nil, nil, nil, nil, 94, 291, 87, 88, nil, + 89, 91, 90, 92, nil, nil, nil, nil, 85, 93, + nil, nil, nil, 75, 76, 77, 63, 58, 86, 98, + 99, 64, 65, nil, nil, nil, 68, nil, 66, 67, + 69, 30, 31, 73, 74, nil, nil, nil, nil, nil, + 78, 28, 27, 106, 105, 107, 108, nil, nil, 238, + nil, nil, nil, nil, nil, nil, 46, nil, nil, 110, + 109, 111, 100, 57, 102, 101, 103, nil, 104, 112, + 113, nil, 96, 97, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 231, nil, nil, 237, + nil, nil, 59, 60, nil, nil, 61, nil, nil, nil, + nil, nil, 45, nil, nil, nil, nil, nil, nil, nil, + nil, 236, nil, nil, nil, nil, 94, 84, 87, 88, + nil, 89, 91, 90, 92, nil, nil, nil, nil, 85, + 93, nil, nil, nil, 75, 76, 77, 63, 58, 86, + 98, 99, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 30, 31, 73, 74, nil, nil, nil, nil, + nil, 78, 28, 27, 106, 105, 107, 108, nil, nil, + 19, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 110, 109, 111, 100, 57, 102, 101, 103, nil, 104, + 112, 113, nil, 96, 97, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 231, nil, nil, + 237, nil, nil, 59, 60, nil, nil, 61, nil, nil, + nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 94, 84, 87, + 88, nil, 89, 91, 90, 92, nil, nil, nil, nil, + 85, 93, nil, nil, nil, 75, 76, 77, 63, 58, + 86, 98, 99, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 231, nil, + nil, 237, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, 226, nil, nil, 75, 76, 77, 63, + 58, 86, 98, 99, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 318, 319, 73, 74, nil, nil, + nil, nil, nil, 78, 315, 321, 106, 105, 107, 108, + nil, nil, 238, nil, nil, nil, nil, nil, nil, 46, + nil, nil, 110, 109, 111, 100, 57, 102, 101, 103, + nil, 104, 112, 113, nil, 96, 97, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 231, + nil, nil, 237, nil, nil, 59, 60, nil, nil, 61, + nil, nil, nil, nil, nil, 45, nil, nil, nil, nil, + nil, nil, nil, nil, 236, nil, nil, nil, nil, 94, + 84, 87, 88, nil, 89, 91, 90, 92, nil, nil, + nil, nil, 85, 93, nil, nil, nil, 75, 76, 77, + 63, 58, 86, 98, 99, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 318, 319, 73, 74, nil, + nil, nil, nil, nil, 78, 315, 321, 106, 105, 107, + 108, nil, nil, 238, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 110, 109, 111, 100, 57, 102, 101, + 103, nil, 104, 112, 113, nil, 96, 97, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 231, nil, nil, 237, nil, nil, 59, 60, nil, nil, + 61, nil, nil, nil, nil, nil, 45, nil, nil, nil, + nil, nil, nil, nil, nil, 236, nil, nil, nil, nil, + 94, 84, 87, 88, nil, 89, 91, 90, 92, nil, + nil, nil, nil, 85, 93, nil, nil, nil, 75, 76, + 77, 63, 58, 86, 98, 99, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 318, 319, 73, 74, + nil, nil, nil, nil, nil, 78, 315, 321, 106, 105, + 107, 108, nil, nil, 238, nil, nil, nil, nil, nil, + nil, 46, nil, nil, 110, 109, 111, 100, 57, 102, + 101, 103, nil, 104, 112, 113, nil, 96, 97, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 231, nil, nil, 237, nil, nil, 59, 60, nil, + nil, 61, nil, nil, nil, nil, nil, 45, nil, nil, + nil, nil, nil, nil, nil, nil, 236, nil, nil, nil, + nil, 94, 84, 87, 88, nil, 89, 91, 90, 92, + nil, nil, nil, nil, 85, 93, nil, nil, nil, 75, + 76, 77, 63, 58, 86, 98, 99, 64, 65, nil, + nil, nil, 68, nil, 66, 67, 69, 318, 319, 73, + 74, nil, nil, nil, nil, nil, 78, 315, 321, 106, + 105, 107, 108, nil, nil, 238, nil, nil, nil, nil, + nil, nil, 46, nil, nil, 110, 109, 111, 100, 57, + 102, 101, 103, nil, 104, 112, 113, nil, 96, 97, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 231, nil, nil, 237, nil, nil, 59, 60, + nil, nil, 61, nil, nil, nil, nil, nil, 45, nil, + nil, nil, nil, nil, nil, nil, nil, 236, nil, nil, + nil, nil, 94, 84, 87, 88, nil, 89, 91, 90, + 92, nil, nil, nil, nil, 85, 93, nil, nil, nil, + 75, 76, 77, 63, 58, 86, 98, 99, 64, 65, + nil, nil, nil, 68, nil, 66, 67, 69, 318, 319, + 73, 74, nil, nil, nil, nil, nil, 78, 315, 321, + 106, 105, 107, 108, nil, nil, 238, nil, nil, nil, + nil, nil, nil, 46, nil, nil, 110, 109, 111, 100, + 57, 102, 101, 103, nil, 104, 112, 113, nil, 96, + 97, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 231, nil, nil, 237, nil, nil, 59, + 60, nil, nil, 61, nil, nil, nil, nil, nil, 45, + nil, nil, nil, nil, nil, nil, nil, nil, 236, nil, + nil, nil, nil, 94, 84, 87, 88, nil, 89, 91, + 90, 92, nil, nil, nil, nil, 85, 93, nil, nil, + nil, 75, 76, 77, 63, 58, 86, 98, 99, 64, + 65, nil, nil, nil, 68, nil, 66, 67, 69, 318, + 319, 73, 74, nil, nil, nil, nil, nil, 78, 315, + 321, 106, 105, 107, 108, nil, nil, 238, nil, nil, + nil, nil, nil, nil, 46, nil, nil, 110, 109, 111, + 100, 57, 102, 101, 103, nil, 104, 112, 113, nil, + 96, 97, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 231, nil, nil, 237, nil, nil, + 59, 60, nil, nil, 61, nil, nil, nil, nil, nil, + 45, nil, nil, nil, nil, nil, nil, nil, nil, 236, + nil, nil, nil, nil, 94, 84, 87, 88, nil, 89, + 91, 90, 92, nil, nil, nil, nil, 85, 93, nil, + nil, nil, 75, 76, 77, 63, 58, 86, 98, 99, + 64, 65, nil, nil, nil, 68, nil, 66, 67, 69, + 318, 319, 73, 74, nil, nil, nil, nil, nil, 78, + 315, 321, 106, 105, 107, 108, nil, nil, 238, nil, + nil, nil, nil, nil, nil, 46, nil, nil, 110, 109, + 111, 100, 57, 102, 101, 103, nil, 104, 112, 113, + nil, 96, 97, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 231, nil, nil, 237, nil, + nil, 59, 60, nil, nil, 61, nil, nil, nil, nil, + nil, 45, nil, nil, nil, nil, nil, nil, nil, nil, + 236, nil, nil, nil, nil, 94, 84, 87, 88, nil, + 89, 91, 90, 92, nil, nil, nil, nil, 85, 93, + nil, nil, nil, 75, 76, 77, 63, 58, 86, 98, + 99, 64, 65, nil, nil, nil, 68, nil, 66, 67, + 69, 318, 319, 73, 74, nil, nil, nil, nil, nil, + 78, 315, 321, 106, 105, 107, 108, nil, nil, 238, + nil, nil, nil, nil, nil, nil, 46, nil, nil, 110, + 109, 111, 100, 57, 102, 101, 103, nil, 104, 112, + 113, nil, 96, 97, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 231, nil, nil, 237, + nil, nil, 59, 60, nil, nil, 61, nil, nil, nil, + nil, nil, 45, nil, nil, nil, nil, nil, nil, nil, + nil, 236, nil, nil, nil, nil, 94, 84, 87, 88, + nil, 89, 91, 90, 92, nil, nil, nil, nil, 85, + 93, nil, nil, nil, 75, 76, 77, 63, 58, 86, + 98, 99, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 318, 319, 73, 74, nil, nil, nil, nil, + nil, 78, 315, 321, 106, 105, 107, 108, nil, nil, + 238, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 110, 109, 111, 100, 57, 102, 101, 103, nil, 104, + 112, 113, nil, 96, 97, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 231, nil, nil, + 237, nil, nil, 59, 60, nil, nil, 61, nil, nil, + nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, + nil, nil, 236, nil, nil, nil, nil, 94, 84, 87, + 88, nil, 89, 91, 90, 92, nil, nil, nil, nil, + 85, 93, nil, nil, nil, 75, 76, 77, 63, 58, + 86, 98, 99, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 318, 319, 73, 74, nil, nil, nil, + nil, nil, 78, 315, 321, 106, 105, 107, 108, nil, + nil, 238, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 231, nil, + nil, 237, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 236, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, 75, 76, 77, 63, + 58, 86, 98, 99, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 318, 319, 73, 74, nil, nil, + nil, nil, nil, 78, 315, 321, 106, 105, 107, 108, + nil, nil, 238, nil, nil, nil, nil, nil, nil, 46, + nil, nil, 110, 109, 111, 100, 57, 102, 101, 103, + nil, 104, 112, 113, nil, 96, 97, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 231, + nil, nil, 237, nil, nil, 59, 60, nil, nil, 61, + nil, nil, nil, nil, nil, 45, nil, nil, nil, nil, + nil, nil, nil, nil, 236, nil, nil, nil, nil, 94, + 84, 87, 88, nil, 89, 91, 90, 92, nil, nil, + nil, nil, 85, 93, nil, nil, nil, 75, 76, 77, + 63, 58, 86, 98, 99, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 318, 319, 73, 74, nil, + nil, nil, nil, nil, 78, 315, 321, 106, 105, 107, + 108, nil, nil, 238, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 110, 109, 111, 100, 57, 102, 101, + 103, nil, 104, 112, 113, nil, 96, 97, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 231, nil, nil, 237, nil, nil, 59, 60, nil, nil, + 61, nil, nil, nil, nil, nil, 45, nil, nil, nil, + nil, nil, nil, nil, nil, 236, nil, nil, nil, nil, + 94, 84, 87, 88, nil, 89, 91, 90, 92, nil, + nil, nil, nil, 85, 93, nil, nil, nil, 75, 76, + 77, 63, 58, 86, 98, 99, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 318, 319, 73, 74, + nil, nil, nil, nil, nil, 78, 315, 321, 106, 105, + 107, 108, nil, nil, 238, nil, nil, nil, nil, nil, + nil, 46, nil, nil, 110, 109, 111, 100, 57, 102, + 101, 103, nil, 104, 112, 113, nil, 96, 97, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 231, nil, nil, 237, nil, nil, 59, 60, nil, + nil, 61, nil, nil, nil, nil, nil, 45, nil, nil, + nil, nil, nil, nil, nil, nil, 236, nil, nil, nil, + nil, 94, 84, 87, 88, nil, 89, 91, 90, 92, + nil, nil, nil, nil, 85, 93, nil, nil, nil, 75, + 76, 77, 63, 58, 86, 98, 99, 64, 65, nil, + nil, nil, 68, nil, 66, 67, 69, 318, 319, 73, + 74, nil, nil, nil, nil, nil, 78, 315, 321, 106, + 105, 107, 108, nil, nil, 238, nil, nil, nil, nil, + nil, nil, 46, nil, nil, 110, 109, 111, 100, 57, + 102, 101, 103, nil, 104, 112, 113, nil, 96, 97, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 231, nil, nil, 237, nil, nil, 59, 60, + nil, nil, 61, nil, nil, nil, nil, nil, 45, nil, + nil, nil, nil, nil, nil, nil, nil, 236, nil, nil, + nil, nil, 94, 84, 87, 88, nil, 89, 91, 90, + 92, nil, nil, nil, nil, 85, 93, nil, nil, nil, + 75, 76, 77, 63, 58, 86, 98, 99, 64, 65, + nil, nil, nil, 68, nil, 66, 67, 69, 318, 319, + 73, 74, nil, nil, nil, nil, nil, 78, 315, 321, + 106, 105, 107, 108, nil, nil, 238, nil, nil, nil, + nil, nil, nil, 46, nil, nil, 110, 109, 111, 100, + 57, 102, 101, 103, nil, 104, 112, 113, nil, 96, + 97, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 231, nil, nil, 237, nil, nil, 59, + 60, nil, nil, 61, nil, nil, nil, nil, nil, 45, + nil, nil, nil, nil, nil, nil, nil, nil, 236, nil, + nil, nil, nil, 94, 84, 87, 88, nil, 89, 91, + 90, 92, nil, nil, nil, nil, 85, 93, nil, nil, + nil, 75, 76, 77, 63, 58, 86, 98, 99, 64, + 65, nil, nil, nil, 68, nil, 66, 67, 69, 318, + 319, 73, 74, nil, nil, nil, nil, nil, 78, 315, + 321, 106, 105, 107, 108, nil, nil, 238, nil, nil, + nil, nil, nil, nil, 46, nil, nil, 110, 109, 111, + 100, 57, 102, 101, 103, nil, 104, 112, 113, nil, + 96, 97, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 231, nil, nil, 237, nil, nil, + 59, 60, nil, nil, 61, nil, nil, nil, nil, nil, + 45, nil, nil, nil, nil, nil, nil, nil, nil, 236, + nil, nil, nil, nil, 94, 84, 87, 88, nil, 89, + 91, 90, 92, nil, nil, nil, nil, 85, 93, nil, + nil, nil, 75, 76, 77, 63, 58, 86, 98, 99, + 64, 65, nil, nil, nil, 68, nil, 66, 67, 69, + 318, 319, 73, 74, nil, nil, nil, nil, nil, 78, + 315, 321, 106, 105, 107, 108, nil, nil, 238, nil, + nil, nil, nil, nil, nil, 46, nil, nil, 110, 109, + 111, 100, 57, 102, 101, 103, nil, 104, 112, 113, + nil, 96, 97, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 231, nil, nil, 237, nil, + nil, 59, 60, nil, nil, 61, nil, nil, nil, nil, + nil, 45, nil, nil, nil, nil, nil, nil, nil, nil, + 236, nil, nil, nil, nil, 94, 84, 87, 88, nil, + 89, 91, 90, 92, nil, nil, nil, nil, 85, 93, + nil, nil, nil, 75, 76, 77, 63, 58, 86, 98, + 99, 64, 65, nil, nil, nil, 68, nil, 66, 67, + 69, 318, 319, 73, 74, nil, nil, nil, nil, nil, + 78, 315, 321, 106, 105, 107, 108, nil, nil, 238, + nil, nil, nil, nil, nil, nil, 46, nil, nil, 110, + 109, 111, 100, 57, 102, 101, 103, nil, 104, 112, + 113, nil, 96, 97, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 231, nil, nil, 237, + nil, nil, 59, 60, nil, nil, 61, nil, nil, nil, + nil, nil, 45, nil, nil, nil, nil, nil, nil, nil, + nil, 236, nil, nil, nil, nil, 94, 84, 87, 88, + nil, 89, 91, 90, 92, nil, nil, nil, nil, 85, + 93, nil, nil, nil, 75, 76, 77, 63, 58, 86, + 98, 99, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 318, 319, 73, 74, nil, nil, nil, nil, + nil, 78, 315, 321, 106, 105, 107, 108, nil, nil, + 238, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 110, 109, 111, 100, 57, 102, 101, 103, nil, 104, + 112, 113, nil, 96, 97, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 231, nil, nil, + 237, nil, nil, 59, 60, nil, nil, 61, nil, nil, + nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, + nil, nil, 236, nil, nil, nil, nil, 94, 84, 87, + 88, nil, 89, 91, 90, 92, nil, nil, nil, nil, + 85, 93, nil, nil, nil, 75, 76, 77, 63, 58, + 86, 98, 99, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 318, 319, 73, 74, nil, nil, nil, + nil, nil, 78, 315, 321, 106, 105, 107, 108, nil, + nil, 238, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 231, nil, + nil, 237, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 236, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, 75, 76, 77, 63, + 58, 86, 98, 99, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 318, 319, 73, 74, nil, nil, + nil, nil, nil, 78, 315, 321, 106, 105, 107, 108, + nil, nil, 238, nil, nil, nil, nil, nil, nil, 46, + nil, nil, 110, 109, 111, 100, 57, 102, 101, 103, + nil, 104, 112, 113, nil, 96, 97, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 231, + nil, nil, 237, nil, nil, 59, 60, nil, nil, 61, + nil, nil, nil, nil, nil, 45, nil, nil, nil, nil, + nil, nil, nil, nil, 236, nil, nil, nil, nil, 94, + 84, 87, 88, nil, 89, 91, 90, 92, nil, nil, + nil, nil, 85, 93, nil, nil, nil, 75, 76, 77, + 63, 58, 86, 98, 99, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 318, 319, 73, 74, nil, + nil, nil, nil, nil, 78, 315, 321, 106, 105, 107, + 108, nil, nil, 238, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 110, 109, 111, 100, 57, 102, 101, + 103, nil, 104, 112, 113, nil, 96, 97, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 231, nil, nil, 237, nil, nil, 59, 60, nil, nil, + 61, nil, nil, nil, nil, nil, 45, nil, nil, nil, + nil, nil, nil, nil, nil, 236, nil, nil, nil, nil, + 94, 84, 87, 88, nil, 89, 91, 90, 92, nil, + nil, nil, nil, 85, 93, nil, nil, nil, 75, 76, + 77, 63, 58, 86, 98, 99, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 318, 319, 73, 74, + nil, nil, nil, nil, nil, 78, 315, 321, 106, 105, + 107, 108, nil, nil, 238, nil, nil, nil, nil, nil, + nil, 46, nil, nil, 110, 109, 111, 100, 57, 102, + 101, 103, nil, 104, 112, 113, nil, 96, 97, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 231, nil, nil, 237, nil, nil, 59, 60, nil, + nil, 61, nil, nil, nil, nil, nil, 45, nil, nil, + nil, nil, nil, nil, nil, nil, 236, nil, nil, nil, + nil, 94, 84, 87, 88, nil, 89, 91, 90, 92, + nil, nil, nil, nil, 85, 93, nil, nil, nil, 75, + 76, 77, 63, 58, 86, 98, 99, 64, 65, nil, + nil, nil, 68, nil, 66, 67, 69, 318, 319, 73, + 74, nil, nil, nil, nil, nil, 78, 315, 321, 106, + 105, 107, 108, nil, nil, 238, nil, nil, nil, nil, + nil, nil, 46, nil, nil, 110, 109, 111, 100, 57, + 102, 101, 103, nil, 104, 112, 113, nil, 96, 97, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 231, nil, nil, 237, nil, nil, 59, 60, + nil, nil, 61, nil, nil, nil, nil, nil, 45, nil, + nil, nil, nil, nil, nil, nil, nil, 236, nil, nil, + nil, nil, 94, 84, 87, 88, nil, 89, 91, 90, + 92, nil, nil, nil, nil, 85, 93, nil, nil, nil, + 75, 76, 77, 63, 58, 86, 98, 99, 64, 65, + nil, nil, nil, 68, nil, 66, 67, 69, 30, 31, + 73, 74, nil, nil, nil, nil, nil, 78, 28, 27, + 106, 105, 107, 108, nil, nil, 238, nil, nil, nil, + nil, nil, nil, 46, nil, nil, 110, 109, 111, 100, + 57, 102, 101, 103, 293, 104, 112, 113, nil, 96, + 97, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 231, nil, nil, 237, nil, nil, 59, + 60, nil, nil, 61, nil, 290, nil, 288, nil, 45, + nil, nil, 294, nil, nil, nil, nil, nil, 236, nil, + nil, nil, nil, 94, 291, 87, 88, nil, 89, 91, + 90, 92, nil, nil, nil, nil, 85, 93, nil, nil, + nil, 75, 76, 77, 63, 58, 86, 98, 99, 64, + 65, nil, nil, nil, 68, nil, 66, 67, 69, 30, + 31, 73, 74, nil, nil, nil, nil, nil, 78, 28, + 27, 106, 105, 107, 108, nil, nil, 238, nil, nil, + nil, nil, nil, nil, 46, nil, nil, 110, 109, 111, + 100, 57, 102, 101, 103, 293, 104, 112, 113, nil, + 96, 97, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 231, nil, nil, 237, nil, nil, + 59, 60, nil, nil, 61, nil, 290, nil, 288, nil, + 45, nil, nil, 294, nil, nil, nil, nil, nil, 236, + nil, nil, nil, nil, 94, 291, 87, 88, nil, 89, + 91, 90, 92, nil, nil, nil, nil, 85, 93, nil, + nil, nil, 75, 76, 77, 63, 58, 86, 98, 99, + 64, 65, nil, nil, nil, 68, nil, 66, 67, 69, + 30, 31, 73, 74, nil, nil, nil, nil, nil, 78, + 28, 27, 106, 105, 107, 108, nil, nil, 238, nil, + nil, nil, nil, nil, nil, 46, nil, nil, 110, 109, + 111, 100, 57, 102, 101, 103, 293, 104, 112, 113, + nil, 96, 97, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 231, nil, nil, 237, nil, + nil, 59, 60, nil, nil, 61, nil, 290, nil, 288, + nil, 45, nil, nil, 294, nil, nil, nil, nil, nil, + 236, nil, nil, nil, nil, 94, 291, 87, 88, nil, + 89, 91, 90, 92, nil, nil, nil, nil, 85, 93, + 226, nil, nil, 75, 76, 77, 63, 58, 86, 98, + 99, 64, 65, nil, nil, nil, 68, nil, 66, 67, + 69, 318, 319, 73, 74, nil, nil, nil, nil, nil, + 78, 315, 321, 106, 105, 107, 108, nil, nil, 238, + nil, nil, nil, nil, nil, nil, 46, nil, nil, 110, + 109, 111, 100, 57, 102, 101, 103, nil, 104, 112, + 113, nil, 96, 97, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 231, nil, nil, 237, + nil, nil, 59, 60, nil, nil, 61, nil, nil, nil, + nil, nil, 45, nil, nil, nil, nil, nil, nil, nil, + nil, 236, nil, nil, nil, nil, 94, 84, 87, 88, + nil, 89, 91, 90, 92, nil, nil, nil, nil, 85, + 93, nil, nil, nil, 75, 76, 77, 63, 58, 86, + 98, 99, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 318, 319, 73, 74, nil, nil, nil, nil, + nil, 78, 315, 321, 106, 105, 107, 108, nil, nil, + 238, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 110, 109, 111, 100, 57, 102, 101, 103, nil, 104, + 112, 113, nil, 96, 97, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 231, nil, nil, + 237, nil, nil, 59, 60, nil, nil, 61, nil, nil, + nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, + nil, nil, 236, nil, nil, nil, nil, 94, 84, 87, + 88, nil, 89, 91, 90, 92, nil, nil, nil, nil, + 85, 93, nil, nil, nil, 75, 76, 77, 63, 58, + 86, 98, 99, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 318, 319, 73, 74, nil, nil, nil, + nil, nil, 78, 315, 321, 106, 105, 107, 108, nil, + nil, 238, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 231, nil, + nil, 237, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 236, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, 75, 76, 77, 63, + 58, 86, 98, 99, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 318, 319, 73, 74, nil, nil, + nil, nil, nil, 78, 315, 321, 106, 105, 107, 108, + nil, nil, 238, nil, nil, nil, nil, nil, nil, 46, + nil, nil, 110, 109, 111, 100, 57, 102, 101, 103, + nil, 104, 112, 113, nil, 96, 97, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 231, + nil, nil, 237, nil, nil, 59, 60, nil, nil, 61, + nil, nil, nil, nil, nil, 45, nil, nil, nil, nil, + nil, nil, nil, nil, 236, nil, nil, nil, nil, 94, + 84, 87, 88, nil, 89, 91, 90, 92, nil, nil, + nil, nil, 85, 93, nil, nil, nil, nil, nil, nil, + 63, nil, 86, 98, 99, 75, 76, 77, 9, 58, + nil, nil, nil, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 19, nil, nil, nil, nil, nil, 8, 46, nil, + 10, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 33, nil, nil, 59, 60, nil, nil, 61, nil, + 35, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, 75, 76, 77, 63, + 58, 86, 98, 99, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 318, 319, 73, 74, nil, nil, + nil, nil, nil, 78, 315, 321, 106, 105, 107, 108, + nil, nil, 238, nil, nil, nil, nil, nil, nil, 316, + nil, nil, 110, 109, 111, 100, 57, 102, 101, 103, + nil, 104, 112, 113, nil, 96, 97, nil, nil, 322, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 312, + nil, nil, 237, nil, nil, 59, 60, nil, nil, 61, + nil, nil, 683, nil, 680, 679, 678, 688, 681, nil, + nil, nil, nil, nil, nil, nil, nil, 691, nil, 94, + 84, 87, 88, nil, 89, 91, 90, 92, nil, nil, + nil, nil, 85, 93, nil, nil, nil, 516, nil, 686, + 63, nil, 86, 98, 99, 75, 76, 77, nil, 58, + 699, 698, nil, 64, 65, 692, nil, nil, 68, nil, + 66, 67, 69, 318, 319, 73, 74, nil, nil, nil, + nil, nil, 78, 315, 321, 106, 105, 107, 108, nil, + nil, 238, nil, nil, nil, nil, nil, nil, 316, nil, + nil, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, nil, nil, 322, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 312, nil, + nil, 308, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, 75, 76, 77, 63, + 58, 86, 98, 99, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 318, 319, 73, 74, nil, nil, + nil, nil, nil, 78, 315, 321, 106, 105, 107, 108, + nil, nil, 238, nil, nil, nil, nil, nil, nil, 46, + nil, nil, 110, 109, 111, 100, 57, 102, 101, 103, + nil, 104, 112, 113, nil, 96, 97, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 231, + nil, nil, 237, nil, nil, 59, 60, nil, nil, 61, + nil, nil, nil, nil, nil, 45, nil, nil, nil, nil, + nil, nil, nil, nil, 236, nil, nil, nil, nil, 94, + 84, 87, 88, nil, 89, 91, 90, 92, nil, nil, + nil, nil, 85, 93, nil, nil, nil, 75, 76, 77, + 63, 58, 86, 98, 99, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 318, 319, 73, 74, nil, + nil, nil, nil, nil, 78, 315, 321, 106, 105, 107, + 108, nil, nil, 238, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 110, 109, 111, 100, 57, 102, 101, + 103, nil, 104, 112, 113, nil, 96, 97, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 231, nil, nil, 237, 533, nil, 59, 60, nil, nil, + 61, nil, nil, nil, nil, nil, 45, nil, nil, nil, + nil, nil, nil, nil, nil, 236, nil, nil, nil, nil, + 94, 84, 87, 88, nil, 89, 91, 90, 92, nil, + nil, nil, nil, 85, 93, nil, nil, nil, 75, 76, + 77, 63, 58, 86, 98, 99, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 30, 31, 73, 74, + nil, nil, nil, nil, nil, 78, 28, 27, 106, 105, + 107, 108, nil, nil, 19, nil, nil, nil, nil, nil, + nil, 46, nil, nil, 110, 109, 111, 100, 57, 102, + 101, 103, nil, 104, 112, 113, nil, 96, 97, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 231, nil, nil, 237, nil, nil, 59, 60, nil, + nil, 61, nil, nil, nil, nil, nil, 45, nil, nil, + nil, nil, nil, nil, nil, nil, 20, nil, nil, nil, + nil, 94, 84, 87, 88, nil, 89, 91, 90, 92, + nil, nil, nil, nil, 85, 93, nil, nil, nil, 75, + 76, 77, 63, 58, 86, 98, 99, 64, 65, nil, + nil, nil, 68, nil, 66, 67, 69, 30, 31, 73, + 74, nil, nil, nil, nil, nil, 78, 28, 27, 106, + 105, 107, 108, nil, nil, 19, nil, nil, nil, nil, + nil, nil, 46, nil, nil, 110, 109, 111, 100, 57, + 102, 101, 103, nil, 104, 112, 113, nil, 96, 97, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 231, nil, nil, 237, nil, nil, 59, 60, + nil, nil, 61, nil, nil, nil, nil, nil, 45, nil, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, nil, 94, 84, 87, 88, nil, 89, 91, 90, + 92, nil, nil, nil, nil, 85, 93, nil, nil, nil, + 75, 76, 77, 63, 58, 86, 98, 99, 64, 65, + nil, nil, nil, 68, nil, 66, 67, 69, 30, 31, + 73, 74, nil, nil, nil, nil, nil, 78, 28, 27, + 106, 105, 107, 108, nil, nil, 19, nil, nil, nil, + nil, nil, nil, 46, nil, nil, 110, 109, 111, 100, + 57, 102, 101, 103, nil, 104, 112, 113, nil, 96, + 97, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 231, nil, nil, 237, nil, nil, 59, + 60, nil, nil, 61, nil, nil, nil, nil, nil, 45, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, nil, nil, 94, 84, 87, 88, nil, 89, 91, + 90, 92, nil, nil, nil, nil, 85, 93, nil, nil, + nil, 75, 76, 77, 63, 58, 86, 98, 99, 64, + 65, nil, nil, nil, 68, nil, 66, 67, 69, 318, + 319, 73, 74, nil, nil, nil, nil, nil, 78, 315, + 321, 106, 105, 107, 108, nil, nil, 238, nil, nil, + nil, nil, nil, nil, 46, nil, nil, 110, 109, 111, + 100, 57, 102, 101, 103, nil, 104, 112, 113, nil, + 96, 97, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 231, nil, nil, 237, nil, nil, + 59, 60, nil, nil, 61, nil, nil, nil, nil, nil, + 45, nil, nil, nil, nil, nil, nil, nil, nil, 236, + nil, nil, nil, nil, 94, 84, 87, 88, nil, 89, + 91, 90, 92, nil, nil, nil, nil, 85, 93, nil, + nil, nil, 75, 76, 77, 63, 58, 86, 98, 99, + 64, 65, nil, nil, nil, 68, nil, 66, 67, 69, + 30, 31, 73, 74, nil, nil, nil, nil, nil, 78, + 28, 27, 106, 105, 107, 108, nil, nil, 238, nil, + nil, nil, nil, nil, nil, 46, nil, nil, 110, 109, + 111, 100, 57, 102, 101, 103, 293, 104, 112, 113, + nil, 96, 97, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 231, nil, nil, 237, nil, + nil, 59, 60, nil, nil, 61, nil, 290, nil, 288, + nil, 45, nil, nil, 294, nil, nil, nil, nil, nil, + 236, nil, nil, nil, nil, 94, 291, 87, 88, nil, + 89, 91, 90, 92, nil, nil, nil, nil, 85, 93, + nil, nil, nil, 75, 76, 77, 63, 58, 86, 98, + 99, 64, 65, nil, nil, nil, 68, nil, 66, 67, + 69, 318, 319, 73, 74, nil, nil, nil, nil, nil, + 78, 315, 321, 106, 105, 107, 108, nil, nil, 238, + nil, nil, nil, nil, nil, nil, 46, nil, nil, 110, + 109, 111, 100, 57, 102, 101, 103, nil, 104, 112, + 113, nil, 96, 97, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 231, nil, nil, 237, + nil, nil, 59, 60, nil, nil, 61, nil, nil, nil, + nil, nil, 45, nil, nil, nil, nil, nil, nil, nil, + nil, 236, nil, nil, nil, nil, 94, 84, 87, 88, + nil, 89, 91, 90, 92, nil, nil, nil, nil, 85, + 93, nil, nil, nil, 75, 76, 77, 63, 58, 86, + 98, 99, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 318, 319, 73, 74, nil, nil, nil, nil, + nil, 78, 315, 321, 106, 105, 107, 108, nil, nil, + 238, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 110, 109, 111, 100, 57, 102, 101, 103, nil, 104, + 112, 113, nil, 96, 97, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 231, nil, nil, + 237, nil, nil, 59, 60, nil, nil, 61, nil, nil, + nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, + nil, nil, 236, nil, nil, nil, nil, 94, 84, 87, + 88, nil, 89, 91, 90, 92, nil, nil, nil, nil, + 85, 93, nil, nil, nil, 75, 76, 77, 63, 58, + 86, 98, 99, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 318, 319, 73, 74, nil, nil, nil, + nil, nil, 78, 315, 321, 106, 105, 107, 108, nil, + nil, 238, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 231, nil, + nil, 237, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 236, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, 75, 76, 77, 63, + 58, 86, 98, 99, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 318, 319, 73, 74, nil, nil, + nil, nil, nil, 78, 315, 321, 106, 105, 107, 108, + nil, nil, 238, nil, nil, nil, nil, nil, nil, 46, + nil, nil, 110, 109, 111, 100, 57, 102, 101, 103, + 293, 104, 112, 113, nil, 96, 97, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 231, + nil, nil, 237, nil, nil, 59, 60, nil, nil, 61, + nil, 641, nil, 288, nil, 45, nil, nil, 294, nil, + nil, nil, nil, nil, 236, nil, nil, nil, nil, 94, + 291, 87, 88, nil, 89, 91, 90, 92, nil, nil, + nil, nil, 85, 93, nil, nil, nil, 75, 76, 77, + 63, 58, 86, 98, 99, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 318, 319, 73, 74, nil, + nil, nil, nil, nil, 78, 315, 321, 106, 105, 107, + 108, nil, nil, 238, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 110, 109, 111, 100, 57, 102, 101, + 103, 293, 104, 112, 113, nil, 96, 97, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 231, nil, nil, 237, nil, nil, 59, 60, nil, nil, + 61, nil, nil, nil, 288, nil, 45, nil, nil, 294, + nil, nil, nil, nil, nil, 236, nil, nil, nil, nil, + 94, 291, 87, 88, nil, 89, 91, 90, 92, nil, + nil, nil, nil, 85, 93, nil, nil, nil, 75, 76, + 77, 63, 58, 86, 98, 99, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 318, 319, 73, 74, + nil, nil, nil, nil, nil, 78, 315, 321, 106, 105, + 107, 108, nil, nil, 238, nil, nil, nil, nil, nil, + nil, 46, nil, nil, 110, 109, 111, 100, 57, 102, + 101, 103, nil, 104, 112, 113, nil, 96, 97, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 231, nil, nil, 237, nil, nil, 59, 60, nil, + nil, 61, nil, nil, nil, nil, nil, 45, nil, nil, + nil, nil, nil, nil, nil, nil, 236, nil, nil, nil, + nil, 94, 84, 87, 88, nil, 89, 91, 90, 92, + nil, nil, nil, nil, 85, 93, nil, nil, nil, nil, + nil, nil, 63, nil, 86, 98, 99, 75, 76, 77, + 9, 58, nil, nil, nil, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 30, 31, 73, 74, nil, + nil, nil, nil, nil, 78, 28, 27, 106, 105, 107, + 108, nil, nil, 19, nil, nil, nil, nil, nil, 8, + 46, 301, 10, 110, 109, 111, 100, 57, 102, 101, + 103, nil, 104, 112, 113, nil, 96, 97, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 40, nil, nil, 33, nil, nil, 59, 60, nil, nil, + 61, nil, 35, nil, nil, nil, 45, nil, nil, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, nil, + 94, 84, 87, 88, nil, 89, 91, 90, 92, nil, + nil, nil, nil, 85, 93, nil, nil, nil, nil, nil, + 398, 63, nil, 86, 98, 99, 75, 76, 77, nil, + 58, nil, nil, nil, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 318, 319, 73, 74, nil, nil, + nil, nil, nil, 78, 315, 321, 106, 105, 107, 108, + nil, nil, 238, nil, nil, nil, nil, nil, nil, 316, + nil, nil, 110, 109, 111, 100, 57, 102, 101, 103, + nil, 104, 112, 113, nil, 96, 97, nil, nil, 322, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 312, + nil, nil, 308, nil, nil, 59, 60, nil, nil, 61, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 94, + 84, 87, 88, nil, 89, 91, 90, 92, nil, nil, + nil, nil, 85, 93, nil, nil, nil, 75, 76, 77, + 63, 58, 86, 98, 99, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 30, 31, 73, 74, nil, + nil, nil, nil, nil, 78, 28, 27, 106, 105, 107, + 108, nil, nil, 238, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 110, 109, 111, 100, 57, 102, 101, + 103, 293, 104, 112, 113, nil, 96, 97, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 231, nil, nil, 237, nil, nil, 59, 60, nil, nil, + 61, nil, 290, nil, 288, nil, 45, nil, nil, 294, + nil, nil, nil, nil, nil, 236, nil, nil, nil, nil, + 94, 291, 87, 88, nil, 89, 91, 90, 92, nil, + nil, nil, nil, 85, 93, nil, nil, nil, 75, 76, + 77, 63, 58, 86, 98, 99, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 318, 319, 73, 74, + nil, nil, nil, nil, nil, 78, 315, 321, 106, 105, + 107, 108, nil, nil, 238, nil, nil, nil, nil, nil, + nil, 316, nil, nil, 110, 109, 111, 100, 57, 102, + 101, 103, nil, 104, 112, 113, nil, 96, 97, nil, + nil, 322, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 312, nil, nil, 308, nil, nil, 59, 60, nil, + nil, 61, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 94, 84, 87, 88, nil, 89, 91, 90, 92, + nil, nil, nil, nil, 85, 93, nil, nil, nil, 75, + 76, 77, 63, 58, 86, 98, 99, 64, 65, nil, + nil, nil, 68, nil, 66, 67, 69, 318, 319, 73, + 74, nil, nil, nil, nil, nil, 78, 315, 321, 106, + 105, 107, 108, nil, nil, 238, nil, nil, nil, nil, + nil, nil, 46, nil, nil, 110, 109, 111, 100, 57, + 102, 101, 103, nil, 104, 112, 113, nil, 96, 97, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 231, nil, nil, 237, nil, nil, 59, 60, + nil, nil, 61, nil, nil, nil, nil, nil, 45, nil, + nil, nil, nil, nil, nil, nil, nil, 236, nil, nil, + nil, nil, 94, 84, 87, 88, nil, 89, 91, 90, + 92, nil, nil, nil, nil, 85, 93, nil, nil, nil, + 75, 76, 77, 63, 58, 86, 98, 99, 64, 65, + nil, nil, nil, 68, nil, 66, 67, 69, 318, 319, + 73, 74, nil, nil, nil, nil, nil, 78, 315, 321, + 106, 105, 107, 108, nil, nil, 238, nil, nil, nil, + nil, nil, nil, 46, nil, nil, 110, 109, 111, 100, + 57, 102, 101, 103, nil, 104, 112, 113, nil, 96, + 97, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 231, nil, nil, 237, nil, nil, 59, + 60, nil, nil, 61, nil, nil, nil, nil, nil, 45, + nil, nil, nil, nil, nil, nil, nil, nil, 236, nil, + nil, nil, nil, 94, 84, 87, 88, nil, 89, 91, + 90, 92, nil, nil, nil, nil, 85, 93, nil, nil, + nil, 75, 76, 77, 63, 58, 86, 98, 99, 64, + 65, nil, nil, nil, 68, nil, 66, 67, 69, 30, + 31, 73, 74, nil, nil, nil, nil, nil, 78, 28, + 27, 106, 105, 107, 108, nil, nil, 19, nil, nil, + nil, nil, nil, nil, 46, nil, nil, 110, 109, 111, + 100, 57, 102, 101, 103, nil, 104, 112, 113, nil, + 96, 97, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 231, nil, nil, 237, nil, nil, + 59, 60, nil, nil, 61, nil, nil, nil, nil, nil, + 45, nil, nil, nil, nil, nil, nil, nil, nil, 20, + nil, nil, nil, nil, 94, 84, 87, 88, nil, 89, + 91, 90, 92, nil, nil, nil, nil, 85, 93, nil, + nil, nil, 75, 76, 77, 63, 58, 86, 98, 99, + 64, 65, nil, nil, nil, 68, nil, 66, 67, 69, + 318, 319, 73, 74, nil, nil, nil, nil, nil, 78, + 315, 321, 106, 105, 107, 108, nil, nil, 238, nil, + nil, nil, nil, nil, nil, 46, nil, nil, 110, 109, + 111, 100, 57, 102, 101, 103, 293, 104, 112, 113, + nil, 96, 97, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 231, nil, nil, 237, nil, + nil, 59, 60, nil, nil, 61, nil, 641, nil, nil, + nil, 45, nil, nil, 294, nil, nil, nil, nil, nil, + 236, nil, nil, nil, nil, 94, 291, 87, 88, nil, + 89, 91, 90, 92, nil, nil, nil, nil, 85, 93, + nil, nil, nil, 75, 76, 77, 63, 58, 86, 98, + 99, 64, 65, nil, nil, nil, 68, nil, 66, 67, + 69, 318, 319, 73, 74, nil, nil, nil, nil, nil, + 78, 315, 321, 106, 105, 107, 108, nil, nil, 238, + nil, nil, nil, nil, nil, nil, 46, nil, nil, 110, + 109, 111, 100, 57, 102, 101, 103, 293, 104, 112, + 113, nil, 96, 97, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 231, nil, nil, 237, + nil, nil, 59, 60, nil, nil, 61, nil, nil, nil, + nil, nil, 45, nil, nil, 294, nil, nil, nil, nil, + nil, 236, nil, nil, nil, nil, 94, 291, 87, 88, + nil, 89, 91, 90, 92, nil, nil, nil, nil, 85, + 93, nil, nil, nil, 75, 76, 77, 63, 58, 86, + 98, 99, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 318, 319, 73, 74, nil, nil, nil, nil, + nil, 78, 315, 321, 106, 105, 107, 108, nil, nil, + 238, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 110, 109, 111, 100, 57, 102, 101, 103, nil, 104, + 112, 113, nil, 96, 97, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 231, nil, nil, + 237, nil, nil, 59, 60, nil, nil, 61, nil, 290, + nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, + nil, nil, 236, nil, nil, nil, nil, 94, 84, 87, + 88, nil, 89, 91, 90, 92, nil, nil, nil, nil, + 85, 93, nil, nil, nil, 75, 76, 77, 63, 58, + 86, 98, 99, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 238, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 110, 109, 111, 100, 57, 102, 101, 103, 293, + 104, 112, 113, nil, 96, 97, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 231, nil, + nil, 237, nil, nil, 59, 60, nil, nil, 61, nil, + 290, nil, 288, nil, 45, nil, nil, 294, nil, nil, + nil, nil, nil, 236, nil, nil, nil, nil, 94, 291, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, 75, 76, 77, 63, + 58, 86, 98, 99, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 30, 31, 73, 74, nil, nil, + nil, nil, nil, 78, 28, 27, 106, 105, 107, 108, + nil, nil, 238, nil, nil, nil, nil, nil, nil, 46, + nil, nil, 110, 109, 111, 100, 57, 102, 101, 103, + 293, 104, 112, 113, nil, 96, 97, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 231, + nil, nil, 237, nil, nil, 59, 60, nil, nil, 61, + nil, 290, nil, 288, nil, 45, nil, nil, 294, nil, + nil, nil, nil, nil, 236, nil, nil, nil, nil, 94, + 291, 87, 88, nil, 89, 91, 90, 92, nil, nil, + nil, nil, 85, 93, nil, nil, nil, 75, 76, 77, + 63, 58, 86, 98, 99, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 318, 319, 73, 74, nil, + nil, nil, nil, nil, 78, 315, 321, 106, 105, 107, + 108, nil, nil, 238, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 110, 109, 111, 100, 57, 102, 101, + 103, nil, 104, 112, 113, nil, 96, 97, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 231, nil, nil, 237, nil, nil, 59, 60, nil, nil, + 61, nil, 745, nil, nil, nil, 45, nil, nil, nil, + nil, nil, nil, nil, nil, 236, nil, nil, nil, nil, + 94, 84, 87, 88, nil, 89, 91, 90, 92, nil, + nil, nil, nil, 85, 93, nil, nil, nil, 75, 76, + 77, 63, 58, 86, 98, 99, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 30, 31, 73, 74, + nil, nil, nil, nil, nil, 78, 28, 27, 106, 105, + 107, 108, nil, nil, 238, nil, nil, nil, nil, nil, + nil, 46, nil, nil, 110, 109, 111, 100, 57, 102, + 101, 103, nil, 104, 112, 113, nil, 96, 97, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 231, nil, nil, 237, nil, nil, 59, 60, nil, + nil, 61, nil, nil, nil, nil, nil, 45, nil, nil, + nil, nil, nil, nil, nil, nil, 236, nil, nil, nil, + nil, 94, 84, 87, 88, nil, 89, 91, 90, 92, + nil, nil, nil, nil, 85, 93, nil, nil, nil, 75, + 76, 77, 63, 58, 86, 98, 99, 64, 65, nil, + nil, nil, 68, nil, 66, 67, 69, 30, 31, 73, + 74, nil, nil, nil, nil, nil, 78, 28, 27, 106, + 105, 107, 108, nil, nil, 238, nil, nil, nil, nil, + nil, nil, 46, nil, nil, 110, 109, 111, 100, 57, + 102, 101, 103, 293, 104, 112, 113, nil, 96, 97, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 231, nil, nil, 237, nil, nil, 59, 60, + nil, nil, 61, nil, 290, nil, 288, nil, 45, nil, + nil, 294, nil, nil, nil, nil, nil, 236, nil, nil, + nil, nil, 94, 291, 87, 88, nil, 89, 91, 90, + 92, nil, nil, nil, nil, 85, 93, nil, nil, nil, + nil, nil, nil, 63, nil, 86, 98, 99, 75, 76, + 77, 9, 58, nil, nil, nil, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 30, 31, 73, 74, + nil, nil, nil, nil, nil, 78, 28, 27, 106, 105, + 107, 108, nil, nil, 19, nil, nil, nil, nil, nil, + 8, 46, nil, 10, 110, 109, 111, 100, 57, 102, + 101, 103, nil, 104, 112, 113, nil, 96, 97, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 40, nil, nil, 33, nil, nil, 59, 60, nil, + nil, 61, nil, 35, nil, nil, nil, 45, nil, nil, + nil, nil, nil, nil, nil, nil, 20, nil, nil, nil, + nil, 94, 84, 87, 88, nil, 89, 91, 90, 92, + nil, nil, nil, nil, 85, 93, nil, nil, nil, 75, + 76, 77, 63, 58, 86, 98, 99, 64, 65, nil, + nil, nil, 68, nil, 66, 67, 69, 318, 319, 73, + 74, nil, nil, nil, nil, nil, 78, 315, 321, 106, + 105, 107, 108, nil, nil, 238, nil, nil, nil, nil, + nil, nil, 46, nil, nil, 110, 109, 111, 100, 57, + 102, 101, 103, nil, 104, 112, 113, nil, 96, 97, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 231, nil, nil, 237, nil, nil, 59, 60, + nil, nil, 61, nil, nil, nil, nil, nil, 45, nil, + nil, nil, nil, nil, nil, nil, nil, 236, nil, nil, + nil, nil, 94, 84, 87, 88, nil, 89, 91, 90, + 92, nil, nil, nil, nil, 85, 93, nil, nil, nil, + 75, 76, 77, 63, 58, 86, 98, 99, 64, 65, + nil, nil, nil, 68, nil, 66, 67, 69, 318, 319, + 73, 74, nil, nil, nil, nil, nil, 78, 315, 321, + 106, 105, 107, 108, nil, nil, 238, nil, nil, nil, + nil, nil, nil, 46, nil, nil, 110, 109, 111, 100, + 57, 102, 101, 103, 293, 104, 112, 113, nil, 96, + 97, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 231, nil, nil, 237, nil, nil, 59, + 60, nil, nil, 61, nil, 641, nil, 288, nil, 45, + nil, nil, 294, nil, nil, nil, nil, nil, 236, nil, + nil, nil, nil, 94, 291, 87, 88, nil, 89, 91, + 90, 92, nil, nil, nil, nil, 85, 93, nil, nil, + nil, 75, 76, 77, 63, 58, 86, 98, 99, 64, + 65, nil, nil, nil, 68, nil, 66, 67, 69, 318, + 319, 73, 74, nil, nil, nil, nil, nil, 78, 315, + 321, 106, 105, 107, 108, nil, nil, 238, nil, nil, + nil, nil, nil, nil, 46, nil, nil, 110, 109, 111, + 100, 57, 102, 101, 103, 293, 104, 112, 113, nil, + 96, 97, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 231, nil, nil, 237, nil, nil, + 59, 60, nil, nil, 61, nil, nil, nil, 288, nil, + 45, nil, nil, 294, nil, nil, nil, nil, nil, 236, + nil, nil, nil, nil, 94, 291, 87, 88, nil, 89, + 91, 90, 92, nil, nil, nil, nil, 85, 93, nil, + nil, nil, 75, 76, 77, 63, 58, 86, 98, 99, + 64, 65, nil, nil, nil, 68, nil, 66, 67, 69, + 30, 31, 73, 74, nil, nil, nil, nil, nil, 78, + 28, 27, 106, 105, 107, 108, nil, nil, 238, nil, + nil, nil, nil, nil, nil, 46, nil, nil, 110, 109, + 111, 100, 57, 102, 101, 103, nil, 104, 112, 113, + nil, 96, 97, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 231, nil, nil, 237, nil, + nil, 59, 60, nil, nil, 61, nil, nil, nil, nil, + nil, 45, nil, nil, nil, nil, nil, nil, nil, nil, + 236, nil, nil, nil, nil, 94, 84, 87, 88, nil, + 89, 91, 90, 92, nil, nil, nil, nil, 85, 93, + nil, nil, nil, 75, 76, 77, 63, 58, 86, 98, + 99, 64, 65, nil, nil, nil, 68, nil, 66, 67, + 69, 30, 31, 73, 74, nil, nil, nil, nil, nil, + 78, 28, 27, 106, 105, 107, 108, nil, nil, 238, + nil, nil, nil, nil, nil, nil, 46, nil, nil, 110, + 109, 111, 100, 57, 102, 101, 103, nil, 104, 112, + 113, nil, 96, 97, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 231, nil, nil, 237, + nil, nil, 59, 60, nil, nil, 61, nil, nil, nil, + nil, nil, 45, nil, nil, nil, nil, nil, nil, nil, + nil, 236, nil, nil, nil, nil, 94, 84, 87, 88, + nil, 89, 91, 90, 92, nil, nil, nil, nil, 85, + 93, nil, nil, nil, 75, 76, 77, 63, 58, 86, + 98, 99, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 30, 31, 73, 74, nil, nil, nil, nil, + nil, 78, 28, 27, 106, 105, 107, 108, nil, nil, + 238, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 110, 109, 111, 100, 57, 102, 101, 103, nil, 104, + 112, 113, nil, 96, 97, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 231, nil, nil, + 237, nil, nil, 59, 60, nil, nil, 61, nil, nil, + nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, + nil, nil, 236, nil, nil, nil, nil, 94, 84, 87, + 88, nil, 89, 91, 90, 92, nil, nil, nil, nil, + 85, 93, nil, nil, nil, 75, 76, 77, 63, 58, + 86, 98, 99, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 30, 31, 73, 74, nil, nil, nil, + nil, nil, 78, 28, 27, 106, 105, 107, 108, nil, + nil, 238, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 231, nil, + nil, 237, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 236, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, 75, 76, 77, 63, + 58, 86, 98, 99, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 318, 319, 73, 74, nil, nil, + nil, nil, nil, 78, 315, 321, 106, 105, 107, 108, + nil, nil, 238, nil, nil, nil, nil, nil, nil, 46, + nil, nil, 110, 109, 111, 100, 57, 102, 101, 103, + nil, 104, 112, 113, nil, 96, 97, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 231, + nil, nil, 237, nil, nil, 59, 60, nil, nil, 61, + nil, nil, nil, nil, nil, 45, nil, nil, nil, nil, + nil, nil, nil, nil, 236, nil, nil, nil, nil, 94, + 84, 87, 88, nil, 89, 91, 90, 92, nil, nil, + nil, nil, 85, 93, nil, nil, nil, 75, 76, 77, + 63, 58, 86, 98, 99, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 318, 319, 73, 74, nil, + nil, nil, nil, nil, 78, 315, 321, 106, 105, 107, + 108, nil, nil, 238, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 110, 109, 111, 100, 57, 102, 101, + 103, nil, 104, 112, 113, nil, 96, 97, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 231, nil, nil, 237, nil, nil, 59, 60, nil, nil, + 61, nil, nil, nil, nil, nil, 45, nil, nil, nil, + nil, nil, nil, nil, nil, 236, nil, nil, nil, nil, + 94, 84, 87, 88, nil, 89, 91, 90, 92, nil, + nil, nil, nil, 85, 93, nil, nil, nil, 75, 76, + 77, 63, 58, 86, 98, 99, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 318, 319, 73, 74, + nil, nil, nil, nil, nil, 78, 315, 321, 106, 105, + 107, 108, nil, nil, 238, nil, nil, nil, nil, nil, + nil, 316, nil, nil, 110, 109, 111, 100, 57, 102, + 101, 103, nil, 104, 112, 113, nil, 96, 97, nil, + nil, 322, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 312, nil, nil, 308, nil, nil, 59, 60, nil, + nil, 61, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 94, 84, 87, 88, nil, 89, 91, 90, 92, + nil, nil, nil, nil, 85, 93, nil, nil, nil, 75, + 76, 77, 63, 58, 86, 98, 99, 64, 65, nil, + nil, nil, 68, nil, 66, 67, 69, 318, 319, 73, + 74, nil, nil, nil, nil, nil, 78, 315, 321, 106, + 105, 107, 108, nil, nil, 238, nil, nil, nil, nil, + nil, nil, 316, nil, nil, 110, 109, 111, 100, 57, + 102, 101, 103, nil, 104, 112, 113, nil, 96, 97, + nil, nil, 322, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 312, nil, nil, 308, nil, nil, 59, 60, + nil, nil, 61, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 94, 84, 87, 88, nil, 89, 91, 90, + 92, nil, nil, nil, nil, 85, 93, nil, nil, nil, + 75, 76, 77, 63, 58, 86, 98, 99, 64, 65, + nil, nil, nil, 68, nil, 66, 67, 69, 318, 319, + 73, 74, nil, nil, nil, nil, nil, 78, 315, 321, + 106, 105, 107, 108, nil, nil, 238, nil, nil, nil, + nil, nil, nil, 46, nil, nil, 110, 109, 111, 100, + 57, 102, 101, 103, nil, 104, 112, 113, nil, 96, + 97, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 231, nil, nil, 237, nil, nil, 59, + 60, nil, nil, 61, nil, 414, nil, nil, nil, 45, + nil, nil, nil, nil, nil, nil, nil, nil, 236, nil, + nil, nil, nil, 94, 84, 87, 88, nil, 89, 91, + 90, 92, nil, nil, nil, nil, 85, 93, nil, nil, + nil, 75, 76, 77, 63, 58, 86, 98, 99, 64, + 65, nil, nil, nil, 68, nil, 66, 67, 69, 318, + 319, 73, 74, nil, nil, nil, nil, nil, 78, 315, + 321, 106, 105, 107, 108, nil, nil, 238, nil, nil, + nil, nil, nil, nil, 46, nil, nil, 110, 109, 111, + 100, 57, 102, 101, 103, nil, 104, 112, 113, nil, + 96, 97, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 231, nil, nil, 237, nil, nil, + 59, 60, nil, nil, 61, nil, nil, nil, nil, nil, + 45, nil, nil, nil, nil, nil, nil, nil, nil, 236, + nil, nil, nil, nil, 94, 84, 87, 88, nil, 89, + 91, 90, 92, nil, nil, nil, nil, 85, 93, nil, + nil, nil, 75, 76, 77, 63, 58, 86, 98, 99, + 64, 65, nil, nil, nil, 68, nil, 66, 67, 69, + 30, 31, 73, 74, nil, nil, nil, nil, nil, 78, + 28, 27, 106, 105, 107, 108, nil, nil, 19, nil, + nil, nil, nil, nil, nil, 46, nil, nil, 110, 109, + 111, 100, 57, 102, 101, 103, nil, 104, 112, 113, + nil, 96, 97, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 231, nil, nil, 237, nil, + nil, 59, 60, nil, nil, 61, nil, nil, nil, nil, + nil, 45, nil, nil, nil, nil, nil, nil, nil, nil, + 20, nil, nil, nil, nil, 94, 84, 87, 88, nil, + 89, 91, 90, 92, nil, nil, nil, nil, 85, 93, + nil, nil, nil, 75, 76, 77, 63, 58, 86, 98, + 99, 64, 65, nil, nil, nil, 68, nil, 66, 67, + 69, 318, 319, 73, 74, nil, nil, nil, nil, nil, + 78, 315, 321, 106, 105, 107, 108, nil, nil, 238, + nil, nil, nil, nil, nil, nil, 46, nil, nil, 110, + 109, 111, 100, 57, 102, 101, 103, nil, 104, 112, + 113, nil, 96, 97, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 231, nil, nil, 237, + nil, nil, 59, 60, nil, nil, 61, nil, nil, nil, + nil, nil, 45, nil, nil, nil, nil, nil, nil, nil, + nil, 236, nil, nil, nil, nil, 94, 84, 87, 88, + nil, 89, 91, 90, 92, nil, nil, nil, nil, 85, + 93, nil, nil, nil, 75, 76, 77, 63, 58, 86, + 98, 99, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 30, 31, 73, 74, nil, nil, nil, nil, + nil, 78, 28, 27, 106, 105, 107, 108, nil, nil, + 238, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 110, 109, 111, 100, 57, 102, 101, 103, nil, 104, + 112, 113, nil, 96, 97, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 231, nil, nil, + 237, nil, nil, 59, 60, nil, nil, 61, nil, nil, + nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, + nil, nil, 236, nil, nil, nil, nil, 94, 84, 87, + 88, nil, 89, 91, 90, 92, nil, nil, nil, nil, + 85, 93, nil, nil, nil, 75, 76, 77, 63, 58, + 86, 98, 99, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 318, 319, 73, 74, nil, nil, nil, + nil, nil, 78, 315, 321, 106, 105, 107, 108, nil, + nil, 238, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, 42, 43, 41, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 231, nil, + nil, 237, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, 45, nil, nil, nil, nil, nil, + nil, nil, nil, 236, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, 75, 76, 77, 63, + 58, 86, 98, 99, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 318, 319, 73, 74, nil, nil, + nil, nil, nil, 78, 315, 321, 106, 105, 107, 108, + nil, nil, 238, nil, nil, nil, nil, nil, nil, 46, + nil, nil, 110, 109, 111, 100, 57, 102, 101, 103, + nil, 104, 112, 113, nil, 96, 97, 42, 43, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 231, + nil, nil, 237, nil, nil, 59, 60, nil, nil, 61, + nil, nil, nil, nil, nil, 45, nil, nil, nil, nil, + nil, nil, nil, nil, 236, nil, nil, nil, nil, 94, + 84, 87, 88, nil, 89, 91, 90, 92, nil, nil, + nil, nil, 85, 93, nil, nil, nil, 75, 76, 77, + 63, 58, 86, 98, 99, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 318, 319, 73, 74, nil, + nil, nil, nil, nil, 78, 315, 321, 106, 105, 107, + 108, nil, nil, 238, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 110, 109, 111, 100, 57, 102, 101, + 103, nil, 104, 112, 113, nil, 96, 97, 42, 43, + 41, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 231, nil, nil, 237, nil, nil, 59, 60, nil, nil, + 61, nil, nil, nil, nil, nil, 45, nil, nil, nil, + nil, nil, nil, nil, nil, 236, nil, nil, nil, nil, + 94, 84, 87, 88, nil, 89, 91, 90, 92, nil, + nil, nil, nil, 85, 93, nil, nil, nil, 75, 76, + 77, 63, 58, 86, 98, 99, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 318, 319, 73, 74, + nil, nil, nil, nil, nil, 78, 315, 321, 106, 105, + 107, 108, nil, nil, 238, nil, nil, nil, nil, nil, + nil, 46, nil, nil, 110, 109, 111, 100, 57, 102, + 101, 103, nil, 104, 112, 113, nil, 96, 97, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 231, nil, nil, 237, nil, nil, 59, 60, nil, + nil, 61, nil, nil, nil, nil, nil, 45, nil, nil, + nil, nil, nil, nil, nil, nil, 236, nil, nil, nil, + nil, 94, 84, 87, 88, nil, 89, 91, 90, 92, + nil, nil, nil, nil, 85, 93, nil, nil, nil, 75, + 76, 77, 63, 58, 86, 98, 99, 64, 65, nil, + nil, nil, 68, nil, 66, 67, 69, 318, 319, 73, + 74, nil, nil, nil, nil, nil, 78, 315, 321, 106, + 105, 107, 108, nil, nil, 238, nil, nil, nil, nil, + nil, nil, 46, nil, nil, 110, 109, 111, 100, 57, + 102, 101, 103, nil, 104, 112, 113, nil, 96, 97, + 42, 43, 41, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 231, nil, nil, 237, nil, nil, 59, 60, + nil, nil, 61, nil, nil, nil, nil, nil, 45, nil, + nil, nil, nil, nil, nil, nil, nil, 236, nil, nil, + nil, nil, 94, 84, 87, 88, nil, 89, 91, 90, + 92, nil, nil, nil, nil, 85, 93, nil, nil, nil, + 75, 76, 77, 63, 58, 86, 98, 99, 64, 65, + nil, nil, nil, 68, nil, 66, 67, 69, 318, 319, + 73, 74, nil, nil, nil, nil, nil, 78, 315, 321, + 106, 105, 107, 108, nil, nil, 238, nil, nil, nil, + nil, nil, nil, 46, nil, nil, 110, 109, 111, 100, + 57, 102, 101, 103, nil, 104, 112, 113, nil, 96, + 97, 42, 43, 41, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 231, nil, nil, 237, nil, nil, 59, + 60, nil, nil, 61, nil, nil, nil, nil, nil, 45, + nil, nil, nil, nil, nil, nil, nil, nil, 236, nil, + nil, nil, nil, 94, 84, 87, 88, nil, 89, 91, + 90, 92, nil, nil, nil, nil, 85, 93, nil, nil, + nil, 75, 76, 77, 63, 58, 86, 98, 99, 64, + 65, nil, nil, nil, 68, nil, 66, 67, 69, 30, + 31, 73, 74, nil, nil, nil, nil, nil, 78, 28, + 27, 106, 105, 107, 108, nil, nil, 19, nil, nil, + nil, nil, nil, nil, 46, nil, nil, 110, 109, 111, + 100, 57, 102, 101, 103, nil, 104, 112, 113, nil, + 96, 97, 42, 43, 41, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 231, nil, nil, 237, nil, nil, + 59, 60, nil, nil, 61, nil, nil, nil, nil, nil, + 45, nil, nil, nil, nil, nil, nil, nil, nil, 20, + nil, nil, nil, nil, 94, 84, 87, 88, nil, 89, + 91, 90, 92, nil, nil, nil, nil, 85, 93, nil, + nil, nil, 75, 76, 77, 63, 58, 86, 98, 99, + 64, 65, nil, nil, nil, 68, nil, 66, 67, 69, + 318, 319, 73, 74, nil, nil, nil, nil, nil, 78, + 315, 321, 106, 105, 107, 108, nil, nil, 238, nil, + nil, nil, nil, nil, nil, 46, nil, nil, 110, 109, + 111, 100, 57, 102, 101, 103, nil, 104, 112, 113, + nil, 96, 97, 42, 43, 41, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 231, nil, nil, 237, nil, + nil, 59, 60, nil, nil, 61, nil, 641, nil, nil, + nil, 45, nil, nil, nil, nil, nil, nil, nil, nil, + 236, nil, nil, nil, nil, 94, 84, 87, 88, nil, + 89, 91, 90, 92, nil, nil, nil, nil, 85, 93, + nil, nil, nil, 75, 76, 77, 63, 58, 86, 98, + 99, 64, 65, nil, nil, nil, 68, nil, 66, 67, + 69, 318, 319, 73, 74, nil, nil, nil, nil, nil, + 78, 315, 321, 106, 105, 107, 108, nil, nil, 238, + nil, nil, nil, nil, nil, nil, 46, nil, nil, 110, + 109, 111, 100, 57, 102, 101, 103, 293, 104, 112, + 113, nil, 96, 97, 42, 43, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 231, nil, nil, 237, + nil, nil, 59, 60, nil, nil, 61, nil, nil, nil, + 288, nil, 45, nil, nil, 294, nil, nil, nil, nil, + nil, 236, nil, nil, nil, nil, 94, 291, 87, 88, + nil, 89, 91, 90, 92, nil, nil, nil, nil, 85, + 93, nil, nil, nil, 75, 76, 77, 63, 58, 86, + 98, 99, 64, 65, nil, nil, nil, 68, nil, 66, + 67, 69, 318, 319, 73, 74, nil, nil, nil, nil, + nil, 78, 315, 321, 106, 105, 107, 108, nil, nil, + 238, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 110, 109, 111, 100, 57, 102, 101, 103, nil, 104, + 112, 113, nil, 96, 97, 42, 43, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 231, nil, nil, + 237, nil, nil, 59, 60, nil, nil, 61, nil, nil, + nil, nil, nil, 45, nil, nil, nil, nil, nil, nil, + nil, nil, 236, nil, nil, nil, nil, 94, 84, 87, + 88, nil, 89, 91, 90, 92, nil, nil, nil, nil, + 85, 93, nil, nil, nil, 75, 76, 77, 63, 58, + 86, 98, 99, 64, 65, nil, nil, nil, 68, nil, + 66, 67, 69, 318, 319, 73, 74, nil, nil, nil, + nil, nil, 78, 315, 321, 106, 105, 107, 108, nil, + nil, 238, nil, nil, nil, nil, nil, nil, 316, nil, + nil, 110, 109, 111, 100, 57, 102, 101, 103, nil, + 104, 112, 113, nil, 96, 97, nil, nil, 322, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 922, nil, + nil, 237, nil, nil, 59, 60, nil, nil, 61, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 94, 84, + 87, 88, nil, 89, 91, 90, 92, nil, nil, nil, + nil, 85, 93, nil, nil, nil, 75, 76, 77, 63, + 58, 86, 98, 99, 64, 65, nil, nil, nil, 68, + nil, 66, 67, 69, 318, 319, 73, 74, nil, nil, + nil, nil, nil, 78, 315, 321, 106, 105, 107, 108, + nil, nil, 238, nil, nil, nil, nil, nil, nil, 316, + nil, nil, 110, 109, 111, 100, 57, 102, 101, 103, + nil, 104, 112, 113, nil, 96, 97, nil, nil, 322, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 928, + nil, nil, 237, nil, nil, 59, 60, nil, nil, 61, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 94, + 84, 87, 88, nil, 89, 91, 90, 92, nil, nil, + nil, nil, 85, 93, nil, nil, nil, 75, 76, 77, + 63, 58, 86, 98, 99, 64, 65, nil, nil, nil, + 68, nil, 66, 67, 69, 318, 319, 73, 74, nil, + nil, nil, nil, nil, 78, 315, 321, 106, 105, 107, + 108, nil, nil, 238, nil, nil, nil, nil, nil, nil, + 316, nil, nil, 110, 109, 111, 100, 57, 102, 101, + 103, nil, 104, 112, 113, nil, 96, 97, nil, nil, + 322, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 922, nil, nil, 237, nil, nil, 59, 60, nil, nil, + 61, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 94, 84, 87, 88, nil, 89, 91, 90, 92, nil, + nil, nil, nil, 85, 93, nil, nil, nil, 75, 76, + 77, 63, 58, 86, 98, 99, 64, 65, nil, nil, + nil, 68, nil, 66, 67, 69, 30, 31, 73, 74, + nil, nil, nil, nil, nil, 78, 28, 27, 106, 105, + 107, 108, nil, nil, 238, nil, nil, nil, nil, nil, + nil, 46, nil, nil, 110, 109, 111, 100, 57, 102, + 101, 103, 293, 104, 112, 113, nil, 96, 97, 42, + 43, 41, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 231, nil, nil, 237, nil, nil, 59, 60, nil, + nil, 61, nil, 290, nil, 288, nil, 45, nil, nil, + 294, nil, nil, nil, nil, nil, 236, nil, nil, nil, + nil, 94, 291, 87, 88, nil, 89, 91, 90, 92, + nil, nil, nil, nil, 85, 93, nil, nil, nil, nil, + nil, nil, 63, nil, 86, 98, 99, 179, 190, 180, + 203, 176, 196, 186, 185, 206, 207, 201, 184, 183, + 178, 204, 208, 209, 188, 177, 191, 195, 197, 189, + 182, nil, nil, nil, 198, 205, 200, 199, 192, 202, + 187, 175, 194, 193, nil, nil, nil, nil, nil, 174, + 181, 172, 173, 169, 170, 171, 130, 132, 129, nil, + 131, nil, nil, nil, nil, nil, nil, nil, 163, 164, + nil, 160, 142, 143, 144, 151, 148, 150, nil, nil, + 145, 146, nil, nil, nil, 165, 166, 152, 153, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 157, 156, nil, 141, 162, 159, 158, 167, + 154, 155, 149, 147, 139, 161, 140, nil, nil, 168, + 94, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 93, 179, 190, 180, 203, 176, + 196, 186, 185, 206, 207, 201, 184, 183, 178, 204, + 208, 209, 188, 177, 191, 195, 197, 189, 182, nil, + nil, nil, 198, 205, 200, 199, 192, 202, 187, 175, + 194, 193, nil, nil, nil, nil, nil, 174, 181, 172, + 173, 169, 170, 171, 130, 132, nil, nil, 131, nil, + nil, nil, nil, nil, nil, nil, 163, 164, nil, 160, + 142, 143, 144, 151, 148, 150, nil, nil, 145, 146, + nil, nil, nil, 165, 166, 152, 153, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 157, 156, nil, 141, 162, 159, 158, 167, 154, 155, + 149, 147, 139, 161, 140, nil, nil, 168, 94, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 93, 179, 190, 180, 203, 176, 196, 186, + 185, 206, 207, 201, 184, 183, 178, 204, 208, 209, + 188, 177, 191, 195, 197, 189, 182, nil, nil, nil, + 198, 205, 200, 199, 192, 202, 187, 175, 194, 193, + nil, nil, nil, nil, nil, 174, 181, 172, 173, 169, + 170, 171, 130, 132, nil, nil, 131, nil, nil, nil, + nil, nil, nil, nil, 163, 164, nil, 160, 142, 143, + 144, 151, 148, 150, nil, nil, 145, 146, nil, nil, + nil, 165, 166, 152, 153, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 157, 156, + nil, 141, 162, 159, 158, 167, 154, 155, 149, 147, + 139, 161, 140, nil, nil, 168, 94, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 93, 179, 190, 180, 203, 176, 196, 186, 185, 206, + 207, 201, 184, 183, 178, 204, 208, 209, 188, 177, + 191, 195, 197, 189, 182, nil, nil, nil, 198, 205, + 200, 199, 192, 202, 187, 175, 194, 193, nil, nil, + nil, nil, nil, 174, 181, 172, 173, 169, 170, 171, + 130, 132, nil, nil, 131, nil, nil, nil, nil, nil, + nil, nil, 163, 164, nil, 160, 142, 143, 144, 151, + 148, 150, nil, nil, 145, 146, nil, nil, nil, 165, + 166, 152, 153, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 157, 156, nil, 141, + 162, 159, 158, 167, 154, 155, 149, 147, 139, 161, + 140, nil, nil, 168, 94, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 93, 179, + 190, 180, 203, 176, 196, 186, 185, 206, 207, 201, + 184, 183, 178, 204, 208, 209, 188, 177, 191, 195, + 197, 189, 182, nil, nil, nil, 198, 205, 200, 381, + 380, 382, 379, 175, 194, 193, nil, nil, nil, nil, + nil, 174, 181, 172, 173, 376, 377, 378, 374, 132, + 102, 101, 375, nil, 104, nil, nil, nil, nil, nil, + 163, 164, nil, 160, 142, 143, 144, 151, 148, 150, + nil, nil, 145, 146, nil, nil, nil, 165, 166, 152, + 153, nil, nil, nil, nil, nil, 386, nil, nil, nil, + nil, nil, nil, nil, 157, 156, nil, 141, 162, 159, + 158, 167, 154, 155, 149, 147, 139, 161, 140, nil, + nil, 168, 179, 190, 180, 203, 176, 196, 186, 185, + 206, 207, 201, 184, 183, 178, 204, 208, 209, 188, + 177, 191, 195, 197, 189, 182, nil, nil, nil, 198, + 205, 200, 199, 192, 202, 187, 175, 194, 193, nil, + nil, nil, nil, nil, 174, 181, 172, 173, 169, 170, + 171, 130, 132, nil, nil, 131, nil, nil, nil, nil, + nil, nil, nil, 163, 164, nil, 160, 142, 143, 144, + 151, 148, 150, nil, nil, 145, 146, nil, nil, nil, + 165, 166, 152, 153, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 157, 156, nil, + 141, 162, 159, 158, 167, 154, 155, 149, 147, 139, + 161, 140, 436, 440, 168, nil, 437, nil, nil, nil, + nil, nil, nil, nil, 163, 164, nil, 160, 142, 143, + 144, 151, 148, 150, nil, nil, 145, 146, nil, nil, + nil, 165, 166, 152, 153, nil, nil, nil, nil, nil, + 272, nil, nil, nil, nil, nil, nil, nil, 157, 156, + nil, 141, 162, 159, 158, 167, 154, 155, 149, 147, + 139, 161, 140, 443, 447, 168, nil, 442, nil, nil, + nil, nil, nil, nil, nil, 163, 164, nil, 160, 142, + 143, 144, 151, 148, 150, nil, nil, 145, 146, nil, + nil, nil, 165, 166, 152, 153, nil, nil, nil, nil, + nil, 272, nil, nil, nil, nil, nil, nil, nil, 157, + 156, nil, 141, 162, 159, 158, 167, 154, 155, 149, + 147, 139, 161, 140, 487, 440, 168, nil, 488, nil, + nil, nil, nil, nil, nil, nil, 163, 164, nil, 160, + 142, 143, 144, 151, 148, 150, nil, nil, 145, 146, + nil, nil, nil, 165, 166, 152, 153, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 157, 156, nil, 141, 162, 159, 158, 167, 154, 155, + 149, 147, 139, 161, 140, 622, 440, 168, nil, 623, + nil, nil, nil, nil, nil, nil, nil, 163, 164, nil, + 160, 142, 143, 144, 151, 148, 150, nil, nil, 145, + 146, nil, nil, nil, 165, 166, 152, 153, nil, nil, + nil, nil, nil, 272, nil, nil, nil, nil, nil, nil, + nil, 157, 156, nil, 141, 162, 159, 158, 167, 154, + 155, 149, 147, 139, 161, 140, 624, 447, 168, nil, + 625, nil, nil, nil, nil, nil, nil, nil, 163, 164, + nil, 160, 142, 143, 144, 151, 148, 150, nil, nil, + 145, 146, nil, nil, nil, 165, 166, 152, 153, nil, + nil, nil, nil, nil, 272, nil, nil, nil, nil, nil, + nil, nil, 157, 156, nil, 141, 162, 159, 158, 167, + 154, 155, 149, 147, 139, 161, 140, 651, 440, 168, + nil, 652, nil, nil, nil, nil, nil, nil, nil, 163, + 164, nil, 160, 142, 143, 144, 151, 148, 150, nil, + nil, 145, 146, nil, nil, nil, 165, 166, 152, 153, + nil, nil, nil, nil, nil, 272, nil, nil, nil, nil, + nil, nil, nil, 157, 156, nil, 141, 162, 159, 158, + 167, 154, 155, 149, 147, 139, 161, 140, 654, 447, + 168, nil, 655, nil, nil, nil, nil, nil, nil, nil, + 163, 164, nil, 160, 142, 143, 144, 151, 148, 150, + nil, nil, 145, 146, nil, nil, nil, 165, 166, 152, + 153, nil, nil, nil, nil, nil, 272, nil, nil, nil, + nil, nil, nil, nil, 157, 156, nil, 141, 162, 159, + 158, 167, 154, 155, 149, 147, 139, 161, 140, 622, + 440, 168, nil, 623, nil, nil, nil, nil, nil, nil, + nil, 163, 164, nil, 160, 142, 143, 144, 151, 148, + 150, nil, nil, 145, 146, nil, nil, nil, 165, 166, + 152, 153, nil, nil, nil, nil, nil, 272, nil, nil, + nil, nil, nil, nil, nil, 157, 156, nil, 141, 162, + 159, 158, 167, 154, 155, 149, 147, 139, 161, 140, + 624, 447, 168, nil, 625, nil, nil, nil, nil, nil, + nil, nil, 163, 164, nil, 160, 142, 143, 144, 151, + 148, 150, nil, nil, 145, 146, nil, nil, nil, 165, + 166, 152, 153, nil, nil, nil, nil, nil, 272, nil, + nil, nil, nil, nil, nil, nil, 157, 156, nil, 141, + 162, 159, 158, 167, 154, 155, 149, 147, 139, 161, + 140, 713, 440, 168, nil, 714, nil, nil, nil, nil, + nil, nil, nil, 163, 164, nil, 160, 142, 143, 144, + 151, 148, 150, nil, nil, 145, 146, nil, nil, nil, + 165, 166, 152, 153, nil, nil, nil, nil, nil, 272, + nil, nil, nil, nil, nil, nil, nil, 157, 156, nil, + 141, 162, 159, 158, 167, 154, 155, 149, 147, 139, + 161, 140, 715, 447, 168, nil, 716, nil, nil, nil, + nil, nil, nil, nil, 163, 164, nil, 160, 142, 143, + 144, 151, 148, 150, nil, nil, 145, 146, nil, nil, + nil, 165, 166, 152, 153, nil, nil, nil, nil, nil, + 272, nil, nil, nil, nil, nil, nil, nil, 157, 156, + nil, 141, 162, 159, 158, 167, 154, 155, 149, 147, + 139, 161, 140, 718, 447, 168, nil, 719, nil, nil, + nil, nil, nil, nil, nil, 163, 164, nil, 160, 142, + 143, 144, 151, 148, 150, nil, nil, 145, 146, nil, + nil, nil, 165, 166, 152, 153, nil, nil, nil, nil, + nil, 272, nil, nil, nil, nil, nil, nil, nil, 157, + 156, nil, 141, 162, 159, 158, 167, 154, 155, 149, + 147, 139, 161, 140, 487, 440, 168, nil, 488, nil, + nil, nil, nil, nil, nil, nil, 163, 164, nil, 160, + 142, 143, 144, 151, 148, 150, nil, nil, 145, 146, + nil, nil, nil, 165, 166, 152, 153, nil, nil, nil, + nil, nil, 272, nil, nil, nil, nil, nil, nil, nil, + 157, 156, nil, 141, 162, 159, 158, 167, 154, 155, + 149, 147, 139, 161, 140, 747, 440, 168, nil, 748, + nil, nil, nil, nil, nil, nil, nil, 163, 164, nil, + 160, 142, 143, 144, 151, 148, 150, nil, nil, 145, + 146, nil, nil, nil, 165, 166, 152, 153, nil, nil, + nil, nil, nil, 272, nil, nil, nil, nil, nil, nil, + nil, 157, 156, nil, 141, 162, 159, 158, 167, 154, + 155, 149, 147, 139, 161, 140, 750, 447, 168, nil, + 749, nil, nil, nil, nil, nil, nil, nil, 163, 164, + nil, 160, 142, 143, 144, 151, 148, 150, nil, nil, + 145, 146, nil, nil, nil, 165, 166, 152, 153, nil, + nil, nil, nil, nil, 272, nil, nil, nil, nil, nil, + nil, nil, 157, 156, nil, 141, 162, 159, 158, 167, + 154, 155, 149, 147, 139, 161, 140, 1002, 447, 168, + nil, 1001, nil, nil, nil, nil, nil, nil, nil, 163, + 164, nil, 160, 142, 143, 144, 151, 148, 150, nil, + nil, 145, 146, nil, nil, nil, 165, 166, 152, 153, + nil, nil, nil, nil, nil, 272, nil, nil, nil, nil, + nil, nil, nil, 157, 156, nil, 141, 162, 159, 158, + 167, 154, 155, 149, 147, 139, 161, 140, 1005, 440, + 168, nil, 1006, nil, nil, nil, nil, nil, nil, nil, + 163, 164, nil, 160, 142, 143, 144, 151, 148, 150, + nil, nil, 145, 146, nil, nil, nil, 165, 166, 152, + 153, nil, nil, nil, nil, nil, 272, nil, nil, nil, + nil, nil, nil, nil, 157, 156, nil, 141, 162, 159, + 158, 167, 154, 155, 149, 147, 139, 161, 140, 1007, + 447, 168, nil, 1008, nil, nil, nil, nil, nil, nil, + nil, 163, 164, nil, 160, 142, 143, 144, 151, 148, + 150, nil, nil, 145, 146, nil, nil, nil, 165, 166, + 152, 153, nil, nil, nil, nil, nil, 272, nil, nil, + nil, nil, nil, nil, nil, 157, 156, nil, 141, 162, + 159, 158, 167, 154, 155, 149, 147, 139, 161, 140, + nil, 683, 168, 680, 679, 678, 688, 681, nil, 683, + nil, 680, 679, 678, 688, 681, 691, nil, nil, nil, + nil, nil, nil, nil, 691, nil, 683, nil, 680, 679, + 678, 688, 681, nil, nil, nil, nil, nil, 686, 669, + nil, 691, nil, nil, nil, nil, 686, 696, 695, 699, + 698, nil, nil, nil, 692, 696, 695, 699, 698, nil, + nil, nil, 692, 686, nil, 683, nil, 680, 679, 678, + 688, 681, 696, 695, 699, 698, nil, nil, nil, 692, + 691, nil, 683, nil, 680, 679, 678, 688, 681, nil, + 683, nil, 680, 679, 678, 688, 681, 691, nil, nil, + nil, nil, 686, nil, nil, 691, nil, nil, nil, nil, + nil, 696, 695, 699, 698, nil, nil, nil, 692, 686, + nil, nil, nil, nil, nil, nil, nil, 686, 696, 695, + 699, 698, nil, nil, nil, 692, 696, 695, 699, 698, + nil, nil, 683, 692, 680, 679, 678, 688, 681, nil, + 683, nil, 680, 679, 678, 688, 681, 691, nil, nil, + nil, nil, nil, nil, nil, 691, nil, 683, nil, 680, + 679, 678, 688, 681, nil, nil, nil, nil, nil, 686, + nil, nil, 691, nil, nil, nil, nil, 686, 696, 695, + 699, 698, nil, nil, nil, 692, 696, 695, 699, 698, + nil, nil, nil, 692, 686, nil, 683, nil, 680, 679, + 678, 688, 681, 696, 695, 699, 698, nil, nil, nil, + 692, 691, nil, 683, nil, 680, 679, 678, 688, 681, + 683, nil, 680, 679, 678, 688, 681, nil, 691, nil, + nil, nil, nil, 686, nil, 691, nil, 683, nil, 680, + 679, 678, 688, 681, 699, 698, nil, nil, nil, 692, + 686, nil, 691, nil, nil, nil, nil, 686, nil, 696, + 695, 699, 698, nil, nil, nil, 692, nil, 699, 698, + nil, nil, nil, 692, 686, nil, 683, nil, 680, 679, + 678, 688, 681, nil, nil, 699, 698, nil, nil, nil, + 692, 691, nil, 683, nil, 680, 679, 678, 688, 681, + 683, nil, 680, 679, 678, 688, 681, nil, 691, nil, + nil, nil, nil, 686, nil, 691, nil, nil, nil, nil, + nil, nil, nil, nil, 699, 698, nil, nil, nil, 692, + 686, nil, nil, nil, nil, nil, nil, 686, nil, nil, + nil, 699, 698, nil, nil, nil, 692, nil, 699, 698, + nil, nil, nil, 692 ] + +racc_action_check = [ + 100, 452, 452, 575, 575, 17, 355, 100, 100, 100, + 1, 347, 100, 100, 100, 24, 100, 26, 19, 393, + 44, 44, 24, 348, 100, 394, 100, 100, 100, 62, + 365, 631, 229, 7, 365, 356, 100, 100, 711, 100, + 100, 100, 100, 100, 868, 894, 925, 926, 929, 359, + 646, 561, 17, 897, 976, 897, 44, 44, 317, 19, + 646, 10, 17, 12, 713, 714, 100, 100, 100, 100, + 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, + 24, 26, 100, 100, 100, 393, 100, 100, 552, 229, + 100, 394, 798, 100, 100, 452, 100, 575, 100, 13, + 100, 15, 100, 100, 26, 100, 100, 100, 100, 100, + 1005, 100, 103, 100, 1006, 355, 62, 828, 631, 103, + 103, 103, 317, 1007, 103, 103, 103, 100, 103, 347, + 100, 100, 100, 100, 347, 100, 103, 100, 103, 103, + 103, 348, 100, 100, 356, 317, 348, 651, 103, 103, + 1008, 103, 103, 103, 103, 103, 711, 1025, 359, 711, + 561, 711, 868, 894, 925, 926, 929, 868, 894, 925, + 926, 929, 976, 713, 714, 715, 635, 976, 103, 103, + 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, + 103, 103, 552, 22, 103, 103, 103, 552, 103, 103, + 1007, 798, 103, 37, 652, 103, 103, 40, 103, 716, + 103, 635, 103, 651, 103, 103, 46, 103, 103, 103, + 103, 103, 442, 103, 114, 103, 828, 1008, 1005, 442, + 442, 442, 1006, 1005, 773, 442, 442, 1006, 442, 103, + 715, 1007, 103, 103, 103, 103, 1007, 103, 210, 103, + 661, 661, 230, 651, 103, 103, 651, 231, 442, 442, + 787, 442, 442, 442, 442, 442, 651, 233, 1008, 773, + 652, 374, 654, 1008, 716, 1025, 14, 14, 374, 815, + 1025, 815, 815, 815, 715, 815, 571, 571, 442, 442, + 442, 442, 442, 442, 442, 442, 442, 442, 442, 442, + 442, 442, 234, 232, 442, 442, 442, 375, 442, 230, + 652, 38, 442, 652, 375, 442, 41, 41, 716, 586, + 442, 238, 442, 652, 442, 442, 787, 442, 442, 442, + 442, 442, 376, 442, 443, 442, 374, 654, 654, 376, + 129, 443, 443, 443, 661, 129, 129, 443, 443, 442, + 443, 3, 442, 442, 271, 442, 3, 442, 38, 443, + 232, 815, 346, 346, 442, 442, 787, 363, 38, 787, + 443, 443, 375, 443, 443, 443, 443, 443, 654, 787, + 571, 654, 285, 586, 586, 571, 946, 388, 946, 946, + 946, 654, 946, 586, 41, 41, 286, 376, 588, 421, + 443, 443, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 458, 289, 443, 443, 443, 363, + 443, 322, 322, 504, 443, 297, 363, 443, 352, 622, + 297, 363, 443, 352, 443, 363, 443, 443, 39, 443, + 443, 443, 443, 443, 623, 443, 443, 443, 389, 301, + 377, 388, 388, 388, 363, 390, 421, 377, 302, 364, + 391, 443, 588, 588, 443, 443, 624, 443, 946, 443, + 304, 458, 588, 624, 624, 624, 443, 443, 624, 624, + 624, 305, 624, 306, 363, 39, 622, 504, 504, 504, + 378, 624, 624, 624, 624, 39, 312, 378, 315, 322, + 322, 623, 624, 624, 504, 624, 624, 624, 624, 624, + 326, 364, 389, 389, 389, 377, 392, 316, 364, 390, + 390, 390, 395, 364, 391, 391, 391, 364, 338, 701, + 701, 338, 624, 624, 624, 624, 624, 624, 624, 624, + 624, 624, 624, 624, 624, 624, 364, 321, 624, 624, + 624, 323, 624, 624, 16, 378, 624, 326, 379, 624, + 624, 16, 624, 327, 624, 379, 624, 326, 624, 624, + 16, 624, 624, 624, 624, 624, 364, 624, 624, 624, + 392, 392, 392, 380, 47, 381, 395, 395, 395, 464, + 380, 47, 381, 624, 330, 436, 624, 624, 624, 624, + 47, 624, 747, 624, 625, 748, 770, 437, 624, 624, + 832, 625, 625, 625, 336, 832, 625, 625, 625, 16, + 625, 464, 340, 379, 341, 464, 464, 382, 384, 465, + 625, 625, 625, 339, 382, 384, 339, 343, 607, 841, + 625, 625, 436, 625, 625, 625, 625, 625, 380, 47, + 381, 228, 436, 309, 437, 803, 803, 353, 228, 747, + 309, 465, 748, 770, 437, 465, 465, 228, 354, 309, + 625, 625, 625, 625, 625, 625, 625, 625, 625, 625, + 625, 625, 625, 625, 837, 607, 625, 625, 625, 837, + 625, 625, 382, 384, 625, 607, 841, 625, 625, 358, + 625, 360, 625, 369, 625, 342, 625, 625, 342, 625, + 625, 625, 625, 625, 749, 625, 228, 625, 309, 987, + 987, 749, 749, 749, 404, 410, 667, 749, 749, 667, + 749, 625, 472, 413, 625, 625, 625, 625, 415, 625, + 82, 625, 718, 418, 422, 432, 625, 625, 472, 472, + 749, 749, 82, 749, 749, 749, 749, 749, 965, 310, + 434, 965, 82, 311, 472, 435, 310, 444, 472, 472, + 311, 472, 472, 454, 466, 310, 467, 468, 469, 311, + 749, 749, 749, 749, 749, 749, 749, 749, 749, 749, + 749, 749, 749, 749, 718, 313, 749, 749, 749, 491, + 749, 718, 313, 495, 749, 511, 718, 749, 512, 515, + 718, 313, 749, 517, 749, 522, 749, 749, 525, 749, + 749, 749, 749, 749, 310, 749, 750, 749, 311, 718, + 534, 535, 536, 750, 750, 750, 800, 537, 549, 750, + 750, 749, 750, 553, 749, 749, 800, 749, 328, 749, + 554, 750, 555, 556, 573, 328, 749, 749, 583, 718, + 313, 591, 750, 750, 328, 750, 750, 750, 750, 750, + 891, 357, 891, 891, 891, 593, 891, 599, 357, 800, + 800, 608, 613, 618, 800, 579, 579, 357, 626, 579, + 579, 579, 750, 750, 750, 750, 750, 750, 750, 750, + 750, 750, 750, 750, 750, 750, 627, 891, 750, 750, + 750, 367, 750, 328, 420, 628, 750, 630, 367, 750, + 634, 420, 636, 638, 750, 640, 750, 367, 750, 750, + 420, 750, 750, 750, 750, 750, 357, 750, 750, 750, + 779, 648, 779, 779, 779, 779, 779, 521, 6, 6, + 6, 6, 6, 750, 521, 779, 750, 750, 27, 750, + 650, 750, 653, 521, 656, 27, 27, 27, 750, 750, + 27, 27, 27, 657, 27, 660, 367, 779, 662, 420, + 671, 479, 672, 27, 27, 27, 779, 779, 779, 779, + 674, 675, 676, 779, 27, 27, 685, 27, 27, 27, + 27, 27, 947, 693, 947, 947, 947, 564, 947, 697, + 700, 703, 521, 479, 564, 709, 712, 479, 479, 779, + 479, 479, 721, 564, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 725, 947, + 27, 27, 27, 744, 746, 27, 755, 27, 27, 776, + 786, 27, 27, 790, 27, 793, 27, 794, 27, 799, + 27, 27, 814, 27, 27, 27, 27, 27, 28, 27, + 27, 27, 564, 816, 821, 28, 28, 28, 824, 829, + 28, 28, 28, 921, 28, 27, 831, 835, 27, 27, + 921, 27, 836, 27, 28, 28, 839, 840, 849, 921, + 27, 850, 852, 853, 28, 28, 854, 28, 28, 28, + 28, 28, 856, 857, 858, 655, 859, 719, 874, 875, + 879, 880, 655, 882, 719, 883, 885, 655, 888, 719, + 890, 655, 901, 719, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 921, 905, + 28, 28, 28, 918, 922, 28, 928, 28, 28, 948, + 955, 28, 28, 958, 28, 959, 28, 960, 28, 961, + 28, 28, 963, 28, 28, 28, 28, 28, 57, 28, + 655, 28, 719, 972, 977, 57, 57, 57, 978, 979, + 57, 57, 57, 927, 57, 28, 980, 981, 28, 28, + 927, 28, 982, 28, 57, 57, 57, 983, 985, 927, + 28, 988, 1001, 1002, 57, 57, 1004, 57, 57, 57, + 57, 57, 919, 969, 919, 919, 919, 1017, 919, 686, + 969, 686, 686, 686, 1000, 686, 1000, 1000, 1000, 969, + 1000, 1020, 1021, 1022, 57, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 57, 57, 57, 57, 927, 908, + 57, 57, 57, 1023, 1026, 57, 686, 1027, 57, 908, + 1034, 57, 57, nil, 57, 686, 57, nil, 57, nil, + 57, 57, nil, 57, 57, 57, 57, 57, 969, 57, + nil, 57, 812, nil, 812, 812, 812, nil, 812, nil, + nil, nil, 908, 908, nil, 57, nil, 908, 57, 57, + 57, 57, nil, 57, 438, 57, nil, nil, nil, nil, + 57, 438, 438, 438, nil, nil, 438, 438, 438, 812, + 438, 889, nil, 889, 889, 889, nil, 889, 812, 438, + 438, 438, 984, nil, 984, 984, 984, nil, 984, nil, + 438, 438, nil, 438, 438, 438, 438, 438, 986, nil, + 986, 986, 986, 1016, 986, 1016, 1016, 1016, 889, 1016, + 300, 300, 300, 300, 300, nil, nil, 889, nil, 984, + 438, 438, 438, 438, 438, 438, 438, 438, 438, 438, + 438, 438, 438, 438, nil, 986, 438, 438, 438, nil, + 1016, 438, nil, 438, 438, nil, nil, 438, 438, nil, + 438, nil, 438, nil, 438, nil, 438, 438, nil, 438, + 438, 438, 438, 438, nil, 438, 438, 438, 808, nil, + 808, 808, 808, 808, 808, 335, 335, 335, 335, 335, + nil, 438, nil, 808, 438, 438, 447, 438, nil, 438, + nil, nil, nil, 447, 447, 447, 438, nil, 447, 447, + 447, nil, 447, 484, nil, 808, 509, 509, 509, 509, + 509, 447, 447, 447, 447, nil, 808, 808, nil, 484, + 484, 808, 447, 447, nil, 447, 447, 447, 447, 447, + nil, nil, nil, nil, nil, 484, nil, 484, nil, 484, + 484, nil, 484, 484, nil, nil, 484, nil, 484, nil, + nil, nil, 447, 447, 447, 447, 447, 447, 447, 447, + 447, 447, 447, 447, 447, 447, nil, nil, 447, 447, + 447, 480, nil, 447, nil, nil, 447, nil, nil, 447, + 447, nil, 447, nil, 447, nil, 447, nil, 447, 447, + nil, 447, 447, 447, 447, 447, nil, 447, 447, 447, + nil, nil, nil, 480, nil, nil, nil, 480, 480, nil, + 480, 480, nil, 447, nil, nil, 447, 447, 447, 447, + nil, 447, 448, 447, nil, nil, nil, nil, 447, 448, + 448, 448, nil, nil, 448, 448, 448, 531, 448, nil, + nil, nil, nil, nil, nil, nil, nil, 448, 448, 448, + 448, nil, nil, 531, 531, nil, nil, nil, 448, 448, + nil, 448, 448, 448, 448, 448, nil, nil, nil, 531, + nil, 531, nil, 531, 531, nil, 531, 531, nil, nil, + 531, nil, 531, nil, nil, nil, nil, nil, 448, 448, + 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, + 448, 448, nil, nil, 448, 448, 448, nil, nil, 448, + nil, nil, 448, nil, nil, 448, 448, nil, 448, nil, + 448, nil, 448, nil, 448, 448, nil, 448, 448, 448, + 448, 448, nil, 448, 448, 448, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 448, + nil, nil, 448, 448, 448, 448, nil, 448, 486, 448, + nil, nil, nil, nil, 448, 486, 486, 486, nil, nil, + 486, 486, 486, 470, 486, nil, nil, nil, nil, nil, + nil, nil, nil, 486, 486, nil, nil, nil, nil, 470, + 470, nil, nil, nil, 486, 486, nil, 486, 486, 486, + 486, 486, nil, nil, nil, 470, nil, 470, nil, 470, + 470, nil, 470, 470, nil, nil, nil, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, nil, 21, + 21, nil, nil, 21, 21, 486, nil, nil, nil, nil, + nil, nil, 486, nil, nil, nil, nil, 486, 486, 21, + nil, 21, nil, 21, 21, nil, 21, 21, 21, 21, + 21, nil, 21, nil, nil, nil, nil, nil, nil, nil, + 486, 486, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 21, nil, nil, 486, nil, nil, 486, nil, + nil, nil, nil, 486, 0, 0, 0, 0, 0, 0, + 486, nil, nil, 0, 0, nil, nil, nil, 0, nil, + 0, 0, 0, 0, 0, 0, 0, nil, nil, nil, + nil, nil, 0, 0, 0, 0, 0, 0, 0, nil, + nil, 0, nil, nil, nil, nil, 425, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, nil, + 0, 0, 0, nil, 0, 0, 0, 0, 0, 425, + 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, + nil, 425, 425, nil, nil, 425, 425, nil, 0, nil, + nil, 0, nil, nil, 0, 0, nil, nil, 0, nil, + 0, 425, nil, 425, 0, 425, 425, nil, 425, 425, + 425, 425, 425, 0, 425, nil, nil, nil, 0, 0, + 0, 0, nil, 0, 0, 0, 0, nil, nil, nil, + nil, 0, 0, nil, 425, nil, 425, nil, nil, 0, + nil, 0, 0, 0, 33, 33, 33, 33, 33, 33, + nil, nil, nil, 33, 33, nil, nil, nil, 33, nil, + 33, 33, 33, 33, 33, 33, 33, nil, nil, nil, + nil, nil, 33, 33, 33, 33, 33, 33, 33, nil, + nil, 33, nil, nil, nil, nil, 431, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, nil, + 33, 33, 33, nil, 33, 33, 33, 33, 33, 431, + 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, + nil, 431, 431, nil, nil, 431, 431, nil, 33, nil, + nil, 33, nil, nil, 33, 33, nil, nil, 33, nil, + 33, 431, nil, 431, 33, 431, 431, nil, 431, 431, + 431, 431, 431, 33, 431, nil, nil, nil, 33, 33, + 33, 33, nil, 33, 33, 33, 33, nil, nil, nil, + nil, 33, 33, nil, 431, nil, nil, nil, nil, 33, + nil, 33, 33, 33, 127, 127, 127, 127, 127, 127, + nil, nil, nil, 127, 127, nil, nil, nil, 127, nil, + 127, 127, 127, 127, 127, 127, 127, nil, nil, nil, + nil, nil, 127, 127, 127, 127, 127, 127, 127, nil, + nil, 127, nil, nil, nil, nil, nil, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, nil, + 127, 127, 127, nil, 127, 127, 127, 127, 127, 283, + 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, + nil, 283, 283, nil, nil, 283, 283, nil, 127, nil, + nil, 127, nil, nil, 127, 127, nil, nil, 127, nil, + 127, 283, nil, 283, 127, 283, 283, nil, 283, 283, + 283, 283, 283, 127, 283, nil, nil, nil, 127, 127, + 127, 127, nil, 127, 127, 127, 127, nil, nil, nil, + nil, 127, 127, nil, 283, nil, nil, nil, nil, 127, + nil, 127, 127, 127, 212, 212, 212, 212, 212, 212, + nil, nil, nil, 212, 212, nil, nil, nil, 212, nil, + 212, 212, 212, 212, 212, 212, 212, nil, nil, nil, + nil, nil, 212, 212, 212, 212, 212, 212, 212, nil, + nil, 212, nil, nil, nil, nil, nil, 212, 212, 212, + 212, 212, 212, 212, 212, 212, 212, 212, 212, nil, + 212, 212, 212, nil, 212, 212, 212, 212, 212, 483, + 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, + nil, 483, 483, nil, nil, 483, 483, nil, 212, nil, + nil, 212, nil, nil, 212, 212, nil, nil, 212, nil, + 212, 483, nil, 483, 212, 483, 483, nil, 483, 483, + 483, 483, 483, 212, 483, nil, nil, nil, 212, 212, + 212, 212, nil, 212, 212, 212, 212, nil, nil, nil, + nil, 212, 212, 483, 483, nil, nil, nil, nil, 212, + nil, 212, 212, 212, 237, 237, 237, 237, 237, 237, + nil, nil, nil, 237, 237, nil, nil, nil, 237, nil, + 237, 237, 237, 237, 237, 237, 237, nil, nil, nil, + nil, nil, 237, 237, 237, 237, 237, 237, 237, nil, + nil, 237, nil, nil, nil, nil, nil, 237, 237, 237, + 237, 237, 237, 237, 237, 237, 237, 237, 237, nil, + 237, 237, 237, nil, 237, 237, 237, 237, 237, 532, + 532, 532, 532, 532, 532, 532, 532, 532, 532, 532, + nil, 532, 532, nil, nil, 532, 532, nil, 237, nil, + nil, 237, nil, nil, 237, 237, nil, nil, 237, nil, + 237, 532, nil, 532, 237, 532, 532, nil, 532, 532, + 532, 532, 532, 237, 532, nil, nil, nil, 237, 237, + 237, 237, nil, 237, 237, 237, 237, nil, nil, nil, + nil, 237, 237, nil, 532, nil, nil, nil, nil, 237, + nil, 237, 237, 237, 303, 303, 303, 303, 303, 303, + nil, nil, nil, 303, 303, nil, nil, nil, 303, nil, + 303, 303, 303, 303, 303, 303, 303, nil, nil, nil, + nil, nil, 303, 303, 303, 303, 303, 303, 303, nil, + nil, 303, nil, nil, nil, nil, nil, 303, 303, 303, + 303, 303, 303, 303, 303, 303, 303, 303, 303, nil, + 303, 303, 303, nil, 303, 303, 303, 303, 303, 752, + 752, 752, 752, 752, 752, 752, 752, 752, 752, 752, + nil, 752, 752, nil, nil, 752, 752, nil, 303, nil, + nil, 303, nil, nil, 303, 303, nil, nil, 303, nil, + 303, 752, nil, 752, 303, 752, 752, nil, 752, 752, + 752, 752, 752, 303, 752, nil, nil, nil, 303, 303, + 303, 303, nil, 303, 303, 303, 303, nil, nil, nil, + nil, 303, 303, nil, 752, nil, nil, nil, nil, 303, + nil, 303, 303, 303, 308, 308, 308, 308, 308, 308, + nil, nil, nil, 308, 308, nil, nil, nil, 308, nil, + 308, 308, 308, 308, 308, 308, 308, nil, nil, nil, + nil, nil, 308, 308, 308, 308, 308, 308, 308, nil, + nil, 308, nil, nil, nil, nil, nil, 308, 308, 308, + 308, 308, 308, 308, 308, 308, 308, 308, 308, nil, + 308, 308, 308, nil, 308, 308, 308, 308, 308, 846, + 846, 846, 846, 846, 846, 846, 846, 846, 846, 846, + nil, 846, 846, nil, nil, 846, 846, nil, 308, nil, + nil, 308, nil, nil, 308, 308, nil, nil, 308, nil, + 308, 846, nil, 846, 308, 846, 846, nil, 846, 846, + 846, 846, 846, 308, 846, nil, nil, nil, 308, 308, + 308, 308, nil, 308, 308, 308, 308, nil, nil, nil, + nil, 308, 308, nil, 846, nil, nil, nil, nil, 308, + nil, 308, 308, 308, 334, 334, 334, 334, 334, 334, + nil, nil, nil, 334, 334, nil, nil, nil, 334, nil, + 334, 334, 334, 334, 334, 334, 334, nil, nil, nil, + nil, nil, 334, 334, 334, 334, 334, 334, 334, nil, + nil, 334, nil, nil, nil, nil, nil, 334, 334, 334, + 334, 334, 334, 334, 334, 334, 334, 334, 334, nil, + 334, 334, 334, nil, 334, 334, 334, 334, 334, 462, + 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, + nil, 462, 462, nil, nil, 462, 462, nil, 334, nil, + nil, 334, nil, nil, 334, 334, nil, nil, 334, nil, + 334, 462, nil, 462, 334, 462, 462, nil, 462, 462, + 462, 462, 462, 334, 462, nil, nil, nil, 334, 334, + 334, 334, nil, 334, 334, 334, 334, nil, nil, nil, + nil, 334, 334, nil, nil, nil, nil, nil, nil, 334, + nil, 334, 334, 334, 350, 350, 350, 350, 350, 350, + nil, nil, nil, 350, 350, nil, nil, nil, 350, nil, + 350, 350, 350, 350, 350, 350, 350, nil, nil, nil, + nil, nil, 350, 350, 350, 350, 350, 350, 350, nil, + nil, 350, nil, nil, nil, nil, nil, 350, 350, 350, + 350, 350, 350, 350, 350, 350, 350, 350, 350, nil, + 350, 350, 350, nil, 350, 350, 350, 350, 350, 463, + 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, + nil, 463, 463, nil, nil, 463, 463, nil, 350, nil, + nil, 350, nil, nil, 350, 350, nil, nil, 350, nil, + 350, 463, nil, 463, 350, 463, 463, nil, 463, 463, + 463, 463, 463, 350, 463, nil, nil, nil, 350, 350, + 350, 350, nil, 350, 350, 350, 350, nil, nil, nil, + nil, 350, 350, nil, nil, nil, nil, nil, nil, 350, + nil, 350, 350, 350, 351, 351, 351, 351, 351, 351, + nil, nil, nil, 351, 351, nil, nil, nil, 351, nil, + 351, 351, 351, 351, 351, 351, 351, nil, nil, nil, + nil, nil, 351, 351, 351, 351, 351, 351, 351, nil, + nil, 351, nil, nil, nil, nil, nil, 351, 351, 351, + 351, 351, 351, 351, 351, 351, 351, 351, 351, nil, + 351, 351, 351, nil, 351, 351, 351, 351, 351, 473, + 473, 473, 473, 473, 473, 473, nil, nil, 473, 473, + nil, nil, nil, nil, nil, 473, 473, nil, 351, nil, + nil, 351, nil, nil, 351, 351, nil, nil, 351, nil, + 351, 473, nil, 473, 351, 473, 473, nil, 473, 473, + 473, 473, 473, 351, 473, nil, nil, nil, 351, 351, + 351, 351, nil, 351, 351, 351, 351, nil, nil, nil, + nil, 351, 351, nil, nil, nil, nil, nil, nil, 351, + nil, 351, 351, 351, 548, 548, 548, 548, 548, 548, + nil, nil, nil, 548, 548, nil, nil, nil, 548, nil, + 548, 548, 548, 548, 548, 548, 548, nil, nil, nil, + nil, nil, 548, 548, 548, 548, 548, 548, 548, nil, + nil, 548, nil, nil, nil, nil, nil, 548, 548, 548, + 548, 548, 548, 548, 548, 548, 548, 548, 548, nil, + 548, 548, 548, nil, 548, 548, 548, 548, 548, 474, + 474, 474, 474, 474, 474, 474, nil, nil, 474, 474, + nil, nil, nil, nil, nil, 474, 474, nil, 548, nil, + nil, 548, nil, nil, 548, 548, nil, nil, 548, nil, + 548, 474, nil, 474, 548, 474, 474, nil, 474, 474, + 474, 474, 474, 548, 474, nil, nil, nil, 548, 548, + 548, 548, nil, 548, 548, 548, 548, nil, nil, nil, + nil, 548, 548, nil, nil, nil, nil, nil, nil, 548, + nil, 548, 548, 548, 551, 551, 551, 551, 551, 551, + nil, nil, nil, 551, 551, nil, nil, nil, 551, nil, + 551, 551, 551, 551, 551, 551, 551, nil, nil, nil, + nil, nil, 551, 551, 551, 551, 551, 551, 551, nil, + nil, 551, nil, nil, nil, nil, nil, 551, 551, 551, + 551, 551, 551, 551, 551, 551, 551, 551, 551, nil, + 551, 551, 551, nil, 551, 551, 551, 551, 551, 475, + 475, 475, 475, 475, 475, 475, nil, nil, 475, 475, + nil, nil, nil, nil, nil, 475, 475, nil, 551, nil, + nil, 551, nil, nil, 551, 551, nil, nil, 551, nil, + 551, 475, nil, 475, 551, 475, 475, nil, 475, 475, + 475, 475, 475, 551, 475, nil, nil, nil, 551, 551, + 551, 551, nil, 551, 551, 551, 551, nil, nil, nil, + nil, 551, 551, nil, nil, nil, nil, nil, nil, 551, + nil, 551, 551, 551, 572, 572, 572, 572, 572, 572, + nil, nil, nil, 572, 572, nil, nil, nil, 572, nil, + 572, 572, 572, 572, 572, 572, 572, nil, nil, nil, + nil, nil, 572, 572, 572, 572, 572, 572, 572, nil, + nil, 572, nil, nil, nil, nil, nil, 572, 572, 572, + 572, 572, 572, 572, 572, 572, 572, 572, 572, nil, + 572, 572, 572, nil, 572, 572, 572, 572, 572, 476, + 476, 476, 476, 476, 476, 476, nil, nil, 476, 476, + nil, nil, nil, nil, nil, 476, 476, nil, 572, nil, + nil, 572, nil, nil, 572, 572, nil, nil, 572, nil, + 572, 476, nil, 476, 572, 476, 476, nil, 476, 476, + 476, 476, 476, 572, 476, nil, nil, nil, 572, 572, + 572, 572, nil, 572, 572, 572, 572, nil, nil, nil, + nil, 572, 572, nil, nil, nil, nil, nil, nil, 572, + nil, 572, 572, 572, 717, 717, 717, 717, 717, 717, + nil, nil, nil, 717, 717, nil, nil, nil, 717, nil, + 717, 717, 717, 717, 717, 717, 717, nil, nil, nil, + nil, nil, 717, 717, 717, 717, 717, 717, 717, nil, + nil, 717, nil, nil, nil, nil, nil, 717, 717, 717, + 717, 717, 717, 717, 717, 717, 717, 717, 717, nil, + 717, 717, 717, nil, 717, 717, 717, 717, 717, 477, + 477, 477, 477, 477, 477, 477, nil, nil, 477, 477, + nil, nil, nil, nil, nil, 477, 477, nil, 717, nil, + nil, 717, nil, nil, 717, 717, nil, nil, 717, nil, + 717, 477, nil, 477, 717, 477, 477, nil, 477, 477, + 477, 477, 477, 717, 477, nil, nil, nil, 717, 717, + 717, 717, nil, 717, 717, 717, 717, nil, nil, nil, + nil, 717, 717, nil, nil, nil, nil, nil, nil, 717, + nil, 717, 717, 717, 722, 722, 722, 722, 722, 722, + nil, nil, nil, 722, 722, nil, nil, nil, 722, nil, + 722, 722, 722, 722, 722, 722, 722, nil, nil, nil, + nil, nil, 722, 722, 722, 722, 722, 722, 722, nil, + nil, 722, nil, nil, nil, nil, nil, 722, 722, 722, + 722, 722, 722, 722, 722, 722, 722, 722, 722, nil, + 722, 722, 722, nil, 722, 722, 722, 722, 722, 478, + 478, 478, 478, 478, 478, 478, nil, nil, 478, 478, + nil, nil, nil, nil, nil, 478, 478, nil, 722, nil, + nil, 722, nil, nil, 722, 722, nil, nil, 722, nil, + 722, 478, nil, 478, 722, 478, 478, nil, 478, 478, + 478, 478, 478, 722, 478, nil, nil, nil, 722, 722, + 722, 722, nil, 722, 722, 722, 722, nil, nil, nil, + nil, 722, 722, nil, nil, nil, nil, nil, nil, 722, + nil, 722, 722, 722, 726, 726, 726, 726, 726, 726, + nil, nil, nil, 726, 726, nil, nil, nil, 726, nil, + 726, 726, 726, 726, 726, 726, 726, nil, nil, nil, + nil, nil, 726, 726, 726, 726, 726, 726, 726, nil, + nil, 726, nil, nil, nil, nil, nil, 726, 726, 726, + 726, 726, 726, 726, 726, 726, 726, 726, 726, nil, + 726, 726, 726, nil, 726, 726, 726, 726, 726, 481, + 481, 481, 481, 481, 481, 481, nil, nil, 481, 481, + nil, nil, nil, nil, nil, 481, 481, nil, 726, nil, + nil, 726, nil, nil, 726, 726, nil, nil, 726, nil, + 726, 481, nil, 481, 726, 481, 481, nil, 481, 481, + 481, 481, 481, 726, 481, nil, nil, nil, 726, 726, + 726, 726, nil, 726, 726, 726, 726, nil, nil, nil, + nil, 726, 726, nil, nil, nil, nil, nil, nil, 726, + nil, 726, 726, 726, 736, 736, 736, 736, 736, 736, + nil, nil, nil, 736, 736, nil, nil, nil, 736, nil, + 736, 736, 736, 736, 736, 736, 736, nil, nil, nil, + nil, nil, 736, 736, 736, 736, 736, 736, 736, nil, + nil, 736, nil, nil, nil, nil, nil, 736, 736, 736, + 736, 736, 736, 736, 736, 736, 736, 736, 736, nil, + 736, 736, 736, nil, 736, 736, 736, 736, 736, 482, + 482, 482, 482, 482, 482, 482, 482, nil, 482, 482, + nil, nil, nil, nil, nil, 482, 482, nil, 736, nil, + nil, 736, nil, nil, 736, 736, nil, nil, 736, nil, + 736, 482, nil, 482, 736, 482, 482, nil, 482, 482, + 482, 482, 482, 736, 482, nil, nil, nil, 736, 736, + 736, 736, nil, 736, 736, 736, 736, nil, nil, nil, + nil, 736, 736, nil, nil, nil, nil, nil, nil, 736, + nil, 736, 736, 736, 781, 781, 781, 781, 781, 781, + nil, nil, nil, 781, 781, nil, nil, nil, 781, nil, + 781, 781, 781, 781, 781, 781, 781, nil, nil, nil, + nil, nil, 781, 781, 781, 781, 781, 781, 781, nil, + nil, 781, nil, nil, nil, nil, nil, 781, 781, 781, + 781, 781, 781, 781, 781, 781, 781, 781, 781, nil, + 781, 781, 781, nil, 781, 781, 781, 781, 781, 471, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 471, 471, nil, 781, nil, + nil, 781, nil, nil, 781, 781, nil, nil, 781, nil, + 781, 471, nil, 471, 781, 471, 471, nil, 471, 471, + nil, nil, nil, 781, nil, nil, nil, nil, 781, 781, + 781, 781, nil, 781, 781, 781, 781, nil, nil, nil, + nil, 781, 781, nil, nil, nil, nil, nil, nil, 781, + nil, 781, 781, 781, 792, 792, 792, 792, 792, 792, + nil, nil, nil, 792, 792, nil, nil, nil, 792, nil, + 792, 792, 792, 792, 792, 792, 792, nil, nil, nil, + nil, nil, 792, 792, 792, 792, 792, 792, 792, nil, + nil, 792, nil, nil, nil, nil, nil, 792, 792, 792, + 792, 792, 792, 792, 792, 792, 792, 792, 792, nil, + 792, 792, 792, nil, 792, 792, 792, 792, 792, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 792, nil, + nil, 792, nil, nil, 792, 792, nil, nil, 792, nil, + 792, nil, nil, nil, 792, nil, nil, nil, nil, nil, + nil, nil, nil, 792, nil, nil, nil, nil, 792, 792, + 792, 792, nil, 792, 792, 792, 792, nil, nil, nil, + nil, 792, 792, nil, nil, nil, nil, nil, nil, 792, + nil, 792, 792, 792, 827, 827, 827, 827, 827, 827, + nil, nil, nil, 827, 827, nil, nil, nil, 827, nil, + 827, 827, 827, 827, 827, 827, 827, nil, nil, nil, + nil, nil, 827, 827, 827, 827, 827, 827, 827, nil, + nil, 827, nil, nil, nil, nil, nil, 827, 827, 827, + 827, 827, 827, 827, 827, 827, 827, 827, 827, nil, + 827, 827, 827, nil, 827, 827, 827, 827, 827, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 827, nil, + nil, 827, nil, nil, 827, 827, nil, nil, 827, nil, + 827, nil, nil, nil, 827, nil, nil, nil, nil, nil, + nil, nil, nil, 827, nil, nil, nil, nil, 827, 827, + 827, 827, nil, 827, 827, 827, 827, nil, nil, nil, + nil, 827, 827, nil, nil, nil, nil, nil, nil, 827, + nil, 827, 827, 827, 833, 833, 833, 833, 833, 833, + nil, nil, nil, 833, 833, nil, nil, nil, 833, nil, + 833, 833, 833, 833, 833, 833, 833, nil, nil, nil, + nil, nil, 833, 833, 833, 833, 833, 833, 833, nil, + nil, 833, nil, nil, nil, nil, nil, 833, 833, 833, + 833, 833, 833, 833, 833, 833, 833, 833, 833, nil, + 833, 833, 833, nil, 833, 833, 833, 833, 833, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 833, nil, + nil, 833, nil, nil, 833, 833, nil, nil, 833, nil, + 833, nil, nil, nil, 833, nil, nil, nil, nil, nil, + nil, nil, nil, 833, nil, nil, nil, nil, 833, 833, + 833, 833, nil, 833, 833, 833, 833, nil, nil, nil, + nil, 833, 833, nil, nil, nil, nil, nil, nil, 833, + nil, 833, 833, 833, 847, 847, 847, 847, 847, 847, + nil, nil, nil, 847, 847, nil, nil, nil, 847, nil, + 847, 847, 847, 847, 847, 847, 847, nil, nil, nil, + nil, nil, 847, 847, 847, 847, 847, 847, 847, nil, + nil, 847, nil, nil, nil, nil, nil, 847, 847, 847, + 847, 847, 847, 847, 847, 847, 847, 847, 847, nil, + 847, 847, 847, nil, 847, 847, 847, 847, 847, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 847, nil, + nil, 847, nil, nil, 847, 847, nil, nil, 847, nil, + 847, nil, nil, nil, 847, nil, nil, nil, nil, nil, + nil, nil, nil, 847, nil, nil, nil, nil, 847, 847, + 847, 847, nil, 847, 847, 847, 847, nil, nil, nil, + nil, 847, 847, nil, nil, nil, nil, nil, nil, 847, + nil, 847, 847, 847, 865, 865, 865, 865, 865, 865, + nil, nil, nil, 865, 865, nil, nil, nil, 865, nil, + 865, 865, 865, 865, 865, 865, 865, nil, nil, nil, + nil, nil, 865, 865, 865, 865, 865, 865, 865, nil, + nil, 865, nil, nil, nil, nil, nil, 865, 865, 865, + 865, 865, 865, 865, 865, 865, 865, 865, 865, nil, + 865, 865, 865, nil, 865, 865, 865, 865, 865, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 865, nil, + nil, 865, nil, nil, 865, 865, nil, nil, 865, nil, + 865, nil, nil, nil, 865, nil, nil, nil, nil, nil, + nil, nil, nil, 865, nil, nil, nil, nil, 865, 865, + 865, 865, nil, 865, 865, 865, 865, nil, nil, nil, + nil, 865, 865, nil, nil, nil, nil, nil, nil, 865, + nil, 865, 865, 865, 924, 924, 924, 924, 924, 924, + nil, nil, nil, 924, 924, nil, nil, nil, 924, nil, + 924, 924, 924, 924, 924, 924, 924, nil, nil, nil, + nil, nil, 924, 924, 924, 924, 924, 924, 924, nil, + nil, 924, nil, nil, nil, nil, nil, 924, 924, 924, + 924, 924, 924, 924, 924, 924, 924, 924, 924, nil, + 924, 924, 924, nil, 924, 924, 924, 924, 924, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 924, nil, + nil, 924, nil, nil, 924, 924, nil, nil, 924, nil, + 924, nil, nil, nil, 924, nil, nil, nil, nil, nil, + nil, nil, nil, 924, nil, nil, nil, nil, 924, 924, + 924, 924, nil, 924, 924, 924, 924, nil, nil, nil, + nil, 924, 924, nil, nil, nil, nil, nil, nil, 924, + nil, 924, 924, 924, 931, 931, 931, 931, 931, 931, + nil, nil, nil, 931, 931, nil, nil, nil, 931, nil, + 931, 931, 931, 931, 931, 931, 931, nil, nil, nil, + nil, nil, 931, 931, 931, 931, 931, 931, 931, nil, + nil, 931, nil, nil, nil, nil, nil, 931, 931, 931, + 931, 931, 931, 931, 931, 931, 931, 931, 931, nil, + 931, 931, 931, nil, 931, 931, 931, 931, 931, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 931, nil, + nil, 931, nil, nil, 931, 931, nil, nil, 931, nil, + 931, nil, nil, nil, 931, nil, nil, nil, nil, nil, + nil, nil, nil, 931, nil, nil, nil, nil, 931, 931, + 931, 931, nil, 931, 931, 931, 931, nil, nil, nil, + nil, 931, 931, nil, nil, nil, nil, nil, nil, 931, + nil, 931, 931, 931, 932, 932, 932, 932, 932, 932, + nil, nil, nil, 932, 932, nil, nil, nil, 932, nil, + 932, 932, 932, 932, 932, 932, 932, nil, nil, nil, + nil, nil, 932, 932, 932, 932, 932, 932, 932, nil, + nil, 932, nil, nil, nil, nil, nil, 932, 932, 932, + 932, 932, 932, 932, 932, 932, 932, 932, 932, nil, + 932, 932, 932, nil, 932, 932, 932, 932, 932, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 932, nil, + nil, 932, nil, nil, 932, 932, nil, nil, 932, nil, + 932, nil, nil, nil, 932, nil, nil, nil, nil, nil, + nil, nil, nil, 932, nil, nil, nil, nil, 932, 932, + 932, 932, nil, 932, 932, 932, 932, nil, nil, nil, + nil, 932, 932, nil, nil, nil, nil, nil, nil, 932, + nil, 932, 932, 932, 949, 949, 949, 949, 949, 949, + nil, nil, nil, 949, 949, nil, nil, nil, 949, nil, + 949, 949, 949, 949, 949, 949, 949, nil, nil, nil, + nil, nil, 949, 949, 949, 949, 949, 949, 949, nil, + nil, 949, nil, nil, nil, nil, nil, 949, 949, 949, + 949, 949, 949, 949, 949, 949, 949, 949, 949, nil, + 949, 949, 949, nil, 949, 949, 949, 949, 949, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 949, nil, + nil, 949, nil, nil, 949, 949, nil, nil, 949, nil, + 949, nil, nil, nil, 949, nil, nil, nil, nil, nil, + nil, nil, nil, 949, nil, nil, nil, nil, 949, 949, + 949, 949, nil, 949, 949, 949, 949, nil, nil, nil, + nil, 949, 949, nil, nil, nil, nil, nil, nil, 949, + nil, 949, 949, 949, 954, 954, 954, 954, 954, 954, + nil, nil, nil, 954, 954, nil, nil, nil, 954, nil, + 954, 954, 954, 954, 954, 954, 954, nil, nil, nil, + nil, nil, 954, 954, 954, 954, 954, 954, 954, nil, + nil, 954, nil, nil, nil, nil, nil, 954, 954, 954, + 954, 954, 954, 954, 954, 954, 954, 954, 954, nil, + 954, 954, 954, nil, 954, 954, 954, 954, 954, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 954, nil, + nil, 954, nil, nil, 954, 954, nil, nil, 954, nil, + 954, nil, nil, nil, 954, nil, nil, nil, nil, nil, + nil, nil, nil, 954, nil, nil, nil, nil, 954, 954, + 954, 954, nil, 954, 954, 954, 954, nil, nil, nil, + nil, 954, 954, nil, nil, nil, nil, nil, nil, 954, + nil, 954, 954, 954, 5, 5, 5, 5, 5, nil, + nil, nil, 5, 5, nil, nil, nil, 5, nil, 5, + 5, 5, 5, 5, 5, 5, nil, nil, nil, nil, + nil, 5, 5, 5, 5, 5, 5, 5, nil, nil, + 5, nil, nil, nil, nil, nil, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, nil, 5, + 5, 5, nil, 5, 5, 5, 5, 5, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 5, nil, nil, + 5, nil, nil, 5, 5, nil, nil, 5, nil, 5, + nil, nil, nil, 5, nil, nil, nil, nil, nil, nil, + nil, nil, 5, nil, nil, nil, nil, 5, 5, 5, + 5, nil, 5, 5, 5, 5, nil, nil, nil, nil, + 5, 5, nil, nil, nil, 20, 20, 20, 5, 20, + 5, 5, 5, 20, 20, nil, nil, nil, 20, nil, + 20, 20, 20, 20, 20, 20, 20, nil, nil, nil, + nil, nil, 20, 20, 20, 20, 20, 20, 20, nil, + nil, 20, nil, nil, nil, nil, nil, nil, 20, nil, + nil, 20, 20, 20, 20, 20, 20, 20, 20, nil, + 20, 20, 20, nil, 20, 20, 20, 20, 20, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 20, nil, + nil, 20, nil, nil, 20, 20, nil, nil, 20, nil, + nil, nil, nil, nil, 20, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 20, 20, + 20, 20, nil, 20, 20, 20, 20, nil, nil, nil, + nil, 20, 20, nil, nil, nil, 29, 29, 29, 20, + 29, 20, 20, 20, 29, 29, nil, nil, nil, 29, + nil, 29, 29, 29, 29, 29, 29, 29, nil, nil, + nil, nil, nil, 29, 29, 29, 29, 29, 29, 29, + nil, nil, 29, nil, nil, nil, nil, nil, nil, 29, + nil, nil, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, nil, 29, 29, 29, 29, 29, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 29, + nil, nil, 29, nil, nil, 29, 29, nil, nil, 29, + nil, 29, nil, 29, nil, 29, nil, nil, 29, nil, + nil, nil, nil, nil, 29, nil, nil, nil, nil, 29, + 29, 29, 29, nil, 29, 29, 29, 29, nil, nil, + nil, nil, 29, 29, nil, nil, nil, 30, 30, 30, + 29, 30, 29, 29, 29, 30, 30, nil, nil, nil, + 30, nil, 30, 30, 30, 30, 30, 30, 30, nil, + nil, nil, nil, nil, 30, 30, 30, 30, 30, 30, + 30, nil, nil, 30, nil, nil, nil, nil, nil, nil, + 30, nil, nil, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, nil, 30, 30, 30, 30, + 30, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 30, nil, nil, 30, nil, nil, 30, 30, nil, nil, + 30, nil, 30, nil, 30, nil, 30, nil, nil, 30, + nil, nil, nil, nil, nil, 30, nil, nil, nil, nil, + 30, 30, 30, 30, nil, 30, 30, 30, 30, nil, + nil, nil, nil, 30, 30, nil, nil, nil, 31, 31, + 31, 30, 31, 30, 30, 30, 31, 31, nil, nil, + nil, 31, nil, 31, 31, 31, 31, 31, 31, 31, + nil, nil, nil, nil, nil, 31, 31, 31, 31, 31, + 31, 31, nil, nil, 31, nil, nil, nil, nil, nil, + nil, 31, nil, nil, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, nil, 31, 31, 31, + 31, 31, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 31, nil, nil, 31, nil, nil, 31, 31, nil, + nil, 31, nil, 31, nil, 31, nil, 31, nil, nil, + 31, nil, nil, nil, nil, nil, 31, nil, nil, nil, + nil, 31, 31, 31, 31, nil, 31, 31, 31, 31, + nil, nil, nil, nil, 31, 31, nil, nil, nil, 34, + 34, 34, 31, 34, 31, 31, 31, 34, 34, nil, + nil, nil, 34, nil, 34, 34, 34, 34, 34, 34, + 34, nil, nil, nil, nil, nil, 34, 34, 34, 34, + 34, 34, 34, nil, nil, 34, nil, nil, nil, nil, + nil, nil, 34, nil, nil, 34, 34, 34, 34, 34, + 34, 34, 34, nil, 34, 34, 34, nil, 34, 34, + nil, nil, 34, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 34, nil, nil, 34, nil, nil, 34, 34, + nil, nil, 34, nil, 34, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 34, 34, 34, 34, nil, 34, 34, 34, + 34, nil, nil, nil, nil, 34, 34, nil, nil, nil, + 35, 35, 35, 34, 35, 34, 34, 34, 35, 35, + nil, nil, nil, 35, nil, 35, 35, 35, 35, 35, + 35, 35, nil, nil, nil, nil, nil, 35, 35, 35, + 35, 35, 35, 35, nil, nil, 35, nil, nil, nil, + nil, nil, nil, 35, nil, nil, 35, 35, 35, 35, + 35, 35, 35, 35, nil, 35, 35, 35, nil, 35, + 35, nil, nil, 35, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 35, nil, nil, 35, nil, nil, 35, + 35, nil, nil, 35, nil, nil, 915, nil, 915, 915, + 915, 915, 915, nil, nil, nil, nil, nil, nil, nil, + nil, 915, nil, 35, 35, 35, 35, nil, 35, 35, + 35, 35, nil, nil, nil, nil, 35, 35, nil, nil, + nil, 35, nil, 915, 35, nil, 35, 35, 35, 42, + 42, 42, nil, 42, 915, 915, nil, 42, 42, 915, + nil, nil, 42, nil, 42, 42, 42, 42, 42, 42, + 42, nil, nil, nil, nil, nil, 42, 42, 42, 42, + 42, 42, 42, nil, nil, 42, nil, nil, nil, nil, + nil, nil, 42, nil, nil, 42, 42, 42, 42, 42, + 42, 42, 42, nil, 42, 42, 42, nil, 42, 42, + 42, 42, 42, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 42, nil, nil, 42, nil, nil, 42, 42, + nil, nil, 42, nil, nil, nil, nil, nil, 42, nil, + nil, nil, nil, nil, nil, nil, nil, 42, nil, nil, + nil, nil, 42, 42, 42, 42, nil, 42, 42, 42, + 42, nil, nil, nil, nil, 42, 42, nil, nil, nil, + 43, 43, 43, 42, 43, 42, 42, 42, 43, 43, + nil, nil, nil, 43, nil, 43, 43, 43, 43, 43, + 43, 43, nil, nil, nil, nil, nil, 43, 43, 43, + 43, 43, 43, 43, nil, nil, 43, nil, nil, nil, + nil, nil, nil, 43, nil, nil, 43, 43, 43, 43, + 43, 43, 43, 43, nil, 43, 43, 43, nil, 43, + 43, 43, 43, 43, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 43, nil, nil, 43, nil, nil, 43, + 43, nil, nil, 43, nil, nil, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, nil, 43, nil, + nil, nil, nil, 43, 43, 43, 43, nil, 43, 43, + 43, 43, nil, nil, nil, nil, 43, 43, nil, nil, + nil, 45, 45, 45, 43, 45, 43, 43, 43, 45, + 45, nil, nil, nil, 45, nil, 45, 45, 45, 45, + 45, 45, 45, nil, nil, nil, nil, nil, 45, 45, + 45, 45, 45, 45, 45, nil, nil, 45, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 45, 45, 45, + 45, 45, 45, 45, 45, nil, 45, 45, 45, nil, + 45, 45, 45, 45, 45, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 45, nil, nil, + 45, 45, nil, nil, 45, nil, nil, nil, nil, nil, + 45, nil, nil, nil, nil, nil, nil, nil, nil, 45, + nil, nil, nil, nil, 45, 45, 45, 45, nil, 45, + 45, 45, 45, nil, nil, nil, nil, 45, 45, nil, + nil, nil, nil, nil, nil, 45, nil, 45, 45, 45, + 59, 59, 59, 59, 59, nil, nil, nil, 59, 59, + nil, nil, nil, 59, nil, 59, 59, 59, 59, 59, + 59, 59, nil, nil, nil, nil, nil, 59, 59, 59, + 59, 59, 59, 59, nil, nil, 59, nil, nil, nil, + nil, nil, 59, 59, nil, 59, 59, 59, 59, 59, + 59, 59, 59, 59, nil, 59, 59, 59, nil, 59, + 59, 59, 59, 59, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 59, nil, nil, 59, nil, nil, 59, + 59, nil, nil, 59, nil, 59, nil, nil, nil, 59, + nil, nil, nil, nil, nil, nil, nil, nil, 59, nil, + nil, nil, nil, 59, 59, 59, 59, nil, 59, 59, + 59, 59, nil, nil, nil, nil, 59, 59, nil, nil, + nil, 60, 60, 60, 59, 60, 59, 59, 59, 60, + 60, nil, nil, nil, 60, nil, 60, 60, 60, 60, + 60, 60, 60, nil, nil, nil, nil, nil, 60, 60, + 60, 60, 60, 60, 60, nil, nil, 60, nil, nil, + nil, nil, nil, nil, 60, nil, nil, 60, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 60, 60, nil, + 60, 60, 60, 60, 60, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 60, nil, nil, 60, nil, nil, + 60, 60, nil, nil, 60, nil, 60, nil, nil, nil, + 60, nil, nil, 60, nil, nil, nil, nil, nil, 60, + nil, nil, nil, nil, 60, 60, 60, 60, nil, 60, + 60, 60, 60, nil, nil, nil, nil, 60, 60, nil, + nil, nil, 61, 61, 61, 60, 61, 60, 60, 60, + 61, 61, nil, nil, nil, 61, nil, 61, 61, 61, + 61, 61, 61, 61, nil, nil, nil, nil, nil, 61, + 61, 61, 61, 61, 61, 61, nil, nil, 61, nil, + nil, nil, nil, nil, nil, 61, nil, nil, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + nil, 61, 61, 61, 61, 61, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 61, nil, nil, 61, nil, + nil, 61, 61, nil, nil, 61, nil, nil, nil, nil, + nil, 61, nil, nil, 61, nil, nil, nil, nil, nil, + 61, nil, nil, nil, nil, 61, 61, 61, 61, nil, + 61, 61, 61, 61, nil, nil, nil, nil, 61, 61, + nil, nil, nil, 64, 64, 64, 61, 64, 61, 61, + 61, 64, 64, nil, nil, nil, 64, nil, 64, 64, + 64, 64, 64, 64, 64, nil, nil, nil, nil, nil, + 64, 64, 64, 64, 64, 64, 64, nil, nil, 64, + nil, nil, nil, nil, nil, nil, 64, nil, nil, 64, + 64, 64, 64, 64, 64, 64, 64, nil, 64, 64, + 64, nil, 64, 64, 64, 64, 64, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 64, nil, nil, 64, + nil, nil, 64, 64, nil, nil, 64, nil, nil, nil, + nil, nil, 64, nil, nil, nil, nil, nil, nil, nil, + nil, 64, nil, nil, nil, nil, 64, 64, 64, 64, + nil, 64, 64, 64, 64, nil, nil, nil, nil, 64, + 64, nil, nil, nil, 65, 65, 65, 64, 65, 64, + 64, 64, 65, 65, nil, nil, nil, 65, nil, 65, + 65, 65, 65, 65, 65, 65, nil, nil, nil, nil, + nil, 65, 65, 65, 65, 65, 65, 65, nil, nil, + 65, nil, nil, nil, nil, nil, nil, 65, nil, nil, + 65, 65, 65, 65, 65, 65, 65, 65, nil, 65, + 65, 65, nil, 65, 65, 65, 65, 65, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 65, nil, nil, + 65, nil, nil, 65, 65, nil, nil, 65, nil, nil, + nil, nil, nil, 65, nil, nil, nil, nil, nil, nil, + nil, nil, 65, nil, nil, nil, nil, 65, 65, 65, + 65, nil, 65, 65, 65, 65, nil, nil, nil, nil, + 65, 65, nil, nil, nil, 68, 68, 68, 65, 68, + 65, 65, 65, 68, 68, nil, nil, nil, 68, nil, + 68, 68, 68, 68, 68, 68, 68, nil, nil, nil, + nil, nil, 68, 68, 68, 68, 68, 68, 68, nil, + nil, 68, nil, nil, nil, nil, nil, nil, 68, nil, + nil, 68, 68, 68, 68, 68, 68, 68, 68, nil, + 68, 68, 68, nil, 68, 68, 68, 68, 68, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 68, nil, + nil, 68, nil, nil, 68, 68, nil, nil, 68, nil, + nil, nil, nil, nil, 68, nil, nil, nil, nil, nil, + nil, nil, nil, 68, nil, nil, nil, nil, 68, 68, + 68, 68, nil, 68, 68, 68, 68, nil, nil, nil, + nil, 68, 68, 68, nil, nil, nil, nil, 68, 68, + nil, 68, 68, 68, 69, 69, 69, nil, 69, nil, + nil, nil, 69, 69, nil, nil, nil, 69, nil, 69, + 69, 69, 69, 69, 69, 69, nil, nil, nil, nil, + nil, 69, 69, 69, 69, 69, 69, 69, nil, nil, + 69, nil, nil, nil, nil, nil, nil, 69, nil, nil, + 69, 69, 69, 69, 69, 69, 69, 69, nil, 69, + 69, 69, nil, 69, 69, nil, nil, 69, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 69, nil, nil, + 69, nil, nil, 69, 69, nil, nil, 69, nil, 69, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 69, 69, 69, + 69, nil, 69, 69, 69, 69, nil, nil, nil, nil, + 69, 69, nil, nil, nil, 70, 70, 70, 69, 70, + 69, 69, 69, 70, 70, nil, nil, nil, 70, nil, + 70, 70, 70, 70, 70, 70, 70, nil, nil, nil, + nil, nil, 70, 70, 70, 70, 70, 70, 70, nil, + nil, 70, nil, nil, nil, nil, nil, nil, 70, nil, + nil, 70, 70, 70, 70, 70, 70, 70, 70, nil, + 70, 70, 70, nil, 70, 70, nil, nil, 70, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 70, nil, nil, 70, nil, + nil, 70, nil, nil, 70, 70, nil, nil, 70, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 70, 70, + 70, 70, nil, 70, 70, 70, 70, nil, nil, nil, + nil, 70, 70, nil, nil, nil, 71, 71, 71, 70, + 71, 70, 70, 70, 71, 71, nil, nil, nil, 71, + nil, 71, 71, 71, 71, 71, 71, 71, nil, nil, + nil, nil, nil, 71, 71, 71, 71, 71, 71, 71, + nil, nil, 71, nil, nil, nil, nil, nil, nil, 71, + nil, nil, 71, 71, 71, 71, 71, 71, 71, 71, + nil, 71, 71, 71, nil, 71, 71, nil, nil, 71, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 71, + nil, nil, 71, nil, nil, 71, 71, nil, nil, 71, + nil, nil, 937, nil, 937, 937, 937, 937, 937, nil, + nil, nil, nil, nil, nil, nil, nil, 937, nil, 71, + 71, 71, 71, nil, 71, 71, 71, 71, nil, nil, + nil, nil, 71, 71, nil, nil, nil, nil, nil, 937, + 71, nil, 71, 71, 71, 116, 116, 116, 116, 116, + 937, 937, nil, 116, 116, 937, nil, nil, 116, nil, + 116, 116, 116, 116, 116, 116, 116, nil, nil, nil, + nil, nil, 116, 116, 116, 116, 116, 116, 116, nil, + nil, 116, nil, nil, nil, nil, nil, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, nil, + 116, 116, 116, nil, 116, 116, 116, 116, 116, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 116, nil, + nil, 116, nil, nil, 116, 116, nil, nil, 116, nil, + 116, nil, nil, nil, 116, nil, nil, nil, nil, nil, + nil, nil, nil, 116, nil, nil, nil, nil, 116, 116, + 116, 116, nil, 116, 116, 116, 116, nil, nil, nil, + nil, 116, 116, nil, nil, nil, nil, nil, 116, 116, + nil, 116, 116, 116, 121, 121, 121, nil, 121, nil, + nil, nil, 121, 121, nil, nil, nil, 121, nil, 121, + 121, 121, 121, 121, 121, 121, nil, nil, nil, nil, + nil, 121, 121, 121, 121, 121, 121, 121, nil, nil, + 121, nil, nil, nil, nil, nil, nil, 121, nil, nil, + 121, 121, 121, 121, 121, 121, 121, 121, nil, 121, + 121, 121, nil, 121, 121, 121, 121, 121, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 121, nil, nil, + 121, nil, nil, 121, 121, nil, nil, 121, nil, nil, + nil, nil, nil, 121, nil, nil, nil, nil, nil, nil, + nil, nil, 121, nil, nil, nil, nil, 121, 121, 121, + 121, nil, 121, 121, 121, 121, nil, nil, nil, nil, + 121, 121, nil, nil, nil, 122, 122, 122, 121, 122, + 121, 121, 121, 122, 122, nil, nil, nil, 122, nil, + 122, 122, 122, 122, 122, 122, 122, nil, nil, nil, + nil, nil, 122, 122, 122, 122, 122, 122, 122, nil, + nil, 122, nil, nil, nil, nil, nil, nil, 122, nil, + nil, 122, 122, 122, 122, 122, 122, 122, 122, nil, + 122, 122, 122, nil, 122, 122, 122, 122, 122, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 122, nil, + nil, 122, nil, nil, 122, 122, nil, nil, 122, nil, + nil, nil, nil, nil, 122, nil, nil, nil, nil, nil, + nil, nil, nil, 122, nil, nil, nil, nil, 122, 122, + 122, 122, nil, 122, 122, 122, 122, nil, nil, nil, + nil, 122, 122, nil, nil, nil, 123, 123, 123, 122, + 123, 122, 122, 122, 123, 123, nil, nil, nil, 123, + nil, 123, 123, 123, 123, 123, 123, 123, nil, nil, + nil, nil, nil, 123, 123, 123, 123, 123, 123, 123, + nil, nil, 123, nil, nil, nil, nil, nil, nil, 123, + nil, nil, 123, 123, 123, 123, 123, 123, 123, 123, + nil, 123, 123, 123, nil, 123, 123, 123, 123, 123, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 123, + nil, nil, 123, nil, nil, 123, 123, nil, nil, 123, + nil, nil, nil, nil, nil, 123, nil, nil, nil, nil, + nil, nil, nil, nil, 123, nil, nil, nil, nil, 123, + 123, 123, 123, nil, 123, 123, 123, 123, nil, nil, + nil, nil, 123, 123, nil, nil, nil, 124, 124, 124, + 123, 124, 123, 123, 123, 124, 124, nil, nil, nil, + 124, nil, 124, 124, 124, 124, 124, 124, 124, nil, + nil, nil, nil, nil, 124, 124, 124, 124, 124, 124, + 124, nil, nil, 124, nil, nil, nil, nil, nil, nil, + 124, nil, nil, 124, 124, 124, 124, 124, 124, 124, + 124, nil, 124, 124, 124, nil, 124, 124, 124, 124, + 124, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 124, nil, nil, 124, nil, nil, 124, 124, nil, nil, + 124, nil, nil, nil, nil, nil, 124, nil, nil, nil, + nil, nil, nil, nil, nil, 124, nil, nil, nil, nil, + 124, 124, 124, 124, nil, 124, 124, 124, 124, nil, + nil, nil, nil, 124, 124, nil, nil, nil, nil, nil, + nil, 124, nil, 124, 124, 124, 125, 125, 125, 125, + 125, nil, nil, nil, 125, 125, nil, nil, nil, 125, + nil, 125, 125, 125, 125, 125, 125, 125, nil, nil, + nil, nil, nil, 125, 125, 125, 125, 125, 125, 125, + nil, nil, 125, nil, nil, nil, nil, nil, 125, 125, + nil, 125, 125, 125, 125, 125, 125, 125, 125, 125, + nil, 125, 125, 125, nil, 125, 125, 125, 125, 125, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 125, + nil, nil, 125, nil, nil, 125, 125, nil, nil, 125, + nil, 125, nil, nil, nil, 125, nil, nil, nil, nil, + nil, nil, nil, nil, 125, nil, nil, nil, nil, 125, + 125, 125, 125, nil, 125, 125, 125, 125, nil, nil, + nil, nil, 125, 125, nil, nil, nil, 213, 213, 213, + 125, 213, 125, 125, 125, 213, 213, nil, nil, nil, + 213, nil, 213, 213, 213, 213, 213, 213, 213, nil, + nil, nil, nil, nil, 213, 213, 213, 213, 213, 213, + 213, nil, nil, 213, nil, nil, nil, nil, nil, nil, + 213, nil, nil, 213, 213, 213, 213, 213, 213, 213, + 213, nil, 213, 213, 213, nil, 213, 213, 213, 213, + 213, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 213, nil, nil, 213, nil, nil, 213, 213, nil, nil, + 213, nil, 213, nil, nil, nil, 213, nil, nil, nil, + nil, nil, nil, nil, nil, 213, nil, nil, nil, nil, + 213, 213, 213, 213, nil, 213, 213, 213, 213, nil, + nil, nil, nil, 213, 213, nil, nil, nil, 214, 214, + 214, 213, 214, 213, 213, 213, 214, 214, nil, nil, + nil, 214, nil, 214, 214, 214, 214, 214, 214, 214, + nil, nil, nil, nil, nil, 214, 214, 214, 214, 214, + 214, 214, nil, nil, 214, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 214, 214, 214, 214, 214, 214, + 214, 214, nil, 214, 214, 214, nil, 214, 214, 214, + 214, 214, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 214, nil, nil, 214, 214, nil, + nil, 214, nil, 214, nil, nil, nil, 214, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, nil, + nil, 214, 214, 214, 214, nil, 214, 214, 214, 214, + nil, nil, nil, nil, 214, 214, nil, nil, nil, 215, + 215, 215, 214, 215, 214, 214, 214, 215, 215, nil, + nil, nil, 215, nil, 215, 215, 215, 215, 215, 215, + 215, nil, nil, nil, nil, nil, 215, 215, 215, 215, + 215, 215, 215, nil, nil, 215, nil, nil, nil, nil, + nil, nil, 215, nil, nil, 215, 215, 215, 215, 215, + 215, 215, 215, nil, 215, 215, 215, nil, 215, 215, + 215, 215, 215, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 215, nil, nil, 215, nil, nil, 215, 215, + nil, nil, 215, nil, nil, nil, nil, nil, 215, nil, + nil, nil, nil, nil, nil, nil, nil, 215, nil, nil, + nil, nil, 215, 215, 215, 215, nil, 215, 215, 215, + 215, nil, nil, nil, nil, 215, 215, nil, nil, nil, + 216, 216, 216, 215, 216, 215, 215, 215, 216, 216, + nil, nil, nil, 216, nil, 216, 216, 216, 216, 216, + 216, 216, nil, nil, nil, nil, nil, 216, 216, 216, + 216, 216, 216, 216, nil, nil, 216, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 216, 216, 216, 216, + 216, 216, 216, 216, nil, 216, 216, 216, nil, 216, + 216, 216, 216, 216, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 216, nil, nil, 216, nil, nil, 216, + 216, nil, nil, 216, nil, nil, nil, nil, nil, 216, + nil, nil, nil, nil, nil, nil, nil, nil, 216, nil, + nil, nil, nil, 216, 216, 216, 216, nil, 216, 216, + 216, 216, nil, nil, nil, nil, 216, 216, nil, nil, + nil, 217, 217, 217, 216, 217, 216, 216, 216, 217, + 217, nil, nil, nil, 217, nil, 217, 217, 217, 217, + 217, 217, 217, nil, nil, nil, nil, nil, 217, 217, + 217, 217, 217, 217, 217, nil, nil, 217, nil, nil, + nil, nil, nil, nil, 217, nil, nil, 217, 217, 217, + 217, 217, 217, 217, 217, nil, 217, 217, 217, nil, + 217, 217, 217, 217, 217, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 217, nil, nil, 217, nil, nil, + 217, 217, nil, nil, 217, nil, nil, nil, nil, nil, + 217, nil, nil, nil, nil, nil, nil, nil, nil, 217, + nil, nil, nil, nil, 217, 217, 217, 217, nil, 217, + 217, 217, 217, nil, nil, nil, nil, 217, 217, nil, + nil, nil, 218, 218, 218, 217, 218, 217, 217, 217, + 218, 218, nil, nil, nil, 218, nil, 218, 218, 218, + 218, 218, 218, 218, nil, nil, nil, nil, nil, 218, + 218, 218, 218, 218, 218, 218, nil, nil, 218, nil, + nil, nil, nil, nil, nil, 218, nil, nil, 218, 218, + 218, 218, 218, 218, 218, 218, 218, 218, 218, 218, + nil, 218, 218, 218, 218, 218, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 218, nil, nil, 218, nil, + nil, 218, 218, nil, nil, 218, nil, 218, nil, 218, + nil, 218, nil, nil, 218, nil, nil, nil, nil, nil, + 218, nil, nil, nil, nil, 218, 218, 218, 218, nil, + 218, 218, 218, 218, nil, nil, nil, nil, 218, 218, + nil, nil, nil, 223, 223, 223, 218, 223, 218, 218, + 218, 223, 223, nil, nil, nil, 223, nil, 223, 223, + 223, 223, 223, 223, 223, nil, nil, nil, nil, nil, + 223, 223, 223, 223, 223, 223, 223, nil, nil, 223, + nil, nil, nil, nil, nil, nil, 223, nil, nil, 223, + 223, 223, 223, 223, 223, 223, 223, nil, 223, 223, + 223, nil, 223, 223, 223, 223, 223, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 223, nil, nil, 223, + nil, nil, 223, 223, nil, nil, 223, nil, nil, nil, + nil, nil, 223, nil, nil, nil, nil, nil, nil, nil, + nil, 223, nil, nil, nil, nil, 223, 223, 223, 223, + nil, 223, 223, 223, 223, nil, nil, nil, nil, 223, + 223, nil, nil, nil, 224, 224, 224, 223, 224, 223, + 223, 223, 224, 224, nil, nil, nil, 224, nil, 224, + 224, 224, 224, 224, 224, 224, nil, nil, nil, nil, + nil, 224, 224, 224, 224, 224, 224, 224, nil, nil, + 224, nil, nil, nil, nil, nil, nil, 224, nil, nil, + 224, 224, 224, 224, 224, 224, 224, 224, nil, 224, + 224, 224, nil, 224, 224, 224, 224, 224, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 224, nil, nil, + 224, nil, nil, 224, 224, nil, nil, 224, nil, nil, + nil, nil, nil, 224, nil, nil, nil, nil, nil, nil, + nil, nil, 224, nil, nil, nil, nil, 224, 224, 224, + 224, nil, 224, 224, 224, 224, nil, nil, nil, nil, + 224, 224, nil, nil, nil, 225, 225, 225, 224, 225, + 224, 224, 224, 225, 225, nil, nil, nil, 225, nil, + 225, 225, 225, 225, 225, 225, 225, nil, nil, nil, + nil, nil, 225, 225, 225, 225, 225, 225, 225, nil, + nil, 225, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 225, 225, 225, 225, 225, 225, 225, 225, nil, + 225, 225, 225, nil, 225, 225, 225, 225, 225, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 225, nil, + nil, 225, nil, nil, 225, 225, nil, nil, 225, nil, + nil, nil, nil, nil, 225, nil, nil, nil, nil, nil, + nil, nil, nil, 225, nil, nil, nil, nil, 225, 225, + 225, 225, nil, 225, 225, 225, 225, nil, nil, nil, + nil, 225, 225, 225, nil, nil, 236, 236, 236, 225, + 236, 225, 225, 225, 236, 236, nil, nil, nil, 236, + nil, 236, 236, 236, 236, 236, 236, 236, nil, nil, + nil, nil, nil, 236, 236, 236, 236, 236, 236, 236, + nil, nil, 236, nil, nil, nil, nil, nil, nil, 236, + nil, nil, 236, 236, 236, 236, 236, 236, 236, 236, + nil, 236, 236, 236, nil, 236, 236, 236, 236, 236, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 236, + nil, nil, 236, nil, nil, 236, 236, nil, nil, 236, + nil, nil, nil, nil, nil, 236, nil, nil, nil, nil, + nil, nil, nil, nil, 236, nil, nil, nil, nil, 236, + 236, 236, 236, nil, 236, 236, 236, 236, nil, nil, + nil, nil, 236, 236, nil, nil, nil, 239, 239, 239, + 236, 239, 236, 236, 236, 239, 239, nil, nil, nil, + 239, nil, 239, 239, 239, 239, 239, 239, 239, nil, + nil, nil, nil, nil, 239, 239, 239, 239, 239, 239, + 239, nil, nil, 239, nil, nil, nil, nil, nil, nil, + 239, nil, nil, 239, 239, 239, 239, 239, 239, 239, + 239, nil, 239, 239, 239, nil, 239, 239, 239, 239, + 239, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 239, nil, nil, 239, nil, nil, 239, 239, nil, nil, + 239, nil, nil, nil, nil, nil, 239, nil, nil, nil, + nil, nil, nil, nil, nil, 239, nil, nil, nil, nil, + 239, 239, 239, 239, nil, 239, 239, 239, 239, nil, + nil, nil, nil, 239, 239, nil, nil, nil, 240, 240, + 240, 239, 240, 239, 239, 239, 240, 240, nil, nil, + nil, 240, nil, 240, 240, 240, 240, 240, 240, 240, + nil, nil, nil, nil, nil, 240, 240, 240, 240, 240, + 240, 240, nil, nil, 240, nil, nil, nil, nil, nil, + nil, 240, nil, nil, 240, 240, 240, 240, 240, 240, + 240, 240, nil, 240, 240, 240, nil, 240, 240, 240, + 240, 240, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 240, nil, nil, 240, nil, nil, 240, 240, nil, + nil, 240, nil, nil, nil, nil, nil, 240, nil, nil, + nil, nil, nil, nil, nil, nil, 240, nil, nil, nil, + nil, 240, 240, 240, 240, nil, 240, 240, 240, 240, + nil, nil, nil, nil, 240, 240, nil, nil, nil, 241, + 241, 241, 240, 241, 240, 240, 240, 241, 241, nil, + nil, nil, 241, nil, 241, 241, 241, 241, 241, 241, + 241, nil, nil, nil, nil, nil, 241, 241, 241, 241, + 241, 241, 241, nil, nil, 241, nil, nil, nil, nil, + nil, nil, 241, nil, nil, 241, 241, 241, 241, 241, + 241, 241, 241, nil, 241, 241, 241, nil, 241, 241, + 241, 241, 241, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 241, nil, nil, 241, nil, nil, 241, 241, + nil, nil, 241, nil, nil, nil, nil, nil, 241, nil, + nil, nil, nil, nil, nil, nil, nil, 241, nil, nil, + nil, nil, 241, 241, 241, 241, nil, 241, 241, 241, + 241, nil, nil, nil, nil, 241, 241, nil, nil, nil, + 242, 242, 242, 241, 242, 241, 241, 241, 242, 242, + nil, nil, nil, 242, nil, 242, 242, 242, 242, 242, + 242, 242, nil, nil, nil, nil, nil, 242, 242, 242, + 242, 242, 242, 242, nil, nil, 242, nil, nil, nil, + nil, nil, nil, 242, nil, nil, 242, 242, 242, 242, + 242, 242, 242, 242, nil, 242, 242, 242, nil, 242, + 242, 242, 242, 242, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 242, nil, nil, 242, nil, nil, 242, + 242, nil, nil, 242, nil, nil, nil, nil, nil, 242, + nil, nil, nil, nil, nil, nil, nil, nil, 242, nil, + nil, nil, nil, 242, 242, 242, 242, nil, 242, 242, + 242, 242, nil, nil, nil, nil, 242, 242, nil, nil, + nil, 243, 243, 243, 242, 243, 242, 242, 242, 243, + 243, nil, nil, nil, 243, nil, 243, 243, 243, 243, + 243, 243, 243, nil, nil, nil, nil, nil, 243, 243, + 243, 243, 243, 243, 243, nil, nil, 243, nil, nil, + nil, nil, nil, nil, 243, nil, nil, 243, 243, 243, + 243, 243, 243, 243, 243, nil, 243, 243, 243, nil, + 243, 243, 243, 243, 243, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 243, nil, nil, 243, nil, nil, + 243, 243, nil, nil, 243, nil, nil, nil, nil, nil, + 243, nil, nil, nil, nil, nil, nil, nil, nil, 243, + nil, nil, nil, nil, 243, 243, 243, 243, nil, 243, + 243, 243, 243, nil, nil, nil, nil, 243, 243, nil, + nil, nil, 244, 244, 244, 243, 244, 243, 243, 243, + 244, 244, nil, nil, nil, 244, nil, 244, 244, 244, + 244, 244, 244, 244, nil, nil, nil, nil, nil, 244, + 244, 244, 244, 244, 244, 244, nil, nil, 244, nil, + nil, nil, nil, nil, nil, 244, nil, nil, 244, 244, + 244, 244, 244, 244, 244, 244, nil, 244, 244, 244, + nil, 244, 244, 244, 244, 244, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 244, nil, nil, 244, nil, + nil, 244, 244, nil, nil, 244, nil, nil, nil, nil, + nil, 244, nil, nil, nil, nil, nil, nil, nil, nil, + 244, nil, nil, nil, nil, 244, 244, 244, 244, nil, + 244, 244, 244, 244, nil, nil, nil, nil, 244, 244, + nil, nil, nil, 245, 245, 245, 244, 245, 244, 244, + 244, 245, 245, nil, nil, nil, 245, nil, 245, 245, + 245, 245, 245, 245, 245, nil, nil, nil, nil, nil, + 245, 245, 245, 245, 245, 245, 245, nil, nil, 245, + nil, nil, nil, nil, nil, nil, 245, nil, nil, 245, + 245, 245, 245, 245, 245, 245, 245, nil, 245, 245, + 245, nil, 245, 245, 245, 245, 245, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 245, nil, nil, 245, + nil, nil, 245, 245, nil, nil, 245, nil, nil, nil, + nil, nil, 245, nil, nil, nil, nil, nil, nil, nil, + nil, 245, nil, nil, nil, nil, 245, 245, 245, 245, + nil, 245, 245, 245, 245, nil, nil, nil, nil, 245, + 245, nil, nil, nil, 246, 246, 246, 245, 246, 245, + 245, 245, 246, 246, nil, nil, nil, 246, nil, 246, + 246, 246, 246, 246, 246, 246, nil, nil, nil, nil, + nil, 246, 246, 246, 246, 246, 246, 246, nil, nil, + 246, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 246, 246, 246, 246, 246, 246, 246, 246, nil, 246, + 246, 246, nil, 246, 246, 246, 246, 246, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 246, nil, nil, 246, 246, nil, nil, 246, nil, nil, + nil, nil, nil, 246, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, nil, nil, 246, 246, 246, + 246, nil, 246, 246, 246, 246, nil, nil, nil, nil, + 246, 246, nil, nil, nil, 247, 247, 247, 246, 247, + 246, 246, 246, 247, 247, nil, nil, nil, 247, nil, + 247, 247, 247, 247, 247, 247, 247, nil, nil, nil, + nil, nil, 247, 247, 247, 247, 247, 247, 247, nil, + nil, 247, nil, nil, nil, nil, nil, nil, 247, nil, + nil, 247, 247, 247, 247, 247, 247, 247, 247, nil, + 247, 247, 247, nil, 247, 247, 247, 247, 247, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 247, nil, + nil, 247, nil, nil, 247, 247, nil, nil, 247, nil, + nil, nil, nil, nil, 247, nil, nil, nil, nil, nil, + nil, nil, nil, 247, nil, nil, nil, nil, 247, 247, + 247, 247, nil, 247, 247, 247, 247, nil, nil, nil, + nil, 247, 247, nil, nil, nil, 248, 248, 248, 247, + 248, 247, 247, 247, 248, 248, nil, nil, nil, 248, + nil, 248, 248, 248, 248, 248, 248, 248, nil, nil, + nil, nil, nil, 248, 248, 248, 248, 248, 248, 248, + nil, nil, 248, nil, nil, nil, nil, nil, nil, 248, + nil, nil, 248, 248, 248, 248, 248, 248, 248, 248, + nil, 248, 248, 248, nil, 248, 248, 248, 248, 248, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 248, + nil, nil, 248, nil, nil, 248, 248, nil, nil, 248, + nil, nil, nil, nil, nil, 248, nil, nil, nil, nil, + nil, nil, nil, nil, 248, nil, nil, nil, nil, 248, + 248, 248, 248, nil, 248, 248, 248, 248, nil, nil, + nil, nil, 248, 248, nil, nil, nil, 249, 249, 249, + 248, 249, 248, 248, 248, 249, 249, nil, nil, nil, + 249, nil, 249, 249, 249, 249, 249, 249, 249, nil, + nil, nil, nil, nil, 249, 249, 249, 249, 249, 249, + 249, nil, nil, 249, nil, nil, nil, nil, nil, nil, + 249, nil, nil, 249, 249, 249, 249, 249, 249, 249, + 249, nil, 249, 249, 249, nil, 249, 249, 249, 249, + 249, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 249, nil, nil, 249, nil, nil, 249, 249, nil, nil, + 249, nil, nil, nil, nil, nil, 249, nil, nil, nil, + nil, nil, nil, nil, nil, 249, nil, nil, nil, nil, + 249, 249, 249, 249, nil, 249, 249, 249, 249, nil, + nil, nil, nil, 249, 249, nil, nil, nil, 250, 250, + 250, 249, 250, 249, 249, 249, 250, 250, nil, nil, + nil, 250, nil, 250, 250, 250, 250, 250, 250, 250, + nil, nil, nil, nil, nil, 250, 250, 250, 250, 250, + 250, 250, nil, nil, 250, nil, nil, nil, nil, nil, + nil, 250, nil, nil, 250, 250, 250, 250, 250, 250, + 250, 250, nil, 250, 250, 250, nil, 250, 250, 250, + 250, 250, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 250, nil, nil, 250, nil, nil, 250, 250, nil, + nil, 250, nil, nil, nil, nil, nil, 250, nil, nil, + nil, nil, nil, nil, nil, nil, 250, nil, nil, nil, + nil, 250, 250, 250, 250, nil, 250, 250, 250, 250, + nil, nil, nil, nil, 250, 250, nil, nil, nil, 251, + 251, 251, 250, 251, 250, 250, 250, 251, 251, nil, + nil, nil, 251, nil, 251, 251, 251, 251, 251, 251, + 251, nil, nil, nil, nil, nil, 251, 251, 251, 251, + 251, 251, 251, nil, nil, 251, nil, nil, nil, nil, + nil, nil, 251, nil, nil, 251, 251, 251, 251, 251, + 251, 251, 251, nil, 251, 251, 251, nil, 251, 251, + 251, 251, 251, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, 251, nil, nil, 251, 251, + nil, nil, 251, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 251, 251, 251, 251, nil, 251, 251, 251, + 251, nil, nil, nil, nil, 251, 251, nil, nil, nil, + 252, 252, 252, 251, 252, 251, 251, 251, 252, 252, + nil, nil, nil, 252, nil, 252, 252, 252, 252, 252, + 252, 252, nil, nil, nil, nil, nil, 252, 252, 252, + 252, 252, 252, 252, nil, nil, 252, nil, nil, nil, + nil, nil, nil, 252, nil, nil, 252, 252, 252, 252, + 252, 252, 252, 252, nil, 252, 252, 252, nil, 252, + 252, 252, 252, 252, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 252, nil, nil, 252, nil, nil, 252, + 252, nil, nil, 252, nil, nil, nil, nil, nil, 252, + nil, nil, nil, nil, nil, nil, nil, nil, 252, nil, + nil, nil, nil, 252, 252, 252, 252, nil, 252, 252, + 252, 252, nil, nil, nil, nil, 252, 252, nil, nil, + nil, 253, 253, 253, 252, 253, 252, 252, 252, 253, + 253, nil, nil, nil, 253, nil, 253, 253, 253, 253, + 253, 253, 253, nil, nil, nil, nil, nil, 253, 253, + 253, 253, 253, 253, 253, nil, nil, 253, nil, nil, + nil, nil, nil, nil, 253, nil, nil, 253, 253, 253, + 253, 253, 253, 253, 253, nil, 253, 253, 253, nil, + 253, 253, 253, 253, 253, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 253, nil, nil, 253, nil, nil, + 253, 253, nil, nil, 253, nil, nil, nil, nil, nil, + 253, nil, nil, nil, nil, nil, nil, nil, nil, 253, + nil, nil, nil, nil, 253, 253, 253, 253, nil, 253, + 253, 253, 253, nil, nil, nil, nil, 253, 253, nil, + nil, nil, 254, 254, 254, 253, 254, 253, 253, 253, + 254, 254, nil, nil, nil, 254, nil, 254, 254, 254, + 254, 254, 254, 254, nil, nil, nil, nil, nil, 254, + 254, 254, 254, 254, 254, 254, nil, nil, 254, nil, + nil, nil, nil, nil, nil, 254, nil, nil, 254, 254, + 254, 254, 254, 254, 254, 254, nil, 254, 254, 254, + nil, 254, 254, 254, 254, 254, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 254, nil, nil, 254, nil, + nil, 254, 254, nil, nil, 254, nil, nil, nil, nil, + nil, 254, nil, nil, nil, nil, nil, nil, nil, nil, + 254, nil, nil, nil, nil, 254, 254, 254, 254, nil, + 254, 254, 254, 254, nil, nil, nil, nil, 254, 254, + nil, nil, nil, 255, 255, 255, 254, 255, 254, 254, + 254, 255, 255, nil, nil, nil, 255, nil, 255, 255, + 255, 255, 255, 255, 255, nil, nil, nil, nil, nil, + 255, 255, 255, 255, 255, 255, 255, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 255, nil, nil, 255, + 255, 255, 255, 255, 255, 255, 255, nil, 255, 255, + 255, nil, 255, 255, 255, 255, 255, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 255, nil, nil, 255, + nil, nil, 255, 255, nil, nil, 255, nil, nil, nil, + nil, nil, 255, nil, nil, nil, nil, nil, nil, nil, + nil, 255, nil, nil, nil, nil, 255, 255, 255, 255, + nil, 255, 255, 255, 255, nil, nil, nil, nil, 255, + 255, nil, nil, nil, 256, 256, 256, 255, 256, 255, + 255, 255, 256, 256, nil, nil, nil, 256, nil, 256, + 256, 256, 256, 256, 256, 256, nil, nil, nil, nil, + nil, 256, 256, 256, 256, 256, 256, 256, nil, nil, + 256, nil, nil, nil, nil, nil, nil, 256, nil, nil, + 256, 256, 256, 256, 256, 256, 256, 256, nil, 256, + 256, 256, nil, 256, 256, 256, 256, 256, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 256, nil, nil, + 256, nil, nil, 256, 256, nil, nil, 256, nil, nil, + nil, nil, nil, 256, nil, nil, nil, nil, nil, nil, + nil, nil, 256, nil, nil, nil, nil, 256, 256, 256, + 256, nil, 256, 256, 256, 256, nil, nil, nil, nil, + 256, 256, nil, nil, nil, 257, 257, 257, 256, 257, + 256, 256, 256, 257, 257, nil, nil, nil, 257, nil, + 257, 257, 257, 257, 257, 257, 257, nil, nil, nil, + nil, nil, 257, 257, 257, 257, 257, 257, 257, nil, + nil, 257, nil, nil, nil, nil, nil, nil, 257, nil, + nil, 257, 257, 257, 257, 257, 257, 257, 257, nil, + 257, 257, 257, nil, 257, 257, 257, 257, 257, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 257, nil, + nil, 257, nil, nil, 257, 257, nil, nil, 257, nil, + nil, nil, nil, nil, 257, nil, nil, nil, nil, nil, + nil, nil, nil, 257, nil, nil, nil, nil, 257, 257, + 257, 257, nil, 257, 257, 257, 257, nil, nil, nil, + nil, 257, 257, nil, nil, nil, 258, 258, 258, 257, + 258, 257, 257, 257, 258, 258, nil, nil, nil, 258, + nil, 258, 258, 258, 258, 258, 258, 258, nil, nil, + nil, nil, nil, 258, 258, 258, 258, 258, 258, 258, + nil, nil, 258, nil, nil, nil, nil, nil, nil, 258, + nil, nil, 258, 258, 258, 258, 258, 258, 258, 258, + nil, 258, 258, 258, nil, 258, 258, 258, 258, 258, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 258, + nil, nil, 258, nil, nil, 258, 258, nil, nil, 258, + nil, nil, nil, nil, nil, 258, nil, nil, nil, nil, + nil, nil, nil, nil, 258, nil, nil, nil, nil, 258, + 258, 258, 258, nil, 258, 258, 258, 258, nil, nil, + nil, nil, 258, 258, nil, nil, nil, 259, 259, 259, + 258, 259, 258, 258, 258, 259, 259, nil, nil, nil, + 259, nil, 259, 259, 259, 259, 259, 259, 259, nil, + nil, nil, nil, nil, 259, 259, 259, 259, 259, 259, + 259, nil, nil, 259, nil, nil, nil, nil, nil, nil, + 259, nil, nil, 259, 259, 259, 259, 259, 259, 259, + 259, nil, 259, 259, 259, nil, 259, 259, 259, 259, + 259, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 259, nil, nil, 259, nil, nil, 259, 259, nil, nil, + 259, nil, nil, nil, nil, nil, 259, nil, nil, nil, + nil, nil, nil, nil, nil, 259, nil, nil, nil, nil, + 259, 259, 259, 259, nil, 259, 259, 259, 259, nil, + nil, nil, nil, 259, 259, nil, nil, nil, 260, 260, + 260, 259, 260, 259, 259, 259, 260, 260, nil, nil, + nil, 260, nil, 260, 260, 260, 260, 260, 260, 260, + nil, nil, nil, nil, nil, 260, 260, 260, 260, 260, + 260, 260, nil, nil, 260, nil, nil, nil, nil, nil, + nil, 260, nil, nil, 260, 260, 260, 260, 260, 260, + 260, 260, nil, 260, 260, 260, nil, 260, 260, 260, + 260, 260, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 260, nil, nil, 260, nil, nil, 260, 260, nil, + nil, 260, nil, nil, nil, nil, nil, 260, nil, nil, + nil, nil, nil, nil, nil, nil, 260, nil, nil, nil, + nil, 260, 260, 260, 260, nil, 260, 260, 260, 260, + nil, nil, nil, nil, 260, 260, nil, nil, nil, 265, + 265, 265, 260, 265, 260, 260, 260, 265, 265, nil, + nil, nil, 265, nil, 265, 265, 265, 265, 265, 265, + 265, nil, nil, nil, nil, nil, 265, 265, 265, 265, + 265, 265, 265, nil, nil, 265, nil, nil, nil, nil, + nil, nil, 265, nil, nil, 265, 265, 265, 265, 265, + 265, 265, 265, nil, 265, 265, 265, nil, 265, 265, + 265, 265, 265, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 265, nil, nil, 265, nil, nil, 265, 265, + nil, nil, 265, nil, nil, nil, nil, nil, 265, nil, + nil, nil, nil, nil, nil, nil, nil, 265, nil, nil, + nil, nil, 265, 265, 265, 265, nil, 265, 265, 265, + 265, nil, nil, nil, nil, 265, 265, nil, nil, nil, + 272, 272, 272, 265, 272, 265, 265, 265, 272, 272, + nil, nil, nil, 272, nil, 272, 272, 272, 272, 272, + 272, 272, nil, nil, nil, nil, nil, 272, 272, 272, + 272, 272, 272, 272, nil, nil, 272, nil, nil, nil, + nil, nil, nil, 272, nil, nil, 272, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, nil, 272, + 272, 272, 272, 272, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 272, nil, nil, 272, nil, nil, 272, + 272, nil, nil, 272, nil, 272, nil, 272, nil, 272, + nil, nil, 272, nil, nil, nil, nil, nil, 272, nil, + nil, nil, nil, 272, 272, 272, 272, nil, 272, 272, + 272, 272, nil, nil, nil, nil, 272, 272, nil, nil, + nil, 273, 273, 273, 272, 273, 272, 272, 272, 273, + 273, nil, nil, nil, 273, nil, 273, 273, 273, 273, + 273, 273, 273, nil, nil, nil, nil, nil, 273, 273, + 273, 273, 273, 273, 273, nil, nil, 273, nil, nil, + nil, nil, nil, nil, 273, nil, nil, 273, 273, 273, + 273, 273, 273, 273, 273, 273, 273, 273, 273, nil, + 273, 273, 273, 273, 273, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 273, nil, nil, 273, nil, nil, + 273, 273, nil, nil, 273, nil, 273, nil, 273, nil, + 273, nil, nil, 273, nil, nil, nil, nil, nil, 273, + nil, nil, nil, nil, 273, 273, 273, 273, nil, 273, + 273, 273, 273, nil, nil, nil, nil, 273, 273, nil, + nil, nil, 281, 281, 281, 273, 281, 273, 273, 273, + 281, 281, nil, nil, nil, 281, nil, 281, 281, 281, + 281, 281, 281, 281, nil, nil, nil, nil, nil, 281, + 281, 281, 281, 281, 281, 281, nil, nil, 281, nil, + nil, nil, nil, nil, nil, 281, nil, nil, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + nil, 281, 281, 281, 281, 281, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 281, nil, nil, 281, nil, + nil, 281, 281, nil, nil, 281, nil, 281, nil, 281, + nil, 281, nil, nil, 281, nil, nil, nil, nil, nil, + 281, nil, nil, nil, nil, 281, 281, 281, 281, nil, + 281, 281, 281, 281, nil, nil, nil, nil, 281, 281, + 281, nil, nil, 288, 288, 288, 281, 288, 281, 281, + 281, 288, 288, nil, nil, nil, 288, nil, 288, 288, + 288, 288, 288, 288, 288, nil, nil, nil, nil, nil, + 288, 288, 288, 288, 288, 288, 288, nil, nil, 288, + nil, nil, nil, nil, nil, nil, 288, nil, nil, 288, + 288, 288, 288, 288, 288, 288, 288, nil, 288, 288, + 288, nil, 288, 288, 288, 288, 288, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 288, nil, nil, 288, + nil, nil, 288, 288, nil, nil, 288, nil, nil, nil, + nil, nil, 288, nil, nil, nil, nil, nil, nil, nil, + nil, 288, nil, nil, nil, nil, 288, 288, 288, 288, + nil, 288, 288, 288, 288, nil, nil, nil, nil, 288, + 288, nil, nil, nil, 290, 290, 290, 288, 290, 288, + 288, 288, 290, 290, nil, nil, nil, 290, nil, 290, + 290, 290, 290, 290, 290, 290, nil, nil, nil, nil, + nil, 290, 290, 290, 290, 290, 290, 290, nil, nil, + 290, nil, nil, nil, nil, nil, nil, 290, nil, nil, + 290, 290, 290, 290, 290, 290, 290, 290, nil, 290, + 290, 290, nil, 290, 290, 290, 290, 290, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 290, nil, nil, + 290, nil, nil, 290, 290, nil, nil, 290, nil, nil, + nil, nil, nil, 290, nil, nil, nil, nil, nil, nil, + nil, nil, 290, nil, nil, nil, nil, 290, 290, 290, + 290, nil, 290, 290, 290, 290, nil, nil, nil, nil, + 290, 290, nil, nil, nil, 293, 293, 293, 290, 293, + 290, 290, 290, 293, 293, nil, nil, nil, 293, nil, + 293, 293, 293, 293, 293, 293, 293, nil, nil, nil, + nil, nil, 293, 293, 293, 293, 293, 293, 293, nil, + nil, 293, nil, nil, nil, nil, nil, nil, 293, nil, + nil, 293, 293, 293, 293, 293, 293, 293, 293, nil, + 293, 293, 293, nil, 293, 293, 293, 293, 293, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 293, nil, + nil, 293, nil, nil, 293, 293, nil, nil, 293, nil, + nil, nil, nil, nil, 293, nil, nil, nil, nil, nil, + nil, nil, nil, 293, nil, nil, nil, nil, 293, 293, + 293, 293, nil, 293, 293, 293, 293, nil, nil, nil, + nil, 293, 293, nil, nil, nil, 294, 294, 294, 293, + 294, 293, 293, 293, 294, 294, nil, nil, nil, 294, + nil, 294, 294, 294, 294, 294, 294, 294, nil, nil, + nil, nil, nil, 294, 294, 294, 294, 294, 294, 294, + nil, nil, 294, nil, nil, nil, nil, nil, nil, 294, + nil, nil, 294, 294, 294, 294, 294, 294, 294, 294, + nil, 294, 294, 294, nil, 294, 294, 294, 294, 294, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 294, + nil, nil, 294, nil, nil, 294, 294, nil, nil, 294, + nil, nil, nil, nil, nil, 294, nil, nil, nil, nil, + nil, nil, nil, nil, 294, nil, nil, nil, nil, 294, + 294, 294, 294, nil, 294, 294, 294, 294, nil, nil, + nil, nil, 294, 294, nil, nil, nil, nil, nil, nil, + 294, nil, 294, 294, 294, 299, 299, 299, 299, 299, + nil, nil, nil, 299, 299, nil, nil, nil, 299, nil, + 299, 299, 299, 299, 299, 299, 299, nil, nil, nil, + nil, nil, 299, 299, 299, 299, 299, 299, 299, nil, + nil, 299, nil, nil, nil, nil, nil, 299, 299, nil, + 299, 299, 299, 299, 299, 299, 299, 299, 299, nil, + 299, 299, 299, nil, 299, 299, 299, 299, 299, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 299, nil, + nil, 299, nil, nil, 299, 299, nil, nil, 299, nil, + 299, nil, nil, nil, 299, nil, nil, nil, nil, nil, + nil, nil, nil, 299, nil, nil, nil, nil, 299, 299, + 299, 299, nil, 299, 299, 299, 299, nil, nil, nil, + nil, 299, 299, nil, nil, nil, 307, 307, 307, 299, + 307, 299, 299, 299, 307, 307, nil, nil, nil, 307, + nil, 307, 307, 307, 307, 307, 307, 307, nil, nil, + nil, nil, nil, 307, 307, 307, 307, 307, 307, 307, + nil, nil, 307, nil, nil, nil, nil, nil, nil, 307, + nil, nil, 307, 307, 307, 307, 307, 307, 307, 307, + nil, 307, 307, 307, nil, 307, 307, nil, nil, 307, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 307, + nil, nil, 307, nil, nil, 307, 307, nil, nil, 307, + nil, nil, 939, nil, 939, 939, 939, 939, 939, nil, + nil, nil, nil, nil, nil, nil, nil, 939, nil, 307, + 307, 307, 307, nil, 307, 307, 307, 307, nil, nil, + nil, nil, 307, 307, nil, nil, nil, 307, nil, 939, + 307, nil, 307, 307, 307, 324, 324, 324, nil, 324, + 939, 939, nil, 324, 324, 939, nil, nil, 324, nil, + 324, 324, 324, 324, 324, 324, 324, nil, nil, nil, + nil, nil, 324, 324, 324, 324, 324, 324, 324, nil, + nil, 324, nil, nil, nil, nil, nil, nil, 324, nil, + nil, 324, 324, 324, 324, 324, 324, 324, 324, nil, + 324, 324, 324, nil, 324, 324, nil, nil, 324, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 324, nil, + nil, 324, nil, nil, 324, 324, nil, nil, 324, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 324, 324, + 324, 324, nil, 324, 324, 324, 324, nil, nil, nil, + nil, 324, 324, nil, nil, nil, 331, 331, 331, 324, + 331, 324, 324, 324, 331, 331, nil, nil, nil, 331, + nil, 331, 331, 331, 331, 331, 331, 331, nil, nil, + nil, nil, nil, 331, 331, 331, 331, 331, 331, 331, + nil, nil, 331, nil, nil, nil, nil, nil, nil, 331, + nil, nil, 331, 331, 331, 331, 331, 331, 331, 331, + nil, 331, 331, 331, nil, 331, 331, 331, 331, 331, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 331, + nil, nil, 331, nil, nil, 331, 331, nil, nil, 331, + nil, nil, nil, nil, nil, 331, nil, nil, nil, nil, + nil, nil, nil, nil, 331, nil, nil, nil, nil, 331, + 331, 331, 331, nil, 331, 331, 331, 331, nil, nil, + nil, nil, 331, 331, nil, nil, nil, 333, 333, 333, + 331, 333, 331, 331, 331, 333, 333, nil, nil, nil, + 333, nil, 333, 333, 333, 333, 333, 333, 333, nil, + nil, nil, nil, nil, 333, 333, 333, 333, 333, 333, + 333, nil, nil, 333, nil, nil, nil, nil, nil, nil, + 333, nil, nil, 333, 333, 333, 333, 333, 333, 333, + 333, nil, 333, 333, 333, nil, 333, 333, 333, 333, + 333, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 333, nil, nil, 333, 333, nil, 333, 333, nil, nil, + 333, nil, nil, nil, nil, nil, 333, nil, nil, nil, + nil, nil, nil, nil, nil, 333, nil, nil, nil, nil, + 333, 333, 333, 333, nil, 333, 333, 333, 333, nil, + nil, nil, nil, 333, 333, nil, nil, nil, 349, 349, + 349, 333, 349, 333, 333, 333, 349, 349, nil, nil, + nil, 349, nil, 349, 349, 349, 349, 349, 349, 349, + nil, nil, nil, nil, nil, 349, 349, 349, 349, 349, + 349, 349, nil, nil, 349, nil, nil, nil, nil, nil, + nil, 349, nil, nil, 349, 349, 349, 349, 349, 349, + 349, 349, nil, 349, 349, 349, nil, 349, 349, 349, + 349, 349, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 349, nil, nil, 349, nil, nil, 349, 349, nil, + nil, 349, nil, nil, nil, nil, nil, 349, nil, nil, + nil, nil, nil, nil, nil, nil, 349, nil, nil, nil, + nil, 349, 349, 349, 349, nil, 349, 349, 349, 349, + nil, nil, nil, nil, 349, 349, nil, nil, nil, 370, + 370, 370, 349, 370, 349, 349, 349, 370, 370, nil, + nil, nil, 370, nil, 370, 370, 370, 370, 370, 370, + 370, nil, nil, nil, nil, nil, 370, 370, 370, 370, + 370, 370, 370, nil, nil, 370, nil, nil, nil, nil, + nil, nil, 370, nil, nil, 370, 370, 370, 370, 370, + 370, 370, 370, nil, 370, 370, 370, nil, 370, 370, + 370, 370, 370, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 370, nil, nil, 370, nil, nil, 370, 370, + nil, nil, 370, nil, nil, nil, nil, nil, 370, nil, + nil, nil, nil, nil, nil, nil, nil, 370, nil, nil, + nil, nil, 370, 370, 370, 370, nil, 370, 370, 370, + 370, nil, nil, nil, nil, 370, 370, nil, nil, nil, + 386, 386, 386, 370, 386, 370, 370, 370, 386, 386, + nil, nil, nil, 386, nil, 386, 386, 386, 386, 386, + 386, 386, nil, nil, nil, nil, nil, 386, 386, 386, + 386, 386, 386, 386, nil, nil, 386, nil, nil, nil, + nil, nil, nil, 386, nil, nil, 386, 386, 386, 386, + 386, 386, 386, 386, nil, 386, 386, 386, nil, 386, + 386, 386, 386, 386, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 386, nil, nil, 386, nil, nil, 386, + 386, nil, nil, 386, nil, nil, nil, nil, nil, 386, + nil, nil, nil, nil, nil, nil, nil, nil, 386, nil, + nil, nil, nil, 386, 386, 386, 386, nil, 386, 386, + 386, 386, nil, nil, nil, nil, 386, 386, nil, nil, + nil, 414, 414, 414, 386, 414, 386, 386, 386, 414, + 414, nil, nil, nil, 414, nil, 414, 414, 414, 414, + 414, 414, 414, nil, nil, nil, nil, nil, 414, 414, + 414, 414, 414, 414, 414, nil, nil, 414, nil, nil, + nil, nil, nil, nil, 414, nil, nil, 414, 414, 414, + 414, 414, 414, 414, 414, nil, 414, 414, 414, nil, + 414, 414, 414, 414, 414, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 414, nil, nil, 414, nil, nil, + 414, 414, nil, nil, 414, nil, nil, nil, nil, nil, + 414, nil, nil, nil, nil, nil, nil, nil, nil, 414, + nil, nil, nil, nil, 414, 414, 414, 414, nil, 414, + 414, 414, 414, nil, nil, nil, nil, 414, 414, nil, + nil, nil, 457, 457, 457, 414, 457, 414, 414, 414, + 457, 457, nil, nil, nil, 457, nil, 457, 457, 457, + 457, 457, 457, 457, nil, nil, nil, nil, nil, 457, + 457, 457, 457, 457, 457, 457, nil, nil, 457, nil, + nil, nil, nil, nil, nil, 457, nil, nil, 457, 457, + 457, 457, 457, 457, 457, 457, 457, 457, 457, 457, + nil, 457, 457, 457, 457, 457, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 457, nil, nil, 457, nil, + nil, 457, 457, nil, nil, 457, nil, 457, nil, 457, + nil, 457, nil, nil, 457, nil, nil, nil, nil, nil, + 457, nil, nil, nil, nil, 457, 457, 457, 457, nil, + 457, 457, 457, 457, nil, nil, nil, nil, 457, 457, + nil, nil, nil, 459, 459, 459, 457, 459, 457, 457, + 457, 459, 459, nil, nil, nil, 459, nil, 459, 459, + 459, 459, 459, 459, 459, nil, nil, nil, nil, nil, + 459, 459, 459, 459, 459, 459, 459, nil, nil, 459, + nil, nil, nil, nil, nil, nil, 459, nil, nil, 459, + 459, 459, 459, 459, 459, 459, 459, nil, 459, 459, + 459, nil, 459, 459, 459, 459, 459, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 459, nil, nil, 459, + nil, nil, 459, 459, nil, nil, 459, nil, nil, nil, + nil, nil, 459, nil, nil, nil, nil, nil, nil, nil, + nil, 459, nil, nil, nil, nil, 459, 459, 459, 459, + nil, 459, 459, 459, 459, nil, nil, nil, nil, 459, + 459, nil, nil, nil, 460, 460, 460, 459, 460, 459, + 459, 459, 460, 460, nil, nil, nil, 460, nil, 460, + 460, 460, 460, 460, 460, 460, nil, nil, nil, nil, + nil, 460, 460, 460, 460, 460, 460, 460, nil, nil, + 460, nil, nil, nil, nil, nil, nil, 460, nil, nil, + 460, 460, 460, 460, 460, 460, 460, 460, nil, 460, + 460, 460, nil, 460, 460, 460, 460, 460, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 460, nil, nil, + 460, nil, nil, 460, 460, nil, nil, 460, nil, nil, + nil, nil, nil, 460, nil, nil, nil, nil, nil, nil, + nil, nil, 460, nil, nil, nil, nil, 460, 460, 460, + 460, nil, 460, 460, 460, 460, nil, nil, nil, nil, + 460, 460, nil, nil, nil, 461, 461, 461, 460, 461, + 460, 460, 460, 461, 461, nil, nil, nil, 461, nil, + 461, 461, 461, 461, 461, 461, 461, nil, nil, nil, + nil, nil, 461, 461, 461, 461, 461, 461, 461, nil, + nil, 461, nil, nil, nil, nil, nil, nil, 461, nil, + nil, 461, 461, 461, 461, 461, 461, 461, 461, nil, + 461, 461, 461, nil, 461, 461, 461, 461, 461, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 461, nil, + nil, 461, nil, nil, 461, 461, nil, nil, 461, nil, + nil, nil, nil, nil, 461, nil, nil, nil, nil, nil, + nil, nil, nil, 461, nil, nil, nil, nil, 461, 461, + 461, 461, nil, 461, 461, 461, 461, nil, nil, nil, + nil, 461, 461, nil, nil, nil, 498, 498, 498, 461, + 498, 461, 461, 461, 498, 498, nil, nil, nil, 498, + nil, 498, 498, 498, 498, 498, 498, 498, nil, nil, + nil, nil, nil, 498, 498, 498, 498, 498, 498, 498, + nil, nil, 498, nil, nil, nil, nil, nil, nil, 498, + nil, nil, 498, 498, 498, 498, 498, 498, 498, 498, + 498, 498, 498, 498, nil, 498, 498, 498, 498, 498, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 498, + nil, nil, 498, nil, nil, 498, 498, nil, nil, 498, + nil, 498, nil, 498, nil, 498, nil, nil, 498, nil, + nil, nil, nil, nil, 498, nil, nil, nil, nil, 498, + 498, 498, 498, nil, 498, 498, 498, 498, nil, nil, + nil, nil, 498, 498, nil, nil, nil, 500, 500, 500, + 498, 500, 498, 498, 498, 500, 500, nil, nil, nil, + 500, nil, 500, 500, 500, 500, 500, 500, 500, nil, + nil, nil, nil, nil, 500, 500, 500, 500, 500, 500, + 500, nil, nil, 500, nil, nil, nil, nil, nil, nil, + 500, nil, nil, 500, 500, 500, 500, 500, 500, 500, + 500, 500, 500, 500, 500, nil, 500, 500, 500, 500, + 500, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 500, nil, nil, 500, nil, nil, 500, 500, nil, nil, + 500, nil, nil, nil, 500, nil, 500, nil, nil, 500, + nil, nil, nil, nil, nil, 500, nil, nil, nil, nil, + 500, 500, 500, 500, nil, 500, 500, 500, 500, nil, + nil, nil, nil, 500, 500, nil, nil, nil, 502, 502, + 502, 500, 502, 500, 500, 500, 502, 502, nil, nil, + nil, 502, nil, 502, 502, 502, 502, 502, 502, 502, + nil, nil, nil, nil, nil, 502, 502, 502, 502, 502, + 502, 502, nil, nil, 502, nil, nil, nil, nil, nil, + nil, 502, nil, nil, 502, 502, 502, 502, 502, 502, + 502, 502, nil, 502, 502, 502, nil, 502, 502, 502, + 502, 502, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 502, nil, nil, 502, nil, nil, 502, 502, nil, + nil, 502, nil, nil, nil, nil, nil, 502, nil, nil, + nil, nil, nil, nil, nil, nil, 502, nil, nil, nil, + nil, 502, 502, 502, 502, nil, 502, 502, 502, 502, + nil, nil, nil, nil, 502, 502, nil, nil, nil, nil, + nil, nil, 502, nil, 502, 502, 502, 508, 508, 508, + 508, 508, nil, nil, nil, 508, 508, nil, nil, nil, + 508, nil, 508, 508, 508, 508, 508, 508, 508, nil, + nil, nil, nil, nil, 508, 508, 508, 508, 508, 508, + 508, nil, nil, 508, nil, nil, nil, nil, nil, 508, + 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, + 508, nil, 508, 508, 508, nil, 508, 508, 508, 508, + 508, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 508, nil, nil, 508, nil, nil, 508, 508, nil, nil, + 508, nil, 508, nil, nil, nil, 508, nil, nil, nil, + nil, nil, nil, nil, nil, 508, nil, nil, nil, nil, + 508, 508, 508, 508, nil, 508, 508, 508, 508, nil, + nil, nil, nil, 508, 508, nil, nil, nil, nil, nil, + 508, 508, nil, 508, 508, 508, 516, 516, 516, nil, + 516, nil, nil, nil, 516, 516, nil, nil, nil, 516, + nil, 516, 516, 516, 516, 516, 516, 516, nil, nil, + nil, nil, nil, 516, 516, 516, 516, 516, 516, 516, + nil, nil, 516, nil, nil, nil, nil, nil, nil, 516, + nil, nil, 516, 516, 516, 516, 516, 516, 516, 516, + nil, 516, 516, 516, nil, 516, 516, nil, nil, 516, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 516, + nil, nil, 516, nil, nil, 516, 516, nil, nil, 516, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 516, + 516, 516, 516, nil, 516, 516, 516, 516, nil, nil, + nil, nil, 516, 516, nil, nil, nil, 518, 518, 518, + 516, 518, 516, 516, 516, 518, 518, nil, nil, nil, + 518, nil, 518, 518, 518, 518, 518, 518, 518, nil, + nil, nil, nil, nil, 518, 518, 518, 518, 518, 518, + 518, nil, nil, 518, nil, nil, nil, nil, nil, nil, + 518, nil, nil, 518, 518, 518, 518, 518, 518, 518, + 518, 518, 518, 518, 518, nil, 518, 518, 518, 518, + 518, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 518, nil, nil, 518, nil, nil, 518, 518, nil, nil, + 518, nil, 518, nil, 518, nil, 518, nil, nil, 518, + nil, nil, nil, nil, nil, 518, nil, nil, nil, nil, + 518, 518, 518, 518, nil, 518, 518, 518, 518, nil, + nil, nil, nil, 518, 518, nil, nil, nil, 524, 524, + 524, 518, 524, 518, 518, 518, 524, 524, nil, nil, + nil, 524, nil, 524, 524, 524, 524, 524, 524, 524, + nil, nil, nil, nil, nil, 524, 524, 524, 524, 524, + 524, 524, nil, nil, 524, nil, nil, nil, nil, nil, + nil, 524, nil, nil, 524, 524, 524, 524, 524, 524, + 524, 524, nil, 524, 524, 524, nil, 524, 524, nil, + nil, 524, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 524, nil, nil, 524, nil, nil, 524, 524, nil, + nil, 524, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 524, 524, 524, 524, nil, 524, 524, 524, 524, + nil, nil, nil, nil, 524, 524, nil, nil, nil, 527, + 527, 527, 524, 527, 524, 524, 524, 527, 527, nil, + nil, nil, 527, nil, 527, 527, 527, 527, 527, 527, + 527, nil, nil, nil, nil, nil, 527, 527, 527, 527, + 527, 527, 527, nil, nil, 527, nil, nil, nil, nil, + nil, nil, 527, nil, nil, 527, 527, 527, 527, 527, + 527, 527, 527, nil, 527, 527, 527, nil, 527, 527, + 527, 527, 527, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 527, nil, nil, 527, nil, nil, 527, 527, + nil, nil, 527, nil, nil, nil, nil, nil, 527, nil, + nil, nil, nil, nil, nil, nil, nil, 527, nil, nil, + nil, nil, 527, 527, 527, 527, nil, 527, 527, 527, + 527, nil, nil, nil, nil, 527, 527, nil, nil, nil, + 528, 528, 528, 527, 528, 527, 527, 527, 528, 528, + nil, nil, nil, 528, nil, 528, 528, 528, 528, 528, + 528, 528, nil, nil, nil, nil, nil, 528, 528, 528, + 528, 528, 528, 528, nil, nil, 528, nil, nil, nil, + nil, nil, nil, 528, nil, nil, 528, 528, 528, 528, + 528, 528, 528, 528, nil, 528, 528, 528, nil, 528, + 528, 528, 528, 528, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 528, nil, nil, 528, nil, nil, 528, + 528, nil, nil, 528, nil, nil, nil, nil, nil, 528, + nil, nil, nil, nil, nil, nil, nil, nil, 528, nil, + nil, nil, nil, 528, 528, 528, 528, nil, 528, 528, + 528, 528, nil, nil, nil, nil, 528, 528, nil, nil, + nil, 533, 533, 533, 528, 533, 528, 528, 528, 533, + 533, nil, nil, nil, 533, nil, 533, 533, 533, 533, + 533, 533, 533, nil, nil, nil, nil, nil, 533, 533, + 533, 533, 533, 533, 533, nil, nil, 533, nil, nil, + nil, nil, nil, nil, 533, nil, nil, 533, 533, 533, + 533, 533, 533, 533, 533, nil, 533, 533, 533, nil, + 533, 533, 533, 533, 533, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 533, nil, nil, 533, nil, nil, + 533, 533, nil, nil, 533, nil, nil, nil, nil, nil, + 533, nil, nil, nil, nil, nil, nil, nil, nil, 533, + nil, nil, nil, nil, 533, 533, 533, 533, nil, 533, + 533, 533, 533, nil, nil, nil, nil, 533, 533, nil, + nil, nil, 539, 539, 539, 533, 539, 533, 533, 533, + 539, 539, nil, nil, nil, 539, nil, 539, 539, 539, + 539, 539, 539, 539, nil, nil, nil, nil, nil, 539, + 539, 539, 539, 539, 539, 539, nil, nil, 539, nil, + nil, nil, nil, nil, nil, 539, nil, nil, 539, 539, + 539, 539, 539, 539, 539, 539, 539, 539, 539, 539, + nil, 539, 539, 539, 539, 539, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 539, nil, nil, 539, nil, + nil, 539, 539, nil, nil, 539, nil, 539, nil, nil, + nil, 539, nil, nil, 539, nil, nil, nil, nil, nil, + 539, nil, nil, nil, nil, 539, 539, 539, 539, nil, + 539, 539, 539, 539, nil, nil, nil, nil, 539, 539, + nil, nil, nil, 542, 542, 542, 539, 542, 539, 539, + 539, 542, 542, nil, nil, nil, 542, nil, 542, 542, + 542, 542, 542, 542, 542, nil, nil, nil, nil, nil, + 542, 542, 542, 542, 542, 542, 542, nil, nil, 542, + nil, nil, nil, nil, nil, nil, 542, nil, nil, 542, + 542, 542, 542, 542, 542, 542, 542, 542, 542, 542, + 542, nil, 542, 542, 542, 542, 542, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 542, nil, nil, 542, + nil, nil, 542, 542, nil, nil, 542, nil, nil, nil, + nil, nil, 542, nil, nil, 542, nil, nil, nil, nil, + nil, 542, nil, nil, nil, nil, 542, 542, 542, 542, + nil, 542, 542, 542, 542, nil, nil, nil, nil, 542, + 542, nil, nil, nil, 557, 557, 557, 542, 557, 542, + 542, 542, 557, 557, nil, nil, nil, 557, nil, 557, + 557, 557, 557, 557, 557, 557, nil, nil, nil, nil, + nil, 557, 557, 557, 557, 557, 557, 557, nil, nil, + 557, nil, nil, nil, nil, nil, nil, 557, nil, nil, + 557, 557, 557, 557, 557, 557, 557, 557, nil, 557, + 557, 557, nil, 557, 557, 557, 557, 557, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 557, nil, nil, + 557, nil, nil, 557, 557, nil, nil, 557, nil, 557, + nil, nil, nil, 557, nil, nil, nil, nil, nil, nil, + nil, nil, 557, nil, nil, nil, nil, 557, 557, 557, + 557, nil, 557, 557, 557, 557, nil, nil, nil, nil, + 557, 557, nil, nil, nil, 558, 558, 558, 557, 558, + 557, 557, 557, 558, 558, nil, nil, nil, 558, nil, + 558, 558, 558, 558, 558, 558, 558, nil, nil, nil, + nil, nil, 558, 558, 558, 558, 558, 558, 558, nil, + nil, 558, nil, nil, nil, nil, nil, nil, 558, nil, + nil, 558, 558, 558, 558, 558, 558, 558, 558, 558, + 558, 558, 558, nil, 558, 558, 558, 558, 558, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 558, nil, + nil, 558, nil, nil, 558, 558, nil, nil, 558, nil, + 558, nil, 558, nil, 558, nil, nil, 558, nil, nil, + nil, nil, nil, 558, nil, nil, nil, nil, 558, 558, + 558, 558, nil, 558, 558, 558, 558, nil, nil, nil, + nil, 558, 558, nil, nil, nil, 568, 568, 568, 558, + 568, 558, 558, 558, 568, 568, nil, nil, nil, 568, + nil, 568, 568, 568, 568, 568, 568, 568, nil, nil, + nil, nil, nil, 568, 568, 568, 568, 568, 568, 568, + nil, nil, 568, nil, nil, nil, nil, nil, nil, 568, + nil, nil, 568, 568, 568, 568, 568, 568, 568, 568, + 568, 568, 568, 568, nil, 568, 568, 568, 568, 568, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 568, + nil, nil, 568, nil, nil, 568, 568, nil, nil, 568, + nil, 568, nil, 568, nil, 568, nil, nil, 568, nil, + nil, nil, nil, nil, 568, nil, nil, nil, nil, 568, + 568, 568, 568, nil, 568, 568, 568, 568, nil, nil, + nil, nil, 568, 568, nil, nil, nil, 600, 600, 600, + 568, 600, 568, 568, 568, 600, 600, nil, nil, nil, + 600, nil, 600, 600, 600, 600, 600, 600, 600, nil, + nil, nil, nil, nil, 600, 600, 600, 600, 600, 600, + 600, nil, nil, 600, nil, nil, nil, nil, nil, nil, + 600, nil, nil, 600, 600, 600, 600, 600, 600, 600, + 600, nil, 600, 600, 600, nil, 600, 600, 600, 600, + 600, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 600, nil, nil, 600, nil, nil, 600, 600, nil, nil, + 600, nil, 600, nil, nil, nil, 600, nil, nil, nil, + nil, nil, nil, nil, nil, 600, nil, nil, nil, nil, + 600, 600, 600, 600, nil, 600, 600, 600, 600, nil, + nil, nil, nil, 600, 600, nil, nil, nil, 601, 601, + 601, 600, 601, 600, 600, 600, 601, 601, nil, nil, + nil, 601, nil, 601, 601, 601, 601, 601, 601, 601, + nil, nil, nil, nil, nil, 601, 601, 601, 601, 601, + 601, 601, nil, nil, 601, nil, nil, nil, nil, nil, + nil, 601, nil, nil, 601, 601, 601, 601, 601, 601, + 601, 601, nil, 601, 601, 601, nil, 601, 601, 601, + 601, 601, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 601, nil, nil, 601, nil, nil, 601, 601, nil, + nil, 601, nil, nil, nil, nil, nil, 601, nil, nil, + nil, nil, nil, nil, nil, nil, 601, nil, nil, nil, + nil, 601, 601, 601, 601, nil, 601, 601, 601, 601, + nil, nil, nil, nil, 601, 601, nil, nil, nil, 602, + 602, 602, 601, 602, 601, 601, 601, 602, 602, nil, + nil, nil, 602, nil, 602, 602, 602, 602, 602, 602, + 602, nil, nil, nil, nil, nil, 602, 602, 602, 602, + 602, 602, 602, nil, nil, 602, nil, nil, nil, nil, + nil, nil, 602, nil, nil, 602, 602, 602, 602, 602, + 602, 602, 602, 602, 602, 602, 602, nil, 602, 602, + 602, 602, 602, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 602, nil, nil, 602, nil, nil, 602, 602, + nil, nil, 602, nil, 602, nil, 602, nil, 602, nil, + nil, 602, nil, nil, nil, nil, nil, 602, nil, nil, + nil, nil, 602, 602, 602, 602, nil, 602, 602, 602, + 602, nil, nil, nil, nil, 602, 602, nil, nil, nil, + nil, nil, nil, 602, nil, 602, 602, 602, 605, 605, + 605, 605, 605, nil, nil, nil, 605, 605, nil, nil, + nil, 605, nil, 605, 605, 605, 605, 605, 605, 605, + nil, nil, nil, nil, nil, 605, 605, 605, 605, 605, + 605, 605, nil, nil, 605, nil, nil, nil, nil, nil, + 605, 605, nil, 605, 605, 605, 605, 605, 605, 605, + 605, 605, nil, 605, 605, 605, nil, 605, 605, 605, + 605, 605, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 605, nil, nil, 605, nil, nil, 605, 605, nil, + nil, 605, nil, 605, nil, nil, nil, 605, nil, nil, + nil, nil, nil, nil, nil, nil, 605, nil, nil, nil, + nil, 605, 605, 605, 605, nil, 605, 605, 605, 605, + nil, nil, nil, nil, 605, 605, nil, nil, nil, 606, + 606, 606, 605, 606, 605, 605, 605, 606, 606, nil, + nil, nil, 606, nil, 606, 606, 606, 606, 606, 606, + 606, nil, nil, nil, nil, nil, 606, 606, 606, 606, + 606, 606, 606, nil, nil, 606, nil, nil, nil, nil, + nil, nil, 606, nil, nil, 606, 606, 606, 606, 606, + 606, 606, 606, nil, 606, 606, 606, nil, 606, 606, + 606, 606, 606, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 606, nil, nil, 606, nil, nil, 606, 606, + nil, nil, 606, nil, nil, nil, nil, nil, 606, nil, + nil, nil, nil, nil, nil, nil, nil, 606, nil, nil, + nil, nil, 606, 606, 606, 606, nil, 606, 606, 606, + 606, nil, nil, nil, nil, 606, 606, nil, nil, nil, + 609, 609, 609, 606, 609, 606, 606, 606, 609, 609, + nil, nil, nil, 609, nil, 609, 609, 609, 609, 609, + 609, 609, nil, nil, nil, nil, nil, 609, 609, 609, + 609, 609, 609, 609, nil, nil, 609, nil, nil, nil, + nil, nil, nil, 609, nil, nil, 609, 609, 609, 609, + 609, 609, 609, 609, 609, 609, 609, 609, nil, 609, + 609, 609, 609, 609, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 609, nil, nil, 609, nil, nil, 609, + 609, nil, nil, 609, nil, 609, nil, 609, nil, 609, + nil, nil, 609, nil, nil, nil, nil, nil, 609, nil, + nil, nil, nil, 609, 609, 609, 609, nil, 609, 609, + 609, 609, nil, nil, nil, nil, 609, 609, nil, nil, + nil, 610, 610, 610, 609, 610, 609, 609, 609, 610, + 610, nil, nil, nil, 610, nil, 610, 610, 610, 610, + 610, 610, 610, nil, nil, nil, nil, nil, 610, 610, + 610, 610, 610, 610, 610, nil, nil, 610, nil, nil, + nil, nil, nil, nil, 610, nil, nil, 610, 610, 610, + 610, 610, 610, 610, 610, 610, 610, 610, 610, nil, + 610, 610, 610, 610, 610, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 610, nil, nil, 610, nil, nil, + 610, 610, nil, nil, 610, nil, nil, nil, 610, nil, + 610, nil, nil, 610, nil, nil, nil, nil, nil, 610, + nil, nil, nil, nil, 610, 610, 610, 610, nil, 610, + 610, 610, 610, nil, nil, nil, nil, 610, 610, nil, + nil, nil, 611, 611, 611, 610, 611, 610, 610, 610, + 611, 611, nil, nil, nil, 611, nil, 611, 611, 611, + 611, 611, 611, 611, nil, nil, nil, nil, nil, 611, + 611, 611, 611, 611, 611, 611, nil, nil, 611, nil, + nil, nil, nil, nil, nil, 611, nil, nil, 611, 611, + 611, 611, 611, 611, 611, 611, nil, 611, 611, 611, + nil, 611, 611, 611, 611, 611, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 611, nil, nil, 611, nil, + nil, 611, 611, nil, nil, 611, nil, nil, nil, nil, + nil, 611, nil, nil, nil, nil, nil, nil, nil, nil, + 611, nil, nil, nil, nil, 611, 611, 611, 611, nil, + 611, 611, 611, 611, nil, nil, nil, nil, 611, 611, + nil, nil, nil, 612, 612, 612, 611, 612, 611, 611, + 611, 612, 612, nil, nil, nil, 612, nil, 612, 612, + 612, 612, 612, 612, 612, nil, nil, nil, nil, nil, + 612, 612, 612, 612, 612, 612, 612, nil, nil, 612, + nil, nil, nil, nil, nil, nil, 612, nil, nil, 612, + 612, 612, 612, 612, 612, 612, 612, nil, 612, 612, + 612, nil, 612, 612, 612, 612, 612, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 612, nil, nil, 612, + nil, nil, 612, 612, nil, nil, 612, nil, nil, nil, + nil, nil, 612, nil, nil, nil, nil, nil, nil, nil, + nil, 612, nil, nil, nil, nil, 612, 612, 612, 612, + nil, 612, 612, 612, 612, nil, nil, nil, nil, 612, + 612, nil, nil, nil, 616, 616, 616, 612, 616, 612, + 612, 612, 616, 616, nil, nil, nil, 616, nil, 616, + 616, 616, 616, 616, 616, 616, nil, nil, nil, nil, + nil, 616, 616, 616, 616, 616, 616, 616, nil, nil, + 616, nil, nil, nil, nil, nil, nil, 616, nil, nil, + 616, 616, 616, 616, 616, 616, 616, 616, nil, 616, + 616, 616, nil, 616, 616, 616, 616, 616, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 616, nil, nil, + 616, nil, nil, 616, 616, nil, nil, 616, nil, nil, + nil, nil, nil, 616, nil, nil, nil, nil, nil, nil, + nil, nil, 616, nil, nil, nil, nil, 616, 616, 616, + 616, nil, 616, 616, 616, 616, nil, nil, nil, nil, + 616, 616, nil, nil, nil, 617, 617, 617, 616, 617, + 616, 616, 616, 617, 617, nil, nil, nil, 617, nil, + 617, 617, 617, 617, 617, 617, 617, nil, nil, nil, + nil, nil, 617, 617, 617, 617, 617, 617, 617, nil, + nil, 617, nil, nil, nil, nil, nil, nil, 617, nil, + nil, 617, 617, 617, 617, 617, 617, 617, 617, nil, + 617, 617, 617, nil, 617, 617, 617, 617, 617, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 617, nil, + nil, 617, nil, nil, 617, 617, nil, nil, 617, nil, + nil, nil, nil, nil, 617, nil, nil, nil, nil, nil, + nil, nil, nil, 617, nil, nil, nil, nil, 617, 617, + 617, 617, nil, 617, 617, 617, 617, nil, nil, nil, + nil, 617, 617, nil, nil, nil, 641, 641, 641, 617, + 641, 617, 617, 617, 641, 641, nil, nil, nil, 641, + nil, 641, 641, 641, 641, 641, 641, 641, nil, nil, + nil, nil, nil, 641, 641, 641, 641, 641, 641, 641, + nil, nil, 641, nil, nil, nil, nil, nil, nil, 641, + nil, nil, 641, 641, 641, 641, 641, 641, 641, 641, + nil, 641, 641, 641, nil, 641, 641, 641, 641, 641, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 641, + nil, nil, 641, nil, nil, 641, 641, nil, nil, 641, + nil, nil, nil, nil, nil, 641, nil, nil, nil, nil, + nil, nil, nil, nil, 641, nil, nil, nil, nil, 641, + 641, 641, 641, nil, 641, 641, 641, 641, nil, nil, + nil, nil, 641, 641, nil, nil, nil, 644, 644, 644, + 641, 644, 641, 641, 641, 644, 644, nil, nil, nil, + 644, nil, 644, 644, 644, 644, 644, 644, 644, nil, + nil, nil, nil, nil, 644, 644, 644, 644, 644, 644, + 644, nil, nil, 644, nil, nil, nil, nil, nil, nil, + 644, nil, nil, 644, 644, 644, 644, 644, 644, 644, + 644, nil, 644, 644, 644, nil, 644, 644, 644, 644, + 644, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 644, nil, nil, 644, nil, nil, 644, 644, nil, nil, + 644, nil, nil, nil, nil, nil, 644, nil, nil, nil, + nil, nil, nil, nil, nil, 644, nil, nil, nil, nil, + 644, 644, 644, 644, nil, 644, 644, 644, 644, nil, + nil, nil, nil, 644, 644, nil, nil, nil, 647, 647, + 647, 644, 647, 644, 644, 644, 647, 647, nil, nil, + nil, 647, nil, 647, 647, 647, 647, 647, 647, 647, + nil, nil, nil, nil, nil, 647, 647, 647, 647, 647, + 647, 647, nil, nil, 647, nil, nil, nil, nil, nil, + nil, 647, nil, nil, 647, 647, 647, 647, 647, 647, + 647, 647, nil, 647, 647, 647, nil, 647, 647, nil, + nil, 647, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 647, nil, nil, 647, nil, nil, 647, 647, nil, + nil, 647, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 647, 647, 647, 647, nil, 647, 647, 647, 647, + nil, nil, nil, nil, 647, 647, nil, nil, nil, 658, + 658, 658, 647, 658, 647, 647, 647, 658, 658, nil, + nil, nil, 658, nil, 658, 658, 658, 658, 658, 658, + 658, nil, nil, nil, nil, nil, 658, 658, 658, 658, + 658, 658, 658, nil, nil, 658, nil, nil, nil, nil, + nil, nil, 658, nil, nil, 658, 658, 658, 658, 658, + 658, 658, 658, nil, 658, 658, 658, nil, 658, 658, + nil, nil, 658, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 658, nil, nil, 658, nil, nil, 658, 658, + nil, nil, 658, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 658, 658, 658, 658, nil, 658, 658, 658, + 658, nil, nil, nil, nil, 658, 658, nil, nil, nil, + 663, 663, 663, 658, 663, 658, 658, 658, 663, 663, + nil, nil, nil, 663, nil, 663, 663, 663, 663, 663, + 663, 663, nil, nil, nil, nil, nil, 663, 663, 663, + 663, 663, 663, 663, nil, nil, 663, nil, nil, nil, + nil, nil, nil, 663, nil, nil, 663, 663, 663, 663, + 663, 663, 663, 663, nil, 663, 663, 663, nil, 663, + 663, 663, 663, 663, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 663, nil, nil, 663, nil, nil, 663, + 663, nil, nil, 663, nil, 663, nil, nil, nil, 663, + nil, nil, nil, nil, nil, nil, nil, nil, 663, nil, + nil, nil, nil, 663, 663, 663, 663, nil, 663, 663, + 663, 663, nil, nil, nil, nil, 663, 663, nil, nil, + nil, 689, 689, 689, 663, 689, 663, 663, 663, 689, + 689, nil, nil, nil, 689, nil, 689, 689, 689, 689, + 689, 689, 689, nil, nil, nil, nil, nil, 689, 689, + 689, 689, 689, 689, 689, nil, nil, 689, nil, nil, + nil, nil, nil, nil, 689, nil, nil, 689, 689, 689, + 689, 689, 689, 689, 689, nil, 689, 689, 689, nil, + 689, 689, 689, 689, 689, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 689, nil, nil, 689, nil, nil, + 689, 689, nil, nil, 689, nil, nil, nil, nil, nil, + 689, nil, nil, nil, nil, nil, nil, nil, nil, 689, + nil, nil, nil, nil, 689, 689, 689, 689, nil, 689, + 689, 689, 689, nil, nil, nil, nil, 689, 689, nil, + nil, nil, 723, 723, 723, 689, 723, 689, 689, 689, + 723, 723, nil, nil, nil, 723, nil, 723, 723, 723, + 723, 723, 723, 723, nil, nil, nil, nil, nil, 723, + 723, 723, 723, 723, 723, 723, nil, nil, 723, nil, + nil, nil, nil, nil, nil, 723, nil, nil, 723, 723, + 723, 723, 723, 723, 723, 723, nil, 723, 723, 723, + nil, 723, 723, 723, 723, 723, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 723, nil, nil, 723, nil, + nil, 723, 723, nil, nil, 723, nil, nil, nil, nil, + nil, 723, nil, nil, nil, nil, nil, nil, nil, nil, + 723, nil, nil, nil, nil, 723, 723, 723, 723, nil, + 723, 723, 723, 723, nil, nil, nil, nil, 723, 723, + nil, nil, nil, 745, 745, 745, 723, 745, 723, 723, + 723, 745, 745, nil, nil, nil, 745, nil, 745, 745, + 745, 745, 745, 745, 745, nil, nil, nil, nil, nil, + 745, 745, 745, 745, 745, 745, 745, nil, nil, 745, + nil, nil, nil, nil, nil, nil, 745, nil, nil, 745, + 745, 745, 745, 745, 745, 745, 745, nil, 745, 745, + 745, nil, 745, 745, 745, 745, 745, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 745, nil, nil, 745, + nil, nil, 745, 745, nil, nil, 745, nil, nil, nil, + nil, nil, 745, nil, nil, nil, nil, nil, nil, nil, + nil, 745, nil, nil, nil, nil, 745, 745, 745, 745, + nil, 745, 745, 745, 745, nil, nil, nil, nil, 745, + 745, nil, nil, nil, 753, 753, 753, 745, 753, 745, + 745, 745, 753, 753, nil, nil, nil, 753, nil, 753, + 753, 753, 753, 753, 753, 753, nil, nil, nil, nil, + nil, 753, 753, 753, 753, 753, 753, 753, nil, nil, + 753, nil, nil, nil, nil, nil, nil, 753, nil, nil, + 753, 753, 753, 753, 753, 753, 753, 753, nil, 753, + 753, 753, nil, 753, 753, 753, 753, 753, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 753, nil, nil, + 753, nil, nil, 753, 753, nil, nil, 753, nil, nil, + nil, nil, nil, 753, nil, nil, nil, nil, nil, nil, + nil, nil, 753, nil, nil, nil, nil, 753, 753, 753, + 753, nil, 753, 753, 753, 753, nil, nil, nil, nil, + 753, 753, nil, nil, nil, 766, 766, 766, 753, 766, + 753, 753, 753, 766, 766, nil, nil, nil, 766, nil, + 766, 766, 766, 766, 766, 766, 766, nil, nil, nil, + nil, nil, 766, 766, 766, 766, 766, 766, 766, nil, + nil, 766, nil, nil, nil, nil, nil, nil, 766, nil, + nil, 766, 766, 766, 766, 766, 766, 766, 766, nil, + 766, 766, 766, nil, 766, 766, 766, 766, 766, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 766, nil, + nil, 766, nil, nil, 766, 766, nil, nil, 766, nil, + nil, nil, nil, nil, 766, nil, nil, nil, nil, nil, + nil, nil, nil, 766, nil, nil, nil, nil, 766, 766, + 766, 766, nil, 766, 766, 766, 766, nil, nil, nil, + nil, 766, 766, nil, nil, nil, 767, 767, 767, 766, + 767, 766, 766, 766, 767, 767, nil, nil, nil, 767, + nil, 767, 767, 767, 767, 767, 767, 767, nil, nil, + nil, nil, nil, 767, 767, 767, 767, 767, 767, 767, + nil, nil, 767, nil, nil, nil, nil, nil, nil, 767, + nil, nil, 767, 767, 767, 767, 767, 767, 767, 767, + nil, 767, 767, 767, nil, 767, 767, 767, 767, 767, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 767, + nil, nil, 767, nil, nil, 767, 767, nil, nil, 767, + nil, nil, nil, nil, nil, 767, nil, nil, nil, nil, + nil, nil, nil, nil, 767, nil, nil, nil, nil, 767, + 767, 767, 767, nil, 767, 767, 767, 767, nil, nil, + nil, nil, 767, 767, nil, nil, nil, 768, 768, 768, + 767, 768, 767, 767, 767, 768, 768, nil, nil, nil, + 768, nil, 768, 768, 768, 768, 768, 768, 768, nil, + nil, nil, nil, nil, 768, 768, 768, 768, 768, 768, + 768, nil, nil, 768, nil, nil, nil, nil, nil, nil, + 768, nil, nil, 768, 768, 768, 768, 768, 768, 768, + 768, nil, 768, 768, 768, nil, 768, 768, 768, 768, + 768, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 768, nil, nil, 768, nil, nil, 768, 768, nil, nil, + 768, nil, nil, nil, nil, nil, 768, nil, nil, nil, + nil, nil, nil, nil, nil, 768, nil, nil, nil, nil, + 768, 768, 768, 768, nil, 768, 768, 768, 768, nil, + nil, nil, nil, 768, 768, nil, nil, nil, 769, 769, + 769, 768, 769, 768, 768, 768, 769, 769, nil, nil, + nil, 769, nil, 769, 769, 769, 769, 769, 769, 769, + nil, nil, nil, nil, nil, 769, 769, 769, 769, 769, + 769, 769, nil, nil, 769, nil, nil, nil, nil, nil, + nil, 769, nil, nil, 769, 769, 769, 769, 769, 769, + 769, 769, nil, 769, 769, 769, nil, 769, 769, 769, + 769, 769, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 769, nil, nil, 769, nil, nil, 769, 769, nil, + nil, 769, nil, nil, nil, nil, nil, 769, nil, nil, + nil, nil, nil, nil, nil, nil, 769, nil, nil, nil, + nil, 769, 769, 769, 769, nil, 769, 769, 769, 769, + nil, nil, nil, nil, 769, 769, nil, nil, nil, 771, + 771, 771, 769, 771, 769, 769, 769, 771, 771, nil, + nil, nil, 771, nil, 771, 771, 771, 771, 771, 771, + 771, nil, nil, nil, nil, nil, 771, 771, 771, 771, + 771, 771, 771, nil, nil, 771, nil, nil, nil, nil, + nil, nil, 771, nil, nil, 771, 771, 771, 771, 771, + 771, 771, 771, nil, 771, 771, 771, nil, 771, 771, + 771, 771, 771, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 771, nil, nil, 771, nil, nil, 771, 771, + nil, nil, 771, nil, nil, nil, nil, nil, 771, nil, + nil, nil, nil, nil, nil, nil, nil, 771, nil, nil, + nil, nil, 771, 771, 771, 771, nil, 771, 771, 771, + 771, nil, nil, nil, nil, 771, 771, nil, nil, nil, + 810, 810, 810, 771, 810, 771, 771, 771, 810, 810, + nil, nil, nil, 810, nil, 810, 810, 810, 810, 810, + 810, 810, nil, nil, nil, nil, nil, 810, 810, 810, + 810, 810, 810, 810, nil, nil, 810, nil, nil, nil, + nil, nil, nil, 810, nil, nil, 810, 810, 810, 810, + 810, 810, 810, 810, nil, 810, 810, 810, nil, 810, + 810, 810, 810, 810, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 810, nil, nil, 810, nil, nil, 810, + 810, nil, nil, 810, nil, nil, nil, nil, nil, 810, + nil, nil, nil, nil, nil, nil, nil, nil, 810, nil, + nil, nil, nil, 810, 810, 810, 810, nil, 810, 810, + 810, 810, nil, nil, nil, nil, 810, 810, nil, nil, + nil, 823, 823, 823, 810, 823, 810, 810, 810, 823, + 823, nil, nil, nil, 823, nil, 823, 823, 823, 823, + 823, 823, 823, nil, nil, nil, nil, nil, 823, 823, + 823, 823, 823, 823, 823, nil, nil, 823, nil, nil, + nil, nil, nil, nil, 823, nil, nil, 823, 823, 823, + 823, 823, 823, 823, 823, nil, 823, 823, 823, nil, + 823, 823, 823, 823, 823, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 823, nil, nil, 823, nil, nil, + 823, 823, nil, nil, 823, nil, nil, nil, nil, nil, + 823, nil, nil, nil, nil, nil, nil, nil, nil, 823, + nil, nil, nil, nil, 823, 823, 823, 823, nil, 823, + 823, 823, 823, nil, nil, nil, nil, 823, 823, nil, + nil, nil, 826, 826, 826, 823, 826, 823, 823, 823, + 826, 826, nil, nil, nil, 826, nil, 826, 826, 826, + 826, 826, 826, 826, nil, nil, nil, nil, nil, 826, + 826, 826, 826, 826, 826, 826, nil, nil, 826, nil, + nil, nil, nil, nil, nil, 826, nil, nil, 826, 826, + 826, 826, 826, 826, 826, 826, nil, 826, 826, 826, + nil, 826, 826, 826, 826, 826, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 826, nil, nil, 826, nil, + nil, 826, 826, nil, nil, 826, nil, 826, nil, nil, + nil, 826, nil, nil, nil, nil, nil, nil, nil, nil, + 826, nil, nil, nil, nil, 826, 826, 826, 826, nil, + 826, 826, 826, 826, nil, nil, nil, nil, 826, 826, + nil, nil, nil, 844, 844, 844, 826, 844, 826, 826, + 826, 844, 844, nil, nil, nil, 844, nil, 844, 844, + 844, 844, 844, 844, 844, nil, nil, nil, nil, nil, + 844, 844, 844, 844, 844, 844, 844, nil, nil, 844, + nil, nil, nil, nil, nil, nil, 844, nil, nil, 844, + 844, 844, 844, 844, 844, 844, 844, 844, 844, 844, + 844, nil, 844, 844, 844, 844, 844, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 844, nil, nil, 844, + nil, nil, 844, 844, nil, nil, 844, nil, nil, nil, + 844, nil, 844, nil, nil, 844, nil, nil, nil, nil, + nil, 844, nil, nil, nil, nil, 844, 844, 844, 844, + nil, 844, 844, 844, 844, nil, nil, nil, nil, 844, + 844, nil, nil, nil, 845, 845, 845, 844, 845, 844, + 844, 844, 845, 845, nil, nil, nil, 845, nil, 845, + 845, 845, 845, 845, 845, 845, nil, nil, nil, nil, + nil, 845, 845, 845, 845, 845, 845, 845, nil, nil, + 845, nil, nil, nil, nil, nil, nil, 845, nil, nil, + 845, 845, 845, 845, 845, 845, 845, 845, nil, 845, + 845, 845, nil, 845, 845, 845, 845, 845, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 845, nil, nil, + 845, nil, nil, 845, 845, nil, nil, 845, nil, nil, + nil, nil, nil, 845, nil, nil, nil, nil, nil, nil, + nil, nil, 845, nil, nil, nil, nil, 845, 845, 845, + 845, nil, 845, 845, 845, 845, nil, nil, nil, nil, + 845, 845, nil, nil, nil, 860, 860, 860, 845, 860, + 845, 845, 845, 860, 860, nil, nil, nil, 860, nil, + 860, 860, 860, 860, 860, 860, 860, nil, nil, nil, + nil, nil, 860, 860, 860, 860, 860, 860, 860, nil, + nil, 860, nil, nil, nil, nil, nil, nil, 860, nil, + nil, 860, 860, 860, 860, 860, 860, 860, 860, nil, + 860, 860, 860, nil, 860, 860, nil, nil, 860, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 860, nil, + nil, 860, nil, nil, 860, 860, nil, nil, 860, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 860, 860, + 860, 860, nil, 860, 860, 860, 860, nil, nil, nil, + nil, 860, 860, nil, nil, nil, 869, 869, 869, 860, + 869, 860, 860, 860, 869, 869, nil, nil, nil, 869, + nil, 869, 869, 869, 869, 869, 869, 869, nil, nil, + nil, nil, nil, 869, 869, 869, 869, 869, 869, 869, + nil, nil, 869, nil, nil, nil, nil, nil, nil, 869, + nil, nil, 869, 869, 869, 869, 869, 869, 869, 869, + nil, 869, 869, 869, nil, 869, 869, nil, nil, 869, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 869, + nil, nil, 869, nil, nil, 869, 869, nil, nil, 869, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 869, + 869, 869, 869, nil, 869, 869, 869, 869, nil, nil, + nil, nil, 869, 869, nil, nil, nil, 920, 920, 920, + 869, 920, 869, 869, 869, 920, 920, nil, nil, nil, + 920, nil, 920, 920, 920, 920, 920, 920, 920, nil, + nil, nil, nil, nil, 920, 920, 920, 920, 920, 920, + 920, nil, nil, 920, nil, nil, nil, nil, nil, nil, + 920, nil, nil, 920, 920, 920, 920, 920, 920, 920, + 920, nil, 920, 920, 920, nil, 920, 920, nil, nil, + 920, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 920, nil, nil, 920, nil, nil, 920, 920, nil, nil, + 920, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 920, 920, 920, 920, nil, 920, 920, 920, 920, nil, + nil, nil, nil, 920, 920, nil, nil, nil, 973, 973, + 973, 920, 973, 920, 920, 920, 973, 973, nil, nil, + nil, 973, nil, 973, 973, 973, 973, 973, 973, 973, + nil, nil, nil, nil, nil, 973, 973, 973, 973, 973, + 973, 973, nil, nil, 973, nil, nil, nil, nil, nil, + nil, 973, nil, nil, 973, 973, 973, 973, 973, 973, + 973, 973, 973, 973, 973, 973, nil, 973, 973, 973, + 973, 973, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 973, nil, nil, 973, nil, nil, 973, 973, nil, + nil, 973, nil, 973, nil, 973, nil, 973, nil, nil, + 973, nil, nil, nil, nil, nil, 973, nil, nil, nil, + nil, 973, 973, 973, 973, nil, 973, 973, 973, 973, + nil, nil, nil, nil, 973, 973, nil, nil, nil, nil, + nil, nil, 973, nil, 973, 973, 973, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, nil, nil, nil, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, nil, nil, nil, nil, nil, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, nil, + 8, nil, nil, nil, nil, nil, nil, nil, 8, 8, + nil, 8, 8, 8, 8, 8, 8, 8, nil, nil, + 8, 8, nil, nil, nil, 8, 8, 8, 8, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 8, 8, nil, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, nil, nil, 8, + 8, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 8, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, nil, + nil, nil, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, nil, nil, nil, nil, nil, 9, 9, 9, + 9, 9, 9, 9, 9, 9, nil, nil, 9, nil, + nil, nil, nil, nil, nil, nil, 9, 9, nil, 9, + 9, 9, 9, 9, 9, 9, nil, nil, 9, 9, + nil, nil, nil, 9, 9, 9, 9, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 9, 9, nil, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, nil, nil, 9, 9, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 9, 405, 405, 405, 405, 405, 405, 405, + 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, + 405, 405, 405, 405, 405, 405, 405, nil, nil, nil, + 405, 405, 405, 405, 405, 405, 405, 405, 405, 405, + nil, nil, nil, nil, nil, 405, 405, 405, 405, 405, + 405, 405, 405, 405, nil, nil, 405, nil, nil, nil, + nil, nil, nil, nil, 405, 405, nil, 405, 405, 405, + 405, 405, 405, 405, nil, nil, 405, 405, nil, nil, + nil, 405, 405, 405, 405, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 405, 405, + nil, 405, 405, 405, 405, 405, 405, 405, 405, 405, + 405, 405, 405, nil, nil, 405, 405, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 405, 597, 597, 597, 597, 597, 597, 597, 597, 597, + 597, 597, 597, 597, 597, 597, 597, 597, 597, 597, + 597, 597, 597, 597, 597, nil, nil, nil, 597, 597, + 597, 597, 597, 597, 597, 597, 597, 597, nil, nil, + nil, nil, nil, 597, 597, 597, 597, 597, 597, 597, + 597, 597, nil, nil, 597, nil, nil, nil, nil, nil, + nil, nil, 597, 597, nil, 597, 597, 597, 597, 597, + 597, 597, nil, nil, 597, 597, nil, nil, nil, 597, + 597, 597, 597, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 597, 597, nil, 597, + 597, 597, 597, 597, 597, 597, 597, 597, 597, 597, + 597, nil, nil, 597, 597, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 597, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, nil, nil, nil, 72, 72, 72, 72, + 72, 72, 72, 72, 72, 72, nil, nil, nil, nil, + nil, 72, 72, 72, 72, 72, 72, 72, 72, 72, + 72, 72, 72, nil, 72, nil, nil, nil, nil, nil, + 72, 72, nil, 72, 72, 72, 72, 72, 72, 72, + nil, nil, 72, 72, nil, nil, nil, 72, 72, 72, + 72, nil, nil, nil, nil, nil, 72, nil, nil, nil, + nil, nil, nil, nil, 72, 72, nil, 72, 72, 72, + 72, 72, 72, 72, 72, 72, 72, 72, 72, nil, + nil, 72, 729, 729, 729, 729, 729, 729, 729, 729, + 729, 729, 729, 729, 729, 729, 729, 729, 729, 729, + 729, 729, 729, 729, 729, 729, nil, nil, nil, 729, + 729, 729, 729, 729, 729, 729, 729, 729, 729, nil, + nil, nil, nil, nil, 729, 729, 729, 729, 729, 729, + 729, 729, 729, nil, nil, 729, nil, nil, nil, nil, + nil, nil, nil, 729, 729, nil, 729, 729, 729, 729, + 729, 729, 729, nil, nil, 729, 729, nil, nil, nil, + 729, 729, 729, 729, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 729, 729, nil, + 729, 729, 729, 729, 729, 729, 729, 729, 729, 729, + 729, 729, 219, 219, 729, nil, 219, nil, nil, nil, + nil, nil, nil, nil, 219, 219, nil, 219, 219, 219, + 219, 219, 219, 219, nil, nil, 219, 219, nil, nil, + nil, 219, 219, 219, 219, nil, nil, nil, nil, nil, + 219, nil, nil, nil, nil, nil, nil, nil, 219, 219, + nil, 219, 219, 219, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 220, 220, 219, nil, 220, nil, nil, + nil, nil, nil, nil, nil, 220, 220, nil, 220, 220, + 220, 220, 220, 220, 220, nil, nil, 220, 220, nil, + nil, nil, 220, 220, 220, 220, nil, nil, nil, nil, + nil, 220, nil, nil, nil, nil, nil, nil, nil, 220, + 220, nil, 220, 220, 220, 220, 220, 220, 220, 220, + 220, 220, 220, 220, 268, 268, 220, nil, 268, nil, + nil, nil, nil, nil, nil, nil, 268, 268, nil, 268, + 268, 268, 268, 268, 268, 268, nil, nil, 268, 268, + nil, nil, nil, 268, 268, 268, 268, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 268, 268, nil, 268, 268, 268, 268, 268, 268, 268, + 268, 268, 268, 268, 268, 455, 455, 268, nil, 455, + nil, nil, nil, nil, nil, nil, nil, 455, 455, nil, + 455, 455, 455, 455, 455, 455, 455, nil, nil, 455, + 455, nil, nil, nil, 455, 455, 455, 455, nil, nil, + nil, nil, nil, 455, nil, nil, nil, nil, nil, nil, + nil, 455, 455, nil, 455, 455, 455, 455, 455, 455, + 455, 455, 455, 455, 455, 455, 456, 456, 455, nil, + 456, nil, nil, nil, nil, nil, nil, nil, 456, 456, + nil, 456, 456, 456, 456, 456, 456, 456, nil, nil, + 456, 456, nil, nil, nil, 456, 456, 456, 456, nil, + nil, nil, nil, nil, 456, nil, nil, nil, nil, nil, + nil, nil, 456, 456, nil, 456, 456, 456, 456, 456, + 456, 456, 456, 456, 456, 456, 456, 519, 519, 456, + nil, 519, nil, nil, nil, nil, nil, nil, nil, 519, + 519, nil, 519, 519, 519, 519, 519, 519, 519, nil, + nil, 519, 519, nil, nil, nil, 519, 519, 519, 519, + nil, nil, nil, nil, nil, 519, nil, nil, nil, nil, + nil, nil, nil, 519, 519, nil, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 519, 519, 519, 520, 520, + 519, nil, 520, nil, nil, nil, nil, nil, nil, nil, + 520, 520, nil, 520, 520, 520, 520, 520, 520, 520, + nil, nil, 520, 520, nil, nil, nil, 520, 520, 520, + 520, nil, nil, nil, nil, nil, 520, nil, nil, nil, + nil, nil, nil, nil, 520, 520, nil, 520, 520, 520, + 520, 520, 520, 520, 520, 520, 520, 520, 520, 529, + 529, 520, nil, 529, nil, nil, nil, nil, nil, nil, + nil, 529, 529, nil, 529, 529, 529, 529, 529, 529, + 529, nil, nil, 529, 529, nil, nil, nil, 529, 529, + 529, 529, nil, nil, nil, nil, nil, 529, nil, nil, + nil, nil, nil, nil, nil, 529, 529, nil, 529, 529, + 529, 529, 529, 529, 529, 529, 529, 529, 529, 529, + 530, 530, 529, nil, 530, nil, nil, nil, nil, nil, + nil, nil, 530, 530, nil, 530, 530, 530, 530, 530, + 530, 530, nil, nil, 530, 530, nil, nil, nil, 530, + 530, 530, 530, nil, nil, nil, nil, nil, 530, nil, + nil, nil, nil, nil, nil, nil, 530, 530, nil, 530, + 530, 530, 530, 530, 530, 530, 530, 530, 530, 530, + 530, 559, 559, 530, nil, 559, nil, nil, nil, nil, + nil, nil, nil, 559, 559, nil, 559, 559, 559, 559, + 559, 559, 559, nil, nil, 559, 559, nil, nil, nil, + 559, 559, 559, 559, nil, nil, nil, nil, nil, 559, + nil, nil, nil, nil, nil, nil, nil, 559, 559, nil, + 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, + 559, 559, 560, 560, 559, nil, 560, nil, nil, nil, + nil, nil, nil, nil, 560, 560, nil, 560, 560, 560, + 560, 560, 560, 560, nil, nil, 560, 560, nil, nil, + nil, 560, 560, 560, 560, nil, nil, nil, nil, nil, + 560, nil, nil, nil, nil, nil, nil, nil, 560, 560, + nil, 560, 560, 560, 560, 560, 560, 560, 560, 560, + 560, 560, 560, 566, 566, 560, nil, 566, nil, nil, + nil, nil, nil, nil, nil, 566, 566, nil, 566, 566, + 566, 566, 566, 566, 566, nil, nil, 566, 566, nil, + nil, nil, 566, 566, 566, 566, nil, nil, nil, nil, + nil, 566, nil, nil, nil, nil, nil, nil, nil, 566, + 566, nil, 566, 566, 566, 566, 566, 566, 566, 566, + 566, 566, 566, 566, 567, 567, 566, nil, 567, nil, + nil, nil, nil, nil, nil, nil, 567, 567, nil, 567, + 567, 567, 567, 567, 567, 567, nil, nil, 567, 567, + nil, nil, nil, 567, 567, 567, 567, nil, nil, nil, + nil, nil, 567, nil, nil, nil, nil, nil, nil, nil, + 567, 567, nil, 567, 567, 567, 567, 567, 567, 567, + 567, 567, 567, 567, 567, 603, 603, 567, nil, 603, + nil, nil, nil, nil, nil, nil, nil, 603, 603, nil, + 603, 603, 603, 603, 603, 603, 603, nil, nil, 603, + 603, nil, nil, nil, 603, 603, 603, 603, nil, nil, + nil, nil, nil, 603, nil, nil, nil, nil, nil, nil, + nil, 603, 603, nil, 603, 603, 603, 603, 603, 603, + 603, 603, 603, 603, 603, 603, 604, 604, 603, nil, + 604, nil, nil, nil, nil, nil, nil, nil, 604, 604, + nil, 604, 604, 604, 604, 604, 604, 604, nil, nil, + 604, 604, nil, nil, nil, 604, 604, 604, 604, nil, + nil, nil, nil, nil, 604, nil, nil, nil, nil, nil, + nil, nil, 604, 604, nil, 604, 604, 604, 604, 604, + 604, 604, 604, 604, 604, 604, 604, 970, 970, 604, + nil, 970, nil, nil, nil, nil, nil, nil, nil, 970, + 970, nil, 970, 970, 970, 970, 970, 970, 970, nil, + nil, 970, 970, nil, nil, nil, 970, 970, 970, 970, + nil, nil, nil, nil, nil, 970, nil, nil, nil, nil, + nil, nil, nil, 970, 970, nil, 970, 970, 970, 970, + 970, 970, 970, 970, 970, 970, 970, 970, 974, 974, + 970, nil, 974, nil, nil, nil, nil, nil, nil, nil, + 974, 974, nil, 974, 974, 974, 974, 974, 974, 974, + nil, nil, 974, 974, nil, nil, nil, 974, 974, 974, + 974, nil, nil, nil, nil, nil, 974, nil, nil, nil, + nil, nil, nil, nil, 974, 974, nil, 974, 974, 974, + 974, 974, 974, 974, 974, 974, 974, 974, 974, 975, + 975, 974, nil, 975, nil, nil, nil, nil, nil, nil, + nil, 975, 975, nil, 975, 975, 975, 975, 975, 975, + 975, nil, nil, 975, 975, nil, nil, nil, 975, 975, + 975, 975, nil, nil, nil, nil, nil, 975, nil, nil, + nil, nil, nil, nil, nil, 975, 975, nil, 975, 975, + 975, 975, 975, 975, 975, 975, 975, 975, 975, 975, + nil, 547, 975, 547, 547, 547, 547, 547, nil, 669, + nil, 669, 669, 669, 669, 669, 547, nil, nil, nil, + nil, nil, nil, nil, 669, nil, 727, nil, 727, 727, + 727, 727, 727, nil, nil, nil, nil, nil, 547, 547, + nil, 727, nil, nil, nil, nil, 669, 547, 547, 547, + 547, nil, nil, nil, 547, 669, 669, 669, 669, nil, + nil, nil, 669, 727, nil, 728, nil, 728, 728, 728, + 728, 728, 727, 727, 727, 727, nil, nil, nil, 727, + 728, nil, 804, nil, 804, 804, 804, 804, 804, nil, + 806, nil, 806, 806, 806, 806, 806, 804, nil, nil, + nil, nil, 728, nil, nil, 806, nil, nil, nil, nil, + nil, 728, 728, 728, 728, nil, nil, nil, 728, 804, + nil, nil, nil, nil, nil, nil, nil, 806, 804, 804, + 804, 804, nil, nil, nil, 804, 806, 806, 806, 806, + nil, nil, 911, 806, 911, 911, 911, 911, 911, nil, + 913, nil, 913, 913, 913, 913, 913, 911, nil, nil, + nil, nil, nil, nil, nil, 913, nil, 935, nil, 935, + 935, 935, 935, 935, nil, nil, nil, nil, nil, 911, + nil, nil, 935, nil, nil, nil, nil, 913, 911, 911, + 911, 911, nil, nil, nil, 911, 913, 913, 913, 913, + nil, nil, nil, 913, 935, nil, 941, nil, 941, 941, + 941, 941, 941, 935, 935, 935, 935, nil, nil, nil, + 935, 941, nil, 990, nil, 990, 990, 990, 990, 990, + 992, nil, 992, 992, 992, 992, 992, nil, 990, nil, + nil, nil, nil, 941, nil, 992, nil, 994, nil, 994, + 994, 994, 994, 994, 941, 941, nil, nil, nil, 941, + 990, nil, 994, nil, nil, nil, nil, 992, nil, 990, + 990, 990, 990, nil, nil, nil, 990, nil, 992, 992, + nil, nil, nil, 992, 994, nil, 996, nil, 996, 996, + 996, 996, 996, nil, nil, 994, 994, nil, nil, nil, + 994, 996, nil, 1011, nil, 1011, 1011, 1011, 1011, 1011, + 1028, nil, 1028, 1028, 1028, 1028, 1028, nil, 1011, nil, + nil, nil, nil, 996, nil, 1028, nil, nil, nil, nil, + nil, nil, nil, nil, 996, 996, nil, nil, nil, 996, + 1011, nil, nil, nil, nil, nil, nil, 1028, nil, nil, + nil, 1011, 1011, nil, nil, nil, 1011, nil, 1028, 1028, + nil, nil, nil, 1028 ] + +racc_action_pointer = [ + 1853, 10, nil, 221, nil, 5772, 909, -79, 22505, 22633, + -51, nil, -80, -44, 240, 15, 477, -81, nil, -71, + 5903, 1711, 166, nil, -62, nil, -8, 958, 1068, 6034, + 6165, 6296, nil, 1993, 6427, 6558, nil, 70, 225, 352, + 152, 255, 6697, 6828, -51, 6959, 86, 507, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 1178, nil, 7098, + 7229, 7360, 4, nil, 7491, 7622, nil, nil, 7753, 7892, + 8023, 8154, 23017, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 624, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 0, nil, nil, 112, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 224, nil, 8293, nil, nil, nil, + nil, 8432, 8563, 8694, 8825, 8964, nil, 2133, nil, 287, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 115, nil, 2273, 9095, 9226, 9357, 9488, 9619, 9750, 23191, + 23252, nil, nil, 9881, 10012, 10143, nil, nil, 574, -54, + 166, 202, 217, 124, 216, nil, 10274, 2413, 232, 10405, + 10536, 10667, 10798, 10929, 11060, 11191, 11322, 11453, 11584, 11715, + 11846, 11977, 12108, 12239, 12370, 12501, 12632, 12763, 12894, 13025, + 13156, nil, nil, nil, nil, 13287, nil, nil, 23313, nil, + nil, 258, 13418, 13549, nil, nil, nil, nil, nil, nil, + nil, 13680, nil, 2133, nil, 249, 263, nil, 13811, 328, + 13942, nil, nil, 14073, 14204, nil, nil, 295, nil, 14343, + 1331, 337, 315, 2553, 340, 391, 350, 14474, 2693, 576, + 682, 686, 441, 718, nil, 409, 387, 33, nil, nil, + nil, 458, 360, 418, 14613, nil, 424, 497, 771, nil, + 528, 14744, nil, 14875, 2833, 1396, 484, nil, 398, 503, + 528, 511, 575, 550, nil, nil, 326, -1, 11, 15006, + 2973, 3113, 298, 641, 533, -18, 11, 794, 644, 25, + 677, nil, nil, 342, 434, -21, nil, 834, nil, 596, + 15137, nil, nil, nil, 194, 230, 255, 373, 413, 481, + 506, 508, 550, nil, 551, nil, 15268, nil, 327, 388, + 395, 400, 456, -41, -35, 462, nil, nil, nil, nil, + nil, nil, nil, nil, 611, 22761, nil, nil, nil, nil, + 612, nil, nil, 600, 15399, 605, nil, nil, 600, nil, + 837, 313, 701, nil, nil, 1853, nil, nil, nil, nil, + nil, 1993, 615, nil, 627, 632, 509, 521, 1314, nil, + nil, nil, 222, 334, 678, nil, nil, 1446, 1582, nil, + nil, nil, -35, nil, 683, 23374, 23435, 15530, 328, 15661, + 15792, 15923, 2833, 2973, 523, 563, 708, 710, 711, 712, + 1667, 4233, 666, 3113, 3253, 3393, 3533, 3673, 3813, 915, + 1465, 3953, 4093, 2273, 1397, nil, 1718, nil, nil, nil, + nil, 669, nil, nil, nil, 673, nil, nil, 16054, nil, + 16185, nil, 16316, nil, 363, nil, nil, nil, 16455, 1427, + nil, 675, 675, nil, nil, 676, 16594, 683, 16725, 23496, + 23557, 870, 726, nil, 16856, 685, nil, 16987, 17118, 23618, + 23679, 1531, 2413, 17249, 823, 822, 702, 747, nil, 17380, + nil, nil, 17511, nil, nil, nil, nil, 24290, 3253, 826, + nil, 3393, 62, 834, 841, 836, 844, 17642, 17773, 23740, + 23801, 27, nil, nil, 930, nil, 23862, 23923, 17904, nil, + nil, 250, 3533, 765, nil, -33, nil, nil, nil, 832, + nil, nil, nil, 739, nil, nil, 259, nil, 338, nil, + nil, 727, nil, 741, nil, nil, nil, 22889, nil, 744, + 18035, 18166, 18297, 23984, 24045, 18436, 18567, 552, 787, 18698, + 18829, 18960, 19091, 786, nil, nil, 19222, 19353, 787, nil, + nil, nil, 343, 358, 466, 604, 758, 774, 906, nil, + 890, 6, nil, nil, 807, 102, 913, nil, 790, nil, + 838, 19484, nil, nil, 19615, nil, -83, 19746, 808, nil, + 830, 123, 180, 873, 248, 1038, 875, 840, 19877, nil, + 909, 214, 964, 20008, nil, nil, nil, 596, nil, 24298, + nil, 847, 849, nil, 857, 858, 859, nil, nil, nil, + nil, nil, nil, nil, nil, 853, 1178, nil, nil, 20139, + nil, nil, nil, 952, nil, nil, nil, 958, nil, nil, + 959, 516, nil, 997, nil, nil, nil, nil, nil, 1006, + nil, 26, 886, 40, 41, 151, 185, 3673, 717, 1040, + nil, 892, 3813, 20270, nil, 1029, 3953, 24315, 24354, 23130, + nil, nil, nil, nil, nil, nil, 4093, nil, nil, nil, + nil, nil, nil, nil, 910, 20401, 914, 516, 519, 714, + 826, nil, 2553, 20532, nil, 913, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 20663, 20794, 20925, 21056, + 520, 21187, nil, 160, nil, nil, 936, nil, nil, 889, + nil, 4233, nil, nil, nil, nil, 917, 236, nil, nil, + 1045, nil, 4373, 922, 970, nil, nil, nil, 64, 929, + 780, nil, nil, 556, 24371, nil, 24379, nil, 1377, nil, + 21318, nil, 1241, nil, 929, 228, 943, nil, nil, nil, + nil, 1065, nil, 21449, 1069, nil, 21580, 4513, 93, 1070, + nil, 1077, 480, 4653, nil, 1078, 962, 554, nil, 969, + 964, 553, nil, nil, 21711, 21842, 2693, 4793, nil, 965, + 968, nil, 969, 970, 973, nil, 1003, 983, 979, 973, + 21973, nil, nil, nil, nil, 4933, nil, nil, 32, 22104, + nil, nil, nil, nil, 1028, 986, nil, nil, nil, 987, + 988, nil, 990, 992, nil, 993, nil, nil, 998, 1280, + 997, 819, nil, nil, 33, nil, nil, 39, nil, nil, + nil, 1123, nil, nil, nil, 1060, nil, nil, 1203, nil, + nil, 24431, nil, 24439, nil, 6605, nil, nil, 1044, 1171, + 22235, 1006, 1099, nil, 5073, 34, 35, 1116, 1101, 36, + nil, 5213, 5353, nil, nil, 24456, nil, 8201, nil, 14521, + nil, 24495, nil, nil, nil, nil, 335, 951, 1026, 5493, + nil, nil, nil, nil, 5633, 1027, nil, nil, 1030, 1032, + 1034, 1036, nil, 1039, nil, 628, nil, nil, nil, 1146, + 24106, nil, 1176, 22366, 24167, 24228, 42, 1071, 1179, 1056, + 1063, 1064, 1069, 1074, 1291, 1075, 1307, 706, 1202, nil, + 24512, nil, 24519, nil, 24536, nil, 24575, nil, nil, nil, + 1183, 1123, 1124, nil, 1086, 98, 102, 111, 138, nil, + nil, 24592, nil, nil, nil, nil, 1312, 1094, nil, nil, + 1108, 1109, 1110, 1130, nil, 145, 1131, 1134, 24599, nil, + nil, nil, nil, nil, 1137, nil ] + +racc_action_default = [ + -3, -611, -1, -597, -4, -611, -7, -611, -611, -611, + -611, -30, -611, -611, -34, -611, -611, -289, -46, -599, + -611, -51, -55, -56, -57, -61, -266, -266, -266, -302, + -332, -333, -73, -12, -77, -85, -87, -611, -501, -502, + -611, -611, -611, -611, -225, -611, -599, -239, -280, -281, + -282, -283, -284, -285, -286, -287, -288, -585, -291, -295, + -610, -575, -310, -312, -611, -611, -53, -53, -597, -611, + -611, -611, -611, -334, -335, -337, -338, -339, -340, -442, + -443, -444, -445, -446, -467, -449, -450, -469, -471, -454, + -459, -463, -465, -481, -467, -483, -485, -486, -487, -488, + -583, -490, -491, -584, -493, -494, -495, -496, -497, -498, + -499, -500, -505, -506, -611, -2, -598, -606, -607, -608, + -6, -611, -611, -611, -611, -611, -8, -3, -18, -611, + -116, -117, -118, -119, -120, -121, -122, -123, -124, -128, + -129, -130, -131, -132, -133, -134, -135, -136, -137, -138, + -139, -140, -141, -142, -143, -144, -145, -146, -147, -148, + -149, -150, -151, -152, -153, -154, -155, -156, -157, -158, + -159, -160, -161, -162, -163, -164, -165, -166, -167, -168, + -169, -170, -171, -172, -173, -174, -175, -176, -177, -178, + -179, -180, -181, -182, -183, -184, -185, -186, -187, -188, + -189, -190, -191, -192, -193, -194, -195, -196, -197, -198, + -23, -125, -12, -611, -611, -611, -611, -611, -256, -611, + -611, -595, -596, -611, -611, -599, -600, -50, -611, -501, + -502, -611, -289, -611, -611, -231, -611, -12, -611, -210, + -211, -611, -611, -611, -611, -611, -611, -611, -611, -611, + -611, -611, -611, -611, -611, -611, -611, -611, -611, -611, + -611, -240, -241, -242, -243, -611, -406, -408, -611, -593, + -594, -62, -256, -611, -309, -412, -421, -423, -68, -418, + -69, -599, -70, -246, -261, -270, -270, -265, -611, -271, + -611, -467, -577, -611, -611, -71, -72, -597, -13, -611, + -16, -611, -75, -12, -599, -611, -78, -81, -12, -93, + -94, -611, -611, -101, -302, -305, -599, -611, -332, -333, + -336, -419, -611, -83, -611, -89, -299, -484, -611, -219, + -220, -611, -232, -611, -12, -293, -599, -247, -603, -603, + -611, -611, -603, -611, -311, -397, -52, -611, -611, -611, + -12, -12, -597, -611, -598, -501, -502, -611, -611, -289, + -611, -350, -351, -111, -112, -611, -114, -611, -289, -509, + -611, -501, -502, -325, -116, -117, -158, -159, -160, -176, + -181, -188, -191, -327, -611, -573, -611, -447, -611, -611, + -611, -611, -611, -611, -611, -611, 1036, -5, -609, -24, + -25, -26, -27, -28, -611, -611, -20, -21, -22, -126, + -611, -31, -33, -276, -611, -611, -275, -32, -611, -35, + -611, -289, -43, -45, -199, -251, -271, -47, -48, -36, + -200, -251, -599, -257, -270, -270, -586, -587, -266, -416, + -588, -589, -587, -586, -266, -415, -417, -588, -589, -42, + -207, -49, -599, -308, -611, -611, -611, -256, -299, -611, + -611, -611, -208, -209, -212, -213, -214, -215, -216, -217, + -221, -222, -223, -224, -226, -227, -228, -229, -230, -233, + -234, -235, -236, -599, -244, -427, -266, -586, -587, -59, + -63, -599, -267, -425, -427, -599, -304, -262, -611, -263, + -611, -268, -611, -272, -611, -580, -582, -11, -598, -15, + -17, -599, -74, -297, -90, -79, -611, -599, -256, -611, + -611, -100, -611, -484, -611, -86, -91, -611, -611, -611, + -611, -245, -237, -611, -434, -611, -599, -611, -248, -605, + -604, -250, -605, -300, -301, -576, -313, -533, -12, -341, + -342, -12, -611, -611, -611, -611, -611, -611, -256, -611, + -611, -299, -53, -111, -112, -113, -611, -611, -256, -321, + -507, -611, -12, -511, -329, -599, -448, -468, -473, -611, + -475, -451, -470, -611, -472, -453, -611, -456, -611, -458, + -461, -611, -462, -611, -482, -9, -19, -611, -29, -279, + -611, -611, -256, -611, -611, -611, -611, -420, -611, -258, + -260, -611, -611, -64, -255, -413, -611, -611, -66, -414, + -307, -601, -586, -587, -586, -587, -599, -611, -611, -428, + -58, -409, -425, -253, -611, -386, -611, -303, -270, -269, + -273, -611, -578, -579, -611, -14, -76, -611, -82, -88, + -599, -586, -587, -254, -590, -99, -611, -84, -611, -206, + -218, -599, -610, -610, -292, -294, -296, -603, -398, -533, + -401, -572, -572, -516, -518, -518, -518, -532, -534, -535, + -536, -537, -538, -539, -540, -541, -611, -543, -545, -547, + -552, -554, -555, -557, -562, -564, -565, -567, -568, -569, + -611, -610, -343, -610, -54, -344, -345, -316, -317, -611, + -319, -611, -599, -586, -587, -590, -298, -12, -111, -112, + -115, -599, -12, -611, -323, -611, -12, -533, -533, -611, + -574, -474, -477, -478, -479, -480, -12, -452, -455, -457, + -460, -464, -466, -127, -277, -611, -599, -586, -587, -587, + -586, -44, -252, -611, -602, -270, -38, -202, -39, -203, + -65, -40, -205, -41, -204, -67, -611, -611, -611, -611, + -420, -611, -407, -386, -411, -410, -611, -422, -387, -599, + -389, -12, -424, -264, -274, -581, -80, -420, -92, -306, + -610, -348, -12, -435, -610, -436, -437, -249, -611, -599, + -611, -514, -515, -611, -611, -525, -611, -528, -611, -530, + -611, -352, -611, -354, -356, -363, -599, -546, -556, -566, + -570, -611, -346, -611, -611, -318, -611, -12, -420, -611, + -420, -611, -611, -12, -326, -611, -599, -611, -330, -611, + -278, -420, -37, -201, -259, -611, -238, -12, -60, -572, + -572, -368, -370, -370, -370, -385, -611, -599, -391, -541, + -549, -550, -560, -426, -10, -12, -441, -349, -611, -611, + -439, -399, -402, -404, -611, -572, -553, -571, -517, -518, + -518, -544, -518, -518, -563, -518, -541, -558, -599, -611, + -361, -611, -542, -314, -611, -315, -273, -610, -320, -322, + -508, -611, -328, -510, -512, -511, -476, -429, -611, -366, + -367, -376, -378, -611, -381, -611, -383, -388, -611, -611, + -611, -548, -611, -440, -12, -501, -502, -611, -611, -289, + -438, -12, -12, -400, -513, -611, -521, -611, -523, -611, + -526, -611, -529, -531, -353, -355, -359, -611, -364, -12, + -430, -431, -432, -324, -12, -572, -551, -369, -370, -370, + -370, -370, -561, -370, -390, -599, -393, -395, -396, -559, + -611, -299, -434, -256, -611, -611, -299, -611, -611, -518, + -518, -518, -518, -357, -611, -362, -611, -610, -611, -365, + -611, -373, -611, -375, -611, -379, -611, -382, -384, -392, + -611, -298, -590, -433, -599, -586, -587, -590, -298, -403, + -405, -611, -519, -522, -524, -527, -611, -360, -347, -331, + -370, -370, -370, -370, -394, -420, -518, -358, -611, -371, + -374, -377, -380, -520, -370, -372 ] + +racc_goto_table = [ + 224, 133, 133, 16, 284, 284, 284, 337, 16, 383, + 267, 344, 416, 417, 285, 285, 285, 726, 548, 551, + 128, 211, 556, 228, 268, 119, 639, 333, 639, 275, + 279, 432, 228, 228, 228, 499, 16, 311, 311, 662, + 347, 348, 6, 429, 352, 338, 525, 6, 227, 449, + 607, 219, 350, 351, 821, 438, 444, 327, 305, 269, + 136, 136, 16, 116, 126, 133, 565, 228, 228, 490, + 306, 228, 357, 367, 367, 138, 138, 884, 642, 853, + 790, 2, 801, 802, 423, 491, 115, 423, 535, 323, + 119, 538, 541, 423, 120, 545, 634, 399, 400, 401, + 402, 335, 881, 816, 486, 781, 320, 320, 302, 966, + 945, 968, 271, 278, 280, 1, 304, 962, 864, 16, + 642, 824, 388, 645, 228, 228, 228, 228, 16, 210, + 16, 628, 395, 286, 286, 286, 362, 639, 639, 412, + 636, 320, 320, 320, 346, 346, 430, 405, 346, 369, + 373, 353, 450, 586, 588, 670, 948, 704, 6, 632, + 597, 331, 340, 677, 339, 342, 631, 403, 385, 6, + 341, 546, 360, 569, 282, 295, 296, 856, 384, 334, + 536, 336, 345, 722, 499, 833, 572, 573, 642, 729, + 1024, 905, 968, 284, 962, 855, 857, 874, 415, 415, + 965, 346, 346, 346, 346, 397, 884, 945, 404, 881, + 668, 958, 985, 448, 871, 16, 228, 420, 228, 228, + 420, 228, 439, 547, 709, 798, 420, 228, 228, 888, + 931, 582, 584, 587, 587, 776, 932, 410, 648, 881, + 16, 411, 422, 847, 770, 422, 657, 284, 284, 1017, + 485, 422, 493, 494, 773, 918, 284, 950, 285, 794, + 909, 910, 305, 455, 868, 387, 285, 720, 787, 389, + 626, 390, 391, 392, 393, 228, 228, 799, 394, 731, + 736, 1027, 723, 26, 228, 677, 934, 879, 26, 876, + 956, 438, 444, nil, 881, 427, 428, 522, nil, nil, + nil, nil, 16, 26, 451, 452, 16, nil, nil, nil, + 311, 16, 26, 26, 26, 951, 26, 537, nil, 119, + 275, nil, nil, nil, 279, 552, 725, 311, 305, 504, + 828, 650, nil, 305, nil, 836, 837, 16, 523, 830, + 1018, 509, 26, 677, 677, nil, 519, 26, 26, 954, + nil, 26, 228, 16, 16, 653, nil, 508, 510, nil, + 526, 515, nil, 529, 841, 653, 989, nil, nil, 786, + nil, 712, 639, 228, 119, 553, 554, 286, 302, 320, + 507, 721, 827, 302, 574, 286, 511, 783, 450, 228, + 430, 517, 559, nil, nil, 653, 320, nil, 133, 26, + nil, nil, nil, 653, 26, 26, 26, 26, 26, nil, + 26, 760, nil, 608, nil, 746, 765, 596, 492, 269, + 797, nil, 642, nil, nil, nil, 495, nil, 739, 346, + 739, nil, 284, nil, nil, 555, nil, 756, 758, 438, + 444, 614, 761, 763, nil, nil, 453, 619, nil, 448, + 571, nil, nil, nil, nil, 603, 659, 136, 439, nil, + 228, nil, 795, nil, 627, nil, 575, nil, nil, nil, + nil, 423, 138, nil, nil, nil, 831, 1003, nil, nil, + 835, 423, 423, nil, nil, nil, 423, 423, nil, 614, + nil, nil, nil, 284, nil, 26, 26, 26, 26, 26, + 26, 26, 496, nil, 783, nil, 26, 26, 26, nil, + nil, 16, nil, 448, nil, nil, nil, nil, nil, 311, + 26, 228, 439, 448, 613, 512, nil, 311, nil, nil, + 618, nil, 439, 284, nil, nil, 228, nil, 860, 924, + 757, 759, 711, 284, nil, 762, 764, nil, 717, nil, + nil, 16, 526, 448, 16, 26, 26, nil, 854, 448, + 526, 228, 439, nil, 26, 949, 952, nil, nil, nil, + 439, 228, 630, 701, 705, 16, 703, 284, nil, 842, + 775, nil, 26, 880, nil, 882, 26, 901, 320, nil, + 133, 26, nil, 724, nil, nil, 320, 448, nil, nil, + nil, 907, 638, nil, 420, 228, 439, 608, 16, 743, + 796, nil, nil, 661, 420, 420, nil, 26, 774, 420, + 420, nil, 1025, 423, nil, nil, nil, nil, nil, 422, + nil, 608, 26, 26, 26, nil, nil, nil, nil, 422, + 422, nil, nil, 667, 422, 422, nil, 751, 415, 136, + 311, nil, 13, 26, nil, nil, 614, 13, nil, 619, + nil, 311, nil, nil, 138, nil, 838, 860, nil, 26, + 860, nil, 860, 620, 860, nil, nil, nil, nil, nil, + nil, nil, 843, 526, nil, 13, 978, nil, nil, nil, + 959, nil, 960, 608, 788, 757, 759, 764, 762, 832, + nil, nil, 608, nil, nil, nil, nil, nil, 988, nil, + nil, 13, 633, 755, 979, nil, 637, nil, nil, 320, + 16, 361, 133, nil, nil, 16, 228, 608, nil, 16, + 320, nil, 646, nil, 685, nil, nil, 866, 649, 16, + 26, 870, 829, nil, nil, nil, nil, nil, nil, 860, + nil, 860, nil, 860, nil, 860, 420, 665, nil, nil, + 858, 839, nil, nil, nil, nil, nil, nil, 13, 1020, + nil, nil, nil, nil, 843, nil, nil, 13, nil, 13, + 858, 422, nil, nil, 16, nil, 1004, 860, nil, nil, + nil, 26, nil, nil, nil, 16, 730, nil, nil, 894, + nil, 26, nil, 346, nil, nil, 863, nil, nil, nil, + 653, nil, nil, nil, nil, 29, 26, 867, nil, nil, + 29, 811, nil, nil, nil, nil, 228, nil, nil, nil, + 16, 26, nil, nil, 26, 29, 16, nil, 858, nil, + nil, 26, nil, nil, 29, 29, 29, nil, 29, nil, + 16, 26, 897, nil, 900, 26, 685, nil, nil, 904, + nil, nil, nil, 921, 13, nil, 418, nil, 16, 418, + nil, nil, 927, nil, 29, 418, nil, nil, nil, 29, + 29, nil, 789, 29, 26, 26, nil, nil, 26, 13, + 923, nil, nil, nil, 26, 26, nil, nil, nil, 26, + 26, nil, nil, 346, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 685, 685, nil, nil, nil, nil, + nil, nil, nil, 969, nil, nil, nil, 16, nil, nil, + nil, 29, 320, nil, 16, 16, 29, 29, 29, 29, + 29, 320, 29, nil, 850, nil, 999, 811, 284, 972, + 890, 13, 16, nil, nil, 13, 977, 16, nil, nil, + 13, nil, 974, 448, nil, 875, 859, nil, 448, nil, + 805, 807, 809, nil, 987, nil, 228, 439, nil, nil, + nil, nil, nil, nil, nil, 608, 13, nil, nil, nil, + nil, 685, 320, 685, nil, nil, nil, nil, nil, nil, + 26, nil, 13, 13, nil, 26, 26, nil, 15, 26, + nil, nil, nil, 15, nil, nil, nil, nil, nil, 26, + nil, nil, nil, nil, 811, nil, 811, 29, 29, 29, + 29, 29, 29, 29, nil, nil, 26, 892, 29, 29, + 29, 15, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 29, nil, nil, nil, nil, 903, nil, nil, + nil, nil, nil, nil, 26, nil, nil, 15, nil, nil, + 851, nil, nil, 955, nil, 26, 850, nil, 850, nil, + 850, 983, 811, nil, nil, nil, nil, 29, 29, nil, + nil, 877, nil, nil, 877, nil, 29, nil, 859, nil, + 859, nil, 852, nil, nil, nil, 26, nil, nil, 944, + 26, nil, nil, nil, 29, nil, 26, nil, 29, 811, + nil, 811, 685, 29, 15, nil, nil, nil, nil, 883, + 26, 885, nil, 15, nil, 15, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 26, 29, + nil, 811, nil, nil, nil, 850, nil, 850, nil, 850, + 13, 850, nil, nil, 29, 29, 29, nil, nil, nil, + nil, nil, nil, nil, nil, 936, 938, 859, 940, 942, + nil, 943, nil, nil, nil, 29, 912, 914, 916, nil, + nil, nil, nil, 850, nil, nil, nil, nil, nil, 877, + 13, 29, 851, 13, 851, nil, 851, 26, nil, nil, + nil, nil, nil, nil, 26, 26, nil, nil, nil, nil, + 15, nil, 15, nil, 13, 15, nil, nil, nil, nil, + nil, 15, 26, nil, nil, nil, 961, 26, 963, nil, + nil, nil, nil, nil, nil, 15, nil, nil, nil, nil, + nil, nil, nil, 418, nil, nil, 26, 13, 980, nil, + 981, nil, 982, 418, 418, nil, 17, nil, 418, 418, + nil, 17, 29, nil, nil, 1012, 1013, 1014, 1015, nil, + nil, 851, nil, 851, nil, 851, nil, 851, nil, nil, + nil, nil, 991, 993, 995, 997, nil, 998, nil, 17, + 313, 313, nil, nil, nil, nil, nil, 15, nil, nil, + nil, 15, nil, 1021, nil, 1022, 15, 1023, nil, 851, + nil, nil, 1033, 29, nil, 17, nil, nil, nil, nil, + nil, nil, nil, 29, 1026, 359, 368, 368, nil, nil, + nil, nil, 15, nil, nil, nil, nil, nil, 29, nil, + nil, 1034, nil, nil, 1029, 1030, 1031, 1032, 15, 15, + nil, nil, nil, 29, nil, nil, 29, nil, 1035, 13, + nil, nil, nil, 29, 13, nil, nil, nil, 13, nil, + nil, nil, 17, 29, nil, nil, nil, 29, 13, nil, + nil, 17, nil, 17, nil, nil, nil, nil, nil, nil, + nil, nil, 38, nil, nil, 418, nil, 38, nil, nil, + nil, nil, nil, nil, nil, nil, 29, 29, nil, nil, + 29, nil, nil, nil, nil, nil, 29, 29, nil, nil, + nil, 29, 29, 13, nil, 38, 309, 309, nil, nil, + nil, nil, nil, nil, 13, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 38, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 355, 371, 371, 371, nil, nil, nil, 17, 13, + 421, nil, nil, 421, nil, 13, nil, nil, nil, 421, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 13, + nil, nil, nil, 17, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 15, 13, 38, nil, + nil, 930, nil, nil, nil, nil, nil, 38, nil, 38, + nil, nil, 29, nil, nil, nil, nil, 29, 29, nil, + nil, 29, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 29, nil, nil, nil, nil, 15, nil, nil, 15, + nil, nil, nil, nil, nil, 17, nil, nil, 29, 17, + nil, nil, nil, 313, 17, nil, 13, nil, nil, nil, + 15, nil, nil, 13, 13, nil, nil, nil, nil, nil, + 313, nil, nil, nil, nil, nil, 29, nil, nil, nil, + 17, 13, nil, nil, nil, nil, 13, 29, nil, 15, + nil, nil, nil, 15, 38, nil, 17, 17, nil, 15, + 15, nil, nil, nil, 15, 15, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 29, 38, + nil, nil, 29, nil, nil, nil, nil, nil, 29, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 29, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 29, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 38, nil, nil, nil, 38, nil, nil, nil, 309, + 38, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 15, 309, nil, nil, nil, + 15, nil, 39, nil, 15, nil, 38, 39, nil, 29, + nil, nil, nil, nil, 15, nil, 29, 29, nil, nil, + nil, nil, 38, 38, nil, nil, nil, nil, nil, nil, + nil, 15, nil, nil, 29, 39, 310, 310, nil, 29, + nil, nil, nil, nil, 17, nil, nil, nil, nil, nil, + nil, nil, 313, nil, nil, nil, nil, nil, 29, 15, + 313, 39, nil, nil, nil, nil, nil, nil, nil, nil, + 15, 356, 372, 372, 372, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 17, nil, nil, 17, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 15, nil, nil, 17, nil, + nil, 15, nil, nil, nil, 735, nil, nil, 39, nil, + nil, nil, nil, nil, nil, 15, nil, 39, nil, 39, + nil, nil, nil, nil, nil, nil, nil, 421, nil, nil, + nil, 17, nil, 15, nil, nil, nil, 421, 421, nil, + nil, nil, 421, 421, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 38, nil, nil, 313, nil, nil, nil, nil, 309, nil, + nil, nil, nil, nil, 313, nil, 309, nil, nil, nil, + nil, nil, 15, nil, nil, nil, nil, nil, nil, 15, + 15, nil, nil, nil, 39, nil, nil, nil, nil, nil, + 38, nil, nil, 38, nil, nil, nil, 15, nil, nil, + nil, nil, 15, nil, nil, nil, nil, nil, nil, 39, + nil, nil, nil, nil, 38, nil, nil, nil, nil, nil, + nil, nil, nil, 17, nil, nil, nil, nil, 17, nil, + nil, nil, 17, nil, nil, nil, nil, nil, nil, nil, + nil, 343, 17, nil, nil, nil, nil, 38, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 421, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 39, nil, nil, nil, 39, nil, nil, nil, 310, + 39, nil, nil, nil, nil, nil, nil, 17, nil, 309, + nil, nil, nil, nil, nil, nil, 310, nil, 17, nil, + 309, nil, nil, nil, nil, nil, 39, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 39, 39, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 17, nil, nil, nil, nil, nil, 17, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 17, nil, nil, nil, nil, nil, 38, + nil, nil, nil, nil, 38, nil, 368, nil, 38, nil, + nil, 17, nil, nil, nil, 929, nil, nil, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 413, 426, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 38, nil, nil, 368, nil, nil, nil, + 17, 235, nil, nil, 38, nil, nil, 17, 17, nil, + 283, 283, 283, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 329, 330, 17, 332, nil, nil, nil, + 17, nil, nil, nil, nil, nil, nil, nil, 501, 38, + 503, 283, 283, 505, 506, 38, nil, nil, nil, nil, + 39, nil, nil, nil, nil, nil, nil, nil, 310, 38, + nil, nil, nil, nil, nil, nil, 310, nil, nil, nil, + nil, nil, 371, nil, nil, nil, nil, 38, nil, nil, + nil, 925, nil, nil, nil, nil, nil, nil, nil, nil, + 39, nil, nil, 39, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 39, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 371, nil, nil, nil, 38, nil, nil, nil, + nil, nil, nil, 38, 38, nil, nil, 39, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 38, nil, nil, 599, nil, 38, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 310, + nil, nil, nil, nil, 283, 425, nil, nil, 431, 283, + 310, nil, nil, nil, 431, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 235, nil, nil, + 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, + 482, 483, nil, nil, nil, nil, 484, nil, 640, nil, + 343, nil, 643, 283, 283, nil, nil, nil, nil, 39, + nil, nil, 283, nil, 39, nil, nil, nil, 39, 283, + nil, 283, nil, nil, 283, 283, nil, nil, 39, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 640, + nil, nil, 343, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 426, nil, nil, + nil, nil, 531, nil, 532, nil, nil, nil, nil, nil, + nil, nil, nil, 39, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 39, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 744, nil, nil, nil, nil, nil, nil, nil, nil, 640, + 343, nil, nil, nil, nil, nil, nil, nil, nil, 39, + nil, nil, nil, nil, nil, 39, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 39, + nil, 784, nil, nil, 785, 283, nil, nil, nil, nil, + nil, nil, 372, nil, nil, nil, nil, 39, nil, nil, + nil, 926, nil, 793, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 283, 817, + 431, 431, 431, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 372, nil, nil, nil, 39, nil, nil, nil, + nil, nil, nil, 39, 39, nil, nil, nil, nil, 283, + nil, 283, nil, 283, nil, nil, nil, nil, nil, nil, + nil, 39, nil, nil, nil, 840, 39, nil, nil, 283, + nil, nil, nil, nil, nil, nil, nil, nil, 431, 660, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 283, nil, nil, 283, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 283, 283, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 283, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 887, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 896, nil, nil, nil, + nil, 283, 431, 283, nil, nil, nil, 752, nil, nil, + 283, 283, 431, 431, 343, nil, nil, 431, 431, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 283, nil, nil, 283, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 283, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 283, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 283, nil, nil, nil, + nil, nil, nil, nil, 431, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 431, 431, 431, + 431, nil, 846, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 283, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 283, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 283, 431, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 283 ] + +racc_goto_check = [ + 34, 64, 64, 29, 39, 39, 39, 77, 29, 63, + 145, 96, 23, 23, 78, 78, 78, 108, 99, 99, + 16, 16, 101, 29, 42, 105, 84, 34, 84, 81, + 81, 30, 29, 29, 29, 83, 29, 29, 29, 11, + 18, 18, 7, 27, 18, 78, 58, 7, 21, 27, + 31, 32, 36, 36, 100, 43, 43, 71, 10, 32, + 67, 67, 29, 6, 8, 64, 61, 29, 29, 45, + 56, 29, 29, 29, 29, 68, 68, 185, 189, 132, + 12, 2, 127, 127, 19, 30, 4, 19, 9, 57, + 105, 79, 79, 19, 5, 79, 46, 18, 18, 18, + 18, 7, 180, 122, 43, 134, 73, 73, 52, 138, + 120, 139, 44, 44, 44, 1, 53, 186, 13, 29, + 189, 12, 162, 15, 29, 29, 29, 29, 29, 17, + 29, 148, 162, 80, 80, 80, 20, 84, 84, 24, + 148, 73, 73, 73, 25, 25, 70, 26, 25, 62, + 62, 4, 70, 166, 166, 144, 123, 37, 7, 48, + 69, 74, 76, 174, 80, 80, 82, 7, 94, 7, + 95, 98, 102, 104, 51, 51, 51, 136, 109, 110, + 111, 112, 113, 114, 83, 115, 116, 117, 189, 118, + 138, 119, 139, 39, 186, 124, 130, 136, 78, 78, + 137, 25, 25, 25, 25, 5, 185, 120, 2, 180, + 140, 132, 123, 64, 141, 29, 29, 29, 29, 29, + 29, 29, 81, 142, 101, 143, 29, 29, 29, 122, + 146, 167, 167, 167, 167, 46, 147, 10, 58, 180, + 29, 21, 21, 134, 31, 21, 58, 39, 39, 123, + 149, 21, 151, 152, 155, 136, 39, 156, 78, 157, + 127, 127, 10, 32, 158, 161, 78, 61, 31, 163, + 30, 164, 165, 168, 169, 29, 29, 144, 170, 171, + 172, 123, 173, 47, 29, 174, 127, 178, 47, 182, + 183, 43, 43, nil, 180, 25, 25, 34, nil, nil, + nil, nil, 29, 47, 25, 25, 29, nil, nil, nil, + 29, 29, 47, 47, 47, 12, 47, 34, nil, 105, + 81, nil, nil, nil, 81, 18, 9, 29, 10, 162, + 31, 30, nil, 10, nil, 144, 144, 29, 71, 31, + 100, 7, 47, 174, 174, nil, 32, 47, 47, 108, + nil, 47, 29, 29, 29, 43, nil, 6, 8, nil, + 56, 57, nil, 32, 31, 43, 127, nil, nil, 58, + nil, 30, 84, 29, 105, 10, 10, 80, 52, 73, + 4, 30, 99, 52, 42, 80, 53, 83, 70, 29, + 70, 53, 32, nil, nil, 43, 73, nil, 64, 47, + nil, nil, nil, 43, 47, 47, 47, 47, 47, nil, + 47, 45, nil, 34, nil, 30, 45, 16, 51, 32, + 79, nil, 189, nil, nil, nil, 51, nil, 167, 25, + 167, nil, 39, nil, nil, 4, nil, 27, 27, 43, + 43, 81, 27, 27, nil, nil, 54, 81, nil, 64, + 25, nil, nil, nil, nil, 32, 70, 67, 81, nil, + 29, nil, 23, nil, 34, nil, 25, nil, nil, nil, + nil, 19, 68, nil, nil, nil, 9, 11, nil, nil, + 9, 19, 19, nil, nil, nil, 19, 19, nil, 81, + nil, nil, nil, 39, nil, 47, 47, 47, 47, 47, + 47, 47, 54, nil, 83, nil, 47, 47, 47, nil, + nil, 29, nil, 64, nil, nil, nil, nil, nil, 29, + 47, 29, 81, 64, 44, 54, nil, 29, nil, nil, + 44, nil, 81, 39, nil, nil, 29, nil, 181, 99, + 70, 70, 78, 39, nil, 70, 70, nil, 36, nil, + nil, 29, 56, 64, 29, 47, 47, nil, 133, 64, + 56, 29, 81, nil, 47, 99, 101, nil, nil, nil, + 81, 29, 44, 10, 105, 29, 10, 39, nil, 27, + 96, nil, 47, 133, nil, 133, 47, 9, 73, nil, + 64, 47, nil, 105, nil, nil, 73, 64, nil, nil, + nil, 9, 80, nil, 29, 29, 81, 34, 29, 16, + 77, nil, nil, 25, 29, 29, nil, 47, 145, 29, + 29, nil, 31, 19, nil, nil, nil, nil, nil, 21, + nil, 34, 47, 47, 47, nil, nil, nil, nil, 21, + 21, nil, nil, 80, 21, 21, nil, 7, 78, 67, + 29, nil, 22, 47, nil, nil, 81, 22, nil, 81, + nil, 29, nil, nil, 68, nil, 63, 181, nil, 47, + 181, nil, 181, 54, 181, nil, nil, nil, nil, nil, + nil, nil, 70, 56, nil, 22, 9, nil, nil, nil, + 133, nil, 133, 34, 56, 70, 70, 70, 70, 18, + nil, nil, 34, nil, nil, nil, nil, nil, 9, nil, + nil, 22, 54, 80, 133, nil, 54, nil, nil, 73, + 29, 22, 64, nil, nil, 29, 29, 34, nil, 29, + 73, nil, 54, nil, 179, nil, nil, 77, 54, 29, + 47, 77, 10, nil, nil, nil, nil, nil, nil, 181, + nil, 181, nil, 181, nil, 181, 29, 54, nil, nil, + 34, 10, nil, nil, nil, nil, nil, nil, 22, 133, + nil, nil, nil, nil, 70, nil, nil, 22, nil, 22, + 34, 21, nil, nil, 29, nil, 30, 181, nil, nil, + nil, 47, nil, nil, nil, 29, 54, nil, nil, 18, + nil, 47, nil, 25, nil, nil, 10, nil, nil, nil, + 43, nil, nil, nil, nil, 50, 47, 10, nil, nil, + 50, 121, nil, nil, nil, nil, 29, nil, nil, nil, + 29, 47, nil, nil, 47, 50, 29, nil, 34, nil, + nil, 47, nil, nil, 50, 50, 50, nil, 50, nil, + 29, 47, 10, nil, 105, 47, 179, nil, nil, 105, + nil, nil, nil, 29, 22, nil, 22, nil, 29, 22, + nil, nil, 29, nil, 50, 22, nil, nil, nil, 50, + 50, nil, 54, 50, 47, 47, nil, nil, 47, 22, + 10, nil, nil, nil, 47, 47, nil, nil, nil, 47, + 47, nil, nil, 25, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 179, 179, nil, nil, nil, nil, + nil, nil, nil, 29, nil, nil, nil, 29, nil, nil, + nil, 50, 73, nil, 29, 29, 50, 50, 50, 50, + 50, 73, 50, nil, 126, nil, 34, 121, 39, 10, + 121, 22, 29, nil, nil, 22, 10, 29, nil, nil, + 22, nil, 32, 64, nil, 126, 179, nil, 64, nil, + 177, 177, 177, nil, 10, nil, 29, 81, nil, nil, + nil, nil, nil, nil, nil, 34, 22, nil, nil, nil, + nil, 179, 73, 179, nil, nil, nil, nil, nil, nil, + 47, nil, 22, 22, nil, 47, 47, nil, 28, 47, + nil, nil, nil, 28, nil, nil, nil, nil, nil, 47, + nil, nil, nil, nil, 121, nil, 121, 50, 50, 50, + 50, 50, 50, 50, nil, nil, 47, 54, 50, 50, + 50, 28, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 50, nil, nil, nil, nil, 54, nil, nil, + nil, nil, nil, nil, 47, nil, nil, 28, nil, nil, + 128, nil, nil, 126, nil, 47, 126, nil, 126, nil, + 126, 121, 121, nil, nil, nil, nil, 50, 50, nil, + nil, 128, nil, nil, 128, nil, 50, nil, 179, nil, + 179, nil, 131, nil, nil, nil, 47, nil, nil, 54, + 47, nil, nil, nil, 50, nil, 47, nil, 50, 121, + nil, 121, 179, 50, 28, nil, nil, nil, nil, 131, + 47, 131, nil, 28, nil, 28, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 47, 50, + nil, 121, nil, nil, nil, 126, nil, 126, nil, 126, + 22, 126, nil, nil, 50, 50, 50, nil, nil, nil, + nil, nil, nil, nil, nil, 177, 177, 179, 177, 177, + nil, 177, nil, nil, nil, 50, 129, 129, 129, nil, + nil, nil, nil, 126, nil, nil, nil, nil, nil, 128, + 22, 50, 128, 22, 128, nil, 128, 47, nil, nil, + nil, nil, nil, nil, 47, 47, nil, nil, nil, nil, + 28, nil, 28, nil, 22, 28, nil, nil, nil, nil, + nil, 28, 47, nil, nil, nil, 131, 47, 131, nil, + nil, nil, nil, nil, nil, 28, nil, nil, nil, nil, + nil, nil, nil, 22, nil, nil, 47, 22, 131, nil, + 131, nil, 131, 22, 22, nil, 33, nil, 22, 22, + nil, 33, 50, nil, nil, 177, 177, 177, 177, nil, + nil, 128, nil, 128, nil, 128, nil, 128, nil, nil, + nil, nil, 129, 129, 129, 129, nil, 129, nil, 33, + 33, 33, nil, nil, nil, nil, nil, 28, nil, nil, + nil, 28, nil, 131, nil, 131, 28, 131, nil, 128, + nil, nil, 177, 50, nil, 33, nil, nil, nil, nil, + nil, nil, nil, 50, 131, 33, 33, 33, nil, nil, + nil, nil, 28, nil, nil, nil, nil, nil, 50, nil, + nil, 131, nil, nil, 129, 129, 129, 129, 28, 28, + nil, nil, nil, 50, nil, nil, 50, nil, 129, 22, + nil, nil, nil, 50, 22, nil, nil, nil, 22, nil, + nil, nil, 33, 50, nil, nil, nil, 50, 22, nil, + nil, 33, nil, 33, nil, nil, nil, nil, nil, nil, + nil, nil, 59, nil, nil, 22, nil, 59, nil, nil, + nil, nil, nil, nil, nil, nil, 50, 50, nil, nil, + 50, nil, nil, nil, nil, nil, 50, 50, nil, nil, + nil, 50, 50, 22, nil, 59, 59, 59, nil, nil, + nil, nil, nil, nil, 22, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 59, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 59, 59, 59, 59, nil, nil, nil, 33, 22, + 33, nil, nil, 33, nil, 22, nil, nil, nil, 33, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 22, + nil, nil, nil, 33, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 28, 22, 59, nil, + nil, 22, nil, nil, nil, nil, nil, 59, nil, 59, + nil, nil, 50, nil, nil, nil, nil, 50, 50, nil, + nil, 50, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 50, nil, nil, nil, nil, 28, nil, nil, 28, + nil, nil, nil, nil, nil, 33, nil, nil, 50, 33, + nil, nil, nil, 33, 33, nil, 22, nil, nil, nil, + 28, nil, nil, 22, 22, nil, nil, nil, nil, nil, + 33, nil, nil, nil, nil, nil, 50, nil, nil, nil, + 33, 22, nil, nil, nil, nil, 22, 50, nil, 28, + nil, nil, nil, 28, 59, nil, 33, 33, nil, 28, + 28, nil, nil, nil, 28, 28, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 50, 59, + nil, nil, 50, nil, nil, nil, nil, nil, 50, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 50, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 50, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 59, nil, nil, nil, 59, nil, nil, nil, 59, + 59, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 28, 59, nil, nil, nil, + 28, nil, 60, nil, 28, nil, 59, 60, nil, 50, + nil, nil, nil, nil, 28, nil, 50, 50, nil, nil, + nil, nil, 59, 59, nil, nil, nil, nil, nil, nil, + nil, 28, nil, nil, 50, 60, 60, 60, nil, 50, + nil, nil, nil, nil, 33, nil, nil, nil, nil, nil, + nil, nil, 33, nil, nil, nil, nil, nil, 50, 28, + 33, 60, nil, nil, nil, nil, nil, nil, nil, nil, + 28, 60, 60, 60, 60, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 33, nil, nil, 33, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 28, nil, nil, 33, nil, + nil, 28, nil, nil, nil, 33, nil, nil, 60, nil, + nil, nil, nil, nil, nil, 28, nil, 60, nil, 60, + nil, nil, nil, nil, nil, nil, nil, 33, nil, nil, + nil, 33, nil, 28, nil, nil, nil, 33, 33, nil, + nil, nil, 33, 33, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 59, nil, nil, 33, nil, nil, nil, nil, 59, nil, + nil, nil, nil, nil, 33, nil, 59, nil, nil, nil, + nil, nil, 28, nil, nil, nil, nil, nil, nil, 28, + 28, nil, nil, nil, 60, nil, nil, nil, nil, nil, + 59, nil, nil, 59, nil, nil, nil, 28, nil, nil, + nil, nil, 28, nil, nil, nil, nil, nil, nil, 60, + nil, nil, nil, nil, 59, nil, nil, nil, nil, nil, + nil, nil, nil, 33, nil, nil, nil, nil, 33, nil, + nil, nil, 33, nil, nil, nil, nil, nil, nil, nil, + nil, 75, 33, nil, nil, nil, nil, 59, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 33, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 60, nil, nil, nil, 60, nil, nil, nil, 60, + 60, nil, nil, nil, nil, nil, nil, 33, nil, 59, + nil, nil, nil, nil, nil, nil, 60, nil, 33, nil, + 59, nil, nil, nil, nil, nil, 60, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 60, 60, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 33, nil, nil, nil, nil, nil, 33, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 33, nil, nil, nil, nil, nil, 59, + nil, nil, nil, nil, 59, nil, 33, nil, 59, nil, + nil, 33, nil, nil, nil, 33, nil, nil, 59, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 75, 75, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 59, nil, nil, 33, nil, nil, nil, + 33, 35, nil, nil, 59, nil, nil, 33, 33, nil, + 35, 35, 35, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 35, 35, 33, 35, nil, nil, nil, + 33, nil, nil, nil, nil, nil, nil, nil, 75, 59, + 75, 35, 35, 75, 75, 59, nil, nil, nil, nil, + 60, nil, nil, nil, nil, nil, nil, nil, 60, 59, + nil, nil, nil, nil, nil, nil, 60, nil, nil, nil, + nil, nil, 59, nil, nil, nil, nil, 59, nil, nil, + nil, 59, nil, nil, nil, nil, nil, nil, nil, nil, + 60, nil, nil, 60, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 60, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 59, nil, nil, nil, 59, nil, nil, nil, + nil, nil, nil, 59, 59, nil, nil, 60, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 59, nil, nil, 75, nil, 59, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 60, + nil, nil, nil, nil, 35, 35, nil, nil, 35, 35, + 60, nil, nil, nil, 35, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 35, nil, nil, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 35, nil, nil, nil, nil, 35, nil, 75, nil, + 75, nil, 75, 35, 35, nil, nil, nil, nil, 60, + nil, nil, 35, nil, 60, nil, nil, nil, 60, 35, + nil, 35, nil, nil, 35, 35, nil, nil, 60, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 75, + nil, nil, 75, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 75, nil, nil, + nil, nil, 35, nil, 35, nil, nil, nil, nil, nil, + nil, nil, nil, 60, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 60, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 75, nil, nil, nil, nil, nil, nil, nil, nil, 75, + 75, nil, nil, nil, nil, nil, nil, nil, nil, 60, + nil, nil, nil, nil, nil, 60, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 60, + nil, 75, nil, nil, 75, 35, nil, nil, nil, nil, + nil, nil, 60, nil, nil, nil, nil, 60, nil, nil, + nil, 60, nil, 75, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 35, 75, + 35, 35, 35, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 60, nil, nil, nil, 60, nil, nil, nil, + nil, nil, nil, 60, 60, nil, nil, nil, nil, 35, + nil, 35, nil, 35, nil, nil, nil, nil, nil, nil, + nil, 60, nil, nil, nil, 75, 60, nil, nil, 35, + nil, nil, nil, nil, nil, nil, nil, nil, 35, 35, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 35, nil, nil, 35, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 35, 35, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 35, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 75, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 75, nil, nil, nil, + nil, 35, 35, 35, nil, nil, nil, 35, nil, nil, + 35, 35, 35, 35, 75, nil, nil, 35, 35, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 35, nil, nil, 35, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 35, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 35, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 35, nil, nil, nil, + nil, nil, nil, nil, 35, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 35, 35, 35, + 35, nil, 35, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 35, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 35, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 35, 35, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 35 ] + +racc_goto_pointer = [ + nil, 115, 81, nil, 83, 89, 60, 42, 57, -246, + 25, -495, -582, -672, nil, -385, 12, 120, -24, -130, + 67, 28, 652, -201, -74, 80, 19, -174, 1008, 3, + -187, -382, 35, 1266, -19, 2171, -14, -395, nil, -25, + nil, nil, 0, -164, 86, -202, -397, 283, -330, nil, + 815, 145, 75, 83, 221, nil, 36, 54, -278, 1402, + 1732, -299, 79, -63, -7, nil, nil, 52, 67, -249, + -71, 16, nil, 72, 117, 1940, 102, -53, -15, -247, + 104, 3, -320, -251, -472, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 96, 109, -51, nil, -174, -329, + -647, -331, 103, nil, -196, 22, nil, nil, -556, 106, + 121, -155, 122, 119, -386, -539, -187, -196, -385, -647, + -779, 135, -583, -735, -584, nil, 165, -589, 291, 334, + -583, 323, -700, -221, -530, nil, -602, -719, -810, -808, + -337, -584, -122, -443, -392, -12, -642, -637, -354, -16, + nil, -24, -24, nil, nil, -375, -640, -404, -530, nil, + nil, 183, 38, 182, 183, 183, -238, -158, 183, 183, + 186, -300, -300, -288, -384, nil, nil, 296, -517, 187, + -702, -241, -511, -618, nil, -729, -796, nil, nil, -422 ] + +racc_goto_default = [ + nil, nil, nil, 3, nil, 4, 354, 300, nil, nil, + 534, nil, 822, nil, 297, 298, nil, nil, nil, 11, + 12, 18, 233, nil, nil, 14, nil, 419, 234, 328, + nil, nil, 567, 232, 454, 21, nil, nil, 349, 22, + 23, 24, nil, 656, nil, nil, nil, 317, nil, 25, + 314, 433, 32, nil, nil, 34, 37, 36, nil, 229, + 230, 366, nil, 135, 441, 134, 137, 80, 81, nil, + 424, 95, 44, 47, 265, 289, nil, 791, 434, nil, + 435, 446, 615, 497, 287, 273, 48, 49, 50, 51, + 52, 53, 54, 55, 56, nil, 274, 62, nil, nil, + nil, nil, nil, 70, nil, 549, 71, 72, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 813, 684, nil, 814, 957, 849, 672, nil, 673, nil, + nil, 674, nil, 676, nil, 778, nil, nil, nil, 682, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 445, nil, nil, 635, 629, nil, nil, nil, nil, 79, + 82, 83, nil, nil, nil, nil, nil, 577, nil, nil, + nil, nil, nil, nil, 878, 728, 671, nil, 675, 886, + 687, 689, 690, 861, 693, 694, 862, 697, 700, 292 ] + +racc_reduce_table = [ + 0, 0, :racc_error, + 1, 146, :_reduce_none, + 2, 147, :_reduce_2, + 0, 148, :_reduce_3, + 1, 148, :_reduce_4, + 3, 148, :_reduce_5, + 2, 148, :_reduce_6, + 1, 150, :_reduce_none, + 2, 150, :_reduce_8, + 3, 153, :_reduce_9, + 4, 154, :_reduce_10, + 2, 155, :_reduce_11, + 0, 159, :_reduce_12, + 1, 159, :_reduce_13, + 3, 159, :_reduce_14, + 2, 159, :_reduce_15, + 1, 160, :_reduce_none, + 2, 160, :_reduce_17, + 0, 171, :_reduce_18, + 4, 152, :_reduce_19, + 3, 152, :_reduce_20, + 3, 152, :_reduce_21, + 3, 152, :_reduce_22, + 2, 152, :_reduce_23, + 3, 152, :_reduce_24, + 3, 152, :_reduce_25, + 3, 152, :_reduce_26, + 3, 152, :_reduce_27, + 3, 152, :_reduce_28, + 4, 152, :_reduce_29, + 1, 152, :_reduce_none, + 3, 152, :_reduce_31, + 3, 152, :_reduce_32, + 3, 152, :_reduce_33, + 1, 152, :_reduce_none, + 3, 164, :_reduce_35, + 3, 164, :_reduce_36, + 6, 164, :_reduce_37, + 5, 164, :_reduce_38, + 5, 164, :_reduce_39, + 5, 164, :_reduce_40, + 5, 164, :_reduce_41, + 3, 164, :_reduce_42, + 1, 172, :_reduce_none, + 3, 172, :_reduce_44, + 1, 172, :_reduce_none, + 1, 170, :_reduce_none, + 3, 170, :_reduce_47, + 3, 170, :_reduce_48, + 3, 170, :_reduce_49, + 2, 170, :_reduce_50, + 1, 170, :_reduce_none, + 1, 163, :_reduce_none, + 0, 183, :_reduce_53, + 3, 181, :_reduce_54, + 1, 166, :_reduce_none, + 1, 166, :_reduce_none, + 1, 185, :_reduce_none, + 4, 185, :_reduce_58, + 0, 193, :_reduce_59, + 4, 190, :_reduce_60, + 1, 192, :_reduce_none, + 2, 184, :_reduce_62, + 3, 184, :_reduce_63, + 4, 184, :_reduce_64, + 5, 184, :_reduce_65, + 4, 184, :_reduce_66, + 5, 184, :_reduce_67, + 2, 184, :_reduce_68, + 2, 184, :_reduce_69, + 2, 184, :_reduce_70, + 2, 184, :_reduce_71, + 2, 184, :_reduce_72, + 1, 165, :_reduce_73, + 3, 165, :_reduce_74, + 1, 198, :_reduce_75, + 3, 198, :_reduce_76, + 1, 197, :_reduce_none, + 2, 197, :_reduce_78, + 3, 197, :_reduce_79, + 5, 197, :_reduce_80, + 2, 197, :_reduce_81, + 4, 197, :_reduce_82, + 2, 197, :_reduce_83, + 4, 197, :_reduce_84, + 1, 197, :_reduce_85, + 3, 197, :_reduce_86, + 1, 201, :_reduce_none, + 3, 201, :_reduce_88, + 2, 200, :_reduce_89, + 3, 200, :_reduce_90, + 1, 203, :_reduce_91, + 3, 203, :_reduce_92, + 1, 202, :_reduce_93, + 1, 202, :_reduce_94, + 4, 202, :_reduce_95, + 3, 202, :_reduce_96, + 3, 202, :_reduce_97, + 3, 202, :_reduce_98, + 3, 202, :_reduce_99, + 2, 202, :_reduce_100, + 1, 202, :_reduce_101, + 1, 167, :_reduce_102, + 1, 167, :_reduce_103, + 4, 167, :_reduce_104, + 3, 167, :_reduce_105, + 3, 167, :_reduce_106, + 3, 167, :_reduce_107, + 3, 167, :_reduce_108, + 2, 167, :_reduce_109, + 1, 167, :_reduce_110, + 1, 206, :_reduce_111, + 1, 206, :_reduce_none, + 2, 207, :_reduce_113, + 1, 207, :_reduce_114, + 3, 207, :_reduce_115, + 1, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 211, :_reduce_121, + 1, 211, :_reduce_none, + 1, 161, :_reduce_none, + 1, 161, :_reduce_none, + 1, 162, :_reduce_125, + 0, 214, :_reduce_126, + 4, 162, :_reduce_127, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 3, 180, :_reduce_199, + 3, 180, :_reduce_200, + 6, 180, :_reduce_201, + 5, 180, :_reduce_202, + 5, 180, :_reduce_203, + 5, 180, :_reduce_204, + 5, 180, :_reduce_205, + 4, 180, :_reduce_206, + 3, 180, :_reduce_207, + 3, 180, :_reduce_208, + 3, 180, :_reduce_209, + 2, 180, :_reduce_210, + 2, 180, :_reduce_211, + 3, 180, :_reduce_212, + 3, 180, :_reduce_213, + 3, 180, :_reduce_214, + 3, 180, :_reduce_215, + 3, 180, :_reduce_216, + 3, 180, :_reduce_217, + 4, 180, :_reduce_218, + 2, 180, :_reduce_219, + 2, 180, :_reduce_220, + 3, 180, :_reduce_221, + 3, 180, :_reduce_222, + 3, 180, :_reduce_223, + 3, 180, :_reduce_224, + 1, 180, :_reduce_none, + 3, 180, :_reduce_226, + 3, 180, :_reduce_227, + 3, 180, :_reduce_228, + 3, 180, :_reduce_229, + 3, 180, :_reduce_230, + 2, 180, :_reduce_231, + 2, 180, :_reduce_232, + 3, 180, :_reduce_233, + 3, 180, :_reduce_234, + 3, 180, :_reduce_235, + 3, 180, :_reduce_236, + 3, 180, :_reduce_237, + 6, 180, :_reduce_238, + 1, 180, :_reduce_none, + 1, 219, :_reduce_none, + 1, 219, :_reduce_none, + 1, 219, :_reduce_none, + 1, 219, :_reduce_none, + 3, 217, :_reduce_244, + 3, 217, :_reduce_245, + 1, 220, :_reduce_none, + 1, 221, :_reduce_none, + 2, 221, :_reduce_none, + 4, 221, :_reduce_249, + 2, 221, :_reduce_250, + 1, 215, :_reduce_none, + 3, 215, :_reduce_252, + 3, 226, :_reduce_253, + 0, 227, :_reduce_254, + 1, 227, :_reduce_none, + 0, 175, :_reduce_256, + 1, 175, :_reduce_none, + 2, 175, :_reduce_none, + 4, 175, :_reduce_259, + 2, 175, :_reduce_260, + 1, 196, :_reduce_261, + 2, 196, :_reduce_262, + 2, 196, :_reduce_263, + 4, 196, :_reduce_264, + 1, 196, :_reduce_265, + 0, 230, :_reduce_266, + 2, 189, :_reduce_267, + 2, 229, :_reduce_268, + 2, 228, :_reduce_269, + 0, 228, :_reduce_270, + 1, 223, :_reduce_271, + 2, 223, :_reduce_272, + 3, 223, :_reduce_273, + 4, 223, :_reduce_274, + 1, 169, :_reduce_275, + 1, 169, :_reduce_none, + 3, 168, :_reduce_277, + 4, 168, :_reduce_278, + 2, 168, :_reduce_279, + 1, 218, :_reduce_none, + 1, 218, :_reduce_none, + 1, 218, :_reduce_none, + 1, 218, :_reduce_none, + 1, 218, :_reduce_none, + 1, 218, :_reduce_none, + 1, 218, :_reduce_none, + 1, 218, :_reduce_none, + 1, 218, :_reduce_none, + 1, 218, :_reduce_none, + 1, 218, :_reduce_290, + 0, 255, :_reduce_291, + 4, 218, :_reduce_292, + 0, 256, :_reduce_293, + 4, 218, :_reduce_294, + 0, 257, :_reduce_295, + 4, 218, :_reduce_296, + 3, 218, :_reduce_297, + 3, 218, :_reduce_298, + 2, 218, :_reduce_299, + 3, 218, :_reduce_300, + 3, 218, :_reduce_301, + 1, 218, :_reduce_302, + 4, 218, :_reduce_303, + 3, 218, :_reduce_304, + 1, 218, :_reduce_305, + 5, 218, :_reduce_306, + 4, 218, :_reduce_307, + 3, 218, :_reduce_308, + 2, 218, :_reduce_309, + 1, 218, :_reduce_none, + 2, 218, :_reduce_311, + 0, 258, :_reduce_312, + 3, 218, :_reduce_313, + 6, 218, :_reduce_314, + 6, 218, :_reduce_315, + 4, 218, :_reduce_316, + 4, 218, :_reduce_317, + 5, 218, :_reduce_318, + 4, 218, :_reduce_319, + 6, 218, :_reduce_320, + 0, 259, :_reduce_321, + 6, 218, :_reduce_322, + 0, 260, :_reduce_323, + 7, 218, :_reduce_324, + 0, 261, :_reduce_325, + 5, 218, :_reduce_326, + 0, 262, :_reduce_327, + 6, 218, :_reduce_328, + 0, 263, :_reduce_329, + 0, 264, :_reduce_330, + 9, 218, :_reduce_331, + 1, 218, :_reduce_332, + 1, 218, :_reduce_333, + 1, 218, :_reduce_334, + 1, 218, :_reduce_335, + 1, 174, :_reduce_none, + 1, 248, :_reduce_337, + 1, 251, :_reduce_338, + 1, 252, :_reduce_339, + 1, 195, :_reduce_340, + 1, 244, :_reduce_none, + 1, 244, :_reduce_none, + 2, 244, :_reduce_343, + 1, 182, :_reduce_none, + 1, 182, :_reduce_none, + 1, 245, :_reduce_none, + 5, 245, :_reduce_347, + 1, 157, :_reduce_none, + 2, 157, :_reduce_349, + 1, 247, :_reduce_none, + 1, 247, :_reduce_none, + 1, 265, :_reduce_352, + 3, 265, :_reduce_353, + 1, 268, :_reduce_354, + 3, 268, :_reduce_355, + 1, 267, :_reduce_none, + 4, 267, :_reduce_357, + 6, 267, :_reduce_358, + 3, 267, :_reduce_359, + 5, 267, :_reduce_360, + 2, 267, :_reduce_361, + 4, 267, :_reduce_362, + 1, 267, :_reduce_363, + 3, 267, :_reduce_364, + 4, 269, :_reduce_365, + 2, 269, :_reduce_366, + 2, 269, :_reduce_367, + 1, 269, :_reduce_368, + 2, 274, :_reduce_369, + 0, 274, :_reduce_370, + 6, 275, :_reduce_371, + 8, 275, :_reduce_372, + 4, 275, :_reduce_373, + 6, 275, :_reduce_374, + 4, 275, :_reduce_375, + 2, 275, :_reduce_none, + 6, 275, :_reduce_377, + 2, 275, :_reduce_378, + 4, 275, :_reduce_379, + 6, 275, :_reduce_380, + 2, 275, :_reduce_381, + 4, 275, :_reduce_382, + 2, 275, :_reduce_383, + 4, 275, :_reduce_384, + 1, 275, :_reduce_none, + 0, 279, :_reduce_386, + 1, 279, :_reduce_387, + 3, 280, :_reduce_388, + 1, 280, :_reduce_389, + 4, 280, :_reduce_390, + 1, 281, :_reduce_391, + 4, 281, :_reduce_392, + 1, 282, :_reduce_393, + 3, 282, :_reduce_394, + 1, 283, :_reduce_395, + 1, 283, :_reduce_none, + 0, 287, :_reduce_397, + 0, 288, :_reduce_398, + 4, 243, :_reduce_399, + 4, 285, :_reduce_400, + 1, 285, :_reduce_401, + 0, 291, :_reduce_402, + 4, 286, :_reduce_403, + 0, 292, :_reduce_404, + 4, 286, :_reduce_405, + 0, 294, :_reduce_406, + 4, 290, :_reduce_407, + 2, 186, :_reduce_408, + 4, 186, :_reduce_409, + 5, 186, :_reduce_410, + 5, 186, :_reduce_411, + 2, 242, :_reduce_412, + 4, 242, :_reduce_413, + 4, 242, :_reduce_414, + 3, 242, :_reduce_415, + 3, 242, :_reduce_416, + 3, 242, :_reduce_417, + 2, 242, :_reduce_418, + 1, 242, :_reduce_419, + 4, 242, :_reduce_420, + 0, 296, :_reduce_421, + 4, 241, :_reduce_422, + 0, 297, :_reduce_423, + 4, 241, :_reduce_424, + 0, 298, :_reduce_425, + 3, 191, :_reduce_426, + 0, 299, :_reduce_427, + 0, 300, :_reduce_428, + 4, 293, :_reduce_429, + 5, 246, :_reduce_430, + 1, 301, :_reduce_431, + 1, 301, :_reduce_none, + 6, 156, :_reduce_433, + 0, 156, :_reduce_434, + 1, 302, :_reduce_435, + 1, 302, :_reduce_none, + 1, 302, :_reduce_none, + 2, 303, :_reduce_438, + 1, 303, :_reduce_none, + 2, 158, :_reduce_440, + 1, 158, :_reduce_none, + 1, 231, :_reduce_none, + 1, 231, :_reduce_none, + 1, 231, :_reduce_none, + 1, 232, :_reduce_445, + 1, 305, :_reduce_446, + 2, 305, :_reduce_447, + 3, 306, :_reduce_448, + 1, 306, :_reduce_449, + 1, 306, :_reduce_450, + 3, 233, :_reduce_451, + 4, 234, :_reduce_452, + 3, 235, :_reduce_453, + 0, 310, :_reduce_454, + 3, 310, :_reduce_455, + 1, 311, :_reduce_456, + 2, 311, :_reduce_457, + 3, 237, :_reduce_458, + 0, 313, :_reduce_459, + 3, 313, :_reduce_460, + 3, 236, :_reduce_461, + 3, 238, :_reduce_462, + 0, 314, :_reduce_463, + 3, 314, :_reduce_464, + 0, 315, :_reduce_465, + 3, 315, :_reduce_466, + 0, 307, :_reduce_467, + 2, 307, :_reduce_468, + 0, 308, :_reduce_469, + 2, 308, :_reduce_470, + 0, 309, :_reduce_471, + 2, 309, :_reduce_472, + 1, 312, :_reduce_473, + 2, 312, :_reduce_474, + 0, 317, :_reduce_475, + 4, 312, :_reduce_476, + 1, 316, :_reduce_477, + 1, 316, :_reduce_478, + 1, 316, :_reduce_479, + 1, 316, :_reduce_none, + 1, 212, :_reduce_481, + 3, 213, :_reduce_482, + 1, 304, :_reduce_483, + 2, 304, :_reduce_484, + 1, 216, :_reduce_485, + 1, 216, :_reduce_486, + 1, 216, :_reduce_487, + 1, 216, :_reduce_488, + 1, 204, :_reduce_489, + 1, 204, :_reduce_490, + 1, 204, :_reduce_491, + 1, 204, :_reduce_492, + 1, 204, :_reduce_493, + 1, 205, :_reduce_494, + 1, 205, :_reduce_495, + 1, 205, :_reduce_496, + 1, 205, :_reduce_497, + 1, 205, :_reduce_498, + 1, 205, :_reduce_499, + 1, 205, :_reduce_500, + 1, 239, :_reduce_501, + 1, 239, :_reduce_502, + 1, 173, :_reduce_503, + 1, 173, :_reduce_504, + 1, 178, :_reduce_505, + 1, 178, :_reduce_506, + 0, 318, :_reduce_507, + 4, 249, :_reduce_508, + 0, 249, :_reduce_509, + 3, 253, :_reduce_510, + 0, 320, :_reduce_511, + 3, 253, :_reduce_512, + 4, 319, :_reduce_513, + 2, 319, :_reduce_514, + 2, 319, :_reduce_515, + 1, 319, :_reduce_516, + 2, 322, :_reduce_517, + 0, 322, :_reduce_518, + 6, 289, :_reduce_519, + 8, 289, :_reduce_520, + 4, 289, :_reduce_521, + 6, 289, :_reduce_522, + 4, 289, :_reduce_523, + 6, 289, :_reduce_524, + 2, 289, :_reduce_525, + 4, 289, :_reduce_526, + 6, 289, :_reduce_527, + 2, 289, :_reduce_528, + 4, 289, :_reduce_529, + 2, 289, :_reduce_530, + 4, 289, :_reduce_531, + 1, 289, :_reduce_532, + 0, 289, :_reduce_533, + 1, 284, :_reduce_534, + 1, 284, :_reduce_535, + 1, 284, :_reduce_536, + 1, 284, :_reduce_537, + 1, 266, :_reduce_none, + 1, 266, :_reduce_539, + 1, 324, :_reduce_540, + 1, 325, :_reduce_541, + 3, 325, :_reduce_542, + 1, 276, :_reduce_543, + 3, 276, :_reduce_544, + 1, 326, :_reduce_545, + 2, 327, :_reduce_546, + 1, 327, :_reduce_547, + 2, 328, :_reduce_548, + 1, 328, :_reduce_549, + 1, 270, :_reduce_550, + 3, 270, :_reduce_551, + 1, 321, :_reduce_552, + 3, 321, :_reduce_553, + 1, 329, :_reduce_none, + 1, 329, :_reduce_none, + 2, 271, :_reduce_556, + 1, 271, :_reduce_557, + 3, 330, :_reduce_558, + 3, 331, :_reduce_559, + 1, 277, :_reduce_560, + 3, 277, :_reduce_561, + 1, 323, :_reduce_562, + 3, 323, :_reduce_563, + 1, 332, :_reduce_none, + 1, 332, :_reduce_none, + 2, 278, :_reduce_566, + 1, 278, :_reduce_567, + 1, 333, :_reduce_none, + 1, 333, :_reduce_none, + 2, 273, :_reduce_570, + 2, 272, :_reduce_571, + 0, 272, :_reduce_572, + 1, 254, :_reduce_none, + 3, 254, :_reduce_574, + 0, 240, :_reduce_575, + 2, 240, :_reduce_none, + 1, 225, :_reduce_577, + 3, 225, :_reduce_578, + 3, 334, :_reduce_579, + 2, 334, :_reduce_580, + 4, 334, :_reduce_581, + 2, 334, :_reduce_582, + 1, 194, :_reduce_none, + 1, 194, :_reduce_none, + 1, 194, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 295, :_reduce_none, + 1, 295, :_reduce_none, + 1, 295, :_reduce_none, + 1, 187, :_reduce_none, + 1, 187, :_reduce_none, + 1, 177, :_reduce_595, + 1, 177, :_reduce_596, + 0, 149, :_reduce_none, + 1, 149, :_reduce_none, + 0, 179, :_reduce_none, + 1, 179, :_reduce_none, + 2, 199, :_reduce_601, + 2, 176, :_reduce_602, + 0, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 250, :_reduce_606, + 1, 250, :_reduce_none, + 1, 151, :_reduce_none, + 2, 151, :_reduce_none, + 0, 222, :_reduce_610 ] + +racc_reduce_n = 611 + +racc_shift_n = 1036 + +racc_token_table = { + false => 0, + :error => 1, + :kCLASS => 2, + :kMODULE => 3, + :kDEF => 4, + :kUNDEF => 5, + :kBEGIN => 6, + :kRESCUE => 7, + :kENSURE => 8, + :kEND => 9, + :kIF => 10, + :kUNLESS => 11, + :kTHEN => 12, + :kELSIF => 13, + :kELSE => 14, + :kCASE => 15, + :kWHEN => 16, + :kWHILE => 17, + :kUNTIL => 18, + :kFOR => 19, + :kBREAK => 20, + :kNEXT => 21, + :kREDO => 22, + :kRETRY => 23, + :kIN => 24, + :kDO => 25, + :kDO_COND => 26, + :kDO_BLOCK => 27, + :kDO_LAMBDA => 28, + :kRETURN => 29, + :kYIELD => 30, + :kSUPER => 31, + :kSELF => 32, + :kNIL => 33, + :kTRUE => 34, + :kFALSE => 35, + :kAND => 36, + :kOR => 37, + :kNOT => 38, + :kIF_MOD => 39, + :kUNLESS_MOD => 40, + :kWHILE_MOD => 41, + :kUNTIL_MOD => 42, + :kRESCUE_MOD => 43, + :kALIAS => 44, + :kDEFINED => 45, + :klBEGIN => 46, + :klEND => 47, + :k__LINE__ => 48, + :k__FILE__ => 49, + :k__ENCODING__ => 50, + :tIDENTIFIER => 51, + :tFID => 52, + :tGVAR => 53, + :tIVAR => 54, + :tCONSTANT => 55, + :tLABEL => 56, + :tCVAR => 57, + :tNTH_REF => 58, + :tBACK_REF => 59, + :tSTRING_CONTENT => 60, + :tINTEGER => 61, + :tFLOAT => 62, + :tUPLUS => 63, + :tUMINUS => 64, + :tUNARY_NUM => 65, + :tPOW => 66, + :tCMP => 67, + :tEQ => 68, + :tEQQ => 69, + :tNEQ => 70, + :tGEQ => 71, + :tLEQ => 72, + :tANDOP => 73, + :tOROP => 74, + :tMATCH => 75, + :tNMATCH => 76, + :tDOT => 77, + :tDOT2 => 78, + :tDOT3 => 79, + :tAREF => 80, + :tASET => 81, + :tLSHFT => 82, + :tRSHFT => 83, + :tCOLON2 => 84, + :tCOLON3 => 85, + :tOP_ASGN => 86, + :tASSOC => 87, + :tLPAREN => 88, + :tLPAREN2 => 89, + :tRPAREN => 90, + :tLPAREN_ARG => 91, + :tLBRACK => 92, + :tLBRACK2 => 93, + :tRBRACK => 94, + :tLBRACE => 95, + :tLBRACE_ARG => 96, + :tSTAR => 97, + :tSTAR2 => 98, + :tAMPER => 99, + :tAMPER2 => 100, + :tTILDE => 101, + :tPERCENT => 102, + :tDIVIDE => 103, + :tDSTAR => 104, + :tPLUS => 105, + :tMINUS => 106, + :tLT => 107, + :tGT => 108, + :tPIPE => 109, + :tBANG => 110, + :tCARET => 111, + :tLCURLY => 112, + :tRCURLY => 113, + :tBACK_REF2 => 114, + :tSYMBEG => 115, + :tSTRING_BEG => 116, + :tXSTRING_BEG => 117, + :tREGEXP_BEG => 118, + :tREGEXP_OPT => 119, + :tWORDS_BEG => 120, + :tQWORDS_BEG => 121, + :tSYMBOLS_BEG => 122, + :tQSYMBOLS_BEG => 123, + :tSTRING_DBEG => 124, + :tSTRING_DVAR => 125, + :tSTRING_END => 126, + :tSTRING_DEND => 127, + :tSTRING => 128, + :tSYMBOL => 129, + :tNL => 130, + :tEH => 131, + :tCOLON => 132, + :tCOMMA => 133, + :tSPACE => 134, + :tSEMI => 135, + :tLAMBDA => 136, + :tLAMBEG => 137, + :tCHARACTER => 138, + :tRATIONAL => 139, + :tIMAGINARY => 140, + :tLABEL_END => 141, + :tANDDOT => 142, + :tEQL => 143, + :tLOWEST => 144 } + +racc_nt_base = 145 + +racc_use_result_var = true + +Racc_arg = [ + racc_action_table, + racc_action_check, + racc_action_default, + racc_action_pointer, + racc_goto_table, + racc_goto_check, + racc_goto_default, + racc_goto_pointer, + racc_nt_base, + racc_reduce_table, + racc_token_table, + racc_shift_n, + racc_reduce_n, + racc_use_result_var ] +Ractor.make_shareable(Racc_arg) if defined?(Ractor) + +Racc_token_to_s_table = [ + "$end", + "error", + "kCLASS", + "kMODULE", + "kDEF", + "kUNDEF", + "kBEGIN", + "kRESCUE", + "kENSURE", + "kEND", + "kIF", + "kUNLESS", + "kTHEN", + "kELSIF", + "kELSE", + "kCASE", + "kWHEN", + "kWHILE", + "kUNTIL", + "kFOR", + "kBREAK", + "kNEXT", + "kREDO", + "kRETRY", + "kIN", + "kDO", + "kDO_COND", + "kDO_BLOCK", + "kDO_LAMBDA", + "kRETURN", + "kYIELD", + "kSUPER", + "kSELF", + "kNIL", + "kTRUE", + "kFALSE", + "kAND", + "kOR", + "kNOT", + "kIF_MOD", + "kUNLESS_MOD", + "kWHILE_MOD", + "kUNTIL_MOD", + "kRESCUE_MOD", + "kALIAS", + "kDEFINED", + "klBEGIN", + "klEND", + "k__LINE__", + "k__FILE__", + "k__ENCODING__", + "tIDENTIFIER", + "tFID", + "tGVAR", + "tIVAR", + "tCONSTANT", + "tLABEL", + "tCVAR", + "tNTH_REF", + "tBACK_REF", + "tSTRING_CONTENT", + "tINTEGER", + "tFLOAT", + "tUPLUS", + "tUMINUS", + "tUNARY_NUM", + "tPOW", + "tCMP", + "tEQ", + "tEQQ", + "tNEQ", + "tGEQ", + "tLEQ", + "tANDOP", + "tOROP", + "tMATCH", + "tNMATCH", + "tDOT", + "tDOT2", + "tDOT3", + "tAREF", + "tASET", + "tLSHFT", + "tRSHFT", + "tCOLON2", + "tCOLON3", + "tOP_ASGN", + "tASSOC", + "tLPAREN", + "tLPAREN2", + "tRPAREN", + "tLPAREN_ARG", + "tLBRACK", + "tLBRACK2", + "tRBRACK", + "tLBRACE", + "tLBRACE_ARG", + "tSTAR", + "tSTAR2", + "tAMPER", + "tAMPER2", + "tTILDE", + "tPERCENT", + "tDIVIDE", + "tDSTAR", + "tPLUS", + "tMINUS", + "tLT", + "tGT", + "tPIPE", + "tBANG", + "tCARET", + "tLCURLY", + "tRCURLY", + "tBACK_REF2", + "tSYMBEG", + "tSTRING_BEG", + "tXSTRING_BEG", + "tREGEXP_BEG", + "tREGEXP_OPT", + "tWORDS_BEG", + "tQWORDS_BEG", + "tSYMBOLS_BEG", + "tQSYMBOLS_BEG", + "tSTRING_DBEG", + "tSTRING_DVAR", + "tSTRING_END", + "tSTRING_DEND", + "tSTRING", + "tSYMBOL", + "tNL", + "tEH", + "tCOLON", + "tCOMMA", + "tSPACE", + "tSEMI", + "tLAMBDA", + "tLAMBEG", + "tCHARACTER", + "tRATIONAL", + "tIMAGINARY", + "tLABEL_END", + "tANDDOT", + "tEQL", + "tLOWEST", + "$start", + "program", + "top_compstmt", + "top_stmts", + "opt_terms", + "top_stmt", + "terms", + "stmt", + "begin_block", + "bodystmt", + "compstmt", + "opt_rescue", + "opt_else", + "opt_ensure", + "stmts", + "stmt_or_begin", + "fitem", + "undef_list", + "expr_value", + "command_asgn", + "mlhs", + "command_call", + "lhs", + "mrhs", + "mrhs_arg", + "expr", + "@1", + "command_rhs", + "var_lhs", + "primary_value", + "opt_call_args", + "rbracket", + "call_op", + "backref", + "opt_nl", + "arg", + "expr_value_do", + "do", + "@2", + "command", + "block_command", + "block_call", + "dot_or_colon", + "operation2", + "command_args", + "cmd_brace_block", + "brace_body", + "fcall", + "@3", + "operation", + "k_return", + "call_args", + "mlhs_basic", + "mlhs_inner", + "rparen", + "mlhs_head", + "mlhs_item", + "mlhs_node", + "mlhs_post", + "user_variable", + "keyword_variable", + "cname", + "cpath", + "fname", + "op", + "reswords", + "fsym", + "symbol", + "dsym", + "@4", + "arg_rhs", + "simple_numeric", + "rel_expr", + "primary", + "relop", + "arg_value", + "aref_args", + "none", + "args", + "trailer", + "assocs", + "paren_args", + "opt_paren_args", + "opt_block_arg", + "block_arg", + "@5", + "literal", + "strings", + "xstring", + "regexp", + "words", + "qwords", + "symbols", + "qsymbols", + "var_ref", + "assoc_list", + "brace_block", + "method_call", + "lambda", + "then", + "if_tail", + "case_body", + "for_var", + "k_class", + "superclass", + "term", + "k_module", + "k_def", + "f_arglist", + "singleton", + "@6", + "@7", + "@8", + "@9", + "@10", + "@11", + "@12", + "@13", + "@14", + "@15", + "f_marg", + "f_norm_arg", + "f_margs", + "f_marg_list", + "block_args_tail", + "f_block_kwarg", + "f_kwrest", + "opt_f_block_arg", + "f_block_arg", + "opt_block_args_tail", + "block_param", + "f_arg", + "f_block_optarg", + "f_rest_arg", + "opt_block_param", + "block_param_def", + "opt_bv_decl", + "bv_decls", + "bvar", + "f_bad_arg", + "f_larglist", + "lambda_body", + "@16", + "@17", + "f_args", + "do_block", + "@18", + "@19", + "do_body", + "@20", + "operation3", + "@21", + "@22", + "@23", + "@24", + "@25", + "cases", + "exc_list", + "exc_var", + "numeric", + "string", + "string1", + "string_contents", + "xstring_contents", + "regexp_contents", + "word_list", + "word", + "string_content", + "symbol_list", + "qword_list", + "qsym_list", + "string_dvar", + "@26", + "@27", + "args_tail", + "@28", + "f_kwarg", + "opt_args_tail", + "f_optarg", + "f_arg_asgn", + "f_arg_item", + "f_label", + "f_kw", + "f_block_kw", + "kwrest_mark", + "f_opt", + "f_block_opt", + "restarg_mark", + "blkarg_mark", + "assoc" ] +Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) + +Racc_debug_parser = false + +##### State transition tables end ##### + +# reduce 0 omitted + +# reduce 1 omitted + +def _reduce_2(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_3(val, _values, result) + result = [] + + result +end + +def _reduce_4(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_5(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_6(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 7 omitted + +def _reduce_8(val, _values, result) + result = @builder.preexe(val[0], *val[1]) + + result +end + +def _reduce_9(val, _values, result) + result = val + + result +end + +def _reduce_10(val, _values, result) + rescue_bodies = val[1] + else_t, else_ = val[2] + ensure_t, ensure_ = val[3] + + if rescue_bodies.empty? && !else_t.nil? + diagnostic :error, :useless_else, nil, else_t + end + + result = @builder.begin_body(val[0], + rescue_bodies, + else_t, else_, + ensure_t, ensure_) + + result +end + +def _reduce_11(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_12(val, _values, result) + result = [] + + result +end + +def _reduce_13(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_14(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_15(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 16 omitted + +def _reduce_17(val, _values, result) + diagnostic :error, :begin_in_method, nil, val[0] + + result +end + +def _reduce_18(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_19(val, _values, result) + result = @builder.alias(val[0], val[1], val[3]) + + result +end + +def _reduce_20(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.gvar(val[2])) + + result +end + +def _reduce_21(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.back_ref(val[2])) + + result +end + +def _reduce_22(val, _values, result) + diagnostic :error, :nth_ref_alias, nil, val[2] + + result +end + +def _reduce_23(val, _values, result) + result = @builder.undef_method(val[0], val[1]) + + result +end + +def _reduce_24(val, _values, result) + result = @builder.condition_mod(val[0], nil, + val[1], val[2]) + + result +end + +def _reduce_25(val, _values, result) + result = @builder.condition_mod(nil, val[0], + val[1], val[2]) + + result +end + +def _reduce_26(val, _values, result) + result = @builder.loop_mod(:while, val[0], val[1], val[2]) + + result +end + +def _reduce_27(val, _values, result) + result = @builder.loop_mod(:until, val[0], val[1], val[2]) + + result +end + +def _reduce_28(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_29(val, _values, result) + result = @builder.postexe(val[0], val[1], val[2], val[3]) + + result +end + +# reduce 30 omitted + +def _reduce_31(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_32(val, _values, result) + result = @builder.assign(val[0], val[1], + @builder.array(nil, val[2], nil)) + + result +end + +def _reduce_33(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +# reduce 34 omitted + +def _reduce_35(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_36(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_37(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_38(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_39(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_40(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_41(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_42(val, _values, result) + @builder.op_assign(val[0], val[1], val[2]) + + result +end + +# reduce 43 omitted + +def _reduce_44(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +# reduce 45 omitted + +# reduce 46 omitted + +def _reduce_47(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_48(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_49(val, _values, result) + result = @builder.not_op(val[0], nil, val[2], nil) + + result +end + +def _reduce_50(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +# reduce 51 omitted + +# reduce 52 omitted + +def _reduce_53(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_54(val, _values, result) + @lexer.cond.pop + result = [ val[1], val[2] ] + + result +end + +# reduce 55 omitted + +# reduce 56 omitted + +# reduce 57 omitted + +def _reduce_58(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_59(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_60(val, _values, result) + result = [ val[0], *val[2], val[3] ] + @context.in_block = val[1].in_block + + result +end + +# reduce 61 omitted + +def _reduce_62(val, _values, result) + result = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + result +end + +def _reduce_63(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + begin_t, args, body, end_t = val[2] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_64(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_65(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_66(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_67(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_68(val, _values, result) + result = @builder.keyword_cmd(:super, val[0], + nil, val[1], nil) + + result +end + +def _reduce_69(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], + nil, val[1], nil) + + result +end + +def _reduce_70(val, _values, result) + result = @builder.keyword_cmd(:return, val[0], + nil, val[1], nil) + + result +end + +def _reduce_71(val, _values, result) + result = @builder.keyword_cmd(:break, val[0], + nil, val[1], nil) + + result +end + +def _reduce_72(val, _values, result) + result = @builder.keyword_cmd(:next, val[0], + nil, val[1], nil) + + result +end + +def _reduce_73(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_74(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_75(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_76(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +# reduce 77 omitted + +def _reduce_78(val, _values, result) + result = val[0]. + push(val[1]) + + result +end + +def _reduce_79(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])) + + result +end + +def _reduce_80(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])). + concat(val[4]) + + result +end + +def _reduce_81(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])) + + result +end + +def _reduce_82(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])). + concat(val[3]) + + result +end + +def _reduce_83(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_84(val, _values, result) + result = [ @builder.splat(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_85(val, _values, result) + result = [ @builder.splat(val[0]) ] + + result +end + +def _reduce_86(val, _values, result) + result = [ @builder.splat(val[0]), + *val[2] ] + + result +end + +# reduce 87 omitted + +def _reduce_88(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_89(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_90(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_91(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_92(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_93(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_94(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_95(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_96(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_97(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_98(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_99(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_100(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_101(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_102(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_103(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_104(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_105(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_106(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_107(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_108(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_109(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_110(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_111(val, _values, result) + diagnostic :error, :module_name_const, nil, val[0] + + result +end + +# reduce 112 omitted + +def _reduce_113(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_114(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_115(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +# reduce 116 omitted + +# reduce 117 omitted + +# reduce 118 omitted + +# reduce 119 omitted + +# reduce 120 omitted + +def _reduce_121(val, _values, result) + result = @builder.symbol_internal(val[0]) + + result +end + +# reduce 122 omitted + +# reduce 123 omitted + +# reduce 124 omitted + +def _reduce_125(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_126(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_127(val, _values, result) + result = val[0] << val[3] + + result +end + +# reduce 128 omitted + +# reduce 129 omitted + +# reduce 130 omitted + +# reduce 131 omitted + +# reduce 132 omitted + +# reduce 133 omitted + +# reduce 134 omitted + +# reduce 135 omitted + +# reduce 136 omitted + +# reduce 137 omitted + +# reduce 138 omitted + +# reduce 139 omitted + +# reduce 140 omitted + +# reduce 141 omitted + +# reduce 142 omitted + +# reduce 143 omitted + +# reduce 144 omitted + +# reduce 145 omitted + +# reduce 146 omitted + +# reduce 147 omitted + +# reduce 148 omitted + +# reduce 149 omitted + +# reduce 150 omitted + +# reduce 151 omitted + +# reduce 152 omitted + +# reduce 153 omitted + +# reduce 154 omitted + +# reduce 155 omitted + +# reduce 156 omitted + +# reduce 157 omitted + +# reduce 158 omitted + +# reduce 159 omitted + +# reduce 160 omitted + +# reduce 161 omitted + +# reduce 162 omitted + +# reduce 163 omitted + +# reduce 164 omitted + +# reduce 165 omitted + +# reduce 166 omitted + +# reduce 167 omitted + +# reduce 168 omitted + +# reduce 169 omitted + +# reduce 170 omitted + +# reduce 171 omitted + +# reduce 172 omitted + +# reduce 173 omitted + +# reduce 174 omitted + +# reduce 175 omitted + +# reduce 176 omitted + +# reduce 177 omitted + +# reduce 178 omitted + +# reduce 179 omitted + +# reduce 180 omitted + +# reduce 181 omitted + +# reduce 182 omitted + +# reduce 183 omitted + +# reduce 184 omitted + +# reduce 185 omitted + +# reduce 186 omitted + +# reduce 187 omitted + +# reduce 188 omitted + +# reduce 189 omitted + +# reduce 190 omitted + +# reduce 191 omitted + +# reduce 192 omitted + +# reduce 193 omitted + +# reduce 194 omitted + +# reduce 195 omitted + +# reduce 196 omitted + +# reduce 197 omitted + +# reduce 198 omitted + +def _reduce_199(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_200(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_201(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_202(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_203(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_204(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_205(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_206(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_global(val[0], val[1])) + result = @builder.op_assign(const, val[2], val[3]) + + result +end + +def _reduce_207(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_208(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_209(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_210(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], nil) + + result +end + +def _reduce_211(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], nil) + + result +end + +def _reduce_212(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_213(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_214(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_215(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_216(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_217(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_218(val, _values, result) + result = @builder.unary_op(val[0], + @builder.binary_op( + val[1], val[2], val[3])) + + result +end + +def _reduce_219(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_220(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_221(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_222(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_223(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_224(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +# reduce 225 omitted + +def _reduce_226(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_227(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_228(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_229(val, _values, result) + result = @builder.match_op(val[0], val[1], val[2]) + + result +end + +def _reduce_230(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_231(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +def _reduce_232(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_233(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_234(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_235(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_236(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_237(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil) + + result +end + +def _reduce_238(val, _values, result) + result = @builder.ternary(val[0], val[1], + val[2], val[4], val[5]) + + result +end + +# reduce 239 omitted + +# reduce 240 omitted + +# reduce 241 omitted + +# reduce 242 omitted + +# reduce 243 omitted + +def _reduce_244(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_245(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +# reduce 246 omitted + +# reduce 247 omitted + +# reduce 248 omitted + +def _reduce_249(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_250(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +# reduce 251 omitted + +def _reduce_252(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_253(val, _values, result) + result = val + + result +end + +def _reduce_254(val, _values, result) + result = [ nil, [], nil ] + + result +end + +# reduce 255 omitted + +def _reduce_256(val, _values, result) + result = [] + + result +end + +# reduce 257 omitted + +# reduce 258 omitted + +def _reduce_259(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_260(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +def _reduce_261(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_262(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_263(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + result.concat(val[1]) + + result +end + +def _reduce_264(val, _values, result) + assocs = @builder.associate(nil, val[2], nil) + result = val[0] << assocs + result.concat(val[3]) + + result +end + +def _reduce_265(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_266(val, _values, result) + # When branch gets invoked by RACC's lookahead + # and command args start with '[' or '(' + # we need to put `true` to the cmdarg stack + # **before** `false` pushed by lexer + # m [], n + # ^ + # Right here we have cmdarg [...0] because + # lexer pushed it on '[' + # We need to modify cmdarg stack to [...10] + # + # For all other cases (like `m n` or `m n, []`) we simply put 1 to the stack + # and later lexer pushes corresponding bits on top of it. + last_token = @last_token[0] + lookahead = last_token == :tLBRACK || last_token == :tLPAREN_ARG + + if lookahead + top = @lexer.cmdarg.pop + @lexer.cmdarg.push(true) + @lexer.cmdarg.push(top) + else + @lexer.cmdarg.push(true) + end + + result +end + +def _reduce_267(val, _values, result) + # call_args can be followed by tLBRACE_ARG (that does cmdarg.push(0) in the lexer) + # but the push must be done after cmdarg.pop() in the parser. + # So this code does cmdarg.pop() to pop 0 pushed by tLBRACE_ARG, + # cmdarg.pop() to pop 1 pushed by command_args, + # and cmdarg.push(0) to restore back the flag set by tLBRACE_ARG. + last_token = @last_token[0] + lookahead = last_token == :tLBRACE_ARG + if lookahead + top = @lexer.cmdarg.pop + @lexer.cmdarg.pop + @lexer.cmdarg.push(top) + else + @lexer.cmdarg.pop + end + + result = val[1] + + result +end + +def _reduce_268(val, _values, result) + result = @builder.block_pass(val[0], val[1]) + + result +end + +def _reduce_269(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_270(val, _values, result) + result = [] + + result +end + +def _reduce_271(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_272(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_273(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_274(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_275(val, _values, result) + result = @builder.array(nil, val[0], nil) + + result +end + +# reduce 276 omitted + +def _reduce_277(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_278(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_279(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +# reduce 280 omitted + +# reduce 281 omitted + +# reduce 282 omitted + +# reduce 283 omitted + +# reduce 284 omitted + +# reduce 285 omitted + +# reduce 286 omitted + +# reduce 287 omitted + +# reduce 288 omitted + +# reduce 289 omitted + +def _reduce_290(val, _values, result) + result = @builder.call_method(nil, nil, val[0]) + + result +end + +def _reduce_291(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_292(val, _values, result) + @lexer.cmdarg.pop + + result = @builder.begin_keyword(val[0], val[2], val[3]) + + result +end + +def _reduce_293(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_294(val, _values, result) + result = @builder.begin(val[0], val[1], val[3]) + + result +end + +def _reduce_295(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_296(val, _values, result) + result = @builder.begin(val[0], nil, val[3]) + + result +end + +def _reduce_297(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_298(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +def _reduce_299(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_300(val, _values, result) + result = @builder.array(val[0], val[1], val[2]) + + result +end + +def _reduce_301(val, _values, result) + result = @builder.associate(val[0], val[1], val[2]) + + result +end + +def _reduce_302(val, _values, result) + result = @builder.keyword_cmd(:return, val[0]) + + result +end + +def _reduce_303(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_304(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2]) + + result +end + +def _reduce_305(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0]) + + result +end + +def _reduce_306(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], + val[2], [ val[3] ], val[4]) + + result +end + +def _reduce_307(val, _values, result) + result = @builder.not_op(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_308(val, _values, result) + result = @builder.not_op(val[0], val[1], nil, val[2]) + + result +end + +def _reduce_309(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0]) + + begin_t, args, body, end_t = val[1] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +# reduce 310 omitted + +def _reduce_311(val, _values, result) + begin_t, args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, args, body, end_t) + + result +end + +def _reduce_312(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_313(val, _values, result) + lambda_call = @builder.call_lambda(val[0]) + + args, (begin_t, body, end_t) = val[2] + result = @builder.block(lambda_call, + begin_t, args, body, end_t) + + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_314(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, val[5]) + + result +end + +def _reduce_315(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + else_, else_t, + val[3], val[5]) + + result +end + +def _reduce_316(val, _values, result) + result = @builder.loop(:while, val[0], *val[1], val[2], val[3]) + + result +end + +def _reduce_317(val, _values, result) + result = @builder.loop(:until, val[0], *val[1], val[2], val[3]) + + result +end + +def _reduce_318(val, _values, result) + *when_bodies, (else_t, else_body) = *val[3] + + result = @builder.case(val[0], val[1], + when_bodies, else_t, else_body, + val[4]) + + result +end + +def _reduce_319(val, _values, result) + *when_bodies, (else_t, else_body) = *val[2] + + result = @builder.case(val[0], nil, + when_bodies, else_t, else_body, + val[3]) + + result +end + +def _reduce_320(val, _values, result) + result = @builder.for(val[0], val[1], val[2], *val[3], val[4], val[5]) + + result +end + +def _reduce_321(val, _values, result) + local_push + @context.in_class = true + + result +end + +def _reduce_322(val, _values, result) + k_class, ctx = val[0] + if @context.in_def + diagnostic :error, :class_in_def, nil, k_class + end + + lt_t, superclass = val[2] + result = @builder.def_class(k_class, val[1], + lt_t, superclass, + val[4], val[5]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_323(val, _values, result) + @context.in_def = false + @context.in_class = false + local_push + + result +end + +def _reduce_324(val, _values, result) + k_class, ctx = val[0] + result = @builder.def_sclass(k_class, val[1], val[2], + val[5], val[6]) + + local_pop + @context.in_def = ctx.in_def + @context.in_class = ctx.in_class + + result +end + +def _reduce_325(val, _values, result) + @context.in_class = true + local_push + + result +end + +def _reduce_326(val, _values, result) + k_mod, ctx = val[0] + if @context.in_def + diagnostic :error, :module_in_def, nil, k_mod + end + + result = @builder.def_module(k_mod, val[1], + val[3], val[4]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_327(val, _values, result) + local_push + result = context.dup + @context.in_def = true + + result +end + +def _reduce_328(val, _values, result) + result = @builder.def_method(val[0], val[1], + val[3], val[4], val[5]) + + local_pop + @context.in_def = val[2].in_def + + result +end + +def _reduce_329(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_330(val, _values, result) + local_push + result = context.dup + @context.in_def = true + + result +end + +def _reduce_331(val, _values, result) + result = @builder.def_singleton(val[0], val[1], val[2], + val[4], val[6], val[7], val[8]) + + local_pop + @context.in_def = val[5].in_def + + result +end + +def _reduce_332(val, _values, result) + result = @builder.keyword_cmd(:break, val[0]) + + result +end + +def _reduce_333(val, _values, result) + result = @builder.keyword_cmd(:next, val[0]) + + result +end + +def _reduce_334(val, _values, result) + result = @builder.keyword_cmd(:redo, val[0]) + + result +end + +def _reduce_335(val, _values, result) + result = @builder.keyword_cmd(:retry, val[0]) + + result +end + +# reduce 336 omitted + +def _reduce_337(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_338(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_339(val, _values, result) + result = val[0] + + result +end + +def _reduce_340(val, _values, result) + if @context.in_class && !@context.in_def && !(context.in_block || context.in_lambda) + diagnostic :error, :invalid_return, nil, val[0] + end + + result +end + +# reduce 341 omitted + +# reduce 342 omitted + +def _reduce_343(val, _values, result) + result = val[1] + + result +end + +# reduce 344 omitted + +# reduce 345 omitted + +# reduce 346 omitted + +def _reduce_347(val, _values, result) + else_t, else_ = val[4] + result = [ val[0], + @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, nil), + ] + + result +end + +# reduce 348 omitted + +def _reduce_349(val, _values, result) + result = val + + result +end + +# reduce 350 omitted + +# reduce 351 omitted + +def _reduce_352(val, _values, result) + result = @builder.arg(val[0]) + + result +end + +def _reduce_353(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_354(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_355(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 356 omitted + +def _reduce_357(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2], val[3])) + + result +end + +def _reduce_358(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2], val[3])). + concat(val[5]) + + result +end + +def _reduce_359(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2])) + + result +end + +def _reduce_360(val, _values, result) + result = val[0]. + push(@builder.restarg(val[2])). + concat(val[4]) + + result +end + +def _reduce_361(val, _values, result) + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_362(val, _values, result) + result = [ @builder.restarg(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_363(val, _values, result) + result = [ @builder.restarg(val[0]) ] + + result +end + +def _reduce_364(val, _values, result) + result = [ @builder.restarg(val[0]), + *val[2] ] + + result +end + +def _reduce_365(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_366(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_367(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_368(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_369(val, _values, result) + result = val[1] + + result +end + +def _reduce_370(val, _values, result) + result = [] + + result +end + +def _reduce_371(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_372(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_373(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_374(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_375(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 376 omitted + +def _reduce_377(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_378(val, _values, result) + if val[1].empty? && val[0].size == 1 + result = [@builder.procarg0(val[0][0])] + else + result = val[0].concat(val[1]) + end + + result +end + +def _reduce_379(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_380(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_381(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_382(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_383(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_384(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 385 omitted + +def _reduce_386(val, _values, result) + result = @builder.args(nil, [], nil) + + result +end + +def _reduce_387(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_388(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + result +end + +def _reduce_389(val, _values, result) + result = @builder.args(val[0], [], val[0]) + + result +end + +def _reduce_390(val, _values, result) + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_391(val, _values, result) + result = [] + + result +end + +def _reduce_392(val, _values, result) + result = val[2] + + result +end + +def _reduce_393(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_394(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_395(val, _values, result) + @static_env.declare val[0][0] + result = @builder.shadowarg(val[0]) + + result +end + +# reduce 396 omitted + +def _reduce_397(val, _values, result) + @static_env.extend_dynamic + + result +end + +def _reduce_398(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_399(val, _values, result) + @lexer.cmdarg.pop + + result = [ val[1], val[3] ] + + @static_env.unextend + + result +end + +def _reduce_400(val, _values, result) + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_401(val, _values, result) + result = @builder.args(nil, val[0], nil) + + result +end + +def _reduce_402(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_403(val, _values, result) + result = [ val[0], val[2], val[3] ] + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_404(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_405(val, _values, result) + result = [ val[0], val[2], val[3] ] + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_406(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_407(val, _values, result) + result = [ val[0], *val[2], val[3] ] + @context.in_block = val[1].in_block + + result +end + +def _reduce_408(val, _values, result) + begin_t, block_args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, block_args, body, end_t) + + result +end + +def _reduce_409(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_410(val, _values, result) + lparen_t, args, rparen_t = val[3] + method_call = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_411(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_412(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.call_method(nil, nil, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_413(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_414(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_415(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2]) + + result +end + +def _reduce_416(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_417(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_418(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.keyword_cmd(:super, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_419(val, _values, result) + result = @builder.keyword_cmd(:zsuper, val[0]) + + result +end + +def _reduce_420(val, _values, result) + result = @builder.index(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_421(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_422(val, _values, result) + result = [ val[0], *val[2], val[3] ] + @context.in_block = val[1].in_block + + result +end + +def _reduce_423(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_424(val, _values, result) + result = [ val[0], *val[2], val[3] ] + @context.in_block = val[1].in_block + + result +end + +def _reduce_425(val, _values, result) + @static_env.extend_dynamic + + result +end + +def _reduce_426(val, _values, result) + result = [ val[1], val[2] ] + + @static_env.unextend + + result +end + +def _reduce_427(val, _values, result) + @static_env.extend_dynamic + + result +end + +def _reduce_428(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_429(val, _values, result) + result = [ val[2], val[3] ] + + @static_env.unextend + @lexer.cmdarg.pop + + result +end + +def _reduce_430(val, _values, result) + result = [ @builder.when(val[0], val[1], val[2], val[3]), + *val[4] ] + + result +end + +def _reduce_431(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 432 omitted + +def _reduce_433(val, _values, result) + assoc_t, exc_var = val[2] + + if val[1] + exc_list = @builder.array(nil, val[1], nil) + end + + result = [ @builder.rescue_body(val[0], + exc_list, assoc_t, exc_var, + val[3], val[4]), + *val[5] ] + + result +end + +def _reduce_434(val, _values, result) + result = [] + + result +end + +def _reduce_435(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 436 omitted + +# reduce 437 omitted + +def _reduce_438(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 439 omitted + +def _reduce_440(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 441 omitted + +# reduce 442 omitted + +# reduce 443 omitted + +# reduce 444 omitted + +def _reduce_445(val, _values, result) + result = @builder.string_compose(nil, val[0], nil) + + result +end + +def _reduce_446(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_447(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_448(val, _values, result) + string = @builder.string_compose(val[0], val[1], val[2]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_449(val, _values, result) + string = @builder.string(val[0]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_450(val, _values, result) + result = @builder.character(val[0]) + + result +end + +def _reduce_451(val, _values, result) + string = @builder.xstring_compose(val[0], val[1], val[2]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_452(val, _values, result) + opts = @builder.regexp_options(val[3]) + result = @builder.regexp_compose(val[0], val[1], val[2], opts) + + result +end + +def _reduce_453(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_454(val, _values, result) + result = [] + + result +end + +def _reduce_455(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_456(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_457(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_458(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_459(val, _values, result) + result = [] + + result +end + +def _reduce_460(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_461(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_462(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_463(val, _values, result) + result = [] + + result +end + +def _reduce_464(val, _values, result) + result = val[0] << @builder.string_internal(val[1]) + + result +end + +def _reduce_465(val, _values, result) + result = [] + + result +end + +def _reduce_466(val, _values, result) + result = val[0] << @builder.symbol_internal(val[1]) + + result +end + +def _reduce_467(val, _values, result) + result = [] + + result +end + +def _reduce_468(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_469(val, _values, result) + result = [] + + result +end + +def _reduce_470(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_471(val, _values, result) + result = [] + + result +end + +def _reduce_472(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_473(val, _values, result) + result = @builder.string_internal(val[0]) + + result +end + +def _reduce_474(val, _values, result) + result = val[1] + + result +end + +def _reduce_475(val, _values, result) + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + + result +end + +def _reduce_476(val, _values, result) + @lexer.cmdarg.pop + @lexer.cond.pop + + result = @builder.begin(val[0], val[2], val[3]) + + result +end + +def _reduce_477(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_478(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_479(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +# reduce 480 omitted + +def _reduce_481(val, _values, result) + @lexer.state = :expr_end + result = @builder.symbol(val[0]) + + result +end + +def _reduce_482(val, _values, result) + @lexer.state = :expr_end + result = @builder.symbol_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_483(val, _values, result) + result = val[0] + + result +end + +def _reduce_484(val, _values, result) + if @builder.respond_to? :negate + # AST builder interface compatibility + result = @builder.negate(val[0], val[1]) + else + result = @builder.unary_num(val[0], val[1]) + end + + result +end + +def _reduce_485(val, _values, result) + @lexer.state = :expr_end + result = @builder.integer(val[0]) + + result +end + +def _reduce_486(val, _values, result) + @lexer.state = :expr_end + result = @builder.float(val[0]) + + result +end + +def _reduce_487(val, _values, result) + @lexer.state = :expr_end + result = @builder.rational(val[0]) + + result +end + +def _reduce_488(val, _values, result) + @lexer.state = :expr_end + result = @builder.complex(val[0]) + + result +end + +def _reduce_489(val, _values, result) + result = @builder.ident(val[0]) + + result +end + +def _reduce_490(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_491(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_492(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_493(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +def _reduce_494(val, _values, result) + result = @builder.nil(val[0]) + + result +end + +def _reduce_495(val, _values, result) + result = @builder.self(val[0]) + + result +end + +def _reduce_496(val, _values, result) + result = @builder.true(val[0]) + + result +end + +def _reduce_497(val, _values, result) + result = @builder.false(val[0]) + + result +end + +def _reduce_498(val, _values, result) + result = @builder.__FILE__(val[0]) + + result +end + +def _reduce_499(val, _values, result) + result = @builder.__LINE__(val[0]) + + result +end + +def _reduce_500(val, _values, result) + result = @builder.__ENCODING__(val[0]) + + result +end + +def _reduce_501(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_502(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_503(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_504(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_505(val, _values, result) + result = @builder.nth_ref(val[0]) + + result +end + +def _reduce_506(val, _values, result) + result = @builder.back_ref(val[0]) + + result +end + +def _reduce_507(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_508(val, _values, result) + result = [ val[0], val[2] ] + + result +end + +def _reduce_509(val, _values, result) + result = nil + + result +end + +def _reduce_510(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + @lexer.state = :expr_value + + result +end + +def _reduce_511(val, _values, result) + result = @context.in_kwarg + @context.in_kwarg = true + + result +end + +def _reduce_512(val, _values, result) + @context.in_kwarg = val[0] + result = @builder.args(nil, val[1], nil) + + result +end + +def _reduce_513(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_514(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_515(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_516(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_517(val, _values, result) + result = val[1] + + result +end + +def _reduce_518(val, _values, result) + result = [] + + result +end + +def _reduce_519(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_520(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_521(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_522(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_523(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_524(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_525(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_526(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_527(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_528(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_529(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_530(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_531(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_532(val, _values, result) + result = val[0] + + result +end + +def _reduce_533(val, _values, result) + result = [] + + result +end + +def _reduce_534(val, _values, result) + diagnostic :error, :argument_const, nil, val[0] + + result +end + +def _reduce_535(val, _values, result) + diagnostic :error, :argument_ivar, nil, val[0] + + result +end + +def _reduce_536(val, _values, result) + diagnostic :error, :argument_gvar, nil, val[0] + + result +end + +def _reduce_537(val, _values, result) + diagnostic :error, :argument_cvar, nil, val[0] + + result +end + +# reduce 538 omitted + +def _reduce_539(val, _values, result) + @static_env.declare val[0][0] + + result = val[0] + + result +end + +def _reduce_540(val, _values, result) + result = val[0] + + result +end + +def _reduce_541(val, _values, result) + result = @builder.arg(val[0]) + + result +end + +def _reduce_542(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_543(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_544(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_545(val, _values, result) + check_kwarg_name(val[0]) + + @static_env.declare val[0][0] + + result = val[0] + + result +end + +def _reduce_546(val, _values, result) + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_547(val, _values, result) + result = @builder.kwarg(val[0]) + + result +end + +def _reduce_548(val, _values, result) + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_549(val, _values, result) + result = @builder.kwarg(val[0]) + + result +end + +def _reduce_550(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_551(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_552(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_553(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 554 omitted + +# reduce 555 omitted + +def _reduce_556(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.kwrestarg(val[0], val[1]) ] + + result +end + +def _reduce_557(val, _values, result) + result = [ @builder.kwrestarg(val[0]) ] + + result +end + +def _reduce_558(val, _values, result) + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_559(val, _values, result) + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_560(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_561(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_562(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_563(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 564 omitted + +# reduce 565 omitted + +def _reduce_566(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_567(val, _values, result) + result = [ @builder.restarg(val[0]) ] + + result +end + +# reduce 568 omitted + +# reduce 569 omitted + +def _reduce_570(val, _values, result) + @static_env.declare val[1][0] + + result = @builder.blockarg(val[0], val[1]) + + result +end + +def _reduce_571(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_572(val, _values, result) + result = [] + + result +end + +# reduce 573 omitted + +def _reduce_574(val, _values, result) + result = val[1] + + result +end + +def _reduce_575(val, _values, result) + result = [] + + result +end + +# reduce 576 omitted + +def _reduce_577(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_578(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_579(val, _values, result) + result = @builder.pair(val[0], val[1], val[2]) + + result +end + +def _reduce_580(val, _values, result) + result = @builder.pair_keyword(val[0], val[1]) + + result +end + +def _reduce_581(val, _values, result) + result = @builder.pair_quoted(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_582(val, _values, result) + result = @builder.kwsplat(val[0], val[1]) + + result +end + +# reduce 583 omitted + +# reduce 584 omitted + +# reduce 585 omitted + +# reduce 586 omitted + +# reduce 587 omitted + +# reduce 588 omitted + +# reduce 589 omitted + +# reduce 590 omitted + +# reduce 591 omitted + +# reduce 592 omitted + +# reduce 593 omitted + +# reduce 594 omitted + +def _reduce_595(val, _values, result) + result = [:dot, val[0][1]] + + result +end + +def _reduce_596(val, _values, result) + result = [:anddot, val[0][1]] + + result +end + +# reduce 597 omitted + +# reduce 598 omitted + +# reduce 599 omitted + +# reduce 600 omitted + +def _reduce_601(val, _values, result) + result = val[1] + + result +end + +def _reduce_602(val, _values, result) + result = val[1] + + result +end + +# reduce 603 omitted + +# reduce 604 omitted + +# reduce 605 omitted + +def _reduce_606(val, _values, result) + yyerrok + + result +end + +# reduce 607 omitted + +# reduce 608 omitted + +# reduce 609 omitted + +def _reduce_610(val, _values, result) + result = nil + + result +end + +def _reduce_none(val, _values, result) + val[0] +end + + end # class Ruby26 +end # module Parser diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby27.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby27.rb new file mode 100644 index 00000000..4ebe8d7a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby27.rb @@ -0,0 +1,11948 @@ +# -*- encoding:utf-8; warn-indent:false; frozen_string_literal: true -*- +# +# DO NOT MODIFY!!!! +# This file is automatically generated by Racc 1.8.1 +# from Racc grammar file "ruby27.y". +# + +require 'racc/parser.rb' + + +require_relative '../parser' + +module Parser + class Ruby27 < Parser::Base + + + def version + 27 + end + + def default_encoding + Encoding::UTF_8 + end + + def local_push + @static_env.extend_static + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + @max_numparam_stack.push(static: true) + end + + def local_pop + @static_env.unextend + @lexer.cmdarg.pop + @lexer.cond.pop + @max_numparam_stack.pop + end + + def try_declare_numparam(node) + name = node.children[0] + + if name =~ /\A_[1-9]\z/ && !static_env.declared?(name) && context.in_dynamic_block? + # definitely an implicit param + location = node.loc.expression + + if max_numparam_stack.has_ordinary_params? + diagnostic :error, :ordinary_param_defined, nil, [nil, location] + end + + raw_max_numparam_stack = max_numparam_stack.stack.dup + + # ignore current block scope + raw_max_numparam_stack.pop + + raw_max_numparam_stack.reverse_each do |outer_scope| + if outer_scope[:static] + # found an outer scope that can't have numparams + # like def/class/etc + break + else + outer_scope_has_numparams = outer_scope[:value] > 0 + + if outer_scope_has_numparams + diagnostic :error, :numparam_used_in_outer_scope, nil, [nil, location] + else + # for now it's ok, but an outer scope can also be a block + # with numparams, so we need to continue + end + end + end + + static_env.declare(name) + max_numparam_stack.register(name[1].to_i) + + true + else + false + end + end +##### State transition tables begin ### + +racc_action_table = [ + -588, 218, 219, 218, 219, 3, -106, -588, -588, -588, + 815, 559, -588, -588, -588, 224, -588, 281, 815, 1026, + 123, 228, 223, 559, -588, 122, -588, -588, -588, 218, + 219, 221, 885, 600, -107, -114, -588, -588, 559, -588, + -588, -588, -588, -588, 559, 559, 559, -106, -107, -703, + 886, -113, 411, 857, -114, 572, -489, 413, 412, 573, + 281, 229, 229, 752, -109, -111, -588, -588, -588, -588, + -588, -588, -588, -588, -588, -588, -588, -588, -588, -588, + 225, 276, -588, -588, -588, 119, -588, -588, 747, 229, + -588, 978, -108, -588, -588, 229, -588, 229, -588, 599, + -588, 1027, -588, -588, 280, -588, -588, -588, -588, -588, + -113, -588, -591, -588, -109, -97, 281, 218, 219, -591, + -591, -591, 1093, 229, -591, -591, -591, -588, -591, 123, + -588, -588, -588, -588, 122, -588, -591, -588, -591, -591, + -591, 123, -588, -98, -105, -588, 122, 280, -591, -591, + -111, -591, -591, -591, -591, -591, 123, -110, -108, 896, + -104, 122, 123, 123, 123, -106, -107, 122, 122, 122, + -106, -107, -114, -100, -102, -110, -112, -114, -591, -591, + -591, -591, -591, -591, -591, -591, -591, -591, -591, -591, + -591, -591, 123, -112, -591, -591, -591, 122, -591, -591, + 977, -99, -591, 280, 1094, -591, -591, -703, -591, 132, + -591, 123, -591, 587, -591, -591, 122, -591, -591, -591, + -591, -591, -304, -591, 229, -591, 815, -602, -113, -304, + -304, -304, -109, -113, -690, -304, -304, -109, -304, -591, + -690, -691, -591, -591, -591, -591, -304, -591, -603, -591, + 281, 1032, 572, 587, -591, 602, 834, -591, -304, -304, + -100, -304, -304, -304, -304, -304, 101, 102, -111, 1031, + -691, 215, 1085, -111, -102, -110, -108, 589, 588, 464, + -110, -108, 101, 102, -101, -103, -106, 781, -304, -304, + -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, + -304, -304, 216, 224, -304, -304, -304, -107, 626, 572, + 274, -112, -304, 834, 276, -304, -112, 589, 588, 585, + -304, 601, -304, 587, -304, -304, -100, -304, -304, -304, + -304, -304, 226, -304, -694, -304, 217, 280, -114, 536, + -102, -694, -694, -694, 103, 104, -703, -694, -694, -304, + -694, 220, -304, -304, -703, -103, -343, -304, -694, -694, + 103, 104, -99, -343, -304, 270, -100, -112, 225, -100, + -694, -694, -343, -694, -694, -694, -694, -694, 329, -588, + -102, -100, 229, -102, -101, 330, -588, 589, 588, 587, + 229, -114, 810, 587, 123, -102, 229, 783, -113, 122, + -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, + -694, -694, -694, -694, 566, 935, -694, -694, -694, 224, + 627, -343, 752, 414, -694, 732, 461, -694, -99, 811, + 587, 463, -694, 621, -694, 462, -694, -694, 587, -694, + -694, -694, -694, -694, -588, -694, -694, -694, 465, -690, + -101, -109, 466, 589, 588, 585, 587, 589, 588, 585, + 226, -694, 587, 733, -694, -694, -687, -101, -99, -694, + 684, -99, 587, -694, 1101, 943, -694, 218, 219, -110, + -694, -694, -694, -99, 225, -694, -694, -694, -111, -694, + -101, 228, -109, -101, 589, 588, -92, -694, -694, -694, + -694, -694, 589, 588, 590, -101, -688, -105, -78, -694, + -694, 1101, -694, -694, -694, -694, -694, 495, -588, -114, + 589, 588, 592, 587, 821, -588, 589, 588, 594, 817, + -687, 622, 507, 818, -588, 918, 589, 588, 598, -694, + -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, + -694, -694, -694, -687, -602, -694, -694, -694, -591, 812, + -694, 549, 509, -694, 548, -591, -694, -694, 511, -694, + -688, -694, 797, -694, -591, -694, -694, 132, -694, -694, + -694, -694, -694, -588, -694, -694, -694, 589, 588, 603, + -111, -600, -591, -688, -108, -601, 267, 268, -600, -591, + -694, -97, -601, -694, -694, -694, -694, -600, -694, -598, + -694, -601, -304, -106, -77, -694, -598, -603, -110, -304, + -304, -304, 229, -591, -304, -304, -304, 224, -304, 218, + 219, -108, 266, 265, 529, -597, -304, 522, -304, -304, + -304, 123, -597, 527, 549, 523, 122, 551, -304, -304, + 536, -304, -304, -304, -304, -304, -600, -591, 530, -295, + -601, 224, -599, -596, -98, 285, -295, 123, 538, -599, + -596, 857, 122, 566, -598, -295, -107, 462, -304, -304, + -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, + -304, -304, 225, 935, -304, -304, -304, -104, 813, -304, + -597, 229, -304, 732, -593, -304, -304, 276, -304, -113, + -304, -593, -304, 549, -304, -304, 551, -304, -304, -304, + -304, -304, -304, -304, -295, -304, 225, -599, -596, -304, + -304, -304, 123, 828, 829, -304, -304, 122, -304, -304, + 533, 733, -304, -304, -304, -304, -304, -304, -594, -304, + 891, 857, 539, 943, -304, -594, 250, -112, -304, -304, + 229, -304, -304, -304, -304, -304, 552, 621, 553, -593, + 724, 224, 721, 720, 719, 729, 722, 511, 569, -595, + 126, 127, 128, 129, 130, 732, -595, 567, -304, -304, + -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, + -304, -304, 566, 224, -304, -304, -304, 727, 626, 403, + 274, 570, -304, -594, -100, -304, 737, 736, 740, 739, + -304, 571, -304, 733, -304, -304, -109, -304, -304, -304, + -304, -304, 622, -304, -694, -304, 225, 549, 579, 87, + 551, -694, -694, -694, -595, 740, 739, -694, -694, -304, + -694, 88, -304, -304, 604, -304, 607, -304, -694, -694, + 608, 89, 229, 909, -304, 1154, -277, -112, 225, 610, + -694, -694, 611, -694, -694, -694, -694, -694, 615, -102, + 1083, 1084, 724, 224, 721, 720, 719, 729, 722, 250, + 575, -111, 724, 229, 721, 720, 719, 732, 722, 577, + -694, -694, -694, -694, -694, -694, -694, -694, -694, -694, + -694, -694, -694, -694, 891, 857, -694, -694, -694, 727, + 627, 247, 250, 619, -694, 249, 248, -694, 737, 736, + 740, 739, -694, 620, -694, 733, -694, -694, 276, -694, + -694, -694, -694, -694, 797, -694, -694, -694, 225, 631, + 224, 250, 250, 250, 247, -305, -305, 614, 249, 248, + 250, -694, -305, -305, -694, -694, 612, -694, 229, -694, + 224, -305, -305, 672, 229, 909, -694, 1117, 229, -110, + 7, 79, 80, 81, 11, 62, 577, 229, -92, 68, + 69, -99, 687, 229, 72, -694, 70, 71, 73, 32, + 33, 77, 78, -108, 542, 698, 703, 704, 82, 30, + 29, 111, 110, 112, 113, 225, 229, 21, 706, 743, + -305, -305, 748, 10, 50, 9, 12, 115, 114, 116, + 105, 61, 107, 106, 108, 225, 109, 117, 118, -304, + 101, 102, 46, 47, 45, -304, -304, -694, 749, 224, + 753, -691, -304, 770, -694, -304, 1122, -691, 780, -690, + 784, -304, 785, -694, 42, 1120, -278, 35, 798, 495, + 63, 64, 224, 495, 65, 229, 37, 815, 816, 1117, + 49, 833, -694, 836, 837, 270, 775, 776, 577, 22, + 777, 117, 118, 843, 99, 87, 90, 91, 845, 92, + 94, 93, 95, 847, -304, 509, 511, 88, 98, 698, + -304, 229, -694, 276, 225, 67, 276, 89, 103, 104, + 698, 250, 43, 44, 303, 79, 80, 81, 11, 62, + 857, 865, 868, 68, 69, 868, 870, 225, 72, 872, + 70, 71, 73, 32, 33, 77, 78, 242, 874, 876, + 887, 888, 82, 30, 29, 111, 110, 112, 113, 857, + 1114, 21, 721, 720, 719, 893, 722, 10, 50, 305, + 12, 115, 114, 116, 105, 61, 107, 106, 108, 894, + 109, 117, 118, 229, 101, 102, 46, 47, 45, 250, + 254, 255, 256, 257, 267, 268, 262, 263, 258, 259, + 229, 243, 244, 904, -279, 260, 261, 229, 42, 917, + 661, 307, 729, 944, 63, 64, 845, 951, 65, 229, + 37, 247, 732, 253, 49, 249, 248, 698, 245, 246, + 266, 265, 251, 22, 252, 970, -277, 974, 99, 87, + 90, 91, 229, 92, 94, 93, 95, 995, 996, 229, + 999, 88, 98, 1001, 264, 740, 739, 1009, 1010, 67, + 733, 89, 103, 104, 1013, 229, 43, 44, 7, 79, + 80, 81, 11, 62, 1015, 229, 1019, 68, 69, -280, + 229, 229, 72, 1025, 70, 71, 73, 32, 33, 77, + 78, 126, 127, 128, 129, 130, 82, 30, 29, 111, + 110, 112, 113, 1028, 229, 21, 229, 229, 229, 1040, + 616, 10, 50, 9, 12, 115, 114, 116, 105, 61, + 107, 106, 108, 868, 109, 117, 118, 868, 101, 102, + 46, 47, 45, 250, 254, 255, 256, 257, 267, 268, + 262, 263, 258, 259, 1044, 243, 244, 1046, 1048, 260, + 261, 1050, 42, 229, 1052, 35, 1053, 1066, 63, 64, + 868, 886, 65, 1068, 37, 247, 1070, 253, 49, 249, + 248, 1072, 245, 246, 266, 265, 251, 22, 252, 1074, + 1074, 229, 99, 87, 90, 91, 1089, 92, 94, 93, + 95, 770, 815, 1092, 1095, 88, 98, 815, 264, 1111, + -250, 1118, 1123, 67, 1130, 89, 103, 104, 1131, 229, + 43, 44, 303, 79, 80, 81, 11, 62, 1139, 1142, + 868, 68, 69, 1144, 1146, 1148, 72, 1150, 70, 71, + 73, 32, 33, 77, 78, 126, 127, 128, 129, 130, + 82, 30, 29, 111, 110, 112, 113, 1150, 703, 21, + 1163, 1164, 1165, 1074, 616, 10, 50, 305, 12, 115, + 114, 116, 105, 61, 107, 106, 108, 1074, 109, 117, + 118, 1074, 101, 102, 46, 47, 45, 250, 254, 255, + 256, 257, 267, 268, 262, 263, 258, 259, 1173, 243, + 244, 1142, 1142, 260, 261, -691, 42, -690, 229, 35, + 729, 1131, 63, 64, 1142, 1186, 65, 1150, 37, 247, + 732, 253, 49, 249, 248, 1150, 245, 246, 266, 265, + 251, 22, 252, 1150, 1074, 1150, 99, 87, 90, 91, + nil, 92, 94, 93, 95, nil, nil, nil, nil, 88, + 98, nil, 264, 740, 739, nil, nil, 67, 733, 89, + 103, 104, nil, nil, 43, 44, 303, 79, 80, 81, + 11, 62, nil, nil, nil, 68, 69, nil, nil, nil, + 72, nil, 70, 71, 73, 32, 33, 77, 78, 126, + 127, 128, 129, 130, 82, 30, 29, 111, 110, 112, + 113, nil, 1114, 21, 721, 720, 719, nil, 722, 10, + 50, 305, 12, 115, 114, 116, 105, 61, 107, 106, + 108, nil, 109, 117, 118, nil, 101, 102, 46, 47, + 45, 250, 254, 255, 256, 257, 267, 268, 262, 263, + 258, 259, nil, 243, 244, nil, nil, 260, 261, nil, + 42, nil, nil, 35, nil, nil, 63, 64, nil, nil, + 65, nil, 37, 247, nil, 253, 49, 249, 248, nil, + 245, 246, 266, 265, 251, 22, 252, nil, nil, nil, + 99, 87, 90, 91, nil, 92, 94, 93, 95, nil, + nil, nil, nil, 88, 98, nil, 264, nil, nil, nil, + nil, 67, nil, 89, 103, 104, nil, nil, 43, 44, + 303, 79, 80, 81, 11, 62, nil, nil, nil, 68, + 69, nil, nil, nil, 72, nil, 70, 71, 73, 32, + 33, 77, 78, nil, nil, nil, nil, nil, 82, 30, + 29, 111, 110, 112, 113, nil, nil, 21, nil, nil, + nil, nil, nil, 10, 50, 305, 12, 115, 114, 116, + 105, 61, 107, 106, 108, nil, 109, 117, 118, nil, + 101, 102, 46, 47, 45, 250, 254, 255, 256, 257, + 267, 268, 262, 263, 258, 259, nil, 243, 244, nil, + nil, 260, 261, nil, 42, nil, nil, 307, nil, nil, + 63, 64, nil, nil, 65, nil, 37, 247, nil, 253, + 49, 249, 248, nil, 245, 246, 266, 265, 251, 22, + 252, nil, nil, nil, 99, 87, 90, 91, nil, 92, + 94, 93, 95, nil, nil, nil, nil, 88, 98, 229, + 264, nil, nil, nil, nil, 67, nil, 89, 103, 104, + nil, nil, 43, 44, 303, 79, 80, 81, 11, 62, + nil, nil, nil, 68, 69, nil, nil, nil, 72, nil, + 70, 71, 73, 32, 33, 77, 78, nil, nil, nil, + nil, nil, 82, 30, 29, 111, 110, 112, 113, nil, + nil, 21, nil, nil, nil, nil, nil, 10, 50, 305, + 12, 115, 114, 116, 105, 61, 107, 106, 108, nil, + 109, 117, 118, nil, 101, 102, 46, 47, 45, 250, + 254, 255, 256, 257, 267, 268, 262, 263, 258, 259, + nil, 243, 244, nil, nil, 260, 261, nil, 42, nil, + nil, 307, nil, nil, 63, 64, nil, nil, 65, nil, + 37, 247, nil, 253, 49, 249, 248, nil, 245, 246, + 266, 265, 251, 22, 252, nil, nil, nil, 99, 87, + 90, 91, nil, 92, 94, 93, 95, nil, nil, nil, + nil, 88, 98, nil, 264, nil, nil, nil, nil, 67, + nil, 89, 103, 104, nil, nil, 43, 44, 303, 79, + 80, 81, 11, 62, nil, nil, nil, 68, 69, nil, + nil, nil, 72, nil, 70, 71, 73, 32, 33, 77, + 78, nil, nil, nil, nil, nil, 82, 30, 29, 111, + 110, 112, 113, nil, nil, 21, nil, nil, nil, nil, + nil, 10, 50, 305, 12, 115, 114, 116, 105, 61, + 107, 106, 108, nil, 109, 117, 118, nil, 101, 102, + 46, 47, 45, 250, 254, 255, 256, 257, 267, 268, + 262, 263, 258, 259, nil, 243, 244, nil, nil, 260, + 261, nil, 42, nil, nil, 35, nil, nil, 63, 64, + nil, nil, 65, nil, 37, 247, nil, 253, 49, 249, + 248, nil, 245, 246, 266, 265, 251, 22, 252, nil, + nil, nil, 99, 87, 90, 91, nil, 92, 94, 93, + 95, nil, nil, nil, nil, 88, 98, nil, 264, nil, + nil, nil, nil, 67, nil, 89, 103, 104, nil, nil, + 43, 44, 303, 79, 80, 81, 11, 62, nil, nil, + nil, 68, 69, nil, nil, nil, 72, nil, 70, 71, + 73, 32, 33, 77, 78, nil, nil, nil, nil, nil, + 82, 30, 29, 111, 110, 112, 113, nil, nil, 21, + nil, nil, nil, nil, nil, 10, 50, 305, 12, 115, + 114, 116, 105, 61, 107, 106, 108, nil, 109, 117, + 118, nil, 101, 102, 46, 47, 45, 250, 254, 255, + 256, 257, 267, 268, 262, 263, 258, 259, nil, 243, + 244, nil, nil, 260, 261, nil, 42, nil, nil, 35, + nil, nil, 63, 64, nil, nil, 65, nil, 37, 247, + nil, 253, 49, 249, 248, nil, 245, 246, 266, 265, + 251, 22, 252, nil, nil, nil, 99, 87, 90, 91, + nil, 92, 94, 93, 95, nil, nil, nil, nil, 88, + 98, nil, 264, nil, nil, nil, nil, 67, nil, 89, + 103, 104, nil, nil, 43, 44, 303, 79, 80, 81, + 11, 62, nil, nil, nil, 68, 69, nil, nil, nil, + 72, nil, 70, 71, 73, 32, 33, 77, 78, nil, + nil, nil, nil, nil, 82, 30, 29, 111, 110, 112, + 113, nil, 724, 21, 721, 720, 719, nil, 722, 10, + 50, 305, 12, 115, 114, 116, 105, 61, 107, 106, + 108, nil, 109, 117, 118, nil, 101, 102, 46, 47, + 45, 724, nil, 721, 720, 719, nil, 722, nil, 878, + nil, 724, nil, 721, 720, 719, nil, 722, 882, nil, + 42, nil, nil, 35, nil, nil, 63, 64, nil, nil, + 65, 724, 37, 721, 720, 719, 49, 722, 878, nil, + nil, nil, nil, nil, nil, 22, nil, 882, 878, nil, + 99, 87, 90, 91, nil, 92, 94, 93, 95, nil, + nil, nil, nil, 88, 98, nil, nil, nil, 878, nil, + nil, 67, nil, 89, 103, 104, nil, 882, 43, 44, + 303, 79, 80, 81, 11, 62, nil, nil, nil, 68, + 69, nil, nil, nil, 72, nil, 70, 71, 73, 32, + 33, 77, 78, nil, nil, nil, nil, nil, 82, 30, + 29, 111, 110, 112, 113, nil, nil, 21, nil, nil, + nil, nil, nil, 10, 50, 305, 12, 115, 114, 116, + 105, 61, 107, 106, 108, nil, 109, 117, 118, nil, + 101, 102, 46, 47, 45, 250, 254, 255, 256, 257, + 267, 268, 262, 263, 258, 259, nil, -716, -716, nil, + nil, 260, 261, nil, 42, nil, nil, 35, nil, nil, + 63, 64, nil, 250, 65, nil, 37, 247, nil, 253, + 49, 249, 248, nil, 245, 246, 266, 265, 251, 22, + 252, nil, nil, nil, 99, 87, 90, 91, nil, 92, + 94, 93, 95, nil, nil, 247, nil, 88, 98, 249, + 248, nil, 245, 246, nil, 67, nil, 89, 103, 104, + nil, nil, 43, 44, 303, 79, 80, 81, 11, 62, + nil, nil, nil, 68, 69, nil, nil, nil, 72, nil, + 70, 71, 73, 32, 33, 77, 78, nil, nil, nil, + nil, nil, 82, 30, 29, 111, 110, 112, 113, nil, + nil, 21, nil, nil, nil, nil, nil, 10, 50, 305, + 12, 115, 114, 116, 105, 61, 107, 106, 108, nil, + 109, 117, 118, nil, 101, 102, 46, 47, 45, 250, + 254, 255, 256, 257, 267, 268, 262, 263, 258, 259, + nil, -716, -716, nil, nil, 260, 261, nil, 42, nil, + nil, 35, nil, nil, 63, 64, nil, 250, 65, nil, + 37, 247, nil, 253, 49, 249, 248, nil, 245, 246, + 266, 265, 251, 22, 252, nil, nil, nil, 99, 87, + 90, 91, nil, 92, 94, 93, 95, nil, nil, 247, + nil, 88, 98, 249, 248, nil, 245, 246, nil, 67, + nil, 89, 103, 104, nil, nil, 43, 44, 303, 79, + 80, 81, 11, 62, nil, nil, nil, 68, 69, nil, + nil, nil, 72, nil, 70, 71, 73, 32, 33, 77, + 78, nil, nil, nil, nil, nil, 82, 30, 29, 111, + 110, 112, 113, nil, nil, 21, nil, nil, nil, nil, + nil, 10, 50, 305, 12, 115, 114, 116, 105, 61, + 107, 106, 108, nil, 109, 117, 118, nil, 101, 102, + 46, 47, 45, 250, 254, 255, 256, 257, 267, 268, + 262, 263, 258, 259, nil, -716, -716, nil, nil, 260, + 261, nil, 42, nil, nil, 35, nil, nil, 63, 64, + nil, nil, 65, nil, 37, 247, nil, 253, 49, 249, + 248, nil, 245, 246, 266, 265, 251, 22, 252, nil, + nil, nil, 99, 87, 90, 91, nil, 92, 94, 93, + 95, nil, nil, nil, nil, 88, 98, nil, 724, nil, + 721, 720, 719, 67, 722, 89, 103, 104, nil, nil, + 43, 44, 303, 79, 80, 81, 11, 62, nil, nil, + nil, 68, 69, nil, nil, nil, 72, nil, 70, 71, + 73, 32, 33, 77, 78, 878, nil, nil, nil, nil, + 82, 30, 29, 111, 110, 112, 113, nil, nil, 21, + nil, nil, nil, nil, nil, 10, 50, 305, 12, 115, + 114, 116, 105, 61, 107, 106, 108, nil, 109, 117, + 118, nil, 101, 102, 46, 47, 45, 250, 254, 255, + 256, 257, 267, 268, 262, 263, 258, 259, nil, -716, + -716, nil, nil, 260, 261, nil, 42, nil, nil, 35, + nil, nil, 63, 64, nil, nil, 65, nil, 37, 247, + nil, 253, 49, 249, 248, nil, 245, 246, 266, 265, + 251, 22, 252, nil, nil, nil, 99, 87, 90, 91, + nil, 92, 94, 93, 95, nil, nil, nil, nil, 88, + 98, nil, 724, nil, 721, 720, 719, 67, 722, 89, + 103, 104, nil, nil, 43, 44, 303, 79, 80, 81, + 11, 62, nil, nil, nil, 68, 69, nil, nil, nil, + 72, nil, 70, 71, 73, 32, 33, 77, 78, 878, + nil, nil, nil, nil, 82, 30, 29, 111, 110, 112, + 113, nil, nil, 21, nil, nil, nil, nil, nil, 10, + 50, 305, 12, 115, 114, 116, 105, 61, 107, 106, + 108, nil, 109, 117, 118, nil, 101, 102, 46, 47, + 45, 250, -716, -716, -716, -716, 267, 268, nil, nil, + -716, -716, nil, nil, nil, nil, nil, 260, 261, nil, + 42, nil, nil, 35, nil, nil, 63, 64, nil, nil, + 65, nil, 37, 247, nil, 253, 49, 249, 248, nil, + 245, 246, 266, 265, 251, 22, 252, nil, nil, nil, + 99, 87, 90, 91, nil, 92, 94, 93, 95, nil, + nil, nil, nil, 88, 98, nil, nil, nil, nil, nil, + nil, 67, nil, 89, 103, 104, nil, nil, 43, 44, + 303, 79, 80, 81, 11, 62, nil, nil, nil, 68, + 69, nil, nil, nil, 72, nil, 70, 71, 73, 32, + 33, 77, 78, nil, nil, nil, nil, nil, 82, 30, + 29, 111, 110, 112, 113, nil, nil, 21, nil, nil, + nil, nil, nil, 10, 50, 305, 12, 115, 114, 116, + 105, 61, 107, 106, 108, nil, 109, 117, 118, nil, + 101, 102, 46, 47, 45, 250, -716, -716, -716, -716, + 267, 268, nil, nil, -716, -716, nil, nil, nil, nil, + nil, 260, 261, nil, 42, nil, nil, 35, nil, nil, + 63, 64, nil, nil, 65, nil, 37, 247, nil, 253, + 49, 249, 248, nil, 245, 246, 266, 265, 251, 22, + 252, nil, nil, nil, 99, 87, 90, 91, nil, 92, + 94, 93, 95, nil, nil, nil, nil, 88, 98, nil, + nil, nil, nil, nil, nil, 67, nil, 89, 103, 104, + nil, nil, 43, 44, 303, 79, 80, 81, 11, 62, + nil, nil, nil, 68, 69, nil, nil, nil, 72, nil, + 70, 71, 73, 32, 33, 77, 78, nil, nil, nil, + nil, nil, 82, 30, 29, 111, 110, 112, 113, nil, + nil, 21, nil, nil, nil, nil, nil, 10, 50, 305, + 12, 115, 114, 116, 105, 61, 107, 106, 108, nil, + 109, 117, 118, nil, 101, 102, 46, 47, 45, 250, + -716, -716, -716, -716, 267, 268, nil, nil, -716, -716, + nil, nil, nil, nil, nil, 260, 261, nil, 42, nil, + nil, 35, nil, nil, 63, 64, nil, nil, 65, nil, + 37, 247, nil, 253, 49, 249, 248, nil, 245, 246, + 266, 265, 251, 22, 252, nil, nil, nil, 99, 87, + 90, 91, nil, 92, 94, 93, 95, nil, nil, nil, + nil, 88, 98, nil, nil, nil, nil, nil, nil, 67, + nil, 89, 103, 104, nil, nil, 43, 44, 303, 79, + 80, 81, 11, 62, nil, nil, nil, 68, 69, nil, + nil, nil, 72, nil, 70, 71, 73, 32, 33, 77, + 78, nil, nil, nil, nil, nil, 82, 30, 29, 111, + 110, 112, 113, nil, nil, 21, nil, nil, nil, nil, + nil, 10, 50, 305, 12, 115, 114, 116, 105, 61, + 107, 106, 108, nil, 109, 117, 118, nil, 101, 102, + 46, 47, 45, 250, -716, -716, -716, -716, 267, 268, + nil, nil, -716, -716, nil, nil, nil, nil, nil, 260, + 261, nil, 42, nil, nil, 35, nil, nil, 63, 64, + nil, nil, 65, nil, 37, 247, nil, 253, 49, 249, + 248, nil, 245, 246, 266, 265, 251, 22, 252, nil, + nil, nil, 99, 87, 90, 91, nil, 92, 94, 93, + 95, nil, nil, nil, nil, 88, 98, nil, nil, nil, + nil, nil, nil, 67, nil, 89, 103, 104, nil, nil, + 43, 44, 303, 79, 80, 81, 11, 62, nil, nil, + nil, 68, 69, nil, nil, nil, 72, nil, 70, 71, + 73, 32, 33, 77, 78, nil, nil, nil, nil, nil, + 82, 30, 29, 111, 110, 112, 113, nil, nil, 21, + nil, nil, nil, nil, nil, 10, 50, 305, 12, 115, + 114, 116, 105, 61, 107, 106, 108, nil, 109, 117, + 118, nil, 101, 102, 46, 47, 45, 250, -716, -716, + -716, -716, 267, 268, nil, nil, -716, -716, nil, nil, + nil, nil, nil, 260, 261, nil, 42, nil, nil, 35, + nil, nil, 63, 64, nil, nil, 65, nil, 37, 247, + nil, 253, 49, 249, 248, nil, 245, 246, 266, 265, + 251, 22, 252, nil, nil, nil, 99, 87, 90, 91, + nil, 92, 94, 93, 95, nil, nil, nil, nil, 88, + 98, nil, nil, nil, nil, nil, nil, 67, nil, 89, + 103, 104, nil, nil, 43, 44, 303, 79, 80, 81, + 11, 62, nil, nil, nil, 68, 69, nil, nil, nil, + 72, nil, 70, 71, 73, 32, 33, 77, 78, nil, + nil, nil, nil, nil, 82, 30, 29, 111, 110, 112, + 113, nil, nil, 21, nil, nil, nil, nil, nil, 10, + 50, 305, 12, 115, 114, 116, 105, 61, 107, 106, + 108, nil, 109, 117, 118, nil, 101, 102, 46, 47, + 45, 250, -716, -716, -716, -716, 267, 268, nil, nil, + -716, -716, nil, nil, nil, nil, nil, 260, 261, nil, + 42, nil, nil, 35, nil, nil, 63, 64, nil, nil, + 65, nil, 37, 247, nil, 253, 49, 249, 248, nil, + 245, 246, 266, 265, 251, 22, 252, nil, nil, nil, + 99, 87, 90, 91, nil, 92, 94, 93, 95, nil, + nil, nil, nil, 88, 98, nil, nil, nil, nil, nil, + nil, 67, nil, 89, 103, 104, nil, nil, 43, 44, + 303, 79, 80, 81, 11, 62, nil, nil, nil, 68, + 69, nil, nil, nil, 72, nil, 70, 71, 73, 32, + 33, 77, 78, nil, nil, nil, nil, nil, 82, 30, + 29, 111, 110, 112, 113, nil, nil, 21, nil, nil, + nil, nil, nil, 10, 50, 305, 12, 115, 114, 116, + 105, 61, 107, 106, 108, nil, 109, 117, 118, nil, + 101, 102, 46, 47, 45, 250, 254, 255, 256, 257, + 267, 268, nil, nil, 258, 259, nil, nil, nil, nil, + nil, 260, 261, nil, 42, nil, nil, 35, nil, nil, + 63, 64, nil, nil, 65, nil, 37, 247, nil, 253, + 49, 249, 248, nil, 245, 246, 266, 265, 251, 22, + 252, nil, nil, nil, 99, 87, 90, 91, nil, 92, + 94, 93, 95, nil, nil, nil, nil, 88, 98, nil, + nil, nil, nil, nil, nil, 67, nil, 89, 103, 104, + nil, nil, 43, 44, 303, 79, 80, 81, 11, 62, + nil, nil, nil, 68, 69, nil, nil, nil, 72, nil, + 70, 71, 73, 32, 33, 77, 78, nil, nil, nil, + nil, nil, 82, 30, 29, 111, 110, 112, 113, nil, + nil, 21, nil, nil, nil, nil, nil, 10, 50, 305, + 12, 115, 114, 116, 105, 61, 107, 106, 108, nil, + 109, 117, 118, nil, 101, 102, 46, 47, 45, 250, + 254, 255, 256, 257, 267, 268, 262, nil, 258, 259, + nil, nil, nil, nil, nil, 260, 261, nil, 42, nil, + nil, 35, nil, nil, 63, 64, nil, nil, 65, nil, + 37, 247, nil, 253, 49, 249, 248, nil, 245, 246, + 266, 265, 251, 22, 252, nil, nil, nil, 99, 87, + 90, 91, nil, 92, 94, 93, 95, nil, nil, nil, + nil, 88, 98, nil, nil, nil, nil, nil, nil, 67, + nil, 89, 103, 104, nil, nil, 43, 44, 303, 79, + 80, 81, 11, 62, nil, nil, nil, 68, 69, nil, + nil, nil, 72, nil, 70, 71, 73, 32, 33, 77, + 78, nil, nil, nil, nil, nil, 82, 30, 29, 111, + 110, 112, 113, nil, nil, 21, nil, nil, nil, nil, + nil, 10, 50, 305, 12, 115, 114, 116, 105, 61, + 107, 106, 108, nil, 109, 117, 118, nil, 101, 102, + 46, 47, 45, 250, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 260, + 261, nil, 42, nil, nil, 35, nil, nil, 63, 64, + nil, nil, 65, nil, 37, 247, nil, 253, 49, 249, + 248, nil, 245, 246, nil, nil, 251, 22, 252, nil, + nil, nil, 99, 87, 90, 91, nil, 92, 94, 93, + 95, nil, nil, nil, nil, 88, 98, nil, nil, nil, + nil, nil, nil, 67, nil, 89, 103, 104, nil, nil, + 43, 44, 303, 79, 80, 81, 11, 62, nil, nil, + nil, 68, 69, nil, nil, nil, 72, nil, 70, 71, + 73, 32, 33, 77, 78, nil, nil, nil, nil, nil, + 82, 30, 29, 111, 110, 112, 113, nil, nil, 21, + nil, nil, nil, nil, nil, 10, 50, 305, 12, 115, + 114, 116, 105, 61, 107, 106, 108, nil, 109, 117, + 118, nil, 101, 102, 46, 47, 45, 250, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 260, 261, nil, 42, nil, nil, 35, + nil, nil, 63, 64, nil, nil, 65, nil, 37, 247, + nil, 253, 49, 249, 248, nil, 245, 246, nil, nil, + 251, 22, 252, nil, nil, nil, 99, 87, 90, 91, + nil, 92, 94, 93, 95, nil, nil, nil, nil, 88, + 98, nil, nil, nil, nil, nil, nil, 67, nil, 89, + 103, 104, nil, nil, 43, 44, 303, 79, 80, 81, + 11, 62, nil, nil, nil, 68, 69, nil, nil, nil, + 72, nil, 70, 71, 73, 32, 33, 77, 78, nil, + nil, nil, nil, nil, 82, 30, 29, 111, 110, 112, + 113, nil, nil, 21, nil, nil, nil, nil, nil, 10, + 50, 305, 12, 115, 114, 116, 105, 61, 107, 106, + 108, nil, 109, 117, 118, nil, 101, 102, 46, 47, + 45, 250, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 260, 261, nil, + 42, nil, nil, 35, nil, nil, 63, 64, nil, nil, + 65, nil, 37, 247, nil, 253, 49, 249, 248, nil, + 245, 246, nil, nil, nil, 22, nil, nil, nil, nil, + 99, 87, 90, 91, nil, 92, 94, 93, 95, nil, + nil, nil, nil, 88, 98, nil, nil, nil, nil, nil, + nil, 67, nil, 89, 103, 104, nil, nil, 43, 44, + 303, 79, 80, 81, 11, 62, nil, nil, nil, 68, + 69, nil, nil, nil, 72, nil, 70, 71, 73, 32, + 33, 77, 78, nil, nil, nil, nil, nil, 82, 30, + 29, 111, 110, 112, 113, nil, nil, 21, nil, nil, + nil, nil, nil, 10, 50, 305, 12, 115, 114, 116, + 105, 61, 107, 106, 108, nil, 109, 117, 118, nil, + 101, 102, 46, 47, 45, 250, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 260, 261, nil, 42, nil, nil, 35, nil, nil, + 63, 64, nil, nil, 65, nil, 37, 247, nil, 253, + 49, 249, 248, nil, 245, 246, nil, nil, nil, 22, + nil, nil, nil, nil, 99, 87, 90, 91, nil, 92, + 94, 93, 95, nil, nil, nil, nil, 88, 98, nil, + nil, nil, nil, nil, nil, 67, nil, 89, 103, 104, + nil, nil, 43, 44, 303, 79, 80, 81, 11, 62, + nil, nil, nil, 68, 69, nil, nil, nil, 72, nil, + 70, 71, 73, 32, 33, 77, 78, nil, nil, nil, + nil, nil, 82, 30, 29, 111, 110, 112, 113, nil, + nil, 21, nil, nil, nil, nil, nil, 10, 50, 305, + 12, 115, 114, 116, 105, 61, 107, 106, 108, nil, + 109, 117, 118, nil, 101, 102, 46, 47, 45, 250, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 260, 261, nil, 42, nil, + nil, 35, nil, nil, 63, 64, nil, nil, 65, nil, + 37, 247, nil, nil, 49, 249, 248, nil, 245, 246, + nil, nil, nil, 22, nil, nil, nil, nil, 99, 87, + 90, 91, nil, 92, 94, 93, 95, nil, nil, nil, + nil, 88, 98, nil, nil, nil, nil, nil, nil, 67, + nil, 89, 103, 104, nil, nil, 43, 44, 303, 79, + 80, 81, 11, 62, nil, nil, nil, 68, 69, nil, + nil, nil, 72, nil, 70, 71, 73, 32, 33, 77, + 78, nil, nil, nil, nil, nil, 82, 30, 29, 111, + 110, 112, 113, nil, nil, 21, nil, nil, nil, nil, + nil, 10, 50, 305, 12, 115, 114, 116, 105, 61, + 107, 106, 108, nil, 109, 117, 118, nil, 101, 102, + 46, 47, 45, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 42, nil, nil, 35, nil, nil, 63, 64, + nil, nil, 65, nil, 37, nil, nil, nil, 49, nil, + nil, nil, nil, nil, nil, nil, nil, 22, nil, nil, + nil, nil, 99, 87, 90, 91, nil, 92, 94, 93, + 95, nil, nil, nil, nil, 88, 98, nil, nil, nil, + nil, nil, nil, 67, nil, 89, 103, 104, nil, nil, + 43, 44, 303, 79, 80, 81, 11, 62, nil, nil, + nil, 68, 69, nil, nil, nil, 72, nil, 70, 71, + 73, 32, 33, 77, 78, nil, nil, nil, nil, nil, + 82, 30, 29, 111, 110, 112, 113, nil, nil, 21, + nil, nil, nil, nil, nil, 10, 50, 305, 12, 115, + 114, 116, 105, 61, 107, 106, 108, nil, 109, 117, + 118, nil, 101, 102, 46, 47, 45, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 42, nil, nil, 35, + nil, nil, 63, 64, nil, nil, 65, nil, 37, nil, + nil, nil, 49, nil, nil, nil, nil, nil, nil, nil, + nil, 22, nil, nil, nil, nil, 99, 87, 90, 91, + nil, 92, 94, 93, 95, nil, nil, nil, nil, 88, + 98, nil, nil, nil, nil, nil, nil, 67, nil, 89, + 103, 104, nil, nil, 43, 44, 79, 80, 81, 11, + 62, nil, nil, nil, 68, 69, nil, nil, nil, 72, + nil, 70, 71, 73, 32, 33, 77, 78, nil, nil, + nil, nil, nil, 82, 30, 29, 111, 110, 112, 113, + nil, nil, 21, nil, nil, nil, nil, nil, 10, 50, + 9, 12, 115, 114, 116, 105, 61, 107, 106, 108, + nil, 109, 117, 118, nil, 101, 102, 46, 47, 45, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 42, + nil, nil, 35, nil, nil, 63, 64, nil, nil, 65, + nil, 37, nil, nil, nil, 49, nil, nil, nil, nil, + nil, nil, nil, nil, 22, nil, nil, nil, nil, 99, + 87, 90, 91, nil, 92, 94, 93, 95, nil, nil, + nil, nil, 88, 98, nil, nil, nil, 79, 80, 81, + 67, 62, 89, 103, 104, 68, 69, 43, 44, nil, + 72, nil, 70, 71, 73, 32, 33, 77, 78, nil, + nil, nil, nil, nil, 82, 30, 29, 111, 110, 112, + 113, nil, nil, 241, nil, nil, nil, nil, nil, nil, + 50, nil, nil, 115, 114, 116, 105, 61, 107, 106, + 108, nil, 109, 117, 118, nil, 101, 102, 46, 47, + 45, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 234, nil, nil, 240, nil, nil, 63, 64, nil, nil, + 65, nil, nil, nil, nil, nil, 49, nil, nil, nil, + nil, nil, nil, nil, nil, 239, nil, nil, nil, nil, + 99, 87, 90, 91, nil, 92, 94, 93, 95, nil, + nil, nil, nil, 88, 98, nil, nil, nil, nil, nil, + nil, 67, nil, 89, 103, 104, -424, nil, 43, 44, + nil, nil, nil, -424, -424, -424, nil, nil, -424, -424, + -424, nil, -424, nil, nil, nil, nil, nil, nil, nil, + -424, -424, -424, -424, nil, nil, nil, nil, nil, nil, + nil, nil, -424, -424, nil, -424, -424, -424, -424, -424, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, -424, -424, -424, -424, -424, -424, -424, -424, + -424, -424, -424, -424, -424, -424, nil, nil, -424, -424, + -424, nil, nil, -424, nil, 276, -424, nil, nil, -424, + -424, nil, -424, nil, -424, nil, -424, nil, -424, -424, + nil, -424, -424, -424, -424, -424, -311, -424, -424, -424, + nil, nil, nil, -311, -311, -311, nil, nil, -311, -311, + -311, nil, -311, -424, nil, nil, -424, -424, nil, -424, + -311, -424, -311, -311, nil, nil, nil, nil, -424, nil, + nil, nil, -311, -311, nil, -311, -311, -311, -311, -311, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, -311, -311, -311, -311, -311, -311, -311, -311, + -311, -311, -311, -311, -311, -311, nil, nil, -311, -311, + -311, nil, nil, -311, nil, 285, -311, nil, nil, -311, + -311, nil, -311, nil, -311, nil, -311, nil, -311, -311, + nil, -311, -311, -311, -311, -311, nil, -311, nil, -311, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, -311, nil, nil, -311, -311, nil, -311, + nil, -311, 79, 80, 81, nil, 62, nil, -311, nil, + 68, 69, nil, nil, nil, 72, nil, 70, 71, 73, + 32, 33, 77, 78, nil, nil, nil, nil, nil, 82, + 30, 29, 111, 110, 112, 113, nil, nil, 241, nil, + nil, nil, nil, nil, nil, 50, nil, nil, 115, 114, + 116, 105, 61, 107, 106, 108, 297, 109, 117, 118, + nil, 101, 102, 46, 47, 45, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 234, nil, nil, 240, nil, + nil, 63, 64, nil, nil, 65, nil, 294, nil, 292, + nil, 49, nil, nil, 298, nil, nil, nil, nil, nil, + 239, nil, nil, nil, nil, 99, 295, 90, 91, nil, + 92, 94, 93, 95, nil, nil, nil, nil, 88, 98, + nil, nil, nil, 79, 80, 81, 67, 62, 89, 103, + 104, 68, 69, 43, 44, nil, 72, nil, 70, 71, + 73, 32, 33, 77, 78, nil, nil, nil, nil, nil, + 82, 30, 29, 111, 110, 112, 113, nil, nil, 241, + nil, nil, nil, nil, nil, nil, 50, nil, nil, 115, + 114, 116, 105, 61, 107, 106, 108, 297, 109, 117, + 118, nil, 101, 102, 46, 47, 45, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 234, nil, nil, 240, + nil, nil, 63, 64, nil, nil, 65, nil, 294, nil, + 292, nil, 49, nil, nil, 298, nil, nil, nil, nil, + nil, 239, nil, nil, nil, nil, 99, 295, 90, 91, + nil, 92, 94, 93, 95, nil, nil, nil, nil, 88, + 98, nil, nil, nil, 79, 80, 81, 67, 62, 89, + 103, 104, 68, 69, 43, 44, nil, 72, nil, 70, + 71, 73, 32, 33, 77, 78, nil, nil, nil, nil, + nil, 82, 30, 29, 111, 110, 112, 113, nil, nil, + 241, nil, nil, nil, nil, nil, nil, 50, nil, nil, + 115, 114, 116, 105, 61, 107, 106, 108, 297, 109, + 117, 118, nil, 101, 102, 46, 47, 45, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 234, nil, nil, + 240, nil, nil, 63, 64, nil, nil, 65, nil, 294, + nil, 292, nil, 49, nil, nil, 298, nil, nil, nil, + nil, nil, 239, nil, nil, nil, nil, 99, 295, 90, + 91, nil, 92, 94, 93, 95, nil, nil, nil, nil, + 88, 98, nil, nil, nil, 79, 80, 81, 67, 62, + 89, 103, 104, 68, 69, 43, 44, nil, 72, nil, + 70, 71, 73, 322, 323, 77, 78, nil, nil, nil, + nil, nil, 82, 319, 325, 111, 110, 112, 113, nil, + nil, 241, nil, nil, nil, nil, nil, nil, 50, nil, + nil, 115, 114, 116, 105, 61, 107, 106, 108, nil, + 109, 117, 118, nil, 101, 102, 46, 47, 45, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 234, nil, + nil, 240, nil, nil, 63, 64, nil, nil, 65, nil, + nil, nil, nil, nil, 49, nil, nil, nil, nil, nil, + nil, nil, nil, 239, nil, nil, nil, nil, 99, 87, + 90, 91, nil, 92, 94, 93, 95, nil, nil, nil, + nil, 88, 98, nil, nil, nil, 79, 80, 81, 67, + 62, 89, 103, 104, 68, 69, 43, 44, nil, 72, + nil, 70, 71, 73, 322, 323, 77, 78, nil, nil, + nil, nil, nil, 82, 319, 325, 111, 110, 112, 113, + nil, nil, 241, nil, nil, nil, nil, nil, nil, 50, + nil, nil, 115, 114, 116, 105, 61, 107, 106, 108, + nil, 109, 117, 118, nil, 101, 102, 46, 47, 45, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 234, + nil, nil, 240, nil, nil, 63, 64, nil, nil, 65, + nil, nil, nil, nil, nil, 49, nil, nil, nil, nil, + nil, nil, nil, nil, 239, nil, nil, nil, nil, 99, + 87, 90, 91, nil, 92, 94, 93, 95, nil, nil, + nil, nil, 88, 98, nil, nil, nil, 79, 80, 81, + 67, 62, 89, 103, 104, 68, 69, 43, 44, nil, + 72, nil, 70, 71, 73, 322, 323, 77, 78, nil, + nil, nil, nil, nil, 82, 319, 325, 111, 110, 112, + 113, nil, nil, 241, nil, nil, nil, nil, nil, nil, + 50, nil, nil, 115, 114, 116, 105, 61, 107, 106, + 108, nil, 109, 117, 118, nil, 101, 102, 46, 47, + 45, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 234, nil, nil, 240, nil, nil, 63, 64, nil, nil, + 65, nil, nil, nil, nil, nil, 49, nil, nil, nil, + nil, nil, nil, nil, nil, 239, nil, nil, nil, nil, + 99, 87, 90, 91, nil, 92, 94, 93, 95, nil, + nil, nil, nil, 88, 98, nil, nil, nil, 79, 80, + 81, 67, 62, 89, 103, 104, 68, 69, 43, 44, + nil, 72, nil, 70, 71, 73, 322, 323, 77, 78, + nil, nil, nil, nil, nil, 82, 319, 325, 111, 110, + 112, 113, nil, nil, 241, nil, nil, nil, nil, nil, + nil, 50, nil, nil, 115, 114, 116, 105, 61, 107, + 106, 108, nil, 109, 117, 118, nil, 101, 102, 46, + 47, 45, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 234, nil, nil, 240, nil, nil, 63, 64, nil, + nil, 65, nil, nil, nil, nil, nil, 49, nil, nil, + nil, nil, nil, nil, nil, nil, 239, nil, nil, nil, + nil, 99, 87, 90, 91, nil, 92, 94, 93, 95, + nil, nil, nil, nil, 88, 98, nil, nil, nil, 79, + 80, 81, 67, 62, 89, 103, 104, 68, 69, 43, + 44, nil, 72, nil, 70, 71, 73, 322, 323, 77, + 78, nil, nil, nil, nil, nil, 82, 319, 325, 111, + 110, 112, 113, nil, nil, 241, nil, nil, nil, nil, + nil, nil, 50, nil, nil, 115, 114, 116, 105, 61, + 107, 106, 108, nil, 109, 117, 118, nil, 101, 102, + 46, 47, 45, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 234, nil, nil, 240, nil, nil, 63, 64, + nil, nil, 65, nil, nil, nil, nil, nil, 49, nil, + nil, nil, nil, nil, nil, nil, nil, 239, nil, nil, + nil, nil, 99, 87, 90, 91, nil, 92, 94, 93, + 95, nil, nil, nil, nil, 88, 98, nil, nil, nil, + nil, nil, nil, 67, nil, 89, 103, 104, -296, nil, + 43, 44, nil, nil, nil, -296, -296, -296, nil, nil, + -296, -296, -296, nil, -296, nil, nil, nil, nil, nil, + nil, nil, -296, nil, -296, -296, -296, nil, nil, nil, + 111, 110, 112, 113, -296, -296, nil, -296, -296, -296, + -296, -296, nil, nil, nil, nil, 115, 114, 116, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 101, + 102, nil, nil, 326, -296, -296, -296, -296, -296, -296, + -296, -296, -296, -296, -296, -296, -296, -296, nil, nil, + -296, -296, -296, nil, nil, -296, nil, nil, -296, nil, + nil, -296, -296, nil, -296, nil, -296, nil, -296, nil, + -296, -296, nil, -296, -296, -296, -296, -296, nil, -296, + nil, -296, nil, 99, 87, 90, 91, nil, 92, 94, + 93, 95, nil, nil, nil, -296, 88, 98, -296, -296, + -296, -296, nil, -296, 660, -296, 89, 103, 104, nil, + -296, 79, 80, 81, 11, 62, nil, nil, nil, 68, + 69, nil, nil, nil, 72, nil, 70, 71, 73, 32, + 33, 77, 78, nil, nil, nil, nil, nil, 82, 30, + 29, 111, 110, 112, 113, nil, nil, 21, nil, nil, + nil, nil, nil, 10, 50, nil, 12, 115, 114, 116, + 105, 61, 107, 106, 108, nil, 109, 117, 118, nil, + 101, 102, 46, 47, 45, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 42, nil, nil, 35, nil, nil, + 63, 64, nil, nil, 65, nil, 37, nil, nil, nil, + 49, nil, nil, nil, nil, nil, nil, nil, nil, 22, + nil, nil, nil, nil, 99, 87, 90, 91, nil, 92, + 94, 93, 95, nil, nil, nil, nil, 88, 98, nil, + nil, nil, 79, 80, 81, 67, 62, 89, 103, 104, + 68, 69, 43, 44, nil, 72, nil, 70, 71, 73, + 322, 323, 77, 78, nil, nil, nil, nil, nil, 82, + 319, 325, 111, 110, 112, 113, nil, nil, 241, nil, + nil, nil, nil, nil, nil, 50, nil, nil, 115, 114, + 116, 105, 61, 107, 106, 108, 297, 109, 117, 118, + nil, 101, 102, 46, 47, 45, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 234, nil, nil, 240, nil, + nil, 63, 64, nil, nil, 65, nil, 294, nil, nil, + nil, 49, nil, nil, 298, nil, nil, nil, nil, nil, + 239, nil, nil, nil, nil, 99, 295, 90, 91, nil, + 92, 94, 93, 95, nil, nil, nil, nil, 88, 98, + nil, nil, nil, 79, 80, 81, 67, 62, 89, 103, + 104, 68, 69, 43, 44, nil, 72, nil, 70, 71, + 73, 322, 323, 77, 78, nil, nil, nil, nil, nil, + 82, 319, 325, 111, 110, 112, 113, nil, nil, 241, + nil, nil, nil, nil, nil, nil, 50, nil, nil, 115, + 114, 116, 105, 61, 107, 106, 108, 297, 109, 117, + 118, nil, 101, 102, 46, 47, 45, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 234, nil, nil, 240, + nil, nil, 63, 64, nil, nil, 65, nil, nil, nil, + nil, nil, 49, nil, nil, 298, nil, nil, nil, nil, + nil, 239, nil, nil, nil, nil, 99, 295, 90, 91, + nil, 92, 94, 93, 95, nil, nil, nil, nil, 88, + 98, nil, nil, nil, 79, 80, 81, 67, 62, 89, + 103, 104, 68, 69, 43, 44, nil, 72, nil, 70, + 71, 73, 32, 33, 77, 78, nil, nil, nil, nil, + nil, 82, 30, 29, 111, 110, 112, 113, nil, nil, + 21, nil, nil, nil, nil, nil, nil, 50, nil, nil, + 115, 114, 116, 105, 61, 107, 106, 108, nil, 109, + 117, 118, nil, 101, 102, 46, 47, 45, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 234, nil, nil, + 240, nil, nil, 63, 64, nil, nil, 65, nil, nil, + nil, nil, nil, 49, nil, nil, nil, nil, nil, nil, + nil, nil, 22, nil, nil, nil, nil, 99, 87, 90, + 91, nil, 92, 94, 93, 95, nil, nil, nil, nil, + 88, 98, nil, nil, nil, 79, 80, 81, 67, 62, + 89, 103, 104, 68, 69, 43, 44, nil, 72, nil, + 70, 71, 73, 32, 33, 77, 78, nil, nil, nil, + nil, nil, 82, 30, 29, 111, 110, 112, 113, nil, + nil, 21, nil, nil, nil, nil, nil, nil, 50, nil, + nil, 115, 114, 116, 105, 61, 107, 106, 108, nil, + 109, 117, 118, nil, 101, 102, 46, 47, 45, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 234, nil, + nil, 240, nil, nil, 63, 64, nil, nil, 65, nil, + nil, nil, nil, nil, 49, nil, nil, nil, nil, nil, + nil, nil, nil, 22, nil, nil, nil, nil, 99, 87, + 90, 91, nil, 92, 94, 93, 95, nil, nil, nil, + nil, 88, 98, nil, nil, nil, 79, 80, 81, 67, + 62, 89, 103, 104, 68, 69, 43, 44, nil, 72, + nil, 70, 71, 73, 32, 33, 77, 78, nil, nil, + nil, nil, nil, 82, 30, 29, 111, 110, 112, 113, + nil, nil, 21, nil, nil, nil, nil, nil, nil, 50, + nil, nil, 115, 114, 116, 105, 61, 107, 106, 108, + nil, 109, 117, 118, nil, 101, 102, 46, 47, 45, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 234, + nil, nil, 240, nil, nil, 63, 64, nil, nil, 65, + nil, nil, nil, nil, nil, 49, nil, nil, nil, nil, + nil, nil, nil, nil, 22, nil, nil, nil, nil, 99, + 87, 90, 91, nil, 92, 94, 93, 95, nil, nil, + nil, nil, 88, 98, 123, nil, nil, nil, nil, 122, + 67, nil, 89, 103, 104, nil, nil, 43, 44, 79, + 80, 81, 11, 62, nil, nil, nil, 68, 69, nil, + nil, nil, 72, nil, 70, 71, 73, 32, 33, 77, + 78, nil, nil, nil, nil, nil, 82, 30, 29, 111, + 110, 112, 113, nil, nil, 21, nil, nil, nil, nil, + nil, 10, 50, 9, 12, 115, 114, 116, 105, 61, + 107, 106, 108, nil, 109, 117, 118, nil, 101, 102, + 46, 47, 45, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 42, nil, nil, 35, nil, nil, 63, 64, + nil, nil, 65, nil, 37, nil, nil, nil, 49, nil, + nil, nil, nil, nil, nil, nil, nil, 22, nil, nil, + nil, nil, 99, 87, 90, 91, nil, 92, 94, 93, + 95, nil, nil, nil, nil, 88, 98, nil, nil, nil, + nil, nil, 403, 67, nil, 89, 103, 104, nil, nil, + 43, 44, 79, 80, 81, nil, 62, nil, nil, nil, + 68, 69, nil, nil, nil, 72, nil, 70, 71, 73, + 32, 33, 77, 78, nil, nil, nil, nil, nil, 82, + 30, 29, 111, 110, 112, 113, nil, nil, 21, nil, + nil, nil, nil, nil, nil, 50, nil, nil, 115, 114, + 116, 105, 61, 107, 106, 108, nil, 109, 117, 118, + nil, 101, 102, 46, 47, 45, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 234, nil, nil, 240, nil, + nil, 63, 64, nil, nil, 65, nil, nil, nil, nil, + nil, 49, nil, nil, nil, nil, nil, nil, nil, nil, + 22, nil, nil, nil, nil, 99, 87, 90, 91, nil, + 92, 94, 93, 95, nil, nil, nil, nil, 88, 98, + nil, nil, nil, 79, 80, 81, 67, 62, 89, 103, + 104, 68, 69, 43, 44, nil, 72, nil, 70, 71, + 73, 32, 33, 77, 78, nil, nil, nil, nil, nil, + 82, 30, 29, 111, 110, 112, 113, nil, nil, 21, + nil, nil, nil, nil, nil, nil, 50, nil, nil, 115, + 114, 116, 105, 61, 107, 106, 108, nil, 109, 117, + 118, nil, 101, 102, 46, 47, 45, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 234, nil, nil, 240, + nil, nil, 63, 64, nil, nil, 65, nil, nil, nil, + nil, nil, 49, nil, nil, nil, nil, nil, nil, nil, + nil, 22, nil, nil, nil, nil, 99, 87, 90, 91, + nil, 92, 94, 93, 95, nil, nil, nil, nil, 88, + 98, nil, nil, nil, 79, 80, 81, 67, 62, 89, + 103, 104, 68, 69, 43, 44, nil, 72, nil, 70, + 71, 73, 32, 33, 77, 78, nil, nil, nil, nil, + nil, 82, 30, 29, 111, 110, 112, 113, nil, nil, + 21, nil, nil, nil, nil, nil, nil, 50, nil, nil, + 115, 114, 116, 105, 61, 107, 106, 108, nil, 109, + 117, 118, nil, 101, 102, 46, 47, 45, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 234, nil, nil, + 240, nil, nil, 63, 64, nil, nil, 65, nil, nil, + nil, nil, nil, 49, nil, nil, nil, nil, nil, nil, + nil, nil, 22, nil, nil, nil, nil, 99, 87, 90, + 91, nil, 92, 94, 93, 95, nil, nil, nil, nil, + 88, 98, nil, nil, nil, 79, 80, 81, 67, 62, + 89, 103, 104, 68, 69, 43, 44, nil, 72, nil, + 70, 71, 73, 32, 33, 77, 78, nil, nil, nil, + nil, nil, 82, 30, 29, 111, 110, 112, 113, nil, + nil, 21, nil, nil, nil, nil, nil, nil, 50, nil, + nil, 115, 114, 116, 105, 61, 107, 106, 108, nil, + 109, 117, 118, nil, 101, 102, 46, 47, 45, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 234, nil, + nil, 240, nil, nil, 63, 64, nil, nil, 65, nil, + nil, nil, nil, nil, 49, nil, nil, nil, nil, nil, + nil, nil, nil, 22, nil, nil, nil, nil, 99, 87, + 90, 91, nil, 92, 94, 93, 95, nil, nil, nil, + nil, 88, 98, nil, nil, nil, nil, nil, nil, 67, + nil, 89, 103, 104, nil, nil, 43, 44, 79, 80, + 81, 11, 62, nil, nil, nil, 68, 69, nil, nil, + nil, 72, nil, 70, 71, 73, 32, 33, 77, 78, + nil, nil, nil, nil, nil, 82, 30, 29, 111, 110, + 112, 113, nil, nil, 21, nil, nil, nil, nil, nil, + 10, 50, nil, 12, 115, 114, 116, 105, 61, 107, + 106, 108, nil, 109, 117, 118, nil, 101, 102, 46, + 47, 45, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 42, nil, nil, 35, nil, nil, 63, 64, nil, + nil, 65, nil, 37, nil, nil, nil, 49, nil, nil, + nil, nil, nil, nil, nil, nil, 22, nil, nil, nil, + nil, 99, 87, 90, 91, nil, 92, 94, 93, 95, + nil, nil, nil, nil, 88, 98, nil, nil, nil, 79, + 80, 81, 67, 62, 89, 103, 104, 68, 69, 43, + 44, nil, 72, nil, 70, 71, 73, 32, 33, 77, + 78, nil, nil, nil, nil, nil, 82, 30, 29, 111, + 110, 112, 113, nil, nil, 241, nil, nil, nil, nil, + nil, nil, 50, nil, nil, 115, 114, 116, 105, 61, + 107, 106, 108, nil, 109, 117, 118, nil, 101, 102, + 46, 47, 45, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 234, nil, nil, 240, nil, nil, 63, 64, + nil, nil, 65, nil, 419, nil, nil, nil, 49, nil, + nil, nil, nil, nil, nil, nil, nil, 239, nil, nil, + nil, nil, 99, 87, 90, 91, nil, 92, 94, 93, + 95, nil, nil, nil, nil, 88, 98, nil, nil, nil, + 79, 80, 81, 67, 62, 89, 103, 104, 68, 69, + 43, 44, nil, 72, nil, 70, 71, 73, 32, 33, + 77, 78, nil, nil, nil, nil, nil, 82, 30, 29, + 111, 110, 112, 113, nil, nil, 241, nil, nil, nil, + nil, nil, nil, 50, nil, nil, 115, 114, 116, 105, + 61, 107, 106, 108, nil, 109, 117, 118, nil, 101, + 102, 46, 47, 45, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 234, nil, nil, 240, nil, nil, 63, + 64, nil, nil, 65, nil, 419, nil, nil, nil, 49, + nil, nil, nil, nil, nil, nil, nil, nil, 239, nil, + nil, nil, nil, 99, 87, 90, 91, nil, 92, 94, + 93, 95, nil, nil, nil, nil, 88, 98, nil, nil, + nil, 79, 80, 81, 67, 62, 89, 103, 104, 68, + 69, 43, 44, nil, 72, nil, 70, 71, 73, 32, + 33, 77, 78, nil, nil, nil, nil, nil, 82, 30, + 29, 111, 110, 112, 113, nil, nil, 21, nil, nil, + nil, nil, nil, nil, 50, nil, nil, 115, 114, 116, + 105, 61, 107, 106, 108, nil, 109, 117, 118, nil, + 101, 102, 46, 47, 45, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 234, nil, nil, 240, nil, nil, + 63, 64, nil, nil, 65, nil, nil, nil, nil, nil, + 49, nil, nil, nil, nil, nil, nil, nil, nil, 22, + nil, nil, nil, nil, 99, 87, 90, 91, nil, 92, + 94, 93, 95, nil, nil, nil, nil, 88, 98, nil, + nil, nil, 79, 80, 81, 67, 62, 89, 103, 104, + 68, 69, 43, 44, nil, 72, nil, 70, 71, 73, + 32, 33, 77, 78, nil, nil, nil, nil, nil, 82, + 30, 29, 111, 110, 112, 113, nil, nil, 21, nil, + nil, nil, nil, nil, nil, 50, nil, nil, 115, 114, + 116, 105, 61, 107, 106, 108, nil, 109, 117, 118, + nil, 101, 102, 46, 47, 45, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 234, nil, nil, 240, nil, + nil, 63, 64, nil, nil, 65, nil, nil, nil, nil, + nil, 49, nil, nil, nil, nil, nil, nil, nil, nil, + 22, nil, nil, nil, nil, 99, 87, 90, 91, nil, + 92, 94, 93, 95, nil, nil, nil, nil, 88, 98, + nil, nil, nil, 79, 80, 81, 67, 62, 89, 103, + 104, 68, 69, 43, 44, nil, 72, nil, 70, 71, + 73, 32, 33, 77, 78, nil, nil, nil, nil, nil, + 82, 30, 29, 111, 110, 112, 113, nil, nil, 241, + nil, nil, nil, nil, nil, nil, 50, nil, nil, 115, + 114, 116, 105, 61, 107, 106, 108, nil, 109, 117, + 118, nil, 101, 102, 46, 47, 45, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 234, nil, nil, 240, + nil, nil, 63, 64, nil, nil, 65, nil, nil, nil, + nil, nil, 49, nil, nil, nil, nil, nil, nil, nil, + nil, 239, nil, nil, nil, nil, 99, 87, 90, 91, + nil, 92, 94, 93, 95, nil, nil, nil, nil, 88, + 98, nil, nil, nil, 79, 80, 81, 67, 62, 89, + 103, 104, 68, 69, 43, 44, nil, 72, nil, 70, + 71, 73, 32, 33, 77, 78, nil, nil, nil, nil, + nil, 82, 30, 29, 111, 110, 112, 113, nil, nil, + 241, nil, nil, nil, nil, nil, nil, 50, nil, nil, + 115, 114, 116, 105, 61, 107, 106, 108, 297, 109, + 117, 118, nil, 101, 102, 46, 47, 45, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 234, nil, nil, + 240, nil, nil, 63, 64, nil, nil, 65, nil, 294, + nil, 292, nil, 49, nil, nil, 298, nil, nil, nil, + nil, nil, 239, nil, nil, nil, nil, 99, 295, 90, + 91, nil, 92, 94, 93, 95, nil, nil, nil, nil, + 88, 98, nil, nil, nil, 79, 80, 81, 67, 62, + 89, 103, 104, 68, 69, 43, 44, nil, 72, nil, + 70, 71, 73, 32, 33, 77, 78, nil, nil, nil, + nil, nil, 82, 30, 29, 111, 110, 112, 113, nil, + nil, 241, nil, nil, nil, nil, nil, nil, 50, nil, + nil, 115, 114, 116, 105, 61, 107, 106, 108, nil, + 109, 117, 118, nil, 101, 102, 46, 47, 45, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 234, nil, + nil, 240, nil, nil, 63, 64, nil, nil, 65, nil, + nil, nil, nil, nil, 49, nil, nil, nil, nil, nil, + nil, nil, nil, 239, nil, nil, nil, nil, 99, 87, + 90, 91, nil, 92, 94, 93, 95, nil, nil, nil, + nil, 88, 98, nil, nil, nil, 79, 80, 81, 67, + 62, 89, 103, 104, 68, 69, 43, 44, nil, 72, + nil, 70, 71, 73, 32, 33, 77, 78, nil, nil, + nil, nil, nil, 82, 30, 29, 111, 110, 112, 113, + nil, nil, 21, nil, nil, nil, nil, nil, nil, 50, + nil, nil, 115, 114, 116, 105, 61, 107, 106, 108, + nil, 109, 117, 118, nil, 101, 102, 46, 47, 45, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 234, + nil, nil, 240, nil, nil, 63, 64, nil, nil, 65, + nil, nil, nil, nil, nil, 49, nil, nil, nil, nil, + nil, nil, nil, nil, 22, nil, nil, nil, nil, 99, + 87, 90, 91, nil, 92, 94, 93, 95, nil, nil, + nil, nil, 88, 98, nil, nil, nil, 79, 80, 81, + 67, 62, 89, 103, 104, 68, 69, 43, 44, nil, + 72, nil, 70, 71, 73, 32, 33, 77, 78, nil, + nil, nil, nil, nil, 82, 30, 29, 111, 110, 112, + 113, nil, nil, 21, nil, nil, nil, nil, nil, nil, + 50, nil, nil, 115, 114, 116, 105, 61, 107, 106, + 108, nil, 109, 117, 118, nil, 101, 102, 46, 47, + 45, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 234, nil, nil, 240, nil, nil, 63, 64, nil, nil, + 65, nil, nil, nil, nil, nil, 49, nil, nil, nil, + nil, nil, nil, nil, nil, 22, nil, nil, nil, nil, + 99, 87, 90, 91, nil, 92, 94, 93, 95, nil, + nil, nil, nil, 88, 98, 229, nil, nil, 79, 80, + 81, 67, 62, 89, 103, 104, 68, 69, 43, 44, + nil, 72, nil, 70, 71, 73, 322, 323, 77, 78, + nil, nil, nil, nil, nil, 82, 319, 325, 111, 110, + 112, 113, nil, nil, 241, nil, nil, nil, nil, nil, + nil, 50, nil, nil, 115, 114, 116, 105, 61, 107, + 106, 108, nil, 109, 117, 118, nil, 101, 102, 46, + 47, 45, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 234, nil, nil, 240, nil, nil, 63, 64, nil, + nil, 65, nil, nil, nil, nil, nil, 49, nil, nil, + nil, nil, nil, nil, nil, nil, 239, nil, nil, nil, + nil, 99, 87, 90, 91, nil, 92, 94, 93, 95, + nil, nil, nil, nil, 88, 98, nil, nil, nil, 79, + 80, 81, 67, 62, 89, 103, 104, 68, 69, 43, + 44, nil, 72, nil, 70, 71, 73, 322, 323, 77, + 78, nil, nil, nil, nil, nil, 82, 319, 325, 111, + 110, 112, 113, nil, nil, 241, nil, nil, nil, nil, + nil, nil, 50, nil, nil, 115, 114, 116, 105, 61, + 107, 106, 108, nil, 109, 117, 118, nil, 101, 102, + 46, 47, 45, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 234, nil, nil, 240, nil, nil, 63, 64, + nil, nil, 65, nil, nil, nil, nil, nil, 49, nil, + nil, nil, nil, nil, nil, nil, nil, 239, nil, nil, + nil, nil, 99, 87, 90, 91, nil, 92, 94, 93, + 95, nil, nil, nil, nil, 88, 98, nil, nil, nil, + 79, 80, 81, 67, 62, 89, 103, 104, 68, 69, + 43, 44, nil, 72, nil, 70, 71, 73, 322, 323, + 77, 78, nil, nil, nil, nil, nil, 82, 319, 325, + 111, 110, 112, 113, nil, nil, 241, nil, nil, nil, + nil, nil, nil, 50, nil, nil, 115, 114, 116, 105, + 61, 107, 106, 108, nil, 109, 117, 118, nil, 101, + 102, 46, 47, 45, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 234, nil, nil, 240, nil, nil, 63, + 64, nil, nil, 65, nil, nil, nil, nil, nil, 49, + nil, nil, nil, nil, nil, nil, nil, nil, 239, nil, + nil, nil, nil, 99, 87, 90, 91, nil, 92, 94, + 93, 95, nil, nil, nil, nil, 88, 98, nil, nil, + nil, 79, 80, 81, 67, 62, 89, 103, 104, 68, + 69, 43, 44, nil, 72, nil, 70, 71, 73, 322, + 323, 77, 78, nil, nil, nil, nil, nil, 82, 319, + 325, 111, 110, 112, 113, nil, nil, 241, nil, nil, + nil, nil, nil, nil, 50, nil, nil, 115, 114, 116, + 105, 61, 107, 106, 108, nil, 109, 117, 118, nil, + 101, 102, 46, 47, 45, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 234, nil, nil, 240, nil, nil, + 63, 64, nil, nil, 65, nil, nil, nil, nil, nil, + 49, nil, nil, nil, nil, nil, nil, nil, nil, 239, + nil, nil, nil, nil, 99, 87, 90, 91, nil, 92, + 94, 93, 95, nil, nil, nil, nil, 88, 98, nil, + nil, nil, 79, 80, 81, 67, 62, 89, 103, 104, + 68, 69, 43, 44, nil, 72, nil, 70, 71, 73, + 322, 323, 77, 78, nil, nil, nil, nil, nil, 82, + 319, 325, 111, 110, 112, 113, nil, nil, 241, nil, + nil, nil, nil, nil, nil, 50, nil, nil, 115, 114, + 116, 105, 61, 107, 106, 108, nil, 109, 117, 118, + nil, 101, 102, 46, 47, 45, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 234, nil, nil, 240, nil, + nil, 63, 64, nil, nil, 65, nil, nil, nil, nil, + nil, 49, nil, nil, nil, nil, nil, nil, nil, nil, + 239, nil, nil, nil, nil, 99, 87, 90, 91, nil, + 92, 94, 93, 95, nil, nil, nil, nil, 88, 98, + nil, nil, nil, 79, 80, 81, 67, 62, 89, 103, + 104, 68, 69, 43, 44, nil, 72, nil, 70, 71, + 73, 322, 323, 77, 78, nil, nil, nil, nil, nil, + 82, 319, 325, 111, 110, 112, 113, nil, nil, 241, + nil, nil, nil, nil, nil, nil, 50, nil, nil, 115, + 114, 116, 105, 61, 107, 106, 108, nil, 109, 117, + 118, nil, 101, 102, 46, 47, 45, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 234, nil, nil, 240, + nil, nil, 63, 64, nil, nil, 65, nil, nil, nil, + nil, nil, 49, nil, nil, nil, nil, nil, nil, nil, + nil, 239, nil, nil, nil, nil, 99, 87, 90, 91, + nil, 92, 94, 93, 95, nil, nil, nil, nil, 88, + 98, nil, nil, nil, 79, 80, 81, 67, 62, 89, + 103, 104, 68, 69, 43, 44, nil, 72, nil, 70, + 71, 73, 322, 323, 77, 78, nil, nil, nil, nil, + nil, 82, 319, 325, 111, 110, 112, 113, nil, nil, + 241, nil, nil, nil, nil, nil, nil, 50, nil, nil, + 115, 114, 116, 105, 61, 107, 106, 108, nil, 109, + 117, 118, nil, 101, 102, 46, 47, 45, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 234, nil, nil, + 240, nil, nil, 63, 64, nil, nil, 65, nil, nil, + nil, nil, nil, 49, nil, nil, nil, nil, nil, nil, + nil, nil, 239, nil, nil, nil, nil, 99, 87, 90, + 91, nil, 92, 94, 93, 95, nil, nil, nil, nil, + 88, 98, nil, nil, nil, 79, 80, 81, 67, 62, + 89, 103, 104, 68, 69, 43, 44, nil, 72, nil, + 70, 71, 73, 322, 323, 77, 78, nil, nil, nil, + nil, nil, 82, 319, 325, 111, 110, 112, 113, nil, + nil, 241, nil, nil, nil, nil, nil, nil, 50, nil, + nil, 115, 114, 116, 105, 61, 107, 106, 108, nil, + 109, 117, 118, nil, 101, 102, 46, 47, 45, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 234, nil, + nil, 240, nil, nil, 63, 64, nil, nil, 65, nil, + nil, nil, nil, nil, 49, nil, nil, nil, nil, nil, + nil, nil, nil, 239, nil, nil, nil, nil, 99, 87, + 90, 91, nil, 92, 94, 93, 95, nil, nil, nil, + nil, 88, 98, nil, nil, nil, 79, 80, 81, 67, + 62, 89, 103, 104, 68, 69, 43, 44, nil, 72, + nil, 70, 71, 73, 322, 323, 77, 78, nil, nil, + nil, nil, nil, 82, 319, 325, 111, 110, 112, 113, + nil, nil, 241, nil, nil, nil, nil, nil, nil, 50, + nil, nil, 115, 114, 116, 105, 61, 107, 106, 108, + nil, 109, 117, 118, nil, 101, 102, 46, 47, 45, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 234, + nil, nil, 240, nil, nil, 63, 64, nil, nil, 65, + nil, nil, nil, nil, nil, 49, nil, nil, nil, nil, + nil, nil, nil, nil, 239, nil, nil, nil, nil, 99, + 87, 90, 91, nil, 92, 94, 93, 95, nil, nil, + nil, nil, 88, 98, nil, nil, nil, 79, 80, 81, + 67, 62, 89, 103, 104, 68, 69, 43, 44, nil, + 72, nil, 70, 71, 73, 322, 323, 77, 78, nil, + nil, nil, nil, nil, 82, 319, 325, 111, 110, 112, + 113, nil, nil, 241, nil, nil, nil, nil, nil, nil, + 50, nil, nil, 115, 114, 116, 105, 61, 107, 106, + 108, nil, 109, 117, 118, nil, 101, 102, 46, 47, + 45, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 234, nil, nil, 240, nil, nil, 63, 64, nil, nil, + 65, nil, nil, nil, nil, nil, 49, nil, nil, nil, + nil, nil, nil, nil, nil, 239, nil, nil, nil, nil, + 99, 87, 90, 91, nil, 92, 94, 93, 95, nil, + nil, nil, nil, 88, 98, nil, nil, nil, 79, 80, + 81, 67, 62, 89, 103, 104, 68, 69, 43, 44, + nil, 72, nil, 70, 71, 73, 322, 323, 77, 78, + nil, nil, nil, nil, nil, 82, 319, 325, 111, 110, + 112, 113, nil, nil, 241, nil, nil, nil, nil, nil, + nil, 50, nil, nil, 115, 114, 116, 105, 61, 107, + 106, 108, nil, 109, 117, 118, nil, 101, 102, 46, + 47, 45, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 234, nil, nil, 240, nil, nil, 63, 64, nil, + nil, 65, nil, nil, nil, nil, nil, 49, nil, nil, + nil, nil, nil, nil, nil, nil, 239, nil, nil, nil, + nil, 99, 87, 90, 91, nil, 92, 94, 93, 95, + nil, nil, nil, nil, 88, 98, nil, nil, nil, 79, + 80, 81, 67, 62, 89, 103, 104, 68, 69, 43, + 44, nil, 72, nil, 70, 71, 73, 322, 323, 77, + 78, nil, nil, nil, nil, nil, 82, 319, 325, 111, + 110, 112, 113, nil, nil, 241, nil, nil, nil, nil, + nil, nil, 50, nil, nil, 115, 114, 116, 105, 61, + 107, 106, 108, nil, 109, 117, 118, nil, 101, 102, + 46, 47, 45, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 234, nil, nil, 240, nil, nil, 63, 64, + nil, nil, 65, nil, nil, nil, nil, nil, 49, nil, + nil, nil, nil, nil, nil, nil, nil, 239, nil, nil, + nil, nil, 99, 87, 90, 91, nil, 92, 94, 93, + 95, nil, nil, nil, nil, 88, 98, nil, nil, nil, + 79, 80, 81, 67, 62, 89, 103, 104, 68, 69, + 43, 44, nil, 72, nil, 70, 71, 73, 322, 323, + 77, 78, nil, nil, nil, nil, nil, 82, 319, 325, + 111, 110, 112, 113, nil, nil, 241, nil, nil, nil, + nil, nil, nil, 50, nil, nil, 115, 114, 116, 105, + 61, 107, 106, 108, nil, 109, 117, 118, nil, 101, + 102, 46, 47, 45, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 234, nil, nil, 240, nil, nil, 63, + 64, nil, nil, 65, nil, nil, nil, nil, nil, 49, + nil, nil, nil, nil, nil, nil, nil, nil, 239, nil, + nil, nil, nil, 99, 87, 90, 91, nil, 92, 94, + 93, 95, nil, nil, nil, nil, 88, 98, nil, nil, + nil, 79, 80, 81, 67, 62, 89, 103, 104, 68, + 69, 43, 44, nil, 72, nil, 70, 71, 73, 322, + 323, 77, 78, nil, nil, nil, nil, nil, 82, 319, + 325, 111, 110, 112, 113, nil, nil, 241, nil, nil, + nil, nil, nil, nil, 50, nil, nil, 115, 114, 116, + 105, 61, 107, 106, 108, nil, 109, 117, 118, nil, + 101, 102, 46, 47, 45, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 234, nil, nil, 240, nil, nil, + 63, 64, nil, nil, 65, nil, nil, nil, nil, nil, + 49, nil, nil, nil, nil, nil, nil, nil, nil, 239, + nil, nil, nil, nil, 99, 87, 90, 91, nil, 92, + 94, 93, 95, nil, nil, nil, nil, 88, 98, nil, + nil, nil, 79, 80, 81, 67, 62, 89, 103, 104, + 68, 69, 43, 44, nil, 72, nil, 70, 71, 73, + 322, 323, 77, 78, nil, nil, nil, nil, nil, 82, + 319, 325, 111, 110, 112, 113, nil, nil, 241, nil, + nil, nil, nil, nil, nil, 50, nil, nil, 115, 114, + 116, 105, 61, 107, 106, 108, nil, 109, 117, 118, + nil, 101, 102, 46, 47, 45, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 234, nil, nil, 240, nil, + nil, 63, 64, nil, nil, 65, nil, nil, nil, nil, + nil, 49, nil, nil, nil, nil, nil, nil, nil, nil, + 239, nil, nil, nil, nil, 99, 87, 90, 91, nil, + 92, 94, 93, 95, nil, nil, nil, nil, 88, 98, + nil, nil, nil, 79, 80, 81, 67, 62, 89, 103, + 104, 68, 69, 43, 44, nil, 72, nil, 70, 71, + 73, 322, 323, 77, 78, nil, nil, nil, nil, nil, + 82, 319, 325, 111, 110, 112, 113, nil, nil, 241, + nil, nil, nil, nil, nil, nil, 50, nil, nil, 115, + 114, 116, 105, 61, 107, 106, 108, nil, 109, 117, + 118, nil, 101, 102, 46, 47, 45, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 234, nil, nil, 240, + nil, nil, 63, 64, nil, nil, 65, nil, nil, nil, + nil, nil, 49, nil, nil, nil, nil, nil, nil, nil, + nil, 239, nil, nil, nil, nil, 99, 87, 90, 91, + nil, 92, 94, 93, 95, nil, nil, nil, nil, 88, + 98, nil, nil, nil, 79, 80, 81, 67, 62, 89, + 103, 104, 68, 69, 43, 44, nil, 72, nil, 70, + 71, 73, 322, 323, 77, 78, nil, nil, nil, nil, + nil, 82, 319, 325, 111, 110, 112, 113, nil, nil, + 241, nil, nil, nil, nil, nil, nil, 50, nil, nil, + 115, 114, 116, 105, 61, 107, 106, 108, nil, 109, + 117, 118, nil, 101, 102, 46, 47, 45, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 234, nil, nil, + 240, nil, nil, 63, 64, nil, nil, 65, nil, nil, + nil, nil, nil, 49, nil, nil, nil, nil, nil, nil, + nil, nil, 239, nil, nil, nil, nil, 99, 87, 90, + 91, nil, 92, 94, 93, 95, nil, nil, nil, nil, + 88, 98, nil, nil, nil, 79, 80, 81, 67, 62, + 89, 103, 104, 68, 69, 43, 44, nil, 72, nil, + 70, 71, 73, 322, 323, 77, 78, nil, nil, nil, + nil, nil, 82, 319, 325, 111, 110, 112, 113, nil, + nil, 241, nil, nil, nil, nil, nil, nil, 50, nil, + nil, 115, 114, 116, 105, 61, 107, 106, 108, nil, + 109, 117, 118, nil, 101, 102, 46, 47, 45, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 234, nil, + nil, 240, nil, nil, 63, 64, nil, nil, 65, nil, + nil, nil, nil, nil, 49, nil, nil, nil, nil, nil, + nil, nil, nil, 239, nil, nil, nil, nil, 99, 87, + 90, 91, nil, 92, 94, 93, 95, nil, nil, nil, + nil, 88, 98, nil, nil, nil, 79, 80, 81, 67, + 62, 89, 103, 104, 68, 69, 43, 44, nil, 72, + nil, 70, 71, 73, 322, 323, 77, 78, nil, nil, + nil, nil, nil, 82, 319, 325, 111, 110, 112, 113, + nil, nil, 241, nil, nil, nil, nil, nil, nil, 50, + nil, nil, 115, 114, 116, 105, 61, 107, 106, 108, + nil, 109, 117, 118, nil, 101, 102, 46, 47, 45, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 234, + nil, nil, 240, nil, nil, 63, 64, nil, nil, 65, + nil, nil, nil, nil, nil, 49, nil, nil, nil, nil, + nil, nil, nil, nil, 239, nil, nil, nil, nil, 99, + 87, 90, 91, nil, 92, 94, 93, 95, nil, nil, + nil, nil, 88, 98, nil, nil, nil, 79, 80, 81, + 67, 62, 89, 103, 104, 68, 69, 43, 44, nil, + 72, nil, 70, 71, 73, 322, 323, 77, 78, nil, + nil, nil, nil, nil, 82, 319, 325, 111, 110, 112, + 113, nil, nil, 241, nil, nil, nil, nil, nil, nil, + 50, nil, nil, 115, 114, 116, 105, 61, 107, 106, + 108, nil, 109, 117, 118, nil, 101, 102, 46, 47, + 45, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 234, nil, nil, 240, nil, nil, 63, 64, nil, nil, + 65, nil, nil, nil, nil, nil, 49, nil, nil, nil, + nil, nil, nil, nil, nil, 239, nil, nil, nil, nil, + 99, 87, 90, 91, nil, 92, 94, 93, 95, nil, + nil, nil, nil, 88, 98, nil, nil, nil, 79, 80, + 81, 67, 62, 89, 103, 104, 68, 69, 43, 44, + nil, 72, nil, 70, 71, 73, 322, 323, 77, 78, + nil, nil, nil, nil, nil, 82, 319, 325, 111, 110, + 112, 113, nil, nil, 241, nil, nil, nil, nil, nil, + nil, 50, nil, nil, 115, 114, 116, 105, 61, 107, + 106, 108, nil, 109, 117, 118, nil, 101, 102, 46, + 47, 45, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 234, nil, nil, 240, nil, nil, 63, 64, nil, + nil, 65, nil, nil, nil, nil, nil, 49, nil, nil, + nil, nil, nil, nil, nil, nil, 239, nil, nil, nil, + nil, 99, 87, 90, 91, nil, 92, 94, 93, 95, + nil, nil, nil, nil, 88, 98, nil, nil, nil, 79, + 80, 81, 67, 62, 89, 103, 104, 68, 69, 43, + 44, nil, 72, nil, 70, 71, 73, 322, 323, 77, + 78, nil, nil, nil, nil, nil, 82, 319, 325, 111, + 110, 112, 113, nil, nil, 241, nil, nil, nil, nil, + nil, nil, 50, nil, nil, 115, 114, 116, 105, 61, + 107, 106, 108, nil, 109, 117, 118, nil, 101, 102, + 46, 47, 45, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 234, nil, nil, 240, nil, nil, 63, 64, + nil, nil, 65, nil, nil, nil, nil, nil, 49, nil, + nil, nil, nil, nil, nil, nil, nil, 239, nil, nil, + nil, nil, 99, 87, 90, 91, nil, 92, 94, 93, + 95, nil, nil, nil, nil, 88, 98, nil, nil, nil, + 79, 80, 81, 67, 62, 89, 103, 104, 68, 69, + 43, 44, nil, 72, nil, 70, 71, 73, 322, 323, + 77, 78, nil, nil, nil, nil, nil, 82, 319, 325, + 111, 110, 112, 113, nil, nil, 241, nil, nil, nil, + nil, nil, nil, 50, nil, nil, 115, 114, 116, 105, + 61, 107, 106, 108, nil, 109, 117, 118, nil, 101, + 102, 46, 47, 45, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 234, nil, nil, 240, nil, nil, 63, + 64, nil, nil, 65, nil, nil, nil, nil, nil, 49, + nil, nil, nil, nil, nil, nil, nil, nil, 239, nil, + nil, nil, nil, 99, 87, 90, 91, nil, 92, 94, + 93, 95, nil, nil, nil, nil, 88, 98, nil, nil, + nil, 79, 80, 81, 67, 62, 89, 103, 104, 68, + 69, 43, 44, nil, 72, nil, 70, 71, 73, 322, + 323, 77, 78, nil, nil, nil, nil, nil, 82, 319, + 325, 111, 110, 112, 113, nil, nil, 241, nil, nil, + nil, nil, nil, nil, 50, nil, nil, 115, 114, 116, + 105, 61, 107, 106, 108, nil, 109, 117, 118, nil, + 101, 102, 46, 47, 45, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 234, nil, nil, 240, nil, nil, + 63, 64, nil, nil, 65, nil, nil, nil, nil, nil, + 49, nil, nil, nil, nil, nil, nil, nil, nil, 239, + nil, nil, nil, nil, 99, 87, 90, 91, nil, 92, + 94, 93, 95, nil, nil, nil, nil, 88, 98, nil, + nil, nil, 79, 80, 81, 67, 62, 89, 103, 104, + 68, 69, 43, 44, nil, 72, nil, 70, 71, 73, + 32, 33, 77, 78, nil, nil, nil, nil, nil, 82, + 30, 29, 111, 110, 112, 113, nil, nil, 241, nil, + nil, nil, nil, nil, nil, 50, nil, nil, 115, 114, + 116, 105, 61, 107, 106, 108, 297, 109, 117, 118, + nil, 101, 102, 46, 47, 45, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 234, nil, nil, 240, nil, + nil, 63, 64, nil, nil, 65, nil, 294, nil, 292, + nil, 49, nil, nil, 298, nil, nil, nil, nil, nil, + 239, nil, nil, nil, nil, 99, 295, 90, 91, nil, + 92, 94, 93, 95, nil, nil, nil, nil, 88, 98, + nil, nil, nil, 79, 80, 81, 67, 62, 89, 103, + 104, 68, 69, 43, 497, nil, 72, nil, 70, 71, + 73, 32, 33, 77, 78, nil, nil, nil, nil, nil, + 82, 30, 29, 111, 110, 112, 113, nil, nil, 241, + nil, nil, nil, nil, nil, nil, 50, nil, nil, 115, + 114, 116, 105, 61, 107, 106, 108, 297, 109, 117, + 118, nil, 101, 102, 46, 47, 45, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 234, nil, nil, 240, + nil, nil, 63, 64, nil, nil, 65, nil, 294, nil, + 292, nil, 49, nil, nil, 298, nil, nil, nil, nil, + nil, 239, nil, nil, nil, nil, 99, 295, 90, 91, + nil, 92, 94, 93, 95, nil, nil, nil, nil, 88, + 98, nil, nil, nil, 79, 80, 81, 67, 62, 89, + 103, 104, 68, 69, 43, 44, nil, 72, nil, 70, + 71, 73, 32, 33, 77, 78, nil, nil, nil, nil, + nil, 82, 30, 29, 111, 110, 112, 113, nil, nil, + 241, nil, nil, nil, nil, nil, nil, 50, nil, nil, + 115, 114, 116, 105, 61, 107, 106, 108, 297, 109, + 117, 118, nil, 101, 102, 46, 47, 45, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 234, nil, nil, + 240, nil, nil, 63, 64, nil, nil, 65, nil, 294, + nil, 292, nil, 49, nil, nil, 298, nil, nil, nil, + nil, nil, 239, nil, nil, nil, nil, 99, 295, 90, + 91, nil, 92, 94, 93, 95, nil, nil, nil, nil, + 88, 98, 229, nil, nil, 79, 80, 81, 67, 62, + 89, 103, 104, 68, 69, 43, 44, nil, 72, nil, + 70, 71, 73, 322, 323, 77, 78, nil, nil, nil, + nil, nil, 82, 319, 325, 111, 110, 112, 113, nil, + nil, 241, nil, nil, nil, nil, nil, nil, 50, nil, + nil, 115, 114, 116, 105, 61, 107, 106, 108, nil, + 109, 117, 118, nil, 101, 102, 46, 47, 45, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 234, nil, + nil, 240, nil, nil, 63, 64, nil, nil, 65, nil, + nil, nil, nil, nil, 49, nil, nil, nil, nil, nil, + nil, nil, nil, 239, nil, nil, nil, nil, 99, 87, + 90, 91, nil, 92, 94, 93, 95, nil, nil, nil, + nil, 88, 98, nil, nil, nil, 79, 80, 81, 67, + 62, 89, 103, 104, 68, 69, 43, 44, nil, 72, + nil, 70, 71, 73, 322, 323, 77, 78, nil, nil, + nil, nil, nil, 82, 319, 325, 111, 110, 112, 113, + nil, nil, 241, nil, nil, nil, nil, nil, nil, 50, + nil, nil, 115, 114, 116, 105, 61, 107, 106, 108, + nil, 109, 117, 118, nil, 101, 102, 46, 47, 45, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 234, + nil, nil, 240, nil, nil, 63, 64, nil, nil, 65, + nil, nil, nil, nil, nil, 49, nil, nil, nil, nil, + nil, nil, nil, nil, 239, nil, nil, nil, nil, 99, + 87, 90, 91, nil, 92, 94, 93, 95, nil, nil, + nil, nil, 88, 98, nil, nil, nil, 79, 80, 81, + 67, 62, 89, 103, 104, 68, 69, 43, 44, nil, + 72, nil, 70, 71, 73, 322, 323, 77, 78, nil, + nil, nil, nil, nil, 82, 319, 325, 111, 110, 112, + 113, nil, nil, 241, nil, nil, nil, nil, nil, nil, + 50, nil, nil, 115, 114, 116, 105, 61, 107, 106, + 108, nil, 109, 117, 118, nil, 101, 102, 46, 47, + 45, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 234, nil, nil, 240, nil, nil, 63, 64, nil, nil, + 65, nil, nil, nil, nil, nil, 49, nil, nil, nil, + nil, nil, nil, nil, nil, 239, nil, nil, nil, nil, + 99, 87, 90, 91, nil, 92, 94, 93, 95, nil, + nil, nil, nil, 88, 98, nil, nil, nil, 79, 80, + 81, 67, 62, 89, 103, 104, 68, 69, 43, 44, + nil, 72, nil, 70, 71, 73, 322, 323, 77, 78, + nil, nil, nil, nil, nil, 82, 319, 325, 111, 110, + 112, 113, nil, nil, 241, nil, nil, nil, nil, nil, + nil, 50, nil, nil, 115, 114, 116, 105, 61, 107, + 106, 108, nil, 109, 117, 118, nil, 101, 102, 46, + 47, 45, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 234, nil, nil, 240, nil, nil, 63, 64, nil, + nil, 65, nil, nil, nil, nil, nil, 49, nil, nil, + nil, nil, nil, nil, nil, nil, 239, nil, nil, nil, + nil, 99, 87, 90, 91, nil, 92, 94, 93, 95, + nil, nil, nil, nil, 88, 98, nil, nil, nil, nil, + nil, nil, 67, nil, 89, 103, 104, nil, nil, 43, + 44, 79, 80, 81, 11, 62, nil, nil, nil, 68, + 69, nil, nil, nil, 72, nil, 70, 71, 73, 32, + 33, 77, 78, nil, nil, nil, nil, nil, 82, 30, + 29, 111, 110, 112, 113, nil, nil, 21, nil, nil, + nil, nil, nil, 10, 50, nil, 12, 115, 114, 116, + 105, 61, 107, 106, 108, nil, 109, 117, 118, nil, + 101, 102, 46, 47, 45, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 42, nil, nil, 35, nil, nil, + 63, 64, nil, nil, 65, nil, 37, nil, nil, nil, + 49, nil, nil, nil, nil, nil, nil, nil, nil, 22, + nil, nil, nil, nil, 99, 87, 90, 91, nil, 92, + 94, 93, 95, nil, nil, nil, nil, 88, 98, nil, + nil, nil, 79, 80, 81, 67, 62, 89, 103, 104, + 68, 69, 43, 44, nil, 72, nil, 70, 71, 73, + 322, 323, 77, 78, nil, nil, nil, nil, nil, 82, + 319, 325, 111, 110, 112, 113, nil, nil, 241, nil, + nil, nil, nil, nil, nil, 50, nil, nil, 115, 114, + 116, 105, 61, 107, 106, 108, nil, 109, 117, 118, + nil, 101, 102, 46, 47, 45, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 234, nil, nil, 240, nil, + nil, 63, 64, nil, nil, 65, nil, nil, nil, nil, + nil, 49, nil, nil, nil, nil, nil, nil, nil, nil, + 239, nil, nil, nil, nil, 99, 87, 90, 91, nil, + 92, 94, 93, 95, nil, nil, nil, nil, 88, 98, + nil, nil, nil, 79, 80, 81, 67, 62, 89, 103, + 104, 68, 69, 43, 44, nil, 72, nil, 70, 71, + 73, 322, 323, 77, 78, nil, nil, nil, nil, nil, + 82, 319, 325, 111, 110, 112, 113, nil, nil, 241, + nil, nil, nil, nil, nil, nil, 50, nil, nil, 115, + 114, 116, 105, 61, 107, 106, 108, nil, 109, 117, + 118, nil, 101, 102, 46, 47, 45, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 234, nil, nil, 240, + 542, nil, 63, 64, nil, nil, 65, nil, nil, nil, + nil, nil, 49, nil, nil, nil, nil, nil, nil, nil, + nil, 239, nil, nil, nil, nil, 99, 87, 90, 91, + nil, 92, 94, 93, 95, nil, nil, nil, nil, 88, + 98, nil, nil, nil, 79, 80, 81, 67, 62, 89, + 103, 104, 68, 69, 43, 44, nil, 72, nil, 70, + 71, 73, 32, 33, 77, 78, nil, nil, nil, nil, + nil, 82, 30, 29, 111, 110, 112, 113, nil, nil, + 21, nil, nil, nil, nil, nil, nil, 50, nil, nil, + 115, 114, 116, 105, 61, 107, 106, 108, nil, 109, + 117, 118, nil, 101, 102, 46, 47, 45, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 234, nil, nil, + 240, nil, nil, 63, 64, nil, nil, 65, nil, nil, + nil, nil, nil, 49, nil, nil, nil, nil, nil, nil, + nil, nil, 22, nil, nil, nil, nil, 99, 87, 90, + 91, nil, 92, 94, 93, 95, nil, nil, nil, nil, + 88, 98, nil, nil, nil, 79, 80, 81, 67, 62, + 89, 103, 104, 68, 69, 43, 44, nil, 72, nil, + 70, 71, 73, 32, 33, 77, 78, nil, nil, nil, + nil, nil, 82, 30, 29, 111, 110, 112, 113, nil, + nil, 21, nil, nil, nil, nil, nil, nil, 50, nil, + nil, 115, 114, 116, 105, 61, 107, 106, 108, nil, + 109, 117, 118, nil, 101, 102, 46, 47, 45, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 234, nil, + nil, 240, nil, nil, 63, 64, nil, nil, 65, nil, + nil, nil, nil, nil, 49, nil, nil, nil, nil, nil, + nil, nil, nil, 22, nil, nil, nil, nil, 99, 87, + 90, 91, nil, 92, 94, 93, 95, nil, nil, nil, + nil, 88, 98, nil, nil, nil, 79, 80, 81, 67, + 62, 89, 103, 104, 68, 69, 43, 44, nil, 72, + nil, 70, 71, 73, 32, 33, 77, 78, nil, nil, + nil, nil, nil, 82, 30, 29, 111, 110, 112, 113, + nil, nil, 21, nil, nil, nil, nil, nil, nil, 50, + nil, nil, 115, 114, 116, 105, 61, 107, 106, 108, + nil, 109, 117, 118, nil, 101, 102, 46, 47, 45, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 234, + nil, nil, 240, nil, nil, 63, 64, nil, nil, 65, + nil, nil, nil, nil, nil, 49, nil, nil, nil, nil, + nil, nil, nil, nil, 22, nil, nil, nil, nil, 99, + 87, 90, 91, nil, 92, 94, 93, 95, nil, nil, + nil, nil, 88, 98, nil, nil, nil, 79, 80, 81, + 67, 62, 89, 103, 104, 68, 69, 43, 44, nil, + 72, nil, 70, 71, 73, 322, 323, 77, 78, nil, + nil, nil, nil, nil, 82, 319, 325, 111, 110, 112, + 113, nil, nil, 241, nil, nil, nil, nil, nil, nil, + 50, nil, nil, 115, 114, 116, 105, 61, 107, 106, + 108, nil, 109, 117, 118, nil, 101, 102, 46, 47, + 45, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 234, nil, nil, 240, nil, nil, 63, 64, nil, nil, + 65, nil, nil, nil, nil, nil, 49, nil, nil, nil, + nil, nil, nil, nil, nil, 239, nil, nil, nil, nil, + 99, 87, 90, 91, nil, 92, 94, 93, 95, nil, + nil, nil, nil, 88, 98, nil, nil, nil, nil, nil, + nil, 67, nil, 89, 103, 104, -260, nil, 43, 44, + nil, nil, nil, -260, -260, -260, nil, nil, -260, -260, + -260, nil, -260, nil, nil, nil, nil, nil, nil, nil, + -260, -260, -260, -260, nil, nil, nil, nil, nil, nil, + nil, nil, -260, -260, nil, -260, -260, -260, -260, -260, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, -260, -260, -260, -260, -260, -260, -260, -260, + -260, -260, -260, -260, -260, -260, nil, nil, -260, -260, + -260, nil, nil, -260, nil, 276, -260, nil, nil, -260, + -260, nil, -260, nil, -260, nil, -260, nil, -260, -260, + nil, -260, -260, -260, -260, -260, nil, -260, -260, -260, + 724, nil, 721, 720, 719, 729, 722, nil, nil, nil, + nil, nil, nil, -260, nil, 732, -260, -260, -695, -260, + nil, -260, nil, nil, nil, -695, -695, -695, -260, nil, + -695, -695, -695, nil, -695, nil, nil, 727, nil, nil, + nil, nil, -695, -695, -695, -695, -695, nil, 740, 739, + nil, nil, nil, 733, -695, -695, nil, -695, -695, -695, + -695, -695, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, -695, -695, -695, -695, -695, -695, + -695, -695, -695, -695, -695, -695, -695, -695, nil, nil, + -695, -695, -695, nil, nil, -695, nil, nil, -695, nil, + nil, -695, -695, nil, -695, nil, -695, nil, -695, nil, + -695, -695, nil, -695, -695, -695, -695, -695, nil, -695, + -695, -695, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, -695, nil, nil, -695, -695, + -695, -695, nil, -695, -696, -695, nil, nil, nil, nil, + -695, -696, -696, -696, nil, nil, -696, -696, -696, nil, + -696, nil, nil, nil, nil, nil, nil, nil, -696, -696, + -696, -696, -696, nil, nil, nil, nil, nil, nil, nil, + -696, -696, nil, -696, -696, -696, -696, -696, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + -696, -696, -696, -696, -696, -696, -696, -696, -696, -696, + -696, -696, -696, -696, nil, nil, -696, -696, -696, nil, + nil, -696, nil, nil, -696, nil, nil, -696, -696, nil, + -696, nil, -696, nil, -696, nil, -696, -696, nil, -696, + -696, -696, -696, -696, nil, -696, -696, -696, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, -696, nil, nil, -696, -696, -696, -696, nil, -696, + nil, -696, nil, 79, 80, 81, -696, 62, nil, nil, + nil, 68, 69, nil, nil, nil, 72, nil, 70, 71, + 73, 32, 33, 77, 78, nil, nil, nil, nil, nil, + 82, 30, 29, 111, 110, 112, 113, nil, nil, 241, + nil, nil, nil, nil, nil, nil, 50, nil, nil, 115, + 114, 116, 105, 61, 107, 106, 108, 297, 109, 117, + 118, nil, 101, 102, 46, 47, 45, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 234, nil, nil, 240, + nil, nil, 63, 64, nil, nil, 65, nil, 294, nil, + 292, nil, 49, nil, nil, 298, nil, nil, nil, nil, + nil, 239, nil, nil, nil, nil, 99, 295, 90, 91, + nil, 92, 94, 93, 95, nil, nil, nil, nil, 88, + 98, nil, nil, nil, 79, 80, 81, 67, 62, 89, + 103, 104, 68, 69, 43, 44, nil, 72, nil, 70, + 71, 73, 322, 323, 77, 78, nil, nil, nil, nil, + nil, 82, 319, 325, 111, 110, 112, 113, nil, nil, + 241, nil, nil, nil, nil, nil, nil, 50, nil, nil, + 115, 114, 116, 105, 61, 107, 106, 108, nil, 109, + 117, 118, nil, 101, 102, 46, 47, 45, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 234, nil, nil, + 240, nil, nil, 63, 64, nil, nil, 65, nil, nil, + nil, nil, nil, 49, nil, nil, nil, nil, nil, nil, + nil, nil, 239, nil, nil, nil, nil, 99, 87, 90, + 91, nil, 92, 94, 93, 95, nil, nil, nil, nil, + 88, 98, nil, nil, nil, 79, 80, 81, 67, 62, + 89, 103, 104, 68, 69, 43, 44, nil, 72, nil, + 70, 71, 73, 322, 323, 77, 78, nil, nil, nil, + nil, nil, 82, 319, 325, 111, 110, 112, 113, nil, + nil, 241, nil, nil, nil, nil, nil, nil, 50, nil, + nil, 115, 114, 116, 105, 61, 107, 106, 108, nil, + 109, 117, 118, nil, 101, 102, 46, 47, 45, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 234, nil, + nil, 240, nil, nil, 63, 64, nil, nil, 65, nil, + nil, nil, nil, nil, 49, nil, nil, nil, nil, nil, + nil, nil, nil, 239, nil, nil, nil, nil, 99, 87, + 90, 91, nil, 92, 94, 93, 95, nil, nil, nil, + nil, 88, 98, nil, nil, nil, 79, 80, 81, 67, + 62, 89, 103, 104, 68, 69, 43, 44, nil, 72, + nil, 70, 71, 73, 322, 323, 77, 78, nil, nil, + nil, nil, nil, 82, 319, 325, 111, 110, 112, 113, + nil, nil, 241, nil, nil, nil, nil, nil, nil, 50, + nil, nil, 115, 114, 116, 105, 61, 107, 106, 108, + nil, 109, 117, 118, nil, 101, 102, 46, 47, 45, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 234, + nil, nil, 240, nil, nil, 63, 64, nil, nil, 65, + nil, nil, nil, nil, nil, 49, nil, nil, nil, nil, + nil, nil, nil, nil, 239, nil, nil, nil, nil, 99, + 87, 90, 91, nil, 92, 94, 93, 95, nil, nil, + nil, nil, 88, 98, nil, nil, nil, nil, nil, nil, + 67, nil, 89, 103, 104, -260, nil, 43, 44, nil, + nil, nil, -260, -260, -260, nil, nil, -260, -260, -260, + 724, -260, 721, 720, 719, 729, 722, nil, nil, -260, + -260, -260, nil, nil, nil, 732, nil, nil, nil, nil, + nil, -260, -260, nil, -260, -260, -260, -260, -260, nil, + nil, nil, nil, nil, nil, nil, nil, 727, nil, 724, + nil, 721, 720, 719, 729, 722, 737, 736, 740, 739, + nil, nil, nil, 733, 732, nil, nil, nil, nil, nil, + nil, nil, -260, nil, nil, nil, nil, nil, nil, -260, + nil, nil, nil, nil, 276, -260, 727, 709, nil, 229, + nil, nil, nil, nil, nil, 737, 736, 740, 739, nil, + nil, nil, 733, nil, nil, nil, nil, -260, -260, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, -260, nil, nil, -260, nil, 79, 80, 81, + -260, 62, nil, nil, nil, 68, 69, -260, nil, nil, + 72, nil, 70, 71, 73, 322, 323, 77, 78, nil, + nil, nil, nil, nil, 82, 319, 325, 111, 110, 112, + 113, nil, nil, 241, nil, nil, nil, nil, nil, nil, + 50, nil, nil, 115, 114, 116, 105, 61, 107, 106, + 108, nil, 109, 117, 118, nil, 101, 102, 46, 47, + 45, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 234, nil, nil, 240, nil, nil, 63, 64, nil, nil, + 65, nil, nil, nil, nil, nil, 49, nil, nil, nil, + nil, nil, nil, nil, nil, 239, nil, nil, nil, nil, + 99, 87, 90, 91, nil, 92, 94, 93, 95, nil, + nil, nil, nil, 88, 98, nil, nil, nil, 79, 80, + 81, 67, 62, 89, 103, 104, 68, 69, 43, 44, + nil, 72, nil, 70, 71, 73, 322, 323, 77, 78, + nil, nil, nil, nil, nil, 82, 319, 325, 111, 110, + 112, 113, nil, nil, 241, nil, nil, nil, nil, nil, + nil, 50, nil, nil, 115, 114, 116, 105, 61, 107, + 106, 108, 297, 109, 117, 118, nil, 101, 102, 46, + 47, 45, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 234, nil, nil, 240, nil, nil, 63, 64, nil, + nil, 65, nil, 681, nil, 292, nil, 49, nil, nil, + 298, nil, nil, nil, nil, nil, 239, nil, nil, nil, + nil, 99, 295, 90, 91, nil, 92, 94, 93, 95, + nil, nil, nil, nil, 88, 98, nil, nil, nil, 79, + 80, 81, 67, 62, 89, 103, 104, 68, 69, 43, + 44, nil, 72, nil, 70, 71, 73, 322, 323, 77, + 78, nil, nil, nil, nil, nil, 82, 319, 325, 111, + 110, 112, 113, nil, nil, 241, nil, nil, nil, nil, + nil, nil, 50, nil, nil, 115, 114, 116, 105, 61, + 107, 106, 108, 297, 109, 117, 118, nil, 101, 102, + 46, 47, 45, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 234, nil, nil, 240, nil, nil, 63, 64, + nil, nil, 65, nil, nil, nil, 292, nil, 49, nil, + nil, 298, nil, nil, nil, nil, nil, 239, nil, nil, + nil, nil, 99, 295, 90, 91, nil, 92, 94, 93, + 95, nil, nil, nil, nil, 88, 98, nil, nil, nil, + 79, 80, 81, 67, 62, 89, 103, 104, 68, 69, + 43, 44, nil, 72, nil, 70, 71, 73, 322, 323, + 77, 78, nil, nil, nil, nil, nil, 82, 319, 325, + 111, 110, 112, 113, nil, nil, 241, nil, nil, nil, + nil, nil, nil, 50, nil, nil, 115, 114, 116, 105, + 61, 107, 106, 108, nil, 109, 117, 118, nil, 101, + 102, 46, 47, 45, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 234, nil, nil, 240, nil, nil, 63, + 64, nil, nil, 65, nil, nil, nil, nil, nil, 49, + nil, nil, nil, nil, nil, nil, nil, nil, 239, nil, + nil, nil, nil, 99, 87, 90, 91, nil, 92, 94, + 93, 95, nil, nil, nil, nil, 88, 98, nil, nil, + nil, nil, nil, nil, 67, nil, 89, 103, 104, nil, + nil, 43, 44, 79, 80, 81, 11, 62, nil, nil, + nil, 68, 69, nil, nil, nil, 72, nil, 70, 71, + 73, 32, 33, 77, 78, nil, nil, nil, nil, nil, + 82, 30, 29, 111, 110, 112, 113, nil, nil, 21, + nil, nil, nil, nil, nil, 10, 50, 305, 12, 115, + 114, 116, 105, 61, 107, 106, 108, nil, 109, 117, + 118, nil, 101, 102, 46, 47, 45, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 42, nil, nil, 35, + nil, nil, 63, 64, nil, nil, 65, nil, 37, nil, + nil, nil, 49, nil, nil, nil, nil, nil, nil, nil, + nil, 22, nil, nil, nil, nil, 99, 87, 90, 91, + nil, 92, 94, 93, 95, nil, nil, nil, nil, 88, + 98, nil, nil, nil, nil, nil, 403, 67, nil, 89, + 103, 104, nil, nil, 43, 44, 79, 80, 81, nil, + 62, nil, nil, nil, 68, 69, nil, nil, nil, 72, + nil, 70, 71, 73, 32, 33, 77, 78, nil, nil, + nil, nil, nil, 82, 30, 29, 111, 110, 112, 113, + nil, nil, 241, nil, nil, nil, nil, nil, nil, 50, + nil, nil, 115, 114, 116, 105, 61, 107, 106, 108, + 297, 109, 117, 118, nil, 101, 102, 46, 47, 45, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 234, + nil, nil, 240, nil, nil, 63, 64, nil, nil, 65, + nil, 294, nil, 292, nil, 49, nil, nil, 298, nil, + nil, nil, nil, nil, 239, nil, nil, nil, nil, 99, + 295, 90, 91, nil, 92, 94, 93, 95, nil, nil, + nil, nil, 88, 98, nil, nil, nil, 79, 80, 81, + 67, 62, 89, 103, 104, 68, 69, 43, 44, nil, + 72, nil, 70, 71, 73, 322, 323, 77, 78, nil, + nil, nil, nil, nil, 82, 319, 325, 111, 110, 112, + 113, nil, nil, 241, nil, nil, nil, nil, nil, nil, + 50, nil, nil, 115, 114, 116, 105, 61, 107, 106, + 108, nil, 109, 117, 118, nil, 101, 102, 46, 47, + 45, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 234, nil, nil, 240, nil, nil, 63, 64, nil, nil, + 65, nil, nil, nil, nil, nil, 49, nil, nil, nil, + nil, nil, nil, nil, nil, 239, nil, nil, nil, nil, + 99, 87, 90, 91, nil, 92, 94, 93, 95, nil, + nil, nil, nil, 88, 98, nil, nil, nil, 79, 80, + 81, 67, 62, 89, 103, 104, 68, 69, 43, 44, + nil, 72, nil, 70, 71, 73, 322, 323, 77, 78, + nil, nil, nil, nil, nil, 82, 319, 325, 111, 110, + 112, 113, nil, nil, 241, nil, nil, nil, nil, nil, + nil, 50, nil, nil, 115, 114, 116, 105, 61, 107, + 106, 108, nil, 109, 117, 118, nil, 101, 102, 46, + 47, 45, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 234, nil, nil, 240, nil, nil, 63, 64, nil, + nil, 65, nil, nil, nil, nil, nil, 49, nil, nil, + nil, nil, nil, nil, nil, nil, 239, nil, nil, nil, + nil, 99, 87, 90, 91, nil, 92, 94, 93, 95, + nil, nil, nil, nil, 88, 98, nil, nil, nil, 79, + 80, 81, 67, 62, 89, 103, 104, 68, 69, 43, + 44, nil, 72, nil, 70, 71, 73, 32, 33, 77, + 78, nil, nil, nil, nil, nil, 82, 30, 29, 111, + 110, 112, 113, nil, nil, 21, nil, nil, nil, nil, + nil, nil, 50, nil, nil, 115, 114, 116, 105, 61, + 107, 106, 108, nil, 109, 117, 118, nil, 101, 102, + 46, 47, 45, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 234, nil, nil, 240, nil, nil, 63, 64, + nil, nil, 65, nil, nil, nil, nil, nil, 49, nil, + nil, nil, nil, nil, nil, nil, nil, 22, nil, nil, + nil, nil, 99, 87, 90, 91, nil, 92, 94, 93, + 95, nil, nil, nil, nil, 88, 98, nil, nil, nil, + 79, 80, 81, 67, 62, 89, 103, 104, 68, 69, + 43, 44, nil, 72, nil, 70, 71, 73, 322, 323, + 77, 78, nil, nil, nil, nil, nil, 82, 319, 325, + 111, 110, 112, 113, nil, nil, 241, nil, nil, nil, + nil, nil, nil, 50, nil, nil, 115, 114, 116, 105, + 61, 107, 106, 108, 297, 109, 117, 118, nil, 101, + 102, 46, 47, 45, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 234, nil, nil, 240, nil, nil, 63, + 64, nil, nil, 65, nil, 681, nil, nil, nil, 49, + nil, nil, 298, nil, nil, nil, nil, nil, 239, nil, + nil, nil, nil, 99, 295, 90, 91, nil, 92, 94, + 93, 95, nil, nil, nil, nil, 88, 98, nil, nil, + nil, 79, 80, 81, 67, 62, 89, 103, 104, 68, + 69, 43, 44, nil, 72, nil, 70, 71, 73, 322, + 323, 77, 78, nil, nil, nil, nil, nil, 82, 319, + 325, 111, 110, 112, 113, nil, nil, 241, nil, nil, + nil, nil, nil, nil, 50, nil, nil, 115, 114, 116, + 105, 61, 107, 106, 108, 297, 109, 117, 118, nil, + 101, 102, 46, 47, 45, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 234, nil, nil, 240, nil, nil, + 63, 64, nil, nil, 65, nil, nil, nil, nil, nil, + 49, nil, nil, 298, nil, nil, nil, nil, nil, 239, + nil, nil, nil, nil, 99, 295, 90, 91, nil, 92, + 94, 93, 95, nil, nil, nil, nil, 88, 98, nil, + nil, nil, 79, 80, 81, 67, 62, 89, 103, 104, + 68, 69, 43, 44, nil, 72, nil, 70, 71, 73, + 322, 323, 77, 78, nil, nil, nil, nil, nil, 82, + 319, 325, 111, 110, 112, 113, nil, nil, 241, nil, + nil, nil, nil, nil, nil, 50, nil, nil, 115, 114, + 116, 105, 61, 107, 106, 108, nil, 109, 117, 118, + nil, 101, 102, 46, 47, 45, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 234, nil, nil, 240, nil, + nil, 63, 64, nil, nil, 65, nil, 294, nil, nil, + nil, 49, nil, nil, nil, nil, nil, nil, nil, nil, + 239, nil, nil, nil, nil, 99, 87, 90, 91, nil, + 92, 94, 93, 95, nil, nil, nil, nil, 88, 98, + nil, nil, nil, 79, 80, 81, 67, 62, 89, 103, + 104, 68, 69, 43, 44, nil, 72, nil, 70, 71, + 73, 32, 33, 77, 78, nil, nil, nil, nil, nil, + 82, 30, 29, 111, 110, 112, 113, nil, nil, 241, + nil, nil, nil, nil, nil, nil, 50, nil, nil, 115, + 114, 116, 105, 61, 107, 106, 108, 297, 109, 117, + 118, nil, 101, 102, 46, 47, 45, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 234, nil, nil, 240, + nil, nil, 63, 64, nil, nil, 65, nil, 294, nil, + 292, nil, 49, nil, nil, 298, nil, nil, nil, nil, + nil, 239, nil, nil, nil, nil, 99, 295, 90, 91, + nil, 92, 94, 93, 95, nil, nil, nil, nil, 88, + 98, nil, nil, nil, 79, 80, 81, 67, 62, 89, + 103, 104, 68, 69, 43, 44, nil, 72, nil, 70, + 71, 73, 32, 33, 77, 78, nil, nil, nil, nil, + nil, 82, 30, 29, 111, 110, 112, 113, nil, nil, + 241, nil, nil, nil, nil, nil, nil, 50, nil, nil, + 115, 114, 116, 105, 61, 107, 106, 108, 297, 109, + 117, 118, nil, 101, 102, 46, 47, 45, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 234, nil, nil, + 240, nil, nil, 63, 64, nil, nil, 65, nil, 294, + nil, 292, nil, 49, nil, nil, 298, nil, nil, nil, + nil, nil, 239, nil, nil, nil, nil, 99, 295, 90, + 91, nil, 92, 94, 93, 95, nil, nil, nil, nil, + 88, 98, nil, nil, nil, nil, nil, nil, 67, nil, + 89, 103, 104, nil, nil, 43, 44, 79, 80, 81, + 11, 62, nil, nil, nil, 68, 69, nil, nil, nil, + 72, nil, 70, 71, 73, 32, 33, 77, 78, nil, + nil, nil, nil, nil, 82, 30, 29, 111, 110, 112, + 113, nil, nil, 21, nil, nil, nil, nil, nil, 10, + 50, nil, 12, 115, 114, 116, 105, 61, 107, 106, + 108, nil, 109, 117, 118, nil, 101, 102, 46, 47, + 45, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 42, nil, nil, 35, nil, nil, 63, 64, nil, nil, + 65, nil, 37, nil, nil, nil, 49, nil, nil, nil, + nil, nil, nil, nil, nil, 22, nil, nil, nil, nil, + 99, 87, 90, 91, nil, 92, 94, 93, 95, nil, + nil, nil, nil, 88, 98, nil, nil, nil, 79, 80, + 81, 67, 62, 89, 103, 104, 68, 69, 43, 44, + nil, 72, nil, 70, 71, 73, 322, 323, 77, 78, + nil, nil, nil, nil, nil, 82, 319, 325, 111, 110, + 112, 113, nil, nil, 241, nil, nil, nil, nil, nil, + nil, 50, nil, nil, 115, 114, 116, 105, 61, 107, + 106, 108, nil, 109, 117, 118, nil, 101, 102, 46, + 47, 45, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 234, nil, nil, 240, nil, nil, 63, 64, nil, + nil, 65, nil, 789, nil, nil, nil, 49, nil, nil, + nil, nil, nil, nil, nil, nil, 239, nil, nil, nil, + nil, 99, 87, 90, 91, nil, 92, 94, 93, 95, + nil, nil, nil, nil, 88, 98, nil, nil, nil, 79, + 80, 81, 67, 62, 89, 103, 104, 68, 69, 43, + 44, nil, 72, nil, 70, 71, 73, 32, 33, 77, + 78, nil, nil, nil, nil, nil, 82, 30, 29, 111, + 110, 112, 113, nil, nil, 241, nil, nil, nil, nil, + nil, nil, 50, nil, nil, 115, 114, 116, 105, 61, + 107, 106, 108, nil, 109, 117, 118, nil, 101, 102, + 46, 47, 45, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 234, nil, nil, 240, nil, nil, 63, 64, + nil, nil, 65, nil, nil, nil, nil, nil, 49, nil, + nil, nil, nil, nil, nil, nil, nil, 239, nil, nil, + nil, nil, 99, 87, 90, 91, nil, 92, 94, 93, + 95, nil, nil, nil, nil, 88, 98, nil, nil, nil, + 79, 80, 81, 67, 62, 89, 103, 104, 68, 69, + 43, 44, nil, 72, nil, 70, 71, 73, 32, 33, + 77, 78, nil, nil, nil, nil, nil, 82, 30, 29, + 111, 110, 112, 113, nil, nil, 241, nil, nil, nil, + nil, nil, nil, 50, nil, nil, 115, 114, 116, 105, + 61, 107, 106, 108, 297, 109, 117, 118, nil, 101, + 102, 46, 47, 45, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 234, nil, nil, 240, nil, nil, 63, + 64, nil, nil, 65, nil, 294, nil, 292, nil, 49, + nil, nil, 298, nil, nil, nil, nil, nil, 239, nil, + nil, nil, nil, 99, 295, 90, 91, nil, 92, 94, + 93, 95, nil, nil, nil, nil, 88, 98, nil, nil, + nil, nil, nil, nil, 67, nil, 89, 103, 104, nil, + nil, 43, 44, 79, 80, 81, 11, 62, nil, nil, + nil, 68, 69, nil, nil, nil, 72, nil, 70, 71, + 73, 32, 33, 77, 78, nil, nil, nil, nil, nil, + 82, 30, 29, 111, 110, 112, 113, nil, nil, 21, + nil, nil, nil, nil, nil, 10, 50, nil, 12, 115, + 114, 116, 105, 61, 107, 106, 108, nil, 109, 117, + 118, nil, 101, 102, 46, 47, 45, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 42, nil, nil, 35, + nil, nil, 63, 64, nil, nil, 65, nil, 37, nil, + nil, nil, 49, nil, nil, nil, nil, nil, nil, nil, + nil, 22, nil, nil, nil, nil, 99, 87, 90, 91, + nil, 92, 94, 93, 95, nil, nil, nil, nil, 88, + 98, nil, nil, nil, 79, 80, 81, 67, 62, 89, + 103, 104, 68, 69, 43, 44, nil, 72, nil, 70, + 71, 73, 322, 323, 77, 78, nil, nil, nil, nil, + nil, 82, 319, 325, 111, 110, 112, 113, nil, nil, + 241, nil, nil, nil, nil, nil, nil, 50, nil, nil, + 115, 114, 116, 105, 61, 107, 106, 108, nil, 109, + 117, 118, nil, 101, 102, 46, 47, 45, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 234, nil, nil, + 240, nil, nil, 63, 64, nil, nil, 65, nil, nil, + nil, nil, nil, 49, nil, nil, nil, nil, nil, nil, + nil, nil, 239, nil, nil, nil, nil, 99, 87, 90, + 91, nil, 92, 94, 93, 95, nil, nil, nil, nil, + 88, 98, nil, nil, nil, 79, 80, 81, 67, 62, + 89, 103, 104, 68, 69, 43, 44, nil, 72, nil, + 70, 71, 73, 322, 323, 77, 78, nil, nil, nil, + nil, nil, 82, 319, 325, 111, 110, 112, 113, nil, + nil, 241, nil, nil, nil, nil, nil, nil, 50, nil, + nil, 115, 114, 116, 105, 61, 107, 106, 108, 297, + 109, 117, 118, nil, 101, 102, 46, 47, 45, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 234, nil, + nil, 240, nil, nil, 63, 64, nil, nil, 65, nil, + 681, nil, 292, nil, 49, nil, nil, 298, nil, nil, + nil, nil, nil, 239, nil, nil, nil, nil, 99, 295, + 90, 91, nil, 92, 94, 93, 95, nil, nil, nil, + nil, 88, 98, nil, nil, nil, 79, 80, 81, 67, + 62, 89, 103, 104, 68, 69, 43, 44, nil, 72, + nil, 70, 71, 73, 322, 323, 77, 78, nil, nil, + nil, nil, nil, 82, 319, 325, 111, 110, 112, 113, + nil, nil, 241, nil, nil, nil, nil, nil, nil, 50, + nil, nil, 115, 114, 116, 105, 61, 107, 106, 108, + 297, 109, 117, 118, nil, 101, 102, 46, 47, 45, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 234, + nil, nil, 240, nil, nil, 63, 64, nil, nil, 65, + nil, nil, nil, 292, nil, 49, nil, nil, 298, nil, + nil, nil, nil, nil, 239, nil, nil, nil, nil, 99, + 295, 90, 91, nil, 92, 94, 93, 95, nil, nil, + nil, nil, 88, 98, nil, nil, nil, 79, 80, 81, + 67, 62, 89, 103, 104, 68, 69, 43, 44, nil, + 72, nil, 70, 71, 73, 32, 33, 77, 78, nil, + nil, nil, nil, nil, 82, 30, 29, 111, 110, 112, + 113, nil, nil, 241, nil, nil, nil, nil, nil, nil, + 50, nil, nil, 115, 114, 116, 105, 61, 107, 106, + 108, nil, 109, 117, 118, nil, 101, 102, 46, 47, + 45, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 234, nil, nil, 240, nil, nil, 63, 64, nil, nil, + 65, nil, nil, nil, nil, nil, 49, nil, nil, nil, + nil, nil, nil, nil, nil, 239, nil, nil, nil, nil, + 99, 87, 90, 91, nil, 92, 94, 93, 95, nil, + nil, nil, nil, 88, 98, nil, nil, nil, 79, 80, + 81, 67, 62, 89, 103, 104, 68, 69, 43, 44, + nil, 72, nil, 70, 71, 73, 32, 33, 77, 78, + nil, nil, nil, nil, nil, 82, 30, 29, 111, 110, + 112, 113, nil, nil, 241, nil, nil, nil, nil, nil, + nil, 50, nil, nil, 115, 114, 116, 105, 61, 107, + 106, 108, nil, 109, 117, 118, nil, 101, 102, 46, + 47, 45, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 234, nil, nil, 240, nil, nil, 63, 64, nil, + nil, 65, nil, nil, nil, nil, nil, 49, nil, nil, + nil, nil, nil, nil, nil, nil, 239, nil, nil, nil, + nil, 99, 87, 90, 91, nil, 92, 94, 93, 95, + nil, nil, nil, nil, 88, 98, nil, nil, nil, 79, + 80, 81, 67, 62, 89, 103, 104, 68, 69, 43, + 44, nil, 72, nil, 70, 71, 73, 32, 33, 77, + 78, nil, nil, nil, nil, nil, 82, 30, 29, 111, + 110, 112, 113, nil, nil, 241, nil, nil, nil, nil, + nil, nil, 50, nil, nil, 115, 114, 116, 105, 61, + 107, 106, 108, nil, 109, 117, 118, nil, 101, 102, + 46, 47, 45, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 234, nil, nil, 240, nil, nil, 63, 64, + nil, nil, 65, nil, nil, nil, nil, nil, 49, nil, + nil, nil, nil, nil, nil, nil, nil, 239, nil, nil, + nil, nil, 99, 87, 90, 91, nil, 92, 94, 93, + 95, nil, nil, nil, nil, 88, 98, nil, nil, nil, + 79, 80, 81, 67, 62, 89, 103, 104, 68, 69, + 43, 44, nil, 72, nil, 70, 71, 73, 32, 33, + 77, 78, nil, nil, nil, nil, nil, 82, 30, 29, + 111, 110, 112, 113, nil, nil, 241, nil, nil, nil, + nil, nil, nil, 50, nil, nil, 115, 114, 116, 105, + 61, 107, 106, 108, nil, 109, 117, 118, nil, 101, + 102, 46, 47, 45, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 234, nil, nil, 240, nil, nil, 63, + 64, nil, nil, 65, nil, nil, nil, nil, nil, 49, + nil, nil, nil, nil, nil, nil, nil, nil, 239, nil, + nil, nil, nil, 99, 87, 90, 91, nil, 92, 94, + 93, 95, nil, nil, nil, nil, 88, 98, nil, nil, + nil, 79, 80, 81, 67, 62, 89, 103, 104, 68, + 69, 43, 44, nil, 72, nil, 70, 71, 73, 322, + 323, 77, 78, nil, nil, nil, nil, nil, 82, 319, + 325, 111, 110, 112, 113, nil, nil, 241, nil, nil, + nil, nil, nil, nil, 50, nil, nil, 115, 114, 116, + 105, 61, 107, 106, 108, 297, 109, 117, 118, nil, + 101, 102, 46, 47, 45, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 234, nil, nil, 240, nil, nil, + 63, 64, nil, nil, 65, nil, 681, nil, 292, nil, + 49, nil, nil, 298, nil, nil, nil, nil, nil, 239, + nil, nil, nil, nil, 99, 295, 90, 91, nil, 92, + 94, 93, 95, nil, nil, nil, nil, 88, 98, nil, + nil, nil, 79, 80, 81, 67, 62, 89, 103, 104, + 68, 69, 43, 497, nil, 72, nil, 70, 71, 73, + 322, 323, 77, 78, nil, nil, nil, nil, nil, 82, + 319, 325, 111, 110, 112, 113, nil, nil, 241, nil, + nil, nil, nil, nil, nil, 50, nil, nil, 115, 114, + 116, 105, 61, 107, 106, 108, nil, 109, 117, 118, + nil, 101, 102, 46, 47, 45, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 234, nil, nil, 240, nil, + nil, 63, 64, nil, nil, 65, nil, nil, nil, nil, + nil, 49, nil, nil, nil, nil, nil, nil, nil, nil, + 239, nil, nil, nil, nil, 99, 87, 90, 91, nil, + 92, 94, 93, 95, nil, nil, nil, nil, 88, 98, + nil, nil, nil, 79, 80, 81, 67, 62, 89, 103, + 104, 68, 69, 43, 44, nil, 72, nil, 70, 71, + 73, 322, 323, 77, 78, nil, nil, nil, nil, nil, + 82, 319, 325, 111, 110, 112, 113, nil, nil, 241, + nil, nil, nil, nil, nil, nil, 50, nil, nil, 115, + 114, 116, 105, 61, 107, 106, 108, nil, 109, 117, + 118, nil, 101, 102, 46, 47, 45, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 234, nil, nil, 240, + nil, nil, 63, 64, nil, nil, 65, nil, nil, nil, + nil, nil, 49, nil, nil, nil, nil, nil, nil, nil, + nil, 239, nil, nil, nil, nil, 99, 87, 90, 91, + nil, 92, 94, 93, 95, nil, nil, nil, nil, 88, + 98, nil, nil, nil, 79, 80, 81, 67, 62, 89, + 103, 104, 68, 69, 43, 44, nil, 72, nil, 70, + 71, 73, 322, 323, 77, 78, nil, nil, nil, nil, + nil, 82, 319, 325, 111, 110, 112, 113, nil, nil, + 241, nil, nil, nil, nil, nil, nil, 50, nil, nil, + 115, 114, 116, 105, 61, 107, 106, 108, nil, 109, + 117, 118, nil, 101, 102, 46, 47, 45, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 234, nil, nil, + 240, nil, nil, 63, 64, nil, nil, 65, nil, 419, + nil, nil, nil, 49, nil, nil, nil, nil, nil, nil, + nil, nil, 239, nil, nil, nil, nil, 99, 87, 90, + 91, nil, 92, 94, 93, 95, nil, nil, nil, nil, + 88, 98, nil, nil, nil, 79, 80, 81, 67, 62, + 89, 103, 104, 68, 69, 43, 44, nil, 72, nil, + 70, 71, 73, 322, 323, 77, 78, nil, nil, nil, + nil, nil, 82, 319, 325, 111, 110, 112, 113, nil, + nil, 241, nil, nil, nil, nil, nil, nil, 50, nil, + nil, 115, 114, 116, 105, 61, 107, 106, 108, nil, + 109, 117, 118, nil, 101, 102, 46, 47, 45, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 234, nil, + nil, 240, nil, nil, 63, 64, nil, nil, 65, nil, + nil, nil, nil, nil, 49, nil, nil, nil, nil, nil, + nil, nil, nil, 239, nil, nil, nil, nil, 99, 87, + 90, 91, nil, 92, 94, 93, 95, nil, nil, nil, + nil, 88, 98, nil, nil, nil, 79, 80, 81, 67, + 62, 89, 103, 104, 68, 69, 43, 44, nil, 72, + nil, 70, 71, 73, 32, 33, 77, 78, nil, nil, + nil, nil, nil, 82, 30, 29, 111, 110, 112, 113, + nil, nil, 21, nil, nil, nil, nil, nil, nil, 50, + nil, nil, 115, 114, 116, 105, 61, 107, 106, 108, + nil, 109, 117, 118, nil, 101, 102, 46, 47, 45, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 234, + nil, nil, 240, nil, nil, 63, 64, nil, nil, 65, + nil, nil, nil, nil, nil, 49, nil, nil, nil, nil, + nil, nil, nil, nil, 22, nil, nil, nil, nil, 99, + 87, 90, 91, nil, 92, 94, 93, 95, nil, nil, + nil, nil, 88, 98, nil, nil, nil, 79, 80, 81, + 67, 62, 89, 103, 104, 68, 69, 43, 44, nil, + 72, nil, 70, 71, 73, 322, 323, 77, 78, nil, + nil, nil, nil, nil, 82, 319, 325, 111, 110, 112, + 113, nil, nil, 241, nil, nil, nil, nil, nil, nil, + 50, nil, nil, 115, 114, 116, 105, 61, 107, 106, + 108, nil, 109, 117, 118, nil, 101, 102, 46, 47, + 45, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 234, nil, nil, 240, nil, nil, 63, 64, nil, nil, + 65, nil, nil, nil, nil, nil, 49, nil, nil, nil, + nil, nil, nil, nil, nil, 239, nil, nil, nil, nil, + 99, 87, 90, 91, nil, 92, 94, 93, 95, nil, + nil, nil, nil, 88, 98, nil, nil, nil, 79, 80, + 81, 67, 62, 89, 103, 104, 68, 69, 43, 44, + nil, 72, nil, 70, 71, 73, 32, 33, 77, 78, + nil, nil, nil, nil, nil, 82, 30, 29, 111, 110, + 112, 113, nil, nil, 241, nil, nil, nil, nil, nil, + nil, 50, nil, nil, 115, 114, 116, 105, 61, 107, + 106, 108, nil, 109, 117, 118, nil, 101, 102, 46, + 47, 45, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 234, nil, nil, 240, nil, nil, 63, 64, nil, + nil, 65, nil, nil, nil, nil, nil, 49, nil, nil, + nil, nil, nil, nil, nil, nil, 239, nil, nil, nil, + nil, 99, 87, 90, 91, nil, 92, 94, 93, 95, + nil, nil, nil, nil, 88, 98, nil, nil, nil, 79, + 80, 81, 67, 62, 89, 103, 104, 68, 69, 43, + 44, nil, 72, nil, 70, 71, 73, 322, 323, 77, + 78, nil, nil, nil, nil, nil, 82, 319, 325, 111, + 110, 112, 113, nil, nil, 241, nil, nil, nil, nil, + nil, nil, 50, nil, nil, 115, 114, 116, 105, 61, + 107, 106, 108, nil, 109, 117, 118, nil, 101, 102, + 46, 47, 45, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 234, nil, nil, 240, nil, nil, 63, 64, + nil, nil, 65, nil, nil, nil, nil, nil, 49, nil, + nil, nil, nil, nil, nil, nil, nil, 239, nil, nil, + nil, nil, 99, 87, 90, 91, nil, 92, 94, 93, + 95, nil, nil, nil, nil, 88, 98, nil, nil, nil, + 79, 80, 81, 67, 62, 89, 103, 104, 68, 69, + 43, 44, nil, 72, nil, 70, 71, 73, 322, 323, + 77, 78, nil, nil, nil, nil, nil, 82, 319, 325, + 111, 110, 112, 113, nil, nil, 241, nil, nil, nil, + nil, nil, nil, 50, nil, nil, 115, 114, 116, 105, + 61, 107, 106, 108, nil, 109, 117, 118, nil, 101, + 102, 46, 47, 45, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 234, nil, nil, 240, nil, nil, 63, + 64, nil, nil, 65, nil, nil, nil, nil, nil, 49, + nil, nil, nil, nil, nil, nil, nil, nil, 239, nil, + nil, nil, nil, 99, 87, 90, 91, nil, 92, 94, + 93, 95, nil, nil, nil, nil, 88, 98, nil, nil, + nil, 79, 80, 81, 67, 62, 89, 103, 104, 68, + 69, 43, 44, nil, 72, nil, 70, 71, 73, 322, + 323, 77, 78, nil, nil, nil, nil, nil, 82, 319, + 325, 111, 110, 112, 113, nil, nil, 241, nil, nil, + nil, nil, nil, nil, 50, nil, nil, 115, 114, 116, + 105, 61, 107, 106, 108, nil, 109, 117, 118, nil, + 101, 102, 46, 47, 45, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 234, nil, nil, 240, nil, nil, + 63, 64, nil, nil, 65, nil, nil, nil, nil, nil, + 49, nil, nil, nil, nil, nil, nil, nil, nil, 239, + nil, nil, nil, nil, 99, 87, 90, 91, nil, 92, + 94, 93, 95, nil, nil, nil, nil, 88, 98, nil, + nil, nil, 79, 80, 81, 67, 62, 89, 103, 104, + 68, 69, 43, 44, nil, 72, nil, 70, 71, 73, + 322, 323, 77, 78, nil, nil, nil, nil, nil, 82, + 319, 325, 111, 110, 112, 113, nil, nil, 241, nil, + nil, nil, nil, nil, nil, 50, nil, nil, 115, 114, + 116, 105, 61, 107, 106, 108, nil, 109, 117, 118, + nil, 101, 102, 46, 47, 45, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 234, nil, nil, 240, nil, + nil, 63, 64, nil, nil, 65, nil, nil, nil, nil, + nil, 49, nil, nil, nil, nil, nil, nil, nil, nil, + 239, nil, nil, nil, nil, 99, 87, 90, 91, nil, + 92, 94, 93, 95, nil, nil, nil, nil, 88, 98, + nil, nil, nil, 79, 80, 81, 67, 62, 89, 103, + 104, 68, 69, 43, 44, nil, 72, nil, 70, 71, + 73, 322, 323, 77, 78, nil, nil, nil, nil, nil, + 82, 319, 325, 111, 110, 112, 113, nil, nil, 241, + nil, nil, nil, nil, nil, nil, 50, nil, nil, 115, + 114, 116, 105, 61, 107, 106, 108, nil, 109, 117, + 118, nil, 101, 102, 46, 47, 45, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 234, nil, nil, 240, + nil, nil, 63, 64, nil, nil, 65, nil, nil, nil, + nil, nil, 49, nil, nil, nil, nil, nil, nil, nil, + nil, 239, nil, nil, nil, nil, 99, 87, 90, 91, + nil, 92, 94, 93, 95, nil, nil, nil, nil, 88, + 98, nil, nil, nil, 79, 80, 81, 67, 62, 89, + 103, 104, 68, 69, 43, 44, nil, 72, nil, 70, + 71, 73, 322, 323, 77, 78, nil, nil, nil, nil, + nil, 82, 319, 325, 111, 110, 112, 113, nil, nil, + 241, nil, nil, nil, nil, nil, nil, 50, nil, nil, + 115, 114, 116, 105, 61, 107, 106, 108, nil, 109, + 117, 118, nil, 101, 102, 46, 47, 45, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 234, nil, nil, + 240, nil, nil, 63, 64, nil, nil, 65, nil, nil, + nil, nil, nil, 49, nil, nil, nil, nil, nil, nil, + nil, nil, 239, nil, nil, nil, nil, 99, 87, 90, + 91, nil, 92, 94, 93, 95, nil, nil, nil, nil, + 88, 98, nil, nil, nil, 79, 80, 81, 67, 62, + 89, 103, 104, 68, 69, 43, 44, nil, 72, nil, + 70, 71, 73, 32, 33, 77, 78, nil, nil, nil, + nil, nil, 82, 30, 29, 111, 110, 112, 113, nil, + nil, 21, nil, nil, nil, nil, nil, nil, 50, nil, + nil, 115, 114, 116, 105, 61, 107, 106, 108, nil, + 109, 117, 118, nil, 101, 102, 46, 47, 45, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 234, nil, + nil, 240, nil, nil, 63, 64, nil, nil, 65, nil, + nil, nil, nil, nil, 49, nil, nil, nil, nil, nil, + nil, nil, nil, 22, nil, nil, nil, nil, 99, 87, + 90, 91, nil, 92, 94, 93, 95, nil, nil, nil, + nil, 88, 98, nil, nil, nil, 79, 80, 81, 67, + 62, 89, 103, 104, 68, 69, 43, 44, nil, 72, + nil, 70, 71, 73, 322, 323, 77, 78, nil, nil, + nil, nil, nil, 82, 319, 325, 111, 110, 112, 113, + nil, nil, 241, nil, nil, nil, nil, nil, nil, 50, + nil, nil, 115, 114, 116, 105, 61, 107, 106, 108, + nil, 109, 117, 118, nil, 101, 102, 46, 47, 45, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 234, + nil, nil, 240, nil, nil, 63, 64, nil, nil, 65, + nil, 681, nil, nil, nil, 49, nil, nil, nil, nil, + nil, nil, nil, nil, 239, nil, nil, nil, nil, 99, + 87, 90, 91, nil, 92, 94, 93, 95, nil, nil, + nil, nil, 88, 98, nil, nil, nil, 79, 80, 81, + 67, 62, 89, 103, 104, 68, 69, 43, 44, nil, + 72, nil, 70, 71, 73, 322, 323, 77, 78, nil, + nil, nil, nil, nil, 82, 319, 325, 111, 110, 112, + 113, nil, nil, 241, nil, nil, nil, nil, nil, nil, + 50, nil, nil, 115, 114, 116, 105, 61, 107, 106, + 108, 297, 109, 117, 118, nil, 101, 102, 46, 47, + 45, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 234, nil, nil, 240, nil, nil, 63, 64, nil, nil, + 65, nil, nil, nil, 292, nil, 49, nil, nil, 298, + nil, nil, nil, nil, nil, 239, nil, nil, nil, nil, + 99, 295, 90, 91, nil, 92, 94, 93, 95, nil, + nil, nil, nil, 88, 98, nil, nil, nil, 79, 80, + 81, 67, 62, 89, 103, 104, 68, 69, 43, 44, + nil, 72, nil, 70, 71, 73, 322, 323, 77, 78, + nil, nil, nil, nil, nil, 82, 319, 325, 111, 110, + 112, 113, nil, nil, 241, nil, nil, nil, nil, nil, + nil, 50, nil, nil, 115, 114, 116, 105, 61, 107, + 106, 108, nil, 109, 117, 118, nil, 101, 102, 46, + 47, 45, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 234, nil, nil, 240, nil, nil, 63, 64, nil, + nil, 65, nil, nil, nil, nil, nil, 49, nil, nil, + nil, nil, nil, nil, nil, nil, 239, nil, nil, nil, + nil, 99, 87, 90, 91, nil, 92, 94, 93, 95, + nil, nil, nil, nil, 88, 98, nil, nil, nil, 79, + 80, 81, 67, 62, 89, 103, 104, 68, 69, 43, + 44, nil, 72, nil, 70, 71, 73, 32, 33, 77, + 78, nil, nil, nil, nil, nil, 82, 30, 29, 111, + 110, 112, 113, nil, nil, 21, nil, nil, nil, nil, + nil, nil, 50, nil, nil, 115, 114, 116, 105, 61, + 107, 106, 108, nil, 109, 117, 118, nil, 101, 102, + 46, 47, 45, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 234, nil, nil, 240, nil, nil, 63, 64, + nil, nil, 65, nil, nil, nil, nil, nil, 49, nil, + nil, nil, nil, nil, nil, nil, nil, 22, nil, nil, + nil, nil, 99, 87, 90, 91, nil, 92, 94, 93, + 95, nil, nil, nil, nil, 88, 98, nil, nil, nil, + 79, 80, 81, 67, 62, 89, 103, 104, 68, 69, + 43, 44, nil, 72, nil, 70, 71, 73, 32, 33, + 77, 78, nil, nil, nil, nil, nil, 82, 30, 29, + 111, 110, 112, 113, nil, nil, 21, nil, nil, nil, + nil, nil, nil, 50, nil, nil, 115, 114, 116, 105, + 61, 107, 106, 108, nil, 109, 117, 118, nil, 101, + 102, 46, 47, 45, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 234, nil, nil, 240, nil, nil, 63, + 64, nil, nil, 65, nil, nil, nil, nil, nil, 49, + nil, nil, nil, nil, nil, nil, nil, nil, 22, nil, + nil, nil, nil, 99, 87, 90, 91, nil, 92, 94, + 93, 95, nil, nil, nil, nil, 88, 98, nil, nil, + nil, 79, 80, 81, 67, 62, 89, 103, 104, 68, + 69, 43, 44, nil, 72, nil, 70, 71, 73, 32, + 33, 77, 78, nil, nil, nil, nil, nil, 82, 30, + 29, 111, 110, 112, 113, nil, nil, 241, nil, nil, + nil, nil, nil, nil, 50, nil, nil, 115, 114, 116, + 105, 61, 107, 106, 108, 297, 109, 117, 118, nil, + 101, 102, 46, 47, 45, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 234, nil, nil, 240, nil, nil, + 63, 64, nil, nil, 65, nil, 294, nil, 292, nil, + 49, nil, nil, 298, nil, nil, nil, nil, nil, 239, + nil, nil, nil, nil, 99, 295, 90, 91, nil, 92, + 94, 93, 95, nil, nil, nil, nil, 88, 98, nil, + nil, nil, 79, 80, 81, 67, 62, 89, 103, 104, + 68, 69, 43, 44, nil, 72, nil, 70, 71, 73, + 322, 323, 77, 78, nil, nil, nil, nil, nil, 82, + 319, 325, 111, 110, 112, 113, nil, nil, 241, nil, + nil, nil, nil, nil, nil, 320, nil, nil, 115, 114, + 116, 105, 61, 107, 106, 108, nil, 109, 117, 118, + nil, 101, 102, nil, nil, 326, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 316, nil, nil, 312, nil, + nil, 63, 64, nil, nil, 65, nil, 311, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 99, 87, 90, 91, nil, + 92, 94, 93, 95, nil, nil, nil, nil, 88, 98, + nil, nil, nil, 79, 80, 81, 67, 62, 89, 103, + 104, 68, 69, nil, nil, nil, 72, nil, 70, 71, + 73, 322, 323, 77, 78, nil, nil, nil, nil, nil, + 82, 319, 325, 111, 110, 112, 113, nil, nil, 241, + nil, nil, nil, nil, nil, nil, 320, nil, nil, 115, + 114, 116, 105, 61, 107, 106, 108, nil, 109, 117, + 118, nil, 101, 102, nil, nil, 326, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 316, nil, nil, 240, + nil, nil, 63, 64, nil, nil, 65, nil, nil, 724, + nil, 721, 720, 719, 729, 722, nil, nil, nil, nil, + nil, nil, nil, nil, 732, nil, 99, 87, 90, 91, + nil, 92, 94, 93, 95, nil, nil, nil, nil, 88, + 98, nil, nil, nil, 328, nil, 727, 67, nil, 89, + 103, 104, 79, 80, 81, nil, 62, 740, 739, nil, + 68, 69, 733, nil, nil, 72, nil, 70, 71, 73, + 322, 323, 77, 78, nil, nil, nil, nil, nil, 82, + 319, 325, 111, 110, 112, 113, nil, nil, 241, nil, + nil, nil, nil, nil, nil, 320, nil, nil, 115, 114, + 116, 105, 61, 107, 106, 108, nil, 109, 117, 118, + nil, 101, 102, nil, nil, 326, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 364, nil, nil, 35, nil, + nil, 63, 64, nil, nil, 65, nil, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 99, 87, 90, 91, nil, + 92, 94, 93, 95, nil, nil, nil, nil, 88, 98, + nil, nil, nil, 79, 80, 81, 67, 62, 89, 103, + 104, 68, 69, nil, nil, nil, 72, nil, 70, 71, + 73, 322, 323, 77, 78, nil, nil, nil, nil, nil, + 82, 319, 325, 111, 110, 112, 113, nil, nil, 241, + nil, nil, nil, nil, nil, nil, 320, nil, nil, 115, + 114, 116, 369, 61, 107, 106, 370, nil, 109, 117, + 118, nil, 101, 102, nil, nil, 326, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 376, nil, nil, 371, nil, nil, 240, + nil, nil, 63, 64, nil, nil, 65, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 99, 87, 90, 91, + nil, 92, 94, 93, 95, nil, nil, nil, nil, 88, + 98, nil, nil, nil, 79, 80, 81, 67, 62, 89, + 103, 104, 68, 69, nil, nil, nil, 72, nil, 70, + 71, 73, 322, 323, 77, 78, nil, nil, nil, nil, + nil, 82, 319, 325, 111, 110, 112, 113, nil, nil, + 241, nil, nil, nil, nil, nil, nil, 320, nil, nil, + 115, 114, 116, 369, 61, 107, 106, 370, nil, 109, + 117, 118, nil, 101, 102, nil, nil, 326, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 371, nil, nil, + 240, nil, nil, 63, 64, nil, nil, 65, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 99, 87, 90, + 91, nil, 92, 94, 93, 95, nil, nil, nil, nil, + 88, 98, nil, nil, nil, 79, 80, 81, 67, 62, + 89, 103, 104, 68, 69, nil, nil, nil, 72, nil, + 70, 71, 73, 322, 323, 77, 78, nil, nil, nil, + nil, nil, 82, 319, 325, 111, 110, 112, 113, nil, + nil, 241, nil, nil, nil, nil, nil, nil, 320, nil, + nil, 115, 114, 116, 105, 61, 107, 106, 108, nil, + 109, 117, 118, nil, 101, 102, nil, nil, 326, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 316, nil, + nil, 240, nil, nil, 63, 64, nil, nil, 65, nil, + nil, 724, nil, 721, 720, 719, 729, 722, nil, nil, + nil, nil, nil, nil, nil, nil, 732, nil, 99, 87, + 90, 91, nil, 92, 94, 93, 95, nil, nil, nil, + nil, 88, 98, nil, nil, nil, 525, nil, 727, 67, + nil, 89, 103, 104, 79, 80, 81, nil, 62, 740, + 739, nil, 68, 69, 733, nil, nil, 72, nil, 70, + 71, 73, 322, 323, 77, 78, nil, nil, nil, nil, + nil, 82, 319, 325, 111, 110, 112, 113, nil, nil, + 241, nil, nil, nil, nil, nil, nil, 320, nil, nil, + 115, 114, 116, 105, 61, 107, 106, 108, nil, 109, + 117, 118, nil, 101, 102, nil, nil, 326, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 316, nil, nil, + 312, nil, nil, 63, 64, nil, nil, 65, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 99, 87, 90, + 91, nil, 92, 94, 93, 95, nil, nil, nil, nil, + 88, 98, nil, nil, nil, 79, 80, 81, 67, 62, + 89, 103, 104, 68, 69, nil, nil, nil, 72, nil, + 70, 71, 73, 322, 323, 77, 78, nil, nil, nil, + nil, nil, 82, 319, 325, 111, 110, 112, 113, nil, + nil, 241, nil, nil, nil, nil, nil, nil, 320, nil, + nil, 115, 114, 116, 105, 61, 107, 106, 108, nil, + 109, 117, 118, nil, 101, 102, nil, nil, 326, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 316, nil, + nil, 312, nil, nil, 63, 64, nil, nil, 65, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 99, 87, + 90, 91, nil, 92, 94, 93, 95, nil, nil, nil, + nil, 88, 98, nil, nil, nil, 79, 80, 81, 67, + 62, 89, 103, 104, 68, 69, nil, nil, nil, 72, + nil, 70, 71, 73, 322, 323, 77, 78, nil, nil, + nil, nil, nil, 82, 319, 325, 111, 110, 112, 113, + nil, nil, 241, nil, nil, nil, nil, nil, nil, 320, + nil, nil, 115, 114, 116, 105, 61, 107, 106, 108, + nil, 109, 117, 118, nil, 101, 102, nil, nil, 326, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 316, + nil, nil, 312, nil, nil, 63, 64, nil, nil, 65, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 99, + 87, 90, 91, nil, 92, 94, 93, 95, nil, nil, + nil, nil, 88, 98, nil, nil, nil, 79, 80, 81, + 67, 62, 89, 103, 104, 68, 69, nil, nil, nil, + 72, nil, 70, 71, 73, 322, 323, 77, 78, nil, + nil, nil, nil, nil, 82, 319, 325, 111, 110, 112, + 113, nil, nil, 241, nil, nil, nil, nil, nil, nil, + 320, nil, nil, 115, 114, 116, 105, 61, 107, 106, + 108, nil, 109, 117, 118, nil, 101, 102, nil, nil, + 326, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 316, nil, nil, 312, nil, nil, 63, 64, nil, nil, + 65, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 99, 87, 90, 91, nil, 92, 94, 93, 95, nil, + nil, nil, nil, 88, 98, nil, nil, nil, 79, 80, + 81, 67, 62, 89, 103, 104, 68, 69, nil, nil, + nil, 72, nil, 70, 71, 73, 322, 323, 77, 78, + nil, nil, nil, nil, nil, 82, 319, 325, 111, 110, + 112, 113, nil, nil, 241, nil, nil, nil, nil, nil, + nil, 320, nil, nil, 115, 114, 116, 105, 61, 107, + 106, 108, nil, 109, 117, 118, nil, 101, 102, nil, + nil, 326, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 316, nil, nil, 312, nil, nil, 63, 64, nil, + nil, 65, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 99, 87, 90, 91, nil, 92, 94, 93, 95, + nil, nil, nil, nil, 88, 98, nil, nil, nil, 79, + 80, 81, 67, 62, 89, 103, 104, 68, 69, nil, + nil, nil, 72, nil, 70, 71, 73, 322, 323, 77, + 78, nil, nil, nil, nil, nil, 82, 319, 325, 111, + 110, 112, 113, nil, nil, 241, nil, nil, nil, nil, + nil, nil, 320, nil, nil, 115, 114, 116, 105, 61, + 107, 106, 108, nil, 109, 117, 118, nil, 101, 102, + nil, nil, 326, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1055, nil, nil, 240, nil, nil, 63, 64, + nil, nil, 65, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 99, 87, 90, 91, nil, 92, 94, 93, + 95, nil, nil, nil, nil, 88, 98, nil, nil, nil, + 79, 80, 81, 67, 62, 89, 103, 104, 68, 69, + nil, nil, nil, 72, nil, 70, 71, 73, 322, 323, + 77, 78, nil, nil, nil, nil, nil, 82, 319, 325, + 111, 110, 112, 113, nil, nil, 241, nil, nil, nil, + nil, nil, nil, 320, nil, nil, 115, 114, 116, 105, + 61, 107, 106, 108, nil, 109, 117, 118, nil, 101, + 102, nil, nil, 326, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 1061, nil, nil, 240, nil, nil, 63, + 64, nil, nil, 65, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 99, 87, 90, 91, nil, 92, 94, + 93, 95, nil, nil, nil, nil, 88, 98, nil, nil, + nil, 79, 80, 81, 67, 62, 89, 103, 104, 68, + 69, nil, nil, nil, 72, nil, 70, 71, 73, 322, + 323, 77, 78, nil, nil, nil, nil, nil, 82, 319, + 325, 111, 110, 112, 113, nil, nil, 241, nil, nil, + nil, nil, nil, nil, 320, nil, nil, 115, 114, 116, + 105, 61, 107, 106, 108, nil, 109, 117, 118, nil, + 101, 102, nil, nil, 326, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1055, nil, nil, 240, nil, nil, + 63, 64, nil, nil, 65, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 99, 87, 90, 91, nil, 92, + 94, 93, 95, nil, nil, nil, nil, 88, 98, nil, + nil, nil, nil, nil, nil, 67, nil, 89, 103, 104, + 182, 193, 183, 206, 179, 199, 189, 188, 209, 210, + 204, 187, 186, 181, 207, 211, 212, 191, 180, 194, + 198, 200, 192, 185, nil, nil, nil, 201, 208, 203, + 202, 195, 205, 190, 178, 197, 196, nil, nil, nil, + nil, nil, 177, 184, 175, 176, 172, 173, 174, 135, + 137, 134, nil, 136, nil, nil, nil, nil, nil, nil, + nil, 166, 167, nil, 163, 145, 146, 147, 154, 151, + 153, nil, nil, 148, 149, nil, nil, nil, 168, 169, + 155, 156, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 160, 159, nil, 144, 165, + 162, 161, 170, 157, 158, 152, 150, 142, 164, 143, + nil, nil, 171, 99, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 98, 182, 193, + 183, 206, 179, 199, 189, 188, 209, 210, 204, 187, + 186, 181, 207, 211, 212, 191, 180, 194, 198, 200, + 192, 185, nil, nil, nil, 201, 208, 203, 202, 195, + 205, 190, 178, 197, 196, nil, nil, nil, nil, nil, + 177, 184, 175, 176, 172, 173, 174, 135, 137, nil, + nil, 136, nil, nil, nil, nil, nil, nil, nil, 166, + 167, nil, 163, 145, 146, 147, 154, 151, 153, nil, + nil, 148, 149, nil, nil, nil, 168, 169, 155, 156, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 160, 159, nil, 144, 165, 162, 161, + 170, 157, 158, 152, 150, 142, 164, 143, nil, nil, + 171, 99, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 98, 182, 193, 183, 206, + 179, 199, 189, 188, 209, 210, 204, 187, 186, 181, + 207, 211, 212, 191, 180, 194, 198, 200, 192, 185, + nil, nil, nil, 201, 208, 203, 202, 195, 205, 190, + 178, 197, 196, nil, nil, nil, nil, nil, 177, 184, + 175, 176, 172, 173, 174, 135, 137, nil, nil, 136, + nil, nil, nil, nil, nil, nil, nil, 166, 167, nil, + 163, 145, 146, 147, 154, 151, 153, nil, nil, 148, + 149, nil, nil, nil, 168, 169, 155, 156, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 160, 159, nil, 144, 165, 162, 161, 170, 157, + 158, 152, 150, 142, 164, 143, nil, nil, 171, 99, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 98, 182, 193, 183, 206, 179, 199, + 189, 188, 209, 210, 204, 187, 186, 181, 207, 211, + 212, 191, 180, 194, 198, 200, 192, 185, nil, nil, + nil, 201, 208, 203, 202, 195, 205, 190, 178, 197, + 196, nil, nil, nil, nil, nil, 177, 184, 175, 176, + 172, 173, 174, 135, 137, nil, nil, 136, nil, nil, + nil, nil, nil, nil, nil, 166, 167, nil, 163, 145, + 146, 147, 154, 151, 153, nil, nil, 148, 149, nil, + nil, nil, 168, 169, 155, 156, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 160, + 159, nil, 144, 165, 162, 161, 170, 157, 158, 152, + 150, 142, 164, 143, nil, nil, 171, 99, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 98, 182, 193, 183, 206, 179, 199, 189, 188, + 209, 210, 204, 187, 186, 181, 207, 211, 212, 191, + 180, 194, 198, 200, 192, 185, nil, nil, nil, 201, + 208, 203, 387, 386, 388, 385, 178, 197, 196, nil, + nil, nil, nil, nil, 177, 184, 175, 176, 382, 383, + 384, 380, 137, 107, 106, 381, nil, 109, nil, nil, + nil, nil, nil, 166, 167, nil, 163, 145, 146, 147, + 154, 151, 153, nil, nil, 148, 149, nil, nil, nil, + 168, 169, 155, 156, nil, nil, nil, nil, nil, 392, + nil, nil, nil, nil, nil, nil, nil, 160, 159, nil, + 144, 165, 162, 161, 170, 157, 158, 152, 150, 142, + 164, 143, nil, nil, 171, 111, 110, 112, 113, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 115, 114, 116, 661, nil, nil, 724, 664, 721, + 720, 719, 729, 722, 101, 102, nil, nil, 326, nil, + nil, nil, 732, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 663, nil, + nil, 645, nil, nil, 727, 643, nil, nil, 644, nil, + nil, nil, nil, 737, 736, 740, 739, nil, nil, nil, + 733, nil, nil, nil, 662, nil, nil, nil, 99, 87, + 90, 91, nil, 92, 94, 93, 95, nil, nil, nil, + nil, 88, 98, nil, nil, nil, nil, nil, nil, 660, + nil, 89, 103, 104, nil, nil, 649, 650, 182, 193, + 183, 206, 179, 199, 189, 188, 209, 210, 204, 187, + 186, 181, 207, 211, 212, 191, 180, 194, 198, 200, + 192, 185, nil, nil, nil, 201, 208, 203, 202, 195, + 205, 190, 178, 197, 196, nil, nil, nil, nil, nil, + 177, 184, 175, 176, 172, 173, 174, 135, 137, nil, + nil, 136, nil, nil, nil, nil, nil, nil, nil, 166, + 167, nil, 163, 145, 146, 147, 154, 151, 153, nil, + nil, 148, 149, nil, nil, nil, 168, 169, 155, 156, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 160, 159, nil, 144, 165, 162, 161, + 170, 157, 158, 152, 150, 142, 164, 143, nil, nil, + 171, 111, 110, 112, 113, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 115, 114, 116, + 661, nil, nil, 724, 664, 721, 720, 719, 729, 722, + 101, 102, nil, nil, 326, nil, nil, nil, 732, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 663, nil, nil, 645, nil, nil, + 727, 643, nil, nil, 644, nil, nil, nil, nil, 737, + 736, 740, 739, nil, nil, nil, 733, nil, nil, nil, + 662, nil, nil, nil, 99, 87, 90, 91, nil, 92, + 94, 93, 95, nil, nil, nil, nil, 88, 98, 111, + 110, 112, 113, nil, nil, 660, nil, 89, 103, 104, + nil, nil, 649, 650, nil, 115, 114, 116, 661, nil, + nil, nil, 664, 935, nil, nil, nil, nil, 101, 102, + nil, nil, 326, 732, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 663, nil, nil, 645, nil, nil, nil, 643, + nil, nil, 644, nil, 929, nil, nil, nil, nil, nil, + nil, 733, nil, nil, nil, nil, nil, nil, 662, nil, + nil, nil, 99, 936, 90, 91, nil, 92, 94, 93, + 95, nil, nil, nil, nil, 88, 98, 111, 110, 112, + 113, nil, nil, 660, nil, 89, 103, 104, nil, nil, + 649, 650, nil, 115, 114, 116, 661, nil, nil, nil, + 664, 935, nil, nil, nil, nil, 101, 102, nil, nil, + 326, 732, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 663, nil, nil, 645, nil, nil, nil, 643, nil, nil, + 644, nil, 929, nil, nil, nil, nil, nil, nil, 733, + nil, nil, nil, nil, nil, nil, 662, nil, nil, nil, + 99, 936, 90, 91, nil, 92, 94, 93, 95, nil, + nil, nil, nil, 88, 98, 111, 110, 112, 113, nil, + nil, 660, nil, 89, 103, 104, nil, nil, 649, 650, + nil, 115, 114, 116, 661, nil, nil, 724, 664, 721, + 720, 719, 729, 722, 101, 102, nil, nil, 326, nil, + nil, nil, 732, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 663, nil, + nil, 645, nil, nil, 727, 643, nil, nil, 644, nil, + 929, nil, nil, 737, 736, 740, 739, nil, nil, nil, + 733, nil, nil, nil, 662, nil, nil, nil, 99, 87, + 90, 91, nil, 92, 94, 93, 95, nil, nil, nil, + nil, 88, 98, 111, 110, 112, 113, nil, nil, 660, + nil, 89, 103, 104, nil, nil, 649, 650, nil, 115, + 114, 116, 661, nil, nil, 724, 664, 721, 720, 719, + 729, 722, 101, 102, nil, nil, 326, nil, nil, nil, + 732, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 663, nil, nil, 645, + nil, nil, 727, 643, nil, nil, 644, nil, nil, nil, + nil, 737, 736, 740, 739, nil, nil, nil, 733, nil, + nil, nil, 662, nil, nil, nil, 99, 87, 90, 91, + nil, 92, 94, 93, 95, nil, nil, nil, nil, 88, + 98, 111, 110, 112, 113, nil, nil, 660, nil, 89, + 103, 104, nil, nil, 649, 650, nil, 115, 114, 116, + 661, nil, nil, nil, 664, 935, nil, nil, nil, nil, + 101, 102, nil, nil, 326, 732, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 663, nil, nil, 645, nil, nil, + nil, 643, nil, nil, 644, nil, 929, nil, nil, nil, + nil, nil, nil, 733, nil, nil, nil, nil, nil, nil, + 662, nil, nil, nil, 99, 936, 90, 91, nil, 92, + 94, 93, 95, nil, nil, nil, nil, 88, 98, 111, + 110, 112, 113, nil, nil, 660, nil, 89, 103, 104, + nil, nil, 649, 650, nil, 115, 114, 116, 661, nil, + nil, 724, 664, 721, 720, 719, 729, 722, 101, 102, + nil, nil, 326, nil, nil, nil, 732, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 663, nil, nil, 645, nil, nil, 727, 643, + nil, nil, 644, nil, 1024, nil, nil, 737, 736, 740, + 739, nil, nil, nil, 733, nil, nil, nil, 662, nil, + nil, nil, 99, 87, 90, 91, nil, 92, 94, 93, + 95, nil, nil, nil, nil, 88, 98, 111, 110, 112, + 113, nil, nil, 660, nil, 89, 103, 104, nil, nil, + 649, 650, nil, 115, 114, 116, 661, nil, nil, 724, + 664, 721, 720, 719, 729, 722, 101, 102, nil, nil, + 326, nil, nil, nil, 732, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 663, nil, nil, 645, nil, nil, 727, 643, nil, nil, + 644, nil, nil, nil, nil, 737, 736, 740, 739, nil, + nil, nil, 733, nil, nil, nil, 662, nil, nil, nil, + 99, 87, 90, 91, nil, 92, 94, 93, 95, nil, + nil, nil, nil, 88, 98, 111, 110, 112, 113, nil, + nil, 660, nil, 89, 103, 104, nil, nil, 649, 650, + nil, 115, 114, 116, 661, nil, nil, 724, 664, 721, + 720, 719, 729, 722, 101, 102, nil, nil, 326, nil, + nil, nil, 732, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 663, nil, + nil, 645, nil, nil, 727, 643, nil, nil, 644, nil, + nil, nil, nil, 737, 736, 740, 739, nil, nil, nil, + 733, nil, nil, nil, 662, nil, nil, nil, 99, 87, + 90, 91, nil, 92, 94, 93, 95, nil, nil, nil, + nil, 88, 98, 111, 110, 112, 113, nil, nil, 660, + nil, 89, 103, 104, nil, nil, 649, 650, nil, 115, + 114, 116, 661, nil, nil, 724, 664, 721, 720, 719, + 729, 722, 101, 102, nil, nil, 326, nil, nil, nil, + 732, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 663, nil, nil, 645, + nil, nil, 727, 643, nil, nil, 644, nil, 929, nil, + nil, nil, nil, 740, 739, nil, nil, nil, 733, nil, + nil, nil, 662, nil, nil, nil, 99, 87, 90, 91, + nil, 92, 94, 93, 95, nil, nil, nil, nil, 88, + 98, 111, 110, 112, 113, nil, nil, 660, nil, 89, + 103, 104, nil, nil, 649, 650, nil, 115, 114, 116, + 661, nil, nil, 724, 664, 721, 720, 719, 729, 722, + 101, 102, nil, nil, 326, nil, nil, nil, 732, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 663, nil, nil, 645, nil, nil, + 727, 643, nil, nil, 644, nil, nil, nil, nil, nil, + nil, 740, 739, nil, nil, nil, 733, nil, nil, nil, + 662, nil, nil, nil, 99, 87, 90, 91, nil, 92, + 94, 93, 95, nil, nil, nil, nil, 88, 98, 111, + 110, 112, 113, nil, nil, 660, nil, 89, 103, 104, + nil, nil, 649, 650, nil, 115, 114, 116, 661, nil, + nil, 724, 664, 721, 720, 719, 729, 722, 101, 102, + nil, nil, 326, nil, nil, nil, 732, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 663, nil, nil, 645, nil, nil, 727, 643, + nil, nil, 644, nil, nil, nil, nil, 737, 736, 740, + 739, nil, nil, nil, 733, nil, nil, nil, 662, nil, + nil, nil, 99, 87, 90, 91, nil, 92, 94, 93, + 95, nil, nil, nil, nil, 88, 98, 111, 110, 112, + 113, nil, nil, 660, nil, 89, 103, 104, nil, nil, + 649, 650, nil, 115, 114, 116, 661, nil, nil, 724, + 664, 721, 720, 719, 729, 722, 101, 102, nil, nil, + 326, nil, nil, nil, 732, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 663, nil, nil, 645, nil, nil, 727, 643, nil, nil, + 644, nil, nil, nil, nil, nil, nil, 740, 739, nil, + nil, nil, 733, nil, nil, nil, 662, nil, nil, nil, + 99, 87, 90, 91, nil, 92, 94, 93, 95, nil, + nil, nil, nil, 88, 98, 111, 110, 112, 113, nil, + nil, 660, nil, 89, 103, 104, nil, nil, 649, 650, + nil, 115, 114, 116, 661, nil, nil, nil, 664, nil, + nil, nil, nil, nil, 101, 102, nil, nil, 326, nil, + nil, nil, nil, nil, nil, nil, 111, 110, 112, 113, + nil, nil, nil, nil, nil, nil, nil, nil, 663, nil, + nil, 645, 115, 114, 116, 643, nil, nil, 644, nil, + nil, nil, nil, nil, nil, 101, 102, nil, nil, 326, + nil, nil, nil, nil, 662, nil, nil, nil, 99, 87, + 90, 91, nil, 92, 94, 93, 95, nil, nil, nil, + nil, 88, 98, nil, nil, nil, nil, nil, nil, 660, + nil, 89, 103, 104, nil, nil, 649, 650, 724, nil, + 721, 720, 719, 729, 722, nil, nil, nil, nil, 99, + 87, 90, 91, 732, 92, 94, 93, 95, nil, nil, + nil, nil, 88, 98, 111, 110, 112, 113, nil, nil, + 660, nil, 89, 103, 104, 727, nil, nil, nil, nil, + 115, 114, 116, nil, nil, nil, 740, 739, nil, nil, + nil, 733, nil, 101, 102, nil, nil, 326, 111, 110, + 112, 113, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 115, 114, 116, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 101, 102, nil, + nil, 326, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 99, 87, 90, + 91, nil, 92, 94, 93, 95, nil, nil, nil, nil, + 88, 98, nil, nil, nil, nil, nil, nil, 660, nil, + 89, 103, 104, nil, nil, nil, nil, nil, nil, nil, + nil, 99, 87, 90, 91, nil, 92, 94, 93, 95, + nil, nil, nil, nil, 88, 98, 441, 445, nil, nil, + 442, nil, 660, nil, 89, 103, 104, nil, 166, 167, + nil, 163, 145, 146, 147, 154, 151, 153, nil, nil, + 148, 149, nil, nil, nil, 168, 169, 155, 156, nil, + nil, nil, nil, nil, 276, nil, nil, nil, nil, nil, + nil, nil, 160, 159, nil, 144, 165, 162, 161, 170, + 157, 158, 152, 150, 142, 164, 143, 448, 452, 171, + nil, 447, nil, nil, nil, nil, nil, nil, nil, 166, + 167, nil, 163, 145, 146, 147, 154, 151, 153, nil, + nil, 148, 149, nil, nil, nil, 168, 169, 155, 156, + nil, nil, nil, nil, nil, 276, nil, nil, nil, nil, + nil, nil, nil, 160, 159, nil, 144, 165, 162, 161, + 170, 157, 158, 152, 150, 142, 164, 143, 493, 445, + 171, nil, 494, nil, nil, nil, nil, nil, nil, nil, + 166, 167, nil, 163, 145, 146, 147, 154, 151, 153, + nil, nil, 148, 149, nil, nil, nil, 168, 169, 155, + 156, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 160, 159, nil, 144, 165, 162, + 161, 170, 157, 158, 152, 150, 142, 164, 143, 632, + 445, 171, nil, 633, nil, nil, nil, nil, nil, nil, + nil, 166, 167, nil, 163, 145, 146, 147, 154, 151, + 153, nil, nil, 148, 149, nil, nil, nil, 168, 169, + 155, 156, nil, nil, nil, nil, nil, 276, nil, nil, + nil, nil, nil, nil, nil, 160, 159, nil, 144, 165, + 162, 161, 170, 157, 158, 152, 150, 142, 164, 143, + 634, 452, 171, nil, 635, nil, nil, nil, nil, nil, + nil, nil, 166, 167, nil, 163, 145, 146, 147, 154, + 151, 153, nil, nil, 148, 149, nil, nil, nil, 168, + 169, 155, 156, nil, nil, nil, nil, nil, 276, nil, + nil, nil, nil, nil, nil, nil, 160, 159, nil, 144, + 165, 162, 161, 170, 157, 158, 152, 150, 142, 164, + 143, 691, 445, 171, nil, 692, nil, nil, nil, nil, + nil, nil, nil, 166, 167, nil, 163, 145, 146, 147, + 154, 151, 153, nil, nil, 148, 149, nil, nil, nil, + 168, 169, 155, 156, nil, nil, nil, nil, nil, 276, + nil, nil, nil, nil, nil, nil, nil, 160, 159, nil, + 144, 165, 162, 161, 170, 157, 158, 152, 150, 142, + 164, 143, 694, 452, 171, nil, 695, nil, nil, nil, + nil, nil, nil, nil, 166, 167, nil, 163, 145, 146, + 147, 154, 151, 153, nil, nil, 148, 149, nil, nil, + nil, 168, 169, 155, 156, nil, nil, nil, nil, nil, + 276, nil, nil, nil, nil, nil, nil, nil, 160, 159, + nil, 144, 165, 162, 161, 170, 157, 158, 152, 150, + 142, 164, 143, 632, 445, 171, nil, 633, nil, nil, + nil, nil, nil, nil, nil, 166, 167, nil, 163, 145, + 146, 147, 154, 151, 153, nil, nil, 148, 149, nil, + nil, nil, 168, 169, 155, 156, nil, nil, nil, nil, + nil, 276, nil, nil, nil, nil, nil, nil, nil, 160, + 159, nil, 144, 165, 162, 161, 170, 157, 158, 152, + 150, 142, 164, 143, 634, 452, 171, nil, 635, nil, + nil, nil, nil, nil, nil, nil, 166, 167, nil, 163, + 145, 146, 147, 154, 151, 153, nil, nil, 148, 149, + nil, nil, nil, 168, 169, 155, 156, nil, nil, nil, + nil, nil, 276, nil, nil, nil, nil, nil, nil, nil, + 160, 159, nil, 144, 165, 162, 161, 170, 157, 158, + 152, 150, 142, 164, 143, 756, 445, 171, nil, 757, + nil, nil, nil, nil, nil, nil, nil, 166, 167, nil, + 163, 145, 146, 147, 154, 151, 153, nil, nil, 148, + 149, nil, nil, nil, 168, 169, 155, 156, nil, nil, + nil, nil, nil, 276, nil, nil, nil, nil, nil, nil, + nil, 160, 159, nil, 144, 165, 162, 161, 170, 157, + 158, 152, 150, 142, 164, 143, 758, 452, 171, nil, + 759, nil, nil, nil, nil, nil, nil, nil, 166, 167, + nil, 163, 145, 146, 147, 154, 151, 153, nil, nil, + 148, 149, nil, nil, nil, 168, 169, 155, 156, nil, + nil, nil, nil, nil, 276, nil, nil, nil, nil, nil, + nil, nil, 160, 159, nil, 144, 165, 162, 161, 170, + 157, 158, 152, 150, 142, 164, 143, 761, 452, 171, + nil, 762, nil, nil, nil, nil, nil, nil, nil, 166, + 167, nil, 163, 145, 146, 147, 154, 151, 153, nil, + nil, 148, 149, nil, nil, nil, 168, 169, 155, 156, + nil, nil, nil, nil, nil, 276, nil, nil, nil, nil, + nil, nil, nil, 160, 159, nil, 144, 165, 162, 161, + 170, 157, 158, 152, 150, 142, 164, 143, 493, 445, + 171, nil, 494, nil, nil, nil, nil, nil, nil, nil, + 166, 167, nil, 163, 145, 146, 147, 154, 151, 153, + nil, nil, 148, 149, nil, nil, nil, 168, 169, 155, + 156, nil, nil, nil, nil, nil, 276, nil, nil, nil, + nil, nil, nil, nil, 160, 159, nil, 144, 165, 162, + 161, 170, 157, 158, 152, 150, 142, 164, 143, 791, + 445, 171, nil, 792, nil, nil, nil, nil, nil, nil, + nil, 166, 167, nil, 163, 145, 146, 147, 154, 151, + 153, nil, nil, 148, 149, nil, nil, nil, 168, 169, + 155, 156, nil, nil, nil, nil, nil, 276, nil, nil, + nil, nil, nil, nil, nil, 160, 159, nil, 144, 165, + 162, 161, 170, 157, 158, 152, 150, 142, 164, 143, + 794, 452, 171, nil, 793, nil, nil, nil, nil, nil, + nil, nil, 166, 167, nil, 163, 145, 146, 147, 154, + 151, 153, nil, nil, 148, 149, nil, nil, nil, 168, + 169, 155, 156, nil, nil, nil, nil, nil, 276, nil, + nil, nil, nil, nil, nil, nil, 160, 159, nil, 144, + 165, 162, 161, 170, 157, 158, 152, 150, 142, 164, + 143, 1156, 452, 171, nil, 1155, nil, nil, nil, nil, + nil, nil, nil, 166, 167, nil, 163, 145, 146, 147, + 154, 151, 153, nil, nil, 148, 149, nil, nil, nil, + 168, 169, 155, 156, nil, nil, nil, nil, nil, 276, + nil, nil, nil, nil, nil, nil, nil, 160, 159, nil, + 144, 165, 162, 161, 170, 157, 158, 152, 150, 142, + 164, 143, 1159, 445, 171, nil, 1160, nil, nil, nil, + nil, nil, nil, nil, 166, 167, nil, 163, 145, 146, + 147, 154, 151, 153, nil, nil, 148, 149, nil, nil, + nil, 168, 169, 155, 156, nil, nil, nil, nil, nil, + 276, nil, nil, nil, nil, nil, nil, nil, 160, 159, + nil, 144, 165, 162, 161, 170, 157, 158, 152, 150, + 142, 164, 143, 1161, 452, 171, nil, 1162, nil, nil, + nil, nil, nil, nil, nil, 166, 167, nil, 163, 145, + 146, 147, 154, 151, 153, nil, nil, 148, 149, nil, + nil, nil, 168, 169, 155, 156, nil, nil, nil, nil, + nil, 276, nil, nil, nil, nil, nil, nil, nil, 160, + 159, nil, 144, 165, 162, 161, 170, 157, 158, 152, + 150, 142, 164, 143, nil, 724, 171, 721, 720, 719, + 729, 722, 724, nil, 721, 720, 719, 729, 722, 724, + 732, 721, 720, 719, 729, 722, nil, 732, nil, nil, + nil, nil, nil, nil, 732, nil, nil, nil, nil, nil, + nil, nil, 727, nil, nil, nil, nil, nil, nil, 727, + nil, nil, nil, 740, 739, nil, 727, nil, 733, nil, + 740, 739, nil, nil, nil, 733, nil, 740, 739, nil, + nil, nil, 733 ] + +racc_action_check = [ + 105, 457, 457, 584, 584, 1, 361, 105, 105, 105, + 923, 353, 105, 105, 105, 18, 105, 28, 945, 929, + 5, 21, 18, 354, 105, 5, 105, 105, 105, 701, + 701, 18, 734, 399, 362, 365, 105, 105, 754, 105, + 105, 105, 105, 105, 973, 1000, 1002, 1058, 1059, 817, + 734, 570, 134, 1172, 1062, 371, 923, 134, 134, 371, + 66, 945, 21, 1172, 756, 757, 105, 105, 105, 105, + 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, + 18, 28, 105, 105, 105, 3, 105, 105, 561, 817, + 105, 863, 898, 105, 105, 457, 105, 584, 105, 399, + 105, 929, 105, 105, 28, 105, 105, 105, 105, 105, + 1123, 105, 108, 105, 1159, 361, 669, 580, 580, 108, + 108, 108, 1024, 701, 108, 108, 108, 105, 108, 353, + 105, 105, 105, 105, 353, 105, 108, 105, 108, 108, + 108, 354, 105, 362, 365, 105, 354, 66, 108, 108, + 1160, 108, 108, 108, 108, 108, 754, 1161, 1181, 754, + 570, 754, 973, 1000, 1002, 1058, 1059, 973, 1000, 1002, + 1058, 1059, 1062, 756, 757, 758, 759, 1062, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 561, 1162, 108, 108, 108, 561, 108, 108, + 863, 898, 108, 669, 1024, 108, 108, 644, 108, 9, + 108, 580, 108, 595, 108, 108, 580, 108, 108, 108, + 108, 108, 447, 108, 644, 108, 1004, 232, 1123, 447, + 447, 447, 1159, 1123, 1161, 447, 447, 1159, 447, 108, + 758, 759, 108, 108, 108, 108, 447, 108, 233, 108, + 321, 937, 663, 394, 108, 400, 663, 108, 447, 447, + 691, 447, 447, 447, 447, 447, 45, 45, 1160, 937, + 1162, 12, 1004, 1160, 692, 1161, 1181, 595, 595, 235, + 1161, 1181, 326, 326, 758, 759, 232, 595, 447, 447, + 447, 447, 447, 447, 447, 447, 447, 447, 447, 447, + 447, 447, 14, 26, 447, 447, 447, 233, 447, 821, + 26, 1162, 447, 821, 321, 447, 1162, 394, 394, 394, + 447, 400, 447, 597, 447, 447, 691, 447, 447, 447, + 447, 447, 426, 447, 448, 447, 15, 321, 235, 463, + 692, 448, 448, 448, 45, 45, 643, 448, 448, 447, + 448, 17, 447, 447, 818, 447, 51, 447, 448, 448, + 326, 326, 852, 51, 447, 24, 691, 447, 26, 691, + 448, 448, 51, 448, 448, 448, 448, 448, 39, 380, + 692, 691, 643, 692, 694, 42, 380, 597, 597, 513, + 818, 426, 632, 1030, 301, 692, 50, 597, 463, 301, + 448, 448, 448, 448, 448, 448, 448, 448, 448, 448, + 448, 448, 448, 448, 564, 824, 448, 448, 448, 231, + 448, 51, 564, 213, 448, 824, 231, 448, 852, 633, + 1037, 234, 448, 791, 448, 231, 448, 448, 395, 448, + 448, 448, 448, 448, 380, 448, 448, 448, 236, 694, + 694, 632, 237, 513, 513, 513, 396, 1030, 1030, 1030, + 19, 448, 397, 824, 448, 448, 369, 448, 852, 448, + 513, 852, 398, 634, 1030, 824, 448, 16, 16, 448, + 634, 634, 634, 852, 231, 634, 634, 634, 633, 634, + 694, 241, 791, 694, 1037, 1037, 686, 634, 634, 634, + 634, 634, 395, 395, 395, 694, 370, 19, 686, 634, + 634, 1037, 634, 634, 634, 634, 634, 275, 369, 19, + 396, 396, 396, 401, 642, 369, 397, 397, 397, 642, + 369, 792, 289, 642, 369, 814, 398, 398, 398, 634, + 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, + 634, 634, 634, 369, 40, 634, 634, 634, 370, 634, + 634, 344, 290, 634, 344, 370, 634, 634, 293, 634, + 370, 634, 914, 634, 370, 634, 634, 305, 634, 634, + 634, 634, 634, 369, 634, 634, 634, 401, 401, 401, + 792, 313, 381, 370, 814, 314, 48, 48, 313, 381, + 634, 40, 314, 634, 634, 634, 634, 313, 634, 382, + 634, 314, 635, 40, 306, 634, 382, 41, 634, 635, + 635, 635, 308, 370, 635, 635, 635, 315, 635, 352, + 352, 914, 48, 48, 315, 383, 635, 309, 635, 635, + 635, 358, 383, 315, 345, 310, 358, 345, 635, 635, + 330, 635, 635, 635, 635, 635, 313, 381, 316, 317, + 314, 331, 384, 385, 41, 319, 317, 902, 331, 384, + 385, 1008, 902, 1008, 382, 317, 41, 331, 635, 635, + 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, + 635, 635, 315, 1028, 635, 635, 635, 330, 635, 635, + 383, 320, 635, 1028, 386, 635, 635, 325, 635, 330, + 635, 386, 635, 348, 635, 635, 348, 635, 635, 635, + 635, 635, 793, 635, 317, 635, 331, 384, 385, 793, + 793, 793, 910, 646, 646, 793, 793, 910, 793, 635, + 327, 1028, 635, 635, 635, 635, 793, 635, 387, 635, + 742, 742, 334, 1028, 635, 387, 336, 635, 793, 793, + 342, 793, 793, 793, 793, 793, 346, 441, 347, 386, + 770, 363, 770, 770, 770, 770, 770, 349, 363, 388, + 8, 8, 8, 8, 8, 770, 388, 363, 793, 793, + 793, 793, 793, 793, 793, 793, 793, 793, 793, 793, + 793, 793, 359, 390, 793, 793, 793, 770, 793, 360, + 390, 364, 793, 387, 441, 793, 770, 770, 770, 770, + 793, 366, 793, 770, 793, 793, 441, 793, 793, 793, + 793, 793, 442, 793, 794, 793, 363, 707, 375, 85, + 707, 794, 794, 794, 388, 868, 868, 794, 794, 793, + 794, 85, 793, 793, 409, 793, 415, 793, 794, 794, + 417, 85, 1112, 770, 793, 1112, 418, 793, 390, 420, + 794, 794, 423, 794, 794, 794, 794, 794, 427, 442, + 1003, 1003, 1015, 373, 1015, 1015, 1015, 1015, 1015, 470, + 373, 442, 882, 437, 882, 882, 882, 1015, 882, 373, + 794, 794, 794, 794, 794, 794, 794, 794, 794, 794, + 794, 794, 794, 794, 1132, 1132, 794, 794, 794, 1015, + 794, 470, 471, 439, 794, 470, 470, 794, 1015, 1015, + 1015, 1015, 794, 440, 794, 1015, 794, 794, 449, 794, + 794, 794, 794, 794, 617, 794, 794, 794, 373, 459, + 425, 472, 473, 474, 471, 530, 573, 425, 471, 471, + 475, 794, 530, 573, 794, 794, 425, 794, 498, 794, + 1054, 530, 573, 499, 500, 1015, 794, 1054, 504, 794, + 2, 2, 2, 2, 2, 2, 1054, 520, 521, 2, + 2, 617, 524, 526, 2, 761, 2, 2, 2, 2, + 2, 2, 2, 617, 531, 534, 543, 544, 2, 2, + 2, 2, 2, 2, 2, 425, 545, 2, 546, 558, + 530, 573, 562, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 1054, 2, 2, 2, 695, + 2, 2, 2, 2, 2, 762, 695, 761, 563, 1060, + 565, 695, 762, 582, 761, 695, 1060, 762, 592, 761, + 600, 762, 602, 761, 2, 1060, 609, 2, 618, 623, + 2, 2, 1116, 628, 2, 636, 2, 637, 639, 1116, + 2, 662, 761, 665, 666, 668, 588, 588, 1116, 2, + 588, 588, 588, 674, 2, 2, 2, 2, 675, 2, + 2, 2, 2, 676, 695, 678, 680, 2, 2, 688, + 762, 690, 761, 693, 1060, 2, 696, 2, 2, 2, + 697, 700, 2, 2, 35, 35, 35, 35, 35, 35, + 702, 711, 712, 35, 35, 713, 715, 1116, 35, 716, + 35, 35, 35, 35, 35, 35, 35, 23, 717, 726, + 738, 741, 35, 35, 35, 35, 35, 35, 35, 744, + 1052, 35, 1052, 1052, 1052, 750, 1052, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 751, + 35, 35, 35, 755, 35, 35, 35, 35, 35, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 764, 23, 23, 768, 788, 23, 23, 790, 35, 799, + 815, 35, 865, 826, 35, 35, 838, 841, 35, 842, + 35, 23, 865, 23, 35, 23, 23, 851, 23, 23, + 23, 23, 23, 35, 23, 855, 858, 859, 35, 35, + 35, 35, 864, 35, 35, 35, 35, 880, 881, 883, + 889, 35, 35, 892, 23, 865, 865, 899, 901, 35, + 865, 35, 35, 35, 905, 906, 35, 35, 132, 132, + 132, 132, 132, 132, 907, 908, 912, 132, 132, 913, + 924, 925, 132, 928, 132, 132, 132, 132, 132, 132, + 132, 304, 304, 304, 304, 304, 132, 132, 132, 132, + 132, 132, 132, 930, 938, 132, 939, 941, 942, 953, + 430, 132, 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 954, 132, 132, 132, 955, 132, 132, + 132, 132, 132, 430, 430, 430, 430, 430, 430, 430, + 430, 430, 430, 430, 957, 430, 430, 958, 959, 430, + 430, 961, 132, 962, 963, 132, 964, 979, 132, 132, + 980, 982, 132, 985, 132, 430, 986, 430, 132, 430, + 430, 988, 430, 430, 430, 430, 430, 132, 430, 989, + 991, 994, 132, 132, 132, 132, 1012, 132, 132, 132, + 132, 1018, 1022, 1023, 1026, 132, 132, 1029, 430, 1051, + 430, 1055, 1061, 132, 1079, 132, 132, 132, 1080, 1090, + 132, 132, 215, 215, 215, 215, 215, 215, 1093, 1096, + 1102, 215, 215, 1105, 1106, 1107, 215, 1108, 215, 215, + 215, 215, 215, 215, 215, 341, 341, 341, 341, 341, + 215, 215, 215, 215, 215, 215, 215, 1110, 1119, 215, + 1124, 1125, 1126, 1127, 436, 215, 215, 215, 215, 215, + 215, 215, 215, 215, 215, 215, 215, 1128, 215, 215, + 215, 1129, 215, 215, 215, 215, 215, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 1138, 436, + 436, 1140, 1141, 436, 436, 1155, 215, 1156, 1158, 215, + 1040, 1170, 215, 215, 1174, 1176, 215, 1177, 215, 436, + 1040, 436, 215, 436, 436, 1178, 436, 436, 436, 436, + 436, 215, 436, 1179, 1182, 1192, 215, 215, 215, 215, + nil, 215, 215, 215, 215, nil, nil, nil, nil, 215, + 215, nil, 436, 1040, 1040, nil, nil, 215, 1040, 215, + 215, 215, nil, nil, 215, 215, 240, 240, 240, 240, + 240, 240, nil, nil, nil, 240, 240, nil, nil, nil, + 240, nil, 240, 240, 240, 240, 240, 240, 240, 518, + 518, 518, 518, 518, 240, 240, 240, 240, 240, 240, + 240, nil, 1154, 240, 1154, 1154, 1154, nil, 1154, 240, + 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, + 240, nil, 240, 240, 240, nil, 240, 240, 240, 240, + 240, 287, 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, nil, 287, 287, nil, nil, 287, 287, nil, + 240, nil, nil, 240, nil, nil, 240, 240, nil, nil, + 240, nil, 240, 287, nil, 287, 240, 287, 287, nil, + 287, 287, 287, 287, 287, 240, 287, nil, nil, nil, + 240, 240, 240, 240, nil, 240, 240, 240, 240, nil, + nil, nil, nil, 240, 240, nil, 287, nil, nil, nil, + nil, 240, nil, 240, 240, 240, nil, nil, 240, 240, + 307, 307, 307, 307, 307, 307, nil, nil, nil, 307, + 307, nil, nil, nil, 307, nil, 307, 307, 307, 307, + 307, 307, 307, nil, nil, nil, nil, nil, 307, 307, + 307, 307, 307, 307, 307, nil, nil, 307, nil, nil, + nil, nil, nil, 307, 307, 307, 307, 307, 307, 307, + 307, 307, 307, 307, 307, nil, 307, 307, 307, nil, + 307, 307, 307, 307, 307, 489, 489, 489, 489, 489, + 489, 489, 489, 489, 489, 489, nil, 489, 489, nil, + nil, 489, 489, nil, 307, nil, nil, 307, nil, nil, + 307, 307, nil, nil, 307, nil, 307, 489, nil, 489, + 307, 489, 489, nil, 489, 489, 489, 489, 489, 307, + 489, nil, nil, nil, 307, 307, 307, 307, nil, 307, + 307, 307, 307, nil, nil, nil, nil, 307, 307, 489, + 489, nil, nil, nil, nil, 307, nil, 307, 307, 307, + nil, nil, 307, 307, 312, 312, 312, 312, 312, 312, + nil, nil, nil, 312, 312, nil, nil, nil, 312, nil, + 312, 312, 312, 312, 312, 312, 312, nil, nil, nil, + nil, nil, 312, 312, 312, 312, 312, 312, 312, nil, + nil, 312, nil, nil, nil, nil, nil, 312, 312, 312, + 312, 312, 312, 312, 312, 312, 312, 312, 312, nil, + 312, 312, 312, nil, 312, 312, 312, 312, 312, 541, + 541, 541, 541, 541, 541, 541, 541, 541, 541, 541, + nil, 541, 541, nil, nil, 541, 541, nil, 312, nil, + nil, 312, nil, nil, 312, 312, nil, nil, 312, nil, + 312, 541, nil, 541, 312, 541, 541, nil, 541, 541, + 541, 541, 541, 312, 541, nil, nil, nil, 312, 312, + 312, 312, nil, 312, 312, 312, 312, nil, nil, nil, + nil, 312, 312, nil, 541, nil, nil, nil, nil, 312, + nil, 312, 312, 312, nil, nil, 312, 312, 340, 340, + 340, 340, 340, 340, nil, nil, nil, 340, 340, nil, + nil, nil, 340, nil, 340, 340, 340, 340, 340, 340, + 340, nil, nil, nil, nil, nil, 340, 340, 340, 340, + 340, 340, 340, nil, nil, 340, nil, nil, nil, nil, + nil, 340, 340, 340, 340, 340, 340, 340, 340, 340, + 340, 340, 340, nil, 340, 340, 340, nil, 340, 340, + 340, 340, 340, 796, 796, 796, 796, 796, 796, 796, + 796, 796, 796, 796, nil, 796, 796, nil, nil, 796, + 796, nil, 340, nil, nil, 340, nil, nil, 340, 340, + nil, nil, 340, nil, 340, 796, nil, 796, 340, 796, + 796, nil, 796, 796, 796, 796, 796, 340, 796, nil, + nil, nil, 340, 340, 340, 340, nil, 340, 340, 340, + 340, nil, nil, nil, nil, 340, 340, nil, 796, nil, + nil, nil, nil, 340, nil, 340, 340, 340, nil, nil, + 340, 340, 356, 356, 356, 356, 356, 356, nil, nil, + nil, 356, 356, nil, nil, nil, 356, nil, 356, 356, + 356, 356, 356, 356, 356, nil, nil, nil, nil, nil, + 356, 356, 356, 356, 356, 356, 356, nil, nil, 356, + nil, nil, nil, nil, nil, 356, 356, 356, 356, 356, + 356, 356, 356, 356, 356, 356, 356, nil, 356, 356, + 356, nil, 356, 356, 356, 356, 356, 949, 949, 949, + 949, 949, 949, 949, 949, 949, 949, 949, nil, 949, + 949, nil, nil, 949, 949, nil, 356, nil, nil, 356, + nil, nil, 356, 356, nil, nil, 356, nil, 356, 949, + nil, 949, 356, 949, 949, nil, 949, 949, 949, 949, + 949, 356, 949, nil, nil, nil, 356, 356, 356, 356, + nil, 356, 356, 356, 356, nil, nil, nil, nil, 356, + 356, nil, 949, nil, nil, nil, nil, 356, nil, 356, + 356, 356, nil, nil, 356, 356, 357, 357, 357, 357, + 357, 357, nil, nil, nil, 357, 357, nil, nil, nil, + 357, nil, 357, 357, 357, 357, 357, 357, 357, nil, + nil, nil, nil, nil, 357, 357, 357, 357, 357, 357, + 357, nil, 727, 357, 727, 727, 727, nil, 727, 357, + 357, 357, 357, 357, 357, 357, 357, 357, 357, 357, + 357, nil, 357, 357, 357, nil, 357, 357, 357, 357, + 357, 878, nil, 878, 878, 878, nil, 878, nil, 727, + nil, 996, nil, 996, 996, 996, nil, 996, 727, nil, + 357, nil, nil, 357, nil, nil, 357, 357, nil, nil, + 357, 995, 357, 995, 995, 995, 357, 995, 878, nil, + nil, nil, nil, nil, nil, 357, nil, 878, 996, nil, + 357, 357, 357, 357, nil, 357, 357, 357, 357, nil, + nil, nil, nil, 357, 357, nil, nil, nil, 995, nil, + nil, 357, nil, 357, 357, 357, nil, 995, 357, 357, + 557, 557, 557, 557, 557, 557, nil, nil, nil, 557, + 557, nil, nil, nil, 557, nil, 557, 557, 557, 557, + 557, 557, 557, nil, nil, nil, nil, nil, 557, 557, + 557, 557, 557, 557, 557, nil, nil, 557, nil, nil, + nil, nil, nil, 557, 557, 557, 557, 557, 557, 557, + 557, 557, 557, 557, 557, nil, 557, 557, 557, nil, + 557, 557, 557, 557, 557, 332, 332, 332, 332, 332, + 332, 332, 332, 332, 332, 332, nil, 332, 332, nil, + nil, 332, 332, nil, 557, nil, nil, 557, nil, nil, + 557, 557, nil, 485, 557, nil, 557, 332, nil, 332, + 557, 332, 332, nil, 332, 332, 332, 332, 332, 557, + 332, nil, nil, nil, 557, 557, 557, 557, nil, 557, + 557, 557, 557, nil, nil, 485, nil, 557, 557, 485, + 485, nil, 485, 485, nil, 557, nil, 557, 557, 557, + nil, nil, 557, 557, 560, 560, 560, 560, 560, 560, + nil, nil, nil, 560, 560, nil, nil, nil, 560, nil, + 560, 560, 560, 560, 560, 560, 560, nil, nil, nil, + nil, nil, 560, 560, 560, 560, 560, 560, 560, nil, + nil, 560, nil, nil, nil, nil, nil, 560, 560, 560, + 560, 560, 560, 560, 560, 560, 560, 560, 560, nil, + 560, 560, 560, nil, 560, 560, 560, 560, 560, 333, + 333, 333, 333, 333, 333, 333, 333, 333, 333, 333, + nil, 333, 333, nil, nil, 333, 333, nil, 560, nil, + nil, 560, nil, nil, 560, 560, nil, 486, 560, nil, + 560, 333, nil, 333, 560, 333, 333, nil, 333, 333, + 333, 333, 333, 560, 333, nil, nil, nil, 560, 560, + 560, 560, nil, 560, 560, 560, 560, nil, nil, 486, + nil, 560, 560, 486, 486, nil, 486, 486, nil, 560, + nil, 560, 560, 560, nil, nil, 560, 560, 581, 581, + 581, 581, 581, 581, nil, nil, nil, 581, 581, nil, + nil, nil, 581, nil, 581, 581, 581, 581, 581, 581, + 581, nil, nil, nil, nil, nil, 581, 581, 581, 581, + 581, 581, 581, nil, nil, 581, nil, nil, nil, nil, + nil, 581, 581, 581, 581, 581, 581, 581, 581, 581, + 581, 581, 581, nil, 581, 581, 581, nil, 581, 581, + 581, 581, 581, 468, 468, 468, 468, 468, 468, 468, + 468, 468, 468, 468, nil, 468, 468, nil, nil, 468, + 468, nil, 581, nil, nil, 581, nil, nil, 581, 581, + nil, nil, 581, nil, 581, 468, nil, 468, 581, 468, + 468, nil, 468, 468, 468, 468, 468, 581, 468, nil, + nil, nil, 581, 581, 581, 581, nil, 581, 581, 581, + 581, nil, nil, nil, nil, 581, 581, nil, 1130, nil, + 1130, 1130, 1130, 581, 1130, 581, 581, 581, nil, nil, + 581, 581, 760, 760, 760, 760, 760, 760, nil, nil, + nil, 760, 760, nil, nil, nil, 760, nil, 760, 760, + 760, 760, 760, 760, 760, 1130, nil, nil, nil, nil, + 760, 760, 760, 760, 760, 760, 760, nil, nil, 760, + nil, nil, nil, nil, nil, 760, 760, 760, 760, 760, + 760, 760, 760, 760, 760, 760, 760, nil, 760, 760, + 760, nil, 760, 760, 760, 760, 760, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, 469, nil, 469, + 469, nil, nil, 469, 469, nil, 760, nil, nil, 760, + nil, nil, 760, 760, nil, nil, 760, nil, 760, 469, + nil, 469, 760, 469, 469, nil, 469, 469, 469, 469, + 469, 760, 469, nil, nil, nil, 760, 760, 760, 760, + nil, 760, 760, 760, 760, nil, nil, nil, nil, 760, + 760, nil, 1131, nil, 1131, 1131, 1131, 760, 1131, 760, + 760, 760, nil, nil, 760, 760, 765, 765, 765, 765, + 765, 765, nil, nil, nil, 765, 765, nil, nil, nil, + 765, nil, 765, 765, 765, 765, 765, 765, 765, 1131, + nil, nil, nil, nil, 765, 765, 765, 765, 765, 765, + 765, nil, nil, 765, nil, nil, nil, nil, nil, 765, + 765, 765, 765, 765, 765, 765, 765, 765, 765, 765, + 765, nil, 765, 765, 765, nil, 765, 765, 765, 765, + 765, 479, 479, 479, 479, 479, 479, 479, nil, nil, + 479, 479, nil, nil, nil, nil, nil, 479, 479, nil, + 765, nil, nil, 765, nil, nil, 765, 765, nil, nil, + 765, nil, 765, 479, nil, 479, 765, 479, 479, nil, + 479, 479, 479, 479, 479, 765, 479, nil, nil, nil, + 765, 765, 765, 765, nil, 765, 765, 765, 765, nil, + nil, nil, nil, 765, 765, nil, nil, nil, nil, nil, + nil, 765, nil, 765, 765, 765, nil, nil, 765, 765, + 769, 769, 769, 769, 769, 769, nil, nil, nil, 769, + 769, nil, nil, nil, 769, nil, 769, 769, 769, 769, + 769, 769, 769, nil, nil, nil, nil, nil, 769, 769, + 769, 769, 769, 769, 769, nil, nil, 769, nil, nil, + nil, nil, nil, 769, 769, 769, 769, 769, 769, 769, + 769, 769, 769, 769, 769, nil, 769, 769, 769, nil, + 769, 769, 769, 769, 769, 480, 480, 480, 480, 480, + 480, 480, nil, nil, 480, 480, nil, nil, nil, nil, + nil, 480, 480, nil, 769, nil, nil, 769, nil, nil, + 769, 769, nil, nil, 769, nil, 769, 480, nil, 480, + 769, 480, 480, nil, 480, 480, 480, 480, 480, 769, + 480, nil, nil, nil, 769, 769, 769, 769, nil, 769, + 769, 769, 769, nil, nil, nil, nil, 769, 769, nil, + nil, nil, nil, nil, nil, 769, nil, 769, 769, 769, + nil, nil, 769, 769, 779, 779, 779, 779, 779, 779, + nil, nil, nil, 779, 779, nil, nil, nil, 779, nil, + 779, 779, 779, 779, 779, 779, 779, nil, nil, nil, + nil, nil, 779, 779, 779, 779, 779, 779, 779, nil, + nil, 779, nil, nil, nil, nil, nil, 779, 779, 779, + 779, 779, 779, 779, 779, 779, 779, 779, 779, nil, + 779, 779, 779, nil, 779, 779, 779, 779, 779, 481, + 481, 481, 481, 481, 481, 481, nil, nil, 481, 481, + nil, nil, nil, nil, nil, 481, 481, nil, 779, nil, + nil, 779, nil, nil, 779, 779, nil, nil, 779, nil, + 779, 481, nil, 481, 779, 481, 481, nil, 481, 481, + 481, 481, 481, 779, 481, nil, nil, nil, 779, 779, + 779, 779, nil, 779, 779, 779, 779, nil, nil, nil, + nil, 779, 779, nil, nil, nil, nil, nil, nil, 779, + nil, 779, 779, 779, nil, nil, 779, 779, 846, 846, + 846, 846, 846, 846, nil, nil, nil, 846, 846, nil, + nil, nil, 846, nil, 846, 846, 846, 846, 846, 846, + 846, nil, nil, nil, nil, nil, 846, 846, 846, 846, + 846, 846, 846, nil, nil, 846, nil, nil, nil, nil, + nil, 846, 846, 846, 846, 846, 846, 846, 846, 846, + 846, 846, 846, nil, 846, 846, 846, nil, 846, 846, + 846, 846, 846, 482, 482, 482, 482, 482, 482, 482, + nil, nil, 482, 482, nil, nil, nil, nil, nil, 482, + 482, nil, 846, nil, nil, 846, nil, nil, 846, 846, + nil, nil, 846, nil, 846, 482, nil, 482, 846, 482, + 482, nil, 482, 482, 482, 482, 482, 846, 482, nil, + nil, nil, 846, 846, 846, 846, nil, 846, 846, 846, + 846, nil, nil, nil, nil, 846, 846, nil, nil, nil, + nil, nil, nil, 846, nil, 846, 846, 846, nil, nil, + 846, 846, 857, 857, 857, 857, 857, 857, nil, nil, + nil, 857, 857, nil, nil, nil, 857, nil, 857, 857, + 857, 857, 857, 857, 857, nil, nil, nil, nil, nil, + 857, 857, 857, 857, 857, 857, 857, nil, nil, 857, + nil, nil, nil, nil, nil, 857, 857, 857, 857, 857, + 857, 857, 857, 857, 857, 857, 857, nil, 857, 857, + 857, nil, 857, 857, 857, 857, 857, 483, 483, 483, + 483, 483, 483, 483, nil, nil, 483, 483, nil, nil, + nil, nil, nil, 483, 483, nil, 857, nil, nil, 857, + nil, nil, 857, 857, nil, nil, 857, nil, 857, 483, + nil, 483, 857, 483, 483, nil, 483, 483, 483, 483, + 483, 857, 483, nil, nil, nil, 857, 857, 857, 857, + nil, 857, 857, 857, 857, nil, nil, nil, nil, 857, + 857, nil, nil, nil, nil, nil, nil, 857, nil, 857, + 857, 857, nil, nil, 857, 857, 897, 897, 897, 897, + 897, 897, nil, nil, nil, 897, 897, nil, nil, nil, + 897, nil, 897, 897, 897, 897, 897, 897, 897, nil, + nil, nil, nil, nil, 897, 897, 897, 897, 897, 897, + 897, nil, nil, 897, nil, nil, nil, nil, nil, 897, + 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, + 897, nil, 897, 897, 897, nil, 897, 897, 897, 897, + 897, 484, 484, 484, 484, 484, 484, 484, nil, nil, + 484, 484, nil, nil, nil, nil, nil, 484, 484, nil, + 897, nil, nil, 897, nil, nil, 897, 897, nil, nil, + 897, nil, 897, 484, nil, 484, 897, 484, 484, nil, + 484, 484, 484, 484, 484, 897, 484, nil, nil, nil, + 897, 897, 897, 897, nil, 897, 897, 897, 897, nil, + nil, nil, nil, 897, 897, nil, nil, nil, nil, nil, + nil, 897, nil, 897, 897, 897, nil, nil, 897, 897, + 903, 903, 903, 903, 903, 903, nil, nil, nil, 903, + 903, nil, nil, nil, 903, nil, 903, 903, 903, 903, + 903, 903, 903, nil, nil, nil, nil, nil, 903, 903, + 903, 903, 903, 903, 903, nil, nil, 903, nil, nil, + nil, nil, nil, 903, 903, 903, 903, 903, 903, 903, + 903, 903, 903, 903, 903, nil, 903, 903, 903, nil, + 903, 903, 903, 903, 903, 487, 487, 487, 487, 487, + 487, 487, nil, nil, 487, 487, nil, nil, nil, nil, + nil, 487, 487, nil, 903, nil, nil, 903, nil, nil, + 903, 903, nil, nil, 903, nil, 903, 487, nil, 487, + 903, 487, 487, nil, 487, 487, 487, 487, 487, 903, + 487, nil, nil, nil, 903, 903, 903, 903, nil, 903, + 903, 903, 903, nil, nil, nil, nil, 903, 903, nil, + nil, nil, nil, nil, nil, 903, nil, 903, 903, 903, + nil, nil, 903, 903, 950, 950, 950, 950, 950, 950, + nil, nil, nil, 950, 950, nil, nil, nil, 950, nil, + 950, 950, 950, 950, 950, 950, 950, nil, nil, nil, + nil, nil, 950, 950, 950, 950, 950, 950, 950, nil, + nil, 950, nil, nil, nil, nil, nil, 950, 950, 950, + 950, 950, 950, 950, 950, 950, 950, 950, 950, nil, + 950, 950, 950, nil, 950, 950, 950, 950, 950, 488, + 488, 488, 488, 488, 488, 488, 488, nil, 488, 488, + nil, nil, nil, nil, nil, 488, 488, nil, 950, nil, + nil, 950, nil, nil, 950, 950, nil, nil, 950, nil, + 950, 488, nil, 488, 950, 488, 488, nil, 488, 488, + 488, 488, 488, 950, 488, nil, nil, nil, 950, 950, + 950, 950, nil, 950, 950, 950, 950, nil, nil, nil, + nil, 950, 950, nil, nil, nil, nil, nil, nil, 950, + nil, 950, 950, 950, nil, nil, 950, 950, 970, 970, + 970, 970, 970, 970, nil, nil, nil, 970, 970, nil, + nil, nil, 970, nil, 970, 970, 970, 970, 970, 970, + 970, nil, nil, nil, nil, nil, 970, 970, 970, 970, + 970, 970, 970, nil, nil, 970, nil, nil, nil, nil, + nil, 970, 970, 970, 970, 970, 970, 970, 970, 970, + 970, 970, 970, nil, 970, 970, 970, nil, 970, 970, + 970, 970, 970, 490, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 490, + 490, nil, 970, nil, nil, 970, nil, nil, 970, 970, + nil, nil, 970, nil, 970, 490, nil, 490, 970, 490, + 490, nil, 490, 490, nil, nil, 490, 970, 490, nil, + nil, nil, 970, 970, 970, 970, nil, 970, 970, 970, + 970, nil, nil, nil, nil, 970, 970, nil, nil, nil, + nil, nil, nil, 970, nil, 970, 970, 970, nil, nil, + 970, 970, 1057, 1057, 1057, 1057, 1057, 1057, nil, nil, + nil, 1057, 1057, nil, nil, nil, 1057, nil, 1057, 1057, + 1057, 1057, 1057, 1057, 1057, nil, nil, nil, nil, nil, + 1057, 1057, 1057, 1057, 1057, 1057, 1057, nil, nil, 1057, + nil, nil, nil, nil, nil, 1057, 1057, 1057, 1057, 1057, + 1057, 1057, 1057, 1057, 1057, 1057, 1057, nil, 1057, 1057, + 1057, nil, 1057, 1057, 1057, 1057, 1057, 540, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 540, 540, nil, 1057, nil, nil, 1057, + nil, nil, 1057, 1057, nil, nil, 1057, nil, 1057, 540, + nil, 540, 1057, 540, 540, nil, 540, 540, nil, nil, + 540, 1057, 540, nil, nil, nil, 1057, 1057, 1057, 1057, + nil, 1057, 1057, 1057, 1057, nil, nil, nil, nil, 1057, + 1057, nil, nil, nil, nil, nil, nil, 1057, nil, 1057, + 1057, 1057, nil, nil, 1057, 1057, 1064, 1064, 1064, 1064, + 1064, 1064, nil, nil, nil, 1064, 1064, nil, nil, nil, + 1064, nil, 1064, 1064, 1064, 1064, 1064, 1064, 1064, nil, + nil, nil, nil, nil, 1064, 1064, 1064, 1064, 1064, 1064, + 1064, nil, nil, 1064, nil, nil, nil, nil, nil, 1064, + 1064, 1064, 1064, 1064, 1064, 1064, 1064, 1064, 1064, 1064, + 1064, nil, 1064, 1064, 1064, nil, 1064, 1064, 1064, 1064, + 1064, 476, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 476, 476, nil, + 1064, nil, nil, 1064, nil, nil, 1064, 1064, nil, nil, + 1064, nil, 1064, 476, nil, 476, 1064, 476, 476, nil, + 476, 476, nil, nil, nil, 1064, nil, nil, nil, nil, + 1064, 1064, 1064, 1064, nil, 1064, 1064, 1064, 1064, nil, + nil, nil, nil, 1064, 1064, nil, nil, nil, nil, nil, + nil, 1064, nil, 1064, 1064, 1064, nil, nil, 1064, 1064, + 1065, 1065, 1065, 1065, 1065, 1065, nil, nil, nil, 1065, + 1065, nil, nil, nil, 1065, nil, 1065, 1065, 1065, 1065, + 1065, 1065, 1065, nil, nil, nil, nil, nil, 1065, 1065, + 1065, 1065, 1065, 1065, 1065, nil, nil, 1065, nil, nil, + nil, nil, nil, 1065, 1065, 1065, 1065, 1065, 1065, 1065, + 1065, 1065, 1065, 1065, 1065, nil, 1065, 1065, 1065, nil, + 1065, 1065, 1065, 1065, 1065, 477, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 477, 477, nil, 1065, nil, nil, 1065, nil, nil, + 1065, 1065, nil, nil, 1065, nil, 1065, 477, nil, 477, + 1065, 477, 477, nil, 477, 477, nil, nil, nil, 1065, + nil, nil, nil, nil, 1065, 1065, 1065, 1065, nil, 1065, + 1065, 1065, 1065, nil, nil, nil, nil, 1065, 1065, nil, + nil, nil, nil, nil, nil, 1065, nil, 1065, 1065, 1065, + nil, nil, 1065, 1065, 1081, 1081, 1081, 1081, 1081, 1081, + nil, nil, nil, 1081, 1081, nil, nil, nil, 1081, nil, + 1081, 1081, 1081, 1081, 1081, 1081, 1081, nil, nil, nil, + nil, nil, 1081, 1081, 1081, 1081, 1081, 1081, 1081, nil, + nil, 1081, nil, nil, nil, nil, nil, 1081, 1081, 1081, + 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, 1081, nil, + 1081, 1081, 1081, nil, 1081, 1081, 1081, 1081, 1081, 478, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 478, 478, nil, 1081, nil, + nil, 1081, nil, nil, 1081, 1081, nil, nil, 1081, nil, + 1081, 478, nil, nil, 1081, 478, 478, nil, 478, 478, + nil, nil, nil, 1081, nil, nil, nil, nil, 1081, 1081, + 1081, 1081, nil, 1081, 1081, 1081, 1081, nil, nil, nil, + nil, 1081, 1081, nil, nil, nil, nil, nil, nil, 1081, + nil, 1081, 1081, 1081, nil, nil, 1081, 1081, 1091, 1091, + 1091, 1091, 1091, 1091, nil, nil, nil, 1091, 1091, nil, + nil, nil, 1091, nil, 1091, 1091, 1091, 1091, 1091, 1091, + 1091, nil, nil, nil, nil, nil, 1091, 1091, 1091, 1091, + 1091, 1091, 1091, nil, nil, 1091, nil, nil, nil, nil, + nil, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, 1091, + 1091, 1091, 1091, nil, 1091, 1091, 1091, nil, 1091, 1091, + 1091, 1091, 1091, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1091, nil, nil, 1091, nil, nil, 1091, 1091, + nil, nil, 1091, nil, 1091, nil, nil, nil, 1091, nil, + nil, nil, nil, nil, nil, nil, nil, 1091, nil, nil, + nil, nil, 1091, 1091, 1091, 1091, nil, 1091, 1091, 1091, + 1091, nil, nil, nil, nil, 1091, 1091, nil, nil, nil, + nil, nil, nil, 1091, nil, 1091, 1091, 1091, nil, nil, + 1091, 1091, 1133, 1133, 1133, 1133, 1133, 1133, nil, nil, + nil, 1133, 1133, nil, nil, nil, 1133, nil, 1133, 1133, + 1133, 1133, 1133, 1133, 1133, nil, nil, nil, nil, nil, + 1133, 1133, 1133, 1133, 1133, 1133, 1133, nil, nil, 1133, + nil, nil, nil, nil, nil, 1133, 1133, 1133, 1133, 1133, + 1133, 1133, 1133, 1133, 1133, 1133, 1133, nil, 1133, 1133, + 1133, nil, 1133, 1133, 1133, 1133, 1133, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1133, nil, nil, 1133, + nil, nil, 1133, 1133, nil, nil, 1133, nil, 1133, nil, + nil, nil, 1133, nil, nil, nil, nil, nil, nil, nil, + nil, 1133, nil, nil, nil, nil, 1133, 1133, 1133, 1133, + nil, 1133, 1133, 1133, 1133, nil, nil, nil, nil, 1133, + 1133, nil, nil, nil, nil, nil, nil, 1133, nil, 1133, + 1133, 1133, nil, nil, 1133, 1133, 7, 7, 7, 7, + 7, nil, nil, nil, 7, 7, nil, nil, nil, 7, + nil, 7, 7, 7, 7, 7, 7, 7, nil, nil, + nil, nil, nil, 7, 7, 7, 7, 7, 7, 7, + nil, nil, 7, nil, nil, nil, nil, nil, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + nil, 7, 7, 7, nil, 7, 7, 7, 7, 7, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 7, + nil, nil, 7, nil, nil, 7, 7, nil, nil, 7, + nil, 7, nil, nil, nil, 7, nil, nil, nil, nil, + nil, nil, nil, nil, 7, nil, nil, nil, nil, 7, + 7, 7, 7, nil, 7, 7, 7, 7, nil, nil, + nil, nil, 7, 7, nil, nil, nil, 22, 22, 22, + 7, 22, 7, 7, 7, 22, 22, 7, 7, nil, + 22, nil, 22, 22, 22, 22, 22, 22, 22, nil, + nil, nil, nil, nil, 22, 22, 22, 22, 22, 22, + 22, nil, nil, 22, nil, nil, nil, nil, nil, nil, + 22, nil, nil, 22, 22, 22, 22, 22, 22, 22, + 22, nil, 22, 22, 22, nil, 22, 22, 22, 22, + 22, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 22, nil, nil, 22, nil, nil, 22, 22, nil, nil, + 22, nil, nil, nil, nil, nil, 22, nil, nil, nil, + nil, nil, nil, nil, nil, 22, nil, nil, nil, nil, + 22, 22, 22, 22, nil, 22, 22, 22, 22, nil, + nil, nil, nil, 22, 22, nil, nil, nil, nil, nil, + nil, 22, nil, 22, 22, 22, 29, nil, 22, 22, + nil, nil, nil, 29, 29, 29, nil, nil, 29, 29, + 29, nil, 29, nil, nil, nil, nil, nil, nil, nil, + 29, 29, 29, 29, nil, nil, nil, nil, nil, nil, + nil, nil, 29, 29, nil, 29, 29, 29, 29, 29, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, nil, nil, 29, 29, + 29, nil, nil, 29, nil, 29, 29, nil, nil, 29, + 29, nil, 29, nil, 29, nil, 29, nil, 29, 29, + nil, 29, 29, 29, 29, 29, 30, 29, 29, 29, + nil, nil, nil, 30, 30, 30, nil, nil, 30, 30, + 30, nil, 30, 29, nil, nil, 29, 29, nil, 29, + 30, 29, 30, 30, nil, nil, nil, nil, 29, nil, + nil, nil, 30, 30, nil, 30, 30, 30, 30, 30, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, nil, nil, 30, 30, + 30, nil, nil, 30, nil, 30, 30, nil, nil, 30, + 30, nil, 30, nil, 30, nil, 30, nil, 30, 30, + nil, 30, 30, 30, 30, 30, nil, 30, nil, 30, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 30, nil, nil, 30, 30, nil, 30, + nil, 30, 31, 31, 31, nil, 31, nil, 30, nil, + 31, 31, nil, nil, nil, 31, nil, 31, 31, 31, + 31, 31, 31, 31, nil, nil, nil, nil, nil, 31, + 31, 31, 31, 31, 31, 31, nil, nil, 31, nil, + nil, nil, nil, nil, nil, 31, nil, nil, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + nil, 31, 31, 31, 31, 31, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 31, nil, nil, 31, nil, + nil, 31, 31, nil, nil, 31, nil, 31, nil, 31, + nil, 31, nil, nil, 31, nil, nil, nil, nil, nil, + 31, nil, nil, nil, nil, 31, 31, 31, 31, nil, + 31, 31, 31, 31, nil, nil, nil, nil, 31, 31, + nil, nil, nil, 32, 32, 32, 31, 32, 31, 31, + 31, 32, 32, 31, 31, nil, 32, nil, 32, 32, + 32, 32, 32, 32, 32, nil, nil, nil, nil, nil, + 32, 32, 32, 32, 32, 32, 32, nil, nil, 32, + nil, nil, nil, nil, nil, nil, 32, nil, nil, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, nil, 32, 32, 32, 32, 32, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 32, nil, nil, 32, + nil, nil, 32, 32, nil, nil, 32, nil, 32, nil, + 32, nil, 32, nil, nil, 32, nil, nil, nil, nil, + nil, 32, nil, nil, nil, nil, 32, 32, 32, 32, + nil, 32, 32, 32, 32, nil, nil, nil, nil, 32, + 32, nil, nil, nil, 33, 33, 33, 32, 33, 32, + 32, 32, 33, 33, 32, 32, nil, 33, nil, 33, + 33, 33, 33, 33, 33, 33, nil, nil, nil, nil, + nil, 33, 33, 33, 33, 33, 33, 33, nil, nil, + 33, nil, nil, nil, nil, nil, nil, 33, nil, nil, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, nil, 33, 33, 33, 33, 33, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 33, nil, nil, + 33, nil, nil, 33, 33, nil, nil, 33, nil, 33, + nil, 33, nil, 33, nil, nil, 33, nil, nil, nil, + nil, nil, 33, nil, nil, nil, nil, 33, 33, 33, + 33, nil, 33, 33, 33, 33, nil, nil, nil, nil, + 33, 33, nil, nil, nil, 43, 43, 43, 33, 43, + 33, 33, 33, 43, 43, 33, 33, nil, 43, nil, + 43, 43, 43, 43, 43, 43, 43, nil, nil, nil, + nil, nil, 43, 43, 43, 43, 43, 43, 43, nil, + nil, 43, nil, nil, nil, nil, nil, nil, 43, nil, + nil, 43, 43, 43, 43, 43, 43, 43, 43, nil, + 43, 43, 43, nil, 43, 43, 43, 43, 43, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 43, nil, + nil, 43, nil, nil, 43, 43, nil, nil, 43, nil, + nil, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, nil, 43, nil, nil, nil, nil, 43, 43, + 43, 43, nil, 43, 43, 43, 43, nil, nil, nil, + nil, 43, 43, nil, nil, nil, 44, 44, 44, 43, + 44, 43, 43, 43, 44, 44, 43, 43, nil, 44, + nil, 44, 44, 44, 44, 44, 44, 44, nil, nil, + nil, nil, nil, 44, 44, 44, 44, 44, 44, 44, + nil, nil, 44, nil, nil, nil, nil, nil, nil, 44, + nil, nil, 44, 44, 44, 44, 44, 44, 44, 44, + nil, 44, 44, 44, nil, 44, 44, 44, 44, 44, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 44, + nil, nil, 44, nil, nil, 44, 44, nil, nil, 44, + nil, nil, nil, nil, nil, 44, nil, nil, nil, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, 44, + 44, 44, 44, nil, 44, 44, 44, 44, nil, nil, + nil, nil, 44, 44, nil, nil, nil, 46, 46, 46, + 44, 46, 44, 44, 44, 46, 46, 44, 44, nil, + 46, nil, 46, 46, 46, 46, 46, 46, 46, nil, + nil, nil, nil, nil, 46, 46, 46, 46, 46, 46, + 46, nil, nil, 46, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 46, 46, 46, 46, 46, 46, 46, + 46, nil, 46, 46, 46, nil, 46, 46, 46, 46, + 46, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 46, nil, nil, 46, nil, nil, 46, 46, nil, nil, + 46, nil, nil, nil, nil, nil, 46, nil, nil, nil, + nil, nil, nil, nil, nil, 46, nil, nil, nil, nil, + 46, 46, 46, 46, nil, 46, 46, 46, 46, nil, + nil, nil, nil, 46, 46, nil, nil, nil, 47, 47, + 47, 46, 47, 46, 46, 46, 47, 47, 46, 46, + nil, 47, nil, 47, 47, 47, 47, 47, 47, 47, + nil, nil, nil, nil, nil, 47, 47, 47, 47, 47, + 47, 47, nil, nil, 47, nil, nil, nil, nil, nil, + nil, 47, nil, nil, 47, 47, 47, 47, 47, 47, + 47, 47, nil, 47, 47, 47, nil, 47, 47, 47, + 47, 47, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 47, nil, nil, 47, nil, nil, 47, 47, nil, + nil, 47, nil, nil, nil, nil, nil, 47, nil, nil, + nil, nil, nil, nil, nil, nil, 47, nil, nil, nil, + nil, 47, 47, 47, 47, nil, 47, 47, 47, 47, + nil, nil, nil, nil, 47, 47, nil, nil, nil, 49, + 49, 49, 47, 49, 47, 47, 47, 49, 49, 47, + 47, nil, 49, nil, 49, 49, 49, 49, 49, 49, + 49, nil, nil, nil, nil, nil, 49, 49, 49, 49, + 49, 49, 49, nil, nil, 49, nil, nil, nil, nil, + nil, nil, 49, nil, nil, 49, 49, 49, 49, 49, + 49, 49, 49, nil, 49, 49, 49, nil, 49, 49, + 49, 49, 49, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 49, nil, nil, 49, nil, nil, 49, 49, + nil, nil, 49, nil, nil, nil, nil, nil, 49, nil, + nil, nil, nil, nil, nil, nil, nil, 49, nil, nil, + nil, nil, 49, 49, 49, 49, nil, 49, 49, 49, + 49, nil, nil, nil, nil, 49, 49, nil, nil, nil, + nil, nil, nil, 49, nil, 49, 49, 49, 61, nil, + 49, 49, nil, nil, nil, 61, 61, 61, nil, nil, + 61, 61, 61, nil, 61, nil, nil, nil, nil, nil, + nil, nil, 61, nil, 61, 61, 61, nil, nil, nil, + 649, 649, 649, 649, 61, 61, nil, 61, 61, 61, + 61, 61, nil, nil, nil, nil, 649, 649, 649, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 649, + 649, nil, nil, 649, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, nil, nil, + 61, 61, 61, nil, nil, 61, nil, nil, 61, nil, + nil, 61, 61, nil, 61, nil, 61, nil, 61, nil, + 61, 61, nil, 61, 61, 61, 61, 61, nil, 61, + nil, 61, nil, 649, 649, 649, 649, nil, 649, 649, + 649, 649, nil, nil, nil, 61, 649, 649, 61, 61, + 61, 61, nil, 61, 649, 61, 649, 649, 649, nil, + 61, 63, 63, 63, 63, 63, nil, nil, nil, 63, + 63, nil, nil, nil, 63, nil, 63, 63, 63, 63, + 63, 63, 63, nil, nil, nil, nil, nil, 63, 63, + 63, 63, 63, 63, 63, nil, nil, 63, nil, nil, + nil, nil, nil, 63, 63, nil, 63, 63, 63, 63, + 63, 63, 63, 63, 63, nil, 63, 63, 63, nil, + 63, 63, 63, 63, 63, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 63, nil, nil, 63, nil, nil, + 63, 63, nil, nil, 63, nil, 63, nil, nil, nil, + 63, nil, nil, nil, nil, nil, nil, nil, nil, 63, + nil, nil, nil, nil, 63, 63, 63, 63, nil, 63, + 63, 63, 63, nil, nil, nil, nil, 63, 63, nil, + nil, nil, 64, 64, 64, 63, 64, 63, 63, 63, + 64, 64, 63, 63, nil, 64, nil, 64, 64, 64, + 64, 64, 64, 64, nil, nil, nil, nil, nil, 64, + 64, 64, 64, 64, 64, 64, nil, nil, 64, nil, + nil, nil, nil, nil, nil, 64, nil, nil, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + nil, 64, 64, 64, 64, 64, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 64, nil, nil, 64, nil, + nil, 64, 64, nil, nil, 64, nil, 64, nil, nil, + nil, 64, nil, nil, 64, nil, nil, nil, nil, nil, + 64, nil, nil, nil, nil, 64, 64, 64, 64, nil, + 64, 64, 64, 64, nil, nil, nil, nil, 64, 64, + nil, nil, nil, 65, 65, 65, 64, 65, 64, 64, + 64, 65, 65, 64, 64, nil, 65, nil, 65, 65, + 65, 65, 65, 65, 65, nil, nil, nil, nil, nil, + 65, 65, 65, 65, 65, 65, 65, nil, nil, 65, + nil, nil, nil, nil, nil, nil, 65, nil, nil, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, nil, 65, 65, 65, 65, 65, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 65, nil, nil, 65, + nil, nil, 65, 65, nil, nil, 65, nil, nil, nil, + nil, nil, 65, nil, nil, 65, nil, nil, nil, nil, + nil, 65, nil, nil, nil, nil, 65, 65, 65, 65, + nil, 65, 65, 65, 65, nil, nil, nil, nil, 65, + 65, nil, nil, nil, 68, 68, 68, 65, 68, 65, + 65, 65, 68, 68, 65, 65, nil, 68, nil, 68, + 68, 68, 68, 68, 68, 68, nil, nil, nil, nil, + nil, 68, 68, 68, 68, 68, 68, 68, nil, nil, + 68, nil, nil, nil, nil, nil, nil, 68, nil, nil, + 68, 68, 68, 68, 68, 68, 68, 68, nil, 68, + 68, 68, nil, 68, 68, 68, 68, 68, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 68, nil, nil, + 68, nil, nil, 68, 68, nil, nil, 68, nil, nil, + nil, nil, nil, 68, nil, nil, nil, nil, nil, nil, + nil, nil, 68, nil, nil, nil, nil, 68, 68, 68, + 68, nil, 68, 68, 68, 68, nil, nil, nil, nil, + 68, 68, nil, nil, nil, 69, 69, 69, 68, 69, + 68, 68, 68, 69, 69, 68, 68, nil, 69, nil, + 69, 69, 69, 69, 69, 69, 69, nil, nil, nil, + nil, nil, 69, 69, 69, 69, 69, 69, 69, nil, + nil, 69, nil, nil, nil, nil, nil, nil, 69, nil, + nil, 69, 69, 69, 69, 69, 69, 69, 69, nil, + 69, 69, 69, nil, 69, 69, 69, 69, 69, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 69, nil, + nil, 69, nil, nil, 69, 69, nil, nil, 69, nil, + nil, nil, nil, nil, 69, nil, nil, nil, nil, nil, + nil, nil, nil, 69, nil, nil, nil, nil, 69, 69, + 69, 69, nil, 69, 69, 69, 69, nil, nil, nil, + nil, 69, 69, nil, nil, nil, 72, 72, 72, 69, + 72, 69, 69, 69, 72, 72, 69, 69, nil, 72, + nil, 72, 72, 72, 72, 72, 72, 72, nil, nil, + nil, nil, nil, 72, 72, 72, 72, 72, 72, 72, + nil, nil, 72, nil, nil, nil, nil, nil, nil, 72, + nil, nil, 72, 72, 72, 72, 72, 72, 72, 72, + nil, 72, 72, 72, nil, 72, 72, 72, 72, 72, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 72, + nil, nil, 72, nil, nil, 72, 72, nil, nil, 72, + nil, nil, nil, nil, nil, 72, nil, nil, nil, nil, + nil, nil, nil, nil, 72, nil, nil, nil, nil, 72, + 72, 72, 72, nil, 72, 72, 72, 72, nil, nil, + nil, nil, 72, 72, 72, nil, nil, nil, nil, 72, + 72, nil, 72, 72, 72, nil, nil, 72, 72, 121, + 121, 121, 121, 121, nil, nil, nil, 121, 121, nil, + nil, nil, 121, nil, 121, 121, 121, 121, 121, 121, + 121, nil, nil, nil, nil, nil, 121, 121, 121, 121, + 121, 121, 121, nil, nil, 121, nil, nil, nil, nil, + nil, 121, 121, 121, 121, 121, 121, 121, 121, 121, + 121, 121, 121, nil, 121, 121, 121, nil, 121, 121, + 121, 121, 121, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 121, nil, nil, 121, nil, nil, 121, 121, + nil, nil, 121, nil, 121, nil, nil, nil, 121, nil, + nil, nil, nil, nil, nil, nil, nil, 121, nil, nil, + nil, nil, 121, 121, 121, 121, nil, 121, 121, 121, + 121, nil, nil, nil, nil, 121, 121, nil, nil, nil, + nil, nil, 121, 121, nil, 121, 121, 121, nil, nil, + 121, 121, 126, 126, 126, nil, 126, nil, nil, nil, + 126, 126, nil, nil, nil, 126, nil, 126, 126, 126, + 126, 126, 126, 126, nil, nil, nil, nil, nil, 126, + 126, 126, 126, 126, 126, 126, nil, nil, 126, nil, + nil, nil, nil, nil, nil, 126, nil, nil, 126, 126, + 126, 126, 126, 126, 126, 126, nil, 126, 126, 126, + nil, 126, 126, 126, 126, 126, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 126, nil, nil, 126, nil, + nil, 126, 126, nil, nil, 126, nil, nil, nil, nil, + nil, 126, nil, nil, nil, nil, nil, nil, nil, nil, + 126, nil, nil, nil, nil, 126, 126, 126, 126, nil, + 126, 126, 126, 126, nil, nil, nil, nil, 126, 126, + nil, nil, nil, 127, 127, 127, 126, 127, 126, 126, + 126, 127, 127, 126, 126, nil, 127, nil, 127, 127, + 127, 127, 127, 127, 127, nil, nil, nil, nil, nil, + 127, 127, 127, 127, 127, 127, 127, nil, nil, 127, + nil, nil, nil, nil, nil, nil, 127, nil, nil, 127, + 127, 127, 127, 127, 127, 127, 127, nil, 127, 127, + 127, nil, 127, 127, 127, 127, 127, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 127, nil, nil, 127, + nil, nil, 127, 127, nil, nil, 127, nil, nil, nil, + nil, nil, 127, nil, nil, nil, nil, nil, nil, nil, + nil, 127, nil, nil, nil, nil, 127, 127, 127, 127, + nil, 127, 127, 127, 127, nil, nil, nil, nil, 127, + 127, nil, nil, nil, 128, 128, 128, 127, 128, 127, + 127, 127, 128, 128, 127, 127, nil, 128, nil, 128, + 128, 128, 128, 128, 128, 128, nil, nil, nil, nil, + nil, 128, 128, 128, 128, 128, 128, 128, nil, nil, + 128, nil, nil, nil, nil, nil, nil, 128, nil, nil, + 128, 128, 128, 128, 128, 128, 128, 128, nil, 128, + 128, 128, nil, 128, 128, 128, 128, 128, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 128, nil, nil, + 128, nil, nil, 128, 128, nil, nil, 128, nil, nil, + nil, nil, nil, 128, nil, nil, nil, nil, nil, nil, + nil, nil, 128, nil, nil, nil, nil, 128, 128, 128, + 128, nil, 128, 128, 128, 128, nil, nil, nil, nil, + 128, 128, nil, nil, nil, 129, 129, 129, 128, 129, + 128, 128, 128, 129, 129, 128, 128, nil, 129, nil, + 129, 129, 129, 129, 129, 129, 129, nil, nil, nil, + nil, nil, 129, 129, 129, 129, 129, 129, 129, nil, + nil, 129, nil, nil, nil, nil, nil, nil, 129, nil, + nil, 129, 129, 129, 129, 129, 129, 129, 129, nil, + 129, 129, 129, nil, 129, 129, 129, 129, 129, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 129, nil, + nil, 129, nil, nil, 129, 129, nil, nil, 129, nil, + nil, nil, nil, nil, 129, nil, nil, nil, nil, nil, + nil, nil, nil, 129, nil, nil, nil, nil, 129, 129, + 129, 129, nil, 129, 129, 129, 129, nil, nil, nil, + nil, 129, 129, nil, nil, nil, nil, nil, nil, 129, + nil, 129, 129, 129, nil, nil, 129, 129, 130, 130, + 130, 130, 130, nil, nil, nil, 130, 130, nil, nil, + nil, 130, nil, 130, 130, 130, 130, 130, 130, 130, + nil, nil, nil, nil, nil, 130, 130, 130, 130, 130, + 130, 130, nil, nil, 130, nil, nil, nil, nil, nil, + 130, 130, nil, 130, 130, 130, 130, 130, 130, 130, + 130, 130, nil, 130, 130, 130, nil, 130, 130, 130, + 130, 130, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 130, nil, nil, 130, nil, nil, 130, 130, nil, + nil, 130, nil, 130, nil, nil, nil, 130, nil, nil, + nil, nil, nil, nil, nil, nil, 130, nil, nil, nil, + nil, 130, 130, 130, 130, nil, 130, 130, 130, 130, + nil, nil, nil, nil, 130, 130, nil, nil, nil, 216, + 216, 216, 130, 216, 130, 130, 130, 216, 216, 130, + 130, nil, 216, nil, 216, 216, 216, 216, 216, 216, + 216, nil, nil, nil, nil, nil, 216, 216, 216, 216, + 216, 216, 216, nil, nil, 216, nil, nil, nil, nil, + nil, nil, 216, nil, nil, 216, 216, 216, 216, 216, + 216, 216, 216, nil, 216, 216, 216, nil, 216, 216, + 216, 216, 216, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 216, nil, nil, 216, nil, nil, 216, 216, + nil, nil, 216, nil, 216, nil, nil, nil, 216, nil, + nil, nil, nil, nil, nil, nil, nil, 216, nil, nil, + nil, nil, 216, 216, 216, 216, nil, 216, 216, 216, + 216, nil, nil, nil, nil, 216, 216, nil, nil, nil, + 217, 217, 217, 216, 217, 216, 216, 216, 217, 217, + 216, 216, nil, 217, nil, 217, 217, 217, 217, 217, + 217, 217, nil, nil, nil, nil, nil, 217, 217, 217, + 217, 217, 217, 217, nil, nil, 217, nil, nil, nil, + nil, nil, nil, 217, nil, nil, 217, 217, 217, 217, + 217, 217, 217, 217, nil, 217, 217, 217, nil, 217, + 217, 217, 217, 217, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 217, nil, nil, 217, nil, nil, 217, + 217, nil, nil, 217, nil, 217, nil, nil, nil, 217, + nil, nil, nil, nil, nil, nil, nil, nil, 217, nil, + nil, nil, nil, 217, 217, 217, 217, nil, 217, 217, + 217, 217, nil, nil, nil, nil, 217, 217, nil, nil, + nil, 218, 218, 218, 217, 218, 217, 217, 217, 218, + 218, 217, 217, nil, 218, nil, 218, 218, 218, 218, + 218, 218, 218, nil, nil, nil, nil, nil, 218, 218, + 218, 218, 218, 218, 218, nil, nil, 218, nil, nil, + nil, nil, nil, nil, 218, nil, nil, 218, 218, 218, + 218, 218, 218, 218, 218, nil, 218, 218, 218, nil, + 218, 218, 218, 218, 218, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 218, nil, nil, 218, nil, nil, + 218, 218, nil, nil, 218, nil, nil, nil, nil, nil, + 218, nil, nil, nil, nil, nil, nil, nil, nil, 218, + nil, nil, nil, nil, 218, 218, 218, 218, nil, 218, + 218, 218, 218, nil, nil, nil, nil, 218, 218, nil, + nil, nil, 219, 219, 219, 218, 219, 218, 218, 218, + 219, 219, 218, 218, nil, 219, nil, 219, 219, 219, + 219, 219, 219, 219, nil, nil, nil, nil, nil, 219, + 219, 219, 219, 219, 219, 219, nil, nil, 219, nil, + nil, nil, nil, nil, nil, 219, nil, nil, 219, 219, + 219, 219, 219, 219, 219, 219, nil, 219, 219, 219, + nil, 219, 219, 219, 219, 219, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 219, nil, nil, 219, nil, + nil, 219, 219, nil, nil, 219, nil, nil, nil, nil, + nil, 219, nil, nil, nil, nil, nil, nil, nil, nil, + 219, nil, nil, nil, nil, 219, 219, 219, 219, nil, + 219, 219, 219, 219, nil, nil, nil, nil, 219, 219, + nil, nil, nil, 220, 220, 220, 219, 220, 219, 219, + 219, 220, 220, 219, 219, nil, 220, nil, 220, 220, + 220, 220, 220, 220, 220, nil, nil, nil, nil, nil, + 220, 220, 220, 220, 220, 220, 220, nil, nil, 220, + nil, nil, nil, nil, nil, nil, 220, nil, nil, 220, + 220, 220, 220, 220, 220, 220, 220, nil, 220, 220, + 220, nil, 220, 220, 220, 220, 220, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 220, nil, nil, 220, + nil, nil, 220, 220, nil, nil, 220, nil, nil, nil, + nil, nil, 220, nil, nil, nil, nil, nil, nil, nil, + nil, 220, nil, nil, nil, nil, 220, 220, 220, 220, + nil, 220, 220, 220, 220, nil, nil, nil, nil, 220, + 220, nil, nil, nil, 221, 221, 221, 220, 221, 220, + 220, 220, 221, 221, 220, 220, nil, 221, nil, 221, + 221, 221, 221, 221, 221, 221, nil, nil, nil, nil, + nil, 221, 221, 221, 221, 221, 221, 221, nil, nil, + 221, nil, nil, nil, nil, nil, nil, 221, nil, nil, + 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, + 221, 221, nil, 221, 221, 221, 221, 221, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, + 221, nil, nil, 221, 221, nil, nil, 221, nil, 221, + nil, 221, nil, 221, nil, nil, 221, nil, nil, nil, + nil, nil, 221, nil, nil, nil, nil, 221, 221, 221, + 221, nil, 221, 221, 221, 221, nil, nil, nil, nil, + 221, 221, nil, nil, nil, 226, 226, 226, 221, 226, + 221, 221, 221, 226, 226, 221, 221, nil, 226, nil, + 226, 226, 226, 226, 226, 226, 226, nil, nil, nil, + nil, nil, 226, 226, 226, 226, 226, 226, 226, nil, + nil, 226, nil, nil, nil, nil, nil, nil, 226, nil, + nil, 226, 226, 226, 226, 226, 226, 226, 226, nil, + 226, 226, 226, nil, 226, 226, 226, 226, 226, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 226, nil, + nil, 226, nil, nil, 226, 226, nil, nil, 226, nil, + nil, nil, nil, nil, 226, nil, nil, nil, nil, nil, + nil, nil, nil, 226, nil, nil, nil, nil, 226, 226, + 226, 226, nil, 226, 226, 226, 226, nil, nil, nil, + nil, 226, 226, nil, nil, nil, 227, 227, 227, 226, + 227, 226, 226, 226, 227, 227, 226, 226, nil, 227, + nil, 227, 227, 227, 227, 227, 227, 227, nil, nil, + nil, nil, nil, 227, 227, 227, 227, 227, 227, 227, + nil, nil, 227, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 227, 227, 227, 227, 227, 227, 227, 227, + nil, 227, 227, 227, nil, 227, 227, 227, 227, 227, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 227, + nil, nil, 227, nil, nil, 227, 227, nil, nil, 227, + nil, nil, nil, nil, nil, 227, nil, nil, nil, nil, + nil, nil, nil, nil, 227, nil, nil, nil, nil, 227, + 227, 227, 227, nil, 227, 227, 227, 227, nil, nil, + nil, nil, 227, 227, nil, nil, nil, 228, 228, 228, + 227, 228, 227, 227, 227, 228, 228, 227, 227, nil, + 228, nil, 228, 228, 228, 228, 228, 228, 228, nil, + nil, nil, nil, nil, 228, 228, 228, 228, 228, 228, + 228, nil, nil, 228, nil, nil, nil, nil, nil, nil, + 228, nil, nil, 228, 228, 228, 228, 228, 228, 228, + 228, nil, 228, 228, 228, nil, 228, 228, 228, 228, + 228, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 228, nil, nil, 228, nil, nil, 228, 228, nil, nil, + 228, nil, nil, nil, nil, nil, 228, nil, nil, nil, + nil, nil, nil, nil, nil, 228, nil, nil, nil, nil, + 228, 228, 228, 228, nil, 228, 228, 228, 228, nil, + nil, nil, nil, 228, 228, 228, nil, nil, 239, 239, + 239, 228, 239, 228, 228, 228, 239, 239, 228, 228, + nil, 239, nil, 239, 239, 239, 239, 239, 239, 239, + nil, nil, nil, nil, nil, 239, 239, 239, 239, 239, + 239, 239, nil, nil, 239, nil, nil, nil, nil, nil, + nil, 239, nil, nil, 239, 239, 239, 239, 239, 239, + 239, 239, nil, 239, 239, 239, nil, 239, 239, 239, + 239, 239, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 239, nil, nil, 239, nil, nil, 239, 239, nil, + nil, 239, nil, nil, nil, nil, nil, 239, nil, nil, + nil, nil, nil, nil, nil, nil, 239, nil, nil, nil, + nil, 239, 239, 239, 239, nil, 239, 239, 239, 239, + nil, nil, nil, nil, 239, 239, nil, nil, nil, 243, + 243, 243, 239, 243, 239, 239, 239, 243, 243, 239, + 239, nil, 243, nil, 243, 243, 243, 243, 243, 243, + 243, nil, nil, nil, nil, nil, 243, 243, 243, 243, + 243, 243, 243, nil, nil, 243, nil, nil, nil, nil, + nil, nil, 243, nil, nil, 243, 243, 243, 243, 243, + 243, 243, 243, nil, 243, 243, 243, nil, 243, 243, + 243, 243, 243, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 243, nil, nil, 243, nil, nil, 243, 243, + nil, nil, 243, nil, nil, nil, nil, nil, 243, nil, + nil, nil, nil, nil, nil, nil, nil, 243, nil, nil, + nil, nil, 243, 243, 243, 243, nil, 243, 243, 243, + 243, nil, nil, nil, nil, 243, 243, nil, nil, nil, + 244, 244, 244, 243, 244, 243, 243, 243, 244, 244, + 243, 243, nil, 244, nil, 244, 244, 244, 244, 244, + 244, 244, nil, nil, nil, nil, nil, 244, 244, 244, + 244, 244, 244, 244, nil, nil, 244, nil, nil, nil, + nil, nil, nil, 244, nil, nil, 244, 244, 244, 244, + 244, 244, 244, 244, nil, 244, 244, 244, nil, 244, + 244, 244, 244, 244, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 244, nil, nil, 244, nil, nil, 244, + 244, nil, nil, 244, nil, nil, nil, nil, nil, 244, + nil, nil, nil, nil, nil, nil, nil, nil, 244, nil, + nil, nil, nil, 244, 244, 244, 244, nil, 244, 244, + 244, 244, nil, nil, nil, nil, 244, 244, nil, nil, + nil, 245, 245, 245, 244, 245, 244, 244, 244, 245, + 245, 244, 244, nil, 245, nil, 245, 245, 245, 245, + 245, 245, 245, nil, nil, nil, nil, nil, 245, 245, + 245, 245, 245, 245, 245, nil, nil, 245, nil, nil, + nil, nil, nil, nil, 245, nil, nil, 245, 245, 245, + 245, 245, 245, 245, 245, nil, 245, 245, 245, nil, + 245, 245, 245, 245, 245, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 245, nil, nil, 245, nil, nil, + 245, 245, nil, nil, 245, nil, nil, nil, nil, nil, + 245, nil, nil, nil, nil, nil, nil, nil, nil, 245, + nil, nil, nil, nil, 245, 245, 245, 245, nil, 245, + 245, 245, 245, nil, nil, nil, nil, 245, 245, nil, + nil, nil, 246, 246, 246, 245, 246, 245, 245, 245, + 246, 246, 245, 245, nil, 246, nil, 246, 246, 246, + 246, 246, 246, 246, nil, nil, nil, nil, nil, 246, + 246, 246, 246, 246, 246, 246, nil, nil, 246, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 246, 246, + 246, 246, 246, 246, 246, 246, nil, 246, 246, 246, + nil, 246, 246, 246, 246, 246, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 246, nil, + nil, 246, 246, nil, nil, 246, nil, nil, nil, nil, + nil, 246, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, nil, nil, 246, 246, 246, 246, nil, + 246, 246, 246, 246, nil, nil, nil, nil, 246, 246, + nil, nil, nil, 247, 247, 247, 246, 247, 246, 246, + 246, 247, 247, 246, 246, nil, 247, nil, 247, 247, + 247, 247, 247, 247, 247, nil, nil, nil, nil, nil, + 247, 247, 247, 247, 247, 247, 247, nil, nil, 247, + nil, nil, nil, nil, nil, nil, 247, nil, nil, 247, + 247, 247, 247, 247, 247, 247, 247, nil, 247, 247, + 247, nil, 247, 247, 247, 247, 247, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 247, nil, nil, 247, + nil, nil, 247, 247, nil, nil, 247, nil, nil, nil, + nil, nil, 247, nil, nil, nil, nil, nil, nil, nil, + nil, 247, nil, nil, nil, nil, 247, 247, 247, 247, + nil, 247, 247, 247, 247, nil, nil, nil, nil, 247, + 247, nil, nil, nil, 248, 248, 248, 247, 248, 247, + 247, 247, 248, 248, 247, 247, nil, 248, nil, 248, + 248, 248, 248, 248, 248, 248, nil, nil, nil, nil, + nil, 248, 248, 248, 248, 248, 248, 248, nil, nil, + 248, nil, nil, nil, nil, nil, nil, 248, nil, nil, + 248, 248, 248, 248, 248, 248, 248, 248, nil, 248, + 248, 248, nil, 248, 248, 248, 248, 248, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 248, nil, nil, + 248, nil, nil, 248, 248, nil, nil, 248, nil, nil, + nil, nil, nil, 248, nil, nil, nil, nil, nil, nil, + nil, nil, 248, nil, nil, nil, nil, 248, 248, 248, + 248, nil, 248, 248, 248, 248, nil, nil, nil, nil, + 248, 248, nil, nil, nil, 249, 249, 249, 248, 249, + 248, 248, 248, 249, 249, 248, 248, nil, 249, nil, + 249, 249, 249, 249, 249, 249, 249, nil, nil, nil, + nil, nil, 249, 249, 249, 249, 249, 249, 249, nil, + nil, 249, nil, nil, nil, nil, nil, nil, 249, nil, + nil, 249, 249, 249, 249, 249, 249, 249, 249, nil, + 249, 249, 249, nil, 249, 249, 249, 249, 249, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 249, nil, + nil, 249, nil, nil, 249, 249, nil, nil, 249, nil, + nil, nil, nil, nil, 249, nil, nil, nil, nil, nil, + nil, nil, nil, 249, nil, nil, nil, nil, 249, 249, + 249, 249, nil, 249, 249, 249, 249, nil, nil, nil, + nil, 249, 249, nil, nil, nil, 250, 250, 250, 249, + 250, 249, 249, 249, 250, 250, 249, 249, nil, 250, + nil, 250, 250, 250, 250, 250, 250, 250, nil, nil, + nil, nil, nil, 250, 250, 250, 250, 250, 250, 250, + nil, nil, 250, nil, nil, nil, nil, nil, nil, 250, + nil, nil, 250, 250, 250, 250, 250, 250, 250, 250, + nil, 250, 250, 250, nil, 250, 250, 250, 250, 250, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 250, + nil, nil, 250, nil, nil, 250, 250, nil, nil, 250, + nil, nil, nil, nil, nil, 250, nil, nil, nil, nil, + nil, nil, nil, nil, 250, nil, nil, nil, nil, 250, + 250, 250, 250, nil, 250, 250, 250, 250, nil, nil, + nil, nil, 250, 250, nil, nil, nil, 251, 251, 251, + 250, 251, 250, 250, 250, 251, 251, 250, 250, nil, + 251, nil, 251, 251, 251, 251, 251, 251, 251, nil, + nil, nil, nil, nil, 251, 251, 251, 251, 251, 251, + 251, nil, nil, 251, nil, nil, nil, nil, nil, nil, + 251, nil, nil, 251, 251, 251, 251, 251, 251, 251, + 251, nil, 251, 251, 251, nil, 251, 251, 251, 251, + 251, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 251, nil, nil, 251, nil, nil, 251, 251, nil, nil, + 251, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 251, 251, 251, 251, nil, 251, 251, 251, 251, nil, + nil, nil, nil, 251, 251, nil, nil, nil, 252, 252, + 252, 251, 252, 251, 251, 251, 252, 252, 251, 251, + nil, 252, nil, 252, 252, 252, 252, 252, 252, 252, + nil, nil, nil, nil, nil, 252, 252, 252, 252, 252, + 252, 252, nil, nil, 252, nil, nil, nil, nil, nil, + nil, 252, nil, nil, 252, 252, 252, 252, 252, 252, + 252, 252, nil, 252, 252, 252, nil, 252, 252, 252, + 252, 252, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 252, nil, nil, 252, nil, nil, 252, 252, nil, + nil, 252, nil, nil, nil, nil, nil, 252, nil, nil, + nil, nil, nil, nil, nil, nil, 252, nil, nil, nil, + nil, 252, 252, 252, 252, nil, 252, 252, 252, 252, + nil, nil, nil, nil, 252, 252, nil, nil, nil, 253, + 253, 253, 252, 253, 252, 252, 252, 253, 253, 252, + 252, nil, 253, nil, 253, 253, 253, 253, 253, 253, + 253, nil, nil, nil, nil, nil, 253, 253, 253, 253, + 253, 253, 253, nil, nil, 253, nil, nil, nil, nil, + nil, nil, 253, nil, nil, 253, 253, 253, 253, 253, + 253, 253, 253, nil, 253, 253, 253, nil, 253, 253, + 253, 253, 253, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 253, nil, nil, 253, nil, nil, 253, 253, + nil, nil, 253, nil, nil, nil, nil, nil, 253, nil, + nil, nil, nil, nil, nil, nil, nil, 253, nil, nil, + nil, nil, 253, 253, 253, 253, nil, 253, 253, 253, + 253, nil, nil, nil, nil, 253, 253, nil, nil, nil, + 254, 254, 254, 253, 254, 253, 253, 253, 254, 254, + 253, 253, nil, 254, nil, 254, 254, 254, 254, 254, + 254, 254, nil, nil, nil, nil, nil, 254, 254, 254, + 254, 254, 254, 254, nil, nil, 254, nil, nil, nil, + nil, nil, nil, 254, nil, nil, 254, 254, 254, 254, + 254, 254, 254, 254, nil, 254, 254, 254, nil, 254, + 254, 254, 254, 254, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 254, nil, nil, 254, nil, nil, 254, + 254, nil, nil, 254, nil, nil, nil, nil, nil, 254, + nil, nil, nil, nil, nil, nil, nil, nil, 254, nil, + nil, nil, nil, 254, 254, 254, 254, nil, 254, 254, + 254, 254, nil, nil, nil, nil, 254, 254, nil, nil, + nil, 255, 255, 255, 254, 255, 254, 254, 254, 255, + 255, 254, 254, nil, 255, nil, 255, 255, 255, 255, + 255, 255, 255, nil, nil, nil, nil, nil, 255, 255, + 255, 255, 255, 255, 255, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 255, nil, nil, 255, 255, 255, + 255, 255, 255, 255, 255, nil, 255, 255, 255, nil, + 255, 255, 255, 255, 255, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 255, nil, nil, 255, nil, nil, + 255, 255, nil, nil, 255, nil, nil, nil, nil, nil, + 255, nil, nil, nil, nil, nil, nil, nil, nil, 255, + nil, nil, nil, nil, 255, 255, 255, 255, nil, 255, + 255, 255, 255, nil, nil, nil, nil, 255, 255, nil, + nil, nil, 256, 256, 256, 255, 256, 255, 255, 255, + 256, 256, 255, 255, nil, 256, nil, 256, 256, 256, + 256, 256, 256, 256, nil, nil, nil, nil, nil, 256, + 256, 256, 256, 256, 256, 256, nil, nil, 256, nil, + nil, nil, nil, nil, nil, 256, nil, nil, 256, 256, + 256, 256, 256, 256, 256, 256, nil, 256, 256, 256, + nil, 256, 256, 256, 256, 256, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 256, nil, nil, 256, nil, + nil, 256, 256, nil, nil, 256, nil, nil, nil, nil, + nil, 256, nil, nil, nil, nil, nil, nil, nil, nil, + 256, nil, nil, nil, nil, 256, 256, 256, 256, nil, + 256, 256, 256, 256, nil, nil, nil, nil, 256, 256, + nil, nil, nil, 257, 257, 257, 256, 257, 256, 256, + 256, 257, 257, 256, 256, nil, 257, nil, 257, 257, + 257, 257, 257, 257, 257, nil, nil, nil, nil, nil, + 257, 257, 257, 257, 257, 257, 257, nil, nil, 257, + nil, nil, nil, nil, nil, nil, 257, nil, nil, 257, + 257, 257, 257, 257, 257, 257, 257, nil, 257, 257, + 257, nil, 257, 257, 257, 257, 257, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 257, nil, nil, 257, + nil, nil, 257, 257, nil, nil, 257, nil, nil, nil, + nil, nil, 257, nil, nil, nil, nil, nil, nil, nil, + nil, 257, nil, nil, nil, nil, 257, 257, 257, 257, + nil, 257, 257, 257, 257, nil, nil, nil, nil, 257, + 257, nil, nil, nil, 258, 258, 258, 257, 258, 257, + 257, 257, 258, 258, 257, 257, nil, 258, nil, 258, + 258, 258, 258, 258, 258, 258, nil, nil, nil, nil, + nil, 258, 258, 258, 258, 258, 258, 258, nil, nil, + 258, nil, nil, nil, nil, nil, nil, 258, nil, nil, + 258, 258, 258, 258, 258, 258, 258, 258, nil, 258, + 258, 258, nil, 258, 258, 258, 258, 258, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 258, nil, nil, + 258, nil, nil, 258, 258, nil, nil, 258, nil, nil, + nil, nil, nil, 258, nil, nil, nil, nil, nil, nil, + nil, nil, 258, nil, nil, nil, nil, 258, 258, 258, + 258, nil, 258, 258, 258, 258, nil, nil, nil, nil, + 258, 258, nil, nil, nil, 259, 259, 259, 258, 259, + 258, 258, 258, 259, 259, 258, 258, nil, 259, nil, + 259, 259, 259, 259, 259, 259, 259, nil, nil, nil, + nil, nil, 259, 259, 259, 259, 259, 259, 259, nil, + nil, 259, nil, nil, nil, nil, nil, nil, 259, nil, + nil, 259, 259, 259, 259, 259, 259, 259, 259, nil, + 259, 259, 259, nil, 259, 259, 259, 259, 259, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 259, nil, + nil, 259, nil, nil, 259, 259, nil, nil, 259, nil, + nil, nil, nil, nil, 259, nil, nil, nil, nil, nil, + nil, nil, nil, 259, nil, nil, nil, nil, 259, 259, + 259, 259, nil, 259, 259, 259, 259, nil, nil, nil, + nil, 259, 259, nil, nil, nil, 260, 260, 260, 259, + 260, 259, 259, 259, 260, 260, 259, 259, nil, 260, + nil, 260, 260, 260, 260, 260, 260, 260, nil, nil, + nil, nil, nil, 260, 260, 260, 260, 260, 260, 260, + nil, nil, 260, nil, nil, nil, nil, nil, nil, 260, + nil, nil, 260, 260, 260, 260, 260, 260, 260, 260, + nil, 260, 260, 260, nil, 260, 260, 260, 260, 260, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 260, + nil, nil, 260, nil, nil, 260, 260, nil, nil, 260, + nil, nil, nil, nil, nil, 260, nil, nil, nil, nil, + nil, nil, nil, nil, 260, nil, nil, nil, nil, 260, + 260, 260, 260, nil, 260, 260, 260, 260, nil, nil, + nil, nil, 260, 260, nil, nil, nil, 261, 261, 261, + 260, 261, 260, 260, 260, 261, 261, 260, 260, nil, + 261, nil, 261, 261, 261, 261, 261, 261, 261, nil, + nil, nil, nil, nil, 261, 261, 261, 261, 261, 261, + 261, nil, nil, 261, nil, nil, nil, nil, nil, nil, + 261, nil, nil, 261, 261, 261, 261, 261, 261, 261, + 261, nil, 261, 261, 261, nil, 261, 261, 261, 261, + 261, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 261, nil, nil, 261, nil, nil, 261, 261, nil, nil, + 261, nil, nil, nil, nil, nil, 261, nil, nil, nil, + nil, nil, nil, nil, nil, 261, nil, nil, nil, nil, + 261, 261, 261, 261, nil, 261, 261, 261, 261, nil, + nil, nil, nil, 261, 261, nil, nil, nil, 262, 262, + 262, 261, 262, 261, 261, 261, 262, 262, 261, 261, + nil, 262, nil, 262, 262, 262, 262, 262, 262, 262, + nil, nil, nil, nil, nil, 262, 262, 262, 262, 262, + 262, 262, nil, nil, 262, nil, nil, nil, nil, nil, + nil, 262, nil, nil, 262, 262, 262, 262, 262, 262, + 262, 262, nil, 262, 262, 262, nil, 262, 262, 262, + 262, 262, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 262, nil, nil, 262, nil, nil, 262, 262, nil, + nil, 262, nil, nil, nil, nil, nil, 262, nil, nil, + nil, nil, nil, nil, nil, nil, 262, nil, nil, nil, + nil, 262, 262, 262, 262, nil, 262, 262, 262, 262, + nil, nil, nil, nil, 262, 262, nil, nil, nil, 263, + 263, 263, 262, 263, 262, 262, 262, 263, 263, 262, + 262, nil, 263, nil, 263, 263, 263, 263, 263, 263, + 263, nil, nil, nil, nil, nil, 263, 263, 263, 263, + 263, 263, 263, nil, nil, 263, nil, nil, nil, nil, + nil, nil, 263, nil, nil, 263, 263, 263, 263, 263, + 263, 263, 263, nil, 263, 263, 263, nil, 263, 263, + 263, 263, 263, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 263, nil, nil, 263, nil, nil, 263, 263, + nil, nil, 263, nil, nil, nil, nil, nil, 263, nil, + nil, nil, nil, nil, nil, nil, nil, 263, nil, nil, + nil, nil, 263, 263, 263, 263, nil, 263, 263, 263, + 263, nil, nil, nil, nil, 263, 263, nil, nil, nil, + 264, 264, 264, 263, 264, 263, 263, 263, 264, 264, + 263, 263, nil, 264, nil, 264, 264, 264, 264, 264, + 264, 264, nil, nil, nil, nil, nil, 264, 264, 264, + 264, 264, 264, 264, nil, nil, 264, nil, nil, nil, + nil, nil, nil, 264, nil, nil, 264, 264, 264, 264, + 264, 264, 264, 264, nil, 264, 264, 264, nil, 264, + 264, 264, 264, 264, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 264, nil, nil, 264, nil, nil, 264, + 264, nil, nil, 264, nil, nil, nil, nil, nil, 264, + nil, nil, nil, nil, nil, nil, nil, nil, 264, nil, + nil, nil, nil, 264, 264, 264, 264, nil, 264, 264, + 264, 264, nil, nil, nil, nil, 264, 264, nil, nil, + nil, 269, 269, 269, 264, 269, 264, 264, 264, 269, + 269, 264, 264, nil, 269, nil, 269, 269, 269, 269, + 269, 269, 269, nil, nil, nil, nil, nil, 269, 269, + 269, 269, 269, 269, 269, nil, nil, 269, nil, nil, + nil, nil, nil, nil, 269, nil, nil, 269, 269, 269, + 269, 269, 269, 269, 269, nil, 269, 269, 269, nil, + 269, 269, 269, 269, 269, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 269, nil, nil, 269, nil, nil, + 269, 269, nil, nil, 269, nil, nil, nil, nil, nil, + 269, nil, nil, nil, nil, nil, nil, nil, nil, 269, + nil, nil, nil, nil, 269, 269, 269, 269, nil, 269, + 269, 269, 269, nil, nil, nil, nil, 269, 269, nil, + nil, nil, 276, 276, 276, 269, 276, 269, 269, 269, + 276, 276, 269, 269, nil, 276, nil, 276, 276, 276, + 276, 276, 276, 276, nil, nil, nil, nil, nil, 276, + 276, 276, 276, 276, 276, 276, nil, nil, 276, nil, + nil, nil, nil, nil, nil, 276, nil, nil, 276, 276, + 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, + nil, 276, 276, 276, 276, 276, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 276, nil, nil, 276, nil, + nil, 276, 276, nil, nil, 276, nil, 276, nil, 276, + nil, 276, nil, nil, 276, nil, nil, nil, nil, nil, + 276, nil, nil, nil, nil, 276, 276, 276, 276, nil, + 276, 276, 276, 276, nil, nil, nil, nil, 276, 276, + nil, nil, nil, 277, 277, 277, 276, 277, 276, 276, + 276, 277, 277, 276, 276, nil, 277, nil, 277, 277, + 277, 277, 277, 277, 277, nil, nil, nil, nil, nil, + 277, 277, 277, 277, 277, 277, 277, nil, nil, 277, + nil, nil, nil, nil, nil, nil, 277, nil, nil, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, nil, 277, 277, 277, 277, 277, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 277, nil, nil, 277, + nil, nil, 277, 277, nil, nil, 277, nil, 277, nil, + 277, nil, 277, nil, nil, 277, nil, nil, nil, nil, + nil, 277, nil, nil, nil, nil, 277, 277, 277, 277, + nil, 277, 277, 277, 277, nil, nil, nil, nil, 277, + 277, nil, nil, nil, 285, 285, 285, 277, 285, 277, + 277, 277, 285, 285, 277, 277, nil, 285, nil, 285, + 285, 285, 285, 285, 285, 285, nil, nil, nil, nil, + nil, 285, 285, 285, 285, 285, 285, 285, nil, nil, + 285, nil, nil, nil, nil, nil, nil, 285, nil, nil, + 285, 285, 285, 285, 285, 285, 285, 285, 285, 285, + 285, 285, nil, 285, 285, 285, 285, 285, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 285, nil, nil, + 285, nil, nil, 285, 285, nil, nil, 285, nil, 285, + nil, 285, nil, 285, nil, nil, 285, nil, nil, nil, + nil, nil, 285, nil, nil, nil, nil, 285, 285, 285, + 285, nil, 285, 285, 285, 285, nil, nil, nil, nil, + 285, 285, 285, nil, nil, 292, 292, 292, 285, 292, + 285, 285, 285, 292, 292, 285, 285, nil, 292, nil, + 292, 292, 292, 292, 292, 292, 292, nil, nil, nil, + nil, nil, 292, 292, 292, 292, 292, 292, 292, nil, + nil, 292, nil, nil, nil, nil, nil, nil, 292, nil, + nil, 292, 292, 292, 292, 292, 292, 292, 292, nil, + 292, 292, 292, nil, 292, 292, 292, 292, 292, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 292, nil, + nil, 292, nil, nil, 292, 292, nil, nil, 292, nil, + nil, nil, nil, nil, 292, nil, nil, nil, nil, nil, + nil, nil, nil, 292, nil, nil, nil, nil, 292, 292, + 292, 292, nil, 292, 292, 292, 292, nil, nil, nil, + nil, 292, 292, nil, nil, nil, 294, 294, 294, 292, + 294, 292, 292, 292, 294, 294, 292, 292, nil, 294, + nil, 294, 294, 294, 294, 294, 294, 294, nil, nil, + nil, nil, nil, 294, 294, 294, 294, 294, 294, 294, + nil, nil, 294, nil, nil, nil, nil, nil, nil, 294, + nil, nil, 294, 294, 294, 294, 294, 294, 294, 294, + nil, 294, 294, 294, nil, 294, 294, 294, 294, 294, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 294, + nil, nil, 294, nil, nil, 294, 294, nil, nil, 294, + nil, nil, nil, nil, nil, 294, nil, nil, nil, nil, + nil, nil, nil, nil, 294, nil, nil, nil, nil, 294, + 294, 294, 294, nil, 294, 294, 294, 294, nil, nil, + nil, nil, 294, 294, nil, nil, nil, 297, 297, 297, + 294, 297, 294, 294, 294, 297, 297, 294, 294, nil, + 297, nil, 297, 297, 297, 297, 297, 297, 297, nil, + nil, nil, nil, nil, 297, 297, 297, 297, 297, 297, + 297, nil, nil, 297, nil, nil, nil, nil, nil, nil, + 297, nil, nil, 297, 297, 297, 297, 297, 297, 297, + 297, nil, 297, 297, 297, nil, 297, 297, 297, 297, + 297, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 297, nil, nil, 297, nil, nil, 297, 297, nil, nil, + 297, nil, nil, nil, nil, nil, 297, nil, nil, nil, + nil, nil, nil, nil, nil, 297, nil, nil, nil, nil, + 297, 297, 297, 297, nil, 297, 297, 297, 297, nil, + nil, nil, nil, 297, 297, nil, nil, nil, 298, 298, + 298, 297, 298, 297, 297, 297, 298, 298, 297, 297, + nil, 298, nil, 298, 298, 298, 298, 298, 298, 298, + nil, nil, nil, nil, nil, 298, 298, 298, 298, 298, + 298, 298, nil, nil, 298, nil, nil, nil, nil, nil, + nil, 298, nil, nil, 298, 298, 298, 298, 298, 298, + 298, 298, nil, 298, 298, 298, nil, 298, 298, 298, + 298, 298, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 298, nil, nil, 298, nil, nil, 298, 298, nil, + nil, 298, nil, nil, nil, nil, nil, 298, nil, nil, + nil, nil, nil, nil, nil, nil, 298, nil, nil, nil, + nil, 298, 298, 298, 298, nil, 298, 298, 298, 298, + nil, nil, nil, nil, 298, 298, nil, nil, nil, nil, + nil, nil, 298, nil, 298, 298, 298, nil, nil, 298, + 298, 303, 303, 303, 303, 303, nil, nil, nil, 303, + 303, nil, nil, nil, 303, nil, 303, 303, 303, 303, + 303, 303, 303, nil, nil, nil, nil, nil, 303, 303, + 303, 303, 303, 303, 303, nil, nil, 303, nil, nil, + nil, nil, nil, 303, 303, nil, 303, 303, 303, 303, + 303, 303, 303, 303, 303, nil, 303, 303, 303, nil, + 303, 303, 303, 303, 303, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 303, nil, nil, 303, nil, nil, + 303, 303, nil, nil, 303, nil, 303, nil, nil, nil, + 303, nil, nil, nil, nil, nil, nil, nil, nil, 303, + nil, nil, nil, nil, 303, 303, 303, 303, nil, 303, + 303, 303, 303, nil, nil, nil, nil, 303, 303, nil, + nil, nil, 337, 337, 337, 303, 337, 303, 303, 303, + 337, 337, 303, 303, nil, 337, nil, 337, 337, 337, + 337, 337, 337, 337, nil, nil, nil, nil, nil, 337, + 337, 337, 337, 337, 337, 337, nil, nil, 337, nil, + nil, nil, nil, nil, nil, 337, nil, nil, 337, 337, + 337, 337, 337, 337, 337, 337, nil, 337, 337, 337, + nil, 337, 337, 337, 337, 337, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 337, nil, nil, 337, nil, + nil, 337, 337, nil, nil, 337, nil, nil, nil, nil, + nil, 337, nil, nil, nil, nil, nil, nil, nil, nil, + 337, nil, nil, nil, nil, 337, 337, 337, 337, nil, + 337, 337, 337, 337, nil, nil, nil, nil, 337, 337, + nil, nil, nil, 339, 339, 339, 337, 339, 337, 337, + 337, 339, 339, 337, 337, nil, 339, nil, 339, 339, + 339, 339, 339, 339, 339, nil, nil, nil, nil, nil, + 339, 339, 339, 339, 339, 339, 339, nil, nil, 339, + nil, nil, nil, nil, nil, nil, 339, nil, nil, 339, + 339, 339, 339, 339, 339, 339, 339, nil, 339, 339, + 339, nil, 339, 339, 339, 339, 339, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 339, nil, nil, 339, + 339, nil, 339, 339, nil, nil, 339, nil, nil, nil, + nil, nil, 339, nil, nil, nil, nil, nil, nil, nil, + nil, 339, nil, nil, nil, nil, 339, 339, 339, 339, + nil, 339, 339, 339, 339, nil, nil, nil, nil, 339, + 339, nil, nil, nil, 355, 355, 355, 339, 355, 339, + 339, 339, 355, 355, 339, 339, nil, 355, nil, 355, + 355, 355, 355, 355, 355, 355, nil, nil, nil, nil, + nil, 355, 355, 355, 355, 355, 355, 355, nil, nil, + 355, nil, nil, nil, nil, nil, nil, 355, nil, nil, + 355, 355, 355, 355, 355, 355, 355, 355, nil, 355, + 355, 355, nil, 355, 355, 355, 355, 355, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 355, nil, nil, + 355, nil, nil, 355, 355, nil, nil, 355, nil, nil, + nil, nil, nil, 355, nil, nil, nil, nil, nil, nil, + nil, nil, 355, nil, nil, nil, nil, 355, 355, 355, + 355, nil, 355, 355, 355, 355, nil, nil, nil, nil, + 355, 355, nil, nil, nil, 376, 376, 376, 355, 376, + 355, 355, 355, 376, 376, 355, 355, nil, 376, nil, + 376, 376, 376, 376, 376, 376, 376, nil, nil, nil, + nil, nil, 376, 376, 376, 376, 376, 376, 376, nil, + nil, 376, nil, nil, nil, nil, nil, nil, 376, nil, + nil, 376, 376, 376, 376, 376, 376, 376, 376, nil, + 376, 376, 376, nil, 376, 376, 376, 376, 376, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 376, nil, + nil, 376, nil, nil, 376, 376, nil, nil, 376, nil, + nil, nil, nil, nil, 376, nil, nil, nil, nil, nil, + nil, nil, nil, 376, nil, nil, nil, nil, 376, 376, + 376, 376, nil, 376, 376, 376, 376, nil, nil, nil, + nil, 376, 376, nil, nil, nil, 392, 392, 392, 376, + 392, 376, 376, 376, 392, 392, 376, 376, nil, 392, + nil, 392, 392, 392, 392, 392, 392, 392, nil, nil, + nil, nil, nil, 392, 392, 392, 392, 392, 392, 392, + nil, nil, 392, nil, nil, nil, nil, nil, nil, 392, + nil, nil, 392, 392, 392, 392, 392, 392, 392, 392, + nil, 392, 392, 392, nil, 392, 392, 392, 392, 392, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 392, + nil, nil, 392, nil, nil, 392, 392, nil, nil, 392, + nil, nil, nil, nil, nil, 392, nil, nil, nil, nil, + nil, nil, nil, nil, 392, nil, nil, nil, nil, 392, + 392, 392, 392, nil, 392, 392, 392, 392, nil, nil, + nil, nil, 392, 392, nil, nil, nil, 419, 419, 419, + 392, 419, 392, 392, 392, 419, 419, 392, 392, nil, + 419, nil, 419, 419, 419, 419, 419, 419, 419, nil, + nil, nil, nil, nil, 419, 419, 419, 419, 419, 419, + 419, nil, nil, 419, nil, nil, nil, nil, nil, nil, + 419, nil, nil, 419, 419, 419, 419, 419, 419, 419, + 419, nil, 419, 419, 419, nil, 419, 419, 419, 419, + 419, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 419, nil, nil, 419, nil, nil, 419, 419, nil, nil, + 419, nil, nil, nil, nil, nil, 419, nil, nil, nil, + nil, nil, nil, nil, nil, 419, nil, nil, nil, nil, + 419, 419, 419, 419, nil, 419, 419, 419, 419, nil, + nil, nil, nil, 419, 419, nil, nil, nil, nil, nil, + nil, 419, nil, 419, 419, 419, 443, nil, 419, 419, + nil, nil, nil, 443, 443, 443, nil, nil, 443, 443, + 443, nil, 443, nil, nil, nil, nil, nil, nil, nil, + 443, 443, 443, 443, nil, nil, nil, nil, nil, nil, + nil, nil, 443, 443, nil, 443, 443, 443, 443, 443, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 443, 443, 443, 443, 443, 443, 443, 443, + 443, 443, 443, 443, 443, 443, nil, nil, 443, 443, + 443, nil, nil, 443, nil, 443, 443, nil, nil, 443, + 443, nil, 443, nil, 443, nil, 443, nil, 443, 443, + nil, 443, 443, 443, 443, 443, nil, 443, 443, 443, + 874, nil, 874, 874, 874, 874, 874, nil, nil, nil, + nil, nil, nil, 443, nil, 874, 443, 443, 452, 443, + nil, 443, nil, nil, nil, 452, 452, 452, 443, nil, + 452, 452, 452, nil, 452, nil, nil, 874, nil, nil, + nil, nil, 452, 452, 452, 452, 452, nil, 874, 874, + nil, nil, nil, 874, 452, 452, nil, 452, 452, 452, + 452, 452, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 452, 452, 452, 452, 452, 452, + 452, 452, 452, 452, 452, 452, 452, 452, nil, nil, + 452, 452, 452, nil, nil, 452, nil, nil, 452, nil, + nil, 452, 452, nil, 452, nil, 452, nil, 452, nil, + 452, 452, nil, 452, 452, 452, 452, 452, nil, 452, + 452, 452, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 452, nil, nil, 452, 452, + 452, 452, nil, 452, 453, 452, nil, nil, nil, nil, + 452, 453, 453, 453, nil, nil, 453, 453, 453, nil, + 453, nil, nil, nil, nil, nil, nil, nil, 453, 453, + 453, 453, 453, nil, nil, nil, nil, nil, nil, nil, + 453, 453, nil, 453, 453, 453, 453, 453, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 453, 453, 453, 453, 453, 453, 453, 453, 453, 453, + 453, 453, 453, 453, nil, nil, 453, 453, 453, nil, + nil, 453, nil, nil, 453, nil, nil, 453, 453, nil, + 453, nil, 453, nil, 453, nil, 453, 453, nil, 453, + 453, 453, 453, 453, nil, 453, 453, 453, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 453, nil, nil, 453, 453, 453, 453, nil, 453, + nil, 453, nil, 462, 462, 462, 453, 462, nil, nil, + nil, 462, 462, nil, nil, nil, 462, nil, 462, 462, + 462, 462, 462, 462, 462, nil, nil, nil, nil, nil, + 462, 462, 462, 462, 462, 462, 462, nil, nil, 462, + nil, nil, nil, nil, nil, nil, 462, nil, nil, 462, + 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, + 462, nil, 462, 462, 462, 462, 462, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 462, nil, nil, 462, + nil, nil, 462, 462, nil, nil, 462, nil, 462, nil, + 462, nil, 462, nil, nil, 462, nil, nil, nil, nil, + nil, 462, nil, nil, nil, nil, 462, 462, 462, 462, + nil, 462, 462, 462, 462, nil, nil, nil, nil, 462, + 462, nil, nil, nil, 464, 464, 464, 462, 464, 462, + 462, 462, 464, 464, 462, 462, nil, 464, nil, 464, + 464, 464, 464, 464, 464, 464, nil, nil, nil, nil, + nil, 464, 464, 464, 464, 464, 464, 464, nil, nil, + 464, nil, nil, nil, nil, nil, nil, 464, nil, nil, + 464, 464, 464, 464, 464, 464, 464, 464, nil, 464, + 464, 464, nil, 464, 464, 464, 464, 464, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 464, nil, nil, + 464, nil, nil, 464, 464, nil, nil, 464, nil, nil, + nil, nil, nil, 464, nil, nil, nil, nil, nil, nil, + nil, nil, 464, nil, nil, nil, nil, 464, 464, 464, + 464, nil, 464, 464, 464, 464, nil, nil, nil, nil, + 464, 464, nil, nil, nil, 465, 465, 465, 464, 465, + 464, 464, 464, 465, 465, 464, 464, nil, 465, nil, + 465, 465, 465, 465, 465, 465, 465, nil, nil, nil, + nil, nil, 465, 465, 465, 465, 465, 465, 465, nil, + nil, 465, nil, nil, nil, nil, nil, nil, 465, nil, + nil, 465, 465, 465, 465, 465, 465, 465, 465, nil, + 465, 465, 465, nil, 465, 465, 465, 465, 465, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 465, nil, + nil, 465, nil, nil, 465, 465, nil, nil, 465, nil, + nil, nil, nil, nil, 465, nil, nil, nil, nil, nil, + nil, nil, nil, 465, nil, nil, nil, nil, 465, 465, + 465, 465, nil, 465, 465, 465, 465, nil, nil, nil, + nil, 465, 465, nil, nil, nil, 466, 466, 466, 465, + 466, 465, 465, 465, 466, 466, 465, 465, nil, 466, + nil, 466, 466, 466, 466, 466, 466, 466, nil, nil, + nil, nil, nil, 466, 466, 466, 466, 466, 466, 466, + nil, nil, 466, nil, nil, nil, nil, nil, nil, 466, + nil, nil, 466, 466, 466, 466, 466, 466, 466, 466, + nil, 466, 466, 466, nil, 466, 466, 466, 466, 466, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 466, + nil, nil, 466, nil, nil, 466, 466, nil, nil, 466, + nil, nil, nil, nil, nil, 466, nil, nil, nil, nil, + nil, nil, nil, nil, 466, nil, nil, nil, nil, 466, + 466, 466, 466, nil, 466, 466, 466, 466, nil, nil, + nil, nil, 466, 466, nil, nil, nil, nil, nil, nil, + 466, nil, 466, 466, 466, 492, nil, 466, 466, nil, + nil, nil, 492, 492, 492, nil, nil, 492, 492, 492, + 845, 492, 845, 845, 845, 845, 845, nil, nil, 492, + 492, 492, nil, nil, nil, 845, nil, nil, nil, nil, + nil, 492, 492, nil, 492, 492, 492, 492, 492, nil, + nil, nil, nil, nil, nil, nil, nil, 845, nil, 556, + nil, 556, 556, 556, 556, 556, 845, 845, 845, 845, + nil, nil, nil, 845, 556, nil, nil, nil, nil, nil, + nil, nil, 492, nil, nil, nil, nil, nil, nil, 492, + nil, nil, nil, nil, 492, 492, 556, 556, nil, 845, + nil, nil, nil, nil, nil, 556, 556, 556, 556, nil, + nil, nil, 556, nil, nil, nil, nil, 492, 492, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 492, nil, nil, 492, nil, 497, 497, 497, + 492, 497, nil, nil, nil, 497, 497, 492, nil, nil, + 497, nil, 497, 497, 497, 497, 497, 497, 497, nil, + nil, nil, nil, nil, 497, 497, 497, 497, 497, 497, + 497, nil, nil, 497, nil, nil, nil, nil, nil, nil, + 497, nil, nil, 497, 497, 497, 497, 497, 497, 497, + 497, nil, 497, 497, 497, nil, 497, 497, 497, 497, + 497, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 497, nil, nil, 497, nil, nil, 497, 497, nil, nil, + 497, nil, nil, nil, nil, nil, 497, nil, nil, nil, + nil, nil, nil, nil, nil, 497, nil, nil, nil, nil, + 497, 497, 497, 497, nil, 497, 497, 497, 497, nil, + nil, nil, nil, 497, 497, nil, nil, nil, 507, 507, + 507, 497, 507, 497, 497, 497, 507, 507, 497, 497, + nil, 507, nil, 507, 507, 507, 507, 507, 507, 507, + nil, nil, nil, nil, nil, 507, 507, 507, 507, 507, + 507, 507, nil, nil, 507, nil, nil, nil, nil, nil, + nil, 507, nil, nil, 507, 507, 507, 507, 507, 507, + 507, 507, 507, 507, 507, 507, nil, 507, 507, 507, + 507, 507, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 507, nil, nil, 507, nil, nil, 507, 507, nil, + nil, 507, nil, 507, nil, 507, nil, 507, nil, nil, + 507, nil, nil, nil, nil, nil, 507, nil, nil, nil, + nil, 507, 507, 507, 507, nil, 507, 507, 507, 507, + nil, nil, nil, nil, 507, 507, nil, nil, nil, 509, + 509, 509, 507, 509, 507, 507, 507, 509, 509, 507, + 507, nil, 509, nil, 509, 509, 509, 509, 509, 509, + 509, nil, nil, nil, nil, nil, 509, 509, 509, 509, + 509, 509, 509, nil, nil, 509, nil, nil, nil, nil, + nil, nil, 509, nil, nil, 509, 509, 509, 509, 509, + 509, 509, 509, 509, 509, 509, 509, nil, 509, 509, + 509, 509, 509, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 509, nil, nil, 509, nil, nil, 509, 509, + nil, nil, 509, nil, nil, nil, 509, nil, 509, nil, + nil, 509, nil, nil, nil, nil, nil, 509, nil, nil, + nil, nil, 509, 509, 509, 509, nil, 509, 509, 509, + 509, nil, nil, nil, nil, 509, 509, nil, nil, nil, + 511, 511, 511, 509, 511, 509, 509, 509, 511, 511, + 509, 509, nil, 511, nil, 511, 511, 511, 511, 511, + 511, 511, nil, nil, nil, nil, nil, 511, 511, 511, + 511, 511, 511, 511, nil, nil, 511, nil, nil, nil, + nil, nil, nil, 511, nil, nil, 511, 511, 511, 511, + 511, 511, 511, 511, nil, 511, 511, 511, nil, 511, + 511, 511, 511, 511, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 511, nil, nil, 511, nil, nil, 511, + 511, nil, nil, 511, nil, nil, nil, nil, nil, 511, + nil, nil, nil, nil, nil, nil, nil, nil, 511, nil, + nil, nil, nil, 511, 511, 511, 511, nil, 511, 511, + 511, 511, nil, nil, nil, nil, 511, 511, nil, nil, + nil, nil, nil, nil, 511, nil, 511, 511, 511, nil, + nil, 511, 511, 517, 517, 517, 517, 517, nil, nil, + nil, 517, 517, nil, nil, nil, 517, nil, 517, 517, + 517, 517, 517, 517, 517, nil, nil, nil, nil, nil, + 517, 517, 517, 517, 517, 517, 517, nil, nil, 517, + nil, nil, nil, nil, nil, 517, 517, 517, 517, 517, + 517, 517, 517, 517, 517, 517, 517, nil, 517, 517, + 517, nil, 517, 517, 517, 517, 517, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 517, nil, nil, 517, + nil, nil, 517, 517, nil, nil, 517, nil, 517, nil, + nil, nil, 517, nil, nil, nil, nil, nil, nil, nil, + nil, 517, nil, nil, nil, nil, 517, 517, 517, 517, + nil, 517, 517, 517, 517, nil, nil, nil, nil, 517, + 517, nil, nil, nil, nil, nil, 517, 517, nil, 517, + 517, 517, nil, nil, 517, 517, 527, 527, 527, nil, + 527, nil, nil, nil, 527, 527, nil, nil, nil, 527, + nil, 527, 527, 527, 527, 527, 527, 527, nil, nil, + nil, nil, nil, 527, 527, 527, 527, 527, 527, 527, + nil, nil, 527, nil, nil, nil, nil, nil, nil, 527, + nil, nil, 527, 527, 527, 527, 527, 527, 527, 527, + 527, 527, 527, 527, nil, 527, 527, 527, 527, 527, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 527, + nil, nil, 527, nil, nil, 527, 527, nil, nil, 527, + nil, 527, nil, 527, nil, 527, nil, nil, 527, nil, + nil, nil, nil, nil, 527, nil, nil, nil, nil, 527, + 527, 527, 527, nil, 527, 527, 527, 527, nil, nil, + nil, nil, 527, 527, nil, nil, nil, 536, 536, 536, + 527, 536, 527, 527, 527, 536, 536, 527, 527, nil, + 536, nil, 536, 536, 536, 536, 536, 536, 536, nil, + nil, nil, nil, nil, 536, 536, 536, 536, 536, 536, + 536, nil, nil, 536, nil, nil, nil, nil, nil, nil, + 536, nil, nil, 536, 536, 536, 536, 536, 536, 536, + 536, nil, 536, 536, 536, nil, 536, 536, 536, 536, + 536, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 536, nil, nil, 536, nil, nil, 536, 536, nil, nil, + 536, nil, nil, nil, nil, nil, 536, nil, nil, nil, + nil, nil, nil, nil, nil, 536, nil, nil, nil, nil, + 536, 536, 536, 536, nil, 536, 536, 536, 536, nil, + nil, nil, nil, 536, 536, nil, nil, nil, 539, 539, + 539, 536, 539, 536, 536, 536, 539, 539, 536, 536, + nil, 539, nil, 539, 539, 539, 539, 539, 539, 539, + nil, nil, nil, nil, nil, 539, 539, 539, 539, 539, + 539, 539, nil, nil, 539, nil, nil, nil, nil, nil, + nil, 539, nil, nil, 539, 539, 539, 539, 539, 539, + 539, 539, nil, 539, 539, 539, nil, 539, 539, 539, + 539, 539, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 539, nil, nil, 539, nil, nil, 539, 539, nil, + nil, 539, nil, nil, nil, nil, nil, 539, nil, nil, + nil, nil, nil, nil, nil, nil, 539, nil, nil, nil, + nil, 539, 539, 539, 539, nil, 539, 539, 539, 539, + nil, nil, nil, nil, 539, 539, nil, nil, nil, 542, + 542, 542, 539, 542, 539, 539, 539, 542, 542, 539, + 539, nil, 542, nil, 542, 542, 542, 542, 542, 542, + 542, nil, nil, nil, nil, nil, 542, 542, 542, 542, + 542, 542, 542, nil, nil, 542, nil, nil, nil, nil, + nil, nil, 542, nil, nil, 542, 542, 542, 542, 542, + 542, 542, 542, nil, 542, 542, 542, nil, 542, 542, + 542, 542, 542, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 542, nil, nil, 542, nil, nil, 542, 542, + nil, nil, 542, nil, nil, nil, nil, nil, 542, nil, + nil, nil, nil, nil, nil, nil, nil, 542, nil, nil, + nil, nil, 542, 542, 542, 542, nil, 542, 542, 542, + 542, nil, nil, nil, nil, 542, 542, nil, nil, nil, + 548, 548, 548, 542, 548, 542, 542, 542, 548, 548, + 542, 542, nil, 548, nil, 548, 548, 548, 548, 548, + 548, 548, nil, nil, nil, nil, nil, 548, 548, 548, + 548, 548, 548, 548, nil, nil, 548, nil, nil, nil, + nil, nil, nil, 548, nil, nil, 548, 548, 548, 548, + 548, 548, 548, 548, 548, 548, 548, 548, nil, 548, + 548, 548, 548, 548, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 548, nil, nil, 548, nil, nil, 548, + 548, nil, nil, 548, nil, 548, nil, nil, nil, 548, + nil, nil, 548, nil, nil, nil, nil, nil, 548, nil, + nil, nil, nil, 548, 548, 548, 548, nil, 548, 548, + 548, 548, nil, nil, nil, nil, 548, 548, nil, nil, + nil, 551, 551, 551, 548, 551, 548, 548, 548, 551, + 551, 548, 548, nil, 551, nil, 551, 551, 551, 551, + 551, 551, 551, nil, nil, nil, nil, nil, 551, 551, + 551, 551, 551, 551, 551, nil, nil, 551, nil, nil, + nil, nil, nil, nil, 551, nil, nil, 551, 551, 551, + 551, 551, 551, 551, 551, 551, 551, 551, 551, nil, + 551, 551, 551, 551, 551, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 551, nil, nil, 551, nil, nil, + 551, 551, nil, nil, 551, nil, nil, nil, nil, nil, + 551, nil, nil, 551, nil, nil, nil, nil, nil, 551, + nil, nil, nil, nil, 551, 551, 551, 551, nil, 551, + 551, 551, 551, nil, nil, nil, nil, 551, 551, nil, + nil, nil, 566, 566, 566, 551, 566, 551, 551, 551, + 566, 566, 551, 551, nil, 566, nil, 566, 566, 566, + 566, 566, 566, 566, nil, nil, nil, nil, nil, 566, + 566, 566, 566, 566, 566, 566, nil, nil, 566, nil, + nil, nil, nil, nil, nil, 566, nil, nil, 566, 566, + 566, 566, 566, 566, 566, 566, nil, 566, 566, 566, + nil, 566, 566, 566, 566, 566, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 566, nil, nil, 566, nil, + nil, 566, 566, nil, nil, 566, nil, 566, nil, nil, + nil, 566, nil, nil, nil, nil, nil, nil, nil, nil, + 566, nil, nil, nil, nil, 566, 566, 566, 566, nil, + 566, 566, 566, 566, nil, nil, nil, nil, 566, 566, + nil, nil, nil, 567, 567, 567, 566, 567, 566, 566, + 566, 567, 567, 566, 566, nil, 567, nil, 567, 567, + 567, 567, 567, 567, 567, nil, nil, nil, nil, nil, + 567, 567, 567, 567, 567, 567, 567, nil, nil, 567, + nil, nil, nil, nil, nil, nil, 567, nil, nil, 567, + 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, + 567, nil, 567, 567, 567, 567, 567, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 567, nil, nil, 567, + nil, nil, 567, 567, nil, nil, 567, nil, 567, nil, + 567, nil, 567, nil, nil, 567, nil, nil, nil, nil, + nil, 567, nil, nil, nil, nil, 567, 567, 567, 567, + nil, 567, 567, 567, 567, nil, nil, nil, nil, 567, + 567, nil, nil, nil, 577, 577, 577, 567, 577, 567, + 567, 567, 577, 577, 567, 567, nil, 577, nil, 577, + 577, 577, 577, 577, 577, 577, nil, nil, nil, nil, + nil, 577, 577, 577, 577, 577, 577, 577, nil, nil, + 577, nil, nil, nil, nil, nil, nil, 577, nil, nil, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, nil, 577, 577, 577, 577, 577, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 577, nil, nil, + 577, nil, nil, 577, 577, nil, nil, 577, nil, 577, + nil, 577, nil, 577, nil, nil, 577, nil, nil, nil, + nil, nil, 577, nil, nil, nil, nil, 577, 577, 577, + 577, nil, 577, 577, 577, 577, nil, nil, nil, nil, + 577, 577, nil, nil, nil, nil, nil, nil, 577, nil, + 577, 577, 577, nil, nil, 577, 577, 608, 608, 608, + 608, 608, nil, nil, nil, 608, 608, nil, nil, nil, + 608, nil, 608, 608, 608, 608, 608, 608, 608, nil, + nil, nil, nil, nil, 608, 608, 608, 608, 608, 608, + 608, nil, nil, 608, nil, nil, nil, nil, nil, 608, + 608, nil, 608, 608, 608, 608, 608, 608, 608, 608, + 608, nil, 608, 608, 608, nil, 608, 608, 608, 608, + 608, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 608, nil, nil, 608, nil, nil, 608, 608, nil, nil, + 608, nil, 608, nil, nil, nil, 608, nil, nil, nil, + nil, nil, nil, nil, nil, 608, nil, nil, nil, nil, + 608, 608, 608, 608, nil, 608, 608, 608, 608, nil, + nil, nil, nil, 608, 608, nil, nil, nil, 610, 610, + 610, 608, 610, 608, 608, 608, 610, 610, 608, 608, + nil, 610, nil, 610, 610, 610, 610, 610, 610, 610, + nil, nil, nil, nil, nil, 610, 610, 610, 610, 610, + 610, 610, nil, nil, 610, nil, nil, nil, nil, nil, + nil, 610, nil, nil, 610, 610, 610, 610, 610, 610, + 610, 610, nil, 610, 610, 610, nil, 610, 610, 610, + 610, 610, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 610, nil, nil, 610, nil, nil, 610, 610, nil, + nil, 610, nil, 610, nil, nil, nil, 610, nil, nil, + nil, nil, nil, nil, nil, nil, 610, nil, nil, nil, + nil, 610, 610, 610, 610, nil, 610, 610, 610, 610, + nil, nil, nil, nil, 610, 610, nil, nil, nil, 611, + 611, 611, 610, 611, 610, 610, 610, 611, 611, 610, + 610, nil, 611, nil, 611, 611, 611, 611, 611, 611, + 611, nil, nil, nil, nil, nil, 611, 611, 611, 611, + 611, 611, 611, nil, nil, 611, nil, nil, nil, nil, + nil, nil, 611, nil, nil, 611, 611, 611, 611, 611, + 611, 611, 611, nil, 611, 611, 611, nil, 611, 611, + 611, 611, 611, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 611, nil, nil, 611, nil, nil, 611, 611, + nil, nil, 611, nil, nil, nil, nil, nil, 611, nil, + nil, nil, nil, nil, nil, nil, nil, 611, nil, nil, + nil, nil, 611, 611, 611, 611, nil, 611, 611, 611, + 611, nil, nil, nil, nil, 611, 611, nil, nil, nil, + 612, 612, 612, 611, 612, 611, 611, 611, 612, 612, + 611, 611, nil, 612, nil, 612, 612, 612, 612, 612, + 612, 612, nil, nil, nil, nil, nil, 612, 612, 612, + 612, 612, 612, 612, nil, nil, 612, nil, nil, nil, + nil, nil, nil, 612, nil, nil, 612, 612, 612, 612, + 612, 612, 612, 612, 612, 612, 612, 612, nil, 612, + 612, 612, 612, 612, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 612, nil, nil, 612, nil, nil, 612, + 612, nil, nil, 612, nil, 612, nil, 612, nil, 612, + nil, nil, 612, nil, nil, nil, nil, nil, 612, nil, + nil, nil, nil, 612, 612, 612, 612, nil, 612, 612, + 612, 612, nil, nil, nil, nil, 612, 612, nil, nil, + nil, nil, nil, nil, 612, nil, 612, 612, 612, nil, + nil, 612, 612, 615, 615, 615, 615, 615, nil, nil, + nil, 615, 615, nil, nil, nil, 615, nil, 615, 615, + 615, 615, 615, 615, 615, nil, nil, nil, nil, nil, + 615, 615, 615, 615, 615, 615, 615, nil, nil, 615, + nil, nil, nil, nil, nil, 615, 615, nil, 615, 615, + 615, 615, 615, 615, 615, 615, 615, nil, 615, 615, + 615, nil, 615, 615, 615, 615, 615, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 615, nil, nil, 615, + nil, nil, 615, 615, nil, nil, 615, nil, 615, nil, + nil, nil, 615, nil, nil, nil, nil, nil, nil, nil, + nil, 615, nil, nil, nil, nil, 615, 615, 615, 615, + nil, 615, 615, 615, 615, nil, nil, nil, nil, 615, + 615, nil, nil, nil, 616, 616, 616, 615, 616, 615, + 615, 615, 616, 616, 615, 615, nil, 616, nil, 616, + 616, 616, 616, 616, 616, 616, nil, nil, nil, nil, + nil, 616, 616, 616, 616, 616, 616, 616, nil, nil, + 616, nil, nil, nil, nil, nil, nil, 616, nil, nil, + 616, 616, 616, 616, 616, 616, 616, 616, nil, 616, + 616, 616, nil, 616, 616, 616, 616, 616, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 616, nil, nil, + 616, nil, nil, 616, 616, nil, nil, 616, nil, nil, + nil, nil, nil, 616, nil, nil, nil, nil, nil, nil, + nil, nil, 616, nil, nil, nil, nil, 616, 616, 616, + 616, nil, 616, 616, 616, 616, nil, nil, nil, nil, + 616, 616, nil, nil, nil, 619, 619, 619, 616, 619, + 616, 616, 616, 619, 619, 616, 616, nil, 619, nil, + 619, 619, 619, 619, 619, 619, 619, nil, nil, nil, + nil, nil, 619, 619, 619, 619, 619, 619, 619, nil, + nil, 619, nil, nil, nil, nil, nil, nil, 619, nil, + nil, 619, 619, 619, 619, 619, 619, 619, 619, 619, + 619, 619, 619, nil, 619, 619, 619, 619, 619, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 619, nil, + nil, 619, nil, nil, 619, 619, nil, nil, 619, nil, + 619, nil, 619, nil, 619, nil, nil, 619, nil, nil, + nil, nil, nil, 619, nil, nil, nil, nil, 619, 619, + 619, 619, nil, 619, 619, 619, 619, nil, nil, nil, + nil, 619, 619, nil, nil, nil, 620, 620, 620, 619, + 620, 619, 619, 619, 620, 620, 619, 619, nil, 620, + nil, 620, 620, 620, 620, 620, 620, 620, nil, nil, + nil, nil, nil, 620, 620, 620, 620, 620, 620, 620, + nil, nil, 620, nil, nil, nil, nil, nil, nil, 620, + nil, nil, 620, 620, 620, 620, 620, 620, 620, 620, + 620, 620, 620, 620, nil, 620, 620, 620, 620, 620, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 620, + nil, nil, 620, nil, nil, 620, 620, nil, nil, 620, + nil, nil, nil, 620, nil, 620, nil, nil, 620, nil, + nil, nil, nil, nil, 620, nil, nil, nil, nil, 620, + 620, 620, 620, nil, 620, 620, 620, 620, nil, nil, + nil, nil, 620, 620, nil, nil, nil, 621, 621, 621, + 620, 621, 620, 620, 620, 621, 621, 620, 620, nil, + 621, nil, 621, 621, 621, 621, 621, 621, 621, nil, + nil, nil, nil, nil, 621, 621, 621, 621, 621, 621, + 621, nil, nil, 621, nil, nil, nil, nil, nil, nil, + 621, nil, nil, 621, 621, 621, 621, 621, 621, 621, + 621, nil, 621, 621, 621, nil, 621, 621, 621, 621, + 621, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 621, nil, nil, 621, nil, nil, 621, 621, nil, nil, + 621, nil, nil, nil, nil, nil, 621, nil, nil, nil, + nil, nil, nil, nil, nil, 621, nil, nil, nil, nil, + 621, 621, 621, 621, nil, 621, 621, 621, 621, nil, + nil, nil, nil, 621, 621, nil, nil, nil, 622, 622, + 622, 621, 622, 621, 621, 621, 622, 622, 621, 621, + nil, 622, nil, 622, 622, 622, 622, 622, 622, 622, + nil, nil, nil, nil, nil, 622, 622, 622, 622, 622, + 622, 622, nil, nil, 622, nil, nil, nil, nil, nil, + nil, 622, nil, nil, 622, 622, 622, 622, 622, 622, + 622, 622, nil, 622, 622, 622, nil, 622, 622, 622, + 622, 622, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 622, nil, nil, 622, nil, nil, 622, 622, nil, + nil, 622, nil, nil, nil, nil, nil, 622, nil, nil, + nil, nil, nil, nil, nil, nil, 622, nil, nil, nil, + nil, 622, 622, 622, 622, nil, 622, 622, 622, 622, + nil, nil, nil, nil, 622, 622, nil, nil, nil, 626, + 626, 626, 622, 626, 622, 622, 622, 626, 626, 622, + 622, nil, 626, nil, 626, 626, 626, 626, 626, 626, + 626, nil, nil, nil, nil, nil, 626, 626, 626, 626, + 626, 626, 626, nil, nil, 626, nil, nil, nil, nil, + nil, nil, 626, nil, nil, 626, 626, 626, 626, 626, + 626, 626, 626, nil, 626, 626, 626, nil, 626, 626, + 626, 626, 626, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 626, nil, nil, 626, nil, nil, 626, 626, + nil, nil, 626, nil, nil, nil, nil, nil, 626, nil, + nil, nil, nil, nil, nil, nil, nil, 626, nil, nil, + nil, nil, 626, 626, 626, 626, nil, 626, 626, 626, + 626, nil, nil, nil, nil, 626, 626, nil, nil, nil, + 627, 627, 627, 626, 627, 626, 626, 626, 627, 627, + 626, 626, nil, 627, nil, 627, 627, 627, 627, 627, + 627, 627, nil, nil, nil, nil, nil, 627, 627, 627, + 627, 627, 627, 627, nil, nil, 627, nil, nil, nil, + nil, nil, nil, 627, nil, nil, 627, 627, 627, 627, + 627, 627, 627, 627, nil, 627, 627, 627, nil, 627, + 627, 627, 627, 627, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 627, nil, nil, 627, nil, nil, 627, + 627, nil, nil, 627, nil, nil, nil, nil, nil, 627, + nil, nil, nil, nil, nil, nil, nil, nil, 627, nil, + nil, nil, nil, 627, 627, 627, 627, nil, 627, 627, + 627, 627, nil, nil, nil, nil, 627, 627, nil, nil, + nil, 672, 672, 672, 627, 672, 627, 627, 627, 672, + 672, 627, 627, nil, 672, nil, 672, 672, 672, 672, + 672, 672, 672, nil, nil, nil, nil, nil, 672, 672, + 672, 672, 672, 672, 672, nil, nil, 672, nil, nil, + nil, nil, nil, nil, 672, nil, nil, 672, 672, 672, + 672, 672, 672, 672, 672, 672, 672, 672, 672, nil, + 672, 672, 672, 672, 672, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 672, nil, nil, 672, nil, nil, + 672, 672, nil, nil, 672, nil, 672, nil, 672, nil, + 672, nil, nil, 672, nil, nil, nil, nil, nil, 672, + nil, nil, nil, nil, 672, 672, 672, 672, nil, 672, + 672, 672, 672, nil, nil, nil, nil, 672, 672, nil, + nil, nil, 681, 681, 681, 672, 681, 672, 672, 672, + 681, 681, 672, 672, nil, 681, nil, 681, 681, 681, + 681, 681, 681, 681, nil, nil, nil, nil, nil, 681, + 681, 681, 681, 681, 681, 681, nil, nil, 681, nil, + nil, nil, nil, nil, nil, 681, nil, nil, 681, 681, + 681, 681, 681, 681, 681, 681, nil, 681, 681, 681, + nil, 681, 681, 681, 681, 681, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 681, nil, nil, 681, nil, + nil, 681, 681, nil, nil, 681, nil, nil, nil, nil, + nil, 681, nil, nil, nil, nil, nil, nil, nil, nil, + 681, nil, nil, nil, nil, 681, 681, 681, 681, nil, + 681, 681, 681, 681, nil, nil, nil, nil, 681, 681, + nil, nil, nil, 684, 684, 684, 681, 684, 681, 681, + 681, 684, 684, 681, 681, nil, 684, nil, 684, 684, + 684, 684, 684, 684, 684, nil, nil, nil, nil, nil, + 684, 684, 684, 684, 684, 684, 684, nil, nil, 684, + nil, nil, nil, nil, nil, nil, 684, nil, nil, 684, + 684, 684, 684, 684, 684, 684, 684, nil, 684, 684, + 684, nil, 684, 684, 684, 684, 684, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 684, nil, nil, 684, + nil, nil, 684, 684, nil, nil, 684, nil, nil, nil, + nil, nil, 684, nil, nil, nil, nil, nil, nil, nil, + nil, 684, nil, nil, nil, nil, 684, 684, 684, 684, + nil, 684, 684, 684, 684, nil, nil, nil, nil, 684, + 684, nil, nil, nil, 703, 703, 703, 684, 703, 684, + 684, 684, 703, 703, 684, 684, nil, 703, nil, 703, + 703, 703, 703, 703, 703, 703, nil, nil, nil, nil, + nil, 703, 703, 703, 703, 703, 703, 703, nil, nil, + 703, nil, nil, nil, nil, nil, nil, 703, nil, nil, + 703, 703, 703, 703, 703, 703, 703, 703, nil, 703, + 703, 703, nil, 703, 703, 703, 703, 703, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 703, nil, nil, + 703, nil, nil, 703, 703, nil, nil, 703, nil, 703, + nil, nil, nil, 703, nil, nil, nil, nil, nil, nil, + nil, nil, 703, nil, nil, nil, nil, 703, 703, 703, + 703, nil, 703, 703, 703, 703, nil, nil, nil, nil, + 703, 703, nil, nil, nil, 730, 730, 730, 703, 730, + 703, 703, 703, 730, 730, 703, 703, nil, 730, nil, + 730, 730, 730, 730, 730, 730, 730, nil, nil, nil, + nil, nil, 730, 730, 730, 730, 730, 730, 730, nil, + nil, 730, nil, nil, nil, nil, nil, nil, 730, nil, + nil, 730, 730, 730, 730, 730, 730, 730, 730, nil, + 730, 730, 730, nil, 730, 730, 730, 730, 730, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 730, nil, + nil, 730, nil, nil, 730, 730, nil, nil, 730, nil, + nil, nil, nil, nil, 730, nil, nil, nil, nil, nil, + nil, nil, nil, 730, nil, nil, nil, nil, 730, 730, + 730, 730, nil, 730, 730, 730, 730, nil, nil, nil, + nil, 730, 730, nil, nil, nil, 766, 766, 766, 730, + 766, 730, 730, 730, 766, 766, 730, 730, nil, 766, + nil, 766, 766, 766, 766, 766, 766, 766, nil, nil, + nil, nil, nil, 766, 766, 766, 766, 766, 766, 766, + nil, nil, 766, nil, nil, nil, nil, nil, nil, 766, + nil, nil, 766, 766, 766, 766, 766, 766, 766, 766, + nil, 766, 766, 766, nil, 766, 766, 766, 766, 766, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 766, + nil, nil, 766, nil, nil, 766, 766, nil, nil, 766, + nil, nil, nil, nil, nil, 766, nil, nil, nil, nil, + nil, nil, nil, nil, 766, nil, nil, nil, nil, 766, + 766, 766, 766, nil, 766, 766, 766, 766, nil, nil, + nil, nil, 766, 766, nil, nil, nil, 789, 789, 789, + 766, 789, 766, 766, 766, 789, 789, 766, 766, nil, + 789, nil, 789, 789, 789, 789, 789, 789, 789, nil, + nil, nil, nil, nil, 789, 789, 789, 789, 789, 789, + 789, nil, nil, 789, nil, nil, nil, nil, nil, nil, + 789, nil, nil, 789, 789, 789, 789, 789, 789, 789, + 789, nil, 789, 789, 789, nil, 789, 789, 789, 789, + 789, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 789, nil, nil, 789, nil, nil, 789, 789, nil, nil, + 789, nil, nil, nil, nil, nil, 789, nil, nil, nil, + nil, nil, nil, nil, nil, 789, nil, nil, nil, nil, + 789, 789, 789, 789, nil, 789, 789, 789, 789, nil, + nil, nil, nil, 789, 789, nil, nil, nil, 797, 797, + 797, 789, 797, 789, 789, 789, 797, 797, 789, 789, + nil, 797, nil, 797, 797, 797, 797, 797, 797, 797, + nil, nil, nil, nil, nil, 797, 797, 797, 797, 797, + 797, 797, nil, nil, 797, nil, nil, nil, nil, nil, + nil, 797, nil, nil, 797, 797, 797, 797, 797, 797, + 797, 797, nil, 797, 797, 797, nil, 797, 797, 797, + 797, 797, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 797, nil, nil, 797, nil, nil, 797, 797, nil, + nil, 797, nil, nil, nil, nil, nil, 797, nil, nil, + nil, nil, nil, nil, nil, nil, 797, nil, nil, nil, + nil, 797, 797, 797, 797, nil, 797, 797, 797, 797, + nil, nil, nil, nil, 797, 797, nil, nil, nil, 810, + 810, 810, 797, 810, 797, 797, 797, 810, 810, 797, + 797, nil, 810, nil, 810, 810, 810, 810, 810, 810, + 810, nil, nil, nil, nil, nil, 810, 810, 810, 810, + 810, 810, 810, nil, nil, 810, nil, nil, nil, nil, + nil, nil, 810, nil, nil, 810, 810, 810, 810, 810, + 810, 810, 810, nil, 810, 810, 810, nil, 810, 810, + 810, 810, 810, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 810, nil, nil, 810, nil, nil, 810, 810, + nil, nil, 810, nil, nil, nil, nil, nil, 810, nil, + nil, nil, nil, nil, nil, nil, nil, 810, nil, nil, + nil, nil, 810, 810, 810, 810, nil, 810, 810, 810, + 810, nil, nil, nil, nil, 810, 810, nil, nil, nil, + 811, 811, 811, 810, 811, 810, 810, 810, 811, 811, + 810, 810, nil, 811, nil, 811, 811, 811, 811, 811, + 811, 811, nil, nil, nil, nil, nil, 811, 811, 811, + 811, 811, 811, 811, nil, nil, 811, nil, nil, nil, + nil, nil, nil, 811, nil, nil, 811, 811, 811, 811, + 811, 811, 811, 811, nil, 811, 811, 811, nil, 811, + 811, 811, 811, 811, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 811, nil, nil, 811, nil, nil, 811, + 811, nil, nil, 811, nil, nil, nil, nil, nil, 811, + nil, nil, nil, nil, nil, nil, nil, nil, 811, nil, + nil, nil, nil, 811, 811, 811, 811, nil, 811, 811, + 811, 811, nil, nil, nil, nil, 811, 811, nil, nil, + nil, 812, 812, 812, 811, 812, 811, 811, 811, 812, + 812, 811, 811, nil, 812, nil, 812, 812, 812, 812, + 812, 812, 812, nil, nil, nil, nil, nil, 812, 812, + 812, 812, 812, 812, 812, nil, nil, 812, nil, nil, + nil, nil, nil, nil, 812, nil, nil, 812, 812, 812, + 812, 812, 812, 812, 812, nil, 812, 812, 812, nil, + 812, 812, 812, 812, 812, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 812, nil, nil, 812, nil, nil, + 812, 812, nil, nil, 812, nil, nil, nil, nil, nil, + 812, nil, nil, nil, nil, nil, nil, nil, nil, 812, + nil, nil, nil, nil, 812, 812, 812, 812, nil, 812, + 812, 812, 812, nil, nil, nil, nil, 812, 812, nil, + nil, nil, 813, 813, 813, 812, 813, 812, 812, 812, + 813, 813, 812, 812, nil, 813, nil, 813, 813, 813, + 813, 813, 813, 813, nil, nil, nil, nil, nil, 813, + 813, 813, 813, 813, 813, 813, nil, nil, 813, nil, + nil, nil, nil, nil, nil, 813, nil, nil, 813, 813, + 813, 813, 813, 813, 813, 813, nil, 813, 813, 813, + nil, 813, 813, 813, 813, 813, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 813, nil, nil, 813, nil, + nil, 813, 813, nil, nil, 813, nil, nil, nil, nil, + nil, 813, nil, nil, nil, nil, nil, nil, nil, nil, + 813, nil, nil, nil, nil, 813, 813, 813, 813, nil, + 813, 813, 813, 813, nil, nil, nil, nil, 813, 813, + nil, nil, nil, 836, 836, 836, 813, 836, 813, 813, + 813, 836, 836, 813, 813, nil, 836, nil, 836, 836, + 836, 836, 836, 836, 836, nil, nil, nil, nil, nil, + 836, 836, 836, 836, 836, 836, 836, nil, nil, 836, + nil, nil, nil, nil, nil, nil, 836, nil, nil, 836, + 836, 836, 836, 836, 836, 836, 836, nil, 836, 836, + 836, nil, 836, 836, 836, 836, 836, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 836, nil, nil, 836, + nil, nil, 836, 836, nil, nil, 836, nil, nil, nil, + nil, nil, 836, nil, nil, nil, nil, nil, nil, nil, + nil, 836, nil, nil, nil, nil, 836, 836, 836, 836, + nil, 836, 836, 836, 836, nil, nil, nil, nil, 836, + 836, nil, nil, nil, 876, 876, 876, 836, 876, 836, + 836, 836, 876, 876, 836, 836, nil, 876, nil, 876, + 876, 876, 876, 876, 876, 876, nil, nil, nil, nil, + nil, 876, 876, 876, 876, 876, 876, 876, nil, nil, + 876, nil, nil, nil, nil, nil, nil, 876, nil, nil, + 876, 876, 876, 876, 876, 876, 876, 876, nil, 876, + 876, 876, nil, 876, 876, 876, 876, 876, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 876, nil, nil, + 876, nil, nil, 876, 876, nil, nil, 876, nil, nil, + nil, nil, nil, 876, nil, nil, nil, nil, nil, nil, + nil, nil, 876, nil, nil, nil, nil, 876, 876, 876, + 876, nil, 876, 876, 876, 876, nil, nil, nil, nil, + 876, 876, nil, nil, nil, 891, 891, 891, 876, 891, + 876, 876, 876, 891, 891, 876, 876, nil, 891, nil, + 891, 891, 891, 891, 891, 891, 891, nil, nil, nil, + nil, nil, 891, 891, 891, 891, 891, 891, 891, nil, + nil, 891, nil, nil, nil, nil, nil, nil, 891, nil, + nil, 891, 891, 891, 891, 891, 891, 891, 891, nil, + 891, 891, 891, nil, 891, 891, 891, 891, 891, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 891, nil, + nil, 891, nil, nil, 891, 891, nil, nil, 891, nil, + nil, nil, nil, nil, 891, nil, nil, nil, nil, nil, + nil, nil, nil, 891, nil, nil, nil, nil, 891, 891, + 891, 891, nil, 891, 891, 891, 891, nil, nil, nil, + nil, 891, 891, nil, nil, nil, 896, 896, 896, 891, + 896, 891, 891, 891, 896, 896, 891, 891, nil, 896, + nil, 896, 896, 896, 896, 896, 896, 896, nil, nil, + nil, nil, nil, 896, 896, 896, 896, 896, 896, 896, + nil, nil, 896, nil, nil, nil, nil, nil, nil, 896, + nil, nil, 896, 896, 896, 896, 896, 896, 896, 896, + nil, 896, 896, 896, nil, 896, 896, 896, 896, 896, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 896, + nil, nil, 896, nil, nil, 896, 896, nil, nil, 896, + nil, 896, nil, nil, nil, 896, nil, nil, nil, nil, + nil, nil, nil, nil, 896, nil, nil, nil, nil, 896, + 896, 896, 896, nil, 896, 896, 896, 896, nil, nil, + nil, nil, 896, 896, nil, nil, nil, 917, 917, 917, + 896, 917, 896, 896, 896, 917, 917, 896, 896, nil, + 917, nil, 917, 917, 917, 917, 917, 917, 917, nil, + nil, nil, nil, nil, 917, 917, 917, 917, 917, 917, + 917, nil, nil, 917, nil, nil, nil, nil, nil, nil, + 917, nil, nil, 917, 917, 917, 917, 917, 917, 917, + 917, 917, 917, 917, 917, nil, 917, 917, 917, 917, + 917, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 917, nil, nil, 917, nil, nil, 917, 917, nil, nil, + 917, nil, nil, nil, 917, nil, 917, nil, nil, 917, + nil, nil, nil, nil, nil, 917, nil, nil, nil, nil, + 917, 917, 917, 917, nil, 917, 917, 917, 917, nil, + nil, nil, nil, 917, 917, nil, nil, nil, 918, 918, + 918, 917, 918, 917, 917, 917, 918, 918, 917, 917, + nil, 918, nil, 918, 918, 918, 918, 918, 918, 918, + nil, nil, nil, nil, nil, 918, 918, 918, 918, 918, + 918, 918, nil, nil, 918, nil, nil, nil, nil, nil, + nil, 918, nil, nil, 918, 918, 918, 918, 918, 918, + 918, 918, nil, 918, 918, 918, nil, 918, 918, 918, + 918, 918, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 918, nil, nil, 918, nil, nil, 918, 918, nil, + nil, 918, nil, nil, nil, nil, nil, 918, nil, nil, + nil, nil, nil, nil, nil, nil, 918, nil, nil, nil, + nil, 918, 918, 918, 918, nil, 918, 918, 918, 918, + nil, nil, nil, nil, 918, 918, nil, nil, nil, 1083, + 1083, 1083, 918, 1083, 918, 918, 918, 1083, 1083, 918, + 918, nil, 1083, nil, 1083, 1083, 1083, 1083, 1083, 1083, + 1083, nil, nil, nil, nil, nil, 1083, 1083, 1083, 1083, + 1083, 1083, 1083, nil, nil, 1083, nil, nil, nil, nil, + nil, nil, 1083, nil, nil, 1083, 1083, 1083, 1083, 1083, + 1083, 1083, 1083, nil, 1083, 1083, 1083, nil, 1083, 1083, + 1083, 1083, 1083, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1083, nil, nil, 1083, nil, nil, 1083, 1083, + nil, nil, 1083, nil, nil, nil, nil, nil, 1083, nil, + nil, nil, nil, nil, nil, nil, nil, 1083, nil, nil, + nil, nil, 1083, 1083, 1083, 1083, nil, 1083, 1083, 1083, + 1083, nil, nil, nil, nil, 1083, 1083, nil, nil, nil, + 1084, 1084, 1084, 1083, 1084, 1083, 1083, 1083, 1084, 1084, + 1083, 1083, nil, 1084, nil, 1084, 1084, 1084, 1084, 1084, + 1084, 1084, nil, nil, nil, nil, nil, 1084, 1084, 1084, + 1084, 1084, 1084, 1084, nil, nil, 1084, nil, nil, nil, + nil, nil, nil, 1084, nil, nil, 1084, 1084, 1084, 1084, + 1084, 1084, 1084, 1084, nil, 1084, 1084, 1084, nil, 1084, + 1084, 1084, 1084, 1084, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 1084, nil, nil, 1084, nil, nil, 1084, + 1084, nil, nil, 1084, nil, nil, nil, nil, nil, 1084, + nil, nil, nil, nil, nil, nil, nil, nil, 1084, nil, + nil, nil, nil, 1084, 1084, 1084, 1084, nil, 1084, 1084, + 1084, 1084, nil, nil, nil, nil, 1084, 1084, nil, nil, + nil, 1120, 1120, 1120, 1084, 1120, 1084, 1084, 1084, 1120, + 1120, 1084, 1084, nil, 1120, nil, 1120, 1120, 1120, 1120, + 1120, 1120, 1120, nil, nil, nil, nil, nil, 1120, 1120, + 1120, 1120, 1120, 1120, 1120, nil, nil, 1120, nil, nil, + nil, nil, nil, nil, 1120, nil, nil, 1120, 1120, 1120, + 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, nil, + 1120, 1120, 1120, 1120, 1120, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1120, nil, nil, 1120, nil, nil, + 1120, 1120, nil, nil, 1120, nil, 1120, nil, 1120, nil, + 1120, nil, nil, 1120, nil, nil, nil, nil, nil, 1120, + nil, nil, nil, nil, 1120, 1120, 1120, 1120, nil, 1120, + 1120, 1120, 1120, nil, nil, nil, nil, 1120, 1120, nil, + nil, nil, 36, 36, 36, 1120, 36, 1120, 1120, 1120, + 36, 36, 1120, 1120, nil, 36, nil, 36, 36, 36, + 36, 36, 36, 36, nil, nil, nil, nil, nil, 36, + 36, 36, 36, 36, 36, 36, nil, nil, 36, nil, + nil, nil, nil, nil, nil, 36, nil, nil, 36, 36, + 36, 36, 36, 36, 36, 36, nil, 36, 36, 36, + nil, 36, 36, nil, nil, 36, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 36, nil, nil, 36, nil, + nil, 36, 36, nil, nil, 36, nil, 36, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 36, 36, 36, 36, nil, + 36, 36, 36, 36, nil, nil, nil, nil, 36, 36, + nil, nil, nil, 37, 37, 37, 36, 37, 36, 36, + 36, 37, 37, nil, nil, nil, 37, nil, 37, 37, + 37, 37, 37, 37, 37, nil, nil, nil, nil, nil, + 37, 37, 37, 37, 37, 37, 37, nil, nil, 37, + nil, nil, nil, nil, nil, nil, 37, nil, nil, 37, + 37, 37, 37, 37, 37, 37, 37, nil, 37, 37, + 37, nil, 37, 37, nil, nil, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 37, nil, nil, 37, + nil, nil, 37, 37, nil, nil, 37, nil, nil, 1048, + nil, 1048, 1048, 1048, 1048, 1048, nil, nil, nil, nil, + nil, nil, nil, nil, 1048, nil, 37, 37, 37, 37, + nil, 37, 37, 37, 37, nil, nil, nil, nil, 37, + 37, nil, nil, nil, 37, nil, 1048, 37, nil, 37, + 37, 37, 73, 73, 73, nil, 73, 1048, 1048, nil, + 73, 73, 1048, nil, nil, 73, nil, 73, 73, 73, + 73, 73, 73, 73, nil, nil, nil, nil, nil, 73, + 73, 73, 73, 73, 73, 73, nil, nil, 73, nil, + nil, nil, nil, nil, nil, 73, nil, nil, 73, 73, + 73, 73, 73, 73, 73, 73, nil, 73, 73, 73, + nil, 73, 73, nil, nil, 73, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 73, nil, nil, 73, nil, + nil, 73, 73, nil, nil, 73, nil, 73, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 73, 73, 73, 73, nil, + 73, 73, 73, 73, nil, nil, nil, nil, 73, 73, + nil, nil, nil, 74, 74, 74, 73, 74, 73, 73, + 73, 74, 74, nil, nil, nil, 74, nil, 74, 74, + 74, 74, 74, 74, 74, nil, nil, nil, nil, nil, + 74, 74, 74, 74, 74, 74, 74, nil, nil, 74, + nil, nil, nil, nil, nil, nil, 74, nil, nil, 74, + 74, 74, 74, 74, 74, 74, 74, nil, 74, 74, + 74, nil, 74, 74, nil, nil, 74, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 74, nil, nil, 74, nil, nil, 74, + nil, nil, 74, 74, nil, nil, 74, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 74, 74, 74, 74, + nil, 74, 74, 74, 74, nil, nil, nil, nil, 74, + 74, nil, nil, nil, 75, 75, 75, 74, 75, 74, + 74, 74, 75, 75, nil, nil, nil, 75, nil, 75, + 75, 75, 75, 75, 75, 75, nil, nil, nil, nil, + nil, 75, 75, 75, 75, 75, 75, 75, nil, nil, + 75, nil, nil, nil, nil, nil, nil, 75, nil, nil, + 75, 75, 75, 75, 75, 75, 75, 75, nil, 75, + 75, 75, nil, 75, 75, nil, nil, 75, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 75, nil, nil, + 75, nil, nil, 75, 75, nil, nil, 75, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 75, 75, 75, + 75, nil, 75, 75, 75, 75, nil, nil, nil, nil, + 75, 75, nil, nil, nil, 311, 311, 311, 75, 311, + 75, 75, 75, 311, 311, nil, nil, nil, 311, nil, + 311, 311, 311, 311, 311, 311, 311, nil, nil, nil, + nil, nil, 311, 311, 311, 311, 311, 311, 311, nil, + nil, 311, nil, nil, nil, nil, nil, nil, 311, nil, + nil, 311, 311, 311, 311, 311, 311, 311, 311, nil, + 311, 311, 311, nil, 311, 311, nil, nil, 311, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 311, nil, + nil, 311, nil, nil, 311, 311, nil, nil, 311, nil, + nil, 1070, nil, 1070, 1070, 1070, 1070, 1070, nil, nil, + nil, nil, nil, nil, nil, nil, 1070, nil, 311, 311, + 311, 311, nil, 311, 311, 311, 311, nil, nil, nil, + nil, 311, 311, nil, nil, nil, 311, nil, 1070, 311, + nil, 311, 311, 311, 328, 328, 328, nil, 328, 1070, + 1070, nil, 328, 328, 1070, nil, nil, 328, nil, 328, + 328, 328, 328, 328, 328, 328, nil, nil, nil, nil, + nil, 328, 328, 328, 328, 328, 328, 328, nil, nil, + 328, nil, nil, nil, nil, nil, nil, 328, nil, nil, + 328, 328, 328, 328, 328, 328, 328, 328, nil, 328, + 328, 328, nil, 328, 328, nil, nil, 328, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 328, nil, nil, + 328, nil, nil, 328, 328, nil, nil, 328, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 328, 328, 328, + 328, nil, 328, 328, 328, 328, nil, nil, nil, nil, + 328, 328, nil, nil, nil, 525, 525, 525, 328, 525, + 328, 328, 328, 525, 525, nil, nil, nil, 525, nil, + 525, 525, 525, 525, 525, 525, 525, nil, nil, nil, + nil, nil, 525, 525, 525, 525, 525, 525, 525, nil, + nil, 525, nil, nil, nil, nil, nil, nil, 525, nil, + nil, 525, 525, 525, 525, 525, 525, 525, 525, nil, + 525, 525, 525, nil, 525, 525, nil, nil, 525, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 525, nil, + nil, 525, nil, nil, 525, 525, nil, nil, 525, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 525, 525, + 525, 525, nil, 525, 525, 525, 525, nil, nil, nil, + nil, 525, 525, nil, nil, nil, 533, 533, 533, 525, + 533, 525, 525, 525, 533, 533, nil, nil, nil, 533, + nil, 533, 533, 533, 533, 533, 533, 533, nil, nil, + nil, nil, nil, 533, 533, 533, 533, 533, 533, 533, + nil, nil, 533, nil, nil, nil, nil, nil, nil, 533, + nil, nil, 533, 533, 533, 533, 533, 533, 533, 533, + nil, 533, 533, 533, nil, 533, 533, nil, nil, 533, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 533, + nil, nil, 533, nil, nil, 533, 533, nil, nil, 533, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 533, + 533, 533, 533, nil, 533, 533, 533, 533, nil, nil, + nil, nil, 533, 533, nil, nil, nil, 687, 687, 687, + 533, 687, 533, 533, 533, 687, 687, nil, nil, nil, + 687, nil, 687, 687, 687, 687, 687, 687, 687, nil, + nil, nil, nil, nil, 687, 687, 687, 687, 687, 687, + 687, nil, nil, 687, nil, nil, nil, nil, nil, nil, + 687, nil, nil, 687, 687, 687, 687, 687, 687, 687, + 687, nil, 687, 687, 687, nil, 687, 687, nil, nil, + 687, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 687, nil, nil, 687, nil, nil, 687, 687, nil, nil, + 687, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 687, 687, 687, 687, nil, 687, 687, 687, 687, nil, + nil, nil, nil, 687, 687, nil, nil, nil, 698, 698, + 698, 687, 698, 687, 687, 687, 698, 698, nil, nil, + nil, 698, nil, 698, 698, 698, 698, 698, 698, 698, + nil, nil, nil, nil, nil, 698, 698, 698, 698, 698, + 698, 698, nil, nil, 698, nil, nil, nil, nil, nil, + nil, 698, nil, nil, 698, 698, 698, 698, 698, 698, + 698, 698, nil, 698, 698, 698, nil, 698, 698, nil, + nil, 698, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 698, nil, nil, 698, nil, nil, 698, 698, nil, + nil, 698, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 698, 698, 698, 698, nil, 698, 698, 698, 698, + nil, nil, nil, nil, 698, 698, nil, nil, nil, 965, + 965, 965, 698, 965, 698, 698, 698, 965, 965, nil, + nil, nil, 965, nil, 965, 965, 965, 965, 965, 965, + 965, nil, nil, nil, nil, nil, 965, 965, 965, 965, + 965, 965, 965, nil, nil, 965, nil, nil, nil, nil, + nil, nil, 965, nil, nil, 965, 965, 965, 965, 965, + 965, 965, 965, nil, 965, 965, 965, nil, 965, 965, + nil, nil, 965, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 965, nil, nil, 965, nil, nil, 965, 965, + nil, nil, 965, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 965, 965, 965, 965, nil, 965, 965, 965, + 965, nil, nil, nil, nil, 965, 965, nil, nil, nil, + 974, 974, 974, 965, 974, 965, 965, 965, 974, 974, + nil, nil, nil, 974, nil, 974, 974, 974, 974, 974, + 974, 974, nil, nil, nil, nil, nil, 974, 974, 974, + 974, 974, 974, 974, nil, nil, 974, nil, nil, nil, + nil, nil, nil, 974, nil, nil, 974, 974, 974, 974, + 974, 974, 974, 974, nil, 974, 974, 974, nil, 974, + 974, nil, nil, 974, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 974, nil, nil, 974, nil, nil, 974, + 974, nil, nil, 974, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 974, 974, 974, 974, nil, 974, 974, + 974, 974, nil, nil, nil, nil, 974, 974, nil, nil, + nil, 1053, 1053, 1053, 974, 1053, 974, 974, 974, 1053, + 1053, nil, nil, nil, 1053, nil, 1053, 1053, 1053, 1053, + 1053, 1053, 1053, nil, nil, nil, nil, nil, 1053, 1053, + 1053, 1053, 1053, 1053, 1053, nil, nil, 1053, nil, nil, + nil, nil, nil, nil, 1053, nil, nil, 1053, 1053, 1053, + 1053, 1053, 1053, 1053, 1053, nil, 1053, 1053, 1053, nil, + 1053, 1053, nil, nil, 1053, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1053, nil, nil, 1053, nil, nil, + 1053, 1053, nil, nil, 1053, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1053, 1053, 1053, 1053, nil, 1053, + 1053, 1053, 1053, nil, nil, nil, nil, 1053, 1053, nil, + nil, nil, nil, nil, nil, 1053, nil, 1053, 1053, 1053, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, nil, nil, nil, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, nil, nil, nil, + nil, nil, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, nil, 10, nil, nil, nil, nil, nil, nil, + nil, 10, 10, nil, 10, 10, 10, 10, 10, 10, + 10, nil, nil, 10, 10, nil, nil, nil, 10, 10, + 10, 10, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 10, 10, nil, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + nil, nil, 10, 10, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 10, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, nil, nil, nil, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, nil, nil, nil, nil, nil, + 11, 11, 11, 11, 11, 11, 11, 11, 11, nil, + nil, 11, nil, nil, nil, nil, nil, nil, nil, 11, + 11, nil, 11, 11, 11, 11, 11, 11, 11, nil, + nil, 11, 11, nil, nil, nil, 11, 11, 11, 11, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 11, 11, nil, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, nil, nil, + 11, 11, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 11, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + nil, nil, nil, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, nil, nil, nil, nil, nil, 410, 410, + 410, 410, 410, 410, 410, 410, 410, nil, nil, 410, + nil, nil, nil, nil, nil, nil, nil, 410, 410, nil, + 410, 410, 410, 410, 410, 410, 410, nil, nil, 410, + 410, nil, nil, nil, 410, 410, 410, 410, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 410, 410, nil, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, nil, nil, 410, 410, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 410, 606, 606, 606, 606, 606, 606, + 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, + 606, 606, 606, 606, 606, 606, 606, 606, nil, nil, + nil, 606, 606, 606, 606, 606, 606, 606, 606, 606, + 606, nil, nil, nil, nil, nil, 606, 606, 606, 606, + 606, 606, 606, 606, 606, nil, nil, 606, nil, nil, + nil, nil, nil, nil, nil, 606, 606, nil, 606, 606, + 606, 606, 606, 606, 606, nil, nil, 606, 606, nil, + nil, nil, 606, 606, 606, 606, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 606, + 606, nil, 606, 606, 606, 606, 606, 606, 606, 606, + 606, 606, 606, 606, nil, nil, 606, 606, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 606, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, nil, nil, nil, 76, + 76, 76, 76, 76, 76, 76, 76, 76, 76, nil, + nil, nil, nil, nil, 76, 76, 76, 76, 76, 76, + 76, 76, 76, 76, 76, 76, nil, 76, nil, nil, + nil, nil, nil, 76, 76, nil, 76, 76, 76, 76, + 76, 76, 76, nil, nil, 76, 76, nil, nil, nil, + 76, 76, 76, 76, nil, nil, nil, nil, nil, 76, + nil, nil, nil, nil, nil, nil, nil, 76, 76, nil, + 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, + 76, 76, nil, nil, 76, 467, 467, 467, 467, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 467, 467, 467, 467, nil, nil, 709, 467, 709, + 709, 709, 709, 709, 467, 467, nil, nil, 467, nil, + nil, nil, 709, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 467, nil, + nil, 467, nil, nil, 709, 467, nil, nil, 467, nil, + nil, nil, nil, 709, 709, 709, 709, nil, nil, nil, + 709, nil, nil, nil, 467, nil, nil, nil, 467, 467, + 467, 467, nil, 467, 467, 467, 467, nil, nil, nil, + nil, 467, 467, nil, nil, nil, nil, nil, nil, 467, + nil, 467, 467, 467, nil, nil, 467, 467, 772, 772, + 772, 772, 772, 772, 772, 772, 772, 772, 772, 772, + 772, 772, 772, 772, 772, 772, 772, 772, 772, 772, + 772, 772, nil, nil, nil, 772, 772, 772, 772, 772, + 772, 772, 772, 772, 772, nil, nil, nil, nil, nil, + 772, 772, 772, 772, 772, 772, 772, 772, 772, nil, + nil, 772, nil, nil, nil, nil, nil, nil, nil, 772, + 772, nil, 772, 772, 772, 772, 772, 772, 772, nil, + nil, 772, 772, nil, nil, nil, 772, 772, 772, 772, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 772, 772, nil, 772, 772, 772, 772, + 772, 772, 772, 772, 772, 772, 772, 772, nil, nil, + 772, 816, 816, 816, 816, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 816, 816, 816, + 816, nil, nil, 771, 816, 771, 771, 771, 771, 771, + 816, 816, nil, nil, 816, nil, nil, nil, 771, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 816, nil, nil, 816, nil, nil, + 771, 816, nil, nil, 816, nil, nil, nil, nil, 771, + 771, 771, 771, nil, nil, nil, 771, nil, nil, nil, + 816, nil, nil, nil, 816, 816, 816, 816, nil, 816, + 816, 816, 816, nil, nil, nil, nil, 816, 816, 819, + 819, 819, 819, nil, nil, 816, nil, 816, 816, 816, + nil, nil, 816, 816, nil, 819, 819, 819, 819, nil, + nil, nil, 819, 819, nil, nil, nil, nil, 819, 819, + nil, nil, 819, 819, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 819, nil, nil, 819, nil, nil, nil, 819, + nil, nil, 819, nil, 819, nil, nil, nil, nil, nil, + nil, 819, nil, nil, nil, nil, nil, nil, 819, nil, + nil, nil, 819, 819, 819, 819, nil, 819, 819, 819, + 819, nil, nil, nil, nil, 819, 819, 820, 820, 820, + 820, nil, nil, 819, nil, 819, 819, 819, nil, nil, + 819, 819, nil, 820, 820, 820, 820, nil, nil, nil, + 820, 820, nil, nil, nil, nil, 820, 820, nil, nil, + 820, 820, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 820, nil, nil, 820, nil, nil, nil, 820, nil, nil, + 820, nil, 820, nil, nil, nil, nil, nil, nil, 820, + nil, nil, nil, nil, nil, nil, 820, nil, nil, nil, + 820, 820, 820, 820, nil, 820, 820, 820, 820, nil, + nil, nil, nil, 820, 820, 822, 822, 822, 822, nil, + nil, 820, nil, 820, 820, 820, nil, nil, 820, 820, + nil, 822, 822, 822, 822, nil, nil, 870, 822, 870, + 870, 870, 870, 870, 822, 822, nil, nil, 822, nil, + nil, nil, 870, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 822, nil, + nil, 822, nil, nil, 870, 822, nil, nil, 822, nil, + 822, nil, nil, 870, 870, 870, 870, nil, nil, nil, + 870, nil, nil, nil, 822, nil, nil, nil, 822, 822, + 822, 822, nil, 822, 822, 822, 822, nil, nil, nil, + nil, 822, 822, 827, 827, 827, 827, nil, nil, 822, + nil, 822, 822, 822, nil, nil, 822, 822, nil, 827, + 827, 827, 827, nil, nil, 872, 827, 872, 872, 872, + 872, 872, 827, 827, nil, nil, 827, nil, nil, nil, + 872, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 827, nil, nil, 827, + nil, nil, 872, 827, nil, nil, 827, nil, nil, nil, + nil, 872, 872, 872, 872, nil, nil, nil, 872, nil, + nil, nil, 827, nil, nil, nil, 827, 827, 827, 827, + nil, 827, 827, 827, 827, nil, nil, nil, nil, 827, + 827, 895, 895, 895, 895, nil, nil, 827, nil, 827, + 827, 827, nil, nil, 827, 827, nil, 895, 895, 895, + 895, nil, nil, nil, 895, 895, nil, nil, nil, nil, + 895, 895, nil, nil, 895, 895, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 895, nil, nil, 895, nil, nil, + nil, 895, nil, nil, 895, nil, 895, nil, nil, nil, + nil, nil, nil, 895, nil, nil, nil, nil, nil, nil, + 895, nil, nil, nil, 895, 895, 895, 895, nil, 895, + 895, 895, 895, nil, nil, nil, nil, 895, 895, 926, + 926, 926, 926, nil, nil, 895, nil, 895, 895, 895, + nil, nil, 895, 895, nil, 926, 926, 926, 926, nil, + nil, 1044, 926, 1044, 1044, 1044, 1044, 1044, 926, 926, + nil, nil, 926, nil, nil, nil, 1044, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 926, nil, nil, 926, nil, nil, 1044, 926, + nil, nil, 926, nil, 926, nil, nil, 1044, 1044, 1044, + 1044, nil, nil, nil, 1044, nil, nil, nil, 926, nil, + nil, nil, 926, 926, 926, 926, nil, 926, 926, 926, + 926, nil, nil, nil, nil, 926, 926, 934, 934, 934, + 934, nil, nil, 926, nil, 926, 926, 926, nil, nil, + 926, 926, nil, 934, 934, 934, 934, nil, nil, 1046, + 934, 1046, 1046, 1046, 1046, 1046, 934, 934, nil, nil, + 934, nil, nil, nil, 1046, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 934, nil, nil, 934, nil, nil, 1046, 934, nil, nil, + 934, nil, nil, nil, nil, 1046, 1046, 1046, 1046, nil, + nil, nil, 1046, nil, nil, nil, 934, nil, nil, nil, + 934, 934, 934, 934, nil, 934, 934, 934, 934, nil, + nil, nil, nil, 934, 934, 1027, 1027, 1027, 1027, nil, + nil, 934, nil, 934, 934, 934, nil, nil, 934, 934, + nil, 1027, 1027, 1027, 1027, nil, nil, 1068, 1027, 1068, + 1068, 1068, 1068, 1068, 1027, 1027, nil, nil, 1027, nil, + nil, nil, 1068, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 1027, nil, + nil, 1027, nil, nil, 1068, 1027, nil, nil, 1027, nil, + nil, nil, nil, 1068, 1068, 1068, 1068, nil, nil, nil, + 1068, nil, nil, nil, 1027, nil, nil, nil, 1027, 1027, + 1027, 1027, nil, 1027, 1027, 1027, 1027, nil, nil, nil, + nil, 1027, 1027, 1085, 1085, 1085, 1085, nil, nil, 1027, + nil, 1027, 1027, 1027, nil, nil, 1027, 1027, nil, 1085, + 1085, 1085, 1085, nil, nil, 1072, 1085, 1072, 1072, 1072, + 1072, 1072, 1085, 1085, nil, nil, 1085, nil, nil, nil, + 1072, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1085, nil, nil, 1085, + nil, nil, 1072, 1085, nil, nil, 1085, nil, 1085, nil, + nil, nil, nil, 1072, 1072, nil, nil, nil, 1072, nil, + nil, nil, 1085, nil, nil, nil, 1085, 1085, 1085, 1085, + nil, 1085, 1085, 1085, 1085, nil, nil, nil, nil, 1085, + 1085, 1094, 1094, 1094, 1094, nil, nil, 1085, nil, 1085, + 1085, 1085, nil, nil, 1085, 1085, nil, 1094, 1094, 1094, + 1094, nil, nil, 1074, 1094, 1074, 1074, 1074, 1074, 1074, + 1094, 1094, nil, nil, 1094, nil, nil, nil, 1074, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1094, nil, nil, 1094, nil, nil, + 1074, 1094, nil, nil, 1094, nil, nil, nil, nil, nil, + nil, 1074, 1074, nil, nil, nil, 1074, nil, nil, nil, + 1094, nil, nil, nil, 1094, 1094, 1094, 1094, nil, 1094, + 1094, 1094, 1094, nil, nil, nil, nil, 1094, 1094, 1095, + 1095, 1095, 1095, nil, nil, 1094, nil, 1094, 1094, 1094, + nil, nil, 1094, 1094, nil, 1095, 1095, 1095, 1095, nil, + nil, 1144, 1095, 1144, 1144, 1144, 1144, 1144, 1095, 1095, + nil, nil, 1095, nil, nil, nil, 1144, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1095, nil, nil, 1095, nil, nil, 1144, 1095, + nil, nil, 1095, nil, nil, nil, nil, 1144, 1144, 1144, + 1144, nil, nil, nil, 1144, nil, nil, nil, 1095, nil, + nil, nil, 1095, 1095, 1095, 1095, nil, 1095, 1095, 1095, + 1095, nil, nil, nil, nil, 1095, 1095, 1139, 1139, 1139, + 1139, nil, nil, 1095, nil, 1095, 1095, 1095, nil, nil, + 1095, 1095, nil, 1139, 1139, 1139, 1139, nil, nil, 1146, + 1139, 1146, 1146, 1146, 1146, 1146, 1139, 1139, nil, nil, + 1139, nil, nil, nil, 1146, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1139, nil, nil, 1139, nil, nil, 1146, 1139, nil, nil, + 1139, nil, nil, nil, nil, nil, nil, 1146, 1146, nil, + nil, nil, 1146, nil, nil, nil, 1139, nil, nil, nil, + 1139, 1139, 1139, 1139, nil, 1139, 1139, 1139, 1139, nil, + nil, nil, nil, 1139, 1139, 1142, 1142, 1142, 1142, nil, + nil, 1139, nil, 1139, 1139, 1139, nil, nil, 1139, 1139, + nil, 1142, 1142, 1142, 1142, nil, nil, nil, 1142, nil, + nil, nil, nil, nil, 1142, 1142, nil, nil, 1142, nil, + nil, nil, nil, nil, nil, nil, 650, 650, 650, 650, + nil, nil, nil, nil, nil, nil, nil, nil, 1142, nil, + nil, 1142, 650, 650, 650, 1142, nil, nil, 1142, nil, + nil, nil, nil, nil, nil, 650, 650, nil, nil, 650, + nil, nil, nil, nil, 1142, nil, nil, nil, 1142, 1142, + 1142, 1142, nil, 1142, 1142, 1142, 1142, nil, nil, nil, + nil, 1142, 1142, nil, nil, nil, nil, nil, nil, 1142, + nil, 1142, 1142, 1142, nil, nil, 1142, 1142, 1148, nil, + 1148, 1148, 1148, 1148, 1148, nil, nil, nil, nil, 650, + 650, 650, 650, 1148, 650, 650, 650, 650, nil, nil, + nil, nil, 650, 650, 828, 828, 828, 828, nil, nil, + 650, nil, 650, 650, 650, 1148, nil, nil, nil, nil, + 828, 828, 828, nil, nil, nil, 1148, 1148, nil, nil, + nil, 1148, nil, 828, 828, nil, nil, 828, 829, 829, + 829, 829, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 829, 829, 829, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 829, 829, nil, + nil, 829, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 828, 828, 828, + 828, nil, 828, 828, 828, 828, nil, nil, nil, nil, + 828, 828, nil, nil, nil, nil, nil, nil, 828, nil, + 828, 828, 828, nil, nil, nil, nil, nil, nil, nil, + nil, 829, 829, 829, 829, nil, 829, 829, 829, 829, + nil, nil, nil, nil, 829, 829, 222, 222, nil, nil, + 222, nil, 829, nil, 829, 829, 829, nil, 222, 222, + nil, 222, 222, 222, 222, 222, 222, 222, nil, nil, + 222, 222, nil, nil, nil, 222, 222, 222, 222, nil, + nil, nil, nil, nil, 222, nil, nil, nil, nil, nil, + nil, nil, 222, 222, nil, 222, 222, 222, 222, 222, + 222, 222, 222, 222, 222, 222, 222, 223, 223, 222, + nil, 223, nil, nil, nil, nil, nil, nil, nil, 223, + 223, nil, 223, 223, 223, 223, 223, 223, 223, nil, + nil, 223, 223, nil, nil, nil, 223, 223, 223, 223, + nil, nil, nil, nil, nil, 223, nil, nil, nil, nil, + nil, nil, nil, 223, 223, nil, 223, 223, 223, 223, + 223, 223, 223, 223, 223, 223, 223, 223, 272, 272, + 223, nil, 272, nil, nil, nil, nil, nil, nil, nil, + 272, 272, nil, 272, 272, 272, 272, 272, 272, 272, + nil, nil, 272, 272, nil, nil, nil, 272, 272, 272, + 272, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 272, 272, nil, 272, 272, 272, + 272, 272, 272, 272, 272, 272, 272, 272, 272, 460, + 460, 272, nil, 460, nil, nil, nil, nil, nil, nil, + nil, 460, 460, nil, 460, 460, 460, 460, 460, 460, + 460, nil, nil, 460, 460, nil, nil, nil, 460, 460, + 460, 460, nil, nil, nil, nil, nil, 460, nil, nil, + nil, nil, nil, nil, nil, 460, 460, nil, 460, 460, + 460, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 461, 461, 460, nil, 461, nil, nil, nil, nil, nil, + nil, nil, 461, 461, nil, 461, 461, 461, 461, 461, + 461, 461, nil, nil, 461, 461, nil, nil, nil, 461, + 461, 461, 461, nil, nil, nil, nil, nil, 461, nil, + nil, nil, nil, nil, nil, nil, 461, 461, nil, 461, + 461, 461, 461, 461, 461, 461, 461, 461, 461, 461, + 461, 528, 528, 461, nil, 528, nil, nil, nil, nil, + nil, nil, nil, 528, 528, nil, 528, 528, 528, 528, + 528, 528, 528, nil, nil, 528, 528, nil, nil, nil, + 528, 528, 528, 528, nil, nil, nil, nil, nil, 528, + nil, nil, nil, nil, nil, nil, nil, 528, 528, nil, + 528, 528, 528, 528, 528, 528, 528, 528, 528, 528, + 528, 528, 529, 529, 528, nil, 529, nil, nil, nil, + nil, nil, nil, nil, 529, 529, nil, 529, 529, 529, + 529, 529, 529, 529, nil, nil, 529, 529, nil, nil, + nil, 529, 529, 529, 529, nil, nil, nil, nil, nil, + 529, nil, nil, nil, nil, nil, nil, nil, 529, 529, + nil, 529, 529, 529, 529, 529, 529, 529, 529, 529, + 529, 529, 529, 537, 537, 529, nil, 537, nil, nil, + nil, nil, nil, nil, nil, 537, 537, nil, 537, 537, + 537, 537, 537, 537, 537, nil, nil, 537, 537, nil, + nil, nil, 537, 537, 537, 537, nil, nil, nil, nil, + nil, 537, nil, nil, nil, nil, nil, nil, nil, 537, + 537, nil, 537, 537, 537, 537, 537, 537, 537, 537, + 537, 537, 537, 537, 538, 538, 537, nil, 538, nil, + nil, nil, nil, nil, nil, nil, 538, 538, nil, 538, + 538, 538, 538, 538, 538, 538, nil, nil, 538, 538, + nil, nil, nil, 538, 538, 538, 538, nil, nil, nil, + nil, nil, 538, nil, nil, nil, nil, nil, nil, nil, + 538, 538, nil, 538, 538, 538, 538, 538, 538, 538, + 538, 538, 538, 538, 538, 568, 568, 538, nil, 568, + nil, nil, nil, nil, nil, nil, nil, 568, 568, nil, + 568, 568, 568, 568, 568, 568, 568, nil, nil, 568, + 568, nil, nil, nil, 568, 568, 568, 568, nil, nil, + nil, nil, nil, 568, nil, nil, nil, nil, nil, nil, + nil, 568, 568, nil, 568, 568, 568, 568, 568, 568, + 568, 568, 568, 568, 568, 568, 569, 569, 568, nil, + 569, nil, nil, nil, nil, nil, nil, nil, 569, 569, + nil, 569, 569, 569, 569, 569, 569, 569, nil, nil, + 569, 569, nil, nil, nil, 569, 569, 569, 569, nil, + nil, nil, nil, nil, 569, nil, nil, nil, nil, nil, + nil, nil, 569, 569, nil, 569, 569, 569, 569, 569, + 569, 569, 569, 569, 569, 569, 569, 575, 575, 569, + nil, 575, nil, nil, nil, nil, nil, nil, nil, 575, + 575, nil, 575, 575, 575, 575, 575, 575, 575, nil, + nil, 575, 575, nil, nil, nil, 575, 575, 575, 575, + nil, nil, nil, nil, nil, 575, nil, nil, nil, nil, + nil, nil, nil, 575, 575, nil, 575, 575, 575, 575, + 575, 575, 575, 575, 575, 575, 575, 575, 576, 576, + 575, nil, 576, nil, nil, nil, nil, nil, nil, nil, + 576, 576, nil, 576, 576, 576, 576, 576, 576, 576, + nil, nil, 576, 576, nil, nil, nil, 576, 576, 576, + 576, nil, nil, nil, nil, nil, 576, nil, nil, nil, + nil, nil, nil, nil, 576, 576, nil, 576, 576, 576, + 576, 576, 576, 576, 576, 576, 576, 576, 576, 613, + 613, 576, nil, 613, nil, nil, nil, nil, nil, nil, + nil, 613, 613, nil, 613, 613, 613, 613, 613, 613, + 613, nil, nil, 613, 613, nil, nil, nil, 613, 613, + 613, 613, nil, nil, nil, nil, nil, 613, nil, nil, + nil, nil, nil, nil, nil, 613, 613, nil, 613, 613, + 613, 613, 613, 613, 613, 613, 613, 613, 613, 613, + 614, 614, 613, nil, 614, nil, nil, nil, nil, nil, + nil, nil, 614, 614, nil, 614, 614, 614, 614, 614, + 614, 614, nil, nil, 614, 614, nil, nil, nil, 614, + 614, 614, 614, nil, nil, nil, nil, nil, 614, nil, + nil, nil, nil, nil, nil, nil, 614, 614, nil, 614, + 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, + 614, 1117, 1117, 614, nil, 1117, nil, nil, nil, nil, + nil, nil, nil, 1117, 1117, nil, 1117, 1117, 1117, 1117, + 1117, 1117, 1117, nil, nil, 1117, 1117, nil, nil, nil, + 1117, 1117, 1117, 1117, nil, nil, nil, nil, nil, 1117, + nil, nil, nil, nil, nil, nil, nil, 1117, 1117, nil, + 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, 1117, + 1117, 1117, 1121, 1121, 1117, nil, 1121, nil, nil, nil, + nil, nil, nil, nil, 1121, 1121, nil, 1121, 1121, 1121, + 1121, 1121, 1121, 1121, nil, nil, 1121, 1121, nil, nil, + nil, 1121, 1121, 1121, 1121, nil, nil, nil, nil, nil, + 1121, nil, nil, nil, nil, nil, nil, nil, 1121, 1121, + nil, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1121, + 1121, 1121, 1121, 1122, 1122, 1121, nil, 1122, nil, nil, + nil, nil, nil, nil, nil, 1122, 1122, nil, 1122, 1122, + 1122, 1122, 1122, 1122, 1122, nil, nil, 1122, 1122, nil, + nil, nil, 1122, 1122, 1122, 1122, nil, nil, nil, nil, + nil, 1122, nil, nil, nil, nil, nil, nil, nil, 1122, + 1122, nil, 1122, 1122, 1122, 1122, 1122, 1122, 1122, 1122, + 1122, 1122, 1122, 1122, nil, 1150, 1122, 1150, 1150, 1150, + 1150, 1150, 1165, nil, 1165, 1165, 1165, 1165, 1165, 1186, + 1150, 1186, 1186, 1186, 1186, 1186, nil, 1165, nil, nil, + nil, nil, nil, nil, 1186, nil, nil, nil, nil, nil, + nil, nil, 1150, nil, nil, nil, nil, nil, nil, 1165, + nil, nil, nil, 1150, 1150, nil, 1186, nil, 1150, nil, + 1165, 1165, nil, nil, nil, 1165, nil, 1186, 1186, nil, + nil, nil, 1186 ] + +racc_action_pointer = [ + nil, 5, 979, 85, nil, -110, nil, 5154, 741, 97, + 23788, 23916, 159, nil, 157, 191, 441, 265, -62, 374, + nil, -68, 5285, 1123, 338, nil, 226, nil, -8, 5426, + 5536, 5670, 5801, 5932, nil, 1123, 21930, 22061, nil, 245, + 468, 531, 330, 6063, 6194, 205, 6325, 6456, 525, 6587, + 266, 279, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 6728, nil, 6869, 7000, 7131, 35, nil, 7262, 7393, + nil, nil, 7524, 22200, 22331, 22462, 24300, nil, nil, nil, + nil, nil, nil, nil, nil, 723, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 0, nil, nil, 112, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 7667, nil, nil, nil, nil, 7810, 7941, 8072, 8203, + 8346, nil, 1267, nil, -1, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 290, nil, 1411, 8477, 8608, 8739, 8870, + 9001, 9132, 26135, 26196, nil, nil, 9263, 9394, 9525, nil, + nil, 342, 141, 162, 376, 193, 303, 366, nil, 9656, + 1555, 402, nil, 9787, 9918, 10049, 10180, 10311, 10442, 10573, + 10704, 10835, 10966, 11097, 11228, 11359, 11490, 11621, 11752, 11883, + 12014, 12145, 12276, 12407, 12538, nil, nil, nil, nil, 12669, + nil, nil, 26257, nil, nil, 421, 12800, 12931, nil, nil, + nil, nil, nil, nil, nil, 13062, nil, 1555, nil, 399, + 429, nil, 13193, 481, 13324, nil, nil, 13455, 13586, nil, + nil, 264, nil, 13729, 1252, 465, 469, 1699, 492, 547, + 512, 22593, 1843, 514, 518, 550, 603, 582, nil, 576, + 571, 225, nil, nil, nil, 618, 221, 607, 22732, nil, + 564, 584, 2419, 2563, 686, nil, 690, 13860, nil, 13991, + 1987, 1396, 630, nil, 431, 514, 672, 655, 583, 690, + nil, nil, 593, -1, 11, 14122, 2131, 2275, 511, 786, + 674, -18, 10, 694, 756, 11, 797, nil, nil, 441, + 481, 4, nil, 806, nil, 731, 14253, nil, nil, nil, + 302, 515, 532, 558, 585, 586, 627, 671, 702, nil, + 726, nil, 14384, nil, 193, 378, 396, 402, 412, -27, + 195, 463, nil, nil, nil, nil, nil, nil, nil, 741, + 24044, nil, nil, nil, nil, 743, nil, 817, 733, 14515, + 736, nil, nil, 727, nil, 873, 246, 835, nil, nil, + 1267, nil, nil, nil, nil, nil, 1411, 763, nil, 790, + 800, 681, 746, 14656, nil, nil, nil, 222, 334, 849, + nil, nil, 14788, 14924, nil, nil, nil, -35, nil, 859, + 26318, 26379, 15061, 253, 15192, 15323, 15454, 24383, 2707, 2851, + 823, 856, 885, 886, 887, 894, 4435, 4579, 4723, 2995, + 3139, 3283, 3427, 3571, 3715, 2447, 2591, 3859, 4003, 1699, + 4147, nil, 15595, nil, nil, nil, nil, 15725, 838, 840, + 844, nil, nil, nil, 848, nil, nil, 15856, nil, 15987, + nil, 16118, nil, 329, nil, nil, nil, 16261, 1540, nil, + 857, 855, nil, nil, 859, 22863, 863, 16404, 26440, 26501, + 878, 915, nil, 22994, 872, nil, 16535, 26562, 26623, 16666, + 4291, 1843, 16797, 999, 998, 886, 928, nil, 16928, nil, + nil, 17059, nil, nil, nil, nil, 15598, 2419, 1007, nil, + 2563, 62, 1013, 1039, 398, 1041, 17190, 17321, 26684, 26745, + 27, nil, nil, 879, nil, 26806, 26867, 17452, nil, nil, + 81, 2707, 964, nil, -33, nil, nil, nil, 1033, nil, + nil, nil, 939, nil, nil, 153, nil, 263, nil, nil, + 926, nil, 928, nil, nil, nil, 24172, nil, 17595, 933, + 17726, 17857, 17988, 26928, 26989, 18131, 18262, 858, 974, 18393, + 18524, 18655, 18786, 973, nil, nil, 18917, 19048, 977, nil, + nil, nil, 306, 343, 473, 612, 945, 990, nil, 969, + nil, nil, 440, 252, 94, nil, 655, nil, nil, 6728, + 25924, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1030, 201, nil, 951, 1075, nil, 1058, 91, + nil, nil, 19179, nil, 980, 989, 1094, nil, 972, nil, + 1019, 19310, nil, nil, 19441, nil, 363, 23125, 976, nil, + 981, 236, 250, 1024, 360, 962, 1027, 987, 23256, nil, + 1055, -7, 1116, 19572, nil, nil, nil, 707, nil, 24386, + nil, 998, 999, 1002, nil, 1003, 1006, 1015, nil, nil, + nil, nil, nil, nil, nil, nil, 1004, 2261, nil, nil, + 19703, nil, nil, nil, -1, nil, nil, nil, 1099, nil, + nil, 1100, 737, nil, 1145, nil, nil, nil, nil, nil, + 1156, 1170, nil, nil, 26, 1053, 40, 41, 151, 152, + 2851, 970, 968, nil, 1070, 2995, 19834, nil, 1194, 3139, + 719, 24612, 24526, nil, nil, nil, nil, nil, nil, 3283, + nil, nil, nil, nil, nil, nil, nil, nil, 1071, 19965, + 1077, 347, 445, 722, 834, nil, 1987, 20096, nil, 1076, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 20227, 20358, 20489, 20620, 449, 1159, 24609, -41, 260, 24707, + 24805, 258, 24903, nil, 359, nil, 1100, 25001, 26022, 26056, + nil, nil, nil, nil, nil, nil, 20751, nil, 1107, nil, + nil, 1104, 1089, nil, nil, 15559, 3427, nil, nil, nil, + nil, 1094, 338, nil, nil, 1227, nil, 3571, 1103, 1150, + nil, nil, nil, 63, 1112, 1156, nil, nil, 746, nil, + 24906, nil, 25004, nil, 14719, nil, 20882, nil, 2290, nil, + 1114, 1115, 841, 1119, nil, nil, nil, nil, nil, 1241, + nil, 21013, 1244, nil, nil, 25099, 21144, 3715, 68, 1248, + nil, 1249, 537, 3859, nil, 1255, 1135, 1141, 1145, nil, + 602, nil, 1149, 1146, 486, nil, nil, 21275, 21406, nil, + nil, nil, nil, -77, 1150, 1151, 25197, nil, 1150, -32, + 1170, nil, nil, nil, 25295, nil, nil, 218, 1174, 1176, + nil, 1177, 1178, nil, nil, -69, nil, nil, nil, 2131, + 4003, nil, nil, 1176, 1190, 1194, nil, 1211, 1214, 1215, + nil, 1242, 1223, 1219, 1211, 23387, nil, nil, nil, nil, + 4147, nil, nil, 32, 23518, nil, nil, nil, nil, 1267, + 1227, nil, 1310, nil, nil, 1230, 1233, nil, 1238, 1246, + nil, 1247, nil, nil, 1251, 2320, 2300, nil, nil, nil, + 33, nil, 34, 841, 139, nil, nil, nil, 657, nil, + nil, nil, 1377, nil, nil, 831, nil, nil, 1302, nil, + nil, nil, 1305, 1260, 71, nil, 1261, 25393, 637, 1310, + 333, nil, nil, nil, nil, nil, nil, 370, nil, nil, + 1444, nil, nil, nil, 25200, nil, 25298, nil, 22108, nil, + nil, 1290, 1109, 23649, 893, 1346, nil, 4291, 35, 36, + 972, 1347, 42, nil, 4435, 4579, nil, nil, 25396, nil, + 22640, nil, 25494, nil, 25592, nil, nil, nil, nil, 1271, + 1275, 4723, nil, 21537, 21668, 25491, nil, nil, nil, nil, + 1279, 4867, nil, 1285, 25589, 25687, 1286, nil, nil, nil, + nil, nil, 1287, nil, nil, 1290, 1291, 1292, 1294, nil, + 1314, nil, 732, nil, nil, nil, 995, 27050, nil, 1441, + 21799, 27111, 27172, 98, 1337, 1442, 1319, 1320, 1334, 1338, + 2787, 2931, 901, 5011, nil, nil, nil, nil, 1479, 25785, + 1358, 1359, 25883, nil, 25690, nil, 25788, nil, 25977, nil, + 27234, nil, nil, nil, 1541, 1406, 1408, nil, 1368, 102, + 138, 145, 181, nil, nil, 27241, nil, nil, nil, nil, + 1368, nil, 39, nil, 1371, nil, 1372, 1374, 1382, 1390, + nil, 146, 1391, nil, nil, nil, 27248, nil, nil, nil, + nil, nil, 1392, nil ] + +racc_action_default = [ + -1, -716, -4, -716, -2, -701, -5, -716, -8, -716, + -716, -716, -716, -31, -716, -716, -36, -716, -716, -295, + -48, -703, -716, -55, -59, -60, -61, -65, -272, -272, + -272, -308, -339, -340, -77, -13, -81, -89, -91, -716, + -600, -601, -716, -716, -716, -716, -716, -716, -229, -716, + -703, -243, -286, -287, -288, -289, -290, -291, -292, -293, + -294, -689, -297, -301, -715, -679, -316, -318, -716, -716, + -57, -57, -701, -716, -716, -716, -716, -341, -342, -344, + -345, -346, -347, -540, -541, -542, -543, -564, -546, -547, + -566, -568, -551, -556, -560, -562, -578, -579, -580, -564, + -582, -584, -585, -586, -587, -687, -589, -590, -688, -592, + -593, -594, -595, -596, -597, -598, -599, -604, -605, 1194, + -3, -702, -711, -712, -713, -7, -716, -716, -716, -716, + -716, -9, -4, -19, -716, -120, -121, -122, -123, -124, + -125, -126, -130, -131, -132, -133, -134, -135, -136, -137, + -138, -139, -140, -141, -142, -143, -144, -145, -146, -147, + -148, -149, -150, -151, -152, -153, -154, -155, -156, -157, + -158, -159, -160, -161, -162, -163, -164, -165, -166, -167, + -168, -169, -170, -171, -172, -173, -174, -175, -176, -177, + -178, -179, -180, -181, -182, -183, -184, -185, -186, -187, + -188, -189, -190, -191, -192, -193, -194, -195, -196, -197, + -198, -199, -200, -24, -127, -13, -716, -716, -716, -716, + -716, -262, -716, -716, -699, -700, -716, -716, -703, -704, + -52, -716, -600, -601, -716, -295, -716, -716, -235, -716, + -13, -716, -53, -212, -213, -716, -716, -716, -716, -716, + -716, -716, -716, -716, -716, -716, -716, -716, -716, -716, + -716, -716, -716, -716, -716, -244, -245, -246, -247, -716, + -411, -413, -716, -697, -698, -66, -262, -716, -315, -417, + -426, -428, -72, -423, -73, -703, -74, -250, -267, -276, + -276, -271, -716, -277, -716, -564, -681, -716, -716, -75, + -76, -701, -14, -716, -17, -716, -79, -13, -703, -716, + -82, -85, -13, -97, -98, -716, -716, -105, -308, -311, + -703, -716, -339, -340, -343, -424, -716, -87, -716, -93, + -305, -716, -214, -215, -583, -223, -224, -716, -236, -716, + -13, -299, -703, -251, -708, -708, -716, -716, -708, -716, + -317, -402, -56, -716, -716, -716, -13, -13, -701, -716, + -702, -600, -601, -716, -716, -295, -716, -357, -358, -115, + -116, -716, -118, -716, -295, -608, -716, -600, -601, -332, + -120, -121, -160, -161, -162, -178, -183, -190, -193, -334, + -716, -677, -716, -544, -716, -716, -716, -716, -716, -716, + -716, -716, -6, -714, -25, -26, -27, -28, -29, -716, + -716, -21, -22, -23, -128, -716, -32, -35, -282, -716, + -716, -281, -33, -716, -37, -716, -295, -45, -47, -201, + -255, -277, -49, -50, -38, -202, -255, -703, -263, -276, + -276, -690, -691, -272, -421, -692, -693, -691, -690, -272, + -420, -422, -692, -693, -44, -209, -51, -703, -314, -716, + -716, -716, -262, -305, -716, -716, -716, -716, -210, -211, + -216, -217, -218, -219, -220, -221, -225, -226, -227, -228, + -230, -231, -232, -233, -234, -237, -238, -239, -240, -703, + -248, -432, -272, -690, -691, -63, -67, -636, -703, -276, + -703, -273, -430, -432, -703, -310, -268, -716, -269, -716, + -274, -716, -278, -716, -684, -686, -12, -702, -16, -18, + -703, -78, -303, -94, -83, -716, -703, -262, -716, -716, + -104, -716, -583, -716, -90, -95, -716, -716, -716, -716, + -249, -241, -716, -532, -716, -703, -716, -252, -710, -709, + -254, -710, -306, -307, -680, -319, -635, -13, -348, -349, + -13, -716, -716, -716, -716, -716, -716, -262, -716, -716, + -305, -57, -115, -116, -117, -716, -716, -262, -328, -606, + -716, -13, -612, -336, -703, -545, -565, -570, -716, -572, + -548, -567, -716, -569, -550, -716, -553, -716, -555, -558, + -716, -559, -716, -581, -10, -20, -716, -30, -716, -285, + -716, -716, -262, -716, -716, -716, -716, -425, -716, -264, + -266, -716, -716, -68, -261, -418, -716, -716, -70, -419, + -313, -705, -690, -691, -690, -691, -703, -54, -451, -453, + -455, -458, -512, -465, -468, -471, -505, -510, -511, -716, + -716, -515, -516, -517, -518, -519, -520, -521, -522, -523, + -524, -526, -716, -716, -530, -716, -716, -433, -62, -414, + -430, -257, -264, -259, -716, -392, -716, -309, -276, -275, + -279, -716, -682, -683, -716, -15, -80, -716, -86, -92, + -703, -690, -691, -260, -694, -103, -716, -88, -716, -208, + -222, -703, -715, -715, -298, -300, -302, -708, -403, -635, + -406, -676, -676, -676, -618, -620, -620, -620, -634, -637, + -638, -639, -640, -641, -642, -643, -644, -716, -646, -648, + -650, -655, -657, -658, -661, -666, -668, -669, -671, -672, + -673, -716, -715, -350, -715, -58, -351, -352, -322, -323, + -716, -716, -438, -325, -716, -703, -690, -691, -694, -304, + -13, -115, -116, -119, -703, -13, -716, -330, -716, -13, + -635, -635, -716, -678, -571, -574, -575, -576, -577, -13, + -549, -552, -554, -557, -561, -563, -129, -34, -283, -716, + -703, -690, -691, -691, -690, -46, -256, -716, -706, -276, + -40, -204, -41, -205, -69, -42, -207, -43, -206, -71, + -716, -716, -716, -716, -425, -716, -716, -456, -457, -716, + -716, -716, -716, -467, -716, -470, -716, -716, -508, -509, + -513, -514, -402, -527, -116, -528, -716, -412, -392, -416, + -415, -716, -703, -427, -393, -703, -13, -429, -270, -280, + -685, -84, -425, -96, -312, -715, -355, -13, -533, -715, + -534, -535, -253, -716, -703, -716, -615, -616, -716, -617, + -716, -627, -716, -630, -716, -632, -716, -359, -716, -361, + -363, -366, -369, -703, -649, -659, -660, -670, -674, -716, + -353, -716, -716, -324, -326, -716, -716, -13, -425, -716, + -425, -716, -716, -13, -333, -716, -703, -620, -703, -636, + -716, -337, -716, -284, -425, -39, -203, -265, -716, -452, + -454, -461, -464, -473, -703, -703, -474, -480, -716, -485, + -491, -493, -495, -496, -499, -500, -564, -503, -703, -703, + -529, -703, -703, -564, -707, -703, -506, -507, -525, -242, + -13, -64, -258, -676, -676, -676, -374, -376, -376, -376, + -391, -716, -703, -396, -644, -652, -653, -664, -431, -11, + -13, -539, -356, -716, -716, -537, -404, -407, -409, -716, + -676, -656, -661, -675, -619, -620, -620, -647, -620, -620, + -667, -620, -644, -662, -703, -716, -716, -368, -645, -320, + -716, -321, -716, -443, -446, -449, -450, -279, -715, -327, + -329, -607, -716, -335, -609, -716, -611, -613, -612, -573, + -459, -460, -489, -475, -478, -481, -483, -716, -492, -498, + -716, -502, -504, -462, -463, -466, -469, -716, -472, -434, + -716, -371, -372, -373, -382, -384, -716, -387, -716, -389, + -394, -716, -716, -716, -651, -716, -538, -13, -600, -601, + -716, -716, -295, -536, -13, -13, -405, -614, -716, -623, + -716, -625, -716, -628, -716, -631, -633, -360, -362, -364, + -367, -13, -439, -716, -716, -447, -435, -436, -437, -331, + -703, -13, -482, -476, -716, -716, -486, -487, -490, -494, + -497, -501, -676, -654, -375, -376, -376, -376, -376, -665, + -376, -395, -703, -398, -400, -401, -663, -716, -305, -532, + -262, -716, -716, -305, -716, -716, -620, -620, -620, -620, + -716, -716, -715, -13, -444, -445, -448, -610, -716, -716, + -479, -484, -716, -370, -716, -379, -716, -381, -716, -385, + -716, -388, -390, -397, -716, -304, -694, -531, -703, -690, + -691, -694, -304, -408, -410, -716, -621, -624, -626, -629, + -365, -354, -715, -338, -477, -488, -376, -376, -376, -376, + -399, -425, -620, -440, -441, -442, -716, -377, -380, -383, + -386, -622, -376, -378 ] + +racc_goto_table = [ + 41, 288, 288, 288, 389, 41, 222, 353, 354, 227, + 124, 358, 500, 271, 273, 394, 557, 560, 751, 350, + 343, 565, 702, 437, 279, 283, 555, 401, 352, 352, + 544, 889, 352, 41, 314, 314, 15, 769, 339, 310, + 508, 15, 356, 357, 637, 877, 289, 289, 289, 682, + 496, 421, 422, 574, 133, 214, 534, 324, 324, 334, + 679, 41, 679, 272, 121, 404, 405, 406, 407, 15, + 855, 362, 378, 378, 378, 131, 120, 124, 498, 344, + 8, 955, 710, 230, 306, 8, 352, 352, 352, 352, + 825, 682, 883, 327, 324, 324, 324, 15, 125, 138, + 138, 141, 141, 434, 443, 449, 990, 367, 958, 454, + 718, 674, 892, 846, 987, 4, 290, 290, 290, 41, + 547, 550, 1078, 308, 554, 985, 924, 938, 41, 941, + 41, 286, 299, 300, 1113, 1115, 1096, 1, 1080, 961, + 666, 341, 1109, 359, 275, 282, 284, 375, 379, 345, + 348, 2, 676, 969, 492, 15, 595, 597, 979, 309, + 682, 685, 213, 368, 15, 138, 15, 617, 417, 410, + 467, 745, 679, 679, 670, 606, 925, 939, 432, 433, + 337, 942, 346, 669, 391, 347, 366, 456, 457, 578, + 508, 288, 428, 390, 340, 428, 877, 545, 342, 8, + 997, 428, 351, 1140, 1141, 765, 903, 581, 408, 582, + 8, 772, 402, 41, 1018, 1079, 960, 959, 444, 460, + 866, 867, 869, 513, 962, 679, 750, 830, 831, 17, + 1112, 420, 420, 708, 17, 864, 1180, 1115, 41, 976, + 1109, 863, 986, 994, 988, 409, 288, 288, 1174, 15, + 1064, 423, 1006, 688, 423, 288, 1051, 763, 1078, 987, + 423, 697, 17, 718, 636, 1065, 591, 593, 596, 596, + 985, 768, 1170, 491, 15, 502, 950, 416, 427, 841, + 955, 427, 955, 503, 955, 838, 1086, 427, 987, 1002, + 17, 499, 289, 1183, 561, 895, 906, 910, 1133, 1003, + 289, 41, 990, 528, 1005, 41, 124, 1105, 531, 314, + 41, 919, 453, 877, 877, 352, 920, 279, 987, 537, + 819, 283, 820, 822, 718, 718, 314, 824, 827, 690, + 546, 535, 324, 1098, 1099, 1100, 580, 15, 41, 415, + 532, 15, 443, 449, 832, 835, 15, 859, 17, 324, + 973, 568, 584, 393, 41, 41, 306, 17, 395, 17, + 517, 306, 290, 124, 309, 396, 814, 524, 397, 755, + 290, 519, 516, 823, 15, 398, 1087, 501, 273, 764, + 955, 518, 955, 399, 955, 504, 955, 986, 1036, 400, + 15, 15, 1136, 774, 987, 520, 923, 923, 804, 923, + 526, 779, 766, 809, 945, 981, 946, 947, 842, 1103, + 693, nil, nil, 613, 790, 851, 1106, 897, 1107, 693, + 852, 1171, 955, 726, nil, 618, nil, 583, 848, 564, + nil, 309, 288, nil, nil, nil, 309, nil, nil, 624, + 1126, nil, 17, nil, 17, 629, nil, 17, 877, 877, + 693, nil, nil, 17, 605, 901, 444, 682, 693, 905, + 1023, nil, 1041, 1042, 1043, 659, 782, 17, 782, nil, + 679, nil, 1004, 1091, nil, nil, nil, 665, nil, nil, + 562, 563, nil, 862, nil, 898, nil, nil, 624, 1067, + nil, nil, nil, nil, 900, 443, 449, 288, nil, 138, + nil, 141, 701, 940, 800, 802, 908, 948, nil, 805, + 807, 1029, nil, nil, nil, 41, 1176, nil, nil, nil, + 914, nil, nil, 314, 444, nil, nil, nil, 535, nil, + 17, 314, nil, 444, 17, nil, 535, 288, 860, 17, + 1184, nil, nil, 760, nil, nil, 324, 288, 922, 848, + 453, 15, nil, nil, 324, 41, nil, nil, 41, 623, + nil, 1097, nil, nil, 444, 628, 746, 17, nil, nil, + 937, 937, 444, nil, nil, 937, 726, nil, nil, 41, + nil, 754, 288, 17, 17, 767, 428, 873, 875, nil, + nil, 15, 678, 1012, 15, nil, 428, 428, 1157, nil, + nil, 428, 428, nil, nil, nil, 41, nil, 668, 444, + nil, 1143, nil, 41, nil, 15, 982, nil, 453, nil, + nil, nil, 840, nil, 618, nil, 1185, 453, 1097, 1097, + nil, 618, 826, 707, nil, nil, 1057, 726, 726, nil, + 1039, nil, 15, nil, 965, 423, 937, 659, 659, 15, + 786, nil, nil, nil, nil, 423, 423, 839, 453, 861, + 423, 423, 923, 1081, 453, 1082, nil, nil, 1033, 1034, + 1088, 1035, 427, 1097, 954, nil, 1175, nil, 618, nil, + 915, 742, 427, 427, 744, 314, 787, 427, 427, 624, + 535, nil, 629, 795, 980, 138, 314, 141, nil, nil, + 911, 853, nil, 453, 799, 902, nil, nil, 324, nil, + nil, 956, 964, nil, nil, nil, nil, nil, 420, 324, + nil, nil, nil, nil, nil, nil, 352, nil, nil, nil, + nil, 983, nil, nil, 983, nil, nil, 726, nil, 726, + nil, nil, nil, 618, 17, nil, nil, nil, nil, nil, + nil, 1090, 618, nil, nil, 1125, nil, 799, 41, nil, + nil, nil, nil, 41, nil, nil, nil, 41, nil, nil, + nil, nil, 428, nil, nil, nil, nil, 41, 618, 937, + nil, 1138, nil, nil, 17, nil, nil, 17, nil, 435, + nil, 982, nil, nil, 15, 455, nil, nil, nil, 15, + nil, nil, nil, 15, nil, nil, 618, nil, 17, nil, + nil, 971, nil, 15, 659, 975, nil, 659, 659, nil, + 659, nil, nil, nil, nil, 659, 659, 659, nil, nil, + 1000, 423, nil, 963, nil, 17, nil, nil, 17, 965, + nil, nil, 17, 965, 41, 965, nil, 965, 17, 17, + nil, 352, 963, 17, 17, 41, 1069, 1071, 427, 1073, + 1075, 138, 1076, nil, 1030, nil, nil, 651, nil, 1102, + nil, 1037, nil, 954, nil, 954, nil, 954, nil, nil, + 15, nil, 726, nil, 899, nil, nil, nil, 1181, nil, + nil, 15, nil, 659, nil, 41, nil, nil, nil, nil, + 458, 41, nil, 912, nil, nil, 983, 1011, nil, nil, + 956, 964, 956, 964, 956, 1017, nil, nil, nil, nil, + nil, nil, 1158, nil, 659, nil, 618, 618, nil, 618, + 826, 15, 659, nil, nil, 726, nil, 15, nil, nil, + nil, nil, nil, 965, 652, 965, nil, 965, 41, 965, + 963, nil, nil, nil, nil, nil, nil, 505, nil, nil, + nil, nil, nil, 378, nil, nil, nil, nil, 41, nil, + 968, nil, 1059, 954, nil, 954, nil, 954, nil, 954, + 521, 972, nil, nil, 15, 965, 324, 17, nil, nil, + nil, nil, 17, nil, nil, 324, 17, 1166, 1167, 1168, + 1169, nil, nil, 693, 15, nil, 17, nil, 1063, nil, + 956, 964, 956, nil, 956, 954, 956, nil, nil, nil, + nil, 1008, 1134, 1135, 17, 659, nil, nil, nil, nil, + nil, nil, nil, 455, nil, 435, 18, nil, nil, nil, + nil, 18, nil, 352, 352, nil, nil, nil, 1121, 651, + 651, 378, 956, 1191, nil, 41, 231, nil, nil, nil, + nil, nil, 41, 41, nil, 231, 231, 231, nil, 18, + 315, 315, nil, 17, 324, nil, nil, nil, nil, 41, + nil, nil, nil, 659, 17, nil, nil, nil, nil, 41, + 288, 15, 659, 659, 1056, nil, nil, 18, 15, 15, + 1153, nil, 231, 231, nil, 699, 231, 363, 373, 373, + nil, nil, nil, nil, nil, 15, nil, 444, 653, nil, + nil, nil, nil, nil, 17, 15, 652, 652, nil, 630, + 17, 41, nil, nil, nil, nil, nil, 659, nil, nil, + 659, nil, nil, nil, nil, nil, 618, nil, nil, nil, + nil, nil, nil, nil, nil, 18, nil, nil, nil, nil, + 231, 231, 231, 231, 18, nil, 18, 15, nil, nil, + 671, nil, 673, nil, nil, nil, 677, 17, nil, nil, + nil, 1119, nil, nil, nil, nil, nil, nil, 1124, nil, + 801, 803, 686, nil, nil, 806, 808, 17, 689, nil, + nil, nil, nil, nil, nil, 1132, 453, nil, nil, nil, + 19, 453, nil, nil, nil, 19, 651, 705, nil, 651, + 651, nil, 651, nil, nil, nil, nil, 651, 651, 651, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 19, 317, 317, nil, nil, nil, 18, + 231, 425, 231, 231, 425, 231, 773, 1172, nil, nil, + 425, 231, 231, nil, nil, nil, nil, nil, nil, nil, + 349, 19, nil, nil, 18, nil, nil, nil, nil, nil, + nil, 365, 374, 374, 17, nil, nil, 1045, 1047, 1049, + nil, 17, 17, 652, nil, 651, 652, 652, nil, 652, + 653, 653, nil, nil, 652, 652, 652, nil, 17, nil, + 231, 231, 907, nil, nil, nil, nil, nil, 17, 231, + nil, nil, nil, nil, nil, nil, 651, nil, nil, 19, + nil, nil, nil, nil, 651, nil, nil, 18, 19, nil, + 19, 18, nil, nil, nil, 315, 18, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 17, nil, 315, nil, nil, nil, 916, nil, nil, nil, + nil, nil, 652, 854, 18, nil, nil, nil, nil, 801, + 803, 808, 806, nil, nil, nil, nil, 957, nil, 231, + 18, 18, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 652, nil, nil, nil, nil, nil, nil, + 231, 652, nil, nil, 989, nil, 991, nil, nil, nil, + nil, 418, 431, 19, nil, 426, 231, 651, 426, nil, + nil, nil, nil, nil, 426, 1145, 1147, 1149, 1151, nil, + 1152, nil, nil, nil, nil, nil, nil, nil, 19, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 653, nil, nil, + 653, 653, nil, 653, nil, nil, nil, nil, 653, 653, + 653, nil, nil, nil, nil, 651, nil, 916, nil, 921, + nil, nil, nil, nil, 651, 651, 231, 510, nil, 512, + nil, nil, 514, 515, 652, nil, 1187, 1188, 1189, 1190, + nil, 19, nil, nil, 952, 19, nil, nil, nil, 317, + 19, nil, 1193, 654, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 317, nil, nil, 651, + nil, nil, 651, nil, nil, nil, 653, nil, 19, nil, + nil, 18, nil, nil, nil, 998, nil, nil, nil, 315, + nil, 231, 652, nil, 19, 19, nil, 315, nil, nil, + nil, 652, 652, nil, nil, nil, 231, 653, 1014, nil, + 1016, nil, nil, nil, nil, 653, nil, nil, 1108, nil, + 1110, 18, nil, nil, 18, nil, 1020, 1021, nil, nil, + nil, 231, nil, nil, nil, nil, nil, nil, nil, nil, + 1127, 231, 1128, nil, 1129, 18, 652, 1038, nil, 652, + nil, nil, nil, nil, 609, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 18, nil, nil, 425, 231, nil, nil, 18, + nil, nil, nil, nil, nil, 425, 425, nil, nil, nil, + 425, 425, nil, nil, 655, nil, 1077, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 653, nil, + nil, nil, nil, nil, nil, nil, 1177, nil, 1178, nil, + 1179, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 654, 654, 1182, nil, nil, + nil, nil, 680, nil, 349, nil, 683, nil, nil, nil, + nil, 315, nil, nil, nil, 19, nil, nil, 1192, nil, + nil, nil, 315, 317, nil, nil, 653, nil, nil, nil, + nil, 317, nil, nil, nil, 653, 653, nil, nil, nil, + nil, nil, nil, 680, nil, nil, 349, nil, nil, nil, + nil, nil, 1137, nil, nil, 19, nil, nil, 19, nil, + nil, 431, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 19, + 653, nil, nil, 653, 18, nil, 778, nil, nil, 18, + 231, nil, nil, 18, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 18, nil, 788, 19, nil, nil, 426, + nil, nil, nil, 19, 680, 349, nil, nil, nil, 426, + 426, 425, nil, 28, 426, 426, nil, nil, 28, nil, + nil, nil, nil, nil, nil, nil, 655, 655, nil, nil, + nil, nil, nil, 28, nil, nil, nil, nil, nil, nil, + nil, nil, 28, 28, 28, nil, 28, nil, nil, nil, + nil, nil, 654, nil, nil, 654, 654, 680, 654, nil, + 18, nil, nil, 654, 654, 654, 849, nil, nil, 850, + nil, 18, nil, nil, 28, 317, nil, nil, nil, 28, + 28, nil, nil, 28, nil, nil, 317, 656, 858, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 231, nil, nil, nil, nil, + nil, 18, nil, nil, nil, 884, nil, 18, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 654, 28, nil, nil, nil, nil, 28, 28, 28, + 28, 28, 657, 28, nil, nil, nil, nil, 19, nil, + nil, nil, nil, 19, nil, nil, nil, 19, nil, nil, + nil, nil, 654, nil, 18, nil, nil, 19, nil, nil, + 654, nil, nil, nil, 913, nil, nil, nil, nil, 1054, + nil, nil, 31, nil, 18, 426, nil, 31, 1060, nil, + nil, nil, nil, 655, nil, nil, 655, 655, nil, 655, + nil, nil, 31, nil, 655, 655, 655, nil, nil, nil, + nil, 31, 31, 31, nil, 31, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 28, 28, 28, 28, + 28, 28, 28, nil, 19, nil, nil, 28, 28, 28, + nil, nil, nil, 31, nil, 19, nil, nil, 31, 31, + nil, 28, 31, nil, nil, nil, nil, nil, nil, nil, + nil, 993, nil, 654, nil, nil, nil, 1116, nil, 656, + 656, 18, 655, nil, nil, nil, nil, nil, 18, 18, + nil, 1007, nil, nil, nil, 19, nil, 28, 28, nil, + nil, 19, nil, nil, nil, 18, 28, 231, 231, nil, + nil, 31, 349, 655, nil, 18, 31, 31, 31, 31, + 31, 655, 31, nil, 28, nil, 658, nil, 28, nil, + nil, 654, nil, 28, 657, 657, nil, nil, nil, nil, + 654, 654, nil, nil, 231, nil, nil, nil, 19, nil, + nil, nil, nil, nil, nil, nil, nil, 18, nil, nil, + nil, 28, nil, 374, nil, nil, nil, nil, 19, nil, + nil, nil, 1062, nil, nil, nil, 28, 28, 28, nil, + nil, nil, nil, nil, nil, 654, nil, nil, 654, nil, + nil, nil, nil, nil, nil, nil, nil, 28, nil, nil, + nil, nil, nil, nil, nil, 31, 31, 31, 31, 31, + 31, 31, nil, 28, 655, nil, 31, 31, 31, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 31, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 656, nil, nil, 656, + 656, 374, 656, nil, nil, 19, nil, 656, 656, 656, + nil, nil, 19, 19, nil, nil, 31, 31, nil, nil, + nil, nil, 655, nil, nil, 31, nil, nil, nil, 19, + nil, 655, 655, 28, nil, nil, nil, nil, nil, 19, + nil, nil, nil, 31, nil, nil, nil, 31, nil, nil, + nil, 657, 31, nil, 657, 657, nil, 657, 658, 658, + nil, nil, 657, 657, 657, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 656, 655, nil, nil, 655, + 31, 19, nil, nil, nil, nil, 40, nil, 28, nil, + nil, 40, nil, nil, nil, 31, 31, 31, 28, nil, + nil, nil, nil, nil, nil, nil, 656, nil, nil, nil, + nil, nil, nil, 28, 656, nil, 31, nil, nil, 40, + 313, 313, nil, nil, nil, nil, nil, nil, 28, nil, + 657, 28, 31, nil, nil, nil, nil, nil, 28, nil, + nil, nil, nil, nil, nil, nil, nil, 40, 28, nil, + nil, nil, 28, nil, nil, nil, nil, 361, 377, 377, + 377, 657, nil, nil, nil, nil, nil, nil, nil, 657, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 28, + nil, nil, 28, 28, nil, nil, 28, nil, nil, nil, + nil, nil, 28, 28, nil, nil, nil, 28, 28, nil, + nil, nil, 31, nil, nil, 40, nil, 656, nil, nil, + nil, nil, nil, nil, 40, nil, 40, nil, nil, nil, + nil, nil, nil, nil, nil, 658, nil, nil, 658, 658, + nil, 658, nil, nil, nil, nil, 658, 658, 658, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 31, nil, nil, + nil, nil, 657, nil, nil, 656, nil, 31, nil, nil, + nil, nil, nil, nil, 656, 656, nil, nil, nil, nil, + nil, nil, 31, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 31, nil, 40, + 31, nil, nil, nil, 658, nil, nil, 31, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 31, nil, 656, + 657, 31, 656, nil, 40, nil, nil, nil, nil, 657, + 657, 28, nil, nil, nil, 658, 28, 28, nil, nil, + 28, nil, nil, 658, nil, nil, nil, nil, 31, nil, + 28, 31, 31, nil, nil, 31, nil, nil, nil, nil, + nil, 31, 31, nil, nil, nil, 31, 31, 28, nil, + nil, nil, nil, nil, 657, nil, nil, 657, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 40, nil, nil, + nil, 40, nil, nil, nil, 313, 40, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 313, nil, nil, nil, nil, 28, nil, nil, + nil, nil, nil, nil, 40, nil, nil, nil, 28, nil, + nil, nil, nil, nil, nil, nil, 658, nil, nil, nil, + 40, 40, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 28, nil, nil, nil, nil, nil, 28, nil, + nil, nil, nil, nil, 28, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 658, nil, nil, nil, nil, nil, + 31, nil, nil, 658, 658, 31, 31, nil, nil, 31, + nil, nil, nil, nil, nil, nil, nil, nil, 238, 31, + nil, 28, nil, nil, nil, nil, nil, 287, 287, 287, + nil, nil, nil, nil, nil, nil, nil, 31, nil, 332, + 333, 28, 335, 336, nil, 338, nil, nil, 658, nil, + nil, 658, nil, nil, nil, nil, nil, nil, nil, nil, + 287, 287, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 31, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 31, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 313, + nil, nil, nil, nil, nil, nil, nil, 313, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 28, nil, + nil, 31, nil, nil, nil, 28, 28, 31, nil, nil, + nil, 40, nil, 31, 40, nil, nil, nil, nil, nil, + nil, nil, 28, nil, 28, 28, nil, nil, nil, nil, + nil, nil, 28, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 31, 28, 40, nil, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, 28, nil, nil, nil, nil, nil, + 31, nil, 287, 430, nil, nil, 436, 287, nil, nil, + nil, nil, 436, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 238, nil, nil, nil, 468, + 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, + 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, + 489, nil, nil, nil, nil, 490, nil, nil, nil, nil, + nil, 313, 287, 287, nil, nil, nil, nil, nil, nil, + nil, 287, 313, nil, nil, nil, nil, nil, 287, nil, + 287, nil, nil, 287, 287, nil, nil, 31, nil, nil, + nil, nil, nil, nil, 31, 31, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 31, nil, 31, 31, nil, nil, nil, nil, nil, + nil, 31, nil, 540, nil, 541, nil, nil, nil, nil, + nil, nil, nil, nil, 40, nil, nil, nil, nil, 40, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + 31, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 31, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 287, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 40, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 287, nil, + 436, 436, 436, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, 333, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 287, nil, 287, nil, 287, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 287, nil, nil, nil, nil, nil, nil, + nil, nil, 436, nil, 40, 700, nil, nil, nil, nil, + nil, nil, nil, nil, 287, nil, nil, 287, nil, 377, + nil, nil, nil, nil, 40, nil, nil, nil, 1058, nil, + nil, nil, 287, 287, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 287, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 287, 436, 287, nil, + nil, nil, 796, nil, nil, 287, 287, 436, 436, nil, + nil, nil, 436, 436, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 377, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, 40, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 40, nil, nil, 287, nil, + nil, nil, nil, nil, nil, 40, nil, 287, nil, nil, + 287, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 287, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, nil, 287, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 287, nil, nil, nil, nil, + nil, nil, nil, 436, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 436, 436, 436, 436, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 949, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 287, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 287, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 287, 436, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 287 ] + +racc_goto_check = [ + 63, 42, 42, 42, 66, 63, 33, 19, 19, 35, + 108, 19, 83, 150, 33, 190, 101, 101, 104, 98, + 78, 103, 12, 31, 82, 82, 100, 190, 26, 26, + 10, 102, 26, 63, 63, 63, 23, 111, 35, 59, + 85, 23, 39, 39, 37, 124, 79, 79, 79, 227, + 48, 24, 24, 64, 17, 17, 61, 74, 74, 72, + 86, 63, 86, 45, 7, 19, 19, 19, 19, 23, + 13, 63, 63, 63, 63, 9, 5, 108, 31, 79, + 8, 132, 149, 22, 55, 8, 26, 26, 26, 26, + 178, 227, 125, 60, 74, 74, 74, 23, 6, 67, + 67, 69, 69, 28, 46, 46, 223, 23, 137, 28, + 213, 49, 13, 139, 219, 2, 81, 81, 81, 63, + 80, 80, 123, 56, 80, 217, 167, 167, 63, 167, + 63, 54, 54, 54, 143, 144, 184, 1, 126, 141, + 153, 8, 224, 5, 47, 47, 47, 65, 65, 81, + 81, 3, 153, 14, 46, 23, 203, 203, 141, 11, + 227, 16, 18, 21, 23, 67, 23, 32, 25, 27, + 38, 40, 86, 86, 51, 70, 169, 169, 26, 26, + 75, 169, 77, 84, 96, 97, 105, 26, 26, 107, + 85, 42, 20, 112, 113, 20, 124, 114, 115, 8, + 124, 20, 116, 184, 184, 117, 118, 119, 8, 120, + 8, 121, 6, 63, 122, 127, 128, 138, 82, 33, + 131, 131, 131, 190, 135, 86, 103, 192, 192, 29, + 142, 79, 79, 145, 29, 149, 143, 144, 63, 146, + 224, 148, 138, 125, 138, 2, 42, 42, 184, 23, + 151, 23, 169, 61, 23, 42, 141, 64, 123, 219, + 23, 61, 29, 213, 31, 152, 204, 204, 204, 204, + 217, 10, 126, 154, 23, 156, 139, 22, 22, 49, + 132, 22, 132, 157, 132, 160, 161, 22, 219, 162, + 29, 79, 79, 163, 19, 164, 149, 149, 165, 166, + 79, 63, 223, 33, 168, 63, 108, 137, 35, 63, + 63, 171, 67, 124, 124, 26, 173, 82, 219, 33, + 174, 82, 175, 179, 213, 213, 63, 180, 181, 31, + 35, 59, 74, 186, 187, 188, 26, 23, 63, 11, + 72, 23, 46, 46, 194, 64, 23, 195, 29, 74, + 196, 33, 26, 199, 63, 63, 55, 29, 200, 29, + 7, 55, 81, 108, 11, 201, 32, 60, 202, 31, + 81, 9, 5, 32, 23, 205, 13, 54, 33, 31, + 132, 8, 132, 206, 132, 54, 132, 138, 178, 207, + 23, 23, 167, 208, 219, 56, 37, 37, 48, 37, + 56, 209, 212, 48, 37, 221, 192, 192, 83, 222, + 46, nil, nil, 33, 31, 61, 138, 101, 138, 46, + 32, 102, 132, 218, nil, 35, nil, 45, 85, 5, + nil, 11, 42, nil, nil, nil, 11, nil, nil, 82, + 138, nil, 29, nil, 29, 82, nil, 29, 124, 124, + 46, nil, nil, 29, 17, 10, 82, 227, 46, 10, + 183, nil, 131, 131, 131, 63, 204, 29, 204, nil, + 86, nil, 37, 111, nil, nil, nil, 35, nil, nil, + 11, 11, nil, 80, nil, 32, nil, nil, 82, 131, + nil, nil, nil, nil, 32, 46, 46, 42, nil, 67, + nil, 69, 26, 64, 28, 28, 83, 100, nil, 28, + 28, 37, nil, nil, nil, 63, 138, nil, nil, nil, + 32, nil, nil, 63, 82, nil, nil, nil, 59, nil, + 29, 63, nil, 82, 29, nil, 59, 42, 24, 29, + 13, nil, nil, 39, nil, nil, 74, 42, 32, 85, + 67, 23, nil, nil, 74, 63, nil, nil, 63, 47, + nil, 183, nil, nil, 82, 47, 108, 29, nil, nil, + 191, 191, 82, nil, nil, 191, 218, nil, nil, 63, + nil, 79, 42, 29, 29, 108, 20, 216, 216, nil, + nil, 23, 81, 10, 23, nil, 20, 20, 12, nil, + nil, 20, 20, nil, nil, nil, 63, nil, 47, 82, + nil, 131, nil, 63, nil, 23, 191, nil, 67, nil, + nil, nil, 98, nil, 35, nil, 104, 67, 183, 183, + nil, 35, 35, 81, nil, nil, 101, 218, 218, nil, + 10, nil, 23, nil, 220, 23, 191, 63, 63, 23, + 17, nil, nil, nil, nil, 23, 23, 150, 67, 78, + 23, 23, 37, 101, 67, 101, nil, nil, 32, 32, + 103, 32, 22, 183, 130, nil, 183, nil, 35, nil, + 28, 11, 22, 22, 11, 63, 8, 22, 22, 82, + 59, nil, 82, 8, 130, 67, 63, 69, nil, nil, + 66, 59, nil, 67, 81, 19, nil, nil, 74, nil, + nil, 133, 218, nil, nil, nil, nil, nil, 79, 74, + nil, nil, nil, nil, nil, nil, 26, nil, nil, nil, + nil, 133, nil, nil, 133, nil, nil, 218, nil, 218, + nil, nil, nil, 35, 29, nil, nil, nil, nil, nil, + nil, 83, 35, nil, nil, 10, nil, 81, 63, nil, + nil, nil, nil, 63, nil, nil, nil, 63, nil, nil, + nil, nil, 20, nil, nil, nil, nil, 63, 35, 191, + nil, 10, nil, nil, 29, nil, nil, 29, nil, 71, + nil, 191, nil, nil, 23, 71, nil, nil, nil, 23, + nil, nil, nil, 23, nil, nil, 35, nil, 29, nil, + nil, 78, nil, 23, 63, 78, nil, 63, 63, nil, + 63, nil, nil, nil, nil, 63, 63, 63, nil, nil, + 19, 23, nil, 35, nil, 29, nil, nil, 29, 220, + nil, nil, 29, 220, 63, 220, nil, 220, 29, 29, + nil, 26, 35, 29, 29, 63, 216, 216, 22, 216, + 216, 67, 216, nil, 190, nil, nil, 88, nil, 130, + nil, 190, nil, 130, nil, 130, nil, 130, nil, nil, + 23, nil, 218, nil, 11, nil, nil, nil, 32, nil, + nil, 23, nil, 63, nil, 63, nil, nil, nil, nil, + 57, 63, nil, 11, nil, nil, 133, 108, nil, nil, + 133, 218, 133, 218, 133, 108, nil, nil, nil, nil, + nil, nil, 31, nil, 63, nil, 35, 35, nil, 35, + 35, 23, 63, nil, nil, 218, nil, 23, nil, nil, + nil, nil, nil, 220, 89, 220, nil, 220, 63, 220, + 35, nil, nil, nil, nil, nil, nil, 57, nil, nil, + nil, nil, nil, 63, nil, nil, nil, nil, 63, nil, + 11, nil, 63, 130, nil, 130, nil, 130, nil, 130, + 57, 11, nil, nil, 23, 220, 74, 29, nil, nil, + nil, nil, 29, nil, nil, 74, 29, 216, 216, 216, + 216, nil, nil, 46, 23, nil, 29, nil, 23, nil, + 133, 218, 133, nil, 133, 130, 133, nil, nil, nil, + nil, 11, 19, 19, 29, 63, nil, nil, nil, nil, + nil, nil, nil, 71, nil, 71, 30, nil, nil, nil, + nil, 30, nil, 26, 26, nil, nil, nil, 33, 88, + 88, 63, 133, 216, nil, 63, 30, nil, nil, nil, + nil, nil, 63, 63, nil, 30, 30, 30, nil, 30, + 30, 30, nil, 29, 74, nil, nil, nil, nil, 63, + nil, nil, nil, 63, 29, nil, nil, nil, nil, 63, + 42, 23, 63, 63, 11, nil, nil, 30, 23, 23, + 35, nil, 30, 30, nil, 71, 30, 30, 30, 30, + nil, nil, nil, nil, nil, 23, nil, 82, 90, nil, + nil, nil, nil, nil, 29, 23, 89, 89, nil, 57, + 29, 63, nil, nil, nil, nil, nil, 63, nil, nil, + 63, nil, nil, nil, nil, nil, 35, nil, nil, nil, + nil, nil, nil, nil, nil, 30, nil, nil, nil, nil, + 30, 30, 30, 30, 30, nil, 30, 23, nil, nil, + 57, nil, 57, nil, nil, nil, 57, 29, nil, nil, + nil, 11, nil, nil, nil, nil, nil, nil, 11, nil, + 71, 71, 57, nil, nil, 71, 71, 29, 57, nil, + nil, nil, nil, nil, nil, 11, 67, nil, nil, nil, + 34, 67, nil, nil, nil, 34, 88, 57, nil, 88, + 88, nil, 88, nil, nil, nil, nil, 88, 88, 88, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 34, 34, 34, nil, nil, nil, 30, + 30, 30, 30, 30, 30, 30, 57, 11, nil, nil, + 30, 30, 30, nil, nil, nil, nil, nil, nil, nil, + 76, 34, nil, nil, 30, nil, nil, nil, nil, nil, + nil, 34, 34, 34, 29, nil, nil, 134, 134, 134, + nil, 29, 29, 89, nil, 88, 89, 89, nil, 89, + 90, 90, nil, nil, 89, 89, 89, nil, 29, nil, + 30, 30, 136, nil, nil, nil, nil, nil, 29, 30, + nil, nil, nil, nil, nil, nil, 88, nil, nil, 34, + nil, nil, nil, nil, 88, nil, nil, 30, 34, nil, + 34, 30, nil, nil, nil, 30, 30, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 29, nil, 30, nil, nil, nil, 71, nil, nil, nil, + nil, nil, 89, 57, 30, nil, nil, nil, nil, 71, + 71, 71, 71, nil, nil, nil, nil, 136, nil, 30, + 30, 30, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 89, nil, nil, nil, nil, nil, nil, + 30, 89, nil, nil, 136, nil, 136, nil, nil, nil, + nil, 76, 76, 34, nil, 34, 30, 88, 34, nil, + nil, nil, nil, nil, 34, 134, 134, 134, 134, nil, + 134, nil, nil, nil, nil, nil, nil, nil, 34, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 90, nil, nil, + 90, 90, nil, 90, nil, nil, nil, nil, 90, 90, + 90, nil, nil, nil, nil, 88, nil, 71, nil, 57, + nil, nil, nil, nil, 88, 88, 30, 76, nil, 76, + nil, nil, 76, 76, 89, nil, 134, 134, 134, 134, + nil, 34, nil, nil, 57, 34, nil, nil, nil, 34, + 34, nil, 134, 91, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 34, nil, nil, 88, + nil, nil, 88, nil, nil, nil, 90, nil, 34, nil, + nil, 30, nil, nil, nil, 57, nil, nil, nil, 30, + nil, 30, 89, nil, 34, 34, nil, 30, nil, nil, + nil, 89, 89, nil, nil, nil, 30, 90, 57, nil, + 57, nil, nil, nil, nil, 90, nil, nil, 136, nil, + 136, 30, nil, nil, 30, nil, 57, 57, nil, nil, + nil, 30, nil, nil, nil, nil, nil, nil, nil, nil, + 136, 30, 136, nil, 136, 30, 89, 57, nil, 89, + nil, nil, nil, nil, 76, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 30, nil, nil, 30, 30, nil, nil, 30, + nil, nil, nil, nil, nil, 30, 30, nil, nil, nil, + 30, 30, nil, nil, 92, nil, 57, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 90, nil, + nil, nil, nil, nil, nil, nil, 136, nil, 136, nil, + 136, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 91, 91, 136, nil, nil, + nil, nil, 76, nil, 76, nil, 76, nil, nil, nil, + nil, 30, nil, nil, nil, 34, nil, nil, 136, nil, + nil, nil, 30, 34, nil, nil, 90, nil, nil, nil, + nil, 34, nil, nil, nil, 90, 90, nil, nil, nil, + nil, nil, nil, 76, nil, nil, 76, nil, nil, nil, + nil, nil, 57, nil, nil, 34, nil, nil, 34, nil, + nil, 76, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 34, + 90, nil, nil, 90, 30, nil, 34, nil, nil, 30, + 30, nil, nil, 30, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 30, nil, 76, 34, nil, nil, 34, + nil, nil, nil, 34, 76, 76, nil, nil, nil, 34, + 34, 30, nil, 50, 34, 34, nil, nil, 50, nil, + nil, nil, nil, nil, nil, nil, 92, 92, nil, nil, + nil, nil, nil, 50, nil, nil, nil, nil, nil, nil, + nil, nil, 50, 50, 50, nil, 50, nil, nil, nil, + nil, nil, 91, nil, nil, 91, 91, 76, 91, nil, + 30, nil, nil, 91, 91, 91, 76, nil, nil, 76, + nil, 30, nil, nil, 50, 34, nil, nil, nil, 50, + 50, nil, nil, 50, nil, nil, 34, 93, 76, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 30, nil, nil, nil, nil, + nil, 30, nil, nil, nil, 76, nil, 30, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 91, 50, nil, nil, nil, nil, 50, 50, 50, + 50, 50, 94, 50, nil, nil, nil, nil, 34, nil, + nil, nil, nil, 34, nil, nil, nil, 34, nil, nil, + nil, nil, 91, nil, 30, nil, nil, 34, nil, nil, + 91, nil, nil, nil, 76, nil, nil, nil, nil, 30, + nil, nil, 53, nil, 30, 34, nil, 53, 30, nil, + nil, nil, nil, 92, nil, nil, 92, 92, nil, 92, + nil, nil, 53, nil, 92, 92, 92, nil, nil, nil, + nil, 53, 53, 53, nil, 53, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 50, 50, 50, 50, + 50, 50, 50, nil, 34, nil, nil, 50, 50, 50, + nil, nil, nil, 53, nil, 34, nil, nil, 53, 53, + nil, 50, 53, nil, nil, nil, nil, nil, nil, nil, + nil, 76, nil, 91, nil, nil, nil, 30, nil, 93, + 93, 30, 92, nil, nil, nil, nil, nil, 30, 30, + nil, 76, nil, nil, nil, 34, nil, 50, 50, nil, + nil, 34, nil, nil, nil, 30, 50, 30, 30, nil, + nil, 53, 76, 92, nil, 30, 53, 53, 53, 53, + 53, 92, 53, nil, 50, nil, 95, nil, 50, nil, + nil, 91, nil, 50, 94, 94, nil, nil, nil, nil, + 91, 91, nil, nil, 30, nil, nil, nil, 34, nil, + nil, nil, nil, nil, nil, nil, nil, 30, nil, nil, + nil, 50, nil, 34, nil, nil, nil, nil, 34, nil, + nil, nil, 34, nil, nil, nil, 50, 50, 50, nil, + nil, nil, nil, nil, nil, 91, nil, nil, 91, nil, + nil, nil, nil, nil, nil, nil, nil, 50, nil, nil, + nil, nil, nil, nil, nil, 53, 53, 53, 53, 53, + 53, 53, nil, 50, 92, nil, 53, 53, 53, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 53, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 93, nil, nil, 93, + 93, 34, 93, nil, nil, 34, nil, 93, 93, 93, + nil, nil, 34, 34, nil, nil, 53, 53, nil, nil, + nil, nil, 92, nil, nil, 53, nil, nil, nil, 34, + nil, 92, 92, 50, nil, nil, nil, nil, nil, 34, + nil, nil, nil, 53, nil, nil, nil, 53, nil, nil, + nil, 94, 53, nil, 94, 94, nil, 94, 95, 95, + nil, nil, 94, 94, 94, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 93, 92, nil, nil, 92, + 53, 34, nil, nil, nil, nil, 62, nil, 50, nil, + nil, 62, nil, nil, nil, 53, 53, 53, 50, nil, + nil, nil, nil, nil, nil, nil, 93, nil, nil, nil, + nil, nil, nil, 50, 93, nil, 53, nil, nil, 62, + 62, 62, nil, nil, nil, nil, nil, nil, 50, nil, + 94, 50, 53, nil, nil, nil, nil, nil, 50, nil, + nil, nil, nil, nil, nil, nil, nil, 62, 50, nil, + nil, nil, 50, nil, nil, nil, nil, 62, 62, 62, + 62, 94, nil, nil, nil, nil, nil, nil, nil, 94, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 50, + nil, nil, 50, 50, nil, nil, 50, nil, nil, nil, + nil, nil, 50, 50, nil, nil, nil, 50, 50, nil, + nil, nil, 53, nil, nil, 62, nil, 93, nil, nil, + nil, nil, nil, nil, 62, nil, 62, nil, nil, nil, + nil, nil, nil, nil, nil, 95, nil, nil, 95, 95, + nil, 95, nil, nil, nil, nil, 95, 95, 95, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 53, nil, nil, + nil, nil, 94, nil, nil, 93, nil, 53, nil, nil, + nil, nil, nil, nil, 93, 93, nil, nil, nil, nil, + nil, nil, 53, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 53, nil, 62, + 53, nil, nil, nil, 95, nil, nil, 53, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 53, nil, 93, + 94, 53, 93, nil, 62, nil, nil, nil, nil, 94, + 94, 50, nil, nil, nil, 95, 50, 50, nil, nil, + 50, nil, nil, 95, nil, nil, nil, nil, 53, nil, + 50, 53, 53, nil, nil, 53, nil, nil, nil, nil, + nil, 53, 53, nil, nil, nil, 53, 53, 50, nil, + nil, nil, nil, nil, 94, nil, nil, 94, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 62, nil, nil, + nil, 62, nil, nil, nil, 62, 62, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 62, nil, nil, nil, nil, 50, nil, nil, + nil, nil, nil, nil, 62, nil, nil, nil, 50, nil, + nil, nil, nil, nil, nil, nil, 95, nil, nil, nil, + 62, 62, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 50, nil, nil, nil, nil, nil, 50, nil, + nil, nil, nil, nil, 50, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 95, nil, nil, nil, nil, nil, + 53, nil, nil, 95, 95, 53, 53, nil, nil, 53, + nil, nil, nil, nil, nil, nil, nil, nil, 36, 53, + nil, 50, nil, nil, nil, nil, nil, 36, 36, 36, + nil, nil, nil, nil, nil, nil, nil, 53, nil, 36, + 36, 50, 36, 36, nil, 36, nil, nil, 95, nil, + nil, 95, nil, nil, nil, nil, nil, nil, nil, nil, + 36, 36, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 53, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 53, nil, nil, + nil, 62, nil, nil, nil, nil, nil, nil, nil, 62, + nil, nil, nil, nil, nil, nil, nil, 62, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 50, nil, + nil, 53, nil, nil, nil, 50, 50, 53, nil, nil, + nil, 62, nil, 53, 62, nil, nil, nil, nil, nil, + nil, nil, 50, nil, 50, 50, nil, nil, nil, nil, + nil, nil, 50, nil, nil, 62, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 53, 50, 62, nil, nil, nil, nil, nil, nil, 62, + nil, nil, nil, nil, 50, nil, nil, nil, nil, nil, + 53, nil, 36, 36, nil, nil, 36, 36, nil, nil, + nil, nil, 36, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 36, nil, nil, nil, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, nil, nil, nil, nil, 36, nil, nil, nil, nil, + nil, 62, 36, 36, nil, nil, nil, nil, nil, nil, + nil, 36, 62, nil, nil, nil, nil, nil, 36, nil, + 36, nil, nil, 36, 36, nil, nil, 53, nil, nil, + nil, nil, nil, nil, 53, 53, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 53, nil, 53, 53, nil, nil, nil, nil, nil, + nil, 53, nil, 36, nil, 36, nil, nil, nil, nil, + nil, nil, nil, nil, 62, nil, nil, nil, nil, 62, + nil, nil, nil, 62, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 62, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 53, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 36, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 62, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 62, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 36, nil, + 36, 36, 36, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 62, nil, nil, nil, nil, nil, 62, nil, nil, + nil, nil, nil, 36, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 36, nil, 36, nil, 36, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 36, nil, nil, nil, nil, nil, nil, + nil, nil, 36, nil, 62, 36, nil, nil, nil, nil, + nil, nil, nil, nil, 36, nil, nil, 36, nil, 62, + nil, nil, nil, nil, 62, nil, nil, nil, 62, nil, + nil, nil, 36, 36, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 36, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 36, 36, 36, nil, + nil, nil, 36, nil, nil, 36, 36, 36, 36, nil, + nil, nil, 36, 36, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 62, nil, nil, + nil, 62, nil, nil, nil, nil, nil, nil, 62, 62, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 62, nil, nil, 36, nil, + nil, nil, nil, nil, nil, 62, nil, 36, nil, nil, + 36, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 36, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 62, nil, nil, + nil, nil, nil, nil, nil, nil, 36, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 36, nil, nil, nil, nil, + nil, nil, nil, 36, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 36, 36, 36, 36, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 36, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 36, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 36, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 36, 36, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 36 ] + +racc_goto_pointer = [ + nil, 137, 113, 151, nil, 71, 91, 59, 78, 66, + -310, 124, -521, -632, -702, nil, -356, 44, 151, -61, + -25, 90, 61, 34, -165, -48, -40, 36, -117, 227, + 1034, -198, -270, -12, 1208, -12, 2756, -423, -72, -28, + -390, nil, -30, nil, nil, 37, -118, 116, -225, -391, + 1831, -321, nil, 2000, 100, 49, 88, 672, nil, 3, + 56, -272, 2344, -2, -318, 73, -72, 89, nil, 91, + -239, 569, 14, nil, 21, 132, 1205, 118, -44, 15, + -224, 85, -4, -264, -309, -250, -447, nil, 400, 477, + 651, 1056, 1197, 1440, 1495, 1669, 108, 120, -47, nil, + -325, -337, -711, -338, -546, 113, nil, -186, 5, nil, + nil, -545, 117, 132, -144, 135, 135, -373, -561, -172, + -180, -372, -697, -873, -682, -635, -858, -780, -629, nil, + -171, -491, -764, -134, 330, -621, 542, -737, -628, -562, + nil, -706, -822, -918, -917, -323, -624, nil, -467, -474, + -11, -727, -713, -351, 3, nil, -5, 2, nil, nil, + -382, -722, -606, -879, -457, -784, -596, -693, -591, -643, + nil, -504, nil, -500, -322, -320, nil, nil, -554, -320, + -317, -317, nil, -466, -891, nil, -695, -694, -693, nil, + -72, -249, -422, nil, -316, -356, -509, nil, nil, 268, + 268, 274, 276, -241, -129, 282, 289, 294, -195, -188, + nil, nil, -177, -446, nil, nil, -129, -745, -133, -756, + -201, -460, -631, -766, -904, nil, nil, -460 ] + +racc_goto_default = [ + nil, nil, nil, nil, 5, nil, 6, 360, 304, nil, + nil, 543, nil, 890, nil, 301, 302, nil, nil, nil, + 13, 14, 20, 236, nil, nil, 16, nil, 424, 237, + 331, nil, nil, 576, 235, 459, 23, 1022, nil, nil, + nil, 355, 24, 25, 26, nil, 696, nil, nil, nil, + 321, nil, 27, 318, 438, 34, nil, nil, 36, 39, + 38, nil, 232, 233, 372, nil, 140, 446, 139, 84, + nil, 429, 100, 48, 51, 269, 293, nil, 856, 439, + nil, 440, 451, nil, 625, 506, 291, 277, 52, 53, + 54, 55, 56, 57, 58, 59, 60, nil, 278, 66, + nil, nil, nil, nil, nil, nil, 74, nil, 558, 75, + 76, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 879, 725, nil, 880, 881, 1104, 953, + 712, nil, 713, 714, nil, nil, 715, nil, 717, nil, + 844, nil, nil, nil, 723, nil, nil, 556, nil, nil, + nil, nil, nil, nil, nil, 450, nil, nil, 675, 667, + nil, nil, nil, nil, nil, nil, nil, nil, 927, nil, + 638, 647, 639, 640, nil, nil, 641, 642, nil, nil, + nil, nil, 926, 928, nil, 930, 931, 932, 933, 934, + nil, 734, 646, 648, nil, nil, nil, 83, 85, 86, + nil, nil, nil, nil, 586, nil, nil, nil, nil, nil, + 96, 97, nil, 984, 771, 711, 871, 716, 992, 728, + 730, 731, 966, 735, 967, 738, 741, 296 ] + +racc_reduce_table = [ + 0, 0, :racc_error, + 0, 150, :_reduce_1, + 2, 148, :_reduce_2, + 2, 149, :_reduce_3, + 0, 151, :_reduce_4, + 1, 151, :_reduce_5, + 3, 151, :_reduce_6, + 2, 151, :_reduce_7, + 1, 153, :_reduce_none, + 2, 153, :_reduce_9, + 3, 156, :_reduce_10, + 4, 157, :_reduce_11, + 2, 158, :_reduce_12, + 0, 162, :_reduce_13, + 1, 162, :_reduce_14, + 3, 162, :_reduce_15, + 2, 162, :_reduce_16, + 1, 163, :_reduce_none, + 2, 163, :_reduce_18, + 0, 174, :_reduce_19, + 4, 155, :_reduce_20, + 3, 155, :_reduce_21, + 3, 155, :_reduce_22, + 3, 155, :_reduce_23, + 2, 155, :_reduce_24, + 3, 155, :_reduce_25, + 3, 155, :_reduce_26, + 3, 155, :_reduce_27, + 3, 155, :_reduce_28, + 3, 155, :_reduce_29, + 4, 155, :_reduce_30, + 1, 155, :_reduce_none, + 3, 155, :_reduce_32, + 3, 155, :_reduce_33, + 5, 155, :_reduce_34, + 3, 155, :_reduce_35, + 1, 155, :_reduce_none, + 3, 167, :_reduce_37, + 3, 167, :_reduce_38, + 6, 167, :_reduce_39, + 5, 167, :_reduce_40, + 5, 167, :_reduce_41, + 5, 167, :_reduce_42, + 5, 167, :_reduce_43, + 3, 167, :_reduce_44, + 1, 175, :_reduce_none, + 3, 175, :_reduce_46, + 1, 175, :_reduce_none, + 1, 173, :_reduce_none, + 3, 173, :_reduce_49, + 3, 173, :_reduce_50, + 3, 173, :_reduce_51, + 2, 173, :_reduce_52, + 0, 185, :_reduce_53, + 4, 173, :_reduce_54, + 1, 173, :_reduce_none, + 1, 166, :_reduce_none, + 0, 188, :_reduce_57, + 3, 186, :_reduce_58, + 1, 169, :_reduce_none, + 1, 169, :_reduce_none, + 1, 190, :_reduce_none, + 4, 190, :_reduce_62, + 0, 198, :_reduce_63, + 4, 195, :_reduce_64, + 1, 197, :_reduce_none, + 2, 189, :_reduce_66, + 3, 189, :_reduce_67, + 4, 189, :_reduce_68, + 5, 189, :_reduce_69, + 4, 189, :_reduce_70, + 5, 189, :_reduce_71, + 2, 189, :_reduce_72, + 2, 189, :_reduce_73, + 2, 189, :_reduce_74, + 2, 189, :_reduce_75, + 2, 189, :_reduce_76, + 1, 168, :_reduce_77, + 3, 168, :_reduce_78, + 1, 203, :_reduce_79, + 3, 203, :_reduce_80, + 1, 202, :_reduce_none, + 2, 202, :_reduce_82, + 3, 202, :_reduce_83, + 5, 202, :_reduce_84, + 2, 202, :_reduce_85, + 4, 202, :_reduce_86, + 2, 202, :_reduce_87, + 4, 202, :_reduce_88, + 1, 202, :_reduce_89, + 3, 202, :_reduce_90, + 1, 206, :_reduce_none, + 3, 206, :_reduce_92, + 2, 205, :_reduce_93, + 3, 205, :_reduce_94, + 1, 208, :_reduce_95, + 3, 208, :_reduce_96, + 1, 207, :_reduce_97, + 1, 207, :_reduce_98, + 4, 207, :_reduce_99, + 3, 207, :_reduce_100, + 3, 207, :_reduce_101, + 3, 207, :_reduce_102, + 3, 207, :_reduce_103, + 2, 207, :_reduce_104, + 1, 207, :_reduce_105, + 1, 170, :_reduce_106, + 1, 170, :_reduce_107, + 4, 170, :_reduce_108, + 3, 170, :_reduce_109, + 3, 170, :_reduce_110, + 3, 170, :_reduce_111, + 3, 170, :_reduce_112, + 2, 170, :_reduce_113, + 1, 170, :_reduce_114, + 1, 211, :_reduce_115, + 1, 211, :_reduce_none, + 2, 212, :_reduce_117, + 1, 212, :_reduce_118, + 3, 212, :_reduce_119, + 1, 213, :_reduce_none, + 1, 213, :_reduce_none, + 1, 213, :_reduce_none, + 1, 213, :_reduce_none, + 1, 213, :_reduce_none, + 1, 164, :_reduce_125, + 1, 164, :_reduce_none, + 1, 165, :_reduce_127, + 0, 217, :_reduce_128, + 4, 165, :_reduce_129, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 214, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 1, 215, :_reduce_none, + 3, 183, :_reduce_201, + 3, 183, :_reduce_202, + 6, 183, :_reduce_203, + 5, 183, :_reduce_204, + 5, 183, :_reduce_205, + 5, 183, :_reduce_206, + 5, 183, :_reduce_207, + 4, 183, :_reduce_208, + 3, 183, :_reduce_209, + 3, 183, :_reduce_210, + 3, 183, :_reduce_211, + 2, 183, :_reduce_212, + 2, 183, :_reduce_213, + 2, 183, :_reduce_214, + 2, 183, :_reduce_215, + 3, 183, :_reduce_216, + 3, 183, :_reduce_217, + 3, 183, :_reduce_218, + 3, 183, :_reduce_219, + 3, 183, :_reduce_220, + 3, 183, :_reduce_221, + 4, 183, :_reduce_222, + 2, 183, :_reduce_223, + 2, 183, :_reduce_224, + 3, 183, :_reduce_225, + 3, 183, :_reduce_226, + 3, 183, :_reduce_227, + 3, 183, :_reduce_228, + 1, 183, :_reduce_none, + 3, 183, :_reduce_230, + 3, 183, :_reduce_231, + 3, 183, :_reduce_232, + 3, 183, :_reduce_233, + 3, 183, :_reduce_234, + 2, 183, :_reduce_235, + 2, 183, :_reduce_236, + 3, 183, :_reduce_237, + 3, 183, :_reduce_238, + 3, 183, :_reduce_239, + 3, 183, :_reduce_240, + 3, 183, :_reduce_241, + 6, 183, :_reduce_242, + 1, 183, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 3, 220, :_reduce_248, + 3, 220, :_reduce_249, + 1, 223, :_reduce_none, + 1, 224, :_reduce_none, + 2, 224, :_reduce_none, + 4, 224, :_reduce_253, + 2, 224, :_reduce_254, + 1, 218, :_reduce_none, + 3, 218, :_reduce_256, + 3, 229, :_reduce_257, + 5, 229, :_reduce_258, + 3, 229, :_reduce_259, + 0, 231, :_reduce_260, + 1, 231, :_reduce_none, + 0, 178, :_reduce_262, + 1, 178, :_reduce_none, + 2, 178, :_reduce_none, + 4, 178, :_reduce_265, + 2, 178, :_reduce_266, + 1, 201, :_reduce_267, + 2, 201, :_reduce_268, + 2, 201, :_reduce_269, + 4, 201, :_reduce_270, + 1, 201, :_reduce_271, + 0, 234, :_reduce_272, + 2, 194, :_reduce_273, + 2, 233, :_reduce_274, + 2, 232, :_reduce_275, + 0, 232, :_reduce_276, + 1, 226, :_reduce_277, + 2, 226, :_reduce_278, + 3, 226, :_reduce_279, + 4, 226, :_reduce_280, + 1, 172, :_reduce_281, + 1, 172, :_reduce_none, + 3, 171, :_reduce_283, + 4, 171, :_reduce_284, + 2, 171, :_reduce_285, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_296, + 0, 260, :_reduce_297, + 4, 221, :_reduce_298, + 0, 261, :_reduce_299, + 4, 221, :_reduce_300, + 0, 262, :_reduce_301, + 4, 221, :_reduce_302, + 3, 221, :_reduce_303, + 3, 221, :_reduce_304, + 2, 221, :_reduce_305, + 3, 221, :_reduce_306, + 3, 221, :_reduce_307, + 1, 221, :_reduce_308, + 4, 221, :_reduce_309, + 3, 221, :_reduce_310, + 1, 221, :_reduce_311, + 5, 221, :_reduce_312, + 4, 221, :_reduce_313, + 3, 221, :_reduce_314, + 2, 221, :_reduce_315, + 1, 221, :_reduce_none, + 2, 221, :_reduce_317, + 0, 263, :_reduce_318, + 3, 221, :_reduce_319, + 6, 221, :_reduce_320, + 6, 221, :_reduce_321, + 4, 221, :_reduce_322, + 4, 221, :_reduce_323, + 5, 221, :_reduce_324, + 4, 221, :_reduce_325, + 5, 221, :_reduce_326, + 6, 221, :_reduce_327, + 0, 264, :_reduce_328, + 6, 221, :_reduce_329, + 0, 265, :_reduce_330, + 7, 221, :_reduce_331, + 0, 266, :_reduce_332, + 5, 221, :_reduce_333, + 0, 267, :_reduce_334, + 6, 221, :_reduce_335, + 0, 268, :_reduce_336, + 0, 269, :_reduce_337, + 9, 221, :_reduce_338, + 1, 221, :_reduce_339, + 1, 221, :_reduce_340, + 1, 221, :_reduce_341, + 1, 221, :_reduce_342, + 1, 177, :_reduce_none, + 1, 253, :_reduce_344, + 1, 256, :_reduce_345, + 1, 257, :_reduce_346, + 1, 200, :_reduce_347, + 1, 248, :_reduce_none, + 1, 248, :_reduce_none, + 2, 248, :_reduce_350, + 1, 187, :_reduce_none, + 1, 187, :_reduce_none, + 1, 249, :_reduce_none, + 5, 249, :_reduce_354, + 1, 160, :_reduce_none, + 2, 160, :_reduce_356, + 1, 252, :_reduce_none, + 1, 252, :_reduce_none, + 1, 270, :_reduce_359, + 3, 270, :_reduce_360, + 1, 273, :_reduce_361, + 3, 273, :_reduce_362, + 1, 272, :_reduce_none, + 3, 272, :_reduce_364, + 5, 272, :_reduce_365, + 1, 272, :_reduce_366, + 3, 272, :_reduce_367, + 2, 274, :_reduce_368, + 1, 274, :_reduce_369, + 4, 275, :_reduce_370, + 2, 275, :_reduce_371, + 2, 275, :_reduce_372, + 2, 275, :_reduce_373, + 1, 275, :_reduce_374, + 2, 281, :_reduce_375, + 0, 281, :_reduce_376, + 6, 282, :_reduce_377, + 8, 282, :_reduce_378, + 4, 282, :_reduce_379, + 6, 282, :_reduce_380, + 4, 282, :_reduce_381, + 2, 282, :_reduce_none, + 6, 282, :_reduce_383, + 2, 282, :_reduce_384, + 4, 282, :_reduce_385, + 6, 282, :_reduce_386, + 2, 282, :_reduce_387, + 4, 282, :_reduce_388, + 2, 282, :_reduce_389, + 4, 282, :_reduce_390, + 1, 282, :_reduce_none, + 0, 286, :_reduce_392, + 1, 286, :_reduce_393, + 3, 287, :_reduce_394, + 4, 287, :_reduce_395, + 1, 288, :_reduce_396, + 4, 288, :_reduce_397, + 1, 289, :_reduce_398, + 3, 289, :_reduce_399, + 1, 290, :_reduce_400, + 1, 290, :_reduce_none, + 0, 294, :_reduce_402, + 0, 295, :_reduce_403, + 4, 247, :_reduce_404, + 4, 292, :_reduce_405, + 1, 292, :_reduce_406, + 0, 298, :_reduce_407, + 4, 293, :_reduce_408, + 0, 299, :_reduce_409, + 4, 293, :_reduce_410, + 0, 301, :_reduce_411, + 4, 297, :_reduce_412, + 2, 191, :_reduce_413, + 4, 191, :_reduce_414, + 5, 191, :_reduce_415, + 5, 191, :_reduce_416, + 2, 246, :_reduce_417, + 4, 246, :_reduce_418, + 4, 246, :_reduce_419, + 3, 246, :_reduce_420, + 3, 246, :_reduce_421, + 3, 246, :_reduce_422, + 2, 246, :_reduce_423, + 1, 246, :_reduce_424, + 4, 246, :_reduce_425, + 0, 303, :_reduce_426, + 4, 245, :_reduce_427, + 0, 304, :_reduce_428, + 4, 245, :_reduce_429, + 0, 305, :_reduce_430, + 3, 196, :_reduce_431, + 0, 306, :_reduce_432, + 0, 307, :_reduce_433, + 4, 300, :_reduce_434, + 5, 250, :_reduce_435, + 1, 308, :_reduce_436, + 1, 308, :_reduce_none, + 0, 311, :_reduce_438, + 0, 312, :_reduce_439, + 7, 251, :_reduce_440, + 1, 310, :_reduce_441, + 1, 310, :_reduce_none, + 1, 309, :_reduce_443, + 3, 309, :_reduce_444, + 3, 309, :_reduce_445, + 1, 313, :_reduce_none, + 2, 313, :_reduce_447, + 3, 313, :_reduce_448, + 1, 313, :_reduce_449, + 1, 313, :_reduce_450, + 1, 184, :_reduce_none, + 3, 317, :_reduce_452, + 1, 317, :_reduce_none, + 3, 319, :_reduce_454, + 1, 319, :_reduce_none, + 1, 321, :_reduce_456, + 1, 322, :_reduce_457, + 1, 320, :_reduce_none, + 4, 320, :_reduce_459, + 4, 320, :_reduce_460, + 3, 320, :_reduce_461, + 4, 320, :_reduce_462, + 4, 320, :_reduce_463, + 3, 320, :_reduce_464, + 0, 326, :_reduce_465, + 4, 320, :_reduce_466, + 2, 320, :_reduce_467, + 0, 327, :_reduce_468, + 4, 320, :_reduce_469, + 2, 320, :_reduce_470, + 0, 328, :_reduce_471, + 4, 320, :_reduce_472, + 1, 314, :_reduce_473, + 1, 314, :_reduce_474, + 2, 314, :_reduce_475, + 3, 314, :_reduce_476, + 5, 314, :_reduce_477, + 2, 314, :_reduce_478, + 4, 314, :_reduce_479, + 1, 314, :_reduce_none, + 2, 329, :_reduce_481, + 3, 329, :_reduce_482, + 2, 315, :_reduce_483, + 4, 315, :_reduce_484, + 1, 315, :_reduce_485, + 3, 315, :_reduce_486, + 1, 331, :_reduce_487, + 3, 331, :_reduce_488, + 1, 330, :_reduce_none, + 3, 316, :_reduce_490, + 1, 316, :_reduce_491, + 2, 316, :_reduce_492, + 1, 316, :_reduce_493, + 3, 316, :_reduce_494, + 1, 316, :_reduce_495, + 1, 332, :_reduce_496, + 3, 332, :_reduce_497, + 2, 335, :_reduce_498, + 1, 335, :_reduce_499, + 1, 336, :_reduce_500, + 3, 336, :_reduce_501, + 2, 333, :_reduce_502, + 1, 333, :_reduce_503, + 2, 334, :_reduce_504, + 1, 323, :_reduce_none, + 3, 323, :_reduce_506, + 3, 323, :_reduce_507, + 2, 323, :_reduce_508, + 2, 323, :_reduce_509, + 1, 323, :_reduce_none, + 1, 323, :_reduce_none, + 1, 323, :_reduce_none, + 2, 323, :_reduce_513, + 2, 323, :_reduce_514, + 1, 339, :_reduce_none, + 1, 339, :_reduce_none, + 1, 339, :_reduce_none, + 1, 339, :_reduce_none, + 1, 339, :_reduce_none, + 1, 339, :_reduce_none, + 1, 339, :_reduce_none, + 1, 339, :_reduce_none, + 1, 339, :_reduce_523, + 0, 341, :_reduce_524, + 3, 339, :_reduce_525, + 1, 318, :_reduce_526, + 2, 340, :_reduce_527, + 2, 324, :_reduce_528, + 3, 324, :_reduce_529, + 1, 324, :_reduce_530, + 6, 159, :_reduce_531, + 0, 159, :_reduce_532, + 1, 342, :_reduce_533, + 1, 342, :_reduce_none, + 1, 342, :_reduce_none, + 2, 343, :_reduce_536, + 1, 343, :_reduce_none, + 2, 161, :_reduce_538, + 1, 161, :_reduce_none, + 1, 235, :_reduce_none, + 1, 235, :_reduce_none, + 1, 236, :_reduce_542, + 1, 345, :_reduce_543, + 2, 345, :_reduce_544, + 3, 346, :_reduce_545, + 1, 346, :_reduce_546, + 1, 346, :_reduce_547, + 3, 237, :_reduce_548, + 4, 238, :_reduce_549, + 3, 239, :_reduce_550, + 0, 349, :_reduce_551, + 3, 349, :_reduce_552, + 1, 350, :_reduce_553, + 2, 350, :_reduce_554, + 3, 241, :_reduce_555, + 0, 352, :_reduce_556, + 3, 352, :_reduce_557, + 3, 240, :_reduce_558, + 3, 242, :_reduce_559, + 0, 353, :_reduce_560, + 3, 353, :_reduce_561, + 0, 354, :_reduce_562, + 3, 354, :_reduce_563, + 0, 337, :_reduce_564, + 2, 337, :_reduce_565, + 0, 347, :_reduce_566, + 2, 347, :_reduce_567, + 0, 348, :_reduce_568, + 2, 348, :_reduce_569, + 1, 351, :_reduce_570, + 2, 351, :_reduce_571, + 0, 356, :_reduce_572, + 4, 351, :_reduce_573, + 1, 355, :_reduce_574, + 1, 355, :_reduce_575, + 1, 355, :_reduce_576, + 1, 355, :_reduce_none, + 1, 216, :_reduce_none, + 1, 216, :_reduce_none, + 1, 357, :_reduce_580, + 3, 358, :_reduce_581, + 1, 344, :_reduce_582, + 2, 344, :_reduce_583, + 1, 219, :_reduce_584, + 1, 219, :_reduce_585, + 1, 219, :_reduce_586, + 1, 219, :_reduce_587, + 1, 209, :_reduce_588, + 1, 209, :_reduce_589, + 1, 209, :_reduce_590, + 1, 209, :_reduce_591, + 1, 209, :_reduce_592, + 1, 210, :_reduce_593, + 1, 210, :_reduce_594, + 1, 210, :_reduce_595, + 1, 210, :_reduce_596, + 1, 210, :_reduce_597, + 1, 210, :_reduce_598, + 1, 210, :_reduce_599, + 1, 243, :_reduce_600, + 1, 243, :_reduce_601, + 1, 176, :_reduce_602, + 1, 176, :_reduce_603, + 1, 181, :_reduce_604, + 1, 181, :_reduce_605, + 0, 359, :_reduce_606, + 4, 254, :_reduce_607, + 0, 254, :_reduce_608, + 3, 258, :_reduce_609, + 5, 258, :_reduce_610, + 3, 258, :_reduce_611, + 0, 361, :_reduce_612, + 3, 258, :_reduce_613, + 4, 360, :_reduce_614, + 2, 360, :_reduce_615, + 2, 360, :_reduce_616, + 2, 360, :_reduce_617, + 1, 360, :_reduce_618, + 2, 363, :_reduce_619, + 0, 363, :_reduce_620, + 6, 296, :_reduce_621, + 8, 296, :_reduce_622, + 4, 296, :_reduce_623, + 6, 296, :_reduce_624, + 4, 296, :_reduce_625, + 6, 296, :_reduce_626, + 2, 296, :_reduce_627, + 4, 296, :_reduce_628, + 6, 296, :_reduce_629, + 2, 296, :_reduce_630, + 4, 296, :_reduce_631, + 2, 296, :_reduce_632, + 4, 296, :_reduce_633, + 1, 296, :_reduce_634, + 0, 296, :_reduce_635, + 1, 230, :_reduce_636, + 1, 291, :_reduce_637, + 1, 291, :_reduce_638, + 1, 291, :_reduce_639, + 1, 291, :_reduce_640, + 1, 271, :_reduce_none, + 1, 271, :_reduce_642, + 1, 365, :_reduce_643, + 1, 366, :_reduce_644, + 3, 366, :_reduce_645, + 1, 283, :_reduce_646, + 3, 283, :_reduce_647, + 1, 367, :_reduce_648, + 2, 368, :_reduce_649, + 1, 368, :_reduce_650, + 2, 369, :_reduce_651, + 1, 369, :_reduce_652, + 1, 276, :_reduce_653, + 3, 276, :_reduce_654, + 1, 362, :_reduce_655, + 3, 362, :_reduce_656, + 1, 338, :_reduce_none, + 1, 338, :_reduce_none, + 2, 279, :_reduce_659, + 2, 277, :_reduce_660, + 1, 277, :_reduce_661, + 3, 370, :_reduce_662, + 3, 371, :_reduce_663, + 1, 284, :_reduce_664, + 3, 284, :_reduce_665, + 1, 364, :_reduce_666, + 3, 364, :_reduce_667, + 1, 372, :_reduce_none, + 1, 372, :_reduce_none, + 2, 285, :_reduce_670, + 1, 285, :_reduce_671, + 1, 373, :_reduce_none, + 1, 373, :_reduce_none, + 2, 280, :_reduce_674, + 2, 278, :_reduce_675, + 0, 278, :_reduce_676, + 1, 259, :_reduce_none, + 3, 259, :_reduce_678, + 0, 244, :_reduce_679, + 2, 244, :_reduce_none, + 1, 228, :_reduce_681, + 3, 228, :_reduce_682, + 3, 374, :_reduce_683, + 2, 374, :_reduce_684, + 4, 374, :_reduce_685, + 2, 374, :_reduce_686, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 199, :_reduce_none, + 1, 193, :_reduce_none, + 1, 193, :_reduce_none, + 1, 193, :_reduce_none, + 1, 193, :_reduce_none, + 1, 302, :_reduce_none, + 1, 302, :_reduce_none, + 1, 302, :_reduce_none, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 180, :_reduce_699, + 1, 180, :_reduce_700, + 0, 152, :_reduce_none, + 1, 152, :_reduce_none, + 0, 182, :_reduce_none, + 1, 182, :_reduce_none, + 2, 204, :_reduce_705, + 2, 179, :_reduce_706, + 2, 325, :_reduce_707, + 0, 227, :_reduce_none, + 1, 227, :_reduce_none, + 1, 227, :_reduce_none, + 1, 255, :_reduce_711, + 1, 255, :_reduce_none, + 1, 154, :_reduce_none, + 2, 154, :_reduce_none, + 0, 225, :_reduce_715 ] + +racc_reduce_n = 716 + +racc_shift_n = 1194 + +racc_token_table = { + false => 0, + :error => 1, + :kCLASS => 2, + :kMODULE => 3, + :kDEF => 4, + :kUNDEF => 5, + :kBEGIN => 6, + :kRESCUE => 7, + :kENSURE => 8, + :kEND => 9, + :kIF => 10, + :kUNLESS => 11, + :kTHEN => 12, + :kELSIF => 13, + :kELSE => 14, + :kCASE => 15, + :kWHEN => 16, + :kWHILE => 17, + :kUNTIL => 18, + :kFOR => 19, + :kBREAK => 20, + :kNEXT => 21, + :kREDO => 22, + :kRETRY => 23, + :kIN => 24, + :kDO => 25, + :kDO_COND => 26, + :kDO_BLOCK => 27, + :kDO_LAMBDA => 28, + :kRETURN => 29, + :kYIELD => 30, + :kSUPER => 31, + :kSELF => 32, + :kNIL => 33, + :kTRUE => 34, + :kFALSE => 35, + :kAND => 36, + :kOR => 37, + :kNOT => 38, + :kIF_MOD => 39, + :kUNLESS_MOD => 40, + :kWHILE_MOD => 41, + :kUNTIL_MOD => 42, + :kRESCUE_MOD => 43, + :kALIAS => 44, + :kDEFINED => 45, + :klBEGIN => 46, + :klEND => 47, + :k__LINE__ => 48, + :k__FILE__ => 49, + :k__ENCODING__ => 50, + :tIDENTIFIER => 51, + :tFID => 52, + :tGVAR => 53, + :tIVAR => 54, + :tCONSTANT => 55, + :tLABEL => 56, + :tCVAR => 57, + :tNTH_REF => 58, + :tBACK_REF => 59, + :tSTRING_CONTENT => 60, + :tINTEGER => 61, + :tFLOAT => 62, + :tUPLUS => 63, + :tUMINUS => 64, + :tUNARY_NUM => 65, + :tPOW => 66, + :tCMP => 67, + :tEQ => 68, + :tEQQ => 69, + :tNEQ => 70, + :tGEQ => 71, + :tLEQ => 72, + :tANDOP => 73, + :tOROP => 74, + :tMATCH => 75, + :tNMATCH => 76, + :tDOT => 77, + :tDOT2 => 78, + :tDOT3 => 79, + :tAREF => 80, + :tASET => 81, + :tLSHFT => 82, + :tRSHFT => 83, + :tCOLON2 => 84, + :tCOLON3 => 85, + :tOP_ASGN => 86, + :tASSOC => 87, + :tLPAREN => 88, + :tLPAREN2 => 89, + :tRPAREN => 90, + :tLPAREN_ARG => 91, + :tLBRACK => 92, + :tLBRACK2 => 93, + :tRBRACK => 94, + :tLBRACE => 95, + :tLBRACE_ARG => 96, + :tSTAR => 97, + :tSTAR2 => 98, + :tAMPER => 99, + :tAMPER2 => 100, + :tTILDE => 101, + :tPERCENT => 102, + :tDIVIDE => 103, + :tDSTAR => 104, + :tPLUS => 105, + :tMINUS => 106, + :tLT => 107, + :tGT => 108, + :tPIPE => 109, + :tBANG => 110, + :tCARET => 111, + :tLCURLY => 112, + :tRCURLY => 113, + :tBACK_REF2 => 114, + :tSYMBEG => 115, + :tSTRING_BEG => 116, + :tXSTRING_BEG => 117, + :tREGEXP_BEG => 118, + :tREGEXP_OPT => 119, + :tWORDS_BEG => 120, + :tQWORDS_BEG => 121, + :tSYMBOLS_BEG => 122, + :tQSYMBOLS_BEG => 123, + :tSTRING_DBEG => 124, + :tSTRING_DVAR => 125, + :tSTRING_END => 126, + :tSTRING_DEND => 127, + :tSTRING => 128, + :tSYMBOL => 129, + :tNL => 130, + :tEH => 131, + :tCOLON => 132, + :tCOMMA => 133, + :tSPACE => 134, + :tSEMI => 135, + :tLAMBDA => 136, + :tLAMBEG => 137, + :tCHARACTER => 138, + :tRATIONAL => 139, + :tIMAGINARY => 140, + :tLABEL_END => 141, + :tANDDOT => 142, + :tBDOT2 => 143, + :tBDOT3 => 144, + :tEQL => 145, + :tLOWEST => 146 } + +racc_nt_base = 147 + +racc_use_result_var = true + +Racc_arg = [ + racc_action_table, + racc_action_check, + racc_action_default, + racc_action_pointer, + racc_goto_table, + racc_goto_check, + racc_goto_default, + racc_goto_pointer, + racc_nt_base, + racc_reduce_table, + racc_token_table, + racc_shift_n, + racc_reduce_n, + racc_use_result_var ] +Ractor.make_shareable(Racc_arg) if defined?(Ractor) + +Racc_token_to_s_table = [ + "$end", + "error", + "kCLASS", + "kMODULE", + "kDEF", + "kUNDEF", + "kBEGIN", + "kRESCUE", + "kENSURE", + "kEND", + "kIF", + "kUNLESS", + "kTHEN", + "kELSIF", + "kELSE", + "kCASE", + "kWHEN", + "kWHILE", + "kUNTIL", + "kFOR", + "kBREAK", + "kNEXT", + "kREDO", + "kRETRY", + "kIN", + "kDO", + "kDO_COND", + "kDO_BLOCK", + "kDO_LAMBDA", + "kRETURN", + "kYIELD", + "kSUPER", + "kSELF", + "kNIL", + "kTRUE", + "kFALSE", + "kAND", + "kOR", + "kNOT", + "kIF_MOD", + "kUNLESS_MOD", + "kWHILE_MOD", + "kUNTIL_MOD", + "kRESCUE_MOD", + "kALIAS", + "kDEFINED", + "klBEGIN", + "klEND", + "k__LINE__", + "k__FILE__", + "k__ENCODING__", + "tIDENTIFIER", + "tFID", + "tGVAR", + "tIVAR", + "tCONSTANT", + "tLABEL", + "tCVAR", + "tNTH_REF", + "tBACK_REF", + "tSTRING_CONTENT", + "tINTEGER", + "tFLOAT", + "tUPLUS", + "tUMINUS", + "tUNARY_NUM", + "tPOW", + "tCMP", + "tEQ", + "tEQQ", + "tNEQ", + "tGEQ", + "tLEQ", + "tANDOP", + "tOROP", + "tMATCH", + "tNMATCH", + "tDOT", + "tDOT2", + "tDOT3", + "tAREF", + "tASET", + "tLSHFT", + "tRSHFT", + "tCOLON2", + "tCOLON3", + "tOP_ASGN", + "tASSOC", + "tLPAREN", + "tLPAREN2", + "tRPAREN", + "tLPAREN_ARG", + "tLBRACK", + "tLBRACK2", + "tRBRACK", + "tLBRACE", + "tLBRACE_ARG", + "tSTAR", + "tSTAR2", + "tAMPER", + "tAMPER2", + "tTILDE", + "tPERCENT", + "tDIVIDE", + "tDSTAR", + "tPLUS", + "tMINUS", + "tLT", + "tGT", + "tPIPE", + "tBANG", + "tCARET", + "tLCURLY", + "tRCURLY", + "tBACK_REF2", + "tSYMBEG", + "tSTRING_BEG", + "tXSTRING_BEG", + "tREGEXP_BEG", + "tREGEXP_OPT", + "tWORDS_BEG", + "tQWORDS_BEG", + "tSYMBOLS_BEG", + "tQSYMBOLS_BEG", + "tSTRING_DBEG", + "tSTRING_DVAR", + "tSTRING_END", + "tSTRING_DEND", + "tSTRING", + "tSYMBOL", + "tNL", + "tEH", + "tCOLON", + "tCOMMA", + "tSPACE", + "tSEMI", + "tLAMBDA", + "tLAMBEG", + "tCHARACTER", + "tRATIONAL", + "tIMAGINARY", + "tLABEL_END", + "tANDDOT", + "tBDOT2", + "tBDOT3", + "tEQL", + "tLOWEST", + "$start", + "program", + "top_compstmt", + "@1", + "top_stmts", + "opt_terms", + "top_stmt", + "terms", + "stmt", + "begin_block", + "bodystmt", + "compstmt", + "opt_rescue", + "opt_else", + "opt_ensure", + "stmts", + "stmt_or_begin", + "fitem", + "undef_list", + "expr_value", + "command_asgn", + "mlhs", + "command_call", + "lhs", + "mrhs", + "mrhs_arg", + "expr", + "@2", + "command_rhs", + "var_lhs", + "primary_value", + "opt_call_args", + "rbracket", + "call_op", + "backref", + "opt_nl", + "arg", + "p_expr", + "@3", + "expr_value_do", + "do", + "@4", + "command", + "block_command", + "block_call", + "dot_or_colon", + "operation2", + "command_args", + "cmd_brace_block", + "brace_body", + "fcall", + "@5", + "operation", + "k_return", + "call_args", + "mlhs_basic", + "mlhs_inner", + "rparen", + "mlhs_head", + "mlhs_item", + "mlhs_node", + "mlhs_post", + "user_variable", + "keyword_variable", + "cname", + "cpath", + "fname", + "op", + "reswords", + "symbol", + "@6", + "arg_rhs", + "simple_numeric", + "rel_expr", + "primary", + "relop", + "arg_value", + "aref_args", + "none", + "args", + "trailer", + "assocs", + "paren_args", + "args_forward", + "opt_paren_args", + "opt_block_arg", + "block_arg", + "@7", + "literal", + "strings", + "xstring", + "regexp", + "words", + "qwords", + "symbols", + "qsymbols", + "var_ref", + "assoc_list", + "brace_block", + "method_call", + "lambda", + "then", + "if_tail", + "case_body", + "p_case_body", + "for_var", + "k_class", + "superclass", + "term", + "k_module", + "k_def", + "f_arglist", + "singleton", + "@8", + "@9", + "@10", + "@11", + "@12", + "@13", + "@14", + "@15", + "@16", + "@17", + "f_marg", + "f_norm_arg", + "f_margs", + "f_marg_list", + "f_rest_marg", + "block_args_tail", + "f_block_kwarg", + "f_kwrest", + "opt_f_block_arg", + "f_no_kwarg", + "f_block_arg", + "opt_block_args_tail", + "block_param", + "f_arg", + "f_block_optarg", + "f_rest_arg", + "opt_block_param", + "block_param_def", + "opt_bv_decl", + "bv_decls", + "bvar", + "f_bad_arg", + "f_larglist", + "lambda_body", + "@18", + "@19", + "f_args", + "do_block", + "@20", + "@21", + "do_body", + "@22", + "operation3", + "@23", + "@24", + "@25", + "@26", + "@27", + "cases", + "p_top_expr", + "p_cases", + "@28", + "@29", + "p_top_expr_body", + "p_args", + "p_args_tail", + "p_kwargs", + "p_as", + "p_variable", + "p_alt", + "p_expr_basic", + "p_lparen", + "p_lbracket", + "p_value", + "p_const", + "rbrace", + "@30", + "@31", + "@32", + "p_args_head", + "p_arg", + "p_args_post", + "p_kwarg", + "p_kwrest", + "p_kwnorest", + "p_kw", + "p_kw_label", + "string_contents", + "kwrest_mark", + "p_primitive", + "p_var_ref", + "@33", + "exc_list", + "exc_var", + "numeric", + "string", + "string1", + "xstring_contents", + "regexp_contents", + "word_list", + "word", + "string_content", + "symbol_list", + "qword_list", + "qsym_list", + "string_dvar", + "@34", + "ssym", + "dsym", + "@35", + "args_tail", + "@36", + "f_kwarg", + "opt_args_tail", + "f_optarg", + "f_arg_asgn", + "f_arg_item", + "f_label", + "f_kw", + "f_block_kw", + "f_opt", + "f_block_opt", + "restarg_mark", + "blkarg_mark", + "assoc" ] +Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) + +Racc_debug_parser = false + +##### State transition tables end ##### + +# reduce 0 omitted + +def _reduce_1(val, _values, result) + @current_arg_stack.push(nil) + @max_numparam_stack.push(static: false) + + result +end + +def _reduce_2(val, _values, result) + result = val[1] + + @current_arg_stack.pop + @max_numparam_stack.pop + + result +end + +def _reduce_3(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_4(val, _values, result) + result = [] + + result +end + +def _reduce_5(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_6(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_7(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 8 omitted + +def _reduce_9(val, _values, result) + result = @builder.preexe(val[0], *val[1]) + + result +end + +def _reduce_10(val, _values, result) + result = val + + result +end + +def _reduce_11(val, _values, result) + rescue_bodies = val[1] + else_t, else_ = val[2] + ensure_t, ensure_ = val[3] + + if rescue_bodies.empty? && !else_t.nil? + diagnostic :error, :useless_else, nil, else_t + end + + result = @builder.begin_body(val[0], + rescue_bodies, + else_t, else_, + ensure_t, ensure_) + + result +end + +def _reduce_12(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_13(val, _values, result) + result = [] + + result +end + +def _reduce_14(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_15(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_16(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 17 omitted + +def _reduce_18(val, _values, result) + diagnostic :error, :begin_in_method, nil, val[0] + + result +end + +def _reduce_19(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_20(val, _values, result) + result = @builder.alias(val[0], val[1], val[3]) + + result +end + +def _reduce_21(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.gvar(val[2])) + + result +end + +def _reduce_22(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.back_ref(val[2])) + + result +end + +def _reduce_23(val, _values, result) + diagnostic :error, :nth_ref_alias, nil, val[2] + + result +end + +def _reduce_24(val, _values, result) + result = @builder.undef_method(val[0], val[1]) + + result +end + +def _reduce_25(val, _values, result) + result = @builder.condition_mod(val[0], nil, + val[1], val[2]) + + result +end + +def _reduce_26(val, _values, result) + result = @builder.condition_mod(nil, val[0], + val[1], val[2]) + + result +end + +def _reduce_27(val, _values, result) + result = @builder.loop_mod(:while, val[0], val[1], val[2]) + + result +end + +def _reduce_28(val, _values, result) + result = @builder.loop_mod(:until, val[0], val[1], val[2]) + + result +end + +def _reduce_29(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_30(val, _values, result) + result = @builder.postexe(val[0], val[1], val[2], val[3]) + + result +end + +# reduce 31 omitted + +def _reduce_32(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_33(val, _values, result) + result = @builder.assign(val[0], val[1], + @builder.array(nil, val[2], nil)) + + result +end + +def _reduce_34(val, _values, result) + rescue_body = @builder.rescue_body(val[3], + nil, nil, nil, + nil, val[4]) + begin_body = @builder.begin_body(val[2], [ rescue_body ]) + + result = @builder.multi_assign(val[0], val[1], begin_body) + + result +end + +def _reduce_35(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +# reduce 36 omitted + +def _reduce_37(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_38(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_39(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_40(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_41(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_42(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_43(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_44(val, _values, result) + @builder.op_assign(val[0], val[1], val[2]) + + result +end + +# reduce 45 omitted + +def _reduce_46(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +# reduce 47 omitted + +# reduce 48 omitted + +def _reduce_49(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_50(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_51(val, _values, result) + result = @builder.not_op(val[0], nil, val[2], nil) + + result +end + +def _reduce_52(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +def _reduce_53(val, _values, result) + @lexer.state = :expr_beg + @lexer.command_start = false + @pattern_variables.push + + result = @context.in_kwarg + @context.in_kwarg = true + + result +end + +def _reduce_54(val, _values, result) + @pattern_variables.pop + @context.in_kwarg = val[2] + if @builder.class.emit_match_pattern + result = @builder.match_pattern(val[0], val[1], val[3]) + else + result = @builder.in_match(val[0], val[1], val[3]) + end + + result +end + +# reduce 55 omitted + +# reduce 56 omitted + +def _reduce_57(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_58(val, _values, result) + @lexer.cond.pop + result = [ val[1], val[2] ] + + result +end + +# reduce 59 omitted + +# reduce 60 omitted + +# reduce 61 omitted + +def _reduce_62(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_63(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_64(val, _values, result) + result = [ val[0], *val[2], val[3] ] + @context.in_block = val[1].in_block + + result +end + +# reduce 65 omitted + +def _reduce_66(val, _values, result) + result = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + result +end + +def _reduce_67(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + begin_t, args, body, end_t = val[2] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_68(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_69(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_70(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_71(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_72(val, _values, result) + result = @builder.keyword_cmd(:super, val[0], + nil, val[1], nil) + + result +end + +def _reduce_73(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], + nil, val[1], nil) + + result +end + +def _reduce_74(val, _values, result) + result = @builder.keyword_cmd(:return, val[0], + nil, val[1], nil) + + result +end + +def _reduce_75(val, _values, result) + result = @builder.keyword_cmd(:break, val[0], + nil, val[1], nil) + + result +end + +def _reduce_76(val, _values, result) + result = @builder.keyword_cmd(:next, val[0], + nil, val[1], nil) + + result +end + +def _reduce_77(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_78(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_79(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_80(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +# reduce 81 omitted + +def _reduce_82(val, _values, result) + result = val[0]. + push(val[1]) + + result +end + +def _reduce_83(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])) + + result +end + +def _reduce_84(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])). + concat(val[4]) + + result +end + +def _reduce_85(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])) + + result +end + +def _reduce_86(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])). + concat(val[3]) + + result +end + +def _reduce_87(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_88(val, _values, result) + result = [ @builder.splat(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_89(val, _values, result) + result = [ @builder.splat(val[0]) ] + + result +end + +def _reduce_90(val, _values, result) + result = [ @builder.splat(val[0]), + *val[2] ] + + result +end + +# reduce 91 omitted + +def _reduce_92(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_93(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_94(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_95(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_96(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_97(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_98(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_99(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_100(val, _values, result) + if (val[1][0] == :anddot) + diagnostic :error, :csend_in_lhs_of_masgn, nil, val[1] + end + + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_101(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_102(val, _values, result) + if (val[1][0] == :anddot) + diagnostic :error, :csend_in_lhs_of_masgn, nil, val[1] + end + + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_103(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_104(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_105(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_106(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_107(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_108(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_109(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_110(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_111(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_112(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_113(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_114(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_115(val, _values, result) + diagnostic :error, :module_name_const, nil, val[0] + + result +end + +# reduce 116 omitted + +def _reduce_117(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_118(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_119(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +# reduce 120 omitted + +# reduce 121 omitted + +# reduce 122 omitted + +# reduce 123 omitted + +# reduce 124 omitted + +def _reduce_125(val, _values, result) + result = @builder.symbol_internal(val[0]) + + result +end + +# reduce 126 omitted + +def _reduce_127(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_128(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_129(val, _values, result) + result = val[0] << val[3] + + result +end + +# reduce 130 omitted + +# reduce 131 omitted + +# reduce 132 omitted + +# reduce 133 omitted + +# reduce 134 omitted + +# reduce 135 omitted + +# reduce 136 omitted + +# reduce 137 omitted + +# reduce 138 omitted + +# reduce 139 omitted + +# reduce 140 omitted + +# reduce 141 omitted + +# reduce 142 omitted + +# reduce 143 omitted + +# reduce 144 omitted + +# reduce 145 omitted + +# reduce 146 omitted + +# reduce 147 omitted + +# reduce 148 omitted + +# reduce 149 omitted + +# reduce 150 omitted + +# reduce 151 omitted + +# reduce 152 omitted + +# reduce 153 omitted + +# reduce 154 omitted + +# reduce 155 omitted + +# reduce 156 omitted + +# reduce 157 omitted + +# reduce 158 omitted + +# reduce 159 omitted + +# reduce 160 omitted + +# reduce 161 omitted + +# reduce 162 omitted + +# reduce 163 omitted + +# reduce 164 omitted + +# reduce 165 omitted + +# reduce 166 omitted + +# reduce 167 omitted + +# reduce 168 omitted + +# reduce 169 omitted + +# reduce 170 omitted + +# reduce 171 omitted + +# reduce 172 omitted + +# reduce 173 omitted + +# reduce 174 omitted + +# reduce 175 omitted + +# reduce 176 omitted + +# reduce 177 omitted + +# reduce 178 omitted + +# reduce 179 omitted + +# reduce 180 omitted + +# reduce 181 omitted + +# reduce 182 omitted + +# reduce 183 omitted + +# reduce 184 omitted + +# reduce 185 omitted + +# reduce 186 omitted + +# reduce 187 omitted + +# reduce 188 omitted + +# reduce 189 omitted + +# reduce 190 omitted + +# reduce 191 omitted + +# reduce 192 omitted + +# reduce 193 omitted + +# reduce 194 omitted + +# reduce 195 omitted + +# reduce 196 omitted + +# reduce 197 omitted + +# reduce 198 omitted + +# reduce 199 omitted + +# reduce 200 omitted + +def _reduce_201(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_202(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_203(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_204(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_205(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_206(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_207(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_208(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_global(val[0], val[1])) + result = @builder.op_assign(const, val[2], val[3]) + + result +end + +def _reduce_209(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_210(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_211(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_212(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], nil) + + result +end + +def _reduce_213(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], nil) + + result +end + +def _reduce_214(val, _values, result) + result = @builder.range_inclusive(nil, val[0], val[1]) + + result +end + +def _reduce_215(val, _values, result) + result = @builder.range_exclusive(nil, val[0], val[1]) + + result +end + +def _reduce_216(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_217(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_218(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_219(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_220(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_221(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_222(val, _values, result) + result = @builder.unary_op(val[0], + @builder.binary_op( + val[1], val[2], val[3])) + + result +end + +def _reduce_223(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_224(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_225(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_226(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_227(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_228(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +# reduce 229 omitted + +def _reduce_230(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_231(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_232(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_233(val, _values, result) + result = @builder.match_op(val[0], val[1], val[2]) + + result +end + +def _reduce_234(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_235(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +def _reduce_236(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_237(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_238(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_239(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_240(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_241(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil) + + result +end + +def _reduce_242(val, _values, result) + result = @builder.ternary(val[0], val[1], + val[2], val[4], val[5]) + + result +end + +# reduce 243 omitted + +# reduce 244 omitted + +# reduce 245 omitted + +# reduce 246 omitted + +# reduce 247 omitted + +def _reduce_248(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_249(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +# reduce 250 omitted + +# reduce 251 omitted + +# reduce 252 omitted + +def _reduce_253(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_254(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +# reduce 255 omitted + +def _reduce_256(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_257(val, _values, result) + result = val + + result +end + +def _reduce_258(val, _values, result) + unless @static_env.declared_forward_args? + diagnostic :error, :unexpected_token, { :token => 'tBDOT3' } , val[3] + end + + result = [val[0], [*val[1], @builder.forwarded_args(val[3])], val[4]] + + result +end + +def _reduce_259(val, _values, result) + unless @static_env.declared_forward_args? + diagnostic :error, :unexpected_token, { :token => 'tBDOT3' } , val[1] + end + + result = [val[0], [@builder.forwarded_args(val[1])], val[2]] + + result +end + +def _reduce_260(val, _values, result) + result = [ nil, [], nil ] + + result +end + +# reduce 261 omitted + +def _reduce_262(val, _values, result) + result = [] + + result +end + +# reduce 263 omitted + +# reduce 264 omitted + +def _reduce_265(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_266(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +def _reduce_267(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_268(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_269(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + result.concat(val[1]) + + result +end + +def _reduce_270(val, _values, result) + assocs = @builder.associate(nil, val[2], nil) + result = val[0] << assocs + result.concat(val[3]) + + result +end + +def _reduce_271(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_272(val, _values, result) + # When branch gets invoked by RACC's lookahead + # and command args start with '[' or '(' + # we need to put `true` to the cmdarg stack + # **before** `false` pushed by lexer + # m [], n + # ^ + # Right here we have cmdarg [...0] because + # lexer pushed it on '[' + # We need to modify cmdarg stack to [...10] + # + # For all other cases (like `m n` or `m n, []`) we simply put 1 to the stack + # and later lexer pushes corresponding bits on top of it. + last_token = @last_token[0] + lookahead = last_token == :tLBRACK || last_token == :tLPAREN_ARG + + if lookahead + top = @lexer.cmdarg.pop + @lexer.cmdarg.push(true) + @lexer.cmdarg.push(top) + else + @lexer.cmdarg.push(true) + end + + result +end + +def _reduce_273(val, _values, result) + # call_args can be followed by tLBRACE_ARG (that does cmdarg.push(0) in the lexer) + # but the push must be done after cmdarg.pop() in the parser. + # So this code does cmdarg.pop() to pop 0 pushed by tLBRACE_ARG, + # cmdarg.pop() to pop 1 pushed by command_args, + # and cmdarg.push(0) to restore back the flag set by tLBRACE_ARG. + last_token = @last_token[0] + lookahead = last_token == :tLBRACE_ARG + if lookahead + top = @lexer.cmdarg.pop + @lexer.cmdarg.pop + @lexer.cmdarg.push(top) + else + @lexer.cmdarg.pop + end + + result = val[1] + + result +end + +def _reduce_274(val, _values, result) + result = @builder.block_pass(val[0], val[1]) + + result +end + +def _reduce_275(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_276(val, _values, result) + result = [] + + result +end + +def _reduce_277(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_278(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_279(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_280(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_281(val, _values, result) + result = @builder.array(nil, val[0], nil) + + result +end + +# reduce 282 omitted + +def _reduce_283(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_284(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_285(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +# reduce 286 omitted + +# reduce 287 omitted + +# reduce 288 omitted + +# reduce 289 omitted + +# reduce 290 omitted + +# reduce 291 omitted + +# reduce 292 omitted + +# reduce 293 omitted + +# reduce 294 omitted + +# reduce 295 omitted + +def _reduce_296(val, _values, result) + result = @builder.call_method(nil, nil, val[0]) + + result +end + +def _reduce_297(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_298(val, _values, result) + @lexer.cmdarg.pop + + result = @builder.begin_keyword(val[0], val[2], val[3]) + + result +end + +def _reduce_299(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_300(val, _values, result) + result = @builder.begin(val[0], val[1], val[3]) + + result +end + +def _reduce_301(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_302(val, _values, result) + result = @builder.begin(val[0], nil, val[3]) + + result +end + +def _reduce_303(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_304(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +def _reduce_305(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_306(val, _values, result) + result = @builder.array(val[0], val[1], val[2]) + + result +end + +def _reduce_307(val, _values, result) + result = @builder.associate(val[0], val[1], val[2]) + + result +end + +def _reduce_308(val, _values, result) + result = @builder.keyword_cmd(:return, val[0]) + + result +end + +def _reduce_309(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_310(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2]) + + result +end + +def _reduce_311(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0]) + + result +end + +def _reduce_312(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], + val[2], [ val[3] ], val[4]) + + result +end + +def _reduce_313(val, _values, result) + result = @builder.not_op(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_314(val, _values, result) + result = @builder.not_op(val[0], val[1], nil, val[2]) + + result +end + +def _reduce_315(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0]) + + begin_t, args, body, end_t = val[1] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +# reduce 316 omitted + +def _reduce_317(val, _values, result) + begin_t, args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, args, body, end_t) + + result +end + +def _reduce_318(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_319(val, _values, result) + lambda_call = @builder.call_lambda(val[0]) + + args, (begin_t, body, end_t) = val[2] + result = @builder.block(lambda_call, + begin_t, args, body, end_t) + + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_320(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, val[5]) + + result +end + +def _reduce_321(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + else_, else_t, + val[3], val[5]) + + result +end + +def _reduce_322(val, _values, result) + result = @builder.loop(:while, val[0], *val[1], val[2], val[3]) + + result +end + +def _reduce_323(val, _values, result) + result = @builder.loop(:until, val[0], *val[1], val[2], val[3]) + + result +end + +def _reduce_324(val, _values, result) + *when_bodies, (else_t, else_body) = *val[3] + + result = @builder.case(val[0], val[1], + when_bodies, else_t, else_body, + val[4]) + + result +end + +def _reduce_325(val, _values, result) + *when_bodies, (else_t, else_body) = *val[2] + + result = @builder.case(val[0], nil, + when_bodies, else_t, else_body, + val[3]) + + result +end + +def _reduce_326(val, _values, result) + *in_bodies, (else_t, else_body) = *val[3] + + result = @builder.case_match(val[0], val[1], + in_bodies, else_t, else_body, + val[4]) + + result +end + +def _reduce_327(val, _values, result) + result = @builder.for(val[0], val[1], val[2], *val[3], val[4], val[5]) + + result +end + +def _reduce_328(val, _values, result) + local_push + @context.in_class = true + + result +end + +def _reduce_329(val, _values, result) + k_class, ctx = val[0] + if @context.in_def + diagnostic :error, :class_in_def, nil, k_class + end + + lt_t, superclass = val[2] + result = @builder.def_class(k_class, val[1], + lt_t, superclass, + val[4], val[5]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_330(val, _values, result) + @context.in_def = false + @context.in_class = false + local_push + + result +end + +def _reduce_331(val, _values, result) + k_class, ctx = val[0] + result = @builder.def_sclass(k_class, val[1], val[2], + val[5], val[6]) + + local_pop + @context.in_def = ctx.in_def + @context.in_class = ctx.in_class + + result +end + +def _reduce_332(val, _values, result) + @context.in_class = true + local_push + + result +end + +def _reduce_333(val, _values, result) + k_mod, ctx = val[0] + if @context.in_def + diagnostic :error, :module_in_def, nil, k_mod + end + + result = @builder.def_module(k_mod, val[1], + val[3], val[4]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_334(val, _values, result) + local_push + result = context.dup + @context.in_def = true + @current_arg_stack.push(nil) + + result +end + +def _reduce_335(val, _values, result) + result = @builder.def_method(val[0], val[1], + val[3], val[4], val[5]) + + local_pop + @context.in_def = val[2].in_def + @current_arg_stack.pop + + result +end + +def _reduce_336(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_337(val, _values, result) + local_push + result = context.dup + @context.in_def = true + @current_arg_stack.push(nil) + + result +end + +def _reduce_338(val, _values, result) + result = @builder.def_singleton(val[0], val[1], val[2], + val[4], val[6], val[7], val[8]) + + local_pop + @context.in_def = val[5].in_def + @current_arg_stack.pop + + result +end + +def _reduce_339(val, _values, result) + result = @builder.keyword_cmd(:break, val[0]) + + result +end + +def _reduce_340(val, _values, result) + result = @builder.keyword_cmd(:next, val[0]) + + result +end + +def _reduce_341(val, _values, result) + result = @builder.keyword_cmd(:redo, val[0]) + + result +end + +def _reduce_342(val, _values, result) + result = @builder.keyword_cmd(:retry, val[0]) + + result +end + +# reduce 343 omitted + +def _reduce_344(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_345(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_346(val, _values, result) + result = val[0] + + result +end + +def _reduce_347(val, _values, result) + if @context.in_class && !@context.in_def && !(context.in_block || context.in_lambda) + diagnostic :error, :invalid_return, nil, val[0] + end + + result +end + +# reduce 348 omitted + +# reduce 349 omitted + +def _reduce_350(val, _values, result) + result = val[1] + + result +end + +# reduce 351 omitted + +# reduce 352 omitted + +# reduce 353 omitted + +def _reduce_354(val, _values, result) + else_t, else_ = val[4] + result = [ val[0], + @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, nil), + ] + + result +end + +# reduce 355 omitted + +def _reduce_356(val, _values, result) + result = val + + result +end + +# reduce 357 omitted + +# reduce 358 omitted + +def _reduce_359(val, _values, result) + result = @builder.arg(val[0]) + + result +end + +def _reduce_360(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_361(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_362(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 363 omitted + +def _reduce_364(val, _values, result) + result = val[0]. + push(val[2]) + + result +end + +def _reduce_365(val, _values, result) + result = val[0]. + push(val[2]). + concat(val[4]) + + result +end + +def _reduce_366(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_367(val, _values, result) + result = [ val[0], *val[2] ] + + result +end + +def _reduce_368(val, _values, result) + result = @builder.restarg(val[0], val[1]) + + result +end + +def _reduce_369(val, _values, result) + result = @builder.restarg(val[0]) + + result +end + +def _reduce_370(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_371(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_372(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_373(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_374(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_375(val, _values, result) + result = val[1] + + result +end + +def _reduce_376(val, _values, result) + result = [] + + result +end + +def _reduce_377(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_378(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_379(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_380(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_381(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 382 omitted + +def _reduce_383(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_384(val, _values, result) + if val[1].empty? && val[0].size == 1 + result = [@builder.procarg0(val[0][0])] + else + result = val[0].concat(val[1]) + end + + result +end + +def _reduce_385(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_386(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_387(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_388(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_389(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_390(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 391 omitted + +def _reduce_392(val, _values, result) + result = @builder.args(nil, [], nil) + + result +end + +def _reduce_393(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_394(val, _values, result) + @max_numparam_stack.has_ordinary_params! + @current_arg_stack.set(nil) + result = @builder.args(val[0], val[1], val[2]) + + result +end + +def _reduce_395(val, _values, result) + @max_numparam_stack.has_ordinary_params! + @current_arg_stack.set(nil) + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_396(val, _values, result) + result = [] + + result +end + +def _reduce_397(val, _values, result) + result = val[2] + + result +end + +def _reduce_398(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_399(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_400(val, _values, result) + @static_env.declare val[0][0] + result = @builder.shadowarg(val[0]) + + result +end + +# reduce 401 omitted + +def _reduce_402(val, _values, result) + @static_env.extend_dynamic + @max_numparam_stack.push(static: false) + + result +end + +def _reduce_403(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_404(val, _values, result) + args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[1] + result = [ args, val[3] ] + + @max_numparam_stack.pop + @static_env.unextend + @lexer.cmdarg.pop + + result +end + +def _reduce_405(val, _values, result) + @max_numparam_stack.has_ordinary_params! + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_406(val, _values, result) + if val[0].any? + @max_numparam_stack.has_ordinary_params! + end + result = @builder.args(nil, val[0], nil) + + result +end + +def _reduce_407(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_408(val, _values, result) + result = [ val[0], val[2], val[3] ] + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_409(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_410(val, _values, result) + result = [ val[0], val[2], val[3] ] + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_411(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_412(val, _values, result) + result = [ val[0], *val[2], val[3] ] + @context.in_block = val[1].in_block + + result +end + +def _reduce_413(val, _values, result) + begin_t, block_args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, block_args, body, end_t) + + result +end + +def _reduce_414(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_415(val, _values, result) + lparen_t, args, rparen_t = val[3] + method_call = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_416(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_417(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.call_method(nil, nil, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_418(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_419(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_420(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2]) + + result +end + +def _reduce_421(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_422(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_423(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.keyword_cmd(:super, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_424(val, _values, result) + result = @builder.keyword_cmd(:zsuper, val[0]) + + result +end + +def _reduce_425(val, _values, result) + result = @builder.index(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_426(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_427(val, _values, result) + result = [ val[0], *val[2], val[3] ] + @context.in_block = val[1].in_block + + result +end + +def _reduce_428(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_429(val, _values, result) + result = [ val[0], *val[2], val[3] ] + @context.in_block = val[1].in_block + + result +end + +def _reduce_430(val, _values, result) + @static_env.extend_dynamic + @max_numparam_stack.push(static: false) + + result +end + +def _reduce_431(val, _values, result) + args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[1] + result = [ args, val[2] ] + + @max_numparam_stack.pop + @static_env.unextend + + result +end + +def _reduce_432(val, _values, result) + @static_env.extend_dynamic + @max_numparam_stack.push(static: false) + + result +end + +def _reduce_433(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_434(val, _values, result) + args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[2] + result = [ args, val[3] ] + + @max_numparam_stack.pop + @static_env.unextend + @lexer.cmdarg.pop + + result +end + +def _reduce_435(val, _values, result) + result = [ @builder.when(val[0], val[1], val[2], val[3]), + *val[4] ] + + result +end + +def _reduce_436(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 437 omitted + +def _reduce_438(val, _values, result) + @lexer.state = :expr_beg + @lexer.command_start = false + @pattern_variables.push + @pattern_hash_keys.push + + result = @context.in_kwarg + @context.in_kwarg = true + + result +end + +def _reduce_439(val, _values, result) + @pattern_hash_keys.pop + @pattern_variables.pop + @context.in_kwarg = val[1] + + result +end + +def _reduce_440(val, _values, result) + result = [ @builder.in_pattern(val[0], *val[2], val[3], val[5]), + *val[6] ] + + result +end + +def _reduce_441(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 442 omitted + +def _reduce_443(val, _values, result) + result = [ val[0], nil ] + + result +end + +def _reduce_444(val, _values, result) + result = [ val[0], @builder.if_guard(val[1], val[2]) ] + + result +end + +def _reduce_445(val, _values, result) + result = [ val[0], @builder.unless_guard(val[1], val[2]) ] + + result +end + +# reduce 446 omitted + +def _reduce_447(val, _values, result) + # array patterns that end with comma + # like 1, 2, + # must be emitted as `array_pattern_with_tail` + item = @builder.match_with_trailing_comma(val[0], val[1]) + result = @builder.array_pattern(nil, [ item ], nil) + + result +end + +def _reduce_448(val, _values, result) + result = @builder.array_pattern(nil, [val[0]].concat(val[2]), nil) + + result +end + +def _reduce_449(val, _values, result) + result = @builder.array_pattern(nil, val[0], nil) + + result +end + +def _reduce_450(val, _values, result) + result = @builder.hash_pattern(nil, val[0], nil) + + result +end + +# reduce 451 omitted + +def _reduce_452(val, _values, result) + result = @builder.match_as(val[0], val[1], val[2]) + + result +end + +# reduce 453 omitted + +def _reduce_454(val, _values, result) + result = @builder.match_alt(val[0], val[1], val[2]) + + result +end + +# reduce 455 omitted + +def _reduce_456(val, _values, result) + result = val[0] + @pattern_hash_keys.push + + result +end + +def _reduce_457(val, _values, result) + result = val[0] + @pattern_hash_keys.push + + result +end + +# reduce 458 omitted + +def _reduce_459(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.array_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_460(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.hash_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_461(val, _values, result) + pattern = @builder.array_pattern(val[1], nil, val[2]) + result = @builder.const_pattern(val[0], val[1], pattern, val[2]) + + result +end + +def _reduce_462(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.array_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_463(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.hash_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_464(val, _values, result) + pattern = @builder.array_pattern(val[1], nil, val[2]) + result = @builder.const_pattern(val[0], val[1], pattern, val[2]) + + result +end + +def _reduce_465(val, _values, result) + @pattern_hash_keys.push + + result +end + +def _reduce_466(val, _values, result) + @pattern_hash_keys.pop + result = @builder.array_pattern(val[0], val[2], val[3]) + + result +end + +def _reduce_467(val, _values, result) + result = @builder.array_pattern(val[0], [], val[1]) + + result +end + +def _reduce_468(val, _values, result) + @pattern_hash_keys.push + result = @context.in_kwarg + @context.in_kwarg = false + + result +end + +def _reduce_469(val, _values, result) + @pattern_hash_keys.pop + @context.in_kwarg = val[1] + result = @builder.hash_pattern(val[0], val[2], val[3]) + + result +end + +def _reduce_470(val, _values, result) + result = @builder.hash_pattern(val[0], [], val[1]) + + result +end + +def _reduce_471(val, _values, result) + @pattern_hash_keys.push + + result +end + +def _reduce_472(val, _values, result) + @pattern_hash_keys.pop + result = @builder.begin(val[0], val[2], val[3]) + + result +end + +def _reduce_473(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_474(val, _values, result) + result = val[0] + + result +end + +def _reduce_475(val, _values, result) + result = [ *val[0], val[1] ] + + result +end + +def _reduce_476(val, _values, result) + match_rest = @builder.match_rest(val[1], val[2]) + result = [ *val[0], match_rest ] + + result +end + +def _reduce_477(val, _values, result) + match_rest = @builder.match_rest(val[1], val[2]) + result = [ *val[0], match_rest, *val[4] ] + + result +end + +def _reduce_478(val, _values, result) + result = [ *val[0], @builder.match_rest(val[1]) ] + + result +end + +def _reduce_479(val, _values, result) + result = [ *val[0], @builder.match_rest(val[1]), *val[3] ] + + result +end + +# reduce 480 omitted + +def _reduce_481(val, _values, result) + # array patterns that end with comma + # like [1, 2,] + # must be emitted as `array_pattern_with_tail` + item = @builder.match_with_trailing_comma(val[0], val[1]) + result = [ item ] + + result +end + +def _reduce_482(val, _values, result) + # array patterns that end with comma + # like [1, 2,] + # must be emitted as `array_pattern_with_tail` + last_item = @builder.match_with_trailing_comma(val[1], val[2]) + result = [ *val[0], last_item ] + + result +end + +def _reduce_483(val, _values, result) + match_rest = @builder.match_rest(val[0], val[1]) + result = [ match_rest ] + + result +end + +def _reduce_484(val, _values, result) + match_rest = @builder.match_rest(val[0], val[1]) + result = [ match_rest, *val[3] ] + + result +end + +def _reduce_485(val, _values, result) + match_rest = @builder.match_rest(val[0]) + result = [ match_rest ] + + result +end + +def _reduce_486(val, _values, result) + match_rest = @builder.match_rest(val[0]) + result = [ match_rest, *val[2] ] + + result +end + +def _reduce_487(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_488(val, _values, result) + result = [ *val[0], val[2] ] + + result +end + +# reduce 489 omitted + +def _reduce_490(val, _values, result) + result = [ *val[0], *val[2] ] + + result +end + +def _reduce_491(val, _values, result) + result = val[0] + + result +end + +def _reduce_492(val, _values, result) + result = val[0] + + result +end + +def _reduce_493(val, _values, result) + result = val[0] + + result +end + +def _reduce_494(val, _values, result) + result = [ *val[0], *val[2] ] + + result +end + +def _reduce_495(val, _values, result) + result = [ *val[0], *val[2] ] + + result +end + +def _reduce_496(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_497(val, _values, result) + result = [ *val[0], val[2] ] + + result +end + +def _reduce_498(val, _values, result) + result = @builder.match_pair(*val[0], val[1]) + + result +end + +def _reduce_499(val, _values, result) + result = @builder.match_label(*val[0]) + + result +end + +def _reduce_500(val, _values, result) + result = [:label, val[0]] + + result +end + +def _reduce_501(val, _values, result) + result = [:quoted, [val[0], val[1], val[2]]] + + result +end + +def _reduce_502(val, _values, result) + result = [ @builder.match_rest(val[0], val[1]) ] + + result +end + +def _reduce_503(val, _values, result) + result = [ @builder.match_rest(val[0], nil) ] + + result +end + +def _reduce_504(val, _values, result) + result = [ @builder.match_nil_pattern(val[0], val[1]) ] + + result +end + +# reduce 505 omitted + +def _reduce_506(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_507(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_508(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], nil) + + result +end + +def _reduce_509(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], nil) + + result +end + +# reduce 510 omitted + +# reduce 511 omitted + +# reduce 512 omitted + +def _reduce_513(val, _values, result) + result = @builder.range_inclusive(nil, val[0], val[1]) + + result +end + +def _reduce_514(val, _values, result) + result = @builder.range_exclusive(nil, val[0], val[1]) + + result +end + +# reduce 515 omitted + +# reduce 516 omitted + +# reduce 517 omitted + +# reduce 518 omitted + +# reduce 519 omitted + +# reduce 520 omitted + +# reduce 521 omitted + +# reduce 522 omitted + +def _reduce_523(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_524(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_525(val, _values, result) + lambda_call = @builder.call_lambda(val[0]) + + args, (begin_t, body, end_t) = val[2] + result = @builder.block(lambda_call, + begin_t, args, body, end_t) + + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_526(val, _values, result) + result = @builder.assignable(@builder.match_var(val[0])) + + result +end + +def _reduce_527(val, _values, result) + name = val[1][0] + lvar = @builder.accessible(@builder.ident(val[1])) + + unless static_env.declared?(name) + diagnostic :error, :undefined_lvar, { :name => name }, val[1] + end + + result = @builder.pin(val[0], lvar) + + result +end + +def _reduce_528(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_529(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +def _reduce_530(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_531(val, _values, result) + assoc_t, exc_var = val[2] + + if val[1] + exc_list = @builder.array(nil, val[1], nil) + end + + result = [ @builder.rescue_body(val[0], + exc_list, assoc_t, exc_var, + val[3], val[4]), + *val[5] ] + + result +end + +def _reduce_532(val, _values, result) + result = [] + + result +end + +def _reduce_533(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 534 omitted + +# reduce 535 omitted + +def _reduce_536(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 537 omitted + +def _reduce_538(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 539 omitted + +# reduce 540 omitted + +# reduce 541 omitted + +def _reduce_542(val, _values, result) + result = @builder.string_compose(nil, val[0], nil) + + result +end + +def _reduce_543(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_544(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_545(val, _values, result) + string = @builder.string_compose(val[0], val[1], val[2]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_546(val, _values, result) + string = @builder.string(val[0]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_547(val, _values, result) + result = @builder.character(val[0]) + + result +end + +def _reduce_548(val, _values, result) + string = @builder.xstring_compose(val[0], val[1], val[2]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_549(val, _values, result) + opts = @builder.regexp_options(val[3]) + result = @builder.regexp_compose(val[0], val[1], val[2], opts) + + result +end + +def _reduce_550(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_551(val, _values, result) + result = [] + + result +end + +def _reduce_552(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_553(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_554(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_555(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_556(val, _values, result) + result = [] + + result +end + +def _reduce_557(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_558(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_559(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_560(val, _values, result) + result = [] + + result +end + +def _reduce_561(val, _values, result) + result = val[0] << @builder.string_internal(val[1]) + + result +end + +def _reduce_562(val, _values, result) + result = [] + + result +end + +def _reduce_563(val, _values, result) + result = val[0] << @builder.symbol_internal(val[1]) + + result +end + +def _reduce_564(val, _values, result) + result = [] + + result +end + +def _reduce_565(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_566(val, _values, result) + result = [] + + result +end + +def _reduce_567(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_568(val, _values, result) + result = [] + + result +end + +def _reduce_569(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_570(val, _values, result) + result = @builder.string_internal(val[0]) + + result +end + +def _reduce_571(val, _values, result) + result = val[1] + + result +end + +def _reduce_572(val, _values, result) + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + + result +end + +def _reduce_573(val, _values, result) + @lexer.cmdarg.pop + @lexer.cond.pop + + result = @builder.begin(val[0], val[2], val[3]) + + result +end + +def _reduce_574(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_575(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_576(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +# reduce 577 omitted + +# reduce 578 omitted + +# reduce 579 omitted + +def _reduce_580(val, _values, result) + @lexer.state = :expr_end + result = @builder.symbol(val[0]) + + result +end + +def _reduce_581(val, _values, result) + @lexer.state = :expr_end + result = @builder.symbol_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_582(val, _values, result) + result = val[0] + + result +end + +def _reduce_583(val, _values, result) + if @builder.respond_to? :negate + # AST builder interface compatibility + result = @builder.negate(val[0], val[1]) + else + result = @builder.unary_num(val[0], val[1]) + end + + result +end + +def _reduce_584(val, _values, result) + @lexer.state = :expr_end + result = @builder.integer(val[0]) + + result +end + +def _reduce_585(val, _values, result) + @lexer.state = :expr_end + result = @builder.float(val[0]) + + result +end + +def _reduce_586(val, _values, result) + @lexer.state = :expr_end + result = @builder.rational(val[0]) + + result +end + +def _reduce_587(val, _values, result) + @lexer.state = :expr_end + result = @builder.complex(val[0]) + + result +end + +def _reduce_588(val, _values, result) + result = @builder.ident(val[0]) + + result +end + +def _reduce_589(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_590(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_591(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_592(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +def _reduce_593(val, _values, result) + result = @builder.nil(val[0]) + + result +end + +def _reduce_594(val, _values, result) + result = @builder.self(val[0]) + + result +end + +def _reduce_595(val, _values, result) + result = @builder.true(val[0]) + + result +end + +def _reduce_596(val, _values, result) + result = @builder.false(val[0]) + + result +end + +def _reduce_597(val, _values, result) + result = @builder.__FILE__(val[0]) + + result +end + +def _reduce_598(val, _values, result) + result = @builder.__LINE__(val[0]) + + result +end + +def _reduce_599(val, _values, result) + result = @builder.__ENCODING__(val[0]) + + result +end + +def _reduce_600(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_601(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_602(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_603(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_604(val, _values, result) + result = @builder.nth_ref(val[0]) + + result +end + +def _reduce_605(val, _values, result) + result = @builder.back_ref(val[0]) + + result +end + +def _reduce_606(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_607(val, _values, result) + result = [ val[0], val[2] ] + + result +end + +def _reduce_608(val, _values, result) + result = nil + + result +end + +def _reduce_609(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + @lexer.state = :expr_value + + result +end + +def _reduce_610(val, _values, result) + args = [ *val[1], @builder.forward_arg(val[3]) ] + result = @builder.args(val[0], args, val[4]) + @static_env.declare_forward_args + + result +end + +def _reduce_611(val, _values, result) + result = @builder.forward_only_args(val[0], val[1], val[2]) + @static_env.declare_forward_args + + @lexer.state = :expr_value + + result +end + +def _reduce_612(val, _values, result) + result = @context.in_kwarg + @context.in_kwarg = true + + result +end + +def _reduce_613(val, _values, result) + @context.in_kwarg = val[0] + result = @builder.args(nil, val[1], nil) + + result +end + +def _reduce_614(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_615(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_616(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_617(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_618(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_619(val, _values, result) + result = val[1] + + result +end + +def _reduce_620(val, _values, result) + result = [] + + result +end + +def _reduce_621(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_622(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_623(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_624(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_625(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_626(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_627(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_628(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_629(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_630(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_631(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_632(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_633(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_634(val, _values, result) + result = val[0] + + result +end + +def _reduce_635(val, _values, result) + result = [] + + result +end + +def _reduce_636(val, _values, result) + result = val[0] + + result +end + +def _reduce_637(val, _values, result) + diagnostic :error, :argument_const, nil, val[0] + + result +end + +def _reduce_638(val, _values, result) + diagnostic :error, :argument_ivar, nil, val[0] + + result +end + +def _reduce_639(val, _values, result) + diagnostic :error, :argument_gvar, nil, val[0] + + result +end + +def _reduce_640(val, _values, result) + diagnostic :error, :argument_cvar, nil, val[0] + + result +end + +# reduce 641 omitted + +def _reduce_642(val, _values, result) + @static_env.declare val[0][0] + + @max_numparam_stack.has_ordinary_params! + + result = val[0] + + result +end + +def _reduce_643(val, _values, result) + @current_arg_stack.set(val[0][0]) + result = val[0] + + result +end + +def _reduce_644(val, _values, result) + @current_arg_stack.set(0) + result = @builder.arg(val[0]) + + result +end + +def _reduce_645(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_646(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_647(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_648(val, _values, result) + check_kwarg_name(val[0]) + + @static_env.declare val[0][0] + + @max_numparam_stack.has_ordinary_params! + + @current_arg_stack.set(val[0][0]) + + result = val[0] + + result +end + +def _reduce_649(val, _values, result) + @current_arg_stack.set(nil) + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_650(val, _values, result) + @current_arg_stack.set(nil) + result = @builder.kwarg(val[0]) + + result +end + +def _reduce_651(val, _values, result) + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_652(val, _values, result) + result = @builder.kwarg(val[0]) + + result +end + +def _reduce_653(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_654(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_655(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_656(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 657 omitted + +# reduce 658 omitted + +def _reduce_659(val, _values, result) + result = [ @builder.kwnilarg(val[0], val[1]) ] + + result +end + +def _reduce_660(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.kwrestarg(val[0], val[1]) ] + + result +end + +def _reduce_661(val, _values, result) + result = [ @builder.kwrestarg(val[0]) ] + + result +end + +def _reduce_662(val, _values, result) + @current_arg_stack.set(0) + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_663(val, _values, result) + @current_arg_stack.set(0) + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_664(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_665(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_666(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_667(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 668 omitted + +# reduce 669 omitted + +def _reduce_670(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_671(val, _values, result) + result = [ @builder.restarg(val[0]) ] + + result +end + +# reduce 672 omitted + +# reduce 673 omitted + +def _reduce_674(val, _values, result) + @static_env.declare val[1][0] + + result = @builder.blockarg(val[0], val[1]) + + result +end + +def _reduce_675(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_676(val, _values, result) + result = [] + + result +end + +# reduce 677 omitted + +def _reduce_678(val, _values, result) + result = val[1] + + result +end + +def _reduce_679(val, _values, result) + result = [] + + result +end + +# reduce 680 omitted + +def _reduce_681(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_682(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_683(val, _values, result) + result = @builder.pair(val[0], val[1], val[2]) + + result +end + +def _reduce_684(val, _values, result) + result = @builder.pair_keyword(val[0], val[1]) + + result +end + +def _reduce_685(val, _values, result) + result = @builder.pair_quoted(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_686(val, _values, result) + result = @builder.kwsplat(val[0], val[1]) + + result +end + +# reduce 687 omitted + +# reduce 688 omitted + +# reduce 689 omitted + +# reduce 690 omitted + +# reduce 691 omitted + +# reduce 692 omitted + +# reduce 693 omitted + +# reduce 694 omitted + +# reduce 695 omitted + +# reduce 696 omitted + +# reduce 697 omitted + +# reduce 698 omitted + +def _reduce_699(val, _values, result) + result = [:dot, val[0][1]] + + result +end + +def _reduce_700(val, _values, result) + result = [:anddot, val[0][1]] + + result +end + +# reduce 701 omitted + +# reduce 702 omitted + +# reduce 703 omitted + +# reduce 704 omitted + +def _reduce_705(val, _values, result) + result = val[1] + + result +end + +def _reduce_706(val, _values, result) + result = val[1] + + result +end + +def _reduce_707(val, _values, result) + result = val[1] + + result +end + +# reduce 708 omitted + +# reduce 709 omitted + +# reduce 710 omitted + +def _reduce_711(val, _values, result) + yyerrok + + result +end + +# reduce 712 omitted + +# reduce 713 omitted + +# reduce 714 omitted + +def _reduce_715(val, _values, result) + result = nil + + result +end + +def _reduce_none(val, _values, result) + val[0] +end + + end # class Ruby27 +end # module Parser diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby30.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby30.rb new file mode 100644 index 00000000..fbbec28e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby30.rb @@ -0,0 +1,12244 @@ +# -*- encoding:utf-8; warn-indent:false; frozen_string_literal: true -*- +# +# DO NOT MODIFY!!!! +# This file is automatically generated by Racc 1.8.1 +# from Racc grammar file "ruby30.y". +# + +require 'racc/parser.rb' + + +require_relative '../parser' + +module Parser + class Ruby30 < Parser::Base + + + def version + 30 + end + + def default_encoding + Encoding::UTF_8 + end + + def endless_method_name(name_t) + if !%w[=== == != <= >=].include?(name_t[0]) && name_t[0].end_with?('=') + diagnostic :error, :endless_setter, nil, name_t + end + end + + def local_push + @static_env.extend_static + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + @max_numparam_stack.push(static: true) + end + + def local_pop + @static_env.unextend + @lexer.cmdarg.pop + @lexer.cond.pop + @max_numparam_stack.pop + end + + def try_declare_numparam(node) + name = node.children[0] + + if name =~ /\A_[1-9]\z/ && !static_env.declared?(name) && @context.in_dynamic_block? + # definitely an implicit param + location = node.loc.expression + + if max_numparam_stack.has_ordinary_params? + diagnostic :error, :ordinary_param_defined, nil, [nil, location] + end + + raw_max_numparam_stack = max_numparam_stack.stack.dup + + # ignore current block scope + raw_max_numparam_stack.pop + + raw_max_numparam_stack.reverse_each do |outer_scope| + if outer_scope[:static] + # found an outer scope that can't have numparams + # like def/class/etc + break + else + outer_scope_has_numparams = outer_scope[:value] > 0 + + if outer_scope_has_numparams + diagnostic :error, :numparam_used_in_outer_scope, nil, [nil, location] + else + # for now it's ok, but an outer scope can also be a block + # like proc { _1; proc { proc { proc { _2 }} }} + # with numparams, so we need to continue + end + end + end + + static_env.declare(name) + max_numparam_stack.register(name[1].to_i) + + true + else + false + end + end +##### State transition tables begin ### + +racc_action_table = [ + -599, 221, 222, 221, 222, 366, -112, -599, -599, -599, + 870, 617, -599, -599, -599, 227, -599, 301, 231, 1083, + 126, -716, 226, 617, -599, 125, -599, -599, -599, 221, + 222, 224, 788, 658, -113, -120, -599, -599, 617, -599, + -599, -599, -599, -599, 617, 617, 617, -112, -113, -716, + 789, -119, 920, 232, -120, 624, 660, 232, 3, 232, + 301, -728, 810, 810, -115, -117, -599, -599, -599, -599, + -599, -599, -599, -599, -599, -599, -599, -599, -599, -599, + 228, 296, -599, -599, -599, 122, -599, -599, 805, 232, + -599, 965, -114, -599, -599, 232, -599, 232, -599, 657, + -599, 1084, -599, -599, 300, -599, -599, -599, -599, -599, + -119, -599, -602, -599, -115, -103, 301, 221, 222, -602, + -602, -602, 659, 232, -602, -602, -602, -599, -602, 126, + -599, -599, -599, -599, 125, -599, -602, -599, -602, -602, + -602, 126, -599, -104, -111, -599, 125, 300, -602, -602, + -117, -602, -602, -602, -602, -602, 126, -116, -114, 954, + -110, 125, 126, 126, 126, -112, -113, 125, 125, 125, + -112, -113, -120, -106, -108, -116, -118, -120, -602, -602, + -602, -602, -602, -602, -602, -602, -602, -602, -602, -602, + -602, -602, 126, -118, -602, -602, -602, 125, -602, -602, + 964, -105, -602, 300, 126, -602, -602, -716, -602, 125, + -602, 126, -602, 645, -602, -602, 125, -602, -602, -602, + -602, -602, -314, -602, 232, -602, 870, -613, -119, -314, + -314, -314, -115, -119, -703, -314, -314, -115, -314, -602, + -703, -704, -602, -602, -602, -602, -314, -602, 227, -602, + 301, 366, 135, 645, -602, 294, 870, -602, -314, -314, + -106, -314, -314, -314, -314, -314, 104, 105, -117, 920, + -704, 624, -501, -117, -108, -116, -114, 647, 646, -614, + -116, -114, 104, 105, -107, -109, -112, 836, -314, -314, + -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, + -314, -314, 1124, 227, -314, -314, -314, -728, 684, -314, + 294, -118, -314, 228, 296, -314, -118, 647, 646, 643, + -314, 218, -314, 645, -314, -314, -106, -314, -314, -314, + -314, -314, 479, -314, -707, -314, 1078, 300, -113, 229, + -108, -707, -707, -707, 106, 107, 126, -707, -707, -314, + -707, 125, -314, -314, 1077, -109, 219, -314, -707, -707, + 106, 107, -105, 555, -314, 220, -106, -118, 228, -106, + -707, -707, 865, -707, -707, -707, -707, -707, -98, -599, + -108, -106, 609, -108, -107, 608, -599, 647, 646, 645, + -84, -120, 866, 645, 126, -108, 223, 838, -120, 125, + -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, + -707, -707, -707, -707, 290, 986, -707, -707, -707, -349, + 685, -707, -119, 351, -707, 590, -349, -707, -105, 679, + 645, -115, -707, 680, -707, -349, -707, -707, 645, -707, + -707, -707, -707, -707, -599, -707, -707, -707, 630, -703, + -107, -117, 631, 647, 646, 643, 645, 647, 646, 643, + 229, -707, 645, 591, -707, -707, -700, -107, -105, -707, + 745, -105, 645, -707, 1137, 1004, -707, 221, 222, -116, + -707, -707, -707, -105, -349, -707, -707, -707, -115, -707, + -107, 126, -117, -107, 647, 646, 125, -707, -707, -707, + -707, -707, 647, 646, 648, -107, -701, -111, 352, -707, + -707, 1137, -707, -707, -707, -707, -707, 232, -599, -120, + 647, 646, 650, 645, 876, -599, 647, 646, 652, 872, + -700, 974, 609, 873, -599, 611, 647, 646, 656, -707, + -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, + -707, -707, -707, -700, 852, -707, -707, -707, -602, 867, + -707, 221, 222, -707, 630, -602, -707, -707, 895, -707, + -701, -707, 429, -707, -602, -707, -707, 478, -707, -707, + -707, -707, -707, -599, -707, -707, -707, 647, 646, 661, + -114, 227, -602, -701, -609, -608, 271, 272, 476, -602, + -707, -609, -608, -707, -707, -707, -707, 477, -707, -610, + -707, -613, -314, -114, 480, -707, -610, -614, -116, -314, + -314, -314, 481, -602, -314, -314, -314, -607, -314, 890, + 891, 231, 270, 269, -607, -604, -314, 513, -314, -314, + -314, 426, -604, 598, 597, 525, 428, 427, -314, -314, + 555, -314, -314, -314, -314, -314, 228, -602, -103, -609, + -608, -605, -606, 630, -104, 949, 920, 895, -605, -606, + -112, 527, 609, 529, -610, 611, -113, 135, -314, -314, + -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, + -314, -314, -607, 986, -314, -314, -314, -110, 868, -314, + -604, 679, -314, 590, 609, -314, -314, 611, -314, -119, + -314, -83, -314, 232, -314, -314, 1174, -314, -314, -314, + -314, -314, -314, -314, 232, -314, -605, -606, 90, -314, + -314, -314, 1122, 1123, 540, -314, -314, 541, -314, -314, + 91, 591, -314, -314, -314, -314, -314, -314, -106, -314, + 92, 949, 920, 1004, -314, 680, 548, -118, -314, -314, + -115, -314, -314, -314, -314, -314, 305, 232, 366, 366, + 582, -611, 579, 578, 577, 587, 580, 296, -611, 852, + 582, 552, 579, 578, 577, 590, 580, -611, -314, -314, + -314, -314, -314, -314, -314, -314, -314, -314, -314, -314, + -314, -314, -108, 558, -314, -314, -314, 585, 684, -314, + 254, 562, -314, -620, -117, -314, 595, 594, 598, 597, + -314, 602, -314, 591, -314, -314, -105, -314, -314, -314, + -314, -314, 232, -314, -707, -314, -611, 612, -114, 613, + 529, -707, -707, -707, 624, 418, 628, -707, -707, -314, + -707, 629, -314, -314, 637, -314, 662, -314, -707, -707, + 665, 666, -287, 576, -314, 668, 669, -118, 673, 232, + -707, -707, 677, -707, -707, -707, -707, -707, 678, 296, + 689, 254, 582, -612, 579, 578, 577, 587, 580, 582, + -612, 579, 578, 577, 254, 580, 254, 590, 254, -612, + -707, -707, -707, -707, -707, -707, -707, -707, -707, -707, + -707, -707, -707, -707, 232, 733, -707, -707, -707, 585, + 685, -707, 232, 232, -707, 232, 781, -707, 595, 594, + 598, 597, -707, -98, -707, 591, -707, -707, 748, -707, + -707, -707, -707, -707, 587, -707, -707, -707, -612, 232, + 227, 561, 759, 765, 590, -305, 227, 547, 766, 232, + 768, -707, -305, 557, -707, -707, 545, -707, 232, -707, + 227, -305, 477, 771, 774, 576, -707, 627, 775, -116, + 7, 81, 82, 83, 11, 65, 625, 598, 597, 71, + 72, 777, 591, 779, 75, -707, 73, 74, 76, 33, + 34, 79, 80, 129, 130, 131, 132, 133, 84, 31, + 30, 114, 113, 115, 116, 228, 790, 21, 791, 793, + -305, 228, 795, 10, 51, 9, 12, 118, 117, 119, + 108, 64, 110, 109, 111, 228, 112, 120, 121, 227, + 104, 105, 47, 48, 46, 227, 633, -707, 796, -315, + 232, 798, 672, 801, -707, 635, -315, 806, 807, -703, + 811, 670, 835, -707, 43, -315, 839, 36, 840, -288, + 66, 67, -315, 853, 68, 513, 38, 513, 232, -315, + 50, 870, -707, 871, 254, 894, 830, 831, -315, 22, + 832, 120, 121, 870, 102, 90, 93, 94, 897, 95, + 97, 96, 98, 899, 228, 290, 905, 91, 101, 907, + 228, 909, -707, 527, -315, 85, 251, 92, 106, 107, + 253, 252, 44, 45, 323, 81, 82, 83, 11, 65, + 529, 759, 232, 71, 72, 296, 296, -315, 75, 759, + 73, 74, 76, 33, 34, 79, 80, 246, 254, 920, + 941, 942, 84, 31, 30, 114, 113, 115, 116, 232, + 1133, 21, 579, 578, 577, 920, 580, 10, 51, 325, + 12, 118, 117, 119, 108, 64, 110, 109, 111, 951, + 112, 120, 121, 952, 104, 105, 47, 48, 46, 254, + 258, 259, 260, 261, 271, 272, 266, 267, 262, 263, + -314, 247, 248, 232, 232, 264, 265, -314, 43, 962, + 245, 327, -704, 232, 66, 67, -314, -289, 68, 232, + 38, 251, 973, 257, 50, 253, 252, 719, 249, 250, + 270, 269, 255, 22, 256, 232, 232, 1000, 102, 90, + 93, 94, 227, 95, 97, 96, 98, 1001, 1002, 1152, + 1005, 91, 101, 907, 268, 1011, 232, 759, 635, 85, + 1029, 92, 106, 107, -287, -314, 44, 45, 7, 81, + 82, 83, 11, 65, 1033, 232, 1036, 71, 72, 1038, + 774, 789, 75, 1041, 73, 74, 76, 33, 34, 79, + 80, 129, 130, 131, 132, 133, 84, 31, 30, 114, + 113, 115, 116, 1043, 1043, 21, 232, 228, 1051, 1053, + 674, 10, 51, 9, 12, 118, 117, 119, 108, 64, + 110, 109, 111, 1062, 112, 120, 121, 1063, 104, 105, + 47, 48, 46, 254, 258, 259, 260, 261, 271, 272, + 266, 267, 262, 263, -314, 247, 248, 1068, 1069, 264, + 265, -314, 43, 1070, -290, 36, -704, 232, 66, 67, + -314, 232, 68, 232, 38, 251, 1074, 257, 50, 253, + 252, 232, 249, 250, 270, 269, 255, 22, 256, 232, + 232, 870, 102, 90, 93, 94, 227, 95, 97, 96, + 98, 1082, 232, 1157, 1091, 91, 101, 774, 268, 1094, + -260, 1097, 1155, 85, 1099, 92, 106, 107, 1101, -314, + 44, 45, 323, 81, 82, 83, 11, 65, 232, 1103, + 1118, 71, 72, 1119, 1128, 870, 75, 1138, 73, 74, + 76, 33, 34, 79, 80, 129, 130, 131, 132, 133, + 84, 31, 30, 114, 113, 115, 116, 1140, 1150, 21, + 1153, 228, 1158, 1159, 674, 10, 51, 325, 12, 118, + 117, 119, 108, 64, 110, 109, 111, 1043, 112, 120, + 121, 1043, 104, 105, 47, 48, 46, 254, 258, 259, + 260, 261, 271, 272, 266, 267, 262, 263, 227, 247, + 248, 1043, 1171, 264, 265, 1152, 43, 1172, 1176, 36, + 587, 774, 66, 67, 635, 1180, 68, 1182, 38, 251, + 590, 257, 50, 253, 252, 1184, 249, 250, 270, 269, + 255, 22, 256, 1186, 1186, 765, 102, 90, 93, 94, + 1119, 95, 97, 96, 98, 1200, 1176, -704, -703, 91, + 101, 232, 268, 598, 597, 1043, 1212, 85, 591, 92, + 106, 107, 1186, 228, 44, 45, 323, 81, 82, 83, + 11, 65, 1186, 1186, 1176, 71, 72, 1186, nil, nil, + 75, nil, 73, 74, 76, 33, 34, 79, 80, 129, + 130, 131, 132, 133, 84, 31, 30, 114, 113, 115, + 116, nil, nil, 21, nil, nil, nil, nil, 917, 10, + 51, 325, 12, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 47, 48, + 46, 254, 258, 259, 260, 261, 271, 272, 266, 267, + 262, 263, nil, 247, 248, nil, nil, 264, 265, nil, + 43, nil, nil, 36, nil, nil, 66, 67, nil, nil, + 68, nil, 38, 251, nil, 257, 50, 253, 252, nil, + 249, 250, 270, 269, 255, 22, 256, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, 268, nil, nil, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 44, 45, + 323, 81, 82, 83, 11, 65, nil, nil, nil, 71, + 72, nil, nil, nil, 75, nil, 73, 74, 76, 33, + 34, 79, 80, nil, nil, nil, nil, nil, 84, 31, + 30, 114, 113, 115, 116, nil, nil, 21, nil, nil, + nil, nil, 945, 10, 51, 325, 12, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 47, 48, 46, 254, 258, 259, 260, 261, + 271, 272, 266, 267, 262, 263, nil, 247, 248, nil, + nil, 264, 265, nil, 43, nil, nil, 327, nil, nil, + 66, 67, nil, nil, 68, nil, 38, 251, nil, 257, + 50, 253, 252, nil, 249, 250, 270, 269, 255, 22, + 256, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + 268, nil, nil, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 44, 45, 323, 81, 82, 83, 11, 65, + nil, nil, nil, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 33, 34, 79, 80, nil, nil, nil, + nil, nil, 84, 31, 30, 114, 113, 115, 116, nil, + 1133, 21, 579, 578, 577, nil, 580, 10, 51, 325, + 12, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 47, 48, 46, 254, + 258, 259, 260, 261, 271, 272, 266, 267, 262, 263, + nil, 247, 248, nil, nil, 264, 265, nil, 43, nil, + nil, 327, nil, nil, 66, 67, nil, nil, 68, nil, + 38, 251, nil, 257, 50, 253, 252, nil, 249, 250, + 270, 269, 255, 22, 256, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, 268, nil, nil, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 44, 45, 323, 81, + 82, 83, 11, 65, nil, nil, nil, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 33, 34, 79, + 80, nil, nil, nil, nil, nil, 84, 31, 30, 114, + 113, 115, 116, nil, nil, 21, nil, nil, nil, nil, + nil, 10, 51, 325, 12, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 47, 48, 46, 254, 258, 259, 260, 261, 271, 272, + 266, 267, 262, 263, nil, 247, 248, nil, nil, 264, + 265, nil, 43, nil, nil, 36, nil, nil, 66, 67, + nil, nil, 68, nil, 38, 251, nil, 257, 50, 253, + 252, nil, 249, 250, 270, 269, 255, 22, 256, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, 232, 268, nil, + nil, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 44, 45, 323, 81, 82, 83, 11, 65, nil, nil, + nil, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 33, 34, 79, 80, nil, nil, nil, nil, nil, + 84, 31, 30, 114, 113, 115, 116, nil, nil, 21, + nil, nil, nil, nil, nil, 10, 51, 325, 12, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 47, 48, 46, 254, 258, 259, + 260, 261, 271, 272, 266, 267, 262, 263, nil, 247, + 248, nil, nil, 264, 265, nil, 43, nil, nil, 36, + nil, nil, 66, 67, nil, nil, 68, nil, 38, 251, + nil, 257, 50, 253, 252, nil, 249, 250, 270, 269, + 255, 22, 256, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, 268, nil, nil, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 44, 45, 323, 81, 82, 83, + 11, 65, nil, nil, nil, 71, 72, nil, nil, nil, + 75, nil, 73, 74, 76, 33, 34, 79, 80, nil, + nil, nil, nil, nil, 84, 31, 30, 114, 113, 115, + 116, nil, nil, 21, nil, nil, nil, nil, nil, 10, + 51, 325, 12, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 47, 48, + 46, 254, 258, 259, 260, 261, 271, 272, 266, 267, + 262, 263, nil, 247, 248, nil, nil, 264, 265, nil, + 43, nil, nil, 36, nil, nil, 66, 67, nil, nil, + 68, nil, 38, 251, nil, 257, 50, 253, 252, nil, + 249, 250, 270, 269, 255, 22, 256, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, 268, nil, nil, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 44, 45, + 323, 81, 82, 83, 11, 65, nil, nil, nil, 71, + 72, nil, nil, nil, 75, nil, 73, 74, 76, 33, + 34, 79, 80, nil, nil, nil, nil, nil, 84, 31, + 30, 114, 113, 115, 116, nil, nil, 21, nil, nil, + nil, nil, nil, 10, 51, 325, 12, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 47, 48, 46, 254, 258, 259, 260, 261, + 271, 272, 266, 267, 262, 263, nil, 247, 248, nil, + nil, 264, 265, nil, 43, nil, nil, 36, nil, nil, + 66, 67, nil, nil, 68, nil, 38, 251, nil, 257, + 50, 253, 252, nil, 249, 250, 270, 269, 255, 22, + 256, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + 268, nil, nil, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 44, 45, 323, 81, 82, 83, 11, 65, + nil, nil, nil, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 33, 34, 79, 80, nil, nil, nil, + nil, nil, 84, 31, 30, 114, 113, 115, 116, nil, + nil, 21, nil, nil, nil, nil, nil, 10, 51, 325, + 12, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 47, 48, 46, 254, + 258, 259, 260, 261, 271, 272, 266, 267, 262, 263, + nil, 247, 248, nil, nil, 264, 265, nil, 43, nil, + nil, 36, nil, nil, 66, 67, nil, nil, 68, nil, + 38, 251, nil, 257, 50, 253, 252, nil, 249, 250, + 270, 269, 255, 22, 256, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, 268, nil, nil, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 44, 45, 323, 81, + 82, 83, 11, 65, nil, nil, nil, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 33, 34, 79, + 80, nil, nil, nil, nil, nil, 84, 31, 30, 114, + 113, 115, 116, nil, nil, 21, nil, nil, nil, nil, + nil, 10, 51, 325, 12, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 47, 48, 46, 254, 258, 259, 260, 261, 271, 272, + 266, 267, 262, 263, nil, 247, 248, nil, nil, 264, + 265, nil, 43, nil, nil, 36, nil, nil, 66, 67, + nil, nil, 68, nil, 38, 251, nil, 257, 50, 253, + 252, nil, 249, 250, 270, 269, 255, 22, 256, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, 268, nil, + nil, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 44, 45, 323, 81, 82, 83, 11, 65, nil, nil, + nil, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 33, 34, 79, 80, nil, nil, nil, nil, nil, + 84, 31, 30, 114, 113, 115, 116, nil, 582, 21, + 579, 578, 577, nil, 580, 10, 51, 325, 12, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 47, 48, 46, 582, nil, 579, + 578, 577, nil, 580, nil, 781, nil, nil, 254, nil, + nil, nil, nil, nil, 785, nil, 43, nil, nil, 36, + nil, nil, 66, 67, nil, nil, 68, 582, 38, 579, + 578, 577, 50, 580, 781, nil, nil, nil, nil, nil, + 251, 22, nil, 785, 253, 252, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 781, nil, nil, 85, nil, 92, + 106, 107, nil, 785, 44, 45, 323, 81, 82, 83, + 11, 65, nil, nil, nil, 71, 72, nil, nil, nil, + 75, nil, 73, 74, 76, 33, 34, 79, 80, nil, + nil, nil, nil, nil, 84, 31, 30, 114, 113, 115, + 116, nil, nil, 21, nil, nil, nil, nil, nil, 10, + 51, 325, 12, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 47, 48, + 46, 254, 258, 259, 260, 261, 271, 272, 266, 267, + 262, 263, nil, -729, -729, nil, nil, 264, 265, nil, + 43, nil, nil, 36, nil, nil, 66, 67, nil, 254, + 68, nil, 38, 251, nil, 257, 50, 253, 252, nil, + 249, 250, 270, 269, 255, 22, 256, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, 251, nil, 91, 101, 253, 252, nil, 249, 250, + nil, 85, nil, 92, 106, 107, nil, nil, 44, 45, + 323, 81, 82, 83, 11, 65, nil, nil, nil, 71, + 72, nil, nil, nil, 75, nil, 73, 74, 76, 33, + 34, 79, 80, nil, nil, nil, nil, nil, 84, 31, + 30, 114, 113, 115, 116, nil, nil, 21, nil, nil, + nil, nil, nil, 10, 51, 325, 12, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 47, 48, 46, 254, 258, 259, 260, 261, + 271, 272, 266, 267, 262, 263, nil, -729, -729, nil, + nil, 264, 265, nil, 43, nil, nil, 36, nil, nil, + 66, 67, nil, 254, 68, nil, 38, 251, nil, 257, + 50, 253, 252, nil, 249, 250, 270, 269, 255, 22, + 256, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, 251, nil, 91, 101, 253, + 252, nil, 249, 250, nil, 85, nil, 92, 106, 107, + nil, nil, 44, 45, 323, 81, 82, 83, 11, 65, + nil, nil, nil, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 33, 34, 79, 80, nil, nil, nil, + nil, nil, 84, 31, 30, 114, 113, 115, 116, nil, + nil, 21, nil, nil, nil, nil, nil, 10, 51, 325, + 12, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 47, 48, 46, 254, + 258, 259, 260, 261, 271, 272, 266, 267, 262, 263, + nil, -729, -729, nil, nil, 264, 265, nil, 43, nil, + nil, 36, nil, nil, 66, 67, nil, nil, 68, nil, + 38, 251, nil, 257, 50, 253, 252, nil, 249, 250, + 270, 269, 255, 22, 256, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, 582, nil, 579, 578, 577, 85, + 580, 92, 106, 107, nil, nil, 44, 45, 323, 81, + 82, 83, 11, 65, nil, nil, nil, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 33, 34, 79, + 80, 781, nil, nil, nil, nil, 84, 31, 30, 114, + 113, 115, 116, nil, nil, 21, nil, nil, nil, nil, + nil, 10, 51, 325, 12, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 47, 48, 46, 254, 258, 259, 260, 261, 271, 272, + 266, 267, 262, 263, nil, -729, -729, nil, nil, 264, + 265, nil, 43, nil, nil, 36, nil, nil, 66, 67, + nil, nil, 68, nil, 38, 251, nil, 257, 50, 253, + 252, nil, 249, 250, 270, 269, 255, 22, 256, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, 582, nil, + 579, 578, 577, 85, 580, 92, 106, 107, nil, nil, + 44, 45, 323, 81, 82, 83, 11, 65, nil, nil, + nil, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 33, 34, 79, 80, 781, nil, nil, nil, nil, + 84, 31, 30, 114, 113, 115, 116, nil, nil, 21, + nil, nil, nil, nil, nil, 10, 51, 325, 12, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 47, 48, 46, 254, -729, -729, + -729, -729, 271, 272, nil, nil, -729, -729, nil, nil, + nil, nil, nil, 264, 265, nil, 43, nil, nil, 36, + nil, nil, 66, 67, nil, nil, 68, nil, 38, 251, + nil, 257, 50, 253, 252, nil, 249, 250, 270, 269, + 255, 22, 256, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, nil, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 44, 45, 323, 81, 82, 83, + 11, 65, nil, nil, nil, 71, 72, nil, nil, nil, + 75, nil, 73, 74, 76, 33, 34, 79, 80, nil, + nil, nil, nil, nil, 84, 31, 30, 114, 113, 115, + 116, nil, nil, 21, nil, nil, nil, nil, nil, 10, + 51, 325, 12, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 47, 48, + 46, 254, -729, -729, -729, -729, 271, 272, nil, nil, + -729, -729, nil, nil, nil, nil, nil, 264, 265, nil, + 43, nil, nil, 36, nil, nil, 66, 67, nil, nil, + 68, nil, 38, 251, nil, 257, 50, 253, 252, nil, + 249, 250, 270, 269, 255, 22, 256, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, nil, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 44, 45, + 323, 81, 82, 83, 11, 65, nil, nil, nil, 71, + 72, nil, nil, nil, 75, nil, 73, 74, 76, 33, + 34, 79, 80, nil, nil, nil, nil, nil, 84, 31, + 30, 114, 113, 115, 116, nil, nil, 21, nil, nil, + nil, nil, nil, 10, 51, 325, 12, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 47, 48, 46, 254, -729, -729, -729, -729, + 271, 272, nil, nil, -729, -729, nil, nil, nil, nil, + nil, 264, 265, nil, 43, nil, nil, 36, nil, nil, + 66, 67, nil, nil, 68, nil, 38, 251, nil, 257, + 50, 253, 252, nil, 249, 250, 270, 269, 255, 22, + 256, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, nil, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 44, 45, 323, 81, 82, 83, 11, 65, + nil, nil, nil, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 33, 34, 79, 80, nil, nil, nil, + nil, nil, 84, 31, 30, 114, 113, 115, 116, nil, + nil, 21, nil, nil, nil, nil, nil, 10, 51, 325, + 12, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 47, 48, 46, 254, + -729, -729, -729, -729, 271, 272, nil, nil, -729, -729, + nil, nil, nil, nil, nil, 264, 265, nil, 43, nil, + nil, 36, nil, nil, 66, 67, nil, nil, 68, nil, + 38, 251, nil, 257, 50, 253, 252, nil, 249, 250, + 270, 269, 255, 22, 256, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, nil, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 44, 45, 323, 81, + 82, 83, 11, 65, nil, nil, nil, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 33, 34, 79, + 80, nil, nil, nil, nil, nil, 84, 31, 30, 114, + 113, 115, 116, nil, nil, 21, nil, nil, nil, nil, + nil, 10, 51, 325, 12, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 47, 48, 46, 254, -729, -729, -729, -729, 271, 272, + nil, nil, -729, -729, nil, nil, nil, nil, nil, 264, + 265, nil, 43, nil, nil, 36, nil, nil, 66, 67, + nil, nil, 68, nil, 38, 251, nil, 257, 50, 253, + 252, nil, 249, 250, 270, 269, 255, 22, 256, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + nil, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 44, 45, 323, 81, 82, 83, 11, 65, nil, nil, + nil, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 33, 34, 79, 80, nil, nil, nil, nil, nil, + 84, 31, 30, 114, 113, 115, 116, nil, nil, 21, + nil, nil, nil, nil, nil, 10, 51, 325, 12, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 47, 48, 46, 254, -729, -729, + -729, -729, 271, 272, nil, nil, -729, -729, nil, nil, + nil, nil, nil, 264, 265, nil, 43, nil, nil, 36, + nil, nil, 66, 67, nil, nil, 68, nil, 38, 251, + nil, 257, 50, 253, 252, nil, 249, 250, 270, 269, + 255, 22, 256, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, nil, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 44, 45, 323, 81, 82, 83, + 11, 65, nil, nil, nil, 71, 72, nil, nil, nil, + 75, nil, 73, 74, 76, 33, 34, 79, 80, nil, + nil, nil, nil, nil, 84, 31, 30, 114, 113, 115, + 116, nil, nil, 21, nil, nil, nil, nil, nil, 10, + 51, 325, 12, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 47, 48, + 46, 254, 258, 259, 260, 261, 271, 272, nil, nil, + 262, 263, nil, nil, nil, nil, nil, 264, 265, nil, + 43, nil, nil, 36, nil, nil, 66, 67, nil, nil, + 68, nil, 38, 251, nil, 257, 50, 253, 252, nil, + 249, 250, 270, 269, 255, 22, 256, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, nil, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 44, 45, + 323, 81, 82, 83, 11, 65, nil, nil, nil, 71, + 72, nil, nil, nil, 75, nil, 73, 74, 76, 33, + 34, 79, 80, nil, nil, nil, nil, nil, 84, 31, + 30, 114, 113, 115, 116, nil, nil, 21, nil, nil, + nil, nil, nil, 10, 51, 325, 12, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 47, 48, 46, 254, 258, 259, 260, 261, + 271, 272, 266, nil, 262, 263, nil, nil, nil, nil, + nil, 264, 265, nil, 43, nil, nil, 36, nil, nil, + 66, 67, nil, nil, 68, nil, 38, 251, nil, 257, + 50, 253, 252, nil, 249, 250, 270, 269, 255, 22, + 256, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, nil, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 44, 45, 323, 81, 82, 83, 11, 65, + nil, nil, nil, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 33, 34, 79, 80, nil, nil, nil, + nil, nil, 84, 31, 30, 114, 113, 115, 116, nil, + nil, 21, nil, nil, nil, nil, nil, 10, 51, 325, + 12, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 47, 48, 46, 254, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 264, 265, nil, 43, nil, + nil, 36, nil, nil, 66, 67, nil, nil, 68, nil, + 38, 251, nil, 257, 50, 253, 252, nil, 249, 250, + nil, nil, 255, 22, 256, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, nil, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 44, 45, 323, 81, + 82, 83, 11, 65, nil, nil, nil, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 33, 34, 79, + 80, nil, nil, nil, nil, nil, 84, 31, 30, 114, + 113, 115, 116, nil, nil, 21, nil, nil, nil, nil, + nil, 10, 51, 325, 12, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 47, 48, 46, 254, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 264, + 265, nil, 43, nil, nil, 36, nil, nil, 66, 67, + nil, nil, 68, nil, 38, 251, nil, 257, 50, 253, + 252, nil, 249, 250, nil, nil, 255, 22, 256, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + nil, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 44, 45, 323, 81, 82, 83, 11, 65, nil, nil, + nil, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 33, 34, 79, 80, nil, nil, nil, nil, nil, + 84, 31, 30, 114, 113, 115, 116, nil, nil, 21, + nil, nil, nil, nil, nil, 10, 51, 325, 12, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 47, 48, 46, 254, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 264, 265, nil, 43, nil, nil, 36, + nil, nil, 66, 67, nil, nil, 68, nil, 38, 251, + nil, 257, 50, 253, 252, nil, 249, 250, nil, nil, + nil, 22, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, nil, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 44, 45, 81, 82, 83, 11, + 65, nil, nil, nil, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 33, 34, 79, 80, nil, nil, + nil, nil, nil, 84, 31, 30, 114, 113, 115, 116, + nil, nil, 21, nil, nil, nil, nil, nil, 10, 51, + 9, 12, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, 47, 48, 46, + 254, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 264, 265, nil, 43, + nil, nil, 36, nil, nil, 66, 67, nil, nil, 68, + nil, 38, 251, nil, 257, 50, 253, 252, nil, 249, + 250, nil, nil, nil, 22, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 44, 45, nil, + 75, nil, 73, 74, 76, 33, 34, 79, 80, nil, + nil, nil, nil, nil, 84, 31, 30, 114, 113, 115, + 116, nil, nil, 244, nil, nil, nil, nil, nil, nil, + 51, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 47, 48, + 46, 254, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 264, 265, nil, + 237, nil, nil, 243, nil, nil, 66, 67, nil, nil, + 68, nil, nil, 251, nil, nil, 50, 253, 252, nil, + 249, 250, nil, nil, nil, 242, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, nil, nil, + nil, 85, nil, 92, 106, 107, -432, nil, 44, 45, + nil, nil, nil, -432, -432, -432, nil, nil, -432, -432, + -432, nil, -432, nil, nil, nil, nil, nil, nil, nil, + -432, -432, -432, -432, nil, nil, nil, nil, nil, nil, + nil, nil, -432, -432, nil, -432, -432, -432, -432, -432, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, -432, -432, -432, -432, -432, -432, -432, -432, + -432, -432, -432, -432, -432, -432, nil, nil, -432, -432, + -432, nil, nil, -432, nil, 296, -432, nil, nil, -432, + -432, nil, -432, nil, -432, nil, -432, nil, -432, -432, + nil, -432, -432, -432, -432, -432, -321, -432, -432, -432, + nil, nil, nil, -321, -321, -321, nil, nil, -321, -321, + -321, nil, -321, -432, nil, nil, -432, -432, nil, -432, + -321, -432, -321, -321, nil, nil, nil, nil, -432, nil, + nil, nil, -321, -321, nil, -321, -321, -321, -321, -321, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, -321, -321, -321, -321, -321, -321, -321, -321, + -321, -321, -321, -321, -321, -321, nil, nil, -321, -321, + -321, nil, nil, -321, nil, 305, -321, nil, nil, -321, + -321, nil, -321, nil, -321, nil, -321, nil, -321, -321, + nil, -321, -321, -321, -321, -321, nil, -321, nil, -321, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, -321, nil, nil, -321, -321, nil, -321, + nil, -321, 81, 82, 83, nil, 65, nil, -321, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 33, 34, 79, 80, nil, nil, nil, nil, nil, 84, + 31, 30, 114, 113, 115, 116, nil, nil, 244, nil, + nil, nil, nil, nil, nil, 51, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, 317, 112, 120, 121, + nil, 104, 105, 47, 48, 46, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 237, nil, nil, 243, nil, + nil, 66, 67, nil, nil, 68, nil, 314, nil, 312, + nil, 50, nil, nil, 318, nil, nil, nil, nil, nil, + 242, nil, nil, nil, nil, 102, 315, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 44, 45, nil, 75, nil, 73, 74, + 76, 33, 34, 79, 80, nil, nil, nil, nil, nil, + 84, 31, 30, 114, 113, 115, 116, nil, nil, 244, + nil, nil, nil, nil, nil, nil, 51, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, 317, 112, 120, + 121, nil, 104, 105, 47, 48, 46, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 237, nil, nil, 243, + nil, nil, 66, 67, nil, nil, 68, nil, 314, nil, + 312, nil, 50, nil, nil, 318, nil, nil, nil, nil, + nil, 242, nil, nil, nil, nil, 102, 315, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 44, 45, nil, 75, nil, 73, + 74, 76, 33, 34, 79, 80, nil, nil, nil, nil, + nil, 84, 31, 30, 114, 113, 115, 116, nil, nil, + 244, nil, nil, nil, nil, nil, nil, 51, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, 317, 112, + 120, 121, nil, 104, 105, 47, 48, 46, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 237, nil, nil, + 243, nil, nil, 66, 67, nil, nil, 68, nil, 314, + nil, 312, nil, 50, nil, nil, 318, nil, nil, nil, + nil, nil, 242, nil, nil, nil, nil, 102, 315, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 44, 45, nil, 75, nil, + 73, 74, 76, 344, 345, 79, 80, nil, nil, nil, + nil, nil, 84, 339, 347, 114, 113, 115, 116, nil, + nil, 244, nil, nil, nil, nil, nil, nil, 51, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 47, 48, 46, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 237, nil, + nil, 243, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 50, nil, nil, nil, nil, nil, + nil, nil, nil, 242, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 44, 45, nil, 75, + nil, 73, 74, 76, 344, 345, 79, 80, nil, nil, + nil, nil, nil, 84, 339, 347, 114, 113, 115, 116, + nil, nil, 244, nil, nil, nil, nil, nil, nil, 51, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, 47, 48, 46, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 237, + nil, nil, 243, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 50, nil, nil, nil, nil, + nil, nil, nil, nil, 242, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 44, 45, nil, + 75, nil, 73, 74, 76, 344, 345, 79, 80, nil, + nil, nil, nil, nil, 84, 339, 347, 114, 113, 115, + 116, nil, nil, 244, nil, nil, nil, nil, nil, nil, + 51, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 47, 48, + 46, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 237, nil, nil, 243, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 50, nil, nil, nil, + nil, nil, nil, nil, nil, 242, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 44, 45, + nil, 75, nil, 73, 74, 76, 344, 345, 79, 80, + nil, nil, nil, nil, nil, 84, 339, 347, 114, 113, + 115, 116, nil, nil, 244, nil, nil, nil, nil, nil, + nil, 51, nil, nil, 118, 117, 119, 108, 64, 110, + 109, 111, nil, 112, 120, 121, nil, 104, 105, 47, + 48, 46, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 237, nil, nil, 243, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 50, nil, nil, + nil, nil, nil, nil, nil, nil, 242, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 44, + 45, nil, 75, nil, 73, 74, 76, 344, 345, 79, + 80, nil, nil, nil, nil, nil, 84, 339, 347, 114, + 113, 115, 116, nil, nil, 244, nil, nil, nil, nil, + nil, nil, 51, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 47, 48, 46, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 237, nil, nil, 243, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 50, nil, + nil, nil, nil, nil, nil, nil, nil, 242, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + nil, nil, nil, 85, nil, 92, 106, 107, -306, nil, + 44, 45, nil, nil, nil, -306, -306, -306, nil, nil, + -306, -306, -306, nil, -306, nil, nil, nil, nil, nil, + nil, nil, -306, nil, -306, -306, -306, nil, nil, nil, + 114, 113, 115, 116, -306, -306, nil, -306, -306, -306, + -306, -306, nil, nil, nil, nil, 118, 117, 119, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 104, + 105, nil, nil, 348, -306, -306, -306, -306, -306, -306, + -306, -306, -306, -306, -306, -306, -306, -306, nil, nil, + -306, -306, -306, nil, nil, -306, nil, nil, -306, nil, + nil, -306, -306, nil, -306, nil, -306, nil, -306, nil, + -306, -306, nil, -306, -306, -306, -306, -306, nil, -306, + nil, -306, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, -306, 91, 101, -306, -306, + -306, -306, nil, -306, 85, -306, 92, 106, 107, nil, + -306, 81, 82, 83, 11, 65, nil, nil, nil, 71, + 72, nil, nil, nil, 75, nil, 73, 74, 76, 33, + 34, 79, 80, nil, nil, nil, nil, nil, 84, 31, + 30, 114, 113, 115, 116, nil, nil, 21, nil, nil, + nil, nil, nil, 10, 51, nil, 12, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 47, 48, 46, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 43, nil, nil, 36, nil, nil, + 66, 67, nil, nil, 68, nil, 38, nil, nil, nil, + 50, nil, nil, nil, nil, nil, nil, nil, nil, 22, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 44, 45, nil, 75, nil, 73, 74, 76, + 344, 345, 79, 80, nil, nil, nil, nil, nil, 84, + 339, 347, 114, 113, 115, 116, nil, nil, 244, nil, + nil, nil, nil, nil, nil, 51, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, 317, 112, 120, 121, + nil, 104, 105, 47, 48, 46, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 237, nil, nil, 243, nil, + nil, 66, 67, nil, nil, 68, nil, 314, nil, nil, + nil, 50, nil, nil, 318, nil, nil, nil, nil, nil, + 242, nil, nil, nil, nil, 102, 315, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 44, 45, nil, 75, nil, 73, 74, + 76, 344, 345, 79, 80, nil, nil, nil, nil, nil, + 84, 339, 347, 114, 113, 115, 116, nil, nil, 244, + nil, nil, nil, nil, nil, nil, 51, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, 317, 112, 120, + 121, nil, 104, 105, 47, 48, 46, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 237, nil, nil, 243, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 50, nil, nil, 318, nil, nil, nil, nil, + nil, 242, nil, nil, nil, nil, 102, 315, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 44, 45, nil, 75, nil, 73, + 74, 76, 33, 34, 79, 80, nil, nil, nil, nil, + nil, 84, 31, 30, 114, 113, 115, 116, nil, nil, + 21, nil, nil, nil, nil, nil, nil, 51, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, nil, 112, + 120, 121, nil, 104, 105, 47, 48, 46, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 237, nil, nil, + 243, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 50, nil, nil, nil, nil, nil, nil, + nil, nil, 22, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 44, 45, nil, 75, nil, + 73, 74, 76, 33, 34, 79, 80, nil, nil, nil, + nil, nil, 84, 31, 30, 114, 113, 115, 116, nil, + nil, 21, nil, nil, nil, nil, nil, nil, 51, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 47, 48, 46, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 237, nil, + nil, 243, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 50, nil, nil, nil, nil, nil, + nil, nil, nil, 22, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 44, 45, nil, 75, + nil, 73, 74, 76, 33, 34, 79, 80, nil, nil, + nil, nil, nil, 84, 31, 30, 114, 113, 115, 116, + nil, nil, 21, nil, nil, nil, nil, nil, nil, 51, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, 47, 48, 46, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 237, + nil, nil, 243, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 50, nil, nil, nil, nil, + nil, nil, nil, nil, 22, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, 126, nil, nil, nil, nil, 125, + 85, nil, 92, 106, 107, nil, nil, 44, 45, 81, + 82, 83, 11, 65, nil, nil, nil, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 33, 34, 79, + 80, nil, nil, nil, nil, nil, 84, 31, 30, 114, + 113, 115, 116, nil, nil, 21, nil, nil, nil, nil, + nil, 10, 51, 9, 12, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 47, 48, 46, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 43, nil, nil, 36, nil, nil, 66, 67, + nil, nil, 68, nil, 38, nil, nil, nil, 50, nil, + nil, nil, nil, nil, nil, nil, nil, 22, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + nil, nil, 418, 85, nil, 92, 106, 107, nil, nil, + 44, 45, 81, 82, 83, nil, 65, nil, nil, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 33, 34, 79, 80, nil, nil, nil, nil, nil, 84, + 31, 30, 114, 113, 115, 116, nil, nil, 21, nil, + nil, nil, nil, nil, nil, 51, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, nil, 112, 120, 121, + nil, 104, 105, 47, 48, 46, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 237, nil, nil, 243, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 50, nil, nil, nil, nil, nil, nil, nil, nil, + 22, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 44, 45, nil, 75, nil, 73, 74, + 76, 33, 34, 79, 80, nil, nil, nil, nil, nil, + 84, 31, 30, 114, 113, 115, 116, nil, nil, 21, + nil, nil, nil, nil, nil, nil, 51, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 47, 48, 46, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 237, nil, nil, 243, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 50, nil, nil, nil, nil, nil, nil, nil, + nil, 22, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 44, 45, nil, 75, nil, 73, + 74, 76, 33, 34, 79, 80, nil, nil, nil, nil, + nil, 84, 31, 30, 114, 113, 115, 116, nil, nil, + 21, nil, nil, nil, nil, nil, nil, 51, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, nil, 112, + 120, 121, nil, 104, 105, 47, 48, 46, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 237, nil, nil, + 243, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 50, nil, nil, nil, nil, nil, nil, + nil, nil, 22, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 44, 45, nil, 75, nil, + 73, 74, 76, 33, 34, 79, 80, nil, nil, nil, + nil, nil, 84, 31, 30, 114, 113, 115, 116, nil, + nil, 21, nil, nil, nil, nil, nil, nil, 51, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 47, 48, 46, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 237, nil, + nil, 243, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 50, nil, nil, nil, nil, nil, + nil, nil, nil, 22, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, nil, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 44, 45, 81, 82, + 83, 11, 65, nil, nil, nil, 71, 72, nil, nil, + nil, 75, nil, 73, 74, 76, 33, 34, 79, 80, + nil, nil, nil, nil, nil, 84, 31, 30, 114, 113, + 115, 116, nil, nil, 21, nil, nil, nil, nil, nil, + 10, 51, nil, 12, 118, 117, 119, 108, 64, 110, + 109, 111, nil, 112, 120, 121, nil, 104, 105, 47, + 48, 46, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 43, nil, nil, 36, nil, nil, 66, 67, nil, + nil, 68, nil, 38, nil, nil, nil, 50, nil, nil, + nil, nil, nil, nil, nil, nil, 22, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 44, + 45, nil, 75, nil, 73, 74, 76, 33, 34, 79, + 80, nil, nil, nil, nil, nil, 84, 31, 30, 114, + 113, 115, 116, nil, nil, 244, nil, nil, nil, nil, + nil, nil, 51, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 47, 48, 46, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 237, nil, nil, 243, nil, nil, 66, 67, + nil, nil, 68, nil, 434, nil, nil, nil, 50, nil, + nil, nil, nil, nil, nil, nil, nil, 242, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 44, 45, nil, 75, nil, 73, 74, 76, 33, 34, + 79, 80, nil, nil, nil, nil, nil, 84, 31, 30, + 114, 113, 115, 116, nil, nil, 244, nil, nil, nil, + nil, nil, nil, 51, nil, nil, 118, 117, 119, 108, + 64, 110, 109, 111, nil, 112, 120, 121, nil, 104, + 105, 47, 48, 46, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 237, nil, nil, 243, nil, nil, 66, + 67, nil, nil, 68, nil, 434, nil, nil, nil, 50, + nil, nil, nil, nil, nil, nil, nil, nil, 242, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 44, 45, nil, 75, nil, 73, 74, 76, 33, + 34, 79, 80, nil, nil, nil, nil, nil, 84, 31, + 30, 114, 113, 115, 116, nil, nil, 21, nil, nil, + nil, nil, nil, nil, 51, nil, nil, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 47, 48, 46, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 237, nil, nil, 243, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 50, nil, nil, nil, nil, nil, nil, nil, nil, 22, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 44, 45, nil, 75, nil, 73, 74, 76, + 33, 34, 79, 80, nil, nil, nil, nil, nil, 84, + 31, 30, 114, 113, 115, 116, nil, nil, 21, nil, + nil, nil, nil, nil, nil, 51, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, nil, 112, 120, 121, + nil, 104, 105, 47, 48, 46, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 237, nil, nil, 243, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 50, nil, nil, nil, nil, nil, nil, nil, nil, + 22, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 44, 45, nil, 75, nil, 73, 74, + 76, 33, 34, 79, 80, nil, nil, nil, nil, nil, + 84, 31, 30, 114, 113, 115, 116, nil, nil, 244, + nil, nil, nil, nil, nil, nil, 51, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 47, 48, 46, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 237, nil, nil, 243, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 50, nil, nil, nil, nil, nil, nil, nil, + nil, 242, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 44, 45, nil, 75, nil, 73, + 74, 76, 33, 34, 79, 80, nil, nil, nil, nil, + nil, 84, 31, 30, 114, 113, 115, 116, nil, nil, + 244, nil, nil, nil, nil, nil, nil, 51, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, 317, 112, + 120, 121, nil, 104, 105, 47, 48, 46, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 237, nil, nil, + 243, nil, nil, 66, 67, nil, nil, 68, nil, 314, + nil, 312, nil, 50, nil, nil, 318, nil, nil, nil, + nil, nil, 242, nil, nil, nil, nil, 102, 315, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 44, 45, nil, 75, nil, + 73, 74, 76, 33, 34, 79, 80, nil, nil, nil, + nil, nil, 84, 31, 30, 114, 113, 115, 116, nil, + nil, 244, nil, nil, nil, nil, nil, nil, 51, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 47, 48, 46, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 237, nil, + nil, 243, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 50, nil, nil, nil, nil, nil, + nil, nil, nil, 242, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 44, 45, nil, 75, + nil, 73, 74, 76, 33, 34, 79, 80, nil, nil, + nil, nil, nil, 84, 31, 30, 114, 113, 115, 116, + nil, nil, 21, nil, nil, nil, nil, nil, nil, 51, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, 47, 48, 46, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 237, + nil, nil, 243, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 50, nil, nil, nil, nil, + nil, nil, nil, nil, 22, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 44, 45, nil, + 75, nil, 73, 74, 76, 33, 34, 79, 80, nil, + nil, nil, nil, nil, 84, 31, 30, 114, 113, 115, + 116, nil, nil, 21, nil, nil, nil, nil, nil, nil, + 51, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 47, 48, + 46, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 237, nil, nil, 243, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 50, nil, nil, nil, + nil, nil, nil, nil, nil, 22, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, 232, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 44, 45, + nil, 75, nil, 73, 74, 76, 344, 345, 79, 80, + nil, nil, nil, nil, nil, 84, 339, 347, 114, 113, + 115, 116, nil, nil, 244, nil, nil, nil, nil, nil, + nil, 51, nil, nil, 118, 117, 119, 108, 64, 110, + 109, 111, nil, 112, 120, 121, nil, 104, 105, 47, + 48, 46, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 237, nil, nil, 243, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 50, nil, nil, + nil, nil, nil, nil, nil, nil, 242, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 44, + 45, nil, 75, nil, 73, 74, 76, 344, 345, 79, + 80, nil, nil, nil, nil, nil, 84, 339, 347, 114, + 113, 115, 116, nil, nil, 244, nil, nil, nil, nil, + nil, nil, 51, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 47, 48, 46, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 237, nil, nil, 243, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 50, nil, + nil, nil, nil, nil, nil, nil, nil, 242, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 44, 45, nil, 75, nil, 73, 74, 76, 344, 345, + 79, 80, nil, nil, nil, nil, nil, 84, 339, 347, + 114, 113, 115, 116, nil, nil, 244, nil, nil, nil, + nil, nil, nil, 51, nil, nil, 118, 117, 119, 108, + 64, 110, 109, 111, nil, 112, 120, 121, nil, 104, + 105, 47, 48, 46, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 237, nil, nil, 243, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 50, + nil, nil, nil, nil, nil, nil, nil, nil, 242, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 44, 45, nil, 75, nil, 73, 74, 76, 344, + 345, 79, 80, nil, nil, nil, nil, nil, 84, 339, + 347, 114, 113, 115, 116, nil, nil, 244, nil, nil, + nil, nil, nil, nil, 51, nil, nil, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 47, 48, 46, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 237, nil, nil, 243, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 50, nil, nil, nil, nil, nil, nil, nil, nil, 242, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 44, 45, nil, 75, nil, 73, 74, 76, + 344, 345, 79, 80, nil, nil, nil, nil, nil, 84, + 339, 347, 114, 113, 115, 116, nil, nil, 244, nil, + nil, nil, nil, nil, nil, 51, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, nil, 112, 120, 121, + nil, 104, 105, 47, 48, 46, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 237, nil, nil, 243, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 50, nil, nil, nil, nil, nil, nil, nil, nil, + 242, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 44, 45, nil, 75, nil, 73, 74, + 76, 344, 345, 79, 80, nil, nil, nil, nil, nil, + 84, 339, 347, 114, 113, 115, 116, nil, nil, 244, + nil, nil, nil, nil, nil, nil, 51, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 47, 48, 46, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 237, nil, nil, 243, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 50, nil, nil, nil, nil, nil, nil, nil, + nil, 242, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 44, 45, nil, 75, nil, 73, + 74, 76, 344, 345, 79, 80, nil, nil, nil, nil, + nil, 84, 339, 347, 114, 113, 115, 116, nil, nil, + 244, nil, nil, nil, nil, nil, nil, 51, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, nil, 112, + 120, 121, nil, 104, 105, 47, 48, 46, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 237, nil, nil, + 243, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 50, nil, nil, nil, nil, nil, nil, + nil, nil, 242, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 44, 45, nil, 75, nil, + 73, 74, 76, 344, 345, 79, 80, nil, nil, nil, + nil, nil, 84, 339, 347, 114, 113, 115, 116, nil, + nil, 244, nil, nil, nil, nil, nil, nil, 51, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 47, 48, 46, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 237, nil, + nil, 243, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 50, nil, nil, nil, nil, nil, + nil, nil, nil, 242, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 44, 45, nil, 75, + nil, 73, 74, 76, 344, 345, 79, 80, nil, nil, + nil, nil, nil, 84, 339, 347, 114, 113, 115, 116, + nil, nil, 244, nil, nil, nil, nil, nil, nil, 51, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, 47, 48, 46, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 237, + nil, nil, 243, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 50, nil, nil, nil, nil, + nil, nil, nil, nil, 242, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 44, 45, nil, + 75, nil, 73, 74, 76, 344, 345, 79, 80, nil, + nil, nil, nil, nil, 84, 339, 347, 114, 113, 115, + 116, nil, nil, 244, nil, nil, nil, nil, nil, nil, + 51, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 47, 48, + 46, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 237, nil, nil, 243, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 50, nil, nil, nil, + nil, nil, nil, nil, nil, 242, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 44, 45, + nil, 75, nil, 73, 74, 76, 344, 345, 79, 80, + nil, nil, nil, nil, nil, 84, 339, 347, 114, 113, + 115, 116, nil, nil, 244, nil, nil, nil, nil, nil, + nil, 51, nil, nil, 118, 117, 119, 108, 64, 110, + 109, 111, nil, 112, 120, 121, nil, 104, 105, 47, + 48, 46, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 237, nil, nil, 243, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 50, nil, nil, + nil, nil, nil, nil, nil, nil, 242, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 44, + 45, nil, 75, nil, 73, 74, 76, 344, 345, 79, + 80, nil, nil, nil, nil, nil, 84, 339, 347, 114, + 113, 115, 116, nil, nil, 244, nil, nil, nil, nil, + nil, nil, 51, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 47, 48, 46, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 237, nil, nil, 243, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 50, nil, + nil, nil, nil, nil, nil, nil, nil, 242, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 44, 45, nil, 75, nil, 73, 74, 76, 344, 345, + 79, 80, nil, nil, nil, nil, nil, 84, 339, 347, + 114, 113, 115, 116, nil, nil, 244, nil, nil, nil, + nil, nil, nil, 51, nil, nil, 118, 117, 119, 108, + 64, 110, 109, 111, nil, 112, 120, 121, nil, 104, + 105, 47, 48, 46, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 237, nil, nil, 243, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 50, + nil, nil, nil, nil, nil, nil, nil, nil, 242, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 44, 45, nil, 75, nil, 73, 74, 76, 344, + 345, 79, 80, nil, nil, nil, nil, nil, 84, 339, + 347, 114, 113, 115, 116, nil, nil, 244, nil, nil, + nil, nil, nil, nil, 51, nil, nil, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 47, 48, 46, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 237, nil, nil, 243, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 50, nil, nil, nil, nil, nil, nil, nil, nil, 242, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 44, 45, nil, 75, nil, 73, 74, 76, + 344, 345, 79, 80, nil, nil, nil, nil, nil, 84, + 339, 347, 114, 113, 115, 116, nil, nil, 244, nil, + nil, nil, nil, nil, nil, 51, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, nil, 112, 120, 121, + nil, 104, 105, 47, 48, 46, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 237, nil, nil, 243, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 50, nil, nil, nil, nil, nil, nil, nil, nil, + 242, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 44, 45, nil, 75, nil, 73, 74, + 76, 344, 345, 79, 80, nil, nil, nil, nil, nil, + 84, 339, 347, 114, 113, 115, 116, nil, nil, 244, + nil, nil, nil, nil, nil, nil, 51, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 47, 48, 46, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 237, nil, nil, 243, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 50, nil, nil, nil, nil, nil, nil, nil, + nil, 242, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 44, 45, nil, 75, nil, 73, + 74, 76, 344, 345, 79, 80, nil, nil, nil, nil, + nil, 84, 339, 347, 114, 113, 115, 116, nil, nil, + 244, nil, nil, nil, nil, nil, nil, 51, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, nil, 112, + 120, 121, nil, 104, 105, 47, 48, 46, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 237, nil, nil, + 243, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 50, nil, nil, nil, nil, nil, nil, + nil, nil, 242, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 44, 45, nil, 75, nil, + 73, 74, 76, 344, 345, 79, 80, nil, nil, nil, + nil, nil, 84, 339, 347, 114, 113, 115, 116, nil, + nil, 244, nil, nil, nil, nil, nil, nil, 51, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 47, 48, 46, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 237, nil, + nil, 243, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 50, nil, nil, nil, nil, nil, + nil, nil, nil, 242, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 44, 45, nil, 75, + nil, 73, 74, 76, 344, 345, 79, 80, nil, nil, + nil, nil, nil, 84, 339, 347, 114, 113, 115, 116, + nil, nil, 244, nil, nil, nil, nil, nil, nil, 51, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, 47, 48, 46, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 237, + nil, nil, 243, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 50, nil, nil, nil, nil, + nil, nil, nil, nil, 242, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 44, 45, nil, + 75, nil, 73, 74, 76, 344, 345, 79, 80, nil, + nil, nil, nil, nil, 84, 339, 347, 114, 113, 115, + 116, nil, nil, 244, nil, nil, nil, nil, nil, nil, + 51, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 47, 48, + 46, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 237, nil, nil, 243, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 50, nil, nil, nil, + nil, nil, nil, nil, nil, 242, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 44, 45, + nil, 75, nil, 73, 74, 76, 344, 345, 79, 80, + nil, nil, nil, nil, nil, 84, 339, 347, 114, 113, + 115, 116, nil, nil, 244, nil, nil, nil, nil, nil, + nil, 51, nil, nil, 118, 117, 119, 108, 64, 110, + 109, 111, nil, 112, 120, 121, nil, 104, 105, 47, + 48, 46, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 237, nil, nil, 243, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 50, nil, nil, + nil, nil, nil, nil, nil, nil, 242, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 44, + 45, nil, 75, nil, 73, 74, 76, 344, 345, 79, + 80, nil, nil, nil, nil, nil, 84, 339, 347, 114, + 113, 115, 116, nil, nil, 244, nil, nil, nil, nil, + nil, nil, 51, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 47, 48, 46, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 237, nil, nil, 243, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 50, nil, + nil, nil, nil, nil, nil, nil, nil, 242, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 44, 45, nil, 75, nil, 73, 74, 76, 344, 345, + 79, 80, nil, nil, nil, nil, nil, 84, 339, 347, + 114, 113, 115, 116, nil, nil, 244, nil, nil, nil, + nil, nil, nil, 51, nil, nil, 118, 117, 119, 108, + 64, 110, 109, 111, nil, 112, 120, 121, nil, 104, + 105, 47, 48, 46, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 237, nil, nil, 243, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 50, + nil, nil, nil, nil, nil, nil, nil, nil, 242, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 44, 45, nil, 75, nil, 73, 74, 76, 344, + 345, 79, 80, nil, nil, nil, nil, nil, 84, 339, + 347, 114, 113, 115, 116, nil, nil, 244, nil, nil, + nil, nil, nil, nil, 51, nil, nil, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 47, 48, 46, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 237, nil, nil, 243, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 50, nil, nil, nil, nil, nil, nil, nil, nil, 242, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 44, 45, nil, 75, nil, 73, 74, 76, + 33, 34, 79, 80, nil, nil, nil, nil, nil, 84, + 31, 30, 114, 113, 115, 116, nil, nil, 21, nil, + nil, nil, nil, nil, nil, 51, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, nil, 112, 120, 121, + nil, 104, 105, 47, 48, 46, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 237, nil, nil, 243, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 50, nil, nil, nil, nil, nil, nil, nil, nil, + 22, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 44, 45, nil, 75, nil, 73, 74, + 76, 33, 34, 79, 80, nil, nil, nil, nil, nil, + 84, 31, 30, 114, 113, 115, 116, nil, nil, 244, + nil, nil, nil, nil, nil, nil, 51, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, 317, 112, 120, + 121, nil, 104, 105, 47, 48, 46, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 237, nil, nil, 243, + nil, nil, 66, 67, nil, nil, 68, nil, 314, nil, + 312, nil, 50, nil, nil, 318, nil, nil, nil, nil, + nil, 242, nil, nil, nil, nil, 102, 315, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 44, 515, nil, 75, nil, 73, + 74, 76, 33, 34, 79, 80, nil, nil, nil, nil, + nil, 84, 31, 30, 114, 113, 115, 116, nil, nil, + 244, nil, nil, nil, nil, nil, nil, 51, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, 317, 112, + 120, 121, nil, 104, 105, 47, 48, 46, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 237, nil, nil, + 243, nil, nil, 66, 67, nil, nil, 68, nil, 314, + nil, 312, nil, 50, nil, nil, 318, nil, nil, nil, + nil, nil, 242, nil, nil, nil, nil, 102, 315, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 44, 45, nil, 75, nil, + 73, 74, 76, 33, 34, 79, 80, nil, nil, nil, + nil, nil, 84, 31, 30, 114, 113, 115, 116, nil, + nil, 244, nil, nil, nil, nil, nil, nil, 51, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, 317, + 112, 120, 121, nil, 104, 105, 47, 48, 46, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 237, nil, + nil, 243, nil, nil, 66, 67, nil, nil, 68, nil, + 314, nil, 312, nil, 50, nil, nil, 318, nil, nil, + nil, nil, nil, 242, nil, nil, nil, nil, 102, 315, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, 232, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 44, 45, nil, 75, + nil, 73, 74, 76, 344, 345, 79, 80, nil, nil, + nil, nil, nil, 84, 339, 347, 114, 113, 115, 116, + nil, nil, 244, nil, nil, nil, nil, nil, nil, 51, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, 47, 48, 46, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 237, + nil, nil, 243, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 50, nil, nil, nil, nil, + nil, nil, nil, nil, 242, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 44, 45, nil, + 75, nil, 73, 74, 76, 344, 345, 79, 80, nil, + nil, nil, nil, nil, 84, 339, 347, 114, 113, 115, + 116, nil, nil, 244, nil, nil, nil, nil, nil, nil, + 51, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 47, 48, + 46, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 237, nil, nil, 243, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 50, nil, nil, nil, + nil, nil, nil, nil, nil, 242, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 44, 45, + nil, 75, nil, 73, 74, 76, 344, 345, 79, 80, + nil, nil, nil, nil, nil, 84, 339, 347, 114, 113, + 115, 116, nil, nil, 244, nil, nil, nil, nil, nil, + nil, 51, nil, nil, 118, 117, 119, 108, 64, 110, + 109, 111, nil, 112, 120, 121, nil, 104, 105, 47, + 48, 46, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 237, nil, nil, 243, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 50, nil, nil, + nil, nil, nil, nil, nil, nil, 242, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 44, + 45, nil, 75, nil, 73, 74, 76, 344, 345, 79, + 80, nil, nil, nil, nil, nil, 84, 339, 347, 114, + 113, 115, 116, nil, nil, 244, nil, nil, nil, nil, + nil, nil, 51, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 47, 48, 46, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 237, nil, nil, 243, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 50, nil, + nil, nil, nil, nil, nil, nil, nil, 242, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + nil, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 44, 45, 81, 82, 83, 11, 65, nil, nil, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 33, 34, 79, 80, nil, nil, nil, nil, nil, 84, + 31, 30, 114, 113, 115, 116, nil, nil, 21, nil, + nil, nil, nil, nil, 10, 51, nil, 12, 118, 117, + 119, 108, 64, 110, 109, 111, nil, 112, 120, 121, + nil, 104, 105, 47, 48, 46, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 43, nil, nil, 36, nil, + nil, 66, 67, nil, nil, 68, nil, 38, nil, nil, + nil, 50, nil, nil, nil, nil, nil, nil, nil, nil, + 22, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 44, 45, nil, 75, nil, 73, 74, + 76, 344, 345, 79, 80, nil, nil, nil, nil, nil, + 84, 339, 347, 114, 113, 115, 116, nil, nil, 244, + nil, nil, nil, nil, nil, nil, 51, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 47, 48, 46, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 237, nil, nil, 243, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 50, nil, nil, nil, nil, nil, nil, nil, + nil, 242, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 44, 45, nil, 75, nil, 73, + 74, 76, 344, 345, 79, 80, nil, nil, nil, nil, + nil, 84, 339, 347, 114, 113, 115, 116, nil, nil, + 244, nil, nil, nil, nil, nil, nil, 51, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, nil, 112, + 120, 121, nil, 104, 105, 47, 48, 46, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 237, nil, nil, + 243, 561, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 50, nil, nil, nil, nil, nil, nil, + nil, nil, 242, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 44, 45, nil, 75, nil, + 73, 74, 76, 33, 34, 79, 80, nil, nil, nil, + nil, nil, 84, 31, 30, 114, 113, 115, 116, nil, + nil, 21, nil, nil, nil, nil, nil, nil, 51, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 47, 48, 46, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 237, nil, + nil, 243, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 50, nil, nil, nil, nil, nil, + nil, nil, nil, 22, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 44, 45, nil, 75, + nil, 73, 74, 76, 33, 34, 79, 80, nil, nil, + nil, nil, nil, 84, 31, 30, 114, 113, 115, 116, + nil, nil, 21, nil, nil, nil, nil, nil, nil, 51, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, 47, 48, 46, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 237, + nil, nil, 243, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 50, nil, nil, nil, nil, + nil, nil, nil, nil, 22, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 44, 45, nil, + 75, nil, 73, 74, 76, 344, 345, 79, 80, nil, + nil, nil, nil, nil, 84, 339, 347, 114, 113, 115, + 116, nil, nil, 244, nil, nil, nil, nil, nil, nil, + 51, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 47, 48, + 46, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 237, nil, nil, 243, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 50, nil, nil, nil, + nil, nil, nil, nil, nil, 242, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, nil, nil, + nil, 85, nil, 92, 106, 107, -270, nil, 44, 45, + nil, nil, nil, -270, -270, -270, nil, nil, -270, -270, + -270, nil, -270, nil, nil, nil, nil, nil, nil, nil, + -270, -270, -270, -270, nil, nil, nil, nil, nil, nil, + nil, nil, -270, -270, nil, -270, -270, -270, -270, -270, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, -270, -270, -270, -270, -270, -270, -270, -270, + -270, -270, -270, -270, -270, -270, nil, nil, -270, -270, + -270, nil, nil, -270, nil, 296, -270, nil, nil, -270, + -270, nil, -270, nil, -270, nil, -270, nil, -270, -270, + nil, -270, -270, -270, -270, -270, nil, -270, -270, -270, + 582, nil, 579, 578, 577, 587, 580, nil, nil, nil, + nil, nil, nil, -270, nil, 590, -270, -270, -708, -270, + nil, -270, nil, nil, nil, -708, -708, -708, -270, nil, + -708, -708, -708, nil, -708, nil, nil, 585, nil, nil, + nil, nil, -708, -708, -708, -708, -708, nil, 598, 597, + nil, nil, nil, 591, -708, -708, nil, -708, -708, -708, + -708, -708, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, -708, -708, -708, -708, -708, -708, + -708, -708, -708, -708, -708, -708, -708, -708, nil, nil, + -708, -708, -708, nil, nil, -708, nil, nil, -708, nil, + nil, -708, -708, nil, -708, nil, -708, nil, -708, nil, + -708, -708, nil, -708, -708, -708, -708, -708, nil, -708, + -708, -708, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, -708, nil, nil, -708, -708, + -708, -708, nil, -708, -709, -708, nil, nil, nil, nil, + -708, -709, -709, -709, nil, nil, -709, -709, -709, nil, + -709, nil, nil, nil, nil, nil, nil, nil, -709, -709, + -709, -709, -709, nil, nil, nil, nil, nil, nil, nil, + -709, -709, nil, -709, -709, -709, -709, -709, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + -709, -709, -709, -709, -709, -709, -709, -709, -709, -709, + -709, -709, -709, -709, nil, nil, -709, -709, -709, nil, + nil, -709, nil, nil, -709, nil, nil, -709, -709, nil, + -709, nil, -709, nil, -709, nil, -709, -709, nil, -709, + -709, -709, -709, -709, nil, -709, -709, -709, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, -709, nil, nil, -709, -709, -709, -709, nil, -709, + nil, -709, nil, 81, 82, 83, -709, 65, nil, nil, + nil, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 33, 34, 79, 80, nil, nil, nil, nil, nil, + 84, 31, 30, 114, 113, 115, 116, nil, nil, 244, + nil, nil, nil, nil, nil, nil, 51, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, 317, 112, 120, + 121, nil, 104, 105, 47, 48, 46, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 237, nil, nil, 243, + nil, nil, 66, 67, nil, nil, 68, nil, 314, nil, + 312, nil, 50, nil, nil, 318, nil, nil, nil, nil, + nil, 242, nil, nil, nil, nil, 102, 315, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 44, 45, nil, 75, nil, 73, + 74, 76, 344, 345, 79, 80, nil, nil, nil, nil, + nil, 84, 339, 347, 114, 113, 115, 116, nil, nil, + 244, nil, nil, nil, nil, nil, nil, 51, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, nil, 112, + 120, 121, nil, 104, 105, 47, 48, 46, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 237, nil, nil, + 243, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 50, nil, nil, nil, nil, nil, nil, + nil, nil, 242, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 44, 45, nil, 75, nil, + 73, 74, 76, 344, 345, 79, 80, nil, nil, nil, + nil, nil, 84, 339, 347, 114, 113, 115, 116, nil, + nil, 244, nil, nil, nil, nil, nil, nil, 51, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 47, 48, 46, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 237, nil, + nil, 243, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 50, nil, nil, nil, nil, nil, + nil, nil, nil, 242, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 44, 45, nil, 75, + nil, 73, 74, 76, 344, 345, 79, 80, nil, nil, + nil, nil, nil, 84, 339, 347, 114, 113, 115, 116, + nil, nil, 244, nil, nil, nil, nil, nil, nil, 51, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, 47, 48, 46, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 237, + nil, nil, 243, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 50, nil, nil, nil, nil, + nil, nil, nil, nil, 242, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, nil, nil, nil, + 85, nil, 92, 106, 107, -270, nil, 44, 45, nil, + nil, nil, -270, -270, -270, nil, nil, -270, -270, -270, + 582, -270, 579, 578, 577, 587, 580, nil, nil, -270, + -270, -270, nil, nil, nil, 590, nil, nil, nil, nil, + nil, -270, -270, nil, -270, -270, -270, -270, -270, nil, + nil, nil, nil, nil, nil, nil, 582, 585, 579, 578, + 577, 587, 580, nil, nil, nil, 595, 594, 598, 597, + nil, 590, nil, 591, nil, 582, nil, 579, 578, 577, + 587, 580, -270, nil, nil, nil, nil, nil, nil, -270, + 590, nil, nil, 585, 296, -270, nil, nil, nil, 232, + nil, nil, 595, 594, 598, 597, nil, nil, nil, 591, + nil, nil, 585, 641, nil, nil, nil, -270, -270, nil, + nil, 595, 594, 598, 597, nil, nil, nil, 591, nil, + nil, nil, -270, nil, nil, -270, nil, 81, 82, 83, + -270, 65, nil, nil, nil, 71, 72, -270, nil, nil, + 75, nil, 73, 74, 76, 344, 345, 79, 80, nil, + nil, nil, nil, nil, 84, 339, 347, 114, 113, 115, + 116, nil, nil, 244, nil, nil, nil, nil, nil, nil, + 51, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 47, 48, + 46, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 237, nil, nil, 243, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 50, nil, nil, nil, + nil, nil, nil, nil, nil, 242, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 44, 45, + nil, 75, nil, 73, 74, 76, 344, 345, 79, 80, + nil, nil, nil, nil, nil, 84, 339, 347, 114, 113, + 115, 116, nil, nil, 244, nil, nil, nil, nil, nil, + nil, 51, nil, nil, 118, 117, 119, 108, 64, 110, + 109, 111, 317, 112, 120, 121, nil, 104, 105, 47, + 48, 46, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 237, nil, nil, 243, nil, nil, 66, 67, nil, + nil, 68, nil, 742, nil, 312, nil, 50, nil, nil, + 318, nil, nil, nil, nil, nil, 242, nil, nil, nil, + nil, 102, 315, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 44, + 45, nil, 75, nil, 73, 74, 76, 344, 345, 79, + 80, nil, nil, nil, nil, nil, 84, 339, 347, 114, + 113, 115, 116, nil, nil, 244, nil, nil, nil, nil, + nil, nil, 51, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, 317, 112, 120, 121, nil, 104, 105, + 47, 48, 46, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 237, nil, nil, 243, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, 312, nil, 50, nil, + nil, 318, nil, nil, nil, nil, nil, 242, nil, nil, + nil, nil, 102, 315, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 44, 45, nil, 75, nil, 73, 74, 76, 344, 345, + 79, 80, nil, nil, nil, nil, nil, 84, 339, 347, + 114, 113, 115, 116, nil, nil, 244, nil, nil, nil, + nil, nil, nil, 51, nil, nil, 118, 117, 119, 108, + 64, 110, 109, 111, nil, 112, 120, 121, nil, 104, + 105, 47, 48, 46, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 237, nil, nil, 243, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 50, + nil, nil, nil, nil, nil, nil, nil, nil, 242, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, nil, nil, nil, 85, nil, 92, 106, 107, nil, + nil, 44, 45, 81, 82, 83, 11, 65, nil, nil, + nil, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 33, 34, 79, 80, nil, nil, nil, nil, nil, + 84, 31, 30, 114, 113, 115, 116, nil, nil, 21, + nil, nil, nil, nil, nil, 10, 51, 325, 12, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 47, 48, 46, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 43, nil, nil, 36, + nil, nil, 66, 67, nil, nil, 68, nil, 38, nil, + nil, nil, 50, nil, nil, nil, nil, nil, nil, nil, + nil, 22, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, nil, nil, 418, 85, nil, 92, + 106, 107, nil, nil, 44, 45, 81, 82, 83, nil, + 65, nil, nil, nil, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 33, 34, 79, 80, nil, nil, + nil, nil, nil, 84, 31, 30, 114, 113, 115, 116, + nil, nil, 244, nil, nil, nil, nil, nil, nil, 51, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + 317, 112, 120, 121, nil, 104, 105, 47, 48, 46, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 237, + nil, nil, 243, nil, nil, 66, 67, nil, nil, 68, + nil, 314, nil, 312, nil, 50, nil, nil, 318, nil, + nil, nil, nil, nil, 242, nil, nil, nil, nil, 102, + 315, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 44, 45, nil, + 75, nil, 73, 74, 76, 344, 345, 79, 80, nil, + nil, nil, nil, nil, 84, 339, 347, 114, 113, 115, + 116, nil, nil, 244, nil, nil, nil, nil, nil, nil, + 51, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 47, 48, + 46, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 237, nil, nil, 243, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 50, nil, nil, nil, + nil, nil, nil, nil, nil, 242, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 44, 45, + nil, 75, nil, 73, 74, 76, 344, 345, 79, 80, + nil, nil, nil, nil, nil, 84, 339, 347, 114, 113, + 115, 116, nil, nil, 244, nil, nil, nil, nil, nil, + nil, 51, nil, nil, 118, 117, 119, 108, 64, 110, + 109, 111, nil, 112, 120, 121, nil, 104, 105, 47, + 48, 46, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 237, nil, nil, 243, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 50, nil, nil, + nil, nil, nil, nil, nil, nil, 242, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 44, + 45, nil, 75, nil, 73, 74, 76, 33, 34, 79, + 80, nil, nil, nil, nil, nil, 84, 31, 30, 114, + 113, 115, 116, nil, nil, 21, nil, nil, nil, nil, + nil, nil, 51, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 47, 48, 46, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 237, nil, nil, 243, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 50, nil, + nil, nil, nil, nil, nil, nil, nil, 22, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 44, 45, nil, 75, nil, 73, 74, 76, 344, 345, + 79, 80, nil, nil, nil, nil, nil, 84, 339, 347, + 114, 113, 115, 116, nil, nil, 244, nil, nil, nil, + nil, nil, nil, 51, nil, nil, 118, 117, 119, 108, + 64, 110, 109, 111, nil, 112, 120, 121, nil, 104, + 105, 47, 48, 46, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 237, nil, nil, 243, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 50, + nil, nil, nil, nil, nil, nil, nil, nil, 242, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 44, 45, nil, 75, nil, 73, 74, 76, 344, + 345, 79, 80, nil, nil, nil, nil, nil, 84, 339, + 347, 114, 113, 115, 116, nil, nil, 244, nil, nil, + nil, nil, nil, nil, 51, nil, nil, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 47, 48, 46, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 237, nil, nil, 243, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 50, nil, nil, nil, nil, nil, nil, nil, nil, 242, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 44, 45, nil, 75, nil, 73, 74, 76, + 344, 345, 79, 80, nil, nil, nil, nil, nil, 84, + 339, 347, 114, 113, 115, 116, nil, nil, 244, nil, + nil, nil, nil, nil, nil, 51, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, nil, 112, 120, 121, + nil, 104, 105, 47, 48, 46, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 237, nil, nil, 243, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 50, nil, nil, nil, nil, nil, nil, nil, nil, + 242, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 44, 45, nil, 75, nil, 73, 74, + 76, 344, 345, 79, 80, nil, nil, nil, nil, nil, + 84, 339, 347, 114, 113, 115, 116, nil, nil, 244, + nil, nil, nil, nil, nil, nil, 51, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, 317, 112, 120, + 121, nil, 104, 105, 47, 48, 46, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 237, nil, nil, 243, + nil, nil, 66, 67, nil, nil, 68, nil, 742, nil, + nil, nil, 50, nil, nil, 318, nil, nil, nil, nil, + nil, 242, nil, nil, nil, nil, 102, 315, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 44, 45, nil, 75, nil, 73, + 74, 76, 344, 345, 79, 80, nil, nil, nil, nil, + nil, 84, 339, 347, 114, 113, 115, 116, nil, nil, + 244, nil, nil, nil, nil, nil, nil, 51, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, 317, 112, + 120, 121, nil, 104, 105, 47, 48, 46, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 237, nil, nil, + 243, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 50, nil, nil, 318, nil, nil, nil, + nil, nil, 242, nil, nil, nil, nil, 102, 315, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 44, 45, nil, 75, nil, + 73, 74, 76, 344, 345, 79, 80, nil, nil, nil, + nil, nil, 84, 339, 347, 114, 113, 115, 116, nil, + nil, 244, nil, nil, nil, nil, nil, nil, 51, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 47, 48, 46, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 237, nil, + nil, 243, nil, nil, 66, 67, nil, nil, 68, nil, + 314, nil, nil, nil, 50, nil, nil, nil, nil, nil, + nil, nil, nil, 242, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 44, 45, nil, 75, + nil, 73, 74, 76, 33, 34, 79, 80, nil, nil, + nil, nil, nil, 84, 31, 30, 114, 113, 115, 116, + nil, nil, 244, nil, nil, nil, nil, nil, nil, 51, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + 317, 112, 120, 121, nil, 104, 105, 47, 48, 46, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 237, + nil, nil, 243, nil, nil, 66, 67, nil, nil, 68, + nil, 314, nil, 312, nil, 50, nil, nil, 318, nil, + nil, nil, nil, nil, 242, nil, nil, nil, nil, 102, + 315, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 44, 45, nil, + 75, nil, 73, 74, 76, 33, 34, 79, 80, nil, + nil, nil, nil, nil, 84, 31, 30, 114, 113, 115, + 116, nil, nil, 244, nil, nil, nil, nil, nil, nil, + 51, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, 317, 112, 120, 121, nil, 104, 105, 47, 48, + 46, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 237, nil, nil, 243, nil, nil, 66, 67, nil, nil, + 68, nil, 314, nil, 312, nil, 50, nil, nil, 318, + nil, nil, nil, nil, nil, 242, nil, nil, nil, nil, + 102, 315, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, nil, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 44, 45, + 81, 82, 83, 11, 65, nil, nil, nil, 71, 72, + nil, nil, nil, 75, nil, 73, 74, 76, 33, 34, + 79, 80, nil, nil, nil, nil, nil, 84, 31, 30, + 114, 113, 115, 116, nil, nil, 21, nil, nil, nil, + nil, nil, 10, 51, nil, 12, 118, 117, 119, 108, + 64, 110, 109, 111, nil, 112, 120, 121, nil, 104, + 105, 47, 48, 46, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 43, nil, nil, 36, nil, nil, 66, + 67, nil, nil, 68, nil, 38, nil, nil, nil, 50, + nil, nil, nil, nil, nil, nil, nil, nil, 22, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 44, 45, nil, 75, nil, 73, 74, 76, 344, + 345, 79, 80, nil, nil, nil, nil, nil, 84, 339, + 347, 114, 113, 115, 116, nil, nil, 244, nil, nil, + nil, nil, nil, nil, 51, nil, nil, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 47, 48, 46, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 237, nil, nil, 243, nil, nil, + 66, 67, nil, nil, 68, nil, 844, nil, nil, nil, + 50, nil, nil, nil, nil, nil, nil, nil, nil, 242, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 44, 45, nil, 75, nil, 73, 74, 76, + 33, 34, 79, 80, nil, nil, nil, nil, nil, 84, + 31, 30, 114, 113, 115, 116, nil, nil, 244, nil, + nil, nil, nil, nil, nil, 51, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, nil, 112, 120, 121, + nil, 104, 105, 47, 48, 46, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 237, nil, nil, 243, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 50, nil, nil, nil, nil, nil, nil, nil, nil, + 242, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 44, 45, nil, 75, nil, 73, 74, + 76, 33, 34, 79, 80, nil, nil, nil, nil, nil, + 84, 31, 30, 114, 113, 115, 116, nil, nil, 244, + nil, nil, nil, nil, nil, nil, 51, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, 317, 112, 120, + 121, nil, 104, 105, 47, 48, 46, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 237, nil, nil, 243, + nil, nil, 66, 67, nil, nil, 68, nil, 314, nil, + 312, nil, 50, nil, nil, 318, nil, nil, nil, nil, + nil, 242, nil, nil, nil, nil, 102, 315, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, nil, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 44, 45, 81, 82, 83, 11, + 65, nil, nil, nil, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 33, 34, 79, 80, nil, nil, + nil, nil, nil, 84, 31, 30, 114, 113, 115, 116, + nil, nil, 21, nil, nil, nil, nil, nil, 10, 51, + nil, 12, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, 47, 48, 46, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 43, + nil, nil, 36, nil, nil, 66, 67, nil, nil, 68, + nil, 38, nil, nil, nil, 50, nil, nil, nil, nil, + nil, nil, nil, nil, 22, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 44, 45, nil, + 75, nil, 73, 74, 76, 344, 345, 79, 80, nil, + nil, nil, nil, nil, 84, 339, 347, 114, 113, 115, + 116, nil, nil, 244, nil, nil, nil, nil, nil, nil, + 51, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 47, 48, + 46, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 237, nil, nil, 243, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 50, nil, nil, nil, + nil, nil, nil, nil, nil, 242, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 44, 45, + nil, 75, nil, 73, 74, 76, 344, 345, 79, 80, + nil, nil, nil, nil, nil, 84, 339, 347, 114, 113, + 115, 116, nil, nil, 244, nil, nil, nil, nil, nil, + nil, 51, nil, nil, 118, 117, 119, 108, 64, 110, + 109, 111, 317, 112, 120, 121, nil, 104, 105, 47, + 48, 46, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 237, nil, nil, 243, nil, nil, 66, 67, nil, + nil, 68, nil, 742, nil, 312, nil, 50, nil, nil, + 318, nil, nil, nil, nil, nil, 242, nil, nil, nil, + nil, 102, 315, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 44, + 45, nil, 75, nil, 73, 74, 76, 344, 345, 79, + 80, nil, nil, nil, nil, nil, 84, 339, 347, 114, + 113, 115, 116, nil, nil, 244, nil, nil, nil, nil, + nil, nil, 51, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, 317, 112, 120, 121, nil, 104, 105, + 47, 48, 46, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 237, nil, nil, 243, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, 312, nil, 50, nil, + nil, 318, nil, nil, nil, nil, nil, 242, nil, nil, + nil, nil, 102, 315, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 44, 45, nil, 75, nil, 73, 74, 76, 33, 34, + 79, 80, nil, nil, nil, nil, nil, 84, 31, 30, + 114, 113, 115, 116, nil, nil, 244, nil, nil, nil, + nil, nil, nil, 51, nil, nil, 118, 117, 119, 108, + 64, 110, 109, 111, nil, 112, 120, 121, nil, 104, + 105, 47, 48, 46, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 237, nil, nil, 243, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 50, + nil, nil, nil, nil, nil, nil, nil, nil, 242, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 44, 45, nil, 75, nil, 73, 74, 76, 33, + 34, 79, 80, nil, nil, nil, nil, nil, 84, 31, + 30, 114, 113, 115, 116, nil, nil, 244, nil, nil, + nil, nil, nil, nil, 51, nil, nil, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 47, 48, 46, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 237, nil, nil, 243, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 50, nil, nil, nil, nil, nil, nil, nil, nil, 242, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 44, 45, nil, 75, nil, 73, 74, 76, + 33, 34, 79, 80, nil, nil, nil, nil, nil, 84, + 31, 30, 114, 113, 115, 116, nil, nil, 244, nil, + nil, nil, nil, nil, nil, 51, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, nil, 112, 120, 121, + nil, 104, 105, 47, 48, 46, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 237, nil, nil, 243, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 50, nil, nil, nil, nil, nil, nil, nil, nil, + 242, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 44, 45, nil, 75, nil, 73, 74, + 76, 33, 34, 79, 80, nil, nil, nil, nil, nil, + 84, 31, 30, 114, 113, 115, 116, nil, nil, 244, + nil, nil, nil, nil, nil, nil, 51, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 47, 48, 46, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 237, nil, nil, 243, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 50, nil, nil, nil, nil, nil, nil, nil, + nil, 242, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 44, 45, nil, 75, nil, 73, + 74, 76, 344, 345, 79, 80, nil, nil, nil, nil, + nil, 84, 339, 347, 114, 113, 115, 116, nil, nil, + 244, nil, nil, nil, nil, nil, nil, 51, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, 317, 112, + 120, 121, nil, 104, 105, 47, 48, 46, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 237, nil, nil, + 243, nil, nil, 66, 67, nil, nil, 68, nil, 742, + nil, 312, nil, 50, nil, nil, 318, nil, nil, nil, + nil, nil, 242, nil, nil, nil, nil, 102, 315, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 44, 515, nil, 75, nil, + 73, 74, 76, 344, 345, 79, 80, nil, nil, nil, + nil, nil, 84, 339, 347, 114, 113, 115, 116, nil, + nil, 244, nil, nil, nil, nil, nil, nil, 51, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 47, 48, 46, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 237, nil, + nil, 243, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 50, nil, nil, nil, nil, nil, + nil, nil, nil, 242, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 44, 45, nil, 75, + nil, 73, 74, 76, 344, 345, 79, 80, nil, nil, + nil, nil, nil, 84, 339, 347, 114, 113, 115, 116, + nil, nil, 244, nil, nil, nil, nil, nil, nil, 51, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, 47, 48, 46, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 237, + nil, nil, 243, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 50, nil, nil, nil, nil, + nil, nil, nil, nil, 242, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 44, 45, nil, + 75, nil, 73, 74, 76, 344, 345, 79, 80, nil, + nil, nil, nil, nil, 84, 339, 347, 114, 113, 115, + 116, nil, nil, 244, nil, nil, nil, nil, nil, nil, + 51, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 47, 48, + 46, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 237, nil, nil, 243, nil, nil, 66, 67, nil, nil, + 68, nil, 434, nil, nil, nil, 50, nil, nil, nil, + nil, nil, nil, nil, nil, 242, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 44, 45, + nil, 75, nil, 73, 74, 76, 344, 345, 79, 80, + nil, nil, nil, nil, nil, 84, 339, 347, 114, 113, + 115, 116, nil, nil, 244, nil, nil, nil, nil, nil, + nil, 51, nil, nil, 118, 117, 119, 108, 64, 110, + 109, 111, nil, 112, 120, 121, nil, 104, 105, 47, + 48, 46, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 237, nil, nil, 243, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 50, nil, nil, + nil, nil, nil, nil, nil, nil, 242, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 44, + 45, nil, 75, nil, 73, 74, 76, 33, 34, 79, + 80, nil, nil, nil, nil, nil, 84, 31, 30, 114, + 113, 115, 116, nil, nil, 21, nil, nil, nil, nil, + nil, nil, 51, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 47, 48, 46, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 237, nil, nil, 243, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 50, nil, + nil, nil, nil, nil, nil, nil, nil, 22, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 44, 45, nil, 75, nil, 73, 74, 76, 344, 345, + 79, 80, nil, nil, nil, nil, nil, 84, 339, 347, + 114, 113, 115, 116, nil, nil, 244, nil, nil, nil, + nil, nil, nil, 51, nil, nil, 118, 117, 119, 108, + 64, 110, 109, 111, nil, 112, 120, 121, nil, 104, + 105, 47, 48, 46, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 237, nil, nil, 243, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 50, + nil, nil, nil, nil, nil, nil, nil, nil, 242, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 44, 45, nil, 75, nil, 73, 74, 76, 33, + 34, 79, 80, nil, nil, nil, nil, nil, 84, 31, + 30, 114, 113, 115, 116, nil, nil, 244, nil, nil, + nil, nil, nil, nil, 51, nil, nil, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 47, 48, 46, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 237, nil, nil, 243, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 50, nil, nil, nil, nil, nil, nil, nil, nil, 242, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 44, 45, nil, 75, nil, 73, 74, 76, + 344, 345, 79, 80, nil, nil, nil, nil, nil, 84, + 339, 347, 114, 113, 115, 116, nil, nil, 244, nil, + nil, nil, nil, nil, nil, 51, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, nil, 112, 120, 121, + nil, 104, 105, 47, 48, 46, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 237, nil, nil, 243, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 50, nil, nil, nil, nil, nil, nil, nil, nil, + 242, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 44, 45, nil, 75, nil, 73, 74, + 76, 344, 345, 79, 80, nil, nil, nil, nil, nil, + 84, 339, 347, 114, 113, 115, 116, nil, nil, 244, + nil, nil, nil, nil, nil, nil, 51, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 47, 48, 46, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 237, nil, nil, 243, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 50, nil, nil, nil, nil, nil, nil, nil, + nil, 242, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 44, 45, nil, 75, nil, 73, + 74, 76, 344, 345, 79, 80, nil, nil, nil, nil, + nil, 84, 339, 347, 114, 113, 115, 116, nil, nil, + 244, nil, nil, nil, nil, nil, nil, 51, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, nil, 112, + 120, 121, nil, 104, 105, 47, 48, 46, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 237, nil, nil, + 243, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 50, nil, nil, nil, nil, nil, nil, + nil, nil, 242, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 44, 45, nil, 75, nil, + 73, 74, 76, 344, 345, 79, 80, nil, nil, nil, + nil, nil, 84, 339, 347, 114, 113, 115, 116, nil, + nil, 244, nil, nil, nil, nil, nil, nil, 51, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 47, 48, 46, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 237, nil, + nil, 243, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 50, nil, nil, nil, nil, nil, + nil, nil, nil, 242, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 44, 45, nil, 75, + nil, 73, 74, 76, 344, 345, 79, 80, nil, nil, + nil, nil, nil, 84, 339, 347, 114, 113, 115, 116, + nil, nil, 244, nil, nil, nil, nil, nil, nil, 51, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, 47, 48, 46, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 237, + nil, nil, 243, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 50, nil, nil, nil, nil, + nil, nil, nil, nil, 242, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 44, 45, nil, + 75, nil, 73, 74, 76, 344, 345, 79, 80, nil, + nil, nil, nil, nil, 84, 339, 347, 114, 113, 115, + 116, nil, nil, 244, nil, nil, nil, nil, nil, nil, + 51, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 47, 48, + 46, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 237, nil, nil, 243, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 50, nil, nil, nil, + nil, nil, nil, nil, nil, 242, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 44, 45, + nil, 75, nil, 73, 74, 76, 344, 345, 79, 80, + nil, nil, nil, nil, nil, 84, 339, 347, 114, 113, + 115, 116, nil, nil, 244, nil, nil, nil, nil, nil, + nil, 51, nil, nil, 118, 117, 119, 108, 64, 110, + 109, 111, nil, 112, 120, 121, nil, 104, 105, 47, + 48, 46, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 237, nil, nil, 243, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 50, nil, nil, + nil, nil, nil, nil, nil, nil, 242, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 44, + 45, nil, 75, nil, 73, 74, 76, 33, 34, 79, + 80, nil, nil, nil, nil, nil, 84, 31, 30, 114, + 113, 115, 116, nil, nil, 21, nil, nil, nil, nil, + nil, nil, 51, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 47, 48, 46, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 237, nil, nil, 243, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 50, nil, + nil, nil, nil, nil, nil, nil, nil, 22, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 44, 45, nil, 75, nil, 73, 74, 76, 344, 345, + 79, 80, nil, nil, nil, nil, nil, 84, 339, 347, + 114, 113, 115, 116, nil, nil, 244, nil, nil, nil, + nil, nil, nil, 51, nil, nil, 118, 117, 119, 108, + 64, 110, 109, 111, nil, 112, 120, 121, nil, 104, + 105, 47, 48, 46, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 237, nil, nil, 243, nil, nil, 66, + 67, nil, nil, 68, nil, 742, nil, nil, nil, 50, + nil, nil, nil, nil, nil, nil, nil, nil, 242, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 44, 45, nil, 75, nil, 73, 74, 76, 344, + 345, 79, 80, nil, nil, nil, nil, nil, 84, 339, + 347, 114, 113, 115, 116, nil, nil, 244, nil, nil, + nil, nil, nil, nil, 51, nil, nil, 118, 117, 119, + 108, 64, 110, 109, 111, 317, 112, 120, 121, nil, + 104, 105, 47, 48, 46, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 237, nil, nil, 243, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, 312, nil, + 50, nil, nil, 318, nil, nil, nil, nil, nil, 242, + nil, nil, nil, nil, 102, 315, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 44, 45, nil, 75, nil, 73, 74, 76, + 344, 345, 79, 80, nil, nil, nil, nil, nil, 84, + 339, 347, 114, 113, 115, 116, nil, nil, 244, nil, + nil, nil, nil, nil, nil, 51, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, nil, 112, 120, 121, + nil, 104, 105, 47, 48, 46, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 237, nil, nil, 243, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 50, nil, nil, nil, nil, nil, nil, nil, nil, + 242, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 44, 45, nil, 75, nil, 73, 74, + 76, 33, 34, 79, 80, nil, nil, nil, nil, nil, + 84, 31, 30, 114, 113, 115, 116, nil, nil, 21, + nil, nil, nil, nil, nil, nil, 51, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 47, 48, 46, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 237, nil, nil, 243, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 50, nil, nil, nil, nil, nil, nil, nil, + nil, 22, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 44, 45, nil, 75, nil, 73, + 74, 76, 33, 34, 79, 80, nil, nil, nil, nil, + nil, 84, 31, 30, 114, 113, 115, 116, nil, nil, + 21, nil, nil, nil, nil, nil, nil, 51, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, nil, 112, + 120, 121, nil, 104, 105, 47, 48, 46, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 237, nil, nil, + 243, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 50, nil, nil, nil, nil, nil, nil, + nil, nil, 22, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 44, 45, nil, 75, nil, + 73, 74, 76, 33, 34, 79, 80, nil, nil, nil, + nil, nil, 84, 31, 30, 114, 113, 115, 116, nil, + nil, 244, nil, nil, nil, nil, nil, nil, 51, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, 317, + 112, 120, 121, nil, 104, 105, 47, 48, 46, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 237, nil, + nil, 243, nil, nil, 66, 67, nil, nil, 68, nil, + 314, nil, 312, nil, 50, nil, nil, 318, nil, nil, + nil, nil, nil, 242, nil, nil, nil, nil, 102, 315, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 44, 45, nil, 75, + nil, 73, 74, 76, 344, 345, 79, 80, nil, nil, + nil, nil, nil, 84, 339, 347, 114, 113, 115, 116, + nil, nil, 244, nil, nil, nil, nil, nil, nil, 340, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, nil, nil, 348, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 336, + nil, nil, 332, nil, nil, 66, 67, nil, nil, 68, + nil, 331, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, nil, nil, nil, + 75, nil, 73, 74, 76, 344, 345, 79, 80, nil, + nil, nil, nil, nil, 84, 339, 347, 114, 113, 115, + 116, nil, nil, 244, nil, nil, nil, nil, nil, nil, + 340, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, nil, nil, + 348, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 336, nil, nil, 243, nil, nil, 66, 67, nil, nil, + 68, nil, nil, 582, nil, 579, 578, 577, 587, 580, + nil, nil, nil, nil, nil, nil, nil, nil, 590, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 350, nil, + 585, 85, nil, 92, 106, 107, 81, 82, 83, nil, + 65, 598, 597, nil, 71, 72, 591, nil, nil, 75, + nil, 73, 74, 76, 344, 345, 79, 80, nil, nil, + nil, nil, nil, 84, 339, 347, 114, 113, 115, 116, + nil, nil, 244, nil, nil, nil, nil, nil, nil, 340, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, nil, nil, 348, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 393, + nil, nil, 36, nil, nil, 66, 67, nil, nil, 68, + nil, 38, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, nil, nil, nil, + 75, nil, 73, 74, 76, 344, 345, 79, 80, nil, + nil, nil, nil, nil, 84, 339, 347, 114, 113, 115, + 116, nil, nil, 244, nil, nil, nil, nil, nil, nil, + 340, nil, nil, 118, 117, 119, 398, 64, 110, 109, + 399, nil, 112, 120, 121, nil, 104, 105, nil, nil, + 348, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 405, nil, nil, + 400, nil, nil, 243, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, nil, nil, + nil, 75, nil, 73, 74, 76, 344, 345, 79, 80, + nil, nil, nil, nil, nil, 84, 339, 347, 114, 113, + 115, 116, nil, nil, 244, nil, nil, nil, nil, nil, + nil, 340, nil, nil, 118, 117, 119, 398, 64, 110, + 109, 399, nil, 112, 120, 121, nil, 104, 105, nil, + nil, 348, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 400, nil, nil, 243, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 344, 345, 79, + 80, nil, nil, nil, nil, nil, 84, 339, 347, 114, + 113, 115, 116, nil, nil, 244, nil, nil, nil, nil, + nil, nil, 340, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + nil, nil, 348, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 336, nil, nil, 243, nil, nil, 66, 67, + nil, nil, 68, nil, nil, 582, nil, 579, 578, 577, + 587, 580, nil, nil, nil, nil, nil, nil, nil, nil, + 590, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 543, nil, 585, 85, nil, 92, 106, 107, 81, 82, + 83, nil, 65, 598, 597, nil, 71, 72, 591, nil, + nil, 75, nil, 73, 74, 76, 344, 345, 79, 80, + nil, nil, nil, nil, nil, 84, 339, 347, 114, 113, + 115, 116, nil, nil, 244, nil, nil, nil, nil, nil, + nil, 340, nil, nil, 118, 117, 119, 108, 64, 110, + 109, 111, nil, 112, 120, 121, nil, 104, 105, nil, + nil, 348, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 336, nil, nil, 332, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 344, 345, 79, + 80, nil, nil, nil, nil, nil, 84, 339, 347, 114, + 113, 115, 116, nil, nil, 244, nil, nil, nil, nil, + nil, nil, 340, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + nil, nil, 348, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 336, nil, nil, 332, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + nil, nil, nil, 75, nil, 73, 74, 76, 344, 345, + 79, 80, nil, nil, nil, nil, nil, 84, 339, 347, + 114, 113, 115, 116, nil, nil, 244, nil, nil, nil, + nil, nil, nil, 340, nil, nil, 118, 117, 119, 108, + 64, 110, 109, 111, nil, 112, 120, 121, nil, 104, + 105, nil, nil, 348, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 336, nil, nil, 332, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, nil, nil, nil, 75, nil, 73, 74, 76, 344, + 345, 79, 80, nil, nil, nil, nil, nil, 84, 339, + 347, 114, 113, 115, 116, nil, nil, 244, nil, nil, + nil, nil, nil, nil, 340, nil, nil, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, nil, nil, 348, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 336, nil, nil, 332, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 344, 345, 79, 80, nil, nil, nil, nil, nil, 84, + 339, 347, 114, 113, 115, 116, nil, nil, 244, nil, + nil, nil, nil, nil, nil, 340, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, nil, 112, 120, 121, + nil, 104, 105, nil, nil, 348, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 336, nil, nil, 332, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 344, 345, 79, 80, nil, nil, nil, nil, nil, + 84, 339, 347, 114, 113, 115, 116, nil, nil, 244, + nil, nil, nil, nil, nil, nil, 340, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, nil, nil, 348, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1105, nil, nil, 243, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, nil, nil, nil, 75, nil, 73, + 74, 76, 344, 345, 79, 80, nil, nil, nil, nil, + nil, 84, 339, 347, 114, 113, 115, 116, nil, nil, + 244, nil, nil, nil, nil, nil, nil, 340, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, nil, 112, + 120, 121, nil, 104, 105, nil, nil, 348, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 1111, nil, nil, + 243, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 344, 345, 79, 80, nil, nil, nil, + nil, nil, 84, 339, 347, 114, 113, 115, 116, nil, + nil, 244, nil, nil, nil, nil, nil, nil, 340, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, nil, nil, 348, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 1105, nil, + nil, 243, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, nil, nil, nil, 85, + nil, 92, 106, 107, 185, 196, 186, 209, 182, 202, + 192, 191, 212, 213, 207, 190, 189, 184, 210, 214, + 215, 194, 183, 197, 201, 203, 195, 188, nil, nil, + nil, 204, 211, 206, 205, 198, 208, 193, 181, 200, + 199, nil, nil, nil, nil, nil, 180, 187, 178, 179, + 175, 176, 177, 138, 140, 137, nil, 139, nil, nil, + nil, nil, nil, nil, nil, 169, 170, nil, 166, 148, + 149, 150, 157, 154, 156, nil, nil, 151, 152, nil, + nil, nil, 171, 172, 158, 159, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 163, + 162, nil, 147, 168, 165, 164, 173, 160, 161, 155, + 153, 145, 167, 146, nil, nil, 174, 102, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 101, 185, 196, 186, 209, 182, 202, 192, 191, + 212, 213, 207, 190, 189, 184, 210, 214, 215, 194, + 183, 197, 201, 203, 195, 188, nil, nil, nil, 204, + 211, 206, 205, 198, 208, 193, 181, 200, 199, nil, + nil, nil, nil, nil, 180, 187, 178, 179, 175, 176, + 177, 138, 140, nil, nil, 139, nil, nil, nil, nil, + nil, nil, nil, 169, 170, nil, 166, 148, 149, 150, + 157, 154, 156, nil, nil, 151, 152, nil, nil, nil, + 171, 172, 158, 159, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 163, 162, nil, + 147, 168, 165, 164, 173, 160, 161, 155, 153, 145, + 167, 146, nil, nil, 174, 102, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 101, + 185, 196, 186, 209, 182, 202, 192, 191, 212, 213, + 207, 190, 189, 184, 210, 214, 215, 194, 183, 197, + 201, 203, 195, 188, nil, nil, nil, 204, 211, 206, + 205, 198, 208, 193, 181, 200, 199, nil, nil, nil, + nil, nil, 180, 187, 178, 179, 175, 176, 177, 138, + 140, nil, nil, 139, nil, nil, nil, nil, nil, nil, + nil, 169, 170, nil, 166, 148, 149, 150, 157, 154, + 156, nil, nil, 151, 152, nil, nil, nil, 171, 172, + 158, 159, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 163, 162, nil, 147, 168, + 165, 164, 173, 160, 161, 155, 153, 145, 167, 146, + nil, nil, 174, 102, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 101, 185, 196, + 186, 209, 182, 202, 192, 191, 212, 213, 207, 190, + 189, 184, 210, 214, 215, 194, 183, 197, 201, 203, + 195, 188, nil, nil, nil, 204, 211, 206, 205, 198, + 208, 193, 181, 200, 199, nil, nil, nil, nil, nil, + 180, 187, 178, 179, 175, 176, 177, 138, 140, nil, + nil, 139, nil, nil, nil, nil, nil, nil, nil, 169, + 170, nil, 166, 148, 149, 150, 157, 154, 156, nil, + nil, 151, 152, nil, nil, nil, 171, 172, 158, 159, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 163, 162, nil, 147, 168, 165, 164, + 173, 160, 161, 155, 153, 145, 167, 146, nil, nil, + 174, 102, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 101, 185, 196, 186, 209, + 182, 202, 192, 191, 212, 213, 207, 190, 189, 184, + 210, 214, 215, 194, 183, 197, 201, 203, 195, 188, + nil, nil, nil, 204, 211, 206, 284, 283, 285, 282, + 181, 200, 199, nil, nil, nil, nil, nil, 180, 187, + 178, 179, 279, 280, 281, 277, 140, 110, 109, 278, + nil, 112, nil, nil, nil, nil, nil, 169, 170, nil, + 166, 148, 149, 150, 157, 154, 156, nil, nil, 151, + 152, nil, nil, nil, 171, 172, 158, 159, nil, nil, + nil, nil, nil, 289, nil, nil, nil, nil, nil, nil, + nil, 163, 162, nil, 147, 168, 165, 164, 173, 160, + 161, 155, 153, 145, 167, 146, nil, nil, 174, 114, + 113, 115, 116, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 118, 117, 119, 719, nil, + nil, 582, 722, 579, 578, 577, 587, 580, 104, 105, + nil, nil, 348, nil, nil, nil, 590, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 721, nil, nil, 703, nil, nil, 585, 701, + nil, nil, 702, nil, nil, nil, nil, 595, 594, 598, + 597, nil, nil, nil, 591, nil, nil, nil, 720, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, 114, 113, 115, + 116, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 707, 708, nil, 118, 117, 119, 719, nil, nil, 582, + 722, 579, 578, 577, 587, 580, 104, 105, nil, nil, + 348, nil, nil, nil, 590, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 721, nil, nil, 703, nil, nil, 585, 701, nil, nil, + 702, nil, nil, nil, nil, 595, 594, 598, 597, nil, + nil, nil, 591, nil, nil, nil, 720, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, 114, 113, 115, 116, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 707, 708, + nil, 118, 117, 119, 719, nil, nil, 582, 722, 579, + 578, 577, 587, 580, 104, 105, nil, nil, 348, nil, + nil, nil, 590, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 721, nil, + nil, 703, nil, nil, 585, 701, nil, nil, 702, nil, + 885, nil, nil, 595, 594, 598, 597, nil, nil, nil, + 591, nil, nil, nil, 720, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, 232, nil, nil, nil, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 707, 708, 185, 196, + 186, 209, 182, 202, 192, 191, 212, 213, 207, 190, + 189, 184, 210, 214, 215, 194, 183, 197, 201, 203, + 195, 188, nil, nil, nil, 204, 211, 206, 205, 198, + 208, 193, 181, 200, 199, nil, nil, nil, nil, nil, + 180, 187, 178, 179, 175, 176, 177, 138, 140, nil, + nil, 139, nil, nil, nil, nil, nil, nil, nil, 169, + 170, nil, 166, 148, 149, 150, 157, 154, 156, nil, + nil, 151, 152, nil, nil, nil, 171, 172, 158, 159, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 163, 162, nil, 147, 168, 165, 164, + 173, 160, 161, 155, 153, 145, 167, 146, nil, nil, + 174, 114, 113, 115, 116, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 118, 117, 119, + 719, nil, nil, 582, 722, 579, 578, 577, 587, 580, + 104, 105, nil, nil, 348, nil, nil, nil, 590, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 721, nil, nil, 703, nil, nil, + 585, 701, nil, nil, 702, nil, nil, nil, nil, 595, + 594, 598, 597, nil, nil, nil, 591, nil, nil, nil, + 720, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, 114, + 113, 115, 116, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 707, 708, nil, 118, 117, 119, 719, nil, + nil, nil, 722, 986, nil, nil, nil, nil, 104, 105, + nil, nil, 348, 590, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 721, nil, nil, 703, nil, nil, nil, 701, + nil, nil, 702, nil, 885, nil, nil, nil, nil, nil, + nil, 591, nil, nil, nil, nil, nil, nil, 720, nil, + nil, nil, 102, 987, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, 114, 113, 115, + 116, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 707, 708, nil, 118, 117, 119, 719, nil, nil, nil, + 722, 986, nil, nil, nil, nil, 104, 105, nil, nil, + 348, 590, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 721, nil, nil, 703, nil, nil, nil, 701, nil, nil, + 702, nil, 885, nil, nil, nil, nil, nil, nil, 591, + nil, nil, nil, nil, nil, nil, 720, nil, nil, nil, + 102, 987, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, 114, 113, 115, 116, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 707, 708, + nil, 118, 117, 119, 719, nil, nil, 582, 722, 579, + 578, 577, 587, 580, 104, 105, nil, nil, 348, nil, + nil, nil, 590, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 721, nil, + nil, 703, nil, nil, 585, 701, nil, nil, 702, nil, + 999, nil, nil, nil, nil, 598, 597, nil, nil, nil, + 591, nil, nil, nil, 720, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, 114, 113, 115, 116, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 707, 708, nil, 118, + 117, 119, 719, nil, nil, 582, 722, 579, 578, 577, + 587, 580, 104, 105, nil, nil, 348, nil, nil, nil, + 590, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 721, nil, nil, 703, + nil, nil, 585, 701, nil, nil, 702, nil, nil, nil, + nil, 595, 594, 598, 597, nil, nil, nil, 591, nil, + nil, nil, 720, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, 114, 113, 115, 116, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 707, 708, nil, 118, 117, 119, + 719, nil, nil, nil, 722, 986, nil, nil, nil, nil, + 104, 105, nil, nil, 348, 590, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 721, nil, nil, 703, nil, nil, + nil, 701, nil, nil, 702, nil, 885, nil, nil, nil, + nil, nil, nil, 591, nil, nil, nil, nil, nil, nil, + 720, nil, nil, nil, 102, 987, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, 114, + 113, 115, 116, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 707, 708, nil, 118, 117, 119, 719, nil, + nil, 582, 722, 579, 578, 577, 587, 580, 104, 105, + nil, nil, 348, nil, nil, nil, 590, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 721, nil, nil, 703, nil, nil, 585, 701, + nil, nil, 702, nil, nil, nil, nil, 595, 594, 598, + 597, nil, nil, nil, 591, nil, nil, nil, 720, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, 114, 113, 115, + 116, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 707, 708, nil, 118, 117, 119, 719, nil, nil, 582, + 722, 579, 578, 577, 587, 580, 104, 105, nil, nil, + 348, nil, nil, nil, 590, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 721, nil, nil, 703, nil, nil, 585, 701, nil, nil, + 702, nil, nil, nil, nil, nil, nil, 598, 597, nil, + nil, nil, 591, nil, nil, nil, 720, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, 114, 113, 115, 116, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 707, 708, + nil, 118, 117, 119, 719, nil, nil, 582, 722, 579, + 578, 577, 587, 580, 104, 105, nil, nil, 348, nil, + nil, nil, 590, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 721, nil, + nil, 703, nil, nil, 585, 701, nil, nil, 702, nil, + nil, nil, nil, nil, nil, 598, 597, nil, nil, nil, + 591, nil, nil, nil, 720, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, 114, 113, 115, 116, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 707, 708, nil, 118, + 117, 119, 719, nil, nil, 582, 722, 579, 578, 577, + 587, 580, 104, 105, nil, nil, 348, nil, nil, nil, + 590, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 721, nil, nil, 703, + nil, nil, 585, 701, nil, nil, 702, nil, 885, nil, + nil, 595, 594, 598, 597, nil, nil, nil, 591, nil, + nil, nil, 720, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, 114, 113, 115, 116, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 707, 708, nil, 118, 117, 119, + 719, nil, nil, 582, 722, 579, 578, 577, 587, 580, + 104, 105, nil, nil, 348, nil, nil, nil, 590, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 721, nil, nil, 703, nil, nil, + 585, 701, nil, nil, 702, nil, nil, nil, nil, nil, + nil, 598, 597, nil, nil, nil, 591, nil, nil, nil, + 720, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, 114, + 113, 115, 116, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 707, 708, nil, 118, 117, 119, 719, nil, + nil, 582, 722, 579, 578, 577, 587, 580, 104, 105, + nil, nil, 348, nil, nil, nil, 590, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 721, nil, nil, 703, nil, nil, 585, 701, + nil, nil, 702, nil, 885, nil, nil, nil, nil, 598, + 597, nil, nil, nil, 591, nil, nil, nil, 720, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, 114, 113, 115, + 116, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 707, 708, nil, 118, 117, 119, 719, nil, nil, 582, + 722, 579, 578, 577, 587, 580, 104, 105, nil, nil, + 348, nil, nil, nil, 590, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 721, nil, nil, 703, nil, nil, 585, 701, nil, nil, + 702, nil, nil, nil, nil, nil, nil, 598, 597, nil, + nil, nil, 591, nil, nil, nil, 720, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, 114, 113, 115, 116, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 707, 708, + nil, 118, 117, 119, 719, nil, nil, nil, 722, nil, + nil, nil, nil, nil, 104, 105, nil, nil, 348, nil, + nil, nil, nil, nil, nil, nil, 114, 113, 115, 116, + nil, nil, nil, nil, nil, nil, nil, nil, 721, nil, + nil, 703, 118, 117, 119, 701, nil, nil, 702, nil, + nil, nil, nil, nil, nil, 104, 105, nil, nil, 348, + nil, nil, nil, nil, 720, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, nil, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 707, 708, 582, nil, + 579, 578, 577, 587, 580, nil, nil, nil, nil, 102, + 90, 93, 94, 590, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, 114, 113, 115, 116, nil, nil, + 85, nil, 92, 106, 107, 585, nil, nil, nil, nil, + 118, 117, 119, nil, nil, nil, 598, 597, nil, nil, + nil, 591, nil, 104, 105, nil, nil, 348, 114, 113, + 115, 116, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 118, 117, 119, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 104, 105, nil, + nil, 348, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, nil, nil, nil, 85, nil, + 92, 106, 107, nil, nil, nil, nil, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, 456, 460, nil, nil, + 457, nil, 85, nil, 92, 106, 107, nil, 169, 170, + nil, 166, 148, 149, 150, 157, 154, 156, nil, nil, + 151, 152, nil, nil, nil, 171, 172, 158, 159, nil, + nil, nil, nil, nil, 296, nil, nil, nil, nil, nil, + nil, nil, 163, 162, nil, 147, 168, 165, 164, 173, + 160, 161, 155, 153, 145, 167, 146, 463, 467, 174, + nil, 462, nil, nil, nil, nil, nil, nil, nil, 169, + 170, nil, 166, 148, 149, 150, 157, 154, 156, nil, + nil, 151, 152, nil, nil, nil, 171, 172, 158, 159, + nil, nil, nil, nil, nil, 296, nil, nil, nil, nil, + nil, nil, nil, 163, 162, nil, 147, 168, 165, 164, + 173, 160, 161, 155, 153, 145, 167, 146, 511, 460, + 174, nil, 512, nil, nil, nil, nil, nil, nil, nil, + 169, 170, nil, 166, 148, 149, 150, 157, 154, 156, + nil, nil, 151, 152, nil, nil, nil, 171, 172, 158, + 159, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 163, 162, nil, 147, 168, 165, + 164, 173, 160, 161, 155, 153, 145, 167, 146, 690, + 460, 174, nil, 691, nil, nil, nil, nil, nil, nil, + nil, 169, 170, nil, 166, 148, 149, 150, 157, 154, + 156, nil, nil, 151, 152, nil, nil, nil, 171, 172, + 158, 159, nil, nil, nil, nil, nil, 296, nil, nil, + nil, nil, nil, nil, nil, 163, 162, nil, 147, 168, + 165, 164, 173, 160, 161, 155, 153, 145, 167, 146, + 692, 467, 174, nil, 693, nil, nil, nil, nil, nil, + nil, nil, 169, 170, nil, 166, 148, 149, 150, 157, + 154, 156, nil, nil, 151, 152, nil, nil, nil, 171, + 172, 158, 159, nil, nil, nil, nil, nil, 296, nil, + nil, nil, nil, nil, nil, nil, 163, 162, nil, 147, + 168, 165, 164, 173, 160, 161, 155, 153, 145, 167, + 146, 752, 460, 174, nil, 753, nil, nil, nil, nil, + nil, nil, nil, 169, 170, nil, 166, 148, 149, 150, + 157, 154, 156, nil, nil, 151, 152, nil, nil, nil, + 171, 172, 158, 159, nil, nil, nil, nil, nil, 296, + nil, nil, nil, nil, nil, nil, nil, 163, 162, nil, + 147, 168, 165, 164, 173, 160, 161, 155, 153, 145, + 167, 146, 755, 467, 174, nil, 756, nil, nil, nil, + nil, nil, nil, nil, 169, 170, nil, 166, 148, 149, + 150, 157, 154, 156, nil, nil, 151, 152, nil, nil, + nil, 171, 172, 158, 159, nil, nil, nil, nil, nil, + 296, nil, nil, nil, nil, nil, nil, nil, 163, 162, + nil, 147, 168, 165, 164, 173, 160, 161, 155, 153, + 145, 167, 146, 690, 460, 174, nil, 691, nil, nil, + nil, nil, nil, nil, nil, 169, 170, nil, 166, 148, + 149, 150, 157, 154, 156, nil, nil, 151, 152, nil, + nil, nil, 171, 172, 158, 159, nil, nil, nil, nil, + nil, 296, nil, nil, nil, nil, nil, nil, nil, 163, + 162, nil, 147, 168, 165, 164, 173, 160, 161, 155, + 153, 145, 167, 146, 692, 467, 174, nil, 693, nil, + nil, nil, nil, nil, nil, nil, 169, 170, nil, 166, + 148, 149, 150, 157, 154, 156, nil, nil, 151, 152, + nil, nil, nil, 171, 172, 158, 159, nil, nil, nil, + nil, nil, 296, nil, nil, nil, nil, nil, nil, nil, + 163, 162, nil, 147, 168, 165, 164, 173, 160, 161, + 155, 153, 145, 167, 146, 814, 460, 174, nil, 815, + nil, nil, nil, nil, nil, nil, nil, 169, 170, nil, + 166, 148, 149, 150, 157, 154, 156, nil, nil, 151, + 152, nil, nil, nil, 171, 172, 158, 159, nil, nil, + nil, nil, nil, 296, nil, nil, nil, nil, nil, nil, + nil, 163, 162, nil, 147, 168, 165, 164, 173, 160, + 161, 155, 153, 145, 167, 146, 816, 467, 174, nil, + 817, nil, nil, nil, nil, nil, nil, nil, 169, 170, + nil, 166, 148, 149, 150, 157, 154, 156, nil, nil, + 151, 152, nil, nil, nil, 171, 172, 158, 159, nil, + nil, nil, nil, nil, 296, nil, nil, nil, nil, nil, + nil, nil, 163, 162, nil, 147, 168, 165, 164, 173, + 160, 161, 155, 153, 145, 167, 146, 819, 467, 174, + nil, 820, nil, nil, nil, nil, nil, nil, nil, 169, + 170, nil, 166, 148, 149, 150, 157, 154, 156, nil, + nil, 151, 152, nil, nil, nil, 171, 172, 158, 159, + nil, nil, nil, nil, nil, 296, nil, nil, nil, nil, + nil, nil, nil, 163, 162, nil, 147, 168, 165, 164, + 173, 160, 161, 155, 153, 145, 167, 146, 511, 460, + 174, nil, 512, nil, nil, nil, nil, nil, nil, nil, + 169, 170, nil, 166, 148, 149, 150, 157, 154, 156, + nil, nil, 151, 152, nil, nil, nil, 171, 172, 158, + 159, nil, nil, nil, nil, nil, 296, nil, nil, nil, + nil, nil, nil, nil, 163, 162, nil, 147, 168, 165, + 164, 173, 160, 161, 155, 153, 145, 167, 146, 846, + 460, 174, nil, 847, nil, nil, nil, nil, nil, nil, + nil, 169, 170, nil, 166, 148, 149, 150, 157, 154, + 156, nil, nil, 151, 152, nil, nil, nil, 171, 172, + 158, 159, nil, nil, nil, nil, nil, 296, nil, nil, + nil, nil, nil, nil, nil, 163, 162, nil, 147, 168, + 165, 164, 173, 160, 161, 155, 153, 145, 167, 146, + 849, 467, 174, nil, 848, nil, nil, nil, nil, nil, + nil, nil, 169, 170, nil, 166, 148, 149, 150, 157, + 154, 156, nil, nil, 151, 152, nil, nil, nil, 171, + 172, 158, 159, nil, nil, nil, nil, nil, 296, nil, + nil, nil, nil, nil, nil, nil, 163, 162, nil, 147, + 168, 165, 164, 173, 160, 161, 155, 153, 145, 167, + 146, 1190, 467, 174, nil, 1189, nil, nil, nil, nil, + nil, nil, nil, 169, 170, nil, 166, 148, 149, 150, + 157, 154, 156, nil, nil, 151, 152, nil, nil, nil, + 171, 172, 158, 159, nil, nil, nil, nil, nil, 296, + nil, nil, nil, nil, nil, nil, nil, 163, 162, nil, + 147, 168, 165, 164, 173, 160, 161, 155, 153, 145, + 167, 146, 1193, 460, 174, nil, 1194, nil, nil, nil, + nil, nil, nil, nil, 169, 170, nil, 166, 148, 149, + 150, 157, 154, 156, nil, nil, 151, 152, nil, nil, + nil, 171, 172, 158, 159, nil, nil, nil, nil, nil, + 296, nil, nil, nil, nil, nil, nil, nil, 163, 162, + nil, 147, 168, 165, 164, 173, 160, 161, 155, 153, + 145, 167, 146, 1195, 467, 174, nil, 1196, nil, nil, + nil, nil, nil, nil, nil, 169, 170, nil, 166, 148, + 149, 150, 157, 154, 156, nil, nil, 151, 152, nil, + nil, nil, 171, 172, 158, 159, nil, nil, nil, nil, + nil, 296, nil, nil, nil, nil, nil, nil, nil, 163, + 162, nil, 147, 168, 165, 164, 173, 160, 161, 155, + 153, 145, 167, 146, nil, nil, 174 ] + +racc_action_check = [ + 108, 472, 472, 508, 508, 52, 390, 108, 108, 108, + 1006, 382, 108, 108, 108, 18, 108, 29, 21, 999, + 5, 873, 18, 383, 108, 5, 108, 108, 108, 762, + 762, 18, 592, 414, 391, 394, 108, 108, 812, 108, + 108, 108, 108, 108, 1032, 1052, 1054, 1108, 1109, 872, + 592, 628, 1199, 1006, 1112, 622, 415, 873, 1, 21, + 69, 52, 1199, 622, 814, 815, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 18, 29, 108, 108, 108, 3, 108, 108, 619, 872, + 108, 827, 956, 108, 108, 472, 108, 508, 108, 414, + 108, 999, 108, 108, 29, 108, 108, 108, 108, 108, + 1158, 108, 111, 108, 1193, 390, 730, 638, 638, 111, + 111, 111, 415, 762, 111, 111, 111, 108, 111, 382, + 108, 108, 108, 108, 382, 108, 111, 108, 111, 111, + 111, 383, 108, 391, 394, 108, 383, 69, 111, 111, + 1194, 111, 111, 111, 111, 111, 812, 1195, 1206, 812, + 628, 812, 1032, 1052, 1054, 1108, 1109, 1032, 1052, 1054, + 1108, 1109, 1112, 814, 815, 816, 817, 1112, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 619, 1196, 111, 111, 111, 619, 111, 111, + 827, 956, 111, 730, 321, 111, 111, 702, 111, 321, + 111, 638, 111, 653, 111, 111, 638, 111, 111, 111, + 111, 111, 462, 111, 702, 111, 877, 235, 1158, 462, + 462, 462, 1193, 1158, 1195, 462, 462, 1193, 462, 111, + 816, 817, 111, 111, 111, 111, 462, 111, 27, 111, + 341, 53, 9, 409, 111, 27, 1056, 111, 462, 462, + 752, 462, 462, 462, 462, 462, 46, 46, 1194, 1061, + 1196, 1061, 877, 1194, 753, 1195, 1206, 653, 653, 236, + 1195, 1206, 348, 348, 816, 817, 235, 653, 462, 462, + 462, 462, 462, 462, 462, 462, 462, 462, 462, 462, + 462, 462, 1056, 276, 462, 462, 462, 53, 462, 462, + 276, 1196, 462, 27, 341, 462, 1196, 409, 409, 409, + 462, 12, 462, 655, 462, 462, 752, 462, 462, 462, + 462, 462, 238, 462, 463, 462, 988, 341, 236, 441, + 753, 463, 463, 463, 46, 46, 387, 463, 463, 462, + 463, 387, 462, 462, 988, 462, 14, 462, 463, 463, + 348, 348, 914, 478, 462, 15, 752, 462, 276, 752, + 463, 463, 690, 463, 463, 463, 463, 463, 747, 277, + 753, 752, 374, 753, 755, 374, 277, 655, 655, 531, + 747, 238, 691, 1076, 600, 753, 17, 655, 441, 600, + 463, 463, 463, 463, 463, 463, 463, 463, 463, 463, + 463, 463, 463, 463, 25, 886, 463, 463, 463, 54, + 463, 463, 478, 40, 463, 886, 54, 463, 914, 846, + 1088, 690, 463, 847, 463, 54, 463, 463, 410, 463, + 463, 463, 463, 463, 277, 463, 463, 463, 400, 755, + 755, 691, 400, 531, 531, 531, 411, 1076, 1076, 1076, + 19, 463, 412, 886, 463, 463, 398, 463, 914, 463, + 531, 914, 413, 692, 1076, 886, 463, 16, 16, 463, + 692, 692, 692, 914, 54, 692, 692, 692, 846, 692, + 755, 960, 847, 755, 1088, 1088, 960, 692, 692, 692, + 692, 692, 410, 410, 410, 755, 399, 19, 43, 692, + 692, 1088, 692, 692, 692, 692, 692, 51, 398, 19, + 411, 411, 411, 416, 700, 398, 412, 412, 412, 700, + 398, 869, 375, 700, 398, 375, 413, 413, 413, 692, + 692, 692, 692, 692, 692, 692, 692, 692, 692, 692, + 692, 692, 692, 398, 970, 692, 692, 692, 399, 692, + 692, 381, 381, 692, 721, 399, 692, 692, 721, 692, + 399, 692, 216, 692, 399, 692, 692, 237, 692, 692, + 692, 692, 692, 398, 692, 692, 692, 416, 416, 416, + 869, 234, 278, 399, 279, 280, 49, 49, 234, 278, + 692, 279, 280, 692, 692, 692, 692, 234, 692, 281, + 692, 41, 693, 970, 239, 692, 281, 42, 692, 693, + 693, 693, 240, 399, 693, 693, 693, 282, 693, 704, + 704, 244, 49, 49, 282, 283, 693, 295, 693, 693, + 693, 137, 283, 774, 774, 309, 137, 137, 693, 693, + 352, 693, 693, 693, 693, 693, 234, 278, 41, 279, + 280, 284, 285, 876, 42, 800, 800, 876, 284, 285, + 41, 310, 378, 313, 281, 378, 42, 325, 693, 693, + 693, 693, 693, 693, 693, 693, 693, 693, 693, 693, + 693, 693, 282, 1074, 693, 693, 693, 352, 693, 693, + 283, 456, 693, 1074, 799, 693, 693, 799, 693, 352, + 693, 326, 693, 1131, 693, 693, 1131, 693, 693, 693, + 693, 693, 848, 693, 328, 693, 284, 285, 88, 848, + 848, 848, 1055, 1055, 329, 848, 848, 330, 848, 693, + 88, 1074, 693, 693, 693, 693, 848, 693, 456, 693, + 88, 1165, 1165, 1074, 693, 457, 336, 693, 848, 848, + 456, 848, 848, 848, 848, 848, 339, 340, 342, 343, + 366, 333, 366, 366, 366, 366, 366, 347, 333, 675, + 785, 349, 785, 785, 785, 366, 785, 333, 848, 848, + 848, 848, 848, 848, 848, 848, 848, 848, 848, 848, + 848, 848, 457, 356, 848, 848, 848, 366, 848, 848, + 358, 362, 848, 364, 457, 848, 366, 366, 366, 366, + 848, 368, 848, 366, 848, 848, 675, 848, 848, 848, + 848, 848, 372, 848, 849, 848, 333, 376, 675, 377, + 379, 849, 849, 849, 388, 389, 393, 849, 849, 848, + 849, 395, 848, 848, 404, 848, 424, 848, 849, 849, + 430, 432, 433, 366, 848, 435, 438, 848, 442, 452, + 849, 849, 454, 849, 849, 849, 849, 849, 455, 464, + 474, 488, 768, 334, 768, 768, 768, 768, 768, 942, + 334, 942, 942, 942, 489, 942, 490, 768, 491, 334, + 849, 849, 849, 849, 849, 849, 849, 849, 849, 849, + 849, 849, 849, 849, 516, 517, 849, 849, 849, 768, + 849, 849, 518, 522, 849, 538, 942, 849, 768, 768, + 768, 768, 849, 539, 849, 768, 849, 849, 542, 849, + 849, 849, 849, 849, 771, 849, 849, 849, 334, 544, + 335, 549, 553, 563, 771, 337, 353, 335, 564, 567, + 568, 849, 337, 353, 849, 849, 335, 849, 569, 849, + 392, 337, 353, 570, 571, 768, 849, 392, 573, 849, + 2, 2, 2, 2, 2, 2, 392, 771, 771, 2, + 2, 574, 771, 584, 2, 819, 2, 2, 2, 2, + 2, 2, 2, 8, 8, 8, 8, 8, 2, 2, + 2, 2, 2, 2, 2, 335, 596, 2, 599, 601, + 337, 353, 603, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 392, 2, 2, 2, 402, + 2, 2, 2, 2, 2, 440, 402, 819, 604, 548, + 605, 606, 440, 616, 819, 402, 548, 620, 621, 819, + 623, 440, 650, 819, 2, 548, 658, 2, 660, 667, + 2, 2, 631, 676, 2, 681, 2, 686, 694, 631, + 2, 695, 819, 697, 486, 720, 646, 646, 631, 2, + 646, 646, 646, 723, 2, 2, 2, 2, 724, 2, + 2, 2, 2, 727, 402, 729, 735, 2, 2, 736, + 440, 737, 819, 739, 548, 2, 486, 2, 2, 2, + 486, 486, 2, 2, 36, 36, 36, 36, 36, 36, + 741, 749, 751, 36, 36, 754, 757, 631, 36, 758, + 36, 36, 36, 36, 36, 36, 36, 23, 761, 764, + 783, 784, 36, 36, 36, 36, 36, 36, 36, 786, + 1068, 36, 1068, 1068, 1068, 802, 1068, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 808, + 36, 36, 36, 809, 36, 36, 36, 36, 36, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 756, 23, 23, 813, 822, 23, 23, 756, 36, 826, + 23, 36, 756, 828, 36, 36, 756, 843, 36, 845, + 36, 23, 854, 23, 36, 23, 23, 870, 23, 23, + 23, 23, 23, 36, 23, 878, 879, 883, 36, 36, + 36, 36, 1104, 36, 36, 36, 36, 884, 885, 1104, + 888, 36, 36, 900, 23, 903, 904, 913, 1104, 36, + 918, 36, 36, 36, 921, 756, 36, 36, 135, 135, + 135, 135, 135, 135, 922, 925, 927, 135, 135, 928, + 930, 932, 135, 934, 135, 135, 135, 135, 135, 135, + 135, 324, 324, 324, 324, 324, 135, 135, 135, 135, + 135, 135, 135, 935, 937, 135, 940, 1104, 947, 950, + 445, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 957, 135, 135, 135, 959, 135, 135, + 135, 135, 135, 445, 445, 445, 445, 445, 445, 445, + 445, 445, 445, 445, 820, 445, 445, 966, 967, 445, + 445, 820, 135, 968, 969, 135, 820, 979, 135, 135, + 820, 980, 135, 981, 135, 445, 982, 445, 135, 445, + 445, 991, 445, 445, 445, 445, 445, 135, 445, 992, + 993, 997, 135, 135, 135, 135, 1110, 135, 135, 135, + 135, 998, 1003, 1110, 1013, 135, 135, 1014, 445, 1016, + 445, 1017, 1110, 135, 1018, 135, 135, 135, 1020, 820, + 135, 135, 218, 218, 218, 218, 218, 218, 1021, 1022, + 1048, 218, 218, 1049, 1065, 1075, 218, 1083, 218, 218, + 218, 218, 218, 218, 218, 371, 371, 371, 371, 371, + 218, 218, 218, 218, 218, 218, 218, 1085, 1102, 218, + 1105, 1110, 1111, 1114, 451, 218, 218, 218, 218, 218, + 218, 218, 218, 218, 218, 218, 218, 1115, 218, 218, + 218, 1116, 218, 218, 218, 218, 218, 451, 451, 451, + 451, 451, 451, 451, 451, 451, 451, 451, 1151, 451, + 451, 1117, 1129, 451, 451, 1151, 218, 1130, 1139, 218, + 1091, 1141, 218, 218, 1151, 1144, 218, 1145, 218, 451, + 1091, 451, 218, 451, 451, 1146, 451, 451, 451, 451, + 451, 218, 451, 1147, 1149, 1154, 218, 218, 218, 218, + 1164, 218, 218, 218, 218, 1170, 1175, 1189, 1190, 218, + 218, 1192, 451, 1091, 1091, 1197, 1202, 218, 1091, 218, + 218, 218, 1203, 1151, 218, 218, 243, 243, 243, 243, + 243, 243, 1204, 1205, 1211, 243, 243, 1217, nil, nil, + 243, nil, 243, 243, 243, 243, 243, 243, 243, 536, + 536, 536, 536, 536, 243, 243, 243, 243, 243, 243, + 243, nil, nil, 243, nil, nil, nil, nil, 763, 243, + 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, + 243, nil, 243, 243, 243, nil, 243, 243, 243, 243, + 243, 763, 763, 763, 763, 763, 763, 763, 763, 763, + 763, 763, nil, 763, 763, nil, nil, 763, 763, nil, + 243, nil, nil, 243, nil, nil, 243, 243, nil, nil, + 243, nil, 243, 763, nil, 763, 243, 763, 763, nil, + 763, 763, 763, 763, 763, 243, 763, nil, nil, nil, + 243, 243, 243, 243, nil, 243, 243, 243, 243, nil, + nil, nil, nil, 243, 243, nil, 763, nil, nil, nil, + nil, 243, nil, 243, 243, 243, nil, nil, 243, 243, + 327, 327, 327, 327, 327, 327, nil, nil, nil, 327, + 327, nil, nil, nil, 327, nil, 327, 327, 327, 327, + 327, 327, 327, nil, nil, nil, nil, nil, 327, 327, + 327, 327, 327, 327, 327, nil, nil, 327, nil, nil, + nil, nil, 794, 327, 327, 327, 327, 327, 327, 327, + 327, 327, 327, 327, 327, nil, 327, 327, 327, nil, + 327, 327, 327, 327, 327, 794, 794, 794, 794, 794, + 794, 794, 794, 794, 794, 794, nil, 794, 794, nil, + nil, 794, 794, nil, 327, nil, nil, 327, nil, nil, + 327, 327, nil, nil, 327, nil, 327, 794, nil, 794, + 327, 794, 794, nil, 794, 794, 794, 794, 794, 327, + 794, nil, nil, nil, 327, 327, 327, 327, nil, 327, + 327, 327, 327, nil, nil, nil, nil, 327, 327, nil, + 794, nil, nil, nil, nil, 327, nil, 327, 327, 327, + nil, nil, 327, 327, 332, 332, 332, 332, 332, 332, + nil, nil, nil, 332, 332, nil, nil, nil, 332, nil, + 332, 332, 332, 332, 332, 332, 332, nil, nil, nil, + nil, nil, 332, 332, 332, 332, 332, 332, 332, nil, + 1174, 332, 1174, 1174, 1174, nil, 1174, 332, 332, 332, + 332, 332, 332, 332, 332, 332, 332, 332, 332, nil, + 332, 332, 332, nil, 332, 332, 332, 332, 332, 307, + 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, + nil, 307, 307, nil, nil, 307, 307, nil, 332, nil, + nil, 332, nil, nil, 332, 332, nil, nil, 332, nil, + 332, 307, nil, 307, 332, 307, 307, nil, 307, 307, + 307, 307, 307, 332, 307, nil, nil, nil, 332, 332, + 332, 332, nil, 332, 332, 332, 332, nil, nil, nil, + nil, 332, 332, nil, 307, nil, nil, nil, nil, 332, + nil, 332, 332, 332, nil, nil, 332, 332, 363, 363, + 363, 363, 363, 363, nil, nil, nil, 363, 363, nil, + nil, nil, 363, nil, 363, 363, 363, 363, 363, 363, + 363, nil, nil, nil, nil, nil, 363, 363, 363, 363, + 363, 363, 363, nil, nil, 363, nil, nil, nil, nil, + nil, 363, 363, 363, 363, 363, 363, 363, 363, 363, + 363, 363, 363, nil, 363, 363, 363, nil, 363, 363, + 363, 363, 363, 505, 505, 505, 505, 505, 505, 505, + 505, 505, 505, 505, nil, 505, 505, nil, nil, 505, + 505, nil, 363, nil, nil, 363, nil, nil, 363, 363, + nil, nil, 363, nil, 363, 505, nil, 505, 363, 505, + 505, nil, 505, 505, 505, 505, 505, 363, 505, nil, + nil, nil, 363, 363, 363, 363, nil, 363, 363, 363, + 363, nil, nil, nil, nil, 363, 363, 505, 505, nil, + nil, nil, nil, 363, nil, 363, 363, 363, nil, nil, + 363, 363, 369, 369, 369, 369, 369, 369, nil, nil, + nil, 369, 369, nil, nil, nil, 369, nil, 369, 369, + 369, 369, 369, 369, 369, nil, nil, nil, nil, nil, + 369, 369, 369, 369, 369, 369, 369, nil, nil, 369, + nil, nil, nil, nil, nil, 369, 369, 369, 369, 369, + 369, 369, 369, 369, 369, 369, 369, nil, 369, 369, + 369, nil, 369, 369, 369, 369, 369, 560, 560, 560, + 560, 560, 560, 560, 560, 560, 560, 560, nil, 560, + 560, nil, nil, 560, 560, nil, 369, nil, nil, 369, + nil, nil, 369, 369, nil, nil, 369, nil, 369, 560, + nil, 560, 369, 560, 560, nil, 560, 560, 560, 560, + 560, 369, 560, nil, nil, nil, 369, 369, 369, 369, + nil, 369, 369, 369, 369, nil, nil, nil, nil, 369, + 369, nil, 560, nil, nil, nil, nil, 369, nil, 369, + 369, 369, nil, nil, 369, 369, 370, 370, 370, 370, + 370, 370, nil, nil, nil, 370, 370, nil, nil, nil, + 370, nil, 370, 370, 370, 370, 370, 370, 370, nil, + nil, nil, nil, nil, 370, 370, 370, 370, 370, 370, + 370, nil, nil, 370, nil, nil, nil, nil, nil, 370, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, + 370, nil, 370, 370, 370, nil, 370, 370, 370, 370, + 370, 851, 851, 851, 851, 851, 851, 851, 851, 851, + 851, 851, nil, 851, 851, nil, nil, 851, 851, nil, + 370, nil, nil, 370, nil, nil, 370, 370, nil, nil, + 370, nil, 370, 851, nil, 851, 370, 851, 851, nil, + 851, 851, 851, 851, 851, 370, 851, nil, nil, nil, + 370, 370, 370, 370, nil, 370, 370, 370, 370, nil, + nil, nil, nil, 370, 370, nil, 851, nil, nil, nil, + nil, 370, nil, 370, 370, 370, nil, nil, 370, 370, + 385, 385, 385, 385, 385, 385, nil, nil, nil, 385, + 385, nil, nil, nil, 385, nil, 385, 385, 385, 385, + 385, 385, 385, nil, nil, nil, nil, nil, 385, 385, + 385, 385, 385, 385, 385, nil, nil, 385, nil, nil, + nil, nil, nil, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 385, 385, nil, 385, 385, 385, nil, + 385, 385, 385, 385, 385, 1009, 1009, 1009, 1009, 1009, + 1009, 1009, 1009, 1009, 1009, 1009, nil, 1009, 1009, nil, + nil, 1009, 1009, nil, 385, nil, nil, 385, nil, nil, + 385, 385, nil, nil, 385, nil, 385, 1009, nil, 1009, + 385, 1009, 1009, nil, 1009, 1009, 1009, 1009, 1009, 385, + 1009, nil, nil, nil, 385, 385, 385, 385, nil, 385, + 385, 385, 385, nil, nil, nil, nil, 385, 385, nil, + 1009, nil, nil, nil, nil, 385, nil, 385, 385, 385, + nil, nil, 385, 385, 386, 386, 386, 386, 386, 386, + nil, nil, nil, 386, 386, nil, nil, nil, 386, nil, + 386, 386, 386, 386, 386, 386, 386, nil, nil, nil, + nil, nil, 386, 386, 386, 386, 386, 386, 386, nil, + nil, 386, nil, nil, nil, nil, nil, 386, 386, 386, + 386, 386, 386, 386, 386, 386, 386, 386, 386, nil, + 386, 386, 386, nil, 386, 386, 386, 386, 386, 1027, + 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, 1027, + nil, 1027, 1027, nil, nil, 1027, 1027, nil, 386, nil, + nil, 386, nil, nil, 386, 386, nil, nil, 386, nil, + 386, 1027, nil, 1027, 386, 1027, 1027, nil, 1027, 1027, + 1027, 1027, 1027, 386, 1027, nil, nil, nil, 386, 386, + 386, 386, nil, 386, 386, 386, 386, nil, nil, nil, + nil, 386, 386, nil, 1027, nil, nil, nil, nil, 386, + nil, 386, 386, 386, nil, nil, 386, 386, 615, 615, + 615, 615, 615, 615, nil, nil, nil, 615, 615, nil, + nil, nil, 615, nil, 615, 615, 615, 615, 615, 615, + 615, nil, nil, nil, nil, nil, 615, 615, 615, 615, + 615, 615, 615, nil, nil, 615, nil, nil, nil, nil, + nil, 615, 615, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615, nil, 615, 615, 615, nil, 615, 615, + 615, 615, 615, 1050, 1050, 1050, 1050, 1050, 1050, 1050, + 1050, 1050, 1050, 1050, nil, 1050, 1050, nil, nil, 1050, + 1050, nil, 615, nil, nil, 615, nil, nil, 615, 615, + nil, nil, 615, nil, 615, 1050, nil, 1050, 615, 1050, + 1050, nil, 1050, 1050, 1050, 1050, 1050, 615, 1050, nil, + nil, nil, 615, 615, 615, 615, nil, 615, 615, 615, + 615, nil, nil, nil, nil, 615, 615, nil, 1050, nil, + nil, nil, nil, 615, nil, 615, 615, 615, nil, nil, + 615, 615, 618, 618, 618, 618, 618, 618, nil, nil, + nil, 618, 618, nil, nil, nil, 618, nil, 618, 618, + 618, 618, 618, 618, 618, nil, nil, nil, nil, nil, + 618, 618, 618, 618, 618, 618, 618, nil, 585, 618, + 585, 585, 585, nil, 585, 618, 618, 618, 618, 618, + 618, 618, 618, 618, 618, 618, 618, nil, 618, 618, + 618, nil, 618, 618, 618, 618, 618, 781, nil, 781, + 781, 781, nil, 781, nil, 585, nil, nil, 487, nil, + nil, nil, nil, nil, 585, nil, 618, nil, nil, 618, + nil, nil, 618, 618, nil, nil, 618, 941, 618, 941, + 941, 941, 618, 941, 781, nil, nil, nil, nil, nil, + 487, 618, nil, 781, 487, 487, 618, 618, 618, 618, + nil, 618, 618, 618, 618, nil, nil, nil, nil, 618, + 618, nil, nil, nil, 941, nil, nil, 618, nil, 618, + 618, 618, nil, 941, 618, 618, 639, 639, 639, 639, + 639, 639, nil, nil, nil, 639, 639, nil, nil, nil, + 639, nil, 639, 639, 639, 639, 639, 639, 639, nil, + nil, nil, nil, nil, 639, 639, 639, 639, 639, 639, + 639, nil, nil, 639, nil, nil, nil, nil, nil, 639, + 639, 639, 639, 639, 639, 639, 639, 639, 639, 639, + 639, nil, 639, 639, 639, nil, 639, 639, 639, 639, + 639, 354, 354, 354, 354, 354, 354, 354, 354, 354, + 354, 354, nil, 354, 354, nil, nil, 354, 354, nil, + 639, nil, nil, 639, nil, nil, 639, 639, nil, 501, + 639, nil, 639, 354, nil, 354, 639, 354, 354, nil, + 354, 354, 354, 354, 354, 639, 354, nil, nil, nil, + 639, 639, 639, 639, nil, 639, 639, 639, 639, nil, + nil, 501, nil, 639, 639, 501, 501, nil, 501, 501, + nil, 639, nil, 639, 639, 639, nil, nil, 639, 639, + 818, 818, 818, 818, 818, 818, nil, nil, nil, 818, + 818, nil, nil, nil, 818, nil, 818, 818, 818, 818, + 818, 818, 818, nil, nil, nil, nil, nil, 818, 818, + 818, 818, 818, 818, 818, nil, nil, 818, nil, nil, + nil, nil, nil, 818, 818, 818, 818, 818, 818, 818, + 818, 818, 818, 818, 818, nil, 818, 818, 818, nil, + 818, 818, 818, 818, 818, 355, 355, 355, 355, 355, + 355, 355, 355, 355, 355, 355, nil, 355, 355, nil, + nil, 355, 355, nil, 818, nil, nil, 818, nil, nil, + 818, 818, nil, 502, 818, nil, 818, 355, nil, 355, + 818, 355, 355, nil, 355, 355, 355, 355, 355, 818, + 355, nil, nil, nil, 818, 818, 818, 818, nil, 818, + 818, 818, 818, nil, nil, 502, nil, 818, 818, 502, + 502, nil, 502, 502, nil, 818, nil, 818, 818, 818, + nil, nil, 818, 818, 823, 823, 823, 823, 823, 823, + nil, nil, nil, 823, 823, nil, nil, nil, 823, nil, + 823, 823, 823, 823, 823, 823, 823, nil, nil, nil, + nil, nil, 823, 823, 823, 823, 823, 823, 823, nil, + nil, 823, nil, nil, nil, nil, nil, 823, 823, 823, + 823, 823, 823, 823, 823, 823, 823, 823, 823, nil, + 823, 823, 823, nil, 823, 823, 823, 823, 823, 484, + 484, 484, 484, 484, 484, 484, 484, 484, 484, 484, + nil, 484, 484, nil, nil, 484, 484, nil, 823, nil, + nil, 823, nil, nil, 823, 823, nil, nil, 823, nil, + 823, 484, nil, 484, 823, 484, 484, nil, 484, 484, + 484, 484, 484, 823, 484, nil, nil, nil, 823, 823, + 823, 823, nil, 823, 823, 823, 823, nil, nil, nil, + nil, 823, 823, nil, 1118, nil, 1118, 1118, 1118, 823, + 1118, 823, 823, 823, nil, nil, 823, 823, 834, 834, + 834, 834, 834, 834, nil, nil, nil, 834, 834, nil, + nil, nil, 834, nil, 834, 834, 834, 834, 834, 834, + 834, 1118, nil, nil, nil, nil, 834, 834, 834, 834, + 834, 834, 834, nil, nil, 834, nil, nil, nil, nil, + nil, 834, 834, 834, 834, 834, 834, 834, 834, 834, + 834, 834, 834, nil, 834, 834, 834, nil, 834, 834, + 834, 834, 834, 485, 485, 485, 485, 485, 485, 485, + 485, 485, 485, 485, nil, 485, 485, nil, nil, 485, + 485, nil, 834, nil, nil, 834, nil, nil, 834, 834, + nil, nil, 834, nil, 834, 485, nil, 485, 834, 485, + 485, nil, 485, 485, 485, 485, 485, 834, 485, nil, + nil, nil, 834, 834, 834, 834, nil, 834, 834, 834, + 834, nil, nil, nil, nil, 834, 834, nil, 1119, nil, + 1119, 1119, 1119, 834, 1119, 834, 834, 834, nil, nil, + 834, 834, 908, 908, 908, 908, 908, 908, nil, nil, + nil, 908, 908, nil, nil, nil, 908, nil, 908, 908, + 908, 908, 908, 908, 908, 1119, nil, nil, nil, nil, + 908, 908, 908, 908, 908, 908, 908, nil, nil, 908, + nil, nil, nil, nil, nil, 908, 908, 908, 908, 908, + 908, 908, 908, 908, 908, 908, 908, nil, 908, 908, + 908, nil, 908, 908, 908, 908, 908, 495, 495, 495, + 495, 495, 495, 495, nil, nil, 495, 495, nil, nil, + nil, nil, nil, 495, 495, nil, 908, nil, nil, 908, + nil, nil, 908, 908, nil, nil, 908, nil, 908, 495, + nil, 495, 908, 495, 495, nil, 495, 495, 495, 495, + 495, 908, 495, nil, nil, nil, 908, 908, 908, 908, + nil, 908, 908, 908, 908, nil, nil, nil, nil, 908, + 908, nil, nil, nil, nil, nil, nil, 908, nil, 908, + 908, 908, nil, nil, 908, 908, 920, 920, 920, 920, + 920, 920, nil, nil, nil, 920, 920, nil, nil, nil, + 920, nil, 920, 920, 920, 920, 920, 920, 920, nil, + nil, nil, nil, nil, 920, 920, 920, 920, 920, 920, + 920, nil, nil, 920, nil, nil, nil, nil, nil, 920, + 920, 920, 920, 920, 920, 920, 920, 920, 920, 920, + 920, nil, 920, 920, 920, nil, 920, 920, 920, 920, + 920, 496, 496, 496, 496, 496, 496, 496, nil, nil, + 496, 496, nil, nil, nil, nil, nil, 496, 496, nil, + 920, nil, nil, 920, nil, nil, 920, 920, nil, nil, + 920, nil, 920, 496, nil, 496, 920, 496, 496, nil, + 496, 496, 496, 496, 496, 920, 496, nil, nil, nil, + 920, 920, 920, 920, nil, 920, 920, 920, 920, nil, + nil, nil, nil, 920, 920, nil, nil, nil, nil, nil, + nil, 920, nil, 920, 920, 920, nil, nil, 920, 920, + 955, 955, 955, 955, 955, 955, nil, nil, nil, 955, + 955, nil, nil, nil, 955, nil, 955, 955, 955, 955, + 955, 955, 955, nil, nil, nil, nil, nil, 955, 955, + 955, 955, 955, 955, 955, nil, nil, 955, nil, nil, + nil, nil, nil, 955, 955, 955, 955, 955, 955, 955, + 955, 955, 955, 955, 955, nil, 955, 955, 955, nil, + 955, 955, 955, 955, 955, 497, 497, 497, 497, 497, + 497, 497, nil, nil, 497, 497, nil, nil, nil, nil, + nil, 497, 497, nil, 955, nil, nil, 955, nil, nil, + 955, 955, nil, nil, 955, nil, 955, 497, nil, 497, + 955, 497, 497, nil, 497, 497, 497, 497, 497, 955, + 497, nil, nil, nil, 955, 955, 955, 955, nil, 955, + 955, 955, 955, nil, nil, nil, nil, 955, 955, nil, + nil, nil, nil, nil, nil, 955, nil, 955, 955, 955, + nil, nil, 955, 955, 961, 961, 961, 961, 961, 961, + nil, nil, nil, 961, 961, nil, nil, nil, 961, nil, + 961, 961, 961, 961, 961, 961, 961, nil, nil, nil, + nil, nil, 961, 961, 961, 961, 961, 961, 961, nil, + nil, 961, nil, nil, nil, nil, nil, 961, 961, 961, + 961, 961, 961, 961, 961, 961, 961, 961, 961, nil, + 961, 961, 961, nil, 961, 961, 961, 961, 961, 498, + 498, 498, 498, 498, 498, 498, nil, nil, 498, 498, + nil, nil, nil, nil, nil, 498, 498, nil, 961, nil, + nil, 961, nil, nil, 961, 961, nil, nil, 961, nil, + 961, 498, nil, 498, 961, 498, 498, nil, 498, 498, + 498, 498, 498, 961, 498, nil, nil, nil, 961, 961, + 961, 961, nil, 961, 961, 961, 961, nil, nil, nil, + nil, 961, 961, nil, nil, nil, nil, nil, nil, 961, + nil, 961, 961, 961, nil, nil, 961, 961, 1010, 1010, + 1010, 1010, 1010, 1010, nil, nil, nil, 1010, 1010, nil, + nil, nil, 1010, nil, 1010, 1010, 1010, 1010, 1010, 1010, + 1010, nil, nil, nil, nil, nil, 1010, 1010, 1010, 1010, + 1010, 1010, 1010, nil, nil, 1010, nil, nil, nil, nil, + nil, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, + 1010, 1010, 1010, nil, 1010, 1010, 1010, nil, 1010, 1010, + 1010, 1010, 1010, 499, 499, 499, 499, 499, 499, 499, + nil, nil, 499, 499, nil, nil, nil, nil, nil, 499, + 499, nil, 1010, nil, nil, 1010, nil, nil, 1010, 1010, + nil, nil, 1010, nil, 1010, 499, nil, 499, 1010, 499, + 499, nil, 499, 499, 499, 499, 499, 1010, 499, nil, + nil, nil, 1010, 1010, 1010, 1010, nil, 1010, 1010, 1010, + 1010, nil, nil, nil, nil, 1010, 1010, nil, nil, nil, + nil, nil, nil, 1010, nil, 1010, 1010, 1010, nil, nil, + 1010, 1010, 1029, 1029, 1029, 1029, 1029, 1029, nil, nil, + nil, 1029, 1029, nil, nil, nil, 1029, nil, 1029, 1029, + 1029, 1029, 1029, 1029, 1029, nil, nil, nil, nil, nil, + 1029, 1029, 1029, 1029, 1029, 1029, 1029, nil, nil, 1029, + nil, nil, nil, nil, nil, 1029, 1029, 1029, 1029, 1029, + 1029, 1029, 1029, 1029, 1029, 1029, 1029, nil, 1029, 1029, + 1029, nil, 1029, 1029, 1029, 1029, 1029, 500, 500, 500, + 500, 500, 500, 500, nil, nil, 500, 500, nil, nil, + nil, nil, nil, 500, 500, nil, 1029, nil, nil, 1029, + nil, nil, 1029, 1029, nil, nil, 1029, nil, 1029, 500, + nil, 500, 1029, 500, 500, nil, 500, 500, 500, 500, + 500, 1029, 500, nil, nil, nil, 1029, 1029, 1029, 1029, + nil, 1029, 1029, 1029, 1029, nil, nil, nil, nil, 1029, + 1029, nil, nil, nil, nil, nil, nil, 1029, nil, 1029, + 1029, 1029, nil, nil, 1029, 1029, 1066, 1066, 1066, 1066, + 1066, 1066, nil, nil, nil, 1066, 1066, nil, nil, nil, + 1066, nil, 1066, 1066, 1066, 1066, 1066, 1066, 1066, nil, + nil, nil, nil, nil, 1066, 1066, 1066, 1066, 1066, 1066, + 1066, nil, nil, 1066, nil, nil, nil, nil, nil, 1066, + 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, + 1066, nil, 1066, 1066, 1066, nil, 1066, 1066, 1066, 1066, + 1066, 503, 503, 503, 503, 503, 503, 503, nil, nil, + 503, 503, nil, nil, nil, nil, nil, 503, 503, nil, + 1066, nil, nil, 1066, nil, nil, 1066, 1066, nil, nil, + 1066, nil, 1066, 503, nil, 503, 1066, 503, 503, nil, + 503, 503, 503, 503, 503, 1066, 503, nil, nil, nil, + 1066, 1066, 1066, 1066, nil, 1066, 1066, 1066, 1066, nil, + nil, nil, nil, 1066, 1066, nil, nil, nil, nil, nil, + nil, 1066, nil, 1066, 1066, 1066, nil, nil, 1066, 1066, + 1067, 1067, 1067, 1067, 1067, 1067, nil, nil, nil, 1067, + 1067, nil, nil, nil, 1067, nil, 1067, 1067, 1067, 1067, + 1067, 1067, 1067, nil, nil, nil, nil, nil, 1067, 1067, + 1067, 1067, 1067, 1067, 1067, nil, nil, 1067, nil, nil, + nil, nil, nil, 1067, 1067, 1067, 1067, 1067, 1067, 1067, + 1067, 1067, 1067, 1067, 1067, nil, 1067, 1067, 1067, nil, + 1067, 1067, 1067, 1067, 1067, 504, 504, 504, 504, 504, + 504, 504, 504, nil, 504, 504, nil, nil, nil, nil, + nil, 504, 504, nil, 1067, nil, nil, 1067, nil, nil, + 1067, 1067, nil, nil, 1067, nil, 1067, 504, nil, 504, + 1067, 504, 504, nil, 504, 504, 504, 504, 504, 1067, + 504, nil, nil, nil, 1067, 1067, 1067, 1067, nil, 1067, + 1067, 1067, 1067, nil, nil, nil, nil, 1067, 1067, nil, + nil, nil, nil, nil, nil, 1067, nil, 1067, 1067, 1067, + nil, nil, 1067, 1067, 1107, 1107, 1107, 1107, 1107, 1107, + nil, nil, nil, 1107, 1107, nil, nil, nil, 1107, nil, + 1107, 1107, 1107, 1107, 1107, 1107, 1107, nil, nil, nil, + nil, nil, 1107, 1107, 1107, 1107, 1107, 1107, 1107, nil, + nil, 1107, nil, nil, nil, nil, nil, 1107, 1107, 1107, + 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, 1107, nil, + 1107, 1107, 1107, nil, 1107, 1107, 1107, 1107, 1107, 506, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 506, 506, nil, 1107, nil, + nil, 1107, nil, nil, 1107, 1107, nil, nil, 1107, nil, + 1107, 506, nil, 506, 1107, 506, 506, nil, 506, 506, + nil, nil, 506, 1107, 506, nil, nil, nil, 1107, 1107, + 1107, 1107, nil, 1107, 1107, 1107, 1107, nil, nil, nil, + nil, 1107, 1107, nil, nil, nil, nil, nil, nil, 1107, + nil, 1107, 1107, 1107, nil, nil, 1107, 1107, 1120, 1120, + 1120, 1120, 1120, 1120, nil, nil, nil, 1120, 1120, nil, + nil, nil, 1120, nil, 1120, 1120, 1120, 1120, 1120, 1120, + 1120, nil, nil, nil, nil, nil, 1120, 1120, 1120, 1120, + 1120, 1120, 1120, nil, nil, 1120, nil, nil, nil, nil, + nil, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, 1120, + 1120, 1120, 1120, nil, 1120, 1120, 1120, nil, 1120, 1120, + 1120, 1120, 1120, 559, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 559, + 559, nil, 1120, nil, nil, 1120, nil, nil, 1120, 1120, + nil, nil, 1120, nil, 1120, 559, nil, 559, 1120, 559, + 559, nil, 559, 559, nil, nil, 559, 1120, 559, nil, + nil, nil, 1120, 1120, 1120, 1120, nil, 1120, 1120, 1120, + 1120, nil, nil, nil, nil, 1120, 1120, nil, nil, nil, + nil, nil, nil, 1120, nil, 1120, 1120, 1120, nil, nil, + 1120, 1120, 1166, 1166, 1166, 1166, 1166, 1166, nil, nil, + nil, 1166, 1166, nil, nil, nil, 1166, nil, 1166, 1166, + 1166, 1166, 1166, 1166, 1166, nil, nil, nil, nil, nil, + 1166, 1166, 1166, 1166, 1166, 1166, 1166, nil, nil, 1166, + nil, nil, nil, nil, nil, 1166, 1166, 1166, 1166, 1166, + 1166, 1166, 1166, 1166, 1166, 1166, 1166, nil, 1166, 1166, + 1166, nil, 1166, 1166, 1166, 1166, 1166, 492, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 492, 492, nil, 1166, nil, nil, 1166, + nil, nil, 1166, 1166, nil, nil, 1166, nil, 1166, 492, + nil, 492, 1166, 492, 492, nil, 492, 492, nil, nil, + nil, 1166, nil, nil, nil, nil, 1166, 1166, 1166, 1166, + nil, 1166, 1166, 1166, 1166, nil, nil, nil, nil, 1166, + 1166, nil, nil, nil, nil, nil, nil, 1166, nil, 1166, + 1166, 1166, nil, nil, 1166, 1166, 7, 7, 7, 7, + 7, nil, nil, nil, 7, 7, nil, nil, nil, 7, + nil, 7, 7, 7, 7, 7, 7, 7, nil, nil, + nil, nil, nil, 7, 7, 7, 7, 7, 7, 7, + nil, nil, 7, nil, nil, nil, nil, nil, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + nil, 7, 7, 7, nil, 7, 7, 7, 7, 7, + 493, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 493, 493, nil, 7, + nil, nil, 7, nil, nil, 7, 7, nil, nil, 7, + nil, 7, 493, nil, 493, 7, 493, 493, nil, 493, + 493, nil, nil, nil, 7, nil, nil, nil, nil, 7, + 7, 7, 7, nil, 7, 7, 7, 7, nil, nil, + nil, nil, 7, 7, nil, nil, nil, 22, 22, 22, + 7, 22, 7, 7, 7, 22, 22, 7, 7, nil, + 22, nil, 22, 22, 22, 22, 22, 22, 22, nil, + nil, nil, nil, nil, 22, 22, 22, 22, 22, 22, + 22, nil, nil, 22, nil, nil, nil, nil, nil, nil, + 22, nil, nil, 22, 22, 22, 22, 22, 22, 22, + 22, nil, 22, 22, 22, nil, 22, 22, 22, 22, + 22, 494, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 494, 494, nil, + 22, nil, nil, 22, nil, nil, 22, 22, nil, nil, + 22, nil, nil, 494, nil, nil, 22, 494, 494, nil, + 494, 494, nil, nil, nil, 22, nil, nil, nil, nil, + 22, 22, 22, 22, nil, 22, 22, 22, 22, nil, + nil, nil, nil, 22, 22, nil, nil, nil, nil, nil, + nil, 22, nil, 22, 22, 22, 30, nil, 22, 22, + nil, nil, nil, 30, 30, 30, nil, nil, 30, 30, + 30, nil, 30, nil, nil, nil, nil, nil, nil, nil, + 30, 30, 30, 30, nil, nil, nil, nil, nil, nil, + nil, nil, 30, 30, nil, 30, 30, 30, 30, 30, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, nil, nil, 30, 30, + 30, nil, nil, 30, nil, 30, 30, nil, nil, 30, + 30, nil, 30, nil, 30, nil, 30, nil, 30, 30, + nil, 30, 30, 30, 30, 30, 31, 30, 30, 30, + nil, nil, nil, 31, 31, 31, nil, nil, 31, 31, + 31, nil, 31, 30, nil, nil, 30, 30, nil, 30, + 31, 30, 31, 31, nil, nil, nil, nil, 30, nil, + nil, nil, 31, 31, nil, 31, 31, 31, 31, 31, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, nil, nil, 31, 31, + 31, nil, nil, 31, nil, 31, 31, nil, nil, 31, + 31, nil, 31, nil, 31, nil, 31, nil, 31, 31, + nil, 31, 31, 31, 31, 31, nil, 31, nil, 31, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 31, nil, nil, 31, 31, nil, 31, + nil, 31, 32, 32, 32, nil, 32, nil, 31, nil, + 32, 32, nil, nil, nil, 32, nil, 32, 32, 32, + 32, 32, 32, 32, nil, nil, nil, nil, nil, 32, + 32, 32, 32, 32, 32, 32, nil, nil, 32, nil, + nil, nil, nil, nil, nil, 32, nil, nil, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + nil, 32, 32, 32, 32, 32, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 32, nil, nil, 32, nil, + nil, 32, 32, nil, nil, 32, nil, 32, nil, 32, + nil, 32, nil, nil, 32, nil, nil, nil, nil, nil, + 32, nil, nil, nil, nil, 32, 32, 32, 32, nil, + 32, 32, 32, 32, nil, nil, nil, nil, 32, 32, + nil, nil, nil, 33, 33, 33, 32, 33, 32, 32, + 32, 33, 33, 32, 32, nil, 33, nil, 33, 33, + 33, 33, 33, 33, 33, nil, nil, nil, nil, nil, + 33, 33, 33, 33, 33, 33, 33, nil, nil, 33, + nil, nil, nil, nil, nil, nil, 33, nil, nil, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, nil, 33, 33, 33, 33, 33, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 33, nil, nil, 33, + nil, nil, 33, 33, nil, nil, 33, nil, 33, nil, + 33, nil, 33, nil, nil, 33, nil, nil, nil, nil, + nil, 33, nil, nil, nil, nil, 33, 33, 33, 33, + nil, 33, 33, 33, 33, nil, nil, nil, nil, 33, + 33, nil, nil, nil, 34, 34, 34, 33, 34, 33, + 33, 33, 34, 34, 33, 33, nil, 34, nil, 34, + 34, 34, 34, 34, 34, 34, nil, nil, nil, nil, + nil, 34, 34, 34, 34, 34, 34, 34, nil, nil, + 34, nil, nil, nil, nil, nil, nil, 34, nil, nil, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, nil, 34, 34, 34, 34, 34, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 34, nil, nil, + 34, nil, nil, 34, 34, nil, nil, 34, nil, 34, + nil, 34, nil, 34, nil, nil, 34, nil, nil, nil, + nil, nil, 34, nil, nil, nil, nil, 34, 34, 34, + 34, nil, 34, 34, 34, 34, nil, nil, nil, nil, + 34, 34, nil, nil, nil, 44, 44, 44, 34, 44, + 34, 34, 34, 44, 44, 34, 34, nil, 44, nil, + 44, 44, 44, 44, 44, 44, 44, nil, nil, nil, + nil, nil, 44, 44, 44, 44, 44, 44, 44, nil, + nil, 44, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 44, 44, 44, 44, 44, 44, 44, 44, nil, + 44, 44, 44, nil, 44, 44, 44, 44, 44, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 44, nil, + nil, 44, nil, nil, 44, 44, nil, nil, 44, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, 44, nil, nil, nil, nil, 44, 44, + 44, 44, nil, 44, 44, 44, 44, nil, nil, nil, + nil, 44, 44, nil, nil, nil, 45, 45, 45, 44, + 45, 44, 44, 44, 45, 45, 44, 44, nil, 45, + nil, 45, 45, 45, 45, 45, 45, 45, nil, nil, + nil, nil, nil, 45, 45, 45, 45, 45, 45, 45, + nil, nil, 45, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 45, 45, 45, 45, 45, 45, 45, 45, + nil, 45, 45, 45, nil, 45, 45, 45, 45, 45, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 45, nil, nil, 45, 45, nil, nil, 45, + nil, nil, nil, nil, nil, 45, nil, nil, nil, nil, + nil, nil, nil, nil, 45, nil, nil, nil, nil, 45, + 45, 45, 45, nil, 45, 45, 45, 45, nil, nil, + nil, nil, 45, 45, nil, nil, nil, 47, 47, 47, + 45, 47, 45, 45, 45, 47, 47, 45, 45, nil, + 47, nil, 47, 47, 47, 47, 47, 47, 47, nil, + nil, nil, nil, nil, 47, 47, 47, 47, 47, 47, + 47, nil, nil, 47, nil, nil, nil, nil, nil, nil, + 47, nil, nil, 47, 47, 47, 47, 47, 47, 47, + 47, nil, 47, 47, 47, nil, 47, 47, 47, 47, + 47, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 47, nil, nil, 47, nil, nil, 47, 47, nil, nil, + 47, nil, nil, nil, nil, nil, 47, nil, nil, nil, + nil, nil, nil, nil, nil, 47, nil, nil, nil, nil, + 47, 47, 47, 47, nil, 47, 47, 47, 47, nil, + nil, nil, nil, 47, 47, nil, nil, nil, 48, 48, + 48, 47, 48, 47, 47, 47, 48, 48, 47, 47, + nil, 48, nil, 48, 48, 48, 48, 48, 48, 48, + nil, nil, nil, nil, nil, 48, 48, 48, 48, 48, + 48, 48, nil, nil, 48, nil, nil, nil, nil, nil, + nil, 48, nil, nil, 48, 48, 48, 48, 48, 48, + 48, 48, nil, 48, 48, 48, nil, 48, 48, 48, + 48, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 48, nil, nil, 48, nil, nil, 48, 48, nil, + nil, 48, nil, nil, nil, nil, nil, 48, nil, nil, + nil, nil, nil, nil, nil, nil, 48, nil, nil, nil, + nil, 48, 48, 48, 48, nil, 48, 48, 48, 48, + nil, nil, nil, nil, 48, 48, nil, nil, nil, 50, + 50, 50, 48, 50, 48, 48, 48, 50, 50, 48, + 48, nil, 50, nil, 50, 50, 50, 50, 50, 50, + 50, nil, nil, nil, nil, nil, 50, 50, 50, 50, + 50, 50, 50, nil, nil, 50, nil, nil, nil, nil, + nil, nil, 50, nil, nil, 50, 50, 50, 50, 50, + 50, 50, 50, nil, 50, 50, 50, nil, 50, 50, + 50, 50, 50, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 50, nil, nil, 50, nil, nil, 50, 50, + nil, nil, 50, nil, nil, nil, nil, nil, 50, nil, + nil, nil, nil, nil, nil, nil, nil, 50, nil, nil, + nil, nil, 50, 50, 50, 50, nil, 50, 50, 50, + 50, nil, nil, nil, nil, 50, 50, nil, nil, nil, + nil, nil, nil, 50, nil, 50, 50, 50, 64, nil, + 50, 50, nil, nil, nil, 64, 64, 64, nil, nil, + 64, 64, 64, nil, 64, nil, nil, nil, nil, nil, + nil, nil, 64, nil, 64, 64, 64, nil, nil, nil, + 707, 707, 707, 707, 64, 64, nil, 64, 64, 64, + 64, 64, nil, nil, nil, nil, 707, 707, 707, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 707, + 707, nil, nil, 707, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, nil, nil, + 64, 64, 64, nil, nil, 64, nil, nil, 64, nil, + nil, 64, 64, nil, 64, nil, 64, nil, 64, nil, + 64, 64, nil, 64, 64, 64, 64, 64, nil, 64, + nil, 64, nil, 707, 707, 707, 707, nil, 707, 707, + 707, 707, nil, nil, nil, 64, 707, 707, 64, 64, + 64, 64, nil, 64, 707, 64, 707, 707, 707, nil, + 64, 66, 66, 66, 66, 66, nil, nil, nil, 66, + 66, nil, nil, nil, 66, nil, 66, 66, 66, 66, + 66, 66, 66, nil, nil, nil, nil, nil, 66, 66, + 66, 66, 66, 66, 66, nil, nil, 66, nil, nil, + nil, nil, nil, 66, 66, nil, 66, 66, 66, 66, + 66, 66, 66, 66, 66, nil, 66, 66, 66, nil, + 66, 66, 66, 66, 66, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 66, nil, nil, 66, nil, nil, + 66, 66, nil, nil, 66, nil, 66, nil, nil, nil, + 66, nil, nil, nil, nil, nil, nil, nil, nil, 66, + nil, nil, nil, nil, 66, 66, 66, 66, nil, 66, + 66, 66, 66, nil, nil, nil, nil, 66, 66, nil, + nil, nil, 67, 67, 67, 66, 67, 66, 66, 66, + 67, 67, 66, 66, nil, 67, nil, 67, 67, 67, + 67, 67, 67, 67, nil, nil, nil, nil, nil, 67, + 67, 67, 67, 67, 67, 67, nil, nil, 67, nil, + nil, nil, nil, nil, nil, 67, nil, nil, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + nil, 67, 67, 67, 67, 67, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 67, nil, nil, 67, nil, + nil, 67, 67, nil, nil, 67, nil, 67, nil, nil, + nil, 67, nil, nil, 67, nil, nil, nil, nil, nil, + 67, nil, nil, nil, nil, 67, 67, 67, 67, nil, + 67, 67, 67, 67, nil, nil, nil, nil, 67, 67, + nil, nil, nil, 68, 68, 68, 67, 68, 67, 67, + 67, 68, 68, 67, 67, nil, 68, nil, 68, 68, + 68, 68, 68, 68, 68, nil, nil, nil, nil, nil, + 68, 68, 68, 68, 68, 68, 68, nil, nil, 68, + nil, nil, nil, nil, nil, nil, 68, nil, nil, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, nil, 68, 68, 68, 68, 68, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 68, nil, nil, 68, + nil, nil, 68, 68, nil, nil, 68, nil, nil, nil, + nil, nil, 68, nil, nil, 68, nil, nil, nil, nil, + nil, 68, nil, nil, nil, nil, 68, 68, 68, 68, + nil, 68, 68, 68, 68, nil, nil, nil, nil, 68, + 68, nil, nil, nil, 71, 71, 71, 68, 71, 68, + 68, 68, 71, 71, 68, 68, nil, 71, nil, 71, + 71, 71, 71, 71, 71, 71, nil, nil, nil, nil, + nil, 71, 71, 71, 71, 71, 71, 71, nil, nil, + 71, nil, nil, nil, nil, nil, nil, 71, nil, nil, + 71, 71, 71, 71, 71, 71, 71, 71, nil, 71, + 71, 71, nil, 71, 71, 71, 71, 71, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 71, nil, nil, + 71, nil, nil, 71, 71, nil, nil, 71, nil, nil, + nil, nil, nil, 71, nil, nil, nil, nil, nil, nil, + nil, nil, 71, nil, nil, nil, nil, 71, 71, 71, + 71, nil, 71, 71, 71, 71, nil, nil, nil, nil, + 71, 71, nil, nil, nil, 72, 72, 72, 71, 72, + 71, 71, 71, 72, 72, 71, 71, nil, 72, nil, + 72, 72, 72, 72, 72, 72, 72, nil, nil, nil, + nil, nil, 72, 72, 72, 72, 72, 72, 72, nil, + nil, 72, nil, nil, nil, nil, nil, nil, 72, nil, + nil, 72, 72, 72, 72, 72, 72, 72, 72, nil, + 72, 72, 72, nil, 72, 72, 72, 72, 72, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 72, nil, + nil, 72, nil, nil, 72, 72, nil, nil, 72, nil, + nil, nil, nil, nil, 72, nil, nil, nil, nil, nil, + nil, nil, nil, 72, nil, nil, nil, nil, 72, 72, + 72, 72, nil, 72, 72, 72, 72, nil, nil, nil, + nil, 72, 72, nil, nil, nil, 75, 75, 75, 72, + 75, 72, 72, 72, 75, 75, 72, 72, nil, 75, + nil, 75, 75, 75, 75, 75, 75, 75, nil, nil, + nil, nil, nil, 75, 75, 75, 75, 75, 75, 75, + nil, nil, 75, nil, nil, nil, nil, nil, nil, 75, + nil, nil, 75, 75, 75, 75, 75, 75, 75, 75, + nil, 75, 75, 75, nil, 75, 75, 75, 75, 75, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 75, + nil, nil, 75, nil, nil, 75, 75, nil, nil, 75, + nil, nil, nil, nil, nil, 75, nil, nil, nil, nil, + nil, nil, nil, nil, 75, nil, nil, nil, nil, 75, + 75, 75, 75, nil, 75, 75, 75, 75, nil, nil, + nil, nil, 75, 75, 75, nil, nil, nil, nil, 75, + 75, nil, 75, 75, 75, nil, nil, 75, 75, 124, + 124, 124, 124, 124, nil, nil, nil, 124, 124, nil, + nil, nil, 124, nil, 124, 124, 124, 124, 124, 124, + 124, nil, nil, nil, nil, nil, 124, 124, 124, 124, + 124, 124, 124, nil, nil, 124, nil, nil, nil, nil, + nil, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, nil, 124, 124, 124, nil, 124, 124, + 124, 124, 124, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 124, nil, nil, 124, nil, nil, 124, 124, + nil, nil, 124, nil, 124, nil, nil, nil, 124, nil, + nil, nil, nil, nil, nil, nil, nil, 124, nil, nil, + nil, nil, 124, 124, 124, 124, nil, 124, 124, 124, + 124, nil, nil, nil, nil, 124, 124, nil, nil, nil, + nil, nil, 124, 124, nil, 124, 124, 124, nil, nil, + 124, 124, 129, 129, 129, nil, 129, nil, nil, nil, + 129, 129, nil, nil, nil, 129, nil, 129, 129, 129, + 129, 129, 129, 129, nil, nil, nil, nil, nil, 129, + 129, 129, 129, 129, 129, 129, nil, nil, 129, nil, + nil, nil, nil, nil, nil, 129, nil, nil, 129, 129, + 129, 129, 129, 129, 129, 129, nil, 129, 129, 129, + nil, 129, 129, 129, 129, 129, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 129, nil, nil, 129, nil, + nil, 129, 129, nil, nil, 129, nil, nil, nil, nil, + nil, 129, nil, nil, nil, nil, nil, nil, nil, nil, + 129, nil, nil, nil, nil, 129, 129, 129, 129, nil, + 129, 129, 129, 129, nil, nil, nil, nil, 129, 129, + nil, nil, nil, 130, 130, 130, 129, 130, 129, 129, + 129, 130, 130, 129, 129, nil, 130, nil, 130, 130, + 130, 130, 130, 130, 130, nil, nil, nil, nil, nil, + 130, 130, 130, 130, 130, 130, 130, nil, nil, 130, + nil, nil, nil, nil, nil, nil, 130, nil, nil, 130, + 130, 130, 130, 130, 130, 130, 130, nil, 130, 130, + 130, nil, 130, 130, 130, 130, 130, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 130, nil, nil, 130, + nil, nil, 130, 130, nil, nil, 130, nil, nil, nil, + nil, nil, 130, nil, nil, nil, nil, nil, nil, nil, + nil, 130, nil, nil, nil, nil, 130, 130, 130, 130, + nil, 130, 130, 130, 130, nil, nil, nil, nil, 130, + 130, nil, nil, nil, 131, 131, 131, 130, 131, 130, + 130, 130, 131, 131, 130, 130, nil, 131, nil, 131, + 131, 131, 131, 131, 131, 131, nil, nil, nil, nil, + nil, 131, 131, 131, 131, 131, 131, 131, nil, nil, + 131, nil, nil, nil, nil, nil, nil, 131, nil, nil, + 131, 131, 131, 131, 131, 131, 131, 131, nil, 131, + 131, 131, nil, 131, 131, 131, 131, 131, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 131, nil, nil, + 131, nil, nil, 131, 131, nil, nil, 131, nil, nil, + nil, nil, nil, 131, nil, nil, nil, nil, nil, nil, + nil, nil, 131, nil, nil, nil, nil, 131, 131, 131, + 131, nil, 131, 131, 131, 131, nil, nil, nil, nil, + 131, 131, nil, nil, nil, 132, 132, 132, 131, 132, + 131, 131, 131, 132, 132, 131, 131, nil, 132, nil, + 132, 132, 132, 132, 132, 132, 132, nil, nil, nil, + nil, nil, 132, 132, 132, 132, 132, 132, 132, nil, + nil, 132, nil, nil, nil, nil, nil, nil, 132, nil, + nil, 132, 132, 132, 132, 132, 132, 132, 132, nil, + 132, 132, 132, nil, 132, 132, 132, 132, 132, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 132, nil, + nil, 132, nil, nil, 132, 132, nil, nil, 132, nil, + nil, nil, nil, nil, 132, nil, nil, nil, nil, nil, + nil, nil, nil, 132, nil, nil, nil, nil, 132, 132, + 132, 132, nil, 132, 132, 132, 132, nil, nil, nil, + nil, 132, 132, nil, nil, nil, nil, nil, nil, 132, + nil, 132, 132, 132, nil, nil, 132, 132, 133, 133, + 133, 133, 133, nil, nil, nil, 133, 133, nil, nil, + nil, 133, nil, 133, 133, 133, 133, 133, 133, 133, + nil, nil, nil, nil, nil, 133, 133, 133, 133, 133, + 133, 133, nil, nil, 133, nil, nil, nil, nil, nil, + 133, 133, nil, 133, 133, 133, 133, 133, 133, 133, + 133, 133, nil, 133, 133, 133, nil, 133, 133, 133, + 133, 133, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 133, nil, nil, 133, nil, nil, 133, 133, nil, + nil, 133, nil, 133, nil, nil, nil, 133, nil, nil, + nil, nil, nil, nil, nil, nil, 133, nil, nil, nil, + nil, 133, 133, 133, 133, nil, 133, 133, 133, 133, + nil, nil, nil, nil, 133, 133, nil, nil, nil, 219, + 219, 219, 133, 219, 133, 133, 133, 219, 219, 133, + 133, nil, 219, nil, 219, 219, 219, 219, 219, 219, + 219, nil, nil, nil, nil, nil, 219, 219, 219, 219, + 219, 219, 219, nil, nil, 219, nil, nil, nil, nil, + nil, nil, 219, nil, nil, 219, 219, 219, 219, 219, + 219, 219, 219, nil, 219, 219, 219, nil, 219, 219, + 219, 219, 219, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 219, nil, nil, 219, nil, nil, 219, 219, + nil, nil, 219, nil, 219, nil, nil, nil, 219, nil, + nil, nil, nil, nil, nil, nil, nil, 219, nil, nil, + nil, nil, 219, 219, 219, 219, nil, 219, 219, 219, + 219, nil, nil, nil, nil, 219, 219, nil, nil, nil, + 220, 220, 220, 219, 220, 219, 219, 219, 220, 220, + 219, 219, nil, 220, nil, 220, 220, 220, 220, 220, + 220, 220, nil, nil, nil, nil, nil, 220, 220, 220, + 220, 220, 220, 220, nil, nil, 220, nil, nil, nil, + nil, nil, nil, 220, nil, nil, 220, 220, 220, 220, + 220, 220, 220, 220, nil, 220, 220, 220, nil, 220, + 220, 220, 220, 220, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 220, nil, nil, 220, nil, nil, 220, + 220, nil, nil, 220, nil, 220, nil, nil, nil, 220, + nil, nil, nil, nil, nil, nil, nil, nil, 220, nil, + nil, nil, nil, 220, 220, 220, 220, nil, 220, 220, + 220, 220, nil, nil, nil, nil, 220, 220, nil, nil, + nil, 221, 221, 221, 220, 221, 220, 220, 220, 221, + 221, 220, 220, nil, 221, nil, 221, 221, 221, 221, + 221, 221, 221, nil, nil, nil, nil, nil, 221, 221, + 221, 221, 221, 221, 221, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 221, nil, nil, 221, 221, 221, + 221, 221, 221, 221, 221, nil, 221, 221, 221, nil, + 221, 221, 221, 221, 221, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 221, nil, nil, 221, nil, nil, + 221, 221, nil, nil, 221, nil, nil, nil, nil, nil, + 221, nil, nil, nil, nil, nil, nil, nil, nil, 221, + nil, nil, nil, nil, 221, 221, 221, 221, nil, 221, + 221, 221, 221, nil, nil, nil, nil, 221, 221, nil, + nil, nil, 222, 222, 222, 221, 222, 221, 221, 221, + 222, 222, 221, 221, nil, 222, nil, 222, 222, 222, + 222, 222, 222, 222, nil, nil, nil, nil, nil, 222, + 222, 222, 222, 222, 222, 222, nil, nil, 222, nil, + nil, nil, nil, nil, nil, 222, nil, nil, 222, 222, + 222, 222, 222, 222, 222, 222, nil, 222, 222, 222, + nil, 222, 222, 222, 222, 222, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 222, nil, nil, 222, nil, + nil, 222, 222, nil, nil, 222, nil, nil, nil, nil, + nil, 222, nil, nil, nil, nil, nil, nil, nil, nil, + 222, nil, nil, nil, nil, 222, 222, 222, 222, nil, + 222, 222, 222, 222, nil, nil, nil, nil, 222, 222, + nil, nil, nil, 223, 223, 223, 222, 223, 222, 222, + 222, 223, 223, 222, 222, nil, 223, nil, 223, 223, + 223, 223, 223, 223, 223, nil, nil, nil, nil, nil, + 223, 223, 223, 223, 223, 223, 223, nil, nil, 223, + nil, nil, nil, nil, nil, nil, 223, nil, nil, 223, + 223, 223, 223, 223, 223, 223, 223, nil, 223, 223, + 223, nil, 223, 223, 223, 223, 223, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 223, nil, nil, 223, + nil, nil, 223, 223, nil, nil, 223, nil, nil, nil, + nil, nil, 223, nil, nil, nil, nil, nil, nil, nil, + nil, 223, nil, nil, nil, nil, 223, 223, 223, 223, + nil, 223, 223, 223, 223, nil, nil, nil, nil, 223, + 223, nil, nil, nil, 224, 224, 224, 223, 224, 223, + 223, 223, 224, 224, 223, 223, nil, 224, nil, 224, + 224, 224, 224, 224, 224, 224, nil, nil, nil, nil, + nil, 224, 224, 224, 224, 224, 224, 224, nil, nil, + 224, nil, nil, nil, nil, nil, nil, 224, nil, nil, + 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, nil, 224, 224, 224, 224, 224, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 224, nil, nil, + 224, nil, nil, 224, 224, nil, nil, 224, nil, 224, + nil, 224, nil, 224, nil, nil, 224, nil, nil, nil, + nil, nil, 224, nil, nil, nil, nil, 224, 224, 224, + 224, nil, 224, 224, 224, 224, nil, nil, nil, nil, + 224, 224, nil, nil, nil, 229, 229, 229, 224, 229, + 224, 224, 224, 229, 229, 224, 224, nil, 229, nil, + 229, 229, 229, 229, 229, 229, 229, nil, nil, nil, + nil, nil, 229, 229, 229, 229, 229, 229, 229, nil, + nil, 229, nil, nil, nil, nil, nil, nil, 229, nil, + nil, 229, 229, 229, 229, 229, 229, 229, 229, nil, + 229, 229, 229, nil, 229, 229, 229, 229, 229, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 229, nil, + nil, 229, nil, nil, 229, 229, nil, nil, 229, nil, + nil, nil, nil, nil, 229, nil, nil, nil, nil, nil, + nil, nil, nil, 229, nil, nil, nil, nil, 229, 229, + 229, 229, nil, 229, 229, 229, 229, nil, nil, nil, + nil, 229, 229, nil, nil, nil, 230, 230, 230, 229, + 230, 229, 229, 229, 230, 230, 229, 229, nil, 230, + nil, 230, 230, 230, 230, 230, 230, 230, nil, nil, + nil, nil, nil, 230, 230, 230, 230, 230, 230, 230, + nil, nil, 230, nil, nil, nil, nil, nil, nil, 230, + nil, nil, 230, 230, 230, 230, 230, 230, 230, 230, + nil, 230, 230, 230, nil, 230, 230, 230, 230, 230, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 230, + nil, nil, 230, nil, nil, 230, 230, nil, nil, 230, + nil, nil, nil, nil, nil, 230, nil, nil, nil, nil, + nil, nil, nil, nil, 230, nil, nil, nil, nil, 230, + 230, 230, 230, nil, 230, 230, 230, 230, nil, nil, + nil, nil, 230, 230, nil, nil, nil, 231, 231, 231, + 230, 231, 230, 230, 230, 231, 231, 230, 230, nil, + 231, nil, 231, 231, 231, 231, 231, 231, 231, nil, + nil, nil, nil, nil, 231, 231, 231, 231, 231, 231, + 231, nil, nil, 231, nil, nil, nil, nil, nil, nil, + 231, nil, nil, 231, 231, 231, 231, 231, 231, 231, + 231, nil, 231, 231, 231, nil, 231, 231, 231, 231, + 231, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 231, nil, nil, 231, nil, nil, 231, 231, nil, nil, + 231, nil, nil, nil, nil, nil, 231, nil, nil, nil, + nil, nil, nil, nil, nil, 231, nil, nil, nil, nil, + 231, 231, 231, 231, nil, 231, 231, 231, 231, nil, + nil, nil, nil, 231, 231, 231, nil, nil, 242, 242, + 242, 231, 242, 231, 231, 231, 242, 242, 231, 231, + nil, 242, nil, 242, 242, 242, 242, 242, 242, 242, + nil, nil, nil, nil, nil, 242, 242, 242, 242, 242, + 242, 242, nil, nil, 242, nil, nil, nil, nil, nil, + nil, 242, nil, nil, 242, 242, 242, 242, 242, 242, + 242, 242, nil, 242, 242, 242, nil, 242, 242, 242, + 242, 242, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 242, nil, nil, 242, nil, nil, 242, 242, nil, + nil, 242, nil, nil, nil, nil, nil, 242, nil, nil, + nil, nil, nil, nil, nil, nil, 242, nil, nil, nil, + nil, 242, 242, 242, 242, nil, 242, 242, 242, 242, + nil, nil, nil, nil, 242, 242, nil, nil, nil, 247, + 247, 247, 242, 247, 242, 242, 242, 247, 247, 242, + 242, nil, 247, nil, 247, 247, 247, 247, 247, 247, + 247, nil, nil, nil, nil, nil, 247, 247, 247, 247, + 247, 247, 247, nil, nil, 247, nil, nil, nil, nil, + nil, nil, 247, nil, nil, 247, 247, 247, 247, 247, + 247, 247, 247, nil, 247, 247, 247, nil, 247, 247, + 247, 247, 247, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 247, nil, nil, 247, nil, nil, 247, 247, + nil, nil, 247, nil, nil, nil, nil, nil, 247, nil, + nil, nil, nil, nil, nil, nil, nil, 247, nil, nil, + nil, nil, 247, 247, 247, 247, nil, 247, 247, 247, + 247, nil, nil, nil, nil, 247, 247, nil, nil, nil, + 248, 248, 248, 247, 248, 247, 247, 247, 248, 248, + 247, 247, nil, 248, nil, 248, 248, 248, 248, 248, + 248, 248, nil, nil, nil, nil, nil, 248, 248, 248, + 248, 248, 248, 248, nil, nil, 248, nil, nil, nil, + nil, nil, nil, 248, nil, nil, 248, 248, 248, 248, + 248, 248, 248, 248, nil, 248, 248, 248, nil, 248, + 248, 248, 248, 248, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 248, nil, nil, 248, nil, nil, 248, + 248, nil, nil, 248, nil, nil, nil, nil, nil, 248, + nil, nil, nil, nil, nil, nil, nil, nil, 248, nil, + nil, nil, nil, 248, 248, 248, 248, nil, 248, 248, + 248, 248, nil, nil, nil, nil, 248, 248, nil, nil, + nil, 249, 249, 249, 248, 249, 248, 248, 248, 249, + 249, 248, 248, nil, 249, nil, 249, 249, 249, 249, + 249, 249, 249, nil, nil, nil, nil, nil, 249, 249, + 249, 249, 249, 249, 249, nil, nil, 249, nil, nil, + nil, nil, nil, nil, 249, nil, nil, 249, 249, 249, + 249, 249, 249, 249, 249, nil, 249, 249, 249, nil, + 249, 249, 249, 249, 249, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 249, nil, nil, 249, nil, nil, + 249, 249, nil, nil, 249, nil, nil, nil, nil, nil, + 249, nil, nil, nil, nil, nil, nil, nil, nil, 249, + nil, nil, nil, nil, 249, 249, 249, 249, nil, 249, + 249, 249, 249, nil, nil, nil, nil, 249, 249, nil, + nil, nil, 250, 250, 250, 249, 250, 249, 249, 249, + 250, 250, 249, 249, nil, 250, nil, 250, 250, 250, + 250, 250, 250, 250, nil, nil, nil, nil, nil, 250, + 250, 250, 250, 250, 250, 250, nil, nil, 250, nil, + nil, nil, nil, nil, nil, 250, nil, nil, 250, 250, + 250, 250, 250, 250, 250, 250, nil, 250, 250, 250, + nil, 250, 250, 250, 250, 250, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 250, nil, nil, 250, nil, + nil, 250, 250, nil, nil, 250, nil, nil, nil, nil, + nil, 250, nil, nil, nil, nil, nil, nil, nil, nil, + 250, nil, nil, nil, nil, 250, 250, 250, 250, nil, + 250, 250, 250, 250, nil, nil, nil, nil, 250, 250, + nil, nil, nil, 251, 251, 251, 250, 251, 250, 250, + 250, 251, 251, 250, 250, nil, 251, nil, 251, 251, + 251, 251, 251, 251, 251, nil, nil, nil, nil, nil, + 251, 251, 251, 251, 251, 251, 251, nil, nil, 251, + nil, nil, nil, nil, nil, nil, 251, nil, nil, 251, + 251, 251, 251, 251, 251, 251, 251, nil, 251, 251, + 251, nil, 251, 251, 251, 251, 251, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, 251, + nil, nil, 251, 251, nil, nil, 251, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 251, 251, 251, 251, + nil, 251, 251, 251, 251, nil, nil, nil, nil, 251, + 251, nil, nil, nil, 252, 252, 252, 251, 252, 251, + 251, 251, 252, 252, 251, 251, nil, 252, nil, 252, + 252, 252, 252, 252, 252, 252, nil, nil, nil, nil, + nil, 252, 252, 252, 252, 252, 252, 252, nil, nil, + 252, nil, nil, nil, nil, nil, nil, 252, nil, nil, + 252, 252, 252, 252, 252, 252, 252, 252, nil, 252, + 252, 252, nil, 252, 252, 252, 252, 252, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 252, nil, nil, + 252, nil, nil, 252, 252, nil, nil, 252, nil, nil, + nil, nil, nil, 252, nil, nil, nil, nil, nil, nil, + nil, nil, 252, nil, nil, nil, nil, 252, 252, 252, + 252, nil, 252, 252, 252, 252, nil, nil, nil, nil, + 252, 252, nil, nil, nil, 253, 253, 253, 252, 253, + 252, 252, 252, 253, 253, 252, 252, nil, 253, nil, + 253, 253, 253, 253, 253, 253, 253, nil, nil, nil, + nil, nil, 253, 253, 253, 253, 253, 253, 253, nil, + nil, 253, nil, nil, nil, nil, nil, nil, 253, nil, + nil, 253, 253, 253, 253, 253, 253, 253, 253, nil, + 253, 253, 253, nil, 253, 253, 253, 253, 253, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 253, nil, + nil, 253, nil, nil, 253, 253, nil, nil, 253, nil, + nil, nil, nil, nil, 253, nil, nil, nil, nil, nil, + nil, nil, nil, 253, nil, nil, nil, nil, 253, 253, + 253, 253, nil, 253, 253, 253, 253, nil, nil, nil, + nil, 253, 253, nil, nil, nil, 254, 254, 254, 253, + 254, 253, 253, 253, 254, 254, 253, 253, nil, 254, + nil, 254, 254, 254, 254, 254, 254, 254, nil, nil, + nil, nil, nil, 254, 254, 254, 254, 254, 254, 254, + nil, nil, 254, nil, nil, nil, nil, nil, nil, 254, + nil, nil, 254, 254, 254, 254, 254, 254, 254, 254, + nil, 254, 254, 254, nil, 254, 254, 254, 254, 254, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 254, + nil, nil, 254, nil, nil, 254, 254, nil, nil, 254, + nil, nil, nil, nil, nil, 254, nil, nil, nil, nil, + nil, nil, nil, nil, 254, nil, nil, nil, nil, 254, + 254, 254, 254, nil, 254, 254, 254, 254, nil, nil, + nil, nil, 254, 254, nil, nil, nil, 255, 255, 255, + 254, 255, 254, 254, 254, 255, 255, 254, 254, nil, + 255, nil, 255, 255, 255, 255, 255, 255, 255, nil, + nil, nil, nil, nil, 255, 255, 255, 255, 255, 255, + 255, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 255, nil, nil, 255, 255, 255, 255, 255, 255, 255, + 255, nil, 255, 255, 255, nil, 255, 255, 255, 255, + 255, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 255, nil, nil, 255, nil, nil, 255, 255, nil, nil, + 255, nil, nil, nil, nil, nil, 255, nil, nil, nil, + nil, nil, nil, nil, nil, 255, nil, nil, nil, nil, + 255, 255, 255, 255, nil, 255, 255, 255, 255, nil, + nil, nil, nil, 255, 255, nil, nil, nil, 256, 256, + 256, 255, 256, 255, 255, 255, 256, 256, 255, 255, + nil, 256, nil, 256, 256, 256, 256, 256, 256, 256, + nil, nil, nil, nil, nil, 256, 256, 256, 256, 256, + 256, 256, nil, nil, 256, nil, nil, nil, nil, nil, + nil, 256, nil, nil, 256, 256, 256, 256, 256, 256, + 256, 256, nil, 256, 256, 256, nil, 256, 256, 256, + 256, 256, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 256, nil, nil, 256, nil, nil, 256, 256, nil, + nil, 256, nil, nil, nil, nil, nil, 256, nil, nil, + nil, nil, nil, nil, nil, nil, 256, nil, nil, nil, + nil, 256, 256, 256, 256, nil, 256, 256, 256, 256, + nil, nil, nil, nil, 256, 256, nil, nil, nil, 257, + 257, 257, 256, 257, 256, 256, 256, 257, 257, 256, + 256, nil, 257, nil, 257, 257, 257, 257, 257, 257, + 257, nil, nil, nil, nil, nil, 257, 257, 257, 257, + 257, 257, 257, nil, nil, 257, nil, nil, nil, nil, + nil, nil, 257, nil, nil, 257, 257, 257, 257, 257, + 257, 257, 257, nil, 257, 257, 257, nil, 257, 257, + 257, 257, 257, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 257, nil, nil, 257, nil, nil, 257, 257, + nil, nil, 257, nil, nil, nil, nil, nil, 257, nil, + nil, nil, nil, nil, nil, nil, nil, 257, nil, nil, + nil, nil, 257, 257, 257, 257, nil, 257, 257, 257, + 257, nil, nil, nil, nil, 257, 257, nil, nil, nil, + 258, 258, 258, 257, 258, 257, 257, 257, 258, 258, + 257, 257, nil, 258, nil, 258, 258, 258, 258, 258, + 258, 258, nil, nil, nil, nil, nil, 258, 258, 258, + 258, 258, 258, 258, nil, nil, 258, nil, nil, nil, + nil, nil, nil, 258, nil, nil, 258, 258, 258, 258, + 258, 258, 258, 258, nil, 258, 258, 258, nil, 258, + 258, 258, 258, 258, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 258, nil, nil, 258, nil, nil, 258, + 258, nil, nil, 258, nil, nil, nil, nil, nil, 258, + nil, nil, nil, nil, nil, nil, nil, nil, 258, nil, + nil, nil, nil, 258, 258, 258, 258, nil, 258, 258, + 258, 258, nil, nil, nil, nil, 258, 258, nil, nil, + nil, 259, 259, 259, 258, 259, 258, 258, 258, 259, + 259, 258, 258, nil, 259, nil, 259, 259, 259, 259, + 259, 259, 259, nil, nil, nil, nil, nil, 259, 259, + 259, 259, 259, 259, 259, nil, nil, 259, nil, nil, + nil, nil, nil, nil, 259, nil, nil, 259, 259, 259, + 259, 259, 259, 259, 259, nil, 259, 259, 259, nil, + 259, 259, 259, 259, 259, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 259, nil, nil, 259, nil, nil, + 259, 259, nil, nil, 259, nil, nil, nil, nil, nil, + 259, nil, nil, nil, nil, nil, nil, nil, nil, 259, + nil, nil, nil, nil, 259, 259, 259, 259, nil, 259, + 259, 259, 259, nil, nil, nil, nil, 259, 259, nil, + nil, nil, 260, 260, 260, 259, 260, 259, 259, 259, + 260, 260, 259, 259, nil, 260, nil, 260, 260, 260, + 260, 260, 260, 260, nil, nil, nil, nil, nil, 260, + 260, 260, 260, 260, 260, 260, nil, nil, 260, nil, + nil, nil, nil, nil, nil, 260, nil, nil, 260, 260, + 260, 260, 260, 260, 260, 260, nil, 260, 260, 260, + nil, 260, 260, 260, 260, 260, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 260, nil, nil, 260, nil, + nil, 260, 260, nil, nil, 260, nil, nil, nil, nil, + nil, 260, nil, nil, nil, nil, nil, nil, nil, nil, + 260, nil, nil, nil, nil, 260, 260, 260, 260, nil, + 260, 260, 260, 260, nil, nil, nil, nil, 260, 260, + nil, nil, nil, 261, 261, 261, 260, 261, 260, 260, + 260, 261, 261, 260, 260, nil, 261, nil, 261, 261, + 261, 261, 261, 261, 261, nil, nil, nil, nil, nil, + 261, 261, 261, 261, 261, 261, 261, nil, nil, 261, + nil, nil, nil, nil, nil, nil, 261, nil, nil, 261, + 261, 261, 261, 261, 261, 261, 261, nil, 261, 261, + 261, nil, 261, 261, 261, 261, 261, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 261, nil, nil, 261, + nil, nil, 261, 261, nil, nil, 261, nil, nil, nil, + nil, nil, 261, nil, nil, nil, nil, nil, nil, nil, + nil, 261, nil, nil, nil, nil, 261, 261, 261, 261, + nil, 261, 261, 261, 261, nil, nil, nil, nil, 261, + 261, nil, nil, nil, 262, 262, 262, 261, 262, 261, + 261, 261, 262, 262, 261, 261, nil, 262, nil, 262, + 262, 262, 262, 262, 262, 262, nil, nil, nil, nil, + nil, 262, 262, 262, 262, 262, 262, 262, nil, nil, + 262, nil, nil, nil, nil, nil, nil, 262, nil, nil, + 262, 262, 262, 262, 262, 262, 262, 262, nil, 262, + 262, 262, nil, 262, 262, 262, 262, 262, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 262, nil, nil, + 262, nil, nil, 262, 262, nil, nil, 262, nil, nil, + nil, nil, nil, 262, nil, nil, nil, nil, nil, nil, + nil, nil, 262, nil, nil, nil, nil, 262, 262, 262, + 262, nil, 262, 262, 262, 262, nil, nil, nil, nil, + 262, 262, nil, nil, nil, 263, 263, 263, 262, 263, + 262, 262, 262, 263, 263, 262, 262, nil, 263, nil, + 263, 263, 263, 263, 263, 263, 263, nil, nil, nil, + nil, nil, 263, 263, 263, 263, 263, 263, 263, nil, + nil, 263, nil, nil, nil, nil, nil, nil, 263, nil, + nil, 263, 263, 263, 263, 263, 263, 263, 263, nil, + 263, 263, 263, nil, 263, 263, 263, 263, 263, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 263, nil, + nil, 263, nil, nil, 263, 263, nil, nil, 263, nil, + nil, nil, nil, nil, 263, nil, nil, nil, nil, nil, + nil, nil, nil, 263, nil, nil, nil, nil, 263, 263, + 263, 263, nil, 263, 263, 263, 263, nil, nil, nil, + nil, 263, 263, nil, nil, nil, 264, 264, 264, 263, + 264, 263, 263, 263, 264, 264, 263, 263, nil, 264, + nil, 264, 264, 264, 264, 264, 264, 264, nil, nil, + nil, nil, nil, 264, 264, 264, 264, 264, 264, 264, + nil, nil, 264, nil, nil, nil, nil, nil, nil, 264, + nil, nil, 264, 264, 264, 264, 264, 264, 264, 264, + nil, 264, 264, 264, nil, 264, 264, 264, 264, 264, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 264, + nil, nil, 264, nil, nil, 264, 264, nil, nil, 264, + nil, nil, nil, nil, nil, 264, nil, nil, nil, nil, + nil, nil, nil, nil, 264, nil, nil, nil, nil, 264, + 264, 264, 264, nil, 264, 264, 264, 264, nil, nil, + nil, nil, 264, 264, nil, nil, nil, 265, 265, 265, + 264, 265, 264, 264, 264, 265, 265, 264, 264, nil, + 265, nil, 265, 265, 265, 265, 265, 265, 265, nil, + nil, nil, nil, nil, 265, 265, 265, 265, 265, 265, + 265, nil, nil, 265, nil, nil, nil, nil, nil, nil, + 265, nil, nil, 265, 265, 265, 265, 265, 265, 265, + 265, nil, 265, 265, 265, nil, 265, 265, 265, 265, + 265, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 265, nil, nil, 265, nil, nil, 265, 265, nil, nil, + 265, nil, nil, nil, nil, nil, 265, nil, nil, nil, + nil, nil, nil, nil, nil, 265, nil, nil, nil, nil, + 265, 265, 265, 265, nil, 265, 265, 265, 265, nil, + nil, nil, nil, 265, 265, nil, nil, nil, 266, 266, + 266, 265, 266, 265, 265, 265, 266, 266, 265, 265, + nil, 266, nil, 266, 266, 266, 266, 266, 266, 266, + nil, nil, nil, nil, nil, 266, 266, 266, 266, 266, + 266, 266, nil, nil, 266, nil, nil, nil, nil, nil, + nil, 266, nil, nil, 266, 266, 266, 266, 266, 266, + 266, 266, nil, 266, 266, 266, nil, 266, 266, 266, + 266, 266, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 266, nil, nil, 266, nil, nil, 266, 266, nil, + nil, 266, nil, nil, nil, nil, nil, 266, nil, nil, + nil, nil, nil, nil, nil, nil, 266, nil, nil, nil, + nil, 266, 266, 266, 266, nil, 266, 266, 266, 266, + nil, nil, nil, nil, 266, 266, nil, nil, nil, 267, + 267, 267, 266, 267, 266, 266, 266, 267, 267, 266, + 266, nil, 267, nil, 267, 267, 267, 267, 267, 267, + 267, nil, nil, nil, nil, nil, 267, 267, 267, 267, + 267, 267, 267, nil, nil, 267, nil, nil, nil, nil, + nil, nil, 267, nil, nil, 267, 267, 267, 267, 267, + 267, 267, 267, nil, 267, 267, 267, nil, 267, 267, + 267, 267, 267, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 267, nil, nil, 267, nil, nil, 267, 267, + nil, nil, 267, nil, nil, nil, nil, nil, 267, nil, + nil, nil, nil, nil, nil, nil, nil, 267, nil, nil, + nil, nil, 267, 267, 267, 267, nil, 267, 267, 267, + 267, nil, nil, nil, nil, 267, 267, nil, nil, nil, + 268, 268, 268, 267, 268, 267, 267, 267, 268, 268, + 267, 267, nil, 268, nil, 268, 268, 268, 268, 268, + 268, 268, nil, nil, nil, nil, nil, 268, 268, 268, + 268, 268, 268, 268, nil, nil, 268, nil, nil, nil, + nil, nil, nil, 268, nil, nil, 268, 268, 268, 268, + 268, 268, 268, 268, nil, 268, 268, 268, nil, 268, + 268, 268, 268, 268, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 268, nil, nil, 268, nil, nil, 268, + 268, nil, nil, 268, nil, nil, nil, nil, nil, 268, + nil, nil, nil, nil, nil, nil, nil, nil, 268, nil, + nil, nil, nil, 268, 268, 268, 268, nil, 268, 268, + 268, 268, nil, nil, nil, nil, 268, 268, nil, nil, + nil, 273, 273, 273, 268, 273, 268, 268, 268, 273, + 273, 268, 268, nil, 273, nil, 273, 273, 273, 273, + 273, 273, 273, nil, nil, nil, nil, nil, 273, 273, + 273, 273, 273, 273, 273, nil, nil, 273, nil, nil, + nil, nil, nil, nil, 273, nil, nil, 273, 273, 273, + 273, 273, 273, 273, 273, nil, 273, 273, 273, nil, + 273, 273, 273, 273, 273, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 273, nil, nil, 273, nil, nil, + 273, 273, nil, nil, 273, nil, nil, nil, nil, nil, + 273, nil, nil, nil, nil, nil, nil, nil, nil, 273, + nil, nil, nil, nil, 273, 273, 273, 273, nil, 273, + 273, 273, 273, nil, nil, nil, nil, 273, 273, nil, + nil, nil, 289, 289, 289, 273, 289, 273, 273, 273, + 289, 289, 273, 273, nil, 289, nil, 289, 289, 289, + 289, 289, 289, 289, nil, nil, nil, nil, nil, 289, + 289, 289, 289, 289, 289, 289, nil, nil, 289, nil, + nil, nil, nil, nil, nil, 289, nil, nil, 289, 289, + 289, 289, 289, 289, 289, 289, nil, 289, 289, 289, + nil, 289, 289, 289, 289, 289, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 289, nil, nil, 289, nil, + nil, 289, 289, nil, nil, 289, nil, nil, nil, nil, + nil, 289, nil, nil, nil, nil, nil, nil, nil, nil, + 289, nil, nil, nil, nil, 289, 289, 289, 289, nil, + 289, 289, 289, 289, nil, nil, nil, nil, 289, 289, + nil, nil, nil, 296, 296, 296, 289, 296, 289, 289, + 289, 296, 296, 289, 289, nil, 296, nil, 296, 296, + 296, 296, 296, 296, 296, nil, nil, nil, nil, nil, + 296, 296, 296, 296, 296, 296, 296, nil, nil, 296, + nil, nil, nil, nil, nil, nil, 296, nil, nil, 296, + 296, 296, 296, 296, 296, 296, 296, 296, 296, 296, + 296, nil, 296, 296, 296, 296, 296, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 296, nil, nil, 296, + nil, nil, 296, 296, nil, nil, 296, nil, 296, nil, + 296, nil, 296, nil, nil, 296, nil, nil, nil, nil, + nil, 296, nil, nil, nil, nil, 296, 296, 296, 296, + nil, 296, 296, 296, 296, nil, nil, nil, nil, 296, + 296, nil, nil, nil, 297, 297, 297, 296, 297, 296, + 296, 296, 297, 297, 296, 296, nil, 297, nil, 297, + 297, 297, 297, 297, 297, 297, nil, nil, nil, nil, + nil, 297, 297, 297, 297, 297, 297, 297, nil, nil, + 297, nil, nil, nil, nil, nil, nil, 297, nil, nil, + 297, 297, 297, 297, 297, 297, 297, 297, 297, 297, + 297, 297, nil, 297, 297, 297, 297, 297, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 297, nil, nil, + 297, nil, nil, 297, 297, nil, nil, 297, nil, 297, + nil, 297, nil, 297, nil, nil, 297, nil, nil, nil, + nil, nil, 297, nil, nil, nil, nil, 297, 297, 297, + 297, nil, 297, 297, 297, 297, nil, nil, nil, nil, + 297, 297, nil, nil, nil, 305, 305, 305, 297, 305, + 297, 297, 297, 305, 305, 297, 297, nil, 305, nil, + 305, 305, 305, 305, 305, 305, 305, nil, nil, nil, + nil, nil, 305, 305, 305, 305, 305, 305, 305, nil, + nil, 305, nil, nil, nil, nil, nil, nil, 305, nil, + nil, 305, 305, 305, 305, 305, 305, 305, 305, 305, + 305, 305, 305, nil, 305, 305, 305, 305, 305, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 305, nil, + nil, 305, nil, nil, 305, 305, nil, nil, 305, nil, + 305, nil, 305, nil, 305, nil, nil, 305, nil, nil, + nil, nil, nil, 305, nil, nil, nil, nil, 305, 305, + 305, 305, nil, 305, 305, 305, 305, nil, nil, nil, + nil, 305, 305, 305, nil, nil, 312, 312, 312, 305, + 312, 305, 305, 305, 312, 312, 305, 305, nil, 312, + nil, 312, 312, 312, 312, 312, 312, 312, nil, nil, + nil, nil, nil, 312, 312, 312, 312, 312, 312, 312, + nil, nil, 312, nil, nil, nil, nil, nil, nil, 312, + nil, nil, 312, 312, 312, 312, 312, 312, 312, 312, + nil, 312, 312, 312, nil, 312, 312, 312, 312, 312, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 312, + nil, nil, 312, nil, nil, 312, 312, nil, nil, 312, + nil, nil, nil, nil, nil, 312, nil, nil, nil, nil, + nil, nil, nil, nil, 312, nil, nil, nil, nil, 312, + 312, 312, 312, nil, 312, 312, 312, 312, nil, nil, + nil, nil, 312, 312, nil, nil, nil, 314, 314, 314, + 312, 314, 312, 312, 312, 314, 314, 312, 312, nil, + 314, nil, 314, 314, 314, 314, 314, 314, 314, nil, + nil, nil, nil, nil, 314, 314, 314, 314, 314, 314, + 314, nil, nil, 314, nil, nil, nil, nil, nil, nil, + 314, nil, nil, 314, 314, 314, 314, 314, 314, 314, + 314, nil, 314, 314, 314, nil, 314, 314, 314, 314, + 314, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 314, nil, nil, 314, nil, nil, 314, 314, nil, nil, + 314, nil, nil, nil, nil, nil, 314, nil, nil, nil, + nil, nil, nil, nil, nil, 314, nil, nil, nil, nil, + 314, 314, 314, 314, nil, 314, 314, 314, 314, nil, + nil, nil, nil, 314, 314, nil, nil, nil, 317, 317, + 317, 314, 317, 314, 314, 314, 317, 317, 314, 314, + nil, 317, nil, 317, 317, 317, 317, 317, 317, 317, + nil, nil, nil, nil, nil, 317, 317, 317, 317, 317, + 317, 317, nil, nil, 317, nil, nil, nil, nil, nil, + nil, 317, nil, nil, 317, 317, 317, 317, 317, 317, + 317, 317, nil, 317, 317, 317, nil, 317, 317, 317, + 317, 317, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 317, nil, nil, 317, nil, nil, 317, 317, nil, + nil, 317, nil, nil, nil, nil, nil, 317, nil, nil, + nil, nil, nil, nil, nil, nil, 317, nil, nil, nil, + nil, 317, 317, 317, 317, nil, 317, 317, 317, 317, + nil, nil, nil, nil, 317, 317, nil, nil, nil, 318, + 318, 318, 317, 318, 317, 317, 317, 318, 318, 317, + 317, nil, 318, nil, 318, 318, 318, 318, 318, 318, + 318, nil, nil, nil, nil, nil, 318, 318, 318, 318, + 318, 318, 318, nil, nil, 318, nil, nil, nil, nil, + nil, nil, 318, nil, nil, 318, 318, 318, 318, 318, + 318, 318, 318, nil, 318, 318, 318, nil, 318, 318, + 318, 318, 318, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 318, nil, nil, 318, nil, nil, 318, 318, + nil, nil, 318, nil, nil, nil, nil, nil, 318, nil, + nil, nil, nil, nil, nil, nil, nil, 318, nil, nil, + nil, nil, 318, 318, 318, 318, nil, 318, 318, 318, + 318, nil, nil, nil, nil, 318, 318, nil, nil, nil, + nil, nil, nil, 318, nil, 318, 318, 318, nil, nil, + 318, 318, 323, 323, 323, 323, 323, nil, nil, nil, + 323, 323, nil, nil, nil, 323, nil, 323, 323, 323, + 323, 323, 323, 323, nil, nil, nil, nil, nil, 323, + 323, 323, 323, 323, 323, 323, nil, nil, 323, nil, + nil, nil, nil, nil, 323, 323, nil, 323, 323, 323, + 323, 323, 323, 323, 323, 323, nil, 323, 323, 323, + nil, 323, 323, 323, 323, 323, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 323, nil, nil, 323, nil, + nil, 323, 323, nil, nil, 323, nil, 323, nil, nil, + nil, 323, nil, nil, nil, nil, nil, nil, nil, nil, + 323, nil, nil, nil, nil, 323, 323, 323, 323, nil, + 323, 323, 323, 323, nil, nil, nil, nil, 323, 323, + nil, nil, nil, 359, 359, 359, 323, 359, 323, 323, + 323, 359, 359, 323, 323, nil, 359, nil, 359, 359, + 359, 359, 359, 359, 359, nil, nil, nil, nil, nil, + 359, 359, 359, 359, 359, 359, 359, nil, nil, 359, + nil, nil, nil, nil, nil, nil, 359, nil, nil, 359, + 359, 359, 359, 359, 359, 359, 359, nil, 359, 359, + 359, nil, 359, 359, 359, 359, 359, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 359, nil, nil, 359, + nil, nil, 359, 359, nil, nil, 359, nil, nil, nil, + nil, nil, 359, nil, nil, nil, nil, nil, nil, nil, + nil, 359, nil, nil, nil, nil, 359, 359, 359, 359, + nil, 359, 359, 359, 359, nil, nil, nil, nil, 359, + 359, nil, nil, nil, 361, 361, 361, 359, 361, 359, + 359, 359, 361, 361, 359, 359, nil, 361, nil, 361, + 361, 361, 361, 361, 361, 361, nil, nil, nil, nil, + nil, 361, 361, 361, 361, 361, 361, 361, nil, nil, + 361, nil, nil, nil, nil, nil, nil, 361, nil, nil, + 361, 361, 361, 361, 361, 361, 361, 361, nil, 361, + 361, 361, nil, 361, 361, 361, 361, 361, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 361, nil, nil, + 361, 361, nil, 361, 361, nil, nil, 361, nil, nil, + nil, nil, nil, 361, nil, nil, nil, nil, nil, nil, + nil, nil, 361, nil, nil, nil, nil, 361, 361, 361, + 361, nil, 361, 361, 361, 361, nil, nil, nil, nil, + 361, 361, nil, nil, nil, 384, 384, 384, 361, 384, + 361, 361, 361, 384, 384, 361, 361, nil, 384, nil, + 384, 384, 384, 384, 384, 384, 384, nil, nil, nil, + nil, nil, 384, 384, 384, 384, 384, 384, 384, nil, + nil, 384, nil, nil, nil, nil, nil, nil, 384, nil, + nil, 384, 384, 384, 384, 384, 384, 384, 384, nil, + 384, 384, 384, nil, 384, 384, 384, 384, 384, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 384, nil, + nil, 384, nil, nil, 384, 384, nil, nil, 384, nil, + nil, nil, nil, nil, 384, nil, nil, nil, nil, nil, + nil, nil, nil, 384, nil, nil, nil, nil, 384, 384, + 384, 384, nil, 384, 384, 384, 384, nil, nil, nil, + nil, 384, 384, nil, nil, nil, 405, 405, 405, 384, + 405, 384, 384, 384, 405, 405, 384, 384, nil, 405, + nil, 405, 405, 405, 405, 405, 405, 405, nil, nil, + nil, nil, nil, 405, 405, 405, 405, 405, 405, 405, + nil, nil, 405, nil, nil, nil, nil, nil, nil, 405, + nil, nil, 405, 405, 405, 405, 405, 405, 405, 405, + nil, 405, 405, 405, nil, 405, 405, 405, 405, 405, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 405, + nil, nil, 405, nil, nil, 405, 405, nil, nil, 405, + nil, nil, nil, nil, nil, 405, nil, nil, nil, nil, + nil, nil, nil, nil, 405, nil, nil, nil, nil, 405, + 405, 405, 405, nil, 405, 405, 405, 405, nil, nil, + nil, nil, 405, 405, nil, nil, nil, 434, 434, 434, + 405, 434, 405, 405, 405, 434, 434, 405, 405, nil, + 434, nil, 434, 434, 434, 434, 434, 434, 434, nil, + nil, nil, nil, nil, 434, 434, 434, 434, 434, 434, + 434, nil, nil, 434, nil, nil, nil, nil, nil, nil, + 434, nil, nil, 434, 434, 434, 434, 434, 434, 434, + 434, nil, 434, 434, 434, nil, 434, 434, 434, 434, + 434, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 434, nil, nil, 434, nil, nil, 434, 434, nil, nil, + 434, nil, nil, nil, nil, nil, 434, nil, nil, nil, + nil, nil, nil, nil, nil, 434, nil, nil, nil, nil, + 434, 434, 434, 434, nil, 434, 434, 434, 434, nil, + nil, nil, nil, 434, 434, nil, nil, nil, nil, nil, + nil, 434, nil, 434, 434, 434, 458, nil, 434, 434, + nil, nil, nil, 458, 458, 458, nil, nil, 458, 458, + 458, nil, 458, nil, nil, nil, nil, nil, nil, nil, + 458, 458, 458, 458, nil, nil, nil, nil, nil, nil, + nil, nil, 458, 458, nil, 458, 458, 458, 458, 458, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 458, 458, 458, 458, 458, 458, 458, 458, + 458, 458, 458, 458, 458, 458, nil, nil, 458, 458, + 458, nil, nil, 458, nil, 458, 458, nil, nil, 458, + 458, nil, 458, nil, 458, nil, 458, nil, 458, 458, + nil, 458, 458, 458, 458, 458, nil, 458, 458, 458, + 777, nil, 777, 777, 777, 777, 777, nil, nil, nil, + nil, nil, nil, 458, nil, 777, 458, 458, 467, 458, + nil, 458, nil, nil, nil, 467, 467, 467, 458, nil, + 467, 467, 467, nil, 467, nil, nil, 777, nil, nil, + nil, nil, 467, 467, 467, 467, 467, nil, 777, 777, + nil, nil, nil, 777, 467, 467, nil, 467, 467, 467, + 467, 467, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, nil, nil, + 467, 467, 467, nil, nil, 467, nil, nil, 467, nil, + nil, 467, 467, nil, 467, nil, 467, nil, 467, nil, + 467, 467, nil, 467, 467, 467, 467, 467, nil, 467, + 467, 467, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 467, nil, nil, 467, 467, + 467, 467, nil, 467, 468, 467, nil, nil, nil, nil, + 467, 468, 468, 468, nil, nil, 468, 468, 468, nil, + 468, nil, nil, nil, nil, nil, nil, nil, 468, 468, + 468, 468, 468, nil, nil, nil, nil, nil, nil, nil, + 468, 468, nil, 468, 468, 468, 468, 468, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 468, 468, 468, 468, 468, 468, 468, 468, 468, 468, + 468, 468, 468, 468, nil, nil, 468, 468, 468, nil, + nil, 468, nil, nil, 468, nil, nil, 468, 468, nil, + 468, nil, 468, nil, 468, nil, 468, 468, nil, 468, + 468, 468, 468, 468, nil, 468, 468, 468, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 468, nil, nil, 468, 468, 468, 468, nil, 468, + nil, 468, nil, 477, 477, 477, 468, 477, nil, nil, + nil, 477, 477, nil, nil, nil, 477, nil, 477, 477, + 477, 477, 477, 477, 477, nil, nil, nil, nil, nil, + 477, 477, 477, 477, 477, 477, 477, nil, nil, 477, + nil, nil, nil, nil, nil, nil, 477, nil, nil, 477, + 477, 477, 477, 477, 477, 477, 477, 477, 477, 477, + 477, nil, 477, 477, 477, 477, 477, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 477, nil, nil, 477, + nil, nil, 477, 477, nil, nil, 477, nil, 477, nil, + 477, nil, 477, nil, nil, 477, nil, nil, nil, nil, + nil, 477, nil, nil, nil, nil, 477, 477, 477, 477, + nil, 477, 477, 477, 477, nil, nil, nil, nil, 477, + 477, nil, nil, nil, 479, 479, 479, 477, 479, 477, + 477, 477, 479, 479, 477, 477, nil, 479, nil, 479, + 479, 479, 479, 479, 479, 479, nil, nil, nil, nil, + nil, 479, 479, 479, 479, 479, 479, 479, nil, nil, + 479, nil, nil, nil, nil, nil, nil, 479, nil, nil, + 479, 479, 479, 479, 479, 479, 479, 479, nil, 479, + 479, 479, nil, 479, 479, 479, 479, 479, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 479, nil, nil, + 479, nil, nil, 479, 479, nil, nil, 479, nil, nil, + nil, nil, nil, 479, nil, nil, nil, nil, nil, nil, + nil, nil, 479, nil, nil, nil, nil, 479, 479, 479, + 479, nil, 479, 479, 479, 479, nil, nil, nil, nil, + 479, 479, nil, nil, nil, 480, 480, 480, 479, 480, + 479, 479, 479, 480, 480, 479, 479, nil, 480, nil, + 480, 480, 480, 480, 480, 480, 480, nil, nil, nil, + nil, nil, 480, 480, 480, 480, 480, 480, 480, nil, + nil, 480, nil, nil, nil, nil, nil, nil, 480, nil, + nil, 480, 480, 480, 480, 480, 480, 480, 480, nil, + 480, 480, 480, nil, 480, 480, 480, 480, 480, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 480, nil, + nil, 480, nil, nil, 480, 480, nil, nil, 480, nil, + nil, nil, nil, nil, 480, nil, nil, nil, nil, nil, + nil, nil, nil, 480, nil, nil, nil, nil, 480, 480, + 480, 480, nil, 480, 480, 480, 480, nil, nil, nil, + nil, 480, 480, nil, nil, nil, 481, 481, 481, 480, + 481, 480, 480, 480, 481, 481, 480, 480, nil, 481, + nil, 481, 481, 481, 481, 481, 481, 481, nil, nil, + nil, nil, nil, 481, 481, 481, 481, 481, 481, 481, + nil, nil, 481, nil, nil, nil, nil, nil, nil, 481, + nil, nil, 481, 481, 481, 481, 481, 481, 481, 481, + nil, 481, 481, 481, nil, 481, 481, 481, 481, 481, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 481, + nil, nil, 481, nil, nil, 481, 481, nil, nil, 481, + nil, nil, nil, nil, nil, 481, nil, nil, nil, nil, + nil, nil, nil, nil, 481, nil, nil, nil, nil, 481, + 481, 481, 481, nil, 481, 481, 481, 481, nil, nil, + nil, nil, 481, 481, nil, nil, nil, nil, nil, nil, + 481, nil, 481, 481, 481, 510, nil, 481, 481, nil, + nil, nil, 510, 510, 510, nil, nil, 510, 510, 510, + 907, 510, 907, 907, 907, 907, 907, nil, nil, 510, + 510, 510, nil, nil, nil, 907, nil, nil, nil, nil, + nil, 510, 510, nil, 510, 510, 510, 510, 510, nil, + nil, nil, nil, nil, nil, nil, 367, 907, 367, 367, + 367, 367, 367, nil, nil, nil, 907, 907, 907, 907, + nil, 367, nil, 907, nil, 407, nil, 407, 407, 407, + 407, 407, 510, nil, nil, nil, nil, nil, nil, 510, + 407, nil, nil, 367, 510, 510, nil, nil, nil, 907, + nil, nil, 367, 367, 367, 367, nil, nil, nil, 367, + nil, nil, 407, 407, nil, nil, nil, 510, 510, nil, + nil, 407, 407, 407, 407, nil, nil, nil, 407, nil, + nil, nil, 510, nil, nil, 510, nil, 515, 515, 515, + 510, 515, nil, nil, nil, 515, 515, 510, nil, nil, + 515, nil, 515, 515, 515, 515, 515, 515, 515, nil, + nil, nil, nil, nil, 515, 515, 515, 515, 515, 515, + 515, nil, nil, 515, nil, nil, nil, nil, nil, nil, + 515, nil, nil, 515, 515, 515, 515, 515, 515, 515, + 515, nil, 515, 515, 515, nil, 515, 515, 515, 515, + 515, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 515, nil, nil, 515, nil, nil, 515, 515, nil, nil, + 515, nil, nil, nil, nil, nil, 515, nil, nil, nil, + nil, nil, nil, nil, nil, 515, nil, nil, nil, nil, + 515, 515, 515, 515, nil, 515, 515, 515, 515, nil, + nil, nil, nil, 515, 515, nil, nil, nil, 525, 525, + 525, 515, 525, 515, 515, 515, 525, 525, 515, 515, + nil, 525, nil, 525, 525, 525, 525, 525, 525, 525, + nil, nil, nil, nil, nil, 525, 525, 525, 525, 525, + 525, 525, nil, nil, 525, nil, nil, nil, nil, nil, + nil, 525, nil, nil, 525, 525, 525, 525, 525, 525, + 525, 525, 525, 525, 525, 525, nil, 525, 525, 525, + 525, 525, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 525, nil, nil, 525, nil, nil, 525, 525, nil, + nil, 525, nil, 525, nil, 525, nil, 525, nil, nil, + 525, nil, nil, nil, nil, nil, 525, nil, nil, nil, + nil, 525, 525, 525, 525, nil, 525, 525, 525, 525, + nil, nil, nil, nil, 525, 525, nil, nil, nil, 527, + 527, 527, 525, 527, 525, 525, 525, 527, 527, 525, + 525, nil, 527, nil, 527, 527, 527, 527, 527, 527, + 527, nil, nil, nil, nil, nil, 527, 527, 527, 527, + 527, 527, 527, nil, nil, 527, nil, nil, nil, nil, + nil, nil, 527, nil, nil, 527, 527, 527, 527, 527, + 527, 527, 527, 527, 527, 527, 527, nil, 527, 527, + 527, 527, 527, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 527, nil, nil, 527, nil, nil, 527, 527, + nil, nil, 527, nil, nil, nil, 527, nil, 527, nil, + nil, 527, nil, nil, nil, nil, nil, 527, nil, nil, + nil, nil, 527, 527, 527, 527, nil, 527, 527, 527, + 527, nil, nil, nil, nil, 527, 527, nil, nil, nil, + 529, 529, 529, 527, 529, 527, 527, 527, 529, 529, + 527, 527, nil, 529, nil, 529, 529, 529, 529, 529, + 529, 529, nil, nil, nil, nil, nil, 529, 529, 529, + 529, 529, 529, 529, nil, nil, 529, nil, nil, nil, + nil, nil, nil, 529, nil, nil, 529, 529, 529, 529, + 529, 529, 529, 529, nil, 529, 529, 529, nil, 529, + 529, 529, 529, 529, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 529, nil, nil, 529, nil, nil, 529, + 529, nil, nil, 529, nil, nil, nil, nil, nil, 529, + nil, nil, nil, nil, nil, nil, nil, nil, 529, nil, + nil, nil, nil, 529, 529, 529, 529, nil, 529, 529, + 529, 529, nil, nil, nil, nil, 529, 529, nil, nil, + nil, nil, nil, nil, 529, nil, 529, 529, 529, nil, + nil, 529, 529, 535, 535, 535, 535, 535, nil, nil, + nil, 535, 535, nil, nil, nil, 535, nil, 535, 535, + 535, 535, 535, 535, 535, nil, nil, nil, nil, nil, + 535, 535, 535, 535, 535, 535, 535, nil, nil, 535, + nil, nil, nil, nil, nil, 535, 535, 535, 535, 535, + 535, 535, 535, 535, 535, 535, 535, nil, 535, 535, + 535, nil, 535, 535, 535, 535, 535, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 535, nil, nil, 535, + nil, nil, 535, 535, nil, nil, 535, nil, 535, nil, + nil, nil, 535, nil, nil, nil, nil, nil, nil, nil, + nil, 535, nil, nil, nil, nil, 535, 535, 535, 535, + nil, 535, 535, 535, 535, nil, nil, nil, nil, 535, + 535, nil, nil, nil, nil, nil, 535, 535, nil, 535, + 535, 535, nil, nil, 535, 535, 545, 545, 545, nil, + 545, nil, nil, nil, 545, 545, nil, nil, nil, 545, + nil, 545, 545, 545, 545, 545, 545, 545, nil, nil, + nil, nil, nil, 545, 545, 545, 545, 545, 545, 545, + nil, nil, 545, nil, nil, nil, nil, nil, nil, 545, + nil, nil, 545, 545, 545, 545, 545, 545, 545, 545, + 545, 545, 545, 545, nil, 545, 545, 545, 545, 545, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 545, + nil, nil, 545, nil, nil, 545, 545, nil, nil, 545, + nil, 545, nil, 545, nil, 545, nil, nil, 545, nil, + nil, nil, nil, nil, 545, nil, nil, nil, nil, 545, + 545, 545, 545, nil, 545, 545, 545, 545, nil, nil, + nil, nil, 545, 545, nil, nil, nil, 555, 555, 555, + 545, 555, 545, 545, 545, 555, 555, 545, 545, nil, + 555, nil, 555, 555, 555, 555, 555, 555, 555, nil, + nil, nil, nil, nil, 555, 555, 555, 555, 555, 555, + 555, nil, nil, 555, nil, nil, nil, nil, nil, nil, + 555, nil, nil, 555, 555, 555, 555, 555, 555, 555, + 555, nil, 555, 555, 555, nil, 555, 555, 555, 555, + 555, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 555, nil, nil, 555, nil, nil, 555, 555, nil, nil, + 555, nil, nil, nil, nil, nil, 555, nil, nil, nil, + nil, nil, nil, nil, nil, 555, nil, nil, nil, nil, + 555, 555, 555, 555, nil, 555, 555, 555, 555, nil, + nil, nil, nil, 555, 555, nil, nil, nil, 558, 558, + 558, 555, 558, 555, 555, 555, 558, 558, 555, 555, + nil, 558, nil, 558, 558, 558, 558, 558, 558, 558, + nil, nil, nil, nil, nil, 558, 558, 558, 558, 558, + 558, 558, nil, nil, 558, nil, nil, nil, nil, nil, + nil, 558, nil, nil, 558, 558, 558, 558, 558, 558, + 558, 558, nil, 558, 558, 558, nil, 558, 558, 558, + 558, 558, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 558, nil, nil, 558, nil, nil, 558, 558, nil, + nil, 558, nil, nil, nil, nil, nil, 558, nil, nil, + nil, nil, nil, nil, nil, nil, 558, nil, nil, nil, + nil, 558, 558, 558, 558, nil, 558, 558, 558, 558, + nil, nil, nil, nil, 558, 558, nil, nil, nil, 561, + 561, 561, 558, 561, 558, 558, 558, 561, 561, 558, + 558, nil, 561, nil, 561, 561, 561, 561, 561, 561, + 561, nil, nil, nil, nil, nil, 561, 561, 561, 561, + 561, 561, 561, nil, nil, 561, nil, nil, nil, nil, + nil, nil, 561, nil, nil, 561, 561, 561, 561, 561, + 561, 561, 561, nil, 561, 561, 561, nil, 561, 561, + 561, 561, 561, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 561, nil, nil, 561, nil, nil, 561, 561, + nil, nil, 561, nil, nil, nil, nil, nil, 561, nil, + nil, nil, nil, nil, nil, nil, nil, 561, nil, nil, + nil, nil, 561, 561, 561, 561, nil, 561, 561, 561, + 561, nil, nil, nil, nil, 561, 561, nil, nil, nil, + 562, 562, 562, 561, 562, 561, 561, 561, 562, 562, + 561, 561, nil, 562, nil, 562, 562, 562, 562, 562, + 562, 562, nil, nil, nil, nil, nil, 562, 562, 562, + 562, 562, 562, 562, nil, nil, 562, nil, nil, nil, + nil, nil, nil, 562, nil, nil, 562, 562, 562, 562, + 562, 562, 562, 562, nil, 562, 562, 562, nil, 562, + 562, 562, 562, 562, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 562, nil, nil, 562, nil, nil, 562, + 562, nil, nil, 562, nil, nil, nil, nil, nil, 562, + nil, nil, nil, nil, nil, nil, nil, nil, 562, nil, + nil, nil, nil, 562, 562, 562, 562, nil, 562, 562, + 562, 562, nil, nil, nil, nil, 562, 562, nil, nil, + nil, 588, 588, 588, 562, 588, 562, 562, 562, 588, + 588, 562, 562, nil, 588, nil, 588, 588, 588, 588, + 588, 588, 588, nil, nil, nil, nil, nil, 588, 588, + 588, 588, 588, 588, 588, nil, nil, 588, nil, nil, + nil, nil, nil, nil, 588, nil, nil, 588, 588, 588, + 588, 588, 588, 588, 588, nil, 588, 588, 588, nil, + 588, 588, 588, 588, 588, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 588, nil, nil, 588, nil, nil, + 588, 588, nil, nil, 588, nil, nil, nil, nil, nil, + 588, nil, nil, nil, nil, nil, nil, nil, nil, 588, + nil, nil, nil, nil, 588, 588, 588, 588, nil, 588, + 588, 588, 588, nil, nil, nil, nil, 588, 588, nil, + nil, nil, 602, 602, 602, 588, 602, 588, 588, 588, + 602, 602, 588, 588, nil, 602, nil, 602, 602, 602, + 602, 602, 602, 602, nil, nil, nil, nil, nil, 602, + 602, 602, 602, 602, 602, 602, nil, nil, 602, nil, + nil, nil, nil, nil, nil, 602, nil, nil, 602, 602, + 602, 602, 602, 602, 602, 602, nil, 602, 602, 602, + nil, 602, 602, 602, 602, 602, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 602, nil, nil, 602, nil, + nil, 602, 602, nil, nil, 602, nil, nil, nil, nil, + nil, 602, nil, nil, nil, nil, nil, nil, nil, nil, + 602, nil, nil, nil, nil, 602, 602, 602, 602, nil, + 602, 602, 602, 602, nil, nil, nil, nil, 602, 602, + nil, nil, nil, 608, 608, 608, 602, 608, 602, 602, + 602, 608, 608, 602, 602, nil, 608, nil, 608, 608, + 608, 608, 608, 608, 608, nil, nil, nil, nil, nil, + 608, 608, 608, 608, 608, 608, 608, nil, nil, 608, + nil, nil, nil, nil, nil, nil, 608, nil, nil, 608, + 608, 608, 608, 608, 608, 608, 608, 608, 608, 608, + 608, nil, 608, 608, 608, 608, 608, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 608, nil, nil, 608, + nil, nil, 608, 608, nil, nil, 608, nil, 608, nil, + nil, nil, 608, nil, nil, 608, nil, nil, nil, nil, + nil, 608, nil, nil, nil, nil, 608, 608, 608, 608, + nil, 608, 608, 608, 608, nil, nil, nil, nil, 608, + 608, nil, nil, nil, 611, 611, 611, 608, 611, 608, + 608, 608, 611, 611, 608, 608, nil, 611, nil, 611, + 611, 611, 611, 611, 611, 611, nil, nil, nil, nil, + nil, 611, 611, 611, 611, 611, 611, 611, nil, nil, + 611, nil, nil, nil, nil, nil, nil, 611, nil, nil, + 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, + 611, 611, nil, 611, 611, 611, 611, 611, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 611, nil, nil, + 611, nil, nil, 611, 611, nil, nil, 611, nil, nil, + nil, nil, nil, 611, nil, nil, 611, nil, nil, nil, + nil, nil, 611, nil, nil, nil, nil, 611, 611, 611, + 611, nil, 611, 611, 611, 611, nil, nil, nil, nil, + 611, 611, nil, nil, nil, 624, 624, 624, 611, 624, + 611, 611, 611, 624, 624, 611, 611, nil, 624, nil, + 624, 624, 624, 624, 624, 624, 624, nil, nil, nil, + nil, nil, 624, 624, 624, 624, 624, 624, 624, nil, + nil, 624, nil, nil, nil, nil, nil, nil, 624, nil, + nil, 624, 624, 624, 624, 624, 624, 624, 624, nil, + 624, 624, 624, nil, 624, 624, 624, 624, 624, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 624, nil, + nil, 624, nil, nil, 624, 624, nil, nil, 624, nil, + 624, nil, nil, nil, 624, nil, nil, nil, nil, nil, + nil, nil, nil, 624, nil, nil, nil, nil, 624, 624, + 624, 624, nil, 624, 624, 624, 624, nil, nil, nil, + nil, 624, 624, nil, nil, nil, 625, 625, 625, 624, + 625, 624, 624, 624, 625, 625, 624, 624, nil, 625, + nil, 625, 625, 625, 625, 625, 625, 625, nil, nil, + nil, nil, nil, 625, 625, 625, 625, 625, 625, 625, + nil, nil, 625, nil, nil, nil, nil, nil, nil, 625, + nil, nil, 625, 625, 625, 625, 625, 625, 625, 625, + 625, 625, 625, 625, nil, 625, 625, 625, 625, 625, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 625, + nil, nil, 625, nil, nil, 625, 625, nil, nil, 625, + nil, 625, nil, 625, nil, 625, nil, nil, 625, nil, + nil, nil, nil, nil, 625, nil, nil, nil, nil, 625, + 625, 625, 625, nil, 625, 625, 625, 625, nil, nil, + nil, nil, 625, 625, nil, nil, nil, 635, 635, 635, + 625, 635, 625, 625, 625, 635, 635, 625, 625, nil, + 635, nil, 635, 635, 635, 635, 635, 635, 635, nil, + nil, nil, nil, nil, 635, 635, 635, 635, 635, 635, + 635, nil, nil, 635, nil, nil, nil, nil, nil, nil, + 635, nil, nil, 635, 635, 635, 635, 635, 635, 635, + 635, 635, 635, 635, 635, nil, 635, 635, 635, 635, + 635, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 635, nil, nil, 635, nil, nil, 635, 635, nil, nil, + 635, nil, 635, nil, 635, nil, 635, nil, nil, 635, + nil, nil, nil, nil, nil, 635, nil, nil, nil, nil, + 635, 635, 635, 635, nil, 635, 635, 635, 635, nil, + nil, nil, nil, 635, 635, nil, nil, nil, nil, nil, + nil, 635, nil, 635, 635, 635, nil, nil, 635, 635, + 666, 666, 666, 666, 666, nil, nil, nil, 666, 666, + nil, nil, nil, 666, nil, 666, 666, 666, 666, 666, + 666, 666, nil, nil, nil, nil, nil, 666, 666, 666, + 666, 666, 666, 666, nil, nil, 666, nil, nil, nil, + nil, nil, 666, 666, nil, 666, 666, 666, 666, 666, + 666, 666, 666, 666, nil, 666, 666, 666, nil, 666, + 666, 666, 666, 666, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 666, nil, nil, 666, nil, nil, 666, + 666, nil, nil, 666, nil, 666, nil, nil, nil, 666, + nil, nil, nil, nil, nil, nil, nil, nil, 666, nil, + nil, nil, nil, 666, 666, 666, 666, nil, 666, 666, + 666, 666, nil, nil, nil, nil, 666, 666, nil, nil, + nil, 668, 668, 668, 666, 668, 666, 666, 666, 668, + 668, 666, 666, nil, 668, nil, 668, 668, 668, 668, + 668, 668, 668, nil, nil, nil, nil, nil, 668, 668, + 668, 668, 668, 668, 668, nil, nil, 668, nil, nil, + nil, nil, nil, nil, 668, nil, nil, 668, 668, 668, + 668, 668, 668, 668, 668, nil, 668, 668, 668, nil, + 668, 668, 668, 668, 668, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 668, nil, nil, 668, nil, nil, + 668, 668, nil, nil, 668, nil, 668, nil, nil, nil, + 668, nil, nil, nil, nil, nil, nil, nil, nil, 668, + nil, nil, nil, nil, 668, 668, 668, 668, nil, 668, + 668, 668, 668, nil, nil, nil, nil, 668, 668, nil, + nil, nil, 669, 669, 669, 668, 669, 668, 668, 668, + 669, 669, 668, 668, nil, 669, nil, 669, 669, 669, + 669, 669, 669, 669, nil, nil, nil, nil, nil, 669, + 669, 669, 669, 669, 669, 669, nil, nil, 669, nil, + nil, nil, nil, nil, nil, 669, nil, nil, 669, 669, + 669, 669, 669, 669, 669, 669, nil, 669, 669, 669, + nil, 669, 669, 669, 669, 669, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 669, nil, nil, 669, nil, + nil, 669, 669, nil, nil, 669, nil, nil, nil, nil, + nil, 669, nil, nil, nil, nil, nil, nil, nil, nil, + 669, nil, nil, nil, nil, 669, 669, 669, 669, nil, + 669, 669, 669, 669, nil, nil, nil, nil, 669, 669, + nil, nil, nil, 670, 670, 670, 669, 670, 669, 669, + 669, 670, 670, 669, 669, nil, 670, nil, 670, 670, + 670, 670, 670, 670, 670, nil, nil, nil, nil, nil, + 670, 670, 670, 670, 670, 670, 670, nil, nil, 670, + nil, nil, nil, nil, nil, nil, 670, nil, nil, 670, + 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, + 670, nil, 670, 670, 670, 670, 670, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 670, nil, nil, 670, + nil, nil, 670, 670, nil, nil, 670, nil, 670, nil, + 670, nil, 670, nil, nil, 670, nil, nil, nil, nil, + nil, 670, nil, nil, nil, nil, 670, 670, 670, 670, + nil, 670, 670, 670, 670, nil, nil, nil, nil, 670, + 670, nil, nil, nil, nil, nil, nil, 670, nil, 670, + 670, 670, nil, nil, 670, 670, 673, 673, 673, 673, + 673, nil, nil, nil, 673, 673, nil, nil, nil, 673, + nil, 673, 673, 673, 673, 673, 673, 673, nil, nil, + nil, nil, nil, 673, 673, 673, 673, 673, 673, 673, + nil, nil, 673, nil, nil, nil, nil, nil, 673, 673, + nil, 673, 673, 673, 673, 673, 673, 673, 673, 673, + nil, 673, 673, 673, nil, 673, 673, 673, 673, 673, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 673, + nil, nil, 673, nil, nil, 673, 673, nil, nil, 673, + nil, 673, nil, nil, nil, 673, nil, nil, nil, nil, + nil, nil, nil, nil, 673, nil, nil, nil, nil, 673, + 673, 673, 673, nil, 673, 673, 673, 673, nil, nil, + nil, nil, 673, 673, nil, nil, nil, 674, 674, 674, + 673, 674, 673, 673, 673, 674, 674, 673, 673, nil, + 674, nil, 674, 674, 674, 674, 674, 674, 674, nil, + nil, nil, nil, nil, 674, 674, 674, 674, 674, 674, + 674, nil, nil, 674, nil, nil, nil, nil, nil, nil, + 674, nil, nil, 674, 674, 674, 674, 674, 674, 674, + 674, nil, 674, 674, 674, nil, 674, 674, 674, 674, + 674, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 674, nil, nil, 674, nil, nil, 674, 674, nil, nil, + 674, nil, nil, nil, nil, nil, 674, nil, nil, nil, + nil, nil, nil, nil, nil, 674, nil, nil, nil, nil, + 674, 674, 674, 674, nil, 674, 674, 674, 674, nil, + nil, nil, nil, 674, 674, nil, nil, nil, 677, 677, + 677, 674, 677, 674, 674, 674, 677, 677, 674, 674, + nil, 677, nil, 677, 677, 677, 677, 677, 677, 677, + nil, nil, nil, nil, nil, 677, 677, 677, 677, 677, + 677, 677, nil, nil, 677, nil, nil, nil, nil, nil, + nil, 677, nil, nil, 677, 677, 677, 677, 677, 677, + 677, 677, 677, 677, 677, 677, nil, 677, 677, 677, + 677, 677, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 677, nil, nil, 677, nil, nil, 677, 677, nil, + nil, 677, nil, 677, nil, 677, nil, 677, nil, nil, + 677, nil, nil, nil, nil, nil, 677, nil, nil, nil, + nil, 677, 677, 677, 677, nil, 677, 677, 677, 677, + nil, nil, nil, nil, 677, 677, nil, nil, nil, 678, + 678, 678, 677, 678, 677, 677, 677, 678, 678, 677, + 677, nil, 678, nil, 678, 678, 678, 678, 678, 678, + 678, nil, nil, nil, nil, nil, 678, 678, 678, 678, + 678, 678, 678, nil, nil, 678, nil, nil, nil, nil, + nil, nil, 678, nil, nil, 678, 678, 678, 678, 678, + 678, 678, 678, 678, 678, 678, 678, nil, 678, 678, + 678, 678, 678, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 678, nil, nil, 678, nil, nil, 678, 678, + nil, nil, 678, nil, nil, nil, 678, nil, 678, nil, + nil, 678, nil, nil, nil, nil, nil, 678, nil, nil, + nil, nil, 678, 678, 678, 678, nil, 678, 678, 678, + 678, nil, nil, nil, nil, 678, 678, nil, nil, nil, + 679, 679, 679, 678, 679, 678, 678, 678, 679, 679, + 678, 678, nil, 679, nil, 679, 679, 679, 679, 679, + 679, 679, nil, nil, nil, nil, nil, 679, 679, 679, + 679, 679, 679, 679, nil, nil, 679, nil, nil, nil, + nil, nil, nil, 679, nil, nil, 679, 679, 679, 679, + 679, 679, 679, 679, nil, 679, 679, 679, nil, 679, + 679, 679, 679, 679, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 679, nil, nil, 679, nil, nil, 679, + 679, nil, nil, 679, nil, nil, nil, nil, nil, 679, + nil, nil, nil, nil, nil, nil, nil, nil, 679, nil, + nil, nil, nil, 679, 679, 679, 679, nil, 679, 679, + 679, 679, nil, nil, nil, nil, 679, 679, nil, nil, + nil, 680, 680, 680, 679, 680, 679, 679, 679, 680, + 680, 679, 679, nil, 680, nil, 680, 680, 680, 680, + 680, 680, 680, nil, nil, nil, nil, nil, 680, 680, + 680, 680, 680, 680, 680, nil, nil, 680, nil, nil, + nil, nil, nil, nil, 680, nil, nil, 680, 680, 680, + 680, 680, 680, 680, 680, nil, 680, 680, 680, nil, + 680, 680, 680, 680, 680, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 680, nil, nil, 680, nil, nil, + 680, 680, nil, nil, 680, nil, nil, nil, nil, nil, + 680, nil, nil, nil, nil, nil, nil, nil, nil, 680, + nil, nil, nil, nil, 680, 680, 680, 680, nil, 680, + 680, 680, 680, nil, nil, nil, nil, 680, 680, nil, + nil, nil, 684, 684, 684, 680, 684, 680, 680, 680, + 684, 684, 680, 680, nil, 684, nil, 684, 684, 684, + 684, 684, 684, 684, nil, nil, nil, nil, nil, 684, + 684, 684, 684, 684, 684, 684, nil, nil, 684, nil, + nil, nil, nil, nil, nil, 684, nil, nil, 684, 684, + 684, 684, 684, 684, 684, 684, nil, 684, 684, 684, + nil, 684, 684, 684, 684, 684, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 684, nil, nil, 684, nil, + nil, 684, 684, nil, nil, 684, nil, nil, nil, nil, + nil, 684, nil, nil, nil, nil, nil, nil, nil, nil, + 684, nil, nil, nil, nil, 684, 684, 684, 684, nil, + 684, 684, 684, 684, nil, nil, nil, nil, 684, 684, + nil, nil, nil, 685, 685, 685, 684, 685, 684, 684, + 684, 685, 685, 684, 684, nil, 685, nil, 685, 685, + 685, 685, 685, 685, 685, nil, nil, nil, nil, nil, + 685, 685, 685, 685, 685, 685, 685, nil, nil, 685, + nil, nil, nil, nil, nil, nil, 685, nil, nil, 685, + 685, 685, 685, 685, 685, 685, 685, nil, 685, 685, + 685, nil, 685, 685, 685, 685, 685, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 685, nil, nil, 685, + nil, nil, 685, 685, nil, nil, 685, nil, nil, nil, + nil, nil, 685, nil, nil, nil, nil, nil, nil, nil, + nil, 685, nil, nil, nil, nil, 685, 685, 685, 685, + nil, 685, 685, 685, 685, nil, nil, nil, nil, 685, + 685, nil, nil, nil, 733, 733, 733, 685, 733, 685, + 685, 685, 733, 733, 685, 685, nil, 733, nil, 733, + 733, 733, 733, 733, 733, 733, nil, nil, nil, nil, + nil, 733, 733, 733, 733, 733, 733, 733, nil, nil, + 733, nil, nil, nil, nil, nil, nil, 733, nil, nil, + 733, 733, 733, 733, 733, 733, 733, 733, 733, 733, + 733, 733, nil, 733, 733, 733, 733, 733, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 733, nil, nil, + 733, nil, nil, 733, 733, nil, nil, 733, nil, 733, + nil, 733, nil, 733, nil, nil, 733, nil, nil, nil, + nil, nil, 733, nil, nil, nil, nil, 733, 733, 733, + 733, nil, 733, 733, 733, 733, nil, nil, nil, nil, + 733, 733, nil, nil, nil, 742, 742, 742, 733, 742, + 733, 733, 733, 742, 742, 733, 733, nil, 742, nil, + 742, 742, 742, 742, 742, 742, 742, nil, nil, nil, + nil, nil, 742, 742, 742, 742, 742, 742, 742, nil, + nil, 742, nil, nil, nil, nil, nil, nil, 742, nil, + nil, 742, 742, 742, 742, 742, 742, 742, 742, nil, + 742, 742, 742, nil, 742, 742, 742, 742, 742, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 742, nil, + nil, 742, nil, nil, 742, 742, nil, nil, 742, nil, + nil, nil, nil, nil, 742, nil, nil, nil, nil, nil, + nil, nil, nil, 742, nil, nil, nil, nil, 742, 742, + 742, 742, nil, 742, 742, 742, 742, nil, nil, nil, + nil, 742, 742, nil, nil, nil, 745, 745, 745, 742, + 745, 742, 742, 742, 745, 745, 742, 742, nil, 745, + nil, 745, 745, 745, 745, 745, 745, 745, nil, nil, + nil, nil, nil, 745, 745, 745, 745, 745, 745, 745, + nil, nil, 745, nil, nil, nil, nil, nil, nil, 745, + nil, nil, 745, 745, 745, 745, 745, 745, 745, 745, + nil, 745, 745, 745, nil, 745, 745, 745, 745, 745, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 745, + nil, nil, 745, nil, nil, 745, 745, nil, nil, 745, + nil, nil, nil, nil, nil, 745, nil, nil, nil, nil, + nil, nil, nil, nil, 745, nil, nil, nil, nil, 745, + 745, 745, 745, nil, 745, 745, 745, 745, nil, nil, + nil, nil, 745, 745, nil, nil, nil, 765, 765, 765, + 745, 765, 745, 745, 745, 765, 765, 745, 745, nil, + 765, nil, 765, 765, 765, 765, 765, 765, 765, nil, + nil, nil, nil, nil, 765, 765, 765, 765, 765, 765, + 765, nil, nil, 765, nil, nil, nil, nil, nil, nil, + 765, nil, nil, 765, 765, 765, 765, 765, 765, 765, + 765, nil, 765, 765, 765, nil, 765, 765, 765, 765, + 765, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 765, nil, nil, 765, nil, nil, 765, 765, nil, nil, + 765, nil, 765, nil, nil, nil, 765, nil, nil, nil, + nil, nil, nil, nil, nil, 765, nil, nil, nil, nil, + 765, 765, 765, 765, nil, 765, 765, 765, 765, nil, + nil, nil, nil, 765, 765, nil, nil, nil, 779, 779, + 779, 765, 779, 765, 765, 765, 779, 779, 765, 765, + nil, 779, nil, 779, 779, 779, 779, 779, 779, 779, + nil, nil, nil, nil, nil, 779, 779, 779, 779, 779, + 779, 779, nil, nil, 779, nil, nil, nil, nil, nil, + nil, 779, nil, nil, 779, 779, 779, 779, 779, 779, + 779, 779, nil, 779, 779, 779, nil, 779, 779, 779, + 779, 779, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 779, nil, nil, 779, nil, nil, 779, 779, nil, + nil, 779, nil, nil, nil, nil, nil, 779, nil, nil, + nil, nil, nil, nil, nil, nil, 779, nil, nil, nil, + nil, 779, 779, 779, 779, nil, 779, 779, 779, 779, + nil, nil, nil, nil, 779, 779, nil, nil, nil, 824, + 824, 824, 779, 824, 779, 779, 779, 824, 824, 779, + 779, nil, 824, nil, 824, 824, 824, 824, 824, 824, + 824, nil, nil, nil, nil, nil, 824, 824, 824, 824, + 824, 824, 824, nil, nil, 824, nil, nil, nil, nil, + nil, nil, 824, nil, nil, 824, 824, 824, 824, 824, + 824, 824, 824, nil, 824, 824, 824, nil, 824, 824, + 824, 824, 824, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 824, nil, nil, 824, nil, nil, 824, 824, + nil, nil, 824, nil, nil, nil, nil, nil, 824, nil, + nil, nil, nil, nil, nil, nil, nil, 824, nil, nil, + nil, nil, 824, 824, 824, 824, nil, 824, 824, 824, + 824, nil, nil, nil, nil, 824, 824, nil, nil, nil, + 844, 844, 844, 824, 844, 824, 824, 824, 844, 844, + 824, 824, nil, 844, nil, 844, 844, 844, 844, 844, + 844, 844, nil, nil, nil, nil, nil, 844, 844, 844, + 844, 844, 844, 844, nil, nil, 844, nil, nil, nil, + nil, nil, nil, 844, nil, nil, 844, 844, 844, 844, + 844, 844, 844, 844, nil, 844, 844, 844, nil, 844, + 844, 844, 844, 844, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 844, nil, nil, 844, nil, nil, 844, + 844, nil, nil, 844, nil, nil, nil, nil, nil, 844, + nil, nil, nil, nil, nil, nil, nil, nil, 844, nil, + nil, nil, nil, 844, 844, 844, 844, nil, 844, 844, + 844, 844, nil, nil, nil, nil, 844, 844, nil, nil, + nil, 852, 852, 852, 844, 852, 844, 844, 844, 852, + 852, 844, 844, nil, 852, nil, 852, 852, 852, 852, + 852, 852, 852, nil, nil, nil, nil, nil, 852, 852, + 852, 852, 852, 852, 852, nil, nil, 852, nil, nil, + nil, nil, nil, nil, 852, nil, nil, 852, 852, 852, + 852, 852, 852, 852, 852, nil, 852, 852, 852, nil, + 852, 852, 852, 852, 852, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 852, nil, nil, 852, nil, nil, + 852, 852, nil, nil, 852, nil, nil, nil, nil, nil, + 852, nil, nil, nil, nil, nil, nil, nil, nil, 852, + nil, nil, nil, nil, 852, 852, 852, 852, nil, 852, + 852, 852, 852, nil, nil, nil, nil, 852, 852, nil, + nil, nil, 865, 865, 865, 852, 865, 852, 852, 852, + 865, 865, 852, 852, nil, 865, nil, 865, 865, 865, + 865, 865, 865, 865, nil, nil, nil, nil, nil, 865, + 865, 865, 865, 865, 865, 865, nil, nil, 865, nil, + nil, nil, nil, nil, nil, 865, nil, nil, 865, 865, + 865, 865, 865, 865, 865, 865, nil, 865, 865, 865, + nil, 865, 865, 865, 865, 865, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 865, nil, nil, 865, nil, + nil, 865, 865, nil, nil, 865, nil, nil, nil, nil, + nil, 865, nil, nil, nil, nil, nil, nil, nil, nil, + 865, nil, nil, nil, nil, 865, 865, 865, 865, nil, + 865, 865, 865, 865, nil, nil, nil, nil, 865, 865, + nil, nil, nil, 866, 866, 866, 865, 866, 865, 865, + 865, 866, 866, 865, 865, nil, 866, nil, 866, 866, + 866, 866, 866, 866, 866, nil, nil, nil, nil, nil, + 866, 866, 866, 866, 866, 866, 866, nil, nil, 866, + nil, nil, nil, nil, nil, nil, 866, nil, nil, 866, + 866, 866, 866, 866, 866, 866, 866, nil, 866, 866, + 866, nil, 866, 866, 866, 866, 866, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 866, nil, nil, 866, + nil, nil, 866, 866, nil, nil, 866, nil, nil, nil, + nil, nil, 866, nil, nil, nil, nil, nil, nil, nil, + nil, 866, nil, nil, nil, nil, 866, 866, 866, 866, + nil, 866, 866, 866, 866, nil, nil, nil, nil, 866, + 866, nil, nil, nil, 867, 867, 867, 866, 867, 866, + 866, 866, 867, 867, 866, 866, nil, 867, nil, 867, + 867, 867, 867, 867, 867, 867, nil, nil, nil, nil, + nil, 867, 867, 867, 867, 867, 867, 867, nil, nil, + 867, nil, nil, nil, nil, nil, nil, 867, nil, nil, + 867, 867, 867, 867, 867, 867, 867, 867, nil, 867, + 867, 867, nil, 867, 867, 867, 867, 867, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 867, nil, nil, + 867, nil, nil, 867, 867, nil, nil, 867, nil, nil, + nil, nil, nil, 867, nil, nil, nil, nil, nil, nil, + nil, nil, 867, nil, nil, nil, nil, 867, 867, 867, + 867, nil, 867, 867, 867, 867, nil, nil, nil, nil, + 867, 867, nil, nil, nil, 868, 868, 868, 867, 868, + 867, 867, 867, 868, 868, 867, 867, nil, 868, nil, + 868, 868, 868, 868, 868, 868, 868, nil, nil, nil, + nil, nil, 868, 868, 868, 868, 868, 868, 868, nil, + nil, 868, nil, nil, nil, nil, nil, nil, 868, nil, + nil, 868, 868, 868, 868, 868, 868, 868, 868, nil, + 868, 868, 868, nil, 868, 868, 868, 868, 868, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 868, nil, + nil, 868, nil, nil, 868, 868, nil, nil, 868, nil, + nil, nil, nil, nil, 868, nil, nil, nil, nil, nil, + nil, nil, nil, 868, nil, nil, nil, nil, 868, 868, + 868, 868, nil, 868, 868, 868, 868, nil, nil, nil, + nil, 868, 868, nil, nil, nil, 897, 897, 897, 868, + 897, 868, 868, 868, 897, 897, 868, 868, nil, 897, + nil, 897, 897, 897, 897, 897, 897, 897, nil, nil, + nil, nil, nil, 897, 897, 897, 897, 897, 897, 897, + nil, nil, 897, nil, nil, nil, nil, nil, nil, 897, + nil, nil, 897, 897, 897, 897, 897, 897, 897, 897, + nil, 897, 897, 897, nil, 897, 897, 897, 897, 897, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 897, + nil, nil, 897, nil, nil, 897, 897, nil, nil, 897, + nil, nil, nil, nil, nil, 897, nil, nil, nil, nil, + nil, nil, nil, nil, 897, nil, nil, nil, nil, 897, + 897, 897, 897, nil, 897, 897, 897, 897, nil, nil, + nil, nil, 897, 897, nil, nil, nil, 917, 917, 917, + 897, 917, 897, 897, 897, 917, 917, 897, 897, nil, + 917, nil, 917, 917, 917, 917, 917, 917, 917, nil, + nil, nil, nil, nil, 917, 917, 917, 917, 917, 917, + 917, nil, nil, 917, nil, nil, nil, nil, nil, nil, + 917, nil, nil, 917, 917, 917, 917, 917, 917, 917, + 917, nil, 917, 917, 917, nil, 917, 917, 917, 917, + 917, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 917, nil, nil, 917, nil, nil, 917, 917, nil, nil, + 917, nil, nil, nil, nil, nil, 917, nil, nil, nil, + nil, nil, nil, nil, nil, 917, nil, nil, nil, nil, + 917, 917, 917, 917, nil, 917, 917, 917, 917, nil, + nil, nil, nil, 917, 917, nil, nil, nil, 945, 945, + 945, 917, 945, 917, 917, 917, 945, 945, 917, 917, + nil, 945, nil, 945, 945, 945, 945, 945, 945, 945, + nil, nil, nil, nil, nil, 945, 945, 945, 945, 945, + 945, 945, nil, nil, 945, nil, nil, nil, nil, nil, + nil, 945, nil, nil, 945, 945, 945, 945, 945, 945, + 945, 945, nil, 945, 945, 945, nil, 945, 945, 945, + 945, 945, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 945, nil, nil, 945, nil, nil, 945, 945, nil, + nil, 945, nil, nil, nil, nil, nil, 945, nil, nil, + nil, nil, nil, nil, nil, nil, 945, nil, nil, nil, + nil, 945, 945, 945, 945, nil, 945, 945, 945, 945, + nil, nil, nil, nil, 945, 945, nil, nil, nil, 949, + 949, 949, 945, 949, 945, 945, 945, 949, 949, 945, + 945, nil, 949, nil, 949, 949, 949, 949, 949, 949, + 949, nil, nil, nil, nil, nil, 949, 949, 949, 949, + 949, 949, 949, nil, nil, 949, nil, nil, nil, nil, + nil, nil, 949, nil, nil, 949, 949, 949, 949, 949, + 949, 949, 949, nil, 949, 949, 949, nil, 949, 949, + 949, 949, 949, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 949, nil, nil, 949, nil, nil, 949, 949, + nil, nil, 949, nil, nil, nil, nil, nil, 949, nil, + nil, nil, nil, nil, nil, nil, nil, 949, nil, nil, + nil, nil, 949, 949, 949, 949, nil, 949, 949, 949, + 949, nil, nil, nil, nil, 949, 949, nil, nil, nil, + 954, 954, 954, 949, 954, 949, 949, 949, 954, 954, + 949, 949, nil, 954, nil, 954, 954, 954, 954, 954, + 954, 954, nil, nil, nil, nil, nil, 954, 954, 954, + 954, 954, 954, 954, nil, nil, 954, nil, nil, nil, + nil, nil, nil, 954, nil, nil, 954, 954, 954, 954, + 954, 954, 954, 954, nil, 954, 954, 954, nil, 954, + 954, 954, 954, 954, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 954, nil, nil, 954, nil, nil, 954, + 954, nil, nil, 954, nil, 954, nil, nil, nil, 954, + nil, nil, nil, nil, nil, nil, nil, nil, 954, nil, + nil, nil, nil, 954, 954, 954, 954, nil, 954, 954, + 954, 954, nil, nil, nil, nil, 954, 954, nil, nil, + nil, 973, 973, 973, 954, 973, 954, 954, 954, 973, + 973, 954, 954, nil, 973, nil, 973, 973, 973, 973, + 973, 973, 973, nil, nil, nil, nil, nil, 973, 973, + 973, 973, 973, 973, 973, nil, nil, 973, nil, nil, + nil, nil, nil, nil, 973, nil, nil, 973, 973, 973, + 973, 973, 973, 973, 973, 973, 973, 973, 973, nil, + 973, 973, 973, 973, 973, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 973, nil, nil, 973, nil, nil, + 973, 973, nil, nil, 973, nil, nil, nil, 973, nil, + 973, nil, nil, 973, nil, nil, nil, nil, nil, 973, + nil, nil, nil, nil, 973, 973, 973, 973, nil, 973, + 973, 973, 973, nil, nil, nil, nil, 973, 973, nil, + nil, nil, 974, 974, 974, 973, 974, 973, 973, 973, + 974, 974, 973, 973, nil, 974, nil, 974, 974, 974, + 974, 974, 974, 974, nil, nil, nil, nil, nil, 974, + 974, 974, 974, 974, 974, 974, nil, nil, 974, nil, + nil, nil, nil, nil, nil, 974, nil, nil, 974, 974, + 974, 974, 974, 974, 974, 974, nil, 974, 974, 974, + nil, 974, 974, 974, 974, 974, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 974, nil, nil, 974, nil, + nil, 974, 974, nil, nil, 974, nil, nil, nil, nil, + nil, 974, nil, nil, nil, nil, nil, nil, nil, nil, + 974, nil, nil, nil, nil, 974, 974, 974, 974, nil, + 974, 974, 974, 974, nil, nil, nil, nil, 974, 974, + nil, nil, nil, 1122, 1122, 1122, 974, 1122, 974, 974, + 974, 1122, 1122, 974, 974, nil, 1122, nil, 1122, 1122, + 1122, 1122, 1122, 1122, 1122, nil, nil, nil, nil, nil, + 1122, 1122, 1122, 1122, 1122, 1122, 1122, nil, nil, 1122, + nil, nil, nil, nil, nil, nil, 1122, nil, nil, 1122, + 1122, 1122, 1122, 1122, 1122, 1122, 1122, nil, 1122, 1122, + 1122, nil, 1122, 1122, 1122, 1122, 1122, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1122, nil, nil, 1122, + nil, nil, 1122, 1122, nil, nil, 1122, nil, nil, nil, + nil, nil, 1122, nil, nil, nil, nil, nil, nil, nil, + nil, 1122, nil, nil, nil, nil, 1122, 1122, 1122, 1122, + nil, 1122, 1122, 1122, 1122, nil, nil, nil, nil, 1122, + 1122, nil, nil, nil, 1123, 1123, 1123, 1122, 1123, 1122, + 1122, 1122, 1123, 1123, 1122, 1122, nil, 1123, nil, 1123, + 1123, 1123, 1123, 1123, 1123, 1123, nil, nil, nil, nil, + nil, 1123, 1123, 1123, 1123, 1123, 1123, 1123, nil, nil, + 1123, nil, nil, nil, nil, nil, nil, 1123, nil, nil, + 1123, 1123, 1123, 1123, 1123, 1123, 1123, 1123, nil, 1123, + 1123, 1123, nil, 1123, 1123, 1123, 1123, 1123, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 1123, nil, nil, + 1123, nil, nil, 1123, 1123, nil, nil, 1123, nil, nil, + nil, nil, nil, 1123, nil, nil, nil, nil, nil, nil, + nil, nil, 1123, nil, nil, nil, nil, 1123, 1123, 1123, + 1123, nil, 1123, 1123, 1123, 1123, nil, nil, nil, nil, + 1123, 1123, nil, nil, nil, 1155, 1155, 1155, 1123, 1155, + 1123, 1123, 1123, 1155, 1155, 1123, 1123, nil, 1155, nil, + 1155, 1155, 1155, 1155, 1155, 1155, 1155, nil, nil, nil, + nil, nil, 1155, 1155, 1155, 1155, 1155, 1155, 1155, nil, + nil, 1155, nil, nil, nil, nil, nil, nil, 1155, nil, + nil, 1155, 1155, 1155, 1155, 1155, 1155, 1155, 1155, 1155, + 1155, 1155, 1155, nil, 1155, 1155, 1155, 1155, 1155, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 1155, nil, + nil, 1155, nil, nil, 1155, 1155, nil, nil, 1155, nil, + 1155, nil, 1155, nil, 1155, nil, nil, 1155, nil, nil, + nil, nil, nil, 1155, nil, nil, nil, nil, 1155, 1155, + 1155, 1155, nil, 1155, 1155, 1155, 1155, nil, nil, nil, + nil, 1155, 1155, nil, nil, nil, 37, 37, 37, 1155, + 37, 1155, 1155, 1155, 37, 37, 1155, 1155, nil, 37, + nil, 37, 37, 37, 37, 37, 37, 37, nil, nil, + nil, nil, nil, 37, 37, 37, 37, 37, 37, 37, + nil, nil, 37, nil, nil, nil, nil, nil, nil, 37, + nil, nil, 37, 37, 37, 37, 37, 37, 37, 37, + nil, 37, 37, 37, nil, 37, 37, nil, nil, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 37, + nil, nil, 37, nil, nil, 37, 37, nil, nil, 37, + nil, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 37, + 37, 37, 37, nil, 37, 37, 37, 37, nil, nil, + nil, nil, 37, 37, nil, nil, nil, 38, 38, 38, + 37, 38, 37, 37, 37, 38, 38, nil, nil, nil, + 38, nil, 38, 38, 38, 38, 38, 38, 38, nil, + nil, nil, nil, nil, 38, 38, 38, 38, 38, 38, + 38, nil, nil, 38, nil, nil, nil, nil, nil, nil, + 38, nil, nil, 38, 38, 38, 38, 38, 38, 38, + 38, nil, 38, 38, 38, nil, 38, 38, nil, nil, + 38, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 38, nil, nil, 38, nil, nil, 38, 38, nil, nil, + 38, nil, nil, 1038, nil, 1038, 1038, 1038, 1038, 1038, + nil, nil, nil, nil, nil, nil, nil, nil, 1038, nil, + 38, 38, 38, 38, nil, 38, 38, 38, 38, nil, + nil, nil, nil, 38, 38, nil, nil, nil, 38, nil, + 1038, 38, nil, 38, 38, 38, 76, 76, 76, nil, + 76, 1038, 1038, nil, 76, 76, 1038, nil, nil, 76, + nil, 76, 76, 76, 76, 76, 76, 76, nil, nil, + nil, nil, nil, 76, 76, 76, 76, 76, 76, 76, + nil, nil, 76, nil, nil, nil, nil, nil, nil, 76, + nil, nil, 76, 76, 76, 76, 76, 76, 76, 76, + nil, 76, 76, 76, nil, 76, 76, nil, nil, 76, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 76, + nil, nil, 76, nil, nil, 76, 76, nil, nil, 76, + nil, 76, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 76, + 76, 76, 76, nil, 76, 76, 76, 76, nil, nil, + nil, nil, 76, 76, nil, nil, nil, 77, 77, 77, + 76, 77, 76, 76, 76, 77, 77, nil, nil, nil, + 77, nil, 77, 77, 77, 77, 77, 77, 77, nil, + nil, nil, nil, nil, 77, 77, 77, 77, 77, 77, + 77, nil, nil, 77, nil, nil, nil, nil, nil, nil, + 77, nil, nil, 77, 77, 77, 77, 77, 77, 77, + 77, nil, 77, 77, 77, nil, 77, 77, nil, nil, + 77, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 77, nil, nil, + 77, nil, nil, 77, nil, nil, 77, 77, nil, nil, + 77, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 77, 77, 77, 77, nil, 77, 77, 77, 77, nil, + nil, nil, nil, 77, 77, nil, nil, nil, 78, 78, + 78, 77, 78, 77, 77, 77, 78, 78, nil, nil, + nil, 78, nil, 78, 78, 78, 78, 78, 78, 78, + nil, nil, nil, nil, nil, 78, 78, 78, 78, 78, + 78, 78, nil, nil, 78, nil, nil, nil, nil, nil, + nil, 78, nil, nil, 78, 78, 78, 78, 78, 78, + 78, 78, nil, 78, 78, 78, nil, 78, 78, nil, + nil, 78, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 78, nil, nil, 78, nil, nil, 78, 78, nil, + nil, 78, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 78, 78, 78, 78, nil, 78, 78, 78, 78, + nil, nil, nil, nil, 78, 78, nil, nil, nil, 331, + 331, 331, 78, 331, 78, 78, 78, 331, 331, nil, + nil, nil, 331, nil, 331, 331, 331, 331, 331, 331, + 331, nil, nil, nil, nil, nil, 331, 331, 331, 331, + 331, 331, 331, nil, nil, 331, nil, nil, nil, nil, + nil, nil, 331, nil, nil, 331, 331, 331, 331, 331, + 331, 331, 331, nil, 331, 331, 331, nil, 331, 331, + nil, nil, 331, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 331, nil, nil, 331, nil, nil, 331, 331, + nil, nil, 331, nil, nil, 1041, nil, 1041, 1041, 1041, + 1041, 1041, nil, nil, nil, nil, nil, nil, nil, nil, + 1041, nil, 331, 331, 331, 331, nil, 331, 331, 331, + 331, nil, nil, nil, nil, 331, 331, nil, nil, nil, + 331, nil, 1041, 331, nil, 331, 331, 331, 350, 350, + 350, nil, 350, 1041, 1041, nil, 350, 350, 1041, nil, + nil, 350, nil, 350, 350, 350, 350, 350, 350, 350, + nil, nil, nil, nil, nil, 350, 350, 350, 350, 350, + 350, 350, nil, nil, 350, nil, nil, nil, nil, nil, + nil, 350, nil, nil, 350, 350, 350, 350, 350, 350, + 350, 350, nil, 350, 350, 350, nil, 350, 350, nil, + nil, 350, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 350, nil, nil, 350, nil, nil, 350, 350, nil, + nil, 350, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 350, 350, 350, 350, nil, 350, 350, 350, 350, + nil, nil, nil, nil, 350, 350, nil, nil, nil, 543, + 543, 543, 350, 543, 350, 350, 350, 543, 543, nil, + nil, nil, 543, nil, 543, 543, 543, 543, 543, 543, + 543, nil, nil, nil, nil, nil, 543, 543, 543, 543, + 543, 543, 543, nil, nil, 543, nil, nil, nil, nil, + nil, nil, 543, nil, nil, 543, 543, 543, 543, 543, + 543, 543, 543, nil, 543, 543, 543, nil, 543, 543, + nil, nil, 543, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 543, nil, nil, 543, nil, nil, 543, 543, + nil, nil, 543, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 543, 543, 543, 543, nil, 543, 543, 543, + 543, nil, nil, nil, nil, 543, 543, nil, nil, nil, + 552, 552, 552, 543, 552, 543, 543, 543, 552, 552, + nil, nil, nil, 552, nil, 552, 552, 552, 552, 552, + 552, 552, nil, nil, nil, nil, nil, 552, 552, 552, + 552, 552, 552, 552, nil, nil, 552, nil, nil, nil, + nil, nil, nil, 552, nil, nil, 552, 552, 552, 552, + 552, 552, 552, 552, nil, 552, 552, 552, nil, 552, + 552, nil, nil, 552, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 552, nil, nil, 552, nil, nil, 552, + 552, nil, nil, 552, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 552, 552, 552, 552, nil, 552, 552, + 552, 552, nil, nil, nil, nil, 552, 552, nil, nil, + nil, 748, 748, 748, 552, 748, 552, 552, 552, 748, + 748, nil, nil, nil, 748, nil, 748, 748, 748, 748, + 748, 748, 748, nil, nil, nil, nil, nil, 748, 748, + 748, 748, 748, 748, 748, nil, nil, 748, nil, nil, + nil, nil, nil, nil, 748, nil, nil, 748, 748, 748, + 748, 748, 748, 748, 748, nil, 748, 748, 748, nil, + 748, 748, nil, nil, 748, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 748, nil, nil, 748, nil, nil, + 748, 748, nil, nil, 748, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 748, 748, 748, 748, nil, 748, + 748, 748, 748, nil, nil, nil, nil, 748, 748, nil, + nil, nil, 759, 759, 759, 748, 759, 748, 748, 748, + 759, 759, nil, nil, nil, 759, nil, 759, 759, 759, + 759, 759, 759, 759, nil, nil, nil, nil, nil, 759, + 759, 759, 759, 759, 759, 759, nil, nil, 759, nil, + nil, nil, nil, nil, nil, 759, nil, nil, 759, 759, + 759, 759, 759, 759, 759, 759, nil, 759, 759, 759, + nil, 759, 759, nil, nil, 759, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 759, nil, nil, 759, nil, + nil, 759, 759, nil, nil, 759, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 759, 759, 759, 759, nil, + 759, 759, 759, 759, nil, nil, nil, nil, 759, 759, + nil, nil, nil, 1023, 1023, 1023, 759, 1023, 759, 759, + 759, 1023, 1023, nil, nil, nil, 1023, nil, 1023, 1023, + 1023, 1023, 1023, 1023, 1023, nil, nil, nil, nil, nil, + 1023, 1023, 1023, 1023, 1023, 1023, 1023, nil, nil, 1023, + nil, nil, nil, nil, nil, nil, 1023, nil, nil, 1023, + 1023, 1023, 1023, 1023, 1023, 1023, 1023, nil, 1023, 1023, + 1023, nil, 1023, 1023, nil, nil, 1023, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1023, nil, nil, 1023, + nil, nil, 1023, 1023, nil, nil, 1023, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1023, 1023, 1023, 1023, + nil, 1023, 1023, 1023, 1023, nil, nil, nil, nil, 1023, + 1023, nil, nil, nil, 1033, 1033, 1033, 1023, 1033, 1023, + 1023, 1023, 1033, 1033, nil, nil, nil, 1033, nil, 1033, + 1033, 1033, 1033, 1033, 1033, 1033, nil, nil, nil, nil, + nil, 1033, 1033, 1033, 1033, 1033, 1033, 1033, nil, nil, + 1033, nil, nil, nil, nil, nil, nil, 1033, nil, nil, + 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1033, nil, 1033, + 1033, 1033, nil, 1033, 1033, nil, nil, 1033, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 1033, nil, nil, + 1033, nil, nil, 1033, 1033, nil, nil, 1033, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 1033, 1033, 1033, + 1033, nil, 1033, 1033, 1033, 1033, nil, nil, nil, nil, + 1033, 1033, nil, nil, nil, 1103, 1103, 1103, 1033, 1103, + 1033, 1033, 1033, 1103, 1103, nil, nil, nil, 1103, nil, + 1103, 1103, 1103, 1103, 1103, 1103, 1103, nil, nil, nil, + nil, nil, 1103, 1103, 1103, 1103, 1103, 1103, 1103, nil, + nil, 1103, nil, nil, nil, nil, nil, nil, 1103, nil, + nil, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, nil, + 1103, 1103, 1103, nil, 1103, 1103, nil, nil, 1103, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 1103, nil, + nil, 1103, nil, nil, 1103, 1103, nil, nil, 1103, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 1103, 1103, + 1103, 1103, nil, 1103, 1103, 1103, 1103, nil, nil, nil, + nil, 1103, 1103, nil, nil, nil, nil, nil, nil, 1103, + nil, 1103, 1103, 1103, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, nil, nil, + nil, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, nil, nil, nil, nil, nil, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, nil, 10, nil, nil, + nil, nil, nil, nil, nil, 10, 10, nil, 10, 10, + 10, 10, 10, 10, 10, nil, nil, 10, 10, nil, + nil, nil, 10, 10, 10, 10, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 10, + 10, nil, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, nil, nil, 10, 10, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 10, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, nil, nil, nil, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, nil, + nil, nil, nil, nil, 11, 11, 11, 11, 11, 11, + 11, 11, 11, nil, nil, 11, nil, nil, nil, nil, + nil, nil, nil, 11, 11, nil, 11, 11, 11, 11, + 11, 11, 11, nil, nil, 11, 11, nil, nil, nil, + 11, 11, 11, 11, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 11, 11, nil, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, nil, nil, 11, 11, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 11, + 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, + 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, + 425, 425, 425, 425, nil, nil, nil, 425, 425, 425, + 425, 425, 425, 425, 425, 425, 425, nil, nil, nil, + nil, nil, 425, 425, 425, 425, 425, 425, 425, 425, + 425, nil, nil, 425, nil, nil, nil, nil, nil, nil, + nil, 425, 425, nil, 425, 425, 425, 425, 425, 425, + 425, nil, nil, 425, 425, nil, nil, nil, 425, 425, + 425, 425, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 425, 425, nil, 425, 425, + 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, + nil, nil, 425, 425, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 425, 664, 664, + 664, 664, 664, 664, 664, 664, 664, 664, 664, 664, + 664, 664, 664, 664, 664, 664, 664, 664, 664, 664, + 664, 664, nil, nil, nil, 664, 664, 664, 664, 664, + 664, 664, 664, 664, 664, nil, nil, nil, nil, nil, + 664, 664, 664, 664, 664, 664, 664, 664, 664, nil, + nil, 664, nil, nil, nil, nil, nil, nil, nil, 664, + 664, nil, 664, 664, 664, 664, 664, 664, 664, nil, + nil, 664, 664, nil, nil, nil, 664, 664, 664, 664, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 664, 664, nil, 664, 664, 664, 664, + 664, 664, 664, 664, 664, 664, 664, 664, nil, nil, + 664, 664, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 664, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + nil, nil, nil, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, nil, nil, nil, nil, nil, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + nil, 24, nil, nil, nil, nil, nil, 24, 24, nil, + 24, 24, 24, 24, 24, 24, 24, nil, nil, 24, + 24, nil, nil, nil, 24, 24, 24, 24, nil, nil, + nil, nil, nil, 24, nil, nil, nil, nil, nil, nil, + nil, 24, 24, nil, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, nil, nil, 24, 482, + 482, 482, 482, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 482, 482, 482, 482, nil, + nil, 641, 482, 641, 641, 641, 641, 641, 482, 482, + nil, nil, 482, nil, nil, nil, 641, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 482, nil, nil, 482, nil, nil, 641, 482, + nil, nil, 482, nil, nil, nil, nil, 641, 641, 641, + 641, nil, nil, nil, 641, nil, nil, nil, 482, nil, + nil, nil, 482, 482, 482, 482, nil, 482, 482, 482, + 482, nil, nil, nil, nil, 482, 482, 483, 483, 483, + 483, nil, nil, 482, nil, 482, 482, 482, nil, nil, + 482, 482, nil, 483, 483, 483, 483, nil, nil, 775, + 483, 775, 775, 775, 775, 775, 483, 483, nil, nil, + 483, nil, nil, nil, 775, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 483, nil, nil, 483, nil, nil, 775, 483, nil, nil, + 483, nil, nil, nil, nil, 775, 775, 775, 775, nil, + nil, nil, 775, nil, nil, nil, 483, nil, nil, nil, + 483, 483, 483, 483, nil, 483, 483, 483, 483, nil, + nil, nil, nil, 483, 483, 701, 701, 701, 701, nil, + nil, 483, nil, 483, 483, 483, nil, nil, 483, 483, + nil, 701, 701, 701, 701, nil, nil, 793, 701, 793, + 793, 793, 793, 793, 701, 701, nil, nil, 701, nil, + nil, nil, 793, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 701, nil, + nil, 701, nil, nil, 793, 701, nil, nil, 701, nil, + 701, nil, nil, 793, 793, 793, 793, nil, nil, nil, + 793, nil, nil, nil, 701, nil, nil, nil, 701, 701, + 701, 701, nil, 701, 701, 701, 701, nil, nil, nil, + nil, 701, 701, 701, nil, nil, nil, nil, nil, 701, + nil, 701, 701, 701, nil, nil, 701, 701, 725, 725, + 725, 725, 725, 725, 725, 725, 725, 725, 725, 725, + 725, 725, 725, 725, 725, 725, 725, 725, 725, 725, + 725, 725, nil, nil, nil, 725, 725, 725, 725, 725, + 725, 725, 725, 725, 725, nil, nil, nil, nil, nil, + 725, 725, 725, 725, 725, 725, 725, 725, 725, nil, + nil, 725, nil, nil, nil, nil, nil, nil, nil, 725, + 725, nil, 725, 725, 725, 725, 725, 725, 725, nil, + nil, 725, 725, nil, nil, nil, 725, 725, 725, 725, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 725, 725, nil, 725, 725, 725, 725, + 725, 725, 725, 725, 725, 725, 725, 725, nil, nil, + 725, 871, 871, 871, 871, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 871, 871, 871, + 871, nil, nil, 1036, 871, 1036, 1036, 1036, 1036, 1036, + 871, 871, nil, nil, 871, nil, nil, nil, 1036, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 871, nil, nil, 871, nil, nil, + 1036, 871, nil, nil, 871, nil, nil, nil, nil, 1036, + 1036, 1036, 1036, nil, nil, nil, 1036, nil, nil, nil, + 871, nil, nil, nil, 871, 871, 871, 871, nil, 871, + 871, 871, 871, nil, nil, nil, nil, 871, 871, 874, + 874, 874, 874, nil, nil, 871, nil, 871, 871, 871, + nil, nil, 871, 871, nil, 874, 874, 874, 874, nil, + nil, nil, 874, 874, nil, nil, nil, nil, 874, 874, + nil, nil, 874, 874, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 874, nil, nil, 874, nil, nil, nil, 874, + nil, nil, 874, nil, 874, nil, nil, nil, nil, nil, + nil, 874, nil, nil, nil, nil, nil, nil, 874, nil, + nil, nil, 874, 874, 874, 874, nil, 874, 874, 874, + 874, nil, nil, nil, nil, 874, 874, 875, 875, 875, + 875, nil, nil, 874, nil, 874, 874, 874, nil, nil, + 874, 874, nil, 875, 875, 875, 875, nil, nil, nil, + 875, 875, nil, nil, nil, nil, 875, 875, nil, nil, + 875, 875, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 875, nil, nil, 875, nil, nil, nil, 875, nil, nil, + 875, nil, 875, nil, nil, nil, nil, nil, nil, 875, + nil, nil, nil, nil, nil, nil, 875, nil, nil, nil, + 875, 875, 875, 875, nil, 875, 875, 875, 875, nil, + nil, nil, nil, 875, 875, 881, 881, 881, 881, nil, + nil, 875, nil, 875, 875, 875, nil, nil, 875, 875, + nil, 881, 881, 881, 881, nil, nil, 1043, 881, 1043, + 1043, 1043, 1043, 1043, 881, 881, nil, nil, 881, nil, + nil, nil, 1043, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 881, nil, + nil, 881, nil, nil, 1043, 881, nil, nil, 881, nil, + 881, nil, nil, nil, nil, 1043, 1043, nil, nil, nil, + 1043, nil, nil, nil, 881, nil, nil, nil, 881, 881, + 881, 881, nil, 881, 881, 881, 881, nil, nil, nil, + nil, 881, 881, 889, 889, 889, 889, nil, nil, 881, + nil, 881, 881, 881, nil, nil, 881, 881, nil, 889, + 889, 889, 889, nil, nil, 1094, 889, 1094, 1094, 1094, + 1094, 1094, 889, 889, nil, nil, 889, nil, nil, nil, + 1094, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 889, nil, nil, 889, + nil, nil, 1094, 889, nil, nil, 889, nil, nil, nil, + nil, 1094, 1094, 1094, 1094, nil, nil, nil, 1094, nil, + nil, nil, 889, nil, nil, nil, 889, 889, 889, 889, + nil, 889, 889, 889, 889, nil, nil, nil, nil, 889, + 889, 953, 953, 953, 953, nil, nil, 889, nil, 889, + 889, 889, nil, nil, 889, 889, nil, 953, 953, 953, + 953, nil, nil, nil, 953, 953, nil, nil, nil, nil, + 953, 953, nil, nil, 953, 953, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 953, nil, nil, 953, nil, nil, + nil, 953, nil, nil, 953, nil, 953, nil, nil, nil, + nil, nil, nil, 953, nil, nil, nil, nil, nil, nil, + 953, nil, nil, nil, 953, 953, 953, 953, nil, 953, + 953, 953, 953, nil, nil, nil, nil, 953, 953, 985, + 985, 985, 985, nil, nil, 953, nil, 953, 953, 953, + nil, nil, 953, 953, nil, 985, 985, 985, 985, nil, + nil, 1097, 985, 1097, 1097, 1097, 1097, 1097, 985, 985, + nil, nil, 985, nil, nil, nil, 1097, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 985, nil, nil, 985, nil, nil, 1097, 985, + nil, nil, 985, nil, nil, nil, nil, 1097, 1097, 1097, + 1097, nil, nil, nil, 1097, nil, nil, nil, 985, nil, + nil, nil, 985, 985, 985, 985, nil, 985, 985, 985, + 985, nil, nil, nil, nil, 985, 985, 1001, 1001, 1001, + 1001, nil, nil, 985, nil, 985, 985, 985, nil, nil, + 985, 985, nil, 1001, 1001, 1001, 1001, nil, nil, 1099, + 1001, 1099, 1099, 1099, 1099, 1099, 1001, 1001, nil, nil, + 1001, nil, nil, nil, 1099, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1001, nil, nil, 1001, nil, nil, 1099, 1001, nil, nil, + 1001, nil, nil, nil, nil, nil, nil, 1099, 1099, nil, + nil, nil, 1099, nil, nil, nil, 1001, nil, nil, nil, + 1001, 1001, 1001, 1001, nil, 1001, 1001, 1001, 1001, nil, + nil, nil, nil, 1001, 1001, 1084, 1084, 1084, 1084, nil, + nil, 1001, nil, 1001, 1001, 1001, nil, nil, 1001, 1001, + nil, 1084, 1084, 1084, 1084, nil, nil, 1159, 1084, 1159, + 1159, 1159, 1159, 1159, 1084, 1084, nil, nil, 1084, nil, + nil, nil, 1159, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 1084, nil, + nil, 1084, nil, nil, 1159, 1084, nil, nil, 1084, nil, + nil, nil, nil, nil, nil, 1159, 1159, nil, nil, nil, + 1159, nil, nil, nil, 1084, nil, nil, nil, 1084, 1084, + 1084, 1084, nil, 1084, 1084, 1084, 1084, nil, nil, nil, + nil, 1084, 1084, 1124, 1124, 1124, 1124, nil, nil, 1084, + nil, 1084, 1084, 1084, nil, nil, 1084, 1084, nil, 1124, + 1124, 1124, 1124, nil, nil, 1180, 1124, 1180, 1180, 1180, + 1180, 1180, 1124, 1124, nil, nil, 1124, nil, nil, nil, + 1180, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1124, nil, nil, 1124, + nil, nil, 1180, 1124, nil, nil, 1124, nil, 1124, nil, + nil, 1180, 1180, 1180, 1180, nil, nil, nil, 1180, nil, + nil, nil, 1124, nil, nil, nil, 1124, 1124, 1124, 1124, + nil, 1124, 1124, 1124, 1124, nil, nil, nil, nil, 1124, + 1124, 1138, 1138, 1138, 1138, nil, nil, 1124, nil, 1124, + 1124, 1124, nil, nil, 1124, 1124, nil, 1138, 1138, 1138, + 1138, nil, nil, 1182, 1138, 1182, 1182, 1182, 1182, 1182, + 1138, 1138, nil, nil, 1138, nil, nil, nil, 1182, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1138, nil, nil, 1138, nil, nil, + 1182, 1138, nil, nil, 1138, nil, nil, nil, nil, nil, + nil, 1182, 1182, nil, nil, nil, 1182, nil, nil, nil, + 1138, nil, nil, nil, 1138, 1138, 1138, 1138, nil, 1138, + 1138, 1138, 1138, nil, nil, nil, nil, 1138, 1138, 1140, + 1140, 1140, 1140, nil, nil, 1138, nil, 1138, 1138, 1138, + nil, nil, 1138, 1138, nil, 1140, 1140, 1140, 1140, nil, + nil, 1184, 1140, 1184, 1184, 1184, 1184, 1184, 1140, 1140, + nil, nil, 1140, nil, nil, nil, 1184, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1140, nil, nil, 1140, nil, nil, 1184, 1140, + nil, nil, 1140, nil, 1140, nil, nil, nil, nil, 1184, + 1184, nil, nil, nil, 1184, nil, nil, nil, 1140, nil, + nil, nil, 1140, 1140, 1140, 1140, nil, 1140, 1140, 1140, + 1140, nil, nil, nil, nil, 1140, 1140, 1176, 1176, 1176, + 1176, nil, nil, 1140, nil, 1140, 1140, 1140, nil, nil, + 1140, 1140, nil, 1176, 1176, 1176, 1176, nil, nil, 1186, + 1176, 1186, 1186, 1186, 1186, 1186, 1176, 1176, nil, nil, + 1176, nil, nil, nil, 1186, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1176, nil, nil, 1176, nil, nil, 1186, 1176, nil, nil, + 1176, nil, nil, nil, nil, nil, nil, 1186, 1186, nil, + nil, nil, 1186, nil, nil, nil, 1176, nil, nil, nil, + 1176, 1176, 1176, 1176, nil, 1176, 1176, 1176, 1176, nil, + nil, nil, nil, 1176, 1176, 1200, 1200, 1200, 1200, nil, + nil, 1176, nil, 1176, 1176, 1176, nil, nil, 1176, 1176, + nil, 1200, 1200, 1200, 1200, nil, nil, nil, 1200, nil, + nil, nil, nil, nil, 1200, 1200, nil, nil, 1200, nil, + nil, nil, nil, nil, nil, nil, 708, 708, 708, 708, + nil, nil, nil, nil, nil, nil, nil, nil, 1200, nil, + nil, 1200, 708, 708, 708, 1200, nil, nil, 1200, nil, + nil, nil, nil, nil, nil, 708, 708, nil, nil, 708, + nil, nil, nil, nil, 1200, nil, nil, nil, 1200, 1200, + 1200, 1200, nil, 1200, 1200, 1200, 1200, nil, nil, nil, + nil, 1200, 1200, nil, nil, nil, nil, nil, nil, 1200, + nil, 1200, 1200, 1200, nil, nil, 1200, 1200, 1212, nil, + 1212, 1212, 1212, 1212, 1212, nil, nil, nil, nil, 708, + 708, 708, 708, 1212, 708, 708, 708, 708, nil, nil, + nil, nil, 708, 708, 890, 890, 890, 890, nil, nil, + 708, nil, 708, 708, 708, 1212, nil, nil, nil, nil, + 890, 890, 890, nil, nil, nil, 1212, 1212, nil, nil, + nil, 1212, nil, 890, 890, nil, nil, 890, 891, 891, + 891, 891, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 891, 891, 891, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 891, 891, nil, + nil, 891, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 890, 890, 890, + 890, nil, 890, 890, 890, 890, nil, nil, nil, nil, + 890, 890, nil, nil, nil, nil, nil, nil, 890, nil, + 890, 890, 890, nil, nil, nil, nil, nil, nil, nil, + nil, 891, 891, 891, 891, nil, 891, 891, 891, 891, + nil, nil, nil, nil, 891, 891, 225, 225, nil, nil, + 225, nil, 891, nil, 891, 891, 891, nil, 225, 225, + nil, 225, 225, 225, 225, 225, 225, 225, nil, nil, + 225, 225, nil, nil, nil, 225, 225, 225, 225, nil, + nil, nil, nil, nil, 225, nil, nil, nil, nil, nil, + nil, nil, 225, 225, nil, 225, 225, 225, 225, 225, + 225, 225, 225, 225, 225, 225, 225, 226, 226, 225, + nil, 226, nil, nil, nil, nil, nil, nil, nil, 226, + 226, nil, 226, 226, 226, 226, 226, 226, 226, nil, + nil, 226, 226, nil, nil, nil, 226, 226, 226, 226, + nil, nil, nil, nil, nil, 226, nil, nil, nil, nil, + nil, nil, nil, 226, 226, nil, 226, 226, 226, 226, + 226, 226, 226, 226, 226, 226, 226, 226, 292, 292, + 226, nil, 292, nil, nil, nil, nil, nil, nil, nil, + 292, 292, nil, 292, 292, 292, 292, 292, 292, 292, + nil, nil, 292, 292, nil, nil, nil, 292, 292, 292, + 292, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 292, 292, nil, 292, 292, 292, + 292, 292, 292, 292, 292, 292, 292, 292, 292, 475, + 475, 292, nil, 475, nil, nil, nil, nil, nil, nil, + nil, 475, 475, nil, 475, 475, 475, 475, 475, 475, + 475, nil, nil, 475, 475, nil, nil, nil, 475, 475, + 475, 475, nil, nil, nil, nil, nil, 475, nil, nil, + nil, nil, nil, nil, nil, 475, 475, nil, 475, 475, + 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, + 476, 476, 475, nil, 476, nil, nil, nil, nil, nil, + nil, nil, 476, 476, nil, 476, 476, 476, 476, 476, + 476, 476, nil, nil, 476, 476, nil, nil, nil, 476, + 476, 476, 476, nil, nil, nil, nil, nil, 476, nil, + nil, nil, nil, nil, nil, nil, 476, 476, nil, 476, + 476, 476, 476, 476, 476, 476, 476, 476, 476, 476, + 476, 546, 546, 476, nil, 546, nil, nil, nil, nil, + nil, nil, nil, 546, 546, nil, 546, 546, 546, 546, + 546, 546, 546, nil, nil, 546, 546, nil, nil, nil, + 546, 546, 546, 546, nil, nil, nil, nil, nil, 546, + nil, nil, nil, nil, nil, nil, nil, 546, 546, nil, + 546, 546, 546, 546, 546, 546, 546, 546, 546, 546, + 546, 546, 547, 547, 546, nil, 547, nil, nil, nil, + nil, nil, nil, nil, 547, 547, nil, 547, 547, 547, + 547, 547, 547, 547, nil, nil, 547, 547, nil, nil, + nil, 547, 547, 547, 547, nil, nil, nil, nil, nil, + 547, nil, nil, nil, nil, nil, nil, nil, 547, 547, + nil, 547, 547, 547, 547, 547, 547, 547, 547, 547, + 547, 547, 547, 556, 556, 547, nil, 556, nil, nil, + nil, nil, nil, nil, nil, 556, 556, nil, 556, 556, + 556, 556, 556, 556, 556, nil, nil, 556, 556, nil, + nil, nil, 556, 556, 556, 556, nil, nil, nil, nil, + nil, 556, nil, nil, nil, nil, nil, nil, nil, 556, + 556, nil, 556, 556, 556, 556, 556, 556, 556, 556, + 556, 556, 556, 556, 557, 557, 556, nil, 557, nil, + nil, nil, nil, nil, nil, nil, 557, 557, nil, 557, + 557, 557, 557, 557, 557, 557, nil, nil, 557, 557, + nil, nil, nil, 557, 557, 557, 557, nil, nil, nil, + nil, nil, 557, nil, nil, nil, nil, nil, nil, nil, + 557, 557, nil, 557, 557, 557, 557, 557, 557, 557, + 557, 557, 557, 557, 557, 626, 626, 557, nil, 626, + nil, nil, nil, nil, nil, nil, nil, 626, 626, nil, + 626, 626, 626, 626, 626, 626, 626, nil, nil, 626, + 626, nil, nil, nil, 626, 626, 626, 626, nil, nil, + nil, nil, nil, 626, nil, nil, nil, nil, nil, nil, + nil, 626, 626, nil, 626, 626, 626, 626, 626, 626, + 626, 626, 626, 626, 626, 626, 627, 627, 626, nil, + 627, nil, nil, nil, nil, nil, nil, nil, 627, 627, + nil, 627, 627, 627, 627, 627, 627, 627, nil, nil, + 627, 627, nil, nil, nil, 627, 627, 627, 627, nil, + nil, nil, nil, nil, 627, nil, nil, nil, nil, nil, + nil, nil, 627, 627, nil, 627, 627, 627, 627, 627, + 627, 627, 627, 627, 627, 627, 627, 633, 633, 627, + nil, 633, nil, nil, nil, nil, nil, nil, nil, 633, + 633, nil, 633, 633, 633, 633, 633, 633, 633, nil, + nil, 633, 633, nil, nil, nil, 633, 633, 633, 633, + nil, nil, nil, nil, nil, 633, nil, nil, nil, nil, + nil, nil, nil, 633, 633, nil, 633, 633, 633, 633, + 633, 633, 633, 633, 633, 633, 633, 633, 634, 634, + 633, nil, 634, nil, nil, nil, nil, nil, nil, nil, + 634, 634, nil, 634, 634, 634, 634, 634, 634, 634, + nil, nil, 634, 634, nil, nil, nil, 634, 634, 634, + 634, nil, nil, nil, nil, nil, 634, nil, nil, nil, + nil, nil, nil, nil, 634, 634, nil, 634, 634, 634, + 634, 634, 634, 634, 634, 634, 634, 634, 634, 671, + 671, 634, nil, 671, nil, nil, nil, nil, nil, nil, + nil, 671, 671, nil, 671, 671, 671, 671, 671, 671, + 671, nil, nil, 671, 671, nil, nil, nil, 671, 671, + 671, 671, nil, nil, nil, nil, nil, 671, nil, nil, + nil, nil, nil, nil, nil, 671, 671, nil, 671, 671, + 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, + 672, 672, 671, nil, 672, nil, nil, nil, nil, nil, + nil, nil, 672, 672, nil, 672, 672, 672, 672, 672, + 672, 672, nil, nil, 672, 672, nil, nil, nil, 672, + 672, 672, 672, nil, nil, nil, nil, nil, 672, nil, + nil, nil, nil, nil, nil, nil, 672, 672, nil, 672, + 672, 672, 672, 672, 672, 672, 672, 672, 672, 672, + 672, 1152, 1152, 672, nil, 1152, nil, nil, nil, nil, + nil, nil, nil, 1152, 1152, nil, 1152, 1152, 1152, 1152, + 1152, 1152, 1152, nil, nil, 1152, 1152, nil, nil, nil, + 1152, 1152, 1152, 1152, nil, nil, nil, nil, nil, 1152, + nil, nil, nil, nil, nil, nil, nil, 1152, 1152, nil, + 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, 1152, + 1152, 1152, 1156, 1156, 1152, nil, 1156, nil, nil, nil, + nil, nil, nil, nil, 1156, 1156, nil, 1156, 1156, 1156, + 1156, 1156, 1156, 1156, nil, nil, 1156, 1156, nil, nil, + nil, 1156, 1156, 1156, 1156, nil, nil, nil, nil, nil, + 1156, nil, nil, nil, nil, nil, nil, nil, 1156, 1156, + nil, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, 1156, + 1156, 1156, 1156, 1157, 1157, 1156, nil, 1157, nil, nil, + nil, nil, nil, nil, nil, 1157, 1157, nil, 1157, 1157, + 1157, 1157, 1157, 1157, 1157, nil, nil, 1157, 1157, nil, + nil, nil, 1157, 1157, 1157, 1157, nil, nil, nil, nil, + nil, 1157, nil, nil, nil, nil, nil, nil, nil, 1157, + 1157, nil, 1157, 1157, 1157, 1157, 1157, 1157, 1157, 1157, + 1157, 1157, 1157, 1157, nil, nil, 1157 ] + +racc_action_pointer = [ + nil, 58, 979, 85, nil, -110, nil, 5154, 964, 140, + 24312, 24440, 209, nil, 211, 220, 441, 310, -62, 374, + nil, -71, 5285, 1123, 24824, 387, nil, 171, nil, -8, + 5426, 5536, 5670, 5801, 5932, nil, 1123, 22454, 22585, nil, + 290, 525, 531, 453, 6063, 6194, 205, 6325, 6456, 525, + 6587, 387, -84, 162, 342, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 6728, nil, 6869, 7000, 7131, 35, + nil, 7262, 7393, nil, nil, 7524, 22724, 22855, 22986, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 612, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 0, nil, + nil, 112, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 7667, nil, nil, nil, nil, 7810, + 7941, 8072, 8203, 8346, nil, 1267, nil, 588, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 439, nil, 1411, 8477, + 8608, 8739, 8870, 9001, 9132, 26855, 26916, nil, nil, 9263, + 9394, 9525, nil, nil, 514, 141, 193, 522, 246, 469, + 536, nil, 9656, 1555, 542, nil, nil, 9787, 9918, 10049, + 10180, 10311, 10442, 10573, 10704, 10835, 10966, 11097, 11228, 11359, + 11490, 11621, 11752, 11883, 12014, 12145, 12276, 12407, 12538, nil, + nil, nil, nil, 12669, nil, nil, 226, 302, 515, 517, + 518, 532, 550, 558, 584, 585, nil, nil, nil, 12800, + nil, nil, 26977, nil, nil, 541, 12931, 13062, nil, nil, + nil, nil, nil, nil, nil, 13193, nil, 1843, nil, 512, + 538, nil, 13324, 586, 13455, nil, nil, 13586, 13717, nil, + nil, 74, nil, 13860, 1252, 565, 566, 1699, 594, 644, + 604, 23117, 1843, 694, 806, 873, 701, 878, nil, 677, + 637, 225, 679, 680, nil, nil, nil, 688, 221, 648, + 23256, nil, 564, 879, 2995, 3139, 737, nil, 744, 13991, + nil, 14122, 666, 1987, 668, nil, 719, 15595, 676, 2131, + 2275, 1396, 702, nil, 252, 402, 743, 726, 542, 753, + nil, 525, -1, 11, 14253, 2419, 2563, 216, 828, 710, + -18, 10, 893, 791, 11, 827, nil, nil, 441, 481, + 397, nil, 962, nil, 747, 14384, nil, 15614, nil, 193, + 378, 396, 402, 412, -27, -4, 463, nil, nil, nil, + nil, nil, nil, nil, 743, 24568, nil, nil, nil, nil, + 747, nil, 818, 729, 14515, 732, nil, nil, 721, nil, + 968, 253, 825, nil, nil, 1267, nil, nil, nil, nil, + nil, 1411, 739, nil, 739, 745, 615, 669, 14656, nil, + nil, nil, 222, 334, 790, nil, nil, 14788, 14924, nil, + nil, nil, -35, nil, 790, 27038, 27099, 15061, 277, 15192, + 15323, 15454, 24907, 25005, 3283, 3427, 1018, 2862, 815, 828, + 830, 832, 5011, 5154, 5285, 3571, 3715, 3859, 4003, 4147, + 4291, 3023, 3167, 4435, 4579, 1987, 4723, nil, -33, nil, + 15595, nil, nil, nil, nil, 15725, 784, 782, 792, nil, + nil, nil, 793, nil, nil, 15856, nil, 15987, nil, 16118, + nil, 329, nil, nil, nil, 16261, 1540, nil, 795, 800, + nil, nil, 805, 23387, 819, 16404, 27160, 27221, 972, 862, + nil, nil, 23518, 819, nil, 16535, 27282, 27343, 16666, 4867, + 2131, 16797, 16928, 946, 949, nil, nil, 829, 827, 838, + 840, 841, nil, 845, 858, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 848, 2837, nil, nil, 17059, nil, + nil, nil, -1, nil, nil, nil, 965, nil, nil, 967, + 264, 886, 17190, 1013, 1039, 920, 961, nil, 17321, nil, + nil, 17452, nil, nil, nil, 2707, 1041, nil, 2851, 62, + 1048, 1049, 39, 1051, 17583, 17714, 27404, 27465, 27, nil, + nil, 995, nil, 27526, 27587, 17845, nil, nil, 81, 2995, + nil, 24910, nil, nil, nil, nil, 1033, nil, nil, nil, + 943, nil, nil, 153, nil, 263, nil, nil, 932, nil, + 934, nil, nil, nil, 24696, nil, 17988, 936, 18119, 18250, + 18381, 27648, 27709, 18524, 18655, 693, 979, 18786, 18917, 19048, + 19179, 979, nil, nil, 19310, 19441, 981, nil, nil, nil, + 286, 306, 473, 612, 948, 994, nil, 974, nil, nil, + 440, 25103, 94, nil, 551, nil, nil, 6728, 26644, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1034, 513, nil, 1006, 966, 25246, nil, 1094, nil, 1078, + 91, nil, nil, 19572, nil, 993, 1000, 1102, nil, 980, + nil, 1043, 19703, nil, nil, 19834, nil, 245, 23649, 998, + nil, 1002, 236, 250, 1046, 360, 1123, 1047, 1006, 23780, + nil, 1082, -7, 1555, 1135, 19965, nil, nil, 831, nil, + nil, 888, nil, nil, 544, 25008, nil, 14719, nil, 20096, + nil, 2866, nil, 1017, 1018, 729, 1029, nil, nil, nil, + nil, nil, nil, 25106, 1699, nil, nil, nil, nil, 574, + 652, nil, 1151, nil, nil, nil, nil, nil, 1170, 1174, + nil, nil, 26, 1073, 40, 41, 151, 152, 3139, 970, + 1267, nil, 1074, 3283, 20227, nil, 1200, 63, 1083, nil, + nil, nil, nil, nil, 3427, nil, nil, nil, nil, nil, + nil, nil, nil, 1084, 20358, 1089, 343, 347, 722, 834, + nil, 2275, 20489, nil, 1089, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 20620, 20751, 20882, 21013, 445, + 1176, 25329, -41, -73, 25427, 25525, 612, 139, 1105, 1106, + nil, 25623, nil, 1104, 1114, 1197, 359, nil, 1137, 25721, + 26742, 26776, nil, nil, nil, nil, nil, 21144, nil, nil, + 1144, nil, nil, 1142, 1126, nil, nil, 15559, 3571, nil, + nil, nil, nil, 1124, 338, nil, nil, 21275, 1252, nil, + 3715, 1131, 1187, nil, nil, 1145, nil, 1143, 1146, nil, + 1147, nil, 1230, nil, 1150, 1170, nil, 1171, nil, nil, + 1176, 2896, 838, nil, nil, 21406, nil, 1299, nil, 21537, + 1300, nil, nil, 25819, 21668, 3859, 68, 1314, nil, 1318, + 361, 4003, nil, nil, nil, nil, 1212, 1258, 1226, 1221, + 468, nil, nil, 21799, 21930, nil, nil, nil, nil, 1227, + 1231, 1233, 1233, nil, nil, 25917, nil, nil, 303, nil, + nil, 1241, 1249, 1250, nil, nil, nil, 1294, 1258, -32, + nil, 26015, nil, 1262, nil, nil, -77, nil, nil, 2419, + 4147, nil, nil, 1261, 1264, nil, 1266, 1268, 1271, nil, + 1299, 1288, 1274, 23911, nil, nil, nil, 2563, nil, 4291, + nil, nil, 32, 24042, nil, nil, 25332, nil, 22632, nil, + nil, 23164, nil, 25626, nil, nil, nil, nil, 1287, 1290, + 2707, nil, 33, nil, 34, 693, 169, nil, nil, nil, + nil, 255, nil, nil, nil, 1415, 4435, 4579, 1109, nil, + nil, nil, nil, nil, 637, 1338, 333, nil, nil, nil, + nil, nil, nil, 1294, 26113, 1314, nil, nil, 370, nil, + nil, 1444, nil, nil, 25724, nil, nil, 25920, nil, 26018, + nil, nil, 1339, 24173, 1165, 1395, nil, 4723, 35, 36, + 1309, 1397, 42, nil, 1320, 1334, 1338, 1358, 3363, 3507, + 4867, nil, 22061, 22192, 26211, nil, nil, nil, nil, 1379, + 1488, 583, nil, nil, nil, nil, nil, nil, 26309, 1365, + 26407, 1368, nil, nil, 1372, 1374, 1382, 1390, nil, 1391, + nil, 1411, 27770, nil, 1518, 22323, 27831, 27892, 98, 26116, + nil, nil, nil, nil, 1397, 738, 5011, nil, nil, nil, + 1402, nil, nil, nil, 1829, 1403, 26505, nil, nil, nil, + 26214, nil, 26312, nil, 26410, nil, 26508, nil, nil, 1448, + 1449, nil, 1411, 102, 138, 145, 181, 1412, nil, 38, + 26603, nil, 1413, 1419, 1429, 1430, 146, nil, nil, nil, + nil, 1431, 26697, nil, nil, nil, nil, 1434, nil ] + +racc_action_default = [ + -1, -729, -4, -729, -2, -714, -5, -729, -8, -729, + -729, -729, -729, -31, -729, -729, -36, -729, -729, -305, + -48, -716, -729, -57, -729, -65, -66, -67, -71, -282, + -282, -282, -318, -345, -346, -83, -13, -87, -95, -97, + -729, -611, -612, -729, -729, -729, -729, -729, -729, -235, + -729, -716, -626, -626, -253, -296, -297, -298, -299, -300, + -301, -302, -303, -304, -702, -307, -311, -728, -692, -326, + -328, -729, -729, -59, -59, -714, -729, -729, -729, -347, + -348, -350, -351, -352, -353, -410, -551, -552, -553, -554, + -575, -557, -558, -577, -579, -562, -567, -571, -573, -589, + -590, -591, -575, -593, -595, -596, -597, -598, -700, -600, + -601, -701, -603, -604, -605, -606, -607, -608, -609, -610, + -615, -616, 1219, -3, -715, -724, -725, -726, -7, -729, + -729, -729, -729, -729, -9, -4, -19, -729, -126, -127, + -128, -129, -130, -131, -132, -136, -137, -138, -139, -140, + -141, -142, -143, -144, -145, -146, -147, -148, -149, -150, + -151, -152, -153, -154, -155, -156, -157, -158, -159, -160, + -161, -162, -163, -164, -165, -166, -167, -168, -169, -170, + -171, -172, -173, -174, -175, -176, -177, -178, -179, -180, + -181, -182, -183, -184, -185, -186, -187, -188, -189, -190, + -191, -192, -193, -194, -195, -196, -197, -198, -199, -200, + -201, -202, -203, -204, -205, -206, -24, -133, -13, -729, + -729, -729, -729, -729, -272, -729, -729, -712, -713, -729, + -729, -716, -717, -52, -729, -611, -612, -729, -305, -729, + -729, -241, -729, -13, -729, -53, -55, -218, -219, -729, + -729, -729, -729, -729, -729, -729, -729, -729, -729, -729, + -729, -729, -729, -729, -729, -729, -729, -729, -729, -254, + -255, -256, -257, -729, -61, -62, -729, -126, -127, -166, + -167, -168, -184, -189, -196, -199, -611, -612, -690, -729, + -419, -421, -729, -710, -711, -72, -272, -729, -325, -425, + -434, -436, -78, -431, -79, -716, -80, -260, -277, -286, + -286, -281, -729, -287, -729, -575, -694, -729, -729, -81, + -82, -714, -14, -729, -17, -729, -85, -13, -716, -729, + -88, -91, -13, -103, -104, -729, -729, -111, -318, -321, + -716, -729, -626, -626, -345, -346, -349, -432, -729, -93, + -729, -99, -315, -729, -220, -221, -594, -229, -230, -729, + -242, -729, -729, -13, -625, -621, -648, -648, -729, -13, + -13, -309, -716, -261, -721, -721, -729, -729, -721, -729, + -327, -58, -729, -729, -729, -13, -13, -714, -729, -715, + -611, -612, -729, -729, -305, -729, -363, -364, -121, -122, + -729, -124, -729, -305, -619, -729, -341, -648, -555, -729, + -729, -729, -729, -729, -729, -729, -729, -6, -727, -25, + -26, -27, -28, -29, -729, -729, -21, -22, -23, -134, + -729, -32, -35, -292, -729, -729, -291, -33, -729, -37, + -729, -305, -45, -47, -207, -265, -287, -49, -50, -38, + -208, -265, -716, -273, -286, -286, -703, -704, -282, -429, + -705, -706, -704, -703, -282, -428, -430, -705, -706, -44, + -215, -51, -716, -324, -729, -729, -729, -272, -315, -729, + -729, -729, -729, -729, -216, -217, -222, -223, -224, -225, + -226, -227, -231, -232, -233, -234, -236, -237, -238, -239, + -240, -243, -244, -245, -246, -716, -258, -63, -716, -440, + -282, -703, -704, -69, -73, -649, -716, -286, -716, -283, + -438, -440, -716, -320, -278, -729, -279, -729, -284, -729, + -288, -729, -697, -699, -12, -715, -16, -18, -716, -84, + -313, -100, -89, -729, -716, -272, -729, -729, -110, -729, + -625, -594, -729, -96, -101, -729, -729, -729, -729, -259, + -247, -729, -729, -543, -729, -376, -377, -716, -633, -716, + -689, -689, -631, -633, -633, -647, -649, -650, -651, -652, + -653, -654, -655, -656, -657, -729, -659, -661, -663, -668, + -670, -671, -674, -679, -681, -682, -684, -685, -686, -729, + -729, -633, -729, -729, -729, -716, -729, -262, -723, -722, + -264, -723, -316, -317, -693, -13, -354, -355, -13, -729, + -729, -729, -729, -729, -729, -272, -729, -729, -315, -59, + -121, -122, -123, -729, -729, -272, -337, -617, -729, -13, + -411, -648, -414, -556, -576, -581, -729, -583, -559, -578, + -729, -580, -561, -729, -564, -729, -566, -569, -729, -570, + -729, -592, -10, -20, -729, -30, -729, -295, -729, -729, + -272, -729, -729, -729, -729, -433, -729, -274, -276, -729, + -729, -74, -271, -426, -729, -729, -76, -427, -323, -718, + -703, -704, -703, -704, -716, -54, -460, -462, -464, -467, + -524, -716, -479, -482, -517, -522, -523, -729, -729, -527, + -528, -529, -530, -531, -532, -533, -534, -535, -536, -537, + -729, -729, -541, -56, -729, -729, -691, -729, -441, -68, + -422, -438, -267, -274, -269, -729, -400, -729, -319, -286, + -285, -289, -729, -695, -696, -729, -15, -86, -729, -92, + -98, -716, -703, -704, -270, -707, -109, -729, -94, -729, + -214, -228, -716, -249, -728, -728, -343, -622, -729, -640, + -624, -729, -629, -630, -729, -729, -643, -729, -645, -729, + -365, -729, -367, -369, -372, -375, -716, -662, -672, -673, + -683, -687, -627, -729, -251, -344, -308, -310, -312, -721, + -728, -356, -728, -60, -357, -358, -331, -332, -729, -729, + -446, -334, -729, -716, -703, -704, -707, -314, -13, -121, + -122, -125, -716, -13, -729, -339, -729, -729, -716, -582, + -585, -586, -587, -588, -13, -560, -563, -565, -568, -572, + -574, -135, -34, -293, -729, -716, -703, -704, -704, -703, + -46, -266, -729, -719, -286, -40, -210, -41, -211, -75, + -42, -213, -43, -212, -77, -729, -729, -729, -729, -433, + -729, -729, -465, -466, -729, -729, -729, -484, -716, -716, + -478, -485, -491, -729, -494, -498, -729, -481, -729, -729, + -520, -521, -525, -526, -538, -122, -539, -729, -64, -420, + -400, -424, -423, -729, -716, -435, -401, -716, -13, -437, + -280, -290, -698, -90, -433, -102, -322, -729, -728, -361, + -13, -544, -728, -545, -546, -716, -632, -633, -633, -660, + -689, -669, -674, -688, -633, -633, -680, -633, -657, -675, + -716, -729, -729, -374, -658, -729, -263, -729, -359, -729, + -729, -333, -335, -729, -729, -13, -433, -729, -433, -729, + -729, -13, -342, -412, -415, -417, -404, -729, -729, -294, + -433, -39, -209, -275, -729, -461, -463, -471, -475, -716, + -716, -716, -503, -505, -506, -509, -510, -575, -513, -515, + -516, -716, -716, -716, -540, -476, -477, -501, -486, -489, + -492, -729, -497, -716, -575, -720, -716, -518, -519, -248, + -13, -70, -268, -689, -689, -381, -383, -383, -383, -399, + -729, -716, -657, -665, -666, -677, -439, -250, -11, -13, + -550, -362, -729, -729, -548, -623, -729, -636, -729, -638, + -628, -729, -641, -729, -644, -646, -366, -368, -370, -373, + -252, -329, -729, -330, -729, -451, -454, -457, -458, -459, + -289, -728, -336, -338, -618, -729, -13, -13, -729, -413, + -584, -468, -469, -470, -504, -508, -729, -512, -514, -472, + -473, -474, -493, -487, -729, -495, -499, -480, -729, -483, + -442, -729, -379, -380, -384, -390, -392, -729, -395, -729, + -397, -402, -729, -729, -664, -729, -549, -13, -611, -612, + -729, -729, -305, -547, -633, -633, -633, -633, -729, -729, + -13, -447, -729, -729, -455, -443, -444, -445, -340, -729, + -729, -716, -406, -408, -409, -502, -507, -511, -729, -490, + -729, -689, -667, -382, -383, -383, -383, -383, -678, -383, + -403, -676, -729, -315, -543, -272, -729, -729, -315, -729, + -634, -637, -639, -642, -371, -728, -13, -452, -453, -456, + -494, -416, -418, -405, -729, -488, -729, -496, -500, -378, + -729, -387, -729, -389, -729, -393, -729, -396, -398, -314, + -707, -542, -716, -703, -704, -707, -314, -633, -360, -728, + -729, -407, -383, -383, -383, -383, -433, -635, -448, -449, + -450, -495, -729, -385, -388, -391, -394, -383, -386 ] + +racc_goto_table = [ + 42, 141, 141, 330, 291, 42, 452, 230, 380, 623, + 809, 308, 308, 308, 225, 141, 275, 409, 274, 342, + 342, 764, 287, 293, 526, 299, 303, 382, 383, 416, + 947, 387, 365, 365, 42, 334, 334, 361, 233, 127, + 929, 458, 464, 564, 136, 217, 292, 373, 356, 603, + 604, 930, 615, 618, 772, 773, 329, 918, 342, 342, + 342, 144, 144, 553, 42, 929, 343, 343, 632, 381, + 381, 385, 386, 381, 391, 287, 287, 780, 516, 518, + 346, 346, 436, 437, 878, 419, 420, 421, 422, 607, + 610, 735, 8, 614, 124, 950, 936, 8, 514, 743, + 887, 369, 584, 584, 449, 343, 343, 343, 510, 127, + 469, 568, 134, 1049, 740, 349, 740, 1014, 15, 346, + 346, 346, 42, 15, 326, 1085, 879, 381, 381, 381, + 381, 42, 786, 42, 328, 123, 1017, 4, 295, 302, + 304, 443, 1047, 584, 443, 967, 908, 128, 1132, 569, + 443, 1148, 15, 1, 567, 600, 371, 404, 406, 927, + 575, 575, 695, 723, 928, 1134, 2, 981, 993, 526, + 675, 934, 306, 319, 320, 1170, 309, 309, 309, 1003, + 1028, 727, 15, 743, 927, 746, 892, 893, 216, 928, + 397, 1177, 396, 737, 432, 642, 362, 368, 653, 655, + 425, 575, 482, 308, 483, 388, 550, 550, 1139, 803, + 276, 374, 725, 731, 8, 664, 42, 468, 359, 447, + 448, 459, 376, 423, 1020, 8, 730, 288, 471, 472, + 475, 377, 395, 636, 1148, 431, 442, 370, 430, 442, + 15, 42, 531, 808, 605, 442, 1059, 372, 823, 15, + 743, 15, 961, 639, 1201, 1048, 749, 979, 991, 694, + 1019, 1095, 1175, 329, 417, 758, 740, 740, 1021, 1131, + 424, 1134, 293, 780, 640, 308, 308, 943, 17, 963, + 407, 827, 932, 17, 308, 1066, 1067, 508, 509, 1164, + 520, 458, 464, 521, 900, 507, 1125, 1054, 1208, 980, + 992, 821, 903, 1018, 1014, 953, 1166, 1014, 1055, 1014, + 1010, 1058, 17, 342, 975, 929, 554, 976, 874, 826, + 1047, 42, 740, 1144, 1211, 42, 549, 751, 940, 334, + 42, 546, 342, 875, 15, 886, 438, 299, 1102, 438, + 619, 889, 17, 303, 1135, 438, 1136, 329, 334, 556, + 551, 922, 329, 1032, 1126, 127, 408, 936, 606, 15, + 343, 42, 754, 435, 435, 410, 929, 42, 42, 1007, + 1008, 1141, 754, 411, 346, 412, 413, 584, 1057, 343, + 414, 877, 381, 42, 42, 988, 988, 415, 626, 896, + 1014, 369, 1014, 346, 1014, 1198, 1014, 988, 829, 834, + 17, 1087, 824, 638, 931, 620, 621, 813, 542, 17, + 535, 17, 869, 536, 1040, 326, 141, 822, 1142, 880, + 326, 127, 1014, nil, nil, 538, nil, nil, 537, 828, + 544, nil, 1114, 780, 780, 575, 671, 519, 676, 15, + 517, 309, 754, 15, nil, 522, nil, nil, 15, 309, + 754, 534, 845, 910, 682, nil, 308, nil, 929, 663, + 687, 913, nil, nil, 988, nil, nil, 468, nil, 914, + nil, 459, nil, nil, nil, nil, 144, nil, nil, 15, + 717, 717, 955, nil, 859, 15, 15, 458, 464, 864, + 1145, 724, 1209, 1146, 17, nil, 17, 1092, 1093, 17, + nil, 15, 15, 959, 584, 17, 682, 1169, nil, 554, + nil, 584, nil, nil, 946, nil, 904, 622, 554, 17, + 935, nil, 937, nil, 308, 342, nil, nil, nil, 584, + nil, 956, nil, 42, 342, nil, nil, nil, 468, nil, + 958, 334, 459, nil, 994, 743, nil, nil, 468, nil, + 334, 925, 459, nil, 877, 877, 998, nil, nil, 762, + 855, 857, 740, 970, nil, 860, 862, 681, 910, 1006, + nil, nil, 343, 686, nil, nil, 1202, nil, nil, nil, + nil, 343, nil, nil, nil, 988, 346, 1210, nil, nil, + 443, 978, nil, nil, nil, 346, 995, 996, nil, 17, + 443, 443, 932, 17, 308, 443, 443, nil, 17, nil, + 780, 780, 1191, 42, 308, nil, 42, nil, 468, 729, + nil, nil, 459, nil, 468, 1179, nil, 818, 923, nil, + 459, nil, nil, 1056, 792, 800, nil, 42, 802, 17, + nil, 1065, nil, 1022, nil, 17, 17, nil, nil, 308, + nil, 15, 1016, 804, nil, 141, 649, 651, 654, 654, + nil, 17, 17, 468, 42, 1075, nil, 459, 450, 902, + nil, 42, 825, nil, 470, nil, 1086, nil, nil, nil, + 676, nil, 1127, nil, nil, 442, nil, 676, 888, nil, + 1090, nil, nil, nil, nil, 442, 442, nil, 841, 717, + 442, 442, 1107, nil, nil, 717, 717, nil, 901, 1079, + 1080, 1081, nil, nil, 554, 144, 141, 898, nil, 274, + nil, nil, 1120, nil, 1121, 915, nil, nil, nil, nil, + 342, 15, nil, 971, 15, nil, nil, 676, nil, nil, + nil, 342, nil, nil, nil, 924, 334, 1130, nil, nil, + 682, nil, nil, 687, nil, 15, 842, 334, nil, 1086, + nil, nil, nil, 850, nil, nil, nil, nil, 812, nil, + nil, nil, 584, 443, nil, nil, nil, 343, nil, nil, + 960, 1115, 15, 1116, 379, 438, 1117, nil, 343, 15, + nil, 346, nil, nil, nil, 438, 438, nil, nil, 676, + 438, 438, 346, nil, 877, nil, nil, nil, 676, nil, + nil, 17, nil, 1086, 966, 1178, 42, nil, nil, nil, + nil, 42, 381, nil, nil, 310, 310, 310, nil, nil, + 1022, 676, 42, 1022, nil, nil, nil, nil, 957, nil, + nil, nil, 1147, nil, 1149, nil, nil, nil, nil, nil, + nil, 1178, nil, nil, 968, nil, nil, nil, 1023, 676, + 375, 378, nil, nil, 676, 676, nil, nil, 442, 717, + nil, nil, 717, 717, nil, 1086, nil, nil, nil, 717, + nil, 933, nil, nil, 933, 776, 778, 717, 717, 717, + nil, 17, nil, 966, 17, nil, nil, nil, 1030, 837, + nil, 837, 1034, nil, 1197, 1052, 42, nil, nil, 435, + 1206, nil, nil, nil, 1076, 17, 1022, nil, 42, nil, + nil, nil, nil, nil, 470, 1203, 450, 1204, 1026, 1205, + nil, 1088, nil, nil, 15, 433, 446, 1192, nil, 15, + 1031, nil, 17, nil, nil, 17, nil, 381, nil, 17, + 15, 717, nil, 42, nil, 17, 17, 1217, nil, 42, + 17, 17, nil, nil, nil, nil, nil, nil, 438, nil, + nil, nil, 754, nil, nil, 1061, nil, 676, 676, 676, + nil, nil, nil, 717, nil, nil, nil, nil, nil, 888, + nil, nil, nil, nil, 1064, nil, nil, nil, nil, 717, + 760, nil, nil, nil, nil, 342, nil, 966, 42, nil, + nil, nil, nil, nil, nil, 342, nil, 1015, nil, nil, + nil, 287, nil, nil, 15, 709, 709, 42, 528, nil, + 530, 1109, nil, 532, 533, nil, 15, nil, 18, nil, + nil, nil, 1023, 18, nil, 1023, nil, nil, 1023, 1106, + 1023, nil, 343, nil, nil, nil, nil, nil, 234, nil, + nil, nil, 343, nil, 42, 42, 346, nil, 234, 234, + 234, 15, 18, 335, 335, nil, 346, 15, 1167, 1168, + nil, nil, 717, nil, nil, 342, 1129, nil, nil, nil, + 310, nil, nil, nil, 17, nil, nil, nil, 310, 17, + nil, 287, 18, nil, nil, 42, 1156, 234, 234, nil, + 17, 234, 392, 402, 402, nil, nil, 1173, 42, nil, + 381, 381, 717, nil, 856, 858, 15, 1154, 17, 861, + 863, 1023, 343, 1023, 308, 1023, 717, 1023, 717, nil, + 1165, nil, nil, 468, nil, 15, 346, nil, 468, 1113, + 667, nil, 459, nil, 19, nil, nil, nil, nil, 19, + 18, nil, nil, 1023, 42, 234, 234, 234, 234, 18, + nil, 18, nil, nil, 717, nil, nil, nil, 676, nil, + nil, nil, 15, 15, 17, nil, 1199, nil, 19, 337, + 337, nil, nil, nil, nil, nil, 17, nil, 717, nil, + nil, 933, nil, 473, 1015, nil, nil, 1015, nil, 1015, + nil, 710, 710, nil, nil, nil, nil, nil, 19, nil, + nil, nil, nil, 15, 1096, 1098, 1100, nil, 394, 403, + 403, 17, nil, nil, nil, nil, 15, 17, nil, 1037, + 1039, 741, nil, 379, 709, 744, 1042, 1044, nil, 1045, + 709, 709, nil, nil, 18, 234, 440, 234, 234, 440, + 234, nil, nil, nil, nil, 440, 234, 234, nil, nil, + nil, nil, nil, nil, nil, nil, 19, 523, nil, 18, + nil, nil, 15, nil, nil, 19, 17, 19, nil, nil, + 1015, nil, 1015, nil, 1015, nil, 1015, 972, nil, nil, + 539, nil, nil, nil, 787, 17, nil, nil, nil, nil, + 856, 858, 863, 861, nil, nil, nil, nil, 739, nil, + nil, nil, 1015, nil, 741, 234, nil, 379, nil, nil, + nil, nil, 234, 234, nil, nil, nil, nil, nil, nil, + 446, 234, 17, 17, nil, nil, nil, nil, nil, nil, + nil, nil, 1181, 1183, 1185, 1187, nil, 1188, nil, 18, + nil, nil, nil, 18, nil, nil, nil, 335, 18, nil, + 19, nil, 441, nil, nil, 441, nil, nil, nil, nil, + nil, 441, nil, 17, 843, nil, 335, nil, nil, nil, + nil, nil, nil, 741, 379, 19, 17, nil, nil, 18, + nil, 799, nil, nil, nil, 18, 18, nil, nil, nil, + 1213, 1214, 1215, 1216, 709, nil, nil, 709, 709, 972, + 234, 18, 18, nil, 709, 1218, 1160, 1161, 1162, 1163, + 710, nil, 709, 709, 709, nil, 710, 710, nil, nil, + nil, 234, 17, nil, 688, nil, nil, nil, nil, 741, + nil, nil, nil, nil, nil, nil, nil, nil, 911, nil, + nil, 912, nil, nil, nil, nil, nil, nil, nil, nil, + 854, nil, nil, nil, nil, 19, nil, nil, nil, 19, + 726, 921, nil, 337, 19, nil, nil, nil, 732, nil, + 734, nil, nil, nil, 738, 939, 709, nil, nil, nil, + nil, nil, 337, nil, nil, nil, nil, nil, nil, 1207, + 747, nil, nil, 234, nil, 19, 750, nil, nil, nil, + nil, 19, 19, nil, nil, nil, 854, nil, 709, nil, + nil, nil, nil, nil, nil, nil, nil, 19, 19, 767, + nil, 770, nil, nil, 709, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 969, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 18, nil, nil, nil, nil, nil, 797, nil, 335, + nil, 234, nil, nil, nil, nil, nil, nil, 335, nil, + nil, nil, nil, nil, nil, nil, nil, 234, nil, nil, + 710, nil, nil, 710, 710, nil, nil, nil, nil, nil, + 710, nil, nil, nil, nil, nil, nil, nil, 710, 710, + 710, nil, nil, nil, nil, nil, nil, 709, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 18, nil, nil, 18, nil, nil, nil, nil, nil, + nil, 234, nil, nil, nil, nil, nil, 709, nil, nil, + 1060, 234, nil, nil, nil, 18, nil, nil, nil, nil, + nil, 709, 710, 709, nil, nil, nil, 19, nil, 379, + nil, nil, nil, nil, nil, 337, nil, nil, nil, nil, + nil, nil, 18, nil, 337, 440, 234, nil, nil, 18, + nil, nil, nil, nil, 710, 440, 440, nil, nil, 709, + 440, 440, nil, nil, nil, nil, nil, nil, nil, nil, + 710, nil, nil, nil, 916, nil, nil, nil, nil, nil, + nil, nil, nil, 709, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 944, nil, + nil, nil, nil, nil, nil, nil, nil, 19, nil, nil, + 19, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 335, nil, nil, nil, nil, nil, + nil, 19, nil, nil, nil, 335, nil, nil, 833, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 710, nil, nil, nil, nil, 19, nil, + nil, 441, nil, nil, nil, 19, nil, nil, nil, nil, + nil, 441, 441, nil, nil, nil, 441, 441, nil, nil, + nil, nil, nil, nil, 977, nil, nil, nil, nil, nil, + nil, nil, nil, 710, 18, nil, nil, nil, nil, 18, + 234, nil, nil, nil, nil, nil, nil, 710, nil, 710, + 18, nil, nil, nil, nil, nil, 1012, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 440, nil, + nil, nil, nil, nil, nil, nil, nil, 1035, nil, nil, + 337, nil, nil, 29, nil, 710, nil, nil, 29, nil, + nil, 337, 1046, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 29, nil, nil, nil, nil, nil, 710, + nil, nil, nil, 29, 29, 29, nil, 29, nil, nil, + nil, nil, nil, nil, 18, nil, nil, nil, nil, nil, + nil, 1071, 1072, 1073, nil, nil, 18, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 29, nil, nil, + 19, nil, 29, 29, nil, 19, 29, nil, 1089, nil, + nil, nil, nil, nil, nil, 234, 19, nil, nil, nil, + nil, 18, nil, nil, nil, nil, nil, 18, nil, nil, + nil, nil, nil, nil, 441, nil, nil, nil, nil, nil, + 711, 711, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 29, nil, nil, nil, nil, + 29, 29, 29, 29, 29, nil, 29, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 18, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 712, 712, nil, 1104, + 19, nil, nil, nil, nil, 18, nil, nil, nil, 1110, + nil, nil, 19, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 18, 18, nil, nil, nil, 19, nil, nil, + nil, nil, nil, 19, nil, nil, nil, nil, nil, 29, + 29, 29, 29, 29, 29, 29, nil, nil, nil, nil, + 29, 29, 29, nil, nil, nil, nil, nil, nil, 1151, + nil, nil, nil, 18, 29, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 18, nil, 234, 234, + nil, nil, 19, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 403, nil, nil, nil, nil, + nil, 19, nil, nil, nil, 1112, nil, nil, nil, nil, + 29, 234, nil, nil, nil, nil, nil, 29, 29, nil, + nil, nil, 18, nil, nil, nil, 29, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 19, 19, + nil, nil, nil, nil, 29, nil, nil, nil, 29, 711, + nil, nil, nil, 29, nil, 711, 711, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 403, nil, nil, 32, 19, + nil, nil, nil, 32, 29, nil, nil, nil, nil, nil, + 29, 29, 19, nil, nil, 712, nil, nil, 32, nil, + nil, 712, 712, nil, nil, 29, 29, 29, 32, 32, + 32, nil, 32, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 29, nil, 41, nil, + nil, nil, nil, 41, nil, nil, nil, nil, 19, nil, + nil, nil, 32, nil, nil, nil, nil, 32, 32, nil, + 286, 32, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 41, 333, 333, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 41, nil, nil, nil, nil, nil, 29, nil, + 32, nil, 390, 286, 286, 32, 32, 32, 32, 32, + nil, 32, nil, nil, nil, nil, nil, 713, 713, 711, + nil, nil, 711, 711, nil, nil, nil, nil, nil, 711, + nil, nil, nil, nil, nil, nil, nil, 711, 711, 711, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 41, nil, nil, nil, nil, nil, 29, nil, nil, 41, + nil, 41, nil, nil, nil, 712, 29, nil, 712, 712, + nil, nil, nil, nil, nil, 712, nil, nil, nil, nil, + nil, nil, 29, 712, 712, 712, nil, nil, nil, nil, + nil, nil, nil, nil, 32, 32, 32, 32, 32, 32, + 32, 711, nil, nil, nil, 32, 32, 32, nil, nil, + 714, 714, nil, nil, nil, nil, nil, nil, nil, 32, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 711, nil, nil, 29, nil, nil, 29, + nil, nil, nil, nil, 41, nil, 29, 712, nil, 711, + nil, nil, nil, nil, nil, nil, 29, nil, nil, nil, + 29, nil, nil, nil, nil, 32, nil, nil, nil, 41, + nil, nil, 32, 32, nil, nil, nil, nil, nil, 712, + nil, 32, nil, nil, nil, nil, nil, 29, nil, nil, + 29, 29, nil, nil, 29, 712, nil, nil, nil, 32, + 29, 29, nil, 32, nil, 29, 29, nil, 32, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 711, nil, nil, nil, 713, nil, nil, 32, + nil, nil, 713, 713, nil, 32, 32, nil, nil, 41, + nil, nil, nil, 41, nil, nil, nil, 333, 41, nil, + 32, 32, 32, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 711, nil, nil, nil, 333, nil, 712, nil, + nil, 32, nil, nil, nil, nil, 711, nil, 711, 41, + nil, nil, nil, nil, nil, 41, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 41, 41, nil, 715, 715, nil, nil, 712, nil, + nil, nil, nil, nil, 711, nil, nil, nil, nil, 714, + nil, nil, 712, nil, 712, 714, 714, nil, nil, 29, + nil, nil, nil, nil, 29, 29, nil, nil, 711, nil, + nil, nil, nil, 32, nil, 29, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 712, nil, nil, 29, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 712, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 713, nil, nil, 713, + 713, 32, nil, nil, nil, nil, 713, nil, nil, nil, + nil, 32, nil, nil, 713, 713, 713, nil, nil, 29, + nil, nil, nil, nil, nil, nil, nil, 32, nil, nil, + nil, 29, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 41, nil, nil, nil, nil, nil, nil, nil, 333, + 29, nil, nil, nil, nil, nil, 29, nil, 333, nil, + nil, nil, 29, nil, nil, nil, nil, nil, 713, nil, + nil, 32, nil, nil, 32, nil, nil, nil, nil, 714, + nil, 32, 714, 714, nil, nil, nil, nil, nil, 714, + nil, 32, nil, nil, nil, 32, nil, 714, 714, 714, + 713, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 29, nil, 715, nil, nil, 713, nil, nil, 715, + 715, 41, 32, nil, 41, 32, 32, nil, nil, 32, + 29, nil, nil, nil, nil, 32, 32, nil, nil, nil, + 32, 32, nil, nil, nil, 41, nil, nil, 716, 716, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 714, nil, nil, nil, nil, nil, 29, 29, nil, + nil, nil, 41, nil, nil, 718, 718, nil, nil, 41, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 714, nil, nil, nil, nil, nil, 713, + nil, nil, nil, nil, nil, 241, nil, nil, 29, 714, + nil, nil, nil, nil, nil, 307, 307, 307, nil, nil, + nil, 29, nil, 29, 29, nil, nil, 354, 355, nil, + 357, 358, nil, 360, nil, nil, nil, nil, nil, 713, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 307, 307, nil, 713, 333, 713, 29, nil, nil, nil, + nil, nil, nil, nil, nil, 333, nil, 29, nil, nil, + nil, nil, nil, nil, 32, nil, nil, nil, nil, 32, + 32, nil, nil, 715, nil, nil, 715, 715, nil, nil, + 32, 713, 714, 715, nil, nil, nil, nil, nil, nil, + nil, 715, 715, 715, nil, nil, nil, nil, 32, nil, + nil, nil, nil, nil, nil, 713, nil, nil, nil, nil, + nil, nil, nil, nil, 41, nil, nil, nil, nil, 41, + nil, nil, 714, nil, nil, nil, nil, nil, nil, nil, + 41, nil, nil, nil, nil, nil, 714, nil, 714, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 32, 715, nil, 716, nil, nil, + nil, nil, nil, 716, 716, nil, 32, nil, nil, nil, + nil, nil, nil, nil, 714, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 718, nil, nil, 715, nil, nil, + 718, 718, 307, 445, nil, 32, 451, 307, 714, nil, + nil, 32, 451, 715, 41, nil, nil, 32, nil, nil, + nil, nil, nil, nil, nil, 241, 41, nil, nil, nil, + 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, + 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, + 504, 505, nil, nil, nil, nil, 506, nil, nil, nil, + nil, 41, nil, nil, nil, nil, 32, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 307, + 307, nil, nil, nil, nil, 32, nil, nil, 307, nil, + nil, nil, nil, nil, nil, 307, 715, 307, nil, nil, + 307, 307, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 41, nil, nil, nil, + nil, nil, 32, 32, nil, nil, nil, nil, nil, 286, + nil, nil, nil, nil, nil, 41, 715, 716, nil, 1108, + 716, 716, 559, nil, 560, nil, nil, 716, nil, nil, + 715, nil, 715, nil, nil, 716, 716, 716, nil, nil, + nil, nil, nil, 32, 718, nil, nil, 718, 718, nil, + nil, nil, 41, 41, 718, nil, 32, nil, 32, 32, + nil, nil, 718, 718, 718, nil, nil, nil, 715, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 286, + nil, 32, 715, 41, nil, nil, nil, 307, nil, 716, + nil, nil, 32, nil, nil, nil, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 718, nil, nil, nil, + nil, 716, nil, nil, nil, nil, nil, nil, nil, nil, + 307, nil, 451, 451, 451, nil, nil, 716, nil, nil, + nil, nil, 41, nil, nil, nil, nil, nil, 718, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 718, nil, nil, nil, 355, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 307, nil, + 307, nil, 307, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 307, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 451, nil, + nil, 761, nil, nil, nil, 763, nil, nil, nil, nil, + 716, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 307, nil, nil, nil, nil, nil, 718, nil, nil, + nil, nil, nil, nil, nil, 794, nil, nil, nil, nil, + 716, 307, nil, nil, 307, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 716, nil, 716, 307, 307, nil, + nil, nil, nil, nil, nil, nil, nil, 718, 307, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 718, nil, 718, nil, nil, nil, nil, nil, nil, + nil, nil, 716, nil, nil, nil, nil, nil, nil, nil, + nil, 307, 451, 307, nil, nil, nil, 851, nil, nil, + 307, 307, 451, 451, nil, nil, 716, 451, 451, 718, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 718, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 307, nil, nil, nil, + nil, nil, nil, nil, nil, 307, nil, nil, 307, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 307, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 307, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 307, nil, nil, + nil, nil, nil, nil, nil, 451, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 451, 451, + 451, 451, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1009, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1027, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 1050, nil, + nil, nil, nil, nil, nil, nil, nil, 307, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 307, 451, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 307 ] + +racc_goto_check = [ + 71, 74, 74, 67, 154, 71, 31, 35, 106, 111, + 112, 51, 51, 51, 33, 74, 42, 194, 44, 45, + 45, 12, 71, 33, 93, 90, 90, 19, 19, 194, + 110, 19, 86, 86, 71, 71, 71, 35, 22, 116, + 225, 54, 54, 10, 17, 17, 49, 86, 79, 10, + 10, 131, 109, 109, 135, 135, 11, 13, 45, 45, + 45, 76, 76, 69, 71, 225, 47, 47, 72, 26, + 26, 40, 40, 26, 71, 71, 71, 126, 31, 91, + 82, 82, 24, 24, 171, 19, 19, 19, 19, 88, + 88, 57, 8, 88, 7, 13, 229, 8, 56, 233, + 183, 118, 224, 224, 28, 47, 47, 47, 54, 116, + 28, 140, 9, 128, 94, 68, 94, 130, 23, 82, + 82, 82, 71, 23, 63, 188, 172, 26, 26, 26, + 26, 71, 127, 71, 64, 5, 141, 2, 55, 55, + 55, 20, 125, 224, 20, 145, 143, 6, 147, 91, + 20, 230, 23, 1, 153, 153, 8, 73, 73, 223, + 219, 219, 37, 37, 142, 148, 3, 174, 174, 93, + 32, 142, 62, 62, 62, 189, 87, 87, 87, 174, + 14, 157, 23, 233, 223, 16, 198, 198, 18, 142, + 21, 189, 23, 157, 25, 153, 81, 81, 208, 208, + 27, 219, 38, 51, 39, 5, 218, 218, 188, 41, + 48, 87, 50, 59, 8, 77, 71, 74, 83, 26, + 26, 90, 85, 8, 145, 8, 92, 104, 26, 26, + 33, 105, 113, 115, 230, 22, 22, 119, 11, 22, + 23, 71, 194, 111, 120, 22, 174, 121, 122, 23, + 233, 23, 123, 124, 147, 129, 69, 171, 171, 31, + 133, 138, 188, 11, 6, 69, 94, 94, 139, 146, + 2, 148, 33, 126, 149, 51, 51, 126, 29, 150, + 151, 152, 196, 29, 51, 155, 156, 26, 158, 128, + 160, 54, 54, 161, 164, 49, 165, 166, 167, 172, + 172, 72, 57, 142, 130, 168, 169, 130, 170, 130, + 143, 173, 29, 45, 176, 225, 67, 178, 179, 10, + 125, 71, 94, 141, 188, 71, 35, 31, 127, 71, + 71, 33, 45, 180, 23, 184, 23, 90, 145, 23, + 19, 185, 29, 90, 191, 23, 192, 11, 71, 33, + 79, 200, 11, 201, 13, 116, 204, 229, 35, 23, + 47, 71, 54, 87, 87, 205, 225, 71, 71, 198, + 198, 131, 54, 206, 82, 207, 210, 224, 172, 47, + 211, 37, 26, 71, 71, 196, 196, 212, 33, 72, + 130, 118, 130, 82, 130, 110, 130, 196, 213, 214, + 29, 183, 217, 26, 227, 11, 11, 31, 68, 29, + 7, 29, 32, 8, 135, 63, 74, 31, 228, 32, + 63, 116, 130, nil, nil, 64, nil, nil, 9, 153, + 64, nil, 142, 126, 126, 219, 33, 62, 35, 23, + 87, 87, 54, 23, nil, 62, nil, nil, 23, 87, + 54, 5, 31, 93, 90, nil, 51, nil, 225, 17, + 90, 69, nil, nil, 196, nil, nil, 74, nil, 32, + nil, 90, nil, nil, nil, nil, 76, nil, nil, 23, + 71, 71, 109, nil, 56, 23, 23, 54, 54, 56, + 142, 35, 13, 142, 29, nil, 29, 135, 135, 29, + nil, 23, 23, 10, 224, 29, 90, 171, nil, 67, + nil, 224, nil, nil, 88, nil, 91, 5, 67, 29, + 140, nil, 140, nil, 51, 45, nil, nil, nil, 224, + nil, 32, nil, 71, 45, nil, nil, nil, 74, nil, + 32, 71, 90, nil, 72, 233, nil, nil, 74, nil, + 71, 91, 90, nil, 37, 37, 187, nil, nil, 26, + 28, 28, 94, 32, nil, 28, 28, 55, 93, 37, + nil, nil, 47, 55, nil, nil, 142, nil, nil, nil, + nil, 47, nil, nil, nil, 196, 82, 112, nil, nil, + 20, 32, nil, nil, nil, 82, 32, 32, nil, 29, + 20, 20, 196, 29, 51, 20, 20, nil, 29, nil, + 126, 126, 12, 71, 51, nil, 71, nil, 74, 55, + nil, nil, 90, nil, 74, 135, nil, 40, 24, nil, + 90, nil, nil, 37, 116, 11, nil, 71, 11, 29, + nil, 10, nil, 224, nil, 29, 29, nil, nil, 51, + nil, 23, 140, 116, nil, 74, 209, 209, 209, 209, + nil, 29, 29, 74, 71, 37, nil, 90, 78, 106, + nil, 71, 116, nil, 78, nil, 187, nil, nil, nil, + 35, nil, 111, nil, nil, 22, nil, 35, 35, nil, + 10, nil, nil, nil, nil, 22, 22, nil, 17, 71, + 22, 22, 109, nil, nil, 71, 71, nil, 154, 32, + 32, 32, nil, nil, 67, 76, 74, 42, nil, 44, + nil, nil, 109, nil, 109, 67, nil, nil, nil, nil, + 45, 23, nil, 28, 23, nil, nil, 35, nil, nil, + nil, 45, nil, nil, nil, 86, 71, 10, nil, nil, + 90, nil, nil, 90, nil, 23, 8, 71, nil, 187, + nil, nil, nil, 8, nil, nil, nil, nil, 87, nil, + nil, nil, 224, 20, nil, nil, nil, 47, nil, nil, + 19, 140, 23, 140, 84, 23, 140, nil, 47, 23, + nil, 82, nil, nil, nil, 23, 23, nil, nil, 35, + 23, 23, 82, nil, 37, nil, nil, nil, 35, nil, + nil, 29, nil, 187, 35, 187, 71, nil, nil, nil, + nil, 71, 26, nil, nil, 89, 89, 89, nil, nil, + 224, 35, 71, 224, nil, nil, nil, nil, 11, nil, + nil, nil, 140, nil, 140, nil, nil, nil, nil, nil, + nil, 187, nil, nil, 11, nil, nil, nil, 226, 35, + 89, 89, nil, nil, 35, 35, nil, nil, 22, 71, + nil, nil, 71, 71, nil, 187, nil, nil, nil, 71, + nil, 136, nil, nil, 136, 222, 222, 71, 71, 71, + nil, 29, nil, 35, 29, nil, nil, nil, 86, 209, + nil, 209, 86, nil, 140, 19, 71, nil, nil, 87, + 32, nil, nil, nil, 194, 29, 224, nil, 71, nil, + nil, nil, nil, nil, 78, 140, 78, 140, 11, 140, + nil, 194, nil, nil, 23, 84, 84, 31, nil, 23, + 11, nil, 29, nil, nil, 29, nil, 26, nil, 29, + 23, 71, nil, 71, nil, 29, 29, 140, nil, 71, + 29, 29, nil, nil, nil, nil, nil, nil, 23, nil, + nil, nil, 54, nil, nil, 11, nil, 35, 35, 35, + nil, nil, nil, 71, nil, nil, nil, nil, nil, 35, + nil, nil, nil, nil, 116, nil, nil, nil, nil, 71, + 78, nil, nil, nil, nil, 45, nil, 35, 71, nil, + nil, nil, nil, nil, nil, 45, nil, 136, nil, nil, + nil, 71, nil, nil, 23, 96, 96, 71, 84, nil, + 84, 71, nil, 84, 84, nil, 23, nil, 30, nil, + nil, nil, 226, 30, nil, 226, nil, nil, 226, 11, + 226, nil, 47, nil, nil, nil, nil, nil, 30, nil, + nil, nil, 47, nil, 71, 71, 82, nil, 30, 30, + 30, 23, 30, 30, 30, nil, 82, 23, 19, 19, + nil, nil, 71, nil, nil, 45, 11, nil, nil, nil, + 89, nil, nil, nil, 29, nil, nil, nil, 89, 29, + nil, 71, 30, nil, nil, 71, 33, 30, 30, nil, + 29, 30, 30, 30, 30, nil, nil, 35, 71, nil, + 26, 26, 71, nil, 78, 78, 23, 11, 29, 78, + 78, 226, 47, 226, 51, 226, 71, 226, 71, nil, + 11, nil, nil, 74, nil, 23, 82, nil, 74, 23, + 84, nil, 90, nil, 34, nil, nil, nil, nil, 34, + 30, nil, nil, 226, 71, 30, 30, 30, 30, 30, + nil, 30, nil, nil, 71, nil, nil, nil, 35, nil, + nil, nil, 23, 23, 29, nil, 11, nil, 34, 34, + 34, nil, nil, nil, nil, nil, 29, nil, 71, nil, + nil, 136, nil, 65, 136, nil, nil, 136, nil, 136, + nil, 97, 97, nil, nil, nil, nil, nil, 34, nil, + nil, nil, nil, 23, 137, 137, 137, nil, 34, 34, + 34, 29, nil, nil, nil, nil, 23, 29, nil, 222, + 222, 84, nil, 84, 96, 84, 222, 222, nil, 222, + 96, 96, nil, nil, 30, 30, 30, 30, 30, 30, + 30, nil, nil, nil, nil, 30, 30, 30, nil, nil, + nil, nil, nil, nil, nil, nil, 34, 65, nil, 30, + nil, nil, 23, nil, nil, 34, 29, 34, nil, nil, + 136, nil, 136, nil, 136, nil, 136, 78, nil, nil, + 65, nil, nil, nil, 84, 29, nil, nil, nil, nil, + 78, 78, 78, 78, nil, nil, nil, nil, 89, nil, + nil, nil, 136, nil, 84, 30, nil, 84, nil, nil, + nil, nil, 30, 30, nil, nil, nil, nil, nil, nil, + 84, 30, 29, 29, nil, nil, nil, nil, nil, nil, + nil, nil, 137, 137, 137, 137, nil, 137, nil, 30, + nil, nil, nil, 30, nil, nil, nil, 30, 30, nil, + 34, nil, 34, nil, nil, 34, nil, nil, nil, nil, + nil, 34, nil, 29, 84, nil, 30, nil, nil, nil, + nil, nil, nil, 84, 84, 34, 29, nil, nil, 30, + nil, 89, nil, nil, nil, 30, 30, nil, nil, nil, + 137, 137, 137, 137, 96, nil, nil, 96, 96, 78, + 30, 30, 30, nil, 96, 137, 222, 222, 222, 222, + 97, nil, 96, 96, 96, nil, 97, 97, nil, nil, + nil, 30, 29, nil, 65, nil, nil, nil, nil, 84, + nil, nil, nil, nil, nil, nil, nil, nil, 84, nil, + nil, 84, nil, nil, nil, nil, nil, nil, nil, nil, + 89, nil, nil, nil, nil, 34, nil, nil, nil, 34, + 65, 84, nil, 34, 34, nil, nil, nil, 65, nil, + 65, nil, nil, nil, 65, 84, 96, nil, nil, nil, + nil, nil, 34, nil, nil, nil, nil, nil, nil, 222, + 65, nil, nil, 30, nil, 34, 65, nil, nil, nil, + nil, 34, 34, nil, nil, nil, 89, nil, 96, nil, + nil, nil, nil, nil, nil, nil, nil, 34, 34, 65, + nil, 65, nil, nil, 96, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 84, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 30, nil, nil, nil, nil, nil, 65, nil, 30, + nil, 30, nil, nil, nil, nil, nil, nil, 30, nil, + nil, nil, nil, nil, nil, nil, nil, 30, nil, nil, + 97, nil, nil, 97, 97, nil, nil, nil, nil, nil, + 97, nil, nil, nil, nil, nil, nil, nil, 97, 97, + 97, nil, nil, nil, nil, nil, nil, 96, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 30, nil, nil, 30, nil, nil, nil, nil, nil, + nil, 30, nil, nil, nil, nil, nil, 96, nil, nil, + 84, 30, nil, nil, nil, 30, nil, nil, nil, nil, + nil, 96, 97, 96, nil, nil, nil, 34, nil, 84, + nil, nil, nil, nil, nil, 34, nil, nil, nil, nil, + nil, nil, 30, nil, 34, 30, 30, nil, nil, 30, + nil, nil, nil, nil, 97, 30, 30, nil, nil, 96, + 30, 30, nil, nil, nil, nil, nil, nil, nil, nil, + 97, nil, nil, nil, 65, nil, nil, nil, nil, nil, + nil, nil, nil, 96, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 65, nil, + nil, nil, nil, nil, nil, nil, nil, 34, nil, nil, + 34, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 30, nil, nil, nil, nil, nil, + nil, 34, nil, nil, nil, 30, nil, nil, 34, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 97, nil, nil, nil, nil, 34, nil, + nil, 34, nil, nil, nil, 34, nil, nil, nil, nil, + nil, 34, 34, nil, nil, nil, 34, 34, nil, nil, + nil, nil, nil, nil, 65, nil, nil, nil, nil, nil, + nil, nil, nil, 97, 30, nil, nil, nil, nil, 30, + 30, nil, nil, nil, nil, nil, nil, 97, nil, 97, + 30, nil, nil, nil, nil, nil, 65, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 30, nil, + nil, nil, nil, nil, nil, nil, nil, 65, nil, nil, + 34, nil, nil, 58, nil, 97, nil, nil, 58, nil, + nil, 34, 65, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 58, nil, nil, nil, nil, nil, 97, + nil, nil, nil, 58, 58, 58, nil, 58, nil, nil, + nil, nil, nil, nil, 30, nil, nil, nil, nil, nil, + nil, 65, 65, 65, nil, nil, 30, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 58, nil, nil, + 34, nil, 58, 58, nil, 34, 58, nil, 65, nil, + nil, nil, nil, nil, nil, 30, 34, nil, nil, nil, + nil, 30, nil, nil, nil, nil, nil, 30, nil, nil, + nil, nil, nil, nil, 34, nil, nil, nil, nil, nil, + 98, 98, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 58, nil, nil, nil, nil, + 58, 58, 58, 58, 58, nil, 58, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 30, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 99, 99, nil, 30, + 34, nil, nil, nil, nil, 30, nil, nil, nil, 30, + nil, nil, 34, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 30, 30, nil, nil, nil, 34, nil, nil, + nil, nil, nil, 34, nil, nil, nil, nil, nil, 58, + 58, 58, 58, 58, 58, 58, nil, nil, nil, nil, + 58, 58, 58, nil, nil, nil, nil, nil, nil, 30, + nil, nil, nil, 30, 58, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 30, nil, 30, 30, + nil, nil, 34, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 34, nil, nil, nil, nil, + nil, 34, nil, nil, nil, 34, nil, nil, nil, nil, + 58, 30, nil, nil, nil, nil, nil, 58, 58, nil, + nil, nil, 30, nil, nil, nil, 58, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 34, 34, + nil, nil, nil, nil, 58, nil, nil, nil, 58, 98, + nil, nil, nil, 58, nil, 98, 98, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 34, nil, nil, 61, 34, + nil, nil, nil, 61, 58, nil, nil, nil, nil, nil, + 58, 58, 34, nil, nil, 99, nil, nil, 61, nil, + nil, 99, 99, nil, nil, 58, 58, 58, 61, 61, + 61, nil, 61, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 58, nil, 70, nil, + nil, nil, nil, 70, nil, nil, nil, nil, 34, nil, + nil, nil, 61, nil, nil, nil, nil, 61, 61, nil, + 70, 61, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 70, 70, 70, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 70, nil, nil, nil, nil, nil, 58, nil, + 61, nil, 70, 70, 70, 61, 61, 61, 61, 61, + nil, 61, nil, nil, nil, nil, nil, 100, 100, 98, + nil, nil, 98, 98, nil, nil, nil, nil, nil, 98, + nil, nil, nil, nil, nil, nil, nil, 98, 98, 98, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 70, nil, nil, nil, nil, nil, 58, nil, nil, 70, + nil, 70, nil, nil, nil, 99, 58, nil, 99, 99, + nil, nil, nil, nil, nil, 99, nil, nil, nil, nil, + nil, nil, 58, 99, 99, 99, nil, nil, nil, nil, + nil, nil, nil, nil, 61, 61, 61, 61, 61, 61, + 61, 98, nil, nil, nil, 61, 61, 61, nil, nil, + 101, 101, nil, nil, nil, nil, nil, nil, nil, 61, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 98, nil, nil, 58, nil, nil, 58, + nil, nil, nil, nil, 70, nil, 58, 99, nil, 98, + nil, nil, nil, nil, nil, nil, 58, nil, nil, nil, + 58, nil, nil, nil, nil, 61, nil, nil, nil, 70, + nil, nil, 61, 61, nil, nil, nil, nil, nil, 99, + nil, 61, nil, nil, nil, nil, nil, 58, nil, nil, + 58, 58, nil, nil, 58, 99, nil, nil, nil, 61, + 58, 58, nil, 61, nil, 58, 58, nil, 61, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 98, nil, nil, nil, 100, nil, nil, 61, + nil, nil, 100, 100, nil, 61, 61, nil, nil, 70, + nil, nil, nil, 70, nil, nil, nil, 70, 70, nil, + 61, 61, 61, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 98, nil, nil, nil, 70, nil, 99, nil, + nil, 61, nil, nil, nil, nil, 98, nil, 98, 70, + nil, nil, nil, nil, nil, 70, 70, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 70, 70, nil, 102, 102, nil, nil, 99, nil, + nil, nil, nil, nil, 98, nil, nil, nil, nil, 101, + nil, nil, 99, nil, 99, 101, 101, nil, nil, 58, + nil, nil, nil, nil, 58, 58, nil, nil, 98, nil, + nil, nil, nil, 61, nil, 58, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 99, nil, nil, 58, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 99, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 100, nil, nil, 100, + 100, 61, nil, nil, nil, nil, 100, nil, nil, nil, + nil, 61, nil, nil, 100, 100, 100, nil, nil, 58, + nil, nil, nil, nil, nil, nil, nil, 61, nil, nil, + nil, 58, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 70, nil, nil, nil, nil, nil, nil, nil, 70, + 58, nil, nil, nil, nil, nil, 58, nil, 70, nil, + nil, nil, 58, nil, nil, nil, nil, nil, 100, nil, + nil, 61, nil, nil, 61, nil, nil, nil, nil, 101, + nil, 61, 101, 101, nil, nil, nil, nil, nil, 101, + nil, 61, nil, nil, nil, 61, nil, 101, 101, 101, + 100, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 58, nil, 102, nil, nil, 100, nil, nil, 102, + 102, 70, 61, nil, 70, 61, 61, nil, nil, 61, + 58, nil, nil, nil, nil, 61, 61, nil, nil, nil, + 61, 61, nil, nil, nil, 70, nil, nil, 103, 103, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 101, nil, nil, nil, nil, nil, 58, 58, nil, + nil, nil, 70, nil, nil, 108, 108, nil, nil, 70, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 101, nil, nil, nil, nil, nil, 100, + nil, nil, nil, nil, nil, 36, nil, nil, 58, 101, + nil, nil, nil, nil, nil, 36, 36, 36, nil, nil, + nil, 58, nil, 58, 58, nil, nil, 36, 36, nil, + 36, 36, nil, 36, nil, nil, nil, nil, nil, 100, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 36, 36, nil, 100, 70, 100, 58, nil, nil, nil, + nil, nil, nil, nil, nil, 70, nil, 58, nil, nil, + nil, nil, nil, nil, 61, nil, nil, nil, nil, 61, + 61, nil, nil, 102, nil, nil, 102, 102, nil, nil, + 61, 100, 101, 102, nil, nil, nil, nil, nil, nil, + nil, 102, 102, 102, nil, nil, nil, nil, 61, nil, + nil, nil, nil, nil, nil, 100, nil, nil, nil, nil, + nil, nil, nil, nil, 70, nil, nil, nil, nil, 70, + nil, nil, 101, nil, nil, nil, nil, nil, nil, nil, + 70, nil, nil, nil, nil, nil, 101, nil, 101, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 61, 102, nil, 103, nil, nil, + nil, nil, nil, 103, 103, nil, 61, nil, nil, nil, + nil, nil, nil, nil, 101, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 108, nil, nil, 102, nil, nil, + 108, 108, 36, 36, nil, 61, 36, 36, 101, nil, + nil, 61, 36, 102, 70, nil, nil, 61, nil, nil, + nil, nil, nil, nil, nil, 36, 70, nil, nil, nil, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, nil, nil, nil, nil, 36, nil, nil, nil, + nil, 70, nil, nil, nil, nil, 61, 70, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 36, + 36, nil, nil, nil, nil, 61, nil, nil, 36, nil, + nil, nil, nil, nil, nil, 36, 102, 36, nil, nil, + 36, 36, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 70, nil, nil, nil, + nil, nil, 61, 61, nil, nil, nil, nil, nil, 70, + nil, nil, nil, nil, nil, 70, 102, 103, nil, 70, + 103, 103, 36, nil, 36, nil, nil, 103, nil, nil, + 102, nil, 102, nil, nil, 103, 103, 103, nil, nil, + nil, nil, nil, 61, 108, nil, nil, 108, 108, nil, + nil, nil, 70, 70, 108, nil, 61, nil, 61, 61, + nil, nil, 108, 108, 108, nil, nil, nil, 102, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 70, + nil, 61, 102, 70, nil, nil, nil, 36, nil, 103, + nil, nil, 61, nil, nil, nil, 70, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 108, nil, nil, nil, + nil, 103, nil, nil, nil, nil, nil, nil, nil, nil, + 36, nil, 36, 36, 36, nil, nil, 103, nil, nil, + nil, nil, 70, nil, nil, nil, nil, nil, 108, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 108, nil, nil, nil, 36, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 36, nil, + 36, nil, 36, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 36, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 36, nil, + nil, 36, nil, nil, nil, 36, nil, nil, nil, nil, + 103, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 36, nil, nil, nil, nil, nil, 108, nil, nil, + nil, nil, nil, nil, nil, 36, nil, nil, nil, nil, + 103, 36, nil, nil, 36, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 103, nil, 103, 36, 36, nil, + nil, nil, nil, nil, nil, nil, nil, 108, 36, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 108, nil, 108, nil, nil, nil, nil, nil, nil, + nil, nil, 103, nil, nil, nil, nil, nil, nil, nil, + nil, 36, 36, 36, nil, nil, nil, 36, nil, nil, + 36, 36, 36, 36, nil, nil, 103, 36, 36, 108, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 108, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 36, nil, nil, nil, + nil, nil, nil, nil, nil, 36, nil, nil, 36, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 36, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 36, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 36, nil, nil, + nil, nil, nil, nil, nil, 36, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 36, 36, + 36, 36, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 36, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 36, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 36, nil, + nil, nil, nil, nil, nil, nil, nil, 36, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 36, 36, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 36 ] + +racc_goto_pointer = [ + nil, 153, 135, 166, nil, 130, 140, 89, 90, 103, + -320, 20, -542, -707, -738, nil, -350, 34, 177, -44, + -79, 114, 16, 116, -137, -25, -2, 64, -119, 276, + 1036, -218, -282, -4, 1152, -14, 2983, -320, -43, -42, + -2, -410, -8, nil, -6, -18, nil, 29, 186, 19, + -295, -21, nil, nil, -184, 109, -197, -429, 1901, -300, + nil, 2256, 140, 88, 98, 972, nil, -34, 77, -287, + 2306, -2, -332, 80, -9, nil, 51, -214, 445, 2, + nil, 144, 43, 169, 716, 155, -20, 144, -285, 793, + -4, -217, -284, -286, -411, nil, 543, 729, 1528, 1574, + 1915, 2008, 2212, 2466, 203, 163, -61, nil, 2493, -330, + -770, -379, -612, 156, nil, -171, 34, nil, 48, 172, + -127, 181, -388, -573, -153, -799, -508, -453, -829, -686, + -790, -720, nil, -647, nil, -516, 110, 208, -755, -639, + -255, -771, -604, -590, nil, -683, -799, -920, -903, -133, + -548, 195, -359, -212, -21, -679, -679, -328, -2, nil, + -10, -8, nil, nil, -434, -765, -656, -901, -505, -815, + -645, -617, -575, -642, -707, nil, -556, nil, -554, -382, + -367, nil, nil, -602, -367, -362, nil, -325, -876, -949, + nil, -730, -728, nil, -73, nil, -489, nil, -521, nil, + -414, -569, nil, nil, 268, 272, 279, 280, -214, 246, + 280, 283, 289, -248, -248, nil, nil, -235, -136, -206, + nil, nil, 312, -609, -264, -728, -49, -367, -673, -679, + -946, nil, nil, -428 ] + +racc_goto_default = [ + nil, nil, nil, nil, 5, nil, 6, 389, 324, nil, + nil, 563, nil, 948, nil, 321, 322, nil, nil, nil, + 13, 14, 20, 239, nil, nil, 16, nil, 439, 240, + 353, nil, nil, 634, 238, 474, 23, 997, nil, nil, + nil, nil, nil, 384, 143, 52, 24, 53, nil, nil, + nil, 25, 26, 27, 757, nil, nil, nil, 341, nil, + 28, 338, 453, 35, nil, nil, 37, 40, 39, nil, + 235, 236, 401, nil, 461, 142, 87, nil, 444, 103, + 49, nil, 54, 273, 313, nil, 919, 454, nil, 455, + 466, nil, 683, 524, 311, 297, 55, 56, 57, 58, + 59, 60, 61, 62, 63, nil, 298, 69, 70, nil, + nil, nil, nil, nil, 77, nil, 616, 78, 363, nil, + nil, nil, nil, nil, nil, 782, 583, nil, 783, 784, + 571, 565, 566, 1143, 1013, nil, 572, nil, nil, nil, + 601, nil, 574, nil, 906, nil, nil, nil, 581, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 465, + nil, nil, 736, 728, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 882, nil, 696, 705, 697, 698, nil, + nil, 699, 700, nil, nil, nil, 881, 883, nil, 884, + 982, 983, 984, 985, nil, 989, 592, 990, 704, 706, + nil, nil, 86, 88, 89, nil, nil, nil, nil, 644, + nil, nil, nil, nil, nil, 99, 100, nil, 364, 926, + 367, 570, 769, 573, 938, 586, 588, 589, 1024, 593, + 1025, 596, 599, 316 ] + +racc_reduce_table = [ + 0, 0, :racc_error, + 0, 150, :_reduce_1, + 2, 148, :_reduce_2, + 2, 149, :_reduce_3, + 0, 151, :_reduce_4, + 1, 151, :_reduce_5, + 3, 151, :_reduce_6, + 2, 151, :_reduce_7, + 1, 153, :_reduce_none, + 2, 153, :_reduce_9, + 3, 156, :_reduce_10, + 4, 157, :_reduce_11, + 2, 158, :_reduce_12, + 0, 162, :_reduce_13, + 1, 162, :_reduce_14, + 3, 162, :_reduce_15, + 2, 162, :_reduce_16, + 1, 163, :_reduce_none, + 2, 163, :_reduce_18, + 0, 174, :_reduce_19, + 4, 155, :_reduce_20, + 3, 155, :_reduce_21, + 3, 155, :_reduce_22, + 3, 155, :_reduce_23, + 2, 155, :_reduce_24, + 3, 155, :_reduce_25, + 3, 155, :_reduce_26, + 3, 155, :_reduce_27, + 3, 155, :_reduce_28, + 3, 155, :_reduce_29, + 4, 155, :_reduce_30, + 1, 155, :_reduce_none, + 3, 155, :_reduce_32, + 3, 155, :_reduce_33, + 5, 155, :_reduce_34, + 3, 155, :_reduce_35, + 1, 155, :_reduce_none, + 3, 167, :_reduce_37, + 3, 167, :_reduce_38, + 6, 167, :_reduce_39, + 5, 167, :_reduce_40, + 5, 167, :_reduce_41, + 5, 167, :_reduce_42, + 5, 167, :_reduce_43, + 3, 167, :_reduce_44, + 1, 175, :_reduce_none, + 3, 175, :_reduce_46, + 1, 175, :_reduce_none, + 1, 173, :_reduce_none, + 3, 173, :_reduce_49, + 3, 173, :_reduce_50, + 3, 173, :_reduce_51, + 2, 173, :_reduce_52, + 0, 185, :_reduce_53, + 4, 173, :_reduce_54, + 0, 186, :_reduce_55, + 4, 173, :_reduce_56, + 1, 173, :_reduce_none, + 1, 166, :_reduce_none, + 0, 190, :_reduce_59, + 3, 187, :_reduce_60, + 1, 189, :_reduce_61, + 2, 192, :_reduce_62, + 0, 197, :_reduce_63, + 5, 194, :_reduce_64, + 1, 169, :_reduce_none, + 1, 169, :_reduce_none, + 1, 199, :_reduce_none, + 4, 199, :_reduce_68, + 0, 206, :_reduce_69, + 4, 203, :_reduce_70, + 1, 205, :_reduce_none, + 2, 198, :_reduce_72, + 3, 198, :_reduce_73, + 4, 198, :_reduce_74, + 5, 198, :_reduce_75, + 4, 198, :_reduce_76, + 5, 198, :_reduce_77, + 2, 198, :_reduce_78, + 2, 198, :_reduce_79, + 2, 198, :_reduce_80, + 2, 198, :_reduce_81, + 2, 198, :_reduce_82, + 1, 168, :_reduce_83, + 3, 168, :_reduce_84, + 1, 211, :_reduce_85, + 3, 211, :_reduce_86, + 1, 210, :_reduce_none, + 2, 210, :_reduce_88, + 3, 210, :_reduce_89, + 5, 210, :_reduce_90, + 2, 210, :_reduce_91, + 4, 210, :_reduce_92, + 2, 210, :_reduce_93, + 4, 210, :_reduce_94, + 1, 210, :_reduce_95, + 3, 210, :_reduce_96, + 1, 214, :_reduce_none, + 3, 214, :_reduce_98, + 2, 213, :_reduce_99, + 3, 213, :_reduce_100, + 1, 216, :_reduce_101, + 3, 216, :_reduce_102, + 1, 215, :_reduce_103, + 1, 215, :_reduce_104, + 4, 215, :_reduce_105, + 3, 215, :_reduce_106, + 3, 215, :_reduce_107, + 3, 215, :_reduce_108, + 3, 215, :_reduce_109, + 2, 215, :_reduce_110, + 1, 215, :_reduce_111, + 1, 170, :_reduce_112, + 1, 170, :_reduce_113, + 4, 170, :_reduce_114, + 3, 170, :_reduce_115, + 3, 170, :_reduce_116, + 3, 170, :_reduce_117, + 3, 170, :_reduce_118, + 2, 170, :_reduce_119, + 1, 170, :_reduce_120, + 1, 219, :_reduce_121, + 1, 219, :_reduce_none, + 2, 220, :_reduce_123, + 1, 220, :_reduce_124, + 3, 220, :_reduce_125, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 191, :_reduce_none, + 1, 164, :_reduce_131, + 1, 164, :_reduce_none, + 1, 165, :_reduce_133, + 0, 224, :_reduce_134, + 4, 165, :_reduce_135, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 221, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 3, 183, :_reduce_207, + 3, 183, :_reduce_208, + 6, 183, :_reduce_209, + 5, 183, :_reduce_210, + 5, 183, :_reduce_211, + 5, 183, :_reduce_212, + 5, 183, :_reduce_213, + 4, 183, :_reduce_214, + 3, 183, :_reduce_215, + 3, 183, :_reduce_216, + 3, 183, :_reduce_217, + 2, 183, :_reduce_218, + 2, 183, :_reduce_219, + 2, 183, :_reduce_220, + 2, 183, :_reduce_221, + 3, 183, :_reduce_222, + 3, 183, :_reduce_223, + 3, 183, :_reduce_224, + 3, 183, :_reduce_225, + 3, 183, :_reduce_226, + 3, 183, :_reduce_227, + 4, 183, :_reduce_228, + 2, 183, :_reduce_229, + 2, 183, :_reduce_230, + 3, 183, :_reduce_231, + 3, 183, :_reduce_232, + 3, 183, :_reduce_233, + 3, 183, :_reduce_234, + 1, 183, :_reduce_none, + 3, 183, :_reduce_236, + 3, 183, :_reduce_237, + 3, 183, :_reduce_238, + 3, 183, :_reduce_239, + 3, 183, :_reduce_240, + 2, 183, :_reduce_241, + 2, 183, :_reduce_242, + 3, 183, :_reduce_243, + 3, 183, :_reduce_244, + 3, 183, :_reduce_245, + 3, 183, :_reduce_246, + 3, 183, :_reduce_247, + 6, 183, :_reduce_248, + 4, 183, :_reduce_249, + 6, 183, :_reduce_250, + 4, 183, :_reduce_251, + 6, 183, :_reduce_252, + 1, 183, :_reduce_none, + 1, 230, :_reduce_none, + 1, 230, :_reduce_none, + 1, 230, :_reduce_none, + 1, 230, :_reduce_none, + 3, 227, :_reduce_258, + 3, 227, :_reduce_259, + 1, 231, :_reduce_none, + 1, 232, :_reduce_none, + 2, 232, :_reduce_none, + 4, 232, :_reduce_263, + 2, 232, :_reduce_264, + 1, 225, :_reduce_none, + 3, 225, :_reduce_266, + 3, 237, :_reduce_267, + 5, 237, :_reduce_268, + 3, 237, :_reduce_269, + 0, 239, :_reduce_270, + 1, 239, :_reduce_none, + 0, 178, :_reduce_272, + 1, 178, :_reduce_none, + 2, 178, :_reduce_none, + 4, 178, :_reduce_275, + 2, 178, :_reduce_276, + 1, 209, :_reduce_277, + 2, 209, :_reduce_278, + 2, 209, :_reduce_279, + 4, 209, :_reduce_280, + 1, 209, :_reduce_281, + 0, 242, :_reduce_282, + 2, 202, :_reduce_283, + 2, 241, :_reduce_284, + 2, 240, :_reduce_285, + 0, 240, :_reduce_286, + 1, 234, :_reduce_287, + 2, 234, :_reduce_288, + 3, 234, :_reduce_289, + 4, 234, :_reduce_290, + 1, 172, :_reduce_291, + 1, 172, :_reduce_none, + 3, 171, :_reduce_293, + 4, 171, :_reduce_294, + 2, 171, :_reduce_295, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_306, + 0, 266, :_reduce_307, + 4, 229, :_reduce_308, + 0, 267, :_reduce_309, + 4, 229, :_reduce_310, + 0, 268, :_reduce_311, + 4, 229, :_reduce_312, + 3, 229, :_reduce_313, + 3, 229, :_reduce_314, + 2, 229, :_reduce_315, + 3, 229, :_reduce_316, + 3, 229, :_reduce_317, + 1, 229, :_reduce_318, + 4, 229, :_reduce_319, + 3, 229, :_reduce_320, + 1, 229, :_reduce_321, + 5, 229, :_reduce_322, + 4, 229, :_reduce_323, + 3, 229, :_reduce_324, + 2, 229, :_reduce_325, + 1, 229, :_reduce_none, + 2, 229, :_reduce_327, + 1, 229, :_reduce_none, + 6, 229, :_reduce_329, + 6, 229, :_reduce_330, + 4, 229, :_reduce_331, + 4, 229, :_reduce_332, + 5, 229, :_reduce_333, + 4, 229, :_reduce_334, + 5, 229, :_reduce_335, + 6, 229, :_reduce_336, + 0, 269, :_reduce_337, + 6, 229, :_reduce_338, + 0, 270, :_reduce_339, + 7, 229, :_reduce_340, + 0, 271, :_reduce_341, + 5, 229, :_reduce_342, + 4, 229, :_reduce_343, + 4, 229, :_reduce_344, + 1, 229, :_reduce_345, + 1, 229, :_reduce_346, + 1, 229, :_reduce_347, + 1, 229, :_reduce_348, + 1, 177, :_reduce_none, + 1, 261, :_reduce_350, + 1, 264, :_reduce_351, + 1, 193, :_reduce_352, + 1, 208, :_reduce_353, + 1, 256, :_reduce_none, + 1, 256, :_reduce_none, + 2, 256, :_reduce_356, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 257, :_reduce_none, + 5, 257, :_reduce_360, + 1, 160, :_reduce_none, + 2, 160, :_reduce_362, + 1, 260, :_reduce_none, + 1, 260, :_reduce_none, + 1, 272, :_reduce_365, + 3, 272, :_reduce_366, + 1, 275, :_reduce_367, + 3, 275, :_reduce_368, + 1, 274, :_reduce_none, + 3, 274, :_reduce_370, + 5, 274, :_reduce_371, + 1, 274, :_reduce_372, + 3, 274, :_reduce_373, + 2, 276, :_reduce_374, + 1, 276, :_reduce_375, + 1, 277, :_reduce_none, + 1, 277, :_reduce_none, + 4, 280, :_reduce_378, + 2, 280, :_reduce_379, + 2, 280, :_reduce_380, + 1, 280, :_reduce_381, + 2, 284, :_reduce_382, + 0, 284, :_reduce_383, + 1, 285, :_reduce_none, + 6, 286, :_reduce_385, + 8, 286, :_reduce_386, + 4, 286, :_reduce_387, + 6, 286, :_reduce_388, + 4, 286, :_reduce_389, + 2, 286, :_reduce_none, + 6, 286, :_reduce_391, + 2, 286, :_reduce_392, + 4, 286, :_reduce_393, + 6, 286, :_reduce_394, + 2, 286, :_reduce_395, + 4, 286, :_reduce_396, + 2, 286, :_reduce_397, + 4, 286, :_reduce_398, + 1, 286, :_reduce_none, + 0, 290, :_reduce_400, + 1, 290, :_reduce_401, + 3, 291, :_reduce_402, + 4, 291, :_reduce_403, + 1, 292, :_reduce_404, + 4, 292, :_reduce_405, + 1, 293, :_reduce_406, + 3, 293, :_reduce_407, + 1, 294, :_reduce_408, + 1, 294, :_reduce_none, + 0, 298, :_reduce_410, + 0, 299, :_reduce_411, + 5, 255, :_reduce_412, + 4, 296, :_reduce_413, + 1, 296, :_reduce_414, + 0, 302, :_reduce_415, + 4, 297, :_reduce_416, + 0, 303, :_reduce_417, + 4, 297, :_reduce_418, + 0, 305, :_reduce_419, + 4, 301, :_reduce_420, + 2, 200, :_reduce_421, + 4, 200, :_reduce_422, + 5, 200, :_reduce_423, + 5, 200, :_reduce_424, + 2, 254, :_reduce_425, + 4, 254, :_reduce_426, + 4, 254, :_reduce_427, + 3, 254, :_reduce_428, + 3, 254, :_reduce_429, + 3, 254, :_reduce_430, + 2, 254, :_reduce_431, + 1, 254, :_reduce_432, + 4, 254, :_reduce_433, + 0, 307, :_reduce_434, + 4, 253, :_reduce_435, + 0, 308, :_reduce_436, + 4, 253, :_reduce_437, + 0, 309, :_reduce_438, + 3, 204, :_reduce_439, + 0, 310, :_reduce_440, + 0, 311, :_reduce_441, + 4, 304, :_reduce_442, + 5, 258, :_reduce_443, + 1, 312, :_reduce_444, + 1, 312, :_reduce_none, + 0, 315, :_reduce_446, + 0, 316, :_reduce_447, + 7, 259, :_reduce_448, + 1, 314, :_reduce_449, + 1, 314, :_reduce_none, + 1, 313, :_reduce_451, + 3, 313, :_reduce_452, + 3, 313, :_reduce_453, + 1, 317, :_reduce_none, + 2, 317, :_reduce_455, + 3, 317, :_reduce_456, + 1, 317, :_reduce_457, + 1, 317, :_reduce_458, + 1, 317, :_reduce_459, + 1, 184, :_reduce_none, + 3, 322, :_reduce_461, + 1, 322, :_reduce_none, + 3, 324, :_reduce_463, + 1, 324, :_reduce_none, + 1, 326, :_reduce_465, + 1, 327, :_reduce_466, + 1, 325, :_reduce_none, + 4, 325, :_reduce_468, + 4, 325, :_reduce_469, + 4, 325, :_reduce_470, + 3, 325, :_reduce_471, + 4, 325, :_reduce_472, + 4, 325, :_reduce_473, + 4, 325, :_reduce_474, + 3, 325, :_reduce_475, + 3, 325, :_reduce_476, + 3, 325, :_reduce_477, + 2, 325, :_reduce_478, + 0, 331, :_reduce_479, + 4, 325, :_reduce_480, + 2, 325, :_reduce_481, + 0, 332, :_reduce_482, + 4, 325, :_reduce_483, + 1, 318, :_reduce_484, + 1, 318, :_reduce_485, + 2, 318, :_reduce_486, + 3, 318, :_reduce_487, + 5, 318, :_reduce_488, + 2, 318, :_reduce_489, + 4, 318, :_reduce_490, + 1, 318, :_reduce_none, + 2, 333, :_reduce_492, + 3, 333, :_reduce_493, + 1, 320, :_reduce_494, + 3, 320, :_reduce_495, + 5, 319, :_reduce_496, + 2, 336, :_reduce_497, + 1, 336, :_reduce_498, + 1, 335, :_reduce_499, + 3, 335, :_reduce_500, + 1, 334, :_reduce_none, + 3, 321, :_reduce_502, + 1, 321, :_reduce_503, + 2, 321, :_reduce_504, + 1, 321, :_reduce_505, + 1, 337, :_reduce_506, + 3, 337, :_reduce_507, + 2, 339, :_reduce_508, + 1, 339, :_reduce_509, + 1, 340, :_reduce_510, + 3, 340, :_reduce_511, + 2, 342, :_reduce_512, + 1, 342, :_reduce_513, + 2, 344, :_reduce_514, + 1, 338, :_reduce_none, + 1, 338, :_reduce_none, + 1, 328, :_reduce_none, + 3, 328, :_reduce_518, + 3, 328, :_reduce_519, + 2, 328, :_reduce_520, + 2, 328, :_reduce_521, + 1, 328, :_reduce_none, + 1, 328, :_reduce_none, + 1, 328, :_reduce_none, + 2, 328, :_reduce_525, + 2, 328, :_reduce_526, + 1, 345, :_reduce_none, + 1, 345, :_reduce_none, + 1, 345, :_reduce_none, + 1, 345, :_reduce_none, + 1, 345, :_reduce_none, + 1, 345, :_reduce_none, + 1, 345, :_reduce_none, + 1, 345, :_reduce_none, + 1, 345, :_reduce_535, + 1, 345, :_reduce_none, + 1, 323, :_reduce_537, + 2, 346, :_reduce_538, + 2, 329, :_reduce_539, + 3, 329, :_reduce_540, + 1, 329, :_reduce_541, + 6, 159, :_reduce_542, + 0, 159, :_reduce_543, + 1, 347, :_reduce_544, + 1, 347, :_reduce_none, + 1, 347, :_reduce_none, + 2, 348, :_reduce_547, + 1, 348, :_reduce_none, + 2, 161, :_reduce_549, + 1, 161, :_reduce_none, + 1, 243, :_reduce_none, + 1, 243, :_reduce_none, + 1, 244, :_reduce_553, + 1, 350, :_reduce_554, + 2, 350, :_reduce_555, + 3, 351, :_reduce_556, + 1, 351, :_reduce_557, + 1, 351, :_reduce_558, + 3, 245, :_reduce_559, + 4, 246, :_reduce_560, + 3, 247, :_reduce_561, + 0, 354, :_reduce_562, + 3, 354, :_reduce_563, + 1, 355, :_reduce_564, + 2, 355, :_reduce_565, + 3, 249, :_reduce_566, + 0, 357, :_reduce_567, + 3, 357, :_reduce_568, + 3, 248, :_reduce_569, + 3, 250, :_reduce_570, + 0, 358, :_reduce_571, + 3, 358, :_reduce_572, + 0, 359, :_reduce_573, + 3, 359, :_reduce_574, + 0, 341, :_reduce_575, + 2, 341, :_reduce_576, + 0, 352, :_reduce_577, + 2, 352, :_reduce_578, + 0, 353, :_reduce_579, + 2, 353, :_reduce_580, + 1, 356, :_reduce_581, + 2, 356, :_reduce_582, + 0, 361, :_reduce_583, + 4, 356, :_reduce_584, + 1, 360, :_reduce_585, + 1, 360, :_reduce_586, + 1, 360, :_reduce_587, + 1, 360, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 362, :_reduce_591, + 3, 363, :_reduce_592, + 1, 349, :_reduce_593, + 2, 349, :_reduce_594, + 1, 226, :_reduce_595, + 1, 226, :_reduce_596, + 1, 226, :_reduce_597, + 1, 226, :_reduce_598, + 1, 217, :_reduce_599, + 1, 217, :_reduce_600, + 1, 217, :_reduce_601, + 1, 217, :_reduce_602, + 1, 217, :_reduce_603, + 1, 218, :_reduce_604, + 1, 218, :_reduce_605, + 1, 218, :_reduce_606, + 1, 218, :_reduce_607, + 1, 218, :_reduce_608, + 1, 218, :_reduce_609, + 1, 218, :_reduce_610, + 1, 251, :_reduce_611, + 1, 251, :_reduce_612, + 1, 176, :_reduce_613, + 1, 176, :_reduce_614, + 1, 181, :_reduce_615, + 1, 181, :_reduce_616, + 0, 364, :_reduce_617, + 4, 262, :_reduce_618, + 0, 262, :_reduce_619, + 1, 228, :_reduce_none, + 1, 228, :_reduce_621, + 3, 365, :_reduce_622, + 5, 365, :_reduce_623, + 3, 365, :_reduce_624, + 1, 265, :_reduce_none, + 0, 367, :_reduce_626, + 3, 265, :_reduce_627, + 4, 366, :_reduce_628, + 2, 366, :_reduce_629, + 2, 366, :_reduce_630, + 1, 366, :_reduce_631, + 2, 369, :_reduce_632, + 0, 369, :_reduce_633, + 6, 300, :_reduce_634, + 8, 300, :_reduce_635, + 4, 300, :_reduce_636, + 6, 300, :_reduce_637, + 4, 300, :_reduce_638, + 6, 300, :_reduce_639, + 2, 300, :_reduce_640, + 4, 300, :_reduce_641, + 6, 300, :_reduce_642, + 2, 300, :_reduce_643, + 4, 300, :_reduce_644, + 2, 300, :_reduce_645, + 4, 300, :_reduce_646, + 1, 300, :_reduce_647, + 0, 300, :_reduce_648, + 1, 238, :_reduce_649, + 1, 295, :_reduce_650, + 1, 295, :_reduce_651, + 1, 295, :_reduce_652, + 1, 295, :_reduce_653, + 1, 273, :_reduce_none, + 1, 273, :_reduce_655, + 1, 371, :_reduce_656, + 1, 372, :_reduce_657, + 3, 372, :_reduce_658, + 1, 287, :_reduce_659, + 3, 287, :_reduce_660, + 1, 373, :_reduce_661, + 2, 374, :_reduce_662, + 1, 374, :_reduce_663, + 2, 375, :_reduce_664, + 1, 375, :_reduce_665, + 1, 281, :_reduce_666, + 3, 281, :_reduce_667, + 1, 368, :_reduce_668, + 3, 368, :_reduce_669, + 1, 343, :_reduce_none, + 1, 343, :_reduce_none, + 2, 279, :_reduce_672, + 2, 278, :_reduce_673, + 1, 278, :_reduce_674, + 3, 376, :_reduce_675, + 3, 377, :_reduce_676, + 1, 288, :_reduce_677, + 3, 288, :_reduce_678, + 1, 370, :_reduce_679, + 3, 370, :_reduce_680, + 1, 378, :_reduce_none, + 1, 378, :_reduce_none, + 2, 289, :_reduce_683, + 1, 289, :_reduce_684, + 1, 379, :_reduce_none, + 1, 379, :_reduce_none, + 2, 283, :_reduce_687, + 2, 282, :_reduce_688, + 0, 282, :_reduce_689, + 1, 195, :_reduce_none, + 3, 195, :_reduce_691, + 0, 252, :_reduce_692, + 2, 252, :_reduce_none, + 1, 236, :_reduce_694, + 3, 236, :_reduce_695, + 3, 380, :_reduce_696, + 2, 380, :_reduce_697, + 4, 380, :_reduce_698, + 2, 380, :_reduce_699, + 1, 207, :_reduce_none, + 1, 207, :_reduce_none, + 1, 207, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 201, :_reduce_none, + 1, 306, :_reduce_none, + 1, 306, :_reduce_none, + 1, 306, :_reduce_none, + 1, 196, :_reduce_none, + 1, 196, :_reduce_none, + 1, 180, :_reduce_712, + 1, 180, :_reduce_713, + 0, 152, :_reduce_none, + 1, 152, :_reduce_none, + 0, 182, :_reduce_none, + 1, 182, :_reduce_none, + 2, 212, :_reduce_718, + 2, 179, :_reduce_719, + 2, 330, :_reduce_720, + 0, 235, :_reduce_none, + 1, 235, :_reduce_none, + 1, 235, :_reduce_none, + 1, 263, :_reduce_724, + 1, 263, :_reduce_none, + 1, 154, :_reduce_none, + 2, 154, :_reduce_none, + 0, 233, :_reduce_728 ] + +racc_reduce_n = 729 + +racc_shift_n = 1219 + +racc_token_table = { + false => 0, + :error => 1, + :kCLASS => 2, + :kMODULE => 3, + :kDEF => 4, + :kUNDEF => 5, + :kBEGIN => 6, + :kRESCUE => 7, + :kENSURE => 8, + :kEND => 9, + :kIF => 10, + :kUNLESS => 11, + :kTHEN => 12, + :kELSIF => 13, + :kELSE => 14, + :kCASE => 15, + :kWHEN => 16, + :kWHILE => 17, + :kUNTIL => 18, + :kFOR => 19, + :kBREAK => 20, + :kNEXT => 21, + :kREDO => 22, + :kRETRY => 23, + :kIN => 24, + :kDO => 25, + :kDO_COND => 26, + :kDO_BLOCK => 27, + :kDO_LAMBDA => 28, + :kRETURN => 29, + :kYIELD => 30, + :kSUPER => 31, + :kSELF => 32, + :kNIL => 33, + :kTRUE => 34, + :kFALSE => 35, + :kAND => 36, + :kOR => 37, + :kNOT => 38, + :kIF_MOD => 39, + :kUNLESS_MOD => 40, + :kWHILE_MOD => 41, + :kUNTIL_MOD => 42, + :kRESCUE_MOD => 43, + :kALIAS => 44, + :kDEFINED => 45, + :klBEGIN => 46, + :klEND => 47, + :k__LINE__ => 48, + :k__FILE__ => 49, + :k__ENCODING__ => 50, + :tIDENTIFIER => 51, + :tFID => 52, + :tGVAR => 53, + :tIVAR => 54, + :tCONSTANT => 55, + :tLABEL => 56, + :tCVAR => 57, + :tNTH_REF => 58, + :tBACK_REF => 59, + :tSTRING_CONTENT => 60, + :tINTEGER => 61, + :tFLOAT => 62, + :tUPLUS => 63, + :tUMINUS => 64, + :tUNARY_NUM => 65, + :tPOW => 66, + :tCMP => 67, + :tEQ => 68, + :tEQQ => 69, + :tNEQ => 70, + :tGEQ => 71, + :tLEQ => 72, + :tANDOP => 73, + :tOROP => 74, + :tMATCH => 75, + :tNMATCH => 76, + :tDOT => 77, + :tDOT2 => 78, + :tDOT3 => 79, + :tAREF => 80, + :tASET => 81, + :tLSHFT => 82, + :tRSHFT => 83, + :tCOLON2 => 84, + :tCOLON3 => 85, + :tOP_ASGN => 86, + :tASSOC => 87, + :tLPAREN => 88, + :tLPAREN2 => 89, + :tRPAREN => 90, + :tLPAREN_ARG => 91, + :tLBRACK => 92, + :tLBRACK2 => 93, + :tRBRACK => 94, + :tLBRACE => 95, + :tLBRACE_ARG => 96, + :tSTAR => 97, + :tSTAR2 => 98, + :tAMPER => 99, + :tAMPER2 => 100, + :tTILDE => 101, + :tPERCENT => 102, + :tDIVIDE => 103, + :tDSTAR => 104, + :tPLUS => 105, + :tMINUS => 106, + :tLT => 107, + :tGT => 108, + :tPIPE => 109, + :tBANG => 110, + :tCARET => 111, + :tLCURLY => 112, + :tRCURLY => 113, + :tBACK_REF2 => 114, + :tSYMBEG => 115, + :tSTRING_BEG => 116, + :tXSTRING_BEG => 117, + :tREGEXP_BEG => 118, + :tREGEXP_OPT => 119, + :tWORDS_BEG => 120, + :tQWORDS_BEG => 121, + :tSYMBOLS_BEG => 122, + :tQSYMBOLS_BEG => 123, + :tSTRING_DBEG => 124, + :tSTRING_DVAR => 125, + :tSTRING_END => 126, + :tSTRING_DEND => 127, + :tSTRING => 128, + :tSYMBOL => 129, + :tNL => 130, + :tEH => 131, + :tCOLON => 132, + :tCOMMA => 133, + :tSPACE => 134, + :tSEMI => 135, + :tLAMBDA => 136, + :tLAMBEG => 137, + :tCHARACTER => 138, + :tRATIONAL => 139, + :tIMAGINARY => 140, + :tLABEL_END => 141, + :tANDDOT => 142, + :tBDOT2 => 143, + :tBDOT3 => 144, + :tEQL => 145, + :tLOWEST => 146 } + +racc_nt_base = 147 + +racc_use_result_var = true + +Racc_arg = [ + racc_action_table, + racc_action_check, + racc_action_default, + racc_action_pointer, + racc_goto_table, + racc_goto_check, + racc_goto_default, + racc_goto_pointer, + racc_nt_base, + racc_reduce_table, + racc_token_table, + racc_shift_n, + racc_reduce_n, + racc_use_result_var ] +Ractor.make_shareable(Racc_arg) if defined?(Ractor) + +Racc_token_to_s_table = [ + "$end", + "error", + "kCLASS", + "kMODULE", + "kDEF", + "kUNDEF", + "kBEGIN", + "kRESCUE", + "kENSURE", + "kEND", + "kIF", + "kUNLESS", + "kTHEN", + "kELSIF", + "kELSE", + "kCASE", + "kWHEN", + "kWHILE", + "kUNTIL", + "kFOR", + "kBREAK", + "kNEXT", + "kREDO", + "kRETRY", + "kIN", + "kDO", + "kDO_COND", + "kDO_BLOCK", + "kDO_LAMBDA", + "kRETURN", + "kYIELD", + "kSUPER", + "kSELF", + "kNIL", + "kTRUE", + "kFALSE", + "kAND", + "kOR", + "kNOT", + "kIF_MOD", + "kUNLESS_MOD", + "kWHILE_MOD", + "kUNTIL_MOD", + "kRESCUE_MOD", + "kALIAS", + "kDEFINED", + "klBEGIN", + "klEND", + "k__LINE__", + "k__FILE__", + "k__ENCODING__", + "tIDENTIFIER", + "tFID", + "tGVAR", + "tIVAR", + "tCONSTANT", + "tLABEL", + "tCVAR", + "tNTH_REF", + "tBACK_REF", + "tSTRING_CONTENT", + "tINTEGER", + "tFLOAT", + "tUPLUS", + "tUMINUS", + "tUNARY_NUM", + "tPOW", + "tCMP", + "tEQ", + "tEQQ", + "tNEQ", + "tGEQ", + "tLEQ", + "tANDOP", + "tOROP", + "tMATCH", + "tNMATCH", + "tDOT", + "tDOT2", + "tDOT3", + "tAREF", + "tASET", + "tLSHFT", + "tRSHFT", + "tCOLON2", + "tCOLON3", + "tOP_ASGN", + "tASSOC", + "tLPAREN", + "tLPAREN2", + "tRPAREN", + "tLPAREN_ARG", + "tLBRACK", + "tLBRACK2", + "tRBRACK", + "tLBRACE", + "tLBRACE_ARG", + "tSTAR", + "tSTAR2", + "tAMPER", + "tAMPER2", + "tTILDE", + "tPERCENT", + "tDIVIDE", + "tDSTAR", + "tPLUS", + "tMINUS", + "tLT", + "tGT", + "tPIPE", + "tBANG", + "tCARET", + "tLCURLY", + "tRCURLY", + "tBACK_REF2", + "tSYMBEG", + "tSTRING_BEG", + "tXSTRING_BEG", + "tREGEXP_BEG", + "tREGEXP_OPT", + "tWORDS_BEG", + "tQWORDS_BEG", + "tSYMBOLS_BEG", + "tQSYMBOLS_BEG", + "tSTRING_DBEG", + "tSTRING_DVAR", + "tSTRING_END", + "tSTRING_DEND", + "tSTRING", + "tSYMBOL", + "tNL", + "tEH", + "tCOLON", + "tCOMMA", + "tSPACE", + "tSEMI", + "tLAMBDA", + "tLAMBEG", + "tCHARACTER", + "tRATIONAL", + "tIMAGINARY", + "tLABEL_END", + "tANDDOT", + "tBDOT2", + "tBDOT3", + "tEQL", + "tLOWEST", + "$start", + "program", + "top_compstmt", + "@1", + "top_stmts", + "opt_terms", + "top_stmt", + "terms", + "stmt", + "begin_block", + "bodystmt", + "compstmt", + "opt_rescue", + "opt_else", + "opt_ensure", + "stmts", + "stmt_or_begin", + "fitem", + "undef_list", + "expr_value", + "command_asgn", + "mlhs", + "command_call", + "lhs", + "mrhs", + "mrhs_arg", + "expr", + "@2", + "command_rhs", + "var_lhs", + "primary_value", + "opt_call_args", + "rbracket", + "call_op", + "backref", + "opt_nl", + "arg", + "p_expr", + "@3", + "@4", + "expr_value_do", + "do", + "def_name", + "@5", + "fname", + "defn_head", + "k_def", + "defs_head", + "singleton", + "dot_or_colon", + "@6", + "command", + "block_command", + "block_call", + "operation2", + "command_args", + "cmd_brace_block", + "brace_body", + "fcall", + "@7", + "operation", + "k_return", + "call_args", + "mlhs_basic", + "mlhs_inner", + "rparen", + "mlhs_head", + "mlhs_item", + "mlhs_node", + "mlhs_post", + "user_variable", + "keyword_variable", + "cname", + "cpath", + "op", + "reswords", + "symbol", + "@8", + "arg_rhs", + "simple_numeric", + "rel_expr", + "f_opt_paren_args", + "primary", + "relop", + "arg_value", + "aref_args", + "none", + "args", + "trailer", + "assocs", + "paren_args", + "args_forward", + "opt_paren_args", + "opt_block_arg", + "block_arg", + "@9", + "literal", + "strings", + "xstring", + "regexp", + "words", + "qwords", + "symbols", + "qsymbols", + "var_ref", + "assoc_list", + "brace_block", + "method_call", + "lambda", + "then", + "if_tail", + "case_body", + "p_case_body", + "for_var", + "k_class", + "superclass", + "term", + "k_module", + "f_arglist", + "@10", + "@11", + "@12", + "@13", + "@14", + "@15", + "f_marg", + "f_norm_arg", + "f_margs", + "f_marg_list", + "f_rest_marg", + "f_any_kwrest", + "f_kwrest", + "f_no_kwarg", + "block_args_tail", + "f_block_kwarg", + "opt_f_block_arg", + "f_block_arg", + "opt_block_args_tail", + "excessed_comma", + "block_param", + "f_arg", + "f_block_optarg", + "f_rest_arg", + "opt_block_param", + "block_param_def", + "opt_bv_decl", + "bv_decls", + "bvar", + "f_bad_arg", + "f_larglist", + "lambda_body", + "@16", + "@17", + "f_args", + "do_block", + "@18", + "@19", + "do_body", + "@20", + "operation3", + "@21", + "@22", + "@23", + "@24", + "@25", + "cases", + "p_top_expr", + "p_cases", + "@26", + "@27", + "p_top_expr_body", + "p_args", + "p_find", + "p_args_tail", + "p_kwargs", + "p_as", + "p_variable", + "p_alt", + "p_expr_basic", + "p_lparen", + "p_lbracket", + "p_value", + "p_const", + "rbrace", + "@28", + "@29", + "p_args_head", + "p_arg", + "p_args_post", + "p_rest", + "p_kwarg", + "p_any_kwrest", + "p_kw", + "p_kw_label", + "string_contents", + "p_kwrest", + "kwrest_mark", + "p_kwnorest", + "p_primitive", + "p_var_ref", + "exc_list", + "exc_var", + "numeric", + "string", + "string1", + "xstring_contents", + "regexp_contents", + "word_list", + "word", + "string_content", + "symbol_list", + "qword_list", + "qsym_list", + "string_dvar", + "@30", + "ssym", + "dsym", + "@31", + "f_paren_args", + "args_tail", + "@32", + "f_kwarg", + "opt_args_tail", + "f_optarg", + "f_arg_asgn", + "f_arg_item", + "f_label", + "f_kw", + "f_block_kw", + "f_opt", + "f_block_opt", + "restarg_mark", + "blkarg_mark", + "assoc" ] +Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) + +Racc_debug_parser = false + +##### State transition tables end ##### + +# reduce 0 omitted + +def _reduce_1(val, _values, result) + @current_arg_stack.push(nil) + @max_numparam_stack.push(static: true) + + result +end + +def _reduce_2(val, _values, result) + result = val[1] + + @current_arg_stack.pop + @max_numparam_stack.pop + + result +end + +def _reduce_3(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_4(val, _values, result) + result = [] + + result +end + +def _reduce_5(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_6(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_7(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 8 omitted + +def _reduce_9(val, _values, result) + result = @builder.preexe(val[0], *val[1]) + + result +end + +def _reduce_10(val, _values, result) + result = val + + result +end + +def _reduce_11(val, _values, result) + rescue_bodies = val[1] + else_t, else_ = val[2] + ensure_t, ensure_ = val[3] + + if rescue_bodies.empty? && !else_t.nil? + diagnostic :error, :useless_else, nil, else_t + end + + result = @builder.begin_body(val[0], + rescue_bodies, + else_t, else_, + ensure_t, ensure_) + + result +end + +def _reduce_12(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_13(val, _values, result) + result = [] + + result +end + +def _reduce_14(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_15(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_16(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 17 omitted + +def _reduce_18(val, _values, result) + diagnostic :error, :begin_in_method, nil, val[0] + + result +end + +def _reduce_19(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_20(val, _values, result) + result = @builder.alias(val[0], val[1], val[3]) + + result +end + +def _reduce_21(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.gvar(val[2])) + + result +end + +def _reduce_22(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.back_ref(val[2])) + + result +end + +def _reduce_23(val, _values, result) + diagnostic :error, :nth_ref_alias, nil, val[2] + + result +end + +def _reduce_24(val, _values, result) + result = @builder.undef_method(val[0], val[1]) + + result +end + +def _reduce_25(val, _values, result) + result = @builder.condition_mod(val[0], nil, + val[1], val[2]) + + result +end + +def _reduce_26(val, _values, result) + result = @builder.condition_mod(nil, val[0], + val[1], val[2]) + + result +end + +def _reduce_27(val, _values, result) + result = @builder.loop_mod(:while, val[0], val[1], val[2]) + + result +end + +def _reduce_28(val, _values, result) + result = @builder.loop_mod(:until, val[0], val[1], val[2]) + + result +end + +def _reduce_29(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_30(val, _values, result) + result = @builder.postexe(val[0], val[1], val[2], val[3]) + + result +end + +# reduce 31 omitted + +def _reduce_32(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_33(val, _values, result) + result = @builder.assign(val[0], val[1], + @builder.array(nil, val[2], nil)) + + result +end + +def _reduce_34(val, _values, result) + rescue_body = @builder.rescue_body(val[3], + nil, nil, nil, + nil, val[4]) + begin_body = @builder.begin_body(val[2], [ rescue_body ]) + + result = @builder.multi_assign(val[0], val[1], begin_body) + + result +end + +def _reduce_35(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +# reduce 36 omitted + +def _reduce_37(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_38(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_39(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_40(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_41(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_42(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_43(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_44(val, _values, result) + @builder.op_assign(val[0], val[1], val[2]) + + result +end + +# reduce 45 omitted + +def _reduce_46(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +# reduce 47 omitted + +# reduce 48 omitted + +def _reduce_49(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_50(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_51(val, _values, result) + result = @builder.not_op(val[0], nil, val[2], nil) + + result +end + +def _reduce_52(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +def _reduce_53(val, _values, result) + @lexer.state = :expr_beg + @lexer.command_start = false + @pattern_variables.push + + result = @context.in_kwarg + @context.in_kwarg = true + + result +end + +def _reduce_54(val, _values, result) + @pattern_variables.pop + @context.in_kwarg = val[2] + result = @builder.match_pattern(val[0], val[1], val[3]) + + result +end + +def _reduce_55(val, _values, result) + @lexer.state = :expr_beg + @lexer.command_start = false + @pattern_variables.push + + result = @context.in_kwarg + @context.in_kwarg = true + + result +end + +def _reduce_56(val, _values, result) + @pattern_variables.pop + @context.in_kwarg = val[2] + result = @builder.match_pattern_p(val[0], val[1], val[3]) + + result +end + +# reduce 57 omitted + +# reduce 58 omitted + +def _reduce_59(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_60(val, _values, result) + @lexer.cond.pop + result = [ val[1], val[2] ] + + result +end + +def _reduce_61(val, _values, result) + local_push + @current_arg_stack.push(nil) + + result = [ val[0], @context.dup ] + @context.in_def = true + + result +end + +def _reduce_62(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +def _reduce_63(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_64(val, _values, result) + result = [ val[0], val[1], val[2], val[4] ] + + result +end + +# reduce 65 omitted + +# reduce 66 omitted + +# reduce 67 omitted + +def _reduce_68(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_69(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_70(val, _values, result) + result = [ val[0], *val[2], val[3] ] + @context.in_block = val[1].in_block + + result +end + +# reduce 71 omitted + +def _reduce_72(val, _values, result) + result = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + result +end + +def _reduce_73(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + begin_t, args, body, end_t = val[2] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_74(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_75(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_76(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_77(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_78(val, _values, result) + result = @builder.keyword_cmd(:super, val[0], + nil, val[1], nil) + + result +end + +def _reduce_79(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], + nil, val[1], nil) + + result +end + +def _reduce_80(val, _values, result) + result = @builder.keyword_cmd(:return, val[0], + nil, val[1], nil) + + result +end + +def _reduce_81(val, _values, result) + result = @builder.keyword_cmd(:break, val[0], + nil, val[1], nil) + + result +end + +def _reduce_82(val, _values, result) + result = @builder.keyword_cmd(:next, val[0], + nil, val[1], nil) + + result +end + +def _reduce_83(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_84(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_85(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_86(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +# reduce 87 omitted + +def _reduce_88(val, _values, result) + result = val[0]. + push(val[1]) + + result +end + +def _reduce_89(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])) + + result +end + +def _reduce_90(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])). + concat(val[4]) + + result +end + +def _reduce_91(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])) + + result +end + +def _reduce_92(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])). + concat(val[3]) + + result +end + +def _reduce_93(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_94(val, _values, result) + result = [ @builder.splat(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_95(val, _values, result) + result = [ @builder.splat(val[0]) ] + + result +end + +def _reduce_96(val, _values, result) + result = [ @builder.splat(val[0]), + *val[2] ] + + result +end + +# reduce 97 omitted + +def _reduce_98(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_99(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_100(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_101(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_102(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_103(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_104(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_105(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_106(val, _values, result) + if (val[1][0] == :anddot) + diagnostic :error, :csend_in_lhs_of_masgn, nil, val[1] + end + + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_107(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_108(val, _values, result) + if (val[1][0] == :anddot) + diagnostic :error, :csend_in_lhs_of_masgn, nil, val[1] + end + + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_109(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_110(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_111(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_112(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_113(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_114(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_115(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_116(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_117(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_118(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_119(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_120(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_121(val, _values, result) + diagnostic :error, :module_name_const, nil, val[0] + + result +end + +# reduce 122 omitted + +def _reduce_123(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_124(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_125(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +# reduce 126 omitted + +# reduce 127 omitted + +# reduce 128 omitted + +# reduce 129 omitted + +# reduce 130 omitted + +def _reduce_131(val, _values, result) + result = @builder.symbol_internal(val[0]) + + result +end + +# reduce 132 omitted + +def _reduce_133(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_134(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_135(val, _values, result) + result = val[0] << val[3] + + result +end + +# reduce 136 omitted + +# reduce 137 omitted + +# reduce 138 omitted + +# reduce 139 omitted + +# reduce 140 omitted + +# reduce 141 omitted + +# reduce 142 omitted + +# reduce 143 omitted + +# reduce 144 omitted + +# reduce 145 omitted + +# reduce 146 omitted + +# reduce 147 omitted + +# reduce 148 omitted + +# reduce 149 omitted + +# reduce 150 omitted + +# reduce 151 omitted + +# reduce 152 omitted + +# reduce 153 omitted + +# reduce 154 omitted + +# reduce 155 omitted + +# reduce 156 omitted + +# reduce 157 omitted + +# reduce 158 omitted + +# reduce 159 omitted + +# reduce 160 omitted + +# reduce 161 omitted + +# reduce 162 omitted + +# reduce 163 omitted + +# reduce 164 omitted + +# reduce 165 omitted + +# reduce 166 omitted + +# reduce 167 omitted + +# reduce 168 omitted + +# reduce 169 omitted + +# reduce 170 omitted + +# reduce 171 omitted + +# reduce 172 omitted + +# reduce 173 omitted + +# reduce 174 omitted + +# reduce 175 omitted + +# reduce 176 omitted + +# reduce 177 omitted + +# reduce 178 omitted + +# reduce 179 omitted + +# reduce 180 omitted + +# reduce 181 omitted + +# reduce 182 omitted + +# reduce 183 omitted + +# reduce 184 omitted + +# reduce 185 omitted + +# reduce 186 omitted + +# reduce 187 omitted + +# reduce 188 omitted + +# reduce 189 omitted + +# reduce 190 omitted + +# reduce 191 omitted + +# reduce 192 omitted + +# reduce 193 omitted + +# reduce 194 omitted + +# reduce 195 omitted + +# reduce 196 omitted + +# reduce 197 omitted + +# reduce 198 omitted + +# reduce 199 omitted + +# reduce 200 omitted + +# reduce 201 omitted + +# reduce 202 omitted + +# reduce 203 omitted + +# reduce 204 omitted + +# reduce 205 omitted + +# reduce 206 omitted + +def _reduce_207(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_208(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_209(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_210(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_211(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_212(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_213(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_214(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_global(val[0], val[1])) + result = @builder.op_assign(const, val[2], val[3]) + + result +end + +def _reduce_215(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_216(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_217(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_218(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], nil) + + result +end + +def _reduce_219(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], nil) + + result +end + +def _reduce_220(val, _values, result) + result = @builder.range_inclusive(nil, val[0], val[1]) + + result +end + +def _reduce_221(val, _values, result) + result = @builder.range_exclusive(nil, val[0], val[1]) + + result +end + +def _reduce_222(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_223(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_224(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_225(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_226(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_227(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_228(val, _values, result) + result = @builder.unary_op(val[0], + @builder.binary_op( + val[1], val[2], val[3])) + + result +end + +def _reduce_229(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_230(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_231(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_232(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_233(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_234(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +# reduce 235 omitted + +def _reduce_236(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_237(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_238(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_239(val, _values, result) + result = @builder.match_op(val[0], val[1], val[2]) + + result +end + +def _reduce_240(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_241(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +def _reduce_242(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_243(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_244(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_245(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_246(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_247(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil) + + result +end + +def _reduce_248(val, _values, result) + result = @builder.ternary(val[0], val[1], + val[2], val[4], val[5]) + + result +end + +def _reduce_249(val, _values, result) + def_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + result = @builder.def_endless_method(def_t, name_t, + val[1], val[2], val[3]) + + local_pop + @context.in_def = ctx.in_def + @current_arg_stack.pop + + result +end + +def _reduce_250(val, _values, result) + def_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + rescue_body = @builder.rescue_body(val[4], + nil, nil, nil, + nil, val[5]) + + method_body = @builder.begin_body(val[3], [ rescue_body ]) + + result = @builder.def_endless_method(def_t, name_t, + val[1], val[2], method_body) + + local_pop + @context.in_def = ctx.in_def + @current_arg_stack.pop + + result +end + +def _reduce_251(val, _values, result) + def_t, recv, dot_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + result = @builder.def_endless_singleton(def_t, recv, dot_t, name_t, + val[1], val[2], val[3]) + + local_pop + @context.in_def = ctx.in_def + @current_arg_stack.pop + + result +end + +def _reduce_252(val, _values, result) + def_t, recv, dot_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + rescue_body = @builder.rescue_body(val[4], + nil, nil, nil, + nil, val[5]) + + method_body = @builder.begin_body(val[3], [ rescue_body ]) + + result = @builder.def_endless_singleton(def_t, recv, dot_t, name_t, + val[1], val[2], method_body) + + local_pop + @context.in_def = ctx.in_def + @current_arg_stack.pop + + result +end + +# reduce 253 omitted + +# reduce 254 omitted + +# reduce 255 omitted + +# reduce 256 omitted + +# reduce 257 omitted + +def _reduce_258(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_259(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +# reduce 260 omitted + +# reduce 261 omitted + +# reduce 262 omitted + +def _reduce_263(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_264(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +# reduce 265 omitted + +def _reduce_266(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_267(val, _values, result) + result = val + + result +end + +def _reduce_268(val, _values, result) + unless @static_env.declared_forward_args? + diagnostic :error, :unexpected_token, { :token => 'tBDOT3' } , val[3] + end + + result = [val[0], [*val[1], @builder.forwarded_args(val[3])], val[4]] + + result +end + +def _reduce_269(val, _values, result) + unless @static_env.declared_forward_args? + diagnostic :error, :unexpected_token, { :token => 'tBDOT3' } , val[1] + end + + result = [val[0], [@builder.forwarded_args(val[1])], val[2]] + + result +end + +def _reduce_270(val, _values, result) + result = [ nil, [], nil ] + + result +end + +# reduce 271 omitted + +def _reduce_272(val, _values, result) + result = [] + + result +end + +# reduce 273 omitted + +# reduce 274 omitted + +def _reduce_275(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_276(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +def _reduce_277(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_278(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_279(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + result.concat(val[1]) + + result +end + +def _reduce_280(val, _values, result) + assocs = @builder.associate(nil, val[2], nil) + result = val[0] << assocs + result.concat(val[3]) + + result +end + +def _reduce_281(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_282(val, _values, result) + # When branch gets invoked by RACC's lookahead + # and command args start with '[' or '(' + # we need to put `true` to the cmdarg stack + # **before** `false` pushed by lexer + # m [], n + # ^ + # Right here we have cmdarg [...0] because + # lexer pushed it on '[' + # We need to modify cmdarg stack to [...10] + # + # For all other cases (like `m n` or `m n, []`) we simply put 1 to the stack + # and later lexer pushes corresponding bits on top of it. + last_token = @last_token[0] + lookahead = last_token == :tLBRACK || last_token == :tLPAREN_ARG + + if lookahead + top = @lexer.cmdarg.pop + @lexer.cmdarg.push(true) + @lexer.cmdarg.push(top) + else + @lexer.cmdarg.push(true) + end + + result +end + +def _reduce_283(val, _values, result) + # call_args can be followed by tLBRACE_ARG (that does cmdarg.push(0) in the lexer) + # but the push must be done after cmdarg.pop() in the parser. + # So this code does cmdarg.pop() to pop 0 pushed by tLBRACE_ARG, + # cmdarg.pop() to pop 1 pushed by command_args, + # and cmdarg.push(0) to restore back the flag set by tLBRACE_ARG. + last_token = @last_token[0] + lookahead = last_token == :tLBRACE_ARG + if lookahead + top = @lexer.cmdarg.pop + @lexer.cmdarg.pop + @lexer.cmdarg.push(top) + else + @lexer.cmdarg.pop + end + + result = val[1] + + result +end + +def _reduce_284(val, _values, result) + result = @builder.block_pass(val[0], val[1]) + + result +end + +def _reduce_285(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_286(val, _values, result) + result = [] + + result +end + +def _reduce_287(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_288(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_289(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_290(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_291(val, _values, result) + result = @builder.array(nil, val[0], nil) + + result +end + +# reduce 292 omitted + +def _reduce_293(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_294(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_295(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +# reduce 296 omitted + +# reduce 297 omitted + +# reduce 298 omitted + +# reduce 299 omitted + +# reduce 300 omitted + +# reduce 301 omitted + +# reduce 302 omitted + +# reduce 303 omitted + +# reduce 304 omitted + +# reduce 305 omitted + +def _reduce_306(val, _values, result) + result = @builder.call_method(nil, nil, val[0]) + + result +end + +def _reduce_307(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_308(val, _values, result) + @lexer.cmdarg.pop + + result = @builder.begin_keyword(val[0], val[2], val[3]) + + result +end + +def _reduce_309(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_310(val, _values, result) + result = @builder.begin(val[0], val[1], val[3]) + + result +end + +def _reduce_311(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_312(val, _values, result) + result = @builder.begin(val[0], nil, val[3]) + + result +end + +def _reduce_313(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_314(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +def _reduce_315(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_316(val, _values, result) + result = @builder.array(val[0], val[1], val[2]) + + result +end + +def _reduce_317(val, _values, result) + result = @builder.associate(val[0], val[1], val[2]) + + result +end + +def _reduce_318(val, _values, result) + result = @builder.keyword_cmd(:return, val[0]) + + result +end + +def _reduce_319(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_320(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2]) + + result +end + +def _reduce_321(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0]) + + result +end + +def _reduce_322(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], + val[2], [ val[3] ], val[4]) + + result +end + +def _reduce_323(val, _values, result) + result = @builder.not_op(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_324(val, _values, result) + result = @builder.not_op(val[0], val[1], nil, val[2]) + + result +end + +def _reduce_325(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0]) + + begin_t, args, body, end_t = val[1] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +# reduce 326 omitted + +def _reduce_327(val, _values, result) + begin_t, args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, args, body, end_t) + + result +end + +# reduce 328 omitted + +def _reduce_329(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, val[5]) + + result +end + +def _reduce_330(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + else_, else_t, + val[3], val[5]) + + result +end + +def _reduce_331(val, _values, result) + result = @builder.loop(:while, val[0], *val[1], val[2], val[3]) + + result +end + +def _reduce_332(val, _values, result) + result = @builder.loop(:until, val[0], *val[1], val[2], val[3]) + + result +end + +def _reduce_333(val, _values, result) + *when_bodies, (else_t, else_body) = *val[3] + + result = @builder.case(val[0], val[1], + when_bodies, else_t, else_body, + val[4]) + + result +end + +def _reduce_334(val, _values, result) + *when_bodies, (else_t, else_body) = *val[2] + + result = @builder.case(val[0], nil, + when_bodies, else_t, else_body, + val[3]) + + result +end + +def _reduce_335(val, _values, result) + *in_bodies, (else_t, else_body) = *val[3] + + result = @builder.case_match(val[0], val[1], + in_bodies, else_t, else_body, + val[4]) + + result +end + +def _reduce_336(val, _values, result) + result = @builder.for(val[0], val[1], val[2], *val[3], val[4], val[5]) + + result +end + +def _reduce_337(val, _values, result) + @context.in_class = true + local_push + + result +end + +def _reduce_338(val, _values, result) + k_class, ctx = val[0] + if @context.in_def + diagnostic :error, :class_in_def, nil, k_class + end + + lt_t, superclass = val[2] + result = @builder.def_class(k_class, val[1], + lt_t, superclass, + val[4], val[5]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_339(val, _values, result) + @context.in_def = false + @context.in_class = false + local_push + + result +end + +def _reduce_340(val, _values, result) + k_class, ctx = val[0] + result = @builder.def_sclass(k_class, val[1], val[2], + val[5], val[6]) + + local_pop + @context.in_def = ctx.in_def + @context.in_class = ctx.in_class + + result +end + +def _reduce_341(val, _values, result) + @context.in_class = true + local_push + + result +end + +def _reduce_342(val, _values, result) + k_mod, ctx = val[0] + if @context.in_def + diagnostic :error, :module_in_def, nil, k_mod + end + + result = @builder.def_module(k_mod, val[1], + val[3], val[4]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_343(val, _values, result) + def_t, (name_t, ctx) = val[0] + result = @builder.def_method(def_t, name_t, val[1], + val[2], val[3]) + + local_pop + @context.in_def = ctx.in_def + @current_arg_stack.pop + + result +end + +def _reduce_344(val, _values, result) + def_t, recv, dot_t, (name_t, ctx) = val[0] + result = @builder.def_singleton(def_t, recv, dot_t, name_t, val[1], + val[2], val[3]) + + local_pop + @context.in_def = ctx.in_def + @current_arg_stack.pop + + result +end + +def _reduce_345(val, _values, result) + result = @builder.keyword_cmd(:break, val[0]) + + result +end + +def _reduce_346(val, _values, result) + result = @builder.keyword_cmd(:next, val[0]) + + result +end + +def _reduce_347(val, _values, result) + result = @builder.keyword_cmd(:redo, val[0]) + + result +end + +def _reduce_348(val, _values, result) + result = @builder.keyword_cmd(:retry, val[0]) + + result +end + +# reduce 349 omitted + +def _reduce_350(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_351(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_352(val, _values, result) + result = val[0] + + result +end + +def _reduce_353(val, _values, result) + if @context.in_class && !@context.in_def && !(context.in_block || context.in_lambda) + diagnostic :error, :invalid_return, nil, val[0] + end + + result +end + +# reduce 354 omitted + +# reduce 355 omitted + +def _reduce_356(val, _values, result) + result = val[1] + + result +end + +# reduce 357 omitted + +# reduce 358 omitted + +# reduce 359 omitted + +def _reduce_360(val, _values, result) + else_t, else_ = val[4] + result = [ val[0], + @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, nil), + ] + + result +end + +# reduce 361 omitted + +def _reduce_362(val, _values, result) + result = val + + result +end + +# reduce 363 omitted + +# reduce 364 omitted + +def _reduce_365(val, _values, result) + result = @builder.arg(val[0]) + + result +end + +def _reduce_366(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_367(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_368(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 369 omitted + +def _reduce_370(val, _values, result) + result = val[0]. + push(val[2]) + + result +end + +def _reduce_371(val, _values, result) + result = val[0]. + push(val[2]). + concat(val[4]) + + result +end + +def _reduce_372(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_373(val, _values, result) + result = [ val[0], *val[2] ] + + result +end + +def _reduce_374(val, _values, result) + result = @builder.restarg(val[0], val[1]) + + result +end + +def _reduce_375(val, _values, result) + result = @builder.restarg(val[0]) + + result +end + +# reduce 376 omitted + +# reduce 377 omitted + +def _reduce_378(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_379(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_380(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_381(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_382(val, _values, result) + result = val[1] + + result +end + +def _reduce_383(val, _values, result) + result = [] + + result +end + +# reduce 384 omitted + +def _reduce_385(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_386(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_387(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_388(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_389(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 390 omitted + +def _reduce_391(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_392(val, _values, result) + if val[1].empty? && val[0].size == 1 + result = [@builder.procarg0(val[0][0])] + else + result = val[0].concat(val[1]) + end + + result +end + +def _reduce_393(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_394(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_395(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_396(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_397(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_398(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 399 omitted + +def _reduce_400(val, _values, result) + result = @builder.args(nil, [], nil) + + result +end + +def _reduce_401(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_402(val, _values, result) + @max_numparam_stack.has_ordinary_params! + @current_arg_stack.set(nil) + result = @builder.args(val[0], val[1], val[2]) + + result +end + +def _reduce_403(val, _values, result) + @max_numparam_stack.has_ordinary_params! + @current_arg_stack.set(nil) + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_404(val, _values, result) + result = [] + + result +end + +def _reduce_405(val, _values, result) + result = val[2] + + result +end + +def _reduce_406(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_407(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_408(val, _values, result) + @static_env.declare val[0][0] + result = @builder.shadowarg(val[0]) + + result +end + +# reduce 409 omitted + +def _reduce_410(val, _values, result) + @static_env.extend_dynamic + @max_numparam_stack.push(static: false) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_411(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_412(val, _values, result) + lambda_call = @builder.call_lambda(val[0]) + args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[2] + begin_t, body, end_t = val[4] + + @max_numparam_stack.pop + @static_env.unextend + @lexer.cmdarg.pop + @context.in_lambda = val[1].in_lambda + + result = @builder.block(lambda_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_413(val, _values, result) + @max_numparam_stack.has_ordinary_params! + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_414(val, _values, result) + if val[0].any? + @max_numparam_stack.has_ordinary_params! + end + result = @builder.args(nil, val[0], nil) + + result +end + +def _reduce_415(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_416(val, _values, result) + result = [ val[0], val[2], val[3] ] + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_417(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_418(val, _values, result) + result = [ val[0], val[2], val[3] ] + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_419(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_420(val, _values, result) + result = [ val[0], *val[2], val[3] ] + @context.in_block = val[1].in_block + + result +end + +def _reduce_421(val, _values, result) + begin_t, block_args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, block_args, body, end_t) + + result +end + +def _reduce_422(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_423(val, _values, result) + lparen_t, args, rparen_t = val[3] + method_call = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_424(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_425(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.call_method(nil, nil, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_426(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_427(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_428(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2]) + + result +end + +def _reduce_429(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_430(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_431(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.keyword_cmd(:super, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_432(val, _values, result) + result = @builder.keyword_cmd(:zsuper, val[0]) + + result +end + +def _reduce_433(val, _values, result) + result = @builder.index(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_434(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_435(val, _values, result) + result = [ val[0], *val[2], val[3] ] + @context.in_block = val[1].in_block + + result +end + +def _reduce_436(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_437(val, _values, result) + result = [ val[0], *val[2], val[3] ] + @context.in_block = val[1].in_block + + result +end + +def _reduce_438(val, _values, result) + @static_env.extend_dynamic + @max_numparam_stack.push(static: false) + + result +end + +def _reduce_439(val, _values, result) + args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[1] + result = [ args, val[2] ] + + @max_numparam_stack.pop + @static_env.unextend + + result +end + +def _reduce_440(val, _values, result) + @static_env.extend_dynamic + @max_numparam_stack.push(static: false) + + result +end + +def _reduce_441(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_442(val, _values, result) + args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[2] + result = [ args, val[3] ] + + @max_numparam_stack.pop + @static_env.unextend + @lexer.cmdarg.pop + + result +end + +def _reduce_443(val, _values, result) + result = [ @builder.when(val[0], val[1], val[2], val[3]), + *val[4] ] + + result +end + +def _reduce_444(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 445 omitted + +def _reduce_446(val, _values, result) + @lexer.state = :expr_beg + @lexer.command_start = false + @pattern_variables.push + @pattern_hash_keys.push + + result = @context.in_kwarg + @context.in_kwarg = true + + result +end + +def _reduce_447(val, _values, result) + @pattern_variables.pop + @pattern_hash_keys.pop + @context.in_kwarg = val[1] + + result +end + +def _reduce_448(val, _values, result) + result = [ @builder.in_pattern(val[0], *val[2], val[3], val[5]), + *val[6] ] + + result +end + +def _reduce_449(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 450 omitted + +def _reduce_451(val, _values, result) + result = [ val[0], nil ] + + result +end + +def _reduce_452(val, _values, result) + result = [ val[0], @builder.if_guard(val[1], val[2]) ] + + result +end + +def _reduce_453(val, _values, result) + result = [ val[0], @builder.unless_guard(val[1], val[2]) ] + + result +end + +# reduce 454 omitted + +def _reduce_455(val, _values, result) + # array patterns that end with comma + # like 1, 2, + # must be emitted as `array_pattern_with_tail` + item = @builder.match_with_trailing_comma(val[0], val[1]) + result = @builder.array_pattern(nil, [ item ], nil) + + result +end + +def _reduce_456(val, _values, result) + result = @builder.array_pattern(nil, [val[0]].concat(val[2]), nil) + + result +end + +def _reduce_457(val, _values, result) + result = @builder.find_pattern(nil, val[0], nil) + + result +end + +def _reduce_458(val, _values, result) + result = @builder.array_pattern(nil, val[0], nil) + + result +end + +def _reduce_459(val, _values, result) + result = @builder.hash_pattern(nil, val[0], nil) + + result +end + +# reduce 460 omitted + +def _reduce_461(val, _values, result) + result = @builder.match_as(val[0], val[1], val[2]) + + result +end + +# reduce 462 omitted + +def _reduce_463(val, _values, result) + result = @builder.match_alt(val[0], val[1], val[2]) + + result +end + +# reduce 464 omitted + +def _reduce_465(val, _values, result) + result = val[0] + @pattern_hash_keys.push + + result +end + +def _reduce_466(val, _values, result) + result = val[0] + @pattern_hash_keys.push + + result +end + +# reduce 467 omitted + +def _reduce_468(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.array_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_469(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.find_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_470(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.hash_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_471(val, _values, result) + pattern = @builder.array_pattern(val[1], nil, val[2]) + result = @builder.const_pattern(val[0], val[1], pattern, val[2]) + + result +end + +def _reduce_472(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.array_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_473(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.find_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_474(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.hash_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_475(val, _values, result) + pattern = @builder.array_pattern(val[1], nil, val[2]) + result = @builder.const_pattern(val[0], val[1], pattern, val[2]) + + result +end + +def _reduce_476(val, _values, result) + result = @builder.array_pattern(val[0], val[1], val[2]) + + result +end + +def _reduce_477(val, _values, result) + result = @builder.find_pattern(val[0], val[1], val[2]) + + result +end + +def _reduce_478(val, _values, result) + result = @builder.array_pattern(val[0], [], val[1]) + + result +end + +def _reduce_479(val, _values, result) + @pattern_hash_keys.push + result = @context.in_kwarg + @context.in_kwarg = false + + result +end + +def _reduce_480(val, _values, result) + @pattern_hash_keys.pop + @context.in_kwarg = val[1] + result = @builder.hash_pattern(val[0], val[2], val[3]) + + result +end + +def _reduce_481(val, _values, result) + result = @builder.hash_pattern(val[0], [], val[1]) + + result +end + +def _reduce_482(val, _values, result) + @pattern_hash_keys.push + + result +end + +def _reduce_483(val, _values, result) + @pattern_hash_keys.pop + result = @builder.begin(val[0], val[2], val[3]) + + result +end + +def _reduce_484(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_485(val, _values, result) + result = val[0] + + result +end + +def _reduce_486(val, _values, result) + result = [ *val[0], val[1] ] + + result +end + +def _reduce_487(val, _values, result) + match_rest = @builder.match_rest(val[1], val[2]) + result = [ *val[0], match_rest ] + + result +end + +def _reduce_488(val, _values, result) + match_rest = @builder.match_rest(val[1], val[2]) + result = [ *val[0], match_rest, *val[4] ] + + result +end + +def _reduce_489(val, _values, result) + result = [ *val[0], @builder.match_rest(val[1]) ] + + result +end + +def _reduce_490(val, _values, result) + result = [ *val[0], @builder.match_rest(val[1]), *val[3] ] + + result +end + +# reduce 491 omitted + +def _reduce_492(val, _values, result) + # array patterns that end with comma + # like [1, 2,] + # must be emitted as `array_pattern_with_tail` + item = @builder.match_with_trailing_comma(val[0], val[1]) + result = [ item ] + + result +end + +def _reduce_493(val, _values, result) + # array patterns that end with comma + # like [1, 2,] + # must be emitted as `array_pattern_with_tail` + last_item = @builder.match_with_trailing_comma(val[1], val[2]) + result = [ *val[0], last_item ] + + result +end + +def _reduce_494(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_495(val, _values, result) + result = [ val[0], *val[2] ] + + result +end + +def _reduce_496(val, _values, result) + result = [ val[0], *val[2], val[4] ] + + result +end + +def _reduce_497(val, _values, result) + result = @builder.match_rest(val[0], val[1]) + + result +end + +def _reduce_498(val, _values, result) + result = @builder.match_rest(val[0]) + + result +end + +def _reduce_499(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_500(val, _values, result) + result = [ *val[0], val[2] ] + + result +end + +# reduce 501 omitted + +def _reduce_502(val, _values, result) + result = [ *val[0], *val[2] ] + + result +end + +def _reduce_503(val, _values, result) + result = val[0] + + result +end + +def _reduce_504(val, _values, result) + result = val[0] + + result +end + +def _reduce_505(val, _values, result) + result = val[0] + + result +end + +def _reduce_506(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_507(val, _values, result) + result = [ *val[0], val[2] ] + + result +end + +def _reduce_508(val, _values, result) + result = @builder.match_pair(*val[0], val[1]) + + result +end + +def _reduce_509(val, _values, result) + result = @builder.match_label(*val[0]) + + result +end + +def _reduce_510(val, _values, result) + result = [:label, val[0]] + + result +end + +def _reduce_511(val, _values, result) + result = [:quoted, [val[0], val[1], val[2]]] + + result +end + +def _reduce_512(val, _values, result) + result = [ @builder.match_rest(val[0], val[1]) ] + + result +end + +def _reduce_513(val, _values, result) + result = [ @builder.match_rest(val[0], nil) ] + + result +end + +def _reduce_514(val, _values, result) + result = [ @builder.match_nil_pattern(val[0], val[1]) ] + + result +end + +# reduce 515 omitted + +# reduce 516 omitted + +# reduce 517 omitted + +def _reduce_518(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_519(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_520(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], nil) + + result +end + +def _reduce_521(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], nil) + + result +end + +# reduce 522 omitted + +# reduce 523 omitted + +# reduce 524 omitted + +def _reduce_525(val, _values, result) + result = @builder.range_inclusive(nil, val[0], val[1]) + + result +end + +def _reduce_526(val, _values, result) + result = @builder.range_exclusive(nil, val[0], val[1]) + + result +end + +# reduce 527 omitted + +# reduce 528 omitted + +# reduce 529 omitted + +# reduce 530 omitted + +# reduce 531 omitted + +# reduce 532 omitted + +# reduce 533 omitted + +# reduce 534 omitted + +def _reduce_535(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +# reduce 536 omitted + +def _reduce_537(val, _values, result) + result = @builder.assignable(@builder.match_var(val[0])) + + result +end + +def _reduce_538(val, _values, result) + name = val[1][0] + lvar = @builder.accessible(@builder.ident(val[1])) + + unless static_env.declared?(name) + diagnostic :error, :undefined_lvar, { :name => name }, val[1] + end + + result = @builder.pin(val[0], lvar) + + result +end + +def _reduce_539(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_540(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +def _reduce_541(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_542(val, _values, result) + assoc_t, exc_var = val[2] + + if val[1] + exc_list = @builder.array(nil, val[1], nil) + end + + result = [ @builder.rescue_body(val[0], + exc_list, assoc_t, exc_var, + val[3], val[4]), + *val[5] ] + + result +end + +def _reduce_543(val, _values, result) + result = [] + + result +end + +def _reduce_544(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 545 omitted + +# reduce 546 omitted + +def _reduce_547(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 548 omitted + +def _reduce_549(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 550 omitted + +# reduce 551 omitted + +# reduce 552 omitted + +def _reduce_553(val, _values, result) + result = @builder.string_compose(nil, val[0], nil) + + result +end + +def _reduce_554(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_555(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_556(val, _values, result) + string = @builder.string_compose(val[0], val[1], val[2]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_557(val, _values, result) + string = @builder.string(val[0]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_558(val, _values, result) + result = @builder.character(val[0]) + + result +end + +def _reduce_559(val, _values, result) + string = @builder.xstring_compose(val[0], val[1], val[2]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_560(val, _values, result) + opts = @builder.regexp_options(val[3]) + result = @builder.regexp_compose(val[0], val[1], val[2], opts) + + result +end + +def _reduce_561(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_562(val, _values, result) + result = [] + + result +end + +def _reduce_563(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_564(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_565(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_566(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_567(val, _values, result) + result = [] + + result +end + +def _reduce_568(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_569(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_570(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_571(val, _values, result) + result = [] + + result +end + +def _reduce_572(val, _values, result) + result = val[0] << @builder.string_internal(val[1]) + + result +end + +def _reduce_573(val, _values, result) + result = [] + + result +end + +def _reduce_574(val, _values, result) + result = val[0] << @builder.symbol_internal(val[1]) + + result +end + +def _reduce_575(val, _values, result) + result = [] + + result +end + +def _reduce_576(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_577(val, _values, result) + result = [] + + result +end + +def _reduce_578(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_579(val, _values, result) + result = [] + + result +end + +def _reduce_580(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_581(val, _values, result) + result = @builder.string_internal(val[0]) + + result +end + +def _reduce_582(val, _values, result) + result = val[1] + + result +end + +def _reduce_583(val, _values, result) + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + + result +end + +def _reduce_584(val, _values, result) + @lexer.cmdarg.pop + @lexer.cond.pop + + result = @builder.begin(val[0], val[2], val[3]) + + result +end + +def _reduce_585(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_586(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_587(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +# reduce 588 omitted + +# reduce 589 omitted + +# reduce 590 omitted + +def _reduce_591(val, _values, result) + @lexer.state = :expr_end + result = @builder.symbol(val[0]) + + result +end + +def _reduce_592(val, _values, result) + @lexer.state = :expr_end + result = @builder.symbol_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_593(val, _values, result) + result = val[0] + + result +end + +def _reduce_594(val, _values, result) + if @builder.respond_to? :negate + # AST builder interface compatibility + result = @builder.negate(val[0], val[1]) + else + result = @builder.unary_num(val[0], val[1]) + end + + result +end + +def _reduce_595(val, _values, result) + @lexer.state = :expr_end + result = @builder.integer(val[0]) + + result +end + +def _reduce_596(val, _values, result) + @lexer.state = :expr_end + result = @builder.float(val[0]) + + result +end + +def _reduce_597(val, _values, result) + @lexer.state = :expr_end + result = @builder.rational(val[0]) + + result +end + +def _reduce_598(val, _values, result) + @lexer.state = :expr_end + result = @builder.complex(val[0]) + + result +end + +def _reduce_599(val, _values, result) + result = @builder.ident(val[0]) + + result +end + +def _reduce_600(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_601(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_602(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_603(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +def _reduce_604(val, _values, result) + result = @builder.nil(val[0]) + + result +end + +def _reduce_605(val, _values, result) + result = @builder.self(val[0]) + + result +end + +def _reduce_606(val, _values, result) + result = @builder.true(val[0]) + + result +end + +def _reduce_607(val, _values, result) + result = @builder.false(val[0]) + + result +end + +def _reduce_608(val, _values, result) + result = @builder.__FILE__(val[0]) + + result +end + +def _reduce_609(val, _values, result) + result = @builder.__LINE__(val[0]) + + result +end + +def _reduce_610(val, _values, result) + result = @builder.__ENCODING__(val[0]) + + result +end + +def _reduce_611(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_612(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_613(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_614(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_615(val, _values, result) + result = @builder.nth_ref(val[0]) + + result +end + +def _reduce_616(val, _values, result) + result = @builder.back_ref(val[0]) + + result +end + +def _reduce_617(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_618(val, _values, result) + result = [ val[0], val[2] ] + + result +end + +def _reduce_619(val, _values, result) + result = nil + + result +end + +# reduce 620 omitted + +def _reduce_621(val, _values, result) + result = @builder.args(nil, [], nil) + + result +end + +def _reduce_622(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + @lexer.state = :expr_value + + result +end + +def _reduce_623(val, _values, result) + args = [ *val[1], @builder.forward_arg(val[3]) ] + result = @builder.args(val[0], args, val[4]) + + @static_env.declare_forward_args + + result +end + +def _reduce_624(val, _values, result) + result = @builder.forward_only_args(val[0], val[1], val[2]) + @static_env.declare_forward_args + + @lexer.state = :expr_value + + result +end + +# reduce 625 omitted + +def _reduce_626(val, _values, result) + result = @context.in_kwarg + @context.in_kwarg = true + + result +end + +def _reduce_627(val, _values, result) + @context.in_kwarg = val[0] + result = @builder.args(nil, val[1], nil) + + result +end + +def _reduce_628(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_629(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_630(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_631(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_632(val, _values, result) + result = val[1] + + result +end + +def _reduce_633(val, _values, result) + result = [] + + result +end + +def _reduce_634(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_635(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_636(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_637(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_638(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_639(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_640(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_641(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_642(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_643(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_644(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_645(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_646(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_647(val, _values, result) + result = val[0] + + result +end + +def _reduce_648(val, _values, result) + result = [] + + result +end + +def _reduce_649(val, _values, result) + result = val[0] + + result +end + +def _reduce_650(val, _values, result) + diagnostic :error, :argument_const, nil, val[0] + + result +end + +def _reduce_651(val, _values, result) + diagnostic :error, :argument_ivar, nil, val[0] + + result +end + +def _reduce_652(val, _values, result) + diagnostic :error, :argument_gvar, nil, val[0] + + result +end + +def _reduce_653(val, _values, result) + diagnostic :error, :argument_cvar, nil, val[0] + + result +end + +# reduce 654 omitted + +def _reduce_655(val, _values, result) + @static_env.declare val[0][0] + + @max_numparam_stack.has_ordinary_params! + + result = val[0] + + result +end + +def _reduce_656(val, _values, result) + @current_arg_stack.set(val[0][0]) + result = val[0] + + result +end + +def _reduce_657(val, _values, result) + @current_arg_stack.set(0) + result = @builder.arg(val[0]) + + result +end + +def _reduce_658(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_659(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_660(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_661(val, _values, result) + check_kwarg_name(val[0]) + + @static_env.declare val[0][0] + + @max_numparam_stack.has_ordinary_params! + + @current_arg_stack.set(val[0][0]) + + result = val[0] + + result +end + +def _reduce_662(val, _values, result) + @current_arg_stack.set(nil) + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_663(val, _values, result) + @current_arg_stack.set(nil) + result = @builder.kwarg(val[0]) + + result +end + +def _reduce_664(val, _values, result) + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_665(val, _values, result) + result = @builder.kwarg(val[0]) + + result +end + +def _reduce_666(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_667(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_668(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_669(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 670 omitted + +# reduce 671 omitted + +def _reduce_672(val, _values, result) + result = [ @builder.kwnilarg(val[0], val[1]) ] + + result +end + +def _reduce_673(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.kwrestarg(val[0], val[1]) ] + + result +end + +def _reduce_674(val, _values, result) + result = [ @builder.kwrestarg(val[0]) ] + + result +end + +def _reduce_675(val, _values, result) + @current_arg_stack.set(0) + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_676(val, _values, result) + @current_arg_stack.set(0) + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_677(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_678(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_679(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_680(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 681 omitted + +# reduce 682 omitted + +def _reduce_683(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_684(val, _values, result) + result = [ @builder.restarg(val[0]) ] + + result +end + +# reduce 685 omitted + +# reduce 686 omitted + +def _reduce_687(val, _values, result) + @static_env.declare val[1][0] + + result = @builder.blockarg(val[0], val[1]) + + result +end + +def _reduce_688(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_689(val, _values, result) + result = [] + + result +end + +# reduce 690 omitted + +def _reduce_691(val, _values, result) + result = val[1] + + result +end + +def _reduce_692(val, _values, result) + result = [] + + result +end + +# reduce 693 omitted + +def _reduce_694(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_695(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_696(val, _values, result) + result = @builder.pair(val[0], val[1], val[2]) + + result +end + +def _reduce_697(val, _values, result) + result = @builder.pair_keyword(val[0], val[1]) + + result +end + +def _reduce_698(val, _values, result) + result = @builder.pair_quoted(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_699(val, _values, result) + result = @builder.kwsplat(val[0], val[1]) + + result +end + +# reduce 700 omitted + +# reduce 701 omitted + +# reduce 702 omitted + +# reduce 703 omitted + +# reduce 704 omitted + +# reduce 705 omitted + +# reduce 706 omitted + +# reduce 707 omitted + +# reduce 708 omitted + +# reduce 709 omitted + +# reduce 710 omitted + +# reduce 711 omitted + +def _reduce_712(val, _values, result) + result = [:dot, val[0][1]] + + result +end + +def _reduce_713(val, _values, result) + result = [:anddot, val[0][1]] + + result +end + +# reduce 714 omitted + +# reduce 715 omitted + +# reduce 716 omitted + +# reduce 717 omitted + +def _reduce_718(val, _values, result) + result = val[1] + + result +end + +def _reduce_719(val, _values, result) + result = val[1] + + result +end + +def _reduce_720(val, _values, result) + result = val[1] + + result +end + +# reduce 721 omitted + +# reduce 722 omitted + +# reduce 723 omitted + +def _reduce_724(val, _values, result) + yyerrok + + result +end + +# reduce 725 omitted + +# reduce 726 omitted + +# reduce 727 omitted + +def _reduce_728(val, _values, result) + result = nil + + result +end + +def _reduce_none(val, _values, result) + val[0] +end + + end # class Ruby30 +end # module Parser diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby31.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby31.rb new file mode 100644 index 00000000..8c5648cb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby31.rb @@ -0,0 +1,12717 @@ +# -*- encoding:utf-8; warn-indent:false; frozen_string_literal: true -*- +# +# DO NOT MODIFY!!!! +# This file is automatically generated by Racc 1.8.1 +# from Racc grammar file "ruby31.y". +# + +require 'racc/parser.rb' + + +require_relative '../parser' + +module Parser + class Ruby31 < Parser::Base + + + def version + 31 + end + + def default_encoding + Encoding::UTF_8 + end + + def endless_method_name(name_t) + if !%w[=== == != <= >=].include?(name_t[0]) && name_t[0].end_with?('=') + diagnostic :error, :endless_setter, nil, name_t + end + end + + def local_push + @static_env.extend_static + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + @max_numparam_stack.push(static: true) + end + + def local_pop + @static_env.unextend + @lexer.cmdarg.pop + @lexer.cond.pop + @max_numparam_stack.pop + end + + def try_declare_numparam(node) + name = node.children[0] + + if name =~ /\A_[1-9]\z/ && !static_env.declared?(name) && @context.in_dynamic_block? + # definitely an implicit param + location = node.loc.expression + + if max_numparam_stack.has_ordinary_params? + diagnostic :error, :ordinary_param_defined, nil, [nil, location] + end + + raw_max_numparam_stack = max_numparam_stack.stack.dup + # ignore current block scope + raw_max_numparam_stack.pop + + raw_max_numparam_stack.reverse_each do |outer_scope| + if outer_scope[:static] + # found an outer scope that can't have numparams + # like def/class/etc + break + else + outer_scope_has_numparams = outer_scope[:value] > 0 + + if outer_scope_has_numparams + diagnostic :error, :numparam_used_in_outer_scope, nil, [nil, location] + else + # for now it's ok, but an outer scope can also be a block + # like proc { _1; proc { proc { proc { _2 }} }} + # with numparams, so we need to continue + end + end + end + + static_env.declare(name) + max_numparam_stack.register(name[1].to_i) + + true + else + false + end + end +##### State transition tables begin ### + +racc_action_table = [ + -614, 221, 222, 221, 222, 233, -116, -614, -614, -614, + 925, 620, -614, -614, -614, 227, -614, 311, 239, 1124, + 126, -732, 226, 620, -614, 125, -614, -614, -614, 221, + 222, 224, 717, 661, -117, -124, -614, -614, 620, -614, + -614, -614, -614, -614, 620, 620, 620, -116, -117, -732, + 718, -123, 892, 240, -124, 627, 663, 240, 3, 240, + 311, -744, 833, 833, -119, -121, -614, -614, -614, -614, + -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, + 228, 306, -614, -614, -614, 122, -614, -614, 828, 240, + -614, 1001, -118, -614, -614, 240, -614, 240, -614, 660, + -614, 1125, -614, -614, 310, -614, -614, -614, -614, -614, + -123, -614, -617, -614, -119, -107, 311, 221, 222, -617, + -617, -617, 662, 240, -617, -617, -617, -614, -617, 126, + -614, -614, -614, -614, 125, -614, -617, -614, -617, -617, + -617, 126, -614, -108, -115, -614, 125, 310, -617, -617, + -121, -617, -617, -617, -617, -617, 126, -120, -118, 990, + -114, 125, 126, 126, 126, -116, -117, 125, 125, 125, + -116, -117, -124, -110, -112, -120, -122, -124, -617, -617, + -617, -617, -617, -617, -617, -617, -617, -617, -617, -617, + -617, -617, 126, -122, -617, -617, -617, 125, -617, -617, + 1000, -109, -617, 310, 126, -617, -617, -732, -617, 125, + -617, 126, -617, 648, -617, -617, 125, -617, -617, -617, + -617, -617, -320, -617, 240, -617, 925, -628, -123, -320, + -320, -320, -119, -123, -719, -320, -320, -119, -320, -617, + -719, -720, -617, -617, -617, -617, -320, -617, 227, -617, + 311, 233, 135, 648, -617, 304, 925, -617, -320, -320, + -110, -320, -320, -320, -320, -320, 104, 105, -121, 892, + -720, 627, 924, -121, -112, -120, -118, 650, 649, -629, + -120, -118, 104, 105, -111, -113, -116, 859, -320, -320, + -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, + -320, -320, -511, 227, -320, -320, -320, -744, 687, -320, + 304, -122, -320, 228, 306, -320, -122, 650, 649, 646, + -320, 218, -320, 648, -320, -320, -110, -320, -320, -320, + -320, -320, 522, -320, -723, -320, 949, 310, -117, 237, + -112, -723, -723, -723, 106, 107, 126, -723, -723, -320, + -723, 125, -320, -320, 948, -113, 219, -320, -723, -723, + 106, 107, -109, 600, -320, 220, -110, -122, 228, -110, + -723, -723, 919, -723, -723, -723, -723, -723, -102, -614, + -112, -110, 612, -112, -111, 611, -614, 650, 649, 648, + -88, -124, 920, 648, 126, -112, 233, 861, -124, 125, + -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, + -723, -723, -723, -723, 223, 754, -723, -723, -723, -356, + 688, -723, -123, 300, -723, 499, -356, -723, -109, 682, + 648, -119, -723, 683, -723, -356, -723, -723, 648, -723, + -723, -723, -723, -723, -614, -723, -723, -723, 361, -719, + -111, -121, -744, 650, 649, 646, 648, 650, 649, 646, + 237, -723, 648, 500, -723, -723, -716, -111, -109, -723, + 800, -109, 648, -723, 1063, 1056, -723, 233, 362, -120, + -723, -723, -723, -109, -356, -723, -723, -723, -119, -723, + -111, 126, -121, -111, 650, 649, 125, -723, -723, -723, + -723, -723, 650, 649, 651, -111, -717, -115, 240, -723, + -723, 1063, -723, -723, -723, -723, -723, 431, -614, -124, + 650, 649, 653, 648, 471, -614, 650, 649, 655, 612, + -716, 1035, 614, -744, -614, -635, 650, 649, 659, -723, + -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, + -723, -723, -723, -716, 875, -723, -723, -723, -617, 921, + -723, 221, 222, -723, 633, -617, -723, -723, 634, -723, + -717, -723, 510, -723, -617, -723, -723, 521, -723, -723, + -723, -723, -723, -614, -723, -723, -723, 650, 649, 664, + -118, 227, -617, -717, -624, -623, 281, 282, 519, -617, + -723, -624, -623, -723, -723, -723, -723, 520, -723, -625, + -723, -628, -320, -118, 523, -723, -625, -629, -120, -320, + -320, -320, 524, -617, -320, -320, -320, -622, -320, 221, + 222, 239, 280, 279, -622, -619, -320, 558, -320, -320, + -320, 428, -619, 507, 506, 570, 430, 429, -320, -320, + 600, -320, -320, -320, -320, -320, 228, -617, -107, -624, + -623, -620, -621, 633, -108, 572, 931, 960, -620, -621, + -116, 927, 574, 633, -625, 928, -117, 960, -320, -320, + -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, + -320, -320, -622, 754, -320, -320, -320, -114, 922, -320, + -619, 682, -320, 499, 612, -320, -320, 614, -320, -123, + -320, 135, -320, 612, -320, -320, 614, -320, -320, -320, + -320, -320, -320, -320, -87, -320, -620, -621, 90, -320, + -320, -320, 950, 951, 240, -320, -320, 1197, -320, -320, + 91, 500, -320, -320, -320, -320, -320, -320, -110, -320, + 92, 985, 892, 1056, -320, 683, 240, -122, -320, -320, + -119, -320, -320, -320, -320, -320, 1149, 1150, 985, 892, + 491, -626, 488, 487, 486, 496, 489, 585, -626, 875, + 491, 586, 488, 487, 486, 499, 489, -626, -320, -320, + -320, -320, -320, -320, -320, -320, -320, -320, -320, -320, + -320, -320, -112, 593, -320, -320, -320, 494, 687, -320, + 315, 240, -320, 233, -121, -320, 504, 503, 507, 506, + -320, 233, -320, 500, -320, -320, -109, -320, -320, -320, + -320, -320, 306, -320, -723, -320, -626, 597, -118, 603, + 264, -723, -723, -723, 606, 240, 615, -723, -723, -320, + -723, 616, -320, -320, 574, -320, 627, -320, -723, -723, + 420, 631, 632, 485, -320, 640, 665, -122, 668, 669, + -723, -723, -293, -723, -723, -723, -723, -723, 671, 672, + 676, 240, 491, -627, 488, 487, 486, 496, 489, 954, + -627, 958, 957, 680, 681, 959, 306, 499, 694, -627, + -723, -723, -723, -723, -723, -723, -723, -723, -723, -723, + -723, -723, -723, -723, 695, 240, -723, -723, -723, 494, + 688, -723, 697, 700, -723, 701, 956, -723, 504, 503, + 507, 506, -723, 703, -723, 500, -723, -723, 705, -723, + -723, -723, -723, -723, 496, -723, -723, -723, -627, -385, + 227, 719, 720, 724, 499, -311, 227, 592, 726, 732, + 733, -723, -311, 602, -723, -723, 590, -723, 264, -723, + 227, -311, 520, 264, 264, 485, -723, 630, 264, -120, + 7, 81, 82, 83, 11, 65, 628, 507, 506, 71, + 72, 240, 500, 788, 75, -723, 73, 74, 76, 35, + 36, 79, 80, 129, 130, 131, 132, 133, 84, 33, + 32, 114, 113, 115, 116, 228, 240, 23, 240, 240, + -311, 228, -102, 10, 53, 9, 12, 118, 117, 119, + 108, 64, 110, 109, 111, 228, 112, 120, 121, 227, + 104, 105, 49, 50, 48, 227, 636, -723, 803, -321, + 240, 606, 675, 814, -723, 638, -321, 819, 240, -719, + 821, 673, 824, -723, 45, -321, 829, 38, 830, 834, + 66, 67, -321, 858, 68, 862, 40, 863, -294, -321, + 52, 876, -723, 558, 264, 558, 853, 854, -321, 24, + 855, 120, 121, 888, 102, 90, 93, 94, 892, 95, + 97, 96, 98, 910, 228, 913, 914, 91, 101, 240, + 228, 917, -723, 240, -321, 85, 261, 92, 106, 107, + 263, 262, 46, 47, 333, 81, 82, 83, 11, 65, + 926, 943, 944, 71, 72, 945, 962, -321, 75, 964, + 73, 74, 76, 35, 36, 79, 80, 256, 300, 970, + 972, 974, 84, 33, 32, 114, 113, 115, 116, 572, + 1159, 23, 488, 487, 486, 574, 489, 10, 53, 335, + 12, 118, 117, 119, 108, 64, 110, 109, 111, 814, + 112, 120, 121, 240, 104, 105, 49, 50, 48, 264, + 268, 269, 270, 271, 281, 282, 276, 277, 272, 273, + -320, 257, 258, 306, 306, 274, 275, -320, 45, 814, + 255, 337, -720, 264, 66, 67, -320, 892, 68, 987, + 40, 261, 988, 267, 52, 263, 262, 240, 259, 260, + 280, 279, 265, 24, 266, 240, 998, 240, 102, 90, + 93, 94, 227, 95, 97, 96, 98, -295, 240, 1164, + 1009, 91, 101, 1013, 278, -293, 1017, 700, 1162, 85, + 718, 92, 106, 107, 1020, -320, 46, 47, 7, 81, + 82, 83, 11, 65, 1022, 1024, 1026, 71, 72, 1026, + 240, 774, 75, 240, 73, 74, 76, 35, 36, 79, + 80, 129, 130, 131, 132, 133, 84, 33, 32, 114, + 113, 115, 116, 240, 1054, 23, 1057, 228, 925, 972, + 677, 10, 53, 9, 12, 118, 117, 119, 108, 64, + 110, 109, 111, 1069, 112, 120, 121, 240, 104, 105, + 49, 50, 48, 264, 268, 269, 270, 271, 281, 282, + 276, 277, 272, 273, -320, 257, 258, 814, 1086, 274, + 275, -320, 45, 1088, 1093, 38, -720, 1094, 66, 67, + -320, 1099, 68, 1100, 40, 261, 1101, 267, 52, 263, + 262, -296, 259, 260, 280, 279, 265, 24, 266, 1114, + 1115, 1116, 102, 90, 93, 94, 227, 95, 97, 96, + 98, 240, 240, 1188, 240, 91, 101, 240, 278, 240, + -265, 240, 638, 85, 925, 92, 106, 107, 1123, -320, + 46, 47, 333, 81, 82, 83, 11, 65, 240, 1129, + 1130, 71, 72, 1132, 700, 1135, 75, 1138, 73, 74, + 76, 35, 36, 79, 80, 129, 130, 131, 132, 133, + 84, 33, 32, 114, 113, 115, 116, 1140, 1142, 23, + 240, 228, -385, 1154, 677, 10, 53, 335, 12, 118, + 117, 119, 108, 64, 110, 109, 111, 1165, 112, 120, + 121, 1166, 104, 105, 49, 50, 48, 264, 268, 269, + 270, 271, 281, 282, 276, 277, 272, 273, 227, 257, + 258, 1026, 1026, 274, 275, 1188, 45, 1026, 1173, 38, + 496, 1186, 66, 67, 638, 1189, 68, 1194, 40, 261, + 499, 267, 52, 263, 262, 1195, 259, 260, 280, 279, + 265, 24, 266, 694, 1115, 1205, 102, 90, 93, 94, + 1205, 95, 97, 96, 98, 700, 1208, 1210, 1212, 91, + 101, 1214, 278, 507, 506, 1214, 240, 85, 500, 92, + 106, 107, 1026, 228, 46, 47, 333, 81, 82, 83, + 11, 65, 1205, -720, -719, 71, 72, 1231, 1214, 1214, + 75, 1214, 73, 74, 76, 35, 36, 79, 80, 129, + 130, 131, 132, 133, 84, 33, 32, 114, 113, 115, + 116, 1214, nil, 23, nil, nil, nil, nil, 889, 10, + 53, 335, 12, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 49, 50, + 48, 264, 268, 269, 270, 271, 281, 282, 276, 277, + 272, 273, nil, 257, 258, nil, nil, 274, 275, nil, + 45, nil, nil, 38, nil, nil, 66, 67, nil, nil, + 68, nil, 40, 261, nil, 267, 52, 263, 262, nil, + 259, 260, 280, 279, 265, 24, 266, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, 278, nil, nil, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 46, 47, + 333, 81, 82, 83, 11, 65, nil, nil, nil, 71, + 72, nil, nil, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, nil, nil, nil, nil, nil, 84, 33, + 32, 114, 113, 115, 116, nil, nil, 23, nil, nil, + nil, nil, 918, 10, 53, 335, 12, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 49, 50, 48, 264, 268, 269, 270, 271, + 281, 282, 276, 277, 272, 273, nil, 257, 258, nil, + nil, 274, 275, nil, 45, nil, nil, 38, nil, nil, + 66, 67, nil, nil, 68, nil, 40, 261, nil, 267, + 52, 263, 262, nil, 259, 260, 280, 279, 265, 24, + 266, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + 278, nil, nil, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 46, 47, 333, 81, 82, 83, 11, 65, + nil, nil, nil, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 114, 113, 115, 116, nil, + 1159, 23, 488, 487, 486, nil, 489, 10, 53, 335, + 12, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 49, 50, 48, 264, + 268, 269, 270, 271, 281, 282, 276, 277, 272, 273, + nil, 257, 258, nil, nil, 274, 275, nil, 45, nil, + nil, 38, nil, nil, 66, 67, nil, nil, 68, nil, + 40, 261, nil, 267, 52, 263, 262, nil, 259, 260, + 280, 279, 265, 24, 266, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, 278, nil, nil, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 46, 47, 333, 81, + 82, 83, 11, 65, nil, nil, nil, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 114, + 113, 115, 116, nil, nil, 23, nil, nil, nil, nil, + nil, 10, 53, 335, 12, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 49, 50, 48, 264, 268, 269, 270, 271, 281, 282, + 276, 277, 272, 273, nil, 257, 258, nil, nil, 274, + 275, nil, 45, nil, nil, 337, nil, nil, 66, 67, + nil, nil, 68, nil, 40, 261, nil, 267, 52, 263, + 262, nil, 259, 260, 280, 279, 265, 24, 266, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, 240, 278, nil, + nil, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 46, 47, 333, 81, 82, 83, 11, 65, nil, nil, + nil, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 114, 113, 115, 116, nil, nil, 23, + nil, nil, nil, nil, nil, 10, 53, 335, 12, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 49, 50, 48, 264, 268, 269, + 270, 271, 281, 282, 276, 277, 272, 273, nil, 257, + 258, nil, nil, 274, 275, nil, 45, nil, nil, 337, + nil, nil, 66, 67, nil, nil, 68, nil, 40, 261, + nil, 267, 52, 263, 262, nil, 259, 260, 280, 279, + 265, 24, 266, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, 278, nil, nil, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 46, 47, 333, 81, 82, 83, + 11, 65, nil, nil, nil, 71, 72, nil, nil, nil, + 75, nil, 73, 74, 76, 35, 36, 79, 80, nil, + nil, nil, nil, nil, 84, 33, 32, 114, 113, 115, + 116, nil, nil, 23, nil, nil, nil, nil, nil, 10, + 53, 335, 12, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 49, 50, + 48, 264, 268, 269, 270, 271, 281, 282, 276, 277, + 272, 273, nil, 257, 258, nil, nil, 274, 275, nil, + 45, nil, nil, 38, nil, nil, 66, 67, nil, nil, + 68, nil, 40, 261, nil, 267, 52, 263, 262, nil, + 259, 260, 280, 279, 265, 24, 266, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, 278, nil, nil, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 46, 47, + 333, 81, 82, 83, 11, 65, nil, nil, nil, 71, + 72, nil, nil, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, nil, nil, nil, nil, nil, 84, 33, + 32, 114, 113, 115, 116, nil, nil, 23, nil, nil, + nil, nil, nil, 10, 53, 335, 12, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 49, 50, 48, 264, 268, 269, 270, 271, + 281, 282, 276, 277, 272, 273, nil, 257, 258, nil, + nil, 274, 275, nil, 45, nil, nil, 38, nil, nil, + 66, 67, nil, nil, 68, nil, 40, 261, nil, 267, + 52, 263, 262, nil, 259, 260, 280, 279, 265, 24, + 266, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + 278, nil, nil, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 46, 47, 333, 81, 82, 83, 11, 65, + nil, nil, nil, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 114, 113, 115, 116, nil, + nil, 23, nil, nil, nil, nil, nil, 10, 53, 335, + 12, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 49, 50, 48, 264, + 268, 269, 270, 271, 281, 282, 276, 277, 272, 273, + nil, 257, 258, nil, nil, 274, 275, nil, 45, nil, + nil, 38, nil, nil, 66, 67, nil, nil, 68, nil, + 40, 261, nil, 267, 52, 263, 262, nil, 259, 260, + 280, 279, 265, 24, 266, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, 278, nil, nil, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 46, 47, 333, 81, + 82, 83, 11, 65, nil, nil, nil, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 114, + 113, 115, 116, nil, nil, 23, nil, nil, nil, nil, + nil, 10, 53, 335, 12, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 49, 50, 48, 264, 268, 269, 270, 271, 281, 282, + 276, 277, 272, 273, nil, 257, 258, nil, nil, 274, + 275, nil, 45, nil, nil, 38, nil, nil, 66, 67, + nil, nil, 68, nil, 40, 261, nil, 267, 52, 263, + 262, nil, 259, 260, 280, 279, 265, 24, 266, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, 278, nil, + nil, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 46, 47, 333, 81, 82, 83, 11, 65, nil, nil, + nil, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 114, 113, 115, 116, nil, nil, 23, + nil, nil, nil, nil, nil, 10, 53, 335, 12, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 49, 50, 48, 264, 268, 269, + 270, 271, 281, 282, 276, 277, 272, 273, nil, 257, + 258, nil, nil, 274, 275, nil, 45, nil, nil, 38, + nil, nil, 66, 67, nil, nil, 68, nil, 40, 261, + nil, 267, 52, 263, 262, nil, 259, 260, 280, 279, + 265, 24, 266, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, 278, nil, nil, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 46, 47, 333, 81, 82, 83, + 11, 65, nil, nil, nil, 71, 72, nil, nil, nil, + 75, nil, 73, 74, 76, 35, 36, 79, 80, nil, + nil, nil, nil, nil, 84, 33, 32, 114, 113, 115, + 116, nil, nil, 23, nil, nil, nil, nil, nil, 10, + 53, 335, 12, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 49, 50, + 48, 264, 268, 269, 270, 271, 281, 282, 276, 277, + 272, 273, nil, 257, 258, nil, nil, 274, 275, nil, + 45, nil, nil, 38, nil, nil, 66, 67, nil, nil, + 68, nil, 40, 261, nil, 267, 52, 263, 262, nil, + 259, 260, 280, 279, 265, 24, 266, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, 278, nil, nil, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 46, 47, + 333, 81, 82, 83, 11, 65, nil, nil, nil, 71, + 72, nil, nil, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, nil, nil, nil, nil, nil, 84, 33, + 32, 114, 113, 115, 116, nil, 491, 23, 488, 487, + 486, nil, 489, 10, 53, 335, 12, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 49, 50, 48, 491, nil, 488, 487, 486, + nil, 489, nil, 710, nil, nil, 264, nil, nil, nil, + nil, nil, 714, nil, 45, nil, nil, 38, nil, nil, + 66, 67, nil, nil, 68, 491, 40, 488, 487, 486, + 52, 489, 710, nil, nil, nil, nil, nil, 261, 24, + nil, 714, 263, 262, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 710, nil, nil, 85, nil, 92, 106, 107, + nil, 714, 46, 47, 333, 81, 82, 83, 11, 65, + nil, nil, nil, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 114, 113, 115, 116, nil, + nil, 23, nil, nil, nil, nil, nil, 10, 53, 335, + 12, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 49, 50, 48, 264, + 268, 269, 270, 271, 281, 282, 276, 277, 272, 273, + nil, -745, -745, nil, nil, 274, 275, nil, 45, nil, + nil, 38, nil, nil, 66, 67, nil, 264, 68, nil, + 40, 261, nil, 267, 52, 263, 262, nil, 259, 260, + 280, 279, 265, 24, 266, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, 261, + nil, 91, 101, 263, 262, nil, 259, 260, nil, 85, + nil, 92, 106, 107, nil, nil, 46, 47, 333, 81, + 82, 83, 11, 65, nil, nil, nil, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 114, + 113, 115, 116, nil, nil, 23, nil, nil, nil, nil, + nil, 10, 53, 335, 12, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 49, 50, 48, 264, 268, 269, 270, 271, 281, 282, + 276, 277, 272, 273, nil, -745, -745, nil, nil, 274, + 275, nil, 45, nil, nil, 38, nil, nil, 66, 67, + nil, 264, 68, nil, 40, 261, nil, 267, 52, 263, + 262, nil, 259, 260, 280, 279, 265, 24, 266, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, 261, nil, 91, 101, 263, 262, nil, + 259, 260, nil, 85, nil, 92, 106, 107, nil, nil, + 46, 47, 333, 81, 82, 83, 11, 65, nil, nil, + nil, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 114, 113, 115, 116, nil, nil, 23, + nil, nil, nil, nil, nil, 10, 53, 335, 12, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 49, 50, 48, 264, 268, 269, + 270, 271, 281, 282, 276, 277, 272, 273, nil, -745, + -745, nil, nil, 274, 275, nil, 45, nil, nil, 38, + nil, nil, 66, 67, nil, nil, 68, nil, 40, 261, + nil, 267, 52, 263, 262, nil, 259, 260, 280, 279, + 265, 24, 266, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, 491, nil, 488, 487, 486, 85, 489, 92, + 106, 107, nil, nil, 46, 47, 333, 81, 82, 83, + 11, 65, nil, nil, nil, 71, 72, nil, nil, nil, + 75, nil, 73, 74, 76, 35, 36, 79, 80, 710, + nil, nil, nil, nil, 84, 33, 32, 114, 113, 115, + 116, nil, nil, 23, nil, nil, nil, nil, nil, 10, + 53, 335, 12, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 49, 50, + 48, 264, 268, 269, 270, 271, 281, 282, 276, 277, + 272, 273, nil, -745, -745, nil, nil, 274, 275, nil, + 45, nil, nil, 38, nil, nil, 66, 67, nil, nil, + 68, nil, 40, 261, nil, 267, 52, 263, 262, nil, + 259, 260, 280, 279, 265, 24, 266, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, 491, nil, 488, 487, + 486, 85, 489, 92, 106, 107, nil, nil, 46, 47, + 333, 81, 82, 83, 11, 65, nil, nil, nil, 71, + 72, nil, nil, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, 710, nil, nil, nil, nil, 84, 33, + 32, 114, 113, 115, 116, nil, 491, 23, 488, 487, + 486, nil, 489, 10, 53, 335, 12, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 49, 50, 48, 264, -745, -745, -745, -745, + 281, 282, nil, 710, -745, -745, nil, nil, nil, nil, + nil, 274, 275, nil, 45, nil, nil, 38, nil, nil, + 66, 67, nil, nil, 68, nil, 40, 261, nil, 267, + 52, 263, 262, nil, 259, 260, 280, 279, 265, 24, + 266, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, nil, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 46, 47, 333, 81, 82, 83, 11, 65, + nil, nil, nil, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 114, 113, 115, 116, nil, + nil, 23, nil, nil, nil, nil, nil, 10, 53, 335, + 12, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 49, 50, 48, 264, + -745, -745, -745, -745, 281, 282, nil, nil, -745, -745, + nil, nil, nil, nil, nil, 274, 275, nil, 45, nil, + nil, 38, nil, nil, 66, 67, nil, nil, 68, nil, + 40, 261, nil, 267, 52, 263, 262, nil, 259, 260, + 280, 279, 265, 24, 266, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, nil, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 46, 47, 333, 81, + 82, 83, 11, 65, nil, nil, nil, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 114, + 113, 115, 116, nil, nil, 23, nil, nil, nil, nil, + nil, 10, 53, 335, 12, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 49, 50, 48, 264, -745, -745, -745, -745, 281, 282, + nil, nil, -745, -745, nil, nil, nil, nil, nil, 274, + 275, nil, 45, nil, nil, 38, nil, nil, 66, 67, + nil, nil, 68, nil, 40, 261, nil, 267, 52, 263, + 262, nil, 259, 260, 280, 279, 265, 24, 266, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + nil, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 46, 47, 333, 81, 82, 83, 11, 65, nil, nil, + nil, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 114, 113, 115, 116, nil, nil, 23, + nil, nil, nil, nil, nil, 10, 53, 335, 12, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 49, 50, 48, 264, -745, -745, + -745, -745, 281, 282, nil, nil, -745, -745, nil, nil, + nil, nil, nil, 274, 275, nil, 45, nil, nil, 38, + nil, nil, 66, 67, nil, nil, 68, nil, 40, 261, + nil, 267, 52, 263, 262, nil, 259, 260, 280, 279, + 265, 24, 266, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, nil, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 46, 47, 333, 81, 82, 83, + 11, 65, nil, nil, nil, 71, 72, nil, nil, nil, + 75, nil, 73, 74, 76, 35, 36, 79, 80, nil, + nil, nil, nil, nil, 84, 33, 32, 114, 113, 115, + 116, nil, nil, 23, nil, nil, nil, nil, nil, 10, + 53, 335, 12, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 49, 50, + 48, 264, -745, -745, -745, -745, 281, 282, nil, nil, + -745, -745, nil, nil, nil, nil, nil, 274, 275, nil, + 45, nil, nil, 38, nil, nil, 66, 67, nil, nil, + 68, nil, 40, 261, nil, 267, 52, 263, 262, nil, + 259, 260, 280, 279, 265, 24, 266, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, nil, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 46, 47, + 333, 81, 82, 83, 11, 65, nil, nil, nil, 71, + 72, nil, nil, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, nil, nil, nil, nil, nil, 84, 33, + 32, 114, 113, 115, 116, nil, nil, 23, nil, nil, + nil, nil, nil, 10, 53, 335, 12, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 49, 50, 48, 264, -745, -745, -745, -745, + 281, 282, nil, nil, -745, -745, nil, nil, nil, nil, + nil, 274, 275, nil, 45, nil, nil, 38, nil, nil, + 66, 67, nil, nil, 68, nil, 40, 261, nil, 267, + 52, 263, 262, nil, 259, 260, 280, 279, 265, 24, + 266, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, nil, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 46, 47, 333, 81, 82, 83, 11, 65, + nil, nil, nil, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 114, 113, 115, 116, nil, + nil, 23, nil, nil, nil, nil, nil, 10, 53, 335, + 12, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 49, 50, 48, 264, + 268, 269, 270, 271, 281, 282, nil, nil, 272, 273, + nil, nil, nil, nil, nil, 274, 275, nil, 45, nil, + nil, 38, nil, nil, 66, 67, nil, nil, 68, nil, + 40, 261, nil, 267, 52, 263, 262, nil, 259, 260, + 280, 279, 265, 24, 266, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, nil, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 46, 47, 333, 81, + 82, 83, 11, 65, nil, nil, nil, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 114, + 113, 115, 116, nil, nil, 23, nil, nil, nil, nil, + nil, 10, 53, 335, 12, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 49, 50, 48, 264, 268, 269, 270, 271, 281, 282, + 276, nil, 272, 273, nil, nil, nil, nil, nil, 274, + 275, nil, 45, nil, nil, 38, nil, nil, 66, 67, + nil, nil, 68, nil, 40, 261, nil, 267, 52, 263, + 262, nil, 259, 260, 280, 279, 265, 24, 266, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + nil, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 46, 47, 333, 81, 82, 83, 11, 65, nil, nil, + nil, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 114, 113, 115, 116, nil, nil, 23, + nil, nil, nil, nil, nil, 10, 53, 335, 12, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 49, 50, 48, 264, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 274, 275, nil, 45, nil, nil, 38, + nil, nil, 66, 67, nil, nil, 68, nil, 40, 261, + nil, 267, 52, 263, 262, nil, 259, 260, nil, nil, + 265, 24, 266, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, nil, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 46, 47, 81, 82, 83, 11, + 65, nil, nil, nil, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 114, 113, 115, 116, + nil, nil, 23, nil, nil, nil, nil, nil, 10, 53, + 9, 12, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, 49, 50, 48, + 264, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 274, 275, nil, 45, + nil, nil, 38, nil, nil, 66, 67, nil, nil, 68, + nil, 40, 261, nil, 267, 52, 263, 262, nil, 259, + 260, nil, nil, 265, 24, 266, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 35, 36, 79, 80, nil, + nil, nil, nil, nil, 84, 33, 32, 114, 113, 115, + 116, nil, nil, 254, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 49, 50, + 48, 264, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 274, 275, nil, + 245, nil, nil, 253, nil, nil, 66, 67, nil, nil, + 68, nil, nil, 261, nil, 267, 52, 263, 262, nil, + 259, 260, nil, nil, nil, 250, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, nil, nil, + nil, 85, nil, 92, 106, 107, -441, nil, 46, 47, + nil, nil, nil, -441, -441, -441, nil, nil, -441, -441, + -441, 264, -441, nil, nil, nil, nil, nil, nil, nil, + -441, -441, -441, -441, nil, nil, nil, 274, 275, nil, + nil, nil, -441, -441, nil, -441, -441, -441, -441, -441, + nil, nil, nil, 261, nil, 267, nil, 263, 262, nil, + 259, 260, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, -441, -441, -441, -441, -441, -441, -441, -441, + -441, -441, -441, -441, -441, -441, nil, nil, -441, -441, + -441, nil, nil, -441, nil, 306, -441, nil, nil, -441, + -441, nil, -441, nil, -441, nil, -441, nil, -441, -441, + nil, -441, -441, -441, -441, -441, -327, -441, -441, -441, + nil, nil, nil, -327, -327, -327, nil, nil, -327, -327, + -327, nil, -327, -441, 264, nil, -441, -441, nil, -441, + -327, -441, -327, -327, nil, nil, nil, nil, -441, nil, + 274, 275, -327, -327, nil, -327, -327, -327, -327, -327, + nil, nil, nil, nil, nil, nil, 261, nil, nil, nil, + 263, 262, nil, 259, 260, nil, nil, nil, nil, nil, + nil, nil, -327, -327, -327, -327, -327, -327, -327, -327, + -327, -327, -327, -327, -327, -327, nil, nil, -327, -327, + -327, nil, nil, -327, nil, 315, -327, nil, nil, -327, + -327, nil, -327, nil, -327, nil, -327, nil, -327, -327, + nil, -327, -327, -327, -327, -327, nil, -327, nil, -327, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, -327, nil, nil, -327, -327, nil, -327, + nil, -327, 81, 82, 83, nil, 65, nil, -327, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 114, 113, 115, 116, nil, nil, 254, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, 327, 112, 120, 121, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 245, nil, nil, 253, nil, + nil, 66, 67, nil, nil, 68, nil, 324, nil, 322, + nil, 52, nil, nil, 328, nil, nil, nil, nil, nil, + 250, nil, nil, nil, nil, 102, 325, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 114, 113, 115, 116, nil, nil, 254, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, 327, 112, 120, + 121, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 245, nil, nil, 253, + nil, nil, 66, 67, nil, nil, 68, nil, 324, nil, + 322, nil, 52, nil, nil, 328, nil, nil, nil, nil, + nil, 250, nil, nil, nil, nil, 102, 325, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 114, 113, 115, 116, nil, nil, + 254, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, 327, 112, + 120, 121, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 245, nil, nil, + 253, nil, nil, 66, 67, nil, nil, 68, nil, 324, + nil, 322, nil, 52, nil, nil, 328, nil, nil, nil, + nil, nil, 250, nil, nil, nil, nil, 102, 325, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 354, 355, 79, 80, nil, nil, nil, + nil, nil, 84, 349, 357, 114, 113, 115, 116, nil, + nil, 254, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 245, nil, + nil, 253, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 250, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 354, 355, 79, 80, nil, nil, + nil, nil, nil, 84, 349, 357, 114, 113, 115, 116, + nil, nil, 254, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 245, + nil, nil, 253, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 250, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 354, 355, 79, 80, nil, + nil, nil, nil, nil, 84, 349, 357, 114, 113, 115, + 116, nil, nil, 254, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 245, nil, nil, 253, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 250, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 354, 355, 79, 80, + nil, nil, nil, nil, nil, 84, 349, 357, 114, 113, + 115, 116, nil, nil, 254, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 118, 117, 119, 108, 64, 110, + 109, 111, nil, 112, 120, 121, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 245, nil, nil, 253, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 250, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 354, 355, 79, + 80, nil, nil, nil, nil, nil, 84, 349, 357, 114, + 113, 115, 116, nil, nil, 254, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 245, nil, nil, 253, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 250, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + nil, nil, nil, 85, nil, 92, 106, 107, -312, nil, + 46, 47, nil, nil, nil, -312, -312, -312, nil, nil, + -312, -312, -312, nil, -312, nil, nil, nil, nil, nil, + nil, nil, -312, nil, -312, -312, -312, nil, nil, nil, + 114, 113, 115, 116, -312, -312, nil, -312, -312, -312, + -312, -312, nil, nil, nil, nil, 118, 117, 119, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 104, + 105, nil, nil, 358, -312, -312, -312, -312, -312, -312, + -312, -312, -312, -312, -312, -312, -312, -312, nil, nil, + -312, -312, -312, nil, nil, -312, nil, nil, -312, nil, + nil, -312, -312, nil, -312, nil, -312, nil, -312, nil, + -312, -312, nil, -312, -312, -312, -312, -312, nil, -312, + nil, -312, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, -312, 91, 101, -312, -312, + -312, -312, nil, -312, 85, -312, 92, 106, 107, nil, + -312, 81, 82, 83, 11, 65, nil, nil, nil, 71, + 72, nil, nil, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, nil, nil, nil, nil, nil, 84, 33, + 32, 114, 113, 115, 116, nil, nil, 23, nil, nil, + nil, nil, nil, 10, 53, nil, 12, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 38, nil, nil, + 66, 67, nil, nil, 68, nil, 40, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 24, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 354, 355, 79, 80, nil, nil, nil, nil, nil, 84, + 349, 357, 114, 113, 115, 116, nil, nil, 254, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, 327, 112, 120, 121, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 245, nil, nil, 253, nil, + nil, 66, 67, nil, nil, 68, nil, 324, nil, nil, + nil, 52, nil, nil, 328, nil, nil, nil, nil, nil, + 250, nil, nil, nil, nil, 102, 325, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 354, 355, 79, 80, nil, nil, nil, nil, nil, + 84, 349, 357, 114, 113, 115, 116, nil, nil, 254, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, 327, 112, 120, + 121, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 245, nil, nil, 253, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, 328, nil, nil, nil, nil, + nil, 250, nil, nil, nil, nil, 102, 325, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 114, 113, 115, 116, nil, nil, + 23, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, nil, 112, + 120, 121, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 245, nil, nil, + 253, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 24, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 114, 113, 115, 116, nil, + nil, 23, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 245, nil, + nil, 253, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 24, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 114, 113, 115, 116, + nil, nil, 23, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 245, + nil, nil, 253, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 24, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, 126, nil, nil, nil, nil, 125, + 85, nil, 92, 106, 107, nil, nil, 46, 47, 81, + 82, 83, 11, 65, nil, nil, nil, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 114, + 113, 115, 116, nil, nil, 23, nil, nil, nil, nil, + nil, 10, 53, 9, 12, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 38, nil, nil, 66, 67, + nil, nil, 68, nil, 40, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 24, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + nil, nil, 420, 85, nil, 92, 106, 107, nil, nil, + 46, 47, 81, 82, 83, nil, 65, nil, nil, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 114, 113, 115, 116, nil, nil, 23, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, nil, 112, 120, 121, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 245, nil, nil, 253, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 24, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 114, 113, 115, 116, nil, nil, 23, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 245, nil, nil, 253, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 24, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 114, 113, 115, 116, nil, nil, + 23, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, nil, 112, + 120, 121, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 245, nil, nil, + 253, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 24, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 114, 113, 115, 116, nil, + nil, 23, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 245, nil, + nil, 253, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 24, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, nil, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 46, 47, 81, 82, + 83, 11, 65, nil, nil, nil, 71, 72, nil, nil, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 114, 113, + 115, 116, nil, nil, 23, nil, nil, nil, nil, nil, + 10, 53, nil, 12, 118, 117, 119, 108, 64, 110, + 109, 111, nil, 112, 120, 121, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 38, nil, nil, 66, 67, nil, + nil, 68, nil, 40, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 24, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 114, + 113, 115, 116, nil, nil, 254, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 245, nil, nil, 253, nil, nil, 66, 67, + nil, nil, 68, nil, 436, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 250, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, nil, nil, nil, nil, nil, 84, 33, 32, + 114, 113, 115, 116, nil, nil, 254, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 118, 117, 119, 108, + 64, 110, 109, 111, nil, 112, 120, 121, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 245, nil, nil, 253, nil, nil, 66, + 67, nil, nil, 68, nil, 436, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 250, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, nil, nil, nil, nil, nil, 84, 33, + 32, 114, 113, 115, 116, nil, nil, 23, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 245, nil, nil, 253, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 24, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 114, 113, 115, 116, nil, nil, 23, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, nil, 112, 120, 121, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 245, nil, nil, 253, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 24, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 114, 113, 115, 116, nil, nil, 254, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 245, nil, nil, 253, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 250, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 114, 113, 115, 116, nil, nil, + 254, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, 327, 112, + 120, 121, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 245, nil, nil, + 253, nil, nil, 66, 67, nil, nil, 68, nil, 324, + nil, 322, nil, 52, nil, nil, 328, nil, nil, nil, + nil, nil, 250, nil, nil, nil, nil, 102, 325, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 114, 113, 115, 116, nil, + nil, 254, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 245, nil, + nil, 253, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 250, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 114, 113, 115, 116, + nil, nil, 23, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 245, + nil, nil, 253, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 24, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 35, 36, 79, 80, nil, + nil, nil, nil, nil, 84, 33, 32, 114, 113, 115, + 116, nil, nil, 23, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 245, nil, nil, 253, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 24, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, 240, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 354, 355, 79, 80, + nil, nil, nil, nil, nil, 84, 349, 357, 114, 113, + 115, 116, nil, nil, 254, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 118, 117, 119, 108, 64, 110, + 109, 111, nil, 112, 120, 121, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 245, nil, nil, 253, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 250, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 354, 355, 79, + 80, nil, nil, nil, nil, nil, 84, 349, 357, 114, + 113, 115, 116, nil, nil, 254, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 245, nil, nil, 253, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 250, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 354, 355, + 79, 80, nil, nil, nil, nil, nil, 84, 349, 357, + 114, 113, 115, 116, nil, nil, 254, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 118, 117, 119, 108, + 64, 110, 109, 111, nil, 112, 120, 121, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 245, nil, nil, 253, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 250, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 354, + 355, 79, 80, nil, nil, nil, nil, nil, 84, 349, + 357, 114, 113, 115, 116, nil, nil, 254, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 245, nil, nil, 253, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 250, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 354, 355, 79, 80, nil, nil, nil, nil, nil, 84, + 349, 357, 114, 113, 115, 116, nil, nil, 254, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, nil, 112, 120, 121, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 245, nil, nil, 253, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 250, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 354, 355, 79, 80, nil, nil, nil, nil, nil, + 84, 349, 357, 114, 113, 115, 116, nil, nil, 254, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 245, nil, nil, 253, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 250, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 354, 355, 79, 80, nil, nil, nil, nil, + nil, 84, 349, 357, 114, 113, 115, 116, nil, nil, + 254, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, nil, 112, + 120, 121, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 245, nil, nil, + 253, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 250, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 354, 355, 79, 80, nil, nil, nil, + nil, nil, 84, 349, 357, 114, 113, 115, 116, nil, + nil, 254, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 245, nil, + nil, 253, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 250, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 354, 355, 79, 80, nil, nil, + nil, nil, nil, 84, 349, 357, 114, 113, 115, 116, + nil, nil, 254, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 245, + nil, nil, 253, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 250, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 354, 355, 79, 80, nil, + nil, nil, nil, nil, 84, 349, 357, 114, 113, 115, + 116, nil, nil, 254, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 245, nil, nil, 253, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 250, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 354, 355, 79, 80, + nil, nil, nil, nil, nil, 84, 349, 357, 114, 113, + 115, 116, nil, nil, 254, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 118, 117, 119, 108, 64, 110, + 109, 111, nil, 112, 120, 121, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 245, nil, nil, 253, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 250, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 354, 355, 79, + 80, nil, nil, nil, nil, nil, 84, 349, 357, 114, + 113, 115, 116, nil, nil, 254, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 245, nil, nil, 253, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 250, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 354, 355, + 79, 80, nil, nil, nil, nil, nil, 84, 349, 357, + 114, 113, 115, 116, nil, nil, 254, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 118, 117, 119, 108, + 64, 110, 109, 111, nil, 112, 120, 121, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 245, nil, nil, 253, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 250, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 354, + 355, 79, 80, nil, nil, nil, nil, nil, 84, 349, + 357, 114, 113, 115, 116, nil, nil, 254, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 245, nil, nil, 253, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 250, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 354, 355, 79, 80, nil, nil, nil, nil, nil, 84, + 349, 357, 114, 113, 115, 116, nil, nil, 254, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, nil, 112, 120, 121, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 245, nil, nil, 253, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 250, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 354, 355, 79, 80, nil, nil, nil, nil, nil, + 84, 349, 357, 114, 113, 115, 116, nil, nil, 254, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 245, nil, nil, 253, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 250, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 354, 355, 79, 80, nil, nil, nil, nil, + nil, 84, 349, 357, 114, 113, 115, 116, nil, nil, + 254, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, nil, 112, + 120, 121, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 245, nil, nil, + 253, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 250, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 354, 355, 79, 80, nil, nil, nil, + nil, nil, 84, 349, 357, 114, 113, 115, 116, nil, + nil, 254, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 245, nil, + nil, 253, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 250, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 354, 355, 79, 80, nil, nil, + nil, nil, nil, 84, 349, 357, 114, 113, 115, 116, + nil, nil, 254, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 245, + nil, nil, 253, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 250, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 354, 355, 79, 80, nil, + nil, nil, nil, nil, 84, 349, 357, 114, 113, 115, + 116, nil, nil, 254, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 245, nil, nil, 253, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 250, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 354, 355, 79, 80, + nil, nil, nil, nil, nil, 84, 349, 357, 114, 113, + 115, 116, nil, nil, 254, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 118, 117, 119, 108, 64, 110, + 109, 111, nil, 112, 120, 121, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 245, nil, nil, 253, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 250, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 354, 355, 79, + 80, nil, nil, nil, nil, nil, 84, 349, 357, 114, + 113, 115, 116, nil, nil, 254, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 245, nil, nil, 253, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 250, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 354, 355, + 79, 80, nil, nil, nil, nil, nil, 84, 349, 357, + 114, 113, 115, 116, nil, nil, 254, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 118, 117, 119, 108, + 64, 110, 109, 111, nil, 112, 120, 121, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 245, nil, nil, 253, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 250, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 354, + 355, 79, 80, nil, nil, nil, nil, nil, 84, 349, + 357, 114, 113, 115, 116, nil, nil, 254, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 245, nil, nil, 253, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 250, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 114, 113, 115, 116, nil, nil, 23, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, nil, 112, 120, 121, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 245, nil, nil, 253, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 24, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 114, 113, 115, 116, nil, nil, 254, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, 327, 112, 120, + 121, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 245, nil, nil, 253, + nil, nil, 66, 67, nil, nil, 68, nil, 324, nil, + 322, nil, 52, nil, nil, 328, nil, nil, nil, nil, + nil, 250, nil, nil, nil, nil, 102, 325, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 560, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 114, 113, 115, 116, nil, nil, + 254, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, 327, 112, + 120, 121, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 245, nil, nil, + 253, nil, nil, 66, 67, nil, nil, 68, nil, 324, + nil, 322, nil, 52, nil, nil, 328, nil, nil, nil, + nil, nil, 250, nil, nil, nil, nil, 102, 325, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 114, 113, 115, 116, nil, + nil, 254, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, 327, + 112, 120, 121, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 245, nil, + nil, 253, nil, nil, 66, 67, nil, nil, 68, nil, + 324, nil, 322, nil, 52, nil, nil, 328, nil, nil, + nil, nil, nil, 250, nil, nil, nil, nil, 102, 325, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, 240, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 354, 355, 79, 80, nil, nil, + nil, nil, nil, 84, 349, 357, 114, 113, 115, 116, + nil, nil, 254, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 245, + nil, nil, 253, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 250, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 354, 355, 79, 80, nil, + nil, nil, nil, nil, 84, 349, 357, 114, 113, 115, + 116, nil, nil, 254, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 245, nil, nil, 253, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 250, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 354, 355, 79, 80, + nil, nil, nil, nil, nil, 84, 349, 357, 114, 113, + 115, 116, nil, nil, 254, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 118, 117, 119, 108, 64, 110, + 109, 111, nil, 112, 120, 121, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 245, nil, nil, 253, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 250, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 354, 355, 79, + 80, nil, nil, nil, nil, nil, 84, 349, 357, 114, + 113, 115, 116, nil, nil, 254, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 245, nil, nil, 253, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 250, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + nil, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 46, 47, 81, 82, 83, 11, 65, nil, nil, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 114, 113, 115, 116, nil, nil, 23, nil, + nil, nil, nil, nil, 10, 53, nil, 12, 118, 117, + 119, 108, 64, 110, 109, 111, nil, 112, 120, 121, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 38, nil, + nil, 66, 67, nil, nil, 68, nil, 40, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 24, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 354, 355, 79, 80, nil, nil, nil, nil, nil, + 84, 349, 357, 114, 113, 115, 116, nil, nil, 254, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 245, nil, nil, 253, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 250, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 114, 113, 115, 116, nil, nil, + 23, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, nil, 112, + 120, 121, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 245, nil, nil, + 253, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 24, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 114, 113, 115, 116, nil, + nil, 23, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 245, nil, + nil, 253, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 24, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 354, 355, 79, 80, nil, nil, + nil, nil, nil, 84, 349, 357, 114, 113, 115, 116, + nil, nil, 254, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 245, + nil, nil, 253, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 250, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, nil, nil, nil, + 85, nil, 92, 106, 107, -275, nil, 46, 47, nil, + nil, nil, -275, -275, -275, nil, nil, -275, -275, -275, + nil, -275, nil, nil, nil, nil, nil, nil, nil, -275, + -275, -275, -275, nil, nil, nil, nil, nil, nil, nil, + nil, -275, -275, nil, -275, -275, -275, -275, -275, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, -275, -275, -275, -275, -275, -275, -275, -275, -275, + -275, -275, -275, -275, -275, nil, nil, -275, -275, -275, + nil, nil, -275, nil, 306, -275, nil, nil, -275, -275, + nil, -275, nil, -275, nil, -275, nil, -275, -275, nil, + -275, -275, -275, -275, -275, nil, -275, -275, -275, 491, + nil, 488, 487, 486, 496, 489, nil, nil, nil, nil, + nil, nil, -275, nil, 499, -275, -275, -724, -275, nil, + -275, nil, nil, nil, -724, -724, -724, -275, nil, -724, + -724, -724, nil, -724, nil, nil, 494, nil, nil, nil, + nil, -724, -724, -724, -724, -724, nil, 507, 506, nil, + nil, nil, 500, -724, -724, nil, -724, -724, -724, -724, + -724, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, -724, -724, -724, -724, -724, -724, -724, + -724, -724, -724, -724, -724, -724, -724, nil, nil, -724, + -724, -724, nil, nil, -724, nil, nil, -724, nil, nil, + -724, -724, nil, -724, nil, -724, nil, -724, nil, -724, + -724, nil, -724, -724, -724, -724, -724, nil, -724, -724, + -724, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, -724, nil, nil, -724, -724, -724, + -724, nil, -724, -725, -724, nil, nil, nil, nil, -724, + -725, -725, -725, nil, nil, -725, -725, -725, nil, -725, + nil, nil, nil, nil, nil, nil, nil, -725, -725, -725, + -725, -725, nil, nil, nil, nil, nil, nil, nil, -725, + -725, nil, -725, -725, -725, -725, -725, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, -725, + -725, -725, -725, -725, -725, -725, -725, -725, -725, -725, + -725, -725, -725, nil, nil, -725, -725, -725, nil, nil, + -725, nil, nil, -725, nil, nil, -725, -725, nil, -725, + nil, -725, nil, -725, nil, -725, -725, nil, -725, -725, + -725, -725, -725, nil, -725, -725, -725, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + -725, nil, nil, -725, -725, -725, -725, nil, -725, nil, + -725, nil, 81, 82, 83, -725, 65, nil, nil, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 114, 113, 115, 116, nil, nil, 254, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, nil, 112, 120, 121, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 245, nil, nil, 253, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 250, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 354, 355, 79, 80, nil, nil, nil, nil, nil, + 84, 349, 357, 114, 113, 115, 116, nil, nil, 254, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 245, nil, nil, 253, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 250, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 114, 113, 115, 116, nil, nil, + 254, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, nil, 112, + 120, 121, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 245, nil, nil, + 253, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 250, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 114, 113, 115, 116, nil, + nil, 254, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, 327, + 112, 120, 121, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 245, nil, + nil, 253, nil, nil, 66, 67, nil, nil, 68, nil, + 324, nil, 322, nil, 52, nil, nil, 328, nil, nil, + nil, nil, nil, 250, nil, nil, nil, nil, 102, 325, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 354, 355, 79, 80, nil, nil, + nil, nil, nil, 84, 349, 357, 114, 113, 115, 116, + nil, nil, 254, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 245, + nil, nil, 253, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 250, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 354, 355, 79, 80, nil, + nil, nil, nil, nil, 84, 349, 357, 114, 113, 115, + 116, nil, nil, 254, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 245, nil, nil, 253, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 250, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 354, 355, 79, 80, + nil, nil, nil, nil, nil, 84, 349, 357, 114, 113, + 115, 116, nil, nil, 254, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 118, 117, 119, 108, 64, 110, + 109, 111, nil, 112, 120, 121, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 245, nil, nil, 253, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 250, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, nil, + nil, nil, 85, nil, 92, 106, 107, -275, nil, 46, + 47, nil, nil, nil, -275, -275, -275, nil, nil, -275, + -275, -275, 491, -275, 488, 487, 486, 496, 489, nil, + nil, -275, -275, -275, nil, nil, nil, 499, nil, nil, + nil, nil, nil, -275, -275, nil, -275, -275, -275, -275, + -275, nil, 491, nil, 488, 487, 486, 496, 489, 494, + 644, nil, nil, nil, nil, nil, nil, 499, 504, 503, + 507, 506, nil, nil, nil, 500, nil, 491, nil, 488, + 487, 486, 496, 489, -275, nil, nil, nil, nil, 494, + nil, -275, 499, nil, nil, nil, 306, -275, 504, 503, + 507, 506, nil, nil, nil, 500, nil, nil, nil, nil, + nil, nil, nil, nil, 494, 485, nil, nil, nil, -275, + -275, nil, nil, 504, 503, 507, 506, nil, nil, nil, + 500, nil, nil, nil, -275, nil, nil, -275, nil, 81, + 82, 83, -275, 65, nil, 485, nil, 71, 72, -275, + nil, nil, 75, nil, 73, 74, 76, 354, 355, 79, + 80, nil, nil, nil, nil, nil, 84, 349, 357, 114, + 113, 115, 116, nil, nil, 254, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 245, nil, nil, 253, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 250, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 354, 355, + 79, 80, nil, nil, nil, nil, nil, 84, 349, 357, + 114, 113, 115, 116, nil, nil, 254, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 118, 117, 119, 108, + 64, 110, 109, 111, 327, 112, 120, 121, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 245, nil, nil, 253, nil, nil, 66, + 67, nil, nil, 68, nil, 797, nil, 322, nil, 52, + nil, nil, 328, nil, nil, nil, nil, nil, 250, nil, + nil, nil, nil, 102, 325, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 354, + 355, 79, 80, nil, nil, nil, nil, nil, 84, 349, + 357, 114, 113, 115, 116, nil, nil, 254, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 118, 117, 119, + 108, 64, 110, 109, 111, 327, 112, 120, 121, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 245, nil, nil, 253, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, 322, nil, + 52, nil, nil, 328, nil, nil, nil, nil, nil, 250, + nil, nil, nil, nil, 102, 325, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 354, 355, 79, 80, nil, nil, nil, nil, nil, 84, + 349, 357, 114, 113, 115, 116, nil, nil, 254, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, nil, 112, 120, 121, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 245, nil, nil, 253, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 250, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, nil, nil, nil, 85, nil, 92, 106, + 107, nil, nil, 46, 47, 81, 82, 83, 11, 65, + nil, nil, nil, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 114, 113, 115, 116, nil, + nil, 23, nil, nil, nil, nil, nil, 10, 53, 335, + 12, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 38, nil, nil, 66, 67, nil, nil, 68, nil, + 40, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 24, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, nil, nil, 420, 85, + nil, 92, 106, 107, nil, nil, 46, 47, 81, 82, + 83, nil, 65, nil, nil, nil, 71, 72, nil, nil, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 114, 113, + 115, 116, nil, nil, 254, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 118, 117, 119, 108, 64, 110, + 109, 111, 327, 112, 120, 121, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 245, nil, nil, 253, nil, nil, 66, 67, nil, + nil, 68, nil, 324, nil, 322, nil, 52, nil, nil, + 328, nil, nil, nil, nil, nil, 250, nil, nil, nil, + nil, 102, 325, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 354, 355, 79, + 80, nil, nil, nil, nil, nil, 84, 349, 357, 114, + 113, 115, 116, nil, nil, 254, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 245, nil, nil, 253, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 250, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 354, 355, + 79, 80, nil, nil, nil, nil, nil, 84, 349, 357, + 114, 113, 115, 116, nil, nil, 254, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 118, 117, 119, 108, + 64, 110, 109, 111, nil, 112, 120, 121, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 245, nil, nil, 253, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 250, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 354, + 355, 79, 80, nil, nil, nil, nil, nil, 84, 349, + 357, 114, 113, 115, 116, nil, nil, 254, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 245, nil, nil, 253, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 250, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 354, 355, 79, 80, nil, nil, nil, nil, nil, 84, + 349, 357, 114, 113, 115, 116, nil, nil, 254, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, 327, 112, 120, 121, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 245, nil, nil, 253, nil, + nil, 66, 67, nil, nil, 68, nil, 797, nil, nil, + nil, 52, nil, nil, 328, nil, nil, nil, nil, nil, + 250, nil, nil, nil, nil, 102, 325, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 354, 355, 79, 80, nil, nil, nil, nil, nil, + 84, 349, 357, 114, 113, 115, 116, nil, nil, 254, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, 327, 112, 120, + 121, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 245, nil, nil, 253, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, 328, nil, nil, nil, nil, + nil, 250, nil, nil, nil, nil, 102, 325, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 354, 355, 79, 80, nil, nil, nil, nil, + nil, 84, 349, 357, 114, 113, 115, 116, nil, nil, + 254, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, nil, 112, + 120, 121, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 245, nil, nil, + 253, nil, nil, 66, 67, nil, nil, 68, nil, 324, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 250, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 114, 113, 115, 116, nil, + nil, 254, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, 327, + 112, 120, 121, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 245, nil, + nil, 253, nil, nil, 66, 67, nil, nil, 68, nil, + 324, nil, 322, nil, 52, nil, nil, 328, nil, nil, + nil, nil, nil, 250, nil, nil, nil, nil, 102, 325, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 114, 113, 115, 116, + nil, nil, 254, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + 327, 112, 120, 121, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 245, + nil, nil, 253, nil, nil, 66, 67, nil, nil, 68, + nil, 324, nil, 322, nil, 52, nil, nil, 328, nil, + nil, nil, nil, nil, 250, nil, nil, nil, nil, 102, + 325, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, nil, nil, nil, + 85, nil, 92, 106, 107, nil, nil, 46, 47, 81, + 82, 83, 11, 65, nil, nil, nil, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 114, + 113, 115, 116, nil, nil, 23, nil, nil, nil, nil, + nil, 10, 53, nil, 12, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 38, nil, nil, 66, 67, + nil, nil, 68, nil, 40, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 24, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 354, 355, + 79, 80, nil, nil, nil, nil, nil, 84, 349, 357, + 114, 113, 115, 116, nil, nil, 254, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 118, 117, 119, 108, + 64, 110, 109, 111, nil, 112, 120, 121, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 245, nil, nil, 253, nil, nil, 66, + 67, nil, nil, 68, nil, 867, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 250, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, nil, nil, nil, nil, nil, 84, 33, + 32, 114, 113, 115, 116, nil, nil, 254, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 245, nil, nil, 253, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 250, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 114, 113, 115, 116, nil, nil, 254, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, 327, 112, 120, 121, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 245, nil, nil, 253, nil, + nil, 66, 67, nil, nil, 68, nil, 324, nil, 322, + nil, 52, nil, nil, 328, nil, nil, nil, nil, nil, + 250, nil, nil, nil, nil, 102, 325, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, nil, nil, nil, 85, nil, 92, 106, + 107, nil, nil, 46, 47, 81, 82, 83, 11, 65, + nil, nil, nil, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 114, 113, 115, 116, nil, + nil, 23, nil, nil, nil, nil, nil, 10, 53, nil, + 12, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 38, nil, nil, 66, 67, nil, nil, 68, nil, + 40, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 24, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 354, 355, 79, 80, nil, nil, + nil, nil, nil, 84, 349, 357, 114, 113, 115, 116, + nil, nil, 254, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 245, + nil, nil, 253, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 250, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 354, 355, 79, 80, nil, + nil, nil, nil, nil, 84, 349, 357, 114, 113, 115, + 116, nil, nil, 254, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, 327, 112, 120, 121, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 245, nil, nil, 253, nil, nil, 66, 67, nil, nil, + 68, nil, 797, nil, 322, nil, 52, nil, nil, 328, + nil, nil, nil, nil, nil, 250, nil, nil, nil, nil, + 102, 325, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 354, 355, 79, 80, + nil, nil, nil, nil, nil, 84, 349, 357, 114, 113, + 115, 116, nil, nil, 254, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 118, 117, 119, 108, 64, 110, + 109, 111, 327, 112, 120, 121, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 245, nil, nil, 253, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, 322, nil, 52, nil, nil, + 328, nil, nil, nil, nil, nil, 250, nil, nil, nil, + nil, 102, 325, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 114, + 113, 115, 116, nil, nil, 254, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 245, nil, nil, 253, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 250, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, nil, nil, nil, nil, nil, 84, 33, 32, + 114, 113, 115, 116, nil, nil, 254, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 118, 117, 119, 108, + 64, 110, 109, 111, nil, 112, 120, 121, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 245, nil, nil, 253, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 250, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, nil, nil, nil, nil, nil, 84, 33, + 32, 114, 113, 115, 116, nil, nil, 254, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 245, nil, nil, 253, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 250, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 114, 113, 115, 116, nil, nil, 254, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, nil, 112, 120, 121, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 245, nil, nil, 253, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 250, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 354, 355, 79, 80, nil, nil, nil, nil, nil, + 84, 349, 357, 114, 113, 115, 116, nil, nil, 254, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 245, nil, nil, 253, + nil, nil, 66, 67, nil, nil, 68, nil, 436, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 250, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 354, 355, 79, 80, nil, nil, nil, nil, + nil, 84, 349, 357, 114, 113, 115, 116, nil, nil, + 254, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, nil, 112, + 120, 121, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 245, nil, nil, + 253, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 250, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 354, 355, 79, 80, nil, nil, nil, + nil, nil, 84, 349, 357, 114, 113, 115, 116, nil, + nil, 254, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 245, nil, + nil, 253, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 250, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 354, 355, 79, 80, nil, nil, + nil, nil, nil, 84, 349, 357, 114, 113, 115, 116, + nil, nil, 254, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 245, + nil, nil, 253, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 250, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 354, 355, 79, 80, nil, + nil, nil, nil, nil, 84, 349, 357, 114, 113, 115, + 116, nil, nil, 254, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, 327, 112, 120, 121, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 245, nil, nil, 253, nil, nil, 66, 67, nil, nil, + 68, nil, 797, nil, 322, nil, 52, nil, nil, 328, + nil, nil, nil, nil, nil, 250, nil, nil, nil, nil, + 102, 325, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 560, + nil, 75, nil, 73, 74, 76, 354, 355, 79, 80, + nil, nil, nil, nil, nil, 84, 349, 357, 114, 113, + 115, 116, nil, nil, 254, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 118, 117, 119, 108, 64, 110, + 109, 111, nil, 112, 120, 121, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 245, nil, nil, 253, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 250, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 354, 355, 79, + 80, nil, nil, nil, nil, nil, 84, 349, 357, 114, + 113, 115, 116, nil, nil, 254, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 245, nil, nil, 253, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 250, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, nil, nil, nil, nil, nil, 84, 33, 32, + 114, 113, 115, 116, nil, nil, 23, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 118, 117, 119, 108, + 64, 110, 109, 111, nil, 112, 120, 121, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 245, nil, nil, 253, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 24, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, nil, nil, nil, nil, nil, 84, 33, + 32, 114, 113, 115, 116, nil, nil, 23, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 245, nil, nil, 253, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 24, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 354, 355, 79, 80, nil, nil, nil, nil, nil, 84, + 349, 357, 114, 113, 115, 116, nil, nil, 254, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, nil, 112, 120, 121, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 245, nil, nil, 253, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 250, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 114, 113, 115, 116, nil, nil, 254, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 245, nil, nil, 253, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 250, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 354, 355, 79, 80, nil, nil, nil, nil, + nil, 84, 349, 357, 114, 113, 115, 116, nil, nil, + 254, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, nil, 112, + 120, 121, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 245, nil, nil, + 253, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 250, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 354, 355, 79, 80, nil, nil, nil, + nil, nil, 84, 349, 357, 114, 113, 115, 116, nil, + nil, 254, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 245, nil, + nil, 253, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 250, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 354, 355, 79, 80, nil, nil, + nil, nil, nil, 84, 349, 357, 114, 113, 115, 116, + nil, nil, 254, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 245, + nil, nil, 253, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 250, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 354, 355, 79, 80, nil, + nil, nil, nil, nil, 84, 349, 357, 114, 113, 115, + 116, nil, nil, 254, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 245, nil, nil, 253, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 250, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 354, 355, 79, 80, + nil, nil, nil, nil, nil, 84, 349, 357, 114, 113, + 115, 116, nil, nil, 254, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 118, 117, 119, 108, 64, 110, + 109, 111, nil, 112, 120, 121, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 245, nil, nil, 253, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 250, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 354, 355, 79, + 80, nil, nil, nil, nil, nil, 84, 349, 357, 114, + 113, 115, 116, nil, nil, 254, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 245, nil, nil, 253, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 250, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 354, 355, + 79, 80, nil, nil, nil, nil, nil, 84, 349, 357, + 114, 113, 115, 116, nil, nil, 254, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 118, 117, 119, 108, + 64, 110, 109, 111, nil, 112, 120, 121, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 245, nil, nil, 253, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 250, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 354, + 355, 79, 80, nil, nil, nil, nil, nil, 84, 349, + 357, 114, 113, 115, 116, nil, nil, 254, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 245, nil, nil, 253, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 250, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 114, 113, 115, 116, nil, nil, 23, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, nil, 112, 120, 121, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 245, nil, nil, 253, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 24, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 354, 355, 79, 80, nil, nil, nil, nil, nil, + 84, 349, 357, 114, 113, 115, 116, nil, nil, 254, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 245, nil, nil, 253, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 250, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 114, 113, 115, 116, nil, nil, + 23, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, nil, 112, + 120, 121, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 245, nil, nil, + 253, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 24, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 354, 355, 79, 80, nil, nil, nil, + nil, nil, 84, 349, 357, 114, 113, 115, 116, nil, + nil, 254, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 245, nil, + nil, 253, nil, nil, 66, 67, nil, nil, 68, nil, + 797, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 250, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 354, 355, 79, 80, nil, nil, + nil, nil, nil, 84, 349, 357, 114, 113, 115, 116, + nil, nil, 254, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + 327, 112, 120, 121, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 245, + nil, nil, 253, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, 322, nil, 52, nil, nil, 328, nil, + nil, nil, nil, nil, 250, nil, nil, nil, nil, 102, + 325, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 354, 355, 79, 80, nil, + nil, nil, nil, nil, 84, 349, 357, 114, 113, 115, + 116, nil, nil, 254, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 245, nil, nil, 253, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 250, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 114, 113, + 115, 116, nil, nil, 23, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 118, 117, 119, 108, 64, 110, + 109, 111, nil, 112, 120, 121, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 245, nil, nil, 253, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 24, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 114, + 113, 115, 116, nil, nil, 23, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 245, nil, nil, 253, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 24, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, nil, nil, nil, nil, nil, 84, 33, 32, + 114, 113, 115, 116, nil, nil, 254, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 118, 117, 119, 108, + 64, 110, 109, 111, 327, 112, 120, 121, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 245, nil, nil, 253, nil, nil, 66, + 67, nil, nil, 68, nil, 324, nil, 322, nil, 52, + nil, nil, 328, nil, nil, nil, nil, nil, 250, nil, + nil, nil, nil, 102, 325, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 354, + 355, 79, 80, nil, nil, nil, nil, nil, 84, 349, + 357, 114, 113, 115, 116, nil, nil, 254, nil, nil, + nil, nil, nil, nil, 350, nil, nil, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, nil, nil, 358, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 346, nil, nil, 342, nil, nil, + 66, 67, nil, nil, 68, nil, 341, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 354, 355, 79, 80, nil, nil, nil, nil, nil, 84, + 349, 357, 114, 113, 115, 116, nil, nil, 254, nil, + nil, nil, nil, nil, nil, 350, nil, nil, 118, 117, + 119, 108, 64, 110, 109, 111, nil, 112, 120, 121, + nil, 104, 105, nil, nil, 358, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 346, nil, nil, 253, nil, + nil, 66, 67, nil, nil, 68, nil, nil, 491, nil, + 488, 487, 486, 496, 489, nil, nil, nil, nil, nil, + nil, nil, nil, 499, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 360, nil, 494, 85, nil, 92, 106, + 107, 81, 82, 83, nil, 65, 507, 506, nil, 71, + 72, 500, nil, nil, 75, nil, 73, 74, 76, 354, + 355, 79, 80, nil, nil, nil, nil, nil, 84, 349, + 357, 114, 113, 115, 116, nil, nil, 254, nil, nil, + nil, nil, nil, nil, 350, nil, nil, 118, 117, 119, + 108, 64, 110, 109, 111, nil, 112, 120, 121, nil, + 104, 105, nil, nil, 358, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 395, nil, nil, 38, nil, nil, + 66, 67, nil, nil, 68, nil, 40, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 354, 355, 79, 80, nil, nil, nil, nil, nil, 84, + 349, 357, 114, 113, 115, 116, nil, nil, 254, nil, + nil, nil, nil, nil, nil, 350, nil, nil, 118, 117, + 119, 400, 64, 110, 109, 401, nil, 112, 120, 121, + nil, 104, 105, nil, nil, 358, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 407, nil, nil, 402, nil, nil, 253, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 354, 355, 79, 80, nil, nil, nil, nil, nil, + 84, 349, 357, 114, 113, 115, 116, nil, nil, 254, + nil, nil, nil, nil, nil, nil, 350, nil, nil, 118, + 117, 119, 400, 64, 110, 109, 401, nil, 112, 120, + 121, nil, 104, 105, nil, nil, 358, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 402, nil, nil, 253, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, nil, nil, nil, 75, nil, 73, + 74, 76, 354, 355, 79, 80, nil, nil, nil, nil, + nil, 84, 349, 357, 114, 113, 115, 116, nil, nil, + 254, nil, nil, nil, nil, nil, nil, 350, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, nil, 112, + 120, 121, nil, 104, 105, nil, nil, 358, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 346, nil, nil, + 253, nil, nil, 66, 67, nil, nil, 68, nil, nil, + 491, nil, 488, 487, 486, 496, 489, nil, nil, nil, + nil, nil, nil, nil, nil, 499, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 588, nil, 494, 85, nil, + 92, 106, 107, 81, 82, 83, nil, 65, 507, 506, + nil, 71, 72, 500, nil, nil, 75, nil, 73, 74, + 76, 354, 355, 79, 80, nil, nil, nil, nil, nil, + 84, 349, 357, 114, 113, 115, 116, nil, nil, 254, + nil, nil, nil, nil, nil, nil, 350, nil, nil, 118, + 117, 119, 108, 64, 110, 109, 111, nil, 112, 120, + 121, nil, 104, 105, nil, nil, 358, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 346, nil, nil, 342, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, nil, nil, nil, 75, nil, 73, + 74, 76, 354, 355, 79, 80, nil, nil, nil, nil, + nil, 84, 349, 357, 114, 113, 115, 116, nil, nil, + 254, nil, nil, nil, nil, nil, nil, 350, nil, nil, + 118, 117, 119, 108, 64, 110, 109, 111, nil, 112, + 120, 121, nil, 104, 105, nil, nil, 358, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 346, nil, nil, + 342, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 354, 355, 79, 80, nil, nil, nil, + nil, nil, 84, 349, 357, 114, 113, 115, 116, nil, + nil, 254, nil, nil, nil, nil, nil, nil, 350, nil, + nil, 118, 117, 119, 108, 64, 110, 109, 111, nil, + 112, 120, 121, nil, 104, 105, nil, nil, 358, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 346, nil, + nil, 342, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 354, 355, 79, 80, nil, nil, + nil, nil, nil, 84, 349, 357, 114, 113, 115, 116, + nil, nil, 254, nil, nil, nil, nil, nil, nil, 350, + nil, nil, 118, 117, 119, 108, 64, 110, 109, 111, + nil, 112, 120, 121, nil, 104, 105, nil, nil, 358, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 346, + nil, nil, 342, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, nil, nil, nil, + 75, nil, 73, 74, 76, 354, 355, 79, 80, nil, + nil, nil, nil, nil, 84, 349, 357, 114, 113, 115, + 116, nil, nil, 254, nil, nil, nil, nil, nil, nil, + 350, nil, nil, 118, 117, 119, 108, 64, 110, 109, + 111, nil, 112, 120, 121, nil, 104, 105, nil, nil, + 358, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 346, nil, nil, 342, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, nil, nil, + nil, 75, nil, 73, 74, 76, 354, 355, 79, 80, + nil, nil, nil, nil, nil, 84, 349, 357, 114, 113, + 115, 116, nil, nil, 254, nil, nil, nil, nil, nil, + nil, 350, nil, nil, 118, 117, 119, 108, 64, 110, + 109, 111, nil, 112, 120, 121, nil, 104, 105, nil, + nil, 358, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 1107, nil, nil, 253, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 354, 355, 79, + 80, nil, nil, nil, nil, nil, 84, 349, 357, 114, + 113, 115, 116, nil, nil, 254, nil, nil, nil, nil, + nil, nil, 350, nil, nil, 118, 117, 119, 108, 64, + 110, 109, 111, nil, 112, 120, 121, nil, 104, 105, + nil, nil, 358, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1146, nil, nil, 253, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + nil, nil, nil, 75, nil, 73, 74, 76, 354, 355, + 79, 80, nil, nil, nil, nil, nil, 84, 349, 357, + 114, 113, 115, 116, nil, nil, 254, nil, nil, nil, + nil, nil, nil, 350, nil, nil, 118, 117, 119, 108, + 64, 110, 109, 111, nil, 112, 120, 121, nil, 104, + 105, nil, nil, 358, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 1146, nil, nil, 253, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, nil, nil, nil, 85, nil, 92, 106, 107, 185, + 196, 186, 209, 182, 202, 192, 191, 212, 213, 207, + 190, 189, 184, 210, 214, 215, 194, 183, 197, 201, + 203, 195, 188, nil, nil, nil, 204, 211, 206, 205, + 198, 208, 193, 181, 200, 199, nil, nil, nil, nil, + nil, 180, 187, 178, 179, 175, 176, 177, 138, 140, + 137, nil, 139, nil, nil, nil, nil, nil, nil, nil, + 169, 170, nil, 166, 148, 149, 150, 157, 154, 156, + nil, nil, 151, 152, nil, nil, nil, 171, 172, 158, + 159, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 163, 162, nil, 147, 168, 165, + 164, 173, 160, 161, 155, 153, 145, 167, 146, nil, + nil, 174, 102, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 101, 185, 196, 186, + 209, 182, 202, 192, 191, 212, 213, 207, 190, 189, + 184, 210, 214, 215, 194, 183, 197, 201, 203, 195, + 188, nil, nil, nil, 204, 211, 206, 205, 198, 208, + 193, 181, 200, 199, nil, nil, nil, nil, nil, 180, + 187, 178, 179, 175, 176, 177, 138, 140, nil, nil, + 139, nil, nil, nil, nil, nil, nil, nil, 169, 170, + nil, 166, 148, 149, 150, 157, 154, 156, nil, nil, + 151, 152, nil, nil, nil, 171, 172, 158, 159, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 163, 162, nil, 147, 168, 165, 164, 173, + 160, 161, 155, 153, 145, 167, 146, nil, nil, 174, + 102, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 101, 185, 196, 186, 209, 182, + 202, 192, 191, 212, 213, 207, 190, 189, 184, 210, + 214, 215, 194, 183, 197, 201, 203, 195, 188, nil, + nil, nil, 204, 211, 206, 205, 198, 208, 193, 181, + 200, 199, nil, nil, nil, nil, nil, 180, 187, 178, + 179, 175, 176, 177, 138, 140, nil, nil, 139, nil, + nil, nil, nil, nil, nil, nil, 169, 170, nil, 166, + 148, 149, 150, 157, 154, 156, nil, nil, 151, 152, + nil, nil, nil, 171, 172, 158, 159, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 163, 162, nil, 147, 168, 165, 164, 173, 160, 161, + 155, 153, 145, 167, 146, nil, nil, 174, 102, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 101, 185, 196, 186, 209, 182, 202, 192, + 191, 212, 213, 207, 190, 189, 184, 210, 214, 215, + 194, 183, 197, 201, 203, 195, 188, nil, nil, nil, + 204, 211, 206, 205, 198, 208, 193, 181, 200, 199, + nil, nil, nil, nil, nil, 180, 187, 178, 179, 175, + 176, 177, 138, 140, nil, nil, 139, nil, nil, nil, + nil, nil, nil, nil, 169, 170, nil, 166, 148, 149, + 150, 157, 154, 156, nil, nil, 151, 152, nil, nil, + nil, 171, 172, 158, 159, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 163, 162, + nil, 147, 168, 165, 164, 173, 160, 161, 155, 153, + 145, 167, 146, nil, nil, 174, 102, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 101, 185, 196, 186, 209, 182, 202, 192, 191, 212, + 213, 207, 190, 189, 184, 210, 214, 215, 194, 183, + 197, 201, 203, 195, 188, nil, nil, nil, 204, 211, + 206, 294, 293, 295, 292, 181, 200, 199, nil, nil, + nil, nil, nil, 180, 187, 178, 179, 289, 290, 291, + 287, 140, 110, 109, 288, nil, 112, nil, nil, nil, + nil, nil, 169, 170, nil, 166, 148, 149, 150, 157, + 154, 156, nil, nil, 151, 152, nil, nil, nil, 171, + 172, 158, 159, nil, nil, nil, nil, nil, 299, nil, + nil, nil, nil, nil, nil, nil, 163, 162, nil, 147, + 168, 165, 164, 173, 160, 161, 155, 153, 145, 167, + 146, nil, nil, 174, 114, 113, 115, 116, nil, nil, + 491, nil, 488, 487, 486, 496, 489, nil, nil, nil, + 118, 117, 119, 774, nil, 499, nil, 777, 754, nil, + nil, nil, nil, 104, 105, nil, nil, 358, 499, nil, + nil, nil, nil, nil, nil, nil, nil, 494, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 776, 507, 506, + 747, nil, nil, 500, 745, nil, nil, 746, nil, 749, + nil, nil, nil, nil, nil, nil, 500, nil, nil, nil, + nil, nil, nil, 775, nil, nil, nil, 102, 755, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, 114, 113, 115, 116, nil, nil, 85, nil, + 92, 106, 107, nil, nil, 762, 763, nil, 118, 117, + 119, 774, nil, nil, nil, 777, 754, nil, nil, nil, + nil, 104, 105, nil, nil, 358, 499, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 776, nil, nil, 747, nil, + nil, nil, 745, nil, nil, 746, nil, 749, nil, nil, + nil, nil, nil, nil, 500, nil, nil, nil, nil, nil, + nil, 775, nil, nil, nil, 102, 755, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + 114, 113, 115, 116, nil, nil, 85, nil, 92, 106, + 107, nil, nil, 762, 763, nil, 118, 117, 119, 774, + nil, nil, nil, 777, nil, nil, nil, nil, nil, 104, + 105, nil, nil, 358, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 776, nil, nil, 747, nil, nil, nil, + 745, nil, nil, 746, nil, 749, nil, nil, nil, nil, + nil, nil, 491, nil, 488, 487, 486, 496, 489, 775, + nil, nil, nil, 102, 90, 93, 94, 499, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, 240, 114, + 113, 115, 116, nil, 85, nil, 92, 106, 107, 494, + nil, 762, 763, nil, nil, 118, 117, 119, 774, nil, + 507, 506, 777, nil, nil, 500, nil, nil, 104, 105, + nil, nil, 358, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 776, nil, nil, 747, nil, nil, nil, 745, + nil, nil, 746, nil, nil, 485, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 775, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + nil, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 762, 763, 185, 196, 186, 209, 182, 202, 192, 191, + 212, 213, 207, 190, 189, 184, 210, 214, 215, 194, + 183, 197, 201, 203, 195, 188, nil, nil, nil, 204, + 211, 206, 205, 198, 208, 193, 181, 200, 199, nil, + nil, nil, nil, nil, 180, 187, 178, 179, 175, 176, + 177, 138, 140, nil, nil, 139, nil, nil, nil, nil, + nil, nil, nil, 169, 170, nil, 166, 148, 149, 150, + 157, 154, 156, nil, nil, 151, 152, nil, nil, nil, + 171, 172, 158, 159, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 163, 162, nil, + 147, 168, 165, 164, 173, 160, 161, 155, 153, 145, + 167, 146, nil, nil, 174, 114, 113, 115, 116, nil, + nil, nil, nil, nil, 491, nil, 488, 487, 486, 496, + 489, 118, 117, 119, 774, nil, nil, nil, 777, 499, + nil, nil, nil, nil, 104, 105, nil, nil, 358, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 494, nil, nil, nil, nil, nil, nil, 776, nil, + nil, 747, 507, 506, nil, 745, nil, 500, 746, nil, + 749, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 775, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, 114, 113, 115, 116, 485, nil, 85, + nil, 92, 106, 107, nil, nil, 762, 763, nil, 118, + 117, 119, 774, nil, nil, 491, 777, 488, 487, 486, + 496, 489, 104, 105, nil, nil, 358, nil, nil, nil, + 499, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 776, nil, nil, 747, + nil, nil, 494, 745, nil, nil, 746, nil, nil, nil, + nil, 504, 503, 507, 506, nil, nil, nil, 500, nil, + nil, nil, 775, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, 114, 113, 115, 116, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 762, 763, nil, 118, 117, 119, + 774, nil, nil, nil, 777, 754, nil, nil, nil, nil, + 104, 105, nil, nil, 358, 499, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 776, nil, nil, 747, nil, nil, + nil, 745, nil, nil, 746, nil, 749, nil, nil, nil, + nil, nil, nil, 500, nil, nil, nil, nil, nil, nil, + 775, nil, nil, nil, 102, 755, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, 114, + 113, 115, 116, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 762, 763, nil, 118, 117, 119, 774, nil, + nil, nil, 777, 754, nil, nil, nil, nil, 104, 105, + nil, nil, 358, 499, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 776, nil, nil, 747, nil, nil, nil, 745, + nil, nil, 746, nil, 749, nil, nil, nil, nil, nil, + nil, 500, nil, nil, nil, nil, nil, nil, 775, nil, + nil, nil, 102, 755, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, 114, 113, 115, + 116, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 762, 763, nil, 118, 117, 119, 774, nil, nil, 491, + 777, 488, 487, 486, 496, 489, 104, 105, nil, nil, + 358, nil, nil, nil, 499, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 776, nil, nil, 747, nil, nil, 494, 745, nil, nil, + 746, nil, 1053, nil, nil, 504, 503, 507, 506, nil, + nil, nil, 500, nil, nil, nil, 775, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, 114, 113, 115, 116, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 762, 763, + nil, 118, 117, 119, 774, nil, nil, 491, 777, 488, + 487, 486, 496, 489, 104, 105, nil, nil, 358, nil, + nil, nil, 499, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 776, nil, + nil, 747, nil, nil, 494, 745, nil, nil, 746, nil, + nil, nil, nil, nil, nil, 507, 506, nil, nil, nil, + 500, nil, nil, nil, 775, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, 114, 113, 115, 116, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 762, 763, nil, 118, + 117, 119, 774, nil, nil, nil, 777, nil, nil, nil, + nil, nil, 104, 105, nil, nil, 358, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 776, nil, nil, 747, + nil, nil, nil, 745, nil, nil, 746, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 775, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, 114, 113, 115, 116, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 762, 763, nil, 118, 117, 119, + 774, nil, nil, nil, 777, 754, nil, nil, nil, nil, + 104, 105, nil, nil, 358, 499, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 776, nil, nil, 747, nil, nil, + nil, 745, nil, nil, 746, nil, 749, nil, nil, nil, + nil, nil, nil, 500, nil, nil, nil, nil, nil, nil, + 775, nil, nil, nil, 102, 755, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, 114, + 113, 115, 116, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 762, 763, nil, 118, 117, 119, 774, nil, + nil, nil, 777, nil, nil, nil, nil, nil, 104, 105, + nil, nil, 358, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 776, nil, nil, 747, nil, nil, nil, 745, + nil, nil, 746, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 775, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, 114, 113, 115, + 116, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 762, 763, nil, 118, 117, 119, 774, nil, nil, nil, + 777, nil, nil, nil, nil, nil, 104, 105, nil, nil, + 358, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 776, nil, nil, 747, nil, nil, nil, 745, nil, nil, + 746, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 775, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, 114, 113, 115, 116, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 762, 763, + nil, 118, 117, 119, 774, nil, nil, nil, 777, nil, + nil, nil, nil, nil, 104, 105, nil, nil, 358, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 776, nil, + nil, 747, nil, nil, nil, 745, nil, nil, 746, nil, + 749, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 775, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, 114, 113, 115, 116, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 762, 763, nil, 118, + 117, 119, 774, nil, nil, nil, 777, nil, nil, nil, + nil, nil, 104, 105, nil, nil, 358, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 776, nil, nil, 747, + nil, nil, nil, 745, nil, nil, 746, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 775, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, 114, 113, 115, 116, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 762, 763, nil, 118, 117, 119, + 774, nil, nil, nil, 777, nil, nil, nil, nil, nil, + 104, 105, nil, nil, 358, nil, nil, nil, nil, nil, + nil, nil, 114, 113, 115, 116, nil, nil, nil, nil, + nil, nil, nil, nil, 776, nil, nil, 747, 118, 117, + 119, 745, nil, nil, 746, nil, nil, nil, nil, nil, + nil, 104, 105, nil, nil, 358, nil, nil, nil, nil, + 775, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, nil, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 762, 763, 491, nil, 488, 487, 486, 496, + 489, nil, nil, nil, nil, 102, 90, 93, 94, 499, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + 114, 113, 115, 116, nil, nil, 85, nil, 92, 106, + 107, 494, nil, nil, nil, nil, 118, 117, 119, nil, + 504, 503, 507, 506, nil, nil, nil, 500, nil, 104, + 105, nil, nil, 358, 114, 113, 115, 116, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 118, 117, 119, 240, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 104, 105, nil, nil, 358, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, nil, nil, nil, 85, nil, 92, 106, 107, nil, + nil, nil, nil, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, nil, nil, nil, 85, nil, + 92, 106, 107, 491, nil, 488, 487, 486, 496, 489, + nil, 491, nil, 488, 487, 486, 496, 489, 499, nil, + nil, nil, nil, nil, nil, nil, 499, nil, 491, nil, + 488, 487, 486, 496, 489, nil, nil, nil, nil, nil, + 494, nil, nil, 499, nil, nil, nil, nil, 494, 504, + 503, 507, 506, nil, nil, nil, 500, 504, 503, 507, + 506, nil, nil, nil, 500, 494, nil, nil, nil, nil, + nil, nil, nil, nil, 504, 503, 507, 506, nil, nil, + 491, 500, 488, 487, 486, 496, 489, 491, nil, 488, + 487, 486, 496, 489, nil, 499, 485, nil, nil, nil, + nil, nil, 499, nil, 485, 491, nil, 488, 487, 486, + 496, 489, nil, nil, nil, nil, nil, 494, nil, nil, + 499, 485, nil, nil, 494, nil, nil, nil, 507, 506, + nil, nil, nil, 500, nil, 507, 506, nil, nil, nil, + 500, nil, 494, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 507, 506, nil, nil, nil, 500, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 458, 462, nil, 485, 459, nil, nil, nil, nil, nil, + 485, nil, 169, 170, nil, 166, 148, 149, 150, 157, + 154, 156, nil, nil, 151, 152, nil, nil, 485, 171, + 172, 158, 159, nil, nil, nil, nil, nil, 306, nil, + nil, nil, nil, nil, nil, nil, 163, 162, nil, 147, + 168, 165, 164, 173, 160, 161, 155, 153, 145, 167, + 146, 465, 469, 174, nil, 464, nil, nil, nil, nil, + nil, nil, nil, 169, 170, nil, 166, 148, 149, 150, + 157, 154, 156, nil, nil, 151, 152, nil, nil, nil, + 171, 172, 158, 159, nil, nil, nil, nil, nil, 306, + nil, nil, nil, nil, nil, nil, nil, 163, 162, nil, + 147, 168, 165, 164, 173, 160, 161, 155, 153, 145, + 167, 146, 556, 462, 174, nil, 557, nil, nil, nil, + nil, nil, nil, nil, 169, 170, nil, 166, 148, 149, + 150, 157, 154, 156, nil, nil, 151, 152, nil, nil, + nil, 171, 172, 158, 159, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 163, 162, + nil, 147, 168, 165, 164, 173, 160, 161, 155, 153, + 145, 167, 146, 727, 462, 174, nil, 728, nil, nil, + nil, nil, nil, nil, nil, 169, 170, nil, 166, 148, + 149, 150, 157, 154, 156, nil, nil, 151, 152, nil, + nil, nil, 171, 172, 158, 159, nil, nil, nil, nil, + nil, 306, nil, nil, nil, nil, nil, nil, nil, 163, + 162, nil, 147, 168, 165, 164, 173, 160, 161, 155, + 153, 145, 167, 146, 729, 469, 174, nil, 730, nil, + nil, nil, nil, nil, nil, nil, 169, 170, nil, 166, + 148, 149, 150, 157, 154, 156, nil, nil, 151, 152, + nil, nil, nil, 171, 172, 158, 159, nil, nil, nil, + nil, nil, 306, nil, nil, nil, nil, nil, nil, nil, + 163, 162, nil, 147, 168, 165, 164, 173, 160, 161, + 155, 153, 145, 167, 146, 807, 462, 174, nil, 808, + nil, nil, nil, nil, nil, nil, nil, 169, 170, nil, + 166, 148, 149, 150, 157, 154, 156, nil, nil, 151, + 152, nil, nil, nil, 171, 172, 158, 159, nil, nil, + nil, nil, nil, 306, nil, nil, nil, nil, nil, nil, + nil, 163, 162, nil, 147, 168, 165, 164, 173, 160, + 161, 155, 153, 145, 167, 146, 810, 469, 174, nil, + 811, nil, nil, nil, nil, nil, nil, nil, 169, 170, + nil, 166, 148, 149, 150, 157, 154, 156, nil, nil, + 151, 152, nil, nil, nil, 171, 172, 158, 159, nil, + nil, nil, nil, nil, 306, nil, nil, nil, nil, nil, + nil, nil, 163, 162, nil, 147, 168, 165, 164, 173, + 160, 161, 155, 153, 145, 167, 146, 727, 462, 174, + nil, 728, nil, nil, nil, nil, nil, nil, nil, 169, + 170, nil, 166, 148, 149, 150, 157, 154, 156, nil, + nil, 151, 152, nil, nil, nil, 171, 172, 158, 159, + nil, nil, nil, nil, nil, 306, nil, nil, nil, nil, + nil, nil, nil, 163, 162, nil, 147, 168, 165, 164, + 173, 160, 161, 155, 153, 145, 167, 146, 729, 469, + 174, nil, 730, nil, nil, nil, nil, nil, nil, nil, + 169, 170, nil, 166, 148, 149, 150, 157, 154, 156, + nil, nil, 151, 152, nil, nil, nil, 171, 172, 158, + 159, nil, nil, nil, nil, nil, 306, nil, nil, nil, + nil, nil, nil, nil, 163, 162, nil, 147, 168, 165, + 164, 173, 160, 161, 155, 153, 145, 167, 146, 837, + 462, 174, nil, 838, nil, nil, nil, nil, nil, nil, + nil, 169, 170, nil, 166, 148, 149, 150, 157, 154, + 156, nil, nil, 151, 152, nil, nil, nil, 171, 172, + 158, 159, nil, nil, nil, nil, nil, 306, nil, nil, + nil, nil, nil, nil, nil, 163, 162, nil, 147, 168, + 165, 164, 173, 160, 161, 155, 153, 145, 167, 146, + 839, 469, 174, nil, 840, nil, nil, nil, nil, nil, + nil, nil, 169, 170, nil, 166, 148, 149, 150, 157, + 154, 156, nil, nil, 151, 152, nil, nil, nil, 171, + 172, 158, 159, nil, nil, nil, nil, nil, 306, nil, + nil, nil, nil, nil, nil, nil, 163, 162, nil, 147, + 168, 165, 164, 173, 160, 161, 155, 153, 145, 167, + 146, 842, 469, 174, nil, 843, nil, nil, nil, nil, + nil, nil, nil, 169, 170, nil, 166, 148, 149, 150, + 157, 154, 156, nil, nil, 151, 152, nil, nil, nil, + 171, 172, 158, 159, nil, nil, nil, nil, nil, 306, + nil, nil, nil, nil, nil, nil, nil, 163, 162, nil, + 147, 168, 165, 164, 173, 160, 161, 155, 153, 145, + 167, 146, 556, 462, 174, nil, 557, nil, nil, nil, + nil, nil, nil, nil, 169, 170, nil, 166, 148, 149, + 150, 157, 154, 156, nil, nil, 151, 152, nil, nil, + nil, 171, 172, 158, 159, nil, nil, nil, nil, nil, + 306, nil, nil, nil, nil, nil, nil, nil, 163, 162, + nil, 147, 168, 165, 164, 173, 160, 161, 155, 153, + 145, 167, 146, 869, 462, 174, nil, 870, nil, nil, + nil, nil, nil, nil, nil, 169, 170, nil, 166, 148, + 149, 150, 157, 154, 156, nil, nil, 151, 152, nil, + nil, nil, 171, 172, 158, 159, nil, nil, nil, nil, + nil, 306, nil, nil, nil, nil, nil, nil, nil, 163, + 162, nil, 147, 168, 165, 164, 173, 160, 161, 155, + 153, 145, 167, 146, 872, 469, 174, nil, 871, nil, + nil, nil, nil, nil, nil, nil, 169, 170, nil, 166, + 148, 149, 150, 157, 154, 156, nil, nil, 151, 152, + nil, nil, nil, 171, 172, 158, 159, nil, nil, nil, + nil, nil, 306, nil, nil, nil, nil, nil, nil, nil, + 163, 162, nil, 147, 168, 165, 164, 173, 160, 161, + 155, 153, 145, 167, 146, 1200, 462, 174, nil, 1201, + nil, nil, nil, nil, nil, nil, nil, 169, 170, nil, + 166, 148, 149, 150, 157, 154, 156, nil, nil, 151, + 152, nil, nil, nil, 171, 172, 158, 159, nil, nil, + nil, nil, nil, 306, nil, nil, nil, nil, nil, nil, + nil, 163, 162, nil, 147, 168, 165, 164, 173, 160, + 161, 155, 153, 145, 167, 146, 1202, 469, 174, nil, + 1203, nil, nil, nil, nil, nil, nil, nil, 169, 170, + nil, 166, 148, 149, 150, 157, 154, 156, nil, nil, + 151, 152, nil, nil, nil, 171, 172, 158, 159, nil, + nil, nil, nil, nil, 306, nil, nil, nil, nil, nil, + nil, nil, 163, 162, nil, 147, 168, 165, 164, 173, + 160, 161, 155, 153, 145, 167, 146, 1218, 469, 174, + nil, 1217, nil, nil, nil, nil, nil, nil, nil, 169, + 170, nil, 166, 148, 149, 150, 157, 154, 156, nil, + nil, 151, 152, nil, nil, nil, 171, 172, 158, 159, + nil, nil, nil, nil, nil, 306, nil, nil, nil, nil, + nil, nil, nil, 163, 162, nil, 147, 168, 165, 164, + 173, 160, 161, 155, 153, 145, 167, 146, nil, nil, + 174 ] + +racc_action_check = [ + 108, 515, 515, 553, 553, 19, 392, 108, 108, 108, + 1058, 384, 108, 108, 108, 18, 108, 31, 23, 1053, + 5, 928, 18, 385, 108, 5, 108, 108, 108, 981, + 981, 18, 501, 416, 393, 396, 108, 108, 835, 108, + 108, 108, 108, 108, 1016, 1087, 1089, 1104, 1105, 927, + 501, 631, 1220, 1058, 1108, 625, 417, 928, 1, 23, + 69, 19, 1220, 625, 837, 838, 108, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, + 18, 31, 108, 108, 108, 3, 108, 108, 622, 927, + 108, 850, 992, 108, 108, 515, 108, 553, 108, 416, + 108, 1053, 108, 108, 31, 108, 108, 108, 108, 108, + 1165, 108, 111, 108, 1200, 392, 785, 641, 641, 111, + 111, 111, 417, 981, 111, 111, 111, 108, 111, 384, + 108, 108, 108, 108, 384, 108, 111, 108, 111, 111, + 111, 385, 108, 393, 396, 108, 385, 69, 111, 111, + 1201, 111, 111, 111, 111, 111, 835, 1202, 1222, 835, + 631, 835, 1016, 1087, 1089, 1104, 1105, 1016, 1087, 1089, + 1104, 1105, 1108, 837, 838, 839, 840, 1108, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 622, 1203, 111, 111, 111, 622, 111, 111, + 850, 992, 111, 785, 331, 111, 111, 746, 111, 331, + 111, 641, 111, 656, 111, 111, 641, 111, 111, 111, + 111, 111, 464, 111, 746, 111, 735, 243, 1165, 464, + 464, 464, 1200, 1165, 1202, 464, 464, 1200, 464, 111, + 839, 840, 111, 111, 111, 111, 464, 111, 29, 111, + 351, 20, 9, 411, 111, 29, 932, 111, 464, 464, + 807, 464, 464, 464, 464, 464, 48, 48, 1201, 1092, + 1203, 1092, 735, 1201, 808, 1202, 1222, 656, 656, 244, + 1202, 1222, 358, 358, 839, 840, 243, 656, 464, 464, + 464, 464, 464, 464, 464, 464, 464, 464, 464, 464, + 464, 464, 932, 286, 464, 464, 464, 20, 464, 464, + 286, 1203, 464, 29, 351, 464, 1203, 411, 411, 411, + 464, 12, 464, 658, 464, 464, 807, 464, 464, 464, + 464, 464, 246, 464, 465, 464, 756, 351, 244, 443, + 808, 465, 465, 465, 48, 48, 389, 465, 465, 464, + 465, 389, 464, 464, 756, 464, 14, 464, 465, 465, + 358, 358, 979, 521, 464, 15, 807, 464, 286, 807, + 465, 465, 727, 465, 465, 465, 465, 465, 802, 287, + 808, 807, 376, 808, 810, 376, 287, 658, 658, 576, + 802, 246, 728, 947, 509, 808, 251, 658, 443, 509, + 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, + 465, 465, 465, 465, 17, 939, 465, 465, 465, 54, + 465, 465, 521, 27, 465, 939, 54, 465, 979, 869, + 1127, 727, 465, 870, 465, 54, 465, 465, 412, 465, + 465, 465, 465, 465, 287, 465, 465, 465, 42, 810, + 810, 728, 251, 576, 576, 576, 413, 947, 947, 947, + 21, 465, 414, 939, 465, 465, 400, 465, 979, 465, + 576, 979, 415, 729, 947, 939, 465, 252, 45, 465, + 729, 729, 729, 979, 54, 729, 729, 729, 869, 729, + 810, 996, 870, 810, 1127, 1127, 996, 729, 729, 729, + 729, 729, 412, 412, 412, 810, 401, 21, 53, 729, + 729, 1127, 729, 729, 729, 729, 729, 216, 400, 21, + 413, 413, 413, 418, 229, 400, 414, 414, 414, 377, + 400, 923, 377, 252, 400, 231, 415, 415, 415, 729, + 729, 729, 729, 729, 729, 729, 729, 729, 729, 729, + 729, 729, 729, 400, 1006, 729, 729, 729, 401, 729, + 729, 16, 16, 729, 402, 401, 729, 729, 402, 729, + 401, 729, 235, 729, 401, 729, 729, 245, 729, 729, + 729, 729, 729, 400, 729, 729, 729, 418, 418, 418, + 923, 242, 288, 401, 289, 290, 51, 51, 242, 288, + 729, 289, 290, 729, 729, 729, 729, 242, 729, 291, + 729, 43, 730, 1006, 247, 729, 291, 44, 729, 730, + 730, 730, 248, 401, 730, 730, 730, 292, 730, 383, + 383, 254, 51, 51, 292, 293, 730, 305, 730, 730, + 730, 137, 293, 700, 700, 319, 137, 137, 730, 730, + 362, 730, 730, 730, 730, 730, 242, 288, 43, 289, + 290, 294, 295, 776, 44, 320, 744, 776, 294, 295, + 43, 744, 323, 931, 291, 744, 44, 931, 730, 730, + 730, 730, 730, 730, 730, 730, 730, 730, 730, 730, + 730, 730, 292, 945, 730, 730, 730, 362, 730, 730, + 293, 458, 730, 945, 380, 730, 730, 380, 730, 362, + 730, 335, 730, 822, 730, 730, 822, 730, 730, 730, + 730, 730, 871, 730, 336, 730, 294, 295, 88, 871, + 871, 871, 759, 759, 1157, 871, 871, 1157, 871, 730, + 88, 945, 730, 730, 730, 730, 871, 730, 458, 730, + 88, 823, 823, 945, 730, 459, 338, 730, 871, 871, + 458, 871, 871, 871, 871, 871, 1090, 1090, 1190, 1190, + 233, 343, 233, 233, 233, 233, 233, 339, 343, 678, + 714, 340, 714, 714, 714, 233, 714, 343, 871, 871, + 871, 871, 871, 871, 871, 871, 871, 871, 871, 871, + 871, 871, 459, 346, 871, 871, 871, 233, 871, 871, + 349, 350, 871, 352, 459, 871, 233, 233, 233, 233, + 871, 353, 871, 233, 871, 871, 678, 871, 871, 871, + 871, 871, 357, 871, 872, 871, 343, 359, 678, 366, + 368, 872, 872, 872, 371, 374, 378, 872, 872, 871, + 872, 379, 871, 871, 381, 871, 390, 871, 872, 872, + 391, 395, 397, 233, 871, 406, 426, 871, 432, 434, + 872, 872, 435, 872, 872, 872, 872, 872, 437, 440, + 444, 454, 234, 344, 234, 234, 234, 234, 234, 775, + 344, 775, 775, 456, 457, 775, 466, 234, 472, 344, + 872, 872, 872, 872, 872, 872, 872, 872, 872, 872, + 872, 872, 872, 872, 473, 476, 872, 872, 872, 234, + 872, 872, 477, 478, 872, 481, 775, 872, 234, 234, + 234, 234, 872, 482, 872, 234, 872, 872, 483, 872, + 872, 872, 872, 872, 697, 872, 872, 872, 344, 493, + 345, 505, 508, 511, 697, 347, 363, 345, 517, 525, + 526, 872, 347, 363, 872, 872, 345, 872, 533, 872, + 394, 347, 363, 534, 535, 234, 872, 394, 536, 872, + 2, 2, 2, 2, 2, 2, 394, 697, 697, 2, + 2, 561, 697, 562, 2, 842, 2, 2, 2, 2, + 2, 2, 2, 8, 8, 8, 8, 8, 2, 2, + 2, 2, 2, 2, 2, 345, 563, 2, 567, 583, + 347, 363, 584, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 394, 2, 2, 2, 404, + 2, 2, 2, 2, 2, 442, 404, 842, 587, 593, + 589, 594, 442, 598, 842, 404, 593, 607, 608, 842, + 609, 442, 619, 842, 2, 593, 623, 2, 624, 626, + 2, 2, 634, 653, 2, 661, 2, 663, 670, 634, + 2, 679, 842, 684, 531, 689, 649, 649, 634, 2, + 649, 649, 649, 691, 2, 2, 2, 2, 693, 2, + 2, 2, 2, 707, 404, 712, 713, 2, 2, 715, + 442, 722, 842, 731, 593, 2, 531, 2, 2, 2, + 531, 531, 2, 2, 38, 38, 38, 38, 38, 38, + 740, 748, 749, 38, 38, 750, 779, 634, 38, 782, + 38, 38, 38, 38, 38, 38, 38, 25, 784, 790, + 791, 792, 38, 38, 38, 38, 38, 38, 38, 794, + 1099, 38, 1099, 1099, 1099, 796, 1099, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 804, + 38, 38, 38, 806, 38, 38, 38, 38, 38, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 811, 25, 25, 809, 812, 25, 25, 811, 38, 813, + 25, 38, 811, 816, 38, 38, 811, 825, 38, 831, + 38, 25, 832, 25, 38, 25, 25, 836, 25, 25, + 25, 25, 25, 38, 25, 845, 849, 851, 38, 38, + 38, 38, 1106, 38, 38, 38, 38, 866, 868, 1106, + 877, 38, 38, 890, 25, 893, 894, 897, 1106, 38, + 899, 38, 38, 38, 902, 811, 38, 38, 135, 135, + 135, 135, 135, 135, 903, 905, 906, 135, 135, 908, + 912, 925, 135, 933, 135, 135, 135, 135, 135, 135, + 135, 334, 334, 334, 334, 334, 135, 135, 135, 135, + 135, 135, 135, 934, 938, 135, 941, 1106, 946, 965, + 447, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 968, 135, 135, 135, 969, 135, 135, + 135, 135, 135, 447, 447, 447, 447, 447, 447, 447, + 447, 447, 447, 447, 843, 447, 447, 978, 983, 447, + 447, 843, 135, 986, 993, 135, 843, 995, 135, 135, + 843, 1002, 135, 1003, 135, 447, 1004, 447, 135, 447, + 447, 1005, 447, 447, 447, 447, 447, 135, 447, 1031, + 1032, 1037, 135, 135, 135, 135, 1145, 135, 135, 135, + 135, 1042, 1043, 1145, 1044, 135, 135, 1045, 447, 1046, + 447, 1047, 1145, 135, 1051, 135, 135, 135, 1052, 843, + 135, 135, 218, 218, 218, 218, 218, 218, 1055, 1059, + 1066, 218, 218, 1071, 1072, 1074, 218, 1075, 218, 218, + 218, 218, 218, 218, 218, 373, 373, 373, 373, 373, + 218, 218, 218, 218, 218, 218, 218, 1076, 1078, 218, + 1079, 1145, 1080, 1096, 453, 218, 218, 218, 218, 218, + 218, 218, 218, 218, 218, 218, 218, 1107, 218, 218, + 218, 1110, 218, 218, 218, 218, 218, 453, 453, 453, + 453, 453, 453, 453, 453, 453, 453, 453, 1187, 453, + 453, 1111, 1112, 453, 453, 1187, 218, 1113, 1124, 218, + 1132, 1143, 218, 218, 1187, 1146, 218, 1155, 218, 453, + 1132, 453, 218, 453, 453, 1156, 453, 453, 453, 453, + 453, 218, 453, 1161, 1171, 1172, 218, 218, 218, 218, + 1174, 218, 218, 218, 218, 1177, 1180, 1181, 1182, 218, + 218, 1183, 453, 1132, 1132, 1185, 1199, 218, 1132, 218, + 218, 218, 1204, 1187, 218, 218, 230, 230, 230, 230, + 230, 230, 1206, 1217, 1218, 230, 230, 1224, 1225, 1226, + 230, 1227, 230, 230, 230, 230, 230, 230, 230, 581, + 581, 581, 581, 581, 230, 230, 230, 230, 230, 230, + 230, 1236, nil, 230, nil, nil, nil, nil, 692, 230, + 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, + 230, nil, 230, 230, 230, nil, 230, 230, 230, 230, + 230, 692, 692, 692, 692, 692, 692, 692, 692, 692, + 692, 692, nil, 692, 692, nil, nil, 692, 692, nil, + 230, nil, nil, 230, nil, nil, 230, 230, nil, nil, + 230, nil, 230, 692, nil, 692, 230, 692, 692, nil, + 692, 692, 692, 692, 692, 230, 692, nil, nil, nil, + 230, 230, 230, 230, nil, 230, 230, 230, 230, nil, + nil, nil, nil, 230, 230, nil, 692, nil, nil, nil, + nil, 230, nil, 230, 230, 230, nil, nil, 230, 230, + 236, 236, 236, 236, 236, 236, nil, nil, nil, 236, + 236, nil, nil, nil, 236, nil, 236, 236, 236, 236, + 236, 236, 236, nil, nil, nil, nil, nil, 236, 236, + 236, 236, 236, 236, 236, nil, nil, 236, nil, nil, + nil, nil, 723, 236, 236, 236, 236, 236, 236, 236, + 236, 236, 236, 236, 236, nil, 236, 236, 236, nil, + 236, 236, 236, 236, 236, 723, 723, 723, 723, 723, + 723, 723, 723, 723, 723, 723, nil, 723, 723, nil, + nil, 723, 723, nil, 236, nil, nil, 236, nil, nil, + 236, 236, nil, nil, 236, nil, 236, 723, nil, 723, + 236, 723, 723, nil, 723, 723, 723, 723, 723, 236, + 723, nil, nil, nil, 236, 236, 236, 236, nil, 236, + 236, 236, 236, nil, nil, nil, nil, 236, 236, nil, + 723, nil, nil, nil, nil, 236, nil, 236, 236, 236, + nil, nil, 236, 236, 253, 253, 253, 253, 253, 253, + nil, nil, nil, 253, 253, nil, nil, nil, 253, nil, + 253, 253, 253, 253, 253, 253, 253, nil, nil, nil, + nil, nil, 253, 253, 253, 253, 253, 253, 253, nil, + 1197, 253, 1197, 1197, 1197, nil, 1197, 253, 253, 253, + 253, 253, 253, 253, 253, 253, 253, 253, 253, nil, + 253, 253, 253, nil, 253, 253, 253, 253, 253, 317, + 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, + nil, 317, 317, nil, nil, 317, 317, nil, 253, nil, + nil, 253, nil, nil, 253, 253, nil, nil, 253, nil, + 253, 317, nil, 317, 253, 317, 317, nil, 317, 317, + 317, 317, 317, 253, 317, nil, nil, nil, 253, 253, + 253, 253, nil, 253, 253, 253, 253, nil, nil, nil, + nil, 253, 253, nil, 317, nil, nil, nil, nil, 253, + nil, 253, 253, 253, nil, nil, 253, 253, 337, 337, + 337, 337, 337, 337, nil, nil, nil, 337, 337, nil, + nil, nil, 337, nil, 337, 337, 337, 337, 337, 337, + 337, nil, nil, nil, nil, nil, 337, 337, 337, 337, + 337, 337, 337, nil, nil, 337, nil, nil, nil, nil, + nil, 337, 337, 337, 337, 337, 337, 337, 337, 337, + 337, 337, 337, nil, 337, 337, 337, nil, 337, 337, + 337, 337, 337, 550, 550, 550, 550, 550, 550, 550, + 550, 550, 550, 550, nil, 550, 550, nil, nil, 550, + 550, nil, 337, nil, nil, 337, nil, nil, 337, 337, + nil, nil, 337, nil, 337, 550, nil, 550, 337, 550, + 550, nil, 550, 550, 550, 550, 550, 337, 550, nil, + nil, nil, 337, 337, 337, 337, nil, 337, 337, 337, + 337, nil, nil, nil, nil, 337, 337, 550, 550, nil, + nil, nil, nil, 337, nil, 337, 337, 337, nil, nil, + 337, 337, 342, 342, 342, 342, 342, 342, nil, nil, + nil, 342, 342, nil, nil, nil, 342, nil, 342, 342, + 342, 342, 342, 342, 342, nil, nil, nil, nil, nil, + 342, 342, 342, 342, 342, 342, 342, nil, nil, 342, + nil, nil, nil, nil, nil, 342, 342, 342, 342, 342, + 342, 342, 342, 342, 342, 342, 342, nil, 342, 342, + 342, nil, 342, 342, 342, 342, 342, 817, 817, 817, + 817, 817, 817, 817, 817, 817, 817, 817, nil, 817, + 817, nil, nil, 817, 817, nil, 342, nil, nil, 342, + nil, nil, 342, 342, nil, nil, 342, nil, 342, 817, + nil, 817, 342, 817, 817, nil, 817, 817, 817, 817, + 817, 342, 817, nil, nil, nil, 342, 342, 342, 342, + nil, 342, 342, 342, 342, nil, nil, nil, nil, 342, + 342, nil, 817, nil, nil, nil, nil, 342, nil, 342, + 342, 342, nil, nil, 342, 342, 372, 372, 372, 372, + 372, 372, nil, nil, nil, 372, 372, nil, nil, nil, + 372, nil, 372, 372, 372, 372, 372, 372, 372, nil, + nil, nil, nil, nil, 372, 372, 372, 372, 372, 372, + 372, nil, nil, 372, nil, nil, nil, nil, nil, 372, + 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, + 372, nil, 372, 372, 372, nil, 372, 372, 372, 372, + 372, 874, 874, 874, 874, 874, 874, 874, 874, 874, + 874, 874, nil, 874, 874, nil, nil, 874, 874, nil, + 372, nil, nil, 372, nil, nil, 372, 372, nil, nil, + 372, nil, 372, 874, nil, 874, 372, 874, 874, nil, + 874, 874, 874, 874, 874, 372, 874, nil, nil, nil, + 372, 372, 372, 372, nil, 372, 372, 372, 372, nil, + nil, nil, nil, 372, 372, nil, 874, nil, nil, nil, + nil, 372, nil, 372, 372, 372, nil, nil, 372, 372, + 387, 387, 387, 387, 387, 387, nil, nil, nil, 387, + 387, nil, nil, nil, 387, nil, 387, 387, 387, 387, + 387, 387, 387, nil, nil, nil, nil, nil, 387, 387, + 387, 387, 387, 387, 387, nil, nil, 387, nil, nil, + nil, nil, nil, 387, 387, 387, 387, 387, 387, 387, + 387, 387, 387, 387, 387, nil, 387, 387, 387, nil, + 387, 387, 387, 387, 387, 1010, 1010, 1010, 1010, 1010, + 1010, 1010, 1010, 1010, 1010, 1010, nil, 1010, 1010, nil, + nil, 1010, 1010, nil, 387, nil, nil, 387, nil, nil, + 387, 387, nil, nil, 387, nil, 387, 1010, nil, 1010, + 387, 1010, 1010, nil, 1010, 1010, 1010, 1010, 1010, 387, + 1010, nil, nil, nil, 387, 387, 387, 387, nil, 387, + 387, 387, 387, nil, nil, nil, nil, 387, 387, nil, + 1010, nil, nil, nil, nil, 387, nil, 387, 387, 387, + nil, nil, 387, 387, 388, 388, 388, 388, 388, 388, + nil, nil, nil, 388, 388, nil, nil, nil, 388, nil, + 388, 388, 388, 388, 388, 388, 388, nil, nil, nil, + nil, nil, 388, 388, 388, 388, 388, 388, 388, nil, + nil, 388, nil, nil, nil, nil, nil, 388, 388, 388, + 388, 388, 388, 388, 388, 388, 388, 388, 388, nil, + 388, 388, 388, nil, 388, 388, 388, 388, 388, 1011, + 1011, 1011, 1011, 1011, 1011, 1011, 1011, 1011, 1011, 1011, + nil, 1011, 1011, nil, nil, 1011, 1011, nil, 388, nil, + nil, 388, nil, nil, 388, 388, nil, nil, 388, nil, + 388, 1011, nil, 1011, 388, 1011, 1011, nil, 1011, 1011, + 1011, 1011, 1011, 388, 1011, nil, nil, nil, 388, 388, + 388, 388, nil, 388, 388, 388, 388, nil, nil, nil, + nil, 388, 388, nil, 1011, nil, nil, nil, nil, 388, + nil, 388, 388, 388, nil, nil, 388, 388, 618, 618, + 618, 618, 618, 618, nil, nil, nil, 618, 618, nil, + nil, nil, 618, nil, 618, 618, 618, 618, 618, 618, + 618, nil, nil, nil, nil, nil, 618, 618, 618, 618, + 618, 618, 618, nil, nil, 618, nil, nil, nil, nil, + nil, 618, 618, 618, 618, 618, 618, 618, 618, 618, + 618, 618, 618, nil, 618, 618, 618, nil, 618, 618, + 618, 618, 618, 1033, 1033, 1033, 1033, 1033, 1033, 1033, + 1033, 1033, 1033, 1033, nil, 1033, 1033, nil, nil, 1033, + 1033, nil, 618, nil, nil, 618, nil, nil, 618, 618, + nil, nil, 618, nil, 618, 1033, nil, 1033, 618, 1033, + 1033, nil, 1033, 1033, 1033, 1033, 1033, 618, 1033, nil, + nil, nil, 618, 618, 618, 618, nil, 618, 618, 618, + 618, nil, nil, nil, nil, 618, 618, nil, 1033, nil, + nil, nil, nil, 618, nil, 618, 618, 618, nil, nil, + 618, 618, 621, 621, 621, 621, 621, 621, nil, nil, + nil, 621, 621, nil, nil, nil, 621, nil, 621, 621, + 621, 621, 621, 621, 621, nil, nil, nil, nil, nil, + 621, 621, 621, 621, 621, 621, 621, nil, nil, 621, + nil, nil, nil, nil, nil, 621, 621, 621, 621, 621, + 621, 621, 621, 621, 621, 621, 621, nil, 621, 621, + 621, nil, 621, 621, 621, 621, 621, 1034, 1034, 1034, + 1034, 1034, 1034, 1034, 1034, 1034, 1034, 1034, nil, 1034, + 1034, nil, nil, 1034, 1034, nil, 621, nil, nil, 621, + nil, nil, 621, 621, nil, nil, 621, nil, 621, 1034, + nil, 1034, 621, 1034, 1034, nil, 1034, 1034, 1034, 1034, + 1034, 621, 1034, nil, nil, nil, 621, 621, 621, 621, + nil, 621, 621, 621, 621, nil, nil, nil, nil, 621, + 621, nil, 1034, nil, nil, nil, nil, 621, nil, 621, + 621, 621, nil, nil, 621, 621, 642, 642, 642, 642, + 642, 642, nil, nil, nil, 642, 642, nil, nil, nil, + 642, nil, 642, 642, 642, 642, 642, 642, 642, nil, + nil, nil, nil, nil, 642, 642, 642, 642, 642, 642, + 642, nil, nil, 642, nil, nil, nil, nil, nil, 642, + 642, 642, 642, 642, 642, 642, 642, 642, 642, 642, + 642, nil, 642, 642, 642, nil, 642, 642, 642, 642, + 642, 1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067, 1067, + 1067, 1067, nil, 1067, 1067, nil, nil, 1067, 1067, nil, + 642, nil, nil, 642, nil, nil, 642, 642, nil, nil, + 642, nil, 642, 1067, nil, 1067, 642, 1067, 1067, nil, + 1067, 1067, 1067, 1067, 1067, 642, 1067, nil, nil, nil, + 642, 642, 642, 642, nil, 642, 642, 642, 642, nil, + nil, nil, nil, 642, 642, nil, 1067, nil, nil, nil, + nil, 642, nil, 642, 642, 642, nil, nil, 642, 642, + 841, 841, 841, 841, 841, 841, nil, nil, nil, 841, + 841, nil, nil, nil, 841, nil, 841, 841, 841, 841, + 841, 841, 841, nil, nil, nil, nil, nil, 841, 841, + 841, 841, 841, 841, 841, nil, 494, 841, 494, 494, + 494, nil, 494, 841, 841, 841, 841, 841, 841, 841, + 841, 841, 841, 841, 841, nil, 841, 841, 841, nil, + 841, 841, 841, 841, 841, 710, nil, 710, 710, 710, + nil, 710, nil, 494, nil, nil, 532, nil, nil, nil, + nil, nil, 494, nil, 841, nil, nil, 841, nil, nil, + 841, 841, nil, nil, 841, 913, 841, 913, 913, 913, + 841, 913, 710, nil, nil, nil, nil, nil, 532, 841, + nil, 710, 532, 532, 841, 841, 841, 841, nil, 841, + 841, 841, 841, nil, nil, nil, nil, 841, 841, nil, + nil, nil, 913, nil, nil, 841, nil, 841, 841, 841, + nil, 913, 841, 841, 846, 846, 846, 846, 846, 846, + nil, nil, nil, 846, 846, nil, nil, nil, 846, nil, + 846, 846, 846, 846, 846, 846, 846, nil, nil, nil, + nil, nil, 846, 846, 846, 846, 846, 846, 846, nil, + nil, 846, nil, nil, nil, nil, nil, 846, 846, 846, + 846, 846, 846, 846, 846, 846, 846, 846, 846, nil, + 846, 846, 846, nil, 846, 846, 846, 846, 846, 364, + 364, 364, 364, 364, 364, 364, 364, 364, 364, 364, + nil, 364, 364, nil, nil, 364, 364, nil, 846, nil, + nil, 846, nil, nil, 846, 846, nil, 546, 846, nil, + 846, 364, nil, 364, 846, 364, 364, nil, 364, 364, + 364, 364, 364, 846, 364, nil, nil, nil, 846, 846, + 846, 846, nil, 846, 846, 846, 846, nil, nil, 546, + nil, 846, 846, 546, 546, nil, 546, 546, nil, 846, + nil, 846, 846, 846, nil, nil, 846, 846, 857, 857, + 857, 857, 857, 857, nil, nil, nil, 857, 857, nil, + nil, nil, 857, nil, 857, 857, 857, 857, 857, 857, + 857, nil, nil, nil, nil, nil, 857, 857, 857, 857, + 857, 857, 857, nil, nil, 857, nil, nil, nil, nil, + nil, 857, 857, 857, 857, 857, 857, 857, 857, 857, + 857, 857, 857, nil, 857, 857, 857, nil, 857, 857, + 857, 857, 857, 365, 365, 365, 365, 365, 365, 365, + 365, 365, 365, 365, nil, 365, 365, nil, nil, 365, + 365, nil, 857, nil, nil, 857, nil, nil, 857, 857, + nil, 547, 857, nil, 857, 365, nil, 365, 857, 365, + 365, nil, 365, 365, 365, 365, 365, 857, 365, nil, + nil, nil, 857, 857, 857, 857, nil, 857, 857, 857, + 857, nil, nil, 547, nil, 857, 857, 547, 547, nil, + 547, 547, nil, 857, nil, 857, 857, 857, nil, nil, + 857, 857, 892, 892, 892, 892, 892, 892, nil, nil, + nil, 892, 892, nil, nil, nil, 892, nil, 892, 892, + 892, 892, 892, 892, 892, nil, nil, nil, nil, nil, + 892, 892, 892, 892, 892, 892, 892, nil, nil, 892, + nil, nil, nil, nil, nil, 892, 892, 892, 892, 892, + 892, 892, 892, 892, 892, 892, 892, nil, 892, 892, + 892, nil, 892, 892, 892, 892, 892, 529, 529, 529, + 529, 529, 529, 529, 529, 529, 529, 529, nil, 529, + 529, nil, nil, 529, 529, nil, 892, nil, nil, 892, + nil, nil, 892, 892, nil, nil, 892, nil, 892, 529, + nil, 529, 892, 529, 529, nil, 529, 529, 529, 529, + 529, 892, 529, nil, nil, nil, 892, 892, 892, 892, + nil, 892, 892, 892, 892, nil, nil, nil, nil, 892, + 892, nil, 914, nil, 914, 914, 914, 892, 914, 892, + 892, 892, nil, nil, 892, 892, 973, 973, 973, 973, + 973, 973, nil, nil, nil, 973, 973, nil, nil, nil, + 973, nil, 973, 973, 973, 973, 973, 973, 973, 914, + nil, nil, nil, nil, 973, 973, 973, 973, 973, 973, + 973, nil, nil, 973, nil, nil, nil, nil, nil, 973, + 973, 973, 973, 973, 973, 973, 973, 973, 973, 973, + 973, nil, 973, 973, 973, nil, 973, 973, 973, 973, + 973, 530, 530, 530, 530, 530, 530, 530, 530, 530, + 530, 530, nil, 530, 530, nil, nil, 530, 530, nil, + 973, nil, nil, 973, nil, nil, 973, 973, nil, nil, + 973, nil, 973, 530, nil, 530, 973, 530, 530, nil, + 530, 530, 530, 530, 530, 973, 530, nil, nil, nil, + 973, 973, 973, 973, nil, 973, 973, 973, 973, nil, + nil, nil, nil, 973, 973, nil, 1114, nil, 1114, 1114, + 1114, 973, 1114, 973, 973, 973, nil, nil, 973, 973, + 991, 991, 991, 991, 991, 991, nil, nil, nil, 991, + 991, nil, nil, nil, 991, nil, 991, 991, 991, 991, + 991, 991, 991, 1114, nil, nil, nil, nil, 991, 991, + 991, 991, 991, 991, 991, nil, 1115, 991, 1115, 1115, + 1115, nil, 1115, 991, 991, 991, 991, 991, 991, 991, + 991, 991, 991, 991, 991, nil, 991, 991, 991, nil, + 991, 991, 991, 991, 991, 540, 540, 540, 540, 540, + 540, 540, nil, 1115, 540, 540, nil, nil, nil, nil, + nil, 540, 540, nil, 991, nil, nil, 991, nil, nil, + 991, 991, nil, nil, 991, nil, 991, 540, nil, 540, + 991, 540, 540, nil, 540, 540, 540, 540, 540, 991, + 540, nil, nil, nil, 991, 991, 991, 991, nil, 991, + 991, 991, 991, nil, nil, nil, nil, 991, 991, nil, + nil, nil, nil, nil, nil, 991, nil, 991, 991, 991, + nil, nil, 991, 991, 997, 997, 997, 997, 997, 997, + nil, nil, nil, 997, 997, nil, nil, nil, 997, nil, + 997, 997, 997, 997, 997, 997, 997, nil, nil, nil, + nil, nil, 997, 997, 997, 997, 997, 997, 997, nil, + nil, 997, nil, nil, nil, nil, nil, 997, 997, 997, + 997, 997, 997, 997, 997, 997, 997, 997, 997, nil, + 997, 997, 997, nil, 997, 997, 997, 997, 997, 541, + 541, 541, 541, 541, 541, 541, nil, nil, 541, 541, + nil, nil, nil, nil, nil, 541, 541, nil, 997, nil, + nil, 997, nil, nil, 997, 997, nil, nil, 997, nil, + 997, 541, nil, 541, 997, 541, 541, nil, 541, 541, + 541, 541, 541, 997, 541, nil, nil, nil, 997, 997, + 997, 997, nil, 997, 997, 997, 997, nil, nil, nil, + nil, 997, 997, nil, nil, nil, nil, nil, nil, 997, + nil, 997, 997, 997, nil, nil, 997, 997, 1013, 1013, + 1013, 1013, 1013, 1013, nil, nil, nil, 1013, 1013, nil, + nil, nil, 1013, nil, 1013, 1013, 1013, 1013, 1013, 1013, + 1013, nil, nil, nil, nil, nil, 1013, 1013, 1013, 1013, + 1013, 1013, 1013, nil, nil, 1013, nil, nil, nil, nil, + nil, 1013, 1013, 1013, 1013, 1013, 1013, 1013, 1013, 1013, + 1013, 1013, 1013, nil, 1013, 1013, 1013, nil, 1013, 1013, + 1013, 1013, 1013, 542, 542, 542, 542, 542, 542, 542, + nil, nil, 542, 542, nil, nil, nil, nil, nil, 542, + 542, nil, 1013, nil, nil, 1013, nil, nil, 1013, 1013, + nil, nil, 1013, nil, 1013, 542, nil, 542, 1013, 542, + 542, nil, 542, 542, 542, 542, 542, 1013, 542, nil, + nil, nil, 1013, 1013, 1013, 1013, nil, 1013, 1013, 1013, + 1013, nil, nil, nil, nil, 1013, 1013, nil, nil, nil, + nil, nil, nil, 1013, nil, 1013, 1013, 1013, nil, nil, + 1013, 1013, 1068, 1068, 1068, 1068, 1068, 1068, nil, nil, + nil, 1068, 1068, nil, nil, nil, 1068, nil, 1068, 1068, + 1068, 1068, 1068, 1068, 1068, nil, nil, nil, nil, nil, + 1068, 1068, 1068, 1068, 1068, 1068, 1068, nil, nil, 1068, + nil, nil, nil, nil, nil, 1068, 1068, 1068, 1068, 1068, + 1068, 1068, 1068, 1068, 1068, 1068, 1068, nil, 1068, 1068, + 1068, nil, 1068, 1068, 1068, 1068, 1068, 543, 543, 543, + 543, 543, 543, 543, nil, nil, 543, 543, nil, nil, + nil, nil, nil, 543, 543, nil, 1068, nil, nil, 1068, + nil, nil, 1068, 1068, nil, nil, 1068, nil, 1068, 543, + nil, 543, 1068, 543, 543, nil, 543, 543, 543, 543, + 543, 1068, 543, nil, nil, nil, 1068, 1068, 1068, 1068, + nil, 1068, 1068, 1068, 1068, nil, nil, nil, nil, 1068, + 1068, nil, nil, nil, nil, nil, nil, 1068, nil, 1068, + 1068, 1068, nil, nil, 1068, 1068, 1097, 1097, 1097, 1097, + 1097, 1097, nil, nil, nil, 1097, 1097, nil, nil, nil, + 1097, nil, 1097, 1097, 1097, 1097, 1097, 1097, 1097, nil, + nil, nil, nil, nil, 1097, 1097, 1097, 1097, 1097, 1097, + 1097, nil, nil, 1097, nil, nil, nil, nil, nil, 1097, + 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, 1097, + 1097, nil, 1097, 1097, 1097, nil, 1097, 1097, 1097, 1097, + 1097, 544, 544, 544, 544, 544, 544, 544, nil, nil, + 544, 544, nil, nil, nil, nil, nil, 544, 544, nil, + 1097, nil, nil, 1097, nil, nil, 1097, 1097, nil, nil, + 1097, nil, 1097, 544, nil, 544, 1097, 544, 544, nil, + 544, 544, 544, 544, 544, 1097, 544, nil, nil, nil, + 1097, 1097, 1097, 1097, nil, 1097, 1097, 1097, 1097, nil, + nil, nil, nil, 1097, 1097, nil, nil, nil, nil, nil, + nil, 1097, nil, 1097, 1097, 1097, nil, nil, 1097, 1097, + 1098, 1098, 1098, 1098, 1098, 1098, nil, nil, nil, 1098, + 1098, nil, nil, nil, 1098, nil, 1098, 1098, 1098, 1098, + 1098, 1098, 1098, nil, nil, nil, nil, nil, 1098, 1098, + 1098, 1098, 1098, 1098, 1098, nil, nil, 1098, nil, nil, + nil, nil, nil, 1098, 1098, 1098, 1098, 1098, 1098, 1098, + 1098, 1098, 1098, 1098, 1098, nil, 1098, 1098, 1098, nil, + 1098, 1098, 1098, 1098, 1098, 545, 545, 545, 545, 545, + 545, 545, nil, nil, 545, 545, nil, nil, nil, nil, + nil, 545, 545, nil, 1098, nil, nil, 1098, nil, nil, + 1098, 1098, nil, nil, 1098, nil, 1098, 545, nil, 545, + 1098, 545, 545, nil, 545, 545, 545, 545, 545, 1098, + 545, nil, nil, nil, 1098, 1098, 1098, 1098, nil, 1098, + 1098, 1098, 1098, nil, nil, nil, nil, 1098, 1098, nil, + nil, nil, nil, nil, nil, 1098, nil, 1098, 1098, 1098, + nil, nil, 1098, 1098, 1103, 1103, 1103, 1103, 1103, 1103, + nil, nil, nil, 1103, 1103, nil, nil, nil, 1103, nil, + 1103, 1103, 1103, 1103, 1103, 1103, 1103, nil, nil, nil, + nil, nil, 1103, 1103, 1103, 1103, 1103, 1103, 1103, nil, + nil, 1103, nil, nil, nil, nil, nil, 1103, 1103, 1103, + 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, nil, + 1103, 1103, 1103, nil, 1103, 1103, 1103, 1103, 1103, 548, + 548, 548, 548, 548, 548, 548, nil, nil, 548, 548, + nil, nil, nil, nil, nil, 548, 548, nil, 1103, nil, + nil, 1103, nil, nil, 1103, 1103, nil, nil, 1103, nil, + 1103, 548, nil, 548, 1103, 548, 548, nil, 548, 548, + 548, 548, 548, 1103, 548, nil, nil, nil, 1103, 1103, + 1103, 1103, nil, 1103, 1103, 1103, 1103, nil, nil, nil, + nil, 1103, 1103, nil, nil, nil, nil, nil, nil, 1103, + nil, 1103, 1103, 1103, nil, nil, 1103, 1103, 1147, 1147, + 1147, 1147, 1147, 1147, nil, nil, nil, 1147, 1147, nil, + nil, nil, 1147, nil, 1147, 1147, 1147, 1147, 1147, 1147, + 1147, nil, nil, nil, nil, nil, 1147, 1147, 1147, 1147, + 1147, 1147, 1147, nil, nil, 1147, nil, nil, nil, nil, + nil, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, 1147, + 1147, 1147, 1147, nil, 1147, 1147, 1147, nil, 1147, 1147, + 1147, 1147, 1147, 549, 549, 549, 549, 549, 549, 549, + 549, nil, 549, 549, nil, nil, nil, nil, nil, 549, + 549, nil, 1147, nil, nil, 1147, nil, nil, 1147, 1147, + nil, nil, 1147, nil, 1147, 549, nil, 549, 1147, 549, + 549, nil, 549, 549, 549, 549, 549, 1147, 549, nil, + nil, nil, 1147, 1147, 1147, 1147, nil, 1147, 1147, 1147, + 1147, nil, nil, nil, nil, 1147, 1147, nil, nil, nil, + nil, nil, nil, 1147, nil, 1147, 1147, 1147, nil, nil, + 1147, 1147, 1191, 1191, 1191, 1191, 1191, 1191, nil, nil, + nil, 1191, 1191, nil, nil, nil, 1191, nil, 1191, 1191, + 1191, 1191, 1191, 1191, 1191, nil, nil, nil, nil, nil, + 1191, 1191, 1191, 1191, 1191, 1191, 1191, nil, nil, 1191, + nil, nil, nil, nil, nil, 1191, 1191, 1191, 1191, 1191, + 1191, 1191, 1191, 1191, 1191, 1191, 1191, nil, 1191, 1191, + 1191, nil, 1191, 1191, 1191, 1191, 1191, 551, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 551, 551, nil, 1191, nil, nil, 1191, + nil, nil, 1191, 1191, nil, nil, 1191, nil, 1191, 551, + nil, 551, 1191, 551, 551, nil, 551, 551, nil, nil, + 551, 1191, 551, nil, nil, nil, 1191, 1191, 1191, 1191, + nil, 1191, 1191, 1191, 1191, nil, nil, nil, nil, 1191, + 1191, nil, nil, nil, nil, nil, nil, 1191, nil, 1191, + 1191, 1191, nil, nil, 1191, 1191, 7, 7, 7, 7, + 7, nil, nil, nil, 7, 7, nil, nil, nil, 7, + nil, 7, 7, 7, 7, 7, 7, 7, nil, nil, + nil, nil, nil, 7, 7, 7, 7, 7, 7, 7, + nil, nil, 7, nil, nil, nil, nil, nil, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + nil, 7, 7, 7, nil, 7, 7, 7, 7, 7, + 604, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 604, 604, nil, 7, + nil, nil, 7, nil, nil, 7, 7, nil, nil, 7, + nil, 7, 604, nil, 604, 7, 604, 604, nil, 604, + 604, nil, nil, 604, 7, 604, nil, nil, nil, 7, + 7, 7, 7, nil, 7, 7, 7, 7, nil, nil, + nil, nil, 7, 7, nil, nil, nil, 24, 24, 24, + 7, 24, 7, 7, 7, 24, 24, 7, 7, nil, + 24, nil, 24, 24, 24, 24, 24, 24, 24, nil, + nil, nil, nil, nil, 24, 24, 24, 24, 24, 24, + 24, nil, nil, 24, nil, nil, nil, nil, nil, nil, + 24, nil, nil, 24, 24, 24, 24, 24, 24, 24, + 24, nil, 24, 24, 24, nil, 24, 24, 24, 24, + 24, 537, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 537, 537, nil, + 24, nil, nil, 24, nil, nil, 24, 24, nil, nil, + 24, nil, nil, 537, nil, 537, 24, 537, 537, nil, + 537, 537, nil, nil, nil, 24, nil, nil, nil, nil, + 24, 24, 24, 24, nil, 24, 24, 24, 24, nil, + nil, nil, nil, 24, 24, nil, nil, nil, nil, nil, + nil, 24, nil, 24, 24, 24, 32, nil, 24, 24, + nil, nil, nil, 32, 32, 32, nil, nil, 32, 32, + 32, 538, 32, nil, nil, nil, nil, nil, nil, nil, + 32, 32, 32, 32, nil, nil, nil, 538, 538, nil, + nil, nil, 32, 32, nil, 32, 32, 32, 32, 32, + nil, nil, nil, 538, nil, 538, nil, 538, 538, nil, + 538, 538, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, nil, nil, 32, 32, + 32, nil, nil, 32, nil, 32, 32, nil, nil, 32, + 32, nil, 32, nil, 32, nil, 32, nil, 32, 32, + nil, 32, 32, 32, 32, 32, 33, 32, 32, 32, + nil, nil, nil, 33, 33, 33, nil, nil, 33, 33, + 33, nil, 33, 32, 539, nil, 32, 32, nil, 32, + 33, 32, 33, 33, nil, nil, nil, nil, 32, nil, + 539, 539, 33, 33, nil, 33, 33, 33, 33, 33, + nil, nil, nil, nil, nil, nil, 539, nil, nil, nil, + 539, 539, nil, 539, 539, nil, nil, nil, nil, nil, + nil, nil, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, nil, nil, 33, 33, + 33, nil, nil, 33, nil, 33, 33, nil, nil, 33, + 33, nil, 33, nil, 33, nil, 33, nil, 33, 33, + nil, 33, 33, 33, 33, 33, nil, 33, nil, 33, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 33, nil, nil, 33, 33, nil, 33, + nil, 33, 34, 34, 34, nil, 34, nil, 33, nil, + 34, 34, nil, nil, nil, 34, nil, 34, 34, 34, + 34, 34, 34, 34, nil, nil, nil, nil, nil, 34, + 34, 34, 34, 34, 34, 34, nil, nil, 34, nil, + nil, nil, nil, nil, nil, 34, nil, nil, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + nil, 34, 34, 34, 34, 34, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 34, nil, nil, 34, nil, + nil, 34, 34, nil, nil, 34, nil, 34, nil, 34, + nil, 34, nil, nil, 34, nil, nil, nil, nil, nil, + 34, nil, nil, nil, nil, 34, 34, 34, 34, nil, + 34, 34, 34, 34, nil, nil, nil, nil, 34, 34, + nil, nil, nil, 35, 35, 35, 34, 35, 34, 34, + 34, 35, 35, 34, 34, nil, 35, nil, 35, 35, + 35, 35, 35, 35, 35, nil, nil, nil, nil, nil, + 35, 35, 35, 35, 35, 35, 35, nil, nil, 35, + nil, nil, nil, nil, nil, nil, 35, nil, nil, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, nil, 35, 35, 35, 35, 35, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 35, nil, nil, 35, + nil, nil, 35, 35, nil, nil, 35, nil, 35, nil, + 35, nil, 35, nil, nil, 35, nil, nil, nil, nil, + nil, 35, nil, nil, nil, nil, 35, 35, 35, 35, + nil, 35, 35, 35, 35, nil, nil, nil, nil, 35, + 35, nil, nil, nil, 36, 36, 36, 35, 36, 35, + 35, 35, 36, 36, 35, 35, nil, 36, nil, 36, + 36, 36, 36, 36, 36, 36, nil, nil, nil, nil, + nil, 36, 36, 36, 36, 36, 36, 36, nil, nil, + 36, nil, nil, nil, nil, nil, nil, 36, nil, nil, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, nil, 36, 36, 36, 36, 36, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 36, nil, nil, + 36, nil, nil, 36, 36, nil, nil, 36, nil, 36, + nil, 36, nil, 36, nil, nil, 36, nil, nil, nil, + nil, nil, 36, nil, nil, nil, nil, 36, 36, 36, + 36, nil, 36, 36, 36, 36, nil, nil, nil, nil, + 36, 36, nil, nil, nil, 46, 46, 46, 36, 46, + 36, 36, 36, 46, 46, 36, 36, nil, 46, nil, + 46, 46, 46, 46, 46, 46, 46, nil, nil, nil, + nil, nil, 46, 46, 46, 46, 46, 46, 46, nil, + nil, 46, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 46, 46, 46, 46, 46, 46, 46, 46, nil, + 46, 46, 46, nil, 46, 46, 46, 46, 46, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 46, nil, nil, 46, 46, nil, nil, 46, nil, + nil, nil, nil, nil, 46, nil, nil, nil, nil, nil, + nil, nil, nil, 46, nil, nil, nil, nil, 46, 46, + 46, 46, nil, 46, 46, 46, 46, nil, nil, nil, + nil, 46, 46, nil, nil, nil, 47, 47, 47, 46, + 47, 46, 46, 46, 47, 47, 46, 46, nil, 47, + nil, 47, 47, 47, 47, 47, 47, 47, nil, nil, + nil, nil, nil, 47, 47, 47, 47, 47, 47, 47, + nil, nil, 47, nil, nil, nil, nil, nil, nil, 47, + nil, nil, 47, 47, 47, 47, 47, 47, 47, 47, + nil, 47, 47, 47, nil, 47, 47, 47, 47, 47, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 47, + nil, nil, 47, nil, nil, 47, 47, nil, nil, 47, + nil, nil, nil, nil, nil, 47, nil, nil, nil, nil, + nil, nil, nil, nil, 47, nil, nil, nil, nil, 47, + 47, 47, 47, nil, 47, 47, 47, 47, nil, nil, + nil, nil, 47, 47, nil, nil, nil, 49, 49, 49, + 47, 49, 47, 47, 47, 49, 49, 47, 47, nil, + 49, nil, 49, 49, 49, 49, 49, 49, 49, nil, + nil, nil, nil, nil, 49, 49, 49, 49, 49, 49, + 49, nil, nil, 49, nil, nil, nil, nil, nil, nil, + 49, nil, nil, 49, 49, 49, 49, 49, 49, 49, + 49, nil, 49, 49, 49, nil, 49, 49, 49, 49, + 49, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 49, nil, nil, 49, nil, nil, 49, 49, nil, nil, + 49, nil, nil, nil, nil, nil, 49, nil, nil, nil, + nil, nil, nil, nil, nil, 49, nil, nil, nil, nil, + 49, 49, 49, 49, nil, 49, 49, 49, 49, nil, + nil, nil, nil, 49, 49, nil, nil, nil, 50, 50, + 50, 49, 50, 49, 49, 49, 50, 50, 49, 49, + nil, 50, nil, 50, 50, 50, 50, 50, 50, 50, + nil, nil, nil, nil, nil, 50, 50, 50, 50, 50, + 50, 50, nil, nil, 50, nil, nil, nil, nil, nil, + nil, 50, nil, nil, 50, 50, 50, 50, 50, 50, + 50, 50, nil, 50, 50, 50, nil, 50, 50, 50, + 50, 50, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 50, nil, nil, 50, nil, nil, 50, 50, nil, + nil, 50, nil, nil, nil, nil, nil, 50, nil, nil, + nil, nil, nil, nil, nil, nil, 50, nil, nil, nil, + nil, 50, 50, 50, 50, nil, 50, 50, 50, 50, + nil, nil, nil, nil, 50, 50, nil, nil, nil, 52, + 52, 52, 50, 52, 50, 50, 50, 52, 52, 50, + 50, nil, 52, nil, 52, 52, 52, 52, 52, 52, + 52, nil, nil, nil, nil, nil, 52, 52, 52, 52, + 52, 52, 52, nil, nil, 52, nil, nil, nil, nil, + nil, nil, 52, nil, nil, 52, 52, 52, 52, 52, + 52, 52, 52, nil, 52, 52, 52, nil, 52, 52, + 52, 52, 52, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 52, nil, nil, 52, nil, nil, 52, 52, + nil, nil, 52, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, 52, 52, 52, 52, nil, 52, 52, 52, + 52, nil, nil, nil, nil, 52, 52, nil, nil, nil, + nil, nil, nil, 52, nil, 52, 52, 52, 64, nil, + 52, 52, nil, nil, nil, 64, 64, 64, nil, nil, + 64, 64, 64, nil, 64, nil, nil, nil, nil, nil, + nil, nil, 64, nil, 64, 64, 64, nil, nil, nil, + 762, 762, 762, 762, 64, 64, nil, 64, 64, 64, + 64, 64, nil, nil, nil, nil, 762, 762, 762, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 762, + 762, nil, nil, 762, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, nil, nil, + 64, 64, 64, nil, nil, 64, nil, nil, 64, nil, + nil, 64, 64, nil, 64, nil, 64, nil, 64, nil, + 64, 64, nil, 64, 64, 64, 64, 64, nil, 64, + nil, 64, nil, 762, 762, 762, 762, nil, 762, 762, + 762, 762, nil, nil, nil, 64, 762, 762, 64, 64, + 64, 64, nil, 64, 762, 64, 762, 762, 762, nil, + 64, 66, 66, 66, 66, 66, nil, nil, nil, 66, + 66, nil, nil, nil, 66, nil, 66, 66, 66, 66, + 66, 66, 66, nil, nil, nil, nil, nil, 66, 66, + 66, 66, 66, 66, 66, nil, nil, 66, nil, nil, + nil, nil, nil, 66, 66, nil, 66, 66, 66, 66, + 66, 66, 66, 66, 66, nil, 66, 66, 66, nil, + 66, 66, 66, 66, 66, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 66, nil, nil, 66, nil, nil, + 66, 66, nil, nil, 66, nil, 66, nil, nil, nil, + 66, nil, nil, nil, nil, nil, nil, nil, nil, 66, + nil, nil, nil, nil, 66, 66, 66, 66, nil, 66, + 66, 66, 66, nil, nil, nil, nil, 66, 66, nil, + nil, nil, 67, 67, 67, 66, 67, 66, 66, 66, + 67, 67, 66, 66, nil, 67, nil, 67, 67, 67, + 67, 67, 67, 67, nil, nil, nil, nil, nil, 67, + 67, 67, 67, 67, 67, 67, nil, nil, 67, nil, + nil, nil, nil, nil, nil, 67, nil, nil, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + nil, 67, 67, 67, 67, 67, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 67, nil, nil, 67, nil, + nil, 67, 67, nil, nil, 67, nil, 67, nil, nil, + nil, 67, nil, nil, 67, nil, nil, nil, nil, nil, + 67, nil, nil, nil, nil, 67, 67, 67, 67, nil, + 67, 67, 67, 67, nil, nil, nil, nil, 67, 67, + nil, nil, nil, 68, 68, 68, 67, 68, 67, 67, + 67, 68, 68, 67, 67, nil, 68, nil, 68, 68, + 68, 68, 68, 68, 68, nil, nil, nil, nil, nil, + 68, 68, 68, 68, 68, 68, 68, nil, nil, 68, + nil, nil, nil, nil, nil, nil, 68, nil, nil, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, nil, 68, 68, 68, 68, 68, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 68, nil, nil, 68, + nil, nil, 68, 68, nil, nil, 68, nil, nil, nil, + nil, nil, 68, nil, nil, 68, nil, nil, nil, nil, + nil, 68, nil, nil, nil, nil, 68, 68, 68, 68, + nil, 68, 68, 68, 68, nil, nil, nil, nil, 68, + 68, nil, nil, nil, 71, 71, 71, 68, 71, 68, + 68, 68, 71, 71, 68, 68, nil, 71, nil, 71, + 71, 71, 71, 71, 71, 71, nil, nil, nil, nil, + nil, 71, 71, 71, 71, 71, 71, 71, nil, nil, + 71, nil, nil, nil, nil, nil, nil, 71, nil, nil, + 71, 71, 71, 71, 71, 71, 71, 71, nil, 71, + 71, 71, nil, 71, 71, 71, 71, 71, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 71, nil, nil, + 71, nil, nil, 71, 71, nil, nil, 71, nil, nil, + nil, nil, nil, 71, nil, nil, nil, nil, nil, nil, + nil, nil, 71, nil, nil, nil, nil, 71, 71, 71, + 71, nil, 71, 71, 71, 71, nil, nil, nil, nil, + 71, 71, nil, nil, nil, 72, 72, 72, 71, 72, + 71, 71, 71, 72, 72, 71, 71, nil, 72, nil, + 72, 72, 72, 72, 72, 72, 72, nil, nil, nil, + nil, nil, 72, 72, 72, 72, 72, 72, 72, nil, + nil, 72, nil, nil, nil, nil, nil, nil, 72, nil, + nil, 72, 72, 72, 72, 72, 72, 72, 72, nil, + 72, 72, 72, nil, 72, 72, 72, 72, 72, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 72, nil, + nil, 72, nil, nil, 72, 72, nil, nil, 72, nil, + nil, nil, nil, nil, 72, nil, nil, nil, nil, nil, + nil, nil, nil, 72, nil, nil, nil, nil, 72, 72, + 72, 72, nil, 72, 72, 72, 72, nil, nil, nil, + nil, 72, 72, nil, nil, nil, 75, 75, 75, 72, + 75, 72, 72, 72, 75, 75, 72, 72, nil, 75, + nil, 75, 75, 75, 75, 75, 75, 75, nil, nil, + nil, nil, nil, 75, 75, 75, 75, 75, 75, 75, + nil, nil, 75, nil, nil, nil, nil, nil, nil, 75, + nil, nil, 75, 75, 75, 75, 75, 75, 75, 75, + nil, 75, 75, 75, nil, 75, 75, 75, 75, 75, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 75, + nil, nil, 75, nil, nil, 75, 75, nil, nil, 75, + nil, nil, nil, nil, nil, 75, nil, nil, nil, nil, + nil, nil, nil, nil, 75, nil, nil, nil, nil, 75, + 75, 75, 75, nil, 75, 75, 75, 75, nil, nil, + nil, nil, 75, 75, 75, nil, nil, nil, nil, 75, + 75, nil, 75, 75, 75, nil, nil, 75, 75, 124, + 124, 124, 124, 124, nil, nil, nil, 124, 124, nil, + nil, nil, 124, nil, 124, 124, 124, 124, 124, 124, + 124, nil, nil, nil, nil, nil, 124, 124, 124, 124, + 124, 124, 124, nil, nil, 124, nil, nil, nil, nil, + nil, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, nil, 124, 124, 124, nil, 124, 124, + 124, 124, 124, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 124, nil, nil, 124, nil, nil, 124, 124, + nil, nil, 124, nil, 124, nil, nil, nil, 124, nil, + nil, nil, nil, nil, nil, nil, nil, 124, nil, nil, + nil, nil, 124, 124, 124, 124, nil, 124, 124, 124, + 124, nil, nil, nil, nil, 124, 124, nil, nil, nil, + nil, nil, 124, 124, nil, 124, 124, 124, nil, nil, + 124, 124, 129, 129, 129, nil, 129, nil, nil, nil, + 129, 129, nil, nil, nil, 129, nil, 129, 129, 129, + 129, 129, 129, 129, nil, nil, nil, nil, nil, 129, + 129, 129, 129, 129, 129, 129, nil, nil, 129, nil, + nil, nil, nil, nil, nil, 129, nil, nil, 129, 129, + 129, 129, 129, 129, 129, 129, nil, 129, 129, 129, + nil, 129, 129, 129, 129, 129, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 129, nil, nil, 129, nil, + nil, 129, 129, nil, nil, 129, nil, nil, nil, nil, + nil, 129, nil, nil, nil, nil, nil, nil, nil, nil, + 129, nil, nil, nil, nil, 129, 129, 129, 129, nil, + 129, 129, 129, 129, nil, nil, nil, nil, 129, 129, + nil, nil, nil, 130, 130, 130, 129, 130, 129, 129, + 129, 130, 130, 129, 129, nil, 130, nil, 130, 130, + 130, 130, 130, 130, 130, nil, nil, nil, nil, nil, + 130, 130, 130, 130, 130, 130, 130, nil, nil, 130, + nil, nil, nil, nil, nil, nil, 130, nil, nil, 130, + 130, 130, 130, 130, 130, 130, 130, nil, 130, 130, + 130, nil, 130, 130, 130, 130, 130, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 130, nil, nil, 130, + nil, nil, 130, 130, nil, nil, 130, nil, nil, nil, + nil, nil, 130, nil, nil, nil, nil, nil, nil, nil, + nil, 130, nil, nil, nil, nil, 130, 130, 130, 130, + nil, 130, 130, 130, 130, nil, nil, nil, nil, 130, + 130, nil, nil, nil, 131, 131, 131, 130, 131, 130, + 130, 130, 131, 131, 130, 130, nil, 131, nil, 131, + 131, 131, 131, 131, 131, 131, nil, nil, nil, nil, + nil, 131, 131, 131, 131, 131, 131, 131, nil, nil, + 131, nil, nil, nil, nil, nil, nil, 131, nil, nil, + 131, 131, 131, 131, 131, 131, 131, 131, nil, 131, + 131, 131, nil, 131, 131, 131, 131, 131, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 131, nil, nil, + 131, nil, nil, 131, 131, nil, nil, 131, nil, nil, + nil, nil, nil, 131, nil, nil, nil, nil, nil, nil, + nil, nil, 131, nil, nil, nil, nil, 131, 131, 131, + 131, nil, 131, 131, 131, 131, nil, nil, nil, nil, + 131, 131, nil, nil, nil, 132, 132, 132, 131, 132, + 131, 131, 131, 132, 132, 131, 131, nil, 132, nil, + 132, 132, 132, 132, 132, 132, 132, nil, nil, nil, + nil, nil, 132, 132, 132, 132, 132, 132, 132, nil, + nil, 132, nil, nil, nil, nil, nil, nil, 132, nil, + nil, 132, 132, 132, 132, 132, 132, 132, 132, nil, + 132, 132, 132, nil, 132, 132, 132, 132, 132, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 132, nil, + nil, 132, nil, nil, 132, 132, nil, nil, 132, nil, + nil, nil, nil, nil, 132, nil, nil, nil, nil, nil, + nil, nil, nil, 132, nil, nil, nil, nil, 132, 132, + 132, 132, nil, 132, 132, 132, 132, nil, nil, nil, + nil, 132, 132, nil, nil, nil, nil, nil, nil, 132, + nil, 132, 132, 132, nil, nil, 132, 132, 133, 133, + 133, 133, 133, nil, nil, nil, 133, 133, nil, nil, + nil, 133, nil, 133, 133, 133, 133, 133, 133, 133, + nil, nil, nil, nil, nil, 133, 133, 133, 133, 133, + 133, 133, nil, nil, 133, nil, nil, nil, nil, nil, + 133, 133, nil, 133, 133, 133, 133, 133, 133, 133, + 133, 133, nil, 133, 133, 133, nil, 133, 133, 133, + 133, 133, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 133, nil, nil, 133, nil, nil, 133, 133, nil, + nil, 133, nil, 133, nil, nil, nil, 133, nil, nil, + nil, nil, nil, nil, nil, nil, 133, nil, nil, nil, + nil, 133, 133, 133, 133, nil, 133, 133, 133, 133, + nil, nil, nil, nil, 133, 133, nil, nil, nil, 219, + 219, 219, 133, 219, 133, 133, 133, 219, 219, 133, + 133, nil, 219, nil, 219, 219, 219, 219, 219, 219, + 219, nil, nil, nil, nil, nil, 219, 219, 219, 219, + 219, 219, 219, nil, nil, 219, nil, nil, nil, nil, + nil, nil, 219, nil, nil, 219, 219, 219, 219, 219, + 219, 219, 219, nil, 219, 219, 219, nil, 219, 219, + 219, 219, 219, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 219, nil, nil, 219, nil, nil, 219, 219, + nil, nil, 219, nil, 219, nil, nil, nil, 219, nil, + nil, nil, nil, nil, nil, nil, nil, 219, nil, nil, + nil, nil, 219, 219, 219, 219, nil, 219, 219, 219, + 219, nil, nil, nil, nil, 219, 219, nil, nil, nil, + 220, 220, 220, 219, 220, 219, 219, 219, 220, 220, + 219, 219, nil, 220, nil, 220, 220, 220, 220, 220, + 220, 220, nil, nil, nil, nil, nil, 220, 220, 220, + 220, 220, 220, 220, nil, nil, 220, nil, nil, nil, + nil, nil, nil, 220, nil, nil, 220, 220, 220, 220, + 220, 220, 220, 220, nil, 220, 220, 220, nil, 220, + 220, 220, 220, 220, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 220, nil, nil, 220, nil, nil, 220, + 220, nil, nil, 220, nil, 220, nil, nil, nil, 220, + nil, nil, nil, nil, nil, nil, nil, nil, 220, nil, + nil, nil, nil, 220, 220, 220, 220, nil, 220, 220, + 220, 220, nil, nil, nil, nil, 220, 220, nil, nil, + nil, 221, 221, 221, 220, 221, 220, 220, 220, 221, + 221, 220, 220, nil, 221, nil, 221, 221, 221, 221, + 221, 221, 221, nil, nil, nil, nil, nil, 221, 221, + 221, 221, 221, 221, 221, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 221, nil, nil, 221, 221, 221, + 221, 221, 221, 221, 221, nil, 221, 221, 221, nil, + 221, 221, 221, 221, 221, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 221, nil, nil, 221, nil, nil, + 221, 221, nil, nil, 221, nil, nil, nil, nil, nil, + 221, nil, nil, nil, nil, nil, nil, nil, nil, 221, + nil, nil, nil, nil, 221, 221, 221, 221, nil, 221, + 221, 221, 221, nil, nil, nil, nil, 221, 221, nil, + nil, nil, 222, 222, 222, 221, 222, 221, 221, 221, + 222, 222, 221, 221, nil, 222, nil, 222, 222, 222, + 222, 222, 222, 222, nil, nil, nil, nil, nil, 222, + 222, 222, 222, 222, 222, 222, nil, nil, 222, nil, + nil, nil, nil, nil, nil, 222, nil, nil, 222, 222, + 222, 222, 222, 222, 222, 222, nil, 222, 222, 222, + nil, 222, 222, 222, 222, 222, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 222, nil, nil, 222, nil, + nil, 222, 222, nil, nil, 222, nil, nil, nil, nil, + nil, 222, nil, nil, nil, nil, nil, nil, nil, nil, + 222, nil, nil, nil, nil, 222, 222, 222, 222, nil, + 222, 222, 222, 222, nil, nil, nil, nil, 222, 222, + nil, nil, nil, 223, 223, 223, 222, 223, 222, 222, + 222, 223, 223, 222, 222, nil, 223, nil, 223, 223, + 223, 223, 223, 223, 223, nil, nil, nil, nil, nil, + 223, 223, 223, 223, 223, 223, 223, nil, nil, 223, + nil, nil, nil, nil, nil, nil, 223, nil, nil, 223, + 223, 223, 223, 223, 223, 223, 223, nil, 223, 223, + 223, nil, 223, 223, 223, 223, 223, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 223, nil, nil, 223, + nil, nil, 223, 223, nil, nil, 223, nil, nil, nil, + nil, nil, 223, nil, nil, nil, nil, nil, nil, nil, + nil, 223, nil, nil, nil, nil, 223, 223, 223, 223, + nil, 223, 223, 223, 223, nil, nil, nil, nil, 223, + 223, nil, nil, nil, 224, 224, 224, 223, 224, 223, + 223, 223, 224, 224, 223, 223, nil, 224, nil, 224, + 224, 224, 224, 224, 224, 224, nil, nil, nil, nil, + nil, 224, 224, 224, 224, 224, 224, 224, nil, nil, + 224, nil, nil, nil, nil, nil, nil, 224, nil, nil, + 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, + 224, 224, nil, 224, 224, 224, 224, 224, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 224, nil, nil, + 224, nil, nil, 224, 224, nil, nil, 224, nil, 224, + nil, 224, nil, 224, nil, nil, 224, nil, nil, nil, + nil, nil, 224, nil, nil, nil, nil, 224, 224, 224, + 224, nil, 224, 224, 224, 224, nil, nil, nil, nil, + 224, 224, nil, nil, nil, 237, 237, 237, 224, 237, + 224, 224, 224, 237, 237, 224, 224, nil, 237, nil, + 237, 237, 237, 237, 237, 237, 237, nil, nil, nil, + nil, nil, 237, 237, 237, 237, 237, 237, 237, nil, + nil, 237, nil, nil, nil, nil, nil, nil, 237, nil, + nil, 237, 237, 237, 237, 237, 237, 237, 237, nil, + 237, 237, 237, nil, 237, 237, 237, 237, 237, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 237, nil, + nil, 237, nil, nil, 237, 237, nil, nil, 237, nil, + nil, nil, nil, nil, 237, nil, nil, nil, nil, nil, + nil, nil, nil, 237, nil, nil, nil, nil, 237, 237, + 237, 237, nil, 237, 237, 237, 237, nil, nil, nil, + nil, 237, 237, nil, nil, nil, 238, 238, 238, 237, + 238, 237, 237, 237, 238, 238, 237, 237, nil, 238, + nil, 238, 238, 238, 238, 238, 238, 238, nil, nil, + nil, nil, nil, 238, 238, 238, 238, 238, 238, 238, + nil, nil, 238, nil, nil, nil, nil, nil, nil, 238, + nil, nil, 238, 238, 238, 238, 238, 238, 238, 238, + nil, 238, 238, 238, nil, 238, 238, 238, 238, 238, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 238, + nil, nil, 238, nil, nil, 238, 238, nil, nil, 238, + nil, nil, nil, nil, nil, 238, nil, nil, nil, nil, + nil, nil, nil, nil, 238, nil, nil, nil, nil, 238, + 238, 238, 238, nil, 238, 238, 238, 238, nil, nil, + nil, nil, 238, 238, nil, nil, nil, 239, 239, 239, + 238, 239, 238, 238, 238, 239, 239, 238, 238, nil, + 239, nil, 239, 239, 239, 239, 239, 239, 239, nil, + nil, nil, nil, nil, 239, 239, 239, 239, 239, 239, + 239, nil, nil, 239, nil, nil, nil, nil, nil, nil, + 239, nil, nil, 239, 239, 239, 239, 239, 239, 239, + 239, nil, 239, 239, 239, nil, 239, 239, 239, 239, + 239, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 239, nil, nil, 239, nil, nil, 239, 239, nil, nil, + 239, nil, nil, nil, nil, nil, 239, nil, nil, nil, + nil, nil, nil, nil, nil, 239, nil, nil, nil, nil, + 239, 239, 239, 239, nil, 239, 239, 239, 239, nil, + nil, nil, nil, 239, 239, 239, nil, nil, 250, 250, + 250, 239, 250, 239, 239, 239, 250, 250, 239, 239, + nil, 250, nil, 250, 250, 250, 250, 250, 250, 250, + nil, nil, nil, nil, nil, 250, 250, 250, 250, 250, + 250, 250, nil, nil, 250, nil, nil, nil, nil, nil, + nil, 250, nil, nil, 250, 250, 250, 250, 250, 250, + 250, 250, nil, 250, 250, 250, nil, 250, 250, 250, + 250, 250, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 250, nil, nil, 250, nil, nil, 250, 250, nil, + nil, 250, nil, nil, nil, nil, nil, 250, nil, nil, + nil, nil, nil, nil, nil, nil, 250, nil, nil, nil, + nil, 250, 250, 250, 250, nil, 250, 250, 250, 250, + nil, nil, nil, nil, 250, 250, nil, nil, nil, 257, + 257, 257, 250, 257, 250, 250, 250, 257, 257, 250, + 250, nil, 257, nil, 257, 257, 257, 257, 257, 257, + 257, nil, nil, nil, nil, nil, 257, 257, 257, 257, + 257, 257, 257, nil, nil, 257, nil, nil, nil, nil, + nil, nil, 257, nil, nil, 257, 257, 257, 257, 257, + 257, 257, 257, nil, 257, 257, 257, nil, 257, 257, + 257, 257, 257, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 257, nil, nil, 257, nil, nil, 257, 257, + nil, nil, 257, nil, nil, nil, nil, nil, 257, nil, + nil, nil, nil, nil, nil, nil, nil, 257, nil, nil, + nil, nil, 257, 257, 257, 257, nil, 257, 257, 257, + 257, nil, nil, nil, nil, 257, 257, nil, nil, nil, + 258, 258, 258, 257, 258, 257, 257, 257, 258, 258, + 257, 257, nil, 258, nil, 258, 258, 258, 258, 258, + 258, 258, nil, nil, nil, nil, nil, 258, 258, 258, + 258, 258, 258, 258, nil, nil, 258, nil, nil, nil, + nil, nil, nil, 258, nil, nil, 258, 258, 258, 258, + 258, 258, 258, 258, nil, 258, 258, 258, nil, 258, + 258, 258, 258, 258, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 258, nil, nil, 258, nil, nil, 258, + 258, nil, nil, 258, nil, nil, nil, nil, nil, 258, + nil, nil, nil, nil, nil, nil, nil, nil, 258, nil, + nil, nil, nil, 258, 258, 258, 258, nil, 258, 258, + 258, 258, nil, nil, nil, nil, 258, 258, nil, nil, + nil, 259, 259, 259, 258, 259, 258, 258, 258, 259, + 259, 258, 258, nil, 259, nil, 259, 259, 259, 259, + 259, 259, 259, nil, nil, nil, nil, nil, 259, 259, + 259, 259, 259, 259, 259, nil, nil, 259, nil, nil, + nil, nil, nil, nil, 259, nil, nil, 259, 259, 259, + 259, 259, 259, 259, 259, nil, 259, 259, 259, nil, + 259, 259, 259, 259, 259, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 259, nil, nil, 259, nil, nil, + 259, 259, nil, nil, 259, nil, nil, nil, nil, nil, + 259, nil, nil, nil, nil, nil, nil, nil, nil, 259, + nil, nil, nil, nil, 259, 259, 259, 259, nil, 259, + 259, 259, 259, nil, nil, nil, nil, 259, 259, nil, + nil, nil, 260, 260, 260, 259, 260, 259, 259, 259, + 260, 260, 259, 259, nil, 260, nil, 260, 260, 260, + 260, 260, 260, 260, nil, nil, nil, nil, nil, 260, + 260, 260, 260, 260, 260, 260, nil, nil, 260, nil, + nil, nil, nil, nil, nil, 260, nil, nil, 260, 260, + 260, 260, 260, 260, 260, 260, nil, 260, 260, 260, + nil, 260, 260, 260, 260, 260, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 260, nil, nil, 260, nil, + nil, 260, 260, nil, nil, 260, nil, nil, nil, nil, + nil, 260, nil, nil, nil, nil, nil, nil, nil, nil, + 260, nil, nil, nil, nil, 260, 260, 260, 260, nil, + 260, 260, 260, 260, nil, nil, nil, nil, 260, 260, + nil, nil, nil, 261, 261, 261, 260, 261, 260, 260, + 260, 261, 261, 260, 260, nil, 261, nil, 261, 261, + 261, 261, 261, 261, 261, nil, nil, nil, nil, nil, + 261, 261, 261, 261, 261, 261, 261, nil, nil, 261, + nil, nil, nil, nil, nil, nil, 261, nil, nil, 261, + 261, 261, 261, 261, 261, 261, 261, nil, 261, 261, + 261, nil, 261, 261, 261, 261, 261, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 261, nil, nil, 261, + nil, nil, 261, 261, nil, nil, 261, nil, nil, nil, + nil, nil, 261, nil, nil, nil, nil, nil, nil, nil, + nil, 261, nil, nil, nil, nil, 261, 261, 261, 261, + nil, 261, 261, 261, 261, nil, nil, nil, nil, 261, + 261, nil, nil, nil, 262, 262, 262, 261, 262, 261, + 261, 261, 262, 262, 261, 261, nil, 262, nil, 262, + 262, 262, 262, 262, 262, 262, nil, nil, nil, nil, + nil, 262, 262, 262, 262, 262, 262, 262, nil, nil, + 262, nil, nil, nil, nil, nil, nil, 262, nil, nil, + 262, 262, 262, 262, 262, 262, 262, 262, nil, 262, + 262, 262, nil, 262, 262, 262, 262, 262, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 262, nil, nil, + 262, nil, nil, 262, 262, nil, nil, 262, nil, nil, + nil, nil, nil, 262, nil, nil, nil, nil, nil, nil, + nil, nil, 262, nil, nil, nil, nil, 262, 262, 262, + 262, nil, 262, 262, 262, 262, nil, nil, nil, nil, + 262, 262, nil, nil, nil, 263, 263, 263, 262, 263, + 262, 262, 262, 263, 263, 262, 262, nil, 263, nil, + 263, 263, 263, 263, 263, 263, 263, nil, nil, nil, + nil, nil, 263, 263, 263, 263, 263, 263, 263, nil, + nil, 263, nil, nil, nil, nil, nil, nil, 263, nil, + nil, 263, 263, 263, 263, 263, 263, 263, 263, nil, + 263, 263, 263, nil, 263, 263, 263, 263, 263, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 263, nil, + nil, 263, nil, nil, 263, 263, nil, nil, 263, nil, + nil, nil, nil, nil, 263, nil, nil, nil, nil, nil, + nil, nil, nil, 263, nil, nil, nil, nil, 263, 263, + 263, 263, nil, 263, 263, 263, 263, nil, nil, nil, + nil, 263, 263, nil, nil, nil, 264, 264, 264, 263, + 264, 263, 263, 263, 264, 264, 263, 263, nil, 264, + nil, 264, 264, 264, 264, 264, 264, 264, nil, nil, + nil, nil, nil, 264, 264, 264, 264, 264, 264, 264, + nil, nil, 264, nil, nil, nil, nil, nil, nil, 264, + nil, nil, 264, 264, 264, 264, 264, 264, 264, 264, + nil, 264, 264, 264, nil, 264, 264, 264, 264, 264, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 264, + nil, nil, 264, nil, nil, 264, 264, nil, nil, 264, + nil, nil, nil, nil, nil, 264, nil, nil, nil, nil, + nil, nil, nil, nil, 264, nil, nil, nil, nil, 264, + 264, 264, 264, nil, 264, 264, 264, 264, nil, nil, + nil, nil, 264, 264, nil, nil, nil, 265, 265, 265, + 264, 265, 264, 264, 264, 265, 265, 264, 264, nil, + 265, nil, 265, 265, 265, 265, 265, 265, 265, nil, + nil, nil, nil, nil, 265, 265, 265, 265, 265, 265, + 265, nil, nil, 265, nil, nil, nil, nil, nil, nil, + 265, nil, nil, 265, 265, 265, 265, 265, 265, 265, + 265, nil, 265, 265, 265, nil, 265, 265, 265, 265, + 265, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 265, nil, nil, 265, nil, nil, 265, 265, nil, nil, + 265, nil, nil, nil, nil, nil, 265, nil, nil, nil, + nil, nil, nil, nil, nil, 265, nil, nil, nil, nil, + 265, 265, 265, 265, nil, 265, 265, 265, 265, nil, + nil, nil, nil, 265, 265, nil, nil, nil, 266, 266, + 266, 265, 266, 265, 265, 265, 266, 266, 265, 265, + nil, 266, nil, 266, 266, 266, 266, 266, 266, 266, + nil, nil, nil, nil, nil, 266, 266, 266, 266, 266, + 266, 266, nil, nil, 266, nil, nil, nil, nil, nil, + nil, 266, nil, nil, 266, 266, 266, 266, 266, 266, + 266, 266, nil, 266, 266, 266, nil, 266, 266, 266, + 266, 266, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 266, nil, nil, 266, nil, nil, 266, 266, nil, + nil, 266, nil, nil, nil, nil, nil, 266, nil, nil, + nil, nil, nil, nil, nil, nil, 266, nil, nil, nil, + nil, 266, 266, 266, 266, nil, 266, 266, 266, 266, + nil, nil, nil, nil, 266, 266, nil, nil, nil, 267, + 267, 267, 266, 267, 266, 266, 266, 267, 267, 266, + 266, nil, 267, nil, 267, 267, 267, 267, 267, 267, + 267, nil, nil, nil, nil, nil, 267, 267, 267, 267, + 267, 267, 267, nil, nil, 267, nil, nil, nil, nil, + nil, nil, 267, nil, nil, 267, 267, 267, 267, 267, + 267, 267, 267, nil, 267, 267, 267, nil, 267, 267, + 267, 267, 267, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 267, nil, nil, 267, nil, nil, 267, 267, + nil, nil, 267, nil, nil, nil, nil, nil, 267, nil, + nil, nil, nil, nil, nil, nil, nil, 267, nil, nil, + nil, nil, 267, 267, 267, 267, nil, 267, 267, 267, + 267, nil, nil, nil, nil, 267, 267, nil, nil, nil, + 268, 268, 268, 267, 268, 267, 267, 267, 268, 268, + 267, 267, nil, 268, nil, 268, 268, 268, 268, 268, + 268, 268, nil, nil, nil, nil, nil, 268, 268, 268, + 268, 268, 268, 268, nil, nil, 268, nil, nil, nil, + nil, nil, nil, 268, nil, nil, 268, 268, 268, 268, + 268, 268, 268, 268, nil, 268, 268, 268, nil, 268, + 268, 268, 268, 268, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 268, nil, nil, 268, nil, nil, 268, + 268, nil, nil, 268, nil, nil, nil, nil, nil, 268, + nil, nil, nil, nil, nil, nil, nil, nil, 268, nil, + nil, nil, nil, 268, 268, 268, 268, nil, 268, 268, + 268, 268, nil, nil, nil, nil, 268, 268, nil, nil, + nil, 269, 269, 269, 268, 269, 268, 268, 268, 269, + 269, 268, 268, nil, 269, nil, 269, 269, 269, 269, + 269, 269, 269, nil, nil, nil, nil, nil, 269, 269, + 269, 269, 269, 269, 269, nil, nil, 269, nil, nil, + nil, nil, nil, nil, 269, nil, nil, 269, 269, 269, + 269, 269, 269, 269, 269, nil, 269, 269, 269, nil, + 269, 269, 269, 269, 269, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 269, nil, nil, 269, nil, nil, + 269, 269, nil, nil, 269, nil, nil, nil, nil, nil, + 269, nil, nil, nil, nil, nil, nil, nil, nil, 269, + nil, nil, nil, nil, 269, 269, 269, 269, nil, 269, + 269, 269, 269, nil, nil, nil, nil, 269, 269, nil, + nil, nil, 270, 270, 270, 269, 270, 269, 269, 269, + 270, 270, 269, 269, nil, 270, nil, 270, 270, 270, + 270, 270, 270, 270, nil, nil, nil, nil, nil, 270, + 270, 270, 270, 270, 270, 270, nil, nil, 270, nil, + nil, nil, nil, nil, nil, 270, nil, nil, 270, 270, + 270, 270, 270, 270, 270, 270, nil, 270, 270, 270, + nil, 270, 270, 270, 270, 270, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 270, nil, nil, 270, nil, + nil, 270, 270, nil, nil, 270, nil, nil, nil, nil, + nil, 270, nil, nil, nil, nil, nil, nil, nil, nil, + 270, nil, nil, nil, nil, 270, 270, 270, 270, nil, + 270, 270, 270, 270, nil, nil, nil, nil, 270, 270, + nil, nil, nil, 271, 271, 271, 270, 271, 270, 270, + 270, 271, 271, 270, 270, nil, 271, nil, 271, 271, + 271, 271, 271, 271, 271, nil, nil, nil, nil, nil, + 271, 271, 271, 271, 271, 271, 271, nil, nil, 271, + nil, nil, nil, nil, nil, nil, 271, nil, nil, 271, + 271, 271, 271, 271, 271, 271, 271, nil, 271, 271, + 271, nil, 271, 271, 271, 271, 271, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 271, nil, nil, 271, + nil, nil, 271, 271, nil, nil, 271, nil, nil, nil, + nil, nil, 271, nil, nil, nil, nil, nil, nil, nil, + nil, 271, nil, nil, nil, nil, 271, 271, 271, 271, + nil, 271, 271, 271, 271, nil, nil, nil, nil, 271, + 271, nil, nil, nil, 272, 272, 272, 271, 272, 271, + 271, 271, 272, 272, 271, 271, nil, 272, nil, 272, + 272, 272, 272, 272, 272, 272, nil, nil, nil, nil, + nil, 272, 272, 272, 272, 272, 272, 272, nil, nil, + 272, nil, nil, nil, nil, nil, nil, 272, nil, nil, + 272, 272, 272, 272, 272, 272, 272, 272, nil, 272, + 272, 272, nil, 272, 272, 272, 272, 272, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 272, nil, nil, + 272, nil, nil, 272, 272, nil, nil, 272, nil, nil, + nil, nil, nil, 272, nil, nil, nil, nil, nil, nil, + nil, nil, 272, nil, nil, nil, nil, 272, 272, 272, + 272, nil, 272, 272, 272, 272, nil, nil, nil, nil, + 272, 272, nil, nil, nil, 273, 273, 273, 272, 273, + 272, 272, 272, 273, 273, 272, 272, nil, 273, nil, + 273, 273, 273, 273, 273, 273, 273, nil, nil, nil, + nil, nil, 273, 273, 273, 273, 273, 273, 273, nil, + nil, 273, nil, nil, nil, nil, nil, nil, 273, nil, + nil, 273, 273, 273, 273, 273, 273, 273, 273, nil, + 273, 273, 273, nil, 273, 273, 273, 273, 273, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 273, nil, + nil, 273, nil, nil, 273, 273, nil, nil, 273, nil, + nil, nil, nil, nil, 273, nil, nil, nil, nil, nil, + nil, nil, nil, 273, nil, nil, nil, nil, 273, 273, + 273, 273, nil, 273, 273, 273, 273, nil, nil, nil, + nil, 273, 273, nil, nil, nil, 274, 274, 274, 273, + 274, 273, 273, 273, 274, 274, 273, 273, nil, 274, + nil, 274, 274, 274, 274, 274, 274, 274, nil, nil, + nil, nil, nil, 274, 274, 274, 274, 274, 274, 274, + nil, nil, 274, nil, nil, nil, nil, nil, nil, 274, + nil, nil, 274, 274, 274, 274, 274, 274, 274, 274, + nil, 274, 274, 274, nil, 274, 274, 274, 274, 274, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 274, + nil, nil, 274, nil, nil, 274, 274, nil, nil, 274, + nil, nil, nil, nil, nil, 274, nil, nil, nil, nil, + nil, nil, nil, nil, 274, nil, nil, nil, nil, 274, + 274, 274, 274, nil, 274, 274, 274, 274, nil, nil, + nil, nil, 274, 274, nil, nil, nil, 275, 275, 275, + 274, 275, 274, 274, 274, 275, 275, 274, 274, nil, + 275, nil, 275, 275, 275, 275, 275, 275, 275, nil, + nil, nil, nil, nil, 275, 275, 275, 275, 275, 275, + 275, nil, nil, 275, nil, nil, nil, nil, nil, nil, + 275, nil, nil, 275, 275, 275, 275, 275, 275, 275, + 275, nil, 275, 275, 275, nil, 275, 275, 275, 275, + 275, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 275, nil, nil, 275, nil, nil, 275, 275, nil, nil, + 275, nil, nil, nil, nil, nil, 275, nil, nil, nil, + nil, nil, nil, nil, nil, 275, nil, nil, nil, nil, + 275, 275, 275, 275, nil, 275, 275, 275, 275, nil, + nil, nil, nil, 275, 275, nil, nil, nil, 276, 276, + 276, 275, 276, 275, 275, 275, 276, 276, 275, 275, + nil, 276, nil, 276, 276, 276, 276, 276, 276, 276, + nil, nil, nil, nil, nil, 276, 276, 276, 276, 276, + 276, 276, nil, nil, 276, nil, nil, nil, nil, nil, + nil, 276, nil, nil, 276, 276, 276, 276, 276, 276, + 276, 276, nil, 276, 276, 276, nil, 276, 276, 276, + 276, 276, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 276, nil, nil, 276, nil, nil, 276, 276, nil, + nil, 276, nil, nil, nil, nil, nil, 276, nil, nil, + nil, nil, nil, nil, nil, nil, 276, nil, nil, nil, + nil, 276, 276, 276, 276, nil, 276, 276, 276, 276, + nil, nil, nil, nil, 276, 276, nil, nil, nil, 277, + 277, 277, 276, 277, 276, 276, 276, 277, 277, 276, + 276, nil, 277, nil, 277, 277, 277, 277, 277, 277, + 277, nil, nil, nil, nil, nil, 277, 277, 277, 277, + 277, 277, 277, nil, nil, 277, nil, nil, nil, nil, + nil, nil, 277, nil, nil, 277, 277, 277, 277, 277, + 277, 277, 277, nil, 277, 277, 277, nil, 277, 277, + 277, 277, 277, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 277, nil, nil, 277, nil, nil, 277, 277, + nil, nil, 277, nil, nil, nil, nil, nil, 277, nil, + nil, nil, nil, nil, nil, nil, nil, 277, nil, nil, + nil, nil, 277, 277, 277, 277, nil, 277, 277, 277, + 277, nil, nil, nil, nil, 277, 277, nil, nil, nil, + 278, 278, 278, 277, 278, 277, 277, 277, 278, 278, + 277, 277, nil, 278, nil, 278, 278, 278, 278, 278, + 278, 278, nil, nil, nil, nil, nil, 278, 278, 278, + 278, 278, 278, 278, nil, nil, 278, nil, nil, nil, + nil, nil, nil, 278, nil, nil, 278, 278, 278, 278, + 278, 278, 278, 278, nil, 278, 278, 278, nil, 278, + 278, 278, 278, 278, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 278, nil, nil, 278, nil, nil, 278, + 278, nil, nil, 278, nil, nil, nil, nil, nil, 278, + nil, nil, nil, nil, nil, nil, nil, nil, 278, nil, + nil, nil, nil, 278, 278, 278, 278, nil, 278, 278, + 278, 278, nil, nil, nil, nil, 278, 278, nil, nil, + nil, 283, 283, 283, 278, 283, 278, 278, 278, 283, + 283, 278, 278, nil, 283, nil, 283, 283, 283, 283, + 283, 283, 283, nil, nil, nil, nil, nil, 283, 283, + 283, 283, 283, 283, 283, nil, nil, 283, nil, nil, + nil, nil, nil, nil, 283, nil, nil, 283, 283, 283, + 283, 283, 283, 283, 283, nil, 283, 283, 283, nil, + 283, 283, 283, 283, 283, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 283, nil, nil, 283, nil, nil, + 283, 283, nil, nil, 283, nil, nil, nil, nil, nil, + 283, nil, nil, nil, nil, nil, nil, nil, nil, 283, + nil, nil, nil, nil, 283, 283, 283, 283, nil, 283, + 283, 283, 283, nil, nil, nil, nil, 283, 283, nil, + nil, nil, 299, 299, 299, 283, 299, 283, 283, 283, + 299, 299, 283, 283, nil, 299, nil, 299, 299, 299, + 299, 299, 299, 299, nil, nil, nil, nil, nil, 299, + 299, 299, 299, 299, 299, 299, nil, nil, 299, nil, + nil, nil, nil, nil, nil, 299, nil, nil, 299, 299, + 299, 299, 299, 299, 299, 299, nil, 299, 299, 299, + nil, 299, 299, 299, 299, 299, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 299, nil, nil, 299, nil, + nil, 299, 299, nil, nil, 299, nil, nil, nil, nil, + nil, 299, nil, nil, nil, nil, nil, nil, nil, nil, + 299, nil, nil, nil, nil, 299, 299, 299, 299, nil, + 299, 299, 299, 299, nil, nil, nil, nil, 299, 299, + nil, nil, nil, 306, 306, 306, 299, 306, 299, 299, + 299, 306, 306, 299, 299, nil, 306, nil, 306, 306, + 306, 306, 306, 306, 306, nil, nil, nil, nil, nil, + 306, 306, 306, 306, 306, 306, 306, nil, nil, 306, + nil, nil, nil, nil, nil, nil, 306, nil, nil, 306, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, nil, 306, 306, 306, 306, 306, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 306, nil, nil, 306, + nil, nil, 306, 306, nil, nil, 306, nil, 306, nil, + 306, nil, 306, nil, nil, 306, nil, nil, nil, nil, + nil, 306, nil, nil, nil, nil, 306, 306, 306, 306, + nil, 306, 306, 306, 306, nil, nil, nil, nil, 306, + 306, nil, nil, nil, 307, 307, 307, 306, 307, 306, + 306, 306, 307, 307, 306, 306, nil, 307, nil, 307, + 307, 307, 307, 307, 307, 307, nil, nil, nil, nil, + nil, 307, 307, 307, 307, 307, 307, 307, nil, nil, + 307, nil, nil, nil, nil, nil, nil, 307, nil, nil, + 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, + 307, 307, nil, 307, 307, 307, 307, 307, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 307, nil, nil, + 307, nil, nil, 307, 307, nil, nil, 307, nil, 307, + nil, 307, nil, 307, nil, nil, 307, nil, nil, nil, + nil, nil, 307, nil, nil, nil, nil, 307, 307, 307, + 307, nil, 307, 307, 307, 307, nil, nil, nil, nil, + 307, 307, nil, nil, nil, 315, 315, 315, 307, 315, + 307, 307, 307, 315, 315, 307, 307, nil, 315, nil, + 315, 315, 315, 315, 315, 315, 315, nil, nil, nil, + nil, nil, 315, 315, 315, 315, 315, 315, 315, nil, + nil, 315, nil, nil, nil, nil, nil, nil, 315, nil, + nil, 315, 315, 315, 315, 315, 315, 315, 315, 315, + 315, 315, 315, nil, 315, 315, 315, 315, 315, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 315, nil, + nil, 315, nil, nil, 315, 315, nil, nil, 315, nil, + 315, nil, 315, nil, 315, nil, nil, 315, nil, nil, + nil, nil, nil, 315, nil, nil, nil, nil, 315, 315, + 315, 315, nil, 315, 315, 315, 315, nil, nil, nil, + nil, 315, 315, 315, nil, nil, 322, 322, 322, 315, + 322, 315, 315, 315, 322, 322, 315, 315, nil, 322, + nil, 322, 322, 322, 322, 322, 322, 322, nil, nil, + nil, nil, nil, 322, 322, 322, 322, 322, 322, 322, + nil, nil, 322, nil, nil, nil, nil, nil, nil, 322, + nil, nil, 322, 322, 322, 322, 322, 322, 322, 322, + nil, 322, 322, 322, nil, 322, 322, 322, 322, 322, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 322, + nil, nil, 322, nil, nil, 322, 322, nil, nil, 322, + nil, nil, nil, nil, nil, 322, nil, nil, nil, nil, + nil, nil, nil, nil, 322, nil, nil, nil, nil, 322, + 322, 322, 322, nil, 322, 322, 322, 322, nil, nil, + nil, nil, 322, 322, nil, nil, nil, 324, 324, 324, + 322, 324, 322, 322, 322, 324, 324, 322, 322, nil, + 324, nil, 324, 324, 324, 324, 324, 324, 324, nil, + nil, nil, nil, nil, 324, 324, 324, 324, 324, 324, + 324, nil, nil, 324, nil, nil, nil, nil, nil, nil, + 324, nil, nil, 324, 324, 324, 324, 324, 324, 324, + 324, nil, 324, 324, 324, nil, 324, 324, 324, 324, + 324, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 324, nil, nil, 324, nil, nil, 324, 324, nil, nil, + 324, nil, nil, nil, nil, nil, 324, nil, nil, nil, + nil, nil, nil, nil, nil, 324, nil, nil, nil, nil, + 324, 324, 324, 324, nil, 324, 324, 324, 324, nil, + nil, nil, nil, 324, 324, nil, nil, nil, 327, 327, + 327, 324, 327, 324, 324, 324, 327, 327, 324, 324, + nil, 327, nil, 327, 327, 327, 327, 327, 327, 327, + nil, nil, nil, nil, nil, 327, 327, 327, 327, 327, + 327, 327, nil, nil, 327, nil, nil, nil, nil, nil, + nil, 327, nil, nil, 327, 327, 327, 327, 327, 327, + 327, 327, nil, 327, 327, 327, nil, 327, 327, 327, + 327, 327, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 327, nil, nil, 327, nil, nil, 327, 327, nil, + nil, 327, nil, nil, nil, nil, nil, 327, nil, nil, + nil, nil, nil, nil, nil, nil, 327, nil, nil, nil, + nil, 327, 327, 327, 327, nil, 327, 327, 327, 327, + nil, nil, nil, nil, 327, 327, nil, nil, nil, 328, + 328, 328, 327, 328, 327, 327, 327, 328, 328, 327, + 327, nil, 328, nil, 328, 328, 328, 328, 328, 328, + 328, nil, nil, nil, nil, nil, 328, 328, 328, 328, + 328, 328, 328, nil, nil, 328, nil, nil, nil, nil, + nil, nil, 328, nil, nil, 328, 328, 328, 328, 328, + 328, 328, 328, nil, 328, 328, 328, nil, 328, 328, + 328, 328, 328, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 328, nil, nil, 328, nil, nil, 328, 328, + nil, nil, 328, nil, nil, nil, nil, nil, 328, nil, + nil, nil, nil, nil, nil, nil, nil, 328, nil, nil, + nil, nil, 328, 328, 328, 328, nil, 328, 328, 328, + 328, nil, nil, nil, nil, 328, 328, nil, nil, nil, + nil, nil, nil, 328, nil, 328, 328, 328, nil, nil, + 328, 328, 333, 333, 333, 333, 333, nil, nil, nil, + 333, 333, nil, nil, nil, 333, nil, 333, 333, 333, + 333, 333, 333, 333, nil, nil, nil, nil, nil, 333, + 333, 333, 333, 333, 333, 333, nil, nil, 333, nil, + nil, nil, nil, nil, 333, 333, nil, 333, 333, 333, + 333, 333, 333, 333, 333, 333, nil, 333, 333, 333, + nil, 333, 333, 333, 333, 333, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 333, nil, nil, 333, nil, + nil, 333, 333, nil, nil, 333, nil, 333, nil, nil, + nil, 333, nil, nil, nil, nil, nil, nil, nil, nil, + 333, nil, nil, nil, nil, 333, 333, 333, 333, nil, + 333, 333, 333, 333, nil, nil, nil, nil, 333, 333, + nil, nil, nil, 369, 369, 369, 333, 369, 333, 333, + 333, 369, 369, 333, 333, nil, 369, nil, 369, 369, + 369, 369, 369, 369, 369, nil, nil, nil, nil, nil, + 369, 369, 369, 369, 369, 369, 369, nil, nil, 369, + nil, nil, nil, nil, nil, nil, 369, nil, nil, 369, + 369, 369, 369, 369, 369, 369, 369, nil, 369, 369, + 369, nil, 369, 369, 369, 369, 369, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 369, nil, nil, 369, + nil, nil, 369, 369, nil, nil, 369, nil, nil, nil, + nil, nil, 369, nil, nil, nil, nil, nil, nil, nil, + nil, 369, nil, nil, nil, nil, 369, 369, 369, 369, + nil, 369, 369, 369, 369, nil, nil, nil, nil, 369, + 369, nil, nil, nil, 386, 386, 386, 369, 386, 369, + 369, 369, 386, 386, 369, 369, nil, 386, nil, 386, + 386, 386, 386, 386, 386, 386, nil, nil, nil, nil, + nil, 386, 386, 386, 386, 386, 386, 386, nil, nil, + 386, nil, nil, nil, nil, nil, nil, 386, nil, nil, + 386, 386, 386, 386, 386, 386, 386, 386, nil, 386, + 386, 386, nil, 386, 386, 386, 386, 386, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 386, nil, nil, + 386, nil, nil, 386, 386, nil, nil, 386, nil, nil, + nil, nil, nil, 386, nil, nil, nil, nil, nil, nil, + nil, nil, 386, nil, nil, nil, nil, 386, 386, 386, + 386, nil, 386, 386, 386, 386, nil, nil, nil, nil, + 386, 386, nil, nil, nil, 407, 407, 407, 386, 407, + 386, 386, 386, 407, 407, 386, 386, nil, 407, nil, + 407, 407, 407, 407, 407, 407, 407, nil, nil, nil, + nil, nil, 407, 407, 407, 407, 407, 407, 407, nil, + nil, 407, nil, nil, nil, nil, nil, nil, 407, nil, + nil, 407, 407, 407, 407, 407, 407, 407, 407, nil, + 407, 407, 407, nil, 407, 407, 407, 407, 407, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 407, nil, + nil, 407, nil, nil, 407, 407, nil, nil, 407, nil, + nil, nil, nil, nil, 407, nil, nil, nil, nil, nil, + nil, nil, nil, 407, nil, nil, nil, nil, 407, 407, + 407, 407, nil, 407, 407, 407, 407, nil, nil, nil, + nil, 407, 407, nil, nil, nil, 436, 436, 436, 407, + 436, 407, 407, 407, 436, 436, 407, 407, nil, 436, + nil, 436, 436, 436, 436, 436, 436, 436, nil, nil, + nil, nil, nil, 436, 436, 436, 436, 436, 436, 436, + nil, nil, 436, nil, nil, nil, nil, nil, nil, 436, + nil, nil, 436, 436, 436, 436, 436, 436, 436, 436, + nil, 436, 436, 436, nil, 436, 436, 436, 436, 436, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 436, + nil, nil, 436, nil, nil, 436, 436, nil, nil, 436, + nil, nil, nil, nil, nil, 436, nil, nil, nil, nil, + nil, nil, nil, nil, 436, nil, nil, nil, nil, 436, + 436, 436, 436, nil, 436, 436, 436, 436, nil, nil, + nil, nil, 436, 436, nil, nil, nil, nil, nil, nil, + 436, nil, 436, 436, 436, 460, nil, 436, 436, nil, + nil, nil, 460, 460, 460, nil, nil, 460, 460, 460, + nil, 460, nil, nil, nil, nil, nil, nil, nil, 460, + 460, 460, 460, nil, nil, nil, nil, nil, nil, nil, + nil, 460, 460, nil, 460, 460, 460, 460, 460, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 460, 460, 460, 460, 460, 460, 460, 460, 460, + 460, 460, 460, 460, 460, nil, nil, 460, 460, 460, + nil, nil, 460, nil, 460, 460, nil, nil, 460, 460, + nil, 460, nil, 460, nil, 460, nil, 460, 460, nil, + 460, 460, 460, 460, 460, nil, 460, 460, 460, 1140, + nil, 1140, 1140, 1140, 1140, 1140, nil, nil, nil, nil, + nil, nil, 460, nil, 1140, 460, 460, 469, 460, nil, + 460, nil, nil, nil, 469, 469, 469, 460, nil, 469, + 469, 469, nil, 469, nil, nil, 1140, nil, nil, nil, + nil, 469, 469, 469, 469, 469, nil, 1140, 1140, nil, + nil, nil, 1140, 469, 469, nil, 469, 469, 469, 469, + 469, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 469, 469, 469, 469, 469, 469, 469, + 469, 469, 469, 469, 469, 469, 469, nil, nil, 469, + 469, 469, nil, nil, 469, nil, nil, 469, nil, nil, + 469, 469, nil, 469, nil, 469, nil, 469, nil, 469, + 469, nil, 469, 469, 469, 469, 469, nil, 469, 469, + 469, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 469, nil, nil, 469, 469, 469, + 469, nil, 469, 470, 469, nil, nil, nil, nil, 469, + 470, 470, 470, nil, nil, 470, 470, 470, nil, 470, + nil, nil, nil, nil, nil, nil, nil, 470, 470, 470, + 470, 470, nil, nil, nil, nil, nil, nil, nil, 470, + 470, nil, 470, 470, 470, 470, 470, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 470, + 470, 470, 470, 470, 470, 470, 470, 470, 470, 470, + 470, 470, 470, nil, nil, 470, 470, 470, nil, nil, + 470, nil, nil, 470, nil, nil, 470, 470, nil, 470, + nil, 470, nil, 470, nil, 470, 470, nil, 470, 470, + 470, 470, 470, nil, 470, 470, 470, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 470, nil, nil, 470, 470, 470, 470, nil, 470, nil, + 470, nil, 471, 471, 471, 470, 471, nil, nil, nil, + 471, 471, nil, nil, nil, 471, nil, 471, 471, 471, + 471, 471, 471, 471, nil, nil, nil, nil, nil, 471, + 471, 471, 471, 471, 471, 471, nil, nil, 471, nil, + nil, nil, nil, nil, nil, 471, nil, nil, 471, 471, + 471, 471, 471, 471, 471, 471, nil, 471, 471, 471, + nil, 471, 471, 471, 471, 471, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 471, nil, nil, 471, nil, + nil, 471, 471, nil, nil, 471, nil, nil, nil, nil, + nil, 471, nil, nil, nil, nil, nil, nil, nil, nil, + 471, nil, nil, nil, nil, 471, 471, 471, 471, nil, + 471, 471, 471, 471, nil, nil, nil, nil, 471, 471, + nil, nil, nil, 497, 497, 497, 471, 497, 471, 471, + 471, 497, 497, 471, 471, nil, 497, nil, 497, 497, + 497, 497, 497, 497, 497, nil, nil, nil, nil, nil, + 497, 497, 497, 497, 497, 497, 497, nil, nil, 497, + nil, nil, nil, nil, nil, nil, 497, nil, nil, 497, + 497, 497, 497, 497, 497, 497, 497, nil, 497, 497, + 497, nil, 497, 497, 497, 497, 497, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 497, nil, nil, 497, + nil, nil, 497, 497, nil, nil, 497, nil, nil, nil, + nil, nil, 497, nil, nil, nil, nil, nil, nil, nil, + nil, 497, nil, nil, nil, nil, 497, 497, 497, 497, + nil, 497, 497, 497, 497, nil, nil, nil, nil, 497, + 497, nil, nil, nil, 510, 510, 510, 497, 510, 497, + 497, 497, 510, 510, 497, 497, nil, 510, nil, 510, + 510, 510, 510, 510, 510, 510, nil, nil, nil, nil, + nil, 510, 510, 510, 510, 510, 510, 510, nil, nil, + 510, nil, nil, nil, nil, nil, nil, 510, nil, nil, + 510, 510, 510, 510, 510, 510, 510, 510, nil, 510, + 510, 510, nil, 510, 510, 510, 510, 510, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 510, nil, nil, + 510, nil, nil, 510, 510, nil, nil, 510, nil, nil, + nil, nil, nil, 510, nil, nil, nil, nil, nil, nil, + nil, nil, 510, nil, nil, nil, nil, 510, 510, 510, + 510, nil, 510, 510, 510, 510, nil, nil, nil, nil, + 510, 510, nil, nil, nil, 520, 520, 520, 510, 520, + 510, 510, 510, 520, 520, 510, 510, nil, 520, nil, + 520, 520, 520, 520, 520, 520, 520, nil, nil, nil, + nil, nil, 520, 520, 520, 520, 520, 520, 520, nil, + nil, 520, nil, nil, nil, nil, nil, nil, 520, nil, + nil, 520, 520, 520, 520, 520, 520, 520, 520, 520, + 520, 520, 520, nil, 520, 520, 520, 520, 520, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 520, nil, + nil, 520, nil, nil, 520, 520, nil, nil, 520, nil, + 520, nil, 520, nil, 520, nil, nil, 520, nil, nil, + nil, nil, nil, 520, nil, nil, nil, nil, 520, 520, + 520, 520, nil, 520, 520, 520, 520, nil, nil, nil, + nil, 520, 520, nil, nil, nil, 522, 522, 522, 520, + 522, 520, 520, 520, 522, 522, 520, 520, nil, 522, + nil, 522, 522, 522, 522, 522, 522, 522, nil, nil, + nil, nil, nil, 522, 522, 522, 522, 522, 522, 522, + nil, nil, 522, nil, nil, nil, nil, nil, nil, 522, + nil, nil, 522, 522, 522, 522, 522, 522, 522, 522, + nil, 522, 522, 522, nil, 522, 522, 522, 522, 522, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 522, + nil, nil, 522, nil, nil, 522, 522, nil, nil, 522, + nil, nil, nil, nil, nil, 522, nil, nil, nil, nil, + nil, nil, nil, nil, 522, nil, nil, nil, nil, 522, + 522, 522, 522, nil, 522, 522, 522, 522, nil, nil, + nil, nil, 522, 522, nil, nil, nil, 523, 523, 523, + 522, 523, 522, 522, 522, 523, 523, 522, 522, nil, + 523, nil, 523, 523, 523, 523, 523, 523, 523, nil, + nil, nil, nil, nil, 523, 523, 523, 523, 523, 523, + 523, nil, nil, 523, nil, nil, nil, nil, nil, nil, + 523, nil, nil, 523, 523, 523, 523, 523, 523, 523, + 523, nil, 523, 523, 523, nil, 523, 523, 523, 523, + 523, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 523, nil, nil, 523, nil, nil, 523, 523, nil, nil, + 523, nil, nil, nil, nil, nil, 523, nil, nil, nil, + nil, nil, nil, nil, nil, 523, nil, nil, nil, nil, + 523, 523, 523, 523, nil, 523, 523, 523, 523, nil, + nil, nil, nil, 523, 523, nil, nil, nil, 524, 524, + 524, 523, 524, 523, 523, 523, 524, 524, 523, 523, + nil, 524, nil, 524, 524, 524, 524, 524, 524, 524, + nil, nil, nil, nil, nil, 524, 524, 524, 524, 524, + 524, 524, nil, nil, 524, nil, nil, nil, nil, nil, + nil, 524, nil, nil, 524, 524, 524, 524, 524, 524, + 524, 524, nil, 524, 524, 524, nil, 524, 524, 524, + 524, 524, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 524, nil, nil, 524, nil, nil, 524, 524, nil, + nil, 524, nil, nil, nil, nil, nil, 524, nil, nil, + nil, nil, nil, nil, nil, nil, 524, nil, nil, nil, + nil, 524, 524, 524, 524, nil, 524, 524, 524, 524, + nil, nil, nil, nil, 524, 524, nil, nil, nil, nil, + nil, nil, 524, nil, 524, 524, 524, 555, nil, 524, + 524, nil, nil, nil, 555, 555, 555, nil, nil, 555, + 555, 555, 409, 555, 409, 409, 409, 409, 409, nil, + nil, 555, 555, 555, nil, nil, nil, 409, nil, nil, + nil, nil, nil, 555, 555, nil, 555, 555, 555, 555, + 555, nil, 644, nil, 644, 644, 644, 644, 644, 409, + 409, nil, nil, nil, nil, nil, nil, 644, 409, 409, + 409, 409, nil, nil, nil, 409, nil, 1135, nil, 1135, + 1135, 1135, 1135, 1135, 555, nil, nil, nil, nil, 644, + nil, 555, 1135, nil, nil, nil, 555, 555, 644, 644, + 644, 644, nil, nil, nil, 644, nil, nil, nil, nil, + nil, nil, nil, nil, 1135, 409, nil, nil, nil, 555, + 555, nil, nil, 1135, 1135, 1135, 1135, nil, nil, nil, + 1135, nil, nil, nil, 555, nil, nil, 555, nil, 560, + 560, 560, 555, 560, nil, 644, nil, 560, 560, 555, + nil, nil, 560, nil, 560, 560, 560, 560, 560, 560, + 560, nil, nil, nil, nil, nil, 560, 560, 560, 560, + 560, 560, 560, nil, nil, 560, nil, nil, nil, nil, + nil, nil, 560, nil, nil, 560, 560, 560, 560, 560, + 560, 560, 560, nil, 560, 560, 560, nil, 560, 560, + 560, 560, 560, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 560, nil, nil, 560, nil, nil, 560, 560, + nil, nil, 560, nil, nil, nil, nil, nil, 560, nil, + nil, nil, nil, nil, nil, nil, nil, 560, nil, nil, + nil, nil, 560, 560, 560, 560, nil, 560, 560, 560, + 560, nil, nil, nil, nil, 560, 560, nil, nil, nil, + 570, 570, 570, 560, 570, 560, 560, 560, 570, 570, + 560, 560, nil, 570, nil, 570, 570, 570, 570, 570, + 570, 570, nil, nil, nil, nil, nil, 570, 570, 570, + 570, 570, 570, 570, nil, nil, 570, nil, nil, nil, + nil, nil, nil, 570, nil, nil, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, nil, 570, + 570, 570, 570, 570, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 570, nil, nil, 570, nil, nil, 570, + 570, nil, nil, 570, nil, 570, nil, 570, nil, 570, + nil, nil, 570, nil, nil, nil, nil, nil, 570, nil, + nil, nil, nil, 570, 570, 570, 570, nil, 570, 570, + 570, 570, nil, nil, nil, nil, 570, 570, nil, nil, + nil, 572, 572, 572, 570, 572, 570, 570, 570, 572, + 572, 570, 570, nil, 572, nil, 572, 572, 572, 572, + 572, 572, 572, nil, nil, nil, nil, nil, 572, 572, + 572, 572, 572, 572, 572, nil, nil, 572, nil, nil, + nil, nil, nil, nil, 572, nil, nil, 572, 572, 572, + 572, 572, 572, 572, 572, 572, 572, 572, 572, nil, + 572, 572, 572, 572, 572, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 572, nil, nil, 572, nil, nil, + 572, 572, nil, nil, 572, nil, nil, nil, 572, nil, + 572, nil, nil, 572, nil, nil, nil, nil, nil, 572, + nil, nil, nil, nil, 572, 572, 572, 572, nil, 572, + 572, 572, 572, nil, nil, nil, nil, 572, 572, nil, + nil, nil, 574, 574, 574, 572, 574, 572, 572, 572, + 574, 574, 572, 572, nil, 574, nil, 574, 574, 574, + 574, 574, 574, 574, nil, nil, nil, nil, nil, 574, + 574, 574, 574, 574, 574, 574, nil, nil, 574, nil, + nil, nil, nil, nil, nil, 574, nil, nil, 574, 574, + 574, 574, 574, 574, 574, 574, nil, 574, 574, 574, + nil, 574, 574, 574, 574, 574, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 574, nil, nil, 574, nil, + nil, 574, 574, nil, nil, 574, nil, nil, nil, nil, + nil, 574, nil, nil, nil, nil, nil, nil, nil, nil, + 574, nil, nil, nil, nil, 574, 574, 574, 574, nil, + 574, 574, 574, 574, nil, nil, nil, nil, 574, 574, + nil, nil, nil, nil, nil, nil, 574, nil, 574, 574, + 574, nil, nil, 574, 574, 580, 580, 580, 580, 580, + nil, nil, nil, 580, 580, nil, nil, nil, 580, nil, + 580, 580, 580, 580, 580, 580, 580, nil, nil, nil, + nil, nil, 580, 580, 580, 580, 580, 580, 580, nil, + nil, 580, nil, nil, nil, nil, nil, 580, 580, 580, + 580, 580, 580, 580, 580, 580, 580, 580, 580, nil, + 580, 580, 580, nil, 580, 580, 580, 580, 580, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 580, nil, + nil, 580, nil, nil, 580, 580, nil, nil, 580, nil, + 580, nil, nil, nil, 580, nil, nil, nil, nil, nil, + nil, nil, nil, 580, nil, nil, nil, nil, 580, 580, + 580, 580, nil, 580, 580, 580, 580, nil, nil, nil, + nil, 580, 580, nil, nil, nil, nil, nil, 580, 580, + nil, 580, 580, 580, nil, nil, 580, 580, 590, 590, + 590, nil, 590, nil, nil, nil, 590, 590, nil, nil, + nil, 590, nil, 590, 590, 590, 590, 590, 590, 590, + nil, nil, nil, nil, nil, 590, 590, 590, 590, 590, + 590, 590, nil, nil, 590, nil, nil, nil, nil, nil, + nil, 590, nil, nil, 590, 590, 590, 590, 590, 590, + 590, 590, 590, 590, 590, 590, nil, 590, 590, 590, + 590, 590, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 590, nil, nil, 590, nil, nil, 590, 590, nil, + nil, 590, nil, 590, nil, 590, nil, 590, nil, nil, + 590, nil, nil, nil, nil, nil, 590, nil, nil, nil, + nil, 590, 590, 590, 590, nil, 590, 590, 590, 590, + nil, nil, nil, nil, 590, 590, nil, nil, nil, 600, + 600, 600, 590, 600, 590, 590, 590, 600, 600, 590, + 590, nil, 600, nil, 600, 600, 600, 600, 600, 600, + 600, nil, nil, nil, nil, nil, 600, 600, 600, 600, + 600, 600, 600, nil, nil, 600, nil, nil, nil, nil, + nil, nil, 600, nil, nil, 600, 600, 600, 600, 600, + 600, 600, 600, nil, 600, 600, 600, nil, 600, 600, + 600, 600, 600, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 600, nil, nil, 600, nil, nil, 600, 600, + nil, nil, 600, nil, nil, nil, nil, nil, 600, nil, + nil, nil, nil, nil, nil, nil, nil, 600, nil, nil, + nil, nil, 600, 600, 600, 600, nil, 600, 600, 600, + 600, nil, nil, nil, nil, 600, 600, nil, nil, nil, + 603, 603, 603, 600, 603, 600, 600, 600, 603, 603, + 600, 600, nil, 603, nil, 603, 603, 603, 603, 603, + 603, 603, nil, nil, nil, nil, nil, 603, 603, 603, + 603, 603, 603, 603, nil, nil, 603, nil, nil, nil, + nil, nil, nil, 603, nil, nil, 603, 603, 603, 603, + 603, 603, 603, 603, nil, 603, 603, 603, nil, 603, + 603, 603, 603, 603, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 603, nil, nil, 603, nil, nil, 603, + 603, nil, nil, 603, nil, nil, nil, nil, nil, 603, + nil, nil, nil, nil, nil, nil, nil, nil, 603, nil, + nil, nil, nil, 603, 603, 603, 603, nil, 603, 603, + 603, 603, nil, nil, nil, nil, 603, 603, nil, nil, + nil, 605, 605, 605, 603, 605, 603, 603, 603, 605, + 605, 603, 603, nil, 605, nil, 605, 605, 605, 605, + 605, 605, 605, nil, nil, nil, nil, nil, 605, 605, + 605, 605, 605, 605, 605, nil, nil, 605, nil, nil, + nil, nil, nil, nil, 605, nil, nil, 605, 605, 605, + 605, 605, 605, 605, 605, nil, 605, 605, 605, nil, + 605, 605, 605, 605, 605, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 605, nil, nil, 605, nil, nil, + 605, 605, nil, nil, 605, nil, nil, nil, nil, nil, + 605, nil, nil, nil, nil, nil, nil, nil, nil, 605, + nil, nil, nil, nil, 605, 605, 605, 605, nil, 605, + 605, 605, 605, nil, nil, nil, nil, 605, 605, nil, + nil, nil, 611, 611, 611, 605, 611, 605, 605, 605, + 611, 611, 605, 605, nil, 611, nil, 611, 611, 611, + 611, 611, 611, 611, nil, nil, nil, nil, nil, 611, + 611, 611, 611, 611, 611, 611, nil, nil, 611, nil, + nil, nil, nil, nil, nil, 611, nil, nil, 611, 611, + 611, 611, 611, 611, 611, 611, 611, 611, 611, 611, + nil, 611, 611, 611, 611, 611, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 611, nil, nil, 611, nil, + nil, 611, 611, nil, nil, 611, nil, 611, nil, nil, + nil, 611, nil, nil, 611, nil, nil, nil, nil, nil, + 611, nil, nil, nil, nil, 611, 611, 611, 611, nil, + 611, 611, 611, 611, nil, nil, nil, nil, 611, 611, + nil, nil, nil, 614, 614, 614, 611, 614, 611, 611, + 611, 614, 614, 611, 611, nil, 614, nil, 614, 614, + 614, 614, 614, 614, 614, nil, nil, nil, nil, nil, + 614, 614, 614, 614, 614, 614, 614, nil, nil, 614, + nil, nil, nil, nil, nil, nil, 614, nil, nil, 614, + 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, + 614, nil, 614, 614, 614, 614, 614, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 614, nil, nil, 614, + nil, nil, 614, 614, nil, nil, 614, nil, nil, nil, + nil, nil, 614, nil, nil, 614, nil, nil, nil, nil, + nil, 614, nil, nil, nil, nil, 614, 614, 614, 614, + nil, 614, 614, 614, 614, nil, nil, nil, nil, 614, + 614, nil, nil, nil, 627, 627, 627, 614, 627, 614, + 614, 614, 627, 627, 614, 614, nil, 627, nil, 627, + 627, 627, 627, 627, 627, 627, nil, nil, nil, nil, + nil, 627, 627, 627, 627, 627, 627, 627, nil, nil, + 627, nil, nil, nil, nil, nil, nil, 627, nil, nil, + 627, 627, 627, 627, 627, 627, 627, 627, nil, 627, + 627, 627, nil, 627, 627, 627, 627, 627, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 627, nil, nil, + 627, nil, nil, 627, 627, nil, nil, 627, nil, 627, + nil, nil, nil, 627, nil, nil, nil, nil, nil, nil, + nil, nil, 627, nil, nil, nil, nil, 627, 627, 627, + 627, nil, 627, 627, 627, 627, nil, nil, nil, nil, + 627, 627, nil, nil, nil, 628, 628, 628, 627, 628, + 627, 627, 627, 628, 628, 627, 627, nil, 628, nil, + 628, 628, 628, 628, 628, 628, 628, nil, nil, nil, + nil, nil, 628, 628, 628, 628, 628, 628, 628, nil, + nil, 628, nil, nil, nil, nil, nil, nil, 628, nil, + nil, 628, 628, 628, 628, 628, 628, 628, 628, 628, + 628, 628, 628, nil, 628, 628, 628, 628, 628, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 628, nil, + nil, 628, nil, nil, 628, 628, nil, nil, 628, nil, + 628, nil, 628, nil, 628, nil, nil, 628, nil, nil, + nil, nil, nil, 628, nil, nil, nil, nil, 628, 628, + 628, 628, nil, 628, 628, 628, 628, nil, nil, nil, + nil, 628, 628, nil, nil, nil, 638, 638, 638, 628, + 638, 628, 628, 628, 638, 638, 628, 628, nil, 638, + nil, 638, 638, 638, 638, 638, 638, 638, nil, nil, + nil, nil, nil, 638, 638, 638, 638, 638, 638, 638, + nil, nil, 638, nil, nil, nil, nil, nil, nil, 638, + nil, nil, 638, 638, 638, 638, 638, 638, 638, 638, + 638, 638, 638, 638, nil, 638, 638, 638, 638, 638, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 638, + nil, nil, 638, nil, nil, 638, 638, nil, nil, 638, + nil, 638, nil, 638, nil, 638, nil, nil, 638, nil, + nil, nil, nil, nil, 638, nil, nil, nil, nil, 638, + 638, 638, 638, nil, 638, 638, 638, 638, nil, nil, + nil, nil, 638, 638, nil, nil, nil, nil, nil, nil, + 638, nil, 638, 638, 638, nil, nil, 638, 638, 669, + 669, 669, 669, 669, nil, nil, nil, 669, 669, nil, + nil, nil, 669, nil, 669, 669, 669, 669, 669, 669, + 669, nil, nil, nil, nil, nil, 669, 669, 669, 669, + 669, 669, 669, nil, nil, 669, nil, nil, nil, nil, + nil, 669, 669, nil, 669, 669, 669, 669, 669, 669, + 669, 669, 669, nil, 669, 669, 669, nil, 669, 669, + 669, 669, 669, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 669, nil, nil, 669, nil, nil, 669, 669, + nil, nil, 669, nil, 669, nil, nil, nil, 669, nil, + nil, nil, nil, nil, nil, nil, nil, 669, nil, nil, + nil, nil, 669, 669, 669, 669, nil, 669, 669, 669, + 669, nil, nil, nil, nil, 669, 669, nil, nil, nil, + 671, 671, 671, 669, 671, 669, 669, 669, 671, 671, + 669, 669, nil, 671, nil, 671, 671, 671, 671, 671, + 671, 671, nil, nil, nil, nil, nil, 671, 671, 671, + 671, 671, 671, 671, nil, nil, 671, nil, nil, nil, + nil, nil, nil, 671, nil, nil, 671, 671, 671, 671, + 671, 671, 671, 671, nil, 671, 671, 671, nil, 671, + 671, 671, 671, 671, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 671, nil, nil, 671, nil, nil, 671, + 671, nil, nil, 671, nil, 671, nil, nil, nil, 671, + nil, nil, nil, nil, nil, nil, nil, nil, 671, nil, + nil, nil, nil, 671, 671, 671, 671, nil, 671, 671, + 671, 671, nil, nil, nil, nil, 671, 671, nil, nil, + nil, 672, 672, 672, 671, 672, 671, 671, 671, 672, + 672, 671, 671, nil, 672, nil, 672, 672, 672, 672, + 672, 672, 672, nil, nil, nil, nil, nil, 672, 672, + 672, 672, 672, 672, 672, nil, nil, 672, nil, nil, + nil, nil, nil, nil, 672, nil, nil, 672, 672, 672, + 672, 672, 672, 672, 672, nil, 672, 672, 672, nil, + 672, 672, 672, 672, 672, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 672, nil, nil, 672, nil, nil, + 672, 672, nil, nil, 672, nil, nil, nil, nil, nil, + 672, nil, nil, nil, nil, nil, nil, nil, nil, 672, + nil, nil, nil, nil, 672, 672, 672, 672, nil, 672, + 672, 672, 672, nil, nil, nil, nil, 672, 672, nil, + nil, nil, 673, 673, 673, 672, 673, 672, 672, 672, + 673, 673, 672, 672, nil, 673, nil, 673, 673, 673, + 673, 673, 673, 673, nil, nil, nil, nil, nil, 673, + 673, 673, 673, 673, 673, 673, nil, nil, 673, nil, + nil, nil, nil, nil, nil, 673, nil, nil, 673, 673, + 673, 673, 673, 673, 673, 673, 673, 673, 673, 673, + nil, 673, 673, 673, 673, 673, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 673, nil, nil, 673, nil, + nil, 673, 673, nil, nil, 673, nil, 673, nil, 673, + nil, 673, nil, nil, 673, nil, nil, nil, nil, nil, + 673, nil, nil, nil, nil, 673, 673, 673, 673, nil, + 673, 673, 673, 673, nil, nil, nil, nil, 673, 673, + nil, nil, nil, nil, nil, nil, 673, nil, 673, 673, + 673, nil, nil, 673, 673, 676, 676, 676, 676, 676, + nil, nil, nil, 676, 676, nil, nil, nil, 676, nil, + 676, 676, 676, 676, 676, 676, 676, nil, nil, nil, + nil, nil, 676, 676, 676, 676, 676, 676, 676, nil, + nil, 676, nil, nil, nil, nil, nil, 676, 676, nil, + 676, 676, 676, 676, 676, 676, 676, 676, 676, nil, + 676, 676, 676, nil, 676, 676, 676, 676, 676, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 676, nil, + nil, 676, nil, nil, 676, 676, nil, nil, 676, nil, + 676, nil, nil, nil, 676, nil, nil, nil, nil, nil, + nil, nil, nil, 676, nil, nil, nil, nil, 676, 676, + 676, 676, nil, 676, 676, 676, 676, nil, nil, nil, + nil, 676, 676, nil, nil, nil, 677, 677, 677, 676, + 677, 676, 676, 676, 677, 677, 676, 676, nil, 677, + nil, 677, 677, 677, 677, 677, 677, 677, nil, nil, + nil, nil, nil, 677, 677, 677, 677, 677, 677, 677, + nil, nil, 677, nil, nil, nil, nil, nil, nil, 677, + nil, nil, 677, 677, 677, 677, 677, 677, 677, 677, + nil, 677, 677, 677, nil, 677, 677, 677, 677, 677, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 677, + nil, nil, 677, nil, nil, 677, 677, nil, nil, 677, + nil, nil, nil, nil, nil, 677, nil, nil, nil, nil, + nil, nil, nil, nil, 677, nil, nil, nil, nil, 677, + 677, 677, 677, nil, 677, 677, 677, 677, nil, nil, + nil, nil, 677, 677, nil, nil, nil, 680, 680, 680, + 677, 680, 677, 677, 677, 680, 680, 677, 677, nil, + 680, nil, 680, 680, 680, 680, 680, 680, 680, nil, + nil, nil, nil, nil, 680, 680, 680, 680, 680, 680, + 680, nil, nil, 680, nil, nil, nil, nil, nil, nil, + 680, nil, nil, 680, 680, 680, 680, 680, 680, 680, + 680, 680, 680, 680, 680, nil, 680, 680, 680, 680, + 680, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 680, nil, nil, 680, nil, nil, 680, 680, nil, nil, + 680, nil, 680, nil, 680, nil, 680, nil, nil, 680, + nil, nil, nil, nil, nil, 680, nil, nil, nil, nil, + 680, 680, 680, 680, nil, 680, 680, 680, 680, nil, + nil, nil, nil, 680, 680, nil, nil, nil, 681, 681, + 681, 680, 681, 680, 680, 680, 681, 681, 680, 680, + nil, 681, nil, 681, 681, 681, 681, 681, 681, 681, + nil, nil, nil, nil, nil, 681, 681, 681, 681, 681, + 681, 681, nil, nil, 681, nil, nil, nil, nil, nil, + nil, 681, nil, nil, 681, 681, 681, 681, 681, 681, + 681, 681, 681, 681, 681, 681, nil, 681, 681, 681, + 681, 681, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 681, nil, nil, 681, nil, nil, 681, 681, nil, + nil, 681, nil, nil, nil, 681, nil, 681, nil, nil, + 681, nil, nil, nil, nil, nil, 681, nil, nil, nil, + nil, 681, 681, 681, 681, nil, 681, 681, 681, 681, + nil, nil, nil, nil, 681, 681, nil, nil, nil, 682, + 682, 682, 681, 682, 681, 681, 681, 682, 682, 681, + 681, nil, 682, nil, 682, 682, 682, 682, 682, 682, + 682, nil, nil, nil, nil, nil, 682, 682, 682, 682, + 682, 682, 682, nil, nil, 682, nil, nil, nil, nil, + nil, nil, 682, nil, nil, 682, 682, 682, 682, 682, + 682, 682, 682, nil, 682, 682, 682, nil, 682, 682, + 682, 682, 682, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 682, nil, nil, 682, nil, nil, 682, 682, + nil, nil, 682, nil, nil, nil, nil, nil, 682, nil, + nil, nil, nil, nil, nil, nil, nil, 682, nil, nil, + nil, nil, 682, 682, 682, 682, nil, 682, 682, 682, + 682, nil, nil, nil, nil, 682, 682, nil, nil, nil, + 683, 683, 683, 682, 683, 682, 682, 682, 683, 683, + 682, 682, nil, 683, nil, 683, 683, 683, 683, 683, + 683, 683, nil, nil, nil, nil, nil, 683, 683, 683, + 683, 683, 683, 683, nil, nil, 683, nil, nil, nil, + nil, nil, nil, 683, nil, nil, 683, 683, 683, 683, + 683, 683, 683, 683, nil, 683, 683, 683, nil, 683, + 683, 683, 683, 683, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 683, nil, nil, 683, nil, nil, 683, + 683, nil, nil, 683, nil, nil, nil, nil, nil, 683, + nil, nil, nil, nil, nil, nil, nil, nil, 683, nil, + nil, nil, nil, 683, 683, 683, 683, nil, 683, 683, + 683, 683, nil, nil, nil, nil, 683, 683, nil, nil, + nil, 687, 687, 687, 683, 687, 683, 683, 683, 687, + 687, 683, 683, nil, 687, nil, 687, 687, 687, 687, + 687, 687, 687, nil, nil, nil, nil, nil, 687, 687, + 687, 687, 687, 687, 687, nil, nil, 687, nil, nil, + nil, nil, nil, nil, 687, nil, nil, 687, 687, 687, + 687, 687, 687, 687, 687, nil, 687, 687, 687, nil, + 687, 687, 687, 687, 687, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 687, nil, nil, 687, nil, nil, + 687, 687, nil, nil, 687, nil, nil, nil, nil, nil, + 687, nil, nil, nil, nil, nil, nil, nil, nil, 687, + nil, nil, nil, nil, 687, 687, 687, 687, nil, 687, + 687, 687, 687, nil, nil, nil, nil, 687, 687, nil, + nil, nil, 688, 688, 688, 687, 688, 687, 687, 687, + 688, 688, 687, 687, nil, 688, nil, 688, 688, 688, + 688, 688, 688, 688, nil, nil, nil, nil, nil, 688, + 688, 688, 688, 688, 688, 688, nil, nil, 688, nil, + nil, nil, nil, nil, nil, 688, nil, nil, 688, 688, + 688, 688, 688, 688, 688, 688, nil, 688, 688, 688, + nil, 688, 688, 688, 688, 688, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 688, nil, nil, 688, nil, + nil, 688, 688, nil, nil, 688, nil, nil, nil, nil, + nil, 688, nil, nil, nil, nil, nil, nil, nil, nil, + 688, nil, nil, nil, nil, 688, 688, 688, 688, nil, + 688, 688, 688, 688, nil, nil, nil, nil, 688, 688, + nil, nil, nil, 694, 694, 694, 688, 694, 688, 688, + 688, 694, 694, 688, 688, nil, 694, nil, 694, 694, + 694, 694, 694, 694, 694, nil, nil, nil, nil, nil, + 694, 694, 694, 694, 694, 694, 694, nil, nil, 694, + nil, nil, nil, nil, nil, nil, 694, nil, nil, 694, + 694, 694, 694, 694, 694, 694, 694, nil, 694, 694, + 694, nil, 694, 694, 694, 694, 694, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 694, nil, nil, 694, + nil, nil, 694, 694, nil, nil, 694, nil, 694, nil, + nil, nil, 694, nil, nil, nil, nil, nil, nil, nil, + nil, 694, nil, nil, nil, nil, 694, 694, 694, 694, + nil, 694, 694, 694, 694, nil, nil, nil, nil, 694, + 694, nil, nil, nil, 708, 708, 708, 694, 708, 694, + 694, 694, 708, 708, 694, 694, nil, 708, nil, 708, + 708, 708, 708, 708, 708, 708, nil, nil, nil, nil, + nil, 708, 708, 708, 708, 708, 708, 708, nil, nil, + 708, nil, nil, nil, nil, nil, nil, 708, nil, nil, + 708, 708, 708, 708, 708, 708, 708, 708, nil, 708, + 708, 708, nil, 708, 708, 708, 708, 708, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 708, nil, nil, + 708, nil, nil, 708, 708, nil, nil, 708, nil, nil, + nil, nil, nil, 708, nil, nil, nil, nil, nil, nil, + nil, nil, 708, nil, nil, nil, nil, 708, 708, 708, + 708, nil, 708, 708, 708, 708, nil, nil, nil, nil, + 708, 708, nil, nil, nil, 732, 732, 732, 708, 732, + 708, 708, 708, 732, 732, 708, 708, nil, 732, nil, + 732, 732, 732, 732, 732, 732, 732, nil, nil, nil, + nil, nil, 732, 732, 732, 732, 732, 732, 732, nil, + nil, 732, nil, nil, nil, nil, nil, nil, 732, nil, + nil, 732, 732, 732, 732, 732, 732, 732, 732, nil, + 732, 732, 732, nil, 732, 732, 732, 732, 732, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 732, nil, + nil, 732, nil, nil, 732, 732, nil, nil, 732, nil, + nil, nil, nil, nil, 732, nil, nil, nil, nil, nil, + nil, nil, nil, 732, nil, nil, nil, nil, 732, 732, + 732, 732, nil, 732, 732, 732, 732, nil, nil, nil, + nil, 732, 732, nil, nil, nil, 733, 733, 733, 732, + 733, 732, 732, 732, 733, 733, 732, 732, nil, 733, + nil, 733, 733, 733, 733, 733, 733, 733, nil, nil, + nil, nil, nil, 733, 733, 733, 733, 733, 733, 733, + nil, nil, 733, nil, nil, nil, nil, nil, nil, 733, + nil, nil, 733, 733, 733, 733, 733, 733, 733, 733, + nil, 733, 733, 733, nil, 733, 733, 733, 733, 733, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 733, + nil, nil, 733, nil, nil, 733, 733, nil, nil, 733, + nil, nil, nil, nil, nil, 733, nil, nil, nil, nil, + nil, nil, nil, nil, 733, nil, nil, nil, nil, 733, + 733, 733, 733, nil, 733, 733, 733, 733, nil, nil, + nil, nil, 733, 733, nil, nil, nil, 788, 788, 788, + 733, 788, 733, 733, 733, 788, 788, 733, 733, nil, + 788, nil, 788, 788, 788, 788, 788, 788, 788, nil, + nil, nil, nil, nil, 788, 788, 788, 788, 788, 788, + 788, nil, nil, 788, nil, nil, nil, nil, nil, nil, + 788, nil, nil, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 788, 788, 788, nil, 788, 788, 788, 788, + 788, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 788, nil, nil, 788, nil, nil, 788, 788, nil, nil, + 788, nil, 788, nil, 788, nil, 788, nil, nil, 788, + nil, nil, nil, nil, nil, 788, nil, nil, nil, nil, + 788, 788, 788, 788, nil, 788, 788, 788, 788, nil, + nil, nil, nil, 788, 788, nil, nil, nil, 797, 797, + 797, 788, 797, 788, 788, 788, 797, 797, 788, 788, + nil, 797, nil, 797, 797, 797, 797, 797, 797, 797, + nil, nil, nil, nil, nil, 797, 797, 797, 797, 797, + 797, 797, nil, nil, 797, nil, nil, nil, nil, nil, + nil, 797, nil, nil, 797, 797, 797, 797, 797, 797, + 797, 797, nil, 797, 797, 797, nil, 797, 797, 797, + 797, 797, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 797, nil, nil, 797, nil, nil, 797, 797, nil, + nil, 797, nil, nil, nil, nil, nil, 797, nil, nil, + nil, nil, nil, nil, nil, nil, 797, nil, nil, nil, + nil, 797, 797, 797, 797, nil, 797, 797, 797, 797, + nil, nil, nil, nil, 797, 797, nil, nil, nil, 800, + 800, 800, 797, 800, 797, 797, 797, 800, 800, 797, + 797, nil, 800, nil, 800, 800, 800, 800, 800, 800, + 800, nil, nil, nil, nil, nil, 800, 800, 800, 800, + 800, 800, 800, nil, nil, 800, nil, nil, nil, nil, + nil, nil, 800, nil, nil, 800, 800, 800, 800, 800, + 800, 800, 800, nil, 800, 800, 800, nil, 800, 800, + 800, 800, 800, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 800, nil, nil, 800, nil, nil, 800, 800, + nil, nil, 800, nil, nil, nil, nil, nil, 800, nil, + nil, nil, nil, nil, nil, nil, nil, 800, nil, nil, + nil, nil, 800, 800, 800, 800, nil, 800, 800, 800, + 800, nil, nil, nil, nil, 800, 800, nil, nil, nil, + 818, 818, 818, 800, 818, 800, 800, 800, 818, 818, + 800, 800, nil, 818, nil, 818, 818, 818, 818, 818, + 818, 818, nil, nil, nil, nil, nil, 818, 818, 818, + 818, 818, 818, 818, nil, nil, 818, nil, nil, nil, + nil, nil, nil, 818, nil, nil, 818, 818, 818, 818, + 818, 818, 818, 818, nil, 818, 818, 818, nil, 818, + 818, 818, 818, 818, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 818, nil, nil, 818, nil, nil, 818, + 818, nil, nil, 818, nil, nil, nil, nil, nil, 818, + nil, nil, nil, nil, nil, nil, nil, nil, 818, nil, + nil, nil, nil, 818, 818, 818, 818, nil, 818, 818, + 818, 818, nil, nil, nil, nil, 818, 818, nil, nil, + nil, 847, 847, 847, 818, 847, 818, 818, 818, 847, + 847, 818, 818, nil, 847, nil, 847, 847, 847, 847, + 847, 847, 847, nil, nil, nil, nil, nil, 847, 847, + 847, 847, 847, 847, 847, nil, nil, 847, nil, nil, + nil, nil, nil, nil, 847, nil, nil, 847, 847, 847, + 847, 847, 847, 847, 847, nil, 847, 847, 847, nil, + 847, 847, 847, 847, 847, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 847, nil, nil, 847, nil, nil, + 847, 847, nil, nil, 847, nil, nil, nil, nil, nil, + 847, nil, nil, nil, nil, nil, nil, nil, nil, 847, + nil, nil, nil, nil, 847, 847, 847, 847, nil, 847, + 847, 847, 847, nil, nil, nil, nil, 847, 847, nil, + nil, nil, 867, 867, 867, 847, 867, 847, 847, 847, + 867, 867, 847, 847, nil, 867, nil, 867, 867, 867, + 867, 867, 867, 867, nil, nil, nil, nil, nil, 867, + 867, 867, 867, 867, 867, 867, nil, nil, 867, nil, + nil, nil, nil, nil, nil, 867, nil, nil, 867, 867, + 867, 867, 867, 867, 867, 867, nil, 867, 867, 867, + nil, 867, 867, 867, 867, 867, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 867, nil, nil, 867, nil, + nil, 867, 867, nil, nil, 867, nil, nil, nil, nil, + nil, 867, nil, nil, nil, nil, nil, nil, nil, nil, + 867, nil, nil, nil, nil, 867, 867, 867, 867, nil, + 867, 867, 867, 867, nil, nil, nil, nil, 867, 867, + nil, nil, nil, 875, 875, 875, 867, 875, 867, 867, + 867, 875, 875, 867, 867, nil, 875, nil, 875, 875, + 875, 875, 875, 875, 875, nil, nil, nil, nil, nil, + 875, 875, 875, 875, 875, 875, 875, nil, nil, 875, + nil, nil, nil, nil, nil, nil, 875, nil, nil, 875, + 875, 875, 875, 875, 875, 875, 875, nil, 875, 875, + 875, nil, 875, 875, 875, 875, 875, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 875, nil, nil, 875, + nil, nil, 875, 875, nil, nil, 875, nil, nil, nil, + nil, nil, 875, nil, nil, nil, nil, nil, nil, nil, + nil, 875, nil, nil, nil, nil, 875, 875, 875, 875, + nil, 875, 875, 875, 875, nil, nil, nil, nil, 875, + 875, nil, nil, nil, 888, 888, 888, 875, 888, 875, + 875, 875, 888, 888, 875, 875, nil, 888, nil, 888, + 888, 888, 888, 888, 888, 888, nil, nil, nil, nil, + nil, 888, 888, 888, 888, 888, 888, 888, nil, nil, + 888, nil, nil, nil, nil, nil, nil, 888, nil, nil, + 888, 888, 888, 888, 888, 888, 888, 888, nil, 888, + 888, 888, nil, 888, 888, 888, 888, 888, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 888, nil, nil, + 888, nil, nil, 888, 888, nil, nil, 888, nil, nil, + nil, nil, nil, 888, nil, nil, nil, nil, nil, nil, + nil, nil, 888, nil, nil, nil, nil, 888, 888, 888, + 888, nil, 888, 888, 888, 888, nil, nil, nil, nil, + 888, 888, nil, nil, nil, 889, 889, 889, 888, 889, + 888, 888, 888, 889, 889, 888, 888, nil, 889, nil, + 889, 889, 889, 889, 889, 889, 889, nil, nil, nil, + nil, nil, 889, 889, 889, 889, 889, 889, 889, nil, + nil, 889, nil, nil, nil, nil, nil, nil, 889, nil, + nil, 889, 889, 889, 889, 889, 889, 889, 889, nil, + 889, 889, 889, nil, 889, 889, 889, 889, 889, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 889, nil, + nil, 889, nil, nil, 889, 889, nil, nil, 889, nil, + nil, nil, nil, nil, 889, nil, nil, nil, nil, nil, + nil, nil, nil, 889, nil, nil, nil, nil, 889, 889, + 889, 889, nil, 889, 889, 889, 889, nil, nil, nil, + nil, 889, 889, nil, nil, nil, 917, 917, 917, 889, + 917, 889, 889, 889, 917, 917, 889, 889, nil, 917, + nil, 917, 917, 917, 917, 917, 917, 917, nil, nil, + nil, nil, nil, 917, 917, 917, 917, 917, 917, 917, + nil, nil, 917, nil, nil, nil, nil, nil, nil, 917, + nil, nil, 917, 917, 917, 917, 917, 917, 917, 917, + nil, 917, 917, 917, nil, 917, 917, 917, 917, 917, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 917, + nil, nil, 917, nil, nil, 917, 917, nil, nil, 917, + nil, nil, nil, nil, nil, 917, nil, nil, nil, nil, + nil, nil, nil, nil, 917, nil, nil, nil, nil, 917, + 917, 917, 917, nil, 917, 917, 917, 917, nil, nil, + nil, nil, 917, 917, nil, nil, nil, 918, 918, 918, + 917, 918, 917, 917, 917, 918, 918, 917, 917, nil, + 918, nil, 918, 918, 918, 918, 918, 918, 918, nil, + nil, nil, nil, nil, 918, 918, 918, 918, 918, 918, + 918, nil, nil, 918, nil, nil, nil, nil, nil, nil, + 918, nil, nil, 918, 918, 918, 918, 918, 918, 918, + 918, nil, 918, 918, 918, nil, 918, 918, 918, 918, + 918, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 918, nil, nil, 918, nil, nil, 918, 918, nil, nil, + 918, nil, nil, nil, nil, nil, 918, nil, nil, nil, + nil, nil, nil, nil, nil, 918, nil, nil, nil, nil, + 918, 918, 918, 918, nil, 918, 918, 918, 918, nil, + nil, nil, nil, 918, 918, nil, nil, nil, 919, 919, + 919, 918, 919, 918, 918, 918, 919, 919, 918, 918, + nil, 919, nil, 919, 919, 919, 919, 919, 919, 919, + nil, nil, nil, nil, nil, 919, 919, 919, 919, 919, + 919, 919, nil, nil, 919, nil, nil, nil, nil, nil, + nil, 919, nil, nil, 919, 919, 919, 919, 919, 919, + 919, 919, nil, 919, 919, 919, nil, 919, 919, 919, + 919, 919, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 919, nil, nil, 919, nil, nil, 919, 919, nil, + nil, 919, nil, nil, nil, nil, nil, 919, nil, nil, + nil, nil, nil, nil, nil, nil, 919, nil, nil, nil, + nil, 919, 919, 919, 919, nil, 919, 919, 919, 919, + nil, nil, nil, nil, 919, 919, nil, nil, nil, 920, + 920, 920, 919, 920, 919, 919, 919, 920, 920, 919, + 919, nil, 920, nil, 920, 920, 920, 920, 920, 920, + 920, nil, nil, nil, nil, nil, 920, 920, 920, 920, + 920, 920, 920, nil, nil, 920, nil, nil, nil, nil, + nil, nil, 920, nil, nil, 920, 920, 920, 920, 920, + 920, 920, 920, nil, 920, 920, 920, nil, 920, 920, + 920, 920, 920, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 920, nil, nil, 920, nil, nil, 920, 920, + nil, nil, 920, nil, nil, nil, nil, nil, 920, nil, + nil, nil, nil, nil, nil, nil, nil, 920, nil, nil, + nil, nil, 920, 920, 920, 920, nil, 920, 920, 920, + 920, nil, nil, nil, nil, 920, 920, nil, nil, nil, + 921, 921, 921, 920, 921, 920, 920, 920, 921, 921, + 920, 920, nil, 921, nil, 921, 921, 921, 921, 921, + 921, 921, nil, nil, nil, nil, nil, 921, 921, 921, + 921, 921, 921, 921, nil, nil, 921, nil, nil, nil, + nil, nil, nil, 921, nil, nil, 921, 921, 921, 921, + 921, 921, 921, 921, nil, 921, 921, 921, nil, 921, + 921, 921, 921, 921, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 921, nil, nil, 921, nil, nil, 921, + 921, nil, nil, 921, nil, nil, nil, nil, nil, 921, + nil, nil, nil, nil, nil, nil, nil, nil, 921, nil, + nil, nil, nil, 921, 921, 921, 921, nil, 921, 921, + 921, 921, nil, nil, nil, nil, 921, 921, nil, nil, + nil, 922, 922, 922, 921, 922, 921, 921, 921, 922, + 922, 921, 921, nil, 922, nil, 922, 922, 922, 922, + 922, 922, 922, nil, nil, nil, nil, nil, 922, 922, + 922, 922, 922, 922, 922, nil, nil, 922, nil, nil, + nil, nil, nil, nil, 922, nil, nil, 922, 922, 922, + 922, 922, 922, 922, 922, nil, 922, 922, 922, nil, + 922, 922, 922, 922, 922, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 922, nil, nil, 922, nil, nil, + 922, 922, nil, nil, 922, nil, nil, nil, nil, nil, + 922, nil, nil, nil, nil, nil, nil, nil, nil, 922, + nil, nil, nil, nil, 922, 922, 922, 922, nil, 922, + 922, 922, 922, nil, nil, nil, nil, 922, 922, nil, + nil, nil, 956, 956, 956, 922, 956, 922, 922, 922, + 956, 956, 922, 922, nil, 956, nil, 956, 956, 956, + 956, 956, 956, 956, nil, nil, nil, nil, nil, 956, + 956, 956, 956, 956, 956, 956, nil, nil, 956, nil, + nil, nil, nil, nil, nil, 956, nil, nil, 956, 956, + 956, 956, 956, 956, 956, 956, nil, 956, 956, 956, + nil, 956, 956, 956, 956, 956, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 956, nil, nil, 956, nil, + nil, 956, 956, nil, nil, 956, nil, nil, nil, nil, + nil, 956, nil, nil, nil, nil, nil, nil, nil, nil, + 956, nil, nil, nil, nil, 956, 956, 956, 956, nil, + 956, 956, 956, 956, nil, nil, nil, nil, 956, 956, + nil, nil, nil, 962, 962, 962, 956, 962, 956, 956, + 956, 962, 962, 956, 956, nil, 962, nil, 962, 962, + 962, 962, 962, 962, 962, nil, nil, nil, nil, nil, + 962, 962, 962, 962, 962, 962, 962, nil, nil, 962, + nil, nil, nil, nil, nil, nil, 962, nil, nil, 962, + 962, 962, 962, 962, 962, 962, 962, nil, 962, 962, + 962, nil, 962, 962, 962, 962, 962, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 962, nil, nil, 962, + nil, nil, 962, 962, nil, nil, 962, nil, nil, nil, + nil, nil, 962, nil, nil, nil, nil, nil, nil, nil, + nil, 962, nil, nil, nil, nil, 962, 962, 962, 962, + nil, 962, 962, 962, 962, nil, nil, nil, nil, 962, + 962, nil, nil, nil, 985, 985, 985, 962, 985, 962, + 962, 962, 985, 985, 962, 962, nil, 985, nil, 985, + 985, 985, 985, 985, 985, 985, nil, nil, nil, nil, + nil, 985, 985, 985, 985, 985, 985, 985, nil, nil, + 985, nil, nil, nil, nil, nil, nil, 985, nil, nil, + 985, 985, 985, 985, 985, 985, 985, 985, nil, 985, + 985, 985, nil, 985, 985, 985, 985, 985, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 985, nil, nil, + 985, nil, nil, 985, 985, nil, nil, 985, nil, nil, + nil, nil, nil, 985, nil, nil, nil, nil, nil, nil, + nil, nil, 985, nil, nil, nil, nil, 985, 985, 985, + 985, nil, 985, 985, 985, 985, nil, nil, nil, nil, + 985, 985, nil, nil, nil, 990, 990, 990, 985, 990, + 985, 985, 985, 990, 990, 985, 985, nil, 990, nil, + 990, 990, 990, 990, 990, 990, 990, nil, nil, nil, + nil, nil, 990, 990, 990, 990, 990, 990, 990, nil, + nil, 990, nil, nil, nil, nil, nil, nil, 990, nil, + nil, 990, 990, 990, 990, 990, 990, 990, 990, nil, + 990, 990, 990, nil, 990, 990, 990, 990, 990, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 990, nil, + nil, 990, nil, nil, 990, 990, nil, nil, 990, nil, + 990, nil, nil, nil, 990, nil, nil, nil, nil, nil, + nil, nil, nil, 990, nil, nil, nil, nil, 990, 990, + 990, 990, nil, 990, 990, 990, 990, nil, nil, nil, + nil, 990, 990, nil, nil, nil, 1009, 1009, 1009, 990, + 1009, 990, 990, 990, 1009, 1009, 990, 990, nil, 1009, + nil, 1009, 1009, 1009, 1009, 1009, 1009, 1009, nil, nil, + nil, nil, nil, 1009, 1009, 1009, 1009, 1009, 1009, 1009, + nil, nil, 1009, nil, nil, nil, nil, nil, nil, 1009, + nil, nil, 1009, 1009, 1009, 1009, 1009, 1009, 1009, 1009, + 1009, 1009, 1009, 1009, nil, 1009, 1009, 1009, 1009, 1009, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 1009, + nil, nil, 1009, nil, nil, 1009, 1009, nil, nil, 1009, + nil, nil, nil, 1009, nil, 1009, nil, nil, 1009, nil, + nil, nil, nil, nil, 1009, nil, nil, nil, nil, 1009, + 1009, 1009, 1009, nil, 1009, 1009, 1009, 1009, nil, nil, + nil, nil, 1009, 1009, nil, nil, nil, 1035, 1035, 1035, + 1009, 1035, 1009, 1009, 1009, 1035, 1035, 1009, 1009, nil, + 1035, nil, 1035, 1035, 1035, 1035, 1035, 1035, 1035, nil, + nil, nil, nil, nil, 1035, 1035, 1035, 1035, 1035, 1035, + 1035, nil, nil, 1035, nil, nil, nil, nil, nil, nil, + 1035, nil, nil, 1035, 1035, 1035, 1035, 1035, 1035, 1035, + 1035, nil, 1035, 1035, 1035, nil, 1035, 1035, 1035, 1035, + 1035, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1035, nil, nil, 1035, nil, nil, 1035, 1035, nil, nil, + 1035, nil, nil, nil, nil, nil, 1035, nil, nil, nil, + nil, nil, nil, nil, nil, 1035, nil, nil, nil, nil, + 1035, 1035, 1035, 1035, nil, 1035, 1035, 1035, 1035, nil, + nil, nil, nil, 1035, 1035, nil, nil, nil, 1149, 1149, + 1149, 1035, 1149, 1035, 1035, 1035, 1149, 1149, 1035, 1035, + nil, 1149, nil, 1149, 1149, 1149, 1149, 1149, 1149, 1149, + nil, nil, nil, nil, nil, 1149, 1149, 1149, 1149, 1149, + 1149, 1149, nil, nil, 1149, nil, nil, nil, nil, nil, + nil, 1149, nil, nil, 1149, 1149, 1149, 1149, 1149, 1149, + 1149, 1149, nil, 1149, 1149, 1149, nil, 1149, 1149, 1149, + 1149, 1149, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 1149, nil, nil, 1149, nil, nil, 1149, 1149, nil, + nil, 1149, nil, nil, nil, nil, nil, 1149, nil, nil, + nil, nil, nil, nil, nil, nil, 1149, nil, nil, nil, + nil, 1149, 1149, 1149, 1149, nil, 1149, 1149, 1149, 1149, + nil, nil, nil, nil, 1149, 1149, nil, nil, nil, 1150, + 1150, 1150, 1149, 1150, 1149, 1149, 1149, 1150, 1150, 1149, + 1149, nil, 1150, nil, 1150, 1150, 1150, 1150, 1150, 1150, + 1150, nil, nil, nil, nil, nil, 1150, 1150, 1150, 1150, + 1150, 1150, 1150, nil, nil, 1150, nil, nil, nil, nil, + nil, nil, 1150, nil, nil, 1150, 1150, 1150, 1150, 1150, + 1150, 1150, 1150, nil, 1150, 1150, 1150, nil, 1150, 1150, + 1150, 1150, 1150, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1150, nil, nil, 1150, nil, nil, 1150, 1150, + nil, nil, 1150, nil, nil, nil, nil, nil, 1150, nil, + nil, nil, nil, nil, nil, nil, nil, 1150, nil, nil, + nil, nil, 1150, 1150, 1150, 1150, nil, 1150, 1150, 1150, + 1150, nil, nil, nil, nil, 1150, 1150, nil, nil, nil, + 1162, 1162, 1162, 1150, 1162, 1150, 1150, 1150, 1162, 1162, + 1150, 1150, nil, 1162, nil, 1162, 1162, 1162, 1162, 1162, + 1162, 1162, nil, nil, nil, nil, nil, 1162, 1162, 1162, + 1162, 1162, 1162, 1162, nil, nil, 1162, nil, nil, nil, + nil, nil, nil, 1162, nil, nil, 1162, 1162, 1162, 1162, + 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, nil, 1162, + 1162, 1162, 1162, 1162, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 1162, nil, nil, 1162, nil, nil, 1162, + 1162, nil, nil, 1162, nil, 1162, nil, 1162, nil, 1162, + nil, nil, 1162, nil, nil, nil, nil, nil, 1162, nil, + nil, nil, nil, 1162, 1162, 1162, 1162, nil, 1162, 1162, + 1162, 1162, nil, nil, nil, nil, 1162, 1162, nil, nil, + nil, 39, 39, 39, 1162, 39, 1162, 1162, 1162, 39, + 39, 1162, 1162, nil, 39, nil, 39, 39, 39, 39, + 39, 39, 39, nil, nil, nil, nil, nil, 39, 39, + 39, 39, 39, 39, 39, nil, nil, 39, nil, nil, + nil, nil, nil, nil, 39, nil, nil, 39, 39, 39, + 39, 39, 39, 39, 39, nil, 39, 39, 39, nil, + 39, 39, nil, nil, 39, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 39, nil, nil, 39, nil, nil, + 39, 39, nil, nil, 39, nil, 39, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 39, 39, 39, 39, nil, 39, + 39, 39, 39, nil, nil, nil, nil, 39, 39, nil, + nil, nil, 40, 40, 40, 39, 40, 39, 39, 39, + 40, 40, nil, nil, nil, 40, nil, 40, 40, 40, + 40, 40, 40, 40, nil, nil, nil, nil, nil, 40, + 40, 40, 40, 40, 40, 40, nil, nil, 40, nil, + nil, nil, nil, nil, nil, 40, nil, nil, 40, 40, + 40, 40, 40, 40, 40, 40, nil, 40, 40, 40, + nil, 40, 40, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 40, nil, nil, 40, nil, + nil, 40, 40, nil, nil, 40, nil, nil, 1210, nil, + 1210, 1210, 1210, 1210, 1210, nil, nil, nil, nil, nil, + nil, nil, nil, 1210, nil, 40, 40, 40, 40, nil, + 40, 40, 40, 40, nil, nil, nil, nil, 40, 40, + nil, nil, nil, 40, nil, 1210, 40, nil, 40, 40, + 40, 76, 76, 76, nil, 76, 1210, 1210, nil, 76, + 76, 1210, nil, nil, 76, nil, 76, 76, 76, 76, + 76, 76, 76, nil, nil, nil, nil, nil, 76, 76, + 76, 76, 76, 76, 76, nil, nil, 76, nil, nil, + nil, nil, nil, nil, 76, nil, nil, 76, 76, 76, + 76, 76, 76, 76, 76, nil, 76, 76, 76, nil, + 76, 76, nil, nil, 76, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 76, nil, nil, 76, nil, nil, + 76, 76, nil, nil, 76, nil, 76, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 76, 76, 76, 76, nil, 76, + 76, 76, 76, nil, nil, nil, nil, 76, 76, nil, + nil, nil, 77, 77, 77, 76, 77, 76, 76, 76, + 77, 77, nil, nil, nil, 77, nil, 77, 77, 77, + 77, 77, 77, 77, nil, nil, nil, nil, nil, 77, + 77, 77, 77, 77, 77, 77, nil, nil, 77, nil, + nil, nil, nil, nil, nil, 77, nil, nil, 77, 77, + 77, 77, 77, 77, 77, 77, nil, 77, 77, 77, + nil, 77, 77, nil, nil, 77, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 77, nil, nil, 77, nil, nil, 77, nil, + nil, 77, 77, nil, nil, 77, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 77, 77, 77, 77, nil, + 77, 77, 77, 77, nil, nil, nil, nil, 77, 77, + nil, nil, nil, 78, 78, 78, 77, 78, 77, 77, + 77, 78, 78, nil, nil, nil, 78, nil, 78, 78, + 78, 78, 78, 78, 78, nil, nil, nil, nil, nil, + 78, 78, 78, 78, 78, 78, 78, nil, nil, 78, + nil, nil, nil, nil, nil, nil, 78, nil, nil, 78, + 78, 78, 78, 78, 78, 78, 78, nil, 78, 78, + 78, nil, 78, 78, nil, nil, 78, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 78, nil, nil, 78, + nil, nil, 78, 78, nil, nil, 78, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 78, 78, 78, 78, + nil, 78, 78, 78, 78, nil, nil, nil, nil, 78, + 78, nil, nil, nil, 341, 341, 341, 78, 341, 78, + 78, 78, 341, 341, nil, nil, nil, 341, nil, 341, + 341, 341, 341, 341, 341, 341, nil, nil, nil, nil, + nil, 341, 341, 341, 341, 341, 341, 341, nil, nil, + 341, nil, nil, nil, nil, nil, nil, 341, nil, nil, + 341, 341, 341, 341, 341, 341, 341, 341, nil, 341, + 341, 341, nil, 341, 341, nil, nil, 341, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 341, nil, nil, + 341, nil, nil, 341, 341, nil, nil, 341, nil, nil, + 1212, nil, 1212, 1212, 1212, 1212, 1212, nil, nil, nil, + nil, nil, nil, nil, nil, 1212, nil, 341, 341, 341, + 341, nil, 341, 341, 341, 341, nil, nil, nil, nil, + 341, 341, nil, nil, nil, 341, nil, 1212, 341, nil, + 341, 341, 341, 360, 360, 360, nil, 360, 1212, 1212, + nil, 360, 360, 1212, nil, nil, 360, nil, 360, 360, + 360, 360, 360, 360, 360, nil, nil, nil, nil, nil, + 360, 360, 360, 360, 360, 360, 360, nil, nil, 360, + nil, nil, nil, nil, nil, nil, 360, nil, nil, 360, + 360, 360, 360, 360, 360, 360, 360, nil, 360, 360, + 360, nil, 360, 360, nil, nil, 360, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 360, nil, nil, 360, + nil, nil, 360, 360, nil, nil, 360, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 360, 360, 360, 360, + nil, 360, 360, 360, 360, nil, nil, nil, nil, 360, + 360, nil, nil, nil, 588, 588, 588, 360, 588, 360, + 360, 360, 588, 588, nil, nil, nil, 588, nil, 588, + 588, 588, 588, 588, 588, 588, nil, nil, nil, nil, + nil, 588, 588, 588, 588, 588, 588, 588, nil, nil, + 588, nil, nil, nil, nil, nil, nil, 588, nil, nil, + 588, 588, 588, 588, 588, 588, 588, 588, nil, 588, + 588, 588, nil, 588, 588, nil, nil, 588, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 588, nil, nil, + 588, nil, nil, 588, 588, nil, nil, 588, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 588, 588, 588, + 588, nil, 588, 588, 588, 588, nil, nil, nil, nil, + 588, 588, nil, nil, nil, 597, 597, 597, 588, 597, + 588, 588, 588, 597, 597, nil, nil, nil, 597, nil, + 597, 597, 597, 597, 597, 597, 597, nil, nil, nil, + nil, nil, 597, 597, 597, 597, 597, 597, 597, nil, + nil, 597, nil, nil, nil, nil, nil, nil, 597, nil, + nil, 597, 597, 597, 597, 597, 597, 597, 597, nil, + 597, 597, 597, nil, 597, 597, nil, nil, 597, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 597, nil, + nil, 597, nil, nil, 597, 597, nil, nil, 597, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 597, 597, + 597, 597, nil, 597, 597, 597, 597, nil, nil, nil, + nil, 597, 597, nil, nil, nil, 803, 803, 803, 597, + 803, 597, 597, 597, 803, 803, nil, nil, nil, 803, + nil, 803, 803, 803, 803, 803, 803, 803, nil, nil, + nil, nil, nil, 803, 803, 803, 803, 803, 803, 803, + nil, nil, 803, nil, nil, nil, nil, nil, nil, 803, + nil, nil, 803, 803, 803, 803, 803, 803, 803, 803, + nil, 803, 803, 803, nil, 803, 803, nil, nil, 803, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 803, + nil, nil, 803, nil, nil, 803, 803, nil, nil, 803, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 803, + 803, 803, 803, nil, 803, 803, 803, 803, nil, nil, + nil, nil, 803, 803, nil, nil, nil, 814, 814, 814, + 803, 814, 803, 803, 803, 814, 814, nil, nil, nil, + 814, nil, 814, 814, 814, 814, 814, 814, 814, nil, + nil, nil, nil, nil, 814, 814, 814, 814, 814, 814, + 814, nil, nil, 814, nil, nil, nil, nil, nil, nil, + 814, nil, nil, 814, 814, 814, 814, 814, 814, 814, + 814, nil, 814, 814, 814, nil, 814, 814, nil, nil, + 814, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 814, nil, nil, 814, nil, nil, 814, 814, nil, nil, + 814, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 814, 814, 814, 814, nil, 814, 814, 814, 814, nil, + nil, nil, nil, 814, 814, nil, nil, nil, 1017, 1017, + 1017, 814, 1017, 814, 814, 814, 1017, 1017, nil, nil, + nil, 1017, nil, 1017, 1017, 1017, 1017, 1017, 1017, 1017, + nil, nil, nil, nil, nil, 1017, 1017, 1017, 1017, 1017, + 1017, 1017, nil, nil, 1017, nil, nil, nil, nil, nil, + nil, 1017, nil, nil, 1017, 1017, 1017, 1017, 1017, 1017, + 1017, 1017, nil, 1017, 1017, 1017, nil, 1017, 1017, nil, + nil, 1017, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 1017, nil, nil, 1017, nil, nil, 1017, 1017, nil, + nil, 1017, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 1017, 1017, 1017, 1017, nil, 1017, 1017, 1017, 1017, + nil, nil, nil, nil, 1017, 1017, nil, nil, nil, 1081, + 1081, 1081, 1017, 1081, 1017, 1017, 1017, 1081, 1081, nil, + nil, nil, 1081, nil, 1081, 1081, 1081, 1081, 1081, 1081, + 1081, nil, nil, nil, nil, nil, 1081, 1081, 1081, 1081, + 1081, 1081, 1081, nil, nil, 1081, nil, nil, nil, nil, + nil, nil, 1081, nil, nil, 1081, 1081, 1081, 1081, 1081, + 1081, 1081, 1081, nil, 1081, 1081, 1081, nil, 1081, 1081, + nil, nil, 1081, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1081, nil, nil, 1081, nil, nil, 1081, 1081, + nil, nil, 1081, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1081, 1081, 1081, 1081, nil, 1081, 1081, 1081, + 1081, nil, nil, nil, nil, 1081, 1081, nil, nil, nil, + 1144, 1144, 1144, 1081, 1144, 1081, 1081, 1081, 1144, 1144, + nil, nil, nil, 1144, nil, 1144, 1144, 1144, 1144, 1144, + 1144, 1144, nil, nil, nil, nil, nil, 1144, 1144, 1144, + 1144, 1144, 1144, 1144, nil, nil, 1144, nil, nil, nil, + nil, nil, nil, 1144, nil, nil, 1144, 1144, 1144, 1144, + 1144, 1144, 1144, 1144, nil, 1144, 1144, 1144, nil, 1144, + 1144, nil, nil, 1144, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 1144, nil, nil, 1144, nil, nil, 1144, + 1144, nil, nil, 1144, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 1144, 1144, 1144, 1144, nil, 1144, 1144, + 1144, 1144, nil, nil, nil, nil, 1144, 1144, nil, nil, + nil, nil, nil, nil, 1144, nil, 1144, 1144, 1144, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, nil, nil, nil, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, nil, nil, nil, nil, + nil, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, nil, 10, nil, nil, nil, nil, nil, nil, nil, + 10, 10, nil, 10, 10, 10, 10, 10, 10, 10, + nil, nil, 10, 10, nil, nil, nil, 10, 10, 10, + 10, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 10, 10, nil, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, nil, + nil, 10, 10, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 10, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, nil, nil, nil, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, nil, nil, nil, nil, nil, 11, + 11, 11, 11, 11, 11, 11, 11, 11, nil, nil, + 11, nil, nil, nil, nil, nil, nil, nil, 11, 11, + nil, 11, 11, 11, 11, 11, 11, 11, nil, nil, + 11, 11, nil, nil, nil, 11, 11, 11, 11, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 11, 11, nil, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, nil, nil, 11, + 11, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 11, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, nil, + nil, nil, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, nil, nil, nil, nil, nil, 427, 427, 427, + 427, 427, 427, 427, 427, 427, nil, nil, 427, nil, + nil, nil, nil, nil, nil, nil, 427, 427, nil, 427, + 427, 427, 427, 427, 427, 427, nil, nil, 427, 427, + nil, nil, nil, 427, 427, 427, 427, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 427, 427, nil, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, nil, nil, 427, 427, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 427, 667, 667, 667, 667, 667, 667, 667, + 667, 667, 667, 667, 667, 667, 667, 667, 667, 667, + 667, 667, 667, 667, 667, 667, 667, nil, nil, nil, + 667, 667, 667, 667, 667, 667, 667, 667, 667, 667, + nil, nil, nil, nil, nil, 667, 667, 667, 667, 667, + 667, 667, 667, 667, nil, nil, 667, nil, nil, nil, + nil, nil, nil, nil, 667, 667, nil, 667, 667, 667, + 667, 667, 667, 667, nil, nil, 667, 667, nil, nil, + nil, 667, 667, 667, 667, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 667, 667, + nil, 667, 667, 667, 667, 667, 667, 667, 667, 667, + 667, 667, 667, nil, nil, 667, 667, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 667, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, nil, nil, nil, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, nil, nil, + nil, nil, nil, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, nil, 26, nil, nil, nil, + nil, nil, 26, 26, nil, 26, 26, 26, 26, 26, + 26, 26, nil, nil, 26, 26, nil, nil, nil, 26, + 26, 26, 26, nil, nil, nil, nil, nil, 26, nil, + nil, nil, nil, nil, nil, nil, 26, 26, nil, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, nil, nil, 26, 527, 527, 527, 527, nil, nil, + 1214, nil, 1214, 1214, 1214, 1214, 1214, nil, nil, nil, + 527, 527, 527, 527, nil, 1214, nil, 527, 527, nil, + nil, nil, nil, 527, 527, nil, nil, 527, 527, nil, + nil, nil, nil, nil, nil, nil, nil, 1214, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 527, 1214, 1214, + 527, nil, nil, 1214, 527, nil, nil, 527, nil, 527, + nil, nil, nil, nil, nil, nil, 527, nil, nil, nil, + nil, nil, nil, 527, nil, nil, nil, 527, 527, 527, + 527, nil, 527, 527, 527, 527, nil, nil, nil, nil, + 527, 527, 528, 528, 528, 528, nil, nil, 527, nil, + 527, 527, 527, nil, nil, 527, 527, nil, 528, 528, + 528, 528, nil, nil, nil, 528, 528, nil, nil, nil, + nil, 528, 528, nil, nil, 528, 528, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 528, nil, nil, 528, nil, + nil, nil, 528, nil, nil, 528, nil, 528, nil, nil, + nil, nil, nil, nil, 528, nil, nil, nil, nil, nil, + nil, 528, nil, nil, nil, 528, 528, 528, 528, nil, + 528, 528, 528, 528, nil, nil, nil, nil, 528, 528, + 745, 745, 745, 745, nil, nil, 528, nil, 528, 528, + 528, nil, nil, 528, 528, nil, 745, 745, 745, 745, + nil, nil, nil, 745, nil, nil, nil, nil, nil, 745, + 745, nil, nil, 745, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 745, nil, nil, 745, nil, nil, nil, + 745, nil, nil, 745, nil, 745, nil, nil, nil, nil, + nil, nil, 705, nil, 705, 705, 705, 705, 705, 745, + nil, nil, nil, 745, 745, 745, 745, 705, 745, 745, + 745, 745, nil, nil, nil, nil, 745, 745, 745, 753, + 753, 753, 753, nil, 745, nil, 745, 745, 745, 705, + nil, 745, 745, nil, nil, 753, 753, 753, 753, nil, + 705, 705, 753, nil, nil, 705, nil, nil, 753, 753, + nil, nil, 753, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 753, nil, nil, 753, nil, nil, nil, 753, + nil, nil, 753, nil, nil, 705, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 753, nil, + nil, nil, 753, 753, 753, 753, nil, 753, 753, 753, + 753, nil, nil, nil, nil, 753, 753, nil, nil, nil, + nil, nil, nil, 753, nil, 753, 753, 753, nil, nil, + 753, 753, 780, 780, 780, 780, 780, 780, 780, 780, + 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, + 780, 780, 780, 780, 780, 780, nil, nil, nil, 780, + 780, 780, 780, 780, 780, 780, 780, 780, 780, nil, + nil, nil, nil, nil, 780, 780, 780, 780, 780, 780, + 780, 780, 780, nil, nil, 780, nil, nil, nil, nil, + nil, nil, nil, 780, 780, nil, 780, 780, 780, 780, + 780, 780, 780, nil, nil, 780, 780, nil, nil, nil, + 780, 780, 780, 780, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 780, 780, nil, + 780, 780, 780, 780, 780, 780, 780, 780, 780, 780, + 780, 780, nil, nil, 780, 924, 924, 924, 924, nil, + nil, nil, nil, nil, 1022, nil, 1022, 1022, 1022, 1022, + 1022, 924, 924, 924, 924, nil, nil, nil, 924, 1022, + nil, nil, nil, nil, 924, 924, nil, nil, 924, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 1022, nil, nil, nil, nil, nil, nil, 924, nil, + nil, 924, 1022, 1022, nil, 924, nil, 1022, 924, nil, + 924, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 924, nil, nil, nil, 924, 924, + 924, 924, nil, 924, 924, 924, 924, nil, nil, nil, + nil, 924, 924, 926, 926, 926, 926, 1022, nil, 924, + nil, 924, 924, 924, nil, nil, 924, 924, nil, 926, + 926, 926, 926, nil, nil, 1138, 926, 1138, 1138, 1138, + 1138, 1138, 926, 926, nil, nil, 926, nil, nil, nil, + 1138, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 926, nil, nil, 926, + nil, nil, 1138, 926, nil, nil, 926, nil, nil, nil, + nil, 1138, 1138, 1138, 1138, nil, nil, nil, 1138, nil, + nil, nil, 926, nil, nil, nil, 926, 926, 926, 926, + nil, 926, 926, 926, 926, nil, nil, nil, nil, 926, + 926, 929, 929, 929, 929, nil, nil, 926, nil, 926, + 926, 926, nil, nil, 926, 926, nil, 929, 929, 929, + 929, nil, nil, nil, 929, 929, nil, nil, nil, nil, + 929, 929, nil, nil, 929, 929, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 929, nil, nil, 929, nil, nil, + nil, 929, nil, nil, 929, nil, 929, nil, nil, nil, + nil, nil, nil, 929, nil, nil, nil, nil, nil, nil, + 929, nil, nil, nil, 929, 929, 929, 929, nil, 929, + 929, 929, 929, nil, nil, nil, nil, 929, 929, 930, + 930, 930, 930, nil, nil, 929, nil, 929, 929, 929, + nil, nil, 929, 929, nil, 930, 930, 930, 930, nil, + nil, nil, 930, 930, nil, nil, nil, nil, 930, 930, + nil, nil, 930, 930, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 930, nil, nil, 930, nil, nil, nil, 930, + nil, nil, 930, nil, 930, nil, nil, nil, nil, nil, + nil, 930, nil, nil, nil, nil, nil, nil, 930, nil, + nil, nil, 930, 930, 930, 930, nil, 930, 930, 930, + 930, nil, nil, nil, nil, 930, 930, 936, 936, 936, + 936, nil, nil, 930, nil, 930, 930, 930, nil, nil, + 930, 930, nil, 936, 936, 936, 936, nil, nil, 1208, + 936, 1208, 1208, 1208, 1208, 1208, 936, 936, nil, nil, + 936, nil, nil, nil, 1208, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 936, nil, nil, 936, nil, nil, 1208, 936, nil, nil, + 936, nil, 936, nil, nil, 1208, 1208, 1208, 1208, nil, + nil, nil, 1208, nil, nil, nil, 936, nil, nil, nil, + 936, 936, 936, 936, nil, 936, 936, 936, 936, nil, + nil, nil, nil, 936, 936, 942, 942, 942, 942, nil, + nil, 936, nil, 936, 936, 936, nil, nil, 936, 936, + nil, 942, 942, 942, 942, nil, nil, 1231, 942, 1231, + 1231, 1231, 1231, 1231, 942, 942, nil, nil, 942, nil, + nil, nil, 1231, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 942, nil, + nil, 942, nil, nil, 1231, 942, nil, nil, 942, nil, + nil, nil, nil, nil, nil, 1231, 1231, nil, nil, nil, + 1231, nil, nil, nil, 942, nil, nil, nil, 942, 942, + 942, 942, nil, 942, 942, 942, 942, nil, nil, nil, + nil, 942, 942, 943, 943, 943, 943, nil, nil, 942, + nil, 942, 942, 942, nil, nil, 942, 942, nil, 943, + 943, 943, 943, nil, nil, nil, 943, nil, nil, nil, + nil, nil, 943, 943, nil, nil, 943, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 943, nil, nil, 943, + nil, nil, nil, 943, nil, nil, 943, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 943, nil, nil, nil, 943, 943, 943, 943, + nil, 943, 943, 943, 943, nil, nil, nil, nil, 943, + 943, 989, 989, 989, 989, nil, nil, 943, nil, 943, + 943, 943, nil, nil, 943, 943, nil, 989, 989, 989, + 989, nil, nil, nil, 989, 989, nil, nil, nil, nil, + 989, 989, nil, nil, 989, 989, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 989, nil, nil, 989, nil, nil, + nil, 989, nil, nil, 989, nil, 989, nil, nil, nil, + nil, nil, nil, 989, nil, nil, nil, nil, nil, nil, + 989, nil, nil, nil, 989, 989, 989, 989, nil, 989, + 989, 989, 989, nil, nil, nil, nil, 989, 989, 1116, + 1116, 1116, 1116, nil, nil, 989, nil, 989, 989, 989, + nil, nil, 989, 989, nil, 1116, 1116, 1116, 1116, nil, + nil, nil, 1116, nil, nil, nil, nil, nil, 1116, 1116, + nil, nil, 1116, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1116, nil, nil, 1116, nil, nil, nil, 1116, + nil, nil, 1116, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 1116, nil, + nil, nil, 1116, 1116, 1116, 1116, nil, 1116, 1116, 1116, + 1116, nil, nil, nil, nil, 1116, 1116, 1125, 1125, 1125, + 1125, nil, nil, 1116, nil, 1116, 1116, 1116, nil, nil, + 1116, 1116, nil, 1125, 1125, 1125, 1125, nil, nil, nil, + 1125, nil, nil, nil, nil, nil, 1125, 1125, nil, nil, + 1125, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1125, nil, nil, 1125, nil, nil, nil, 1125, nil, nil, + 1125, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1125, nil, nil, nil, + 1125, 1125, 1125, 1125, nil, 1125, 1125, 1125, 1125, nil, + nil, nil, nil, 1125, 1125, 1129, 1129, 1129, 1129, nil, + nil, 1125, nil, 1125, 1125, 1125, nil, nil, 1125, 1125, + nil, 1129, 1129, 1129, 1129, nil, nil, nil, 1129, nil, + nil, nil, nil, nil, 1129, 1129, nil, nil, 1129, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 1129, nil, + nil, 1129, nil, nil, nil, 1129, nil, nil, 1129, nil, + 1129, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1129, nil, nil, nil, 1129, 1129, + 1129, 1129, nil, 1129, 1129, 1129, 1129, nil, nil, nil, + nil, 1129, 1129, 1173, 1173, 1173, 1173, nil, nil, 1129, + nil, 1129, 1129, 1129, nil, nil, 1129, 1129, nil, 1173, + 1173, 1173, 1173, nil, nil, nil, 1173, nil, nil, nil, + nil, nil, 1173, 1173, nil, nil, 1173, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1173, nil, nil, 1173, + nil, nil, nil, 1173, nil, nil, 1173, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1173, nil, nil, nil, 1173, 1173, 1173, 1173, + nil, 1173, 1173, 1173, 1173, nil, nil, nil, nil, 1173, + 1173, 1205, 1205, 1205, 1205, nil, nil, 1173, nil, 1173, + 1173, 1173, nil, nil, 1173, 1173, nil, 1205, 1205, 1205, + 1205, nil, nil, nil, 1205, nil, nil, nil, nil, nil, + 1205, 1205, nil, nil, 1205, nil, nil, nil, nil, nil, + nil, nil, 763, 763, 763, 763, nil, nil, nil, nil, + nil, nil, nil, nil, 1205, nil, nil, 1205, 763, 763, + 763, 1205, nil, nil, 1205, nil, nil, nil, nil, nil, + nil, 763, 763, nil, nil, 763, nil, nil, nil, nil, + 1205, nil, nil, nil, 1205, 1205, 1205, 1205, nil, 1205, + 1205, 1205, 1205, nil, nil, nil, nil, 1205, 1205, nil, + nil, nil, nil, nil, nil, 1205, nil, 1205, 1205, 1205, + nil, nil, 1205, 1205, 972, nil, 972, 972, 972, 972, + 972, nil, nil, nil, nil, 763, 763, 763, 763, 972, + 763, 763, 763, 763, nil, nil, nil, nil, 763, 763, + 950, 950, 950, 950, nil, nil, 763, nil, 763, 763, + 763, 972, nil, nil, nil, nil, 950, 950, 950, nil, + 972, 972, 972, 972, nil, nil, nil, 972, nil, 950, + 950, nil, nil, 950, 951, 951, 951, 951, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 951, 951, 951, 972, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 951, 951, nil, nil, 951, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 950, 950, 950, 950, nil, 950, 950, + 950, 950, nil, nil, nil, nil, 950, 950, nil, nil, + nil, nil, nil, nil, 950, nil, 950, 950, 950, nil, + nil, nil, nil, nil, nil, nil, nil, 951, 951, 951, + 951, nil, 951, 951, 951, 951, nil, nil, nil, nil, + 951, 951, nil, nil, nil, nil, nil, nil, 951, nil, + 951, 951, 951, 701, nil, 701, 701, 701, 701, 701, + nil, 703, nil, 703, 703, 703, 703, 703, 701, nil, + nil, nil, nil, nil, nil, nil, 703, nil, 1020, nil, + 1020, 1020, 1020, 1020, 1020, nil, nil, nil, nil, nil, + 701, nil, nil, 1020, nil, nil, nil, nil, 703, 701, + 701, 701, 701, nil, nil, nil, 701, 703, 703, 703, + 703, nil, nil, nil, 703, 1020, nil, nil, nil, nil, + nil, nil, nil, nil, 1020, 1020, 1020, 1020, nil, nil, + 1024, 1020, 1024, 1024, 1024, 1024, 1024, 1026, nil, 1026, + 1026, 1026, 1026, 1026, nil, 1024, 701, nil, nil, nil, + nil, nil, 1026, nil, 703, 1166, nil, 1166, 1166, 1166, + 1166, 1166, nil, nil, nil, nil, nil, 1024, nil, nil, + 1166, 1020, nil, nil, 1026, nil, nil, nil, 1024, 1024, + nil, nil, nil, 1024, nil, 1026, 1026, nil, nil, nil, + 1026, nil, 1166, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 1166, 1166, nil, nil, nil, 1166, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 225, 225, nil, 1024, 225, nil, nil, nil, nil, nil, + 1026, nil, 225, 225, nil, 225, 225, 225, 225, 225, + 225, 225, nil, nil, 225, 225, nil, nil, 1166, 225, + 225, 225, 225, nil, nil, nil, nil, nil, 225, nil, + nil, nil, nil, nil, nil, nil, 225, 225, nil, 225, + 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, + 225, 226, 226, 225, nil, 226, nil, nil, nil, nil, + nil, nil, nil, 226, 226, nil, 226, 226, 226, 226, + 226, 226, 226, nil, nil, 226, 226, nil, nil, nil, + 226, 226, 226, 226, nil, nil, nil, nil, nil, 226, + nil, nil, nil, nil, nil, nil, nil, 226, 226, nil, + 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, + 226, 226, 302, 302, 226, nil, 302, nil, nil, nil, + nil, nil, nil, nil, 302, 302, nil, 302, 302, 302, + 302, 302, 302, 302, nil, nil, 302, 302, nil, nil, + nil, 302, 302, 302, 302, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 302, 302, + nil, 302, 302, 302, 302, 302, 302, 302, 302, 302, + 302, 302, 302, 518, 518, 302, nil, 518, nil, nil, + nil, nil, nil, nil, nil, 518, 518, nil, 518, 518, + 518, 518, 518, 518, 518, nil, nil, 518, 518, nil, + nil, nil, 518, 518, 518, 518, nil, nil, nil, nil, + nil, 518, nil, nil, nil, nil, nil, nil, nil, 518, + 518, nil, 518, 518, 518, 518, 518, 518, 518, 518, + 518, 518, 518, 518, 519, 519, 518, nil, 519, nil, + nil, nil, nil, nil, nil, nil, 519, 519, nil, 519, + 519, 519, 519, 519, 519, 519, nil, nil, 519, 519, + nil, nil, nil, 519, 519, 519, 519, nil, nil, nil, + nil, nil, 519, nil, nil, nil, nil, nil, nil, nil, + 519, 519, nil, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519, 519, 591, 591, 519, nil, 591, + nil, nil, nil, nil, nil, nil, nil, 591, 591, nil, + 591, 591, 591, 591, 591, 591, 591, nil, nil, 591, + 591, nil, nil, nil, 591, 591, 591, 591, nil, nil, + nil, nil, nil, 591, nil, nil, nil, nil, nil, nil, + nil, 591, 591, nil, 591, 591, 591, 591, 591, 591, + 591, 591, 591, 591, 591, 591, 592, 592, 591, nil, + 592, nil, nil, nil, nil, nil, nil, nil, 592, 592, + nil, 592, 592, 592, 592, 592, 592, 592, nil, nil, + 592, 592, nil, nil, nil, 592, 592, 592, 592, nil, + nil, nil, nil, nil, 592, nil, nil, nil, nil, nil, + nil, nil, 592, 592, nil, 592, 592, 592, 592, 592, + 592, 592, 592, 592, 592, 592, 592, 601, 601, 592, + nil, 601, nil, nil, nil, nil, nil, nil, nil, 601, + 601, nil, 601, 601, 601, 601, 601, 601, 601, nil, + nil, 601, 601, nil, nil, nil, 601, 601, 601, 601, + nil, nil, nil, nil, nil, 601, nil, nil, nil, nil, + nil, nil, nil, 601, 601, nil, 601, 601, 601, 601, + 601, 601, 601, 601, 601, 601, 601, 601, 602, 602, + 601, nil, 602, nil, nil, nil, nil, nil, nil, nil, + 602, 602, nil, 602, 602, 602, 602, 602, 602, 602, + nil, nil, 602, 602, nil, nil, nil, 602, 602, 602, + 602, nil, nil, nil, nil, nil, 602, nil, nil, nil, + nil, nil, nil, nil, 602, 602, nil, 602, 602, 602, + 602, 602, 602, 602, 602, 602, 602, 602, 602, 629, + 629, 602, nil, 629, nil, nil, nil, nil, nil, nil, + nil, 629, 629, nil, 629, 629, 629, 629, 629, 629, + 629, nil, nil, 629, 629, nil, nil, nil, 629, 629, + 629, 629, nil, nil, nil, nil, nil, 629, nil, nil, + nil, nil, nil, nil, nil, 629, 629, nil, 629, 629, + 629, 629, 629, 629, 629, 629, 629, 629, 629, 629, + 630, 630, 629, nil, 630, nil, nil, nil, nil, nil, + nil, nil, 630, 630, nil, 630, 630, 630, 630, 630, + 630, 630, nil, nil, 630, 630, nil, nil, nil, 630, + 630, 630, 630, nil, nil, nil, nil, nil, 630, nil, + nil, nil, nil, nil, nil, nil, 630, 630, nil, 630, + 630, 630, 630, 630, 630, 630, 630, 630, 630, 630, + 630, 636, 636, 630, nil, 636, nil, nil, nil, nil, + nil, nil, nil, 636, 636, nil, 636, 636, 636, 636, + 636, 636, 636, nil, nil, 636, 636, nil, nil, nil, + 636, 636, 636, 636, nil, nil, nil, nil, nil, 636, + nil, nil, nil, nil, nil, nil, nil, 636, 636, nil, + 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, + 636, 636, 637, 637, 636, nil, 637, nil, nil, nil, + nil, nil, nil, nil, 637, 637, nil, 637, 637, 637, + 637, 637, 637, 637, nil, nil, 637, 637, nil, nil, + nil, 637, 637, 637, 637, nil, nil, nil, nil, nil, + 637, nil, nil, nil, nil, nil, nil, nil, 637, 637, + nil, 637, 637, 637, 637, 637, 637, 637, 637, 637, + 637, 637, 637, 674, 674, 637, nil, 674, nil, nil, + nil, nil, nil, nil, nil, 674, 674, nil, 674, 674, + 674, 674, 674, 674, 674, nil, nil, 674, 674, nil, + nil, nil, 674, 674, 674, 674, nil, nil, nil, nil, + nil, 674, nil, nil, nil, nil, nil, nil, nil, 674, + 674, nil, 674, 674, 674, 674, 674, 674, 674, 674, + 674, 674, 674, 674, 675, 675, 674, nil, 675, nil, + nil, nil, nil, nil, nil, nil, 675, 675, nil, 675, + 675, 675, 675, 675, 675, 675, nil, nil, 675, 675, + nil, nil, nil, 675, 675, 675, 675, nil, nil, nil, + nil, nil, 675, nil, nil, nil, nil, nil, nil, nil, + 675, 675, nil, 675, 675, 675, 675, 675, 675, 675, + 675, 675, 675, 675, 675, 1163, 1163, 675, nil, 1163, + nil, nil, nil, nil, nil, nil, nil, 1163, 1163, nil, + 1163, 1163, 1163, 1163, 1163, 1163, 1163, nil, nil, 1163, + 1163, nil, nil, nil, 1163, 1163, 1163, 1163, nil, nil, + nil, nil, nil, 1163, nil, nil, nil, nil, nil, nil, + nil, 1163, 1163, nil, 1163, 1163, 1163, 1163, 1163, 1163, + 1163, 1163, 1163, 1163, 1163, 1163, 1164, 1164, 1163, nil, + 1164, nil, nil, nil, nil, nil, nil, nil, 1164, 1164, + nil, 1164, 1164, 1164, 1164, 1164, 1164, 1164, nil, nil, + 1164, 1164, nil, nil, nil, 1164, 1164, 1164, 1164, nil, + nil, nil, nil, nil, 1164, nil, nil, nil, nil, nil, + nil, nil, 1164, 1164, nil, 1164, 1164, 1164, 1164, 1164, + 1164, 1164, 1164, 1164, 1164, 1164, 1164, 1188, 1188, 1164, + nil, 1188, nil, nil, nil, nil, nil, nil, nil, 1188, + 1188, nil, 1188, 1188, 1188, 1188, 1188, 1188, 1188, nil, + nil, 1188, 1188, nil, nil, nil, 1188, 1188, 1188, 1188, + nil, nil, nil, nil, nil, 1188, nil, nil, nil, nil, + nil, nil, nil, 1188, 1188, nil, 1188, 1188, 1188, 1188, + 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, nil, nil, + 1188 ] + +racc_action_pointer = [ + nil, 58, 979, 85, nil, -110, nil, 5154, 964, 140, + 24967, 25095, 209, nil, 211, 220, 525, 328, -62, -84, + 162, 374, nil, -71, 5285, 1123, 25479, 396, nil, 171, + nil, -8, 5426, 5536, 5670, 5801, 5932, nil, 1123, 23109, + 23240, nil, 315, 525, 531, 423, 6063, 6194, 205, 6325, + 6456, 525, 6587, 378, 342, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 6728, nil, 6869, 7000, 7131, 35, + nil, 7262, 7393, nil, nil, 7524, 23379, 23510, 23641, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 612, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 0, nil, + nil, 112, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 7667, nil, nil, nil, nil, 7810, + 7941, 8072, 8203, 8346, nil, 1267, nil, 588, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 384, nil, 1411, 8477, + 8608, 8739, 8870, 9001, 9132, 27689, 27750, nil, nil, 379, + 1555, 390, nil, 719, 831, 427, 1699, 9263, 9394, 9525, + nil, nil, 514, 141, 193, 522, 246, 469, 536, nil, + 9656, 307, 388, 1843, 542, nil, nil, 9787, 9918, 10049, + 10180, 10311, 10442, 10573, 10704, 10835, 10966, 11097, 11228, 11359, + 11490, 11621, 11752, 11883, 12014, 12145, 12276, 12407, 12538, nil, + nil, nil, nil, 12669, nil, nil, 226, 302, 515, 517, + 518, 532, 550, 558, 584, 585, nil, nil, nil, 12800, + nil, nil, 27811, nil, nil, 541, 12931, 13062, nil, nil, + nil, nil, nil, nil, nil, 13193, nil, 1843, nil, 512, + 532, nil, 13324, 585, 13455, nil, nil, 13586, 13717, nil, + nil, 74, nil, 13860, 1252, 599, 579, 1987, 626, 687, + 648, 23772, 2131, 694, 806, 873, 748, 878, nil, 721, + 681, 225, 724, 732, nil, nil, nil, 743, 221, 704, + 23911, nil, 564, 879, 3283, 3427, 773, nil, 774, 13991, + nil, 755, 2275, 1396, 715, nil, 252, 399, 752, 738, + 574, 767, nil, 593, -1, 11, 14122, 2419, 2563, 216, + 840, 725, -18, 10, 893, 806, 11, 838, nil, nil, + 441, 481, 513, nil, 962, nil, 758, 14253, nil, 15821, + nil, 193, 378, 396, 402, 412, -27, -4, 463, nil, + nil, nil, nil, nil, nil, nil, 753, 25223, nil, nil, + nil, nil, 755, nil, 826, 739, 14384, 745, nil, nil, + 734, nil, 968, 253, 837, nil, nil, 1267, nil, nil, + nil, nil, nil, 1411, 751, nil, 760, 761, 615, 669, + 14525, nil, nil, nil, 222, 334, 807, nil, nil, 14657, + 14793, 14930, 891, 905, nil, nil, 785, 789, 790, nil, + nil, 792, 800, 805, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 804, 3125, nil, nil, 15061, nil, nil, + nil, -1, nil, nil, nil, 900, nil, nil, 901, 264, + 15192, 944, nil, nil, nil, -35, nil, 868, 27872, 27933, + 15323, 277, 15454, 15585, 15716, 814, 815, 25562, 25660, 3571, + 3715, 1018, 3150, 902, 907, 908, 912, 5285, 5375, 5488, + 3859, 4003, 4147, 4291, 4435, 4579, 3311, 3455, 4723, 4867, + 1987, 5011, nil, -33, nil, 15857, nil, nil, nil, nil, + 15987, 861, 860, 886, nil, nil, nil, 888, nil, nil, + 16118, nil, 16249, nil, 16380, nil, 329, nil, nil, nil, + 16523, 1540, nil, 889, 889, nil, nil, 915, 24042, 920, + 16666, 27994, 28055, 972, 962, nil, nil, 24173, 920, nil, + 16797, 28116, 28177, 16928, 5154, 17059, nil, 1048, 928, 970, + nil, 17190, nil, nil, 17321, nil, nil, nil, 2707, 1050, + nil, 2851, 62, 1057, 1059, 39, 1060, 17452, 17583, 28238, + 28299, 27, nil, nil, 995, nil, 28360, 28421, 17714, nil, + nil, 81, 2995, nil, 15851, nil, nil, nil, nil, 1033, + nil, nil, nil, 954, nil, nil, 153, nil, 263, nil, + nil, 941, nil, 943, nil, nil, nil, 25351, nil, 17857, + 945, 17988, 18119, 18250, 28482, 28543, 18393, 18524, 693, 987, + 18655, 18786, 18917, 19048, 987, nil, nil, 19179, 19310, 989, + nil, 1050, 1555, 1084, 19441, nil, nil, 888, nil, nil, + 544, 27522, nil, 27530, nil, 25811, nil, 958, 19572, nil, + 3154, nil, 972, 973, 729, 979, nil, nil, nil, nil, + nil, nil, 1068, 1699, nil, nil, nil, 286, 306, 473, + 612, 983, 19703, 19834, nil, 139, nil, nil, nil, nil, + 1021, nil, nil, nil, 582, 25758, 94, nil, 998, 1081, + 1002, nil, nil, 25857, nil, nil, 303, nil, nil, 654, + nil, nil, 6728, 27300, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 838, 612, nil, nil, 1004, + 26000, nil, 1130, nil, 1121, 91, nil, nil, 19965, nil, + 1036, 1041, 1142, nil, 1026, nil, 1078, 20096, nil, nil, + 20227, nil, 245, 24304, 1046, nil, 1053, 236, 250, 1114, + 360, 1123, 1115, 1076, 24435, nil, 1147, 2131, 20358, nil, + nil, nil, 583, 738, nil, 1203, nil, nil, nil, nil, + nil, 1210, 1213, nil, nil, 26, 1097, 40, 41, 151, + 152, 3139, 970, 1267, nil, 1105, 3283, 20489, nil, 1227, + 63, 1107, nil, nil, nil, nil, nil, 3427, nil, nil, + nil, nil, nil, nil, nil, nil, 1114, 20620, 1118, 343, + 347, 722, 834, nil, 2275, 20751, nil, 1117, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 20882, 21013, + 1245, nil, 3571, 1122, 1169, nil, nil, 1124, nil, 1209, + nil, nil, 1131, 1141, nil, 1142, 1143, nil, 1146, nil, + nil, nil, 1150, 3184, 3651, nil, nil, 21144, 21275, 21406, + 21537, 21668, 21799, 445, 26083, 1230, 26181, -41, -73, 26279, + 26377, 622, 169, 1153, 1173, nil, 26475, nil, 1171, 359, + nil, 1193, 26573, 26671, nil, 637, 1221, 333, nil, nil, + 27398, 27432, nil, nil, nil, nil, 21930, nil, nil, nil, + nil, nil, 22061, nil, nil, 1200, nil, nil, 1210, 1197, + nil, nil, 27353, 3715, nil, nil, nil, nil, 1214, 338, + nil, -7, nil, 1339, nil, 22192, 1344, nil, nil, 26769, + 22323, 3859, 68, 1345, nil, 1348, 361, 4003, nil, nil, + nil, nil, 1226, 1273, 1239, 1238, 468, nil, nil, 22454, + 2419, 2563, nil, 4147, nil, nil, 32, 24566, nil, nil, + 27547, nil, 26073, nil, 27599, nil, 27606, nil, nil, nil, + nil, 1246, 1247, 2707, 2851, 22585, nil, 1248, nil, nil, + nil, nil, 1261, 1262, 1264, 1267, 1269, 1271, nil, nil, + nil, 1317, 1275, -32, nil, 1288, nil, nil, -77, 1286, + nil, nil, nil, nil, nil, nil, 1330, 2995, 4291, nil, + nil, 1290, 1291, nil, 1292, 1294, 1314, nil, 1339, 1320, + 1307, 24697, nil, nil, nil, nil, nil, 33, nil, 34, + 727, nil, 255, nil, nil, nil, 1444, 4435, 4579, 1109, + nil, nil, nil, 4723, 35, 36, 1165, 1412, 42, nil, + 1338, 1358, 1359, 1364, 3795, 3845, 26867, nil, nil, nil, + nil, nil, nil, nil, 1365, 26965, nil, 370, nil, 27063, + nil, nil, 1444, nil, nil, 15876, nil, nil, 26184, nil, + 14588, nil, nil, 1392, 24828, 1309, 1450, 4867, nil, 22716, + 22847, nil, nil, nil, nil, 1394, 1506, 604, nil, nil, + nil, 1516, 22978, 28604, 28665, 98, 27624, nil, nil, nil, + nil, 1391, 1392, 27161, 1397, nil, nil, 1402, nil, nil, + 1403, 1404, 1405, 1408, nil, 1412, nil, 1411, 28726, nil, + 755, 5011, nil, nil, nil, nil, nil, 1829, nil, 1416, + 102, 138, 145, 181, 1419, 27259, 1429, nil, 26478, nil, + 23287, nil, 23819, nil, 25549, nil, nil, 1474, 1475, nil, + 38, nil, 146, nil, 1434, 1435, 1436, 1438, nil, nil, + nil, 26576, nil, nil, nil, nil, 1458, nil ] + +racc_action_default = [ + -1, -745, -4, -745, -2, -730, -5, -745, -8, -745, + -745, -745, -745, -31, -745, -745, -36, -745, -745, -639, + -639, -311, -52, -732, -745, -61, -745, -69, -70, -71, + -75, -287, -287, -287, -324, -352, -353, -87, -13, -91, + -99, -101, -745, -626, -627, -745, -745, -745, -745, -745, + -745, -239, -745, -732, -258, -302, -303, -304, -305, -306, + -307, -308, -309, -310, -718, -313, -317, -744, -707, -333, + -335, -745, -745, -63, -63, -730, -745, -745, -745, -354, + -355, -357, -358, -359, -360, -419, -563, -564, -565, -566, + -587, -569, -570, -589, -591, -574, -579, -583, -585, -601, + -602, -603, -587, -605, -607, -608, -609, -610, -716, -615, + -616, -717, -618, -619, -620, -621, -622, -623, -624, -625, + -630, -631, 1238, -3, -731, -740, -741, -742, -7, -745, + -745, -745, -745, -745, -9, -4, -19, -745, -130, -131, + -132, -133, -134, -135, -136, -140, -141, -142, -143, -144, + -145, -146, -147, -148, -149, -150, -151, -152, -153, -154, + -155, -156, -157, -158, -159, -160, -161, -162, -163, -164, + -165, -166, -167, -168, -169, -170, -171, -172, -173, -174, + -175, -176, -177, -178, -179, -180, -181, -182, -183, -184, + -185, -186, -187, -188, -189, -190, -191, -192, -193, -194, + -195, -196, -197, -198, -199, -200, -201, -202, -203, -204, + -205, -206, -207, -208, -209, -210, -24, -137, -13, -745, + -745, -745, -745, -745, -277, -745, -745, -728, -729, -745, + -13, -638, -636, -662, -662, -745, -13, -745, -745, -732, + -733, -56, -745, -626, -627, -745, -311, -745, -745, -245, + -745, -639, -639, -13, -745, -57, -59, -222, -223, -745, + -745, -745, -745, -745, -745, -745, -745, -745, -745, -745, + -745, -745, -745, -745, -745, -745, -745, -745, -745, -259, + -260, -261, -262, -745, -65, -66, -745, -130, -131, -170, + -171, -172, -188, -193, -200, -203, -626, -627, -705, -745, + -428, -430, -745, -726, -727, -76, -277, -745, -332, -434, + -443, -445, -82, -440, -83, -732, -84, -265, -282, -292, + -292, -286, -290, -293, -745, -587, -709, -713, -745, -85, + -86, -730, -14, -745, -17, -745, -89, -13, -732, -745, + -92, -95, -13, -107, -108, -745, -745, -115, -324, -327, + -732, -745, -639, -639, -352, -353, -356, -441, -745, -97, + -745, -103, -321, -745, -224, -225, -606, -233, -234, -745, + -246, -251, -13, -315, -732, -266, -737, -737, -745, -745, + -737, -745, -334, -62, -745, -745, -745, -13, -13, -730, + -745, -731, -626, -627, -745, -745, -311, -745, -370, -371, + -125, -126, -745, -128, -745, -311, -634, -745, -348, -662, + -567, -745, -745, -745, -745, -745, -745, -745, -745, -6, + -743, -25, -26, -27, -28, -29, -745, -745, -21, -22, + -23, -138, -745, -32, -35, -298, -745, -745, -297, -33, + -745, -37, -745, -311, -49, -51, -211, -270, -293, -53, + -54, -38, -212, -270, -732, -278, -292, -292, -719, -720, + -287, -438, -721, -722, -720, -719, -287, -437, -439, -721, + -722, -745, -555, -745, -383, -384, -732, -704, -704, -644, + -645, -647, -647, -647, -661, -663, -664, -665, -666, -667, + -668, -669, -670, -671, -745, -673, -675, -677, -682, -684, + -685, -688, -693, -695, -696, -698, -699, -700, -702, -745, + -745, -745, -48, -219, -55, -732, -331, -745, -745, -745, + -277, -321, -745, -745, -745, -745, -745, -745, -745, -220, + -221, -226, -227, -228, -229, -230, -231, -235, -236, -237, + -238, -240, -241, -242, -243, -244, -247, -248, -249, -250, + -732, -263, -67, -732, -449, -287, -719, -720, -73, -77, + -663, -732, -292, -732, -288, -447, -449, -732, -326, -283, + -745, -284, -745, -289, -745, -294, -745, -712, -715, -12, + -731, -16, -18, -732, -88, -319, -104, -93, -745, -732, + -277, -745, -745, -114, -745, -638, -606, -745, -100, -105, + -745, -745, -745, -745, -264, -745, -328, -745, -732, -745, + -267, -739, -738, -269, -739, -322, -323, -708, -13, -361, + -362, -13, -745, -745, -745, -745, -745, -745, -277, -745, + -745, -321, -63, -125, -126, -127, -745, -745, -277, -344, + -632, -745, -13, -420, -662, -423, -568, -588, -593, -745, + -595, -571, -590, -745, -592, -573, -745, -576, -745, -578, + -581, -745, -582, -745, -604, -10, -20, -745, -30, -745, + -301, -745, -745, -277, -745, -745, -745, -745, -442, -745, + -279, -281, -745, -745, -78, -276, -435, -745, -745, -80, + -436, -44, -254, -744, -744, -350, -637, -745, -642, -643, + -745, -745, -654, -745, -657, -745, -659, -745, -745, -372, + -745, -374, -376, -379, -382, -732, -676, -686, -687, -697, + -701, -640, -46, -256, -351, -330, -734, -719, -720, -719, + -720, -732, -745, -745, -58, -463, -466, -467, -468, -469, + -471, -473, -476, -477, -534, -732, -489, -492, -504, -508, + -513, -515, -516, -519, -520, -587, -523, -525, -526, -527, + -532, -533, -745, -745, -537, -538, -539, -540, -541, -542, + -543, -544, -545, -546, -547, -745, -745, -553, -60, -745, + -745, -706, -745, -450, -72, -431, -447, -272, -279, -274, + -745, -409, -745, -325, -292, -291, -295, -745, -710, -711, + -745, -15, -90, -745, -96, -102, -732, -719, -720, -275, + -723, -113, -745, -98, -745, -218, -232, -252, -745, -314, + -316, -318, -737, -744, -363, -744, -64, -364, -365, -338, + -339, -745, -745, -455, -341, -745, -732, -719, -720, -723, + -320, -13, -125, -126, -129, -732, -13, -745, -346, -745, + -745, -732, -594, -597, -598, -599, -600, -13, -572, -575, + -577, -580, -584, -586, -139, -34, -299, -745, -732, -719, + -720, -720, -719, -50, -271, -745, -735, -292, -40, -214, + -41, -215, -79, -42, -217, -43, -216, -81, -745, -745, + -744, -368, -13, -556, -744, -557, -558, -704, -683, -688, + -703, -646, -647, -647, -674, -647, -647, -694, -647, -671, + -386, -689, -732, -745, -745, -381, -672, -745, -745, -745, + -745, -745, -745, -442, -464, -745, -745, -474, -475, -745, + -745, -745, -494, -732, -732, -488, -495, -501, -745, -745, + -491, -745, -745, -745, -507, -514, -518, -745, -522, -524, + -530, -531, -535, -536, -548, -549, -745, -611, -612, -613, + -126, -551, -745, -68, -429, -409, -433, -432, -745, -732, + -444, -410, -732, -13, -446, -285, -296, -714, -94, -442, + -106, -732, -268, -745, -366, -745, -745, -340, -342, -745, + -745, -13, -442, -745, -442, -745, -745, -13, -349, -421, + -424, -426, -413, -745, -745, -300, -442, -39, -213, -280, + -45, -255, -11, -13, -562, -369, -745, -745, -560, -641, + -745, -650, -745, -652, -745, -655, -745, -658, -660, -373, + -375, -377, -380, -47, -257, -745, -465, -504, -470, -472, + -481, -485, -732, -732, -732, -732, -732, -732, -552, -486, + -487, -511, -496, -499, -502, -732, -587, -736, -732, -505, + -509, -512, -517, -521, -528, -529, -745, -253, -13, -74, + -273, -704, -704, -390, -392, -392, -392, -408, -745, -732, + -671, -679, -680, -691, -448, -329, -336, -745, -337, -745, + -460, -295, -744, -343, -345, -633, -745, -13, -13, -745, + -422, -596, -561, -13, -626, -627, -745, -745, -311, -559, + -647, -647, -647, -647, -745, -745, -745, -478, -479, -480, + -482, -483, -484, -503, -497, -745, -490, -745, -493, -745, + -550, -451, -745, -388, -389, -393, -399, -401, -745, -404, + -745, -406, -411, -745, -745, -678, -745, -13, -456, -745, + -745, -452, -453, -454, -347, -745, -745, -732, -415, -417, + -418, -555, -277, -745, -745, -321, -745, -648, -651, -653, + -656, -378, -505, -745, -500, -506, -510, -704, -681, -391, + -392, -392, -392, -392, -692, -392, -412, -690, -745, -321, + -744, -13, -461, -462, -425, -427, -414, -745, -554, -732, + -719, -720, -723, -320, -647, -745, -498, -387, -745, -396, + -745, -398, -745, -402, -745, -405, -407, -320, -723, -367, + -744, -416, -442, -649, -392, -392, -392, -392, -457, -458, + -459, -745, -394, -397, -400, -403, -392, -395 ] + +racc_goto_table = [ + 44, 493, 493, 411, 285, 44, 141, 141, 318, 318, + 318, 382, 309, 313, 301, 418, 340, 890, 225, 384, + 385, 284, 141, 389, 297, 15, 693, 473, 626, 303, + 15, 635, 454, 511, 618, 621, 44, 344, 344, 136, + 217, 127, 232, 232, 698, 699, 144, 144, 451, 8, + 708, 832, 563, 339, 8, 702, 704, 706, 387, 388, + 598, 15, 512, 897, 44, 983, 438, 439, 320, 320, + 320, 356, 356, 123, 393, 297, 297, 421, 422, 423, + 424, 236, 17, 460, 466, 336, 366, 17, 940, 15, + 375, 559, 571, 904, 383, 383, 734, 778, 383, 398, + 445, 377, 380, 445, 302, 124, 241, 134, 356, 356, + 356, 127, 907, 373, 561, 737, 737, 445, 17, 359, + 452, 790, 44, 1030, 305, 312, 314, 709, 715, 1032, + 973, 44, 1075, 44, 513, 610, 613, 756, 756, 617, + 4, 1059, 1158, 390, 338, 1037, 17, 15, 1184, 986, + 476, 509, 383, 383, 383, 383, 15, 798, 15, 1160, + 555, 128, 652, 654, 657, 657, 406, 408, 1, 607, + 2, 8, 795, 1003, 795, 1012, 782, 493, 484, 484, + 425, 801, 8, 216, 934, 399, 952, 953, 792, 434, + 903, 427, 905, 319, 319, 319, 527, 238, 318, 798, + 656, 658, 229, 235, 17, 528, 461, 1044, 1047, 826, + 316, 329, 330, 17, 286, 17, 44, 1055, 1184, 595, + 595, 780, 470, 786, 667, 369, 376, 371, 44, 571, + 605, 378, 785, 432, 44, 298, 379, 397, 576, 678, + 1221, 15, 518, 440, 449, 450, 440, 639, 372, 608, + 374, 44, 818, 15, 846, 997, 642, 1160, 1031, 15, + 440, 514, 515, 831, 1077, 844, 798, 1136, 339, 1079, + 1157, 643, 999, 426, 232, 232, 15, 409, 419, 850, + 318, 318, 795, 795, 1097, 1098, 303, 554, 804, 318, + 565, 566, 965, 1151, 1078, 1180, 1089, 813, 17, 1228, + 17, 433, 444, 17, 1068, 444, 989, 899, 1191, 1038, + 17, 1039, 929, 236, 1172, 930, 17, 17, 939, 444, + 942, 933, 553, 1174, 1061, 1030, 645, 1062, 731, 1171, + 955, 44, 309, 17, 622, 44, 894, 599, 313, 344, + 44, 320, 968, 709, 912, 591, 1016, 915, 410, 320, + 1175, 412, 339, 413, 484, 414, 15, 339, 344, 415, + 15, 552, 416, 601, 417, 15, 852, 127, 1043, 1046, + 44, 1206, 857, 356, 1064, 1065, 460, 466, 437, 437, + 581, 847, 902, 898, 336, 44, 44, 1178, nil, 336, + 795, nil, 356, nil, 629, 15, 596, 1126, 806, 579, + nil, 1143, 623, 624, nil, 961, 860, nil, 860, 383, + 15, 15, 493, 17, 236, nil, 1152, 17, 904, 513, + 587, 452, 17, 141, nil, 127, nil, nil, nil, 907, + 641, 580, 1219, 582, 525, 526, 836, nil, nil, 849, + nil, 685, 674, 583, nil, 691, 845, 690, 589, 809, + nil, 900, 17, nil, 900, nil, 666, 625, nil, 809, + nil, 1076, nil, 144, 1019, 562, 319, 17, 17, 493, + 882, 493, nil, nil, 319, 887, 1021, 1023, nil, 1025, + 1027, 868, 1028, 564, 722, 991, nil, 809, nil, nil, + nil, 567, nil, nil, 318, 809, nil, 815, 1177, 461, + 1036, nil, nil, 978, nil, 1042, 1045, 878, 880, 1110, + nil, nil, 883, 885, nil, 470, 923, nil, nil, nil, + nil, nil, nil, nil, 594, 772, 772, 904, nil, nil, + 935, nil, 460, 466, 969, nil, 685, nil, nil, 756, + 756, 895, nil, nil, 1229, 721, 709, 709, 609, 756, + nil, nil, 445, 684, nil, 756, nil, nil, 1090, 689, + 1048, 851, 445, 445, 318, 599, 975, 445, 445, nil, + nil, nil, 461, nil, 599, nil, nil, 737, 44, 879, + 881, 982, 461, nil, 884, 886, 344, nil, 470, 484, + nil, 979, nil, nil, 798, 344, nil, nil, 470, 756, + nil, nil, 318, 15, 794, nil, 904, nil, nil, nil, + 461, 795, 318, nil, nil, nil, 44, 841, 461, 44, + 356, 992, nil, nil, 1181, nil, 470, 1182, 679, 356, + 994, nil, 470, 823, nil, nil, 825, 1144, 1133, 1134, + 44, 15, nil, 995, 15, 822, 1230, 318, 784, 975, + nil, nil, nil, 1006, 1052, 461, nil, nil, 827, nil, + 17, 1060, nil, 141, nil, 15, 1103, 44, 947, nil, + nil, 470, nil, nil, 44, nil, nil, 848, nil, nil, + nil, nil, nil, nil, 1167, 1168, 1169, 1170, nil, nil, + nil, nil, 15, nil, nil, 440, 864, 1224, 17, 15, + 1007, 17, nil, 144, nil, 440, 440, nil, nil, nil, + 440, 440, nil, 1041, 877, 1198, 865, 896, 1049, 1050, + nil, nil, 17, 873, 779, nil, 1073, 967, nil, nil, + 1153, nil, 735, 735, nil, nil, nil, 1147, nil, 1148, + 1080, nil, 899, 772, 1207, nil, nil, 709, 709, 17, + nil, 772, 17, nil, 444, 445, 17, nil, 963, nil, + 772, 772, 17, 17, 444, 444, nil, 17, 17, 444, + 444, 966, 1008, nil, nil, 284, 141, nil, 1223, nil, + 599, nil, nil, nil, nil, nil, 835, nil, 493, nil, + 685, 980, nil, 690, 1096, 996, nil, nil, nil, nil, + nil, 344, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 344, nil, nil, nil, 879, 881, 886, 884, + nil, nil, 877, nil, nil, nil, nil, nil, nil, nil, + 1120, 1121, 1122, nil, 1060, 356, nil, nil, nil, 44, + nil, 981, nil, 1060, 44, nil, 356, 1176, nil, nil, + 1072, nil, nil, 437, nil, 44, 993, nil, nil, nil, + nil, nil, nil, nil, 15, 1131, nil, nil, nil, 15, + 383, nil, 1004, nil, nil, nil, nil, nil, nil, nil, + 15, nil, nil, nil, nil, nil, 900, 516, nil, 1073, + 44, 1060, 1073, nil, 1073, 1156, nil, nil, 440, nil, + nil, nil, nil, 1080, 1066, 679, 1080, 1015, nil, nil, + nil, nil, nil, 1014, nil, 15, nil, 1018, nil, 679, + 941, 17, 772, 1176, 772, nil, 17, 772, 772, nil, + nil, nil, 1008, 1087, 772, nil, nil, 17, nil, nil, + 772, 772, nil, nil, nil, nil, nil, nil, 772, 772, + 932, nil, nil, nil, nil, 17, nil, 444, 946, nil, + nil, nil, 1073, 568, 1073, nil, 1073, nil, 1073, 1127, + 1199, 44, 17, nil, nil, nil, 1080, nil, nil, 383, + 679, nil, nil, nil, 1222, 1073, 584, 772, 1084, 44, + nil, nil, nil, nil, nil, 44, 15, nil, nil, 906, + nil, 908, nil, nil, nil, nil, 1092, nil, 383, nil, + 679, 44, nil, 1072, 15, 1105, 1072, nil, 1072, 679, + 15, 809, nil, nil, nil, 1002, nil, nil, 1102, nil, + nil, nil, 1095, nil, nil, nil, 15, nil, nil, nil, + 1109, nil, 679, nil, 1081, nil, nil, nil, 381, 356, + nil, nil, nil, 17, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 44, nil, nil, nil, + nil, 17, nil, nil, nil, nil, nil, 17, nil, 297, + nil, nil, nil, nil, nil, nil, 1072, nil, 1072, nil, + 1072, 15, 1072, 17, nil, 44, 44, 1192, 1193, nil, + nil, 44, 679, nil, nil, nil, 1163, 679, 679, 1072, + nil, nil, 1155, 356, 772, nil, nil, 18, 1161, nil, + 15, 15, 18, 772, 696, nil, 15, 772, nil, 932, + nil, nil, nil, nil, 932, 932, 318, nil, nil, 242, + nil, nil, 297, nil, 461, 44, 1002, 1058, 17, 242, + 242, 242, nil, 18, 345, 345, nil, nil, nil, 19, + 470, nil, 1190, 725, 19, nil, nil, nil, nil, nil, + 15, 772, 383, 383, nil, nil, 356, 17, 17, nil, + nil, 18, nil, 17, 470, nil, 242, 242, nil, 44, + 242, 394, 404, 404, 735, 19, 352, 352, nil, 435, + 448, 781, nil, 772, 1081, nil, 1220, 1081, nil, 787, + 1081, 789, 1081, nil, 15, 793, nil, nil, nil, 679, + 679, 679, nil, 19, nil, nil, nil, 17, nil, 941, + nil, 802, nil, 352, 352, 352, nil, 805, nil, 18, + nil, nil, nil, nil, 242, 242, 242, 242, 18, nil, + 18, nil, nil, 1002, nil, nil, 820, nil, nil, nil, + 764, 764, nil, nil, nil, nil, nil, nil, 1074, nil, + nil, 17, nil, nil, nil, 1137, 1139, 1141, nil, nil, + 1081, 19, 1081, nil, 1081, nil, 1081, nil, nil, nil, + 19, nil, 19, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 573, 1081, 575, nil, nil, 577, 578, nil, + nil, nil, nil, nil, nil, nil, 1111, nil, 1112, nil, + 1113, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 1196, nil, 18, 242, 442, 242, 242, 442, 242, + nil, nil, nil, nil, nil, 18, nil, 765, 765, nil, + nil, 18, 442, 242, 242, nil, nil, nil, nil, nil, + nil, nil, nil, 916, nil, nil, nil, nil, 18, nil, + nil, nil, nil, 679, nil, 19, nil, 19, nil, nil, + 19, 1209, 1211, 1213, 1215, nil, 1216, 19, nil, nil, + nil, nil, nil, 19, 19, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 19, nil, nil, nil, 242, nil, 670, nil, nil, nil, + nil, 242, 242, nil, nil, 1232, 1233, 1234, 1235, nil, + 242, nil, nil, nil, 1183, nil, 1185, 1237, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 18, nil, + nil, nil, 18, nil, nil, nil, 345, 18, nil, nil, + nil, nil, 1204, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 345, nil, 716, 764, nil, + nil, nil, nil, 20, nil, nil, 764, 18, 20, nil, + 19, nil, nil, nil, 19, 764, 764, nil, 352, 19, + nil, 242, 18, 18, 1225, nil, 1226, nil, 1227, nil, + nil, nil, nil, nil, nil, nil, nil, 352, nil, 20, + 353, 353, 242, nil, nil, nil, nil, 1236, nil, 19, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 19, 19, nil, 20, nil, nil, + 796, nil, 381, nil, 799, nil, nil, 353, 353, 353, + 1029, nil, nil, nil, nil, 765, nil, nil, nil, nil, + nil, nil, nil, 765, nil, 1040, nil, nil, nil, nil, + nil, nil, 765, 765, nil, nil, 242, nil, nil, nil, + nil, 796, nil, nil, 381, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 20, nil, 448, nil, nil, + nil, nil, nil, nil, 20, nil, 20, 1070, nil, nil, + nil, nil, nil, nil, nil, 242, nil, nil, nil, 1085, + nil, nil, nil, nil, nil, 242, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 866, nil, nil, nil, nil, nil, 764, nil, 764, + 796, 381, 764, 764, nil, nil, nil, nil, nil, 764, + nil, nil, nil, nil, 893, 764, 764, nil, nil, nil, + nil, nil, nil, 764, 764, nil, nil, nil, 911, nil, + 1117, 1118, 1119, nil, nil, 18, nil, nil, nil, 20, + nil, 20, nil, 345, 20, 242, 1128, nil, nil, nil, + nil, 20, 345, nil, nil, nil, nil, 20, 20, nil, + nil, nil, 764, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 18, 20, nil, 18, 19, nil, nil, + nil, nil, nil, 242, 765, 352, 765, nil, nil, 765, + 765, nil, nil, 242, 352, nil, 765, 18, nil, nil, + nil, nil, 765, 765, nil, nil, nil, nil, 796, nil, + 765, 765, nil, nil, nil, 19, nil, 976, 19, nil, + 977, nil, nil, nil, 18, nil, nil, 442, 242, nil, + nil, 18, nil, nil, nil, nil, nil, 442, 442, 19, + nil, nil, 442, 442, nil, nil, nil, nil, nil, 765, + nil, nil, nil, nil, 20, nil, nil, nil, 20, nil, + nil, nil, 353, 20, 766, 766, 19, nil, nil, 19, + nil, nil, nil, 19, nil, nil, nil, nil, nil, 19, + 19, 353, nil, nil, 19, 19, 21, 1005, nil, 764, + nil, 21, nil, 20, nil, nil, nil, nil, 764, nil, + nil, nil, 764, nil, nil, nil, nil, nil, 20, 20, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 21, 347, 347, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 764, nil, nil, nil, + 21, nil, nil, nil, nil, nil, nil, nil, 345, nil, + 396, 405, 405, nil, nil, nil, 767, 767, nil, 345, + nil, nil, nil, 242, nil, nil, 765, nil, 764, nil, + nil, nil, nil, nil, nil, 765, nil, nil, nil, 765, + nil, nil, nil, nil, nil, nil, 18, nil, nil, nil, + 352, 18, 242, nil, nil, nil, nil, nil, 21, nil, + 1091, 352, 18, nil, nil, nil, nil, 21, nil, 21, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 381, + 442, nil, nil, 765, nil, nil, nil, nil, 19, nil, + nil, nil, nil, 19, nil, nil, nil, 18, nil, nil, + nil, nil, nil, nil, 19, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 765, nil, nil, nil, nil, + nil, nil, 19, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 766, nil, nil, nil, nil, nil, nil, 19, + 766, nil, nil, nil, nil, nil, nil, nil, nil, 766, + 766, 20, 21, nil, 443, nil, nil, 443, nil, 353, + nil, 242, nil, nil, 21, nil, nil, nil, 353, nil, + 21, 443, nil, nil, nil, nil, nil, nil, 18, nil, + nil, nil, nil, nil, nil, nil, nil, 21, nil, 20, + 242, nil, 20, nil, nil, nil, 18, nil, nil, nil, + nil, nil, 18, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 18, nil, + 19, nil, 1106, nil, nil, nil, nil, nil, nil, nil, + nil, 768, 768, nil, 767, nil, nil, nil, 19, nil, + 20, nil, 767, 20, 19, nil, nil, 20, nil, nil, + nil, 767, 767, 20, 20, nil, nil, nil, 20, 20, + 19, nil, nil, nil, 352, nil, nil, 21, nil, nil, + nil, 21, nil, 18, nil, 347, 21, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1145, nil, nil, nil, + nil, nil, nil, nil, 347, nil, nil, nil, nil, nil, + nil, nil, 18, 18, nil, nil, 21, nil, 18, nil, + nil, 766, nil, 766, nil, 19, 766, 766, nil, nil, + nil, 21, 21, 766, nil, nil, nil, nil, 352, 766, + 766, 769, 769, nil, nil, nil, nil, 766, 766, nil, + nil, nil, nil, nil, 19, 19, nil, nil, nil, 1187, + 19, nil, 18, nil, 242, 242, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 242, nil, nil, + nil, nil, nil, nil, 353, nil, 766, nil, nil, nil, + nil, nil, nil, nil, nil, 353, nil, nil, nil, nil, + nil, 352, nil, nil, 19, nil, 18, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 20, 767, nil, 767, nil, 20, 767, 767, + nil, nil, nil, nil, nil, 767, nil, nil, 20, nil, + nil, 767, 767, nil, nil, nil, nil, nil, 19, 767, + 767, nil, nil, nil, nil, nil, 20, nil, nil, 768, + nil, nil, nil, nil, nil, nil, nil, 768, nil, nil, + nil, nil, nil, 20, nil, nil, 768, 768, 31, nil, + nil, nil, nil, 31, nil, nil, nil, nil, 767, nil, + nil, 770, 770, nil, nil, nil, nil, nil, nil, nil, + 31, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 31, 31, 31, 766, 31, nil, nil, nil, nil, nil, + nil, nil, 766, nil, 21, nil, 766, nil, nil, nil, + nil, nil, 347, nil, nil, nil, nil, nil, nil, nil, + nil, 347, 31, nil, nil, nil, nil, 31, 31, nil, + nil, 31, nil, nil, 20, nil, nil, nil, nil, 769, + nil, nil, 21, nil, nil, 21, nil, 769, nil, nil, + 766, nil, 20, nil, nil, nil, 769, 769, 20, nil, + nil, nil, nil, nil, nil, nil, 21, nil, nil, nil, + nil, nil, nil, 856, 20, nil, nil, nil, 353, nil, + 31, nil, 766, nil, nil, 31, 31, 31, 31, 31, + nil, 31, nil, 21, nil, 767, 443, nil, nil, nil, + 21, nil, nil, nil, 767, nil, 443, 443, 767, nil, + nil, 443, 443, nil, nil, nil, nil, nil, 768, nil, + 768, nil, nil, 768, 768, nil, nil, nil, nil, 20, + 768, nil, nil, nil, nil, nil, 768, 768, nil, nil, + nil, nil, 353, nil, 768, 768, nil, nil, nil, nil, + nil, nil, 767, nil, nil, nil, nil, nil, 20, 20, + nil, nil, nil, nil, 20, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 31, 31, 31, 31, 31, 31, + 31, nil, nil, 768, 767, nil, 31, nil, nil, 770, + nil, nil, 31, 31, 31, 31, nil, 770, nil, nil, + nil, nil, nil, nil, nil, 353, 770, 770, 20, 31, + nil, nil, nil, nil, nil, nil, nil, nil, 769, nil, + 769, nil, nil, 769, 769, nil, nil, 347, nil, nil, + 769, nil, nil, nil, nil, nil, 769, 769, 347, nil, + nil, nil, nil, nil, 769, 769, nil, nil, nil, nil, + nil, nil, 20, nil, nil, 31, nil, nil, nil, nil, + nil, nil, 31, 31, nil, 21, nil, nil, nil, nil, + 21, 31, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 21, nil, 769, nil, nil, nil, nil, nil, 31, + nil, nil, nil, 31, nil, nil, nil, nil, 31, 443, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 768, nil, nil, nil, nil, nil, 21, nil, nil, 768, + nil, nil, nil, 768, nil, nil, nil, nil, 31, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 31, 31, 31, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 31, nil, nil, nil, 768, 770, nil, + 770, nil, nil, 770, 770, nil, nil, nil, nil, nil, + 770, nil, nil, nil, nil, nil, 770, 770, nil, nil, + nil, nil, nil, nil, 770, 770, nil, 21, nil, 768, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 769, nil, nil, nil, nil, 21, nil, nil, nil, 769, + nil, 21, nil, 769, nil, nil, nil, 31, nil, nil, + 771, 771, nil, 770, nil, nil, nil, 21, nil, nil, + nil, 1108, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 31, 769, nil, nil, + nil, 773, 773, nil, 34, nil, 31, nil, nil, 34, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 21, nil, nil, nil, 34, nil, nil, 769, + nil, nil, nil, nil, nil, 405, 34, 34, 34, nil, + 34, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 21, 21, nil, nil, nil, nil, 21, nil, nil, + nil, nil, nil, nil, nil, nil, 31, nil, 34, nil, + nil, nil, nil, 34, 34, nil, 31, 34, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 770, nil, nil, nil, nil, nil, nil, nil, 405, 770, + nil, 21, nil, 770, 31, nil, nil, 31, nil, nil, + nil, nil, nil, nil, 31, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 31, nil, 34, nil, 31, nil, + nil, 34, 34, 34, 34, 34, nil, 34, nil, nil, + nil, nil, nil, nil, nil, 21, nil, 770, nil, nil, + nil, nil, nil, nil, nil, 31, nil, nil, 31, 31, + nil, nil, 31, nil, nil, nil, nil, nil, 31, 31, + nil, nil, nil, 31, 31, nil, nil, nil, 771, 770, + nil, nil, nil, nil, nil, nil, 771, nil, nil, nil, + nil, nil, nil, nil, nil, 771, 771, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 773, + 34, 34, 34, 34, 34, 34, 34, 773, nil, nil, + nil, nil, 34, nil, nil, nil, 773, 773, 34, 34, + 34, 34, nil, nil, nil, nil, 43, nil, nil, nil, + nil, 43, nil, nil, nil, 34, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 296, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 43, 343, 343, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 34, nil, nil, 31, nil, nil, nil, 34, 34, + 43, nil, nil, nil, nil, nil, nil, 34, nil, nil, + 392, 296, 296, nil, nil, nil, nil, 31, nil, nil, + nil, nil, 31, 31, nil, 34, nil, nil, nil, 34, + nil, nil, nil, 31, 34, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 771, nil, 771, + nil, 31, 771, 771, nil, nil, nil, nil, 43, 771, + nil, nil, nil, nil, 34, 771, 771, 43, 31, 43, + nil, nil, nil, 771, 771, nil, nil, nil, 34, 34, + 34, nil, nil, nil, nil, nil, nil, nil, 773, nil, + 773, nil, nil, 773, 773, nil, nil, nil, nil, 34, + 773, nil, nil, nil, nil, nil, 773, 773, nil, nil, + nil, nil, 771, nil, 773, 773, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 31, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 31, + nil, nil, 43, 773, nil, nil, nil, nil, nil, nil, + nil, 31, nil, 34, 43, nil, nil, 31, nil, nil, + 43, nil, nil, 31, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 43, nil, 31, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 34, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 34, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 771, + nil, nil, nil, nil, 31, nil, nil, nil, 771, nil, + nil, nil, 771, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 43, nil, nil, + nil, 43, 34, 31, 31, 343, 43, nil, nil, 31, + 773, nil, 34, nil, nil, nil, nil, nil, nil, 773, + nil, nil, nil, 773, 343, nil, 771, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 43, nil, nil, nil, + 34, nil, nil, 34, nil, nil, nil, nil, nil, nil, + 34, 43, 43, 31, nil, 31, 31, nil, 771, nil, + 34, nil, nil, nil, 34, nil, nil, 773, 31, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 34, nil, nil, 34, 34, nil, 31, 34, 773, + nil, nil, nil, nil, 34, 34, nil, nil, nil, 34, + 34, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 249, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 317, 317, 317, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 364, 365, nil, 367, 368, + nil, 370, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 317, 317, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 34, nil, nil, nil, 43, nil, nil, nil, nil, nil, + nil, nil, 343, nil, nil, nil, nil, nil, nil, nil, + nil, 343, nil, 34, nil, nil, nil, nil, 34, 34, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 34, + nil, nil, 43, nil, nil, 43, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 34, nil, nil, + nil, nil, nil, nil, nil, nil, 43, nil, nil, nil, + nil, nil, nil, nil, 34, nil, nil, nil, 317, 447, + nil, nil, 453, 317, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 43, nil, nil, 453, nil, nil, nil, + 43, nil, nil, nil, nil, nil, nil, nil, nil, 249, + nil, nil, nil, nil, nil, nil, 529, 530, 531, 532, + 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, + 543, 544, 545, 546, 547, 548, 549, 550, 34, nil, + nil, nil, 551, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 34, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 317, 317, 34, nil, nil, + nil, nil, nil, 34, 317, nil, nil, nil, nil, 34, + nil, 317, nil, 317, nil, nil, 317, 317, nil, nil, + nil, nil, nil, nil, nil, 34, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 343, 604, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 343, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 34, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 43, nil, nil, nil, nil, + 43, nil, nil, nil, nil, nil, nil, nil, nil, 34, + 34, 43, nil, nil, nil, 34, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 317, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 43, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 34, + 692, 34, 34, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 34, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 317, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 723, + nil, nil, nil, 34, nil, nil, nil, nil, nil, 317, + nil, 453, 453, 453, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 43, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 43, nil, nil, nil, 365, + nil, 43, nil, nil, nil, nil, nil, nil, nil, 317, + nil, 317, nil, 317, nil, nil, nil, 43, nil, nil, + nil, 1104, nil, nil, nil, nil, nil, nil, nil, 317, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 453, + nil, nil, 816, nil, 817, nil, nil, nil, nil, nil, + 317, nil, nil, 317, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 317, 317, nil, nil, + nil, nil, 43, nil, nil, nil, nil, 317, nil, nil, + nil, nil, nil, nil, nil, 296, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 43, 43, nil, nil, nil, nil, 43, nil, nil, + 317, 453, 317, nil, nil, nil, 874, nil, nil, 317, + 317, 453, 453, nil, nil, nil, 453, 453, nil, nil, + nil, nil, nil, 317, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 317, 296, nil, + nil, 43, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 692, 723, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 43, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 317, nil, nil, + nil, nil, nil, nil, nil, nil, 317, nil, nil, 317, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 317, nil, nil, nil, + nil, nil, nil, nil, 453, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 1010, 1011, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1033, 1034, 453, 453, + 453, 453, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 1067, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 317, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 317, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 453, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 317 ] + +racc_goto_check = [ + 72, 230, 230, 198, 46, 72, 75, 75, 36, 36, + 36, 107, 91, 91, 158, 198, 68, 13, 33, 19, + 19, 48, 75, 19, 72, 23, 12, 10, 112, 33, + 23, 73, 31, 10, 110, 110, 72, 72, 72, 17, + 17, 117, 87, 87, 139, 139, 77, 77, 28, 8, + 135, 113, 92, 11, 8, 228, 228, 228, 44, 44, + 70, 23, 28, 133, 72, 111, 24, 24, 90, 90, + 90, 82, 82, 5, 72, 72, 72, 19, 19, 19, + 19, 119, 29, 55, 55, 64, 80, 29, 187, 23, + 87, 57, 94, 231, 26, 26, 41, 41, 26, 23, + 20, 90, 90, 20, 51, 7, 22, 9, 82, 82, + 82, 117, 235, 8, 31, 177, 177, 20, 29, 69, + 79, 58, 72, 127, 56, 56, 56, 128, 129, 130, + 147, 72, 145, 72, 79, 89, 89, 200, 200, 89, + 2, 192, 151, 5, 65, 193, 29, 23, 236, 13, + 157, 157, 26, 26, 26, 26, 23, 239, 23, 152, + 55, 6, 215, 215, 215, 215, 74, 74, 1, 10, + 3, 8, 95, 149, 95, 14, 161, 230, 225, 225, + 8, 16, 8, 18, 176, 21, 202, 202, 161, 25, + 146, 27, 146, 88, 88, 88, 42, 40, 36, 239, + 214, 214, 35, 35, 29, 43, 91, 178, 178, 45, + 63, 63, 63, 29, 50, 29, 72, 178, 236, 224, + 224, 52, 75, 60, 78, 83, 88, 40, 72, 94, + 84, 86, 93, 11, 72, 105, 106, 114, 198, 32, + 151, 23, 33, 23, 26, 26, 23, 116, 120, 121, + 122, 72, 123, 23, 124, 125, 126, 152, 131, 23, + 23, 26, 26, 112, 136, 73, 239, 142, 11, 143, + 150, 153, 154, 2, 87, 87, 23, 155, 6, 156, + 36, 36, 95, 95, 159, 160, 33, 162, 70, 36, + 164, 165, 168, 169, 149, 145, 170, 70, 29, 171, + 29, 22, 22, 29, 147, 22, 172, 200, 173, 180, + 29, 182, 183, 119, 192, 184, 29, 29, 188, 22, + 189, 175, 26, 192, 195, 127, 157, 196, 31, 130, + 205, 72, 91, 29, 19, 72, 206, 68, 91, 72, + 72, 90, 58, 128, 129, 33, 207, 128, 210, 90, + 193, 211, 11, 212, 225, 213, 23, 11, 72, 216, + 23, 51, 217, 33, 218, 23, 219, 117, 176, 176, + 72, 192, 220, 82, 202, 202, 55, 55, 88, 88, + 8, 223, 229, 233, 64, 72, 72, 234, nil, 64, + 95, nil, 82, nil, 33, 23, 80, 187, 31, 5, + nil, 149, 11, 11, nil, 73, 215, nil, 215, 26, + 23, 23, 230, 29, 119, nil, 13, 29, 231, 79, + 69, 79, 29, 75, nil, 117, nil, nil, nil, 235, + 26, 7, 111, 9, 35, 35, 31, nil, nil, 10, + nil, 91, 33, 65, nil, 36, 31, 91, 65, 55, + nil, 140, 29, nil, 140, nil, 17, 5, nil, 55, + nil, 146, nil, 77, 139, 88, 88, 29, 29, 230, + 57, 230, nil, nil, 88, 57, 228, 228, nil, 228, + 228, 31, 228, 63, 36, 110, nil, 55, nil, nil, + nil, 63, nil, nil, 36, 55, nil, 79, 133, 91, + 175, nil, nil, 70, nil, 175, 175, 28, 28, 146, + nil, nil, 28, 28, nil, 75, 32, nil, nil, nil, + nil, nil, nil, nil, 40, 72, 72, 231, nil, nil, + 32, nil, 55, 55, 92, nil, 91, nil, nil, 200, + 200, 24, nil, nil, 13, 117, 128, 128, 40, 200, + nil, nil, 20, 56, nil, 200, nil, nil, 41, 56, + 73, 157, 20, 20, 36, 68, 94, 20, 20, nil, + nil, nil, 91, nil, 68, nil, nil, 177, 72, 79, + 79, 89, 91, nil, 79, 79, 72, nil, 75, 225, + nil, 32, nil, nil, 239, 72, nil, nil, 75, 200, + nil, nil, 36, 23, 90, nil, 231, nil, nil, nil, + 91, 95, 36, nil, nil, nil, 72, 44, 91, 72, + 82, 32, nil, nil, 146, nil, 75, 146, 40, 82, + 32, nil, 75, 11, nil, nil, 11, 135, 139, 139, + 72, 23, nil, 10, 23, 90, 113, 36, 56, 94, + nil, nil, nil, 32, 191, 91, nil, nil, 117, nil, + 29, 191, nil, 75, nil, 23, 110, 72, 198, nil, + nil, 75, nil, nil, 72, nil, nil, 117, nil, nil, + nil, nil, nil, nil, 228, 228, 228, 228, nil, nil, + nil, nil, 23, nil, nil, 23, 17, 146, 29, 23, + 28, 29, nil, 77, nil, 23, 23, nil, nil, nil, + 23, 23, nil, 32, 90, 12, 8, 87, 32, 32, + nil, nil, 29, 8, 40, nil, 140, 107, nil, nil, + 112, nil, 174, 174, nil, nil, nil, 110, nil, 110, + 230, nil, 200, 72, 139, nil, nil, 128, 128, 29, + nil, 72, 29, nil, 22, 20, 29, nil, 46, nil, + 72, 72, 29, 29, 22, 22, nil, 29, 29, 22, + 22, 158, 79, nil, nil, 48, 75, nil, 228, nil, + 68, nil, nil, nil, nil, nil, 88, nil, 230, nil, + 91, 68, nil, 91, 10, 19, nil, nil, nil, nil, + nil, 72, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 72, nil, nil, nil, 79, 79, 79, 79, + nil, nil, 90, nil, nil, nil, nil, nil, nil, nil, + 32, 32, 32, nil, 191, 82, nil, nil, nil, 72, + nil, 26, nil, 191, 72, nil, 82, 191, nil, nil, + 132, nil, nil, 88, nil, 72, 11, nil, nil, nil, + nil, nil, nil, nil, 23, 10, nil, nil, nil, 23, + 26, nil, 11, nil, nil, nil, nil, nil, nil, nil, + 23, nil, nil, nil, nil, nil, 140, 66, nil, 140, + 72, 191, 140, nil, 140, 10, nil, nil, 23, nil, + nil, nil, nil, 230, 19, 40, 230, 11, nil, nil, + nil, nil, nil, 87, nil, 23, nil, 87, nil, 40, + 40, 29, 72, 191, 72, nil, 29, 72, 72, nil, + nil, nil, 79, 19, 72, nil, nil, 29, nil, nil, + 72, 72, nil, nil, nil, nil, nil, nil, 72, 72, + 174, nil, nil, nil, nil, 29, nil, 22, 174, nil, + nil, nil, 140, 66, 140, nil, 140, nil, 140, 198, + 31, 72, 29, nil, nil, nil, 230, nil, nil, 26, + 40, nil, nil, nil, 32, 140, 66, 72, 11, 72, + nil, nil, nil, nil, nil, 72, 23, nil, nil, 144, + nil, 144, nil, nil, nil, nil, 11, nil, 26, nil, + 40, 72, nil, 132, 23, 72, 132, nil, 132, 40, + 23, 55, nil, nil, nil, 40, nil, nil, 11, nil, + nil, nil, 117, nil, nil, nil, 23, nil, nil, nil, + 23, nil, 40, nil, 232, nil, nil, nil, 85, 82, + nil, nil, nil, 29, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 72, nil, nil, nil, + nil, 29, nil, nil, nil, nil, nil, 29, nil, 72, + nil, nil, nil, nil, nil, nil, 132, nil, 132, nil, + 132, 23, 132, 29, nil, 72, 72, 19, 19, nil, + nil, 72, 40, nil, nil, nil, 33, 40, 40, 132, + nil, nil, 11, 82, 72, nil, nil, 30, 11, nil, + 23, 23, 30, 72, 66, nil, 23, 72, nil, 174, + nil, nil, nil, nil, 174, 174, 36, nil, nil, 30, + nil, nil, 72, nil, 91, 72, 40, 174, 29, 30, + 30, 30, nil, 30, 30, 30, nil, nil, nil, 34, + 75, nil, 11, 66, 34, nil, nil, nil, nil, nil, + 23, 72, 26, 26, nil, nil, 82, 29, 29, nil, + nil, 30, nil, 29, 75, nil, 30, 30, nil, 72, + 30, 30, 30, 30, 174, 34, 34, 34, nil, 85, + 85, 66, nil, 72, 232, nil, 11, 232, nil, 66, + 232, 66, 232, nil, 23, 66, nil, nil, nil, 40, + 40, 40, nil, 34, nil, nil, nil, 29, nil, 40, + nil, 66, nil, 34, 34, 34, nil, 66, nil, 30, + nil, nil, nil, nil, 30, 30, 30, 30, 30, nil, + 30, nil, nil, 40, nil, nil, 66, nil, nil, nil, + 97, 97, nil, nil, nil, nil, nil, nil, 144, nil, + nil, 29, nil, nil, nil, 141, 141, 141, nil, nil, + 232, 34, 232, nil, 232, nil, 232, nil, nil, nil, + 34, nil, 34, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 85, 232, 85, nil, nil, 85, 85, nil, + nil, nil, nil, nil, nil, nil, 144, nil, 144, nil, + 144, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 40, nil, 30, 30, 30, 30, 30, 30, 30, + nil, nil, nil, nil, nil, 30, nil, 98, 98, nil, + nil, 30, 30, 30, 30, nil, nil, nil, nil, nil, + nil, nil, nil, 66, nil, nil, nil, nil, 30, nil, + nil, nil, nil, 40, nil, 34, nil, 34, nil, nil, + 34, 141, 141, 141, 141, nil, 141, 34, nil, nil, + nil, nil, nil, 34, 34, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 34, nil, nil, nil, 30, nil, 85, nil, nil, nil, + nil, 30, 30, nil, nil, 141, 141, 141, 141, nil, + 30, nil, nil, nil, 144, nil, 144, 141, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 30, nil, + nil, nil, 30, nil, nil, nil, 30, 30, nil, nil, + nil, nil, 144, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 30, nil, 85, 97, nil, + nil, nil, nil, 38, nil, nil, 97, 30, 38, nil, + 34, nil, nil, nil, 34, 97, 97, nil, 34, 34, + nil, 30, 30, 30, 144, nil, 144, nil, 144, nil, + nil, nil, nil, nil, nil, nil, nil, 34, nil, 38, + 38, 38, 30, nil, nil, nil, nil, 144, nil, 34, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 34, 34, nil, 38, nil, nil, + 85, nil, 85, nil, 85, nil, nil, 38, 38, 38, + 66, nil, nil, nil, nil, 98, nil, nil, nil, nil, + nil, nil, nil, 98, nil, 66, nil, nil, nil, nil, + nil, nil, 98, 98, nil, nil, 30, nil, nil, nil, + nil, 85, nil, nil, 85, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 38, nil, 85, nil, nil, + nil, nil, nil, nil, 38, nil, 38, 66, nil, nil, + nil, nil, nil, nil, nil, 30, nil, nil, nil, 66, + nil, nil, nil, nil, nil, 30, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 85, nil, nil, nil, nil, nil, 97, nil, 97, + 85, 85, 97, 97, nil, nil, nil, nil, nil, 97, + nil, nil, nil, nil, 85, 97, 97, nil, nil, nil, + nil, nil, nil, 97, 97, nil, nil, nil, 85, nil, + 66, 66, 66, nil, nil, 30, nil, nil, nil, 38, + nil, 38, nil, 30, 38, 30, 66, nil, nil, nil, + nil, 38, 30, nil, nil, nil, nil, 38, 38, nil, + nil, nil, 97, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 30, 38, nil, 30, 34, nil, nil, + nil, nil, nil, 30, 98, 34, 98, nil, nil, 98, + 98, nil, nil, 30, 34, nil, 98, 30, nil, nil, + nil, nil, 98, 98, nil, nil, nil, nil, 85, nil, + 98, 98, nil, nil, nil, 34, nil, 85, 34, nil, + 85, nil, nil, nil, 30, nil, nil, 30, 30, nil, + nil, 30, nil, nil, nil, nil, nil, 30, 30, 34, + nil, nil, 30, 30, nil, nil, nil, nil, nil, 98, + nil, nil, nil, nil, 38, nil, nil, nil, 38, nil, + nil, nil, 38, 38, 99, 99, 34, nil, nil, 34, + nil, nil, nil, 34, nil, nil, nil, nil, nil, 34, + 34, 38, nil, nil, 34, 34, 39, 85, nil, 97, + nil, 39, nil, 38, nil, nil, nil, nil, 97, nil, + nil, nil, 97, nil, nil, nil, nil, nil, 38, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 39, 39, 39, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 97, nil, nil, nil, + 39, nil, nil, nil, nil, nil, nil, nil, 30, nil, + 39, 39, 39, nil, nil, nil, 100, 100, nil, 30, + nil, nil, nil, 30, nil, nil, 98, nil, 97, nil, + nil, nil, nil, nil, nil, 98, nil, nil, nil, 98, + nil, nil, nil, nil, nil, nil, 30, nil, nil, nil, + 34, 30, 30, nil, nil, nil, nil, nil, 39, nil, + 85, 34, 30, nil, nil, nil, nil, 39, nil, 39, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 85, + 30, nil, nil, 98, nil, nil, nil, nil, 34, nil, + nil, nil, nil, 34, nil, nil, nil, 30, nil, nil, + nil, nil, nil, nil, 34, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 98, nil, nil, nil, nil, + nil, nil, 34, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 99, nil, nil, nil, nil, nil, nil, 34, + 99, nil, nil, nil, nil, nil, nil, nil, nil, 99, + 99, 38, 39, nil, 39, nil, nil, 39, nil, 38, + nil, 30, nil, nil, 39, nil, nil, nil, 38, nil, + 39, 39, nil, nil, nil, nil, nil, nil, 30, nil, + nil, nil, nil, nil, nil, nil, nil, 39, nil, 38, + 30, nil, 38, nil, nil, nil, 30, nil, nil, nil, + nil, nil, 30, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 38, nil, nil, nil, nil, 30, nil, + 34, nil, 30, nil, nil, nil, nil, nil, nil, nil, + nil, 101, 101, nil, 100, nil, nil, nil, 34, nil, + 38, nil, 100, 38, 34, nil, nil, 38, nil, nil, + nil, 100, 100, 38, 38, nil, nil, nil, 38, 38, + 34, nil, nil, nil, 34, nil, nil, 39, nil, nil, + nil, 39, nil, 30, nil, 39, 39, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 30, nil, nil, nil, + nil, nil, nil, nil, 39, nil, nil, nil, nil, nil, + nil, nil, 30, 30, nil, nil, 39, nil, 30, nil, + nil, 99, nil, 99, nil, 34, 99, 99, nil, nil, + nil, 39, 39, 99, nil, nil, nil, nil, 34, 99, + 99, 102, 102, nil, nil, nil, nil, 99, 99, nil, + nil, nil, nil, nil, 34, 34, nil, nil, nil, 30, + 34, nil, 30, nil, 30, 30, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 30, nil, nil, + nil, nil, nil, nil, 38, nil, 99, nil, nil, nil, + nil, nil, nil, nil, nil, 38, nil, nil, nil, nil, + nil, 34, nil, nil, 34, nil, 30, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 38, 100, nil, 100, nil, 38, 100, 100, + nil, nil, nil, nil, nil, 100, nil, nil, 38, nil, + nil, 100, 100, nil, nil, nil, nil, nil, 34, 100, + 100, nil, nil, nil, nil, nil, 38, nil, nil, 101, + nil, nil, nil, nil, nil, nil, nil, 101, nil, nil, + nil, nil, nil, 38, nil, nil, 101, 101, 59, nil, + nil, nil, nil, 59, nil, nil, nil, nil, 100, nil, + nil, 103, 103, nil, nil, nil, nil, nil, nil, nil, + 59, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 59, 59, 59, 99, 59, nil, nil, nil, nil, nil, + nil, nil, 99, nil, 39, nil, 99, nil, nil, nil, + nil, nil, 39, nil, nil, nil, nil, nil, nil, nil, + nil, 39, 59, nil, nil, nil, nil, 59, 59, nil, + nil, 59, nil, nil, 38, nil, nil, nil, nil, 102, + nil, nil, 39, nil, nil, 39, nil, 102, nil, nil, + 99, nil, 38, nil, nil, nil, 102, 102, 38, nil, + nil, nil, nil, nil, nil, nil, 39, nil, nil, nil, + nil, nil, nil, 39, 38, nil, nil, nil, 38, nil, + 59, nil, 99, nil, nil, 59, 59, 59, 59, 59, + nil, 59, nil, 39, nil, 100, 39, nil, nil, nil, + 39, nil, nil, nil, 100, nil, 39, 39, 100, nil, + nil, 39, 39, nil, nil, nil, nil, nil, 101, nil, + 101, nil, nil, 101, 101, nil, nil, nil, nil, 38, + 101, nil, nil, nil, nil, nil, 101, 101, nil, nil, + nil, nil, 38, nil, 101, 101, nil, nil, nil, nil, + nil, nil, 100, nil, nil, nil, nil, nil, 38, 38, + nil, nil, nil, nil, 38, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 59, 59, 59, 59, 59, 59, + 59, nil, nil, 101, 100, nil, 59, nil, nil, 103, + nil, nil, 59, 59, 59, 59, nil, 103, nil, nil, + nil, nil, nil, nil, nil, 38, 103, 103, 38, 59, + nil, nil, nil, nil, nil, nil, nil, nil, 102, nil, + 102, nil, nil, 102, 102, nil, nil, 39, nil, nil, + 102, nil, nil, nil, nil, nil, 102, 102, 39, nil, + nil, nil, nil, nil, 102, 102, nil, nil, nil, nil, + nil, nil, 38, nil, nil, 59, nil, nil, nil, nil, + nil, nil, 59, 59, nil, 39, nil, nil, nil, nil, + 39, 59, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 39, nil, 102, nil, nil, nil, nil, nil, 59, + nil, nil, nil, 59, nil, nil, nil, nil, 59, 39, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 101, nil, nil, nil, nil, nil, 39, nil, nil, 101, + nil, nil, nil, 101, nil, nil, nil, nil, 59, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 59, 59, 59, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 59, nil, nil, nil, 101, 103, nil, + 103, nil, nil, 103, 103, nil, nil, nil, nil, nil, + 103, nil, nil, nil, nil, nil, 103, 103, nil, nil, + nil, nil, nil, nil, 103, 103, nil, 39, nil, 101, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 102, nil, nil, nil, nil, 39, nil, nil, nil, 102, + nil, 39, nil, 102, nil, nil, nil, 59, nil, nil, + 104, 104, nil, 103, nil, nil, nil, 39, nil, nil, + nil, 39, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 59, 102, nil, nil, + nil, 109, 109, nil, 62, nil, 59, nil, nil, 62, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 39, nil, nil, nil, 62, nil, nil, 102, + nil, nil, nil, nil, nil, 39, 62, 62, 62, nil, + 62, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 39, 39, nil, nil, nil, nil, 39, nil, nil, + nil, nil, nil, nil, nil, nil, 59, nil, 62, nil, + nil, nil, nil, 62, 62, nil, 59, 62, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 103, nil, nil, nil, nil, nil, nil, nil, 39, 103, + nil, 39, nil, 103, 59, nil, nil, 59, nil, nil, + nil, nil, nil, nil, 59, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 59, nil, 62, nil, 59, nil, + nil, 62, 62, 62, 62, 62, nil, 62, nil, nil, + nil, nil, nil, nil, nil, 39, nil, 103, nil, nil, + nil, nil, nil, nil, nil, 59, nil, nil, 59, 59, + nil, nil, 59, nil, nil, nil, nil, nil, 59, 59, + nil, nil, nil, 59, 59, nil, nil, nil, 104, 103, + nil, nil, nil, nil, nil, nil, 104, nil, nil, nil, + nil, nil, nil, nil, nil, 104, 104, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 109, + 62, 62, 62, 62, 62, 62, 62, 109, nil, nil, + nil, nil, 62, nil, nil, nil, 109, 109, 62, 62, + 62, 62, nil, nil, nil, nil, 71, nil, nil, nil, + nil, 71, nil, nil, nil, 62, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 71, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 71, 71, 71, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 62, nil, nil, 59, nil, nil, nil, 62, 62, + 71, nil, nil, nil, nil, nil, nil, 62, nil, nil, + 71, 71, 71, nil, nil, nil, nil, 59, nil, nil, + nil, nil, 59, 59, nil, 62, nil, nil, nil, 62, + nil, nil, nil, 59, 62, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 104, nil, 104, + nil, 59, 104, 104, nil, nil, nil, nil, 71, 104, + nil, nil, nil, nil, 62, 104, 104, 71, 59, 71, + nil, nil, nil, 104, 104, nil, nil, nil, 62, 62, + 62, nil, nil, nil, nil, nil, nil, nil, 109, nil, + 109, nil, nil, 109, 109, nil, nil, nil, nil, 62, + 109, nil, nil, nil, nil, nil, 109, 109, nil, nil, + nil, nil, 104, nil, 109, 109, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 59, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 59, + nil, nil, 71, 109, nil, nil, nil, nil, nil, nil, + nil, 59, nil, 62, 71, nil, nil, 59, nil, nil, + 71, nil, nil, 59, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 71, nil, 59, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 62, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 62, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 104, + nil, nil, nil, nil, 59, nil, nil, nil, 104, nil, + nil, nil, 104, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 71, nil, nil, + nil, 71, 62, 59, 59, 71, 71, nil, nil, 59, + 109, nil, 62, nil, nil, nil, nil, nil, nil, 109, + nil, nil, nil, 109, 71, nil, 104, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 71, nil, nil, nil, + 62, nil, nil, 62, nil, nil, nil, nil, nil, nil, + 62, 71, 71, 59, nil, 59, 59, nil, 104, nil, + 62, nil, nil, nil, 62, nil, nil, 109, 59, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 62, nil, nil, 62, 62, nil, 59, 62, 109, + nil, nil, nil, nil, 62, 62, nil, nil, nil, 62, + 62, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 37, 37, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 37, 37, nil, 37, 37, + nil, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 37, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 62, nil, nil, nil, 71, nil, nil, nil, nil, nil, + nil, nil, 71, nil, nil, nil, nil, nil, nil, nil, + nil, 71, nil, 62, nil, nil, nil, nil, 62, 62, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 62, + nil, nil, 71, nil, nil, 71, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 62, nil, nil, + nil, nil, nil, nil, nil, nil, 71, nil, nil, nil, + nil, nil, nil, nil, 62, nil, nil, nil, 37, 37, + nil, nil, 37, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 71, nil, nil, 37, nil, nil, nil, + 71, nil, nil, nil, nil, nil, nil, nil, nil, 37, + nil, nil, nil, nil, nil, nil, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 62, nil, + nil, nil, 37, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 62, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 37, 37, 62, nil, nil, + nil, nil, nil, 62, 37, nil, nil, nil, nil, 62, + nil, 37, nil, 37, nil, nil, 37, 37, nil, nil, + nil, nil, nil, nil, nil, 62, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 71, 37, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 71, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 62, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 71, nil, nil, nil, nil, + 71, nil, nil, nil, nil, nil, nil, nil, nil, 62, + 62, 71, nil, nil, nil, 62, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 71, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 62, + 37, 62, 62, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 62, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 37, + nil, nil, nil, 62, nil, nil, nil, nil, nil, 37, + nil, 37, 37, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 71, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 71, nil, nil, nil, 37, + nil, 71, nil, nil, nil, nil, nil, nil, nil, 37, + nil, 37, nil, 37, nil, nil, nil, 71, nil, nil, + nil, 71, nil, nil, nil, nil, nil, nil, nil, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 37, + nil, nil, 37, nil, 37, nil, nil, nil, nil, nil, + 37, nil, nil, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 37, 37, nil, nil, + nil, nil, 71, nil, nil, nil, nil, 37, nil, nil, + nil, nil, nil, nil, nil, 71, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 71, 71, nil, nil, nil, nil, 71, nil, nil, + 37, 37, 37, nil, nil, nil, 37, nil, nil, 37, + 37, 37, 37, nil, nil, nil, 37, 37, nil, nil, + nil, nil, nil, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 37, 71, nil, + nil, 71, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 37, 37, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 71, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 37, nil, nil, + nil, nil, nil, nil, nil, nil, 37, nil, nil, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 37, nil, nil, nil, + nil, nil, nil, nil, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 37, 37, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 37, 37, 37, 37, + 37, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 37, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 37 ] + +racc_goto_pointer = [ + nil, 168, 138, 170, nil, 68, 154, 100, 47, 98, + -203, 15, -446, -676, -715, nil, -399, 29, 172, -52, + -120, 109, 82, 23, -153, -30, 23, 55, -175, 80, + 1115, -192, -215, 0, 1157, 183, -26, 3569, 1481, 1844, + 174, -431, -59, -51, -15, -413, -22, nil, -5, nil, + 188, 75, -331, nil, nil, -142, 93, -214, -444, 2376, + -335, nil, 2892, 176, 47, 106, 648, nil, -23, 79, + -300, 3134, -2, -371, 89, -4, nil, 36, -207, -103, + 38, nil, 32, 174, -141, 980, 164, 23, 159, -241, + 34, -19, -254, -323, -228, -398, nil, 733, 820, 1297, + 1399, 1614, 1714, 1864, 2323, 209, 168, -58, nil, 2364, + -350, -758, -362, -574, 161, nil, -159, 36, nil, 61, + 183, -124, 184, -354, -385, -593, -152, -790, -367, -366, + -785, -655, -122, -634, nil, -443, -708, nil, nil, -433, + -246, 201, -807, -703, 296, -840, -511, -661, nil, -678, + -829, -957, -940, -138, -578, 192, -364, -83, -13, -716, + -716, -378, -13, nil, -20, -20, nil, nil, -491, -799, + -693, -921, -527, -840, 205, -424, -561, -412, -722, nil, + -616, nil, -615, -432, -429, nil, nil, -658, -428, -427, + nil, -282, -802, -779, nil, -621, -618, nil, -87, nil, + -390, nil, -576, nil, nil, -445, -358, -548, nil, nil, + 260, 258, 259, 260, -214, -250, 263, 265, 266, -283, + -278, nil, nil, -259, -133, -55, nil, nil, -426, -319, + -232, -608, 72, -314, -745, -591, -990, nil, nil, -415 ] + +racc_goto_default = [ + nil, nil, nil, nil, 5, nil, 6, 391, 334, nil, + nil, 472, nil, 984, nil, 331, 332, nil, nil, nil, + 13, 14, 22, 247, nil, nil, 16, nil, 441, 248, + 363, nil, nil, 637, 251, nil, 27, 25, 252, 246, + 517, nil, nil, nil, nil, nil, nil, 386, 143, 26, + nil, nil, nil, 28, 29, 812, nil, nil, nil, 351, + nil, 30, 348, 455, 37, nil, nil, 39, 42, 41, + nil, 243, 244, 403, nil, 463, 142, 87, nil, 446, + 103, 51, 54, 283, nil, 323, nil, 891, 456, nil, + 457, 468, 480, 686, 569, 321, 307, 55, 56, 57, + 58, 59, 60, 61, 62, 63, nil, 308, 69, 70, + nil, nil, nil, nil, nil, 77, nil, 619, 78, 230, + nil, nil, nil, nil, nil, nil, nil, 711, 492, nil, + 712, 713, 478, 474, 475, nil, 1179, 707, 1071, nil, + 479, nil, nil, nil, 481, nil, 483, nil, 971, nil, + nil, nil, 490, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 467, nil, nil, 791, 783, nil, nil, + nil, nil, nil, nil, 1051, nil, 736, 937, 738, 739, + 743, 740, 741, nil, nil, 742, 744, nil, nil, nil, + 936, 938, nil, 748, 750, 751, 752, 753, nil, 757, + 501, 758, 759, 760, 761, nil, nil, nil, 86, 88, + 89, nil, nil, nil, nil, 647, nil, nil, nil, nil, + nil, 99, 100, nil, 231, 901, 234, 477, nil, 482, + 909, 495, 497, 498, 1082, 502, 1083, 505, 508, 326 ] + +racc_reduce_table = [ + 0, 0, :racc_error, + 0, 150, :_reduce_1, + 2, 148, :_reduce_2, + 2, 149, :_reduce_3, + 0, 151, :_reduce_4, + 1, 151, :_reduce_5, + 3, 151, :_reduce_6, + 2, 151, :_reduce_7, + 1, 153, :_reduce_none, + 2, 153, :_reduce_9, + 3, 156, :_reduce_10, + 4, 157, :_reduce_11, + 2, 158, :_reduce_12, + 0, 162, :_reduce_13, + 1, 162, :_reduce_14, + 3, 162, :_reduce_15, + 2, 162, :_reduce_16, + 1, 163, :_reduce_none, + 2, 163, :_reduce_18, + 0, 174, :_reduce_19, + 4, 155, :_reduce_20, + 3, 155, :_reduce_21, + 3, 155, :_reduce_22, + 3, 155, :_reduce_23, + 2, 155, :_reduce_24, + 3, 155, :_reduce_25, + 3, 155, :_reduce_26, + 3, 155, :_reduce_27, + 3, 155, :_reduce_28, + 3, 155, :_reduce_29, + 4, 155, :_reduce_30, + 1, 155, :_reduce_none, + 3, 155, :_reduce_32, + 3, 155, :_reduce_33, + 5, 155, :_reduce_34, + 3, 155, :_reduce_35, + 1, 155, :_reduce_none, + 3, 167, :_reduce_37, + 3, 167, :_reduce_38, + 6, 167, :_reduce_39, + 5, 167, :_reduce_40, + 5, 167, :_reduce_41, + 5, 167, :_reduce_42, + 5, 167, :_reduce_43, + 4, 167, :_reduce_44, + 6, 167, :_reduce_45, + 4, 167, :_reduce_46, + 6, 167, :_reduce_47, + 3, 167, :_reduce_48, + 1, 175, :_reduce_none, + 3, 175, :_reduce_50, + 1, 175, :_reduce_none, + 1, 173, :_reduce_none, + 3, 173, :_reduce_53, + 3, 173, :_reduce_54, + 3, 173, :_reduce_55, + 2, 173, :_reduce_56, + 0, 189, :_reduce_57, + 4, 173, :_reduce_58, + 0, 190, :_reduce_59, + 4, 173, :_reduce_60, + 1, 173, :_reduce_none, + 1, 166, :_reduce_none, + 0, 194, :_reduce_63, + 3, 191, :_reduce_64, + 1, 193, :_reduce_65, + 2, 181, :_reduce_66, + 0, 199, :_reduce_67, + 5, 185, :_reduce_68, + 1, 169, :_reduce_none, + 1, 169, :_reduce_none, + 1, 200, :_reduce_none, + 4, 200, :_reduce_72, + 0, 207, :_reduce_73, + 4, 204, :_reduce_74, + 1, 206, :_reduce_none, + 2, 183, :_reduce_76, + 3, 183, :_reduce_77, + 4, 183, :_reduce_78, + 5, 183, :_reduce_79, + 4, 183, :_reduce_80, + 5, 183, :_reduce_81, + 2, 183, :_reduce_82, + 2, 183, :_reduce_83, + 2, 183, :_reduce_84, + 2, 183, :_reduce_85, + 2, 183, :_reduce_86, + 1, 168, :_reduce_87, + 3, 168, :_reduce_88, + 1, 212, :_reduce_89, + 3, 212, :_reduce_90, + 1, 211, :_reduce_none, + 2, 211, :_reduce_92, + 3, 211, :_reduce_93, + 5, 211, :_reduce_94, + 2, 211, :_reduce_95, + 4, 211, :_reduce_96, + 2, 211, :_reduce_97, + 4, 211, :_reduce_98, + 1, 211, :_reduce_99, + 3, 211, :_reduce_100, + 1, 215, :_reduce_none, + 3, 215, :_reduce_102, + 2, 214, :_reduce_103, + 3, 214, :_reduce_104, + 1, 217, :_reduce_105, + 3, 217, :_reduce_106, + 1, 216, :_reduce_107, + 1, 216, :_reduce_108, + 4, 216, :_reduce_109, + 3, 216, :_reduce_110, + 3, 216, :_reduce_111, + 3, 216, :_reduce_112, + 3, 216, :_reduce_113, + 2, 216, :_reduce_114, + 1, 216, :_reduce_115, + 1, 170, :_reduce_116, + 1, 170, :_reduce_117, + 4, 170, :_reduce_118, + 3, 170, :_reduce_119, + 3, 170, :_reduce_120, + 3, 170, :_reduce_121, + 3, 170, :_reduce_122, + 2, 170, :_reduce_123, + 1, 170, :_reduce_124, + 1, 220, :_reduce_125, + 1, 220, :_reduce_none, + 2, 221, :_reduce_127, + 1, 221, :_reduce_128, + 3, 221, :_reduce_129, + 1, 195, :_reduce_none, + 1, 195, :_reduce_none, + 1, 195, :_reduce_none, + 1, 195, :_reduce_none, + 1, 195, :_reduce_none, + 1, 164, :_reduce_135, + 1, 164, :_reduce_none, + 1, 165, :_reduce_137, + 0, 225, :_reduce_138, + 4, 165, :_reduce_139, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 3, 184, :_reduce_211, + 3, 184, :_reduce_212, + 6, 184, :_reduce_213, + 5, 184, :_reduce_214, + 5, 184, :_reduce_215, + 5, 184, :_reduce_216, + 5, 184, :_reduce_217, + 4, 184, :_reduce_218, + 3, 184, :_reduce_219, + 3, 184, :_reduce_220, + 3, 184, :_reduce_221, + 2, 184, :_reduce_222, + 2, 184, :_reduce_223, + 2, 184, :_reduce_224, + 2, 184, :_reduce_225, + 3, 184, :_reduce_226, + 3, 184, :_reduce_227, + 3, 184, :_reduce_228, + 3, 184, :_reduce_229, + 3, 184, :_reduce_230, + 3, 184, :_reduce_231, + 4, 184, :_reduce_232, + 2, 184, :_reduce_233, + 2, 184, :_reduce_234, + 3, 184, :_reduce_235, + 3, 184, :_reduce_236, + 3, 184, :_reduce_237, + 3, 184, :_reduce_238, + 1, 184, :_reduce_none, + 3, 184, :_reduce_240, + 3, 184, :_reduce_241, + 3, 184, :_reduce_242, + 3, 184, :_reduce_243, + 3, 184, :_reduce_244, + 2, 184, :_reduce_245, + 2, 184, :_reduce_246, + 3, 184, :_reduce_247, + 3, 184, :_reduce_248, + 3, 184, :_reduce_249, + 3, 184, :_reduce_250, + 0, 231, :_reduce_251, + 4, 184, :_reduce_252, + 6, 184, :_reduce_253, + 4, 184, :_reduce_254, + 6, 184, :_reduce_255, + 4, 184, :_reduce_256, + 6, 184, :_reduce_257, + 1, 184, :_reduce_none, + 1, 230, :_reduce_none, + 1, 230, :_reduce_none, + 1, 230, :_reduce_none, + 1, 230, :_reduce_none, + 3, 228, :_reduce_263, + 3, 228, :_reduce_264, + 1, 232, :_reduce_none, + 1, 233, :_reduce_none, + 2, 233, :_reduce_none, + 4, 233, :_reduce_268, + 2, 233, :_reduce_269, + 1, 226, :_reduce_none, + 3, 226, :_reduce_271, + 3, 238, :_reduce_272, + 5, 238, :_reduce_273, + 3, 238, :_reduce_274, + 0, 240, :_reduce_275, + 1, 240, :_reduce_none, + 0, 178, :_reduce_277, + 1, 178, :_reduce_none, + 2, 178, :_reduce_none, + 4, 178, :_reduce_280, + 2, 178, :_reduce_281, + 1, 210, :_reduce_282, + 2, 210, :_reduce_283, + 2, 210, :_reduce_284, + 4, 210, :_reduce_285, + 1, 210, :_reduce_286, + 0, 243, :_reduce_287, + 2, 203, :_reduce_288, + 2, 242, :_reduce_289, + 1, 242, :_reduce_290, + 2, 241, :_reduce_291, + 0, 241, :_reduce_292, + 1, 235, :_reduce_293, + 2, 235, :_reduce_294, + 3, 235, :_reduce_295, + 4, 235, :_reduce_296, + 1, 172, :_reduce_297, + 1, 172, :_reduce_none, + 3, 171, :_reduce_299, + 4, 171, :_reduce_300, + 2, 171, :_reduce_301, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_312, + 0, 267, :_reduce_313, + 4, 229, :_reduce_314, + 0, 268, :_reduce_315, + 4, 229, :_reduce_316, + 0, 269, :_reduce_317, + 4, 229, :_reduce_318, + 3, 229, :_reduce_319, + 3, 229, :_reduce_320, + 2, 229, :_reduce_321, + 3, 229, :_reduce_322, + 3, 229, :_reduce_323, + 1, 229, :_reduce_324, + 4, 229, :_reduce_325, + 3, 229, :_reduce_326, + 1, 229, :_reduce_327, + 0, 270, :_reduce_328, + 6, 229, :_reduce_329, + 4, 229, :_reduce_330, + 3, 229, :_reduce_331, + 2, 229, :_reduce_332, + 1, 229, :_reduce_none, + 2, 229, :_reduce_334, + 1, 229, :_reduce_none, + 6, 229, :_reduce_336, + 6, 229, :_reduce_337, + 4, 229, :_reduce_338, + 4, 229, :_reduce_339, + 5, 229, :_reduce_340, + 4, 229, :_reduce_341, + 5, 229, :_reduce_342, + 6, 229, :_reduce_343, + 0, 271, :_reduce_344, + 6, 229, :_reduce_345, + 0, 272, :_reduce_346, + 7, 229, :_reduce_347, + 0, 273, :_reduce_348, + 5, 229, :_reduce_349, + 4, 229, :_reduce_350, + 4, 229, :_reduce_351, + 1, 229, :_reduce_352, + 1, 229, :_reduce_353, + 1, 229, :_reduce_354, + 1, 229, :_reduce_355, + 1, 177, :_reduce_none, + 1, 262, :_reduce_357, + 1, 265, :_reduce_358, + 1, 196, :_reduce_359, + 1, 209, :_reduce_360, + 1, 257, :_reduce_none, + 1, 257, :_reduce_none, + 2, 257, :_reduce_363, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 258, :_reduce_none, + 5, 258, :_reduce_367, + 1, 160, :_reduce_none, + 2, 160, :_reduce_369, + 1, 261, :_reduce_none, + 1, 261, :_reduce_none, + 1, 274, :_reduce_372, + 3, 274, :_reduce_373, + 1, 277, :_reduce_374, + 3, 277, :_reduce_375, + 1, 276, :_reduce_none, + 3, 276, :_reduce_377, + 5, 276, :_reduce_378, + 1, 276, :_reduce_379, + 3, 276, :_reduce_380, + 2, 278, :_reduce_381, + 1, 278, :_reduce_382, + 1, 279, :_reduce_none, + 1, 279, :_reduce_none, + 0, 284, :_reduce_385, + 2, 282, :_reduce_386, + 4, 283, :_reduce_387, + 2, 283, :_reduce_388, + 2, 283, :_reduce_389, + 1, 283, :_reduce_390, + 2, 288, :_reduce_391, + 0, 288, :_reduce_392, + 1, 289, :_reduce_none, + 6, 290, :_reduce_394, + 8, 290, :_reduce_395, + 4, 290, :_reduce_396, + 6, 290, :_reduce_397, + 4, 290, :_reduce_398, + 2, 290, :_reduce_none, + 6, 290, :_reduce_400, + 2, 290, :_reduce_401, + 4, 290, :_reduce_402, + 6, 290, :_reduce_403, + 2, 290, :_reduce_404, + 4, 290, :_reduce_405, + 2, 290, :_reduce_406, + 4, 290, :_reduce_407, + 1, 290, :_reduce_none, + 0, 294, :_reduce_409, + 1, 294, :_reduce_410, + 3, 295, :_reduce_411, + 4, 295, :_reduce_412, + 1, 296, :_reduce_413, + 4, 296, :_reduce_414, + 1, 297, :_reduce_415, + 3, 297, :_reduce_416, + 1, 298, :_reduce_417, + 1, 298, :_reduce_none, + 0, 302, :_reduce_419, + 0, 303, :_reduce_420, + 5, 256, :_reduce_421, + 4, 300, :_reduce_422, + 1, 300, :_reduce_423, + 0, 306, :_reduce_424, + 4, 301, :_reduce_425, + 0, 307, :_reduce_426, + 4, 301, :_reduce_427, + 0, 309, :_reduce_428, + 4, 305, :_reduce_429, + 2, 201, :_reduce_430, + 4, 201, :_reduce_431, + 5, 201, :_reduce_432, + 5, 201, :_reduce_433, + 2, 255, :_reduce_434, + 4, 255, :_reduce_435, + 4, 255, :_reduce_436, + 3, 255, :_reduce_437, + 3, 255, :_reduce_438, + 3, 255, :_reduce_439, + 2, 255, :_reduce_440, + 1, 255, :_reduce_441, + 4, 255, :_reduce_442, + 0, 311, :_reduce_443, + 4, 254, :_reduce_444, + 0, 312, :_reduce_445, + 4, 254, :_reduce_446, + 0, 313, :_reduce_447, + 3, 205, :_reduce_448, + 0, 314, :_reduce_449, + 0, 315, :_reduce_450, + 4, 308, :_reduce_451, + 5, 259, :_reduce_452, + 1, 316, :_reduce_453, + 1, 316, :_reduce_none, + 0, 319, :_reduce_455, + 0, 320, :_reduce_456, + 7, 260, :_reduce_457, + 1, 318, :_reduce_458, + 1, 318, :_reduce_none, + 1, 317, :_reduce_460, + 3, 317, :_reduce_461, + 3, 317, :_reduce_462, + 1, 188, :_reduce_none, + 2, 188, :_reduce_464, + 3, 188, :_reduce_465, + 1, 188, :_reduce_466, + 1, 188, :_reduce_467, + 1, 188, :_reduce_468, + 1, 321, :_reduce_none, + 3, 326, :_reduce_470, + 1, 326, :_reduce_none, + 3, 328, :_reduce_472, + 1, 328, :_reduce_none, + 1, 330, :_reduce_474, + 1, 331, :_reduce_475, + 1, 329, :_reduce_none, + 1, 329, :_reduce_none, + 4, 329, :_reduce_478, + 4, 329, :_reduce_479, + 4, 329, :_reduce_480, + 3, 329, :_reduce_481, + 4, 329, :_reduce_482, + 4, 329, :_reduce_483, + 4, 329, :_reduce_484, + 3, 329, :_reduce_485, + 3, 329, :_reduce_486, + 3, 329, :_reduce_487, + 2, 329, :_reduce_488, + 0, 335, :_reduce_489, + 4, 329, :_reduce_490, + 2, 329, :_reduce_491, + 0, 336, :_reduce_492, + 4, 329, :_reduce_493, + 1, 322, :_reduce_494, + 1, 322, :_reduce_495, + 2, 322, :_reduce_496, + 3, 322, :_reduce_497, + 5, 322, :_reduce_498, + 2, 322, :_reduce_499, + 4, 322, :_reduce_500, + 1, 322, :_reduce_none, + 2, 337, :_reduce_502, + 3, 337, :_reduce_503, + 1, 324, :_reduce_504, + 3, 324, :_reduce_505, + 5, 323, :_reduce_506, + 2, 340, :_reduce_507, + 1, 340, :_reduce_508, + 1, 339, :_reduce_509, + 3, 339, :_reduce_510, + 1, 338, :_reduce_none, + 3, 325, :_reduce_512, + 1, 325, :_reduce_513, + 2, 325, :_reduce_514, + 1, 325, :_reduce_515, + 1, 341, :_reduce_516, + 3, 341, :_reduce_517, + 2, 343, :_reduce_518, + 1, 343, :_reduce_519, + 1, 344, :_reduce_520, + 3, 344, :_reduce_521, + 2, 346, :_reduce_522, + 1, 346, :_reduce_523, + 2, 348, :_reduce_524, + 1, 342, :_reduce_none, + 1, 342, :_reduce_none, + 1, 332, :_reduce_none, + 3, 332, :_reduce_528, + 3, 332, :_reduce_529, + 2, 332, :_reduce_530, + 2, 332, :_reduce_531, + 1, 332, :_reduce_none, + 1, 332, :_reduce_none, + 1, 332, :_reduce_none, + 2, 332, :_reduce_535, + 2, 332, :_reduce_536, + 1, 349, :_reduce_none, + 1, 349, :_reduce_none, + 1, 349, :_reduce_none, + 1, 349, :_reduce_none, + 1, 349, :_reduce_none, + 1, 349, :_reduce_none, + 1, 349, :_reduce_none, + 1, 349, :_reduce_none, + 1, 349, :_reduce_545, + 1, 349, :_reduce_none, + 1, 327, :_reduce_547, + 2, 350, :_reduce_548, + 2, 350, :_reduce_549, + 4, 351, :_reduce_550, + 2, 333, :_reduce_551, + 3, 333, :_reduce_552, + 1, 333, :_reduce_553, + 6, 159, :_reduce_554, + 0, 159, :_reduce_555, + 1, 353, :_reduce_556, + 1, 353, :_reduce_none, + 1, 353, :_reduce_none, + 2, 354, :_reduce_559, + 1, 354, :_reduce_none, + 2, 161, :_reduce_561, + 1, 161, :_reduce_none, + 1, 244, :_reduce_none, + 1, 244, :_reduce_none, + 1, 245, :_reduce_565, + 1, 356, :_reduce_566, + 2, 356, :_reduce_567, + 3, 357, :_reduce_568, + 1, 357, :_reduce_569, + 1, 357, :_reduce_570, + 3, 246, :_reduce_571, + 4, 247, :_reduce_572, + 3, 248, :_reduce_573, + 0, 360, :_reduce_574, + 3, 360, :_reduce_575, + 1, 361, :_reduce_576, + 2, 361, :_reduce_577, + 3, 250, :_reduce_578, + 0, 363, :_reduce_579, + 3, 363, :_reduce_580, + 3, 249, :_reduce_581, + 3, 251, :_reduce_582, + 0, 364, :_reduce_583, + 3, 364, :_reduce_584, + 0, 365, :_reduce_585, + 3, 365, :_reduce_586, + 0, 345, :_reduce_587, + 2, 345, :_reduce_588, + 0, 358, :_reduce_589, + 2, 358, :_reduce_590, + 0, 359, :_reduce_591, + 2, 359, :_reduce_592, + 1, 362, :_reduce_593, + 2, 362, :_reduce_594, + 0, 367, :_reduce_595, + 4, 362, :_reduce_596, + 1, 366, :_reduce_597, + 1, 366, :_reduce_598, + 1, 366, :_reduce_599, + 1, 366, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 368, :_reduce_603, + 3, 369, :_reduce_604, + 1, 355, :_reduce_605, + 2, 355, :_reduce_606, + 1, 227, :_reduce_607, + 1, 227, :_reduce_608, + 1, 227, :_reduce_609, + 1, 227, :_reduce_610, + 1, 352, :_reduce_611, + 1, 352, :_reduce_612, + 1, 352, :_reduce_613, + 1, 218, :_reduce_614, + 1, 218, :_reduce_615, + 1, 218, :_reduce_616, + 1, 218, :_reduce_617, + 1, 218, :_reduce_618, + 1, 219, :_reduce_619, + 1, 219, :_reduce_620, + 1, 219, :_reduce_621, + 1, 219, :_reduce_622, + 1, 219, :_reduce_623, + 1, 219, :_reduce_624, + 1, 219, :_reduce_625, + 1, 252, :_reduce_626, + 1, 252, :_reduce_627, + 1, 176, :_reduce_628, + 1, 176, :_reduce_629, + 1, 186, :_reduce_630, + 1, 186, :_reduce_631, + 0, 370, :_reduce_632, + 4, 263, :_reduce_633, + 0, 263, :_reduce_634, + 1, 182, :_reduce_none, + 1, 182, :_reduce_636, + 3, 371, :_reduce_637, + 1, 266, :_reduce_none, + 0, 373, :_reduce_639, + 3, 266, :_reduce_640, + 4, 372, :_reduce_641, + 2, 372, :_reduce_642, + 2, 372, :_reduce_643, + 1, 372, :_reduce_644, + 1, 372, :_reduce_645, + 2, 375, :_reduce_646, + 0, 375, :_reduce_647, + 6, 304, :_reduce_648, + 8, 304, :_reduce_649, + 4, 304, :_reduce_650, + 6, 304, :_reduce_651, + 4, 304, :_reduce_652, + 6, 304, :_reduce_653, + 2, 304, :_reduce_654, + 4, 304, :_reduce_655, + 6, 304, :_reduce_656, + 2, 304, :_reduce_657, + 4, 304, :_reduce_658, + 2, 304, :_reduce_659, + 4, 304, :_reduce_660, + 1, 304, :_reduce_661, + 0, 304, :_reduce_662, + 1, 239, :_reduce_663, + 1, 299, :_reduce_664, + 1, 299, :_reduce_665, + 1, 299, :_reduce_666, + 1, 299, :_reduce_667, + 1, 275, :_reduce_none, + 1, 275, :_reduce_669, + 1, 377, :_reduce_670, + 1, 378, :_reduce_671, + 3, 378, :_reduce_672, + 1, 291, :_reduce_673, + 3, 291, :_reduce_674, + 1, 379, :_reduce_675, + 2, 380, :_reduce_676, + 1, 380, :_reduce_677, + 2, 381, :_reduce_678, + 1, 381, :_reduce_679, + 1, 285, :_reduce_680, + 3, 285, :_reduce_681, + 1, 374, :_reduce_682, + 3, 374, :_reduce_683, + 1, 347, :_reduce_none, + 1, 347, :_reduce_none, + 2, 281, :_reduce_686, + 2, 280, :_reduce_687, + 1, 280, :_reduce_688, + 3, 382, :_reduce_689, + 3, 383, :_reduce_690, + 1, 292, :_reduce_691, + 3, 292, :_reduce_692, + 1, 376, :_reduce_693, + 3, 376, :_reduce_694, + 1, 384, :_reduce_none, + 1, 384, :_reduce_none, + 2, 293, :_reduce_697, + 1, 293, :_reduce_698, + 1, 385, :_reduce_none, + 1, 385, :_reduce_none, + 2, 287, :_reduce_701, + 1, 287, :_reduce_702, + 2, 286, :_reduce_703, + 0, 286, :_reduce_704, + 1, 197, :_reduce_none, + 3, 197, :_reduce_706, + 0, 253, :_reduce_707, + 2, 253, :_reduce_none, + 1, 237, :_reduce_709, + 3, 237, :_reduce_710, + 3, 386, :_reduce_711, + 2, 386, :_reduce_712, + 1, 386, :_reduce_713, + 4, 386, :_reduce_714, + 2, 386, :_reduce_715, + 1, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 310, :_reduce_none, + 1, 310, :_reduce_none, + 1, 310, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 180, :_reduce_728, + 1, 180, :_reduce_729, + 0, 152, :_reduce_none, + 1, 152, :_reduce_none, + 0, 187, :_reduce_none, + 1, 187, :_reduce_none, + 2, 213, :_reduce_734, + 2, 179, :_reduce_735, + 2, 334, :_reduce_736, + 0, 236, :_reduce_none, + 1, 236, :_reduce_none, + 1, 236, :_reduce_none, + 1, 264, :_reduce_740, + 1, 264, :_reduce_none, + 1, 154, :_reduce_none, + 2, 154, :_reduce_none, + 0, 234, :_reduce_744 ] + +racc_reduce_n = 745 + +racc_shift_n = 1238 + +racc_token_table = { + false => 0, + :error => 1, + :kCLASS => 2, + :kMODULE => 3, + :kDEF => 4, + :kUNDEF => 5, + :kBEGIN => 6, + :kRESCUE => 7, + :kENSURE => 8, + :kEND => 9, + :kIF => 10, + :kUNLESS => 11, + :kTHEN => 12, + :kELSIF => 13, + :kELSE => 14, + :kCASE => 15, + :kWHEN => 16, + :kWHILE => 17, + :kUNTIL => 18, + :kFOR => 19, + :kBREAK => 20, + :kNEXT => 21, + :kREDO => 22, + :kRETRY => 23, + :kIN => 24, + :kDO => 25, + :kDO_COND => 26, + :kDO_BLOCK => 27, + :kDO_LAMBDA => 28, + :kRETURN => 29, + :kYIELD => 30, + :kSUPER => 31, + :kSELF => 32, + :kNIL => 33, + :kTRUE => 34, + :kFALSE => 35, + :kAND => 36, + :kOR => 37, + :kNOT => 38, + :kIF_MOD => 39, + :kUNLESS_MOD => 40, + :kWHILE_MOD => 41, + :kUNTIL_MOD => 42, + :kRESCUE_MOD => 43, + :kALIAS => 44, + :kDEFINED => 45, + :klBEGIN => 46, + :klEND => 47, + :k__LINE__ => 48, + :k__FILE__ => 49, + :k__ENCODING__ => 50, + :tIDENTIFIER => 51, + :tFID => 52, + :tGVAR => 53, + :tIVAR => 54, + :tCONSTANT => 55, + :tLABEL => 56, + :tCVAR => 57, + :tNTH_REF => 58, + :tBACK_REF => 59, + :tSTRING_CONTENT => 60, + :tINTEGER => 61, + :tFLOAT => 62, + :tUPLUS => 63, + :tUMINUS => 64, + :tUNARY_NUM => 65, + :tPOW => 66, + :tCMP => 67, + :tEQ => 68, + :tEQQ => 69, + :tNEQ => 70, + :tGEQ => 71, + :tLEQ => 72, + :tANDOP => 73, + :tOROP => 74, + :tMATCH => 75, + :tNMATCH => 76, + :tDOT => 77, + :tDOT2 => 78, + :tDOT3 => 79, + :tAREF => 80, + :tASET => 81, + :tLSHFT => 82, + :tRSHFT => 83, + :tCOLON2 => 84, + :tCOLON3 => 85, + :tOP_ASGN => 86, + :tASSOC => 87, + :tLPAREN => 88, + :tLPAREN2 => 89, + :tRPAREN => 90, + :tLPAREN_ARG => 91, + :tLBRACK => 92, + :tLBRACK2 => 93, + :tRBRACK => 94, + :tLBRACE => 95, + :tLBRACE_ARG => 96, + :tSTAR => 97, + :tSTAR2 => 98, + :tAMPER => 99, + :tAMPER2 => 100, + :tTILDE => 101, + :tPERCENT => 102, + :tDIVIDE => 103, + :tDSTAR => 104, + :tPLUS => 105, + :tMINUS => 106, + :tLT => 107, + :tGT => 108, + :tPIPE => 109, + :tBANG => 110, + :tCARET => 111, + :tLCURLY => 112, + :tRCURLY => 113, + :tBACK_REF2 => 114, + :tSYMBEG => 115, + :tSTRING_BEG => 116, + :tXSTRING_BEG => 117, + :tREGEXP_BEG => 118, + :tREGEXP_OPT => 119, + :tWORDS_BEG => 120, + :tQWORDS_BEG => 121, + :tSYMBOLS_BEG => 122, + :tQSYMBOLS_BEG => 123, + :tSTRING_DBEG => 124, + :tSTRING_DVAR => 125, + :tSTRING_END => 126, + :tSTRING_DEND => 127, + :tSTRING => 128, + :tSYMBOL => 129, + :tNL => 130, + :tEH => 131, + :tCOLON => 132, + :tCOMMA => 133, + :tSPACE => 134, + :tSEMI => 135, + :tLAMBDA => 136, + :tLAMBEG => 137, + :tCHARACTER => 138, + :tRATIONAL => 139, + :tIMAGINARY => 140, + :tLABEL_END => 141, + :tANDDOT => 142, + :tBDOT2 => 143, + :tBDOT3 => 144, + :tEQL => 145, + :tLOWEST => 146 } + +racc_nt_base = 147 + +racc_use_result_var = true + +Racc_arg = [ + racc_action_table, + racc_action_check, + racc_action_default, + racc_action_pointer, + racc_goto_table, + racc_goto_check, + racc_goto_default, + racc_goto_pointer, + racc_nt_base, + racc_reduce_table, + racc_token_table, + racc_shift_n, + racc_reduce_n, + racc_use_result_var ] +Ractor.make_shareable(Racc_arg) if defined?(Ractor) + +Racc_token_to_s_table = [ + "$end", + "error", + "kCLASS", + "kMODULE", + "kDEF", + "kUNDEF", + "kBEGIN", + "kRESCUE", + "kENSURE", + "kEND", + "kIF", + "kUNLESS", + "kTHEN", + "kELSIF", + "kELSE", + "kCASE", + "kWHEN", + "kWHILE", + "kUNTIL", + "kFOR", + "kBREAK", + "kNEXT", + "kREDO", + "kRETRY", + "kIN", + "kDO", + "kDO_COND", + "kDO_BLOCK", + "kDO_LAMBDA", + "kRETURN", + "kYIELD", + "kSUPER", + "kSELF", + "kNIL", + "kTRUE", + "kFALSE", + "kAND", + "kOR", + "kNOT", + "kIF_MOD", + "kUNLESS_MOD", + "kWHILE_MOD", + "kUNTIL_MOD", + "kRESCUE_MOD", + "kALIAS", + "kDEFINED", + "klBEGIN", + "klEND", + "k__LINE__", + "k__FILE__", + "k__ENCODING__", + "tIDENTIFIER", + "tFID", + "tGVAR", + "tIVAR", + "tCONSTANT", + "tLABEL", + "tCVAR", + "tNTH_REF", + "tBACK_REF", + "tSTRING_CONTENT", + "tINTEGER", + "tFLOAT", + "tUPLUS", + "tUMINUS", + "tUNARY_NUM", + "tPOW", + "tCMP", + "tEQ", + "tEQQ", + "tNEQ", + "tGEQ", + "tLEQ", + "tANDOP", + "tOROP", + "tMATCH", + "tNMATCH", + "tDOT", + "tDOT2", + "tDOT3", + "tAREF", + "tASET", + "tLSHFT", + "tRSHFT", + "tCOLON2", + "tCOLON3", + "tOP_ASGN", + "tASSOC", + "tLPAREN", + "tLPAREN2", + "tRPAREN", + "tLPAREN_ARG", + "tLBRACK", + "tLBRACK2", + "tRBRACK", + "tLBRACE", + "tLBRACE_ARG", + "tSTAR", + "tSTAR2", + "tAMPER", + "tAMPER2", + "tTILDE", + "tPERCENT", + "tDIVIDE", + "tDSTAR", + "tPLUS", + "tMINUS", + "tLT", + "tGT", + "tPIPE", + "tBANG", + "tCARET", + "tLCURLY", + "tRCURLY", + "tBACK_REF2", + "tSYMBEG", + "tSTRING_BEG", + "tXSTRING_BEG", + "tREGEXP_BEG", + "tREGEXP_OPT", + "tWORDS_BEG", + "tQWORDS_BEG", + "tSYMBOLS_BEG", + "tQSYMBOLS_BEG", + "tSTRING_DBEG", + "tSTRING_DVAR", + "tSTRING_END", + "tSTRING_DEND", + "tSTRING", + "tSYMBOL", + "tNL", + "tEH", + "tCOLON", + "tCOMMA", + "tSPACE", + "tSEMI", + "tLAMBDA", + "tLAMBEG", + "tCHARACTER", + "tRATIONAL", + "tIMAGINARY", + "tLABEL_END", + "tANDDOT", + "tBDOT2", + "tBDOT3", + "tEQL", + "tLOWEST", + "$start", + "program", + "top_compstmt", + "@1", + "top_stmts", + "opt_terms", + "top_stmt", + "terms", + "stmt", + "begin_block", + "bodystmt", + "compstmt", + "opt_rescue", + "opt_else", + "opt_ensure", + "stmts", + "stmt_or_begin", + "fitem", + "undef_list", + "expr_value", + "command_asgn", + "mlhs", + "command_call", + "lhs", + "mrhs", + "mrhs_arg", + "expr", + "@2", + "command_rhs", + "var_lhs", + "primary_value", + "opt_call_args", + "rbracket", + "call_op", + "defn_head", + "f_opt_paren_args", + "command", + "arg", + "defs_head", + "backref", + "opt_nl", + "p_top_expr_body", + "@3", + "@4", + "expr_value_do", + "do", + "def_name", + "@5", + "fname", + "k_def", + "singleton", + "dot_or_colon", + "@6", + "block_command", + "block_call", + "operation2", + "command_args", + "cmd_brace_block", + "brace_body", + "fcall", + "@7", + "operation", + "k_return", + "call_args", + "mlhs_basic", + "mlhs_inner", + "rparen", + "mlhs_head", + "mlhs_item", + "mlhs_node", + "mlhs_post", + "user_variable", + "keyword_variable", + "cname", + "cpath", + "op", + "reswords", + "symbol", + "@8", + "arg_rhs", + "simple_numeric", + "rel_expr", + "primary", + "relop", + "@9", + "arg_value", + "aref_args", + "none", + "args", + "trailer", + "assocs", + "paren_args", + "args_forward", + "opt_paren_args", + "opt_block_arg", + "block_arg", + "@10", + "literal", + "strings", + "xstring", + "regexp", + "words", + "qwords", + "symbols", + "qsymbols", + "var_ref", + "assoc_list", + "brace_block", + "method_call", + "lambda", + "then", + "if_tail", + "case_body", + "p_case_body", + "for_var", + "k_class", + "superclass", + "term", + "k_module", + "f_arglist", + "@11", + "@12", + "@13", + "@14", + "@15", + "@16", + "@17", + "f_marg", + "f_norm_arg", + "f_margs", + "f_marg_list", + "f_rest_marg", + "f_any_kwrest", + "f_kwrest", + "f_no_kwarg", + "f_eq", + "block_args_tail", + "@18", + "f_block_kwarg", + "opt_f_block_arg", + "f_block_arg", + "opt_block_args_tail", + "excessed_comma", + "block_param", + "f_arg", + "f_block_optarg", + "f_rest_arg", + "opt_block_param", + "block_param_def", + "opt_bv_decl", + "bv_decls", + "bvar", + "f_bad_arg", + "f_larglist", + "lambda_body", + "@19", + "@20", + "f_args", + "do_block", + "@21", + "@22", + "do_body", + "@23", + "operation3", + "@24", + "@25", + "@26", + "@27", + "@28", + "cases", + "p_top_expr", + "p_cases", + "@29", + "@30", + "p_expr", + "p_args", + "p_find", + "p_args_tail", + "p_kwargs", + "p_as", + "p_variable", + "p_alt", + "p_expr_basic", + "p_lparen", + "p_lbracket", + "p_value", + "p_const", + "rbrace", + "@31", + "@32", + "p_args_head", + "p_arg", + "p_args_post", + "p_rest", + "p_kwarg", + "p_any_kwrest", + "p_kw", + "p_kw_label", + "string_contents", + "p_kwrest", + "kwrest_mark", + "p_kwnorest", + "p_primitive", + "p_var_ref", + "p_expr_ref", + "nonlocal_var", + "exc_list", + "exc_var", + "numeric", + "string", + "string1", + "xstring_contents", + "regexp_contents", + "word_list", + "word", + "string_content", + "symbol_list", + "qword_list", + "qsym_list", + "string_dvar", + "@33", + "ssym", + "dsym", + "@34", + "f_paren_args", + "args_tail", + "@35", + "f_kwarg", + "opt_args_tail", + "f_optarg", + "f_arg_asgn", + "f_arg_item", + "f_label", + "f_kw", + "f_block_kw", + "f_opt", + "f_block_opt", + "restarg_mark", + "blkarg_mark", + "assoc" ] +Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) + +Racc_debug_parser = false + +##### State transition tables end ##### + +# reduce 0 omitted + +def _reduce_1(val, _values, result) + @current_arg_stack.push(nil) + @max_numparam_stack.push(static: true) + + result +end + +def _reduce_2(val, _values, result) + result = val[1] + + @current_arg_stack.pop + @max_numparam_stack.pop + + result +end + +def _reduce_3(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_4(val, _values, result) + result = [] + + result +end + +def _reduce_5(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_6(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_7(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 8 omitted + +def _reduce_9(val, _values, result) + result = @builder.preexe(val[0], *val[1]) + + result +end + +def _reduce_10(val, _values, result) + result = val + + result +end + +def _reduce_11(val, _values, result) + rescue_bodies = val[1] + else_t, else_ = val[2] + ensure_t, ensure_ = val[3] + + if rescue_bodies.empty? && !else_t.nil? + diagnostic :error, :useless_else, nil, else_t + end + + result = @builder.begin_body(val[0], + rescue_bodies, + else_t, else_, + ensure_t, ensure_) + + result +end + +def _reduce_12(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_13(val, _values, result) + result = [] + + result +end + +def _reduce_14(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_15(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_16(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 17 omitted + +def _reduce_18(val, _values, result) + diagnostic :error, :begin_in_method, nil, val[0] + + result +end + +def _reduce_19(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_20(val, _values, result) + result = @builder.alias(val[0], val[1], val[3]) + + result +end + +def _reduce_21(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.gvar(val[2])) + + result +end + +def _reduce_22(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.back_ref(val[2])) + + result +end + +def _reduce_23(val, _values, result) + diagnostic :error, :nth_ref_alias, nil, val[2] + + result +end + +def _reduce_24(val, _values, result) + result = @builder.undef_method(val[0], val[1]) + + result +end + +def _reduce_25(val, _values, result) + result = @builder.condition_mod(val[0], nil, + val[1], val[2]) + + result +end + +def _reduce_26(val, _values, result) + result = @builder.condition_mod(nil, val[0], + val[1], val[2]) + + result +end + +def _reduce_27(val, _values, result) + result = @builder.loop_mod(:while, val[0], val[1], val[2]) + + result +end + +def _reduce_28(val, _values, result) + result = @builder.loop_mod(:until, val[0], val[1], val[2]) + + result +end + +def _reduce_29(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_30(val, _values, result) + result = @builder.postexe(val[0], val[1], val[2], val[3]) + + result +end + +# reduce 31 omitted + +def _reduce_32(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_33(val, _values, result) + result = @builder.assign(val[0], val[1], + @builder.array(nil, val[2], nil)) + + result +end + +def _reduce_34(val, _values, result) + rescue_body = @builder.rescue_body(val[3], + nil, nil, nil, + nil, val[4]) + begin_body = @builder.begin_body(val[2], [ rescue_body ]) + + result = @builder.multi_assign(val[0], val[1], begin_body) + + result +end + +def _reduce_35(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +# reduce 36 omitted + +def _reduce_37(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_38(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_39(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_40(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_41(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_42(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_43(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_44(val, _values, result) + def_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + result = @builder.def_endless_method(def_t, name_t, + val[1], val[2], val[3]) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_45(val, _values, result) + def_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + rescue_body = @builder.rescue_body(val[4], + nil, nil, nil, + nil, val[5]) + + method_body = @builder.begin_body(val[3], [ rescue_body ]) + + result = @builder.def_endless_method(def_t, name_t, + val[1], val[2], method_body) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_46(val, _values, result) + def_t, recv, dot_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + result = @builder.def_endless_singleton(def_t, recv, dot_t, name_t, + val[1], val[2], val[3]) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_47(val, _values, result) + def_t, recv, dot_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + rescue_body = @builder.rescue_body(val[4], + nil, nil, nil, + nil, val[5]) + + method_body = @builder.begin_body(val[3], [ rescue_body ]) + + result = @builder.def_endless_singleton(def_t, recv, dot_t, name_t, + val[1], val[2], method_body) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_48(val, _values, result) + @builder.op_assign(val[0], val[1], val[2]) + + result +end + +# reduce 49 omitted + +def _reduce_50(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +# reduce 51 omitted + +# reduce 52 omitted + +def _reduce_53(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_54(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_55(val, _values, result) + result = @builder.not_op(val[0], nil, val[2], nil) + + result +end + +def _reduce_56(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +def _reduce_57(val, _values, result) + @lexer.state = :expr_beg + @lexer.command_start = false + @pattern_variables.push + @pattern_hash_keys.push + + result = @context.in_kwarg + @context.in_kwarg = true + + result +end + +def _reduce_58(val, _values, result) + @pattern_variables.pop + @pattern_hash_keys.pop + @context.in_kwarg = val[2] + result = @builder.match_pattern(val[0], val[1], val[3]) + + result +end + +def _reduce_59(val, _values, result) + @lexer.state = :expr_beg + @lexer.command_start = false + @pattern_variables.push + @pattern_hash_keys.push + + result = @context.in_kwarg + @context.in_kwarg = true + + result +end + +def _reduce_60(val, _values, result) + @pattern_variables.pop + @pattern_hash_keys.pop + @context.in_kwarg = val[2] + result = @builder.match_pattern_p(val[0], val[1], val[3]) + + result +end + +# reduce 61 omitted + +# reduce 62 omitted + +def _reduce_63(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_64(val, _values, result) + @lexer.cond.pop + result = [ val[1], val[2] ] + + result +end + +def _reduce_65(val, _values, result) + local_push + @current_arg_stack.push(nil) + + result = [ val[0], @context.dup ] + @context.in_def = true + + result +end + +def _reduce_66(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +def _reduce_67(val, _values, result) + @lexer.state = :expr_fname + @context.in_argdef = true + + result +end + +def _reduce_68(val, _values, result) + result = [ val[0], val[1], val[2], val[4] ] + + result +end + +# reduce 69 omitted + +# reduce 70 omitted + +# reduce 71 omitted + +def _reduce_72(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_73(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_74(val, _values, result) + @context.in_block = val[1].in_block + result = [ val[0], *val[2], val[3] ] + + result +end + +# reduce 75 omitted + +def _reduce_76(val, _values, result) + result = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + result +end + +def _reduce_77(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + begin_t, args, body, end_t = val[2] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_78(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_79(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_80(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_81(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_82(val, _values, result) + result = @builder.keyword_cmd(:super, val[0], + nil, val[1], nil) + + result +end + +def _reduce_83(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], + nil, val[1], nil) + + result +end + +def _reduce_84(val, _values, result) + result = @builder.keyword_cmd(:return, val[0], + nil, val[1], nil) + + result +end + +def _reduce_85(val, _values, result) + result = @builder.keyword_cmd(:break, val[0], + nil, val[1], nil) + + result +end + +def _reduce_86(val, _values, result) + result = @builder.keyword_cmd(:next, val[0], + nil, val[1], nil) + + result +end + +def _reduce_87(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_88(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_89(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_90(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +# reduce 91 omitted + +def _reduce_92(val, _values, result) + result = val[0]. + push(val[1]) + + result +end + +def _reduce_93(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])) + + result +end + +def _reduce_94(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])). + concat(val[4]) + + result +end + +def _reduce_95(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])) + + result +end + +def _reduce_96(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])). + concat(val[3]) + + result +end + +def _reduce_97(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_98(val, _values, result) + result = [ @builder.splat(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_99(val, _values, result) + result = [ @builder.splat(val[0]) ] + + result +end + +def _reduce_100(val, _values, result) + result = [ @builder.splat(val[0]), + *val[2] ] + + result +end + +# reduce 101 omitted + +def _reduce_102(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_103(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_104(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_105(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_106(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_107(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_108(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_109(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_110(val, _values, result) + if (val[1][0] == :anddot) + diagnostic :error, :csend_in_lhs_of_masgn, nil, val[1] + end + + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_111(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_112(val, _values, result) + if (val[1][0] == :anddot) + diagnostic :error, :csend_in_lhs_of_masgn, nil, val[1] + end + + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_113(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_114(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_115(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_116(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_117(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_118(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_119(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_120(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_121(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_122(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_123(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_124(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_125(val, _values, result) + diagnostic :error, :module_name_const, nil, val[0] + + result +end + +# reduce 126 omitted + +def _reduce_127(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_128(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_129(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +# reduce 130 omitted + +# reduce 131 omitted + +# reduce 132 omitted + +# reduce 133 omitted + +# reduce 134 omitted + +def _reduce_135(val, _values, result) + result = @builder.symbol_internal(val[0]) + + result +end + +# reduce 136 omitted + +def _reduce_137(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_138(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_139(val, _values, result) + result = val[0] << val[3] + + result +end + +# reduce 140 omitted + +# reduce 141 omitted + +# reduce 142 omitted + +# reduce 143 omitted + +# reduce 144 omitted + +# reduce 145 omitted + +# reduce 146 omitted + +# reduce 147 omitted + +# reduce 148 omitted + +# reduce 149 omitted + +# reduce 150 omitted + +# reduce 151 omitted + +# reduce 152 omitted + +# reduce 153 omitted + +# reduce 154 omitted + +# reduce 155 omitted + +# reduce 156 omitted + +# reduce 157 omitted + +# reduce 158 omitted + +# reduce 159 omitted + +# reduce 160 omitted + +# reduce 161 omitted + +# reduce 162 omitted + +# reduce 163 omitted + +# reduce 164 omitted + +# reduce 165 omitted + +# reduce 166 omitted + +# reduce 167 omitted + +# reduce 168 omitted + +# reduce 169 omitted + +# reduce 170 omitted + +# reduce 171 omitted + +# reduce 172 omitted + +# reduce 173 omitted + +# reduce 174 omitted + +# reduce 175 omitted + +# reduce 176 omitted + +# reduce 177 omitted + +# reduce 178 omitted + +# reduce 179 omitted + +# reduce 180 omitted + +# reduce 181 omitted + +# reduce 182 omitted + +# reduce 183 omitted + +# reduce 184 omitted + +# reduce 185 omitted + +# reduce 186 omitted + +# reduce 187 omitted + +# reduce 188 omitted + +# reduce 189 omitted + +# reduce 190 omitted + +# reduce 191 omitted + +# reduce 192 omitted + +# reduce 193 omitted + +# reduce 194 omitted + +# reduce 195 omitted + +# reduce 196 omitted + +# reduce 197 omitted + +# reduce 198 omitted + +# reduce 199 omitted + +# reduce 200 omitted + +# reduce 201 omitted + +# reduce 202 omitted + +# reduce 203 omitted + +# reduce 204 omitted + +# reduce 205 omitted + +# reduce 206 omitted + +# reduce 207 omitted + +# reduce 208 omitted + +# reduce 209 omitted + +# reduce 210 omitted + +def _reduce_211(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_212(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_213(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_214(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_215(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_216(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_217(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_218(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_global(val[0], val[1])) + result = @builder.op_assign(const, val[2], val[3]) + + result +end + +def _reduce_219(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_220(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_221(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_222(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], nil) + + result +end + +def _reduce_223(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], nil) + + result +end + +def _reduce_224(val, _values, result) + result = @builder.range_inclusive(nil, val[0], val[1]) + + result +end + +def _reduce_225(val, _values, result) + result = @builder.range_exclusive(nil, val[0], val[1]) + + result +end + +def _reduce_226(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_227(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_228(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_229(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_230(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_231(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_232(val, _values, result) + result = @builder.unary_op(val[0], + @builder.binary_op( + val[1], val[2], val[3])) + + result +end + +def _reduce_233(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_234(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_235(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_236(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_237(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_238(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +# reduce 239 omitted + +def _reduce_240(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_241(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_242(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_243(val, _values, result) + result = @builder.match_op(val[0], val[1], val[2]) + + result +end + +def _reduce_244(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_245(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +def _reduce_246(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_247(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_248(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_249(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_250(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_251(val, _values, result) + @context.in_defined = true + + result +end + +def _reduce_252(val, _values, result) + @context.in_defined = false + result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[3] ], nil) + + result +end + +def _reduce_253(val, _values, result) + result = @builder.ternary(val[0], val[1], + val[2], val[4], val[5]) + + result +end + +def _reduce_254(val, _values, result) + def_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + result = @builder.def_endless_method(def_t, name_t, + val[1], val[2], val[3]) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_255(val, _values, result) + def_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + rescue_body = @builder.rescue_body(val[4], + nil, nil, nil, + nil, val[5]) + + method_body = @builder.begin_body(val[3], [ rescue_body ]) + + result = @builder.def_endless_method(def_t, name_t, + val[1], val[2], method_body) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_256(val, _values, result) + def_t, recv, dot_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + result = @builder.def_endless_singleton(def_t, recv, dot_t, name_t, + val[1], val[2], val[3]) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_257(val, _values, result) + def_t, recv, dot_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + rescue_body = @builder.rescue_body(val[4], + nil, nil, nil, + nil, val[5]) + + method_body = @builder.begin_body(val[3], [ rescue_body ]) + + result = @builder.def_endless_singleton(def_t, recv, dot_t, name_t, + val[1], val[2], method_body) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +# reduce 258 omitted + +# reduce 259 omitted + +# reduce 260 omitted + +# reduce 261 omitted + +# reduce 262 omitted + +def _reduce_263(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_264(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +# reduce 265 omitted + +# reduce 266 omitted + +# reduce 267 omitted + +def _reduce_268(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_269(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +# reduce 270 omitted + +def _reduce_271(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_272(val, _values, result) + result = val + + result +end + +def _reduce_273(val, _values, result) + unless @static_env.declared_forward_args? + diagnostic :error, :unexpected_token, { :token => 'tBDOT3' } , val[3] + end + + result = [val[0], [*val[1], @builder.forwarded_args(val[3])], val[4]] + + result +end + +def _reduce_274(val, _values, result) + unless @static_env.declared_forward_args? + diagnostic :error, :unexpected_token, { :token => 'tBDOT3' } , val[1] + end + + result = [val[0], [@builder.forwarded_args(val[1])], val[2]] + + result +end + +def _reduce_275(val, _values, result) + result = [ nil, [], nil ] + + result +end + +# reduce 276 omitted + +def _reduce_277(val, _values, result) + result = [] + + result +end + +# reduce 278 omitted + +# reduce 279 omitted + +def _reduce_280(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_281(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +def _reduce_282(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_283(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_284(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + result.concat(val[1]) + + result +end + +def _reduce_285(val, _values, result) + assocs = @builder.associate(nil, val[2], nil) + result = val[0] << assocs + result.concat(val[3]) + + result +end + +def _reduce_286(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_287(val, _values, result) + # When branch gets invoked by RACC's lookahead + # and command args start with '[' or '(' + # we need to put `true` to the cmdarg stack + # **before** `false` pushed by lexer + # m [], n + # ^ + # Right here we have cmdarg [...0] because + # lexer pushed it on '[' + # We need to modify cmdarg stack to [...10] + # + # For all other cases (like `m n` or `m n, []`) we simply put 1 to the stack + # and later lexer pushes corresponding bits on top of it. + last_token = @last_token[0] + lookahead = last_token == :tLBRACK || last_token == :tLPAREN_ARG + + if lookahead + top = @lexer.cmdarg.pop + @lexer.cmdarg.push(true) + @lexer.cmdarg.push(top) + else + @lexer.cmdarg.push(true) + end + + result +end + +def _reduce_288(val, _values, result) + # call_args can be followed by tLBRACE_ARG (that does cmdarg.push(0) in the lexer) + # but the push must be done after cmdarg.pop() in the parser. + # So this code does cmdarg.pop() to pop 0 pushed by tLBRACE_ARG, + # cmdarg.pop() to pop 1 pushed by command_args, + # and cmdarg.push(0) to restore back the flag set by tLBRACE_ARG. + last_token = @last_token[0] + lookahead = last_token == :tLBRACE_ARG + if lookahead + top = @lexer.cmdarg.pop + @lexer.cmdarg.pop + @lexer.cmdarg.push(top) + else + @lexer.cmdarg.pop + end + + result = val[1] + + result +end + +def _reduce_289(val, _values, result) + result = @builder.block_pass(val[0], val[1]) + + result +end + +def _reduce_290(val, _values, result) + if !@static_env.declared_anonymous_blockarg? + diagnostic :error, :no_anonymous_blockarg, nil, val[0] + end + + result = @builder.block_pass(val[0], nil) + + result +end + +def _reduce_291(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_292(val, _values, result) + result = [] + + result +end + +def _reduce_293(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_294(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_295(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_296(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_297(val, _values, result) + result = @builder.array(nil, val[0], nil) + + result +end + +# reduce 298 omitted + +def _reduce_299(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_300(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_301(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +# reduce 302 omitted + +# reduce 303 omitted + +# reduce 304 omitted + +# reduce 305 omitted + +# reduce 306 omitted + +# reduce 307 omitted + +# reduce 308 omitted + +# reduce 309 omitted + +# reduce 310 omitted + +# reduce 311 omitted + +def _reduce_312(val, _values, result) + result = @builder.call_method(nil, nil, val[0]) + + result +end + +def _reduce_313(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_314(val, _values, result) + @lexer.cmdarg.pop + + result = @builder.begin_keyword(val[0], val[2], val[3]) + + result +end + +def _reduce_315(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_316(val, _values, result) + result = @builder.begin(val[0], val[1], val[3]) + + result +end + +def _reduce_317(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_318(val, _values, result) + result = @builder.begin(val[0], nil, val[3]) + + result +end + +def _reduce_319(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_320(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +def _reduce_321(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_322(val, _values, result) + result = @builder.array(val[0], val[1], val[2]) + + result +end + +def _reduce_323(val, _values, result) + result = @builder.associate(val[0], val[1], val[2]) + + result +end + +def _reduce_324(val, _values, result) + result = @builder.keyword_cmd(:return, val[0]) + + result +end + +def _reduce_325(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_326(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2]) + + result +end + +def _reduce_327(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0]) + + result +end + +def _reduce_328(val, _values, result) + @context.in_defined = true + + result +end + +def _reduce_329(val, _values, result) + @context.in_defined = false + result = @builder.keyword_cmd(:defined?, val[0], + val[2], [ val[4] ], val[5]) + + result +end + +def _reduce_330(val, _values, result) + result = @builder.not_op(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_331(val, _values, result) + result = @builder.not_op(val[0], val[1], nil, val[2]) + + result +end + +def _reduce_332(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0]) + + begin_t, args, body, end_t = val[1] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +# reduce 333 omitted + +def _reduce_334(val, _values, result) + begin_t, args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, args, body, end_t) + + result +end + +# reduce 335 omitted + +def _reduce_336(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, val[5]) + + result +end + +def _reduce_337(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + else_, else_t, + val[3], val[5]) + + result +end + +def _reduce_338(val, _values, result) + result = @builder.loop(:while, val[0], *val[1], val[2], val[3]) + + result +end + +def _reduce_339(val, _values, result) + result = @builder.loop(:until, val[0], *val[1], val[2], val[3]) + + result +end + +def _reduce_340(val, _values, result) + *when_bodies, (else_t, else_body) = *val[3] + + result = @builder.case(val[0], val[1], + when_bodies, else_t, else_body, + val[4]) + + result +end + +def _reduce_341(val, _values, result) + *when_bodies, (else_t, else_body) = *val[2] + + result = @builder.case(val[0], nil, + when_bodies, else_t, else_body, + val[3]) + + result +end + +def _reduce_342(val, _values, result) + *in_bodies, (else_t, else_body) = *val[3] + + result = @builder.case_match(val[0], val[1], + in_bodies, else_t, else_body, + val[4]) + + result +end + +def _reduce_343(val, _values, result) + result = @builder.for(val[0], val[1], val[2], *val[3], val[4], val[5]) + + result +end + +def _reduce_344(val, _values, result) + @context.in_class = true + local_push + + result +end + +def _reduce_345(val, _values, result) + k_class, ctx = val[0] + if @context.in_def + diagnostic :error, :class_in_def, nil, k_class + end + lt_t, superclass = val[2] + result = @builder.def_class(k_class, val[1], + lt_t, superclass, + val[4], val[5]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_346(val, _values, result) + @context.in_def = false + @context.in_class = false + local_push + + result +end + +def _reduce_347(val, _values, result) + k_class, ctx = val[0] + result = @builder.def_sclass(k_class, val[1], val[2], + val[5], val[6]) + + local_pop + @context.in_def = ctx.in_def + @context.in_class = ctx.in_class + + result +end + +def _reduce_348(val, _values, result) + @context.in_class = true + local_push + + result +end + +def _reduce_349(val, _values, result) + k_mod, ctx = val[0] + if @context.in_def + diagnostic :error, :module_in_def, nil, k_mod + end + result = @builder.def_module(k_mod, val[1], + val[3], val[4]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_350(val, _values, result) + def_t, (name_t, ctx) = val[0] + result = @builder.def_method(def_t, name_t, val[1], + val[2], val[3]) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_351(val, _values, result) + def_t, recv, dot_t, (name_t, ctx) = val[0] + result = @builder.def_singleton(def_t, recv, dot_t, name_t, val[1], + val[2], val[3]) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_352(val, _values, result) + result = @builder.keyword_cmd(:break, val[0]) + + result +end + +def _reduce_353(val, _values, result) + result = @builder.keyword_cmd(:next, val[0]) + + result +end + +def _reduce_354(val, _values, result) + result = @builder.keyword_cmd(:redo, val[0]) + + result +end + +def _reduce_355(val, _values, result) + result = @builder.keyword_cmd(:retry, val[0]) + + result +end + +# reduce 356 omitted + +def _reduce_357(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_358(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_359(val, _values, result) + result = val[0] + @context.in_argdef = true + + result +end + +def _reduce_360(val, _values, result) + if @context.in_class && !@context.in_def && !(context.in_block || context.in_lambda) + diagnostic :error, :invalid_return, nil, val[0] + end + + result +end + +# reduce 361 omitted + +# reduce 362 omitted + +def _reduce_363(val, _values, result) + result = val[1] + + result +end + +# reduce 364 omitted + +# reduce 365 omitted + +# reduce 366 omitted + +def _reduce_367(val, _values, result) + else_t, else_ = val[4] + result = [ val[0], + @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, nil), + ] + + result +end + +# reduce 368 omitted + +def _reduce_369(val, _values, result) + result = val + + result +end + +# reduce 370 omitted + +# reduce 371 omitted + +def _reduce_372(val, _values, result) + result = @builder.arg(val[0]) + + result +end + +def _reduce_373(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_374(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_375(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 376 omitted + +def _reduce_377(val, _values, result) + result = val[0]. + push(val[2]) + + result +end + +def _reduce_378(val, _values, result) + result = val[0]. + push(val[2]). + concat(val[4]) + + result +end + +def _reduce_379(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_380(val, _values, result) + result = [ val[0], *val[2] ] + + result +end + +def _reduce_381(val, _values, result) + result = @builder.restarg(val[0], val[1]) + + result +end + +def _reduce_382(val, _values, result) + result = @builder.restarg(val[0]) + + result +end + +# reduce 383 omitted + +# reduce 384 omitted + +def _reduce_385(val, _values, result) + @context.in_argdef = false + + result +end + +def _reduce_386(val, _values, result) + result = val[1] + + result +end + +def _reduce_387(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_388(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_389(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_390(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_391(val, _values, result) + result = val[1] + + result +end + +def _reduce_392(val, _values, result) + result = [] + + result +end + +# reduce 393 omitted + +def _reduce_394(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_395(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_396(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_397(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_398(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 399 omitted + +def _reduce_400(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_401(val, _values, result) + if val[1].empty? && val[0].size == 1 + result = [@builder.procarg0(val[0][0])] + else + result = val[0].concat(val[1]) + end + + result +end + +def _reduce_402(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_403(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_404(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_405(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_406(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_407(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 408 omitted + +def _reduce_409(val, _values, result) + result = @builder.args(nil, [], nil) + + result +end + +def _reduce_410(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_411(val, _values, result) + @max_numparam_stack.has_ordinary_params! + @current_arg_stack.set(nil) + @context.in_argdef = false + result = @builder.args(val[0], val[1], val[2]) + + result +end + +def _reduce_412(val, _values, result) + @max_numparam_stack.has_ordinary_params! + @current_arg_stack.set(nil) + @context.in_argdef = false + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_413(val, _values, result) + result = [] + + result +end + +def _reduce_414(val, _values, result) + result = val[2] + + result +end + +def _reduce_415(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_416(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_417(val, _values, result) + @static_env.declare val[0][0] + result = @builder.shadowarg(val[0]) + + result +end + +# reduce 418 omitted + +def _reduce_419(val, _values, result) + @static_env.extend_dynamic + @max_numparam_stack.push(static: false) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_420(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_421(val, _values, result) + lambda_call = @builder.call_lambda(val[0]) + args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[2] + begin_t, body, end_t = val[4] + + @max_numparam_stack.pop + @static_env.unextend + @lexer.cmdarg.pop + @context.in_lambda = val[1].in_lambda + + result = @builder.block(lambda_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_422(val, _values, result) + @context.in_argdef = false + @max_numparam_stack.has_ordinary_params! + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_423(val, _values, result) + @context.in_argdef = false + if val[0].any? + @max_numparam_stack.has_ordinary_params! + end + result = @builder.args(nil, val[0], nil) + + result +end + +def _reduce_424(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_425(val, _values, result) + @context.in_lambda = val[1].in_lambda + result = [ val[0], val[2], val[3] ] + + result +end + +def _reduce_426(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_427(val, _values, result) + @context.in_lambda = val[1].in_lambda + result = [ val[0], val[2], val[3] ] + + result +end + +def _reduce_428(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_429(val, _values, result) + @context.in_block = val[1].in_block + result = [ val[0], *val[2], val[3] ] + + result +end + +def _reduce_430(val, _values, result) + begin_t, block_args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, block_args, body, end_t) + + result +end + +def _reduce_431(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_432(val, _values, result) + lparen_t, args, rparen_t = val[3] + method_call = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_433(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_434(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.call_method(nil, nil, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_435(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_436(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_437(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2]) + + result +end + +def _reduce_438(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_439(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_440(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.keyword_cmd(:super, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_441(val, _values, result) + result = @builder.keyword_cmd(:zsuper, val[0]) + + result +end + +def _reduce_442(val, _values, result) + result = @builder.index(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_443(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_444(val, _values, result) + @context.in_block = val[1].in_block + result = [ val[0], *val[2], val[3] ] + + result +end + +def _reduce_445(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_446(val, _values, result) + @context.in_block = val[1].in_block + result = [ val[0], *val[2], val[3] ] + + result +end + +def _reduce_447(val, _values, result) + @static_env.extend_dynamic + @max_numparam_stack.push(static: false) + + result +end + +def _reduce_448(val, _values, result) + args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[1] + result = [ args, val[2] ] + + @max_numparam_stack.pop + @static_env.unextend + + result +end + +def _reduce_449(val, _values, result) + @static_env.extend_dynamic + @max_numparam_stack.push(static: false) + + result +end + +def _reduce_450(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_451(val, _values, result) + args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[2] + result = [ args, val[3] ] + + @max_numparam_stack.pop + @static_env.unextend + @lexer.cmdarg.pop + + result +end + +def _reduce_452(val, _values, result) + result = [ @builder.when(val[0], val[1], val[2], val[3]), + *val[4] ] + + result +end + +def _reduce_453(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 454 omitted + +def _reduce_455(val, _values, result) + @lexer.state = :expr_beg + @lexer.command_start = false + @pattern_variables.push + @pattern_hash_keys.push + + result = @context.in_kwarg + @context.in_kwarg = true + + result +end + +def _reduce_456(val, _values, result) + @pattern_variables.pop + @pattern_hash_keys.pop + @context.in_kwarg = val[1] + + result +end + +def _reduce_457(val, _values, result) + result = [ @builder.in_pattern(val[0], *val[2], val[3], val[5]), + *val[6] ] + + result +end + +def _reduce_458(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 459 omitted + +def _reduce_460(val, _values, result) + result = [ val[0], nil ] + + result +end + +def _reduce_461(val, _values, result) + result = [ val[0], @builder.if_guard(val[1], val[2]) ] + + result +end + +def _reduce_462(val, _values, result) + result = [ val[0], @builder.unless_guard(val[1], val[2]) ] + + result +end + +# reduce 463 omitted + +def _reduce_464(val, _values, result) + # array patterns that end with comma + # like 1, 2, + # must be emitted as `array_pattern_with_tail` + item = @builder.match_with_trailing_comma(val[0], val[1]) + result = @builder.array_pattern(nil, [ item ], nil) + + result +end + +def _reduce_465(val, _values, result) + result = @builder.array_pattern(nil, [val[0]].concat(val[2]), nil) + + result +end + +def _reduce_466(val, _values, result) + result = @builder.find_pattern(nil, val[0], nil) + + result +end + +def _reduce_467(val, _values, result) + result = @builder.array_pattern(nil, val[0], nil) + + result +end + +def _reduce_468(val, _values, result) + result = @builder.hash_pattern(nil, val[0], nil) + + result +end + +# reduce 469 omitted + +def _reduce_470(val, _values, result) + result = @builder.match_as(val[0], val[1], val[2]) + + result +end + +# reduce 471 omitted + +def _reduce_472(val, _values, result) + result = @builder.match_alt(val[0], val[1], val[2]) + + result +end + +# reduce 473 omitted + +def _reduce_474(val, _values, result) + result = val[0] + @pattern_hash_keys.push + + result +end + +def _reduce_475(val, _values, result) + result = val[0] + @pattern_hash_keys.push + + result +end + +# reduce 476 omitted + +# reduce 477 omitted + +def _reduce_478(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.array_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_479(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.find_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_480(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.hash_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_481(val, _values, result) + pattern = @builder.array_pattern(val[1], nil, val[2]) + result = @builder.const_pattern(val[0], val[1], pattern, val[2]) + + result +end + +def _reduce_482(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.array_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_483(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.find_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_484(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.hash_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_485(val, _values, result) + pattern = @builder.array_pattern(val[1], nil, val[2]) + result = @builder.const_pattern(val[0], val[1], pattern, val[2]) + + result +end + +def _reduce_486(val, _values, result) + result = @builder.array_pattern(val[0], val[1], val[2]) + + result +end + +def _reduce_487(val, _values, result) + result = @builder.find_pattern(val[0], val[1], val[2]) + + result +end + +def _reduce_488(val, _values, result) + result = @builder.array_pattern(val[0], [], val[1]) + + result +end + +def _reduce_489(val, _values, result) + @pattern_hash_keys.push + result = @context.in_kwarg + @context.in_kwarg = false + + result +end + +def _reduce_490(val, _values, result) + @pattern_hash_keys.pop + @context.in_kwarg = val[1] + result = @builder.hash_pattern(val[0], val[2], val[3]) + + result +end + +def _reduce_491(val, _values, result) + result = @builder.hash_pattern(val[0], [], val[1]) + + result +end + +def _reduce_492(val, _values, result) + @pattern_hash_keys.push + + result +end + +def _reduce_493(val, _values, result) + @pattern_hash_keys.pop + result = @builder.begin(val[0], val[2], val[3]) + + result +end + +def _reduce_494(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_495(val, _values, result) + result = val[0] + + result +end + +def _reduce_496(val, _values, result) + result = [ *val[0], val[1] ] + + result +end + +def _reduce_497(val, _values, result) + match_rest = @builder.match_rest(val[1], val[2]) + result = [ *val[0], match_rest ] + + result +end + +def _reduce_498(val, _values, result) + match_rest = @builder.match_rest(val[1], val[2]) + result = [ *val[0], match_rest, *val[4] ] + + result +end + +def _reduce_499(val, _values, result) + result = [ *val[0], @builder.match_rest(val[1]) ] + + result +end + +def _reduce_500(val, _values, result) + result = [ *val[0], @builder.match_rest(val[1]), *val[3] ] + + result +end + +# reduce 501 omitted + +def _reduce_502(val, _values, result) + # array patterns that end with comma + # like [1, 2,] + # must be emitted as `array_pattern_with_tail` + item = @builder.match_with_trailing_comma(val[0], val[1]) + result = [ item ] + + result +end + +def _reduce_503(val, _values, result) + # array patterns that end with comma + # like [1, 2,] + # must be emitted as `array_pattern_with_tail` + last_item = @builder.match_with_trailing_comma(val[1], val[2]) + result = [ *val[0], last_item ] + + result +end + +def _reduce_504(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_505(val, _values, result) + result = [ val[0], *val[2] ] + + result +end + +def _reduce_506(val, _values, result) + result = [ val[0], *val[2], val[4] ] + + result +end + +def _reduce_507(val, _values, result) + result = @builder.match_rest(val[0], val[1]) + + result +end + +def _reduce_508(val, _values, result) + result = @builder.match_rest(val[0]) + + result +end + +def _reduce_509(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_510(val, _values, result) + result = [ *val[0], val[2] ] + + result +end + +# reduce 511 omitted + +def _reduce_512(val, _values, result) + result = [ *val[0], *val[2] ] + + result +end + +def _reduce_513(val, _values, result) + result = val[0] + + result +end + +def _reduce_514(val, _values, result) + result = val[0] + + result +end + +def _reduce_515(val, _values, result) + result = val[0] + + result +end + +def _reduce_516(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_517(val, _values, result) + result = [ *val[0], val[2] ] + + result +end + +def _reduce_518(val, _values, result) + result = @builder.match_pair(*val[0], val[1]) + + result +end + +def _reduce_519(val, _values, result) + result = @builder.match_label(*val[0]) + + result +end + +def _reduce_520(val, _values, result) + result = [:label, val[0]] + + result +end + +def _reduce_521(val, _values, result) + result = [:quoted, [val[0], val[1], val[2]]] + + result +end + +def _reduce_522(val, _values, result) + result = [ @builder.match_rest(val[0], val[1]) ] + + result +end + +def _reduce_523(val, _values, result) + result = [ @builder.match_rest(val[0], nil) ] + + result +end + +def _reduce_524(val, _values, result) + result = [ @builder.match_nil_pattern(val[0], val[1]) ] + + result +end + +# reduce 525 omitted + +# reduce 526 omitted + +# reduce 527 omitted + +def _reduce_528(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_529(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_530(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], nil) + + result +end + +def _reduce_531(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], nil) + + result +end + +# reduce 532 omitted + +# reduce 533 omitted + +# reduce 534 omitted + +def _reduce_535(val, _values, result) + result = @builder.range_inclusive(nil, val[0], val[1]) + + result +end + +def _reduce_536(val, _values, result) + result = @builder.range_exclusive(nil, val[0], val[1]) + + result +end + +# reduce 537 omitted + +# reduce 538 omitted + +# reduce 539 omitted + +# reduce 540 omitted + +# reduce 541 omitted + +# reduce 542 omitted + +# reduce 543 omitted + +# reduce 544 omitted + +def _reduce_545(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +# reduce 546 omitted + +def _reduce_547(val, _values, result) + result = @builder.assignable(@builder.match_var(val[0])) + + result +end + +def _reduce_548(val, _values, result) + name = val[1][0] + lvar = @builder.accessible(@builder.ident(val[1])) + + unless static_env.declared?(name) + diagnostic :error, :undefined_lvar, { :name => name }, val[1] + end + + result = @builder.pin(val[0], lvar) + + result +end + +def _reduce_549(val, _values, result) + non_lvar = @builder.accessible(val[1]) + result = @builder.pin(val[0], non_lvar) + + result +end + +def _reduce_550(val, _values, result) + expr = @builder.begin(val[1], val[2], val[3]) + result = @builder.pin(val[0], expr) + + result +end + +def _reduce_551(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_552(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +def _reduce_553(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_554(val, _values, result) + assoc_t, exc_var = val[2] + + if val[1] + exc_list = @builder.array(nil, val[1], nil) + end + + result = [ @builder.rescue_body(val[0], + exc_list, assoc_t, exc_var, + val[3], val[4]), + *val[5] ] + + result +end + +def _reduce_555(val, _values, result) + result = [] + + result +end + +def _reduce_556(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 557 omitted + +# reduce 558 omitted + +def _reduce_559(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 560 omitted + +def _reduce_561(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 562 omitted + +# reduce 563 omitted + +# reduce 564 omitted + +def _reduce_565(val, _values, result) + result = @builder.string_compose(nil, val[0], nil) + + result +end + +def _reduce_566(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_567(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_568(val, _values, result) + string = @builder.string_compose(val[0], val[1], val[2]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_569(val, _values, result) + string = @builder.string(val[0]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_570(val, _values, result) + result = @builder.character(val[0]) + + result +end + +def _reduce_571(val, _values, result) + string = @builder.xstring_compose(val[0], val[1], val[2]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_572(val, _values, result) + opts = @builder.regexp_options(val[3]) + result = @builder.regexp_compose(val[0], val[1], val[2], opts) + + result +end + +def _reduce_573(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_574(val, _values, result) + result = [] + + result +end + +def _reduce_575(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_576(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_577(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_578(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_579(val, _values, result) + result = [] + + result +end + +def _reduce_580(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_581(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_582(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_583(val, _values, result) + result = [] + + result +end + +def _reduce_584(val, _values, result) + result = val[0] << @builder.string_internal(val[1]) + + result +end + +def _reduce_585(val, _values, result) + result = [] + + result +end + +def _reduce_586(val, _values, result) + result = val[0] << @builder.symbol_internal(val[1]) + + result +end + +def _reduce_587(val, _values, result) + result = [] + + result +end + +def _reduce_588(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_589(val, _values, result) + result = [] + + result +end + +def _reduce_590(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_591(val, _values, result) + result = [] + + result +end + +def _reduce_592(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_593(val, _values, result) + result = @builder.string_internal(val[0]) + + result +end + +def _reduce_594(val, _values, result) + result = val[1] + + result +end + +def _reduce_595(val, _values, result) + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + + result +end + +def _reduce_596(val, _values, result) + @lexer.cmdarg.pop + @lexer.cond.pop + + result = @builder.begin(val[0], val[2], val[3]) + + result +end + +def _reduce_597(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_598(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_599(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +# reduce 600 omitted + +# reduce 601 omitted + +# reduce 602 omitted + +def _reduce_603(val, _values, result) + @lexer.state = :expr_end + result = @builder.symbol(val[0]) + + result +end + +def _reduce_604(val, _values, result) + @lexer.state = :expr_end + result = @builder.symbol_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_605(val, _values, result) + result = val[0] + + result +end + +def _reduce_606(val, _values, result) + if @builder.respond_to? :negate + # AST builder interface compatibility + result = @builder.negate(val[0], val[1]) + else + result = @builder.unary_num(val[0], val[1]) + end + + result +end + +def _reduce_607(val, _values, result) + @lexer.state = :expr_end + result = @builder.integer(val[0]) + + result +end + +def _reduce_608(val, _values, result) + @lexer.state = :expr_end + result = @builder.float(val[0]) + + result +end + +def _reduce_609(val, _values, result) + @lexer.state = :expr_end + result = @builder.rational(val[0]) + + result +end + +def _reduce_610(val, _values, result) + @lexer.state = :expr_end + result = @builder.complex(val[0]) + + result +end + +def _reduce_611(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_612(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_613(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +def _reduce_614(val, _values, result) + result = @builder.ident(val[0]) + + result +end + +def _reduce_615(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_616(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_617(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_618(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +def _reduce_619(val, _values, result) + result = @builder.nil(val[0]) + + result +end + +def _reduce_620(val, _values, result) + result = @builder.self(val[0]) + + result +end + +def _reduce_621(val, _values, result) + result = @builder.true(val[0]) + + result +end + +def _reduce_622(val, _values, result) + result = @builder.false(val[0]) + + result +end + +def _reduce_623(val, _values, result) + result = @builder.__FILE__(val[0]) + + result +end + +def _reduce_624(val, _values, result) + result = @builder.__LINE__(val[0]) + + result +end + +def _reduce_625(val, _values, result) + result = @builder.__ENCODING__(val[0]) + + result +end + +def _reduce_626(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_627(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_628(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_629(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_630(val, _values, result) + result = @builder.nth_ref(val[0]) + + result +end + +def _reduce_631(val, _values, result) + result = @builder.back_ref(val[0]) + + result +end + +def _reduce_632(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_633(val, _values, result) + result = [ val[0], val[2] ] + + result +end + +def _reduce_634(val, _values, result) + result = nil + + result +end + +# reduce 635 omitted + +def _reduce_636(val, _values, result) + @context.in_argdef = false + result = @builder.args(nil, [], nil) + + result +end + +def _reduce_637(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + @lexer.state = :expr_value + @context.in_argdef = false + + result +end + +# reduce 638 omitted + +def _reduce_639(val, _values, result) + result = @context.dup + @context.in_kwarg = true + @context.in_argdef = true + + result +end + +def _reduce_640(val, _values, result) + @context.in_kwarg = val[0].in_kwarg + @context.in_argdef = false + result = @builder.args(nil, val[1], nil) + + result +end + +def _reduce_641(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_642(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_643(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_644(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_645(val, _values, result) + @static_env.declare_forward_args + result = [ @builder.forward_arg(val[0]) ] + + result +end + +def _reduce_646(val, _values, result) + result = val[1] + + result +end + +def _reduce_647(val, _values, result) + result = [] + + result +end + +def _reduce_648(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_649(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_650(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_651(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_652(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_653(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_654(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_655(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_656(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_657(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_658(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_659(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_660(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_661(val, _values, result) + result = val[0] + + result +end + +def _reduce_662(val, _values, result) + result = [] + + result +end + +def _reduce_663(val, _values, result) + result = val[0] + + result +end + +def _reduce_664(val, _values, result) + diagnostic :error, :argument_const, nil, val[0] + + result +end + +def _reduce_665(val, _values, result) + diagnostic :error, :argument_ivar, nil, val[0] + + result +end + +def _reduce_666(val, _values, result) + diagnostic :error, :argument_gvar, nil, val[0] + + result +end + +def _reduce_667(val, _values, result) + diagnostic :error, :argument_cvar, nil, val[0] + + result +end + +# reduce 668 omitted + +def _reduce_669(val, _values, result) + @static_env.declare val[0][0] + + @max_numparam_stack.has_ordinary_params! + + result = val[0] + + result +end + +def _reduce_670(val, _values, result) + @current_arg_stack.set(val[0][0]) + result = val[0] + + result +end + +def _reduce_671(val, _values, result) + @current_arg_stack.set(0) + result = @builder.arg(val[0]) + + result +end + +def _reduce_672(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_673(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_674(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_675(val, _values, result) + check_kwarg_name(val[0]) + + @static_env.declare val[0][0] + + @max_numparam_stack.has_ordinary_params! + + @current_arg_stack.set(val[0][0]) + @context.in_argdef = false + + result = val[0] + + result +end + +def _reduce_676(val, _values, result) + @current_arg_stack.set(nil) + @context.in_argdef = true + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_677(val, _values, result) + @current_arg_stack.set(nil) + @context.in_argdef = true + result = @builder.kwarg(val[0]) + + result +end + +def _reduce_678(val, _values, result) + @context.in_argdef = true + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_679(val, _values, result) + @context.in_argdef = true + result = @builder.kwarg(val[0]) + + result +end + +def _reduce_680(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_681(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_682(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_683(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 684 omitted + +# reduce 685 omitted + +def _reduce_686(val, _values, result) + result = [ @builder.kwnilarg(val[0], val[1]) ] + + result +end + +def _reduce_687(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.kwrestarg(val[0], val[1]) ] + + result +end + +def _reduce_688(val, _values, result) + result = [ @builder.kwrestarg(val[0]) ] + + result +end + +def _reduce_689(val, _values, result) + @current_arg_stack.set(0) + @context.in_argdef = true + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_690(val, _values, result) + @current_arg_stack.set(0) + @context.in_argdef = true + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_691(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_692(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_693(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_694(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 695 omitted + +# reduce 696 omitted + +def _reduce_697(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_698(val, _values, result) + result = [ @builder.restarg(val[0]) ] + + result +end + +# reduce 699 omitted + +# reduce 700 omitted + +def _reduce_701(val, _values, result) + @static_env.declare val[1][0] + + result = @builder.blockarg(val[0], val[1]) + + result +end + +def _reduce_702(val, _values, result) + @static_env.declare_anonymous_blockarg + + result = @builder.blockarg(val[0], nil) + + result +end + +def _reduce_703(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_704(val, _values, result) + result = [] + + result +end + +# reduce 705 omitted + +def _reduce_706(val, _values, result) + result = val[1] + + result +end + +def _reduce_707(val, _values, result) + result = [] + + result +end + +# reduce 708 omitted + +def _reduce_709(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_710(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_711(val, _values, result) + result = @builder.pair(val[0], val[1], val[2]) + + result +end + +def _reduce_712(val, _values, result) + result = @builder.pair_keyword(val[0], val[1]) + + result +end + +def _reduce_713(val, _values, result) + result = @builder.pair_label(val[0]) + + result +end + +def _reduce_714(val, _values, result) + result = @builder.pair_quoted(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_715(val, _values, result) + result = @builder.kwsplat(val[0], val[1]) + + result +end + +# reduce 716 omitted + +# reduce 717 omitted + +# reduce 718 omitted + +# reduce 719 omitted + +# reduce 720 omitted + +# reduce 721 omitted + +# reduce 722 omitted + +# reduce 723 omitted + +# reduce 724 omitted + +# reduce 725 omitted + +# reduce 726 omitted + +# reduce 727 omitted + +def _reduce_728(val, _values, result) + result = [:dot, val[0][1]] + + result +end + +def _reduce_729(val, _values, result) + result = [:anddot, val[0][1]] + + result +end + +# reduce 730 omitted + +# reduce 731 omitted + +# reduce 732 omitted + +# reduce 733 omitted + +def _reduce_734(val, _values, result) + result = val[1] + + result +end + +def _reduce_735(val, _values, result) + result = val[1] + + result +end + +def _reduce_736(val, _values, result) + result = val[1] + + result +end + +# reduce 737 omitted + +# reduce 738 omitted + +# reduce 739 omitted + +def _reduce_740(val, _values, result) + yyerrok + + result +end + +# reduce 741 omitted + +# reduce 742 omitted + +# reduce 743 omitted + +def _reduce_744(val, _values, result) + result = nil + + result +end + +def _reduce_none(val, _values, result) + val[0] +end + + end # class Ruby31 +end # module Parser diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby32.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby32.rb new file mode 100644 index 00000000..ea7021b6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby32.rb @@ -0,0 +1,12705 @@ +# -*- encoding:utf-8; warn-indent:false; frozen_string_literal: true -*- +# +# DO NOT MODIFY!!!! +# This file is automatically generated by Racc 1.8.1 +# from Racc grammar file "ruby32.y". +# + +require 'racc/parser.rb' + + +require_relative '../parser' + +module Parser + class Ruby32 < Parser::Base + + + def version + 32 + end + + def default_encoding + Encoding::UTF_8 + end + + def endless_method_name(name_t) + if !%w[=== == != <= >=].include?(name_t[0]) && name_t[0].end_with?('=') + diagnostic :error, :endless_setter, nil, name_t + end + end + + def local_push + @static_env.extend_static + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + @max_numparam_stack.push(static: true) + end + + def local_pop + @static_env.unextend + @lexer.cmdarg.pop + @lexer.cond.pop + @max_numparam_stack.pop + end + + def try_declare_numparam(node) + name = node.children[0] + + if name =~ /\A_[1-9]\z/ && !static_env.declared?(name) && @context.in_dynamic_block? + # definitely an implicit param + location = node.loc.expression + + if max_numparam_stack.has_ordinary_params? + diagnostic :error, :ordinary_param_defined, nil, [nil, location] + end + + raw_max_numparam_stack = max_numparam_stack.stack.dup + # ignore current block scope + raw_max_numparam_stack.pop + + raw_max_numparam_stack.reverse_each do |outer_scope| + if outer_scope[:static] + # found an outer scope that can't have numparams + # like def/class/etc + break + else + outer_scope_has_numparams = outer_scope[:value] > 0 + + if outer_scope_has_numparams + diagnostic :error, :numparam_used_in_outer_scope, nil, [nil, location] + else + # for now it's ok, but an outer scope can also be a block + # like proc { _1; proc { proc { proc { _2 }} }} + # with numparams, so we need to continue + end + end + end + + static_env.declare(name) + max_numparam_stack.register(name[1].to_i) + + true + else + false + end + end +##### State transition tables begin ### + +racc_action_table = [ + -614, 222, 223, 222, 223, 234, -116, -614, -614, -614, + 928, 623, -614, -614, -614, 228, -614, 312, 240, 664, + 127, 265, 227, 623, -614, 126, -614, -614, -614, 222, + 223, 225, 699, 666, -117, -124, -614, -614, 623, -614, + -614, -614, -614, -614, 623, 623, 623, -116, -117, -729, + 700, -123, 895, 262, -124, 928, 927, 264, 263, 241, + 312, -740, 836, -626, -119, -121, -614, -614, -614, -614, + -614, -614, -614, -614, -614, -614, -614, -614, -614, -614, + 229, 307, -614, -614, -614, 663, -614, -614, 831, 241, + -614, 1000, -118, -614, -614, 241, -614, 241, -614, 665, + -614, -511, -614, -614, 311, -614, -614, -614, -614, -614, + -123, -614, -615, -614, -119, -107, 312, 222, 223, -615, + -615, -615, -116, 241, -615, -615, -615, -614, -615, 127, + -614, -614, -614, -614, 126, -614, -615, -614, -615, -615, + -615, 127, -614, -108, -115, -614, 126, 311, -615, -615, + -121, -615, -615, -615, -615, -615, 127, -120, -118, 989, + -114, 126, 127, 127, 127, -116, -117, 126, 126, 126, + -116, -117, -124, -110, -112, -120, -122, -124, -615, -615, + -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, + -615, -615, 127, -122, -615, -615, -615, 126, -615, -615, + 999, -109, -615, 311, 3, -615, -615, -729, -615, 928, + -615, 127, -615, 651, -615, -615, 126, -615, -615, -615, + -615, -615, -322, -615, 241, -615, 123, -627, -123, -322, + -322, -322, -119, -123, -715, -322, -322, -119, -322, -615, + -715, -716, -615, -615, -615, -615, -322, -615, 228, -615, + 312, 234, 241, 651, -615, 305, 136, -615, -322, -322, + -110, -322, -322, -322, -322, -322, 104, 105, -121, 241, + -716, 219, 614, -121, -112, -120, -118, 653, 652, 525, + -120, -118, 104, 105, -111, -113, -117, 862, -322, -322, + -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, + -322, -322, 220, 228, -322, -322, -322, -740, 690, -322, + 305, -122, -322, 229, 307, -322, -122, 653, 652, 649, + -322, 221, -322, 651, -322, -322, -110, -322, -322, -322, + -322, -322, 238, -322, -720, -322, 699, 311, -124, 603, + -112, -720, -720, -720, 106, 107, -729, -720, -720, -322, + -720, 127, -322, -322, 951, -113, 126, -322, -720, -720, + 106, 107, -109, 922, -322, 224, -110, -122, 229, -110, + -720, -720, 923, -720, -720, -720, -720, -720, -102, -614, + -112, -110, 241, -112, -111, 301, -614, 653, 652, 651, + -88, -124, 685, 651, 127, -112, 234, 864, -123, 126, + -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, + -720, -720, -720, -720, 362, 757, -720, -720, -720, -358, + 691, -720, -119, 363, -720, 502, -358, -720, -109, 686, + 651, -121, -720, 1034, -720, -358, -720, -720, 651, -720, + -720, -720, -720, -720, -614, -720, -720, -720, 241, -715, + -111, -119, -740, 653, 652, 649, 651, 653, 652, 649, + 238, -720, 651, 503, -720, -720, -715, -111, -109, -720, + 803, -109, 651, -720, 1062, 1055, -720, 234, 432, -120, + -720, -720, -720, -109, -358, -720, -720, -720, -121, -720, + -111, 127, -118, -111, 653, 652, 126, -720, -720, -720, + -720, -720, 653, 652, 654, -111, -716, -115, 473, -720, + -720, 1062, -720, -720, -720, -720, -720, -633, -614, -124, + 653, 652, 656, 651, 630, -614, 653, 652, 658, 513, + -715, 878, 836, -740, -614, 524, 653, 652, 662, -720, + -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, + -720, -720, -720, -715, 526, -720, -720, -720, -615, 924, + -720, 222, 223, -720, 636, -615, -720, -720, 637, -720, + -716, -720, 127, -720, -615, -720, -720, 126, -720, -720, + -720, -720, -720, -614, -720, -720, -720, 653, 652, 667, + -118, 228, -615, -716, -622, -621, 282, 283, 522, -615, + -720, -622, -621, -720, -720, -720, -720, 523, -720, -623, + -720, -626, -322, 222, 223, -720, -623, -627, -120, -322, + -322, -322, 527, -615, -322, -322, -322, -620, -322, 895, + 240, 630, 281, 280, -620, -617, -322, 561, -322, -322, + -322, 429, -617, 510, 509, 573, 431, 430, -322, -322, + 603, -322, -322, -322, -322, -322, 229, -615, -107, -622, + -621, -618, -619, 636, -108, 575, 934, 959, -618, -619, + -116, 930, 577, 636, -623, 931, -117, 959, -322, -322, + -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, + -322, -322, -620, 757, -322, -322, -322, -114, 925, -322, + -617, 685, -322, 502, 241, -322, -322, 617, -322, -123, + -322, 136, -322, 241, -322, -322, 617, -322, -322, -322, + -322, -322, -322, -322, -87, -322, -618, -619, 90, -322, + -322, -322, 952, 953, 241, -322, -322, 617, -322, -322, + 91, 503, -322, -322, -322, -322, -322, -322, -110, -322, + 92, 984, 895, 1055, -322, 686, 241, -122, -322, -322, + -119, -322, -322, -322, -322, -322, 241, 1147, 1148, 1194, + 494, -624, 491, 490, 489, 499, 492, 588, -624, 878, + 494, 589, 491, 490, 489, 502, 492, -624, -322, -322, + -322, -322, -322, -322, -322, -322, -322, -322, -322, -322, + -322, -322, -112, 596, -322, -322, -322, 497, 690, -322, + 984, 895, -322, 316, -121, -322, 507, 506, 510, 509, + -322, 241, -322, 503, -322, -322, -109, -322, -322, -322, + -322, -322, 234, -322, -720, -322, -624, 234, -118, 307, + 600, -720, -720, -720, 606, 265, 609, -720, -720, -322, + -720, 241, -322, -322, 618, -322, 619, -322, -720, -720, + 577, 630, 421, 488, -322, 634, 635, -122, 643, 668, + -720, -720, 671, -720, -720, -720, -720, -720, 672, -293, + 674, 675, 494, -625, 491, 490, 489, 499, 492, 956, + -625, 109, 108, 679, 241, 110, 683, 502, 684, -625, + -720, -720, -720, -720, -720, -720, -720, -720, -720, -720, + -720, -720, -720, -720, 307, 697, -720, -720, -720, 497, + 691, -720, 698, 241, -720, 702, 958, -720, 507, 506, + 510, 509, -720, 705, -720, 503, -720, -720, 706, -720, + -720, -720, -720, -720, 499, -720, -720, -720, -625, 708, + 228, 710, -387, 722, 502, -313, 228, 595, 723, 727, + 729, -720, -313, 605, -720, -720, 593, -720, 735, -720, + 228, -313, 523, 736, 265, 488, -720, 633, 265, -120, + 7, 81, 82, 83, 11, 65, 631, 510, 509, 71, + 72, 265, 503, 265, 75, -720, 73, 74, 76, 35, + 36, 79, 80, 130, 131, 132, 133, 134, 84, 33, + 32, 115, 114, 116, 117, 229, 241, 23, 791, 241, + -313, 229, 241, 10, 53, 9, 12, 119, 118, 120, + 111, 64, 109, 108, 112, 229, 110, 121, 122, 228, + 104, 105, 49, 50, 48, 228, 639, -720, 241, -323, + -102, 806, 678, 241, -720, 641, -323, 609, 817, -715, + 822, 676, 241, -720, 45, -323, 824, 38, 827, 832, + 66, 67, -323, 833, 68, 837, 40, 861, 865, -323, + 52, 866, -720, -294, 265, 879, 856, 857, -323, 24, + 858, 121, 122, 561, 102, 90, 93, 94, 561, 95, + 97, 96, 98, 891, 229, 895, 913, 91, 101, 916, + 229, 917, -720, 241, -323, 85, 262, 92, 106, 107, + 264, 263, 46, 47, 334, 81, 82, 83, 11, 65, + 920, 241, 929, 71, 72, 946, 947, -323, 75, 948, + 73, 74, 76, 35, 36, 79, 80, 257, 961, 963, + 301, 969, 84, 33, 32, 115, 114, 116, 117, 971, + 1157, 23, 491, 490, 489, 973, 492, 10, 53, 336, + 12, 119, 118, 120, 111, 64, 109, 108, 112, 575, + 110, 121, 122, 577, 104, 105, 49, 50, 48, 265, + 269, 270, 271, 272, 282, 283, 277, 278, 273, 274, + -322, 258, 259, 817, 241, 275, 276, -322, 45, 307, + 256, 338, -716, 307, 66, 67, -322, 817, 68, 265, + 40, 262, 895, 268, 52, 264, 263, 986, 260, 261, + 281, 280, 266, 24, 267, 987, 241, 241, 102, 90, + 93, 94, 228, 95, 97, 96, 98, 997, 241, 1162, + -296, 91, 101, 241, 279, 1008, 1012, -293, 1160, 85, + 1016, 92, 106, 107, 705, -322, 46, 47, 7, 81, + 82, 83, 11, 65, 700, 1019, 1021, 71, 72, 1023, + 1025, 1025, 75, 241, 73, 74, 76, 35, 36, 79, + 80, 130, 131, 132, 133, 134, 84, 33, 32, 115, + 114, 116, 117, 777, 241, 23, 241, 229, 1053, 1056, + 680, 10, 53, 9, 12, 119, 118, 120, 111, 64, + 109, 108, 112, 928, 110, 121, 122, 971, 104, 105, + 49, 50, 48, 265, 269, 270, 271, 272, 282, 283, + 277, 278, 273, 274, -322, 258, 259, 1068, 241, 275, + 276, -322, 45, 817, 1085, 38, -716, 1087, 66, 67, + -322, 1092, 68, 1093, 40, 262, 1098, 268, 52, 264, + 263, 1099, 260, 261, 281, 280, 266, 24, 267, 1100, + -297, 1113, 102, 90, 93, 94, 228, 95, 97, 96, + 98, 1114, 1115, 1185, 241, 91, 101, 241, 279, 241, + -265, 241, 641, 85, 241, 92, 106, 107, 241, -322, + 46, 47, 334, 81, 82, 83, 11, 65, 928, 1122, + 1123, 71, 72, 241, 1127, 241, 75, 1130, 73, 74, + 76, 35, 36, 79, 80, 130, 131, 132, 133, 134, + 84, 33, 32, 115, 114, 116, 117, 705, 1133, 23, + 1136, 229, 1138, 1140, 680, 10, 53, 336, 12, 119, + 118, 120, 111, 64, 109, 108, 112, 241, 110, 121, + 122, -387, 104, 105, 49, 50, 48, 265, 269, 270, + 271, 272, 282, 283, 277, 278, 273, 274, 228, 258, + 259, 1152, 1163, 275, 276, 1185, 45, 1164, 1025, 38, + 499, 1025, 66, 67, 641, 1025, 68, 1183, 40, 262, + 502, 268, 52, 264, 263, 1186, 260, 261, 281, 280, + 266, 24, 267, 1191, 1192, 697, 102, 90, 93, 94, + 1114, 95, 97, 96, 98, 1202, 1202, 705, 1204, 91, + 101, 1206, 279, 510, 509, 1208, 1210, 85, 503, 92, + 106, 107, 1210, 229, 46, 47, 334, 81, 82, 83, + 11, 65, 241, 1025, -716, 71, 72, -715, 1227, 1210, + 75, 1210, 73, 74, 76, 35, 36, 79, 80, 130, + 131, 132, 133, 134, 84, 33, 32, 115, 114, 116, + 117, 1210, 1210, 23, nil, nil, nil, nil, 892, 10, + 53, 336, 12, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, 265, 269, 270, 271, 272, 282, 283, 277, 278, + 273, 274, nil, 258, 259, nil, nil, 275, 276, nil, + 45, nil, nil, 38, nil, nil, 66, 67, nil, nil, + 68, nil, 40, 262, nil, 268, 52, 264, 263, nil, + 260, 261, 281, 280, 266, 24, 267, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, 279, nil, nil, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 46, 47, + 334, 81, 82, 83, 11, 65, nil, nil, nil, 71, + 72, nil, nil, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, nil, nil, nil, nil, nil, 84, 33, + 32, 115, 114, 116, 117, nil, nil, 23, nil, nil, + nil, nil, 921, 10, 53, 336, 12, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, 265, 269, 270, 271, 272, + 282, 283, 277, 278, 273, 274, nil, 258, 259, nil, + nil, 275, 276, nil, 45, nil, nil, 38, nil, nil, + 66, 67, nil, nil, 68, nil, 40, 262, nil, 268, + 52, 264, 263, nil, 260, 261, 281, 280, 266, 24, + 267, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + 279, nil, nil, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 46, 47, 334, 81, 82, 83, 11, 65, + nil, nil, nil, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 115, 114, 116, 117, nil, + 1157, 23, 491, 490, 489, nil, 492, 10, 53, 336, + 12, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, 265, + 269, 270, 271, 272, 282, 283, 277, 278, 273, 274, + nil, 258, 259, nil, nil, 275, 276, nil, 45, nil, + nil, 38, nil, nil, 66, 67, nil, nil, 68, nil, + 40, 262, nil, 268, 52, 264, 263, nil, 260, 261, + 281, 280, 266, 24, 267, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, 279, nil, nil, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 46, 47, 334, 81, + 82, 83, 11, 65, nil, nil, nil, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 23, nil, nil, nil, nil, + nil, 10, 53, 336, 12, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, 265, 269, 270, 271, 272, 282, 283, + 277, 278, 273, 274, nil, 258, 259, nil, nil, 275, + 276, nil, 45, nil, nil, 338, nil, nil, 66, 67, + nil, nil, 68, nil, 40, 262, nil, 268, 52, 264, + 263, nil, 260, 261, 281, 280, 266, 24, 267, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, 241, 279, nil, + nil, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 46, 47, 334, 81, 82, 83, 11, 65, nil, nil, + nil, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 115, 114, 116, 117, nil, nil, 23, + nil, nil, nil, nil, nil, 10, 53, 336, 12, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, 265, 269, 270, + 271, 272, 282, 283, 277, 278, 273, 274, nil, 258, + 259, nil, nil, 275, 276, nil, 45, nil, nil, 338, + nil, nil, 66, 67, nil, nil, 68, nil, 40, 262, + nil, 268, 52, 264, 263, nil, 260, 261, 281, 280, + 266, 24, 267, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, 279, nil, nil, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 46, 47, 334, 81, 82, 83, + 11, 65, nil, nil, nil, 71, 72, nil, nil, nil, + 75, nil, 73, 74, 76, 35, 36, 79, 80, nil, + nil, nil, nil, nil, 84, 33, 32, 115, 114, 116, + 117, nil, nil, 23, nil, nil, nil, nil, nil, 10, + 53, 336, 12, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, 265, 269, 270, 271, 272, 282, 283, 277, 278, + 273, 274, nil, 258, 259, nil, nil, 275, 276, nil, + 45, nil, nil, 38, nil, nil, 66, 67, nil, nil, + 68, nil, 40, 262, nil, 268, 52, 264, 263, nil, + 260, 261, 281, 280, 266, 24, 267, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, 279, nil, nil, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 46, 47, + 334, 81, 82, 83, 11, 65, nil, nil, nil, 71, + 72, nil, nil, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, nil, nil, nil, nil, nil, 84, 33, + 32, 115, 114, 116, 117, nil, nil, 23, nil, nil, + nil, nil, nil, 10, 53, 336, 12, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, 265, 269, 270, 271, 272, + 282, 283, 277, 278, 273, 274, nil, 258, 259, nil, + nil, 275, 276, nil, 45, nil, nil, 38, nil, nil, + 66, 67, nil, nil, 68, nil, 40, 262, nil, 268, + 52, 264, 263, nil, 260, 261, 281, 280, 266, 24, + 267, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + 279, nil, nil, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 46, 47, 334, 81, 82, 83, 11, 65, + nil, nil, nil, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 115, 114, 116, 117, nil, + nil, 23, nil, nil, nil, nil, nil, 10, 53, 336, + 12, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, 265, + 269, 270, 271, 272, 282, 283, 277, 278, 273, 274, + nil, 258, 259, nil, nil, 275, 276, nil, 45, nil, + nil, 38, nil, nil, 66, 67, nil, nil, 68, nil, + 40, 262, nil, 268, 52, 264, 263, nil, 260, 261, + 281, 280, 266, 24, 267, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, 279, nil, nil, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 46, 47, 334, 81, + 82, 83, 11, 65, nil, nil, nil, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 23, nil, nil, nil, nil, + nil, 10, 53, 336, 12, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, 265, 269, 270, 271, 272, 282, 283, + 277, 278, 273, 274, nil, 258, 259, nil, nil, 275, + 276, nil, 45, nil, nil, 38, nil, nil, 66, 67, + nil, nil, 68, nil, 40, 262, nil, 268, 52, 264, + 263, nil, 260, 261, 281, 280, 266, 24, 267, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, 279, nil, + nil, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 46, 47, 334, 81, 82, 83, 11, 65, nil, nil, + nil, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 115, 114, 116, 117, nil, nil, 23, + nil, nil, nil, nil, nil, 10, 53, 336, 12, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, 265, 269, 270, + 271, 272, 282, 283, 277, 278, 273, 274, nil, 258, + 259, nil, nil, 275, 276, nil, 45, nil, nil, 38, + nil, nil, 66, 67, nil, nil, 68, nil, 40, 262, + nil, 268, 52, 264, 263, nil, 260, 261, 281, 280, + 266, 24, 267, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, 279, nil, nil, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 46, 47, 334, 81, 82, 83, + 11, 65, nil, nil, nil, 71, 72, nil, nil, nil, + 75, nil, 73, 74, 76, 35, 36, 79, 80, nil, + nil, nil, nil, nil, 84, 33, 32, 115, 114, 116, + 117, nil, nil, 23, nil, nil, nil, nil, nil, 10, + 53, 336, 12, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, 265, 269, 270, 271, 272, 282, 283, 277, 278, + 273, 274, nil, 258, 259, nil, nil, 275, 276, nil, + 45, nil, nil, 38, nil, nil, 66, 67, nil, nil, + 68, nil, 40, 262, nil, 268, 52, 264, 263, nil, + 260, 261, 281, 280, 266, 24, 267, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, 279, nil, nil, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 46, 47, + 334, 81, 82, 83, 11, 65, nil, nil, nil, 71, + 72, nil, nil, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, nil, nil, nil, nil, nil, 84, 33, + 32, 115, 114, 116, 117, nil, 494, 23, 491, 490, + 489, nil, 492, 10, 53, 336, 12, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, 494, nil, 491, 490, 489, + nil, 492, nil, 715, nil, 494, nil, 491, 490, 489, + nil, 492, 719, nil, 45, nil, nil, 38, nil, nil, + 66, 67, nil, nil, 68, 494, 40, 491, 490, 489, + 52, 492, 715, nil, nil, nil, nil, nil, nil, 24, + nil, 719, 715, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 715, nil, nil, 85, nil, 92, 106, 107, + nil, 719, 46, 47, 334, 81, 82, 83, 11, 65, + nil, nil, nil, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 115, 114, 116, 117, nil, + nil, 23, nil, nil, nil, nil, nil, 10, 53, 336, + 12, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, 265, + 269, 270, 271, 272, 282, 283, 277, 278, 273, 274, + nil, -741, -741, nil, nil, 275, 276, nil, 45, nil, + nil, 38, nil, nil, 66, 67, nil, 265, 68, nil, + 40, 262, nil, 268, 52, 264, 263, nil, 260, 261, + 281, 280, 266, 24, 267, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, 262, + nil, 91, 101, 264, 263, nil, 260, 261, nil, 85, + nil, 92, 106, 107, nil, nil, 46, 47, 334, 81, + 82, 83, 11, 65, nil, nil, nil, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 23, nil, nil, nil, nil, + nil, 10, 53, 336, 12, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, 265, 269, 270, 271, 272, 282, 283, + 277, 278, 273, 274, nil, -741, -741, nil, nil, 275, + 276, nil, 45, nil, nil, 38, nil, nil, 66, 67, + nil, 265, 68, nil, 40, 262, nil, 268, 52, 264, + 263, nil, 260, 261, 281, 280, 266, 24, 267, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, 262, nil, 91, 101, 264, 263, nil, + 260, 261, nil, 85, nil, 92, 106, 107, nil, nil, + 46, 47, 334, 81, 82, 83, 11, 65, nil, nil, + nil, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 115, 114, 116, 117, nil, nil, 23, + nil, nil, nil, nil, nil, 10, 53, 336, 12, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, 265, 269, 270, + 271, 272, 282, 283, 277, 278, 273, 274, nil, -741, + -741, nil, nil, 275, 276, nil, 45, nil, nil, 38, + nil, nil, 66, 67, nil, nil, 68, nil, 40, 262, + nil, 268, 52, 264, 263, nil, 260, 261, 281, 280, + 266, 24, 267, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, 494, nil, 491, 490, 489, 85, 492, 92, + 106, 107, nil, nil, 46, 47, 334, 81, 82, 83, + 11, 65, nil, nil, nil, 71, 72, nil, nil, nil, + 75, nil, 73, 74, 76, 35, 36, 79, 80, 715, + nil, nil, nil, nil, 84, 33, 32, 115, 114, 116, + 117, nil, nil, 23, nil, nil, nil, nil, nil, 10, + 53, 336, 12, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, 265, 269, 270, 271, 272, 282, 283, 277, 278, + 273, 274, nil, -741, -741, nil, nil, 275, 276, nil, + 45, nil, nil, 38, nil, nil, 66, 67, nil, nil, + 68, nil, 40, 262, nil, 268, 52, 264, 263, nil, + 260, 261, 281, 280, 266, 24, 267, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, 494, nil, 491, 490, + 489, 85, 492, 92, 106, 107, nil, nil, 46, 47, + 334, 81, 82, 83, 11, 65, nil, nil, nil, 71, + 72, nil, nil, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, 715, nil, nil, nil, nil, 84, 33, + 32, 115, 114, 116, 117, nil, nil, 23, nil, nil, + nil, nil, nil, 10, 53, 336, 12, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, 265, -741, -741, -741, -741, + 282, 283, nil, nil, -741, -741, nil, nil, nil, nil, + nil, 275, 276, nil, 45, nil, nil, 38, nil, nil, + 66, 67, nil, nil, 68, nil, 40, 262, nil, 268, + 52, 264, 263, nil, 260, 261, 281, 280, 266, 24, + 267, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, nil, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 46, 47, 334, 81, 82, 83, 11, 65, + nil, nil, nil, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 115, 114, 116, 117, nil, + nil, 23, nil, nil, nil, nil, nil, 10, 53, 336, + 12, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, 265, + -741, -741, -741, -741, 282, 283, nil, nil, -741, -741, + nil, nil, nil, nil, nil, 275, 276, nil, 45, nil, + nil, 38, nil, nil, 66, 67, nil, nil, 68, nil, + 40, 262, nil, 268, 52, 264, 263, nil, 260, 261, + 281, 280, 266, 24, 267, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, nil, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 46, 47, 334, 81, + 82, 83, 11, 65, nil, nil, nil, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 23, nil, nil, nil, nil, + nil, 10, 53, 336, 12, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, 265, -741, -741, -741, -741, 282, 283, + nil, nil, -741, -741, nil, nil, nil, nil, nil, 275, + 276, nil, 45, nil, nil, 38, nil, nil, 66, 67, + nil, nil, 68, nil, 40, 262, nil, 268, 52, 264, + 263, nil, 260, 261, 281, 280, 266, 24, 267, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + nil, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 46, 47, 334, 81, 82, 83, 11, 65, nil, nil, + nil, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 115, 114, 116, 117, nil, nil, 23, + nil, nil, nil, nil, nil, 10, 53, 336, 12, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, 265, -741, -741, + -741, -741, 282, 283, nil, nil, -741, -741, nil, nil, + nil, nil, nil, 275, 276, nil, 45, nil, nil, 38, + nil, nil, 66, 67, nil, nil, 68, nil, 40, 262, + nil, 268, 52, 264, 263, nil, 260, 261, 281, 280, + 266, 24, 267, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, nil, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 46, 47, 334, 81, 82, 83, + 11, 65, nil, nil, nil, 71, 72, nil, nil, nil, + 75, nil, 73, 74, 76, 35, 36, 79, 80, nil, + nil, nil, nil, nil, 84, 33, 32, 115, 114, 116, + 117, nil, nil, 23, nil, nil, nil, nil, nil, 10, + 53, 336, 12, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, 265, -741, -741, -741, -741, 282, 283, nil, nil, + -741, -741, nil, nil, nil, nil, nil, 275, 276, nil, + 45, nil, nil, 38, nil, nil, 66, 67, nil, nil, + 68, nil, 40, 262, nil, 268, 52, 264, 263, nil, + 260, 261, 281, 280, 266, 24, 267, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, nil, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 46, 47, + 334, 81, 82, 83, 11, 65, nil, nil, nil, 71, + 72, nil, nil, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, nil, nil, nil, nil, nil, 84, 33, + 32, 115, 114, 116, 117, nil, nil, 23, nil, nil, + nil, nil, nil, 10, 53, 336, 12, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, 265, -741, -741, -741, -741, + 282, 283, nil, nil, -741, -741, nil, nil, nil, nil, + nil, 275, 276, nil, 45, nil, nil, 38, nil, nil, + 66, 67, nil, nil, 68, nil, 40, 262, nil, 268, + 52, 264, 263, nil, 260, 261, 281, 280, 266, 24, + 267, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, nil, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 46, 47, 334, 81, 82, 83, 11, 65, + nil, nil, nil, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 115, 114, 116, 117, nil, + nil, 23, nil, nil, nil, nil, nil, 10, 53, 336, + 12, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, 265, + 269, 270, 271, 272, 282, 283, nil, nil, 273, 274, + nil, nil, nil, nil, nil, 275, 276, nil, 45, nil, + nil, 38, nil, nil, 66, 67, nil, nil, 68, nil, + 40, 262, nil, 268, 52, 264, 263, nil, 260, 261, + 281, 280, 266, 24, 267, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, nil, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 46, 47, 334, 81, + 82, 83, 11, 65, nil, nil, nil, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 23, nil, nil, nil, nil, + nil, 10, 53, 336, 12, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, 265, 269, 270, 271, 272, 282, 283, + 277, nil, 273, 274, nil, nil, nil, nil, nil, 275, + 276, nil, 45, nil, nil, 38, nil, nil, 66, 67, + nil, nil, 68, nil, 40, 262, nil, 268, 52, 264, + 263, nil, 260, 261, 281, 280, 266, 24, 267, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + nil, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 46, 47, 334, 81, 82, 83, 11, 65, nil, nil, + nil, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 115, 114, 116, 117, nil, nil, 23, + nil, nil, nil, nil, nil, 10, 53, 336, 12, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, 265, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 275, 276, nil, 45, nil, nil, 38, + nil, nil, 66, 67, nil, nil, 68, nil, 40, 262, + nil, 268, 52, 264, 263, nil, 260, 261, nil, nil, + 266, 24, 267, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, nil, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 46, 47, 81, 82, 83, 11, + 65, nil, nil, nil, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 23, nil, nil, nil, nil, nil, 10, 53, + 9, 12, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + 265, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 275, 276, nil, 45, + nil, nil, 38, nil, nil, 66, 67, nil, nil, 68, + nil, 40, 262, nil, 268, 52, 264, 263, nil, 260, + 261, nil, nil, 266, 24, 267, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 35, 36, 79, 80, nil, + nil, nil, nil, nil, 84, 33, 32, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, 265, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 275, 276, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, 262, nil, 268, 52, 264, 263, nil, + 260, 261, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, nil, nil, + nil, 85, nil, 92, 106, 107, -443, nil, 46, 47, + nil, nil, nil, -443, -443, -443, nil, nil, -443, -443, + -443, 265, -443, nil, nil, nil, nil, nil, nil, nil, + -443, -443, -443, -443, nil, nil, nil, 275, 276, nil, + nil, nil, -443, -443, nil, -443, -443, -443, -443, -443, + nil, nil, nil, 262, nil, 268, nil, 264, 263, nil, + 260, 261, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, -443, -443, -443, -443, -443, -443, -443, -443, + -443, -443, -443, -443, -443, -443, nil, nil, -443, -443, + -443, nil, nil, -443, nil, 307, -443, nil, nil, -443, + -443, nil, -443, nil, -443, nil, -443, nil, -443, -443, + nil, -443, -443, -443, -443, -443, -329, -443, -443, -443, + nil, nil, nil, -329, -329, -329, nil, nil, -329, -329, + -329, nil, -329, -443, 265, nil, -443, -443, nil, -443, + -329, -443, -329, -329, nil, nil, nil, nil, -443, nil, + 275, 276, -329, -329, nil, -329, -329, -329, -329, -329, + nil, nil, nil, nil, nil, nil, 262, nil, nil, nil, + 264, 263, nil, 260, 261, nil, nil, nil, nil, nil, + nil, nil, -329, -329, -329, -329, -329, -329, -329, -329, + -329, -329, -329, -329, -329, -329, nil, nil, -329, -329, + -329, nil, nil, -329, nil, 316, -329, nil, nil, -329, + -329, nil, -329, nil, -329, nil, -329, nil, -329, -329, + nil, -329, -329, -329, -329, -329, nil, -329, nil, -329, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, -329, nil, nil, -329, -329, nil, -329, + nil, -329, 81, 82, 83, nil, 65, nil, -329, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, 328, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, 325, nil, 323, + nil, 52, nil, nil, 329, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 326, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, 328, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, 325, nil, + 323, nil, 52, nil, nil, 329, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 326, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, 328, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, 325, + nil, 323, nil, 52, nil, nil, 329, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 326, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 355, 356, 79, 80, nil, nil, nil, + nil, nil, 84, 350, 358, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 355, 356, 79, 80, nil, nil, + nil, nil, nil, 84, 350, 358, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 355, 356, 79, 80, nil, + nil, nil, nil, nil, 84, 350, 358, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 355, 356, 79, 80, + nil, nil, nil, nil, nil, 84, 350, 358, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 355, 356, 79, + 80, nil, nil, nil, nil, nil, 84, 350, 358, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + nil, nil, nil, 85, nil, 92, 106, 107, -314, nil, + 46, 47, nil, nil, nil, -314, -314, -314, nil, nil, + -314, -314, -314, nil, -314, nil, nil, nil, nil, nil, + nil, nil, -314, nil, -314, -314, -314, nil, nil, nil, + 115, 114, 116, 117, -314, -314, nil, -314, -314, -314, + -314, -314, nil, nil, nil, nil, 119, 118, 120, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 104, + 105, nil, nil, 359, -314, -314, -314, -314, -314, -314, + -314, -314, -314, -314, -314, -314, -314, -314, nil, nil, + -314, -314, -314, nil, nil, -314, nil, nil, -314, nil, + nil, -314, -314, nil, -314, nil, -314, nil, -314, nil, + -314, -314, nil, -314, -314, -314, -314, -314, nil, -314, + nil, -314, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, -314, 91, 101, -314, -314, + -314, -314, nil, -314, 85, -314, 92, 106, 107, nil, + -314, 81, 82, 83, 11, 65, nil, nil, nil, 71, + 72, nil, nil, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, nil, nil, nil, nil, nil, 84, 33, + 32, 115, 114, 116, 117, nil, nil, 23, nil, nil, + nil, nil, nil, 10, 53, nil, 12, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 45, nil, nil, 38, nil, nil, + 66, 67, nil, nil, 68, nil, 40, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 24, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 355, 356, 79, 80, nil, nil, nil, nil, nil, 84, + 350, 358, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, 328, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, 325, nil, nil, + nil, 52, nil, nil, 329, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 326, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 355, 356, 79, 80, nil, nil, nil, nil, nil, + 84, 350, 358, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, 328, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, 329, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 326, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 115, 114, 116, 117, nil, nil, + 23, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 24, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 115, 114, 116, 117, nil, + nil, 23, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 24, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 23, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 24, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, 127, nil, nil, nil, nil, 126, + 85, nil, 92, 106, 107, nil, nil, 46, 47, 81, + 82, 83, 11, 65, nil, nil, nil, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 23, nil, nil, nil, nil, + nil, 10, 53, 9, 12, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 38, nil, nil, 66, 67, + nil, nil, 68, nil, 40, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 24, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + nil, nil, 421, 85, nil, 92, 106, 107, nil, nil, + 46, 47, 81, 82, 83, nil, 65, nil, nil, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 23, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 24, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 115, 114, 116, 117, nil, nil, 23, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 24, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 115, 114, 116, 117, nil, nil, + 23, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 24, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 115, 114, 116, 117, nil, + nil, 23, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 24, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, nil, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 46, 47, 81, 82, + 83, 11, 65, nil, nil, nil, 71, 72, nil, nil, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 23, nil, nil, nil, nil, nil, + 10, 53, nil, 12, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 45, nil, nil, 38, nil, nil, 66, 67, nil, + nil, 68, nil, 40, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 24, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, 437, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, nil, nil, nil, nil, nil, 84, 33, 32, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, 437, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, nil, nil, nil, nil, nil, 84, 33, + 32, 115, 114, 116, 117, nil, nil, 23, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 24, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 23, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 24, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, 328, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, 325, + nil, 323, nil, 52, nil, nil, 329, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 326, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 23, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 24, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 35, 36, 79, 80, nil, + nil, nil, nil, nil, 84, 33, 32, 115, 114, 116, + 117, nil, nil, 23, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 24, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, 241, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 355, 356, 79, 80, + nil, nil, nil, nil, nil, 84, 350, 358, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 355, 356, 79, + 80, nil, nil, nil, nil, nil, 84, 350, 358, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 355, 356, + 79, 80, nil, nil, nil, nil, nil, 84, 350, 358, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 355, + 356, 79, 80, nil, nil, nil, nil, nil, 84, 350, + 358, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 355, 356, 79, 80, nil, nil, nil, nil, nil, 84, + 350, 358, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 355, 356, 79, 80, nil, nil, nil, nil, nil, + 84, 350, 358, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 355, 356, 79, 80, nil, nil, nil, nil, + nil, 84, 350, 358, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 355, 356, 79, 80, nil, nil, nil, + nil, nil, 84, 350, 358, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 355, 356, 79, 80, nil, nil, + nil, nil, nil, 84, 350, 358, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 355, 356, 79, 80, nil, + nil, nil, nil, nil, 84, 350, 358, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 355, 356, 79, 80, + nil, nil, nil, nil, nil, 84, 350, 358, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 355, 356, 79, + 80, nil, nil, nil, nil, nil, 84, 350, 358, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 355, 356, + 79, 80, nil, nil, nil, nil, nil, 84, 350, 358, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 355, + 356, 79, 80, nil, nil, nil, nil, nil, 84, 350, + 358, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 355, 356, 79, 80, nil, nil, nil, nil, nil, 84, + 350, 358, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 355, 356, 79, 80, nil, nil, nil, nil, nil, + 84, 350, 358, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 355, 356, 79, 80, nil, nil, nil, nil, + nil, 84, 350, 358, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 355, 356, 79, 80, nil, nil, nil, + nil, nil, 84, 350, 358, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 355, 356, 79, 80, nil, nil, + nil, nil, nil, 84, 350, 358, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 355, 356, 79, 80, nil, + nil, nil, nil, nil, 84, 350, 358, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 355, 356, 79, 80, + nil, nil, nil, nil, nil, 84, 350, 358, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 355, 356, 79, + 80, nil, nil, nil, nil, nil, 84, 350, 358, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 355, 356, + 79, 80, nil, nil, nil, nil, nil, 84, 350, 358, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 355, + 356, 79, 80, nil, nil, nil, nil, nil, 84, 350, + 358, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 23, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 24, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, 328, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, 325, nil, + 323, nil, 52, nil, nil, 329, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 326, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 563, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, 328, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, 325, + nil, 323, nil, 52, nil, nil, 329, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 326, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, 328, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + 325, nil, 323, nil, 52, nil, nil, 329, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 326, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, 241, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 355, 356, 79, 80, nil, nil, + nil, nil, nil, 84, 350, 358, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 355, 356, 79, 80, nil, + nil, nil, nil, nil, 84, 350, 358, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 355, 356, 79, 80, + nil, nil, nil, nil, nil, 84, 350, 358, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 355, 356, 79, + 80, nil, nil, nil, nil, nil, 84, 350, 358, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + nil, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 46, 47, 81, 82, 83, 11, 65, nil, nil, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 23, nil, + nil, nil, nil, nil, 10, 53, nil, 12, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 38, nil, + nil, 66, 67, nil, nil, 68, nil, 40, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 24, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 355, 356, 79, 80, nil, nil, nil, nil, nil, + 84, 350, 358, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 115, 114, 116, 117, nil, nil, + 23, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 24, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 115, 114, 116, 117, nil, + nil, 23, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 24, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 355, 356, 79, 80, nil, nil, + nil, nil, nil, 84, 350, 358, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, nil, nil, nil, + 85, nil, 92, 106, 107, -275, nil, 46, 47, nil, + nil, nil, -275, -275, -275, nil, nil, -275, -275, -275, + nil, -275, nil, nil, nil, nil, nil, nil, nil, -275, + -275, -275, -275, nil, nil, nil, nil, nil, nil, nil, + nil, -275, -275, nil, -275, -275, -275, -275, -275, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, -275, -275, -275, -275, -275, -275, -275, -275, -275, + -275, -275, -275, -275, -275, nil, nil, -275, -275, -275, + nil, nil, -275, nil, 307, -275, nil, nil, -275, -275, + nil, -275, nil, -275, nil, -275, nil, -275, -275, nil, + -275, -275, -275, -275, -275, nil, -275, -275, -275, 494, + nil, 491, 490, 489, 499, 492, nil, nil, nil, nil, + nil, nil, -275, nil, 502, -275, -275, -721, -275, nil, + -275, nil, nil, nil, -721, -721, -721, -275, nil, -721, + -721, -721, nil, -721, nil, nil, 497, nil, nil, nil, + nil, -721, -721, -721, -721, -721, nil, 510, 509, nil, + nil, nil, 503, -721, -721, nil, -721, -721, -721, -721, + -721, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, -721, -721, -721, -721, -721, -721, -721, + -721, -721, -721, -721, -721, -721, -721, nil, nil, -721, + -721, -721, nil, nil, -721, nil, nil, -721, nil, nil, + -721, -721, nil, -721, nil, -721, nil, -721, nil, -721, + -721, nil, -721, -721, -721, -721, -721, nil, -721, -721, + -721, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, -721, nil, nil, -721, -721, -721, + -721, nil, -721, -722, -721, nil, nil, nil, nil, -721, + -722, -722, -722, nil, nil, -722, -722, -722, nil, -722, + nil, nil, nil, nil, nil, nil, nil, -722, -722, -722, + -722, -722, nil, nil, nil, nil, nil, nil, nil, -722, + -722, nil, -722, -722, -722, -722, -722, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, -722, + -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, + -722, -722, -722, nil, nil, -722, -722, -722, nil, nil, + -722, nil, nil, -722, nil, nil, -722, -722, nil, -722, + nil, -722, nil, -722, nil, -722, -722, nil, -722, -722, + -722, -722, -722, nil, -722, -722, -722, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + -722, nil, nil, -722, -722, -722, -722, nil, -722, nil, + -722, nil, 81, 82, 83, -722, 65, nil, nil, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 355, 356, 79, 80, nil, nil, nil, nil, nil, + 84, 350, 358, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, 328, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + 325, nil, 323, nil, 52, nil, nil, 329, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 326, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 355, 356, 79, 80, nil, nil, + nil, nil, nil, 84, 350, 358, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 355, 356, 79, 80, nil, + nil, nil, nil, nil, 84, 350, 358, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 355, 356, 79, 80, + nil, nil, nil, nil, nil, 84, 350, 358, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, nil, + nil, nil, 85, nil, 92, 106, 107, -275, nil, 46, + 47, nil, nil, nil, -275, -275, -275, nil, nil, -275, + -275, -275, 494, -275, 491, 490, 489, 499, 492, nil, + nil, -275, -275, -275, nil, nil, nil, 502, nil, nil, + nil, nil, nil, -275, -275, nil, -275, -275, -275, -275, + -275, nil, 494, nil, 491, 490, 489, 499, 492, 497, + 647, nil, nil, nil, nil, nil, nil, 502, 507, 506, + 510, 509, nil, nil, nil, 503, nil, 494, nil, 491, + 490, 489, 499, 492, -275, nil, nil, nil, nil, 497, + nil, -275, 502, nil, nil, nil, 307, -275, 507, 506, + 510, 509, nil, nil, nil, 503, nil, nil, nil, nil, + nil, nil, nil, nil, 497, 488, nil, nil, nil, -275, + -275, nil, nil, 507, 506, 510, 509, nil, nil, nil, + 503, nil, nil, nil, -275, nil, nil, -275, nil, 81, + 82, 83, -275, 65, nil, 488, nil, 71, 72, -275, + nil, nil, 75, nil, 73, 74, 76, 355, 356, 79, + 80, nil, nil, nil, nil, nil, 84, 350, 358, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 355, 356, + 79, 80, nil, nil, nil, nil, nil, 84, 350, 358, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, 328, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, 800, nil, 323, nil, 52, + nil, nil, 329, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 326, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 355, + 356, 79, 80, nil, nil, nil, nil, nil, 84, 350, + 358, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, 328, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, 323, nil, + 52, nil, nil, 329, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 326, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 355, 356, 79, 80, nil, nil, nil, nil, nil, 84, + 350, 358, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, nil, nil, nil, 85, nil, 92, 106, + 107, nil, nil, 46, 47, 81, 82, 83, 11, 65, + nil, nil, nil, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 115, 114, 116, 117, nil, + nil, 23, nil, nil, nil, nil, nil, 10, 53, 336, + 12, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 38, nil, nil, 66, 67, nil, nil, 68, nil, + 40, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 24, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, nil, nil, 421, 85, + nil, 92, 106, 107, nil, nil, 46, 47, 81, 82, + 83, nil, 65, nil, nil, nil, 71, 72, nil, nil, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, 328, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, 325, nil, 323, nil, 52, nil, nil, + 329, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 326, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 355, 356, 79, + 80, nil, nil, nil, nil, nil, 84, 350, 358, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 355, 356, + 79, 80, nil, nil, nil, nil, nil, 84, 350, 358, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 355, + 356, 79, 80, nil, nil, nil, nil, nil, 84, 350, + 358, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 355, 356, 79, 80, nil, nil, nil, nil, nil, 84, + 350, 358, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, 328, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, 800, nil, nil, + nil, 52, nil, nil, 329, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 326, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 355, 356, 79, 80, nil, nil, nil, nil, nil, + 84, 350, 358, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, 328, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, 329, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 326, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 355, 356, 79, 80, nil, nil, nil, nil, + nil, 84, 350, 358, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, 325, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, 328, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + 325, nil, 323, nil, 52, nil, nil, 329, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 326, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + 328, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, 325, nil, 323, nil, 52, nil, nil, 329, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 326, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, nil, nil, nil, + 85, nil, 92, 106, 107, nil, nil, 46, 47, 81, + 82, 83, 11, 65, nil, nil, nil, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 23, nil, nil, nil, nil, + nil, 10, 53, nil, 12, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 38, nil, nil, 66, 67, + nil, nil, 68, nil, 40, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 24, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 355, 356, + 79, 80, nil, nil, nil, nil, nil, 84, 350, 358, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, 870, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, nil, nil, nil, nil, nil, 84, 33, + 32, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, 328, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, 325, nil, 323, + nil, 52, nil, nil, 329, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 326, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, nil, nil, nil, 85, nil, 92, 106, + 107, nil, nil, 46, 47, 81, 82, 83, 11, 65, + nil, nil, nil, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 115, 114, 116, 117, nil, + nil, 23, nil, nil, nil, nil, nil, 10, 53, nil, + 12, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 38, nil, nil, 66, 67, nil, nil, 68, nil, + 40, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 24, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 355, 356, 79, 80, nil, nil, + nil, nil, nil, 84, 350, 358, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 355, 356, 79, 80, nil, + nil, nil, nil, nil, 84, 350, 358, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, 328, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, 800, nil, 323, nil, 52, nil, nil, 329, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 326, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 355, 356, 79, 80, + nil, nil, nil, nil, nil, 84, 350, 358, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, 328, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, 323, nil, 52, nil, nil, + 329, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 326, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, nil, nil, nil, nil, nil, 84, 33, 32, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, nil, nil, nil, nil, nil, 84, 33, + 32, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 355, 356, 79, 80, nil, nil, nil, nil, nil, + 84, 350, 358, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, 437, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 355, 356, 79, 80, nil, nil, nil, nil, + nil, 84, 350, 358, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 355, 356, 79, 80, nil, nil, nil, + nil, nil, 84, 350, 358, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 355, 356, 79, 80, nil, nil, + nil, nil, nil, 84, 350, 358, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 355, 356, 79, 80, nil, + nil, nil, nil, nil, 84, 350, 358, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, 328, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, 800, nil, 323, nil, 52, nil, nil, 329, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 326, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 563, + nil, 75, nil, 73, 74, 76, 355, 356, 79, 80, + nil, nil, nil, nil, nil, 84, 350, 358, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 355, 356, 79, + 80, nil, nil, nil, nil, nil, 84, 350, 358, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, nil, nil, nil, nil, nil, 84, 33, 32, + 115, 114, 116, 117, nil, nil, 23, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 24, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, nil, nil, nil, nil, nil, 84, 33, + 32, 115, 114, 116, 117, nil, nil, 23, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 24, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 355, 356, 79, 80, nil, nil, nil, nil, nil, 84, + 350, 358, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 355, 356, 79, 80, nil, nil, nil, nil, + nil, 84, 350, 358, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 355, 356, 79, 80, nil, nil, nil, + nil, nil, 84, 350, 358, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 355, 356, 79, 80, nil, nil, + nil, nil, nil, 84, 350, 358, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 355, 356, 79, 80, nil, + nil, nil, nil, nil, 84, 350, 358, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 355, 356, 79, 80, + nil, nil, nil, nil, nil, 84, 350, 358, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 355, 356, 79, + 80, nil, nil, nil, nil, nil, 84, 350, 358, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 355, 356, + 79, 80, nil, nil, nil, nil, nil, 84, 350, 358, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 355, + 356, 79, 80, nil, nil, nil, nil, nil, 84, 350, + 358, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 23, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 24, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 355, 356, 79, 80, nil, nil, nil, nil, nil, + 84, 350, 358, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 115, 114, 116, 117, nil, nil, + 23, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 24, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 355, 356, 79, 80, nil, nil, nil, + nil, nil, 84, 350, 358, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + 800, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 355, 356, 79, 80, nil, nil, + nil, nil, nil, 84, 350, 358, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + 328, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, 323, nil, 52, nil, nil, 329, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 326, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 355, 356, 79, 80, nil, + nil, nil, nil, nil, 84, 350, 358, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 23, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 24, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 23, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 24, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, nil, nil, nil, nil, nil, 84, 33, 32, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, 328, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, 325, nil, 323, nil, 52, + nil, nil, 329, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 326, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 355, + 356, 79, 80, nil, nil, nil, nil, nil, 84, 350, + 358, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 351, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, nil, nil, 359, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 347, nil, nil, 343, nil, nil, + 66, 67, nil, nil, 68, nil, 342, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 355, 356, 79, 80, nil, nil, nil, nil, nil, 84, + 350, 358, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 351, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, nil, nil, 359, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 347, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, 494, nil, + 491, 490, 489, 499, 492, nil, nil, nil, nil, nil, + nil, nil, nil, 502, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 361, nil, 497, 85, nil, 92, 106, + 107, 81, 82, 83, nil, 65, 510, 509, nil, 71, + 72, 503, nil, nil, 75, nil, 73, 74, 76, 355, + 356, 79, 80, nil, nil, nil, nil, nil, 84, 350, + 358, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 351, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, nil, nil, 359, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 396, nil, nil, 38, nil, nil, + 66, 67, nil, nil, 68, nil, 40, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 355, 356, 79, 80, nil, nil, nil, nil, nil, 84, + 350, 358, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 351, nil, nil, 119, 118, + 120, 401, 64, 109, 108, 402, nil, 110, 121, 122, + nil, 104, 105, nil, nil, 359, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 408, nil, nil, 403, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 355, 356, 79, 80, nil, nil, nil, nil, nil, + 84, 350, 358, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 351, nil, nil, 119, + 118, 120, 401, 64, 109, 108, 402, nil, 110, 121, + 122, nil, 104, 105, nil, nil, 359, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 403, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, nil, nil, nil, 75, nil, 73, + 74, 76, 355, 356, 79, 80, nil, nil, nil, nil, + nil, 84, 350, 358, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 351, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, nil, nil, 359, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 347, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + 494, nil, 491, 490, 489, 499, 492, nil, nil, nil, + nil, nil, nil, nil, nil, 502, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 591, nil, 497, 85, nil, + 92, 106, 107, 81, 82, 83, nil, 65, 510, 509, + nil, 71, 72, 503, nil, nil, 75, nil, 73, 74, + 76, 355, 356, 79, 80, nil, nil, nil, nil, nil, + 84, 350, 358, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 351, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, nil, nil, 359, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 347, nil, nil, 343, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, nil, nil, nil, 75, nil, 73, + 74, 76, 355, 356, 79, 80, nil, nil, nil, nil, + nil, 84, 350, 358, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 351, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, nil, nil, 359, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 347, nil, nil, + 343, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 355, 356, 79, 80, nil, nil, nil, + nil, nil, 84, 350, 358, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 351, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, nil, nil, 359, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 347, nil, + nil, 343, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 355, 356, 79, 80, nil, nil, + nil, nil, nil, 84, 350, 358, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 351, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, nil, nil, 359, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 347, + nil, nil, 343, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, nil, nil, nil, + 75, nil, 73, 74, 76, 355, 356, 79, 80, nil, + nil, nil, nil, nil, 84, 350, 358, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 351, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, nil, nil, + 359, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 347, nil, nil, 343, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, nil, nil, + nil, 75, nil, 73, 74, 76, 355, 356, 79, 80, + nil, nil, nil, nil, nil, 84, 350, 358, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 351, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, nil, + nil, 359, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 1106, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 355, 356, 79, + 80, nil, nil, nil, nil, nil, 84, 350, 358, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 351, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + nil, nil, 359, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1144, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + nil, nil, nil, 75, nil, 73, 74, 76, 355, 356, + 79, 80, nil, nil, nil, nil, nil, 84, 350, 358, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 351, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, nil, nil, 359, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 1144, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, nil, nil, nil, 85, nil, 92, 106, 107, 186, + 197, 187, 210, 183, 203, 193, 192, 213, 214, 208, + 191, 190, 185, 211, 215, 216, 195, 184, 198, 202, + 204, 196, 189, nil, nil, nil, 205, 212, 207, 206, + 199, 209, 194, 182, 201, 200, nil, nil, nil, nil, + nil, 181, 188, 179, 180, 176, 177, 178, 139, 141, + 138, nil, 140, nil, nil, nil, nil, nil, nil, nil, + 170, 171, nil, 167, 149, 150, 151, 158, 155, 157, + nil, nil, 152, 153, nil, nil, nil, 172, 173, 159, + 160, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 164, 163, nil, 148, 169, 166, + 165, 174, 161, 162, 156, 154, 146, 168, 147, nil, + nil, 175, 102, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 101, 186, 197, 187, + 210, 183, 203, 193, 192, 213, 214, 208, 191, 190, + 185, 211, 215, 216, 195, 184, 198, 202, 204, 196, + 189, nil, nil, nil, 205, 212, 207, 206, 199, 209, + 194, 182, 201, 200, nil, nil, nil, nil, nil, 181, + 188, 179, 180, 176, 177, 178, 139, 141, nil, nil, + 140, nil, nil, nil, nil, nil, nil, nil, 170, 171, + nil, 167, 149, 150, 151, 158, 155, 157, nil, nil, + 152, 153, nil, nil, nil, 172, 173, 159, 160, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 164, 163, nil, 148, 169, 166, 165, 174, + 161, 162, 156, 154, 146, 168, 147, nil, nil, 175, + 102, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 101, 186, 197, 187, 210, 183, + 203, 193, 192, 213, 214, 208, 191, 190, 185, 211, + 215, 216, 195, 184, 198, 202, 204, 196, 189, nil, + nil, nil, 205, 212, 207, 206, 199, 209, 194, 182, + 201, 200, nil, nil, nil, nil, nil, 181, 188, 179, + 180, 176, 177, 178, 139, 141, nil, nil, 140, nil, + nil, nil, nil, nil, nil, nil, 170, 171, nil, 167, + 149, 150, 151, 158, 155, 157, nil, nil, 152, 153, + nil, nil, nil, 172, 173, 159, 160, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 164, 163, nil, 148, 169, 166, 165, 174, 161, 162, + 156, 154, 146, 168, 147, nil, nil, 175, 102, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 101, 186, 197, 187, 210, 183, 203, 193, + 192, 213, 214, 208, 191, 190, 185, 211, 215, 216, + 195, 184, 198, 202, 204, 196, 189, nil, nil, nil, + 205, 212, 207, 206, 199, 209, 194, 182, 201, 200, + nil, nil, nil, nil, nil, 181, 188, 179, 180, 176, + 177, 178, 139, 141, nil, nil, 140, nil, nil, nil, + nil, nil, nil, nil, 170, 171, nil, 167, 149, 150, + 151, 158, 155, 157, nil, nil, 152, 153, nil, nil, + nil, 172, 173, 159, 160, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 164, 163, + nil, 148, 169, 166, 165, 174, 161, 162, 156, 154, + 146, 168, 147, nil, nil, 175, 102, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 101, 186, 197, 187, 210, 183, 203, 193, 192, 213, + 214, 208, 191, 190, 185, 211, 215, 216, 195, 184, + 198, 202, 204, 196, 189, nil, nil, nil, 205, 212, + 207, 295, 294, 296, 293, 182, 201, 200, nil, nil, + nil, nil, nil, 181, 188, 179, 180, 290, 291, 292, + 288, 141, 109, 108, 289, nil, 110, nil, nil, nil, + nil, nil, 170, 171, nil, 167, 149, 150, 151, 158, + 155, 157, nil, nil, 152, 153, nil, nil, nil, 172, + 173, 159, 160, nil, nil, nil, nil, nil, 300, nil, + nil, nil, nil, nil, nil, nil, 164, 163, nil, 148, + 169, 166, 165, 174, 161, 162, 156, 154, 146, 168, + 147, nil, nil, 175, 115, 114, 116, 117, nil, nil, + 494, nil, 491, 490, 489, 499, 492, nil, nil, nil, + 119, 118, 120, 777, nil, 502, nil, 780, 757, nil, + nil, nil, nil, 104, 105, nil, nil, 359, 502, nil, + nil, nil, nil, nil, nil, nil, nil, 497, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 779, 510, 509, + 750, nil, nil, 503, 748, nil, nil, 749, nil, 752, + nil, nil, nil, nil, nil, nil, 503, nil, nil, nil, + nil, nil, nil, 778, nil, nil, nil, 102, 758, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, 115, 114, 116, 117, nil, nil, 85, nil, + 92, 106, 107, nil, nil, 765, 766, nil, 119, 118, + 120, 777, nil, nil, nil, 780, 757, nil, nil, nil, + nil, 104, 105, nil, nil, 359, 502, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 779, nil, nil, 750, nil, + nil, nil, 748, nil, nil, 749, nil, 752, nil, nil, + nil, nil, nil, nil, 503, nil, nil, nil, nil, nil, + nil, 778, nil, nil, nil, 102, 758, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + 115, 114, 116, 117, nil, nil, 85, nil, 92, 106, + 107, nil, nil, 765, 766, nil, 119, 118, 120, 777, + nil, nil, nil, 780, nil, nil, nil, nil, nil, 104, + 105, nil, nil, 359, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 779, nil, nil, 750, nil, nil, nil, + 748, nil, nil, 749, nil, 752, nil, nil, nil, nil, + nil, nil, 494, nil, 491, 490, 489, 499, 492, 778, + nil, nil, nil, 102, 90, 93, 94, 502, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, 241, 115, + 114, 116, 117, nil, 85, nil, 92, 106, 107, 497, + nil, 765, 766, nil, nil, 119, 118, 120, 777, nil, + 510, 509, 780, nil, nil, 503, nil, nil, 104, 105, + nil, nil, 359, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 779, nil, nil, 750, nil, nil, nil, 748, + nil, nil, 749, nil, nil, 488, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 778, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + nil, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 765, 766, 186, 197, 187, 210, 183, 203, 193, 192, + 213, 214, 208, 191, 190, 185, 211, 215, 216, 195, + 184, 198, 202, 204, 196, 189, nil, nil, nil, 205, + 212, 207, 206, 199, 209, 194, 182, 201, 200, nil, + nil, nil, nil, nil, 181, 188, 179, 180, 176, 177, + 178, 139, 141, nil, nil, 140, nil, nil, nil, nil, + nil, nil, nil, 170, 171, nil, 167, 149, 150, 151, + 158, 155, 157, nil, nil, 152, 153, nil, nil, nil, + 172, 173, 159, 160, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 164, 163, nil, + 148, 169, 166, 165, 174, 161, 162, 156, 154, 146, + 168, 147, nil, nil, 175, 115, 114, 116, 117, nil, + nil, nil, nil, nil, 494, nil, 491, 490, 489, 499, + 492, 119, 118, 120, 777, nil, nil, nil, 780, 502, + nil, nil, nil, nil, 104, 105, nil, nil, 359, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 497, nil, nil, nil, nil, nil, nil, 779, nil, + nil, 750, 510, 509, nil, 748, nil, 503, 749, nil, + 752, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 778, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, 115, 114, 116, 117, 488, nil, 85, + nil, 92, 106, 107, nil, nil, 765, 766, nil, 119, + 118, 120, 777, nil, nil, 494, 780, 491, 490, 489, + 499, 492, 104, 105, nil, nil, 359, nil, nil, nil, + 502, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 779, nil, nil, 750, + nil, nil, 497, 748, nil, nil, 749, nil, nil, nil, + nil, 507, 506, 510, 509, nil, nil, nil, 503, nil, + nil, nil, 778, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, 115, 114, 116, 117, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 765, 766, nil, 119, 118, 120, + 777, nil, nil, nil, 780, 757, nil, nil, nil, nil, + 104, 105, nil, nil, 359, 502, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 779, nil, nil, 750, nil, nil, + nil, 748, nil, nil, 749, nil, 752, nil, nil, nil, + nil, nil, nil, 503, nil, nil, nil, nil, nil, nil, + 778, nil, nil, nil, 102, 758, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, 115, + 114, 116, 117, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 765, 766, nil, 119, 118, 120, 777, nil, + nil, nil, 780, 757, nil, nil, nil, nil, 104, 105, + nil, nil, 359, 502, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 779, nil, nil, 750, nil, nil, nil, 748, + nil, nil, 749, nil, 752, nil, nil, nil, nil, nil, + nil, 503, nil, nil, nil, nil, nil, nil, 778, nil, + nil, nil, 102, 758, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, 115, 114, 116, + 117, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 765, 766, nil, 119, 118, 120, 777, nil, nil, 494, + 780, 491, 490, 489, 499, 492, 104, 105, nil, nil, + 359, nil, nil, nil, 502, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 779, nil, nil, 750, nil, nil, 497, 748, nil, nil, + 749, nil, 752, nil, nil, 507, 506, 510, 509, nil, + nil, nil, 503, nil, nil, nil, 778, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, 115, 114, 116, 117, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 765, 766, + nil, 119, 118, 120, 777, nil, nil, 494, 780, 491, + 490, 489, 499, 492, 104, 105, nil, nil, 359, nil, + nil, nil, 502, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 779, nil, + nil, 750, nil, nil, 497, 748, nil, nil, 749, nil, + nil, nil, nil, nil, nil, 510, 509, nil, nil, nil, + 503, nil, nil, nil, 778, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, 115, 114, 116, 117, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 765, 766, nil, 119, + 118, 120, 777, nil, nil, nil, 780, nil, nil, nil, + nil, nil, 104, 105, nil, nil, 359, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 779, nil, nil, 750, + nil, nil, nil, 748, nil, nil, 749, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 778, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, 115, 114, 116, 117, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 765, 766, nil, 119, 118, 120, + 777, nil, nil, nil, 780, 757, nil, nil, nil, nil, + 104, 105, nil, nil, 359, 502, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 779, nil, nil, 750, nil, nil, + nil, 748, nil, nil, 749, nil, 752, nil, nil, nil, + nil, nil, nil, 503, nil, nil, nil, nil, nil, nil, + 778, nil, nil, nil, 102, 758, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, 115, + 114, 116, 117, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 765, 766, nil, 119, 118, 120, 777, nil, + nil, nil, 780, nil, nil, nil, nil, nil, 104, 105, + nil, nil, 359, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 779, nil, nil, 750, nil, nil, nil, 748, + nil, nil, 749, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 778, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, 115, 114, 116, + 117, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 765, 766, nil, 119, 118, 120, 777, nil, nil, nil, + 780, nil, nil, nil, nil, nil, 104, 105, nil, nil, + 359, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 779, nil, nil, 750, nil, nil, nil, 748, nil, nil, + 749, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 778, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, 115, 114, 116, 117, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 765, 766, + nil, 119, 118, 120, 777, nil, nil, nil, 780, nil, + nil, nil, nil, nil, 104, 105, nil, nil, 359, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 779, nil, + nil, 750, nil, nil, nil, 748, nil, nil, 749, nil, + 752, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 778, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, 115, 114, 116, 117, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 765, 766, nil, 119, + 118, 120, 777, nil, nil, nil, 780, nil, nil, nil, + nil, nil, 104, 105, nil, nil, 359, nil, nil, nil, + nil, nil, nil, nil, 115, 114, 116, 117, nil, nil, + nil, nil, nil, nil, nil, nil, 779, nil, nil, 750, + 119, 118, 120, 748, nil, nil, 749, nil, nil, nil, + nil, nil, nil, 104, 105, nil, nil, 359, nil, nil, + nil, nil, 778, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, nil, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 765, 766, 494, nil, 491, 490, + 489, 499, 492, nil, nil, nil, nil, 102, 90, 93, + 94, 502, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, 115, 114, 116, 117, nil, nil, 85, nil, + 92, 106, 107, 497, nil, nil, nil, nil, 119, 118, + 120, nil, 507, 506, 510, 509, nil, nil, nil, 503, + nil, 104, 105, nil, nil, 359, 115, 114, 116, 117, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 119, 118, 120, 241, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 104, 105, nil, nil, 359, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, nil, nil, nil, 85, nil, 92, 106, + 107, nil, nil, nil, nil, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, nil, nil, nil, + 85, nil, 92, 106, 107, 494, nil, 491, 490, 489, + 499, 492, nil, 494, nil, 491, 490, 489, 499, 492, + 502, nil, nil, nil, nil, nil, nil, nil, 502, nil, + 494, nil, 491, 490, 489, 499, 492, nil, nil, nil, + nil, nil, 497, nil, nil, 502, nil, nil, nil, nil, + 497, 507, 506, 510, 509, nil, nil, nil, 503, 507, + 506, 510, 509, nil, nil, nil, 503, 497, nil, nil, + nil, nil, nil, nil, nil, nil, 507, 506, 510, 509, + nil, nil, 494, 503, 491, 490, 489, 499, 492, 494, + nil, 491, 490, 489, 499, 492, nil, 502, 488, nil, + nil, nil, nil, nil, 502, nil, 488, 494, nil, 491, + 490, 489, 499, 492, nil, nil, nil, nil, nil, 497, + nil, nil, 502, 488, nil, nil, 497, nil, nil, nil, + 510, 509, nil, nil, nil, 503, nil, 510, 509, nil, + nil, nil, 503, nil, 497, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 510, 509, nil, nil, nil, + 503, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 459, 463, nil, 488, 460, nil, nil, nil, + nil, nil, 488, nil, 170, 171, nil, 167, 149, 150, + 151, 158, 155, 157, nil, nil, 152, 153, nil, nil, + 488, 172, 173, 159, 160, nil, nil, nil, nil, nil, + 307, nil, nil, nil, nil, nil, nil, nil, 164, 163, + nil, 148, 169, 166, 165, 174, 161, 162, 156, 154, + 146, 168, 147, 467, 471, 175, nil, 466, nil, nil, + nil, nil, nil, nil, nil, 170, 171, nil, 167, 149, + 150, 151, 158, 155, 157, nil, nil, 152, 153, nil, + nil, nil, 172, 173, 159, 160, nil, nil, nil, nil, + nil, 307, nil, nil, nil, nil, nil, nil, nil, 164, + 163, nil, 148, 169, 166, 165, 174, 161, 162, 156, + 154, 146, 168, 147, 559, 463, 175, nil, 560, nil, + nil, nil, nil, nil, nil, nil, 170, 171, nil, 167, + 149, 150, 151, 158, 155, 157, nil, nil, 152, 153, + nil, nil, nil, 172, 173, 159, 160, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 164, 163, nil, 148, 169, 166, 165, 174, 161, 162, + 156, 154, 146, 168, 147, 730, 463, 175, nil, 731, + nil, nil, nil, nil, nil, nil, nil, 170, 171, nil, + 167, 149, 150, 151, 158, 155, 157, nil, nil, 152, + 153, nil, nil, nil, 172, 173, 159, 160, nil, nil, + nil, nil, nil, 307, nil, nil, nil, nil, nil, nil, + nil, 164, 163, nil, 148, 169, 166, 165, 174, 161, + 162, 156, 154, 146, 168, 147, 732, 471, 175, nil, + 733, nil, nil, nil, nil, nil, nil, nil, 170, 171, + nil, 167, 149, 150, 151, 158, 155, 157, nil, nil, + 152, 153, nil, nil, nil, 172, 173, 159, 160, nil, + nil, nil, nil, nil, 307, nil, nil, nil, nil, nil, + nil, nil, 164, 163, nil, 148, 169, 166, 165, 174, + 161, 162, 156, 154, 146, 168, 147, 810, 463, 175, + nil, 811, nil, nil, nil, nil, nil, nil, nil, 170, + 171, nil, 167, 149, 150, 151, 158, 155, 157, nil, + nil, 152, 153, nil, nil, nil, 172, 173, 159, 160, + nil, nil, nil, nil, nil, 307, nil, nil, nil, nil, + nil, nil, nil, 164, 163, nil, 148, 169, 166, 165, + 174, 161, 162, 156, 154, 146, 168, 147, 813, 471, + 175, nil, 814, nil, nil, nil, nil, nil, nil, nil, + 170, 171, nil, 167, 149, 150, 151, 158, 155, 157, + nil, nil, 152, 153, nil, nil, nil, 172, 173, 159, + 160, nil, nil, nil, nil, nil, 307, nil, nil, nil, + nil, nil, nil, nil, 164, 163, nil, 148, 169, 166, + 165, 174, 161, 162, 156, 154, 146, 168, 147, 730, + 463, 175, nil, 731, nil, nil, nil, nil, nil, nil, + nil, 170, 171, nil, 167, 149, 150, 151, 158, 155, + 157, nil, nil, 152, 153, nil, nil, nil, 172, 173, + 159, 160, nil, nil, nil, nil, nil, 307, nil, nil, + nil, nil, nil, nil, nil, 164, 163, nil, 148, 169, + 166, 165, 174, 161, 162, 156, 154, 146, 168, 147, + 732, 471, 175, nil, 733, nil, nil, nil, nil, nil, + nil, nil, 170, 171, nil, 167, 149, 150, 151, 158, + 155, 157, nil, nil, 152, 153, nil, nil, nil, 172, + 173, 159, 160, nil, nil, nil, nil, nil, 307, nil, + nil, nil, nil, nil, nil, nil, 164, 163, nil, 148, + 169, 166, 165, 174, 161, 162, 156, 154, 146, 168, + 147, 840, 463, 175, nil, 841, nil, nil, nil, nil, + nil, nil, nil, 170, 171, nil, 167, 149, 150, 151, + 158, 155, 157, nil, nil, 152, 153, nil, nil, nil, + 172, 173, 159, 160, nil, nil, nil, nil, nil, 307, + nil, nil, nil, nil, nil, nil, nil, 164, 163, nil, + 148, 169, 166, 165, 174, 161, 162, 156, 154, 146, + 168, 147, 842, 471, 175, nil, 843, nil, nil, nil, + nil, nil, nil, nil, 170, 171, nil, 167, 149, 150, + 151, 158, 155, 157, nil, nil, 152, 153, nil, nil, + nil, 172, 173, 159, 160, nil, nil, nil, nil, nil, + 307, nil, nil, nil, nil, nil, nil, nil, 164, 163, + nil, 148, 169, 166, 165, 174, 161, 162, 156, 154, + 146, 168, 147, 845, 471, 175, nil, 846, nil, nil, + nil, nil, nil, nil, nil, 170, 171, nil, 167, 149, + 150, 151, 158, 155, 157, nil, nil, 152, 153, nil, + nil, nil, 172, 173, 159, 160, nil, nil, nil, nil, + nil, 307, nil, nil, nil, nil, nil, nil, nil, 164, + 163, nil, 148, 169, 166, 165, 174, 161, 162, 156, + 154, 146, 168, 147, 559, 463, 175, nil, 560, nil, + nil, nil, nil, nil, nil, nil, 170, 171, nil, 167, + 149, 150, 151, 158, 155, 157, nil, nil, 152, 153, + nil, nil, nil, 172, 173, 159, 160, nil, nil, nil, + nil, nil, 307, nil, nil, nil, nil, nil, nil, nil, + 164, 163, nil, 148, 169, 166, 165, 174, 161, 162, + 156, 154, 146, 168, 147, 872, 463, 175, nil, 873, + nil, nil, nil, nil, nil, nil, nil, 170, 171, nil, + 167, 149, 150, 151, 158, 155, 157, nil, nil, 152, + 153, nil, nil, nil, 172, 173, 159, 160, nil, nil, + nil, nil, nil, 307, nil, nil, nil, nil, nil, nil, + nil, 164, 163, nil, 148, 169, 166, 165, 174, 161, + 162, 156, 154, 146, 168, 147, 875, 471, 175, nil, + 874, nil, nil, nil, nil, nil, nil, nil, 170, 171, + nil, 167, 149, 150, 151, 158, 155, 157, nil, nil, + 152, 153, nil, nil, nil, 172, 173, 159, 160, nil, + nil, nil, nil, nil, 307, nil, nil, nil, nil, nil, + nil, nil, 164, 163, nil, 148, 169, 166, 165, 174, + 161, 162, 156, 154, 146, 168, 147, 1197, 463, 175, + nil, 1198, nil, nil, nil, nil, nil, nil, nil, 170, + 171, nil, 167, 149, 150, 151, 158, 155, 157, nil, + nil, 152, 153, nil, nil, nil, 172, 173, 159, 160, + nil, nil, nil, nil, nil, 307, nil, nil, nil, nil, + nil, nil, nil, 164, 163, nil, 148, 169, 166, 165, + 174, 161, 162, 156, 154, 146, 168, 147, 1199, 471, + 175, nil, 1200, nil, nil, nil, nil, nil, nil, nil, + 170, 171, nil, 167, 149, 150, 151, 158, 155, 157, + nil, nil, 152, 153, nil, nil, nil, 172, 173, 159, + 160, nil, nil, nil, nil, nil, 307, nil, nil, nil, + nil, nil, nil, nil, 164, 163, nil, 148, 169, 166, + 165, 174, 161, 162, 156, 154, 146, 168, 147, 1214, + 471, 175, nil, 1213, nil, nil, nil, nil, nil, nil, + nil, 170, 171, nil, 167, 149, 150, 151, 158, 155, + 157, nil, nil, 152, 153, nil, nil, nil, 172, 173, + 159, 160, nil, nil, nil, nil, nil, 307, nil, nil, + nil, nil, nil, nil, nil, 164, 163, nil, 148, 169, + 166, 165, 174, 161, 162, 156, 154, 146, 168, 147, + nil, nil, 175 ] + +racc_action_check = [ + 111, 518, 518, 556, 556, 19, 393, 111, 111, 111, + 738, 385, 111, 111, 111, 18, 111, 31, 23, 417, + 5, 534, 18, 386, 111, 5, 111, 111, 111, 980, + 980, 18, 478, 418, 394, 397, 111, 111, 838, 111, + 111, 111, 111, 111, 1015, 1086, 1088, 1103, 1104, 930, + 478, 634, 1216, 534, 1107, 935, 738, 534, 534, 23, + 69, 19, 1216, 244, 840, 841, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 18, 31, 111, 111, 111, 417, 111, 111, 625, 930, + 111, 853, 991, 111, 111, 518, 111, 556, 111, 418, + 111, 935, 111, 111, 31, 111, 111, 111, 111, 111, + 1163, 111, 112, 111, 1197, 393, 788, 644, 644, 112, + 112, 112, 244, 980, 112, 112, 112, 111, 112, 385, + 111, 111, 111, 111, 385, 111, 112, 111, 112, 112, + 112, 386, 111, 394, 397, 111, 386, 69, 112, 112, + 1198, 112, 112, 112, 112, 112, 838, 1199, 1218, 838, + 634, 838, 1015, 1086, 1088, 1103, 1104, 1015, 1086, 1088, + 1103, 1104, 1107, 840, 841, 842, 843, 1107, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 625, 1200, 112, 112, 112, 625, 112, 112, + 853, 991, 112, 788, 1, 112, 112, 749, 112, 1057, + 112, 644, 112, 659, 112, 112, 644, 112, 112, 112, + 112, 112, 466, 112, 749, 112, 3, 245, 1163, 466, + 466, 466, 1197, 1163, 1199, 466, 466, 1197, 466, 112, + 842, 843, 112, 112, 112, 112, 466, 112, 29, 112, + 352, 20, 1057, 412, 112, 29, 9, 112, 466, 466, + 810, 466, 466, 466, 466, 466, 48, 48, 1198, 377, + 1200, 12, 377, 1198, 811, 1199, 1218, 659, 659, 247, + 1199, 1218, 359, 359, 842, 843, 245, 659, 466, 466, + 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, + 466, 466, 14, 287, 466, 466, 466, 20, 466, 466, + 287, 1200, 466, 29, 352, 466, 1200, 412, 412, 412, + 466, 15, 466, 661, 466, 466, 810, 466, 466, 466, + 466, 466, 444, 466, 467, 466, 759, 352, 247, 524, + 811, 467, 467, 467, 48, 48, 931, 467, 467, 466, + 467, 332, 466, 466, 759, 466, 332, 466, 467, 467, + 359, 359, 978, 730, 466, 17, 810, 466, 287, 810, + 467, 467, 731, 467, 467, 467, 467, 467, 805, 288, + 811, 810, 931, 811, 813, 27, 288, 661, 661, 579, + 805, 444, 872, 950, 390, 811, 252, 661, 524, 390, + 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 42, 942, 467, 467, 467, 54, + 467, 467, 730, 45, 467, 942, 54, 467, 978, 873, + 1125, 731, 467, 926, 467, 54, 467, 467, 413, 467, + 467, 467, 467, 467, 288, 467, 467, 467, 53, 813, + 813, 872, 252, 579, 579, 579, 414, 950, 950, 950, + 21, 467, 415, 942, 467, 467, 401, 467, 978, 467, + 579, 978, 416, 732, 950, 942, 467, 253, 217, 467, + 732, 732, 732, 978, 54, 732, 732, 732, 873, 732, + 813, 512, 926, 813, 1125, 1125, 512, 732, 732, 732, + 732, 732, 413, 413, 413, 813, 402, 21, 230, 732, + 732, 1125, 732, 732, 732, 732, 732, 232, 401, 21, + 414, 414, 414, 419, 628, 401, 415, 415, 415, 236, + 401, 1005, 628, 253, 401, 246, 416, 416, 416, 732, + 732, 732, 732, 732, 732, 732, 732, 732, 732, 732, + 732, 732, 732, 401, 248, 732, 732, 732, 402, 732, + 732, 16, 16, 732, 403, 402, 732, 732, 403, 732, + 402, 732, 995, 732, 402, 732, 732, 995, 732, 732, + 732, 732, 732, 401, 732, 732, 732, 419, 419, 419, + 1005, 243, 289, 402, 290, 291, 51, 51, 243, 289, + 732, 290, 291, 732, 732, 732, 732, 243, 732, 292, + 732, 43, 733, 384, 384, 732, 292, 44, 732, 733, + 733, 733, 249, 402, 733, 733, 733, 293, 733, 1091, + 255, 1091, 51, 51, 293, 294, 733, 306, 733, 733, + 733, 138, 294, 705, 705, 320, 138, 138, 733, 733, + 363, 733, 733, 733, 733, 733, 243, 289, 43, 290, + 291, 295, 296, 779, 44, 321, 747, 779, 295, 296, + 43, 747, 324, 934, 292, 747, 44, 934, 733, 733, + 733, 733, 733, 733, 733, 733, 733, 733, 733, 733, + 733, 733, 293, 948, 733, 733, 733, 363, 733, 733, + 294, 459, 733, 948, 378, 733, 733, 378, 733, 363, + 733, 336, 733, 381, 733, 733, 381, 733, 733, 733, + 733, 733, 874, 733, 337, 733, 295, 296, 88, 874, + 874, 874, 762, 762, 825, 874, 874, 825, 874, 733, + 88, 948, 733, 733, 733, 733, 874, 733, 459, 733, + 88, 826, 826, 948, 733, 460, 339, 733, 874, 874, + 459, 874, 874, 874, 874, 874, 1155, 1089, 1089, 1155, + 234, 344, 234, 234, 234, 234, 234, 340, 344, 681, + 719, 341, 719, 719, 719, 234, 719, 344, 874, 874, + 874, 874, 874, 874, 874, 874, 874, 874, 874, 874, + 874, 874, 460, 347, 874, 874, 874, 234, 874, 874, + 1187, 1187, 874, 350, 460, 874, 234, 234, 234, 234, + 874, 351, 874, 234, 874, 874, 681, 874, 874, 874, + 874, 874, 353, 874, 875, 874, 344, 354, 681, 358, + 360, 875, 875, 875, 367, 369, 372, 875, 875, 874, + 875, 375, 874, 874, 379, 874, 380, 874, 875, 875, + 382, 391, 392, 234, 874, 396, 398, 874, 407, 427, + 875, 875, 433, 875, 875, 875, 875, 875, 435, 436, + 438, 441, 235, 345, 235, 235, 235, 235, 235, 778, + 345, 778, 778, 445, 455, 778, 457, 235, 458, 345, + 875, 875, 875, 875, 875, 875, 875, 875, 875, 875, + 875, 875, 875, 875, 468, 474, 875, 875, 875, 235, + 875, 875, 475, 479, 875, 480, 778, 875, 235, 235, + 235, 235, 875, 481, 875, 235, 875, 875, 484, 875, + 875, 875, 875, 875, 702, 875, 875, 875, 345, 485, + 346, 486, 496, 508, 702, 348, 364, 346, 511, 514, + 520, 875, 348, 364, 875, 875, 346, 875, 528, 875, + 395, 348, 364, 529, 536, 235, 875, 395, 537, 875, + 2, 2, 2, 2, 2, 2, 395, 702, 702, 2, + 2, 538, 702, 539, 2, 845, 2, 2, 2, 2, + 2, 2, 2, 8, 8, 8, 8, 8, 2, 2, + 2, 2, 2, 2, 2, 346, 564, 2, 565, 566, + 348, 364, 570, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 395, 2, 2, 2, 405, + 2, 2, 2, 2, 2, 443, 405, 845, 586, 596, + 587, 590, 443, 592, 845, 405, 596, 597, 601, 845, + 610, 443, 611, 845, 2, 596, 612, 2, 622, 626, + 2, 2, 637, 627, 2, 629, 2, 656, 664, 637, + 2, 666, 845, 673, 535, 682, 652, 652, 637, 2, + 652, 652, 652, 687, 2, 2, 2, 2, 692, 2, + 2, 2, 2, 694, 405, 696, 712, 2, 2, 717, + 443, 718, 845, 720, 596, 2, 535, 2, 2, 2, + 535, 535, 2, 2, 38, 38, 38, 38, 38, 38, + 725, 734, 743, 38, 38, 751, 752, 637, 38, 753, + 38, 38, 38, 38, 38, 38, 38, 25, 782, 785, + 787, 793, 38, 38, 38, 38, 38, 38, 38, 794, + 1098, 38, 1098, 1098, 1098, 795, 1098, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 797, + 38, 38, 38, 799, 38, 38, 38, 38, 38, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 814, 25, 25, 807, 809, 25, 25, 814, 38, 812, + 25, 38, 814, 815, 38, 38, 814, 816, 38, 819, + 38, 25, 828, 25, 38, 25, 25, 834, 25, 25, + 25, 25, 25, 38, 25, 835, 839, 848, 38, 38, + 38, 38, 1105, 38, 38, 38, 38, 852, 854, 1105, + 869, 38, 38, 871, 25, 880, 893, 896, 1105, 38, + 897, 38, 38, 38, 900, 814, 38, 38, 136, 136, + 136, 136, 136, 136, 902, 905, 906, 136, 136, 908, + 909, 911, 136, 915, 136, 136, 136, 136, 136, 136, + 136, 335, 335, 335, 335, 335, 136, 136, 136, 136, + 136, 136, 136, 928, 936, 136, 937, 1105, 941, 944, + 448, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 136, 949, 136, 136, 136, 964, 136, 136, + 136, 136, 136, 448, 448, 448, 448, 448, 448, 448, + 448, 448, 448, 448, 846, 448, 448, 967, 968, 448, + 448, 846, 136, 977, 982, 136, 846, 985, 136, 136, + 846, 992, 136, 994, 136, 448, 1001, 448, 136, 448, + 448, 1002, 448, 448, 448, 448, 448, 136, 448, 1003, + 1004, 1030, 136, 136, 136, 136, 1143, 136, 136, 136, + 136, 1031, 1036, 1143, 1041, 136, 136, 1042, 448, 1043, + 448, 1044, 1143, 136, 1045, 136, 136, 136, 1046, 846, + 136, 136, 219, 219, 219, 219, 219, 219, 1050, 1051, + 1052, 219, 219, 1054, 1058, 1065, 219, 1070, 219, 219, + 219, 219, 219, 219, 219, 374, 374, 374, 374, 374, + 219, 219, 219, 219, 219, 219, 219, 1071, 1073, 219, + 1074, 1143, 1075, 1077, 454, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, 219, 1078, 219, 219, + 219, 1079, 219, 219, 219, 219, 219, 454, 454, 454, + 454, 454, 454, 454, 454, 454, 454, 454, 1184, 454, + 454, 1095, 1106, 454, 454, 1184, 219, 1109, 1110, 219, + 1130, 1111, 219, 219, 1184, 1112, 219, 1141, 219, 454, + 1130, 454, 219, 454, 454, 1144, 454, 454, 454, 454, + 454, 219, 454, 1153, 1154, 1159, 219, 219, 219, 219, + 1169, 219, 219, 219, 219, 1170, 1171, 1174, 1177, 219, + 219, 1178, 454, 1130, 1130, 1179, 1180, 219, 1130, 219, + 219, 219, 1182, 1184, 219, 219, 231, 231, 231, 231, + 231, 231, 1196, 1201, 1213, 231, 231, 1214, 1220, 1221, + 231, 1222, 231, 231, 231, 231, 231, 231, 231, 584, + 584, 584, 584, 584, 231, 231, 231, 231, 231, 231, + 231, 1223, 1232, 231, nil, nil, nil, nil, 695, 231, + 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, + 231, nil, 231, 231, 231, nil, 231, 231, 231, 231, + 231, 695, 695, 695, 695, 695, 695, 695, 695, 695, + 695, 695, nil, 695, 695, nil, nil, 695, 695, nil, + 231, nil, nil, 231, nil, nil, 231, 231, nil, nil, + 231, nil, 231, 695, nil, 695, 231, 695, 695, nil, + 695, 695, 695, 695, 695, 231, 695, nil, nil, nil, + 231, 231, 231, 231, nil, 231, 231, 231, 231, nil, + nil, nil, nil, 231, 231, nil, 695, nil, nil, nil, + nil, 231, nil, 231, 231, 231, nil, nil, 231, 231, + 237, 237, 237, 237, 237, 237, nil, nil, nil, 237, + 237, nil, nil, nil, 237, nil, 237, 237, 237, 237, + 237, 237, 237, nil, nil, nil, nil, nil, 237, 237, + 237, 237, 237, 237, 237, nil, nil, 237, nil, nil, + nil, nil, 726, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, 237, nil, 237, 237, 237, nil, + 237, 237, 237, 237, 237, 726, 726, 726, 726, 726, + 726, 726, 726, 726, 726, 726, nil, 726, 726, nil, + nil, 726, 726, nil, 237, nil, nil, 237, nil, nil, + 237, 237, nil, nil, 237, nil, 237, 726, nil, 726, + 237, 726, 726, nil, 726, 726, 726, 726, 726, 237, + 726, nil, nil, nil, 237, 237, 237, 237, nil, 237, + 237, 237, 237, nil, nil, nil, nil, 237, 237, nil, + 726, nil, nil, nil, nil, 237, nil, 237, 237, 237, + nil, nil, 237, 237, 254, 254, 254, 254, 254, 254, + nil, nil, nil, 254, 254, nil, nil, nil, 254, nil, + 254, 254, 254, 254, 254, 254, 254, nil, nil, nil, + nil, nil, 254, 254, 254, 254, 254, 254, 254, nil, + 1194, 254, 1194, 1194, 1194, nil, 1194, 254, 254, 254, + 254, 254, 254, 254, 254, 254, 254, 254, 254, nil, + 254, 254, 254, nil, 254, 254, 254, 254, 254, 318, + 318, 318, 318, 318, 318, 318, 318, 318, 318, 318, + nil, 318, 318, nil, nil, 318, 318, nil, 254, nil, + nil, 254, nil, nil, 254, 254, nil, nil, 254, nil, + 254, 318, nil, 318, 254, 318, 318, nil, 318, 318, + 318, 318, 318, 254, 318, nil, nil, nil, 254, 254, + 254, 254, nil, 254, 254, 254, 254, nil, nil, nil, + nil, 254, 254, nil, 318, nil, nil, nil, nil, 254, + nil, 254, 254, 254, nil, nil, 254, 254, 338, 338, + 338, 338, 338, 338, nil, nil, nil, 338, 338, nil, + nil, nil, 338, nil, 338, 338, 338, 338, 338, 338, + 338, nil, nil, nil, nil, nil, 338, 338, 338, 338, + 338, 338, 338, nil, nil, 338, nil, nil, nil, nil, + nil, 338, 338, 338, 338, 338, 338, 338, 338, 338, + 338, 338, 338, nil, 338, 338, 338, nil, 338, 338, + 338, 338, 338, 553, 553, 553, 553, 553, 553, 553, + 553, 553, 553, 553, nil, 553, 553, nil, nil, 553, + 553, nil, 338, nil, nil, 338, nil, nil, 338, 338, + nil, nil, 338, nil, 338, 553, nil, 553, 338, 553, + 553, nil, 553, 553, 553, 553, 553, 338, 553, nil, + nil, nil, 338, 338, 338, 338, nil, 338, 338, 338, + 338, nil, nil, nil, nil, 338, 338, 553, 553, nil, + nil, nil, nil, 338, nil, 338, 338, 338, nil, nil, + 338, 338, 343, 343, 343, 343, 343, 343, nil, nil, + nil, 343, 343, nil, nil, nil, 343, nil, 343, 343, + 343, 343, 343, 343, 343, nil, nil, nil, nil, nil, + 343, 343, 343, 343, 343, 343, 343, nil, nil, 343, + nil, nil, nil, nil, nil, 343, 343, 343, 343, 343, + 343, 343, 343, 343, 343, 343, 343, nil, 343, 343, + 343, nil, 343, 343, 343, 343, 343, 820, 820, 820, + 820, 820, 820, 820, 820, 820, 820, 820, nil, 820, + 820, nil, nil, 820, 820, nil, 343, nil, nil, 343, + nil, nil, 343, 343, nil, nil, 343, nil, 343, 820, + nil, 820, 343, 820, 820, nil, 820, 820, 820, 820, + 820, 343, 820, nil, nil, nil, 343, 343, 343, 343, + nil, 343, 343, 343, 343, nil, nil, nil, nil, 343, + 343, nil, 820, nil, nil, nil, nil, 343, nil, 343, + 343, 343, nil, nil, 343, 343, 373, 373, 373, 373, + 373, 373, nil, nil, nil, 373, 373, nil, nil, nil, + 373, nil, 373, 373, 373, 373, 373, 373, 373, nil, + nil, nil, nil, nil, 373, 373, 373, 373, 373, 373, + 373, nil, nil, 373, nil, nil, nil, nil, nil, 373, + 373, 373, 373, 373, 373, 373, 373, 373, 373, 373, + 373, nil, 373, 373, 373, nil, 373, 373, 373, 373, + 373, 877, 877, 877, 877, 877, 877, 877, 877, 877, + 877, 877, nil, 877, 877, nil, nil, 877, 877, nil, + 373, nil, nil, 373, nil, nil, 373, 373, nil, nil, + 373, nil, 373, 877, nil, 877, 373, 877, 877, nil, + 877, 877, 877, 877, 877, 373, 877, nil, nil, nil, + 373, 373, 373, 373, nil, 373, 373, 373, 373, nil, + nil, nil, nil, 373, 373, nil, 877, nil, nil, nil, + nil, 373, nil, 373, 373, 373, nil, nil, 373, 373, + 388, 388, 388, 388, 388, 388, nil, nil, nil, 388, + 388, nil, nil, nil, 388, nil, 388, 388, 388, 388, + 388, 388, 388, nil, nil, nil, nil, nil, 388, 388, + 388, 388, 388, 388, 388, nil, nil, 388, nil, nil, + nil, nil, nil, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, 388, nil, 388, 388, 388, nil, + 388, 388, 388, 388, 388, 1009, 1009, 1009, 1009, 1009, + 1009, 1009, 1009, 1009, 1009, 1009, nil, 1009, 1009, nil, + nil, 1009, 1009, nil, 388, nil, nil, 388, nil, nil, + 388, 388, nil, nil, 388, nil, 388, 1009, nil, 1009, + 388, 1009, 1009, nil, 1009, 1009, 1009, 1009, 1009, 388, + 1009, nil, nil, nil, 388, 388, 388, 388, nil, 388, + 388, 388, 388, nil, nil, nil, nil, 388, 388, nil, + 1009, nil, nil, nil, nil, 388, nil, 388, 388, 388, + nil, nil, 388, 388, 389, 389, 389, 389, 389, 389, + nil, nil, nil, 389, 389, nil, nil, nil, 389, nil, + 389, 389, 389, 389, 389, 389, 389, nil, nil, nil, + nil, nil, 389, 389, 389, 389, 389, 389, 389, nil, + nil, 389, nil, nil, nil, nil, nil, 389, 389, 389, + 389, 389, 389, 389, 389, 389, 389, 389, 389, nil, + 389, 389, 389, nil, 389, 389, 389, 389, 389, 1010, + 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, 1010, + nil, 1010, 1010, nil, nil, 1010, 1010, nil, 389, nil, + nil, 389, nil, nil, 389, 389, nil, nil, 389, nil, + 389, 1010, nil, 1010, 389, 1010, 1010, nil, 1010, 1010, + 1010, 1010, 1010, 389, 1010, nil, nil, nil, 389, 389, + 389, 389, nil, 389, 389, 389, 389, nil, nil, nil, + nil, 389, 389, nil, 1010, nil, nil, nil, nil, 389, + nil, 389, 389, 389, nil, nil, 389, 389, 621, 621, + 621, 621, 621, 621, nil, nil, nil, 621, 621, nil, + nil, nil, 621, nil, 621, 621, 621, 621, 621, 621, + 621, nil, nil, nil, nil, nil, 621, 621, 621, 621, + 621, 621, 621, nil, nil, 621, nil, nil, nil, nil, + nil, 621, 621, 621, 621, 621, 621, 621, 621, 621, + 621, 621, 621, nil, 621, 621, 621, nil, 621, 621, + 621, 621, 621, 1032, 1032, 1032, 1032, 1032, 1032, 1032, + 1032, 1032, 1032, 1032, nil, 1032, 1032, nil, nil, 1032, + 1032, nil, 621, nil, nil, 621, nil, nil, 621, 621, + nil, nil, 621, nil, 621, 1032, nil, 1032, 621, 1032, + 1032, nil, 1032, 1032, 1032, 1032, 1032, 621, 1032, nil, + nil, nil, 621, 621, 621, 621, nil, 621, 621, 621, + 621, nil, nil, nil, nil, 621, 621, nil, 1032, nil, + nil, nil, nil, 621, nil, 621, 621, 621, nil, nil, + 621, 621, 624, 624, 624, 624, 624, 624, nil, nil, + nil, 624, 624, nil, nil, nil, 624, nil, 624, 624, + 624, 624, 624, 624, 624, nil, nil, nil, nil, nil, + 624, 624, 624, 624, 624, 624, 624, nil, nil, 624, + nil, nil, nil, nil, nil, 624, 624, 624, 624, 624, + 624, 624, 624, 624, 624, 624, 624, nil, 624, 624, + 624, nil, 624, 624, 624, 624, 624, 1033, 1033, 1033, + 1033, 1033, 1033, 1033, 1033, 1033, 1033, 1033, nil, 1033, + 1033, nil, nil, 1033, 1033, nil, 624, nil, nil, 624, + nil, nil, 624, 624, nil, nil, 624, nil, 624, 1033, + nil, 1033, 624, 1033, 1033, nil, 1033, 1033, 1033, 1033, + 1033, 624, 1033, nil, nil, nil, 624, 624, 624, 624, + nil, 624, 624, 624, 624, nil, nil, nil, nil, 624, + 624, nil, 1033, nil, nil, nil, nil, 624, nil, 624, + 624, 624, nil, nil, 624, 624, 645, 645, 645, 645, + 645, 645, nil, nil, nil, 645, 645, nil, nil, nil, + 645, nil, 645, 645, 645, 645, 645, 645, 645, nil, + nil, nil, nil, nil, 645, 645, 645, 645, 645, 645, + 645, nil, nil, 645, nil, nil, nil, nil, nil, 645, + 645, 645, 645, 645, 645, 645, 645, 645, 645, 645, + 645, nil, 645, 645, 645, nil, 645, 645, 645, 645, + 645, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, 1066, + 1066, 1066, nil, 1066, 1066, nil, nil, 1066, 1066, nil, + 645, nil, nil, 645, nil, nil, 645, 645, nil, nil, + 645, nil, 645, 1066, nil, 1066, 645, 1066, 1066, nil, + 1066, 1066, 1066, 1066, 1066, 645, 1066, nil, nil, nil, + 645, 645, 645, 645, nil, 645, 645, 645, 645, nil, + nil, nil, nil, 645, 645, nil, 1066, nil, nil, nil, + nil, 645, nil, 645, 645, 645, nil, nil, 645, 645, + 844, 844, 844, 844, 844, 844, nil, nil, nil, 844, + 844, nil, nil, nil, 844, nil, 844, 844, 844, 844, + 844, 844, 844, nil, nil, nil, nil, nil, 844, 844, + 844, 844, 844, 844, 844, nil, 497, 844, 497, 497, + 497, nil, 497, 844, 844, 844, 844, 844, 844, 844, + 844, 844, 844, 844, 844, nil, 844, 844, 844, nil, + 844, 844, 844, 844, 844, 715, nil, 715, 715, 715, + nil, 715, nil, 497, nil, 917, nil, 917, 917, 917, + nil, 917, 497, nil, 844, nil, nil, 844, nil, nil, + 844, 844, nil, nil, 844, 916, 844, 916, 916, 916, + 844, 916, 715, nil, nil, nil, nil, nil, nil, 844, + nil, 715, 917, nil, 844, 844, 844, 844, nil, 844, + 844, 844, 844, nil, nil, nil, nil, 844, 844, nil, + nil, nil, 916, nil, nil, 844, nil, 844, 844, 844, + nil, 916, 844, 844, 849, 849, 849, 849, 849, 849, + nil, nil, nil, 849, 849, nil, nil, nil, 849, nil, + 849, 849, 849, 849, 849, 849, 849, nil, nil, nil, + nil, nil, 849, 849, 849, 849, 849, 849, 849, nil, + nil, 849, nil, nil, nil, nil, nil, 849, 849, 849, + 849, 849, 849, 849, 849, 849, 849, 849, 849, nil, + 849, 849, 849, nil, 849, 849, 849, 849, 849, 365, + 365, 365, 365, 365, 365, 365, 365, 365, 365, 365, + nil, 365, 365, nil, nil, 365, 365, nil, 849, nil, + nil, 849, nil, nil, 849, 849, nil, 549, 849, nil, + 849, 365, nil, 365, 849, 365, 365, nil, 365, 365, + 365, 365, 365, 849, 365, nil, nil, nil, 849, 849, + 849, 849, nil, 849, 849, 849, 849, nil, nil, 549, + nil, 849, 849, 549, 549, nil, 549, 549, nil, 849, + nil, 849, 849, 849, nil, nil, 849, 849, 860, 860, + 860, 860, 860, 860, nil, nil, nil, 860, 860, nil, + nil, nil, 860, nil, 860, 860, 860, 860, 860, 860, + 860, nil, nil, nil, nil, nil, 860, 860, 860, 860, + 860, 860, 860, nil, nil, 860, nil, nil, nil, nil, + nil, 860, 860, 860, 860, 860, 860, 860, 860, 860, + 860, 860, 860, nil, 860, 860, 860, nil, 860, 860, + 860, 860, 860, 366, 366, 366, 366, 366, 366, 366, + 366, 366, 366, 366, nil, 366, 366, nil, nil, 366, + 366, nil, 860, nil, nil, 860, nil, nil, 860, 860, + nil, 550, 860, nil, 860, 366, nil, 366, 860, 366, + 366, nil, 366, 366, 366, 366, 366, 860, 366, nil, + nil, nil, 860, 860, 860, 860, nil, 860, 860, 860, + 860, nil, nil, 550, nil, 860, 860, 550, 550, nil, + 550, 550, nil, 860, nil, 860, 860, 860, nil, nil, + 860, 860, 895, 895, 895, 895, 895, 895, nil, nil, + nil, 895, 895, nil, nil, nil, 895, nil, 895, 895, + 895, 895, 895, 895, 895, nil, nil, nil, nil, nil, + 895, 895, 895, 895, 895, 895, 895, nil, nil, 895, + nil, nil, nil, nil, nil, 895, 895, 895, 895, 895, + 895, 895, 895, 895, 895, 895, 895, nil, 895, 895, + 895, nil, 895, 895, 895, 895, 895, 532, 532, 532, + 532, 532, 532, 532, 532, 532, 532, 532, nil, 532, + 532, nil, nil, 532, 532, nil, 895, nil, nil, 895, + nil, nil, 895, 895, nil, nil, 895, nil, 895, 532, + nil, 532, 895, 532, 532, nil, 532, 532, 532, 532, + 532, 895, 532, nil, nil, nil, 895, 895, 895, 895, + nil, 895, 895, 895, 895, nil, nil, nil, nil, 895, + 895, nil, 1113, nil, 1113, 1113, 1113, 895, 1113, 895, + 895, 895, nil, nil, 895, 895, 972, 972, 972, 972, + 972, 972, nil, nil, nil, 972, 972, nil, nil, nil, + 972, nil, 972, 972, 972, 972, 972, 972, 972, 1113, + nil, nil, nil, nil, 972, 972, 972, 972, 972, 972, + 972, nil, nil, 972, nil, nil, nil, nil, nil, 972, + 972, 972, 972, 972, 972, 972, 972, 972, 972, 972, + 972, nil, 972, 972, 972, nil, 972, 972, 972, 972, + 972, 533, 533, 533, 533, 533, 533, 533, 533, 533, + 533, 533, nil, 533, 533, nil, nil, 533, 533, nil, + 972, nil, nil, 972, nil, nil, 972, 972, nil, nil, + 972, nil, 972, 533, nil, 533, 972, 533, 533, nil, + 533, 533, 533, 533, 533, 972, 533, nil, nil, nil, + 972, 972, 972, 972, nil, 972, 972, 972, 972, nil, + nil, nil, nil, 972, 972, nil, 1114, nil, 1114, 1114, + 1114, 972, 1114, 972, 972, 972, nil, nil, 972, 972, + 990, 990, 990, 990, 990, 990, nil, nil, nil, 990, + 990, nil, nil, nil, 990, nil, 990, 990, 990, 990, + 990, 990, 990, 1114, nil, nil, nil, nil, 990, 990, + 990, 990, 990, 990, 990, nil, nil, 990, nil, nil, + nil, nil, nil, 990, 990, 990, 990, 990, 990, 990, + 990, 990, 990, 990, 990, nil, 990, 990, 990, nil, + 990, 990, 990, 990, 990, 543, 543, 543, 543, 543, + 543, 543, nil, nil, 543, 543, nil, nil, nil, nil, + nil, 543, 543, nil, 990, nil, nil, 990, nil, nil, + 990, 990, nil, nil, 990, nil, 990, 543, nil, 543, + 990, 543, 543, nil, 543, 543, 543, 543, 543, 990, + 543, nil, nil, nil, 990, 990, 990, 990, nil, 990, + 990, 990, 990, nil, nil, nil, nil, 990, 990, nil, + nil, nil, nil, nil, nil, 990, nil, 990, 990, 990, + nil, nil, 990, 990, 996, 996, 996, 996, 996, 996, + nil, nil, nil, 996, 996, nil, nil, nil, 996, nil, + 996, 996, 996, 996, 996, 996, 996, nil, nil, nil, + nil, nil, 996, 996, 996, 996, 996, 996, 996, nil, + nil, 996, nil, nil, nil, nil, nil, 996, 996, 996, + 996, 996, 996, 996, 996, 996, 996, 996, 996, nil, + 996, 996, 996, nil, 996, 996, 996, 996, 996, 544, + 544, 544, 544, 544, 544, 544, nil, nil, 544, 544, + nil, nil, nil, nil, nil, 544, 544, nil, 996, nil, + nil, 996, nil, nil, 996, 996, nil, nil, 996, nil, + 996, 544, nil, 544, 996, 544, 544, nil, 544, 544, + 544, 544, 544, 996, 544, nil, nil, nil, 996, 996, + 996, 996, nil, 996, 996, 996, 996, nil, nil, nil, + nil, 996, 996, nil, nil, nil, nil, nil, nil, 996, + nil, 996, 996, 996, nil, nil, 996, 996, 1012, 1012, + 1012, 1012, 1012, 1012, nil, nil, nil, 1012, 1012, nil, + nil, nil, 1012, nil, 1012, 1012, 1012, 1012, 1012, 1012, + 1012, nil, nil, nil, nil, nil, 1012, 1012, 1012, 1012, + 1012, 1012, 1012, nil, nil, 1012, nil, nil, nil, nil, + nil, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1012, 1012, + 1012, 1012, 1012, nil, 1012, 1012, 1012, nil, 1012, 1012, + 1012, 1012, 1012, 545, 545, 545, 545, 545, 545, 545, + nil, nil, 545, 545, nil, nil, nil, nil, nil, 545, + 545, nil, 1012, nil, nil, 1012, nil, nil, 1012, 1012, + nil, nil, 1012, nil, 1012, 545, nil, 545, 1012, 545, + 545, nil, 545, 545, 545, 545, 545, 1012, 545, nil, + nil, nil, 1012, 1012, 1012, 1012, nil, 1012, 1012, 1012, + 1012, nil, nil, nil, nil, 1012, 1012, nil, nil, nil, + nil, nil, nil, 1012, nil, 1012, 1012, 1012, nil, nil, + 1012, 1012, 1067, 1067, 1067, 1067, 1067, 1067, nil, nil, + nil, 1067, 1067, nil, nil, nil, 1067, nil, 1067, 1067, + 1067, 1067, 1067, 1067, 1067, nil, nil, nil, nil, nil, + 1067, 1067, 1067, 1067, 1067, 1067, 1067, nil, nil, 1067, + nil, nil, nil, nil, nil, 1067, 1067, 1067, 1067, 1067, + 1067, 1067, 1067, 1067, 1067, 1067, 1067, nil, 1067, 1067, + 1067, nil, 1067, 1067, 1067, 1067, 1067, 546, 546, 546, + 546, 546, 546, 546, nil, nil, 546, 546, nil, nil, + nil, nil, nil, 546, 546, nil, 1067, nil, nil, 1067, + nil, nil, 1067, 1067, nil, nil, 1067, nil, 1067, 546, + nil, 546, 1067, 546, 546, nil, 546, 546, 546, 546, + 546, 1067, 546, nil, nil, nil, 1067, 1067, 1067, 1067, + nil, 1067, 1067, 1067, 1067, nil, nil, nil, nil, 1067, + 1067, nil, nil, nil, nil, nil, nil, 1067, nil, 1067, + 1067, 1067, nil, nil, 1067, 1067, 1096, 1096, 1096, 1096, + 1096, 1096, nil, nil, nil, 1096, 1096, nil, nil, nil, + 1096, nil, 1096, 1096, 1096, 1096, 1096, 1096, 1096, nil, + nil, nil, nil, nil, 1096, 1096, 1096, 1096, 1096, 1096, + 1096, nil, nil, 1096, nil, nil, nil, nil, nil, 1096, + 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, 1096, + 1096, nil, 1096, 1096, 1096, nil, 1096, 1096, 1096, 1096, + 1096, 547, 547, 547, 547, 547, 547, 547, nil, nil, + 547, 547, nil, nil, nil, nil, nil, 547, 547, nil, + 1096, nil, nil, 1096, nil, nil, 1096, 1096, nil, nil, + 1096, nil, 1096, 547, nil, 547, 1096, 547, 547, nil, + 547, 547, 547, 547, 547, 1096, 547, nil, nil, nil, + 1096, 1096, 1096, 1096, nil, 1096, 1096, 1096, 1096, nil, + nil, nil, nil, 1096, 1096, nil, nil, nil, nil, nil, + nil, 1096, nil, 1096, 1096, 1096, nil, nil, 1096, 1096, + 1097, 1097, 1097, 1097, 1097, 1097, nil, nil, nil, 1097, + 1097, nil, nil, nil, 1097, nil, 1097, 1097, 1097, 1097, + 1097, 1097, 1097, nil, nil, nil, nil, nil, 1097, 1097, + 1097, 1097, 1097, 1097, 1097, nil, nil, 1097, nil, nil, + nil, nil, nil, 1097, 1097, 1097, 1097, 1097, 1097, 1097, + 1097, 1097, 1097, 1097, 1097, nil, 1097, 1097, 1097, nil, + 1097, 1097, 1097, 1097, 1097, 548, 548, 548, 548, 548, + 548, 548, nil, nil, 548, 548, nil, nil, nil, nil, + nil, 548, 548, nil, 1097, nil, nil, 1097, nil, nil, + 1097, 1097, nil, nil, 1097, nil, 1097, 548, nil, 548, + 1097, 548, 548, nil, 548, 548, 548, 548, 548, 1097, + 548, nil, nil, nil, 1097, 1097, 1097, 1097, nil, 1097, + 1097, 1097, 1097, nil, nil, nil, nil, 1097, 1097, nil, + nil, nil, nil, nil, nil, 1097, nil, 1097, 1097, 1097, + nil, nil, 1097, 1097, 1102, 1102, 1102, 1102, 1102, 1102, + nil, nil, nil, 1102, 1102, nil, nil, nil, 1102, nil, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, nil, nil, nil, + nil, nil, 1102, 1102, 1102, 1102, 1102, 1102, 1102, nil, + nil, 1102, nil, nil, nil, nil, nil, 1102, 1102, 1102, + 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, 1102, nil, + 1102, 1102, 1102, nil, 1102, 1102, 1102, 1102, 1102, 551, + 551, 551, 551, 551, 551, 551, nil, nil, 551, 551, + nil, nil, nil, nil, nil, 551, 551, nil, 1102, nil, + nil, 1102, nil, nil, 1102, 1102, nil, nil, 1102, nil, + 1102, 551, nil, 551, 1102, 551, 551, nil, 551, 551, + 551, 551, 551, 1102, 551, nil, nil, nil, 1102, 1102, + 1102, 1102, nil, 1102, 1102, 1102, 1102, nil, nil, nil, + nil, 1102, 1102, nil, nil, nil, nil, nil, nil, 1102, + nil, 1102, 1102, 1102, nil, nil, 1102, 1102, 1145, 1145, + 1145, 1145, 1145, 1145, nil, nil, nil, 1145, 1145, nil, + nil, nil, 1145, nil, 1145, 1145, 1145, 1145, 1145, 1145, + 1145, nil, nil, nil, nil, nil, 1145, 1145, 1145, 1145, + 1145, 1145, 1145, nil, nil, 1145, nil, nil, nil, nil, + nil, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, 1145, + 1145, 1145, 1145, nil, 1145, 1145, 1145, nil, 1145, 1145, + 1145, 1145, 1145, 552, 552, 552, 552, 552, 552, 552, + 552, nil, 552, 552, nil, nil, nil, nil, nil, 552, + 552, nil, 1145, nil, nil, 1145, nil, nil, 1145, 1145, + nil, nil, 1145, nil, 1145, 552, nil, 552, 1145, 552, + 552, nil, 552, 552, 552, 552, 552, 1145, 552, nil, + nil, nil, 1145, 1145, 1145, 1145, nil, 1145, 1145, 1145, + 1145, nil, nil, nil, nil, 1145, 1145, nil, nil, nil, + nil, nil, nil, 1145, nil, 1145, 1145, 1145, nil, nil, + 1145, 1145, 1188, 1188, 1188, 1188, 1188, 1188, nil, nil, + nil, 1188, 1188, nil, nil, nil, 1188, nil, 1188, 1188, + 1188, 1188, 1188, 1188, 1188, nil, nil, nil, nil, nil, + 1188, 1188, 1188, 1188, 1188, 1188, 1188, nil, nil, 1188, + nil, nil, nil, nil, nil, 1188, 1188, 1188, 1188, 1188, + 1188, 1188, 1188, 1188, 1188, 1188, 1188, nil, 1188, 1188, + 1188, nil, 1188, 1188, 1188, 1188, 1188, 554, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 554, 554, nil, 1188, nil, nil, 1188, + nil, nil, 1188, 1188, nil, nil, 1188, nil, 1188, 554, + nil, 554, 1188, 554, 554, nil, 554, 554, nil, nil, + 554, 1188, 554, nil, nil, nil, 1188, 1188, 1188, 1188, + nil, 1188, 1188, 1188, 1188, nil, nil, nil, nil, 1188, + 1188, nil, nil, nil, nil, nil, nil, 1188, nil, 1188, + 1188, 1188, nil, nil, 1188, 1188, 7, 7, 7, 7, + 7, nil, nil, nil, 7, 7, nil, nil, nil, 7, + nil, 7, 7, 7, 7, 7, 7, 7, nil, nil, + nil, nil, nil, 7, 7, 7, 7, 7, 7, 7, + nil, nil, 7, nil, nil, nil, nil, nil, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + nil, 7, 7, 7, nil, 7, 7, 7, 7, 7, + 607, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 607, 607, nil, 7, + nil, nil, 7, nil, nil, 7, 7, nil, nil, 7, + nil, 7, 607, nil, 607, 7, 607, 607, nil, 607, + 607, nil, nil, 607, 7, 607, nil, nil, nil, 7, + 7, 7, 7, nil, 7, 7, 7, 7, nil, nil, + nil, nil, 7, 7, nil, nil, nil, 24, 24, 24, + 7, 24, 7, 7, 7, 24, 24, 7, 7, nil, + 24, nil, 24, 24, 24, 24, 24, 24, 24, nil, + nil, nil, nil, nil, 24, 24, 24, 24, 24, 24, + 24, nil, nil, 24, nil, nil, nil, nil, nil, nil, + 24, nil, nil, 24, 24, 24, 24, 24, 24, 24, + 24, nil, 24, 24, 24, nil, 24, 24, 24, 24, + 24, 540, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 540, 540, nil, + 24, nil, nil, 24, nil, nil, 24, 24, nil, nil, + 24, nil, nil, 540, nil, 540, 24, 540, 540, nil, + 540, 540, nil, nil, nil, 24, nil, nil, nil, nil, + 24, 24, 24, 24, nil, 24, 24, 24, 24, nil, + nil, nil, nil, 24, 24, nil, nil, nil, nil, nil, + nil, 24, nil, 24, 24, 24, 32, nil, 24, 24, + nil, nil, nil, 32, 32, 32, nil, nil, 32, 32, + 32, 541, 32, nil, nil, nil, nil, nil, nil, nil, + 32, 32, 32, 32, nil, nil, nil, 541, 541, nil, + nil, nil, 32, 32, nil, 32, 32, 32, 32, 32, + nil, nil, nil, 541, nil, 541, nil, 541, 541, nil, + 541, 541, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, nil, nil, 32, 32, + 32, nil, nil, 32, nil, 32, 32, nil, nil, 32, + 32, nil, 32, nil, 32, nil, 32, nil, 32, 32, + nil, 32, 32, 32, 32, 32, 33, 32, 32, 32, + nil, nil, nil, 33, 33, 33, nil, nil, 33, 33, + 33, nil, 33, 32, 542, nil, 32, 32, nil, 32, + 33, 32, 33, 33, nil, nil, nil, nil, 32, nil, + 542, 542, 33, 33, nil, 33, 33, 33, 33, 33, + nil, nil, nil, nil, nil, nil, 542, nil, nil, nil, + 542, 542, nil, 542, 542, nil, nil, nil, nil, nil, + nil, nil, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, nil, nil, 33, 33, + 33, nil, nil, 33, nil, 33, 33, nil, nil, 33, + 33, nil, 33, nil, 33, nil, 33, nil, 33, 33, + nil, 33, 33, 33, 33, 33, nil, 33, nil, 33, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 33, nil, nil, 33, 33, nil, 33, + nil, 33, 34, 34, 34, nil, 34, nil, 33, nil, + 34, 34, nil, nil, nil, 34, nil, 34, 34, 34, + 34, 34, 34, 34, nil, nil, nil, nil, nil, 34, + 34, 34, 34, 34, 34, 34, nil, nil, 34, nil, + nil, nil, nil, nil, nil, 34, nil, nil, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + nil, 34, 34, 34, 34, 34, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 34, nil, nil, 34, nil, + nil, 34, 34, nil, nil, 34, nil, 34, nil, 34, + nil, 34, nil, nil, 34, nil, nil, nil, nil, nil, + 34, nil, nil, nil, nil, 34, 34, 34, 34, nil, + 34, 34, 34, 34, nil, nil, nil, nil, 34, 34, + nil, nil, nil, 35, 35, 35, 34, 35, 34, 34, + 34, 35, 35, 34, 34, nil, 35, nil, 35, 35, + 35, 35, 35, 35, 35, nil, nil, nil, nil, nil, + 35, 35, 35, 35, 35, 35, 35, nil, nil, 35, + nil, nil, nil, nil, nil, nil, 35, nil, nil, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, nil, 35, 35, 35, 35, 35, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 35, nil, nil, 35, + nil, nil, 35, 35, nil, nil, 35, nil, 35, nil, + 35, nil, 35, nil, nil, 35, nil, nil, nil, nil, + nil, 35, nil, nil, nil, nil, 35, 35, 35, 35, + nil, 35, 35, 35, 35, nil, nil, nil, nil, 35, + 35, nil, nil, nil, 36, 36, 36, 35, 36, 35, + 35, 35, 36, 36, 35, 35, nil, 36, nil, 36, + 36, 36, 36, 36, 36, 36, nil, nil, nil, nil, + nil, 36, 36, 36, 36, 36, 36, 36, nil, nil, + 36, nil, nil, nil, nil, nil, nil, 36, nil, nil, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, nil, 36, 36, 36, 36, 36, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 36, nil, nil, + 36, nil, nil, 36, 36, nil, nil, 36, nil, 36, + nil, 36, nil, 36, nil, nil, 36, nil, nil, nil, + nil, nil, 36, nil, nil, nil, nil, 36, 36, 36, + 36, nil, 36, 36, 36, 36, nil, nil, nil, nil, + 36, 36, nil, nil, nil, 46, 46, 46, 36, 46, + 36, 36, 36, 46, 46, 36, 36, nil, 46, nil, + 46, 46, 46, 46, 46, 46, 46, nil, nil, nil, + nil, nil, 46, 46, 46, 46, 46, 46, 46, nil, + nil, 46, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 46, 46, 46, 46, 46, 46, 46, 46, nil, + 46, 46, 46, nil, 46, 46, 46, 46, 46, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 46, nil, + nil, 46, nil, nil, 46, 46, nil, nil, 46, nil, + nil, nil, nil, nil, 46, nil, nil, nil, nil, nil, + nil, nil, nil, 46, nil, nil, nil, nil, 46, 46, + 46, 46, nil, 46, 46, 46, 46, nil, nil, nil, + nil, 46, 46, nil, nil, nil, 47, 47, 47, 46, + 47, 46, 46, 46, 47, 47, 46, 46, nil, 47, + nil, 47, 47, 47, 47, 47, 47, 47, nil, nil, + nil, nil, nil, 47, 47, 47, 47, 47, 47, 47, + nil, nil, 47, nil, nil, nil, nil, nil, nil, 47, + nil, nil, 47, 47, 47, 47, 47, 47, 47, 47, + nil, 47, 47, 47, nil, 47, 47, 47, 47, 47, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 47, + nil, nil, 47, nil, nil, 47, 47, nil, nil, 47, + nil, nil, nil, nil, nil, 47, nil, nil, nil, nil, + nil, nil, nil, nil, 47, nil, nil, nil, nil, 47, + 47, 47, 47, nil, 47, 47, 47, 47, nil, nil, + nil, nil, 47, 47, nil, nil, nil, 49, 49, 49, + 47, 49, 47, 47, 47, 49, 49, 47, 47, nil, + 49, nil, 49, 49, 49, 49, 49, 49, 49, nil, + nil, nil, nil, nil, 49, 49, 49, 49, 49, 49, + 49, nil, nil, 49, nil, nil, nil, nil, nil, nil, + 49, nil, nil, 49, 49, 49, 49, 49, 49, 49, + 49, nil, 49, 49, 49, nil, 49, 49, 49, 49, + 49, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 49, nil, nil, 49, nil, nil, 49, 49, nil, nil, + 49, nil, nil, nil, nil, nil, 49, nil, nil, nil, + nil, nil, nil, nil, nil, 49, nil, nil, nil, nil, + 49, 49, 49, 49, nil, 49, 49, 49, 49, nil, + nil, nil, nil, 49, 49, nil, nil, nil, 50, 50, + 50, 49, 50, 49, 49, 49, 50, 50, 49, 49, + nil, 50, nil, 50, 50, 50, 50, 50, 50, 50, + nil, nil, nil, nil, nil, 50, 50, 50, 50, 50, + 50, 50, nil, nil, 50, nil, nil, nil, nil, nil, + nil, 50, nil, nil, 50, 50, 50, 50, 50, 50, + 50, 50, nil, 50, 50, 50, nil, 50, 50, 50, + 50, 50, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 50, nil, nil, 50, nil, nil, 50, 50, nil, + nil, 50, nil, nil, nil, nil, nil, 50, nil, nil, + nil, nil, nil, nil, nil, nil, 50, nil, nil, nil, + nil, 50, 50, 50, 50, nil, 50, 50, 50, 50, + nil, nil, nil, nil, 50, 50, nil, nil, nil, 52, + 52, 52, 50, 52, 50, 50, 50, 52, 52, 50, + 50, nil, 52, nil, 52, 52, 52, 52, 52, 52, + 52, nil, nil, nil, nil, nil, 52, 52, 52, 52, + 52, 52, 52, nil, nil, 52, nil, nil, nil, nil, + nil, nil, 52, nil, nil, 52, 52, 52, 52, 52, + 52, 52, 52, nil, 52, 52, 52, nil, 52, 52, + 52, 52, 52, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 52, nil, nil, 52, nil, nil, 52, 52, + nil, nil, 52, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, 52, 52, 52, 52, nil, 52, 52, 52, + 52, nil, nil, nil, nil, 52, 52, nil, nil, nil, + nil, nil, nil, 52, nil, 52, 52, 52, 64, nil, + 52, 52, nil, nil, nil, 64, 64, 64, nil, nil, + 64, 64, 64, nil, 64, nil, nil, nil, nil, nil, + nil, nil, 64, nil, 64, 64, 64, nil, nil, nil, + 765, 765, 765, 765, 64, 64, nil, 64, 64, 64, + 64, 64, nil, nil, nil, nil, 765, 765, 765, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 765, + 765, nil, nil, 765, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, nil, nil, + 64, 64, 64, nil, nil, 64, nil, nil, 64, nil, + nil, 64, 64, nil, 64, nil, 64, nil, 64, nil, + 64, 64, nil, 64, 64, 64, 64, 64, nil, 64, + nil, 64, nil, 765, 765, 765, 765, nil, 765, 765, + 765, 765, nil, nil, nil, 64, 765, 765, 64, 64, + 64, 64, nil, 64, 765, 64, 765, 765, 765, nil, + 64, 66, 66, 66, 66, 66, nil, nil, nil, 66, + 66, nil, nil, nil, 66, nil, 66, 66, 66, 66, + 66, 66, 66, nil, nil, nil, nil, nil, 66, 66, + 66, 66, 66, 66, 66, nil, nil, 66, nil, nil, + nil, nil, nil, 66, 66, nil, 66, 66, 66, 66, + 66, 66, 66, 66, 66, nil, 66, 66, 66, nil, + 66, 66, 66, 66, 66, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 66, nil, nil, 66, nil, nil, + 66, 66, nil, nil, 66, nil, 66, nil, nil, nil, + 66, nil, nil, nil, nil, nil, nil, nil, nil, 66, + nil, nil, nil, nil, 66, 66, 66, 66, nil, 66, + 66, 66, 66, nil, nil, nil, nil, 66, 66, nil, + nil, nil, 67, 67, 67, 66, 67, 66, 66, 66, + 67, 67, 66, 66, nil, 67, nil, 67, 67, 67, + 67, 67, 67, 67, nil, nil, nil, nil, nil, 67, + 67, 67, 67, 67, 67, 67, nil, nil, 67, nil, + nil, nil, nil, nil, nil, 67, nil, nil, 67, 67, + 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, + nil, 67, 67, 67, 67, 67, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 67, nil, nil, 67, nil, + nil, 67, 67, nil, nil, 67, nil, 67, nil, nil, + nil, 67, nil, nil, 67, nil, nil, nil, nil, nil, + 67, nil, nil, nil, nil, 67, 67, 67, 67, nil, + 67, 67, 67, 67, nil, nil, nil, nil, 67, 67, + nil, nil, nil, 68, 68, 68, 67, 68, 67, 67, + 67, 68, 68, 67, 67, nil, 68, nil, 68, 68, + 68, 68, 68, 68, 68, nil, nil, nil, nil, nil, + 68, 68, 68, 68, 68, 68, 68, nil, nil, 68, + nil, nil, nil, nil, nil, nil, 68, nil, nil, 68, + 68, 68, 68, 68, 68, 68, 68, 68, 68, 68, + 68, nil, 68, 68, 68, 68, 68, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 68, nil, nil, 68, + nil, nil, 68, 68, nil, nil, 68, nil, nil, nil, + nil, nil, 68, nil, nil, 68, nil, nil, nil, nil, + nil, 68, nil, nil, nil, nil, 68, 68, 68, 68, + nil, 68, 68, 68, 68, nil, nil, nil, nil, 68, + 68, nil, nil, nil, 71, 71, 71, 68, 71, 68, + 68, 68, 71, 71, 68, 68, nil, 71, nil, 71, + 71, 71, 71, 71, 71, 71, nil, nil, nil, nil, + nil, 71, 71, 71, 71, 71, 71, 71, nil, nil, + 71, nil, nil, nil, nil, nil, nil, 71, nil, nil, + 71, 71, 71, 71, 71, 71, 71, 71, nil, 71, + 71, 71, nil, 71, 71, 71, 71, 71, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 71, nil, nil, + 71, nil, nil, 71, 71, nil, nil, 71, nil, nil, + nil, nil, nil, 71, nil, nil, nil, nil, nil, nil, + nil, nil, 71, nil, nil, nil, nil, 71, 71, 71, + 71, nil, 71, 71, 71, 71, nil, nil, nil, nil, + 71, 71, nil, nil, nil, 72, 72, 72, 71, 72, + 71, 71, 71, 72, 72, 71, 71, nil, 72, nil, + 72, 72, 72, 72, 72, 72, 72, nil, nil, nil, + nil, nil, 72, 72, 72, 72, 72, 72, 72, nil, + nil, 72, nil, nil, nil, nil, nil, nil, 72, nil, + nil, 72, 72, 72, 72, 72, 72, 72, 72, nil, + 72, 72, 72, nil, 72, 72, 72, 72, 72, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 72, nil, + nil, 72, nil, nil, 72, 72, nil, nil, 72, nil, + nil, nil, nil, nil, 72, nil, nil, nil, nil, nil, + nil, nil, nil, 72, nil, nil, nil, nil, 72, 72, + 72, 72, nil, 72, 72, 72, 72, nil, nil, nil, + nil, 72, 72, nil, nil, nil, 75, 75, 75, 72, + 75, 72, 72, 72, 75, 75, 72, 72, nil, 75, + nil, 75, 75, 75, 75, 75, 75, 75, nil, nil, + nil, nil, nil, 75, 75, 75, 75, 75, 75, 75, + nil, nil, 75, nil, nil, nil, nil, nil, nil, 75, + nil, nil, 75, 75, 75, 75, 75, 75, 75, 75, + nil, 75, 75, 75, nil, 75, 75, 75, 75, 75, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 75, + nil, nil, 75, nil, nil, 75, 75, nil, nil, 75, + nil, nil, nil, nil, nil, 75, nil, nil, nil, nil, + nil, nil, nil, nil, 75, nil, nil, nil, nil, 75, + 75, 75, 75, nil, 75, 75, 75, 75, nil, nil, + nil, nil, 75, 75, 75, nil, nil, nil, nil, 75, + 75, nil, 75, 75, 75, nil, nil, 75, 75, 125, + 125, 125, 125, 125, nil, nil, nil, 125, 125, nil, + nil, nil, 125, nil, 125, 125, 125, 125, 125, 125, + 125, nil, nil, nil, nil, nil, 125, 125, 125, 125, + 125, 125, 125, nil, nil, 125, nil, nil, nil, nil, + nil, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, nil, 125, 125, 125, nil, 125, 125, + 125, 125, 125, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 125, nil, nil, 125, nil, nil, 125, 125, + nil, nil, 125, nil, 125, nil, nil, nil, 125, nil, + nil, nil, nil, nil, nil, nil, nil, 125, nil, nil, + nil, nil, 125, 125, 125, 125, nil, 125, 125, 125, + 125, nil, nil, nil, nil, 125, 125, nil, nil, nil, + nil, nil, 125, 125, nil, 125, 125, 125, nil, nil, + 125, 125, 130, 130, 130, nil, 130, nil, nil, nil, + 130, 130, nil, nil, nil, 130, nil, 130, 130, 130, + 130, 130, 130, 130, nil, nil, nil, nil, nil, 130, + 130, 130, 130, 130, 130, 130, nil, nil, 130, nil, + nil, nil, nil, nil, nil, 130, nil, nil, 130, 130, + 130, 130, 130, 130, 130, 130, nil, 130, 130, 130, + nil, 130, 130, 130, 130, 130, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 130, nil, nil, 130, nil, + nil, 130, 130, nil, nil, 130, nil, nil, nil, nil, + nil, 130, nil, nil, nil, nil, nil, nil, nil, nil, + 130, nil, nil, nil, nil, 130, 130, 130, 130, nil, + 130, 130, 130, 130, nil, nil, nil, nil, 130, 130, + nil, nil, nil, 131, 131, 131, 130, 131, 130, 130, + 130, 131, 131, 130, 130, nil, 131, nil, 131, 131, + 131, 131, 131, 131, 131, nil, nil, nil, nil, nil, + 131, 131, 131, 131, 131, 131, 131, nil, nil, 131, + nil, nil, nil, nil, nil, nil, 131, nil, nil, 131, + 131, 131, 131, 131, 131, 131, 131, nil, 131, 131, + 131, nil, 131, 131, 131, 131, 131, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 131, nil, nil, 131, + nil, nil, 131, 131, nil, nil, 131, nil, nil, nil, + nil, nil, 131, nil, nil, nil, nil, nil, nil, nil, + nil, 131, nil, nil, nil, nil, 131, 131, 131, 131, + nil, 131, 131, 131, 131, nil, nil, nil, nil, 131, + 131, nil, nil, nil, 132, 132, 132, 131, 132, 131, + 131, 131, 132, 132, 131, 131, nil, 132, nil, 132, + 132, 132, 132, 132, 132, 132, nil, nil, nil, nil, + nil, 132, 132, 132, 132, 132, 132, 132, nil, nil, + 132, nil, nil, nil, nil, nil, nil, 132, nil, nil, + 132, 132, 132, 132, 132, 132, 132, 132, nil, 132, + 132, 132, nil, 132, 132, 132, 132, 132, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 132, nil, nil, + 132, nil, nil, 132, 132, nil, nil, 132, nil, nil, + nil, nil, nil, 132, nil, nil, nil, nil, nil, nil, + nil, nil, 132, nil, nil, nil, nil, 132, 132, 132, + 132, nil, 132, 132, 132, 132, nil, nil, nil, nil, + 132, 132, nil, nil, nil, 133, 133, 133, 132, 133, + 132, 132, 132, 133, 133, 132, 132, nil, 133, nil, + 133, 133, 133, 133, 133, 133, 133, nil, nil, nil, + nil, nil, 133, 133, 133, 133, 133, 133, 133, nil, + nil, 133, nil, nil, nil, nil, nil, nil, 133, nil, + nil, 133, 133, 133, 133, 133, 133, 133, 133, nil, + 133, 133, 133, nil, 133, 133, 133, 133, 133, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 133, nil, + nil, 133, nil, nil, 133, 133, nil, nil, 133, nil, + nil, nil, nil, nil, 133, nil, nil, nil, nil, nil, + nil, nil, nil, 133, nil, nil, nil, nil, 133, 133, + 133, 133, nil, 133, 133, 133, 133, nil, nil, nil, + nil, 133, 133, nil, nil, nil, nil, nil, nil, 133, + nil, 133, 133, 133, nil, nil, 133, 133, 134, 134, + 134, 134, 134, nil, nil, nil, 134, 134, nil, nil, + nil, 134, nil, 134, 134, 134, 134, 134, 134, 134, + nil, nil, nil, nil, nil, 134, 134, 134, 134, 134, + 134, 134, nil, nil, 134, nil, nil, nil, nil, nil, + 134, 134, nil, 134, 134, 134, 134, 134, 134, 134, + 134, 134, nil, 134, 134, 134, nil, 134, 134, 134, + 134, 134, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 134, nil, nil, 134, nil, nil, 134, 134, nil, + nil, 134, nil, 134, nil, nil, nil, 134, nil, nil, + nil, nil, nil, nil, nil, nil, 134, nil, nil, nil, + nil, 134, 134, 134, 134, nil, 134, 134, 134, 134, + nil, nil, nil, nil, 134, 134, nil, nil, nil, 220, + 220, 220, 134, 220, 134, 134, 134, 220, 220, 134, + 134, nil, 220, nil, 220, 220, 220, 220, 220, 220, + 220, nil, nil, nil, nil, nil, 220, 220, 220, 220, + 220, 220, 220, nil, nil, 220, nil, nil, nil, nil, + nil, nil, 220, nil, nil, 220, 220, 220, 220, 220, + 220, 220, 220, nil, 220, 220, 220, nil, 220, 220, + 220, 220, 220, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 220, nil, nil, 220, nil, nil, 220, 220, + nil, nil, 220, nil, 220, nil, nil, nil, 220, nil, + nil, nil, nil, nil, nil, nil, nil, 220, nil, nil, + nil, nil, 220, 220, 220, 220, nil, 220, 220, 220, + 220, nil, nil, nil, nil, 220, 220, nil, nil, nil, + 221, 221, 221, 220, 221, 220, 220, 220, 221, 221, + 220, 220, nil, 221, nil, 221, 221, 221, 221, 221, + 221, 221, nil, nil, nil, nil, nil, 221, 221, 221, + 221, 221, 221, 221, nil, nil, 221, nil, nil, nil, + nil, nil, nil, 221, nil, nil, 221, 221, 221, 221, + 221, 221, 221, 221, nil, 221, 221, 221, nil, 221, + 221, 221, 221, 221, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 221, nil, nil, 221, nil, nil, 221, + 221, nil, nil, 221, nil, 221, nil, nil, nil, 221, + nil, nil, nil, nil, nil, nil, nil, nil, 221, nil, + nil, nil, nil, 221, 221, 221, 221, nil, 221, 221, + 221, 221, nil, nil, nil, nil, 221, 221, nil, nil, + nil, 222, 222, 222, 221, 222, 221, 221, 221, 222, + 222, 221, 221, nil, 222, nil, 222, 222, 222, 222, + 222, 222, 222, nil, nil, nil, nil, nil, 222, 222, + 222, 222, 222, 222, 222, nil, nil, 222, nil, nil, + nil, nil, nil, nil, 222, nil, nil, 222, 222, 222, + 222, 222, 222, 222, 222, nil, 222, 222, 222, nil, + 222, 222, 222, 222, 222, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 222, nil, nil, 222, nil, nil, + 222, 222, nil, nil, 222, nil, nil, nil, nil, nil, + 222, nil, nil, nil, nil, nil, nil, nil, nil, 222, + nil, nil, nil, nil, 222, 222, 222, 222, nil, 222, + 222, 222, 222, nil, nil, nil, nil, 222, 222, nil, + nil, nil, 223, 223, 223, 222, 223, 222, 222, 222, + 223, 223, 222, 222, nil, 223, nil, 223, 223, 223, + 223, 223, 223, 223, nil, nil, nil, nil, nil, 223, + 223, 223, 223, 223, 223, 223, nil, nil, 223, nil, + nil, nil, nil, nil, nil, 223, nil, nil, 223, 223, + 223, 223, 223, 223, 223, 223, nil, 223, 223, 223, + nil, 223, 223, 223, 223, 223, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 223, nil, nil, 223, nil, + nil, 223, 223, nil, nil, 223, nil, nil, nil, nil, + nil, 223, nil, nil, nil, nil, nil, nil, nil, nil, + 223, nil, nil, nil, nil, 223, 223, 223, 223, nil, + 223, 223, 223, 223, nil, nil, nil, nil, 223, 223, + nil, nil, nil, 224, 224, 224, 223, 224, 223, 223, + 223, 224, 224, 223, 223, nil, 224, nil, 224, 224, + 224, 224, 224, 224, 224, nil, nil, nil, nil, nil, + 224, 224, 224, 224, 224, 224, 224, nil, nil, 224, + nil, nil, nil, nil, nil, nil, 224, nil, nil, 224, + 224, 224, 224, 224, 224, 224, 224, nil, 224, 224, + 224, nil, 224, 224, 224, 224, 224, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 224, nil, nil, 224, + nil, nil, 224, 224, nil, nil, 224, nil, nil, nil, + nil, nil, 224, nil, nil, nil, nil, nil, nil, nil, + nil, 224, nil, nil, nil, nil, 224, 224, 224, 224, + nil, 224, 224, 224, 224, nil, nil, nil, nil, 224, + 224, nil, nil, nil, 225, 225, 225, 224, 225, 224, + 224, 224, 225, 225, 224, 224, nil, 225, nil, 225, + 225, 225, 225, 225, 225, 225, nil, nil, nil, nil, + nil, 225, 225, 225, 225, 225, 225, 225, nil, nil, + 225, nil, nil, nil, nil, nil, nil, 225, nil, nil, + 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, + 225, 225, nil, 225, 225, 225, 225, 225, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 225, nil, nil, + 225, nil, nil, 225, 225, nil, nil, 225, nil, 225, + nil, 225, nil, 225, nil, nil, 225, nil, nil, nil, + nil, nil, 225, nil, nil, nil, nil, 225, 225, 225, + 225, nil, 225, 225, 225, 225, nil, nil, nil, nil, + 225, 225, nil, nil, nil, 238, 238, 238, 225, 238, + 225, 225, 225, 238, 238, 225, 225, nil, 238, nil, + 238, 238, 238, 238, 238, 238, 238, nil, nil, nil, + nil, nil, 238, 238, 238, 238, 238, 238, 238, nil, + nil, 238, nil, nil, nil, nil, nil, nil, 238, nil, + nil, 238, 238, 238, 238, 238, 238, 238, 238, nil, + 238, 238, 238, nil, 238, 238, 238, 238, 238, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 238, nil, + nil, 238, nil, nil, 238, 238, nil, nil, 238, nil, + nil, nil, nil, nil, 238, nil, nil, nil, nil, nil, + nil, nil, nil, 238, nil, nil, nil, nil, 238, 238, + 238, 238, nil, 238, 238, 238, 238, nil, nil, nil, + nil, 238, 238, nil, nil, nil, 239, 239, 239, 238, + 239, 238, 238, 238, 239, 239, 238, 238, nil, 239, + nil, 239, 239, 239, 239, 239, 239, 239, nil, nil, + nil, nil, nil, 239, 239, 239, 239, 239, 239, 239, + nil, nil, 239, nil, nil, nil, nil, nil, nil, 239, + nil, nil, 239, 239, 239, 239, 239, 239, 239, 239, + nil, 239, 239, 239, nil, 239, 239, 239, 239, 239, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 239, + nil, nil, 239, nil, nil, 239, 239, nil, nil, 239, + nil, nil, nil, nil, nil, 239, nil, nil, nil, nil, + nil, nil, nil, nil, 239, nil, nil, nil, nil, 239, + 239, 239, 239, nil, 239, 239, 239, 239, nil, nil, + nil, nil, 239, 239, nil, nil, nil, 240, 240, 240, + 239, 240, 239, 239, 239, 240, 240, 239, 239, nil, + 240, nil, 240, 240, 240, 240, 240, 240, 240, nil, + nil, nil, nil, nil, 240, 240, 240, 240, 240, 240, + 240, nil, nil, 240, nil, nil, nil, nil, nil, nil, + 240, nil, nil, 240, 240, 240, 240, 240, 240, 240, + 240, nil, 240, 240, 240, nil, 240, 240, 240, 240, + 240, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 240, nil, nil, 240, nil, nil, 240, 240, nil, nil, + 240, nil, nil, nil, nil, nil, 240, nil, nil, nil, + nil, nil, nil, nil, nil, 240, nil, nil, nil, nil, + 240, 240, 240, 240, nil, 240, 240, 240, 240, nil, + nil, nil, nil, 240, 240, 240, nil, nil, 251, 251, + 251, 240, 251, 240, 240, 240, 251, 251, 240, 240, + nil, 251, nil, 251, 251, 251, 251, 251, 251, 251, + nil, nil, nil, nil, nil, 251, 251, 251, 251, 251, + 251, 251, nil, nil, 251, nil, nil, nil, nil, nil, + nil, 251, nil, nil, 251, 251, 251, 251, 251, 251, + 251, 251, nil, 251, 251, 251, nil, 251, 251, 251, + 251, 251, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, 251, nil, nil, 251, 251, nil, + nil, 251, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 251, 251, 251, 251, nil, 251, 251, 251, 251, + nil, nil, nil, nil, 251, 251, nil, nil, nil, 258, + 258, 258, 251, 258, 251, 251, 251, 258, 258, 251, + 251, nil, 258, nil, 258, 258, 258, 258, 258, 258, + 258, nil, nil, nil, nil, nil, 258, 258, 258, 258, + 258, 258, 258, nil, nil, 258, nil, nil, nil, nil, + nil, nil, 258, nil, nil, 258, 258, 258, 258, 258, + 258, 258, 258, nil, 258, 258, 258, nil, 258, 258, + 258, 258, 258, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 258, nil, nil, 258, nil, nil, 258, 258, + nil, nil, 258, nil, nil, nil, nil, nil, 258, nil, + nil, nil, nil, nil, nil, nil, nil, 258, nil, nil, + nil, nil, 258, 258, 258, 258, nil, 258, 258, 258, + 258, nil, nil, nil, nil, 258, 258, nil, nil, nil, + 259, 259, 259, 258, 259, 258, 258, 258, 259, 259, + 258, 258, nil, 259, nil, 259, 259, 259, 259, 259, + 259, 259, nil, nil, nil, nil, nil, 259, 259, 259, + 259, 259, 259, 259, nil, nil, 259, nil, nil, nil, + nil, nil, nil, 259, nil, nil, 259, 259, 259, 259, + 259, 259, 259, 259, nil, 259, 259, 259, nil, 259, + 259, 259, 259, 259, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 259, nil, nil, 259, nil, nil, 259, + 259, nil, nil, 259, nil, nil, nil, nil, nil, 259, + nil, nil, nil, nil, nil, nil, nil, nil, 259, nil, + nil, nil, nil, 259, 259, 259, 259, nil, 259, 259, + 259, 259, nil, nil, nil, nil, 259, 259, nil, nil, + nil, 260, 260, 260, 259, 260, 259, 259, 259, 260, + 260, 259, 259, nil, 260, nil, 260, 260, 260, 260, + 260, 260, 260, nil, nil, nil, nil, nil, 260, 260, + 260, 260, 260, 260, 260, nil, nil, 260, nil, nil, + nil, nil, nil, nil, 260, nil, nil, 260, 260, 260, + 260, 260, 260, 260, 260, nil, 260, 260, 260, nil, + 260, 260, 260, 260, 260, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 260, nil, nil, 260, nil, nil, + 260, 260, nil, nil, 260, nil, nil, nil, nil, nil, + 260, nil, nil, nil, nil, nil, nil, nil, nil, 260, + nil, nil, nil, nil, 260, 260, 260, 260, nil, 260, + 260, 260, 260, nil, nil, nil, nil, 260, 260, nil, + nil, nil, 261, 261, 261, 260, 261, 260, 260, 260, + 261, 261, 260, 260, nil, 261, nil, 261, 261, 261, + 261, 261, 261, 261, nil, nil, nil, nil, nil, 261, + 261, 261, 261, 261, 261, 261, nil, nil, 261, nil, + nil, nil, nil, nil, nil, 261, nil, nil, 261, 261, + 261, 261, 261, 261, 261, 261, nil, 261, 261, 261, + nil, 261, 261, 261, 261, 261, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 261, nil, nil, 261, nil, + nil, 261, 261, nil, nil, 261, nil, nil, nil, nil, + nil, 261, nil, nil, nil, nil, nil, nil, nil, nil, + 261, nil, nil, nil, nil, 261, 261, 261, 261, nil, + 261, 261, 261, 261, nil, nil, nil, nil, 261, 261, + nil, nil, nil, 262, 262, 262, 261, 262, 261, 261, + 261, 262, 262, 261, 261, nil, 262, nil, 262, 262, + 262, 262, 262, 262, 262, nil, nil, nil, nil, nil, + 262, 262, 262, 262, 262, 262, 262, nil, nil, 262, + nil, nil, nil, nil, nil, nil, 262, nil, nil, 262, + 262, 262, 262, 262, 262, 262, 262, nil, 262, 262, + 262, nil, 262, 262, 262, 262, 262, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 262, nil, nil, 262, + nil, nil, 262, 262, nil, nil, 262, nil, nil, nil, + nil, nil, 262, nil, nil, nil, nil, nil, nil, nil, + nil, 262, nil, nil, nil, nil, 262, 262, 262, 262, + nil, 262, 262, 262, 262, nil, nil, nil, nil, 262, + 262, nil, nil, nil, 263, 263, 263, 262, 263, 262, + 262, 262, 263, 263, 262, 262, nil, 263, nil, 263, + 263, 263, 263, 263, 263, 263, nil, nil, nil, nil, + nil, 263, 263, 263, 263, 263, 263, 263, nil, nil, + 263, nil, nil, nil, nil, nil, nil, 263, nil, nil, + 263, 263, 263, 263, 263, 263, 263, 263, nil, 263, + 263, 263, nil, 263, 263, 263, 263, 263, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 263, nil, nil, + 263, nil, nil, 263, 263, nil, nil, 263, nil, nil, + nil, nil, nil, 263, nil, nil, nil, nil, nil, nil, + nil, nil, 263, nil, nil, nil, nil, 263, 263, 263, + 263, nil, 263, 263, 263, 263, nil, nil, nil, nil, + 263, 263, nil, nil, nil, 264, 264, 264, 263, 264, + 263, 263, 263, 264, 264, 263, 263, nil, 264, nil, + 264, 264, 264, 264, 264, 264, 264, nil, nil, nil, + nil, nil, 264, 264, 264, 264, 264, 264, 264, nil, + nil, 264, nil, nil, nil, nil, nil, nil, 264, nil, + nil, 264, 264, 264, 264, 264, 264, 264, 264, nil, + 264, 264, 264, nil, 264, 264, 264, 264, 264, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 264, nil, + nil, 264, nil, nil, 264, 264, nil, nil, 264, nil, + nil, nil, nil, nil, 264, nil, nil, nil, nil, nil, + nil, nil, nil, 264, nil, nil, nil, nil, 264, 264, + 264, 264, nil, 264, 264, 264, 264, nil, nil, nil, + nil, 264, 264, nil, nil, nil, 265, 265, 265, 264, + 265, 264, 264, 264, 265, 265, 264, 264, nil, 265, + nil, 265, 265, 265, 265, 265, 265, 265, nil, nil, + nil, nil, nil, 265, 265, 265, 265, 265, 265, 265, + nil, nil, 265, nil, nil, nil, nil, nil, nil, 265, + nil, nil, 265, 265, 265, 265, 265, 265, 265, 265, + nil, 265, 265, 265, nil, 265, 265, 265, 265, 265, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 265, + nil, nil, 265, nil, nil, 265, 265, nil, nil, 265, + nil, nil, nil, nil, nil, 265, nil, nil, nil, nil, + nil, nil, nil, nil, 265, nil, nil, nil, nil, 265, + 265, 265, 265, nil, 265, 265, 265, 265, nil, nil, + nil, nil, 265, 265, nil, nil, nil, 266, 266, 266, + 265, 266, 265, 265, 265, 266, 266, 265, 265, nil, + 266, nil, 266, 266, 266, 266, 266, 266, 266, nil, + nil, nil, nil, nil, 266, 266, 266, 266, 266, 266, + 266, nil, nil, 266, nil, nil, nil, nil, nil, nil, + 266, nil, nil, 266, 266, 266, 266, 266, 266, 266, + 266, nil, 266, 266, 266, nil, 266, 266, 266, 266, + 266, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 266, nil, nil, 266, nil, nil, 266, 266, nil, nil, + 266, nil, nil, nil, nil, nil, 266, nil, nil, nil, + nil, nil, nil, nil, nil, 266, nil, nil, nil, nil, + 266, 266, 266, 266, nil, 266, 266, 266, 266, nil, + nil, nil, nil, 266, 266, nil, nil, nil, 267, 267, + 267, 266, 267, 266, 266, 266, 267, 267, 266, 266, + nil, 267, nil, 267, 267, 267, 267, 267, 267, 267, + nil, nil, nil, nil, nil, 267, 267, 267, 267, 267, + 267, 267, nil, nil, 267, nil, nil, nil, nil, nil, + nil, 267, nil, nil, 267, 267, 267, 267, 267, 267, + 267, 267, nil, 267, 267, 267, nil, 267, 267, 267, + 267, 267, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 267, nil, nil, 267, nil, nil, 267, 267, nil, + nil, 267, nil, nil, nil, nil, nil, 267, nil, nil, + nil, nil, nil, nil, nil, nil, 267, nil, nil, nil, + nil, 267, 267, 267, 267, nil, 267, 267, 267, 267, + nil, nil, nil, nil, 267, 267, nil, nil, nil, 268, + 268, 268, 267, 268, 267, 267, 267, 268, 268, 267, + 267, nil, 268, nil, 268, 268, 268, 268, 268, 268, + 268, nil, nil, nil, nil, nil, 268, 268, 268, 268, + 268, 268, 268, nil, nil, 268, nil, nil, nil, nil, + nil, nil, 268, nil, nil, 268, 268, 268, 268, 268, + 268, 268, 268, nil, 268, 268, 268, nil, 268, 268, + 268, 268, 268, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 268, nil, nil, 268, nil, nil, 268, 268, + nil, nil, 268, nil, nil, nil, nil, nil, 268, nil, + nil, nil, nil, nil, nil, nil, nil, 268, nil, nil, + nil, nil, 268, 268, 268, 268, nil, 268, 268, 268, + 268, nil, nil, nil, nil, 268, 268, nil, nil, nil, + 269, 269, 269, 268, 269, 268, 268, 268, 269, 269, + 268, 268, nil, 269, nil, 269, 269, 269, 269, 269, + 269, 269, nil, nil, nil, nil, nil, 269, 269, 269, + 269, 269, 269, 269, nil, nil, 269, nil, nil, nil, + nil, nil, nil, 269, nil, nil, 269, 269, 269, 269, + 269, 269, 269, 269, nil, 269, 269, 269, nil, 269, + 269, 269, 269, 269, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 269, nil, nil, 269, nil, nil, 269, + 269, nil, nil, 269, nil, nil, nil, nil, nil, 269, + nil, nil, nil, nil, nil, nil, nil, nil, 269, nil, + nil, nil, nil, 269, 269, 269, 269, nil, 269, 269, + 269, 269, nil, nil, nil, nil, 269, 269, nil, nil, + nil, 270, 270, 270, 269, 270, 269, 269, 269, 270, + 270, 269, 269, nil, 270, nil, 270, 270, 270, 270, + 270, 270, 270, nil, nil, nil, nil, nil, 270, 270, + 270, 270, 270, 270, 270, nil, nil, 270, nil, nil, + nil, nil, nil, nil, 270, nil, nil, 270, 270, 270, + 270, 270, 270, 270, 270, nil, 270, 270, 270, nil, + 270, 270, 270, 270, 270, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 270, nil, nil, 270, nil, nil, + 270, 270, nil, nil, 270, nil, nil, nil, nil, nil, + 270, nil, nil, nil, nil, nil, nil, nil, nil, 270, + nil, nil, nil, nil, 270, 270, 270, 270, nil, 270, + 270, 270, 270, nil, nil, nil, nil, 270, 270, nil, + nil, nil, 271, 271, 271, 270, 271, 270, 270, 270, + 271, 271, 270, 270, nil, 271, nil, 271, 271, 271, + 271, 271, 271, 271, nil, nil, nil, nil, nil, 271, + 271, 271, 271, 271, 271, 271, nil, nil, 271, nil, + nil, nil, nil, nil, nil, 271, nil, nil, 271, 271, + 271, 271, 271, 271, 271, 271, nil, 271, 271, 271, + nil, 271, 271, 271, 271, 271, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 271, nil, nil, 271, nil, + nil, 271, 271, nil, nil, 271, nil, nil, nil, nil, + nil, 271, nil, nil, nil, nil, nil, nil, nil, nil, + 271, nil, nil, nil, nil, 271, 271, 271, 271, nil, + 271, 271, 271, 271, nil, nil, nil, nil, 271, 271, + nil, nil, nil, 272, 272, 272, 271, 272, 271, 271, + 271, 272, 272, 271, 271, nil, 272, nil, 272, 272, + 272, 272, 272, 272, 272, nil, nil, nil, nil, nil, + 272, 272, 272, 272, 272, 272, 272, nil, nil, 272, + nil, nil, nil, nil, nil, nil, 272, nil, nil, 272, + 272, 272, 272, 272, 272, 272, 272, nil, 272, 272, + 272, nil, 272, 272, 272, 272, 272, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 272, nil, nil, 272, + nil, nil, 272, 272, nil, nil, 272, nil, nil, nil, + nil, nil, 272, nil, nil, nil, nil, nil, nil, nil, + nil, 272, nil, nil, nil, nil, 272, 272, 272, 272, + nil, 272, 272, 272, 272, nil, nil, nil, nil, 272, + 272, nil, nil, nil, 273, 273, 273, 272, 273, 272, + 272, 272, 273, 273, 272, 272, nil, 273, nil, 273, + 273, 273, 273, 273, 273, 273, nil, nil, nil, nil, + nil, 273, 273, 273, 273, 273, 273, 273, nil, nil, + 273, nil, nil, nil, nil, nil, nil, 273, nil, nil, + 273, 273, 273, 273, 273, 273, 273, 273, nil, 273, + 273, 273, nil, 273, 273, 273, 273, 273, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 273, nil, nil, + 273, nil, nil, 273, 273, nil, nil, 273, nil, nil, + nil, nil, nil, 273, nil, nil, nil, nil, nil, nil, + nil, nil, 273, nil, nil, nil, nil, 273, 273, 273, + 273, nil, 273, 273, 273, 273, nil, nil, nil, nil, + 273, 273, nil, nil, nil, 274, 274, 274, 273, 274, + 273, 273, 273, 274, 274, 273, 273, nil, 274, nil, + 274, 274, 274, 274, 274, 274, 274, nil, nil, nil, + nil, nil, 274, 274, 274, 274, 274, 274, 274, nil, + nil, 274, nil, nil, nil, nil, nil, nil, 274, nil, + nil, 274, 274, 274, 274, 274, 274, 274, 274, nil, + 274, 274, 274, nil, 274, 274, 274, 274, 274, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 274, nil, + nil, 274, nil, nil, 274, 274, nil, nil, 274, nil, + nil, nil, nil, nil, 274, nil, nil, nil, nil, nil, + nil, nil, nil, 274, nil, nil, nil, nil, 274, 274, + 274, 274, nil, 274, 274, 274, 274, nil, nil, nil, + nil, 274, 274, nil, nil, nil, 275, 275, 275, 274, + 275, 274, 274, 274, 275, 275, 274, 274, nil, 275, + nil, 275, 275, 275, 275, 275, 275, 275, nil, nil, + nil, nil, nil, 275, 275, 275, 275, 275, 275, 275, + nil, nil, 275, nil, nil, nil, nil, nil, nil, 275, + nil, nil, 275, 275, 275, 275, 275, 275, 275, 275, + nil, 275, 275, 275, nil, 275, 275, 275, 275, 275, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 275, + nil, nil, 275, nil, nil, 275, 275, nil, nil, 275, + nil, nil, nil, nil, nil, 275, nil, nil, nil, nil, + nil, nil, nil, nil, 275, nil, nil, nil, nil, 275, + 275, 275, 275, nil, 275, 275, 275, 275, nil, nil, + nil, nil, 275, 275, nil, nil, nil, 276, 276, 276, + 275, 276, 275, 275, 275, 276, 276, 275, 275, nil, + 276, nil, 276, 276, 276, 276, 276, 276, 276, nil, + nil, nil, nil, nil, 276, 276, 276, 276, 276, 276, + 276, nil, nil, 276, nil, nil, nil, nil, nil, nil, + 276, nil, nil, 276, 276, 276, 276, 276, 276, 276, + 276, nil, 276, 276, 276, nil, 276, 276, 276, 276, + 276, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 276, nil, nil, 276, nil, nil, 276, 276, nil, nil, + 276, nil, nil, nil, nil, nil, 276, nil, nil, nil, + nil, nil, nil, nil, nil, 276, nil, nil, nil, nil, + 276, 276, 276, 276, nil, 276, 276, 276, 276, nil, + nil, nil, nil, 276, 276, nil, nil, nil, 277, 277, + 277, 276, 277, 276, 276, 276, 277, 277, 276, 276, + nil, 277, nil, 277, 277, 277, 277, 277, 277, 277, + nil, nil, nil, nil, nil, 277, 277, 277, 277, 277, + 277, 277, nil, nil, 277, nil, nil, nil, nil, nil, + nil, 277, nil, nil, 277, 277, 277, 277, 277, 277, + 277, 277, nil, 277, 277, 277, nil, 277, 277, 277, + 277, 277, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 277, nil, nil, 277, nil, nil, 277, 277, nil, + nil, 277, nil, nil, nil, nil, nil, 277, nil, nil, + nil, nil, nil, nil, nil, nil, 277, nil, nil, nil, + nil, 277, 277, 277, 277, nil, 277, 277, 277, 277, + nil, nil, nil, nil, 277, 277, nil, nil, nil, 278, + 278, 278, 277, 278, 277, 277, 277, 278, 278, 277, + 277, nil, 278, nil, 278, 278, 278, 278, 278, 278, + 278, nil, nil, nil, nil, nil, 278, 278, 278, 278, + 278, 278, 278, nil, nil, 278, nil, nil, nil, nil, + nil, nil, 278, nil, nil, 278, 278, 278, 278, 278, + 278, 278, 278, nil, 278, 278, 278, nil, 278, 278, + 278, 278, 278, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 278, nil, nil, 278, nil, nil, 278, 278, + nil, nil, 278, nil, nil, nil, nil, nil, 278, nil, + nil, nil, nil, nil, nil, nil, nil, 278, nil, nil, + nil, nil, 278, 278, 278, 278, nil, 278, 278, 278, + 278, nil, nil, nil, nil, 278, 278, nil, nil, nil, + 279, 279, 279, 278, 279, 278, 278, 278, 279, 279, + 278, 278, nil, 279, nil, 279, 279, 279, 279, 279, + 279, 279, nil, nil, nil, nil, nil, 279, 279, 279, + 279, 279, 279, 279, nil, nil, 279, nil, nil, nil, + nil, nil, nil, 279, nil, nil, 279, 279, 279, 279, + 279, 279, 279, 279, nil, 279, 279, 279, nil, 279, + 279, 279, 279, 279, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 279, nil, nil, 279, nil, nil, 279, + 279, nil, nil, 279, nil, nil, nil, nil, nil, 279, + nil, nil, nil, nil, nil, nil, nil, nil, 279, nil, + nil, nil, nil, 279, 279, 279, 279, nil, 279, 279, + 279, 279, nil, nil, nil, nil, 279, 279, nil, nil, + nil, 284, 284, 284, 279, 284, 279, 279, 279, 284, + 284, 279, 279, nil, 284, nil, 284, 284, 284, 284, + 284, 284, 284, nil, nil, nil, nil, nil, 284, 284, + 284, 284, 284, 284, 284, nil, nil, 284, nil, nil, + nil, nil, nil, nil, 284, nil, nil, 284, 284, 284, + 284, 284, 284, 284, 284, nil, 284, 284, 284, nil, + 284, 284, 284, 284, 284, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 284, nil, nil, 284, nil, nil, + 284, 284, nil, nil, 284, nil, nil, nil, nil, nil, + 284, nil, nil, nil, nil, nil, nil, nil, nil, 284, + nil, nil, nil, nil, 284, 284, 284, 284, nil, 284, + 284, 284, 284, nil, nil, nil, nil, 284, 284, nil, + nil, nil, 300, 300, 300, 284, 300, 284, 284, 284, + 300, 300, 284, 284, nil, 300, nil, 300, 300, 300, + 300, 300, 300, 300, nil, nil, nil, nil, nil, 300, + 300, 300, 300, 300, 300, 300, nil, nil, 300, nil, + nil, nil, nil, nil, nil, 300, nil, nil, 300, 300, + 300, 300, 300, 300, 300, 300, nil, 300, 300, 300, + nil, 300, 300, 300, 300, 300, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 300, nil, nil, 300, nil, + nil, 300, 300, nil, nil, 300, nil, nil, nil, nil, + nil, 300, nil, nil, nil, nil, nil, nil, nil, nil, + 300, nil, nil, nil, nil, 300, 300, 300, 300, nil, + 300, 300, 300, 300, nil, nil, nil, nil, 300, 300, + nil, nil, nil, 307, 307, 307, 300, 307, 300, 300, + 300, 307, 307, 300, 300, nil, 307, nil, 307, 307, + 307, 307, 307, 307, 307, nil, nil, nil, nil, nil, + 307, 307, 307, 307, 307, 307, 307, nil, nil, 307, + nil, nil, nil, nil, nil, nil, 307, nil, nil, 307, + 307, 307, 307, 307, 307, 307, 307, 307, 307, 307, + 307, nil, 307, 307, 307, 307, 307, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 307, nil, nil, 307, + nil, nil, 307, 307, nil, nil, 307, nil, 307, nil, + 307, nil, 307, nil, nil, 307, nil, nil, nil, nil, + nil, 307, nil, nil, nil, nil, 307, 307, 307, 307, + nil, 307, 307, 307, 307, nil, nil, nil, nil, 307, + 307, nil, nil, nil, 308, 308, 308, 307, 308, 307, + 307, 307, 308, 308, 307, 307, nil, 308, nil, 308, + 308, 308, 308, 308, 308, 308, nil, nil, nil, nil, + nil, 308, 308, 308, 308, 308, 308, 308, nil, nil, + 308, nil, nil, nil, nil, nil, nil, 308, nil, nil, + 308, 308, 308, 308, 308, 308, 308, 308, 308, 308, + 308, 308, nil, 308, 308, 308, 308, 308, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 308, nil, nil, + 308, nil, nil, 308, 308, nil, nil, 308, nil, 308, + nil, 308, nil, 308, nil, nil, 308, nil, nil, nil, + nil, nil, 308, nil, nil, nil, nil, 308, 308, 308, + 308, nil, 308, 308, 308, 308, nil, nil, nil, nil, + 308, 308, nil, nil, nil, 316, 316, 316, 308, 316, + 308, 308, 308, 316, 316, 308, 308, nil, 316, nil, + 316, 316, 316, 316, 316, 316, 316, nil, nil, nil, + nil, nil, 316, 316, 316, 316, 316, 316, 316, nil, + nil, 316, nil, nil, nil, nil, nil, nil, 316, nil, + nil, 316, 316, 316, 316, 316, 316, 316, 316, 316, + 316, 316, 316, nil, 316, 316, 316, 316, 316, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 316, nil, + nil, 316, nil, nil, 316, 316, nil, nil, 316, nil, + 316, nil, 316, nil, 316, nil, nil, 316, nil, nil, + nil, nil, nil, 316, nil, nil, nil, nil, 316, 316, + 316, 316, nil, 316, 316, 316, 316, nil, nil, nil, + nil, 316, 316, 316, nil, nil, 323, 323, 323, 316, + 323, 316, 316, 316, 323, 323, 316, 316, nil, 323, + nil, 323, 323, 323, 323, 323, 323, 323, nil, nil, + nil, nil, nil, 323, 323, 323, 323, 323, 323, 323, + nil, nil, 323, nil, nil, nil, nil, nil, nil, 323, + nil, nil, 323, 323, 323, 323, 323, 323, 323, 323, + nil, 323, 323, 323, nil, 323, 323, 323, 323, 323, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 323, + nil, nil, 323, nil, nil, 323, 323, nil, nil, 323, + nil, nil, nil, nil, nil, 323, nil, nil, nil, nil, + nil, nil, nil, nil, 323, nil, nil, nil, nil, 323, + 323, 323, 323, nil, 323, 323, 323, 323, nil, nil, + nil, nil, 323, 323, nil, nil, nil, 325, 325, 325, + 323, 325, 323, 323, 323, 325, 325, 323, 323, nil, + 325, nil, 325, 325, 325, 325, 325, 325, 325, nil, + nil, nil, nil, nil, 325, 325, 325, 325, 325, 325, + 325, nil, nil, 325, nil, nil, nil, nil, nil, nil, + 325, nil, nil, 325, 325, 325, 325, 325, 325, 325, + 325, nil, 325, 325, 325, nil, 325, 325, 325, 325, + 325, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 325, nil, nil, 325, nil, nil, 325, 325, nil, nil, + 325, nil, nil, nil, nil, nil, 325, nil, nil, nil, + nil, nil, nil, nil, nil, 325, nil, nil, nil, nil, + 325, 325, 325, 325, nil, 325, 325, 325, 325, nil, + nil, nil, nil, 325, 325, nil, nil, nil, 328, 328, + 328, 325, 328, 325, 325, 325, 328, 328, 325, 325, + nil, 328, nil, 328, 328, 328, 328, 328, 328, 328, + nil, nil, nil, nil, nil, 328, 328, 328, 328, 328, + 328, 328, nil, nil, 328, nil, nil, nil, nil, nil, + nil, 328, nil, nil, 328, 328, 328, 328, 328, 328, + 328, 328, nil, 328, 328, 328, nil, 328, 328, 328, + 328, 328, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 328, nil, nil, 328, nil, nil, 328, 328, nil, + nil, 328, nil, nil, nil, nil, nil, 328, nil, nil, + nil, nil, nil, nil, nil, nil, 328, nil, nil, nil, + nil, 328, 328, 328, 328, nil, 328, 328, 328, 328, + nil, nil, nil, nil, 328, 328, nil, nil, nil, 329, + 329, 329, 328, 329, 328, 328, 328, 329, 329, 328, + 328, nil, 329, nil, 329, 329, 329, 329, 329, 329, + 329, nil, nil, nil, nil, nil, 329, 329, 329, 329, + 329, 329, 329, nil, nil, 329, nil, nil, nil, nil, + nil, nil, 329, nil, nil, 329, 329, 329, 329, 329, + 329, 329, 329, nil, 329, 329, 329, nil, 329, 329, + 329, 329, 329, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 329, nil, nil, 329, nil, nil, 329, 329, + nil, nil, 329, nil, nil, nil, nil, nil, 329, nil, + nil, nil, nil, nil, nil, nil, nil, 329, nil, nil, + nil, nil, 329, 329, 329, 329, nil, 329, 329, 329, + 329, nil, nil, nil, nil, 329, 329, nil, nil, nil, + nil, nil, nil, 329, nil, 329, 329, 329, nil, nil, + 329, 329, 334, 334, 334, 334, 334, nil, nil, nil, + 334, 334, nil, nil, nil, 334, nil, 334, 334, 334, + 334, 334, 334, 334, nil, nil, nil, nil, nil, 334, + 334, 334, 334, 334, 334, 334, nil, nil, 334, nil, + nil, nil, nil, nil, 334, 334, nil, 334, 334, 334, + 334, 334, 334, 334, 334, 334, nil, 334, 334, 334, + nil, 334, 334, 334, 334, 334, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 334, nil, nil, 334, nil, + nil, 334, 334, nil, nil, 334, nil, 334, nil, nil, + nil, 334, nil, nil, nil, nil, nil, nil, nil, nil, + 334, nil, nil, nil, nil, 334, 334, 334, 334, nil, + 334, 334, 334, 334, nil, nil, nil, nil, 334, 334, + nil, nil, nil, 370, 370, 370, 334, 370, 334, 334, + 334, 370, 370, 334, 334, nil, 370, nil, 370, 370, + 370, 370, 370, 370, 370, nil, nil, nil, nil, nil, + 370, 370, 370, 370, 370, 370, 370, nil, nil, 370, + nil, nil, nil, nil, nil, nil, 370, nil, nil, 370, + 370, 370, 370, 370, 370, 370, 370, nil, 370, 370, + 370, nil, 370, 370, 370, 370, 370, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 370, nil, nil, 370, + nil, nil, 370, 370, nil, nil, 370, nil, nil, nil, + nil, nil, 370, nil, nil, nil, nil, nil, nil, nil, + nil, 370, nil, nil, nil, nil, 370, 370, 370, 370, + nil, 370, 370, 370, 370, nil, nil, nil, nil, 370, + 370, nil, nil, nil, 387, 387, 387, 370, 387, 370, + 370, 370, 387, 387, 370, 370, nil, 387, nil, 387, + 387, 387, 387, 387, 387, 387, nil, nil, nil, nil, + nil, 387, 387, 387, 387, 387, 387, 387, nil, nil, + 387, nil, nil, nil, nil, nil, nil, 387, nil, nil, + 387, 387, 387, 387, 387, 387, 387, 387, nil, 387, + 387, 387, nil, 387, 387, 387, 387, 387, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 387, nil, nil, + 387, nil, nil, 387, 387, nil, nil, 387, nil, nil, + nil, nil, nil, 387, nil, nil, nil, nil, nil, nil, + nil, nil, 387, nil, nil, nil, nil, 387, 387, 387, + 387, nil, 387, 387, 387, 387, nil, nil, nil, nil, + 387, 387, nil, nil, nil, 408, 408, 408, 387, 408, + 387, 387, 387, 408, 408, 387, 387, nil, 408, nil, + 408, 408, 408, 408, 408, 408, 408, nil, nil, nil, + nil, nil, 408, 408, 408, 408, 408, 408, 408, nil, + nil, 408, nil, nil, nil, nil, nil, nil, 408, nil, + nil, 408, 408, 408, 408, 408, 408, 408, 408, nil, + 408, 408, 408, nil, 408, 408, 408, 408, 408, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 408, nil, + nil, 408, nil, nil, 408, 408, nil, nil, 408, nil, + nil, nil, nil, nil, 408, nil, nil, nil, nil, nil, + nil, nil, nil, 408, nil, nil, nil, nil, 408, 408, + 408, 408, nil, 408, 408, 408, 408, nil, nil, nil, + nil, 408, 408, nil, nil, nil, 437, 437, 437, 408, + 437, 408, 408, 408, 437, 437, 408, 408, nil, 437, + nil, 437, 437, 437, 437, 437, 437, 437, nil, nil, + nil, nil, nil, 437, 437, 437, 437, 437, 437, 437, + nil, nil, 437, nil, nil, nil, nil, nil, nil, 437, + nil, nil, 437, 437, 437, 437, 437, 437, 437, 437, + nil, 437, 437, 437, nil, 437, 437, 437, 437, 437, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 437, + nil, nil, 437, nil, nil, 437, 437, nil, nil, 437, + nil, nil, nil, nil, nil, 437, nil, nil, nil, nil, + nil, nil, nil, nil, 437, nil, nil, nil, nil, 437, + 437, 437, 437, nil, 437, 437, 437, 437, nil, nil, + nil, nil, 437, 437, nil, nil, nil, nil, nil, nil, + 437, nil, 437, 437, 437, 461, nil, 437, 437, nil, + nil, nil, 461, 461, 461, nil, nil, 461, 461, 461, + nil, 461, nil, nil, nil, nil, nil, nil, nil, 461, + 461, 461, 461, nil, nil, nil, nil, nil, nil, nil, + nil, 461, 461, nil, 461, 461, 461, 461, 461, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 461, 461, 461, 461, 461, 461, 461, 461, 461, + 461, 461, 461, 461, 461, nil, nil, 461, 461, 461, + nil, nil, 461, nil, 461, 461, nil, nil, 461, 461, + nil, 461, nil, 461, nil, 461, nil, 461, 461, nil, + 461, 461, 461, 461, 461, nil, 461, 461, 461, 1138, + nil, 1138, 1138, 1138, 1138, 1138, nil, nil, nil, nil, + nil, nil, 461, nil, 1138, 461, 461, 471, 461, nil, + 461, nil, nil, nil, 471, 471, 471, 461, nil, 471, + 471, 471, nil, 471, nil, nil, 1138, nil, nil, nil, + nil, 471, 471, 471, 471, 471, nil, 1138, 1138, nil, + nil, nil, 1138, 471, 471, nil, 471, 471, 471, 471, + 471, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 471, 471, 471, 471, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, nil, nil, 471, + 471, 471, nil, nil, 471, nil, nil, 471, nil, nil, + 471, 471, nil, 471, nil, 471, nil, 471, nil, 471, + 471, nil, 471, 471, 471, 471, 471, nil, 471, 471, + 471, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 471, nil, nil, 471, 471, 471, + 471, nil, 471, 472, 471, nil, nil, nil, nil, 471, + 472, 472, 472, nil, nil, 472, 472, 472, nil, 472, + nil, nil, nil, nil, nil, nil, nil, 472, 472, 472, + 472, 472, nil, nil, nil, nil, nil, nil, nil, 472, + 472, nil, 472, 472, 472, 472, 472, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 472, + 472, 472, 472, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, nil, nil, 472, 472, 472, nil, nil, + 472, nil, nil, 472, nil, nil, 472, 472, nil, 472, + nil, 472, nil, 472, nil, 472, 472, nil, 472, 472, + 472, 472, 472, nil, 472, 472, 472, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 472, nil, nil, 472, 472, 472, 472, nil, 472, nil, + 472, nil, 473, 473, 473, 472, 473, nil, nil, nil, + 473, 473, nil, nil, nil, 473, nil, 473, 473, 473, + 473, 473, 473, 473, nil, nil, nil, nil, nil, 473, + 473, 473, 473, 473, 473, 473, nil, nil, 473, nil, + nil, nil, nil, nil, nil, 473, nil, nil, 473, 473, + 473, 473, 473, 473, 473, 473, nil, 473, 473, 473, + nil, 473, 473, 473, 473, 473, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 473, nil, nil, 473, nil, + nil, 473, 473, nil, nil, 473, nil, nil, nil, nil, + nil, 473, nil, nil, nil, nil, nil, nil, nil, nil, + 473, nil, nil, nil, nil, 473, 473, 473, 473, nil, + 473, 473, 473, 473, nil, nil, nil, nil, 473, 473, + nil, nil, nil, 500, 500, 500, 473, 500, 473, 473, + 473, 500, 500, 473, 473, nil, 500, nil, 500, 500, + 500, 500, 500, 500, 500, nil, nil, nil, nil, nil, + 500, 500, 500, 500, 500, 500, 500, nil, nil, 500, + nil, nil, nil, nil, nil, nil, 500, nil, nil, 500, + 500, 500, 500, 500, 500, 500, 500, nil, 500, 500, + 500, nil, 500, 500, 500, 500, 500, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 500, nil, nil, 500, + nil, nil, 500, 500, nil, nil, 500, nil, nil, nil, + nil, nil, 500, nil, nil, nil, nil, nil, nil, nil, + nil, 500, nil, nil, nil, nil, 500, 500, 500, 500, + nil, 500, 500, 500, 500, nil, nil, nil, nil, 500, + 500, nil, nil, nil, 513, 513, 513, 500, 513, 500, + 500, 500, 513, 513, 500, 500, nil, 513, nil, 513, + 513, 513, 513, 513, 513, 513, nil, nil, nil, nil, + nil, 513, 513, 513, 513, 513, 513, 513, nil, nil, + 513, nil, nil, nil, nil, nil, nil, 513, nil, nil, + 513, 513, 513, 513, 513, 513, 513, 513, nil, 513, + 513, 513, nil, 513, 513, 513, 513, 513, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 513, nil, nil, + 513, nil, nil, 513, 513, nil, nil, 513, nil, nil, + nil, nil, nil, 513, nil, nil, nil, nil, nil, nil, + nil, nil, 513, nil, nil, nil, nil, 513, 513, 513, + 513, nil, 513, 513, 513, 513, nil, nil, nil, nil, + 513, 513, nil, nil, nil, 523, 523, 523, 513, 523, + 513, 513, 513, 523, 523, 513, 513, nil, 523, nil, + 523, 523, 523, 523, 523, 523, 523, nil, nil, nil, + nil, nil, 523, 523, 523, 523, 523, 523, 523, nil, + nil, 523, nil, nil, nil, nil, nil, nil, 523, nil, + nil, 523, 523, 523, 523, 523, 523, 523, 523, 523, + 523, 523, 523, nil, 523, 523, 523, 523, 523, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 523, nil, + nil, 523, nil, nil, 523, 523, nil, nil, 523, nil, + 523, nil, 523, nil, 523, nil, nil, 523, nil, nil, + nil, nil, nil, 523, nil, nil, nil, nil, 523, 523, + 523, 523, nil, 523, 523, 523, 523, nil, nil, nil, + nil, 523, 523, nil, nil, nil, 525, 525, 525, 523, + 525, 523, 523, 523, 525, 525, 523, 523, nil, 525, + nil, 525, 525, 525, 525, 525, 525, 525, nil, nil, + nil, nil, nil, 525, 525, 525, 525, 525, 525, 525, + nil, nil, 525, nil, nil, nil, nil, nil, nil, 525, + nil, nil, 525, 525, 525, 525, 525, 525, 525, 525, + nil, 525, 525, 525, nil, 525, 525, 525, 525, 525, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 525, + nil, nil, 525, nil, nil, 525, 525, nil, nil, 525, + nil, nil, nil, nil, nil, 525, nil, nil, nil, nil, + nil, nil, nil, nil, 525, nil, nil, nil, nil, 525, + 525, 525, 525, nil, 525, 525, 525, 525, nil, nil, + nil, nil, 525, 525, nil, nil, nil, 526, 526, 526, + 525, 526, 525, 525, 525, 526, 526, 525, 525, nil, + 526, nil, 526, 526, 526, 526, 526, 526, 526, nil, + nil, nil, nil, nil, 526, 526, 526, 526, 526, 526, + 526, nil, nil, 526, nil, nil, nil, nil, nil, nil, + 526, nil, nil, 526, 526, 526, 526, 526, 526, 526, + 526, nil, 526, 526, 526, nil, 526, 526, 526, 526, + 526, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 526, nil, nil, 526, nil, nil, 526, 526, nil, nil, + 526, nil, nil, nil, nil, nil, 526, nil, nil, nil, + nil, nil, nil, nil, nil, 526, nil, nil, nil, nil, + 526, 526, 526, 526, nil, 526, 526, 526, 526, nil, + nil, nil, nil, 526, 526, nil, nil, nil, 527, 527, + 527, 526, 527, 526, 526, 526, 527, 527, 526, 526, + nil, 527, nil, 527, 527, 527, 527, 527, 527, 527, + nil, nil, nil, nil, nil, 527, 527, 527, 527, 527, + 527, 527, nil, nil, 527, nil, nil, nil, nil, nil, + nil, 527, nil, nil, 527, 527, 527, 527, 527, 527, + 527, 527, nil, 527, 527, 527, nil, 527, 527, 527, + 527, 527, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 527, nil, nil, 527, nil, nil, 527, 527, nil, + nil, 527, nil, nil, nil, nil, nil, 527, nil, nil, + nil, nil, nil, nil, nil, nil, 527, nil, nil, nil, + nil, 527, 527, 527, 527, nil, 527, 527, 527, 527, + nil, nil, nil, nil, 527, 527, nil, nil, nil, nil, + nil, nil, 527, nil, 527, 527, 527, 558, nil, 527, + 527, nil, nil, nil, 558, 558, 558, nil, nil, 558, + 558, 558, 410, 558, 410, 410, 410, 410, 410, nil, + nil, 558, 558, 558, nil, nil, nil, 410, nil, nil, + nil, nil, nil, 558, 558, nil, 558, 558, 558, 558, + 558, nil, 647, nil, 647, 647, 647, 647, 647, 410, + 410, nil, nil, nil, nil, nil, nil, 647, 410, 410, + 410, 410, nil, nil, nil, 410, nil, 1133, nil, 1133, + 1133, 1133, 1133, 1133, 558, nil, nil, nil, nil, 647, + nil, 558, 1133, nil, nil, nil, 558, 558, 647, 647, + 647, 647, nil, nil, nil, 647, nil, nil, nil, nil, + nil, nil, nil, nil, 1133, 410, nil, nil, nil, 558, + 558, nil, nil, 1133, 1133, 1133, 1133, nil, nil, nil, + 1133, nil, nil, nil, 558, nil, nil, 558, nil, 563, + 563, 563, 558, 563, nil, 647, nil, 563, 563, 558, + nil, nil, 563, nil, 563, 563, 563, 563, 563, 563, + 563, nil, nil, nil, nil, nil, 563, 563, 563, 563, + 563, 563, 563, nil, nil, 563, nil, nil, nil, nil, + nil, nil, 563, nil, nil, 563, 563, 563, 563, 563, + 563, 563, 563, nil, 563, 563, 563, nil, 563, 563, + 563, 563, 563, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 563, nil, nil, 563, nil, nil, 563, 563, + nil, nil, 563, nil, nil, nil, nil, nil, 563, nil, + nil, nil, nil, nil, nil, nil, nil, 563, nil, nil, + nil, nil, 563, 563, 563, 563, nil, 563, 563, 563, + 563, nil, nil, nil, nil, 563, 563, nil, nil, nil, + 573, 573, 573, 563, 573, 563, 563, 563, 573, 573, + 563, 563, nil, 573, nil, 573, 573, 573, 573, 573, + 573, 573, nil, nil, nil, nil, nil, 573, 573, 573, + 573, 573, 573, 573, nil, nil, 573, nil, nil, nil, + nil, nil, nil, 573, nil, nil, 573, 573, 573, 573, + 573, 573, 573, 573, 573, 573, 573, 573, nil, 573, + 573, 573, 573, 573, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 573, nil, nil, 573, nil, nil, 573, + 573, nil, nil, 573, nil, 573, nil, 573, nil, 573, + nil, nil, 573, nil, nil, nil, nil, nil, 573, nil, + nil, nil, nil, 573, 573, 573, 573, nil, 573, 573, + 573, 573, nil, nil, nil, nil, 573, 573, nil, nil, + nil, 575, 575, 575, 573, 575, 573, 573, 573, 575, + 575, 573, 573, nil, 575, nil, 575, 575, 575, 575, + 575, 575, 575, nil, nil, nil, nil, nil, 575, 575, + 575, 575, 575, 575, 575, nil, nil, 575, nil, nil, + nil, nil, nil, nil, 575, nil, nil, 575, 575, 575, + 575, 575, 575, 575, 575, 575, 575, 575, 575, nil, + 575, 575, 575, 575, 575, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 575, nil, nil, 575, nil, nil, + 575, 575, nil, nil, 575, nil, nil, nil, 575, nil, + 575, nil, nil, 575, nil, nil, nil, nil, nil, 575, + nil, nil, nil, nil, 575, 575, 575, 575, nil, 575, + 575, 575, 575, nil, nil, nil, nil, 575, 575, nil, + nil, nil, 577, 577, 577, 575, 577, 575, 575, 575, + 577, 577, 575, 575, nil, 577, nil, 577, 577, 577, + 577, 577, 577, 577, nil, nil, nil, nil, nil, 577, + 577, 577, 577, 577, 577, 577, nil, nil, 577, nil, + nil, nil, nil, nil, nil, 577, nil, nil, 577, 577, + 577, 577, 577, 577, 577, 577, nil, 577, 577, 577, + nil, 577, 577, 577, 577, 577, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 577, nil, nil, 577, nil, + nil, 577, 577, nil, nil, 577, nil, nil, nil, nil, + nil, 577, nil, nil, nil, nil, nil, nil, nil, nil, + 577, nil, nil, nil, nil, 577, 577, 577, 577, nil, + 577, 577, 577, 577, nil, nil, nil, nil, 577, 577, + nil, nil, nil, nil, nil, nil, 577, nil, 577, 577, + 577, nil, nil, 577, 577, 583, 583, 583, 583, 583, + nil, nil, nil, 583, 583, nil, nil, nil, 583, nil, + 583, 583, 583, 583, 583, 583, 583, nil, nil, nil, + nil, nil, 583, 583, 583, 583, 583, 583, 583, nil, + nil, 583, nil, nil, nil, nil, nil, 583, 583, 583, + 583, 583, 583, 583, 583, 583, 583, 583, 583, nil, + 583, 583, 583, nil, 583, 583, 583, 583, 583, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 583, nil, + nil, 583, nil, nil, 583, 583, nil, nil, 583, nil, + 583, nil, nil, nil, 583, nil, nil, nil, nil, nil, + nil, nil, nil, 583, nil, nil, nil, nil, 583, 583, + 583, 583, nil, 583, 583, 583, 583, nil, nil, nil, + nil, 583, 583, nil, nil, nil, nil, nil, 583, 583, + nil, 583, 583, 583, nil, nil, 583, 583, 593, 593, + 593, nil, 593, nil, nil, nil, 593, 593, nil, nil, + nil, 593, nil, 593, 593, 593, 593, 593, 593, 593, + nil, nil, nil, nil, nil, 593, 593, 593, 593, 593, + 593, 593, nil, nil, 593, nil, nil, nil, nil, nil, + nil, 593, nil, nil, 593, 593, 593, 593, 593, 593, + 593, 593, 593, 593, 593, 593, nil, 593, 593, 593, + 593, 593, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 593, nil, nil, 593, nil, nil, 593, 593, nil, + nil, 593, nil, 593, nil, 593, nil, 593, nil, nil, + 593, nil, nil, nil, nil, nil, 593, nil, nil, nil, + nil, 593, 593, 593, 593, nil, 593, 593, 593, 593, + nil, nil, nil, nil, 593, 593, nil, nil, nil, 603, + 603, 603, 593, 603, 593, 593, 593, 603, 603, 593, + 593, nil, 603, nil, 603, 603, 603, 603, 603, 603, + 603, nil, nil, nil, nil, nil, 603, 603, 603, 603, + 603, 603, 603, nil, nil, 603, nil, nil, nil, nil, + nil, nil, 603, nil, nil, 603, 603, 603, 603, 603, + 603, 603, 603, nil, 603, 603, 603, nil, 603, 603, + 603, 603, 603, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 603, nil, nil, 603, nil, nil, 603, 603, + nil, nil, 603, nil, nil, nil, nil, nil, 603, nil, + nil, nil, nil, nil, nil, nil, nil, 603, nil, nil, + nil, nil, 603, 603, 603, 603, nil, 603, 603, 603, + 603, nil, nil, nil, nil, 603, 603, nil, nil, nil, + 606, 606, 606, 603, 606, 603, 603, 603, 606, 606, + 603, 603, nil, 606, nil, 606, 606, 606, 606, 606, + 606, 606, nil, nil, nil, nil, nil, 606, 606, 606, + 606, 606, 606, 606, nil, nil, 606, nil, nil, nil, + nil, nil, nil, 606, nil, nil, 606, 606, 606, 606, + 606, 606, 606, 606, nil, 606, 606, 606, nil, 606, + 606, 606, 606, 606, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 606, nil, nil, 606, nil, nil, 606, + 606, nil, nil, 606, nil, nil, nil, nil, nil, 606, + nil, nil, nil, nil, nil, nil, nil, nil, 606, nil, + nil, nil, nil, 606, 606, 606, 606, nil, 606, 606, + 606, 606, nil, nil, nil, nil, 606, 606, nil, nil, + nil, 608, 608, 608, 606, 608, 606, 606, 606, 608, + 608, 606, 606, nil, 608, nil, 608, 608, 608, 608, + 608, 608, 608, nil, nil, nil, nil, nil, 608, 608, + 608, 608, 608, 608, 608, nil, nil, 608, nil, nil, + nil, nil, nil, nil, 608, nil, nil, 608, 608, 608, + 608, 608, 608, 608, 608, nil, 608, 608, 608, nil, + 608, 608, 608, 608, 608, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 608, nil, nil, 608, nil, nil, + 608, 608, nil, nil, 608, nil, nil, nil, nil, nil, + 608, nil, nil, nil, nil, nil, nil, nil, nil, 608, + nil, nil, nil, nil, 608, 608, 608, 608, nil, 608, + 608, 608, 608, nil, nil, nil, nil, 608, 608, nil, + nil, nil, 614, 614, 614, 608, 614, 608, 608, 608, + 614, 614, 608, 608, nil, 614, nil, 614, 614, 614, + 614, 614, 614, 614, nil, nil, nil, nil, nil, 614, + 614, 614, 614, 614, 614, 614, nil, nil, 614, nil, + nil, nil, nil, nil, nil, 614, nil, nil, 614, 614, + 614, 614, 614, 614, 614, 614, 614, 614, 614, 614, + nil, 614, 614, 614, 614, 614, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 614, nil, nil, 614, nil, + nil, 614, 614, nil, nil, 614, nil, 614, nil, nil, + nil, 614, nil, nil, 614, nil, nil, nil, nil, nil, + 614, nil, nil, nil, nil, 614, 614, 614, 614, nil, + 614, 614, 614, 614, nil, nil, nil, nil, 614, 614, + nil, nil, nil, 617, 617, 617, 614, 617, 614, 614, + 614, 617, 617, 614, 614, nil, 617, nil, 617, 617, + 617, 617, 617, 617, 617, nil, nil, nil, nil, nil, + 617, 617, 617, 617, 617, 617, 617, nil, nil, 617, + nil, nil, nil, nil, nil, nil, 617, nil, nil, 617, + 617, 617, 617, 617, 617, 617, 617, 617, 617, 617, + 617, nil, 617, 617, 617, 617, 617, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 617, nil, nil, 617, + nil, nil, 617, 617, nil, nil, 617, nil, nil, nil, + nil, nil, 617, nil, nil, 617, nil, nil, nil, nil, + nil, 617, nil, nil, nil, nil, 617, 617, 617, 617, + nil, 617, 617, 617, 617, nil, nil, nil, nil, 617, + 617, nil, nil, nil, 630, 630, 630, 617, 630, 617, + 617, 617, 630, 630, 617, 617, nil, 630, nil, 630, + 630, 630, 630, 630, 630, 630, nil, nil, nil, nil, + nil, 630, 630, 630, 630, 630, 630, 630, nil, nil, + 630, nil, nil, nil, nil, nil, nil, 630, nil, nil, + 630, 630, 630, 630, 630, 630, 630, 630, nil, 630, + 630, 630, nil, 630, 630, 630, 630, 630, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 630, nil, nil, + 630, nil, nil, 630, 630, nil, nil, 630, nil, 630, + nil, nil, nil, 630, nil, nil, nil, nil, nil, nil, + nil, nil, 630, nil, nil, nil, nil, 630, 630, 630, + 630, nil, 630, 630, 630, 630, nil, nil, nil, nil, + 630, 630, nil, nil, nil, 631, 631, 631, 630, 631, + 630, 630, 630, 631, 631, 630, 630, nil, 631, nil, + 631, 631, 631, 631, 631, 631, 631, nil, nil, nil, + nil, nil, 631, 631, 631, 631, 631, 631, 631, nil, + nil, 631, nil, nil, nil, nil, nil, nil, 631, nil, + nil, 631, 631, 631, 631, 631, 631, 631, 631, 631, + 631, 631, 631, nil, 631, 631, 631, 631, 631, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 631, nil, + nil, 631, nil, nil, 631, 631, nil, nil, 631, nil, + 631, nil, 631, nil, 631, nil, nil, 631, nil, nil, + nil, nil, nil, 631, nil, nil, nil, nil, 631, 631, + 631, 631, nil, 631, 631, 631, 631, nil, nil, nil, + nil, 631, 631, nil, nil, nil, 641, 641, 641, 631, + 641, 631, 631, 631, 641, 641, 631, 631, nil, 641, + nil, 641, 641, 641, 641, 641, 641, 641, nil, nil, + nil, nil, nil, 641, 641, 641, 641, 641, 641, 641, + nil, nil, 641, nil, nil, nil, nil, nil, nil, 641, + nil, nil, 641, 641, 641, 641, 641, 641, 641, 641, + 641, 641, 641, 641, nil, 641, 641, 641, 641, 641, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 641, + nil, nil, 641, nil, nil, 641, 641, nil, nil, 641, + nil, 641, nil, 641, nil, 641, nil, nil, 641, nil, + nil, nil, nil, nil, 641, nil, nil, nil, nil, 641, + 641, 641, 641, nil, 641, 641, 641, 641, nil, nil, + nil, nil, 641, 641, nil, nil, nil, nil, nil, nil, + 641, nil, 641, 641, 641, nil, nil, 641, 641, 672, + 672, 672, 672, 672, nil, nil, nil, 672, 672, nil, + nil, nil, 672, nil, 672, 672, 672, 672, 672, 672, + 672, nil, nil, nil, nil, nil, 672, 672, 672, 672, + 672, 672, 672, nil, nil, 672, nil, nil, nil, nil, + nil, 672, 672, nil, 672, 672, 672, 672, 672, 672, + 672, 672, 672, nil, 672, 672, 672, nil, 672, 672, + 672, 672, 672, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 672, nil, nil, 672, nil, nil, 672, 672, + nil, nil, 672, nil, 672, nil, nil, nil, 672, nil, + nil, nil, nil, nil, nil, nil, nil, 672, nil, nil, + nil, nil, 672, 672, 672, 672, nil, 672, 672, 672, + 672, nil, nil, nil, nil, 672, 672, nil, nil, nil, + 674, 674, 674, 672, 674, 672, 672, 672, 674, 674, + 672, 672, nil, 674, nil, 674, 674, 674, 674, 674, + 674, 674, nil, nil, nil, nil, nil, 674, 674, 674, + 674, 674, 674, 674, nil, nil, 674, nil, nil, nil, + nil, nil, nil, 674, nil, nil, 674, 674, 674, 674, + 674, 674, 674, 674, nil, 674, 674, 674, nil, 674, + 674, 674, 674, 674, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 674, nil, nil, 674, nil, nil, 674, + 674, nil, nil, 674, nil, 674, nil, nil, nil, 674, + nil, nil, nil, nil, nil, nil, nil, nil, 674, nil, + nil, nil, nil, 674, 674, 674, 674, nil, 674, 674, + 674, 674, nil, nil, nil, nil, 674, 674, nil, nil, + nil, 675, 675, 675, 674, 675, 674, 674, 674, 675, + 675, 674, 674, nil, 675, nil, 675, 675, 675, 675, + 675, 675, 675, nil, nil, nil, nil, nil, 675, 675, + 675, 675, 675, 675, 675, nil, nil, 675, nil, nil, + nil, nil, nil, nil, 675, nil, nil, 675, 675, 675, + 675, 675, 675, 675, 675, nil, 675, 675, 675, nil, + 675, 675, 675, 675, 675, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 675, nil, nil, 675, nil, nil, + 675, 675, nil, nil, 675, nil, nil, nil, nil, nil, + 675, nil, nil, nil, nil, nil, nil, nil, nil, 675, + nil, nil, nil, nil, 675, 675, 675, 675, nil, 675, + 675, 675, 675, nil, nil, nil, nil, 675, 675, nil, + nil, nil, 676, 676, 676, 675, 676, 675, 675, 675, + 676, 676, 675, 675, nil, 676, nil, 676, 676, 676, + 676, 676, 676, 676, nil, nil, nil, nil, nil, 676, + 676, 676, 676, 676, 676, 676, nil, nil, 676, nil, + nil, nil, nil, nil, nil, 676, nil, nil, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, 676, 676, + nil, 676, 676, 676, 676, 676, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 676, nil, nil, 676, nil, + nil, 676, 676, nil, nil, 676, nil, 676, nil, 676, + nil, 676, nil, nil, 676, nil, nil, nil, nil, nil, + 676, nil, nil, nil, nil, 676, 676, 676, 676, nil, + 676, 676, 676, 676, nil, nil, nil, nil, 676, 676, + nil, nil, nil, nil, nil, nil, 676, nil, 676, 676, + 676, nil, nil, 676, 676, 679, 679, 679, 679, 679, + nil, nil, nil, 679, 679, nil, nil, nil, 679, nil, + 679, 679, 679, 679, 679, 679, 679, nil, nil, nil, + nil, nil, 679, 679, 679, 679, 679, 679, 679, nil, + nil, 679, nil, nil, nil, nil, nil, 679, 679, nil, + 679, 679, 679, 679, 679, 679, 679, 679, 679, nil, + 679, 679, 679, nil, 679, 679, 679, 679, 679, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 679, nil, + nil, 679, nil, nil, 679, 679, nil, nil, 679, nil, + 679, nil, nil, nil, 679, nil, nil, nil, nil, nil, + nil, nil, nil, 679, nil, nil, nil, nil, 679, 679, + 679, 679, nil, 679, 679, 679, 679, nil, nil, nil, + nil, 679, 679, nil, nil, nil, 680, 680, 680, 679, + 680, 679, 679, 679, 680, 680, 679, 679, nil, 680, + nil, 680, 680, 680, 680, 680, 680, 680, nil, nil, + nil, nil, nil, 680, 680, 680, 680, 680, 680, 680, + nil, nil, 680, nil, nil, nil, nil, nil, nil, 680, + nil, nil, 680, 680, 680, 680, 680, 680, 680, 680, + nil, 680, 680, 680, nil, 680, 680, 680, 680, 680, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 680, + nil, nil, 680, nil, nil, 680, 680, nil, nil, 680, + nil, nil, nil, nil, nil, 680, nil, nil, nil, nil, + nil, nil, nil, nil, 680, nil, nil, nil, nil, 680, + 680, 680, 680, nil, 680, 680, 680, 680, nil, nil, + nil, nil, 680, 680, nil, nil, nil, 683, 683, 683, + 680, 683, 680, 680, 680, 683, 683, 680, 680, nil, + 683, nil, 683, 683, 683, 683, 683, 683, 683, nil, + nil, nil, nil, nil, 683, 683, 683, 683, 683, 683, + 683, nil, nil, 683, nil, nil, nil, nil, nil, nil, + 683, nil, nil, 683, 683, 683, 683, 683, 683, 683, + 683, 683, 683, 683, 683, nil, 683, 683, 683, 683, + 683, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 683, nil, nil, 683, nil, nil, 683, 683, nil, nil, + 683, nil, 683, nil, 683, nil, 683, nil, nil, 683, + nil, nil, nil, nil, nil, 683, nil, nil, nil, nil, + 683, 683, 683, 683, nil, 683, 683, 683, 683, nil, + nil, nil, nil, 683, 683, nil, nil, nil, 684, 684, + 684, 683, 684, 683, 683, 683, 684, 684, 683, 683, + nil, 684, nil, 684, 684, 684, 684, 684, 684, 684, + nil, nil, nil, nil, nil, 684, 684, 684, 684, 684, + 684, 684, nil, nil, 684, nil, nil, nil, nil, nil, + nil, 684, nil, nil, 684, 684, 684, 684, 684, 684, + 684, 684, 684, 684, 684, 684, nil, 684, 684, 684, + 684, 684, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 684, nil, nil, 684, nil, nil, 684, 684, nil, + nil, 684, nil, nil, nil, 684, nil, 684, nil, nil, + 684, nil, nil, nil, nil, nil, 684, nil, nil, nil, + nil, 684, 684, 684, 684, nil, 684, 684, 684, 684, + nil, nil, nil, nil, 684, 684, nil, nil, nil, 685, + 685, 685, 684, 685, 684, 684, 684, 685, 685, 684, + 684, nil, 685, nil, 685, 685, 685, 685, 685, 685, + 685, nil, nil, nil, nil, nil, 685, 685, 685, 685, + 685, 685, 685, nil, nil, 685, nil, nil, nil, nil, + nil, nil, 685, nil, nil, 685, 685, 685, 685, 685, + 685, 685, 685, nil, 685, 685, 685, nil, 685, 685, + 685, 685, 685, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 685, nil, nil, 685, nil, nil, 685, 685, + nil, nil, 685, nil, nil, nil, nil, nil, 685, nil, + nil, nil, nil, nil, nil, nil, nil, 685, nil, nil, + nil, nil, 685, 685, 685, 685, nil, 685, 685, 685, + 685, nil, nil, nil, nil, 685, 685, nil, nil, nil, + 686, 686, 686, 685, 686, 685, 685, 685, 686, 686, + 685, 685, nil, 686, nil, 686, 686, 686, 686, 686, + 686, 686, nil, nil, nil, nil, nil, 686, 686, 686, + 686, 686, 686, 686, nil, nil, 686, nil, nil, nil, + nil, nil, nil, 686, nil, nil, 686, 686, 686, 686, + 686, 686, 686, 686, nil, 686, 686, 686, nil, 686, + 686, 686, 686, 686, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 686, nil, nil, 686, nil, nil, 686, + 686, nil, nil, 686, nil, nil, nil, nil, nil, 686, + nil, nil, nil, nil, nil, nil, nil, nil, 686, nil, + nil, nil, nil, 686, 686, 686, 686, nil, 686, 686, + 686, 686, nil, nil, nil, nil, 686, 686, nil, nil, + nil, 690, 690, 690, 686, 690, 686, 686, 686, 690, + 690, 686, 686, nil, 690, nil, 690, 690, 690, 690, + 690, 690, 690, nil, nil, nil, nil, nil, 690, 690, + 690, 690, 690, 690, 690, nil, nil, 690, nil, nil, + nil, nil, nil, nil, 690, nil, nil, 690, 690, 690, + 690, 690, 690, 690, 690, nil, 690, 690, 690, nil, + 690, 690, 690, 690, 690, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 690, nil, nil, 690, nil, nil, + 690, 690, nil, nil, 690, nil, nil, nil, nil, nil, + 690, nil, nil, nil, nil, nil, nil, nil, nil, 690, + nil, nil, nil, nil, 690, 690, 690, 690, nil, 690, + 690, 690, 690, nil, nil, nil, nil, 690, 690, nil, + nil, nil, 691, 691, 691, 690, 691, 690, 690, 690, + 691, 691, 690, 690, nil, 691, nil, 691, 691, 691, + 691, 691, 691, 691, nil, nil, nil, nil, nil, 691, + 691, 691, 691, 691, 691, 691, nil, nil, 691, nil, + nil, nil, nil, nil, nil, 691, nil, nil, 691, 691, + 691, 691, 691, 691, 691, 691, nil, 691, 691, 691, + nil, 691, 691, 691, 691, 691, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 691, nil, nil, 691, nil, + nil, 691, 691, nil, nil, 691, nil, nil, nil, nil, + nil, 691, nil, nil, nil, nil, nil, nil, nil, nil, + 691, nil, nil, nil, nil, 691, 691, 691, 691, nil, + 691, 691, 691, 691, nil, nil, nil, nil, 691, 691, + nil, nil, nil, 697, 697, 697, 691, 697, 691, 691, + 691, 697, 697, 691, 691, nil, 697, nil, 697, 697, + 697, 697, 697, 697, 697, nil, nil, nil, nil, nil, + 697, 697, 697, 697, 697, 697, 697, nil, nil, 697, + nil, nil, nil, nil, nil, nil, 697, nil, nil, 697, + 697, 697, 697, 697, 697, 697, 697, nil, 697, 697, + 697, nil, 697, 697, 697, 697, 697, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 697, nil, nil, 697, + nil, nil, 697, 697, nil, nil, 697, nil, 697, nil, + nil, nil, 697, nil, nil, nil, nil, nil, nil, nil, + nil, 697, nil, nil, nil, nil, 697, 697, 697, 697, + nil, 697, 697, 697, 697, nil, nil, nil, nil, 697, + 697, nil, nil, nil, 713, 713, 713, 697, 713, 697, + 697, 697, 713, 713, 697, 697, nil, 713, nil, 713, + 713, 713, 713, 713, 713, 713, nil, nil, nil, nil, + nil, 713, 713, 713, 713, 713, 713, 713, nil, nil, + 713, nil, nil, nil, nil, nil, nil, 713, nil, nil, + 713, 713, 713, 713, 713, 713, 713, 713, nil, 713, + 713, 713, nil, 713, 713, 713, 713, 713, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 713, nil, nil, + 713, nil, nil, 713, 713, nil, nil, 713, nil, nil, + nil, nil, nil, 713, nil, nil, nil, nil, nil, nil, + nil, nil, 713, nil, nil, nil, nil, 713, 713, 713, + 713, nil, 713, 713, 713, 713, nil, nil, nil, nil, + 713, 713, nil, nil, nil, 735, 735, 735, 713, 735, + 713, 713, 713, 735, 735, 713, 713, nil, 735, nil, + 735, 735, 735, 735, 735, 735, 735, nil, nil, nil, + nil, nil, 735, 735, 735, 735, 735, 735, 735, nil, + nil, 735, nil, nil, nil, nil, nil, nil, 735, nil, + nil, 735, 735, 735, 735, 735, 735, 735, 735, nil, + 735, 735, 735, nil, 735, 735, 735, 735, 735, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 735, nil, + nil, 735, nil, nil, 735, 735, nil, nil, 735, nil, + nil, nil, nil, nil, 735, nil, nil, nil, nil, nil, + nil, nil, nil, 735, nil, nil, nil, nil, 735, 735, + 735, 735, nil, 735, 735, 735, 735, nil, nil, nil, + nil, 735, 735, nil, nil, nil, 736, 736, 736, 735, + 736, 735, 735, 735, 736, 736, 735, 735, nil, 736, + nil, 736, 736, 736, 736, 736, 736, 736, nil, nil, + nil, nil, nil, 736, 736, 736, 736, 736, 736, 736, + nil, nil, 736, nil, nil, nil, nil, nil, nil, 736, + nil, nil, 736, 736, 736, 736, 736, 736, 736, 736, + nil, 736, 736, 736, nil, 736, 736, 736, 736, 736, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 736, + nil, nil, 736, nil, nil, 736, 736, nil, nil, 736, + nil, nil, nil, nil, nil, 736, nil, nil, nil, nil, + nil, nil, nil, nil, 736, nil, nil, nil, nil, 736, + 736, 736, 736, nil, 736, 736, 736, 736, nil, nil, + nil, nil, 736, 736, nil, nil, nil, 791, 791, 791, + 736, 791, 736, 736, 736, 791, 791, 736, 736, nil, + 791, nil, 791, 791, 791, 791, 791, 791, 791, nil, + nil, nil, nil, nil, 791, 791, 791, 791, 791, 791, + 791, nil, nil, 791, nil, nil, nil, nil, nil, nil, + 791, nil, nil, 791, 791, 791, 791, 791, 791, 791, + 791, 791, 791, 791, 791, nil, 791, 791, 791, 791, + 791, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 791, nil, nil, 791, nil, nil, 791, 791, nil, nil, + 791, nil, 791, nil, 791, nil, 791, nil, nil, 791, + nil, nil, nil, nil, nil, 791, nil, nil, nil, nil, + 791, 791, 791, 791, nil, 791, 791, 791, 791, nil, + nil, nil, nil, 791, 791, nil, nil, nil, 800, 800, + 800, 791, 800, 791, 791, 791, 800, 800, 791, 791, + nil, 800, nil, 800, 800, 800, 800, 800, 800, 800, + nil, nil, nil, nil, nil, 800, 800, 800, 800, 800, + 800, 800, nil, nil, 800, nil, nil, nil, nil, nil, + nil, 800, nil, nil, 800, 800, 800, 800, 800, 800, + 800, 800, nil, 800, 800, 800, nil, 800, 800, 800, + 800, 800, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 800, nil, nil, 800, nil, nil, 800, 800, nil, + nil, 800, nil, nil, nil, nil, nil, 800, nil, nil, + nil, nil, nil, nil, nil, nil, 800, nil, nil, nil, + nil, 800, 800, 800, 800, nil, 800, 800, 800, 800, + nil, nil, nil, nil, 800, 800, nil, nil, nil, 803, + 803, 803, 800, 803, 800, 800, 800, 803, 803, 800, + 800, nil, 803, nil, 803, 803, 803, 803, 803, 803, + 803, nil, nil, nil, nil, nil, 803, 803, 803, 803, + 803, 803, 803, nil, nil, 803, nil, nil, nil, nil, + nil, nil, 803, nil, nil, 803, 803, 803, 803, 803, + 803, 803, 803, nil, 803, 803, 803, nil, 803, 803, + 803, 803, 803, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 803, nil, nil, 803, nil, nil, 803, 803, + nil, nil, 803, nil, nil, nil, nil, nil, 803, nil, + nil, nil, nil, nil, nil, nil, nil, 803, nil, nil, + nil, nil, 803, 803, 803, 803, nil, 803, 803, 803, + 803, nil, nil, nil, nil, 803, 803, nil, nil, nil, + 821, 821, 821, 803, 821, 803, 803, 803, 821, 821, + 803, 803, nil, 821, nil, 821, 821, 821, 821, 821, + 821, 821, nil, nil, nil, nil, nil, 821, 821, 821, + 821, 821, 821, 821, nil, nil, 821, nil, nil, nil, + nil, nil, nil, 821, nil, nil, 821, 821, 821, 821, + 821, 821, 821, 821, nil, 821, 821, 821, nil, 821, + 821, 821, 821, 821, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 821, nil, nil, 821, nil, nil, 821, + 821, nil, nil, 821, nil, nil, nil, nil, nil, 821, + nil, nil, nil, nil, nil, nil, nil, nil, 821, nil, + nil, nil, nil, 821, 821, 821, 821, nil, 821, 821, + 821, 821, nil, nil, nil, nil, 821, 821, nil, nil, + nil, 850, 850, 850, 821, 850, 821, 821, 821, 850, + 850, 821, 821, nil, 850, nil, 850, 850, 850, 850, + 850, 850, 850, nil, nil, nil, nil, nil, 850, 850, + 850, 850, 850, 850, 850, nil, nil, 850, nil, nil, + nil, nil, nil, nil, 850, nil, nil, 850, 850, 850, + 850, 850, 850, 850, 850, nil, 850, 850, 850, nil, + 850, 850, 850, 850, 850, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 850, nil, nil, 850, nil, nil, + 850, 850, nil, nil, 850, nil, nil, nil, nil, nil, + 850, nil, nil, nil, nil, nil, nil, nil, nil, 850, + nil, nil, nil, nil, 850, 850, 850, 850, nil, 850, + 850, 850, 850, nil, nil, nil, nil, 850, 850, nil, + nil, nil, 870, 870, 870, 850, 870, 850, 850, 850, + 870, 870, 850, 850, nil, 870, nil, 870, 870, 870, + 870, 870, 870, 870, nil, nil, nil, nil, nil, 870, + 870, 870, 870, 870, 870, 870, nil, nil, 870, nil, + nil, nil, nil, nil, nil, 870, nil, nil, 870, 870, + 870, 870, 870, 870, 870, 870, nil, 870, 870, 870, + nil, 870, 870, 870, 870, 870, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 870, nil, nil, 870, nil, + nil, 870, 870, nil, nil, 870, nil, nil, nil, nil, + nil, 870, nil, nil, nil, nil, nil, nil, nil, nil, + 870, nil, nil, nil, nil, 870, 870, 870, 870, nil, + 870, 870, 870, 870, nil, nil, nil, nil, 870, 870, + nil, nil, nil, 878, 878, 878, 870, 878, 870, 870, + 870, 878, 878, 870, 870, nil, 878, nil, 878, 878, + 878, 878, 878, 878, 878, nil, nil, nil, nil, nil, + 878, 878, 878, 878, 878, 878, 878, nil, nil, 878, + nil, nil, nil, nil, nil, nil, 878, nil, nil, 878, + 878, 878, 878, 878, 878, 878, 878, nil, 878, 878, + 878, nil, 878, 878, 878, 878, 878, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 878, nil, nil, 878, + nil, nil, 878, 878, nil, nil, 878, nil, nil, nil, + nil, nil, 878, nil, nil, nil, nil, nil, nil, nil, + nil, 878, nil, nil, nil, nil, 878, 878, 878, 878, + nil, 878, 878, 878, 878, nil, nil, nil, nil, 878, + 878, nil, nil, nil, 891, 891, 891, 878, 891, 878, + 878, 878, 891, 891, 878, 878, nil, 891, nil, 891, + 891, 891, 891, 891, 891, 891, nil, nil, nil, nil, + nil, 891, 891, 891, 891, 891, 891, 891, nil, nil, + 891, nil, nil, nil, nil, nil, nil, 891, nil, nil, + 891, 891, 891, 891, 891, 891, 891, 891, nil, 891, + 891, 891, nil, 891, 891, 891, 891, 891, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 891, nil, nil, + 891, nil, nil, 891, 891, nil, nil, 891, nil, nil, + nil, nil, nil, 891, nil, nil, nil, nil, nil, nil, + nil, nil, 891, nil, nil, nil, nil, 891, 891, 891, + 891, nil, 891, 891, 891, 891, nil, nil, nil, nil, + 891, 891, nil, nil, nil, 892, 892, 892, 891, 892, + 891, 891, 891, 892, 892, 891, 891, nil, 892, nil, + 892, 892, 892, 892, 892, 892, 892, nil, nil, nil, + nil, nil, 892, 892, 892, 892, 892, 892, 892, nil, + nil, 892, nil, nil, nil, nil, nil, nil, 892, nil, + nil, 892, 892, 892, 892, 892, 892, 892, 892, nil, + 892, 892, 892, nil, 892, 892, 892, 892, 892, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 892, nil, + nil, 892, nil, nil, 892, 892, nil, nil, 892, nil, + nil, nil, nil, nil, 892, nil, nil, nil, nil, nil, + nil, nil, nil, 892, nil, nil, nil, nil, 892, 892, + 892, 892, nil, 892, 892, 892, 892, nil, nil, nil, + nil, 892, 892, nil, nil, nil, 920, 920, 920, 892, + 920, 892, 892, 892, 920, 920, 892, 892, nil, 920, + nil, 920, 920, 920, 920, 920, 920, 920, nil, nil, + nil, nil, nil, 920, 920, 920, 920, 920, 920, 920, + nil, nil, 920, nil, nil, nil, nil, nil, nil, 920, + nil, nil, 920, 920, 920, 920, 920, 920, 920, 920, + nil, 920, 920, 920, nil, 920, 920, 920, 920, 920, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 920, + nil, nil, 920, nil, nil, 920, 920, nil, nil, 920, + nil, nil, nil, nil, nil, 920, nil, nil, nil, nil, + nil, nil, nil, nil, 920, nil, nil, nil, nil, 920, + 920, 920, 920, nil, 920, 920, 920, 920, nil, nil, + nil, nil, 920, 920, nil, nil, nil, 921, 921, 921, + 920, 921, 920, 920, 920, 921, 921, 920, 920, nil, + 921, nil, 921, 921, 921, 921, 921, 921, 921, nil, + nil, nil, nil, nil, 921, 921, 921, 921, 921, 921, + 921, nil, nil, 921, nil, nil, nil, nil, nil, nil, + 921, nil, nil, 921, 921, 921, 921, 921, 921, 921, + 921, nil, 921, 921, 921, nil, 921, 921, 921, 921, + 921, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 921, nil, nil, 921, nil, nil, 921, 921, nil, nil, + 921, nil, nil, nil, nil, nil, 921, nil, nil, nil, + nil, nil, nil, nil, nil, 921, nil, nil, nil, nil, + 921, 921, 921, 921, nil, 921, 921, 921, 921, nil, + nil, nil, nil, 921, 921, nil, nil, nil, 922, 922, + 922, 921, 922, 921, 921, 921, 922, 922, 921, 921, + nil, 922, nil, 922, 922, 922, 922, 922, 922, 922, + nil, nil, nil, nil, nil, 922, 922, 922, 922, 922, + 922, 922, nil, nil, 922, nil, nil, nil, nil, nil, + nil, 922, nil, nil, 922, 922, 922, 922, 922, 922, + 922, 922, nil, 922, 922, 922, nil, 922, 922, 922, + 922, 922, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 922, nil, nil, 922, nil, nil, 922, 922, nil, + nil, 922, nil, nil, nil, nil, nil, 922, nil, nil, + nil, nil, nil, nil, nil, nil, 922, nil, nil, nil, + nil, 922, 922, 922, 922, nil, 922, 922, 922, 922, + nil, nil, nil, nil, 922, 922, nil, nil, nil, 923, + 923, 923, 922, 923, 922, 922, 922, 923, 923, 922, + 922, nil, 923, nil, 923, 923, 923, 923, 923, 923, + 923, nil, nil, nil, nil, nil, 923, 923, 923, 923, + 923, 923, 923, nil, nil, 923, nil, nil, nil, nil, + nil, nil, 923, nil, nil, 923, 923, 923, 923, 923, + 923, 923, 923, nil, 923, 923, 923, nil, 923, 923, + 923, 923, 923, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 923, nil, nil, 923, nil, nil, 923, 923, + nil, nil, 923, nil, nil, nil, nil, nil, 923, nil, + nil, nil, nil, nil, nil, nil, nil, 923, nil, nil, + nil, nil, 923, 923, 923, 923, nil, 923, 923, 923, + 923, nil, nil, nil, nil, 923, 923, nil, nil, nil, + 924, 924, 924, 923, 924, 923, 923, 923, 924, 924, + 923, 923, nil, 924, nil, 924, 924, 924, 924, 924, + 924, 924, nil, nil, nil, nil, nil, 924, 924, 924, + 924, 924, 924, 924, nil, nil, 924, nil, nil, nil, + nil, nil, nil, 924, nil, nil, 924, 924, 924, 924, + 924, 924, 924, 924, nil, 924, 924, 924, nil, 924, + 924, 924, 924, 924, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 924, nil, nil, 924, nil, nil, 924, + 924, nil, nil, 924, nil, nil, nil, nil, nil, 924, + nil, nil, nil, nil, nil, nil, nil, nil, 924, nil, + nil, nil, nil, 924, 924, 924, 924, nil, 924, 924, + 924, 924, nil, nil, nil, nil, 924, 924, nil, nil, + nil, 925, 925, 925, 924, 925, 924, 924, 924, 925, + 925, 924, 924, nil, 925, nil, 925, 925, 925, 925, + 925, 925, 925, nil, nil, nil, nil, nil, 925, 925, + 925, 925, 925, 925, 925, nil, nil, 925, nil, nil, + nil, nil, nil, nil, 925, nil, nil, 925, 925, 925, + 925, 925, 925, 925, 925, nil, 925, 925, 925, nil, + 925, 925, 925, 925, 925, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 925, nil, nil, 925, nil, nil, + 925, 925, nil, nil, 925, nil, nil, nil, nil, nil, + 925, nil, nil, nil, nil, nil, nil, nil, nil, 925, + nil, nil, nil, nil, 925, 925, 925, 925, nil, 925, + 925, 925, 925, nil, nil, nil, nil, 925, 925, nil, + nil, nil, 958, 958, 958, 925, 958, 925, 925, 925, + 958, 958, 925, 925, nil, 958, nil, 958, 958, 958, + 958, 958, 958, 958, nil, nil, nil, nil, nil, 958, + 958, 958, 958, 958, 958, 958, nil, nil, 958, nil, + nil, nil, nil, nil, nil, 958, nil, nil, 958, 958, + 958, 958, 958, 958, 958, 958, nil, 958, 958, 958, + nil, 958, 958, 958, 958, 958, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 958, nil, nil, 958, nil, + nil, 958, 958, nil, nil, 958, nil, nil, nil, nil, + nil, 958, nil, nil, nil, nil, nil, nil, nil, nil, + 958, nil, nil, nil, nil, 958, 958, 958, 958, nil, + 958, 958, 958, 958, nil, nil, nil, nil, 958, 958, + nil, nil, nil, 961, 961, 961, 958, 961, 958, 958, + 958, 961, 961, 958, 958, nil, 961, nil, 961, 961, + 961, 961, 961, 961, 961, nil, nil, nil, nil, nil, + 961, 961, 961, 961, 961, 961, 961, nil, nil, 961, + nil, nil, nil, nil, nil, nil, 961, nil, nil, 961, + 961, 961, 961, 961, 961, 961, 961, nil, 961, 961, + 961, nil, 961, 961, 961, 961, 961, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 961, nil, nil, 961, + nil, nil, 961, 961, nil, nil, 961, nil, nil, nil, + nil, nil, 961, nil, nil, nil, nil, nil, nil, nil, + nil, 961, nil, nil, nil, nil, 961, 961, 961, 961, + nil, 961, 961, 961, 961, nil, nil, nil, nil, 961, + 961, nil, nil, nil, 984, 984, 984, 961, 984, 961, + 961, 961, 984, 984, 961, 961, nil, 984, nil, 984, + 984, 984, 984, 984, 984, 984, nil, nil, nil, nil, + nil, 984, 984, 984, 984, 984, 984, 984, nil, nil, + 984, nil, nil, nil, nil, nil, nil, 984, nil, nil, + 984, 984, 984, 984, 984, 984, 984, 984, nil, 984, + 984, 984, nil, 984, 984, 984, 984, 984, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 984, nil, nil, + 984, nil, nil, 984, 984, nil, nil, 984, nil, nil, + nil, nil, nil, 984, nil, nil, nil, nil, nil, nil, + nil, nil, 984, nil, nil, nil, nil, 984, 984, 984, + 984, nil, 984, 984, 984, 984, nil, nil, nil, nil, + 984, 984, nil, nil, nil, 989, 989, 989, 984, 989, + 984, 984, 984, 989, 989, 984, 984, nil, 989, nil, + 989, 989, 989, 989, 989, 989, 989, nil, nil, nil, + nil, nil, 989, 989, 989, 989, 989, 989, 989, nil, + nil, 989, nil, nil, nil, nil, nil, nil, 989, nil, + nil, 989, 989, 989, 989, 989, 989, 989, 989, nil, + 989, 989, 989, nil, 989, 989, 989, 989, 989, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 989, nil, + nil, 989, nil, nil, 989, 989, nil, nil, 989, nil, + 989, nil, nil, nil, 989, nil, nil, nil, nil, nil, + nil, nil, nil, 989, nil, nil, nil, nil, 989, 989, + 989, 989, nil, 989, 989, 989, 989, nil, nil, nil, + nil, 989, 989, nil, nil, nil, 1008, 1008, 1008, 989, + 1008, 989, 989, 989, 1008, 1008, 989, 989, nil, 1008, + nil, 1008, 1008, 1008, 1008, 1008, 1008, 1008, nil, nil, + nil, nil, nil, 1008, 1008, 1008, 1008, 1008, 1008, 1008, + nil, nil, 1008, nil, nil, nil, nil, nil, nil, 1008, + nil, nil, 1008, 1008, 1008, 1008, 1008, 1008, 1008, 1008, + 1008, 1008, 1008, 1008, nil, 1008, 1008, 1008, 1008, 1008, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 1008, + nil, nil, 1008, nil, nil, 1008, 1008, nil, nil, 1008, + nil, nil, nil, 1008, nil, 1008, nil, nil, 1008, nil, + nil, nil, nil, nil, 1008, nil, nil, nil, nil, 1008, + 1008, 1008, 1008, nil, 1008, 1008, 1008, 1008, nil, nil, + nil, nil, 1008, 1008, nil, nil, nil, 1034, 1034, 1034, + 1008, 1034, 1008, 1008, 1008, 1034, 1034, 1008, 1008, nil, + 1034, nil, 1034, 1034, 1034, 1034, 1034, 1034, 1034, nil, + nil, nil, nil, nil, 1034, 1034, 1034, 1034, 1034, 1034, + 1034, nil, nil, 1034, nil, nil, nil, nil, nil, nil, + 1034, nil, nil, 1034, 1034, 1034, 1034, 1034, 1034, 1034, + 1034, nil, 1034, 1034, 1034, nil, 1034, 1034, 1034, 1034, + 1034, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1034, nil, nil, 1034, nil, nil, 1034, 1034, nil, nil, + 1034, nil, nil, nil, nil, nil, 1034, nil, nil, nil, + nil, nil, nil, nil, nil, 1034, nil, nil, nil, nil, + 1034, 1034, 1034, 1034, nil, 1034, 1034, 1034, 1034, nil, + nil, nil, nil, 1034, 1034, nil, nil, nil, 1147, 1147, + 1147, 1034, 1147, 1034, 1034, 1034, 1147, 1147, 1034, 1034, + nil, 1147, nil, 1147, 1147, 1147, 1147, 1147, 1147, 1147, + nil, nil, nil, nil, nil, 1147, 1147, 1147, 1147, 1147, + 1147, 1147, nil, nil, 1147, nil, nil, nil, nil, nil, + nil, 1147, nil, nil, 1147, 1147, 1147, 1147, 1147, 1147, + 1147, 1147, nil, 1147, 1147, 1147, nil, 1147, 1147, 1147, + 1147, 1147, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 1147, nil, nil, 1147, nil, nil, 1147, 1147, nil, + nil, 1147, nil, nil, nil, nil, nil, 1147, nil, nil, + nil, nil, nil, nil, nil, nil, 1147, nil, nil, nil, + nil, 1147, 1147, 1147, 1147, nil, 1147, 1147, 1147, 1147, + nil, nil, nil, nil, 1147, 1147, nil, nil, nil, 1148, + 1148, 1148, 1147, 1148, 1147, 1147, 1147, 1148, 1148, 1147, + 1147, nil, 1148, nil, 1148, 1148, 1148, 1148, 1148, 1148, + 1148, nil, nil, nil, nil, nil, 1148, 1148, 1148, 1148, + 1148, 1148, 1148, nil, nil, 1148, nil, nil, nil, nil, + nil, nil, 1148, nil, nil, 1148, 1148, 1148, 1148, 1148, + 1148, 1148, 1148, nil, 1148, 1148, 1148, nil, 1148, 1148, + 1148, 1148, 1148, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1148, nil, nil, 1148, nil, nil, 1148, 1148, + nil, nil, 1148, nil, nil, nil, nil, nil, 1148, nil, + nil, nil, nil, nil, nil, nil, nil, 1148, nil, nil, + nil, nil, 1148, 1148, 1148, 1148, nil, 1148, 1148, 1148, + 1148, nil, nil, nil, nil, 1148, 1148, nil, nil, nil, + 1160, 1160, 1160, 1148, 1160, 1148, 1148, 1148, 1160, 1160, + 1148, 1148, nil, 1160, nil, 1160, 1160, 1160, 1160, 1160, + 1160, 1160, nil, nil, nil, nil, nil, 1160, 1160, 1160, + 1160, 1160, 1160, 1160, nil, nil, 1160, nil, nil, nil, + nil, nil, nil, 1160, nil, nil, 1160, 1160, 1160, 1160, + 1160, 1160, 1160, 1160, 1160, 1160, 1160, 1160, nil, 1160, + 1160, 1160, 1160, 1160, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 1160, nil, nil, 1160, nil, nil, 1160, + 1160, nil, nil, 1160, nil, 1160, nil, 1160, nil, 1160, + nil, nil, 1160, nil, nil, nil, nil, nil, 1160, nil, + nil, nil, nil, 1160, 1160, 1160, 1160, nil, 1160, 1160, + 1160, 1160, nil, nil, nil, nil, 1160, 1160, nil, nil, + nil, 39, 39, 39, 1160, 39, 1160, 1160, 1160, 39, + 39, 1160, 1160, nil, 39, nil, 39, 39, 39, 39, + 39, 39, 39, nil, nil, nil, nil, nil, 39, 39, + 39, 39, 39, 39, 39, nil, nil, 39, nil, nil, + nil, nil, nil, nil, 39, nil, nil, 39, 39, 39, + 39, 39, 39, 39, 39, nil, 39, 39, 39, nil, + 39, 39, nil, nil, 39, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 39, nil, nil, 39, nil, nil, + 39, 39, nil, nil, 39, nil, 39, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 39, 39, 39, 39, nil, 39, + 39, 39, 39, nil, nil, nil, nil, 39, 39, nil, + nil, nil, 40, 40, 40, 39, 40, 39, 39, 39, + 40, 40, nil, nil, nil, 40, nil, 40, 40, 40, + 40, 40, 40, 40, nil, nil, nil, nil, nil, 40, + 40, 40, 40, 40, 40, 40, nil, nil, 40, nil, + nil, nil, nil, nil, nil, 40, nil, nil, 40, 40, + 40, 40, 40, 40, 40, 40, nil, 40, 40, 40, + nil, 40, 40, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 40, nil, nil, 40, nil, + nil, 40, 40, nil, nil, 40, nil, nil, 1206, nil, + 1206, 1206, 1206, 1206, 1206, nil, nil, nil, nil, nil, + nil, nil, nil, 1206, nil, 40, 40, 40, 40, nil, + 40, 40, 40, 40, nil, nil, nil, nil, 40, 40, + nil, nil, nil, 40, nil, 1206, 40, nil, 40, 40, + 40, 76, 76, 76, nil, 76, 1206, 1206, nil, 76, + 76, 1206, nil, nil, 76, nil, 76, 76, 76, 76, + 76, 76, 76, nil, nil, nil, nil, nil, 76, 76, + 76, 76, 76, 76, 76, nil, nil, 76, nil, nil, + nil, nil, nil, nil, 76, nil, nil, 76, 76, 76, + 76, 76, 76, 76, 76, nil, 76, 76, 76, nil, + 76, 76, nil, nil, 76, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 76, nil, nil, 76, nil, nil, + 76, 76, nil, nil, 76, nil, 76, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 76, 76, 76, 76, nil, 76, + 76, 76, 76, nil, nil, nil, nil, 76, 76, nil, + nil, nil, 77, 77, 77, 76, 77, 76, 76, 76, + 77, 77, nil, nil, nil, 77, nil, 77, 77, 77, + 77, 77, 77, 77, nil, nil, nil, nil, nil, 77, + 77, 77, 77, 77, 77, 77, nil, nil, 77, nil, + nil, nil, nil, nil, nil, 77, nil, nil, 77, 77, + 77, 77, 77, 77, 77, 77, nil, 77, 77, 77, + nil, 77, 77, nil, nil, 77, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 77, nil, nil, 77, nil, nil, 77, nil, + nil, 77, 77, nil, nil, 77, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 77, 77, 77, 77, nil, + 77, 77, 77, 77, nil, nil, nil, nil, 77, 77, + nil, nil, nil, 78, 78, 78, 77, 78, 77, 77, + 77, 78, 78, nil, nil, nil, 78, nil, 78, 78, + 78, 78, 78, 78, 78, nil, nil, nil, nil, nil, + 78, 78, 78, 78, 78, 78, 78, nil, nil, 78, + nil, nil, nil, nil, nil, nil, 78, nil, nil, 78, + 78, 78, 78, 78, 78, 78, 78, nil, 78, 78, + 78, nil, 78, 78, nil, nil, 78, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 78, nil, nil, 78, + nil, nil, 78, 78, nil, nil, 78, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 78, 78, 78, 78, + nil, 78, 78, 78, 78, nil, nil, nil, nil, 78, + 78, nil, nil, nil, 342, 342, 342, 78, 342, 78, + 78, 78, 342, 342, nil, nil, nil, 342, nil, 342, + 342, 342, 342, 342, 342, 342, nil, nil, nil, nil, + nil, 342, 342, 342, 342, 342, 342, 342, nil, nil, + 342, nil, nil, nil, nil, nil, nil, 342, nil, nil, + 342, 342, 342, 342, 342, 342, 342, 342, nil, 342, + 342, 342, nil, 342, 342, nil, nil, 342, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 342, nil, nil, + 342, nil, nil, 342, 342, nil, nil, 342, nil, nil, + 1208, nil, 1208, 1208, 1208, 1208, 1208, nil, nil, nil, + nil, nil, nil, nil, nil, 1208, nil, 342, 342, 342, + 342, nil, 342, 342, 342, 342, nil, nil, nil, nil, + 342, 342, nil, nil, nil, 342, nil, 1208, 342, nil, + 342, 342, 342, 361, 361, 361, nil, 361, 1208, 1208, + nil, 361, 361, 1208, nil, nil, 361, nil, 361, 361, + 361, 361, 361, 361, 361, nil, nil, nil, nil, nil, + 361, 361, 361, 361, 361, 361, 361, nil, nil, 361, + nil, nil, nil, nil, nil, nil, 361, nil, nil, 361, + 361, 361, 361, 361, 361, 361, 361, nil, 361, 361, + 361, nil, 361, 361, nil, nil, 361, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 361, nil, nil, 361, + nil, nil, 361, 361, nil, nil, 361, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 361, 361, 361, 361, + nil, 361, 361, 361, 361, nil, nil, nil, nil, 361, + 361, nil, nil, nil, 591, 591, 591, 361, 591, 361, + 361, 361, 591, 591, nil, nil, nil, 591, nil, 591, + 591, 591, 591, 591, 591, 591, nil, nil, nil, nil, + nil, 591, 591, 591, 591, 591, 591, 591, nil, nil, + 591, nil, nil, nil, nil, nil, nil, 591, nil, nil, + 591, 591, 591, 591, 591, 591, 591, 591, nil, 591, + 591, 591, nil, 591, 591, nil, nil, 591, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 591, nil, nil, + 591, nil, nil, 591, 591, nil, nil, 591, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 591, 591, 591, + 591, nil, 591, 591, 591, 591, nil, nil, nil, nil, + 591, 591, nil, nil, nil, 600, 600, 600, 591, 600, + 591, 591, 591, 600, 600, nil, nil, nil, 600, nil, + 600, 600, 600, 600, 600, 600, 600, nil, nil, nil, + nil, nil, 600, 600, 600, 600, 600, 600, 600, nil, + nil, 600, nil, nil, nil, nil, nil, nil, 600, nil, + nil, 600, 600, 600, 600, 600, 600, 600, 600, nil, + 600, 600, 600, nil, 600, 600, nil, nil, 600, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 600, nil, + nil, 600, nil, nil, 600, 600, nil, nil, 600, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 600, 600, + 600, 600, nil, 600, 600, 600, 600, nil, nil, nil, + nil, 600, 600, nil, nil, nil, 806, 806, 806, 600, + 806, 600, 600, 600, 806, 806, nil, nil, nil, 806, + nil, 806, 806, 806, 806, 806, 806, 806, nil, nil, + nil, nil, nil, 806, 806, 806, 806, 806, 806, 806, + nil, nil, 806, nil, nil, nil, nil, nil, nil, 806, + nil, nil, 806, 806, 806, 806, 806, 806, 806, 806, + nil, 806, 806, 806, nil, 806, 806, nil, nil, 806, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 806, + nil, nil, 806, nil, nil, 806, 806, nil, nil, 806, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 806, + 806, 806, 806, nil, 806, 806, 806, 806, nil, nil, + nil, nil, 806, 806, nil, nil, nil, 817, 817, 817, + 806, 817, 806, 806, 806, 817, 817, nil, nil, nil, + 817, nil, 817, 817, 817, 817, 817, 817, 817, nil, + nil, nil, nil, nil, 817, 817, 817, 817, 817, 817, + 817, nil, nil, 817, nil, nil, nil, nil, nil, nil, + 817, nil, nil, 817, 817, 817, 817, 817, 817, 817, + 817, nil, 817, 817, 817, nil, 817, 817, nil, nil, + 817, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 817, nil, nil, 817, nil, nil, 817, 817, nil, nil, + 817, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 817, 817, 817, 817, nil, 817, 817, 817, 817, nil, + nil, nil, nil, 817, 817, nil, nil, nil, 1016, 1016, + 1016, 817, 1016, 817, 817, 817, 1016, 1016, nil, nil, + nil, 1016, nil, 1016, 1016, 1016, 1016, 1016, 1016, 1016, + nil, nil, nil, nil, nil, 1016, 1016, 1016, 1016, 1016, + 1016, 1016, nil, nil, 1016, nil, nil, nil, nil, nil, + nil, 1016, nil, nil, 1016, 1016, 1016, 1016, 1016, 1016, + 1016, 1016, nil, 1016, 1016, 1016, nil, 1016, 1016, nil, + nil, 1016, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 1016, nil, nil, 1016, nil, nil, 1016, 1016, nil, + nil, 1016, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 1016, 1016, 1016, 1016, nil, 1016, 1016, 1016, 1016, + nil, nil, nil, nil, 1016, 1016, nil, nil, nil, 1080, + 1080, 1080, 1016, 1080, 1016, 1016, 1016, 1080, 1080, nil, + nil, nil, 1080, nil, 1080, 1080, 1080, 1080, 1080, 1080, + 1080, nil, nil, nil, nil, nil, 1080, 1080, 1080, 1080, + 1080, 1080, 1080, nil, nil, 1080, nil, nil, nil, nil, + nil, nil, 1080, nil, nil, 1080, 1080, 1080, 1080, 1080, + 1080, 1080, 1080, nil, 1080, 1080, 1080, nil, 1080, 1080, + nil, nil, 1080, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1080, nil, nil, 1080, nil, nil, 1080, 1080, + nil, nil, 1080, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1080, 1080, 1080, 1080, nil, 1080, 1080, 1080, + 1080, nil, nil, nil, nil, 1080, 1080, nil, nil, nil, + 1142, 1142, 1142, 1080, 1142, 1080, 1080, 1080, 1142, 1142, + nil, nil, nil, 1142, nil, 1142, 1142, 1142, 1142, 1142, + 1142, 1142, nil, nil, nil, nil, nil, 1142, 1142, 1142, + 1142, 1142, 1142, 1142, nil, nil, 1142, nil, nil, nil, + nil, nil, nil, 1142, nil, nil, 1142, 1142, 1142, 1142, + 1142, 1142, 1142, 1142, nil, 1142, 1142, 1142, nil, 1142, + 1142, nil, nil, 1142, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 1142, nil, nil, 1142, nil, nil, 1142, + 1142, nil, nil, 1142, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 1142, 1142, 1142, 1142, nil, 1142, 1142, + 1142, 1142, nil, nil, nil, nil, 1142, 1142, nil, nil, + nil, nil, nil, nil, 1142, nil, 1142, 1142, 1142, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, nil, nil, nil, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, nil, nil, nil, nil, + nil, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, nil, 10, nil, nil, nil, nil, nil, nil, nil, + 10, 10, nil, 10, 10, 10, 10, 10, 10, 10, + nil, nil, 10, 10, nil, nil, nil, 10, 10, 10, + 10, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 10, 10, nil, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, nil, + nil, 10, 10, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 10, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, nil, nil, nil, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, nil, nil, nil, nil, nil, 11, + 11, 11, 11, 11, 11, 11, 11, 11, nil, nil, + 11, nil, nil, nil, nil, nil, nil, nil, 11, 11, + nil, 11, 11, 11, 11, 11, 11, 11, nil, nil, + 11, 11, nil, nil, nil, 11, 11, 11, 11, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 11, 11, nil, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, nil, nil, 11, + 11, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 11, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, 428, nil, + nil, nil, 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, nil, nil, nil, nil, nil, 428, 428, 428, + 428, 428, 428, 428, 428, 428, nil, nil, 428, nil, + nil, nil, nil, nil, nil, nil, 428, 428, nil, 428, + 428, 428, 428, 428, 428, 428, nil, nil, 428, 428, + nil, nil, nil, 428, 428, 428, 428, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 428, 428, nil, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, nil, nil, 428, 428, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 428, 670, 670, 670, 670, 670, 670, 670, + 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, + 670, 670, 670, 670, 670, 670, 670, nil, nil, nil, + 670, 670, 670, 670, 670, 670, 670, 670, 670, 670, + nil, nil, nil, nil, nil, 670, 670, 670, 670, 670, + 670, 670, 670, 670, nil, nil, 670, nil, nil, nil, + nil, nil, nil, nil, 670, 670, nil, 670, 670, 670, + 670, 670, 670, 670, nil, nil, 670, 670, nil, nil, + nil, 670, 670, 670, 670, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 670, 670, + nil, 670, 670, 670, 670, 670, 670, 670, 670, 670, + 670, 670, 670, nil, nil, 670, 670, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 670, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, nil, nil, nil, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, nil, nil, + nil, nil, nil, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, nil, 26, nil, nil, nil, + nil, nil, 26, 26, nil, 26, 26, 26, 26, 26, + 26, 26, nil, nil, 26, 26, nil, nil, nil, 26, + 26, 26, 26, nil, nil, nil, nil, nil, 26, nil, + nil, nil, nil, nil, nil, nil, 26, 26, nil, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, nil, nil, 26, 530, 530, 530, 530, nil, nil, + 1210, nil, 1210, 1210, 1210, 1210, 1210, nil, nil, nil, + 530, 530, 530, 530, nil, 1210, nil, 530, 530, nil, + nil, nil, nil, 530, 530, nil, nil, 530, 530, nil, + nil, nil, nil, nil, nil, nil, nil, 1210, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 530, 1210, 1210, + 530, nil, nil, 1210, 530, nil, nil, 530, nil, 530, + nil, nil, nil, nil, nil, nil, 530, nil, nil, nil, + nil, nil, nil, 530, nil, nil, nil, 530, 530, 530, + 530, nil, 530, 530, 530, 530, nil, nil, nil, nil, + 530, 530, 531, 531, 531, 531, nil, nil, 530, nil, + 530, 530, 530, nil, nil, 530, 530, nil, 531, 531, + 531, 531, nil, nil, nil, 531, 531, nil, nil, nil, + nil, 531, 531, nil, nil, 531, 531, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 531, nil, nil, 531, nil, + nil, nil, 531, nil, nil, 531, nil, 531, nil, nil, + nil, nil, nil, nil, 531, nil, nil, nil, nil, nil, + nil, 531, nil, nil, nil, 531, 531, 531, 531, nil, + 531, 531, 531, 531, nil, nil, nil, nil, 531, 531, + 748, 748, 748, 748, nil, nil, 531, nil, 531, 531, + 531, nil, nil, 531, 531, nil, 748, 748, 748, 748, + nil, nil, nil, 748, nil, nil, nil, nil, nil, 748, + 748, nil, nil, 748, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 748, nil, nil, 748, nil, nil, nil, + 748, nil, nil, 748, nil, 748, nil, nil, nil, nil, + nil, nil, 710, nil, 710, 710, 710, 710, 710, 748, + nil, nil, nil, 748, 748, 748, 748, 710, 748, 748, + 748, 748, nil, nil, nil, nil, 748, 748, 748, 756, + 756, 756, 756, nil, 748, nil, 748, 748, 748, 710, + nil, 748, 748, nil, nil, 756, 756, 756, 756, nil, + 710, 710, 756, nil, nil, 710, nil, nil, 756, 756, + nil, nil, 756, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 756, nil, nil, 756, nil, nil, nil, 756, + nil, nil, 756, nil, nil, 710, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 756, nil, + nil, nil, 756, 756, 756, 756, nil, 756, 756, 756, + 756, nil, nil, nil, nil, 756, 756, nil, nil, nil, + nil, nil, nil, 756, nil, 756, 756, 756, nil, nil, + 756, 756, 783, 783, 783, 783, 783, 783, 783, 783, + 783, 783, 783, 783, 783, 783, 783, 783, 783, 783, + 783, 783, 783, 783, 783, 783, nil, nil, nil, 783, + 783, 783, 783, 783, 783, 783, 783, 783, 783, nil, + nil, nil, nil, nil, 783, 783, 783, 783, 783, 783, + 783, 783, 783, nil, nil, 783, nil, nil, nil, nil, + nil, nil, nil, 783, 783, nil, 783, 783, 783, 783, + 783, 783, 783, nil, nil, 783, 783, nil, nil, nil, + 783, 783, 783, 783, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 783, 783, nil, + 783, 783, 783, 783, 783, 783, 783, 783, 783, 783, + 783, 783, nil, nil, 783, 927, 927, 927, 927, nil, + nil, nil, nil, nil, 1021, nil, 1021, 1021, 1021, 1021, + 1021, 927, 927, 927, 927, nil, nil, nil, 927, 1021, + nil, nil, nil, nil, 927, 927, nil, nil, 927, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 1021, nil, nil, nil, nil, nil, nil, 927, nil, + nil, 927, 1021, 1021, nil, 927, nil, 1021, 927, nil, + 927, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 927, nil, nil, nil, 927, 927, + 927, 927, nil, 927, 927, 927, 927, nil, nil, nil, + nil, 927, 927, 929, 929, 929, 929, 1021, nil, 927, + nil, 927, 927, 927, nil, nil, 927, 927, nil, 929, + 929, 929, 929, nil, nil, 1136, 929, 1136, 1136, 1136, + 1136, 1136, 929, 929, nil, nil, 929, nil, nil, nil, + 1136, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 929, nil, nil, 929, + nil, nil, 1136, 929, nil, nil, 929, nil, nil, nil, + nil, 1136, 1136, 1136, 1136, nil, nil, nil, 1136, nil, + nil, nil, 929, nil, nil, nil, 929, 929, 929, 929, + nil, 929, 929, 929, 929, nil, nil, nil, nil, 929, + 929, 932, 932, 932, 932, nil, nil, 929, nil, 929, + 929, 929, nil, nil, 929, 929, nil, 932, 932, 932, + 932, nil, nil, nil, 932, 932, nil, nil, nil, nil, + 932, 932, nil, nil, 932, 932, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 932, nil, nil, 932, nil, nil, + nil, 932, nil, nil, 932, nil, 932, nil, nil, nil, + nil, nil, nil, 932, nil, nil, nil, nil, nil, nil, + 932, nil, nil, nil, 932, 932, 932, 932, nil, 932, + 932, 932, 932, nil, nil, nil, nil, 932, 932, 933, + 933, 933, 933, nil, nil, 932, nil, 932, 932, 932, + nil, nil, 932, 932, nil, 933, 933, 933, 933, nil, + nil, nil, 933, 933, nil, nil, nil, nil, 933, 933, + nil, nil, 933, 933, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 933, nil, nil, 933, nil, nil, nil, 933, + nil, nil, 933, nil, 933, nil, nil, nil, nil, nil, + nil, 933, nil, nil, nil, nil, nil, nil, 933, nil, + nil, nil, 933, 933, 933, 933, nil, 933, 933, 933, + 933, nil, nil, nil, nil, 933, 933, 939, 939, 939, + 939, nil, nil, 933, nil, 933, 933, 933, nil, nil, + 933, 933, nil, 939, 939, 939, 939, nil, nil, 1204, + 939, 1204, 1204, 1204, 1204, 1204, 939, 939, nil, nil, + 939, nil, nil, nil, 1204, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 939, nil, nil, 939, nil, nil, 1204, 939, nil, nil, + 939, nil, 939, nil, nil, 1204, 1204, 1204, 1204, nil, + nil, nil, 1204, nil, nil, nil, 939, nil, nil, nil, + 939, 939, 939, 939, nil, 939, 939, 939, 939, nil, + nil, nil, nil, 939, 939, 945, 945, 945, 945, nil, + nil, 939, nil, 939, 939, 939, nil, nil, 939, 939, + nil, 945, 945, 945, 945, nil, nil, 1227, 945, 1227, + 1227, 1227, 1227, 1227, 945, 945, nil, nil, 945, nil, + nil, nil, 1227, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 945, nil, + nil, 945, nil, nil, 1227, 945, nil, nil, 945, nil, + nil, nil, nil, nil, nil, 1227, 1227, nil, nil, nil, + 1227, nil, nil, nil, 945, nil, nil, nil, 945, 945, + 945, 945, nil, 945, 945, 945, 945, nil, nil, nil, + nil, 945, 945, 946, 946, 946, 946, nil, nil, 945, + nil, 945, 945, 945, nil, nil, 945, 945, nil, 946, + 946, 946, 946, nil, nil, nil, 946, nil, nil, nil, + nil, nil, 946, 946, nil, nil, 946, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 946, nil, nil, 946, + nil, nil, nil, 946, nil, nil, 946, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 946, nil, nil, nil, 946, 946, 946, 946, + nil, 946, 946, 946, 946, nil, nil, nil, nil, 946, + 946, 988, 988, 988, 988, nil, nil, 946, nil, 946, + 946, 946, nil, nil, 946, 946, nil, 988, 988, 988, + 988, nil, nil, nil, 988, 988, nil, nil, nil, nil, + 988, 988, nil, nil, 988, 988, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 988, nil, nil, 988, nil, nil, + nil, 988, nil, nil, 988, nil, 988, nil, nil, nil, + nil, nil, nil, 988, nil, nil, nil, nil, nil, nil, + 988, nil, nil, nil, 988, 988, 988, 988, nil, 988, + 988, 988, 988, nil, nil, nil, nil, 988, 988, 1115, + 1115, 1115, 1115, nil, nil, 988, nil, 988, 988, 988, + nil, nil, 988, 988, nil, 1115, 1115, 1115, 1115, nil, + nil, nil, 1115, nil, nil, nil, nil, nil, 1115, 1115, + nil, nil, 1115, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1115, nil, nil, 1115, nil, nil, nil, 1115, + nil, nil, 1115, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 1115, nil, + nil, nil, 1115, 1115, 1115, 1115, nil, 1115, 1115, 1115, + 1115, nil, nil, nil, nil, 1115, 1115, 1123, 1123, 1123, + 1123, nil, nil, 1115, nil, 1115, 1115, 1115, nil, nil, + 1115, 1115, nil, 1123, 1123, 1123, 1123, nil, nil, nil, + 1123, nil, nil, nil, nil, nil, 1123, 1123, nil, nil, + 1123, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1123, nil, nil, 1123, nil, nil, nil, 1123, nil, nil, + 1123, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1123, nil, nil, nil, + 1123, 1123, 1123, 1123, nil, 1123, 1123, 1123, 1123, nil, + nil, nil, nil, 1123, 1123, 1127, 1127, 1127, 1127, nil, + nil, 1123, nil, 1123, 1123, 1123, nil, nil, 1123, 1123, + nil, 1127, 1127, 1127, 1127, nil, nil, nil, 1127, nil, + nil, nil, nil, nil, 1127, 1127, nil, nil, 1127, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 1127, nil, + nil, 1127, nil, nil, nil, 1127, nil, nil, 1127, nil, + 1127, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1127, nil, nil, nil, 1127, 1127, + 1127, 1127, nil, 1127, 1127, 1127, 1127, nil, nil, nil, + nil, 1127, 1127, 1202, 1202, 1202, 1202, nil, nil, 1127, + nil, 1127, 1127, 1127, nil, nil, 1127, 1127, nil, 1202, + 1202, 1202, 1202, nil, nil, nil, 1202, nil, nil, nil, + nil, nil, 1202, 1202, nil, nil, 1202, nil, nil, nil, + nil, nil, nil, nil, 766, 766, 766, 766, nil, nil, + nil, nil, nil, nil, nil, nil, 1202, nil, nil, 1202, + 766, 766, 766, 1202, nil, nil, 1202, nil, nil, nil, + nil, nil, nil, 766, 766, nil, nil, 766, nil, nil, + nil, nil, 1202, nil, nil, nil, 1202, 1202, 1202, 1202, + nil, 1202, 1202, 1202, 1202, nil, nil, nil, nil, 1202, + 1202, nil, nil, nil, nil, nil, nil, 1202, nil, 1202, + 1202, 1202, nil, nil, 1202, 1202, 971, nil, 971, 971, + 971, 971, 971, nil, nil, nil, nil, 766, 766, 766, + 766, 971, 766, 766, 766, 766, nil, nil, nil, nil, + 766, 766, 952, 952, 952, 952, nil, nil, 766, nil, + 766, 766, 766, 971, nil, nil, nil, nil, 952, 952, + 952, nil, 971, 971, 971, 971, nil, nil, nil, 971, + nil, 952, 952, nil, nil, 952, 953, 953, 953, 953, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 953, 953, 953, 971, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 953, 953, nil, nil, 953, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 952, 952, 952, 952, nil, + 952, 952, 952, 952, nil, nil, nil, nil, 952, 952, + nil, nil, nil, nil, nil, nil, 952, nil, 952, 952, + 952, nil, nil, nil, nil, nil, nil, nil, nil, 953, + 953, 953, 953, nil, 953, 953, 953, 953, nil, nil, + nil, nil, 953, 953, nil, nil, nil, nil, nil, nil, + 953, nil, 953, 953, 953, 706, nil, 706, 706, 706, + 706, 706, nil, 708, nil, 708, 708, 708, 708, 708, + 706, nil, nil, nil, nil, nil, nil, nil, 708, nil, + 1019, nil, 1019, 1019, 1019, 1019, 1019, nil, nil, nil, + nil, nil, 706, nil, nil, 1019, nil, nil, nil, nil, + 708, 706, 706, 706, 706, nil, nil, nil, 706, 708, + 708, 708, 708, nil, nil, nil, 708, 1019, nil, nil, + nil, nil, nil, nil, nil, nil, 1019, 1019, 1019, 1019, + nil, nil, 1023, 1019, 1023, 1023, 1023, 1023, 1023, 1025, + nil, 1025, 1025, 1025, 1025, 1025, nil, 1023, 706, nil, + nil, nil, nil, nil, 1025, nil, 708, 1164, nil, 1164, + 1164, 1164, 1164, 1164, nil, nil, nil, nil, nil, 1023, + nil, nil, 1164, 1019, nil, nil, 1025, nil, nil, nil, + 1023, 1023, nil, nil, nil, 1023, nil, 1025, 1025, nil, + nil, nil, 1025, nil, 1164, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 1164, 1164, nil, nil, nil, + 1164, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 226, 226, nil, 1023, 226, nil, nil, nil, + nil, nil, 1025, nil, 226, 226, nil, 226, 226, 226, + 226, 226, 226, 226, nil, nil, 226, 226, nil, nil, + 1164, 226, 226, 226, 226, nil, nil, nil, nil, nil, + 226, nil, nil, nil, nil, nil, nil, nil, 226, 226, + nil, 226, 226, 226, 226, 226, 226, 226, 226, 226, + 226, 226, 226, 227, 227, 226, nil, 227, nil, nil, + nil, nil, nil, nil, nil, 227, 227, nil, 227, 227, + 227, 227, 227, 227, 227, nil, nil, 227, 227, nil, + nil, nil, 227, 227, 227, 227, nil, nil, nil, nil, + nil, 227, nil, nil, nil, nil, nil, nil, nil, 227, + 227, nil, 227, 227, 227, 227, 227, 227, 227, 227, + 227, 227, 227, 227, 303, 303, 227, nil, 303, nil, + nil, nil, nil, nil, nil, nil, 303, 303, nil, 303, + 303, 303, 303, 303, 303, 303, nil, nil, 303, 303, + nil, nil, nil, 303, 303, 303, 303, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 303, 303, nil, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 303, 521, 521, 303, nil, 521, + nil, nil, nil, nil, nil, nil, nil, 521, 521, nil, + 521, 521, 521, 521, 521, 521, 521, nil, nil, 521, + 521, nil, nil, nil, 521, 521, 521, 521, nil, nil, + nil, nil, nil, 521, nil, nil, nil, nil, nil, nil, + nil, 521, 521, nil, 521, 521, 521, 521, 521, 521, + 521, 521, 521, 521, 521, 521, 522, 522, 521, nil, + 522, nil, nil, nil, nil, nil, nil, nil, 522, 522, + nil, 522, 522, 522, 522, 522, 522, 522, nil, nil, + 522, 522, nil, nil, nil, 522, 522, 522, 522, nil, + nil, nil, nil, nil, 522, nil, nil, nil, nil, nil, + nil, nil, 522, 522, nil, 522, 522, 522, 522, 522, + 522, 522, 522, 522, 522, 522, 522, 594, 594, 522, + nil, 594, nil, nil, nil, nil, nil, nil, nil, 594, + 594, nil, 594, 594, 594, 594, 594, 594, 594, nil, + nil, 594, 594, nil, nil, nil, 594, 594, 594, 594, + nil, nil, nil, nil, nil, 594, nil, nil, nil, nil, + nil, nil, nil, 594, 594, nil, 594, 594, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 595, 595, + 594, nil, 595, nil, nil, nil, nil, nil, nil, nil, + 595, 595, nil, 595, 595, 595, 595, 595, 595, 595, + nil, nil, 595, 595, nil, nil, nil, 595, 595, 595, + 595, nil, nil, nil, nil, nil, 595, nil, nil, nil, + nil, nil, nil, nil, 595, 595, nil, 595, 595, 595, + 595, 595, 595, 595, 595, 595, 595, 595, 595, 604, + 604, 595, nil, 604, nil, nil, nil, nil, nil, nil, + nil, 604, 604, nil, 604, 604, 604, 604, 604, 604, + 604, nil, nil, 604, 604, nil, nil, nil, 604, 604, + 604, 604, nil, nil, nil, nil, nil, 604, nil, nil, + nil, nil, nil, nil, nil, 604, 604, nil, 604, 604, + 604, 604, 604, 604, 604, 604, 604, 604, 604, 604, + 605, 605, 604, nil, 605, nil, nil, nil, nil, nil, + nil, nil, 605, 605, nil, 605, 605, 605, 605, 605, + 605, 605, nil, nil, 605, 605, nil, nil, nil, 605, + 605, 605, 605, nil, nil, nil, nil, nil, 605, nil, + nil, nil, nil, nil, nil, nil, 605, 605, nil, 605, + 605, 605, 605, 605, 605, 605, 605, 605, 605, 605, + 605, 632, 632, 605, nil, 632, nil, nil, nil, nil, + nil, nil, nil, 632, 632, nil, 632, 632, 632, 632, + 632, 632, 632, nil, nil, 632, 632, nil, nil, nil, + 632, 632, 632, 632, nil, nil, nil, nil, nil, 632, + nil, nil, nil, nil, nil, nil, nil, 632, 632, nil, + 632, 632, 632, 632, 632, 632, 632, 632, 632, 632, + 632, 632, 633, 633, 632, nil, 633, nil, nil, nil, + nil, nil, nil, nil, 633, 633, nil, 633, 633, 633, + 633, 633, 633, 633, nil, nil, 633, 633, nil, nil, + nil, 633, 633, 633, 633, nil, nil, nil, nil, nil, + 633, nil, nil, nil, nil, nil, nil, nil, 633, 633, + nil, 633, 633, 633, 633, 633, 633, 633, 633, 633, + 633, 633, 633, 639, 639, 633, nil, 639, nil, nil, + nil, nil, nil, nil, nil, 639, 639, nil, 639, 639, + 639, 639, 639, 639, 639, nil, nil, 639, 639, nil, + nil, nil, 639, 639, 639, 639, nil, nil, nil, nil, + nil, 639, nil, nil, nil, nil, nil, nil, nil, 639, + 639, nil, 639, 639, 639, 639, 639, 639, 639, 639, + 639, 639, 639, 639, 640, 640, 639, nil, 640, nil, + nil, nil, nil, nil, nil, nil, 640, 640, nil, 640, + 640, 640, 640, 640, 640, 640, nil, nil, 640, 640, + nil, nil, nil, 640, 640, 640, 640, nil, nil, nil, + nil, nil, 640, nil, nil, nil, nil, nil, nil, nil, + 640, 640, nil, 640, 640, 640, 640, 640, 640, 640, + 640, 640, 640, 640, 640, 677, 677, 640, nil, 677, + nil, nil, nil, nil, nil, nil, nil, 677, 677, nil, + 677, 677, 677, 677, 677, 677, 677, nil, nil, 677, + 677, nil, nil, nil, 677, 677, 677, 677, nil, nil, + nil, nil, nil, 677, nil, nil, nil, nil, nil, nil, + nil, 677, 677, nil, 677, 677, 677, 677, 677, 677, + 677, 677, 677, 677, 677, 677, 678, 678, 677, nil, + 678, nil, nil, nil, nil, nil, nil, nil, 678, 678, + nil, 678, 678, 678, 678, 678, 678, 678, nil, nil, + 678, 678, nil, nil, nil, 678, 678, 678, 678, nil, + nil, nil, nil, nil, 678, nil, nil, nil, nil, nil, + nil, nil, 678, 678, nil, 678, 678, 678, 678, 678, + 678, 678, 678, 678, 678, 678, 678, 1161, 1161, 678, + nil, 1161, nil, nil, nil, nil, nil, nil, nil, 1161, + 1161, nil, 1161, 1161, 1161, 1161, 1161, 1161, 1161, nil, + nil, 1161, 1161, nil, nil, nil, 1161, 1161, 1161, 1161, + nil, nil, nil, nil, nil, 1161, nil, nil, nil, nil, + nil, nil, nil, 1161, 1161, nil, 1161, 1161, 1161, 1161, + 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1161, 1162, 1162, + 1161, nil, 1162, nil, nil, nil, nil, nil, nil, nil, + 1162, 1162, nil, 1162, 1162, 1162, 1162, 1162, 1162, 1162, + nil, nil, 1162, 1162, nil, nil, nil, 1162, 1162, 1162, + 1162, nil, nil, nil, nil, nil, 1162, nil, nil, nil, + nil, nil, nil, nil, 1162, 1162, nil, 1162, 1162, 1162, + 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1162, 1185, + 1185, 1162, nil, 1185, nil, nil, nil, nil, nil, nil, + nil, 1185, 1185, nil, 1185, 1185, 1185, 1185, 1185, 1185, + 1185, nil, nil, 1185, 1185, nil, nil, nil, 1185, 1185, + 1185, 1185, nil, nil, nil, nil, nil, 1185, nil, nil, + nil, nil, nil, nil, nil, 1185, 1185, nil, 1185, 1185, + 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, 1185, + nil, nil, 1185 ] + +racc_action_pointer = [ + nil, 204, 979, 226, nil, -110, nil, 5154, 964, 144, + 24967, 25095, 159, nil, 157, 176, 525, 279, -62, -84, + 162, 374, nil, -71, 5285, 1123, 25479, 358, nil, 171, + nil, -8, 5426, 5536, 5670, 5801, 5932, nil, 1123, 23109, + 23240, nil, 281, 525, 531, 368, 6063, 6194, 205, 6325, + 6456, 525, 6587, 318, 342, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 6728, nil, 6869, 7000, 7131, 35, + nil, 7262, 7393, nil, nil, 7524, 23379, 23510, 23641, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 612, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 0, 112, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 7667, nil, nil, nil, nil, + 7810, 7941, 8072, 8203, 8346, nil, 1267, nil, 588, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 345, nil, 1411, + 8477, 8608, 8739, 8870, 9001, 9132, 27591, 27652, nil, nil, + 363, 1555, 372, nil, 719, 831, 384, 1699, 9263, 9394, + 9525, nil, nil, 514, -23, 141, 480, 193, 409, 536, + nil, 9656, 307, 388, 1843, 541, nil, nil, 9787, 9918, + 10049, 10180, 10311, 10442, 10573, 10704, 10835, 10966, 11097, 11228, + 11359, 11490, 11621, 11752, 11883, 12014, 12145, 12276, 12407, 12538, + nil, nil, nil, nil, 12669, nil, nil, 226, 302, 515, + 517, 518, 532, 550, 558, 584, 585, nil, nil, nil, + 12800, nil, nil, 27713, nil, nil, 541, 12931, 13062, nil, + nil, nil, nil, nil, nil, nil, 13193, nil, 1843, nil, + 512, 532, nil, 13324, 585, 13455, nil, nil, 13586, 13717, + nil, nil, 221, nil, 13860, 1252, 599, 579, 1987, 626, + 687, 648, 23772, 2131, 694, 806, 873, 748, 878, nil, + 724, 691, 225, 743, 748, nil, nil, nil, 750, 221, + 707, 23911, nil, 564, 879, 3283, 3427, 778, nil, 779, + 13991, nil, 757, 2275, 1396, 721, nil, 139, 574, 760, + 743, 583, 773, nil, 577, -1, 11, 14122, 2419, 2563, + 264, 845, 727, -18, 10, 893, 810, 11, 842, nil, + nil, 441, 481, 513, nil, 962, nil, 761, 14253, nil, + 15821, nil, 193, 378, 396, 402, 412, -41, -27, 463, + nil, nil, nil, nil, nil, nil, nil, 756, 25223, nil, + nil, nil, nil, 759, nil, 835, 746, 14384, 747, nil, + nil, 736, nil, 968, 246, 850, nil, nil, 1267, nil, + nil, nil, nil, nil, 1411, 764, nil, 763, 765, 615, + 669, 14525, nil, nil, nil, nil, 222, 334, 825, nil, + nil, 14657, 14793, 14930, 908, 913, nil, nil, -1, 793, + 792, 800, nil, nil, 805, 816, 818, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 807, 3125, nil, nil, + 15061, nil, nil, nil, nil, nil, nil, nil, 902, nil, + nil, 907, 361, 15192, 950, nil, nil, nil, -35, nil, + 870, 27774, 27835, 15323, 253, 15454, 15585, 15716, 823, 828, + 25562, 25660, 3571, 3715, -45, 1018, 908, 912, 925, 927, + 5285, 5375, 5488, 3859, 4003, 4147, 4291, 4435, 4579, 3311, + 3455, 4723, 4867, 1987, 5011, nil, -33, nil, 15857, nil, + nil, nil, nil, 15987, 886, 885, 889, nil, nil, nil, + 892, nil, nil, 16118, nil, 16249, nil, 16380, nil, 329, + nil, nil, nil, 16523, 1540, nil, 918, 917, nil, nil, + 918, 24042, 923, 16666, 27896, 27957, 972, 968, nil, nil, + 24173, 925, nil, 16797, 28018, 28079, 16928, 5154, 17059, nil, + 1051, 932, 976, nil, 17190, nil, nil, 17321, nil, nil, + nil, 2707, 1056, nil, 2851, 62, 1060, 1064, 508, 1066, + 17452, 17583, 28140, 28201, 27, nil, nil, 995, nil, 28262, + 28323, 17714, nil, nil, 81, 2995, nil, 15851, nil, nil, + nil, nil, 1033, nil, nil, nil, 958, nil, nil, 153, + nil, 263, nil, nil, 944, nil, 947, nil, nil, nil, + 25351, nil, 17857, 950, 17988, 18119, 18250, 28384, 28445, 18393, + 18524, 693, 991, 18655, 18786, 18917, 19048, 997, nil, nil, + 19179, 19310, 1002, nil, 1060, 1555, 1091, 19441, nil, nil, + nil, nil, 888, nil, nil, 544, 27424, nil, 27432, nil, + 25811, nil, 961, 19572, nil, 3154, nil, 976, 978, 729, + 983, nil, nil, nil, nil, 1087, 1699, nil, nil, nil, + 277, 286, 473, 612, 1001, 19703, 19834, nil, -77, nil, + nil, nil, nil, 1023, nil, nil, nil, 582, 25758, 94, + nil, 1002, 1085, 1006, nil, nil, 25857, nil, nil, 303, + nil, nil, 654, nil, nil, 6728, 27202, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 838, 612, + nil, nil, 1016, 26000, nil, 1140, nil, 1123, 91, nil, + nil, 19965, nil, 1038, 1050, 1156, nil, 1046, nil, 1096, + 20096, nil, nil, 20227, nil, 245, 24304, 1070, nil, 1074, + 236, 250, 1120, 360, 1123, 1124, 1084, 24435, nil, 1153, + 2131, 20358, nil, nil, nil, 604, 738, nil, 1208, nil, + nil, nil, nil, nil, 1218, 1226, nil, nil, 26, 1106, + 40, 41, 151, 152, 3139, 970, 1267, nil, 1107, 3283, + 20489, nil, 1238, 63, 1118, nil, nil, nil, nil, nil, + 3427, nil, nil, nil, nil, nil, nil, nil, nil, 1117, + 20620, 1123, 306, 343, 722, 834, nil, 2275, 20751, nil, + 1122, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 20882, 21013, 1248, nil, 3571, 1124, 1173, nil, nil, + 1131, nil, 1223, nil, nil, 1142, 1143, nil, 1146, 1147, + nil, 1148, nil, nil, nil, 1153, 3184, 3164, nil, nil, + 21144, 21275, 21406, 21537, 21668, 21799, 347, 26083, 1252, 26181, + -41, 252, 26279, 26377, 622, -32, 1174, 1176, nil, 26475, + nil, 1175, 359, nil, 1196, 26573, 26671, nil, 637, 1236, + 333, nil, 27300, 27334, nil, nil, nil, nil, 21930, nil, + nil, 22061, nil, nil, 1218, nil, nil, 1234, 1218, nil, + nil, 27255, 3715, nil, nil, nil, nil, 1220, 338, nil, + -7, nil, 1345, nil, 22192, 1348, nil, nil, 26769, 22323, + 3859, 68, 1352, nil, 1354, 442, 4003, nil, nil, nil, + nil, 1231, 1281, 1252, 1247, 445, nil, nil, 22454, 2419, + 2563, nil, 4147, nil, nil, 32, 24566, nil, nil, 27449, + nil, 26073, nil, 27501, nil, 27508, nil, nil, nil, nil, + 1248, 1258, 2707, 2851, 22585, nil, 1259, nil, nil, nil, + nil, 1264, 1267, 1269, 1271, 1274, 1278, nil, nil, nil, + 1331, 1286, 1287, nil, 1293, nil, nil, 122, 1291, nil, + nil, nil, nil, nil, nil, 1295, 2995, 4291, nil, nil, + 1294, 1314, nil, 1315, 1317, 1319, nil, 1344, 1337, 1326, + 24697, nil, nil, nil, nil, nil, 33, nil, 34, 728, + nil, 615, nil, nil, nil, 1482, 4435, 4579, 1109, nil, + nil, nil, 4723, 35, 36, 1165, 1437, 42, nil, 1364, + 1365, 1368, 1372, 3651, 3795, 26867, nil, nil, nil, nil, + nil, nil, nil, 26965, nil, 370, nil, 27063, nil, nil, + 1444, nil, nil, 15876, nil, nil, 26184, nil, 14588, nil, + nil, 1398, 24828, 1309, 1460, 4867, nil, 22716, 22847, nil, + nil, nil, nil, 1410, 1515, 636, nil, nil, nil, 1518, + 22978, 28506, 28567, 98, 27526, nil, nil, nil, nil, 1397, + 1402, 1403, nil, nil, 1404, nil, nil, 1405, 1408, 1412, + 1413, nil, 1419, nil, 1411, 28628, nil, 797, 5011, nil, + nil, nil, nil, nil, 1829, nil, 1432, 102, 138, 145, + 181, 1430, 27161, nil, 26478, nil, 23287, nil, 23819, nil, + 25549, nil, nil, 1475, 1478, nil, 38, nil, 146, nil, + 1435, 1436, 1438, 1458, nil, nil, nil, 26576, nil, nil, + nil, nil, 1459, nil ] + +racc_action_default = [ + -1, -741, -4, -741, -2, -727, -5, -741, -8, -741, + -741, -741, -741, -31, -741, -741, -36, -741, -741, -637, + -637, -313, -52, -729, -741, -61, -741, -69, -70, -71, + -75, -287, -287, -287, -326, -354, -355, -87, -13, -91, + -99, -101, -741, -624, -625, -741, -741, -741, -741, -741, + -741, -239, -741, -729, -258, -304, -305, -306, -307, -308, + -309, -310, -311, -312, -717, -315, -319, -740, -705, -335, + -337, -741, -741, -63, -63, -727, -741, -741, -741, -356, + -357, -359, -360, -361, -362, -421, -563, -564, -565, -566, + -587, -569, -570, -589, -591, -574, -579, -583, -585, -601, + -602, -603, -587, -605, -607, -608, -609, -610, -611, -612, + -613, -715, -716, -616, -617, -618, -619, -620, -621, -622, + -623, -628, -629, 1234, -3, -728, -736, -737, -738, -7, + -741, -741, -741, -741, -741, -9, -4, -19, -741, -130, + -131, -132, -133, -134, -135, -136, -140, -141, -142, -143, + -144, -145, -146, -147, -148, -149, -150, -151, -152, -153, + -154, -155, -156, -157, -158, -159, -160, -161, -162, -163, + -164, -165, -166, -167, -168, -169, -170, -171, -172, -173, + -174, -175, -176, -177, -178, -179, -180, -181, -182, -183, + -184, -185, -186, -187, -188, -189, -190, -191, -192, -193, + -194, -195, -196, -197, -198, -199, -200, -201, -202, -203, + -204, -205, -206, -207, -208, -209, -210, -24, -137, -13, + -741, -741, -741, -741, -741, -277, -741, -741, -725, -726, + -741, -13, -636, -634, -660, -660, -741, -13, -741, -741, + -729, -730, -56, -741, -624, -625, -741, -313, -741, -741, + -245, -741, -637, -637, -13, -741, -57, -59, -222, -223, + -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, + -741, -741, -741, -741, -741, -741, -741, -741, -741, -741, + -259, -260, -261, -262, -741, -65, -66, -741, -130, -131, + -170, -171, -172, -188, -193, -200, -203, -624, -625, -703, + -741, -430, -432, -741, -723, -724, -76, -277, -741, -334, + -436, -445, -447, -82, -442, -83, -729, -84, -265, -282, + -292, -292, -286, -290, -293, -295, -587, -707, -711, -714, + -85, -86, -727, -14, -741, -17, -741, -89, -13, -729, + -741, -92, -95, -13, -107, -108, -741, -741, -115, -326, + -329, -729, -741, -637, -637, -354, -355, -358, -443, -741, + -97, -741, -103, -323, -741, -224, -225, -606, -233, -234, + -741, -246, -251, -13, -317, -729, -266, -729, -729, -741, + -741, -729, -741, -336, -62, -741, -741, -741, -13, -13, + -727, -741, -728, -624, -625, -741, -741, -313, -741, -372, + -373, -125, -126, -741, -128, -741, -313, -632, -741, -350, + -660, -567, -741, -741, -741, -741, -741, -741, -741, -741, + -6, -739, -25, -26, -27, -28, -29, -741, -741, -21, + -22, -23, -138, -741, -32, -35, -300, -295, -741, -299, + -33, -741, -37, -741, -313, -49, -51, -211, -270, -293, + -53, -54, -38, -212, -270, -729, -278, -292, -292, -715, + -716, -287, -440, -717, -718, -719, -716, -715, -287, -439, + -441, -717, -719, -741, -555, -741, -385, -386, -686, -729, + -702, -702, -642, -643, -645, -645, -645, -659, -661, -662, + -663, -664, -665, -666, -667, -668, -669, -741, -671, -673, + -675, -680, -682, -683, -684, -691, -693, -694, -696, -697, + -698, -700, -741, -741, -741, -48, -219, -55, -729, -333, + -741, -741, -741, -277, -323, -741, -741, -741, -741, -741, + -741, -741, -220, -221, -226, -227, -228, -229, -230, -231, + -235, -236, -237, -238, -240, -241, -242, -243, -244, -247, + -248, -249, -250, -729, -263, -67, -729, -451, -287, -715, + -716, -73, -77, -661, -729, -292, -729, -288, -449, -451, + -729, -328, -283, -741, -284, -741, -289, -741, -294, -741, + -710, -713, -12, -728, -16, -18, -729, -88, -321, -104, + -93, -741, -729, -277, -741, -741, -114, -741, -636, -606, + -741, -100, -105, -741, -741, -741, -741, -264, -741, -330, + -741, -729, -741, -267, -735, -734, -269, -735, -324, -325, + -706, -13, -363, -364, -13, -741, -741, -741, -741, -741, + -741, -277, -741, -741, -323, -63, -125, -126, -127, -741, + -741, -277, -346, -630, -741, -13, -422, -660, -425, -568, + -588, -593, -741, -595, -571, -590, -741, -592, -573, -741, + -576, -741, -578, -581, -741, -582, -741, -604, -10, -20, + -741, -30, -741, -303, -741, -741, -277, -741, -741, -741, + -741, -444, -741, -279, -281, -741, -741, -78, -276, -437, + -741, -741, -80, -438, -44, -254, -740, -740, -352, -524, + -685, -635, -741, -640, -641, -741, -741, -652, -741, -655, + -741, -657, -741, -741, -374, -741, -376, -378, -381, -384, + -729, -674, -695, -699, -638, -46, -256, -353, -332, -731, + -715, -716, -715, -716, -729, -741, -741, -58, -465, -468, + -469, -470, -471, -473, -475, -478, -479, -534, -729, -491, + -494, -504, -508, -513, -515, -516, -519, -520, -587, -523, + -525, -526, -527, -532, -533, -741, -741, -537, -538, -539, + -540, -541, -542, -543, -544, -545, -546, -547, -741, -741, + -553, -60, -741, -741, -704, -741, -452, -72, -433, -449, + -272, -279, -274, -741, -411, -741, -327, -292, -291, -296, + -298, -708, -709, -741, -15, -90, -741, -96, -102, -729, + -715, -716, -275, -720, -113, -741, -98, -741, -218, -232, + -252, -741, -316, -318, -320, -729, -740, -365, -740, -64, + -366, -367, -340, -341, -741, -741, -457, -343, -741, -729, + -715, -716, -720, -322, -13, -125, -126, -129, -729, -13, + -741, -348, -741, -741, -729, -594, -597, -598, -599, -600, + -13, -572, -575, -577, -580, -584, -586, -139, -34, -301, + -298, -729, -715, -716, -716, -715, -50, -271, -741, -732, + -292, -40, -214, -41, -215, -79, -42, -217, -43, -216, + -81, -741, -741, -740, -370, -13, -556, -740, -557, -558, + -702, -681, -686, -701, -644, -645, -645, -672, -645, -645, + -692, -645, -669, -388, -687, -729, -741, -741, -383, -670, + -741, -741, -741, -741, -741, -741, -444, -466, -741, -741, + -476, -477, -741, -741, -741, -496, -729, -729, -490, -497, + -501, -741, -741, -493, -741, -741, -741, -507, -514, -518, + -741, -522, -530, -531, -535, -536, -548, -549, -741, -126, + -551, -741, -68, -431, -411, -435, -434, -741, -729, -446, + -412, -729, -13, -448, -285, -297, -712, -94, -444, -106, + -729, -268, -741, -368, -741, -741, -342, -344, -741, -741, + -13, -444, -741, -444, -741, -741, -13, -351, -423, -426, + -428, -415, -741, -741, -302, -444, -39, -213, -280, -45, + -255, -11, -13, -562, -371, -741, -741, -560, -639, -741, + -648, -741, -650, -741, -653, -741, -656, -658, -375, -377, + -379, -382, -47, -257, -741, -467, -504, -472, -474, -483, + -487, -729, -729, -729, -729, -729, -729, -552, -488, -489, + -511, -498, -499, -502, -729, -587, -733, -729, -505, -509, + -512, -517, -521, -528, -529, -729, -253, -13, -74, -273, + -702, -702, -392, -394, -394, -394, -410, -741, -729, -669, + -677, -678, -689, -450, -331, -338, -741, -339, -741, -462, + -296, -740, -345, -347, -631, -741, -13, -13, -741, -424, + -596, -561, -13, -624, -625, -741, -741, -313, -559, -645, + -645, -645, -645, -741, -741, -741, -480, -481, -482, -484, + -485, -486, -503, -741, -492, -741, -495, -741, -550, -453, + -741, -390, -391, -395, -401, -403, -741, -406, -741, -408, + -413, -741, -741, -676, -741, -13, -458, -741, -741, -454, + -455, -456, -349, -741, -741, -729, -417, -419, -420, -555, + -277, -741, -741, -323, -741, -646, -649, -651, -654, -380, + -505, -500, -506, -510, -702, -679, -393, -394, -394, -394, + -394, -690, -394, -414, -688, -741, -323, -740, -13, -463, + -464, -427, -429, -416, -741, -554, -729, -715, -716, -720, + -322, -645, -741, -389, -741, -398, -741, -400, -741, -404, + -741, -407, -409, -322, -720, -369, -740, -418, -444, -647, + -394, -394, -394, -394, -459, -460, -461, -741, -396, -399, + -402, -405, -394, -397 ] + +racc_goto_table = [ + 44, 412, 475, 341, 340, 44, 142, 142, 514, 319, + 319, 319, 696, 419, 233, 233, 226, 302, 286, 638, + 496, 496, 142, 285, 298, 383, 128, 304, 455, 385, + 386, 714, 893, 390, 137, 218, 44, 345, 345, 145, + 145, 713, 15, 629, 357, 357, 835, 15, 388, 389, + 566, 703, 704, 900, 461, 468, 907, 621, 624, 737, + 781, 562, 376, 125, 44, 135, 574, 310, 314, 982, + 439, 440, 242, 124, 394, 298, 298, 798, 15, 798, + 801, 357, 357, 357, 306, 313, 315, 237, 422, 423, + 424, 425, 367, 910, 303, 906, 128, 908, 793, 17, + 740, 740, 446, 360, 17, 446, 15, 337, 1029, 601, + 564, 613, 616, 479, 512, 620, 399, 487, 487, 446, + 720, 1031, 801, 44, 707, 709, 711, 1036, 320, 320, + 320, 558, 44, 1002, 44, 17, 4, 972, 339, 1052, + 943, 452, 129, 391, 610, 785, 1074, 1, 903, 1156, + 1158, 903, 2, 1181, 1011, 515, 804, 795, 936, 1043, + 1046, 377, 217, 17, 985, 15, 407, 409, 400, 1054, + 659, 661, 598, 598, 15, 435, 15, 954, 955, 8, + 317, 330, 331, 428, 8, 433, 530, 798, 798, 801, + 531, 829, 1051, 287, 783, 789, 496, 759, 759, 1059, + 319, 670, 370, 574, 1058, 608, 379, 788, 299, 380, + 398, 642, 373, 655, 657, 660, 660, 44, 611, 375, + 340, 1181, 17, 472, 821, 849, 996, 645, 1030, 44, + 937, 17, 1076, 17, 1134, 44, 1078, 579, 1155, 230, + 236, 521, 646, 374, 998, 1217, 1158, 233, 233, 714, + 1077, 410, 44, 918, 853, 847, 738, 738, 1096, 15, + 420, 441, 462, 1097, 441, 557, 568, 569, 434, 445, + 427, 15, 445, 964, 1149, 1088, 1224, 15, 441, 988, + 834, 1188, 319, 319, 1037, 304, 445, 1038, 932, 648, + 933, 319, 942, 487, 15, 798, 321, 321, 321, 945, + 1060, 1061, 8, 957, 340, 897, 1029, 1067, 1177, 340, + 1015, 426, 411, 8, 438, 438, 17, 1169, 17, 967, + 237, 17, 464, 464, 413, 602, 734, 1172, 17, 378, + 381, 414, 44, 415, 17, 17, 44, 1035, 915, 807, + 345, 44, 1041, 1044, 594, 625, 416, 357, 816, 461, + 468, 17, 555, 128, 626, 627, 417, 1141, 418, 345, + 1075, 855, 604, 860, 1063, 1064, 357, 850, 1059, 902, + 905, 44, 901, 1170, 15, 907, 1059, 1175, 15, nil, + 1173, 1171, nil, 15, nil, nil, 44, 44, 310, nil, + 583, nil, 585, 632, 314, 960, 809, nil, nil, 464, + 582, 565, 320, 599, 910, 590, nil, 337, 1109, nil, + 320, 128, 337, 15, 1042, 1045, 852, 1072, nil, nil, + nil, 237, 812, nil, 142, 761, 761, 1150, 15, 15, + 1215, 17, 812, 496, 839, 17, nil, nil, 586, nil, + 17, 677, 885, 592, 848, 1124, nil, 890, 694, nil, + 714, 714, 669, nil, 567, 1173, nil, 145, 628, 863, + 812, 863, 570, nil, nil, nil, 239, nil, 812, nil, + 17, 1018, 528, 529, 935, nil, 384, 384, nil, 871, + 384, 1174, 949, 907, nil, 17, 17, nil, 725, nil, + nil, nil, 496, 519, 496, nil, 372, 688, 319, nil, + nil, nil, nil, nil, 693, 461, 468, nil, nil, nil, + 990, 584, 798, 801, 687, nil, nil, 1089, 472, nil, + nil, 692, 1178, nil, nil, 1179, 854, nil, 775, 775, + 487, nil, nil, 724, 968, 384, 384, 384, 384, 909, + nil, 911, 974, nil, nil, 1020, 1022, 898, 1024, 1026, + 1047, 1027, 1225, nil, 977, 602, 446, 462, 740, 981, + 907, nil, nil, nil, 602, nil, 446, 446, 319, 571, + 321, 446, 446, nil, nil, nil, 903, nil, 321, 1072, + nil, 44, 1072, nil, 1072, nil, nil, 826, nil, 345, + 828, 472, 587, 1220, 688, nil, 357, nil, 345, 759, + 759, 472, 881, 883, nil, 357, 319, 886, 888, 759, + 844, 787, nil, nil, nil, 759, 319, 464, 464, 44, + 994, nil, 44, 15, 1142, 974, nil, 450, 451, 472, + 462, nil, nil, nil, 1226, 472, nil, nil, nil, nil, + 462, 1131, 1132, 44, 517, 518, 830, 714, 714, nil, + 1072, 319, 1072, 935, 1072, 759, 1072, nil, 935, 935, + nil, 15, nil, nil, 15, 851, 142, nil, 462, 950, + 44, 1057, nil, 1072, 472, nil, 462, 44, nil, nil, + 17, nil, nil, nil, nil, 15, nil, 1102, nil, nil, + 464, 464, 899, nil, 867, nil, nil, 1195, nil, 145, + 464, 464, nil, nil, nil, 556, nil, nil, nil, nil, + nil, nil, 15, 462, 738, 441, nil, nil, 17, 15, + nil, 17, nil, 445, 838, 441, 441, nil, 464, 464, + 441, 441, 701, 445, 445, 464, 464, nil, 445, 445, + nil, nil, 17, 1151, 966, 1203, 775, nil, 1071, 1165, + 1166, 1167, 1168, nil, 775, nil, nil, 1079, 1145, 446, + 1146, nil, nil, 775, 775, nil, nil, 1095, nil, 17, + 602, 728, 17, 464, 464, 962, 17, 965, nil, 142, + 285, 979, 17, 17, nil, nil, nil, 17, 17, nil, + nil, 438, 384, nil, 597, 1006, nil, 902, nil, nil, + nil, nil, 1073, nil, 345, 496, nil, nil, 995, 784, + 992, 357, nil, 644, nil, 345, nil, 790, 612, 792, + 615, 615, 357, 796, 615, nil, 1003, 761, 761, nil, + nil, nil, nil, nil, nil, 797, nil, 761, 1129, 805, + 1080, 1219, 44, 761, nil, 808, nil, 44, 688, 868, + 1110, 693, 1111, nil, 1112, nil, 876, nil, 44, nil, + nil, 1014, nil, nil, 823, nil, nil, nil, 1154, nil, + nil, nil, nil, nil, nil, nil, 825, nil, nil, nil, + nil, nil, nil, 761, 15, nil, nil, 453, 1013, 15, + nil, nil, 1017, 44, nil, nil, nil, nil, 682, nil, + 15, 516, nil, nil, nil, nil, nil, nil, nil, nil, + 1071, nil, nil, 1071, 382, 1071, 1065, nil, 441, 1079, + nil, nil, 1079, nil, nil, 775, 445, 775, nil, nil, + 775, 775, nil, nil, nil, 15, nil, 775, 1083, nil, + nil, 17, 1086, 775, 775, 880, 17, nil, nil, nil, + 775, 775, nil, nil, nil, nil, 1091, 17, nil, nil, + nil, nil, nil, 1196, nil, nil, 1125, 1180, nil, 1182, + 44, nil, nil, 919, nil, 17, nil, nil, 1101, nil, + nil, 1071, nil, 1071, nil, 1071, 775, 1071, 44, 812, + 1079, nil, 17, nil, 44, 1201, 782, nil, nil, 1080, + nil, nil, 1080, nil, 1071, 1080, nil, 1080, nil, nil, + 44, nil, 15, nil, 1104, nil, 1094, nil, nil, nil, + nil, 357, nil, nil, nil, nil, nil, nil, nil, nil, + 15, nil, nil, nil, nil, 1221, 15, 1222, nil, 1223, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 15, 880, nil, nil, 1108, nil, 1232, nil, + nil, nil, 1153, nil, nil, 44, 436, 449, 1159, 17, + nil, nil, nil, 1080, nil, 1080, nil, 1080, 298, 1080, + nil, nil, nil, nil, nil, 357, 18, 17, nil, nil, + nil, 18, nil, 17, 44, 44, 1080, 1135, 1137, 1139, + 44, nil, nil, 1161, nil, 1189, 1190, 15, 243, 17, + nil, 1187, nil, 775, nil, nil, nil, nil, 243, 243, + 243, 775, 18, 346, 346, 775, nil, nil, nil, nil, + nil, nil, 681, nil, nil, 319, 15, 15, nil, nil, + 298, nil, 15, 44, nil, nil, nil, 357, nil, nil, + 18, nil, nil, nil, 1216, 243, 243, nil, 472, 243, + 395, 405, 405, nil, 17, nil, nil, nil, 1028, 576, + nil, 578, nil, nil, 580, 581, nil, 682, nil, nil, + nil, 472, nil, 1039, nil, 15, 44, nil, 516, nil, + 453, 682, 944, 17, 17, nil, nil, 462, nil, 17, + 775, 1205, 1207, 1209, 1211, nil, 1212, nil, nil, 18, + nil, nil, nil, nil, 243, 243, 243, 243, 18, nil, + 18, 1069, nil, nil, nil, nil, 980, nil, 15, nil, + nil, nil, nil, 1084, nil, nil, nil, nil, nil, nil, + nil, nil, 17, nil, 1228, 1229, 1230, 1231, nil, nil, + nil, nil, 682, nil, nil, 384, 1233, 464, 464, nil, + nil, nil, nil, nil, nil, nil, 818, nil, 615, nil, + nil, nil, nil, nil, nil, nil, nil, 767, 767, nil, + nil, 464, 682, 673, nil, 17, nil, nil, nil, nil, + nil, 682, nil, nil, 1116, 1117, 1118, 1001, nil, nil, + nil, nil, nil, 18, 243, 443, 243, 243, 443, 243, + 1126, nil, nil, nil, 682, 18, nil, nil, 1128, nil, + nil, 18, 443, 243, 243, nil, nil, nil, nil, nil, + nil, nil, 19, nil, nil, nil, nil, 19, 18, nil, + nil, nil, nil, nil, nil, nil, 721, nil, 882, 884, + nil, nil, nil, 887, 889, nil, nil, nil, nil, nil, + nil, nil, nil, 384, nil, nil, nil, nil, 19, 353, + 353, nil, nil, nil, 682, nil, nil, nil, nil, 682, + 682, nil, nil, nil, 243, 768, 768, nil, nil, 384, + nil, 243, 243, nil, nil, nil, 19, nil, nil, nil, + 243, nil, nil, nil, nil, 20, 353, 353, 353, nil, + 20, 926, nil, nil, 1001, nil, nil, nil, 18, 799, + nil, 382, 18, 802, nil, 938, 346, 18, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 20, 354, 354, nil, 346, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 19, nil, 18, nil, nil, + 799, nil, nil, 382, 19, nil, 19, nil, nil, 20, + nil, 243, 18, 18, nil, nil, 449, nil, nil, 354, + 354, 354, nil, nil, nil, nil, 978, 682, 682, 682, + nil, nil, 243, nil, nil, 767, nil, 944, nil, nil, + nil, nil, nil, 767, nil, nil, nil, nil, nil, nil, + nil, nil, 767, 767, nil, nil, 991, nil, nil, nil, + 869, 1001, nil, nil, nil, 993, nil, nil, 20, 799, + 382, nil, nil, nil, nil, nil, nil, 20, nil, 20, + nil, 1007, nil, 896, nil, nil, nil, nil, 1005, 19, + nil, 19, 384, 384, 19, nil, nil, 243, nil, 914, + nil, 19, nil, nil, nil, nil, nil, 19, 19, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 19, 882, 884, 889, 887, nil, + nil, nil, nil, nil, nil, nil, nil, 243, 1193, nil, + nil, nil, nil, 768, nil, nil, nil, 243, 1040, nil, + nil, 768, nil, 1048, 1049, nil, nil, nil, nil, nil, + 768, 768, 20, nil, 20, nil, nil, 20, nil, nil, + nil, nil, nil, nil, 20, nil, nil, 799, nil, 682, + 20, 20, nil, nil, nil, nil, 975, nil, nil, 976, + nil, nil, nil, nil, nil, nil, nil, 20, nil, nil, + nil, 769, 769, nil, 19, nil, nil, 18, 19, nil, + nil, nil, 353, 19, 767, 346, 767, 243, nil, 767, + 767, nil, nil, nil, 346, nil, 767, nil, nil, nil, + nil, 353, 767, 767, nil, nil, nil, 1007, nil, 767, + 767, nil, nil, 19, nil, 18, nil, nil, 18, nil, + nil, nil, nil, nil, nil, 243, 1004, nil, 19, 19, + nil, 1119, 1120, 1121, nil, 243, nil, nil, nil, 18, + nil, nil, nil, nil, nil, 767, nil, 20, nil, nil, + nil, 20, nil, nil, nil, 354, 20, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 18, nil, nil, 443, + 243, nil, nil, 18, 354, nil, nil, nil, nil, 443, + 443, nil, nil, nil, 443, 443, 20, nil, nil, nil, + nil, nil, 768, nil, 768, nil, nil, 768, 768, nil, + nil, 20, 20, nil, 768, nil, nil, nil, nil, nil, + 768, 768, nil, nil, nil, nil, nil, 768, 768, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 1090, nil, nil, nil, nil, + nil, nil, nil, 768, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 382, nil, nil, nil, nil, nil, + nil, nil, 767, nil, nil, nil, nil, nil, nil, nil, + 767, nil, nil, 1218, 767, nil, nil, nil, nil, 769, + nil, nil, nil, nil, nil, nil, nil, 769, nil, nil, + 346, nil, nil, nil, nil, nil, 769, 769, nil, nil, + nil, 346, nil, nil, nil, 243, nil, nil, nil, 21, + nil, nil, nil, 19, 21, nil, nil, nil, nil, nil, + nil, 353, nil, nil, nil, nil, nil, nil, 18, nil, + 353, nil, nil, 18, 243, nil, nil, nil, nil, nil, + nil, nil, 770, 770, 18, 21, 348, 348, nil, 767, + nil, 19, nil, nil, 19, nil, nil, nil, nil, nil, + nil, nil, 443, nil, nil, nil, nil, nil, nil, nil, + 768, nil, nil, 21, nil, 19, nil, nil, 768, 18, + 771, 771, 768, 397, 406, 406, 20, nil, nil, nil, + nil, nil, nil, nil, 354, nil, nil, nil, nil, nil, + nil, nil, 19, 354, nil, 19, nil, nil, nil, 19, + nil, nil, nil, nil, nil, 19, 19, nil, nil, nil, + 19, 19, nil, nil, 20, nil, nil, 20, nil, nil, + nil, nil, 21, nil, nil, nil, nil, nil, 772, 772, + nil, 21, 243, 21, nil, nil, nil, nil, 20, nil, + nil, nil, nil, nil, nil, nil, 18, 768, 769, nil, + 769, nil, nil, 769, 769, nil, nil, nil, 243, nil, + 769, nil, nil, nil, 18, 20, 769, 769, 20, nil, + 18, nil, 20, 769, 769, nil, nil, nil, 20, 20, + nil, nil, nil, 20, 20, nil, 18, nil, nil, nil, + 1105, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 769, + nil, nil, nil, nil, nil, nil, 21, nil, 444, nil, + nil, 444, nil, nil, nil, nil, 353, nil, 21, nil, + nil, nil, nil, nil, 21, 444, nil, 353, nil, nil, + nil, 18, nil, nil, nil, nil, nil, nil, nil, nil, + 770, 21, nil, nil, 1143, nil, nil, nil, 770, nil, + nil, nil, nil, nil, 19, nil, nil, 770, 770, 19, + 18, 18, nil, nil, nil, nil, 18, nil, nil, nil, + 19, nil, nil, nil, nil, nil, nil, nil, 771, nil, + nil, nil, nil, nil, nil, nil, 771, nil, 19, 354, + nil, nil, nil, nil, nil, 771, 771, nil, nil, nil, + 354, nil, nil, nil, nil, 19, 1184, nil, nil, 18, + nil, 243, 243, nil, nil, nil, nil, nil, nil, nil, + nil, 21, nil, nil, 243, 21, 769, 20, nil, 348, + 21, nil, 20, nil, 769, nil, 772, nil, 769, nil, + nil, nil, nil, 20, 772, nil, nil, nil, 348, nil, + nil, nil, 18, 772, 772, nil, nil, nil, nil, nil, + 21, 20, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 21, 21, nil, 20, nil, + nil, nil, 19, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 19, nil, nil, nil, nil, nil, 19, nil, nil, nil, + nil, nil, nil, 769, nil, nil, nil, nil, nil, 770, + nil, 770, 19, nil, 770, 770, 353, nil, nil, nil, + nil, 770, nil, nil, nil, nil, nil, 770, 770, nil, + nil, nil, nil, nil, 770, 770, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 20, nil, 771, nil, 771, + nil, nil, 771, 771, nil, nil, nil, nil, nil, 771, + nil, nil, nil, 20, nil, 771, 771, 19, nil, 20, + 770, nil, 771, 771, nil, nil, nil, nil, nil, nil, + 353, nil, nil, nil, nil, 20, nil, nil, nil, 354, + nil, nil, nil, nil, nil, nil, 19, 19, nil, nil, + nil, nil, 19, nil, nil, 772, nil, 772, 771, nil, + 772, 772, nil, nil, nil, nil, nil, 772, nil, nil, + nil, nil, nil, 772, 772, nil, nil, nil, nil, nil, + 772, 772, nil, nil, nil, nil, nil, nil, nil, nil, + 20, nil, 353, 773, 773, 19, nil, nil, nil, nil, + nil, nil, nil, 354, nil, nil, nil, nil, nil, nil, + 21, nil, nil, nil, nil, nil, 772, nil, 348, 20, + 20, nil, nil, nil, nil, 20, nil, 348, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 19, nil, + nil, nil, nil, nil, nil, nil, nil, 770, 21, nil, + nil, 21, nil, nil, nil, 770, nil, nil, nil, 770, + nil, nil, 31, nil, nil, 354, nil, 31, 20, nil, + nil, nil, 21, nil, nil, nil, nil, nil, nil, 859, + nil, nil, nil, nil, 31, 771, nil, nil, nil, nil, + nil, nil, nil, 771, 31, 31, 31, 771, 31, 21, + nil, nil, 444, nil, 43, nil, 21, nil, nil, 43, + nil, 20, 444, 444, nil, nil, nil, 444, 444, nil, + nil, nil, nil, nil, nil, nil, 31, nil, 297, nil, + nil, 31, 31, nil, 770, 31, nil, nil, nil, nil, + 43, 344, 344, 772, nil, nil, nil, nil, nil, nil, + nil, 772, nil, nil, nil, 772, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 43, nil, + nil, nil, 771, nil, nil, nil, nil, nil, 393, 297, + 297, nil, nil, nil, nil, 31, nil, nil, nil, nil, + 31, 31, 31, 31, 31, nil, 31, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 773, nil, nil, nil, nil, nil, nil, nil, 773, + nil, nil, nil, nil, nil, nil, nil, 43, 773, 773, + 772, nil, nil, 348, nil, nil, 43, nil, 43, nil, + nil, nil, nil, nil, 348, nil, nil, nil, nil, nil, + nil, nil, 774, 774, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 21, nil, nil, nil, nil, 21, nil, nil, 31, + 31, 31, 31, 31, 31, 31, nil, 21, nil, nil, + nil, 31, nil, nil, nil, nil, nil, 31, 31, 31, + 31, nil, nil, nil, nil, 444, nil, nil, nil, nil, + nil, nil, nil, nil, 31, nil, nil, nil, nil, nil, + nil, 43, 21, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 43, nil, nil, nil, nil, nil, 43, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 43, nil, nil, nil, + 31, nil, nil, nil, nil, nil, nil, 31, 31, nil, + nil, nil, nil, nil, nil, nil, 31, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 773, nil, 773, nil, 31, 773, 773, nil, 31, 21, + nil, nil, 773, 31, nil, nil, nil, nil, 773, 773, + nil, nil, nil, nil, nil, 773, 773, 21, nil, nil, + nil, nil, nil, 21, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 31, nil, nil, 43, nil, nil, 21, + 43, nil, nil, 1107, 344, 43, nil, 31, 31, 31, + nil, 773, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 344, nil, nil, nil, nil, 31, nil, + 774, nil, nil, nil, nil, 43, nil, 34, 774, nil, + nil, nil, 34, nil, nil, nil, nil, 774, 774, nil, + 43, 43, nil, nil, 21, nil, nil, nil, nil, 34, + nil, nil, nil, nil, nil, nil, nil, 406, nil, 34, + 34, 34, nil, 34, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 21, 21, nil, nil, nil, nil, 21, + nil, nil, nil, 31, nil, nil, nil, nil, nil, nil, + nil, 34, nil, nil, nil, nil, 34, 34, nil, nil, + 34, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 406, + 776, 776, 21, 31, nil, nil, nil, nil, 773, nil, + nil, nil, nil, 31, nil, nil, 773, nil, nil, nil, + 773, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 34, nil, nil, nil, nil, 34, 34, 34, 34, 34, + nil, 34, nil, nil, nil, 21, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 31, nil, nil, nil, nil, nil, 774, + nil, 774, nil, 31, 774, 774, nil, nil, nil, nil, + nil, 774, nil, nil, nil, 773, nil, 774, 774, nil, + nil, nil, nil, nil, 774, 774, nil, nil, nil, nil, + nil, 31, nil, nil, 31, 43, nil, nil, nil, nil, + nil, 31, nil, 344, 34, 34, 34, 34, 34, 34, + 34, 31, 344, nil, nil, 31, 34, nil, nil, nil, + 774, nil, 34, 34, 34, 34, nil, nil, nil, nil, + nil, nil, nil, 43, nil, nil, 43, nil, nil, 34, + nil, nil, 31, nil, nil, 31, 31, nil, nil, 31, + nil, nil, nil, nil, nil, 31, 31, 43, nil, nil, + 31, 31, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 43, 34, nil, nil, nil, nil, + nil, 43, 34, 34, nil, nil, nil, nil, 776, nil, + nil, 34, nil, nil, nil, nil, 776, nil, nil, nil, + nil, nil, nil, nil, nil, 776, 776, nil, nil, 34, + nil, nil, nil, 34, nil, nil, nil, nil, 34, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 774, nil, nil, + nil, nil, nil, nil, nil, 774, nil, nil, 34, 774, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 34, 34, 34, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 31, nil, 34, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 31, nil, nil, nil, 344, 31, + 31, nil, nil, nil, nil, nil, nil, nil, nil, 344, + 31, nil, nil, nil, 774, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 31, nil, + nil, nil, nil, nil, nil, nil, 43, nil, 34, nil, + nil, 43, nil, nil, nil, 31, nil, nil, nil, nil, + nil, nil, 43, nil, nil, nil, nil, 776, nil, 776, + nil, nil, 776, 776, nil, nil, nil, nil, nil, 776, + nil, nil, nil, nil, nil, 776, 776, nil, 34, nil, + nil, nil, 776, 776, nil, nil, nil, 43, 34, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 31, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 776, nil, + nil, nil, 31, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 31, nil, nil, nil, nil, nil, + 31, nil, nil, nil, nil, nil, 31, nil, 34, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 34, nil, + nil, nil, 31, nil, 43, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 43, nil, nil, nil, 34, nil, 43, 34, + nil, nil, nil, nil, nil, nil, 34, nil, nil, nil, + nil, nil, nil, nil, 43, nil, 34, nil, 1103, nil, + 34, nil, nil, nil, nil, nil, nil, 31, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 34, nil, nil, + 34, 34, nil, nil, 34, 776, 31, 31, nil, nil, + 34, 34, 31, 776, nil, 34, 34, 776, 250, 43, + nil, nil, nil, nil, nil, nil, nil, nil, 318, 318, + 318, nil, 297, nil, nil, nil, nil, nil, nil, nil, + 365, 366, nil, 368, 369, nil, 371, nil, 43, 43, + nil, nil, nil, nil, 43, 31, nil, 31, 31, nil, + nil, 318, 318, nil, nil, nil, nil, nil, nil, nil, + 31, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 776, nil, 297, nil, nil, 43, 31, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 43, nil, nil, nil, nil, nil, 34, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 34, + nil, nil, nil, nil, 34, 34, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 34, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 34, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 318, 448, nil, nil, 454, 318, + 34, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 454, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 250, nil, nil, nil, nil, + nil, nil, 532, 533, 534, 535, 536, 537, 538, 539, + 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, + 550, 551, 552, 553, nil, nil, nil, nil, 554, nil, + nil, nil, nil, 34, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 34, nil, nil, + nil, 318, 318, nil, nil, nil, nil, nil, nil, 34, + 318, nil, nil, nil, nil, 34, nil, 318, nil, 318, + nil, 34, 318, 318, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 34, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 607, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 34, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 34, 34, nil, nil, nil, nil, 34, nil, nil, + nil, 318, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 695, nil, nil, + 34, nil, 34, 34, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 34, nil, nil, nil, nil, + nil, nil, nil, nil, 318, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 726, nil, nil, + nil, nil, nil, 34, nil, nil, nil, 318, nil, 454, + 454, 454, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 366, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 318, nil, 318, + nil, 318, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 318, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 454, nil, nil, + 819, nil, 820, nil, nil, nil, nil, nil, 318, nil, + nil, 318, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 318, 318, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 318, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 318, 454, + 318, nil, nil, nil, 877, nil, nil, 318, 318, 454, + 454, nil, nil, nil, 454, 454, nil, nil, nil, nil, + nil, 318, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 318, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 695, + 726, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 318, nil, nil, nil, nil, + nil, nil, nil, nil, 318, nil, nil, 318, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 318, nil, nil, nil, nil, nil, + nil, nil, 454, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 1009, 1010, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1032, 1033, 454, 454, 454, 454, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 1066, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 318, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 318, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 454, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 318 ] + +racc_goto_check = [ + 72, 198, 10, 68, 11, 72, 75, 75, 10, 36, + 36, 36, 12, 198, 87, 87, 33, 158, 46, 73, + 230, 230, 75, 48, 72, 107, 117, 33, 31, 19, + 19, 128, 13, 19, 17, 17, 72, 72, 72, 77, + 77, 135, 23, 112, 82, 82, 113, 23, 44, 44, + 92, 139, 139, 133, 55, 55, 231, 110, 110, 41, + 41, 57, 87, 7, 72, 9, 94, 91, 91, 111, + 24, 24, 22, 5, 72, 72, 72, 95, 23, 95, + 239, 82, 82, 82, 56, 56, 56, 119, 19, 19, + 19, 19, 80, 235, 51, 146, 117, 146, 58, 29, + 177, 177, 20, 69, 29, 20, 23, 64, 127, 70, + 31, 89, 89, 157, 157, 89, 23, 225, 225, 20, + 129, 130, 239, 72, 228, 228, 228, 192, 88, 88, + 88, 55, 72, 149, 72, 29, 2, 147, 65, 192, + 187, 28, 6, 5, 10, 161, 145, 1, 140, 151, + 152, 140, 3, 236, 14, 28, 16, 161, 175, 178, + 178, 88, 18, 29, 13, 23, 74, 74, 21, 178, + 214, 214, 224, 224, 23, 25, 23, 202, 202, 8, + 63, 63, 63, 27, 8, 11, 42, 95, 95, 239, + 43, 45, 191, 50, 52, 60, 230, 200, 200, 191, + 36, 78, 83, 94, 193, 84, 86, 93, 105, 106, + 114, 116, 120, 215, 215, 215, 215, 72, 121, 122, + 11, 236, 29, 75, 123, 124, 125, 126, 131, 72, + 176, 29, 136, 29, 142, 72, 143, 198, 150, 35, + 35, 33, 153, 8, 154, 151, 152, 87, 87, 128, + 149, 155, 72, 128, 156, 73, 174, 174, 159, 23, + 6, 23, 91, 160, 23, 162, 164, 165, 22, 22, + 2, 23, 22, 168, 169, 170, 171, 23, 23, 172, + 112, 173, 36, 36, 180, 33, 22, 182, 183, 157, + 184, 36, 188, 225, 23, 95, 90, 90, 90, 189, + 195, 196, 8, 205, 11, 206, 127, 147, 145, 11, + 207, 8, 210, 8, 88, 88, 29, 130, 29, 58, + 119, 29, 61, 61, 211, 68, 31, 192, 29, 90, + 90, 212, 72, 213, 29, 29, 72, 175, 129, 70, + 72, 72, 175, 175, 33, 19, 216, 82, 70, 55, + 55, 29, 51, 117, 11, 11, 217, 149, 218, 72, + 146, 219, 33, 220, 202, 202, 82, 223, 191, 200, + 229, 72, 233, 193, 23, 231, 191, 234, 23, nil, + 191, 193, nil, 23, nil, nil, 72, 72, 91, nil, + 7, nil, 9, 33, 91, 73, 31, nil, nil, 61, + 5, 88, 88, 80, 235, 69, nil, 64, 146, nil, + 88, 117, 64, 23, 176, 176, 10, 140, nil, nil, + nil, 119, 55, nil, 75, 201, 201, 13, 23, 23, + 111, 29, 55, 230, 31, 29, nil, nil, 65, nil, + 29, 33, 57, 65, 31, 187, nil, 57, 36, nil, + 128, 128, 17, nil, 63, 191, nil, 77, 5, 215, + 55, 215, 63, nil, nil, nil, 40, nil, 55, nil, + 29, 139, 35, 35, 174, nil, 26, 26, nil, 31, + 26, 133, 174, 231, nil, 29, 29, nil, 36, nil, + nil, nil, 230, 66, 230, nil, 40, 91, 36, nil, + nil, nil, nil, nil, 91, 55, 55, nil, nil, nil, + 110, 8, 95, 239, 56, nil, nil, 41, 75, nil, + nil, 56, 146, nil, nil, 146, 157, nil, 72, 72, + 225, nil, nil, 117, 92, 26, 26, 26, 26, 144, + nil, 144, 94, nil, nil, 228, 228, 24, 228, 228, + 73, 228, 13, nil, 70, 68, 20, 91, 177, 89, + 231, nil, nil, nil, 68, nil, 20, 20, 36, 66, + 90, 20, 20, nil, nil, nil, 140, nil, 90, 140, + nil, 72, 140, nil, 140, nil, nil, 11, nil, 72, + 11, 75, 66, 146, 91, nil, 82, nil, 72, 200, + 200, 75, 28, 28, nil, 82, 36, 28, 28, 200, + 44, 56, nil, nil, nil, 200, 36, 61, 61, 72, + 10, nil, 72, 23, 135, 94, nil, 26, 26, 75, + 91, nil, nil, nil, 113, 75, nil, nil, nil, nil, + 91, 139, 139, 72, 26, 26, 117, 128, 128, nil, + 140, 36, 140, 174, 140, 200, 140, nil, 174, 174, + nil, 23, nil, nil, 23, 117, 75, nil, 91, 198, + 72, 174, nil, 140, 75, nil, 91, 72, nil, nil, + 29, nil, nil, nil, nil, 23, nil, 110, nil, nil, + 61, 61, 87, nil, 17, nil, nil, 12, nil, 77, + 61, 61, nil, nil, nil, 26, nil, nil, nil, nil, + nil, nil, 23, 91, 174, 23, nil, nil, 29, 23, + nil, 29, nil, 22, 88, 23, 23, nil, 61, 61, + 23, 23, 66, 22, 22, 61, 61, nil, 22, 22, + nil, nil, 29, 112, 107, 139, 72, nil, 132, 228, + 228, 228, 228, nil, 72, nil, nil, 230, 110, 20, + 110, nil, nil, 72, 72, nil, nil, 10, nil, 29, + 68, 66, 29, 61, 61, 46, 29, 158, nil, 75, + 48, 68, 29, 29, nil, nil, nil, 29, 29, nil, + nil, 88, 26, nil, 40, 28, nil, 200, nil, nil, + nil, nil, 144, nil, 72, 230, nil, nil, 19, 66, + 11, 82, nil, 26, nil, 72, nil, 66, 40, 66, + 40, 40, 82, 66, 40, nil, 11, 201, 201, nil, + nil, nil, nil, nil, nil, 90, nil, 201, 10, 66, + 232, 228, 72, 201, nil, 66, nil, 72, 91, 8, + 144, 91, 144, nil, 144, nil, 8, nil, 72, nil, + nil, 11, nil, nil, 66, nil, nil, nil, 10, nil, + nil, nil, nil, nil, nil, nil, 90, nil, nil, nil, + nil, nil, nil, 201, 23, nil, nil, 79, 87, 23, + nil, nil, 87, 72, nil, nil, nil, nil, 40, nil, + 23, 79, nil, nil, nil, nil, nil, nil, nil, nil, + 132, nil, nil, 132, 85, 132, 19, nil, 23, 230, + nil, nil, 230, nil, nil, 72, 22, 72, nil, nil, + 72, 72, nil, nil, nil, 23, nil, 72, 11, nil, + nil, 29, 19, 72, 72, 90, 29, nil, nil, nil, + 72, 72, nil, nil, nil, nil, 11, 29, nil, nil, + nil, nil, nil, 31, nil, nil, 198, 144, nil, 144, + 72, nil, nil, 66, nil, 29, nil, nil, 11, nil, + nil, 132, nil, 132, nil, 132, 72, 132, 72, 55, + 230, nil, 29, nil, 72, 144, 40, nil, nil, 232, + nil, nil, 232, nil, 132, 232, nil, 232, nil, nil, + 72, nil, 23, nil, 72, nil, 117, nil, nil, nil, + nil, 82, nil, nil, nil, nil, nil, nil, nil, nil, + 23, nil, nil, nil, nil, 144, 23, 144, nil, 144, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 23, 90, nil, nil, 23, nil, 144, nil, + nil, nil, 11, nil, nil, 72, 85, 85, 11, 29, + nil, nil, nil, 232, nil, 232, nil, 232, 72, 232, + nil, nil, nil, nil, nil, 82, 30, 29, nil, nil, + nil, 30, nil, 29, 72, 72, 232, 141, 141, 141, + 72, nil, nil, 33, nil, 19, 19, 23, 30, 29, + nil, 11, nil, 72, nil, nil, nil, nil, 30, 30, + 30, 72, 30, 30, 30, 72, nil, nil, nil, nil, + nil, nil, 32, nil, nil, 36, 23, 23, nil, nil, + 72, nil, 23, 72, nil, nil, nil, 82, nil, nil, + 30, nil, nil, nil, 11, 30, 30, nil, 75, 30, + 30, 30, 30, nil, 29, nil, nil, nil, 66, 85, + nil, 85, nil, nil, 85, 85, nil, 40, nil, nil, + nil, 75, nil, 66, nil, 23, 72, nil, 79, nil, + 79, 40, 40, 29, 29, nil, nil, 91, nil, 29, + 72, 141, 141, 141, 141, nil, 141, nil, nil, 30, + nil, nil, nil, nil, 30, 30, 30, 30, 30, nil, + 30, 66, nil, nil, nil, nil, 26, nil, 23, nil, + nil, nil, nil, 66, nil, nil, nil, nil, nil, nil, + nil, nil, 29, nil, 141, 141, 141, 141, nil, nil, + nil, nil, 40, nil, nil, 26, 141, 61, 61, nil, + nil, nil, nil, nil, nil, nil, 79, nil, 40, nil, + nil, nil, nil, nil, nil, nil, nil, 97, 97, nil, + nil, 61, 40, 85, nil, 29, nil, nil, nil, nil, + nil, 40, nil, nil, 66, 66, 66, 40, nil, nil, + nil, nil, nil, 30, 30, 30, 30, 30, 30, 30, + 66, nil, nil, nil, 40, 30, nil, nil, 66, nil, + nil, 30, 30, 30, 30, nil, nil, nil, nil, nil, + nil, nil, 34, nil, nil, nil, nil, 34, 30, nil, + nil, nil, nil, nil, nil, nil, 85, nil, 79, 79, + nil, nil, nil, 79, 79, nil, nil, nil, nil, nil, + nil, nil, nil, 26, nil, nil, nil, nil, 34, 34, + 34, nil, nil, nil, 40, nil, nil, nil, nil, 40, + 40, nil, nil, nil, 30, 98, 98, nil, nil, 26, + nil, 30, 30, nil, nil, nil, 34, nil, nil, nil, + 30, nil, nil, nil, nil, 38, 34, 34, 34, nil, + 38, 32, nil, nil, 40, nil, nil, nil, 30, 85, + nil, 85, 30, 85, nil, 32, 30, 30, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 38, 38, 38, nil, 30, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 34, nil, 30, nil, nil, + 85, nil, nil, 85, 34, nil, 34, nil, nil, 38, + nil, 30, 30, 30, nil, nil, 85, nil, nil, 38, + 38, 38, nil, nil, nil, nil, 32, 40, 40, 40, + nil, nil, 30, nil, nil, 97, nil, 40, nil, nil, + nil, nil, nil, 97, nil, nil, nil, nil, nil, nil, + nil, nil, 97, 97, nil, nil, 32, nil, nil, nil, + 85, 40, nil, nil, nil, 32, nil, nil, 38, 85, + 85, nil, nil, nil, nil, nil, nil, 38, nil, 38, + nil, 79, nil, 85, nil, nil, nil, nil, 32, 34, + nil, 34, 26, 26, 34, nil, nil, 30, nil, 85, + nil, 34, nil, nil, nil, nil, nil, 34, 34, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 34, 79, 79, 79, 79, nil, + nil, nil, nil, nil, nil, nil, nil, 30, 40, nil, + nil, nil, nil, 98, nil, nil, nil, 30, 32, nil, + nil, 98, nil, 32, 32, nil, nil, nil, nil, nil, + 98, 98, 38, nil, 38, nil, nil, 38, nil, nil, + nil, nil, nil, nil, 38, nil, nil, 85, nil, 40, + 38, 38, nil, nil, nil, nil, 85, nil, nil, 85, + nil, nil, nil, nil, nil, nil, nil, 38, nil, nil, + nil, 99, 99, nil, 34, nil, nil, 30, 34, nil, + nil, nil, 34, 34, 97, 30, 97, 30, nil, 97, + 97, nil, nil, nil, 30, nil, 97, nil, nil, nil, + nil, 34, 97, 97, nil, nil, nil, 79, nil, 97, + 97, nil, nil, 34, nil, 30, nil, nil, 30, nil, + nil, nil, nil, nil, nil, 30, 85, nil, 34, 34, + nil, 32, 32, 32, nil, 30, nil, nil, nil, 30, + nil, nil, nil, nil, nil, 97, nil, 38, nil, nil, + nil, 38, nil, nil, nil, 38, 38, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 30, nil, nil, 30, + 30, nil, nil, 30, 38, nil, nil, nil, nil, 30, + 30, nil, nil, nil, 30, 30, 38, nil, nil, nil, + nil, nil, 98, nil, 98, nil, nil, 98, 98, nil, + nil, 38, 38, nil, 98, nil, nil, nil, nil, nil, + 98, 98, nil, nil, nil, nil, nil, 98, 98, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 85, nil, nil, nil, nil, + nil, nil, nil, 98, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 85, nil, nil, nil, nil, nil, + nil, nil, 97, nil, nil, nil, nil, nil, nil, nil, + 97, nil, nil, 32, 97, nil, nil, nil, nil, 99, + nil, nil, nil, nil, nil, nil, nil, 99, nil, nil, + 30, nil, nil, nil, nil, nil, 99, 99, nil, nil, + nil, 30, nil, nil, nil, 30, nil, nil, nil, 39, + nil, nil, nil, 34, 39, nil, nil, nil, nil, nil, + nil, 34, nil, nil, nil, nil, nil, nil, 30, nil, + 34, nil, nil, 30, 30, nil, nil, nil, nil, nil, + nil, nil, 100, 100, 30, 39, 39, 39, nil, 97, + nil, 34, nil, nil, 34, nil, nil, nil, nil, nil, + nil, nil, 30, nil, nil, nil, nil, nil, nil, nil, + 98, nil, nil, 39, nil, 34, nil, nil, 98, 30, + 101, 101, 98, 39, 39, 39, 38, nil, nil, nil, + nil, nil, nil, nil, 38, nil, nil, nil, nil, nil, + nil, nil, 34, 38, nil, 34, nil, nil, nil, 34, + nil, nil, nil, nil, nil, 34, 34, nil, nil, nil, + 34, 34, nil, nil, 38, nil, nil, 38, nil, nil, + nil, nil, 39, nil, nil, nil, nil, nil, 102, 102, + nil, 39, 30, 39, nil, nil, nil, nil, 38, nil, + nil, nil, nil, nil, nil, nil, 30, 98, 99, nil, + 99, nil, nil, 99, 99, nil, nil, nil, 30, nil, + 99, nil, nil, nil, 30, 38, 99, 99, 38, nil, + 30, nil, 38, 99, 99, nil, nil, nil, 38, 38, + nil, nil, nil, 38, 38, nil, 30, nil, nil, nil, + 30, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 99, + nil, nil, nil, nil, nil, nil, 39, nil, 39, nil, + nil, 39, nil, nil, nil, nil, 34, nil, 39, nil, + nil, nil, nil, nil, 39, 39, nil, 34, nil, nil, + nil, 30, nil, nil, nil, nil, nil, nil, nil, nil, + 100, 39, nil, nil, 30, nil, nil, nil, 100, nil, + nil, nil, nil, nil, 34, nil, nil, 100, 100, 34, + 30, 30, nil, nil, nil, nil, 30, nil, nil, nil, + 34, nil, nil, nil, nil, nil, nil, nil, 101, nil, + nil, nil, nil, nil, nil, nil, 101, nil, 34, 38, + nil, nil, nil, nil, nil, 101, 101, nil, nil, nil, + 38, nil, nil, nil, nil, 34, 30, nil, nil, 30, + nil, 30, 30, nil, nil, nil, nil, nil, nil, nil, + nil, 39, nil, nil, 30, 39, 99, 38, nil, 39, + 39, nil, 38, nil, 99, nil, 102, nil, 99, nil, + nil, nil, nil, 38, 102, nil, nil, nil, 39, nil, + nil, nil, 30, 102, 102, nil, nil, nil, nil, nil, + 39, 38, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 39, 39, nil, 38, nil, + nil, nil, 34, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 34, nil, nil, nil, nil, nil, 34, nil, nil, nil, + nil, nil, nil, 99, nil, nil, nil, nil, nil, 100, + nil, 100, 34, nil, 100, 100, 34, nil, nil, nil, + nil, 100, nil, nil, nil, nil, nil, 100, 100, nil, + nil, nil, nil, nil, 100, 100, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 38, nil, 101, nil, 101, + nil, nil, 101, 101, nil, nil, nil, nil, nil, 101, + nil, nil, nil, 38, nil, 101, 101, 34, nil, 38, + 100, nil, 101, 101, nil, nil, nil, nil, nil, nil, + 34, nil, nil, nil, nil, 38, nil, nil, nil, 38, + nil, nil, nil, nil, nil, nil, 34, 34, nil, nil, + nil, nil, 34, nil, nil, 102, nil, 102, 101, nil, + 102, 102, nil, nil, nil, nil, nil, 102, nil, nil, + nil, nil, nil, 102, 102, nil, nil, nil, nil, nil, + 102, 102, nil, nil, nil, nil, nil, nil, nil, nil, + 38, nil, 34, 103, 103, 34, nil, nil, nil, nil, + nil, nil, nil, 38, nil, nil, nil, nil, nil, nil, + 39, nil, nil, nil, nil, nil, 102, nil, 39, 38, + 38, nil, nil, nil, nil, 38, nil, 39, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 34, nil, + nil, nil, nil, nil, nil, nil, nil, 100, 39, nil, + nil, 39, nil, nil, nil, 100, nil, nil, nil, 100, + nil, nil, 59, nil, nil, 38, nil, 59, 38, nil, + nil, nil, 39, nil, nil, nil, nil, nil, nil, 39, + nil, nil, nil, nil, 59, 101, nil, nil, nil, nil, + nil, nil, nil, 101, 59, 59, 59, 101, 59, 39, + nil, nil, 39, nil, 71, nil, 39, nil, nil, 71, + nil, 38, 39, 39, nil, nil, nil, 39, 39, nil, + nil, nil, nil, nil, nil, nil, 59, nil, 71, nil, + nil, 59, 59, nil, 100, 59, nil, nil, nil, nil, + 71, 71, 71, 102, nil, nil, nil, nil, nil, nil, + nil, 102, nil, nil, nil, 102, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 71, nil, + nil, nil, 101, nil, nil, nil, nil, nil, 71, 71, + 71, nil, nil, nil, nil, 59, nil, nil, nil, nil, + 59, 59, 59, 59, 59, nil, 59, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 103, nil, nil, nil, nil, nil, nil, nil, 103, + nil, nil, nil, nil, nil, nil, nil, 71, 103, 103, + 102, nil, nil, 39, nil, nil, 71, nil, 71, nil, + nil, nil, nil, nil, 39, nil, nil, nil, nil, nil, + nil, nil, 104, 104, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 39, nil, nil, nil, nil, 39, nil, nil, 59, + 59, 59, 59, 59, 59, 59, nil, 39, nil, nil, + nil, 59, nil, nil, nil, nil, nil, 59, 59, 59, + 59, nil, nil, nil, nil, 39, nil, nil, nil, nil, + nil, nil, nil, nil, 59, nil, nil, nil, nil, nil, + nil, 71, 39, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 71, nil, nil, nil, nil, nil, 71, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 71, nil, nil, nil, + 59, nil, nil, nil, nil, nil, nil, 59, 59, nil, + nil, nil, nil, nil, nil, nil, 59, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 103, nil, 103, nil, 59, 103, 103, nil, 59, 39, + nil, nil, 103, 59, nil, nil, nil, nil, 103, 103, + nil, nil, nil, nil, nil, 103, 103, 39, nil, nil, + nil, nil, nil, 39, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 59, nil, nil, 71, nil, nil, 39, + 71, nil, nil, 39, 71, 71, nil, 59, 59, 59, + nil, 103, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 71, nil, nil, nil, nil, 59, nil, + 104, nil, nil, nil, nil, 71, nil, 62, 104, nil, + nil, nil, 62, nil, nil, nil, nil, 104, 104, nil, + 71, 71, nil, nil, 39, nil, nil, nil, nil, 62, + nil, nil, nil, nil, nil, nil, nil, 39, nil, 62, + 62, 62, nil, 62, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 39, 39, nil, nil, nil, nil, 39, + nil, nil, nil, 59, nil, nil, nil, nil, nil, nil, + nil, 62, nil, nil, nil, nil, 62, 62, nil, nil, + 62, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 39, + 109, 109, 39, 59, nil, nil, nil, nil, 103, nil, + nil, nil, nil, 59, nil, nil, 103, nil, nil, nil, + 103, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 62, nil, nil, nil, nil, 62, 62, 62, 62, 62, + nil, 62, nil, nil, nil, 39, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 59, nil, nil, nil, nil, nil, 104, + nil, 104, nil, 59, 104, 104, nil, nil, nil, nil, + nil, 104, nil, nil, nil, 103, nil, 104, 104, nil, + nil, nil, nil, nil, 104, 104, nil, nil, nil, nil, + nil, 59, nil, nil, 59, 71, nil, nil, nil, nil, + nil, 59, nil, 71, 62, 62, 62, 62, 62, 62, + 62, 59, 71, nil, nil, 59, 62, nil, nil, nil, + 104, nil, 62, 62, 62, 62, nil, nil, nil, nil, + nil, nil, nil, 71, nil, nil, 71, nil, nil, 62, + nil, nil, 59, nil, nil, 59, 59, nil, nil, 59, + nil, nil, nil, nil, nil, 59, 59, 71, nil, nil, + 59, 59, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 71, 62, nil, nil, nil, nil, + nil, 71, 62, 62, nil, nil, nil, nil, 109, nil, + nil, 62, nil, nil, nil, nil, 109, nil, nil, nil, + nil, nil, nil, nil, nil, 109, 109, nil, nil, 62, + nil, nil, nil, 62, nil, nil, nil, nil, 62, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 104, nil, nil, + nil, nil, nil, nil, nil, 104, nil, nil, 62, 104, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 62, 62, 62, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 59, nil, 62, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 59, nil, nil, nil, 71, 59, + 59, nil, nil, nil, nil, nil, nil, nil, nil, 71, + 59, nil, nil, nil, 104, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 59, nil, + nil, nil, nil, nil, nil, nil, 71, nil, 62, nil, + nil, 71, nil, nil, nil, 59, nil, nil, nil, nil, + nil, nil, 71, nil, nil, nil, nil, 109, nil, 109, + nil, nil, 109, 109, nil, nil, nil, nil, nil, 109, + nil, nil, nil, nil, nil, 109, 109, nil, 62, nil, + nil, nil, 109, 109, nil, nil, nil, 71, 62, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 59, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 109, nil, + nil, nil, 59, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 59, nil, nil, nil, nil, nil, + 59, nil, nil, nil, nil, nil, 59, nil, 62, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 62, nil, + nil, nil, 59, nil, 71, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 71, nil, nil, nil, 62, nil, 71, 62, + nil, nil, nil, nil, nil, nil, 62, nil, nil, nil, + nil, nil, nil, nil, 71, nil, 62, nil, 71, nil, + 62, nil, nil, nil, nil, nil, nil, 59, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 62, nil, nil, + 62, 62, nil, nil, 62, 109, 59, 59, nil, nil, + 62, 62, 59, 109, nil, 62, 62, 109, 37, 71, + nil, nil, nil, nil, nil, nil, nil, nil, 37, 37, + 37, nil, 71, nil, nil, nil, nil, nil, nil, nil, + 37, 37, nil, 37, 37, nil, 37, nil, 71, 71, + nil, nil, nil, nil, 71, 59, nil, 59, 59, nil, + nil, 37, 37, nil, nil, nil, nil, nil, nil, nil, + 59, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 109, nil, 71, nil, nil, 71, 59, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 71, nil, nil, nil, nil, nil, 62, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 62, + nil, nil, nil, nil, 62, 62, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 62, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 62, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 37, 37, nil, nil, 37, 37, + 62, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 37, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 37, nil, nil, nil, nil, + nil, nil, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, nil, nil, nil, nil, 37, nil, + nil, nil, nil, 62, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 62, nil, nil, + nil, 37, 37, nil, nil, nil, nil, nil, nil, 62, + 37, nil, nil, nil, nil, 62, nil, 37, nil, 37, + nil, 62, 37, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 62, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 62, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 62, 62, nil, nil, nil, nil, 62, nil, nil, + nil, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 37, nil, nil, + 62, nil, 62, 62, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 62, nil, nil, nil, nil, + nil, nil, nil, nil, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 37, nil, nil, + nil, nil, nil, 62, nil, nil, nil, 37, nil, 37, + 37, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 37, nil, 37, + nil, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 37, nil, nil, + 37, nil, 37, nil, nil, nil, nil, nil, 37, nil, + nil, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 37, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 37, 37, + 37, nil, nil, nil, 37, nil, nil, 37, 37, 37, + 37, nil, nil, nil, 37, 37, nil, nil, nil, nil, + nil, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 37, + 37, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 37, nil, nil, nil, nil, + nil, nil, nil, nil, 37, nil, nil, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 37, nil, nil, nil, nil, nil, + nil, nil, 37, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 37, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 37, 37, 37, 37, 37, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 37, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 37, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 37, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 37 ] + +racc_goto_pointer = [ + nil, 147, 134, 152, nil, 68, 135, 58, 177, 56, + -229, -34, -462, -664, -739, nil, -427, 24, 151, -42, + -119, 92, 48, 40, -150, -45, 405, 46, -83, 97, + 1084, -197, 677, -2, 1330, 220, -25, 3624, 1403, 1907, + 443, -471, -70, -67, -25, -434, -8, nil, -3, nil, + 167, 65, -361, nil, nil, -172, 53, -245, -470, 2540, + -366, 96, 2955, 146, 69, 100, 253, nil, -36, 63, + -252, 2582, -2, -384, 89, -4, nil, 29, -231, 663, + 44, nil, 5, 151, -167, 846, 139, -5, 94, -266, + 262, 36, -257, -351, -255, -496, nil, 747, 855, 1131, + 1412, 1450, 1508, 1943, 2202, 182, 141, -44, nil, 2520, + -328, -757, -348, -582, 134, nil, -196, 21, nil, 67, + 147, -156, 153, -385, -417, -625, -182, -808, -466, -377, + -796, -688, -223, -649, nil, -455, -739, nil, nil, -429, + -554, 24, -839, -735, -169, -825, -611, -657, nil, -721, + -860, -949, -948, -168, -609, 166, -392, -121, -10, -741, + -737, -412, -36, nil, -45, -45, nil, nil, -513, -817, + -713, -940, -557, -865, -274, -590, -518, -430, -773, nil, + -644, nil, -642, -459, -457, nil, nil, -609, -457, -451, + nil, -747, -800, -742, nil, -648, -647, nil, -89, nil, + -333, -105, -588, nil, nil, -475, -392, -587, nil, nil, + 224, 231, 237, 238, -245, -200, 250, 259, 260, -291, + -290, nil, nil, -276, -181, -117, nil, nil, -360, -336, + -214, -650, -131, -330, -753, -615, -983, nil, nil, -495 ] + +racc_goto_default = [ + nil, nil, nil, nil, 5, nil, 6, 392, 335, nil, + nil, 474, nil, 983, nil, 332, 333, nil, nil, nil, + 13, 14, 22, 248, nil, nil, 16, nil, 442, 249, + 364, nil, nil, 640, 252, nil, 27, 25, 253, 247, + 520, nil, nil, nil, nil, nil, nil, 387, 144, 26, + nil, nil, nil, 28, 29, 815, nil, nil, nil, 352, + nil, 30, 349, 456, 37, nil, nil, 39, 42, 41, + nil, 244, 245, 404, nil, 465, 143, 87, nil, 447, + 103, 51, 54, 284, nil, 324, nil, 894, 457, nil, + 458, 470, 483, 689, 572, 322, 308, 55, 56, 57, + 58, 59, 60, 61, 62, 63, nil, 309, 69, 70, + nil, nil, nil, nil, nil, 77, nil, 622, 78, 231, + nil, nil, nil, nil, nil, nil, nil, 716, 495, nil, + 717, 718, 481, 476, 477, nil, 1176, 712, 1070, nil, + 482, nil, nil, nil, 484, nil, 486, nil, 970, nil, + nil, nil, 493, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 469, nil, nil, 794, 786, nil, nil, + nil, nil, nil, nil, 1050, nil, 739, 940, 741, 742, + 746, 743, 744, nil, nil, 745, 747, nil, nil, nil, + 939, 941, 751, nil, 753, 754, 755, 756, nil, 760, + 478, 504, 762, 763, 764, 113, nil, nil, 86, 88, + 89, nil, nil, nil, nil, 650, nil, nil, nil, nil, + nil, 99, 100, nil, 232, 904, 235, 480, nil, 485, + 912, 498, 500, 501, 1081, 505, 1082, 508, 511, 327 ] + +racc_reduce_table = [ + 0, 0, :racc_error, + 0, 150, :_reduce_1, + 2, 148, :_reduce_2, + 2, 149, :_reduce_3, + 0, 151, :_reduce_4, + 1, 151, :_reduce_5, + 3, 151, :_reduce_6, + 2, 151, :_reduce_7, + 1, 153, :_reduce_none, + 2, 153, :_reduce_9, + 3, 156, :_reduce_10, + 4, 157, :_reduce_11, + 2, 158, :_reduce_12, + 0, 162, :_reduce_13, + 1, 162, :_reduce_14, + 3, 162, :_reduce_15, + 2, 162, :_reduce_16, + 1, 163, :_reduce_none, + 2, 163, :_reduce_18, + 0, 174, :_reduce_19, + 4, 155, :_reduce_20, + 3, 155, :_reduce_21, + 3, 155, :_reduce_22, + 3, 155, :_reduce_23, + 2, 155, :_reduce_24, + 3, 155, :_reduce_25, + 3, 155, :_reduce_26, + 3, 155, :_reduce_27, + 3, 155, :_reduce_28, + 3, 155, :_reduce_29, + 4, 155, :_reduce_30, + 1, 155, :_reduce_none, + 3, 155, :_reduce_32, + 3, 155, :_reduce_33, + 5, 155, :_reduce_34, + 3, 155, :_reduce_35, + 1, 155, :_reduce_none, + 3, 167, :_reduce_37, + 3, 167, :_reduce_38, + 6, 167, :_reduce_39, + 5, 167, :_reduce_40, + 5, 167, :_reduce_41, + 5, 167, :_reduce_42, + 5, 167, :_reduce_43, + 4, 167, :_reduce_44, + 6, 167, :_reduce_45, + 4, 167, :_reduce_46, + 6, 167, :_reduce_47, + 3, 167, :_reduce_48, + 1, 175, :_reduce_none, + 3, 175, :_reduce_50, + 1, 175, :_reduce_none, + 1, 173, :_reduce_none, + 3, 173, :_reduce_53, + 3, 173, :_reduce_54, + 3, 173, :_reduce_55, + 2, 173, :_reduce_56, + 0, 189, :_reduce_57, + 4, 173, :_reduce_58, + 0, 190, :_reduce_59, + 4, 173, :_reduce_60, + 1, 173, :_reduce_none, + 1, 166, :_reduce_none, + 0, 194, :_reduce_63, + 3, 191, :_reduce_64, + 1, 193, :_reduce_65, + 2, 181, :_reduce_66, + 0, 199, :_reduce_67, + 5, 185, :_reduce_68, + 1, 169, :_reduce_none, + 1, 169, :_reduce_none, + 1, 200, :_reduce_none, + 4, 200, :_reduce_72, + 0, 207, :_reduce_73, + 4, 204, :_reduce_74, + 1, 206, :_reduce_none, + 2, 183, :_reduce_76, + 3, 183, :_reduce_77, + 4, 183, :_reduce_78, + 5, 183, :_reduce_79, + 4, 183, :_reduce_80, + 5, 183, :_reduce_81, + 2, 183, :_reduce_82, + 2, 183, :_reduce_83, + 2, 183, :_reduce_84, + 2, 183, :_reduce_85, + 2, 183, :_reduce_86, + 1, 168, :_reduce_87, + 3, 168, :_reduce_88, + 1, 212, :_reduce_89, + 3, 212, :_reduce_90, + 1, 211, :_reduce_none, + 2, 211, :_reduce_92, + 3, 211, :_reduce_93, + 5, 211, :_reduce_94, + 2, 211, :_reduce_95, + 4, 211, :_reduce_96, + 2, 211, :_reduce_97, + 4, 211, :_reduce_98, + 1, 211, :_reduce_99, + 3, 211, :_reduce_100, + 1, 215, :_reduce_none, + 3, 215, :_reduce_102, + 2, 214, :_reduce_103, + 3, 214, :_reduce_104, + 1, 217, :_reduce_105, + 3, 217, :_reduce_106, + 1, 216, :_reduce_107, + 1, 216, :_reduce_108, + 4, 216, :_reduce_109, + 3, 216, :_reduce_110, + 3, 216, :_reduce_111, + 3, 216, :_reduce_112, + 3, 216, :_reduce_113, + 2, 216, :_reduce_114, + 1, 216, :_reduce_115, + 1, 170, :_reduce_116, + 1, 170, :_reduce_117, + 4, 170, :_reduce_118, + 3, 170, :_reduce_119, + 3, 170, :_reduce_120, + 3, 170, :_reduce_121, + 3, 170, :_reduce_122, + 2, 170, :_reduce_123, + 1, 170, :_reduce_124, + 1, 220, :_reduce_125, + 1, 220, :_reduce_none, + 2, 221, :_reduce_127, + 1, 221, :_reduce_128, + 3, 221, :_reduce_129, + 1, 195, :_reduce_none, + 1, 195, :_reduce_none, + 1, 195, :_reduce_none, + 1, 195, :_reduce_none, + 1, 195, :_reduce_none, + 1, 164, :_reduce_135, + 1, 164, :_reduce_none, + 1, 165, :_reduce_137, + 0, 225, :_reduce_138, + 4, 165, :_reduce_139, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 1, 223, :_reduce_none, + 3, 184, :_reduce_211, + 3, 184, :_reduce_212, + 6, 184, :_reduce_213, + 5, 184, :_reduce_214, + 5, 184, :_reduce_215, + 5, 184, :_reduce_216, + 5, 184, :_reduce_217, + 4, 184, :_reduce_218, + 3, 184, :_reduce_219, + 3, 184, :_reduce_220, + 3, 184, :_reduce_221, + 2, 184, :_reduce_222, + 2, 184, :_reduce_223, + 2, 184, :_reduce_224, + 2, 184, :_reduce_225, + 3, 184, :_reduce_226, + 3, 184, :_reduce_227, + 3, 184, :_reduce_228, + 3, 184, :_reduce_229, + 3, 184, :_reduce_230, + 3, 184, :_reduce_231, + 4, 184, :_reduce_232, + 2, 184, :_reduce_233, + 2, 184, :_reduce_234, + 3, 184, :_reduce_235, + 3, 184, :_reduce_236, + 3, 184, :_reduce_237, + 3, 184, :_reduce_238, + 1, 184, :_reduce_none, + 3, 184, :_reduce_240, + 3, 184, :_reduce_241, + 3, 184, :_reduce_242, + 3, 184, :_reduce_243, + 3, 184, :_reduce_244, + 2, 184, :_reduce_245, + 2, 184, :_reduce_246, + 3, 184, :_reduce_247, + 3, 184, :_reduce_248, + 3, 184, :_reduce_249, + 3, 184, :_reduce_250, + 0, 231, :_reduce_251, + 4, 184, :_reduce_252, + 6, 184, :_reduce_253, + 4, 184, :_reduce_254, + 6, 184, :_reduce_255, + 4, 184, :_reduce_256, + 6, 184, :_reduce_257, + 1, 184, :_reduce_none, + 1, 230, :_reduce_none, + 1, 230, :_reduce_none, + 1, 230, :_reduce_none, + 1, 230, :_reduce_none, + 3, 228, :_reduce_263, + 3, 228, :_reduce_264, + 1, 232, :_reduce_none, + 1, 233, :_reduce_none, + 2, 233, :_reduce_none, + 4, 233, :_reduce_268, + 2, 233, :_reduce_269, + 1, 226, :_reduce_none, + 3, 226, :_reduce_271, + 3, 238, :_reduce_272, + 5, 238, :_reduce_273, + 3, 238, :_reduce_274, + 0, 240, :_reduce_275, + 1, 240, :_reduce_none, + 0, 178, :_reduce_277, + 1, 178, :_reduce_none, + 2, 178, :_reduce_none, + 4, 178, :_reduce_280, + 2, 178, :_reduce_281, + 1, 210, :_reduce_282, + 2, 210, :_reduce_283, + 2, 210, :_reduce_284, + 4, 210, :_reduce_285, + 1, 210, :_reduce_286, + 0, 243, :_reduce_287, + 2, 203, :_reduce_288, + 2, 242, :_reduce_289, + 1, 242, :_reduce_290, + 2, 241, :_reduce_291, + 0, 241, :_reduce_292, + 1, 235, :_reduce_293, + 2, 235, :_reduce_294, + 1, 235, :_reduce_295, + 3, 235, :_reduce_296, + 4, 235, :_reduce_297, + 3, 235, :_reduce_298, + 1, 172, :_reduce_299, + 1, 172, :_reduce_none, + 3, 171, :_reduce_301, + 4, 171, :_reduce_302, + 2, 171, :_reduce_303, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_none, + 1, 229, :_reduce_314, + 0, 267, :_reduce_315, + 4, 229, :_reduce_316, + 0, 268, :_reduce_317, + 4, 229, :_reduce_318, + 0, 269, :_reduce_319, + 4, 229, :_reduce_320, + 3, 229, :_reduce_321, + 3, 229, :_reduce_322, + 2, 229, :_reduce_323, + 3, 229, :_reduce_324, + 3, 229, :_reduce_325, + 1, 229, :_reduce_326, + 4, 229, :_reduce_327, + 3, 229, :_reduce_328, + 1, 229, :_reduce_329, + 0, 270, :_reduce_330, + 6, 229, :_reduce_331, + 4, 229, :_reduce_332, + 3, 229, :_reduce_333, + 2, 229, :_reduce_334, + 1, 229, :_reduce_none, + 2, 229, :_reduce_336, + 1, 229, :_reduce_none, + 6, 229, :_reduce_338, + 6, 229, :_reduce_339, + 4, 229, :_reduce_340, + 4, 229, :_reduce_341, + 5, 229, :_reduce_342, + 4, 229, :_reduce_343, + 5, 229, :_reduce_344, + 6, 229, :_reduce_345, + 0, 271, :_reduce_346, + 6, 229, :_reduce_347, + 0, 272, :_reduce_348, + 7, 229, :_reduce_349, + 0, 273, :_reduce_350, + 5, 229, :_reduce_351, + 4, 229, :_reduce_352, + 4, 229, :_reduce_353, + 1, 229, :_reduce_354, + 1, 229, :_reduce_355, + 1, 229, :_reduce_356, + 1, 229, :_reduce_357, + 1, 177, :_reduce_none, + 1, 262, :_reduce_359, + 1, 265, :_reduce_360, + 1, 196, :_reduce_361, + 1, 209, :_reduce_362, + 1, 257, :_reduce_none, + 1, 257, :_reduce_none, + 2, 257, :_reduce_365, + 1, 192, :_reduce_none, + 1, 192, :_reduce_none, + 1, 258, :_reduce_none, + 5, 258, :_reduce_369, + 1, 160, :_reduce_none, + 2, 160, :_reduce_371, + 1, 261, :_reduce_none, + 1, 261, :_reduce_none, + 1, 274, :_reduce_374, + 3, 274, :_reduce_375, + 1, 277, :_reduce_376, + 3, 277, :_reduce_377, + 1, 276, :_reduce_none, + 3, 276, :_reduce_379, + 5, 276, :_reduce_380, + 1, 276, :_reduce_381, + 3, 276, :_reduce_382, + 2, 278, :_reduce_383, + 1, 278, :_reduce_384, + 1, 279, :_reduce_none, + 1, 279, :_reduce_none, + 0, 284, :_reduce_387, + 2, 282, :_reduce_388, + 4, 283, :_reduce_389, + 2, 283, :_reduce_390, + 2, 283, :_reduce_391, + 1, 283, :_reduce_392, + 2, 288, :_reduce_393, + 0, 288, :_reduce_394, + 1, 289, :_reduce_none, + 6, 290, :_reduce_396, + 8, 290, :_reduce_397, + 4, 290, :_reduce_398, + 6, 290, :_reduce_399, + 4, 290, :_reduce_400, + 2, 290, :_reduce_none, + 6, 290, :_reduce_402, + 2, 290, :_reduce_403, + 4, 290, :_reduce_404, + 6, 290, :_reduce_405, + 2, 290, :_reduce_406, + 4, 290, :_reduce_407, + 2, 290, :_reduce_408, + 4, 290, :_reduce_409, + 1, 290, :_reduce_none, + 0, 294, :_reduce_411, + 1, 294, :_reduce_412, + 3, 295, :_reduce_413, + 4, 295, :_reduce_414, + 1, 296, :_reduce_415, + 4, 296, :_reduce_416, + 1, 297, :_reduce_417, + 3, 297, :_reduce_418, + 1, 298, :_reduce_419, + 1, 298, :_reduce_none, + 0, 302, :_reduce_421, + 0, 303, :_reduce_422, + 5, 256, :_reduce_423, + 4, 300, :_reduce_424, + 1, 300, :_reduce_425, + 0, 306, :_reduce_426, + 4, 301, :_reduce_427, + 0, 307, :_reduce_428, + 4, 301, :_reduce_429, + 0, 309, :_reduce_430, + 4, 305, :_reduce_431, + 2, 201, :_reduce_432, + 4, 201, :_reduce_433, + 5, 201, :_reduce_434, + 5, 201, :_reduce_435, + 2, 255, :_reduce_436, + 4, 255, :_reduce_437, + 4, 255, :_reduce_438, + 3, 255, :_reduce_439, + 3, 255, :_reduce_440, + 3, 255, :_reduce_441, + 2, 255, :_reduce_442, + 1, 255, :_reduce_443, + 4, 255, :_reduce_444, + 0, 311, :_reduce_445, + 4, 254, :_reduce_446, + 0, 312, :_reduce_447, + 4, 254, :_reduce_448, + 0, 313, :_reduce_449, + 3, 205, :_reduce_450, + 0, 314, :_reduce_451, + 0, 315, :_reduce_452, + 4, 308, :_reduce_453, + 5, 259, :_reduce_454, + 1, 316, :_reduce_455, + 1, 316, :_reduce_none, + 0, 319, :_reduce_457, + 0, 320, :_reduce_458, + 7, 260, :_reduce_459, + 1, 318, :_reduce_460, + 1, 318, :_reduce_none, + 1, 317, :_reduce_462, + 3, 317, :_reduce_463, + 3, 317, :_reduce_464, + 1, 188, :_reduce_none, + 2, 188, :_reduce_466, + 3, 188, :_reduce_467, + 1, 188, :_reduce_468, + 1, 188, :_reduce_469, + 1, 188, :_reduce_470, + 1, 321, :_reduce_none, + 3, 326, :_reduce_472, + 1, 326, :_reduce_none, + 3, 328, :_reduce_474, + 1, 328, :_reduce_none, + 1, 330, :_reduce_476, + 1, 331, :_reduce_477, + 1, 329, :_reduce_none, + 1, 329, :_reduce_none, + 4, 329, :_reduce_480, + 4, 329, :_reduce_481, + 4, 329, :_reduce_482, + 3, 329, :_reduce_483, + 4, 329, :_reduce_484, + 4, 329, :_reduce_485, + 4, 329, :_reduce_486, + 3, 329, :_reduce_487, + 3, 329, :_reduce_488, + 3, 329, :_reduce_489, + 2, 329, :_reduce_490, + 0, 335, :_reduce_491, + 4, 329, :_reduce_492, + 2, 329, :_reduce_493, + 0, 336, :_reduce_494, + 4, 329, :_reduce_495, + 1, 322, :_reduce_496, + 1, 322, :_reduce_497, + 2, 322, :_reduce_498, + 2, 322, :_reduce_499, + 4, 322, :_reduce_500, + 1, 322, :_reduce_none, + 2, 337, :_reduce_502, + 3, 337, :_reduce_503, + 1, 324, :_reduce_504, + 3, 324, :_reduce_505, + 5, 323, :_reduce_506, + 2, 339, :_reduce_507, + 1, 339, :_reduce_508, + 1, 340, :_reduce_509, + 3, 340, :_reduce_510, + 1, 338, :_reduce_none, + 3, 325, :_reduce_512, + 1, 325, :_reduce_513, + 2, 325, :_reduce_514, + 1, 325, :_reduce_515, + 1, 341, :_reduce_516, + 3, 341, :_reduce_517, + 2, 343, :_reduce_518, + 1, 343, :_reduce_519, + 1, 344, :_reduce_520, + 3, 344, :_reduce_521, + 2, 346, :_reduce_522, + 1, 346, :_reduce_523, + 2, 348, :_reduce_524, + 1, 342, :_reduce_none, + 1, 342, :_reduce_526, + 1, 332, :_reduce_none, + 3, 332, :_reduce_528, + 3, 332, :_reduce_529, + 2, 332, :_reduce_530, + 2, 332, :_reduce_531, + 1, 332, :_reduce_none, + 1, 332, :_reduce_none, + 1, 332, :_reduce_none, + 2, 332, :_reduce_535, + 2, 332, :_reduce_536, + 1, 349, :_reduce_none, + 1, 349, :_reduce_none, + 1, 349, :_reduce_none, + 1, 349, :_reduce_none, + 1, 349, :_reduce_none, + 1, 349, :_reduce_none, + 1, 349, :_reduce_none, + 1, 349, :_reduce_none, + 1, 349, :_reduce_545, + 1, 349, :_reduce_none, + 1, 327, :_reduce_547, + 2, 350, :_reduce_548, + 2, 350, :_reduce_549, + 4, 351, :_reduce_550, + 2, 333, :_reduce_551, + 3, 333, :_reduce_552, + 1, 333, :_reduce_553, + 6, 159, :_reduce_554, + 0, 159, :_reduce_555, + 1, 353, :_reduce_556, + 1, 353, :_reduce_none, + 1, 353, :_reduce_none, + 2, 354, :_reduce_559, + 1, 354, :_reduce_none, + 2, 161, :_reduce_561, + 1, 161, :_reduce_none, + 1, 244, :_reduce_none, + 1, 244, :_reduce_none, + 1, 245, :_reduce_565, + 1, 356, :_reduce_566, + 2, 356, :_reduce_567, + 3, 357, :_reduce_568, + 1, 357, :_reduce_569, + 1, 357, :_reduce_570, + 3, 246, :_reduce_571, + 4, 247, :_reduce_572, + 3, 248, :_reduce_573, + 0, 360, :_reduce_574, + 3, 360, :_reduce_575, + 1, 361, :_reduce_576, + 2, 361, :_reduce_577, + 3, 250, :_reduce_578, + 0, 363, :_reduce_579, + 3, 363, :_reduce_580, + 3, 249, :_reduce_581, + 3, 251, :_reduce_582, + 0, 364, :_reduce_583, + 3, 364, :_reduce_584, + 0, 365, :_reduce_585, + 3, 365, :_reduce_586, + 0, 345, :_reduce_587, + 2, 345, :_reduce_588, + 0, 358, :_reduce_589, + 2, 358, :_reduce_590, + 0, 359, :_reduce_591, + 2, 359, :_reduce_592, + 1, 362, :_reduce_593, + 2, 362, :_reduce_594, + 0, 367, :_reduce_595, + 4, 362, :_reduce_596, + 1, 366, :_reduce_597, + 1, 366, :_reduce_598, + 1, 366, :_reduce_599, + 1, 366, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 368, :_reduce_603, + 3, 369, :_reduce_604, + 1, 355, :_reduce_605, + 2, 355, :_reduce_606, + 1, 227, :_reduce_607, + 1, 227, :_reduce_608, + 1, 227, :_reduce_609, + 1, 227, :_reduce_610, + 1, 352, :_reduce_611, + 1, 352, :_reduce_612, + 1, 352, :_reduce_613, + 1, 218, :_reduce_614, + 1, 218, :_reduce_615, + 1, 218, :_reduce_none, + 1, 219, :_reduce_617, + 1, 219, :_reduce_618, + 1, 219, :_reduce_619, + 1, 219, :_reduce_620, + 1, 219, :_reduce_621, + 1, 219, :_reduce_622, + 1, 219, :_reduce_623, + 1, 252, :_reduce_624, + 1, 252, :_reduce_625, + 1, 176, :_reduce_626, + 1, 176, :_reduce_627, + 1, 186, :_reduce_628, + 1, 186, :_reduce_629, + 0, 370, :_reduce_630, + 4, 263, :_reduce_631, + 0, 263, :_reduce_632, + 1, 182, :_reduce_none, + 1, 182, :_reduce_634, + 3, 371, :_reduce_635, + 1, 266, :_reduce_none, + 0, 373, :_reduce_637, + 3, 266, :_reduce_638, + 4, 372, :_reduce_639, + 2, 372, :_reduce_640, + 2, 372, :_reduce_641, + 1, 372, :_reduce_642, + 1, 372, :_reduce_643, + 2, 375, :_reduce_644, + 0, 375, :_reduce_645, + 6, 304, :_reduce_646, + 8, 304, :_reduce_647, + 4, 304, :_reduce_648, + 6, 304, :_reduce_649, + 4, 304, :_reduce_650, + 6, 304, :_reduce_651, + 2, 304, :_reduce_652, + 4, 304, :_reduce_653, + 6, 304, :_reduce_654, + 2, 304, :_reduce_655, + 4, 304, :_reduce_656, + 2, 304, :_reduce_657, + 4, 304, :_reduce_658, + 1, 304, :_reduce_659, + 0, 304, :_reduce_660, + 1, 239, :_reduce_661, + 1, 299, :_reduce_662, + 1, 299, :_reduce_663, + 1, 299, :_reduce_664, + 1, 299, :_reduce_665, + 1, 275, :_reduce_none, + 1, 275, :_reduce_667, + 1, 377, :_reduce_668, + 1, 378, :_reduce_669, + 3, 378, :_reduce_670, + 1, 291, :_reduce_671, + 3, 291, :_reduce_672, + 1, 379, :_reduce_673, + 2, 380, :_reduce_674, + 1, 380, :_reduce_675, + 2, 381, :_reduce_676, + 1, 381, :_reduce_677, + 1, 285, :_reduce_678, + 3, 285, :_reduce_679, + 1, 374, :_reduce_680, + 3, 374, :_reduce_681, + 1, 347, :_reduce_none, + 1, 347, :_reduce_none, + 1, 281, :_reduce_684, + 2, 280, :_reduce_685, + 1, 280, :_reduce_686, + 3, 382, :_reduce_687, + 3, 383, :_reduce_688, + 1, 292, :_reduce_689, + 3, 292, :_reduce_690, + 1, 376, :_reduce_691, + 3, 376, :_reduce_692, + 1, 384, :_reduce_none, + 1, 384, :_reduce_none, + 2, 293, :_reduce_695, + 1, 293, :_reduce_696, + 1, 385, :_reduce_none, + 1, 385, :_reduce_none, + 2, 287, :_reduce_699, + 1, 287, :_reduce_700, + 2, 286, :_reduce_701, + 0, 286, :_reduce_702, + 1, 197, :_reduce_none, + 3, 197, :_reduce_704, + 0, 253, :_reduce_705, + 2, 253, :_reduce_none, + 1, 237, :_reduce_707, + 3, 237, :_reduce_708, + 3, 386, :_reduce_709, + 2, 386, :_reduce_710, + 1, 386, :_reduce_711, + 4, 386, :_reduce_712, + 2, 386, :_reduce_713, + 1, 386, :_reduce_714, + 1, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 208, :_reduce_none, + 1, 202, :_reduce_none, + 1, 202, :_reduce_none, + 1, 310, :_reduce_none, + 1, 310, :_reduce_none, + 1, 310, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 180, :_reduce_725, + 1, 180, :_reduce_726, + 0, 152, :_reduce_none, + 1, 152, :_reduce_none, + 0, 187, :_reduce_none, + 1, 187, :_reduce_none, + 2, 213, :_reduce_731, + 2, 179, :_reduce_732, + 2, 334, :_reduce_733, + 1, 236, :_reduce_none, + 1, 236, :_reduce_none, + 1, 264, :_reduce_736, + 1, 264, :_reduce_none, + 1, 154, :_reduce_none, + 2, 154, :_reduce_none, + 0, 234, :_reduce_740 ] + +racc_reduce_n = 741 + +racc_shift_n = 1234 + +racc_token_table = { + false => 0, + :error => 1, + :kCLASS => 2, + :kMODULE => 3, + :kDEF => 4, + :kUNDEF => 5, + :kBEGIN => 6, + :kRESCUE => 7, + :kENSURE => 8, + :kEND => 9, + :kIF => 10, + :kUNLESS => 11, + :kTHEN => 12, + :kELSIF => 13, + :kELSE => 14, + :kCASE => 15, + :kWHEN => 16, + :kWHILE => 17, + :kUNTIL => 18, + :kFOR => 19, + :kBREAK => 20, + :kNEXT => 21, + :kREDO => 22, + :kRETRY => 23, + :kIN => 24, + :kDO => 25, + :kDO_COND => 26, + :kDO_BLOCK => 27, + :kDO_LAMBDA => 28, + :kRETURN => 29, + :kYIELD => 30, + :kSUPER => 31, + :kSELF => 32, + :kNIL => 33, + :kTRUE => 34, + :kFALSE => 35, + :kAND => 36, + :kOR => 37, + :kNOT => 38, + :kIF_MOD => 39, + :kUNLESS_MOD => 40, + :kWHILE_MOD => 41, + :kUNTIL_MOD => 42, + :kRESCUE_MOD => 43, + :kALIAS => 44, + :kDEFINED => 45, + :klBEGIN => 46, + :klEND => 47, + :k__LINE__ => 48, + :k__FILE__ => 49, + :k__ENCODING__ => 50, + :tIDENTIFIER => 51, + :tFID => 52, + :tGVAR => 53, + :tIVAR => 54, + :tCONSTANT => 55, + :tLABEL => 56, + :tCVAR => 57, + :tNTH_REF => 58, + :tBACK_REF => 59, + :tSTRING_CONTENT => 60, + :tINTEGER => 61, + :tFLOAT => 62, + :tUPLUS => 63, + :tUMINUS => 64, + :tUNARY_NUM => 65, + :tPOW => 66, + :tCMP => 67, + :tEQ => 68, + :tEQQ => 69, + :tNEQ => 70, + :tGEQ => 71, + :tLEQ => 72, + :tANDOP => 73, + :tOROP => 74, + :tMATCH => 75, + :tNMATCH => 76, + :tDOT => 77, + :tDOT2 => 78, + :tDOT3 => 79, + :tAREF => 80, + :tASET => 81, + :tLSHFT => 82, + :tRSHFT => 83, + :tCOLON2 => 84, + :tCOLON3 => 85, + :tOP_ASGN => 86, + :tASSOC => 87, + :tLPAREN => 88, + :tLPAREN2 => 89, + :tRPAREN => 90, + :tLPAREN_ARG => 91, + :tLBRACK => 92, + :tLBRACK2 => 93, + :tRBRACK => 94, + :tLBRACE => 95, + :tLBRACE_ARG => 96, + :tSTAR => 97, + :tSTAR2 => 98, + :tAMPER => 99, + :tAMPER2 => 100, + :tTILDE => 101, + :tPERCENT => 102, + :tDIVIDE => 103, + :tDSTAR => 104, + :tPLUS => 105, + :tMINUS => 106, + :tLT => 107, + :tGT => 108, + :tPIPE => 109, + :tBANG => 110, + :tCARET => 111, + :tLCURLY => 112, + :tRCURLY => 113, + :tBACK_REF2 => 114, + :tSYMBEG => 115, + :tSTRING_BEG => 116, + :tXSTRING_BEG => 117, + :tREGEXP_BEG => 118, + :tREGEXP_OPT => 119, + :tWORDS_BEG => 120, + :tQWORDS_BEG => 121, + :tSYMBOLS_BEG => 122, + :tQSYMBOLS_BEG => 123, + :tSTRING_DBEG => 124, + :tSTRING_DVAR => 125, + :tSTRING_END => 126, + :tSTRING_DEND => 127, + :tSTRING => 128, + :tSYMBOL => 129, + :tNL => 130, + :tEH => 131, + :tCOLON => 132, + :tCOMMA => 133, + :tSPACE => 134, + :tSEMI => 135, + :tLAMBDA => 136, + :tLAMBEG => 137, + :tCHARACTER => 138, + :tRATIONAL => 139, + :tIMAGINARY => 140, + :tLABEL_END => 141, + :tANDDOT => 142, + :tBDOT2 => 143, + :tBDOT3 => 144, + :tEQL => 145, + :tLOWEST => 146 } + +racc_nt_base = 147 + +racc_use_result_var = true + +Racc_arg = [ + racc_action_table, + racc_action_check, + racc_action_default, + racc_action_pointer, + racc_goto_table, + racc_goto_check, + racc_goto_default, + racc_goto_pointer, + racc_nt_base, + racc_reduce_table, + racc_token_table, + racc_shift_n, + racc_reduce_n, + racc_use_result_var ] +Ractor.make_shareable(Racc_arg) if defined?(Ractor) + +Racc_token_to_s_table = [ + "$end", + "error", + "kCLASS", + "kMODULE", + "kDEF", + "kUNDEF", + "kBEGIN", + "kRESCUE", + "kENSURE", + "kEND", + "kIF", + "kUNLESS", + "kTHEN", + "kELSIF", + "kELSE", + "kCASE", + "kWHEN", + "kWHILE", + "kUNTIL", + "kFOR", + "kBREAK", + "kNEXT", + "kREDO", + "kRETRY", + "kIN", + "kDO", + "kDO_COND", + "kDO_BLOCK", + "kDO_LAMBDA", + "kRETURN", + "kYIELD", + "kSUPER", + "kSELF", + "kNIL", + "kTRUE", + "kFALSE", + "kAND", + "kOR", + "kNOT", + "kIF_MOD", + "kUNLESS_MOD", + "kWHILE_MOD", + "kUNTIL_MOD", + "kRESCUE_MOD", + "kALIAS", + "kDEFINED", + "klBEGIN", + "klEND", + "k__LINE__", + "k__FILE__", + "k__ENCODING__", + "tIDENTIFIER", + "tFID", + "tGVAR", + "tIVAR", + "tCONSTANT", + "tLABEL", + "tCVAR", + "tNTH_REF", + "tBACK_REF", + "tSTRING_CONTENT", + "tINTEGER", + "tFLOAT", + "tUPLUS", + "tUMINUS", + "tUNARY_NUM", + "tPOW", + "tCMP", + "tEQ", + "tEQQ", + "tNEQ", + "tGEQ", + "tLEQ", + "tANDOP", + "tOROP", + "tMATCH", + "tNMATCH", + "tDOT", + "tDOT2", + "tDOT3", + "tAREF", + "tASET", + "tLSHFT", + "tRSHFT", + "tCOLON2", + "tCOLON3", + "tOP_ASGN", + "tASSOC", + "tLPAREN", + "tLPAREN2", + "tRPAREN", + "tLPAREN_ARG", + "tLBRACK", + "tLBRACK2", + "tRBRACK", + "tLBRACE", + "tLBRACE_ARG", + "tSTAR", + "tSTAR2", + "tAMPER", + "tAMPER2", + "tTILDE", + "tPERCENT", + "tDIVIDE", + "tDSTAR", + "tPLUS", + "tMINUS", + "tLT", + "tGT", + "tPIPE", + "tBANG", + "tCARET", + "tLCURLY", + "tRCURLY", + "tBACK_REF2", + "tSYMBEG", + "tSTRING_BEG", + "tXSTRING_BEG", + "tREGEXP_BEG", + "tREGEXP_OPT", + "tWORDS_BEG", + "tQWORDS_BEG", + "tSYMBOLS_BEG", + "tQSYMBOLS_BEG", + "tSTRING_DBEG", + "tSTRING_DVAR", + "tSTRING_END", + "tSTRING_DEND", + "tSTRING", + "tSYMBOL", + "tNL", + "tEH", + "tCOLON", + "tCOMMA", + "tSPACE", + "tSEMI", + "tLAMBDA", + "tLAMBEG", + "tCHARACTER", + "tRATIONAL", + "tIMAGINARY", + "tLABEL_END", + "tANDDOT", + "tBDOT2", + "tBDOT3", + "tEQL", + "tLOWEST", + "$start", + "program", + "top_compstmt", + "@1", + "top_stmts", + "opt_terms", + "top_stmt", + "terms", + "stmt", + "begin_block", + "bodystmt", + "compstmt", + "opt_rescue", + "opt_else", + "opt_ensure", + "stmts", + "stmt_or_begin", + "fitem", + "undef_list", + "expr_value", + "command_asgn", + "mlhs", + "command_call", + "lhs", + "mrhs", + "mrhs_arg", + "expr", + "@2", + "command_rhs", + "var_lhs", + "primary_value", + "opt_call_args", + "rbracket", + "call_op", + "defn_head", + "f_opt_paren_args", + "command", + "arg", + "defs_head", + "backref", + "opt_nl", + "p_top_expr_body", + "@3", + "@4", + "expr_value_do", + "do", + "def_name", + "@5", + "fname", + "k_def", + "singleton", + "dot_or_colon", + "@6", + "block_command", + "block_call", + "operation2", + "command_args", + "cmd_brace_block", + "brace_body", + "fcall", + "@7", + "operation", + "k_return", + "call_args", + "mlhs_basic", + "mlhs_inner", + "rparen", + "mlhs_head", + "mlhs_item", + "mlhs_node", + "mlhs_post", + "user_variable", + "keyword_variable", + "cname", + "cpath", + "op", + "reswords", + "symbol", + "@8", + "arg_rhs", + "simple_numeric", + "rel_expr", + "primary", + "relop", + "@9", + "arg_value", + "aref_args", + "none", + "args", + "trailer", + "assocs", + "paren_args", + "args_forward", + "opt_paren_args", + "opt_block_arg", + "block_arg", + "@10", + "literal", + "strings", + "xstring", + "regexp", + "words", + "qwords", + "symbols", + "qsymbols", + "var_ref", + "assoc_list", + "brace_block", + "method_call", + "lambda", + "then", + "if_tail", + "case_body", + "p_case_body", + "for_var", + "k_class", + "superclass", + "term", + "k_module", + "f_arglist", + "@11", + "@12", + "@13", + "@14", + "@15", + "@16", + "@17", + "f_marg", + "f_norm_arg", + "f_margs", + "f_marg_list", + "f_rest_marg", + "f_any_kwrest", + "f_kwrest", + "f_no_kwarg", + "f_eq", + "block_args_tail", + "@18", + "f_block_kwarg", + "opt_f_block_arg", + "f_block_arg", + "opt_block_args_tail", + "excessed_comma", + "block_param", + "f_arg", + "f_block_optarg", + "f_rest_arg", + "opt_block_param", + "block_param_def", + "opt_bv_decl", + "bv_decls", + "bvar", + "f_bad_arg", + "f_larglist", + "lambda_body", + "@19", + "@20", + "f_args", + "do_block", + "@21", + "@22", + "do_body", + "@23", + "operation3", + "@24", + "@25", + "@26", + "@27", + "@28", + "cases", + "p_top_expr", + "p_cases", + "@29", + "@30", + "p_expr", + "p_args", + "p_find", + "p_args_tail", + "p_kwargs", + "p_as", + "p_variable", + "p_alt", + "p_expr_basic", + "p_lparen", + "p_lbracket", + "p_value", + "p_const", + "rbrace", + "@31", + "@32", + "p_args_head", + "p_arg", + "p_rest", + "p_args_post", + "p_kwarg", + "p_any_kwrest", + "p_kw", + "p_kw_label", + "string_contents", + "p_kwrest", + "kwrest_mark", + "p_kwnorest", + "p_primitive", + "p_var_ref", + "p_expr_ref", + "nonlocal_var", + "exc_list", + "exc_var", + "numeric", + "string", + "string1", + "xstring_contents", + "regexp_contents", + "word_list", + "word", + "string_content", + "symbol_list", + "qword_list", + "qsym_list", + "string_dvar", + "@33", + "ssym", + "dsym", + "@34", + "f_paren_args", + "args_tail", + "@35", + "f_kwarg", + "opt_args_tail", + "f_optarg", + "f_arg_asgn", + "f_arg_item", + "f_label", + "f_kw", + "f_block_kw", + "f_opt", + "f_block_opt", + "restarg_mark", + "blkarg_mark", + "assoc" ] +Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) + +Racc_debug_parser = false + +##### State transition tables end ##### + +# reduce 0 omitted + +def _reduce_1(val, _values, result) + @current_arg_stack.push(nil) + @max_numparam_stack.push(static: true) + + result +end + +def _reduce_2(val, _values, result) + result = val[1] + + @current_arg_stack.pop + @max_numparam_stack.pop + + result +end + +def _reduce_3(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_4(val, _values, result) + result = [] + + result +end + +def _reduce_5(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_6(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_7(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 8 omitted + +def _reduce_9(val, _values, result) + result = @builder.preexe(val[0], *val[1]) + + result +end + +def _reduce_10(val, _values, result) + result = val + + result +end + +def _reduce_11(val, _values, result) + rescue_bodies = val[1] + else_t, else_ = val[2] + ensure_t, ensure_ = val[3] + + if rescue_bodies.empty? && !else_t.nil? + diagnostic :error, :useless_else, nil, else_t + end + + result = @builder.begin_body(val[0], + rescue_bodies, + else_t, else_, + ensure_t, ensure_) + + result +end + +def _reduce_12(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_13(val, _values, result) + result = [] + + result +end + +def _reduce_14(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_15(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_16(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 17 omitted + +def _reduce_18(val, _values, result) + diagnostic :error, :begin_in_method, nil, val[0] + + result +end + +def _reduce_19(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_20(val, _values, result) + result = @builder.alias(val[0], val[1], val[3]) + + result +end + +def _reduce_21(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.gvar(val[2])) + + result +end + +def _reduce_22(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.back_ref(val[2])) + + result +end + +def _reduce_23(val, _values, result) + diagnostic :error, :nth_ref_alias, nil, val[2] + + result +end + +def _reduce_24(val, _values, result) + result = @builder.undef_method(val[0], val[1]) + + result +end + +def _reduce_25(val, _values, result) + result = @builder.condition_mod(val[0], nil, + val[1], val[2]) + + result +end + +def _reduce_26(val, _values, result) + result = @builder.condition_mod(nil, val[0], + val[1], val[2]) + + result +end + +def _reduce_27(val, _values, result) + result = @builder.loop_mod(:while, val[0], val[1], val[2]) + + result +end + +def _reduce_28(val, _values, result) + result = @builder.loop_mod(:until, val[0], val[1], val[2]) + + result +end + +def _reduce_29(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_30(val, _values, result) + result = @builder.postexe(val[0], val[1], val[2], val[3]) + + result +end + +# reduce 31 omitted + +def _reduce_32(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_33(val, _values, result) + result = @builder.assign(val[0], val[1], + @builder.array(nil, val[2], nil)) + + result +end + +def _reduce_34(val, _values, result) + rescue_body = @builder.rescue_body(val[3], + nil, nil, nil, + nil, val[4]) + begin_body = @builder.begin_body(val[2], [ rescue_body ]) + + result = @builder.multi_assign(val[0], val[1], begin_body) + + result +end + +def _reduce_35(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +# reduce 36 omitted + +def _reduce_37(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_38(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_39(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_40(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_41(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_42(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_43(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_44(val, _values, result) + def_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + result = @builder.def_endless_method(def_t, name_t, + val[1], val[2], val[3]) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_45(val, _values, result) + def_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + rescue_body = @builder.rescue_body(val[4], + nil, nil, nil, + nil, val[5]) + + method_body = @builder.begin_body(val[3], [ rescue_body ]) + + result = @builder.def_endless_method(def_t, name_t, + val[1], val[2], method_body) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_46(val, _values, result) + def_t, recv, dot_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + result = @builder.def_endless_singleton(def_t, recv, dot_t, name_t, + val[1], val[2], val[3]) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_47(val, _values, result) + def_t, recv, dot_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + rescue_body = @builder.rescue_body(val[4], + nil, nil, nil, + nil, val[5]) + + method_body = @builder.begin_body(val[3], [ rescue_body ]) + + result = @builder.def_endless_singleton(def_t, recv, dot_t, name_t, + val[1], val[2], method_body) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_48(val, _values, result) + @builder.op_assign(val[0], val[1], val[2]) + + result +end + +# reduce 49 omitted + +def _reduce_50(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +# reduce 51 omitted + +# reduce 52 omitted + +def _reduce_53(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_54(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_55(val, _values, result) + result = @builder.not_op(val[0], nil, val[2], nil) + + result +end + +def _reduce_56(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +def _reduce_57(val, _values, result) + @lexer.state = :expr_beg + @lexer.command_start = false + @pattern_variables.push + @pattern_hash_keys.push + + result = @context.in_kwarg + @context.in_kwarg = true + + result +end + +def _reduce_58(val, _values, result) + @pattern_variables.pop + @pattern_hash_keys.pop + @context.in_kwarg = val[2] + result = @builder.match_pattern(val[0], val[1], val[3]) + + result +end + +def _reduce_59(val, _values, result) + @lexer.state = :expr_beg + @lexer.command_start = false + @pattern_variables.push + @pattern_hash_keys.push + + result = @context.in_kwarg + @context.in_kwarg = true + + result +end + +def _reduce_60(val, _values, result) + @pattern_variables.pop + @pattern_hash_keys.pop + @context.in_kwarg = val[2] + result = @builder.match_pattern_p(val[0], val[1], val[3]) + + result +end + +# reduce 61 omitted + +# reduce 62 omitted + +def _reduce_63(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_64(val, _values, result) + @lexer.cond.pop + result = [ val[1], val[2] ] + + result +end + +def _reduce_65(val, _values, result) + local_push + @current_arg_stack.push(nil) + + result = [ val[0], @context.dup ] + @context.in_def = true + + result +end + +def _reduce_66(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +def _reduce_67(val, _values, result) + @lexer.state = :expr_fname + @context.in_argdef = true + + result +end + +def _reduce_68(val, _values, result) + result = [ val[0], val[1], val[2], val[4] ] + + result +end + +# reduce 69 omitted + +# reduce 70 omitted + +# reduce 71 omitted + +def _reduce_72(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_73(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_74(val, _values, result) + @context.in_block = val[1].in_block + result = [ val[0], *val[2], val[3] ] + + result +end + +# reduce 75 omitted + +def _reduce_76(val, _values, result) + result = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + result +end + +def _reduce_77(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + begin_t, args, body, end_t = val[2] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_78(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_79(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_80(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_81(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_82(val, _values, result) + result = @builder.keyword_cmd(:super, val[0], + nil, val[1], nil) + + result +end + +def _reduce_83(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], + nil, val[1], nil) + + result +end + +def _reduce_84(val, _values, result) + result = @builder.keyword_cmd(:return, val[0], + nil, val[1], nil) + + result +end + +def _reduce_85(val, _values, result) + result = @builder.keyword_cmd(:break, val[0], + nil, val[1], nil) + + result +end + +def _reduce_86(val, _values, result) + result = @builder.keyword_cmd(:next, val[0], + nil, val[1], nil) + + result +end + +def _reduce_87(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_88(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_89(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_90(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +# reduce 91 omitted + +def _reduce_92(val, _values, result) + result = val[0]. + push(val[1]) + + result +end + +def _reduce_93(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])) + + result +end + +def _reduce_94(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])). + concat(val[4]) + + result +end + +def _reduce_95(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])) + + result +end + +def _reduce_96(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])). + concat(val[3]) + + result +end + +def _reduce_97(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_98(val, _values, result) + result = [ @builder.splat(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_99(val, _values, result) + result = [ @builder.splat(val[0]) ] + + result +end + +def _reduce_100(val, _values, result) + result = [ @builder.splat(val[0]), + *val[2] ] + + result +end + +# reduce 101 omitted + +def _reduce_102(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_103(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_104(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_105(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_106(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_107(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_108(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_109(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_110(val, _values, result) + if (val[1][0] == :anddot) + diagnostic :error, :csend_in_lhs_of_masgn, nil, val[1] + end + + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_111(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_112(val, _values, result) + if (val[1][0] == :anddot) + diagnostic :error, :csend_in_lhs_of_masgn, nil, val[1] + end + + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_113(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_114(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_115(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_116(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_117(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_118(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_119(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_120(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_121(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_122(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_123(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_124(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_125(val, _values, result) + diagnostic :error, :module_name_const, nil, val[0] + + result +end + +# reduce 126 omitted + +def _reduce_127(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_128(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_129(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +# reduce 130 omitted + +# reduce 131 omitted + +# reduce 132 omitted + +# reduce 133 omitted + +# reduce 134 omitted + +def _reduce_135(val, _values, result) + result = @builder.symbol_internal(val[0]) + + result +end + +# reduce 136 omitted + +def _reduce_137(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_138(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_139(val, _values, result) + result = val[0] << val[3] + + result +end + +# reduce 140 omitted + +# reduce 141 omitted + +# reduce 142 omitted + +# reduce 143 omitted + +# reduce 144 omitted + +# reduce 145 omitted + +# reduce 146 omitted + +# reduce 147 omitted + +# reduce 148 omitted + +# reduce 149 omitted + +# reduce 150 omitted + +# reduce 151 omitted + +# reduce 152 omitted + +# reduce 153 omitted + +# reduce 154 omitted + +# reduce 155 omitted + +# reduce 156 omitted + +# reduce 157 omitted + +# reduce 158 omitted + +# reduce 159 omitted + +# reduce 160 omitted + +# reduce 161 omitted + +# reduce 162 omitted + +# reduce 163 omitted + +# reduce 164 omitted + +# reduce 165 omitted + +# reduce 166 omitted + +# reduce 167 omitted + +# reduce 168 omitted + +# reduce 169 omitted + +# reduce 170 omitted + +# reduce 171 omitted + +# reduce 172 omitted + +# reduce 173 omitted + +# reduce 174 omitted + +# reduce 175 omitted + +# reduce 176 omitted + +# reduce 177 omitted + +# reduce 178 omitted + +# reduce 179 omitted + +# reduce 180 omitted + +# reduce 181 omitted + +# reduce 182 omitted + +# reduce 183 omitted + +# reduce 184 omitted + +# reduce 185 omitted + +# reduce 186 omitted + +# reduce 187 omitted + +# reduce 188 omitted + +# reduce 189 omitted + +# reduce 190 omitted + +# reduce 191 omitted + +# reduce 192 omitted + +# reduce 193 omitted + +# reduce 194 omitted + +# reduce 195 omitted + +# reduce 196 omitted + +# reduce 197 omitted + +# reduce 198 omitted + +# reduce 199 omitted + +# reduce 200 omitted + +# reduce 201 omitted + +# reduce 202 omitted + +# reduce 203 omitted + +# reduce 204 omitted + +# reduce 205 omitted + +# reduce 206 omitted + +# reduce 207 omitted + +# reduce 208 omitted + +# reduce 209 omitted + +# reduce 210 omitted + +def _reduce_211(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_212(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_213(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_214(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_215(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_216(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_217(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_218(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_global(val[0], val[1])) + result = @builder.op_assign(const, val[2], val[3]) + + result +end + +def _reduce_219(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_220(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_221(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_222(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], nil) + + result +end + +def _reduce_223(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], nil) + + result +end + +def _reduce_224(val, _values, result) + result = @builder.range_inclusive(nil, val[0], val[1]) + + result +end + +def _reduce_225(val, _values, result) + result = @builder.range_exclusive(nil, val[0], val[1]) + + result +end + +def _reduce_226(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_227(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_228(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_229(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_230(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_231(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_232(val, _values, result) + result = @builder.unary_op(val[0], + @builder.binary_op( + val[1], val[2], val[3])) + + result +end + +def _reduce_233(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_234(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_235(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_236(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_237(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_238(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +# reduce 239 omitted + +def _reduce_240(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_241(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_242(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_243(val, _values, result) + result = @builder.match_op(val[0], val[1], val[2]) + + result +end + +def _reduce_244(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_245(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +def _reduce_246(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_247(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_248(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_249(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_250(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_251(val, _values, result) + @context.in_defined = true + + result +end + +def _reduce_252(val, _values, result) + @context.in_defined = false + result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[3] ], nil) + + result +end + +def _reduce_253(val, _values, result) + result = @builder.ternary(val[0], val[1], + val[2], val[4], val[5]) + + result +end + +def _reduce_254(val, _values, result) + def_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + result = @builder.def_endless_method(def_t, name_t, + val[1], val[2], val[3]) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_255(val, _values, result) + def_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + rescue_body = @builder.rescue_body(val[4], + nil, nil, nil, + nil, val[5]) + + method_body = @builder.begin_body(val[3], [ rescue_body ]) + + result = @builder.def_endless_method(def_t, name_t, + val[1], val[2], method_body) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_256(val, _values, result) + def_t, recv, dot_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + result = @builder.def_endless_singleton(def_t, recv, dot_t, name_t, + val[1], val[2], val[3]) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_257(val, _values, result) + def_t, recv, dot_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + rescue_body = @builder.rescue_body(val[4], + nil, nil, nil, + nil, val[5]) + + method_body = @builder.begin_body(val[3], [ rescue_body ]) + + result = @builder.def_endless_singleton(def_t, recv, dot_t, name_t, + val[1], val[2], method_body) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +# reduce 258 omitted + +# reduce 259 omitted + +# reduce 260 omitted + +# reduce 261 omitted + +# reduce 262 omitted + +def _reduce_263(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_264(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +# reduce 265 omitted + +# reduce 266 omitted + +# reduce 267 omitted + +def _reduce_268(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_269(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +# reduce 270 omitted + +def _reduce_271(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_272(val, _values, result) + result = val + + result +end + +def _reduce_273(val, _values, result) + unless @static_env.declared_forward_args? + diagnostic :error, :unexpected_token, { :token => 'tBDOT3' } , val[3] + end + + result = [val[0], [*val[1], @builder.forwarded_args(val[3])], val[4]] + + result +end + +def _reduce_274(val, _values, result) + unless @static_env.declared_forward_args? + diagnostic :error, :unexpected_token, { :token => 'tBDOT3' } , val[1] + end + + result = [val[0], [@builder.forwarded_args(val[1])], val[2]] + + result +end + +def _reduce_275(val, _values, result) + result = [ nil, [], nil ] + + result +end + +# reduce 276 omitted + +def _reduce_277(val, _values, result) + result = [] + + result +end + +# reduce 278 omitted + +# reduce 279 omitted + +def _reduce_280(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_281(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +def _reduce_282(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_283(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_284(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + result.concat(val[1]) + + result +end + +def _reduce_285(val, _values, result) + assocs = @builder.associate(nil, val[2], nil) + result = val[0] << assocs + result.concat(val[3]) + + result +end + +def _reduce_286(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_287(val, _values, result) + # When branch gets invoked by RACC's lookahead + # and command args start with '[' or '(' + # we need to put `true` to the cmdarg stack + # **before** `false` pushed by lexer + # m [], n + # ^ + # Right here we have cmdarg [...0] because + # lexer pushed it on '[' + # We need to modify cmdarg stack to [...10] + # + # For all other cases (like `m n` or `m n, []`) we simply put 1 to the stack + # and later lexer pushes corresponding bits on top of it. + last_token = @last_token[0] + lookahead = last_token == :tLBRACK || last_token == :tLPAREN_ARG + + if lookahead + top = @lexer.cmdarg.pop + @lexer.cmdarg.push(true) + @lexer.cmdarg.push(top) + else + @lexer.cmdarg.push(true) + end + + result +end + +def _reduce_288(val, _values, result) + # call_args can be followed by tLBRACE_ARG (that does cmdarg.push(0) in the lexer) + # but the push must be done after cmdarg.pop() in the parser. + # So this code does cmdarg.pop() to pop 0 pushed by tLBRACE_ARG, + # cmdarg.pop() to pop 1 pushed by command_args, + # and cmdarg.push(0) to restore back the flag set by tLBRACE_ARG. + last_token = @last_token[0] + lookahead = last_token == :tLBRACE_ARG + if lookahead + top = @lexer.cmdarg.pop + @lexer.cmdarg.pop + @lexer.cmdarg.push(top) + else + @lexer.cmdarg.pop + end + + result = val[1] + + result +end + +def _reduce_289(val, _values, result) + result = @builder.block_pass(val[0], val[1]) + + result +end + +def _reduce_290(val, _values, result) + if !@static_env.declared_anonymous_blockarg? + diagnostic :error, :no_anonymous_blockarg, nil, val[0] + end + + result = @builder.block_pass(val[0], nil) + + result +end + +def _reduce_291(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_292(val, _values, result) + result = [] + + result +end + +def _reduce_293(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_294(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_295(val, _values, result) + if !@static_env.declared_anonymous_restarg? + diagnostic :error, :no_anonymous_restarg, nil, val[0] + end + + result = [ @builder.forwarded_restarg(val[0]) ] + + result +end + +def _reduce_296(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_297(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_298(val, _values, result) + if !@static_env.declared_anonymous_restarg? + diagnostic :error, :no_anonymous_restarg, nil, val[2] + end + + result = val[0] << @builder.forwarded_restarg(val[2]) + + result +end + +def _reduce_299(val, _values, result) + result = @builder.array(nil, val[0], nil) + + result +end + +# reduce 300 omitted + +def _reduce_301(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_302(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_303(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +# reduce 304 omitted + +# reduce 305 omitted + +# reduce 306 omitted + +# reduce 307 omitted + +# reduce 308 omitted + +# reduce 309 omitted + +# reduce 310 omitted + +# reduce 311 omitted + +# reduce 312 omitted + +# reduce 313 omitted + +def _reduce_314(val, _values, result) + result = @builder.call_method(nil, nil, val[0]) + + result +end + +def _reduce_315(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_316(val, _values, result) + @lexer.cmdarg.pop + + result = @builder.begin_keyword(val[0], val[2], val[3]) + + result +end + +def _reduce_317(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_318(val, _values, result) + result = @builder.begin(val[0], val[1], val[3]) + + result +end + +def _reduce_319(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_320(val, _values, result) + result = @builder.begin(val[0], nil, val[3]) + + result +end + +def _reduce_321(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_322(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +def _reduce_323(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_324(val, _values, result) + result = @builder.array(val[0], val[1], val[2]) + + result +end + +def _reduce_325(val, _values, result) + result = @builder.associate(val[0], val[1], val[2]) + + result +end + +def _reduce_326(val, _values, result) + result = @builder.keyword_cmd(:return, val[0]) + + result +end + +def _reduce_327(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_328(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2]) + + result +end + +def _reduce_329(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0]) + + result +end + +def _reduce_330(val, _values, result) + @context.in_defined = true + + result +end + +def _reduce_331(val, _values, result) + @context.in_defined = false + result = @builder.keyword_cmd(:defined?, val[0], + val[2], [ val[4] ], val[5]) + + result +end + +def _reduce_332(val, _values, result) + result = @builder.not_op(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_333(val, _values, result) + result = @builder.not_op(val[0], val[1], nil, val[2]) + + result +end + +def _reduce_334(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0]) + + begin_t, args, body, end_t = val[1] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +# reduce 335 omitted + +def _reduce_336(val, _values, result) + begin_t, args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, args, body, end_t) + + result +end + +# reduce 337 omitted + +def _reduce_338(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, val[5]) + + result +end + +def _reduce_339(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + else_, else_t, + val[3], val[5]) + + result +end + +def _reduce_340(val, _values, result) + result = @builder.loop(:while, val[0], *val[1], val[2], val[3]) + + result +end + +def _reduce_341(val, _values, result) + result = @builder.loop(:until, val[0], *val[1], val[2], val[3]) + + result +end + +def _reduce_342(val, _values, result) + *when_bodies, (else_t, else_body) = *val[3] + + result = @builder.case(val[0], val[1], + when_bodies, else_t, else_body, + val[4]) + + result +end + +def _reduce_343(val, _values, result) + *when_bodies, (else_t, else_body) = *val[2] + + result = @builder.case(val[0], nil, + when_bodies, else_t, else_body, + val[3]) + + result +end + +def _reduce_344(val, _values, result) + *in_bodies, (else_t, else_body) = *val[3] + + result = @builder.case_match(val[0], val[1], + in_bodies, else_t, else_body, + val[4]) + + result +end + +def _reduce_345(val, _values, result) + result = @builder.for(val[0], val[1], val[2], *val[3], val[4], val[5]) + + result +end + +def _reduce_346(val, _values, result) + @context.in_class = true + local_push + + result +end + +def _reduce_347(val, _values, result) + k_class, ctx = val[0] + if @context.in_def + diagnostic :error, :class_in_def, nil, k_class + end + lt_t, superclass = val[2] + result = @builder.def_class(k_class, val[1], + lt_t, superclass, + val[4], val[5]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_348(val, _values, result) + @context.in_def = false + @context.in_class = false + local_push + + result +end + +def _reduce_349(val, _values, result) + k_class, ctx = val[0] + result = @builder.def_sclass(k_class, val[1], val[2], + val[5], val[6]) + + local_pop + @context.in_def = ctx.in_def + @context.in_class = ctx.in_class + + result +end + +def _reduce_350(val, _values, result) + @context.in_class = true + local_push + + result +end + +def _reduce_351(val, _values, result) + k_mod, ctx = val[0] + if @context.in_def + diagnostic :error, :module_in_def, nil, k_mod + end + result = @builder.def_module(k_mod, val[1], + val[3], val[4]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_352(val, _values, result) + def_t, (name_t, ctx) = val[0] + result = @builder.def_method(def_t, name_t, val[1], + val[2], val[3]) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_353(val, _values, result) + def_t, recv, dot_t, (name_t, ctx) = val[0] + result = @builder.def_singleton(def_t, recv, dot_t, name_t, val[1], + val[2], val[3]) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_354(val, _values, result) + result = @builder.keyword_cmd(:break, val[0]) + + result +end + +def _reduce_355(val, _values, result) + result = @builder.keyword_cmd(:next, val[0]) + + result +end + +def _reduce_356(val, _values, result) + result = @builder.keyword_cmd(:redo, val[0]) + + result +end + +def _reduce_357(val, _values, result) + result = @builder.keyword_cmd(:retry, val[0]) + + result +end + +# reduce 358 omitted + +def _reduce_359(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_360(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_361(val, _values, result) + result = val[0] + @context.in_argdef = true + + result +end + +def _reduce_362(val, _values, result) + if @context.in_class && !@context.in_def && !(context.in_block || context.in_lambda) + diagnostic :error, :invalid_return, nil, val[0] + end + + result +end + +# reduce 363 omitted + +# reduce 364 omitted + +def _reduce_365(val, _values, result) + result = val[1] + + result +end + +# reduce 366 omitted + +# reduce 367 omitted + +# reduce 368 omitted + +def _reduce_369(val, _values, result) + else_t, else_ = val[4] + result = [ val[0], + @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, nil), + ] + + result +end + +# reduce 370 omitted + +def _reduce_371(val, _values, result) + result = val + + result +end + +# reduce 372 omitted + +# reduce 373 omitted + +def _reduce_374(val, _values, result) + result = @builder.arg(val[0]) + + result +end + +def _reduce_375(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_376(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_377(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 378 omitted + +def _reduce_379(val, _values, result) + result = val[0]. + push(val[2]) + + result +end + +def _reduce_380(val, _values, result) + result = val[0]. + push(val[2]). + concat(val[4]) + + result +end + +def _reduce_381(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_382(val, _values, result) + result = [ val[0], *val[2] ] + + result +end + +def _reduce_383(val, _values, result) + result = @builder.restarg(val[0], val[1]) + + result +end + +def _reduce_384(val, _values, result) + result = @builder.restarg(val[0]) + + result +end + +# reduce 385 omitted + +# reduce 386 omitted + +def _reduce_387(val, _values, result) + @context.in_argdef = false + + result +end + +def _reduce_388(val, _values, result) + result = val[1] + + result +end + +def _reduce_389(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_390(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_391(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_392(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_393(val, _values, result) + result = val[1] + + result +end + +def _reduce_394(val, _values, result) + result = [] + + result +end + +# reduce 395 omitted + +def _reduce_396(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_397(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_398(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_399(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_400(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 401 omitted + +def _reduce_402(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_403(val, _values, result) + if val[1].empty? && val[0].size == 1 + result = [@builder.procarg0(val[0][0])] + else + result = val[0].concat(val[1]) + end + + result +end + +def _reduce_404(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_405(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_406(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_407(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_408(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_409(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 410 omitted + +def _reduce_411(val, _values, result) + result = @builder.args(nil, [], nil) + + result +end + +def _reduce_412(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_413(val, _values, result) + @max_numparam_stack.has_ordinary_params! + @current_arg_stack.set(nil) + @context.in_argdef = false + result = @builder.args(val[0], val[1], val[2]) + + result +end + +def _reduce_414(val, _values, result) + @max_numparam_stack.has_ordinary_params! + @current_arg_stack.set(nil) + @context.in_argdef = false + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_415(val, _values, result) + result = [] + + result +end + +def _reduce_416(val, _values, result) + result = val[2] + + result +end + +def _reduce_417(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_418(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_419(val, _values, result) + @static_env.declare val[0][0] + result = @builder.shadowarg(val[0]) + + result +end + +# reduce 420 omitted + +def _reduce_421(val, _values, result) + @static_env.extend_dynamic + @max_numparam_stack.push(static: false) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_422(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_423(val, _values, result) + lambda_call = @builder.call_lambda(val[0]) + args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[2] + begin_t, body, end_t = val[4] + + @max_numparam_stack.pop + @static_env.unextend + @lexer.cmdarg.pop + @context.in_lambda = val[1].in_lambda + + result = @builder.block(lambda_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_424(val, _values, result) + @context.in_argdef = false + @max_numparam_stack.has_ordinary_params! + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_425(val, _values, result) + @context.in_argdef = false + if val[0].any? + @max_numparam_stack.has_ordinary_params! + end + result = @builder.args(nil, val[0], nil) + + result +end + +def _reduce_426(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_427(val, _values, result) + @context.in_lambda = val[1].in_lambda + result = [ val[0], val[2], val[3] ] + + result +end + +def _reduce_428(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_429(val, _values, result) + @context.in_lambda = val[1].in_lambda + result = [ val[0], val[2], val[3] ] + + result +end + +def _reduce_430(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_431(val, _values, result) + @context.in_block = val[1].in_block + result = [ val[0], *val[2], val[3] ] + + result +end + +def _reduce_432(val, _values, result) + begin_t, block_args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, block_args, body, end_t) + + result +end + +def _reduce_433(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_434(val, _values, result) + lparen_t, args, rparen_t = val[3] + method_call = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_435(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_436(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.call_method(nil, nil, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_437(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_438(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_439(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2]) + + result +end + +def _reduce_440(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_441(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_442(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.keyword_cmd(:super, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_443(val, _values, result) + result = @builder.keyword_cmd(:zsuper, val[0]) + + result +end + +def _reduce_444(val, _values, result) + result = @builder.index(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_445(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_446(val, _values, result) + @context.in_block = val[1].in_block + result = [ val[0], *val[2], val[3] ] + + result +end + +def _reduce_447(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_448(val, _values, result) + @context.in_block = val[1].in_block + result = [ val[0], *val[2], val[3] ] + + result +end + +def _reduce_449(val, _values, result) + @static_env.extend_dynamic + @max_numparam_stack.push(static: false) + + result +end + +def _reduce_450(val, _values, result) + args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[1] + result = [ args, val[2] ] + + @max_numparam_stack.pop + @static_env.unextend + + result +end + +def _reduce_451(val, _values, result) + @static_env.extend_dynamic + @max_numparam_stack.push(static: false) + + result +end + +def _reduce_452(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_453(val, _values, result) + args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[2] + result = [ args, val[3] ] + + @max_numparam_stack.pop + @static_env.unextend + @lexer.cmdarg.pop + + result +end + +def _reduce_454(val, _values, result) + result = [ @builder.when(val[0], val[1], val[2], val[3]), + *val[4] ] + + result +end + +def _reduce_455(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 456 omitted + +def _reduce_457(val, _values, result) + @lexer.state = :expr_beg + @lexer.command_start = false + @pattern_variables.push + @pattern_hash_keys.push + + result = @context.in_kwarg + @context.in_kwarg = true + + result +end + +def _reduce_458(val, _values, result) + @pattern_variables.pop + @pattern_hash_keys.pop + @context.in_kwarg = val[1] + + result +end + +def _reduce_459(val, _values, result) + result = [ @builder.in_pattern(val[0], *val[2], val[3], val[5]), + *val[6] ] + + result +end + +def _reduce_460(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 461 omitted + +def _reduce_462(val, _values, result) + result = [ val[0], nil ] + + result +end + +def _reduce_463(val, _values, result) + result = [ val[0], @builder.if_guard(val[1], val[2]) ] + + result +end + +def _reduce_464(val, _values, result) + result = [ val[0], @builder.unless_guard(val[1], val[2]) ] + + result +end + +# reduce 465 omitted + +def _reduce_466(val, _values, result) + # array patterns that end with comma + # like 1, 2, + # must be emitted as `array_pattern_with_tail` + item = @builder.match_with_trailing_comma(val[0], val[1]) + result = @builder.array_pattern(nil, [ item ], nil) + + result +end + +def _reduce_467(val, _values, result) + result = @builder.array_pattern(nil, [val[0]].concat(val[2]), nil) + + result +end + +def _reduce_468(val, _values, result) + result = @builder.find_pattern(nil, val[0], nil) + + result +end + +def _reduce_469(val, _values, result) + result = @builder.array_pattern(nil, val[0], nil) + + result +end + +def _reduce_470(val, _values, result) + result = @builder.hash_pattern(nil, val[0], nil) + + result +end + +# reduce 471 omitted + +def _reduce_472(val, _values, result) + result = @builder.match_as(val[0], val[1], val[2]) + + result +end + +# reduce 473 omitted + +def _reduce_474(val, _values, result) + result = @builder.match_alt(val[0], val[1], val[2]) + + result +end + +# reduce 475 omitted + +def _reduce_476(val, _values, result) + result = val[0] + @pattern_hash_keys.push + + result +end + +def _reduce_477(val, _values, result) + result = val[0] + @pattern_hash_keys.push + + result +end + +# reduce 478 omitted + +# reduce 479 omitted + +def _reduce_480(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.array_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_481(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.find_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_482(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.hash_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_483(val, _values, result) + pattern = @builder.array_pattern(val[1], nil, val[2]) + result = @builder.const_pattern(val[0], val[1], pattern, val[2]) + + result +end + +def _reduce_484(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.array_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_485(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.find_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_486(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.hash_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_487(val, _values, result) + pattern = @builder.array_pattern(val[1], nil, val[2]) + result = @builder.const_pattern(val[0], val[1], pattern, val[2]) + + result +end + +def _reduce_488(val, _values, result) + result = @builder.array_pattern(val[0], val[1], val[2]) + + result +end + +def _reduce_489(val, _values, result) + result = @builder.find_pattern(val[0], val[1], val[2]) + + result +end + +def _reduce_490(val, _values, result) + result = @builder.array_pattern(val[0], [], val[1]) + + result +end + +def _reduce_491(val, _values, result) + @pattern_hash_keys.push + result = @context.in_kwarg + @context.in_kwarg = false + + result +end + +def _reduce_492(val, _values, result) + @pattern_hash_keys.pop + @context.in_kwarg = val[1] + result = @builder.hash_pattern(val[0], val[2], val[3]) + + result +end + +def _reduce_493(val, _values, result) + result = @builder.hash_pattern(val[0], [], val[1]) + + result +end + +def _reduce_494(val, _values, result) + @pattern_hash_keys.push + + result +end + +def _reduce_495(val, _values, result) + @pattern_hash_keys.pop + result = @builder.begin(val[0], val[2], val[3]) + + result +end + +def _reduce_496(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_497(val, _values, result) + result = val[0] + + result +end + +def _reduce_498(val, _values, result) + result = [ *val[0], val[1] ] + + result +end + +def _reduce_499(val, _values, result) + result = [ *val[0], val[1] ] + + result +end + +def _reduce_500(val, _values, result) + result = [ *val[0], val[1], *val[3] ] + + result +end + +# reduce 501 omitted + +def _reduce_502(val, _values, result) + # array patterns that end with comma + # like [1, 2,] + # must be emitted as `array_pattern_with_tail` + item = @builder.match_with_trailing_comma(val[0], val[1]) + result = [ item ] + + result +end + +def _reduce_503(val, _values, result) + # array patterns that end with comma + # like [1, 2,] + # must be emitted as `array_pattern_with_tail` + last_item = @builder.match_with_trailing_comma(val[1], val[2]) + result = [ *val[0], last_item ] + + result +end + +def _reduce_504(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_505(val, _values, result) + result = [ val[0], *val[2] ] + + result +end + +def _reduce_506(val, _values, result) + result = [ val[0], *val[2], val[4] ] + + result +end + +def _reduce_507(val, _values, result) + result = @builder.match_rest(val[0], val[1]) + + result +end + +def _reduce_508(val, _values, result) + result = @builder.match_rest(val[0]) + + result +end + +def _reduce_509(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_510(val, _values, result) + result = [ *val[0], val[2] ] + + result +end + +# reduce 511 omitted + +def _reduce_512(val, _values, result) + result = [ *val[0], *val[2] ] + + result +end + +def _reduce_513(val, _values, result) + result = val[0] + + result +end + +def _reduce_514(val, _values, result) + result = val[0] + + result +end + +def _reduce_515(val, _values, result) + result = val[0] + + result +end + +def _reduce_516(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_517(val, _values, result) + result = [ *val[0], val[2] ] + + result +end + +def _reduce_518(val, _values, result) + result = @builder.match_pair(*val[0], val[1]) + + result +end + +def _reduce_519(val, _values, result) + result = @builder.match_label(*val[0]) + + result +end + +def _reduce_520(val, _values, result) + result = [:label, val[0]] + + result +end + +def _reduce_521(val, _values, result) + result = [:quoted, [val[0], val[1], val[2]]] + + result +end + +def _reduce_522(val, _values, result) + result = [ @builder.match_rest(val[0], val[1]) ] + + result +end + +def _reduce_523(val, _values, result) + result = [ @builder.match_rest(val[0], nil) ] + + result +end + +def _reduce_524(val, _values, result) + result = val + + result +end + +# reduce 525 omitted + +def _reduce_526(val, _values, result) + result = [ @builder.match_nil_pattern(val[0][0], val[0][1]) ] + + result +end + +# reduce 527 omitted + +def _reduce_528(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_529(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_530(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], nil) + + result +end + +def _reduce_531(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], nil) + + result +end + +# reduce 532 omitted + +# reduce 533 omitted + +# reduce 534 omitted + +def _reduce_535(val, _values, result) + result = @builder.range_inclusive(nil, val[0], val[1]) + + result +end + +def _reduce_536(val, _values, result) + result = @builder.range_exclusive(nil, val[0], val[1]) + + result +end + +# reduce 537 omitted + +# reduce 538 omitted + +# reduce 539 omitted + +# reduce 540 omitted + +# reduce 541 omitted + +# reduce 542 omitted + +# reduce 543 omitted + +# reduce 544 omitted + +def _reduce_545(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +# reduce 546 omitted + +def _reduce_547(val, _values, result) + result = @builder.assignable(@builder.match_var(val[0])) + + result +end + +def _reduce_548(val, _values, result) + name = val[1][0] + lvar = @builder.accessible(@builder.ident(val[1])) + + unless static_env.declared?(name) + diagnostic :error, :undefined_lvar, { :name => name }, val[1] + end + + result = @builder.pin(val[0], lvar) + + result +end + +def _reduce_549(val, _values, result) + non_lvar = @builder.accessible(val[1]) + result = @builder.pin(val[0], non_lvar) + + result +end + +def _reduce_550(val, _values, result) + expr = @builder.begin(val[1], val[2], val[3]) + result = @builder.pin(val[0], expr) + + result +end + +def _reduce_551(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_552(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +def _reduce_553(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_554(val, _values, result) + assoc_t, exc_var = val[2] + + if val[1] + exc_list = @builder.array(nil, val[1], nil) + end + + result = [ @builder.rescue_body(val[0], + exc_list, assoc_t, exc_var, + val[3], val[4]), + *val[5] ] + + result +end + +def _reduce_555(val, _values, result) + result = [] + + result +end + +def _reduce_556(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 557 omitted + +# reduce 558 omitted + +def _reduce_559(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 560 omitted + +def _reduce_561(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 562 omitted + +# reduce 563 omitted + +# reduce 564 omitted + +def _reduce_565(val, _values, result) + result = @builder.string_compose(nil, val[0], nil) + + result +end + +def _reduce_566(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_567(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_568(val, _values, result) + string = @builder.string_compose(val[0], val[1], val[2]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_569(val, _values, result) + string = @builder.string(val[0]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_570(val, _values, result) + result = @builder.character(val[0]) + + result +end + +def _reduce_571(val, _values, result) + string = @builder.xstring_compose(val[0], val[1], val[2]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_572(val, _values, result) + opts = @builder.regexp_options(val[3]) + result = @builder.regexp_compose(val[0], val[1], val[2], opts) + + result +end + +def _reduce_573(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_574(val, _values, result) + result = [] + + result +end + +def _reduce_575(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_576(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_577(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_578(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_579(val, _values, result) + result = [] + + result +end + +def _reduce_580(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_581(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_582(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_583(val, _values, result) + result = [] + + result +end + +def _reduce_584(val, _values, result) + result = val[0] << @builder.string_internal(val[1]) + + result +end + +def _reduce_585(val, _values, result) + result = [] + + result +end + +def _reduce_586(val, _values, result) + result = val[0] << @builder.symbol_internal(val[1]) + + result +end + +def _reduce_587(val, _values, result) + result = [] + + result +end + +def _reduce_588(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_589(val, _values, result) + result = [] + + result +end + +def _reduce_590(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_591(val, _values, result) + result = [] + + result +end + +def _reduce_592(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_593(val, _values, result) + result = @builder.string_internal(val[0]) + + result +end + +def _reduce_594(val, _values, result) + result = val[1] + + result +end + +def _reduce_595(val, _values, result) + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + + result +end + +def _reduce_596(val, _values, result) + @lexer.cmdarg.pop + @lexer.cond.pop + + result = @builder.begin(val[0], val[2], val[3]) + + result +end + +def _reduce_597(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_598(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_599(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +# reduce 600 omitted + +# reduce 601 omitted + +# reduce 602 omitted + +def _reduce_603(val, _values, result) + @lexer.state = :expr_end + result = @builder.symbol(val[0]) + + result +end + +def _reduce_604(val, _values, result) + @lexer.state = :expr_end + result = @builder.symbol_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_605(val, _values, result) + result = val[0] + + result +end + +def _reduce_606(val, _values, result) + if @builder.respond_to? :negate + # AST builder interface compatibility + result = @builder.negate(val[0], val[1]) + else + result = @builder.unary_num(val[0], val[1]) + end + + result +end + +def _reduce_607(val, _values, result) + @lexer.state = :expr_end + result = @builder.integer(val[0]) + + result +end + +def _reduce_608(val, _values, result) + @lexer.state = :expr_end + result = @builder.float(val[0]) + + result +end + +def _reduce_609(val, _values, result) + @lexer.state = :expr_end + result = @builder.rational(val[0]) + + result +end + +def _reduce_610(val, _values, result) + @lexer.state = :expr_end + result = @builder.complex(val[0]) + + result +end + +def _reduce_611(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_612(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_613(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +def _reduce_614(val, _values, result) + result = @builder.ident(val[0]) + + result +end + +def _reduce_615(val, _values, result) + result = @builder.const(val[0]) + + result +end + +# reduce 616 omitted + +def _reduce_617(val, _values, result) + result = @builder.nil(val[0]) + + result +end + +def _reduce_618(val, _values, result) + result = @builder.self(val[0]) + + result +end + +def _reduce_619(val, _values, result) + result = @builder.true(val[0]) + + result +end + +def _reduce_620(val, _values, result) + result = @builder.false(val[0]) + + result +end + +def _reduce_621(val, _values, result) + result = @builder.__FILE__(val[0]) + + result +end + +def _reduce_622(val, _values, result) + result = @builder.__LINE__(val[0]) + + result +end + +def _reduce_623(val, _values, result) + result = @builder.__ENCODING__(val[0]) + + result +end + +def _reduce_624(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_625(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_626(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_627(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_628(val, _values, result) + result = @builder.nth_ref(val[0]) + + result +end + +def _reduce_629(val, _values, result) + result = @builder.back_ref(val[0]) + + result +end + +def _reduce_630(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_631(val, _values, result) + result = [ val[0], val[2] ] + + result +end + +def _reduce_632(val, _values, result) + result = nil + + result +end + +# reduce 633 omitted + +def _reduce_634(val, _values, result) + @context.in_argdef = false + result = @builder.args(nil, [], nil) + + result +end + +def _reduce_635(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + @lexer.state = :expr_value + @context.in_argdef = false + + result +end + +# reduce 636 omitted + +def _reduce_637(val, _values, result) + result = @context.dup + @context.in_kwarg = true + @context.in_argdef = true + + result +end + +def _reduce_638(val, _values, result) + @context.in_kwarg = val[0].in_kwarg + @context.in_argdef = false + result = @builder.args(nil, val[1], nil) + + result +end + +def _reduce_639(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_640(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_641(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_642(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_643(val, _values, result) + @static_env.declare_forward_args + result = [ @builder.forward_arg(val[0]) ] + + result +end + +def _reduce_644(val, _values, result) + result = val[1] + + result +end + +def _reduce_645(val, _values, result) + result = [] + + result +end + +def _reduce_646(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_647(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_648(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_649(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_650(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_651(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_652(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_653(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_654(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_655(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_656(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_657(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_658(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_659(val, _values, result) + result = val[0] + + result +end + +def _reduce_660(val, _values, result) + result = [] + + result +end + +def _reduce_661(val, _values, result) + result = val[0] + + result +end + +def _reduce_662(val, _values, result) + diagnostic :error, :argument_const, nil, val[0] + + result +end + +def _reduce_663(val, _values, result) + diagnostic :error, :argument_ivar, nil, val[0] + + result +end + +def _reduce_664(val, _values, result) + diagnostic :error, :argument_gvar, nil, val[0] + + result +end + +def _reduce_665(val, _values, result) + diagnostic :error, :argument_cvar, nil, val[0] + + result +end + +# reduce 666 omitted + +def _reduce_667(val, _values, result) + @static_env.declare val[0][0] + + @max_numparam_stack.has_ordinary_params! + + result = val[0] + + result +end + +def _reduce_668(val, _values, result) + @current_arg_stack.set(val[0][0]) + result = val[0] + + result +end + +def _reduce_669(val, _values, result) + @current_arg_stack.set(0) + result = @builder.arg(val[0]) + + result +end + +def _reduce_670(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_671(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_672(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_673(val, _values, result) + check_kwarg_name(val[0]) + + @static_env.declare val[0][0] + + @max_numparam_stack.has_ordinary_params! + + @current_arg_stack.set(val[0][0]) + @context.in_argdef = false + + result = val[0] + + result +end + +def _reduce_674(val, _values, result) + @current_arg_stack.set(nil) + @context.in_argdef = true + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_675(val, _values, result) + @current_arg_stack.set(nil) + @context.in_argdef = true + result = @builder.kwarg(val[0]) + + result +end + +def _reduce_676(val, _values, result) + @context.in_argdef = true + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_677(val, _values, result) + @context.in_argdef = true + result = @builder.kwarg(val[0]) + + result +end + +def _reduce_678(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_679(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_680(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_681(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 682 omitted + +# reduce 683 omitted + +def _reduce_684(val, _values, result) + result = [ @builder.kwnilarg(val[0][0], val[0][1]) ] + + result +end + +def _reduce_685(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.kwrestarg(val[0], val[1]) ] + + result +end + +def _reduce_686(val, _values, result) + @static_env.declare_anonymous_kwrestarg + + result = [ @builder.kwrestarg(val[0]) ] + + result +end + +def _reduce_687(val, _values, result) + @current_arg_stack.set(0) + @context.in_argdef = true + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_688(val, _values, result) + @current_arg_stack.set(0) + @context.in_argdef = true + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_689(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_690(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_691(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_692(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 693 omitted + +# reduce 694 omitted + +def _reduce_695(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_696(val, _values, result) + @static_env.declare_anonymous_restarg + + result = [ @builder.restarg(val[0]) ] + + result +end + +# reduce 697 omitted + +# reduce 698 omitted + +def _reduce_699(val, _values, result) + @static_env.declare val[1][0] + + result = @builder.blockarg(val[0], val[1]) + + result +end + +def _reduce_700(val, _values, result) + @static_env.declare_anonymous_blockarg + + result = @builder.blockarg(val[0], nil) + + result +end + +def _reduce_701(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_702(val, _values, result) + result = [] + + result +end + +# reduce 703 omitted + +def _reduce_704(val, _values, result) + result = val[1] + + result +end + +def _reduce_705(val, _values, result) + result = [] + + result +end + +# reduce 706 omitted + +def _reduce_707(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_708(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_709(val, _values, result) + result = @builder.pair(val[0], val[1], val[2]) + + result +end + +def _reduce_710(val, _values, result) + result = @builder.pair_keyword(val[0], val[1]) + + result +end + +def _reduce_711(val, _values, result) + result = @builder.pair_label(val[0]) + + result +end + +def _reduce_712(val, _values, result) + result = @builder.pair_quoted(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_713(val, _values, result) + result = @builder.kwsplat(val[0], val[1]) + + result +end + +def _reduce_714(val, _values, result) + if !@static_env.declared_anonymous_kwrestarg? + diagnostic :error, :no_anonymous_kwrestarg, nil, val[0] + end + + result = @builder.forwarded_kwrestarg(val[0]) + + result +end + +# reduce 715 omitted + +# reduce 716 omitted + +# reduce 717 omitted + +# reduce 718 omitted + +# reduce 719 omitted + +# reduce 720 omitted + +# reduce 721 omitted + +# reduce 722 omitted + +# reduce 723 omitted + +# reduce 724 omitted + +def _reduce_725(val, _values, result) + result = [:dot, val[0][1]] + + result +end + +def _reduce_726(val, _values, result) + result = [:anddot, val[0][1]] + + result +end + +# reduce 727 omitted + +# reduce 728 omitted + +# reduce 729 omitted + +# reduce 730 omitted + +def _reduce_731(val, _values, result) + result = val[1] + + result +end + +def _reduce_732(val, _values, result) + result = val[1] + + result +end + +def _reduce_733(val, _values, result) + result = val[1] + + result +end + +# reduce 734 omitted + +# reduce 735 omitted + +def _reduce_736(val, _values, result) + yyerrok + + result +end + +# reduce 737 omitted + +# reduce 738 omitted + +# reduce 739 omitted + +def _reduce_740(val, _values, result) + result = nil + + result +end + +def _reduce_none(val, _values, result) + val[0] +end + + end # class Ruby32 +end # module Parser diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby33.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby33.rb new file mode 100644 index 00000000..0de496c6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby33.rb @@ -0,0 +1,12590 @@ +# -*- encoding:utf-8; warn-indent:false; frozen_string_literal: true -*- +# +# DO NOT MODIFY!!!! +# This file is automatically generated by Racc 1.8.1 +# from Racc grammar file "ruby33.y". +# + +require 'racc/parser.rb' + + +require_relative '../parser' + +module Parser + class Ruby33 < Parser::Base + + + def version + 33 + end + + def default_encoding + Encoding::UTF_8 + end + + def endless_method_name(name_t) + if !%w[=== == != <= >=].include?(name_t[0]) && name_t[0].end_with?('=') + diagnostic :error, :endless_setter, nil, name_t + end + end + + def local_push + @static_env.extend_static + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + @max_numparam_stack.push(static: true) + end + + def local_pop + @static_env.unextend + @lexer.cmdarg.pop + @lexer.cond.pop + @max_numparam_stack.pop + end + + def try_declare_numparam(node) + name = node.children[0] + + if name =~ /\A_[1-9]\z/ && !static_env.declared?(name) && @context.in_dynamic_block? + # definitely an implicit param + location = node.loc.expression + + if max_numparam_stack.has_ordinary_params? + diagnostic :error, :ordinary_param_defined, nil, [nil, location] + end + + raw_max_numparam_stack = max_numparam_stack.stack.dup + # ignore current block scope + raw_max_numparam_stack.pop + + raw_max_numparam_stack.reverse_each do |outer_scope| + if outer_scope[:static] + # found an outer scope that can't have numparams + # like def/class/etc + break + else + outer_scope_has_numparams = outer_scope[:value] > 0 + + if outer_scope_has_numparams + diagnostic :error, :numparam_used_in_outer_scope, nil, [nil, location] + else + # for now it's ok, but an outer scope can also be a block + # like proc { _1; proc { proc { proc { _2 }} }} + # with numparams, so we need to continue + end + end + end + + static_env.declare(name) + max_numparam_stack.register(name[1].to_i) + + true + else + false + end + end +##### State transition tables begin ### + +racc_action_table = [ + -615, -627, 312, 222, 223, 312, -116, -615, -615, -615, + 1064, 624, -615, -615, -615, 228, -615, 312, 1064, 665, + 127, 240, 227, 624, -615, 126, -615, -615, -615, 222, + 223, 225, 704, 667, -117, -124, -615, -615, 624, -615, + -615, -615, -615, -615, 624, 624, -116, -117, -124, 859, + 705, -123, 3, 127, -123, 1064, 1063, -628, 126, 799, + -116, 241, 241, 525, -119, -121, -615, -615, -615, -615, + -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, + 229, 307, -615, -615, -615, 664, -615, -615, 794, 311, + -615, 931, 311, -615, -615, -118, -615, 241, -615, 666, + -615, -511, -615, -615, 311, -615, -615, -615, -615, -615, + 624, -615, -616, -615, -119, -107, -117, 222, 223, -616, + -616, -616, -124, 241, -616, -616, -616, -615, -616, 127, + -615, -615, -615, -615, 126, -615, -616, -615, -616, -616, + -616, 127, -615, -108, -115, -615, 126, 234, -616, -616, + -121, -616, -616, -616, -616, -616, 127, -120, -118, 920, + -114, 126, 127, 127, -116, -117, -124, 126, 126, -116, + -117, -124, -123, -110, -112, -120, -730, -123, -616, -616, + -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, + -616, -616, 127, -122, -616, -616, -616, 126, -616, -616, + 930, -122, -616, -741, -109, -616, -616, 859, -616, 631, + -616, 241, -616, 234, -616, -616, 241, -616, -616, -616, + -616, -616, -321, -616, 238, -616, 238, 604, 127, -321, + -321, -321, -119, 126, -716, -321, -321, -119, -321, -616, + -716, -110, -616, -616, -616, -616, -321, -616, 228, -616, + 312, -730, 631, 652, -616, 305, 123, -616, -321, -321, + 799, -321, -321, -321, -321, -321, -717, -102, -121, -741, + -717, -115, -112, -121, -111, -120, -118, 652, -109, -88, + -120, -118, 136, -124, -111, -124, -123, 241, -321, -321, + -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, + -321, -321, 219, 234, -321, -321, -321, -110, 691, -321, + -113, -122, -321, 229, 307, -321, -122, 654, 653, 650, + -321, 220, -321, 884, -321, -321, 652, -321, -321, -321, + -321, -321, 234, -321, 692, -321, 221, 311, -112, -716, + -111, 654, 653, 650, -109, 224, 989, -110, 240, -321, + -110, 90, -321, -321, 652, -113, 502, -321, 766, -741, + 127, -721, -110, 91, -321, 126, 885, -122, -721, -721, + -721, 104, 105, 92, -721, -721, 301, -721, -112, -730, + -111, -112, -119, -111, -109, -721, -721, -109, -741, 241, + 654, 653, 650, -112, 503, -111, 241, -721, -721, -109, + -721, -721, -721, -721, -721, 241, 1156, 1163, 615, 494, + -356, 491, 490, 489, 499, 492, 228, -356, 654, 653, + 655, 104, 105, 305, 502, -121, -356, -721, -721, -721, + -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, + -721, 240, -627, -721, -721, -721, 497, 693, -721, 106, + 107, -721, 652, 363, -721, 507, 506, 510, 509, -721, + 652, -721, 503, -721, -721, 652, -721, -721, -721, -721, + -721, -321, -721, -721, -721, -356, 686, 687, -321, -321, + -321, 229, 241, -321, -321, -321, -615, -321, -721, -107, + 364, -721, -721, -615, -111, -321, -721, -321, -321, 106, + 107, -116, 488, -721, -716, 241, -120, -321, -321, 704, + -321, -321, -321, -321, -321, 127, 654, 653, 222, 223, + 126, 652, 967, 652, 654, 653, 432, 1087, 652, 654, + 653, 657, 473, 1163, 823, -119, -121, -321, -321, -321, + -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, + -321, -615, -628, -321, -321, -321, -615, 886, -321, 241, + -634, -321, 618, -615, -321, -321, 652, -321, -716, -321, + 840, -321, -615, -321, -321, 513, -321, -321, -321, -321, + -321, -118, -321, 692, -321, 654, 653, 654, 653, 659, + -616, -716, 654, 653, 663, 823, 228, -616, -321, -108, + -623, -321, -321, 522, -321, 524, -321, -623, -622, 604, + -721, -117, 523, -321, 526, -622, -122, -721, -721, -721, + 127, -615, -721, -721, -721, 126, -721, 282, 283, -118, + 654, 653, 668, -624, -721, -721, -721, -721, -721, 1070, + -624, 637, 222, 223, 1066, 638, -721, -721, 1067, -721, + -721, -721, -721, -721, 637, -616, -114, 127, 1095, -621, + -618, 229, 126, 281, 280, -623, -621, -618, -123, 241, + 527, 886, 618, -622, -717, 240, -721, -721, -721, -721, + -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, + 562, 989, -721, -721, -721, 574, 887, -721, -624, 686, + -721, 502, -619, -721, -721, 576, -721, -620, -721, -619, + -721, 578, -721, -721, -620, -721, -721, -721, -721, -721, + -321, -721, -721, -721, -621, -618, 429, -321, -321, -321, + -122, 431, 430, -321, -321, 136, -321, -721, 265, 503, + -721, -721, -721, -721, -321, -721, -110, -721, 510, 509, + 637, 1156, -721, -717, 1095, -120, -321, -321, -119, -321, + -321, -321, -321, -321, -87, 241, 241, -619, 618, -625, + 262, 499, -620, 589, 264, 263, -625, 687, 109, 108, + 590, 502, 110, 121, 122, -625, -321, -321, -321, -321, + -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, + 597, 840, -321, -321, -321, -616, 691, -321, 241, 316, + -321, 1186, -616, -321, 510, 509, 241, -717, -321, 503, + -321, -616, -321, -321, -112, -321, -321, -321, -321, -321, + 234, -321, 692, -321, -625, 234, -121, 915, 859, 494, + -717, 491, 490, 489, 499, 492, 307, -321, -109, 601, + -321, -321, -721, -321, 502, -321, 607, 265, 265, -721, + -118, 611, -321, 1088, 1089, -122, -721, -721, -721, 499, + -616, 619, -721, -721, 620, -721, 497, 915, 859, 502, + 1222, 1223, 578, -721, -721, 507, 506, 510, 509, 262, + -626, 631, 503, 264, 263, -721, -721, -626, -721, -721, + -721, -721, -721, 421, -721, 635, -626, 636, 228, 644, + 669, -721, 510, 509, 672, 596, -716, 503, 241, 673, + -721, -294, 674, 676, 594, -721, -721, -721, -721, -721, + -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, + 680, -721, -721, -721, 241, 693, -721, -314, 684, -721, + 685, 307, -721, 702, -314, -626, 703, -721, 241, -721, + 707, -721, -721, -314, -721, -721, -721, -721, -721, -721, + -721, -721, -721, 229, 710, 228, 711, 713, 715, -385, + 228, 228, 606, 727, 728, 732, -721, 634, 640, -721, + -721, 523, -721, 734, -721, 228, 632, 642, 740, 741, + 265, -721, 679, 265, -120, 7, 81, 82, 83, 11, + 65, 677, -314, 265, 71, 72, 265, 241, 754, 75, + 241, 73, 74, 76, 35, 36, 79, 80, 257, 241, + 241, -102, 769, 84, 33, 32, 115, 114, 116, 117, + 229, 241, 23, 611, 780, 229, 229, 786, 10, 53, + 9, 12, 119, 118, 120, 111, 64, 109, 108, 112, + 229, 110, 121, 122, 787, 104, 105, 49, 50, 48, + 265, 269, 270, 271, 272, 282, 283, 277, 278, 273, + 274, -322, 258, 259, 790, 795, 275, 276, -322, 45, + 796, 256, 38, 800, 822, 66, 67, -322, 823, 68, + 823, 40, 262, -298, 268, 52, 264, 263, 841, 260, + 261, 281, 280, 266, 24, 267, 562, 562, 854, 102, + 90, 93, 94, -322, 95, 97, 96, 98, 856, 859, + -322, 877, 91, 101, 880, 279, 881, 241, 854, -322, + 85, 856, 92, 106, 107, 241, -322, 46, 47, 335, + 81, 82, 83, 11, 65, 893, 895, 301, 71, 72, + 901, 903, 905, 75, 576, 73, 74, 76, 35, 36, + 79, 80, 130, 131, 132, 133, 134, 84, 33, 32, + 115, 114, 116, 117, 578, 780, 23, 241, -322, 307, + 307, 681, 10, 53, 337, 12, 119, 118, 120, 111, + 64, 109, 108, 112, 780, 110, 121, 122, 265, 104, + 105, 49, 50, 48, 265, 269, 270, 271, 272, 282, + 283, 277, 278, 273, 274, -321, 258, 259, 859, 917, + 275, 276, -321, 45, 918, 241, 339, -717, 241, 66, + 67, -321, 928, 68, 241, 40, 262, 935, 268, 52, + 264, 263, 935, 260, 261, 281, 280, 266, 24, 267, + 935, 935, -296, 102, 90, 93, 94, 228, 95, 97, + 96, 98, 241, 940, 1128, 941, 91, 101, 947, 279, + -294, -266, 951, 1126, 85, 710, 92, 106, 107, 705, + -321, 46, 47, 335, 81, 82, 83, 11, 65, 954, + 956, 958, 71, 72, 960, 960, 241, 75, 903, 73, + 74, 76, 35, 36, 79, 80, 130, 131, 132, 133, + 134, 84, 33, 32, 115, 114, 116, 117, 1016, 241, + 23, 780, 229, 1033, 1035, 681, 10, 53, 337, 12, + 119, 118, 120, 111, 64, 109, 108, 112, 1039, 110, + 121, 122, 1040, 104, 105, 49, 50, 48, 265, 269, + 270, 271, 272, 282, 283, 277, 278, 273, 274, -321, + 258, 259, 1045, 1046, 275, 276, -321, 45, 1048, -298, + 38, -717, 854, 66, 67, -321, 856, 68, 1061, 40, + 262, 1062, 268, 52, 264, 263, 1065, 260, 261, 281, + 280, 266, 24, 267, 1082, 1083, 1084, 102, 90, 93, + 94, 228, 95, 97, 96, 98, 1098, 710, 1178, 1101, + 91, 101, 1104, 279, 1106, 1108, 241, 642, 85, -385, + 92, 106, 107, 1118, -321, 46, 47, 7, 81, 82, + 83, 11, 65, 1129, 1130, 960, 71, 72, 960, 960, + 1009, 75, 241, 73, 74, 76, 35, 36, 79, 80, + 130, 131, 132, 133, 134, 84, 33, 32, 115, 114, + 116, 117, 241, 1154, 23, 1157, 229, 1064, 1176, 1179, + 10, 53, 9, 12, 119, 118, 120, 111, 64, 109, + 108, 112, 1183, 110, 121, 122, 1184, 104, 105, 49, + 50, 48, 265, 269, 270, 271, 272, 282, 283, 277, + 278, 273, 274, 228, 258, 259, 702, 1062, 275, 276, + 1178, 45, 1194, 241, 38, 241, 241, 66, 67, 642, + 241, 68, 241, 40, 262, 241, 268, 52, 264, 263, + 1064, 260, 261, 281, 280, 266, 24, 267, 1201, 1202, + 241, 102, 90, 93, 94, 1206, 95, 97, 96, 98, + 241, 710, 1209, 1211, 91, 101, 1213, 279, 1215, 1215, + 241, 960, 85, -717, 92, 106, 107, -716, 229, 46, + 47, 335, 81, 82, 83, 11, 65, 1238, 1238, 1239, + 71, 72, 1215, 1215, 1215, 75, 1215, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, 494, 23, 491, + 490, 489, nil, 492, 10, 53, 337, 12, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, 265, 269, 270, 271, + 272, 282, 283, 277, 278, 273, 274, nil, 258, 259, + nil, nil, 275, 276, nil, 45, nil, 1092, 38, 109, + 108, 66, 67, 110, nil, 68, nil, 40, 262, nil, + 268, 52, 264, 263, nil, 260, 261, 281, 280, 266, + 24, 267, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, 1094, nil, nil, nil, 91, 101, + 241, 279, nil, nil, nil, nil, 85, nil, 92, 106, + 107, nil, nil, 46, 47, 335, 81, 82, 83, 11, + 65, nil, nil, nil, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, 1123, 23, 491, 490, 489, nil, 492, 10, 53, + 337, 12, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + 265, 269, 270, 271, 272, 282, 283, 277, 278, 273, + 274, nil, 258, 259, nil, nil, 275, 276, nil, 45, + nil, nil, 38, nil, nil, 66, 67, nil, nil, 68, + nil, 40, 262, nil, 268, 52, 264, 263, nil, 260, + 261, 281, 280, 266, 24, 267, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, 279, nil, nil, nil, nil, + 85, nil, 92, 106, 107, nil, nil, 46, 47, 335, + 81, 82, 83, 11, 65, nil, nil, nil, 71, 72, + nil, nil, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, nil, nil, nil, nil, nil, 84, 33, 32, + 115, 114, 116, 117, nil, 1123, 23, 491, 490, 489, + nil, 492, 10, 53, 337, 12, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, 265, 269, 270, 271, 272, 282, + 283, 277, 278, 273, 274, nil, 258, 259, nil, nil, + 275, 276, nil, 45, nil, nil, 38, nil, nil, 66, + 67, nil, nil, 68, nil, 40, 262, nil, 268, 52, + 264, 263, nil, 260, 261, 281, 280, 266, 24, 267, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, 279, + nil, nil, nil, nil, 85, nil, 92, 106, 107, nil, + nil, 46, 47, 335, 81, 82, 83, 11, 65, nil, + nil, nil, 71, 72, nil, nil, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 115, 114, 116, 117, nil, nil, + 23, nil, nil, nil, nil, nil, 10, 53, 337, 12, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, 265, 269, + 270, 271, 272, 282, 283, 277, 278, 273, 274, nil, + 258, 259, nil, nil, 275, 276, nil, 45, nil, nil, + 38, nil, nil, 66, 67, nil, nil, 68, nil, 40, + 262, nil, 268, 52, 264, 263, nil, 260, 261, 281, + 280, 266, 24, 267, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, 279, nil, nil, nil, nil, 85, nil, + 92, 106, 107, nil, nil, 46, 47, 335, 81, 82, + 83, 11, 65, nil, nil, nil, 71, 72, nil, nil, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 23, nil, nil, nil, nil, nil, + 10, 53, 337, 12, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, 265, 269, 270, 271, 272, 282, 283, 277, + 278, 273, 274, nil, 258, 259, nil, nil, 275, 276, + nil, 45, nil, nil, 339, nil, nil, 66, 67, nil, + nil, 68, nil, 40, 262, nil, 268, 52, 264, 263, + nil, 260, 261, 281, 280, 266, 24, 267, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, 279, nil, nil, + nil, nil, 85, nil, 92, 106, 107, nil, nil, 46, + 47, 335, 81, 82, 83, 11, 65, nil, nil, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 23, nil, + nil, nil, nil, nil, 10, 53, 337, 12, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, 265, 269, 270, 271, + 272, 282, 283, 277, 278, 273, 274, nil, 258, 259, + nil, nil, 275, 276, nil, 45, nil, nil, 339, nil, + nil, 66, 67, nil, nil, 68, nil, 40, 262, nil, + 268, 52, 264, 263, nil, 260, 261, 281, 280, 266, + 24, 267, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, 279, nil, nil, nil, nil, 85, nil, 92, 106, + 107, nil, nil, 46, 47, 335, 81, 82, 83, 11, + 65, nil, nil, nil, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 23, nil, nil, nil, nil, nil, 10, 53, + 337, 12, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + 265, 269, 270, 271, 272, 282, 283, 277, 278, 273, + 274, nil, 258, 259, nil, nil, 275, 276, nil, 45, + nil, nil, 38, nil, nil, 66, 67, nil, nil, 68, + nil, 40, 262, nil, 268, 52, 264, 263, nil, 260, + 261, 281, 280, 266, 24, 267, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, 279, nil, nil, nil, nil, + 85, nil, 92, 106, 107, nil, nil, 46, 47, 335, + 81, 82, 83, 11, 65, nil, nil, nil, 71, 72, + nil, nil, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, nil, nil, nil, nil, nil, 84, 33, 32, + 115, 114, 116, 117, nil, 494, 23, 491, 490, 489, + nil, 492, 10, 53, 337, 12, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, 494, nil, 491, 490, 489, nil, + 492, nil, 720, nil, 494, nil, 491, 490, 489, nil, + 492, 724, nil, 45, nil, nil, 38, nil, nil, 66, + 67, nil, nil, 68, 494, 40, 491, 490, 489, 52, + 492, 720, nil, nil, nil, nil, nil, nil, 24, nil, + 724, 720, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 720, nil, nil, 85, nil, 92, 106, 107, nil, + 724, 46, 47, 335, 81, 82, 83, 11, 65, nil, + nil, nil, 71, 72, nil, nil, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 115, 114, 116, 117, nil, nil, + 23, nil, nil, nil, nil, nil, 10, 53, 337, 12, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, 265, 269, + 270, 271, 272, 282, 283, 277, 278, 273, 274, nil, + -742, -742, nil, nil, 275, 276, nil, 45, nil, nil, + 38, nil, nil, 66, 67, nil, 265, 68, nil, 40, + 262, nil, 268, 52, 264, 263, nil, 260, 261, 281, + 280, 266, 24, 267, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, 262, nil, + 91, 101, 264, 263, nil, 260, 261, nil, 85, nil, + 92, 106, 107, nil, nil, 46, 47, 335, 81, 82, + 83, 11, 65, nil, nil, nil, 71, 72, nil, nil, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 23, nil, nil, nil, nil, nil, + 10, 53, 337, 12, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, 265, 269, 270, 271, 272, 282, 283, 277, + 278, 273, 274, nil, -742, -742, nil, nil, 275, 276, + nil, 45, nil, nil, 38, nil, nil, 66, 67, nil, + 265, 68, nil, 40, 262, nil, 268, 52, 264, 263, + nil, 260, 261, 281, 280, 266, 24, 267, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, 262, nil, 91, 101, 264, 263, nil, 260, + 261, nil, 85, nil, 92, 106, 107, nil, nil, 46, + 47, 335, 81, 82, 83, 11, 65, nil, nil, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 23, nil, + nil, nil, nil, nil, 10, 53, 337, 12, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, 265, 269, 270, 271, + 272, 282, 283, 277, 278, 273, 274, nil, -742, -742, + nil, nil, 275, 276, nil, 45, nil, nil, 38, nil, + nil, 66, 67, nil, nil, 68, nil, 40, 262, nil, + 268, 52, 264, 263, nil, 260, 261, 281, 280, 266, + 24, 267, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, 494, nil, 491, 490, 489, 85, 492, 92, 106, + 107, nil, nil, 46, 47, 335, 81, 82, 83, 11, + 65, nil, nil, nil, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, 720, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 23, nil, nil, nil, nil, nil, 10, 53, + 337, 12, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + 265, 269, 270, 271, 272, 282, 283, 277, 278, 273, + 274, nil, -742, -742, nil, nil, 275, 276, nil, 45, + nil, nil, 38, nil, nil, 66, 67, nil, nil, 68, + nil, 40, 262, nil, 268, 52, 264, 263, nil, 260, + 261, 281, 280, 266, 24, 267, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, 494, nil, 491, 490, 489, + 85, 492, 92, 106, 107, nil, nil, 46, 47, 335, + 81, 82, 83, 11, 65, nil, nil, nil, 71, 72, + nil, nil, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, 720, nil, nil, nil, nil, 84, 33, 32, + 115, 114, 116, 117, nil, nil, 23, nil, nil, nil, + nil, nil, 10, 53, 337, 12, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, 265, -742, -742, -742, -742, 282, + 283, nil, nil, -742, -742, nil, nil, nil, nil, nil, + 275, 276, nil, 45, nil, nil, 38, nil, nil, 66, + 67, nil, nil, 68, nil, 40, 262, nil, 268, 52, + 264, 263, nil, 260, 261, 281, 280, 266, 24, 267, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, nil, nil, nil, 85, nil, 92, 106, 107, nil, + nil, 46, 47, 335, 81, 82, 83, 11, 65, nil, + nil, nil, 71, 72, nil, nil, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 115, 114, 116, 117, nil, nil, + 23, nil, nil, nil, nil, nil, 10, 53, 337, 12, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, 265, -742, + -742, -742, -742, 282, 283, nil, nil, -742, -742, nil, + nil, nil, nil, nil, 275, 276, nil, 45, nil, nil, + 38, nil, nil, 66, 67, nil, nil, 68, nil, 40, + 262, nil, 268, 52, 264, 263, nil, 260, 261, 281, + 280, 266, 24, 267, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, nil, nil, nil, 85, nil, + 92, 106, 107, nil, nil, 46, 47, 335, 81, 82, + 83, 11, 65, nil, nil, nil, 71, 72, nil, nil, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 23, nil, nil, nil, nil, nil, + 10, 53, 337, 12, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, 265, -742, -742, -742, -742, 282, 283, nil, + nil, -742, -742, nil, nil, nil, nil, nil, 275, 276, + nil, 45, nil, nil, 38, nil, nil, 66, 67, nil, + nil, 68, nil, 40, 262, nil, 268, 52, 264, 263, + nil, 260, 261, 281, 280, 266, 24, 267, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, nil, + nil, nil, 85, nil, 92, 106, 107, nil, nil, 46, + 47, 335, 81, 82, 83, 11, 65, nil, nil, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 23, nil, + nil, nil, nil, nil, 10, 53, 337, 12, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, 265, -742, -742, -742, + -742, 282, 283, nil, nil, -742, -742, nil, nil, nil, + nil, nil, 275, 276, nil, 45, nil, nil, 38, nil, + nil, 66, 67, nil, nil, 68, nil, 40, 262, nil, + 268, 52, 264, 263, nil, 260, 261, 281, 280, 266, + 24, 267, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, nil, nil, nil, 85, nil, 92, 106, + 107, nil, nil, 46, 47, 335, 81, 82, 83, 11, + 65, nil, nil, nil, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 23, nil, nil, nil, nil, nil, 10, 53, + 337, 12, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + 265, -742, -742, -742, -742, 282, 283, nil, nil, -742, + -742, nil, nil, nil, nil, nil, 275, 276, nil, 45, + nil, nil, 38, nil, nil, 66, 67, nil, nil, 68, + nil, 40, 262, nil, 268, 52, 264, 263, nil, 260, + 261, 281, 280, 266, 24, 267, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, nil, nil, nil, + 85, nil, 92, 106, 107, nil, nil, 46, 47, 335, + 81, 82, 83, 11, 65, nil, nil, nil, 71, 72, + nil, nil, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, nil, nil, nil, nil, nil, 84, 33, 32, + 115, 114, 116, 117, nil, nil, 23, nil, nil, nil, + nil, nil, 10, 53, 337, 12, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, 265, -742, -742, -742, -742, 282, + 283, nil, nil, -742, -742, nil, nil, nil, nil, nil, + 275, 276, nil, 45, nil, nil, 38, nil, nil, 66, + 67, nil, nil, 68, nil, 40, 262, nil, 268, 52, + 264, 263, nil, 260, 261, 281, 280, 266, 24, 267, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, nil, nil, nil, 85, nil, 92, 106, 107, nil, + nil, 46, 47, 335, 81, 82, 83, 11, 65, nil, + nil, nil, 71, 72, nil, nil, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 115, 114, 116, 117, nil, nil, + 23, nil, nil, nil, nil, nil, 10, 53, 337, 12, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, 265, 269, + 270, 271, 272, 282, 283, nil, nil, 273, 274, nil, + nil, nil, nil, nil, 275, 276, nil, 45, nil, nil, + 38, nil, nil, 66, 67, nil, nil, 68, nil, 40, + 262, nil, 268, 52, 264, 263, nil, 260, 261, 281, + 280, 266, 24, 267, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, nil, nil, nil, 85, nil, + 92, 106, 107, nil, nil, 46, 47, 335, 81, 82, + 83, 11, 65, nil, nil, nil, 71, 72, nil, nil, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 23, nil, nil, nil, nil, nil, + 10, 53, 337, 12, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, 265, 269, 270, 271, 272, 282, 283, 277, + nil, 273, 274, nil, nil, nil, nil, nil, 275, 276, + nil, 45, nil, nil, 38, nil, nil, 66, 67, nil, + nil, 68, nil, 40, 262, nil, 268, 52, 264, 263, + nil, 260, 261, 281, 280, 266, 24, 267, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, nil, + nil, nil, 85, nil, 92, 106, 107, nil, nil, 46, + 47, 335, 81, 82, 83, 11, 65, nil, nil, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 23, nil, + nil, nil, nil, nil, 10, 53, 337, 12, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, 265, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 275, 276, nil, 45, nil, nil, 38, nil, + nil, 66, 67, nil, nil, 68, nil, 40, 262, nil, + 268, 52, 264, 263, nil, 260, 261, nil, nil, 266, + 24, 267, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, nil, nil, nil, 85, nil, 92, 106, + 107, nil, nil, 46, 47, 335, 81, 82, 83, 11, + 65, nil, nil, nil, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 23, nil, nil, nil, nil, nil, 10, 53, + 337, 12, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + 265, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 275, 276, nil, 45, + nil, nil, 38, nil, nil, 66, 67, nil, nil, 68, + nil, 40, 262, nil, 268, 52, 264, 263, nil, 260, + 261, nil, nil, 266, 24, 267, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, nil, nil, nil, + 85, nil, 92, 106, 107, nil, nil, 46, 47, 335, + 81, 82, 83, 11, 65, nil, nil, nil, 71, 72, + nil, nil, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, nil, nil, nil, nil, nil, 84, 33, 32, + 115, 114, 116, 117, nil, nil, 23, nil, nil, nil, + nil, nil, 10, 53, 337, 12, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, 265, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 275, 276, nil, 45, nil, nil, 38, nil, nil, 66, + 67, nil, nil, 68, nil, 40, 262, nil, 268, 52, + 264, 263, nil, 260, 261, nil, nil, nil, 24, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, nil, nil, nil, 85, nil, 92, 106, 107, nil, + nil, 46, 47, 335, 81, 82, 83, 11, 65, nil, + nil, nil, 71, 72, nil, nil, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 115, 114, 116, 117, nil, nil, + 23, nil, nil, nil, nil, nil, 10, 53, 337, 12, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, 265, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 275, 276, nil, 45, nil, nil, + 38, nil, nil, 66, 67, nil, nil, 68, nil, 40, + 262, nil, 268, 52, 264, 263, nil, 260, 261, nil, + nil, nil, 24, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, nil, nil, nil, 85, nil, + 92, 106, 107, nil, nil, 46, 47, 335, 81, 82, + 83, 11, 65, nil, nil, nil, 71, 72, nil, nil, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 23, nil, nil, nil, nil, nil, + 10, 53, 337, 12, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, 265, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 275, 276, + nil, 45, nil, nil, 38, nil, nil, 66, 67, nil, + nil, 68, nil, 40, 262, nil, nil, 52, 264, 263, + nil, 260, 261, nil, nil, nil, 24, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, nil, + nil, nil, 85, nil, 92, 106, 107, nil, nil, 46, + 47, 335, 81, 82, 83, 11, 65, nil, nil, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 23, nil, + nil, nil, nil, nil, 10, 53, 337, 12, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 38, nil, + nil, 66, 67, nil, nil, 68, nil, 40, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 24, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, nil, nil, nil, 85, nil, 92, 106, + 107, nil, nil, 46, 47, 81, 82, 83, 11, 65, + nil, nil, nil, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 115, 114, 116, 117, nil, + nil, 23, nil, nil, nil, nil, nil, 10, 53, 9, + 12, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 38, nil, nil, 66, 67, nil, nil, 68, nil, + 40, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 24, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, nil, nil, nil, + 85, nil, 92, 106, 107, -441, nil, 46, 47, nil, + nil, nil, -441, -441, -441, nil, nil, -441, -441, -441, + nil, -441, nil, nil, nil, nil, nil, nil, nil, -441, + -441, -441, -441, nil, nil, nil, nil, nil, nil, nil, + nil, -441, -441, nil, -441, -441, -441, -441, -441, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, -441, -441, -441, -441, -441, -441, -441, -441, -441, + -441, -441, -441, -441, -441, nil, nil, -441, -441, -441, + nil, nil, -441, nil, 307, -441, nil, nil, -441, -441, + nil, -441, nil, -441, nil, -441, nil, -441, -441, nil, + -441, -441, -441, -441, -441, -328, -441, -441, -441, nil, + nil, nil, -328, -328, -328, nil, nil, -328, -328, -328, + nil, -328, -441, nil, nil, -441, -441, nil, -441, -328, + -441, -328, -328, nil, nil, nil, nil, -441, nil, nil, + nil, -328, -328, nil, -328, -328, -328, -328, -328, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, -328, -328, -328, -328, -328, -328, -328, -328, -328, + -328, -328, -328, -328, -328, nil, nil, -328, -328, -328, + nil, nil, -328, nil, 316, -328, nil, nil, -328, -328, + nil, -328, nil, -328, nil, -328, nil, -328, -328, nil, + -328, -328, -328, -328, -328, nil, -328, nil, -328, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, -328, nil, nil, -328, -328, nil, -328, nil, + -328, 81, 82, 83, nil, 65, nil, -328, nil, 71, + 72, nil, nil, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, nil, nil, nil, nil, nil, 84, 33, + 32, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, 329, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, 326, nil, 323, nil, + 52, nil, nil, 330, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 327, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, 329, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, 326, nil, 323, + nil, 52, nil, nil, 330, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 327, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, 329, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, 326, nil, + 323, nil, 52, nil, nil, 330, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 327, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 356, 357, 79, 80, nil, nil, nil, nil, + nil, 84, 351, 359, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 356, 357, 79, 80, nil, nil, nil, + nil, nil, 84, 351, 359, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 356, 357, 79, 80, nil, nil, + nil, nil, nil, 84, 351, 359, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 356, 357, 79, 80, nil, + nil, nil, nil, nil, 84, 351, 359, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 356, 357, 79, 80, + nil, nil, nil, nil, nil, 84, 351, 359, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, nil, + nil, nil, 85, nil, 92, 106, 107, -315, nil, 46, + 47, nil, nil, nil, -315, -315, -315, nil, nil, -315, + -315, -315, nil, -315, nil, nil, nil, nil, nil, nil, + nil, -315, nil, -315, -315, -315, nil, nil, nil, nil, + nil, nil, nil, -315, -315, nil, -315, -315, -315, -315, + -315, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, -315, -315, -315, -315, -315, -315, -315, + -315, -315, -315, -315, -315, -315, -315, nil, nil, -315, + -315, -315, nil, nil, -315, nil, nil, -315, nil, nil, + -315, -315, nil, -315, nil, -315, nil, -315, nil, -315, + -315, nil, -315, -315, -315, -315, -315, nil, -315, nil, + -315, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, -315, nil, nil, -315, -315, -315, + -315, nil, -315, nil, -315, nil, 81, 82, 83, -315, + 65, nil, nil, nil, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 356, 357, 79, 80, nil, nil, + nil, nil, nil, 84, 351, 359, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + 329, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, 326, nil, nil, nil, 52, nil, nil, 330, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 327, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 356, 357, 79, 80, nil, + nil, nil, nil, nil, 84, 351, 359, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, 329, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, 330, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 327, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 23, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 24, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 23, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 24, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, nil, nil, nil, nil, nil, 84, 33, 32, + 115, 114, 116, 117, nil, nil, 23, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 24, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, 127, nil, + nil, nil, nil, 126, 85, nil, 92, 106, 107, nil, + nil, 46, 47, 81, 82, 83, 11, 65, nil, nil, + nil, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 115, 114, 116, 117, nil, nil, 23, + nil, nil, nil, nil, nil, 10, 53, 9, 12, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 38, + nil, nil, 66, 67, nil, nil, 68, nil, 40, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 24, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, nil, nil, 421, 85, nil, 92, + 106, 107, nil, nil, 46, 47, 81, 82, 83, nil, + 65, nil, nil, nil, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 23, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 24, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 35, 36, 79, 80, nil, + nil, nil, nil, nil, 84, 33, 32, 115, 114, 116, + 117, nil, nil, 23, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 24, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 23, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 24, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 23, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 24, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + nil, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 46, 47, 81, 82, 83, 11, 65, nil, nil, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 23, nil, + nil, nil, nil, nil, 10, 53, nil, 12, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 38, nil, + nil, 66, 67, nil, nil, 68, nil, 40, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 24, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, 438, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, 438, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 115, 114, 116, 117, nil, + nil, 23, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 24, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 23, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 24, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 35, 36, 79, 80, nil, + nil, nil, nil, nil, 84, 33, 32, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, 329, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, 326, nil, 323, nil, 52, nil, nil, + 330, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 327, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, nil, nil, nil, nil, nil, 84, 33, 32, + 115, 114, 116, 117, nil, nil, 23, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 24, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, nil, nil, nil, nil, nil, 84, 33, + 32, 115, 114, 116, 117, nil, nil, 23, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 24, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, 241, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 356, 357, 79, 80, nil, nil, nil, nil, nil, 84, + 351, 359, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 356, 357, 79, 80, nil, nil, nil, nil, nil, + 84, 351, 359, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 356, 357, 79, 80, nil, nil, nil, nil, + nil, 84, 351, 359, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 356, 357, 79, 80, nil, nil, nil, + nil, nil, 84, 351, 359, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 356, 357, 79, 80, nil, nil, + nil, nil, nil, 84, 351, 359, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 356, 357, 79, 80, nil, + nil, nil, nil, nil, 84, 351, 359, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 356, 357, 79, 80, + nil, nil, nil, nil, nil, 84, 351, 359, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 356, 357, 79, + 80, nil, nil, nil, nil, nil, 84, 351, 359, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 356, 357, + 79, 80, nil, nil, nil, nil, nil, 84, 351, 359, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 356, + 357, 79, 80, nil, nil, nil, nil, nil, 84, 351, + 359, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 356, 357, 79, 80, nil, nil, nil, nil, nil, 84, + 351, 359, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 356, 357, 79, 80, nil, nil, nil, nil, nil, + 84, 351, 359, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 356, 357, 79, 80, nil, nil, nil, nil, + nil, 84, 351, 359, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 356, 357, 79, 80, nil, nil, nil, + nil, nil, 84, 351, 359, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 356, 357, 79, 80, nil, nil, + nil, nil, nil, 84, 351, 359, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 356, 357, 79, 80, nil, + nil, nil, nil, nil, 84, 351, 359, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 356, 357, 79, 80, + nil, nil, nil, nil, nil, 84, 351, 359, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 356, 357, 79, + 80, nil, nil, nil, nil, nil, 84, 351, 359, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 356, 357, + 79, 80, nil, nil, nil, nil, nil, 84, 351, 359, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 356, + 357, 79, 80, nil, nil, nil, nil, nil, 84, 351, + 359, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 356, 357, 79, 80, nil, nil, nil, nil, nil, 84, + 351, 359, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 356, 357, 79, 80, nil, nil, nil, nil, nil, + 84, 351, 359, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 356, 357, 79, 80, nil, nil, nil, nil, + nil, 84, 351, 359, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 356, 357, 79, 80, nil, nil, nil, + nil, nil, 84, 351, 359, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 23, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 24, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 35, 36, 79, 80, nil, + nil, nil, nil, nil, 84, 33, 32, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, 329, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, 326, nil, 323, nil, 52, nil, nil, 330, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 327, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 564, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, 329, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, 326, nil, 323, nil, 52, nil, nil, + 330, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 327, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, 329, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, 326, nil, 323, nil, 52, nil, + nil, 330, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 327, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, 241, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 356, 357, + 79, 80, nil, nil, nil, nil, nil, 84, 351, 359, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 356, + 357, 79, 80, nil, nil, nil, nil, nil, 84, 351, + 359, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 356, 357, 79, 80, nil, nil, nil, nil, nil, 84, + 351, 359, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 356, 357, 79, 80, nil, nil, nil, nil, nil, + 84, 351, 359, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, nil, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 46, 47, 81, 82, 83, 11, + 65, nil, nil, nil, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 23, nil, nil, nil, nil, nil, 10, 53, + nil, 12, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 38, nil, nil, 66, 67, nil, nil, 68, + nil, 40, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 24, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 356, 357, 79, 80, nil, + nil, nil, nil, nil, 84, 351, 359, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 23, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 24, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 23, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 24, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 356, 357, + 79, 80, nil, nil, nil, nil, nil, 84, 351, 359, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, nil, nil, nil, 85, nil, 92, 106, 107, -276, + nil, 46, 47, nil, nil, nil, -276, -276, -276, nil, + nil, -276, -276, -276, nil, -276, nil, nil, nil, nil, + nil, nil, nil, -276, -276, -276, -276, nil, nil, nil, + nil, nil, nil, nil, nil, -276, -276, nil, -276, -276, + -276, -276, -276, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, -276, -276, -276, -276, -276, + -276, -276, -276, -276, -276, -276, -276, -276, -276, nil, + nil, -276, -276, -276, nil, nil, -276, nil, 307, -276, + nil, nil, -276, -276, nil, -276, nil, -276, nil, -276, + nil, -276, -276, nil, -276, -276, -276, -276, -276, nil, + -276, -276, -276, 494, nil, 491, 490, 489, 499, 492, + nil, nil, nil, nil, nil, nil, -276, nil, 502, -276, + -276, -722, -276, nil, -276, nil, nil, nil, -722, -722, + -722, -276, nil, -722, -722, -722, nil, -722, nil, nil, + 497, nil, nil, nil, nil, -722, -722, -722, -722, -722, + nil, 510, 509, nil, nil, nil, 503, -722, -722, nil, + -722, -722, -722, -722, -722, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, -722, -722, -722, + -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, + -722, nil, nil, -722, -722, -722, nil, nil, -722, nil, + nil, -722, nil, nil, -722, -722, nil, -722, nil, -722, + nil, -722, nil, -722, -722, nil, -722, -722, -722, -722, + -722, nil, -722, -722, -722, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, -722, nil, + nil, -722, -722, -722, -722, nil, -722, -723, -722, nil, + nil, nil, nil, -722, -723, -723, -723, nil, nil, -723, + -723, -723, nil, -723, nil, nil, nil, nil, nil, nil, + nil, -723, -723, -723, -723, -723, nil, nil, nil, nil, + nil, nil, nil, -723, -723, nil, -723, -723, -723, -723, + -723, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, -723, -723, -723, -723, -723, -723, -723, + -723, -723, -723, -723, -723, -723, -723, nil, nil, -723, + -723, -723, nil, nil, -723, nil, nil, -723, nil, nil, + -723, -723, nil, -723, nil, -723, nil, -723, nil, -723, + -723, nil, -723, -723, -723, -723, -723, nil, -723, -723, + -723, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, -723, nil, nil, -723, -723, -723, + -723, nil, -723, nil, -723, nil, 81, 82, 83, -723, + 65, nil, nil, nil, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 698, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 356, 357, 79, 80, nil, + nil, nil, nil, nil, 84, 351, 359, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 698, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, 329, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, 326, nil, 323, nil, 52, nil, + nil, 330, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 327, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 356, 357, + 79, 80, nil, nil, nil, nil, nil, 84, 351, 359, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 356, + 357, 79, 80, nil, nil, nil, nil, nil, 84, 351, + 359, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 356, 357, 79, 80, nil, nil, nil, nil, nil, 84, + 351, 359, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, nil, nil, nil, 85, nil, 92, 106, + 107, -276, nil, 46, 47, nil, nil, nil, -276, -276, + -276, nil, nil, -276, -276, -276, 494, -276, 491, 490, + 489, 499, 492, nil, nil, -276, -276, -276, nil, nil, + nil, 502, nil, nil, nil, nil, nil, -276, -276, nil, + -276, -276, -276, -276, -276, nil, 494, nil, 491, 490, + 489, 499, 492, 497, nil, nil, nil, nil, nil, nil, + nil, 502, 507, 506, 510, 509, nil, nil, nil, 503, + nil, 494, nil, 491, 490, 489, 499, 492, -276, nil, + nil, nil, nil, 497, 648, -276, 502, nil, nil, nil, + 307, -276, 507, 506, 510, 509, nil, nil, nil, 503, + nil, nil, nil, nil, nil, nil, nil, nil, 497, 488, + nil, nil, nil, -276, -276, nil, nil, 507, 506, 510, + 509, nil, nil, nil, 503, nil, nil, nil, -276, nil, + nil, -276, nil, 81, 82, 83, -276, 65, nil, 488, + nil, 71, 72, -276, nil, nil, 75, nil, 73, 74, + 76, 356, 357, 79, 80, nil, nil, nil, nil, nil, + 84, 351, 359, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 356, 357, 79, 80, nil, nil, nil, nil, + nil, 84, 351, 359, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, 329, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, 326, + nil, 323, nil, 52, nil, nil, 330, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 327, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 356, 357, 79, 80, nil, nil, nil, + nil, nil, 84, 351, 359, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, 329, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, 323, nil, 52, nil, nil, 330, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 327, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 356, 357, 79, 80, nil, nil, + nil, nil, nil, 84, 351, 359, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, nil, nil, nil, + 85, nil, 92, 106, 107, nil, nil, 46, 47, 81, + 82, 83, 11, 65, nil, nil, nil, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 23, nil, nil, nil, nil, + nil, 10, 53, 337, 12, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 38, nil, nil, 66, 67, + nil, nil, 68, nil, 40, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 24, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + nil, nil, 421, 85, nil, 92, 106, 107, nil, nil, + 46, 47, 81, 82, 83, nil, 65, nil, nil, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, 329, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, 326, nil, 323, + nil, 52, nil, nil, 330, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 327, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 356, 357, 79, 80, nil, nil, nil, nil, nil, + 84, 351, 359, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 356, 357, 79, 80, nil, nil, nil, nil, + nil, 84, 351, 359, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 356, 357, 79, 80, nil, nil, nil, + nil, nil, 84, 351, 359, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 356, 357, 79, 80, nil, nil, + nil, nil, nil, 84, 351, 359, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + 329, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, 326, nil, nil, nil, 52, nil, nil, 330, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 327, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 356, 357, 79, 80, nil, + nil, nil, nil, nil, 84, 351, 359, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, 329, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, 330, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 327, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 356, 357, 79, 80, + nil, nil, nil, nil, nil, 84, 351, 359, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, 326, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, 329, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, 326, nil, 323, nil, 52, nil, + nil, 330, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 327, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, nil, nil, nil, nil, nil, 84, 33, 32, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, 329, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, 326, nil, 323, nil, 52, + nil, nil, 330, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 327, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, nil, nil, nil, 85, nil, 92, 106, 107, nil, + nil, 46, 47, 81, 82, 83, 11, 65, nil, nil, + nil, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 115, 114, 116, 117, nil, nil, 23, + nil, nil, nil, nil, nil, 10, 53, nil, 12, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 38, + nil, nil, 66, 67, nil, nil, 68, nil, 40, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 24, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 356, 357, 79, 80, nil, nil, nil, nil, + nil, 84, 351, 359, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, 832, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + 329, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, 326, nil, 323, nil, 52, nil, nil, 330, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 327, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, nil, nil, nil, + 85, nil, 92, 106, 107, nil, nil, 46, 47, 81, + 82, 83, 11, 65, nil, nil, nil, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 23, nil, nil, nil, nil, + nil, 10, 53, nil, 12, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 38, nil, nil, 66, 67, + nil, nil, 68, nil, 40, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 24, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 356, 357, + 79, 80, nil, nil, nil, nil, nil, 84, 351, 359, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 356, + 357, 79, 80, nil, nil, nil, nil, nil, 84, 351, + 359, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, 329, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, 326, nil, 323, nil, + 52, nil, nil, 330, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 327, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 356, 357, 79, 80, nil, nil, nil, nil, nil, 84, + 351, 359, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, 329, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, 323, + nil, 52, nil, nil, 330, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 327, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 356, 357, 79, 80, nil, + nil, nil, nil, nil, 84, 351, 359, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, 438, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 356, 357, 79, 80, + nil, nil, nil, nil, nil, 84, 351, 359, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 356, 357, 79, + 80, nil, nil, nil, nil, nil, 84, 351, 359, 115, + 114, 116, 117, nil, nil, 889, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 356, 357, + 79, 80, nil, nil, nil, nil, nil, 84, 351, 359, + 115, 114, 116, 117, nil, nil, 889, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 356, + 357, 79, 80, nil, nil, nil, nil, nil, 84, 351, + 359, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, 329, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, 326, nil, 323, nil, + 52, nil, nil, 330, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 327, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 564, nil, 75, nil, 73, 74, 76, + 356, 357, 79, 80, nil, nil, nil, nil, nil, 84, + 351, 359, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 115, 114, 116, 117, nil, nil, 23, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 24, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 115, 114, 116, 117, nil, nil, + 23, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 24, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 356, 357, 79, 80, nil, nil, nil, + nil, nil, 84, 351, 359, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 356, 357, 79, 80, nil, + nil, nil, nil, nil, 84, 351, 359, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 698, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 356, 357, 79, + 80, nil, nil, nil, nil, nil, 84, 351, 359, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 356, 357, + 79, 80, nil, nil, nil, nil, nil, 84, 351, 359, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 356, + 357, 79, 80, nil, nil, nil, nil, nil, 84, 351, + 359, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 356, 357, 79, 80, nil, nil, nil, nil, nil, 84, + 351, 359, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 356, 357, 79, 80, nil, nil, nil, nil, nil, + 84, 351, 359, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 356, 357, 79, 80, nil, nil, nil, nil, + nil, 84, 351, 359, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 115, 114, 116, 117, nil, + nil, 23, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 24, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 356, 357, 79, 80, nil, nil, + nil, nil, nil, 84, 351, 359, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, 326, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 356, 357, 79, 80, nil, + nil, nil, nil, nil, 84, 351, 359, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, 329, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, 323, nil, 52, nil, nil, 330, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 327, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 356, 357, 79, 80, + nil, nil, nil, nil, nil, 84, 351, 359, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 356, 357, 79, + 80, nil, nil, nil, nil, nil, 84, 351, 359, 115, + 114, 116, 117, nil, nil, 889, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, nil, nil, nil, nil, nil, 84, 33, 32, + 115, 114, 116, 117, nil, nil, 23, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 24, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, nil, nil, nil, nil, nil, 84, 33, + 32, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, 329, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, 326, nil, 323, nil, + 52, nil, nil, 330, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 327, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 23, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 24, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 115, 114, 116, 117, nil, nil, 23, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 24, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 356, 357, 79, 80, nil, nil, nil, nil, + nil, 84, 351, 359, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 352, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, nil, nil, 360, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 348, nil, nil, + 344, nil, nil, 66, 67, nil, nil, 68, nil, 343, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 356, 357, 79, 80, nil, nil, nil, + nil, nil, 84, 351, 359, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 352, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, nil, nil, 360, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 348, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, 494, nil, 491, 490, 489, 499, 492, nil, nil, + nil, nil, nil, nil, nil, nil, 502, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 362, nil, 497, 85, + nil, 92, 106, 107, 81, 82, 83, nil, 65, 510, + 509, nil, 71, 72, 503, nil, nil, 75, nil, 73, + 74, 76, 356, 357, 79, 80, nil, nil, nil, nil, + nil, 84, 351, 359, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 352, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, nil, nil, 360, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 396, nil, nil, + 38, nil, nil, 66, 67, nil, nil, 68, nil, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 356, 357, 79, 80, nil, nil, nil, + nil, nil, 84, 351, 359, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 352, nil, + nil, 119, 118, 120, 401, 64, 109, 108, 402, nil, + 110, 121, 122, nil, 104, 105, nil, nil, 360, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 408, nil, nil, 403, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 356, 357, 79, 80, nil, nil, + nil, nil, nil, 84, 351, 359, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 352, + nil, nil, 119, 118, 120, 401, 64, 109, 108, 402, + nil, 110, 121, 122, nil, 104, 105, nil, nil, 360, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 403, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, nil, nil, nil, + 75, nil, 73, 74, 76, 356, 357, 79, 80, nil, + nil, nil, nil, nil, 84, 351, 359, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 352, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, nil, nil, + 360, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 348, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, 494, nil, 491, 490, 489, 499, 492, + nil, nil, nil, nil, nil, nil, nil, nil, 502, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 592, nil, + 497, 85, nil, 92, 106, 107, 81, 82, 83, nil, + 65, 510, 509, nil, 71, 72, 503, nil, nil, 75, + nil, 73, 74, 76, 356, 357, 79, 80, nil, nil, + nil, nil, nil, 84, 351, 359, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 352, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, nil, nil, 360, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 348, + nil, nil, 344, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, nil, nil, nil, + 75, nil, 73, 74, 76, 356, 357, 79, 80, nil, + nil, nil, nil, nil, 84, 351, 359, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 352, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, nil, nil, + 360, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 348, nil, nil, 344, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, nil, nil, + nil, 75, nil, 73, 74, 76, 356, 357, 79, 80, + nil, nil, nil, nil, nil, 84, 351, 359, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 352, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, nil, + nil, 360, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 348, nil, nil, 344, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 356, 357, 79, + 80, nil, nil, nil, nil, nil, 84, 351, 359, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 352, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + nil, nil, 360, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 348, nil, nil, 344, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + nil, nil, nil, 75, nil, 73, 74, 76, 356, 357, + 79, 80, nil, nil, nil, nil, nil, 84, 351, 359, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 352, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, nil, nil, 360, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 348, nil, nil, 344, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, nil, nil, nil, 75, nil, 73, 74, 76, 356, + 357, 79, 80, nil, nil, nil, nil, nil, 84, 351, + 359, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 352, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, nil, nil, 360, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1054, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 356, 357, 79, 80, nil, nil, nil, nil, nil, 84, + 351, 359, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 352, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, nil, nil, 360, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 1112, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 356, 357, 79, 80, nil, nil, nil, nil, nil, + 84, 351, 359, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 352, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, nil, nil, 360, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1112, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, nil, nil, nil, 85, nil, 92, + 106, 107, 186, 197, 187, 210, 183, 203, 193, 192, + 213, 214, 208, 191, 190, 185, 211, 215, 216, 195, + 184, 198, 202, 204, 196, 189, nil, nil, nil, 205, + 212, 207, 206, 199, 209, 194, 182, 201, 200, nil, + nil, nil, nil, nil, 181, 188, 179, 180, 176, 177, + 178, 139, 141, 138, nil, 140, nil, nil, nil, nil, + nil, nil, nil, 170, 171, nil, 167, 149, 150, 151, + 158, 155, 157, nil, nil, 152, 153, nil, nil, nil, + 172, 173, 159, 160, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 164, 163, nil, + 148, 169, 166, 165, 174, 161, 162, 156, 154, 146, + 168, 147, nil, nil, 175, 102, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 101, + 186, 197, 187, 210, 183, 203, 193, 192, 213, 214, + 208, 191, 190, 185, 211, 215, 216, 195, 184, 198, + 202, 204, 196, 189, nil, nil, nil, 205, 212, 207, + 206, 199, 209, 194, 182, 201, 200, nil, nil, nil, + nil, nil, 181, 188, 179, 180, 176, 177, 178, 139, + 141, nil, nil, 140, nil, nil, nil, nil, nil, nil, + nil, 170, 171, nil, 167, 149, 150, 151, 158, 155, + 157, nil, nil, 152, 153, nil, nil, nil, 172, 173, + 159, 160, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 164, 163, nil, 148, 169, + 166, 165, 174, 161, 162, 156, 154, 146, 168, 147, + nil, nil, 175, 102, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 101, 186, 197, + 187, 210, 183, 203, 193, 192, 213, 214, 208, 191, + 190, 185, 211, 215, 216, 195, 184, 198, 202, 204, + 196, 189, nil, nil, nil, 205, 212, 207, 206, 199, + 209, 194, 182, 201, 200, nil, nil, nil, nil, nil, + 181, 188, 179, 180, 176, 177, 178, 139, 141, nil, + nil, 140, nil, nil, nil, nil, nil, nil, nil, 170, + 171, nil, 167, 149, 150, 151, 158, 155, 157, nil, + nil, 152, 153, nil, nil, nil, 172, 173, 159, 160, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 164, 163, nil, 148, 169, 166, 165, + 174, 161, 162, 156, 154, 146, 168, 147, nil, nil, + 175, 102, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 101, 186, 197, 187, 210, + 183, 203, 193, 192, 213, 214, 208, 191, 190, 185, + 211, 215, 216, 195, 184, 198, 202, 204, 196, 189, + nil, nil, nil, 205, 212, 207, 206, 199, 209, 194, + 182, 201, 200, nil, nil, nil, nil, nil, 181, 188, + 179, 180, 176, 177, 178, 139, 141, nil, nil, 140, + nil, nil, nil, nil, nil, nil, nil, 170, 171, nil, + 167, 149, 150, 151, 158, 155, 157, nil, nil, 152, + 153, nil, nil, nil, 172, 173, 159, 160, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 164, 163, nil, 148, 169, 166, 165, 174, 161, + 162, 156, 154, 146, 168, 147, nil, nil, 175, 102, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 101, 186, 197, 187, 210, 183, 203, + 193, 192, 213, 214, 208, 191, 190, 185, 211, 215, + 216, 195, 184, 198, 202, 204, 196, 189, nil, nil, + nil, 205, 212, 207, 295, 294, 296, 293, 182, 201, + 200, nil, nil, nil, nil, nil, 181, 188, 179, 180, + 290, 291, 292, 288, 141, 109, 108, 289, nil, 110, + nil, nil, nil, nil, nil, 170, 171, nil, 167, 149, + 150, 151, 158, 155, 157, nil, nil, 152, 153, nil, + nil, nil, 172, 173, 159, 160, nil, nil, nil, nil, + nil, 300, nil, nil, nil, nil, nil, nil, nil, 164, + 163, nil, 148, 169, 166, 165, 174, 161, 162, 156, + 154, 146, 168, 147, nil, nil, 175, 186, 197, 187, + 210, 183, 203, 193, 192, 213, 214, 208, 191, 190, + 185, 211, 215, 216, 195, 184, 198, 202, 204, 196, + 189, nil, nil, nil, 205, 212, 207, 206, 199, 209, + 194, 182, 201, 200, nil, nil, nil, nil, nil, 181, + 188, 179, 180, 176, 177, 178, 139, 141, nil, nil, + 140, nil, nil, nil, nil, nil, nil, nil, 170, 171, + nil, 167, 149, 150, 151, 158, 155, 157, nil, nil, + 152, 153, nil, nil, nil, 172, 173, 159, 160, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 164, 163, nil, 148, 169, 166, 165, 174, + 161, 162, 156, 154, 146, 168, 147, nil, nil, 175, + 115, 114, 116, 117, nil, nil, 494, nil, 491, 490, + 489, 499, 492, nil, nil, nil, 119, 118, 120, 1009, + nil, 502, nil, 1012, 989, nil, nil, nil, nil, 104, + 105, nil, nil, 360, 502, nil, nil, nil, nil, nil, + nil, nil, nil, 497, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 1011, 510, 509, 982, nil, nil, 503, + 980, nil, nil, 981, nil, 984, nil, nil, nil, nil, + nil, nil, 503, nil, nil, nil, nil, nil, nil, 1010, + nil, nil, nil, 102, 990, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, 115, 114, + 116, 117, nil, nil, 85, nil, 92, 106, 107, nil, + nil, 997, 998, nil, 119, 118, 120, 1009, nil, nil, + nil, 1012, 989, nil, nil, nil, nil, 104, 105, nil, + nil, 360, 502, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 1011, nil, nil, 982, nil, nil, nil, 980, nil, + nil, 981, nil, 984, nil, nil, nil, nil, nil, nil, + 503, nil, nil, nil, nil, nil, nil, 1010, nil, nil, + nil, 102, 990, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, 115, 114, 116, 117, + nil, nil, 85, nil, 92, 106, 107, nil, nil, 997, + 998, nil, 119, 118, 120, 1009, nil, nil, nil, 1012, + nil, nil, nil, nil, nil, 104, 105, nil, nil, 360, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 1011, + nil, nil, 982, nil, nil, nil, 980, nil, nil, 981, + nil, 984, nil, nil, nil, nil, nil, nil, 494, nil, + 491, 490, 489, 499, 492, 1010, nil, nil, nil, 102, + 90, 93, 94, 502, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, 241, 115, 114, 116, 117, nil, + 85, nil, 92, 106, 107, 497, nil, 997, 998, nil, + nil, 119, 118, 120, 1009, nil, 510, 509, 1012, nil, + nil, 503, nil, nil, 104, 105, nil, nil, 360, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 1011, nil, + nil, 982, nil, nil, nil, 980, nil, nil, 981, nil, + nil, 488, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1010, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, 115, 114, 116, 117, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 997, 998, nil, 119, + 118, 120, 1009, nil, nil, 494, 1012, 491, 490, 489, + 499, 492, 104, 105, nil, nil, 360, nil, nil, nil, + 502, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1011, nil, nil, 982, + nil, nil, 497, 980, nil, nil, 981, nil, 984, nil, + nil, 507, 506, 510, 509, nil, nil, nil, 503, nil, + nil, nil, 1010, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, 115, 114, 116, 117, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 997, 998, nil, 119, 118, 120, + 1009, nil, nil, 494, 1012, 491, 490, 489, 499, 492, + 104, 105, nil, nil, 360, nil, nil, nil, 502, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1011, nil, nil, 982, nil, nil, + 497, 980, nil, nil, 981, nil, nil, nil, nil, 507, + 506, 510, 509, nil, nil, nil, 503, nil, nil, nil, + 1010, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, 115, + 114, 116, 117, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 997, 998, nil, 119, 118, 120, 1009, nil, + nil, nil, 1012, 989, nil, nil, nil, nil, 104, 105, + nil, nil, 360, 502, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1011, nil, nil, 982, nil, nil, nil, 980, + nil, nil, 981, nil, 984, nil, nil, nil, nil, nil, + nil, 503, nil, nil, nil, nil, nil, nil, 1010, nil, + nil, nil, 102, 990, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, 115, 114, 116, + 117, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 997, 998, nil, 119, 118, 120, 1009, nil, nil, nil, + 1012, 989, nil, nil, nil, nil, 104, 105, nil, nil, + 360, 502, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1011, nil, nil, 982, nil, nil, nil, 980, nil, nil, + 981, nil, 984, nil, nil, nil, nil, nil, nil, 503, + nil, nil, nil, nil, nil, nil, 1010, nil, nil, nil, + 102, 990, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, 115, 114, 116, 117, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 997, 998, + nil, 119, 118, 120, 1009, nil, nil, 494, 1012, 491, + 490, 489, 499, 492, 104, 105, nil, nil, 360, nil, + nil, nil, 502, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 1011, nil, + nil, 982, nil, nil, 497, 980, nil, nil, 981, nil, + 984, nil, nil, nil, nil, 510, 509, nil, nil, nil, + 503, nil, nil, nil, 1010, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, 115, 114, 116, 117, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 997, 998, nil, 119, + 118, 120, 1009, nil, nil, nil, 1012, nil, nil, nil, + nil, nil, 104, 105, nil, nil, 360, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1011, nil, nil, 982, + nil, nil, nil, 980, nil, nil, 981, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1010, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, 115, 114, 116, 117, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 997, 998, nil, 119, 118, 120, + 1009, nil, nil, nil, 1012, nil, nil, nil, nil, nil, + 104, 105, nil, nil, 360, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1011, nil, nil, 982, nil, nil, + nil, 980, nil, nil, 981, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1010, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, 115, + 114, 116, 117, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 997, 998, nil, 119, 118, 120, 1009, nil, + nil, nil, 1012, 989, nil, nil, nil, nil, 104, 105, + nil, nil, 360, 502, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1011, nil, nil, 982, nil, nil, nil, 980, + nil, nil, 981, nil, 984, nil, nil, nil, nil, nil, + nil, 503, nil, nil, nil, nil, nil, nil, 1010, nil, + nil, nil, 102, 990, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, 115, 114, 116, + 117, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 997, 998, nil, 119, 118, 120, 1009, nil, nil, nil, + 1012, nil, nil, nil, nil, nil, 104, 105, nil, nil, + 360, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1011, nil, nil, 982, nil, nil, nil, 980, nil, nil, + 981, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1010, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, 115, 114, 116, 117, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 997, 998, + nil, 119, 118, 120, 1009, nil, nil, nil, 1012, nil, + nil, nil, nil, nil, 104, 105, nil, nil, 360, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 1011, nil, + nil, 982, nil, nil, nil, 980, nil, nil, 981, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1010, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, 115, 114, 116, 117, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 997, 998, nil, 119, + 118, 120, 1009, nil, nil, nil, 1012, nil, nil, nil, + nil, nil, 104, 105, nil, nil, 360, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1011, nil, nil, 982, + nil, nil, nil, 980, nil, nil, 981, nil, 984, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1010, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, 115, 114, 116, 117, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 997, 998, nil, 119, 118, 120, + 1009, nil, nil, nil, 1012, nil, nil, nil, nil, nil, + 104, 105, nil, nil, 360, nil, nil, nil, nil, nil, + nil, nil, 115, 114, 116, 117, nil, nil, nil, nil, + nil, nil, nil, nil, 1011, nil, nil, 982, 119, 118, + 120, 980, nil, nil, 981, nil, nil, nil, nil, nil, + nil, 104, 105, nil, nil, 360, nil, nil, nil, nil, + 1010, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, nil, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 997, 998, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + 115, 114, 116, 117, nil, nil, 85, nil, 92, 106, + 107, nil, nil, nil, nil, nil, 119, 118, 120, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 104, + 105, nil, nil, 360, 115, 114, 116, 117, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 119, 118, 120, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 104, 105, nil, nil, 360, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, nil, nil, nil, 85, nil, 92, 106, 107, nil, + nil, nil, nil, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, 115, 114, 116, 117, nil, nil, 85, nil, + 92, 106, 107, nil, nil, nil, nil, nil, 119, 118, + 120, 494, nil, 491, 490, 489, 499, 492, nil, nil, + nil, 104, 105, nil, nil, 360, 502, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 497, nil, + nil, nil, nil, nil, nil, nil, nil, 507, 506, 510, + 509, nil, nil, nil, 503, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, nil, nil, nil, 85, nil, 92, 106, + 107, nil, nil, 494, 488, 491, 490, 489, 499, 492, + nil, 494, nil, 491, 490, 489, 499, 492, 502, nil, + nil, nil, nil, nil, nil, nil, 502, nil, 494, nil, + 491, 490, 489, 499, 492, nil, nil, nil, nil, nil, + 497, nil, nil, 502, nil, nil, nil, nil, 497, 507, + 506, 510, 509, nil, nil, nil, 503, 507, 506, 510, + 509, nil, nil, nil, 503, 497, nil, nil, nil, nil, + nil, nil, nil, nil, 507, 506, 510, 509, nil, nil, + 494, 503, 491, 490, 489, 499, 492, 494, nil, 491, + 490, 489, 499, 492, nil, 502, 488, nil, nil, nil, + nil, nil, 502, nil, 488, 494, nil, 491, 490, 489, + 499, 492, nil, nil, nil, nil, nil, 497, nil, nil, + 502, 488, nil, nil, 497, nil, nil, nil, 510, 509, + nil, nil, nil, 503, nil, 510, 509, nil, nil, nil, + 503, 494, 497, 491, 490, 489, 499, 492, nil, nil, + nil, nil, nil, 510, 509, nil, 502, nil, 503, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 488, nil, nil, nil, nil, 497, nil, + 488, nil, nil, nil, nil, nil, nil, nil, nil, 510, + 509, 459, 463, nil, 503, 460, nil, nil, 488, nil, + nil, nil, nil, 170, 171, nil, 167, 149, 150, 151, + 158, 155, 157, nil, nil, 152, 153, nil, nil, nil, + 172, 173, 159, 160, nil, nil, nil, nil, nil, 307, + nil, nil, nil, nil, 488, nil, nil, 164, 163, nil, + 148, 169, 166, 165, 174, 161, 162, 156, 154, 146, + 168, 147, 467, 471, 175, nil, 466, nil, nil, nil, + nil, nil, nil, nil, 170, 171, nil, 167, 149, 150, + 151, 158, 155, 157, nil, nil, 152, 153, nil, nil, + nil, 172, 173, 159, 160, nil, nil, nil, nil, nil, + 307, nil, nil, nil, nil, nil, nil, nil, 164, 163, + nil, 148, 169, 166, 165, 174, 161, 162, 156, 154, + 146, 168, 147, 560, 463, 175, nil, 561, nil, nil, + nil, nil, nil, nil, nil, 170, 171, nil, 167, 149, + 150, 151, 158, 155, 157, nil, nil, 152, 153, nil, + nil, nil, 172, 173, 159, 160, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 164, + 163, nil, 148, 169, 166, 165, 174, 161, 162, 156, + 154, 146, 168, 147, 735, 463, 175, nil, 736, nil, + nil, nil, nil, nil, nil, nil, 170, 171, nil, 167, + 149, 150, 151, 158, 155, 157, nil, nil, 152, 153, + nil, nil, nil, 172, 173, 159, 160, nil, nil, nil, + nil, nil, 307, nil, nil, nil, nil, nil, nil, nil, + 164, 163, nil, 148, 169, 166, 165, 174, 161, 162, + 156, 154, 146, 168, 147, 738, 471, 175, nil, 737, + nil, nil, nil, nil, nil, nil, nil, 170, 171, nil, + 167, 149, 150, 151, 158, 155, 157, nil, nil, 152, + 153, nil, nil, nil, 172, 173, 159, 160, nil, nil, + nil, nil, nil, 307, nil, nil, nil, nil, nil, nil, + nil, 164, 163, nil, 148, 169, 166, 165, 174, 161, + 162, 156, 154, 146, 168, 147, 773, 463, 175, nil, + 774, nil, nil, nil, nil, nil, nil, nil, 170, 171, + nil, 167, 149, 150, 151, 158, 155, 157, nil, nil, + 152, 153, nil, nil, nil, 172, 173, 159, 160, nil, + nil, nil, nil, nil, 307, nil, nil, nil, nil, nil, + nil, nil, 164, 163, nil, 148, 169, 166, 165, 174, + 161, 162, 156, 154, 146, 168, 147, 776, 471, 175, + nil, 777, nil, nil, nil, nil, nil, nil, nil, 170, + 171, nil, 167, 149, 150, 151, 158, 155, 157, nil, + nil, 152, 153, nil, nil, nil, 172, 173, 159, 160, + nil, nil, nil, nil, nil, 307, nil, nil, nil, nil, + nil, nil, nil, 164, 163, nil, 148, 169, 166, 165, + 174, 161, 162, 156, 154, 146, 168, 147, 735, 463, + 175, nil, 736, nil, nil, nil, nil, nil, nil, nil, + 170, 171, nil, 167, 149, 150, 151, 158, 155, 157, + nil, nil, 152, 153, nil, nil, nil, 172, 173, 159, + 160, nil, nil, nil, nil, nil, 307, nil, nil, nil, + nil, nil, nil, nil, 164, 163, nil, 148, 169, 166, + 165, 174, 161, 162, 156, 154, 146, 168, 147, 738, + 471, 175, nil, 782, nil, nil, nil, nil, nil, nil, + nil, 170, 171, nil, 167, 149, 150, 151, 158, 155, + 157, nil, nil, 152, 153, nil, nil, nil, 172, 173, + 159, 160, nil, nil, nil, nil, nil, 307, nil, nil, + nil, nil, nil, nil, nil, 164, 163, nil, 148, 169, + 166, 165, 174, 161, 162, 156, 154, 146, 168, 147, + 803, 463, 175, nil, 804, nil, nil, nil, nil, nil, + nil, nil, 170, 171, nil, 167, 149, 150, 151, 158, + 155, 157, nil, nil, 152, 153, nil, nil, nil, 172, + 173, 159, 160, nil, nil, nil, nil, nil, 307, nil, + nil, nil, nil, nil, nil, nil, 164, 163, nil, 148, + 169, 166, 165, 174, 161, 162, 156, 154, 146, 168, + 147, 805, 471, 175, nil, 806, nil, nil, nil, nil, + nil, nil, nil, 170, 171, nil, 167, 149, 150, 151, + 158, 155, 157, nil, nil, 152, 153, nil, nil, nil, + 172, 173, 159, 160, nil, nil, nil, nil, nil, 307, + nil, nil, nil, nil, nil, nil, nil, 164, 163, nil, + 148, 169, 166, 165, 174, 161, 162, 156, 154, 146, + 168, 147, 808, 471, 175, nil, 809, nil, nil, nil, + nil, nil, nil, nil, 170, 171, nil, 167, 149, 150, + 151, 158, 155, 157, nil, nil, 152, 153, nil, nil, + nil, 172, 173, 159, 160, nil, nil, nil, nil, nil, + 307, nil, nil, nil, nil, nil, nil, nil, 164, 163, + nil, 148, 169, 166, 165, 174, 161, 162, 156, 154, + 146, 168, 147, 560, 463, 175, nil, 561, nil, nil, + nil, nil, nil, nil, nil, 170, 171, nil, 167, 149, + 150, 151, 158, 155, 157, nil, nil, 152, 153, nil, + nil, nil, 172, 173, 159, 160, nil, nil, nil, nil, + nil, 307, nil, nil, nil, nil, nil, nil, nil, 164, + 163, nil, 148, 169, 166, 165, 174, 161, 162, 156, + 154, 146, 168, 147, 834, 463, 175, nil, 835, nil, + nil, nil, nil, nil, nil, nil, 170, 171, nil, 167, + 149, 150, 151, 158, 155, 157, nil, nil, 152, 153, + nil, nil, nil, 172, 173, 159, 160, nil, nil, nil, + nil, nil, 307, nil, nil, nil, nil, nil, nil, nil, + 164, 163, nil, 148, 169, 166, 165, 174, 161, 162, + 156, 154, 146, 168, 147, 837, 471, 175, nil, 836, + nil, nil, nil, nil, nil, nil, nil, 170, 171, nil, + 167, 149, 150, 151, 158, 155, 157, nil, nil, 152, + 153, nil, nil, nil, 172, 173, 159, 160, nil, nil, + nil, nil, nil, 307, nil, nil, nil, nil, nil, nil, + nil, 164, 163, nil, 148, 169, 166, 165, 174, 161, + 162, 156, 154, 146, 168, 147, 1189, 463, 175, nil, + 1190, nil, nil, nil, nil, nil, nil, nil, 170, 171, + nil, 167, 149, 150, 151, 158, 155, 157, nil, nil, + 152, 153, nil, nil, nil, 172, 173, 159, 160, nil, + nil, nil, nil, nil, 307, nil, nil, nil, nil, nil, + nil, nil, 164, 163, nil, 148, 169, 166, 165, 174, + 161, 162, 156, 154, 146, 168, 147, 1191, 471, 175, + nil, 1192, nil, nil, nil, nil, nil, nil, nil, 170, + 171, nil, 167, 149, 150, 151, 158, 155, 157, nil, + nil, 152, 153, nil, nil, nil, 172, 173, 159, 160, + nil, nil, nil, nil, nil, 307, nil, nil, nil, nil, + nil, nil, nil, 164, 163, nil, 148, 169, 166, 165, + 174, 161, 162, 156, 154, 146, 168, 147, 1219, 471, + 175, nil, 1218, nil, nil, nil, nil, nil, nil, nil, + 170, 171, nil, 167, 149, 150, 151, 158, 155, 157, + nil, nil, 152, 153, nil, nil, nil, 172, 173, 159, + 160, nil, nil, nil, nil, nil, 307, nil, nil, nil, + nil, nil, nil, nil, 164, 163, nil, 148, 169, 166, + 165, 174, 161, 162, 156, 154, 146, 168, 147, nil, + nil, 175 ] + +racc_action_check = [ + 111, 244, 69, 518, 518, 751, 393, 111, 111, 111, + 970, 385, 111, 111, 111, 18, 111, 31, 1158, 417, + 5, 23, 18, 386, 111, 5, 111, 111, 111, 557, + 557, 18, 478, 418, 394, 397, 111, 111, 801, 111, + 111, 111, 111, 111, 950, 1034, 1051, 1052, 1055, 1244, + 478, 635, 1, 333, 1129, 1071, 970, 245, 333, 1244, + 244, 1158, 23, 247, 803, 804, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 18, 31, 111, 111, 111, 417, 111, 111, 626, 69, + 111, 816, 751, 111, 111, 922, 111, 518, 111, 418, + 111, 1071, 111, 111, 31, 111, 111, 111, 111, 111, + 1181, 111, 112, 111, 1189, 393, 245, 911, 911, 112, + 112, 112, 247, 557, 112, 112, 112, 111, 112, 385, + 111, 111, 111, 111, 385, 111, 112, 111, 112, 112, + 112, 386, 111, 394, 397, 111, 386, 19, 112, 112, + 1190, 112, 112, 112, 112, 112, 801, 1191, 1225, 801, + 635, 801, 950, 1034, 1051, 1052, 1055, 950, 1034, 1051, + 1052, 1055, 1129, 803, 804, 805, 1066, 1129, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 626, 1192, 112, 112, 112, 626, 112, 112, + 816, 806, 112, 19, 922, 112, 112, 1038, 112, 1038, + 112, 911, 112, 20, 112, 112, 1066, 112, 112, 112, + 112, 112, 466, 112, 21, 112, 444, 524, 1181, 466, + 466, 466, 1189, 1181, 1191, 466, 466, 1189, 466, 112, + 805, 773, 112, 112, 112, 112, 466, 112, 29, 112, + 353, 1067, 629, 412, 112, 29, 3, 112, 466, 466, + 629, 466, 466, 466, 466, 466, 806, 768, 1190, 20, + 1192, 21, 774, 1190, 776, 1191, 1225, 580, 909, 768, + 1191, 1225, 9, 21, 805, 444, 524, 1067, 466, 466, + 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, + 466, 466, 12, 252, 466, 466, 466, 773, 466, 466, + 806, 1192, 466, 29, 353, 466, 1192, 412, 412, 412, + 466, 14, 466, 735, 466, 466, 1086, 466, 466, 466, + 466, 466, 253, 466, 466, 466, 15, 353, 774, 776, + 776, 580, 580, 580, 909, 17, 1078, 773, 698, 466, + 773, 88, 466, 466, 413, 466, 1078, 466, 580, 252, + 390, 467, 773, 88, 466, 390, 736, 466, 467, 467, + 467, 48, 48, 88, 467, 467, 27, 467, 774, 981, + 776, 774, 735, 776, 909, 467, 467, 909, 253, 698, + 1086, 1086, 1086, 774, 1078, 776, 981, 467, 467, 909, + 467, 467, 467, 467, 467, 377, 1078, 1086, 377, 234, + 54, 234, 234, 234, 234, 234, 287, 54, 413, 413, + 413, 360, 360, 287, 234, 736, 54, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, + 467, 889, 43, 467, 467, 467, 234, 467, 467, 48, + 48, 467, 1204, 42, 467, 234, 234, 234, 234, 467, + 660, 467, 234, 467, 467, 414, 467, 467, 467, 467, + 467, 737, 467, 467, 467, 54, 834, 835, 737, 737, + 737, 287, 889, 737, 737, 737, 288, 737, 467, 43, + 45, 467, 467, 288, 467, 737, 467, 737, 737, 360, + 360, 43, 234, 467, 401, 53, 467, 737, 737, 991, + 737, 737, 737, 737, 737, 512, 1204, 1204, 16, 16, + 512, 662, 888, 415, 660, 660, 217, 991, 416, 414, + 414, 414, 230, 1204, 660, 834, 835, 737, 737, 737, + 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, + 737, 288, 44, 737, 737, 737, 401, 737, 737, 378, + 232, 737, 378, 401, 737, 737, 419, 737, 401, 737, + 937, 737, 401, 737, 737, 236, 737, 737, 737, 737, + 737, 888, 737, 737, 737, 662, 662, 415, 415, 415, + 289, 401, 416, 416, 416, 662, 243, 289, 737, 44, + 290, 737, 737, 243, 737, 246, 737, 290, 291, 364, + 738, 44, 243, 737, 248, 291, 737, 738, 738, 738, + 645, 401, 738, 738, 738, 645, 738, 51, 51, 937, + 419, 419, 419, 292, 738, 738, 738, 738, 738, 979, + 292, 403, 384, 384, 979, 403, 738, 738, 979, 738, + 738, 738, 738, 738, 1011, 289, 364, 926, 1011, 293, + 294, 243, 926, 51, 51, 290, 293, 294, 364, 381, + 249, 782, 381, 291, 782, 255, 738, 738, 738, 738, + 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, + 306, 1084, 738, 738, 738, 320, 738, 738, 292, 459, + 738, 1084, 295, 738, 738, 321, 738, 296, 738, 295, + 738, 324, 738, 738, 296, 738, 738, 738, 738, 738, + 836, 738, 738, 738, 293, 294, 138, 836, 836, 836, + 782, 138, 138, 836, 836, 337, 836, 738, 535, 1084, + 738, 738, 738, 738, 836, 738, 459, 738, 710, 710, + 1070, 1084, 738, 402, 1070, 738, 836, 836, 459, 836, + 836, 836, 836, 836, 338, 788, 340, 295, 788, 345, + 535, 707, 296, 341, 535, 535, 345, 460, 653, 653, + 342, 707, 653, 653, 653, 345, 836, 836, 836, 836, + 836, 836, 836, 836, 836, 836, 836, 836, 836, 836, + 348, 682, 836, 836, 836, 402, 836, 836, 1121, 351, + 836, 1121, 402, 836, 707, 707, 352, 402, 836, 707, + 836, 402, 836, 836, 460, 836, 836, 836, 836, 836, + 354, 836, 836, 836, 345, 355, 460, 789, 789, 903, + 402, 903, 903, 903, 903, 903, 359, 836, 682, 361, + 836, 836, 808, 836, 903, 836, 368, 536, 370, 837, + 682, 373, 836, 994, 994, 836, 837, 837, 837, 1098, + 402, 379, 837, 837, 380, 837, 903, 1180, 1180, 1098, + 1182, 1182, 382, 837, 837, 903, 903, 903, 903, 536, + 346, 391, 903, 536, 536, 837, 837, 346, 837, 837, + 837, 837, 837, 392, 808, 396, 346, 398, 347, 407, + 427, 808, 1098, 1098, 433, 347, 808, 1098, 903, 435, + 808, 436, 437, 441, 347, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 808, + 445, 837, 837, 837, 455, 837, 837, 349, 457, 837, + 458, 468, 837, 474, 349, 346, 475, 837, 479, 837, + 480, 837, 837, 349, 837, 837, 837, 837, 837, 808, + 837, 837, 837, 347, 481, 365, 484, 485, 486, 496, + 395, 405, 365, 508, 511, 514, 837, 395, 405, 837, + 837, 365, 837, 520, 837, 443, 395, 405, 528, 529, + 537, 837, 443, 538, 837, 2, 2, 2, 2, 2, + 2, 443, 349, 539, 2, 2, 540, 565, 566, 2, + 567, 2, 2, 2, 2, 2, 2, 2, 25, 571, + 587, 588, 591, 2, 2, 2, 2, 2, 2, 2, + 365, 593, 2, 598, 602, 395, 405, 612, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 443, 2, 2, 2, 613, 2, 2, 2, 2, 2, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 597, 25, 25, 623, 627, 25, 25, 597, 2, + 628, 25, 2, 630, 657, 2, 2, 597, 665, 2, + 667, 2, 25, 675, 25, 2, 25, 25, 683, 25, + 25, 25, 25, 25, 2, 25, 688, 694, 696, 2, + 2, 2, 2, 638, 2, 2, 2, 2, 700, 701, + 638, 717, 2, 2, 722, 25, 723, 725, 730, 638, + 2, 731, 2, 2, 2, 739, 597, 2, 2, 38, + 38, 38, 38, 38, 38, 745, 748, 750, 38, 38, + 756, 757, 758, 38, 760, 38, 38, 38, 38, 38, + 38, 38, 8, 8, 8, 8, 8, 38, 38, 38, + 38, 38, 38, 38, 762, 770, 38, 772, 638, 775, + 778, 448, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 779, 38, 38, 38, 783, 38, + 38, 38, 38, 38, 448, 448, 448, 448, 448, 448, + 448, 448, 448, 448, 448, 777, 448, 448, 791, 797, + 448, 448, 777, 38, 798, 802, 38, 777, 811, 38, + 38, 777, 815, 38, 817, 38, 448, 824, 448, 38, + 448, 448, 826, 448, 448, 448, 448, 448, 38, 448, + 827, 828, 831, 38, 38, 38, 38, 1053, 38, 38, + 38, 38, 833, 842, 1053, 850, 38, 38, 857, 448, + 860, 448, 861, 1053, 38, 864, 38, 38, 38, 866, + 777, 38, 38, 66, 66, 66, 66, 66, 66, 869, + 870, 872, 66, 66, 873, 875, 879, 66, 896, 66, + 66, 66, 66, 66, 66, 66, 336, 336, 336, 336, + 336, 66, 66, 66, 66, 66, 66, 66, 899, 900, + 66, 908, 1053, 913, 916, 454, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 923, 66, + 66, 66, 925, 66, 66, 66, 66, 66, 454, 454, + 454, 454, 454, 454, 454, 454, 454, 454, 454, 809, + 454, 454, 932, 933, 454, 454, 809, 66, 934, 936, + 66, 809, 943, 66, 66, 809, 944, 66, 965, 66, + 454, 966, 454, 66, 454, 454, 975, 454, 454, 454, + 454, 454, 66, 454, 983, 984, 985, 66, 66, 66, + 66, 1111, 66, 66, 66, 66, 1018, 1019, 1111, 1021, + 66, 66, 1022, 454, 1023, 1025, 1026, 1111, 66, 1027, + 66, 66, 66, 1042, 809, 66, 66, 136, 136, 136, + 136, 136, 136, 1054, 1057, 1058, 136, 136, 1059, 1060, + 1064, 136, 1072, 136, 136, 136, 136, 136, 136, 136, + 585, 585, 585, 585, 585, 136, 136, 136, 136, 136, + 136, 136, 1073, 1077, 136, 1080, 1111, 1085, 1109, 1112, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 1119, 136, 136, 136, 1120, 136, 136, 136, + 136, 136, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 1177, 318, 318, 1125, 1135, 318, 318, + 1177, 136, 1137, 1142, 136, 1143, 1144, 136, 136, 1177, + 1145, 136, 1146, 136, 318, 1147, 318, 136, 318, 318, + 1151, 318, 318, 318, 318, 318, 136, 318, 1152, 1153, + 1155, 136, 136, 136, 136, 1159, 136, 136, 136, 136, + 1166, 1167, 1170, 1171, 136, 136, 1172, 318, 1173, 1175, + 1188, 1193, 136, 1218, 136, 136, 136, 1219, 1177, 136, + 136, 219, 219, 219, 219, 219, 219, 1227, 1228, 1231, + 219, 219, 1232, 1233, 1234, 219, 1245, 219, 219, 219, + 219, 219, 219, 219, nil, nil, nil, nil, nil, 219, + 219, 219, 219, 219, 219, 219, nil, 724, 219, 724, + 724, 724, nil, 724, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, nil, 219, 219, 219, + nil, 219, 219, 219, 219, 219, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, nil, 554, 554, + nil, nil, 554, 554, nil, 219, nil, 1010, 219, 1010, + 1010, 219, 219, 1010, nil, 219, nil, 219, 554, nil, + 554, 219, 554, 554, nil, 554, 554, 554, 554, 554, + 219, 554, nil, nil, nil, 219, 219, 219, 219, nil, + 219, 219, 219, 219, 1010, nil, nil, nil, 219, 219, + 554, 554, nil, nil, nil, nil, 219, nil, 219, 219, + 219, nil, nil, 219, 219, 231, 231, 231, 231, 231, + 231, nil, nil, nil, 231, 231, nil, nil, nil, 231, + nil, 231, 231, 231, 231, 231, 231, 231, nil, nil, + nil, nil, nil, 231, 231, 231, 231, 231, 231, 231, + nil, 1045, 231, 1045, 1045, 1045, nil, 1045, 231, 231, + 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, + nil, 231, 231, 231, nil, 231, 231, 231, 231, 231, + 699, 699, 699, 699, 699, 699, 699, 699, 699, 699, + 699, nil, 699, 699, nil, nil, 699, 699, nil, 231, + nil, nil, 231, nil, nil, 231, 231, nil, nil, 231, + nil, 231, 699, nil, 699, 231, 699, 699, nil, 699, + 699, 699, 699, 699, 231, 699, nil, nil, nil, 231, + 231, 231, 231, nil, 231, 231, 231, 231, nil, nil, + nil, nil, 231, 231, nil, 699, nil, nil, nil, nil, + 231, nil, 231, 231, 231, nil, nil, 231, 231, 237, + 237, 237, 237, 237, 237, nil, nil, nil, 237, 237, + nil, nil, nil, 237, nil, 237, 237, 237, 237, 237, + 237, 237, nil, nil, nil, nil, nil, 237, 237, 237, + 237, 237, 237, 237, nil, 1186, 237, 1186, 1186, 1186, + nil, 1186, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, nil, 237, 237, 237, nil, 237, + 237, 237, 237, 237, 784, 784, 784, 784, 784, 784, + 784, 784, 784, 784, 784, nil, 784, 784, nil, nil, + 784, 784, nil, 237, nil, nil, 237, nil, nil, 237, + 237, nil, nil, 237, nil, 237, 784, nil, 784, 237, + 784, 784, nil, 784, 784, 784, 784, 784, 237, 784, + nil, nil, nil, 237, 237, 237, 237, nil, 237, 237, + 237, 237, nil, nil, nil, nil, 237, 237, nil, 784, + nil, nil, nil, nil, 237, nil, 237, 237, 237, nil, + nil, 237, 237, 254, 254, 254, 254, 254, 254, nil, + nil, nil, 254, 254, nil, nil, nil, 254, nil, 254, + 254, 254, 254, 254, 254, 254, nil, nil, nil, nil, + nil, 254, 254, 254, 254, 254, 254, 254, nil, nil, + 254, nil, nil, nil, nil, nil, 254, 254, 254, 254, + 254, 254, 254, 254, 254, 254, 254, 254, nil, 254, + 254, 254, nil, 254, 254, 254, 254, 254, 839, 839, + 839, 839, 839, 839, 839, 839, 839, 839, 839, nil, + 839, 839, nil, nil, 839, 839, nil, 254, nil, nil, + 254, nil, nil, 254, 254, nil, nil, 254, nil, 254, + 839, nil, 839, 254, 839, 839, nil, 839, 839, 839, + 839, 839, 254, 839, nil, nil, nil, 254, 254, 254, + 254, nil, 254, 254, 254, 254, nil, nil, nil, nil, + 254, 254, nil, 839, nil, nil, nil, nil, 254, nil, + 254, 254, 254, nil, nil, 254, 254, 339, 339, 339, + 339, 339, 339, nil, nil, nil, 339, 339, nil, nil, + nil, 339, nil, 339, 339, 339, 339, 339, 339, 339, + nil, nil, nil, nil, nil, 339, 339, 339, 339, 339, + 339, 339, nil, nil, 339, nil, nil, nil, nil, nil, + 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, nil, 339, 339, 339, nil, 339, 339, 339, + 339, 339, 942, 942, 942, 942, 942, 942, 942, 942, + 942, 942, 942, nil, 942, 942, nil, nil, 942, 942, + nil, 339, nil, nil, 339, nil, nil, 339, 339, nil, + nil, 339, nil, 339, 942, nil, 942, 339, 942, 942, + nil, 942, 942, 942, 942, 942, 339, 942, nil, nil, + nil, 339, 339, 339, 339, nil, 339, 339, 339, 339, + nil, nil, nil, nil, 339, 339, nil, 942, nil, nil, + nil, nil, 339, nil, 339, 339, 339, nil, nil, 339, + 339, 344, 344, 344, 344, 344, 344, nil, nil, nil, + 344, 344, nil, nil, nil, 344, nil, 344, 344, 344, + 344, 344, 344, 344, nil, nil, nil, nil, nil, 344, + 344, 344, 344, 344, 344, 344, nil, nil, 344, nil, + nil, nil, nil, nil, 344, 344, 344, 344, 344, 344, + 344, 344, 344, 344, 344, 344, nil, 344, 344, 344, + nil, 344, 344, 344, 344, 344, 945, 945, 945, 945, + 945, 945, 945, 945, 945, 945, 945, nil, 945, 945, + nil, nil, 945, 945, nil, 344, nil, nil, 344, nil, + nil, 344, 344, nil, nil, 344, nil, 344, 945, nil, + 945, 344, 945, 945, nil, 945, 945, 945, 945, 945, + 344, 945, nil, nil, nil, 344, 344, 344, 344, nil, + 344, 344, 344, 344, nil, nil, nil, nil, 344, 344, + nil, 945, nil, nil, nil, nil, 344, nil, 344, 344, + 344, nil, nil, 344, 344, 374, 374, 374, 374, 374, + 374, nil, nil, nil, 374, 374, nil, nil, nil, 374, + nil, 374, 374, 374, 374, 374, 374, 374, nil, nil, + nil, nil, nil, 374, 374, 374, 374, 374, 374, 374, + nil, nil, 374, nil, nil, nil, nil, nil, 374, 374, + 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, + nil, 374, 374, 374, nil, 374, 374, 374, 374, 374, + 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, + 1014, nil, 1014, 1014, nil, nil, 1014, 1014, nil, 374, + nil, nil, 374, nil, nil, 374, 374, nil, nil, 374, + nil, 374, 1014, nil, 1014, 374, 1014, 1014, nil, 1014, + 1014, 1014, 1014, 1014, 374, 1014, nil, nil, nil, 374, + 374, 374, 374, nil, 374, 374, 374, 374, nil, nil, + nil, nil, 374, 374, nil, 1014, nil, nil, nil, nil, + 374, nil, 374, 374, 374, nil, nil, 374, 374, 388, + 388, 388, 388, 388, 388, nil, nil, nil, 388, 388, + nil, nil, nil, 388, nil, 388, 388, 388, 388, 388, + 388, 388, nil, nil, nil, nil, nil, 388, 388, 388, + 388, 388, 388, 388, nil, 497, 388, 497, 497, 497, + nil, 497, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, nil, 388, 388, 388, nil, 388, + 388, 388, 388, 388, 720, nil, 720, 720, 720, nil, + 720, nil, 497, nil, 881, nil, 881, 881, 881, nil, + 881, 497, nil, 388, nil, nil, 388, nil, nil, 388, + 388, nil, nil, 388, 880, 388, 880, 880, 880, 388, + 880, 720, nil, nil, nil, nil, nil, nil, 388, nil, + 720, 881, nil, 388, 388, 388, 388, nil, 388, 388, + 388, 388, nil, nil, nil, nil, 388, 388, nil, nil, + nil, 880, nil, nil, 388, nil, 388, 388, 388, nil, + 880, 388, 388, 389, 389, 389, 389, 389, 389, nil, + nil, nil, 389, 389, nil, nil, nil, 389, nil, 389, + 389, 389, 389, 389, 389, 389, nil, nil, nil, nil, + nil, 389, 389, 389, 389, 389, 389, 389, nil, nil, + 389, nil, nil, nil, nil, nil, 389, 389, 389, 389, + 389, 389, 389, 389, 389, 389, 389, 389, nil, 389, + 389, 389, nil, 389, 389, 389, 389, 389, 366, 366, + 366, 366, 366, 366, 366, 366, 366, 366, 366, nil, + 366, 366, nil, nil, 366, 366, nil, 389, nil, nil, + 389, nil, nil, 389, 389, nil, 550, 389, nil, 389, + 366, nil, 366, 389, 366, 366, nil, 366, 366, 366, + 366, 366, 389, 366, nil, nil, nil, 389, 389, 389, + 389, nil, 389, 389, 389, 389, nil, nil, 550, nil, + 389, 389, 550, 550, nil, 550, 550, nil, 389, nil, + 389, 389, 389, nil, nil, 389, 389, 622, 622, 622, + 622, 622, 622, nil, nil, nil, 622, 622, nil, nil, + nil, 622, nil, 622, 622, 622, 622, 622, 622, 622, + nil, nil, nil, nil, nil, 622, 622, 622, 622, 622, + 622, 622, nil, nil, 622, nil, nil, nil, nil, nil, + 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, + 622, 622, nil, 622, 622, 622, nil, 622, 622, 622, + 622, 622, 367, 367, 367, 367, 367, 367, 367, 367, + 367, 367, 367, nil, 367, 367, nil, nil, 367, 367, + nil, 622, nil, nil, 622, nil, nil, 622, 622, nil, + 551, 622, nil, 622, 367, nil, 367, 622, 367, 367, + nil, 367, 367, 367, 367, 367, 622, 367, nil, nil, + nil, 622, 622, 622, 622, nil, 622, 622, 622, 622, + nil, nil, 551, nil, 622, 622, 551, 551, nil, 551, + 551, nil, 622, nil, 622, 622, 622, nil, nil, 622, + 622, 625, 625, 625, 625, 625, 625, nil, nil, nil, + 625, 625, nil, nil, nil, 625, nil, 625, 625, 625, + 625, 625, 625, 625, nil, nil, nil, nil, nil, 625, + 625, 625, 625, 625, 625, 625, nil, nil, 625, nil, + nil, nil, nil, nil, 625, 625, 625, 625, 625, 625, + 625, 625, 625, 625, 625, 625, nil, 625, 625, 625, + nil, 625, 625, 625, 625, 625, 533, 533, 533, 533, + 533, 533, 533, 533, 533, 533, 533, nil, 533, 533, + nil, nil, 533, 533, nil, 625, nil, nil, 625, nil, + nil, 625, 625, nil, nil, 625, nil, 625, 533, nil, + 533, 625, 533, 533, nil, 533, 533, 533, 533, 533, + 625, 533, nil, nil, nil, 625, 625, 625, 625, nil, + 625, 625, 625, 625, nil, nil, nil, nil, 625, 625, + nil, 1061, nil, 1061, 1061, 1061, 625, 1061, 625, 625, + 625, nil, nil, 625, 625, 646, 646, 646, 646, 646, + 646, nil, nil, nil, 646, 646, nil, nil, nil, 646, + nil, 646, 646, 646, 646, 646, 646, 646, 1061, nil, + nil, nil, nil, 646, 646, 646, 646, 646, 646, 646, + nil, nil, 646, nil, nil, nil, nil, nil, 646, 646, + 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, + nil, 646, 646, 646, nil, 646, 646, 646, 646, 646, + 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, + 534, nil, 534, 534, nil, nil, 534, 534, nil, 646, + nil, nil, 646, nil, nil, 646, 646, nil, nil, 646, + nil, 646, 534, nil, 534, 646, 534, 534, nil, 534, + 534, 534, 534, 534, 646, 534, nil, nil, nil, 646, + 646, 646, 646, nil, 646, 646, 646, 646, nil, nil, + nil, nil, 646, 646, nil, 1062, nil, 1062, 1062, 1062, + 646, 1062, 646, 646, 646, nil, nil, 646, 646, 807, + 807, 807, 807, 807, 807, nil, nil, nil, 807, 807, + nil, nil, nil, 807, nil, 807, 807, 807, 807, 807, + 807, 807, 1062, nil, nil, nil, nil, 807, 807, 807, + 807, 807, 807, 807, nil, nil, 807, nil, nil, nil, + nil, nil, 807, 807, 807, 807, 807, 807, 807, 807, + 807, 807, 807, 807, nil, 807, 807, 807, nil, 807, + 807, 807, 807, 807, 544, 544, 544, 544, 544, 544, + 544, nil, nil, 544, 544, nil, nil, nil, nil, nil, + 544, 544, nil, 807, nil, nil, 807, nil, nil, 807, + 807, nil, nil, 807, nil, 807, 544, nil, 544, 807, + 544, 544, nil, 544, 544, 544, 544, 544, 807, 544, + nil, nil, nil, 807, 807, 807, 807, nil, 807, 807, + 807, 807, nil, nil, nil, nil, 807, 807, nil, nil, + nil, nil, nil, nil, 807, nil, 807, 807, 807, nil, + nil, 807, 807, 812, 812, 812, 812, 812, 812, nil, + nil, nil, 812, 812, nil, nil, nil, 812, nil, 812, + 812, 812, 812, 812, 812, 812, nil, nil, nil, nil, + nil, 812, 812, 812, 812, 812, 812, 812, nil, nil, + 812, nil, nil, nil, nil, nil, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, nil, 812, + 812, 812, nil, 812, 812, 812, 812, 812, 545, 545, + 545, 545, 545, 545, 545, nil, nil, 545, 545, nil, + nil, nil, nil, nil, 545, 545, nil, 812, nil, nil, + 812, nil, nil, 812, 812, nil, nil, 812, nil, 812, + 545, nil, 545, 812, 545, 545, nil, 545, 545, 545, + 545, 545, 812, 545, nil, nil, nil, 812, 812, 812, + 812, nil, 812, 812, 812, 812, nil, nil, nil, nil, + 812, 812, nil, nil, nil, nil, nil, nil, 812, nil, + 812, 812, 812, nil, nil, 812, 812, 821, 821, 821, + 821, 821, 821, nil, nil, nil, 821, 821, nil, nil, + nil, 821, nil, 821, 821, 821, 821, 821, 821, 821, + nil, nil, nil, nil, nil, 821, 821, 821, 821, 821, + 821, 821, nil, nil, 821, nil, nil, nil, nil, nil, + 821, 821, 821, 821, 821, 821, 821, 821, 821, 821, + 821, 821, nil, 821, 821, 821, nil, 821, 821, 821, + 821, 821, 546, 546, 546, 546, 546, 546, 546, nil, + nil, 546, 546, nil, nil, nil, nil, nil, 546, 546, + nil, 821, nil, nil, 821, nil, nil, 821, 821, nil, + nil, 821, nil, 821, 546, nil, 546, 821, 546, 546, + nil, 546, 546, 546, 546, 546, 821, 546, nil, nil, + nil, 821, 821, 821, 821, nil, 821, 821, 821, 821, + nil, nil, nil, nil, 821, 821, nil, nil, nil, nil, + nil, nil, 821, nil, 821, 821, 821, nil, nil, 821, + 821, 859, 859, 859, 859, 859, 859, nil, nil, nil, + 859, 859, nil, nil, nil, 859, nil, 859, 859, 859, + 859, 859, 859, 859, nil, nil, nil, nil, nil, 859, + 859, 859, 859, 859, 859, 859, nil, nil, 859, nil, + nil, nil, nil, nil, 859, 859, 859, 859, 859, 859, + 859, 859, 859, 859, 859, 859, nil, 859, 859, 859, + nil, 859, 859, 859, 859, 859, 547, 547, 547, 547, + 547, 547, 547, nil, nil, 547, 547, nil, nil, nil, + nil, nil, 547, 547, nil, 859, nil, nil, 859, nil, + nil, 859, 859, nil, nil, 859, nil, 859, 547, nil, + 547, 859, 547, 547, nil, 547, 547, 547, 547, 547, + 859, 547, nil, nil, nil, 859, 859, 859, 859, nil, + 859, 859, 859, 859, nil, nil, nil, nil, 859, 859, + nil, nil, nil, nil, nil, nil, 859, nil, 859, 859, + 859, nil, nil, 859, 859, 904, 904, 904, 904, 904, + 904, nil, nil, nil, 904, 904, nil, nil, nil, 904, + nil, 904, 904, 904, 904, 904, 904, 904, nil, nil, + nil, nil, nil, 904, 904, 904, 904, 904, 904, 904, + nil, nil, 904, nil, nil, nil, nil, nil, 904, 904, + 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, + nil, 904, 904, 904, nil, 904, 904, 904, 904, 904, + 548, 548, 548, 548, 548, 548, 548, nil, nil, 548, + 548, nil, nil, nil, nil, nil, 548, 548, nil, 904, + nil, nil, 904, nil, nil, 904, 904, nil, nil, 904, + nil, 904, 548, nil, 548, 904, 548, 548, nil, 548, + 548, 548, 548, 548, 904, 548, nil, nil, nil, 904, + 904, 904, 904, nil, 904, 904, 904, 904, nil, nil, + nil, nil, 904, 904, nil, nil, nil, nil, nil, nil, + 904, nil, 904, 904, 904, nil, nil, 904, 904, 921, + 921, 921, 921, 921, 921, nil, nil, nil, 921, 921, + nil, nil, nil, 921, nil, 921, 921, 921, 921, 921, + 921, 921, nil, nil, nil, nil, nil, 921, 921, 921, + 921, 921, 921, 921, nil, nil, 921, nil, nil, nil, + nil, nil, 921, 921, 921, 921, 921, 921, 921, 921, + 921, 921, 921, 921, nil, 921, 921, 921, nil, 921, + 921, 921, 921, 921, 549, 549, 549, 549, 549, 549, + 549, nil, nil, 549, 549, nil, nil, nil, nil, nil, + 549, 549, nil, 921, nil, nil, 921, nil, nil, 921, + 921, nil, nil, 921, nil, 921, 549, nil, 549, 921, + 549, 549, nil, 549, 549, 549, 549, 549, 921, 549, + nil, nil, nil, 921, 921, 921, 921, nil, 921, 921, + 921, 921, nil, nil, nil, nil, 921, 921, nil, nil, + nil, nil, nil, nil, 921, nil, 921, 921, 921, nil, + nil, 921, 921, 927, 927, 927, 927, 927, 927, nil, + nil, nil, 927, 927, nil, nil, nil, 927, nil, 927, + 927, 927, 927, 927, 927, 927, nil, nil, nil, nil, + nil, 927, 927, 927, 927, 927, 927, 927, nil, nil, + 927, nil, nil, nil, nil, nil, 927, 927, 927, 927, + 927, 927, 927, 927, 927, 927, 927, 927, nil, 927, + 927, 927, nil, 927, 927, 927, 927, 927, 552, 552, + 552, 552, 552, 552, 552, nil, nil, 552, 552, nil, + nil, nil, nil, nil, 552, 552, nil, 927, nil, nil, + 927, nil, nil, 927, 927, nil, nil, 927, nil, 927, + 552, nil, 552, 927, 552, 552, nil, 552, 552, 552, + 552, 552, 927, 552, nil, nil, nil, 927, 927, 927, + 927, nil, 927, 927, 927, 927, nil, nil, nil, nil, + 927, 927, nil, nil, nil, nil, nil, nil, 927, nil, + 927, 927, 927, nil, nil, 927, 927, 947, 947, 947, + 947, 947, 947, nil, nil, nil, 947, 947, nil, nil, + nil, 947, nil, 947, 947, 947, 947, 947, 947, 947, + nil, nil, nil, nil, nil, 947, 947, 947, 947, 947, + 947, 947, nil, nil, 947, nil, nil, nil, nil, nil, + 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, + 947, 947, nil, 947, 947, 947, nil, 947, 947, 947, + 947, 947, 553, 553, 553, 553, 553, 553, 553, 553, + nil, 553, 553, nil, nil, nil, nil, nil, 553, 553, + nil, 947, nil, nil, 947, nil, nil, 947, 947, nil, + nil, 947, nil, 947, 553, nil, 553, 947, 553, 553, + nil, 553, 553, 553, 553, 553, 947, 553, nil, nil, + nil, 947, 947, 947, 947, nil, 947, 947, 947, 947, + nil, nil, nil, nil, 947, 947, nil, nil, nil, nil, + nil, nil, 947, nil, 947, 947, 947, nil, nil, 947, + 947, 1015, 1015, 1015, 1015, 1015, 1015, nil, nil, nil, + 1015, 1015, nil, nil, nil, 1015, nil, 1015, 1015, 1015, + 1015, 1015, 1015, 1015, nil, nil, nil, nil, nil, 1015, + 1015, 1015, 1015, 1015, 1015, 1015, nil, nil, 1015, nil, + nil, nil, nil, nil, 1015, 1015, 1015, 1015, 1015, 1015, + 1015, 1015, 1015, 1015, 1015, 1015, nil, 1015, 1015, 1015, + nil, 1015, 1015, 1015, 1015, 1015, 555, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 555, 555, nil, 1015, nil, nil, 1015, nil, + nil, 1015, 1015, nil, nil, 1015, nil, 1015, 555, nil, + 555, 1015, 555, 555, nil, 555, 555, nil, nil, 555, + 1015, 555, nil, nil, nil, 1015, 1015, 1015, 1015, nil, + 1015, 1015, 1015, 1015, nil, nil, nil, nil, 1015, 1015, + nil, nil, nil, nil, nil, nil, 1015, nil, 1015, 1015, + 1015, nil, nil, 1015, 1015, 1043, 1043, 1043, 1043, 1043, + 1043, nil, nil, nil, 1043, 1043, nil, nil, nil, 1043, + nil, 1043, 1043, 1043, 1043, 1043, 1043, 1043, nil, nil, + nil, nil, nil, 1043, 1043, 1043, 1043, 1043, 1043, 1043, + nil, nil, 1043, nil, nil, nil, nil, nil, 1043, 1043, + 1043, 1043, 1043, 1043, 1043, 1043, 1043, 1043, 1043, 1043, + nil, 1043, 1043, 1043, nil, 1043, 1043, 1043, 1043, 1043, + 608, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 608, 608, nil, 1043, + nil, nil, 1043, nil, nil, 1043, 1043, nil, nil, 1043, + nil, 1043, 608, nil, 608, 1043, 608, 608, nil, 608, + 608, nil, nil, 608, 1043, 608, nil, nil, nil, 1043, + 1043, 1043, 1043, nil, 1043, 1043, 1043, 1043, nil, nil, + nil, nil, 1043, 1043, nil, nil, nil, nil, nil, nil, + 1043, nil, 1043, 1043, 1043, nil, nil, 1043, 1043, 1044, + 1044, 1044, 1044, 1044, 1044, nil, nil, nil, 1044, 1044, + nil, nil, nil, 1044, nil, 1044, 1044, 1044, 1044, 1044, + 1044, 1044, nil, nil, nil, nil, nil, 1044, 1044, 1044, + 1044, 1044, 1044, 1044, nil, nil, 1044, nil, nil, nil, + nil, nil, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, + 1044, 1044, 1044, 1044, nil, 1044, 1044, 1044, nil, 1044, + 1044, 1044, 1044, 1044, 541, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 541, 541, nil, 1044, nil, nil, 1044, nil, nil, 1044, + 1044, nil, nil, 1044, nil, 1044, 541, nil, 541, 1044, + 541, 541, nil, 541, 541, nil, nil, nil, 1044, nil, + nil, nil, nil, 1044, 1044, 1044, 1044, nil, 1044, 1044, + 1044, 1044, nil, nil, nil, nil, 1044, 1044, nil, nil, + nil, nil, nil, nil, 1044, nil, 1044, 1044, 1044, nil, + nil, 1044, 1044, 1050, 1050, 1050, 1050, 1050, 1050, nil, + nil, nil, 1050, 1050, nil, nil, nil, 1050, nil, 1050, + 1050, 1050, 1050, 1050, 1050, 1050, nil, nil, nil, nil, + nil, 1050, 1050, 1050, 1050, 1050, 1050, 1050, nil, nil, + 1050, nil, nil, nil, nil, nil, 1050, 1050, 1050, 1050, + 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050, nil, 1050, + 1050, 1050, nil, 1050, 1050, 1050, 1050, 1050, 542, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 542, 542, nil, 1050, nil, nil, + 1050, nil, nil, 1050, 1050, nil, nil, 1050, nil, 1050, + 542, nil, 542, 1050, 542, 542, nil, 542, 542, nil, + nil, nil, 1050, nil, nil, nil, nil, 1050, 1050, 1050, + 1050, nil, 1050, 1050, 1050, 1050, nil, nil, nil, nil, + 1050, 1050, nil, nil, nil, nil, nil, nil, 1050, nil, + 1050, 1050, 1050, nil, nil, 1050, 1050, 1113, 1113, 1113, + 1113, 1113, 1113, nil, nil, nil, 1113, 1113, nil, nil, + nil, 1113, nil, 1113, 1113, 1113, 1113, 1113, 1113, 1113, + nil, nil, nil, nil, nil, 1113, 1113, 1113, 1113, 1113, + 1113, 1113, nil, nil, 1113, nil, nil, nil, nil, nil, + 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, + 1113, 1113, nil, 1113, 1113, 1113, nil, 1113, 1113, 1113, + 1113, 1113, 543, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 543, 543, + nil, 1113, nil, nil, 1113, nil, nil, 1113, 1113, nil, + nil, 1113, nil, 1113, 543, nil, nil, 1113, 543, 543, + nil, 543, 543, nil, nil, nil, 1113, nil, nil, nil, + nil, 1113, 1113, 1113, 1113, nil, 1113, 1113, 1113, 1113, + nil, nil, nil, nil, 1113, 1113, nil, nil, nil, nil, + nil, nil, 1113, nil, 1113, 1113, 1113, nil, nil, 1113, + 1113, 1235, 1235, 1235, 1235, 1235, 1235, nil, nil, nil, + 1235, 1235, nil, nil, nil, 1235, nil, 1235, 1235, 1235, + 1235, 1235, 1235, 1235, nil, nil, nil, nil, nil, 1235, + 1235, 1235, 1235, 1235, 1235, 1235, nil, nil, 1235, nil, + nil, nil, nil, nil, 1235, 1235, 1235, 1235, 1235, 1235, + 1235, 1235, 1235, 1235, 1235, 1235, nil, 1235, 1235, 1235, + nil, 1235, 1235, 1235, 1235, 1235, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 1235, nil, nil, 1235, nil, + nil, 1235, 1235, nil, nil, 1235, nil, 1235, nil, nil, + nil, 1235, nil, nil, nil, nil, nil, nil, nil, nil, + 1235, nil, nil, nil, nil, 1235, 1235, 1235, 1235, nil, + 1235, 1235, 1235, 1235, nil, nil, nil, nil, 1235, 1235, + nil, nil, nil, nil, nil, nil, 1235, nil, 1235, 1235, + 1235, nil, nil, 1235, 1235, 7, 7, 7, 7, 7, + nil, nil, nil, 7, 7, nil, nil, nil, 7, nil, + 7, 7, 7, 7, 7, 7, 7, nil, nil, nil, + nil, nil, 7, 7, 7, 7, 7, 7, 7, nil, + nil, 7, nil, nil, nil, nil, nil, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, nil, + 7, 7, 7, nil, 7, 7, 7, 7, 7, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 7, nil, + nil, 7, nil, nil, 7, 7, nil, nil, 7, nil, + 7, nil, nil, nil, 7, nil, nil, nil, nil, nil, + nil, nil, nil, 7, nil, nil, nil, nil, 7, 7, + 7, 7, nil, 7, 7, 7, 7, nil, nil, nil, + nil, 7, 7, nil, nil, nil, 24, 24, 24, 7, + 24, 7, 7, 7, 24, 24, 7, 7, nil, 24, + nil, 24, 24, 24, 24, 24, 24, 24, nil, nil, + nil, nil, nil, 24, 24, 24, 24, 24, 24, 24, + nil, nil, 24, nil, nil, nil, nil, nil, nil, 24, + nil, nil, 24, 24, 24, 24, 24, 24, 24, 24, + nil, 24, 24, 24, nil, 24, 24, 24, 24, 24, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 24, + nil, nil, 24, nil, nil, 24, 24, nil, nil, 24, + nil, nil, nil, nil, nil, 24, nil, nil, nil, nil, + nil, nil, nil, nil, 24, nil, nil, nil, nil, 24, + 24, 24, 24, nil, 24, 24, 24, 24, nil, nil, + nil, nil, 24, 24, nil, nil, nil, nil, nil, nil, + 24, nil, 24, 24, 24, 32, nil, 24, 24, nil, + nil, nil, 32, 32, 32, nil, nil, 32, 32, 32, + nil, 32, nil, nil, nil, nil, nil, nil, nil, 32, + 32, 32, 32, nil, nil, nil, nil, nil, nil, nil, + nil, 32, 32, nil, 32, 32, 32, 32, 32, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, nil, nil, 32, 32, 32, + nil, nil, 32, nil, 32, 32, nil, nil, 32, 32, + nil, 32, nil, 32, nil, 32, nil, 32, 32, nil, + 32, 32, 32, 32, 32, 33, 32, 32, 32, nil, + nil, nil, 33, 33, 33, nil, nil, 33, 33, 33, + nil, 33, 32, nil, nil, 32, 32, nil, 32, 33, + 32, 33, 33, nil, nil, nil, nil, 32, nil, nil, + nil, 33, 33, nil, 33, 33, 33, 33, 33, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, nil, nil, 33, 33, 33, + nil, nil, 33, nil, 33, 33, nil, nil, 33, 33, + nil, 33, nil, 33, nil, 33, nil, 33, 33, nil, + 33, 33, 33, 33, 33, nil, 33, nil, 33, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 33, nil, nil, 33, 33, nil, 33, nil, + 33, 34, 34, 34, nil, 34, nil, 33, nil, 34, + 34, nil, nil, nil, 34, nil, 34, 34, 34, 34, + 34, 34, 34, nil, nil, nil, nil, nil, 34, 34, + 34, 34, 34, 34, 34, nil, nil, 34, nil, nil, + nil, nil, nil, nil, 34, nil, nil, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, nil, + 34, 34, 34, 34, 34, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 34, nil, nil, 34, nil, nil, + 34, 34, nil, nil, 34, nil, 34, nil, 34, nil, + 34, nil, nil, 34, nil, nil, nil, nil, nil, 34, + nil, nil, nil, nil, 34, 34, 34, 34, nil, 34, + 34, 34, 34, nil, nil, nil, nil, 34, 34, nil, + nil, nil, 35, 35, 35, 34, 35, 34, 34, 34, + 35, 35, 34, 34, nil, 35, nil, 35, 35, 35, + 35, 35, 35, 35, nil, nil, nil, nil, nil, 35, + 35, 35, 35, 35, 35, 35, nil, nil, 35, nil, + nil, nil, nil, nil, nil, 35, nil, nil, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + nil, 35, 35, 35, 35, 35, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 35, nil, nil, 35, nil, + nil, 35, 35, nil, nil, 35, nil, 35, nil, 35, + nil, 35, nil, nil, 35, nil, nil, nil, nil, nil, + 35, nil, nil, nil, nil, 35, 35, 35, 35, nil, + 35, 35, 35, 35, nil, nil, nil, nil, 35, 35, + nil, nil, nil, 36, 36, 36, 35, 36, 35, 35, + 35, 36, 36, 35, 35, nil, 36, nil, 36, 36, + 36, 36, 36, 36, 36, nil, nil, nil, nil, nil, + 36, 36, 36, 36, 36, 36, 36, nil, nil, 36, + nil, nil, nil, nil, nil, nil, 36, nil, nil, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, nil, 36, 36, 36, 36, 36, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 36, nil, nil, 36, + nil, nil, 36, 36, nil, nil, 36, nil, 36, nil, + 36, nil, 36, nil, nil, 36, nil, nil, nil, nil, + nil, 36, nil, nil, nil, nil, 36, 36, 36, 36, + nil, 36, 36, 36, 36, nil, nil, nil, nil, 36, + 36, nil, nil, nil, 46, 46, 46, 36, 46, 36, + 36, 36, 46, 46, 36, 36, nil, 46, nil, 46, + 46, 46, 46, 46, 46, 46, nil, nil, nil, nil, + nil, 46, 46, 46, 46, 46, 46, 46, nil, nil, + 46, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 46, 46, 46, 46, 46, 46, 46, 46, nil, 46, + 46, 46, nil, 46, 46, 46, 46, 46, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 46, nil, nil, 46, 46, nil, nil, 46, nil, nil, + nil, nil, nil, 46, nil, nil, nil, nil, nil, nil, + nil, nil, 46, nil, nil, nil, nil, 46, 46, 46, + 46, nil, 46, 46, 46, 46, nil, nil, nil, nil, + 46, 46, nil, nil, nil, 47, 47, 47, 46, 47, + 46, 46, 46, 47, 47, 46, 46, nil, 47, nil, + 47, 47, 47, 47, 47, 47, 47, nil, nil, nil, + nil, nil, 47, 47, 47, 47, 47, 47, 47, nil, + nil, 47, nil, nil, nil, nil, nil, nil, 47, nil, + nil, 47, 47, 47, 47, 47, 47, 47, 47, nil, + 47, 47, 47, nil, 47, 47, 47, 47, 47, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 47, nil, + nil, 47, nil, nil, 47, 47, nil, nil, 47, nil, + nil, nil, nil, nil, 47, nil, nil, nil, nil, nil, + nil, nil, nil, 47, nil, nil, nil, nil, 47, 47, + 47, 47, nil, 47, 47, 47, 47, nil, nil, nil, + nil, 47, 47, nil, nil, nil, 49, 49, 49, 47, + 49, 47, 47, 47, 49, 49, 47, 47, nil, 49, + nil, 49, 49, 49, 49, 49, 49, 49, nil, nil, + nil, nil, nil, 49, 49, 49, 49, 49, 49, 49, + nil, nil, 49, nil, nil, nil, nil, nil, nil, 49, + nil, nil, 49, 49, 49, 49, 49, 49, 49, 49, + nil, 49, 49, 49, nil, 49, 49, 49, 49, 49, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 49, + nil, nil, 49, nil, nil, 49, 49, nil, nil, 49, + nil, nil, nil, nil, nil, 49, nil, nil, nil, nil, + nil, nil, nil, nil, 49, nil, nil, nil, nil, 49, + 49, 49, 49, nil, 49, 49, 49, 49, nil, nil, + nil, nil, 49, 49, nil, nil, nil, 50, 50, 50, + 49, 50, 49, 49, 49, 50, 50, 49, 49, nil, + 50, nil, 50, 50, 50, 50, 50, 50, 50, nil, + nil, nil, nil, nil, 50, 50, 50, 50, 50, 50, + 50, nil, nil, 50, nil, nil, nil, nil, nil, nil, + 50, nil, nil, 50, 50, 50, 50, 50, 50, 50, + 50, nil, 50, 50, 50, nil, 50, 50, 50, 50, + 50, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 50, nil, nil, 50, nil, nil, 50, 50, nil, nil, + 50, nil, nil, nil, nil, nil, 50, nil, nil, nil, + nil, nil, nil, nil, nil, 50, nil, nil, nil, nil, + 50, 50, 50, 50, nil, 50, 50, 50, 50, nil, + nil, nil, nil, 50, 50, nil, nil, nil, 52, 52, + 52, 50, 52, 50, 50, 50, 52, 52, 50, 50, + nil, 52, nil, 52, 52, 52, 52, 52, 52, 52, + nil, nil, nil, nil, nil, 52, 52, 52, 52, 52, + 52, 52, nil, nil, 52, nil, nil, nil, nil, nil, + nil, 52, nil, nil, 52, 52, 52, 52, 52, 52, + 52, 52, nil, 52, 52, 52, nil, 52, 52, 52, + 52, 52, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 52, nil, nil, 52, nil, nil, 52, 52, nil, + nil, 52, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, 52, 52, 52, 52, nil, 52, 52, 52, 52, + nil, nil, nil, nil, 52, 52, nil, nil, nil, nil, + nil, nil, 52, nil, 52, 52, 52, 64, nil, 52, + 52, nil, nil, nil, 64, 64, 64, nil, nil, 64, + 64, 64, nil, 64, nil, nil, nil, nil, nil, nil, + nil, 64, nil, 64, 64, 64, nil, nil, nil, nil, + nil, nil, nil, 64, 64, nil, 64, 64, 64, 64, + 64, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, nil, nil, 64, + 64, 64, nil, nil, 64, nil, nil, 64, nil, nil, + 64, 64, nil, 64, nil, 64, nil, 64, nil, 64, + 64, nil, 64, 64, 64, 64, 64, nil, 64, nil, + 64, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 64, nil, nil, 64, 64, 64, + 64, nil, 64, nil, 64, nil, 67, 67, 67, 64, + 67, nil, nil, nil, 67, 67, nil, nil, nil, 67, + nil, 67, 67, 67, 67, 67, 67, 67, nil, nil, + nil, nil, nil, 67, 67, 67, 67, 67, 67, 67, + nil, nil, 67, nil, nil, nil, nil, nil, nil, 67, + nil, nil, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, nil, 67, 67, 67, 67, 67, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 67, + nil, nil, 67, nil, nil, 67, 67, nil, nil, 67, + nil, 67, nil, nil, nil, 67, nil, nil, 67, nil, + nil, nil, nil, nil, 67, nil, nil, nil, nil, 67, + 67, 67, 67, nil, 67, 67, 67, 67, nil, nil, + nil, nil, 67, 67, nil, nil, nil, 68, 68, 68, + 67, 68, 67, 67, 67, 68, 68, 67, 67, nil, + 68, nil, 68, 68, 68, 68, 68, 68, 68, nil, + nil, nil, nil, nil, 68, 68, 68, 68, 68, 68, + 68, nil, nil, 68, nil, nil, nil, nil, nil, nil, + 68, nil, nil, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, nil, 68, 68, 68, 68, + 68, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 68, nil, nil, 68, nil, nil, 68, 68, nil, nil, + 68, nil, nil, nil, nil, nil, 68, nil, nil, 68, + nil, nil, nil, nil, nil, 68, nil, nil, nil, nil, + 68, 68, 68, 68, nil, 68, 68, 68, 68, nil, + nil, nil, nil, 68, 68, nil, nil, nil, 71, 71, + 71, 68, 71, 68, 68, 68, 71, 71, 68, 68, + nil, 71, nil, 71, 71, 71, 71, 71, 71, 71, + nil, nil, nil, nil, nil, 71, 71, 71, 71, 71, + 71, 71, nil, nil, 71, nil, nil, nil, nil, nil, + nil, 71, nil, nil, 71, 71, 71, 71, 71, 71, + 71, 71, nil, 71, 71, 71, nil, 71, 71, 71, + 71, 71, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 71, nil, nil, 71, nil, nil, 71, 71, nil, + nil, 71, nil, nil, nil, nil, nil, 71, nil, nil, + nil, nil, nil, nil, nil, nil, 71, nil, nil, nil, + nil, 71, 71, 71, 71, nil, 71, 71, 71, 71, + nil, nil, nil, nil, 71, 71, nil, nil, nil, 72, + 72, 72, 71, 72, 71, 71, 71, 72, 72, 71, + 71, nil, 72, nil, 72, 72, 72, 72, 72, 72, + 72, nil, nil, nil, nil, nil, 72, 72, 72, 72, + 72, 72, 72, nil, nil, 72, nil, nil, nil, nil, + nil, nil, 72, nil, nil, 72, 72, 72, 72, 72, + 72, 72, 72, nil, 72, 72, 72, nil, 72, 72, + 72, 72, 72, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 72, nil, nil, 72, nil, nil, 72, 72, + nil, nil, 72, nil, nil, nil, nil, nil, 72, nil, + nil, nil, nil, nil, nil, nil, nil, 72, nil, nil, + nil, nil, 72, 72, 72, 72, nil, 72, 72, 72, + 72, nil, nil, nil, nil, 72, 72, nil, nil, nil, + 75, 75, 75, 72, 75, 72, 72, 72, 75, 75, + 72, 72, nil, 75, nil, 75, 75, 75, 75, 75, + 75, 75, nil, nil, nil, nil, nil, 75, 75, 75, + 75, 75, 75, 75, nil, nil, 75, nil, nil, nil, + nil, nil, nil, 75, nil, nil, 75, 75, 75, 75, + 75, 75, 75, 75, nil, 75, 75, 75, nil, 75, + 75, 75, 75, 75, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 75, nil, nil, 75, nil, nil, 75, + 75, nil, nil, 75, nil, nil, nil, nil, nil, 75, + nil, nil, nil, nil, nil, nil, nil, nil, 75, nil, + nil, nil, nil, 75, 75, 75, 75, nil, 75, 75, + 75, 75, nil, nil, nil, nil, 75, 75, 75, nil, + nil, nil, nil, 75, 75, nil, 75, 75, 75, nil, + nil, 75, 75, 125, 125, 125, 125, 125, nil, nil, + nil, 125, 125, nil, nil, nil, 125, nil, 125, 125, + 125, 125, 125, 125, 125, nil, nil, nil, nil, nil, + 125, 125, 125, 125, 125, 125, 125, nil, nil, 125, + nil, nil, nil, nil, nil, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, nil, 125, 125, + 125, nil, 125, 125, 125, 125, 125, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 125, nil, nil, 125, + nil, nil, 125, 125, nil, nil, 125, nil, 125, nil, + nil, nil, 125, nil, nil, nil, nil, nil, nil, nil, + nil, 125, nil, nil, nil, nil, 125, 125, 125, 125, + nil, 125, 125, 125, 125, nil, nil, nil, nil, 125, + 125, nil, nil, nil, nil, nil, 125, 125, nil, 125, + 125, 125, nil, nil, 125, 125, 130, 130, 130, nil, + 130, nil, nil, nil, 130, 130, nil, nil, nil, 130, + nil, 130, 130, 130, 130, 130, 130, 130, nil, nil, + nil, nil, nil, 130, 130, 130, 130, 130, 130, 130, + nil, nil, 130, nil, nil, nil, nil, nil, nil, 130, + nil, nil, 130, 130, 130, 130, 130, 130, 130, 130, + nil, 130, 130, 130, nil, 130, 130, 130, 130, 130, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 130, + nil, nil, 130, nil, nil, 130, 130, nil, nil, 130, + nil, nil, nil, nil, nil, 130, nil, nil, nil, nil, + nil, nil, nil, nil, 130, nil, nil, nil, nil, 130, + 130, 130, 130, nil, 130, 130, 130, 130, nil, nil, + nil, nil, 130, 130, nil, nil, nil, 131, 131, 131, + 130, 131, 130, 130, 130, 131, 131, 130, 130, nil, + 131, nil, 131, 131, 131, 131, 131, 131, 131, nil, + nil, nil, nil, nil, 131, 131, 131, 131, 131, 131, + 131, nil, nil, 131, nil, nil, nil, nil, nil, nil, + 131, nil, nil, 131, 131, 131, 131, 131, 131, 131, + 131, nil, 131, 131, 131, nil, 131, 131, 131, 131, + 131, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 131, nil, nil, 131, nil, nil, 131, 131, nil, nil, + 131, nil, nil, nil, nil, nil, 131, nil, nil, nil, + nil, nil, nil, nil, nil, 131, nil, nil, nil, nil, + 131, 131, 131, 131, nil, 131, 131, 131, 131, nil, + nil, nil, nil, 131, 131, nil, nil, nil, 132, 132, + 132, 131, 132, 131, 131, 131, 132, 132, 131, 131, + nil, 132, nil, 132, 132, 132, 132, 132, 132, 132, + nil, nil, nil, nil, nil, 132, 132, 132, 132, 132, + 132, 132, nil, nil, 132, nil, nil, nil, nil, nil, + nil, 132, nil, nil, 132, 132, 132, 132, 132, 132, + 132, 132, nil, 132, 132, 132, nil, 132, 132, 132, + 132, 132, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 132, nil, nil, 132, nil, nil, 132, 132, nil, + nil, 132, nil, nil, nil, nil, nil, 132, nil, nil, + nil, nil, nil, nil, nil, nil, 132, nil, nil, nil, + nil, 132, 132, 132, 132, nil, 132, 132, 132, 132, + nil, nil, nil, nil, 132, 132, nil, nil, nil, 133, + 133, 133, 132, 133, 132, 132, 132, 133, 133, 132, + 132, nil, 133, nil, 133, 133, 133, 133, 133, 133, + 133, nil, nil, nil, nil, nil, 133, 133, 133, 133, + 133, 133, 133, nil, nil, 133, nil, nil, nil, nil, + nil, nil, 133, nil, nil, 133, 133, 133, 133, 133, + 133, 133, 133, nil, 133, 133, 133, nil, 133, 133, + 133, 133, 133, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 133, nil, nil, 133, nil, nil, 133, 133, + nil, nil, 133, nil, nil, nil, nil, nil, 133, nil, + nil, nil, nil, nil, nil, nil, nil, 133, nil, nil, + nil, nil, 133, 133, 133, 133, nil, 133, 133, 133, + 133, nil, nil, nil, nil, 133, 133, nil, nil, nil, + nil, nil, nil, 133, nil, 133, 133, 133, nil, nil, + 133, 133, 134, 134, 134, 134, 134, nil, nil, nil, + 134, 134, nil, nil, nil, 134, nil, 134, 134, 134, + 134, 134, 134, 134, nil, nil, nil, nil, nil, 134, + 134, 134, 134, 134, 134, 134, nil, nil, 134, nil, + nil, nil, nil, nil, 134, 134, nil, 134, 134, 134, + 134, 134, 134, 134, 134, 134, nil, 134, 134, 134, + nil, 134, 134, 134, 134, 134, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 134, nil, nil, 134, nil, + nil, 134, 134, nil, nil, 134, nil, 134, nil, nil, + nil, 134, nil, nil, nil, nil, nil, nil, nil, nil, + 134, nil, nil, nil, nil, 134, 134, 134, 134, nil, + 134, 134, 134, 134, nil, nil, nil, nil, 134, 134, + nil, nil, nil, 220, 220, 220, 134, 220, 134, 134, + 134, 220, 220, 134, 134, nil, 220, nil, 220, 220, + 220, 220, 220, 220, 220, nil, nil, nil, nil, nil, + 220, 220, 220, 220, 220, 220, 220, nil, nil, 220, + nil, nil, nil, nil, nil, nil, 220, nil, nil, 220, + 220, 220, 220, 220, 220, 220, 220, nil, 220, 220, + 220, nil, 220, 220, 220, 220, 220, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 220, nil, nil, 220, + nil, nil, 220, 220, nil, nil, 220, nil, 220, nil, + nil, nil, 220, nil, nil, nil, nil, nil, nil, nil, + nil, 220, nil, nil, nil, nil, 220, 220, 220, 220, + nil, 220, 220, 220, 220, nil, nil, nil, nil, 220, + 220, nil, nil, nil, 221, 221, 221, 220, 221, 220, + 220, 220, 221, 221, 220, 220, nil, 221, nil, 221, + 221, 221, 221, 221, 221, 221, nil, nil, nil, nil, + nil, 221, 221, 221, 221, 221, 221, 221, nil, nil, + 221, nil, nil, nil, nil, nil, nil, 221, nil, nil, + 221, 221, 221, 221, 221, 221, 221, 221, nil, 221, + 221, 221, nil, 221, 221, 221, 221, 221, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, + 221, nil, nil, 221, 221, nil, nil, 221, nil, 221, + nil, nil, nil, 221, nil, nil, nil, nil, nil, nil, + nil, nil, 221, nil, nil, nil, nil, 221, 221, 221, + 221, nil, 221, 221, 221, 221, nil, nil, nil, nil, + 221, 221, nil, nil, nil, 222, 222, 222, 221, 222, + 221, 221, 221, 222, 222, 221, 221, nil, 222, nil, + 222, 222, 222, 222, 222, 222, 222, nil, nil, nil, + nil, nil, 222, 222, 222, 222, 222, 222, 222, nil, + nil, 222, nil, nil, nil, nil, nil, nil, 222, nil, + nil, 222, 222, 222, 222, 222, 222, 222, 222, nil, + 222, 222, 222, nil, 222, 222, 222, 222, 222, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 222, nil, + nil, 222, nil, nil, 222, 222, nil, nil, 222, nil, + nil, nil, nil, nil, 222, nil, nil, nil, nil, nil, + nil, nil, nil, 222, nil, nil, nil, nil, 222, 222, + 222, 222, nil, 222, 222, 222, 222, nil, nil, nil, + nil, 222, 222, nil, nil, nil, 223, 223, 223, 222, + 223, 222, 222, 222, 223, 223, 222, 222, nil, 223, + nil, 223, 223, 223, 223, 223, 223, 223, nil, nil, + nil, nil, nil, 223, 223, 223, 223, 223, 223, 223, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 223, + nil, nil, 223, 223, 223, 223, 223, 223, 223, 223, + nil, 223, 223, 223, nil, 223, 223, 223, 223, 223, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 223, + nil, nil, 223, nil, nil, 223, 223, nil, nil, 223, + nil, nil, nil, nil, nil, 223, nil, nil, nil, nil, + nil, nil, nil, nil, 223, nil, nil, nil, nil, 223, + 223, 223, 223, nil, 223, 223, 223, 223, nil, nil, + nil, nil, 223, 223, nil, nil, nil, 224, 224, 224, + 223, 224, 223, 223, 223, 224, 224, 223, 223, nil, + 224, nil, 224, 224, 224, 224, 224, 224, 224, nil, + nil, nil, nil, nil, 224, 224, 224, 224, 224, 224, + 224, nil, nil, 224, nil, nil, nil, nil, nil, nil, + 224, nil, nil, 224, 224, 224, 224, 224, 224, 224, + 224, nil, 224, 224, 224, nil, 224, 224, 224, 224, + 224, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 224, nil, nil, 224, nil, nil, 224, 224, nil, nil, + 224, nil, nil, nil, nil, nil, 224, nil, nil, nil, + nil, nil, nil, nil, nil, 224, nil, nil, nil, nil, + 224, 224, 224, 224, nil, 224, 224, 224, 224, nil, + nil, nil, nil, 224, 224, nil, nil, nil, 225, 225, + 225, 224, 225, 224, 224, 224, 225, 225, 224, 224, + nil, 225, nil, 225, 225, 225, 225, 225, 225, 225, + nil, nil, nil, nil, nil, 225, 225, 225, 225, 225, + 225, 225, nil, nil, 225, nil, nil, nil, nil, nil, + nil, 225, nil, nil, 225, 225, 225, 225, 225, 225, + 225, 225, 225, 225, 225, 225, nil, 225, 225, 225, + 225, 225, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 225, nil, nil, 225, nil, nil, 225, 225, nil, + nil, 225, nil, 225, nil, 225, nil, 225, nil, nil, + 225, nil, nil, nil, nil, nil, 225, nil, nil, nil, + nil, 225, 225, 225, 225, nil, 225, 225, 225, 225, + nil, nil, nil, nil, 225, 225, nil, nil, nil, 238, + 238, 238, 225, 238, 225, 225, 225, 238, 238, 225, + 225, nil, 238, nil, 238, 238, 238, 238, 238, 238, + 238, nil, nil, nil, nil, nil, 238, 238, 238, 238, + 238, 238, 238, nil, nil, 238, nil, nil, nil, nil, + nil, nil, 238, nil, nil, 238, 238, 238, 238, 238, + 238, 238, 238, nil, 238, 238, 238, nil, 238, 238, + 238, 238, 238, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 238, nil, nil, 238, nil, nil, 238, 238, + nil, nil, 238, nil, nil, nil, nil, nil, 238, nil, + nil, nil, nil, nil, nil, nil, nil, 238, nil, nil, + nil, nil, 238, 238, 238, 238, nil, 238, 238, 238, + 238, nil, nil, nil, nil, 238, 238, nil, nil, nil, + 239, 239, 239, 238, 239, 238, 238, 238, 239, 239, + 238, 238, nil, 239, nil, 239, 239, 239, 239, 239, + 239, 239, nil, nil, nil, nil, nil, 239, 239, 239, + 239, 239, 239, 239, nil, nil, 239, nil, nil, nil, + nil, nil, nil, 239, nil, nil, 239, 239, 239, 239, + 239, 239, 239, 239, nil, 239, 239, 239, nil, 239, + 239, 239, 239, 239, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 239, nil, nil, 239, nil, nil, 239, + 239, nil, nil, 239, nil, nil, nil, nil, nil, 239, + nil, nil, nil, nil, nil, nil, nil, nil, 239, nil, + nil, nil, nil, 239, 239, 239, 239, nil, 239, 239, + 239, 239, nil, nil, nil, nil, 239, 239, nil, nil, + nil, 240, 240, 240, 239, 240, 239, 239, 239, 240, + 240, 239, 239, nil, 240, nil, 240, 240, 240, 240, + 240, 240, 240, nil, nil, nil, nil, nil, 240, 240, + 240, 240, 240, 240, 240, nil, nil, 240, nil, nil, + nil, nil, nil, nil, 240, nil, nil, 240, 240, 240, + 240, 240, 240, 240, 240, nil, 240, 240, 240, nil, + 240, 240, 240, 240, 240, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 240, nil, nil, 240, nil, nil, + 240, 240, nil, nil, 240, nil, nil, nil, nil, nil, + 240, nil, nil, nil, nil, nil, nil, nil, nil, 240, + nil, nil, nil, nil, 240, 240, 240, 240, nil, 240, + 240, 240, 240, nil, nil, nil, nil, 240, 240, 240, + nil, nil, 251, 251, 251, 240, 251, 240, 240, 240, + 251, 251, 240, 240, nil, 251, nil, 251, 251, 251, + 251, 251, 251, 251, nil, nil, nil, nil, nil, 251, + 251, 251, 251, 251, 251, 251, nil, nil, 251, nil, + nil, nil, nil, nil, nil, 251, nil, nil, 251, 251, + 251, 251, 251, 251, 251, 251, nil, 251, 251, 251, + nil, 251, 251, 251, 251, 251, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, 251, nil, + nil, 251, 251, nil, nil, 251, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 251, 251, 251, 251, nil, + 251, 251, 251, 251, nil, nil, nil, nil, 251, 251, + nil, nil, nil, 258, 258, 258, 251, 258, 251, 251, + 251, 258, 258, 251, 251, nil, 258, nil, 258, 258, + 258, 258, 258, 258, 258, nil, nil, nil, nil, nil, + 258, 258, 258, 258, 258, 258, 258, nil, nil, 258, + nil, nil, nil, nil, nil, nil, 258, nil, nil, 258, + 258, 258, 258, 258, 258, 258, 258, nil, 258, 258, + 258, nil, 258, 258, 258, 258, 258, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 258, nil, nil, 258, + nil, nil, 258, 258, nil, nil, 258, nil, nil, nil, + nil, nil, 258, nil, nil, nil, nil, nil, nil, nil, + nil, 258, nil, nil, nil, nil, 258, 258, 258, 258, + nil, 258, 258, 258, 258, nil, nil, nil, nil, 258, + 258, nil, nil, nil, 259, 259, 259, 258, 259, 258, + 258, 258, 259, 259, 258, 258, nil, 259, nil, 259, + 259, 259, 259, 259, 259, 259, nil, nil, nil, nil, + nil, 259, 259, 259, 259, 259, 259, 259, nil, nil, + 259, nil, nil, nil, nil, nil, nil, 259, nil, nil, + 259, 259, 259, 259, 259, 259, 259, 259, nil, 259, + 259, 259, nil, 259, 259, 259, 259, 259, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 259, nil, nil, + 259, nil, nil, 259, 259, nil, nil, 259, nil, nil, + nil, nil, nil, 259, nil, nil, nil, nil, nil, nil, + nil, nil, 259, nil, nil, nil, nil, 259, 259, 259, + 259, nil, 259, 259, 259, 259, nil, nil, nil, nil, + 259, 259, nil, nil, nil, 260, 260, 260, 259, 260, + 259, 259, 259, 260, 260, 259, 259, nil, 260, nil, + 260, 260, 260, 260, 260, 260, 260, nil, nil, nil, + nil, nil, 260, 260, 260, 260, 260, 260, 260, nil, + nil, 260, nil, nil, nil, nil, nil, nil, 260, nil, + nil, 260, 260, 260, 260, 260, 260, 260, 260, nil, + 260, 260, 260, nil, 260, 260, 260, 260, 260, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 260, nil, + nil, 260, nil, nil, 260, 260, nil, nil, 260, nil, + nil, nil, nil, nil, 260, nil, nil, nil, nil, nil, + nil, nil, nil, 260, nil, nil, nil, nil, 260, 260, + 260, 260, nil, 260, 260, 260, 260, nil, nil, nil, + nil, 260, 260, nil, nil, nil, 261, 261, 261, 260, + 261, 260, 260, 260, 261, 261, 260, 260, nil, 261, + nil, 261, 261, 261, 261, 261, 261, 261, nil, nil, + nil, nil, nil, 261, 261, 261, 261, 261, 261, 261, + nil, nil, 261, nil, nil, nil, nil, nil, nil, 261, + nil, nil, 261, 261, 261, 261, 261, 261, 261, 261, + nil, 261, 261, 261, nil, 261, 261, 261, 261, 261, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 261, + nil, nil, 261, nil, nil, 261, 261, nil, nil, 261, + nil, nil, nil, nil, nil, 261, nil, nil, nil, nil, + nil, nil, nil, nil, 261, nil, nil, nil, nil, 261, + 261, 261, 261, nil, 261, 261, 261, 261, nil, nil, + nil, nil, 261, 261, nil, nil, nil, 262, 262, 262, + 261, 262, 261, 261, 261, 262, 262, 261, 261, nil, + 262, nil, 262, 262, 262, 262, 262, 262, 262, nil, + nil, nil, nil, nil, 262, 262, 262, 262, 262, 262, + 262, nil, nil, 262, nil, nil, nil, nil, nil, nil, + 262, nil, nil, 262, 262, 262, 262, 262, 262, 262, + 262, nil, 262, 262, 262, nil, 262, 262, 262, 262, + 262, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 262, nil, nil, 262, nil, nil, 262, 262, nil, nil, + 262, nil, nil, nil, nil, nil, 262, nil, nil, nil, + nil, nil, nil, nil, nil, 262, nil, nil, nil, nil, + 262, 262, 262, 262, nil, 262, 262, 262, 262, nil, + nil, nil, nil, 262, 262, nil, nil, nil, 263, 263, + 263, 262, 263, 262, 262, 262, 263, 263, 262, 262, + nil, 263, nil, 263, 263, 263, 263, 263, 263, 263, + nil, nil, nil, nil, nil, 263, 263, 263, 263, 263, + 263, 263, nil, nil, 263, nil, nil, nil, nil, nil, + nil, 263, nil, nil, 263, 263, 263, 263, 263, 263, + 263, 263, nil, 263, 263, 263, nil, 263, 263, 263, + 263, 263, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 263, nil, nil, 263, nil, nil, 263, 263, nil, + nil, 263, nil, nil, nil, nil, nil, 263, nil, nil, + nil, nil, nil, nil, nil, nil, 263, nil, nil, nil, + nil, 263, 263, 263, 263, nil, 263, 263, 263, 263, + nil, nil, nil, nil, 263, 263, nil, nil, nil, 264, + 264, 264, 263, 264, 263, 263, 263, 264, 264, 263, + 263, nil, 264, nil, 264, 264, 264, 264, 264, 264, + 264, nil, nil, nil, nil, nil, 264, 264, 264, 264, + 264, 264, 264, nil, nil, 264, nil, nil, nil, nil, + nil, nil, 264, nil, nil, 264, 264, 264, 264, 264, + 264, 264, 264, nil, 264, 264, 264, nil, 264, 264, + 264, 264, 264, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 264, nil, nil, 264, nil, nil, 264, 264, + nil, nil, 264, nil, nil, nil, nil, nil, 264, nil, + nil, nil, nil, nil, nil, nil, nil, 264, nil, nil, + nil, nil, 264, 264, 264, 264, nil, 264, 264, 264, + 264, nil, nil, nil, nil, 264, 264, nil, nil, nil, + 265, 265, 265, 264, 265, 264, 264, 264, 265, 265, + 264, 264, nil, 265, nil, 265, 265, 265, 265, 265, + 265, 265, nil, nil, nil, nil, nil, 265, 265, 265, + 265, 265, 265, 265, nil, nil, 265, nil, nil, nil, + nil, nil, nil, 265, nil, nil, 265, 265, 265, 265, + 265, 265, 265, 265, nil, 265, 265, 265, nil, 265, + 265, 265, 265, 265, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 265, nil, nil, 265, nil, nil, 265, + 265, nil, nil, 265, nil, nil, nil, nil, nil, 265, + nil, nil, nil, nil, nil, nil, nil, nil, 265, nil, + nil, nil, nil, 265, 265, 265, 265, nil, 265, 265, + 265, 265, nil, nil, nil, nil, 265, 265, nil, nil, + nil, 266, 266, 266, 265, 266, 265, 265, 265, 266, + 266, 265, 265, nil, 266, nil, 266, 266, 266, 266, + 266, 266, 266, nil, nil, nil, nil, nil, 266, 266, + 266, 266, 266, 266, 266, nil, nil, 266, nil, nil, + nil, nil, nil, nil, 266, nil, nil, 266, 266, 266, + 266, 266, 266, 266, 266, nil, 266, 266, 266, nil, + 266, 266, 266, 266, 266, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 266, nil, nil, 266, nil, nil, + 266, 266, nil, nil, 266, nil, nil, nil, nil, nil, + 266, nil, nil, nil, nil, nil, nil, nil, nil, 266, + nil, nil, nil, nil, 266, 266, 266, 266, nil, 266, + 266, 266, 266, nil, nil, nil, nil, 266, 266, nil, + nil, nil, 267, 267, 267, 266, 267, 266, 266, 266, + 267, 267, 266, 266, nil, 267, nil, 267, 267, 267, + 267, 267, 267, 267, nil, nil, nil, nil, nil, 267, + 267, 267, 267, 267, 267, 267, nil, nil, 267, nil, + nil, nil, nil, nil, nil, 267, nil, nil, 267, 267, + 267, 267, 267, 267, 267, 267, nil, 267, 267, 267, + nil, 267, 267, 267, 267, 267, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 267, nil, nil, 267, nil, + nil, 267, 267, nil, nil, 267, nil, nil, nil, nil, + nil, 267, nil, nil, nil, nil, nil, nil, nil, nil, + 267, nil, nil, nil, nil, 267, 267, 267, 267, nil, + 267, 267, 267, 267, nil, nil, nil, nil, 267, 267, + nil, nil, nil, 268, 268, 268, 267, 268, 267, 267, + 267, 268, 268, 267, 267, nil, 268, nil, 268, 268, + 268, 268, 268, 268, 268, nil, nil, nil, nil, nil, + 268, 268, 268, 268, 268, 268, 268, nil, nil, 268, + nil, nil, nil, nil, nil, nil, 268, nil, nil, 268, + 268, 268, 268, 268, 268, 268, 268, nil, 268, 268, + 268, nil, 268, 268, 268, 268, 268, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 268, nil, nil, 268, + nil, nil, 268, 268, nil, nil, 268, nil, nil, nil, + nil, nil, 268, nil, nil, nil, nil, nil, nil, nil, + nil, 268, nil, nil, nil, nil, 268, 268, 268, 268, + nil, 268, 268, 268, 268, nil, nil, nil, nil, 268, + 268, nil, nil, nil, 269, 269, 269, 268, 269, 268, + 268, 268, 269, 269, 268, 268, nil, 269, nil, 269, + 269, 269, 269, 269, 269, 269, nil, nil, nil, nil, + nil, 269, 269, 269, 269, 269, 269, 269, nil, nil, + 269, nil, nil, nil, nil, nil, nil, 269, nil, nil, + 269, 269, 269, 269, 269, 269, 269, 269, nil, 269, + 269, 269, nil, 269, 269, 269, 269, 269, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 269, nil, nil, + 269, nil, nil, 269, 269, nil, nil, 269, nil, nil, + nil, nil, nil, 269, nil, nil, nil, nil, nil, nil, + nil, nil, 269, nil, nil, nil, nil, 269, 269, 269, + 269, nil, 269, 269, 269, 269, nil, nil, nil, nil, + 269, 269, nil, nil, nil, 270, 270, 270, 269, 270, + 269, 269, 269, 270, 270, 269, 269, nil, 270, nil, + 270, 270, 270, 270, 270, 270, 270, nil, nil, nil, + nil, nil, 270, 270, 270, 270, 270, 270, 270, nil, + nil, 270, nil, nil, nil, nil, nil, nil, 270, nil, + nil, 270, 270, 270, 270, 270, 270, 270, 270, nil, + 270, 270, 270, nil, 270, 270, 270, 270, 270, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 270, nil, + nil, 270, nil, nil, 270, 270, nil, nil, 270, nil, + nil, nil, nil, nil, 270, nil, nil, nil, nil, nil, + nil, nil, nil, 270, nil, nil, nil, nil, 270, 270, + 270, 270, nil, 270, 270, 270, 270, nil, nil, nil, + nil, 270, 270, nil, nil, nil, 271, 271, 271, 270, + 271, 270, 270, 270, 271, 271, 270, 270, nil, 271, + nil, 271, 271, 271, 271, 271, 271, 271, nil, nil, + nil, nil, nil, 271, 271, 271, 271, 271, 271, 271, + nil, nil, 271, nil, nil, nil, nil, nil, nil, 271, + nil, nil, 271, 271, 271, 271, 271, 271, 271, 271, + nil, 271, 271, 271, nil, 271, 271, 271, 271, 271, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 271, + nil, nil, 271, nil, nil, 271, 271, nil, nil, 271, + nil, nil, nil, nil, nil, 271, nil, nil, nil, nil, + nil, nil, nil, nil, 271, nil, nil, nil, nil, 271, + 271, 271, 271, nil, 271, 271, 271, 271, nil, nil, + nil, nil, 271, 271, nil, nil, nil, 272, 272, 272, + 271, 272, 271, 271, 271, 272, 272, 271, 271, nil, + 272, nil, 272, 272, 272, 272, 272, 272, 272, nil, + nil, nil, nil, nil, 272, 272, 272, 272, 272, 272, + 272, nil, nil, 272, nil, nil, nil, nil, nil, nil, + 272, nil, nil, 272, 272, 272, 272, 272, 272, 272, + 272, nil, 272, 272, 272, nil, 272, 272, 272, 272, + 272, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 272, nil, nil, 272, nil, nil, 272, 272, nil, nil, + 272, nil, nil, nil, nil, nil, 272, nil, nil, nil, + nil, nil, nil, nil, nil, 272, nil, nil, nil, nil, + 272, 272, 272, 272, nil, 272, 272, 272, 272, nil, + nil, nil, nil, 272, 272, nil, nil, nil, 273, 273, + 273, 272, 273, 272, 272, 272, 273, 273, 272, 272, + nil, 273, nil, 273, 273, 273, 273, 273, 273, 273, + nil, nil, nil, nil, nil, 273, 273, 273, 273, 273, + 273, 273, nil, nil, 273, nil, nil, nil, nil, nil, + nil, 273, nil, nil, 273, 273, 273, 273, 273, 273, + 273, 273, nil, 273, 273, 273, nil, 273, 273, 273, + 273, 273, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 273, nil, nil, 273, nil, nil, 273, 273, nil, + nil, 273, nil, nil, nil, nil, nil, 273, nil, nil, + nil, nil, nil, nil, nil, nil, 273, nil, nil, nil, + nil, 273, 273, 273, 273, nil, 273, 273, 273, 273, + nil, nil, nil, nil, 273, 273, nil, nil, nil, 274, + 274, 274, 273, 274, 273, 273, 273, 274, 274, 273, + 273, nil, 274, nil, 274, 274, 274, 274, 274, 274, + 274, nil, nil, nil, nil, nil, 274, 274, 274, 274, + 274, 274, 274, nil, nil, 274, nil, nil, nil, nil, + nil, nil, 274, nil, nil, 274, 274, 274, 274, 274, + 274, 274, 274, nil, 274, 274, 274, nil, 274, 274, + 274, 274, 274, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 274, nil, nil, 274, nil, nil, 274, 274, + nil, nil, 274, nil, nil, nil, nil, nil, 274, nil, + nil, nil, nil, nil, nil, nil, nil, 274, nil, nil, + nil, nil, 274, 274, 274, 274, nil, 274, 274, 274, + 274, nil, nil, nil, nil, 274, 274, nil, nil, nil, + 275, 275, 275, 274, 275, 274, 274, 274, 275, 275, + 274, 274, nil, 275, nil, 275, 275, 275, 275, 275, + 275, 275, nil, nil, nil, nil, nil, 275, 275, 275, + 275, 275, 275, 275, nil, nil, 275, nil, nil, nil, + nil, nil, nil, 275, nil, nil, 275, 275, 275, 275, + 275, 275, 275, 275, nil, 275, 275, 275, nil, 275, + 275, 275, 275, 275, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 275, nil, nil, 275, nil, nil, 275, + 275, nil, nil, 275, nil, nil, nil, nil, nil, 275, + nil, nil, nil, nil, nil, nil, nil, nil, 275, nil, + nil, nil, nil, 275, 275, 275, 275, nil, 275, 275, + 275, 275, nil, nil, nil, nil, 275, 275, nil, nil, + nil, 276, 276, 276, 275, 276, 275, 275, 275, 276, + 276, 275, 275, nil, 276, nil, 276, 276, 276, 276, + 276, 276, 276, nil, nil, nil, nil, nil, 276, 276, + 276, 276, 276, 276, 276, nil, nil, 276, nil, nil, + nil, nil, nil, nil, 276, nil, nil, 276, 276, 276, + 276, 276, 276, 276, 276, nil, 276, 276, 276, nil, + 276, 276, 276, 276, 276, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 276, nil, nil, 276, nil, nil, + 276, 276, nil, nil, 276, nil, nil, nil, nil, nil, + 276, nil, nil, nil, nil, nil, nil, nil, nil, 276, + nil, nil, nil, nil, 276, 276, 276, 276, nil, 276, + 276, 276, 276, nil, nil, nil, nil, 276, 276, nil, + nil, nil, 277, 277, 277, 276, 277, 276, 276, 276, + 277, 277, 276, 276, nil, 277, nil, 277, 277, 277, + 277, 277, 277, 277, nil, nil, nil, nil, nil, 277, + 277, 277, 277, 277, 277, 277, nil, nil, 277, nil, + nil, nil, nil, nil, nil, 277, nil, nil, 277, 277, + 277, 277, 277, 277, 277, 277, nil, 277, 277, 277, + nil, 277, 277, 277, 277, 277, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 277, nil, nil, 277, nil, + nil, 277, 277, nil, nil, 277, nil, nil, nil, nil, + nil, 277, nil, nil, nil, nil, nil, nil, nil, nil, + 277, nil, nil, nil, nil, 277, 277, 277, 277, nil, + 277, 277, 277, 277, nil, nil, nil, nil, 277, 277, + nil, nil, nil, 278, 278, 278, 277, 278, 277, 277, + 277, 278, 278, 277, 277, nil, 278, nil, 278, 278, + 278, 278, 278, 278, 278, nil, nil, nil, nil, nil, + 278, 278, 278, 278, 278, 278, 278, nil, nil, 278, + nil, nil, nil, nil, nil, nil, 278, nil, nil, 278, + 278, 278, 278, 278, 278, 278, 278, nil, 278, 278, + 278, nil, 278, 278, 278, 278, 278, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 278, nil, nil, 278, + nil, nil, 278, 278, nil, nil, 278, nil, nil, nil, + nil, nil, 278, nil, nil, nil, nil, nil, nil, nil, + nil, 278, nil, nil, nil, nil, 278, 278, 278, 278, + nil, 278, 278, 278, 278, nil, nil, nil, nil, 278, + 278, nil, nil, nil, 279, 279, 279, 278, 279, 278, + 278, 278, 279, 279, 278, 278, nil, 279, nil, 279, + 279, 279, 279, 279, 279, 279, nil, nil, nil, nil, + nil, 279, 279, 279, 279, 279, 279, 279, nil, nil, + 279, nil, nil, nil, nil, nil, nil, 279, nil, nil, + 279, 279, 279, 279, 279, 279, 279, 279, nil, 279, + 279, 279, nil, 279, 279, 279, 279, 279, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 279, nil, nil, + 279, nil, nil, 279, 279, nil, nil, 279, nil, nil, + nil, nil, nil, 279, nil, nil, nil, nil, nil, nil, + nil, nil, 279, nil, nil, nil, nil, 279, 279, 279, + 279, nil, 279, 279, 279, 279, nil, nil, nil, nil, + 279, 279, nil, nil, nil, 284, 284, 284, 279, 284, + 279, 279, 279, 284, 284, 279, 279, nil, 284, nil, + 284, 284, 284, 284, 284, 284, 284, nil, nil, nil, + nil, nil, 284, 284, 284, 284, 284, 284, 284, nil, + nil, 284, nil, nil, nil, nil, nil, nil, 284, nil, + nil, 284, 284, 284, 284, 284, 284, 284, 284, nil, + 284, 284, 284, nil, 284, 284, 284, 284, 284, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 284, nil, + nil, 284, nil, nil, 284, 284, nil, nil, 284, nil, + nil, nil, nil, nil, 284, nil, nil, nil, nil, nil, + nil, nil, nil, 284, nil, nil, nil, nil, 284, 284, + 284, 284, nil, 284, 284, 284, 284, nil, nil, nil, + nil, 284, 284, nil, nil, nil, 300, 300, 300, 284, + 300, 284, 284, 284, 300, 300, 284, 284, nil, 300, + nil, 300, 300, 300, 300, 300, 300, 300, nil, nil, + nil, nil, nil, 300, 300, 300, 300, 300, 300, 300, + nil, nil, 300, nil, nil, nil, nil, nil, nil, 300, + nil, nil, 300, 300, 300, 300, 300, 300, 300, 300, + nil, 300, 300, 300, nil, 300, 300, 300, 300, 300, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 300, + nil, nil, 300, nil, nil, 300, 300, nil, nil, 300, + nil, nil, nil, nil, nil, 300, nil, nil, nil, nil, + nil, nil, nil, nil, 300, nil, nil, nil, nil, 300, + 300, 300, 300, nil, 300, 300, 300, 300, nil, nil, + nil, nil, 300, 300, nil, nil, nil, 307, 307, 307, + 300, 307, 300, 300, 300, 307, 307, 300, 300, nil, + 307, nil, 307, 307, 307, 307, 307, 307, 307, nil, + nil, nil, nil, nil, 307, 307, 307, 307, 307, 307, + 307, nil, nil, 307, nil, nil, nil, nil, nil, nil, + 307, nil, nil, 307, 307, 307, 307, 307, 307, 307, + 307, 307, 307, 307, 307, nil, 307, 307, 307, 307, + 307, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 307, nil, nil, 307, nil, nil, 307, 307, nil, nil, + 307, nil, 307, nil, 307, nil, 307, nil, nil, 307, + nil, nil, nil, nil, nil, 307, nil, nil, nil, nil, + 307, 307, 307, 307, nil, 307, 307, 307, 307, nil, + nil, nil, nil, 307, 307, nil, nil, nil, 308, 308, + 308, 307, 308, 307, 307, 307, 308, 308, 307, 307, + nil, 308, nil, 308, 308, 308, 308, 308, 308, 308, + nil, nil, nil, nil, nil, 308, 308, 308, 308, 308, + 308, 308, nil, nil, 308, nil, nil, nil, nil, nil, + nil, 308, nil, nil, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, nil, 308, 308, 308, + 308, 308, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 308, nil, nil, 308, nil, nil, 308, 308, nil, + nil, 308, nil, 308, nil, 308, nil, 308, nil, nil, + 308, nil, nil, nil, nil, nil, 308, nil, nil, nil, + nil, 308, 308, 308, 308, nil, 308, 308, 308, 308, + nil, nil, nil, nil, 308, 308, nil, nil, nil, 316, + 316, 316, 308, 316, 308, 308, 308, 316, 316, 308, + 308, nil, 316, nil, 316, 316, 316, 316, 316, 316, + 316, nil, nil, nil, nil, nil, 316, 316, 316, 316, + 316, 316, 316, nil, nil, 316, nil, nil, nil, nil, + nil, nil, 316, nil, nil, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, nil, 316, 316, + 316, 316, 316, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 316, nil, nil, 316, nil, nil, 316, 316, + nil, nil, 316, nil, 316, nil, 316, nil, 316, nil, + nil, 316, nil, nil, nil, nil, nil, 316, nil, nil, + nil, nil, 316, 316, 316, 316, nil, 316, 316, 316, + 316, nil, nil, nil, nil, 316, 316, 316, nil, nil, + 323, 323, 323, 316, 323, 316, 316, 316, 323, 323, + 316, 316, nil, 323, nil, 323, 323, 323, 323, 323, + 323, 323, nil, nil, nil, nil, nil, 323, 323, 323, + 323, 323, 323, 323, nil, nil, 323, nil, nil, nil, + nil, nil, nil, 323, nil, nil, 323, 323, 323, 323, + 323, 323, 323, 323, nil, 323, 323, 323, nil, 323, + 323, 323, 323, 323, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 323, nil, nil, 323, nil, nil, 323, + 323, nil, nil, 323, nil, nil, nil, nil, nil, 323, + nil, nil, nil, nil, nil, nil, nil, nil, 323, nil, + nil, nil, nil, 323, 323, 323, 323, nil, 323, 323, + 323, 323, nil, nil, nil, nil, 323, 323, nil, nil, + nil, 326, 326, 326, 323, 326, 323, 323, 323, 326, + 326, 323, 323, nil, 326, nil, 326, 326, 326, 326, + 326, 326, 326, nil, nil, nil, nil, nil, 326, 326, + 326, 326, 326, 326, 326, nil, nil, 326, nil, nil, + nil, nil, nil, nil, 326, nil, nil, 326, 326, 326, + 326, 326, 326, 326, 326, nil, 326, 326, 326, nil, + 326, 326, 326, 326, 326, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 326, nil, nil, 326, nil, nil, + 326, 326, nil, nil, 326, nil, nil, nil, nil, nil, + 326, nil, nil, nil, nil, nil, nil, nil, nil, 326, + nil, nil, nil, nil, 326, 326, 326, 326, nil, 326, + 326, 326, 326, nil, nil, nil, nil, 326, 326, nil, + nil, nil, 329, 329, 329, 326, 329, 326, 326, 326, + 329, 329, 326, 326, nil, 329, nil, 329, 329, 329, + 329, 329, 329, 329, nil, nil, nil, nil, nil, 329, + 329, 329, 329, 329, 329, 329, nil, nil, 329, nil, + nil, nil, nil, nil, nil, 329, nil, nil, 329, 329, + 329, 329, 329, 329, 329, 329, nil, 329, 329, 329, + nil, 329, 329, 329, 329, 329, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 329, nil, nil, 329, nil, + nil, 329, 329, nil, nil, 329, nil, nil, nil, nil, + nil, 329, nil, nil, nil, nil, nil, nil, nil, nil, + 329, nil, nil, nil, nil, 329, 329, 329, 329, nil, + 329, 329, 329, 329, nil, nil, nil, nil, 329, 329, + nil, nil, nil, 330, 330, 330, 329, 330, 329, 329, + 329, 330, 330, 329, 329, nil, 330, nil, 330, 330, + 330, 330, 330, 330, 330, nil, nil, nil, nil, nil, + 330, 330, 330, 330, 330, 330, 330, nil, nil, 330, + nil, nil, nil, nil, nil, nil, 330, nil, nil, 330, + 330, 330, 330, 330, 330, 330, 330, nil, 330, 330, + 330, nil, 330, 330, 330, 330, 330, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 330, nil, nil, 330, + nil, nil, 330, 330, nil, nil, 330, nil, nil, nil, + nil, nil, 330, nil, nil, nil, nil, nil, nil, nil, + nil, 330, nil, nil, nil, nil, 330, 330, 330, 330, + nil, 330, 330, 330, 330, nil, nil, nil, nil, 330, + 330, nil, nil, nil, nil, nil, nil, 330, nil, 330, + 330, 330, nil, nil, 330, 330, 335, 335, 335, 335, + 335, nil, nil, nil, 335, 335, nil, nil, nil, 335, + nil, 335, 335, 335, 335, 335, 335, 335, nil, nil, + nil, nil, nil, 335, 335, 335, 335, 335, 335, 335, + nil, nil, 335, nil, nil, nil, nil, nil, 335, 335, + nil, 335, 335, 335, 335, 335, 335, 335, 335, 335, + nil, 335, 335, 335, nil, 335, 335, 335, 335, 335, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 335, + nil, nil, 335, nil, nil, 335, 335, nil, nil, 335, + nil, 335, nil, nil, nil, 335, nil, nil, nil, nil, + nil, nil, nil, nil, 335, nil, nil, nil, nil, 335, + 335, 335, 335, nil, 335, 335, 335, 335, nil, nil, + nil, nil, 335, 335, nil, nil, nil, 371, 371, 371, + 335, 371, 335, 335, 335, 371, 371, 335, 335, nil, + 371, nil, 371, 371, 371, 371, 371, 371, 371, nil, + nil, nil, nil, nil, 371, 371, 371, 371, 371, 371, + 371, nil, nil, 371, nil, nil, nil, nil, nil, nil, + 371, nil, nil, 371, 371, 371, 371, 371, 371, 371, + 371, nil, 371, 371, 371, nil, 371, 371, 371, 371, + 371, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 371, nil, nil, 371, nil, nil, 371, 371, nil, nil, + 371, nil, nil, nil, nil, nil, 371, nil, nil, nil, + nil, nil, nil, nil, nil, 371, nil, nil, nil, nil, + 371, 371, 371, 371, nil, 371, 371, 371, 371, nil, + nil, nil, nil, 371, 371, nil, nil, nil, 387, 387, + 387, 371, 387, 371, 371, 371, 387, 387, 371, 371, + nil, 387, nil, 387, 387, 387, 387, 387, 387, 387, + nil, nil, nil, nil, nil, 387, 387, 387, 387, 387, + 387, 387, nil, nil, 387, nil, nil, nil, nil, nil, + nil, 387, nil, nil, 387, 387, 387, 387, 387, 387, + 387, 387, nil, 387, 387, 387, nil, 387, 387, 387, + 387, 387, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 387, nil, nil, 387, nil, nil, 387, 387, nil, + nil, 387, nil, nil, nil, nil, nil, 387, nil, nil, + nil, nil, nil, nil, nil, nil, 387, nil, nil, nil, + nil, 387, 387, 387, 387, nil, 387, 387, 387, 387, + nil, nil, nil, nil, 387, 387, nil, nil, nil, 408, + 408, 408, 387, 408, 387, 387, 387, 408, 408, 387, + 387, nil, 408, nil, 408, 408, 408, 408, 408, 408, + 408, nil, nil, nil, nil, nil, 408, 408, 408, 408, + 408, 408, 408, nil, nil, 408, nil, nil, nil, nil, + nil, nil, 408, nil, nil, 408, 408, 408, 408, 408, + 408, 408, 408, nil, 408, 408, 408, nil, 408, 408, + 408, 408, 408, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 408, nil, nil, 408, nil, nil, 408, 408, + nil, nil, 408, nil, nil, nil, nil, nil, 408, nil, + nil, nil, nil, nil, nil, nil, nil, 408, nil, nil, + nil, nil, 408, 408, 408, 408, nil, 408, 408, 408, + 408, nil, nil, nil, nil, 408, 408, nil, nil, nil, + 438, 438, 438, 408, 438, 408, 408, 408, 438, 438, + 408, 408, nil, 438, nil, 438, 438, 438, 438, 438, + 438, 438, nil, nil, nil, nil, nil, 438, 438, 438, + 438, 438, 438, 438, nil, nil, 438, nil, nil, nil, + nil, nil, nil, 438, nil, nil, 438, 438, 438, 438, + 438, 438, 438, 438, nil, 438, 438, 438, nil, 438, + 438, 438, 438, 438, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 438, nil, nil, 438, nil, nil, 438, + 438, nil, nil, 438, nil, nil, nil, nil, nil, 438, + nil, nil, nil, nil, nil, nil, nil, nil, 438, nil, + nil, nil, nil, 438, 438, 438, 438, nil, 438, 438, + 438, 438, nil, nil, nil, nil, 438, 438, nil, nil, + nil, nil, nil, nil, 438, nil, 438, 438, 438, 461, + nil, 438, 438, nil, nil, nil, 461, 461, 461, nil, + nil, 461, 461, 461, nil, 461, nil, nil, nil, nil, + nil, nil, nil, 461, 461, 461, 461, nil, nil, nil, + nil, nil, nil, nil, nil, 461, 461, nil, 461, 461, + 461, 461, 461, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 461, 461, 461, 461, 461, + 461, 461, 461, 461, 461, 461, 461, 461, 461, nil, + nil, 461, 461, 461, nil, nil, 461, nil, 461, 461, + nil, nil, 461, 461, nil, 461, nil, 461, nil, 461, + nil, 461, 461, nil, 461, 461, 461, 461, 461, nil, + 461, 461, 461, 1106, nil, 1106, 1106, 1106, 1106, 1106, + nil, nil, nil, nil, nil, nil, 461, nil, 1106, 461, + 461, 471, 461, nil, 461, nil, nil, nil, 471, 471, + 471, 461, nil, 471, 471, 471, nil, 471, nil, nil, + 1106, nil, nil, nil, nil, 471, 471, 471, 471, 471, + nil, 1106, 1106, nil, nil, nil, 1106, 471, 471, nil, + 471, 471, 471, 471, 471, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, nil, nil, 471, 471, 471, nil, nil, 471, nil, + nil, 471, nil, nil, 471, 471, nil, 471, nil, 471, + nil, 471, nil, 471, 471, nil, 471, 471, 471, 471, + 471, nil, 471, 471, 471, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 471, nil, + nil, 471, 471, 471, 471, nil, 471, 472, 471, nil, + nil, nil, nil, 471, 472, 472, 472, nil, nil, 472, + 472, 472, nil, 472, nil, nil, nil, nil, nil, nil, + nil, 472, 472, 472, 472, 472, nil, nil, nil, nil, + nil, nil, nil, 472, 472, nil, 472, 472, 472, 472, + 472, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, nil, nil, 472, + 472, 472, nil, nil, 472, nil, nil, 472, nil, nil, + 472, 472, nil, 472, nil, 472, nil, 472, nil, 472, + 472, nil, 472, 472, 472, 472, 472, nil, 472, 472, + 472, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 472, nil, nil, 472, 472, 472, + 472, nil, 472, nil, 472, nil, 473, 473, 473, 472, + 473, nil, nil, nil, 473, 473, nil, nil, nil, 473, + nil, 473, 473, 473, 473, 473, 473, 473, nil, nil, + nil, nil, nil, 473, 473, 473, 473, 473, 473, 473, + nil, nil, 473, nil, nil, nil, nil, nil, nil, 473, + nil, nil, 473, 473, 473, 473, 473, 473, 473, 473, + nil, 473, 473, 473, nil, 473, 473, 473, 473, 473, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 473, + nil, nil, 473, nil, nil, 473, 473, nil, nil, 473, + nil, nil, nil, nil, nil, 473, nil, nil, nil, nil, + nil, nil, nil, nil, 473, nil, nil, nil, nil, 473, + 473, 473, 473, nil, 473, 473, 473, 473, nil, nil, + nil, nil, 473, 473, nil, nil, nil, 500, 500, 500, + 473, 500, 473, 473, 473, 500, 500, 473, 473, nil, + 500, nil, 500, 500, 500, 500, 500, 500, 500, nil, + nil, nil, nil, nil, 500, 500, 500, 500, 500, 500, + 500, nil, nil, 500, nil, nil, nil, nil, nil, nil, + 500, nil, nil, 500, 500, 500, 500, 500, 500, 500, + 500, nil, 500, 500, 500, nil, 500, 500, 500, 500, + 500, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 500, nil, nil, 500, nil, nil, 500, 500, nil, nil, + 500, nil, nil, nil, nil, nil, 500, nil, nil, nil, + nil, nil, nil, nil, nil, 500, nil, nil, nil, nil, + 500, 500, 500, 500, nil, 500, 500, 500, 500, nil, + nil, nil, nil, 500, 500, nil, nil, nil, 513, 513, + 513, 500, 513, 500, 500, 500, 513, 513, 500, 500, + nil, 513, nil, 513, 513, 513, 513, 513, 513, 513, + nil, nil, nil, nil, nil, 513, 513, 513, 513, 513, + 513, 513, nil, nil, 513, nil, nil, nil, nil, nil, + nil, 513, nil, nil, 513, 513, 513, 513, 513, 513, + 513, 513, nil, 513, 513, 513, nil, 513, 513, 513, + 513, 513, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 513, nil, nil, 513, nil, nil, 513, 513, nil, + nil, 513, nil, nil, nil, nil, nil, 513, nil, nil, + nil, nil, nil, nil, nil, nil, 513, nil, nil, nil, + nil, 513, 513, 513, 513, nil, 513, 513, 513, 513, + nil, nil, nil, nil, 513, 513, nil, nil, nil, 523, + 523, 523, 513, 523, 513, 513, 513, 523, 523, 513, + 513, nil, 523, nil, 523, 523, 523, 523, 523, 523, + 523, nil, nil, nil, nil, nil, 523, 523, 523, 523, + 523, 523, 523, nil, nil, 523, nil, nil, nil, nil, + nil, nil, 523, nil, nil, 523, 523, 523, 523, 523, + 523, 523, 523, 523, 523, 523, 523, nil, 523, 523, + 523, 523, 523, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 523, nil, nil, 523, nil, nil, 523, 523, + nil, nil, 523, nil, 523, nil, 523, nil, 523, nil, + nil, 523, nil, nil, nil, nil, nil, 523, nil, nil, + nil, nil, 523, 523, 523, 523, nil, 523, 523, 523, + 523, nil, nil, nil, nil, 523, 523, nil, nil, nil, + 525, 525, 525, 523, 525, 523, 523, 523, 525, 525, + 523, 523, nil, 525, nil, 525, 525, 525, 525, 525, + 525, 525, nil, nil, nil, nil, nil, 525, 525, 525, + 525, 525, 525, 525, nil, nil, 525, nil, nil, nil, + nil, nil, nil, 525, nil, nil, 525, 525, 525, 525, + 525, 525, 525, 525, nil, 525, 525, 525, nil, 525, + 525, 525, 525, 525, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 525, nil, nil, 525, nil, nil, 525, + 525, nil, nil, 525, nil, nil, nil, nil, nil, 525, + nil, nil, nil, nil, nil, nil, nil, nil, 525, nil, + nil, nil, nil, 525, 525, 525, 525, nil, 525, 525, + 525, 525, nil, nil, nil, nil, 525, 525, nil, nil, + nil, 526, 526, 526, 525, 526, 525, 525, 525, 526, + 526, 525, 525, nil, 526, nil, 526, 526, 526, 526, + 526, 526, 526, nil, nil, nil, nil, nil, 526, 526, + 526, 526, 526, 526, 526, nil, nil, 526, nil, nil, + nil, nil, nil, nil, 526, nil, nil, 526, 526, 526, + 526, 526, 526, 526, 526, nil, 526, 526, 526, nil, + 526, 526, 526, 526, 526, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 526, nil, nil, 526, nil, nil, + 526, 526, nil, nil, 526, nil, nil, nil, nil, nil, + 526, nil, nil, nil, nil, nil, nil, nil, nil, 526, + nil, nil, nil, nil, 526, 526, 526, 526, nil, 526, + 526, 526, 526, nil, nil, nil, nil, 526, 526, nil, + nil, nil, 527, 527, 527, 526, 527, 526, 526, 526, + 527, 527, 526, 526, nil, 527, nil, 527, 527, 527, + 527, 527, 527, 527, nil, nil, nil, nil, nil, 527, + 527, 527, 527, 527, 527, 527, nil, nil, 527, nil, + nil, nil, nil, nil, nil, 527, nil, nil, 527, 527, + 527, 527, 527, 527, 527, 527, nil, 527, 527, 527, + nil, 527, 527, 527, 527, 527, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 527, nil, nil, 527, nil, + nil, 527, 527, nil, nil, 527, nil, nil, nil, nil, + nil, 527, nil, nil, nil, nil, nil, nil, nil, nil, + 527, nil, nil, nil, nil, 527, 527, 527, 527, nil, + 527, 527, 527, 527, nil, nil, nil, nil, 527, 527, + nil, nil, nil, nil, nil, nil, 527, nil, 527, 527, + 527, 559, nil, 527, 527, nil, nil, nil, 559, 559, + 559, nil, nil, 559, 559, 559, 235, 559, 235, 235, + 235, 235, 235, nil, nil, 559, 559, 559, nil, nil, + nil, 235, nil, nil, nil, nil, nil, 559, 559, nil, + 559, 559, 559, 559, 559, nil, 410, nil, 410, 410, + 410, 410, 410, 235, nil, nil, nil, nil, nil, nil, + nil, 410, 235, 235, 235, 235, nil, nil, nil, 235, + nil, 1101, nil, 1101, 1101, 1101, 1101, 1101, 559, nil, + nil, nil, nil, 410, 410, 559, 1101, nil, nil, nil, + 559, 559, 410, 410, 410, 410, nil, nil, nil, 410, + nil, nil, nil, nil, nil, nil, nil, nil, 1101, 235, + nil, nil, nil, 559, 559, nil, nil, 1101, 1101, 1101, + 1101, nil, nil, nil, 1101, nil, nil, nil, 559, nil, + nil, 559, nil, 564, 564, 564, 559, 564, nil, 410, + nil, 564, 564, 559, nil, nil, 564, nil, 564, 564, + 564, 564, 564, 564, 564, nil, nil, nil, nil, nil, + 564, 564, 564, 564, 564, 564, 564, nil, nil, 564, + nil, nil, nil, nil, nil, nil, 564, nil, nil, 564, + 564, 564, 564, 564, 564, 564, 564, nil, 564, 564, + 564, nil, 564, 564, 564, 564, 564, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 564, nil, nil, 564, + nil, nil, 564, 564, nil, nil, 564, nil, nil, nil, + nil, nil, 564, nil, nil, nil, nil, nil, nil, nil, + nil, 564, nil, nil, nil, nil, 564, 564, 564, 564, + nil, 564, 564, 564, 564, nil, nil, nil, nil, 564, + 564, nil, nil, nil, 574, 574, 574, 564, 574, 564, + 564, 564, 574, 574, 564, 564, nil, 574, nil, 574, + 574, 574, 574, 574, 574, 574, nil, nil, nil, nil, + nil, 574, 574, 574, 574, 574, 574, 574, nil, nil, + 574, nil, nil, nil, nil, nil, nil, 574, nil, nil, + 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, + 574, 574, nil, 574, 574, 574, 574, 574, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 574, nil, nil, + 574, nil, nil, 574, 574, nil, nil, 574, nil, 574, + nil, 574, nil, 574, nil, nil, 574, nil, nil, nil, + nil, nil, 574, nil, nil, nil, nil, 574, 574, 574, + 574, nil, 574, 574, 574, 574, nil, nil, nil, nil, + 574, 574, nil, nil, nil, 576, 576, 576, 574, 576, + 574, 574, 574, 576, 576, 574, 574, nil, 576, nil, + 576, 576, 576, 576, 576, 576, 576, nil, nil, nil, + nil, nil, 576, 576, 576, 576, 576, 576, 576, nil, + nil, 576, nil, nil, nil, nil, nil, nil, 576, nil, + nil, 576, 576, 576, 576, 576, 576, 576, 576, 576, + 576, 576, 576, nil, 576, 576, 576, 576, 576, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 576, nil, + nil, 576, nil, nil, 576, 576, nil, nil, 576, nil, + nil, nil, 576, nil, 576, nil, nil, 576, nil, nil, + nil, nil, nil, 576, nil, nil, nil, nil, 576, 576, + 576, 576, nil, 576, 576, 576, 576, nil, nil, nil, + nil, 576, 576, nil, nil, nil, 578, 578, 578, 576, + 578, 576, 576, 576, 578, 578, 576, 576, nil, 578, + nil, 578, 578, 578, 578, 578, 578, 578, nil, nil, + nil, nil, nil, 578, 578, 578, 578, 578, 578, 578, + nil, nil, 578, nil, nil, nil, nil, nil, nil, 578, + nil, nil, 578, 578, 578, 578, 578, 578, 578, 578, + nil, 578, 578, 578, nil, 578, 578, 578, 578, 578, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 578, + nil, nil, 578, nil, nil, 578, 578, nil, nil, 578, + nil, nil, nil, nil, nil, 578, nil, nil, nil, nil, + nil, nil, nil, nil, 578, nil, nil, nil, nil, 578, + 578, 578, 578, nil, 578, 578, 578, 578, nil, nil, + nil, nil, 578, 578, nil, nil, nil, nil, nil, nil, + 578, nil, 578, 578, 578, nil, nil, 578, 578, 584, + 584, 584, 584, 584, nil, nil, nil, 584, 584, nil, + nil, nil, 584, nil, 584, 584, 584, 584, 584, 584, + 584, nil, nil, nil, nil, nil, 584, 584, 584, 584, + 584, 584, 584, nil, nil, 584, nil, nil, nil, nil, + nil, 584, 584, 584, 584, 584, 584, 584, 584, 584, + 584, 584, 584, nil, 584, 584, 584, nil, 584, 584, + 584, 584, 584, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 584, nil, nil, 584, nil, nil, 584, 584, + nil, nil, 584, nil, 584, nil, nil, nil, 584, nil, + nil, nil, nil, nil, nil, nil, nil, 584, nil, nil, + nil, nil, 584, 584, 584, 584, nil, 584, 584, 584, + 584, nil, nil, nil, nil, 584, 584, nil, nil, nil, + nil, nil, 584, 584, nil, 584, 584, 584, nil, nil, + 584, 584, 594, 594, 594, nil, 594, nil, nil, nil, + 594, 594, nil, nil, nil, 594, nil, 594, 594, 594, + 594, 594, 594, 594, nil, nil, nil, nil, nil, 594, + 594, 594, 594, 594, 594, 594, nil, nil, 594, nil, + nil, nil, nil, nil, nil, 594, nil, nil, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + nil, 594, 594, 594, 594, 594, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 594, nil, nil, 594, nil, + nil, 594, 594, nil, nil, 594, nil, 594, nil, 594, + nil, 594, nil, nil, 594, nil, nil, nil, nil, nil, + 594, nil, nil, nil, nil, 594, 594, 594, 594, nil, + 594, 594, 594, 594, nil, nil, nil, nil, 594, 594, + nil, nil, nil, 604, 604, 604, 594, 604, 594, 594, + 594, 604, 604, 594, 594, nil, 604, nil, 604, 604, + 604, 604, 604, 604, 604, nil, nil, nil, nil, nil, + 604, 604, 604, 604, 604, 604, 604, nil, nil, 604, + nil, nil, nil, nil, nil, nil, 604, nil, nil, 604, + 604, 604, 604, 604, 604, 604, 604, nil, 604, 604, + 604, nil, 604, 604, 604, 604, 604, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 604, nil, nil, 604, + nil, nil, 604, 604, nil, nil, 604, nil, nil, nil, + nil, nil, 604, nil, nil, nil, nil, nil, nil, nil, + nil, 604, nil, nil, nil, nil, 604, 604, 604, 604, + nil, 604, 604, 604, 604, nil, nil, nil, nil, 604, + 604, nil, nil, nil, 607, 607, 607, 604, 607, 604, + 604, 604, 607, 607, 604, 604, nil, 607, nil, 607, + 607, 607, 607, 607, 607, 607, nil, nil, nil, nil, + nil, 607, 607, 607, 607, 607, 607, 607, nil, nil, + 607, nil, nil, nil, nil, nil, nil, 607, nil, nil, + 607, 607, 607, 607, 607, 607, 607, 607, nil, 607, + 607, 607, nil, 607, 607, 607, 607, 607, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 607, nil, nil, + 607, nil, nil, 607, 607, nil, nil, 607, nil, nil, + nil, nil, nil, 607, nil, nil, nil, nil, nil, nil, + nil, nil, 607, nil, nil, nil, nil, 607, 607, 607, + 607, nil, 607, 607, 607, 607, nil, nil, nil, nil, + 607, 607, nil, nil, nil, 609, 609, 609, 607, 609, + 607, 607, 607, 609, 609, 607, 607, nil, 609, nil, + 609, 609, 609, 609, 609, 609, 609, nil, nil, nil, + nil, nil, 609, 609, 609, 609, 609, 609, 609, nil, + nil, 609, nil, nil, nil, nil, nil, nil, 609, nil, + nil, 609, 609, 609, 609, 609, 609, 609, 609, nil, + 609, 609, 609, nil, 609, 609, 609, 609, 609, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 609, nil, + nil, 609, nil, nil, 609, 609, nil, nil, 609, nil, + nil, nil, nil, nil, 609, nil, nil, nil, nil, nil, + nil, nil, nil, 609, nil, nil, nil, nil, 609, 609, + 609, 609, nil, 609, 609, 609, 609, nil, nil, nil, + nil, 609, 609, nil, nil, nil, 615, 615, 615, 609, + 615, 609, 609, 609, 615, 615, 609, 609, nil, 615, + nil, 615, 615, 615, 615, 615, 615, 615, nil, nil, + nil, nil, nil, 615, 615, 615, 615, 615, 615, 615, + nil, nil, 615, nil, nil, nil, nil, nil, nil, 615, + nil, nil, 615, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615, 615, nil, 615, 615, 615, 615, 615, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 615, + nil, nil, 615, nil, nil, 615, 615, nil, nil, 615, + nil, 615, nil, nil, nil, 615, nil, nil, 615, nil, + nil, nil, nil, nil, 615, nil, nil, nil, nil, 615, + 615, 615, 615, nil, 615, 615, 615, 615, nil, nil, + nil, nil, 615, 615, nil, nil, nil, 618, 618, 618, + 615, 618, 615, 615, 615, 618, 618, 615, 615, nil, + 618, nil, 618, 618, 618, 618, 618, 618, 618, nil, + nil, nil, nil, nil, 618, 618, 618, 618, 618, 618, + 618, nil, nil, 618, nil, nil, nil, nil, nil, nil, + 618, nil, nil, 618, 618, 618, 618, 618, 618, 618, + 618, 618, 618, 618, 618, nil, 618, 618, 618, 618, + 618, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 618, nil, nil, 618, nil, nil, 618, 618, nil, nil, + 618, nil, nil, nil, nil, nil, 618, nil, nil, 618, + nil, nil, nil, nil, nil, 618, nil, nil, nil, nil, + 618, 618, 618, 618, nil, 618, 618, 618, 618, nil, + nil, nil, nil, 618, 618, nil, nil, nil, 631, 631, + 631, 618, 631, 618, 618, 618, 631, 631, 618, 618, + nil, 631, nil, 631, 631, 631, 631, 631, 631, 631, + nil, nil, nil, nil, nil, 631, 631, 631, 631, 631, + 631, 631, nil, nil, 631, nil, nil, nil, nil, nil, + nil, 631, nil, nil, 631, 631, 631, 631, 631, 631, + 631, 631, nil, 631, 631, 631, nil, 631, 631, 631, + 631, 631, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 631, nil, nil, 631, nil, nil, 631, 631, nil, + nil, 631, nil, 631, nil, nil, nil, 631, nil, nil, + nil, nil, nil, nil, nil, nil, 631, nil, nil, nil, + nil, 631, 631, 631, 631, nil, 631, 631, 631, 631, + nil, nil, nil, nil, 631, 631, nil, nil, nil, 632, + 632, 632, 631, 632, 631, 631, 631, 632, 632, 631, + 631, nil, 632, nil, 632, 632, 632, 632, 632, 632, + 632, nil, nil, nil, nil, nil, 632, 632, 632, 632, + 632, 632, 632, nil, nil, 632, nil, nil, nil, nil, + nil, nil, 632, nil, nil, 632, 632, 632, 632, 632, + 632, 632, 632, 632, 632, 632, 632, nil, 632, 632, + 632, 632, 632, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 632, nil, nil, 632, nil, nil, 632, 632, + nil, nil, 632, nil, 632, nil, 632, nil, 632, nil, + nil, 632, nil, nil, nil, nil, nil, 632, nil, nil, + nil, nil, 632, 632, 632, 632, nil, 632, 632, 632, + 632, nil, nil, nil, nil, 632, 632, nil, nil, nil, + 642, 642, 642, 632, 642, 632, 632, 632, 642, 642, + 632, 632, nil, 642, nil, 642, 642, 642, 642, 642, + 642, 642, nil, nil, nil, nil, nil, 642, 642, 642, + 642, 642, 642, 642, nil, nil, 642, nil, nil, nil, + nil, nil, nil, 642, nil, nil, 642, 642, 642, 642, + 642, 642, 642, 642, 642, 642, 642, 642, nil, 642, + 642, 642, 642, 642, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 642, nil, nil, 642, nil, nil, 642, + 642, nil, nil, 642, nil, 642, nil, 642, nil, 642, + nil, nil, 642, nil, nil, nil, nil, nil, 642, nil, + nil, nil, nil, 642, 642, 642, 642, nil, 642, 642, + 642, 642, nil, nil, nil, nil, 642, 642, nil, nil, + nil, nil, nil, nil, 642, nil, 642, 642, 642, nil, + nil, 642, 642, 673, 673, 673, 673, 673, nil, nil, + nil, 673, 673, nil, nil, nil, 673, nil, 673, 673, + 673, 673, 673, 673, 673, nil, nil, nil, nil, nil, + 673, 673, 673, 673, 673, 673, 673, nil, nil, 673, + nil, nil, nil, nil, nil, 673, 673, nil, 673, 673, + 673, 673, 673, 673, 673, 673, 673, nil, 673, 673, + 673, nil, 673, 673, 673, 673, 673, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 673, nil, nil, 673, + nil, nil, 673, 673, nil, nil, 673, nil, 673, nil, + nil, nil, 673, nil, nil, nil, nil, nil, nil, nil, + nil, 673, nil, nil, nil, nil, 673, 673, 673, 673, + nil, 673, 673, 673, 673, nil, nil, nil, nil, 673, + 673, nil, nil, nil, 674, 674, 674, 673, 674, 673, + 673, 673, 674, 674, 673, 673, nil, 674, nil, 674, + 674, 674, 674, 674, 674, 674, nil, nil, nil, nil, + nil, 674, 674, 674, 674, 674, 674, 674, nil, nil, + 674, nil, nil, nil, nil, nil, nil, 674, nil, nil, + 674, 674, 674, 674, 674, 674, 674, 674, nil, 674, + 674, 674, nil, 674, 674, 674, 674, 674, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 674, nil, nil, + 674, nil, nil, 674, 674, nil, nil, 674, nil, 674, + nil, nil, nil, 674, nil, nil, nil, nil, nil, nil, + nil, nil, 674, nil, nil, nil, nil, 674, 674, 674, + 674, nil, 674, 674, 674, 674, nil, nil, nil, nil, + 674, 674, nil, nil, nil, 676, 676, 676, 674, 676, + 674, 674, 674, 676, 676, 674, 674, nil, 676, nil, + 676, 676, 676, 676, 676, 676, 676, nil, nil, nil, + nil, nil, 676, 676, 676, 676, 676, 676, 676, nil, + nil, 676, nil, nil, nil, nil, nil, nil, 676, nil, + nil, 676, 676, 676, 676, 676, 676, 676, 676, nil, + 676, 676, 676, nil, 676, 676, 676, 676, 676, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 676, nil, + nil, 676, nil, nil, 676, 676, nil, nil, 676, nil, + nil, nil, nil, nil, 676, nil, nil, nil, nil, nil, + nil, nil, nil, 676, nil, nil, nil, nil, 676, 676, + 676, 676, nil, 676, 676, 676, 676, nil, nil, nil, + nil, 676, 676, nil, nil, nil, 677, 677, 677, 676, + 677, 676, 676, 676, 677, 677, 676, 676, nil, 677, + nil, 677, 677, 677, 677, 677, 677, 677, nil, nil, + nil, nil, nil, 677, 677, 677, 677, 677, 677, 677, + nil, nil, 677, nil, nil, nil, nil, nil, nil, 677, + nil, nil, 677, 677, 677, 677, 677, 677, 677, 677, + 677, 677, 677, 677, nil, 677, 677, 677, 677, 677, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 677, + nil, nil, 677, nil, nil, 677, 677, nil, nil, 677, + nil, 677, nil, 677, nil, 677, nil, nil, 677, nil, + nil, nil, nil, nil, 677, nil, nil, nil, nil, 677, + 677, 677, 677, nil, 677, 677, 677, 677, nil, nil, + nil, nil, 677, 677, nil, nil, nil, nil, nil, nil, + 677, nil, 677, 677, 677, nil, nil, 677, 677, 680, + 680, 680, 680, 680, nil, nil, nil, 680, 680, nil, + nil, nil, 680, nil, 680, 680, 680, 680, 680, 680, + 680, nil, nil, nil, nil, nil, 680, 680, 680, 680, + 680, 680, 680, nil, nil, 680, nil, nil, nil, nil, + nil, 680, 680, nil, 680, 680, 680, 680, 680, 680, + 680, 680, 680, nil, 680, 680, 680, nil, 680, 680, + 680, 680, 680, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 680, nil, nil, 680, nil, nil, 680, 680, + nil, nil, 680, nil, 680, nil, nil, nil, 680, nil, + nil, nil, nil, nil, nil, nil, nil, 680, nil, nil, + nil, nil, 680, 680, 680, 680, nil, 680, 680, 680, + 680, nil, nil, nil, nil, 680, 680, nil, nil, nil, + 681, 681, 681, 680, 681, 680, 680, 680, 681, 681, + 680, 680, nil, 681, nil, 681, 681, 681, 681, 681, + 681, 681, nil, nil, nil, nil, nil, 681, 681, 681, + 681, 681, 681, 681, nil, nil, 681, nil, nil, nil, + nil, nil, nil, 681, nil, nil, 681, 681, 681, 681, + 681, 681, 681, 681, nil, 681, 681, 681, nil, 681, + 681, 681, 681, 681, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 681, nil, nil, 681, nil, nil, 681, + 681, nil, nil, 681, nil, nil, nil, nil, nil, 681, + nil, nil, nil, nil, nil, nil, nil, nil, 681, nil, + nil, nil, nil, 681, 681, 681, 681, nil, 681, 681, + 681, 681, nil, nil, nil, nil, 681, 681, nil, nil, + nil, 684, 684, 684, 681, 684, 681, 681, 681, 684, + 684, 681, 681, nil, 684, nil, 684, 684, 684, 684, + 684, 684, 684, nil, nil, nil, nil, nil, 684, 684, + 684, 684, 684, 684, 684, nil, nil, 684, nil, nil, + nil, nil, nil, nil, 684, nil, nil, 684, 684, 684, + 684, 684, 684, 684, 684, 684, 684, 684, 684, nil, + 684, 684, 684, 684, 684, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 684, nil, nil, 684, nil, nil, + 684, 684, nil, nil, 684, nil, 684, nil, 684, nil, + 684, nil, nil, 684, nil, nil, nil, nil, nil, 684, + nil, nil, nil, nil, 684, 684, 684, 684, nil, 684, + 684, 684, 684, nil, nil, nil, nil, 684, 684, nil, + nil, nil, 685, 685, 685, 684, 685, 684, 684, 684, + 685, 685, 684, 684, nil, 685, nil, 685, 685, 685, + 685, 685, 685, 685, nil, nil, nil, nil, nil, 685, + 685, 685, 685, 685, 685, 685, nil, nil, 685, nil, + nil, nil, nil, nil, nil, 685, nil, nil, 685, 685, + 685, 685, 685, 685, 685, 685, 685, 685, 685, 685, + nil, 685, 685, 685, 685, 685, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 685, nil, nil, 685, nil, + nil, 685, 685, nil, nil, 685, nil, nil, nil, 685, + nil, 685, nil, nil, 685, nil, nil, nil, nil, nil, + 685, nil, nil, nil, nil, 685, 685, 685, 685, nil, + 685, 685, 685, 685, nil, nil, nil, nil, 685, 685, + nil, nil, nil, 686, 686, 686, 685, 686, 685, 685, + 685, 686, 686, 685, 685, nil, 686, nil, 686, 686, + 686, 686, 686, 686, 686, nil, nil, nil, nil, nil, + 686, 686, 686, 686, 686, 686, 686, nil, nil, 686, + nil, nil, nil, nil, nil, nil, 686, nil, nil, 686, + 686, 686, 686, 686, 686, 686, 686, nil, 686, 686, + 686, nil, 686, 686, 686, 686, 686, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 686, nil, nil, 686, + nil, nil, 686, 686, nil, nil, 686, nil, nil, nil, + nil, nil, 686, nil, nil, nil, nil, nil, nil, nil, + nil, 686, nil, nil, nil, nil, 686, 686, 686, 686, + nil, 686, 686, 686, 686, nil, nil, nil, nil, 686, + 686, nil, nil, nil, 687, 687, 687, 686, 687, 686, + 686, 686, 687, 687, 686, 686, nil, 687, nil, 687, + 687, 687, 687, 687, 687, 687, nil, nil, nil, nil, + nil, 687, 687, 687, 687, 687, 687, 687, nil, nil, + 687, nil, nil, nil, nil, nil, nil, 687, nil, nil, + 687, 687, 687, 687, 687, 687, 687, 687, nil, 687, + 687, 687, nil, 687, 687, 687, 687, 687, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 687, nil, nil, + 687, nil, nil, 687, 687, nil, nil, 687, nil, nil, + nil, nil, nil, 687, nil, nil, nil, nil, nil, nil, + nil, nil, 687, nil, nil, nil, nil, 687, 687, 687, + 687, nil, 687, 687, 687, 687, nil, nil, nil, nil, + 687, 687, nil, nil, nil, 691, 691, 691, 687, 691, + 687, 687, 687, 691, 691, 687, 687, nil, 691, nil, + 691, 691, 691, 691, 691, 691, 691, nil, nil, nil, + nil, nil, 691, 691, 691, 691, 691, 691, 691, nil, + nil, 691, nil, nil, nil, nil, nil, nil, 691, nil, + nil, 691, 691, 691, 691, 691, 691, 691, 691, nil, + 691, 691, 691, nil, 691, 691, 691, 691, 691, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 691, nil, + nil, 691, nil, nil, 691, 691, nil, nil, 691, nil, + nil, nil, nil, nil, 691, nil, nil, nil, nil, nil, + nil, nil, nil, 691, nil, nil, nil, nil, 691, 691, + 691, 691, nil, 691, 691, 691, 691, nil, nil, nil, + nil, 691, 691, nil, nil, nil, 693, 693, 693, 691, + 693, 691, 691, 691, 693, 693, 691, 691, nil, 693, + nil, 693, 693, 693, 693, 693, 693, 693, nil, nil, + nil, nil, nil, 693, 693, 693, 693, 693, 693, 693, + nil, nil, 693, nil, nil, nil, nil, nil, nil, 693, + nil, nil, 693, 693, 693, 693, 693, 693, 693, 693, + nil, 693, 693, 693, nil, 693, 693, 693, 693, 693, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 693, + nil, nil, 693, nil, nil, 693, 693, nil, nil, 693, + nil, nil, nil, nil, nil, 693, nil, nil, nil, nil, + nil, nil, nil, nil, 693, nil, nil, nil, nil, 693, + 693, 693, 693, nil, 693, 693, 693, 693, nil, nil, + nil, nil, 693, 693, nil, nil, nil, 702, 702, 702, + 693, 702, 693, 693, 693, 702, 702, 693, 693, nil, + 702, nil, 702, 702, 702, 702, 702, 702, 702, nil, + nil, nil, nil, nil, 702, 702, 702, 702, 702, 702, + 702, nil, nil, 702, nil, nil, nil, nil, nil, nil, + 702, nil, nil, 702, 702, 702, 702, 702, 702, 702, + 702, nil, 702, 702, 702, nil, 702, 702, 702, 702, + 702, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 702, nil, nil, 702, nil, nil, 702, 702, nil, nil, + 702, nil, 702, nil, nil, nil, 702, nil, nil, nil, + nil, nil, nil, nil, nil, 702, nil, nil, nil, nil, + 702, 702, 702, 702, nil, 702, 702, 702, 702, nil, + nil, nil, nil, 702, 702, nil, nil, nil, 718, 718, + 718, 702, 718, 702, 702, 702, 718, 718, 702, 702, + nil, 718, nil, 718, 718, 718, 718, 718, 718, 718, + nil, nil, nil, nil, nil, 718, 718, 718, 718, 718, + 718, 718, nil, nil, 718, nil, nil, nil, nil, nil, + nil, 718, nil, nil, 718, 718, 718, 718, 718, 718, + 718, 718, nil, 718, 718, 718, nil, 718, 718, 718, + 718, 718, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 718, nil, nil, 718, nil, nil, 718, 718, nil, + nil, 718, nil, nil, nil, nil, nil, 718, nil, nil, + nil, nil, nil, nil, nil, nil, 718, nil, nil, nil, + nil, 718, 718, 718, 718, nil, 718, 718, 718, 718, + nil, nil, nil, nil, 718, 718, nil, nil, nil, 740, + 740, 740, 718, 740, 718, 718, 718, 740, 740, 718, + 718, nil, 740, nil, 740, 740, 740, 740, 740, 740, + 740, nil, nil, nil, nil, nil, 740, 740, 740, 740, + 740, 740, 740, nil, nil, 740, nil, nil, nil, nil, + nil, nil, 740, nil, nil, 740, 740, 740, 740, 740, + 740, 740, 740, nil, 740, 740, 740, nil, 740, 740, + 740, 740, 740, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 740, nil, nil, 740, nil, nil, 740, 740, + nil, nil, 740, nil, nil, nil, nil, nil, 740, nil, + nil, nil, nil, nil, nil, nil, nil, 740, nil, nil, + nil, nil, 740, 740, 740, 740, nil, 740, 740, 740, + 740, nil, nil, nil, nil, 740, 740, nil, nil, nil, + 741, 741, 741, 740, 741, 740, 740, 740, 741, 741, + 740, 740, nil, 741, nil, 741, 741, 741, 741, 741, + 741, 741, nil, nil, nil, nil, nil, 741, 741, 741, + 741, 741, 741, 741, nil, nil, 741, nil, nil, nil, + nil, nil, nil, 741, nil, nil, 741, 741, 741, 741, + 741, 741, 741, 741, nil, 741, 741, 741, nil, 741, + 741, 741, 741, 741, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 741, nil, nil, 741, nil, nil, 741, + 741, nil, nil, 741, nil, nil, nil, nil, nil, 741, + nil, nil, nil, nil, nil, nil, nil, nil, 741, nil, + nil, nil, nil, 741, 741, 741, 741, nil, 741, 741, + 741, 741, nil, nil, nil, nil, 741, 741, nil, nil, + nil, 754, 754, 754, 741, 754, 741, 741, 741, 754, + 754, 741, 741, nil, 754, nil, 754, 754, 754, 754, + 754, 754, 754, nil, nil, nil, nil, nil, 754, 754, + 754, 754, 754, 754, 754, nil, nil, 754, nil, nil, + nil, nil, nil, nil, 754, nil, nil, 754, 754, 754, + 754, 754, 754, 754, 754, 754, 754, 754, 754, nil, + 754, 754, 754, 754, 754, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 754, nil, nil, 754, nil, nil, + 754, 754, nil, nil, 754, nil, 754, nil, 754, nil, + 754, nil, nil, 754, nil, nil, nil, nil, nil, 754, + nil, nil, nil, nil, 754, 754, 754, 754, nil, 754, + 754, 754, 754, nil, nil, nil, nil, 754, 754, nil, + nil, nil, 766, 766, 766, 754, 766, 754, 754, 754, + 766, 766, 754, 754, nil, 766, nil, 766, 766, 766, + 766, 766, 766, 766, nil, nil, nil, nil, nil, 766, + 766, 766, 766, 766, 766, 766, nil, nil, 766, nil, + nil, nil, nil, nil, nil, 766, nil, nil, 766, 766, + 766, 766, 766, 766, 766, 766, nil, 766, 766, 766, + nil, 766, 766, 766, 766, 766, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 766, nil, nil, 766, nil, + nil, 766, 766, nil, nil, 766, nil, nil, nil, nil, + nil, 766, nil, nil, nil, nil, nil, nil, nil, nil, + 766, nil, nil, nil, nil, 766, 766, 766, 766, nil, + 766, 766, 766, 766, nil, nil, nil, nil, 766, 766, + nil, nil, nil, 785, 785, 785, 766, 785, 766, 766, + 766, 785, 785, 766, 766, nil, 785, nil, 785, 785, + 785, 785, 785, 785, 785, nil, nil, nil, nil, nil, + 785, 785, 785, 785, 785, 785, 785, nil, nil, 785, + nil, nil, nil, nil, nil, nil, 785, nil, nil, 785, + 785, 785, 785, 785, 785, 785, 785, nil, 785, 785, + 785, nil, 785, 785, 785, 785, 785, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 785, nil, nil, 785, + nil, nil, 785, 785, nil, nil, 785, nil, nil, nil, + nil, nil, 785, nil, nil, nil, nil, nil, nil, nil, + nil, 785, nil, nil, nil, nil, 785, 785, 785, 785, + nil, 785, 785, 785, 785, nil, nil, nil, nil, 785, + 785, nil, nil, nil, 813, 813, 813, 785, 813, 785, + 785, 785, 813, 813, 785, 785, nil, 813, nil, 813, + 813, 813, 813, 813, 813, 813, nil, nil, nil, nil, + nil, 813, 813, 813, 813, 813, 813, 813, nil, nil, + 813, nil, nil, nil, nil, nil, nil, 813, nil, nil, + 813, 813, 813, 813, 813, 813, 813, 813, nil, 813, + 813, 813, nil, 813, 813, 813, 813, 813, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 813, nil, nil, + 813, nil, nil, 813, 813, nil, nil, 813, nil, nil, + nil, nil, nil, 813, nil, nil, nil, nil, nil, nil, + nil, nil, 813, nil, nil, nil, nil, 813, 813, 813, + 813, nil, 813, 813, 813, 813, nil, nil, nil, nil, + 813, 813, nil, nil, nil, 832, 832, 832, 813, 832, + 813, 813, 813, 832, 832, 813, 813, nil, 832, nil, + 832, 832, 832, 832, 832, 832, 832, nil, nil, nil, + nil, nil, 832, 832, 832, 832, 832, 832, 832, nil, + nil, 832, nil, nil, nil, nil, nil, nil, 832, nil, + nil, 832, 832, 832, 832, 832, 832, 832, 832, nil, + 832, 832, 832, nil, 832, 832, 832, 832, 832, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 832, nil, + nil, 832, nil, nil, 832, 832, nil, nil, 832, nil, + nil, nil, nil, nil, 832, nil, nil, nil, nil, nil, + nil, nil, nil, 832, nil, nil, nil, nil, 832, 832, + 832, 832, nil, 832, 832, 832, 832, nil, nil, nil, + nil, 832, 832, nil, nil, nil, 840, 840, 840, 832, + 840, 832, 832, 832, 840, 840, 832, 832, nil, 840, + nil, 840, 840, 840, 840, 840, 840, 840, nil, nil, + nil, nil, nil, 840, 840, 840, 840, 840, 840, 840, + nil, nil, 840, nil, nil, nil, nil, nil, nil, 840, + nil, nil, 840, 840, 840, 840, 840, 840, 840, 840, + nil, 840, 840, 840, nil, 840, 840, 840, 840, 840, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 840, + nil, nil, 840, nil, nil, 840, 840, nil, nil, 840, + nil, nil, nil, nil, nil, 840, nil, nil, nil, nil, + nil, nil, nil, nil, 840, nil, nil, nil, nil, 840, + 840, 840, 840, nil, 840, 840, 840, 840, nil, nil, + nil, nil, 840, 840, nil, nil, nil, 854, 854, 854, + 840, 854, 840, 840, 840, 854, 854, 840, 840, nil, + 854, nil, 854, 854, 854, 854, 854, 854, 854, nil, + nil, nil, nil, nil, 854, 854, 854, 854, 854, 854, + 854, nil, nil, 854, nil, nil, nil, nil, nil, nil, + 854, nil, nil, 854, 854, 854, 854, 854, 854, 854, + 854, nil, 854, 854, 854, nil, 854, 854, 854, 854, + 854, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 854, nil, nil, 854, nil, nil, 854, 854, nil, nil, + 854, nil, nil, nil, nil, nil, 854, nil, nil, nil, + nil, nil, nil, nil, nil, 854, nil, nil, nil, nil, + 854, 854, 854, 854, nil, 854, 854, 854, 854, nil, + nil, nil, nil, 854, 854, nil, nil, nil, 855, 855, + 855, 854, 855, 854, 854, 854, 855, 855, 854, 854, + nil, 855, nil, 855, 855, 855, 855, 855, 855, 855, + nil, nil, nil, nil, nil, 855, 855, 855, 855, 855, + 855, 855, nil, nil, 855, nil, nil, nil, nil, nil, + nil, 855, nil, nil, 855, 855, 855, 855, 855, 855, + 855, 855, nil, 855, 855, 855, nil, 855, 855, 855, + 855, 855, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 855, nil, nil, 855, nil, nil, 855, 855, nil, + nil, 855, nil, nil, nil, nil, nil, 855, nil, nil, + nil, nil, nil, nil, nil, nil, 855, nil, nil, nil, + nil, 855, 855, 855, 855, nil, 855, 855, 855, 855, + nil, nil, nil, nil, 855, 855, nil, nil, nil, 856, + 856, 856, 855, 856, 855, 855, 855, 856, 856, 855, + 855, nil, 856, nil, 856, 856, 856, 856, 856, 856, + 856, nil, nil, nil, nil, nil, 856, 856, 856, 856, + 856, 856, 856, nil, nil, 856, nil, nil, nil, nil, + nil, nil, 856, nil, nil, 856, 856, 856, 856, 856, + 856, 856, 856, nil, 856, 856, 856, nil, 856, 856, + 856, 856, 856, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 856, nil, nil, 856, nil, nil, 856, 856, + nil, nil, 856, nil, nil, nil, nil, nil, 856, nil, + nil, nil, nil, nil, nil, nil, nil, 856, nil, nil, + nil, nil, 856, 856, 856, 856, nil, 856, 856, 856, + 856, nil, nil, nil, nil, 856, 856, nil, nil, nil, + 884, 884, 884, 856, 884, 856, 856, 856, 884, 884, + 856, 856, nil, 884, nil, 884, 884, 884, 884, 884, + 884, 884, nil, nil, nil, nil, nil, 884, 884, 884, + 884, 884, 884, 884, nil, nil, 884, nil, nil, nil, + nil, nil, nil, 884, nil, nil, 884, 884, 884, 884, + 884, 884, 884, 884, nil, 884, 884, 884, nil, 884, + 884, 884, 884, 884, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 884, nil, nil, 884, nil, nil, 884, + 884, nil, nil, 884, nil, nil, nil, nil, nil, 884, + nil, nil, nil, nil, nil, nil, nil, nil, 884, nil, + nil, nil, nil, 884, 884, 884, 884, nil, 884, 884, + 884, 884, nil, nil, nil, nil, 884, 884, nil, nil, + nil, 885, 885, 885, 884, 885, 884, 884, 884, 885, + 885, 884, 884, nil, 885, nil, 885, 885, 885, 885, + 885, 885, 885, nil, nil, nil, nil, nil, 885, 885, + 885, 885, 885, 885, 885, nil, nil, 885, nil, nil, + nil, nil, nil, nil, 885, nil, nil, 885, 885, 885, + 885, 885, 885, 885, 885, nil, 885, 885, 885, nil, + 885, 885, 885, 885, 885, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 885, nil, nil, 885, nil, nil, + 885, 885, nil, nil, 885, nil, nil, nil, nil, nil, + 885, nil, nil, nil, nil, nil, nil, nil, nil, 885, + nil, nil, nil, nil, 885, 885, 885, 885, nil, 885, + 885, 885, 885, nil, nil, nil, nil, 885, 885, nil, + nil, nil, 886, 886, 886, 885, 886, 885, 885, 885, + 886, 886, 885, 885, nil, 886, nil, 886, 886, 886, + 886, 886, 886, 886, nil, nil, nil, nil, nil, 886, + 886, 886, 886, 886, 886, 886, nil, nil, 886, nil, + nil, nil, nil, nil, nil, 886, nil, nil, 886, 886, + 886, 886, 886, 886, 886, 886, nil, 886, 886, 886, + nil, 886, 886, 886, 886, 886, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 886, nil, nil, 886, nil, + nil, 886, 886, nil, nil, 886, nil, nil, nil, nil, + nil, 886, nil, nil, nil, nil, nil, nil, nil, nil, + 886, nil, nil, nil, nil, 886, 886, 886, 886, nil, + 886, 886, 886, 886, nil, nil, nil, nil, 886, 886, + nil, nil, nil, 887, 887, 887, 886, 887, 886, 886, + 886, 887, 887, 886, 886, nil, 887, nil, 887, 887, + 887, 887, 887, 887, 887, nil, nil, nil, nil, nil, + 887, 887, 887, 887, 887, 887, 887, nil, nil, 887, + nil, nil, nil, nil, nil, nil, 887, nil, nil, 887, + 887, 887, 887, 887, 887, 887, 887, nil, 887, 887, + 887, nil, 887, 887, 887, 887, 887, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 887, nil, nil, 887, + nil, nil, 887, 887, nil, nil, 887, nil, nil, nil, + nil, nil, 887, nil, nil, nil, nil, nil, nil, nil, + nil, 887, nil, nil, nil, nil, 887, 887, 887, 887, + nil, 887, 887, 887, 887, nil, nil, nil, nil, 887, + 887, nil, nil, nil, 893, 893, 893, 887, 893, 887, + 887, 887, 893, 893, 887, 887, nil, 893, nil, 893, + 893, 893, 893, 893, 893, 893, nil, nil, nil, nil, + nil, 893, 893, 893, 893, 893, 893, 893, nil, nil, + 893, nil, nil, nil, nil, nil, nil, 893, nil, nil, + 893, 893, 893, 893, 893, 893, 893, 893, nil, 893, + 893, 893, nil, 893, 893, 893, 893, 893, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 893, nil, nil, + 893, nil, nil, 893, 893, nil, nil, 893, nil, nil, + nil, nil, nil, 893, nil, nil, nil, nil, nil, nil, + nil, nil, 893, nil, nil, nil, nil, 893, 893, 893, + 893, nil, 893, 893, 893, 893, nil, nil, nil, nil, + 893, 893, nil, nil, nil, 915, 915, 915, 893, 915, + 893, 893, 893, 915, 915, 893, 893, nil, 915, nil, + 915, 915, 915, 915, 915, 915, 915, nil, nil, nil, + nil, nil, 915, 915, 915, 915, 915, 915, 915, nil, + nil, 915, nil, nil, nil, nil, nil, nil, 915, nil, + nil, 915, 915, 915, 915, 915, 915, 915, 915, nil, + 915, 915, 915, nil, 915, 915, 915, 915, 915, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 915, nil, + nil, 915, nil, nil, 915, 915, nil, nil, 915, nil, + nil, nil, nil, nil, 915, nil, nil, nil, nil, nil, + nil, nil, nil, 915, nil, nil, nil, nil, 915, 915, + 915, 915, nil, 915, 915, 915, 915, nil, nil, nil, + nil, 915, 915, nil, nil, nil, 920, 920, 920, 915, + 920, 915, 915, 915, 920, 920, 915, 915, nil, 920, + nil, 920, 920, 920, 920, 920, 920, 920, nil, nil, + nil, nil, nil, 920, 920, 920, 920, 920, 920, 920, + nil, nil, 920, nil, nil, nil, nil, nil, nil, 920, + nil, nil, 920, 920, 920, 920, 920, 920, 920, 920, + nil, 920, 920, 920, nil, 920, 920, 920, 920, 920, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 920, + nil, nil, 920, nil, nil, 920, 920, nil, nil, 920, + nil, 920, nil, nil, nil, 920, nil, nil, nil, nil, + nil, nil, nil, nil, 920, nil, nil, nil, nil, 920, + 920, 920, 920, nil, 920, 920, 920, 920, nil, nil, + nil, nil, 920, 920, nil, nil, nil, 940, 940, 940, + 920, 940, 920, 920, 920, 940, 940, 920, 920, nil, + 940, nil, 940, 940, 940, 940, 940, 940, 940, nil, + nil, nil, nil, nil, 940, 940, 940, 940, 940, 940, + 940, nil, nil, 940, nil, nil, nil, nil, nil, nil, + 940, nil, nil, 940, 940, 940, 940, 940, 940, 940, + 940, 940, 940, 940, 940, nil, 940, 940, 940, 940, + 940, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 940, nil, nil, 940, nil, nil, 940, 940, nil, nil, + 940, nil, nil, nil, 940, nil, 940, nil, nil, 940, + nil, nil, nil, nil, nil, 940, nil, nil, nil, nil, + 940, 940, 940, 940, nil, 940, 940, 940, 940, nil, + nil, nil, nil, 940, 940, nil, nil, nil, 967, 967, + 967, 940, 967, 940, 940, 940, 967, 967, 940, 940, + nil, 967, nil, 967, 967, 967, 967, 967, 967, 967, + nil, nil, nil, nil, nil, 967, 967, 967, 967, 967, + 967, 967, nil, nil, 967, nil, nil, nil, nil, nil, + nil, 967, nil, nil, 967, 967, 967, 967, 967, 967, + 967, 967, nil, 967, 967, 967, nil, 967, 967, 967, + 967, 967, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 967, nil, nil, 967, nil, nil, 967, 967, nil, + nil, 967, nil, nil, nil, nil, nil, 967, nil, nil, + nil, nil, nil, nil, nil, nil, 967, nil, nil, nil, + nil, 967, 967, 967, 967, nil, 967, 967, 967, 967, + nil, nil, nil, nil, 967, 967, nil, nil, nil, 968, + 968, 968, 967, 968, 967, 967, 967, 968, 968, 967, + 967, nil, 968, nil, 968, 968, 968, 968, 968, 968, + 968, nil, nil, nil, nil, nil, 968, 968, 968, 968, + 968, 968, 968, nil, nil, 968, nil, nil, nil, nil, + nil, nil, 968, nil, nil, 968, 968, 968, 968, 968, + 968, 968, 968, nil, 968, 968, 968, nil, 968, 968, + 968, 968, 968, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 968, nil, nil, 968, nil, nil, 968, 968, + nil, nil, 968, nil, nil, nil, nil, nil, 968, nil, + nil, nil, nil, nil, nil, nil, nil, 968, nil, nil, + nil, nil, 968, 968, 968, 968, nil, 968, 968, 968, + 968, nil, nil, nil, nil, 968, 968, nil, nil, nil, + 1094, 1094, 1094, 968, 1094, 968, 968, 968, 1094, 1094, + 968, 968, nil, 1094, nil, 1094, 1094, 1094, 1094, 1094, + 1094, 1094, nil, nil, nil, nil, nil, 1094, 1094, 1094, + 1094, 1094, 1094, 1094, nil, nil, 1094, nil, nil, nil, + nil, nil, nil, 1094, nil, nil, 1094, 1094, 1094, 1094, + 1094, 1094, 1094, 1094, nil, 1094, 1094, 1094, nil, 1094, + 1094, 1094, 1094, 1094, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 1094, nil, nil, 1094, nil, nil, 1094, + 1094, nil, nil, 1094, nil, nil, nil, nil, nil, 1094, + nil, nil, nil, nil, nil, nil, nil, nil, 1094, nil, + nil, nil, nil, 1094, 1094, 1094, 1094, nil, 1094, 1094, + 1094, 1094, nil, nil, nil, nil, 1094, 1094, nil, nil, + nil, 1126, 1126, 1126, 1094, 1126, 1094, 1094, 1094, 1126, + 1126, 1094, 1094, nil, 1126, nil, 1126, 1126, 1126, 1126, + 1126, 1126, 1126, nil, nil, nil, nil, nil, 1126, 1126, + 1126, 1126, 1126, 1126, 1126, nil, nil, 1126, nil, nil, + nil, nil, nil, nil, 1126, nil, nil, 1126, 1126, 1126, + 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, nil, + 1126, 1126, 1126, 1126, 1126, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1126, nil, nil, 1126, nil, nil, + 1126, 1126, nil, nil, 1126, nil, 1126, nil, 1126, nil, + 1126, nil, nil, 1126, nil, nil, nil, nil, nil, 1126, + nil, nil, nil, nil, 1126, 1126, 1126, 1126, nil, 1126, + 1126, 1126, 1126, nil, nil, nil, nil, 1126, 1126, nil, + nil, nil, 1222, 1222, 1222, 1126, 1222, 1126, 1126, 1126, + 1222, 1222, 1126, 1126, nil, 1222, nil, 1222, 1222, 1222, + 1222, 1222, 1222, 1222, nil, nil, nil, nil, nil, 1222, + 1222, 1222, 1222, 1222, 1222, 1222, nil, nil, 1222, nil, + nil, nil, nil, nil, nil, 1222, nil, nil, 1222, 1222, + 1222, 1222, 1222, 1222, 1222, 1222, nil, 1222, 1222, 1222, + nil, 1222, 1222, 1222, 1222, 1222, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 1222, nil, nil, 1222, nil, + nil, 1222, 1222, nil, nil, 1222, nil, nil, nil, nil, + nil, 1222, nil, nil, nil, nil, nil, nil, nil, nil, + 1222, nil, nil, nil, nil, 1222, 1222, 1222, 1222, nil, + 1222, 1222, 1222, 1222, nil, nil, nil, nil, 1222, 1222, + nil, nil, nil, 1223, 1223, 1223, 1222, 1223, 1222, 1222, + 1222, 1223, 1223, 1222, 1222, nil, 1223, nil, 1223, 1223, + 1223, 1223, 1223, 1223, 1223, nil, nil, nil, nil, nil, + 1223, 1223, 1223, 1223, 1223, 1223, 1223, nil, nil, 1223, + nil, nil, nil, nil, nil, nil, 1223, nil, nil, 1223, + 1223, 1223, 1223, 1223, 1223, 1223, 1223, nil, 1223, 1223, + 1223, nil, 1223, 1223, 1223, 1223, 1223, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1223, nil, nil, 1223, + nil, nil, 1223, 1223, nil, nil, 1223, nil, nil, nil, + nil, nil, 1223, nil, nil, nil, nil, nil, nil, nil, + nil, 1223, nil, nil, nil, nil, 1223, 1223, 1223, 1223, + nil, 1223, 1223, 1223, 1223, nil, nil, nil, nil, 1223, + 1223, nil, nil, nil, 39, 39, 39, 1223, 39, 1223, + 1223, 1223, 39, 39, 1223, 1223, nil, 39, nil, 39, + 39, 39, 39, 39, 39, 39, nil, nil, nil, nil, + nil, 39, 39, 39, 39, 39, 39, 39, nil, nil, + 39, nil, nil, nil, nil, nil, nil, 39, nil, nil, + 39, 39, 39, 39, 39, 39, 39, 39, nil, 39, + 39, 39, nil, 39, 39, nil, nil, 39, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 39, nil, nil, + 39, nil, nil, 39, 39, nil, nil, 39, nil, 39, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 39, 39, 39, + 39, nil, 39, 39, 39, 39, nil, nil, nil, nil, + 39, 39, nil, nil, nil, 40, 40, 40, 39, 40, + 39, 39, 39, 40, 40, nil, nil, nil, 40, nil, + 40, 40, 40, 40, 40, 40, 40, nil, nil, nil, + nil, nil, 40, 40, 40, 40, 40, 40, 40, nil, + nil, 40, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 40, 40, 40, 40, 40, 40, 40, 40, nil, + 40, 40, 40, nil, 40, 40, nil, nil, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 40, nil, nil, 40, 40, nil, nil, 40, nil, + nil, 1211, nil, 1211, 1211, 1211, 1211, 1211, nil, nil, + nil, nil, nil, nil, nil, nil, 1211, nil, 40, 40, + 40, 40, nil, 40, 40, 40, 40, nil, nil, nil, + nil, 40, 40, nil, nil, nil, 40, nil, 1211, 40, + nil, 40, 40, 40, 76, 76, 76, nil, 76, 1211, + 1211, nil, 76, 76, 1211, nil, nil, 76, nil, 76, + 76, 76, 76, 76, 76, 76, nil, nil, nil, nil, + nil, 76, 76, 76, 76, 76, 76, 76, nil, nil, + 76, nil, nil, nil, nil, nil, nil, 76, nil, nil, + 76, 76, 76, 76, 76, 76, 76, 76, nil, 76, + 76, 76, nil, 76, 76, nil, nil, 76, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 76, nil, nil, + 76, nil, nil, 76, 76, nil, nil, 76, nil, 76, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 76, 76, 76, + 76, nil, 76, 76, 76, 76, nil, nil, nil, nil, + 76, 76, nil, nil, nil, 77, 77, 77, 76, 77, + 76, 76, 76, 77, 77, nil, nil, nil, 77, nil, + 77, 77, 77, 77, 77, 77, 77, nil, nil, nil, + nil, nil, 77, 77, 77, 77, 77, 77, 77, nil, + nil, 77, nil, nil, nil, nil, nil, nil, 77, nil, + nil, 77, 77, 77, 77, 77, 77, 77, 77, nil, + 77, 77, 77, nil, 77, 77, nil, nil, 77, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 77, nil, nil, 77, nil, + nil, 77, nil, nil, 77, 77, nil, nil, 77, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 77, 77, + 77, 77, nil, 77, 77, 77, 77, nil, nil, nil, + nil, 77, 77, nil, nil, nil, 78, 78, 78, 77, + 78, 77, 77, 77, 78, 78, nil, nil, nil, 78, + nil, 78, 78, 78, 78, 78, 78, 78, nil, nil, + nil, nil, nil, 78, 78, 78, 78, 78, 78, 78, + nil, nil, 78, nil, nil, nil, nil, nil, nil, 78, + nil, nil, 78, 78, 78, 78, 78, 78, 78, 78, + nil, 78, 78, 78, nil, 78, 78, nil, nil, 78, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 78, + nil, nil, 78, nil, nil, 78, 78, nil, nil, 78, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 78, + 78, 78, 78, nil, 78, 78, 78, 78, nil, nil, + nil, nil, 78, 78, nil, nil, nil, 343, 343, 343, + 78, 343, 78, 78, 78, 343, 343, nil, nil, nil, + 343, nil, 343, 343, 343, 343, 343, 343, 343, nil, + nil, nil, nil, nil, 343, 343, 343, 343, 343, 343, + 343, nil, nil, 343, nil, nil, nil, nil, nil, nil, + 343, nil, nil, 343, 343, 343, 343, 343, 343, 343, + 343, nil, 343, 343, 343, nil, 343, 343, nil, nil, + 343, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 343, nil, nil, 343, nil, nil, 343, 343, nil, nil, + 343, nil, nil, 1213, nil, 1213, 1213, 1213, 1213, 1213, + nil, nil, nil, nil, nil, nil, nil, nil, 1213, nil, + 343, 343, 343, 343, nil, 343, 343, 343, 343, nil, + nil, nil, nil, 343, 343, nil, nil, nil, 343, nil, + 1213, 343, nil, 343, 343, 343, 362, 362, 362, nil, + 362, 1213, 1213, nil, 362, 362, 1213, nil, nil, 362, + nil, 362, 362, 362, 362, 362, 362, 362, nil, nil, + nil, nil, nil, 362, 362, 362, 362, 362, 362, 362, + nil, nil, 362, nil, nil, nil, nil, nil, nil, 362, + nil, nil, 362, 362, 362, 362, 362, 362, 362, 362, + nil, 362, 362, 362, nil, 362, 362, nil, nil, 362, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 362, + nil, nil, 362, nil, nil, 362, 362, nil, nil, 362, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 362, + 362, 362, 362, nil, 362, 362, 362, 362, nil, nil, + nil, nil, 362, 362, nil, nil, nil, 592, 592, 592, + 362, 592, 362, 362, 362, 592, 592, nil, nil, nil, + 592, nil, 592, 592, 592, 592, 592, 592, 592, nil, + nil, nil, nil, nil, 592, 592, 592, 592, 592, 592, + 592, nil, nil, 592, nil, nil, nil, nil, nil, nil, + 592, nil, nil, 592, 592, 592, 592, 592, 592, 592, + 592, nil, 592, 592, 592, nil, 592, 592, nil, nil, + 592, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 592, nil, nil, 592, nil, nil, 592, 592, nil, nil, + 592, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 592, 592, 592, 592, nil, 592, 592, 592, 592, nil, + nil, nil, nil, 592, 592, nil, nil, nil, 601, 601, + 601, 592, 601, 592, 592, 592, 601, 601, nil, nil, + nil, 601, nil, 601, 601, 601, 601, 601, 601, 601, + nil, nil, nil, nil, nil, 601, 601, 601, 601, 601, + 601, 601, nil, nil, 601, nil, nil, nil, nil, nil, + nil, 601, nil, nil, 601, 601, 601, 601, 601, 601, + 601, 601, nil, 601, 601, 601, nil, 601, 601, nil, + nil, 601, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 601, nil, nil, 601, nil, nil, 601, 601, nil, + nil, 601, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 601, 601, 601, 601, nil, 601, 601, 601, 601, + nil, nil, nil, nil, 601, 601, nil, nil, nil, 769, + 769, 769, 601, 769, 601, 601, 601, 769, 769, nil, + nil, nil, 769, nil, 769, 769, 769, 769, 769, 769, + 769, nil, nil, nil, nil, nil, 769, 769, 769, 769, + 769, 769, 769, nil, nil, 769, nil, nil, nil, nil, + nil, nil, 769, nil, nil, 769, 769, 769, 769, 769, + 769, 769, 769, nil, 769, 769, 769, nil, 769, 769, + nil, nil, 769, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 769, nil, nil, 769, nil, nil, 769, 769, + nil, nil, 769, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 769, 769, 769, 769, nil, 769, 769, 769, + 769, nil, nil, nil, nil, 769, 769, nil, nil, nil, + 780, 780, 780, 769, 780, 769, 769, 769, 780, 780, + nil, nil, nil, 780, nil, 780, 780, 780, 780, 780, + 780, 780, nil, nil, nil, nil, nil, 780, 780, 780, + 780, 780, 780, 780, nil, nil, 780, nil, nil, nil, + nil, nil, nil, 780, nil, nil, 780, 780, 780, 780, + 780, 780, 780, 780, nil, 780, 780, 780, nil, 780, + 780, nil, nil, 780, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 780, nil, nil, 780, nil, nil, 780, + 780, nil, nil, 780, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 780, 780, 780, 780, nil, 780, 780, + 780, 780, nil, nil, nil, nil, 780, 780, nil, nil, + nil, 951, 951, 951, 780, 951, 780, 780, 780, 951, + 951, nil, nil, nil, 951, nil, 951, 951, 951, 951, + 951, 951, 951, nil, nil, nil, nil, nil, 951, 951, + 951, 951, 951, 951, 951, nil, nil, 951, nil, nil, + nil, nil, nil, nil, 951, nil, nil, 951, 951, 951, + 951, 951, 951, 951, 951, nil, 951, 951, 951, nil, + 951, 951, nil, nil, 951, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 951, nil, nil, 951, nil, nil, + 951, 951, nil, nil, 951, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 951, 951, 951, 951, nil, 951, + 951, 951, 951, nil, nil, nil, nil, 951, 951, nil, + nil, nil, 1028, 1028, 1028, 951, 1028, 951, 951, 951, + 1028, 1028, nil, nil, nil, 1028, nil, 1028, 1028, 1028, + 1028, 1028, 1028, 1028, nil, nil, nil, nil, nil, 1028, + 1028, 1028, 1028, 1028, 1028, 1028, nil, nil, 1028, nil, + nil, nil, nil, nil, nil, 1028, nil, nil, 1028, 1028, + 1028, 1028, 1028, 1028, 1028, 1028, nil, 1028, 1028, 1028, + nil, 1028, 1028, nil, nil, 1028, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 1028, nil, nil, 1028, nil, + nil, 1028, 1028, nil, nil, 1028, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 1028, 1028, 1028, 1028, nil, + 1028, 1028, 1028, 1028, nil, nil, nil, nil, 1028, 1028, + nil, nil, nil, 1110, 1110, 1110, 1028, 1110, 1028, 1028, + 1028, 1110, 1110, nil, nil, nil, 1110, nil, 1110, 1110, + 1110, 1110, 1110, 1110, 1110, nil, nil, nil, nil, nil, + 1110, 1110, 1110, 1110, 1110, 1110, 1110, nil, nil, 1110, + nil, nil, nil, nil, nil, nil, 1110, nil, nil, 1110, + 1110, 1110, 1110, 1110, 1110, 1110, 1110, nil, 1110, 1110, + 1110, nil, 1110, 1110, nil, nil, 1110, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1110, nil, nil, 1110, + nil, nil, 1110, 1110, nil, nil, 1110, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1110, 1110, 1110, 1110, + nil, 1110, 1110, 1110, 1110, nil, nil, nil, nil, 1110, + 1110, nil, nil, nil, nil, nil, nil, 1110, nil, 1110, + 1110, 1110, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, nil, nil, nil, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, nil, + nil, nil, nil, nil, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, nil, 10, nil, nil, nil, nil, + nil, nil, nil, 10, 10, nil, 10, 10, 10, 10, + 10, 10, 10, nil, nil, 10, 10, nil, nil, nil, + 10, 10, 10, 10, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 10, 10, nil, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, nil, nil, 10, 10, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 10, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, nil, nil, nil, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, nil, nil, nil, + nil, nil, 11, 11, 11, 11, 11, 11, 11, 11, + 11, nil, nil, 11, nil, nil, nil, nil, nil, nil, + nil, 11, 11, nil, 11, 11, 11, 11, 11, 11, + 11, nil, nil, 11, 11, nil, nil, nil, 11, 11, + 11, 11, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 11, 11, nil, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + nil, nil, 11, 11, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 11, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, nil, nil, nil, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, nil, nil, nil, nil, nil, + 428, 428, 428, 428, 428, 428, 428, 428, 428, nil, + nil, 428, nil, nil, nil, nil, nil, nil, nil, 428, + 428, nil, 428, 428, 428, 428, 428, 428, 428, nil, + nil, 428, 428, nil, nil, nil, 428, 428, 428, 428, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 428, 428, nil, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, nil, nil, + 428, 428, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 428, 671, 671, 671, 671, + 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, + 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, + nil, nil, nil, 671, 671, 671, 671, 671, 671, 671, + 671, 671, 671, nil, nil, nil, nil, nil, 671, 671, + 671, 671, 671, 671, 671, 671, 671, nil, nil, 671, + nil, nil, nil, nil, nil, nil, nil, 671, 671, nil, + 671, 671, 671, 671, 671, 671, 671, nil, nil, 671, + 671, nil, nil, nil, 671, 671, 671, 671, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 671, 671, nil, 671, 671, 671, 671, 671, 671, + 671, 671, 671, 671, 671, 671, nil, nil, 671, 671, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 671, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, nil, nil, + nil, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, nil, nil, nil, nil, nil, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, nil, 26, + nil, nil, nil, nil, nil, 26, 26, nil, 26, 26, + 26, 26, 26, 26, 26, nil, nil, 26, 26, nil, + nil, nil, 26, 26, 26, 26, nil, nil, nil, nil, + nil, 26, nil, nil, nil, nil, nil, nil, nil, 26, + 26, nil, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, nil, nil, 26, 746, 746, 746, + 746, 746, 746, 746, 746, 746, 746, 746, 746, 746, + 746, 746, 746, 746, 746, 746, 746, 746, 746, 746, + 746, nil, nil, nil, 746, 746, 746, 746, 746, 746, + 746, 746, 746, 746, nil, nil, nil, nil, nil, 746, + 746, 746, 746, 746, 746, 746, 746, 746, nil, nil, + 746, nil, nil, nil, nil, nil, nil, nil, 746, 746, + nil, 746, 746, 746, 746, 746, 746, 746, nil, nil, + 746, 746, nil, nil, nil, 746, 746, 746, 746, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 746, 746, nil, 746, 746, 746, 746, 746, + 746, 746, 746, 746, 746, 746, 746, nil, nil, 746, + 890, 890, 890, 890, nil, nil, 1215, nil, 1215, 1215, + 1215, 1215, 1215, nil, nil, nil, 890, 890, 890, 890, + nil, 1215, nil, 890, 890, nil, nil, nil, nil, 890, + 890, nil, nil, 890, 890, nil, nil, nil, nil, nil, + nil, nil, nil, 1215, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 890, 1215, 1215, 890, nil, nil, 1215, + 890, nil, nil, 890, nil, 890, nil, nil, nil, nil, + nil, nil, 890, nil, nil, nil, nil, nil, nil, 890, + nil, nil, nil, 890, 890, 890, 890, nil, 890, 890, + 890, 890, nil, nil, nil, nil, 890, 890, 892, 892, + 892, 892, nil, nil, 890, nil, 890, 890, 890, nil, + nil, 890, 890, nil, 892, 892, 892, 892, nil, nil, + nil, 892, 892, nil, nil, nil, nil, 892, 892, nil, + nil, 892, 892, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 892, nil, nil, 892, nil, nil, nil, 892, nil, + nil, 892, nil, 892, nil, nil, nil, nil, nil, nil, + 892, nil, nil, nil, nil, nil, nil, 892, nil, nil, + nil, 892, 892, 892, 892, nil, 892, 892, 892, 892, + nil, nil, nil, nil, 892, 892, 980, 980, 980, 980, + nil, nil, 892, nil, 892, 892, 892, nil, nil, 892, + 892, nil, 980, 980, 980, 980, nil, nil, nil, 980, + nil, nil, nil, nil, nil, 980, 980, nil, nil, 980, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 980, + nil, nil, 980, nil, nil, nil, 980, nil, nil, 980, + nil, 980, nil, nil, nil, nil, nil, nil, 715, nil, + 715, 715, 715, 715, 715, 980, nil, nil, nil, 980, + 980, 980, 980, 715, 980, 980, 980, 980, nil, nil, + nil, nil, 980, 980, 980, 988, 988, 988, 988, nil, + 980, nil, 980, 980, 980, 715, nil, 980, 980, nil, + nil, 988, 988, 988, 988, nil, 715, 715, 988, nil, + nil, 715, nil, nil, 988, 988, nil, nil, 988, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 988, nil, + nil, 988, nil, nil, nil, 988, nil, nil, 988, nil, + nil, 715, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 988, nil, nil, nil, 988, 988, + 988, 988, nil, 988, 988, 988, 988, nil, nil, nil, + nil, 988, 988, 1063, 1063, 1063, 1063, nil, nil, 988, + nil, 988, 988, 988, nil, nil, 988, 988, nil, 1063, + 1063, 1063, 1063, nil, nil, 1104, 1063, 1104, 1104, 1104, + 1104, 1104, 1063, 1063, nil, nil, 1063, nil, nil, nil, + 1104, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1063, nil, nil, 1063, + nil, nil, 1104, 1063, nil, nil, 1063, nil, 1063, nil, + nil, 1104, 1104, 1104, 1104, nil, nil, nil, 1104, nil, + nil, nil, 1063, nil, nil, nil, 1063, 1063, 1063, 1063, + nil, 1063, 1063, 1063, 1063, nil, nil, nil, nil, 1063, + 1063, 1065, 1065, 1065, 1065, nil, nil, 1063, nil, 1063, + 1063, 1063, nil, nil, 1063, 1063, nil, 1065, 1065, 1065, + 1065, nil, nil, 1209, 1065, 1209, 1209, 1209, 1209, 1209, + 1065, 1065, nil, nil, 1065, nil, nil, nil, 1209, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1065, nil, nil, 1065, nil, nil, + 1209, 1065, nil, nil, 1065, nil, nil, nil, nil, 1209, + 1209, 1209, 1209, nil, nil, nil, 1209, nil, nil, nil, + 1065, nil, nil, nil, 1065, 1065, 1065, 1065, nil, 1065, + 1065, 1065, 1065, nil, nil, nil, nil, 1065, 1065, 1068, + 1068, 1068, 1068, nil, nil, 1065, nil, 1065, 1065, 1065, + nil, nil, 1065, 1065, nil, 1068, 1068, 1068, 1068, nil, + nil, nil, 1068, 1068, nil, nil, nil, nil, 1068, 1068, + nil, nil, 1068, 1068, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1068, nil, nil, 1068, nil, nil, nil, 1068, + nil, nil, 1068, nil, 1068, nil, nil, nil, nil, nil, + nil, 1068, nil, nil, nil, nil, nil, nil, 1068, nil, + nil, nil, 1068, 1068, 1068, 1068, nil, 1068, 1068, 1068, + 1068, nil, nil, nil, nil, 1068, 1068, 1069, 1069, 1069, + 1069, nil, nil, 1068, nil, 1068, 1068, 1068, nil, nil, + 1068, 1068, nil, 1069, 1069, 1069, 1069, nil, nil, nil, + 1069, 1069, nil, nil, nil, nil, 1069, 1069, nil, nil, + 1069, 1069, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1069, nil, nil, 1069, nil, nil, nil, 1069, nil, nil, + 1069, nil, 1069, nil, nil, nil, nil, nil, nil, 1069, + nil, nil, nil, nil, nil, nil, 1069, nil, nil, nil, + 1069, 1069, 1069, 1069, nil, 1069, 1069, 1069, 1069, nil, + nil, nil, nil, 1069, 1069, 1075, 1075, 1075, 1075, nil, + nil, 1069, nil, 1069, 1069, 1069, nil, nil, 1069, 1069, + nil, 1075, 1075, 1075, 1075, nil, nil, 1239, 1075, 1239, + 1239, 1239, 1239, 1239, 1075, 1075, nil, nil, 1075, nil, + nil, nil, 1239, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 1075, nil, + nil, 1075, nil, nil, 1239, 1075, nil, nil, 1075, nil, + 1075, nil, nil, nil, nil, 1239, 1239, nil, nil, nil, + 1239, nil, nil, nil, 1075, nil, nil, nil, 1075, 1075, + 1075, 1075, nil, 1075, 1075, 1075, 1075, nil, nil, nil, + nil, 1075, 1075, 1081, 1081, 1081, 1081, nil, nil, 1075, + nil, 1075, 1075, 1075, nil, nil, 1075, 1075, nil, 1081, + 1081, 1081, 1081, nil, nil, nil, 1081, nil, nil, nil, + nil, nil, 1081, 1081, nil, nil, 1081, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1081, nil, nil, 1081, + nil, nil, nil, 1081, nil, nil, 1081, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1081, nil, nil, nil, 1081, 1081, 1081, 1081, + nil, 1081, 1081, 1081, 1081, nil, nil, nil, nil, 1081, + 1081, 1082, 1082, 1082, 1082, nil, nil, 1081, nil, 1081, + 1081, 1081, nil, nil, 1081, 1081, nil, 1082, 1082, 1082, + 1082, nil, nil, nil, 1082, nil, nil, nil, nil, nil, + 1082, 1082, nil, nil, 1082, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1082, nil, nil, 1082, nil, nil, + nil, 1082, nil, nil, 1082, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1082, nil, nil, nil, 1082, 1082, 1082, 1082, nil, 1082, + 1082, 1082, 1082, nil, nil, nil, nil, 1082, 1082, 1114, + 1114, 1114, 1114, nil, nil, 1082, nil, 1082, 1082, 1082, + nil, nil, 1082, 1082, nil, 1114, 1114, 1114, 1114, nil, + nil, nil, 1114, 1114, nil, nil, nil, nil, 1114, 1114, + nil, nil, 1114, 1114, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1114, nil, nil, 1114, nil, nil, nil, 1114, + nil, nil, 1114, nil, 1114, nil, nil, nil, nil, nil, + nil, 1114, nil, nil, nil, nil, nil, nil, 1114, nil, + nil, nil, 1114, 1114, 1114, 1114, nil, 1114, 1114, 1114, + 1114, nil, nil, nil, nil, 1114, 1114, 1194, 1194, 1194, + 1194, nil, nil, 1114, nil, 1114, 1114, 1114, nil, nil, + 1114, 1114, nil, 1194, 1194, 1194, 1194, nil, nil, nil, + 1194, nil, nil, nil, nil, nil, 1194, 1194, nil, nil, + 1194, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1194, nil, nil, 1194, nil, nil, nil, 1194, nil, nil, + 1194, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1194, nil, nil, nil, + 1194, 1194, 1194, 1194, nil, 1194, 1194, 1194, 1194, nil, + nil, nil, nil, 1194, 1194, 1202, 1202, 1202, 1202, nil, + nil, 1194, nil, 1194, 1194, 1194, nil, nil, 1194, 1194, + nil, 1202, 1202, 1202, 1202, nil, nil, nil, 1202, nil, + nil, nil, nil, nil, 1202, 1202, nil, nil, 1202, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 1202, nil, + nil, 1202, nil, nil, nil, 1202, nil, nil, 1202, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1202, nil, nil, nil, 1202, 1202, + 1202, 1202, nil, 1202, 1202, 1202, 1202, nil, nil, nil, + nil, 1202, 1202, 1206, 1206, 1206, 1206, nil, nil, 1202, + nil, 1202, 1202, 1202, nil, nil, 1202, 1202, nil, 1206, + 1206, 1206, 1206, nil, nil, nil, 1206, nil, nil, nil, + nil, nil, 1206, 1206, nil, nil, 1206, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1206, nil, nil, 1206, + nil, nil, nil, 1206, nil, nil, 1206, nil, 1206, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1206, nil, nil, nil, 1206, 1206, 1206, 1206, + nil, 1206, 1206, 1206, 1206, nil, nil, nil, nil, 1206, + 1206, 1238, 1238, 1238, 1238, nil, nil, 1206, nil, 1206, + 1206, 1206, nil, nil, 1206, 1206, nil, 1238, 1238, 1238, + 1238, nil, nil, nil, 1238, nil, nil, nil, nil, nil, + 1238, 1238, nil, nil, 1238, nil, nil, nil, nil, nil, + nil, nil, 997, 997, 997, 997, nil, nil, nil, nil, + nil, nil, nil, nil, 1238, nil, nil, 1238, 997, 997, + 997, 1238, nil, nil, 1238, nil, nil, nil, nil, nil, + nil, 997, 997, nil, nil, 997, nil, nil, nil, nil, + 1238, nil, nil, nil, 1238, 1238, 1238, 1238, nil, 1238, + 1238, 1238, 1238, nil, nil, nil, nil, 1238, 1238, nil, + nil, nil, nil, nil, nil, 1238, nil, 1238, 1238, 1238, + nil, nil, 1238, 1238, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 997, 997, 997, 997, nil, + 997, 997, 997, 997, nil, nil, nil, nil, 997, 997, + 998, 998, 998, 998, nil, nil, 997, nil, 997, 997, + 997, nil, nil, nil, nil, nil, 998, 998, 998, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 998, + 998, nil, nil, 998, 1088, 1088, 1088, 1088, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1088, 1088, 1088, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 1088, 1088, nil, nil, 1088, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 998, 998, 998, 998, nil, 998, 998, + 998, 998, nil, nil, nil, nil, 998, 998, nil, nil, + nil, nil, nil, nil, 998, nil, 998, 998, 998, nil, + nil, nil, nil, nil, nil, nil, nil, 1088, 1088, 1088, + 1088, nil, 1088, 1088, 1088, 1088, nil, nil, nil, nil, + 1088, 1088, 1089, 1089, 1089, 1089, nil, nil, 1088, nil, + 1088, 1088, 1088, nil, nil, nil, nil, nil, 1089, 1089, + 1089, 648, nil, 648, 648, 648, 648, 648, nil, nil, + nil, 1089, 1089, nil, nil, 1089, 648, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 648, nil, + nil, nil, nil, nil, nil, nil, nil, 648, 648, 648, + 648, nil, nil, nil, 648, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 1089, 1089, 1089, 1089, nil, + 1089, 1089, 1089, 1089, nil, nil, nil, nil, 1089, 1089, + nil, nil, nil, nil, nil, nil, 1089, nil, 1089, 1089, + 1089, nil, nil, 711, 648, 711, 711, 711, 711, 711, + nil, 713, nil, 713, 713, 713, 713, 713, 711, nil, + nil, nil, nil, nil, nil, nil, 713, nil, 954, nil, + 954, 954, 954, 954, 954, nil, nil, nil, nil, nil, + 711, nil, nil, 954, nil, nil, nil, nil, 713, 711, + 711, 711, 711, nil, nil, nil, 711, 713, 713, 713, + 713, nil, nil, nil, 713, 954, nil, nil, nil, nil, + nil, nil, nil, nil, 954, 954, 954, 954, nil, nil, + 956, 954, 956, 956, 956, 956, 956, 958, nil, 958, + 958, 958, 958, 958, nil, 956, 711, nil, nil, nil, + nil, nil, 958, nil, 713, 960, nil, 960, 960, 960, + 960, 960, nil, nil, nil, nil, nil, 956, nil, nil, + 960, 954, nil, nil, 958, nil, nil, nil, 956, 956, + nil, nil, nil, 956, nil, 958, 958, nil, nil, nil, + 958, 1130, 960, 1130, 1130, 1130, 1130, 1130, nil, nil, + nil, nil, nil, 960, 960, nil, 1130, nil, 960, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 956, nil, nil, nil, nil, 1130, nil, + 958, nil, nil, nil, nil, nil, nil, nil, nil, 1130, + 1130, 226, 226, nil, 1130, 226, nil, nil, 960, nil, + nil, nil, nil, 226, 226, nil, 226, 226, 226, 226, + 226, 226, 226, nil, nil, 226, 226, nil, nil, nil, + 226, 226, 226, 226, nil, nil, nil, nil, nil, 226, + nil, nil, nil, nil, 1130, nil, nil, 226, 226, nil, + 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, + 226, 226, 227, 227, 226, nil, 227, nil, nil, nil, + nil, nil, nil, nil, 227, 227, nil, 227, 227, 227, + 227, 227, 227, 227, nil, nil, 227, 227, nil, nil, + nil, 227, 227, 227, 227, nil, nil, nil, nil, nil, + 227, nil, nil, nil, nil, nil, nil, nil, 227, 227, + nil, 227, 227, 227, 227, 227, 227, 227, 227, 227, + 227, 227, 227, 303, 303, 227, nil, 303, nil, nil, + nil, nil, nil, nil, nil, 303, 303, nil, 303, 303, + 303, 303, 303, 303, 303, nil, nil, 303, 303, nil, + nil, nil, 303, 303, 303, 303, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 303, + 303, nil, 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 521, 521, 303, nil, 521, nil, + nil, nil, nil, nil, nil, nil, 521, 521, nil, 521, + 521, 521, 521, 521, 521, 521, nil, nil, 521, 521, + nil, nil, nil, 521, 521, 521, 521, nil, nil, nil, + nil, nil, 521, nil, nil, nil, nil, nil, nil, nil, + 521, 521, nil, 521, 521, 521, 521, 521, 521, 521, + 521, 521, 521, 521, 521, 522, 522, 521, nil, 522, + nil, nil, nil, nil, nil, nil, nil, 522, 522, nil, + 522, 522, 522, 522, 522, 522, 522, nil, nil, 522, + 522, nil, nil, nil, 522, 522, 522, 522, nil, nil, + nil, nil, nil, 522, nil, nil, nil, nil, nil, nil, + nil, 522, 522, nil, 522, 522, 522, 522, 522, 522, + 522, 522, 522, 522, 522, 522, 595, 595, 522, nil, + 595, nil, nil, nil, nil, nil, nil, nil, 595, 595, + nil, 595, 595, 595, 595, 595, 595, 595, nil, nil, + 595, 595, nil, nil, nil, 595, 595, 595, 595, nil, + nil, nil, nil, nil, 595, nil, nil, nil, nil, nil, + nil, nil, 595, 595, nil, 595, 595, 595, 595, 595, + 595, 595, 595, 595, 595, 595, 595, 596, 596, 595, + nil, 596, nil, nil, nil, nil, nil, nil, nil, 596, + 596, nil, 596, 596, 596, 596, 596, 596, 596, nil, + nil, 596, 596, nil, nil, nil, 596, 596, 596, 596, + nil, nil, nil, nil, nil, 596, nil, nil, nil, nil, + nil, nil, nil, 596, 596, nil, 596, 596, 596, 596, + 596, 596, 596, 596, 596, 596, 596, 596, 605, 605, + 596, nil, 605, nil, nil, nil, nil, nil, nil, nil, + 605, 605, nil, 605, 605, 605, 605, 605, 605, 605, + nil, nil, 605, 605, nil, nil, nil, 605, 605, 605, + 605, nil, nil, nil, nil, nil, 605, nil, nil, nil, + nil, nil, nil, nil, 605, 605, nil, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, 605, 606, + 606, 605, nil, 606, nil, nil, nil, nil, nil, nil, + nil, 606, 606, nil, 606, 606, 606, 606, 606, 606, + 606, nil, nil, 606, 606, nil, nil, nil, 606, 606, + 606, 606, nil, nil, nil, nil, nil, 606, nil, nil, + nil, nil, nil, nil, nil, 606, 606, nil, 606, 606, + 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, + 633, 633, 606, nil, 633, nil, nil, nil, nil, nil, + nil, nil, 633, 633, nil, 633, 633, 633, 633, 633, + 633, 633, nil, nil, 633, 633, nil, nil, nil, 633, + 633, 633, 633, nil, nil, nil, nil, nil, 633, nil, + nil, nil, nil, nil, nil, nil, 633, 633, nil, 633, + 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, + 633, 634, 634, 633, nil, 634, nil, nil, nil, nil, + nil, nil, nil, 634, 634, nil, 634, 634, 634, 634, + 634, 634, 634, nil, nil, 634, 634, nil, nil, nil, + 634, 634, 634, 634, nil, nil, nil, nil, nil, 634, + nil, nil, nil, nil, nil, nil, nil, 634, 634, nil, + 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, + 634, 634, 640, 640, 634, nil, 640, nil, nil, nil, + nil, nil, nil, nil, 640, 640, nil, 640, 640, 640, + 640, 640, 640, 640, nil, nil, 640, 640, nil, nil, + nil, 640, 640, 640, 640, nil, nil, nil, nil, nil, + 640, nil, nil, nil, nil, nil, nil, nil, 640, 640, + nil, 640, 640, 640, 640, 640, 640, 640, 640, 640, + 640, 640, 640, 641, 641, 640, nil, 641, nil, nil, + nil, nil, nil, nil, nil, 641, 641, nil, 641, 641, + 641, 641, 641, 641, 641, nil, nil, 641, 641, nil, + nil, nil, 641, 641, 641, 641, nil, nil, nil, nil, + nil, 641, nil, nil, nil, nil, nil, nil, nil, 641, + 641, nil, 641, 641, 641, 641, 641, 641, 641, 641, + 641, 641, 641, 641, 678, 678, 641, nil, 678, nil, + nil, nil, nil, nil, nil, nil, 678, 678, nil, 678, + 678, 678, 678, 678, 678, 678, nil, nil, 678, 678, + nil, nil, nil, 678, 678, 678, 678, nil, nil, nil, + nil, nil, 678, nil, nil, nil, nil, nil, nil, nil, + 678, 678, nil, 678, 678, 678, 678, 678, 678, 678, + 678, 678, 678, 678, 678, 679, 679, 678, nil, 679, + nil, nil, nil, nil, nil, nil, nil, 679, 679, nil, + 679, 679, 679, 679, 679, 679, 679, nil, nil, 679, + 679, nil, nil, nil, 679, 679, 679, 679, nil, nil, + nil, nil, nil, 679, nil, nil, nil, nil, nil, nil, + nil, 679, 679, nil, 679, 679, 679, 679, 679, 679, + 679, 679, 679, 679, 679, 679, 1127, 1127, 679, nil, + 1127, nil, nil, nil, nil, nil, nil, nil, 1127, 1127, + nil, 1127, 1127, 1127, 1127, 1127, 1127, 1127, nil, nil, + 1127, 1127, nil, nil, nil, 1127, 1127, 1127, 1127, nil, + nil, nil, nil, nil, 1127, nil, nil, nil, nil, nil, + nil, nil, 1127, 1127, nil, 1127, 1127, 1127, 1127, 1127, + 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1128, 1128, 1127, + nil, 1128, nil, nil, nil, nil, nil, nil, nil, 1128, + 1128, nil, 1128, 1128, 1128, 1128, 1128, 1128, 1128, nil, + nil, 1128, 1128, nil, nil, nil, 1128, 1128, 1128, 1128, + nil, nil, nil, nil, nil, 1128, nil, nil, nil, nil, + nil, nil, nil, 1128, 1128, nil, 1128, 1128, 1128, 1128, + 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1178, 1178, + 1128, nil, 1178, nil, nil, nil, nil, nil, nil, nil, + 1178, 1178, nil, 1178, 1178, 1178, 1178, 1178, 1178, 1178, + nil, nil, 1178, 1178, nil, nil, nil, 1178, 1178, 1178, + 1178, nil, nil, nil, nil, nil, 1178, nil, nil, nil, + nil, nil, nil, nil, 1178, 1178, nil, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, nil, + nil, 1178 ] + +racc_action_pointer = [ + nil, 52, 1004, 256, nil, -110, nil, 5323, 1133, 170, + 24870, 24998, 190, nil, 176, 191, 482, 259, -62, 58, + 124, 138, nil, -68, 5454, 1004, 25382, 349, nil, 171, + nil, -8, 5595, 5705, 5839, 5970, 6101, nil, 1148, 23012, + 23143, nil, 320, 356, 466, 435, 6232, 6363, 310, 6494, + 6625, 556, 6756, 375, 333, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 6897, nil, 1292, 7034, 7165, -23, + nil, 7296, 7427, nil, nil, 7558, 23282, 23413, 23544, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 235, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 0, 112, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 7701, nil, nil, nil, nil, + 7844, 7975, 8106, 8237, 8380, nil, 1436, nil, 673, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 393, nil, 1580, + 8511, 8642, 8773, 8904, 9035, 9166, 27600, 27661, nil, nil, + 387, 1724, 415, nil, 358, 15855, 430, 1868, 9297, 9428, + 9559, nil, nil, 519, -85, -29, 550, -23, 469, 584, + nil, 9690, 214, 243, 2012, 586, nil, nil, 9821, 9952, + 10083, 10214, 10345, 10476, 10607, 10738, 10869, 11000, 11131, 11262, + 11393, 11524, 11655, 11786, 11917, 12048, 12179, 12310, 12441, 12572, + nil, nil, nil, nil, 12703, nil, nil, 339, 409, 513, + 523, 531, 556, 582, 583, 625, 630, nil, nil, nil, + 12834, nil, nil, 27722, nil, nil, 594, 12965, 13096, nil, + nil, nil, nil, nil, nil, nil, 13227, nil, 1436, nil, + 562, 572, nil, 13358, 624, nil, 13489, nil, nil, 13620, + 13751, nil, nil, -77, nil, 13894, 1277, 623, 619, 2156, + 636, 683, 647, 23675, 2300, 692, 813, 831, 745, 870, + nil, 720, 686, 225, 741, 746, nil, nil, nil, 757, + 360, 716, 23814, nil, 523, 898, 2732, 2876, 790, nil, + 792, 14025, nil, 772, 2444, nil, nil, 275, 429, 777, + 761, 539, 795, nil, 606, -1, 11, 14156, 2588, 2732, + 230, 875, 768, -18, 10, 903, 850, 11, 883, nil, + nil, 479, 728, 590, nil, 904, nil, 802, 14287, nil, + 15885, nil, 193, 294, 405, 463, 468, -41, -27, 506, + nil, nil, nil, nil, nil, nil, nil, 797, 25126, nil, + nil, nil, nil, 801, nil, 876, 788, 789, 14418, nil, + nil, 778, nil, 918, 140, 897, nil, nil, 1148, nil, + nil, nil, nil, nil, 1292, 814, nil, 815, 817, 613, + 691, 14559, nil, nil, nil, nil, 222, 361, 862, nil, + nil, 14691, 14827, 14964, 946, 947, nil, nil, -1, 828, + 827, 841, nil, nil, 843, 844, 845, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 834, 2574, nil, nil, + 15095, nil, nil, nil, nil, nil, nil, nil, 932, nil, + nil, 933, 385, 15226, 976, nil, nil, nil, -33, nil, + 903, 27783, 27844, 15357, 141, 15488, 15619, 15750, 853, 854, + nil, nil, nil, 3020, 3164, 672, 791, 934, 937, 947, + 950, 4748, 4892, 5036, 3308, 3452, 3596, 3740, 3884, 4028, + 2760, 2904, 4172, 4316, 1580, 4460, nil, -7, nil, 15891, + nil, nil, nil, nil, 16021, 887, 885, 890, nil, nil, + nil, 899, nil, nil, 16152, nil, 16283, nil, 16414, nil, + 217, nil, nil, nil, 16557, 1421, nil, 900, 898, nil, + nil, 899, 23945, 911, 16700, 27905, 27966, 1004, 954, nil, + nil, 24076, 911, nil, 16831, 28027, 28088, 16962, 4604, 17093, + nil, nil, 1038, 974, nil, 17224, nil, nil, 17355, nil, + nil, nil, 2876, 1072, nil, 3020, 62, 1076, 1081, 236, + 1084, 17486, 17617, 28149, 28210, 27, nil, nil, 1046, nil, + 28271, 28332, 17748, nil, nil, 490, 3164, nil, 27320, nil, + nil, nil, nil, 725, nil, nil, nil, 975, nil, nil, + 400, nil, 461, nil, nil, 964, nil, 966, nil, nil, + nil, 25254, nil, 17891, 18022, 970, 18153, 18284, 28393, 28454, + 18427, 18558, 715, 1014, 18689, 18820, 18951, 19082, 1020, nil, + nil, 19213, nil, 19344, 1021, nil, 1075, nil, 259, 1724, + 1085, 1115, 19475, nil, nil, nil, nil, 715, nil, nil, + 649, 27412, nil, 27420, nil, 25827, nil, 986, 19606, nil, + 2603, nil, 1001, 1003, 1566, 1007, nil, nil, nil, nil, + 1095, 1098, nil, nil, nil, 237, 280, 471, 610, 1015, + 19737, 19868, nil, nil, nil, 1023, 25495, nil, 1147, nil, + 1130, -20, nil, nil, 19999, nil, 1047, 1052, 1153, nil, + 1031, nil, 1097, nil, nil, nil, 20130, nil, 134, 24207, + 1052, nil, 1057, 217, 248, 1100, 250, 1148, 1101, 1071, + 24338, nil, 585, 1142, 1868, 20261, nil, nil, 635, 824, + nil, 1214, nil, nil, nil, nil, nil, 1220, 1225, nil, + nil, 26, 1105, 40, 41, 151, 177, 3308, 827, 1292, + nil, 1108, 3452, 20392, nil, 1233, 63, 1114, nil, nil, + nil, 3596, nil, nil, 1113, nil, 1118, 1126, 1127, nil, + nil, 1129, 20523, 1142, 390, 391, 720, 859, nil, 2012, + 20654, nil, 1140, nil, nil, nil, nil, nil, nil, nil, + 1162, nil, nil, nil, 20785, 20916, 21047, 1270, nil, 3740, + 1147, 1195, nil, nil, 1152, nil, 1238, nil, nil, 1166, + 1167, nil, 1168, 1171, nil, 1172, nil, nil, nil, 1176, + 2633, 2613, nil, nil, 21178, 21309, 21440, 21571, 436, 352, + 25578, nil, 25676, 21702, nil, nil, 1199, nil, nil, 1215, + 1199, nil, nil, 788, 3884, nil, nil, nil, 1198, 254, + nil, 81, nil, 1324, nil, 21833, 1325, nil, nil, nil, + 21964, 4028, 71, 1339, nil, 1343, 527, 4172, nil, nil, + nil, nil, 1237, 1283, 1251, nil, 1246, 484, nil, nil, + 22095, nil, 2156, 1339, 1343, 2300, nil, 4316, nil, nil, + 32, 24469, nil, nil, 27437, nil, 27489, nil, 27496, nil, + 27514, nil, nil, nil, nil, 1255, 1258, 22226, 22357, nil, + -77, nil, nil, nil, nil, 1287, nil, nil, nil, 555, + 25774, 266, nil, 1271, 1354, 1273, nil, nil, 25873, nil, + nil, 476, nil, nil, 785, nil, nil, 27090, 27188, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1616, 603, nil, nil, 2444, 4460, nil, nil, 1283, 1284, + nil, 1286, 1289, 1291, nil, 1316, 1296, 1284, 24600, nil, + nil, nil, nil, nil, 33, nil, nil, nil, 193, nil, + nil, nil, 1424, 4604, 4748, 1710, nil, nil, nil, nil, + 4892, 34, 35, 1190, 1388, 36, nil, 1311, 1312, 1315, + 1316, 3100, 3244, 25971, 1399, 26069, 86, 157, 26167, 26265, + 699, -32, 1322, 1342, nil, 26363, nil, 1340, 290, nil, + 1362, 26461, 26559, nil, 635, 1390, 266, nil, 27222, 27320, + nil, nil, nil, nil, 22488, nil, nil, nil, 813, nil, + nil, 15910, nil, nil, 25974, nil, 14622, nil, nil, 1369, + 24731, 1334, 1424, 5036, 26657, nil, nil, nil, nil, 1379, + 1487, 678, nil, nil, nil, 1509, 22619, 28515, 28576, 42, + 27550, nil, nil, nil, nil, 1384, nil, 1389, nil, nil, + nil, nil, 1393, 1395, 1396, 1400, 1402, 1405, nil, nil, + nil, 1453, 1415, 1416, nil, 1420, nil, nil, -69, 1422, + nil, nil, nil, nil, nil, nil, 1430, 1428, nil, nil, + 1429, 1430, 1433, 1435, nil, 1436, nil, 1436, 28637, nil, + 864, 98, 841, nil, nil, nil, 1854, nil, 1440, 102, + 138, 145, 181, 1438, 26755, nil, nil, nil, nil, nil, + nil, nil, 26853, nil, 392, nil, 26951, nil, nil, 26072, + nil, 23190, nil, 23722, nil, 25565, nil, nil, 1484, 1488, + nil, nil, 22750, 22881, nil, 146, nil, 1454, 1455, nil, + nil, 1456, 1459, 1460, 1461, 5180, nil, nil, 27049, 26366, + nil, nil, nil, nil, 35, 1463, nil, nil, nil, nil ] + +racc_action_default = [ + -1, -742, -4, -742, -2, -728, -5, -742, -8, -742, + -742, -742, -742, -31, -742, -742, -36, -742, -742, -638, + -638, -314, -53, -730, -742, -60, -742, -68, -69, -70, + -74, -288, -288, -288, -325, -352, -353, -87, -13, -91, + -99, -101, -742, -625, -626, -742, -742, -742, -742, -742, + -742, -239, -742, -730, -255, -305, -306, -307, -308, -309, + -310, -311, -312, -313, -718, -316, -13, -741, -706, -333, + -335, -742, -742, -62, -62, -728, -742, -742, -742, -354, + -355, -357, -358, -359, -360, -419, -563, -564, -565, -566, + -589, -569, -570, -591, -593, -576, -581, -585, -587, -602, + -603, -604, -589, -606, -608, -609, -610, -611, -612, -613, + -614, -716, -717, -617, -618, -619, -620, -621, -622, -623, + -624, -629, -630, 1250, -3, -729, -737, -738, -739, -7, + -742, -742, -742, -742, -742, -9, -4, -19, -742, -130, + -131, -132, -133, -134, -135, -136, -140, -141, -142, -143, + -144, -145, -146, -147, -148, -149, -150, -151, -152, -153, + -154, -155, -156, -157, -158, -159, -160, -161, -162, -163, + -164, -165, -166, -167, -168, -169, -170, -171, -172, -173, + -174, -175, -176, -177, -178, -179, -180, -181, -182, -183, + -184, -185, -186, -187, -188, -189, -190, -191, -192, -193, + -194, -195, -196, -197, -198, -199, -200, -201, -202, -203, + -204, -205, -206, -207, -208, -209, -210, -24, -137, -13, + -742, -742, -742, -742, -742, -278, -742, -742, -726, -727, + -742, -13, -637, -635, -661, -661, -742, -13, -742, -742, + -730, -731, -57, -742, -625, -626, -742, -314, -742, -742, + -245, -742, -638, -638, -13, -742, -741, -741, -222, -223, + -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, + -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, + -259, -260, -261, -262, -742, -64, -65, -742, -130, -131, + -170, -171, -172, -188, -193, -200, -203, -625, -626, -704, + -742, -428, -430, -742, -724, -725, -75, -278, -742, -332, + -434, -443, -445, -82, -440, -83, -730, -84, -266, -283, + -293, -293, -287, -291, -294, -295, -299, -589, -708, -712, + -715, -85, -86, -728, -14, -742, -17, -742, -89, -13, + -730, -742, -92, -95, -13, -107, -108, -742, -742, -115, + -325, -328, -730, -742, -638, -638, -352, -353, -356, -441, + -742, -97, -742, -103, -322, -742, -224, -225, -607, -233, + -234, -742, -246, -741, -13, -318, -267, -730, -730, -742, + -742, -730, -742, -334, -61, -742, -742, -742, -13, -13, + -728, -742, -729, -625, -626, -742, -742, -314, -742, -370, + -371, -125, -126, -742, -128, -742, -314, -633, -742, -348, + -661, -567, -742, -742, -742, -742, -742, -742, -742, -742, + -6, -740, -25, -26, -27, -28, -29, -742, -742, -21, + -22, -23, -138, -742, -32, -35, -301, -742, -299, -300, + -33, -742, -37, -742, -314, -50, -52, -211, -271, -294, + -54, -55, -38, -212, -271, -730, -279, -293, -293, -716, + -717, -288, -438, -718, -719, -720, -717, -716, -288, -437, + -439, -718, -720, -742, -555, -742, -383, -384, -687, -730, + -703, -703, -643, -644, -646, -646, -646, -660, -662, -663, + -664, -665, -666, -667, -668, -669, -670, -742, -672, -674, + -676, -681, -683, -684, -685, -692, -694, -695, -697, -698, + -699, -701, -742, -742, -742, -46, -219, -56, -730, -331, + -742, -742, -742, -278, -322, -742, -742, -742, -742, -742, + -741, -457, -741, -220, -221, -226, -227, -228, -229, -230, + -231, -235, -236, -237, -238, -240, -241, -242, -243, -244, + -247, -248, -249, -250, -730, -263, -66, -730, -449, -288, + -716, -717, -72, -76, -662, -730, -293, -730, -289, -447, + -449, -730, -327, -284, -742, -285, -742, -290, -742, -298, + -742, -711, -714, -12, -729, -16, -18, -730, -88, -320, + -104, -93, -742, -730, -278, -742, -742, -114, -742, -637, + -607, -742, -100, -105, -742, -742, -742, -742, -264, -742, + -265, -741, -742, -742, -268, -736, -735, -270, -736, -323, + -324, -707, -13, -361, -362, -13, -742, -742, -742, -742, + -742, -742, -278, -742, -742, -322, -62, -125, -126, -127, + -742, -742, -278, -344, -631, -742, -13, -420, -661, -423, + -568, -590, -595, -742, -597, -571, -592, -742, -594, -575, + -742, -578, -742, -580, -583, -742, -584, -742, -605, -10, + -20, -742, -30, -742, -742, -304, -742, -278, -742, -742, + -742, -742, -442, -742, -280, -282, -742, -742, -77, -277, + -435, -742, -447, -742, -79, -436, -44, -47, -730, -256, + -253, -741, -741, -350, -524, -686, -636, -742, -641, -642, + -742, -742, -653, -742, -656, -742, -658, -742, -742, -372, + -742, -374, -376, -379, -382, -730, -675, -696, -700, -639, + -45, -254, -351, -330, -732, -716, -717, -717, -716, -730, + -742, -742, -741, -455, -741, -742, -742, -705, -742, -450, + -71, -431, -447, -273, -280, -275, -742, -409, -742, -326, + -293, -292, -296, -297, -709, -710, -742, -15, -90, -742, + -96, -102, -730, -716, -717, -276, -721, -113, -742, -98, + -742, -218, -321, -232, -251, -742, -317, -319, -730, -741, + -363, -741, -63, -364, -365, -338, -339, -742, -742, -741, + -341, -742, -730, -716, -717, -721, -321, -13, -125, -126, + -129, -730, -13, -742, -346, -742, -742, -730, -596, -600, + -601, -13, -572, -573, -577, -579, -582, -586, -588, -139, + -34, -302, -299, -730, -716, -717, -717, -716, -51, -272, + -742, -733, -293, -40, -214, -41, -215, -78, -42, -217, + -742, -43, -216, -80, -742, -742, -742, -741, -368, -13, + -556, -741, -557, -558, -703, -682, -687, -702, -645, -646, + -646, -673, -646, -646, -693, -646, -670, -386, -688, -730, + -742, -742, -381, -671, -742, -742, -742, -742, -442, -730, + -742, -456, -742, -742, -67, -429, -409, -433, -432, -742, + -730, -444, -410, -730, -13, -446, -286, -713, -94, -442, + -106, -730, -269, -742, -366, -742, -742, -340, -342, -741, + -742, -13, -442, -742, -442, -742, -742, -13, -349, -421, + -424, -426, -413, -742, -742, -574, -303, -442, -39, -213, + -281, -81, -48, -49, -258, -257, -11, -13, -562, -369, + -742, -742, -560, -640, -742, -649, -742, -651, -742, -654, + -742, -657, -659, -373, -375, -377, -380, -742, -742, -58, + -465, -468, -469, -470, -471, -473, -475, -478, -479, -534, + -730, -491, -494, -504, -508, -513, -515, -516, -519, -520, + -589, -523, -525, -526, -527, -532, -533, -742, -742, -537, + -538, -539, -540, -541, -542, -543, -544, -545, -546, -547, + -742, -742, -553, -59, -252, -13, -73, -274, -703, -703, + -390, -392, -392, -392, -408, -742, -730, -670, -678, -679, + -690, -448, -329, -336, -742, -337, -741, -296, -741, -343, + -345, -632, -742, -13, -13, -742, -422, -598, -599, -561, + -13, -625, -626, -742, -742, -314, -559, -646, -646, -646, + -646, -742, -742, -466, -742, -742, -476, -477, -742, -742, + -742, -496, -730, -730, -490, -497, -501, -742, -742, -493, + -742, -742, -742, -507, -514, -518, -742, -522, -530, -531, + -535, -536, -548, -549, -742, -126, -551, -451, -742, -388, + -389, -393, -399, -401, -742, -404, -742, -406, -411, -742, + -742, -677, -742, -13, -742, -452, -453, -454, -347, -742, + -742, -730, -415, -417, -418, -555, -278, -742, -742, -322, + -742, -647, -650, -652, -655, -378, -467, -504, -472, -474, + -483, -487, -730, -730, -730, -730, -730, -730, -552, -488, + -489, -511, -498, -499, -502, -730, -589, -734, -730, -505, + -509, -512, -517, -521, -528, -529, -730, -703, -680, -391, + -392, -392, -392, -392, -691, -392, -412, -689, -742, -322, + -741, -742, -462, -425, -427, -414, -742, -554, -730, -716, + -717, -721, -321, -646, -742, -480, -481, -482, -484, -485, + -486, -503, -742, -492, -742, -495, -742, -550, -387, -742, + -396, -742, -398, -742, -402, -742, -405, -407, -321, -721, + -367, -458, -742, -742, -416, -442, -648, -505, -500, -506, + -510, -392, -392, -392, -392, -13, -463, -464, -742, -742, + -394, -397, -400, -403, -741, -392, -459, -460, -461, -395 ] + +racc_goto_table = [ + 44, 302, 310, 314, 412, 44, 142, 142, 455, 385, + 386, 798, 286, 390, 383, 567, 419, 319, 319, 319, + 622, 625, 142, 226, 298, 242, 128, 384, 384, 475, + 701, 384, 285, 639, 304, 514, 44, 346, 346, 718, + 496, 496, 15, 342, 358, 358, 857, 15, 630, 708, + 709, 388, 389, 137, 218, 871, 145, 145, 530, 532, + 439, 440, 575, 742, 44, 744, 819, 731, 422, 423, + 424, 425, 913, 563, 394, 298, 298, 453, 15, 17, + 125, 358, 358, 358, 17, 864, 384, 384, 384, 384, + 565, 516, 135, 870, 368, 872, 128, 303, 461, 468, + 464, 464, 446, 124, 338, 446, 15, 237, 321, 321, + 321, 306, 313, 315, 602, 17, 399, 682, 874, 446, + 696, 479, 512, 44, 361, 320, 320, 320, 725, 487, + 487, 452, 44, 761, 44, 761, 916, 340, 609, 4, + 933, 378, 381, 17, 756, 515, 764, 614, 617, 1022, + 964, 621, 890, 1174, 892, 230, 236, 969, 377, 1013, + 730, 972, 1122, 972, 1079, 15, 1124, 317, 331, 332, + 966, 129, 612, 391, 15, 559, 15, 464, 450, 451, + 1072, 904, 748, 763, 1090, 1091, 1137, 8, 764, 1, + 1144, 1147, 8, 2, 758, 517, 518, 462, 1153, 575, + 1155, 946, 17, 407, 409, 767, 1159, 824, 319, 826, + 341, 17, 827, 17, 828, 217, 496, 44, 660, 662, + 400, 434, 445, 472, 763, 445, 1025, 435, 1073, 44, + 599, 599, 428, 792, 287, 44, 746, 752, 375, 445, + 671, 580, 371, 761, 761, 379, 751, 299, 521, 712, + 714, 716, 44, 380, 398, 764, 557, 643, 1174, 15, + 374, 441, 719, 1136, 441, 613, 812, 850, 1142, 1145, + 810, 15, 927, 427, 646, 1164, 1165, 15, 441, 656, + 658, 661, 661, 763, 965, 1023, 797, 1024, 1102, 420, + 319, 319, 304, 763, 15, 731, 17, 649, 17, 319, + 1026, 17, 1121, 1224, 871, 487, 739, 1124, 17, 647, + 8, 437, 437, 761, 17, 17, 1143, 1146, 1227, 426, + 1015, 8, 929, 410, 310, 626, 1228, 899, 816, 1229, + 314, 17, 964, 44, 1043, 1044, 1057, 44, 1203, 558, + 237, 346, 44, 384, 770, 569, 645, 1170, 358, 1109, + 1135, 879, 595, 779, 128, 556, 570, 896, 1115, 874, + 346, 1181, 1246, 763, 384, 1235, 603, 358, 1138, 1139, + 605, 1068, 44, 1069, 1078, 15, 785, 772, 516, 15, + 453, 1182, 321, 1116, 15, 972, 44, 44, 528, 529, + 321, 433, 1081, 461, 468, 464, 464, 1161, 566, 320, + 633, 888, 1162, 861, 950, 338, 600, 320, 584, 944, + 338, 128, 17, 411, 15, 802, 17, 413, 414, 415, + 586, 17, 416, 1093, 142, 811, 341, 591, 15, 15, + 417, 583, 689, 953, 909, 418, 921, 818, 587, 695, + 1047, 568, 237, 593, 815, 871, 1114, 821, 678, 571, + 813, 17, 1036, 869, 496, 847, 697, 781, 865, 1168, + 833, 853, 900, 1220, 922, 17, 17, 775, nil, 464, + 464, 670, nil, 924, 145, nil, 1167, 775, nil, 464, + 464, nil, nil, 1171, nil, 719, 1172, nil, 629, 882, + 1152, nil, 462, nil, nil, 937, 697, 1160, nil, 761, + nil, 906, 943, nil, nil, 775, 319, 464, 464, nil, + 764, 341, nil, 775, 464, 464, 341, 496, 472, 496, + 585, 908, 944, nil, nil, nil, 825, nil, 825, 763, + 689, nil, nil, 729, nil, 817, nil, nil, nil, 844, + 846, 688, 862, 487, 849, nil, 852, nil, 694, nil, + 461, 468, 464, 464, nil, nil, nil, 446, 912, 871, + 627, 628, nil, nil, nil, nil, 462, 446, 446, nil, + 1110, nil, 446, nil, 446, nil, 462, 319, nil, nil, + nil, nil, 44, 906, nil, 1050, nil, 1099, 1100, 1247, + 346, 1231, 472, 843, 845, nil, 603, 358, 848, 346, + 851, 919, 472, 866, 462, 603, 358, nil, nil, 1160, + 925, nil, 462, nil, 807, 319, nil, 1160, nil, nil, + 44, 1230, nil, 44, 15, 319, 1248, nil, nil, nil, + 472, nil, nil, nil, 955, 957, 472, 959, 961, 750, + 962, 1096, 1074, nil, 44, 719, 719, 793, 760, 462, + nil, nil, nil, 1230, nil, nil, nil, nil, nil, nil, + 319, 17, 15, nil, nil, 15, 814, 142, nil, 1113, + nil, 44, nil, nil, nil, 472, nil, 445, 44, nil, + nil, 1187, nil, nil, nil, nil, 15, 445, 445, 788, + nil, nil, 445, 939, 445, 1117, 898, nil, nil, 17, + 1148, nil, 17, nil, nil, nil, nil, nil, nil, 1027, + nil, nil, nil, 15, 829, nil, 441, 145, nil, nil, + 15, 446, 801, 17, 897, 1042, 441, 441, nil, 1141, + nil, 441, 894, 441, 1149, 1150, 1208, 844, 846, 849, + 852, 911, 142, nil, nil, nil, 689, 938, nil, 695, + 17, 926, 285, 17, nil, nil, nil, 17, 842, nil, + 496, nil, nil, 17, 17, nil, nil, 346, 17, 384, + 17, nil, nil, 603, 358, nil, nil, nil, 346, nil, + nil, 993, nil, 993, 910, 358, 991, nil, 991, nil, + nil, nil, nil, 437, 789, nil, nil, 791, nil, 18, + nil, nil, nil, nil, 18, 44, nil, 1198, 1199, 1200, + 44, nil, nil, 1097, nil, 867, 1221, nil, 867, 44, + 939, 243, 1131, 1132, 1133, 1134, 719, 719, 842, nil, + nil, 243, 243, 243, nil, 18, 347, 347, 697, nil, + nil, 445, 1120, nil, nil, nil, nil, 15, nil, nil, + 1225, nil, 15, 1034, nil, nil, nil, 44, 830, nil, + nil, 15, nil, 18, nil, 838, nil, nil, 243, 243, + nil, 384, 243, 395, 405, 405, nil, nil, nil, nil, + 441, nil, nil, nil, 17, nil, nil, nil, 1007, 17, + 1007, nil, nil, nil, nil, nil, nil, nil, 17, 15, + nil, nil, 44, nil, 1086, nil, nil, 1027, nil, 1188, + 1027, nil, nil, nil, nil, nil, nil, 17, nil, 44, + nil, nil, 18, nil, nil, 44, nil, 243, 243, 243, + 243, 18, nil, 18, nil, nil, 17, nil, nil, nil, + nil, nil, nil, nil, 15, 44, 1019, 1041, nil, 1052, + nil, nil, nil, nil, nil, nil, 358, nil, 1226, 993, + 993, 15, nil, nil, 991, 991, nil, 15, nil, 993, + nil, nil, nil, nil, 991, 993, nil, nil, 1007, 923, + 991, 17, nil, nil, nil, nil, 1007, 15, nil, nil, + nil, 1056, nil, 934, 866, 1007, 1007, nil, 17, 775, + nil, 464, 464, nil, 17, 993, nil, nil, nil, nil, + 991, 1020, nil, 44, nil, 1027, 18, 243, 443, 243, + 243, 443, 243, 873, 17, 875, 298, nil, 18, nil, + nil, 949, 1166, 358, 18, 443, 243, 243, nil, nil, + nil, 44, 44, nil, nil, nil, nil, 970, 44, 970, + 384, 18, 464, nil, nil, 15, nil, nil, 1127, nil, + nil, 1007, nil, 1007, nil, nil, 1007, 1007, nil, nil, + 1204, nil, nil, 1007, nil, nil, 1031, nil, nil, 1007, + 1007, nil, nil, 15, 15, nil, 1007, 1007, nil, nil, + 15, nil, 17, 1038, 1103, 1105, 1107, 243, 462, nil, + nil, nil, nil, nil, 243, 243, 233, 233, 298, 319, + nil, 44, 1007, 243, nil, 358, nil, nil, nil, 1049, + 17, 17, nil, nil, 472, nil, nil, 17, nil, nil, + nil, nil, 18, nil, nil, nil, 18, 1071, nil, nil, + 347, 18, nil, nil, 1019, 1085, nil, 1019, nil, 1019, + nil, nil, nil, 15, 376, nil, nil, 1028, nil, 347, + 1236, 1237, nil, nil, nil, 19, nil, nil, nil, nil, + 19, 18, nil, nil, 472, nil, nil, nil, 384, 384, + nil, nil, nil, nil, 243, 18, 18, nil, nil, nil, + 17, nil, 1007, nil, nil, nil, nil, nil, nil, nil, + 1007, 19, 354, 354, 1007, 243, 867, nil, nil, 1020, + nil, nil, 1020, 1021, 1020, 1119, nil, nil, nil, nil, + 1071, nil, 1125, nil, nil, 1071, 1071, nil, nil, 19, + nil, nil, nil, 44, nil, nil, 1007, nil, 1158, 354, + 354, 354, nil, 1210, 1212, 1214, 1216, 239, 1217, nil, + nil, nil, 1019, nil, 1019, nil, 1019, nil, 1019, nil, + nil, nil, nil, 999, 1058, 999, 1059, nil, 1060, nil, + 243, 970, nil, nil, nil, 15, nil, 373, nil, nil, + nil, nil, 1019, nil, nil, 1180, nil, nil, 19, nil, + nil, nil, nil, nil, nil, nil, nil, 19, 20, 19, + nil, nil, nil, 20, 1240, 1241, 1242, 1243, nil, nil, + 243, nil, 17, nil, nil, nil, nil, 1020, 1249, 1020, + 243, 1020, nil, 1020, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 20, 355, 355, nil, nil, 233, + 233, nil, nil, 531, 531, nil, nil, 1020, nil, nil, + nil, nil, 1028, 999, nil, 1028, nil, nil, 1028, nil, + 1028, 999, 20, nil, nil, nil, nil, nil, nil, nil, + 999, 999, 355, 355, 355, nil, nil, nil, nil, nil, + nil, 18, 19, nil, 19, nil, nil, 19, nil, 347, + nil, 243, nil, nil, 19, nil, nil, nil, 347, nil, + 19, 19, nil, nil, nil, nil, nil, 1244, nil, nil, + 519, nil, nil, nil, 1173, nil, 1175, 19, nil, 18, + nil, 20, 18, nil, nil, nil, nil, nil, nil, 243, + 20, nil, 20, nil, nil, nil, 999, nil, 999, 243, + 1193, 999, 999, 18, nil, nil, nil, nil, 999, nil, + nil, nil, nil, nil, 999, 999, nil, nil, nil, nil, + 610, 999, 999, 1028, nil, 1028, nil, 1028, nil, 1028, + 18, nil, nil, 443, 243, nil, nil, 18, nil, nil, + nil, nil, nil, 443, 443, nil, 572, 999, 443, nil, + 443, nil, nil, 1028, nil, nil, nil, nil, 19, nil, + nil, nil, 19, nil, nil, nil, 354, 19, nil, nil, + 588, nil, nil, nil, nil, 20, nil, 20, nil, 1232, + 20, 1233, nil, 1234, nil, 354, nil, 20, nil, nil, + nil, nil, nil, 20, 20, nil, nil, 19, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 21, 1245, + 20, 19, 19, 21, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 347, 999, nil, nil, + nil, nil, nil, nil, nil, 999, 598, 347, nil, 999, + nil, nil, 243, nil, 21, 349, 349, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 616, 616, nil, 18, 616, nil, nil, nil, 18, + 243, 999, 21, nil, nil, nil, nil, 743, 18, 743, + nil, nil, 397, 406, 406, nil, nil, nil, nil, nil, + nil, 20, nil, nil, nil, 20, nil, 443, nil, 355, + 20, nil, nil, nil, nil, nil, nil, nil, nil, 706, + nil, nil, 243, nil, nil, nil, 18, nil, 355, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 20, 21, nil, nil, nil, nil, nil, nil, nil, 683, + 21, nil, 21, nil, 20, 20, nil, nil, 733, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 610, nil, + nil, 18, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 243, nil, nil, nil, nil, nil, 18, nil, + nil, nil, nil, nil, 18, nil, nil, 747, nil, nil, + nil, nil, nil, nil, nil, 753, nil, 755, nil, nil, + nil, 759, nil, nil, 18, nil, nil, 19, 1053, nil, + nil, nil, nil, nil, nil, 354, nil, 768, nil, nil, + nil, nil, nil, 771, 354, 21, nil, 444, nil, nil, + 444, nil, nil, nil, nil, nil, nil, 21, 745, nil, + nil, nil, nil, 21, 444, 19, nil, nil, 19, 863, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 21, nil, nil, nil, nil, nil, nil, nil, nil, 19, + nil, nil, 18, 382, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 1111, nil, nil, nil, 891, + nil, 891, nil, nil, nil, nil, 19, nil, nil, 19, + 18, 18, nil, 19, nil, nil, nil, 18, nil, 19, + 19, nil, nil, nil, 19, nil, 19, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 20, 21, nil, nil, nil, 21, 531, nil, 355, 349, + 21, 243, nil, nil, nil, 883, nil, 355, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 1177, 349, nil, + 18, nil, nil, nil, nil, nil, nil, nil, 20, nil, + 21, 20, 855, 243, nil, nil, nil, nil, nil, nil, + nil, nil, 354, nil, 21, 21, nil, nil, nil, nil, + nil, nil, 20, 354, 948, nil, nil, nil, 952, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 683, nil, 436, 449, nil, nil, 20, + 19, nil, 20, nil, nil, 19, 20, nil, nil, nil, + nil, nil, 20, 20, 19, nil, nil, 20, nil, 20, + nil, nil, nil, nil, nil, nil, 683, nil, nil, nil, + nil, nil, nil, 19, nil, nil, 743, nil, nil, nil, + nil, nil, 616, nil, nil, nil, nil, nil, nil, 243, + 243, nil, 19, nil, nil, nil, 683, nil, nil, nil, + nil, nil, 18, nil, nil, 683, nil, nil, nil, nil, + nil, 932, nil, nil, nil, nil, nil, nil, nil, 963, + nil, nil, nil, nil, nil, nil, nil, 683, nil, nil, + nil, nil, nil, nil, nil, 355, nil, 19, 577, nil, + 1017, 579, nil, nil, 581, 582, 355, nil, nil, nil, + nil, 1032, nil, nil, 19, nil, nil, nil, nil, nil, + 19, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 20, nil, + 19, nil, nil, 968, 354, nil, nil, 20, nil, nil, + nil, nil, nil, 891, nil, nil, nil, 932, nil, nil, + 21, nil, nil, nil, nil, nil, 20, nil, 349, nil, + nil, nil, nil, nil, nil, nil, nil, 349, nil, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 21, nil, + nil, 21, nil, nil, nil, nil, nil, nil, 19, nil, + nil, nil, nil, 675, nil, nil, nil, nil, nil, nil, + nil, 354, 21, nil, nil, nil, nil, nil, nil, 820, + 20, nil, nil, nil, 683, 1080, 19, 19, nil, nil, + nil, nil, nil, 19, nil, nil, nil, 20, nil, 21, + 31, nil, 444, 20, nil, 31, 21, nil, nil, nil, + nil, nil, 444, 444, nil, nil, 1140, 444, nil, 444, + nil, nil, 31, 20, nil, 726, nil, 355, nil, nil, + 932, nil, 31, 31, 31, nil, 31, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 354, nil, nil, 19, nil, nil, nil, + nil, nil, nil, nil, 31, nil, nil, nil, nil, 31, + 31, 683, nil, 31, nil, nil, 683, 683, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 20, 1195, 1196, 1197, 349, nil, nil, nil, 762, + nil, 382, nil, 765, 355, 1000, 349, 1000, 1205, nil, + nil, nil, nil, nil, nil, nil, 1207, nil, nil, 20, + 20, nil, nil, 31, nil, 1185, 20, nil, 31, 31, + 31, 31, 31, 21, 31, nil, nil, nil, 21, nil, + 762, nil, nil, 382, nil, nil, nil, 21, nil, 683, + 683, 683, nil, nil, nil, nil, 449, nil, nil, 1080, + nil, nil, nil, nil, nil, nil, 444, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 19, nil, + nil, nil, nil, nil, nil, 21, 355, nil, nil, 20, + nil, nil, 683, nil, nil, 1000, nil, nil, nil, 831, + nil, nil, nil, 1000, nil, nil, nil, nil, nil, 762, + 382, nil, 1000, 1000, nil, nil, nil, 31, 31, 31, + 31, 31, 31, 31, nil, nil, nil, 860, nil, 31, + 21, nil, nil, nil, nil, 31, 31, 31, 31, nil, + nil, nil, nil, 878, nil, nil, nil, 21, nil, nil, + nil, nil, 31, 21, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 21, nil, nil, nil, 1055, 1000, 762, + 1000, nil, nil, 1000, 1000, nil, nil, nil, nil, nil, + 1000, 907, nil, nil, nil, nil, 1000, 1000, 31, nil, + nil, nil, nil, 1000, 1000, 31, 31, nil, nil, nil, + nil, 20, nil, nil, 31, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 1000, + nil, nil, nil, 31, nil, nil, nil, 31, nil, nil, + nil, 21, 31, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 406, nil, 1001, 936, 1001, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 21, + 21, nil, 31, nil, nil, nil, 21, nil, nil, nil, + nil, nil, nil, nil, nil, 31, 31, 31, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 31, nil, nil, 1000, + nil, nil, nil, nil, nil, nil, nil, 1000, nil, nil, + nil, 1000, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 406, nil, nil, 21, + nil, nil, nil, nil, 34, 1037, 1001, nil, nil, 34, + nil, nil, nil, 1000, 1001, nil, nil, nil, nil, nil, + nil, nil, nil, 1001, 1001, 382, 34, nil, nil, nil, + nil, 31, nil, nil, nil, nil, 34, 34, 34, nil, + 34, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 34, nil, + nil, 31, nil, 34, 34, nil, nil, 34, nil, nil, + nil, 31, 43, nil, 1002, nil, 1002, 43, nil, 1001, + nil, 1001, nil, nil, 1001, 1001, nil, nil, nil, nil, + nil, 1001, nil, nil, nil, nil, 297, 1001, 1001, nil, + nil, nil, nil, nil, 1001, 1001, nil, nil, 43, 345, + 345, 21, nil, nil, nil, nil, nil, 34, nil, nil, + nil, nil, 34, 34, 34, 34, 34, nil, 34, nil, + 1001, nil, 31, nil, nil, nil, 43, nil, nil, nil, + nil, nil, 31, nil, nil, nil, 393, 297, 297, nil, + 1003, nil, 1003, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1002, nil, nil, nil, nil, nil, + 31, nil, 1002, 31, nil, nil, nil, nil, nil, nil, + 31, 1002, 1002, nil, nil, nil, nil, nil, nil, nil, + 31, nil, nil, nil, 31, 43, nil, nil, nil, nil, + nil, nil, nil, nil, 43, nil, 43, nil, nil, nil, + 1001, 34, 34, 34, 34, 34, 34, 34, 1001, nil, + nil, 31, 1001, 34, 31, 31, nil, nil, 31, 34, + 34, 34, 34, nil, 31, 31, nil, nil, nil, 31, + 1003, 31, nil, nil, nil, nil, 34, 1002, 1003, 1002, + nil, nil, 1002, 1002, 1001, nil, nil, 1003, 1003, 1002, + nil, nil, nil, nil, nil, 1002, 1002, nil, nil, nil, + nil, nil, 1002, 1002, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 43, + nil, nil, 34, nil, nil, nil, nil, nil, 1002, 34, + 34, 43, nil, nil, nil, nil, nil, 43, 34, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 1003, 43, 1003, nil, 34, 1003, 1003, + nil, 34, nil, 31, nil, 1003, 34, nil, nil, nil, + nil, 1003, 1003, 1004, nil, 1004, nil, nil, 1003, 1003, + nil, nil, nil, nil, nil, 31, nil, nil, nil, nil, + 31, 31, nil, nil, nil, nil, 34, nil, nil, 31, + nil, nil, nil, nil, 1003, nil, nil, nil, 1002, 34, + 34, 34, nil, nil, nil, nil, 1002, nil, 31, nil, + 1002, nil, nil, nil, nil, nil, 1005, nil, 1005, nil, + 34, nil, nil, 31, nil, 43, nil, 31, nil, 43, + nil, nil, nil, 345, 43, nil, nil, nil, nil, nil, + nil, nil, 1002, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 345, 1004, nil, nil, nil, nil, nil, nil, + nil, 1004, nil, nil, 43, nil, nil, nil, nil, nil, + 1004, 1004, 31, nil, 1003, nil, nil, nil, 43, 43, + nil, nil, 1003, 31, nil, 34, 1003, nil, nil, 31, + nil, nil, nil, nil, nil, 31, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1005, nil, nil, nil, + nil, nil, nil, nil, 1005, 31, nil, nil, 1003, nil, + nil, nil, nil, 1005, 1005, 34, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 34, 1004, nil, 1004, nil, + nil, 1004, 1004, nil, nil, nil, nil, nil, 1004, nil, + nil, nil, nil, nil, 1004, 1004, nil, nil, nil, nil, + nil, 1004, 1004, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 31, nil, nil, nil, 1004, nil, 1005, + nil, 1005, nil, nil, 1005, 1005, 34, nil, nil, nil, + nil, 1005, nil, nil, nil, nil, 34, 1005, 1005, nil, + nil, 31, 31, nil, 1005, 1005, nil, nil, 31, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 34, nil, nil, 34, nil, nil, + 1005, nil, nil, nil, 34, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 34, nil, nil, nil, 34, nil, + nil, nil, 31, nil, nil, nil, nil, 1004, nil, nil, + nil, nil, nil, nil, 43, 1004, nil, nil, nil, 1004, + nil, 31, 345, nil, nil, 34, nil, nil, 34, 34, + nil, 345, 34, nil, 31, nil, nil, nil, 34, 34, + nil, nil, nil, 34, nil, 34, nil, nil, nil, nil, + nil, 1004, 43, nil, nil, 43, nil, nil, nil, nil, + 1005, nil, nil, nil, nil, nil, nil, nil, 1005, 250, + nil, nil, 1005, nil, nil, nil, 43, nil, nil, 318, + 318, 318, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 366, 367, nil, 369, 370, nil, 372, nil, nil, + nil, nil, nil, 43, 1005, nil, nil, nil, nil, nil, + 43, nil, 318, 318, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 31, 31, nil, nil, nil, nil, nil, 34, nil, nil, + nil, nil, nil, 31, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 34, + nil, nil, nil, nil, 34, 34, nil, nil, nil, nil, + nil, nil, nil, 34, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 1006, nil, 1006, + nil, nil, 34, nil, nil, nil, nil, nil, nil, 345, + nil, nil, nil, nil, nil, nil, nil, 34, nil, nil, + 345, 34, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 43, nil, nil, + nil, nil, 43, nil, nil, nil, nil, nil, nil, nil, + nil, 43, nil, nil, nil, nil, 34, nil, nil, nil, + nil, nil, nil, nil, nil, 318, 448, 34, nil, 454, + 318, nil, nil, 34, nil, nil, nil, 1006, nil, 34, + nil, nil, nil, 454, nil, 1006, nil, nil, nil, 43, + nil, nil, nil, nil, 1006, 1006, 250, nil, nil, 34, + nil, nil, nil, 533, 534, 535, 536, 537, 538, 539, + 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, + 550, 551, 552, 553, 554, nil, nil, nil, nil, 555, + nil, 1008, nil, 1008, 43, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 43, 318, 318, nil, nil, nil, 43, nil, nil, + 1006, 318, 1006, nil, nil, 1006, 1006, 34, 318, nil, + nil, 318, 1006, nil, 318, 318, nil, 43, 1006, 1006, + nil, 1051, nil, nil, nil, 1006, 1006, nil, nil, nil, + nil, nil, nil, nil, nil, 34, 34, nil, nil, nil, + nil, nil, 34, nil, nil, nil, nil, nil, nil, nil, + nil, 1006, nil, nil, nil, nil, 608, nil, nil, nil, + nil, 1008, nil, nil, nil, nil, nil, nil, nil, 1008, + nil, nil, nil, nil, nil, nil, nil, nil, 1008, 1008, + nil, nil, nil, nil, nil, 43, 34, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 297, nil, + nil, nil, nil, nil, nil, 34, nil, nil, nil, nil, + nil, nil, nil, 43, 43, nil, nil, nil, 34, nil, + 43, nil, nil, 318, nil, nil, nil, nil, nil, nil, + nil, 1006, nil, nil, nil, nil, nil, nil, nil, 1006, + nil, nil, nil, 1006, 1008, nil, 1008, nil, nil, 1008, + 1008, nil, nil, nil, nil, nil, 1008, nil, 699, nil, + nil, nil, 1008, 1008, nil, nil, nil, nil, nil, 1008, + 1008, nil, nil, nil, nil, 1006, nil, nil, nil, nil, + 297, nil, nil, 43, nil, 318, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 1008, nil, nil, 699, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 318, nil, + 454, 454, 454, nil, 34, 34, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 34, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 367, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 318, + nil, 318, nil, 318, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 1008, nil, nil, nil, 318, + nil, nil, nil, 1008, nil, nil, nil, 1008, nil, 454, + nil, nil, 783, nil, 784, nil, nil, nil, nil, nil, + 318, nil, nil, 318, nil, 43, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 318, 318, nil, 1008, + nil, nil, nil, nil, nil, nil, nil, 318, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 318, + nil, 454, 318, nil, nil, nil, 839, nil, nil, 318, + 318, 454, 454, nil, nil, nil, 454, nil, 454, nil, + nil, nil, nil, nil, nil, nil, nil, 318, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 318, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 699, 699, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 318, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 318, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 318, nil, nil, + nil, nil, nil, nil, nil, 454, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 942, + 699, 945, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 454, + 454, 454, 454, nil, nil, nil, nil, nil, 1014, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 318, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 318, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 454, 699, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 318 ] + +racc_goto_check = [ + 74, 160, 94, 94, 199, 74, 77, 77, 31, 19, + 19, 117, 48, 19, 111, 95, 199, 39, 39, 39, + 114, 114, 77, 33, 74, 22, 121, 26, 26, 10, + 12, 26, 50, 75, 33, 10, 74, 74, 74, 137, + 233, 233, 23, 70, 86, 86, 13, 23, 116, 141, + 141, 46, 46, 17, 17, 234, 79, 79, 42, 42, + 24, 24, 97, 43, 74, 43, 206, 85, 19, 19, + 19, 19, 115, 59, 74, 74, 74, 81, 23, 29, + 7, 86, 86, 86, 29, 135, 26, 26, 26, 26, + 31, 81, 9, 148, 82, 148, 121, 53, 57, 57, + 63, 63, 20, 5, 66, 20, 23, 123, 93, 93, + 93, 58, 58, 58, 72, 29, 23, 32, 238, 20, + 36, 159, 159, 74, 71, 91, 91, 91, 131, 228, + 228, 28, 74, 98, 74, 98, 13, 67, 84, 2, + 151, 93, 93, 29, 60, 28, 242, 92, 92, 147, + 129, 92, 44, 239, 44, 35, 35, 45, 91, 45, + 36, 178, 153, 178, 188, 23, 154, 65, 65, 65, + 132, 6, 10, 5, 23, 57, 23, 63, 26, 26, + 176, 149, 163, 100, 203, 203, 193, 8, 242, 1, + 179, 179, 8, 3, 163, 26, 26, 94, 193, 97, + 179, 14, 29, 76, 76, 16, 194, 214, 39, 214, + 11, 29, 214, 29, 214, 18, 233, 74, 216, 216, + 21, 22, 22, 77, 100, 22, 151, 25, 177, 74, + 227, 227, 27, 47, 52, 74, 54, 62, 11, 22, + 80, 199, 87, 98, 98, 90, 96, 109, 33, 231, + 231, 231, 74, 110, 118, 242, 26, 120, 239, 23, + 124, 23, 130, 176, 23, 125, 126, 60, 176, 176, + 75, 23, 127, 2, 128, 203, 203, 23, 23, 217, + 217, 217, 217, 100, 133, 148, 116, 138, 144, 6, + 39, 39, 33, 100, 23, 85, 29, 159, 29, 39, + 145, 29, 152, 153, 234, 228, 31, 154, 29, 155, + 8, 91, 91, 98, 29, 29, 177, 177, 194, 8, + 149, 8, 156, 157, 94, 19, 194, 60, 158, 193, + 94, 29, 129, 74, 161, 162, 148, 74, 188, 164, + 123, 74, 74, 26, 72, 166, 19, 147, 86, 151, + 132, 131, 33, 72, 121, 53, 167, 170, 171, 238, + 74, 172, 173, 100, 26, 174, 70, 86, 181, 183, + 33, 184, 74, 185, 189, 23, 84, 31, 81, 23, + 81, 45, 93, 13, 23, 178, 74, 74, 35, 35, + 93, 11, 190, 57, 57, 63, 63, 196, 91, 91, + 33, 32, 197, 207, 208, 66, 82, 91, 7, 85, + 66, 121, 29, 211, 23, 31, 29, 212, 213, 215, + 9, 29, 218, 206, 77, 31, 11, 71, 23, 23, + 219, 5, 94, 141, 32, 220, 114, 221, 67, 94, + 222, 65, 123, 67, 10, 234, 44, 223, 33, 65, + 226, 29, 43, 232, 233, 59, 39, 81, 236, 237, + 31, 59, 95, 115, 32, 29, 29, 57, nil, 63, + 63, 17, nil, 32, 79, nil, 135, 57, nil, 63, + 63, nil, nil, 148, nil, 130, 148, nil, 5, 130, + 192, nil, 94, nil, nil, 32, 39, 192, nil, 98, + nil, 97, 36, nil, nil, 57, 39, 63, 63, nil, + 242, 11, nil, 57, 63, 63, 11, 233, 77, 233, + 8, 72, 85, nil, nil, nil, 217, nil, 217, 100, + 94, nil, nil, 121, nil, 159, nil, nil, nil, 81, + 81, 58, 24, 228, 81, nil, 81, nil, 58, nil, + 57, 57, 63, 63, nil, nil, nil, 20, 92, 234, + 11, 11, nil, nil, nil, nil, 94, 20, 20, nil, + 137, nil, 20, nil, 20, nil, 94, 39, nil, nil, + nil, nil, 74, 97, nil, 114, nil, 141, 141, 13, + 74, 148, 77, 28, 28, nil, 70, 86, 28, 74, + 28, 42, 77, 201, 94, 70, 86, nil, nil, 192, + 10, nil, 94, nil, 46, 39, nil, 192, nil, nil, + 74, 192, nil, 74, 23, 39, 117, nil, nil, nil, + 77, nil, nil, nil, 231, 231, 77, 231, 231, 58, + 231, 75, 32, nil, 74, 130, 130, 121, 93, 94, + nil, nil, nil, 192, nil, nil, nil, nil, nil, nil, + 39, 29, 23, nil, nil, 23, 121, 77, nil, 114, + nil, 74, nil, nil, nil, 77, nil, 22, 74, nil, + nil, 12, nil, nil, nil, nil, 23, 22, 22, 93, + nil, nil, 22, 81, 22, 116, 111, nil, nil, 29, + 75, nil, 29, nil, nil, nil, nil, nil, nil, 233, + nil, nil, nil, 23, 17, nil, 23, 79, nil, nil, + 23, 20, 91, 29, 160, 10, 23, 23, nil, 32, + nil, 23, 48, 23, 32, 32, 141, 81, 81, 81, + 81, 26, 77, nil, nil, nil, 94, 28, nil, 94, + 29, 19, 50, 29, nil, nil, nil, 29, 93, nil, + 233, nil, nil, 29, 29, nil, nil, 74, 29, 26, + 29, nil, nil, 70, 86, nil, nil, nil, 74, nil, + nil, 202, nil, 202, 70, 86, 201, nil, 201, nil, + nil, nil, nil, 91, 11, nil, nil, 11, nil, 30, + nil, nil, nil, nil, 30, 74, nil, 32, 32, 32, + 74, nil, nil, 10, nil, 142, 114, nil, 142, 74, + 81, 30, 231, 231, 231, 231, 130, 130, 93, nil, + nil, 30, 30, 30, nil, 30, 30, 30, 39, nil, + nil, 22, 10, nil, nil, nil, nil, 23, nil, nil, + 32, nil, 23, 19, nil, nil, nil, 74, 8, nil, + nil, 23, nil, 30, nil, 8, nil, nil, 30, 30, + nil, 26, 30, 30, 30, 30, nil, nil, nil, nil, + 23, nil, nil, nil, 29, nil, nil, nil, 74, 29, + 74, nil, nil, nil, nil, nil, nil, nil, 29, 23, + nil, nil, 74, nil, 199, nil, nil, 233, nil, 31, + 233, nil, nil, nil, nil, nil, nil, 29, nil, 74, + nil, nil, 30, nil, nil, 74, nil, 30, 30, 30, + 30, 30, nil, 30, nil, nil, 29, nil, nil, nil, + nil, nil, nil, nil, 23, 74, 134, 121, nil, 74, + nil, nil, nil, nil, nil, nil, 86, nil, 231, 202, + 202, 23, nil, nil, 201, 201, nil, 23, nil, 202, + nil, nil, nil, nil, 201, 202, nil, nil, 74, 11, + 201, 29, nil, nil, nil, nil, 74, 23, nil, nil, + nil, 23, nil, 11, 201, 74, 74, nil, 29, 57, + nil, 63, 63, nil, 29, 202, nil, nil, nil, nil, + 201, 142, nil, 74, nil, 233, 30, 30, 30, 30, + 30, 30, 30, 146, 29, 146, 74, nil, 30, nil, + nil, 11, 19, 86, 30, 30, 30, 30, nil, nil, + nil, 74, 74, nil, nil, nil, nil, 175, 74, 175, + 26, 30, 63, nil, nil, 23, nil, nil, 33, nil, + nil, 74, nil, 74, nil, nil, 74, 74, nil, nil, + 199, nil, nil, 74, nil, nil, 11, nil, nil, 74, + 74, nil, nil, 23, 23, nil, 74, 74, nil, nil, + 23, nil, 29, 11, 143, 143, 143, 30, 94, nil, + nil, nil, nil, nil, 30, 30, 88, 88, 74, 39, + nil, 74, 74, 30, nil, 86, nil, nil, nil, 11, + 29, 29, nil, nil, 77, nil, nil, 29, nil, nil, + nil, nil, 30, nil, nil, nil, 30, 175, nil, nil, + 30, 30, nil, nil, 134, 175, nil, 134, nil, 134, + nil, nil, nil, 23, 88, nil, nil, 235, nil, 30, + 19, 19, nil, nil, nil, 34, nil, nil, nil, nil, + 34, 30, nil, nil, 77, nil, nil, nil, 26, 26, + nil, nil, nil, nil, 30, 30, 30, nil, nil, nil, + 29, nil, 74, nil, nil, nil, nil, nil, nil, nil, + 74, 34, 34, 34, 74, 30, 142, nil, nil, 142, + nil, nil, 142, 146, 142, 11, nil, nil, nil, nil, + 175, nil, 11, nil, nil, 175, 175, nil, nil, 34, + nil, nil, nil, 74, nil, nil, 74, nil, 175, 34, + 34, 34, nil, 143, 143, 143, 143, 41, 143, nil, + nil, nil, 134, nil, 134, nil, 134, nil, 134, nil, + nil, nil, nil, 101, 146, 101, 146, nil, 146, nil, + 30, 175, nil, nil, nil, 23, nil, 41, nil, nil, + nil, nil, 134, nil, nil, 11, nil, nil, 34, nil, + nil, nil, nil, nil, nil, nil, nil, 34, 37, 34, + nil, nil, nil, 37, 143, 143, 143, 143, nil, nil, + 30, nil, 29, nil, nil, nil, nil, 142, 143, 142, + 30, 142, nil, 142, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 37, 37, 37, nil, nil, 88, + 88, nil, nil, 88, 88, nil, nil, 142, nil, nil, + nil, nil, 235, 101, nil, 235, nil, nil, 235, nil, + 235, 101, 37, nil, nil, nil, nil, nil, nil, nil, + 101, 101, 37, 37, 37, nil, nil, nil, nil, nil, + nil, 30, 34, nil, 34, nil, nil, 34, nil, 30, + nil, 30, nil, nil, 34, nil, nil, nil, 30, nil, + 34, 34, nil, nil, nil, nil, nil, 11, nil, nil, + 68, nil, nil, nil, 146, nil, 146, 34, nil, 30, + nil, 37, 30, nil, nil, nil, nil, nil, nil, 30, + 37, nil, 37, nil, nil, nil, 101, nil, 101, 30, + 146, 101, 101, 30, nil, nil, nil, nil, 101, nil, + nil, nil, nil, nil, 101, 101, nil, nil, nil, nil, + 88, 101, 101, 235, nil, 235, nil, 235, nil, 235, + 30, nil, nil, 30, 30, nil, nil, 30, nil, nil, + nil, nil, nil, 30, 30, nil, 68, 101, 30, nil, + 30, nil, nil, 235, nil, nil, nil, nil, 34, nil, + nil, nil, 34, nil, nil, nil, 34, 34, nil, nil, + 68, nil, nil, nil, nil, 37, nil, 37, nil, 146, + 37, 146, nil, 146, nil, 34, nil, 37, nil, nil, + nil, nil, nil, 37, 37, nil, nil, 34, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 38, 146, + 37, 34, 34, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 30, 101, nil, nil, + nil, nil, nil, nil, nil, 101, 41, 30, nil, 101, + nil, nil, 30, nil, 38, 38, 38, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 41, 41, nil, 30, 41, nil, nil, nil, 30, + 30, 101, 38, nil, nil, nil, nil, 88, 30, 88, + nil, nil, 38, 38, 38, nil, nil, nil, nil, nil, + nil, 37, nil, nil, nil, 37, nil, 30, nil, 37, + 37, nil, nil, nil, nil, nil, nil, nil, nil, 68, + nil, nil, 30, nil, nil, nil, 30, nil, 37, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 37, 38, nil, nil, nil, nil, nil, nil, nil, 41, + 38, nil, 38, nil, 37, 37, nil, nil, 68, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 88, nil, + nil, 30, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 30, nil, nil, nil, nil, nil, 30, nil, + nil, nil, nil, nil, 30, nil, nil, 68, nil, nil, + nil, nil, nil, nil, nil, 68, nil, 68, nil, nil, + nil, 68, nil, nil, 30, nil, nil, 34, 30, nil, + nil, nil, nil, nil, nil, 34, nil, 68, nil, nil, + nil, nil, nil, 68, 34, 38, nil, 38, nil, nil, + 38, nil, nil, nil, nil, nil, nil, 38, 41, nil, + nil, nil, nil, 38, 38, 34, nil, nil, 34, 88, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 38, nil, nil, nil, nil, nil, nil, nil, nil, 34, + nil, nil, 30, 89, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 30, nil, nil, nil, 88, + nil, 88, nil, nil, nil, nil, 34, nil, nil, 34, + 30, 30, nil, 34, nil, nil, nil, 30, nil, 34, + 34, nil, nil, nil, 34, nil, 34, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 37, 38, nil, nil, nil, 38, 88, nil, 37, 38, + 38, 30, nil, nil, nil, 68, nil, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 30, 38, nil, + 30, nil, nil, nil, nil, nil, nil, nil, 37, nil, + 38, 37, 41, 30, nil, nil, nil, nil, nil, nil, + nil, nil, 34, nil, 38, 38, nil, nil, nil, nil, + nil, nil, 37, 34, 88, nil, nil, nil, 88, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 41, nil, 89, 89, nil, nil, 37, + 34, nil, 37, nil, nil, 34, 37, nil, nil, nil, + nil, nil, 37, 37, 34, nil, nil, 37, nil, 37, + nil, nil, nil, nil, nil, nil, 41, nil, nil, nil, + nil, nil, nil, 34, nil, nil, 88, nil, nil, nil, + nil, nil, 41, nil, nil, nil, nil, nil, nil, 30, + 30, nil, 34, nil, nil, nil, 41, nil, nil, nil, + nil, nil, 30, nil, nil, 41, nil, nil, nil, nil, + nil, 41, nil, nil, nil, nil, nil, nil, nil, 68, + nil, nil, nil, nil, nil, nil, nil, 41, nil, nil, + nil, nil, nil, nil, nil, 37, nil, 34, 89, nil, + 68, 89, nil, nil, 89, 89, 37, nil, nil, nil, + nil, 68, nil, nil, 34, nil, nil, nil, nil, nil, + 34, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 37, nil, nil, nil, nil, 37, nil, + 34, nil, nil, 41, 34, nil, nil, 37, nil, nil, + nil, nil, nil, 88, nil, nil, nil, 41, nil, nil, + 38, nil, nil, nil, nil, nil, 37, nil, 38, nil, + nil, nil, nil, nil, nil, nil, nil, 38, nil, nil, + nil, nil, nil, nil, nil, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 38, nil, + nil, 38, nil, nil, nil, nil, nil, nil, 34, nil, + nil, nil, nil, 89, nil, nil, nil, nil, nil, nil, + nil, 34, 38, nil, nil, nil, nil, nil, nil, 38, + 37, nil, nil, nil, 41, 41, 34, 34, nil, nil, + nil, nil, nil, 34, nil, nil, nil, 37, nil, 38, + 61, nil, 38, 37, nil, 61, 38, nil, nil, nil, + nil, nil, 38, 38, nil, nil, 68, 38, nil, 38, + nil, nil, 61, 37, nil, 89, nil, 37, nil, nil, + 41, nil, 61, 61, 61, nil, 61, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 34, nil, nil, 34, nil, nil, nil, + nil, nil, nil, nil, 61, nil, nil, nil, nil, 61, + 61, 41, nil, 61, nil, nil, 41, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 37, 68, 68, 68, 38, nil, nil, nil, 89, + nil, 89, nil, 89, 37, 102, 38, 102, 68, nil, + nil, nil, nil, nil, nil, nil, 68, nil, nil, 37, + 37, nil, nil, 61, nil, 41, 37, nil, 61, 61, + 61, 61, 61, 38, 61, nil, nil, nil, 38, nil, + 89, nil, nil, 89, nil, nil, nil, 38, nil, 41, + 41, 41, nil, nil, nil, nil, 89, nil, nil, 41, + nil, nil, nil, nil, nil, nil, 38, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 34, nil, + nil, nil, nil, nil, nil, 38, 37, nil, nil, 37, + nil, nil, 41, nil, nil, 102, nil, nil, nil, 89, + nil, nil, nil, 102, nil, nil, nil, nil, nil, 89, + 89, nil, 102, 102, nil, nil, nil, 61, 61, 61, + 61, 61, 61, 61, nil, nil, nil, 89, nil, 61, + 38, nil, nil, nil, nil, 61, 61, 61, 61, nil, + nil, nil, nil, 89, nil, nil, nil, 38, nil, nil, + nil, nil, 61, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 38, nil, nil, nil, 38, 102, 89, + 102, nil, nil, 102, 102, nil, nil, nil, nil, nil, + 102, 89, nil, nil, nil, nil, 102, 102, 61, nil, + nil, nil, nil, 102, 102, 61, 61, nil, nil, nil, + nil, 37, nil, nil, 61, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 102, + nil, nil, nil, 61, nil, nil, nil, 61, nil, nil, + nil, 38, 61, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 38, nil, 103, 89, 103, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 38, + 38, nil, 61, nil, nil, nil, 38, nil, nil, nil, + nil, nil, nil, nil, nil, 61, 61, 61, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 61, nil, nil, 102, + nil, nil, nil, nil, nil, nil, nil, 102, nil, nil, + nil, 102, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 38, nil, nil, 38, + nil, nil, nil, nil, 64, 89, 103, nil, nil, 64, + nil, nil, nil, 102, 103, nil, nil, nil, nil, nil, + nil, nil, nil, 103, 103, 89, 64, nil, nil, nil, + nil, 61, nil, nil, nil, nil, 64, 64, 64, nil, + 64, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 64, nil, + nil, 61, nil, 64, 64, nil, nil, 64, nil, nil, + nil, 61, 73, nil, 104, nil, 104, 73, nil, 103, + nil, 103, nil, nil, 103, 103, nil, nil, nil, nil, + nil, 103, nil, nil, nil, nil, 73, 103, 103, nil, + nil, nil, nil, nil, 103, 103, nil, nil, 73, 73, + 73, 38, nil, nil, nil, nil, nil, 64, nil, nil, + nil, nil, 64, 64, 64, 64, 64, nil, 64, nil, + 103, nil, 61, nil, nil, nil, 73, nil, nil, nil, + nil, nil, 61, nil, nil, nil, 73, 73, 73, nil, + 105, nil, 105, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 104, nil, nil, nil, nil, nil, + 61, nil, 104, 61, nil, nil, nil, nil, nil, nil, + 61, 104, 104, nil, nil, nil, nil, nil, nil, nil, + 61, nil, nil, nil, 61, 73, nil, nil, nil, nil, + nil, nil, nil, nil, 73, nil, 73, nil, nil, nil, + 103, 64, 64, 64, 64, 64, 64, 64, 103, nil, + nil, 61, 103, 64, 61, 61, nil, nil, 61, 64, + 64, 64, 64, nil, 61, 61, nil, nil, nil, 61, + 105, 61, nil, nil, nil, nil, 64, 104, 105, 104, + nil, nil, 104, 104, 103, nil, nil, 105, 105, 104, + nil, nil, nil, nil, nil, 104, 104, nil, nil, nil, + nil, nil, 104, 104, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 73, + nil, nil, 64, nil, nil, nil, nil, nil, 104, 64, + 64, 73, nil, nil, nil, nil, nil, 73, 64, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 105, 73, 105, nil, 64, 105, 105, + nil, 64, nil, 61, nil, 105, 64, nil, nil, nil, + nil, 105, 105, 106, nil, 106, nil, nil, 105, 105, + nil, nil, nil, nil, nil, 61, nil, nil, nil, nil, + 61, 61, nil, nil, nil, nil, 64, nil, nil, 61, + nil, nil, nil, nil, 105, nil, nil, nil, 104, 64, + 64, 64, nil, nil, nil, nil, 104, nil, 61, nil, + 104, nil, nil, nil, nil, nil, 107, nil, 107, nil, + 64, nil, nil, 61, nil, 73, nil, 61, nil, 73, + nil, nil, nil, 73, 73, nil, nil, nil, nil, nil, + nil, nil, 104, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 73, 106, nil, nil, nil, nil, nil, nil, + nil, 106, nil, nil, 73, nil, nil, nil, nil, nil, + 106, 106, 61, nil, 105, nil, nil, nil, 73, 73, + nil, nil, 105, 61, nil, 64, 105, nil, nil, 61, + nil, nil, nil, nil, nil, 61, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 107, nil, nil, nil, + nil, nil, nil, nil, 107, 61, nil, nil, 105, nil, + nil, nil, nil, 107, 107, 64, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 64, 106, nil, 106, nil, + nil, 106, 106, nil, nil, nil, nil, nil, 106, nil, + nil, nil, nil, nil, 106, 106, nil, nil, nil, nil, + nil, 106, 106, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 61, nil, nil, nil, 106, nil, 107, + nil, 107, nil, nil, 107, 107, 64, nil, nil, nil, + nil, 107, nil, nil, nil, nil, 64, 107, 107, nil, + nil, 61, 61, nil, 107, 107, nil, nil, 61, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 64, nil, nil, 64, nil, nil, + 107, nil, nil, nil, 64, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 64, nil, nil, nil, 64, nil, + nil, nil, 61, nil, nil, nil, nil, 106, nil, nil, + nil, nil, nil, nil, 73, 106, nil, nil, nil, 106, + nil, 61, 73, nil, nil, 64, nil, nil, 64, 64, + nil, 73, 64, nil, 61, nil, nil, nil, 64, 64, + nil, nil, nil, 64, nil, 64, nil, nil, nil, nil, + nil, 106, 73, nil, nil, 73, nil, nil, nil, nil, + 107, nil, nil, nil, nil, nil, nil, nil, 107, 40, + nil, nil, 107, nil, nil, nil, 73, nil, nil, 40, + 40, 40, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 40, 40, nil, 40, 40, nil, 40, nil, nil, + nil, nil, nil, 73, 107, nil, nil, nil, nil, nil, + 73, nil, 40, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 61, 61, nil, nil, nil, nil, nil, 64, nil, nil, + nil, nil, nil, 61, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 64, + nil, nil, nil, nil, 64, 64, nil, nil, nil, nil, + nil, nil, nil, 64, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 108, nil, 108, + nil, nil, 64, nil, nil, nil, nil, nil, nil, 73, + nil, nil, nil, nil, nil, nil, nil, 64, nil, nil, + 73, 64, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 73, nil, nil, + nil, nil, 73, nil, nil, nil, nil, nil, nil, nil, + nil, 73, nil, nil, nil, nil, 64, nil, nil, nil, + nil, nil, nil, nil, nil, 40, 40, 64, nil, 40, + 40, nil, nil, 64, nil, nil, nil, 108, nil, 64, + nil, nil, nil, 40, nil, 108, nil, nil, nil, 73, + nil, nil, nil, nil, 108, 108, 40, nil, nil, 64, + nil, nil, nil, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, nil, nil, nil, nil, 40, + nil, 113, nil, 113, 73, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 73, 40, 40, nil, nil, nil, 73, nil, nil, + 108, 40, 108, nil, nil, 108, 108, 64, 40, nil, + nil, 40, 108, nil, 40, 40, nil, 73, 108, 108, + nil, 73, nil, nil, nil, 108, 108, nil, nil, nil, + nil, nil, nil, nil, nil, 64, 64, nil, nil, nil, + nil, nil, 64, nil, nil, nil, nil, nil, nil, nil, + nil, 108, nil, nil, nil, nil, 40, nil, nil, nil, + nil, 113, nil, nil, nil, nil, nil, nil, nil, 113, + nil, nil, nil, nil, nil, nil, nil, nil, 113, 113, + nil, nil, nil, nil, nil, 73, 64, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 73, nil, + nil, nil, nil, nil, nil, 64, nil, nil, nil, nil, + nil, nil, nil, 73, 73, nil, nil, nil, 64, nil, + 73, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 108, nil, nil, nil, nil, nil, nil, nil, 108, + nil, nil, nil, 108, 113, nil, 113, nil, nil, 113, + 113, nil, nil, nil, nil, nil, 113, nil, 40, nil, + nil, nil, 113, 113, nil, nil, nil, nil, nil, 113, + 113, nil, nil, nil, nil, 108, nil, nil, nil, nil, + 73, nil, nil, 73, nil, 40, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 113, nil, nil, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + 40, 40, 40, nil, 64, 64, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 64, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 40, + nil, 40, nil, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 113, nil, nil, nil, 40, + nil, nil, nil, 113, nil, nil, nil, 113, nil, 40, + nil, nil, 40, nil, 40, nil, nil, nil, nil, nil, + 40, nil, nil, 40, nil, 73, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 40, 40, nil, 113, + nil, nil, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 40, + nil, 40, 40, nil, nil, nil, 40, nil, nil, 40, + 40, 40, 40, nil, nil, nil, 40, nil, 40, nil, + nil, nil, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 40, 40, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 40, + 40, 40, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 40, + 40, 40, 40, nil, nil, nil, nil, nil, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 40, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 40 ] + +racc_goto_pointer = [ + nil, 189, 137, 193, nil, 98, 164, 75, 185, 83, + -202, 172, -444, -655, -656, nil, -379, 43, 204, -62, + -119, 144, 1, 40, -160, 7, -44, 95, -93, 77, + 797, -217, -338, 5, 1163, 136, -353, 1296, 1546, -17, + 3355, 1224, -198, -467, -590, -733, -22, -393, -14, nil, + 6, nil, 208, 68, -320, nil, nil, -128, 80, -233, + -425, 2218, -325, -126, 2662, 133, 66, 99, 1170, nil, + 4, 84, -248, 2740, -2, -370, 126, -4, nil, 46, + -192, -147, 46, nil, -235, -446, 5, 191, 1087, 1745, + 178, 91, -230, 74, -29, -292, -313, -259, -441, nil, + -391, 373, 1435, 1686, 1854, 1930, 2123, 2176, 2607, 221, + 185, -55, nil, 2751, -365, -717, -343, -618, 178, nil, + -150, 21, nil, 87, 195, -110, -377, -542, -135, -730, + -235, -369, -711, -596, 43, -622, nil, -457, -616, nil, + nil, -431, 108, 73, -733, -603, 310, -754, -618, -576, + nil, -677, -743, -883, -879, -101, -494, 238, -319, -113, + -26, -596, -596, -376, 38, nil, 34, 44, nil, nil, + -392, -680, -753, -882, -856, 157, -800, -752, -729, -878, + nil, -696, nil, -696, -608, -606, nil, nil, -817, -607, + -590, nil, -585, -877, -876, nil, -687, -682, nil, -86, + nil, -104, -109, -813, nil, nil, -587, -299, -457, nil, + nil, 325, 324, 324, -453, 324, -197, -134, 326, 333, + 337, -216, -494, -207, nil, nil, -194, -124, -105, nil, + nil, -235, -258, -194, -656, 254, -249, -639, -595, -951, + nil, nil, -430 ] + +racc_goto_default = [ + nil, nil, nil, nil, 5, nil, 6, 392, 336, nil, + nil, 474, nil, 914, nil, 333, 334, nil, nil, nil, + 13, 14, 22, 248, nil, nil, 16, nil, 442, 249, + 365, nil, nil, 641, 252, nil, nil, 253, 247, 27, + 25, 520, nil, nil, nil, nil, nil, nil, nil, 387, + 144, 26, nil, nil, nil, 28, 29, 778, nil, nil, + nil, 353, nil, 30, 350, 456, 37, nil, nil, 39, + 42, 41, nil, 244, 245, 404, nil, 465, 143, 87, + nil, 447, 103, 51, nil, 700, 54, 284, 858, 324, + nil, 457, nil, 458, 470, 483, 690, 573, 322, 308, + 325, 55, 56, 57, 58, 59, 60, 61, 62, 63, + nil, 309, 69, 70, nil, nil, nil, nil, nil, 77, + nil, 623, 78, 231, nil, nil, nil, nil, nil, 721, + 495, nil, 722, 723, 481, 476, 477, nil, 1169, 717, + 1018, nil, 482, nil, nil, nil, 484, nil, 486, nil, + 902, nil, nil, nil, 493, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 469, nil, nil, 757, 749, + nil, nil, nil, nil, nil, 1151, nil, 971, 1076, 973, + 974, 978, 975, 976, nil, nil, 977, 979, nil, nil, + nil, 1075, 1077, 983, nil, 985, 986, 987, 988, nil, + 992, 478, 504, 994, 995, 996, 113, nil, nil, 86, + 88, 89, nil, nil, nil, nil, nil, 651, nil, nil, + nil, nil, nil, nil, 99, 100, nil, 232, 868, 235, + 480, nil, 485, 876, 498, 500, 501, 1029, 505, 1030, + 508, 511, 328 ] + +racc_reduce_table = [ + 0, 0, :racc_error, + 0, 150, :_reduce_1, + 2, 148, :_reduce_2, + 2, 149, :_reduce_3, + 0, 151, :_reduce_4, + 1, 151, :_reduce_5, + 3, 151, :_reduce_6, + 2, 151, :_reduce_7, + 1, 153, :_reduce_none, + 2, 153, :_reduce_9, + 3, 156, :_reduce_10, + 4, 157, :_reduce_11, + 2, 158, :_reduce_12, + 0, 162, :_reduce_13, + 1, 162, :_reduce_14, + 3, 162, :_reduce_15, + 2, 162, :_reduce_16, + 1, 163, :_reduce_none, + 2, 163, :_reduce_18, + 0, 174, :_reduce_19, + 4, 155, :_reduce_20, + 3, 155, :_reduce_21, + 3, 155, :_reduce_22, + 3, 155, :_reduce_23, + 2, 155, :_reduce_24, + 3, 155, :_reduce_25, + 3, 155, :_reduce_26, + 3, 155, :_reduce_27, + 3, 155, :_reduce_28, + 3, 155, :_reduce_29, + 4, 155, :_reduce_30, + 1, 155, :_reduce_none, + 3, 155, :_reduce_32, + 3, 155, :_reduce_33, + 5, 155, :_reduce_34, + 3, 155, :_reduce_35, + 1, 155, :_reduce_none, + 3, 167, :_reduce_37, + 3, 167, :_reduce_38, + 6, 167, :_reduce_39, + 5, 167, :_reduce_40, + 5, 167, :_reduce_41, + 5, 167, :_reduce_42, + 5, 167, :_reduce_43, + 4, 167, :_reduce_44, + 4, 167, :_reduce_45, + 3, 167, :_reduce_46, + 1, 183, :_reduce_none, + 3, 183, :_reduce_48, + 3, 183, :_reduce_49, + 1, 175, :_reduce_none, + 3, 175, :_reduce_51, + 1, 175, :_reduce_none, + 1, 173, :_reduce_none, + 3, 173, :_reduce_54, + 3, 173, :_reduce_55, + 3, 173, :_reduce_56, + 2, 173, :_reduce_57, + 6, 173, :_reduce_58, + 6, 173, :_reduce_59, + 1, 173, :_reduce_none, + 1, 166, :_reduce_none, + 0, 196, :_reduce_62, + 3, 193, :_reduce_63, + 1, 195, :_reduce_64, + 2, 181, :_reduce_65, + 0, 201, :_reduce_66, + 5, 184, :_reduce_67, + 1, 169, :_reduce_none, + 1, 169, :_reduce_none, + 1, 202, :_reduce_none, + 4, 202, :_reduce_71, + 0, 209, :_reduce_72, + 4, 206, :_reduce_73, + 1, 208, :_reduce_none, + 2, 186, :_reduce_75, + 3, 186, :_reduce_76, + 4, 186, :_reduce_77, + 5, 186, :_reduce_78, + 4, 186, :_reduce_79, + 5, 186, :_reduce_80, + 6, 186, :_reduce_81, + 2, 186, :_reduce_82, + 2, 186, :_reduce_83, + 2, 186, :_reduce_84, + 2, 186, :_reduce_85, + 2, 186, :_reduce_86, + 1, 168, :_reduce_87, + 3, 168, :_reduce_88, + 1, 214, :_reduce_89, + 3, 214, :_reduce_90, + 1, 213, :_reduce_none, + 2, 213, :_reduce_92, + 3, 213, :_reduce_93, + 5, 213, :_reduce_94, + 2, 213, :_reduce_95, + 4, 213, :_reduce_96, + 2, 213, :_reduce_97, + 4, 213, :_reduce_98, + 1, 213, :_reduce_99, + 3, 213, :_reduce_100, + 1, 217, :_reduce_none, + 3, 217, :_reduce_102, + 2, 216, :_reduce_103, + 3, 216, :_reduce_104, + 1, 219, :_reduce_105, + 3, 219, :_reduce_106, + 1, 218, :_reduce_107, + 1, 218, :_reduce_108, + 4, 218, :_reduce_109, + 3, 218, :_reduce_110, + 3, 218, :_reduce_111, + 3, 218, :_reduce_112, + 3, 218, :_reduce_113, + 2, 218, :_reduce_114, + 1, 218, :_reduce_115, + 1, 170, :_reduce_116, + 1, 170, :_reduce_117, + 4, 170, :_reduce_118, + 3, 170, :_reduce_119, + 3, 170, :_reduce_120, + 3, 170, :_reduce_121, + 3, 170, :_reduce_122, + 2, 170, :_reduce_123, + 1, 170, :_reduce_124, + 1, 222, :_reduce_125, + 1, 222, :_reduce_none, + 2, 223, :_reduce_127, + 1, 223, :_reduce_128, + 3, 223, :_reduce_129, + 1, 197, :_reduce_none, + 1, 197, :_reduce_none, + 1, 197, :_reduce_none, + 1, 197, :_reduce_none, + 1, 197, :_reduce_none, + 1, 164, :_reduce_135, + 1, 164, :_reduce_none, + 1, 165, :_reduce_137, + 0, 227, :_reduce_138, + 4, 165, :_reduce_139, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 3, 187, :_reduce_211, + 3, 187, :_reduce_212, + 6, 187, :_reduce_213, + 5, 187, :_reduce_214, + 5, 187, :_reduce_215, + 5, 187, :_reduce_216, + 5, 187, :_reduce_217, + 4, 187, :_reduce_218, + 3, 187, :_reduce_219, + 3, 187, :_reduce_220, + 3, 187, :_reduce_221, + 2, 187, :_reduce_222, + 2, 187, :_reduce_223, + 2, 187, :_reduce_224, + 2, 187, :_reduce_225, + 3, 187, :_reduce_226, + 3, 187, :_reduce_227, + 3, 187, :_reduce_228, + 3, 187, :_reduce_229, + 3, 187, :_reduce_230, + 3, 187, :_reduce_231, + 4, 187, :_reduce_232, + 2, 187, :_reduce_233, + 2, 187, :_reduce_234, + 3, 187, :_reduce_235, + 3, 187, :_reduce_236, + 3, 187, :_reduce_237, + 3, 187, :_reduce_238, + 1, 187, :_reduce_none, + 3, 187, :_reduce_240, + 3, 187, :_reduce_241, + 3, 187, :_reduce_242, + 3, 187, :_reduce_243, + 3, 187, :_reduce_244, + 2, 187, :_reduce_245, + 2, 187, :_reduce_246, + 3, 187, :_reduce_247, + 3, 187, :_reduce_248, + 3, 187, :_reduce_249, + 3, 187, :_reduce_250, + 4, 187, :_reduce_251, + 6, 187, :_reduce_252, + 4, 187, :_reduce_253, + 4, 187, :_reduce_254, + 1, 187, :_reduce_none, + 1, 232, :_reduce_none, + 3, 232, :_reduce_257, + 3, 232, :_reduce_258, + 1, 234, :_reduce_none, + 1, 234, :_reduce_none, + 1, 234, :_reduce_none, + 1, 234, :_reduce_none, + 3, 230, :_reduce_263, + 3, 230, :_reduce_264, + 1, 231, :_reduce_265, + 1, 236, :_reduce_none, + 1, 237, :_reduce_none, + 2, 237, :_reduce_none, + 4, 237, :_reduce_269, + 2, 237, :_reduce_270, + 1, 228, :_reduce_none, + 3, 228, :_reduce_272, + 3, 241, :_reduce_273, + 5, 241, :_reduce_274, + 3, 241, :_reduce_275, + 0, 243, :_reduce_276, + 1, 243, :_reduce_none, + 0, 178, :_reduce_278, + 1, 178, :_reduce_none, + 2, 178, :_reduce_none, + 4, 178, :_reduce_281, + 2, 178, :_reduce_282, + 1, 212, :_reduce_283, + 2, 212, :_reduce_284, + 2, 212, :_reduce_285, + 4, 212, :_reduce_286, + 1, 212, :_reduce_287, + 0, 246, :_reduce_288, + 2, 205, :_reduce_289, + 2, 245, :_reduce_290, + 1, 245, :_reduce_291, + 2, 244, :_reduce_292, + 0, 244, :_reduce_293, + 1, 238, :_reduce_294, + 1, 238, :_reduce_none, + 3, 238, :_reduce_296, + 3, 238, :_reduce_297, + 2, 247, :_reduce_298, + 1, 247, :_reduce_299, + 1, 172, :_reduce_300, + 1, 172, :_reduce_none, + 3, 171, :_reduce_302, + 4, 171, :_reduce_303, + 2, 171, :_reduce_304, + 1, 233, :_reduce_none, + 1, 233, :_reduce_none, + 1, 233, :_reduce_none, + 1, 233, :_reduce_none, + 1, 233, :_reduce_none, + 1, 233, :_reduce_none, + 1, 233, :_reduce_none, + 1, 233, :_reduce_none, + 1, 233, :_reduce_none, + 1, 233, :_reduce_none, + 1, 233, :_reduce_315, + 0, 271, :_reduce_316, + 4, 233, :_reduce_317, + 0, 272, :_reduce_318, + 4, 233, :_reduce_319, + 3, 233, :_reduce_320, + 3, 233, :_reduce_321, + 2, 233, :_reduce_322, + 3, 233, :_reduce_323, + 3, 233, :_reduce_324, + 1, 233, :_reduce_325, + 4, 233, :_reduce_326, + 3, 233, :_reduce_327, + 1, 233, :_reduce_328, + 6, 233, :_reduce_329, + 4, 233, :_reduce_330, + 3, 233, :_reduce_331, + 2, 233, :_reduce_332, + 1, 233, :_reduce_none, + 2, 233, :_reduce_334, + 1, 233, :_reduce_none, + 6, 233, :_reduce_336, + 6, 233, :_reduce_337, + 4, 233, :_reduce_338, + 4, 233, :_reduce_339, + 5, 233, :_reduce_340, + 4, 233, :_reduce_341, + 5, 233, :_reduce_342, + 6, 233, :_reduce_343, + 0, 273, :_reduce_344, + 6, 233, :_reduce_345, + 0, 274, :_reduce_346, + 7, 233, :_reduce_347, + 0, 275, :_reduce_348, + 5, 233, :_reduce_349, + 4, 233, :_reduce_350, + 4, 233, :_reduce_351, + 1, 233, :_reduce_352, + 1, 233, :_reduce_353, + 1, 233, :_reduce_354, + 1, 233, :_reduce_355, + 1, 177, :_reduce_none, + 1, 266, :_reduce_357, + 1, 269, :_reduce_358, + 1, 198, :_reduce_359, + 1, 211, :_reduce_360, + 1, 261, :_reduce_none, + 1, 261, :_reduce_none, + 2, 261, :_reduce_363, + 1, 194, :_reduce_none, + 1, 194, :_reduce_none, + 1, 262, :_reduce_none, + 5, 262, :_reduce_367, + 1, 160, :_reduce_none, + 2, 160, :_reduce_369, + 1, 265, :_reduce_none, + 1, 265, :_reduce_none, + 1, 276, :_reduce_372, + 3, 276, :_reduce_373, + 1, 279, :_reduce_374, + 3, 279, :_reduce_375, + 1, 278, :_reduce_none, + 3, 278, :_reduce_377, + 5, 278, :_reduce_378, + 1, 278, :_reduce_379, + 3, 278, :_reduce_380, + 2, 280, :_reduce_381, + 1, 280, :_reduce_382, + 1, 281, :_reduce_none, + 1, 281, :_reduce_none, + 0, 286, :_reduce_385, + 2, 284, :_reduce_386, + 4, 285, :_reduce_387, + 2, 285, :_reduce_388, + 2, 285, :_reduce_389, + 1, 285, :_reduce_390, + 2, 290, :_reduce_391, + 0, 290, :_reduce_392, + 1, 291, :_reduce_none, + 6, 292, :_reduce_394, + 8, 292, :_reduce_395, + 4, 292, :_reduce_396, + 6, 292, :_reduce_397, + 4, 292, :_reduce_398, + 2, 292, :_reduce_none, + 6, 292, :_reduce_400, + 2, 292, :_reduce_401, + 4, 292, :_reduce_402, + 6, 292, :_reduce_403, + 2, 292, :_reduce_404, + 4, 292, :_reduce_405, + 2, 292, :_reduce_406, + 4, 292, :_reduce_407, + 1, 292, :_reduce_none, + 0, 296, :_reduce_409, + 1, 296, :_reduce_410, + 3, 297, :_reduce_411, + 4, 297, :_reduce_412, + 1, 298, :_reduce_413, + 4, 298, :_reduce_414, + 1, 299, :_reduce_415, + 3, 299, :_reduce_416, + 1, 300, :_reduce_417, + 1, 300, :_reduce_none, + 0, 304, :_reduce_419, + 0, 305, :_reduce_420, + 5, 260, :_reduce_421, + 4, 302, :_reduce_422, + 1, 302, :_reduce_423, + 0, 308, :_reduce_424, + 4, 303, :_reduce_425, + 0, 309, :_reduce_426, + 4, 303, :_reduce_427, + 0, 311, :_reduce_428, + 4, 307, :_reduce_429, + 2, 203, :_reduce_430, + 4, 203, :_reduce_431, + 5, 203, :_reduce_432, + 5, 203, :_reduce_433, + 2, 259, :_reduce_434, + 4, 259, :_reduce_435, + 4, 259, :_reduce_436, + 3, 259, :_reduce_437, + 3, 259, :_reduce_438, + 3, 259, :_reduce_439, + 2, 259, :_reduce_440, + 1, 259, :_reduce_441, + 4, 259, :_reduce_442, + 0, 313, :_reduce_443, + 4, 258, :_reduce_444, + 0, 314, :_reduce_445, + 4, 258, :_reduce_446, + 0, 315, :_reduce_447, + 3, 207, :_reduce_448, + 0, 316, :_reduce_449, + 0, 317, :_reduce_450, + 4, 310, :_reduce_451, + 5, 263, :_reduce_452, + 1, 318, :_reduce_453, + 1, 318, :_reduce_none, + 1, 190, :_reduce_455, + 1, 191, :_reduce_456, + 1, 189, :_reduce_457, + 0, 321, :_reduce_458, + 9, 264, :_reduce_459, + 1, 320, :_reduce_460, + 1, 320, :_reduce_none, + 1, 319, :_reduce_462, + 3, 319, :_reduce_463, + 3, 319, :_reduce_464, + 1, 192, :_reduce_none, + 2, 192, :_reduce_466, + 3, 192, :_reduce_467, + 1, 192, :_reduce_468, + 1, 192, :_reduce_469, + 1, 192, :_reduce_470, + 1, 322, :_reduce_none, + 3, 327, :_reduce_472, + 1, 327, :_reduce_none, + 3, 329, :_reduce_474, + 1, 329, :_reduce_none, + 1, 331, :_reduce_476, + 1, 332, :_reduce_477, + 1, 330, :_reduce_none, + 1, 330, :_reduce_none, + 4, 330, :_reduce_480, + 4, 330, :_reduce_481, + 4, 330, :_reduce_482, + 3, 330, :_reduce_483, + 4, 330, :_reduce_484, + 4, 330, :_reduce_485, + 4, 330, :_reduce_486, + 3, 330, :_reduce_487, + 3, 330, :_reduce_488, + 3, 330, :_reduce_489, + 2, 330, :_reduce_490, + 0, 336, :_reduce_491, + 4, 330, :_reduce_492, + 2, 330, :_reduce_493, + 0, 337, :_reduce_494, + 4, 330, :_reduce_495, + 1, 323, :_reduce_496, + 1, 323, :_reduce_497, + 2, 323, :_reduce_498, + 2, 323, :_reduce_499, + 4, 323, :_reduce_500, + 1, 323, :_reduce_none, + 2, 338, :_reduce_502, + 3, 338, :_reduce_503, + 1, 325, :_reduce_504, + 3, 325, :_reduce_505, + 5, 324, :_reduce_506, + 2, 340, :_reduce_507, + 1, 340, :_reduce_508, + 1, 341, :_reduce_509, + 3, 341, :_reduce_510, + 1, 339, :_reduce_none, + 3, 326, :_reduce_512, + 1, 326, :_reduce_513, + 2, 326, :_reduce_514, + 1, 326, :_reduce_515, + 1, 342, :_reduce_516, + 3, 342, :_reduce_517, + 2, 344, :_reduce_518, + 1, 344, :_reduce_519, + 1, 345, :_reduce_520, + 3, 345, :_reduce_521, + 2, 347, :_reduce_522, + 1, 347, :_reduce_523, + 2, 349, :_reduce_524, + 1, 343, :_reduce_none, + 1, 343, :_reduce_526, + 1, 333, :_reduce_none, + 3, 333, :_reduce_528, + 3, 333, :_reduce_529, + 2, 333, :_reduce_530, + 2, 333, :_reduce_531, + 1, 333, :_reduce_none, + 1, 333, :_reduce_none, + 1, 333, :_reduce_none, + 2, 333, :_reduce_535, + 2, 333, :_reduce_536, + 1, 350, :_reduce_none, + 1, 350, :_reduce_none, + 1, 350, :_reduce_none, + 1, 350, :_reduce_none, + 1, 350, :_reduce_none, + 1, 350, :_reduce_none, + 1, 350, :_reduce_none, + 1, 350, :_reduce_none, + 1, 350, :_reduce_545, + 1, 350, :_reduce_none, + 1, 328, :_reduce_547, + 2, 351, :_reduce_548, + 2, 351, :_reduce_549, + 4, 352, :_reduce_550, + 2, 334, :_reduce_551, + 3, 334, :_reduce_552, + 1, 334, :_reduce_553, + 6, 159, :_reduce_554, + 0, 159, :_reduce_555, + 1, 354, :_reduce_556, + 1, 354, :_reduce_none, + 1, 354, :_reduce_none, + 2, 355, :_reduce_559, + 1, 355, :_reduce_none, + 2, 161, :_reduce_561, + 1, 161, :_reduce_none, + 1, 248, :_reduce_none, + 1, 248, :_reduce_none, + 1, 249, :_reduce_565, + 1, 357, :_reduce_566, + 2, 357, :_reduce_567, + 3, 358, :_reduce_568, + 1, 358, :_reduce_569, + 1, 358, :_reduce_570, + 3, 250, :_reduce_571, + 4, 251, :_reduce_572, + 1, 361, :_reduce_none, + 2, 361, :_reduce_none, + 3, 252, :_reduce_575, + 0, 362, :_reduce_576, + 3, 362, :_reduce_577, + 1, 363, :_reduce_578, + 2, 363, :_reduce_579, + 3, 254, :_reduce_580, + 0, 365, :_reduce_581, + 3, 365, :_reduce_582, + 3, 253, :_reduce_583, + 3, 255, :_reduce_584, + 0, 366, :_reduce_585, + 3, 366, :_reduce_586, + 0, 367, :_reduce_587, + 3, 367, :_reduce_588, + 0, 346, :_reduce_589, + 2, 346, :_reduce_590, + 0, 359, :_reduce_591, + 2, 359, :_reduce_592, + 0, 360, :_reduce_593, + 2, 360, :_reduce_594, + 1, 364, :_reduce_595, + 2, 364, :_reduce_596, + 0, 370, :_reduce_597, + 4, 364, :_reduce_598, + 1, 369, :_reduce_none, + 1, 368, :_reduce_600, + 1, 368, :_reduce_none, + 1, 226, :_reduce_none, + 1, 226, :_reduce_none, + 1, 371, :_reduce_604, + 3, 372, :_reduce_605, + 1, 356, :_reduce_606, + 2, 356, :_reduce_607, + 1, 229, :_reduce_608, + 1, 229, :_reduce_609, + 1, 229, :_reduce_610, + 1, 229, :_reduce_611, + 1, 353, :_reduce_612, + 1, 353, :_reduce_613, + 1, 353, :_reduce_614, + 1, 220, :_reduce_615, + 1, 220, :_reduce_616, + 1, 220, :_reduce_none, + 1, 221, :_reduce_618, + 1, 221, :_reduce_619, + 1, 221, :_reduce_620, + 1, 221, :_reduce_621, + 1, 221, :_reduce_622, + 1, 221, :_reduce_623, + 1, 221, :_reduce_624, + 1, 256, :_reduce_625, + 1, 256, :_reduce_626, + 1, 176, :_reduce_627, + 1, 176, :_reduce_628, + 1, 185, :_reduce_629, + 1, 185, :_reduce_630, + 0, 373, :_reduce_631, + 4, 267, :_reduce_632, + 0, 267, :_reduce_633, + 1, 182, :_reduce_none, + 1, 182, :_reduce_635, + 3, 374, :_reduce_636, + 1, 270, :_reduce_none, + 0, 376, :_reduce_638, + 3, 270, :_reduce_639, + 4, 375, :_reduce_640, + 2, 375, :_reduce_641, + 2, 375, :_reduce_642, + 1, 375, :_reduce_643, + 1, 375, :_reduce_644, + 2, 378, :_reduce_645, + 0, 378, :_reduce_646, + 6, 306, :_reduce_647, + 8, 306, :_reduce_648, + 4, 306, :_reduce_649, + 6, 306, :_reduce_650, + 4, 306, :_reduce_651, + 6, 306, :_reduce_652, + 2, 306, :_reduce_653, + 4, 306, :_reduce_654, + 6, 306, :_reduce_655, + 2, 306, :_reduce_656, + 4, 306, :_reduce_657, + 2, 306, :_reduce_658, + 4, 306, :_reduce_659, + 1, 306, :_reduce_660, + 0, 306, :_reduce_661, + 1, 242, :_reduce_662, + 1, 301, :_reduce_663, + 1, 301, :_reduce_664, + 1, 301, :_reduce_665, + 1, 301, :_reduce_666, + 1, 277, :_reduce_none, + 1, 277, :_reduce_668, + 1, 380, :_reduce_669, + 1, 381, :_reduce_670, + 3, 381, :_reduce_671, + 1, 293, :_reduce_672, + 3, 293, :_reduce_673, + 1, 382, :_reduce_674, + 2, 383, :_reduce_675, + 1, 383, :_reduce_676, + 2, 384, :_reduce_677, + 1, 384, :_reduce_678, + 1, 287, :_reduce_679, + 3, 287, :_reduce_680, + 1, 377, :_reduce_681, + 3, 377, :_reduce_682, + 1, 348, :_reduce_none, + 1, 348, :_reduce_none, + 1, 283, :_reduce_685, + 2, 282, :_reduce_686, + 1, 282, :_reduce_687, + 3, 385, :_reduce_688, + 3, 386, :_reduce_689, + 1, 294, :_reduce_690, + 3, 294, :_reduce_691, + 1, 379, :_reduce_692, + 3, 379, :_reduce_693, + 1, 387, :_reduce_none, + 1, 387, :_reduce_none, + 2, 295, :_reduce_696, + 1, 295, :_reduce_697, + 1, 388, :_reduce_none, + 1, 388, :_reduce_none, + 2, 289, :_reduce_700, + 1, 289, :_reduce_701, + 2, 288, :_reduce_702, + 0, 288, :_reduce_703, + 1, 199, :_reduce_none, + 3, 199, :_reduce_705, + 0, 257, :_reduce_706, + 2, 257, :_reduce_none, + 1, 240, :_reduce_708, + 3, 240, :_reduce_709, + 3, 389, :_reduce_710, + 2, 389, :_reduce_711, + 1, 389, :_reduce_712, + 4, 389, :_reduce_713, + 2, 389, :_reduce_714, + 1, 389, :_reduce_715, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 312, :_reduce_none, + 1, 312, :_reduce_none, + 1, 312, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 180, :_reduce_726, + 1, 180, :_reduce_727, + 0, 152, :_reduce_none, + 1, 152, :_reduce_none, + 0, 188, :_reduce_none, + 1, 188, :_reduce_none, + 2, 215, :_reduce_732, + 2, 179, :_reduce_733, + 2, 335, :_reduce_734, + 1, 239, :_reduce_none, + 1, 239, :_reduce_none, + 1, 268, :_reduce_737, + 1, 268, :_reduce_none, + 1, 154, :_reduce_none, + 2, 154, :_reduce_none, + 0, 235, :_reduce_741 ] + +racc_reduce_n = 742 + +racc_shift_n = 1250 + +racc_token_table = { + false => 0, + :error => 1, + :kCLASS => 2, + :kMODULE => 3, + :kDEF => 4, + :kUNDEF => 5, + :kBEGIN => 6, + :kRESCUE => 7, + :kENSURE => 8, + :kEND => 9, + :kIF => 10, + :kUNLESS => 11, + :kTHEN => 12, + :kELSIF => 13, + :kELSE => 14, + :kCASE => 15, + :kWHEN => 16, + :kWHILE => 17, + :kUNTIL => 18, + :kFOR => 19, + :kBREAK => 20, + :kNEXT => 21, + :kREDO => 22, + :kRETRY => 23, + :kIN => 24, + :kDO => 25, + :kDO_COND => 26, + :kDO_BLOCK => 27, + :kDO_LAMBDA => 28, + :kRETURN => 29, + :kYIELD => 30, + :kSUPER => 31, + :kSELF => 32, + :kNIL => 33, + :kTRUE => 34, + :kFALSE => 35, + :kAND => 36, + :kOR => 37, + :kNOT => 38, + :kIF_MOD => 39, + :kUNLESS_MOD => 40, + :kWHILE_MOD => 41, + :kUNTIL_MOD => 42, + :kRESCUE_MOD => 43, + :kALIAS => 44, + :kDEFINED => 45, + :klBEGIN => 46, + :klEND => 47, + :k__LINE__ => 48, + :k__FILE__ => 49, + :k__ENCODING__ => 50, + :tIDENTIFIER => 51, + :tFID => 52, + :tGVAR => 53, + :tIVAR => 54, + :tCONSTANT => 55, + :tLABEL => 56, + :tCVAR => 57, + :tNTH_REF => 58, + :tBACK_REF => 59, + :tSTRING_CONTENT => 60, + :tINTEGER => 61, + :tFLOAT => 62, + :tUPLUS => 63, + :tUMINUS => 64, + :tUNARY_NUM => 65, + :tPOW => 66, + :tCMP => 67, + :tEQ => 68, + :tEQQ => 69, + :tNEQ => 70, + :tGEQ => 71, + :tLEQ => 72, + :tANDOP => 73, + :tOROP => 74, + :tMATCH => 75, + :tNMATCH => 76, + :tDOT => 77, + :tDOT2 => 78, + :tDOT3 => 79, + :tAREF => 80, + :tASET => 81, + :tLSHFT => 82, + :tRSHFT => 83, + :tCOLON2 => 84, + :tCOLON3 => 85, + :tOP_ASGN => 86, + :tASSOC => 87, + :tLPAREN => 88, + :tLPAREN2 => 89, + :tRPAREN => 90, + :tLPAREN_ARG => 91, + :tLBRACK => 92, + :tLBRACK2 => 93, + :tRBRACK => 94, + :tLBRACE => 95, + :tLBRACE_ARG => 96, + :tSTAR => 97, + :tSTAR2 => 98, + :tAMPER => 99, + :tAMPER2 => 100, + :tTILDE => 101, + :tPERCENT => 102, + :tDIVIDE => 103, + :tDSTAR => 104, + :tPLUS => 105, + :tMINUS => 106, + :tLT => 107, + :tGT => 108, + :tPIPE => 109, + :tBANG => 110, + :tCARET => 111, + :tLCURLY => 112, + :tRCURLY => 113, + :tBACK_REF2 => 114, + :tSYMBEG => 115, + :tSTRING_BEG => 116, + :tXSTRING_BEG => 117, + :tREGEXP_BEG => 118, + :tREGEXP_OPT => 119, + :tWORDS_BEG => 120, + :tQWORDS_BEG => 121, + :tSYMBOLS_BEG => 122, + :tQSYMBOLS_BEG => 123, + :tSTRING_DBEG => 124, + :tSTRING_DVAR => 125, + :tSTRING_END => 126, + :tSTRING_DEND => 127, + :tSTRING => 128, + :tSYMBOL => 129, + :tNL => 130, + :tEH => 131, + :tCOLON => 132, + :tCOMMA => 133, + :tSPACE => 134, + :tSEMI => 135, + :tLAMBDA => 136, + :tLAMBEG => 137, + :tCHARACTER => 138, + :tRATIONAL => 139, + :tIMAGINARY => 140, + :tLABEL_END => 141, + :tANDDOT => 142, + :tBDOT2 => 143, + :tBDOT3 => 144, + :tEQL => 145, + :tLOWEST => 146 } + +racc_nt_base = 147 + +racc_use_result_var = true + +Racc_arg = [ + racc_action_table, + racc_action_check, + racc_action_default, + racc_action_pointer, + racc_goto_table, + racc_goto_check, + racc_goto_default, + racc_goto_pointer, + racc_nt_base, + racc_reduce_table, + racc_token_table, + racc_shift_n, + racc_reduce_n, + racc_use_result_var ] +Ractor.make_shareable(Racc_arg) if defined?(Ractor) + +Racc_token_to_s_table = [ + "$end", + "error", + "kCLASS", + "kMODULE", + "kDEF", + "kUNDEF", + "kBEGIN", + "kRESCUE", + "kENSURE", + "kEND", + "kIF", + "kUNLESS", + "kTHEN", + "kELSIF", + "kELSE", + "kCASE", + "kWHEN", + "kWHILE", + "kUNTIL", + "kFOR", + "kBREAK", + "kNEXT", + "kREDO", + "kRETRY", + "kIN", + "kDO", + "kDO_COND", + "kDO_BLOCK", + "kDO_LAMBDA", + "kRETURN", + "kYIELD", + "kSUPER", + "kSELF", + "kNIL", + "kTRUE", + "kFALSE", + "kAND", + "kOR", + "kNOT", + "kIF_MOD", + "kUNLESS_MOD", + "kWHILE_MOD", + "kUNTIL_MOD", + "kRESCUE_MOD", + "kALIAS", + "kDEFINED", + "klBEGIN", + "klEND", + "k__LINE__", + "k__FILE__", + "k__ENCODING__", + "tIDENTIFIER", + "tFID", + "tGVAR", + "tIVAR", + "tCONSTANT", + "tLABEL", + "tCVAR", + "tNTH_REF", + "tBACK_REF", + "tSTRING_CONTENT", + "tINTEGER", + "tFLOAT", + "tUPLUS", + "tUMINUS", + "tUNARY_NUM", + "tPOW", + "tCMP", + "tEQ", + "tEQQ", + "tNEQ", + "tGEQ", + "tLEQ", + "tANDOP", + "tOROP", + "tMATCH", + "tNMATCH", + "tDOT", + "tDOT2", + "tDOT3", + "tAREF", + "tASET", + "tLSHFT", + "tRSHFT", + "tCOLON2", + "tCOLON3", + "tOP_ASGN", + "tASSOC", + "tLPAREN", + "tLPAREN2", + "tRPAREN", + "tLPAREN_ARG", + "tLBRACK", + "tLBRACK2", + "tRBRACK", + "tLBRACE", + "tLBRACE_ARG", + "tSTAR", + "tSTAR2", + "tAMPER", + "tAMPER2", + "tTILDE", + "tPERCENT", + "tDIVIDE", + "tDSTAR", + "tPLUS", + "tMINUS", + "tLT", + "tGT", + "tPIPE", + "tBANG", + "tCARET", + "tLCURLY", + "tRCURLY", + "tBACK_REF2", + "tSYMBEG", + "tSTRING_BEG", + "tXSTRING_BEG", + "tREGEXP_BEG", + "tREGEXP_OPT", + "tWORDS_BEG", + "tQWORDS_BEG", + "tSYMBOLS_BEG", + "tQSYMBOLS_BEG", + "tSTRING_DBEG", + "tSTRING_DVAR", + "tSTRING_END", + "tSTRING_DEND", + "tSTRING", + "tSYMBOL", + "tNL", + "tEH", + "tCOLON", + "tCOMMA", + "tSPACE", + "tSEMI", + "tLAMBDA", + "tLAMBEG", + "tCHARACTER", + "tRATIONAL", + "tIMAGINARY", + "tLABEL_END", + "tANDDOT", + "tBDOT2", + "tBDOT3", + "tEQL", + "tLOWEST", + "$start", + "program", + "top_compstmt", + "@1", + "top_stmts", + "opt_terms", + "top_stmt", + "terms", + "stmt", + "begin_block", + "bodystmt", + "compstmt", + "opt_rescue", + "opt_else", + "opt_ensure", + "stmts", + "stmt_or_begin", + "fitem", + "undef_list", + "expr_value", + "command_asgn", + "mlhs", + "command_call", + "lhs", + "mrhs", + "mrhs_arg", + "expr", + "@2", + "command_rhs", + "var_lhs", + "primary_value", + "opt_call_args", + "rbracket", + "call_op", + "defn_head", + "f_opt_paren_args", + "endless_command", + "defs_head", + "backref", + "command", + "arg", + "opt_nl", + "p_in_kwarg", + "p_pvtbl", + "p_pktbl", + "p_top_expr_body", + "expr_value_do", + "do", + "def_name", + "@3", + "fname", + "k_def", + "singleton", + "dot_or_colon", + "@4", + "block_command", + "block_call", + "operation2", + "command_args", + "cmd_brace_block", + "brace_body", + "fcall", + "@5", + "operation", + "k_return", + "call_args", + "mlhs_basic", + "mlhs_inner", + "rparen", + "mlhs_head", + "mlhs_item", + "mlhs_node", + "mlhs_post", + "user_variable", + "keyword_variable", + "cname", + "cpath", + "op", + "reswords", + "symbol", + "@6", + "arg_rhs", + "simple_numeric", + "rel_expr", + "begin_defined", + "endless_arg", + "primary", + "relop", + "none", + "arg_value", + "aref_args", + "args", + "trailer", + "assocs", + "paren_args", + "args_forward", + "opt_paren_args", + "opt_block_arg", + "block_arg", + "@7", + "arg_splat", + "literal", + "strings", + "xstring", + "regexp", + "words", + "qwords", + "symbols", + "qsymbols", + "var_ref", + "assoc_list", + "brace_block", + "method_call", + "lambda", + "then", + "if_tail", + "case_body", + "p_case_body", + "for_var", + "k_class", + "superclass", + "term", + "k_module", + "f_arglist", + "@8", + "@9", + "@10", + "@11", + "@12", + "f_marg", + "f_norm_arg", + "f_margs", + "f_marg_list", + "f_rest_marg", + "f_any_kwrest", + "f_kwrest", + "f_no_kwarg", + "f_eq", + "block_args_tail", + "@13", + "f_block_kwarg", + "opt_f_block_arg", + "f_block_arg", + "opt_block_args_tail", + "excessed_comma", + "block_param", + "f_arg", + "f_block_optarg", + "f_rest_arg", + "opt_block_param", + "block_param_def", + "opt_bv_decl", + "bv_decls", + "bvar", + "f_bad_arg", + "f_larglist", + "lambda_body", + "@14", + "@15", + "f_args", + "do_block", + "@16", + "@17", + "do_body", + "@18", + "operation3", + "@19", + "@20", + "@21", + "@22", + "@23", + "cases", + "p_top_expr", + "p_cases", + "@24", + "p_expr", + "p_args", + "p_find", + "p_args_tail", + "p_kwargs", + "p_as", + "p_variable", + "p_alt", + "p_expr_basic", + "p_lparen", + "p_lbracket", + "p_value", + "p_const", + "rbrace", + "@25", + "@26", + "p_args_head", + "p_arg", + "p_rest", + "p_args_post", + "p_kwarg", + "p_any_kwrest", + "p_kw", + "p_kw_label", + "string_contents", + "p_kwrest", + "kwrest_mark", + "p_kwnorest", + "p_primitive", + "p_var_ref", + "p_expr_ref", + "nonlocal_var", + "exc_list", + "exc_var", + "numeric", + "string", + "string1", + "xstring_contents", + "regexp_contents", + "words_sep", + "word_list", + "word", + "string_content", + "symbol_list", + "qword_list", + "qsym_list", + "string_dvar", + "string_dend", + "@27", + "ssym", + "dsym", + "@28", + "f_paren_args", + "args_tail", + "@29", + "f_kwarg", + "opt_args_tail", + "f_optarg", + "f_arg_asgn", + "f_arg_item", + "f_label", + "f_kw", + "f_block_kw", + "f_opt", + "f_block_opt", + "restarg_mark", + "blkarg_mark", + "assoc" ] +Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) + +Racc_debug_parser = false + +##### State transition tables end ##### + +# reduce 0 omitted + +def _reduce_1(val, _values, result) + @current_arg_stack.push(nil) + @max_numparam_stack.push(static: true) + + result +end + +def _reduce_2(val, _values, result) + result = val[1] + + @current_arg_stack.pop + @max_numparam_stack.pop + + result +end + +def _reduce_3(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_4(val, _values, result) + result = [] + + result +end + +def _reduce_5(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_6(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_7(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 8 omitted + +def _reduce_9(val, _values, result) + result = @builder.preexe(val[0], *val[1]) + + result +end + +def _reduce_10(val, _values, result) + result = val + + result +end + +def _reduce_11(val, _values, result) + rescue_bodies = val[1] + else_t, else_ = val[2] + ensure_t, ensure_ = val[3] + + if rescue_bodies.empty? && !else_t.nil? + diagnostic :error, :useless_else, nil, else_t + end + + result = @builder.begin_body(val[0], + rescue_bodies, + else_t, else_, + ensure_t, ensure_) + + result +end + +def _reduce_12(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_13(val, _values, result) + result = [] + + result +end + +def _reduce_14(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_15(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_16(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 17 omitted + +def _reduce_18(val, _values, result) + diagnostic :error, :begin_in_method, nil, val[0] + + result +end + +def _reduce_19(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_20(val, _values, result) + result = @builder.alias(val[0], val[1], val[3]) + + result +end + +def _reduce_21(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.gvar(val[2])) + + result +end + +def _reduce_22(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.back_ref(val[2])) + + result +end + +def _reduce_23(val, _values, result) + diagnostic :error, :nth_ref_alias, nil, val[2] + + result +end + +def _reduce_24(val, _values, result) + result = @builder.undef_method(val[0], val[1]) + + result +end + +def _reduce_25(val, _values, result) + result = @builder.condition_mod(val[0], nil, + val[1], val[2]) + + result +end + +def _reduce_26(val, _values, result) + result = @builder.condition_mod(nil, val[0], + val[1], val[2]) + + result +end + +def _reduce_27(val, _values, result) + result = @builder.loop_mod(:while, val[0], val[1], val[2]) + + result +end + +def _reduce_28(val, _values, result) + result = @builder.loop_mod(:until, val[0], val[1], val[2]) + + result +end + +def _reduce_29(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_30(val, _values, result) + result = @builder.postexe(val[0], val[1], val[2], val[3]) + + result +end + +# reduce 31 omitted + +def _reduce_32(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_33(val, _values, result) + result = @builder.assign(val[0], val[1], + @builder.array(nil, val[2], nil)) + + result +end + +def _reduce_34(val, _values, result) + rescue_body = @builder.rescue_body(val[3], + nil, nil, nil, + nil, val[4]) + begin_body = @builder.begin_body(val[2], [ rescue_body ]) + + result = @builder.multi_assign(val[0], val[1], begin_body) + + result +end + +def _reduce_35(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +# reduce 36 omitted + +def _reduce_37(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_38(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_39(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_40(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_41(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_42(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_43(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_44(val, _values, result) + def_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + result = @builder.def_endless_method(def_t, name_t, + val[1], val[2], val[3]) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_45(val, _values, result) + def_t, recv, dot_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + result = @builder.def_endless_singleton(def_t, recv, dot_t, name_t, + val[1], val[2], val[3]) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_46(val, _values, result) + @builder.op_assign(val[0], val[1], val[2]) + + result +end + +# reduce 47 omitted + +def _reduce_48(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_49(val, _values, result) + result = @builder.not_op(val[0], nil, val[2], nil) + + result +end + +# reduce 50 omitted + +def _reduce_51(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +# reduce 52 omitted + +# reduce 53 omitted + +def _reduce_54(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_55(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_56(val, _values, result) + result = @builder.not_op(val[0], nil, val[2], nil) + + result +end + +def _reduce_57(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +def _reduce_58(val, _values, result) + @pattern_variables.pop + @pattern_hash_keys.pop + @context.in_kwarg = val[2] + result = @builder.match_pattern(val[0], val[1], val[5]) + + result +end + +def _reduce_59(val, _values, result) + @pattern_variables.pop + @pattern_hash_keys.pop + @context.in_kwarg = val[2] + result = @builder.match_pattern_p(val[0], val[1], val[5]) + + result +end + +# reduce 60 omitted + +# reduce 61 omitted + +def _reduce_62(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_63(val, _values, result) + @lexer.cond.pop + result = [ val[1], val[2] ] + + result +end + +def _reduce_64(val, _values, result) + local_push + @current_arg_stack.push(nil) + + result = [ val[0], @context.dup ] + @context.in_def = true + + result +end + +def _reduce_65(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +def _reduce_66(val, _values, result) + @lexer.state = :expr_fname + @context.in_argdef = true + + result +end + +def _reduce_67(val, _values, result) + result = [ val[0], val[1], val[2], val[4] ] + + result +end + +# reduce 68 omitted + +# reduce 69 omitted + +# reduce 70 omitted + +def _reduce_71(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_72(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_73(val, _values, result) + @context.in_block = val[1].in_block + result = [ val[0], *val[2], val[3] ] + + result +end + +# reduce 74 omitted + +def _reduce_75(val, _values, result) + result = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + result +end + +def _reduce_76(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + begin_t, args, body, end_t = val[2] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_77(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_78(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_79(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_80(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_81(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, [], nil) + + args, body = val[4] + result = @builder.block(method_call, val[3], args, body, val[5]) + + result +end + +def _reduce_82(val, _values, result) + result = @builder.keyword_cmd(:super, val[0], + nil, val[1], nil) + + result +end + +def _reduce_83(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], + nil, val[1], nil) + + result +end + +def _reduce_84(val, _values, result) + result = @builder.keyword_cmd(:return, val[0], + nil, val[1], nil) + + result +end + +def _reduce_85(val, _values, result) + result = @builder.keyword_cmd(:break, val[0], + nil, val[1], nil) + + result +end + +def _reduce_86(val, _values, result) + result = @builder.keyword_cmd(:next, val[0], + nil, val[1], nil) + + result +end + +def _reduce_87(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_88(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_89(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_90(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +# reduce 91 omitted + +def _reduce_92(val, _values, result) + result = val[0]. + push(val[1]) + + result +end + +def _reduce_93(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])) + + result +end + +def _reduce_94(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])). + concat(val[4]) + + result +end + +def _reduce_95(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])) + + result +end + +def _reduce_96(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])). + concat(val[3]) + + result +end + +def _reduce_97(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_98(val, _values, result) + result = [ @builder.splat(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_99(val, _values, result) + result = [ @builder.splat(val[0]) ] + + result +end + +def _reduce_100(val, _values, result) + result = [ @builder.splat(val[0]), + *val[2] ] + + result +end + +# reduce 101 omitted + +def _reduce_102(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_103(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_104(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_105(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_106(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_107(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_108(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_109(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_110(val, _values, result) + if (val[1][0] == :anddot) + diagnostic :error, :csend_in_lhs_of_masgn, nil, val[1] + end + + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_111(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_112(val, _values, result) + if (val[1][0] == :anddot) + diagnostic :error, :csend_in_lhs_of_masgn, nil, val[1] + end + + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_113(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_114(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_115(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_116(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_117(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_118(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_119(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_120(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_121(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_122(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_123(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_124(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_125(val, _values, result) + diagnostic :error, :module_name_const, nil, val[0] + + result +end + +# reduce 126 omitted + +def _reduce_127(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_128(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_129(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +# reduce 130 omitted + +# reduce 131 omitted + +# reduce 132 omitted + +# reduce 133 omitted + +# reduce 134 omitted + +def _reduce_135(val, _values, result) + result = @builder.symbol_internal(val[0]) + + result +end + +# reduce 136 omitted + +def _reduce_137(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_138(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_139(val, _values, result) + result = val[0] << val[3] + + result +end + +# reduce 140 omitted + +# reduce 141 omitted + +# reduce 142 omitted + +# reduce 143 omitted + +# reduce 144 omitted + +# reduce 145 omitted + +# reduce 146 omitted + +# reduce 147 omitted + +# reduce 148 omitted + +# reduce 149 omitted + +# reduce 150 omitted + +# reduce 151 omitted + +# reduce 152 omitted + +# reduce 153 omitted + +# reduce 154 omitted + +# reduce 155 omitted + +# reduce 156 omitted + +# reduce 157 omitted + +# reduce 158 omitted + +# reduce 159 omitted + +# reduce 160 omitted + +# reduce 161 omitted + +# reduce 162 omitted + +# reduce 163 omitted + +# reduce 164 omitted + +# reduce 165 omitted + +# reduce 166 omitted + +# reduce 167 omitted + +# reduce 168 omitted + +# reduce 169 omitted + +# reduce 170 omitted + +# reduce 171 omitted + +# reduce 172 omitted + +# reduce 173 omitted + +# reduce 174 omitted + +# reduce 175 omitted + +# reduce 176 omitted + +# reduce 177 omitted + +# reduce 178 omitted + +# reduce 179 omitted + +# reduce 180 omitted + +# reduce 181 omitted + +# reduce 182 omitted + +# reduce 183 omitted + +# reduce 184 omitted + +# reduce 185 omitted + +# reduce 186 omitted + +# reduce 187 omitted + +# reduce 188 omitted + +# reduce 189 omitted + +# reduce 190 omitted + +# reduce 191 omitted + +# reduce 192 omitted + +# reduce 193 omitted + +# reduce 194 omitted + +# reduce 195 omitted + +# reduce 196 omitted + +# reduce 197 omitted + +# reduce 198 omitted + +# reduce 199 omitted + +# reduce 200 omitted + +# reduce 201 omitted + +# reduce 202 omitted + +# reduce 203 omitted + +# reduce 204 omitted + +# reduce 205 omitted + +# reduce 206 omitted + +# reduce 207 omitted + +# reduce 208 omitted + +# reduce 209 omitted + +# reduce 210 omitted + +def _reduce_211(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_212(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_213(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_214(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_215(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_216(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_217(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_218(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_global(val[0], val[1])) + result = @builder.op_assign(const, val[2], val[3]) + + result +end + +def _reduce_219(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_220(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_221(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_222(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], nil) + + result +end + +def _reduce_223(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], nil) + + result +end + +def _reduce_224(val, _values, result) + result = @builder.range_inclusive(nil, val[0], val[1]) + + result +end + +def _reduce_225(val, _values, result) + result = @builder.range_exclusive(nil, val[0], val[1]) + + result +end + +def _reduce_226(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_227(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_228(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_229(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_230(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_231(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_232(val, _values, result) + result = @builder.unary_op(val[0], + @builder.binary_op( + val[1], val[2], val[3])) + + result +end + +def _reduce_233(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_234(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_235(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_236(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_237(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_238(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +# reduce 239 omitted + +def _reduce_240(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_241(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_242(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_243(val, _values, result) + result = @builder.match_op(val[0], val[1], val[2]) + + result +end + +def _reduce_244(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_245(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +def _reduce_246(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_247(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_248(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_249(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_250(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_251(val, _values, result) + @context.in_defined = val[2].in_defined + result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[3] ], nil) + + result +end + +def _reduce_252(val, _values, result) + result = @builder.ternary(val[0], val[1], + val[2], val[4], val[5]) + + result +end + +def _reduce_253(val, _values, result) + def_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + result = @builder.def_endless_method(def_t, name_t, + val[1], val[2], val[3]) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_254(val, _values, result) + def_t, recv, dot_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + result = @builder.def_endless_singleton(def_t, recv, dot_t, name_t, + val[1], val[2], val[3]) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +# reduce 255 omitted + +# reduce 256 omitted + +def _reduce_257(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_258(val, _values, result) + result = @builder.not_op(val[0], nil, val[2], nil) + + result +end + +# reduce 259 omitted + +# reduce 260 omitted + +# reduce 261 omitted + +# reduce 262 omitted + +def _reduce_263(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_264(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_265(val, _values, result) + result = @context.dup + + result +end + +# reduce 266 omitted + +# reduce 267 omitted + +# reduce 268 omitted + +def _reduce_269(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_270(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +# reduce 271 omitted + +def _reduce_272(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_273(val, _values, result) + result = val + + result +end + +def _reduce_274(val, _values, result) + unless @static_env.declared_forward_args? + diagnostic :error, :unexpected_token, { :token => 'tBDOT3' } , val[3] + end + + result = [val[0], [*val[1], @builder.forwarded_args(val[3])], val[4]] + + result +end + +def _reduce_275(val, _values, result) + unless @static_env.declared_forward_args? + diagnostic :error, :unexpected_token, { :token => 'tBDOT3' } , val[1] + end + + result = [val[0], [@builder.forwarded_args(val[1])], val[2]] + + result +end + +def _reduce_276(val, _values, result) + result = [ nil, [], nil ] + + result +end + +# reduce 277 omitted + +def _reduce_278(val, _values, result) + result = [] + + result +end + +# reduce 279 omitted + +# reduce 280 omitted + +def _reduce_281(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_282(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +def _reduce_283(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_284(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_285(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + result.concat(val[1]) + + result +end + +def _reduce_286(val, _values, result) + assocs = @builder.associate(nil, val[2], nil) + result = val[0] << assocs + result.concat(val[3]) + + result +end + +def _reduce_287(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_288(val, _values, result) + # When branch gets invoked by RACC's lookahead + # and command args start with '[' or '(' + # we need to put `true` to the cmdarg stack + # **before** `false` pushed by lexer + # m [], n + # ^ + # Right here we have cmdarg [...0] because + # lexer pushed it on '[' + # We need to modify cmdarg stack to [...10] + # + # For all other cases (like `m n` or `m n, []`) we simply put 1 to the stack + # and later lexer pushes corresponding bits on top of it. + last_token = @last_token[0] + lookahead = last_token == :tLBRACK || last_token == :tLPAREN_ARG + + if lookahead + top = @lexer.cmdarg.pop + @lexer.cmdarg.push(true) + @lexer.cmdarg.push(top) + else + @lexer.cmdarg.push(true) + end + + result +end + +def _reduce_289(val, _values, result) + # call_args can be followed by tLBRACE_ARG (that does cmdarg.push(0) in the lexer) + # but the push must be done after cmdarg.pop() in the parser. + # So this code does cmdarg.pop() to pop 0 pushed by tLBRACE_ARG, + # cmdarg.pop() to pop 1 pushed by command_args, + # and cmdarg.push(0) to restore back the flag set by tLBRACE_ARG. + last_token = @last_token[0] + lookahead = last_token == :tLBRACE_ARG + if lookahead + top = @lexer.cmdarg.pop + @lexer.cmdarg.pop + @lexer.cmdarg.push(top) + else + @lexer.cmdarg.pop + end + + result = val[1] + + result +end + +def _reduce_290(val, _values, result) + result = @builder.block_pass(val[0], val[1]) + + result +end + +def _reduce_291(val, _values, result) + if !@static_env.declared_anonymous_blockarg? + diagnostic :error, :no_anonymous_blockarg, nil, val[0] + end + + if @context.in_dynamic_block? && context.in_def && + @static_env.declared_anonymous_blockarg_in_current_scpe? && @static_env.parent_has_anonymous_blockarg? + diagnostic :error, :ambiguous_anonymous_blockarg, nil, val[0] + end + + result = @builder.block_pass(val[0], nil) + + result +end + +def _reduce_292(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_293(val, _values, result) + result = [] + + result +end + +def _reduce_294(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 295 omitted + +def _reduce_296(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_297(val, _values, result) + result = val[0].concat(val[2]) + + result +end + +def _reduce_298(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_299(val, _values, result) + if !@static_env.declared_anonymous_restarg? + diagnostic :error, :no_anonymous_restarg, nil, val[0] + end + + if @context.in_dynamic_block? && context.in_def && + @static_env.declared_anonymous_restarg_in_current_scope? && @static_env.parent_has_anonymous_restarg? + diagnostic :error, :ambiguous_anonymous_restarg, nil, val[0] + end + + result = [ @builder.forwarded_restarg(val[0]) ] + + result +end + +def _reduce_300(val, _values, result) + result = @builder.array(nil, val[0], nil) + + result +end + +# reduce 301 omitted + +def _reduce_302(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_303(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_304(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +# reduce 305 omitted + +# reduce 306 omitted + +# reduce 307 omitted + +# reduce 308 omitted + +# reduce 309 omitted + +# reduce 310 omitted + +# reduce 311 omitted + +# reduce 312 omitted + +# reduce 313 omitted + +# reduce 314 omitted + +def _reduce_315(val, _values, result) + result = @builder.call_method(nil, nil, val[0]) + + result +end + +def _reduce_316(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_317(val, _values, result) + @lexer.cmdarg.pop + + result = @builder.begin_keyword(val[0], val[2], val[3]) + + result +end + +def _reduce_318(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_319(val, _values, result) + result = @builder.begin(val[0], val[1], val[3]) + + result +end + +def _reduce_320(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_321(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +def _reduce_322(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_323(val, _values, result) + result = @builder.array(val[0], val[1], val[2]) + + result +end + +def _reduce_324(val, _values, result) + result = @builder.associate(val[0], val[1], val[2]) + + result +end + +def _reduce_325(val, _values, result) + result = @builder.keyword_cmd(:return, val[0]) + + result +end + +def _reduce_326(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_327(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2]) + + result +end + +def _reduce_328(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0]) + + result +end + +def _reduce_329(val, _values, result) + @context.in_defined = val[3].in_defined + result = @builder.keyword_cmd(:defined?, val[0], + val[2], [ val[4] ], val[5]) + + result +end + +def _reduce_330(val, _values, result) + result = @builder.not_op(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_331(val, _values, result) + result = @builder.not_op(val[0], val[1], nil, val[2]) + + result +end + +def _reduce_332(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0]) + + begin_t, args, body, end_t = val[1] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +# reduce 333 omitted + +def _reduce_334(val, _values, result) + begin_t, args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, args, body, end_t) + + result +end + +# reduce 335 omitted + +def _reduce_336(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, val[5]) + + result +end + +def _reduce_337(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + else_, else_t, + val[3], val[5]) + + result +end + +def _reduce_338(val, _values, result) + result = @builder.loop(:while, val[0], *val[1], val[2], val[3]) + + result +end + +def _reduce_339(val, _values, result) + result = @builder.loop(:until, val[0], *val[1], val[2], val[3]) + + result +end + +def _reduce_340(val, _values, result) + *when_bodies, (else_t, else_body) = *val[3] + + result = @builder.case(val[0], val[1], + when_bodies, else_t, else_body, + val[4]) + + result +end + +def _reduce_341(val, _values, result) + *when_bodies, (else_t, else_body) = *val[2] + + result = @builder.case(val[0], nil, + when_bodies, else_t, else_body, + val[3]) + + result +end + +def _reduce_342(val, _values, result) + *in_bodies, (else_t, else_body) = *val[3] + + result = @builder.case_match(val[0], val[1], + in_bodies, else_t, else_body, + val[4]) + + result +end + +def _reduce_343(val, _values, result) + result = @builder.for(val[0], val[1], val[2], *val[3], val[4], val[5]) + + result +end + +def _reduce_344(val, _values, result) + @context.in_class = true + local_push + + result +end + +def _reduce_345(val, _values, result) + k_class, ctx = val[0] + if @context.in_def + diagnostic :error, :class_in_def, nil, k_class + end + lt_t, superclass = val[2] + result = @builder.def_class(k_class, val[1], + lt_t, superclass, + val[4], val[5]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_346(val, _values, result) + @context.in_def = false + @context.in_class = false + local_push + + result +end + +def _reduce_347(val, _values, result) + k_class, ctx = val[0] + result = @builder.def_sclass(k_class, val[1], val[2], + val[5], val[6]) + + local_pop + @context.in_def = ctx.in_def + @context.in_class = ctx.in_class + + result +end + +def _reduce_348(val, _values, result) + @context.in_class = true + local_push + + result +end + +def _reduce_349(val, _values, result) + k_mod, ctx = val[0] + if @context.in_def + diagnostic :error, :module_in_def, nil, k_mod + end + result = @builder.def_module(k_mod, val[1], + val[3], val[4]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_350(val, _values, result) + def_t, (name_t, ctx) = val[0] + result = @builder.def_method(def_t, name_t, val[1], + val[2], val[3]) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_351(val, _values, result) + def_t, recv, dot_t, (name_t, ctx) = val[0] + result = @builder.def_singleton(def_t, recv, dot_t, name_t, val[1], + val[2], val[3]) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_352(val, _values, result) + result = @builder.keyword_cmd(:break, val[0]) + + result +end + +def _reduce_353(val, _values, result) + result = @builder.keyword_cmd(:next, val[0]) + + result +end + +def _reduce_354(val, _values, result) + result = @builder.keyword_cmd(:redo, val[0]) + + result +end + +def _reduce_355(val, _values, result) + result = @builder.keyword_cmd(:retry, val[0]) + + result +end + +# reduce 356 omitted + +def _reduce_357(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_358(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_359(val, _values, result) + result = val[0] + @context.in_argdef = true + + result +end + +def _reduce_360(val, _values, result) + if @context.in_class && !@context.in_def && !(context.in_block || context.in_lambda) + diagnostic :error, :invalid_return, nil, val[0] + end + + result +end + +# reduce 361 omitted + +# reduce 362 omitted + +def _reduce_363(val, _values, result) + result = val[1] + + result +end + +# reduce 364 omitted + +# reduce 365 omitted + +# reduce 366 omitted + +def _reduce_367(val, _values, result) + else_t, else_ = val[4] + result = [ val[0], + @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, nil), + ] + + result +end + +# reduce 368 omitted + +def _reduce_369(val, _values, result) + result = val + + result +end + +# reduce 370 omitted + +# reduce 371 omitted + +def _reduce_372(val, _values, result) + result = @builder.arg(val[0]) + + result +end + +def _reduce_373(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_374(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_375(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 376 omitted + +def _reduce_377(val, _values, result) + result = val[0]. + push(val[2]) + + result +end + +def _reduce_378(val, _values, result) + result = val[0]. + push(val[2]). + concat(val[4]) + + result +end + +def _reduce_379(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_380(val, _values, result) + result = [ val[0], *val[2] ] + + result +end + +def _reduce_381(val, _values, result) + result = @builder.restarg(val[0], val[1]) + + result +end + +def _reduce_382(val, _values, result) + result = @builder.restarg(val[0]) + + result +end + +# reduce 383 omitted + +# reduce 384 omitted + +def _reduce_385(val, _values, result) + @context.in_argdef = false + + result +end + +def _reduce_386(val, _values, result) + result = val[1] + + result +end + +def _reduce_387(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_388(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_389(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_390(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_391(val, _values, result) + result = val[1] + + result +end + +def _reduce_392(val, _values, result) + result = [] + + result +end + +# reduce 393 omitted + +def _reduce_394(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_395(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_396(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_397(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_398(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 399 omitted + +def _reduce_400(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_401(val, _values, result) + if val[1].empty? && val[0].size == 1 + result = [@builder.procarg0(val[0][0])] + else + result = val[0].concat(val[1]) + end + + result +end + +def _reduce_402(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_403(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_404(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_405(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_406(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_407(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 408 omitted + +def _reduce_409(val, _values, result) + result = @builder.args(nil, [], nil) + + result +end + +def _reduce_410(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_411(val, _values, result) + @max_numparam_stack.has_ordinary_params! + @current_arg_stack.set(nil) + @context.in_argdef = false + result = @builder.args(val[0], val[1], val[2]) + + result +end + +def _reduce_412(val, _values, result) + @max_numparam_stack.has_ordinary_params! + @current_arg_stack.set(nil) + @context.in_argdef = false + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_413(val, _values, result) + result = [] + + result +end + +def _reduce_414(val, _values, result) + result = val[2] + + result +end + +def _reduce_415(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_416(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_417(val, _values, result) + @static_env.declare val[0][0] + result = @builder.shadowarg(val[0]) + + result +end + +# reduce 418 omitted + +def _reduce_419(val, _values, result) + @static_env.extend_dynamic + @max_numparam_stack.push(static: false) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_420(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_421(val, _values, result) + lambda_call = @builder.call_lambda(val[0]) + args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[2] + begin_t, body, end_t = val[4] + + @max_numparam_stack.pop + @static_env.unextend + @lexer.cmdarg.pop + @context.in_lambda = val[1].in_lambda + + result = @builder.block(lambda_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_422(val, _values, result) + @context.in_argdef = false + @max_numparam_stack.has_ordinary_params! + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_423(val, _values, result) + @context.in_argdef = false + if val[0].any? + @max_numparam_stack.has_ordinary_params! + end + result = @builder.args(nil, val[0], nil) + + result +end + +def _reduce_424(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_425(val, _values, result) + @context.in_lambda = val[1].in_lambda + result = [ val[0], val[2], val[3] ] + + result +end + +def _reduce_426(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_427(val, _values, result) + @context.in_lambda = val[1].in_lambda + result = [ val[0], val[2], val[3] ] + + result +end + +def _reduce_428(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_429(val, _values, result) + @context.in_block = val[1].in_block + result = [ val[0], *val[2], val[3] ] + + result +end + +def _reduce_430(val, _values, result) + begin_t, block_args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, block_args, body, end_t) + + result +end + +def _reduce_431(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_432(val, _values, result) + lparen_t, args, rparen_t = val[3] + method_call = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_433(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_434(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.call_method(nil, nil, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_435(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_436(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_437(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2]) + + result +end + +def _reduce_438(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_439(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_440(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.keyword_cmd(:super, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_441(val, _values, result) + result = @builder.keyword_cmd(:zsuper, val[0]) + + result +end + +def _reduce_442(val, _values, result) + result = @builder.index(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_443(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_444(val, _values, result) + @context.in_block = val[1].in_block + result = [ val[0], *val[2], val[3] ] + + result +end + +def _reduce_445(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_446(val, _values, result) + @context.in_block = val[1].in_block + result = [ val[0], *val[2], val[3] ] + + result +end + +def _reduce_447(val, _values, result) + @static_env.extend_dynamic + @max_numparam_stack.push(static: false) + + result +end + +def _reduce_448(val, _values, result) + args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[1] + result = [ args, val[2] ] + + @max_numparam_stack.pop + @static_env.unextend + + result +end + +def _reduce_449(val, _values, result) + @static_env.extend_dynamic + @max_numparam_stack.push(static: false) + + result +end + +def _reduce_450(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_451(val, _values, result) + args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[2] + result = [ args, val[3] ] + + @max_numparam_stack.pop + @static_env.unextend + @lexer.cmdarg.pop + + result +end + +def _reduce_452(val, _values, result) + result = [ @builder.when(val[0], val[1], val[2], val[3]), + *val[4] ] + + result +end + +def _reduce_453(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 454 omitted + +def _reduce_455(val, _values, result) + @pattern_variables.push + + result +end + +def _reduce_456(val, _values, result) + @pattern_hash_keys.push + + result +end + +def _reduce_457(val, _values, result) + result = @context.in_kwarg + + @lexer.state = :expr_beg + @lexer.command_start = false + @context.in_kwarg = true + + result +end + +def _reduce_458(val, _values, result) + @pattern_variables.pop + @pattern_hash_keys.pop + @context.in_kwarg = val[1] + + result +end + +def _reduce_459(val, _values, result) + result = [ @builder.in_pattern(val[0], *val[4], val[5], val[7]), + *val[8] ] + + result +end + +def _reduce_460(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 461 omitted + +def _reduce_462(val, _values, result) + result = [ val[0], nil ] + + result +end + +def _reduce_463(val, _values, result) + result = [ val[0], @builder.if_guard(val[1], val[2]) ] + + result +end + +def _reduce_464(val, _values, result) + result = [ val[0], @builder.unless_guard(val[1], val[2]) ] + + result +end + +# reduce 465 omitted + +def _reduce_466(val, _values, result) + # array patterns that end with comma + # like 1, 2, + # must be emitted as `array_pattern_with_tail` + item = @builder.match_with_trailing_comma(val[0], val[1]) + result = @builder.array_pattern(nil, [ item ], nil) + + result +end + +def _reduce_467(val, _values, result) + result = @builder.array_pattern(nil, [val[0]].concat(val[2]), nil) + + result +end + +def _reduce_468(val, _values, result) + result = @builder.find_pattern(nil, val[0], nil) + + result +end + +def _reduce_469(val, _values, result) + result = @builder.array_pattern(nil, val[0], nil) + + result +end + +def _reduce_470(val, _values, result) + result = @builder.hash_pattern(nil, val[0], nil) + + result +end + +# reduce 471 omitted + +def _reduce_472(val, _values, result) + result = @builder.match_as(val[0], val[1], val[2]) + + result +end + +# reduce 473 omitted + +def _reduce_474(val, _values, result) + result = @builder.match_alt(val[0], val[1], val[2]) + + result +end + +# reduce 475 omitted + +def _reduce_476(val, _values, result) + result = val[0] + @pattern_hash_keys.push + + result +end + +def _reduce_477(val, _values, result) + result = val[0] + @pattern_hash_keys.push + + result +end + +# reduce 478 omitted + +# reduce 479 omitted + +def _reduce_480(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.array_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_481(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.find_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_482(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.hash_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_483(val, _values, result) + pattern = @builder.array_pattern(val[1], nil, val[2]) + result = @builder.const_pattern(val[0], val[1], pattern, val[2]) + + result +end + +def _reduce_484(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.array_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_485(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.find_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_486(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.hash_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_487(val, _values, result) + pattern = @builder.array_pattern(val[1], nil, val[2]) + result = @builder.const_pattern(val[0], val[1], pattern, val[2]) + + result +end + +def _reduce_488(val, _values, result) + result = @builder.array_pattern(val[0], val[1], val[2]) + + result +end + +def _reduce_489(val, _values, result) + result = @builder.find_pattern(val[0], val[1], val[2]) + + result +end + +def _reduce_490(val, _values, result) + result = @builder.array_pattern(val[0], [], val[1]) + + result +end + +def _reduce_491(val, _values, result) + @pattern_hash_keys.push + result = @context.in_kwarg + @context.in_kwarg = false + + result +end + +def _reduce_492(val, _values, result) + @pattern_hash_keys.pop + @context.in_kwarg = val[1] + result = @builder.hash_pattern(val[0], val[2], val[3]) + + result +end + +def _reduce_493(val, _values, result) + result = @builder.hash_pattern(val[0], [], val[1]) + + result +end + +def _reduce_494(val, _values, result) + @pattern_hash_keys.push + + result +end + +def _reduce_495(val, _values, result) + @pattern_hash_keys.pop + result = @builder.begin(val[0], val[2], val[3]) + + result +end + +def _reduce_496(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_497(val, _values, result) + result = val[0] + + result +end + +def _reduce_498(val, _values, result) + result = [ *val[0], val[1] ] + + result +end + +def _reduce_499(val, _values, result) + result = [ *val[0], val[1] ] + + result +end + +def _reduce_500(val, _values, result) + result = [ *val[0], val[1], *val[3] ] + + result +end + +# reduce 501 omitted + +def _reduce_502(val, _values, result) + # array patterns that end with comma + # like [1, 2,] + # must be emitted as `array_pattern_with_tail` + item = @builder.match_with_trailing_comma(val[0], val[1]) + result = [ item ] + + result +end + +def _reduce_503(val, _values, result) + # array patterns that end with comma + # like [1, 2,] + # must be emitted as `array_pattern_with_tail` + last_item = @builder.match_with_trailing_comma(val[1], val[2]) + result = [ *val[0], last_item ] + + result +end + +def _reduce_504(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_505(val, _values, result) + result = [ val[0], *val[2] ] + + result +end + +def _reduce_506(val, _values, result) + result = [ val[0], *val[2], val[4] ] + + result +end + +def _reduce_507(val, _values, result) + result = @builder.match_rest(val[0], val[1]) + + result +end + +def _reduce_508(val, _values, result) + result = @builder.match_rest(val[0]) + + result +end + +def _reduce_509(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_510(val, _values, result) + result = [ *val[0], val[2] ] + + result +end + +# reduce 511 omitted + +def _reduce_512(val, _values, result) + result = [ *val[0], *val[2] ] + + result +end + +def _reduce_513(val, _values, result) + result = val[0] + + result +end + +def _reduce_514(val, _values, result) + result = val[0] + + result +end + +def _reduce_515(val, _values, result) + result = val[0] + + result +end + +def _reduce_516(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_517(val, _values, result) + result = [ *val[0], val[2] ] + + result +end + +def _reduce_518(val, _values, result) + result = @builder.match_pair(*val[0], val[1]) + + result +end + +def _reduce_519(val, _values, result) + result = @builder.match_label(*val[0]) + + result +end + +def _reduce_520(val, _values, result) + result = [:label, val[0]] + + result +end + +def _reduce_521(val, _values, result) + result = [:quoted, [val[0], val[1], val[2]]] + + result +end + +def _reduce_522(val, _values, result) + result = [ @builder.match_rest(val[0], val[1]) ] + + result +end + +def _reduce_523(val, _values, result) + result = [ @builder.match_rest(val[0], nil) ] + + result +end + +def _reduce_524(val, _values, result) + result = val + + result +end + +# reduce 525 omitted + +def _reduce_526(val, _values, result) + result = [ @builder.match_nil_pattern(val[0][0], val[0][1]) ] + + result +end + +# reduce 527 omitted + +def _reduce_528(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_529(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_530(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], nil) + + result +end + +def _reduce_531(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], nil) + + result +end + +# reduce 532 omitted + +# reduce 533 omitted + +# reduce 534 omitted + +def _reduce_535(val, _values, result) + result = @builder.range_inclusive(nil, val[0], val[1]) + + result +end + +def _reduce_536(val, _values, result) + result = @builder.range_exclusive(nil, val[0], val[1]) + + result +end + +# reduce 537 omitted + +# reduce 538 omitted + +# reduce 539 omitted + +# reduce 540 omitted + +# reduce 541 omitted + +# reduce 542 omitted + +# reduce 543 omitted + +# reduce 544 omitted + +def _reduce_545(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +# reduce 546 omitted + +def _reduce_547(val, _values, result) + result = @builder.assignable(@builder.match_var(val[0])) + + result +end + +def _reduce_548(val, _values, result) + name = val[1][0] + lvar = @builder.accessible(@builder.ident(val[1])) + + unless static_env.declared?(name) + diagnostic :error, :undefined_lvar, { :name => name }, val[1] + end + + result = @builder.pin(val[0], lvar) + + result +end + +def _reduce_549(val, _values, result) + non_lvar = @builder.accessible(val[1]) + result = @builder.pin(val[0], non_lvar) + + result +end + +def _reduce_550(val, _values, result) + expr = @builder.begin(val[1], val[2], val[3]) + result = @builder.pin(val[0], expr) + + result +end + +def _reduce_551(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_552(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +def _reduce_553(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_554(val, _values, result) + assoc_t, exc_var = val[2] + + if val[1] + exc_list = @builder.array(nil, val[1], nil) + end + + result = [ @builder.rescue_body(val[0], + exc_list, assoc_t, exc_var, + val[3], val[4]), + *val[5] ] + + result +end + +def _reduce_555(val, _values, result) + result = [] + + result +end + +def _reduce_556(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 557 omitted + +# reduce 558 omitted + +def _reduce_559(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 560 omitted + +def _reduce_561(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 562 omitted + +# reduce 563 omitted + +# reduce 564 omitted + +def _reduce_565(val, _values, result) + result = @builder.string_compose(nil, val[0], nil) + + result +end + +def _reduce_566(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_567(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_568(val, _values, result) + string = @builder.string_compose(val[0], val[1], val[2]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_569(val, _values, result) + string = @builder.string(val[0]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_570(val, _values, result) + result = @builder.character(val[0]) + + result +end + +def _reduce_571(val, _values, result) + string = @builder.xstring_compose(val[0], val[1], val[2]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_572(val, _values, result) + opts = @builder.regexp_options(val[3]) + result = @builder.regexp_compose(val[0], val[1], val[2], opts) + + result +end + +# reduce 573 omitted + +# reduce 574 omitted + +def _reduce_575(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_576(val, _values, result) + result = [] + + result +end + +def _reduce_577(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_578(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_579(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_580(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_581(val, _values, result) + result = [] + + result +end + +def _reduce_582(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_583(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_584(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_585(val, _values, result) + result = [] + + result +end + +def _reduce_586(val, _values, result) + result = val[0] << @builder.string_internal(val[1]) + + result +end + +def _reduce_587(val, _values, result) + result = [] + + result +end + +def _reduce_588(val, _values, result) + result = val[0] << @builder.symbol_internal(val[1]) + + result +end + +def _reduce_589(val, _values, result) + result = [] + + result +end + +def _reduce_590(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_591(val, _values, result) + result = [] + + result +end + +def _reduce_592(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_593(val, _values, result) + result = [] + + result +end + +def _reduce_594(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_595(val, _values, result) + result = @builder.string_internal(val[0]) + + result +end + +def _reduce_596(val, _values, result) + result = val[1] + + result +end + +def _reduce_597(val, _values, result) + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + + result +end + +def _reduce_598(val, _values, result) + @lexer.cmdarg.pop + @lexer.cond.pop + + result = @builder.begin(val[0], val[2], val[3]) + + result +end + +# reduce 599 omitted + +def _reduce_600(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +# reduce 601 omitted + +# reduce 602 omitted + +# reduce 603 omitted + +def _reduce_604(val, _values, result) + @lexer.state = :expr_end + result = @builder.symbol(val[0]) + + result +end + +def _reduce_605(val, _values, result) + @lexer.state = :expr_end + result = @builder.symbol_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_606(val, _values, result) + result = val[0] + + result +end + +def _reduce_607(val, _values, result) + if @builder.respond_to? :negate + # AST builder interface compatibility + result = @builder.negate(val[0], val[1]) + else + result = @builder.unary_num(val[0], val[1]) + end + + result +end + +def _reduce_608(val, _values, result) + @lexer.state = :expr_end + result = @builder.integer(val[0]) + + result +end + +def _reduce_609(val, _values, result) + @lexer.state = :expr_end + result = @builder.float(val[0]) + + result +end + +def _reduce_610(val, _values, result) + @lexer.state = :expr_end + result = @builder.rational(val[0]) + + result +end + +def _reduce_611(val, _values, result) + @lexer.state = :expr_end + result = @builder.complex(val[0]) + + result +end + +def _reduce_612(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_613(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_614(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +def _reduce_615(val, _values, result) + result = @builder.ident(val[0]) + + result +end + +def _reduce_616(val, _values, result) + result = @builder.const(val[0]) + + result +end + +# reduce 617 omitted + +def _reduce_618(val, _values, result) + result = @builder.nil(val[0]) + + result +end + +def _reduce_619(val, _values, result) + result = @builder.self(val[0]) + + result +end + +def _reduce_620(val, _values, result) + result = @builder.true(val[0]) + + result +end + +def _reduce_621(val, _values, result) + result = @builder.false(val[0]) + + result +end + +def _reduce_622(val, _values, result) + result = @builder.__FILE__(val[0]) + + result +end + +def _reduce_623(val, _values, result) + result = @builder.__LINE__(val[0]) + + result +end + +def _reduce_624(val, _values, result) + result = @builder.__ENCODING__(val[0]) + + result +end + +def _reduce_625(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_626(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_627(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_628(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_629(val, _values, result) + result = @builder.nth_ref(val[0]) + + result +end + +def _reduce_630(val, _values, result) + result = @builder.back_ref(val[0]) + + result +end + +def _reduce_631(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_632(val, _values, result) + result = [ val[0], val[2] ] + + result +end + +def _reduce_633(val, _values, result) + result = nil + + result +end + +# reduce 634 omitted + +def _reduce_635(val, _values, result) + @context.in_argdef = false + result = @builder.args(nil, [], nil) + + result +end + +def _reduce_636(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + @lexer.state = :expr_value + @context.in_argdef = false + + result +end + +# reduce 637 omitted + +def _reduce_638(val, _values, result) + result = @context.dup + @context.in_kwarg = true + @context.in_argdef = true + + result +end + +def _reduce_639(val, _values, result) + @context.in_kwarg = val[0].in_kwarg + @context.in_argdef = false + result = @builder.args(nil, val[1], nil) + + result +end + +def _reduce_640(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_641(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_642(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_643(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_644(val, _values, result) + @static_env.declare_forward_args + result = [ @builder.forward_arg(val[0]) ] + + result +end + +def _reduce_645(val, _values, result) + result = val[1] + + result +end + +def _reduce_646(val, _values, result) + result = [] + + result +end + +def _reduce_647(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_648(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_649(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_650(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_651(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_652(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_653(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_654(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_655(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_656(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_657(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_658(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_659(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_660(val, _values, result) + result = val[0] + + result +end + +def _reduce_661(val, _values, result) + result = [] + + result +end + +def _reduce_662(val, _values, result) + result = val[0] + + result +end + +def _reduce_663(val, _values, result) + diagnostic :error, :argument_const, nil, val[0] + + result +end + +def _reduce_664(val, _values, result) + diagnostic :error, :argument_ivar, nil, val[0] + + result +end + +def _reduce_665(val, _values, result) + diagnostic :error, :argument_gvar, nil, val[0] + + result +end + +def _reduce_666(val, _values, result) + diagnostic :error, :argument_cvar, nil, val[0] + + result +end + +# reduce 667 omitted + +def _reduce_668(val, _values, result) + @static_env.declare val[0][0] + + @max_numparam_stack.has_ordinary_params! + + result = val[0] + + result +end + +def _reduce_669(val, _values, result) + @current_arg_stack.set(val[0][0]) + result = val[0] + + result +end + +def _reduce_670(val, _values, result) + @current_arg_stack.set(0) + result = @builder.arg(val[0]) + + result +end + +def _reduce_671(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_672(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_673(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_674(val, _values, result) + check_kwarg_name(val[0]) + + @static_env.declare val[0][0] + + @max_numparam_stack.has_ordinary_params! + + @current_arg_stack.set(val[0][0]) + @context.in_argdef = false + + result = val[0] + + result +end + +def _reduce_675(val, _values, result) + @current_arg_stack.set(nil) + @context.in_argdef = true + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_676(val, _values, result) + @current_arg_stack.set(nil) + @context.in_argdef = true + result = @builder.kwarg(val[0]) + + result +end + +def _reduce_677(val, _values, result) + @context.in_argdef = true + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_678(val, _values, result) + @context.in_argdef = true + result = @builder.kwarg(val[0]) + + result +end + +def _reduce_679(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_680(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_681(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_682(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 683 omitted + +# reduce 684 omitted + +def _reduce_685(val, _values, result) + result = [ @builder.kwnilarg(val[0][0], val[0][1]) ] + + result +end + +def _reduce_686(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.kwrestarg(val[0], val[1]) ] + + result +end + +def _reduce_687(val, _values, result) + @static_env.declare_anonymous_kwrestarg + + result = [ @builder.kwrestarg(val[0]) ] + + result +end + +def _reduce_688(val, _values, result) + @current_arg_stack.set(0) + @context.in_argdef = true + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_689(val, _values, result) + @current_arg_stack.set(0) + @context.in_argdef = true + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_690(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_691(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_692(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_693(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 694 omitted + +# reduce 695 omitted + +def _reduce_696(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_697(val, _values, result) + @static_env.declare_anonymous_restarg + + result = [ @builder.restarg(val[0]) ] + + result +end + +# reduce 698 omitted + +# reduce 699 omitted + +def _reduce_700(val, _values, result) + @static_env.declare val[1][0] + + result = @builder.blockarg(val[0], val[1]) + + result +end + +def _reduce_701(val, _values, result) + @static_env.declare_anonymous_blockarg + + result = @builder.blockarg(val[0], nil) + + result +end + +def _reduce_702(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_703(val, _values, result) + result = [] + + result +end + +# reduce 704 omitted + +def _reduce_705(val, _values, result) + result = val[1] + + result +end + +def _reduce_706(val, _values, result) + result = [] + + result +end + +# reduce 707 omitted + +def _reduce_708(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_709(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_710(val, _values, result) + result = @builder.pair(val[0], val[1], val[2]) + + result +end + +def _reduce_711(val, _values, result) + result = @builder.pair_keyword(val[0], val[1]) + + result +end + +def _reduce_712(val, _values, result) + result = @builder.pair_label(val[0]) + + result +end + +def _reduce_713(val, _values, result) + result = @builder.pair_quoted(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_714(val, _values, result) + result = @builder.kwsplat(val[0], val[1]) + + result +end + +def _reduce_715(val, _values, result) + if !@static_env.declared_anonymous_kwrestarg? + diagnostic :error, :no_anonymous_kwrestarg, nil, val[0] + end + + if @context.in_dynamic_block? && context.in_def && + @static_env.declared_anonymous_kwrestarg_in_current_scope? && @static_env.parent_has_anonymous_kwrestarg? + diagnostic :error, :ambiguous_anonymous_kwrestarg, nil, val[0] + end + + result = @builder.forwarded_kwrestarg(val[0]) + + result +end + +# reduce 716 omitted + +# reduce 717 omitted + +# reduce 718 omitted + +# reduce 719 omitted + +# reduce 720 omitted + +# reduce 721 omitted + +# reduce 722 omitted + +# reduce 723 omitted + +# reduce 724 omitted + +# reduce 725 omitted + +def _reduce_726(val, _values, result) + result = [:dot, val[0][1]] + + result +end + +def _reduce_727(val, _values, result) + result = [:anddot, val[0][1]] + + result +end + +# reduce 728 omitted + +# reduce 729 omitted + +# reduce 730 omitted + +# reduce 731 omitted + +def _reduce_732(val, _values, result) + result = val[1] + + result +end + +def _reduce_733(val, _values, result) + result = val[1] + + result +end + +def _reduce_734(val, _values, result) + result = val[1] + + result +end + +# reduce 735 omitted + +# reduce 736 omitted + +def _reduce_737(val, _values, result) + yyerrok + + result +end + +# reduce 738 omitted + +# reduce 739 omitted + +# reduce 740 omitted + +def _reduce_741(val, _values, result) + result = nil + + result +end + +def _reduce_none(val, _values, result) + val[0] +end + + end # class Ruby33 +end # module Parser diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby34.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby34.rb new file mode 100644 index 00000000..660e4671 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/ruby34.rb @@ -0,0 +1,12597 @@ +# -*- encoding:utf-8; warn-indent:false; frozen_string_literal: true -*- +# +# DO NOT MODIFY!!!! +# This file is automatically generated by Racc 1.8.1 +# from Racc grammar file "ruby34.y". +# + +require 'racc/parser.rb' + + +require_relative '../parser' + +module Parser + class Ruby34 < Parser::Base + + + def version + 34 + end + + def default_encoding + Encoding::UTF_8 + end + + def endless_method_name(name_t) + if !%w[=== == != <= >=].include?(name_t[0]) && name_t[0].end_with?('=') + diagnostic :error, :endless_setter, nil, name_t + end + end + + def local_push + @static_env.extend_static + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + @max_numparam_stack.push(static: true) + end + + def local_pop + @static_env.unextend + @lexer.cmdarg.pop + @lexer.cond.pop + @max_numparam_stack.pop + end + + def try_declare_numparam(node) + name = node.children[0] + + if name =~ /\A_[1-9]\z/ && !static_env.declared?(name) && @context.in_dynamic_block? + # definitely an implicit param + location = node.loc.expression + + if max_numparam_stack.has_ordinary_params? + diagnostic :error, :ordinary_param_defined, nil, [nil, location] + end + + raw_max_numparam_stack = max_numparam_stack.stack.dup + # ignore current block scope + raw_max_numparam_stack.pop + + raw_max_numparam_stack.reverse_each do |outer_scope| + if outer_scope[:static] + # found an outer scope that can't have numparams + # like def/class/etc + break + else + outer_scope_has_numparams = outer_scope[:value] > 0 + + if outer_scope_has_numparams + diagnostic :error, :numparam_used_in_outer_scope, nil, [nil, location] + else + # for now it's ok, but an outer scope can also be a block + # like proc { _1; proc { proc { proc { _2 }} }} + # with numparams, so we need to continue + end + end + end + + static_env.declare(name) + max_numparam_stack.register(name[1].to_i) + + true + else + false + end + end +##### State transition tables begin ### + +racc_action_table = [ + -615, -627, 312, 222, 223, 312, -116, -615, -615, -615, + 1064, 624, -615, -615, -615, 228, -615, 312, 1064, 665, + 127, 240, 227, 624, -615, 126, -615, -615, -615, 222, + 223, 225, 704, 667, -117, -124, -615, -615, 624, -615, + -615, -615, -615, -615, 624, 624, -116, -117, -124, 859, + 705, -123, 3, 127, -123, 1064, 1063, -628, 126, 799, + -116, 241, 241, 525, -119, -121, -615, -615, -615, -615, + -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, + 229, 307, -615, -615, -615, 664, -615, -615, 794, 311, + -615, 931, 311, -615, -615, -118, -615, 241, -615, 666, + -615, -511, -615, -615, 311, -615, -615, -615, -615, -615, + 624, -615, -616, -615, -119, -107, -117, 222, 223, -616, + -616, -616, -124, 241, -616, -616, -616, -615, -616, 127, + -615, -615, -615, -615, 126, -615, -616, -615, -616, -616, + -616, 127, -615, -108, -115, -615, 126, 234, -616, -616, + -121, -616, -616, -616, -616, -616, 127, -120, -118, 920, + -114, 126, 127, 127, -116, -117, -124, 126, 126, -116, + -117, -124, -123, -110, -112, -120, -730, -123, -616, -616, + -616, -616, -616, -616, -616, -616, -616, -616, -616, -616, + -616, -616, 127, -122, -616, -616, -616, 126, -616, -616, + 930, -122, -616, -741, -109, -616, -616, 859, -616, 631, + -616, 241, -616, 234, -616, -616, 241, -616, -616, -616, + -616, -616, -321, -616, 238, -616, 238, 604, 127, -321, + -321, -321, -119, 126, -716, -321, -321, -119, -321, -616, + -716, -110, -616, -616, -616, -616, -321, -616, 228, -616, + 312, -730, 631, 652, -616, 305, 123, -616, -321, -321, + 799, -321, -321, -321, -321, -321, -717, -102, -121, -741, + -717, -115, -112, -121, -111, -120, -118, 652, -109, -88, + -120, -118, 136, -124, -111, -124, -123, 241, -321, -321, + -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, + -321, -321, 219, 234, -321, -321, -321, -110, 691, -321, + -113, -122, -321, 229, 307, -321, -122, 654, 653, 650, + -321, 220, -321, 884, -321, -321, 652, -321, -321, -321, + -321, -321, 234, -321, 692, -321, 221, 311, -112, -716, + -111, 654, 653, 650, -109, 224, 989, -110, 240, -321, + -110, 90, -321, -321, 652, -113, 502, -321, 766, -741, + 127, -721, -110, 91, -321, 126, 885, -122, -721, -721, + -721, 104, 105, 92, -721, -721, 301, -721, -112, -730, + -111, -112, -119, -111, -109, -721, -721, -109, -741, 241, + 654, 653, 650, -112, 503, -111, 241, -721, -721, -109, + -721, -721, -721, -721, -721, 241, 1156, 1163, 615, 494, + -356, 491, 490, 489, 499, 492, 228, -356, 654, 653, + 655, 104, 105, 305, 502, -121, -356, -721, -721, -721, + -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, + -721, 240, -627, -721, -721, -721, 497, 693, -721, 106, + 107, -721, 652, 363, -721, 507, 506, 510, 509, -721, + 652, -721, 503, -721, -721, 652, -721, -721, -721, -721, + -721, -321, -721, -721, -721, -356, 686, 687, -321, -321, + -321, 229, 241, -321, -321, -321, -615, -321, -721, -107, + 364, -721, -721, -615, -111, -321, -721, -321, -321, 106, + 107, -116, 488, -721, -716, 241, -120, -321, -321, 704, + -321, -321, -321, -321, -321, 127, 654, 653, 222, 223, + 126, 652, 967, 652, 654, 653, 432, 1087, 652, 654, + 653, 657, 473, 1163, 823, -119, -121, -321, -321, -321, + -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, + -321, -615, -628, -321, -321, -321, -615, 886, -321, 241, + -634, -321, 618, -615, -321, -321, 652, -321, -716, -321, + 840, -321, -615, -321, -321, 513, -321, -321, -321, -321, + -321, -118, -321, 692, -321, 654, 653, 654, 653, 659, + -616, -716, 654, 653, 663, 823, 228, -616, -321, -108, + -623, -321, -321, 522, -321, 524, -321, -623, -622, 604, + -721, -117, 523, -321, 526, -622, -122, -721, -721, -721, + 127, -615, -721, -721, -721, 126, -721, 282, 283, -118, + 654, 653, 668, -624, -721, -721, -721, -721, -721, 1070, + -624, 637, 222, 223, 1066, 638, -721, -721, 1067, -721, + -721, -721, -721, -721, 637, -616, -114, 127, 1095, -621, + -618, 229, 126, 281, 280, -623, -621, -618, -123, 241, + 527, 886, 618, -622, -717, 240, -721, -721, -721, -721, + -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, + 562, 989, -721, -721, -721, 574, 887, -721, -624, 686, + -721, 502, -619, -721, -721, 576, -721, -620, -721, -619, + -721, 578, -721, -721, -620, -721, -721, -721, -721, -721, + -321, -721, -721, -721, -621, -618, 429, -321, -321, -321, + -122, 431, 430, -321, -321, 136, -321, -721, 265, 503, + -721, -721, -721, -721, -321, -721, -110, -721, 510, 509, + 637, 1156, -721, -717, 1095, -120, -321, -321, -119, -321, + -321, -321, -321, -321, -87, 241, 241, -619, 618, -625, + 262, 499, -620, 589, 264, 263, -625, 687, 109, 108, + 590, 502, 110, 121, 122, -625, -321, -321, -321, -321, + -321, -321, -321, -321, -321, -321, -321, -321, -321, -321, + 597, 840, -321, -321, -321, -616, 691, -321, 241, 316, + -321, 1186, -616, -321, 510, 509, 241, -717, -321, 503, + -321, -616, -321, -321, -112, -321, -321, -321, -321, -321, + 234, -321, 692, -321, -625, 234, -121, 915, 859, 494, + -717, 491, 490, 489, 499, 492, 307, -321, -109, 601, + -321, -321, -721, -321, 502, -321, 607, 265, 265, -721, + -118, 611, -321, 1088, 1089, -122, -721, -721, -721, 499, + -616, 619, -721, -721, 620, -721, 497, 915, 859, 502, + 1222, 1223, 578, -721, -721, 507, 506, 510, 509, 262, + -626, 631, 503, 264, 263, -721, -721, -626, -721, -721, + -721, -721, -721, 421, -721, 635, -626, 636, 228, 644, + 669, -721, 510, 509, 672, 596, -716, 503, 241, 673, + -721, -294, 674, 676, 594, -721, -721, -721, -721, -721, + -721, -721, -721, -721, -721, -721, -721, -721, -721, -721, + 680, -721, -721, -721, 241, 693, -721, -314, 684, -721, + 685, 307, -721, 702, -314, -626, 703, -721, 241, -721, + 707, -721, -721, -314, -721, -721, -721, -721, -721, -721, + -721, -721, -721, 229, 710, 228, 711, 713, 715, -385, + 228, 228, 606, 727, 728, 732, -721, 634, 640, -721, + -721, 523, -721, 734, -721, 228, 632, 642, 740, 741, + 265, -721, 679, 265, -120, 7, 81, 82, 83, 11, + 65, 677, -314, 265, 71, 72, 265, 241, 754, 75, + 241, 73, 74, 76, 35, 36, 79, 80, 257, 241, + 241, -102, 769, 84, 33, 32, 115, 114, 116, 117, + 229, 241, 23, 611, 780, 229, 229, 786, 10, 53, + 9, 12, 119, 118, 120, 111, 64, 109, 108, 112, + 229, 110, 121, 122, 787, 104, 105, 49, 50, 48, + 265, 269, 270, 271, 272, 282, 283, 277, 278, 273, + 274, -322, 258, 259, 790, 795, 275, 276, -322, 45, + 796, 256, 38, 800, 822, 66, 67, -322, 823, 68, + 823, 40, 262, -298, 268, 52, 264, 263, 841, 260, + 261, 281, 280, 266, 24, 267, 562, 562, 854, 102, + 90, 93, 94, -322, 95, 97, 96, 98, 856, 859, + -322, 877, 91, 101, 880, 279, 881, 241, 854, -322, + 85, 856, 92, 106, 107, 241, -322, 46, 47, 335, + 81, 82, 83, 11, 65, 893, 895, 301, 71, 72, + 901, 903, 905, 75, 576, 73, 74, 76, 35, 36, + 79, 80, 130, 131, 132, 133, 134, 84, 33, 32, + 115, 114, 116, 117, 578, 780, 23, 241, -322, 307, + 307, 681, 10, 53, 337, 12, 119, 118, 120, 111, + 64, 109, 108, 112, 780, 110, 121, 122, 265, 104, + 105, 49, 50, 48, 265, 269, 270, 271, 272, 282, + 283, 277, 278, 273, 274, -321, 258, 259, 859, 917, + 275, 276, -321, 45, 918, 241, 339, -717, 241, 66, + 67, -321, 928, 68, 241, 40, 262, 935, 268, 52, + 264, 263, 935, 260, 261, 281, 280, 266, 24, 267, + 935, 935, -296, 102, 90, 93, 94, 228, 95, 97, + 96, 98, 241, 940, 1128, 941, 91, 101, 947, 279, + -294, -266, 951, 1126, 85, 710, 92, 106, 107, 705, + -321, 46, 47, 335, 81, 82, 83, 11, 65, 954, + 956, 958, 71, 72, 960, 960, 241, 75, 903, 73, + 74, 76, 35, 36, 79, 80, 130, 131, 132, 133, + 134, 84, 33, 32, 115, 114, 116, 117, 1016, 241, + 23, 780, 229, 1033, 1035, 681, 10, 53, 337, 12, + 119, 118, 120, 111, 64, 109, 108, 112, 1039, 110, + 121, 122, 1040, 104, 105, 49, 50, 48, 265, 269, + 270, 271, 272, 282, 283, 277, 278, 273, 274, -321, + 258, 259, 1045, 1046, 275, 276, -321, 45, 1048, -298, + 38, -717, 854, 66, 67, -321, 856, 68, 1061, 40, + 262, 1062, 268, 52, 264, 263, 1065, 260, 261, 281, + 280, 266, 24, 267, 1082, 1083, 1084, 102, 90, 93, + 94, 228, 95, 97, 96, 98, 1098, 710, 1178, 1101, + 91, 101, 1104, 279, 1106, 1108, 241, 642, 85, -385, + 92, 106, 107, 1118, -321, 46, 47, 7, 81, 82, + 83, 11, 65, 1129, 1130, 960, 71, 72, 960, 960, + 1009, 75, 241, 73, 74, 76, 35, 36, 79, 80, + 130, 131, 132, 133, 134, 84, 33, 32, 115, 114, + 116, 117, 241, 1154, 23, 1157, 229, 1064, 1176, 1179, + 10, 53, 9, 12, 119, 118, 120, 111, 64, 109, + 108, 112, 1183, 110, 121, 122, 1184, 104, 105, 49, + 50, 48, 265, 269, 270, 271, 272, 282, 283, 277, + 278, 273, 274, 228, 258, 259, 702, 1062, 275, 276, + 1178, 45, 1194, 241, 38, 241, 241, 66, 67, 642, + 241, 68, 241, 40, 262, 241, 268, 52, 264, 263, + 1064, 260, 261, 281, 280, 266, 24, 267, 1201, 1202, + 241, 102, 90, 93, 94, 1206, 95, 97, 96, 98, + 241, 710, 1209, 1211, 91, 101, 1213, 279, 1215, 1215, + 241, 960, 85, -717, 92, 106, 107, -716, 229, 46, + 47, 335, 81, 82, 83, 11, 65, 1238, 1238, 1239, + 71, 72, 1215, 1215, 1215, 75, 1215, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, 494, 23, 491, + 490, 489, nil, 492, 10, 53, 337, 12, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, 265, 269, 270, 271, + 272, 282, 283, 277, 278, 273, 274, nil, 258, 259, + nil, nil, 275, 276, nil, 45, nil, 1092, 38, 109, + 108, 66, 67, 110, nil, 68, nil, 40, 262, nil, + 268, 52, 264, 263, nil, 260, 261, 281, 280, 266, + 24, 267, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, 1094, nil, nil, nil, 91, 101, + 241, 279, nil, nil, nil, nil, 85, nil, 92, 106, + 107, nil, nil, 46, 47, 335, 81, 82, 83, 11, + 65, nil, nil, nil, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, 1123, 23, 491, 490, 489, nil, 492, 10, 53, + 337, 12, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + 265, 269, 270, 271, 272, 282, 283, 277, 278, 273, + 274, nil, 258, 259, nil, nil, 275, 276, nil, 45, + nil, nil, 38, nil, nil, 66, 67, nil, nil, 68, + nil, 40, 262, nil, 268, 52, 264, 263, nil, 260, + 261, 281, 280, 266, 24, 267, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, 279, nil, nil, nil, nil, + 85, nil, 92, 106, 107, nil, nil, 46, 47, 335, + 81, 82, 83, 11, 65, nil, nil, nil, 71, 72, + nil, nil, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, nil, nil, nil, nil, nil, 84, 33, 32, + 115, 114, 116, 117, nil, 1123, 23, 491, 490, 489, + nil, 492, 10, 53, 337, 12, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, 265, 269, 270, 271, 272, 282, + 283, 277, 278, 273, 274, nil, 258, 259, nil, nil, + 275, 276, nil, 45, nil, nil, 38, nil, nil, 66, + 67, nil, nil, 68, nil, 40, 262, nil, 268, 52, + 264, 263, nil, 260, 261, 281, 280, 266, 24, 267, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, 279, + nil, nil, nil, nil, 85, nil, 92, 106, 107, nil, + nil, 46, 47, 335, 81, 82, 83, 11, 65, nil, + nil, nil, 71, 72, nil, nil, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 115, 114, 116, 117, nil, nil, + 23, nil, nil, nil, nil, nil, 10, 53, 337, 12, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, 265, 269, + 270, 271, 272, 282, 283, 277, 278, 273, 274, nil, + 258, 259, nil, nil, 275, 276, nil, 45, nil, nil, + 38, nil, nil, 66, 67, nil, nil, 68, nil, 40, + 262, nil, 268, 52, 264, 263, nil, 260, 261, 281, + 280, 266, 24, 267, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, 279, nil, nil, nil, nil, 85, nil, + 92, 106, 107, nil, nil, 46, 47, 335, 81, 82, + 83, 11, 65, nil, nil, nil, 71, 72, nil, nil, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 23, nil, nil, nil, nil, nil, + 10, 53, 337, 12, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, 265, 269, 270, 271, 272, 282, 283, 277, + 278, 273, 274, nil, 258, 259, nil, nil, 275, 276, + nil, 45, nil, nil, 339, nil, nil, 66, 67, nil, + nil, 68, nil, 40, 262, nil, 268, 52, 264, 263, + nil, 260, 261, 281, 280, 266, 24, 267, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, 279, nil, nil, + nil, nil, 85, nil, 92, 106, 107, nil, nil, 46, + 47, 335, 81, 82, 83, 11, 65, nil, nil, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 23, nil, + nil, nil, nil, nil, 10, 53, 337, 12, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, 265, 269, 270, 271, + 272, 282, 283, 277, 278, 273, 274, nil, 258, 259, + nil, nil, 275, 276, nil, 45, nil, nil, 339, nil, + nil, 66, 67, nil, nil, 68, nil, 40, 262, nil, + 268, 52, 264, 263, nil, 260, 261, 281, 280, 266, + 24, 267, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, 279, nil, nil, nil, nil, 85, nil, 92, 106, + 107, nil, nil, 46, 47, 335, 81, 82, 83, 11, + 65, nil, nil, nil, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 23, nil, nil, nil, nil, nil, 10, 53, + 337, 12, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + 265, 269, 270, 271, 272, 282, 283, 277, 278, 273, + 274, nil, 258, 259, nil, nil, 275, 276, nil, 45, + nil, nil, 38, nil, nil, 66, 67, nil, nil, 68, + nil, 40, 262, nil, 268, 52, 264, 263, nil, 260, + 261, 281, 280, 266, 24, 267, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, 279, nil, nil, nil, nil, + 85, nil, 92, 106, 107, nil, nil, 46, 47, 335, + 81, 82, 83, 11, 65, nil, nil, nil, 71, 72, + nil, nil, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, nil, nil, nil, nil, nil, 84, 33, 32, + 115, 114, 116, 117, nil, 494, 23, 491, 490, 489, + nil, 492, 10, 53, 337, 12, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, 494, nil, 491, 490, 489, nil, + 492, nil, 720, nil, 494, nil, 491, 490, 489, nil, + 492, 724, nil, 45, nil, nil, 38, nil, nil, 66, + 67, nil, nil, 68, 494, 40, 491, 490, 489, 52, + 492, 720, nil, nil, nil, nil, nil, nil, 24, nil, + 724, 720, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 720, nil, nil, 85, nil, 92, 106, 107, nil, + 724, 46, 47, 335, 81, 82, 83, 11, 65, nil, + nil, nil, 71, 72, nil, nil, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 115, 114, 116, 117, nil, nil, + 23, nil, nil, nil, nil, nil, 10, 53, 337, 12, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, 265, 269, + 270, 271, 272, 282, 283, 277, 278, 273, 274, nil, + -742, -742, nil, nil, 275, 276, nil, 45, nil, nil, + 38, nil, nil, 66, 67, nil, 265, 68, nil, 40, + 262, nil, 268, 52, 264, 263, nil, 260, 261, 281, + 280, 266, 24, 267, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, 262, nil, + 91, 101, 264, 263, nil, 260, 261, nil, 85, nil, + 92, 106, 107, nil, nil, 46, 47, 335, 81, 82, + 83, 11, 65, nil, nil, nil, 71, 72, nil, nil, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 23, nil, nil, nil, nil, nil, + 10, 53, 337, 12, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, 265, 269, 270, 271, 272, 282, 283, 277, + 278, 273, 274, nil, -742, -742, nil, nil, 275, 276, + nil, 45, nil, nil, 38, nil, nil, 66, 67, nil, + 265, 68, nil, 40, 262, nil, 268, 52, 264, 263, + nil, 260, 261, 281, 280, 266, 24, 267, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, 262, nil, 91, 101, 264, 263, nil, 260, + 261, nil, 85, nil, 92, 106, 107, nil, nil, 46, + 47, 335, 81, 82, 83, 11, 65, nil, nil, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 23, nil, + nil, nil, nil, nil, 10, 53, 337, 12, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, 265, 269, 270, 271, + 272, 282, 283, 277, 278, 273, 274, nil, -742, -742, + nil, nil, 275, 276, nil, 45, nil, nil, 38, nil, + nil, 66, 67, nil, nil, 68, nil, 40, 262, nil, + 268, 52, 264, 263, nil, 260, 261, 281, 280, 266, + 24, 267, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, 494, nil, 491, 490, 489, 85, 492, 92, 106, + 107, nil, nil, 46, 47, 335, 81, 82, 83, 11, + 65, nil, nil, nil, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, 720, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 23, nil, nil, nil, nil, nil, 10, 53, + 337, 12, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + 265, 269, 270, 271, 272, 282, 283, 277, 278, 273, + 274, nil, -742, -742, nil, nil, 275, 276, nil, 45, + nil, nil, 38, nil, nil, 66, 67, nil, nil, 68, + nil, 40, 262, nil, 268, 52, 264, 263, nil, 260, + 261, 281, 280, 266, 24, 267, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, 494, nil, 491, 490, 489, + 85, 492, 92, 106, 107, nil, nil, 46, 47, 335, + 81, 82, 83, 11, 65, nil, nil, nil, 71, 72, + nil, nil, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, 720, nil, nil, nil, nil, 84, 33, 32, + 115, 114, 116, 117, nil, nil, 23, nil, nil, nil, + nil, nil, 10, 53, 337, 12, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, 265, -742, -742, -742, -742, 282, + 283, nil, nil, -742, -742, nil, nil, nil, nil, nil, + 275, 276, nil, 45, nil, nil, 38, nil, nil, 66, + 67, nil, nil, 68, nil, 40, 262, nil, 268, 52, + 264, 263, nil, 260, 261, 281, 280, 266, 24, 267, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, nil, nil, nil, 85, nil, 92, 106, 107, nil, + nil, 46, 47, 335, 81, 82, 83, 11, 65, nil, + nil, nil, 71, 72, nil, nil, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 115, 114, 116, 117, nil, nil, + 23, nil, nil, nil, nil, nil, 10, 53, 337, 12, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, 265, -742, + -742, -742, -742, 282, 283, nil, nil, -742, -742, nil, + nil, nil, nil, nil, 275, 276, nil, 45, nil, nil, + 38, nil, nil, 66, 67, nil, nil, 68, nil, 40, + 262, nil, 268, 52, 264, 263, nil, 260, 261, 281, + 280, 266, 24, 267, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, nil, nil, nil, 85, nil, + 92, 106, 107, nil, nil, 46, 47, 335, 81, 82, + 83, 11, 65, nil, nil, nil, 71, 72, nil, nil, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 23, nil, nil, nil, nil, nil, + 10, 53, 337, 12, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, 265, -742, -742, -742, -742, 282, 283, nil, + nil, -742, -742, nil, nil, nil, nil, nil, 275, 276, + nil, 45, nil, nil, 38, nil, nil, 66, 67, nil, + nil, 68, nil, 40, 262, nil, 268, 52, 264, 263, + nil, 260, 261, 281, 280, 266, 24, 267, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, nil, + nil, nil, 85, nil, 92, 106, 107, nil, nil, 46, + 47, 335, 81, 82, 83, 11, 65, nil, nil, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 23, nil, + nil, nil, nil, nil, 10, 53, 337, 12, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, 265, -742, -742, -742, + -742, 282, 283, nil, nil, -742, -742, nil, nil, nil, + nil, nil, 275, 276, nil, 45, nil, nil, 38, nil, + nil, 66, 67, nil, nil, 68, nil, 40, 262, nil, + 268, 52, 264, 263, nil, 260, 261, 281, 280, 266, + 24, 267, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, nil, nil, nil, 85, nil, 92, 106, + 107, nil, nil, 46, 47, 335, 81, 82, 83, 11, + 65, nil, nil, nil, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 23, nil, nil, nil, nil, nil, 10, 53, + 337, 12, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + 265, -742, -742, -742, -742, 282, 283, nil, nil, -742, + -742, nil, nil, nil, nil, nil, 275, 276, nil, 45, + nil, nil, 38, nil, nil, 66, 67, nil, nil, 68, + nil, 40, 262, nil, 268, 52, 264, 263, nil, 260, + 261, 281, 280, 266, 24, 267, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, nil, nil, nil, + 85, nil, 92, 106, 107, nil, nil, 46, 47, 335, + 81, 82, 83, 11, 65, nil, nil, nil, 71, 72, + nil, nil, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, nil, nil, nil, nil, nil, 84, 33, 32, + 115, 114, 116, 117, nil, nil, 23, nil, nil, nil, + nil, nil, 10, 53, 337, 12, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, 265, -742, -742, -742, -742, 282, + 283, nil, nil, -742, -742, nil, nil, nil, nil, nil, + 275, 276, nil, 45, nil, nil, 38, nil, nil, 66, + 67, nil, nil, 68, nil, 40, 262, nil, 268, 52, + 264, 263, nil, 260, 261, 281, 280, 266, 24, 267, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, nil, nil, nil, 85, nil, 92, 106, 107, nil, + nil, 46, 47, 335, 81, 82, 83, 11, 65, nil, + nil, nil, 71, 72, nil, nil, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 115, 114, 116, 117, nil, nil, + 23, nil, nil, nil, nil, nil, 10, 53, 337, 12, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, 265, 269, + 270, 271, 272, 282, 283, nil, nil, 273, 274, nil, + nil, nil, nil, nil, 275, 276, nil, 45, nil, nil, + 38, nil, nil, 66, 67, nil, nil, 68, nil, 40, + 262, nil, 268, 52, 264, 263, nil, 260, 261, 281, + 280, 266, 24, 267, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, nil, nil, nil, 85, nil, + 92, 106, 107, nil, nil, 46, 47, 335, 81, 82, + 83, 11, 65, nil, nil, nil, 71, 72, nil, nil, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 23, nil, nil, nil, nil, nil, + 10, 53, 337, 12, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, 265, 269, 270, 271, 272, 282, 283, 277, + nil, 273, 274, nil, nil, nil, nil, nil, 275, 276, + nil, 45, nil, nil, 38, nil, nil, 66, 67, nil, + nil, 68, nil, 40, 262, nil, 268, 52, 264, 263, + nil, 260, 261, 281, 280, 266, 24, 267, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, nil, + nil, nil, 85, nil, 92, 106, 107, nil, nil, 46, + 47, 335, 81, 82, 83, 11, 65, nil, nil, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 23, nil, + nil, nil, nil, nil, 10, 53, 337, 12, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, 265, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 275, 276, nil, 45, nil, nil, 38, nil, + nil, 66, 67, nil, nil, 68, nil, 40, 262, nil, + 268, 52, 264, 263, nil, 260, 261, nil, nil, 266, + 24, 267, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, nil, nil, nil, 85, nil, 92, 106, + 107, nil, nil, 46, 47, 335, 81, 82, 83, 11, + 65, nil, nil, nil, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 23, nil, nil, nil, nil, nil, 10, 53, + 337, 12, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + 265, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 275, 276, nil, 45, + nil, nil, 38, nil, nil, 66, 67, nil, nil, 68, + nil, 40, 262, nil, 268, 52, 264, 263, nil, 260, + 261, nil, nil, 266, 24, 267, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, nil, nil, nil, + 85, nil, 92, 106, 107, nil, nil, 46, 47, 335, + 81, 82, 83, 11, 65, nil, nil, nil, 71, 72, + nil, nil, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, nil, nil, nil, nil, nil, 84, 33, 32, + 115, 114, 116, 117, nil, nil, 23, nil, nil, nil, + nil, nil, 10, 53, 337, 12, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, 265, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 275, 276, nil, 45, nil, nil, 38, nil, nil, 66, + 67, nil, nil, 68, nil, 40, 262, nil, 268, 52, + 264, 263, nil, 260, 261, nil, nil, nil, 24, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, nil, nil, nil, 85, nil, 92, 106, 107, nil, + nil, 46, 47, 335, 81, 82, 83, 11, 65, nil, + nil, nil, 71, 72, nil, nil, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 115, 114, 116, 117, nil, nil, + 23, nil, nil, nil, nil, nil, 10, 53, 337, 12, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, 265, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 275, 276, nil, 45, nil, nil, + 38, nil, nil, 66, 67, nil, nil, 68, nil, 40, + 262, nil, 268, 52, 264, 263, nil, 260, 261, nil, + nil, nil, 24, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, nil, nil, nil, 85, nil, + 92, 106, 107, nil, nil, 46, 47, 335, 81, 82, + 83, 11, 65, nil, nil, nil, 71, 72, nil, nil, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 23, nil, nil, nil, nil, nil, + 10, 53, 337, 12, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, 265, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 275, 276, + nil, 45, nil, nil, 38, nil, nil, 66, 67, nil, + nil, 68, nil, 40, 262, nil, nil, 52, 264, 263, + nil, 260, 261, nil, nil, nil, 24, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, nil, + nil, nil, 85, nil, 92, 106, 107, nil, nil, 46, + 47, 335, 81, 82, 83, 11, 65, nil, nil, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 23, nil, + nil, nil, nil, nil, 10, 53, 337, 12, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 38, nil, + nil, 66, 67, nil, nil, 68, nil, 40, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 24, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, nil, nil, nil, 85, nil, 92, 106, + 107, nil, nil, 46, 47, 81, 82, 83, 11, 65, + nil, nil, nil, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 115, 114, 116, 117, nil, + nil, 23, nil, nil, nil, nil, nil, 10, 53, 9, + 12, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 45, nil, + nil, 38, nil, nil, 66, 67, nil, nil, 68, nil, + 40, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 24, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, nil, nil, nil, + 85, nil, 92, 106, 107, -441, nil, 46, 47, nil, + nil, nil, -441, -441, -441, nil, nil, -441, -441, -441, + nil, -441, nil, nil, nil, nil, nil, nil, nil, -441, + -441, -441, -441, nil, nil, nil, nil, nil, nil, nil, + nil, -441, -441, nil, -441, -441, -441, -441, -441, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, -441, -441, -441, -441, -441, -441, -441, -441, -441, + -441, -441, -441, -441, -441, nil, nil, -441, -441, -441, + nil, nil, -441, nil, 307, -441, nil, nil, -441, -441, + nil, -441, nil, -441, nil, -441, nil, -441, -441, nil, + -441, -441, -441, -441, -441, -328, -441, -441, -441, nil, + nil, nil, -328, -328, -328, nil, nil, -328, -328, -328, + nil, -328, -441, nil, nil, -441, -441, nil, -441, -328, + -441, -328, -328, nil, nil, nil, nil, -441, nil, nil, + nil, -328, -328, nil, -328, -328, -328, -328, -328, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, -328, -328, -328, -328, -328, -328, -328, -328, -328, + -328, -328, -328, -328, -328, nil, nil, -328, -328, -328, + nil, nil, -328, nil, 316, -328, nil, nil, -328, -328, + nil, -328, nil, -328, nil, -328, nil, -328, -328, nil, + -328, -328, -328, -328, -328, nil, -328, nil, -328, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, -328, nil, nil, -328, -328, nil, -328, nil, + -328, 81, 82, 83, nil, 65, nil, -328, nil, 71, + 72, nil, nil, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, nil, nil, nil, nil, nil, 84, 33, + 32, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, 329, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, 326, nil, 323, nil, + 52, nil, nil, 330, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 327, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, 329, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, 326, nil, 323, + nil, 52, nil, nil, 330, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 327, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, 329, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, 326, nil, + 323, nil, 52, nil, nil, 330, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 327, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 356, 357, 79, 80, nil, nil, nil, nil, + nil, 84, 351, 359, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 356, 357, 79, 80, nil, nil, nil, + nil, nil, 84, 351, 359, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 356, 357, 79, 80, nil, nil, + nil, nil, nil, 84, 351, 359, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 356, 357, 79, 80, nil, + nil, nil, nil, nil, 84, 351, 359, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 356, 357, 79, 80, + nil, nil, nil, nil, nil, 84, 351, 359, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, nil, + nil, nil, 85, nil, 92, 106, 107, -315, nil, 46, + 47, nil, nil, nil, -315, -315, -315, nil, nil, -315, + -315, -315, nil, -315, nil, nil, nil, nil, nil, nil, + nil, -315, nil, -315, -315, -315, nil, nil, nil, nil, + nil, nil, nil, -315, -315, nil, -315, -315, -315, -315, + -315, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, -315, -315, -315, -315, -315, -315, -315, + -315, -315, -315, -315, -315, -315, -315, nil, nil, -315, + -315, -315, nil, nil, -315, nil, nil, -315, nil, nil, + -315, -315, nil, -315, nil, -315, nil, -315, nil, -315, + -315, nil, -315, -315, -315, -315, -315, nil, -315, nil, + -315, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, -315, nil, nil, -315, -315, -315, + -315, nil, -315, nil, -315, nil, 81, 82, 83, -315, + 65, nil, nil, nil, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 356, 357, 79, 80, nil, nil, + nil, nil, nil, 84, 351, 359, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + 329, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, 326, nil, nil, nil, 52, nil, nil, 330, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 327, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 356, 357, 79, 80, nil, + nil, nil, nil, nil, 84, 351, 359, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, 329, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, 330, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 327, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 23, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 24, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 23, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 24, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, nil, nil, nil, nil, nil, 84, 33, 32, + 115, 114, 116, 117, nil, nil, 23, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 24, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, 127, nil, + nil, nil, nil, 126, 85, nil, 92, 106, 107, nil, + nil, 46, 47, 81, 82, 83, 11, 65, nil, nil, + nil, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 115, 114, 116, 117, nil, nil, 23, + nil, nil, nil, nil, nil, 10, 53, 9, 12, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 38, + nil, nil, 66, 67, nil, nil, 68, nil, 40, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 24, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, nil, nil, 421, 85, nil, 92, + 106, 107, nil, nil, 46, 47, 81, 82, 83, nil, + 65, nil, nil, nil, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 23, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 24, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 35, 36, 79, 80, nil, + nil, nil, nil, nil, 84, 33, 32, 115, 114, 116, + 117, nil, nil, 23, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 24, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 23, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 24, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 23, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 24, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + nil, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 46, 47, 81, 82, 83, 11, 65, nil, nil, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 23, nil, + nil, nil, nil, nil, 10, 53, nil, 12, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 45, nil, nil, 38, nil, + nil, 66, 67, nil, nil, 68, nil, 40, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 24, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, 438, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, 438, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 115, 114, 116, 117, nil, + nil, 23, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 24, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 23, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 24, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 35, 36, 79, 80, nil, + nil, nil, nil, nil, 84, 33, 32, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, 329, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, 326, nil, 323, nil, 52, nil, nil, + 330, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 327, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, nil, nil, nil, nil, nil, 84, 33, 32, + 115, 114, 116, 117, nil, nil, 23, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 24, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, nil, nil, nil, nil, nil, 84, 33, + 32, 115, 114, 116, 117, nil, nil, 23, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 24, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, 241, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 356, 357, 79, 80, nil, nil, nil, nil, nil, 84, + 351, 359, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 356, 357, 79, 80, nil, nil, nil, nil, nil, + 84, 351, 359, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 356, 357, 79, 80, nil, nil, nil, nil, + nil, 84, 351, 359, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 356, 357, 79, 80, nil, nil, nil, + nil, nil, 84, 351, 359, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 356, 357, 79, 80, nil, nil, + nil, nil, nil, 84, 351, 359, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 356, 357, 79, 80, nil, + nil, nil, nil, nil, 84, 351, 359, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 356, 357, 79, 80, + nil, nil, nil, nil, nil, 84, 351, 359, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 356, 357, 79, + 80, nil, nil, nil, nil, nil, 84, 351, 359, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 356, 357, + 79, 80, nil, nil, nil, nil, nil, 84, 351, 359, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 356, + 357, 79, 80, nil, nil, nil, nil, nil, 84, 351, + 359, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 356, 357, 79, 80, nil, nil, nil, nil, nil, 84, + 351, 359, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 356, 357, 79, 80, nil, nil, nil, nil, nil, + 84, 351, 359, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 356, 357, 79, 80, nil, nil, nil, nil, + nil, 84, 351, 359, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 356, 357, 79, 80, nil, nil, nil, + nil, nil, 84, 351, 359, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 356, 357, 79, 80, nil, nil, + nil, nil, nil, 84, 351, 359, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 356, 357, 79, 80, nil, + nil, nil, nil, nil, 84, 351, 359, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 356, 357, 79, 80, + nil, nil, nil, nil, nil, 84, 351, 359, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 356, 357, 79, + 80, nil, nil, nil, nil, nil, 84, 351, 359, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 356, 357, + 79, 80, nil, nil, nil, nil, nil, 84, 351, 359, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 356, + 357, 79, 80, nil, nil, nil, nil, nil, 84, 351, + 359, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 356, 357, 79, 80, nil, nil, nil, nil, nil, 84, + 351, 359, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 356, 357, 79, 80, nil, nil, nil, nil, nil, + 84, 351, 359, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 356, 357, 79, 80, nil, nil, nil, nil, + nil, 84, 351, 359, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 356, 357, 79, 80, nil, nil, nil, + nil, nil, 84, 351, 359, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 23, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 24, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 35, 36, 79, 80, nil, + nil, nil, nil, nil, 84, 33, 32, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, 329, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, 326, nil, 323, nil, 52, nil, nil, 330, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 327, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 564, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, 329, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, 326, nil, 323, nil, 52, nil, nil, + 330, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 327, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, 329, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, 326, nil, 323, nil, 52, nil, + nil, 330, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 327, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, 241, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 356, 357, + 79, 80, nil, nil, nil, nil, nil, 84, 351, 359, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 356, + 357, 79, 80, nil, nil, nil, nil, nil, 84, 351, + 359, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 356, 357, 79, 80, nil, nil, nil, nil, nil, 84, + 351, 359, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 356, 357, 79, 80, nil, nil, nil, nil, nil, + 84, 351, 359, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, nil, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 46, 47, 81, 82, 83, 11, + 65, nil, nil, nil, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 23, nil, nil, nil, nil, nil, 10, 53, + nil, 12, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 45, + nil, nil, 38, nil, nil, 66, 67, nil, nil, 68, + nil, 40, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 24, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 356, 357, 79, 80, nil, + nil, nil, nil, nil, 84, 351, 359, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 23, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 24, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 23, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 24, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 356, 357, + 79, 80, nil, nil, nil, nil, nil, 84, 351, 359, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, nil, nil, nil, 85, nil, 92, 106, 107, -276, + nil, 46, 47, nil, nil, nil, -276, -276, -276, nil, + nil, -276, -276, -276, nil, -276, nil, nil, nil, nil, + nil, nil, nil, -276, -276, -276, -276, nil, nil, nil, + nil, nil, nil, nil, nil, -276, -276, nil, -276, -276, + -276, -276, -276, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, -276, -276, -276, -276, -276, + -276, -276, -276, -276, -276, -276, -276, -276, -276, nil, + nil, -276, -276, -276, nil, nil, -276, nil, 307, -276, + nil, nil, -276, -276, nil, -276, nil, -276, nil, -276, + nil, -276, -276, nil, -276, -276, -276, -276, -276, nil, + -276, -276, -276, 494, nil, 491, 490, 489, 499, 492, + nil, nil, nil, nil, nil, nil, -276, nil, 502, -276, + -276, -722, -276, nil, -276, nil, nil, nil, -722, -722, + -722, -276, nil, -722, -722, -722, nil, -722, nil, nil, + 497, nil, nil, nil, nil, -722, -722, -722, -722, -722, + nil, 510, 509, nil, nil, nil, 503, -722, -722, nil, + -722, -722, -722, -722, -722, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, -722, -722, -722, + -722, -722, -722, -722, -722, -722, -722, -722, -722, -722, + -722, nil, nil, -722, -722, -722, nil, nil, -722, nil, + nil, -722, nil, nil, -722, -722, nil, -722, nil, -722, + nil, -722, nil, -722, -722, nil, -722, -722, -722, -722, + -722, nil, -722, -722, -722, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, -722, nil, + nil, -722, -722, -722, -722, nil, -722, -723, -722, nil, + nil, nil, nil, -722, -723, -723, -723, nil, nil, -723, + -723, -723, nil, -723, nil, nil, nil, nil, nil, nil, + nil, -723, -723, -723, -723, -723, nil, nil, nil, nil, + nil, nil, nil, -723, -723, nil, -723, -723, -723, -723, + -723, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, -723, -723, -723, -723, -723, -723, -723, + -723, -723, -723, -723, -723, -723, -723, nil, nil, -723, + -723, -723, nil, nil, -723, nil, nil, -723, nil, nil, + -723, -723, nil, -723, nil, -723, nil, -723, nil, -723, + -723, nil, -723, -723, -723, -723, -723, nil, -723, -723, + -723, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, -723, nil, nil, -723, -723, -723, + -723, nil, -723, nil, -723, nil, 81, 82, 83, -723, + 65, nil, nil, nil, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 698, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 356, 357, 79, 80, nil, + nil, nil, nil, nil, 84, 351, 359, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 698, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, 329, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, 326, nil, 323, nil, 52, nil, + nil, 330, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 327, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 356, 357, + 79, 80, nil, nil, nil, nil, nil, 84, 351, 359, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 356, + 357, 79, 80, nil, nil, nil, nil, nil, 84, 351, + 359, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 356, 357, 79, 80, nil, nil, nil, nil, nil, 84, + 351, 359, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, nil, nil, nil, 85, nil, 92, 106, + 107, -276, nil, 46, 47, nil, nil, nil, -276, -276, + -276, nil, nil, -276, -276, -276, 494, -276, 491, 490, + 489, 499, 492, nil, nil, -276, -276, -276, nil, nil, + nil, 502, nil, nil, nil, nil, nil, -276, -276, nil, + -276, -276, -276, -276, -276, nil, 494, nil, 491, 490, + 489, 499, 492, 497, nil, nil, nil, nil, nil, nil, + nil, 502, 507, 506, 510, 509, nil, nil, nil, 503, + nil, 494, nil, 491, 490, 489, 499, 492, -276, nil, + nil, nil, nil, 497, 648, -276, 502, nil, nil, nil, + 307, -276, 507, 506, 510, 509, nil, nil, nil, 503, + nil, nil, nil, nil, nil, nil, nil, nil, 497, 488, + nil, nil, nil, -276, -276, nil, nil, 507, 506, 510, + 509, nil, nil, nil, 503, nil, nil, nil, -276, nil, + nil, -276, nil, 81, 82, 83, -276, 65, nil, 488, + nil, 71, 72, -276, nil, nil, 75, nil, 73, 74, + 76, 356, 357, 79, 80, nil, nil, nil, nil, nil, + 84, 351, 359, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 356, 357, 79, 80, nil, nil, nil, nil, + nil, 84, 351, 359, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, 329, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, 326, + nil, 323, nil, 52, nil, nil, 330, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 327, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 356, 357, 79, 80, nil, nil, nil, + nil, nil, 84, 351, 359, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, 329, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, 323, nil, 52, nil, nil, 330, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 327, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 356, 357, 79, 80, nil, nil, + nil, nil, nil, 84, 351, 359, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, nil, nil, nil, + 85, nil, 92, 106, 107, nil, nil, 46, 47, 81, + 82, 83, 11, 65, nil, nil, nil, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 23, nil, nil, nil, nil, + nil, 10, 53, 337, 12, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 38, nil, nil, 66, 67, + nil, nil, 68, nil, 40, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 24, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + nil, nil, 421, 85, nil, 92, 106, 107, nil, nil, + 46, 47, 81, 82, 83, nil, 65, nil, nil, nil, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, 329, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, 326, nil, 323, + nil, 52, nil, nil, 330, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 327, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 356, 357, 79, 80, nil, nil, nil, nil, nil, + 84, 351, 359, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 356, 357, 79, 80, nil, nil, nil, nil, + nil, 84, 351, 359, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 356, 357, 79, 80, nil, nil, nil, + nil, nil, 84, 351, 359, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 356, 357, 79, 80, nil, nil, + nil, nil, nil, 84, 351, 359, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + 329, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, 326, nil, nil, nil, 52, nil, nil, 330, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 327, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 356, 357, 79, 80, nil, + nil, nil, nil, nil, 84, 351, 359, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, 329, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, 330, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 327, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 356, 357, 79, 80, + nil, nil, nil, nil, nil, 84, 351, 359, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, 326, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, 329, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, 326, nil, 323, nil, 52, nil, + nil, 330, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 327, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, nil, nil, nil, nil, nil, 84, 33, 32, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, 329, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, 326, nil, 323, nil, 52, + nil, nil, 330, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 327, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, nil, nil, nil, 85, nil, 92, 106, 107, nil, + nil, 46, 47, 81, 82, 83, 11, 65, nil, nil, + nil, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 115, 114, 116, 117, nil, nil, 23, + nil, nil, nil, nil, nil, 10, 53, nil, 12, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 45, nil, nil, 38, + nil, nil, 66, 67, nil, nil, 68, nil, 40, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 24, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 356, 357, 79, 80, nil, nil, nil, nil, + nil, 84, 351, 359, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, 832, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + 329, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, 326, nil, 323, nil, 52, nil, nil, 330, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 327, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, nil, nil, nil, + 85, nil, 92, 106, 107, nil, nil, 46, 47, 81, + 82, 83, 11, 65, nil, nil, nil, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 35, 36, 79, + 80, nil, nil, nil, nil, nil, 84, 33, 32, 115, + 114, 116, 117, nil, nil, 23, nil, nil, nil, nil, + nil, 10, 53, nil, 12, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 45, nil, nil, 38, nil, nil, 66, 67, + nil, nil, 68, nil, 40, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 24, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 356, 357, + 79, 80, nil, nil, nil, nil, nil, 84, 351, 359, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 356, + 357, 79, 80, nil, nil, nil, nil, nil, 84, 351, + 359, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, 329, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, 326, nil, 323, nil, + 52, nil, nil, 330, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 327, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 356, 357, 79, 80, nil, nil, nil, nil, nil, 84, + 351, 359, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, 329, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, 323, + nil, 52, nil, nil, 330, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 327, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 356, 357, 79, 80, nil, + nil, nil, nil, nil, 84, 351, 359, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, 438, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 356, 357, 79, 80, + nil, nil, nil, nil, nil, 84, 351, 359, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 356, 357, 79, + 80, nil, nil, nil, nil, nil, 84, 351, 359, 115, + 114, 116, 117, nil, nil, 889, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 356, 357, + 79, 80, nil, nil, nil, nil, nil, 84, 351, 359, + 115, 114, 116, 117, nil, nil, 889, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 356, + 357, 79, 80, nil, nil, nil, nil, nil, 84, 351, + 359, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, 329, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, 326, nil, 323, nil, + 52, nil, nil, 330, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 327, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 564, nil, 75, nil, 73, 74, 76, + 356, 357, 79, 80, nil, nil, nil, nil, nil, 84, + 351, 359, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 115, 114, 116, 117, nil, nil, 23, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 24, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 35, 36, 79, 80, nil, nil, nil, nil, + nil, 84, 33, 32, 115, 114, 116, 117, nil, nil, + 23, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 24, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 356, 357, 79, 80, nil, nil, nil, + nil, nil, 84, 351, 359, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 35, 36, 79, 80, nil, nil, + nil, nil, nil, 84, 33, 32, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 356, 357, 79, 80, nil, + nil, nil, nil, nil, 84, 351, 359, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 35, 36, 79, 80, + nil, nil, nil, nil, nil, 84, 33, 32, 115, 114, + 116, 117, nil, nil, 698, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 356, 357, 79, + 80, nil, nil, nil, nil, nil, 84, 351, 359, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 356, 357, + 79, 80, nil, nil, nil, nil, nil, 84, 351, 359, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 251, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 356, + 357, 79, 80, nil, nil, nil, nil, nil, 84, 351, + 359, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + 52, nil, nil, nil, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 356, 357, 79, 80, nil, nil, nil, nil, nil, 84, + 351, 359, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 356, 357, 79, 80, nil, nil, nil, nil, nil, + 84, 351, 359, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 356, 357, 79, 80, nil, nil, nil, nil, + nil, 84, 351, 359, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 53, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, 49, 50, 48, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 246, nil, nil, + 254, nil, nil, 66, 67, nil, nil, 68, nil, nil, + nil, nil, nil, 52, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, 46, 47, nil, 75, nil, + 73, 74, 76, 35, 36, 79, 80, nil, nil, nil, + nil, nil, 84, 33, 32, 115, 114, 116, 117, nil, + nil, 23, nil, nil, nil, nil, nil, nil, 53, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, 49, 50, 48, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 246, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, nil, + nil, nil, nil, 24, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, 46, 47, nil, 75, + nil, 73, 74, 76, 356, 357, 79, 80, nil, nil, + nil, nil, nil, 84, 351, 359, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 53, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, 49, 50, 48, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 246, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, 326, nil, nil, nil, 52, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, 46, 47, nil, + 75, nil, 73, 74, 76, 356, 357, 79, 80, nil, + nil, nil, nil, nil, 84, 351, 359, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 53, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, 329, 110, 121, 122, nil, 104, 105, 49, 50, + 48, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 246, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, 323, nil, 52, nil, nil, 330, + nil, nil, nil, nil, nil, 251, nil, nil, nil, nil, + 102, 327, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, 46, 47, + nil, 75, nil, 73, 74, 76, 356, 357, 79, 80, + nil, nil, nil, nil, nil, 84, 351, 359, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 53, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, 49, + 50, 48, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 254, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, 46, + 47, nil, 75, nil, 73, 74, 76, 356, 357, 79, + 80, nil, nil, nil, nil, nil, 84, 351, 359, 115, + 114, 116, 117, nil, nil, 889, nil, nil, nil, nil, + nil, nil, 53, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + 49, 50, 48, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 246, nil, nil, 254, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, 52, nil, + nil, nil, nil, nil, nil, nil, nil, 251, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + 46, 47, nil, 75, nil, 73, 74, 76, 35, 36, + 79, 80, nil, nil, nil, nil, nil, 84, 33, 32, + 115, 114, 116, 117, nil, nil, 23, nil, nil, nil, + nil, nil, nil, 53, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, 49, 50, 48, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 246, nil, nil, 254, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, 52, + nil, nil, nil, nil, nil, nil, nil, nil, 24, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, 46, 47, nil, 75, nil, 73, 74, 76, 35, + 36, 79, 80, nil, nil, nil, nil, nil, 84, 33, + 32, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 53, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, 329, 110, 121, 122, nil, + 104, 105, 49, 50, 48, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 246, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, 326, nil, 323, nil, + 52, nil, nil, 330, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, 102, 327, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, 46, 47, nil, 75, nil, 73, 74, 76, + 35, 36, 79, 80, nil, nil, nil, nil, nil, 84, + 33, 32, 115, 114, 116, 117, nil, nil, 23, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, 49, 50, 48, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, 52, nil, nil, nil, nil, nil, nil, nil, nil, + 24, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, 46, 47, nil, 75, nil, 73, 74, + 76, 35, 36, 79, 80, nil, nil, nil, nil, nil, + 84, 33, 32, 115, 114, 116, 117, nil, nil, 23, + nil, nil, nil, nil, nil, nil, 53, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, 49, 50, 48, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 246, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, 52, nil, nil, nil, nil, nil, nil, nil, + nil, 24, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, 81, 82, 83, 85, 65, 92, + 106, 107, 71, 72, 46, 47, nil, 75, nil, 73, + 74, 76, 356, 357, 79, 80, nil, nil, nil, nil, + nil, 84, 351, 359, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 352, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, nil, nil, 360, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 348, nil, nil, + 344, nil, nil, 66, 67, nil, nil, 68, nil, 343, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 356, 357, 79, 80, nil, nil, nil, + nil, nil, 84, 351, 359, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 352, nil, + nil, 119, 118, 120, 111, 64, 109, 108, 112, nil, + 110, 121, 122, nil, 104, 105, nil, nil, 360, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 348, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, 494, nil, 491, 490, 489, 499, 492, nil, nil, + nil, nil, nil, nil, nil, nil, 502, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 362, nil, 497, 85, + nil, 92, 106, 107, 81, 82, 83, nil, 65, 510, + 509, nil, 71, 72, 503, nil, nil, 75, nil, 73, + 74, 76, 356, 357, 79, 80, nil, nil, nil, nil, + nil, 84, 351, 359, 115, 114, 116, 117, nil, nil, + 255, nil, nil, nil, nil, nil, nil, 352, nil, nil, + 119, 118, 120, 111, 64, 109, 108, 112, nil, 110, + 121, 122, nil, 104, 105, nil, nil, 360, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 396, nil, nil, + 38, nil, nil, 66, 67, nil, nil, 68, nil, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, nil, nil, nil, 81, 82, 83, 85, 65, + 92, 106, 107, 71, 72, nil, nil, nil, 75, nil, + 73, 74, 76, 356, 357, 79, 80, nil, nil, nil, + nil, nil, 84, 351, 359, 115, 114, 116, 117, nil, + nil, 255, nil, nil, nil, nil, nil, nil, 352, nil, + nil, 119, 118, 120, 401, 64, 109, 108, 402, nil, + 110, 121, 122, nil, 104, 105, nil, nil, 360, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 408, nil, nil, 403, nil, + nil, 254, nil, nil, 66, 67, nil, nil, 68, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, nil, nil, nil, 81, 82, 83, 85, + 65, 92, 106, 107, 71, 72, nil, nil, nil, 75, + nil, 73, 74, 76, 356, 357, 79, 80, nil, nil, + nil, nil, nil, 84, 351, 359, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 352, + nil, nil, 119, 118, 120, 401, 64, 109, 108, 402, + nil, 110, 121, 122, nil, 104, 105, nil, nil, 360, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 403, + nil, nil, 254, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, nil, nil, nil, + 75, nil, 73, 74, 76, 356, 357, 79, 80, nil, + nil, nil, nil, nil, 84, 351, 359, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 352, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, nil, nil, + 360, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 348, nil, nil, 254, nil, nil, 66, 67, nil, nil, + 68, nil, nil, 494, nil, 491, 490, 489, 499, 492, + nil, nil, nil, nil, nil, nil, nil, nil, 502, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 592, nil, + 497, 85, nil, 92, 106, 107, 81, 82, 83, nil, + 65, 510, 509, nil, 71, 72, 503, nil, nil, 75, + nil, 73, 74, 76, 356, 357, 79, 80, nil, nil, + nil, nil, nil, 84, 351, 359, 115, 114, 116, 117, + nil, nil, 255, nil, nil, nil, nil, nil, nil, 352, + nil, nil, 119, 118, 120, 111, 64, 109, 108, 112, + nil, 110, 121, 122, nil, 104, 105, nil, nil, 360, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 348, + nil, nil, 344, nil, nil, 66, 67, nil, nil, 68, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 102, + 90, 93, 94, nil, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, nil, nil, nil, 81, 82, 83, + 85, 65, 92, 106, 107, 71, 72, nil, nil, nil, + 75, nil, 73, 74, 76, 356, 357, 79, 80, nil, + nil, nil, nil, nil, 84, 351, 359, 115, 114, 116, + 117, nil, nil, 255, nil, nil, nil, nil, nil, nil, + 352, nil, nil, 119, 118, 120, 111, 64, 109, 108, + 112, nil, 110, 121, 122, nil, 104, 105, nil, nil, + 360, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 348, nil, nil, 344, nil, nil, 66, 67, nil, nil, + 68, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, nil, nil, nil, 81, 82, + 83, 85, 65, 92, 106, 107, 71, 72, nil, nil, + nil, 75, nil, 73, 74, 76, 356, 357, 79, 80, + nil, nil, nil, nil, nil, 84, 351, 359, 115, 114, + 116, 117, nil, nil, 255, nil, nil, nil, nil, nil, + nil, 352, nil, nil, 119, 118, 120, 111, 64, 109, + 108, 112, nil, 110, 121, 122, nil, 104, 105, nil, + nil, 360, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 348, nil, nil, 344, nil, nil, 66, 67, nil, + nil, 68, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 102, 90, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, nil, nil, nil, 81, + 82, 83, 85, 65, 92, 106, 107, 71, 72, nil, + nil, nil, 75, nil, 73, 74, 76, 356, 357, 79, + 80, nil, nil, nil, nil, nil, 84, 351, 359, 115, + 114, 116, 117, nil, nil, 255, nil, nil, nil, nil, + nil, nil, 352, nil, nil, 119, 118, 120, 111, 64, + 109, 108, 112, nil, 110, 121, 122, nil, 104, 105, + nil, nil, 360, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 348, nil, nil, 344, nil, nil, 66, 67, + nil, nil, 68, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 102, 90, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, nil, nil, nil, + 81, 82, 83, 85, 65, 92, 106, 107, 71, 72, + nil, nil, nil, 75, nil, 73, 74, 76, 356, 357, + 79, 80, nil, nil, nil, nil, nil, 84, 351, 359, + 115, 114, 116, 117, nil, nil, 255, nil, nil, nil, + nil, nil, nil, 352, nil, nil, 119, 118, 120, 111, + 64, 109, 108, 112, nil, 110, 121, 122, nil, 104, + 105, nil, nil, 360, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 348, nil, nil, 344, nil, nil, 66, + 67, nil, nil, 68, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, 81, 82, 83, 85, 65, 92, 106, 107, 71, + 72, nil, nil, nil, 75, nil, 73, 74, 76, 356, + 357, 79, 80, nil, nil, nil, nil, nil, 84, 351, + 359, 115, 114, 116, 117, nil, nil, 255, nil, nil, + nil, nil, nil, nil, 352, nil, nil, 119, 118, 120, + 111, 64, 109, 108, 112, nil, 110, 121, 122, nil, + 104, 105, nil, nil, 360, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1054, nil, nil, 254, nil, nil, + 66, 67, nil, nil, 68, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, 81, 82, 83, 85, 65, 92, 106, 107, + 71, 72, nil, nil, nil, 75, nil, 73, 74, 76, + 356, 357, 79, 80, nil, nil, nil, nil, nil, 84, + 351, 359, 115, 114, 116, 117, nil, nil, 255, nil, + nil, nil, nil, nil, nil, 352, nil, nil, 119, 118, + 120, 111, 64, 109, 108, 112, nil, 110, 121, 122, + nil, 104, 105, nil, nil, 360, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 1112, nil, nil, 254, nil, + nil, 66, 67, nil, nil, 68, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, 81, 82, 83, 85, 65, 92, 106, + 107, 71, 72, nil, nil, nil, 75, nil, 73, 74, + 76, 356, 357, 79, 80, nil, nil, nil, nil, nil, + 84, 351, 359, 115, 114, 116, 117, nil, nil, 255, + nil, nil, nil, nil, nil, nil, 352, nil, nil, 119, + 118, 120, 111, 64, 109, 108, 112, nil, 110, 121, + 122, nil, 104, 105, nil, nil, 360, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1112, nil, nil, 254, + nil, nil, 66, 67, nil, nil, 68, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, nil, nil, nil, nil, nil, nil, 85, nil, 92, + 106, 107, 186, 197, 187, 210, 183, 203, 193, 192, + 213, 214, 208, 191, 190, 185, 211, 215, 216, 195, + 184, 198, 202, 204, 196, 189, nil, nil, nil, 205, + 212, 207, 206, 199, 209, 194, 182, 201, 200, nil, + nil, nil, nil, nil, 181, 188, 179, 180, 176, 177, + 178, 139, 141, 138, nil, 140, nil, nil, nil, nil, + nil, nil, nil, 170, 171, nil, 167, 149, 150, 151, + 158, 155, 157, nil, nil, 152, 153, nil, nil, nil, + 172, 173, 159, 160, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 164, 163, nil, + 148, 169, 166, 165, 174, 161, 162, 156, 154, 146, + 168, 147, nil, nil, 175, 102, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 101, + 186, 197, 187, 210, 183, 203, 193, 192, 213, 214, + 208, 191, 190, 185, 211, 215, 216, 195, 184, 198, + 202, 204, 196, 189, nil, nil, nil, 205, 212, 207, + 206, 199, 209, 194, 182, 201, 200, nil, nil, nil, + nil, nil, 181, 188, 179, 180, 176, 177, 178, 139, + 141, nil, nil, 140, nil, nil, nil, nil, nil, nil, + nil, 170, 171, nil, 167, 149, 150, 151, 158, 155, + 157, nil, nil, 152, 153, nil, nil, nil, 172, 173, + 159, 160, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 164, 163, nil, 148, 169, + 166, 165, 174, 161, 162, 156, 154, 146, 168, 147, + nil, nil, 175, 102, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 101, 186, 197, + 187, 210, 183, 203, 193, 192, 213, 214, 208, 191, + 190, 185, 211, 215, 216, 195, 184, 198, 202, 204, + 196, 189, nil, nil, nil, 205, 212, 207, 206, 199, + 209, 194, 182, 201, 200, nil, nil, nil, nil, nil, + 181, 188, 179, 180, 176, 177, 178, 139, 141, nil, + nil, 140, nil, nil, nil, nil, nil, nil, nil, 170, + 171, nil, 167, 149, 150, 151, 158, 155, 157, nil, + nil, 152, 153, nil, nil, nil, 172, 173, 159, 160, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 164, 163, nil, 148, 169, 166, 165, + 174, 161, 162, 156, 154, 146, 168, 147, nil, nil, + 175, 102, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 101, 186, 197, 187, 210, + 183, 203, 193, 192, 213, 214, 208, 191, 190, 185, + 211, 215, 216, 195, 184, 198, 202, 204, 196, 189, + nil, nil, nil, 205, 212, 207, 206, 199, 209, 194, + 182, 201, 200, nil, nil, nil, nil, nil, 181, 188, + 179, 180, 176, 177, 178, 139, 141, nil, nil, 140, + nil, nil, nil, nil, nil, nil, nil, 170, 171, nil, + 167, 149, 150, 151, 158, 155, 157, nil, nil, 152, + 153, nil, nil, nil, 172, 173, 159, 160, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 164, 163, nil, 148, 169, 166, 165, 174, 161, + 162, 156, 154, 146, 168, 147, nil, nil, 175, 102, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 101, 186, 197, 187, 210, 183, 203, + 193, 192, 213, 214, 208, 191, 190, 185, 211, 215, + 216, 195, 184, 198, 202, 204, 196, 189, nil, nil, + nil, 205, 212, 207, 295, 294, 296, 293, 182, 201, + 200, nil, nil, nil, nil, nil, 181, 188, 179, 180, + 290, 291, 292, 288, 141, 109, 108, 289, nil, 110, + nil, nil, nil, nil, nil, 170, 171, nil, 167, 149, + 150, 151, 158, 155, 157, nil, nil, 152, 153, nil, + nil, nil, 172, 173, 159, 160, nil, nil, nil, nil, + nil, 300, nil, nil, nil, nil, nil, nil, nil, 164, + 163, nil, 148, 169, 166, 165, 174, 161, 162, 156, + 154, 146, 168, 147, nil, nil, 175, 186, 197, 187, + 210, 183, 203, 193, 192, 213, 214, 208, 191, 190, + 185, 211, 215, 216, 195, 184, 198, 202, 204, 196, + 189, nil, nil, nil, 205, 212, 207, 206, 199, 209, + 194, 182, 201, 200, nil, nil, nil, nil, nil, 181, + 188, 179, 180, 176, 177, 178, 139, 141, nil, nil, + 140, nil, nil, nil, nil, nil, nil, nil, 170, 171, + nil, 167, 149, 150, 151, 158, 155, 157, nil, nil, + 152, 153, nil, nil, nil, 172, 173, 159, 160, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 164, 163, nil, 148, 169, 166, 165, 174, + 161, 162, 156, 154, 146, 168, 147, nil, nil, 175, + 115, 114, 116, 117, nil, nil, 494, nil, 491, 490, + 489, 499, 492, nil, nil, nil, 119, 118, 120, 1009, + nil, 502, nil, 1012, 989, nil, nil, nil, nil, 104, + 105, nil, nil, 360, 502, nil, nil, nil, nil, nil, + nil, nil, nil, 497, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 1011, 510, 509, 982, nil, nil, 503, + 980, nil, nil, 981, nil, 984, nil, nil, nil, nil, + nil, nil, 503, nil, nil, nil, nil, nil, nil, 1010, + nil, nil, nil, 102, 990, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, 115, 114, + 116, 117, nil, nil, 85, nil, 92, 106, 107, nil, + nil, 997, 998, nil, 119, 118, 120, 1009, nil, nil, + nil, 1012, 989, nil, nil, nil, nil, 104, 105, nil, + nil, 360, 502, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 1011, nil, nil, 982, nil, nil, nil, 980, nil, + nil, 981, nil, 984, nil, nil, nil, nil, nil, nil, + 503, nil, nil, nil, nil, nil, nil, 1010, nil, nil, + nil, 102, 990, 93, 94, nil, 95, 97, 96, 98, + nil, nil, nil, nil, 91, 101, 115, 114, 116, 117, + nil, nil, 85, nil, 92, 106, 107, nil, nil, 997, + 998, nil, 119, 118, 120, 1009, nil, nil, nil, 1012, + nil, nil, nil, nil, nil, 104, 105, nil, nil, 360, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 1011, + nil, nil, 982, nil, nil, nil, 980, nil, nil, 981, + nil, 984, nil, nil, nil, nil, nil, nil, 494, nil, + 491, 490, 489, 499, 492, 1010, nil, nil, nil, 102, + 90, 93, 94, 502, 95, 97, 96, 98, nil, nil, + nil, nil, 91, 101, 241, 115, 114, 116, 117, nil, + 85, nil, 92, 106, 107, 497, nil, 997, 998, nil, + nil, 119, 118, 120, 1009, nil, 510, 509, 1012, nil, + nil, 503, nil, nil, 104, 105, nil, nil, 360, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 1011, nil, + nil, 982, nil, nil, nil, 980, nil, nil, 981, nil, + nil, 488, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1010, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, 115, 114, 116, 117, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 997, 998, nil, 119, + 118, 120, 1009, nil, nil, 494, 1012, 491, 490, 489, + 499, 492, 104, 105, nil, nil, 360, nil, nil, nil, + 502, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1011, nil, nil, 982, + nil, nil, 497, 980, nil, nil, 981, nil, 984, nil, + nil, 507, 506, 510, 509, nil, nil, nil, 503, nil, + nil, nil, 1010, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, 115, 114, 116, 117, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 997, 998, nil, 119, 118, 120, + 1009, nil, nil, 494, 1012, 491, 490, 489, 499, 492, + 104, 105, nil, nil, 360, nil, nil, nil, 502, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1011, nil, nil, 982, nil, nil, + 497, 980, nil, nil, 981, nil, nil, nil, nil, 507, + 506, 510, 509, nil, nil, nil, 503, nil, nil, nil, + 1010, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, 115, + 114, 116, 117, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 997, 998, nil, 119, 118, 120, 1009, nil, + nil, nil, 1012, 989, nil, nil, nil, nil, 104, 105, + nil, nil, 360, 502, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1011, nil, nil, 982, nil, nil, nil, 980, + nil, nil, 981, nil, 984, nil, nil, nil, nil, nil, + nil, 503, nil, nil, nil, nil, nil, nil, 1010, nil, + nil, nil, 102, 990, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, 115, 114, 116, + 117, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 997, 998, nil, 119, 118, 120, 1009, nil, nil, nil, + 1012, 989, nil, nil, nil, nil, 104, 105, nil, nil, + 360, 502, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1011, nil, nil, 982, nil, nil, nil, 980, nil, nil, + 981, nil, 984, nil, nil, nil, nil, nil, nil, 503, + nil, nil, nil, nil, nil, nil, 1010, nil, nil, nil, + 102, 990, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, 115, 114, 116, 117, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 997, 998, + nil, 119, 118, 120, 1009, nil, nil, 494, 1012, 491, + 490, 489, 499, 492, 104, 105, nil, nil, 360, nil, + nil, nil, 502, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 1011, nil, + nil, 982, nil, nil, 497, 980, nil, nil, 981, nil, + 984, nil, nil, nil, nil, 510, 509, nil, nil, nil, + 503, nil, nil, nil, 1010, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, 115, 114, 116, 117, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 997, 998, nil, 119, + 118, 120, 1009, nil, nil, nil, 1012, nil, nil, nil, + nil, nil, 104, 105, nil, nil, 360, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1011, nil, nil, 982, + nil, nil, nil, 980, nil, nil, 981, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1010, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, 115, 114, 116, 117, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 997, 998, nil, 119, 118, 120, + 1009, nil, nil, nil, 1012, nil, nil, nil, nil, nil, + 104, 105, nil, nil, 360, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1011, nil, nil, 982, nil, nil, + nil, 980, nil, nil, 981, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1010, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, 115, + 114, 116, 117, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 997, 998, nil, 119, 118, 120, 1009, nil, + nil, nil, 1012, 989, nil, nil, nil, nil, 104, 105, + nil, nil, 360, 502, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1011, nil, nil, 982, nil, nil, nil, 980, + nil, nil, 981, nil, 984, nil, nil, nil, nil, nil, + nil, 503, nil, nil, nil, nil, nil, nil, 1010, nil, + nil, nil, 102, 990, 93, 94, nil, 95, 97, 96, + 98, nil, nil, nil, nil, 91, 101, 115, 114, 116, + 117, nil, nil, 85, nil, 92, 106, 107, nil, nil, + 997, 998, nil, 119, 118, 120, 1009, nil, nil, nil, + 1012, nil, nil, nil, nil, nil, 104, 105, nil, nil, + 360, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1011, nil, nil, 982, nil, nil, nil, 980, nil, nil, + 981, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1010, nil, nil, nil, + 102, 90, 93, 94, nil, 95, 97, 96, 98, nil, + nil, nil, nil, 91, 101, 115, 114, 116, 117, nil, + nil, 85, nil, 92, 106, 107, nil, nil, 997, 998, + nil, 119, 118, 120, 1009, nil, nil, nil, 1012, nil, + nil, nil, nil, nil, 104, 105, nil, nil, 360, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 1011, nil, + nil, 982, nil, nil, nil, 980, nil, nil, 981, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1010, nil, nil, nil, 102, 90, + 93, 94, nil, 95, 97, 96, 98, nil, nil, nil, + nil, 91, 101, 115, 114, 116, 117, nil, nil, 85, + nil, 92, 106, 107, nil, nil, 997, 998, nil, 119, + 118, 120, 1009, nil, nil, nil, 1012, nil, nil, nil, + nil, nil, 104, 105, nil, nil, 360, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1011, nil, nil, 982, + nil, nil, nil, 980, nil, nil, 981, nil, 984, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1010, nil, nil, nil, 102, 90, 93, 94, + nil, 95, 97, 96, 98, nil, nil, nil, nil, 91, + 101, 115, 114, 116, 117, nil, nil, 85, nil, 92, + 106, 107, nil, nil, 997, 998, nil, 119, 118, 120, + 1009, nil, nil, nil, 1012, nil, nil, nil, nil, nil, + 104, 105, nil, nil, 360, nil, nil, nil, nil, nil, + nil, nil, 115, 114, 116, 117, nil, nil, nil, nil, + nil, nil, nil, nil, 1011, nil, nil, 982, 119, 118, + 120, 980, nil, nil, 981, nil, nil, nil, nil, nil, + nil, 104, 105, nil, nil, 360, nil, nil, nil, nil, + 1010, nil, nil, nil, 102, 90, 93, 94, nil, 95, + 97, 96, 98, nil, nil, nil, nil, 91, 101, nil, + nil, nil, nil, nil, nil, 85, nil, 92, 106, 107, + nil, nil, 997, 998, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + 115, 114, 116, 117, nil, nil, 85, nil, 92, 106, + 107, nil, nil, nil, nil, nil, 119, 118, 120, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 104, + 105, nil, nil, 360, 115, 114, 116, 117, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 119, 118, 120, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 104, 105, nil, nil, 360, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 102, 90, 93, 94, nil, 95, 97, + 96, 98, nil, nil, nil, nil, 91, 101, nil, nil, + nil, nil, nil, nil, 85, nil, 92, 106, 107, nil, + nil, nil, nil, nil, nil, nil, nil, 102, 90, 93, + 94, nil, 95, 97, 96, 98, nil, nil, nil, nil, + 91, 101, 115, 114, 116, 117, nil, nil, 85, nil, + 92, 106, 107, nil, nil, nil, nil, nil, 119, 118, + 120, 494, nil, 491, 490, 489, 499, 492, nil, nil, + nil, 104, 105, nil, nil, 360, 502, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 497, nil, + nil, nil, nil, nil, nil, nil, nil, 507, 506, 510, + 509, nil, nil, nil, 503, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 102, 90, 93, 94, nil, + 95, 97, 96, 98, nil, nil, nil, nil, 91, 101, + nil, nil, nil, nil, nil, nil, 85, nil, 92, 106, + 107, nil, nil, 494, 488, 491, 490, 489, 499, 492, + nil, 494, nil, 491, 490, 489, 499, 492, 502, nil, + nil, nil, nil, nil, nil, nil, 502, nil, 494, nil, + 491, 490, 489, 499, 492, nil, nil, nil, nil, nil, + 497, nil, nil, 502, nil, nil, nil, nil, 497, 507, + 506, 510, 509, nil, nil, nil, 503, 507, 506, 510, + 509, nil, nil, nil, 503, 497, nil, nil, nil, nil, + nil, nil, nil, nil, 507, 506, 510, 509, nil, nil, + 494, 503, 491, 490, 489, 499, 492, 494, nil, 491, + 490, 489, 499, 492, nil, 502, 488, nil, nil, nil, + nil, nil, 502, nil, 488, 494, nil, 491, 490, 489, + 499, 492, nil, nil, nil, nil, nil, 497, nil, nil, + 502, 488, nil, nil, 497, nil, nil, nil, 510, 509, + nil, nil, nil, 503, nil, 510, 509, nil, nil, nil, + 503, 494, 497, 491, 490, 489, 499, 492, nil, nil, + nil, nil, nil, 510, 509, nil, 502, nil, 503, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 488, nil, nil, nil, nil, 497, nil, + 488, nil, nil, nil, nil, nil, nil, nil, nil, 510, + 509, 459, 463, nil, 503, 460, nil, nil, 488, nil, + nil, nil, nil, 170, 171, nil, 167, 149, 150, 151, + 158, 155, 157, nil, nil, 152, 153, nil, nil, nil, + 172, 173, 159, 160, nil, nil, nil, nil, nil, 307, + nil, nil, nil, nil, 488, nil, nil, 164, 163, nil, + 148, 169, 166, 165, 174, 161, 162, 156, 154, 146, + 168, 147, 467, 471, 175, nil, 466, nil, nil, nil, + nil, nil, nil, nil, 170, 171, nil, 167, 149, 150, + 151, 158, 155, 157, nil, nil, 152, 153, nil, nil, + nil, 172, 173, 159, 160, nil, nil, nil, nil, nil, + 307, nil, nil, nil, nil, nil, nil, nil, 164, 163, + nil, 148, 169, 166, 165, 174, 161, 162, 156, 154, + 146, 168, 147, 560, 463, 175, nil, 561, nil, nil, + nil, nil, nil, nil, nil, 170, 171, nil, 167, 149, + 150, 151, 158, 155, 157, nil, nil, 152, 153, nil, + nil, nil, 172, 173, 159, 160, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 164, + 163, nil, 148, 169, 166, 165, 174, 161, 162, 156, + 154, 146, 168, 147, 735, 463, 175, nil, 736, nil, + nil, nil, nil, nil, nil, nil, 170, 171, nil, 167, + 149, 150, 151, 158, 155, 157, nil, nil, 152, 153, + nil, nil, nil, 172, 173, 159, 160, nil, nil, nil, + nil, nil, 307, nil, nil, nil, nil, nil, nil, nil, + 164, 163, nil, 148, 169, 166, 165, 174, 161, 162, + 156, 154, 146, 168, 147, 738, 471, 175, nil, 737, + nil, nil, nil, nil, nil, nil, nil, 170, 171, nil, + 167, 149, 150, 151, 158, 155, 157, nil, nil, 152, + 153, nil, nil, nil, 172, 173, 159, 160, nil, nil, + nil, nil, nil, 307, nil, nil, nil, nil, nil, nil, + nil, 164, 163, nil, 148, 169, 166, 165, 174, 161, + 162, 156, 154, 146, 168, 147, 773, 463, 175, nil, + 774, nil, nil, nil, nil, nil, nil, nil, 170, 171, + nil, 167, 149, 150, 151, 158, 155, 157, nil, nil, + 152, 153, nil, nil, nil, 172, 173, 159, 160, nil, + nil, nil, nil, nil, 307, nil, nil, nil, nil, nil, + nil, nil, 164, 163, nil, 148, 169, 166, 165, 174, + 161, 162, 156, 154, 146, 168, 147, 776, 471, 175, + nil, 777, nil, nil, nil, nil, nil, nil, nil, 170, + 171, nil, 167, 149, 150, 151, 158, 155, 157, nil, + nil, 152, 153, nil, nil, nil, 172, 173, 159, 160, + nil, nil, nil, nil, nil, 307, nil, nil, nil, nil, + nil, nil, nil, 164, 163, nil, 148, 169, 166, 165, + 174, 161, 162, 156, 154, 146, 168, 147, 735, 463, + 175, nil, 736, nil, nil, nil, nil, nil, nil, nil, + 170, 171, nil, 167, 149, 150, 151, 158, 155, 157, + nil, nil, 152, 153, nil, nil, nil, 172, 173, 159, + 160, nil, nil, nil, nil, nil, 307, nil, nil, nil, + nil, nil, nil, nil, 164, 163, nil, 148, 169, 166, + 165, 174, 161, 162, 156, 154, 146, 168, 147, 738, + 471, 175, nil, 782, nil, nil, nil, nil, nil, nil, + nil, 170, 171, nil, 167, 149, 150, 151, 158, 155, + 157, nil, nil, 152, 153, nil, nil, nil, 172, 173, + 159, 160, nil, nil, nil, nil, nil, 307, nil, nil, + nil, nil, nil, nil, nil, 164, 163, nil, 148, 169, + 166, 165, 174, 161, 162, 156, 154, 146, 168, 147, + 803, 463, 175, nil, 804, nil, nil, nil, nil, nil, + nil, nil, 170, 171, nil, 167, 149, 150, 151, 158, + 155, 157, nil, nil, 152, 153, nil, nil, nil, 172, + 173, 159, 160, nil, nil, nil, nil, nil, 307, nil, + nil, nil, nil, nil, nil, nil, 164, 163, nil, 148, + 169, 166, 165, 174, 161, 162, 156, 154, 146, 168, + 147, 805, 471, 175, nil, 806, nil, nil, nil, nil, + nil, nil, nil, 170, 171, nil, 167, 149, 150, 151, + 158, 155, 157, nil, nil, 152, 153, nil, nil, nil, + 172, 173, 159, 160, nil, nil, nil, nil, nil, 307, + nil, nil, nil, nil, nil, nil, nil, 164, 163, nil, + 148, 169, 166, 165, 174, 161, 162, 156, 154, 146, + 168, 147, 808, 471, 175, nil, 809, nil, nil, nil, + nil, nil, nil, nil, 170, 171, nil, 167, 149, 150, + 151, 158, 155, 157, nil, nil, 152, 153, nil, nil, + nil, 172, 173, 159, 160, nil, nil, nil, nil, nil, + 307, nil, nil, nil, nil, nil, nil, nil, 164, 163, + nil, 148, 169, 166, 165, 174, 161, 162, 156, 154, + 146, 168, 147, 560, 463, 175, nil, 561, nil, nil, + nil, nil, nil, nil, nil, 170, 171, nil, 167, 149, + 150, 151, 158, 155, 157, nil, nil, 152, 153, nil, + nil, nil, 172, 173, 159, 160, nil, nil, nil, nil, + nil, 307, nil, nil, nil, nil, nil, nil, nil, 164, + 163, nil, 148, 169, 166, 165, 174, 161, 162, 156, + 154, 146, 168, 147, 834, 463, 175, nil, 835, nil, + nil, nil, nil, nil, nil, nil, 170, 171, nil, 167, + 149, 150, 151, 158, 155, 157, nil, nil, 152, 153, + nil, nil, nil, 172, 173, 159, 160, nil, nil, nil, + nil, nil, 307, nil, nil, nil, nil, nil, nil, nil, + 164, 163, nil, 148, 169, 166, 165, 174, 161, 162, + 156, 154, 146, 168, 147, 837, 471, 175, nil, 836, + nil, nil, nil, nil, nil, nil, nil, 170, 171, nil, + 167, 149, 150, 151, 158, 155, 157, nil, nil, 152, + 153, nil, nil, nil, 172, 173, 159, 160, nil, nil, + nil, nil, nil, 307, nil, nil, nil, nil, nil, nil, + nil, 164, 163, nil, 148, 169, 166, 165, 174, 161, + 162, 156, 154, 146, 168, 147, 1189, 463, 175, nil, + 1190, nil, nil, nil, nil, nil, nil, nil, 170, 171, + nil, 167, 149, 150, 151, 158, 155, 157, nil, nil, + 152, 153, nil, nil, nil, 172, 173, 159, 160, nil, + nil, nil, nil, nil, 307, nil, nil, nil, nil, nil, + nil, nil, 164, 163, nil, 148, 169, 166, 165, 174, + 161, 162, 156, 154, 146, 168, 147, 1191, 471, 175, + nil, 1192, nil, nil, nil, nil, nil, nil, nil, 170, + 171, nil, 167, 149, 150, 151, 158, 155, 157, nil, + nil, 152, 153, nil, nil, nil, 172, 173, 159, 160, + nil, nil, nil, nil, nil, 307, nil, nil, nil, nil, + nil, nil, nil, 164, 163, nil, 148, 169, 166, 165, + 174, 161, 162, 156, 154, 146, 168, 147, 1219, 471, + 175, nil, 1218, nil, nil, nil, nil, nil, nil, nil, + 170, 171, nil, 167, 149, 150, 151, 158, 155, 157, + nil, nil, 152, 153, nil, nil, nil, 172, 173, 159, + 160, nil, nil, nil, nil, nil, 307, nil, nil, nil, + nil, nil, nil, nil, 164, 163, nil, 148, 169, 166, + 165, 174, 161, 162, 156, 154, 146, 168, 147, nil, + nil, 175 ] + +racc_action_check = [ + 111, 244, 69, 518, 518, 751, 393, 111, 111, 111, + 970, 385, 111, 111, 111, 18, 111, 31, 1158, 417, + 5, 23, 18, 386, 111, 5, 111, 111, 111, 557, + 557, 18, 478, 418, 394, 397, 111, 111, 801, 111, + 111, 111, 111, 111, 950, 1034, 1051, 1052, 1055, 1244, + 478, 635, 1, 333, 1129, 1071, 970, 245, 333, 1244, + 244, 1158, 23, 247, 803, 804, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 18, 31, 111, 111, 111, 417, 111, 111, 626, 69, + 111, 816, 751, 111, 111, 922, 111, 518, 111, 418, + 111, 1071, 111, 111, 31, 111, 111, 111, 111, 111, + 1181, 111, 112, 111, 1189, 393, 245, 911, 911, 112, + 112, 112, 247, 557, 112, 112, 112, 111, 112, 385, + 111, 111, 111, 111, 385, 111, 112, 111, 112, 112, + 112, 386, 111, 394, 397, 111, 386, 19, 112, 112, + 1190, 112, 112, 112, 112, 112, 801, 1191, 1225, 801, + 635, 801, 950, 1034, 1051, 1052, 1055, 950, 1034, 1051, + 1052, 1055, 1129, 803, 804, 805, 1066, 1129, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 626, 1192, 112, 112, 112, 626, 112, 112, + 816, 806, 112, 19, 922, 112, 112, 1038, 112, 1038, + 112, 911, 112, 20, 112, 112, 1066, 112, 112, 112, + 112, 112, 466, 112, 21, 112, 444, 524, 1181, 466, + 466, 466, 1189, 1181, 1191, 466, 466, 1189, 466, 112, + 805, 773, 112, 112, 112, 112, 466, 112, 29, 112, + 353, 1067, 629, 412, 112, 29, 3, 112, 466, 466, + 629, 466, 466, 466, 466, 466, 806, 768, 1190, 20, + 1192, 21, 774, 1190, 776, 1191, 1225, 580, 909, 768, + 1191, 1225, 9, 21, 805, 444, 524, 1067, 466, 466, + 466, 466, 466, 466, 466, 466, 466, 466, 466, 466, + 466, 466, 12, 252, 466, 466, 466, 773, 466, 466, + 806, 1192, 466, 29, 353, 466, 1192, 412, 412, 412, + 466, 14, 466, 735, 466, 466, 1086, 466, 466, 466, + 466, 466, 253, 466, 466, 466, 15, 353, 774, 776, + 776, 580, 580, 580, 909, 17, 1078, 773, 698, 466, + 773, 88, 466, 466, 413, 466, 1078, 466, 580, 252, + 390, 467, 773, 88, 466, 390, 736, 466, 467, 467, + 467, 48, 48, 88, 467, 467, 27, 467, 774, 981, + 776, 774, 735, 776, 909, 467, 467, 909, 253, 698, + 1086, 1086, 1086, 774, 1078, 776, 981, 467, 467, 909, + 467, 467, 467, 467, 467, 377, 1078, 1086, 377, 234, + 54, 234, 234, 234, 234, 234, 287, 54, 413, 413, + 413, 360, 360, 287, 234, 736, 54, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, 467, 467, + 467, 889, 43, 467, 467, 467, 234, 467, 467, 48, + 48, 467, 1204, 42, 467, 234, 234, 234, 234, 467, + 660, 467, 234, 467, 467, 414, 467, 467, 467, 467, + 467, 737, 467, 467, 467, 54, 834, 835, 737, 737, + 737, 287, 889, 737, 737, 737, 288, 737, 467, 43, + 45, 467, 467, 288, 467, 737, 467, 737, 737, 360, + 360, 43, 234, 467, 401, 53, 467, 737, 737, 991, + 737, 737, 737, 737, 737, 512, 1204, 1204, 16, 16, + 512, 662, 888, 415, 660, 660, 217, 991, 416, 414, + 414, 414, 230, 1204, 660, 834, 835, 737, 737, 737, + 737, 737, 737, 737, 737, 737, 737, 737, 737, 737, + 737, 288, 44, 737, 737, 737, 401, 737, 737, 378, + 232, 737, 378, 401, 737, 737, 419, 737, 401, 737, + 937, 737, 401, 737, 737, 236, 737, 737, 737, 737, + 737, 888, 737, 737, 737, 662, 662, 415, 415, 415, + 289, 401, 416, 416, 416, 662, 243, 289, 737, 44, + 290, 737, 737, 243, 737, 246, 737, 290, 291, 364, + 738, 44, 243, 737, 248, 291, 737, 738, 738, 738, + 645, 401, 738, 738, 738, 645, 738, 51, 51, 937, + 419, 419, 419, 292, 738, 738, 738, 738, 738, 979, + 292, 403, 384, 384, 979, 403, 738, 738, 979, 738, + 738, 738, 738, 738, 1011, 289, 364, 926, 1011, 293, + 294, 243, 926, 51, 51, 290, 293, 294, 364, 381, + 249, 782, 381, 291, 782, 255, 738, 738, 738, 738, + 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, + 306, 1084, 738, 738, 738, 320, 738, 738, 292, 459, + 738, 1084, 295, 738, 738, 321, 738, 296, 738, 295, + 738, 324, 738, 738, 296, 738, 738, 738, 738, 738, + 836, 738, 738, 738, 293, 294, 138, 836, 836, 836, + 782, 138, 138, 836, 836, 337, 836, 738, 535, 1084, + 738, 738, 738, 738, 836, 738, 459, 738, 710, 710, + 1070, 1084, 738, 402, 1070, 738, 836, 836, 459, 836, + 836, 836, 836, 836, 338, 788, 340, 295, 788, 345, + 535, 707, 296, 341, 535, 535, 345, 460, 653, 653, + 342, 707, 653, 653, 653, 345, 836, 836, 836, 836, + 836, 836, 836, 836, 836, 836, 836, 836, 836, 836, + 348, 682, 836, 836, 836, 402, 836, 836, 1121, 351, + 836, 1121, 402, 836, 707, 707, 352, 402, 836, 707, + 836, 402, 836, 836, 460, 836, 836, 836, 836, 836, + 354, 836, 836, 836, 345, 355, 460, 789, 789, 903, + 402, 903, 903, 903, 903, 903, 359, 836, 682, 361, + 836, 836, 808, 836, 903, 836, 368, 536, 370, 837, + 682, 373, 836, 994, 994, 836, 837, 837, 837, 1098, + 402, 379, 837, 837, 380, 837, 903, 1180, 1180, 1098, + 1182, 1182, 382, 837, 837, 903, 903, 903, 903, 536, + 346, 391, 903, 536, 536, 837, 837, 346, 837, 837, + 837, 837, 837, 392, 808, 396, 346, 398, 347, 407, + 427, 808, 1098, 1098, 433, 347, 808, 1098, 903, 435, + 808, 436, 437, 441, 347, 837, 837, 837, 837, 837, + 837, 837, 837, 837, 837, 837, 837, 837, 837, 808, + 445, 837, 837, 837, 455, 837, 837, 349, 457, 837, + 458, 468, 837, 474, 349, 346, 475, 837, 479, 837, + 480, 837, 837, 349, 837, 837, 837, 837, 837, 808, + 837, 837, 837, 347, 481, 365, 484, 485, 486, 496, + 395, 405, 365, 508, 511, 514, 837, 395, 405, 837, + 837, 365, 837, 520, 837, 443, 395, 405, 528, 529, + 537, 837, 443, 538, 837, 2, 2, 2, 2, 2, + 2, 443, 349, 539, 2, 2, 540, 565, 566, 2, + 567, 2, 2, 2, 2, 2, 2, 2, 25, 571, + 587, 588, 591, 2, 2, 2, 2, 2, 2, 2, + 365, 593, 2, 598, 602, 395, 405, 612, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 443, 2, 2, 2, 613, 2, 2, 2, 2, 2, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 597, 25, 25, 623, 627, 25, 25, 597, 2, + 628, 25, 2, 630, 657, 2, 2, 597, 665, 2, + 667, 2, 25, 675, 25, 2, 25, 25, 683, 25, + 25, 25, 25, 25, 2, 25, 688, 694, 696, 2, + 2, 2, 2, 638, 2, 2, 2, 2, 700, 701, + 638, 717, 2, 2, 722, 25, 723, 725, 730, 638, + 2, 731, 2, 2, 2, 739, 597, 2, 2, 38, + 38, 38, 38, 38, 38, 745, 748, 750, 38, 38, + 756, 757, 758, 38, 760, 38, 38, 38, 38, 38, + 38, 38, 8, 8, 8, 8, 8, 38, 38, 38, + 38, 38, 38, 38, 762, 770, 38, 772, 638, 775, + 778, 448, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 779, 38, 38, 38, 783, 38, + 38, 38, 38, 38, 448, 448, 448, 448, 448, 448, + 448, 448, 448, 448, 448, 777, 448, 448, 791, 797, + 448, 448, 777, 38, 798, 802, 38, 777, 811, 38, + 38, 777, 815, 38, 817, 38, 448, 824, 448, 38, + 448, 448, 826, 448, 448, 448, 448, 448, 38, 448, + 827, 828, 831, 38, 38, 38, 38, 1053, 38, 38, + 38, 38, 833, 842, 1053, 850, 38, 38, 857, 448, + 860, 448, 861, 1053, 38, 864, 38, 38, 38, 866, + 777, 38, 38, 66, 66, 66, 66, 66, 66, 869, + 870, 872, 66, 66, 873, 875, 879, 66, 896, 66, + 66, 66, 66, 66, 66, 66, 336, 336, 336, 336, + 336, 66, 66, 66, 66, 66, 66, 66, 899, 900, + 66, 908, 1053, 913, 916, 454, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 923, 66, + 66, 66, 925, 66, 66, 66, 66, 66, 454, 454, + 454, 454, 454, 454, 454, 454, 454, 454, 454, 809, + 454, 454, 932, 933, 454, 454, 809, 66, 934, 936, + 66, 809, 943, 66, 66, 809, 944, 66, 965, 66, + 454, 966, 454, 66, 454, 454, 975, 454, 454, 454, + 454, 454, 66, 454, 983, 984, 985, 66, 66, 66, + 66, 1111, 66, 66, 66, 66, 1018, 1019, 1111, 1021, + 66, 66, 1022, 454, 1023, 1025, 1026, 1111, 66, 1027, + 66, 66, 66, 1042, 809, 66, 66, 136, 136, 136, + 136, 136, 136, 1054, 1057, 1058, 136, 136, 1059, 1060, + 1064, 136, 1072, 136, 136, 136, 136, 136, 136, 136, + 585, 585, 585, 585, 585, 136, 136, 136, 136, 136, + 136, 136, 1073, 1077, 136, 1080, 1111, 1085, 1109, 1112, + 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, + 136, 136, 1119, 136, 136, 136, 1120, 136, 136, 136, + 136, 136, 318, 318, 318, 318, 318, 318, 318, 318, + 318, 318, 318, 1177, 318, 318, 1125, 1135, 318, 318, + 1177, 136, 1137, 1142, 136, 1143, 1144, 136, 136, 1177, + 1145, 136, 1146, 136, 318, 1147, 318, 136, 318, 318, + 1151, 318, 318, 318, 318, 318, 136, 318, 1152, 1153, + 1155, 136, 136, 136, 136, 1159, 136, 136, 136, 136, + 1166, 1167, 1170, 1171, 136, 136, 1172, 318, 1173, 1175, + 1188, 1193, 136, 1218, 136, 136, 136, 1219, 1177, 136, + 136, 219, 219, 219, 219, 219, 219, 1227, 1228, 1231, + 219, 219, 1232, 1233, 1234, 219, 1245, 219, 219, 219, + 219, 219, 219, 219, nil, nil, nil, nil, nil, 219, + 219, 219, 219, 219, 219, 219, nil, 724, 219, 724, + 724, 724, nil, 724, 219, 219, 219, 219, 219, 219, + 219, 219, 219, 219, 219, 219, nil, 219, 219, 219, + nil, 219, 219, 219, 219, 219, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, nil, 554, 554, + nil, nil, 554, 554, nil, 219, nil, 1010, 219, 1010, + 1010, 219, 219, 1010, nil, 219, nil, 219, 554, nil, + 554, 219, 554, 554, nil, 554, 554, 554, 554, 554, + 219, 554, nil, nil, nil, 219, 219, 219, 219, nil, + 219, 219, 219, 219, 1010, nil, nil, nil, 219, 219, + 554, 554, nil, nil, nil, nil, 219, nil, 219, 219, + 219, nil, nil, 219, 219, 231, 231, 231, 231, 231, + 231, nil, nil, nil, 231, 231, nil, nil, nil, 231, + nil, 231, 231, 231, 231, 231, 231, 231, nil, nil, + nil, nil, nil, 231, 231, 231, 231, 231, 231, 231, + nil, 1045, 231, 1045, 1045, 1045, nil, 1045, 231, 231, + 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, + nil, 231, 231, 231, nil, 231, 231, 231, 231, 231, + 699, 699, 699, 699, 699, 699, 699, 699, 699, 699, + 699, nil, 699, 699, nil, nil, 699, 699, nil, 231, + nil, nil, 231, nil, nil, 231, 231, nil, nil, 231, + nil, 231, 699, nil, 699, 231, 699, 699, nil, 699, + 699, 699, 699, 699, 231, 699, nil, nil, nil, 231, + 231, 231, 231, nil, 231, 231, 231, 231, nil, nil, + nil, nil, 231, 231, nil, 699, nil, nil, nil, nil, + 231, nil, 231, 231, 231, nil, nil, 231, 231, 237, + 237, 237, 237, 237, 237, nil, nil, nil, 237, 237, + nil, nil, nil, 237, nil, 237, 237, 237, 237, 237, + 237, 237, nil, nil, nil, nil, nil, 237, 237, 237, + 237, 237, 237, 237, nil, 1186, 237, 1186, 1186, 1186, + nil, 1186, 237, 237, 237, 237, 237, 237, 237, 237, + 237, 237, 237, 237, nil, 237, 237, 237, nil, 237, + 237, 237, 237, 237, 784, 784, 784, 784, 784, 784, + 784, 784, 784, 784, 784, nil, 784, 784, nil, nil, + 784, 784, nil, 237, nil, nil, 237, nil, nil, 237, + 237, nil, nil, 237, nil, 237, 784, nil, 784, 237, + 784, 784, nil, 784, 784, 784, 784, 784, 237, 784, + nil, nil, nil, 237, 237, 237, 237, nil, 237, 237, + 237, 237, nil, nil, nil, nil, 237, 237, nil, 784, + nil, nil, nil, nil, 237, nil, 237, 237, 237, nil, + nil, 237, 237, 254, 254, 254, 254, 254, 254, nil, + nil, nil, 254, 254, nil, nil, nil, 254, nil, 254, + 254, 254, 254, 254, 254, 254, nil, nil, nil, nil, + nil, 254, 254, 254, 254, 254, 254, 254, nil, nil, + 254, nil, nil, nil, nil, nil, 254, 254, 254, 254, + 254, 254, 254, 254, 254, 254, 254, 254, nil, 254, + 254, 254, nil, 254, 254, 254, 254, 254, 839, 839, + 839, 839, 839, 839, 839, 839, 839, 839, 839, nil, + 839, 839, nil, nil, 839, 839, nil, 254, nil, nil, + 254, nil, nil, 254, 254, nil, nil, 254, nil, 254, + 839, nil, 839, 254, 839, 839, nil, 839, 839, 839, + 839, 839, 254, 839, nil, nil, nil, 254, 254, 254, + 254, nil, 254, 254, 254, 254, nil, nil, nil, nil, + 254, 254, nil, 839, nil, nil, nil, nil, 254, nil, + 254, 254, 254, nil, nil, 254, 254, 339, 339, 339, + 339, 339, 339, nil, nil, nil, 339, 339, nil, nil, + nil, 339, nil, 339, 339, 339, 339, 339, 339, 339, + nil, nil, nil, nil, nil, 339, 339, 339, 339, 339, + 339, 339, nil, nil, 339, nil, nil, nil, nil, nil, + 339, 339, 339, 339, 339, 339, 339, 339, 339, 339, + 339, 339, nil, 339, 339, 339, nil, 339, 339, 339, + 339, 339, 942, 942, 942, 942, 942, 942, 942, 942, + 942, 942, 942, nil, 942, 942, nil, nil, 942, 942, + nil, 339, nil, nil, 339, nil, nil, 339, 339, nil, + nil, 339, nil, 339, 942, nil, 942, 339, 942, 942, + nil, 942, 942, 942, 942, 942, 339, 942, nil, nil, + nil, 339, 339, 339, 339, nil, 339, 339, 339, 339, + nil, nil, nil, nil, 339, 339, nil, 942, nil, nil, + nil, nil, 339, nil, 339, 339, 339, nil, nil, 339, + 339, 344, 344, 344, 344, 344, 344, nil, nil, nil, + 344, 344, nil, nil, nil, 344, nil, 344, 344, 344, + 344, 344, 344, 344, nil, nil, nil, nil, nil, 344, + 344, 344, 344, 344, 344, 344, nil, nil, 344, nil, + nil, nil, nil, nil, 344, 344, 344, 344, 344, 344, + 344, 344, 344, 344, 344, 344, nil, 344, 344, 344, + nil, 344, 344, 344, 344, 344, 945, 945, 945, 945, + 945, 945, 945, 945, 945, 945, 945, nil, 945, 945, + nil, nil, 945, 945, nil, 344, nil, nil, 344, nil, + nil, 344, 344, nil, nil, 344, nil, 344, 945, nil, + 945, 344, 945, 945, nil, 945, 945, 945, 945, 945, + 344, 945, nil, nil, nil, 344, 344, 344, 344, nil, + 344, 344, 344, 344, nil, nil, nil, nil, 344, 344, + nil, 945, nil, nil, nil, nil, 344, nil, 344, 344, + 344, nil, nil, 344, 344, 374, 374, 374, 374, 374, + 374, nil, nil, nil, 374, 374, nil, nil, nil, 374, + nil, 374, 374, 374, 374, 374, 374, 374, nil, nil, + nil, nil, nil, 374, 374, 374, 374, 374, 374, 374, + nil, nil, 374, nil, nil, nil, nil, nil, 374, 374, + 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, + nil, 374, 374, 374, nil, 374, 374, 374, 374, 374, + 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, 1014, + 1014, nil, 1014, 1014, nil, nil, 1014, 1014, nil, 374, + nil, nil, 374, nil, nil, 374, 374, nil, nil, 374, + nil, 374, 1014, nil, 1014, 374, 1014, 1014, nil, 1014, + 1014, 1014, 1014, 1014, 374, 1014, nil, nil, nil, 374, + 374, 374, 374, nil, 374, 374, 374, 374, nil, nil, + nil, nil, 374, 374, nil, 1014, nil, nil, nil, nil, + 374, nil, 374, 374, 374, nil, nil, 374, 374, 388, + 388, 388, 388, 388, 388, nil, nil, nil, 388, 388, + nil, nil, nil, 388, nil, 388, 388, 388, 388, 388, + 388, 388, nil, nil, nil, nil, nil, 388, 388, 388, + 388, 388, 388, 388, nil, 497, 388, 497, 497, 497, + nil, 497, 388, 388, 388, 388, 388, 388, 388, 388, + 388, 388, 388, 388, nil, 388, 388, 388, nil, 388, + 388, 388, 388, 388, 720, nil, 720, 720, 720, nil, + 720, nil, 497, nil, 881, nil, 881, 881, 881, nil, + 881, 497, nil, 388, nil, nil, 388, nil, nil, 388, + 388, nil, nil, 388, 880, 388, 880, 880, 880, 388, + 880, 720, nil, nil, nil, nil, nil, nil, 388, nil, + 720, 881, nil, 388, 388, 388, 388, nil, 388, 388, + 388, 388, nil, nil, nil, nil, 388, 388, nil, nil, + nil, 880, nil, nil, 388, nil, 388, 388, 388, nil, + 880, 388, 388, 389, 389, 389, 389, 389, 389, nil, + nil, nil, 389, 389, nil, nil, nil, 389, nil, 389, + 389, 389, 389, 389, 389, 389, nil, nil, nil, nil, + nil, 389, 389, 389, 389, 389, 389, 389, nil, nil, + 389, nil, nil, nil, nil, nil, 389, 389, 389, 389, + 389, 389, 389, 389, 389, 389, 389, 389, nil, 389, + 389, 389, nil, 389, 389, 389, 389, 389, 366, 366, + 366, 366, 366, 366, 366, 366, 366, 366, 366, nil, + 366, 366, nil, nil, 366, 366, nil, 389, nil, nil, + 389, nil, nil, 389, 389, nil, 550, 389, nil, 389, + 366, nil, 366, 389, 366, 366, nil, 366, 366, 366, + 366, 366, 389, 366, nil, nil, nil, 389, 389, 389, + 389, nil, 389, 389, 389, 389, nil, nil, 550, nil, + 389, 389, 550, 550, nil, 550, 550, nil, 389, nil, + 389, 389, 389, nil, nil, 389, 389, 622, 622, 622, + 622, 622, 622, nil, nil, nil, 622, 622, nil, nil, + nil, 622, nil, 622, 622, 622, 622, 622, 622, 622, + nil, nil, nil, nil, nil, 622, 622, 622, 622, 622, + 622, 622, nil, nil, 622, nil, nil, nil, nil, nil, + 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, + 622, 622, nil, 622, 622, 622, nil, 622, 622, 622, + 622, 622, 367, 367, 367, 367, 367, 367, 367, 367, + 367, 367, 367, nil, 367, 367, nil, nil, 367, 367, + nil, 622, nil, nil, 622, nil, nil, 622, 622, nil, + 551, 622, nil, 622, 367, nil, 367, 622, 367, 367, + nil, 367, 367, 367, 367, 367, 622, 367, nil, nil, + nil, 622, 622, 622, 622, nil, 622, 622, 622, 622, + nil, nil, 551, nil, 622, 622, 551, 551, nil, 551, + 551, nil, 622, nil, 622, 622, 622, nil, nil, 622, + 622, 625, 625, 625, 625, 625, 625, nil, nil, nil, + 625, 625, nil, nil, nil, 625, nil, 625, 625, 625, + 625, 625, 625, 625, nil, nil, nil, nil, nil, 625, + 625, 625, 625, 625, 625, 625, nil, nil, 625, nil, + nil, nil, nil, nil, 625, 625, 625, 625, 625, 625, + 625, 625, 625, 625, 625, 625, nil, 625, 625, 625, + nil, 625, 625, 625, 625, 625, 533, 533, 533, 533, + 533, 533, 533, 533, 533, 533, 533, nil, 533, 533, + nil, nil, 533, 533, nil, 625, nil, nil, 625, nil, + nil, 625, 625, nil, nil, 625, nil, 625, 533, nil, + 533, 625, 533, 533, nil, 533, 533, 533, 533, 533, + 625, 533, nil, nil, nil, 625, 625, 625, 625, nil, + 625, 625, 625, 625, nil, nil, nil, nil, 625, 625, + nil, 1061, nil, 1061, 1061, 1061, 625, 1061, 625, 625, + 625, nil, nil, 625, 625, 646, 646, 646, 646, 646, + 646, nil, nil, nil, 646, 646, nil, nil, nil, 646, + nil, 646, 646, 646, 646, 646, 646, 646, 1061, nil, + nil, nil, nil, 646, 646, 646, 646, 646, 646, 646, + nil, nil, 646, nil, nil, nil, nil, nil, 646, 646, + 646, 646, 646, 646, 646, 646, 646, 646, 646, 646, + nil, 646, 646, 646, nil, 646, 646, 646, 646, 646, + 534, 534, 534, 534, 534, 534, 534, 534, 534, 534, + 534, nil, 534, 534, nil, nil, 534, 534, nil, 646, + nil, nil, 646, nil, nil, 646, 646, nil, nil, 646, + nil, 646, 534, nil, 534, 646, 534, 534, nil, 534, + 534, 534, 534, 534, 646, 534, nil, nil, nil, 646, + 646, 646, 646, nil, 646, 646, 646, 646, nil, nil, + nil, nil, 646, 646, nil, 1062, nil, 1062, 1062, 1062, + 646, 1062, 646, 646, 646, nil, nil, 646, 646, 807, + 807, 807, 807, 807, 807, nil, nil, nil, 807, 807, + nil, nil, nil, 807, nil, 807, 807, 807, 807, 807, + 807, 807, 1062, nil, nil, nil, nil, 807, 807, 807, + 807, 807, 807, 807, nil, nil, 807, nil, nil, nil, + nil, nil, 807, 807, 807, 807, 807, 807, 807, 807, + 807, 807, 807, 807, nil, 807, 807, 807, nil, 807, + 807, 807, 807, 807, 544, 544, 544, 544, 544, 544, + 544, nil, nil, 544, 544, nil, nil, nil, nil, nil, + 544, 544, nil, 807, nil, nil, 807, nil, nil, 807, + 807, nil, nil, 807, nil, 807, 544, nil, 544, 807, + 544, 544, nil, 544, 544, 544, 544, 544, 807, 544, + nil, nil, nil, 807, 807, 807, 807, nil, 807, 807, + 807, 807, nil, nil, nil, nil, 807, 807, nil, nil, + nil, nil, nil, nil, 807, nil, 807, 807, 807, nil, + nil, 807, 807, 812, 812, 812, 812, 812, 812, nil, + nil, nil, 812, 812, nil, nil, nil, 812, nil, 812, + 812, 812, 812, 812, 812, 812, nil, nil, nil, nil, + nil, 812, 812, 812, 812, 812, 812, 812, nil, nil, + 812, nil, nil, nil, nil, nil, 812, 812, 812, 812, + 812, 812, 812, 812, 812, 812, 812, 812, nil, 812, + 812, 812, nil, 812, 812, 812, 812, 812, 545, 545, + 545, 545, 545, 545, 545, nil, nil, 545, 545, nil, + nil, nil, nil, nil, 545, 545, nil, 812, nil, nil, + 812, nil, nil, 812, 812, nil, nil, 812, nil, 812, + 545, nil, 545, 812, 545, 545, nil, 545, 545, 545, + 545, 545, 812, 545, nil, nil, nil, 812, 812, 812, + 812, nil, 812, 812, 812, 812, nil, nil, nil, nil, + 812, 812, nil, nil, nil, nil, nil, nil, 812, nil, + 812, 812, 812, nil, nil, 812, 812, 821, 821, 821, + 821, 821, 821, nil, nil, nil, 821, 821, nil, nil, + nil, 821, nil, 821, 821, 821, 821, 821, 821, 821, + nil, nil, nil, nil, nil, 821, 821, 821, 821, 821, + 821, 821, nil, nil, 821, nil, nil, nil, nil, nil, + 821, 821, 821, 821, 821, 821, 821, 821, 821, 821, + 821, 821, nil, 821, 821, 821, nil, 821, 821, 821, + 821, 821, 546, 546, 546, 546, 546, 546, 546, nil, + nil, 546, 546, nil, nil, nil, nil, nil, 546, 546, + nil, 821, nil, nil, 821, nil, nil, 821, 821, nil, + nil, 821, nil, 821, 546, nil, 546, 821, 546, 546, + nil, 546, 546, 546, 546, 546, 821, 546, nil, nil, + nil, 821, 821, 821, 821, nil, 821, 821, 821, 821, + nil, nil, nil, nil, 821, 821, nil, nil, nil, nil, + nil, nil, 821, nil, 821, 821, 821, nil, nil, 821, + 821, 859, 859, 859, 859, 859, 859, nil, nil, nil, + 859, 859, nil, nil, nil, 859, nil, 859, 859, 859, + 859, 859, 859, 859, nil, nil, nil, nil, nil, 859, + 859, 859, 859, 859, 859, 859, nil, nil, 859, nil, + nil, nil, nil, nil, 859, 859, 859, 859, 859, 859, + 859, 859, 859, 859, 859, 859, nil, 859, 859, 859, + nil, 859, 859, 859, 859, 859, 547, 547, 547, 547, + 547, 547, 547, nil, nil, 547, 547, nil, nil, nil, + nil, nil, 547, 547, nil, 859, nil, nil, 859, nil, + nil, 859, 859, nil, nil, 859, nil, 859, 547, nil, + 547, 859, 547, 547, nil, 547, 547, 547, 547, 547, + 859, 547, nil, nil, nil, 859, 859, 859, 859, nil, + 859, 859, 859, 859, nil, nil, nil, nil, 859, 859, + nil, nil, nil, nil, nil, nil, 859, nil, 859, 859, + 859, nil, nil, 859, 859, 904, 904, 904, 904, 904, + 904, nil, nil, nil, 904, 904, nil, nil, nil, 904, + nil, 904, 904, 904, 904, 904, 904, 904, nil, nil, + nil, nil, nil, 904, 904, 904, 904, 904, 904, 904, + nil, nil, 904, nil, nil, nil, nil, nil, 904, 904, + 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, + nil, 904, 904, 904, nil, 904, 904, 904, 904, 904, + 548, 548, 548, 548, 548, 548, 548, nil, nil, 548, + 548, nil, nil, nil, nil, nil, 548, 548, nil, 904, + nil, nil, 904, nil, nil, 904, 904, nil, nil, 904, + nil, 904, 548, nil, 548, 904, 548, 548, nil, 548, + 548, 548, 548, 548, 904, 548, nil, nil, nil, 904, + 904, 904, 904, nil, 904, 904, 904, 904, nil, nil, + nil, nil, 904, 904, nil, nil, nil, nil, nil, nil, + 904, nil, 904, 904, 904, nil, nil, 904, 904, 921, + 921, 921, 921, 921, 921, nil, nil, nil, 921, 921, + nil, nil, nil, 921, nil, 921, 921, 921, 921, 921, + 921, 921, nil, nil, nil, nil, nil, 921, 921, 921, + 921, 921, 921, 921, nil, nil, 921, nil, nil, nil, + nil, nil, 921, 921, 921, 921, 921, 921, 921, 921, + 921, 921, 921, 921, nil, 921, 921, 921, nil, 921, + 921, 921, 921, 921, 549, 549, 549, 549, 549, 549, + 549, nil, nil, 549, 549, nil, nil, nil, nil, nil, + 549, 549, nil, 921, nil, nil, 921, nil, nil, 921, + 921, nil, nil, 921, nil, 921, 549, nil, 549, 921, + 549, 549, nil, 549, 549, 549, 549, 549, 921, 549, + nil, nil, nil, 921, 921, 921, 921, nil, 921, 921, + 921, 921, nil, nil, nil, nil, 921, 921, nil, nil, + nil, nil, nil, nil, 921, nil, 921, 921, 921, nil, + nil, 921, 921, 927, 927, 927, 927, 927, 927, nil, + nil, nil, 927, 927, nil, nil, nil, 927, nil, 927, + 927, 927, 927, 927, 927, 927, nil, nil, nil, nil, + nil, 927, 927, 927, 927, 927, 927, 927, nil, nil, + 927, nil, nil, nil, nil, nil, 927, 927, 927, 927, + 927, 927, 927, 927, 927, 927, 927, 927, nil, 927, + 927, 927, nil, 927, 927, 927, 927, 927, 552, 552, + 552, 552, 552, 552, 552, nil, nil, 552, 552, nil, + nil, nil, nil, nil, 552, 552, nil, 927, nil, nil, + 927, nil, nil, 927, 927, nil, nil, 927, nil, 927, + 552, nil, 552, 927, 552, 552, nil, 552, 552, 552, + 552, 552, 927, 552, nil, nil, nil, 927, 927, 927, + 927, nil, 927, 927, 927, 927, nil, nil, nil, nil, + 927, 927, nil, nil, nil, nil, nil, nil, 927, nil, + 927, 927, 927, nil, nil, 927, 927, 947, 947, 947, + 947, 947, 947, nil, nil, nil, 947, 947, nil, nil, + nil, 947, nil, 947, 947, 947, 947, 947, 947, 947, + nil, nil, nil, nil, nil, 947, 947, 947, 947, 947, + 947, 947, nil, nil, 947, nil, nil, nil, nil, nil, + 947, 947, 947, 947, 947, 947, 947, 947, 947, 947, + 947, 947, nil, 947, 947, 947, nil, 947, 947, 947, + 947, 947, 553, 553, 553, 553, 553, 553, 553, 553, + nil, 553, 553, nil, nil, nil, nil, nil, 553, 553, + nil, 947, nil, nil, 947, nil, nil, 947, 947, nil, + nil, 947, nil, 947, 553, nil, 553, 947, 553, 553, + nil, 553, 553, 553, 553, 553, 947, 553, nil, nil, + nil, 947, 947, 947, 947, nil, 947, 947, 947, 947, + nil, nil, nil, nil, 947, 947, nil, nil, nil, nil, + nil, nil, 947, nil, 947, 947, 947, nil, nil, 947, + 947, 1015, 1015, 1015, 1015, 1015, 1015, nil, nil, nil, + 1015, 1015, nil, nil, nil, 1015, nil, 1015, 1015, 1015, + 1015, 1015, 1015, 1015, nil, nil, nil, nil, nil, 1015, + 1015, 1015, 1015, 1015, 1015, 1015, nil, nil, 1015, nil, + nil, nil, nil, nil, 1015, 1015, 1015, 1015, 1015, 1015, + 1015, 1015, 1015, 1015, 1015, 1015, nil, 1015, 1015, 1015, + nil, 1015, 1015, 1015, 1015, 1015, 555, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 555, 555, nil, 1015, nil, nil, 1015, nil, + nil, 1015, 1015, nil, nil, 1015, nil, 1015, 555, nil, + 555, 1015, 555, 555, nil, 555, 555, nil, nil, 555, + 1015, 555, nil, nil, nil, 1015, 1015, 1015, 1015, nil, + 1015, 1015, 1015, 1015, nil, nil, nil, nil, 1015, 1015, + nil, nil, nil, nil, nil, nil, 1015, nil, 1015, 1015, + 1015, nil, nil, 1015, 1015, 1043, 1043, 1043, 1043, 1043, + 1043, nil, nil, nil, 1043, 1043, nil, nil, nil, 1043, + nil, 1043, 1043, 1043, 1043, 1043, 1043, 1043, nil, nil, + nil, nil, nil, 1043, 1043, 1043, 1043, 1043, 1043, 1043, + nil, nil, 1043, nil, nil, nil, nil, nil, 1043, 1043, + 1043, 1043, 1043, 1043, 1043, 1043, 1043, 1043, 1043, 1043, + nil, 1043, 1043, 1043, nil, 1043, 1043, 1043, 1043, 1043, + 608, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 608, 608, nil, 1043, + nil, nil, 1043, nil, nil, 1043, 1043, nil, nil, 1043, + nil, 1043, 608, nil, 608, 1043, 608, 608, nil, 608, + 608, nil, nil, 608, 1043, 608, nil, nil, nil, 1043, + 1043, 1043, 1043, nil, 1043, 1043, 1043, 1043, nil, nil, + nil, nil, 1043, 1043, nil, nil, nil, nil, nil, nil, + 1043, nil, 1043, 1043, 1043, nil, nil, 1043, 1043, 1044, + 1044, 1044, 1044, 1044, 1044, nil, nil, nil, 1044, 1044, + nil, nil, nil, 1044, nil, 1044, 1044, 1044, 1044, 1044, + 1044, 1044, nil, nil, nil, nil, nil, 1044, 1044, 1044, + 1044, 1044, 1044, 1044, nil, nil, 1044, nil, nil, nil, + nil, nil, 1044, 1044, 1044, 1044, 1044, 1044, 1044, 1044, + 1044, 1044, 1044, 1044, nil, 1044, 1044, 1044, nil, 1044, + 1044, 1044, 1044, 1044, 541, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 541, 541, nil, 1044, nil, nil, 1044, nil, nil, 1044, + 1044, nil, nil, 1044, nil, 1044, 541, nil, 541, 1044, + 541, 541, nil, 541, 541, nil, nil, nil, 1044, nil, + nil, nil, nil, 1044, 1044, 1044, 1044, nil, 1044, 1044, + 1044, 1044, nil, nil, nil, nil, 1044, 1044, nil, nil, + nil, nil, nil, nil, 1044, nil, 1044, 1044, 1044, nil, + nil, 1044, 1044, 1050, 1050, 1050, 1050, 1050, 1050, nil, + nil, nil, 1050, 1050, nil, nil, nil, 1050, nil, 1050, + 1050, 1050, 1050, 1050, 1050, 1050, nil, nil, nil, nil, + nil, 1050, 1050, 1050, 1050, 1050, 1050, 1050, nil, nil, + 1050, nil, nil, nil, nil, nil, 1050, 1050, 1050, 1050, + 1050, 1050, 1050, 1050, 1050, 1050, 1050, 1050, nil, 1050, + 1050, 1050, nil, 1050, 1050, 1050, 1050, 1050, 542, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 542, 542, nil, 1050, nil, nil, + 1050, nil, nil, 1050, 1050, nil, nil, 1050, nil, 1050, + 542, nil, 542, 1050, 542, 542, nil, 542, 542, nil, + nil, nil, 1050, nil, nil, nil, nil, 1050, 1050, 1050, + 1050, nil, 1050, 1050, 1050, 1050, nil, nil, nil, nil, + 1050, 1050, nil, nil, nil, nil, nil, nil, 1050, nil, + 1050, 1050, 1050, nil, nil, 1050, 1050, 1113, 1113, 1113, + 1113, 1113, 1113, nil, nil, nil, 1113, 1113, nil, nil, + nil, 1113, nil, 1113, 1113, 1113, 1113, 1113, 1113, 1113, + nil, nil, nil, nil, nil, 1113, 1113, 1113, 1113, 1113, + 1113, 1113, nil, nil, 1113, nil, nil, nil, nil, nil, + 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, + 1113, 1113, nil, 1113, 1113, 1113, nil, 1113, 1113, 1113, + 1113, 1113, 543, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 543, 543, + nil, 1113, nil, nil, 1113, nil, nil, 1113, 1113, nil, + nil, 1113, nil, 1113, 543, nil, nil, 1113, 543, 543, + nil, 543, 543, nil, nil, nil, 1113, nil, nil, nil, + nil, 1113, 1113, 1113, 1113, nil, 1113, 1113, 1113, 1113, + nil, nil, nil, nil, 1113, 1113, nil, nil, nil, nil, + nil, nil, 1113, nil, 1113, 1113, 1113, nil, nil, 1113, + 1113, 1235, 1235, 1235, 1235, 1235, 1235, nil, nil, nil, + 1235, 1235, nil, nil, nil, 1235, nil, 1235, 1235, 1235, + 1235, 1235, 1235, 1235, nil, nil, nil, nil, nil, 1235, + 1235, 1235, 1235, 1235, 1235, 1235, nil, nil, 1235, nil, + nil, nil, nil, nil, 1235, 1235, 1235, 1235, 1235, 1235, + 1235, 1235, 1235, 1235, 1235, 1235, nil, 1235, 1235, 1235, + nil, 1235, 1235, 1235, 1235, 1235, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 1235, nil, nil, 1235, nil, + nil, 1235, 1235, nil, nil, 1235, nil, 1235, nil, nil, + nil, 1235, nil, nil, nil, nil, nil, nil, nil, nil, + 1235, nil, nil, nil, nil, 1235, 1235, 1235, 1235, nil, + 1235, 1235, 1235, 1235, nil, nil, nil, nil, 1235, 1235, + nil, nil, nil, nil, nil, nil, 1235, nil, 1235, 1235, + 1235, nil, nil, 1235, 1235, 7, 7, 7, 7, 7, + nil, nil, nil, 7, 7, nil, nil, nil, 7, nil, + 7, 7, 7, 7, 7, 7, 7, nil, nil, nil, + nil, nil, 7, 7, 7, 7, 7, 7, 7, nil, + nil, 7, nil, nil, nil, nil, nil, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, nil, + 7, 7, 7, nil, 7, 7, 7, 7, 7, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 7, nil, + nil, 7, nil, nil, 7, 7, nil, nil, 7, nil, + 7, nil, nil, nil, 7, nil, nil, nil, nil, nil, + nil, nil, nil, 7, nil, nil, nil, nil, 7, 7, + 7, 7, nil, 7, 7, 7, 7, nil, nil, nil, + nil, 7, 7, nil, nil, nil, 24, 24, 24, 7, + 24, 7, 7, 7, 24, 24, 7, 7, nil, 24, + nil, 24, 24, 24, 24, 24, 24, 24, nil, nil, + nil, nil, nil, 24, 24, 24, 24, 24, 24, 24, + nil, nil, 24, nil, nil, nil, nil, nil, nil, 24, + nil, nil, 24, 24, 24, 24, 24, 24, 24, 24, + nil, 24, 24, 24, nil, 24, 24, 24, 24, 24, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 24, + nil, nil, 24, nil, nil, 24, 24, nil, nil, 24, + nil, nil, nil, nil, nil, 24, nil, nil, nil, nil, + nil, nil, nil, nil, 24, nil, nil, nil, nil, 24, + 24, 24, 24, nil, 24, 24, 24, 24, nil, nil, + nil, nil, 24, 24, nil, nil, nil, nil, nil, nil, + 24, nil, 24, 24, 24, 32, nil, 24, 24, nil, + nil, nil, 32, 32, 32, nil, nil, 32, 32, 32, + nil, 32, nil, nil, nil, nil, nil, nil, nil, 32, + 32, 32, 32, nil, nil, nil, nil, nil, nil, nil, + nil, 32, 32, nil, 32, 32, 32, 32, 32, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, nil, nil, 32, 32, 32, + nil, nil, 32, nil, 32, 32, nil, nil, 32, 32, + nil, 32, nil, 32, nil, 32, nil, 32, 32, nil, + 32, 32, 32, 32, 32, 33, 32, 32, 32, nil, + nil, nil, 33, 33, 33, nil, nil, 33, 33, 33, + nil, 33, 32, nil, nil, 32, 32, nil, 32, 33, + 32, 33, 33, nil, nil, nil, nil, 32, nil, nil, + nil, 33, 33, nil, 33, 33, 33, 33, 33, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, nil, nil, 33, 33, 33, + nil, nil, 33, nil, 33, 33, nil, nil, 33, 33, + nil, 33, nil, 33, nil, 33, nil, 33, 33, nil, + 33, 33, 33, 33, 33, nil, 33, nil, 33, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 33, nil, nil, 33, 33, nil, 33, nil, + 33, 34, 34, 34, nil, 34, nil, 33, nil, 34, + 34, nil, nil, nil, 34, nil, 34, 34, 34, 34, + 34, 34, 34, nil, nil, nil, nil, nil, 34, 34, + 34, 34, 34, 34, 34, nil, nil, 34, nil, nil, + nil, nil, nil, nil, 34, nil, nil, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, nil, + 34, 34, 34, 34, 34, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 34, nil, nil, 34, nil, nil, + 34, 34, nil, nil, 34, nil, 34, nil, 34, nil, + 34, nil, nil, 34, nil, nil, nil, nil, nil, 34, + nil, nil, nil, nil, 34, 34, 34, 34, nil, 34, + 34, 34, 34, nil, nil, nil, nil, 34, 34, nil, + nil, nil, 35, 35, 35, 34, 35, 34, 34, 34, + 35, 35, 34, 34, nil, 35, nil, 35, 35, 35, + 35, 35, 35, 35, nil, nil, nil, nil, nil, 35, + 35, 35, 35, 35, 35, 35, nil, nil, 35, nil, + nil, nil, nil, nil, nil, 35, nil, nil, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + nil, 35, 35, 35, 35, 35, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 35, nil, nil, 35, nil, + nil, 35, 35, nil, nil, 35, nil, 35, nil, 35, + nil, 35, nil, nil, 35, nil, nil, nil, nil, nil, + 35, nil, nil, nil, nil, 35, 35, 35, 35, nil, + 35, 35, 35, 35, nil, nil, nil, nil, 35, 35, + nil, nil, nil, 36, 36, 36, 35, 36, 35, 35, + 35, 36, 36, 35, 35, nil, 36, nil, 36, 36, + 36, 36, 36, 36, 36, nil, nil, nil, nil, nil, + 36, 36, 36, 36, 36, 36, 36, nil, nil, 36, + nil, nil, nil, nil, nil, nil, 36, nil, nil, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, nil, 36, 36, 36, 36, 36, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 36, nil, nil, 36, + nil, nil, 36, 36, nil, nil, 36, nil, 36, nil, + 36, nil, 36, nil, nil, 36, nil, nil, nil, nil, + nil, 36, nil, nil, nil, nil, 36, 36, 36, 36, + nil, 36, 36, 36, 36, nil, nil, nil, nil, 36, + 36, nil, nil, nil, 46, 46, 46, 36, 46, 36, + 36, 36, 46, 46, 36, 36, nil, 46, nil, 46, + 46, 46, 46, 46, 46, 46, nil, nil, nil, nil, + nil, 46, 46, 46, 46, 46, 46, 46, nil, nil, + 46, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 46, 46, 46, 46, 46, 46, 46, 46, nil, 46, + 46, 46, nil, 46, 46, 46, 46, 46, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 46, nil, nil, + 46, nil, nil, 46, 46, nil, nil, 46, nil, nil, + nil, nil, nil, 46, nil, nil, nil, nil, nil, nil, + nil, nil, 46, nil, nil, nil, nil, 46, 46, 46, + 46, nil, 46, 46, 46, 46, nil, nil, nil, nil, + 46, 46, nil, nil, nil, 47, 47, 47, 46, 47, + 46, 46, 46, 47, 47, 46, 46, nil, 47, nil, + 47, 47, 47, 47, 47, 47, 47, nil, nil, nil, + nil, nil, 47, 47, 47, 47, 47, 47, 47, nil, + nil, 47, nil, nil, nil, nil, nil, nil, 47, nil, + nil, 47, 47, 47, 47, 47, 47, 47, 47, nil, + 47, 47, 47, nil, 47, 47, 47, 47, 47, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 47, nil, + nil, 47, nil, nil, 47, 47, nil, nil, 47, nil, + nil, nil, nil, nil, 47, nil, nil, nil, nil, nil, + nil, nil, nil, 47, nil, nil, nil, nil, 47, 47, + 47, 47, nil, 47, 47, 47, 47, nil, nil, nil, + nil, 47, 47, nil, nil, nil, 49, 49, 49, 47, + 49, 47, 47, 47, 49, 49, 47, 47, nil, 49, + nil, 49, 49, 49, 49, 49, 49, 49, nil, nil, + nil, nil, nil, 49, 49, 49, 49, 49, 49, 49, + nil, nil, 49, nil, nil, nil, nil, nil, nil, 49, + nil, nil, 49, 49, 49, 49, 49, 49, 49, 49, + nil, 49, 49, 49, nil, 49, 49, 49, 49, 49, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 49, + nil, nil, 49, nil, nil, 49, 49, nil, nil, 49, + nil, nil, nil, nil, nil, 49, nil, nil, nil, nil, + nil, nil, nil, nil, 49, nil, nil, nil, nil, 49, + 49, 49, 49, nil, 49, 49, 49, 49, nil, nil, + nil, nil, 49, 49, nil, nil, nil, 50, 50, 50, + 49, 50, 49, 49, 49, 50, 50, 49, 49, nil, + 50, nil, 50, 50, 50, 50, 50, 50, 50, nil, + nil, nil, nil, nil, 50, 50, 50, 50, 50, 50, + 50, nil, nil, 50, nil, nil, nil, nil, nil, nil, + 50, nil, nil, 50, 50, 50, 50, 50, 50, 50, + 50, nil, 50, 50, 50, nil, 50, 50, 50, 50, + 50, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 50, nil, nil, 50, nil, nil, 50, 50, nil, nil, + 50, nil, nil, nil, nil, nil, 50, nil, nil, nil, + nil, nil, nil, nil, nil, 50, nil, nil, nil, nil, + 50, 50, 50, 50, nil, 50, 50, 50, 50, nil, + nil, nil, nil, 50, 50, nil, nil, nil, 52, 52, + 52, 50, 52, 50, 50, 50, 52, 52, 50, 50, + nil, 52, nil, 52, 52, 52, 52, 52, 52, 52, + nil, nil, nil, nil, nil, 52, 52, 52, 52, 52, + 52, 52, nil, nil, 52, nil, nil, nil, nil, nil, + nil, 52, nil, nil, 52, 52, 52, 52, 52, 52, + 52, 52, nil, 52, 52, 52, nil, 52, 52, 52, + 52, 52, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 52, nil, nil, 52, nil, nil, 52, 52, nil, + nil, 52, nil, nil, nil, nil, nil, 52, nil, nil, + nil, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, 52, 52, 52, 52, nil, 52, 52, 52, 52, + nil, nil, nil, nil, 52, 52, nil, nil, nil, nil, + nil, nil, 52, nil, 52, 52, 52, 64, nil, 52, + 52, nil, nil, nil, 64, 64, 64, nil, nil, 64, + 64, 64, nil, 64, nil, nil, nil, nil, nil, nil, + nil, 64, nil, 64, 64, 64, nil, nil, nil, nil, + nil, nil, nil, 64, 64, nil, 64, 64, 64, 64, + 64, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, nil, nil, 64, + 64, 64, nil, nil, 64, nil, nil, 64, nil, nil, + 64, 64, nil, 64, nil, 64, nil, 64, nil, 64, + 64, nil, 64, 64, 64, 64, 64, nil, 64, nil, + 64, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 64, nil, nil, 64, 64, 64, + 64, nil, 64, nil, 64, nil, 67, 67, 67, 64, + 67, nil, nil, nil, 67, 67, nil, nil, nil, 67, + nil, 67, 67, 67, 67, 67, 67, 67, nil, nil, + nil, nil, nil, 67, 67, 67, 67, 67, 67, 67, + nil, nil, 67, nil, nil, nil, nil, nil, nil, 67, + nil, nil, 67, 67, 67, 67, 67, 67, 67, 67, + 67, 67, 67, 67, nil, 67, 67, 67, 67, 67, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 67, + nil, nil, 67, nil, nil, 67, 67, nil, nil, 67, + nil, 67, nil, nil, nil, 67, nil, nil, 67, nil, + nil, nil, nil, nil, 67, nil, nil, nil, nil, 67, + 67, 67, 67, nil, 67, 67, 67, 67, nil, nil, + nil, nil, 67, 67, nil, nil, nil, 68, 68, 68, + 67, 68, 67, 67, 67, 68, 68, 67, 67, nil, + 68, nil, 68, 68, 68, 68, 68, 68, 68, nil, + nil, nil, nil, nil, 68, 68, 68, 68, 68, 68, + 68, nil, nil, 68, nil, nil, nil, nil, nil, nil, + 68, nil, nil, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, nil, 68, 68, 68, 68, + 68, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 68, nil, nil, 68, nil, nil, 68, 68, nil, nil, + 68, nil, nil, nil, nil, nil, 68, nil, nil, 68, + nil, nil, nil, nil, nil, 68, nil, nil, nil, nil, + 68, 68, 68, 68, nil, 68, 68, 68, 68, nil, + nil, nil, nil, 68, 68, nil, nil, nil, 71, 71, + 71, 68, 71, 68, 68, 68, 71, 71, 68, 68, + nil, 71, nil, 71, 71, 71, 71, 71, 71, 71, + nil, nil, nil, nil, nil, 71, 71, 71, 71, 71, + 71, 71, nil, nil, 71, nil, nil, nil, nil, nil, + nil, 71, nil, nil, 71, 71, 71, 71, 71, 71, + 71, 71, nil, 71, 71, 71, nil, 71, 71, 71, + 71, 71, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 71, nil, nil, 71, nil, nil, 71, 71, nil, + nil, 71, nil, nil, nil, nil, nil, 71, nil, nil, + nil, nil, nil, nil, nil, nil, 71, nil, nil, nil, + nil, 71, 71, 71, 71, nil, 71, 71, 71, 71, + nil, nil, nil, nil, 71, 71, nil, nil, nil, 72, + 72, 72, 71, 72, 71, 71, 71, 72, 72, 71, + 71, nil, 72, nil, 72, 72, 72, 72, 72, 72, + 72, nil, nil, nil, nil, nil, 72, 72, 72, 72, + 72, 72, 72, nil, nil, 72, nil, nil, nil, nil, + nil, nil, 72, nil, nil, 72, 72, 72, 72, 72, + 72, 72, 72, nil, 72, 72, 72, nil, 72, 72, + 72, 72, 72, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 72, nil, nil, 72, nil, nil, 72, 72, + nil, nil, 72, nil, nil, nil, nil, nil, 72, nil, + nil, nil, nil, nil, nil, nil, nil, 72, nil, nil, + nil, nil, 72, 72, 72, 72, nil, 72, 72, 72, + 72, nil, nil, nil, nil, 72, 72, nil, nil, nil, + 75, 75, 75, 72, 75, 72, 72, 72, 75, 75, + 72, 72, nil, 75, nil, 75, 75, 75, 75, 75, + 75, 75, nil, nil, nil, nil, nil, 75, 75, 75, + 75, 75, 75, 75, nil, nil, 75, nil, nil, nil, + nil, nil, nil, 75, nil, nil, 75, 75, 75, 75, + 75, 75, 75, 75, nil, 75, 75, 75, nil, 75, + 75, 75, 75, 75, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 75, nil, nil, 75, nil, nil, 75, + 75, nil, nil, 75, nil, nil, nil, nil, nil, 75, + nil, nil, nil, nil, nil, nil, nil, nil, 75, nil, + nil, nil, nil, 75, 75, 75, 75, nil, 75, 75, + 75, 75, nil, nil, nil, nil, 75, 75, 75, nil, + nil, nil, nil, 75, 75, nil, 75, 75, 75, nil, + nil, 75, 75, 125, 125, 125, 125, 125, nil, nil, + nil, 125, 125, nil, nil, nil, 125, nil, 125, 125, + 125, 125, 125, 125, 125, nil, nil, nil, nil, nil, + 125, 125, 125, 125, 125, 125, 125, nil, nil, 125, + nil, nil, nil, nil, nil, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, nil, 125, 125, + 125, nil, 125, 125, 125, 125, 125, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 125, nil, nil, 125, + nil, nil, 125, 125, nil, nil, 125, nil, 125, nil, + nil, nil, 125, nil, nil, nil, nil, nil, nil, nil, + nil, 125, nil, nil, nil, nil, 125, 125, 125, 125, + nil, 125, 125, 125, 125, nil, nil, nil, nil, 125, + 125, nil, nil, nil, nil, nil, 125, 125, nil, 125, + 125, 125, nil, nil, 125, 125, 130, 130, 130, nil, + 130, nil, nil, nil, 130, 130, nil, nil, nil, 130, + nil, 130, 130, 130, 130, 130, 130, 130, nil, nil, + nil, nil, nil, 130, 130, 130, 130, 130, 130, 130, + nil, nil, 130, nil, nil, nil, nil, nil, nil, 130, + nil, nil, 130, 130, 130, 130, 130, 130, 130, 130, + nil, 130, 130, 130, nil, 130, 130, 130, 130, 130, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 130, + nil, nil, 130, nil, nil, 130, 130, nil, nil, 130, + nil, nil, nil, nil, nil, 130, nil, nil, nil, nil, + nil, nil, nil, nil, 130, nil, nil, nil, nil, 130, + 130, 130, 130, nil, 130, 130, 130, 130, nil, nil, + nil, nil, 130, 130, nil, nil, nil, 131, 131, 131, + 130, 131, 130, 130, 130, 131, 131, 130, 130, nil, + 131, nil, 131, 131, 131, 131, 131, 131, 131, nil, + nil, nil, nil, nil, 131, 131, 131, 131, 131, 131, + 131, nil, nil, 131, nil, nil, nil, nil, nil, nil, + 131, nil, nil, 131, 131, 131, 131, 131, 131, 131, + 131, nil, 131, 131, 131, nil, 131, 131, 131, 131, + 131, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 131, nil, nil, 131, nil, nil, 131, 131, nil, nil, + 131, nil, nil, nil, nil, nil, 131, nil, nil, nil, + nil, nil, nil, nil, nil, 131, nil, nil, nil, nil, + 131, 131, 131, 131, nil, 131, 131, 131, 131, nil, + nil, nil, nil, 131, 131, nil, nil, nil, 132, 132, + 132, 131, 132, 131, 131, 131, 132, 132, 131, 131, + nil, 132, nil, 132, 132, 132, 132, 132, 132, 132, + nil, nil, nil, nil, nil, 132, 132, 132, 132, 132, + 132, 132, nil, nil, 132, nil, nil, nil, nil, nil, + nil, 132, nil, nil, 132, 132, 132, 132, 132, 132, + 132, 132, nil, 132, 132, 132, nil, 132, 132, 132, + 132, 132, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 132, nil, nil, 132, nil, nil, 132, 132, nil, + nil, 132, nil, nil, nil, nil, nil, 132, nil, nil, + nil, nil, nil, nil, nil, nil, 132, nil, nil, nil, + nil, 132, 132, 132, 132, nil, 132, 132, 132, 132, + nil, nil, nil, nil, 132, 132, nil, nil, nil, 133, + 133, 133, 132, 133, 132, 132, 132, 133, 133, 132, + 132, nil, 133, nil, 133, 133, 133, 133, 133, 133, + 133, nil, nil, nil, nil, nil, 133, 133, 133, 133, + 133, 133, 133, nil, nil, 133, nil, nil, nil, nil, + nil, nil, 133, nil, nil, 133, 133, 133, 133, 133, + 133, 133, 133, nil, 133, 133, 133, nil, 133, 133, + 133, 133, 133, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 133, nil, nil, 133, nil, nil, 133, 133, + nil, nil, 133, nil, nil, nil, nil, nil, 133, nil, + nil, nil, nil, nil, nil, nil, nil, 133, nil, nil, + nil, nil, 133, 133, 133, 133, nil, 133, 133, 133, + 133, nil, nil, nil, nil, 133, 133, nil, nil, nil, + nil, nil, nil, 133, nil, 133, 133, 133, nil, nil, + 133, 133, 134, 134, 134, 134, 134, nil, nil, nil, + 134, 134, nil, nil, nil, 134, nil, 134, 134, 134, + 134, 134, 134, 134, nil, nil, nil, nil, nil, 134, + 134, 134, 134, 134, 134, 134, nil, nil, 134, nil, + nil, nil, nil, nil, 134, 134, nil, 134, 134, 134, + 134, 134, 134, 134, 134, 134, nil, 134, 134, 134, + nil, 134, 134, 134, 134, 134, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 134, nil, nil, 134, nil, + nil, 134, 134, nil, nil, 134, nil, 134, nil, nil, + nil, 134, nil, nil, nil, nil, nil, nil, nil, nil, + 134, nil, nil, nil, nil, 134, 134, 134, 134, nil, + 134, 134, 134, 134, nil, nil, nil, nil, 134, 134, + nil, nil, nil, 220, 220, 220, 134, 220, 134, 134, + 134, 220, 220, 134, 134, nil, 220, nil, 220, 220, + 220, 220, 220, 220, 220, nil, nil, nil, nil, nil, + 220, 220, 220, 220, 220, 220, 220, nil, nil, 220, + nil, nil, nil, nil, nil, nil, 220, nil, nil, 220, + 220, 220, 220, 220, 220, 220, 220, nil, 220, 220, + 220, nil, 220, 220, 220, 220, 220, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 220, nil, nil, 220, + nil, nil, 220, 220, nil, nil, 220, nil, 220, nil, + nil, nil, 220, nil, nil, nil, nil, nil, nil, nil, + nil, 220, nil, nil, nil, nil, 220, 220, 220, 220, + nil, 220, 220, 220, 220, nil, nil, nil, nil, 220, + 220, nil, nil, nil, 221, 221, 221, 220, 221, 220, + 220, 220, 221, 221, 220, 220, nil, 221, nil, 221, + 221, 221, 221, 221, 221, 221, nil, nil, nil, nil, + nil, 221, 221, 221, 221, 221, 221, 221, nil, nil, + 221, nil, nil, nil, nil, nil, nil, 221, nil, nil, + 221, 221, 221, 221, 221, 221, 221, 221, nil, 221, + 221, 221, nil, 221, 221, 221, 221, 221, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 221, nil, nil, + 221, nil, nil, 221, 221, nil, nil, 221, nil, 221, + nil, nil, nil, 221, nil, nil, nil, nil, nil, nil, + nil, nil, 221, nil, nil, nil, nil, 221, 221, 221, + 221, nil, 221, 221, 221, 221, nil, nil, nil, nil, + 221, 221, nil, nil, nil, 222, 222, 222, 221, 222, + 221, 221, 221, 222, 222, 221, 221, nil, 222, nil, + 222, 222, 222, 222, 222, 222, 222, nil, nil, nil, + nil, nil, 222, 222, 222, 222, 222, 222, 222, nil, + nil, 222, nil, nil, nil, nil, nil, nil, 222, nil, + nil, 222, 222, 222, 222, 222, 222, 222, 222, nil, + 222, 222, 222, nil, 222, 222, 222, 222, 222, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 222, nil, + nil, 222, nil, nil, 222, 222, nil, nil, 222, nil, + nil, nil, nil, nil, 222, nil, nil, nil, nil, nil, + nil, nil, nil, 222, nil, nil, nil, nil, 222, 222, + 222, 222, nil, 222, 222, 222, 222, nil, nil, nil, + nil, 222, 222, nil, nil, nil, 223, 223, 223, 222, + 223, 222, 222, 222, 223, 223, 222, 222, nil, 223, + nil, 223, 223, 223, 223, 223, 223, 223, nil, nil, + nil, nil, nil, 223, 223, 223, 223, 223, 223, 223, + nil, nil, 223, nil, nil, nil, nil, nil, nil, 223, + nil, nil, 223, 223, 223, 223, 223, 223, 223, 223, + nil, 223, 223, 223, nil, 223, 223, 223, 223, 223, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 223, + nil, nil, 223, nil, nil, 223, 223, nil, nil, 223, + nil, nil, nil, nil, nil, 223, nil, nil, nil, nil, + nil, nil, nil, nil, 223, nil, nil, nil, nil, 223, + 223, 223, 223, nil, 223, 223, 223, 223, nil, nil, + nil, nil, 223, 223, nil, nil, nil, 224, 224, 224, + 223, 224, 223, 223, 223, 224, 224, 223, 223, nil, + 224, nil, 224, 224, 224, 224, 224, 224, 224, nil, + nil, nil, nil, nil, 224, 224, 224, 224, 224, 224, + 224, nil, nil, 224, nil, nil, nil, nil, nil, nil, + 224, nil, nil, 224, 224, 224, 224, 224, 224, 224, + 224, nil, 224, 224, 224, nil, 224, 224, 224, 224, + 224, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 224, nil, nil, 224, nil, nil, 224, 224, nil, nil, + 224, nil, nil, nil, nil, nil, 224, nil, nil, nil, + nil, nil, nil, nil, nil, 224, nil, nil, nil, nil, + 224, 224, 224, 224, nil, 224, 224, 224, 224, nil, + nil, nil, nil, 224, 224, nil, nil, nil, 225, 225, + 225, 224, 225, 224, 224, 224, 225, 225, 224, 224, + nil, 225, nil, 225, 225, 225, 225, 225, 225, 225, + nil, nil, nil, nil, nil, 225, 225, 225, 225, 225, + 225, 225, nil, nil, 225, nil, nil, nil, nil, nil, + nil, 225, nil, nil, 225, 225, 225, 225, 225, 225, + 225, 225, 225, 225, 225, 225, nil, 225, 225, 225, + 225, 225, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 225, nil, nil, 225, nil, nil, 225, 225, nil, + nil, 225, nil, 225, nil, 225, nil, 225, nil, nil, + 225, nil, nil, nil, nil, nil, 225, nil, nil, nil, + nil, 225, 225, 225, 225, nil, 225, 225, 225, 225, + nil, nil, nil, nil, 225, 225, nil, nil, nil, 238, + 238, 238, 225, 238, 225, 225, 225, 238, 238, 225, + 225, nil, 238, nil, 238, 238, 238, 238, 238, 238, + 238, nil, nil, nil, nil, nil, 238, 238, 238, 238, + 238, 238, 238, nil, nil, 238, nil, nil, nil, nil, + nil, nil, 238, nil, nil, 238, 238, 238, 238, 238, + 238, 238, 238, nil, 238, 238, 238, nil, 238, 238, + 238, 238, 238, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 238, nil, nil, 238, nil, nil, 238, 238, + nil, nil, 238, nil, nil, nil, nil, nil, 238, nil, + nil, nil, nil, nil, nil, nil, nil, 238, nil, nil, + nil, nil, 238, 238, 238, 238, nil, 238, 238, 238, + 238, nil, nil, nil, nil, 238, 238, nil, nil, nil, + 239, 239, 239, 238, 239, 238, 238, 238, 239, 239, + 238, 238, nil, 239, nil, 239, 239, 239, 239, 239, + 239, 239, nil, nil, nil, nil, nil, 239, 239, 239, + 239, 239, 239, 239, nil, nil, 239, nil, nil, nil, + nil, nil, nil, 239, nil, nil, 239, 239, 239, 239, + 239, 239, 239, 239, nil, 239, 239, 239, nil, 239, + 239, 239, 239, 239, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 239, nil, nil, 239, nil, nil, 239, + 239, nil, nil, 239, nil, nil, nil, nil, nil, 239, + nil, nil, nil, nil, nil, nil, nil, nil, 239, nil, + nil, nil, nil, 239, 239, 239, 239, nil, 239, 239, + 239, 239, nil, nil, nil, nil, 239, 239, nil, nil, + nil, 240, 240, 240, 239, 240, 239, 239, 239, 240, + 240, 239, 239, nil, 240, nil, 240, 240, 240, 240, + 240, 240, 240, nil, nil, nil, nil, nil, 240, 240, + 240, 240, 240, 240, 240, nil, nil, 240, nil, nil, + nil, nil, nil, nil, 240, nil, nil, 240, 240, 240, + 240, 240, 240, 240, 240, nil, 240, 240, 240, nil, + 240, 240, 240, 240, 240, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 240, nil, nil, 240, nil, nil, + 240, 240, nil, nil, 240, nil, nil, nil, nil, nil, + 240, nil, nil, nil, nil, nil, nil, nil, nil, 240, + nil, nil, nil, nil, 240, 240, 240, 240, nil, 240, + 240, 240, 240, nil, nil, nil, nil, 240, 240, 240, + nil, nil, 251, 251, 251, 240, 251, 240, 240, 240, + 251, 251, 240, 240, nil, 251, nil, 251, 251, 251, + 251, 251, 251, 251, nil, nil, nil, nil, nil, 251, + 251, 251, 251, 251, 251, 251, nil, nil, 251, nil, + nil, nil, nil, nil, nil, 251, nil, nil, 251, 251, + 251, 251, 251, 251, 251, 251, nil, 251, 251, 251, + nil, 251, 251, 251, 251, 251, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 251, nil, nil, 251, nil, + nil, 251, 251, nil, nil, 251, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, nil, nil, nil, nil, + 251, nil, nil, nil, nil, 251, 251, 251, 251, nil, + 251, 251, 251, 251, nil, nil, nil, nil, 251, 251, + nil, nil, nil, 258, 258, 258, 251, 258, 251, 251, + 251, 258, 258, 251, 251, nil, 258, nil, 258, 258, + 258, 258, 258, 258, 258, nil, nil, nil, nil, nil, + 258, 258, 258, 258, 258, 258, 258, nil, nil, 258, + nil, nil, nil, nil, nil, nil, 258, nil, nil, 258, + 258, 258, 258, 258, 258, 258, 258, nil, 258, 258, + 258, nil, 258, 258, 258, 258, 258, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 258, nil, nil, 258, + nil, nil, 258, 258, nil, nil, 258, nil, nil, nil, + nil, nil, 258, nil, nil, nil, nil, nil, nil, nil, + nil, 258, nil, nil, nil, nil, 258, 258, 258, 258, + nil, 258, 258, 258, 258, nil, nil, nil, nil, 258, + 258, nil, nil, nil, 259, 259, 259, 258, 259, 258, + 258, 258, 259, 259, 258, 258, nil, 259, nil, 259, + 259, 259, 259, 259, 259, 259, nil, nil, nil, nil, + nil, 259, 259, 259, 259, 259, 259, 259, nil, nil, + 259, nil, nil, nil, nil, nil, nil, 259, nil, nil, + 259, 259, 259, 259, 259, 259, 259, 259, nil, 259, + 259, 259, nil, 259, 259, 259, 259, 259, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 259, nil, nil, + 259, nil, nil, 259, 259, nil, nil, 259, nil, nil, + nil, nil, nil, 259, nil, nil, nil, nil, nil, nil, + nil, nil, 259, nil, nil, nil, nil, 259, 259, 259, + 259, nil, 259, 259, 259, 259, nil, nil, nil, nil, + 259, 259, nil, nil, nil, 260, 260, 260, 259, 260, + 259, 259, 259, 260, 260, 259, 259, nil, 260, nil, + 260, 260, 260, 260, 260, 260, 260, nil, nil, nil, + nil, nil, 260, 260, 260, 260, 260, 260, 260, nil, + nil, 260, nil, nil, nil, nil, nil, nil, 260, nil, + nil, 260, 260, 260, 260, 260, 260, 260, 260, nil, + 260, 260, 260, nil, 260, 260, 260, 260, 260, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 260, nil, + nil, 260, nil, nil, 260, 260, nil, nil, 260, nil, + nil, nil, nil, nil, 260, nil, nil, nil, nil, nil, + nil, nil, nil, 260, nil, nil, nil, nil, 260, 260, + 260, 260, nil, 260, 260, 260, 260, nil, nil, nil, + nil, 260, 260, nil, nil, nil, 261, 261, 261, 260, + 261, 260, 260, 260, 261, 261, 260, 260, nil, 261, + nil, 261, 261, 261, 261, 261, 261, 261, nil, nil, + nil, nil, nil, 261, 261, 261, 261, 261, 261, 261, + nil, nil, 261, nil, nil, nil, nil, nil, nil, 261, + nil, nil, 261, 261, 261, 261, 261, 261, 261, 261, + nil, 261, 261, 261, nil, 261, 261, 261, 261, 261, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 261, + nil, nil, 261, nil, nil, 261, 261, nil, nil, 261, + nil, nil, nil, nil, nil, 261, nil, nil, nil, nil, + nil, nil, nil, nil, 261, nil, nil, nil, nil, 261, + 261, 261, 261, nil, 261, 261, 261, 261, nil, nil, + nil, nil, 261, 261, nil, nil, nil, 262, 262, 262, + 261, 262, 261, 261, 261, 262, 262, 261, 261, nil, + 262, nil, 262, 262, 262, 262, 262, 262, 262, nil, + nil, nil, nil, nil, 262, 262, 262, 262, 262, 262, + 262, nil, nil, 262, nil, nil, nil, nil, nil, nil, + 262, nil, nil, 262, 262, 262, 262, 262, 262, 262, + 262, nil, 262, 262, 262, nil, 262, 262, 262, 262, + 262, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 262, nil, nil, 262, nil, nil, 262, 262, nil, nil, + 262, nil, nil, nil, nil, nil, 262, nil, nil, nil, + nil, nil, nil, nil, nil, 262, nil, nil, nil, nil, + 262, 262, 262, 262, nil, 262, 262, 262, 262, nil, + nil, nil, nil, 262, 262, nil, nil, nil, 263, 263, + 263, 262, 263, 262, 262, 262, 263, 263, 262, 262, + nil, 263, nil, 263, 263, 263, 263, 263, 263, 263, + nil, nil, nil, nil, nil, 263, 263, 263, 263, 263, + 263, 263, nil, nil, 263, nil, nil, nil, nil, nil, + nil, 263, nil, nil, 263, 263, 263, 263, 263, 263, + 263, 263, nil, 263, 263, 263, nil, 263, 263, 263, + 263, 263, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 263, nil, nil, 263, nil, nil, 263, 263, nil, + nil, 263, nil, nil, nil, nil, nil, 263, nil, nil, + nil, nil, nil, nil, nil, nil, 263, nil, nil, nil, + nil, 263, 263, 263, 263, nil, 263, 263, 263, 263, + nil, nil, nil, nil, 263, 263, nil, nil, nil, 264, + 264, 264, 263, 264, 263, 263, 263, 264, 264, 263, + 263, nil, 264, nil, 264, 264, 264, 264, 264, 264, + 264, nil, nil, nil, nil, nil, 264, 264, 264, 264, + 264, 264, 264, nil, nil, 264, nil, nil, nil, nil, + nil, nil, 264, nil, nil, 264, 264, 264, 264, 264, + 264, 264, 264, nil, 264, 264, 264, nil, 264, 264, + 264, 264, 264, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 264, nil, nil, 264, nil, nil, 264, 264, + nil, nil, 264, nil, nil, nil, nil, nil, 264, nil, + nil, nil, nil, nil, nil, nil, nil, 264, nil, nil, + nil, nil, 264, 264, 264, 264, nil, 264, 264, 264, + 264, nil, nil, nil, nil, 264, 264, nil, nil, nil, + 265, 265, 265, 264, 265, 264, 264, 264, 265, 265, + 264, 264, nil, 265, nil, 265, 265, 265, 265, 265, + 265, 265, nil, nil, nil, nil, nil, 265, 265, 265, + 265, 265, 265, 265, nil, nil, 265, nil, nil, nil, + nil, nil, nil, 265, nil, nil, 265, 265, 265, 265, + 265, 265, 265, 265, nil, 265, 265, 265, nil, 265, + 265, 265, 265, 265, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 265, nil, nil, 265, nil, nil, 265, + 265, nil, nil, 265, nil, nil, nil, nil, nil, 265, + nil, nil, nil, nil, nil, nil, nil, nil, 265, nil, + nil, nil, nil, 265, 265, 265, 265, nil, 265, 265, + 265, 265, nil, nil, nil, nil, 265, 265, nil, nil, + nil, 266, 266, 266, 265, 266, 265, 265, 265, 266, + 266, 265, 265, nil, 266, nil, 266, 266, 266, 266, + 266, 266, 266, nil, nil, nil, nil, nil, 266, 266, + 266, 266, 266, 266, 266, nil, nil, 266, nil, nil, + nil, nil, nil, nil, 266, nil, nil, 266, 266, 266, + 266, 266, 266, 266, 266, nil, 266, 266, 266, nil, + 266, 266, 266, 266, 266, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 266, nil, nil, 266, nil, nil, + 266, 266, nil, nil, 266, nil, nil, nil, nil, nil, + 266, nil, nil, nil, nil, nil, nil, nil, nil, 266, + nil, nil, nil, nil, 266, 266, 266, 266, nil, 266, + 266, 266, 266, nil, nil, nil, nil, 266, 266, nil, + nil, nil, 267, 267, 267, 266, 267, 266, 266, 266, + 267, 267, 266, 266, nil, 267, nil, 267, 267, 267, + 267, 267, 267, 267, nil, nil, nil, nil, nil, 267, + 267, 267, 267, 267, 267, 267, nil, nil, 267, nil, + nil, nil, nil, nil, nil, 267, nil, nil, 267, 267, + 267, 267, 267, 267, 267, 267, nil, 267, 267, 267, + nil, 267, 267, 267, 267, 267, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 267, nil, nil, 267, nil, + nil, 267, 267, nil, nil, 267, nil, nil, nil, nil, + nil, 267, nil, nil, nil, nil, nil, nil, nil, nil, + 267, nil, nil, nil, nil, 267, 267, 267, 267, nil, + 267, 267, 267, 267, nil, nil, nil, nil, 267, 267, + nil, nil, nil, 268, 268, 268, 267, 268, 267, 267, + 267, 268, 268, 267, 267, nil, 268, nil, 268, 268, + 268, 268, 268, 268, 268, nil, nil, nil, nil, nil, + 268, 268, 268, 268, 268, 268, 268, nil, nil, 268, + nil, nil, nil, nil, nil, nil, 268, nil, nil, 268, + 268, 268, 268, 268, 268, 268, 268, nil, 268, 268, + 268, nil, 268, 268, 268, 268, 268, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 268, nil, nil, 268, + nil, nil, 268, 268, nil, nil, 268, nil, nil, nil, + nil, nil, 268, nil, nil, nil, nil, nil, nil, nil, + nil, 268, nil, nil, nil, nil, 268, 268, 268, 268, + nil, 268, 268, 268, 268, nil, nil, nil, nil, 268, + 268, nil, nil, nil, 269, 269, 269, 268, 269, 268, + 268, 268, 269, 269, 268, 268, nil, 269, nil, 269, + 269, 269, 269, 269, 269, 269, nil, nil, nil, nil, + nil, 269, 269, 269, 269, 269, 269, 269, nil, nil, + 269, nil, nil, nil, nil, nil, nil, 269, nil, nil, + 269, 269, 269, 269, 269, 269, 269, 269, nil, 269, + 269, 269, nil, 269, 269, 269, 269, 269, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 269, nil, nil, + 269, nil, nil, 269, 269, nil, nil, 269, nil, nil, + nil, nil, nil, 269, nil, nil, nil, nil, nil, nil, + nil, nil, 269, nil, nil, nil, nil, 269, 269, 269, + 269, nil, 269, 269, 269, 269, nil, nil, nil, nil, + 269, 269, nil, nil, nil, 270, 270, 270, 269, 270, + 269, 269, 269, 270, 270, 269, 269, nil, 270, nil, + 270, 270, 270, 270, 270, 270, 270, nil, nil, nil, + nil, nil, 270, 270, 270, 270, 270, 270, 270, nil, + nil, 270, nil, nil, nil, nil, nil, nil, 270, nil, + nil, 270, 270, 270, 270, 270, 270, 270, 270, nil, + 270, 270, 270, nil, 270, 270, 270, 270, 270, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 270, nil, + nil, 270, nil, nil, 270, 270, nil, nil, 270, nil, + nil, nil, nil, nil, 270, nil, nil, nil, nil, nil, + nil, nil, nil, 270, nil, nil, nil, nil, 270, 270, + 270, 270, nil, 270, 270, 270, 270, nil, nil, nil, + nil, 270, 270, nil, nil, nil, 271, 271, 271, 270, + 271, 270, 270, 270, 271, 271, 270, 270, nil, 271, + nil, 271, 271, 271, 271, 271, 271, 271, nil, nil, + nil, nil, nil, 271, 271, 271, 271, 271, 271, 271, + nil, nil, 271, nil, nil, nil, nil, nil, nil, 271, + nil, nil, 271, 271, 271, 271, 271, 271, 271, 271, + nil, 271, 271, 271, nil, 271, 271, 271, 271, 271, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 271, + nil, nil, 271, nil, nil, 271, 271, nil, nil, 271, + nil, nil, nil, nil, nil, 271, nil, nil, nil, nil, + nil, nil, nil, nil, 271, nil, nil, nil, nil, 271, + 271, 271, 271, nil, 271, 271, 271, 271, nil, nil, + nil, nil, 271, 271, nil, nil, nil, 272, 272, 272, + 271, 272, 271, 271, 271, 272, 272, 271, 271, nil, + 272, nil, 272, 272, 272, 272, 272, 272, 272, nil, + nil, nil, nil, nil, 272, 272, 272, 272, 272, 272, + 272, nil, nil, 272, nil, nil, nil, nil, nil, nil, + 272, nil, nil, 272, 272, 272, 272, 272, 272, 272, + 272, nil, 272, 272, 272, nil, 272, 272, 272, 272, + 272, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 272, nil, nil, 272, nil, nil, 272, 272, nil, nil, + 272, nil, nil, nil, nil, nil, 272, nil, nil, nil, + nil, nil, nil, nil, nil, 272, nil, nil, nil, nil, + 272, 272, 272, 272, nil, 272, 272, 272, 272, nil, + nil, nil, nil, 272, 272, nil, nil, nil, 273, 273, + 273, 272, 273, 272, 272, 272, 273, 273, 272, 272, + nil, 273, nil, 273, 273, 273, 273, 273, 273, 273, + nil, nil, nil, nil, nil, 273, 273, 273, 273, 273, + 273, 273, nil, nil, 273, nil, nil, nil, nil, nil, + nil, 273, nil, nil, 273, 273, 273, 273, 273, 273, + 273, 273, nil, 273, 273, 273, nil, 273, 273, 273, + 273, 273, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 273, nil, nil, 273, nil, nil, 273, 273, nil, + nil, 273, nil, nil, nil, nil, nil, 273, nil, nil, + nil, nil, nil, nil, nil, nil, 273, nil, nil, nil, + nil, 273, 273, 273, 273, nil, 273, 273, 273, 273, + nil, nil, nil, nil, 273, 273, nil, nil, nil, 274, + 274, 274, 273, 274, 273, 273, 273, 274, 274, 273, + 273, nil, 274, nil, 274, 274, 274, 274, 274, 274, + 274, nil, nil, nil, nil, nil, 274, 274, 274, 274, + 274, 274, 274, nil, nil, 274, nil, nil, nil, nil, + nil, nil, 274, nil, nil, 274, 274, 274, 274, 274, + 274, 274, 274, nil, 274, 274, 274, nil, 274, 274, + 274, 274, 274, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 274, nil, nil, 274, nil, nil, 274, 274, + nil, nil, 274, nil, nil, nil, nil, nil, 274, nil, + nil, nil, nil, nil, nil, nil, nil, 274, nil, nil, + nil, nil, 274, 274, 274, 274, nil, 274, 274, 274, + 274, nil, nil, nil, nil, 274, 274, nil, nil, nil, + 275, 275, 275, 274, 275, 274, 274, 274, 275, 275, + 274, 274, nil, 275, nil, 275, 275, 275, 275, 275, + 275, 275, nil, nil, nil, nil, nil, 275, 275, 275, + 275, 275, 275, 275, nil, nil, 275, nil, nil, nil, + nil, nil, nil, 275, nil, nil, 275, 275, 275, 275, + 275, 275, 275, 275, nil, 275, 275, 275, nil, 275, + 275, 275, 275, 275, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 275, nil, nil, 275, nil, nil, 275, + 275, nil, nil, 275, nil, nil, nil, nil, nil, 275, + nil, nil, nil, nil, nil, nil, nil, nil, 275, nil, + nil, nil, nil, 275, 275, 275, 275, nil, 275, 275, + 275, 275, nil, nil, nil, nil, 275, 275, nil, nil, + nil, 276, 276, 276, 275, 276, 275, 275, 275, 276, + 276, 275, 275, nil, 276, nil, 276, 276, 276, 276, + 276, 276, 276, nil, nil, nil, nil, nil, 276, 276, + 276, 276, 276, 276, 276, nil, nil, 276, nil, nil, + nil, nil, nil, nil, 276, nil, nil, 276, 276, 276, + 276, 276, 276, 276, 276, nil, 276, 276, 276, nil, + 276, 276, 276, 276, 276, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 276, nil, nil, 276, nil, nil, + 276, 276, nil, nil, 276, nil, nil, nil, nil, nil, + 276, nil, nil, nil, nil, nil, nil, nil, nil, 276, + nil, nil, nil, nil, 276, 276, 276, 276, nil, 276, + 276, 276, 276, nil, nil, nil, nil, 276, 276, nil, + nil, nil, 277, 277, 277, 276, 277, 276, 276, 276, + 277, 277, 276, 276, nil, 277, nil, 277, 277, 277, + 277, 277, 277, 277, nil, nil, nil, nil, nil, 277, + 277, 277, 277, 277, 277, 277, nil, nil, 277, nil, + nil, nil, nil, nil, nil, 277, nil, nil, 277, 277, + 277, 277, 277, 277, 277, 277, nil, 277, 277, 277, + nil, 277, 277, 277, 277, 277, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 277, nil, nil, 277, nil, + nil, 277, 277, nil, nil, 277, nil, nil, nil, nil, + nil, 277, nil, nil, nil, nil, nil, nil, nil, nil, + 277, nil, nil, nil, nil, 277, 277, 277, 277, nil, + 277, 277, 277, 277, nil, nil, nil, nil, 277, 277, + nil, nil, nil, 278, 278, 278, 277, 278, 277, 277, + 277, 278, 278, 277, 277, nil, 278, nil, 278, 278, + 278, 278, 278, 278, 278, nil, nil, nil, nil, nil, + 278, 278, 278, 278, 278, 278, 278, nil, nil, 278, + nil, nil, nil, nil, nil, nil, 278, nil, nil, 278, + 278, 278, 278, 278, 278, 278, 278, nil, 278, 278, + 278, nil, 278, 278, 278, 278, 278, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 278, nil, nil, 278, + nil, nil, 278, 278, nil, nil, 278, nil, nil, nil, + nil, nil, 278, nil, nil, nil, nil, nil, nil, nil, + nil, 278, nil, nil, nil, nil, 278, 278, 278, 278, + nil, 278, 278, 278, 278, nil, nil, nil, nil, 278, + 278, nil, nil, nil, 279, 279, 279, 278, 279, 278, + 278, 278, 279, 279, 278, 278, nil, 279, nil, 279, + 279, 279, 279, 279, 279, 279, nil, nil, nil, nil, + nil, 279, 279, 279, 279, 279, 279, 279, nil, nil, + 279, nil, nil, nil, nil, nil, nil, 279, nil, nil, + 279, 279, 279, 279, 279, 279, 279, 279, nil, 279, + 279, 279, nil, 279, 279, 279, 279, 279, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 279, nil, nil, + 279, nil, nil, 279, 279, nil, nil, 279, nil, nil, + nil, nil, nil, 279, nil, nil, nil, nil, nil, nil, + nil, nil, 279, nil, nil, nil, nil, 279, 279, 279, + 279, nil, 279, 279, 279, 279, nil, nil, nil, nil, + 279, 279, nil, nil, nil, 284, 284, 284, 279, 284, + 279, 279, 279, 284, 284, 279, 279, nil, 284, nil, + 284, 284, 284, 284, 284, 284, 284, nil, nil, nil, + nil, nil, 284, 284, 284, 284, 284, 284, 284, nil, + nil, 284, nil, nil, nil, nil, nil, nil, 284, nil, + nil, 284, 284, 284, 284, 284, 284, 284, 284, nil, + 284, 284, 284, nil, 284, 284, 284, 284, 284, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 284, nil, + nil, 284, nil, nil, 284, 284, nil, nil, 284, nil, + nil, nil, nil, nil, 284, nil, nil, nil, nil, nil, + nil, nil, nil, 284, nil, nil, nil, nil, 284, 284, + 284, 284, nil, 284, 284, 284, 284, nil, nil, nil, + nil, 284, 284, nil, nil, nil, 300, 300, 300, 284, + 300, 284, 284, 284, 300, 300, 284, 284, nil, 300, + nil, 300, 300, 300, 300, 300, 300, 300, nil, nil, + nil, nil, nil, 300, 300, 300, 300, 300, 300, 300, + nil, nil, 300, nil, nil, nil, nil, nil, nil, 300, + nil, nil, 300, 300, 300, 300, 300, 300, 300, 300, + nil, 300, 300, 300, nil, 300, 300, 300, 300, 300, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 300, + nil, nil, 300, nil, nil, 300, 300, nil, nil, 300, + nil, nil, nil, nil, nil, 300, nil, nil, nil, nil, + nil, nil, nil, nil, 300, nil, nil, nil, nil, 300, + 300, 300, 300, nil, 300, 300, 300, 300, nil, nil, + nil, nil, 300, 300, nil, nil, nil, 307, 307, 307, + 300, 307, 300, 300, 300, 307, 307, 300, 300, nil, + 307, nil, 307, 307, 307, 307, 307, 307, 307, nil, + nil, nil, nil, nil, 307, 307, 307, 307, 307, 307, + 307, nil, nil, 307, nil, nil, nil, nil, nil, nil, + 307, nil, nil, 307, 307, 307, 307, 307, 307, 307, + 307, 307, 307, 307, 307, nil, 307, 307, 307, 307, + 307, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 307, nil, nil, 307, nil, nil, 307, 307, nil, nil, + 307, nil, 307, nil, 307, nil, 307, nil, nil, 307, + nil, nil, nil, nil, nil, 307, nil, nil, nil, nil, + 307, 307, 307, 307, nil, 307, 307, 307, 307, nil, + nil, nil, nil, 307, 307, nil, nil, nil, 308, 308, + 308, 307, 308, 307, 307, 307, 308, 308, 307, 307, + nil, 308, nil, 308, 308, 308, 308, 308, 308, 308, + nil, nil, nil, nil, nil, 308, 308, 308, 308, 308, + 308, 308, nil, nil, 308, nil, nil, nil, nil, nil, + nil, 308, nil, nil, 308, 308, 308, 308, 308, 308, + 308, 308, 308, 308, 308, 308, nil, 308, 308, 308, + 308, 308, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 308, nil, nil, 308, nil, nil, 308, 308, nil, + nil, 308, nil, 308, nil, 308, nil, 308, nil, nil, + 308, nil, nil, nil, nil, nil, 308, nil, nil, nil, + nil, 308, 308, 308, 308, nil, 308, 308, 308, 308, + nil, nil, nil, nil, 308, 308, nil, nil, nil, 316, + 316, 316, 308, 316, 308, 308, 308, 316, 316, 308, + 308, nil, 316, nil, 316, 316, 316, 316, 316, 316, + 316, nil, nil, nil, nil, nil, 316, 316, 316, 316, + 316, 316, 316, nil, nil, 316, nil, nil, nil, nil, + nil, nil, 316, nil, nil, 316, 316, 316, 316, 316, + 316, 316, 316, 316, 316, 316, 316, nil, 316, 316, + 316, 316, 316, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 316, nil, nil, 316, nil, nil, 316, 316, + nil, nil, 316, nil, 316, nil, 316, nil, 316, nil, + nil, 316, nil, nil, nil, nil, nil, 316, nil, nil, + nil, nil, 316, 316, 316, 316, nil, 316, 316, 316, + 316, nil, nil, nil, nil, 316, 316, 316, nil, nil, + 323, 323, 323, 316, 323, 316, 316, 316, 323, 323, + 316, 316, nil, 323, nil, 323, 323, 323, 323, 323, + 323, 323, nil, nil, nil, nil, nil, 323, 323, 323, + 323, 323, 323, 323, nil, nil, 323, nil, nil, nil, + nil, nil, nil, 323, nil, nil, 323, 323, 323, 323, + 323, 323, 323, 323, nil, 323, 323, 323, nil, 323, + 323, 323, 323, 323, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 323, nil, nil, 323, nil, nil, 323, + 323, nil, nil, 323, nil, nil, nil, nil, nil, 323, + nil, nil, nil, nil, nil, nil, nil, nil, 323, nil, + nil, nil, nil, 323, 323, 323, 323, nil, 323, 323, + 323, 323, nil, nil, nil, nil, 323, 323, nil, nil, + nil, 326, 326, 326, 323, 326, 323, 323, 323, 326, + 326, 323, 323, nil, 326, nil, 326, 326, 326, 326, + 326, 326, 326, nil, nil, nil, nil, nil, 326, 326, + 326, 326, 326, 326, 326, nil, nil, 326, nil, nil, + nil, nil, nil, nil, 326, nil, nil, 326, 326, 326, + 326, 326, 326, 326, 326, nil, 326, 326, 326, nil, + 326, 326, 326, 326, 326, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 326, nil, nil, 326, nil, nil, + 326, 326, nil, nil, 326, nil, nil, nil, nil, nil, + 326, nil, nil, nil, nil, nil, nil, nil, nil, 326, + nil, nil, nil, nil, 326, 326, 326, 326, nil, 326, + 326, 326, 326, nil, nil, nil, nil, 326, 326, nil, + nil, nil, 329, 329, 329, 326, 329, 326, 326, 326, + 329, 329, 326, 326, nil, 329, nil, 329, 329, 329, + 329, 329, 329, 329, nil, nil, nil, nil, nil, 329, + 329, 329, 329, 329, 329, 329, nil, nil, 329, nil, + nil, nil, nil, nil, nil, 329, nil, nil, 329, 329, + 329, 329, 329, 329, 329, 329, nil, 329, 329, 329, + nil, 329, 329, 329, 329, 329, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 329, nil, nil, 329, nil, + nil, 329, 329, nil, nil, 329, nil, nil, nil, nil, + nil, 329, nil, nil, nil, nil, nil, nil, nil, nil, + 329, nil, nil, nil, nil, 329, 329, 329, 329, nil, + 329, 329, 329, 329, nil, nil, nil, nil, 329, 329, + nil, nil, nil, 330, 330, 330, 329, 330, 329, 329, + 329, 330, 330, 329, 329, nil, 330, nil, 330, 330, + 330, 330, 330, 330, 330, nil, nil, nil, nil, nil, + 330, 330, 330, 330, 330, 330, 330, nil, nil, 330, + nil, nil, nil, nil, nil, nil, 330, nil, nil, 330, + 330, 330, 330, 330, 330, 330, 330, nil, 330, 330, + 330, nil, 330, 330, 330, 330, 330, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 330, nil, nil, 330, + nil, nil, 330, 330, nil, nil, 330, nil, nil, nil, + nil, nil, 330, nil, nil, nil, nil, nil, nil, nil, + nil, 330, nil, nil, nil, nil, 330, 330, 330, 330, + nil, 330, 330, 330, 330, nil, nil, nil, nil, 330, + 330, nil, nil, nil, nil, nil, nil, 330, nil, 330, + 330, 330, nil, nil, 330, 330, 335, 335, 335, 335, + 335, nil, nil, nil, 335, 335, nil, nil, nil, 335, + nil, 335, 335, 335, 335, 335, 335, 335, nil, nil, + nil, nil, nil, 335, 335, 335, 335, 335, 335, 335, + nil, nil, 335, nil, nil, nil, nil, nil, 335, 335, + nil, 335, 335, 335, 335, 335, 335, 335, 335, 335, + nil, 335, 335, 335, nil, 335, 335, 335, 335, 335, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 335, + nil, nil, 335, nil, nil, 335, 335, nil, nil, 335, + nil, 335, nil, nil, nil, 335, nil, nil, nil, nil, + nil, nil, nil, nil, 335, nil, nil, nil, nil, 335, + 335, 335, 335, nil, 335, 335, 335, 335, nil, nil, + nil, nil, 335, 335, nil, nil, nil, 371, 371, 371, + 335, 371, 335, 335, 335, 371, 371, 335, 335, nil, + 371, nil, 371, 371, 371, 371, 371, 371, 371, nil, + nil, nil, nil, nil, 371, 371, 371, 371, 371, 371, + 371, nil, nil, 371, nil, nil, nil, nil, nil, nil, + 371, nil, nil, 371, 371, 371, 371, 371, 371, 371, + 371, nil, 371, 371, 371, nil, 371, 371, 371, 371, + 371, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 371, nil, nil, 371, nil, nil, 371, 371, nil, nil, + 371, nil, nil, nil, nil, nil, 371, nil, nil, nil, + nil, nil, nil, nil, nil, 371, nil, nil, nil, nil, + 371, 371, 371, 371, nil, 371, 371, 371, 371, nil, + nil, nil, nil, 371, 371, nil, nil, nil, 387, 387, + 387, 371, 387, 371, 371, 371, 387, 387, 371, 371, + nil, 387, nil, 387, 387, 387, 387, 387, 387, 387, + nil, nil, nil, nil, nil, 387, 387, 387, 387, 387, + 387, 387, nil, nil, 387, nil, nil, nil, nil, nil, + nil, 387, nil, nil, 387, 387, 387, 387, 387, 387, + 387, 387, nil, 387, 387, 387, nil, 387, 387, 387, + 387, 387, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 387, nil, nil, 387, nil, nil, 387, 387, nil, + nil, 387, nil, nil, nil, nil, nil, 387, nil, nil, + nil, nil, nil, nil, nil, nil, 387, nil, nil, nil, + nil, 387, 387, 387, 387, nil, 387, 387, 387, 387, + nil, nil, nil, nil, 387, 387, nil, nil, nil, 408, + 408, 408, 387, 408, 387, 387, 387, 408, 408, 387, + 387, nil, 408, nil, 408, 408, 408, 408, 408, 408, + 408, nil, nil, nil, nil, nil, 408, 408, 408, 408, + 408, 408, 408, nil, nil, 408, nil, nil, nil, nil, + nil, nil, 408, nil, nil, 408, 408, 408, 408, 408, + 408, 408, 408, nil, 408, 408, 408, nil, 408, 408, + 408, 408, 408, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 408, nil, nil, 408, nil, nil, 408, 408, + nil, nil, 408, nil, nil, nil, nil, nil, 408, nil, + nil, nil, nil, nil, nil, nil, nil, 408, nil, nil, + nil, nil, 408, 408, 408, 408, nil, 408, 408, 408, + 408, nil, nil, nil, nil, 408, 408, nil, nil, nil, + 438, 438, 438, 408, 438, 408, 408, 408, 438, 438, + 408, 408, nil, 438, nil, 438, 438, 438, 438, 438, + 438, 438, nil, nil, nil, nil, nil, 438, 438, 438, + 438, 438, 438, 438, nil, nil, 438, nil, nil, nil, + nil, nil, nil, 438, nil, nil, 438, 438, 438, 438, + 438, 438, 438, 438, nil, 438, 438, 438, nil, 438, + 438, 438, 438, 438, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 438, nil, nil, 438, nil, nil, 438, + 438, nil, nil, 438, nil, nil, nil, nil, nil, 438, + nil, nil, nil, nil, nil, nil, nil, nil, 438, nil, + nil, nil, nil, 438, 438, 438, 438, nil, 438, 438, + 438, 438, nil, nil, nil, nil, 438, 438, nil, nil, + nil, nil, nil, nil, 438, nil, 438, 438, 438, 461, + nil, 438, 438, nil, nil, nil, 461, 461, 461, nil, + nil, 461, 461, 461, nil, 461, nil, nil, nil, nil, + nil, nil, nil, 461, 461, 461, 461, nil, nil, nil, + nil, nil, nil, nil, nil, 461, 461, nil, 461, 461, + 461, 461, 461, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 461, 461, 461, 461, 461, + 461, 461, 461, 461, 461, 461, 461, 461, 461, nil, + nil, 461, 461, 461, nil, nil, 461, nil, 461, 461, + nil, nil, 461, 461, nil, 461, nil, 461, nil, 461, + nil, 461, 461, nil, 461, 461, 461, 461, 461, nil, + 461, 461, 461, 1106, nil, 1106, 1106, 1106, 1106, 1106, + nil, nil, nil, nil, nil, nil, 461, nil, 1106, 461, + 461, 471, 461, nil, 461, nil, nil, nil, 471, 471, + 471, 461, nil, 471, 471, 471, nil, 471, nil, nil, + 1106, nil, nil, nil, nil, 471, 471, 471, 471, 471, + nil, 1106, 1106, nil, nil, nil, 1106, 471, 471, nil, + 471, 471, 471, 471, 471, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 471, 471, 471, + 471, 471, 471, 471, 471, 471, 471, 471, 471, 471, + 471, nil, nil, 471, 471, 471, nil, nil, 471, nil, + nil, 471, nil, nil, 471, 471, nil, 471, nil, 471, + nil, 471, nil, 471, 471, nil, 471, 471, 471, 471, + 471, nil, 471, 471, 471, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 471, nil, + nil, 471, 471, 471, 471, nil, 471, 472, 471, nil, + nil, nil, nil, 471, 472, 472, 472, nil, nil, 472, + 472, 472, nil, 472, nil, nil, nil, nil, nil, nil, + nil, 472, 472, 472, 472, 472, nil, nil, nil, nil, + nil, nil, nil, 472, 472, nil, 472, 472, 472, 472, + 472, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 472, 472, 472, 472, 472, 472, 472, + 472, 472, 472, 472, 472, 472, 472, nil, nil, 472, + 472, 472, nil, nil, 472, nil, nil, 472, nil, nil, + 472, 472, nil, 472, nil, 472, nil, 472, nil, 472, + 472, nil, 472, 472, 472, 472, 472, nil, 472, 472, + 472, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 472, nil, nil, 472, 472, 472, + 472, nil, 472, nil, 472, nil, 473, 473, 473, 472, + 473, nil, nil, nil, 473, 473, nil, nil, nil, 473, + nil, 473, 473, 473, 473, 473, 473, 473, nil, nil, + nil, nil, nil, 473, 473, 473, 473, 473, 473, 473, + nil, nil, 473, nil, nil, nil, nil, nil, nil, 473, + nil, nil, 473, 473, 473, 473, 473, 473, 473, 473, + nil, 473, 473, 473, nil, 473, 473, 473, 473, 473, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 473, + nil, nil, 473, nil, nil, 473, 473, nil, nil, 473, + nil, nil, nil, nil, nil, 473, nil, nil, nil, nil, + nil, nil, nil, nil, 473, nil, nil, nil, nil, 473, + 473, 473, 473, nil, 473, 473, 473, 473, nil, nil, + nil, nil, 473, 473, nil, nil, nil, 500, 500, 500, + 473, 500, 473, 473, 473, 500, 500, 473, 473, nil, + 500, nil, 500, 500, 500, 500, 500, 500, 500, nil, + nil, nil, nil, nil, 500, 500, 500, 500, 500, 500, + 500, nil, nil, 500, nil, nil, nil, nil, nil, nil, + 500, nil, nil, 500, 500, 500, 500, 500, 500, 500, + 500, nil, 500, 500, 500, nil, 500, 500, 500, 500, + 500, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 500, nil, nil, 500, nil, nil, 500, 500, nil, nil, + 500, nil, nil, nil, nil, nil, 500, nil, nil, nil, + nil, nil, nil, nil, nil, 500, nil, nil, nil, nil, + 500, 500, 500, 500, nil, 500, 500, 500, 500, nil, + nil, nil, nil, 500, 500, nil, nil, nil, 513, 513, + 513, 500, 513, 500, 500, 500, 513, 513, 500, 500, + nil, 513, nil, 513, 513, 513, 513, 513, 513, 513, + nil, nil, nil, nil, nil, 513, 513, 513, 513, 513, + 513, 513, nil, nil, 513, nil, nil, nil, nil, nil, + nil, 513, nil, nil, 513, 513, 513, 513, 513, 513, + 513, 513, nil, 513, 513, 513, nil, 513, 513, 513, + 513, 513, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 513, nil, nil, 513, nil, nil, 513, 513, nil, + nil, 513, nil, nil, nil, nil, nil, 513, nil, nil, + nil, nil, nil, nil, nil, nil, 513, nil, nil, nil, + nil, 513, 513, 513, 513, nil, 513, 513, 513, 513, + nil, nil, nil, nil, 513, 513, nil, nil, nil, 523, + 523, 523, 513, 523, 513, 513, 513, 523, 523, 513, + 513, nil, 523, nil, 523, 523, 523, 523, 523, 523, + 523, nil, nil, nil, nil, nil, 523, 523, 523, 523, + 523, 523, 523, nil, nil, 523, nil, nil, nil, nil, + nil, nil, 523, nil, nil, 523, 523, 523, 523, 523, + 523, 523, 523, 523, 523, 523, 523, nil, 523, 523, + 523, 523, 523, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 523, nil, nil, 523, nil, nil, 523, 523, + nil, nil, 523, nil, 523, nil, 523, nil, 523, nil, + nil, 523, nil, nil, nil, nil, nil, 523, nil, nil, + nil, nil, 523, 523, 523, 523, nil, 523, 523, 523, + 523, nil, nil, nil, nil, 523, 523, nil, nil, nil, + 525, 525, 525, 523, 525, 523, 523, 523, 525, 525, + 523, 523, nil, 525, nil, 525, 525, 525, 525, 525, + 525, 525, nil, nil, nil, nil, nil, 525, 525, 525, + 525, 525, 525, 525, nil, nil, 525, nil, nil, nil, + nil, nil, nil, 525, nil, nil, 525, 525, 525, 525, + 525, 525, 525, 525, nil, 525, 525, 525, nil, 525, + 525, 525, 525, 525, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 525, nil, nil, 525, nil, nil, 525, + 525, nil, nil, 525, nil, nil, nil, nil, nil, 525, + nil, nil, nil, nil, nil, nil, nil, nil, 525, nil, + nil, nil, nil, 525, 525, 525, 525, nil, 525, 525, + 525, 525, nil, nil, nil, nil, 525, 525, nil, nil, + nil, 526, 526, 526, 525, 526, 525, 525, 525, 526, + 526, 525, 525, nil, 526, nil, 526, 526, 526, 526, + 526, 526, 526, nil, nil, nil, nil, nil, 526, 526, + 526, 526, 526, 526, 526, nil, nil, 526, nil, nil, + nil, nil, nil, nil, 526, nil, nil, 526, 526, 526, + 526, 526, 526, 526, 526, nil, 526, 526, 526, nil, + 526, 526, 526, 526, 526, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 526, nil, nil, 526, nil, nil, + 526, 526, nil, nil, 526, nil, nil, nil, nil, nil, + 526, nil, nil, nil, nil, nil, nil, nil, nil, 526, + nil, nil, nil, nil, 526, 526, 526, 526, nil, 526, + 526, 526, 526, nil, nil, nil, nil, 526, 526, nil, + nil, nil, 527, 527, 527, 526, 527, 526, 526, 526, + 527, 527, 526, 526, nil, 527, nil, 527, 527, 527, + 527, 527, 527, 527, nil, nil, nil, nil, nil, 527, + 527, 527, 527, 527, 527, 527, nil, nil, 527, nil, + nil, nil, nil, nil, nil, 527, nil, nil, 527, 527, + 527, 527, 527, 527, 527, 527, nil, 527, 527, 527, + nil, 527, 527, 527, 527, 527, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 527, nil, nil, 527, nil, + nil, 527, 527, nil, nil, 527, nil, nil, nil, nil, + nil, 527, nil, nil, nil, nil, nil, nil, nil, nil, + 527, nil, nil, nil, nil, 527, 527, 527, 527, nil, + 527, 527, 527, 527, nil, nil, nil, nil, 527, 527, + nil, nil, nil, nil, nil, nil, 527, nil, 527, 527, + 527, 559, nil, 527, 527, nil, nil, nil, 559, 559, + 559, nil, nil, 559, 559, 559, 235, 559, 235, 235, + 235, 235, 235, nil, nil, 559, 559, 559, nil, nil, + nil, 235, nil, nil, nil, nil, nil, 559, 559, nil, + 559, 559, 559, 559, 559, nil, 410, nil, 410, 410, + 410, 410, 410, 235, nil, nil, nil, nil, nil, nil, + nil, 410, 235, 235, 235, 235, nil, nil, nil, 235, + nil, 1101, nil, 1101, 1101, 1101, 1101, 1101, 559, nil, + nil, nil, nil, 410, 410, 559, 1101, nil, nil, nil, + 559, 559, 410, 410, 410, 410, nil, nil, nil, 410, + nil, nil, nil, nil, nil, nil, nil, nil, 1101, 235, + nil, nil, nil, 559, 559, nil, nil, 1101, 1101, 1101, + 1101, nil, nil, nil, 1101, nil, nil, nil, 559, nil, + nil, 559, nil, 564, 564, 564, 559, 564, nil, 410, + nil, 564, 564, 559, nil, nil, 564, nil, 564, 564, + 564, 564, 564, 564, 564, nil, nil, nil, nil, nil, + 564, 564, 564, 564, 564, 564, 564, nil, nil, 564, + nil, nil, nil, nil, nil, nil, 564, nil, nil, 564, + 564, 564, 564, 564, 564, 564, 564, nil, 564, 564, + 564, nil, 564, 564, 564, 564, 564, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 564, nil, nil, 564, + nil, nil, 564, 564, nil, nil, 564, nil, nil, nil, + nil, nil, 564, nil, nil, nil, nil, nil, nil, nil, + nil, 564, nil, nil, nil, nil, 564, 564, 564, 564, + nil, 564, 564, 564, 564, nil, nil, nil, nil, 564, + 564, nil, nil, nil, 574, 574, 574, 564, 574, 564, + 564, 564, 574, 574, 564, 564, nil, 574, nil, 574, + 574, 574, 574, 574, 574, 574, nil, nil, nil, nil, + nil, 574, 574, 574, 574, 574, 574, 574, nil, nil, + 574, nil, nil, nil, nil, nil, nil, 574, nil, nil, + 574, 574, 574, 574, 574, 574, 574, 574, 574, 574, + 574, 574, nil, 574, 574, 574, 574, 574, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 574, nil, nil, + 574, nil, nil, 574, 574, nil, nil, 574, nil, 574, + nil, 574, nil, 574, nil, nil, 574, nil, nil, nil, + nil, nil, 574, nil, nil, nil, nil, 574, 574, 574, + 574, nil, 574, 574, 574, 574, nil, nil, nil, nil, + 574, 574, nil, nil, nil, 576, 576, 576, 574, 576, + 574, 574, 574, 576, 576, 574, 574, nil, 576, nil, + 576, 576, 576, 576, 576, 576, 576, nil, nil, nil, + nil, nil, 576, 576, 576, 576, 576, 576, 576, nil, + nil, 576, nil, nil, nil, nil, nil, nil, 576, nil, + nil, 576, 576, 576, 576, 576, 576, 576, 576, 576, + 576, 576, 576, nil, 576, 576, 576, 576, 576, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 576, nil, + nil, 576, nil, nil, 576, 576, nil, nil, 576, nil, + nil, nil, 576, nil, 576, nil, nil, 576, nil, nil, + nil, nil, nil, 576, nil, nil, nil, nil, 576, 576, + 576, 576, nil, 576, 576, 576, 576, nil, nil, nil, + nil, 576, 576, nil, nil, nil, 578, 578, 578, 576, + 578, 576, 576, 576, 578, 578, 576, 576, nil, 578, + nil, 578, 578, 578, 578, 578, 578, 578, nil, nil, + nil, nil, nil, 578, 578, 578, 578, 578, 578, 578, + nil, nil, 578, nil, nil, nil, nil, nil, nil, 578, + nil, nil, 578, 578, 578, 578, 578, 578, 578, 578, + nil, 578, 578, 578, nil, 578, 578, 578, 578, 578, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 578, + nil, nil, 578, nil, nil, 578, 578, nil, nil, 578, + nil, nil, nil, nil, nil, 578, nil, nil, nil, nil, + nil, nil, nil, nil, 578, nil, nil, nil, nil, 578, + 578, 578, 578, nil, 578, 578, 578, 578, nil, nil, + nil, nil, 578, 578, nil, nil, nil, nil, nil, nil, + 578, nil, 578, 578, 578, nil, nil, 578, 578, 584, + 584, 584, 584, 584, nil, nil, nil, 584, 584, nil, + nil, nil, 584, nil, 584, 584, 584, 584, 584, 584, + 584, nil, nil, nil, nil, nil, 584, 584, 584, 584, + 584, 584, 584, nil, nil, 584, nil, nil, nil, nil, + nil, 584, 584, 584, 584, 584, 584, 584, 584, 584, + 584, 584, 584, nil, 584, 584, 584, nil, 584, 584, + 584, 584, 584, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 584, nil, nil, 584, nil, nil, 584, 584, + nil, nil, 584, nil, 584, nil, nil, nil, 584, nil, + nil, nil, nil, nil, nil, nil, nil, 584, nil, nil, + nil, nil, 584, 584, 584, 584, nil, 584, 584, 584, + 584, nil, nil, nil, nil, 584, 584, nil, nil, nil, + nil, nil, 584, 584, nil, 584, 584, 584, nil, nil, + 584, 584, 594, 594, 594, nil, 594, nil, nil, nil, + 594, 594, nil, nil, nil, 594, nil, 594, 594, 594, + 594, 594, 594, 594, nil, nil, nil, nil, nil, 594, + 594, 594, 594, 594, 594, 594, nil, nil, 594, nil, + nil, nil, nil, nil, nil, 594, nil, nil, 594, 594, + 594, 594, 594, 594, 594, 594, 594, 594, 594, 594, + nil, 594, 594, 594, 594, 594, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 594, nil, nil, 594, nil, + nil, 594, 594, nil, nil, 594, nil, 594, nil, 594, + nil, 594, nil, nil, 594, nil, nil, nil, nil, nil, + 594, nil, nil, nil, nil, 594, 594, 594, 594, nil, + 594, 594, 594, 594, nil, nil, nil, nil, 594, 594, + nil, nil, nil, 604, 604, 604, 594, 604, 594, 594, + 594, 604, 604, 594, 594, nil, 604, nil, 604, 604, + 604, 604, 604, 604, 604, nil, nil, nil, nil, nil, + 604, 604, 604, 604, 604, 604, 604, nil, nil, 604, + nil, nil, nil, nil, nil, nil, 604, nil, nil, 604, + 604, 604, 604, 604, 604, 604, 604, nil, 604, 604, + 604, nil, 604, 604, 604, 604, 604, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 604, nil, nil, 604, + nil, nil, 604, 604, nil, nil, 604, nil, nil, nil, + nil, nil, 604, nil, nil, nil, nil, nil, nil, nil, + nil, 604, nil, nil, nil, nil, 604, 604, 604, 604, + nil, 604, 604, 604, 604, nil, nil, nil, nil, 604, + 604, nil, nil, nil, 607, 607, 607, 604, 607, 604, + 604, 604, 607, 607, 604, 604, nil, 607, nil, 607, + 607, 607, 607, 607, 607, 607, nil, nil, nil, nil, + nil, 607, 607, 607, 607, 607, 607, 607, nil, nil, + 607, nil, nil, nil, nil, nil, nil, 607, nil, nil, + 607, 607, 607, 607, 607, 607, 607, 607, nil, 607, + 607, 607, nil, 607, 607, 607, 607, 607, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 607, nil, nil, + 607, nil, nil, 607, 607, nil, nil, 607, nil, nil, + nil, nil, nil, 607, nil, nil, nil, nil, nil, nil, + nil, nil, 607, nil, nil, nil, nil, 607, 607, 607, + 607, nil, 607, 607, 607, 607, nil, nil, nil, nil, + 607, 607, nil, nil, nil, 609, 609, 609, 607, 609, + 607, 607, 607, 609, 609, 607, 607, nil, 609, nil, + 609, 609, 609, 609, 609, 609, 609, nil, nil, nil, + nil, nil, 609, 609, 609, 609, 609, 609, 609, nil, + nil, 609, nil, nil, nil, nil, nil, nil, 609, nil, + nil, 609, 609, 609, 609, 609, 609, 609, 609, nil, + 609, 609, 609, nil, 609, 609, 609, 609, 609, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 609, nil, + nil, 609, nil, nil, 609, 609, nil, nil, 609, nil, + nil, nil, nil, nil, 609, nil, nil, nil, nil, nil, + nil, nil, nil, 609, nil, nil, nil, nil, 609, 609, + 609, 609, nil, 609, 609, 609, 609, nil, nil, nil, + nil, 609, 609, nil, nil, nil, 615, 615, 615, 609, + 615, 609, 609, 609, 615, 615, 609, 609, nil, 615, + nil, 615, 615, 615, 615, 615, 615, 615, nil, nil, + nil, nil, nil, 615, 615, 615, 615, 615, 615, 615, + nil, nil, 615, nil, nil, nil, nil, nil, nil, 615, + nil, nil, 615, 615, 615, 615, 615, 615, 615, 615, + 615, 615, 615, 615, nil, 615, 615, 615, 615, 615, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 615, + nil, nil, 615, nil, nil, 615, 615, nil, nil, 615, + nil, 615, nil, nil, nil, 615, nil, nil, 615, nil, + nil, nil, nil, nil, 615, nil, nil, nil, nil, 615, + 615, 615, 615, nil, 615, 615, 615, 615, nil, nil, + nil, nil, 615, 615, nil, nil, nil, 618, 618, 618, + 615, 618, 615, 615, 615, 618, 618, 615, 615, nil, + 618, nil, 618, 618, 618, 618, 618, 618, 618, nil, + nil, nil, nil, nil, 618, 618, 618, 618, 618, 618, + 618, nil, nil, 618, nil, nil, nil, nil, nil, nil, + 618, nil, nil, 618, 618, 618, 618, 618, 618, 618, + 618, 618, 618, 618, 618, nil, 618, 618, 618, 618, + 618, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 618, nil, nil, 618, nil, nil, 618, 618, nil, nil, + 618, nil, nil, nil, nil, nil, 618, nil, nil, 618, + nil, nil, nil, nil, nil, 618, nil, nil, nil, nil, + 618, 618, 618, 618, nil, 618, 618, 618, 618, nil, + nil, nil, nil, 618, 618, nil, nil, nil, 631, 631, + 631, 618, 631, 618, 618, 618, 631, 631, 618, 618, + nil, 631, nil, 631, 631, 631, 631, 631, 631, 631, + nil, nil, nil, nil, nil, 631, 631, 631, 631, 631, + 631, 631, nil, nil, 631, nil, nil, nil, nil, nil, + nil, 631, nil, nil, 631, 631, 631, 631, 631, 631, + 631, 631, nil, 631, 631, 631, nil, 631, 631, 631, + 631, 631, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 631, nil, nil, 631, nil, nil, 631, 631, nil, + nil, 631, nil, 631, nil, nil, nil, 631, nil, nil, + nil, nil, nil, nil, nil, nil, 631, nil, nil, nil, + nil, 631, 631, 631, 631, nil, 631, 631, 631, 631, + nil, nil, nil, nil, 631, 631, nil, nil, nil, 632, + 632, 632, 631, 632, 631, 631, 631, 632, 632, 631, + 631, nil, 632, nil, 632, 632, 632, 632, 632, 632, + 632, nil, nil, nil, nil, nil, 632, 632, 632, 632, + 632, 632, 632, nil, nil, 632, nil, nil, nil, nil, + nil, nil, 632, nil, nil, 632, 632, 632, 632, 632, + 632, 632, 632, 632, 632, 632, 632, nil, 632, 632, + 632, 632, 632, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 632, nil, nil, 632, nil, nil, 632, 632, + nil, nil, 632, nil, 632, nil, 632, nil, 632, nil, + nil, 632, nil, nil, nil, nil, nil, 632, nil, nil, + nil, nil, 632, 632, 632, 632, nil, 632, 632, 632, + 632, nil, nil, nil, nil, 632, 632, nil, nil, nil, + 642, 642, 642, 632, 642, 632, 632, 632, 642, 642, + 632, 632, nil, 642, nil, 642, 642, 642, 642, 642, + 642, 642, nil, nil, nil, nil, nil, 642, 642, 642, + 642, 642, 642, 642, nil, nil, 642, nil, nil, nil, + nil, nil, nil, 642, nil, nil, 642, 642, 642, 642, + 642, 642, 642, 642, 642, 642, 642, 642, nil, 642, + 642, 642, 642, 642, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 642, nil, nil, 642, nil, nil, 642, + 642, nil, nil, 642, nil, 642, nil, 642, nil, 642, + nil, nil, 642, nil, nil, nil, nil, nil, 642, nil, + nil, nil, nil, 642, 642, 642, 642, nil, 642, 642, + 642, 642, nil, nil, nil, nil, 642, 642, nil, nil, + nil, nil, nil, nil, 642, nil, 642, 642, 642, nil, + nil, 642, 642, 673, 673, 673, 673, 673, nil, nil, + nil, 673, 673, nil, nil, nil, 673, nil, 673, 673, + 673, 673, 673, 673, 673, nil, nil, nil, nil, nil, + 673, 673, 673, 673, 673, 673, 673, nil, nil, 673, + nil, nil, nil, nil, nil, 673, 673, nil, 673, 673, + 673, 673, 673, 673, 673, 673, 673, nil, 673, 673, + 673, nil, 673, 673, 673, 673, 673, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 673, nil, nil, 673, + nil, nil, 673, 673, nil, nil, 673, nil, 673, nil, + nil, nil, 673, nil, nil, nil, nil, nil, nil, nil, + nil, 673, nil, nil, nil, nil, 673, 673, 673, 673, + nil, 673, 673, 673, 673, nil, nil, nil, nil, 673, + 673, nil, nil, nil, 674, 674, 674, 673, 674, 673, + 673, 673, 674, 674, 673, 673, nil, 674, nil, 674, + 674, 674, 674, 674, 674, 674, nil, nil, nil, nil, + nil, 674, 674, 674, 674, 674, 674, 674, nil, nil, + 674, nil, nil, nil, nil, nil, nil, 674, nil, nil, + 674, 674, 674, 674, 674, 674, 674, 674, nil, 674, + 674, 674, nil, 674, 674, 674, 674, 674, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 674, nil, nil, + 674, nil, nil, 674, 674, nil, nil, 674, nil, 674, + nil, nil, nil, 674, nil, nil, nil, nil, nil, nil, + nil, nil, 674, nil, nil, nil, nil, 674, 674, 674, + 674, nil, 674, 674, 674, 674, nil, nil, nil, nil, + 674, 674, nil, nil, nil, 676, 676, 676, 674, 676, + 674, 674, 674, 676, 676, 674, 674, nil, 676, nil, + 676, 676, 676, 676, 676, 676, 676, nil, nil, nil, + nil, nil, 676, 676, 676, 676, 676, 676, 676, nil, + nil, 676, nil, nil, nil, nil, nil, nil, 676, nil, + nil, 676, 676, 676, 676, 676, 676, 676, 676, nil, + 676, 676, 676, nil, 676, 676, 676, 676, 676, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 676, nil, + nil, 676, nil, nil, 676, 676, nil, nil, 676, nil, + nil, nil, nil, nil, 676, nil, nil, nil, nil, nil, + nil, nil, nil, 676, nil, nil, nil, nil, 676, 676, + 676, 676, nil, 676, 676, 676, 676, nil, nil, nil, + nil, 676, 676, nil, nil, nil, 677, 677, 677, 676, + 677, 676, 676, 676, 677, 677, 676, 676, nil, 677, + nil, 677, 677, 677, 677, 677, 677, 677, nil, nil, + nil, nil, nil, 677, 677, 677, 677, 677, 677, 677, + nil, nil, 677, nil, nil, nil, nil, nil, nil, 677, + nil, nil, 677, 677, 677, 677, 677, 677, 677, 677, + 677, 677, 677, 677, nil, 677, 677, 677, 677, 677, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 677, + nil, nil, 677, nil, nil, 677, 677, nil, nil, 677, + nil, 677, nil, 677, nil, 677, nil, nil, 677, nil, + nil, nil, nil, nil, 677, nil, nil, nil, nil, 677, + 677, 677, 677, nil, 677, 677, 677, 677, nil, nil, + nil, nil, 677, 677, nil, nil, nil, nil, nil, nil, + 677, nil, 677, 677, 677, nil, nil, 677, 677, 680, + 680, 680, 680, 680, nil, nil, nil, 680, 680, nil, + nil, nil, 680, nil, 680, 680, 680, 680, 680, 680, + 680, nil, nil, nil, nil, nil, 680, 680, 680, 680, + 680, 680, 680, nil, nil, 680, nil, nil, nil, nil, + nil, 680, 680, nil, 680, 680, 680, 680, 680, 680, + 680, 680, 680, nil, 680, 680, 680, nil, 680, 680, + 680, 680, 680, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 680, nil, nil, 680, nil, nil, 680, 680, + nil, nil, 680, nil, 680, nil, nil, nil, 680, nil, + nil, nil, nil, nil, nil, nil, nil, 680, nil, nil, + nil, nil, 680, 680, 680, 680, nil, 680, 680, 680, + 680, nil, nil, nil, nil, 680, 680, nil, nil, nil, + 681, 681, 681, 680, 681, 680, 680, 680, 681, 681, + 680, 680, nil, 681, nil, 681, 681, 681, 681, 681, + 681, 681, nil, nil, nil, nil, nil, 681, 681, 681, + 681, 681, 681, 681, nil, nil, 681, nil, nil, nil, + nil, nil, nil, 681, nil, nil, 681, 681, 681, 681, + 681, 681, 681, 681, nil, 681, 681, 681, nil, 681, + 681, 681, 681, 681, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 681, nil, nil, 681, nil, nil, 681, + 681, nil, nil, 681, nil, nil, nil, nil, nil, 681, + nil, nil, nil, nil, nil, nil, nil, nil, 681, nil, + nil, nil, nil, 681, 681, 681, 681, nil, 681, 681, + 681, 681, nil, nil, nil, nil, 681, 681, nil, nil, + nil, 684, 684, 684, 681, 684, 681, 681, 681, 684, + 684, 681, 681, nil, 684, nil, 684, 684, 684, 684, + 684, 684, 684, nil, nil, nil, nil, nil, 684, 684, + 684, 684, 684, 684, 684, nil, nil, 684, nil, nil, + nil, nil, nil, nil, 684, nil, nil, 684, 684, 684, + 684, 684, 684, 684, 684, 684, 684, 684, 684, nil, + 684, 684, 684, 684, 684, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 684, nil, nil, 684, nil, nil, + 684, 684, nil, nil, 684, nil, 684, nil, 684, nil, + 684, nil, nil, 684, nil, nil, nil, nil, nil, 684, + nil, nil, nil, nil, 684, 684, 684, 684, nil, 684, + 684, 684, 684, nil, nil, nil, nil, 684, 684, nil, + nil, nil, 685, 685, 685, 684, 685, 684, 684, 684, + 685, 685, 684, 684, nil, 685, nil, 685, 685, 685, + 685, 685, 685, 685, nil, nil, nil, nil, nil, 685, + 685, 685, 685, 685, 685, 685, nil, nil, 685, nil, + nil, nil, nil, nil, nil, 685, nil, nil, 685, 685, + 685, 685, 685, 685, 685, 685, 685, 685, 685, 685, + nil, 685, 685, 685, 685, 685, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 685, nil, nil, 685, nil, + nil, 685, 685, nil, nil, 685, nil, nil, nil, 685, + nil, 685, nil, nil, 685, nil, nil, nil, nil, nil, + 685, nil, nil, nil, nil, 685, 685, 685, 685, nil, + 685, 685, 685, 685, nil, nil, nil, nil, 685, 685, + nil, nil, nil, 686, 686, 686, 685, 686, 685, 685, + 685, 686, 686, 685, 685, nil, 686, nil, 686, 686, + 686, 686, 686, 686, 686, nil, nil, nil, nil, nil, + 686, 686, 686, 686, 686, 686, 686, nil, nil, 686, + nil, nil, nil, nil, nil, nil, 686, nil, nil, 686, + 686, 686, 686, 686, 686, 686, 686, nil, 686, 686, + 686, nil, 686, 686, 686, 686, 686, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 686, nil, nil, 686, + nil, nil, 686, 686, nil, nil, 686, nil, nil, nil, + nil, nil, 686, nil, nil, nil, nil, nil, nil, nil, + nil, 686, nil, nil, nil, nil, 686, 686, 686, 686, + nil, 686, 686, 686, 686, nil, nil, nil, nil, 686, + 686, nil, nil, nil, 687, 687, 687, 686, 687, 686, + 686, 686, 687, 687, 686, 686, nil, 687, nil, 687, + 687, 687, 687, 687, 687, 687, nil, nil, nil, nil, + nil, 687, 687, 687, 687, 687, 687, 687, nil, nil, + 687, nil, nil, nil, nil, nil, nil, 687, nil, nil, + 687, 687, 687, 687, 687, 687, 687, 687, nil, 687, + 687, 687, nil, 687, 687, 687, 687, 687, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 687, nil, nil, + 687, nil, nil, 687, 687, nil, nil, 687, nil, nil, + nil, nil, nil, 687, nil, nil, nil, nil, nil, nil, + nil, nil, 687, nil, nil, nil, nil, 687, 687, 687, + 687, nil, 687, 687, 687, 687, nil, nil, nil, nil, + 687, 687, nil, nil, nil, 691, 691, 691, 687, 691, + 687, 687, 687, 691, 691, 687, 687, nil, 691, nil, + 691, 691, 691, 691, 691, 691, 691, nil, nil, nil, + nil, nil, 691, 691, 691, 691, 691, 691, 691, nil, + nil, 691, nil, nil, nil, nil, nil, nil, 691, nil, + nil, 691, 691, 691, 691, 691, 691, 691, 691, nil, + 691, 691, 691, nil, 691, 691, 691, 691, 691, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 691, nil, + nil, 691, nil, nil, 691, 691, nil, nil, 691, nil, + nil, nil, nil, nil, 691, nil, nil, nil, nil, nil, + nil, nil, nil, 691, nil, nil, nil, nil, 691, 691, + 691, 691, nil, 691, 691, 691, 691, nil, nil, nil, + nil, 691, 691, nil, nil, nil, 693, 693, 693, 691, + 693, 691, 691, 691, 693, 693, 691, 691, nil, 693, + nil, 693, 693, 693, 693, 693, 693, 693, nil, nil, + nil, nil, nil, 693, 693, 693, 693, 693, 693, 693, + nil, nil, 693, nil, nil, nil, nil, nil, nil, 693, + nil, nil, 693, 693, 693, 693, 693, 693, 693, 693, + nil, 693, 693, 693, nil, 693, 693, 693, 693, 693, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 693, + nil, nil, 693, nil, nil, 693, 693, nil, nil, 693, + nil, nil, nil, nil, nil, 693, nil, nil, nil, nil, + nil, nil, nil, nil, 693, nil, nil, nil, nil, 693, + 693, 693, 693, nil, 693, 693, 693, 693, nil, nil, + nil, nil, 693, 693, nil, nil, nil, 702, 702, 702, + 693, 702, 693, 693, 693, 702, 702, 693, 693, nil, + 702, nil, 702, 702, 702, 702, 702, 702, 702, nil, + nil, nil, nil, nil, 702, 702, 702, 702, 702, 702, + 702, nil, nil, 702, nil, nil, nil, nil, nil, nil, + 702, nil, nil, 702, 702, 702, 702, 702, 702, 702, + 702, nil, 702, 702, 702, nil, 702, 702, 702, 702, + 702, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 702, nil, nil, 702, nil, nil, 702, 702, nil, nil, + 702, nil, 702, nil, nil, nil, 702, nil, nil, nil, + nil, nil, nil, nil, nil, 702, nil, nil, nil, nil, + 702, 702, 702, 702, nil, 702, 702, 702, 702, nil, + nil, nil, nil, 702, 702, nil, nil, nil, 718, 718, + 718, 702, 718, 702, 702, 702, 718, 718, 702, 702, + nil, 718, nil, 718, 718, 718, 718, 718, 718, 718, + nil, nil, nil, nil, nil, 718, 718, 718, 718, 718, + 718, 718, nil, nil, 718, nil, nil, nil, nil, nil, + nil, 718, nil, nil, 718, 718, 718, 718, 718, 718, + 718, 718, nil, 718, 718, 718, nil, 718, 718, 718, + 718, 718, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 718, nil, nil, 718, nil, nil, 718, 718, nil, + nil, 718, nil, nil, nil, nil, nil, 718, nil, nil, + nil, nil, nil, nil, nil, nil, 718, nil, nil, nil, + nil, 718, 718, 718, 718, nil, 718, 718, 718, 718, + nil, nil, nil, nil, 718, 718, nil, nil, nil, 740, + 740, 740, 718, 740, 718, 718, 718, 740, 740, 718, + 718, nil, 740, nil, 740, 740, 740, 740, 740, 740, + 740, nil, nil, nil, nil, nil, 740, 740, 740, 740, + 740, 740, 740, nil, nil, 740, nil, nil, nil, nil, + nil, nil, 740, nil, nil, 740, 740, 740, 740, 740, + 740, 740, 740, nil, 740, 740, 740, nil, 740, 740, + 740, 740, 740, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 740, nil, nil, 740, nil, nil, 740, 740, + nil, nil, 740, nil, nil, nil, nil, nil, 740, nil, + nil, nil, nil, nil, nil, nil, nil, 740, nil, nil, + nil, nil, 740, 740, 740, 740, nil, 740, 740, 740, + 740, nil, nil, nil, nil, 740, 740, nil, nil, nil, + 741, 741, 741, 740, 741, 740, 740, 740, 741, 741, + 740, 740, nil, 741, nil, 741, 741, 741, 741, 741, + 741, 741, nil, nil, nil, nil, nil, 741, 741, 741, + 741, 741, 741, 741, nil, nil, 741, nil, nil, nil, + nil, nil, nil, 741, nil, nil, 741, 741, 741, 741, + 741, 741, 741, 741, nil, 741, 741, 741, nil, 741, + 741, 741, 741, 741, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 741, nil, nil, 741, nil, nil, 741, + 741, nil, nil, 741, nil, nil, nil, nil, nil, 741, + nil, nil, nil, nil, nil, nil, nil, nil, 741, nil, + nil, nil, nil, 741, 741, 741, 741, nil, 741, 741, + 741, 741, nil, nil, nil, nil, 741, 741, nil, nil, + nil, 754, 754, 754, 741, 754, 741, 741, 741, 754, + 754, 741, 741, nil, 754, nil, 754, 754, 754, 754, + 754, 754, 754, nil, nil, nil, nil, nil, 754, 754, + 754, 754, 754, 754, 754, nil, nil, 754, nil, nil, + nil, nil, nil, nil, 754, nil, nil, 754, 754, 754, + 754, 754, 754, 754, 754, 754, 754, 754, 754, nil, + 754, 754, 754, 754, 754, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 754, nil, nil, 754, nil, nil, + 754, 754, nil, nil, 754, nil, 754, nil, 754, nil, + 754, nil, nil, 754, nil, nil, nil, nil, nil, 754, + nil, nil, nil, nil, 754, 754, 754, 754, nil, 754, + 754, 754, 754, nil, nil, nil, nil, 754, 754, nil, + nil, nil, 766, 766, 766, 754, 766, 754, 754, 754, + 766, 766, 754, 754, nil, 766, nil, 766, 766, 766, + 766, 766, 766, 766, nil, nil, nil, nil, nil, 766, + 766, 766, 766, 766, 766, 766, nil, nil, 766, nil, + nil, nil, nil, nil, nil, 766, nil, nil, 766, 766, + 766, 766, 766, 766, 766, 766, nil, 766, 766, 766, + nil, 766, 766, 766, 766, 766, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 766, nil, nil, 766, nil, + nil, 766, 766, nil, nil, 766, nil, nil, nil, nil, + nil, 766, nil, nil, nil, nil, nil, nil, nil, nil, + 766, nil, nil, nil, nil, 766, 766, 766, 766, nil, + 766, 766, 766, 766, nil, nil, nil, nil, 766, 766, + nil, nil, nil, 785, 785, 785, 766, 785, 766, 766, + 766, 785, 785, 766, 766, nil, 785, nil, 785, 785, + 785, 785, 785, 785, 785, nil, nil, nil, nil, nil, + 785, 785, 785, 785, 785, 785, 785, nil, nil, 785, + nil, nil, nil, nil, nil, nil, 785, nil, nil, 785, + 785, 785, 785, 785, 785, 785, 785, nil, 785, 785, + 785, nil, 785, 785, 785, 785, 785, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 785, nil, nil, 785, + nil, nil, 785, 785, nil, nil, 785, nil, nil, nil, + nil, nil, 785, nil, nil, nil, nil, nil, nil, nil, + nil, 785, nil, nil, nil, nil, 785, 785, 785, 785, + nil, 785, 785, 785, 785, nil, nil, nil, nil, 785, + 785, nil, nil, nil, 813, 813, 813, 785, 813, 785, + 785, 785, 813, 813, 785, 785, nil, 813, nil, 813, + 813, 813, 813, 813, 813, 813, nil, nil, nil, nil, + nil, 813, 813, 813, 813, 813, 813, 813, nil, nil, + 813, nil, nil, nil, nil, nil, nil, 813, nil, nil, + 813, 813, 813, 813, 813, 813, 813, 813, nil, 813, + 813, 813, nil, 813, 813, 813, 813, 813, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 813, nil, nil, + 813, nil, nil, 813, 813, nil, nil, 813, nil, nil, + nil, nil, nil, 813, nil, nil, nil, nil, nil, nil, + nil, nil, 813, nil, nil, nil, nil, 813, 813, 813, + 813, nil, 813, 813, 813, 813, nil, nil, nil, nil, + 813, 813, nil, nil, nil, 832, 832, 832, 813, 832, + 813, 813, 813, 832, 832, 813, 813, nil, 832, nil, + 832, 832, 832, 832, 832, 832, 832, nil, nil, nil, + nil, nil, 832, 832, 832, 832, 832, 832, 832, nil, + nil, 832, nil, nil, nil, nil, nil, nil, 832, nil, + nil, 832, 832, 832, 832, 832, 832, 832, 832, nil, + 832, 832, 832, nil, 832, 832, 832, 832, 832, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 832, nil, + nil, 832, nil, nil, 832, 832, nil, nil, 832, nil, + nil, nil, nil, nil, 832, nil, nil, nil, nil, nil, + nil, nil, nil, 832, nil, nil, nil, nil, 832, 832, + 832, 832, nil, 832, 832, 832, 832, nil, nil, nil, + nil, 832, 832, nil, nil, nil, 840, 840, 840, 832, + 840, 832, 832, 832, 840, 840, 832, 832, nil, 840, + nil, 840, 840, 840, 840, 840, 840, 840, nil, nil, + nil, nil, nil, 840, 840, 840, 840, 840, 840, 840, + nil, nil, 840, nil, nil, nil, nil, nil, nil, 840, + nil, nil, 840, 840, 840, 840, 840, 840, 840, 840, + nil, 840, 840, 840, nil, 840, 840, 840, 840, 840, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 840, + nil, nil, 840, nil, nil, 840, 840, nil, nil, 840, + nil, nil, nil, nil, nil, 840, nil, nil, nil, nil, + nil, nil, nil, nil, 840, nil, nil, nil, nil, 840, + 840, 840, 840, nil, 840, 840, 840, 840, nil, nil, + nil, nil, 840, 840, nil, nil, nil, 854, 854, 854, + 840, 854, 840, 840, 840, 854, 854, 840, 840, nil, + 854, nil, 854, 854, 854, 854, 854, 854, 854, nil, + nil, nil, nil, nil, 854, 854, 854, 854, 854, 854, + 854, nil, nil, 854, nil, nil, nil, nil, nil, nil, + 854, nil, nil, 854, 854, 854, 854, 854, 854, 854, + 854, nil, 854, 854, 854, nil, 854, 854, 854, 854, + 854, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 854, nil, nil, 854, nil, nil, 854, 854, nil, nil, + 854, nil, nil, nil, nil, nil, 854, nil, nil, nil, + nil, nil, nil, nil, nil, 854, nil, nil, nil, nil, + 854, 854, 854, 854, nil, 854, 854, 854, 854, nil, + nil, nil, nil, 854, 854, nil, nil, nil, 855, 855, + 855, 854, 855, 854, 854, 854, 855, 855, 854, 854, + nil, 855, nil, 855, 855, 855, 855, 855, 855, 855, + nil, nil, nil, nil, nil, 855, 855, 855, 855, 855, + 855, 855, nil, nil, 855, nil, nil, nil, nil, nil, + nil, 855, nil, nil, 855, 855, 855, 855, 855, 855, + 855, 855, nil, 855, 855, 855, nil, 855, 855, 855, + 855, 855, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 855, nil, nil, 855, nil, nil, 855, 855, nil, + nil, 855, nil, nil, nil, nil, nil, 855, nil, nil, + nil, nil, nil, nil, nil, nil, 855, nil, nil, nil, + nil, 855, 855, 855, 855, nil, 855, 855, 855, 855, + nil, nil, nil, nil, 855, 855, nil, nil, nil, 856, + 856, 856, 855, 856, 855, 855, 855, 856, 856, 855, + 855, nil, 856, nil, 856, 856, 856, 856, 856, 856, + 856, nil, nil, nil, nil, nil, 856, 856, 856, 856, + 856, 856, 856, nil, nil, 856, nil, nil, nil, nil, + nil, nil, 856, nil, nil, 856, 856, 856, 856, 856, + 856, 856, 856, nil, 856, 856, 856, nil, 856, 856, + 856, 856, 856, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 856, nil, nil, 856, nil, nil, 856, 856, + nil, nil, 856, nil, nil, nil, nil, nil, 856, nil, + nil, nil, nil, nil, nil, nil, nil, 856, nil, nil, + nil, nil, 856, 856, 856, 856, nil, 856, 856, 856, + 856, nil, nil, nil, nil, 856, 856, nil, nil, nil, + 884, 884, 884, 856, 884, 856, 856, 856, 884, 884, + 856, 856, nil, 884, nil, 884, 884, 884, 884, 884, + 884, 884, nil, nil, nil, nil, nil, 884, 884, 884, + 884, 884, 884, 884, nil, nil, 884, nil, nil, nil, + nil, nil, nil, 884, nil, nil, 884, 884, 884, 884, + 884, 884, 884, 884, nil, 884, 884, 884, nil, 884, + 884, 884, 884, 884, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 884, nil, nil, 884, nil, nil, 884, + 884, nil, nil, 884, nil, nil, nil, nil, nil, 884, + nil, nil, nil, nil, nil, nil, nil, nil, 884, nil, + nil, nil, nil, 884, 884, 884, 884, nil, 884, 884, + 884, 884, nil, nil, nil, nil, 884, 884, nil, nil, + nil, 885, 885, 885, 884, 885, 884, 884, 884, 885, + 885, 884, 884, nil, 885, nil, 885, 885, 885, 885, + 885, 885, 885, nil, nil, nil, nil, nil, 885, 885, + 885, 885, 885, 885, 885, nil, nil, 885, nil, nil, + nil, nil, nil, nil, 885, nil, nil, 885, 885, 885, + 885, 885, 885, 885, 885, nil, 885, 885, 885, nil, + 885, 885, 885, 885, 885, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 885, nil, nil, 885, nil, nil, + 885, 885, nil, nil, 885, nil, nil, nil, nil, nil, + 885, nil, nil, nil, nil, nil, nil, nil, nil, 885, + nil, nil, nil, nil, 885, 885, 885, 885, nil, 885, + 885, 885, 885, nil, nil, nil, nil, 885, 885, nil, + nil, nil, 886, 886, 886, 885, 886, 885, 885, 885, + 886, 886, 885, 885, nil, 886, nil, 886, 886, 886, + 886, 886, 886, 886, nil, nil, nil, nil, nil, 886, + 886, 886, 886, 886, 886, 886, nil, nil, 886, nil, + nil, nil, nil, nil, nil, 886, nil, nil, 886, 886, + 886, 886, 886, 886, 886, 886, nil, 886, 886, 886, + nil, 886, 886, 886, 886, 886, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 886, nil, nil, 886, nil, + nil, 886, 886, nil, nil, 886, nil, nil, nil, nil, + nil, 886, nil, nil, nil, nil, nil, nil, nil, nil, + 886, nil, nil, nil, nil, 886, 886, 886, 886, nil, + 886, 886, 886, 886, nil, nil, nil, nil, 886, 886, + nil, nil, nil, 887, 887, 887, 886, 887, 886, 886, + 886, 887, 887, 886, 886, nil, 887, nil, 887, 887, + 887, 887, 887, 887, 887, nil, nil, nil, nil, nil, + 887, 887, 887, 887, 887, 887, 887, nil, nil, 887, + nil, nil, nil, nil, nil, nil, 887, nil, nil, 887, + 887, 887, 887, 887, 887, 887, 887, nil, 887, 887, + 887, nil, 887, 887, 887, 887, 887, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 887, nil, nil, 887, + nil, nil, 887, 887, nil, nil, 887, nil, nil, nil, + nil, nil, 887, nil, nil, nil, nil, nil, nil, nil, + nil, 887, nil, nil, nil, nil, 887, 887, 887, 887, + nil, 887, 887, 887, 887, nil, nil, nil, nil, 887, + 887, nil, nil, nil, 893, 893, 893, 887, 893, 887, + 887, 887, 893, 893, 887, 887, nil, 893, nil, 893, + 893, 893, 893, 893, 893, 893, nil, nil, nil, nil, + nil, 893, 893, 893, 893, 893, 893, 893, nil, nil, + 893, nil, nil, nil, nil, nil, nil, 893, nil, nil, + 893, 893, 893, 893, 893, 893, 893, 893, nil, 893, + 893, 893, nil, 893, 893, 893, 893, 893, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 893, nil, nil, + 893, nil, nil, 893, 893, nil, nil, 893, nil, nil, + nil, nil, nil, 893, nil, nil, nil, nil, nil, nil, + nil, nil, 893, nil, nil, nil, nil, 893, 893, 893, + 893, nil, 893, 893, 893, 893, nil, nil, nil, nil, + 893, 893, nil, nil, nil, 915, 915, 915, 893, 915, + 893, 893, 893, 915, 915, 893, 893, nil, 915, nil, + 915, 915, 915, 915, 915, 915, 915, nil, nil, nil, + nil, nil, 915, 915, 915, 915, 915, 915, 915, nil, + nil, 915, nil, nil, nil, nil, nil, nil, 915, nil, + nil, 915, 915, 915, 915, 915, 915, 915, 915, nil, + 915, 915, 915, nil, 915, 915, 915, 915, 915, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 915, nil, + nil, 915, nil, nil, 915, 915, nil, nil, 915, nil, + nil, nil, nil, nil, 915, nil, nil, nil, nil, nil, + nil, nil, nil, 915, nil, nil, nil, nil, 915, 915, + 915, 915, nil, 915, 915, 915, 915, nil, nil, nil, + nil, 915, 915, nil, nil, nil, 920, 920, 920, 915, + 920, 915, 915, 915, 920, 920, 915, 915, nil, 920, + nil, 920, 920, 920, 920, 920, 920, 920, nil, nil, + nil, nil, nil, 920, 920, 920, 920, 920, 920, 920, + nil, nil, 920, nil, nil, nil, nil, nil, nil, 920, + nil, nil, 920, 920, 920, 920, 920, 920, 920, 920, + nil, 920, 920, 920, nil, 920, 920, 920, 920, 920, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 920, + nil, nil, 920, nil, nil, 920, 920, nil, nil, 920, + nil, 920, nil, nil, nil, 920, nil, nil, nil, nil, + nil, nil, nil, nil, 920, nil, nil, nil, nil, 920, + 920, 920, 920, nil, 920, 920, 920, 920, nil, nil, + nil, nil, 920, 920, nil, nil, nil, 940, 940, 940, + 920, 940, 920, 920, 920, 940, 940, 920, 920, nil, + 940, nil, 940, 940, 940, 940, 940, 940, 940, nil, + nil, nil, nil, nil, 940, 940, 940, 940, 940, 940, + 940, nil, nil, 940, nil, nil, nil, nil, nil, nil, + 940, nil, nil, 940, 940, 940, 940, 940, 940, 940, + 940, 940, 940, 940, 940, nil, 940, 940, 940, 940, + 940, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 940, nil, nil, 940, nil, nil, 940, 940, nil, nil, + 940, nil, nil, nil, 940, nil, 940, nil, nil, 940, + nil, nil, nil, nil, nil, 940, nil, nil, nil, nil, + 940, 940, 940, 940, nil, 940, 940, 940, 940, nil, + nil, nil, nil, 940, 940, nil, nil, nil, 967, 967, + 967, 940, 967, 940, 940, 940, 967, 967, 940, 940, + nil, 967, nil, 967, 967, 967, 967, 967, 967, 967, + nil, nil, nil, nil, nil, 967, 967, 967, 967, 967, + 967, 967, nil, nil, 967, nil, nil, nil, nil, nil, + nil, 967, nil, nil, 967, 967, 967, 967, 967, 967, + 967, 967, nil, 967, 967, 967, nil, 967, 967, 967, + 967, 967, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 967, nil, nil, 967, nil, nil, 967, 967, nil, + nil, 967, nil, nil, nil, nil, nil, 967, nil, nil, + nil, nil, nil, nil, nil, nil, 967, nil, nil, nil, + nil, 967, 967, 967, 967, nil, 967, 967, 967, 967, + nil, nil, nil, nil, 967, 967, nil, nil, nil, 968, + 968, 968, 967, 968, 967, 967, 967, 968, 968, 967, + 967, nil, 968, nil, 968, 968, 968, 968, 968, 968, + 968, nil, nil, nil, nil, nil, 968, 968, 968, 968, + 968, 968, 968, nil, nil, 968, nil, nil, nil, nil, + nil, nil, 968, nil, nil, 968, 968, 968, 968, 968, + 968, 968, 968, nil, 968, 968, 968, nil, 968, 968, + 968, 968, 968, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 968, nil, nil, 968, nil, nil, 968, 968, + nil, nil, 968, nil, nil, nil, nil, nil, 968, nil, + nil, nil, nil, nil, nil, nil, nil, 968, nil, nil, + nil, nil, 968, 968, 968, 968, nil, 968, 968, 968, + 968, nil, nil, nil, nil, 968, 968, nil, nil, nil, + 1094, 1094, 1094, 968, 1094, 968, 968, 968, 1094, 1094, + 968, 968, nil, 1094, nil, 1094, 1094, 1094, 1094, 1094, + 1094, 1094, nil, nil, nil, nil, nil, 1094, 1094, 1094, + 1094, 1094, 1094, 1094, nil, nil, 1094, nil, nil, nil, + nil, nil, nil, 1094, nil, nil, 1094, 1094, 1094, 1094, + 1094, 1094, 1094, 1094, nil, 1094, 1094, 1094, nil, 1094, + 1094, 1094, 1094, 1094, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 1094, nil, nil, 1094, nil, nil, 1094, + 1094, nil, nil, 1094, nil, nil, nil, nil, nil, 1094, + nil, nil, nil, nil, nil, nil, nil, nil, 1094, nil, + nil, nil, nil, 1094, 1094, 1094, 1094, nil, 1094, 1094, + 1094, 1094, nil, nil, nil, nil, 1094, 1094, nil, nil, + nil, 1126, 1126, 1126, 1094, 1126, 1094, 1094, 1094, 1126, + 1126, 1094, 1094, nil, 1126, nil, 1126, 1126, 1126, 1126, + 1126, 1126, 1126, nil, nil, nil, nil, nil, 1126, 1126, + 1126, 1126, 1126, 1126, 1126, nil, nil, 1126, nil, nil, + nil, nil, nil, nil, 1126, nil, nil, 1126, 1126, 1126, + 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, 1126, nil, + 1126, 1126, 1126, 1126, 1126, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1126, nil, nil, 1126, nil, nil, + 1126, 1126, nil, nil, 1126, nil, 1126, nil, 1126, nil, + 1126, nil, nil, 1126, nil, nil, nil, nil, nil, 1126, + nil, nil, nil, nil, 1126, 1126, 1126, 1126, nil, 1126, + 1126, 1126, 1126, nil, nil, nil, nil, 1126, 1126, nil, + nil, nil, 1222, 1222, 1222, 1126, 1222, 1126, 1126, 1126, + 1222, 1222, 1126, 1126, nil, 1222, nil, 1222, 1222, 1222, + 1222, 1222, 1222, 1222, nil, nil, nil, nil, nil, 1222, + 1222, 1222, 1222, 1222, 1222, 1222, nil, nil, 1222, nil, + nil, nil, nil, nil, nil, 1222, nil, nil, 1222, 1222, + 1222, 1222, 1222, 1222, 1222, 1222, nil, 1222, 1222, 1222, + nil, 1222, 1222, 1222, 1222, 1222, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 1222, nil, nil, 1222, nil, + nil, 1222, 1222, nil, nil, 1222, nil, nil, nil, nil, + nil, 1222, nil, nil, nil, nil, nil, nil, nil, nil, + 1222, nil, nil, nil, nil, 1222, 1222, 1222, 1222, nil, + 1222, 1222, 1222, 1222, nil, nil, nil, nil, 1222, 1222, + nil, nil, nil, 1223, 1223, 1223, 1222, 1223, 1222, 1222, + 1222, 1223, 1223, 1222, 1222, nil, 1223, nil, 1223, 1223, + 1223, 1223, 1223, 1223, 1223, nil, nil, nil, nil, nil, + 1223, 1223, 1223, 1223, 1223, 1223, 1223, nil, nil, 1223, + nil, nil, nil, nil, nil, nil, 1223, nil, nil, 1223, + 1223, 1223, 1223, 1223, 1223, 1223, 1223, nil, 1223, 1223, + 1223, nil, 1223, 1223, 1223, 1223, 1223, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1223, nil, nil, 1223, + nil, nil, 1223, 1223, nil, nil, 1223, nil, nil, nil, + nil, nil, 1223, nil, nil, nil, nil, nil, nil, nil, + nil, 1223, nil, nil, nil, nil, 1223, 1223, 1223, 1223, + nil, 1223, 1223, 1223, 1223, nil, nil, nil, nil, 1223, + 1223, nil, nil, nil, 39, 39, 39, 1223, 39, 1223, + 1223, 1223, 39, 39, 1223, 1223, nil, 39, nil, 39, + 39, 39, 39, 39, 39, 39, nil, nil, nil, nil, + nil, 39, 39, 39, 39, 39, 39, 39, nil, nil, + 39, nil, nil, nil, nil, nil, nil, 39, nil, nil, + 39, 39, 39, 39, 39, 39, 39, 39, nil, 39, + 39, 39, nil, 39, 39, nil, nil, 39, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 39, nil, nil, + 39, nil, nil, 39, 39, nil, nil, 39, nil, 39, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 39, 39, 39, + 39, nil, 39, 39, 39, 39, nil, nil, nil, nil, + 39, 39, nil, nil, nil, 40, 40, 40, 39, 40, + 39, 39, 39, 40, 40, nil, nil, nil, 40, nil, + 40, 40, 40, 40, 40, 40, 40, nil, nil, nil, + nil, nil, 40, 40, 40, 40, 40, 40, 40, nil, + nil, 40, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 40, 40, 40, 40, 40, 40, 40, 40, nil, + 40, 40, 40, nil, 40, 40, nil, nil, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + nil, 40, nil, nil, 40, 40, nil, nil, 40, nil, + nil, 1211, nil, 1211, 1211, 1211, 1211, 1211, nil, nil, + nil, nil, nil, nil, nil, nil, 1211, nil, 40, 40, + 40, 40, nil, 40, 40, 40, 40, nil, nil, nil, + nil, 40, 40, nil, nil, nil, 40, nil, 1211, 40, + nil, 40, 40, 40, 76, 76, 76, nil, 76, 1211, + 1211, nil, 76, 76, 1211, nil, nil, 76, nil, 76, + 76, 76, 76, 76, 76, 76, nil, nil, nil, nil, + nil, 76, 76, 76, 76, 76, 76, 76, nil, nil, + 76, nil, nil, nil, nil, nil, nil, 76, nil, nil, + 76, 76, 76, 76, 76, 76, 76, 76, nil, 76, + 76, 76, nil, 76, 76, nil, nil, 76, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 76, nil, nil, + 76, nil, nil, 76, 76, nil, nil, 76, nil, 76, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 76, 76, 76, + 76, nil, 76, 76, 76, 76, nil, nil, nil, nil, + 76, 76, nil, nil, nil, 77, 77, 77, 76, 77, + 76, 76, 76, 77, 77, nil, nil, nil, 77, nil, + 77, 77, 77, 77, 77, 77, 77, nil, nil, nil, + nil, nil, 77, 77, 77, 77, 77, 77, 77, nil, + nil, 77, nil, nil, nil, nil, nil, nil, 77, nil, + nil, 77, 77, 77, 77, 77, 77, 77, 77, nil, + 77, 77, 77, nil, 77, 77, nil, nil, 77, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 77, nil, nil, 77, nil, + nil, 77, nil, nil, 77, 77, nil, nil, 77, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 77, 77, + 77, 77, nil, 77, 77, 77, 77, nil, nil, nil, + nil, 77, 77, nil, nil, nil, 78, 78, 78, 77, + 78, 77, 77, 77, 78, 78, nil, nil, nil, 78, + nil, 78, 78, 78, 78, 78, 78, 78, nil, nil, + nil, nil, nil, 78, 78, 78, 78, 78, 78, 78, + nil, nil, 78, nil, nil, nil, nil, nil, nil, 78, + nil, nil, 78, 78, 78, 78, 78, 78, 78, 78, + nil, 78, 78, 78, nil, 78, 78, nil, nil, 78, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 78, + nil, nil, 78, nil, nil, 78, 78, nil, nil, 78, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 78, + 78, 78, 78, nil, 78, 78, 78, 78, nil, nil, + nil, nil, 78, 78, nil, nil, nil, 343, 343, 343, + 78, 343, 78, 78, 78, 343, 343, nil, nil, nil, + 343, nil, 343, 343, 343, 343, 343, 343, 343, nil, + nil, nil, nil, nil, 343, 343, 343, 343, 343, 343, + 343, nil, nil, 343, nil, nil, nil, nil, nil, nil, + 343, nil, nil, 343, 343, 343, 343, 343, 343, 343, + 343, nil, 343, 343, 343, nil, 343, 343, nil, nil, + 343, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 343, nil, nil, 343, nil, nil, 343, 343, nil, nil, + 343, nil, nil, 1213, nil, 1213, 1213, 1213, 1213, 1213, + nil, nil, nil, nil, nil, nil, nil, nil, 1213, nil, + 343, 343, 343, 343, nil, 343, 343, 343, 343, nil, + nil, nil, nil, 343, 343, nil, nil, nil, 343, nil, + 1213, 343, nil, 343, 343, 343, 362, 362, 362, nil, + 362, 1213, 1213, nil, 362, 362, 1213, nil, nil, 362, + nil, 362, 362, 362, 362, 362, 362, 362, nil, nil, + nil, nil, nil, 362, 362, 362, 362, 362, 362, 362, + nil, nil, 362, nil, nil, nil, nil, nil, nil, 362, + nil, nil, 362, 362, 362, 362, 362, 362, 362, 362, + nil, 362, 362, 362, nil, 362, 362, nil, nil, 362, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 362, + nil, nil, 362, nil, nil, 362, 362, nil, nil, 362, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 362, + 362, 362, 362, nil, 362, 362, 362, 362, nil, nil, + nil, nil, 362, 362, nil, nil, nil, 592, 592, 592, + 362, 592, 362, 362, 362, 592, 592, nil, nil, nil, + 592, nil, 592, 592, 592, 592, 592, 592, 592, nil, + nil, nil, nil, nil, 592, 592, 592, 592, 592, 592, + 592, nil, nil, 592, nil, nil, nil, nil, nil, nil, + 592, nil, nil, 592, 592, 592, 592, 592, 592, 592, + 592, nil, 592, 592, 592, nil, 592, 592, nil, nil, + 592, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 592, nil, nil, 592, nil, nil, 592, 592, nil, nil, + 592, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 592, 592, 592, 592, nil, 592, 592, 592, 592, nil, + nil, nil, nil, 592, 592, nil, nil, nil, 601, 601, + 601, 592, 601, 592, 592, 592, 601, 601, nil, nil, + nil, 601, nil, 601, 601, 601, 601, 601, 601, 601, + nil, nil, nil, nil, nil, 601, 601, 601, 601, 601, + 601, 601, nil, nil, 601, nil, nil, nil, nil, nil, + nil, 601, nil, nil, 601, 601, 601, 601, 601, 601, + 601, 601, nil, 601, 601, 601, nil, 601, 601, nil, + nil, 601, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 601, nil, nil, 601, nil, nil, 601, 601, nil, + nil, 601, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 601, 601, 601, 601, nil, 601, 601, 601, 601, + nil, nil, nil, nil, 601, 601, nil, nil, nil, 769, + 769, 769, 601, 769, 601, 601, 601, 769, 769, nil, + nil, nil, 769, nil, 769, 769, 769, 769, 769, 769, + 769, nil, nil, nil, nil, nil, 769, 769, 769, 769, + 769, 769, 769, nil, nil, 769, nil, nil, nil, nil, + nil, nil, 769, nil, nil, 769, 769, 769, 769, 769, + 769, 769, 769, nil, 769, 769, 769, nil, 769, 769, + nil, nil, 769, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 769, nil, nil, 769, nil, nil, 769, 769, + nil, nil, 769, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 769, 769, 769, 769, nil, 769, 769, 769, + 769, nil, nil, nil, nil, 769, 769, nil, nil, nil, + 780, 780, 780, 769, 780, 769, 769, 769, 780, 780, + nil, nil, nil, 780, nil, 780, 780, 780, 780, 780, + 780, 780, nil, nil, nil, nil, nil, 780, 780, 780, + 780, 780, 780, 780, nil, nil, 780, nil, nil, nil, + nil, nil, nil, 780, nil, nil, 780, 780, 780, 780, + 780, 780, 780, 780, nil, 780, 780, 780, nil, 780, + 780, nil, nil, 780, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 780, nil, nil, 780, nil, nil, 780, + 780, nil, nil, 780, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 780, 780, 780, 780, nil, 780, 780, + 780, 780, nil, nil, nil, nil, 780, 780, nil, nil, + nil, 951, 951, 951, 780, 951, 780, 780, 780, 951, + 951, nil, nil, nil, 951, nil, 951, 951, 951, 951, + 951, 951, 951, nil, nil, nil, nil, nil, 951, 951, + 951, 951, 951, 951, 951, nil, nil, 951, nil, nil, + nil, nil, nil, nil, 951, nil, nil, 951, 951, 951, + 951, 951, 951, 951, 951, nil, 951, 951, 951, nil, + 951, 951, nil, nil, 951, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 951, nil, nil, 951, nil, nil, + 951, 951, nil, nil, 951, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 951, 951, 951, 951, nil, 951, + 951, 951, 951, nil, nil, nil, nil, 951, 951, nil, + nil, nil, 1028, 1028, 1028, 951, 1028, 951, 951, 951, + 1028, 1028, nil, nil, nil, 1028, nil, 1028, 1028, 1028, + 1028, 1028, 1028, 1028, nil, nil, nil, nil, nil, 1028, + 1028, 1028, 1028, 1028, 1028, 1028, nil, nil, 1028, nil, + nil, nil, nil, nil, nil, 1028, nil, nil, 1028, 1028, + 1028, 1028, 1028, 1028, 1028, 1028, nil, 1028, 1028, 1028, + nil, 1028, 1028, nil, nil, 1028, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 1028, nil, nil, 1028, nil, + nil, 1028, 1028, nil, nil, 1028, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 1028, 1028, 1028, 1028, nil, + 1028, 1028, 1028, 1028, nil, nil, nil, nil, 1028, 1028, + nil, nil, nil, 1110, 1110, 1110, 1028, 1110, 1028, 1028, + 1028, 1110, 1110, nil, nil, nil, 1110, nil, 1110, 1110, + 1110, 1110, 1110, 1110, 1110, nil, nil, nil, nil, nil, + 1110, 1110, 1110, 1110, 1110, 1110, 1110, nil, nil, 1110, + nil, nil, nil, nil, nil, nil, 1110, nil, nil, 1110, + 1110, 1110, 1110, 1110, 1110, 1110, 1110, nil, 1110, 1110, + 1110, nil, 1110, 1110, nil, nil, 1110, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1110, nil, nil, 1110, + nil, nil, 1110, 1110, nil, nil, 1110, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1110, 1110, 1110, 1110, + nil, 1110, 1110, 1110, 1110, nil, nil, nil, nil, 1110, + 1110, nil, nil, nil, nil, nil, nil, 1110, nil, 1110, + 1110, 1110, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, nil, nil, nil, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, nil, + nil, nil, nil, nil, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, nil, 10, nil, nil, nil, nil, + nil, nil, nil, 10, 10, nil, 10, 10, 10, 10, + 10, 10, 10, nil, nil, 10, 10, nil, nil, nil, + 10, 10, 10, 10, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 10, 10, nil, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, nil, nil, 10, 10, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 10, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, nil, nil, nil, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, nil, nil, nil, + nil, nil, 11, 11, 11, 11, 11, 11, 11, 11, + 11, nil, nil, 11, nil, nil, nil, nil, nil, nil, + nil, 11, 11, nil, 11, 11, 11, 11, 11, 11, + 11, nil, nil, 11, 11, nil, nil, nil, 11, 11, + 11, 11, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 11, 11, nil, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + nil, nil, 11, 11, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 11, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, 428, 428, + 428, 428, nil, nil, nil, 428, 428, 428, 428, 428, + 428, 428, 428, 428, 428, nil, nil, nil, nil, nil, + 428, 428, 428, 428, 428, 428, 428, 428, 428, nil, + nil, 428, nil, nil, nil, nil, nil, nil, nil, 428, + 428, nil, 428, 428, 428, 428, 428, 428, 428, nil, + nil, 428, 428, nil, nil, nil, 428, 428, 428, 428, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 428, 428, nil, 428, 428, 428, 428, + 428, 428, 428, 428, 428, 428, 428, 428, nil, nil, + 428, 428, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 428, 671, 671, 671, 671, + 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, + 671, 671, 671, 671, 671, 671, 671, 671, 671, 671, + nil, nil, nil, 671, 671, 671, 671, 671, 671, 671, + 671, 671, 671, nil, nil, nil, nil, nil, 671, 671, + 671, 671, 671, 671, 671, 671, 671, nil, nil, 671, + nil, nil, nil, nil, nil, nil, nil, 671, 671, nil, + 671, 671, 671, 671, 671, 671, 671, nil, nil, 671, + 671, nil, nil, nil, 671, 671, 671, 671, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 671, 671, nil, 671, 671, 671, 671, 671, 671, + 671, 671, 671, 671, 671, 671, nil, nil, 671, 671, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 671, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, nil, nil, + nil, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, nil, nil, nil, nil, nil, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, nil, 26, + nil, nil, nil, nil, nil, 26, 26, nil, 26, 26, + 26, 26, 26, 26, 26, nil, nil, 26, 26, nil, + nil, nil, 26, 26, 26, 26, nil, nil, nil, nil, + nil, 26, nil, nil, nil, nil, nil, nil, nil, 26, + 26, nil, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, nil, nil, 26, 746, 746, 746, + 746, 746, 746, 746, 746, 746, 746, 746, 746, 746, + 746, 746, 746, 746, 746, 746, 746, 746, 746, 746, + 746, nil, nil, nil, 746, 746, 746, 746, 746, 746, + 746, 746, 746, 746, nil, nil, nil, nil, nil, 746, + 746, 746, 746, 746, 746, 746, 746, 746, nil, nil, + 746, nil, nil, nil, nil, nil, nil, nil, 746, 746, + nil, 746, 746, 746, 746, 746, 746, 746, nil, nil, + 746, 746, nil, nil, nil, 746, 746, 746, 746, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 746, 746, nil, 746, 746, 746, 746, 746, + 746, 746, 746, 746, 746, 746, 746, nil, nil, 746, + 890, 890, 890, 890, nil, nil, 1215, nil, 1215, 1215, + 1215, 1215, 1215, nil, nil, nil, 890, 890, 890, 890, + nil, 1215, nil, 890, 890, nil, nil, nil, nil, 890, + 890, nil, nil, 890, 890, nil, nil, nil, nil, nil, + nil, nil, nil, 1215, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 890, 1215, 1215, 890, nil, nil, 1215, + 890, nil, nil, 890, nil, 890, nil, nil, nil, nil, + nil, nil, 890, nil, nil, nil, nil, nil, nil, 890, + nil, nil, nil, 890, 890, 890, 890, nil, 890, 890, + 890, 890, nil, nil, nil, nil, 890, 890, 892, 892, + 892, 892, nil, nil, 890, nil, 890, 890, 890, nil, + nil, 890, 890, nil, 892, 892, 892, 892, nil, nil, + nil, 892, 892, nil, nil, nil, nil, 892, 892, nil, + nil, 892, 892, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 892, nil, nil, 892, nil, nil, nil, 892, nil, + nil, 892, nil, 892, nil, nil, nil, nil, nil, nil, + 892, nil, nil, nil, nil, nil, nil, 892, nil, nil, + nil, 892, 892, 892, 892, nil, 892, 892, 892, 892, + nil, nil, nil, nil, 892, 892, 980, 980, 980, 980, + nil, nil, 892, nil, 892, 892, 892, nil, nil, 892, + 892, nil, 980, 980, 980, 980, nil, nil, nil, 980, + nil, nil, nil, nil, nil, 980, 980, nil, nil, 980, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 980, + nil, nil, 980, nil, nil, nil, 980, nil, nil, 980, + nil, 980, nil, nil, nil, nil, nil, nil, 715, nil, + 715, 715, 715, 715, 715, 980, nil, nil, nil, 980, + 980, 980, 980, 715, 980, 980, 980, 980, nil, nil, + nil, nil, 980, 980, 980, 988, 988, 988, 988, nil, + 980, nil, 980, 980, 980, 715, nil, 980, 980, nil, + nil, 988, 988, 988, 988, nil, 715, 715, 988, nil, + nil, 715, nil, nil, 988, 988, nil, nil, 988, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 988, nil, + nil, 988, nil, nil, nil, 988, nil, nil, 988, nil, + nil, 715, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 988, nil, nil, nil, 988, 988, + 988, 988, nil, 988, 988, 988, 988, nil, nil, nil, + nil, 988, 988, 1063, 1063, 1063, 1063, nil, nil, 988, + nil, 988, 988, 988, nil, nil, 988, 988, nil, 1063, + 1063, 1063, 1063, nil, nil, 1104, 1063, 1104, 1104, 1104, + 1104, 1104, 1063, 1063, nil, nil, 1063, nil, nil, nil, + 1104, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1063, nil, nil, 1063, + nil, nil, 1104, 1063, nil, nil, 1063, nil, 1063, nil, + nil, 1104, 1104, 1104, 1104, nil, nil, nil, 1104, nil, + nil, nil, 1063, nil, nil, nil, 1063, 1063, 1063, 1063, + nil, 1063, 1063, 1063, 1063, nil, nil, nil, nil, 1063, + 1063, 1065, 1065, 1065, 1065, nil, nil, 1063, nil, 1063, + 1063, 1063, nil, nil, 1063, 1063, nil, 1065, 1065, 1065, + 1065, nil, nil, 1209, 1065, 1209, 1209, 1209, 1209, 1209, + 1065, 1065, nil, nil, 1065, nil, nil, nil, 1209, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1065, nil, nil, 1065, nil, nil, + 1209, 1065, nil, nil, 1065, nil, nil, nil, nil, 1209, + 1209, 1209, 1209, nil, nil, nil, 1209, nil, nil, nil, + 1065, nil, nil, nil, 1065, 1065, 1065, 1065, nil, 1065, + 1065, 1065, 1065, nil, nil, nil, nil, 1065, 1065, 1068, + 1068, 1068, 1068, nil, nil, 1065, nil, 1065, 1065, 1065, + nil, nil, 1065, 1065, nil, 1068, 1068, 1068, 1068, nil, + nil, nil, 1068, 1068, nil, nil, nil, nil, 1068, 1068, + nil, nil, 1068, 1068, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1068, nil, nil, 1068, nil, nil, nil, 1068, + nil, nil, 1068, nil, 1068, nil, nil, nil, nil, nil, + nil, 1068, nil, nil, nil, nil, nil, nil, 1068, nil, + nil, nil, 1068, 1068, 1068, 1068, nil, 1068, 1068, 1068, + 1068, nil, nil, nil, nil, 1068, 1068, 1069, 1069, 1069, + 1069, nil, nil, 1068, nil, 1068, 1068, 1068, nil, nil, + 1068, 1068, nil, 1069, 1069, 1069, 1069, nil, nil, nil, + 1069, 1069, nil, nil, nil, nil, 1069, 1069, nil, nil, + 1069, 1069, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1069, nil, nil, 1069, nil, nil, nil, 1069, nil, nil, + 1069, nil, 1069, nil, nil, nil, nil, nil, nil, 1069, + nil, nil, nil, nil, nil, nil, 1069, nil, nil, nil, + 1069, 1069, 1069, 1069, nil, 1069, 1069, 1069, 1069, nil, + nil, nil, nil, 1069, 1069, 1075, 1075, 1075, 1075, nil, + nil, 1069, nil, 1069, 1069, 1069, nil, nil, 1069, 1069, + nil, 1075, 1075, 1075, 1075, nil, nil, 1239, 1075, 1239, + 1239, 1239, 1239, 1239, 1075, 1075, nil, nil, 1075, nil, + nil, nil, 1239, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 1075, nil, + nil, 1075, nil, nil, 1239, 1075, nil, nil, 1075, nil, + 1075, nil, nil, nil, nil, 1239, 1239, nil, nil, nil, + 1239, nil, nil, nil, 1075, nil, nil, nil, 1075, 1075, + 1075, 1075, nil, 1075, 1075, 1075, 1075, nil, nil, nil, + nil, 1075, 1075, 1081, 1081, 1081, 1081, nil, nil, 1075, + nil, 1075, 1075, 1075, nil, nil, 1075, 1075, nil, 1081, + 1081, 1081, 1081, nil, nil, nil, 1081, nil, nil, nil, + nil, nil, 1081, 1081, nil, nil, 1081, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1081, nil, nil, 1081, + nil, nil, nil, 1081, nil, nil, 1081, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1081, nil, nil, nil, 1081, 1081, 1081, 1081, + nil, 1081, 1081, 1081, 1081, nil, nil, nil, nil, 1081, + 1081, 1082, 1082, 1082, 1082, nil, nil, 1081, nil, 1081, + 1081, 1081, nil, nil, 1081, 1081, nil, 1082, 1082, 1082, + 1082, nil, nil, nil, 1082, nil, nil, nil, nil, nil, + 1082, 1082, nil, nil, 1082, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1082, nil, nil, 1082, nil, nil, + nil, 1082, nil, nil, 1082, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1082, nil, nil, nil, 1082, 1082, 1082, 1082, nil, 1082, + 1082, 1082, 1082, nil, nil, nil, nil, 1082, 1082, 1114, + 1114, 1114, 1114, nil, nil, 1082, nil, 1082, 1082, 1082, + nil, nil, 1082, 1082, nil, 1114, 1114, 1114, 1114, nil, + nil, nil, 1114, 1114, nil, nil, nil, nil, 1114, 1114, + nil, nil, 1114, 1114, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1114, nil, nil, 1114, nil, nil, nil, 1114, + nil, nil, 1114, nil, 1114, nil, nil, nil, nil, nil, + nil, 1114, nil, nil, nil, nil, nil, nil, 1114, nil, + nil, nil, 1114, 1114, 1114, 1114, nil, 1114, 1114, 1114, + 1114, nil, nil, nil, nil, 1114, 1114, 1194, 1194, 1194, + 1194, nil, nil, 1114, nil, 1114, 1114, 1114, nil, nil, + 1114, 1114, nil, 1194, 1194, 1194, 1194, nil, nil, nil, + 1194, nil, nil, nil, nil, nil, 1194, 1194, nil, nil, + 1194, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1194, nil, nil, 1194, nil, nil, nil, 1194, nil, nil, + 1194, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1194, nil, nil, nil, + 1194, 1194, 1194, 1194, nil, 1194, 1194, 1194, 1194, nil, + nil, nil, nil, 1194, 1194, 1202, 1202, 1202, 1202, nil, + nil, 1194, nil, 1194, 1194, 1194, nil, nil, 1194, 1194, + nil, 1202, 1202, 1202, 1202, nil, nil, nil, 1202, nil, + nil, nil, nil, nil, 1202, 1202, nil, nil, 1202, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 1202, nil, + nil, 1202, nil, nil, nil, 1202, nil, nil, 1202, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1202, nil, nil, nil, 1202, 1202, + 1202, 1202, nil, 1202, 1202, 1202, 1202, nil, nil, nil, + nil, 1202, 1202, 1206, 1206, 1206, 1206, nil, nil, 1202, + nil, 1202, 1202, 1202, nil, nil, 1202, 1202, nil, 1206, + 1206, 1206, 1206, nil, nil, nil, 1206, nil, nil, nil, + nil, nil, 1206, 1206, nil, nil, 1206, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1206, nil, nil, 1206, + nil, nil, nil, 1206, nil, nil, 1206, nil, 1206, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 1206, nil, nil, nil, 1206, 1206, 1206, 1206, + nil, 1206, 1206, 1206, 1206, nil, nil, nil, nil, 1206, + 1206, 1238, 1238, 1238, 1238, nil, nil, 1206, nil, 1206, + 1206, 1206, nil, nil, 1206, 1206, nil, 1238, 1238, 1238, + 1238, nil, nil, nil, 1238, nil, nil, nil, nil, nil, + 1238, 1238, nil, nil, 1238, nil, nil, nil, nil, nil, + nil, nil, 997, 997, 997, 997, nil, nil, nil, nil, + nil, nil, nil, nil, 1238, nil, nil, 1238, 997, 997, + 997, 1238, nil, nil, 1238, nil, nil, nil, nil, nil, + nil, 997, 997, nil, nil, 997, nil, nil, nil, nil, + 1238, nil, nil, nil, 1238, 1238, 1238, 1238, nil, 1238, + 1238, 1238, 1238, nil, nil, nil, nil, 1238, 1238, nil, + nil, nil, nil, nil, nil, 1238, nil, 1238, 1238, 1238, + nil, nil, 1238, 1238, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 997, 997, 997, 997, nil, + 997, 997, 997, 997, nil, nil, nil, nil, 997, 997, + 998, 998, 998, 998, nil, nil, 997, nil, 997, 997, + 997, nil, nil, nil, nil, nil, 998, 998, 998, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 998, + 998, nil, nil, 998, 1088, 1088, 1088, 1088, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1088, 1088, 1088, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 1088, 1088, nil, nil, 1088, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 998, 998, 998, 998, nil, 998, 998, + 998, 998, nil, nil, nil, nil, 998, 998, nil, nil, + nil, nil, nil, nil, 998, nil, 998, 998, 998, nil, + nil, nil, nil, nil, nil, nil, nil, 1088, 1088, 1088, + 1088, nil, 1088, 1088, 1088, 1088, nil, nil, nil, nil, + 1088, 1088, 1089, 1089, 1089, 1089, nil, nil, 1088, nil, + 1088, 1088, 1088, nil, nil, nil, nil, nil, 1089, 1089, + 1089, 648, nil, 648, 648, 648, 648, 648, nil, nil, + nil, 1089, 1089, nil, nil, 1089, 648, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 648, nil, + nil, nil, nil, nil, nil, nil, nil, 648, 648, 648, + 648, nil, nil, nil, 648, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 1089, 1089, 1089, 1089, nil, + 1089, 1089, 1089, 1089, nil, nil, nil, nil, 1089, 1089, + nil, nil, nil, nil, nil, nil, 1089, nil, 1089, 1089, + 1089, nil, nil, 711, 648, 711, 711, 711, 711, 711, + nil, 713, nil, 713, 713, 713, 713, 713, 711, nil, + nil, nil, nil, nil, nil, nil, 713, nil, 954, nil, + 954, 954, 954, 954, 954, nil, nil, nil, nil, nil, + 711, nil, nil, 954, nil, nil, nil, nil, 713, 711, + 711, 711, 711, nil, nil, nil, 711, 713, 713, 713, + 713, nil, nil, nil, 713, 954, nil, nil, nil, nil, + nil, nil, nil, nil, 954, 954, 954, 954, nil, nil, + 956, 954, 956, 956, 956, 956, 956, 958, nil, 958, + 958, 958, 958, 958, nil, 956, 711, nil, nil, nil, + nil, nil, 958, nil, 713, 960, nil, 960, 960, 960, + 960, 960, nil, nil, nil, nil, nil, 956, nil, nil, + 960, 954, nil, nil, 958, nil, nil, nil, 956, 956, + nil, nil, nil, 956, nil, 958, 958, nil, nil, nil, + 958, 1130, 960, 1130, 1130, 1130, 1130, 1130, nil, nil, + nil, nil, nil, 960, 960, nil, 1130, nil, 960, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 956, nil, nil, nil, nil, 1130, nil, + 958, nil, nil, nil, nil, nil, nil, nil, nil, 1130, + 1130, 226, 226, nil, 1130, 226, nil, nil, 960, nil, + nil, nil, nil, 226, 226, nil, 226, 226, 226, 226, + 226, 226, 226, nil, nil, 226, 226, nil, nil, nil, + 226, 226, 226, 226, nil, nil, nil, nil, nil, 226, + nil, nil, nil, nil, 1130, nil, nil, 226, 226, nil, + 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, + 226, 226, 227, 227, 226, nil, 227, nil, nil, nil, + nil, nil, nil, nil, 227, 227, nil, 227, 227, 227, + 227, 227, 227, 227, nil, nil, 227, 227, nil, nil, + nil, 227, 227, 227, 227, nil, nil, nil, nil, nil, + 227, nil, nil, nil, nil, nil, nil, nil, 227, 227, + nil, 227, 227, 227, 227, 227, 227, 227, 227, 227, + 227, 227, 227, 303, 303, 227, nil, 303, nil, nil, + nil, nil, nil, nil, nil, 303, 303, nil, 303, 303, + 303, 303, 303, 303, 303, nil, nil, 303, 303, nil, + nil, nil, 303, 303, 303, 303, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 303, + 303, nil, 303, 303, 303, 303, 303, 303, 303, 303, + 303, 303, 303, 303, 521, 521, 303, nil, 521, nil, + nil, nil, nil, nil, nil, nil, 521, 521, nil, 521, + 521, 521, 521, 521, 521, 521, nil, nil, 521, 521, + nil, nil, nil, 521, 521, 521, 521, nil, nil, nil, + nil, nil, 521, nil, nil, nil, nil, nil, nil, nil, + 521, 521, nil, 521, 521, 521, 521, 521, 521, 521, + 521, 521, 521, 521, 521, 522, 522, 521, nil, 522, + nil, nil, nil, nil, nil, nil, nil, 522, 522, nil, + 522, 522, 522, 522, 522, 522, 522, nil, nil, 522, + 522, nil, nil, nil, 522, 522, 522, 522, nil, nil, + nil, nil, nil, 522, nil, nil, nil, nil, nil, nil, + nil, 522, 522, nil, 522, 522, 522, 522, 522, 522, + 522, 522, 522, 522, 522, 522, 595, 595, 522, nil, + 595, nil, nil, nil, nil, nil, nil, nil, 595, 595, + nil, 595, 595, 595, 595, 595, 595, 595, nil, nil, + 595, 595, nil, nil, nil, 595, 595, 595, 595, nil, + nil, nil, nil, nil, 595, nil, nil, nil, nil, nil, + nil, nil, 595, 595, nil, 595, 595, 595, 595, 595, + 595, 595, 595, 595, 595, 595, 595, 596, 596, 595, + nil, 596, nil, nil, nil, nil, nil, nil, nil, 596, + 596, nil, 596, 596, 596, 596, 596, 596, 596, nil, + nil, 596, 596, nil, nil, nil, 596, 596, 596, 596, + nil, nil, nil, nil, nil, 596, nil, nil, nil, nil, + nil, nil, nil, 596, 596, nil, 596, 596, 596, 596, + 596, 596, 596, 596, 596, 596, 596, 596, 605, 605, + 596, nil, 605, nil, nil, nil, nil, nil, nil, nil, + 605, 605, nil, 605, 605, 605, 605, 605, 605, 605, + nil, nil, 605, 605, nil, nil, nil, 605, 605, 605, + 605, nil, nil, nil, nil, nil, 605, nil, nil, nil, + nil, nil, nil, nil, 605, 605, nil, 605, 605, 605, + 605, 605, 605, 605, 605, 605, 605, 605, 605, 606, + 606, 605, nil, 606, nil, nil, nil, nil, nil, nil, + nil, 606, 606, nil, 606, 606, 606, 606, 606, 606, + 606, nil, nil, 606, 606, nil, nil, nil, 606, 606, + 606, 606, nil, nil, nil, nil, nil, 606, nil, nil, + nil, nil, nil, nil, nil, 606, 606, nil, 606, 606, + 606, 606, 606, 606, 606, 606, 606, 606, 606, 606, + 633, 633, 606, nil, 633, nil, nil, nil, nil, nil, + nil, nil, 633, 633, nil, 633, 633, 633, 633, 633, + 633, 633, nil, nil, 633, 633, nil, nil, nil, 633, + 633, 633, 633, nil, nil, nil, nil, nil, 633, nil, + nil, nil, nil, nil, nil, nil, 633, 633, nil, 633, + 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, + 633, 634, 634, 633, nil, 634, nil, nil, nil, nil, + nil, nil, nil, 634, 634, nil, 634, 634, 634, 634, + 634, 634, 634, nil, nil, 634, 634, nil, nil, nil, + 634, 634, 634, 634, nil, nil, nil, nil, nil, 634, + nil, nil, nil, nil, nil, nil, nil, 634, 634, nil, + 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, + 634, 634, 640, 640, 634, nil, 640, nil, nil, nil, + nil, nil, nil, nil, 640, 640, nil, 640, 640, 640, + 640, 640, 640, 640, nil, nil, 640, 640, nil, nil, + nil, 640, 640, 640, 640, nil, nil, nil, nil, nil, + 640, nil, nil, nil, nil, nil, nil, nil, 640, 640, + nil, 640, 640, 640, 640, 640, 640, 640, 640, 640, + 640, 640, 640, 641, 641, 640, nil, 641, nil, nil, + nil, nil, nil, nil, nil, 641, 641, nil, 641, 641, + 641, 641, 641, 641, 641, nil, nil, 641, 641, nil, + nil, nil, 641, 641, 641, 641, nil, nil, nil, nil, + nil, 641, nil, nil, nil, nil, nil, nil, nil, 641, + 641, nil, 641, 641, 641, 641, 641, 641, 641, 641, + 641, 641, 641, 641, 678, 678, 641, nil, 678, nil, + nil, nil, nil, nil, nil, nil, 678, 678, nil, 678, + 678, 678, 678, 678, 678, 678, nil, nil, 678, 678, + nil, nil, nil, 678, 678, 678, 678, nil, nil, nil, + nil, nil, 678, nil, nil, nil, nil, nil, nil, nil, + 678, 678, nil, 678, 678, 678, 678, 678, 678, 678, + 678, 678, 678, 678, 678, 679, 679, 678, nil, 679, + nil, nil, nil, nil, nil, nil, nil, 679, 679, nil, + 679, 679, 679, 679, 679, 679, 679, nil, nil, 679, + 679, nil, nil, nil, 679, 679, 679, 679, nil, nil, + nil, nil, nil, 679, nil, nil, nil, nil, nil, nil, + nil, 679, 679, nil, 679, 679, 679, 679, 679, 679, + 679, 679, 679, 679, 679, 679, 1127, 1127, 679, nil, + 1127, nil, nil, nil, nil, nil, nil, nil, 1127, 1127, + nil, 1127, 1127, 1127, 1127, 1127, 1127, 1127, nil, nil, + 1127, 1127, nil, nil, nil, 1127, 1127, 1127, 1127, nil, + nil, nil, nil, nil, 1127, nil, nil, nil, nil, nil, + nil, nil, 1127, 1127, nil, 1127, 1127, 1127, 1127, 1127, + 1127, 1127, 1127, 1127, 1127, 1127, 1127, 1128, 1128, 1127, + nil, 1128, nil, nil, nil, nil, nil, nil, nil, 1128, + 1128, nil, 1128, 1128, 1128, 1128, 1128, 1128, 1128, nil, + nil, 1128, 1128, nil, nil, nil, 1128, 1128, 1128, 1128, + nil, nil, nil, nil, nil, 1128, nil, nil, nil, nil, + nil, nil, nil, 1128, 1128, nil, 1128, 1128, 1128, 1128, + 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1128, 1178, 1178, + 1128, nil, 1178, nil, nil, nil, nil, nil, nil, nil, + 1178, 1178, nil, 1178, 1178, 1178, 1178, 1178, 1178, 1178, + nil, nil, 1178, 1178, nil, nil, nil, 1178, 1178, 1178, + 1178, nil, nil, nil, nil, nil, 1178, nil, nil, nil, + nil, nil, nil, nil, 1178, 1178, nil, 1178, 1178, 1178, + 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, 1178, nil, + nil, 1178 ] + +racc_action_pointer = [ + nil, 52, 1004, 256, nil, -110, nil, 5323, 1133, 170, + 24870, 24998, 190, nil, 176, 191, 482, 259, -62, 58, + 124, 138, nil, -68, 5454, 1004, 25382, 349, nil, 171, + nil, -8, 5595, 5705, 5839, 5970, 6101, nil, 1148, 23012, + 23143, nil, 320, 356, 466, 435, 6232, 6363, 310, 6494, + 6625, 556, 6756, 375, 333, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 6897, nil, 1292, 7034, 7165, -23, + nil, 7296, 7427, nil, nil, 7558, 23282, 23413, 23544, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 235, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 0, 112, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 7701, nil, nil, nil, nil, + 7844, 7975, 8106, 8237, 8380, nil, 1436, nil, 673, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 393, nil, 1580, + 8511, 8642, 8773, 8904, 9035, 9166, 27600, 27661, nil, nil, + 387, 1724, 415, nil, 358, 15855, 430, 1868, 9297, 9428, + 9559, nil, nil, 519, -85, -29, 550, -23, 469, 584, + nil, 9690, 214, 243, 2012, 586, nil, nil, 9821, 9952, + 10083, 10214, 10345, 10476, 10607, 10738, 10869, 11000, 11131, 11262, + 11393, 11524, 11655, 11786, 11917, 12048, 12179, 12310, 12441, 12572, + nil, nil, nil, nil, 12703, nil, nil, 339, 409, 513, + 523, 531, 556, 582, 583, 625, 630, nil, nil, nil, + 12834, nil, nil, 27722, nil, nil, 594, 12965, 13096, nil, + nil, nil, nil, nil, nil, nil, 13227, nil, 1436, nil, + 562, 572, nil, 13358, 624, nil, 13489, nil, nil, 13620, + 13751, nil, nil, -77, nil, 13894, 1277, 623, 619, 2156, + 636, 683, 647, 23675, 2300, 692, 813, 831, 745, 870, + nil, 720, 686, 225, 741, 746, nil, nil, nil, 757, + 360, 716, 23814, nil, 523, 898, 2732, 2876, 790, nil, + 792, 14025, nil, 772, 2444, nil, nil, 275, 429, 777, + 761, 539, 795, nil, 606, -1, 11, 14156, 2588, 2732, + 230, 875, 768, -18, 10, 903, 850, 11, 883, nil, + nil, 479, 728, 590, nil, 904, nil, 802, 14287, nil, + 15885, nil, 193, 294, 405, 463, 468, -41, -27, 506, + nil, nil, nil, nil, nil, nil, nil, 797, 25126, nil, + nil, nil, nil, 801, nil, 876, 788, 789, 14418, nil, + nil, 778, nil, 918, 140, 897, nil, nil, 1148, nil, + nil, nil, nil, nil, 1292, 814, nil, 815, 817, 613, + 691, 14559, nil, nil, nil, nil, 222, 361, 862, nil, + nil, 14691, 14827, 14964, 946, 947, nil, nil, -1, 828, + 827, 841, nil, nil, 843, 844, 845, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 834, 2574, nil, nil, + 15095, nil, nil, nil, nil, nil, nil, nil, 932, nil, + nil, 933, 385, 15226, 976, nil, nil, nil, -33, nil, + 903, 27783, 27844, 15357, 141, 15488, 15619, 15750, 853, 854, + nil, nil, nil, 3020, 3164, 672, 791, 934, 937, 947, + 950, 4748, 4892, 5036, 3308, 3452, 3596, 3740, 3884, 4028, + 2760, 2904, 4172, 4316, 1580, 4460, nil, -7, nil, 15891, + nil, nil, nil, nil, 16021, 887, 885, 890, nil, nil, + nil, 899, nil, nil, 16152, nil, 16283, nil, 16414, nil, + 217, nil, nil, nil, 16557, 1421, nil, 900, 898, nil, + nil, 899, 23945, 911, 16700, 27905, 27966, 1004, 954, nil, + nil, 24076, 911, nil, 16831, 28027, 28088, 16962, 4604, 17093, + nil, nil, 1038, 974, nil, 17224, nil, nil, 17355, nil, + nil, nil, 2876, 1072, nil, 3020, 62, 1076, 1081, 236, + 1084, 17486, 17617, 28149, 28210, 27, nil, nil, 1046, nil, + 28271, 28332, 17748, nil, nil, 490, 3164, nil, 27320, nil, + nil, nil, nil, 725, nil, nil, nil, 975, nil, nil, + 400, nil, 461, nil, nil, 964, nil, 966, nil, nil, + nil, 25254, nil, 17891, 18022, 970, 18153, 18284, 28393, 28454, + 18427, 18558, 715, 1014, 18689, 18820, 18951, 19082, 1020, nil, + nil, 19213, nil, 19344, 1021, nil, 1075, nil, 259, 1724, + 1085, 1115, 19475, nil, nil, nil, nil, 715, nil, nil, + 649, 27412, nil, 27420, nil, 25827, nil, 986, 19606, nil, + 2603, nil, 1001, 1003, 1566, 1007, nil, nil, nil, nil, + 1095, 1098, nil, nil, nil, 237, 280, 471, 610, 1015, + 19737, 19868, nil, nil, nil, 1023, 25495, nil, 1147, nil, + 1130, -20, nil, nil, 19999, nil, 1047, 1052, 1153, nil, + 1031, nil, 1097, nil, nil, nil, 20130, nil, 134, 24207, + 1052, nil, 1057, 217, 248, 1100, 250, 1148, 1101, 1071, + 24338, nil, 585, 1142, 1868, 20261, nil, nil, 635, 824, + nil, 1214, nil, nil, nil, nil, nil, 1220, 1225, nil, + nil, 26, 1105, 40, 41, 151, 177, 3308, 827, 1292, + nil, 1108, 3452, 20392, nil, 1233, 63, 1114, nil, nil, + nil, 3596, nil, nil, 1113, nil, 1118, 1126, 1127, nil, + nil, 1129, 20523, 1142, 390, 391, 720, 859, nil, 2012, + 20654, nil, 1140, nil, nil, nil, nil, nil, nil, nil, + 1162, nil, nil, nil, 20785, 20916, 21047, 1270, nil, 3740, + 1147, 1195, nil, nil, 1152, nil, 1238, nil, nil, 1166, + 1167, nil, 1168, 1171, nil, 1172, nil, nil, nil, 1176, + 2633, 2613, nil, nil, 21178, 21309, 21440, 21571, 436, 352, + 25578, nil, 25676, 21702, nil, nil, 1199, nil, nil, 1215, + 1199, nil, nil, 788, 3884, nil, nil, nil, 1198, 254, + nil, 81, nil, 1324, nil, 21833, 1325, nil, nil, nil, + 21964, 4028, 71, 1339, nil, 1343, 527, 4172, nil, nil, + nil, nil, 1237, 1283, 1251, nil, 1246, 484, nil, nil, + 22095, nil, 2156, 1339, 1343, 2300, nil, 4316, nil, nil, + 32, 24469, nil, nil, 27437, nil, 27489, nil, 27496, nil, + 27514, nil, nil, nil, nil, 1255, 1258, 22226, 22357, nil, + -77, nil, nil, nil, nil, 1287, nil, nil, nil, 555, + 25774, 266, nil, 1271, 1354, 1273, nil, nil, 25873, nil, + nil, 476, nil, nil, 785, nil, nil, 27090, 27188, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 1616, 603, nil, nil, 2444, 4460, nil, nil, 1283, 1284, + nil, 1286, 1289, 1291, nil, 1316, 1296, 1284, 24600, nil, + nil, nil, nil, nil, 33, nil, nil, nil, 193, nil, + nil, nil, 1424, 4604, 4748, 1710, nil, nil, nil, nil, + 4892, 34, 35, 1190, 1388, 36, nil, 1311, 1312, 1315, + 1316, 3100, 3244, 25971, 1399, 26069, 86, 157, 26167, 26265, + 699, -32, 1322, 1342, nil, 26363, nil, 1340, 290, nil, + 1362, 26461, 26559, nil, 635, 1390, 266, nil, 27222, 27320, + nil, nil, nil, nil, 22488, nil, nil, nil, 813, nil, + nil, 15910, nil, nil, 25974, nil, 14622, nil, nil, 1369, + 24731, 1334, 1424, 5036, 26657, nil, nil, nil, nil, 1379, + 1487, 678, nil, nil, nil, 1509, 22619, 28515, 28576, 42, + 27550, nil, nil, nil, nil, 1384, nil, 1389, nil, nil, + nil, nil, 1393, 1395, 1396, 1400, 1402, 1405, nil, nil, + nil, 1453, 1415, 1416, nil, 1420, nil, nil, -69, 1422, + nil, nil, nil, nil, nil, nil, 1430, 1428, nil, nil, + 1429, 1430, 1433, 1435, nil, 1436, nil, 1436, 28637, nil, + 864, 98, 841, nil, nil, nil, 1854, nil, 1440, 102, + 138, 145, 181, 1438, 26755, nil, nil, nil, nil, nil, + nil, nil, 26853, nil, 392, nil, 26951, nil, nil, 26072, + nil, 23190, nil, 23722, nil, 25565, nil, nil, 1484, 1488, + nil, nil, 22750, 22881, nil, 146, nil, 1454, 1455, nil, + nil, 1456, 1459, 1460, 1461, 5180, nil, nil, 27049, 26366, + nil, nil, nil, nil, 35, 1463, nil, nil, nil, nil ] + +racc_action_default = [ + -1, -742, -4, -742, -2, -728, -5, -742, -8, -742, + -742, -742, -742, -31, -742, -742, -36, -742, -742, -638, + -638, -314, -53, -730, -742, -60, -742, -68, -69, -70, + -74, -288, -288, -288, -325, -352, -353, -87, -13, -91, + -99, -101, -742, -625, -626, -742, -742, -742, -742, -742, + -742, -239, -742, -730, -255, -305, -306, -307, -308, -309, + -310, -311, -312, -313, -718, -316, -13, -741, -706, -333, + -335, -742, -742, -62, -62, -728, -742, -742, -742, -354, + -355, -357, -358, -359, -360, -419, -563, -564, -565, -566, + -589, -569, -570, -591, -593, -576, -581, -585, -587, -602, + -603, -604, -589, -606, -608, -609, -610, -611, -612, -613, + -614, -716, -717, -617, -618, -619, -620, -621, -622, -623, + -624, -629, -630, 1250, -3, -729, -737, -738, -739, -7, + -742, -742, -742, -742, -742, -9, -4, -19, -742, -130, + -131, -132, -133, -134, -135, -136, -140, -141, -142, -143, + -144, -145, -146, -147, -148, -149, -150, -151, -152, -153, + -154, -155, -156, -157, -158, -159, -160, -161, -162, -163, + -164, -165, -166, -167, -168, -169, -170, -171, -172, -173, + -174, -175, -176, -177, -178, -179, -180, -181, -182, -183, + -184, -185, -186, -187, -188, -189, -190, -191, -192, -193, + -194, -195, -196, -197, -198, -199, -200, -201, -202, -203, + -204, -205, -206, -207, -208, -209, -210, -24, -137, -13, + -742, -742, -742, -742, -742, -278, -742, -742, -726, -727, + -742, -13, -637, -635, -661, -661, -742, -13, -742, -742, + -730, -731, -57, -742, -625, -626, -742, -314, -742, -742, + -245, -742, -638, -638, -13, -742, -741, -741, -222, -223, + -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, + -742, -742, -742, -742, -742, -742, -742, -742, -742, -742, + -259, -260, -261, -262, -742, -64, -65, -742, -130, -131, + -170, -171, -172, -188, -193, -200, -203, -625, -626, -704, + -742, -428, -430, -742, -724, -725, -75, -278, -742, -332, + -434, -443, -445, -82, -440, -83, -730, -84, -266, -283, + -293, -293, -287, -291, -294, -295, -299, -589, -708, -712, + -715, -85, -86, -728, -14, -742, -17, -742, -89, -13, + -730, -742, -92, -95, -13, -107, -108, -742, -742, -115, + -325, -328, -730, -742, -638, -638, -352, -353, -356, -441, + -742, -97, -742, -103, -322, -742, -224, -225, -607, -233, + -234, -742, -246, -741, -13, -318, -267, -730, -730, -742, + -742, -730, -742, -334, -61, -742, -742, -742, -13, -13, + -728, -742, -729, -625, -626, -742, -742, -314, -742, -370, + -371, -125, -126, -742, -128, -742, -314, -633, -742, -348, + -661, -567, -742, -742, -742, -742, -742, -742, -742, -742, + -6, -740, -25, -26, -27, -28, -29, -742, -742, -21, + -22, -23, -138, -742, -32, -35, -301, -742, -299, -300, + -33, -742, -37, -742, -314, -50, -52, -211, -271, -294, + -54, -55, -38, -212, -271, -730, -279, -293, -293, -716, + -717, -288, -438, -718, -719, -720, -717, -716, -288, -437, + -439, -718, -720, -742, -555, -742, -383, -384, -687, -730, + -703, -703, -643, -644, -646, -646, -646, -660, -662, -663, + -664, -665, -666, -667, -668, -669, -670, -742, -672, -674, + -676, -681, -683, -684, -685, -692, -694, -695, -697, -698, + -699, -701, -742, -742, -742, -46, -219, -56, -730, -331, + -742, -742, -742, -278, -322, -742, -742, -742, -742, -742, + -741, -457, -741, -220, -221, -226, -227, -228, -229, -230, + -231, -235, -236, -237, -238, -240, -241, -242, -243, -244, + -247, -248, -249, -250, -730, -263, -66, -730, -449, -288, + -716, -717, -72, -76, -662, -730, -293, -730, -289, -447, + -449, -730, -327, -284, -742, -285, -742, -290, -742, -298, + -742, -711, -714, -12, -729, -16, -18, -730, -88, -320, + -104, -93, -742, -730, -278, -742, -742, -114, -742, -637, + -607, -742, -100, -105, -742, -742, -742, -742, -264, -742, + -265, -741, -742, -742, -268, -736, -735, -270, -736, -323, + -324, -707, -13, -361, -362, -13, -742, -742, -742, -742, + -742, -742, -278, -742, -742, -322, -62, -125, -126, -127, + -742, -742, -278, -344, -631, -742, -13, -420, -661, -423, + -568, -590, -595, -742, -597, -571, -592, -742, -594, -575, + -742, -578, -742, -580, -583, -742, -584, -742, -605, -10, + -20, -742, -30, -742, -742, -304, -742, -278, -742, -742, + -742, -742, -442, -742, -280, -282, -742, -742, -77, -277, + -435, -742, -447, -742, -79, -436, -44, -47, -730, -256, + -253, -741, -741, -350, -524, -686, -636, -742, -641, -642, + -742, -742, -653, -742, -656, -742, -658, -742, -742, -372, + -742, -374, -376, -379, -382, -730, -675, -696, -700, -639, + -45, -254, -351, -330, -732, -716, -717, -717, -716, -730, + -742, -742, -741, -455, -741, -742, -742, -705, -742, -450, + -71, -431, -447, -273, -280, -275, -742, -409, -742, -326, + -293, -292, -296, -297, -709, -710, -742, -15, -90, -742, + -96, -102, -730, -716, -717, -276, -721, -113, -742, -98, + -742, -218, -321, -232, -251, -742, -317, -319, -730, -741, + -363, -741, -63, -364, -365, -338, -339, -742, -742, -741, + -341, -742, -730, -716, -717, -721, -321, -13, -125, -126, + -129, -730, -13, -742, -346, -742, -742, -730, -596, -600, + -601, -13, -572, -573, -577, -579, -582, -586, -588, -139, + -34, -302, -299, -730, -716, -717, -717, -716, -51, -272, + -742, -733, -293, -40, -214, -41, -215, -78, -42, -217, + -742, -43, -216, -80, -742, -742, -742, -741, -368, -13, + -556, -741, -557, -558, -703, -682, -687, -702, -645, -646, + -646, -673, -646, -646, -693, -646, -670, -386, -688, -730, + -742, -742, -381, -671, -742, -742, -742, -742, -442, -730, + -742, -456, -742, -742, -67, -429, -409, -433, -432, -742, + -730, -444, -410, -730, -13, -446, -286, -713, -94, -442, + -106, -730, -269, -742, -366, -742, -742, -340, -342, -741, + -742, -13, -442, -742, -442, -742, -742, -13, -349, -421, + -424, -426, -413, -742, -742, -574, -303, -442, -39, -213, + -281, -81, -48, -49, -258, -257, -11, -13, -562, -369, + -742, -742, -560, -640, -742, -649, -742, -651, -742, -654, + -742, -657, -659, -373, -375, -377, -380, -742, -742, -58, + -465, -468, -469, -470, -471, -473, -475, -478, -479, -534, + -730, -491, -494, -504, -508, -513, -515, -516, -519, -520, + -589, -523, -525, -526, -527, -532, -533, -742, -742, -537, + -538, -539, -540, -541, -542, -543, -544, -545, -546, -547, + -742, -742, -553, -59, -252, -13, -73, -274, -703, -703, + -390, -392, -392, -392, -408, -742, -730, -670, -678, -679, + -690, -448, -329, -336, -742, -337, -741, -296, -741, -343, + -345, -632, -742, -13, -13, -742, -422, -598, -599, -561, + -13, -625, -626, -742, -742, -314, -559, -646, -646, -646, + -646, -742, -742, -466, -742, -742, -476, -477, -742, -742, + -742, -496, -730, -730, -490, -497, -501, -742, -742, -493, + -742, -742, -742, -507, -514, -518, -742, -522, -530, -531, + -535, -536, -548, -549, -742, -126, -551, -451, -742, -388, + -389, -393, -399, -401, -742, -404, -742, -406, -411, -742, + -742, -677, -742, -13, -742, -452, -453, -454, -347, -742, + -742, -730, -415, -417, -418, -555, -278, -742, -742, -322, + -742, -647, -650, -652, -655, -378, -467, -504, -472, -474, + -483, -487, -730, -730, -730, -730, -730, -730, -552, -488, + -489, -511, -498, -499, -502, -730, -589, -734, -730, -505, + -509, -512, -517, -521, -528, -529, -730, -703, -680, -391, + -392, -392, -392, -392, -691, -392, -412, -689, -742, -322, + -741, -742, -462, -425, -427, -414, -742, -554, -730, -716, + -717, -721, -321, -646, -742, -480, -481, -482, -484, -485, + -486, -503, -742, -492, -742, -495, -742, -550, -387, -742, + -396, -742, -398, -742, -402, -742, -405, -407, -321, -721, + -367, -458, -742, -742, -416, -442, -648, -505, -500, -506, + -510, -392, -392, -392, -392, -13, -463, -464, -742, -742, + -394, -397, -400, -403, -741, -392, -459, -460, -461, -395 ] + +racc_goto_table = [ + 44, 302, 310, 314, 412, 44, 142, 142, 455, 385, + 386, 798, 286, 390, 383, 567, 419, 319, 319, 319, + 622, 625, 142, 226, 298, 242, 128, 384, 384, 475, + 701, 384, 285, 639, 304, 514, 44, 346, 346, 718, + 496, 496, 15, 342, 358, 358, 857, 15, 630, 708, + 709, 388, 389, 137, 218, 871, 145, 145, 530, 532, + 439, 440, 575, 742, 44, 744, 819, 731, 422, 423, + 424, 425, 913, 563, 394, 298, 298, 453, 15, 17, + 125, 358, 358, 358, 17, 864, 384, 384, 384, 384, + 565, 516, 135, 870, 368, 872, 128, 303, 461, 468, + 464, 464, 446, 124, 338, 446, 15, 237, 321, 321, + 321, 306, 313, 315, 602, 17, 399, 682, 874, 446, + 696, 479, 512, 44, 361, 320, 320, 320, 725, 487, + 487, 452, 44, 761, 44, 761, 916, 340, 609, 4, + 933, 378, 381, 17, 756, 515, 764, 614, 617, 1022, + 964, 621, 890, 1174, 892, 230, 236, 969, 377, 1013, + 730, 972, 1122, 972, 1079, 15, 1124, 317, 331, 332, + 966, 129, 612, 391, 15, 559, 15, 464, 450, 451, + 1072, 904, 748, 763, 1090, 1091, 1137, 8, 764, 1, + 1144, 1147, 8, 2, 758, 517, 518, 462, 1153, 575, + 1155, 946, 17, 407, 409, 767, 1159, 824, 319, 826, + 341, 17, 827, 17, 828, 217, 496, 44, 660, 662, + 400, 434, 445, 472, 763, 445, 1025, 435, 1073, 44, + 599, 599, 428, 792, 287, 44, 746, 752, 375, 445, + 671, 580, 371, 761, 761, 379, 751, 299, 521, 712, + 714, 716, 44, 380, 398, 764, 557, 643, 1174, 15, + 374, 441, 719, 1136, 441, 613, 812, 850, 1142, 1145, + 810, 15, 927, 427, 646, 1164, 1165, 15, 441, 656, + 658, 661, 661, 763, 965, 1023, 797, 1024, 1102, 420, + 319, 319, 304, 763, 15, 731, 17, 649, 17, 319, + 1026, 17, 1121, 1224, 871, 487, 739, 1124, 17, 647, + 8, 437, 437, 761, 17, 17, 1143, 1146, 1227, 426, + 1015, 8, 929, 410, 310, 626, 1228, 899, 816, 1229, + 314, 17, 964, 44, 1043, 1044, 1057, 44, 1203, 558, + 237, 346, 44, 384, 770, 569, 645, 1170, 358, 1109, + 1135, 879, 595, 779, 128, 556, 570, 896, 1115, 874, + 346, 1181, 1246, 763, 384, 1235, 603, 358, 1138, 1139, + 605, 1068, 44, 1069, 1078, 15, 785, 772, 516, 15, + 453, 1182, 321, 1116, 15, 972, 44, 44, 528, 529, + 321, 433, 1081, 461, 468, 464, 464, 1161, 566, 320, + 633, 888, 1162, 861, 950, 338, 600, 320, 584, 944, + 338, 128, 17, 411, 15, 802, 17, 413, 414, 415, + 586, 17, 416, 1093, 142, 811, 341, 591, 15, 15, + 417, 583, 689, 953, 909, 418, 921, 818, 587, 695, + 1047, 568, 237, 593, 815, 871, 1114, 821, 678, 571, + 813, 17, 1036, 869, 496, 847, 697, 781, 865, 1168, + 833, 853, 900, 1220, 922, 17, 17, 775, nil, 464, + 464, 670, nil, 924, 145, nil, 1167, 775, nil, 464, + 464, nil, nil, 1171, nil, 719, 1172, nil, 629, 882, + 1152, nil, 462, nil, nil, 937, 697, 1160, nil, 761, + nil, 906, 943, nil, nil, 775, 319, 464, 464, nil, + 764, 341, nil, 775, 464, 464, 341, 496, 472, 496, + 585, 908, 944, nil, nil, nil, 825, nil, 825, 763, + 689, nil, nil, 729, nil, 817, nil, nil, nil, 844, + 846, 688, 862, 487, 849, nil, 852, nil, 694, nil, + 461, 468, 464, 464, nil, nil, nil, 446, 912, 871, + 627, 628, nil, nil, nil, nil, 462, 446, 446, nil, + 1110, nil, 446, nil, 446, nil, 462, 319, nil, nil, + nil, nil, 44, 906, nil, 1050, nil, 1099, 1100, 1247, + 346, 1231, 472, 843, 845, nil, 603, 358, 848, 346, + 851, 919, 472, 866, 462, 603, 358, nil, nil, 1160, + 925, nil, 462, nil, 807, 319, nil, 1160, nil, nil, + 44, 1230, nil, 44, 15, 319, 1248, nil, nil, nil, + 472, nil, nil, nil, 955, 957, 472, 959, 961, 750, + 962, 1096, 1074, nil, 44, 719, 719, 793, 760, 462, + nil, nil, nil, 1230, nil, nil, nil, nil, nil, nil, + 319, 17, 15, nil, nil, 15, 814, 142, nil, 1113, + nil, 44, nil, nil, nil, 472, nil, 445, 44, nil, + nil, 1187, nil, nil, nil, nil, 15, 445, 445, 788, + nil, nil, 445, 939, 445, 1117, 898, nil, nil, 17, + 1148, nil, 17, nil, nil, nil, nil, nil, nil, 1027, + nil, nil, nil, 15, 829, nil, 441, 145, nil, nil, + 15, 446, 801, 17, 897, 1042, 441, 441, nil, 1141, + nil, 441, 894, 441, 1149, 1150, 1208, 844, 846, 849, + 852, 911, 142, nil, nil, nil, 689, 938, nil, 695, + 17, 926, 285, 17, nil, nil, nil, 17, 842, nil, + 496, nil, nil, 17, 17, nil, nil, 346, 17, 384, + 17, nil, nil, 603, 358, nil, nil, nil, 346, nil, + nil, 993, nil, 993, 910, 358, 991, nil, 991, nil, + nil, nil, nil, 437, 789, nil, nil, 791, nil, 18, + nil, nil, nil, nil, 18, 44, nil, 1198, 1199, 1200, + 44, nil, nil, 1097, nil, 867, 1221, nil, 867, 44, + 939, 243, 1131, 1132, 1133, 1134, 719, 719, 842, nil, + nil, 243, 243, 243, nil, 18, 347, 347, 697, nil, + nil, 445, 1120, nil, nil, nil, nil, 15, nil, nil, + 1225, nil, 15, 1034, nil, nil, nil, 44, 830, nil, + nil, 15, nil, 18, nil, 838, nil, nil, 243, 243, + nil, 384, 243, 395, 405, 405, nil, nil, nil, nil, + 441, nil, nil, nil, 17, nil, nil, nil, 1007, 17, + 1007, nil, nil, nil, nil, nil, nil, nil, 17, 15, + nil, nil, 44, nil, 1086, nil, nil, 1027, nil, 1188, + 1027, nil, nil, nil, nil, nil, nil, 17, nil, 44, + nil, nil, 18, nil, nil, 44, nil, 243, 243, 243, + 243, 18, nil, 18, nil, nil, 17, nil, nil, nil, + nil, nil, nil, nil, 15, 44, 1019, 1041, nil, 1052, + nil, nil, nil, nil, nil, nil, 358, nil, 1226, 993, + 993, 15, nil, nil, 991, 991, nil, 15, nil, 993, + nil, nil, nil, nil, 991, 993, nil, nil, 1007, 923, + 991, 17, nil, nil, nil, nil, 1007, 15, nil, nil, + nil, 1056, nil, 934, 866, 1007, 1007, nil, 17, 775, + nil, 464, 464, nil, 17, 993, nil, nil, nil, nil, + 991, 1020, nil, 44, nil, 1027, 18, 243, 443, 243, + 243, 443, 243, 873, 17, 875, 298, nil, 18, nil, + nil, 949, 1166, 358, 18, 443, 243, 243, nil, nil, + nil, 44, 44, nil, nil, nil, nil, 970, 44, 970, + 384, 18, 464, nil, nil, 15, nil, nil, 1127, nil, + nil, 1007, nil, 1007, nil, nil, 1007, 1007, nil, nil, + 1204, nil, nil, 1007, nil, nil, 1031, nil, nil, 1007, + 1007, nil, nil, 15, 15, nil, 1007, 1007, nil, nil, + 15, nil, 17, 1038, 1103, 1105, 1107, 243, 462, nil, + nil, nil, nil, nil, 243, 243, 233, 233, 298, 319, + nil, 44, 1007, 243, nil, 358, nil, nil, nil, 1049, + 17, 17, nil, nil, 472, nil, nil, 17, nil, nil, + nil, nil, 18, nil, nil, nil, 18, 1071, nil, nil, + 347, 18, nil, nil, 1019, 1085, nil, 1019, nil, 1019, + nil, nil, nil, 15, 376, nil, nil, 1028, nil, 347, + 1236, 1237, nil, nil, nil, 19, nil, nil, nil, nil, + 19, 18, nil, nil, 472, nil, nil, nil, 384, 384, + nil, nil, nil, nil, 243, 18, 18, nil, nil, nil, + 17, nil, 1007, nil, nil, nil, nil, nil, nil, nil, + 1007, 19, 354, 354, 1007, 243, 867, nil, nil, 1020, + nil, nil, 1020, 1021, 1020, 1119, nil, nil, nil, nil, + 1071, nil, 1125, nil, nil, 1071, 1071, nil, nil, 19, + nil, nil, nil, 44, nil, nil, 1007, nil, 1158, 354, + 354, 354, nil, 1210, 1212, 1214, 1216, 239, 1217, nil, + nil, nil, 1019, nil, 1019, nil, 1019, nil, 1019, nil, + nil, nil, nil, 999, 1058, 999, 1059, nil, 1060, nil, + 243, 970, nil, nil, nil, 15, nil, 373, nil, nil, + nil, nil, 1019, nil, nil, 1180, nil, nil, 19, nil, + nil, nil, nil, nil, nil, nil, nil, 19, 20, 19, + nil, nil, nil, 20, 1240, 1241, 1242, 1243, nil, nil, + 243, nil, 17, nil, nil, nil, nil, 1020, 1249, 1020, + 243, 1020, nil, 1020, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 20, 355, 355, nil, nil, 233, + 233, nil, nil, 531, 531, nil, nil, 1020, nil, nil, + nil, nil, 1028, 999, nil, 1028, nil, nil, 1028, nil, + 1028, 999, 20, nil, nil, nil, nil, nil, nil, nil, + 999, 999, 355, 355, 355, nil, nil, nil, nil, nil, + nil, 18, 19, nil, 19, nil, nil, 19, nil, 347, + nil, 243, nil, nil, 19, nil, nil, nil, 347, nil, + 19, 19, nil, nil, nil, nil, nil, 1244, nil, nil, + 519, nil, nil, nil, 1173, nil, 1175, 19, nil, 18, + nil, 20, 18, nil, nil, nil, nil, nil, nil, 243, + 20, nil, 20, nil, nil, nil, 999, nil, 999, 243, + 1193, 999, 999, 18, nil, nil, nil, nil, 999, nil, + nil, nil, nil, nil, 999, 999, nil, nil, nil, nil, + 610, 999, 999, 1028, nil, 1028, nil, 1028, nil, 1028, + 18, nil, nil, 443, 243, nil, nil, 18, nil, nil, + nil, nil, nil, 443, 443, nil, 572, 999, 443, nil, + 443, nil, nil, 1028, nil, nil, nil, nil, 19, nil, + nil, nil, 19, nil, nil, nil, 354, 19, nil, nil, + 588, nil, nil, nil, nil, 20, nil, 20, nil, 1232, + 20, 1233, nil, 1234, nil, 354, nil, 20, nil, nil, + nil, nil, nil, 20, 20, nil, nil, 19, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 21, 1245, + 20, 19, 19, 21, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 347, 999, nil, nil, + nil, nil, nil, nil, nil, 999, 598, 347, nil, 999, + nil, nil, 243, nil, 21, 349, 349, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 616, 616, nil, 18, 616, nil, nil, nil, 18, + 243, 999, 21, nil, nil, nil, nil, 743, 18, 743, + nil, nil, 397, 406, 406, nil, nil, nil, nil, nil, + nil, 20, nil, nil, nil, 20, nil, 443, nil, 355, + 20, nil, nil, nil, nil, nil, nil, nil, nil, 706, + nil, nil, 243, nil, nil, nil, 18, nil, 355, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 20, 21, nil, nil, nil, nil, nil, nil, nil, 683, + 21, nil, 21, nil, 20, 20, nil, nil, 733, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 610, nil, + nil, 18, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 243, nil, nil, nil, nil, nil, 18, nil, + nil, nil, nil, nil, 18, nil, nil, 747, nil, nil, + nil, nil, nil, nil, nil, 753, nil, 755, nil, nil, + nil, 759, nil, nil, 18, nil, nil, 19, 1053, nil, + nil, nil, nil, nil, nil, 354, nil, 768, nil, nil, + nil, nil, nil, 771, 354, 21, nil, 444, nil, nil, + 444, nil, nil, nil, nil, nil, nil, 21, 745, nil, + nil, nil, nil, 21, 444, 19, nil, nil, 19, 863, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 21, nil, nil, nil, nil, nil, nil, nil, nil, 19, + nil, nil, 18, 382, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 1111, nil, nil, nil, 891, + nil, 891, nil, nil, nil, nil, 19, nil, nil, 19, + 18, 18, nil, 19, nil, nil, nil, 18, nil, 19, + 19, nil, nil, nil, 19, nil, 19, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 20, 21, nil, nil, nil, 21, 531, nil, 355, 349, + 21, 243, nil, nil, nil, 883, nil, 355, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 1177, 349, nil, + 18, nil, nil, nil, nil, nil, nil, nil, 20, nil, + 21, 20, 855, 243, nil, nil, nil, nil, nil, nil, + nil, nil, 354, nil, 21, 21, nil, nil, nil, nil, + nil, nil, 20, 354, 948, nil, nil, nil, 952, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 683, nil, 436, 449, nil, nil, 20, + 19, nil, 20, nil, nil, 19, 20, nil, nil, nil, + nil, nil, 20, 20, 19, nil, nil, 20, nil, 20, + nil, nil, nil, nil, nil, nil, 683, nil, nil, nil, + nil, nil, nil, 19, nil, nil, 743, nil, nil, nil, + nil, nil, 616, nil, nil, nil, nil, nil, nil, 243, + 243, nil, 19, nil, nil, nil, 683, nil, nil, nil, + nil, nil, 18, nil, nil, 683, nil, nil, nil, nil, + nil, 932, nil, nil, nil, nil, nil, nil, nil, 963, + nil, nil, nil, nil, nil, nil, nil, 683, nil, nil, + nil, nil, nil, nil, nil, 355, nil, 19, 577, nil, + 1017, 579, nil, nil, 581, 582, 355, nil, nil, nil, + nil, 1032, nil, nil, 19, nil, nil, nil, nil, nil, + 19, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 20, nil, nil, nil, nil, 20, nil, + 19, nil, nil, 968, 354, nil, nil, 20, nil, nil, + nil, nil, nil, 891, nil, nil, nil, 932, nil, nil, + 21, nil, nil, nil, nil, nil, 20, nil, 349, nil, + nil, nil, nil, nil, nil, nil, nil, 349, nil, nil, + nil, nil, nil, nil, nil, 20, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 21, nil, + nil, 21, nil, nil, nil, nil, nil, nil, 19, nil, + nil, nil, nil, 675, nil, nil, nil, nil, nil, nil, + nil, 354, 21, nil, nil, nil, nil, nil, nil, 820, + 20, nil, nil, nil, 683, 1080, 19, 19, nil, nil, + nil, nil, nil, 19, nil, nil, nil, 20, nil, 21, + 31, nil, 444, 20, nil, 31, 21, nil, nil, nil, + nil, nil, 444, 444, nil, nil, 1140, 444, nil, 444, + nil, nil, 31, 20, nil, 726, nil, 355, nil, nil, + 932, nil, 31, 31, 31, nil, 31, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 354, nil, nil, 19, nil, nil, nil, + nil, nil, nil, nil, 31, nil, nil, nil, nil, 31, + 31, 683, nil, 31, nil, nil, 683, 683, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 20, 1195, 1196, 1197, 349, nil, nil, nil, 762, + nil, 382, nil, 765, 355, 1000, 349, 1000, 1205, nil, + nil, nil, nil, nil, nil, nil, 1207, nil, nil, 20, + 20, nil, nil, 31, nil, 1185, 20, nil, 31, 31, + 31, 31, 31, 21, 31, nil, nil, nil, 21, nil, + 762, nil, nil, 382, nil, nil, nil, 21, nil, 683, + 683, 683, nil, nil, nil, nil, 449, nil, nil, 1080, + nil, nil, nil, nil, nil, nil, 444, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 19, nil, + nil, nil, nil, nil, nil, 21, 355, nil, nil, 20, + nil, nil, 683, nil, nil, 1000, nil, nil, nil, 831, + nil, nil, nil, 1000, nil, nil, nil, nil, nil, 762, + 382, nil, 1000, 1000, nil, nil, nil, 31, 31, 31, + 31, 31, 31, 31, nil, nil, nil, 860, nil, 31, + 21, nil, nil, nil, nil, 31, 31, 31, 31, nil, + nil, nil, nil, 878, nil, nil, nil, 21, nil, nil, + nil, nil, 31, 21, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 21, nil, nil, nil, 1055, 1000, 762, + 1000, nil, nil, 1000, 1000, nil, nil, nil, nil, nil, + 1000, 907, nil, nil, nil, nil, 1000, 1000, 31, nil, + nil, nil, nil, 1000, 1000, 31, 31, nil, nil, nil, + nil, 20, nil, nil, 31, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 1000, + nil, nil, nil, 31, nil, nil, nil, 31, nil, nil, + nil, 21, 31, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 406, nil, 1001, 936, 1001, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 21, + 21, nil, 31, nil, nil, nil, 21, nil, nil, nil, + nil, nil, nil, nil, nil, 31, 31, 31, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 31, nil, nil, 1000, + nil, nil, nil, nil, nil, nil, nil, 1000, nil, nil, + nil, 1000, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 406, nil, nil, 21, + nil, nil, nil, nil, 34, 1037, 1001, nil, nil, 34, + nil, nil, nil, 1000, 1001, nil, nil, nil, nil, nil, + nil, nil, nil, 1001, 1001, 382, 34, nil, nil, nil, + nil, 31, nil, nil, nil, nil, 34, 34, 34, nil, + 34, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 34, nil, + nil, 31, nil, 34, 34, nil, nil, 34, nil, nil, + nil, 31, 43, nil, 1002, nil, 1002, 43, nil, 1001, + nil, 1001, nil, nil, 1001, 1001, nil, nil, nil, nil, + nil, 1001, nil, nil, nil, nil, 297, 1001, 1001, nil, + nil, nil, nil, nil, 1001, 1001, nil, nil, 43, 345, + 345, 21, nil, nil, nil, nil, nil, 34, nil, nil, + nil, nil, 34, 34, 34, 34, 34, nil, 34, nil, + 1001, nil, 31, nil, nil, nil, 43, nil, nil, nil, + nil, nil, 31, nil, nil, nil, 393, 297, 297, nil, + 1003, nil, 1003, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 1002, nil, nil, nil, nil, nil, + 31, nil, 1002, 31, nil, nil, nil, nil, nil, nil, + 31, 1002, 1002, nil, nil, nil, nil, nil, nil, nil, + 31, nil, nil, nil, 31, 43, nil, nil, nil, nil, + nil, nil, nil, nil, 43, nil, 43, nil, nil, nil, + 1001, 34, 34, 34, 34, 34, 34, 34, 1001, nil, + nil, 31, 1001, 34, 31, 31, nil, nil, 31, 34, + 34, 34, 34, nil, 31, 31, nil, nil, nil, 31, + 1003, 31, nil, nil, nil, nil, 34, 1002, 1003, 1002, + nil, nil, 1002, 1002, 1001, nil, nil, 1003, 1003, 1002, + nil, nil, nil, nil, nil, 1002, 1002, nil, nil, nil, + nil, nil, 1002, 1002, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 43, + nil, nil, 34, nil, nil, nil, nil, nil, 1002, 34, + 34, 43, nil, nil, nil, nil, nil, 43, 34, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 1003, 43, 1003, nil, 34, 1003, 1003, + nil, 34, nil, 31, nil, 1003, 34, nil, nil, nil, + nil, 1003, 1003, 1004, nil, 1004, nil, nil, 1003, 1003, + nil, nil, nil, nil, nil, 31, nil, nil, nil, nil, + 31, 31, nil, nil, nil, nil, 34, nil, nil, 31, + nil, nil, nil, nil, 1003, nil, nil, nil, 1002, 34, + 34, 34, nil, nil, nil, nil, 1002, nil, 31, nil, + 1002, nil, nil, nil, nil, nil, 1005, nil, 1005, nil, + 34, nil, nil, 31, nil, 43, nil, 31, nil, 43, + nil, nil, nil, 345, 43, nil, nil, nil, nil, nil, + nil, nil, 1002, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 345, 1004, nil, nil, nil, nil, nil, nil, + nil, 1004, nil, nil, 43, nil, nil, nil, nil, nil, + 1004, 1004, 31, nil, 1003, nil, nil, nil, 43, 43, + nil, nil, 1003, 31, nil, 34, 1003, nil, nil, 31, + nil, nil, nil, nil, nil, 31, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 1005, nil, nil, nil, + nil, nil, nil, nil, 1005, 31, nil, nil, 1003, nil, + nil, nil, nil, 1005, 1005, 34, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 34, 1004, nil, 1004, nil, + nil, 1004, 1004, nil, nil, nil, nil, nil, 1004, nil, + nil, nil, nil, nil, 1004, 1004, nil, nil, nil, nil, + nil, 1004, 1004, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 31, nil, nil, nil, 1004, nil, 1005, + nil, 1005, nil, nil, 1005, 1005, 34, nil, nil, nil, + nil, 1005, nil, nil, nil, nil, 34, 1005, 1005, nil, + nil, 31, 31, nil, 1005, 1005, nil, nil, 31, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 34, nil, nil, 34, nil, nil, + 1005, nil, nil, nil, 34, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 34, nil, nil, nil, 34, nil, + nil, nil, 31, nil, nil, nil, nil, 1004, nil, nil, + nil, nil, nil, nil, 43, 1004, nil, nil, nil, 1004, + nil, 31, 345, nil, nil, 34, nil, nil, 34, 34, + nil, 345, 34, nil, 31, nil, nil, nil, 34, 34, + nil, nil, nil, 34, nil, 34, nil, nil, nil, nil, + nil, 1004, 43, nil, nil, 43, nil, nil, nil, nil, + 1005, nil, nil, nil, nil, nil, nil, nil, 1005, 250, + nil, nil, 1005, nil, nil, nil, 43, nil, nil, 318, + 318, 318, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 366, 367, nil, 369, 370, nil, 372, nil, nil, + nil, nil, nil, 43, 1005, nil, nil, nil, nil, nil, + 43, nil, 318, 318, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 31, 31, nil, nil, nil, nil, nil, 34, nil, nil, + nil, nil, nil, 31, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 34, + nil, nil, nil, nil, 34, 34, nil, nil, nil, nil, + nil, nil, nil, 34, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 1006, nil, 1006, + nil, nil, 34, nil, nil, nil, nil, nil, nil, 345, + nil, nil, nil, nil, nil, nil, nil, 34, nil, nil, + 345, 34, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 43, nil, nil, + nil, nil, 43, nil, nil, nil, nil, nil, nil, nil, + nil, 43, nil, nil, nil, nil, 34, nil, nil, nil, + nil, nil, nil, nil, nil, 318, 448, 34, nil, 454, + 318, nil, nil, 34, nil, nil, nil, 1006, nil, 34, + nil, nil, nil, 454, nil, 1006, nil, nil, nil, 43, + nil, nil, nil, nil, 1006, 1006, 250, nil, nil, 34, + nil, nil, nil, 533, 534, 535, 536, 537, 538, 539, + 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, + 550, 551, 552, 553, 554, nil, nil, nil, nil, 555, + nil, 1008, nil, 1008, 43, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 43, 318, 318, nil, nil, nil, 43, nil, nil, + 1006, 318, 1006, nil, nil, 1006, 1006, 34, 318, nil, + nil, 318, 1006, nil, 318, 318, nil, 43, 1006, 1006, + nil, 1051, nil, nil, nil, 1006, 1006, nil, nil, nil, + nil, nil, nil, nil, nil, 34, 34, nil, nil, nil, + nil, nil, 34, nil, nil, nil, nil, nil, nil, nil, + nil, 1006, nil, nil, nil, nil, 608, nil, nil, nil, + nil, 1008, nil, nil, nil, nil, nil, nil, nil, 1008, + nil, nil, nil, nil, nil, nil, nil, nil, 1008, 1008, + nil, nil, nil, nil, nil, 43, 34, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 297, nil, + nil, nil, nil, nil, nil, 34, nil, nil, nil, nil, + nil, nil, nil, 43, 43, nil, nil, nil, 34, nil, + 43, nil, nil, 318, nil, nil, nil, nil, nil, nil, + nil, 1006, nil, nil, nil, nil, nil, nil, nil, 1006, + nil, nil, nil, 1006, 1008, nil, 1008, nil, nil, 1008, + 1008, nil, nil, nil, nil, nil, 1008, nil, 699, nil, + nil, nil, 1008, 1008, nil, nil, nil, nil, nil, 1008, + 1008, nil, nil, nil, nil, 1006, nil, nil, nil, nil, + 297, nil, nil, 43, nil, 318, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 1008, nil, nil, 699, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 318, nil, + 454, 454, 454, nil, 34, 34, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 34, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 367, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 318, + nil, 318, nil, 318, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 1008, nil, nil, nil, 318, + nil, nil, nil, 1008, nil, nil, nil, 1008, nil, 454, + nil, nil, 783, nil, 784, nil, nil, nil, nil, nil, + 318, nil, nil, 318, nil, 43, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 318, 318, nil, 1008, + nil, nil, nil, nil, nil, nil, nil, 318, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 318, + nil, 454, 318, nil, nil, nil, 839, nil, nil, 318, + 318, 454, 454, nil, nil, nil, 454, nil, 454, nil, + nil, nil, nil, nil, nil, nil, nil, 318, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 318, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 699, 699, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 318, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 318, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 318, nil, nil, + nil, nil, nil, nil, nil, 454, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 942, + 699, 945, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 454, + 454, 454, 454, nil, nil, nil, nil, nil, 1014, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 318, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 318, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 454, 699, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 318 ] + +racc_goto_check = [ + 74, 160, 94, 94, 199, 74, 77, 77, 31, 19, + 19, 117, 48, 19, 111, 95, 199, 39, 39, 39, + 114, 114, 77, 33, 74, 22, 121, 26, 26, 10, + 12, 26, 50, 75, 33, 10, 74, 74, 74, 137, + 233, 233, 23, 70, 86, 86, 13, 23, 116, 141, + 141, 46, 46, 17, 17, 234, 79, 79, 42, 42, + 24, 24, 97, 43, 74, 43, 206, 85, 19, 19, + 19, 19, 115, 59, 74, 74, 74, 81, 23, 29, + 7, 86, 86, 86, 29, 135, 26, 26, 26, 26, + 31, 81, 9, 148, 82, 148, 121, 53, 57, 57, + 63, 63, 20, 5, 66, 20, 23, 123, 93, 93, + 93, 58, 58, 58, 72, 29, 23, 32, 238, 20, + 36, 159, 159, 74, 71, 91, 91, 91, 131, 228, + 228, 28, 74, 98, 74, 98, 13, 67, 84, 2, + 151, 93, 93, 29, 60, 28, 242, 92, 92, 147, + 129, 92, 44, 239, 44, 35, 35, 45, 91, 45, + 36, 178, 153, 178, 188, 23, 154, 65, 65, 65, + 132, 6, 10, 5, 23, 57, 23, 63, 26, 26, + 176, 149, 163, 100, 203, 203, 193, 8, 242, 1, + 179, 179, 8, 3, 163, 26, 26, 94, 193, 97, + 179, 14, 29, 76, 76, 16, 194, 214, 39, 214, + 11, 29, 214, 29, 214, 18, 233, 74, 216, 216, + 21, 22, 22, 77, 100, 22, 151, 25, 177, 74, + 227, 227, 27, 47, 52, 74, 54, 62, 11, 22, + 80, 199, 87, 98, 98, 90, 96, 109, 33, 231, + 231, 231, 74, 110, 118, 242, 26, 120, 239, 23, + 124, 23, 130, 176, 23, 125, 126, 60, 176, 176, + 75, 23, 127, 2, 128, 203, 203, 23, 23, 217, + 217, 217, 217, 100, 133, 148, 116, 138, 144, 6, + 39, 39, 33, 100, 23, 85, 29, 159, 29, 39, + 145, 29, 152, 153, 234, 228, 31, 154, 29, 155, + 8, 91, 91, 98, 29, 29, 177, 177, 194, 8, + 149, 8, 156, 157, 94, 19, 194, 60, 158, 193, + 94, 29, 129, 74, 161, 162, 148, 74, 188, 164, + 123, 74, 74, 26, 72, 166, 19, 147, 86, 151, + 132, 131, 33, 72, 121, 53, 167, 170, 171, 238, + 74, 172, 173, 100, 26, 174, 70, 86, 181, 183, + 33, 184, 74, 185, 189, 23, 84, 31, 81, 23, + 81, 45, 93, 13, 23, 178, 74, 74, 35, 35, + 93, 11, 190, 57, 57, 63, 63, 196, 91, 91, + 33, 32, 197, 207, 208, 66, 82, 91, 7, 85, + 66, 121, 29, 211, 23, 31, 29, 212, 213, 215, + 9, 29, 218, 206, 77, 31, 11, 71, 23, 23, + 219, 5, 94, 141, 32, 220, 114, 221, 67, 94, + 222, 65, 123, 67, 10, 234, 44, 223, 33, 65, + 226, 29, 43, 232, 233, 59, 39, 81, 236, 237, + 31, 59, 95, 115, 32, 29, 29, 57, nil, 63, + 63, 17, nil, 32, 79, nil, 135, 57, nil, 63, + 63, nil, nil, 148, nil, 130, 148, nil, 5, 130, + 192, nil, 94, nil, nil, 32, 39, 192, nil, 98, + nil, 97, 36, nil, nil, 57, 39, 63, 63, nil, + 242, 11, nil, 57, 63, 63, 11, 233, 77, 233, + 8, 72, 85, nil, nil, nil, 217, nil, 217, 100, + 94, nil, nil, 121, nil, 159, nil, nil, nil, 81, + 81, 58, 24, 228, 81, nil, 81, nil, 58, nil, + 57, 57, 63, 63, nil, nil, nil, 20, 92, 234, + 11, 11, nil, nil, nil, nil, 94, 20, 20, nil, + 137, nil, 20, nil, 20, nil, 94, 39, nil, nil, + nil, nil, 74, 97, nil, 114, nil, 141, 141, 13, + 74, 148, 77, 28, 28, nil, 70, 86, 28, 74, + 28, 42, 77, 201, 94, 70, 86, nil, nil, 192, + 10, nil, 94, nil, 46, 39, nil, 192, nil, nil, + 74, 192, nil, 74, 23, 39, 117, nil, nil, nil, + 77, nil, nil, nil, 231, 231, 77, 231, 231, 58, + 231, 75, 32, nil, 74, 130, 130, 121, 93, 94, + nil, nil, nil, 192, nil, nil, nil, nil, nil, nil, + 39, 29, 23, nil, nil, 23, 121, 77, nil, 114, + nil, 74, nil, nil, nil, 77, nil, 22, 74, nil, + nil, 12, nil, nil, nil, nil, 23, 22, 22, 93, + nil, nil, 22, 81, 22, 116, 111, nil, nil, 29, + 75, nil, 29, nil, nil, nil, nil, nil, nil, 233, + nil, nil, nil, 23, 17, nil, 23, 79, nil, nil, + 23, 20, 91, 29, 160, 10, 23, 23, nil, 32, + nil, 23, 48, 23, 32, 32, 141, 81, 81, 81, + 81, 26, 77, nil, nil, nil, 94, 28, nil, 94, + 29, 19, 50, 29, nil, nil, nil, 29, 93, nil, + 233, nil, nil, 29, 29, nil, nil, 74, 29, 26, + 29, nil, nil, 70, 86, nil, nil, nil, 74, nil, + nil, 202, nil, 202, 70, 86, 201, nil, 201, nil, + nil, nil, nil, 91, 11, nil, nil, 11, nil, 30, + nil, nil, nil, nil, 30, 74, nil, 32, 32, 32, + 74, nil, nil, 10, nil, 142, 114, nil, 142, 74, + 81, 30, 231, 231, 231, 231, 130, 130, 93, nil, + nil, 30, 30, 30, nil, 30, 30, 30, 39, nil, + nil, 22, 10, nil, nil, nil, nil, 23, nil, nil, + 32, nil, 23, 19, nil, nil, nil, 74, 8, nil, + nil, 23, nil, 30, nil, 8, nil, nil, 30, 30, + nil, 26, 30, 30, 30, 30, nil, nil, nil, nil, + 23, nil, nil, nil, 29, nil, nil, nil, 74, 29, + 74, nil, nil, nil, nil, nil, nil, nil, 29, 23, + nil, nil, 74, nil, 199, nil, nil, 233, nil, 31, + 233, nil, nil, nil, nil, nil, nil, 29, nil, 74, + nil, nil, 30, nil, nil, 74, nil, 30, 30, 30, + 30, 30, nil, 30, nil, nil, 29, nil, nil, nil, + nil, nil, nil, nil, 23, 74, 134, 121, nil, 74, + nil, nil, nil, nil, nil, nil, 86, nil, 231, 202, + 202, 23, nil, nil, 201, 201, nil, 23, nil, 202, + nil, nil, nil, nil, 201, 202, nil, nil, 74, 11, + 201, 29, nil, nil, nil, nil, 74, 23, nil, nil, + nil, 23, nil, 11, 201, 74, 74, nil, 29, 57, + nil, 63, 63, nil, 29, 202, nil, nil, nil, nil, + 201, 142, nil, 74, nil, 233, 30, 30, 30, 30, + 30, 30, 30, 146, 29, 146, 74, nil, 30, nil, + nil, 11, 19, 86, 30, 30, 30, 30, nil, nil, + nil, 74, 74, nil, nil, nil, nil, 175, 74, 175, + 26, 30, 63, nil, nil, 23, nil, nil, 33, nil, + nil, 74, nil, 74, nil, nil, 74, 74, nil, nil, + 199, nil, nil, 74, nil, nil, 11, nil, nil, 74, + 74, nil, nil, 23, 23, nil, 74, 74, nil, nil, + 23, nil, 29, 11, 143, 143, 143, 30, 94, nil, + nil, nil, nil, nil, 30, 30, 88, 88, 74, 39, + nil, 74, 74, 30, nil, 86, nil, nil, nil, 11, + 29, 29, nil, nil, 77, nil, nil, 29, nil, nil, + nil, nil, 30, nil, nil, nil, 30, 175, nil, nil, + 30, 30, nil, nil, 134, 175, nil, 134, nil, 134, + nil, nil, nil, 23, 88, nil, nil, 235, nil, 30, + 19, 19, nil, nil, nil, 34, nil, nil, nil, nil, + 34, 30, nil, nil, 77, nil, nil, nil, 26, 26, + nil, nil, nil, nil, 30, 30, 30, nil, nil, nil, + 29, nil, 74, nil, nil, nil, nil, nil, nil, nil, + 74, 34, 34, 34, 74, 30, 142, nil, nil, 142, + nil, nil, 142, 146, 142, 11, nil, nil, nil, nil, + 175, nil, 11, nil, nil, 175, 175, nil, nil, 34, + nil, nil, nil, 74, nil, nil, 74, nil, 175, 34, + 34, 34, nil, 143, 143, 143, 143, 41, 143, nil, + nil, nil, 134, nil, 134, nil, 134, nil, 134, nil, + nil, nil, nil, 101, 146, 101, 146, nil, 146, nil, + 30, 175, nil, nil, nil, 23, nil, 41, nil, nil, + nil, nil, 134, nil, nil, 11, nil, nil, 34, nil, + nil, nil, nil, nil, nil, nil, nil, 34, 37, 34, + nil, nil, nil, 37, 143, 143, 143, 143, nil, nil, + 30, nil, 29, nil, nil, nil, nil, 142, 143, 142, + 30, 142, nil, 142, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 37, 37, 37, nil, nil, 88, + 88, nil, nil, 88, 88, nil, nil, 142, nil, nil, + nil, nil, 235, 101, nil, 235, nil, nil, 235, nil, + 235, 101, 37, nil, nil, nil, nil, nil, nil, nil, + 101, 101, 37, 37, 37, nil, nil, nil, nil, nil, + nil, 30, 34, nil, 34, nil, nil, 34, nil, 30, + nil, 30, nil, nil, 34, nil, nil, nil, 30, nil, + 34, 34, nil, nil, nil, nil, nil, 11, nil, nil, + 68, nil, nil, nil, 146, nil, 146, 34, nil, 30, + nil, 37, 30, nil, nil, nil, nil, nil, nil, 30, + 37, nil, 37, nil, nil, nil, 101, nil, 101, 30, + 146, 101, 101, 30, nil, nil, nil, nil, 101, nil, + nil, nil, nil, nil, 101, 101, nil, nil, nil, nil, + 88, 101, 101, 235, nil, 235, nil, 235, nil, 235, + 30, nil, nil, 30, 30, nil, nil, 30, nil, nil, + nil, nil, nil, 30, 30, nil, 68, 101, 30, nil, + 30, nil, nil, 235, nil, nil, nil, nil, 34, nil, + nil, nil, 34, nil, nil, nil, 34, 34, nil, nil, + 68, nil, nil, nil, nil, 37, nil, 37, nil, 146, + 37, 146, nil, 146, nil, 34, nil, 37, nil, nil, + nil, nil, nil, 37, 37, nil, nil, 34, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 38, 146, + 37, 34, 34, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 30, 101, nil, nil, + nil, nil, nil, nil, nil, 101, 41, 30, nil, 101, + nil, nil, 30, nil, 38, 38, 38, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 41, 41, nil, 30, 41, nil, nil, nil, 30, + 30, 101, 38, nil, nil, nil, nil, 88, 30, 88, + nil, nil, 38, 38, 38, nil, nil, nil, nil, nil, + nil, 37, nil, nil, nil, 37, nil, 30, nil, 37, + 37, nil, nil, nil, nil, nil, nil, nil, nil, 68, + nil, nil, 30, nil, nil, nil, 30, nil, 37, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 37, 38, nil, nil, nil, nil, nil, nil, nil, 41, + 38, nil, 38, nil, 37, 37, nil, nil, 68, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 88, nil, + nil, 30, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 30, nil, nil, nil, nil, nil, 30, nil, + nil, nil, nil, nil, 30, nil, nil, 68, nil, nil, + nil, nil, nil, nil, nil, 68, nil, 68, nil, nil, + nil, 68, nil, nil, 30, nil, nil, 34, 30, nil, + nil, nil, nil, nil, nil, 34, nil, 68, nil, nil, + nil, nil, nil, 68, 34, 38, nil, 38, nil, nil, + 38, nil, nil, nil, nil, nil, nil, 38, 41, nil, + nil, nil, nil, 38, 38, 34, nil, nil, 34, 88, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 38, nil, nil, nil, nil, nil, nil, nil, nil, 34, + nil, nil, 30, 89, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 30, nil, nil, nil, 88, + nil, 88, nil, nil, nil, nil, 34, nil, nil, 34, + 30, 30, nil, 34, nil, nil, nil, 30, nil, 34, + 34, nil, nil, nil, 34, nil, 34, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 37, 38, nil, nil, nil, 38, 88, nil, 37, 38, + 38, 30, nil, nil, nil, 68, nil, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 30, 38, nil, + 30, nil, nil, nil, nil, nil, nil, nil, 37, nil, + 38, 37, 41, 30, nil, nil, nil, nil, nil, nil, + nil, nil, 34, nil, 38, 38, nil, nil, nil, nil, + nil, nil, 37, 34, 88, nil, nil, nil, 88, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 41, nil, 89, 89, nil, nil, 37, + 34, nil, 37, nil, nil, 34, 37, nil, nil, nil, + nil, nil, 37, 37, 34, nil, nil, 37, nil, 37, + nil, nil, nil, nil, nil, nil, 41, nil, nil, nil, + nil, nil, nil, 34, nil, nil, 88, nil, nil, nil, + nil, nil, 41, nil, nil, nil, nil, nil, nil, 30, + 30, nil, 34, nil, nil, nil, 41, nil, nil, nil, + nil, nil, 30, nil, nil, 41, nil, nil, nil, nil, + nil, 41, nil, nil, nil, nil, nil, nil, nil, 68, + nil, nil, nil, nil, nil, nil, nil, 41, nil, nil, + nil, nil, nil, nil, nil, 37, nil, 34, 89, nil, + 68, 89, nil, nil, 89, 89, 37, nil, nil, nil, + nil, 68, nil, nil, 34, nil, nil, nil, nil, nil, + 34, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 37, nil, nil, nil, nil, 37, nil, + 34, nil, nil, 41, 34, nil, nil, 37, nil, nil, + nil, nil, nil, 88, nil, nil, nil, 41, nil, nil, + 38, nil, nil, nil, nil, nil, 37, nil, 38, nil, + nil, nil, nil, nil, nil, nil, nil, 38, nil, nil, + nil, nil, nil, nil, nil, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 38, nil, + nil, 38, nil, nil, nil, nil, nil, nil, 34, nil, + nil, nil, nil, 89, nil, nil, nil, nil, nil, nil, + nil, 34, 38, nil, nil, nil, nil, nil, nil, 38, + 37, nil, nil, nil, 41, 41, 34, 34, nil, nil, + nil, nil, nil, 34, nil, nil, nil, 37, nil, 38, + 61, nil, 38, 37, nil, 61, 38, nil, nil, nil, + nil, nil, 38, 38, nil, nil, 68, 38, nil, 38, + nil, nil, 61, 37, nil, 89, nil, 37, nil, nil, + 41, nil, 61, 61, 61, nil, 61, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 34, nil, nil, 34, nil, nil, nil, + nil, nil, nil, nil, 61, nil, nil, nil, nil, 61, + 61, 41, nil, 61, nil, nil, 41, 41, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 37, 68, 68, 68, 38, nil, nil, nil, 89, + nil, 89, nil, 89, 37, 102, 38, 102, 68, nil, + nil, nil, nil, nil, nil, nil, 68, nil, nil, 37, + 37, nil, nil, 61, nil, 41, 37, nil, 61, 61, + 61, 61, 61, 38, 61, nil, nil, nil, 38, nil, + 89, nil, nil, 89, nil, nil, nil, 38, nil, 41, + 41, 41, nil, nil, nil, nil, 89, nil, nil, 41, + nil, nil, nil, nil, nil, nil, 38, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 34, nil, + nil, nil, nil, nil, nil, 38, 37, nil, nil, 37, + nil, nil, 41, nil, nil, 102, nil, nil, nil, 89, + nil, nil, nil, 102, nil, nil, nil, nil, nil, 89, + 89, nil, 102, 102, nil, nil, nil, 61, 61, 61, + 61, 61, 61, 61, nil, nil, nil, 89, nil, 61, + 38, nil, nil, nil, nil, 61, 61, 61, 61, nil, + nil, nil, nil, 89, nil, nil, nil, 38, nil, nil, + nil, nil, 61, 38, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 38, nil, nil, nil, 38, 102, 89, + 102, nil, nil, 102, 102, nil, nil, nil, nil, nil, + 102, 89, nil, nil, nil, nil, 102, 102, 61, nil, + nil, nil, nil, 102, 102, 61, 61, nil, nil, nil, + nil, 37, nil, nil, 61, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 102, + nil, nil, nil, 61, nil, nil, nil, 61, nil, nil, + nil, 38, 61, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 38, nil, 103, 89, 103, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 38, + 38, nil, 61, nil, nil, nil, 38, nil, nil, nil, + nil, nil, nil, nil, nil, 61, 61, 61, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 61, nil, nil, 102, + nil, nil, nil, nil, nil, nil, nil, 102, nil, nil, + nil, 102, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 38, nil, nil, 38, + nil, nil, nil, nil, 64, 89, 103, nil, nil, 64, + nil, nil, nil, 102, 103, nil, nil, nil, nil, nil, + nil, nil, nil, 103, 103, 89, 64, nil, nil, nil, + nil, 61, nil, nil, nil, nil, 64, 64, 64, nil, + 64, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 64, nil, + nil, 61, nil, 64, 64, nil, nil, 64, nil, nil, + nil, 61, 73, nil, 104, nil, 104, 73, nil, 103, + nil, 103, nil, nil, 103, 103, nil, nil, nil, nil, + nil, 103, nil, nil, nil, nil, 73, 103, 103, nil, + nil, nil, nil, nil, 103, 103, nil, nil, 73, 73, + 73, 38, nil, nil, nil, nil, nil, 64, nil, nil, + nil, nil, 64, 64, 64, 64, 64, nil, 64, nil, + 103, nil, 61, nil, nil, nil, 73, nil, nil, nil, + nil, nil, 61, nil, nil, nil, 73, 73, 73, nil, + 105, nil, 105, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 104, nil, nil, nil, nil, nil, + 61, nil, 104, 61, nil, nil, nil, nil, nil, nil, + 61, 104, 104, nil, nil, nil, nil, nil, nil, nil, + 61, nil, nil, nil, 61, 73, nil, nil, nil, nil, + nil, nil, nil, nil, 73, nil, 73, nil, nil, nil, + 103, 64, 64, 64, 64, 64, 64, 64, 103, nil, + nil, 61, 103, 64, 61, 61, nil, nil, 61, 64, + 64, 64, 64, nil, 61, 61, nil, nil, nil, 61, + 105, 61, nil, nil, nil, nil, 64, 104, 105, 104, + nil, nil, 104, 104, 103, nil, nil, 105, 105, 104, + nil, nil, nil, nil, nil, 104, 104, nil, nil, nil, + nil, nil, 104, 104, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 73, + nil, nil, 64, nil, nil, nil, nil, nil, 104, 64, + 64, 73, nil, nil, nil, nil, nil, 73, 64, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 105, 73, 105, nil, 64, 105, 105, + nil, 64, nil, 61, nil, 105, 64, nil, nil, nil, + nil, 105, 105, 106, nil, 106, nil, nil, 105, 105, + nil, nil, nil, nil, nil, 61, nil, nil, nil, nil, + 61, 61, nil, nil, nil, nil, 64, nil, nil, 61, + nil, nil, nil, nil, 105, nil, nil, nil, 104, 64, + 64, 64, nil, nil, nil, nil, 104, nil, 61, nil, + 104, nil, nil, nil, nil, nil, 107, nil, 107, nil, + 64, nil, nil, 61, nil, 73, nil, 61, nil, 73, + nil, nil, nil, 73, 73, nil, nil, nil, nil, nil, + nil, nil, 104, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 73, 106, nil, nil, nil, nil, nil, nil, + nil, 106, nil, nil, 73, nil, nil, nil, nil, nil, + 106, 106, 61, nil, 105, nil, nil, nil, 73, 73, + nil, nil, 105, 61, nil, 64, 105, nil, nil, 61, + nil, nil, nil, nil, nil, 61, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 107, nil, nil, nil, + nil, nil, nil, nil, 107, 61, nil, nil, 105, nil, + nil, nil, nil, 107, 107, 64, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 64, 106, nil, 106, nil, + nil, 106, 106, nil, nil, nil, nil, nil, 106, nil, + nil, nil, nil, nil, 106, 106, nil, nil, nil, nil, + nil, 106, 106, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 61, nil, nil, nil, 106, nil, 107, + nil, 107, nil, nil, 107, 107, 64, nil, nil, nil, + nil, 107, nil, nil, nil, nil, 64, 107, 107, nil, + nil, 61, 61, nil, 107, 107, nil, nil, 61, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 64, nil, nil, 64, nil, nil, + 107, nil, nil, nil, 64, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 64, nil, nil, nil, 64, nil, + nil, nil, 61, nil, nil, nil, nil, 106, nil, nil, + nil, nil, nil, nil, 73, 106, nil, nil, nil, 106, + nil, 61, 73, nil, nil, 64, nil, nil, 64, 64, + nil, 73, 64, nil, 61, nil, nil, nil, 64, 64, + nil, nil, nil, 64, nil, 64, nil, nil, nil, nil, + nil, 106, 73, nil, nil, 73, nil, nil, nil, nil, + 107, nil, nil, nil, nil, nil, nil, nil, 107, 40, + nil, nil, 107, nil, nil, nil, 73, nil, nil, 40, + 40, 40, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 40, 40, nil, 40, 40, nil, 40, nil, nil, + nil, nil, nil, 73, 107, nil, nil, nil, nil, nil, + 73, nil, 40, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 61, 61, nil, nil, nil, nil, nil, 64, nil, nil, + nil, nil, nil, 61, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 64, + nil, nil, nil, nil, 64, 64, nil, nil, nil, nil, + nil, nil, nil, 64, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 108, nil, 108, + nil, nil, 64, nil, nil, nil, nil, nil, nil, 73, + nil, nil, nil, nil, nil, nil, nil, 64, nil, nil, + 73, 64, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 73, nil, nil, + nil, nil, 73, nil, nil, nil, nil, nil, nil, nil, + nil, 73, nil, nil, nil, nil, 64, nil, nil, nil, + nil, nil, nil, nil, nil, 40, 40, 64, nil, 40, + 40, nil, nil, 64, nil, nil, nil, 108, nil, 64, + nil, nil, nil, 40, nil, 108, nil, nil, nil, 73, + nil, nil, nil, nil, 108, 108, 40, nil, nil, 64, + nil, nil, nil, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, nil, nil, nil, nil, 40, + nil, 113, nil, 113, 73, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 73, 40, 40, nil, nil, nil, 73, nil, nil, + 108, 40, 108, nil, nil, 108, 108, 64, 40, nil, + nil, 40, 108, nil, 40, 40, nil, 73, 108, 108, + nil, 73, nil, nil, nil, 108, 108, nil, nil, nil, + nil, nil, nil, nil, nil, 64, 64, nil, nil, nil, + nil, nil, 64, nil, nil, nil, nil, nil, nil, nil, + nil, 108, nil, nil, nil, nil, 40, nil, nil, nil, + nil, 113, nil, nil, nil, nil, nil, nil, nil, 113, + nil, nil, nil, nil, nil, nil, nil, nil, 113, 113, + nil, nil, nil, nil, nil, 73, 64, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 73, nil, + nil, nil, nil, nil, nil, 64, nil, nil, nil, nil, + nil, nil, nil, 73, 73, nil, nil, nil, 64, nil, + 73, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 108, nil, nil, nil, nil, nil, nil, nil, 108, + nil, nil, nil, 108, 113, nil, 113, nil, nil, 113, + 113, nil, nil, nil, nil, nil, 113, nil, 40, nil, + nil, nil, 113, 113, nil, nil, nil, nil, nil, 113, + 113, nil, nil, nil, nil, 108, nil, nil, nil, nil, + 73, nil, nil, 73, nil, 40, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 113, nil, nil, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 40, nil, + 40, 40, 40, nil, 64, 64, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 64, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 40, + nil, 40, nil, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 113, nil, nil, nil, 40, + nil, nil, nil, 113, nil, nil, nil, 113, nil, 40, + nil, nil, 40, nil, 40, nil, nil, nil, nil, nil, + 40, nil, nil, 40, nil, 73, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 40, 40, nil, 113, + nil, nil, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 40, + nil, 40, 40, nil, nil, nil, 40, nil, nil, 40, + 40, 40, 40, nil, nil, nil, 40, nil, 40, nil, + nil, nil, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 40, 40, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 40, + 40, 40, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 40, + 40, 40, 40, nil, nil, nil, nil, nil, 40, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 40, 40, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 40 ] + +racc_goto_pointer = [ + nil, 189, 137, 193, nil, 98, 164, 75, 185, 83, + -202, 172, -444, -655, -656, nil, -379, 43, 204, -62, + -119, 144, 1, 40, -160, 7, -44, 95, -93, 77, + 797, -217, -338, 5, 1163, 136, -353, 1296, 1546, -17, + 3355, 1224, -198, -467, -590, -733, -22, -393, -14, nil, + 6, nil, 208, 68, -320, nil, nil, -128, 80, -233, + -425, 2218, -325, -126, 2662, 133, 66, 99, 1170, nil, + 4, 84, -248, 2740, -2, -370, 126, -4, nil, 46, + -192, -147, 46, nil, -235, -446, 5, 191, 1087, 1745, + 178, 91, -230, 74, -29, -292, -313, -259, -441, nil, + -391, 373, 1435, 1686, 1854, 1930, 2123, 2176, 2607, 221, + 185, -55, nil, 2751, -365, -717, -343, -618, 178, nil, + -150, 21, nil, 87, 195, -110, -377, -542, -135, -730, + -235, -369, -711, -596, 43, -622, nil, -457, -616, nil, + nil, -431, 108, 73, -733, -603, 310, -754, -618, -576, + nil, -677, -743, -883, -879, -101, -494, 238, -319, -113, + -26, -596, -596, -376, 38, nil, 34, 44, nil, nil, + -392, -680, -753, -882, -856, 157, -800, -752, -729, -878, + nil, -696, nil, -696, -608, -606, nil, nil, -817, -607, + -590, nil, -585, -877, -876, nil, -687, -682, nil, -86, + nil, -104, -109, -813, nil, nil, -587, -299, -457, nil, + nil, 325, 324, 324, -453, 324, -197, -134, 326, 333, + 337, -216, -494, -207, nil, nil, -194, -124, -105, nil, + nil, -235, -258, -194, -656, 254, -249, -639, -595, -951, + nil, nil, -430 ] + +racc_goto_default = [ + nil, nil, nil, nil, 5, nil, 6, 392, 336, nil, + nil, 474, nil, 914, nil, 333, 334, nil, nil, nil, + 13, 14, 22, 248, nil, nil, 16, nil, 442, 249, + 365, nil, nil, 641, 252, nil, nil, 253, 247, 27, + 25, 520, nil, nil, nil, nil, nil, nil, nil, 387, + 144, 26, nil, nil, nil, 28, 29, 778, nil, nil, + nil, 353, nil, 30, 350, 456, 37, nil, nil, 39, + 42, 41, nil, 244, 245, 404, nil, 465, 143, 87, + nil, 447, 103, 51, nil, 700, 54, 284, 858, 324, + nil, 457, nil, 458, 470, 483, 690, 573, 322, 308, + 325, 55, 56, 57, 58, 59, 60, 61, 62, 63, + nil, 309, 69, 70, nil, nil, nil, nil, nil, 77, + nil, 623, 78, 231, nil, nil, nil, nil, nil, 721, + 495, nil, 722, 723, 481, 476, 477, nil, 1169, 717, + 1018, nil, 482, nil, nil, nil, 484, nil, 486, nil, + 902, nil, nil, nil, 493, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 469, nil, nil, 757, 749, + nil, nil, nil, nil, nil, 1151, nil, 971, 1076, 973, + 974, 978, 975, 976, nil, nil, 977, 979, nil, nil, + nil, 1075, 1077, 983, nil, 985, 986, 987, 988, nil, + 992, 478, 504, 994, 995, 996, 113, nil, nil, 86, + 88, 89, nil, nil, nil, nil, nil, 651, nil, nil, + nil, nil, nil, nil, 99, 100, nil, 232, 868, 235, + 480, nil, 485, 876, 498, 500, 501, 1029, 505, 1030, + 508, 511, 328 ] + +racc_reduce_table = [ + 0, 0, :racc_error, + 0, 150, :_reduce_1, + 2, 148, :_reduce_2, + 2, 149, :_reduce_3, + 0, 151, :_reduce_4, + 1, 151, :_reduce_5, + 3, 151, :_reduce_6, + 2, 151, :_reduce_7, + 1, 153, :_reduce_none, + 2, 153, :_reduce_9, + 3, 156, :_reduce_10, + 4, 157, :_reduce_11, + 2, 158, :_reduce_12, + 0, 162, :_reduce_13, + 1, 162, :_reduce_14, + 3, 162, :_reduce_15, + 2, 162, :_reduce_16, + 1, 163, :_reduce_none, + 2, 163, :_reduce_18, + 0, 174, :_reduce_19, + 4, 155, :_reduce_20, + 3, 155, :_reduce_21, + 3, 155, :_reduce_22, + 3, 155, :_reduce_23, + 2, 155, :_reduce_24, + 3, 155, :_reduce_25, + 3, 155, :_reduce_26, + 3, 155, :_reduce_27, + 3, 155, :_reduce_28, + 3, 155, :_reduce_29, + 4, 155, :_reduce_30, + 1, 155, :_reduce_none, + 3, 155, :_reduce_32, + 3, 155, :_reduce_33, + 5, 155, :_reduce_34, + 3, 155, :_reduce_35, + 1, 155, :_reduce_none, + 3, 167, :_reduce_37, + 3, 167, :_reduce_38, + 6, 167, :_reduce_39, + 5, 167, :_reduce_40, + 5, 167, :_reduce_41, + 5, 167, :_reduce_42, + 5, 167, :_reduce_43, + 4, 167, :_reduce_44, + 4, 167, :_reduce_45, + 3, 167, :_reduce_46, + 1, 183, :_reduce_none, + 3, 183, :_reduce_48, + 3, 183, :_reduce_49, + 1, 175, :_reduce_none, + 3, 175, :_reduce_51, + 1, 175, :_reduce_none, + 1, 173, :_reduce_none, + 3, 173, :_reduce_54, + 3, 173, :_reduce_55, + 3, 173, :_reduce_56, + 2, 173, :_reduce_57, + 6, 173, :_reduce_58, + 6, 173, :_reduce_59, + 1, 173, :_reduce_none, + 1, 166, :_reduce_none, + 0, 196, :_reduce_62, + 3, 193, :_reduce_63, + 1, 195, :_reduce_64, + 2, 181, :_reduce_65, + 0, 201, :_reduce_66, + 5, 184, :_reduce_67, + 1, 169, :_reduce_none, + 1, 169, :_reduce_none, + 1, 202, :_reduce_none, + 4, 202, :_reduce_71, + 0, 209, :_reduce_72, + 4, 206, :_reduce_73, + 1, 208, :_reduce_none, + 2, 186, :_reduce_75, + 3, 186, :_reduce_76, + 4, 186, :_reduce_77, + 5, 186, :_reduce_78, + 4, 186, :_reduce_79, + 5, 186, :_reduce_80, + 6, 186, :_reduce_81, + 2, 186, :_reduce_82, + 2, 186, :_reduce_83, + 2, 186, :_reduce_84, + 2, 186, :_reduce_85, + 2, 186, :_reduce_86, + 1, 168, :_reduce_87, + 3, 168, :_reduce_88, + 1, 214, :_reduce_89, + 3, 214, :_reduce_90, + 1, 213, :_reduce_none, + 2, 213, :_reduce_92, + 3, 213, :_reduce_93, + 5, 213, :_reduce_94, + 2, 213, :_reduce_95, + 4, 213, :_reduce_96, + 2, 213, :_reduce_97, + 4, 213, :_reduce_98, + 1, 213, :_reduce_99, + 3, 213, :_reduce_100, + 1, 217, :_reduce_none, + 3, 217, :_reduce_102, + 2, 216, :_reduce_103, + 3, 216, :_reduce_104, + 1, 219, :_reduce_105, + 3, 219, :_reduce_106, + 1, 218, :_reduce_107, + 1, 218, :_reduce_108, + 4, 218, :_reduce_109, + 3, 218, :_reduce_110, + 3, 218, :_reduce_111, + 3, 218, :_reduce_112, + 3, 218, :_reduce_113, + 2, 218, :_reduce_114, + 1, 218, :_reduce_115, + 1, 170, :_reduce_116, + 1, 170, :_reduce_117, + 4, 170, :_reduce_118, + 3, 170, :_reduce_119, + 3, 170, :_reduce_120, + 3, 170, :_reduce_121, + 3, 170, :_reduce_122, + 2, 170, :_reduce_123, + 1, 170, :_reduce_124, + 1, 222, :_reduce_125, + 1, 222, :_reduce_none, + 2, 223, :_reduce_127, + 1, 223, :_reduce_128, + 3, 223, :_reduce_129, + 1, 197, :_reduce_none, + 1, 197, :_reduce_none, + 1, 197, :_reduce_none, + 1, 197, :_reduce_none, + 1, 197, :_reduce_none, + 1, 164, :_reduce_135, + 1, 164, :_reduce_none, + 1, 165, :_reduce_137, + 0, 227, :_reduce_138, + 4, 165, :_reduce_139, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 1, 225, :_reduce_none, + 3, 187, :_reduce_211, + 3, 187, :_reduce_212, + 6, 187, :_reduce_213, + 5, 187, :_reduce_214, + 5, 187, :_reduce_215, + 5, 187, :_reduce_216, + 5, 187, :_reduce_217, + 4, 187, :_reduce_218, + 3, 187, :_reduce_219, + 3, 187, :_reduce_220, + 3, 187, :_reduce_221, + 2, 187, :_reduce_222, + 2, 187, :_reduce_223, + 2, 187, :_reduce_224, + 2, 187, :_reduce_225, + 3, 187, :_reduce_226, + 3, 187, :_reduce_227, + 3, 187, :_reduce_228, + 3, 187, :_reduce_229, + 3, 187, :_reduce_230, + 3, 187, :_reduce_231, + 4, 187, :_reduce_232, + 2, 187, :_reduce_233, + 2, 187, :_reduce_234, + 3, 187, :_reduce_235, + 3, 187, :_reduce_236, + 3, 187, :_reduce_237, + 3, 187, :_reduce_238, + 1, 187, :_reduce_none, + 3, 187, :_reduce_240, + 3, 187, :_reduce_241, + 3, 187, :_reduce_242, + 3, 187, :_reduce_243, + 3, 187, :_reduce_244, + 2, 187, :_reduce_245, + 2, 187, :_reduce_246, + 3, 187, :_reduce_247, + 3, 187, :_reduce_248, + 3, 187, :_reduce_249, + 3, 187, :_reduce_250, + 4, 187, :_reduce_251, + 6, 187, :_reduce_252, + 4, 187, :_reduce_253, + 4, 187, :_reduce_254, + 1, 187, :_reduce_none, + 1, 232, :_reduce_none, + 3, 232, :_reduce_257, + 3, 232, :_reduce_258, + 1, 234, :_reduce_none, + 1, 234, :_reduce_none, + 1, 234, :_reduce_none, + 1, 234, :_reduce_none, + 3, 230, :_reduce_263, + 3, 230, :_reduce_264, + 1, 231, :_reduce_265, + 1, 236, :_reduce_none, + 1, 237, :_reduce_none, + 2, 237, :_reduce_none, + 4, 237, :_reduce_269, + 2, 237, :_reduce_270, + 1, 228, :_reduce_none, + 3, 228, :_reduce_272, + 3, 241, :_reduce_273, + 5, 241, :_reduce_274, + 3, 241, :_reduce_275, + 0, 243, :_reduce_276, + 1, 243, :_reduce_none, + 0, 178, :_reduce_278, + 1, 178, :_reduce_none, + 2, 178, :_reduce_none, + 4, 178, :_reduce_281, + 2, 178, :_reduce_282, + 1, 212, :_reduce_283, + 2, 212, :_reduce_284, + 2, 212, :_reduce_285, + 4, 212, :_reduce_286, + 1, 212, :_reduce_287, + 0, 246, :_reduce_288, + 2, 205, :_reduce_289, + 2, 245, :_reduce_290, + 1, 245, :_reduce_291, + 2, 244, :_reduce_292, + 0, 244, :_reduce_293, + 1, 238, :_reduce_294, + 1, 238, :_reduce_none, + 3, 238, :_reduce_296, + 3, 238, :_reduce_297, + 2, 247, :_reduce_298, + 1, 247, :_reduce_299, + 1, 172, :_reduce_300, + 1, 172, :_reduce_none, + 3, 171, :_reduce_302, + 4, 171, :_reduce_303, + 2, 171, :_reduce_304, + 1, 233, :_reduce_none, + 1, 233, :_reduce_none, + 1, 233, :_reduce_none, + 1, 233, :_reduce_none, + 1, 233, :_reduce_none, + 1, 233, :_reduce_none, + 1, 233, :_reduce_none, + 1, 233, :_reduce_none, + 1, 233, :_reduce_none, + 1, 233, :_reduce_none, + 1, 233, :_reduce_315, + 0, 271, :_reduce_316, + 4, 233, :_reduce_317, + 0, 272, :_reduce_318, + 4, 233, :_reduce_319, + 3, 233, :_reduce_320, + 3, 233, :_reduce_321, + 2, 233, :_reduce_322, + 3, 233, :_reduce_323, + 3, 233, :_reduce_324, + 1, 233, :_reduce_325, + 4, 233, :_reduce_326, + 3, 233, :_reduce_327, + 1, 233, :_reduce_328, + 6, 233, :_reduce_329, + 4, 233, :_reduce_330, + 3, 233, :_reduce_331, + 2, 233, :_reduce_332, + 1, 233, :_reduce_none, + 2, 233, :_reduce_334, + 1, 233, :_reduce_none, + 6, 233, :_reduce_336, + 6, 233, :_reduce_337, + 4, 233, :_reduce_338, + 4, 233, :_reduce_339, + 5, 233, :_reduce_340, + 4, 233, :_reduce_341, + 5, 233, :_reduce_342, + 6, 233, :_reduce_343, + 0, 273, :_reduce_344, + 6, 233, :_reduce_345, + 0, 274, :_reduce_346, + 7, 233, :_reduce_347, + 0, 275, :_reduce_348, + 5, 233, :_reduce_349, + 4, 233, :_reduce_350, + 4, 233, :_reduce_351, + 1, 233, :_reduce_352, + 1, 233, :_reduce_353, + 1, 233, :_reduce_354, + 1, 233, :_reduce_355, + 1, 177, :_reduce_none, + 1, 266, :_reduce_357, + 1, 269, :_reduce_358, + 1, 198, :_reduce_359, + 1, 211, :_reduce_360, + 1, 261, :_reduce_none, + 1, 261, :_reduce_none, + 2, 261, :_reduce_363, + 1, 194, :_reduce_none, + 1, 194, :_reduce_none, + 1, 262, :_reduce_none, + 5, 262, :_reduce_367, + 1, 160, :_reduce_none, + 2, 160, :_reduce_369, + 1, 265, :_reduce_none, + 1, 265, :_reduce_none, + 1, 276, :_reduce_372, + 3, 276, :_reduce_373, + 1, 279, :_reduce_374, + 3, 279, :_reduce_375, + 1, 278, :_reduce_none, + 3, 278, :_reduce_377, + 5, 278, :_reduce_378, + 1, 278, :_reduce_379, + 3, 278, :_reduce_380, + 2, 280, :_reduce_381, + 1, 280, :_reduce_382, + 1, 281, :_reduce_none, + 1, 281, :_reduce_none, + 0, 286, :_reduce_385, + 2, 284, :_reduce_386, + 4, 285, :_reduce_387, + 2, 285, :_reduce_388, + 2, 285, :_reduce_389, + 1, 285, :_reduce_390, + 2, 290, :_reduce_391, + 0, 290, :_reduce_392, + 1, 291, :_reduce_none, + 6, 292, :_reduce_394, + 8, 292, :_reduce_395, + 4, 292, :_reduce_396, + 6, 292, :_reduce_397, + 4, 292, :_reduce_398, + 2, 292, :_reduce_none, + 6, 292, :_reduce_400, + 2, 292, :_reduce_401, + 4, 292, :_reduce_402, + 6, 292, :_reduce_403, + 2, 292, :_reduce_404, + 4, 292, :_reduce_405, + 2, 292, :_reduce_406, + 4, 292, :_reduce_407, + 1, 292, :_reduce_none, + 0, 296, :_reduce_409, + 1, 296, :_reduce_410, + 3, 297, :_reduce_411, + 4, 297, :_reduce_412, + 1, 298, :_reduce_413, + 4, 298, :_reduce_414, + 1, 299, :_reduce_415, + 3, 299, :_reduce_416, + 1, 300, :_reduce_417, + 1, 300, :_reduce_none, + 0, 304, :_reduce_419, + 0, 305, :_reduce_420, + 5, 260, :_reduce_421, + 4, 302, :_reduce_422, + 1, 302, :_reduce_423, + 0, 308, :_reduce_424, + 4, 303, :_reduce_425, + 0, 309, :_reduce_426, + 4, 303, :_reduce_427, + 0, 311, :_reduce_428, + 4, 307, :_reduce_429, + 2, 203, :_reduce_430, + 4, 203, :_reduce_431, + 5, 203, :_reduce_432, + 5, 203, :_reduce_433, + 2, 259, :_reduce_434, + 4, 259, :_reduce_435, + 4, 259, :_reduce_436, + 3, 259, :_reduce_437, + 3, 259, :_reduce_438, + 3, 259, :_reduce_439, + 2, 259, :_reduce_440, + 1, 259, :_reduce_441, + 4, 259, :_reduce_442, + 0, 313, :_reduce_443, + 4, 258, :_reduce_444, + 0, 314, :_reduce_445, + 4, 258, :_reduce_446, + 0, 315, :_reduce_447, + 3, 207, :_reduce_448, + 0, 316, :_reduce_449, + 0, 317, :_reduce_450, + 4, 310, :_reduce_451, + 5, 263, :_reduce_452, + 1, 318, :_reduce_453, + 1, 318, :_reduce_none, + 1, 190, :_reduce_455, + 1, 191, :_reduce_456, + 1, 189, :_reduce_457, + 0, 321, :_reduce_458, + 9, 264, :_reduce_459, + 1, 320, :_reduce_460, + 1, 320, :_reduce_none, + 1, 319, :_reduce_462, + 3, 319, :_reduce_463, + 3, 319, :_reduce_464, + 1, 192, :_reduce_none, + 2, 192, :_reduce_466, + 3, 192, :_reduce_467, + 1, 192, :_reduce_468, + 1, 192, :_reduce_469, + 1, 192, :_reduce_470, + 1, 322, :_reduce_none, + 3, 327, :_reduce_472, + 1, 327, :_reduce_none, + 3, 329, :_reduce_474, + 1, 329, :_reduce_none, + 1, 331, :_reduce_476, + 1, 332, :_reduce_477, + 1, 330, :_reduce_none, + 1, 330, :_reduce_none, + 4, 330, :_reduce_480, + 4, 330, :_reduce_481, + 4, 330, :_reduce_482, + 3, 330, :_reduce_483, + 4, 330, :_reduce_484, + 4, 330, :_reduce_485, + 4, 330, :_reduce_486, + 3, 330, :_reduce_487, + 3, 330, :_reduce_488, + 3, 330, :_reduce_489, + 2, 330, :_reduce_490, + 0, 336, :_reduce_491, + 4, 330, :_reduce_492, + 2, 330, :_reduce_493, + 0, 337, :_reduce_494, + 4, 330, :_reduce_495, + 1, 323, :_reduce_496, + 1, 323, :_reduce_497, + 2, 323, :_reduce_498, + 2, 323, :_reduce_499, + 4, 323, :_reduce_500, + 1, 323, :_reduce_none, + 2, 338, :_reduce_502, + 3, 338, :_reduce_503, + 1, 325, :_reduce_504, + 3, 325, :_reduce_505, + 5, 324, :_reduce_506, + 2, 340, :_reduce_507, + 1, 340, :_reduce_508, + 1, 341, :_reduce_509, + 3, 341, :_reduce_510, + 1, 339, :_reduce_none, + 3, 326, :_reduce_512, + 1, 326, :_reduce_513, + 2, 326, :_reduce_514, + 1, 326, :_reduce_515, + 1, 342, :_reduce_516, + 3, 342, :_reduce_517, + 2, 344, :_reduce_518, + 1, 344, :_reduce_519, + 1, 345, :_reduce_520, + 3, 345, :_reduce_521, + 2, 347, :_reduce_522, + 1, 347, :_reduce_523, + 2, 349, :_reduce_524, + 1, 343, :_reduce_none, + 1, 343, :_reduce_526, + 1, 333, :_reduce_none, + 3, 333, :_reduce_528, + 3, 333, :_reduce_529, + 2, 333, :_reduce_530, + 2, 333, :_reduce_531, + 1, 333, :_reduce_none, + 1, 333, :_reduce_none, + 1, 333, :_reduce_none, + 2, 333, :_reduce_535, + 2, 333, :_reduce_536, + 1, 350, :_reduce_none, + 1, 350, :_reduce_none, + 1, 350, :_reduce_none, + 1, 350, :_reduce_none, + 1, 350, :_reduce_none, + 1, 350, :_reduce_none, + 1, 350, :_reduce_none, + 1, 350, :_reduce_none, + 1, 350, :_reduce_545, + 1, 350, :_reduce_none, + 1, 328, :_reduce_547, + 2, 351, :_reduce_548, + 2, 351, :_reduce_549, + 4, 352, :_reduce_550, + 2, 334, :_reduce_551, + 3, 334, :_reduce_552, + 1, 334, :_reduce_553, + 6, 159, :_reduce_554, + 0, 159, :_reduce_555, + 1, 354, :_reduce_556, + 1, 354, :_reduce_none, + 1, 354, :_reduce_none, + 2, 355, :_reduce_559, + 1, 355, :_reduce_none, + 2, 161, :_reduce_561, + 1, 161, :_reduce_none, + 1, 248, :_reduce_none, + 1, 248, :_reduce_none, + 1, 249, :_reduce_565, + 1, 357, :_reduce_566, + 2, 357, :_reduce_567, + 3, 358, :_reduce_568, + 1, 358, :_reduce_569, + 1, 358, :_reduce_570, + 3, 250, :_reduce_571, + 4, 251, :_reduce_572, + 1, 361, :_reduce_none, + 2, 361, :_reduce_none, + 3, 252, :_reduce_575, + 0, 362, :_reduce_576, + 3, 362, :_reduce_577, + 1, 363, :_reduce_578, + 2, 363, :_reduce_579, + 3, 254, :_reduce_580, + 0, 365, :_reduce_581, + 3, 365, :_reduce_582, + 3, 253, :_reduce_583, + 3, 255, :_reduce_584, + 0, 366, :_reduce_585, + 3, 366, :_reduce_586, + 0, 367, :_reduce_587, + 3, 367, :_reduce_588, + 0, 346, :_reduce_589, + 2, 346, :_reduce_590, + 0, 359, :_reduce_591, + 2, 359, :_reduce_592, + 0, 360, :_reduce_593, + 2, 360, :_reduce_594, + 1, 364, :_reduce_595, + 2, 364, :_reduce_596, + 0, 370, :_reduce_597, + 4, 364, :_reduce_598, + 1, 369, :_reduce_none, + 1, 368, :_reduce_600, + 1, 368, :_reduce_none, + 1, 226, :_reduce_none, + 1, 226, :_reduce_none, + 1, 371, :_reduce_604, + 3, 372, :_reduce_605, + 1, 356, :_reduce_606, + 2, 356, :_reduce_607, + 1, 229, :_reduce_608, + 1, 229, :_reduce_609, + 1, 229, :_reduce_610, + 1, 229, :_reduce_611, + 1, 353, :_reduce_612, + 1, 353, :_reduce_613, + 1, 353, :_reduce_614, + 1, 220, :_reduce_615, + 1, 220, :_reduce_616, + 1, 220, :_reduce_none, + 1, 221, :_reduce_618, + 1, 221, :_reduce_619, + 1, 221, :_reduce_620, + 1, 221, :_reduce_621, + 1, 221, :_reduce_622, + 1, 221, :_reduce_623, + 1, 221, :_reduce_624, + 1, 256, :_reduce_625, + 1, 256, :_reduce_626, + 1, 176, :_reduce_627, + 1, 176, :_reduce_628, + 1, 185, :_reduce_629, + 1, 185, :_reduce_630, + 0, 373, :_reduce_631, + 4, 267, :_reduce_632, + 0, 267, :_reduce_633, + 1, 182, :_reduce_none, + 1, 182, :_reduce_635, + 3, 374, :_reduce_636, + 1, 270, :_reduce_none, + 0, 376, :_reduce_638, + 3, 270, :_reduce_639, + 4, 375, :_reduce_640, + 2, 375, :_reduce_641, + 2, 375, :_reduce_642, + 1, 375, :_reduce_643, + 1, 375, :_reduce_644, + 2, 378, :_reduce_645, + 0, 378, :_reduce_646, + 6, 306, :_reduce_647, + 8, 306, :_reduce_648, + 4, 306, :_reduce_649, + 6, 306, :_reduce_650, + 4, 306, :_reduce_651, + 6, 306, :_reduce_652, + 2, 306, :_reduce_653, + 4, 306, :_reduce_654, + 6, 306, :_reduce_655, + 2, 306, :_reduce_656, + 4, 306, :_reduce_657, + 2, 306, :_reduce_658, + 4, 306, :_reduce_659, + 1, 306, :_reduce_660, + 0, 306, :_reduce_661, + 1, 242, :_reduce_662, + 1, 301, :_reduce_663, + 1, 301, :_reduce_664, + 1, 301, :_reduce_665, + 1, 301, :_reduce_666, + 1, 277, :_reduce_none, + 1, 277, :_reduce_668, + 1, 380, :_reduce_669, + 1, 381, :_reduce_670, + 3, 381, :_reduce_671, + 1, 293, :_reduce_672, + 3, 293, :_reduce_673, + 1, 382, :_reduce_674, + 2, 383, :_reduce_675, + 1, 383, :_reduce_676, + 2, 384, :_reduce_677, + 1, 384, :_reduce_678, + 1, 287, :_reduce_679, + 3, 287, :_reduce_680, + 1, 377, :_reduce_681, + 3, 377, :_reduce_682, + 1, 348, :_reduce_none, + 1, 348, :_reduce_none, + 1, 283, :_reduce_685, + 2, 282, :_reduce_686, + 1, 282, :_reduce_687, + 3, 385, :_reduce_688, + 3, 386, :_reduce_689, + 1, 294, :_reduce_690, + 3, 294, :_reduce_691, + 1, 379, :_reduce_692, + 3, 379, :_reduce_693, + 1, 387, :_reduce_none, + 1, 387, :_reduce_none, + 2, 295, :_reduce_696, + 1, 295, :_reduce_697, + 1, 388, :_reduce_none, + 1, 388, :_reduce_none, + 2, 289, :_reduce_700, + 1, 289, :_reduce_701, + 2, 288, :_reduce_702, + 0, 288, :_reduce_703, + 1, 199, :_reduce_none, + 3, 199, :_reduce_705, + 0, 257, :_reduce_706, + 2, 257, :_reduce_none, + 1, 240, :_reduce_708, + 3, 240, :_reduce_709, + 3, 389, :_reduce_710, + 2, 389, :_reduce_711, + 1, 389, :_reduce_712, + 4, 389, :_reduce_713, + 2, 389, :_reduce_714, + 1, 389, :_reduce_715, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 210, :_reduce_none, + 1, 204, :_reduce_none, + 1, 204, :_reduce_none, + 1, 312, :_reduce_none, + 1, 312, :_reduce_none, + 1, 312, :_reduce_none, + 1, 200, :_reduce_none, + 1, 200, :_reduce_none, + 1, 180, :_reduce_726, + 1, 180, :_reduce_727, + 0, 152, :_reduce_none, + 1, 152, :_reduce_none, + 0, 188, :_reduce_none, + 1, 188, :_reduce_none, + 2, 215, :_reduce_732, + 2, 179, :_reduce_733, + 2, 335, :_reduce_734, + 1, 239, :_reduce_none, + 1, 239, :_reduce_none, + 1, 268, :_reduce_737, + 1, 268, :_reduce_none, + 1, 154, :_reduce_none, + 2, 154, :_reduce_none, + 0, 235, :_reduce_741 ] + +racc_reduce_n = 742 + +racc_shift_n = 1250 + +racc_token_table = { + false => 0, + :error => 1, + :kCLASS => 2, + :kMODULE => 3, + :kDEF => 4, + :kUNDEF => 5, + :kBEGIN => 6, + :kRESCUE => 7, + :kENSURE => 8, + :kEND => 9, + :kIF => 10, + :kUNLESS => 11, + :kTHEN => 12, + :kELSIF => 13, + :kELSE => 14, + :kCASE => 15, + :kWHEN => 16, + :kWHILE => 17, + :kUNTIL => 18, + :kFOR => 19, + :kBREAK => 20, + :kNEXT => 21, + :kREDO => 22, + :kRETRY => 23, + :kIN => 24, + :kDO => 25, + :kDO_COND => 26, + :kDO_BLOCK => 27, + :kDO_LAMBDA => 28, + :kRETURN => 29, + :kYIELD => 30, + :kSUPER => 31, + :kSELF => 32, + :kNIL => 33, + :kTRUE => 34, + :kFALSE => 35, + :kAND => 36, + :kOR => 37, + :kNOT => 38, + :kIF_MOD => 39, + :kUNLESS_MOD => 40, + :kWHILE_MOD => 41, + :kUNTIL_MOD => 42, + :kRESCUE_MOD => 43, + :kALIAS => 44, + :kDEFINED => 45, + :klBEGIN => 46, + :klEND => 47, + :k__LINE__ => 48, + :k__FILE__ => 49, + :k__ENCODING__ => 50, + :tIDENTIFIER => 51, + :tFID => 52, + :tGVAR => 53, + :tIVAR => 54, + :tCONSTANT => 55, + :tLABEL => 56, + :tCVAR => 57, + :tNTH_REF => 58, + :tBACK_REF => 59, + :tSTRING_CONTENT => 60, + :tINTEGER => 61, + :tFLOAT => 62, + :tUPLUS => 63, + :tUMINUS => 64, + :tUNARY_NUM => 65, + :tPOW => 66, + :tCMP => 67, + :tEQ => 68, + :tEQQ => 69, + :tNEQ => 70, + :tGEQ => 71, + :tLEQ => 72, + :tANDOP => 73, + :tOROP => 74, + :tMATCH => 75, + :tNMATCH => 76, + :tDOT => 77, + :tDOT2 => 78, + :tDOT3 => 79, + :tAREF => 80, + :tASET => 81, + :tLSHFT => 82, + :tRSHFT => 83, + :tCOLON2 => 84, + :tCOLON3 => 85, + :tOP_ASGN => 86, + :tASSOC => 87, + :tLPAREN => 88, + :tLPAREN2 => 89, + :tRPAREN => 90, + :tLPAREN_ARG => 91, + :tLBRACK => 92, + :tLBRACK2 => 93, + :tRBRACK => 94, + :tLBRACE => 95, + :tLBRACE_ARG => 96, + :tSTAR => 97, + :tSTAR2 => 98, + :tAMPER => 99, + :tAMPER2 => 100, + :tTILDE => 101, + :tPERCENT => 102, + :tDIVIDE => 103, + :tDSTAR => 104, + :tPLUS => 105, + :tMINUS => 106, + :tLT => 107, + :tGT => 108, + :tPIPE => 109, + :tBANG => 110, + :tCARET => 111, + :tLCURLY => 112, + :tRCURLY => 113, + :tBACK_REF2 => 114, + :tSYMBEG => 115, + :tSTRING_BEG => 116, + :tXSTRING_BEG => 117, + :tREGEXP_BEG => 118, + :tREGEXP_OPT => 119, + :tWORDS_BEG => 120, + :tQWORDS_BEG => 121, + :tSYMBOLS_BEG => 122, + :tQSYMBOLS_BEG => 123, + :tSTRING_DBEG => 124, + :tSTRING_DVAR => 125, + :tSTRING_END => 126, + :tSTRING_DEND => 127, + :tSTRING => 128, + :tSYMBOL => 129, + :tNL => 130, + :tEH => 131, + :tCOLON => 132, + :tCOMMA => 133, + :tSPACE => 134, + :tSEMI => 135, + :tLAMBDA => 136, + :tLAMBEG => 137, + :tCHARACTER => 138, + :tRATIONAL => 139, + :tIMAGINARY => 140, + :tLABEL_END => 141, + :tANDDOT => 142, + :tBDOT2 => 143, + :tBDOT3 => 144, + :tEQL => 145, + :tLOWEST => 146 } + +racc_nt_base = 147 + +racc_use_result_var = true + +Racc_arg = [ + racc_action_table, + racc_action_check, + racc_action_default, + racc_action_pointer, + racc_goto_table, + racc_goto_check, + racc_goto_default, + racc_goto_pointer, + racc_nt_base, + racc_reduce_table, + racc_token_table, + racc_shift_n, + racc_reduce_n, + racc_use_result_var ] +Ractor.make_shareable(Racc_arg) if defined?(Ractor) + +Racc_token_to_s_table = [ + "$end", + "error", + "kCLASS", + "kMODULE", + "kDEF", + "kUNDEF", + "kBEGIN", + "kRESCUE", + "kENSURE", + "kEND", + "kIF", + "kUNLESS", + "kTHEN", + "kELSIF", + "kELSE", + "kCASE", + "kWHEN", + "kWHILE", + "kUNTIL", + "kFOR", + "kBREAK", + "kNEXT", + "kREDO", + "kRETRY", + "kIN", + "kDO", + "kDO_COND", + "kDO_BLOCK", + "kDO_LAMBDA", + "kRETURN", + "kYIELD", + "kSUPER", + "kSELF", + "kNIL", + "kTRUE", + "kFALSE", + "kAND", + "kOR", + "kNOT", + "kIF_MOD", + "kUNLESS_MOD", + "kWHILE_MOD", + "kUNTIL_MOD", + "kRESCUE_MOD", + "kALIAS", + "kDEFINED", + "klBEGIN", + "klEND", + "k__LINE__", + "k__FILE__", + "k__ENCODING__", + "tIDENTIFIER", + "tFID", + "tGVAR", + "tIVAR", + "tCONSTANT", + "tLABEL", + "tCVAR", + "tNTH_REF", + "tBACK_REF", + "tSTRING_CONTENT", + "tINTEGER", + "tFLOAT", + "tUPLUS", + "tUMINUS", + "tUNARY_NUM", + "tPOW", + "tCMP", + "tEQ", + "tEQQ", + "tNEQ", + "tGEQ", + "tLEQ", + "tANDOP", + "tOROP", + "tMATCH", + "tNMATCH", + "tDOT", + "tDOT2", + "tDOT3", + "tAREF", + "tASET", + "tLSHFT", + "tRSHFT", + "tCOLON2", + "tCOLON3", + "tOP_ASGN", + "tASSOC", + "tLPAREN", + "tLPAREN2", + "tRPAREN", + "tLPAREN_ARG", + "tLBRACK", + "tLBRACK2", + "tRBRACK", + "tLBRACE", + "tLBRACE_ARG", + "tSTAR", + "tSTAR2", + "tAMPER", + "tAMPER2", + "tTILDE", + "tPERCENT", + "tDIVIDE", + "tDSTAR", + "tPLUS", + "tMINUS", + "tLT", + "tGT", + "tPIPE", + "tBANG", + "tCARET", + "tLCURLY", + "tRCURLY", + "tBACK_REF2", + "tSYMBEG", + "tSTRING_BEG", + "tXSTRING_BEG", + "tREGEXP_BEG", + "tREGEXP_OPT", + "tWORDS_BEG", + "tQWORDS_BEG", + "tSYMBOLS_BEG", + "tQSYMBOLS_BEG", + "tSTRING_DBEG", + "tSTRING_DVAR", + "tSTRING_END", + "tSTRING_DEND", + "tSTRING", + "tSYMBOL", + "tNL", + "tEH", + "tCOLON", + "tCOMMA", + "tSPACE", + "tSEMI", + "tLAMBDA", + "tLAMBEG", + "tCHARACTER", + "tRATIONAL", + "tIMAGINARY", + "tLABEL_END", + "tANDDOT", + "tBDOT2", + "tBDOT3", + "tEQL", + "tLOWEST", + "$start", + "program", + "top_compstmt", + "@1", + "top_stmts", + "opt_terms", + "top_stmt", + "terms", + "stmt", + "begin_block", + "bodystmt", + "compstmt", + "opt_rescue", + "opt_else", + "opt_ensure", + "stmts", + "stmt_or_begin", + "fitem", + "undef_list", + "expr_value", + "command_asgn", + "mlhs", + "command_call", + "lhs", + "mrhs", + "mrhs_arg", + "expr", + "@2", + "command_rhs", + "var_lhs", + "primary_value", + "opt_call_args", + "rbracket", + "call_op", + "defn_head", + "f_opt_paren_args", + "endless_command", + "defs_head", + "backref", + "command", + "arg", + "opt_nl", + "p_in_kwarg", + "p_pvtbl", + "p_pktbl", + "p_top_expr_body", + "expr_value_do", + "do", + "def_name", + "@3", + "fname", + "k_def", + "singleton", + "dot_or_colon", + "@4", + "block_command", + "block_call", + "operation2", + "command_args", + "cmd_brace_block", + "brace_body", + "fcall", + "@5", + "operation", + "k_return", + "call_args", + "mlhs_basic", + "mlhs_inner", + "rparen", + "mlhs_head", + "mlhs_item", + "mlhs_node", + "mlhs_post", + "user_variable", + "keyword_variable", + "cname", + "cpath", + "op", + "reswords", + "symbol", + "@6", + "arg_rhs", + "simple_numeric", + "rel_expr", + "begin_defined", + "endless_arg", + "primary", + "relop", + "none", + "arg_value", + "aref_args", + "args", + "trailer", + "assocs", + "paren_args", + "args_forward", + "opt_paren_args", + "opt_block_arg", + "block_arg", + "@7", + "arg_splat", + "literal", + "strings", + "xstring", + "regexp", + "words", + "qwords", + "symbols", + "qsymbols", + "var_ref", + "assoc_list", + "brace_block", + "method_call", + "lambda", + "then", + "if_tail", + "case_body", + "p_case_body", + "for_var", + "k_class", + "superclass", + "term", + "k_module", + "f_arglist", + "@8", + "@9", + "@10", + "@11", + "@12", + "f_marg", + "f_norm_arg", + "f_margs", + "f_marg_list", + "f_rest_marg", + "f_any_kwrest", + "f_kwrest", + "f_no_kwarg", + "f_eq", + "block_args_tail", + "@13", + "f_block_kwarg", + "opt_f_block_arg", + "f_block_arg", + "opt_block_args_tail", + "excessed_comma", + "block_param", + "f_arg", + "f_block_optarg", + "f_rest_arg", + "opt_block_param", + "block_param_def", + "opt_bv_decl", + "bv_decls", + "bvar", + "f_bad_arg", + "f_larglist", + "lambda_body", + "@14", + "@15", + "f_args", + "do_block", + "@16", + "@17", + "do_body", + "@18", + "operation3", + "@19", + "@20", + "@21", + "@22", + "@23", + "cases", + "p_top_expr", + "p_cases", + "@24", + "p_expr", + "p_args", + "p_find", + "p_args_tail", + "p_kwargs", + "p_as", + "p_variable", + "p_alt", + "p_expr_basic", + "p_lparen", + "p_lbracket", + "p_value", + "p_const", + "rbrace", + "@25", + "@26", + "p_args_head", + "p_arg", + "p_rest", + "p_args_post", + "p_kwarg", + "p_any_kwrest", + "p_kw", + "p_kw_label", + "string_contents", + "p_kwrest", + "kwrest_mark", + "p_kwnorest", + "p_primitive", + "p_var_ref", + "p_expr_ref", + "nonlocal_var", + "exc_list", + "exc_var", + "numeric", + "string", + "string1", + "xstring_contents", + "regexp_contents", + "words_sep", + "word_list", + "word", + "string_content", + "symbol_list", + "qword_list", + "qsym_list", + "string_dvar", + "string_dend", + "@27", + "ssym", + "dsym", + "@28", + "f_paren_args", + "args_tail", + "@29", + "f_kwarg", + "opt_args_tail", + "f_optarg", + "f_arg_asgn", + "f_arg_item", + "f_label", + "f_kw", + "f_block_kw", + "f_opt", + "f_block_opt", + "restarg_mark", + "blkarg_mark", + "assoc" ] +Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) + +Racc_debug_parser = false + +##### State transition tables end ##### + +# reduce 0 omitted + +def _reduce_1(val, _values, result) + @current_arg_stack.push(nil) + @max_numparam_stack.push(static: true) + + result +end + +def _reduce_2(val, _values, result) + result = val[1] + + @current_arg_stack.pop + @max_numparam_stack.pop + + result +end + +def _reduce_3(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_4(val, _values, result) + result = [] + + result +end + +def _reduce_5(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_6(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_7(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 8 omitted + +def _reduce_9(val, _values, result) + result = @builder.preexe(val[0], *val[1]) + + result +end + +def _reduce_10(val, _values, result) + result = val + + result +end + +def _reduce_11(val, _values, result) + rescue_bodies = val[1] + else_t, else_ = val[2] + ensure_t, ensure_ = val[3] + + if rescue_bodies.empty? && !else_t.nil? + diagnostic :error, :useless_else, nil, else_t + end + + result = @builder.begin_body(val[0], + rescue_bodies, + else_t, else_, + ensure_t, ensure_) + + result +end + +def _reduce_12(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_13(val, _values, result) + result = [] + + result +end + +def _reduce_14(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_15(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_16(val, _values, result) + result = [ val[1] ] + + result +end + +# reduce 17 omitted + +def _reduce_18(val, _values, result) + diagnostic :error, :begin_in_method, nil, val[0] + + result +end + +def _reduce_19(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_20(val, _values, result) + result = @builder.alias(val[0], val[1], val[3]) + + result +end + +def _reduce_21(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.gvar(val[2])) + + result +end + +def _reduce_22(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.back_ref(val[2])) + + result +end + +def _reduce_23(val, _values, result) + diagnostic :error, :nth_ref_alias, nil, val[2] + + result +end + +def _reduce_24(val, _values, result) + result = @builder.undef_method(val[0], val[1]) + + result +end + +def _reduce_25(val, _values, result) + result = @builder.condition_mod(val[0], nil, + val[1], val[2]) + + result +end + +def _reduce_26(val, _values, result) + result = @builder.condition_mod(nil, val[0], + val[1], val[2]) + + result +end + +def _reduce_27(val, _values, result) + result = @builder.loop_mod(:while, val[0], val[1], val[2]) + + result +end + +def _reduce_28(val, _values, result) + result = @builder.loop_mod(:until, val[0], val[1], val[2]) + + result +end + +def _reduce_29(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_30(val, _values, result) + result = @builder.postexe(val[0], val[1], val[2], val[3]) + + result +end + +# reduce 31 omitted + +def _reduce_32(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_33(val, _values, result) + result = @builder.assign(val[0], val[1], + @builder.array(nil, val[2], nil)) + + result +end + +def _reduce_34(val, _values, result) + rescue_body = @builder.rescue_body(val[3], + nil, nil, nil, + nil, val[4]) + begin_body = @builder.begin_body(val[2], [ rescue_body ]) + + result = @builder.multi_assign(val[0], val[1], begin_body) + + result +end + +def _reduce_35(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +# reduce 36 omitted + +def _reduce_37(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_38(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_39(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_40(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_41(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_42(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_43(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_44(val, _values, result) + def_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + result = @builder.def_endless_method(def_t, name_t, + val[1], val[2], val[3]) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_45(val, _values, result) + def_t, recv, dot_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + result = @builder.def_endless_singleton(def_t, recv, dot_t, name_t, + val[1], val[2], val[3]) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_46(val, _values, result) + @builder.op_assign(val[0], val[1], val[2]) + + result +end + +# reduce 47 omitted + +def _reduce_48(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_49(val, _values, result) + result = @builder.not_op(val[0], nil, val[2], nil) + + result +end + +# reduce 50 omitted + +def _reduce_51(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +# reduce 52 omitted + +# reduce 53 omitted + +def _reduce_54(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_55(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_56(val, _values, result) + result = @builder.not_op(val[0], nil, val[2], nil) + + result +end + +def _reduce_57(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +def _reduce_58(val, _values, result) + @pattern_variables.pop + @pattern_hash_keys.pop + @context.in_kwarg = val[2] + result = @builder.match_pattern(val[0], val[1], val[5]) + + result +end + +def _reduce_59(val, _values, result) + @pattern_variables.pop + @pattern_hash_keys.pop + @context.in_kwarg = val[2] + result = @builder.match_pattern_p(val[0], val[1], val[5]) + + result +end + +# reduce 60 omitted + +# reduce 61 omitted + +def _reduce_62(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_63(val, _values, result) + @lexer.cond.pop + result = [ val[1], val[2] ] + + result +end + +def _reduce_64(val, _values, result) + local_push + @current_arg_stack.push(nil) + + result = [ val[0], @context.dup ] + @context.in_def = true + @context.cant_return = false + + result +end + +def _reduce_65(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +def _reduce_66(val, _values, result) + @lexer.state = :expr_fname + @context.in_argdef = true + + result +end + +def _reduce_67(val, _values, result) + result = [ val[0], val[1], val[2], val[4] ] + + result +end + +# reduce 68 omitted + +# reduce 69 omitted + +# reduce 70 omitted + +def _reduce_71(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_72(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_73(val, _values, result) + @context.in_block = val[1].in_block + result = [ val[0], *val[2], val[3] ] + + result +end + +# reduce 74 omitted + +def _reduce_75(val, _values, result) + result = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + result +end + +def _reduce_76(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0], + nil, val[1], nil) + + begin_t, args, body, end_t = val[2] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_77(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_78(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_79(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + result +end + +def _reduce_80(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_81(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, [], nil) + + args, body = val[4] + result = @builder.block(method_call, val[3], args, body, val[5]) + + result +end + +def _reduce_82(val, _values, result) + result = @builder.keyword_cmd(:super, val[0], + nil, val[1], nil) + + result +end + +def _reduce_83(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], + nil, val[1], nil) + + result +end + +def _reduce_84(val, _values, result) + result = @builder.keyword_cmd(:return, val[0], + nil, val[1], nil) + + result +end + +def _reduce_85(val, _values, result) + result = @builder.keyword_cmd(:break, val[0], + nil, val[1], nil) + + result +end + +def _reduce_86(val, _values, result) + result = @builder.keyword_cmd(:next, val[0], + nil, val[1], nil) + + result +end + +def _reduce_87(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_88(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_89(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_90(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +# reduce 91 omitted + +def _reduce_92(val, _values, result) + result = val[0]. + push(val[1]) + + result +end + +def _reduce_93(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])) + + result +end + +def _reduce_94(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])). + concat(val[4]) + + result +end + +def _reduce_95(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])) + + result +end + +def _reduce_96(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])). + concat(val[3]) + + result +end + +def _reduce_97(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_98(val, _values, result) + result = [ @builder.splat(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_99(val, _values, result) + result = [ @builder.splat(val[0]) ] + + result +end + +def _reduce_100(val, _values, result) + result = [ @builder.splat(val[0]), + *val[2] ] + + result +end + +# reduce 101 omitted + +def _reduce_102(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_103(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_104(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_105(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_106(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_107(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_108(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_109(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_110(val, _values, result) + if (val[1][0] == :anddot) + diagnostic :error, :csend_in_lhs_of_masgn, nil, val[1] + end + + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_111(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_112(val, _values, result) + if (val[1][0] == :anddot) + diagnostic :error, :csend_in_lhs_of_masgn, nil, val[1] + end + + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_113(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_114(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_115(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_116(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_117(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_118(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_119(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_120(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_121(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_122(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_123(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_124(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_125(val, _values, result) + diagnostic :error, :module_name_const, nil, val[0] + + result +end + +# reduce 126 omitted + +def _reduce_127(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_128(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_129(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +# reduce 130 omitted + +# reduce 131 omitted + +# reduce 132 omitted + +# reduce 133 omitted + +# reduce 134 omitted + +def _reduce_135(val, _values, result) + result = @builder.symbol_internal(val[0]) + + result +end + +# reduce 136 omitted + +def _reduce_137(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_138(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_139(val, _values, result) + result = val[0] << val[3] + + result +end + +# reduce 140 omitted + +# reduce 141 omitted + +# reduce 142 omitted + +# reduce 143 omitted + +# reduce 144 omitted + +# reduce 145 omitted + +# reduce 146 omitted + +# reduce 147 omitted + +# reduce 148 omitted + +# reduce 149 omitted + +# reduce 150 omitted + +# reduce 151 omitted + +# reduce 152 omitted + +# reduce 153 omitted + +# reduce 154 omitted + +# reduce 155 omitted + +# reduce 156 omitted + +# reduce 157 omitted + +# reduce 158 omitted + +# reduce 159 omitted + +# reduce 160 omitted + +# reduce 161 omitted + +# reduce 162 omitted + +# reduce 163 omitted + +# reduce 164 omitted + +# reduce 165 omitted + +# reduce 166 omitted + +# reduce 167 omitted + +# reduce 168 omitted + +# reduce 169 omitted + +# reduce 170 omitted + +# reduce 171 omitted + +# reduce 172 omitted + +# reduce 173 omitted + +# reduce 174 omitted + +# reduce 175 omitted + +# reduce 176 omitted + +# reduce 177 omitted + +# reduce 178 omitted + +# reduce 179 omitted + +# reduce 180 omitted + +# reduce 181 omitted + +# reduce 182 omitted + +# reduce 183 omitted + +# reduce 184 omitted + +# reduce 185 omitted + +# reduce 186 omitted + +# reduce 187 omitted + +# reduce 188 omitted + +# reduce 189 omitted + +# reduce 190 omitted + +# reduce 191 omitted + +# reduce 192 omitted + +# reduce 193 omitted + +# reduce 194 omitted + +# reduce 195 omitted + +# reduce 196 omitted + +# reduce 197 omitted + +# reduce 198 omitted + +# reduce 199 omitted + +# reduce 200 omitted + +# reduce 201 omitted + +# reduce 202 omitted + +# reduce 203 omitted + +# reduce 204 omitted + +# reduce 205 omitted + +# reduce 206 omitted + +# reduce 207 omitted + +# reduce 208 omitted + +# reduce 209 omitted + +# reduce 210 omitted + +def _reduce_211(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_212(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_213(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_214(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_215(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_216(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_217(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_fetch(val[0], val[1], val[2])) + result = @builder.op_assign(const, val[3], val[4]) + + result +end + +def _reduce_218(val, _values, result) + const = @builder.const_op_assignable( + @builder.const_global(val[0], val[1])) + result = @builder.op_assign(const, val[2], val[3]) + + result +end + +def _reduce_219(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_220(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_221(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_222(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], nil) + + result +end + +def _reduce_223(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], nil) + + result +end + +def _reduce_224(val, _values, result) + result = @builder.range_inclusive(nil, val[0], val[1]) + + result +end + +def _reduce_225(val, _values, result) + result = @builder.range_exclusive(nil, val[0], val[1]) + + result +end + +def _reduce_226(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_227(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_228(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_229(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_230(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_231(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_232(val, _values, result) + result = @builder.unary_op(val[0], + @builder.binary_op( + val[1], val[2], val[3])) + + result +end + +def _reduce_233(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_234(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_235(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_236(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_237(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_238(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +# reduce 239 omitted + +def _reduce_240(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_241(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_242(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_243(val, _values, result) + result = @builder.match_op(val[0], val[1], val[2]) + + result +end + +def _reduce_244(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_245(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +def _reduce_246(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_247(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_248(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_249(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_250(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_251(val, _values, result) + @context.in_defined = val[2].in_defined + result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[3] ], nil) + + result +end + +def _reduce_252(val, _values, result) + result = @builder.ternary(val[0], val[1], + val[2], val[4], val[5]) + + result +end + +def _reduce_253(val, _values, result) + def_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + result = @builder.def_endless_method(def_t, name_t, + val[1], val[2], val[3]) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_254(val, _values, result) + def_t, recv, dot_t, (name_t, ctx) = val[0] + endless_method_name(name_t) + + result = @builder.def_endless_singleton(def_t, recv, dot_t, name_t, + val[1], val[2], val[3]) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +# reduce 255 omitted + +# reduce 256 omitted + +def _reduce_257(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_258(val, _values, result) + result = @builder.not_op(val[0], nil, val[2], nil) + + result +end + +# reduce 259 omitted + +# reduce 260 omitted + +# reduce 261 omitted + +# reduce 262 omitted + +def _reduce_263(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_264(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_265(val, _values, result) + result = @context.dup + + result +end + +# reduce 266 omitted + +# reduce 267 omitted + +# reduce 268 omitted + +def _reduce_269(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_270(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +# reduce 271 omitted + +def _reduce_272(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_273(val, _values, result) + result = val + + result +end + +def _reduce_274(val, _values, result) + unless @static_env.declared_forward_args? + diagnostic :error, :unexpected_token, { :token => 'tBDOT3' } , val[3] + end + + result = [val[0], [*val[1], @builder.forwarded_args(val[3])], val[4]] + + result +end + +def _reduce_275(val, _values, result) + unless @static_env.declared_forward_args? + diagnostic :error, :unexpected_token, { :token => 'tBDOT3' } , val[1] + end + + result = [val[0], [@builder.forwarded_args(val[1])], val[2]] + + result +end + +def _reduce_276(val, _values, result) + result = [ nil, [], nil ] + + result +end + +# reduce 277 omitted + +def _reduce_278(val, _values, result) + result = [] + + result +end + +# reduce 279 omitted + +# reduce 280 omitted + +def _reduce_281(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_282(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +def _reduce_283(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_284(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_285(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + result.concat(val[1]) + + result +end + +def _reduce_286(val, _values, result) + assocs = @builder.associate(nil, val[2], nil) + result = val[0] << assocs + result.concat(val[3]) + + result +end + +def _reduce_287(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_288(val, _values, result) + # When branch gets invoked by RACC's lookahead + # and command args start with '[' or '(' + # we need to put `true` to the cmdarg stack + # **before** `false` pushed by lexer + # m [], n + # ^ + # Right here we have cmdarg [...0] because + # lexer pushed it on '[' + # We need to modify cmdarg stack to [...10] + # + # For all other cases (like `m n` or `m n, []`) we simply put 1 to the stack + # and later lexer pushes corresponding bits on top of it. + last_token = @last_token[0] + lookahead = last_token == :tLBRACK || last_token == :tLPAREN_ARG + + if lookahead + top = @lexer.cmdarg.pop + @lexer.cmdarg.push(true) + @lexer.cmdarg.push(top) + else + @lexer.cmdarg.push(true) + end + + result +end + +def _reduce_289(val, _values, result) + # call_args can be followed by tLBRACE_ARG (that does cmdarg.push(0) in the lexer) + # but the push must be done after cmdarg.pop() in the parser. + # So this code does cmdarg.pop() to pop 0 pushed by tLBRACE_ARG, + # cmdarg.pop() to pop 1 pushed by command_args, + # and cmdarg.push(0) to restore back the flag set by tLBRACE_ARG. + last_token = @last_token[0] + lookahead = last_token == :tLBRACE_ARG + if lookahead + top = @lexer.cmdarg.pop + @lexer.cmdarg.pop + @lexer.cmdarg.push(top) + else + @lexer.cmdarg.pop + end + + result = val[1] + + result +end + +def _reduce_290(val, _values, result) + result = @builder.block_pass(val[0], val[1]) + + result +end + +def _reduce_291(val, _values, result) + if !@static_env.declared_anonymous_blockarg? + diagnostic :error, :no_anonymous_blockarg, nil, val[0] + end + + if @context.in_dynamic_block? && context.in_def && + @static_env.declared_anonymous_blockarg_in_current_scpe? && @static_env.parent_has_anonymous_blockarg? + diagnostic :error, :ambiguous_anonymous_blockarg, nil, val[0] + end + + result = @builder.block_pass(val[0], nil) + + result +end + +def _reduce_292(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_293(val, _values, result) + result = [] + + result +end + +def _reduce_294(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 295 omitted + +def _reduce_296(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_297(val, _values, result) + result = val[0].concat(val[2]) + + result +end + +def _reduce_298(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_299(val, _values, result) + if !@static_env.declared_anonymous_restarg? + diagnostic :error, :no_anonymous_restarg, nil, val[0] + end + + if @context.in_dynamic_block? && context.in_def && + @static_env.declared_anonymous_restarg_in_current_scope? && @static_env.parent_has_anonymous_restarg? + diagnostic :error, :ambiguous_anonymous_restarg, nil, val[0] + end + + result = [ @builder.forwarded_restarg(val[0]) ] + + result +end + +def _reduce_300(val, _values, result) + result = @builder.array(nil, val[0], nil) + + result +end + +# reduce 301 omitted + +def _reduce_302(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_303(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_304(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +# reduce 305 omitted + +# reduce 306 omitted + +# reduce 307 omitted + +# reduce 308 omitted + +# reduce 309 omitted + +# reduce 310 omitted + +# reduce 311 omitted + +# reduce 312 omitted + +# reduce 313 omitted + +# reduce 314 omitted + +def _reduce_315(val, _values, result) + result = @builder.call_method(nil, nil, val[0]) + + result +end + +def _reduce_316(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_317(val, _values, result) + @lexer.cmdarg.pop + + result = @builder.begin_keyword(val[0], val[2], val[3]) + + result +end + +def _reduce_318(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_319(val, _values, result) + result = @builder.begin(val[0], val[1], val[3]) + + result +end + +def _reduce_320(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_321(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +def _reduce_322(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_323(val, _values, result) + result = @builder.array(val[0], val[1], val[2]) + + result +end + +def _reduce_324(val, _values, result) + result = @builder.associate(val[0], val[1], val[2]) + + result +end + +def _reduce_325(val, _values, result) + result = @builder.keyword_cmd(:return, val[0]) + + result +end + +def _reduce_326(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_327(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2]) + + result +end + +def _reduce_328(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0]) + + result +end + +def _reduce_329(val, _values, result) + @context.in_defined = val[3].in_defined + result = @builder.keyword_cmd(:defined?, val[0], + val[2], [ val[4] ], val[5]) + + result +end + +def _reduce_330(val, _values, result) + result = @builder.not_op(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_331(val, _values, result) + result = @builder.not_op(val[0], val[1], nil, val[2]) + + result +end + +def _reduce_332(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0]) + + begin_t, args, body, end_t = val[1] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +# reduce 333 omitted + +def _reduce_334(val, _values, result) + begin_t, args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, args, body, end_t) + + result +end + +# reduce 335 omitted + +def _reduce_336(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, val[5]) + + result +end + +def _reduce_337(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + else_, else_t, + val[3], val[5]) + + result +end + +def _reduce_338(val, _values, result) + result = @builder.loop(:while, val[0], *val[1], val[2], val[3]) + + result +end + +def _reduce_339(val, _values, result) + result = @builder.loop(:until, val[0], *val[1], val[2], val[3]) + + result +end + +def _reduce_340(val, _values, result) + *when_bodies, (else_t, else_body) = *val[3] + + result = @builder.case(val[0], val[1], + when_bodies, else_t, else_body, + val[4]) + + result +end + +def _reduce_341(val, _values, result) + *when_bodies, (else_t, else_body) = *val[2] + + result = @builder.case(val[0], nil, + when_bodies, else_t, else_body, + val[3]) + + result +end + +def _reduce_342(val, _values, result) + *in_bodies, (else_t, else_body) = *val[3] + + result = @builder.case_match(val[0], val[1], + in_bodies, else_t, else_body, + val[4]) + + result +end + +def _reduce_343(val, _values, result) + result = @builder.for(val[0], val[1], val[2], *val[3], val[4], val[5]) + + result +end + +def _reduce_344(val, _values, result) + @context.in_class = true + @context.cant_return = true + local_push + + result +end + +def _reduce_345(val, _values, result) + k_class, ctx = val[0] + if @context.in_def + diagnostic :error, :class_in_def, nil, k_class + end + lt_t, superclass = val[2] + result = @builder.def_class(k_class, val[1], + lt_t, superclass, + val[4], val[5]) + + local_pop + @context.in_class = ctx.in_class + @context.cant_return = ctx.cant_return + + result +end + +def _reduce_346(val, _values, result) + @context.in_def = false + @context.in_class = false + @context.cant_return = true + local_push + + result +end + +def _reduce_347(val, _values, result) + k_class, ctx = val[0] + result = @builder.def_sclass(k_class, val[1], val[2], + val[5], val[6]) + + local_pop + @context.in_def = ctx.in_def + @context.in_class = ctx.in_class + @context.cant_return = ctx.cant_return + + result +end + +def _reduce_348(val, _values, result) + @context.in_class = true + @context.cant_return = true + local_push + + result +end + +def _reduce_349(val, _values, result) + k_mod, ctx = val[0] + if @context.in_def + diagnostic :error, :module_in_def, nil, k_mod + end + result = @builder.def_module(k_mod, val[1], + val[3], val[4]) + + local_pop + @context.in_class = ctx.in_class + @context.cant_return = ctx.cant_return + + result +end + +def _reduce_350(val, _values, result) + def_t, (name_t, ctx) = val[0] + result = @builder.def_method(def_t, name_t, val[1], + val[2], val[3]) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_351(val, _values, result) + def_t, recv, dot_t, (name_t, ctx) = val[0] + result = @builder.def_singleton(def_t, recv, dot_t, name_t, val[1], + val[2], val[3]) + + local_pop + @current_arg_stack.pop + @context.in_def = ctx.in_def + + result +end + +def _reduce_352(val, _values, result) + result = @builder.keyword_cmd(:break, val[0]) + + result +end + +def _reduce_353(val, _values, result) + result = @builder.keyword_cmd(:next, val[0]) + + result +end + +def _reduce_354(val, _values, result) + result = @builder.keyword_cmd(:redo, val[0]) + + result +end + +def _reduce_355(val, _values, result) + result = @builder.keyword_cmd(:retry, val[0]) + + result +end + +# reduce 356 omitted + +def _reduce_357(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_358(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_359(val, _values, result) + result = val[0] + @context.in_argdef = true + + result +end + +def _reduce_360(val, _values, result) + if @context.cant_return && !(context.in_block || context.in_lambda) + diagnostic :error, :invalid_return, nil, val[0] + end + + result +end + +# reduce 361 omitted + +# reduce 362 omitted + +def _reduce_363(val, _values, result) + result = val[1] + + result +end + +# reduce 364 omitted + +# reduce 365 omitted + +# reduce 366 omitted + +def _reduce_367(val, _values, result) + else_t, else_ = val[4] + result = [ val[0], + @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, nil), + ] + + result +end + +# reduce 368 omitted + +def _reduce_369(val, _values, result) + result = val + + result +end + +# reduce 370 omitted + +# reduce 371 omitted + +def _reduce_372(val, _values, result) + result = @builder.arg(val[0]) + + result +end + +def _reduce_373(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_374(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_375(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 376 omitted + +def _reduce_377(val, _values, result) + result = val[0]. + push(val[2]) + + result +end + +def _reduce_378(val, _values, result) + result = val[0]. + push(val[2]). + concat(val[4]) + + result +end + +def _reduce_379(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_380(val, _values, result) + result = [ val[0], *val[2] ] + + result +end + +def _reduce_381(val, _values, result) + result = @builder.restarg(val[0], val[1]) + + result +end + +def _reduce_382(val, _values, result) + result = @builder.restarg(val[0]) + + result +end + +# reduce 383 omitted + +# reduce 384 omitted + +def _reduce_385(val, _values, result) + @context.in_argdef = false + + result +end + +def _reduce_386(val, _values, result) + result = val[1] + + result +end + +def _reduce_387(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_388(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_389(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_390(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_391(val, _values, result) + result = val[1] + + result +end + +def _reduce_392(val, _values, result) + result = [] + + result +end + +# reduce 393 omitted + +def _reduce_394(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_395(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_396(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_397(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_398(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 399 omitted + +def _reduce_400(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_401(val, _values, result) + if val[1].empty? && val[0].size == 1 + result = [@builder.procarg0(val[0][0])] + else + result = val[0].concat(val[1]) + end + + result +end + +def _reduce_402(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_403(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_404(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_405(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_406(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_407(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 408 omitted + +def _reduce_409(val, _values, result) + result = @builder.args(nil, [], nil) + + result +end + +def _reduce_410(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_411(val, _values, result) + @max_numparam_stack.has_ordinary_params! + @current_arg_stack.set(nil) + @context.in_argdef = false + result = @builder.args(val[0], val[1], val[2]) + + result +end + +def _reduce_412(val, _values, result) + @max_numparam_stack.has_ordinary_params! + @current_arg_stack.set(nil) + @context.in_argdef = false + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_413(val, _values, result) + result = [] + + result +end + +def _reduce_414(val, _values, result) + result = val[2] + + result +end + +def _reduce_415(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_416(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_417(val, _values, result) + @static_env.declare val[0][0] + result = @builder.shadowarg(val[0]) + + result +end + +# reduce 418 omitted + +def _reduce_419(val, _values, result) + @static_env.extend_dynamic + @max_numparam_stack.push(static: false) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_420(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_421(val, _values, result) + lambda_call = @builder.call_lambda(val[0]) + args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[2] + begin_t, body, end_t = val[4] + + @max_numparam_stack.pop + @static_env.unextend + @lexer.cmdarg.pop + @context.in_lambda = val[1].in_lambda + + result = @builder.block(lambda_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_422(val, _values, result) + @context.in_argdef = false + @max_numparam_stack.has_ordinary_params! + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_423(val, _values, result) + @context.in_argdef = false + if val[0].any? + @max_numparam_stack.has_ordinary_params! + end + result = @builder.args(nil, val[0], nil) + + result +end + +def _reduce_424(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_425(val, _values, result) + @context.in_lambda = val[1].in_lambda + result = [ val[0], val[2], val[3] ] + + result +end + +def _reduce_426(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_427(val, _values, result) + @context.in_lambda = val[1].in_lambda + result = [ val[0], val[2], val[3] ] + + result +end + +def _reduce_428(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_429(val, _values, result) + @context.in_block = val[1].in_block + result = [ val[0], *val[2], val[3] ] + + result +end + +def _reduce_430(val, _values, result) + begin_t, block_args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, block_args, body, end_t) + + result +end + +def _reduce_431(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_432(val, _values, result) + lparen_t, args, rparen_t = val[3] + method_call = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_433(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + nil, val[3], nil) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_434(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.call_method(nil, nil, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_435(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_436(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_437(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2]) + + result +end + +def _reduce_438(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_439(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_440(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.keyword_cmd(:super, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_441(val, _values, result) + result = @builder.keyword_cmd(:zsuper, val[0]) + + result +end + +def _reduce_442(val, _values, result) + result = @builder.index(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_443(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_444(val, _values, result) + @context.in_block = val[1].in_block + result = [ val[0], *val[2], val[3] ] + + result +end + +def _reduce_445(val, _values, result) + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_446(val, _values, result) + @context.in_block = val[1].in_block + result = [ val[0], *val[2], val[3] ] + + result +end + +def _reduce_447(val, _values, result) + @static_env.extend_dynamic + @max_numparam_stack.push(static: false) + + result +end + +def _reduce_448(val, _values, result) + args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[1] + result = [ args, val[2] ] + + @max_numparam_stack.pop + @static_env.unextend + + result +end + +def _reduce_449(val, _values, result) + @static_env.extend_dynamic + @max_numparam_stack.push(static: false) + + result +end + +def _reduce_450(val, _values, result) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_451(val, _values, result) + args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[2] + result = [ args, val[3] ] + + @max_numparam_stack.pop + @static_env.unextend + @lexer.cmdarg.pop + + result +end + +def _reduce_452(val, _values, result) + result = [ @builder.when(val[0], val[1], val[2], val[3]), + *val[4] ] + + result +end + +def _reduce_453(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 454 omitted + +def _reduce_455(val, _values, result) + @pattern_variables.push + + result +end + +def _reduce_456(val, _values, result) + @pattern_hash_keys.push + + result +end + +def _reduce_457(val, _values, result) + result = @context.in_kwarg + + @lexer.state = :expr_beg + @lexer.command_start = false + @context.in_kwarg = true + + result +end + +def _reduce_458(val, _values, result) + @pattern_variables.pop + @pattern_hash_keys.pop + @context.in_kwarg = val[1] + + result +end + +def _reduce_459(val, _values, result) + result = [ @builder.in_pattern(val[0], *val[4], val[5], val[7]), + *val[8] ] + + result +end + +def _reduce_460(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 461 omitted + +def _reduce_462(val, _values, result) + result = [ val[0], nil ] + + result +end + +def _reduce_463(val, _values, result) + result = [ val[0], @builder.if_guard(val[1], val[2]) ] + + result +end + +def _reduce_464(val, _values, result) + result = [ val[0], @builder.unless_guard(val[1], val[2]) ] + + result +end + +# reduce 465 omitted + +def _reduce_466(val, _values, result) + # array patterns that end with comma + # like 1, 2, + # must be emitted as `array_pattern_with_tail` + item = @builder.match_with_trailing_comma(val[0], val[1]) + result = @builder.array_pattern(nil, [ item ], nil) + + result +end + +def _reduce_467(val, _values, result) + result = @builder.array_pattern(nil, [val[0]].concat(val[2]), nil) + + result +end + +def _reduce_468(val, _values, result) + result = @builder.find_pattern(nil, val[0], nil) + + result +end + +def _reduce_469(val, _values, result) + result = @builder.array_pattern(nil, val[0], nil) + + result +end + +def _reduce_470(val, _values, result) + result = @builder.hash_pattern(nil, val[0], nil) + + result +end + +# reduce 471 omitted + +def _reduce_472(val, _values, result) + result = @builder.match_as(val[0], val[1], val[2]) + + result +end + +# reduce 473 omitted + +def _reduce_474(val, _values, result) + result = @builder.match_alt(val[0], val[1], val[2]) + + result +end + +# reduce 475 omitted + +def _reduce_476(val, _values, result) + result = val[0] + @pattern_hash_keys.push + + result +end + +def _reduce_477(val, _values, result) + result = val[0] + @pattern_hash_keys.push + + result +end + +# reduce 478 omitted + +# reduce 479 omitted + +def _reduce_480(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.array_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_481(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.find_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_482(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.hash_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_483(val, _values, result) + pattern = @builder.array_pattern(val[1], nil, val[2]) + result = @builder.const_pattern(val[0], val[1], pattern, val[2]) + + result +end + +def _reduce_484(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.array_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_485(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.find_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_486(val, _values, result) + @pattern_hash_keys.pop + pattern = @builder.hash_pattern(nil, val[2], nil) + result = @builder.const_pattern(val[0], val[1], pattern, val[3]) + + result +end + +def _reduce_487(val, _values, result) + pattern = @builder.array_pattern(val[1], nil, val[2]) + result = @builder.const_pattern(val[0], val[1], pattern, val[2]) + + result +end + +def _reduce_488(val, _values, result) + result = @builder.array_pattern(val[0], val[1], val[2]) + + result +end + +def _reduce_489(val, _values, result) + result = @builder.find_pattern(val[0], val[1], val[2]) + + result +end + +def _reduce_490(val, _values, result) + result = @builder.array_pattern(val[0], [], val[1]) + + result +end + +def _reduce_491(val, _values, result) + @pattern_hash_keys.push + result = @context.in_kwarg + @context.in_kwarg = false + + result +end + +def _reduce_492(val, _values, result) + @pattern_hash_keys.pop + @context.in_kwarg = val[1] + result = @builder.hash_pattern(val[0], val[2], val[3]) + + result +end + +def _reduce_493(val, _values, result) + result = @builder.hash_pattern(val[0], [], val[1]) + + result +end + +def _reduce_494(val, _values, result) + @pattern_hash_keys.push + + result +end + +def _reduce_495(val, _values, result) + @pattern_hash_keys.pop + result = @builder.begin(val[0], val[2], val[3]) + + result +end + +def _reduce_496(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_497(val, _values, result) + result = val[0] + + result +end + +def _reduce_498(val, _values, result) + result = [ *val[0], val[1] ] + + result +end + +def _reduce_499(val, _values, result) + result = [ *val[0], val[1] ] + + result +end + +def _reduce_500(val, _values, result) + result = [ *val[0], val[1], *val[3] ] + + result +end + +# reduce 501 omitted + +def _reduce_502(val, _values, result) + # array patterns that end with comma + # like [1, 2,] + # must be emitted as `array_pattern_with_tail` + item = @builder.match_with_trailing_comma(val[0], val[1]) + result = [ item ] + + result +end + +def _reduce_503(val, _values, result) + # array patterns that end with comma + # like [1, 2,] + # must be emitted as `array_pattern_with_tail` + last_item = @builder.match_with_trailing_comma(val[1], val[2]) + result = [ *val[0], last_item ] + + result +end + +def _reduce_504(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_505(val, _values, result) + result = [ val[0], *val[2] ] + + result +end + +def _reduce_506(val, _values, result) + result = [ val[0], *val[2], val[4] ] + + result +end + +def _reduce_507(val, _values, result) + result = @builder.match_rest(val[0], val[1]) + + result +end + +def _reduce_508(val, _values, result) + result = @builder.match_rest(val[0]) + + result +end + +def _reduce_509(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_510(val, _values, result) + result = [ *val[0], val[2] ] + + result +end + +# reduce 511 omitted + +def _reduce_512(val, _values, result) + result = [ *val[0], *val[2] ] + + result +end + +def _reduce_513(val, _values, result) + result = val[0] + + result +end + +def _reduce_514(val, _values, result) + result = val[0] + + result +end + +def _reduce_515(val, _values, result) + result = val[0] + + result +end + +def _reduce_516(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_517(val, _values, result) + result = [ *val[0], val[2] ] + + result +end + +def _reduce_518(val, _values, result) + result = @builder.match_pair(*val[0], val[1]) + + result +end + +def _reduce_519(val, _values, result) + result = @builder.match_label(*val[0]) + + result +end + +def _reduce_520(val, _values, result) + result = [:label, val[0]] + + result +end + +def _reduce_521(val, _values, result) + result = [:quoted, [val[0], val[1], val[2]]] + + result +end + +def _reduce_522(val, _values, result) + result = [ @builder.match_rest(val[0], val[1]) ] + + result +end + +def _reduce_523(val, _values, result) + result = [ @builder.match_rest(val[0], nil) ] + + result +end + +def _reduce_524(val, _values, result) + result = val + + result +end + +# reduce 525 omitted + +def _reduce_526(val, _values, result) + result = [ @builder.match_nil_pattern(val[0][0], val[0][1]) ] + + result +end + +# reduce 527 omitted + +def _reduce_528(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_529(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_530(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], nil) + + result +end + +def _reduce_531(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], nil) + + result +end + +# reduce 532 omitted + +# reduce 533 omitted + +# reduce 534 omitted + +def _reduce_535(val, _values, result) + result = @builder.range_inclusive(nil, val[0], val[1]) + + result +end + +def _reduce_536(val, _values, result) + result = @builder.range_exclusive(nil, val[0], val[1]) + + result +end + +# reduce 537 omitted + +# reduce 538 omitted + +# reduce 539 omitted + +# reduce 540 omitted + +# reduce 541 omitted + +# reduce 542 omitted + +# reduce 543 omitted + +# reduce 544 omitted + +def _reduce_545(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +# reduce 546 omitted + +def _reduce_547(val, _values, result) + result = @builder.assignable(@builder.match_var(val[0])) + + result +end + +def _reduce_548(val, _values, result) + name = val[1][0] + lvar = @builder.accessible(@builder.ident(val[1])) + + unless static_env.declared?(name) + diagnostic :error, :undefined_lvar, { :name => name }, val[1] + end + + result = @builder.pin(val[0], lvar) + + result +end + +def _reduce_549(val, _values, result) + non_lvar = @builder.accessible(val[1]) + result = @builder.pin(val[0], non_lvar) + + result +end + +def _reduce_550(val, _values, result) + expr = @builder.begin(val[1], val[2], val[3]) + result = @builder.pin(val[0], expr) + + result +end + +def _reduce_551(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_552(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +def _reduce_553(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_554(val, _values, result) + assoc_t, exc_var = val[2] + + if val[1] + exc_list = @builder.array(nil, val[1], nil) + end + + result = [ @builder.rescue_body(val[0], + exc_list, assoc_t, exc_var, + val[3], val[4]), + *val[5] ] + + result +end + +def _reduce_555(val, _values, result) + result = [] + + result +end + +def _reduce_556(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 557 omitted + +# reduce 558 omitted + +def _reduce_559(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 560 omitted + +def _reduce_561(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 562 omitted + +# reduce 563 omitted + +# reduce 564 omitted + +def _reduce_565(val, _values, result) + result = @builder.string_compose(nil, val[0], nil) + + result +end + +def _reduce_566(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_567(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_568(val, _values, result) + string = @builder.string_compose(val[0], val[1], val[2]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_569(val, _values, result) + string = @builder.string(val[0]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_570(val, _values, result) + result = @builder.character(val[0]) + + result +end + +def _reduce_571(val, _values, result) + string = @builder.xstring_compose(val[0], val[1], val[2]) + result = @builder.dedent_string(string, @lexer.dedent_level) + + result +end + +def _reduce_572(val, _values, result) + opts = @builder.regexp_options(val[3]) + result = @builder.regexp_compose(val[0], val[1], val[2], opts) + + result +end + +# reduce 573 omitted + +# reduce 574 omitted + +def _reduce_575(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_576(val, _values, result) + result = [] + + result +end + +def _reduce_577(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_578(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_579(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_580(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_581(val, _values, result) + result = [] + + result +end + +def _reduce_582(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_583(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_584(val, _values, result) + result = @builder.symbols_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_585(val, _values, result) + result = [] + + result +end + +def _reduce_586(val, _values, result) + result = val[0] << @builder.string_internal(val[1]) + + result +end + +def _reduce_587(val, _values, result) + result = [] + + result +end + +def _reduce_588(val, _values, result) + result = val[0] << @builder.symbol_internal(val[1]) + + result +end + +def _reduce_589(val, _values, result) + result = [] + + result +end + +def _reduce_590(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_591(val, _values, result) + result = [] + + result +end + +def _reduce_592(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_593(val, _values, result) + result = [] + + result +end + +def _reduce_594(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_595(val, _values, result) + result = @builder.string_internal(val[0]) + + result +end + +def _reduce_596(val, _values, result) + result = val[1] + + result +end + +def _reduce_597(val, _values, result) + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + + result +end + +def _reduce_598(val, _values, result) + @lexer.cmdarg.pop + @lexer.cond.pop + + result = @builder.begin(val[0], val[2], val[3]) + + result +end + +# reduce 599 omitted + +def _reduce_600(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +# reduce 601 omitted + +# reduce 602 omitted + +# reduce 603 omitted + +def _reduce_604(val, _values, result) + @lexer.state = :expr_end + result = @builder.symbol(val[0]) + + result +end + +def _reduce_605(val, _values, result) + @lexer.state = :expr_end + result = @builder.symbol_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_606(val, _values, result) + result = val[0] + + result +end + +def _reduce_607(val, _values, result) + if @builder.respond_to? :negate + # AST builder interface compatibility + result = @builder.negate(val[0], val[1]) + else + result = @builder.unary_num(val[0], val[1]) + end + + result +end + +def _reduce_608(val, _values, result) + @lexer.state = :expr_end + result = @builder.integer(val[0]) + + result +end + +def _reduce_609(val, _values, result) + @lexer.state = :expr_end + result = @builder.float(val[0]) + + result +end + +def _reduce_610(val, _values, result) + @lexer.state = :expr_end + result = @builder.rational(val[0]) + + result +end + +def _reduce_611(val, _values, result) + @lexer.state = :expr_end + result = @builder.complex(val[0]) + + result +end + +def _reduce_612(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_613(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_614(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +def _reduce_615(val, _values, result) + result = @builder.ident(val[0]) + + result +end + +def _reduce_616(val, _values, result) + result = @builder.const(val[0]) + + result +end + +# reduce 617 omitted + +def _reduce_618(val, _values, result) + result = @builder.nil(val[0]) + + result +end + +def _reduce_619(val, _values, result) + result = @builder.self(val[0]) + + result +end + +def _reduce_620(val, _values, result) + result = @builder.true(val[0]) + + result +end + +def _reduce_621(val, _values, result) + result = @builder.false(val[0]) + + result +end + +def _reduce_622(val, _values, result) + result = @builder.__FILE__(val[0]) + + result +end + +def _reduce_623(val, _values, result) + result = @builder.__LINE__(val[0]) + + result +end + +def _reduce_624(val, _values, result) + result = @builder.__ENCODING__(val[0]) + + result +end + +def _reduce_625(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_626(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_627(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_628(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_629(val, _values, result) + result = @builder.nth_ref(val[0]) + + result +end + +def _reduce_630(val, _values, result) + result = @builder.back_ref(val[0]) + + result +end + +def _reduce_631(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_632(val, _values, result) + result = [ val[0], val[2] ] + + result +end + +def _reduce_633(val, _values, result) + result = nil + + result +end + +# reduce 634 omitted + +def _reduce_635(val, _values, result) + @context.in_argdef = false + result = @builder.args(nil, [], nil) + + result +end + +def _reduce_636(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + @lexer.state = :expr_value + @context.in_argdef = false + + result +end + +# reduce 637 omitted + +def _reduce_638(val, _values, result) + result = @context.dup + @context.in_kwarg = true + @context.in_argdef = true + + result +end + +def _reduce_639(val, _values, result) + @context.in_kwarg = val[0].in_kwarg + @context.in_argdef = false + result = @builder.args(nil, val[1], nil) + + result +end + +def _reduce_640(val, _values, result) + result = val[0].concat(val[2]).concat(val[3]) + + result +end + +def _reduce_641(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_642(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_643(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_644(val, _values, result) + @static_env.declare_forward_args + result = [ @builder.forward_arg(val[0]) ] + + result +end + +def _reduce_645(val, _values, result) + result = val[1] + + result +end + +def _reduce_646(val, _values, result) + result = [] + + result +end + +def _reduce_647(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_648(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_649(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_650(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_651(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_652(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_653(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_654(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_655(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_656(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_657(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_658(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_659(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_660(val, _values, result) + result = val[0] + + result +end + +def _reduce_661(val, _values, result) + result = [] + + result +end + +def _reduce_662(val, _values, result) + result = val[0] + + result +end + +def _reduce_663(val, _values, result) + diagnostic :error, :argument_const, nil, val[0] + + result +end + +def _reduce_664(val, _values, result) + diagnostic :error, :argument_ivar, nil, val[0] + + result +end + +def _reduce_665(val, _values, result) + diagnostic :error, :argument_gvar, nil, val[0] + + result +end + +def _reduce_666(val, _values, result) + diagnostic :error, :argument_cvar, nil, val[0] + + result +end + +# reduce 667 omitted + +def _reduce_668(val, _values, result) + @static_env.declare val[0][0] + + @max_numparam_stack.has_ordinary_params! + + result = val[0] + + result +end + +def _reduce_669(val, _values, result) + @current_arg_stack.set(val[0][0]) + result = val[0] + + result +end + +def _reduce_670(val, _values, result) + @current_arg_stack.set(0) + result = @builder.arg(val[0]) + + result +end + +def _reduce_671(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_672(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_673(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_674(val, _values, result) + check_kwarg_name(val[0]) + + @static_env.declare val[0][0] + + @max_numparam_stack.has_ordinary_params! + + @current_arg_stack.set(val[0][0]) + @context.in_argdef = false + + result = val[0] + + result +end + +def _reduce_675(val, _values, result) + @current_arg_stack.set(nil) + @context.in_argdef = true + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_676(val, _values, result) + @current_arg_stack.set(nil) + @context.in_argdef = true + result = @builder.kwarg(val[0]) + + result +end + +def _reduce_677(val, _values, result) + @context.in_argdef = true + result = @builder.kwoptarg(val[0], val[1]) + + result +end + +def _reduce_678(val, _values, result) + @context.in_argdef = true + result = @builder.kwarg(val[0]) + + result +end + +def _reduce_679(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_680(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_681(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_682(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 683 omitted + +# reduce 684 omitted + +def _reduce_685(val, _values, result) + result = [ @builder.kwnilarg(val[0][0], val[0][1]) ] + + result +end + +def _reduce_686(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.kwrestarg(val[0], val[1]) ] + + result +end + +def _reduce_687(val, _values, result) + @static_env.declare_anonymous_kwrestarg + + result = [ @builder.kwrestarg(val[0]) ] + + result +end + +def _reduce_688(val, _values, result) + @current_arg_stack.set(0) + @context.in_argdef = true + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_689(val, _values, result) + @current_arg_stack.set(0) + @context.in_argdef = true + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_690(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_691(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_692(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_693(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 694 omitted + +# reduce 695 omitted + +def _reduce_696(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_697(val, _values, result) + @static_env.declare_anonymous_restarg + + result = [ @builder.restarg(val[0]) ] + + result +end + +# reduce 698 omitted + +# reduce 699 omitted + +def _reduce_700(val, _values, result) + @static_env.declare val[1][0] + + result = @builder.blockarg(val[0], val[1]) + + result +end + +def _reduce_701(val, _values, result) + @static_env.declare_anonymous_blockarg + + result = @builder.blockarg(val[0], nil) + + result +end + +def _reduce_702(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_703(val, _values, result) + result = [] + + result +end + +# reduce 704 omitted + +def _reduce_705(val, _values, result) + result = val[1] + + result +end + +def _reduce_706(val, _values, result) + result = [] + + result +end + +# reduce 707 omitted + +def _reduce_708(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_709(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_710(val, _values, result) + result = @builder.pair(val[0], val[1], val[2]) + + result +end + +def _reduce_711(val, _values, result) + result = @builder.pair_keyword(val[0], val[1]) + + result +end + +def _reduce_712(val, _values, result) + result = @builder.pair_label(val[0]) + + result +end + +def _reduce_713(val, _values, result) + result = @builder.pair_quoted(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_714(val, _values, result) + result = @builder.kwsplat(val[0], val[1]) + + result +end + +def _reduce_715(val, _values, result) + if !@static_env.declared_anonymous_kwrestarg? + diagnostic :error, :no_anonymous_kwrestarg, nil, val[0] + end + + if @context.in_dynamic_block? && context.in_def && + @static_env.declared_anonymous_kwrestarg_in_current_scope? && @static_env.parent_has_anonymous_kwrestarg? + diagnostic :error, :ambiguous_anonymous_kwrestarg, nil, val[0] + end + + result = @builder.forwarded_kwrestarg(val[0]) + + result +end + +# reduce 716 omitted + +# reduce 717 omitted + +# reduce 718 omitted + +# reduce 719 omitted + +# reduce 720 omitted + +# reduce 721 omitted + +# reduce 722 omitted + +# reduce 723 omitted + +# reduce 724 omitted + +# reduce 725 omitted + +def _reduce_726(val, _values, result) + result = [:dot, val[0][1]] + + result +end + +def _reduce_727(val, _values, result) + result = [:anddot, val[0][1]] + + result +end + +# reduce 728 omitted + +# reduce 729 omitted + +# reduce 730 omitted + +# reduce 731 omitted + +def _reduce_732(val, _values, result) + result = val[1] + + result +end + +def _reduce_733(val, _values, result) + result = val[1] + + result +end + +def _reduce_734(val, _values, result) + result = val[1] + + result +end + +# reduce 735 omitted + +# reduce 736 omitted + +def _reduce_737(val, _values, result) + yyerrok + + result +end + +# reduce 738 omitted + +# reduce 739 omitted + +# reduce 740 omitted + +def _reduce_741(val, _values, result) + result = nil + + result +end + +def _reduce_none(val, _values, result) + val[0] +end + + end # class Ruby34 +end # module Parser diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/rubymotion.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/rubymotion.rb new file mode 100644 index 00000000..d3ef0264 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/rubymotion.rb @@ -0,0 +1,9515 @@ +# -*- encoding:utf-8; warn-indent:false; frozen_string_literal: true -*- +# +# DO NOT MODIFY!!!! +# This file is automatically generated by Racc 1.8.1 +# from Racc grammar file "rubymotion.y". +# + +require 'racc/parser.rb' + + +require_relative '../parser' + +module Parser + class RubyMotion < Parser::Base + + + def version + 19 # closest released match: v1_9_0_2 + end + + def default_encoding + Encoding::BINARY + end + + def local_push + @static_env.extend_static + @lexer.cmdarg.push(false) + @lexer.cond.push(false) + end + + def local_pop + @static_env.unextend + @lexer.cmdarg.pop + @lexer.cond.pop + end +##### State transition tables begin ### + +racc_action_table = [ + -453, 5, 68, 69, 65, 7, 51, -453, -453, -453, + 57, 58, -453, -453, -453, 61, -453, 59, 60, 62, + 23, 24, 66, 67, -453, 274, -453, -453, -453, 22, + 28, 27, 92, 91, 93, 94, -453, -453, 17, -453, + -453, -453, -453, -453, 6, 41, 8, 9, 96, 95, + 97, 86, 50, 88, 87, 89, 530, 90, 98, 99, + 509, 84, 85, 38, 39, 37, -453, -453, -453, -453, + -453, -453, -453, -453, -453, -453, -453, -453, -453, -453, + 100, 452, -453, -453, -453, 36, -453, -453, 30, -86, + -453, 52, 53, -453, -453, 54, -453, 32, -453, 551, + -453, 40, -453, -453, -453, -453, -453, -453, -453, 18, + -453, 273, -453, -93, 83, 75, 78, 79, 195, 80, + 81, 540, -92, 731, 76, 82, -453, -453, -453, -453, + -456, -453, 56, -453, 77, -453, -453, -456, -456, -456, + -466, 196, -456, -456, -456, 661, -456, 197, 509, 661, + 209, 206, 207, 203, -456, 509, -456, -456, -456, 104, + 267, 529, 550, 751, 103, -88, -456, -456, -90, -456, + -456, -456, -456, -456, 104, 509, -86, -93, 509, 103, + -87, 104, 542, 541, -92, -88, 103, 210, 521, 198, + -86, 693, 522, 417, -78, -89, -456, -456, -456, -456, + -456, -456, -456, -456, -456, -456, -456, -456, -456, -456, + 104, 204, -456, -456, -456, 103, -456, -456, -85, -90, + -456, -87, -80, -456, -456, 199, -456, -84, -456, 625, + -456, 515, -456, -456, -456, -456, -456, -456, -456, -531, + -456, 210, -456, -93, -453, 104, -531, -531, -531, 104, + 103, -453, -531, -531, 103, -531, -456, -456, -456, -456, + -527, -456, 104, -456, -531, -456, -456, 103, 750, 104, + -80, -91, 779, -82, 103, -531, -531, 661, -531, -531, + -531, -531, -531, -89, 499, -79, -91, 498, -80, 104, + -86, -93, 104, 248, 103, -86, -93, 103, -92, -88, + -81, -82, -453, -92, -88, -531, -531, -531, -531, -531, + -531, -531, -531, -531, -531, -531, -531, -531, -531, 206, + 207, -531, -531, -531, -80, 568, 298, -80, 486, -531, + 760, 540, -531, -90, -80, -87, -528, -531, -90, -531, + -87, -531, -531, -531, -531, -531, -531, -531, -279, -531, + -531, -531, 206, 207, 712, -279, -279, -279, 713, 299, + -527, -279, -279, -528, -279, -531, -531, -82, -81, 210, + -531, 206, 207, 274, -531, -89, -83, 104, -92, 761, + 274, -524, 103, 364, -279, -279, 205, -279, -279, -279, + -279, -279, 542, 541, 538, 499, 499, -89, 501, 501, + -91, 540, -89, -82, -88, -91, -82, 540, -90, 210, + 206, 207, 376, -82, -279, -279, -279, -279, -279, -279, + -279, -279, -279, -279, -279, -279, -279, -279, -466, -85, + -279, -279, -279, -453, 571, 416, -93, 269, -279, 418, + -453, -279, 104, -525, 269, -524, -279, 103, -279, -453, + -279, -279, -279, -279, -279, -279, -279, 540, -279, 273, + -279, 210, 542, 541, 543, 540, 273, -524, 542, 541, + 545, -78, 583, -531, -279, -279, 760, -83, -86, -279, + -531, -531, -531, -279, -91, -531, -531, -531, 796, -531, + -73, -453, 300, 301, 419, -456, -456, -59, -531, -531, + -531, -531, -456, -456, 209, 499, 582, -525, 501, -531, + -531, -456, -531, -531, -531, -531, -531, 448, 542, 541, + 547, -81, -79, 450, -463, 810, 542, 541, 552, -525, + 583, -463, 104, 452, 583, 481, 482, 103, -87, -531, + -531, -531, -531, -531, -531, -531, -531, -531, -531, -531, + -531, -531, -531, -456, -456, -531, -531, -531, 459, 714, + -531, -58, 583, -531, 582, 210, -531, -531, 582, -531, + 486, -531, 471, -531, 472, -531, -531, -531, -531, -531, + -531, -531, -463, -531, -531, -531, -527, -81, -79, 768, + -462, 641, 640, 639, 645, 642, 582, -462, 203, -531, + -531, -531, -531, -279, -531, 202, -531, 479, -531, -89, + -279, -279, -279, -84, 200, -279, -279, -279, 278, -279, + -92, 206, 207, -81, -79, -323, -81, -79, 229, -279, + -279, -279, -323, -81, -79, 206, 207, 774, 625, -279, + -279, -323, -279, -279, -279, -279, -279, 768, -462, 641, + 640, 639, 645, 642, -464, 210, 204, 373, 269, -461, + 226, -464, 375, 374, 228, 227, -461, 843, 483, -279, + -279, -279, -279, -279, -279, -279, -279, -279, -279, -279, + -279, -279, -279, -323, 487, -279, -279, -279, 488, 571, + -279, 774, 625, -279, 229, 75, -279, -279, 494, -279, + 563, -279, 495, -279, 76, -279, -279, -279, -279, -279, + -279, -279, -464, -279, 77, -279, 724, -461, 641, 640, + 639, 645, 642, 502, 503, 931, 452, 515, 203, -279, + -279, -279, -279, -396, -279, 414, -279, 564, -279, -91, + -396, -396, -396, -80, 415, -396, -396, -396, 366, -396, + -88, 104, 519, 647, 520, 555, 103, 229, -396, -396, + -396, -465, 651, 650, 654, 653, -531, 556, -465, -396, + -396, 559, -396, -396, -396, -396, -396, -465, -259, 808, + -82, 641, 640, 639, -458, 642, 204, -90, -459, 226, + -460, -458, 210, 228, 227, -459, 723, -460, 269, -396, + -396, -396, -396, -396, -396, -396, -396, -396, -396, -396, + -396, -396, -396, 573, 229, -396, -396, -396, -531, -465, + -396, 203, 269, -396, 229, -531, -396, -396, 536, -396, + -527, -396, 701, -396, -531, -396, -396, -396, -396, -396, + -396, -396, -458, -396, -396, -396, -459, 203, -460, 229, + 104, 229, -531, 210, 478, 103, 210, 210, -286, -396, + -396, -73, -396, 476, -396, -286, -286, -286, -396, 607, + -286, -286, -286, 210, -286, -79, -531, 492, 618, 204, + -273, 625, -87, 210, -286, -286, 203, -273, 106, 107, + 108, 109, 110, 490, -286, -286, -273, -286, -286, -286, + -286, -286, 415, 657, 808, 204, 641, 640, 639, 768, + 642, 641, 640, 639, 645, 642, 768, 515, 641, 640, + 639, 645, 642, 664, -286, -286, -286, -286, -286, -286, + -286, -286, -286, -286, -286, -286, -286, -286, -273, 692, + -286, -286, -286, 203, 204, -286, 764, 278, -286, 695, + 518, -286, -286, 764, -286, 767, -286, -260, -286, 516, + -286, -286, -286, -286, -286, -286, -286, 702, -286, 459, + -286, 768, 203, 641, 640, 639, 645, 642, 459, 524, + 210, 716, 728, -274, -286, -286, 452, -286, 526, -286, + -274, -274, -274, -286, 450, -274, -274, -274, 210, -274, + 618, 204, 210, 269, 269, -280, 618, 229, 764, -274, + -274, -274, -280, 229, 229, 742, -259, 767, 746, -274, + -274, -280, -274, -274, -274, -274, -274, 723, 754, 756, + 204, 759, 768, 762, 641, 640, 639, 645, 642, 226, + 770, 771, 625, 228, 227, 224, 225, 778, 210, -274, + -274, -274, -274, -274, -274, -274, -274, -274, -274, -274, + -274, -274, -274, -280, 210, -274, -274, -274, 787, 764, + -274, -261, 798, -274, 800, 803, -274, -274, 894, -274, + 804, -274, 723, -274, 811, -274, -274, -274, -274, -274, + -274, -274, 210, -274, 818, -274, 819, 618, 723, -280, + 838, 203, 841, 760, 210, 845, -280, 847, 878, -274, + -274, -274, -274, -232, -274, -280, -274, 876, -274, 853, + -232, -232, -232, 855, 210, -232, -232, -232, 644, -232, + 641, 640, 639, 645, 642, -279, 858, -262, -232, -232, + -232, 865, -279, 866, 870, 871, 873, -528, 450, -232, + -232, -279, -232, -232, -232, -232, -232, -280, 879, 204, + 106, 107, 108, 109, 110, 647, 633, 768, 210, 641, + 640, 639, 645, 642, 651, 650, 654, 653, 883, -232, + -232, -232, -232, -232, -232, -232, -232, -232, -232, -232, + -232, -232, -232, -279, 229, -232, -232, -232, -279, 886, + -232, 888, 269, -232, 764, -279, -232, -232, 890, -232, + -528, -232, 890, -232, -279, -232, -232, -232, -232, -232, + -232, -232, 210, -232, -232, -232, 226, 203, 895, 898, + 228, 227, 224, 225, 915, 899, 904, 906, -532, -232, + -232, 909, -232, 526, -232, -532, -532, -532, -232, 911, + -532, -532, -532, 890, -532, 229, -279, 106, 107, 108, + 109, 110, 890, -532, -532, -532, -532, 916, 494, 924, + 925, 243, 244, 933, -532, -532, 450, -532, -532, -532, + -532, -532, 210, 946, 890, 204, 890, 226, 890, 232, + 950, 228, 227, 224, 225, 933, 953, 230, 954, 231, + 956, 890, 890, 890, -532, -532, -532, -532, -532, -532, + -532, -532, -532, -532, -532, -532, -532, -532, -528, -527, + -532, -532, -532, 933, 890, -532, 933, 890, -532, nil, + nil, -532, -532, nil, -532, nil, -532, nil, -532, nil, + -532, -532, -532, -532, -532, -532, -532, nil, -532, -532, + -532, 644, nil, 641, 640, 639, 645, 642, nil, nil, + nil, nil, nil, nil, -532, -532, -532, -532, -533, -532, + nil, -532, nil, -532, nil, -533, -533, -533, nil, nil, + -533, -533, -533, nil, -533, 229, 687, 688, 647, 682, + 689, 98, 99, -533, -533, -533, -533, 651, 650, 654, + 653, 243, 244, nil, -533, -533, nil, -533, -533, -533, + -533, -533, nil, nil, nil, nil, nil, 226, nil, 232, + nil, 228, 227, 224, 225, nil, nil, 230, nil, 231, + nil, nil, nil, nil, -533, -533, -533, -533, -533, -533, + -533, -533, -533, -533, -533, -533, -533, -533, nil, nil, + -533, -533, -533, nil, nil, -533, nil, nil, -533, nil, + nil, -533, -533, nil, -533, nil, -533, nil, -533, nil, + -533, -533, -533, -533, -533, -533, -533, nil, -533, -533, + -533, 644, nil, 641, 640, 639, 645, 642, nil, nil, + nil, nil, nil, nil, -533, -533, -533, -533, -232, -533, + nil, -533, nil, -533, nil, -232, -232, -232, nil, nil, + -232, -232, -232, nil, -232, nil, nil, 768, 647, 641, + 640, 639, 645, 642, -232, nil, nil, 651, 650, 654, + 653, nil, nil, nil, -232, -232, nil, -232, -232, -232, + -232, -232, nil, 768, nil, 641, 640, 639, 645, 642, + nil, nil, nil, -232, 764, nil, nil, nil, nil, nil, + -232, -232, -232, nil, nil, -232, -232, -232, 644, -232, + 641, 640, 639, 645, 642, -232, nil, nil, nil, -232, + 764, nil, -232, nil, nil, nil, nil, 269, -232, -232, + -232, nil, -232, -232, -232, -232, -232, nil, 644, nil, + 641, 640, 639, 645, 642, 647, nil, nil, nil, nil, + -232, nil, nil, nil, 651, 650, 654, 653, nil, nil, + nil, nil, nil, 229, -232, nil, nil, nil, nil, -232, + -232, nil, nil, -232, nil, 647, nil, -232, nil, 243, + 244, nil, 269, -232, 651, 650, 654, 653, 768, nil, + 641, 640, 639, 645, 642, 226, nil, 232, nil, 228, + 227, 224, 225, nil, nil, -232, nil, nil, nil, nil, + nil, nil, nil, 5, 68, 69, 65, 7, 51, -232, + nil, nil, 57, 58, -232, 647, nil, 61, -232, 59, + 60, 62, 23, 24, 66, 67, 654, 653, nil, nil, + nil, 22, 28, 27, 92, 91, 93, 94, nil, 768, + 17, 641, 640, 639, 645, 642, 6, 41, 8, 9, + 96, 95, 97, 86, 50, 88, 87, 89, nil, 90, + 98, 99, nil, 84, 85, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, 768, 764, 641, 640, 639, + 645, 642, nil, nil, nil, nil, nil, 36, nil, nil, + 280, nil, nil, 52, 53, nil, nil, 54, nil, 32, + nil, nil, nil, 40, 768, nil, 641, 640, 639, 645, + 642, 18, 647, nil, nil, nil, 83, 75, 78, 79, + nil, 80, 81, 654, 653, nil, 76, 82, 5, 68, + 69, 65, 7, 51, 56, nil, 77, 57, 58, nil, + nil, 647, 61, nil, 59, 60, 62, 23, 24, 66, + 67, nil, 654, 653, nil, nil, 22, 28, 27, 92, + 91, 93, 94, nil, nil, 17, nil, nil, nil, nil, + nil, 6, 41, 8, 9, 96, 95, 97, 86, 50, + 88, 87, 89, nil, 90, 98, 99, nil, 84, 85, + 38, 39, 37, nil, nil, nil, nil, nil, nil, nil, + 768, nil, 641, 640, 639, 645, 642, nil, nil, nil, + nil, nil, 36, nil, nil, 30, nil, nil, 52, 53, + nil, nil, 54, nil, 32, nil, nil, nil, 40, 768, + nil, 641, 640, 639, 645, 642, 18, 647, nil, nil, + nil, 83, 75, 78, 79, nil, 80, 81, 654, 653, + nil, 76, 82, 5, 68, 69, 65, 7, 51, 56, + nil, 77, 57, 58, nil, nil, 647, 61, nil, 59, + 60, 62, 23, 24, 66, 67, nil, 654, 653, nil, + nil, 22, 28, 27, 92, 91, 93, 94, nil, nil, + 17, nil, nil, nil, nil, nil, 6, 41, 8, 9, + 96, 95, 97, 86, 50, 88, 87, 89, nil, 90, + 98, 99, nil, 84, 85, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, 768, nil, 641, 640, 639, + 645, 642, nil, nil, nil, nil, nil, 36, nil, nil, + 30, nil, nil, 52, 53, nil, nil, 54, nil, 32, + nil, nil, nil, 40, 768, nil, 641, 640, 639, 645, + 642, 18, 647, nil, nil, nil, 83, 75, 78, 79, + nil, 80, 81, 654, 653, nil, 76, 82, 5, 68, + 69, 65, 7, 51, 56, nil, 77, 57, 58, nil, + nil, 647, 61, nil, 59, 60, 62, 23, 24, 66, + 67, nil, 654, 653, nil, nil, 22, 28, 27, 92, + 91, 93, 94, nil, nil, 17, nil, nil, nil, nil, + nil, 6, 41, 8, 9, 96, 95, 97, 86, 50, + 88, 87, 89, nil, 90, 98, 99, nil, 84, 85, + 38, 39, 37, nil, nil, nil, nil, nil, nil, nil, + 768, nil, 641, 640, 639, 645, 642, nil, nil, nil, + nil, nil, 36, nil, nil, 30, nil, nil, 52, 53, + nil, nil, 54, nil, 32, nil, nil, nil, 40, 768, + nil, 641, 640, 639, 645, 642, 18, 647, nil, nil, + nil, 83, 75, 78, 79, nil, 80, 81, 654, 653, + nil, 76, 82, 5, 68, 69, 65, 7, 51, 56, + nil, 77, 57, 58, nil, nil, 647, 61, nil, 59, + 60, 62, 23, 24, 66, 67, nil, 654, 653, nil, + nil, 22, 28, 27, 92, 91, 93, 94, nil, nil, + 17, nil, nil, nil, nil, nil, 6, 41, 8, 9, + 96, 95, 97, 86, 50, 88, 87, 89, nil, 90, + 98, 99, nil, 84, 85, 38, 39, 37, 229, 233, + 238, 239, 240, 235, 237, 245, 246, 241, 242, nil, + -552, -552, nil, nil, 243, 244, nil, 36, nil, nil, + 30, nil, nil, 52, 53, nil, nil, 54, nil, 32, + 226, nil, 232, 40, 228, 227, 224, 225, 236, 234, + 230, 18, 231, nil, nil, nil, 83, 75, 78, 79, + nil, 80, 81, nil, nil, nil, 76, 82, 5, 68, + 69, 65, 7, 51, 56, nil, 77, 57, 58, nil, + nil, nil, 61, nil, 59, 60, 62, 23, 24, 66, + 67, nil, nil, nil, nil, nil, 22, 28, 27, 92, + 91, 93, 94, nil, nil, 17, nil, nil, nil, nil, + nil, 6, 41, 8, 9, 96, 95, 97, 86, 50, + 88, 87, 89, nil, 90, 98, 99, nil, 84, 85, + 38, 39, 37, 229, 233, 238, 239, 240, 235, 237, + 245, 246, 241, 242, nil, -552, -552, nil, nil, 243, + 244, nil, 36, nil, nil, 280, nil, nil, 52, 53, + nil, nil, 54, nil, 32, 226, nil, 232, 40, 228, + 227, 224, 225, 236, 234, 230, 18, 231, nil, nil, + nil, 83, 75, 78, 79, nil, 80, 81, nil, nil, + nil, 76, 82, 5, 68, 69, 65, 7, 51, 56, + nil, 77, 57, 58, nil, nil, nil, 61, nil, 59, + 60, 62, 23, 24, 66, 67, nil, nil, nil, nil, + nil, 22, 28, 27, 92, 91, 93, 94, nil, nil, + 17, nil, nil, nil, nil, nil, 6, 41, 8, 9, + 96, 95, 97, 86, 50, 88, 87, 89, nil, 90, + 98, 99, nil, 84, 85, 38, 39, 37, 229, -552, + -552, -552, -552, 235, 237, nil, nil, -552, -552, nil, + nil, nil, nil, nil, 243, 244, nil, 36, nil, nil, + 280, nil, nil, 52, 53, nil, nil, 54, nil, 32, + 226, nil, 232, 40, 228, 227, 224, 225, 236, 234, + 230, 18, 231, nil, nil, nil, 83, 75, 78, 79, + nil, 80, 81, nil, nil, nil, 76, 82, 5, 68, + 69, 65, 7, 51, 56, nil, 77, 57, 58, nil, + nil, nil, 61, nil, 59, 60, 62, 23, 24, 66, + 67, nil, nil, nil, nil, nil, 22, 28, 27, 92, + 91, 93, 94, nil, nil, 17, nil, nil, nil, nil, + nil, 6, 41, 8, 9, 96, 95, 97, 86, 50, + 88, 87, 89, nil, 90, 98, 99, nil, 84, 85, + 38, 39, 37, 229, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 243, + 244, nil, 36, nil, nil, 30, nil, nil, 52, 53, + nil, nil, 54, nil, 32, 226, nil, 232, 40, 228, + 227, 224, 225, nil, nil, 230, 18, 231, nil, nil, + nil, 83, 75, 78, 79, nil, 80, 81, nil, nil, + nil, 76, 82, 5, 68, 69, 65, 7, 51, 56, + nil, 77, 57, 58, nil, nil, nil, 61, nil, 59, + 60, 62, 23, 24, 66, 67, nil, nil, nil, nil, + nil, 22, 28, 27, 92, 91, 93, 94, nil, nil, + 17, nil, nil, nil, nil, nil, 6, 41, 8, 9, + 96, 95, 97, 86, 50, 88, 87, 89, nil, 90, + 98, 99, nil, 84, 85, 38, 39, 37, 229, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 243, 244, nil, 36, nil, nil, + 30, nil, nil, 52, 53, nil, nil, 54, nil, 32, + 226, nil, 232, 40, 228, 227, 224, 225, nil, nil, + 230, 18, 231, nil, nil, nil, 83, 75, 78, 79, + nil, 80, 81, nil, nil, nil, 76, 82, 5, 68, + 69, 65, 7, 51, 56, nil, 77, 57, 58, nil, + nil, nil, 61, nil, 59, 60, 62, 23, 24, 66, + 67, nil, nil, nil, nil, nil, 22, 28, 27, 92, + 91, 93, 94, nil, nil, 17, nil, nil, nil, nil, + nil, 6, 41, 8, 9, 96, 95, 97, 86, 50, + 88, 87, 89, nil, 90, 98, 99, nil, 84, 85, + 38, 39, 37, 229, -552, -552, -552, -552, 235, 237, + nil, nil, -552, -552, nil, nil, nil, nil, nil, 243, + 244, nil, 36, nil, nil, 30, nil, nil, 52, 53, + nil, nil, 54, nil, 32, 226, nil, 232, 40, 228, + 227, 224, 225, 236, 234, 230, 18, 231, nil, nil, + nil, 83, 75, 78, 79, nil, 80, 81, nil, nil, + nil, 76, 82, 5, 68, 69, 65, 7, 51, 56, + nil, 77, 57, 58, nil, nil, nil, 61, nil, 59, + 60, 62, 23, 24, 66, 67, nil, nil, nil, nil, + nil, 22, 28, 27, 92, 91, 93, 94, nil, nil, + 17, nil, nil, nil, nil, nil, 6, 41, 8, 9, + 96, 95, 97, 86, 50, 88, 87, 89, nil, 90, + 98, 99, nil, 84, 85, 38, 39, 37, 229, -552, + -552, -552, -552, 235, 237, nil, nil, -552, -552, nil, + nil, nil, nil, nil, 243, 244, nil, 36, nil, nil, + 30, nil, nil, 52, 53, nil, nil, 54, nil, 32, + 226, nil, 232, 40, 228, 227, 224, 225, 236, 234, + 230, 18, 231, nil, nil, nil, 83, 75, 78, 79, + nil, 80, 81, nil, nil, nil, 76, 82, 5, 68, + 69, 65, 7, 51, 56, nil, 77, 57, 58, nil, + nil, nil, 61, nil, 59, 60, 62, 23, 24, 66, + 67, nil, nil, nil, nil, nil, 22, 28, 27, 92, + 91, 93, 94, nil, nil, 17, nil, nil, nil, nil, + nil, 6, 41, 8, 9, 96, 95, 97, 86, 50, + 88, 87, 89, nil, 90, 98, 99, nil, 84, 85, + 38, 39, 37, 229, -552, -552, -552, -552, 235, 237, + nil, nil, -552, -552, nil, nil, nil, nil, nil, 243, + 244, nil, 36, nil, nil, 30, nil, nil, 52, 53, + nil, nil, 54, nil, 32, 226, nil, 232, 40, 228, + 227, 224, 225, 236, 234, 230, 18, 231, nil, nil, + nil, 83, 75, 78, 79, nil, 80, 81, nil, nil, + nil, 76, 82, 5, 68, 69, 65, 7, 51, 56, + nil, 77, 57, 58, nil, nil, nil, 61, nil, 59, + 60, 62, 23, 24, 66, 67, nil, nil, nil, nil, + nil, 22, 28, 27, 92, 91, 93, 94, nil, nil, + 17, nil, nil, nil, nil, nil, 6, 41, 8, 9, + 96, 95, 97, 86, 50, 88, 87, 89, nil, 90, + 98, 99, nil, 84, 85, 38, 39, 37, 229, -552, + -552, -552, -552, 235, 237, nil, nil, -552, -552, nil, + nil, nil, nil, nil, 243, 244, nil, 36, nil, nil, + 30, nil, nil, 52, 53, nil, nil, 54, nil, 32, + 226, nil, 232, 40, 228, 227, 224, 225, 236, 234, + 230, 18, 231, nil, nil, nil, 83, 75, 78, 79, + nil, 80, 81, nil, nil, nil, 76, 82, 5, 68, + 69, 65, 7, 51, 56, nil, 77, 57, 58, nil, + nil, nil, 61, nil, 59, 60, 62, 23, 24, 66, + 67, nil, nil, nil, nil, nil, 22, 28, 27, 92, + 91, 93, 94, nil, nil, 17, nil, nil, nil, nil, + nil, 6, 41, 8, 9, 96, 95, 97, 86, 50, + 88, 87, 89, nil, 90, 98, 99, nil, 84, 85, + 38, 39, 37, 229, -552, -552, -552, -552, 235, 237, + nil, nil, -552, -552, nil, nil, nil, nil, nil, 243, + 244, nil, 36, nil, nil, 30, nil, nil, 52, 53, + nil, nil, 54, nil, 32, 226, nil, 232, 40, 228, + 227, 224, 225, 236, 234, 230, 18, 231, nil, nil, + nil, 83, 75, 78, 79, nil, 80, 81, nil, nil, + nil, 76, 82, 5, 68, 69, 65, 7, 51, 56, + nil, 77, 57, 58, nil, nil, nil, 61, nil, 59, + 60, 62, 23, 24, 66, 67, nil, nil, nil, nil, + nil, 22, 28, 27, 92, 91, 93, 94, nil, nil, + 17, nil, nil, nil, nil, nil, 6, 41, 8, 9, + 96, 95, 97, 86, 50, 88, 87, 89, nil, 90, + 98, 99, nil, 84, 85, 38, 39, 37, 229, 233, + 238, 239, 240, 235, 237, nil, nil, 241, 242, nil, + nil, nil, nil, nil, 243, 244, nil, 36, nil, nil, + 30, nil, nil, 52, 53, nil, nil, 54, nil, 32, + 226, nil, 232, 40, 228, 227, 224, 225, 236, 234, + 230, 18, 231, nil, nil, nil, 83, 75, 78, 79, + nil, 80, 81, nil, nil, nil, 76, 82, 5, 68, + 69, 65, 7, 51, 56, nil, 77, 57, 58, nil, + nil, nil, 61, nil, 59, 60, 62, 23, 24, 66, + 67, nil, nil, nil, nil, nil, 22, 28, 27, 92, + 91, 93, 94, nil, nil, 17, nil, nil, nil, nil, + nil, 6, 41, 8, 9, 96, 95, 97, 86, 50, + 88, 87, 89, nil, 90, 98, 99, nil, 84, 85, + 38, 39, 37, 229, 233, 238, 239, 240, 235, 237, + 245, nil, 241, 242, nil, nil, nil, nil, nil, 243, + 244, nil, 36, nil, nil, 30, nil, nil, 52, 53, + nil, nil, 54, nil, 32, 226, nil, 232, 40, 228, + 227, 224, 225, 236, 234, 230, 18, 231, nil, nil, + nil, 83, 75, 78, 79, nil, 80, 81, nil, nil, + nil, 76, 82, 5, 68, 69, 65, 7, 51, 56, + nil, 77, 57, 58, nil, nil, nil, 61, nil, 59, + 60, 62, 23, 24, 66, 67, nil, nil, nil, nil, + nil, 22, 28, 27, 92, 91, 93, 94, nil, nil, + 17, nil, nil, nil, nil, nil, 6, 41, 8, 9, + 96, 95, 97, 86, 50, 88, 87, 89, nil, 90, + 98, 99, nil, 84, 85, 38, 39, 37, 229, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 243, 244, nil, 36, nil, nil, + 30, nil, nil, 52, 53, nil, nil, 54, nil, 32, + 226, nil, 232, 40, 228, 227, 224, 225, nil, nil, + nil, 18, nil, nil, nil, nil, 83, 75, 78, 79, + nil, 80, 81, nil, nil, nil, 76, 82, 5, 68, + 69, 65, 7, 51, 56, nil, 77, 57, 58, nil, + nil, nil, 61, nil, 59, 60, 62, 23, 24, 66, + 67, nil, nil, nil, nil, nil, 22, 28, 27, 92, + 91, 93, 94, nil, nil, 17, nil, nil, nil, nil, + nil, 6, 41, 8, 9, 96, 95, 97, 86, 50, + 88, 87, 89, nil, 90, 98, 99, nil, 84, 85, + 38, 39, 37, 229, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 243, + 244, nil, 36, nil, nil, 30, nil, nil, 52, 53, + nil, nil, 54, nil, 32, 226, nil, nil, 40, 228, + 227, 224, 225, nil, nil, nil, 18, nil, nil, nil, + nil, 83, 75, 78, 79, nil, 80, 81, nil, nil, + nil, 76, 82, 5, 68, 69, 65, 7, 51, 56, + nil, 77, 57, 58, nil, nil, nil, 61, nil, 59, + 60, 62, 23, 24, 66, 67, nil, nil, nil, nil, + nil, 22, 28, 27, 92, 91, 93, 94, nil, nil, + 17, nil, nil, nil, nil, nil, 6, 41, 8, 9, + 96, 95, 97, 86, 50, 88, 87, 89, nil, 90, + 98, 99, nil, 84, 85, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 36, nil, nil, + 30, nil, nil, 52, 53, nil, nil, 54, nil, 32, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 18, nil, nil, nil, nil, 83, 75, 78, 79, + nil, 80, 81, nil, nil, nil, 76, 82, 5, 68, + 69, 65, 7, 51, 56, nil, 77, 57, 58, nil, + nil, nil, 61, nil, 59, 60, 62, 23, 24, 66, + 67, nil, nil, nil, nil, nil, 22, 28, 27, 92, + 91, 93, 94, nil, nil, 17, nil, nil, nil, nil, + nil, 6, 41, 8, 9, 96, 95, 97, 86, 50, + 88, 87, 89, nil, 90, 98, 99, nil, 84, 85, + 38, 39, 37, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 36, nil, nil, 30, nil, nil, 52, 53, + nil, nil, 54, nil, 32, nil, nil, nil, 40, nil, + nil, nil, nil, nil, nil, nil, 18, nil, nil, nil, + nil, 83, 75, 78, 79, nil, 80, 81, nil, nil, + nil, 76, 82, 5, 68, 69, 65, 7, 51, 56, + nil, 77, 57, 58, nil, nil, nil, 61, nil, 59, + 60, 62, 23, 24, 66, 67, nil, nil, nil, nil, + nil, 22, 28, 27, 92, 91, 93, 94, nil, nil, + 17, nil, nil, nil, nil, nil, 6, 41, 8, 9, + 96, 95, 97, 86, 50, 88, 87, 89, nil, 90, + 98, 99, nil, 84, 85, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 36, nil, nil, + 30, nil, nil, 52, 53, nil, nil, 54, nil, 32, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 18, nil, nil, nil, nil, 83, 75, 78, 79, + nil, 80, 81, nil, nil, nil, 76, 82, 5, 68, + 69, 65, 7, 51, 56, nil, 77, 57, 58, nil, + nil, nil, 61, nil, 59, 60, 62, 23, 24, 66, + 67, nil, nil, nil, nil, nil, 22, 28, 27, 92, + 91, 93, 94, nil, nil, 17, nil, nil, nil, nil, + nil, 6, 41, 8, 9, 96, 95, 97, 86, 50, + 88, 87, 89, nil, 90, 98, 99, nil, 84, 85, + 38, 39, 37, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 36, nil, nil, 30, nil, nil, 52, 53, + nil, nil, 54, nil, 32, nil, nil, nil, 40, nil, + nil, nil, nil, nil, nil, nil, 18, nil, nil, nil, + nil, 83, 75, 78, 79, nil, 80, 81, nil, nil, + nil, 76, 82, 5, 68, 69, 65, 7, 51, 56, + nil, 77, 57, 58, nil, nil, nil, 61, nil, 59, + 60, 62, 23, 24, 66, 67, nil, nil, nil, nil, + nil, 22, 28, 27, 92, 91, 93, 94, nil, nil, + 17, nil, nil, nil, nil, nil, 6, 41, 8, 9, + 96, 95, 97, 86, 50, 88, 87, 89, nil, 90, + 98, 99, nil, 84, 85, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 36, nil, nil, + 30, nil, nil, 52, 53, nil, nil, 54, nil, 32, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 18, nil, nil, nil, nil, 83, 75, 78, 79, + nil, 80, 81, nil, nil, nil, 76, 82, 5, 68, + 69, 65, 7, 51, 56, nil, 77, 57, 58, nil, + nil, nil, 61, nil, 59, 60, 62, 23, 24, 66, + 67, nil, nil, nil, nil, nil, 22, 28, 27, 92, + 91, 93, 94, nil, nil, 17, nil, nil, nil, nil, + nil, 6, 41, 8, 9, 96, 95, 97, 86, 50, + 88, 87, 89, nil, 90, 98, 99, nil, 84, 85, + 38, 39, 37, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 36, nil, nil, 30, nil, nil, 52, 53, + nil, nil, 54, nil, 32, nil, nil, nil, 40, nil, + nil, nil, nil, nil, nil, nil, 18, nil, nil, nil, + nil, 83, 75, 78, 79, nil, 80, 81, nil, nil, + nil, 76, 82, 5, 68, 69, 65, 7, 51, 56, + nil, 77, 57, 58, nil, nil, nil, 61, nil, 59, + 60, 62, 23, 24, 66, 67, nil, nil, nil, nil, + nil, 22, 28, 27, 92, 91, 93, 94, nil, nil, + 17, nil, nil, nil, nil, nil, 6, 41, 8, 9, + 96, 95, 97, 86, 50, 88, 87, 89, nil, 90, + 98, 99, nil, 84, 85, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 36, nil, nil, + 30, nil, nil, 52, 53, nil, nil, 54, nil, 32, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 18, nil, nil, nil, nil, 83, 75, 78, 79, + nil, 80, 81, nil, nil, nil, 76, 82, 5, 68, + 69, 65, 7, 51, 56, nil, 77, 57, 58, nil, + nil, nil, 61, nil, 59, 60, 62, 23, 24, 66, + 67, nil, nil, nil, nil, nil, 22, 28, 27, 92, + 91, 93, 94, nil, nil, 17, nil, nil, nil, nil, + nil, 6, 41, 8, 9, 96, 95, 97, 86, 50, + 88, 87, 89, nil, 90, 98, 99, nil, 84, 85, + 38, 39, 37, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 36, nil, nil, 30, nil, nil, 52, 53, + nil, nil, 54, nil, 32, nil, nil, nil, 40, nil, + nil, nil, nil, nil, nil, nil, 18, nil, nil, nil, + nil, 83, 75, 78, 79, nil, 80, 81, nil, nil, + nil, 76, 82, 5, 68, 69, 65, 7, 51, 56, + nil, 77, 57, 58, nil, nil, nil, 61, nil, 59, + 60, 62, 23, 24, 66, 67, nil, nil, nil, nil, + nil, 22, 28, 27, 92, 91, 93, 94, nil, nil, + 17, nil, nil, nil, nil, nil, 6, 41, 8, 9, + 96, 95, 97, 86, 50, 88, 87, 89, nil, 90, + 98, 99, nil, 84, 85, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 36, nil, nil, + 30, nil, nil, 52, 53, nil, nil, 54, nil, 32, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 18, nil, nil, nil, nil, 83, 75, 78, 79, + nil, 80, 81, nil, nil, nil, 76, 82, 5, 68, + 69, 65, 7, 51, 56, nil, 77, 57, 58, nil, + nil, nil, 61, nil, 59, 60, 62, 23, 24, 66, + 67, nil, nil, nil, nil, nil, 22, 28, 27, 92, + 91, 93, 94, nil, nil, 17, nil, nil, nil, nil, + nil, 6, 41, 8, 9, 96, 95, 97, 86, 50, + 88, 87, 89, nil, 90, 98, 99, nil, 84, 85, + 38, 39, 37, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 36, nil, nil, 30, nil, nil, 52, 53, + nil, nil, 54, nil, 32, nil, nil, nil, 40, nil, + nil, nil, nil, nil, nil, nil, 18, nil, nil, nil, + nil, 83, 75, 78, 79, nil, 80, 81, nil, nil, + nil, 76, 82, 5, 68, 69, 65, 7, 51, 56, + nil, 77, 57, 58, nil, nil, nil, 61, nil, 59, + 60, 62, 23, 24, 66, 67, nil, nil, nil, nil, + nil, 22, 28, 27, 92, 91, 93, 94, nil, nil, + 17, nil, nil, nil, nil, nil, 6, 41, 8, 9, + 96, 95, 97, 86, 50, 88, 87, 89, nil, 90, + 98, 99, nil, 84, 85, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 36, nil, nil, + 30, nil, nil, 52, 53, nil, nil, 54, nil, 32, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 18, nil, nil, nil, nil, 83, 75, 78, 79, + nil, 80, 81, nil, nil, nil, 76, 82, nil, 68, + 69, 65, 7, 51, 56, nil, 77, 57, 58, nil, + nil, nil, 61, nil, 59, 60, 62, 23, 24, 66, + 67, nil, nil, nil, nil, nil, 22, 28, 27, 92, + 91, 93, 94, nil, nil, 17, nil, nil, nil, nil, + nil, 6, 41, 8, 9, 96, 95, 97, 86, 50, + 88, 87, 89, nil, 90, 98, 99, nil, 84, 85, + 38, 39, 37, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 36, nil, nil, 30, nil, nil, 52, 53, + nil, nil, 54, nil, 32, nil, nil, nil, 40, nil, + nil, nil, nil, nil, nil, nil, 18, nil, nil, nil, + nil, 83, 75, 78, 79, nil, 80, 81, nil, nil, + nil, 76, 82, nil, 68, 69, 65, nil, 51, 56, + nil, 77, 57, 58, nil, nil, nil, 61, nil, 59, + 60, 62, 23, 24, 66, 67, nil, nil, nil, nil, + nil, 22, 28, 27, 92, 91, 93, 94, nil, nil, + 221, nil, nil, nil, nil, nil, nil, 41, nil, nil, + 96, 95, 97, 86, 50, 88, 87, 89, nil, 90, + 98, 99, nil, 84, 85, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 214, nil, nil, + 220, nil, nil, 52, 53, nil, nil, 54, nil, nil, + nil, nil, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 219, nil, nil, nil, nil, 83, 75, 78, 79, + nil, 80, 81, nil, nil, nil, 76, 82, nil, 68, + 69, 65, nil, 51, 56, nil, 77, 57, 58, nil, + nil, nil, 61, nil, 59, 60, 62, 260, 261, 66, + 67, nil, nil, nil, nil, nil, 259, 28, 27, 92, + 91, 93, 94, nil, nil, 221, nil, nil, nil, nil, + nil, nil, 41, nil, nil, 96, 95, 97, 86, 50, + 88, 87, 89, 263, 90, 98, 99, nil, 84, 85, + 38, 39, 37, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 214, nil, nil, 220, nil, nil, 52, 53, + nil, nil, 54, nil, 258, nil, 256, nil, 40, nil, + nil, nil, nil, nil, nil, nil, 219, nil, nil, nil, + nil, 83, 75, 78, 79, nil, 80, 81, nil, nil, + nil, 76, 82, nil, 68, 69, 65, nil, 51, 56, + nil, 77, 57, 58, nil, nil, nil, 61, nil, 59, + 60, 62, 260, 261, 66, 67, nil, nil, nil, nil, + nil, 259, 28, 27, 92, 91, 93, 94, nil, nil, + 221, nil, nil, nil, nil, nil, nil, 41, nil, nil, + 96, 95, 97, 86, 50, 88, 87, 89, 263, 90, + 98, 99, nil, 84, 85, 38, 39, 37, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 214, nil, nil, + 220, nil, nil, 52, 53, nil, nil, 54, nil, 258, + nil, 256, nil, 40, nil, nil, nil, nil, nil, nil, + nil, 219, nil, nil, nil, nil, 83, 75, 78, 79, + nil, 80, 81, nil, nil, nil, 76, 82, nil, 68, + 69, 65, nil, 51, 56, nil, 77, 57, 58, nil, + nil, nil, 61, nil, 59, 60, 62, 260, 261, 66, + 67, nil, nil, nil, nil, nil, 259, 28, 27, 92, + 91, 93, 94, nil, nil, 221, nil, nil, nil, nil, + nil, nil, 41, nil, nil, 96, 95, 97, 86, 50, + 88, 87, 89, 263, 90, 98, 99, nil, 84, 85, + 38, 39, 37, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 214, nil, nil, 220, nil, nil, 52, 53, + nil, nil, 54, nil, 258, nil, 256, nil, 40, nil, + nil, nil, nil, nil, nil, nil, 219, nil, nil, nil, + nil, 83, 75, 78, 79, nil, 80, 81, nil, nil, + nil, 76, 82, nil, 68, 69, 65, nil, 51, 56, + nil, 77, 57, 58, nil, nil, nil, 61, nil, 59, + 60, 62, 260, 261, 66, 67, nil, nil, nil, nil, + nil, 259, 290, 294, 92, 91, 93, 94, nil, nil, + 221, nil, nil, nil, nil, nil, nil, 291, nil, nil, + 96, 95, 97, 86, 50, 88, 87, 89, nil, 90, + 98, 99, nil, 84, 85, nil, 644, 295, 641, 640, + 639, 645, 642, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 288, nil, nil, + 285, nil, nil, 52, 53, nil, nil, 54, nil, 284, + nil, nil, nil, 647, nil, nil, nil, nil, nil, nil, + nil, nil, 651, 650, 654, 653, 83, 75, 78, 79, + nil, 80, 81, nil, nil, nil, 76, 82, nil, 68, + 69, 65, nil, 51, 56, nil, 77, 57, 58, nil, + nil, nil, 61, nil, 59, 60, 62, 260, 261, 66, + 67, nil, nil, nil, nil, nil, 259, 290, 294, 92, + 91, 93, 94, nil, nil, 221, nil, nil, nil, nil, + nil, 557, 291, nil, nil, 96, 95, 97, 86, 50, + 88, 87, 89, nil, 90, 98, 99, nil, 84, 85, + nil, nil, 295, nil, 229, 233, 238, 239, 240, 235, + 237, 245, 246, 241, 242, nil, 222, 223, nil, nil, + 243, 244, 288, nil, nil, 220, nil, nil, 52, 53, + nil, nil, 54, nil, nil, nil, 226, nil, 232, nil, + 228, 227, 224, 225, 236, 234, 230, nil, 231, nil, + nil, 83, 75, 78, 79, nil, 80, 81, nil, nil, + nil, 76, 82, nil, nil, 247, 297, -226, nil, 56, + nil, 77, 68, 69, 65, nil, 51, nil, nil, nil, + 57, 58, nil, nil, nil, 61, nil, 59, 60, 62, + 260, 261, 66, 67, nil, nil, nil, nil, nil, 259, + 290, 294, 92, 91, 93, 94, nil, nil, 221, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 96, 95, + 97, 86, 50, 88, 87, 89, nil, 90, 98, 99, + nil, 84, 85, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 214, nil, nil, 220, nil, + nil, 52, 53, nil, nil, 54, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 219, + nil, nil, nil, nil, 83, 75, 78, 79, nil, 80, + 81, nil, nil, nil, 76, 82, nil, 68, 69, 65, + nil, 51, 56, nil, 77, 57, 58, nil, nil, nil, + 61, nil, 59, 60, 62, 260, 261, 66, 67, nil, + nil, nil, nil, nil, 259, 290, 294, 92, 91, 93, + 94, nil, nil, 221, nil, nil, nil, nil, nil, nil, + 41, nil, nil, 96, 95, 97, 86, 50, 88, 87, + 89, nil, 90, 98, 99, nil, 84, 85, 38, 39, + 37, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 214, nil, nil, 220, nil, nil, 52, 53, nil, nil, + 54, nil, nil, nil, nil, nil, 40, nil, nil, nil, + nil, nil, nil, nil, 219, nil, nil, nil, nil, 83, + 75, 78, 79, nil, 80, 81, nil, nil, nil, 76, + 82, nil, 68, 69, 65, nil, 51, 56, nil, 77, + 57, 58, nil, nil, nil, 61, nil, 59, 60, 62, + 260, 261, 66, 67, nil, nil, nil, nil, nil, 259, + 290, 294, 92, 91, 93, 94, nil, nil, 221, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 96, 95, + 97, 86, 50, 88, 87, 89, nil, 90, 98, 99, + nil, 84, 85, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 214, nil, nil, 220, nil, + nil, 52, 53, nil, nil, 54, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 219, + nil, nil, nil, nil, 83, 75, 78, 79, nil, 80, + 81, nil, nil, nil, 76, 82, nil, 68, 69, 65, + nil, 51, 56, nil, 77, 57, 58, nil, nil, nil, + 61, nil, 59, 60, 62, 23, 24, 66, 67, nil, + nil, nil, nil, nil, 22, 28, 27, 92, 91, 93, + 94, nil, nil, 17, nil, nil, nil, nil, nil, nil, + 41, nil, nil, 96, 95, 97, 86, 50, 88, 87, + 89, nil, 90, 98, 99, nil, 84, 85, 38, 39, + 37, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 214, nil, nil, 220, nil, nil, 52, 53, nil, nil, + 54, nil, nil, nil, nil, nil, 40, nil, nil, nil, + nil, nil, nil, nil, 18, nil, nil, nil, nil, 83, + 75, 78, 79, nil, 80, 81, nil, nil, nil, 76, + 82, nil, 68, 69, 65, nil, 51, 56, nil, 77, + 57, 58, nil, nil, nil, 61, nil, 59, 60, 62, + 260, 261, 66, 67, nil, nil, nil, nil, nil, 259, + 290, 294, 92, 91, 93, 94, nil, nil, 221, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 96, 95, + 97, 86, 50, 88, 87, 89, 263, 90, 98, 99, + nil, 84, 85, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 214, nil, nil, 220, nil, + nil, 52, 53, nil, nil, 54, nil, 258, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 219, + nil, nil, nil, nil, 83, 75, 78, 79, nil, 80, + 81, nil, nil, nil, 76, 82, nil, 68, 69, 65, + nil, 51, 56, nil, 77, 57, 58, nil, nil, nil, + 61, nil, 59, 60, 62, 260, 261, 66, 67, nil, + nil, nil, nil, nil, 259, 290, 294, 92, 91, 93, + 94, nil, nil, 221, nil, nil, nil, nil, nil, nil, + 41, nil, nil, 96, 95, 97, 86, 50, 88, 87, + 89, 263, 90, 98, 99, nil, 84, 85, 38, 39, + 37, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 214, nil, nil, 220, nil, nil, 52, 53, nil, nil, + 54, nil, nil, nil, nil, nil, 40, nil, nil, nil, + nil, nil, nil, nil, 219, nil, nil, nil, nil, 83, + 75, 78, 79, nil, 80, 81, nil, nil, nil, 76, + 82, nil, 68, 69, 65, nil, 51, 56, nil, 77, + 57, 58, nil, nil, nil, 61, nil, 59, 60, 62, + 23, 24, 66, 67, nil, nil, nil, nil, nil, 22, + 28, 27, 92, 91, 93, 94, nil, nil, 17, nil, + nil, nil, nil, nil, nil, 41, nil, nil, 96, 95, + 97, 86, 50, 88, 87, 89, nil, 90, 98, 99, + nil, 84, 85, 38, 39, 37, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 214, nil, nil, 220, nil, + nil, 52, 53, nil, nil, 54, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 18, + nil, nil, nil, nil, 83, 75, 78, 79, nil, 80, + 81, nil, nil, nil, 76, 82, nil, 68, 69, 65, + nil, 51, 56, nil, 77, 57, 58, nil, nil, nil, + 61, nil, 59, 60, 62, 23, 24, 66, 67, nil, + nil, nil, nil, nil, 22, 28, 27, 92, 91, 93, + 94, nil, nil, 17, nil, nil, nil, nil, nil, nil, + 41, nil, nil, 96, 95, 97, 86, 50, 88, 87, + 89, nil, 90, 98, 99, nil, 84, 85, 38, 39, + 37, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 214, nil, nil, 220, nil, nil, 52, 53, nil, nil, + 54, nil, nil, nil, nil, nil, 40, nil, nil, nil, + nil, nil, nil, nil, 18, nil, nil, nil, nil, 83, + 75, 78, 79, nil, 80, 81, nil, nil, nil, 76, + 82, nil, 68, 69, 65, nil, 51, 56, nil, 77, + 57, 58, nil, nil, nil, 61, nil, 59, 60, 62, + 23, 24, 66, 67, nil, nil, nil, nil, nil, 22, + 28, 27, 92, 91, 93, 94, nil, nil, 17, nil, + nil, nil, nil, 560, nil, 41, nil, nil, 96, 95, + 97, 86, 50, 88, 87, 89, nil, 90, 98, 99, + nil, 84, 85, 38, 39, 37, 229, 233, 238, 239, + 240, 235, 237, 245, 246, 241, 242, nil, 222, 223, + nil, nil, 243, 244, nil, 214, nil, nil, 220, nil, + nil, 52, 53, nil, nil, 54, nil, nil, 226, nil, + 232, 40, 228, 227, 224, 225, 236, 234, 230, 18, + 231, nil, nil, nil, 83, 75, 78, 79, nil, 80, + 81, nil, nil, nil, 76, 82, 104, 247, nil, nil, + nil, 103, 56, nil, 77, 68, 69, 65, nil, 51, + nil, nil, nil, 57, 58, nil, nil, nil, 61, nil, + 59, 60, 62, 260, 261, 66, 67, nil, nil, nil, + nil, nil, 259, 290, 294, 92, 91, 93, 94, nil, + nil, 221, nil, nil, nil, nil, nil, nil, 291, nil, + nil, 96, 95, 97, 86, 50, 88, 87, 89, nil, + 90, 98, 99, nil, 84, 85, nil, 724, 295, 641, + 640, 639, 645, 642, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 329, nil, + nil, 30, nil, nil, 52, 53, nil, nil, 54, nil, + 32, nil, nil, nil, 647, nil, nil, nil, nil, nil, + nil, nil, nil, 651, 650, 654, 653, 83, 75, 78, + 79, nil, 80, 81, nil, nil, nil, 76, 82, nil, + 68, 69, 65, nil, 51, 56, nil, 77, 57, 58, + nil, nil, nil, 61, nil, 59, 60, 62, 260, 261, + 66, 67, nil, nil, nil, nil, nil, 259, 290, 294, + 92, 91, 93, 94, nil, nil, 221, nil, nil, nil, + nil, nil, nil, 291, nil, nil, 96, 95, 97, 334, + 50, 88, 87, 335, nil, 90, 98, 99, nil, 84, + 85, nil, 724, 295, 641, 640, 639, 645, 642, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 341, nil, nil, 336, nil, nil, 220, nil, nil, 52, + 53, nil, nil, 54, nil, nil, nil, nil, nil, 647, + nil, nil, nil, nil, nil, nil, nil, nil, 651, 650, + 654, 653, 83, 75, 78, 79, nil, 80, 81, nil, + nil, nil, 76, 82, nil, 68, 69, 65, nil, 51, + 56, nil, 77, 57, 58, nil, nil, nil, 61, nil, + 59, 60, 62, 260, 261, 66, 67, nil, nil, nil, + nil, nil, 259, 290, 294, 92, 91, 93, 94, nil, + nil, 221, nil, nil, nil, nil, nil, nil, 291, nil, + nil, 96, 95, 97, 334, 50, 88, 87, 335, nil, + 90, 98, 99, nil, 84, 85, nil, 644, 295, 641, + 640, 639, 645, 642, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 336, nil, + nil, 220, nil, nil, 52, 53, nil, nil, 54, nil, + nil, nil, nil, nil, 647, 682, nil, nil, nil, nil, + nil, nil, nil, 651, 650, 654, 653, 83, 75, 78, + 79, nil, 80, 81, nil, nil, nil, 76, 82, nil, + 68, 69, 65, 7, 51, 56, nil, 77, 57, 58, + nil, nil, nil, 61, nil, 59, 60, 62, 23, 24, + 66, 67, nil, nil, nil, nil, nil, 22, 28, 27, + 92, 91, 93, 94, nil, nil, 17, nil, nil, nil, + nil, 557, 6, 41, 8, 9, 96, 95, 97, 86, + 50, 88, 87, 89, nil, 90, 98, 99, nil, 84, + 85, 38, 39, 37, 229, 233, 238, 239, 240, 235, + 237, 245, 246, 241, 242, nil, 222, 223, nil, nil, + 243, 244, nil, 36, nil, nil, 30, nil, nil, 52, + 53, nil, nil, 54, nil, 32, 226, nil, 232, 40, + 228, 227, 224, 225, 236, 234, 230, 18, 231, nil, + nil, nil, 83, 75, 78, 79, nil, 80, 81, nil, + nil, nil, 76, 82, nil, 247, nil, nil, nil, 366, + 56, nil, 77, 68, 69, 65, nil, 51, nil, nil, + nil, 57, 58, nil, nil, nil, 61, nil, 59, 60, + 62, 23, 24, 66, 67, nil, nil, nil, nil, nil, + 22, 28, 27, 92, 91, 93, 94, nil, nil, 17, + nil, nil, nil, nil, nil, nil, 41, nil, nil, 96, + 95, 97, 86, 50, 88, 87, 89, nil, 90, 98, + 99, nil, 84, 85, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, 220, + nil, nil, 52, 53, nil, nil, 54, nil, nil, nil, + nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 18, nil, nil, nil, nil, 83, 75, 78, 79, nil, + 80, 81, nil, nil, nil, 76, 82, nil, 68, 69, + 65, nil, 51, 56, nil, 77, 57, 58, nil, nil, + nil, 61, nil, 59, 60, 62, 23, 24, 66, 67, + nil, nil, nil, nil, nil, 22, 28, 27, 92, 91, + 93, 94, nil, nil, 17, nil, nil, nil, nil, nil, + nil, 41, nil, nil, 96, 95, 97, 86, 50, 88, + 87, 89, nil, 90, 98, 99, nil, 84, 85, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 220, nil, nil, 52, 53, nil, + nil, 54, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 18, nil, nil, nil, nil, + 83, 75, 78, 79, nil, 80, 81, nil, nil, nil, + 76, 82, nil, 68, 69, 65, nil, 51, 56, nil, + 77, 57, 58, nil, nil, nil, 61, nil, 59, 60, + 62, 23, 24, 66, 67, nil, nil, nil, nil, nil, + 22, 28, 27, 92, 91, 93, 94, nil, nil, 17, + nil, nil, nil, nil, nil, nil, 41, nil, nil, 96, + 95, 97, 86, 50, 88, 87, 89, nil, 90, 98, + 99, nil, 84, 85, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, 220, + nil, nil, 52, 53, nil, nil, 54, nil, nil, nil, + nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 18, nil, nil, nil, nil, 83, 75, 78, 79, nil, + 80, 81, nil, nil, nil, 76, 82, nil, 68, 69, + 65, nil, 51, 56, nil, 77, 57, 58, nil, nil, + nil, 61, nil, 59, 60, 62, 23, 24, 66, 67, + nil, nil, nil, nil, nil, 22, 28, 27, 92, 91, + 93, 94, nil, nil, 17, nil, nil, nil, nil, nil, + nil, 41, nil, nil, 96, 95, 97, 86, 50, 88, + 87, 89, nil, 90, 98, 99, nil, 84, 85, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 220, nil, nil, 52, 53, nil, + nil, 54, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 18, nil, nil, nil, nil, + 83, 75, 78, 79, nil, 80, 81, nil, nil, nil, + 76, 82, nil, 68, 69, 65, 7, 51, 56, nil, + 77, 57, 58, nil, nil, nil, 61, nil, 59, 60, + 62, 23, 24, 66, 67, nil, nil, nil, nil, nil, + 22, 28, 27, 92, 91, 93, 94, nil, nil, 17, + nil, nil, nil, nil, nil, 6, 41, 8, 9, 96, + 95, 97, 86, 50, 88, 87, 89, nil, 90, 98, + 99, nil, 84, 85, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 36, nil, nil, 30, + nil, nil, 52, 53, nil, nil, 54, nil, 32, nil, + nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 18, nil, nil, nil, nil, 83, 75, 78, 79, nil, + 80, 81, nil, nil, nil, 76, 82, nil, 68, 69, + 65, nil, 51, 56, nil, 77, 57, 58, nil, nil, + nil, 61, nil, 59, 60, 62, 23, 24, 66, 67, + nil, nil, nil, nil, nil, 22, 28, 27, 92, 91, + 93, 94, nil, nil, 221, nil, nil, nil, nil, nil, + nil, 41, nil, nil, 96, 95, 97, 86, 50, 88, + 87, 89, nil, 90, 98, 99, nil, 84, 85, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 220, nil, nil, 52, 53, nil, + nil, 54, nil, 383, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 219, nil, nil, nil, nil, + 83, 75, 78, 79, nil, 80, 81, nil, nil, nil, + 76, 82, nil, 68, 69, 65, nil, 51, 56, nil, + 77, 57, 58, nil, nil, nil, 61, nil, 59, 60, + 62, 23, 24, 66, 67, nil, nil, nil, nil, nil, + 22, 28, 27, 92, 91, 93, 94, nil, nil, 221, + nil, nil, nil, nil, nil, nil, 41, nil, nil, 96, + 95, 97, 86, 50, 88, 87, 89, nil, 90, 98, + 99, nil, 84, 85, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, 220, + nil, nil, 52, 53, nil, nil, 54, nil, 383, nil, + nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 219, nil, nil, nil, nil, 83, 75, 78, 79, nil, + 80, 81, nil, nil, nil, 76, 82, nil, 68, 69, + 65, nil, 51, 56, nil, 77, 57, 58, nil, nil, + nil, 61, nil, 59, 60, 62, 23, 24, 66, 67, + nil, nil, nil, nil, nil, 22, 28, 27, 92, 91, + 93, 94, nil, nil, 221, nil, nil, nil, nil, nil, + nil, 41, nil, nil, 96, 95, 97, 86, 50, 88, + 87, 89, nil, 90, 98, 99, nil, 84, 85, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 220, nil, nil, 52, 53, nil, + nil, 54, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 219, nil, nil, nil, nil, + 83, 75, 78, 79, nil, 80, 81, nil, nil, nil, + 76, 82, nil, 68, 69, 65, nil, 51, 56, nil, + 77, 57, 58, nil, nil, nil, 61, nil, 59, 60, + 62, 260, 261, 66, 67, nil, nil, nil, nil, nil, + 259, 28, 27, 92, 91, 93, 94, nil, nil, 221, + nil, nil, nil, nil, nil, nil, 41, nil, nil, 96, + 95, 97, 86, 50, 88, 87, 89, 263, 90, 98, + 99, nil, 84, 85, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, 220, + nil, nil, 52, 53, nil, nil, 54, nil, 258, nil, + 256, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 219, nil, nil, nil, nil, 83, 75, 78, 79, nil, + 80, 81, nil, nil, nil, 76, 82, nil, 68, 69, + 65, nil, 51, 56, nil, 77, 57, 58, nil, nil, + nil, 61, nil, 59, 60, 62, 23, 24, 66, 67, + nil, nil, nil, nil, nil, 22, 28, 27, 92, 91, + 93, 94, nil, nil, 221, nil, nil, nil, nil, nil, + nil, 41, nil, nil, 96, 95, 97, 86, 50, 88, + 87, 89, nil, 90, 98, 99, nil, 84, 85, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 220, nil, nil, 52, 53, nil, + nil, 54, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 219, nil, nil, nil, nil, + 83, 75, 78, 79, nil, 80, 81, nil, nil, nil, + 76, 82, nil, 68, 69, 65, nil, 51, 56, nil, + 77, 57, 58, nil, nil, nil, 61, nil, 59, 60, + 62, 23, 24, 66, 67, nil, nil, nil, nil, nil, + 22, 28, 27, 92, 91, 93, 94, nil, nil, 17, + nil, nil, nil, nil, nil, nil, 41, nil, nil, 96, + 95, 97, 86, 50, 88, 87, 89, nil, 90, 98, + 99, nil, 84, 85, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, 220, + nil, nil, 52, 53, nil, nil, 54, nil, nil, nil, + nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 18, nil, nil, nil, nil, 83, 75, 78, 79, nil, + 80, 81, nil, nil, nil, 76, 82, nil, 68, 69, + 65, nil, 51, 56, nil, 77, 57, 58, nil, nil, + nil, 61, nil, 59, 60, 62, 23, 24, 66, 67, + nil, nil, nil, nil, nil, 22, 28, 27, 92, 91, + 93, 94, nil, nil, 17, nil, nil, nil, nil, nil, + nil, 41, nil, nil, 96, 95, 97, 86, 50, 88, + 87, 89, nil, 90, 98, 99, nil, 84, 85, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 220, nil, nil, 52, 53, nil, + nil, 54, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 18, nil, nil, nil, nil, + 83, 75, 78, 79, nil, 80, 81, nil, nil, nil, + 76, 82, nil, 68, 69, 65, nil, 51, 56, nil, + 77, 57, 58, nil, nil, nil, 61, nil, 59, 60, + 62, 23, 24, 66, 67, nil, nil, nil, nil, nil, + 22, 28, 27, 92, 91, 93, 94, nil, nil, 17, + nil, nil, nil, nil, nil, nil, 41, nil, nil, 96, + 95, 97, 86, 50, 88, 87, 89, nil, 90, 98, + 99, nil, 84, 85, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, 220, + nil, nil, 52, 53, nil, nil, 54, nil, nil, nil, + nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 18, nil, nil, nil, nil, 83, 75, 78, 79, nil, + 80, 81, nil, nil, nil, 76, 82, nil, 68, 69, + 65, nil, 51, 56, nil, 77, 57, 58, nil, nil, + nil, 61, nil, 59, 60, 62, 23, 24, 66, 67, + nil, nil, nil, nil, nil, 22, 28, 27, 92, 91, + 93, 94, nil, nil, 17, nil, nil, nil, nil, nil, + nil, 41, nil, nil, 96, 95, 97, 86, 50, 88, + 87, 89, nil, 90, 98, 99, nil, 84, 85, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 220, nil, nil, 52, 53, nil, + nil, 54, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 18, nil, nil, nil, nil, + 83, 75, 78, 79, nil, 80, 81, nil, nil, nil, + 76, 82, 210, 68, 69, 65, nil, 51, 56, nil, + 77, 57, 58, nil, nil, nil, 61, nil, 59, 60, + 62, 260, 261, 66, 67, nil, nil, nil, nil, nil, + 259, 290, 294, 92, 91, 93, 94, nil, nil, 221, + nil, nil, nil, nil, nil, nil, 41, nil, nil, 96, + 95, 97, 86, 50, 88, 87, 89, nil, 90, 98, + 99, nil, 84, 85, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, 220, + nil, nil, 52, 53, nil, nil, 54, nil, nil, nil, + nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 219, nil, nil, nil, nil, 83, 75, 78, 79, nil, + 80, 81, nil, nil, nil, 76, 82, nil, 68, 69, + 65, nil, 51, 56, nil, 77, 57, 58, nil, nil, + nil, 61, nil, 59, 60, 62, 260, 261, 66, 67, + nil, nil, nil, nil, nil, 259, 290, 294, 92, 91, + 93, 94, nil, nil, 221, nil, nil, nil, nil, nil, + nil, 41, nil, nil, 96, 95, 97, 86, 50, 88, + 87, 89, nil, 90, 98, 99, nil, 84, 85, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 220, nil, nil, 52, 53, nil, + nil, 54, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 219, nil, nil, nil, nil, + 83, 75, 78, 79, nil, 80, 81, nil, nil, nil, + 76, 82, nil, 68, 69, 65, nil, 51, 56, nil, + 77, 57, 58, nil, nil, nil, 61, nil, 59, 60, + 62, 260, 261, 66, 67, nil, nil, nil, nil, nil, + 259, 290, 294, 92, 91, 93, 94, nil, nil, 221, + nil, nil, nil, nil, nil, nil, 41, nil, nil, 96, + 95, 97, 86, 50, 88, 87, 89, nil, 90, 98, + 99, nil, 84, 85, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, 220, + nil, nil, 52, 53, nil, nil, 54, nil, nil, nil, + nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 219, nil, nil, nil, nil, 83, 75, 78, 79, nil, + 80, 81, nil, nil, nil, 76, 82, nil, 68, 69, + 65, nil, 51, 56, nil, 77, 57, 58, nil, nil, + nil, 61, nil, 59, 60, 62, 260, 261, 66, 67, + nil, nil, nil, nil, nil, 259, 290, 294, 92, 91, + 93, 94, nil, nil, 221, nil, nil, nil, nil, nil, + nil, 41, nil, nil, 96, 95, 97, 86, 50, 88, + 87, 89, nil, 90, 98, 99, nil, 84, 85, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 220, nil, nil, 52, 53, nil, + nil, 54, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 219, nil, nil, nil, nil, + 83, 75, 78, 79, nil, 80, 81, nil, nil, nil, + 76, 82, nil, 68, 69, 65, nil, 51, 56, nil, + 77, 57, 58, nil, nil, nil, 61, nil, 59, 60, + 62, 260, 261, 66, 67, nil, nil, nil, nil, nil, + 259, 290, 294, 92, 91, 93, 94, nil, nil, 221, + nil, nil, nil, nil, nil, nil, 41, nil, nil, 96, + 95, 97, 86, 50, 88, 87, 89, nil, 90, 98, + 99, nil, 84, 85, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, 220, + nil, nil, 52, 53, nil, nil, 54, nil, nil, nil, + nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 219, nil, nil, nil, nil, 83, 75, 78, 79, nil, + 80, 81, nil, nil, nil, 76, 82, nil, 68, 69, + 65, nil, 51, 56, nil, 77, 57, 58, nil, nil, + nil, 61, nil, 59, 60, 62, 260, 261, 66, 67, + nil, nil, nil, nil, nil, 259, 290, 294, 92, 91, + 93, 94, nil, nil, 221, nil, nil, nil, nil, nil, + nil, 41, nil, nil, 96, 95, 97, 86, 50, 88, + 87, 89, nil, 90, 98, 99, nil, 84, 85, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 220, nil, nil, 52, 53, nil, + nil, 54, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 219, nil, nil, nil, nil, + 83, 75, 78, 79, nil, 80, 81, nil, nil, nil, + 76, 82, nil, 68, 69, 65, nil, 51, 56, nil, + 77, 57, 58, nil, nil, nil, 61, nil, 59, 60, + 62, 260, 261, 66, 67, nil, nil, nil, nil, nil, + 259, 290, 294, 92, 91, 93, 94, nil, nil, 221, + nil, nil, nil, nil, nil, nil, 41, nil, nil, 96, + 95, 97, 86, 50, 88, 87, 89, nil, 90, 98, + 99, nil, 84, 85, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, 220, + nil, nil, 52, 53, nil, nil, 54, nil, nil, nil, + nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 219, nil, nil, nil, nil, 83, 75, 78, 79, nil, + 80, 81, nil, nil, nil, 76, 82, nil, 68, 69, + 65, nil, 51, 56, nil, 77, 57, 58, nil, nil, + nil, 61, nil, 59, 60, 62, 260, 261, 66, 67, + nil, nil, nil, nil, nil, 259, 290, 294, 92, 91, + 93, 94, nil, nil, 221, nil, nil, nil, nil, nil, + nil, 41, nil, nil, 96, 95, 97, 86, 50, 88, + 87, 89, nil, 90, 98, 99, nil, 84, 85, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 220, nil, nil, 52, 53, nil, + nil, 54, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 219, nil, nil, nil, nil, + 83, 75, 78, 79, nil, 80, 81, nil, nil, nil, + 76, 82, nil, 68, 69, 65, nil, 51, 56, nil, + 77, 57, 58, nil, nil, nil, 61, nil, 59, 60, + 62, 260, 261, 66, 67, nil, nil, nil, nil, nil, + 259, 290, 294, 92, 91, 93, 94, nil, nil, 221, + nil, nil, nil, nil, nil, nil, 41, nil, nil, 96, + 95, 97, 86, 50, 88, 87, 89, nil, 90, 98, + 99, nil, 84, 85, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, 220, + nil, nil, 52, 53, nil, nil, 54, nil, nil, nil, + nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 219, nil, nil, nil, nil, 83, 75, 78, 79, nil, + 80, 81, nil, nil, nil, 76, 82, nil, 68, 69, + 65, nil, 51, 56, nil, 77, 57, 58, nil, nil, + nil, 61, nil, 59, 60, 62, 260, 261, 66, 67, + nil, nil, nil, nil, nil, 259, 290, 294, 92, 91, + 93, 94, nil, nil, 221, nil, nil, nil, nil, nil, + nil, 41, nil, nil, 96, 95, 97, 86, 50, 88, + 87, 89, nil, 90, 98, 99, nil, 84, 85, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 220, nil, nil, 52, 53, nil, + nil, 54, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 219, nil, nil, nil, nil, + 83, 75, 78, 79, nil, 80, 81, nil, nil, nil, + 76, 82, nil, 68, 69, 65, nil, 51, 56, nil, + 77, 57, 58, nil, nil, nil, 61, nil, 59, 60, + 62, 260, 261, 66, 67, nil, nil, nil, nil, nil, + 259, 290, 294, 92, 91, 93, 94, nil, nil, 221, + nil, nil, nil, nil, nil, nil, 41, nil, nil, 96, + 95, 97, 86, 50, 88, 87, 89, nil, 90, 98, + 99, nil, 84, 85, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, 220, + nil, nil, 52, 53, nil, nil, 54, nil, nil, nil, + nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 219, nil, nil, nil, nil, 83, 75, 78, 79, nil, + 80, 81, nil, nil, nil, 76, 82, nil, 68, 69, + 65, nil, 51, 56, nil, 77, 57, 58, nil, nil, + nil, 61, nil, 59, 60, 62, 260, 261, 66, 67, + nil, nil, nil, nil, nil, 259, 290, 294, 92, 91, + 93, 94, nil, nil, 221, nil, nil, nil, nil, nil, + nil, 41, nil, nil, 96, 95, 97, 86, 50, 88, + 87, 89, nil, 90, 98, 99, nil, 84, 85, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 220, nil, nil, 52, 53, nil, + nil, 54, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 219, nil, nil, nil, nil, + 83, 75, 78, 79, nil, 80, 81, nil, nil, nil, + 76, 82, nil, 68, 69, 65, nil, 51, 56, nil, + 77, 57, 58, nil, nil, nil, 61, nil, 59, 60, + 62, 260, 261, 66, 67, nil, nil, nil, nil, nil, + 259, 290, 294, 92, 91, 93, 94, nil, nil, 221, + nil, nil, nil, nil, nil, nil, 41, nil, nil, 96, + 95, 97, 86, 50, 88, 87, 89, nil, 90, 98, + 99, nil, 84, 85, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, 220, + nil, nil, 52, 53, nil, nil, 54, nil, nil, nil, + nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 219, nil, nil, nil, nil, 83, 75, 78, 79, nil, + 80, 81, nil, nil, nil, 76, 82, nil, 68, 69, + 65, nil, 51, 56, nil, 77, 57, 58, nil, nil, + nil, 61, nil, 59, 60, 62, 260, 261, 66, 67, + nil, nil, nil, nil, nil, 259, 290, 294, 92, 91, + 93, 94, nil, nil, 221, nil, nil, nil, nil, nil, + nil, 41, nil, nil, 96, 95, 97, 86, 50, 88, + 87, 89, nil, 90, 98, 99, nil, 84, 85, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 220, nil, nil, 52, 53, nil, + nil, 54, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 219, nil, nil, nil, nil, + 83, 75, 78, 79, nil, 80, 81, nil, nil, nil, + 76, 82, nil, 68, 69, 65, nil, 51, 56, nil, + 77, 57, 58, nil, nil, nil, 61, nil, 59, 60, + 62, 260, 261, 66, 67, nil, nil, nil, nil, nil, + 259, 290, 294, 92, 91, 93, 94, nil, nil, 221, + nil, nil, nil, nil, nil, nil, 41, nil, nil, 96, + 95, 97, 86, 50, 88, 87, 89, nil, 90, 98, + 99, nil, 84, 85, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, 220, + nil, nil, 52, 53, nil, nil, 54, nil, nil, nil, + nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 219, nil, nil, nil, nil, 83, 75, 78, 79, nil, + 80, 81, nil, nil, nil, 76, 82, nil, 68, 69, + 65, nil, 51, 56, nil, 77, 57, 58, nil, nil, + nil, 61, nil, 59, 60, 62, 260, 261, 66, 67, + nil, nil, nil, nil, nil, 259, 290, 294, 92, 91, + 93, 94, nil, nil, 221, nil, nil, nil, nil, nil, + nil, 41, nil, nil, 96, 95, 97, 86, 50, 88, + 87, 89, nil, 90, 98, 99, nil, 84, 85, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 220, nil, nil, 52, 53, nil, + nil, 54, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 219, nil, nil, nil, nil, + 83, 75, 78, 79, nil, 80, 81, nil, nil, nil, + 76, 82, nil, 68, 69, 65, nil, 51, 56, nil, + 77, 57, 58, nil, nil, nil, 61, nil, 59, 60, + 62, 260, 261, 66, 67, nil, nil, nil, nil, nil, + 259, 290, 294, 92, 91, 93, 94, nil, nil, 221, + nil, nil, nil, nil, nil, nil, 41, nil, nil, 96, + 95, 97, 86, 50, 88, 87, 89, nil, 90, 98, + 99, nil, 84, 85, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, 220, + nil, nil, 52, 53, nil, nil, 54, nil, nil, nil, + nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 219, nil, nil, nil, nil, 83, 75, 78, 79, nil, + 80, 81, nil, nil, nil, 76, 82, nil, 68, 69, + 65, nil, 51, 56, nil, 77, 57, 58, nil, nil, + nil, 61, nil, 59, 60, 62, 260, 261, 66, 67, + nil, nil, nil, nil, nil, 259, 290, 294, 92, 91, + 93, 94, nil, nil, 221, nil, nil, nil, nil, nil, + nil, 41, nil, nil, 96, 95, 97, 86, 50, 88, + 87, 89, nil, 90, 98, 99, nil, 84, 85, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 220, nil, nil, 52, 53, nil, + nil, 54, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 219, nil, nil, nil, nil, + 83, 75, 78, 79, nil, 80, 81, nil, nil, nil, + 76, 82, nil, 68, 69, 65, nil, 51, 56, nil, + 77, 57, 58, nil, nil, nil, 61, nil, 59, 60, + 62, 260, 261, 66, 67, nil, nil, nil, nil, nil, + 259, 290, 294, 92, 91, 93, 94, nil, nil, 221, + nil, nil, nil, nil, nil, nil, 41, nil, nil, 96, + 95, 97, 86, 50, 88, 87, 89, nil, 90, 98, + 99, nil, 84, 85, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, 220, + nil, nil, 52, 53, nil, nil, 54, nil, nil, nil, + nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 219, nil, nil, nil, nil, 83, 75, 78, 79, nil, + 80, 81, nil, nil, nil, 76, 82, nil, 68, 69, + 65, nil, 51, 56, nil, 77, 57, 58, nil, nil, + nil, 61, nil, 59, 60, 62, 260, 261, 66, 67, + nil, nil, nil, nil, nil, 259, 290, 294, 92, 91, + 93, 94, nil, nil, 221, nil, nil, nil, nil, nil, + nil, 41, nil, nil, 96, 95, 97, 86, 50, 88, + 87, 89, nil, 90, 98, 99, nil, 84, 85, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 220, nil, nil, 52, 53, nil, + nil, 54, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 219, nil, nil, nil, nil, + 83, 75, 78, 79, nil, 80, 81, nil, nil, nil, + 76, 82, nil, 68, 69, 65, nil, 51, 56, nil, + 77, 57, 58, nil, nil, nil, 61, nil, 59, 60, + 62, 260, 261, 66, 67, nil, nil, nil, nil, nil, + 259, 290, 294, 92, 91, 93, 94, nil, nil, 221, + nil, nil, nil, nil, nil, nil, 41, nil, nil, 96, + 95, 97, 86, 50, 88, 87, 89, nil, 90, 98, + 99, nil, 84, 85, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, 220, + nil, nil, 52, 53, nil, nil, 54, nil, nil, nil, + nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 219, nil, nil, nil, nil, 83, 75, 78, 79, nil, + 80, 81, nil, nil, nil, 76, 82, nil, 68, 69, + 65, nil, 51, 56, nil, 77, 57, 58, nil, nil, + nil, 61, nil, 59, 60, 62, 260, 261, 66, 67, + nil, nil, nil, nil, nil, 259, 290, 294, 92, 91, + 93, 94, nil, nil, 221, nil, nil, nil, nil, nil, + nil, 41, nil, nil, 96, 95, 97, 86, 50, 88, + 87, 89, nil, 90, 98, 99, nil, 84, 85, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 220, nil, nil, 52, 53, nil, + nil, 54, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 219, nil, nil, nil, nil, + 83, 75, 78, 79, nil, 80, 81, nil, nil, nil, + 76, 82, nil, 68, 69, 65, nil, 51, 56, nil, + 77, 57, 58, nil, nil, nil, 61, nil, 59, 60, + 62, 260, 261, 66, 67, nil, nil, nil, nil, nil, + 259, 290, 294, 92, 91, 93, 94, nil, nil, 221, + nil, nil, nil, nil, nil, nil, 41, nil, nil, 96, + 95, 97, 86, 50, 88, 87, 89, nil, 90, 98, + 99, nil, 84, 85, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, 220, + nil, nil, 52, 53, nil, nil, 54, nil, nil, nil, + nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 219, nil, nil, nil, nil, 83, 75, 78, 79, nil, + 80, 81, nil, nil, nil, 76, 82, nil, 68, 69, + 65, nil, 51, 56, nil, 77, 57, 58, nil, nil, + nil, 61, nil, 59, 60, 62, 260, 261, 66, 67, + nil, nil, nil, nil, nil, 259, 290, 294, 92, 91, + 93, 94, nil, nil, 221, nil, nil, nil, nil, nil, + nil, 41, nil, nil, 96, 95, 97, 86, 50, 88, + 87, 89, nil, 90, 98, 99, nil, 84, 85, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 220, nil, nil, 52, 53, nil, + nil, 54, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 219, nil, nil, nil, nil, + 83, 75, 78, 79, nil, 80, 81, nil, nil, nil, + 76, 82, nil, 68, 69, 65, nil, 51, 56, nil, + 77, 57, 58, nil, nil, nil, 61, nil, 59, 60, + 62, 260, 261, 66, 67, nil, nil, nil, nil, nil, + 259, 290, 294, 92, 91, 93, 94, nil, nil, 221, + nil, nil, nil, nil, nil, nil, 41, nil, nil, 96, + 95, 97, 86, 50, 88, 87, 89, nil, 90, 98, + 99, nil, 84, 85, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, 220, + nil, nil, 52, 53, nil, nil, 54, nil, nil, nil, + nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 219, nil, nil, nil, nil, 83, 75, 78, 79, nil, + 80, 81, nil, nil, nil, 76, 82, nil, 68, 69, + 65, nil, 51, 56, nil, 77, 57, 58, nil, nil, + nil, 61, nil, 59, 60, 62, 260, 261, 66, 67, + nil, nil, nil, nil, nil, 259, 290, 294, 92, 91, + 93, 94, nil, nil, 221, nil, nil, nil, nil, nil, + nil, 41, nil, nil, 96, 95, 97, 86, 50, 88, + 87, 89, nil, 90, 98, 99, nil, 84, 85, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 220, nil, nil, 52, 53, nil, + nil, 54, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 219, nil, nil, nil, nil, + 83, 75, 78, 79, nil, 80, 81, nil, nil, nil, + 76, 82, nil, 68, 69, 65, nil, 51, 56, nil, + 77, 57, 58, nil, nil, nil, 61, nil, 59, 60, + 62, 260, 261, 66, 67, nil, nil, nil, nil, nil, + 259, 290, 294, 92, 91, 93, 94, nil, nil, 221, + nil, nil, nil, nil, nil, nil, 41, nil, nil, 96, + 95, 97, 86, 50, 88, 87, 89, nil, 90, 98, + 99, nil, 84, 85, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, 220, + nil, nil, 52, 53, nil, nil, 54, nil, nil, nil, + nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 219, nil, nil, nil, nil, 83, 75, 78, 79, nil, + 80, 81, nil, nil, nil, 76, 82, nil, 68, 69, + 65, nil, 51, 56, nil, 77, 57, 58, nil, nil, + nil, 61, nil, 59, 60, 62, 260, 261, 66, 67, + nil, nil, nil, nil, nil, 259, 290, 294, 92, 91, + 93, 94, nil, nil, 221, nil, nil, nil, nil, nil, + nil, 41, nil, nil, 96, 95, 97, 86, 50, 88, + 87, 89, nil, 90, 98, 99, nil, 84, 85, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 220, nil, nil, 52, 53, nil, + nil, 54, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 219, nil, nil, nil, nil, + 83, 75, 78, 79, nil, 80, 81, nil, nil, nil, + 76, 82, nil, 68, 69, 65, nil, 51, 56, nil, + 77, 57, 58, nil, nil, nil, 61, nil, 59, 60, + 62, 260, 261, 66, 67, nil, nil, nil, nil, nil, + 259, 290, 294, 92, 91, 93, 94, nil, nil, 221, + nil, nil, nil, nil, nil, nil, 41, nil, nil, 96, + 95, 97, 86, 50, 88, 87, 89, nil, 90, 98, + 99, nil, 84, 85, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, 220, + nil, nil, 52, 53, nil, nil, 54, nil, nil, nil, + nil, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 219, nil, nil, nil, nil, 83, 75, 78, 79, nil, + 80, 81, nil, nil, nil, 76, 82, nil, 68, 69, + 65, nil, 51, 56, nil, 77, 57, 58, nil, nil, + nil, 61, nil, 59, 60, 62, 260, 261, 66, 67, + nil, nil, nil, nil, nil, 259, 290, 294, 92, 91, + 93, 94, nil, nil, 221, nil, nil, nil, nil, nil, + nil, 41, nil, nil, 96, 95, 97, 86, 50, 88, + 87, 89, nil, 90, 98, 99, nil, 84, 85, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 220, nil, nil, 52, 53, nil, + nil, 54, nil, nil, nil, nil, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 219, nil, nil, nil, nil, + 83, 75, 78, 79, nil, 80, 81, nil, nil, nil, + 76, 82, nil, 68, 69, 65, nil, 51, 56, nil, + 77, 57, 58, nil, nil, nil, 61, nil, 59, 60, + 62, 260, 261, 66, 67, nil, nil, nil, nil, nil, + 259, 28, 27, 92, 91, 93, 94, nil, nil, 221, + nil, nil, nil, nil, nil, nil, 41, nil, nil, 96, + 95, 97, 86, 50, 88, 87, 89, 263, 90, 98, + 99, nil, 84, 85, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, 220, + nil, nil, 52, 53, nil, nil, 54, nil, 258, nil, + 256, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 219, nil, nil, nil, nil, 83, 75, 78, 79, nil, + 80, 81, nil, nil, nil, 76, 82, nil, 68, 69, + 65, nil, 51, 56, nil, 77, 57, 58, nil, nil, + nil, 61, nil, 59, 60, 62, 260, 261, 66, 67, + nil, nil, nil, nil, nil, 259, 28, 27, 92, 91, + 93, 94, nil, nil, 221, nil, nil, nil, nil, nil, + nil, 41, nil, nil, 96, 95, 97, 86, 50, 88, + 87, 89, 263, 90, 98, 99, nil, 84, 85, 38, + 39, 37, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 214, nil, nil, 220, nil, nil, 464, 53, nil, + nil, 54, nil, 258, nil, 256, nil, 40, nil, nil, + nil, nil, nil, nil, nil, 219, nil, nil, nil, nil, + 83, 75, 78, 79, nil, 80, 81, nil, nil, nil, + 76, 82, nil, 68, 69, 65, nil, 51, 56, nil, + 77, 57, 58, nil, nil, nil, 61, nil, 59, 60, + 62, 260, 261, 66, 67, nil, nil, nil, nil, nil, + 259, 28, 27, 92, 91, 93, 94, nil, nil, 221, + nil, nil, nil, nil, nil, nil, 41, nil, nil, 96, + 95, 97, 86, 50, 88, 87, 89, 263, 90, 98, + 99, nil, 84, 85, 38, 39, 37, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 214, nil, nil, 220, + nil, nil, 52, 53, nil, nil, 54, nil, 258, nil, + 256, nil, 40, nil, nil, nil, nil, nil, nil, nil, + 219, nil, nil, nil, nil, 83, 75, 78, 79, nil, + 80, 81, nil, nil, nil, 76, 82, 210, 68, 69, + 65, nil, 51, 56, nil, 77, 57, 58, nil, nil, + nil, 61, nil, 59, 60, 62, 260, 261, 66, 67, + nil, nil, nil, nil, nil, 259, 290, 294, 92, 91, + 93, 94, nil, nil, 221, nil, nil, nil, nil, nil, + nil, 291, nil, nil, 96, 95, 97, 86, 50, 88, + 87, 89, nil, 90, 98, 99, nil, 84, 85, nil, + nil, 295, 229, 233, 238, 239, 240, 235, 237, 245, + 246, 241, 242, nil, 222, 223, nil, nil, 243, 244, + nil, 288, nil, nil, 220, nil, nil, 52, 53, nil, + nil, 54, nil, nil, 226, nil, 232, nil, 228, 227, + 224, 225, 236, 234, 230, nil, 231, nil, nil, nil, + 83, 75, 78, 79, nil, 80, 81, nil, nil, nil, + 76, 82, nil, 247, nil, 474, nil, nil, 56, nil, + 77, 68, 69, 65, nil, 51, nil, nil, nil, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 260, + 261, 66, 67, nil, nil, nil, nil, nil, 259, 290, + 294, 92, 91, 93, 94, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 291, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, nil, 90, 98, 99, nil, + 84, 85, nil, 644, 295, 641, 640, 639, 645, 642, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 288, nil, nil, 285, nil, nil, + 52, 53, nil, nil, 54, nil, nil, nil, nil, nil, + 647, nil, nil, nil, nil, nil, nil, nil, nil, 651, + 650, 654, 653, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 260, 261, 66, 67, nil, nil, + nil, nil, nil, 259, 290, 294, 92, 91, 93, 94, + nil, nil, 221, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + nil, 90, 98, 99, nil, 84, 85, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 214, + nil, nil, 220, 492, nil, 52, 53, nil, nil, 54, + nil, nil, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 219, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 23, + 24, 66, 67, nil, nil, nil, nil, nil, 22, 28, + 27, 92, 91, 93, 94, nil, nil, 17, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, nil, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, nil, nil, nil, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 18, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 23, 24, 66, 67, nil, nil, + nil, nil, nil, 22, 28, 27, 92, 91, 93, 94, + nil, nil, 17, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + nil, 90, 98, 99, nil, 84, 85, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 214, + nil, nil, 220, nil, nil, 52, 53, nil, nil, 54, + nil, nil, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 18, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 23, + 24, 66, 67, nil, nil, nil, nil, nil, 22, 28, + 27, 92, 91, 93, 94, nil, nil, 17, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, nil, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, nil, nil, nil, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 18, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 23, 24, 66, 67, nil, nil, + nil, nil, nil, 22, 28, 27, 92, 91, 93, 94, + nil, nil, 17, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + nil, 90, 98, 99, nil, 84, 85, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 214, + nil, nil, 220, nil, nil, 52, 53, nil, nil, 54, + nil, nil, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 18, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 260, + 261, 66, 67, nil, nil, nil, nil, nil, 259, 290, + 294, 92, 91, 93, 94, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, nil, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, nil, nil, nil, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 219, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 260, 261, 66, 67, nil, nil, + nil, nil, nil, 259, 28, 27, 92, 91, 93, 94, + nil, nil, 221, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + 263, 90, 98, 99, nil, 84, 85, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 214, + nil, nil, 220, nil, nil, 52, 53, nil, nil, 54, + nil, 258, nil, 256, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 219, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 260, + 261, 66, 67, nil, nil, nil, nil, nil, 259, 290, + 294, 92, 91, 93, 94, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, nil, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, nil, nil, nil, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 219, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 260, 261, 66, 67, nil, nil, + nil, nil, nil, 259, 290, 294, 92, 91, 93, 94, + nil, nil, 221, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + nil, 90, 98, 99, nil, 84, 85, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 214, + nil, nil, 220, nil, nil, 52, 53, nil, nil, 54, + nil, nil, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 219, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 260, + 261, 66, 67, nil, nil, nil, nil, nil, 259, 290, + 294, 92, 91, 93, 94, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, nil, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, nil, nil, nil, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 219, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 260, 261, 66, 67, nil, nil, + nil, nil, nil, 259, 290, 294, 92, 91, 93, 94, + nil, nil, 221, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + 263, 90, 98, 99, nil, 84, 85, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 214, + nil, nil, 220, nil, nil, 52, 53, nil, nil, 54, + nil, 588, nil, 256, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 219, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 260, + 261, 66, 67, nil, nil, nil, nil, nil, 259, 290, + 294, 92, 91, 93, 94, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, 263, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, nil, nil, 256, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 219, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 260, 261, 66, 67, nil, nil, + nil, nil, nil, 259, 290, 294, 92, 91, 93, 94, + nil, nil, 221, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + nil, 90, 98, 99, nil, 84, 85, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 214, + nil, nil, 220, nil, nil, 52, 53, nil, nil, 54, + nil, nil, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 219, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 23, + 24, 66, 67, nil, nil, nil, nil, nil, 22, 28, + 27, 92, 91, 93, 94, nil, nil, 17, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, 263, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, nil, nil, 256, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 18, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 260, 261, 66, 67, nil, nil, + nil, nil, nil, 259, 290, 294, 92, 91, 93, 94, + nil, nil, 221, nil, nil, nil, nil, nil, nil, 291, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + nil, 90, 98, 99, nil, 84, 85, nil, 724, 295, + 641, 640, 639, 645, 642, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 288, + nil, nil, 285, nil, nil, 52, 53, nil, nil, 54, + nil, nil, nil, nil, nil, 647, nil, nil, nil, nil, + nil, nil, nil, nil, 651, 650, 654, 653, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 260, + 261, 66, 67, nil, nil, nil, nil, nil, 259, 28, + 27, 92, 91, 93, 94, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, 263, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, 258, nil, 256, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 219, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 260, 261, 66, 67, nil, nil, + nil, nil, nil, 259, 290, 294, 92, 91, 93, 94, + nil, nil, 221, nil, nil, nil, nil, nil, nil, 291, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + nil, 90, 98, 99, nil, 84, 85, nil, nil, 295, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 288, + nil, nil, 285, nil, nil, 52, 53, nil, nil, 54, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 260, + 261, 66, 67, nil, nil, nil, nil, nil, 259, 290, + 294, 92, 91, 93, 94, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, nil, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, nil, nil, nil, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 219, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 260, 261, 66, 67, nil, nil, + nil, nil, nil, 259, 290, 294, 92, 91, 93, 94, + nil, nil, 221, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + nil, 90, 98, 99, nil, 84, 85, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 214, + nil, nil, 220, nil, nil, 52, 53, nil, nil, 54, + nil, nil, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 219, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 260, + 261, 66, 67, nil, nil, nil, nil, nil, 259, 290, + 294, 92, 91, 93, 94, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, nil, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, nil, nil, nil, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 219, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 23, 24, 66, 67, nil, nil, + nil, nil, nil, 22, 28, 27, 92, 91, 93, 94, + nil, nil, 17, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + nil, 90, 98, 99, nil, 84, 85, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 214, + nil, nil, 220, nil, nil, 52, 53, nil, nil, 54, + nil, nil, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 18, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 260, + 261, 66, 67, nil, nil, nil, nil, nil, 259, 290, + 294, 92, 91, 93, 94, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, nil, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, 383, nil, nil, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 219, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 260, 261, 66, 67, nil, nil, + nil, nil, nil, 259, 290, 294, 92, 91, 93, 94, + nil, nil, 221, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + 263, 90, 98, 99, nil, 84, 85, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 214, + nil, nil, 220, nil, nil, 52, 53, nil, nil, 54, + nil, 588, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 219, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 260, + 261, 66, 67, nil, nil, nil, nil, nil, 259, 290, + 294, 92, 91, 93, 94, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, 263, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, nil, nil, nil, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 219, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 260, 261, 66, 67, nil, nil, + nil, nil, nil, 259, 290, 294, 92, 91, 93, 94, + nil, nil, 221, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + nil, 90, 98, 99, nil, 84, 85, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 214, + nil, nil, 220, nil, nil, 52, 53, nil, nil, 54, + nil, 258, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 219, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 260, + 261, 66, 67, nil, nil, nil, nil, nil, 259, 28, + 27, 92, 91, 93, 94, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, 263, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, 258, nil, 256, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 219, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 260, 261, 66, 67, nil, nil, + nil, nil, nil, 259, 28, 27, 92, 91, 93, 94, + nil, nil, 221, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + 263, 90, 98, 99, nil, 84, 85, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 214, + nil, nil, 220, nil, nil, 52, 53, nil, nil, 54, + nil, 258, nil, 256, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 219, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 23, + 24, 66, 67, nil, nil, nil, nil, nil, 22, 28, + 27, 92, 91, 93, 94, nil, nil, 17, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, nil, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, nil, nil, nil, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 18, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 260, 261, 66, 67, nil, nil, + nil, nil, nil, 259, 290, 294, 92, 91, 93, 94, + nil, nil, 221, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + nil, 90, 98, 99, nil, 84, 85, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 214, + nil, nil, 220, nil, nil, 52, 53, nil, nil, 54, + nil, nil, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 219, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 260, + 261, 66, 67, nil, nil, nil, nil, nil, 259, 290, + 294, 92, 91, 93, 94, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, nil, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, 699, nil, nil, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 219, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 260, 261, 66, 67, nil, nil, + nil, nil, nil, 259, 290, 294, 92, 91, 93, 94, + nil, nil, 221, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + nil, 90, 98, 99, nil, 84, 85, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 214, + nil, nil, 220, nil, nil, 52, 53, nil, nil, 54, + nil, nil, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 219, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 23, + 24, 66, 67, nil, nil, nil, nil, nil, 22, 28, + 27, 92, 91, 93, 94, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, nil, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, nil, nil, nil, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 219, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 23, 24, 66, 67, nil, nil, + nil, nil, nil, 22, 28, 27, 92, 91, 93, 94, + nil, nil, 221, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + nil, 90, 98, 99, nil, 84, 85, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 214, + nil, nil, 220, nil, nil, 52, 53, nil, nil, 54, + nil, nil, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 219, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 23, + 24, 66, 67, nil, nil, nil, nil, nil, 22, 28, + 27, 92, 91, 93, 94, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, nil, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, nil, nil, nil, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 219, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 260, 261, 66, 67, nil, nil, + nil, nil, nil, 259, 290, 294, 92, 91, 93, 94, + nil, nil, 221, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + nil, 90, 98, 99, nil, 84, 85, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 214, + nil, nil, 220, nil, nil, 52, 53, nil, nil, 54, + nil, nil, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 219, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 260, + 261, 66, 67, nil, nil, nil, nil, nil, 259, 290, + 294, 92, 91, 93, 94, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, nil, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, nil, nil, nil, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 219, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 260, 261, 66, 67, nil, nil, + nil, nil, nil, 259, 290, 294, 92, 91, 93, 94, + nil, nil, 221, nil, nil, nil, nil, nil, nil, 291, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + nil, 90, 98, 99, nil, 84, 85, nil, nil, 295, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 288, + nil, nil, 285, nil, nil, 52, 53, nil, nil, 54, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 260, + 261, 66, 67, nil, nil, nil, nil, nil, 259, 290, + 294, 92, 91, 93, 94, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 291, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, nil, 90, 98, 99, nil, + 84, 85, nil, nil, 295, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 288, nil, nil, 285, nil, nil, + 52, 53, nil, nil, 54, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 23, 24, 66, 67, nil, nil, + nil, nil, nil, 22, 28, 27, 92, 91, 93, 94, + nil, nil, 17, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + nil, 90, 98, 99, nil, 84, 85, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 214, + nil, nil, 220, nil, nil, 52, 53, nil, nil, 54, + nil, nil, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 18, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 260, + 261, 66, 67, nil, nil, nil, nil, nil, 259, 290, + 294, 92, 91, 93, 94, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, nil, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, nil, nil, nil, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 219, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 23, 24, 66, 67, nil, nil, + nil, nil, nil, 22, 28, 27, 92, 91, 93, 94, + nil, nil, 221, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + nil, 90, 98, 99, nil, 84, 85, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 214, + nil, nil, 220, nil, nil, 52, 53, nil, nil, 54, + nil, nil, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 219, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 260, + 261, 66, 67, nil, nil, nil, nil, nil, 259, 290, + 294, 92, 91, 93, 94, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, nil, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, nil, nil, nil, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 219, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 260, 261, 66, 67, nil, nil, + nil, nil, nil, 259, 290, 294, 92, 91, 93, 94, + nil, nil, 221, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + nil, 90, 98, 99, nil, 84, 85, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 214, + nil, nil, 220, nil, nil, 52, 53, nil, nil, 54, + nil, nil, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 219, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 260, + 261, 66, 67, nil, nil, nil, nil, nil, 259, 290, + 294, 92, 91, 93, 94, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, nil, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, nil, nil, nil, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 219, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 260, 261, 66, 67, nil, nil, + nil, nil, nil, 259, 290, 294, 92, 91, 93, 94, + nil, nil, 221, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + nil, 90, 98, 99, nil, 84, 85, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 214, + nil, nil, 220, nil, nil, 52, 53, nil, nil, 54, + nil, nil, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 219, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 260, + 261, 66, 67, nil, nil, nil, nil, nil, 259, 290, + 294, 92, 91, 93, 94, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, 263, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, 258, nil, 256, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 219, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 260, 261, 66, 67, nil, nil, + nil, nil, nil, 259, 290, 294, 92, 91, 93, 94, + nil, nil, 221, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + 263, 90, 98, 99, nil, 84, 85, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 214, + nil, nil, 220, nil, nil, 52, 53, nil, nil, 54, + nil, 258, nil, 256, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 219, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 260, + 261, 66, 67, nil, nil, nil, nil, nil, 259, 290, + 294, 92, 91, 93, 94, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 291, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, nil, 90, 98, 99, nil, + 84, 85, nil, nil, 295, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 824, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 260, 261, 66, 67, nil, nil, + nil, nil, nil, 259, 290, 294, 92, 91, 93, 94, + nil, nil, 221, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + nil, 90, 98, 99, nil, 84, 85, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 214, + nil, nil, 220, nil, nil, 52, 53, nil, nil, 54, + nil, nil, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 219, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 23, + 24, 66, 67, nil, nil, nil, nil, nil, 22, 28, + 27, 92, 91, 93, 94, nil, nil, 17, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, nil, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, nil, nil, nil, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 18, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 260, 261, 66, 67, nil, nil, + nil, nil, nil, 259, 290, 294, 92, 91, 93, 94, + nil, nil, 221, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + nil, 90, 98, 99, nil, 84, 85, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 214, + nil, nil, 220, nil, nil, 52, 53, nil, nil, 54, + nil, 588, nil, nil, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 219, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 260, + 261, 66, 67, nil, nil, nil, nil, nil, 259, 290, + 294, 92, 91, 93, 94, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, nil, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, nil, nil, nil, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 219, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 260, 261, 66, 67, nil, nil, + nil, nil, nil, 259, 290, 294, 92, 91, 93, 94, + nil, nil, 221, nil, nil, nil, nil, nil, nil, 291, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + nil, 90, 98, 99, nil, 84, 85, nil, nil, 295, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 868, + nil, nil, 220, nil, nil, 52, 53, nil, nil, 54, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 260, + 261, 66, 67, nil, nil, nil, nil, nil, 259, 290, + 294, 92, 91, 93, 94, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, nil, 90, 98, 99, nil, + 84, 85, 38, 39, 37, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 214, nil, nil, 220, nil, nil, + 52, 53, nil, nil, 54, nil, 588, nil, 256, nil, + 40, nil, nil, nil, nil, nil, nil, nil, 219, nil, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 68, 69, 65, nil, + 51, 56, nil, 77, 57, 58, nil, nil, nil, 61, + nil, 59, 60, 62, 260, 261, 66, 67, nil, nil, + nil, nil, nil, 259, 290, 294, 92, 91, 93, 94, + nil, nil, 221, nil, nil, nil, nil, nil, nil, 41, + nil, nil, 96, 95, 97, 86, 50, 88, 87, 89, + 263, 90, 98, 99, nil, 84, 85, 38, 39, 37, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 214, + nil, nil, 220, nil, nil, 52, 53, nil, nil, 54, + nil, 588, nil, 256, nil, 40, nil, nil, nil, nil, + nil, nil, nil, 219, nil, nil, nil, nil, 83, 75, + 78, 79, nil, 80, 81, nil, nil, nil, 76, 82, + nil, 68, 69, 65, nil, 51, 56, nil, 77, 57, + 58, nil, nil, nil, 61, nil, 59, 60, 62, 260, + 261, 66, 67, nil, nil, nil, nil, nil, 259, 28, + 27, 92, 91, 93, 94, nil, nil, 221, nil, nil, + nil, nil, nil, nil, 41, nil, nil, 96, 95, 97, + 86, 50, 88, 87, 89, 263, 90, 98, 99, nil, + 84, 85, 38, 39, 37, 229, 233, 238, 239, 240, + 235, 237, 245, 246, 241, 242, nil, 222, 223, nil, + nil, 243, 244, nil, 214, nil, -226, 220, nil, nil, + 52, 53, nil, nil, 54, nil, 258, 226, 256, 232, + 40, 228, 227, 224, 225, 236, 234, 230, 219, 231, + nil, nil, nil, 83, 75, 78, 79, nil, 80, 81, + nil, nil, nil, 76, 82, nil, 247, nil, -226, nil, + nil, 56, nil, 77, 162, 173, 163, 186, 159, 179, + 169, 168, 189, 190, 184, 167, 166, 161, 187, 191, + 192, 171, 160, 174, 178, 180, 172, 165, nil, nil, + nil, 181, 188, 183, 182, 175, 185, 170, 158, 177, + 176, nil, nil, nil, nil, nil, 157, 164, 155, 156, + 152, 153, 154, 114, 116, 113, nil, 115, nil, nil, + nil, nil, nil, nil, nil, 147, 148, nil, 144, 126, + 127, 128, 135, 132, 134, nil, nil, 129, 130, nil, + nil, nil, 149, 150, 136, 137, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 141, + 140, nil, 125, 146, 143, 142, 138, 139, 133, 131, + 123, 145, 124, nil, nil, 151, 83, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 82, 162, 173, + 163, 186, 159, 179, 169, 168, 189, 190, 184, 167, + 166, 161, 187, 191, 192, 171, 160, 174, 178, 180, + 172, 165, nil, nil, nil, 181, 188, 183, 182, 175, + 185, 170, 158, 177, 176, nil, nil, nil, nil, nil, + 157, 164, 155, 156, 152, 153, 154, 114, 116, nil, + nil, 115, nil, nil, nil, nil, nil, nil, nil, 147, + 148, nil, 144, 126, 127, 128, 135, 132, 134, nil, + nil, 129, 130, nil, nil, nil, 149, 150, 136, 137, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 141, 140, nil, 125, 146, 143, 142, + 138, 139, 133, 131, 123, 145, 124, nil, nil, 151, + 83, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 82, 162, 173, 163, 186, 159, 179, 169, 168, + 189, 190, 184, 167, 166, 161, 187, 191, 192, 171, + 160, 174, 178, 180, 172, 165, nil, nil, nil, 181, + 188, 183, 182, 175, 185, 170, 158, 177, 176, nil, + nil, nil, nil, nil, 157, 164, 155, 156, 152, 153, + 154, 114, 116, nil, nil, 115, nil, nil, nil, nil, + nil, nil, nil, 147, 148, nil, 144, 126, 127, 128, + 135, 132, 134, nil, nil, 129, 130, nil, nil, nil, + 149, 150, 136, 137, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 141, 140, nil, + 125, 146, 143, 142, 138, 139, 133, 131, 123, 145, + 124, nil, nil, 151, 83, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 82, 162, 173, 163, 186, + 159, 179, 169, 168, 189, 190, 184, 167, 166, 161, + 187, 191, 192, 171, 160, 174, 178, 180, 172, 165, + nil, nil, nil, 181, 188, 183, 182, 175, 185, 170, + 158, 177, 176, nil, nil, nil, nil, nil, 157, 164, + 155, 156, 152, 153, 154, 114, 116, nil, nil, 115, + nil, nil, nil, nil, nil, nil, nil, 147, 148, nil, + 144, 126, 127, 128, 135, 132, 134, nil, nil, 129, + 130, nil, nil, nil, 149, 150, 136, 137, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 141, 140, nil, 125, 146, 143, 142, 138, 139, + 133, 131, 123, 145, 124, nil, nil, 151, 83, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 82, + 162, 173, 163, 186, 159, 179, 169, 168, 189, 190, + 184, 167, 166, 161, 187, 191, 192, 171, 160, 174, + 178, 180, 172, 165, nil, nil, nil, 181, 188, 183, + 351, 350, 352, 349, 158, 177, 176, nil, nil, nil, + nil, nil, 157, 164, 155, 156, 346, 347, 348, 344, + 116, 88, 87, 345, nil, 90, nil, nil, nil, nil, + nil, 147, 148, nil, 144, 126, 127, 128, 135, 132, + 134, nil, nil, 129, 130, nil, nil, nil, 149, 150, + 136, 137, nil, nil, nil, nil, nil, 356, nil, nil, + nil, nil, nil, nil, nil, 141, 140, nil, 125, 146, + 143, 142, 138, 139, 133, 131, 123, 145, 124, nil, + nil, 151, 162, 173, 163, 186, 159, 179, 169, 168, + 189, 190, 184, 167, 166, 161, 187, 191, 192, 171, + 160, 174, 178, 180, 172, 165, nil, nil, nil, 181, + 188, 183, 182, 175, 185, 170, 158, 177, 176, nil, + nil, nil, nil, nil, 157, 164, 155, 156, 152, 153, + 154, 114, 116, nil, nil, 115, nil, nil, nil, nil, + nil, nil, nil, 147, 148, nil, 144, 126, 127, 128, + 135, 132, 134, nil, nil, 129, 130, nil, nil, nil, + 149, 150, 136, 137, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 141, 140, nil, + 125, 146, 143, 142, 138, 139, 133, 131, 123, 145, + 124, 392, 396, 151, nil, 393, nil, nil, nil, nil, + nil, nil, nil, 147, 148, nil, 144, 126, 127, 128, + 135, 132, 134, nil, nil, 129, 130, nil, nil, nil, + 149, 150, 136, 137, nil, nil, nil, nil, nil, 269, + nil, nil, nil, nil, nil, nil, nil, 141, 140, nil, + 125, 146, 143, 142, 138, 139, 133, 131, 123, 145, + 124, 398, 403, 151, nil, 400, nil, nil, nil, nil, + nil, nil, nil, 147, 148, nil, 144, 126, 127, 128, + 135, 132, 134, nil, nil, 129, 130, nil, nil, nil, + 149, 150, 136, 137, nil, nil, nil, nil, nil, 269, + nil, nil, nil, nil, nil, nil, nil, 141, 140, nil, + 125, 146, 143, 142, 138, 139, 133, 131, 123, 145, + 124, 456, 396, 151, nil, 457, nil, nil, nil, nil, + nil, nil, nil, 147, 148, nil, 144, 126, 127, 128, + 135, 132, 134, nil, nil, 129, 130, nil, nil, nil, + 149, 150, 136, 137, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 141, 140, nil, + 125, 146, 143, 142, 138, 139, 133, 131, 123, 145, + 124, 456, 396, 151, nil, 457, nil, nil, nil, nil, + nil, nil, nil, 147, 148, nil, 144, 126, 127, 128, + 135, 132, 134, nil, nil, 129, 130, nil, nil, nil, + 149, 150, 136, 137, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 141, 140, nil, + 125, 146, 143, 142, 138, 139, 133, 131, 123, 145, + 124, 574, 396, 151, nil, 575, nil, nil, nil, nil, + nil, nil, nil, 147, 148, nil, 144, 126, 127, 128, + 135, 132, 134, nil, nil, 129, 130, nil, nil, nil, + 149, 150, 136, 137, nil, nil, nil, nil, nil, 269, + nil, nil, nil, nil, nil, nil, nil, 141, 140, nil, + 125, 146, 143, 142, 138, 139, 133, 131, 123, 145, + 124, 576, 403, 151, nil, 577, nil, nil, nil, nil, + nil, nil, nil, 147, 148, nil, 144, 126, 127, 128, + 135, 132, 134, nil, nil, 129, 130, nil, nil, nil, + 149, 150, 136, 137, nil, nil, nil, nil, nil, 269, + nil, nil, nil, nil, nil, nil, nil, 141, 140, nil, + 125, 146, 143, 142, 138, 139, 133, 131, 123, 145, + 124, 611, 396, 151, nil, 612, nil, nil, nil, nil, + nil, nil, nil, 147, 148, nil, 144, 126, 127, 128, + 135, 132, 134, nil, nil, 129, 130, nil, nil, nil, + 149, 150, 136, 137, nil, nil, nil, nil, nil, 269, + nil, nil, nil, nil, nil, nil, nil, 141, 140, nil, + 125, 146, 143, 142, 138, 139, 133, 131, 123, 145, + 124, 614, 403, 151, nil, 615, nil, nil, nil, nil, + nil, nil, nil, 147, 148, nil, 144, 126, 127, 128, + 135, 132, 134, nil, nil, 129, 130, nil, nil, nil, + 149, 150, 136, 137, nil, nil, nil, nil, nil, 269, + nil, nil, nil, nil, nil, nil, nil, 141, 140, nil, + 125, 146, 143, 142, 138, 139, 133, 131, 123, 145, + 124, 574, 396, 151, nil, 575, nil, nil, nil, nil, + nil, nil, nil, 147, 148, nil, 144, 126, 127, 128, + 135, 132, 134, nil, nil, 129, 130, nil, nil, nil, + 149, 150, 136, 137, nil, nil, nil, nil, nil, 269, + nil, nil, nil, nil, nil, nil, nil, 141, 140, nil, + 125, 146, 143, 142, 138, 139, 133, 131, 123, 145, + 124, 576, 403, 151, nil, 577, nil, nil, nil, nil, + nil, nil, nil, 147, 148, nil, 144, 126, 127, 128, + 135, 132, 134, nil, nil, 129, 130, nil, nil, nil, + 149, 150, 136, 137, nil, nil, nil, nil, nil, 269, + nil, nil, nil, nil, nil, nil, nil, 141, 140, nil, + 125, 146, 143, 142, 138, 139, 133, 131, 123, 145, + 124, 667, 396, 151, nil, 668, nil, nil, nil, nil, + nil, nil, nil, 147, 148, nil, 144, 126, 127, 128, + 135, 132, 134, nil, nil, 129, 130, nil, nil, nil, + 149, 150, 136, 137, nil, nil, nil, nil, nil, 269, + nil, nil, nil, nil, nil, nil, nil, 141, 140, nil, + 125, 146, 143, 142, 138, 139, 133, 131, 123, 145, + 124, 669, 403, 151, nil, 670, nil, nil, nil, nil, + nil, nil, nil, 147, 148, nil, 144, 126, 127, 128, + 135, 132, 134, nil, nil, 129, 130, nil, nil, nil, + 149, 150, 136, 137, nil, nil, nil, nil, nil, 269, + nil, nil, nil, nil, nil, nil, nil, 141, 140, nil, + 125, 146, 143, 142, 138, 139, 133, 131, 123, 145, + 124, 672, 403, 151, nil, 673, nil, nil, nil, nil, + nil, nil, nil, 147, 148, nil, 144, 126, 127, 128, + 135, 132, 134, nil, nil, 129, 130, nil, nil, nil, + 149, 150, 136, 137, nil, nil, nil, nil, nil, 269, + nil, nil, nil, nil, nil, nil, nil, 141, 140, nil, + 125, 146, 143, 142, 138, 139, 133, 131, 123, 145, + 124, 456, 396, 151, nil, 457, nil, nil, nil, nil, + nil, nil, nil, 147, 148, nil, 144, 126, 127, 128, + 135, 132, 134, nil, nil, 129, 130, nil, nil, nil, + 149, 150, 136, 137, nil, nil, nil, nil, nil, 269, + nil, nil, nil, nil, nil, nil, nil, 141, 140, nil, + 125, 146, 143, 142, 138, 139, 133, 131, 123, 145, + 124, 920, 396, 151, nil, 921, nil, nil, nil, nil, + nil, nil, nil, 147, 148, nil, 144, 126, 127, 128, + 135, 132, 134, nil, nil, 129, 130, nil, nil, nil, + 149, 150, 136, 137, nil, nil, nil, nil, nil, 269, + nil, nil, nil, nil, nil, nil, nil, 141, 140, nil, + 125, 146, 143, 142, 138, 139, 133, 131, 123, 145, + 124, 922, 403, 151, nil, 923, nil, nil, nil, nil, + nil, nil, nil, 147, 148, nil, 144, 126, 127, 128, + 135, 132, 134, nil, nil, 129, 130, nil, nil, nil, + 149, 150, 136, 137, nil, nil, nil, nil, nil, 269, + nil, nil, nil, nil, nil, nil, nil, 141, 140, nil, + 125, 146, 143, 142, 138, 139, 133, 131, 123, 145, + 124, 942, 403, 151, nil, 941, nil, nil, nil, nil, + nil, nil, nil, 147, 148, nil, 144, 126, 127, 128, + 135, 132, 134, nil, nil, 129, 130, nil, nil, nil, + 149, 150, 136, 137, nil, nil, nil, nil, nil, 269, + nil, nil, nil, nil, nil, nil, nil, 141, 140, nil, + 125, 146, 143, 142, 138, 139, 133, 131, 123, 145, + 124, nil, nil, 151, 229, 233, 238, 239, 240, 235, + 237, 245, 246, 241, 242, nil, 222, 223, nil, nil, + 243, 244, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 226, nil, 232, nil, + 228, 227, 224, 225, 236, 234, 230, nil, 231, nil, + 229, 233, 238, 239, 240, 235, 237, 245, 246, 241, + 242, nil, 222, 223, nil, 247, 243, 244, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 226, nil, 232, nil, 228, 227, 224, 225, + 236, 234, 230, nil, 231, nil, 229, 233, 238, 239, + 240, 235, 237, 245, 246, 241, 242, nil, 222, 223, + nil, 247, 243, 244, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 226, nil, + 232, nil, 228, 227, 224, 225, 236, 234, 230, nil, + 231, nil, 229, 233, 238, 239, 240, 235, 237, 245, + 246, 241, 242, nil, 222, 223, 210, 247, 243, 244, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 226, nil, 232, nil, 228, 227, + 224, 225, 236, 234, 230, nil, 231, nil, 229, 233, + 238, 239, 240, 235, 237, 245, 246, 241, 242, nil, + 222, 223, nil, 247, 243, 244, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 226, nil, 232, nil, 228, 227, 224, 225, 236, 234, + 230, nil, 231, nil, 229, 233, 238, 239, 240, 235, + 237, 245, 246, 241, 242, nil, 222, 223, nil, 247, + 243, 244, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 226, nil, 232, nil, + 228, 227, 224, 225, 236, 234, 230, nil, 231, nil, + 229, 233, 238, 239, 240, 235, 237, 245, 246, 241, + 242, nil, 222, 223, nil, 247, 243, 244, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 226, nil, 232, nil, 228, 227, 224, 225, + 236, 234, 230, nil, 231, nil, 229, 233, 238, 239, + 240, 235, 237, 245, 246, 241, 242, nil, 222, 223, + nil, 247, 243, 244, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 226, nil, + 232, nil, 228, 227, 224, 225, 236, 234, 230, nil, + 231, nil, 229, 233, 238, 239, 240, 235, 237, 245, + 246, 241, 242, nil, 222, 223, nil, 247, 243, 244, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 226, nil, 232, nil, 228, 227, + 224, 225, 236, 234, 230, nil, 231, nil, 229, 233, + 238, 239, 240, 235, 237, 245, 246, 241, 242, nil, + 222, 223, nil, 247, 243, 244, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 226, nil, 232, nil, 228, 227, 224, 225, 236, 234, + 230, nil, 231, nil, 229, 233, 238, 239, 240, 235, + 237, 245, 246, 241, 242, nil, 222, 223, nil, 247, + 243, 244, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 226, nil, 232, nil, + 228, 227, 224, 225, 236, 234, 230, nil, 231, nil, + 229, 233, 238, 239, 240, 235, 237, 245, 246, 241, + 242, nil, 222, 223, nil, 247, 243, 244, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 226, nil, 232, nil, 228, 227, 224, 225, + 236, 234, 230, nil, 231, nil, 229, 233, 238, 239, + 240, 235, 237, 245, 246, 241, 242, nil, 222, 223, + nil, 247, 243, 244, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 226, nil, + 232, nil, 228, 227, 224, 225, 236, 234, 230, nil, + 231, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 247 ] + +racc_action_check = [ + 86, 0, 0, 0, 0, 0, 0, 86, 86, 86, + 0, 0, 86, 86, 86, 0, 86, 0, 0, 0, + 0, 0, 0, 0, 86, 55, 86, 86, 86, 0, + 0, 0, 0, 0, 0, 0, 86, 86, 0, 86, + 86, 86, 86, 86, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 340, 0, 0, 0, + 320, 0, 0, 0, 0, 0, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 1, 598, 86, 86, 86, 0, 86, 86, 0, 327, + 86, 0, 0, 86, 86, 0, 86, 0, 86, 362, + 86, 0, 86, 86, 86, 86, 86, 86, 86, 0, + 86, 55, 86, 330, 0, 0, 0, 0, 8, 0, + 0, 548, 519, 598, 0, 0, 86, 86, 86, 86, + 89, 86, 0, 86, 0, 86, 86, 89, 89, 89, + 213, 9, 89, 89, 89, 511, 89, 10, 321, 512, + 17, 410, 410, 25, 89, 665, 89, 89, 89, 3, + 25, 340, 362, 632, 3, 667, 89, 89, 668, 89, + 89, 89, 89, 89, 320, 745, 822, 825, 846, 320, + 781, 340, 548, 548, 879, 920, 340, 17, 336, 11, + 213, 548, 336, 215, 327, 669, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 324, 25, 89, 89, 89, 324, 89, 89, 330, 921, + 89, 944, 611, 89, 89, 12, 89, 519, 89, 851, + 89, 851, 89, 89, 89, 89, 89, 89, 89, 398, + 89, 410, 89, 215, 344, 511, 398, 398, 398, 512, + 511, 344, 398, 398, 512, 398, 89, 89, 89, 89, + 669, 89, 321, 89, 398, 89, 89, 321, 632, 665, + 667, 670, 665, 668, 665, 398, 398, 782, 398, 398, + 398, 398, 398, 922, 311, 781, 923, 311, 611, 745, + 822, 825, 846, 20, 745, 822, 825, 846, 879, 920, + 669, 612, 344, 879, 920, 398, 398, 398, 398, 398, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 537, + 537, 398, 398, 398, 611, 398, 34, 611, 416, 398, + 644, 358, 398, 921, 611, 944, 670, 398, 921, 398, + 944, 398, 398, 398, 398, 398, 398, 398, 400, 398, + 398, 398, 531, 531, 574, 400, 400, 400, 575, 36, + 922, 400, 400, 923, 400, 398, 398, 612, 398, 41, + 398, 622, 622, 26, 398, 398, 670, 782, 416, 644, + 292, 334, 782, 100, 400, 400, 14, 400, 400, 400, + 400, 400, 358, 358, 358, 312, 315, 922, 312, 315, + 923, 359, 922, 612, 574, 923, 612, 360, 575, 537, + 15, 15, 193, 612, 400, 400, 400, 400, 400, 400, + 400, 400, 400, 400, 400, 400, 400, 400, 35, 14, + 400, 400, 400, 334, 400, 214, 14, 26, 400, 216, + 334, 400, 531, 335, 292, 334, 400, 531, 400, 334, + 400, 400, 400, 400, 400, 400, 400, 361, 400, 26, + 400, 622, 359, 359, 359, 363, 292, 334, 360, 360, + 360, 35, 446, 576, 400, 400, 724, 400, 35, 400, + 576, 576, 576, 400, 400, 576, 576, 576, 715, 576, + 606, 334, 37, 37, 217, 335, 345, 606, 576, 576, + 576, 576, 335, 345, 221, 631, 446, 335, 631, 576, + 576, 335, 576, 576, 576, 576, 576, 253, 361, 361, + 361, 614, 738, 254, 346, 724, 363, 363, 363, 335, + 465, 346, 530, 257, 466, 295, 295, 530, 715, 576, + 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, + 576, 576, 576, 335, 345, 576, 576, 576, 268, 576, + 576, 279, 595, 576, 465, 281, 576, 576, 466, 576, + 299, 576, 282, 576, 283, 576, 576, 576, 576, 576, + 576, 576, 346, 576, 576, 576, 614, 614, 738, 767, + 347, 767, 767, 767, 767, 767, 595, 347, 13, 576, + 576, 576, 576, 577, 576, 13, 576, 288, 576, 576, + 577, 577, 577, 299, 13, 577, 577, 577, 290, 577, + 299, 309, 309, 614, 738, 42, 614, 738, 422, 577, + 577, 577, 42, 614, 738, 319, 319, 656, 656, 577, + 577, 42, 577, 577, 577, 577, 577, 894, 347, 894, + 894, 894, 894, 894, 348, 291, 13, 113, 294, 349, + 422, 348, 113, 113, 422, 422, 349, 767, 296, 577, + 577, 577, 577, 577, 577, 577, 577, 577, 577, 577, + 577, 577, 577, 42, 300, 577, 577, 577, 301, 577, + 577, 934, 934, 577, 304, 73, 577, 577, 307, 577, + 392, 577, 308, 577, 73, 577, 577, 577, 577, 577, + 577, 577, 348, 577, 73, 577, 582, 349, 582, 582, + 582, 582, 582, 313, 314, 894, 316, 325, 212, 577, + 577, 577, 577, 27, 577, 212, 577, 393, 577, 577, + 27, 27, 27, 392, 212, 27, 27, 27, 326, 27, + 392, 677, 329, 582, 331, 377, 677, 423, 27, 27, + 27, 286, 582, 582, 582, 582, 672, 378, 286, 27, + 27, 384, 27, 27, 27, 27, 27, 286, 386, 723, + 393, 723, 723, 723, 350, 723, 212, 393, 351, 423, + 352, 350, 390, 423, 423, 351, 582, 352, 399, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 412, 424, 27, 27, 27, 672, 286, + 27, 354, 27, 27, 425, 672, 27, 27, 354, 27, + 672, 27, 561, 27, 672, 27, 27, 27, 27, 27, + 27, 27, 350, 27, 27, 27, 351, 287, 352, 426, + 683, 427, 672, 461, 287, 683, 467, 469, 28, 27, + 27, 470, 27, 287, 27, 28, 28, 28, 27, 473, + 28, 28, 28, 475, 28, 561, 672, 480, 484, 354, + 289, 493, 561, 496, 28, 28, 302, 289, 4, 4, + 4, 4, 4, 302, 28, 28, 289, 28, 28, 28, + 28, 28, 302, 508, 866, 287, 866, 866, 866, 647, + 866, 647, 647, 647, 647, 647, 843, 513, 843, 843, + 843, 843, 843, 514, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 289, 545, + 28, 28, 28, 328, 302, 28, 647, 28, 28, 551, + 328, 28, 28, 843, 28, 647, 28, 558, 28, 328, + 28, 28, 28, 28, 28, 28, 28, 562, 28, 565, + 28, 764, 338, 764, 764, 764, 764, 764, 569, 338, + 578, 580, 585, 50, 28, 28, 587, 28, 338, 28, + 50, 50, 50, 28, 599, 50, 50, 50, 601, 50, + 608, 328, 610, 613, 616, 479, 617, 441, 764, 50, + 50, 50, 479, 620, 621, 623, 626, 764, 627, 50, + 50, 479, 50, 50, 50, 50, 50, 634, 635, 636, + 338, 637, 841, 645, 841, 841, 841, 841, 841, 441, + 652, 655, 658, 441, 441, 441, 441, 663, 666, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 479, 675, 50, 50, 50, 680, 841, + 50, 698, 717, 50, 718, 719, 50, 50, 841, 50, + 721, 50, 722, 50, 726, 50, 50, 50, 50, 50, + 50, 50, 734, 50, 735, 50, 736, 737, 752, 522, + 760, 823, 766, 768, 769, 772, 522, 775, 823, 50, + 50, 50, 50, 394, 50, 522, 50, 823, 50, 784, + 394, 394, 394, 788, 789, 394, 394, 394, 506, 394, + 506, 506, 506, 506, 506, 615, 792, 793, 394, 394, + 394, 805, 615, 806, 812, 813, 814, 615, 816, 394, + 394, 615, 394, 394, 394, 394, 394, 522, 824, 823, + 111, 111, 111, 111, 111, 506, 506, 895, 829, 895, + 895, 895, 895, 895, 506, 506, 506, 506, 830, 394, + 394, 394, 394, 394, 394, 394, 394, 394, 394, 394, + 394, 394, 394, 615, 442, 394, 394, 394, 673, 831, + 394, 834, 394, 394, 895, 673, 394, 394, 835, 394, + 673, 394, 837, 394, 673, 394, 394, 394, 394, 394, + 394, 394, 840, 394, 394, 394, 442, 867, 842, 848, + 442, 442, 442, 442, 867, 849, 854, 859, 403, 394, + 394, 860, 394, 867, 394, 403, 403, 403, 394, 861, + 403, 403, 403, 862, 403, 432, 673, 365, 365, 365, + 365, 365, 864, 403, 403, 403, 403, 868, 875, 880, + 881, 432, 432, 896, 403, 403, 917, 403, 403, 403, + 403, 403, 919, 926, 927, 867, 928, 432, 929, 432, + 930, 432, 432, 432, 432, 932, 935, 432, 936, 432, + 937, 938, 939, 940, 403, 403, 403, 403, 403, 403, + 403, 403, 403, 403, 403, 403, 403, 403, 941, 942, + 403, 403, 403, 951, 960, 403, 961, 962, 403, nil, + nil, 403, 403, nil, 403, nil, 403, nil, 403, nil, + 403, 403, 403, 403, 403, 403, 403, nil, 403, 403, + 403, 533, nil, 533, 533, 533, 533, 533, nil, nil, + nil, nil, nil, nil, 403, 403, 403, 403, 404, 403, + nil, 403, nil, 403, nil, 404, 404, 404, nil, nil, + 404, 404, 404, nil, 404, 433, 541, 541, 533, 533, + 541, 541, 541, 404, 404, 404, 404, 533, 533, 533, + 533, 433, 433, nil, 404, 404, nil, 404, 404, 404, + 404, 404, nil, nil, nil, nil, nil, 433, nil, 433, + nil, 433, 433, 433, 433, nil, nil, 433, nil, 433, + nil, nil, nil, nil, 404, 404, 404, 404, 404, 404, + 404, 404, 404, 404, 404, 404, 404, 404, nil, nil, + 404, 404, 404, nil, nil, 404, nil, nil, 404, nil, + nil, 404, 404, nil, 404, nil, 404, nil, 404, nil, + 404, 404, 404, 404, 404, 404, 404, nil, 404, 404, + 404, 633, nil, 633, 633, 633, 633, 633, nil, nil, + nil, nil, nil, nil, 404, 404, 404, 404, 455, 404, + nil, 404, nil, 404, nil, 455, 455, 455, nil, nil, + 455, 455, 455, nil, 455, nil, nil, 931, 633, 931, + 931, 931, 931, 931, 455, nil, nil, 633, 633, 633, + 633, nil, nil, nil, 455, 455, nil, 455, 455, 455, + 455, 455, nil, 933, nil, 933, 933, 933, 933, 933, + nil, nil, nil, 458, 931, nil, nil, nil, nil, nil, + 458, 458, 458, nil, nil, 458, 458, 458, 682, 458, + 682, 682, 682, 682, 682, 455, nil, nil, nil, 458, + 933, nil, 455, nil, nil, nil, nil, 455, 455, 458, + 458, nil, 458, 458, 458, 458, 458, nil, 754, nil, + 754, 754, 754, 754, 754, 682, nil, nil, nil, nil, + 455, nil, nil, nil, 682, 682, 682, 682, nil, nil, + nil, nil, nil, 428, 455, nil, nil, nil, nil, 455, + 458, nil, nil, 455, nil, 754, nil, 458, nil, 428, + 428, nil, 458, 458, 754, 754, 754, 754, 759, nil, + 759, 759, 759, 759, 759, 428, nil, 428, nil, 428, + 428, 428, 428, nil, nil, 458, nil, nil, nil, nil, + nil, nil, nil, 30, 30, 30, 30, 30, 30, 458, + nil, nil, 30, 30, 458, 759, nil, 30, 458, 30, + 30, 30, 30, 30, 30, 30, 759, 759, nil, nil, + nil, 30, 30, 30, 30, 30, 30, 30, nil, 950, + 30, 950, 950, 950, 950, 950, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, nil, 30, + 30, 30, nil, 30, 30, 30, 30, 30, nil, nil, + nil, nil, nil, nil, nil, 803, 950, 803, 803, 803, + 803, 803, nil, nil, nil, nil, nil, 30, nil, nil, + 30, nil, nil, 30, 30, nil, nil, 30, nil, 30, + nil, nil, nil, 30, 886, nil, 886, 886, 886, 886, + 886, 30, 803, nil, nil, nil, 30, 30, 30, 30, + nil, 30, 30, 803, 803, nil, 30, 30, 51, 51, + 51, 51, 51, 51, 30, nil, 30, 51, 51, nil, + nil, 886, 51, nil, 51, 51, 51, 51, 51, 51, + 51, nil, 886, 886, nil, nil, 51, 51, 51, 51, + 51, 51, 51, nil, nil, 51, nil, nil, nil, nil, + nil, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, nil, 51, 51, 51, nil, 51, 51, + 51, 51, 51, nil, nil, nil, nil, nil, nil, nil, + 888, nil, 888, 888, 888, 888, 888, nil, nil, nil, + nil, nil, 51, nil, nil, 51, nil, nil, 51, 51, + nil, nil, 51, nil, 51, nil, nil, nil, 51, 890, + nil, 890, 890, 890, 890, 890, 51, 888, nil, nil, + nil, 51, 51, 51, 51, nil, 51, 51, 888, 888, + nil, 51, 51, 195, 195, 195, 195, 195, 195, 51, + nil, 51, 195, 195, nil, nil, 890, 195, nil, 195, + 195, 195, 195, 195, 195, 195, nil, 890, 890, nil, + nil, 195, 195, 195, 195, 195, 195, 195, nil, nil, + 195, nil, nil, nil, nil, nil, 195, 195, 195, 195, + 195, 195, 195, 195, 195, 195, 195, 195, nil, 195, + 195, 195, nil, 195, 195, 195, 195, 195, nil, nil, + nil, nil, nil, nil, nil, 909, nil, 909, 909, 909, + 909, 909, nil, nil, nil, nil, nil, 195, nil, nil, + 195, nil, nil, 195, 195, nil, nil, 195, nil, 195, + nil, nil, nil, 195, 911, nil, 911, 911, 911, 911, + 911, 195, 909, nil, nil, nil, 195, 195, 195, 195, + nil, 195, 195, 909, 909, nil, 195, 195, 196, 196, + 196, 196, 196, 196, 195, nil, 195, 196, 196, nil, + nil, 911, 196, nil, 196, 196, 196, 196, 196, 196, + 196, nil, 911, 911, nil, nil, 196, 196, 196, 196, + 196, 196, 196, nil, nil, 196, nil, nil, nil, nil, + nil, 196, 196, 196, 196, 196, 196, 196, 196, 196, + 196, 196, 196, nil, 196, 196, 196, nil, 196, 196, + 196, 196, 196, nil, nil, nil, nil, nil, nil, nil, + 946, nil, 946, 946, 946, 946, 946, nil, nil, nil, + nil, nil, 196, nil, nil, 196, nil, nil, 196, 196, + nil, nil, 196, nil, 196, nil, nil, nil, 196, 956, + nil, 956, 956, 956, 956, 956, 196, 946, nil, nil, + nil, 196, 196, 196, 196, nil, 196, 196, 946, 946, + nil, 196, 196, 220, 220, 220, 220, 220, 220, 196, + nil, 196, 220, 220, nil, nil, 956, 220, nil, 220, + 220, 220, 220, 220, 220, 220, nil, 956, 956, nil, + nil, 220, 220, 220, 220, 220, 220, 220, nil, nil, + 220, nil, nil, nil, nil, nil, 220, 220, 220, 220, + 220, 220, 220, 220, 220, 220, 220, 220, nil, 220, + 220, 220, nil, 220, 220, 220, 220, 220, 420, 420, + 420, 420, 420, 420, 420, 420, 420, 420, 420, nil, + 420, 420, nil, nil, 420, 420, nil, 220, nil, nil, + 220, nil, nil, 220, 220, nil, nil, 220, nil, 220, + 420, nil, 420, 220, 420, 420, 420, 420, 420, 420, + 420, 220, 420, nil, nil, nil, 220, 220, 220, 220, + nil, 220, 220, nil, nil, nil, 220, 220, 280, 280, + 280, 280, 280, 280, 220, nil, 220, 280, 280, nil, + nil, nil, 280, nil, 280, 280, 280, 280, 280, 280, + 280, nil, nil, nil, nil, nil, 280, 280, 280, 280, + 280, 280, 280, nil, nil, 280, nil, nil, nil, nil, + nil, 280, 280, 280, 280, 280, 280, 280, 280, 280, + 280, 280, 280, nil, 280, 280, 280, nil, 280, 280, + 280, 280, 280, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, nil, 421, 421, nil, nil, 421, + 421, nil, 280, nil, nil, 280, nil, nil, 280, 280, + nil, nil, 280, nil, 280, 421, nil, 421, 280, 421, + 421, 421, 421, 421, 421, 421, 280, 421, nil, nil, + nil, 280, 280, 280, 280, nil, 280, 280, nil, nil, + nil, 280, 280, 285, 285, 285, 285, 285, 285, 280, + nil, 280, 285, 285, nil, nil, nil, 285, nil, 285, + 285, 285, 285, 285, 285, 285, nil, nil, nil, nil, + nil, 285, 285, 285, 285, 285, 285, 285, nil, nil, + 285, nil, nil, nil, nil, nil, 285, 285, 285, 285, + 285, 285, 285, 285, 285, 285, 285, 285, nil, 285, + 285, 285, nil, 285, 285, 285, 285, 285, 431, 431, + 431, 431, 431, 431, 431, nil, nil, 431, 431, nil, + nil, nil, nil, nil, 431, 431, nil, 285, nil, nil, + 285, nil, nil, 285, 285, nil, nil, 285, nil, 285, + 431, nil, 431, 285, 431, 431, 431, 431, 431, 431, + 431, 285, 431, nil, nil, nil, 285, 285, 285, 285, + nil, 285, 285, nil, nil, nil, 285, 285, 507, 507, + 507, 507, 507, 507, 285, nil, 285, 507, 507, nil, + nil, nil, 507, nil, 507, 507, 507, 507, 507, 507, + 507, nil, nil, nil, nil, nil, 507, 507, 507, 507, + 507, 507, 507, nil, nil, 507, nil, nil, nil, nil, + nil, 507, 507, 507, 507, 507, 507, 507, 507, 507, + 507, 507, 507, nil, 507, 507, 507, nil, 507, 507, + 507, 507, 507, 434, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 434, + 434, nil, 507, nil, nil, 507, nil, nil, 507, 507, + nil, nil, 507, nil, 507, 434, nil, 434, 507, 434, + 434, 434, 434, nil, nil, 434, 507, 434, nil, nil, + nil, 507, 507, 507, 507, nil, 507, 507, nil, nil, + nil, 507, 507, 510, 510, 510, 510, 510, 510, 507, + nil, 507, 510, 510, nil, nil, nil, 510, nil, 510, + 510, 510, 510, 510, 510, 510, nil, nil, nil, nil, + nil, 510, 510, 510, 510, 510, 510, 510, nil, nil, + 510, nil, nil, nil, nil, nil, 510, 510, 510, 510, + 510, 510, 510, 510, 510, 510, 510, 510, nil, 510, + 510, 510, nil, 510, 510, 510, 510, 510, 435, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 435, 435, nil, 510, nil, nil, + 510, nil, nil, 510, 510, nil, nil, 510, nil, 510, + 435, nil, 435, 510, 435, 435, 435, 435, nil, nil, + 435, 510, 435, nil, nil, nil, 510, 510, 510, 510, + nil, 510, 510, nil, nil, nil, 510, 510, 532, 532, + 532, 532, 532, 532, 510, nil, 510, 532, 532, nil, + nil, nil, 532, nil, 532, 532, 532, 532, 532, 532, + 532, nil, nil, nil, nil, nil, 532, 532, 532, 532, + 532, 532, 532, nil, nil, 532, nil, nil, nil, nil, + nil, 532, 532, 532, 532, 532, 532, 532, 532, 532, + 532, 532, 532, nil, 532, 532, 532, nil, 532, 532, + 532, 532, 532, 436, 436, 436, 436, 436, 436, 436, + nil, nil, 436, 436, nil, nil, nil, nil, nil, 436, + 436, nil, 532, nil, nil, 532, nil, nil, 532, 532, + nil, nil, 532, nil, 532, 436, nil, 436, 532, 436, + 436, 436, 436, 436, 436, 436, 532, 436, nil, nil, + nil, 532, 532, 532, 532, nil, 532, 532, nil, nil, + nil, 532, 532, 584, 584, 584, 584, 584, 584, 532, + nil, 532, 584, 584, nil, nil, nil, 584, nil, 584, + 584, 584, 584, 584, 584, 584, nil, nil, nil, nil, + nil, 584, 584, 584, 584, 584, 584, 584, nil, nil, + 584, nil, nil, nil, nil, nil, 584, 584, 584, 584, + 584, 584, 584, 584, 584, 584, 584, 584, nil, 584, + 584, 584, nil, 584, 584, 584, 584, 584, 437, 437, + 437, 437, 437, 437, 437, nil, nil, 437, 437, nil, + nil, nil, nil, nil, 437, 437, nil, 584, nil, nil, + 584, nil, nil, 584, 584, nil, nil, 584, nil, 584, + 437, nil, 437, 584, 437, 437, 437, 437, 437, 437, + 437, 584, 437, nil, nil, nil, 584, 584, 584, 584, + nil, 584, 584, nil, nil, nil, 584, 584, 603, 603, + 603, 603, 603, 603, 584, nil, 584, 603, 603, nil, + nil, nil, 603, nil, 603, 603, 603, 603, 603, 603, + 603, nil, nil, nil, nil, nil, 603, 603, 603, 603, + 603, 603, 603, nil, nil, 603, nil, nil, nil, nil, + nil, 603, 603, 603, 603, 603, 603, 603, 603, 603, + 603, 603, 603, nil, 603, 603, 603, nil, 603, 603, + 603, 603, 603, 438, 438, 438, 438, 438, 438, 438, + nil, nil, 438, 438, nil, nil, nil, nil, nil, 438, + 438, nil, 603, nil, nil, 603, nil, nil, 603, 603, + nil, nil, 603, nil, 603, 438, nil, 438, 603, 438, + 438, 438, 438, 438, 438, 438, 603, 438, nil, nil, + nil, 603, 603, 603, 603, nil, 603, 603, nil, nil, + nil, 603, 603, 604, 604, 604, 604, 604, 604, 603, + nil, 603, 604, 604, nil, nil, nil, 604, nil, 604, + 604, 604, 604, 604, 604, 604, nil, nil, nil, nil, + nil, 604, 604, 604, 604, 604, 604, 604, nil, nil, + 604, nil, nil, nil, nil, nil, 604, 604, 604, 604, + 604, 604, 604, 604, 604, 604, 604, 604, nil, 604, + 604, 604, nil, 604, 604, 604, 604, 604, 439, 439, + 439, 439, 439, 439, 439, nil, nil, 439, 439, nil, + nil, nil, nil, nil, 439, 439, nil, 604, nil, nil, + 604, nil, nil, 604, 604, nil, nil, 604, nil, 604, + 439, nil, 439, 604, 439, 439, 439, 439, 439, 439, + 439, 604, 439, nil, nil, nil, 604, 604, 604, 604, + nil, 604, 604, nil, nil, nil, 604, 604, 625, 625, + 625, 625, 625, 625, 604, nil, 604, 625, 625, nil, + nil, nil, 625, nil, 625, 625, 625, 625, 625, 625, + 625, nil, nil, nil, nil, nil, 625, 625, 625, 625, + 625, 625, 625, nil, nil, 625, nil, nil, nil, nil, + nil, 625, 625, 625, 625, 625, 625, 625, 625, 625, + 625, 625, 625, nil, 625, 625, 625, nil, 625, 625, + 625, 625, 625, 440, 440, 440, 440, 440, 440, 440, + nil, nil, 440, 440, nil, nil, nil, nil, nil, 440, + 440, nil, 625, nil, nil, 625, nil, nil, 625, 625, + nil, nil, 625, nil, 625, 440, nil, 440, 625, 440, + 440, 440, 440, 440, 440, 440, 625, 440, nil, nil, + nil, 625, 625, 625, 625, nil, 625, 625, nil, nil, + nil, 625, 625, 676, 676, 676, 676, 676, 676, 625, + nil, 625, 676, 676, nil, nil, nil, 676, nil, 676, + 676, 676, 676, 676, 676, 676, nil, nil, nil, nil, + nil, 676, 676, 676, 676, 676, 676, 676, nil, nil, + 676, nil, nil, nil, nil, nil, 676, 676, 676, 676, + 676, 676, 676, 676, 676, 676, 676, 676, nil, 676, + 676, 676, nil, 676, 676, 676, 676, 676, 443, 443, + 443, 443, 443, 443, 443, nil, nil, 443, 443, nil, + nil, nil, nil, nil, 443, 443, nil, 676, nil, nil, + 676, nil, nil, 676, 676, nil, nil, 676, nil, 676, + 443, nil, 443, 676, 443, 443, 443, 443, 443, 443, + 443, 676, 443, nil, nil, nil, 676, 676, 676, 676, + nil, 676, 676, nil, nil, nil, 676, 676, 681, 681, + 681, 681, 681, 681, 676, nil, 676, 681, 681, nil, + nil, nil, 681, nil, 681, 681, 681, 681, 681, 681, + 681, nil, nil, nil, nil, nil, 681, 681, 681, 681, + 681, 681, 681, nil, nil, 681, nil, nil, nil, nil, + nil, 681, 681, 681, 681, 681, 681, 681, 681, 681, + 681, 681, 681, nil, 681, 681, 681, nil, 681, 681, + 681, 681, 681, 444, 444, 444, 444, 444, 444, 444, + 444, nil, 444, 444, nil, nil, nil, nil, nil, 444, + 444, nil, 681, nil, nil, 681, nil, nil, 681, 681, + nil, nil, 681, nil, 681, 444, nil, 444, 681, 444, + 444, 444, 444, 444, 444, 444, 681, 444, nil, nil, + nil, 681, 681, 681, 681, nil, 681, 681, nil, nil, + nil, 681, 681, 691, 691, 691, 691, 691, 691, 681, + nil, 681, 691, 691, nil, nil, nil, 691, nil, 691, + 691, 691, 691, 691, 691, 691, nil, nil, nil, nil, + nil, 691, 691, 691, 691, 691, 691, 691, nil, nil, + 691, nil, nil, nil, nil, nil, 691, 691, 691, 691, + 691, 691, 691, 691, 691, 691, 691, 691, nil, 691, + 691, 691, nil, 691, 691, 691, 691, 691, 429, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 429, 429, nil, 691, nil, nil, + 691, nil, nil, 691, 691, nil, nil, 691, nil, 691, + 429, nil, 429, 691, 429, 429, 429, 429, nil, nil, + nil, 691, nil, nil, nil, nil, 691, 691, 691, 691, + nil, 691, 691, nil, nil, nil, 691, 691, 730, 730, + 730, 730, 730, 730, 691, nil, 691, 730, 730, nil, + nil, nil, 730, nil, 730, 730, 730, 730, 730, 730, + 730, nil, nil, nil, nil, nil, 730, 730, 730, 730, + 730, 730, 730, nil, nil, 730, nil, nil, nil, nil, + nil, 730, 730, 730, 730, 730, 730, 730, 730, 730, + 730, 730, 730, nil, 730, 730, 730, nil, 730, 730, + 730, 730, 730, 430, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 430, + 430, nil, 730, nil, nil, 730, nil, nil, 730, 730, + nil, nil, 730, nil, 730, 430, nil, nil, 730, 430, + 430, 430, 430, nil, nil, nil, 730, nil, nil, nil, + nil, 730, 730, 730, 730, nil, 730, 730, nil, nil, + nil, 730, 730, 742, 742, 742, 742, 742, 742, 730, + nil, 730, 742, 742, nil, nil, nil, 742, nil, 742, + 742, 742, 742, 742, 742, 742, nil, nil, nil, nil, + nil, 742, 742, 742, 742, 742, 742, 742, nil, nil, + 742, nil, nil, nil, nil, nil, 742, 742, 742, 742, + 742, 742, 742, 742, 742, 742, 742, 742, nil, 742, + 742, 742, nil, 742, 742, 742, 742, 742, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 742, nil, nil, + 742, nil, nil, 742, 742, nil, nil, 742, nil, 742, + nil, nil, nil, 742, nil, nil, nil, nil, nil, nil, + nil, 742, nil, nil, nil, nil, 742, 742, 742, 742, + nil, 742, 742, nil, nil, nil, 742, 742, 776, 776, + 776, 776, 776, 776, 742, nil, 742, 776, 776, nil, + nil, nil, 776, nil, 776, 776, 776, 776, 776, 776, + 776, nil, nil, nil, nil, nil, 776, 776, 776, 776, + 776, 776, 776, nil, nil, 776, nil, nil, nil, nil, + nil, 776, 776, 776, 776, 776, 776, 776, 776, 776, + 776, 776, 776, nil, 776, 776, 776, nil, 776, 776, + 776, 776, 776, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 776, nil, nil, 776, nil, nil, 776, 776, + nil, nil, 776, nil, 776, nil, nil, nil, 776, nil, + nil, nil, nil, nil, nil, nil, 776, nil, nil, nil, + nil, 776, 776, 776, 776, nil, 776, 776, nil, nil, + nil, 776, 776, 777, 777, 777, 777, 777, 777, 776, + nil, 776, 777, 777, nil, nil, nil, 777, nil, 777, + 777, 777, 777, 777, 777, 777, nil, nil, nil, nil, + nil, 777, 777, 777, 777, 777, 777, 777, nil, nil, + 777, nil, nil, nil, nil, nil, 777, 777, 777, 777, + 777, 777, 777, 777, 777, 777, 777, 777, nil, 777, + 777, 777, nil, 777, 777, 777, 777, 777, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 777, nil, nil, + 777, nil, nil, 777, 777, nil, nil, 777, nil, 777, + nil, nil, nil, 777, nil, nil, nil, nil, nil, nil, + nil, 777, nil, nil, nil, nil, 777, 777, 777, 777, + nil, 777, 777, nil, nil, nil, 777, 777, 780, 780, + 780, 780, 780, 780, 777, nil, 777, 780, 780, nil, + nil, nil, 780, nil, 780, 780, 780, 780, 780, 780, + 780, nil, nil, nil, nil, nil, 780, 780, 780, 780, + 780, 780, 780, nil, nil, 780, nil, nil, nil, nil, + nil, 780, 780, 780, 780, 780, 780, 780, 780, 780, + 780, 780, 780, nil, 780, 780, 780, nil, 780, 780, + 780, 780, 780, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 780, nil, nil, 780, nil, nil, 780, 780, + nil, nil, 780, nil, 780, nil, nil, nil, 780, nil, + nil, nil, nil, nil, nil, nil, 780, nil, nil, nil, + nil, 780, 780, 780, 780, nil, 780, 780, nil, nil, + nil, 780, 780, 786, 786, 786, 786, 786, 786, 780, + nil, 780, 786, 786, nil, nil, nil, 786, nil, 786, + 786, 786, 786, 786, 786, 786, nil, nil, nil, nil, + nil, 786, 786, 786, 786, 786, 786, 786, nil, nil, + 786, nil, nil, nil, nil, nil, 786, 786, 786, 786, + 786, 786, 786, 786, 786, 786, 786, 786, nil, 786, + 786, 786, nil, 786, 786, 786, 786, 786, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 786, nil, nil, + 786, nil, nil, 786, 786, nil, nil, 786, nil, 786, + nil, nil, nil, 786, nil, nil, nil, nil, nil, nil, + nil, 786, nil, nil, nil, nil, 786, 786, 786, 786, + nil, 786, 786, nil, nil, nil, 786, 786, 821, 821, + 821, 821, 821, 821, 786, nil, 786, 821, 821, nil, + nil, nil, 821, nil, 821, 821, 821, 821, 821, 821, + 821, nil, nil, nil, nil, nil, 821, 821, 821, 821, + 821, 821, 821, nil, nil, 821, nil, nil, nil, nil, + nil, 821, 821, 821, 821, 821, 821, 821, 821, 821, + 821, 821, 821, nil, 821, 821, 821, nil, 821, 821, + 821, 821, 821, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 821, nil, nil, 821, nil, nil, 821, 821, + nil, nil, 821, nil, 821, nil, nil, nil, 821, nil, + nil, nil, nil, nil, nil, nil, 821, nil, nil, nil, + nil, 821, 821, 821, 821, nil, 821, 821, nil, nil, + nil, 821, 821, 827, 827, 827, 827, 827, 827, 821, + nil, 821, 827, 827, nil, nil, nil, 827, nil, 827, + 827, 827, 827, 827, 827, 827, nil, nil, nil, nil, + nil, 827, 827, 827, 827, 827, 827, 827, nil, nil, + 827, nil, nil, nil, nil, nil, 827, 827, 827, 827, + 827, 827, 827, 827, 827, 827, 827, 827, nil, 827, + 827, 827, nil, 827, 827, 827, 827, 827, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 827, nil, nil, + 827, nil, nil, 827, 827, nil, nil, 827, nil, 827, + nil, nil, nil, 827, nil, nil, nil, nil, nil, nil, + nil, 827, nil, nil, nil, nil, 827, 827, 827, 827, + nil, 827, 827, nil, nil, nil, 827, 827, 828, 828, + 828, 828, 828, 828, 827, nil, 827, 828, 828, nil, + nil, nil, 828, nil, 828, 828, 828, 828, 828, 828, + 828, nil, nil, nil, nil, nil, 828, 828, 828, 828, + 828, 828, 828, nil, nil, 828, nil, nil, nil, nil, + nil, 828, 828, 828, 828, 828, 828, 828, 828, 828, + 828, 828, 828, nil, 828, 828, 828, nil, 828, 828, + 828, 828, 828, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 828, nil, nil, 828, nil, nil, 828, 828, + nil, nil, 828, nil, 828, nil, nil, nil, 828, nil, + nil, nil, nil, nil, nil, nil, 828, nil, nil, nil, + nil, 828, 828, 828, 828, nil, 828, 828, nil, nil, + nil, 828, 828, 897, 897, 897, 897, 897, 897, 828, + nil, 828, 897, 897, nil, nil, nil, 897, nil, 897, + 897, 897, 897, 897, 897, 897, nil, nil, nil, nil, + nil, 897, 897, 897, 897, 897, 897, 897, nil, nil, + 897, nil, nil, nil, nil, nil, 897, 897, 897, 897, + 897, 897, 897, 897, 897, 897, 897, 897, nil, 897, + 897, 897, nil, 897, 897, 897, 897, 897, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 897, nil, nil, + 897, nil, nil, 897, 897, nil, nil, 897, nil, 897, + nil, nil, nil, 897, nil, nil, nil, nil, nil, nil, + nil, 897, nil, nil, nil, nil, 897, 897, 897, 897, + nil, 897, 897, nil, nil, nil, 897, 897, 903, 903, + 903, 903, 903, 903, 897, nil, 897, 903, 903, nil, + nil, nil, 903, nil, 903, 903, 903, 903, 903, 903, + 903, nil, nil, nil, nil, nil, 903, 903, 903, 903, + 903, 903, 903, nil, nil, 903, nil, nil, nil, nil, + nil, 903, 903, 903, 903, 903, 903, 903, 903, 903, + 903, 903, 903, nil, 903, 903, 903, nil, 903, 903, + 903, 903, 903, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 903, nil, nil, 903, nil, nil, 903, 903, + nil, nil, 903, nil, 903, nil, nil, nil, 903, nil, + nil, nil, nil, nil, nil, nil, 903, nil, nil, nil, + nil, 903, 903, 903, 903, nil, 903, 903, nil, nil, + nil, 903, 903, 905, 905, 905, 905, 905, 905, 903, + nil, 903, 905, 905, nil, nil, nil, 905, nil, 905, + 905, 905, 905, 905, 905, 905, nil, nil, nil, nil, + nil, 905, 905, 905, 905, 905, 905, 905, nil, nil, + 905, nil, nil, nil, nil, nil, 905, 905, 905, 905, + 905, 905, 905, 905, 905, 905, 905, 905, nil, 905, + 905, 905, nil, 905, 905, 905, 905, 905, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 905, nil, nil, + 905, nil, nil, 905, 905, nil, nil, 905, nil, 905, + nil, nil, nil, 905, nil, nil, nil, nil, nil, nil, + nil, 905, nil, nil, nil, nil, 905, 905, 905, 905, + nil, 905, 905, nil, nil, nil, 905, 905, nil, 5, + 5, 5, 5, 5, 905, nil, 905, 5, 5, nil, + nil, nil, 5, nil, 5, 5, 5, 5, 5, 5, + 5, nil, nil, nil, nil, nil, 5, 5, 5, 5, + 5, 5, 5, nil, nil, 5, nil, nil, nil, nil, + nil, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, nil, 5, 5, 5, nil, 5, 5, + 5, 5, 5, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 5, nil, nil, 5, nil, nil, 5, 5, + nil, nil, 5, nil, 5, nil, nil, nil, 5, nil, + nil, nil, nil, nil, nil, nil, 5, nil, nil, nil, + nil, 5, 5, 5, 5, nil, 5, 5, nil, nil, + nil, 5, 5, nil, 18, 18, 18, nil, 18, 5, + nil, 5, 18, 18, nil, nil, nil, 18, nil, 18, + 18, 18, 18, 18, 18, 18, nil, nil, nil, nil, + nil, 18, 18, 18, 18, 18, 18, 18, nil, nil, + 18, nil, nil, nil, nil, nil, nil, 18, nil, nil, + 18, 18, 18, 18, 18, 18, 18, 18, nil, 18, + 18, 18, nil, 18, 18, 18, 18, 18, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 18, nil, nil, + 18, nil, nil, 18, 18, nil, nil, 18, nil, nil, + nil, nil, nil, 18, nil, nil, nil, nil, nil, nil, + nil, 18, nil, nil, nil, nil, 18, 18, 18, 18, + nil, 18, 18, nil, nil, nil, 18, 18, nil, 22, + 22, 22, nil, 22, 18, nil, 18, 22, 22, nil, + nil, nil, 22, nil, 22, 22, 22, 22, 22, 22, + 22, nil, nil, nil, nil, nil, 22, 22, 22, 22, + 22, 22, 22, nil, nil, 22, nil, nil, nil, nil, + nil, nil, 22, nil, nil, 22, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, nil, 22, 22, + 22, 22, 22, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 22, nil, nil, 22, nil, nil, 22, 22, + nil, nil, 22, nil, 22, nil, 22, nil, 22, nil, + nil, nil, nil, nil, nil, nil, 22, nil, nil, nil, + nil, 22, 22, 22, 22, nil, 22, 22, nil, nil, + nil, 22, 22, nil, 23, 23, 23, nil, 23, 22, + nil, 22, 23, 23, nil, nil, nil, 23, nil, 23, + 23, 23, 23, 23, 23, 23, nil, nil, nil, nil, + nil, 23, 23, 23, 23, 23, 23, 23, nil, nil, + 23, nil, nil, nil, nil, nil, nil, 23, nil, nil, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, nil, 23, 23, 23, 23, 23, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 23, nil, nil, + 23, nil, nil, 23, 23, nil, nil, 23, nil, 23, + nil, 23, nil, 23, nil, nil, nil, nil, nil, nil, + nil, 23, nil, nil, nil, nil, 23, 23, 23, 23, + nil, 23, 23, nil, nil, nil, 23, 23, nil, 24, + 24, 24, nil, 24, 23, nil, 23, 24, 24, nil, + nil, nil, 24, nil, 24, 24, 24, 24, 24, 24, + 24, nil, nil, nil, nil, nil, 24, 24, 24, 24, + 24, 24, 24, nil, nil, 24, nil, nil, nil, nil, + nil, nil, 24, nil, nil, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, nil, 24, 24, + 24, 24, 24, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 24, nil, nil, 24, nil, nil, 24, 24, + nil, nil, 24, nil, 24, nil, 24, nil, 24, nil, + nil, nil, nil, nil, nil, nil, 24, nil, nil, nil, + nil, 24, 24, 24, 24, nil, 24, 24, nil, nil, + nil, 24, 24, nil, 31, 31, 31, nil, 31, 24, + nil, 24, 31, 31, nil, nil, nil, 31, nil, 31, + 31, 31, 31, 31, 31, 31, nil, nil, nil, nil, + nil, 31, 31, 31, 31, 31, 31, 31, nil, nil, + 31, nil, nil, nil, nil, nil, nil, 31, nil, nil, + 31, 31, 31, 31, 31, 31, 31, 31, nil, 31, + 31, 31, nil, 31, 31, nil, 756, 31, 756, 756, + 756, 756, 756, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 31, nil, nil, + 31, nil, nil, 31, 31, nil, nil, 31, nil, 31, + nil, nil, nil, 756, nil, nil, nil, nil, nil, nil, + nil, nil, 756, 756, 756, 756, 31, 31, 31, 31, + nil, 31, 31, nil, nil, nil, 31, 31, nil, 32, + 32, 32, nil, 32, 31, nil, 31, 32, 32, nil, + nil, nil, 32, nil, 32, 32, 32, 32, 32, 32, + 32, nil, nil, nil, nil, nil, 32, 32, 32, 32, + 32, 32, 32, nil, nil, 32, nil, nil, nil, nil, + nil, 381, 32, nil, nil, 32, 32, 32, 32, 32, + 32, 32, 32, nil, 32, 32, 32, nil, 32, 32, + nil, nil, 32, nil, 381, 381, 381, 381, 381, 381, + 381, 381, 381, 381, 381, nil, 381, 381, nil, nil, + 381, 381, 32, nil, nil, 32, nil, nil, 32, 32, + nil, nil, 32, nil, nil, nil, 381, nil, 381, nil, + 381, 381, 381, 381, 381, 381, 381, nil, 381, nil, + nil, 32, 32, 32, 32, nil, 32, 32, nil, nil, + nil, 32, 32, nil, nil, 381, 32, 381, nil, 32, + nil, 32, 38, 38, 38, nil, 38, nil, nil, nil, + 38, 38, nil, nil, nil, 38, nil, 38, 38, 38, + 38, 38, 38, 38, nil, nil, nil, nil, nil, 38, + 38, 38, 38, 38, 38, 38, nil, nil, 38, nil, + nil, nil, nil, nil, nil, 38, nil, nil, 38, 38, + 38, 38, 38, 38, 38, 38, nil, 38, 38, 38, + nil, 38, 38, 38, 38, 38, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 38, nil, nil, 38, nil, + nil, 38, 38, nil, nil, 38, nil, nil, nil, nil, + nil, 38, nil, nil, nil, nil, nil, nil, nil, 38, + nil, nil, nil, nil, 38, 38, 38, 38, nil, 38, + 38, nil, nil, nil, 38, 38, nil, 39, 39, 39, + nil, 39, 38, nil, 38, 39, 39, nil, nil, nil, + 39, nil, 39, 39, 39, 39, 39, 39, 39, nil, + nil, nil, nil, nil, 39, 39, 39, 39, 39, 39, + 39, nil, nil, 39, nil, nil, nil, nil, nil, nil, + 39, nil, nil, 39, 39, 39, 39, 39, 39, 39, + 39, nil, 39, 39, 39, nil, 39, 39, 39, 39, + 39, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 39, nil, nil, 39, nil, nil, 39, 39, nil, nil, + 39, nil, nil, nil, nil, nil, 39, nil, nil, nil, + nil, nil, nil, nil, 39, nil, nil, nil, nil, 39, + 39, 39, 39, nil, 39, 39, nil, nil, nil, 39, + 39, nil, 40, 40, 40, nil, 40, 39, nil, 39, + 40, 40, nil, nil, nil, 40, nil, 40, 40, 40, + 40, 40, 40, 40, nil, nil, nil, nil, nil, 40, + 40, 40, 40, 40, 40, 40, nil, nil, 40, nil, + nil, nil, nil, nil, nil, 40, nil, nil, 40, 40, + 40, 40, 40, 40, 40, 40, nil, 40, 40, 40, + nil, 40, 40, 40, 40, 40, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 40, nil, nil, 40, nil, + nil, 40, 40, nil, nil, 40, nil, nil, nil, nil, + nil, 40, nil, nil, nil, nil, nil, nil, nil, 40, + nil, nil, nil, nil, 40, 40, 40, 40, nil, 40, + 40, nil, nil, nil, 40, 40, nil, 52, 52, 52, + nil, 52, 40, nil, 40, 52, 52, nil, nil, nil, + 52, nil, 52, 52, 52, 52, 52, 52, 52, nil, + nil, nil, nil, nil, 52, 52, 52, 52, 52, 52, + 52, nil, nil, 52, nil, nil, nil, nil, nil, nil, + 52, nil, nil, 52, 52, 52, 52, 52, 52, 52, + 52, nil, 52, 52, 52, nil, 52, 52, 52, 52, + 52, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 52, nil, nil, 52, nil, nil, 52, 52, nil, nil, + 52, nil, nil, nil, nil, nil, 52, nil, nil, nil, + nil, nil, nil, nil, 52, nil, nil, nil, nil, 52, + 52, 52, 52, nil, 52, 52, nil, nil, nil, 52, + 52, nil, 53, 53, 53, nil, 53, 52, nil, 52, + 53, 53, nil, nil, nil, 53, nil, 53, 53, 53, + 53, 53, 53, 53, nil, nil, nil, nil, nil, 53, + 53, 53, 53, 53, 53, 53, nil, nil, 53, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 53, 53, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, + nil, 53, 53, 53, 53, 53, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 53, nil, nil, 53, nil, + nil, 53, 53, nil, nil, 53, nil, 53, nil, nil, + nil, 53, nil, nil, nil, nil, nil, nil, nil, 53, + nil, nil, nil, nil, 53, 53, 53, 53, nil, 53, + 53, nil, nil, nil, 53, 53, nil, 54, 54, 54, + nil, 54, 53, nil, 53, 54, 54, nil, nil, nil, + 54, nil, 54, 54, 54, 54, 54, 54, 54, nil, + nil, nil, nil, nil, 54, 54, 54, 54, 54, 54, + 54, nil, nil, 54, nil, nil, nil, nil, nil, nil, + 54, nil, nil, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, nil, 54, 54, 54, 54, + 54, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 54, nil, nil, 54, nil, nil, 54, 54, nil, nil, + 54, nil, nil, nil, nil, nil, 54, nil, nil, nil, + nil, nil, nil, nil, 54, nil, nil, nil, nil, 54, + 54, 54, 54, nil, 54, 54, nil, nil, nil, 54, + 54, nil, 57, 57, 57, nil, 57, 54, nil, 54, + 57, 57, nil, nil, nil, 57, nil, 57, 57, 57, + 57, 57, 57, 57, nil, nil, nil, nil, nil, 57, + 57, 57, 57, 57, 57, 57, nil, nil, 57, nil, + nil, nil, nil, nil, nil, 57, nil, nil, 57, 57, + 57, 57, 57, 57, 57, 57, nil, 57, 57, 57, + nil, 57, 57, 57, 57, 57, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 57, nil, nil, 57, nil, + nil, 57, 57, nil, nil, 57, nil, nil, nil, nil, + nil, 57, nil, nil, nil, nil, nil, nil, nil, 57, + nil, nil, nil, nil, 57, 57, 57, 57, nil, 57, + 57, nil, nil, nil, 57, 57, nil, 58, 58, 58, + nil, 58, 57, nil, 57, 58, 58, nil, nil, nil, + 58, nil, 58, 58, 58, 58, 58, 58, 58, nil, + nil, nil, nil, nil, 58, 58, 58, 58, 58, 58, + 58, nil, nil, 58, nil, nil, nil, nil, nil, nil, + 58, nil, nil, 58, 58, 58, 58, 58, 58, 58, + 58, nil, 58, 58, 58, nil, 58, 58, 58, 58, + 58, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 58, nil, nil, 58, nil, nil, 58, 58, nil, nil, + 58, nil, nil, nil, nil, nil, 58, nil, nil, nil, + nil, nil, nil, nil, 58, nil, nil, nil, nil, 58, + 58, 58, 58, nil, 58, 58, nil, nil, nil, 58, + 58, nil, 61, 61, 61, nil, 61, 58, nil, 58, + 61, 61, nil, nil, nil, 61, nil, 61, 61, 61, + 61, 61, 61, 61, nil, nil, nil, nil, nil, 61, + 61, 61, 61, 61, 61, 61, nil, nil, 61, nil, + nil, nil, nil, 389, nil, 61, nil, nil, 61, 61, + 61, 61, 61, 61, 61, 61, nil, 61, 61, 61, + nil, 61, 61, 61, 61, 61, 389, 389, 389, 389, + 389, 389, 389, 389, 389, 389, 389, nil, 389, 389, + nil, nil, 389, 389, nil, 61, nil, nil, 61, nil, + nil, 61, 61, nil, nil, 61, nil, nil, 389, nil, + 389, 61, 389, 389, 389, 389, 389, 389, 389, 61, + 389, nil, nil, nil, 61, 61, 61, 61, nil, 61, + 61, nil, nil, nil, 61, 61, 61, 389, nil, nil, + nil, 61, 61, nil, 61, 62, 62, 62, nil, 62, + nil, nil, nil, 62, 62, nil, nil, nil, 62, nil, + 62, 62, 62, 62, 62, 62, 62, nil, nil, nil, + nil, nil, 62, 62, 62, 62, 62, 62, 62, nil, + nil, 62, nil, nil, nil, nil, nil, nil, 62, nil, + nil, 62, 62, 62, 62, 62, 62, 62, 62, nil, + 62, 62, 62, nil, 62, 62, nil, 798, 62, 798, + 798, 798, 798, 798, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 62, nil, + nil, 62, nil, nil, 62, 62, nil, nil, 62, nil, + 62, nil, nil, nil, 798, nil, nil, nil, nil, nil, + nil, nil, nil, 798, 798, 798, 798, 62, 62, 62, + 62, nil, 62, 62, nil, nil, nil, 62, 62, nil, + 63, 63, 63, nil, 63, 62, nil, 62, 63, 63, + nil, nil, nil, 63, nil, 63, 63, 63, 63, 63, + 63, 63, nil, nil, nil, nil, nil, 63, 63, 63, + 63, 63, 63, 63, nil, nil, 63, nil, nil, nil, + nil, nil, nil, 63, nil, nil, 63, 63, 63, 63, + 63, 63, 63, 63, nil, 63, 63, 63, nil, 63, + 63, nil, 800, 63, 800, 800, 800, 800, 800, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 63, nil, nil, 63, nil, nil, 63, nil, nil, 63, + 63, nil, nil, 63, nil, nil, nil, nil, nil, 800, + nil, nil, nil, nil, nil, nil, nil, nil, 800, 800, + 800, 800, 63, 63, 63, 63, nil, 63, 63, nil, + nil, nil, 63, 63, nil, 64, 64, 64, nil, 64, + 63, nil, 63, 64, 64, nil, nil, nil, 64, nil, + 64, 64, 64, 64, 64, 64, 64, nil, nil, nil, + nil, nil, 64, 64, 64, 64, 64, 64, 64, nil, + nil, 64, nil, nil, nil, nil, nil, nil, 64, nil, + nil, 64, 64, 64, 64, 64, 64, 64, 64, nil, + 64, 64, 64, nil, 64, 64, nil, 857, 64, 857, + 857, 857, 857, 857, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 64, nil, + nil, 64, nil, nil, 64, 64, nil, nil, 64, nil, + nil, nil, nil, nil, 857, 857, nil, nil, nil, nil, + nil, nil, nil, 857, 857, 857, 857, 64, 64, 64, + 64, nil, 64, 64, nil, nil, nil, 64, 64, nil, + 102, 102, 102, 102, 102, 64, nil, 64, 102, 102, + nil, nil, nil, 102, nil, 102, 102, 102, 102, 102, + 102, 102, nil, nil, nil, nil, nil, 102, 102, 102, + 102, 102, 102, 102, nil, nil, 102, nil, nil, nil, + nil, 579, 102, 102, 102, 102, 102, 102, 102, 102, + 102, 102, 102, 102, nil, 102, 102, 102, nil, 102, + 102, 102, 102, 102, 579, 579, 579, 579, 579, 579, + 579, 579, 579, 579, 579, nil, 579, 579, nil, nil, + 579, 579, nil, 102, nil, nil, 102, nil, nil, 102, + 102, nil, nil, 102, nil, 102, 579, nil, 579, 102, + 579, 579, 579, 579, 579, 579, 579, 102, 579, nil, + nil, nil, 102, 102, 102, 102, nil, 102, 102, nil, + nil, nil, 102, 102, nil, 579, nil, nil, nil, 102, + 102, nil, 102, 106, 106, 106, nil, 106, nil, nil, + nil, 106, 106, nil, nil, nil, 106, nil, 106, 106, + 106, 106, 106, 106, 106, nil, nil, nil, nil, nil, + 106, 106, 106, 106, 106, 106, 106, nil, nil, 106, + nil, nil, nil, nil, nil, nil, 106, nil, nil, 106, + 106, 106, 106, 106, 106, 106, 106, nil, 106, 106, + 106, nil, 106, 106, 106, 106, 106, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 106, nil, nil, 106, + nil, nil, 106, 106, nil, nil, 106, nil, nil, nil, + nil, nil, 106, nil, nil, nil, nil, nil, nil, nil, + 106, nil, nil, nil, nil, 106, 106, 106, 106, nil, + 106, 106, nil, nil, nil, 106, 106, nil, 107, 107, + 107, nil, 107, 106, nil, 106, 107, 107, nil, nil, + nil, 107, nil, 107, 107, 107, 107, 107, 107, 107, + nil, nil, nil, nil, nil, 107, 107, 107, 107, 107, + 107, 107, nil, nil, 107, nil, nil, nil, nil, nil, + nil, 107, nil, nil, 107, 107, 107, 107, 107, 107, + 107, 107, nil, 107, 107, 107, nil, 107, 107, 107, + 107, 107, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 107, nil, nil, 107, nil, nil, 107, 107, nil, + nil, 107, nil, nil, nil, nil, nil, 107, nil, nil, + nil, nil, nil, nil, nil, 107, nil, nil, nil, nil, + 107, 107, 107, 107, nil, 107, 107, nil, nil, nil, + 107, 107, nil, 108, 108, 108, nil, 108, 107, nil, + 107, 108, 108, nil, nil, nil, 108, nil, 108, 108, + 108, 108, 108, 108, 108, nil, nil, nil, nil, nil, + 108, 108, 108, 108, 108, 108, 108, nil, nil, 108, + nil, nil, nil, nil, nil, nil, 108, nil, nil, 108, + 108, 108, 108, 108, 108, 108, 108, nil, 108, 108, + 108, nil, 108, 108, 108, 108, 108, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 108, nil, nil, 108, + nil, nil, 108, 108, nil, nil, 108, nil, nil, nil, + nil, nil, 108, nil, nil, nil, nil, nil, nil, nil, + 108, nil, nil, nil, nil, 108, 108, 108, 108, nil, + 108, 108, nil, nil, nil, 108, 108, nil, 109, 109, + 109, nil, 109, 108, nil, 108, 109, 109, nil, nil, + nil, 109, nil, 109, 109, 109, 109, 109, 109, 109, + nil, nil, nil, nil, nil, 109, 109, 109, 109, 109, + 109, 109, nil, nil, 109, nil, nil, nil, nil, nil, + nil, 109, nil, nil, 109, 109, 109, 109, 109, 109, + 109, 109, nil, 109, 109, 109, nil, 109, 109, 109, + 109, 109, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 109, nil, nil, 109, nil, nil, 109, 109, nil, + nil, 109, nil, nil, nil, nil, nil, 109, nil, nil, + nil, nil, nil, nil, nil, 109, nil, nil, nil, nil, + 109, 109, 109, 109, nil, 109, 109, nil, nil, nil, + 109, 109, nil, 110, 110, 110, 110, 110, 109, nil, + 109, 110, 110, nil, nil, nil, 110, nil, 110, 110, + 110, 110, 110, 110, 110, nil, nil, nil, nil, nil, + 110, 110, 110, 110, 110, 110, 110, nil, nil, 110, + nil, nil, nil, nil, nil, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 110, nil, 110, 110, + 110, nil, 110, 110, 110, 110, 110, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 110, nil, nil, 110, + nil, nil, 110, 110, nil, nil, 110, nil, 110, nil, + nil, nil, 110, nil, nil, nil, nil, nil, nil, nil, + 110, nil, nil, nil, nil, 110, 110, 110, 110, nil, + 110, 110, nil, nil, nil, 110, 110, nil, 197, 197, + 197, nil, 197, 110, nil, 110, 197, 197, nil, nil, + nil, 197, nil, 197, 197, 197, 197, 197, 197, 197, + nil, nil, nil, nil, nil, 197, 197, 197, 197, 197, + 197, 197, nil, nil, 197, nil, nil, nil, nil, nil, + nil, 197, nil, nil, 197, 197, 197, 197, 197, 197, + 197, 197, nil, 197, 197, 197, nil, 197, 197, 197, + 197, 197, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 197, nil, nil, 197, nil, nil, 197, 197, nil, + nil, 197, nil, 197, nil, nil, nil, 197, nil, nil, + nil, nil, nil, nil, nil, 197, nil, nil, nil, nil, + 197, 197, 197, 197, nil, 197, 197, nil, nil, nil, + 197, 197, nil, 198, 198, 198, nil, 198, 197, nil, + 197, 198, 198, nil, nil, nil, 198, nil, 198, 198, + 198, 198, 198, 198, 198, nil, nil, nil, nil, nil, + 198, 198, 198, 198, 198, 198, 198, nil, nil, 198, + nil, nil, nil, nil, nil, nil, 198, nil, nil, 198, + 198, 198, 198, 198, 198, 198, 198, nil, 198, 198, + 198, nil, 198, 198, 198, 198, 198, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 198, nil, nil, 198, + nil, nil, 198, 198, nil, nil, 198, nil, 198, nil, + nil, nil, 198, nil, nil, nil, nil, nil, nil, nil, + 198, nil, nil, nil, nil, 198, 198, 198, 198, nil, + 198, 198, nil, nil, nil, 198, 198, nil, 199, 199, + 199, nil, 199, 198, nil, 198, 199, 199, nil, nil, + nil, 199, nil, 199, 199, 199, 199, 199, 199, 199, + nil, nil, nil, nil, nil, 199, 199, 199, 199, 199, + 199, 199, nil, nil, 199, nil, nil, nil, nil, nil, + nil, 199, nil, nil, 199, 199, 199, 199, 199, 199, + 199, 199, nil, 199, 199, 199, nil, 199, 199, 199, + 199, 199, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 199, nil, nil, 199, nil, nil, 199, 199, nil, + nil, 199, nil, nil, nil, nil, nil, 199, nil, nil, + nil, nil, nil, nil, nil, 199, nil, nil, nil, nil, + 199, 199, 199, 199, nil, 199, 199, nil, nil, nil, + 199, 199, nil, 200, 200, 200, nil, 200, 199, nil, + 199, 200, 200, nil, nil, nil, 200, nil, 200, 200, + 200, 200, 200, 200, 200, nil, nil, nil, nil, nil, + 200, 200, 200, 200, 200, 200, 200, nil, nil, 200, + nil, nil, nil, nil, nil, nil, 200, nil, nil, 200, + 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, + 200, nil, 200, 200, 200, 200, 200, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 200, nil, nil, 200, + nil, nil, 200, 200, nil, nil, 200, nil, 200, nil, + 200, nil, 200, nil, nil, nil, nil, nil, nil, nil, + 200, nil, nil, nil, nil, 200, 200, 200, 200, nil, + 200, 200, nil, nil, nil, 200, 200, nil, 205, 205, + 205, nil, 205, 200, nil, 200, 205, 205, nil, nil, + nil, 205, nil, 205, 205, 205, 205, 205, 205, 205, + nil, nil, nil, nil, nil, 205, 205, 205, 205, 205, + 205, 205, nil, nil, 205, nil, nil, nil, nil, nil, + nil, 205, nil, nil, 205, 205, 205, 205, 205, 205, + 205, 205, nil, 205, 205, 205, nil, 205, 205, 205, + 205, 205, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 205, nil, nil, 205, nil, nil, 205, 205, nil, + nil, 205, nil, nil, nil, nil, nil, 205, nil, nil, + nil, nil, nil, nil, nil, 205, nil, nil, nil, nil, + 205, 205, 205, 205, nil, 205, 205, nil, nil, nil, + 205, 205, nil, 206, 206, 206, nil, 206, 205, nil, + 205, 206, 206, nil, nil, nil, 206, nil, 206, 206, + 206, 206, 206, 206, 206, nil, nil, nil, nil, nil, + 206, 206, 206, 206, 206, 206, 206, nil, nil, 206, + nil, nil, nil, nil, nil, nil, 206, nil, nil, 206, + 206, 206, 206, 206, 206, 206, 206, nil, 206, 206, + 206, nil, 206, 206, 206, 206, 206, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 206, nil, nil, 206, + nil, nil, 206, 206, nil, nil, 206, nil, nil, nil, + nil, nil, 206, nil, nil, nil, nil, nil, nil, nil, + 206, nil, nil, nil, nil, 206, 206, 206, 206, nil, + 206, 206, nil, nil, nil, 206, 206, nil, 207, 207, + 207, nil, 207, 206, nil, 206, 207, 207, nil, nil, + nil, 207, nil, 207, 207, 207, 207, 207, 207, 207, + nil, nil, nil, nil, nil, 207, 207, 207, 207, 207, + 207, 207, nil, nil, 207, nil, nil, nil, nil, nil, + nil, 207, nil, nil, 207, 207, 207, 207, 207, 207, + 207, 207, nil, 207, 207, 207, nil, 207, 207, 207, + 207, 207, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 207, nil, nil, 207, nil, nil, 207, 207, nil, + nil, 207, nil, nil, nil, nil, nil, 207, nil, nil, + nil, nil, nil, nil, nil, 207, nil, nil, nil, nil, + 207, 207, 207, 207, nil, 207, 207, nil, nil, nil, + 207, 207, nil, 208, 208, 208, nil, 208, 207, nil, + 207, 208, 208, nil, nil, nil, 208, nil, 208, 208, + 208, 208, 208, 208, 208, nil, nil, nil, nil, nil, + 208, 208, 208, 208, 208, 208, 208, nil, nil, 208, + nil, nil, nil, nil, nil, nil, 208, nil, nil, 208, + 208, 208, 208, 208, 208, 208, 208, nil, 208, 208, + 208, nil, 208, 208, 208, 208, 208, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 208, nil, nil, 208, + nil, nil, 208, 208, nil, nil, 208, nil, nil, nil, + nil, nil, 208, nil, nil, nil, nil, nil, nil, nil, + 208, nil, nil, nil, nil, 208, 208, 208, 208, nil, + 208, 208, nil, nil, nil, 208, 208, nil, 209, 209, + 209, nil, 209, 208, nil, 208, 209, 209, nil, nil, + nil, 209, nil, 209, 209, 209, 209, 209, 209, 209, + nil, nil, nil, nil, nil, 209, 209, 209, 209, 209, + 209, 209, nil, nil, 209, nil, nil, nil, nil, nil, + nil, 209, nil, nil, 209, 209, 209, 209, 209, 209, + 209, 209, nil, 209, 209, 209, nil, 209, 209, 209, + 209, 209, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 209, nil, nil, 209, nil, nil, 209, 209, nil, + nil, 209, nil, nil, nil, nil, nil, 209, nil, nil, + nil, nil, nil, nil, nil, 209, nil, nil, nil, nil, + 209, 209, 209, 209, nil, 209, 209, nil, nil, nil, + 209, 209, 209, 219, 219, 219, nil, 219, 209, nil, + 209, 219, 219, nil, nil, nil, 219, nil, 219, 219, + 219, 219, 219, 219, 219, nil, nil, nil, nil, nil, + 219, 219, 219, 219, 219, 219, 219, nil, nil, 219, + nil, nil, nil, nil, nil, nil, 219, nil, nil, 219, + 219, 219, 219, 219, 219, 219, 219, nil, 219, 219, + 219, nil, 219, 219, 219, 219, 219, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 219, nil, nil, 219, + nil, nil, 219, 219, nil, nil, 219, nil, nil, nil, + nil, nil, 219, nil, nil, nil, nil, nil, nil, nil, + 219, nil, nil, nil, nil, 219, 219, 219, 219, nil, + 219, 219, nil, nil, nil, 219, 219, nil, 222, 222, + 222, nil, 222, 219, nil, 219, 222, 222, nil, nil, + nil, 222, nil, 222, 222, 222, 222, 222, 222, 222, + nil, nil, nil, nil, nil, 222, 222, 222, 222, 222, + 222, 222, nil, nil, 222, nil, nil, nil, nil, nil, + nil, 222, nil, nil, 222, 222, 222, 222, 222, 222, + 222, 222, nil, 222, 222, 222, nil, 222, 222, 222, + 222, 222, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 222, nil, nil, 222, nil, nil, 222, 222, nil, + nil, 222, nil, nil, nil, nil, nil, 222, nil, nil, + nil, nil, nil, nil, nil, 222, nil, nil, nil, nil, + 222, 222, 222, 222, nil, 222, 222, nil, nil, nil, + 222, 222, nil, 223, 223, 223, nil, 223, 222, nil, + 222, 223, 223, nil, nil, nil, 223, nil, 223, 223, + 223, 223, 223, 223, 223, nil, nil, nil, nil, nil, + 223, 223, 223, 223, 223, 223, 223, nil, nil, 223, + nil, nil, nil, nil, nil, nil, 223, nil, nil, 223, + 223, 223, 223, 223, 223, 223, 223, nil, 223, 223, + 223, nil, 223, 223, 223, 223, 223, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 223, nil, nil, 223, + nil, nil, 223, 223, nil, nil, 223, nil, nil, nil, + nil, nil, 223, nil, nil, nil, nil, nil, nil, nil, + 223, nil, nil, nil, nil, 223, 223, 223, 223, nil, + 223, 223, nil, nil, nil, 223, 223, nil, 224, 224, + 224, nil, 224, 223, nil, 223, 224, 224, nil, nil, + nil, 224, nil, 224, 224, 224, 224, 224, 224, 224, + nil, nil, nil, nil, nil, 224, 224, 224, 224, 224, + 224, 224, nil, nil, 224, nil, nil, nil, nil, nil, + nil, 224, nil, nil, 224, 224, 224, 224, 224, 224, + 224, 224, nil, 224, 224, 224, nil, 224, 224, 224, + 224, 224, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 224, nil, nil, 224, nil, nil, 224, 224, nil, + nil, 224, nil, nil, nil, nil, nil, 224, nil, nil, + nil, nil, nil, nil, nil, 224, nil, nil, nil, nil, + 224, 224, 224, 224, nil, 224, 224, nil, nil, nil, + 224, 224, nil, 225, 225, 225, nil, 225, 224, nil, + 224, 225, 225, nil, nil, nil, 225, nil, 225, 225, + 225, 225, 225, 225, 225, nil, nil, nil, nil, nil, + 225, 225, 225, 225, 225, 225, 225, nil, nil, 225, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 225, + 225, 225, 225, 225, 225, 225, 225, nil, 225, 225, + 225, nil, 225, 225, 225, 225, 225, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 225, nil, nil, 225, + nil, nil, 225, 225, nil, nil, 225, nil, nil, nil, + nil, nil, 225, nil, nil, nil, nil, nil, nil, nil, + 225, nil, nil, nil, nil, 225, 225, 225, 225, nil, + 225, 225, nil, nil, nil, 225, 225, nil, 226, 226, + 226, nil, 226, 225, nil, 225, 226, 226, nil, nil, + nil, 226, nil, 226, 226, 226, 226, 226, 226, 226, + nil, nil, nil, nil, nil, 226, 226, 226, 226, 226, + 226, 226, nil, nil, 226, nil, nil, nil, nil, nil, + nil, 226, nil, nil, 226, 226, 226, 226, 226, 226, + 226, 226, nil, 226, 226, 226, nil, 226, 226, 226, + 226, 226, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 226, nil, nil, 226, nil, nil, 226, 226, nil, + nil, 226, nil, nil, nil, nil, nil, 226, nil, nil, + nil, nil, nil, nil, nil, 226, nil, nil, nil, nil, + 226, 226, 226, 226, nil, 226, 226, nil, nil, nil, + 226, 226, nil, 227, 227, 227, nil, 227, 226, nil, + 226, 227, 227, nil, nil, nil, 227, nil, 227, 227, + 227, 227, 227, 227, 227, nil, nil, nil, nil, nil, + 227, 227, 227, 227, 227, 227, 227, nil, nil, 227, + nil, nil, nil, nil, nil, nil, 227, nil, nil, 227, + 227, 227, 227, 227, 227, 227, 227, nil, 227, 227, + 227, nil, 227, 227, 227, 227, 227, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 227, nil, nil, 227, + nil, nil, 227, 227, nil, nil, 227, nil, nil, nil, + nil, nil, 227, nil, nil, nil, nil, nil, nil, nil, + 227, nil, nil, nil, nil, 227, 227, 227, 227, nil, + 227, 227, nil, nil, nil, 227, 227, nil, 228, 228, + 228, nil, 228, 227, nil, 227, 228, 228, nil, nil, + nil, 228, nil, 228, 228, 228, 228, 228, 228, 228, + nil, nil, nil, nil, nil, 228, 228, 228, 228, 228, + 228, 228, nil, nil, 228, nil, nil, nil, nil, nil, + nil, 228, nil, nil, 228, 228, 228, 228, 228, 228, + 228, 228, nil, 228, 228, 228, nil, 228, 228, 228, + 228, 228, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 228, nil, nil, 228, nil, nil, 228, 228, nil, + nil, 228, nil, nil, nil, nil, nil, 228, nil, nil, + nil, nil, nil, nil, nil, 228, nil, nil, nil, nil, + 228, 228, 228, 228, nil, 228, 228, nil, nil, nil, + 228, 228, nil, 229, 229, 229, nil, 229, 228, nil, + 228, 229, 229, nil, nil, nil, 229, nil, 229, 229, + 229, 229, 229, 229, 229, nil, nil, nil, nil, nil, + 229, 229, 229, 229, 229, 229, 229, nil, nil, 229, + nil, nil, nil, nil, nil, nil, 229, nil, nil, 229, + 229, 229, 229, 229, 229, 229, 229, nil, 229, 229, + 229, nil, 229, 229, 229, 229, 229, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 229, nil, nil, 229, + nil, nil, 229, 229, nil, nil, 229, nil, nil, nil, + nil, nil, 229, nil, nil, nil, nil, nil, nil, nil, + 229, nil, nil, nil, nil, 229, 229, 229, 229, nil, + 229, 229, nil, nil, nil, 229, 229, nil, 230, 230, + 230, nil, 230, 229, nil, 229, 230, 230, nil, nil, + nil, 230, nil, 230, 230, 230, 230, 230, 230, 230, + nil, nil, nil, nil, nil, 230, 230, 230, 230, 230, + 230, 230, nil, nil, 230, nil, nil, nil, nil, nil, + nil, 230, nil, nil, 230, 230, 230, 230, 230, 230, + 230, 230, nil, 230, 230, 230, nil, 230, 230, 230, + 230, 230, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 230, nil, nil, 230, nil, nil, 230, 230, nil, + nil, 230, nil, nil, nil, nil, nil, 230, nil, nil, + nil, nil, nil, nil, nil, 230, nil, nil, nil, nil, + 230, 230, 230, 230, nil, 230, 230, nil, nil, nil, + 230, 230, nil, 231, 231, 231, nil, 231, 230, nil, + 230, 231, 231, nil, nil, nil, 231, nil, 231, 231, + 231, 231, 231, 231, 231, nil, nil, nil, nil, nil, + 231, 231, 231, 231, 231, 231, 231, nil, nil, 231, + nil, nil, nil, nil, nil, nil, 231, nil, nil, 231, + 231, 231, 231, 231, 231, 231, 231, nil, 231, 231, + 231, nil, 231, 231, 231, 231, 231, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 231, nil, nil, 231, + nil, nil, 231, 231, nil, nil, 231, nil, nil, nil, + nil, nil, 231, nil, nil, nil, nil, nil, nil, nil, + 231, nil, nil, nil, nil, 231, 231, 231, 231, nil, + 231, 231, nil, nil, nil, 231, 231, nil, 232, 232, + 232, nil, 232, 231, nil, 231, 232, 232, nil, nil, + nil, 232, nil, 232, 232, 232, 232, 232, 232, 232, + nil, nil, nil, nil, nil, 232, 232, 232, 232, 232, + 232, 232, nil, nil, 232, nil, nil, nil, nil, nil, + nil, 232, nil, nil, 232, 232, 232, 232, 232, 232, + 232, 232, nil, 232, 232, 232, nil, 232, 232, 232, + 232, 232, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 232, nil, nil, 232, nil, nil, 232, 232, nil, + nil, 232, nil, nil, nil, nil, nil, 232, nil, nil, + nil, nil, nil, nil, nil, 232, nil, nil, nil, nil, + 232, 232, 232, 232, nil, 232, 232, nil, nil, nil, + 232, 232, nil, 233, 233, 233, nil, 233, 232, nil, + 232, 233, 233, nil, nil, nil, 233, nil, 233, 233, + 233, 233, 233, 233, 233, nil, nil, nil, nil, nil, + 233, 233, 233, 233, 233, 233, 233, nil, nil, 233, + nil, nil, nil, nil, nil, nil, 233, nil, nil, 233, + 233, 233, 233, 233, 233, 233, 233, nil, 233, 233, + 233, nil, 233, 233, 233, 233, 233, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 233, nil, nil, 233, + nil, nil, 233, 233, nil, nil, 233, nil, nil, nil, + nil, nil, 233, nil, nil, nil, nil, nil, nil, nil, + 233, nil, nil, nil, nil, 233, 233, 233, 233, nil, + 233, 233, nil, nil, nil, 233, 233, nil, 234, 234, + 234, nil, 234, 233, nil, 233, 234, 234, nil, nil, + nil, 234, nil, 234, 234, 234, 234, 234, 234, 234, + nil, nil, nil, nil, nil, 234, 234, 234, 234, 234, + 234, 234, nil, nil, 234, nil, nil, nil, nil, nil, + nil, 234, nil, nil, 234, 234, 234, 234, 234, 234, + 234, 234, nil, 234, 234, 234, nil, 234, 234, 234, + 234, 234, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 234, nil, nil, 234, nil, nil, 234, 234, nil, + nil, 234, nil, nil, nil, nil, nil, 234, nil, nil, + nil, nil, nil, nil, nil, 234, nil, nil, nil, nil, + 234, 234, 234, 234, nil, 234, 234, nil, nil, nil, + 234, 234, nil, 235, 235, 235, nil, 235, 234, nil, + 234, 235, 235, nil, nil, nil, 235, nil, 235, 235, + 235, 235, 235, 235, 235, nil, nil, nil, nil, nil, + 235, 235, 235, 235, 235, 235, 235, nil, nil, 235, + nil, nil, nil, nil, nil, nil, 235, nil, nil, 235, + 235, 235, 235, 235, 235, 235, 235, nil, 235, 235, + 235, nil, 235, 235, 235, 235, 235, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 235, nil, nil, 235, + nil, nil, 235, 235, nil, nil, 235, nil, nil, nil, + nil, nil, 235, nil, nil, nil, nil, nil, nil, nil, + 235, nil, nil, nil, nil, 235, 235, 235, 235, nil, + 235, 235, nil, nil, nil, 235, 235, nil, 236, 236, + 236, nil, 236, 235, nil, 235, 236, 236, nil, nil, + nil, 236, nil, 236, 236, 236, 236, 236, 236, 236, + nil, nil, nil, nil, nil, 236, 236, 236, 236, 236, + 236, 236, nil, nil, 236, nil, nil, nil, nil, nil, + nil, 236, nil, nil, 236, 236, 236, 236, 236, 236, + 236, 236, nil, 236, 236, 236, nil, 236, 236, 236, + 236, 236, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 236, nil, nil, 236, nil, nil, 236, 236, nil, + nil, 236, nil, nil, nil, nil, nil, 236, nil, nil, + nil, nil, nil, nil, nil, 236, nil, nil, nil, nil, + 236, 236, 236, 236, nil, 236, 236, nil, nil, nil, + 236, 236, nil, 237, 237, 237, nil, 237, 236, nil, + 236, 237, 237, nil, nil, nil, 237, nil, 237, 237, + 237, 237, 237, 237, 237, nil, nil, nil, nil, nil, + 237, 237, 237, 237, 237, 237, 237, nil, nil, 237, + nil, nil, nil, nil, nil, nil, 237, nil, nil, 237, + 237, 237, 237, 237, 237, 237, 237, nil, 237, 237, + 237, nil, 237, 237, 237, 237, 237, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 237, nil, nil, 237, + nil, nil, 237, 237, nil, nil, 237, nil, nil, nil, + nil, nil, 237, nil, nil, nil, nil, nil, nil, nil, + 237, nil, nil, nil, nil, 237, 237, 237, 237, nil, + 237, 237, nil, nil, nil, 237, 237, nil, 238, 238, + 238, nil, 238, 237, nil, 237, 238, 238, nil, nil, + nil, 238, nil, 238, 238, 238, 238, 238, 238, 238, + nil, nil, nil, nil, nil, 238, 238, 238, 238, 238, + 238, 238, nil, nil, 238, nil, nil, nil, nil, nil, + nil, 238, nil, nil, 238, 238, 238, 238, 238, 238, + 238, 238, nil, 238, 238, 238, nil, 238, 238, 238, + 238, 238, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 238, nil, nil, 238, nil, nil, 238, 238, nil, + nil, 238, nil, nil, nil, nil, nil, 238, nil, nil, + nil, nil, nil, nil, nil, 238, nil, nil, nil, nil, + 238, 238, 238, 238, nil, 238, 238, nil, nil, nil, + 238, 238, nil, 239, 239, 239, nil, 239, 238, nil, + 238, 239, 239, nil, nil, nil, 239, nil, 239, 239, + 239, 239, 239, 239, 239, nil, nil, nil, nil, nil, + 239, 239, 239, 239, 239, 239, 239, nil, nil, 239, + nil, nil, nil, nil, nil, nil, 239, nil, nil, 239, + 239, 239, 239, 239, 239, 239, 239, nil, 239, 239, + 239, nil, 239, 239, 239, 239, 239, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 239, nil, nil, 239, + nil, nil, 239, 239, nil, nil, 239, nil, nil, nil, + nil, nil, 239, nil, nil, nil, nil, nil, nil, nil, + 239, nil, nil, nil, nil, 239, 239, 239, 239, nil, + 239, 239, nil, nil, nil, 239, 239, nil, 240, 240, + 240, nil, 240, 239, nil, 239, 240, 240, nil, nil, + nil, 240, nil, 240, 240, 240, 240, 240, 240, 240, + nil, nil, nil, nil, nil, 240, 240, 240, 240, 240, + 240, 240, nil, nil, 240, nil, nil, nil, nil, nil, + nil, 240, nil, nil, 240, 240, 240, 240, 240, 240, + 240, 240, nil, 240, 240, 240, nil, 240, 240, 240, + 240, 240, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 240, nil, nil, 240, nil, nil, 240, 240, nil, + nil, 240, nil, nil, nil, nil, nil, 240, nil, nil, + nil, nil, nil, nil, nil, 240, nil, nil, nil, nil, + 240, 240, 240, 240, nil, 240, 240, nil, nil, nil, + 240, 240, nil, 241, 241, 241, nil, 241, 240, nil, + 240, 241, 241, nil, nil, nil, 241, nil, 241, 241, + 241, 241, 241, 241, 241, nil, nil, nil, nil, nil, + 241, 241, 241, 241, 241, 241, 241, nil, nil, 241, + nil, nil, nil, nil, nil, nil, 241, nil, nil, 241, + 241, 241, 241, 241, 241, 241, 241, nil, 241, 241, + 241, nil, 241, 241, 241, 241, 241, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 241, nil, nil, 241, + nil, nil, 241, 241, nil, nil, 241, nil, nil, nil, + nil, nil, 241, nil, nil, nil, nil, nil, nil, nil, + 241, nil, nil, nil, nil, 241, 241, 241, 241, nil, + 241, 241, nil, nil, nil, 241, 241, nil, 242, 242, + 242, nil, 242, 241, nil, 241, 242, 242, nil, nil, + nil, 242, nil, 242, 242, 242, 242, 242, 242, 242, + nil, nil, nil, nil, nil, 242, 242, 242, 242, 242, + 242, 242, nil, nil, 242, nil, nil, nil, nil, nil, + nil, 242, nil, nil, 242, 242, 242, 242, 242, 242, + 242, 242, nil, 242, 242, 242, nil, 242, 242, 242, + 242, 242, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 242, nil, nil, 242, nil, nil, 242, 242, nil, + nil, 242, nil, nil, nil, nil, nil, 242, nil, nil, + nil, nil, nil, nil, nil, 242, nil, nil, nil, nil, + 242, 242, 242, 242, nil, 242, 242, nil, nil, nil, + 242, 242, nil, 243, 243, 243, nil, 243, 242, nil, + 242, 243, 243, nil, nil, nil, 243, nil, 243, 243, + 243, 243, 243, 243, 243, nil, nil, nil, nil, nil, + 243, 243, 243, 243, 243, 243, 243, nil, nil, 243, + nil, nil, nil, nil, nil, nil, 243, nil, nil, 243, + 243, 243, 243, 243, 243, 243, 243, nil, 243, 243, + 243, nil, 243, 243, 243, 243, 243, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 243, nil, nil, 243, + nil, nil, 243, 243, nil, nil, 243, nil, nil, nil, + nil, nil, 243, nil, nil, nil, nil, nil, nil, nil, + 243, nil, nil, nil, nil, 243, 243, 243, 243, nil, + 243, 243, nil, nil, nil, 243, 243, nil, 244, 244, + 244, nil, 244, 243, nil, 243, 244, 244, nil, nil, + nil, 244, nil, 244, 244, 244, 244, 244, 244, 244, + nil, nil, nil, nil, nil, 244, 244, 244, 244, 244, + 244, 244, nil, nil, 244, nil, nil, nil, nil, nil, + nil, 244, nil, nil, 244, 244, 244, 244, 244, 244, + 244, 244, nil, 244, 244, 244, nil, 244, 244, 244, + 244, 244, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 244, nil, nil, 244, nil, nil, 244, 244, nil, + nil, 244, nil, nil, nil, nil, nil, 244, nil, nil, + nil, nil, nil, nil, nil, 244, nil, nil, nil, nil, + 244, 244, 244, 244, nil, 244, 244, nil, nil, nil, + 244, 244, nil, 245, 245, 245, nil, 245, 244, nil, + 244, 245, 245, nil, nil, nil, 245, nil, 245, 245, + 245, 245, 245, 245, 245, nil, nil, nil, nil, nil, + 245, 245, 245, 245, 245, 245, 245, nil, nil, 245, + nil, nil, nil, nil, nil, nil, 245, nil, nil, 245, + 245, 245, 245, 245, 245, 245, 245, nil, 245, 245, + 245, nil, 245, 245, 245, 245, 245, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 245, nil, nil, 245, + nil, nil, 245, 245, nil, nil, 245, nil, nil, nil, + nil, nil, 245, nil, nil, nil, nil, nil, nil, nil, + 245, nil, nil, nil, nil, 245, 245, 245, 245, nil, + 245, 245, nil, nil, nil, 245, 245, nil, 246, 246, + 246, nil, 246, 245, nil, 245, 246, 246, nil, nil, + nil, 246, nil, 246, 246, 246, 246, 246, 246, 246, + nil, nil, nil, nil, nil, 246, 246, 246, 246, 246, + 246, 246, nil, nil, 246, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 246, 246, 246, 246, 246, 246, + 246, 246, nil, 246, 246, 246, nil, 246, 246, 246, + 246, 246, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 246, nil, nil, 246, nil, nil, 246, 246, nil, + nil, 246, nil, nil, nil, nil, nil, 246, nil, nil, + nil, nil, nil, nil, nil, 246, nil, nil, nil, nil, + 246, 246, 246, 246, nil, 246, 246, nil, nil, nil, + 246, 246, nil, 247, 247, 247, nil, 247, 246, nil, + 246, 247, 247, nil, nil, nil, 247, nil, 247, 247, + 247, 247, 247, 247, 247, nil, nil, nil, nil, nil, + 247, 247, 247, 247, 247, 247, 247, nil, nil, 247, + nil, nil, nil, nil, nil, nil, 247, nil, nil, 247, + 247, 247, 247, 247, 247, 247, 247, nil, 247, 247, + 247, nil, 247, 247, 247, 247, 247, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 247, nil, nil, 247, + nil, nil, 247, 247, nil, nil, 247, nil, nil, nil, + nil, nil, 247, nil, nil, nil, nil, nil, nil, nil, + 247, nil, nil, nil, nil, 247, 247, 247, 247, nil, + 247, 247, nil, nil, nil, 247, 247, nil, 256, 256, + 256, nil, 256, 247, nil, 247, 256, 256, nil, nil, + nil, 256, nil, 256, 256, 256, 256, 256, 256, 256, + nil, nil, nil, nil, nil, 256, 256, 256, 256, 256, + 256, 256, nil, nil, 256, nil, nil, nil, nil, nil, + nil, 256, nil, nil, 256, 256, 256, 256, 256, 256, + 256, 256, nil, 256, 256, 256, nil, 256, 256, 256, + 256, 256, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 256, nil, nil, 256, nil, nil, 256, 256, nil, + nil, 256, nil, nil, nil, nil, nil, 256, nil, nil, + nil, nil, nil, nil, nil, 256, nil, nil, nil, nil, + 256, 256, 256, 256, nil, 256, 256, nil, nil, nil, + 256, 256, nil, 258, 258, 258, nil, 258, 256, nil, + 256, 258, 258, nil, nil, nil, 258, nil, 258, 258, + 258, 258, 258, 258, 258, nil, nil, nil, nil, nil, + 258, 258, 258, 258, 258, 258, 258, nil, nil, 258, + nil, nil, nil, nil, nil, nil, 258, nil, nil, 258, + 258, 258, 258, 258, 258, 258, 258, nil, 258, 258, + 258, nil, 258, 258, 258, 258, 258, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 258, nil, nil, 258, + nil, nil, 258, 258, nil, nil, 258, nil, nil, nil, + nil, nil, 258, nil, nil, nil, nil, nil, nil, nil, + 258, nil, nil, nil, nil, 258, 258, 258, 258, nil, + 258, 258, nil, nil, nil, 258, 258, nil, 263, 263, + 263, nil, 263, 258, nil, 258, 263, 263, nil, nil, + nil, 263, nil, 263, 263, 263, 263, 263, 263, 263, + nil, nil, nil, nil, nil, 263, 263, 263, 263, 263, + 263, 263, nil, nil, 263, nil, nil, nil, nil, nil, + nil, 263, nil, nil, 263, 263, 263, 263, 263, 263, + 263, 263, nil, 263, 263, 263, nil, 263, 263, 263, + 263, 263, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 263, nil, nil, 263, nil, nil, 263, 263, nil, + nil, 263, nil, nil, nil, nil, nil, 263, nil, nil, + nil, nil, nil, nil, nil, 263, nil, nil, nil, nil, + 263, 263, 263, 263, nil, 263, 263, nil, nil, nil, + 263, 263, nil, 269, 269, 269, nil, 269, 263, nil, + 263, 269, 269, nil, nil, nil, 269, nil, 269, 269, + 269, 269, 269, 269, 269, nil, nil, nil, nil, nil, + 269, 269, 269, 269, 269, 269, 269, nil, nil, 269, + nil, nil, nil, nil, nil, nil, 269, nil, nil, 269, + 269, 269, 269, 269, 269, 269, 269, 269, 269, 269, + 269, nil, 269, 269, 269, 269, 269, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 269, nil, nil, 269, + nil, nil, 269, 269, nil, nil, 269, nil, 269, nil, + 269, nil, 269, nil, nil, nil, nil, nil, nil, nil, + 269, nil, nil, nil, nil, 269, 269, 269, 269, nil, + 269, 269, nil, nil, nil, 269, 269, nil, 270, 270, + 270, nil, 270, 269, nil, 269, 270, 270, nil, nil, + nil, 270, nil, 270, 270, 270, 270, 270, 270, 270, + nil, nil, nil, nil, nil, 270, 270, 270, 270, 270, + 270, 270, nil, nil, 270, nil, nil, nil, nil, nil, + nil, 270, nil, nil, 270, 270, 270, 270, 270, 270, + 270, 270, 270, 270, 270, 270, nil, 270, 270, 270, + 270, 270, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 270, nil, nil, 270, nil, nil, 270, 270, nil, + nil, 270, nil, 270, nil, 270, nil, 270, nil, nil, + nil, nil, nil, nil, nil, 270, nil, nil, nil, nil, + 270, 270, 270, 270, nil, 270, 270, nil, nil, nil, + 270, 270, nil, 278, 278, 278, nil, 278, 270, nil, + 270, 278, 278, nil, nil, nil, 278, nil, 278, 278, + 278, 278, 278, 278, 278, nil, nil, nil, nil, nil, + 278, 278, 278, 278, 278, 278, 278, nil, nil, 278, + nil, nil, nil, nil, nil, nil, 278, nil, nil, 278, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 278, nil, 278, 278, 278, 278, 278, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 278, nil, nil, 278, + nil, nil, 278, 278, nil, nil, 278, nil, 278, nil, + 278, nil, 278, nil, nil, nil, nil, nil, nil, nil, + 278, nil, nil, nil, nil, 278, 278, 278, 278, nil, + 278, 278, nil, nil, nil, 278, 278, 278, 284, 284, + 284, nil, 284, 278, nil, 278, 284, 284, nil, nil, + nil, 284, nil, 284, 284, 284, 284, 284, 284, 284, + nil, nil, nil, nil, nil, 284, 284, 284, 284, 284, + 284, 284, nil, nil, 284, nil, nil, nil, nil, nil, + nil, 284, nil, nil, 284, 284, 284, 284, 284, 284, + 284, 284, nil, 284, 284, 284, nil, 284, 284, nil, + nil, 284, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, nil, 19, 19, nil, nil, 19, 19, + nil, 284, nil, nil, 284, nil, nil, 284, 284, nil, + nil, 284, nil, nil, 19, nil, 19, nil, 19, 19, + 19, 19, 19, 19, 19, nil, 19, nil, nil, nil, + 284, 284, 284, 284, nil, 284, 284, nil, nil, nil, + 284, 284, nil, 19, nil, 284, nil, nil, 284, nil, + 284, 297, 297, 297, nil, 297, nil, nil, nil, 297, + 297, nil, nil, nil, 297, nil, 297, 297, 297, 297, + 297, 297, 297, nil, nil, nil, nil, nil, 297, 297, + 297, 297, 297, 297, 297, nil, nil, 297, nil, nil, + nil, nil, nil, nil, 297, nil, nil, 297, 297, 297, + 297, 297, 297, 297, 297, nil, 297, 297, 297, nil, + 297, 297, nil, 883, 297, 883, 883, 883, 883, 883, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 297, nil, nil, 297, nil, nil, + 297, 297, nil, nil, 297, nil, nil, nil, nil, nil, + 883, nil, nil, nil, nil, nil, nil, nil, nil, 883, + 883, 883, 883, 297, 297, 297, 297, nil, 297, 297, + nil, nil, nil, 297, 297, nil, 306, 306, 306, nil, + 306, 297, nil, 297, 306, 306, nil, nil, nil, 306, + nil, 306, 306, 306, 306, 306, 306, 306, nil, nil, + nil, nil, nil, 306, 306, 306, 306, 306, 306, 306, + nil, nil, 306, nil, nil, nil, nil, nil, nil, 306, + nil, nil, 306, 306, 306, 306, 306, 306, 306, 306, + nil, 306, 306, 306, nil, 306, 306, 306, 306, 306, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 306, + nil, nil, 306, 306, nil, 306, 306, nil, nil, 306, + nil, nil, nil, nil, nil, 306, nil, nil, nil, nil, + nil, nil, nil, 306, nil, nil, nil, nil, 306, 306, + 306, 306, nil, 306, 306, nil, nil, nil, 306, 306, + nil, 322, 322, 322, nil, 322, 306, nil, 306, 322, + 322, nil, nil, nil, 322, nil, 322, 322, 322, 322, + 322, 322, 322, nil, nil, nil, nil, nil, 322, 322, + 322, 322, 322, 322, 322, nil, nil, 322, nil, nil, + nil, nil, nil, nil, 322, nil, nil, 322, 322, 322, + 322, 322, 322, 322, 322, nil, 322, 322, 322, nil, + 322, 322, 322, 322, 322, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 322, nil, nil, 322, nil, nil, + 322, 322, nil, nil, 322, nil, nil, nil, nil, nil, + 322, nil, nil, nil, nil, nil, nil, nil, 322, nil, + nil, nil, nil, 322, 322, 322, 322, nil, 322, 322, + nil, nil, nil, 322, 322, nil, 323, 323, 323, nil, + 323, 322, nil, 322, 323, 323, nil, nil, nil, 323, + nil, 323, 323, 323, 323, 323, 323, 323, nil, nil, + nil, nil, nil, 323, 323, 323, 323, 323, 323, 323, + nil, nil, 323, nil, nil, nil, nil, nil, nil, 323, + nil, nil, 323, 323, 323, 323, 323, 323, 323, 323, + nil, 323, 323, 323, nil, 323, 323, 323, 323, 323, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 323, + nil, nil, 323, nil, nil, 323, 323, nil, nil, 323, + nil, nil, nil, nil, nil, 323, nil, nil, nil, nil, + nil, nil, nil, 323, nil, nil, nil, nil, 323, 323, + 323, 323, nil, 323, 323, nil, nil, nil, 323, 323, + nil, 341, 341, 341, nil, 341, 323, nil, 323, 341, + 341, nil, nil, nil, 341, nil, 341, 341, 341, 341, + 341, 341, 341, nil, nil, nil, nil, nil, 341, 341, + 341, 341, 341, 341, 341, nil, nil, 341, nil, nil, + nil, nil, nil, nil, 341, nil, nil, 341, 341, 341, + 341, 341, 341, 341, 341, nil, 341, 341, 341, nil, + 341, 341, 341, 341, 341, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 341, nil, nil, 341, nil, nil, + 341, 341, nil, nil, 341, nil, nil, nil, nil, nil, + 341, nil, nil, nil, nil, nil, nil, nil, 341, nil, + nil, nil, nil, 341, 341, 341, 341, nil, 341, 341, + nil, nil, nil, 341, 341, nil, 356, 356, 356, nil, + 356, 341, nil, 341, 356, 356, nil, nil, nil, 356, + nil, 356, 356, 356, 356, 356, 356, 356, nil, nil, + nil, nil, nil, 356, 356, 356, 356, 356, 356, 356, + nil, nil, 356, nil, nil, nil, nil, nil, nil, 356, + nil, nil, 356, 356, 356, 356, 356, 356, 356, 356, + nil, 356, 356, 356, nil, 356, 356, 356, 356, 356, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 356, + nil, nil, 356, nil, nil, 356, 356, nil, nil, 356, + nil, nil, nil, nil, nil, 356, nil, nil, nil, nil, + nil, nil, nil, 356, nil, nil, nil, nil, 356, 356, + 356, 356, nil, 356, 356, nil, nil, nil, 356, 356, + nil, 383, 383, 383, nil, 383, 356, nil, 356, 383, + 383, nil, nil, nil, 383, nil, 383, 383, 383, 383, + 383, 383, 383, nil, nil, nil, nil, nil, 383, 383, + 383, 383, 383, 383, 383, nil, nil, 383, nil, nil, + nil, nil, nil, nil, 383, nil, nil, 383, 383, 383, + 383, 383, 383, 383, 383, nil, 383, 383, 383, nil, + 383, 383, 383, 383, 383, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 383, nil, nil, 383, nil, nil, + 383, 383, nil, nil, 383, nil, nil, nil, nil, nil, + 383, nil, nil, nil, nil, nil, nil, nil, 383, nil, + nil, nil, nil, 383, 383, 383, 383, nil, 383, 383, + nil, nil, nil, 383, 383, nil, 415, 415, 415, nil, + 415, 383, nil, 383, 415, 415, nil, nil, nil, 415, + nil, 415, 415, 415, 415, 415, 415, 415, nil, nil, + nil, nil, nil, 415, 415, 415, 415, 415, 415, 415, + nil, nil, 415, nil, nil, nil, nil, nil, nil, 415, + nil, nil, 415, 415, 415, 415, 415, 415, 415, 415, + 415, 415, 415, 415, nil, 415, 415, 415, 415, 415, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 415, + nil, nil, 415, nil, nil, 415, 415, nil, nil, 415, + nil, 415, nil, 415, nil, 415, nil, nil, nil, nil, + nil, nil, nil, 415, nil, nil, nil, nil, 415, 415, + 415, 415, nil, 415, 415, nil, nil, nil, 415, 415, + nil, 417, 417, 417, nil, 417, 415, nil, 415, 417, + 417, nil, nil, nil, 417, nil, 417, 417, 417, 417, + 417, 417, 417, nil, nil, nil, nil, nil, 417, 417, + 417, 417, 417, 417, 417, nil, nil, 417, nil, nil, + nil, nil, nil, nil, 417, nil, nil, 417, 417, 417, + 417, 417, 417, 417, 417, nil, 417, 417, 417, nil, + 417, 417, 417, 417, 417, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 417, nil, nil, 417, nil, nil, + 417, 417, nil, nil, 417, nil, nil, nil, nil, nil, + 417, nil, nil, nil, nil, nil, nil, nil, 417, nil, + nil, nil, nil, 417, 417, 417, 417, nil, 417, 417, + nil, nil, nil, 417, 417, nil, 418, 418, 418, nil, + 418, 417, nil, 417, 418, 418, nil, nil, nil, 418, + nil, 418, 418, 418, 418, 418, 418, 418, nil, nil, + nil, nil, nil, 418, 418, 418, 418, 418, 418, 418, + nil, nil, 418, nil, nil, nil, nil, nil, nil, 418, + nil, nil, 418, 418, 418, 418, 418, 418, 418, 418, + nil, 418, 418, 418, nil, 418, 418, 418, 418, 418, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 418, + nil, nil, 418, nil, nil, 418, 418, nil, nil, 418, + nil, nil, nil, nil, nil, 418, nil, nil, nil, nil, + nil, nil, nil, 418, nil, nil, nil, nil, 418, 418, + 418, 418, nil, 418, 418, nil, nil, nil, 418, 418, + nil, 419, 419, 419, nil, 419, 418, nil, 418, 419, + 419, nil, nil, nil, 419, nil, 419, 419, 419, 419, + 419, 419, 419, nil, nil, nil, nil, nil, 419, 419, + 419, 419, 419, 419, 419, nil, nil, 419, nil, nil, + nil, nil, nil, nil, 419, nil, nil, 419, 419, 419, + 419, 419, 419, 419, 419, nil, 419, 419, 419, nil, + 419, 419, 419, 419, 419, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 419, nil, nil, 419, nil, nil, + 419, 419, nil, nil, 419, nil, nil, nil, nil, nil, + 419, nil, nil, nil, nil, nil, nil, nil, 419, nil, + nil, nil, nil, 419, 419, 419, 419, nil, 419, 419, + nil, nil, nil, 419, 419, nil, 448, 448, 448, nil, + 448, 419, nil, 419, 448, 448, nil, nil, nil, 448, + nil, 448, 448, 448, 448, 448, 448, 448, nil, nil, + nil, nil, nil, 448, 448, 448, 448, 448, 448, 448, + nil, nil, 448, nil, nil, nil, nil, nil, nil, 448, + nil, nil, 448, 448, 448, 448, 448, 448, 448, 448, + 448, 448, 448, 448, nil, 448, 448, 448, 448, 448, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 448, + nil, nil, 448, nil, nil, 448, 448, nil, nil, 448, + nil, 448, nil, 448, nil, 448, nil, nil, nil, nil, + nil, nil, nil, 448, nil, nil, nil, nil, 448, 448, + 448, 448, nil, 448, 448, nil, nil, nil, 448, 448, + nil, 450, 450, 450, nil, 450, 448, nil, 448, 450, + 450, nil, nil, nil, 450, nil, 450, 450, 450, 450, + 450, 450, 450, nil, nil, nil, nil, nil, 450, 450, + 450, 450, 450, 450, 450, nil, nil, 450, nil, nil, + nil, nil, nil, nil, 450, nil, nil, 450, 450, 450, + 450, 450, 450, 450, 450, 450, 450, 450, 450, nil, + 450, 450, 450, 450, 450, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 450, nil, nil, 450, nil, nil, + 450, 450, nil, nil, 450, nil, nil, nil, 450, nil, + 450, nil, nil, nil, nil, nil, nil, nil, 450, nil, + nil, nil, nil, 450, 450, 450, 450, nil, 450, 450, + nil, nil, nil, 450, 450, nil, 452, 452, 452, nil, + 452, 450, nil, 450, 452, 452, nil, nil, nil, 452, + nil, 452, 452, 452, 452, 452, 452, 452, nil, nil, + nil, nil, nil, 452, 452, 452, 452, 452, 452, 452, + nil, nil, 452, nil, nil, nil, nil, nil, nil, 452, + nil, nil, 452, 452, 452, 452, 452, 452, 452, 452, + nil, 452, 452, 452, nil, 452, 452, 452, 452, 452, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 452, + nil, nil, 452, nil, nil, 452, 452, nil, nil, 452, + nil, nil, nil, nil, nil, 452, nil, nil, nil, nil, + nil, nil, nil, 452, nil, nil, nil, nil, 452, 452, + 452, 452, nil, 452, 452, nil, nil, nil, 452, 452, + nil, 464, 464, 464, nil, 464, 452, nil, 452, 464, + 464, nil, nil, nil, 464, nil, 464, 464, 464, 464, + 464, 464, 464, nil, nil, nil, nil, nil, 464, 464, + 464, 464, 464, 464, 464, nil, nil, 464, nil, nil, + nil, nil, nil, nil, 464, nil, nil, 464, 464, 464, + 464, 464, 464, 464, 464, 464, 464, 464, 464, nil, + 464, 464, 464, 464, 464, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 464, nil, nil, 464, nil, nil, + 464, 464, nil, nil, 464, nil, nil, nil, 464, nil, + 464, nil, nil, nil, nil, nil, nil, nil, 464, nil, + nil, nil, nil, 464, 464, 464, 464, nil, 464, 464, + nil, nil, nil, 464, 464, nil, 474, 474, 474, nil, + 474, 464, nil, 464, 474, 474, nil, nil, nil, 474, + nil, 474, 474, 474, 474, 474, 474, 474, nil, nil, + nil, nil, nil, 474, 474, 474, 474, 474, 474, 474, + nil, nil, 474, nil, nil, nil, nil, nil, nil, 474, + nil, nil, 474, 474, 474, 474, 474, 474, 474, 474, + nil, 474, 474, 474, nil, 474, 474, nil, 906, 474, + 906, 906, 906, 906, 906, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 474, + nil, nil, 474, nil, nil, 474, 474, nil, nil, 474, + nil, nil, nil, nil, nil, 906, nil, nil, nil, nil, + nil, nil, nil, nil, 906, 906, 906, 906, 474, 474, + 474, 474, nil, 474, 474, nil, nil, nil, 474, 474, + nil, 476, 476, 476, nil, 476, 474, nil, 474, 476, + 476, nil, nil, nil, 476, nil, 476, 476, 476, 476, + 476, 476, 476, nil, nil, nil, nil, nil, 476, 476, + 476, 476, 476, 476, 476, nil, nil, 476, nil, nil, + nil, nil, nil, nil, 476, nil, nil, 476, 476, 476, + 476, 476, 476, 476, 476, 476, 476, 476, 476, nil, + 476, 476, 476, 476, 476, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 476, nil, nil, 476, nil, nil, + 476, 476, nil, nil, 476, nil, 476, nil, 476, nil, + 476, nil, nil, nil, nil, nil, nil, nil, 476, nil, + nil, nil, nil, 476, 476, 476, 476, nil, 476, 476, + nil, nil, nil, 476, 476, nil, 483, 483, 483, nil, + 483, 476, nil, 476, 483, 483, nil, nil, nil, 483, + nil, 483, 483, 483, 483, 483, 483, 483, nil, nil, + nil, nil, nil, 483, 483, 483, 483, 483, 483, 483, + nil, nil, 483, nil, nil, nil, nil, nil, nil, 483, + nil, nil, 483, 483, 483, 483, 483, 483, 483, 483, + nil, 483, 483, 483, nil, 483, 483, nil, nil, 483, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 483, + nil, nil, 483, nil, nil, 483, 483, nil, nil, 483, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 483, 483, + 483, 483, nil, 483, 483, nil, nil, nil, 483, 483, + nil, 486, 486, 486, nil, 486, 483, nil, 483, 486, + 486, nil, nil, nil, 486, nil, 486, 486, 486, 486, + 486, 486, 486, nil, nil, nil, nil, nil, 486, 486, + 486, 486, 486, 486, 486, nil, nil, 486, nil, nil, + nil, nil, nil, nil, 486, nil, nil, 486, 486, 486, + 486, 486, 486, 486, 486, nil, 486, 486, 486, nil, + 486, 486, 486, 486, 486, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 486, nil, nil, 486, nil, nil, + 486, 486, nil, nil, 486, nil, nil, nil, nil, nil, + 486, nil, nil, nil, nil, nil, nil, nil, 486, nil, + nil, nil, nil, 486, 486, 486, 486, nil, 486, 486, + nil, nil, nil, 486, 486, nil, 487, 487, 487, nil, + 487, 486, nil, 486, 487, 487, nil, nil, nil, 487, + nil, 487, 487, 487, 487, 487, 487, 487, nil, nil, + nil, nil, nil, 487, 487, 487, 487, 487, 487, 487, + nil, nil, 487, nil, nil, nil, nil, nil, nil, 487, + nil, nil, 487, 487, 487, 487, 487, 487, 487, 487, + nil, 487, 487, 487, nil, 487, 487, 487, 487, 487, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 487, + nil, nil, 487, nil, nil, 487, 487, nil, nil, 487, + nil, nil, nil, nil, nil, 487, nil, nil, nil, nil, + nil, nil, nil, 487, nil, nil, nil, nil, 487, 487, + 487, 487, nil, 487, 487, nil, nil, nil, 487, 487, + nil, 488, 488, 488, nil, 488, 487, nil, 487, 488, + 488, nil, nil, nil, 488, nil, 488, 488, 488, 488, + 488, 488, 488, nil, nil, nil, nil, nil, 488, 488, + 488, 488, 488, 488, 488, nil, nil, 488, nil, nil, + nil, nil, nil, nil, 488, nil, nil, 488, 488, 488, + 488, 488, 488, 488, 488, nil, 488, 488, 488, nil, + 488, 488, 488, 488, 488, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 488, nil, nil, 488, nil, nil, + 488, 488, nil, nil, 488, nil, nil, nil, nil, nil, + 488, nil, nil, nil, nil, nil, nil, nil, 488, nil, + nil, nil, nil, 488, 488, 488, 488, nil, 488, 488, + nil, nil, nil, 488, 488, nil, 492, 492, 492, nil, + 492, 488, nil, 488, 492, 492, nil, nil, nil, 492, + nil, 492, 492, 492, 492, 492, 492, 492, nil, nil, + nil, nil, nil, 492, 492, 492, 492, 492, 492, 492, + nil, nil, 492, nil, nil, nil, nil, nil, nil, 492, + nil, nil, 492, 492, 492, 492, 492, 492, 492, 492, + nil, 492, 492, 492, nil, 492, 492, 492, 492, 492, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 492, + nil, nil, 492, nil, nil, 492, 492, nil, nil, 492, + nil, nil, nil, nil, nil, 492, nil, nil, nil, nil, + nil, nil, nil, 492, nil, nil, nil, nil, 492, 492, + 492, 492, nil, 492, 492, nil, nil, nil, 492, 492, + nil, 494, 494, 494, nil, 494, 492, nil, 492, 494, + 494, nil, nil, nil, 494, nil, 494, 494, 494, 494, + 494, 494, 494, nil, nil, nil, nil, nil, 494, 494, + 494, 494, 494, 494, 494, nil, nil, 494, nil, nil, + nil, nil, nil, nil, 494, nil, nil, 494, 494, 494, + 494, 494, 494, 494, 494, nil, 494, 494, 494, nil, + 494, 494, 494, 494, 494, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 494, nil, nil, 494, nil, nil, + 494, 494, nil, nil, 494, nil, 494, nil, nil, nil, + 494, nil, nil, nil, nil, nil, nil, nil, 494, nil, + nil, nil, nil, 494, 494, 494, 494, nil, 494, 494, + nil, nil, nil, 494, 494, nil, 498, 498, 498, nil, + 498, 494, nil, 494, 498, 498, nil, nil, nil, 498, + nil, 498, 498, 498, 498, 498, 498, 498, nil, nil, + nil, nil, nil, 498, 498, 498, 498, 498, 498, 498, + nil, nil, 498, nil, nil, nil, nil, nil, nil, 498, + nil, nil, 498, 498, 498, 498, 498, 498, 498, 498, + 498, 498, 498, 498, nil, 498, 498, 498, 498, 498, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 498, + nil, nil, 498, nil, nil, 498, 498, nil, nil, 498, + nil, 498, nil, nil, nil, 498, nil, nil, nil, nil, + nil, nil, nil, 498, nil, nil, nil, nil, 498, 498, + 498, 498, nil, 498, 498, nil, nil, nil, 498, 498, + nil, 501, 501, 501, nil, 501, 498, nil, 498, 501, + 501, nil, nil, nil, 501, nil, 501, 501, 501, 501, + 501, 501, 501, nil, nil, nil, nil, nil, 501, 501, + 501, 501, 501, 501, 501, nil, nil, 501, nil, nil, + nil, nil, nil, nil, 501, nil, nil, 501, 501, 501, + 501, 501, 501, 501, 501, 501, 501, 501, 501, nil, + 501, 501, 501, 501, 501, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 501, nil, nil, 501, nil, nil, + 501, 501, nil, nil, 501, nil, nil, nil, nil, nil, + 501, nil, nil, nil, nil, nil, nil, nil, 501, nil, + nil, nil, nil, 501, 501, 501, 501, nil, 501, 501, + nil, nil, nil, 501, 501, nil, 515, 515, 515, nil, + 515, 501, nil, 501, 515, 515, nil, nil, nil, 515, + nil, 515, 515, 515, 515, 515, 515, 515, nil, nil, + nil, nil, nil, 515, 515, 515, 515, 515, 515, 515, + nil, nil, 515, nil, nil, nil, nil, nil, nil, 515, + nil, nil, 515, 515, 515, 515, 515, 515, 515, 515, + nil, 515, 515, 515, nil, 515, 515, 515, 515, 515, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 515, + nil, nil, 515, nil, nil, 515, 515, nil, nil, 515, + nil, 515, nil, nil, nil, 515, nil, nil, nil, nil, + nil, nil, nil, 515, nil, nil, nil, nil, 515, 515, + 515, 515, nil, 515, 515, nil, nil, nil, 515, 515, + nil, 516, 516, 516, nil, 516, 515, nil, 515, 516, + 516, nil, nil, nil, 516, nil, 516, 516, 516, 516, + 516, 516, 516, nil, nil, nil, nil, nil, 516, 516, + 516, 516, 516, 516, 516, nil, nil, 516, nil, nil, + nil, nil, nil, nil, 516, nil, nil, 516, 516, 516, + 516, 516, 516, 516, 516, 516, 516, 516, 516, nil, + 516, 516, 516, 516, 516, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 516, nil, nil, 516, nil, nil, + 516, 516, nil, nil, 516, nil, 516, nil, 516, nil, + 516, nil, nil, nil, nil, nil, nil, nil, 516, nil, + nil, nil, nil, 516, 516, 516, 516, nil, 516, 516, + nil, nil, nil, 516, 516, nil, 526, 526, 526, nil, + 526, 516, nil, 516, 526, 526, nil, nil, nil, 526, + nil, 526, 526, 526, 526, 526, 526, 526, nil, nil, + nil, nil, nil, 526, 526, 526, 526, 526, 526, 526, + nil, nil, 526, nil, nil, nil, nil, nil, nil, 526, + nil, nil, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, nil, 526, 526, 526, 526, 526, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 526, + nil, nil, 526, nil, nil, 526, 526, nil, nil, 526, + nil, 526, nil, 526, nil, 526, nil, nil, nil, nil, + nil, nil, nil, 526, nil, nil, nil, nil, 526, 526, + 526, 526, nil, 526, 526, nil, nil, nil, 526, 526, + nil, 529, 529, 529, nil, 529, 526, nil, 526, 529, + 529, nil, nil, nil, 529, nil, 529, 529, 529, 529, + 529, 529, 529, nil, nil, nil, nil, nil, 529, 529, + 529, 529, 529, 529, 529, nil, nil, 529, nil, nil, + nil, nil, nil, nil, 529, nil, nil, 529, 529, 529, + 529, 529, 529, 529, 529, nil, 529, 529, 529, nil, + 529, 529, 529, 529, 529, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 529, nil, nil, 529, nil, nil, + 529, 529, nil, nil, 529, nil, nil, nil, nil, nil, + 529, nil, nil, nil, nil, nil, nil, nil, 529, nil, + nil, nil, nil, 529, 529, 529, 529, nil, 529, 529, + nil, nil, nil, 529, 529, nil, 557, 557, 557, nil, + 557, 529, nil, 529, 557, 557, nil, nil, nil, 557, + nil, 557, 557, 557, 557, 557, 557, 557, nil, nil, + nil, nil, nil, 557, 557, 557, 557, 557, 557, 557, + nil, nil, 557, nil, nil, nil, nil, nil, nil, 557, + nil, nil, 557, 557, 557, 557, 557, 557, 557, 557, + nil, 557, 557, 557, nil, 557, 557, 557, 557, 557, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 557, + nil, nil, 557, nil, nil, 557, 557, nil, nil, 557, + nil, nil, nil, nil, nil, 557, nil, nil, nil, nil, + nil, nil, nil, 557, nil, nil, nil, nil, 557, 557, + 557, 557, nil, 557, 557, nil, nil, nil, 557, 557, + nil, 559, 559, 559, nil, 559, 557, nil, 557, 559, + 559, nil, nil, nil, 559, nil, 559, 559, 559, 559, + 559, 559, 559, nil, nil, nil, nil, nil, 559, 559, + 559, 559, 559, 559, 559, nil, nil, 559, nil, nil, + nil, nil, nil, nil, 559, nil, nil, 559, 559, 559, + 559, 559, 559, 559, 559, nil, 559, 559, 559, nil, + 559, 559, 559, 559, 559, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 559, nil, nil, 559, nil, nil, + 559, 559, nil, nil, 559, nil, 559, nil, nil, nil, + 559, nil, nil, nil, nil, nil, nil, nil, 559, nil, + nil, nil, nil, 559, 559, 559, 559, nil, 559, 559, + nil, nil, nil, 559, 559, nil, 560, 560, 560, nil, + 560, 559, nil, 559, 560, 560, nil, nil, nil, 560, + nil, 560, 560, 560, 560, 560, 560, 560, nil, nil, + nil, nil, nil, 560, 560, 560, 560, 560, 560, 560, + nil, nil, 560, nil, nil, nil, nil, nil, nil, 560, + nil, nil, 560, 560, 560, 560, 560, 560, 560, 560, + nil, 560, 560, 560, nil, 560, 560, 560, 560, 560, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 560, + nil, nil, 560, nil, nil, 560, 560, nil, nil, 560, + nil, nil, nil, nil, nil, 560, nil, nil, nil, nil, + nil, nil, nil, 560, nil, nil, nil, nil, 560, 560, + 560, 560, nil, 560, 560, nil, nil, nil, 560, 560, + nil, 563, 563, 563, nil, 563, 560, nil, 560, 563, + 563, nil, nil, nil, 563, nil, 563, 563, 563, 563, + 563, 563, 563, nil, nil, nil, nil, nil, 563, 563, + 563, 563, 563, 563, 563, nil, nil, 563, nil, nil, + nil, nil, nil, nil, 563, nil, nil, 563, 563, 563, + 563, 563, 563, 563, 563, nil, 563, 563, 563, nil, + 563, 563, 563, 563, 563, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 563, nil, nil, 563, nil, nil, + 563, 563, nil, nil, 563, nil, nil, nil, nil, nil, + 563, nil, nil, nil, nil, nil, nil, nil, 563, nil, + nil, nil, nil, 563, 563, 563, 563, nil, 563, 563, + nil, nil, nil, 563, 563, nil, 564, 564, 564, nil, + 564, 563, nil, 563, 564, 564, nil, nil, nil, 564, + nil, 564, 564, 564, 564, 564, 564, 564, nil, nil, + nil, nil, nil, 564, 564, 564, 564, 564, 564, 564, + nil, nil, 564, nil, nil, nil, nil, nil, nil, 564, + nil, nil, 564, 564, 564, 564, 564, 564, 564, 564, + nil, 564, 564, 564, nil, 564, 564, 564, 564, 564, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 564, + nil, nil, 564, nil, nil, 564, 564, nil, nil, 564, + nil, nil, nil, nil, nil, 564, nil, nil, nil, nil, + nil, nil, nil, 564, nil, nil, nil, nil, 564, 564, + 564, 564, nil, 564, 564, nil, nil, nil, 564, 564, + nil, 568, 568, 568, nil, 568, 564, nil, 564, 568, + 568, nil, nil, nil, 568, nil, 568, 568, 568, 568, + 568, 568, 568, nil, nil, nil, nil, nil, 568, 568, + 568, 568, 568, 568, 568, nil, nil, 568, nil, nil, + nil, nil, nil, nil, 568, nil, nil, 568, 568, 568, + 568, 568, 568, 568, 568, nil, 568, 568, 568, nil, + 568, 568, 568, 568, 568, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 568, nil, nil, 568, nil, nil, + 568, 568, nil, nil, 568, nil, nil, nil, nil, nil, + 568, nil, nil, nil, nil, nil, nil, nil, 568, nil, + nil, nil, nil, 568, 568, 568, 568, nil, 568, 568, + nil, nil, nil, 568, 568, nil, 571, 571, 571, nil, + 571, 568, nil, 568, 571, 571, nil, nil, nil, 571, + nil, 571, 571, 571, 571, 571, 571, 571, nil, nil, + nil, nil, nil, 571, 571, 571, 571, 571, 571, 571, + nil, nil, 571, nil, nil, nil, nil, nil, nil, 571, + nil, nil, 571, 571, 571, 571, 571, 571, 571, 571, + nil, 571, 571, 571, nil, 571, 571, 571, 571, 571, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 571, + nil, nil, 571, nil, nil, 571, 571, nil, nil, 571, + nil, nil, nil, nil, nil, 571, nil, nil, nil, nil, + nil, nil, nil, 571, nil, nil, nil, nil, 571, 571, + 571, 571, nil, 571, 571, nil, nil, nil, 571, 571, + nil, 588, 588, 588, nil, 588, 571, nil, 571, 588, + 588, nil, nil, nil, 588, nil, 588, 588, 588, 588, + 588, 588, 588, nil, nil, nil, nil, nil, 588, 588, + 588, 588, 588, 588, 588, nil, nil, 588, nil, nil, + nil, nil, nil, nil, 588, nil, nil, 588, 588, 588, + 588, 588, 588, 588, 588, nil, 588, 588, 588, nil, + 588, 588, 588, 588, 588, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 588, nil, nil, 588, nil, nil, + 588, 588, nil, nil, 588, nil, nil, nil, nil, nil, + 588, nil, nil, nil, nil, nil, nil, nil, 588, nil, + nil, nil, nil, 588, 588, 588, 588, nil, 588, 588, + nil, nil, nil, 588, 588, nil, 607, 607, 607, nil, + 607, 588, nil, 588, 607, 607, nil, nil, nil, 607, + nil, 607, 607, 607, 607, 607, 607, 607, nil, nil, + nil, nil, nil, 607, 607, 607, 607, 607, 607, 607, + nil, nil, 607, nil, nil, nil, nil, nil, nil, 607, + nil, nil, 607, 607, 607, 607, 607, 607, 607, 607, + nil, 607, 607, 607, nil, 607, 607, nil, nil, 607, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 607, + nil, nil, 607, nil, nil, 607, 607, nil, nil, 607, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 607, 607, + 607, 607, nil, 607, 607, nil, nil, nil, 607, 607, + nil, 618, 618, 618, nil, 618, 607, nil, 607, 618, + 618, nil, nil, nil, 618, nil, 618, 618, 618, 618, + 618, 618, 618, nil, nil, nil, nil, nil, 618, 618, + 618, 618, 618, 618, 618, nil, nil, 618, nil, nil, + nil, nil, nil, nil, 618, nil, nil, 618, 618, 618, + 618, 618, 618, 618, 618, nil, 618, 618, 618, nil, + 618, 618, nil, nil, 618, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 618, nil, nil, 618, nil, nil, + 618, 618, nil, nil, 618, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 618, 618, 618, 618, nil, 618, 618, + nil, nil, nil, 618, 618, nil, 671, 671, 671, nil, + 671, 618, nil, 618, 671, 671, nil, nil, nil, 671, + nil, 671, 671, 671, 671, 671, 671, 671, nil, nil, + nil, nil, nil, 671, 671, 671, 671, 671, 671, 671, + nil, nil, 671, nil, nil, nil, nil, nil, nil, 671, + nil, nil, 671, 671, 671, 671, 671, 671, 671, 671, + nil, 671, 671, 671, nil, 671, 671, 671, 671, 671, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 671, + nil, nil, 671, nil, nil, 671, 671, nil, nil, 671, + nil, nil, nil, nil, nil, 671, nil, nil, nil, nil, + nil, nil, nil, 671, nil, nil, nil, nil, 671, 671, + 671, 671, nil, 671, 671, nil, nil, nil, 671, 671, + nil, 699, 699, 699, nil, 699, 671, nil, 671, 699, + 699, nil, nil, nil, 699, nil, 699, 699, 699, 699, + 699, 699, 699, nil, nil, nil, nil, nil, 699, 699, + 699, 699, 699, 699, 699, nil, nil, 699, nil, nil, + nil, nil, nil, nil, 699, nil, nil, 699, 699, 699, + 699, 699, 699, 699, 699, nil, 699, 699, 699, nil, + 699, 699, 699, 699, 699, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 699, nil, nil, 699, nil, nil, + 699, 699, nil, nil, 699, nil, nil, nil, nil, nil, + 699, nil, nil, nil, nil, nil, nil, nil, 699, nil, + nil, nil, nil, 699, 699, 699, 699, nil, 699, 699, + nil, nil, nil, 699, 699, nil, 701, 701, 701, nil, + 701, 699, nil, 699, 701, 701, nil, nil, nil, 701, + nil, 701, 701, 701, 701, 701, 701, 701, nil, nil, + nil, nil, nil, 701, 701, 701, 701, 701, 701, 701, + nil, nil, 701, nil, nil, nil, nil, nil, nil, 701, + nil, nil, 701, 701, 701, 701, 701, 701, 701, 701, + nil, 701, 701, 701, nil, 701, 701, 701, 701, 701, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 701, + nil, nil, 701, nil, nil, 701, 701, nil, nil, 701, + nil, nil, nil, nil, nil, 701, nil, nil, nil, nil, + nil, nil, nil, 701, nil, nil, nil, nil, 701, 701, + 701, 701, nil, 701, 701, nil, nil, nil, 701, 701, + nil, 712, 712, 712, nil, 712, 701, nil, 701, 712, + 712, nil, nil, nil, 712, nil, 712, 712, 712, 712, + 712, 712, 712, nil, nil, nil, nil, nil, 712, 712, + 712, 712, 712, 712, 712, nil, nil, 712, nil, nil, + nil, nil, nil, nil, 712, nil, nil, 712, 712, 712, + 712, 712, 712, 712, 712, nil, 712, 712, 712, nil, + 712, 712, 712, 712, 712, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 712, nil, nil, 712, nil, nil, + 712, 712, nil, nil, 712, nil, nil, nil, nil, nil, + 712, nil, nil, nil, nil, nil, nil, nil, 712, nil, + nil, nil, nil, 712, 712, 712, 712, nil, 712, 712, + nil, nil, nil, 712, 712, nil, 713, 713, 713, nil, + 713, 712, nil, 712, 713, 713, nil, nil, nil, 713, + nil, 713, 713, 713, 713, 713, 713, 713, nil, nil, + nil, nil, nil, 713, 713, 713, 713, 713, 713, 713, + nil, nil, 713, nil, nil, nil, nil, nil, nil, 713, + nil, nil, 713, 713, 713, 713, 713, 713, 713, 713, + nil, 713, 713, 713, nil, 713, 713, 713, 713, 713, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 713, + nil, nil, 713, nil, nil, 713, 713, nil, nil, 713, + nil, nil, nil, nil, nil, 713, nil, nil, nil, nil, + nil, nil, nil, 713, nil, nil, nil, nil, 713, 713, + 713, 713, nil, 713, 713, nil, nil, nil, 713, 713, + nil, 714, 714, 714, nil, 714, 713, nil, 713, 714, + 714, nil, nil, nil, 714, nil, 714, 714, 714, 714, + 714, 714, 714, nil, nil, nil, nil, nil, 714, 714, + 714, 714, 714, 714, 714, nil, nil, 714, nil, nil, + nil, nil, nil, nil, 714, nil, nil, 714, 714, 714, + 714, 714, 714, 714, 714, nil, 714, 714, 714, nil, + 714, 714, 714, 714, 714, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 714, nil, nil, 714, nil, nil, + 714, 714, nil, nil, 714, nil, nil, nil, nil, nil, + 714, nil, nil, nil, nil, nil, nil, nil, 714, nil, + nil, nil, nil, 714, 714, 714, 714, nil, 714, 714, + nil, nil, nil, 714, 714, nil, 716, 716, 716, nil, + 716, 714, nil, 714, 716, 716, nil, nil, nil, 716, + nil, 716, 716, 716, 716, 716, 716, 716, nil, nil, + nil, nil, nil, 716, 716, 716, 716, 716, 716, 716, + nil, nil, 716, nil, nil, nil, nil, nil, nil, 716, + nil, nil, 716, 716, 716, 716, 716, 716, 716, 716, + nil, 716, 716, 716, nil, 716, 716, 716, 716, 716, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 716, + nil, nil, 716, nil, nil, 716, 716, nil, nil, 716, + nil, nil, nil, nil, nil, 716, nil, nil, nil, nil, + nil, nil, nil, 716, nil, nil, nil, nil, 716, 716, + 716, 716, nil, 716, 716, nil, nil, nil, 716, 716, + nil, 728, 728, 728, nil, 728, 716, nil, 716, 728, + 728, nil, nil, nil, 728, nil, 728, 728, 728, 728, + 728, 728, 728, nil, nil, nil, nil, nil, 728, 728, + 728, 728, 728, 728, 728, nil, nil, 728, nil, nil, + nil, nil, nil, nil, 728, nil, nil, 728, 728, 728, + 728, 728, 728, 728, 728, 728, 728, 728, 728, nil, + 728, 728, 728, 728, 728, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 728, nil, nil, 728, nil, nil, + 728, 728, nil, nil, 728, nil, 728, nil, 728, nil, + 728, nil, nil, nil, nil, nil, nil, nil, 728, nil, + nil, nil, nil, 728, 728, 728, 728, nil, 728, 728, + nil, nil, nil, 728, 728, nil, 731, 731, 731, nil, + 731, 728, nil, 728, 731, 731, nil, nil, nil, 731, + nil, 731, 731, 731, 731, 731, 731, 731, nil, nil, + nil, nil, nil, 731, 731, 731, 731, 731, 731, 731, + nil, nil, 731, nil, nil, nil, nil, nil, nil, 731, + nil, nil, 731, 731, 731, 731, 731, 731, 731, 731, + 731, 731, 731, 731, nil, 731, 731, 731, 731, 731, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 731, + nil, nil, 731, nil, nil, 731, 731, nil, nil, 731, + nil, 731, nil, 731, nil, 731, nil, nil, nil, nil, + nil, nil, nil, 731, nil, nil, nil, nil, 731, 731, + 731, 731, nil, 731, 731, nil, nil, nil, 731, 731, + nil, 746, 746, 746, nil, 746, 731, nil, 731, 746, + 746, nil, nil, nil, 746, nil, 746, 746, 746, 746, + 746, 746, 746, nil, nil, nil, nil, nil, 746, 746, + 746, 746, 746, 746, 746, nil, nil, 746, nil, nil, + nil, nil, nil, nil, 746, nil, nil, 746, 746, 746, + 746, 746, 746, 746, 746, nil, 746, 746, 746, nil, + 746, 746, nil, nil, 746, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 746, nil, nil, 746, nil, nil, + 746, 746, nil, nil, 746, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 746, 746, 746, 746, nil, 746, 746, + nil, nil, nil, 746, 746, nil, 761, 761, 761, nil, + 761, 746, nil, 746, 761, 761, nil, nil, nil, 761, + nil, 761, 761, 761, 761, 761, 761, 761, nil, nil, + nil, nil, nil, 761, 761, 761, 761, 761, 761, 761, + nil, nil, 761, nil, nil, nil, nil, nil, nil, 761, + nil, nil, 761, 761, 761, 761, 761, 761, 761, 761, + nil, 761, 761, 761, nil, 761, 761, 761, 761, 761, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 761, + nil, nil, 761, nil, nil, 761, 761, nil, nil, 761, + nil, nil, nil, nil, nil, 761, nil, nil, nil, nil, + nil, nil, nil, 761, nil, nil, nil, nil, 761, 761, + 761, 761, nil, 761, 761, nil, nil, nil, 761, 761, + nil, 774, 774, 774, nil, 774, 761, nil, 761, 774, + 774, nil, nil, nil, 774, nil, 774, 774, 774, 774, + 774, 774, 774, nil, nil, nil, nil, nil, 774, 774, + 774, 774, 774, 774, 774, nil, nil, 774, nil, nil, + nil, nil, nil, nil, 774, nil, nil, 774, 774, 774, + 774, 774, 774, 774, 774, nil, 774, 774, 774, nil, + 774, 774, 774, 774, 774, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 774, nil, nil, 774, nil, nil, + 774, 774, nil, nil, 774, nil, nil, nil, nil, nil, + 774, nil, nil, nil, nil, nil, nil, nil, 774, nil, + nil, nil, nil, 774, 774, 774, 774, nil, 774, 774, + nil, nil, nil, 774, 774, nil, 779, 779, 779, nil, + 779, 774, nil, 774, 779, 779, nil, nil, nil, 779, + nil, 779, 779, 779, 779, 779, 779, 779, nil, nil, + nil, nil, nil, 779, 779, 779, 779, 779, 779, 779, + nil, nil, 779, nil, nil, nil, nil, nil, nil, 779, + nil, nil, 779, 779, 779, 779, 779, 779, 779, 779, + nil, 779, 779, 779, nil, 779, 779, 779, 779, 779, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 779, + nil, nil, 779, nil, nil, 779, 779, nil, nil, 779, + nil, 779, nil, nil, nil, 779, nil, nil, nil, nil, + nil, nil, nil, 779, nil, nil, nil, nil, 779, 779, + 779, 779, nil, 779, 779, nil, nil, nil, 779, 779, + nil, 796, 796, 796, nil, 796, 779, nil, 779, 796, + 796, nil, nil, nil, 796, nil, 796, 796, 796, 796, + 796, 796, 796, nil, nil, nil, nil, nil, 796, 796, + 796, 796, 796, 796, 796, nil, nil, 796, nil, nil, + nil, nil, nil, nil, 796, nil, nil, 796, 796, 796, + 796, 796, 796, 796, 796, nil, 796, 796, 796, nil, + 796, 796, 796, 796, 796, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 796, nil, nil, 796, nil, nil, + 796, 796, nil, nil, 796, nil, nil, nil, nil, nil, + 796, nil, nil, nil, nil, nil, nil, nil, 796, nil, + nil, nil, nil, 796, 796, 796, 796, nil, 796, 796, + nil, nil, nil, 796, 796, nil, 810, 810, 810, nil, + 810, 796, nil, 796, 810, 810, nil, nil, nil, 810, + nil, 810, 810, 810, 810, 810, 810, 810, nil, nil, + nil, nil, nil, 810, 810, 810, 810, 810, 810, 810, + nil, nil, 810, nil, nil, nil, nil, nil, nil, 810, + nil, nil, 810, 810, 810, 810, 810, 810, 810, 810, + nil, 810, 810, 810, nil, 810, 810, nil, nil, 810, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 810, + nil, nil, 810, nil, nil, 810, 810, nil, nil, 810, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 810, 810, + 810, 810, nil, 810, 810, nil, nil, nil, 810, 810, + nil, 870, 870, 870, nil, 870, 810, nil, 810, 870, + 870, nil, nil, nil, 870, nil, 870, 870, 870, 870, + 870, 870, 870, nil, nil, nil, nil, nil, 870, 870, + 870, 870, 870, 870, 870, nil, nil, 870, nil, nil, + nil, nil, nil, nil, 870, nil, nil, 870, 870, 870, + 870, 870, 870, 870, 870, nil, 870, 870, 870, nil, + 870, 870, 870, 870, 870, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 870, nil, nil, 870, nil, nil, + 870, 870, nil, nil, 870, nil, 870, nil, 870, nil, + 870, nil, nil, nil, nil, nil, nil, nil, 870, nil, + nil, nil, nil, 870, 870, 870, 870, nil, 870, 870, + nil, nil, nil, 870, 870, nil, 873, 873, 873, nil, + 873, 870, nil, 870, 873, 873, nil, nil, nil, 873, + nil, 873, 873, 873, 873, 873, 873, 873, nil, nil, + nil, nil, nil, 873, 873, 873, 873, 873, 873, 873, + nil, nil, 873, nil, nil, nil, nil, nil, nil, 873, + nil, nil, 873, 873, 873, 873, 873, 873, 873, 873, + 873, 873, 873, 873, nil, 873, 873, 873, 873, 873, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 873, + nil, nil, 873, nil, nil, 873, 873, nil, nil, 873, + nil, 873, nil, 873, nil, 873, nil, nil, nil, nil, + nil, nil, nil, 873, nil, nil, nil, nil, 873, 873, + 873, 873, nil, 873, 873, nil, nil, nil, 873, 873, + nil, 876, 876, 876, nil, 876, 873, nil, 873, 876, + 876, nil, nil, nil, 876, nil, 876, 876, 876, 876, + 876, 876, 876, nil, nil, nil, nil, nil, 876, 876, + 876, 876, 876, 876, 876, nil, nil, 876, nil, nil, + nil, nil, nil, nil, 876, nil, nil, 876, 876, 876, + 876, 876, 876, 876, 876, 876, 876, 876, 876, nil, + 876, 876, 876, 876, 876, 597, 597, 597, 597, 597, + 597, 597, 597, 597, 597, 597, nil, 597, 597, nil, + nil, 597, 597, nil, 876, nil, 597, 876, nil, nil, + 876, 876, nil, nil, 876, nil, 876, 597, 876, 597, + 876, 597, 597, 597, 597, 597, 597, 597, 876, 597, + nil, nil, nil, 876, 876, 876, 876, nil, 876, 876, + nil, nil, nil, 876, 876, nil, 597, nil, 597, nil, + nil, 876, nil, 876, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, nil, nil, + nil, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, nil, nil, nil, nil, nil, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, nil, 6, nil, nil, + nil, nil, nil, nil, nil, 6, 6, nil, 6, 6, + 6, 6, 6, 6, 6, nil, nil, 6, 6, nil, + nil, nil, 6, 6, 6, 6, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 6, + 6, nil, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, nil, nil, 6, 6, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 6, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, nil, nil, nil, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, nil, nil, nil, nil, nil, + 7, 7, 7, 7, 7, 7, 7, 7, 7, nil, + nil, 7, nil, nil, nil, nil, nil, nil, nil, 7, + 7, nil, 7, 7, 7, 7, 7, 7, 7, nil, + nil, 7, 7, nil, nil, nil, 7, 7, 7, 7, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 7, 7, nil, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, nil, nil, 7, + 7, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 7, 372, 372, 372, 372, 372, 372, 372, 372, + 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, + 372, 372, 372, 372, 372, 372, nil, nil, nil, 372, + 372, 372, 372, 372, 372, 372, 372, 372, 372, nil, + nil, nil, nil, nil, 372, 372, 372, 372, 372, 372, + 372, 372, 372, nil, nil, 372, nil, nil, nil, nil, + nil, nil, nil, 372, 372, nil, 372, 372, 372, 372, + 372, 372, 372, nil, nil, 372, 372, nil, nil, nil, + 372, 372, 372, 372, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 372, 372, nil, + 372, 372, 372, 372, 372, 372, 372, 372, 372, 372, + 372, nil, nil, 372, 372, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 372, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, 554, 554, 554, 554, 554, + nil, nil, nil, 554, 554, 554, 554, 554, 554, 554, + 554, 554, 554, nil, nil, nil, nil, nil, 554, 554, + 554, 554, 554, 554, 554, 554, 554, nil, nil, 554, + nil, nil, nil, nil, nil, nil, nil, 554, 554, nil, + 554, 554, 554, 554, 554, 554, 554, nil, nil, 554, + 554, nil, nil, nil, 554, 554, 554, 554, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 554, 554, nil, 554, 554, 554, 554, 554, 554, + 554, 554, 554, 554, 554, nil, nil, 554, 554, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 554, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, nil, nil, nil, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, nil, nil, nil, + nil, nil, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, nil, 65, nil, nil, nil, nil, + nil, 65, 65, nil, 65, 65, 65, 65, 65, 65, + 65, nil, nil, 65, 65, nil, nil, nil, 65, 65, + 65, 65, nil, nil, nil, nil, nil, 65, nil, nil, + nil, nil, nil, nil, nil, 65, 65, nil, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, nil, + nil, 65, 684, 684, 684, 684, 684, 684, 684, 684, + 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, + 684, 684, 684, 684, 684, 684, nil, nil, nil, 684, + 684, 684, 684, 684, 684, 684, 684, 684, 684, nil, + nil, nil, nil, nil, 684, 684, 684, 684, 684, 684, + 684, 684, 684, nil, nil, 684, nil, nil, nil, nil, + nil, nil, nil, 684, 684, nil, 684, 684, 684, 684, + 684, 684, 684, nil, nil, 684, 684, nil, nil, nil, + 684, 684, 684, 684, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 684, 684, nil, + 684, 684, 684, 684, 684, 684, 684, 684, 684, 684, + 684, 201, 201, 684, nil, 201, nil, nil, nil, nil, + nil, nil, nil, 201, 201, nil, 201, 201, 201, 201, + 201, 201, 201, nil, nil, 201, 201, nil, nil, nil, + 201, 201, 201, 201, nil, nil, nil, nil, nil, 201, + nil, nil, nil, nil, nil, nil, nil, 201, 201, nil, + 201, 201, 201, 201, 201, 201, 201, 201, 201, 201, + 201, 202, 202, 201, nil, 202, nil, nil, nil, nil, + nil, nil, nil, 202, 202, nil, 202, 202, 202, 202, + 202, 202, 202, nil, nil, 202, 202, nil, nil, nil, + 202, 202, 202, 202, nil, nil, nil, nil, nil, 202, + nil, nil, nil, nil, nil, nil, nil, 202, 202, nil, + 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, + 202, 266, 266, 202, nil, 266, nil, nil, nil, nil, + nil, nil, nil, 266, 266, nil, 266, 266, 266, 266, + 266, 266, 266, nil, nil, 266, 266, nil, nil, nil, + 266, 266, 266, 266, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 266, 266, nil, + 266, 266, 266, 266, 266, 266, 266, 266, 266, 266, + 266, 267, 267, 266, nil, 267, nil, nil, nil, nil, + nil, nil, nil, 267, 267, nil, 267, 267, 267, 267, + 267, 267, 267, nil, nil, 267, 267, nil, nil, nil, + 267, 267, 267, 267, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 267, 267, nil, + 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, + 267, 413, 413, 267, nil, 413, nil, nil, nil, nil, + nil, nil, nil, 413, 413, nil, 413, 413, 413, 413, + 413, 413, 413, nil, nil, 413, 413, nil, nil, nil, + 413, 413, 413, 413, nil, nil, nil, nil, nil, 413, + nil, nil, nil, nil, nil, nil, nil, 413, 413, nil, + 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, + 413, 414, 414, 413, nil, 414, nil, nil, nil, nil, + nil, nil, nil, 414, 414, nil, 414, 414, 414, 414, + 414, 414, 414, nil, nil, 414, 414, nil, nil, nil, + 414, 414, 414, 414, nil, nil, nil, nil, nil, 414, + nil, nil, nil, nil, nil, nil, nil, 414, 414, nil, + 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, + 414, 477, 477, 414, nil, 477, nil, nil, nil, nil, + nil, nil, nil, 477, 477, nil, 477, 477, 477, 477, + 477, 477, 477, nil, nil, 477, 477, nil, nil, nil, + 477, 477, 477, 477, nil, nil, nil, nil, nil, 477, + nil, nil, nil, nil, nil, nil, nil, 477, 477, nil, + 477, 477, 477, 477, 477, 477, 477, 477, 477, 477, + 477, 478, 478, 477, nil, 478, nil, nil, nil, nil, + nil, nil, nil, 478, 478, nil, 478, 478, 478, 478, + 478, 478, 478, nil, nil, 478, 478, nil, nil, nil, + 478, 478, 478, 478, nil, nil, nil, nil, nil, 478, + nil, nil, nil, nil, nil, nil, nil, 478, 478, nil, + 478, 478, 478, 478, 478, 478, 478, 478, 478, 478, + 478, 489, 489, 478, nil, 489, nil, nil, nil, nil, + nil, nil, nil, 489, 489, nil, 489, 489, 489, 489, + 489, 489, 489, nil, nil, 489, 489, nil, nil, nil, + 489, 489, 489, 489, nil, nil, nil, nil, nil, 489, + nil, nil, nil, nil, nil, nil, nil, 489, 489, nil, + 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, + 489, 490, 490, 489, nil, 490, nil, nil, nil, nil, + nil, nil, nil, 490, 490, nil, 490, 490, 490, 490, + 490, 490, 490, nil, nil, 490, 490, nil, nil, nil, + 490, 490, 490, 490, nil, nil, nil, nil, nil, 490, + nil, nil, nil, nil, nil, nil, nil, 490, 490, nil, + 490, 490, 490, 490, 490, 490, 490, 490, 490, 490, + 490, 517, 517, 490, nil, 517, nil, nil, nil, nil, + nil, nil, nil, 517, 517, nil, 517, 517, 517, 517, + 517, 517, 517, nil, nil, 517, 517, nil, nil, nil, + 517, 517, 517, 517, nil, nil, nil, nil, nil, 517, + nil, nil, nil, nil, nil, nil, nil, 517, 517, nil, + 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, + 517, 518, 518, 517, nil, 518, nil, nil, nil, nil, + nil, nil, nil, 518, 518, nil, 518, 518, 518, 518, + 518, 518, 518, nil, nil, 518, 518, nil, nil, nil, + 518, 518, 518, 518, nil, nil, nil, nil, nil, 518, + nil, nil, nil, nil, nil, nil, nil, 518, 518, nil, + 518, 518, 518, 518, 518, 518, 518, 518, 518, 518, + 518, 524, 524, 518, nil, 524, nil, nil, nil, nil, + nil, nil, nil, 524, 524, nil, 524, 524, 524, 524, + 524, 524, 524, nil, nil, 524, 524, nil, nil, nil, + 524, 524, 524, 524, nil, nil, nil, nil, nil, 524, + nil, nil, nil, nil, nil, nil, nil, 524, 524, nil, + 524, 524, 524, 524, 524, 524, 524, 524, 524, 524, + 524, 525, 525, 524, nil, 525, nil, nil, nil, nil, + nil, nil, nil, 525, 525, nil, 525, 525, 525, 525, + 525, 525, 525, nil, nil, 525, 525, nil, nil, nil, + 525, 525, 525, 525, nil, nil, nil, nil, nil, 525, + nil, nil, nil, nil, nil, nil, nil, 525, 525, nil, + 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, + 525, 877, 877, 525, nil, 877, nil, nil, nil, nil, + nil, nil, nil, 877, 877, nil, 877, 877, 877, 877, + 877, 877, 877, nil, nil, 877, 877, nil, nil, nil, + 877, 877, 877, 877, nil, nil, nil, nil, nil, 877, + nil, nil, nil, nil, nil, nil, nil, 877, 877, nil, + 877, 877, 877, 877, 877, 877, 877, 877, 877, 877, + 877, 878, 878, 877, nil, 878, nil, nil, nil, nil, + nil, nil, nil, 878, 878, nil, 878, 878, 878, 878, + 878, 878, 878, nil, nil, 878, 878, nil, nil, nil, + 878, 878, 878, 878, nil, nil, nil, nil, nil, 878, + nil, nil, nil, nil, nil, nil, nil, 878, 878, nil, + 878, 878, 878, 878, 878, 878, 878, 878, 878, 878, + 878, 915, 915, 878, nil, 915, nil, nil, nil, nil, + nil, nil, nil, 915, 915, nil, 915, 915, 915, 915, + 915, 915, 915, nil, nil, 915, 915, nil, nil, nil, + 915, 915, 915, 915, nil, nil, nil, nil, nil, 915, + nil, nil, nil, nil, nil, nil, nil, 915, 915, nil, + 915, 915, 915, 915, 915, 915, 915, 915, 915, 915, + 915, nil, nil, 915, 251, 251, 251, 251, 251, 251, + 251, 251, 251, 251, 251, nil, 251, 251, nil, nil, + 251, 251, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 251, nil, 251, nil, + 251, 251, 251, 251, 251, 251, 251, nil, 251, nil, + 406, 406, 406, 406, 406, 406, 406, 406, 406, 406, + 406, nil, 406, 406, nil, 251, 406, 406, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 406, nil, 406, nil, 406, 406, 406, 406, + 406, 406, 406, nil, 406, nil, 445, 445, 445, 445, + 445, 445, 445, 445, 445, 445, 445, nil, 445, 445, + nil, 406, 445, 445, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 445, nil, + 445, nil, 445, 445, 445, 445, 445, 445, 445, nil, + 445, nil, 491, 491, 491, 491, 491, 491, 491, 491, + 491, 491, 491, nil, 491, 491, 445, 445, 491, 491, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 491, nil, 491, nil, 491, 491, + 491, 491, 491, 491, 491, nil, 491, nil, 619, 619, + 619, 619, 619, 619, 619, 619, 619, 619, 619, nil, + 619, 619, nil, 491, 619, 619, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 619, nil, 619, nil, 619, 619, 619, 619, 619, 619, + 619, nil, 619, nil, 697, 697, 697, 697, 697, 697, + 697, 697, 697, 697, 697, nil, 697, 697, nil, 619, + 697, 697, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 697, nil, 697, nil, + 697, 697, 697, 697, 697, 697, 697, nil, 697, nil, + 700, 700, 700, 700, 700, 700, 700, 700, 700, 700, + 700, nil, 700, 700, nil, 697, 700, 700, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 700, nil, 700, nil, 700, 700, 700, 700, + 700, 700, 700, nil, 700, nil, 704, 704, 704, 704, + 704, 704, 704, 704, 704, 704, 704, nil, 704, 704, + nil, 700, 704, 704, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 704, nil, + 704, nil, 704, 704, 704, 704, 704, 704, 704, nil, + 704, nil, 706, 706, 706, 706, 706, 706, 706, 706, + 706, 706, 706, nil, 706, 706, nil, 704, 706, 706, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 706, nil, 706, nil, 706, 706, + 706, 706, 706, 706, 706, nil, 706, nil, 709, 709, + 709, 709, 709, 709, 709, 709, 709, 709, 709, nil, + 709, 709, nil, 706, 709, 709, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 709, nil, 709, nil, 709, 709, 709, 709, 709, 709, + 709, nil, 709, nil, 711, 711, 711, 711, 711, 711, + 711, 711, 711, 711, 711, nil, 711, 711, nil, 709, + 711, 711, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 711, nil, 711, nil, + 711, 711, 711, 711, 711, 711, 711, nil, 711, nil, + 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, + 795, nil, 795, 795, nil, 711, 795, 795, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 795, nil, 795, nil, 795, 795, 795, 795, + 795, 795, 795, nil, 795, nil, 797, 797, 797, 797, + 797, 797, 797, 797, 797, 797, 797, nil, 797, 797, + nil, 795, 797, 797, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 797, nil, + 797, nil, 797, 797, 797, 797, 797, 797, 797, nil, + 797, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 797 ] + +racc_action_pointer = [ + 0, 80, nil, 33, 849, 5297, 20962, 21086, 7, 30, + 11, 53, 139, 521, 300, 374, nil, 61, 5422, 13696, + 266, nil, 5547, 5672, 5797, 76, 348, 733, 858, nil, + 1672, 5922, 6047, nil, 197, 342, 304, 431, 6180, 6305, + 6430, 243, 548, nil, nil, nil, nil, nil, nil, nil, + 983, 1797, 6555, 6680, 6805, 0, nil, 6930, 7055, nil, + nil, 7180, 7313, 7438, 7563, 21458, nil, nil, nil, nil, + nil, nil, nil, 580, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 0, nil, nil, 130, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 383, nil, 7688, nil, nil, nil, 7821, 7946, 8071, 8196, + 8321, 1121, nil, 604, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 283, nil, 1922, 2047, 8446, 8571, 8696, + 8821, 21630, 21690, nil, nil, 8946, 9071, 9196, 9321, 9446, + nil, nil, 651, 54, 380, 107, 303, 408, nil, 9571, + 2172, 415, 9696, 9821, 9946, 10071, 10196, 10321, 10446, 10571, + 10696, 10821, 10946, 11071, 11196, 11321, 11446, 11571, 11696, 11821, + 11946, 12071, 12196, 12321, 12446, 12571, 12696, 12821, nil, nil, + nil, 22638, nil, 388, 394, nil, 12946, 446, 13071, nil, + nil, nil, nil, 13196, nil, nil, 21750, 21810, 462, 13321, + 13446, nil, nil, nil, nil, nil, nil, nil, 13571, 425, + 2297, 439, 482, 445, 13696, 2422, 684, 770, 552, 803, + 529, 529, 355, nil, 569, 474, 539, 13829, nil, 484, + 618, 622, 809, nil, 628, nil, 13954, 691, 693, 585, + nil, 158, 269, 629, 612, 270, 639, nil, nil, 599, + 48, 136, 14079, 14204, 84, 711, 617, 65, 866, 697, + 89, 730, nil, nil, 356, 418, 137, nil, 895, nil, + 55, 14329, nil, nil, 167, 419, 447, 513, 577, 582, + 707, 711, 713, nil, 744, nil, 14454, nil, 271, 341, + 347, 397, 39, 405, nil, 1218, nil, nil, nil, nil, + nil, nil, 21210, nil, nil, nil, nil, 643, 655, nil, + nil, 6048, nil, 14579, 642, nil, 649, nil, nil, 7180, + 666, nil, 614, 651, 1113, nil, nil, nil, 239, 709, + 348, nil, nil, 1238, 1368, nil, 22684, nil, nil, nil, + 115, nil, 723, 21870, 21930, 14704, 242, 14829, 14954, 15079, + 2172, 2297, 562, 691, 748, 758, 783, 785, 1557, 3672, + 3797, 2422, 1189, 1319, 2547, 2672, 2797, 2922, 3047, 3172, + 3297, 941, 1128, 3422, 3547, 22730, 398, nil, 15204, nil, + 15329, nil, 15454, nil, nil, 1498, nil, nil, 1553, nil, + nil, 727, nil, nil, 15579, 456, 460, 730, nil, 731, + 732, nil, nil, 740, 15704, 747, 15829, 21990, 22050, 928, + 788, nil, nil, 15954, 749, nil, 16079, 16204, 16329, 22110, + 22170, 22776, 16454, 867, 16579, nil, 757, nil, 16704, nil, + nil, 16829, nil, nil, nil, nil, 1077, 2547, 891, nil, + 2672, 119, 123, 901, 914, 16954, 17079, 22230, 22290, 98, + nil, nil, 1022, nil, 22350, 22410, 17204, nil, nil, 17329, + 406, 316, 2797, 1300, nil, nil, nil, 283, nil, nil, + nil, 1333, nil, nil, nil, 821, nil, nil, 61, nil, + nil, 819, nil, nil, 21334, nil, nil, 17454, 828, 17579, + 17704, 746, 873, 17829, 17954, 873, nil, nil, 18079, 882, + nil, 18204, nil, nil, 268, 272, 473, 603, 854, 7688, + 853, nil, 665, nil, 2922, 853, nil, 899, 18329, nil, + nil, nil, nil, nil, nil, 488, nil, 20829, -6, 865, + nil, 872, nil, 3047, 3172, nil, 361, 18454, 871, nil, + 876, 198, 277, 914, 497, 1058, 915, 877, 18579, 22822, + 947, 948, 335, 1007, nil, 3297, 887, 931, nil, nil, + nil, 379, 135, 1430, 896, 899, 900, 902, nil, nil, + nil, nil, nil, nil, 243, 982, nil, 858, nil, nil, + nil, nil, 989, nil, nil, 990, 624, nil, 1028, nil, + nil, nil, nil, 1038, nil, 143, 922, 141, 144, 171, + 247, 18704, 741, 1121, nil, 938, 3422, 625, nil, nil, + 1059, 3547, 1517, 724, 21570, nil, nil, nil, nil, nil, + nil, 3672, nil, nil, nil, nil, nil, 22868, 942, 18829, + 22914, 18954, nil, nil, 22960, nil, 23006, nil, nil, 23052, + nil, 23098, 19079, 19204, 19329, 402, 19454, 943, 945, 946, + nil, 972, 951, 728, 389, nil, 1075, nil, 19579, nil, + 3797, 19704, nil, nil, 966, 982, 1087, 968, 498, nil, + nil, nil, 3922, nil, nil, 163, 19829, nil, nil, nil, + nil, nil, 967, nil, 1547, nil, 5935, nil, nil, 1597, + 1049, 19954, nil, nil, 920, nil, 973, 538, 1016, 978, + nil, nil, 1096, nil, 20079, 1098, 4047, 4172, nil, 20204, + 4297, 156, 251, nil, 1110, nil, 4422, nil, 1114, 998, + nil, nil, 1024, 1008, nil, 23144, 20329, 23190, 7326, nil, + 7451, nil, nil, 1694, nil, 1033, 1014, nil, nil, nil, + 20454, nil, 1015, 1033, 1017, nil, 1019, nil, nil, nil, + nil, 4547, 164, 1024, 1103, 165, nil, 4672, 4797, 1042, + 1049, 1070, nil, nil, 1072, 1079, nil, 1083, nil, nil, + 1096, 981, 1099, 865, nil, nil, 166, nil, 1220, 1226, + nil, 215, nil, nil, 1227, nil, nil, 7576, nil, 1108, + 1112, 1120, 1124, nil, 1133, nil, 853, 1150, 1212, nil, + 20579, nil, nil, 20704, nil, 1261, 20829, 22470, 22530, 172, + 1157, 1261, nil, 13842, nil, nil, 1723, nil, 1819, nil, + 1848, nil, nil, nil, 596, 1116, 1144, 4922, nil, nil, + nil, nil, nil, 5047, nil, 5172, 15717, nil, nil, 1944, + nil, 1973, nil, nil, nil, 22590, nil, 1147, nil, 1156, + 173, 207, 271, 274, nil, nil, 1154, 1155, 1157, 1159, + 1161, 1466, 1166, 1492, 678, 1287, 1289, 1171, 1172, 1173, + 1174, 1229, 1230, nil, 209, nil, 2069, nil, nil, nil, + 1658, 1194, nil, nil, nil, nil, 2098, nil, nil, nil, + 1195, 1197, 1198, nil, nil ] + +racc_action_default = [ + -4, -552, -1, -538, -5, -552, -552, -552, -552, -552, + -552, -552, -552, -552, -273, -32, -33, -540, -552, -38, + -40, -41, -283, -319, -320, -45, -248, -248, -248, -58, + -4, -62, -70, -72, -552, -465, -552, -552, -552, -552, + -552, -540, -225, -266, -267, -268, -269, -270, -271, -272, + -526, -4, -552, -551, -518, -291, -293, -552, -552, -297, + -300, -538, -552, -552, -552, -552, -321, -322, -324, -325, + -414, -415, -416, -417, -418, -433, -421, -422, -435, -437, + -426, -431, -447, -435, -449, -450, -524, -454, -455, -525, + -457, -458, -459, -460, -461, -462, -463, -464, -467, -468, + -552, -3, -539, -547, -548, -549, -552, -552, -552, -552, + -552, -7, -8, -552, -99, -100, -101, -102, -103, -104, + -105, -106, -107, -111, -112, -113, -114, -115, -116, -117, + -118, -119, -120, -121, -122, -123, -124, -125, -126, -127, + -128, -129, -130, -131, -132, -133, -134, -135, -136, -137, + -138, -139, -140, -141, -142, -143, -144, -145, -146, -147, + -148, -149, -150, -151, -152, -153, -154, -155, -156, -157, + -158, -159, -160, -161, -162, -163, -164, -165, -166, -167, + -168, -169, -170, -171, -172, -173, -174, -175, -176, -177, + -178, -179, -180, -13, -108, -4, -4, -552, -552, -552, + -234, -552, -552, -536, -537, -552, -552, -552, -552, -540, + -541, -37, -552, -465, -552, -273, -552, -552, -217, -552, + -4, -552, -552, -552, -552, -552, -552, -552, -552, -552, + -552, -552, -552, -552, -552, -552, -552, -552, -552, -552, + -552, -552, -552, -552, -552, -552, -552, -552, -384, -386, + -42, -226, -236, -258, -258, -241, -552, -259, -552, -283, + -319, -320, -520, -552, -43, -44, -552, -552, -50, -234, + -552, -290, -389, -398, -400, -56, -395, -57, -540, -60, + -4, -540, -552, -63, -66, -4, -78, -552, -552, -85, + -286, -540, -552, -323, -396, -552, -68, -552, -74, -280, + -451, -452, -552, -202, -203, -218, -552, -406, -552, -276, + -227, -544, -544, -552, -552, -544, -552, -292, -376, -39, + -552, -552, -552, -552, -538, -552, -539, -465, -552, -552, + -273, -552, -335, -336, -94, -95, -552, -97, -552, -273, + -552, -552, -465, -312, -99, -100, -140, -141, -142, -158, + -163, -170, -173, -314, -552, -516, -552, -419, -552, -552, + -552, -552, -552, -552, 965, -6, -550, -14, -15, -16, + -17, -18, -552, -10, -11, -12, -109, -552, -552, -21, + -29, -181, -259, -552, -552, -22, -30, -31, -23, -183, + -540, -235, -527, -528, -248, -393, -529, -530, -527, -248, + -528, -392, -394, -529, -530, -28, -191, -34, -35, -36, + -540, -289, -552, -552, -552, -234, -280, -552, -552, -552, + -192, -193, -194, -195, -196, -197, -198, -199, -204, -205, + -206, -207, -208, -209, -210, -211, -212, -213, -214, -215, + -216, -219, -220, -221, -222, -540, -365, -237, -257, -238, + -257, -255, -552, -260, -523, -248, -527, -528, -248, -48, + -51, -540, -249, -250, -251, -365, -365, -540, -285, -540, + -59, -278, -75, -64, -552, -540, -234, -552, -552, -84, + -552, -451, -452, -552, -71, -76, -552, -552, -552, -552, + -552, -223, -552, -551, -551, -275, -540, -228, -546, -545, + -230, -546, -281, -282, -519, -294, -488, -4, -326, -327, + -4, -552, -552, -552, -552, -552, -234, -552, -552, -280, + -305, -94, -95, -96, -552, -552, -234, -308, -469, -552, + -552, -552, -4, -488, -316, -534, -535, -540, -420, -434, + -439, -552, -441, -423, -436, -552, -438, -425, -552, -428, + -430, -552, -448, -9, -552, -19, -20, -552, -265, -552, + -552, -397, -552, -552, -552, -52, -233, -390, -552, -54, + -391, -552, -288, -542, -527, -528, -527, -528, -540, -181, + -552, -366, -370, -368, -4, -258, -256, -261, -552, -521, + -522, -46, -387, -47, -388, -365, -231, -38, -552, -258, + -247, -540, -253, -4, -4, -284, -61, -552, -67, -73, + -540, -527, -528, -232, -531, -83, -552, -69, -552, -190, + -200, -201, -540, -551, -333, -4, -407, -551, -408, -409, + -277, -544, -552, -488, -370, -515, -515, -515, -487, -489, + -490, -491, -492, -493, -494, -552, -497, -552, -499, -505, + -507, -508, -510, -511, -512, -552, -551, -328, -551, -298, + -329, -330, -301, -552, -304, -552, -540, -527, -528, -531, + -279, -552, -94, -95, -98, -540, -4, -552, -471, -310, + -552, -4, -488, -552, -552, -517, -440, -443, -444, -445, + -446, -4, -424, -427, -429, -432, -110, -182, -263, -552, + -184, -552, -543, -25, -186, -26, -187, -53, -27, -188, + -55, -189, -552, -552, -552, -397, -552, -515, -515, -515, + -364, -552, -370, -552, -494, -503, -552, -239, -257, -262, + -4, -552, -244, -252, -540, -552, -552, -65, -397, -77, + -287, -2, -4, -413, -334, -552, -552, -411, -229, -377, + -380, -382, -370, -379, -552, -480, -552, -483, -485, -552, + -552, -552, -496, -337, -552, -339, -341, -348, -494, -540, + -509, -513, -552, -331, -552, -552, -4, -4, -303, -552, + -4, -397, -552, -397, -552, -470, -4, -313, -552, -540, + -473, -317, -552, -264, -24, -185, -552, -224, -355, -357, + -552, -360, -362, -552, -367, -552, -371, -372, -374, -375, + -552, -385, -258, -552, -258, -243, -258, -254, -399, -401, + -412, -4, -465, -552, -552, -273, -410, -4, -4, -540, + -515, -515, -500, -514, -515, -515, -506, -515, -495, -501, + -540, -552, -346, -552, -498, -295, -552, -296, -552, -552, + -261, -551, -306, -309, -552, -315, -472, -488, -442, -515, + -515, -515, -515, -504, -515, -369, -552, -502, -552, -240, + -257, -49, -242, -257, -245, -406, -234, -552, -552, -280, + -552, -552, -378, -552, -476, -478, -552, -481, -552, -484, + -552, -486, -338, -340, -344, -552, -349, -4, -299, -302, + -402, -403, -404, -4, -311, -4, -552, -352, -354, -552, + -358, -552, -361, -363, -373, -552, -280, -258, -405, -540, + -527, -528, -531, -279, -381, -383, -515, -515, -515, -515, + -342, -552, -347, -552, -551, -552, -552, -515, -515, -515, + -515, -279, -531, -246, -397, -474, -552, -477, -479, -482, + -552, -345, -332, -307, -318, -350, -552, -353, -356, -359, + -515, -343, -515, -475, -351 ] + +racc_goto_table = [ + 117, 117, 208, 10, 201, 312, 315, 308, 10, 493, + 310, 390, 717, 293, 293, 353, 266, 12, 283, 507, + 510, 311, 12, 623, 320, 321, 306, 681, 324, 514, + 772, 105, 101, 10, 394, 399, 380, 387, 252, 252, + 252, 718, 589, 296, 293, 293, 293, 12, 112, 194, + 561, 523, 447, 449, 10, 120, 120, 807, 638, 117, + 460, 122, 122, 809, 634, 332, 272, 276, 12, 896, + 268, 275, 277, 367, 368, 369, 370, 659, 662, 586, + 461, 586, 250, 264, 265, 638, 832, 497, 500, 105, + 325, 504, 721, 589, 211, 600, 584, 836, 863, 455, + 458, 769, 359, 893, 111, 10, 592, 363, 1, 594, + 279, 340, 343, 10, 484, 603, 604, 281, 741, 12, + 102, 932, 193, 333, 719, 372, 595, 12, 554, 313, + 832, 602, 462, 539, 720, 546, 549, 601, 734, 355, + 314, 317, 505, 331, 753, 527, 354, 534, 496, 318, + 322, 776, 323, 777, 671, 903, 676, 951, 786, 532, + 533, 684, 857, 722, 806, 384, 384, 632, 749, 506, + 249, 827, 828, 446, 465, 466, 961, 900, 627, 745, + 357, 358, 360, 361, 548, 638, 835, 362, 775, 837, + 686, 752, 691, 830, 763, 893, 404, 13, 10, 10, + 914, 365, 13, 413, 863, nil, 809, nil, nil, 371, + nil, nil, 12, 12, nil, 212, 252, 663, 840, 212, + 212, 212, 832, 10, 836, nil, 578, 13, 287, 287, + 862, nil, 805, 864, 638, nil, nil, 12, 715, 674, + 789, 395, nil, nil, nil, 730, 394, 399, 13, 212, + nil, nil, nil, nil, 212, 212, nil, 859, 212, 328, + 338, 338, 829, nil, nil, nil, 293, nil, nil, nil, + 738, nil, nil, 379, 385, 388, 480, nil, 477, 293, + nil, 405, nil, 10, 485, 252, 252, 610, 10, 511, + 512, 608, nil, 489, 252, 473, 831, 12, 834, 13, + 617, nil, 12, 212, 212, 212, 212, 13, 952, nil, + 613, 763, nil, 927, 842, nil, 928, nil, 929, 517, + 589, nil, 613, 694, nil, nil, 781, 666, nil, nil, + 463, nil, 272, 628, 276, 783, 938, 675, 467, 939, + 860, 940, 861, nil, nil, 535, nil, nil, 852, nil, + 613, 905, 105, 513, nil, nil, nil, 707, 613, 586, + 279, 710, 815, nil, 780, 279, 117, 469, 528, nil, + nil, nil, 475, nil, nil, 562, 960, nil, nil, nil, + nil, 901, nil, nil, 727, nil, 962, nil, 763, nil, + 763, nil, 13, 13, 212, 212, 212, 212, 732, nil, + 585, nil, 212, 212, 212, 212, 212, 748, 404, 638, + nil, nil, nil, nil, 553, nil, 599, 13, nil, nil, + nil, 120, nil, nil, 737, 926, nil, 122, nil, nil, + 580, 252, nil, nil, 566, nil, nil, nil, 565, 570, + nil, 930, 763, 569, 821, nil, nil, nil, 937, nil, + 631, 629, nil, 395, nil, nil, 293, nil, nil, nil, + nil, 485, 384, nil, nil, 293, 212, 212, nil, nil, + 485, nil, 404, nil, nil, 212, nil, 13, 763, nil, + 763, 287, 13, 665, 404, nil, nil, nil, 680, nil, + nil, nil, 252, nil, 287, 566, 677, 763, 566, 591, + nil, 586, 593, nil, 586, nil, nil, nil, nil, nil, + 10, nil, 404, 10, nil, nil, nil, 395, 404, 212, + 212, nil, nil, nil, 12, nil, nil, 12, nil, 395, + nil, nil, 252, nil, nil, 10, nil, nil, 212, 660, + 660, nil, 252, nil, nil, 897, nil, nil, 117, 12, + nil, nil, nil, 212, nil, 902, nil, 395, 678, 679, + nil, nil, nil, 562, nil, 395, nil, 14, nil, nil, + nil, nil, 14, nil, nil, nil, nil, 918, 2, 944, + 743, nil, nil, nil, 747, nil, nil, 10, nil, 293, + nil, nil, nil, nil, 485, 562, 696, 14, 289, 289, + 293, 12, nil, 120, nil, 739, 10, 10, 282, 122, + nil, 869, 212, 872, nil, 874, nil, nil, 14, nil, + 12, 12, nil, nil, nil, nil, nil, nil, 10, 330, + 339, 339, 784, nil, 791, nil, nil, 788, 782, 703, + 705, nil, 12, nil, 708, nil, nil, nil, nil, nil, + nil, 562, nil, 566, nil, nil, 570, nil, nil, nil, + 562, 212, nil, nil, nil, nil, nil, nil, nil, 14, + nil, 287, nil, 212, nil, nil, nil, 14, 117, 10, + 287, nil, nil, 816, 10, nil, nil, 919, nil, 212, + nil, nil, nil, 12, 10, nil, 812, nil, 12, 814, + nil, nil, nil, nil, 13, 785, nil, 13, 12, nil, + 613, 790, nil, 212, nil, nil, 943, nil, nil, nil, + nil, nil, nil, 212, nil, nil, 212, nil, 293, 13, + nil, nil, nil, 10, nil, nil, nil, nil, nil, 411, + nil, 846, 854, nil, nil, 10, nil, 12, nil, 826, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 12, + 212, 212, 14, 14, nil, 212, nil, nil, nil, nil, + nil, nil, nil, 377, 378, nil, nil, 794, nil, 10, + 10, 13, nil, 10, nil, nil, nil, 14, nil, 10, + nil, nil, 293, 12, 12, nil, nil, 12, 282, nil, + 13, 13, nil, 12, 287, nil, nil, nil, 468, nil, + 660, 470, nil, nil, 877, 287, nil, nil, nil, nil, + nil, nil, 13, nil, 10, 917, nil, nil, nil, nil, + 10, 10, nil, nil, nil, nil, nil, nil, 12, nil, + nil, nil, nil, nil, 12, 12, nil, 14, nil, nil, + nil, 289, 14, nil, nil, nil, nil, nil, 282, nil, + nil, 936, nil, 282, 289, nil, nil, nil, 212, nil, + nil, nil, 404, 13, nil, nil, nil, nil, 13, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 13, nil, + nil, nil, 252, nil, nil, nil, nil, nil, 212, nil, + 10, nil, nil, nil, 562, nil, 10, nil, 10, 404, + nil, nil, nil, nil, 12, nil, nil, 395, nil, nil, + 12, nil, 12, nil, nil, nil, nil, 13, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 26, nil, 13, + 572, nil, 26, 823, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 26, nil, nil, nil, 26, + 26, 26, nil, nil, nil, nil, nil, 26, nil, nil, + nil, 212, nil, 13, 13, nil, nil, 13, nil, nil, + nil, nil, nil, 13, nil, nil, nil, nil, 26, 26, + nil, 596, nil, nil, 26, 26, nil, 605, 26, 606, + nil, nil, nil, nil, nil, 609, nil, 867, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 13, nil, + nil, nil, nil, nil, 13, 13, 630, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 26, + nil, 289, nil, 26, 26, 26, 26, 26, nil, nil, + 289, nil, nil, nil, nil, nil, 309, nil, nil, nil, + nil, 319, 319, nil, nil, 319, nil, 685, nil, nil, + nil, nil, nil, 212, 14, nil, nil, 14, nil, nil, + nil, nil, nil, nil, nil, 656, nil, nil, 658, nil, + nil, nil, nil, nil, 13, nil, nil, nil, nil, 14, + 13, nil, 13, nil, nil, nil, nil, nil, 690, nil, + 319, 319, 319, 319, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 316, nil, + nil, 733, 26, 26, 26, 26, 26, 26, nil, nil, + nil, nil, 26, 26, 26, 26, 26, nil, nil, nil, + nil, 14, 740, nil, nil, nil, nil, 26, nil, nil, + nil, nil, 726, nil, nil, nil, nil, nil, nil, nil, + 14, 14, nil, nil, 289, nil, nil, nil, nil, nil, + nil, 735, 736, nil, nil, 289, nil, nil, nil, nil, + nil, nil, 14, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 744, nil, nil, 26, 26, nil, nil, + 407, 408, 409, 410, nil, 26, nil, 26, nil, 35, + nil, nil, 26, nil, 35, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 14, nil, nil, nil, nil, 14, 35, + 286, 286, nil, nil, nil, nil, nil, nil, 14, 26, + 26, nil, nil, nil, 817, nil, nil, nil, nil, 792, + 35, 382, 386, nil, nil, nil, nil, nil, 26, nil, + nil, 327, 342, 342, 342, nil, nil, nil, nil, nil, + nil, nil, nil, 26, nil, nil, nil, 14, nil, 844, + nil, nil, nil, nil, nil, nil, nil, nil, 813, 14, + nil, nil, nil, 825, nil, nil, nil, nil, nil, 856, + 820, 35, nil, nil, nil, nil, 319, 319, nil, 35, + 451, nil, 453, nil, nil, nil, nil, 454, nil, nil, + nil, nil, nil, 14, 14, 531, nil, 14, nil, nil, + nil, nil, 26, 14, 848, 849, nil, nil, 851, 882, + 537, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 892, nil, nil, nil, nil, nil, nil, 339, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 14, nil, + nil, nil, nil, nil, 14, 14, nil, nil, nil, 875, + nil, 26, nil, nil, nil, 880, 881, nil, nil, nil, + nil, nil, nil, 26, 35, 35, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 26, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 35, + nil, nil, nil, nil, 26, nil, nil, 26, nil, nil, + nil, nil, nil, 26, nil, nil, nil, 558, nil, nil, + nil, nil, nil, 26, 14, nil, 26, nil, 309, 26, + 14, nil, 14, nil, nil, 934, nil, nil, nil, nil, + nil, 935, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 622, nil, nil, 35, + 26, 26, nil, 286, 35, 26, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 286, nil, nil, nil, + nil, 26, 587, nil, 316, nil, 590, nil, nil, nil, + nil, nil, nil, 319, nil, nil, nil, nil, 598, nil, + 26, 26, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 26, nil, nil, nil, nil, nil, 626, nil, + nil, nil, 587, nil, nil, 316, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 382, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 26, nil, + nil, nil, nil, 26, nil, nil, nil, nil, 26, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 26, nil, + nil, nil, nil, 698, nil, nil, nil, nil, 26, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 218, nil, nil, nil, 251, 251, 251, nil, nil, + nil, nil, 729, nil, nil, nil, nil, 26, nil, nil, + nil, 303, 304, 305, nil, 319, nil, nil, nil, 26, + nil, nil, nil, nil, nil, nil, 251, 251, 755, 757, + 758, nil, nil, 286, nil, nil, nil, nil, nil, nil, + nil, nil, 286, nil, nil, nil, nil, nil, nil, nil, + nil, 26, nil, 26, 26, nil, nil, 26, nil, nil, + nil, nil, nil, 26, nil, nil, 35, nil, nil, 35, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 35, nil, nil, nil, nil, nil, nil, 26, nil, + nil, nil, nil, nil, 26, 26, nil, nil, nil, nil, + 799, 801, 802, 793, nil, nil, nil, nil, 319, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 35, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 26, nil, nil, nil, nil, nil, nil, + nil, nil, 35, 35, nil, nil, 286, nil, nil, nil, + 381, 251, 389, 251, 26, 839, nil, 286, 406, nil, + 26, nil, 26, nil, 35, nil, nil, nil, nil, nil, + nil, nil, 218, 850, nil, 420, 421, 422, 423, 424, + 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, + 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, + 445, nil, nil, 884, 885, nil, nil, 887, 889, 251, + 891, 251, nil, nil, nil, 35, 251, nil, nil, nil, + 35, nil, 251, 251, nil, nil, nil, nil, nil, nil, + 35, 251, 907, 908, 910, 912, nil, 913, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 491, + nil, nil, nil, nil, 850, nil, nil, 587, nil, 35, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 35, nil, nil, nil, 822, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 945, + 947, 948, 949, nil, nil, nil, nil, nil, nil, nil, + 955, 957, 958, 959, nil, 35, 35, nil, nil, 35, + nil, nil, nil, nil, nil, 35, nil, nil, nil, nil, + nil, nil, nil, 963, nil, 964, 251, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 342, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 35, nil, nil, nil, nil, nil, 35, 35, 251, nil, + 406, 579, 389, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, 251, nil, 251, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 597, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, nil, nil, 35, nil, nil, 619, + 620, 621, 35, nil, 35, nil, nil, 251, nil, nil, + nil, 251, nil, nil, 251, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 251, 251, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 251, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 697, nil, 251, 700, nil, nil, 704, 706, nil, nil, + nil, 709, nil, nil, 711, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, 795, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 704, 706, 709, nil, 797, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 251, nil, nil, 251, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 251, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 251, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 795, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 251, nil, nil, 251, nil, nil, 251 ] + +racc_goto_check = [ + 50, 50, 27, 14, 21, 61, 61, 3, 14, 4, + 58, 19, 113, 56, 56, 49, 21, 17, 43, 82, + 82, 59, 17, 5, 13, 13, 27, 91, 13, 85, + 83, 89, 8, 14, 33, 33, 23, 23, 29, 29, + 29, 114, 155, 44, 56, 56, 56, 17, 11, 11, + 20, 47, 64, 64, 14, 53, 53, 121, 117, 50, + 35, 54, 54, 122, 126, 14, 62, 62, 17, 111, + 34, 34, 34, 13, 13, 13, 13, 84, 84, 65, + 19, 65, 31, 31, 31, 117, 150, 60, 60, 89, + 8, 60, 119, 155, 15, 65, 36, 151, 152, 33, + 33, 110, 141, 108, 9, 14, 63, 141, 1, 63, + 39, 48, 48, 14, 45, 36, 36, 40, 6, 17, + 10, 111, 12, 16, 115, 26, 37, 17, 55, 57, + 150, 66, 67, 145, 117, 145, 145, 69, 70, 77, + 78, 79, 81, 86, 119, 88, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, 102, 111, 103, 104, + 105, 106, 107, 112, 120, 59, 59, 123, 124, 125, + 127, 128, 129, 130, 132, 133, 111, 134, 135, 136, + 139, 140, 142, 143, 144, 117, 113, 146, 5, 113, + 147, 126, 148, 149, 109, 108, 50, 18, 14, 14, + 121, 9, 18, 21, 152, nil, 122, nil, nil, 9, + nil, nil, 17, 17, nil, 18, 29, 85, 110, 18, + 18, 18, 150, 14, 151, nil, 19, 18, 18, 18, + 113, nil, 119, 113, 117, nil, nil, 17, 20, 47, + 126, 62, nil, nil, nil, 36, 33, 33, 18, 18, + nil, nil, nil, nil, 18, 18, nil, 114, 18, 18, + 18, 18, 119, nil, nil, nil, 56, nil, nil, nil, + 20, nil, nil, 15, 15, 15, 27, nil, 21, 56, + nil, 15, nil, 14, 43, 29, 29, 19, 14, 13, + 13, 45, nil, 21, 29, 44, 115, 17, 115, 18, + 45, nil, 17, 18, 18, 18, 18, 18, 83, nil, + 33, 109, nil, 113, 109, nil, 113, nil, 113, 21, + 155, nil, 33, 145, nil, nil, 20, 19, nil, nil, + 31, nil, 62, 23, 62, 20, 113, 19, 31, 113, + 115, 113, 115, nil, nil, 21, nil, nil, 84, nil, + 33, 91, 89, 8, nil, nil, nil, 35, 33, 65, + 39, 35, 65, nil, 82, 39, 50, 40, 89, nil, + nil, nil, 40, nil, nil, 27, 113, nil, nil, nil, + nil, 5, nil, nil, 64, nil, 113, nil, 109, nil, + 109, nil, 18, 18, 18, 18, 18, 18, 64, nil, + 61, nil, 18, 18, 18, 18, 18, 60, 50, 117, + nil, nil, nil, nil, 11, nil, 61, 18, nil, nil, + nil, 53, nil, nil, 45, 115, nil, 54, nil, nil, + 27, 29, nil, nil, 62, nil, nil, nil, 34, 62, + nil, 109, 109, 34, 82, nil, nil, nil, 115, nil, + 61, 58, nil, 62, nil, nil, 56, nil, nil, nil, + nil, 43, 59, nil, nil, 56, 18, 18, nil, nil, + 43, nil, 50, nil, nil, 18, nil, 18, 109, nil, + 109, 18, 18, 59, 50, nil, nil, nil, 3, nil, + nil, nil, 29, nil, 18, 62, 13, 109, 62, 34, + nil, 65, 34, nil, 65, nil, nil, nil, nil, nil, + 14, nil, 50, 14, nil, nil, nil, 62, 50, 18, + 18, nil, nil, nil, 17, nil, nil, 17, nil, 62, + nil, nil, 29, nil, nil, 14, nil, nil, 18, 89, + 89, nil, 29, nil, nil, 82, nil, nil, 50, 17, + nil, nil, nil, 18, nil, 85, nil, 62, 89, 89, + nil, nil, nil, 27, nil, 62, nil, 22, nil, nil, + nil, nil, 22, nil, nil, nil, nil, 4, 2, 20, + 58, nil, nil, nil, 58, nil, nil, 14, nil, 56, + nil, nil, nil, nil, 43, 27, 11, 22, 22, 22, + 56, 17, nil, 53, nil, 43, 14, 14, 2, 54, + nil, 64, 18, 64, nil, 64, nil, nil, 22, nil, + 17, 17, nil, nil, nil, nil, nil, nil, 14, 22, + 22, 22, 3, nil, 49, nil, nil, 3, 13, 15, + 15, nil, 17, nil, 15, nil, nil, nil, nil, nil, + nil, 27, nil, 62, nil, nil, 62, nil, nil, nil, + 27, 18, nil, nil, nil, nil, nil, nil, nil, 22, + nil, 18, nil, 18, nil, nil, nil, 22, 50, 14, + 18, nil, nil, 61, 14, nil, nil, 19, nil, 18, + nil, nil, nil, 17, 14, nil, 59, nil, 17, 59, + nil, nil, nil, nil, 18, 89, nil, 18, 17, nil, + 33, 89, nil, 18, nil, nil, 64, nil, nil, nil, + nil, nil, nil, 18, nil, nil, 18, nil, 56, 18, + nil, nil, nil, 14, nil, nil, nil, nil, nil, 41, + nil, 13, 3, nil, nil, 14, nil, 17, nil, 14, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 17, + 18, 18, 22, 22, nil, 18, nil, nil, nil, nil, + nil, nil, nil, 2, 2, nil, nil, 15, nil, 14, + 14, 18, nil, 14, nil, nil, nil, 22, nil, 14, + nil, nil, 56, 17, 17, nil, nil, 17, 2, nil, + 18, 18, nil, 17, 18, nil, nil, nil, 41, nil, + 89, 41, nil, nil, 21, 18, nil, nil, nil, nil, + nil, nil, 18, nil, 14, 61, nil, nil, nil, nil, + 14, 14, nil, nil, nil, nil, nil, nil, 17, nil, + nil, nil, nil, nil, 17, 17, nil, 22, nil, nil, + nil, 22, 22, nil, nil, nil, nil, nil, 2, nil, + nil, 3, nil, 2, 22, nil, nil, nil, 18, nil, + nil, nil, 50, 18, nil, nil, nil, nil, 18, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 18, nil, + nil, nil, 29, nil, nil, nil, nil, nil, 18, nil, + 14, nil, nil, nil, 27, nil, 14, nil, 14, 50, + nil, nil, nil, nil, 17, nil, nil, 62, nil, nil, + 17, nil, 17, nil, nil, nil, nil, 18, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 38, nil, 18, + 41, nil, 38, 18, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 38, nil, nil, nil, 38, + 38, 38, nil, nil, nil, nil, nil, 38, nil, nil, + nil, 18, nil, 18, 18, nil, nil, 18, nil, nil, + nil, nil, nil, 18, nil, nil, nil, nil, 38, 38, + nil, 41, nil, nil, 38, 38, nil, 41, 38, 41, + nil, nil, nil, nil, nil, 41, nil, 18, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 18, nil, + nil, nil, nil, nil, 18, 18, 41, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 38, + nil, 22, nil, 38, 38, 38, 38, 38, nil, nil, + 22, nil, nil, nil, nil, nil, 25, nil, nil, nil, + nil, 25, 25, nil, nil, 25, nil, 41, nil, nil, + nil, nil, nil, 18, 22, nil, nil, 22, nil, nil, + nil, nil, nil, nil, nil, 2, nil, nil, 2, nil, + nil, nil, nil, nil, 18, nil, nil, nil, nil, 22, + 18, nil, 18, nil, nil, nil, nil, nil, 22, nil, + 25, 25, 25, 25, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 24, nil, + nil, 41, 38, 38, 38, 38, 38, 38, nil, nil, + nil, nil, 38, 38, 38, 38, 38, nil, nil, nil, + nil, 22, 41, nil, nil, nil, nil, 38, nil, nil, + nil, nil, 2, nil, nil, nil, nil, nil, nil, nil, + 22, 22, nil, nil, 22, nil, nil, nil, nil, nil, + nil, 2, 2, nil, nil, 22, nil, nil, nil, nil, + nil, nil, 22, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 2, nil, nil, 38, 38, nil, nil, + 25, 25, 25, 25, nil, 38, nil, 38, nil, 46, + nil, nil, 38, nil, 46, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 22, nil, nil, nil, nil, 22, 46, + 46, 46, nil, nil, nil, nil, nil, nil, 22, 38, + 38, nil, nil, nil, 41, nil, nil, nil, nil, 2, + 46, 24, 24, nil, nil, nil, nil, nil, 38, nil, + nil, 46, 46, 46, 46, nil, nil, nil, nil, nil, + nil, nil, nil, 38, nil, nil, nil, 22, nil, 41, + nil, nil, nil, nil, nil, nil, nil, nil, 2, 22, + nil, nil, nil, 22, nil, nil, nil, nil, nil, 41, + 2, 46, nil, nil, nil, nil, 25, 25, nil, 46, + 24, nil, 24, nil, nil, nil, nil, 24, nil, nil, + nil, nil, nil, 22, 22, 25, nil, 22, nil, nil, + nil, nil, 38, 22, 2, 2, nil, nil, 2, 41, + 25, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 41, nil, nil, nil, nil, nil, nil, 22, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 22, nil, + nil, nil, nil, nil, 22, 22, nil, nil, nil, 2, + nil, 38, nil, nil, nil, 2, 2, nil, nil, nil, + nil, nil, nil, 38, 46, 46, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 38, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 46, + nil, nil, nil, nil, 38, nil, nil, 38, nil, nil, + nil, nil, nil, 38, nil, nil, nil, 24, nil, nil, + nil, nil, nil, 38, 22, nil, 38, nil, 25, 38, + 22, nil, 22, nil, nil, 2, nil, nil, nil, nil, + nil, 2, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 25, nil, nil, 46, + 38, 38, nil, 46, 46, 38, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 46, nil, nil, nil, + nil, 38, 24, nil, 24, nil, 24, nil, nil, nil, + nil, nil, nil, 25, nil, nil, nil, nil, 24, nil, + 38, 38, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 38, nil, nil, nil, nil, nil, 24, nil, + nil, nil, 24, nil, nil, 24, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 24, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 38, nil, + nil, nil, nil, 38, nil, nil, nil, nil, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 38, nil, + nil, nil, nil, 24, nil, nil, nil, nil, 38, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 28, nil, nil, nil, 28, 28, 28, nil, nil, + nil, nil, 24, nil, nil, nil, nil, 38, nil, nil, + nil, 28, 28, 28, nil, 25, nil, nil, nil, 38, + nil, nil, nil, nil, nil, nil, 28, 28, 116, 116, + 116, nil, nil, 46, nil, nil, nil, nil, nil, nil, + nil, nil, 46, nil, nil, nil, nil, nil, nil, nil, + nil, 38, nil, 38, 38, nil, nil, 38, nil, nil, + nil, nil, nil, 38, nil, nil, 46, nil, nil, 46, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 46, nil, nil, nil, nil, nil, nil, 38, nil, + nil, nil, nil, nil, 38, 38, nil, nil, nil, nil, + 116, 116, 116, 24, nil, nil, nil, nil, 25, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 46, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 38, nil, nil, nil, nil, nil, nil, + nil, nil, 46, 46, nil, nil, 46, nil, nil, nil, + 28, 28, 28, 28, 38, 24, nil, 46, 28, nil, + 38, nil, 38, nil, 46, nil, nil, nil, nil, nil, + nil, nil, 28, 24, nil, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, nil, nil, 116, 116, nil, nil, 116, 116, 28, + 116, 28, nil, nil, nil, 46, 28, nil, nil, nil, + 46, nil, 28, 28, nil, nil, nil, nil, nil, nil, + 46, 28, 116, 116, 116, 116, nil, 116, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 28, + nil, nil, nil, nil, 24, nil, nil, 24, nil, 46, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 46, nil, nil, nil, 46, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 116, + 116, 116, 116, nil, nil, nil, nil, nil, nil, nil, + 116, 116, 116, 116, nil, 46, 46, nil, nil, 46, + nil, nil, nil, nil, nil, 46, nil, nil, nil, nil, + nil, nil, nil, 116, nil, 116, 28, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 46, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 46, nil, nil, nil, nil, nil, 46, 46, 28, nil, + 28, 28, 28, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 28, nil, 28, nil, 28, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, 28, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 28, + nil, nil, nil, nil, nil, nil, 46, nil, nil, 28, + 28, 28, 46, nil, 46, nil, nil, 28, nil, nil, + nil, 28, nil, nil, 28, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 28, 28, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 28, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + 28, nil, 28, 28, nil, nil, 28, 28, nil, nil, + nil, 28, nil, nil, 28, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 28, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 28, nil, 28, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 28, 28, 28, nil, 28, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, 28, nil, nil, 28, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, 28, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, 28, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, 28, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, 28, nil, nil, 28, nil, nil, 28 ] + +racc_goto_pointer = [ + nil, 108, 578, -44, -298, -470, -505, nil, 29, 99, + 117, 42, 115, -33, 3, 76, 61, 17, 197, -189, + -340, -9, 567, -161, 1074, 1004, 13, -15, 1633, 16, + nil, 60, nil, -167, 44, -208, -350, -333, 937, 80, + 87, 530, nil, -13, 11, -183, 1219, -285, 48, -50, + -6, nil, nil, 49, 55, -248, -18, 76, -43, -32, + -224, -48, 40, -349, -201, -369, -333, -138, nil, -327, + -464, nil, nil, nil, nil, nil, nil, 74, 86, 86, + nil, -176, -301, -626, -434, -296, 81, nil, -195, 28, + nil, -506, 81, -207, -161, 93, 91, -508, 92, -509, + -366, -697, -371, -521, -184, -193, -373, -629, -738, -453, + -546, -774, -419, -570, -541, -458, 1053, -448, nil, -490, + -559, -666, -660, -339, -464, -149, -442, 150, -579, -579, + -75, nil, -99, -99, -674, -316, -448, nil, nil, 107, + 106, 24, 103, 103, -177, -225, 106, -351, -350, -561, + -668, -659, -702, nil, nil, -408 ] + +racc_goto_default = [ + nil, nil, 307, nil, nil, 773, nil, 3, nil, 4, + 326, nil, nil, nil, 216, 16, 11, 217, 302, nil, + nil, 525, 215, nil, 257, 15, nil, 412, 19, 20, + 21, 391, 25, 616, nil, nil, nil, nil, 292, 29, + nil, nil, 31, 34, 33, nil, 213, 337, nil, 119, + 397, 118, 121, 71, 72, nil, 42, nil, 624, 253, + nil, 254, 402, 567, nil, 255, nil, nil, 270, nil, + nil, 43, 44, 45, 46, 47, 48, 49, nil, 271, + 55, nil, nil, nil, nil, nil, nil, 63, nil, 508, + 64, nil, nil, nil, nil, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, nil, nil, 765, 646, + nil, 766, nil, 635, nil, 637, nil, 833, 581, nil, + nil, nil, 643, nil, nil, nil, 683, nil, nil, nil, + nil, 401, nil, nil, nil, nil, nil, 70, 73, 74, + nil, nil, nil, nil, nil, 544, nil, nil, nil, 636, + 648, 649, 725, 652, 655, 262 ] + +racc_reduce_table = [ + 0, 0, :racc_error, + 1, 139, :_reduce_none, + 4, 141, :_reduce_2, + 2, 140, :_reduce_3, + 0, 145, :_reduce_4, + 1, 145, :_reduce_5, + 3, 145, :_reduce_6, + 2, 145, :_reduce_7, + 0, 164, :_reduce_8, + 4, 147, :_reduce_9, + 3, 147, :_reduce_10, + 3, 147, :_reduce_11, + 3, 147, :_reduce_12, + 2, 147, :_reduce_13, + 3, 147, :_reduce_14, + 3, 147, :_reduce_15, + 3, 147, :_reduce_16, + 3, 147, :_reduce_17, + 3, 147, :_reduce_18, + 4, 147, :_reduce_19, + 4, 147, :_reduce_20, + 3, 147, :_reduce_21, + 3, 147, :_reduce_22, + 3, 147, :_reduce_23, + 6, 147, :_reduce_24, + 5, 147, :_reduce_25, + 5, 147, :_reduce_26, + 5, 147, :_reduce_27, + 3, 147, :_reduce_28, + 3, 147, :_reduce_29, + 3, 147, :_reduce_30, + 3, 147, :_reduce_31, + 1, 147, :_reduce_none, + 1, 163, :_reduce_none, + 3, 163, :_reduce_34, + 3, 163, :_reduce_35, + 3, 163, :_reduce_36, + 2, 163, :_reduce_37, + 1, 163, :_reduce_none, + 1, 151, :_reduce_none, + 1, 153, :_reduce_none, + 1, 153, :_reduce_none, + 2, 153, :_reduce_42, + 2, 153, :_reduce_43, + 2, 153, :_reduce_44, + 1, 168, :_reduce_none, + 4, 168, :_reduce_46, + 4, 168, :_reduce_47, + 0, 175, :_reduce_48, + 5, 173, :_reduce_49, + 2, 167, :_reduce_50, + 3, 167, :_reduce_51, + 4, 167, :_reduce_52, + 5, 167, :_reduce_53, + 4, 167, :_reduce_54, + 5, 167, :_reduce_55, + 2, 167, :_reduce_56, + 2, 167, :_reduce_57, + 1, 154, :_reduce_58, + 3, 154, :_reduce_59, + 1, 178, :_reduce_60, + 3, 178, :_reduce_61, + 1, 177, :_reduce_none, + 2, 177, :_reduce_63, + 3, 177, :_reduce_64, + 5, 177, :_reduce_65, + 2, 177, :_reduce_66, + 4, 177, :_reduce_67, + 2, 177, :_reduce_68, + 4, 177, :_reduce_69, + 1, 177, :_reduce_70, + 3, 177, :_reduce_71, + 1, 181, :_reduce_none, + 3, 181, :_reduce_73, + 2, 180, :_reduce_74, + 3, 180, :_reduce_75, + 1, 183, :_reduce_76, + 3, 183, :_reduce_77, + 1, 182, :_reduce_78, + 4, 182, :_reduce_79, + 3, 182, :_reduce_80, + 3, 182, :_reduce_81, + 3, 182, :_reduce_82, + 3, 182, :_reduce_83, + 2, 182, :_reduce_84, + 1, 182, :_reduce_85, + 1, 152, :_reduce_86, + 4, 152, :_reduce_87, + 3, 152, :_reduce_88, + 3, 152, :_reduce_89, + 3, 152, :_reduce_90, + 3, 152, :_reduce_91, + 2, 152, :_reduce_92, + 1, 152, :_reduce_93, + 1, 185, :_reduce_94, + 1, 185, :_reduce_none, + 2, 186, :_reduce_96, + 1, 186, :_reduce_97, + 3, 186, :_reduce_98, + 1, 187, :_reduce_none, + 1, 187, :_reduce_none, + 1, 187, :_reduce_none, + 1, 187, :_reduce_none, + 1, 187, :_reduce_none, + 1, 190, :_reduce_104, + 1, 190, :_reduce_none, + 1, 149, :_reduce_none, + 1, 149, :_reduce_none, + 1, 150, :_reduce_108, + 0, 193, :_reduce_109, + 4, 150, :_reduce_110, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 188, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 1, 189, :_reduce_none, + 3, 166, :_reduce_181, + 5, 166, :_reduce_182, + 3, 166, :_reduce_183, + 5, 166, :_reduce_184, + 6, 166, :_reduce_185, + 5, 166, :_reduce_186, + 5, 166, :_reduce_187, + 5, 166, :_reduce_188, + 5, 166, :_reduce_189, + 4, 166, :_reduce_190, + 3, 166, :_reduce_191, + 3, 166, :_reduce_192, + 3, 166, :_reduce_193, + 3, 166, :_reduce_194, + 3, 166, :_reduce_195, + 3, 166, :_reduce_196, + 3, 166, :_reduce_197, + 3, 166, :_reduce_198, + 3, 166, :_reduce_199, + 4, 166, :_reduce_200, + 4, 166, :_reduce_201, + 2, 166, :_reduce_202, + 2, 166, :_reduce_203, + 3, 166, :_reduce_204, + 3, 166, :_reduce_205, + 3, 166, :_reduce_206, + 3, 166, :_reduce_207, + 3, 166, :_reduce_208, + 3, 166, :_reduce_209, + 3, 166, :_reduce_210, + 3, 166, :_reduce_211, + 3, 166, :_reduce_212, + 3, 166, :_reduce_213, + 3, 166, :_reduce_214, + 3, 166, :_reduce_215, + 3, 166, :_reduce_216, + 2, 166, :_reduce_217, + 2, 166, :_reduce_218, + 3, 166, :_reduce_219, + 3, 166, :_reduce_220, + 3, 166, :_reduce_221, + 3, 166, :_reduce_222, + 3, 166, :_reduce_223, + 6, 166, :_reduce_224, + 1, 166, :_reduce_none, + 1, 162, :_reduce_none, + 1, 195, :_reduce_none, + 2, 195, :_reduce_none, + 4, 195, :_reduce_229, + 2, 195, :_reduce_230, + 3, 200, :_reduce_231, + 0, 201, :_reduce_232, + 1, 201, :_reduce_none, + 0, 157, :_reduce_234, + 1, 157, :_reduce_none, + 1, 169, :_reduce_236, + 2, 169, :_reduce_237, + 2, 169, :_reduce_238, + 4, 169, :_reduce_239, + 6, 169, :_reduce_240, + 1, 169, :_reduce_241, + 4, 204, :_reduce_242, + 3, 204, :_reduce_243, + 2, 204, :_reduce_244, + 4, 204, :_reduce_245, + 6, 204, :_reduce_246, + 1, 204, :_reduce_247, + 0, 206, :_reduce_248, + 2, 172, :_reduce_249, + 1, 205, :_reduce_250, + 0, 207, :_reduce_251, + 3, 205, :_reduce_252, + 0, 208, :_reduce_253, + 4, 205, :_reduce_254, + 2, 203, :_reduce_255, + 2, 202, :_reduce_256, + 1, 202, :_reduce_257, + 0, 202, :_reduce_258, + 1, 197, :_reduce_259, + 2, 197, :_reduce_260, + 3, 197, :_reduce_261, + 4, 197, :_reduce_262, + 3, 161, :_reduce_263, + 4, 161, :_reduce_264, + 2, 161, :_reduce_265, + 1, 194, :_reduce_none, + 1, 194, :_reduce_none, + 1, 194, :_reduce_none, + 1, 194, :_reduce_none, + 1, 194, :_reduce_none, + 1, 194, :_reduce_none, + 1, 194, :_reduce_none, + 1, 194, :_reduce_none, + 1, 194, :_reduce_274, + 3, 194, :_reduce_275, + 0, 232, :_reduce_276, + 4, 194, :_reduce_277, + 3, 194, :_reduce_278, + 3, 194, :_reduce_279, + 2, 194, :_reduce_280, + 3, 194, :_reduce_281, + 3, 194, :_reduce_282, + 1, 194, :_reduce_283, + 4, 194, :_reduce_284, + 3, 194, :_reduce_285, + 1, 194, :_reduce_286, + 5, 194, :_reduce_287, + 4, 194, :_reduce_288, + 3, 194, :_reduce_289, + 2, 194, :_reduce_290, + 1, 194, :_reduce_none, + 2, 194, :_reduce_292, + 0, 233, :_reduce_293, + 3, 194, :_reduce_294, + 6, 194, :_reduce_295, + 6, 194, :_reduce_296, + 0, 234, :_reduce_297, + 0, 235, :_reduce_298, + 7, 194, :_reduce_299, + 0, 236, :_reduce_300, + 0, 237, :_reduce_301, + 7, 194, :_reduce_302, + 5, 194, :_reduce_303, + 4, 194, :_reduce_304, + 0, 238, :_reduce_305, + 0, 239, :_reduce_306, + 9, 194, :_reduce_307, + 0, 240, :_reduce_308, + 6, 194, :_reduce_309, + 0, 241, :_reduce_310, + 7, 194, :_reduce_311, + 0, 242, :_reduce_312, + 5, 194, :_reduce_313, + 0, 243, :_reduce_314, + 6, 194, :_reduce_315, + 0, 244, :_reduce_316, + 0, 245, :_reduce_317, + 9, 194, :_reduce_318, + 1, 194, :_reduce_319, + 1, 194, :_reduce_320, + 1, 194, :_reduce_321, + 1, 194, :_reduce_322, + 1, 156, :_reduce_none, + 1, 225, :_reduce_324, + 1, 228, :_reduce_325, + 1, 220, :_reduce_none, + 1, 220, :_reduce_none, + 2, 220, :_reduce_328, + 1, 222, :_reduce_none, + 1, 222, :_reduce_none, + 1, 221, :_reduce_none, + 5, 221, :_reduce_332, + 1, 143, :_reduce_none, + 2, 143, :_reduce_334, + 1, 224, :_reduce_none, + 1, 224, :_reduce_none, + 1, 246, :_reduce_none, + 3, 246, :_reduce_338, + 1, 249, :_reduce_339, + 3, 249, :_reduce_340, + 1, 248, :_reduce_none, + 4, 248, :_reduce_342, + 6, 248, :_reduce_343, + 3, 248, :_reduce_344, + 5, 248, :_reduce_345, + 2, 248, :_reduce_346, + 4, 248, :_reduce_347, + 1, 248, :_reduce_348, + 3, 248, :_reduce_349, + 6, 250, :_reduce_350, + 8, 250, :_reduce_351, + 4, 250, :_reduce_352, + 6, 250, :_reduce_353, + 4, 250, :_reduce_354, + 2, 250, :_reduce_none, + 6, 250, :_reduce_356, + 2, 250, :_reduce_357, + 4, 250, :_reduce_358, + 6, 250, :_reduce_359, + 2, 250, :_reduce_360, + 4, 250, :_reduce_361, + 2, 250, :_reduce_362, + 4, 250, :_reduce_363, + 1, 250, :_reduce_364, + 0, 174, :_reduce_365, + 1, 174, :_reduce_366, + 3, 256, :_reduce_367, + 1, 256, :_reduce_368, + 4, 256, :_reduce_369, + 0, 257, :_reduce_370, + 2, 257, :_reduce_371, + 1, 258, :_reduce_372, + 3, 258, :_reduce_373, + 1, 259, :_reduce_374, + 1, 259, :_reduce_none, + 0, 263, :_reduce_376, + 3, 219, :_reduce_377, + 4, 261, :_reduce_378, + 2, 261, :_reduce_379, + 0, 266, :_reduce_380, + 4, 262, :_reduce_381, + 0, 267, :_reduce_382, + 4, 262, :_reduce_383, + 0, 268, :_reduce_384, + 5, 265, :_reduce_385, + 2, 170, :_reduce_386, + 4, 170, :_reduce_387, + 4, 170, :_reduce_388, + 2, 218, :_reduce_389, + 4, 218, :_reduce_390, + 4, 218, :_reduce_391, + 3, 218, :_reduce_392, + 3, 218, :_reduce_393, + 3, 218, :_reduce_394, + 2, 218, :_reduce_395, + 1, 218, :_reduce_396, + 4, 218, :_reduce_397, + 0, 270, :_reduce_398, + 5, 217, :_reduce_399, + 0, 271, :_reduce_400, + 5, 217, :_reduce_401, + 5, 223, :_reduce_402, + 1, 272, :_reduce_403, + 1, 272, :_reduce_none, + 6, 142, :_reduce_405, + 0, 142, :_reduce_406, + 1, 273, :_reduce_407, + 1, 273, :_reduce_none, + 1, 273, :_reduce_none, + 2, 274, :_reduce_410, + 1, 274, :_reduce_none, + 2, 144, :_reduce_412, + 1, 144, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 209, :_reduce_none, + 1, 210, :_reduce_417, + 1, 276, :_reduce_418, + 2, 276, :_reduce_419, + 3, 277, :_reduce_420, + 1, 277, :_reduce_421, + 1, 277, :_reduce_422, + 3, 211, :_reduce_423, + 4, 212, :_reduce_424, + 3, 213, :_reduce_425, + 0, 281, :_reduce_426, + 3, 281, :_reduce_427, + 1, 282, :_reduce_428, + 2, 282, :_reduce_429, + 3, 214, :_reduce_430, + 0, 284, :_reduce_431, + 3, 284, :_reduce_432, + 0, 278, :_reduce_433, + 2, 278, :_reduce_434, + 0, 279, :_reduce_435, + 2, 279, :_reduce_436, + 0, 280, :_reduce_437, + 2, 280, :_reduce_438, + 1, 283, :_reduce_439, + 2, 283, :_reduce_440, + 0, 286, :_reduce_441, + 4, 283, :_reduce_442, + 1, 285, :_reduce_443, + 1, 285, :_reduce_444, + 1, 285, :_reduce_445, + 1, 285, :_reduce_none, + 1, 191, :_reduce_447, + 3, 192, :_reduce_448, + 1, 275, :_reduce_449, + 1, 275, :_reduce_450, + 2, 275, :_reduce_451, + 2, 275, :_reduce_452, + 1, 184, :_reduce_453, + 1, 184, :_reduce_454, + 1, 184, :_reduce_455, + 1, 184, :_reduce_456, + 1, 184, :_reduce_457, + 1, 184, :_reduce_458, + 1, 184, :_reduce_459, + 1, 184, :_reduce_460, + 1, 184, :_reduce_461, + 1, 184, :_reduce_462, + 1, 184, :_reduce_463, + 1, 184, :_reduce_464, + 1, 215, :_reduce_465, + 1, 155, :_reduce_466, + 1, 160, :_reduce_467, + 1, 160, :_reduce_468, + 1, 226, :_reduce_469, + 3, 226, :_reduce_470, + 2, 226, :_reduce_471, + 3, 229, :_reduce_472, + 2, 229, :_reduce_473, + 6, 264, :_reduce_474, + 8, 264, :_reduce_475, + 4, 264, :_reduce_476, + 6, 264, :_reduce_477, + 4, 264, :_reduce_478, + 6, 264, :_reduce_479, + 2, 264, :_reduce_480, + 4, 264, :_reduce_481, + 6, 264, :_reduce_482, + 2, 264, :_reduce_483, + 4, 264, :_reduce_484, + 2, 264, :_reduce_485, + 4, 264, :_reduce_486, + 1, 264, :_reduce_487, + 0, 264, :_reduce_488, + 1, 260, :_reduce_489, + 1, 260, :_reduce_490, + 1, 260, :_reduce_491, + 1, 260, :_reduce_492, + 1, 247, :_reduce_none, + 1, 247, :_reduce_494, + 3, 247, :_reduce_495, + 2, 247, :_reduce_496, + 1, 288, :_reduce_none, + 3, 288, :_reduce_498, + 1, 251, :_reduce_499, + 3, 251, :_reduce_500, + 3, 289, :_reduce_501, + 3, 290, :_reduce_502, + 1, 252, :_reduce_503, + 3, 252, :_reduce_504, + 1, 287, :_reduce_505, + 3, 287, :_reduce_506, + 1, 291, :_reduce_none, + 1, 291, :_reduce_none, + 2, 253, :_reduce_509, + 1, 253, :_reduce_510, + 1, 292, :_reduce_none, + 1, 292, :_reduce_none, + 2, 255, :_reduce_513, + 2, 254, :_reduce_514, + 0, 254, :_reduce_515, + 1, 230, :_reduce_none, + 3, 230, :_reduce_517, + 0, 216, :_reduce_518, + 2, 216, :_reduce_none, + 1, 199, :_reduce_520, + 3, 199, :_reduce_521, + 3, 293, :_reduce_522, + 2, 293, :_reduce_523, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 176, :_reduce_none, + 1, 171, :_reduce_none, + 1, 171, :_reduce_none, + 1, 171, :_reduce_none, + 1, 171, :_reduce_none, + 1, 269, :_reduce_none, + 1, 269, :_reduce_none, + 1, 269, :_reduce_none, + 1, 231, :_reduce_none, + 1, 231, :_reduce_none, + 1, 159, :_reduce_536, + 1, 159, :_reduce_537, + 0, 146, :_reduce_none, + 1, 146, :_reduce_none, + 0, 165, :_reduce_none, + 1, 165, :_reduce_none, + 2, 179, :_reduce_542, + 2, 158, :_reduce_543, + 0, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 198, :_reduce_none, + 1, 227, :_reduce_547, + 1, 227, :_reduce_none, + 1, 148, :_reduce_none, + 2, 148, :_reduce_none, + 0, 196, :_reduce_551 ] + +racc_reduce_n = 552 + +racc_shift_n = 965 + +racc_token_table = { + false => 0, + :error => 1, + :kCLASS => 2, + :kMODULE => 3, + :kDEF => 4, + :kUNDEF => 5, + :kBEGIN => 6, + :kRESCUE => 7, + :kENSURE => 8, + :kEND => 9, + :kIF => 10, + :kUNLESS => 11, + :kTHEN => 12, + :kELSIF => 13, + :kELSE => 14, + :kCASE => 15, + :kWHEN => 16, + :kWHILE => 17, + :kUNTIL => 18, + :kFOR => 19, + :kBREAK => 20, + :kNEXT => 21, + :kREDO => 22, + :kRETRY => 23, + :kIN => 24, + :kDO => 25, + :kDO_COND => 26, + :kDO_BLOCK => 27, + :kDO_LAMBDA => 28, + :kRETURN => 29, + :kYIELD => 30, + :kSUPER => 31, + :kSELF => 32, + :kNIL => 33, + :kTRUE => 34, + :kFALSE => 35, + :kAND => 36, + :kOR => 37, + :kNOT => 38, + :kIF_MOD => 39, + :kUNLESS_MOD => 40, + :kWHILE_MOD => 41, + :kUNTIL_MOD => 42, + :kRESCUE_MOD => 43, + :kALIAS => 44, + :kDEFINED => 45, + :klBEGIN => 46, + :klEND => 47, + :k__LINE__ => 48, + :k__FILE__ => 49, + :k__ENCODING__ => 50, + :tIDENTIFIER => 51, + :tFID => 52, + :tGVAR => 53, + :tIVAR => 54, + :tCONSTANT => 55, + :tLABEL => 56, + :tCVAR => 57, + :tNTH_REF => 58, + :tBACK_REF => 59, + :tSTRING_CONTENT => 60, + :tINTEGER => 61, + :tFLOAT => 62, + :tUPLUS => 63, + :tUMINUS => 64, + :tUNARY_NUM => 65, + :tPOW => 66, + :tCMP => 67, + :tEQ => 68, + :tEQQ => 69, + :tNEQ => 70, + :tGEQ => 71, + :tLEQ => 72, + :tANDOP => 73, + :tOROP => 74, + :tMATCH => 75, + :tNMATCH => 76, + :tDOT => 77, + :tDOT2 => 78, + :tDOT3 => 79, + :tAREF => 80, + :tASET => 81, + :tLSHFT => 82, + :tRSHFT => 83, + :tCOLON2 => 84, + :tCOLON3 => 85, + :tOP_ASGN => 86, + :tASSOC => 87, + :tLPAREN => 88, + :tLPAREN2 => 89, + :tRPAREN => 90, + :tLPAREN_ARG => 91, + :tLBRACK => 92, + :tLBRACK2 => 93, + :tRBRACK => 94, + :tLBRACE => 95, + :tLBRACE_ARG => 96, + :tSTAR => 97, + :tSTAR2 => 98, + :tAMPER => 99, + :tAMPER2 => 100, + :tTILDE => 101, + :tPERCENT => 102, + :tDIVIDE => 103, + :tPLUS => 104, + :tMINUS => 105, + :tLT => 106, + :tGT => 107, + :tPIPE => 108, + :tBANG => 109, + :tCARET => 110, + :tLCURLY => 111, + :tRCURLY => 112, + :tBACK_REF2 => 113, + :tSYMBEG => 114, + :tSTRING_BEG => 115, + :tXSTRING_BEG => 116, + :tREGEXP_BEG => 117, + :tREGEXP_OPT => 118, + :tWORDS_BEG => 119, + :tQWORDS_BEG => 120, + :tSTRING_DBEG => 121, + :tSTRING_DVAR => 122, + :tSTRING_END => 123, + :tSTRING => 124, + :tSYMBOL => 125, + :tNL => 126, + :tEH => 127, + :tCOLON => 128, + :tCOMMA => 129, + :tSPACE => 130, + :tSEMI => 131, + :tLAMBDA => 132, + :tLAMBEG => 133, + :tCHARACTER => 134, + :tANDDOT => 135, + :tEQL => 136, + :tLOWEST => 137 } + +racc_nt_base = 138 + +racc_use_result_var = true + +Racc_arg = [ + racc_action_table, + racc_action_check, + racc_action_default, + racc_action_pointer, + racc_goto_table, + racc_goto_check, + racc_goto_default, + racc_goto_pointer, + racc_nt_base, + racc_reduce_table, + racc_token_table, + racc_shift_n, + racc_reduce_n, + racc_use_result_var ] +Ractor.make_shareable(Racc_arg) if defined?(Ractor) + +Racc_token_to_s_table = [ + "$end", + "error", + "kCLASS", + "kMODULE", + "kDEF", + "kUNDEF", + "kBEGIN", + "kRESCUE", + "kENSURE", + "kEND", + "kIF", + "kUNLESS", + "kTHEN", + "kELSIF", + "kELSE", + "kCASE", + "kWHEN", + "kWHILE", + "kUNTIL", + "kFOR", + "kBREAK", + "kNEXT", + "kREDO", + "kRETRY", + "kIN", + "kDO", + "kDO_COND", + "kDO_BLOCK", + "kDO_LAMBDA", + "kRETURN", + "kYIELD", + "kSUPER", + "kSELF", + "kNIL", + "kTRUE", + "kFALSE", + "kAND", + "kOR", + "kNOT", + "kIF_MOD", + "kUNLESS_MOD", + "kWHILE_MOD", + "kUNTIL_MOD", + "kRESCUE_MOD", + "kALIAS", + "kDEFINED", + "klBEGIN", + "klEND", + "k__LINE__", + "k__FILE__", + "k__ENCODING__", + "tIDENTIFIER", + "tFID", + "tGVAR", + "tIVAR", + "tCONSTANT", + "tLABEL", + "tCVAR", + "tNTH_REF", + "tBACK_REF", + "tSTRING_CONTENT", + "tINTEGER", + "tFLOAT", + "tUPLUS", + "tUMINUS", + "tUNARY_NUM", + "tPOW", + "tCMP", + "tEQ", + "tEQQ", + "tNEQ", + "tGEQ", + "tLEQ", + "tANDOP", + "tOROP", + "tMATCH", + "tNMATCH", + "tDOT", + "tDOT2", + "tDOT3", + "tAREF", + "tASET", + "tLSHFT", + "tRSHFT", + "tCOLON2", + "tCOLON3", + "tOP_ASGN", + "tASSOC", + "tLPAREN", + "tLPAREN2", + "tRPAREN", + "tLPAREN_ARG", + "tLBRACK", + "tLBRACK2", + "tRBRACK", + "tLBRACE", + "tLBRACE_ARG", + "tSTAR", + "tSTAR2", + "tAMPER", + "tAMPER2", + "tTILDE", + "tPERCENT", + "tDIVIDE", + "tPLUS", + "tMINUS", + "tLT", + "tGT", + "tPIPE", + "tBANG", + "tCARET", + "tLCURLY", + "tRCURLY", + "tBACK_REF2", + "tSYMBEG", + "tSTRING_BEG", + "tXSTRING_BEG", + "tREGEXP_BEG", + "tREGEXP_OPT", + "tWORDS_BEG", + "tQWORDS_BEG", + "tSTRING_DBEG", + "tSTRING_DVAR", + "tSTRING_END", + "tSTRING", + "tSYMBOL", + "tNL", + "tEH", + "tCOLON", + "tCOMMA", + "tSPACE", + "tSEMI", + "tLAMBDA", + "tLAMBEG", + "tCHARACTER", + "tANDDOT", + "tEQL", + "tLOWEST", + "$start", + "program", + "compstmt", + "bodystmt", + "opt_rescue", + "opt_else", + "opt_ensure", + "stmts", + "opt_terms", + "stmt", + "terms", + "fitem", + "undef_list", + "expr_value", + "lhs", + "command_call", + "mlhs", + "var_lhs", + "primary_value", + "opt_call_args", + "rbracket", + "call_op", + "backref", + "mrhs", + "arg_value", + "expr", + "@1", + "opt_nl", + "arg", + "command", + "block_command", + "call_args", + "block_call", + "operation2", + "command_args", + "cmd_brace_block", + "opt_block_param", + "@2", + "operation", + "mlhs_basic", + "mlhs_inner", + "rparen", + "mlhs_head", + "mlhs_item", + "mlhs_node", + "mlhs_post", + "variable", + "cname", + "cpath", + "fname", + "op", + "reswords", + "fsym", + "symbol", + "dsym", + "@3", + "primary", + "aref_args", + "none", + "args", + "trailer", + "assocs", + "paren_args", + "opt_paren_args", + "opt_block_arg", + "block_arg", + "call_args2", + "open_args", + "@4", + "@5", + "@6", + "literal", + "strings", + "xstring", + "regexp", + "words", + "qwords", + "var_ref", + "assoc_list", + "brace_block", + "method_call", + "lambda", + "then", + "if_tail", + "do", + "case_body", + "for_var", + "k_class", + "superclass", + "term", + "k_module", + "f_arglist", + "singleton", + "dot_or_colon", + "@7", + "@8", + "@9", + "@10", + "@11", + "@12", + "@13", + "@14", + "@15", + "@16", + "@17", + "@18", + "@19", + "@20", + "f_marg", + "f_norm_arg", + "f_margs", + "f_marg_list", + "block_param", + "f_arg", + "f_block_optarg", + "f_rest_arg", + "opt_f_block_arg", + "f_block_arg", + "block_param_def", + "opt_bv_decl", + "bv_decls", + "bvar", + "f_bad_arg", + "f_larglist", + "lambda_body", + "@21", + "f_args", + "do_block", + "@22", + "@23", + "@24", + "operation3", + "@25", + "@26", + "cases", + "exc_list", + "exc_var", + "numeric", + "string", + "string1", + "string_contents", + "xstring_contents", + "regexp_contents", + "word_list", + "word", + "string_content", + "qword_list", + "string_dvar", + "@27", + "f_optarg", + "f_arg_item", + "f_opt", + "f_block_opt", + "restarg_mark", + "blkarg_mark", + "assoc" ] +Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor) + +Racc_debug_parser = false + +##### State transition tables end ##### + +# reduce 0 omitted + +# reduce 1 omitted + +def _reduce_2(val, _values, result) + rescue_bodies = val[1] + else_t, else_ = val[2] + ensure_t, ensure_ = val[3] + + if rescue_bodies.empty? && !else_t.nil? + diagnostic :warning, :useless_else, nil, else_t + end + + result = @builder.begin_body(val[0], + rescue_bodies, + else_t, else_, + ensure_t, ensure_) + + result +end + +def _reduce_3(val, _values, result) + result = @builder.compstmt(val[0]) + + result +end + +def _reduce_4(val, _values, result) + result = [] + + result +end + +def _reduce_5(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_6(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_7(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_8(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_9(val, _values, result) + result = @builder.alias(val[0], val[1], val[3]) + + result +end + +def _reduce_10(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.gvar(val[2])) + + result +end + +def _reduce_11(val, _values, result) + result = @builder.alias(val[0], + @builder.gvar(val[1]), + @builder.back_ref(val[2])) + + result +end + +def _reduce_12(val, _values, result) + diagnostic :error, :nth_ref_alias, nil, val[2] + + result +end + +def _reduce_13(val, _values, result) + result = @builder.undef_method(val[0], val[1]) + + result +end + +def _reduce_14(val, _values, result) + result = @builder.condition_mod(val[0], nil, + val[1], val[2]) + + result +end + +def _reduce_15(val, _values, result) + result = @builder.condition_mod(nil, val[0], + val[1], val[2]) + + result +end + +def _reduce_16(val, _values, result) + result = @builder.loop_mod(:while, val[0], val[1], val[2]) + + result +end + +def _reduce_17(val, _values, result) + result = @builder.loop_mod(:until, val[0], val[1], val[2]) + + result +end + +def _reduce_18(val, _values, result) + rescue_body = @builder.rescue_body(val[1], + nil, nil, nil, + nil, val[2]) + + result = @builder.begin_body(val[0], [ rescue_body ]) + + result +end + +def _reduce_19(val, _values, result) + if @context.in_def + diagnostic :error, :begin_in_method, nil, val[0] + end + + result = @builder.preexe(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_20(val, _values, result) + result = @builder.postexe(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_21(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_22(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_23(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_24(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_25(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_26(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_27(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_28(val, _values, result) + @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_29(val, _values, result) + result = @builder.assign(val[0], val[1], + @builder.array(nil, val[2], nil)) + + result +end + +def _reduce_30(val, _values, result) + result = @builder.multi_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_31(val, _values, result) + result = @builder.multi_assign(val[0], val[1], + @builder.array(nil, val[2], nil)) + + result +end + +# reduce 32 omitted + +# reduce 33 omitted + +def _reduce_34(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_35(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_36(val, _values, result) + result = @builder.not_op(val[0], nil, val[2], nil) + + result +end + +def _reduce_37(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +# reduce 38 omitted + +# reduce 39 omitted + +# reduce 40 omitted + +# reduce 41 omitted + +def _reduce_42(val, _values, result) + result = @builder.keyword_cmd(:return, val[0], + nil, val[1], nil) + + result +end + +def _reduce_43(val, _values, result) + result = @builder.keyword_cmd(:break, val[0], + nil, val[1], nil) + + result +end + +def _reduce_44(val, _values, result) + result = @builder.keyword_cmd(:next, val[0], + nil, val[1], nil) + + result +end + +# reduce 45 omitted + +def _reduce_46(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + *val[3]) + + result +end + +def _reduce_47(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + *val[3]) + + result +end + +def _reduce_48(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_49(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_50(val, _values, result) + result = @builder.call_method(nil, nil, val[0], + *val[1]) + + result +end + +def _reduce_51(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0], + *val[1]) + + begin_t, args, body, end_t = val[2] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_52(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + *val[3]) + + result +end + +def _reduce_53(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + *val[3]) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_54(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2], + *val[3]) + + result +end + +def _reduce_55(val, _values, result) + method_call = @builder.call_method(val[0], val[1], val[2], + *val[3]) + + begin_t, args, body, end_t = val[4] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +def _reduce_56(val, _values, result) + result = @builder.keyword_cmd(:super, val[0], + *val[1]) + + result +end + +def _reduce_57(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], + *val[1]) + + result +end + +def _reduce_58(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_59(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_60(val, _values, result) + result = @builder.multi_lhs(nil, val[0], nil) + + result +end + +def _reduce_61(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +# reduce 62 omitted + +def _reduce_63(val, _values, result) + result = val[0]. + push(val[1]) + + result +end + +def _reduce_64(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])) + + result +end + +def _reduce_65(val, _values, result) + result = val[0]. + push(@builder.splat(val[1], val[2])). + concat(val[4]) + + result +end + +def _reduce_66(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])) + + result +end + +def _reduce_67(val, _values, result) + result = val[0]. + push(@builder.splat(val[1])). + concat(val[3]) + + result +end + +def _reduce_68(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_69(val, _values, result) + result = [ @builder.splat(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_70(val, _values, result) + result = [ @builder.splat(val[0]) ] + + result +end + +def _reduce_71(val, _values, result) + result = [ @builder.splat(val[0]), + *val[2] ] + + result +end + +# reduce 72 omitted + +def _reduce_73(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_74(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_75(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_76(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_77(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_78(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_79(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_80(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_81(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_82(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_83(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_84(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_85(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_86(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_87(val, _values, result) + result = @builder.index_asgn(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_88(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_89(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_90(val, _values, result) + result = @builder.attr_asgn(val[0], val[1], val[2]) + + result +end + +def _reduce_91(val, _values, result) + result = @builder.assignable( + @builder.const_fetch(val[0], val[1], val[2])) + + result +end + +def _reduce_92(val, _values, result) + result = @builder.assignable( + @builder.const_global(val[0], val[1])) + + result +end + +def _reduce_93(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_94(val, _values, result) + diagnostic :error, :module_name_const, nil, val[0] + + result +end + +# reduce 95 omitted + +def _reduce_96(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_97(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_98(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +# reduce 99 omitted + +# reduce 100 omitted + +# reduce 101 omitted + +# reduce 102 omitted + +# reduce 103 omitted + +def _reduce_104(val, _values, result) + result = @builder.symbol_internal(val[0]) + + result +end + +# reduce 105 omitted + +# reduce 106 omitted + +# reduce 107 omitted + +def _reduce_108(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_109(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_110(val, _values, result) + result = val[0] << val[3] + + result +end + +# reduce 111 omitted + +# reduce 112 omitted + +# reduce 113 omitted + +# reduce 114 omitted + +# reduce 115 omitted + +# reduce 116 omitted + +# reduce 117 omitted + +# reduce 118 omitted + +# reduce 119 omitted + +# reduce 120 omitted + +# reduce 121 omitted + +# reduce 122 omitted + +# reduce 123 omitted + +# reduce 124 omitted + +# reduce 125 omitted + +# reduce 126 omitted + +# reduce 127 omitted + +# reduce 128 omitted + +# reduce 129 omitted + +# reduce 130 omitted + +# reduce 131 omitted + +# reduce 132 omitted + +# reduce 133 omitted + +# reduce 134 omitted + +# reduce 135 omitted + +# reduce 136 omitted + +# reduce 137 omitted + +# reduce 138 omitted + +# reduce 139 omitted + +# reduce 140 omitted + +# reduce 141 omitted + +# reduce 142 omitted + +# reduce 143 omitted + +# reduce 144 omitted + +# reduce 145 omitted + +# reduce 146 omitted + +# reduce 147 omitted + +# reduce 148 omitted + +# reduce 149 omitted + +# reduce 150 omitted + +# reduce 151 omitted + +# reduce 152 omitted + +# reduce 153 omitted + +# reduce 154 omitted + +# reduce 155 omitted + +# reduce 156 omitted + +# reduce 157 omitted + +# reduce 158 omitted + +# reduce 159 omitted + +# reduce 160 omitted + +# reduce 161 omitted + +# reduce 162 omitted + +# reduce 163 omitted + +# reduce 164 omitted + +# reduce 165 omitted + +# reduce 166 omitted + +# reduce 167 omitted + +# reduce 168 omitted + +# reduce 169 omitted + +# reduce 170 omitted + +# reduce 171 omitted + +# reduce 172 omitted + +# reduce 173 omitted + +# reduce 174 omitted + +# reduce 175 omitted + +# reduce 176 omitted + +# reduce 177 omitted + +# reduce 178 omitted + +# reduce 179 omitted + +# reduce 180 omitted + +def _reduce_181(val, _values, result) + result = @builder.assign(val[0], val[1], val[2]) + + result +end + +def _reduce_182(val, _values, result) + rescue_body = @builder.rescue_body(val[3], + nil, nil, nil, + nil, val[4]) + + rescue_ = @builder.begin_body(val[2], [ rescue_body ]) + + result = @builder.assign(val[0], val[1], rescue_) + + result +end + +def _reduce_183(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_184(val, _values, result) + rescue_body = @builder.rescue_body(val[3], + nil, nil, nil, + nil, val[4]) + + rescue_ = @builder.begin_body(val[2], [ rescue_body ]) + + result = @builder.op_assign(val[0], val[1], rescue_) + + result +end + +def _reduce_185(val, _values, result) + result = @builder.op_assign( + @builder.index( + val[0], val[1], val[2], val[3]), + val[4], val[5]) + + result +end + +def _reduce_186(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_187(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_188(val, _values, result) + result = @builder.op_assign( + @builder.call_method( + val[0], val[1], val[2]), + val[3], val[4]) + + result +end + +def _reduce_189(val, _values, result) + diagnostic :error, :dynamic_const, nil, val[2], [ val[3] ] + + result +end + +def _reduce_190(val, _values, result) + diagnostic :error, :dynamic_const, nil, val[1], [ val[2] ] + + result +end + +def _reduce_191(val, _values, result) + result = @builder.op_assign(val[0], val[1], val[2]) + + result +end + +def _reduce_192(val, _values, result) + result = @builder.range_inclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_193(val, _values, result) + result = @builder.range_exclusive(val[0], val[1], val[2]) + + result +end + +def _reduce_194(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_195(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_196(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_197(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_198(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_199(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_200(val, _values, result) + result = @builder.unary_op(val[0], + @builder.binary_op( + @builder.integer(val[1]), + val[2], val[3])) + + result +end + +def _reduce_201(val, _values, result) + result = @builder.unary_op(val[0], + @builder.binary_op( + @builder.float(val[1]), + val[2], val[3])) + + result +end + +def _reduce_202(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_203(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_204(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_205(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_206(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_207(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_208(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_209(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_210(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_211(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_212(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_213(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_214(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_215(val, _values, result) + result = @builder.match_op(val[0], val[1], val[2]) + + result +end + +def _reduce_216(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_217(val, _values, result) + result = @builder.not_op(val[0], nil, val[1], nil) + + result +end + +def _reduce_218(val, _values, result) + result = @builder.unary_op(val[0], val[1]) + + result +end + +def _reduce_219(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_220(val, _values, result) + result = @builder.binary_op(val[0], val[1], val[2]) + + result +end + +def _reduce_221(val, _values, result) + result = @builder.logical_op(:and, val[0], val[1], val[2]) + + result +end + +def _reduce_222(val, _values, result) + result = @builder.logical_op(:or, val[0], val[1], val[2]) + + result +end + +def _reduce_223(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil) + + result +end + +def _reduce_224(val, _values, result) + result = @builder.ternary(val[0], val[1], + val[2], val[4], val[5]) + + result +end + +# reduce 225 omitted + +# reduce 226 omitted + +# reduce 227 omitted + +# reduce 228 omitted + +def _reduce_229(val, _values, result) + result = val[0] << @builder.associate(nil, val[2], nil) + + result +end + +def _reduce_230(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + + result +end + +def _reduce_231(val, _values, result) + result = val + + result +end + +def _reduce_232(val, _values, result) + result = [ nil, [], nil ] + + result +end + +# reduce 233 omitted + +def _reduce_234(val, _values, result) + result = [] + + result +end + +# reduce 235 omitted + +def _reduce_236(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_237(val, _values, result) + result = val[0].concat(val[1]) + + result +end + +def _reduce_238(val, _values, result) + result = [ @builder.associate(nil, val[0], nil) ] + result.concat(val[1]) + + result +end + +def _reduce_239(val, _values, result) + assocs = @builder.associate(nil, val[2], nil) + result = val[0] << assocs + result.concat(val[3]) + + result +end + +def _reduce_240(val, _values, result) + val[2][-1] = @builder.objc_varargs(val[2][-1], val[4]) + assocs = @builder.associate(nil, val[2], nil) + result = val[0] << assocs + result.concat(val[5]) + + result +end + +def _reduce_241(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_242(val, _values, result) + result = [ val[0], *val[2].concat(val[3]) ] + + result +end + +def _reduce_243(val, _values, result) + result = [ val[0], val[2] ] + + result +end + +def _reduce_244(val, _values, result) + result = [ @builder.associate(nil, val[0], nil), + *val[1] ] + + result +end + +def _reduce_245(val, _values, result) + result = [ val[0], + @builder.associate(nil, val[2], nil), + *val[3] ] + + result +end + +def _reduce_246(val, _values, result) + result = [ val[0], + *val[2]. + push(@builder.associate(nil, val[4], nil)). + concat(val[5]) ] + + result +end + +def _reduce_247(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_248(val, _values, result) + result = @lexer.cmdarg.dup + @lexer.cmdarg.push(true) + + result +end + +def _reduce_249(val, _values, result) + @lexer.cmdarg = val[0] + + result = val[1] + + result +end + +def _reduce_250(val, _values, result) + result = [ nil, val[0], nil ] + + result +end + +def _reduce_251(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_252(val, _values, result) + result = [ val[0], [], val[2] ] + + result +end + +def _reduce_253(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_254(val, _values, result) + result = [ val[0], val[1], val[3] ] + + result +end + +def _reduce_255(val, _values, result) + result = @builder.block_pass(val[0], val[1]) + + result +end + +def _reduce_256(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_257(val, _values, result) + result = [] + + result +end + +def _reduce_258(val, _values, result) + result = [] + + result +end + +def _reduce_259(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_260(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +def _reduce_261(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_262(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_263(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_264(val, _values, result) + result = val[0] << @builder.splat(val[2], val[3]) + + result +end + +def _reduce_265(val, _values, result) + result = [ @builder.splat(val[0], val[1]) ] + + result +end + +# reduce 266 omitted + +# reduce 267 omitted + +# reduce 268 omitted + +# reduce 269 omitted + +# reduce 270 omitted + +# reduce 271 omitted + +# reduce 272 omitted + +# reduce 273 omitted + +def _reduce_274(val, _values, result) + result = @builder.call_method(nil, nil, val[0]) + + result +end + +def _reduce_275(val, _values, result) + result = @builder.begin_keyword(val[0], val[1], val[2]) + + result +end + +def _reduce_276(val, _values, result) + @lexer.state = :expr_endarg + + result +end + +def _reduce_277(val, _values, result) + result = @builder.begin(val[0], val[1], val[3]) + + result +end + +def _reduce_278(val, _values, result) + result = @builder.begin(val[0], val[1], val[2]) + + result +end + +def _reduce_279(val, _values, result) + result = @builder.const_fetch(val[0], val[1], val[2]) + + result +end + +def _reduce_280(val, _values, result) + result = @builder.const_global(val[0], val[1]) + + result +end + +def _reduce_281(val, _values, result) + result = @builder.array(val[0], val[1], val[2]) + + result +end + +def _reduce_282(val, _values, result) + result = @builder.associate(val[0], val[1], val[2]) + + result +end + +def _reduce_283(val, _values, result) + result = @builder.keyword_cmd(:return, val[0]) + + result +end + +def _reduce_284(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_285(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2]) + + result +end + +def _reduce_286(val, _values, result) + result = @builder.keyword_cmd(:yield, val[0]) + + result +end + +def _reduce_287(val, _values, result) + result = @builder.keyword_cmd(:defined?, val[0], + val[2], [ val[3] ], val[4]) + + result +end + +def _reduce_288(val, _values, result) + result = @builder.not_op(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_289(val, _values, result) + result = @builder.not_op(val[0], val[1], nil, val[2]) + + result +end + +def _reduce_290(val, _values, result) + method_call = @builder.call_method(nil, nil, val[0]) + + begin_t, args, body, end_t = val[1] + result = @builder.block(method_call, + begin_t, args, body, end_t) + + result +end + +# reduce 291 omitted + +def _reduce_292(val, _values, result) + begin_t, args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, args, body, end_t) + + result +end + +def _reduce_293(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_294(val, _values, result) + lambda_call = @builder.call_lambda(val[0]) + + args, (begin_t, body, end_t) = val[2] + result = @builder.block(lambda_call, + begin_t, args, body, end_t) + + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_295(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, val[5]) + + result +end + +def _reduce_296(val, _values, result) + else_t, else_ = val[4] + result = @builder.condition(val[0], val[1], val[2], + else_, else_t, + val[3], val[5]) + + result +end + +def _reduce_297(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_298(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_299(val, _values, result) + result = @builder.loop(:while, val[0], val[2], val[3], + val[5], val[6]) + + result +end + +def _reduce_300(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_301(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_302(val, _values, result) + result = @builder.loop(:until, val[0], val[2], val[3], + val[5], val[6]) + + result +end + +def _reduce_303(val, _values, result) + *when_bodies, (else_t, else_body) = *val[3] + + result = @builder.case(val[0], val[1], + when_bodies, else_t, else_body, + val[4]) + + result +end + +def _reduce_304(val, _values, result) + *when_bodies, (else_t, else_body) = *val[2] + + result = @builder.case(val[0], nil, + when_bodies, else_t, else_body, + val[3]) + + result +end + +def _reduce_305(val, _values, result) + @lexer.cond.push(true) + + result +end + +def _reduce_306(val, _values, result) + @lexer.cond.pop + + result +end + +def _reduce_307(val, _values, result) + result = @builder.for(val[0], val[1], + val[2], val[4], + val[5], val[7], val[8]) + + result +end + +def _reduce_308(val, _values, result) + local_push + @context.in_class = true + + result +end + +def _reduce_309(val, _values, result) + k_class, ctx = val[0] + if @context.in_def + diagnostic :error, :class_in_def, nil, k_class + end + + lt_t, superclass = val[2] + result = @builder.def_class(k_class, val[1], + lt_t, superclass, + val[4], val[5]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_310(val, _values, result) + @context.in_def = false + @context.in_class = false + local_push + + result +end + +def _reduce_311(val, _values, result) + k_class, ctx = val[0] + result = @builder.def_sclass(k_class, val[1], val[2], + val[5], val[6]) + + local_pop + @context.in_def = ctx.in_def + @context.in_class = ctx.in_class + + result +end + +def _reduce_312(val, _values, result) + @context.in_class = true + local_push + + result +end + +def _reduce_313(val, _values, result) + k_mod, ctx = val[0] + if @context.in_def + diagnostic :error, :module_in_def, nil, k_mod + end + + result = @builder.def_module(k_mod, val[1], + val[3], val[4]) + + local_pop + @context.in_class = ctx.in_class + + result +end + +def _reduce_314(val, _values, result) + local_push + result = context.dup + @context.in_def = true + + result +end + +def _reduce_315(val, _values, result) + result = @builder.def_method(val[0], val[1], + val[3], val[4], val[5]) + + local_pop + @context.in_def = val[2].in_def + + result +end + +def _reduce_316(val, _values, result) + @lexer.state = :expr_fname + + result +end + +def _reduce_317(val, _values, result) + local_push + result = context.dup + @context.in_def = true + + result +end + +def _reduce_318(val, _values, result) + result = @builder.def_singleton(val[0], val[1], val[2], + val[4], val[6], val[7], val[8]) + + local_pop + @context.in_def = val[5].in_def + + result +end + +def _reduce_319(val, _values, result) + result = @builder.keyword_cmd(:break, val[0]) + + result +end + +def _reduce_320(val, _values, result) + result = @builder.keyword_cmd(:next, val[0]) + + result +end + +def _reduce_321(val, _values, result) + result = @builder.keyword_cmd(:redo, val[0]) + + result +end + +def _reduce_322(val, _values, result) + result = @builder.keyword_cmd(:retry, val[0]) + + result +end + +# reduce 323 omitted + +def _reduce_324(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +def _reduce_325(val, _values, result) + result = [ val[0], @context.dup ] + + result +end + +# reduce 326 omitted + +# reduce 327 omitted + +def _reduce_328(val, _values, result) + result = val[1] + + result +end + +# reduce 329 omitted + +# reduce 330 omitted + +# reduce 331 omitted + +def _reduce_332(val, _values, result) + else_t, else_ = val[4] + result = [ val[0], + @builder.condition(val[0], val[1], val[2], + val[3], else_t, + else_, nil), + ] + + result +end + +# reduce 333 omitted + +def _reduce_334(val, _values, result) + result = val + + result +end + +# reduce 335 omitted + +# reduce 336 omitted + +# reduce 337 omitted + +def _reduce_338(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_339(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_340(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 341 omitted + +def _reduce_342(val, _values, result) + result = val[0]. + push(@builder.objc_restarg(val[2], val[3])) + + result +end + +def _reduce_343(val, _values, result) + result = val[0]. + push(@builder.objc_restarg(val[2], val[3])). + concat(val[5]) + + result +end + +def _reduce_344(val, _values, result) + result = val[0]. + push(@builder.objc_restarg(val[2])) + + result +end + +def _reduce_345(val, _values, result) + result = val[0]. + push(@builder.objc_restarg(val[2])). + concat(val[4]) + + result +end + +def _reduce_346(val, _values, result) + result = [ @builder.objc_restarg(val[0], val[1]) ] + + result +end + +def _reduce_347(val, _values, result) + result = [ @builder.objc_restarg(val[0], val[1]), + *val[3] ] + + result +end + +def _reduce_348(val, _values, result) + result = [ @builder.objc_restarg(val[0]) ] + + result +end + +def _reduce_349(val, _values, result) + result = [ @builder.objc_restarg(val[0]), + *val[2] ] + + result +end + +def _reduce_350(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_351(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_352(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_353(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_354(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +# reduce 355 omitted + +def _reduce_356(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_357(val, _values, result) + if val[1].empty? && val[0].size == 1 + result = [@builder.procarg0(val[0][0])] + else + result = val[0].concat(val[1]) + end + + result +end + +def _reduce_358(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_359(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_360(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_361(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_362(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_363(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_364(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_365(val, _values, result) + result = @builder.args(nil, [], nil) + + result +end + +def _reduce_366(val, _values, result) + @lexer.state = :expr_value + + result +end + +def _reduce_367(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + result +end + +def _reduce_368(val, _values, result) + result = @builder.args(val[0], [], val[0]) + + result +end + +def _reduce_369(val, _values, result) + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_370(val, _values, result) + result = [] + + result +end + +def _reduce_371(val, _values, result) + result = val[1] + + result +end + +def _reduce_372(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_373(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_374(val, _values, result) + @static_env.declare val[0][0] + result = @builder.shadowarg(val[0]) + + result +end + +# reduce 375 omitted + +def _reduce_376(val, _values, result) + @static_env.extend_dynamic + + result +end + +def _reduce_377(val, _values, result) + result = [ val[1], val[2] ] + + @static_env.unextend + + result +end + +def _reduce_378(val, _values, result) + result = @builder.args(val[0], val[1].concat(val[2]), val[3]) + + result +end + +def _reduce_379(val, _values, result) + result = @builder.args(nil, val[0].concat(val[1]), nil) + + result +end + +def _reduce_380(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_381(val, _values, result) + result = [ val[0], val[2], val[3] ] + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_382(val, _values, result) + result = @context.dup + @context.in_lambda = true + + result +end + +def _reduce_383(val, _values, result) + result = [ val[0], val[2], val[3] ] + @context.in_lambda = val[1].in_lambda + + result +end + +def _reduce_384(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_385(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_386(val, _values, result) + begin_t, block_args, body, end_t = val[1] + result = @builder.block(val[0], + begin_t, block_args, body, end_t) + + result +end + +def _reduce_387(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_388(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_389(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.call_method(nil, nil, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_390(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_391(val, _values, result) + lparen_t, args, rparen_t = val[3] + result = @builder.call_method(val[0], val[1], val[2], + lparen_t, args, rparen_t) + + result +end + +def _reduce_392(val, _values, result) + result = @builder.call_method(val[0], val[1], val[2]) + + result +end + +def _reduce_393(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_394(val, _values, result) + lparen_t, args, rparen_t = val[2] + result = @builder.call_method(val[0], val[1], nil, + lparen_t, args, rparen_t) + + result +end + +def _reduce_395(val, _values, result) + lparen_t, args, rparen_t = val[1] + result = @builder.keyword_cmd(:super, val[0], + lparen_t, args, rparen_t) + + result +end + +def _reduce_396(val, _values, result) + result = @builder.keyword_cmd(:zsuper, val[0]) + + result +end + +def _reduce_397(val, _values, result) + result = @builder.index(val[0], val[1], val[2], val[3]) + + result +end + +def _reduce_398(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_399(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_400(val, _values, result) + @static_env.extend_dynamic + result = @context.dup + @context.in_block = true + + result +end + +def _reduce_401(val, _values, result) + result = [ val[0], val[2], val[3], val[4] ] + + @static_env.unextend + @context.in_block = val[1].in_block + + result +end + +def _reduce_402(val, _values, result) + result = [ @builder.when(val[0], val[1], val[2], val[3]), + *val[4] ] + + result +end + +def _reduce_403(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 404 omitted + +def _reduce_405(val, _values, result) + assoc_t, exc_var = val[2] + + if val[1] + exc_list = @builder.array(nil, val[1], nil) + end + + result = [ @builder.rescue_body(val[0], + exc_list, assoc_t, exc_var, + val[3], val[4]), + *val[5] ] + + result +end + +def _reduce_406(val, _values, result) + result = [] + + result +end + +def _reduce_407(val, _values, result) + result = [ val[0] ] + + result +end + +# reduce 408 omitted + +# reduce 409 omitted + +def _reduce_410(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 411 omitted + +def _reduce_412(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +# reduce 413 omitted + +# reduce 414 omitted + +# reduce 415 omitted + +# reduce 416 omitted + +def _reduce_417(val, _values, result) + result = @builder.string_compose(nil, val[0], nil) + + result +end + +def _reduce_418(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_419(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_420(val, _values, result) + result = @builder.string_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_421(val, _values, result) + result = @builder.string(val[0]) + + result +end + +def _reduce_422(val, _values, result) + result = @builder.character(val[0]) + + result +end + +def _reduce_423(val, _values, result) + result = @builder.xstring_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_424(val, _values, result) + opts = @builder.regexp_options(val[3]) + result = @builder.regexp_compose(val[0], val[1], val[2], opts) + + result +end + +def _reduce_425(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_426(val, _values, result) + result = [] + + result +end + +def _reduce_427(val, _values, result) + result = val[0] << @builder.word(val[1]) + + result +end + +def _reduce_428(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_429(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_430(val, _values, result) + result = @builder.words_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_431(val, _values, result) + result = [] + + result +end + +def _reduce_432(val, _values, result) + result = val[0] << @builder.string_internal(val[1]) + + result +end + +def _reduce_433(val, _values, result) + result = [] + + result +end + +def _reduce_434(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_435(val, _values, result) + result = [] + + result +end + +def _reduce_436(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_437(val, _values, result) + result = [] + + result +end + +def _reduce_438(val, _values, result) + result = val[0] << val[1] + + result +end + +def _reduce_439(val, _values, result) + result = @builder.string_internal(val[0]) + + result +end + +def _reduce_440(val, _values, result) + result = val[1] + + result +end + +def _reduce_441(val, _values, result) + @lexer.cond.push(false) + @lexer.cmdarg.push(false) + + result +end + +def _reduce_442(val, _values, result) + @lexer.cond.lexpop + @lexer.cmdarg.lexpop + + result = @builder.begin(val[0], val[2], val[3]) + + result +end + +def _reduce_443(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_444(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_445(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +# reduce 446 omitted + +def _reduce_447(val, _values, result) + result = @builder.symbol(val[0]) + + result +end + +def _reduce_448(val, _values, result) + result = @builder.symbol_compose(val[0], val[1], val[2]) + + result +end + +def _reduce_449(val, _values, result) + result = @builder.integer(val[0]) + + result +end + +def _reduce_450(val, _values, result) + result = @builder.float(val[0]) + + result +end + +def _reduce_451(val, _values, result) + num = @builder.integer(val[1]) + if @builder.respond_to? :negate + # AST builder interface compatibility + result = @builder.negate(val[0], num) + else + result = @builder.unary_num(val[0], num) + end + + result +end + +def _reduce_452(val, _values, result) + num = @builder.float(val[1]) + if @builder.respond_to? :negate + # AST builder interface compatibility + result = @builder.negate(val[0], num) + else + result = @builder.unary_num(val[0], num) + end + + result +end + +def _reduce_453(val, _values, result) + result = @builder.ident(val[0]) + + result +end + +def _reduce_454(val, _values, result) + result = @builder.ivar(val[0]) + + result +end + +def _reduce_455(val, _values, result) + result = @builder.gvar(val[0]) + + result +end + +def _reduce_456(val, _values, result) + result = @builder.const(val[0]) + + result +end + +def _reduce_457(val, _values, result) + result = @builder.cvar(val[0]) + + result +end + +def _reduce_458(val, _values, result) + result = @builder.nil(val[0]) + + result +end + +def _reduce_459(val, _values, result) + result = @builder.self(val[0]) + + result +end + +def _reduce_460(val, _values, result) + result = @builder.true(val[0]) + + result +end + +def _reduce_461(val, _values, result) + result = @builder.false(val[0]) + + result +end + +def _reduce_462(val, _values, result) + result = @builder.__FILE__(val[0]) + + result +end + +def _reduce_463(val, _values, result) + result = @builder.__LINE__(val[0]) + + result +end + +def _reduce_464(val, _values, result) + result = @builder.__ENCODING__(val[0]) + + result +end + +def _reduce_465(val, _values, result) + result = @builder.accessible(val[0]) + + result +end + +def _reduce_466(val, _values, result) + result = @builder.assignable(val[0]) + + result +end + +def _reduce_467(val, _values, result) + result = @builder.nth_ref(val[0]) + + result +end + +def _reduce_468(val, _values, result) + result = @builder.back_ref(val[0]) + + result +end + +def _reduce_469(val, _values, result) + result = nil + + result +end + +def _reduce_470(val, _values, result) + result = [ val[0], val[1] ] + + result +end + +def _reduce_471(val, _values, result) + yyerrok + result = nil + + result +end + +def _reduce_472(val, _values, result) + result = @builder.args(val[0], val[1], val[2]) + + @lexer.state = :expr_value + + result +end + +def _reduce_473(val, _values, result) + result = @builder.args(nil, val[0], nil) + + result +end + +def _reduce_474(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_475(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[6]). + concat(val[7]) + + result +end + +def _reduce_476(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_477(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_478(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_479(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_480(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_481(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_482(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[4]). + concat(val[5]) + + result +end + +def _reduce_483(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_484(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_485(val, _values, result) + result = val[0]. + concat(val[1]) + + result +end + +def _reduce_486(val, _values, result) + result = val[0]. + concat(val[2]). + concat(val[3]) + + result +end + +def _reduce_487(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_488(val, _values, result) + result = [] + + result +end + +def _reduce_489(val, _values, result) + diagnostic :error, :argument_const, nil, val[0] + + result +end + +def _reduce_490(val, _values, result) + diagnostic :error, :argument_ivar, nil, val[0] + + result +end + +def _reduce_491(val, _values, result) + diagnostic :error, :argument_gvar, nil, val[0] + + result +end + +def _reduce_492(val, _values, result) + diagnostic :error, :argument_cvar, nil, val[0] + + result +end + +# reduce 493 omitted + +def _reduce_494(val, _values, result) + @static_env.declare val[0][0] + + result = @builder.arg(val[0]) + + result +end + +def _reduce_495(val, _values, result) + @static_env.declare val[2][0] + + result = @builder.objc_kwarg(val[0], val[1], val[2]) + + result +end + +def _reduce_496(val, _values, result) + @static_env.declare val[1][0] + + result = @builder.objc_kwarg(val[0], nil, val[1]) + + result +end + +# reduce 497 omitted + +def _reduce_498(val, _values, result) + result = @builder.multi_lhs(val[0], val[1], val[2]) + + result +end + +def _reduce_499(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_500(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_501(val, _values, result) + @static_env.declare val[0][0] + + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_502(val, _values, result) + @static_env.declare val[0][0] + + result = @builder.optarg(val[0], val[1], val[2]) + + result +end + +def _reduce_503(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_504(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_505(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_506(val, _values, result) + result = val[0] << val[2] + + result +end + +# reduce 507 omitted + +# reduce 508 omitted + +def _reduce_509(val, _values, result) + @static_env.declare val[1][0] + + result = [ @builder.restarg(val[0], val[1]) ] + + result +end + +def _reduce_510(val, _values, result) + result = [ @builder.restarg(val[0]) ] + + result +end + +# reduce 511 omitted + +# reduce 512 omitted + +def _reduce_513(val, _values, result) + @static_env.declare val[1][0] + + result = @builder.blockarg(val[0], val[1]) + + result +end + +def _reduce_514(val, _values, result) + result = [ val[1] ] + + result +end + +def _reduce_515(val, _values, result) + result = [] + + result +end + +# reduce 516 omitted + +def _reduce_517(val, _values, result) + result = val[1] + + result +end + +def _reduce_518(val, _values, result) + result = [] + + result +end + +# reduce 519 omitted + +def _reduce_520(val, _values, result) + result = [ val[0] ] + + result +end + +def _reduce_521(val, _values, result) + result = val[0] << val[2] + + result +end + +def _reduce_522(val, _values, result) + result = @builder.pair(val[0], val[1], val[2]) + + result +end + +def _reduce_523(val, _values, result) + result = @builder.pair_keyword(val[0], val[1]) + + result +end + +# reduce 524 omitted + +# reduce 525 omitted + +# reduce 526 omitted + +# reduce 527 omitted + +# reduce 528 omitted + +# reduce 529 omitted + +# reduce 530 omitted + +# reduce 531 omitted + +# reduce 532 omitted + +# reduce 533 omitted + +# reduce 534 omitted + +# reduce 535 omitted + +def _reduce_536(val, _values, result) + result = [:dot, val[0][1]] + + result +end + +def _reduce_537(val, _values, result) + result = [:anddot, val[0][1]] + + result +end + +# reduce 538 omitted + +# reduce 539 omitted + +# reduce 540 omitted + +# reduce 541 omitted + +def _reduce_542(val, _values, result) + result = val[1] + + result +end + +def _reduce_543(val, _values, result) + result = val[1] + + result +end + +# reduce 544 omitted + +# reduce 545 omitted + +# reduce 546 omitted + +def _reduce_547(val, _values, result) + yyerrok + + result +end + +# reduce 548 omitted + +# reduce 549 omitted + +# reduce 550 omitted + +def _reduce_551(val, _values, result) + result = nil + + result +end + +def _reduce_none(val, _values, result) + val[0] +end + + end # class RubyMotion +end # module Parser diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/runner.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/runner.rb new file mode 100644 index 00000000..95f3efa9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/runner.rb @@ -0,0 +1,299 @@ +# frozen_string_literal: true + +require 'find' +require 'optparse' + +require_relative '../parser' + +module Parser + + class Runner + def self.go(options) + new.execute(options) + end + + def initialize + @option_parser = OptionParser.new { |opts| setup_option_parsing(opts) } + @legacy = {} + @parser_class = nil + @parser = nil + @files = [] + @fragments = [] + @warnings = false + @benchmark = false + + @source_count = 0 + @source_size = 0 + end + + def execute(options) + parse_options(options) + setup_builder_default + prepare_parser + + process_all_input + end + + private + + LEGACY_MODES = %i[lambda procarg0 encoding index arg_inside_procarg0 forward_arg kwargs match_pattern].freeze + + def runner_name + raise NotImplementedError, "implement #{self.class}##{__callee__}" + end + + def setup_option_parsing(opts) + opts.banner = "Usage: #{runner_name} [options] FILE|DIRECTORY..." + + opts.on_tail '-h', '--help', 'Display this help message and exit' do + puts opts.help + puts <<-HELP + + If you specify a DIRECTORY, then all *.rb files are fetched + from it recursively and appended to the file list. + + The default parsing mode is for current Ruby (#{RUBY_VERSION}). + HELP + exit + end + + opts.on_tail '-V', '--version', 'Output version information and exit' do + puts "#{runner_name} based on parser version #{Parser::VERSION}" + exit + end + + opts.on '--18', 'Parse as Ruby 1.8.7 would' do + require_relative 'ruby18' + @parser_class = Parser::Ruby18 + end + + opts.on '--19', 'Parse as Ruby 1.9.3 would' do + require_relative 'ruby19' + @parser_class = Parser::Ruby19 + end + + opts.on '--20', 'Parse as Ruby 2.0 would' do + require_relative 'ruby20' + @parser_class = Parser::Ruby20 + end + + opts.on '--21', 'Parse as Ruby 2.1 would' do + require_relative 'ruby21' + @parser_class = Parser::Ruby21 + end + + opts.on '--22', 'Parse as Ruby 2.2 would' do + require_relative 'ruby22' + @parser_class = Parser::Ruby22 + end + + opts.on '--23', 'Parse as Ruby 2.3 would' do + require_relative 'ruby23' + @parser_class = Parser::Ruby23 + end + + opts.on '--24', 'Parse as Ruby 2.4 would' do + require_relative 'ruby24' + @parser_class = Parser::Ruby24 + end + + opts.on '--25', 'Parse as Ruby 2.5 would' do + require_relative 'ruby25' + @parser_class = Parser::Ruby25 + end + + opts.on '--26', 'Parse as Ruby 2.6 would' do + require_relative 'ruby26' + @parser_class = Parser::Ruby26 + end + + opts.on '--27', 'Parse as Ruby 2.7 would' do + require_relative 'ruby27' + @parser_class = Parser::Ruby27 + end + + opts.on '--30', 'Parse as Ruby 3.0 would' do + require_relative 'ruby30' + @parser_class = Parser::Ruby30 + end + + opts.on '--31', 'Parse as Ruby 3.1 would' do + require_relative 'ruby31' + @parser_class = Parser::Ruby31 + end + + opts.on '--32', 'Parse as Ruby 3.2 would' do + require_relative 'ruby32' + @parser_class = Parser::Ruby32 + end + + opts.on '--33', 'Parse as Ruby 3.3 would' do + require_relative 'ruby33' + @parser_class = Parser::Ruby33 + end + + opts.on '--34', 'Parse as Ruby 3.4 would' do + require_relative 'ruby34' + @parser_class = Parser::Ruby34 + end + + opts.on '--mac', 'Parse as MacRuby 0.12 would' do + require_relative 'macruby' + @parser_class = Parser::MacRuby + end + + opts.on '--ios', 'Parse as mid-2015 RubyMotion would' do + require_relative 'rubymotion' + @parser_class = Parser::RubyMotion + end + + opts.on '--legacy', "Parse with all legacy modes" do + @legacy = Hash.new(true) + end + + LEGACY_MODES.each do |mode| + opt_name = "--legacy-#{mode.to_s.gsub('_', '-')}" + opts.on opt_name, "Parse with legacy mode for emit_#{mode}" do + @legacy[mode] = true + end + end + + opts.on '-w', '--warnings', 'Enable warnings' do |w| + @warnings = w + end + + opts.on '-B', '--benchmark', 'Benchmark the processor' do |b| + @benchmark = b + end + + opts.on '-e fragment', 'Process a fragment of Ruby code' do |fragment| + @fragments << fragment + end + end + + def parse_options(options) + @option_parser.parse!(options) + + # Slop has just removed recognized options from `options`. + @fragments << $stdin.read if options.delete('-') + options.each do |file_or_dir| + if File.directory?(file_or_dir) + Find.find(file_or_dir) do |path| + @files << path if path.end_with? '.rb' + end + else + @files << file_or_dir + end + end + + if @files.empty? && @fragments.empty? + $stderr.puts 'Need something to parse!' + exit 1 + end + + if @parser_class.nil? + require_relative 'current' + @parser_class = Parser::CurrentRuby + end + end + + def setup_builder_default + LEGACY_MODES.each do |mode| + Parser::Builders::Default.send(:"emit_#{mode}=", !@legacy[mode]) + end + end + + def prepare_parser + @parser = @parser_class.new + + @parser.diagnostics.all_errors_are_fatal = true + @parser.diagnostics.ignore_warnings = !@warnings + + @parser.diagnostics.consumer = lambda do |diagnostic| + puts(diagnostic.render) + end + end + + def input_size + @files.size + @fragments.size + end + + def process_all_input + time_start = Process.clock_gettime(Process::CLOCK_MONOTONIC) + process_fragments + process_files + time_elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - time_start + + if @benchmark + report_with_time(time_elapsed) + end + end + + def process_fragments + @fragments.each_with_index do |fragment, index| + fragment = fragment.dup.force_encoding(@parser.default_encoding) + + buffer = Source::Buffer.new("(fragment:#{index})") + buffer.source = fragment + + process_buffer(buffer) + end + end + + def process_files + @files.each do |filename| + source = begin + File.read(filename).force_encoding(@parser.default_encoding) + rescue Errno::EISDIR + # Will happen for a folder called `foo.rb`. Just catch this here, it's cheaper than checking every file. + next + end + + buffer = Parser::Source::Buffer.new(filename) + + if @parser.class.name == 'Parser::Ruby18' + buffer.raw_source = source + else + buffer.source = source + end + + process_buffer(buffer) + end + end + + def process_buffer(buffer) + @parser.reset + + process(buffer) + + @source_count += 1 + @source_size += buffer.source.size + + rescue Parser::SyntaxError + # skip + + rescue StandardError + $stderr.puts("Failed on: #{buffer.name}") + raise + end + + def process(buffer) + raise NotImplementedError, "implement #{self.class}##{__callee__}" + end + + def report_with_time(time_elapsed) + speed = '%.3f' % (@source_size / time_elapsed / 1000) + puts "Parsed #{@source_count} files (#{@source_size} characters)" \ + " in #{'%.2f' % time_elapsed} seconds (#{speed} kchars/s)." + + if defined?(RUBY_ENGINE) + engine = RUBY_ENGINE + else + engine = 'ruby' + end + + puts "Running on #{engine} #{RUBY_VERSION}." + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/runner/ruby_parse.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/runner/ruby_parse.rb new file mode 100644 index 00000000..827efdc2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/runner/ruby_parse.rb @@ -0,0 +1,157 @@ +# frozen_string_literal: true + +require_relative '../runner' +require_relative '../color' +require_relative '../lexer/explanation' +require 'json' + +module Parser + + class Runner::RubyParse < Parser::Runner + + class LocationProcessor < Parser::AST::Processor + def process(node) + if node + p node + + source_line_no = nil + source_line = '' + hilight_line = '' + + print_line = lambda do + unless hilight_line.empty? + puts hilight_line. + gsub(/[a-z_]+/) { |m| Color.yellow(m, bold: true) }. + gsub(/[~.]+/) { |m| Color.magenta(m, bold: true) } + hilight_line = '' + end + end + + print_source = lambda do |range| + source_line = range.source_line + puts Color.green(source_line) + source_line + end + + (node.loc || {}).to_hash. + sort_by do |name, range| + [(range ? range.line : 0), + (name == :expression ? 1 : 0)] + end. + each do |name, range| + next if range.nil? + + if source_line_no != range.line + print_line.call() + source_line = print_source.call(range) + source_line_no = range.line + end + + beg_col = range.begin.column + + if beg_col + range.length > source_line.length + multiline = true + range_length = source_line.length - beg_col + 3 + else + multiline = false + range_length = range.length + end + + length = range_length + 1 + name.length + end_col = beg_col + length + + if beg_col > 0 + col_range = (beg_col - 1)...end_col + else + col_range = beg_col...end_col + end + + if hilight_line.length < end_col + hilight_line = hilight_line.ljust(end_col) + end + + if hilight_line[col_range] =~ /^\s*$/ + if multiline + tail = ('~' * (source_line.length - beg_col)) + '...' + else + tail = '~' * range_length + end + + tail = ' ' + tail if beg_col > 0 + + hilight_line[col_range] = tail + " #{name}" + else + print_line.call + redo + end + end + + print_line.call + end + + super + end + end + + def initialize + super + + @locate = false + @emit_ruby = false + @emit_json = false + end + + private + + def runner_name + 'ruby-parse' + end + + def setup_option_parsing(opts) + super(opts) + + opts.on '-L', '--locate', 'Explain how source maps for AST nodes are laid out' do |v| + @locate = v + end + + opts.on '-E', '--explain', 'Explain how the source is tokenized' do + ENV['RACC_DEBUG'] = '1' + + Lexer.send :include, Lexer::Explanation + end + + opts.on '--emit-ruby', 'Emit S-expressions as valid Ruby code' do + @emit_ruby = true + end + + opts.on '--emit-json', 'Emit S-expressions as valid JSON' do + @emit_json = true + end + end + + def process_all_input + if input_size > 1 + puts "Using #{@parser_class} to parse #{input_size} files." + end + + super + end + + def process(buffer) + ast = @parser.parse(buffer) + + if @locate + LocationProcessor.new.process(ast) + elsif !@benchmark + if @emit_ruby + puts ast.inspect + elsif @emit_json + puts(ast ? JSON.generate(ast.to_sexp_array) : nil) + else + puts ast.to_s + end + end + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/runner/ruby_rewrite.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/runner/ruby_rewrite.rb new file mode 100644 index 00000000..8039eba8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/runner/ruby_rewrite.rb @@ -0,0 +1,101 @@ +# frozen_string_literal: true + +require_relative '../runner' +require 'tempfile' + +module Parser + + class Runner::RubyRewrite < Runner + def initialize + super + + @rewriters = [] + @modify = false + end + + private + + def runner_name + 'ruby-rewrite' + end + + def setup_option_parsing(opts) + super(opts) + + opts.on '-l file', '--load', 'Load a rewriter' do |file| + load_and_discover(file) + end + + opts.on '-m', '--modify', 'Assume rewriters normally modify AST' do + @modify = true + end + end + + def load_and_discover(file) + load file + + const_name = File.basename(file). + sub(/\.rb$/, ''). + gsub(/(^|_)([a-z])/) do |m| + "#{$2.upcase}" + end + + @rewriters << Object.const_get(const_name) + end + + def process(initial_buffer) + buffer = initial_buffer + original_name = buffer.name + + @rewriters.each do |rewriter_class| + @parser.reset + ast = @parser.parse(buffer) + + rewriter = rewriter_class.new + new_source = rewriter.rewrite(buffer, ast) + + new_buffer = Source::Buffer.new(initial_buffer.name + + '|after ' + rewriter_class.name, + source: new_source) + + @parser.reset + new_ast = @parser.parse(new_buffer) + + if !@modify && ast != new_ast + $stderr.puts 'ASTs do not match:' + + old = Tempfile.new('old') + old.write ast.inspect + "\n"; old.flush + + new = Tempfile.new('new') + new.write new_ast.inspect + "\n"; new.flush + + IO.popen("diff -u #{old.path} #{new.path}") do |io| + diff = io.read. + sub(/^---.*/, "--- #{buffer.name}"). + sub(/^\+\+\+.*/, "+++ #{new_buffer.name}") + + $stderr.write diff + end + + exit 1 + end + + buffer = new_buffer + end + + if File.exist?(original_name) + File.open(original_name, 'w') do |file| + file.write buffer.source + end + else + if input_size > 1 + puts "Rewritten content of #{buffer.name}:" + end + + puts buffer.source + end + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/buffer.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/buffer.rb new file mode 100644 index 00000000..ea9c7cf8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/buffer.rb @@ -0,0 +1,369 @@ +# encoding: ascii-8bit +# frozen_string_literal: true + +module Parser + module Source + + ## + # A buffer with source code. {Buffer} contains the source code itself, + # associated location information (name and first line), and takes care + # of encoding. + # + # A source buffer is immutable once populated. + # + # @!attribute [r] name + # Buffer name. If the buffer was created from a file, the name corresponds + # to relative path to the file. + # @return [String] buffer name + # + # @!attribute [r] first_line + # First line of the buffer, 1 by default. + # @return [Integer] first line + # + # @api public + # + class Buffer + attr_reader :name, :first_line + + ## + # @api private + # + ENCODING_RE = + /[\s#](en)?coding\s*[:=]\s* + ( + # Special-case: there's a UTF8-MAC encoding. + (utf8-mac) + | + # Chew the suffix; it's there for emacs compat. + ([A-Za-z0-9_-]+?)(-unix|-dos|-mac) + | + ([A-Za-z0-9_-]+) + ) + /x + + ## + # Try to recognize encoding of `string` as Ruby would, i.e. by looking for + # magic encoding comment or UTF-8 BOM. `string` can be in any encoding. + # + # @param [String] string + # @raise [Parser::UnknownEncodingInMagicComment] if the encoding is not recognized + # @return [String, nil] encoding name, if recognized + # + def self.recognize_encoding(string) + return if string.empty? + + # extract the first two lines in an efficient way + string =~ /\A(.*)\n?(.*\n)?/ + first_line, second_line = $1, $2 + + if first_line.start_with?("\xef\xbb\xbf".freeze) # BOM + return Encoding::UTF_8 + elsif first_line[0, 2] == '#!'.freeze + encoding_line = second_line + else + encoding_line = first_line + end + + return nil if encoding_line.nil? || encoding_line[0] != '#' + + if (result = ENCODING_RE.match(encoding_line)) + begin + Encoding.find(result[3] || result[4] || result[6]) + rescue ArgumentError => e + raise Parser::UnknownEncodingInMagicComment, e.message + end + else + nil + end + end + + ## + # Recognize encoding of `input` and process it so it could be lexed. + # + # * If `input` does not contain BOM or magic encoding comment, it is + # kept in the original encoding. + # * If the detected encoding is binary, `input` is kept in binary. + # * Otherwise, `input` is re-encoded into UTF-8 and returned as a + # new string. + # + # This method mutates the encoding of `input`, but not its content. + # + # @param [String] input + # @return [String] + # @raise [EncodingError] + # + def self.reencode_string(input) + original_encoding = input.encoding + detected_encoding = recognize_encoding(input.force_encoding(Encoding::BINARY)) + + if detected_encoding.nil? + input.force_encoding(original_encoding) + elsif detected_encoding == Encoding::BINARY + input + else + input. + force_encoding(detected_encoding). + encode(Encoding::UTF_8) + end + end + + def initialize(name, first_line = 1, source: nil) + @name = name.to_s + @source = nil + @first_line = first_line + + @lines = nil + @line_begins = nil + + # UTF-32-reencoded source for O(1) slicing + @slice_source = nil + + # Cache for fast lookup + @line_index_for_position = {} + + self.source = source if source + end + + ## + # Populate this buffer from correspondingly named file. + # + # @example + # Parser::Source::Buffer.new('foo/bar.rb').read + # + # @return [Buffer] self + # @raise [ArgumentError] if already populated + # + def read + File.open(@name, 'rb') do |io| + self.source = io.read + end + + self + end + + ## + # Source code contained in this buffer. + # + # @return [String] source code + # @raise [RuntimeError] if buffer is not populated yet + # + def source + if @source.nil? + raise RuntimeError, 'Cannot extract source from uninitialized Source::Buffer' + end + + @source + end + + ## + # Populate this buffer from a string with encoding autodetection. + # `input` is mutated if not frozen. + # + # @param [String] input + # @raise [ArgumentError] if already populated + # @raise [EncodingError] if `input` includes invalid byte sequence for the encoding + # @return [String] + # + def source=(input) + input = input.dup if input.frozen? + input = self.class.reencode_string(input) + + unless input.valid_encoding? + raise EncodingError, "invalid byte sequence in #{input.encoding.name}" + end + + self.raw_source = input + end + + ## + # Populate this buffer from a string without encoding autodetection. + # + # @param [String] input + # @raise [ArgumentError] if already populated + # @return [String] + # + def raw_source=(input) + if @source + raise ArgumentError, 'Source::Buffer is immutable' + end + + @source = input.gsub("\r\n".freeze, "\n".freeze).freeze + + if !@source.ascii_only? && + @source.encoding != Encoding::UTF_32LE && + @source.encoding != Encoding::BINARY + @slice_source = @source.encode(Encoding::UTF_32LE) + end + end + + def slice(start, length = nil) + if length.nil? + if start.is_a?(::Range) + length = start.size + start = start.begin + else + length = 1 + end + end + + if @slice_source.nil? + @source[start, length] + else + @slice_source[start, length].encode(@source.encoding) + end + end + + ## + # Convert a character index into the source to a `[line, column]` tuple. + # + # @param [Integer] position + # @return [[Integer, Integer]] `[line, column]` + # + def decompose_position(position) + line_index = line_index_for_position(position) + line_begin = line_begins[line_index] + + [ @first_line + line_index , position - line_begin ] + end + + ## + # Convert a character index into the source to a line number. + # + # @param [Integer] position + # @return [Integer] line + # @api private + # + def line_for_position(position) + line_index_for_position(position) + @first_line + end + + ## + # Convert a character index into the source to a column number. + # + # @param [Integer] position + # @return [Integer] column + # @api private + # + def column_for_position(position) + line_index = line_index_for_position(position) + position - line_begins[line_index] + end + + ## + # Return an `Array` of source code lines. + # + # @return [Array] + # + def source_lines + @lines ||= begin + lines = @source.lines.to_a + lines << ''.dup if @source.end_with?("\n".freeze) + + lines.each do |line| + line.chomp!("\n".freeze) + line.freeze + end + + lines.freeze + end + end + + ## + # Extract line `lineno` from source, taking `first_line` into account. + # + # @param [Integer] lineno + # @return [String] + # @raise [IndexError] if `lineno` is out of bounds + # + def source_line(lineno) + source_lines.fetch(lineno - @first_line).dup + end + + ## + # Extract line `lineno` as a new `Range`, taking `first_line` into account. + # + # @param [Integer] lineno + # @return [Range] + # @raise [IndexError] if `lineno` is out of bounds + # + def line_range(lineno) + index = lineno - @first_line + if index < 0 || index + 1 >= line_begins.size + raise IndexError, 'Parser::Source::Buffer: range for line ' \ + "#{lineno} requested, valid line numbers are #{@first_line}.." \ + "#{@first_line + line_begins.size - 2}" + else + Range.new(self, line_begins[index], line_begins[index + 1] - 1) + end + end + + ## + # @return [Range] A range covering the whole source + # + def source_range + @source_range ||= Range.new(self, 0, source.size) + end + + ## + # Number of last line in the buffer + # + # @return [Integer] + # + def last_line + line_begins.size + @first_line - 2 + end + + # :nodoc: + def freeze + source_lines; line_begins; source_range # build cache + super + end + + # :nodoc: + def inspect + "#<#{self.class} #{name}>" + end + + private + + # @returns [0, line_begin_of_line_1, ..., source.size + 1] + def line_begins + @line_begins ||= begin + begins = [0] + index = 0 + while index = @source.index("\n".freeze, index) + index += 1 + begins << index + end + begins << @source.size + 1 + begins + end + end + + # @returns 0-based line index of position + def line_index_for_position(position) + @line_index_for_position[position] || begin + index = bsearch(line_begins, position) - 1 + @line_index_for_position[position] = index unless @line_index_for_position.frozen? + index + end + end + + if Array.method_defined?(:bsearch_index) # RUBY_VERSION >= 2.3 + def bsearch(line_begins, position) + line_begins.bsearch_index do |line_begin| + position < line_begin + end || line_begins.size - 1 # || only for out of bound values + end + else + def bsearch(line_begins, position) + @line_range ||= 0...line_begins.size + @line_range.bsearch do |i| + position < line_begins[i] + end || line_begins.size - 1 # || only for out of bound values + end + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/comment.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/comment.rb new file mode 100644 index 00000000..411d9872 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/comment.rb @@ -0,0 +1,134 @@ +# frozen_string_literal: true + +module Parser + module Source + + ## + # A comment in the source code. + # + # @!attribute [r] text + # @return [String] + # + # @!attribute [r] location + # @return [Parser::Source::Range] + # + # @api public + # + class Comment + attr_reader :text + + attr_reader :location + alias_method :loc, :location + + ## + # Associate `comments` with `ast` nodes by their corresponding node. + # + # @param [Parser::AST::Node] ast + # @param [Array] comments + # @return [Hash>] + # @see Parser::Source::Comment::Associator#associate + # @deprecated Use {associate_locations}. + # + def self.associate(ast, comments) + associator = Associator.new(ast, comments) + associator.associate + end + + ## + # Associate `comments` with `ast` nodes by their location in the + # source. + # + # @param [Parser::AST::Node] ast + # @param [Array] comments + # @return [Hash>] + # @see Parser::Source::Comment::Associator#associate_locations + # + def self.associate_locations(ast, comments) + associator = Associator.new(ast, comments) + associator.associate_locations + end + + ## + # Associate `comments` with `ast` nodes using identity. + # + # @param [Parser::AST::Node] ast + # @param [Array] comments + # @return [Hash>] + # @see Parser::Source::Comment::Associator#associate_by_identity + # + def self.associate_by_identity(ast, comments) + associator = Associator.new(ast, comments) + associator.associate_by_identity + end + + ## + # @param [Parser::Source::Range] range + # + def initialize(range) + @location = Parser::Source::Map.new(range) + @text = range.source.freeze + + freeze + end + + ## + # Type of this comment. + # + # * Inline comments correspond to `:inline`: + # + # # whatever + # + # * Block comments correspond to `:document`: + # + # =begin + # hi i am a document + # =end + # + # @return [Symbol] + # + def type + if text.start_with?("#".freeze) + :inline + elsif text.start_with?("=begin".freeze) + :document + end + end + + ## + # @see #type + # @return [Boolean] true if this is an inline comment. + # + def inline? + type == :inline + end + + ## + # @see #type + # @return [Boolean] true if this is a block comment. + # + def document? + type == :document + end + + ## + # Compares comments. Two comments are equal if they + # correspond to the same source range. + # + # @param [Object] other + # @return [Boolean] + # + def ==(other) + other.is_a?(Source::Comment) && + @location == other.location + end + + ## + # @return [String] a human-readable representation of this comment + # + def inspect + "#" + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/comment/associator.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/comment/associator.rb new file mode 100644 index 00000000..b81d4959 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/comment/associator.rb @@ -0,0 +1,233 @@ +# frozen_string_literal: true + +module Parser + module Source + + ## + # A processor which associates AST nodes with comments based on their + # location in source code. It may be used, for example, to implement + # rdoc-style processing. + # + # @example + # require 'parser/current' + # + # ast, comments = Parser::CurrentRuby.parse_with_comments(<<-CODE) + # # Class stuff + # class Foo + # # Attr stuff + # # @see bar + # attr_accessor :foo + # end + # CODE + # + # p Parser::Source::Comment.associate(ast, comments) + # # => { + # # (class (const nil :Foo) ...) => + # # [#], + # # (send nil :attr_accessor (sym :foo)) => + # # [#, + # # #] + # # } + # + # @see {associate} + # + # @!attribute skip_directives + # Skip file processing directives disguised as comments. + # Namely: + # + # * Shebang line, + # * Magic encoding comment. + # + # @return [Boolean] + # + # @api public + # + class Comment::Associator + attr_accessor :skip_directives + + ## + # @param [Parser::AST::Node] ast + # @param [Array] comments + def initialize(ast, comments) + @ast = ast + @comments = comments + + @skip_directives = true + end + + ## + # Compute a mapping between AST nodes and comments. Comment is + # associated with the node, if it is one of the following types: + # + # - preceding comment, it ends before the node start + # - sparse comment, it is located inside the node, after all child nodes + # - decorating comment, it starts at the same line, where the node ends + # + # This rule is unambiguous and produces the result + # one could reasonably expect; for example, this code + # + # # foo + # hoge # bar + # + fuga + # + # will result in the following association: + # + # { + # (send (lvar :hoge) :+ (lvar :fuga)) => + # [#], + # (lvar :fuga) => + # [#] + # } + # + # Note that comments after the end of the end of a passed tree range are + # ignored (except root decorating comment). + # + # Note that {associate} produces unexpected result for nodes which are + # equal but have distinct locations; comments for these nodes are merged. + # You may prefer using {associate_by_identity} or {associate_locations}. + # + # @return [Hash>] + # @deprecated Use {associate_locations}. + # + def associate + @map_using = :eql + do_associate + end + + ## + # Same as {associate}, but uses `node.loc` instead of `node` as + # the hash key, thus producing an unambiguous result even in presence + # of equal nodes. + # + # @return [Hash>] + # + def associate_locations + @map_using = :location + do_associate + end + + ## + # Same as {associate}, but compares by identity, thus producing an unambiguous + # result even in presence of equal nodes. + # + # @return [Hash>] + # + def associate_by_identity + @map_using = :identity + do_associate + end + + private + + POSTFIX_TYPES = Set[:if, :while, :while_post, :until, :until_post, :masgn].freeze + def children_in_source_order(node) + if POSTFIX_TYPES.include?(node.type) + # All these types have either nodes with expressions, or `nil` + # so a compact will do, but they need to be sorted. + node.children.compact.sort_by { |child| child.loc.expression.begin_pos } + else + node.children.select do |child| + child.is_a?(AST::Node) && child.loc && child.loc.expression + end + end + end + + def do_associate + @mapping = Hash.new { |h, k| h[k] = [] } + @mapping.compare_by_identity if @map_using == :identity + @comment_num = -1 + advance_comment + + advance_through_directives if @skip_directives + + visit(@ast) if @ast + + @mapping + end + + def visit(node) + process_leading_comments(node) + + return unless @current_comment + + # If the next comment is beyond the last line of this node, we don't + # need to iterate over its subnodes + # (Unless this node is a heredoc... there could be a comment in its body, + # inside an interpolation) + node_loc = node.location + if @current_comment.location.line <= node_loc.last_line || + node_loc.is_a?(Map::Heredoc) + children_in_source_order(node).each { |child| visit(child) } + + process_trailing_comments(node) + end + end + + def process_leading_comments(node) + return if node.type == :begin + while current_comment_before?(node) # preceding comment + associate_and_advance_comment(node) + end + end + + def process_trailing_comments(node) + while current_comment_before_end?(node) + associate_and_advance_comment(node) # sparse comment + end + while current_comment_decorates?(node) + associate_and_advance_comment(node) # decorating comment + end + end + + def advance_comment + @comment_num += 1 + @current_comment = @comments[@comment_num] + end + + def current_comment_before?(node) + return false if !@current_comment + comment_loc = @current_comment.location.expression + node_loc = node.location.expression + comment_loc.end_pos <= node_loc.begin_pos + end + + def current_comment_before_end?(node) + return false if !@current_comment + comment_loc = @current_comment.location.expression + node_loc = node.location.expression + comment_loc.end_pos <= node_loc.end_pos + end + + def current_comment_decorates?(node) + return false if !@current_comment + @current_comment.location.line == node.location.last_line + end + + def associate_and_advance_comment(node) + key = @map_using == :location ? node.location : node + @mapping[key] << @current_comment + advance_comment + end + + MAGIC_COMMENT_RE = /^#\s*(-\*-|)\s*(frozen_string_literal|warn_indent|warn_past_scope):.*\1$/ + + def advance_through_directives + # Skip shebang. + if @current_comment && @current_comment.text.start_with?('#!'.freeze) + advance_comment + end + + # Skip magic comments. + if @current_comment && @current_comment.text =~ MAGIC_COMMENT_RE + advance_comment + end + + # Skip encoding line. + if @current_comment && @current_comment.text =~ Buffer::ENCODING_RE + advance_comment + end + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map.rb new file mode 100644 index 00000000..456e11f8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map.rb @@ -0,0 +1,186 @@ +# frozen_string_literal: true + +module Parser + module Source + + ## + # {Map} relates AST nodes to the source code they were parsed from. + # More specifically, a {Map} or its subclass contains a set of ranges: + # + # * `expression`: smallest range which includes all source corresponding + # to the node and all `expression` ranges of its children. + # * other ranges (`begin`, `end`, `operator`, ...): node-specific ranges + # pointing to various interesting tokens corresponding to the node. + # + # Note that the {Map::Heredoc} map is the only one whose `expression` does + # not include other ranges. It only covers the heredoc marker (`< 2]').children[0].loc + # # => > + # + # The {file:doc/AST_FORMAT.md} document describes how ranges associated to source + # code tokens. For example, the entry + # + # (array (int 1) (int 2)) + # + # "[1, 2]" + # ^ begin + # ^ end + # ~~~~~~ expression + # + # means that if `node` is an {Parser::AST::Node} `(array (int 1) (int 2))`, + # then `node.loc` responds to `begin`, `end` and `expression`, and + # `node.loc.begin` returns a range pointing at the opening bracket, and so on. + # + # If you want to write code polymorphic by the source map (i.e. accepting + # several subclasses of {Map}), use `respond_to?` instead of `is_a?` to + # check whether the map features the range you need. Concrete {Map} + # subclasses may not be preserved between versions, but their interfaces + # will be kept compatible. + # + # You can visualize the source maps with `ruby-parse -E` command-line tool. + # + # @example + # require 'parser/current' + # + # p Parser::CurrentRuby.parse('[1, 2]').loc + # # => #, + # # @begin=#, + # # @expression=#> + # + # @!attribute [r] node + # The node that is described by this map. Nodes and maps have 1:1 correspondence. + # @return [Parser::AST::Node] + # + # @!attribute [r] expression + # @return [Range] + # + # @api public + # + class Map + attr_reader :node + attr_reader :expression + + ## + # @param [Range] expression + def initialize(expression) + @expression = expression + end + + ## + # @api private + def initialize_copy(other) + super + @node = nil + end + + ## + # @api private + def node=(node) + @node = node + freeze + @node + end + + ## + # A shortcut for `self.expression.line`. + # @return [Integer] + # + def line + @expression.line + end + + alias_method :first_line, :line + + ## + # A shortcut for `self.expression.column`. + # @return [Integer] + # + def column + @expression.column + end + + ## + # A shortcut for `self.expression.last_line`. + # @return [Integer] + # + def last_line + @expression.last_line + end + + ## + # A shortcut for `self.expression.last_column`. + # @return [Integer] + # + def last_column + @expression.last_column + end + + ## + # @api private + # + def with_expression(expression_l) + with { |map| map.update_expression(expression_l) } + end + + ## + # Compares source maps. + # @return [Boolean] + # + def ==(other) + other.class == self.class && + instance_variables.map do |ivar| + instance_variable_get(ivar) == + other.send(:instance_variable_get, ivar) + end.reduce(:&) + end + + ## + # Converts this source map to a hash with keys corresponding to + # ranges. For example, if called on an instance of {Collection}, + # which adds the `begin` and `end` ranges, the resulting hash + # will contain keys `:expression`, `:begin` and `:end`. + # + # @example + # require 'parser/current' + # + # p Parser::CurrentRuby.parse('[1, 2]').loc.to_hash + # # => { + # # :begin => #, + # # :end => #, + # # :expression => # + # # } + # + # @return [Hash] + # + def to_hash + instance_variables.inject({}) do |hash, ivar| + next hash if ivar.to_sym == :@node + hash[ivar[1..-1].to_sym] = instance_variable_get(ivar) + hash + end + end + + protected + + def with(&block) + dup.tap(&block) + end + + def update_expression(expression_l) + @expression = expression_l + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/collection.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/collection.rb new file mode 100644 index 00000000..1bf1f970 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/collection.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module Parser + module Source + + class Map::Collection < Map + attr_reader :begin + attr_reader :end + + def initialize(begin_l, end_l, expression_l) + @begin, @end = begin_l, end_l + + super(expression_l) + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/condition.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/condition.rb new file mode 100644 index 00000000..07a6f6f9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/condition.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Parser + module Source + + class Map::Condition < Map + attr_reader :keyword + attr_reader :begin + attr_reader :else + attr_reader :end + + def initialize(keyword_l, begin_l, else_l, end_l, expression_l) + @keyword = keyword_l + @begin, @else, @end = begin_l, else_l, end_l + + super(expression_l) + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/constant.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/constant.rb new file mode 100644 index 00000000..d22b3451 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/constant.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module Parser + module Source + + class Map::Constant < Map + attr_reader :double_colon + attr_reader :name + attr_reader :operator + + def initialize(double_colon, name, expression) + @double_colon, @name = double_colon, name + + super(expression) + end + + ## + # @api private + # + def with_operator(operator_l) + with { |map| map.update_operator(operator_l) } + end + + protected + + def update_operator(operator_l) + @operator = operator_l + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/definition.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/definition.rb new file mode 100644 index 00000000..2260192a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/definition.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Parser + module Source + + class Map::Definition < Map + attr_reader :keyword + attr_reader :operator + attr_reader :name + attr_reader :end + + def initialize(keyword_l, operator_l, name_l, end_l) + @keyword = keyword_l + @operator = operator_l + @name = name_l + @end = end_l + + super(@keyword.join(@end)) + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/for.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/for.rb new file mode 100644 index 00000000..7eec546a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/for.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Parser + module Source + + class Map::For < Map + attr_reader :keyword, :in + attr_reader :begin, :end + + def initialize(keyword_l, in_l, begin_l, end_l, expression_l) + @keyword, @in = keyword_l, in_l + @begin, @end = begin_l, end_l + + super(expression_l) + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/heredoc.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/heredoc.rb new file mode 100644 index 00000000..7e5db343 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/heredoc.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Parser + module Source + + class Map::Heredoc < Map + attr_reader :heredoc_body + attr_reader :heredoc_end + + def initialize(begin_l, body_l, end_l) + @heredoc_body = body_l + @heredoc_end = end_l + + super(begin_l) + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/index.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/index.rb new file mode 100644 index 00000000..62cf9b0f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/index.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +module Parser + module Source + + class Map::Index < Map + attr_reader :begin + attr_reader :end + attr_reader :operator + + def initialize(begin_l, end_l, expression_l) + @begin, @end = begin_l, end_l + @operator = nil + + super(expression_l) + end + + ## + # @api private + # + def with_operator(operator_l) + with { |map| map.update_operator(operator_l) } + end + + protected + + def update_operator(operator_l) + @operator = operator_l + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/keyword.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/keyword.rb new file mode 100644 index 00000000..15bf1e4e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/keyword.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Parser + module Source + + class Map::Keyword < Map + attr_reader :keyword + attr_reader :begin + attr_reader :end + + def initialize(keyword_l, begin_l, end_l, expression_l) + @keyword = keyword_l + @begin, @end = begin_l, end_l + + super(expression_l) + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/method_definition.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/method_definition.rb new file mode 100644 index 00000000..12f6b9f1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/method_definition.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Parser + module Source + + class Map::MethodDefinition < Map + attr_reader :keyword + attr_reader :operator + attr_reader :name + attr_reader :end + attr_reader :assignment + + def initialize(keyword_l, operator_l, name_l, end_l, assignment_l, body_l) + @keyword = keyword_l + @operator = operator_l + @name = name_l + @end = end_l + @assignment = assignment_l + + super(@keyword.join(end_l || body_l)) + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/objc_kwarg.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/objc_kwarg.rb new file mode 100644 index 00000000..33bd6a8b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/objc_kwarg.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Parser + module Source + + class Map::ObjcKwarg < Map + attr_reader :keyword + attr_reader :operator + attr_reader :argument + + def initialize(keyword_l, operator_l, argument_l, expression_l) + @keyword, @operator, @argument = keyword_l, operator_l, argument_l + + super(expression_l) + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/operator.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/operator.rb new file mode 100644 index 00000000..c54e6182 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/operator.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Parser + module Source + + class Map::Operator < Map + attr_reader :operator + + def initialize(operator, expression) + @operator = operator + + super(expression) + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/rescue_body.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/rescue_body.rb new file mode 100644 index 00000000..92edd890 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/rescue_body.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Parser + module Source + + class Map::RescueBody < Map + attr_reader :keyword + attr_reader :assoc + attr_reader :begin + + def initialize(keyword_l, assoc_l, begin_l, expression_l) + @keyword = keyword_l + @assoc = assoc_l + @begin = begin_l + + super(expression_l) + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/send.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/send.rb new file mode 100644 index 00000000..659d6d48 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/send.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module Parser + module Source + + class Map::Send < Map + attr_reader :dot + attr_reader :selector + attr_reader :operator + attr_reader :begin + attr_reader :end + + def initialize(dot_l, selector_l, begin_l, end_l, expression_l) + @dot = dot_l + @selector = selector_l + @begin, @end = begin_l, end_l + + super(expression_l) + end + + ## + # @api private + # + def with_operator(operator_l) + with { |map| map.update_operator(operator_l) } + end + + protected + + def update_operator(operator_l) + @operator = operator_l + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/ternary.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/ternary.rb new file mode 100644 index 00000000..312d8c73 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/ternary.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module Parser + module Source + + class Map::Ternary < Map + attr_reader :question + attr_reader :colon + + def initialize(question_l, colon_l, expression_l) + @question, @colon = question_l, colon_l + + super(expression_l) + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/variable.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/variable.rb new file mode 100644 index 00000000..479f7049 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/map/variable.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module Parser + module Source + + class Map::Variable < Map + attr_reader :name + attr_reader :operator + + def initialize(name_l, expression_l=name_l) + @name = name_l + + super(expression_l) + end + + ## + # @api private + # + def with_operator(operator_l) + with { |map| map.update_operator(operator_l) } + end + + protected + + def update_operator(operator_l) + @operator = operator_l + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/range.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/range.rb new file mode 100644 index 00000000..60264b1c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/range.rb @@ -0,0 +1,326 @@ +# frozen_string_literal: true + +module Parser + module Source + + ## + # A range of characters in a particular source buffer. + # + # The range is always exclusive, i.e. a range with `begin_pos` of 3 and + # `end_pos` of 5 will contain the following characters: + # + # example + # ^^ + # + # @!attribute [r] source_buffer + # @return [Parser::Source::Buffer] + # + # @!attribute [r] begin_pos + # @return [Integer] index of the first character in the range + # + # @!attribute [r] end_pos + # @return [Integer] index of the character after the last character in the range + # + # @api public + # + class Range + include Comparable + + attr_reader :source_buffer + attr_reader :begin_pos, :end_pos + + ## + # @param [Buffer] source_buffer + # @param [Integer] begin_pos + # @param [Integer] end_pos + # + def initialize(source_buffer, begin_pos, end_pos) + if end_pos < begin_pos + raise ArgumentError, 'Parser::Source::Range: end_pos must not be less than begin_pos' + end + if source_buffer.nil? + raise ArgumentError, 'Parser::Source::Range: source_buffer must not be nil' + end + + @source_buffer = source_buffer + @begin_pos, @end_pos = begin_pos, end_pos + + freeze + end + + ## + # @return [Range] a zero-length range located just before the beginning + # of this range. + # + def begin + with(end_pos: @begin_pos) + end + + ## + # @return [Range] a zero-length range located just after the end + # of this range. + # + def end + with(begin_pos: @end_pos) + end + + ## + # @return [Integer] amount of characters included in this range. + # + def size + @end_pos - @begin_pos + end + + alias length size + + ## + # Line number of the beginning of this range. By default, the first line + # of a buffer is 1; as such, line numbers are most commonly one-based. + # + # @see Buffer + # @return [Integer] line number of the beginning of this range. + # + def line + @source_buffer.line_for_position(@begin_pos) + end + + alias_method :first_line, :line + + ## + # @return [Integer] zero-based column number of the beginning of this range. + # + def column + @source_buffer.column_for_position(@begin_pos) + end + + ## + # @return [Integer] line number of the end of this range. + # + def last_line + @source_buffer.line_for_position(@end_pos) + end + + ## + # @return [Integer] zero-based column number of the end of this range. + # + def last_column + @source_buffer.column_for_position(@end_pos) + end + + ## + # @return [::Range] a range of columns spanned by this range. + # @raise RangeError + # + def column_range + if line != last_line + raise RangeError, "#{self.inspect} spans more than one line" + end + + column...last_column + end + + ## + # @return [String] a line of source code containing the beginning of this range. + # + def source_line + @source_buffer.source_line(line) + end + + ## + # @return [String] all source code covered by this range. + # + def source + @source_buffer.slice(@begin_pos, @end_pos - @begin_pos) + end + + ## + # `is?` provides a concise way to compare the source corresponding to this range. + # For example, `r.source == '(' || r.source == 'begin'` is equivalent to + # `r.is?('(', 'begin')`. + # + def is?(*what) + what.include?(source) + end + + ## + # @return [Array] a set of character indexes contained in this range. + # + def to_a + (@begin_pos...@end_pos).to_a + end + + ## + # @return [Range] a Ruby range with the same `begin_pos` and `end_pos` + # + def to_range + self.begin_pos...self.end_pos + end + + ## + # Composes a GNU/Clang-style string representation of the beginning of this + # range. + # + # For example, for the following range in file `foo.rb`, + # + # def foo + # ^^^ + # + # `to_s` will return `foo.rb:1:5`. + # Note that the column index is one-based. + # + # @return [String] + # + def to_s + line, column = @source_buffer.decompose_position(@begin_pos) + + [@source_buffer.name, line, column + 1].join(':') + end + + ## + # @param [Hash] Endpoint(s) to change, any combination of :begin_pos or :end_pos + # @return [Range] the same range as this range but with the given end point(s) changed + # to the given value(s). + # + def with(begin_pos: @begin_pos, end_pos: @end_pos) + Range.new(@source_buffer, begin_pos, end_pos) + end + + ## + # @param [Hash] Endpoint(s) to change, any combination of :begin_pos or :end_pos + # @return [Range] the same range as this range but with the given end point(s) adjusted + # by the given amount(s) + # + def adjust(begin_pos: 0, end_pos: 0) + Range.new(@source_buffer, @begin_pos + begin_pos, @end_pos + end_pos) + end + + ## + # @param [Integer] new_size + # @return [Range] a range beginning at the same point as this range and length `new_size`. + # + def resize(new_size) + with(end_pos: @begin_pos + new_size) + end + + ## + # @param [Range] other + # @return [Range] smallest possible range spanning both this range and `other`. + # + def join(other) + Range.new(@source_buffer, + [@begin_pos, other.begin_pos].min, + [@end_pos, other.end_pos].max) + end + + ## + # @param [Range] other + # @return [Range] overlapping region of this range and `other`, or `nil` + # if they do not overlap + # + def intersect(other) + unless disjoint?(other) + Range.new(@source_buffer, + [@begin_pos, other.begin_pos].max, + [@end_pos, other.end_pos].min) + end + end + + ## + # Return `true` iff this range and `other` are disjoint. + # + # Two ranges must be one and only one of ==, disjoint?, contains?, contained? or crossing? + # + # @param [Range] other + # @return [Boolean] + # + def disjoint?(other) + if empty? && other.empty? + @begin_pos != other.begin_pos + else + @begin_pos >= other.end_pos || other.begin_pos >= @end_pos + end + end + + ## + # Return `true` iff this range is not disjoint from `other`. + # + # @param [Range] other + # @return [Boolean] `true` if this range and `other` overlap + # + def overlaps?(other) + !disjoint?(other) + end + + ## + # Returns true iff this range contains (strictly) `other`. + # + # Two ranges must be one and only one of ==, disjoint?, contains?, contained? or crossing? + # + # @param [Range] other + # @return [Boolean] + # + def contains?(other) + (other.begin_pos <=> @begin_pos) + (@end_pos <=> other.end_pos) >= (other.empty? ? 2 : 1) + end + + ## + # Return `other.contains?(self)` + # + # Two ranges must be one and only one of ==, disjoint?, contains?, contained? or crossing? + # + # @param [Range] other + # @return [Boolean] + # + def contained?(other) + other.contains?(self) + end + + ## + # Returns true iff both ranges intersect and also have different elements from one another. + # + # Two ranges must be one and only one of ==, disjoint?, contains?, contained? or crossing? + # + # @param [Range] other + # @return [Boolean] + # + def crossing?(other) + return false unless overlaps?(other) + (@begin_pos <=> other.begin_pos) * (@end_pos <=> other.end_pos) == 1 + end + + ## + # Checks if a range is empty; if it contains no characters + # @return [Boolean] + def empty? + @begin_pos == @end_pos + end + + ## + # Compare ranges, first by begin_pos, then by end_pos. + # + def <=>(other) + return nil unless other.is_a?(::Parser::Source::Range) && + @source_buffer == other.source_buffer + (@begin_pos <=> other.begin_pos).nonzero? || + (@end_pos <=> other.end_pos) + end + + alias_method :eql?, :== + + ## + # Support for Ranges be used in as Hash indices and in Sets. + # + def hash + [@source_buffer, @begin_pos, @end_pos].hash + end + + ## + # @return [String] a human-readable representation of this range. + # + def inspect + "#" + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/rewriter.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/rewriter.rb new file mode 100644 index 00000000..23a6fb99 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/rewriter.rb @@ -0,0 +1,513 @@ +# frozen_string_literal: true + +module Parser + module Source + + ## + # {Rewriter} is deprecated. Use {TreeRewriter} instead. + # + # TreeRewriter has simplified semantics, and customizable policies + # with regards to clobbering. Please read the documentation. + # + # Keep in mind: + # - Rewriter was discarding the `end_pos` of the given range for `insert_before`, + # and the `begin_pos` for `insert_after`. These are meaningful in TreeRewriter. + # - TreeRewriter's wrap/insert_before/insert_after are multiple by default, while + # Rewriter would raise clobbering errors if the non '_multi' version was called. + # - The TreeRewriter policy closest to Rewriter's behavior is: + # different_replacements: :raise, + # swallowed_insertions: :raise, + # crossing_deletions: :accept + # + # @!attribute [r] source_buffer + # @return [Source::Buffer] + # + # @!attribute [r] diagnostics + # @return [Diagnostic::Engine] + # + # @api public + # @deprecated Use {TreeRewriter} + # + class Rewriter + attr_reader :source_buffer + attr_reader :diagnostics + + ## + # @param [Source::Buffer] source_buffer + # @deprecated Use {TreeRewriter} + # + def initialize(source_buffer) + self.class.warn_of_deprecation + @diagnostics = Diagnostic::Engine.new + @diagnostics.consumer = lambda do |diag| + $stderr.puts diag.render + end + + @source_buffer = source_buffer + @queue = [] + @clobber = 0 + @insertions = 0 # clobbered zero-length positions; index 0 is the far left + + @insert_before_multi_order = 0 + @insert_after_multi_order = 0 + + @pending_queue = nil + @pending_clobber = nil + @pending_insertions = nil + end + + ## + # Removes the source range. + # + # @param [Range] range + # @return [Rewriter] self + # @raise [ClobberingError] when clobbering is detected + # @deprecated Use {TreeRewriter#remove} + # + def remove(range) + append Rewriter::Action.new(range, ''.freeze) + end + + ## + # Inserts new code before the given source range. + # + # @param [Range] range + # @param [String] content + # @return [Rewriter] self + # @raise [ClobberingError] when clobbering is detected + # @deprecated Use {TreeRewriter#insert_before} + # + def insert_before(range, content) + append Rewriter::Action.new(range.begin, content) + end + + ## + # Inserts new code before and after the given source range. + # + # @param [Range] range + # @param [String] before + # @param [String] after + # @return [Rewriter] self + # @raise [ClobberingError] when clobbering is detected + # @deprecated Use {TreeRewriter#wrap} + # + def wrap(range, before, after) + append Rewriter::Action.new(range.begin, before) + append Rewriter::Action.new(range.end, after) + end + + ## + # Inserts new code before the given source range by allowing other + # insertions at the same position. + # Note that an insertion with latter invocation comes _before_ earlier + # insertion at the same position in the rewritten source. + # + # @example Inserting '[(' + # rewriter. + # insert_before_multi(range, '('). + # insert_before_multi(range, '['). + # process + # + # @param [Range] range + # @param [String] content + # @return [Rewriter] self + # @raise [ClobberingError] when clobbering is detected + # @deprecated Use {TreeRewriter#insert_before} + # + def insert_before_multi(range, content) + @insert_before_multi_order -= 1 + append Rewriter::Action.new(range.begin, content, true, @insert_before_multi_order) + end + + ## + # Inserts new code after the given source range. + # + # @param [Range] range + # @param [String] content + # @return [Rewriter] self + # @raise [ClobberingError] when clobbering is detected + # @deprecated Use {TreeRewriter#insert_after} + # + def insert_after(range, content) + append Rewriter::Action.new(range.end, content) + end + + ## + # Inserts new code after the given source range by allowing other + # insertions at the same position. + # Note that an insertion with latter invocation comes _after_ earlier + # insertion at the same position in the rewritten source. + # + # @example Inserting ')]' + # rewriter. + # insert_after_multi(range, ')'). + # insert_after_multi(range, ']'). + # process + # + # @param [Range] range + # @param [String] content + # @return [Rewriter] self + # @raise [ClobberingError] when clobbering is detected + # @deprecated Use {TreeRewriter#insert_after} + # + def insert_after_multi(range, content) + @insert_after_multi_order += 1 + append Rewriter::Action.new(range.end, content, true, @insert_after_multi_order) + end + + ## + # Replaces the code of the source range `range` with `content`. + # + # @param [Range] range + # @param [String] content + # @return [Rewriter] self + # @raise [ClobberingError] when clobbering is detected + # @deprecated Use {TreeRewriter#replace} + # + def replace(range, content) + append Rewriter::Action.new(range, content) + end + + ## + # Applies all scheduled changes to the `source_buffer` and returns + # modified source as a new string. + # + # @return [String] + # @deprecated Use {TreeRewriter#process} + # + def process + if in_transaction? + raise "Do not call #{self.class}##{__method__} inside a transaction" + end + + adjustment = 0 + source = @source_buffer.source.dup + + @queue.sort.each do |action| + begin_pos = action.range.begin_pos + adjustment + end_pos = begin_pos + action.range.length + + source[begin_pos...end_pos] = action.replacement + + adjustment += (action.replacement.length - action.range.length) + end + + source + end + + ## + # Provides a protected block where a sequence of multiple rewrite actions + # are handled atomically. If any of the actions failed by clobbering, + # all the actions are rolled back. + # + # @example + # begin + # rewriter.transaction do + # rewriter.insert_before(range_of_something, '(') + # rewriter.insert_after(range_of_something, ')') + # end + # rescue Parser::ClobberingError + # end + # + # @raise [RuntimeError] when no block is passed + # @raise [RuntimeError] when already in a transaction + # @deprecated Use {TreeRewriter#transaction} + # + def transaction + unless block_given? + raise "#{self.class}##{__method__} requires block" + end + + if in_transaction? + raise 'Nested transaction is not supported' + end + + @pending_queue = @queue.dup + @pending_clobber = @clobber + @pending_insertions = @insertions + + yield + + @queue = @pending_queue + @clobber = @pending_clobber + @insertions = @pending_insertions + + self + ensure + @pending_queue = nil + @pending_clobber = nil + @pending_insertions = nil + end + + private + + # Schedule a code update. If it overlaps with another update, check + # whether they conflict, and raise a clobbering error if they do. + # (As a special case, zero-length ranges at the same position are + # considered to "overlap".) Otherwise, merge them. + # + # Updates which are adjacent to each other, but do not overlap, are also + # merged. + # + # RULES: + # + # - Insertion ("replacing" a zero-length range): + # - Two insertions at the same point conflict. This is true even + # if the earlier insertion has already been merged with an adjacent + # update, and even if they are both inserting the same text. + # - An insertion never conflicts with a replace or remove operation + # on its right or left side, which does not overlap it (in other + # words, which does not update BOTH its right and left sides). + # - An insertion always conflicts with a remove operation which spans + # both its sides. + # - An insertion conflicts with a replace operation which spans both its + # sides, unless the replacement text is longer than the replaced text + # by the size of the insertion (or more), and the portion of + # replacement text immediately after the insertion position is + # identical to the inserted text. + # + # - Removal operations never conflict with each other. + # + # - Replacement operations: + # - Take the portion of each replacement text which falls within: + # - The other operation's replaced region + # - The other operation's replacement text, if it extends past the + # end of its own replaced region (in other words, if the replacement + # text is longer than the text it replaces) + # - If and only if the taken texts are identical for both operations, + # they do not conflict. + # + def append(action) + range = action.range + + # Is this an insertion? + if range.empty? + # Replacing nothing with... nothing? + return self if action.replacement.empty? + + if !action.allow_multiple_insertions? && (conflicting = clobbered_insertion?(range)) + raise_clobber_error(action, [conflicting]) + end + + record_insertion(range) + + if (adjacent = adjacent_updates?(range)) + conflicting = adjacent.find do |a| + a.range.overlaps?(range) && + !replace_compatible_with_insertion?(a, action) + end + raise_clobber_error(action, [conflicting]) if conflicting + + merge_actions!(action, adjacent) + else + active_queue << action + end + else + # It's a replace or remove operation. + if (insertions = adjacent_insertions?(range)) + insertions.each do |insertion| + if range.overlaps?(insertion.range) && + !replace_compatible_with_insertion?(action, insertion) + raise_clobber_error(action, [insertion]) + else + action = merge_actions(action, [insertion]) + active_queue.delete(insertion) + end + end + end + + if (adjacent = adjacent_updates?(range)) + if can_merge?(action, adjacent) + record_replace(range) + merge_actions!(action, adjacent) + else + raise_clobber_error(action, adjacent) + end + else + record_replace(range) + active_queue << action + end + end + + self + end + + def record_insertion(range) + self.active_insertions = active_insertions | (1 << range.begin_pos) + end + + def record_replace(range) + self.active_clobber = active_clobber | clobbered_position_mask(range) + end + + def clobbered_position_mask(range) + ((1 << range.size) - 1) << range.begin_pos + end + + def adjacent_position_mask(range) + ((1 << (range.size + 2)) - 1) << (range.begin_pos - 1) + end + + def adjacent_insertion_mask(range) + ((1 << (range.size + 1)) - 1) << range.begin_pos + end + + def clobbered_insertion?(insertion) + insertion_pos = insertion.begin_pos + if active_insertions & (1 << insertion_pos) != 0 + # The clobbered insertion may have already been merged with other + # updates, so it won't necessarily have the same begin_pos. + active_queue.find do |a| + a.range.begin_pos <= insertion_pos && insertion_pos <= a.range.end_pos + end + end + end + + def adjacent_insertions?(range) + # Just retrieve insertions which have not been merged with an adjacent + # remove or replace. + if active_insertions & adjacent_insertion_mask(range) != 0 + result = active_queue.select do |a| + a.range.empty? && adjacent?(range, a.range) + end + result.empty? ? nil : result + end + end + + def adjacent_updates?(range) + if active_clobber & adjacent_position_mask(range) != 0 + active_queue.select { |a| adjacent?(range, a.range) } + end + end + + def replace_compatible_with_insertion?(replace, insertion) + (replace.replacement.length - replace.range.size) >= insertion.range.size && + (offset = insertion.range.begin_pos - replace.range.begin_pos) && + replace.replacement[offset, insertion.replacement.length] == insertion.replacement + end + + def can_merge?(action, existing) + # Compare 2 replace/remove operations (neither is an insertion) + range = action.range + + existing.all? do |other| + overlap = range.intersect(other.range) + next true if overlap.nil? # adjacent, not overlapping + + repl1_offset = overlap.begin_pos - range.begin_pos + repl2_offset = overlap.begin_pos - other.range.begin_pos + repl1_length = [other.range.length - repl2_offset, + other.replacement.length - repl2_offset].max + repl2_length = [range.length - repl1_offset, + action.replacement.length - repl1_offset].max + + replacement1 = action.replacement[repl1_offset, repl1_length] || ''.freeze + replacement2 = other.replacement[repl2_offset, repl2_length] || ''.freeze + replacement1 == replacement2 + end + end + + def merge_actions(action, existing) + actions = existing.push(action).sort_by do |a| + [a.range.begin_pos, a.range.end_pos] + end + range = actions.first.range.join(actions.max_by { |a| a.range.end_pos }.range) + + Rewriter::Action.new(range, merge_replacements(actions)) + end + + def merge_actions!(action, existing) + new_action = merge_actions(action, existing) + active_queue.delete(action) + replace_actions(existing, new_action) + end + + def merge_replacements(actions) + result = ''.dup + prev_act = nil + + actions.each do |act| + if !prev_act || act.range.disjoint?(prev_act.range) + result << act.replacement + else + prev_end = [prev_act.range.begin_pos + prev_act.replacement.length, + prev_act.range.end_pos].max + offset = prev_end - act.range.begin_pos + result << act.replacement[offset..-1] if offset < act.replacement.size + end + + prev_act = act + end + + result + end + + def replace_actions(old, updated) + old.each { |act| active_queue.delete(act) } + active_queue << updated + end + + def raise_clobber_error(action, existing) + # cannot replace 3 characters with "foobar" + diagnostic = Diagnostic.new(:error, + :invalid_action, + { :action => action }, + action.range) + @diagnostics.process(diagnostic) + + # clobbered by: remove 3 characters + diagnostic = Diagnostic.new(:note, + :clobbered, + { :action => existing[0] }, + existing[0].range) + @diagnostics.process(diagnostic) + + raise ClobberingError, "Parser::Source::Rewriter detected clobbering" + end + + def in_transaction? + !@pending_queue.nil? + end + + def active_queue + @pending_queue || @queue + end + + def active_clobber + @pending_clobber || @clobber + end + + def active_insertions + @pending_insertions || @insertions + end + + def active_clobber=(value) + if @pending_clobber + @pending_clobber = value + else + @clobber = value + end + end + + def active_insertions=(value) + if @pending_insertions + @pending_insertions = value + else + @insertions = value + end + end + + def adjacent?(range1, range2) + range1.begin_pos <= range2.end_pos && range2.begin_pos <= range1.end_pos + end + + DEPRECATION_WARNING = [ + 'Parser::Source::Rewriter is deprecated.', + 'Please update your code to use Parser::Source::TreeRewriter instead' + ].join("\n").freeze + + extend Deprecation + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/rewriter/action.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/rewriter/action.rb new file mode 100644 index 00000000..908e6d10 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/rewriter/action.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +module Parser + module Source + + ## + # @api private + # + class Rewriter::Action + include Comparable + + attr_reader :range, :replacement, :allow_multiple_insertions, :order + alias_method :allow_multiple_insertions?, :allow_multiple_insertions + + def initialize(range, replacement='', allow_multiple_insertions = false, order = 0) + @range = range + @replacement = replacement + @allow_multiple_insertions = allow_multiple_insertions + @order = order + + freeze + end + + def <=>(other) + result = range.begin_pos <=> other.range.begin_pos + return result unless result.zero? + order <=> other.order + end + + def to_s + if @range.length == 0 && @replacement.empty? + 'do nothing' + elsif @range.length == 0 + "insert #{@replacement.inspect}" + elsif @replacement.empty? + "remove #{@range.length} character(s)" + else + "replace #{@range.length} character(s) with #{@replacement.inspect}" + end + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/tree_rewriter.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/tree_rewriter.rb new file mode 100644 index 00000000..2bbff582 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/tree_rewriter.rb @@ -0,0 +1,431 @@ +# frozen_string_literal: true + +module Parser + module Source + + ## + # {TreeRewriter} performs the heavy lifting in the source rewriting process. + # It schedules code updates to be performed in the correct order. + # + # For simple cases, the resulting source will be obvious. + # + # Examples for more complex cases follow. Assume these examples are acting on + # the source `'puts(:hello, :world)`. The methods #wrap, #remove, etc. + # receive a Range as first argument; for clarity, examples below use english + # sentences and a string of raw code instead. + # + # ## Overlapping ranges: + # + # Any two rewriting actions on overlapping ranges will fail and raise + # a `ClobberingError`, unless they are both deletions (covered next). + # + # * wrap ':hello, ' with '(' and ')' + # * wrap ', :world' with '(' and ')' + # => CloberringError + # + # ## Overlapping deletions: + # + # * remove ':hello, ' + # * remove ', :world' + # + # The overlapping ranges are merged and `':hello, :world'` will be removed. + # This policy can be changed. `:crossing_deletions` defaults to `:accept` + # but can be set to `:warn` or `:raise`. + # + # ## Multiple actions at the same end points: + # + # Results will always be independent on the order they were given. + # Exception: rewriting actions done on exactly the same range (covered next). + # + # Example: + # * replace ', ' by ' => ' + # * wrap ':hello, :world' with '{' and '}' + # * replace ':world' with ':everybody' + # * wrap ':world' with '[', ']' + # + # The resulting string will be `'puts({:hello => [:everybody]})'` + # and this result is independent on the order the instructions were given in. + # + # Note that if the two "replace" were given as a single replacement of ', :world' + # for ' => :everybody', the result would be a `ClobberingError` because of the wrap + # in square brackets. + # + # ## Multiple wraps on same range: + # * wrap ':hello' with '(' and ')' + # * wrap ':hello' with '[' and ']' + # + # The wraps are combined in order given and results would be `'puts([(:hello)], :world)'`. + # + # ## Multiple replacements on same range: + # * replace ':hello' by ':hi', then + # * replace ':hello' by ':hey' + # + # The replacements are made in the order given, so the latter replacement + # supersedes the former and ':hello' will be replaced by ':hey'. + # + # This policy can be changed. `:different_replacements` defaults to `:accept` + # but can be set to `:warn` or `:raise`. + # + # ## Swallowed insertions: + # wrap 'world' by '__', '__' + # replace ':hello, :world' with ':hi' + # + # A containing replacement will swallow the contained rewriting actions + # and `':hello, :world'` will be replaced by `':hi'`. + # + # This policy can be changed for swallowed insertions. `:swallowed_insertions` + # defaults to `:accept` but can be set to `:warn` or `:raise` + # + # ## Implementation + # The updates are organized in a tree, according to the ranges they act on + # (where children are strictly contained by their parent), hence the name. + # + # @!attribute [r] source_buffer + # @return [Source::Buffer] + # + # @!attribute [r] diagnostics + # @return [Diagnostic::Engine] + # + # @api public + # + class TreeRewriter + attr_reader :source_buffer + attr_reader :diagnostics + + ## + # @param [Source::Buffer] source_buffer + # + def initialize(source_buffer, + crossing_deletions: :accept, + different_replacements: :accept, + swallowed_insertions: :accept) + @diagnostics = Diagnostic::Engine.new + @diagnostics.consumer = -> diag { $stderr.puts diag.render } + + @source_buffer = source_buffer + @in_transaction = false + + @policy = {crossing_deletions: crossing_deletions, + different_replacements: different_replacements, + swallowed_insertions: swallowed_insertions}.freeze + check_policy_validity + + @enforcer = method(:enforce_policy) + # We need a range that would be jugded as containing all other ranges, + # including 0...0 and size...size: + all_encompassing_range = @source_buffer.source_range.adjust(begin_pos: -1, end_pos: +1) + @action_root = TreeRewriter::Action.new(all_encompassing_range, @enforcer) + end + + ## + # Returns true iff no (non trivial) update has been recorded + # + # @return [Boolean] + # + def empty? + @action_root.empty? + end + + ## + # Merges the updates of argument with the receiver. + # Policies of the receiver are used. + # This action is atomic in that it won't change the receiver + # unless it succeeds. + # + # @param [Rewriter] with + # @return [Rewriter] self + # @raise [ClobberingError] when clobbering is detected + # + def merge!(with) + raise 'TreeRewriter are not for the same source_buffer' unless + source_buffer == with.source_buffer + + @action_root = @action_root.combine(with.action_root) + self + end + + ## + # Returns a new rewriter that consists of the updates of the received + # and the given argument. Policies of the receiver are used. + # + # @param [Rewriter] with + # @return [Rewriter] merge of receiver and argument + # @raise [ClobberingError] when clobbering is detected + # + def merge(with) + dup.merge!(with) + end + + ## + # For special cases where one needs to merge a rewriter attached to a different source_buffer + # or that needs to be offset. Policies of the receiver are used. + # + # @param [TreeRewriter] rewriter from different source_buffer + # @param [Integer] offset + # @return [Rewriter] self + # @raise [IndexError] if action ranges (once offset) don't fit the current buffer + # + def import!(foreign_rewriter, offset: 0) + return self if foreign_rewriter.empty? + + contracted = foreign_rewriter.action_root.contract + merge_effective_range = ::Parser::Source::Range.new( + @source_buffer, + contracted.range.begin_pos + offset, + contracted.range.end_pos + offset, + ) + check_range_validity(merge_effective_range) + + merge_with = contracted.moved(@source_buffer, offset) + + @action_root = @action_root.combine(merge_with) + self + end + + ## + # Replaces the code of the source range `range` with `content`. + # + # @param [Range] range + # @param [String] content + # @return [Rewriter] self + # @raise [ClobberingError] when clobbering is detected + # + def replace(range, content) + combine(range, replacement: content) + end + + ## + # Inserts the given strings before and after the given range. + # + # @param [Range] range + # @param [String, nil] insert_before + # @param [String, nil] insert_after + # @return [Rewriter] self + # @raise [ClobberingError] when clobbering is detected + # + def wrap(range, insert_before, insert_after) + combine(range, insert_before: insert_before.to_s, insert_after: insert_after.to_s) + end + + ## + # Shortcut for `replace(range, '')` + # + # @param [Range] range + # @return [Rewriter] self + # @raise [ClobberingError] when clobbering is detected + # + def remove(range) + replace(range, ''.freeze) + end + + + ## + # Shortcut for `wrap(range, content, nil)` + # + # @param [Range] range + # @param [String] content + # @return [Rewriter] self + # @raise [ClobberingError] when clobbering is detected + # + def insert_before(range, content) + wrap(range, content, nil) + end + + ## + # Shortcut for `wrap(range, nil, content)` + # + # @param [Range] range + # @param [String] content + # @return [Rewriter] self + # @raise [ClobberingError] when clobbering is detected + # + def insert_after(range, content) + wrap(range, nil, content) + end + + ## + # Applies all scheduled changes to the `source_buffer` and returns + # modified source as a new string. + # + # @return [String] + # + def process + source = @source_buffer.source + + chunks = [] + last_end = 0 + @action_root.ordered_replacements.each do |range, replacement| + chunks << source[last_end...range.begin_pos] << replacement + last_end = range.end_pos + end + chunks << source[last_end...source.length] + chunks.join + end + + ## + # Returns a representation of the rewriter as an ordered list of replacements. + # + # rewriter.as_replacements # => [ [1...1, '('], + # [2...4, 'foo'], + # [5...6, ''], + # [6...6, '!'], + # [10...10, ')'], + # ] + # + # This representation is sufficient to recreate the result of `process` but it is + # not sufficient to recreate completely the rewriter for further merging/actions. + # See `as_nested_actions` + # + # @return [Array] an ordered list of pairs of range & replacement + # + def as_replacements + @action_root.ordered_replacements + end + + ## + # Returns a representation of the rewriter as nested insertions (:wrap) and replacements. + # + # rewriter.as_actions # =>[ [:wrap, 1...10, '(', ')'], + # [:wrap, 2...6, '', '!'], # aka "insert_after" + # [:replace, 2...4, 'foo'], + # [:replace, 5...6, ''], # aka "removal" + # ], + # + # Contrary to `as_replacements`, this representation is sufficient to recreate exactly + # the rewriter. + # + # @return [Array<(Symbol, Range, String{, String})>] + # + def as_nested_actions + @action_root.nested_actions + end + + ## + # Provides a protected block where a sequence of multiple rewrite actions + # are handled atomically. If any of the actions failed by clobbering, + # all the actions are rolled back. Transactions can be nested. + # + # @raise [RuntimeError] when no block is passed + # + def transaction + unless block_given? + raise "#{self.class}##{__method__} requires block" + end + + previous = @in_transaction + @in_transaction = true + restore_root = @action_root + + yield + + restore_root = nil + + self + ensure + @action_root = restore_root if restore_root + @in_transaction = previous + end + + def in_transaction? + @in_transaction + end + + # :nodoc: + def inspect + "#<#{self.class} #{source_buffer.name}: #{action_summary}>" + end + + ## + # @api private + # @deprecated Use insert_after or wrap + # + def insert_before_multi(range, text) + self.class.warn_of_deprecation + insert_before(range, text) + end + + ## + # @api private + # @deprecated Use insert_after or wrap + # + def insert_after_multi(range, text) + self.class.warn_of_deprecation + insert_after(range, text) + end + + DEPRECATION_WARNING = [ + 'TreeRewriter#insert_before_multi and insert_before_multi exist only for legacy compatibility.', + 'Please update your code to use `wrap`, `insert_before` or `insert_after` instead.' + ].join("\n").freeze + + extend Deprecation + + protected + + attr_reader :action_root + + private + + def action_summary + replacements = as_replacements + case replacements.size + when 0 then return 'empty' + when 1..3 then #ok + else + replacements = replacements.first(3) + suffix = '…' + end + parts = replacements.map do |(range, str)| + if str.empty? # is this a deletion? + "-#{range.to_range}" + elsif range.size == 0 # is this an insertion? + "+#{str.inspect}@#{range.begin_pos}" + else # it is a replacement + "^#{str.inspect}@#{range.to_range}" + end + end + parts << suffix if suffix + parts.join(', ') + end + + ACTIONS = %i[accept warn raise].freeze + def check_policy_validity + invalid = @policy.values - ACTIONS + raise ArgumentError, "Invalid policy: #{invalid.join(', ')}" unless invalid.empty? + end + + def combine(range, attributes) + range = check_range_validity(range) + action = TreeRewriter::Action.new(range, @enforcer, **attributes) + @action_root = @action_root.combine(action) + self + end + + def check_range_validity(range) + if range.begin_pos < 0 || range.end_pos > @source_buffer.source.size + raise IndexError, "The range #{range.to_range} is outside the bounds of the source" + end + range + end + + def enforce_policy(event) + return if @policy[event] == :accept + return unless (values = yield) + trigger_policy(event, **values) + end + + POLICY_TO_LEVEL = {warn: :warning, raise: :error}.freeze + def trigger_policy(event, range: raise, conflict: nil, **arguments) + action = @policy[event] || :raise + diag = Parser::Diagnostic.new(POLICY_TO_LEVEL[action], event, arguments, range) + @diagnostics.process(diag) + if conflict + range, *highlights = conflict + diag = Parser::Diagnostic.new(POLICY_TO_LEVEL[action], :"#{event}_conflict", arguments, range, highlights) + @diagnostics.process(diag) + end + raise Parser::ClobberingError, "Parser::Source::TreeRewriter detected clobbering" if action == :raise + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/tree_rewriter/action.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/tree_rewriter/action.rb new file mode 100644 index 00000000..27002b57 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/source/tree_rewriter/action.rb @@ -0,0 +1,243 @@ +# frozen_string_literal: true + +module Parser + module Source + ## + # @api private + # + # Actions are arranged in a tree and get combined so that: + # + # * Children are strictly contained by their parent + # * Siblings are all disjointed from one another and ordered + # * Only actions with `replacement == nil` may have children + # + class TreeRewriter::Action + attr_reader :range, :replacement, :insert_before, :insert_after + + def initialize(range, enforcer, + insert_before: '', + replacement: nil, + insert_after: '', + children: [] + ) + @range, @enforcer, @children, @insert_before, @replacement, @insert_after = + range, enforcer, children.freeze, insert_before.freeze, replacement, insert_after.freeze + + freeze + end + + def combine(action) + return self if action.empty? # Ignore empty action + do_combine(action) + end + + def empty? + @insert_before.empty? && + @insert_after.empty? && + @children.empty? && + (@replacement == nil || (@replacement.empty? && @range.empty?)) + end + + def ordered_replacements + reps = [] + reps << [@range.begin, @insert_before] unless @insert_before.empty? + reps << [@range, @replacement] if @replacement + reps.concat(@children.flat_map(&:ordered_replacements)) + reps << [@range.end, @insert_after] unless @insert_after.empty? + reps + end + + def nested_actions + actions = [] + actions << [:wrap, @range, @insert_before, @insert_after] if !@insert_before.empty? || + !@insert_after.empty? + actions << [:replace, @range, @replacement] if @replacement + actions.concat(@children.flat_map(&:nested_actions)) + end + + def insertion? + !insert_before.empty? || !insert_after.empty? || (replacement && !replacement.empty?) + end + + ## + # A root action has its range set to the whole source range, even + # though it typically does not act on that range. + # This method returns the action as if it was a child action with + # its range contracted. + # @return [Action] + def contract + raise 'Empty actions can not be contracted' if empty? + return self if insertion? + range = @range.with( + begin_pos: children.first.range.begin_pos, + end_pos: children.last.range.end_pos, + ) + with(range: range) + end + + ## + # @return [Action] that has been moved to the given source_buffer and with the given offset + # No check is done on validity of resulting range. + def moved(source_buffer, offset) + moved_range = ::Parser::Source::Range.new( + source_buffer, + @range.begin_pos + offset, + @range.end_pos + offset + ) + with( + range: moved_range, + children: children.map { |child| child.moved(source_buffer, offset) } + ) + end + + protected + + attr_reader :children + + def with(range: @range, enforcer: @enforcer, children: @children, insert_before: @insert_before, replacement: @replacement, insert_after: @insert_after) + children = swallow(children) if replacement + self.class.new(range, enforcer, children: children, insert_before: insert_before, replacement: replacement, insert_after: insert_after) + end + + # Assumes range.contains?(action.range) && action.children.empty? + def do_combine(action) + if action.range == @range + merge(action) + else + place_in_hierarchy(action) + end + end + + def place_in_hierarchy(action) + family = analyse_hierarchy(action) + + if family[:fusible] + fuse_deletions(action, family[:fusible], [*family[:sibbling_left], *family[:child], *family[:sibbling_right]]) + else + extra_sibbling = if family[:parent] # action should be a descendant of one of the children + family[:parent].do_combine(action) + elsif family[:child] # or it should become the parent of some of the children, + action.with(children: family[:child], enforcer: @enforcer) + .combine_children(action.children) + else # or else it should become an additional child + action + end + with(children: [*family[:sibbling_left], extra_sibbling, *family[:sibbling_right]]) + end + end + + # Assumes `more_children` all contained within `@range` + def combine_children(more_children) + more_children.inject(self) do |parent, new_child| + parent.place_in_hierarchy(new_child) + end + end + + def fuse_deletions(action, fusible, other_sibblings) + without_fusible = with(children: other_sibblings) + fused_range = [action, *fusible].map(&:range).inject(:join) + fused_deletion = action.with(range: fused_range) + without_fusible.do_combine(fused_deletion) + end + + # Similar to @children.bsearch_index || size + # except allows for a starting point + # and `bsearch_index` is only Ruby 2.3+ + def bsearch_child_index(from = 0) + size = @children.size + (from...size).bsearch { |i| yield @children[i] } || size + end + + # Returns the children in a hierarchy with respect to `action`: + # :sibbling_left, sibbling_right (for those that are disjoint from `action`) + # :parent (in case one of our children contains `action`) + # :child (in case `action` strictly contains some of our children) + # :fusible (in case `action` overlaps some children but they can be fused in one deletion) + # or raises a `CloberingError` + # In case a child has equal range to `action`, it is returned as `:parent` + # Reminder: an empty range 1...1 is considered disjoint from 1...10 + def analyse_hierarchy(action) + r = action.range + # left_index is the index of the first child that isn't completely to the left of action + left_index = bsearch_child_index { |child| child.range.end_pos > r.begin_pos } + # right_index is the index of the first child that is completely on the right of action + start = left_index == 0 ? 0 : left_index - 1 # See "corner case" below for reason of -1 + right_index = bsearch_child_index(start) { |child| child.range.begin_pos >= r.end_pos } + center = right_index - left_index + case center + when 0 + # All children are disjoint from action, nothing else to do + when -1 + # Corner case: if a child has empty range == action's range + # then it will appear to be both disjoint and to the left of action, + # as well as disjoint and to the right of action. + # Since ranges are equal, we return it as parent + left_index -= 1 # Fix indices, as otherwise this child would be + right_index += 1 # considered as a sibbling (both left and right!) + parent = @children[left_index] + else + overlap_left = @children[left_index].range.begin_pos <=> r.begin_pos + overlap_right = @children[right_index-1].range.end_pos <=> r.end_pos + + # For one child to be the parent of action, we must have: + if center == 1 && overlap_left <= 0 && overlap_right >= 0 + parent = @children[left_index] + else + # Otherwise consider all non disjoint elements (center) to be contained... + contained = @children[left_index...right_index] + fusible = check_fusible(action, + (contained.shift if overlap_left < 0), # ... but check first and last one + (contained.pop if overlap_right > 0) # ... for overlaps + ) + end + end + + { + parent: parent, + sibbling_left: @children[0...left_index], + sibbling_right: @children[right_index...@children.size], + fusible: fusible, + child: contained, + } + end + + # @param [Array(Action | nil)] fusible + def check_fusible(action, *fusible) + fusible.compact! + return if fusible.empty? + fusible.each do |child| + kind = action.insertion? || child.insertion? ? :crossing_insertions : :crossing_deletions + @enforcer.call(kind) { {range: action.range, conflict: child.range} } + end + fusible + end + + # Assumes action.range == range && action.children.empty? + def merge(action) + call_enforcer_for_merge(action) + with( + insert_before: "#{action.insert_before}#{insert_before}", + replacement: action.replacement || @replacement, + insert_after: "#{insert_after}#{action.insert_after}", + ).combine_children(action.children) + end + + def call_enforcer_for_merge(action) + @enforcer.call(:different_replacements) do + if @replacement && action.replacement && @replacement != action.replacement + {range: @range, replacement: action.replacement, other_replacement: @replacement} + end + end + end + + def swallow(children) + @enforcer.call(:swallowed_insertions) do + insertions = children.select(&:insertion?) + + {range: @range, conflict: insertions.map(&:range)} unless insertions.empty? + end + [] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/static_environment.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/static_environment.rb new file mode 100644 index 00000000..a3e5537c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/static_environment.rb @@ -0,0 +1,134 @@ +# frozen_string_literal: true + +module Parser + + class StaticEnvironment + FORWARD_ARGS = :FORWARD_ARGS + + ANONYMOUS_RESTARG_IN_CURRENT_SCOPE = :ANONYMOUS_RESTARG_IN_CURRENT_SCOPE + ANONYMOUS_RESTARG_INHERITED = :ANONYMOUS_RESTARG_INHERITED + + ANONYMOUS_KWRESTARG_IN_CURRENT_SCOPE = :ANONYMOUS_KWRESTARG_IN_CURRENT_SCOPE + ANONYMOUS_KWRESTARG_INHERITED = :ANONYMOUS_KWRESTARG_INHERITED + + ANONYMOUS_BLOCKARG_IN_CURRENT_SCOPE = :ANONYMOUS_BLOCKARG_IN_CURRENT_SCOPE + ANONYMOUS_BLOCKARG_INHERITED = :ANONYMOUS_BLOCKARG_INHERITED + + def initialize + reset + end + + def reset + @variables = Set[] + @stack = [] + end + + def extend_static + @stack.push(@variables) + @variables = Set[] + + self + end + + def extend_dynamic + @stack.push(@variables) + @variables = @variables.dup + if @variables.delete(ANONYMOUS_BLOCKARG_IN_CURRENT_SCOPE) + @variables.add(ANONYMOUS_BLOCKARG_INHERITED) + end + if @variables.delete(ANONYMOUS_RESTARG_IN_CURRENT_SCOPE) + @variables.add(ANONYMOUS_RESTARG_INHERITED) + end + if @variables.delete(ANONYMOUS_KWRESTARG_IN_CURRENT_SCOPE) + @variables.add(ANONYMOUS_KWRESTARG_INHERITED) + end + + self + end + + def unextend + @variables = @stack.pop + + self + end + + def declare(name) + @variables.add(name.to_sym) + + self + end + + def declared?(name) + @variables.include?(name.to_sym) + end + + # Forward args + + def declare_forward_args + declare(FORWARD_ARGS) + end + + def declared_forward_args? + declared?(FORWARD_ARGS) + end + + # Anonymous blockarg + + def declare_anonymous_blockarg + declare(ANONYMOUS_BLOCKARG_IN_CURRENT_SCOPE) + end + + def declared_anonymous_blockarg? + declared?(ANONYMOUS_BLOCKARG_IN_CURRENT_SCOPE) || declared?(ANONYMOUS_BLOCKARG_INHERITED) + end + + def declared_anonymous_blockarg_in_current_scpe? + declared?(ANONYMOUS_BLOCKARG_IN_CURRENT_SCOPE) + end + + def parent_has_anonymous_blockarg? + @stack.any? { |variables| variables.include?(ANONYMOUS_BLOCKARG_IN_CURRENT_SCOPE) } + end + + # Anonymous restarg + + def declare_anonymous_restarg + declare(ANONYMOUS_RESTARG_IN_CURRENT_SCOPE) + end + + def declared_anonymous_restarg? + declared?(ANONYMOUS_RESTARG_IN_CURRENT_SCOPE) || declared?(ANONYMOUS_RESTARG_INHERITED) + end + + def declared_anonymous_restarg_in_current_scope? + declared?(ANONYMOUS_RESTARG_IN_CURRENT_SCOPE) + end + + def parent_has_anonymous_restarg? + @stack.any? { |variables| variables.include?(ANONYMOUS_RESTARG_IN_CURRENT_SCOPE) } + end + + # Anonymous kwresarg + + def declare_anonymous_kwrestarg + declare(ANONYMOUS_KWRESTARG_IN_CURRENT_SCOPE) + end + + def declared_anonymous_kwrestarg? + declared?(ANONYMOUS_KWRESTARG_IN_CURRENT_SCOPE) || declared?(ANONYMOUS_KWRESTARG_INHERITED) + end + + def declared_anonymous_kwrestarg_in_current_scope? + declared?(ANONYMOUS_KWRESTARG_IN_CURRENT_SCOPE) + end + + def parent_has_anonymous_kwrestarg? + @stack.any? { |variables| variables.include?(ANONYMOUS_KWRESTARG_IN_CURRENT_SCOPE) } + end + + def empty? + @stack.empty? + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/syntax_error.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/syntax_error.rb new file mode 100644 index 00000000..0ac867de --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/syntax_error.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Parser + ## + # {Parser::SyntaxError} is raised whenever parser detects a syntax error, + # similar to the standard SyntaxError class. + # + # @api public + # + # @!attribute [r] diagnostic + # @return [Parser::Diagnostic] + # + class SyntaxError < StandardError + attr_reader :diagnostic + + def initialize(diagnostic) + @diagnostic = diagnostic + super(diagnostic.message) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/tree_rewriter.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/tree_rewriter.rb new file mode 100644 index 00000000..a84d882b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/tree_rewriter.rb @@ -0,0 +1,133 @@ +# frozen_string_literal: true + +module Parser + + ## + # {Parser::TreeRewriter} offers a basic API that makes it easy to rewrite + # existing ASTs. It's built on top of {Parser::AST::Processor} and + # {Parser::Source::TreeRewriter} + # + # For example, assume you want to remove `do` tokens from a while statement. + # You can do this as following: + # + # require 'parser/current' + # + # class RemoveDo < Parser::TreeRewriter + # def on_while(node) + # # Check if the statement starts with "do" + # if node.location.begin.is?('do') + # remove(node.location.begin) + # end + # end + # end + # + # code = <<-EOF + # while true do + # puts 'hello' + # end + # EOF + # + # ast = Parser::CurrentRuby.parse code + # buffer = Parser::Source::Buffer.new('(example)', source: code) + # rewriter = RemoveDo.new + # + # # Rewrite the AST, returns a String with the new form. + # puts rewriter.rewrite(buffer, ast) + # + # This would result in the following Ruby code: + # + # while true + # puts 'hello' + # end + # + # Keep in mind that {Parser::TreeRewriter} does not take care of indentation when + # inserting/replacing code so you'll have to do this yourself. + # + # See also [a blog entry](http://whitequark.org/blog/2013/04/26/lets-play-with-ruby-code/) + # describing rewriters in greater detail. + # + # @api public + # + class TreeRewriter < Parser::AST::Processor + ## + # Rewrites the AST/source buffer and returns a String containing the new + # version. + # + # @param [Parser::Source::Buffer] source_buffer + # @param [Parser::AST::Node] ast + # @param [Symbol] crossing_deletions:, different_replacements:, swallowed_insertions: + # policy arguments for TreeRewriter (optional) + # @return [String] + # + def rewrite(source_buffer, + ast, + **policy) + @source_rewriter = Parser::Source::TreeRewriter.new(source_buffer, **policy) + + process(ast) + + @source_rewriter.process + end + + ## + # Returns `true` if the specified node is an assignment node, returns false + # otherwise. + # + # @param [Parser::AST::Node] node + # @return [Boolean] + # + def assignment?(node) + [:lvasgn, :ivasgn, :gvasgn, :cvasgn, :casgn].include?(node.type) + end + + ## + # Removes the source range. + # + # @param [Parser::Source::Range] range + # + def remove(range) + @source_rewriter.remove(range) + end + + ## + # Wraps the given source range with the given values. + # + # @param [Parser::Source::Range] range + # @param [String] content + # + def wrap(range, before, after) + @source_rewriter.wrap(range, before, after) + end + + ## + # Inserts new code before the given source range. + # + # @param [Parser::Source::Range] range + # @param [String] content + # + def insert_before(range, content) + @source_rewriter.insert_before(range, content) + end + + ## + # Inserts new code after the given source range. + # + # @param [Parser::Source::Range] range + # @param [String] content + # + def insert_after(range, content) + @source_rewriter.insert_after(range, content) + end + + ## + # Replaces the code of the source range `range` with `content`. + # + # @param [Parser::Source::Range] range + # @param [String] content + # + def replace(range, content) + @source_rewriter.replace(range, content) + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/unknown_encoding_in_magic_comment_error.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/unknown_encoding_in_magic_comment_error.rb new file mode 100644 index 00000000..c29b8290 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/unknown_encoding_in_magic_comment_error.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Parser + ## + # {Parser::UnknownEncodingInMagicComment} is raised when a magic encoding + # comment is encountered that the currently running Ruby version doesn't + # recognize. It inherits from {ArgumentError} since that is the exception + # Ruby itself raises when trying to execute a file with an unknown encoding. + # As such, it is also not a {Parser::SyntaxError}. + # + # @api public + # + class UnknownEncodingInMagicComment < ArgumentError + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/variables_stack.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/variables_stack.rb new file mode 100644 index 00000000..2e27bf42 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/variables_stack.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module Parser + + class VariablesStack + def initialize + @stack = [] + push + end + + def empty? + @stack.empty? + end + + def push + @stack << Set.new + end + + def pop + @stack.pop + end + + def reset + @stack.clear + end + + def declare(name) + @stack.last << name.to_sym + end + + def declared?(name) + @stack.last.include?(name.to_sym) + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/version.rb b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/version.rb new file mode 100644 index 00000000..f56663fc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/lib/parser/version.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +module Parser + VERSION = '3.3.8.0' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/parser.gemspec b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/parser.gemspec new file mode 100644 index 00000000..3c5bd3ec --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/parser-3.3.8.0/parser.gemspec @@ -0,0 +1,43 @@ +# encoding: utf-8 +# frozen_string_literal: true + +require File.expand_path('../lib/parser/version', __FILE__) + +Gem::Specification.new do |spec| + spec.name = 'parser' + spec.version = Parser::VERSION + spec.authors = ['whitequark'] + spec.email = ['whitequark@whitequark.org'] + spec.description = 'A Ruby parser written in pure Ruby.' + spec.summary = spec.description + spec.homepage = 'https://github.com/whitequark/parser' + spec.license = 'MIT' + + spec.metadata = { + 'bug_tracker_uri' => 'https://github.com/whitequark/parser/issues', + 'changelog_uri' => "https://github.com/whitequark/parser/blob/v#{spec.version}/CHANGELOG.md", + 'documentation_uri' => "https://www.rubydoc.info/gems/parser/#{spec.version}", + 'source_code_uri' => "https://github.com/whitequark/parser/tree/v#{spec.version}" + } + + spec.files = Dir['bin/*', 'lib/**/*.rb', 'parser.gemspec', 'LICENSE.txt'] + spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } + spec.require_paths = ['lib'] + + spec.required_ruby_version = '>= 2.0.0' + + spec.add_dependency 'ast', '~> 2.4.1' + spec.add_dependency 'racc' + + spec.add_development_dependency 'bundler', '>= 1.15', '< 3.0.0' + spec.add_development_dependency 'rake', '~> 13.0.1' + spec.add_development_dependency 'cliver', '~> 0.3.2' + + spec.add_development_dependency 'yard' + spec.add_development_dependency 'kramdown' + + spec.add_development_dependency 'minitest', '~> 5.10' + spec.add_development_dependency 'simplecov', '~> 0.15.1' + + spec.add_development_dependency 'gauntlet' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/pp-0.6.2/BSDL b/vendor/bundle/ruby/3.4.0/gems/pp-0.6.2/BSDL new file mode 100644 index 00000000..66d93598 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/pp-0.6.2/BSDL @@ -0,0 +1,22 @@ +Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/vendor/bundle/ruby/3.4.0/gems/pp-0.6.2/COPYING b/vendor/bundle/ruby/3.4.0/gems/pp-0.6.2/COPYING new file mode 100644 index 00000000..48e5a96d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/pp-0.6.2/COPYING @@ -0,0 +1,56 @@ +Ruby is copyrighted free software by Yukihiro Matsumoto . +You can redistribute it and/or modify it under either the terms of the +2-clause BSDL (see the file BSDL), or the conditions below: + +1. You may make and give away verbatim copies of the source form of the + software without restriction, provided that you duplicate all of the + original copyright notices and associated disclaimers. + +2. You may modify your copy of the software in any way, provided that + you do at least ONE of the following: + + a. place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said + modifications to Usenet or an equivalent medium, or by allowing + the author to include your modifications in the software. + + b. use the modified software only within your corporation or + organization. + + c. give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d. make other distribution arrangements with the author. + +3. You may distribute the software in object code or binary form, + provided that you do at least ONE of the following: + + a. distribute the binaries and library files of the software, + together with instructions (in the manual page or equivalent) + on where to get the original distribution. + + b. accompany the distribution with the machine-readable source of + the software. + + c. give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d. make other distribution arrangements with the author. + +4. You may modify and include the part of the software into any other + software (possibly commercial). But some files in the distribution + are not written by the author, so that they are not under these terms. + + For the list of those files and their copying conditions, see the + file LEGAL. + +5. The scripts and library files supplied as input to or produced as + output from the software do not automatically fall under the + copyright of the software, but belong to whomever generated them, + and may be sold commercially, and may be aggregated with this + software. + +6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. diff --git a/vendor/bundle/ruby/3.4.0/gems/pp-0.6.2/lib/pp.rb b/vendor/bundle/ruby/3.4.0/gems/pp-0.6.2/lib/pp.rb new file mode 100644 index 00000000..b8e69e64 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/pp-0.6.2/lib/pp.rb @@ -0,0 +1,699 @@ +# frozen_string_literal: true + +require 'prettyprint' + +## +# A pretty-printer for Ruby objects. +# +## +# == What PP Does +# +# Standard output by #p returns this: +# #, @group_queue=#], []]>, @buffer=[], @newline="\n", @group_stack=[#], @buffer_width=0, @indent=0, @maxwidth=79, @output_width=2, @output=#> +# +# Pretty-printed output returns this: +# #, +# @group_queue= +# #], +# []]>, +# @group_stack= +# [#], +# @indent=0, +# @maxwidth=79, +# @newline="\n", +# @output=#, +# @output_width=2> +# +## +# == Usage +# +# pp(obj) #=> obj +# pp obj #=> obj +# pp(obj1, obj2, ...) #=> [obj1, obj2, ...] +# pp() #=> nil +# +# Output obj(s) to $> in pretty printed format. +# +# It returns obj(s). +# +## +# == Output Customization +# +# To define a customized pretty printing function for your classes, +# redefine method #pretty_print(pp) in the class. +# Note that require 'pp' is needed before redefining #pretty_print(pp). +# +# #pretty_print takes the +pp+ argument, which is an instance of the PP class. +# The method uses #text, #breakable, #nest, #group and #pp to print the +# object. +# +## +# == Pretty-Print JSON +# +# To pretty-print JSON refer to JSON#pretty_generate. +# +## +# == Author +# Tanaka Akira + +class PP < PrettyPrint + + # The version string + VERSION = "0.6.2" + + # Returns the usable width for +out+. + # As the width of +out+: + # 1. If +out+ is assigned to a tty device, its width is used. + # 2. Otherwise, or it could not get the value, the +COLUMN+ + # environment variable is assumed to be set to the width. + # 3. If +COLUMN+ is not set to a non-zero number, 80 is assumed. + # + # And finally, returns the above width value - 1. + # * This -1 is for Windows command prompt, which moves the cursor to + # the next line if it reaches the last column. + def PP.width_for(out) + begin + require 'io/console' + _, width = out.winsize + rescue LoadError, NoMethodError, SystemCallError + end + (width || ENV['COLUMNS']&.to_i&.nonzero? || 80) - 1 + end + + # Outputs +obj+ to +out+ in pretty printed format of + # +width+ columns in width. + # + # If +out+ is omitted, $> is assumed. + # If +width+ is omitted, the width of +out+ is assumed (see + # width_for). + # + # PP.pp returns +out+. + def PP.pp(obj, out=$>, width=width_for(out)) + q = new(out, width) + q.guard_inspect_key {q.pp obj} + q.flush + #$pp = q + out << "\n" + end + + # Outputs +obj+ to +out+ like PP.pp but with no indent and + # newline. + # + # PP.singleline_pp returns +out+. + def PP.singleline_pp(obj, out=$>) + q = SingleLine.new(out) + q.guard_inspect_key {q.pp obj} + q.flush + out + end + + # :stopdoc: + def PP.mcall(obj, mod, meth, *args, &block) + mod.instance_method(meth).bind_call(obj, *args, &block) + end + # :startdoc: + + if defined? ::Ractor + class << self + # Returns the sharing detection flag as a boolean value. + # It is false (nil) by default. + def sharing_detection + Ractor.current[:pp_sharing_detection] + end + # Sets the sharing detection flag to b. + def sharing_detection=(b) + Ractor.current[:pp_sharing_detection] = b + end + end + else + @sharing_detection = false + class << self + # Returns the sharing detection flag as a boolean value. + # It is false by default. + attr_accessor :sharing_detection + end + end + + # Module that defines helper methods for pretty_print. + module PPMethods + + # Yields to a block + # and preserves the previous set of objects being printed. + def guard_inspect_key + if Thread.current[:__recursive_key__] == nil + Thread.current[:__recursive_key__] = {}.compare_by_identity + end + + if Thread.current[:__recursive_key__][:inspect] == nil + Thread.current[:__recursive_key__][:inspect] = {}.compare_by_identity + end + + save = Thread.current[:__recursive_key__][:inspect] + + begin + Thread.current[:__recursive_key__][:inspect] = {}.compare_by_identity + yield + ensure + Thread.current[:__recursive_key__][:inspect] = save + end + end + + # Check whether the object_id +id+ is in the current buffer of objects + # to be pretty printed. Used to break cycles in chains of objects to be + # pretty printed. + def check_inspect_key(id) + Thread.current[:__recursive_key__] && + Thread.current[:__recursive_key__][:inspect] && + Thread.current[:__recursive_key__][:inspect].include?(id) + end + + # Adds the object_id +id+ to the set of objects being pretty printed, so + # as to not repeat objects. + def push_inspect_key(id) + Thread.current[:__recursive_key__][:inspect][id] = true + end + + # Removes an object from the set of objects being pretty printed. + def pop_inspect_key(id) + Thread.current[:__recursive_key__][:inspect].delete id + end + + # Adds +obj+ to the pretty printing buffer + # using Object#pretty_print or Object#pretty_print_cycle. + # + # Object#pretty_print_cycle is used when +obj+ is already + # printed, a.k.a the object reference chain has a cycle. + def pp(obj) + # If obj is a Delegator then use the object being delegated to for cycle + # detection + obj = obj.__getobj__ if defined?(::Delegator) and ::Delegator === obj + + if check_inspect_key(obj) + group {obj.pretty_print_cycle self} + return + end + + begin + push_inspect_key(obj) + group do + obj.pretty_print self + rescue NoMethodError + text Kernel.instance_method(:inspect).bind_call(obj) + end + ensure + pop_inspect_key(obj) unless PP.sharing_detection + end + end + + # A convenience method which is same as follows: + # + # group(1, '#<' + obj.class.name, '>') { ... } + def object_group(obj, &block) # :yield: + group(1, '#<' + obj.class.name, '>', &block) + end + + # A convenience method, like object_group, but also reformats the Object's + # object_id. + def object_address_group(obj, &block) + str = Kernel.instance_method(:to_s).bind_call(obj) + str.chomp!('>') + group(1, str, '>', &block) + end + + # A convenience method which is same as follows: + # + # text ',' + # breakable + def comma_breakable + text ',' + breakable + end + + # Adds a separated list. + # The list is separated by comma with breakable space, by default. + # + # #seplist iterates the +list+ using +iter_method+. + # It yields each object to the block given for #seplist. + # The procedure +separator_proc+ is called between each yields. + # + # If the iteration is zero times, +separator_proc+ is not called at all. + # + # If +separator_proc+ is nil or not given, + # +lambda { comma_breakable }+ is used. + # If +iter_method+ is not given, :each is used. + # + # For example, following 3 code fragments has similar effect. + # + # q.seplist([1,2,3]) {|v| xxx v } + # + # q.seplist([1,2,3], lambda { q.comma_breakable }, :each) {|v| xxx v } + # + # xxx 1 + # q.comma_breakable + # xxx 2 + # q.comma_breakable + # xxx 3 + def seplist(list, sep=nil, iter_method=:each) # :yield: element + sep ||= lambda { comma_breakable } + first = true + list.__send__(iter_method) {|*v| + if first + first = false + else + sep.call + end + RUBY_VERSION >= "3.0" ? yield(*v, **{}) : yield(*v) + } + end + + # A present standard failsafe for pretty printing any given Object + def pp_object(obj) + object_address_group(obj) { + seplist(obj.pretty_print_instance_variables, lambda { text ',' }) {|v| + breakable + v = v.to_s if Symbol === v + text v + text '=' + group(1) { + breakable '' + pp(obj.instance_eval(v)) + } + } + } + end + + # A pretty print for a Hash + def pp_hash(obj) + group(1, '{', '}') { + seplist(obj, nil, :each_pair) {|k, v| + group { + pp_hash_pair k, v + } + } + } + end + + if RUBY_VERSION >= '3.4.' + # A pretty print for a pair of Hash + def pp_hash_pair(k, v) + if Symbol === k + sym_s = k.inspect + if sym_s[1].match?(/["$@!]/) || sym_s[-1].match?(/[%&*+\-\/<=>@\]^`|~]/) + text "#{k.to_s.inspect}:" + else + text "#{k}:" + end + else + pp k + text ' ' + text '=>' + end + group(1) { + breakable + pp v + } + end + else + def pp_hash_pair(k, v) + pp k + text '=>' + group(1) { + breakable '' + pp v + } + end + end + end + + include PPMethods + + class SingleLine < PrettyPrint::SingleLine # :nodoc: + include PPMethods + end + + module ObjectMixin # :nodoc: + # 1. specific pretty_print + # 2. specific inspect + # 3. generic pretty_print + + # A default pretty printing method for general objects. + # It calls #pretty_print_instance_variables to list instance variables. + # + # If +self+ has a customized (redefined) #inspect method, + # the result of self.inspect is used but it obviously has no + # line break hints. + # + # This module provides predefined #pretty_print methods for some of + # the most commonly used built-in classes for convenience. + def pretty_print(q) + umethod_method = Object.instance_method(:method) + begin + inspect_method = umethod_method.bind_call(self, :inspect) + rescue NameError + end + if inspect_method && inspect_method.owner != Kernel + q.text self.inspect + elsif !inspect_method && self.respond_to?(:inspect) + q.text self.inspect + else + q.pp_object(self) + end + end + + # A default pretty printing method for general objects that are + # detected as part of a cycle. + def pretty_print_cycle(q) + q.object_address_group(self) { + q.breakable + q.text '...' + } + end + + # Returns a sorted array of instance variable names. + # + # This method should return an array of names of instance variables as symbols or strings as: + # +[:@a, :@b]+. + def pretty_print_instance_variables + instance_variables.sort + end + + # Is #inspect implementation using #pretty_print. + # If you implement #pretty_print, it can be used as follows. + # + # alias inspect pretty_print_inspect + # + # However, doing this requires that every class that #inspect is called on + # implement #pretty_print, or a RuntimeError will be raised. + def pretty_print_inspect + if Object.instance_method(:method).bind_call(self, :pretty_print).owner == PP::ObjectMixin + raise "pretty_print is not overridden for #{self.class}" + end + PP.singleline_pp(self, ''.dup) + end + end +end + +class Array # :nodoc: + def pretty_print(q) # :nodoc: + q.group(1, '[', ']') { + q.seplist(self) {|v| + q.pp v + } + } + end + + def pretty_print_cycle(q) # :nodoc: + q.text(empty? ? '[]' : '[...]') + end +end + +class Hash # :nodoc: + def pretty_print(q) # :nodoc: + q.pp_hash self + end + + def pretty_print_cycle(q) # :nodoc: + q.text(empty? ? '{}' : '{...}') + end +end + +class << ENV # :nodoc: + def pretty_print(q) # :nodoc: + h = {} + ENV.keys.sort.each {|k| + h[k] = ENV[k] + } + q.pp_hash h + end +end + +class Struct # :nodoc: + def pretty_print(q) # :nodoc: + q.group(1, sprintf("#') { + q.seplist(PP.mcall(self, Struct, :members), lambda { q.text "," }) {|member| + q.breakable + q.text member.to_s + q.text '=' + q.group(1) { + q.breakable '' + q.pp self[member] + } + } + } + end + + def pretty_print_cycle(q) # :nodoc: + q.text sprintf("#", PP.mcall(self, Kernel, :class).name) + end +end + +class Data # :nodoc: + def pretty_print(q) # :nodoc: + class_name = PP.mcall(self, Kernel, :class).name + class_name = " #{class_name}" if class_name + q.group(1, "#') { + + members = PP.mcall(self, Kernel, :class).members + values = [] + members.select! do |member| + begin + values << __send__(member) + true + rescue NoMethodError + false + end + end + + q.seplist(members.zip(values), lambda { q.text "," }) {|(member, value)| + q.breakable + q.text member.to_s + q.text '=' + q.group(1) { + q.breakable '' + q.pp value + } + } + } + end + + def pretty_print_cycle(q) # :nodoc: + q.text sprintf("#", PP.mcall(self, Kernel, :class).name) + end +end if defined?(Data.define) + +class Range # :nodoc: + def pretty_print(q) # :nodoc: + begin_nil = self.begin == nil + end_nil = self.end == nil + q.pp self.begin if !begin_nil || end_nil + q.breakable '' + q.text(self.exclude_end? ? '...' : '..') + q.breakable '' + q.pp self.end if !end_nil || begin_nil + end +end + +class String # :nodoc: + def pretty_print(q) # :nodoc: + lines = self.lines + if lines.size > 1 + q.group(0, '', '') do + q.seplist(lines, lambda { q.text ' +'; q.breakable }) do |v| + q.pp v + end + end + else + q.text inspect + end + end +end + +class File < IO # :nodoc: + class Stat # :nodoc: + def pretty_print(q) # :nodoc: + require 'etc' + q.object_group(self) { + q.breakable + q.text sprintf("dev=0x%x", self.dev); q.comma_breakable + q.text "ino="; q.pp self.ino; q.comma_breakable + q.group { + m = self.mode + q.text sprintf("mode=0%o", m) + q.breakable + q.text sprintf("(%s %c%c%c%c%c%c%c%c%c)", + self.ftype, + (m & 0400 == 0 ? ?- : ?r), + (m & 0200 == 0 ? ?- : ?w), + (m & 0100 == 0 ? (m & 04000 == 0 ? ?- : ?S) : + (m & 04000 == 0 ? ?x : ?s)), + (m & 0040 == 0 ? ?- : ?r), + (m & 0020 == 0 ? ?- : ?w), + (m & 0010 == 0 ? (m & 02000 == 0 ? ?- : ?S) : + (m & 02000 == 0 ? ?x : ?s)), + (m & 0004 == 0 ? ?- : ?r), + (m & 0002 == 0 ? ?- : ?w), + (m & 0001 == 0 ? (m & 01000 == 0 ? ?- : ?T) : + (m & 01000 == 0 ? ?x : ?t))) + } + q.comma_breakable + q.text "nlink="; q.pp self.nlink; q.comma_breakable + q.group { + q.text "uid="; q.pp self.uid + begin + pw = Etc.getpwuid(self.uid) + rescue ArgumentError + end + if pw + q.breakable; q.text "(#{pw.name})" + end + } + q.comma_breakable + q.group { + q.text "gid="; q.pp self.gid + begin + gr = Etc.getgrgid(self.gid) + rescue ArgumentError + end + if gr + q.breakable; q.text "(#{gr.name})" + end + } + q.comma_breakable + q.group { + q.text sprintf("rdev=0x%x", self.rdev) + if self.rdev_major && self.rdev_minor + q.breakable + q.text sprintf('(%d, %d)', self.rdev_major, self.rdev_minor) + end + } + q.comma_breakable + q.text "size="; q.pp self.size; q.comma_breakable + q.text "blksize="; q.pp self.blksize; q.comma_breakable + q.text "blocks="; q.pp self.blocks; q.comma_breakable + q.group { + t = self.atime + q.text "atime="; q.pp t + q.breakable; q.text "(#{t.tv_sec})" + } + q.comma_breakable + q.group { + t = self.mtime + q.text "mtime="; q.pp t + q.breakable; q.text "(#{t.tv_sec})" + } + q.comma_breakable + q.group { + t = self.ctime + q.text "ctime="; q.pp t + q.breakable; q.text "(#{t.tv_sec})" + } + } + end + end +end + +class MatchData # :nodoc: + def pretty_print(q) # :nodoc: + nc = [] + self.regexp.named_captures.each {|name, indexes| + indexes.each {|i| nc[i] = name } + } + q.object_group(self) { + q.breakable + q.seplist(0...self.size, lambda { q.breakable }) {|i| + if i == 0 + q.pp self[i] + else + if nc[i] + q.text nc[i] + else + q.pp i + end + q.text ':' + q.pp self[i] + end + } + } + end +end + +if defined?(RubyVM::AbstractSyntaxTree) + class RubyVM::AbstractSyntaxTree::Node # :nodoc: + def pretty_print_children(q, names = []) + children.zip(names) do |c, n| + if n + q.breakable + q.text "#{n}:" + end + q.group(2) do + q.breakable + q.pp c + end + end + end + + def pretty_print(q) + q.group(1, "(#{type}@#{first_lineno}:#{first_column}-#{last_lineno}:#{last_column}", ")") { + case type + when :SCOPE + pretty_print_children(q, %w"tbl args body") + when :ARGS + pretty_print_children(q, %w[pre_num pre_init opt first_post post_num post_init rest kw kwrest block]) + when :DEFN + pretty_print_children(q, %w[mid body]) + when :ARYPTN + pretty_print_children(q, %w[const pre rest post]) + when :HSHPTN + pretty_print_children(q, %w[const kw kwrest]) + else + pretty_print_children(q) + end + } + end + end +end + +class Object < BasicObject # :nodoc: + include PP::ObjectMixin +end + +[Numeric, Symbol, FalseClass, TrueClass, NilClass, Module].each {|c| + c.class_eval { + def pretty_print_cycle(q) + q.text inspect + end + } +} + +[Numeric, FalseClass, TrueClass, Module].each {|c| + c.class_eval { + def pretty_print(q) + q.text inspect + end + } +} + +module Kernel + # Returns a pretty printed object as a string. + # + # See the PP module for more information. + def pretty_inspect + PP.pp(self, ''.dup) + end + + # prints arguments in pretty form. + # + # +#pp+ returns argument(s). + def pp(*objs) + objs.each {|obj| + PP.pp(obj) + } + objs.size <= 1 ? objs.first : objs + end + module_function :pp +end diff --git a/vendor/bundle/ruby/3.4.0/gems/pp-0.6.2/pp.gemspec b/vendor/bundle/ruby/3.4.0/gems/pp-0.6.2/pp.gemspec new file mode 100644 index 00000000..15a3b4dc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/pp-0.6.2/pp.gemspec @@ -0,0 +1,35 @@ +name = File.basename(__FILE__, ".gemspec") +version = ["lib", Array.new(name.count("-")+1).join("/")].find do |dir| + break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line| + /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1 + end rescue nil +end + +Gem::Specification.new do |spec| + spec.name = name + spec.version = version + spec.authors = ["Tanaka Akira"] + spec.email = ["akr@fsij.org"] + + spec.summary = %q{Provides a PrettyPrinter for Ruby objects} + spec.description = %q{Provides a PrettyPrinter for Ruby objects} + spec.homepage = "https://github.com/ruby/pp" + spec.licenses = ["Ruby", "BSD-2-Clause"] + + spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0") + + spec.metadata["homepage_uri"] = spec.homepage + spec.metadata["source_code_uri"] = spec.homepage + + spec.files = %w[ + BSDL + COPYING + lib/pp.rb + pp.gemspec + ] + spec.bindir = "exe" + spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } + spec.require_paths = ["lib"] + + spec.add_dependency "prettyprint" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/.github/dependabot.yml b/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/.github/dependabot.yml new file mode 100644 index 00000000..b18fd293 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: 'github-actions' + directory: '/' + schedule: + interval: 'weekly' diff --git a/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/.github/workflows/test.yml b/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/.github/workflows/test.yml new file mode 100644 index 00000000..e9f0a6dc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/.github/workflows/test.yml @@ -0,0 +1,41 @@ +name: test + +on: + push: + pull_request: + schedule: + - cron: '15 3 * * *' + +jobs: + ruby-versions: + uses: ruby/actions/.github/workflows/ruby_versions.yml@master + with: + engine: cruby + min_version: 2.5 + + test: + needs: ruby-versions + strategy: + matrix: + ruby: ${{ fromJson(needs.ruby-versions.outputs.versions) }} + os: [ ubuntu-latest, macos-latest, windows-latest ] + exclude: + - { os: windows-latest , ruby: head } + include: + - { os: windows-latest , ruby: mingw } + - { os: windows-latest , ruby: mswin } + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + - name: Install dependencies + run: bundle install + - name: Build + run: rake build + - name: Run test + run: rake test + - name: Installation test + run: gem install pkg/*.gem diff --git a/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/.gitignore b/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/.gitignore new file mode 100644 index 00000000..9106b2a3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/.gitignore @@ -0,0 +1,8 @@ +/.bundle/ +/.yardoc +/_yardoc/ +/coverage/ +/doc/ +/pkg/ +/spec/reports/ +/tmp/ diff --git a/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/Gemfile b/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/Gemfile new file mode 100644 index 00000000..eb861920 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/Gemfile @@ -0,0 +1,4 @@ +source "https://rubygems.org" + +gem "rake" +gem "test-unit" diff --git a/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/LICENSE.txt b/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/LICENSE.txt new file mode 100644 index 00000000..a009caef --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/README.md b/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/README.md new file mode 100644 index 00000000..7ee82768 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/README.md @@ -0,0 +1,43 @@ +# PrettyPrint + +This class implements a pretty printing algorithm. It finds line breaks and +nice indentations for grouped structure. + +By default, the class assumes that primitive elements are strings and each +byte in the strings have single column in width. But it can be used for +other situations by giving suitable arguments for some methods: + +* newline object and space generation block for PrettyPrint.new +* optional width argument for PrettyPrint#text +* PrettyPrint#breakable + +There are several candidate uses: + +* text formatting using proportional fonts +* multibyte characters which has columns different to number of bytes + +## Installation + +Add this line to your application's Gemfile: + +```ruby +gem 'prettyprint' +``` + +And then execute: + + $ bundle install + +Or install it yourself as: + + $ gem install prettyprint + +## Development + +After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. + +To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org). + +## Contributing + +Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/prettyprint. diff --git a/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/Rakefile b/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/Rakefile new file mode 100644 index 00000000..30baabd9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/Rakefile @@ -0,0 +1,10 @@ +require "bundler/gem_tasks" +require "rake/testtask" + +Rake::TestTask.new(:test) do |t| + t.libs << "test" + t.libs << "lib" + t.test_files = FileList["test/**/test_*.rb"] +end + +task :default => :test diff --git a/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/bin/console b/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/bin/console new file mode 100755 index 00000000..5afa2833 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/bin/console @@ -0,0 +1,14 @@ +#!/usr/bin/env ruby + +require "bundler/setup" +require "prettyprint" + +# You can add fixtures and/or initialization code here to make experimenting +# with your gem easier. You can also use a different console, if you like. + +# (If you use this, don't forget to add pry to your Gemfile!) +# require "pry" +# Pry.start + +require "irb" +IRB.start(__FILE__) diff --git a/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/bin/setup b/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/bin/setup new file mode 100755 index 00000000..dce67d86 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/bin/setup @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -euo pipefail +IFS=$'\n\t' +set -vx + +bundle install + +# Do any other automated setup that you need to do here diff --git a/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/lib/prettyprint.rb b/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/lib/prettyprint.rb new file mode 100644 index 00000000..6f50192f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/lib/prettyprint.rb @@ -0,0 +1,558 @@ +# frozen_string_literal: true +# +# This class implements a pretty printing algorithm. It finds line breaks and +# nice indentations for grouped structure. +# +# By default, the class assumes that primitive elements are strings and each +# byte in the strings have single column in width. But it can be used for +# other situations by giving suitable arguments for some methods: +# * newline object and space generation block for PrettyPrint.new +# * optional width argument for PrettyPrint#text +# * PrettyPrint#breakable +# +# There are several candidate uses: +# * text formatting using proportional fonts +# * multibyte characters which has columns different to number of bytes +# * non-string formatting +# +# == Bugs +# * Box based formatting? +# * Other (better) model/algorithm? +# +# Report any bugs at http://bugs.ruby-lang.org +# +# == References +# Christian Lindig, Strictly Pretty, March 2000, +# https://lindig.github.io/papers/strictly-pretty-2000.pdf +# +# Philip Wadler, A prettier printer, March 1998, +# https://homepages.inf.ed.ac.uk/wadler/topics/language-design.html#prettier +# +# == Author +# Tanaka Akira +# +class PrettyPrint + + VERSION = "0.2.0" + + # This is a convenience method which is same as follows: + # + # begin + # q = PrettyPrint.new(output, maxwidth, newline, &genspace) + # ... + # q.flush + # output + # end + # + def PrettyPrint.format(output=''.dup, maxwidth=79, newline="\n", genspace=lambda {|n| ' ' * n}) + q = PrettyPrint.new(output, maxwidth, newline, &genspace) + yield q + q.flush + output + end + + # This is similar to PrettyPrint::format but the result has no breaks. + # + # +maxwidth+, +newline+ and +genspace+ are ignored. + # + # The invocation of +breakable+ in the block doesn't break a line and is + # treated as just an invocation of +text+. + # + def PrettyPrint.singleline_format(output=''.dup, maxwidth=nil, newline=nil, genspace=nil) + q = SingleLine.new(output) + yield q + output + end + + # Creates a buffer for pretty printing. + # + # +output+ is an output target. If it is not specified, '' is assumed. It + # should have a << method which accepts the first argument +obj+ of + # PrettyPrint#text, the first argument +sep+ of PrettyPrint#breakable, the + # first argument +newline+ of PrettyPrint.new, and the result of a given + # block for PrettyPrint.new. + # + # +maxwidth+ specifies maximum line length. If it is not specified, 79 is + # assumed. However actual outputs may overflow +maxwidth+ if long + # non-breakable texts are provided. + # + # +newline+ is used for line breaks. "\n" is used if it is not specified. + # + # The block is used to generate spaces. {|width| ' ' * width} is used if it + # is not given. + # + def initialize(output=''.dup, maxwidth=79, newline="\n", &genspace) + @output = output + @maxwidth = maxwidth + @newline = newline + @genspace = genspace || lambda {|n| ' ' * n} + + @output_width = 0 + @buffer_width = 0 + @buffer = [] + + root_group = Group.new(0) + @group_stack = [root_group] + @group_queue = GroupQueue.new(root_group) + @indent = 0 + end + + # The output object. + # + # This defaults to '', and should accept the << method + attr_reader :output + + # The maximum width of a line, before it is separated in to a newline + # + # This defaults to 79, and should be an Integer + attr_reader :maxwidth + + # The value that is appended to +output+ to add a new line. + # + # This defaults to "\n", and should be String + attr_reader :newline + + # A lambda or Proc, that takes one argument, of an Integer, and returns + # the corresponding number of spaces. + # + # By default this is: + # lambda {|n| ' ' * n} + attr_reader :genspace + + # The number of spaces to be indented + attr_reader :indent + + # The PrettyPrint::GroupQueue of groups in stack to be pretty printed + attr_reader :group_queue + + # Returns the group most recently added to the stack. + # + # Contrived example: + # out = "" + # => "" + # q = PrettyPrint.new(out) + # => #, @output_width=0, @buffer_width=0, @buffer=[], @group_stack=[#], @group_queue=#]]>, @indent=0> + # q.group { + # q.text q.current_group.inspect + # q.text q.newline + # q.group(q.current_group.depth + 1) { + # q.text q.current_group.inspect + # q.text q.newline + # q.group(q.current_group.depth + 1) { + # q.text q.current_group.inspect + # q.text q.newline + # q.group(q.current_group.depth + 1) { + # q.text q.current_group.inspect + # q.text q.newline + # } + # } + # } + # } + # => 284 + # puts out + # # + # # + # # + # # + def current_group + @group_stack.last + end + + # Breaks the buffer into lines that are shorter than #maxwidth + def break_outmost_groups + while @maxwidth < @output_width + @buffer_width + return unless group = @group_queue.deq + until group.breakables.empty? + data = @buffer.shift + @output_width = data.output(@output, @output_width) + @buffer_width -= data.width + end + while !@buffer.empty? && Text === @buffer.first + text = @buffer.shift + @output_width = text.output(@output, @output_width) + @buffer_width -= text.width + end + end + end + + # This adds +obj+ as a text of +width+ columns in width. + # + # If +width+ is not specified, obj.length is used. + # + def text(obj, width=obj.length) + if @buffer.empty? + @output << obj + @output_width += width + else + text = @buffer.last + unless Text === text + text = Text.new + @buffer << text + end + text.add(obj, width) + @buffer_width += width + break_outmost_groups + end + end + + # This is similar to #breakable except + # the decision to break or not is determined individually. + # + # Two #fill_breakable under a group may cause 4 results: + # (break,break), (break,non-break), (non-break,break), (non-break,non-break). + # This is different to #breakable because two #breakable under a group + # may cause 2 results: + # (break,break), (non-break,non-break). + # + # The text +sep+ is inserted if a line is not broken at this point. + # + # If +sep+ is not specified, " " is used. + # + # If +width+ is not specified, +sep.length+ is used. You will have to + # specify this when +sep+ is a multibyte character, for example. + # + def fill_breakable(sep=' ', width=sep.length) + group { breakable sep, width } + end + + # This says "you can break a line here if necessary", and a +width+\-column + # text +sep+ is inserted if a line is not broken at the point. + # + # If +sep+ is not specified, " " is used. + # + # If +width+ is not specified, +sep.length+ is used. You will have to + # specify this when +sep+ is a multibyte character, for example. + # + def breakable(sep=' ', width=sep.length) + group = @group_stack.last + if group.break? + flush + @output << @newline + @output << @genspace.call(@indent) + @output_width = @indent + @buffer_width = 0 + else + @buffer << Breakable.new(sep, width, self) + @buffer_width += width + break_outmost_groups + end + end + + # Groups line break hints added in the block. The line break hints are all + # to be used or not. + # + # If +indent+ is specified, the method call is regarded as nested by + # nest(indent) { ... }. + # + # If +open_obj+ is specified, text open_obj, open_width is called + # before grouping. If +close_obj+ is specified, text close_obj, + # close_width is called after grouping. + # + def group(indent=0, open_obj='', close_obj='', open_width=open_obj.length, close_width=close_obj.length) + text open_obj, open_width + group_sub { + nest(indent) { + yield + } + } + text close_obj, close_width + end + + # Takes a block and queues a new group that is indented 1 level further. + def group_sub + group = Group.new(@group_stack.last.depth + 1) + @group_stack.push group + @group_queue.enq group + begin + yield + ensure + @group_stack.pop + if group.breakables.empty? + @group_queue.delete group + end + end + end + + # Increases left margin after newline with +indent+ for line breaks added in + # the block. + # + def nest(indent) + @indent += indent + begin + yield + ensure + @indent -= indent + end + end + + # outputs buffered data. + # + def flush + @buffer.each {|data| + @output_width = data.output(@output, @output_width) + } + @buffer.clear + @buffer_width = 0 + end + + # The Text class is the means by which to collect strings from objects. + # + # This class is intended for internal use of the PrettyPrint buffers. + class Text # :nodoc: + + # Creates a new text object. + # + # This constructor takes no arguments. + # + # The workflow is to append a PrettyPrint::Text object to the buffer, and + # being able to call the buffer.last() to reference it. + # + # As there are objects, use PrettyPrint::Text#add to include the objects + # and the width to utilized by the String version of this object. + def initialize + @objs = [] + @width = 0 + end + + # The total width of the objects included in this Text object. + attr_reader :width + + # Render the String text of the objects that have been added to this Text object. + # + # Output the text to +out+, and increment the width to +output_width+ + def output(out, output_width) + @objs.each {|obj| out << obj} + output_width + @width + end + + # Include +obj+ in the objects to be pretty printed, and increment + # this Text object's total width by +width+ + def add(obj, width) + @objs << obj + @width += width + end + end + + # The Breakable class is used for breaking up object information + # + # This class is intended for internal use of the PrettyPrint buffers. + class Breakable # :nodoc: + + # Create a new Breakable object. + # + # Arguments: + # * +sep+ String of the separator + # * +width+ Integer width of the +sep+ + # * +q+ parent PrettyPrint object, to base from + def initialize(sep, width, q) + @obj = sep + @width = width + @pp = q + @indent = q.indent + @group = q.current_group + @group.breakables.push self + end + + # Holds the separator String + # + # The +sep+ argument from ::new + attr_reader :obj + + # The width of +obj+ / +sep+ + attr_reader :width + + # The number of spaces to indent. + # + # This is inferred from +q+ within PrettyPrint, passed in ::new + attr_reader :indent + + # Render the String text of the objects that have been added to this + # Breakable object. + # + # Output the text to +out+, and increment the width to +output_width+ + def output(out, output_width) + @group.breakables.shift + if @group.break? + out << @pp.newline + out << @pp.genspace.call(@indent) + @indent + else + @pp.group_queue.delete @group if @group.breakables.empty? + out << @obj + output_width + @width + end + end + end + + # The Group class is used for making indentation easier. + # + # While this class does neither the breaking into newlines nor indentation, + # it is used in a stack (as well as a queue) within PrettyPrint, to group + # objects. + # + # For information on using groups, see PrettyPrint#group + # + # This class is intended for internal use of the PrettyPrint buffers. + class Group # :nodoc: + # Create a Group object + # + # Arguments: + # * +depth+ - this group's relation to previous groups + def initialize(depth) + @depth = depth + @breakables = [] + @break = false + end + + # This group's relation to previous groups + attr_reader :depth + + # Array to hold the Breakable objects for this Group + attr_reader :breakables + + # Makes a break for this Group, and returns true + def break + @break = true + end + + # Boolean of whether this Group has made a break + def break? + @break + end + + # Boolean of whether this Group has been queried for being first + # + # This is used as a predicate, and ought to be called first. + def first? + if defined? @first + false + else + @first = false + true + end + end + end + + # The GroupQueue class is used for managing the queue of Group to be pretty + # printed. + # + # This queue groups the Group objects, based on their depth. + # + # This class is intended for internal use of the PrettyPrint buffers. + class GroupQueue # :nodoc: + # Create a GroupQueue object + # + # Arguments: + # * +groups+ - one or more PrettyPrint::Group objects + def initialize(*groups) + @queue = [] + groups.each {|g| enq g} + end + + # Enqueue +group+ + # + # This does not strictly append the group to the end of the queue, + # but instead adds it in line, base on the +group.depth+ + def enq(group) + depth = group.depth + @queue << [] until depth < @queue.length + @queue[depth] << group + end + + # Returns the outer group of the queue + def deq + @queue.each {|gs| + (gs.length-1).downto(0) {|i| + unless gs[i].breakables.empty? + group = gs.slice!(i, 1).first + group.break + return group + end + } + gs.each {|group| group.break} + gs.clear + } + return nil + end + + # Remote +group+ from this queue + def delete(group) + @queue[group.depth].delete(group) + end + end + + # PrettyPrint::SingleLine is used by PrettyPrint.singleline_format + # + # It is passed to be similar to a PrettyPrint object itself, by responding to: + # * #text + # * #breakable + # * #nest + # * #group + # * #flush + # * #first? + # + # but instead, the output has no line breaks + # + class SingleLine + # Create a PrettyPrint::SingleLine object + # + # Arguments: + # * +output+ - String (or similar) to store rendered text. Needs to respond to '<<' + # * +maxwidth+ - Argument position expected to be here for compatibility. + # This argument is a noop. + # * +newline+ - Argument position expected to be here for compatibility. + # This argument is a noop. + def initialize(output, maxwidth=nil, newline=nil) + @output = output + @first = [true] + end + + # Add +obj+ to the text to be output. + # + # +width+ argument is here for compatibility. It is a noop argument. + def text(obj, width=nil) + @output << obj + end + + # Appends +sep+ to the text to be output. By default +sep+ is ' ' + # + # +width+ argument is here for compatibility. It is a noop argument. + def breakable(sep=' ', width=nil) + @output << sep + end + + # Takes +indent+ arg, but does nothing with it. + # + # Yields to a block. + def nest(indent) # :nodoc: + yield + end + + # Opens a block for grouping objects to be pretty printed. + # + # Arguments: + # * +indent+ - noop argument. Present for compatibility. + # * +open_obj+ - text appended before the &blok. Default is '' + # * +close_obj+ - text appended after the &blok. Default is '' + # * +open_width+ - noop argument. Present for compatibility. + # * +close_width+ - noop argument. Present for compatibility. + def group(indent=nil, open_obj='', close_obj='', open_width=nil, close_width=nil) + @first.push true + @output << open_obj + yield + @output << close_obj + @first.pop + end + + # Method present for compatibility, but is a noop + def flush # :nodoc: + end + + # This is used as a predicate, and ought to be called first. + def first? + result = @first[-1] + @first[-1] = false + result + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/prettyprint.gemspec b/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/prettyprint.gemspec new file mode 100644 index 00000000..a18adb17 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prettyprint-0.2.0/prettyprint.gemspec @@ -0,0 +1,29 @@ +name = File.basename(__FILE__, ".gemspec") +version = ["lib", Array.new(name.count("-")+1).join("/")].find do |dir| + break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line| + /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1 + end rescue nil +end + +Gem::Specification.new do |spec| + spec.name = name + spec.version = version + spec.authors = ["Tanaka Akira"] + spec.email = ["akr@fsij.org"] + + spec.summary = %q{Implements a pretty printing algorithm for readable structure.} + spec.description = %q{Implements a pretty printing algorithm for readable structure.} + spec.homepage = "https://github.com/ruby/prettyprint" + spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0") + spec.licenses = ["Ruby", "BSD-2-Clause"] + + spec.metadata["homepage_uri"] = spec.homepage + spec.metadata["source_code_uri"] = spec.homepage + + spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do + `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } + end + spec.bindir = "exe" + spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } + spec.require_paths = ["lib"] +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/BSDmakefile b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/BSDmakefile new file mode 100644 index 00000000..13174f8f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/BSDmakefile @@ -0,0 +1,58 @@ +# GNU makefile proxy script for BSD make +# +# Written and maintained by Mahmoud Al-Qudsi +# Copyright NeoSmart Technologies 2014-2019 +# Obtain updates from +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +JARG = +GMAKE = "gmake" +# When gmake is called from another make instance, -w is automatically added +# which causes extraneous messages about directory changes to be emitted. +# Running with --no-print-directory silences these messages. +GARGS = "--no-print-directory" + +.if "$(.MAKE.JOBS)" != "" + JARG = -j$(.MAKE.JOBS) +.endif + +# bmake prefers out-of-source builds and tries to cd into ./obj (among others) +# where possible. GNU Make doesn't, so override that value. +.OBJDIR: ./ + +# The GNU convention is to use the lowercased `prefix` variable/macro to +# specify the installation directory. Humor them. +GPREFIX = "" +.if defined(PREFIX) && ! defined(prefix) + GPREFIX = 'prefix = "$(PREFIX)"' +.endif + +.BEGIN: .SILENT + which $(GMAKE) || printf "Error: GNU Make is required!\n\n" 1>&2 && false + +.PHONY: FRC +$(.TARGETS): FRC + $(GMAKE) $(GPREFIX) $(GARGS) $(.TARGETS:S,.DONE,,) $(JARG) + +.DONE .DEFAULT: .SILENT + $(GMAKE) $(GPREFIX) $(GARGS) $(.TARGETS:S,.DONE,,) $(JARG) diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/CHANGELOG.md b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/CHANGELOG.md new file mode 100644 index 00000000..aa17d500 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/CHANGELOG.md @@ -0,0 +1,684 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [1.4.0] - 2025-03-18 + +### Added + +- Support `3.5` as a version option. +- Many, many compatibility fixes for the parser translation layer. +- Handle escapes in named capture names. +- The `freeze` option is added to the various `Prism::` APIs to deeply freeze the AST. +- Properly support `it` for the parser and ruby_parser translation layers. +- Track the `then` keyword on `rescue` nodes. +- Add a `multiple_statements?` flag to parentheses nodes to support desired `defined?` behavior. + +### Changed + +- The strings used in the AST are now frozen. +- Fixed handling escaped characters after control sequences in character literals. +- Fix reading off the end of an unterminated global variable. +- Raise a syntax error for defining `[]=` with endless method syntax. +- Increase value of `PRISM_DEPTH_MAXIMUM` to `10000`. +- Freeze `Prism::VERSION`. +- Fix up rescue modifier precedence. + +## [1.3.0] - 2024-12-21 + +### Added + +- Introduce `Prism::StringQuery`. +- Introduce `Prism::Relocation`. +- Track `do` keyword for `WhileNode` and `UntilNode`. +- Change the way the gem is built to rely on `mkmf` instead of `make`. +- Lots more documentation on node fields. + +### Changed + +- Properly add an error for `def @foo; end`. +- Properly add an error for `foo(**, *)`. +- Fix up regression in string parsing in `RubyParser` translation. +- Reject invalid dot method call after match expression. +- Reject invalid operator after match expression. +- Fix up %-literals delimited by newlines. +- Properly add an error for `-> { _1; -> { _1 } }`. +- Reject blocks and keywords in index writes. + +## [1.2.0] - 2024-10-10 + +### Added + +- Introduce `Prism::CodeUnitsCache`. + +### Changed + +- Properly handle lexing global variables that begin with `$-`. +- Properly reject invalid multi writes within parentheses. +- Fix unary `*` binding power. +- Set `contains_keywords` flag for implicit `gets` calls when `-p` is used. +- Properly reject invalid non-associative operator patterns. +- Do not warn about unused variables declared on negative lines. + +## [1.1.0] - 2024-10-02 + +### Added + +- Explicitly type each child node field in the Ruby API. +- Add the `main_script` option to the parse APIs, which controls whether or not shebangs are considered. +- Add the `partial_script` options to the parse APIs, which controls whether or not jumps that would otherwise be considered invalid are allowed. This is useful for parsing things like ERB sources, where you know it will be evaluated in a different context. Note that this functionality is replacing the previous idiom of passing in a list of scopes to indicate an `eval` context, because that behavior has changed upstream in `ruby/ruby`. +- Add `ArgumentsNode#contains_multiple_splats?`. +- Add `ArgumentsNode#contains_forwarding?`. +- Accept all valid Ruby versions for the `version` option on parse APIs. +- Accept version shorthands like `"3.3"` and `"3.4"` for the `version` option on parse APIs. +- Support a max depth to protect against malicious payloads without hitting the stack limit. + +### Changed + +- Fix some token incompatibilities in the `parser` translation. +- Fix up parsing tempfiles on Windows. +- Fix up handling UTF-8 characters in file paths on Windows. +- Do not warn for a `\r` at the end of a shebang on Windows. +- Properly handle erroring for parsing a directory on Windows. +- When a numbered reference is out of range, warn instead of raise. +- Allow returns in default parameter values. +- Reject many more invalid syntax patterns. + +## [1.0.0] - 2024-08-28 + +### Added + +- Add `Node#breadth_first_search`. +- Add `Node#node_id`. +- Add `ArgumentsNode#contains_splat?`. +- Passing the special value `false` for the `encoding` option tells Prism to ignore magic encoding comments. +- Expose flags on every node type (allows checking static literal and newline). +- Implement mismatched indentation warning. +- Add C API for receiving a callback when parsing shebangs with additional flags. + +### Changed + +- **BREAKING**: Some fields are renamed that had illogical names. The previous names all now emit deprecation warnings. + - `CaseMatchNode#consequent` was renamed to `CaseMatchNode#else_clause` + - `CaseNode#consequent` was renamed to `CaseNode#else_clause` + - `IfNode#consequent` was renamed to `IfNode#subsequent` + - `RescueNode#consequent` was renamed to `RescueNode#subsequent` + - `UnlessNode#consequent` was renamed to `UnlessNode#else_clause` +- Block exits are now allowed in loop predicates (e.g., `while _ && break do end`). +- Multi-writes are now disallowed when not at the statement level. +- Ensure that range operators are non-associative. +- (JavaScript) Correctly deserialize encoded strings. +- Properly support parsing regular expressions in extended mode. +- Use gmake on FreeBSD. +- Parsing streams now handles NUL bytes in the middle of the stream. +- Properly detect invalid returns. + +## [0.30.0] - 2024-06-07 + +### Added + +- More correctly raise mixed encoding errors. +- Implement ambiguous binary operator warning. +- Fix up regexp escapes with control and meta characters. +- Fix up support for the `it` implicit local variable. +- Heredoc identifiers now properly disallow CLRF. +- Errors added for void value expressions in begin clauses. +- Many updates to more closely match the `parser` gem in parser translation. +- Many errors added for invalid regular expressions. + +### Changed + +- Handle parser translation missing the `parser` gem. +- Handle ruby_parser translation missing the `ruby_parser` gem. +- Various error messages have been updated to more closely match CRuby. +- `RationalNode` now has a `numerator` and `denominator` field instead of a `numeric` field. For the Ruby API we provide a `RationalNode#numeric` method for backwards-compatibility. + +## [0.29.0] - 2024-05-10 + +### Added + +- Added `Prism::CallNode#full_message_loc`, which gives the location including the `=` if there is one. +- A warning for when `# shareable_constant_value` is not used on its own line. +- An error for invalid implicit local variable writes. +- Implicit hash patterns in array patterns are disallowed. +- We now validate that Unicode escape sequences are not surrogates. + +### Changed + +- All fields named `operator` have been renamed to `binary_operator` for `*OperatorWriteNode` nodes. This is to make it easier to provide C++ support. In the Ruby API, the old fields are aliased to the new fields with a deprecation warning. +- Many updated error messages to more closely match CRuby. +- We ensure keyword parameters do not end in `!` or `?`. +- Fixed some escaping in string literals with control sequences and hex escapes. +- Fix a bug with RBS types when used outside the `ruby/prism` codebase. + +## [0.28.0] - 2024-05-03 + +### Added + +- Nested hashes will now warn for duplicated keys, as in: `{ foo: 1, **{ foo: 2 } }`. +- `Prism::ReturnNode` now has a flag on it to indicate if it is redundant. +- `Prism::Location#slice_lines` and `Prism::Node#slice_lines` are now provided to slice the source code of a node including the content before the node on the same line that it starts on and the content after the node on the same line that it ends on. +- Symbols with invalid byte sequences now give errors. +- You can now pass `"3.3.1"` to the `version:` parameter on all `Prism.*` APIs. +- `Prism::Source#lines`, `Prism::Location#source_lines`, `Prism::Node#source_lines`, and `Prism::Node#script_lines` are now provided, which will all return the source code of the source as an array of strings. +- `Prism::ASCIISource` is now provided, which is a subclass of `Prism::Source` but specialized to increase performance when the source is entirely ASCII. +- Prism now provides errors when parsing Ruby 3.4+ syntax for index expressions with keywords or blocks. +- Prism now provides an error when `**nil` is used after other keyword parameters. +- Prism now provides errors when safe navigation is used in call target expressions, e.g., `foo&.bar, = 1`. +- `Prism::Node#tunnel` is now provided, which returns an array of nodes starting at the current node that contain a given line and column. + +### Changed + +- All translation layers now assume an eval context, which means they will not return errors for invalid jumps like `yield`. +- `Prism::Node#inspect` now uses a queue instead of recursion to avoid stack overflows. +- Prism now more closely mirrors CRuby interpolation semantics, which means you could potentially have a static literal string that directly interpolates another static literal string. +- The shipped RBI sorbet types no longer use generics. +- `Prism::ConstantPathNode#child` and `Prism::ConstantTargetNode#child` are now deprecated, replaced by two new fields on these nodes: `name` and `name_loc`. + +## [0.27.0] - 2024-04-23 + +### Added + +- Implemented `===` for each of the nodes, which will check if equality but ignore the specific ranges of locations. + +### Changed + +- Fix translation of `ItParametersNode` for parser translation. +- Fix translation of `dstr` for ruby_parser translation. +- Do not allow omitted hash values whose keys end with `!` or `?`. +- Split up `Prism::ParseResult` into `Prism::Result` with subclasses `Prism::ParseResult`, `Prism::LexResult`, `Prism::ParseLexResult`, and `Prism::LexCompat::Result`. +- Change reflection classes to have only a single `IntegerField` class and rename `DoubleField` to `FloatField`. +- Fall back to default `AR` and `CC` in `Makefile`. +- Use GC-able symbols for the syntax tree to avoid adding to the global symbol table. +- Fix a bug with karatsuba_multiply that would result in a stack overflow. +- Fix parser translation when looking for tokens with `srange_find`. + +## [0.26.0] - 2024-04-18 + +### Added + +- Add `Prism::Node::fields`, which returns a list of `Prism::Reflection::Field` objects representing the fields of the node class. This is useful in metaprogramming contexts. +- `Prism::Location#chop`, for removing the last byte from a location. +- The void statement warning is now implemented. +- The unreachable statement warning is now implemented. +- A syntax error has been added for block arguments on yields, e.g., `yield(&foo)`. + +### Changed + +- Better fidelity to `parser` when translating heredocs with interpolation. +- Fixed `RBI` and `RBS` types for `Prism::parse_*` signatures. +- Remove some incorrect warnings about unused local variables. +- More closely match CRuby error messages for global variables. +- Fix an issue with `parser` translation when line continuations are found in string literals. + +## [0.25.0] - 2024-04-05 + +### Added + +- `Prism::Translation::Ripper` is now able to mirror all of the Ripper APIs. +- `Prism::Location#leading_comments` and `Prism::Location#trailing_comments` is added. +- `Prism::Comment#slice` is added. +- Warn for writing literal values in conditional predicates. +- Check for `_POSIX_MAPPED_FILES` before using `mmap`. +- `Prism::ItParametersNode` is added, to support `-> { it }`. +- Parse integer and float literal values onto the tree. +- Warn on duplicated hash keys and duplicated when clauses. +- Ship much improved `RBI` and `RBS` types. +- Support for the `-p`, `-n`, `-a`, and `-l` command line switches. +- Warn on integer literals in flip-flops. +- Support BSD make. +- Add `Prism::WhenNode#then_keyword_loc`. +- Support custom allocation functions through the `PRISM_XALLOCATOR` define. +- Warn for certain keywrods at the end of the line. +- Provide `pm_visit_node`, a C visitor API. +- `Prism::parse_stream` is added, which works for any Ruby `IO` object. +- Provide flags for regular expression literals for their derived encoding. +- Provide flags for whether or not an interpolated string literal is frozen. +- Add `Prism::StringNode.mutable?` for when a string is explicitly mutable, to support delineating chilled strings. +- Warn for incorrect character literal syntax. +- Warn for chained comparison operators. +- Warn for `**` interpreted as an argument prefix. +- Warn for `&` interpreted as an argument prefix. +- `Prism::ShareableConstantNode` added to support ractors. +- Warn for frozen string literals found after tokens. +- Support `PRISM_BUILD_MINIMAL` to provide only the minimal necessary functionality to reduce the binary size. +- Handle CLRF inside heredocs, strings, and regular expressions. +- Mark inner strings in interpolated strings as frozen. +- Support the `-x` command line switch. +- Error messages now much more closely mirror CRuby. +- Provide syntax errors for invalid block exits (`break`, `next`, `retry`, and `yield`). +- Warn on unused local variables. +- Do not syntax error on default parameter values that only write to the parameter. + +### Changed + +- Many improvements to the compatibility with the `whitequark/parser` translation. +- Accept newlines before pattern terminators `)` or `]`. +- `Prism::Node#start_offset` and `Prism::Node#end_offset` are now much more efficient. +- Read files using `fread` instead of `mmap` when we're going to keep around the source through the Ruby API. +- Fix `Sexp#line_max` setting in the `seattlerb/ruby_parser` translation layer. +- Allow spaces before the encoding comment. + +## [0.24.0] - 2024-02-15 + +### Added + +- More support for `Prism::Translation::Ripper` is added. +- Support multiple versions for `Prism::Translation::Parser`. +- Improved memory usage in the FFI backend. +- Very large speed and memory improvements for creating the Ruby AST. + +### Changed + +- Fix location for empty symbol in hash key. +- Fix parsing a rescue modifier on the value of an assignment when the LHS is a method call with arguments and no parentheses. + +## [0.23.0] - 2024-02-14 + +### Added + +- More support for `Prism::RipperCompat` is added. +- A significantly faster offset cache for `Prism::Translation::Parser` is added for files with multibyte characters. +- `Prism::Translation::RubyParser` is added. +- `Prism::ConstantPathTarget#full_name` is added. +- `version: "3.4.0"` is added as an option that is an alias for `version: "latest"`. +- Four new APIs are added to `Prism::Location`: + - `Prism::Location#start_code_units_offset` + - `Prism::Location#end_code_units_offset` + - `Prism::Location#start_code_units_column` + - `Prism::Location#end_code_units_column` +- Invalid multibyte characters are now validated within strings, lists, and heredocs. + +### Changed + +- When defining `def !@`, the `name_loc` was previously only pointing to `!`, but now includes the `@`. The `name` is the same. +- `Prism::RipperCompat` has been moved to `Prism::Translation::Ripper`. +- Many of the error messages that prism produces have been changed to match the error messages that CRuby produces. + +## [0.22.0] - 2024-02-07 + +### Added + +- More support for `Prism::RipperCompat` is added. +- Support for Ruby 2.7 has been added, and the minimum Ruby requirement has been lowered to 2.7. + +### Changed + +- The error for an invalid source encoding has a new `:argument` level to indicate it raises an argument error. +- `BeginNode` nodes that are used when a class, singleton class, module, method definition, or block have an inline `rescue`/`ensure`/`else` now have their opening locations set to the beginning of the respective keyword. +- Improved error messages for invalid characters. +- `Prism.parse_file` and similar APIs will raise more appropriate errors when the file does not exist or cannot be mapped. +- Correctly handle the `recover` parameter for `Prism::Translation::Parser`. + +## [0.21.0] - 2024-02-05 + +### Added + +- Add the `pm_constant_pool_find` API for finding a constant. + +### Changed + +- Fixes for `Prism::Translation::Parser`. + - Ensure all errors flow through `parser.diagnostics.process`. + - Fix the find pattern node. + - Fix block forwarding with `NumberedParametersNode`. + - Ensure we can parse strings with invalid bytes for the encoding. + - Fix hash pairs in pattern matching. +- Properly reject operator writes on operator calls, e.g., `a.+ -= b`. +- Fix multi-byte escapes. +- Handle missing body in `begin` within the receiver of a method call. + +## [0.20.0] - 2024-02-01 + +### Added + +- String literal hash keys are now marked as frozen as static literal. +- `IndexTargetNode` now always has the `ATTRIBUTE_WRITE` flag. +- `Call*Node` nodes now have an `IGNORE_VISIBILITY` flag. +- We now support the `it` default parameter. +- Errors and warnings now have levels associated with them. +- Symbols now have correct encoding flags. +- We have now merged `parser-prism` in, which provides translation to the `whitequark/parser` AST. +- We now emit errors for invalid method definition receivers. + +### Changed + +- We now emit errors on invalid pinned local variables. +- When passed scopes, it is now assumed that the innermost scope is the current binding. +- We now provide better error recovery for non terminated heredocs. +- Fix for `RationalNode#value` for non-decimal integers. +- Unary symbols `!@` and `~@` now unescape to `!` and `~`, respectively. +- `frozen_string_literal: false` now works properly. + +### Removed + +- We've removed the `locals_body_index` field. +- We've removed the `verbose` option on the various parse APIs. Warnings are now always emitted with their associated level so that consumers can decide how to handle them. + +## [0.19.0] - 2023-12-14 + +### Added + +- `ArrayNode` now has a `contains_splat?` flag if it has a splatted element in it. +- All of the remaining encodings have been implemented. +- Allow forwarding `&` in a method that has a `...` parameter. +- Many statements that are found in non-statement positions are being properly rejected now. +- Void values are now properly checked. +- Referencing a parameter in its own default value is now properly rejected. +- `DATA`/`__END__` is now parsed as its own field on parse result (`data_loc`) as opposed to as a comment. +- Blank `*` now properly forwards into arrays. +- `ImplicitRestNode` is introduced to represent the implicit rest of a destructure. +- We now support negative start lines. +- `StringNode#heredoc?`, `InterpolatedStringNode#heredoc?`, `XStringNode#heredoc?`, and `InterpolatedXStringNode#heredoc?` are introduced. +- `NumberedParametersNode` is introduced to represent the implicit set of parameters when numbered parameters are used. +- `Prism::parse_success?` and `Prism::parse_failure?` are introduced to bypass reifying the AST. +- We now emit a warning for constant assignments in method definitions. +- We now provide flags on strings and xstrings to indicate the correct encoding. +- The hash pattern `rest` field now more accurately parses `**` and `**nil`. +- The equality operators are now properly parsed as non-associative. + +### Changed + +- **BREAKING**: Many fields have changed positions within their nodes. This impacts the C API and the Ruby API if you are manually creating nodes through the initializer. +- **BREAKING**: Almost all of the error messages have been updated to begin with lowercase characters to match ruby/spec. +- Unterminated strings with only plain content are now always `StringNode` as opposed to `InterpolatedStringNode` +- **BREAKING**: Call node has been split up when it is in the target position into `CallTargetNode` and `IndexTargetNode`. + +## [0.18.0] - 2023-11-21 + +### Added + +- The `ParametersNode#signature` method is added, which returns the same thing as `Method#parameters`. +- Visitor functionality has been added to the JavaScript API. +- The `Node#to_dot` API has been added to convert syntax trees to Graphviz digraphs. +- `IfNode` and `UnlessNode` now have a `then_keyword_loc` field. +- Many more encodings are now supported. +- Some new `Location` APIs have been added for dealing with characters instead of bytes, which are: `start_character_offset`, `end_character_offset`, `start_character_column`, and `end_character_column`. +- A warning has been added for when `END {}` is used within a method. +- `ConstantPathNode#full_name{,_parts}` will now raise an error if the receiver of the constant path is not itself a constant. +- The `in` keyword and the `=>` operator now respect non-associativity. +- The `..` and `...` operators now properly respect non-associativity. + +### Changed + +- Previously `...` in blocks was accepted, but it is now properly rejected. +- **BREAKING**: `librubyparser.*` has been renamed to `libprism.*` in the C API. +- We now properly reject floats with exponent and rational suffixes. +- We now properly reject void value expressions. +- **BREAKING**: The `--disable-static` option has been removed from the C extension. +- The rescue modifier keyword is now properly parsed in terms of precedence. +- We now properly reject defining a numbered parameter method. +- **BREAKING**: `MatchWriteNode` now has a list of `targets`, which are local variable target nodes. This is instead of `locals` which was a constant list. This is to support writing to local variables outside the current scope. It has the added benefit of providing location information for the local variable targets. +- **BREAKING**: `CaseNode` has been split into `CaseNode` and `CaseMatchNode`, the latter is used for `case ... in` expressions. +- **BREAKING**: `StringConcatNode` has been removed in favor of using `InterpolatedStringNode` as a list. + +## [0.17.1] - 2023-11-03 + +### Changed + +- Do not use constant nesting in RBI files. + +## [0.17.0] - 2023-11-03 + +### Added + +- We now properly support forwarding arguments into arrays, like `def foo(*) = [*]`. +- We now have much better documentation for the C and Ruby APIs. +- We now properly provide an error message when attempting to assign to numbered parameters from within regular expression named capture groups, as in `/(?<_1>)/ =~ ""`. + +### Changed + +- **BREAKING**: `KeywordParameterNode` is split into `OptionalKeywordParameterNode` and `RequiredKeywordParameterNode`. `RequiredKeywordParameterNode` has no `value` field. +- **BREAKING**: Most of the `Prism::` APIs now accept a bunch of keyword options. The options we now support are: `filepath`, `encoding`, `line`, `frozen_string_literal`, `verbose`, and `scopes`. See [the pull request](https://github.com/ruby/prism/pull/1763) for more details. +- **BREAKING**: Comments are now split into three different classes instead of a single class, and the `type` field has been removed. They are: `InlineComment`, `EmbDocComment`, and `DATAComment`. + +## [0.16.0] - 2023-10-30 + +### Added + +- `InterpolatedMatchLastLineNode#options` and `MatchLastLineNode#options` are added, which are the same methods as are exposed on `InterpolatedRegularExpressionNode` and `RegularExpressionNode`. +- The project can now be compiled with `wasi-sdk` to expose a WebAssembly interface. +- `ArgumentsNode#keyword_splat?` is added to indicate if the arguments node has a keyword splat. +- The C API `pm_prettyprint` has a much improved output which lines up closely with `Node#inspect`. +- Prism now ships with `RBS` and `RBI` type signatures (in the `/sig` and `/rbi` directories, respectively). +- `Prism::parse_comments` and `Prism::parse_file_comments` APIs are added to extract only the comments from the source code. + +### Changed + +- **BREAKING**: `Multi{Target,Write}Node#targets` is split up now into `lefts`, `rest`, and `rights`. This is to avoid having to scan the list in the case that there are splat nodes. +- Some bugs are fixed on `Multi{Target,Write}Node` accidentally creating additional nesting when not necessary. +- **BREAKING**: `RequiredDestructuredParameterNode` has been removed in favor of using `MultiTargetNode` in those places. +- **BREAKING**: `HashPatternNode#assocs` has been renamed to `HashPatternNode#elements`. `HashPatternNode#kwrest` has been renamed to `HashPatternNode#rest`. + +## [0.15.1] - 2023-10-18 + +### Changed + +- Fix compilation warning on assigning to bitfield. + +## [0.15.0] - 2023-10-18 + +### Added + +- `BackReferenceReadNode#name` is now provided. +- `Index{Operator,And,Or}WriteNode` are introduced, split out from `Call{Operator,And,Or}WriteNode` when the method is `[]`. + +### Changed + +- Ensure `PM_NODE_FLAG_COMMON_MASK` into a constant expression to fix compile errors. +- `super(&arg)` is now fixed. +- Ensure the last encoding flag on regular expressions wins. +- Fix the common whitespace calculation when embedded expressions begin on a line. +- Capture groups in regular expressions now scan the unescaped version to get the correct local variables. +- `*` and `&` are added to the local table when `...` is found in the parameters of a method definition. + +## [0.14.0] - 2023-10-13 + +### Added + +- Syntax errors are added for invalid lambda local semicolon placement. +- Lambda locals are now checked for duplicate names. +- Destructured parameters are now checked for duplicate names. +- `Constant{Read,Path,PathTarget}Node#full_name` and `Constant{Read,Path,PathTarget}Node#full_name_parts` are added to walk constant paths for you to find the full name of the constant. +- Syntax errors are added when assigning to a numbered parameter. +- `Node::type` is added, which matches the `Node#type` API. +- Magic comments are now parsed as part of the parsing process and a new field is added in the form of `ParseResult#magic_comments` to access them. + +### Changed + +- **BREAKING**: `Call*Node#name` methods now return symbols instead of strings. +- **BREAKING**: For loops now have their index value considered as part of the body, so depths of local variable assignments will be increased by 1. +- Tilde heredocs now split up their lines into multiple string nodes to make them easier to dedent. + +## [0.13.0] - 2023-09-29 + +### Added + +- `BEGIN {}` blocks are only allowed at the top-level, and will now provide a syntax error if they are not. +- Numbered parameters are not allowed in block parameters, and will now provide a syntax error if they are. +- Many more Ruby modules and classes are now documented. Also, many have been moved into their own files and autoloaded so that initial boot time of the gem is much faster. +- `PM_TOKEN_METHOD_NAME` is introduced, used to indicate an identifier that if definitely a method name because it has an `!` or `?` at the end. +- In the C API, arrays, assocs, and hashes now can have the `PM_NODE_FLAG_STATIC_LITERAL` flag attached if they can be compiled statically. This is used in CRuby, for example, to determine if a `duphash`/`duparray` instruction can be used as opposed to a `newhash`/`newarray`. +- `Node#type` is introduced, which returns a symbol representing the type of the node. This is useful for case comparisons when you have to compare against multiple types. + +### Changed + +- **BREAKING**: Everything has been renamed to `prism` instead of `yarp`. The `yp_`/`YP_` prefix in the C API has been changed to `pm_`/`PM_`. For the most part, everything should be find/replaceable. +- **BREAKING**: `BlockArgumentNode` nodes now go into the `block` field on `CallNode` nodes, in addition to the `BlockNode` nodes that used to be there. Hopefully this makes it more consistent to compile/deal with in general, but it does mean it can be a surprising breaking change. +- Escaped whitespace in `%w` lists is now properly unescaped. +- `Node#pretty_print` now respects pretty print indentation. +- `Dispatcher` was previously firing `_leave` events in the incorrect order. This has now been fixed. +- **BREAKING**: `Visitor` has now been split into `Visitor` and `Compiler`. The visitor visits nodes but doesn't return anything from the visit methods. It is suitable for taking action based on the tree, but not manipulating the tree itself. The `Compiler` visits nodes and returns the computed value up the tree. It is suitable for compiling the tree into another format. As such, `MutationVisitor` has been renamed to `MutationCompiler`. + +## [0.12.0] - 2023-09-15 + +### Added + +- `RegularExpressionNode#options` and `InterpolatedRegularExpressionNode#options` are now provided. These return integers that match up to the `Regexp#options` API. +- Greatly improved `Node#inspect` and `Node#pretty_print` APIs. +- `MatchLastLineNode` and `InterpolatedMatchLastLineNode` are introduced to represent using a regular expression as the predicate of an `if` or `unless` statement. +- `IntegerNode` now has a base flag on it. +- Heredocs that were previously `InterpolatedStringNode` and `InterpolatedXStringNode` nodes without any actual interpolation are now `StringNode` and `XStringNode`, respectively. +- `StringNode` now has a `frozen?` flag on it, which respects the `frozen_string_literal` magic comment. +- Numbered parameters are now supported, and are properly represented using `LocalVariableReadNode` nodes. +- `ImplicitNode` is introduced, which wraps implicit calls, local variable reads, or constant reads in omitted hash values. +- `YARP::Dispatcher` is introduced, which provides a way for multiple objects to listen for certain events on the AST while it is being walked. This is effectively a way to implement a more efficient visitor pattern when you have many different uses for the AST. + +### Changed + +- **BREAKING**: Flags fields are now marked as private, to ensure we can change their implementation under the hood. Actually querying should be through the accessor methods. +- **BREAKING**: `AliasNode` is now split into `AliasMethodNode` and `AliasGlobalVariableNode`. +- Method definitions on local variables is now correctly handled. +- Unary minus precedence has been fixed. +- Concatenating character literals with string literals is now fixed. +- Many more invalid syntaxes are now properly rejected. +- **BREAKING**: Comments now no longer include their trailing newline. + +## [0.11.0] - 2023-09-08 + +### Added + +- `Node#inspect` is much improved. +- `YARP::Pattern` is introduced, which can construct procs to match against nodes. +- `BlockLocalVariableNode` is introduced to take the place of the locations array on `BlockParametersNode`. +- `ParseResult#attach_comments!` is now provided to attach comments to locations in the tree. +- `MultiTargetNode` is introduced as the target of multi writes and for loops. +- `Node#comment_targets` is introduced to return the list of objects that can have attached comments. + +### Changed + +- **BREAKING**: `GlobalVariable*Node#name` now returns a symbol. +- **BREAKING**: `Constant*Node#name` now returns a symbol. +- **BREAKING**: `BlockParameterNode`, `KeywordParameterNode`, `KeywordRestParameterNode`, `RestParameterNode`, `DefNode` all have their `name` methods returning symbols now. +- **BREAKING**: `ClassNode#name` and `ModuleNode#name` now return symbols. +- **BREAKING**: `Location#end_column` is now exclusive instead of inclusive. +- `Location#slice` now returns a properly encoded string. +- `CallNode#operator_loc` is now `CallNode#call_operator_loc`. +- `CallOperatorAndWriteNode` is renamed to `CallAndWriteNode` and its structure has changed. +- `CallOperatorOrWriteNode` is renamed to `CallOrWriteNode` and its structure has changed. + +## [0.10.0] - 2023-09-01 + +### Added + +- `InstanceVariable*Node` and `ClassVariable*Node` objects now have their `name` returning a Symbol. This is because they are now part of the constant pool. +- `NumberedReferenceReadNode` now has a `number` field, which returns an Integer. + +### Changed + +- **BREAKING**: Various `operator_id` and `constant_id` fields have been renamed to `operator` and `name`, respectively. See [09d0a144](https://github.com/ruby/yarp/commit/09d0a144dfd519c5b5f96f0b6ee95d256e2cb1a6) for details. +- `%w`, `%W`, `%i`, `%I`, `%q`, and `%Q` literals can now span around the contents of a heredoc. +- **BREAKING**: All of the public C APIs that accept the source string now accept `const uint8_t *` as opposed to `const char *`. + +## [0.9.0] - 2023-08-25 + +### Added + +- Regular expressions can now be bound by `\n`, `\r`, and a combination of `\r\n`. +- Strings delimited by `%`, `%q`, and `%Q` can now be bound by `\n`, `\r`, and a combination of `\r\n`. +- `IntegerNode#value` now returns the value of the integer as a Ruby `Integer`. +- `FloatNode#value` now returns the value of the float as a Ruby `Float`. +- `RationalNode#value` now returns the value of the rational as a Ruby `Rational`. +- `ImaginaryNode#value` now returns the value of the imaginary as a Ruby `Complex`. +- `ClassNode#name` is now a string that returns the name of just the class, without the namespace. +- `ModuleNode#name` is now a string that returns the name of just the module, without the namespace. +- Regular expressions and strings found after a heredoc declaration but before the heredoc body are now parsed correctly. +- The serialization API now supports shared strings, which should help reduce the size of the serialized AST. +- `*Node#copy` is introduced, which returns a copy of the node with the given overrides. +- `Location#copy` is introduced, which returns a copy of the location with the given overrides. +- `DesugarVisitor` is introduced, which provides a simpler AST for use in tools that want to process fewer node types. +- `{ClassVariable,Constant,ConstantPath,GlobalVariable,InstanceVariable,LocalVariable}TargetNode` are introduced. These nodes represent the target of writes in locations where a value cannot be provided, like a multi write or a rescue reference. +- `UntilNode#closing_loc` and `WhileNode#closing_loc` are now provided. +- `Location#join` is now provided, which joins two locations together. +- `YARP::parse_lex` and `YARP::parse_lex_file` are introduced to parse and lex in one result. + +### Changed + +- When there is a magic encoding comment, the encoding of the first token's source string is now properly reencoded. +- Constants followed by unary `&` are now properly parsed as a call with a passed block argument. +- Escaping multi-byte characters in a string literal will now properly escape the entire character. +- `YARP.lex_compat` now has more accurate behavior when a byte-order mark is present in the file. +- **BREAKING**: `AndWriteNode`, `OrWriteNode`, and `OperatorWriteNode` have been split back up into their `0.7.0` versions. +- We now properly support spaces between the `encoding` and `=`/`:` in a magic encoding comment. +- We now properly parse `-> foo: bar do end`. + +## [0.8.0] - 2023-08-18 + +### Added + +- Some performance improvements when converting from the C AST to the Ruby AST. +- Two rust crates have been added: `yarp-sys` and `yarp`. They are as yet unpublished. + +### Changed + +- Escaped newlines in strings and heredocs are now handled more correctly. +- Dedenting heredocs that result in empty string nodes will now drop those string nodes from the list. +- Beginless and endless ranges in conditional expressions now properly form a flip flop node. +- `%` at the end of files no longer crashes. +- Location information has been corrected for `if/elsif` chains that have no `else`. +- `__END__` at the very end of the file was previously parsed as an identifier, but is now correct. +- **BREAKING**: Nodes that reference `&&=`, `||=`, and other writing operators have been consolidated. Previously, they were separate individual nodes. Now they are a tree with the target being the left-hand side and the value being the right-hand side with a joining `AndWriteNode`, `OrWriteNode`, or `OperatorWriteNode` in the middle. This impacts all of the nodes that match this pattern: `{ClassVariable,Constant,ConstantPath,GlobalVariable,InstanceVariable,LocalVariable}Operator{And,Or,}WriteNode`. +- **BREAKING**: `BlockParametersNode`, `ClassNode`, `DefNode`, `LambdaNode`, `ModuleNode`, `ParenthesesNode`, and `SingletonClassNode` have had their `statements` field renamed to `body` to give a hint that it might not be a `StatementsNode` (it could also be a `BeginNode`). + +## [0.7.0] - 2023-08-14 + +### Added + +- We now have an explicit `FlipFlopNode`. It has the same flags as `RangeNode`. +- We now have a syntax error when implicit and explicit blocks are passed to a method call. +- `Node#slice` is now implemented, for retrieving the slice of the source code corresponding to a node. +- We now support the `utf8-mac` encoding. +- Predicate methods have been added for nodes that have flags. For example `CallNode#safe_navigation?` and `RangeNode#exclude_end?`. +- The gem now functions on JRuby and TruffleRuby, thanks to a new FFI backend. +- Comments are now part of the serialization API. + +### Changed + +- Autotools has been removed from the build system, so when the gem is installed it will no longer need to go through a configure step. +- The AST for `foo = *bar` has changed to have an explicit array on the right hand side, rather than a splat node. This is more consistent with how other parsers handle this. +- **BREAKING**: `RangeNodeFlags` has been renamed to `RangeFlags`. +- Unary minus on number literals is now parsed as part of the literal, rather than a call to a unary operator. This is more consistent with how other parsers handle this. + +## [0.6.0] - 2023-08-09 + +### Added + +- 🎉 Initial release! 🎉 + +[unreleased]: https://github.com/ruby/prism/compare/v1.4.0...HEAD +[1.4.0]: https://github.com/ruby/prism/compare/v1.3.0...v1.4.0 +[1.3.0]: https://github.com/ruby/prism/compare/v1.2.0...v1.3.0 +[1.2.0]: https://github.com/ruby/prism/compare/v1.1.0...v1.2.0 +[1.1.0]: https://github.com/ruby/prism/compare/v1.0.0...v1.1.0 +[1.0.0]: https://github.com/ruby/prism/compare/v0.30.0...v1.0.0 +[0.30.0]: https://github.com/ruby/prism/compare/v0.29.0...v0.30.0 +[0.29.0]: https://github.com/ruby/prism/compare/v0.28.0...v0.29.0 +[0.28.0]: https://github.com/ruby/prism/compare/v0.27.0...v0.28.0 +[0.27.0]: https://github.com/ruby/prism/compare/v0.26.0...v0.27.0 +[0.26.0]: https://github.com/ruby/prism/compare/v0.25.0...v0.26.0 +[0.25.0]: https://github.com/ruby/prism/compare/v0.24.0...v0.25.0 +[0.24.0]: https://github.com/ruby/prism/compare/v0.23.0...v0.24.0 +[0.23.0]: https://github.com/ruby/prism/compare/v0.22.0...v0.23.0 +[0.22.0]: https://github.com/ruby/prism/compare/v0.21.0...v0.22.0 +[0.21.0]: https://github.com/ruby/prism/compare/v0.20.0...v0.21.0 +[0.20.0]: https://github.com/ruby/prism/compare/v0.19.0...v0.20.0 +[0.19.0]: https://github.com/ruby/prism/compare/v0.18.0...v0.19.0 +[0.18.0]: https://github.com/ruby/prism/compare/v0.17.1...v0.18.0 +[0.17.1]: https://github.com/ruby/prism/compare/v0.17.0...v0.17.1 +[0.17.0]: https://github.com/ruby/prism/compare/v0.16.0...v0.17.0 +[0.16.0]: https://github.com/ruby/prism/compare/v0.15.1...v0.16.0 +[0.15.1]: https://github.com/ruby/prism/compare/v0.15.0...v0.15.1 +[0.15.0]: https://github.com/ruby/prism/compare/v0.14.0...v0.15.0 +[0.14.0]: https://github.com/ruby/prism/compare/v0.13.0...v0.14.0 +[0.13.0]: https://github.com/ruby/prism/compare/v0.12.0...v0.13.0 +[0.12.0]: https://github.com/ruby/prism/compare/v0.11.0...v0.12.0 +[0.11.0]: https://github.com/ruby/prism/compare/v0.10.0...v0.11.0 +[0.10.0]: https://github.com/ruby/prism/compare/v0.9.0...v0.10.0 +[0.9.0]: https://github.com/ruby/prism/compare/v0.8.0...v0.9.0 +[0.8.0]: https://github.com/ruby/prism/compare/v0.7.0...v0.8.0 +[0.7.0]: https://github.com/ruby/prism/compare/v0.6.0...v0.7.0 +[0.6.0]: https://github.com/ruby/prism/compare/d60531...v0.6.0 diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/CODE_OF_CONDUCT.md b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..f6ae7f67 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery and unwelcome sexual attention or + advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others' private information, such as a physical or electronic + address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at opensource@shopify.com. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/CONTRIBUTING.md b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/CONTRIBUTING.md new file mode 100644 index 00000000..8e6fa3b8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/CONTRIBUTING.md @@ -0,0 +1,58 @@ +# Contributing + +Thank you for your interest in contributing to prism! Below are a couple of ways that you can help out. + +## Discussions + +The discussions page on the GitHub repository are open. If you have a question or want to discuss the project, feel free to open a new discussion or comment on an existing one. This is the best place to ask questions about the project. + +## Code + +If you want to contribute code, please first open or contribute to a discussion. A lot of the project is in flux, and we want to make sure that you are contributing to the right place. Once you have a discussion going, you can open a pull request with your changes. We will review your code and get it merged in. + +## Tests + +We could always use more tests! One of the biggest challenges of this project is building up a big test suite. If you want to contribute tests, feel free to open a pull request. These will get merged in as soon as possible. + +The `test` Rake task will not compile libraries or the C extension, and this is intentional (to make testing against an installed version easier). If you want to test your changes, please make sure you're also running either the task: + +``` sh +bundle exec rake +``` + +or explicitly running the `compile` task: + +``` sh +bundle exec rake compile test +# or to just compile the C extension ... +bundle exec rake compile:prism test +``` + +To test the rust bindings (with caveats about setting up your Rust environment properly first): + +``` sh +bundle exec rake compile test:rust +``` + + +## Documentation + +We could always use more documentation! If you want to contribute documentation, feel free to open a pull request. These will get merged in as soon as possible. Documenting functions or methods is always useful, but we also need more guides and tutorials. If you have an idea for a guide or tutorial, feel free to open an issue and we can discuss it. + +## Developing + +To get `clangd` support in the editor for development, generate the compilation database. This command will +create an ignored `compile_commands.json` file at the project root, which is used by clangd to provide functionality. + +You will need `bear` which can be installed on macOS with `brew install bear`. + +```sh +bundle exec rake bear +``` + +## Debugging + +Some useful rake tasks: + +- `test:valgrind` runs the test suite under valgrind to look for illegal memory access or memory leaks +- `test:gdb` and `test:lldb` run the test suite under those debuggers diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/LICENSE.md b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/LICENSE.md new file mode 100644 index 00000000..2d449f90 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/LICENSE.md @@ -0,0 +1,7 @@ +Copyright 2022-present, Shopify Inc. + +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 AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/Makefile b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/Makefile new file mode 100644 index 00000000..fddeecd9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/Makefile @@ -0,0 +1,108 @@ + +# V=0 quiet, V=1 verbose. other values don't work. +V = 0 +V0 = $(V:0=) +Q1 = $(V:1=) +Q = $(Q1:0=@) +ECHO1 = $(V:1=@ :) +ECHO = $(ECHO1:0=@ echo) +FUZZ_OUTPUT_DIR = $(CURDIR)/fuzz/output + +SOEXT ?= $(shell ruby -e 'puts RbConfig::CONFIG["SOEXT"]') + +CPPFLAGS := -Iinclude $(CPPFLAGS) +CFLAGS := -g -O2 -std=c99 -Wall -Werror -Wextra -Wpedantic -Wundef -Wconversion -Wno-missing-braces -fPIC -fvisibility=hidden -Wimplicit-fallthrough $(CFLAGS) +CC ?= cc +AR ?= ar +WASI_SDK_PATH := /opt/wasi-sdk + +MAKEDIRS ?= mkdir -p +RMALL ?= rm -f -r + +HEADERS := $(wildcard include/*.h include/*/*.h include/*/*/*.h') +SOURCES := $(wildcard src/*.c src/*/*.c) +SHARED_OBJECTS := $(subst src/,build/shared/,$(SOURCES:.c=.o)) +STATIC_OBJECTS := $(subst src/,build/static/,$(SOURCES:.c=.o)) + +all: shared static + +shared: build/libprism.$(SOEXT) +static: build/libprism.a +wasm: javascript/src/prism.wasm +java-wasm: java-wasm/src/test/resources/prism.wasm + +build/libprism.$(SOEXT): $(SHARED_OBJECTS) + $(ECHO) "linking $@ with $(CC)" + $(Q) $(CC) $(DEBUG_FLAGS) $(CFLAGS) -shared -o $@ $(SHARED_OBJECTS) + +build/libprism.a: $(STATIC_OBJECTS) + $(ECHO) "building $@ with $(AR)" + $(Q) $(AR) $(ARFLAGS) $@ $(STATIC_OBJECTS) $(Q1:0=>/dev/null) + +javascript/src/prism.wasm: Makefile $(SOURCES) $(HEADERS) + $(ECHO) "building $@" + $(Q) $(WASI_SDK_PATH)/bin/clang --sysroot=$(WASI_SDK_PATH)/share/wasi-sysroot/ $(DEBUG_FLAGS) -DPRISM_EXPORT_SYMBOLS -D_WASI_EMULATED_MMAN -lwasi-emulated-mman $(CPPFLAGS) $(CFLAGS) -Wl,--export-all -Wl,--no-entry -mexec-model=reactor -o $@ $(SOURCES) + +java-wasm/src/test/resources/prism.wasm: Makefile $(SOURCES) $(HEADERS) + $(ECHO) "building $@" + $(Q) $(WASI_SDK_PATH)/bin/clang $(DEBUG_FLAGS) -DPRISM_EXPORT_SYMBOLS -D_WASI_EMULATED_MMAN -lwasi-emulated-mman $(CPPFLAGS) $(CFLAGS) -Wl,--export-all -Wl,--no-entry -mexec-model=reactor -lc++ -lc++abi -o $@ $(SOURCES) + +build/shared/%.o: src/%.c Makefile $(HEADERS) + $(ECHO) "compiling $@" + $(Q) $(MAKEDIRS) $(@D) + $(Q) $(CC) $(DEBUG_FLAGS) -DPRISM_EXPORT_SYMBOLS $(CPPFLAGS) $(CFLAGS) -c -o $@ $< + +build/static/%.o: src/%.c Makefile $(HEADERS) + $(ECHO) "compiling $@" + $(Q) $(MAKEDIRS) $(@D) + $(Q) $(CC) $(DEBUG_FLAGS) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< + +build/fuzz.%: $(SOURCES) fuzz/%.c fuzz/fuzz.c + $(ECHO) "building $* fuzzer" + $(Q) $(MAKEDIRS) $(@D) + $(ECHO) "building main fuzz binary" + $(Q) AFL_HARDEN=1 afl-clang-lto $(DEBUG_FLAGS) $(CPPFLAGS) $(CFLAGS) $(FUZZ_FLAGS) -O0 -fsanitize-ignorelist=fuzz/asan.ignore -fsanitize=fuzzer,address -ggdb3 -std=c99 -Iinclude -o $@ $^ + $(ECHO) "building cmplog binary" + $(Q) AFL_HARDEN=1 AFL_LLVM_CMPLOG=1 afl-clang-lto $(DEBUG_FLAGS) $(CPPFLAGS) $(CFLAGS) $(FUZZ_FLAGS) -O0 -fsanitize-ignorelist=fuzz/asan.ignore -fsanitize=fuzzer,address -ggdb3 -std=c99 -Iinclude -o $@.cmplog $^ + +build/fuzz.heisenbug.%: $(SOURCES) fuzz/%.c fuzz/heisenbug.c + $(Q) AFL_HARDEN=1 afl-clang-lto $(DEBUG_FLAGS) $(CPPFLAGS) $(CFLAGS) $(FUZZ_FLAGS) -O0 -fsanitize-ignorelist=fuzz/asan.ignore -fsanitize=fuzzer,address -ggdb3 -std=c99 -Iinclude -o $@ $^ + +fuzz-debug: + $(ECHO) "entering debug shell" + $(Q) docker run -it --rm -e HISTFILE=/prism/fuzz/output/.bash_history -v $(CURDIR):/prism -v $(FUZZ_OUTPUT_DIR):/fuzz_output prism/fuzz + +fuzz-docker-build: fuzz/docker/Dockerfile + $(ECHO) "building docker image" + $(Q) docker build -t prism/fuzz fuzz/docker/ + +fuzz-run-%: FORCE fuzz-docker-build + $(ECHO) "generating templates" + $(Q) bundle exec rake templates + $(ECHO) "running $* fuzzer" + $(Q) docker run --rm -v $(CURDIR):/prism prism/fuzz /bin/bash -c "FUZZ_FLAGS=\"$(FUZZ_FLAGS)\" make build/fuzz.$*" + $(ECHO) "starting AFL++ run" + $(Q) $(MAKEDIRS) $(FUZZ_OUTPUT_DIR)/$* + $(Q) docker run -it --rm -v $(CURDIR):/prism -v $(FUZZ_OUTPUT_DIR):/fuzz_output prism/fuzz /bin/bash -c "./fuzz/$*.sh /fuzz_output/$*" +FORCE: + +fuzz-clean: + $(Q) $(RMALL) fuzz/output + +clean: + $(Q) $(RMALL) build + +.PHONY: clean fuzz-clean + +all-no-debug: DEBUG_FLAGS := -DNDEBUG=1 +all-no-debug: OPTFLAGS := -O3 +all-no-debug: all + +minimal: CFLAGS := $(CFLAGS) -DPRISM_BUILD_MINIMAL +minimal: all + +run: Makefile $(STATIC_OBJECTS) $(HEADERS) test.c + $(ECHO) "compiling test.c" + $(Q) $(CC) $(CPPFLAGS) $(CFLAGS) $(STATIC_OBJECTS) test.c + $(ECHO) "running test.c" + $(Q) ./a.out diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/README.md b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/README.md new file mode 100644 index 00000000..b601ee52 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/README.md @@ -0,0 +1,141 @@ +

Prism Ruby parser

+
+ Prism Ruby parser +
+ +This is a parser for the Ruby programming language. It is designed to be portable, error tolerant, and maintainable. It is written in C99 and has no dependencies. + +## Overview + +The repository contains the infrastructure for both a shared library (libprism) and a native CRuby extension. The shared library has no bindings to CRuby itself, and so can be used by other projects. The native CRuby extension links against `ruby.h`, and so is suitable in the context of CRuby. + +``` +. +├── Makefile configuration to compile the shared library and native tests +├── Rakefile configuration to compile the native extension and run the Ruby tests +├── bin +│   ├── lex runs the lexer on a file or string, prints the tokens, and compares to ripper +│   ├── parse runs the parse on a file or string and prints the AST +│   └── prism a CLI for development and debugging +├── config.yml specification for tokens and nodes in the tree +├── doc documentation website +├── docs markdown documentation about the project +├── ext +│   └── prism +│   ├── extconf.rb configuration to generate the Makefile for the native extension +│   └── extension.c the native extension that interacts with libprism +├── fuzz files related to fuzz testing +├── gemfiles gemfiles used by different Ruby versions in CI +├── include +│   ├── prism header files for the shared library +│   └── prism.h main header file for the shared library +├── java Java bindings for the shared library +├── java-wasm Java WASM bindings for the shared library +├── javascript JavaScript WASM bindings for the shared library +├── lib +│   ├── prism Ruby library files +│   └── prism.rb main entrypoint for the Ruby library +├── rakelib various Rake tasks for the project +├── rbi RBI type signatures for the Ruby library +├── rust +│   ├── ruby-prism Rustified crate for the shared library +│   └── ruby-prism-sys FFI binding for Rust +├── sample +│ └── prism Sample code that uses the Ruby API for documentation purposes +├── sig RBS type signatures for the Ruby library +├── src +│   ├── util various utility files +│   └── prism.c main entrypoint for the shared library +├── templates contains ERB templates generated by templates/template.rb +│   └── template.rb generates code from the nodes and tokens configured by config.yml +└── test + └── prism + ├── fixtures Ruby code used for testing + └── snapshots snapshots of generated syntax trees corresponding to fixtures +``` + +## Getting started + +To compile the shared library, you will need: + +* C99 compiler +* GNU make +* Ruby 2.7.0 or later + +Once you have these dependencies, run: + +``` +bundle install +``` + +to fetch the Ruby dependencies. Finally, run: + +``` +bundle exec rake compile +``` + +to compile the shared library. It will be built in the `build` directory. To test that everything is working, run: + +``` +bin/parse -e "1 + 2" +``` + +to see the syntax tree for the expression `1 + 2`. + +## Contributing + +See the [CONTRIBUTING.md](CONTRIBUTING.md) file for more information. We additionally have documentation about the overall design of the project as well as various subtopics. + +* [Build system](docs/build_system.md) +* [Configuration](docs/configuration.md) +* [CRuby compilation](docs/cruby_compilation.md) +* [Design](docs/design.md) +* [Encoding](docs/encoding.md) +* [Fuzzing](docs/fuzzing.md) +* [Heredocs](docs/heredocs.md) +* [JavaScript](docs/javascript.md) +* [Local variable depth](docs/local_variable_depth.md) +* [Mapping](docs/mapping.md) +* [Parser translation](docs/parser_translation.md) +* [Parsing rules](docs/parsing_rules.md) +* [Releasing](docs/releasing.md) +* [Ripper translation](docs/ripper_translation.md) +* [Ruby API](docs/ruby_api.md) +* [RubyParser translation](docs/ruby_parser_translation.md) +* [Serialization](docs/serialization.md) +* [Testing](docs/testing.md) + +## Examples + +Prism has been integrated into the majority of Ruby runtimes, many libraries, and some applications. Below is a list of some of the projects that use Prism: + +### Runtimes + +* [CRuby](https://github.com/ruby/ruby/pull/7964) (via C) +* [Garnet](https://github.com/camertron/garnet-js) (via WASM) +* [JRuby](https://github.com/jruby/jruby/pull/8103) (via Java) +* [Natalie](https://github.com/natalie-lang/natalie/pull/1213) (via C++ and Ruby) +* [Opal](https://github.com/opal/opal/pull/2642) (via Ruby and WASM) +* [TruffleRuby](https://github.com/oracle/truffleruby/issues/3117) (via Java) + +### Libraries + +* [dispersion](https://github.com/joeldrapper/dispersion) +* [minifyrb](https://github.com/koic/minifyrb) +* [packwerk](https://github.com/Shopify/packwerk/pull/388) (via parser translator) +* [rbi](https://github.com/Shopify/rbi) +* [rails](https://github.com/rails/rails) + * [parsing renders](https://github.com/rails/rails/pull/49438) + * [parsing rdoc](https://github.com/rails/rails/pull/50870) + * [parsing tests](https://github.com/rails/rails/pull/51006) +* [repl_type_completor](https://github.com/ruby/repl_type_completor) +* [rubocop](https://docs.rubocop.org/rubocop/configuration.html#setting-the-parser-engine) (via parser translator) +* [ruby-lsp](https://github.com/Shopify/ruby-lsp) +* [smart_todo](https://github.com/Shopify/smart_todo/pull/69) +* [sorbet-eraser](https://github.com/kddnewton/sorbet-eraser/pull/25) +* [synvert](https://github.com/xinminlabs/synvert-core-ruby) +* [typeprof](https://github.com/ruby/typeprof) + +### Applications + +* [gem.sh](https://github.com/marcoroth/gem.sh/pull/96) diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/config.yml b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/config.yml new file mode 100644 index 00000000..3d5eee19 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/config.yml @@ -0,0 +1,4486 @@ +errors: + - ALIAS_ARGUMENT + - ALIAS_ARGUMENT_NUMBERED_REFERENCE + - AMPAMPEQ_MULTI_ASSIGN + - ARGUMENT_AFTER_BLOCK + - ARGUMENT_AFTER_FORWARDING_ELLIPSES + - ARGUMENT_BARE_HASH + - ARGUMENT_BLOCK_FORWARDING + - ARGUMENT_BLOCK_MULTI + - ARGUMENT_CONFLICT_AMPERSAND + - ARGUMENT_CONFLICT_STAR + - ARGUMENT_CONFLICT_STAR_STAR + - ARGUMENT_FORMAL_CLASS + - ARGUMENT_FORMAL_CONSTANT + - ARGUMENT_FORMAL_GLOBAL + - ARGUMENT_FORMAL_IVAR + - ARGUMENT_FORWARDING_UNBOUND + - ARGUMENT_NO_FORWARDING_AMPERSAND + - ARGUMENT_NO_FORWARDING_ELLIPSES + - ARGUMENT_NO_FORWARDING_STAR + - ARGUMENT_NO_FORWARDING_STAR_STAR + - ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT + - ARGUMENT_SPLAT_AFTER_SPLAT + - ARGUMENT_TERM_PAREN + - ARGUMENT_UNEXPECTED_BLOCK + - ARRAY_ELEMENT + - ARRAY_EXPRESSION + - ARRAY_EXPRESSION_AFTER_STAR + - ARRAY_SEPARATOR + - ARRAY_TERM + - BEGIN_LONELY_ELSE + - BEGIN_TERM + - BEGIN_UPCASE_BRACE + - BEGIN_UPCASE_TERM + - BEGIN_UPCASE_TOPLEVEL + - BLOCK_PARAM_LOCAL_VARIABLE + - BLOCK_PARAM_PIPE_TERM + - BLOCK_TERM_BRACE + - BLOCK_TERM_END + - CANNOT_PARSE_EXPRESSION + - CANNOT_PARSE_STRING_PART + - CASE_EXPRESSION_AFTER_CASE + - CASE_EXPRESSION_AFTER_WHEN + - CASE_MATCH_MISSING_PREDICATE + - CASE_MISSING_CONDITIONS + - CASE_TERM + - CLASS_IN_METHOD + - CLASS_NAME + - CLASS_SUPERCLASS + - CLASS_TERM + - CLASS_UNEXPECTED_END + - CLASS_VARIABLE_BARE + - CONDITIONAL_ELSIF_PREDICATE + - CONDITIONAL_IF_PREDICATE + - CONDITIONAL_PREDICATE_TERM + - CONDITIONAL_TERM + - CONDITIONAL_TERM_ELSE + - CONDITIONAL_UNLESS_PREDICATE + - CONDITIONAL_UNTIL_PREDICATE + - CONDITIONAL_WHILE_PREDICATE + - CONSTANT_PATH_COLON_COLON_CONSTANT + - DEF_ENDLESS + - DEF_ENDLESS_SETTER + - DEF_NAME + - DEF_PARAMS_TERM + - DEF_PARAMS_TERM_PAREN + - DEF_RECEIVER + - DEF_RECEIVER_TERM + - DEF_TERM + - DEFINED_EXPRESSION + - EMBDOC_TERM + - EMBEXPR_END + - EMBVAR_INVALID + - END_UPCASE_BRACE + - END_UPCASE_TERM + - ESCAPE_INVALID_CONTROL + - ESCAPE_INVALID_CONTROL_REPEAT + - ESCAPE_INVALID_HEXADECIMAL + - ESCAPE_INVALID_META + - ESCAPE_INVALID_META_REPEAT + - ESCAPE_INVALID_UNICODE + - ESCAPE_INVALID_UNICODE_CM_FLAGS + - ESCAPE_INVALID_UNICODE_LIST + - ESCAPE_INVALID_UNICODE_LITERAL + - ESCAPE_INVALID_UNICODE_LONG + - ESCAPE_INVALID_UNICODE_SHORT + - ESCAPE_INVALID_UNICODE_TERM + - EXPECT_ARGUMENT + - EXPECT_EOL_AFTER_STATEMENT + - EXPECT_EXPRESSION_AFTER_AMPAMPEQ + - EXPECT_EXPRESSION_AFTER_COMMA + - EXPECT_EXPRESSION_AFTER_EQUAL + - EXPECT_EXPRESSION_AFTER_LESS_LESS + - EXPECT_EXPRESSION_AFTER_LPAREN + - EXPECT_EXPRESSION_AFTER_OPERATOR + - EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ + - EXPECT_EXPRESSION_AFTER_QUESTION + - EXPECT_EXPRESSION_AFTER_SPLAT + - EXPECT_EXPRESSION_AFTER_SPLAT_HASH + - EXPECT_EXPRESSION_AFTER_STAR + - EXPECT_FOR_DELIMITER + - EXPECT_IDENT_REQ_PARAMETER + - EXPECT_IN_DELIMITER + - EXPECT_LPAREN_REQ_PARAMETER + - EXPECT_MESSAGE + - EXPECT_RBRACKET + - EXPECT_RPAREN + - EXPECT_RPAREN_AFTER_MULTI + - EXPECT_RPAREN_REQ_PARAMETER + - EXPECT_SINGLETON_CLASS_DELIMITER + - EXPECT_STRING_CONTENT + - EXPECT_WHEN_DELIMITER + - EXPRESSION_BARE_HASH + - EXPRESSION_NOT_WRITABLE + - EXPRESSION_NOT_WRITABLE_ENCODING + - EXPRESSION_NOT_WRITABLE_FALSE + - EXPRESSION_NOT_WRITABLE_FILE + - EXPRESSION_NOT_WRITABLE_LINE + - EXPRESSION_NOT_WRITABLE_NIL + - EXPRESSION_NOT_WRITABLE_NUMBERED + - EXPRESSION_NOT_WRITABLE_SELF + - EXPRESSION_NOT_WRITABLE_TRUE + - FLOAT_PARSE + - FOR_COLLECTION + - FOR_IN + - FOR_INDEX + - FOR_TERM + - GLOBAL_VARIABLE_BARE + - HASH_EXPRESSION_AFTER_LABEL + - HASH_KEY + - HASH_ROCKET + - HASH_TERM + - HASH_VALUE + - HEREDOC_IDENTIFIER + - HEREDOC_TERM + - INCOMPLETE_QUESTION_MARK + - INCOMPLETE_VARIABLE_CLASS + - INCOMPLETE_VARIABLE_CLASS_3_3 + - INCOMPLETE_VARIABLE_INSTANCE + - INCOMPLETE_VARIABLE_INSTANCE_3_3 + - INSTANCE_VARIABLE_BARE + - INVALID_BLOCK_EXIT + - INVALID_CHARACTER + - INVALID_COMMA + - INVALID_ENCODING_MAGIC_COMMENT + - INVALID_ESCAPE_CHARACTER + - INVALID_FLOAT_EXPONENT + - INVALID_LOCAL_VARIABLE_READ + - INVALID_LOCAL_VARIABLE_WRITE + - INVALID_MULTIBYTE_CHAR + - INVALID_MULTIBYTE_CHARACTER + - INVALID_MULTIBYTE_ESCAPE + - INVALID_NUMBER_BINARY + - INVALID_NUMBER_DECIMAL + - INVALID_NUMBER_FRACTION + - INVALID_NUMBER_HEXADECIMAL + - INVALID_NUMBER_OCTAL + - INVALID_NUMBER_UNDERSCORE_INNER + - INVALID_NUMBER_UNDERSCORE_TRAILING + - INVALID_PERCENT + - INVALID_PERCENT_EOF + - INVALID_PRINTABLE_CHARACTER + - INVALID_RETRY_AFTER_ELSE + - INVALID_RETRY_AFTER_ENSURE + - INVALID_RETRY_WITHOUT_RESCUE + - INVALID_SYMBOL + - INVALID_VARIABLE_GLOBAL + - INVALID_VARIABLE_GLOBAL_3_3 + - INVALID_YIELD + - IT_NOT_ALLOWED_NUMBERED + - IT_NOT_ALLOWED_ORDINARY + - LAMBDA_OPEN + - LAMBDA_TERM_BRACE + - LAMBDA_TERM_END + - LIST_I_LOWER_ELEMENT + - LIST_I_LOWER_TERM + - LIST_I_UPPER_ELEMENT + - LIST_I_UPPER_TERM + - LIST_W_LOWER_ELEMENT + - LIST_W_LOWER_TERM + - LIST_W_UPPER_ELEMENT + - LIST_W_UPPER_TERM + - MALLOC_FAILED + - MIXED_ENCODING + - MODULE_IN_METHOD + - MODULE_NAME + - MODULE_TERM + - MULTI_ASSIGN_MULTI_SPLATS + - MULTI_ASSIGN_UNEXPECTED_REST + - NESTING_TOO_DEEP + - NO_LOCAL_VARIABLE + - NON_ASSOCIATIVE_OPERATOR + - NOT_EXPRESSION + - NUMBER_LITERAL_UNDERSCORE + - NUMBERED_PARAMETER_INNER_BLOCK + - NUMBERED_PARAMETER_IT + - NUMBERED_PARAMETER_ORDINARY + - NUMBERED_PARAMETER_OUTER_BLOCK + - OPERATOR_MULTI_ASSIGN + - OPERATOR_WRITE_ARGUMENTS + - OPERATOR_WRITE_BLOCK + - PARAMETER_ASSOC_SPLAT_MULTI + - PARAMETER_BLOCK_MULTI + - PARAMETER_CIRCULAR + - PARAMETER_FORWARDING_AFTER_REST + - PARAMETER_METHOD_NAME + - PARAMETER_NAME_DUPLICATED + - PARAMETER_NO_DEFAULT + - PARAMETER_NO_DEFAULT_KW + - PARAMETER_NUMBERED_RESERVED + - PARAMETER_ORDER + - PARAMETER_SPLAT_MULTI + - PARAMETER_STAR + - PARAMETER_UNEXPECTED_FWD + - PARAMETER_UNEXPECTED_NO_KW + - PARAMETER_WILD_LOOSE_COMMA + - PATTERN_ARRAY_MULTIPLE_RESTS + - PATTERN_CAPTURE_DUPLICATE + - PATTERN_EXPRESSION_AFTER_BRACKET + - PATTERN_EXPRESSION_AFTER_COMMA + - PATTERN_EXPRESSION_AFTER_HROCKET + - PATTERN_EXPRESSION_AFTER_IN + - PATTERN_EXPRESSION_AFTER_KEY + - PATTERN_EXPRESSION_AFTER_PAREN + - PATTERN_EXPRESSION_AFTER_PIN + - PATTERN_EXPRESSION_AFTER_PIPE + - PATTERN_EXPRESSION_AFTER_RANGE + - PATTERN_EXPRESSION_AFTER_REST + - PATTERN_FIND_MISSING_INNER + - PATTERN_HASH_IMPLICIT + - PATTERN_HASH_KEY + - PATTERN_HASH_KEY_DUPLICATE + - PATTERN_HASH_KEY_INTERPOLATED + - PATTERN_HASH_KEY_LABEL + - PATTERN_HASH_KEY_LOCALS + - PATTERN_IDENT_AFTER_HROCKET + - PATTERN_LABEL_AFTER_COMMA + - PATTERN_REST + - PATTERN_TERM_BRACE + - PATTERN_TERM_BRACKET + - PATTERN_TERM_PAREN + - PIPEPIPEEQ_MULTI_ASSIGN + - REGEXP_ENCODING_OPTION_MISMATCH + - REGEXP_INCOMPAT_CHAR_ENCODING + - REGEXP_INVALID_UNICODE_RANGE + - REGEXP_NON_ESCAPED_MBC + - REGEXP_PARSE_ERROR + - REGEXP_TERM + - REGEXP_UNKNOWN_OPTIONS + - REGEXP_UTF8_CHAR_NON_UTF8_REGEXP + - RESCUE_EXPRESSION + - RESCUE_MODIFIER_VALUE + - RESCUE_TERM + - RESCUE_VARIABLE + - RETURN_INVALID + - SCRIPT_NOT_FOUND + - SINGLETON_FOR_LITERALS + - STATEMENT_ALIAS + - STATEMENT_POSTEXE_END + - STATEMENT_PREEXE_BEGIN + - STATEMENT_UNDEF + - STRING_CONCATENATION + - STRING_INTERPOLATED_TERM + - STRING_LITERAL_EOF + - STRING_LITERAL_TERM + - SYMBOL_INVALID + - SYMBOL_TERM_DYNAMIC + - SYMBOL_TERM_INTERPOLATED + - TERNARY_COLON + - TERNARY_EXPRESSION_FALSE + - TERNARY_EXPRESSION_TRUE + - UNARY_DISALLOWED + - UNARY_RECEIVER + - UNDEF_ARGUMENT + - UNEXPECTED_BLOCK_ARGUMENT + - UNEXPECTED_INDEX_BLOCK + - UNEXPECTED_INDEX_KEYWORDS + - UNEXPECTED_LABEL + - UNEXPECTED_MULTI_WRITE + - UNEXPECTED_RANGE_OPERATOR + - UNEXPECTED_SAFE_NAVIGATION + - UNEXPECTED_TOKEN_CLOSE_CONTEXT + - UNEXPECTED_TOKEN_IGNORE + - UNTIL_TERM + - VOID_EXPRESSION + - WHILE_TERM + - WRITE_TARGET_IN_METHOD + - WRITE_TARGET_READONLY + - WRITE_TARGET_UNEXPECTED + - XSTRING_TERM +warnings: + - AMBIGUOUS_BINARY_OPERATOR + - AMBIGUOUS_FIRST_ARGUMENT_MINUS + - AMBIGUOUS_FIRST_ARGUMENT_PLUS + - AMBIGUOUS_PREFIX_AMPERSAND + - AMBIGUOUS_PREFIX_STAR + - AMBIGUOUS_PREFIX_STAR_STAR + - AMBIGUOUS_SLASH + - COMPARISON_AFTER_COMPARISON + - DOT_DOT_DOT_EOL + - EQUAL_IN_CONDITIONAL + - EQUAL_IN_CONDITIONAL_3_3 + - END_IN_METHOD + - DUPLICATED_HASH_KEY + - DUPLICATED_WHEN_CLAUSE + - FLOAT_OUT_OF_RANGE + - IGNORED_FROZEN_STRING_LITERAL + - INDENTATION_MISMATCH + - INTEGER_IN_FLIP_FLOP + - INVALID_CHARACTER + - INVALID_MAGIC_COMMENT_VALUE + - INVALID_NUMBERED_REFERENCE + - KEYWORD_EOL + - LITERAL_IN_CONDITION_DEFAULT + - LITERAL_IN_CONDITION_VERBOSE + - SHAREABLE_CONSTANT_VALUE_LINE + - SHEBANG_CARRIAGE_RETURN + - UNEXPECTED_CARRIAGE_RETURN + - UNREACHABLE_STATEMENT + - UNUSED_LOCAL_VARIABLE + - VOID_STATEMENT +tokens: + - name: EOF + value: 1 + comment: final token in the file + - name: MISSING + comment: "a token that was expected but not found" + - name: NOT_PROVIDED + comment: "a token that was not present but it is okay" + - name: AMPERSAND + comment: "&" + - name: AMPERSAND_AMPERSAND + comment: "&&" + - name: AMPERSAND_AMPERSAND_EQUAL + comment: "&&=" + - name: AMPERSAND_DOT + comment: "&." + - name: AMPERSAND_EQUAL + comment: "&=" + - name: BACKTICK + comment: "`" + - name: BACK_REFERENCE + comment: "a back reference" + - name: BANG + comment: "! or !@" + - name: BANG_EQUAL + comment: "!=" + - name: BANG_TILDE + comment: "!~" + - name: BRACE_LEFT + comment: "{" + - name: BRACE_RIGHT + comment: "}" + - name: BRACKET_LEFT + comment: "[" + - name: BRACKET_LEFT_ARRAY + comment: "[ for the beginning of an array" + - name: BRACKET_LEFT_RIGHT + comment: "[]" + - name: BRACKET_LEFT_RIGHT_EQUAL + comment: "[]=" + - name: BRACKET_RIGHT + comment: "]" + - name: CARET + comment: "^" + - name: CARET_EQUAL + comment: "^=" + - name: CHARACTER_LITERAL + comment: "a character literal" + - name: CLASS_VARIABLE + comment: "a class variable" + - name: COLON + comment: ":" + - name: COLON_COLON + comment: "::" + - name: COMMA + comment: "," + - name: COMMENT + comment: "a comment" + - name: CONSTANT + comment: "a constant" + - name: DOT + comment: "the . call operator" + - name: DOT_DOT + comment: "the .. range operator" + - name: DOT_DOT_DOT + comment: "the ... range operator or forwarding parameter" + - name: EMBDOC_BEGIN + comment: "=begin" + - name: EMBDOC_END + comment: "=end" + - name: EMBDOC_LINE + comment: "a line inside of embedded documentation" + - name: EMBEXPR_BEGIN + comment: "#{" + - name: EMBEXPR_END + comment: "}" + - name: EMBVAR + comment: "#" + - name: EQUAL + comment: "=" + - name: EQUAL_EQUAL + comment: "==" + - name: EQUAL_EQUAL_EQUAL + comment: "===" + - name: EQUAL_GREATER + comment: "=>" + - name: EQUAL_TILDE + comment: "=~" + - name: FLOAT + comment: "a floating point number" + - name: FLOAT_IMAGINARY + comment: "a floating pointer number with an imaginary suffix" + - name: FLOAT_RATIONAL + comment: "a floating pointer number with a rational suffix" + - name: FLOAT_RATIONAL_IMAGINARY + comment: "a floating pointer number with a rational and imaginary suffix" + - name: GLOBAL_VARIABLE + comment: "a global variable" + - name: GREATER + comment: ">" + - name: GREATER_EQUAL + comment: ">=" + - name: GREATER_GREATER + comment: ">>" + - name: GREATER_GREATER_EQUAL + comment: ">>=" + - name: HEREDOC_END + comment: "the end of a heredoc" + - name: HEREDOC_START + comment: "the start of a heredoc" + - name: IDENTIFIER + comment: "an identifier" + - name: IGNORED_NEWLINE + comment: "an ignored newline" + - name: INSTANCE_VARIABLE + comment: "an instance variable" + - name: INTEGER + comment: "an integer (any base)" + - name: INTEGER_IMAGINARY + comment: "an integer with an imaginary suffix" + - name: INTEGER_RATIONAL + comment: "an integer with a rational suffix" + - name: INTEGER_RATIONAL_IMAGINARY + comment: "an integer with a rational and imaginary suffix" + - name: KEYWORD_ALIAS + comment: "alias" + - name: KEYWORD_AND + comment: "and" + - name: KEYWORD_BEGIN + comment: "begin" + - name: KEYWORD_BEGIN_UPCASE + comment: "BEGIN" + - name: KEYWORD_BREAK + comment: "break" + - name: KEYWORD_CASE + comment: "case" + - name: KEYWORD_CLASS + comment: "class" + - name: KEYWORD_DEF + comment: "def" + - name: KEYWORD_DEFINED + comment: "defined?" + - name: KEYWORD_DO + comment: "do" + - name: KEYWORD_DO_LOOP + comment: "do keyword for a predicate in a while, until, or for loop" + - name: KEYWORD_ELSE + comment: "else" + - name: KEYWORD_ELSIF + comment: "elsif" + - name: KEYWORD_END + comment: "end" + - name: KEYWORD_END_UPCASE + comment: "END" + - name: KEYWORD_ENSURE + comment: "ensure" + - name: KEYWORD_FALSE + comment: "false" + - name: KEYWORD_FOR + comment: "for" + - name: KEYWORD_IF + comment: "if" + - name: KEYWORD_IF_MODIFIER + comment: "if in the modifier form" + - name: KEYWORD_IN + comment: "in" + - name: KEYWORD_MODULE + comment: "module" + - name: KEYWORD_NEXT + comment: "next" + - name: KEYWORD_NIL + comment: "nil" + - name: KEYWORD_NOT + comment: "not" + - name: KEYWORD_OR + comment: "or" + - name: KEYWORD_REDO + comment: "redo" + - name: KEYWORD_RESCUE + comment: "rescue" + - name: KEYWORD_RESCUE_MODIFIER + comment: "rescue in the modifier form" + - name: KEYWORD_RETRY + comment: "retry" + - name: KEYWORD_RETURN + comment: "return" + - name: KEYWORD_SELF + comment: "self" + - name: KEYWORD_SUPER + comment: "super" + - name: KEYWORD_THEN + comment: "then" + - name: KEYWORD_TRUE + comment: "true" + - name: KEYWORD_UNDEF + comment: "undef" + - name: KEYWORD_UNLESS + comment: "unless" + - name: KEYWORD_UNLESS_MODIFIER + comment: "unless in the modifier form" + - name: KEYWORD_UNTIL + comment: "until" + - name: KEYWORD_UNTIL_MODIFIER + comment: "until in the modifier form" + - name: KEYWORD_WHEN + comment: "when" + - name: KEYWORD_WHILE + comment: "while" + - name: KEYWORD_WHILE_MODIFIER + comment: "while in the modifier form" + - name: KEYWORD_YIELD + comment: "yield" + - name: KEYWORD___ENCODING__ + comment: "__ENCODING__" + - name: KEYWORD___FILE__ + comment: "__FILE__" + - name: KEYWORD___LINE__ + comment: "__LINE__" + - name: LABEL + comment: "a label" + - name: LABEL_END + comment: "the end of a label" + - name: LAMBDA_BEGIN + comment: "{" + - name: LESS + comment: "<" + - name: LESS_EQUAL + comment: "<=" + - name: LESS_EQUAL_GREATER + comment: "<=>" + - name: LESS_LESS + comment: "<<" + - name: LESS_LESS_EQUAL + comment: "<<=" + - name: METHOD_NAME + comment: "a method name" + - name: MINUS + comment: "-" + - name: MINUS_EQUAL + comment: "-=" + - name: MINUS_GREATER + comment: "->" + - name: NEWLINE + comment: "a newline character outside of other tokens" + - name: NUMBERED_REFERENCE + comment: "a numbered reference to a capture group in the previous regular expression match" + - name: PARENTHESIS_LEFT + comment: "(" + - name: PARENTHESIS_LEFT_PARENTHESES + comment: "( for a parentheses node" + - name: PARENTHESIS_RIGHT + comment: ")" + - name: PERCENT + comment: "%" + - name: PERCENT_EQUAL + comment: "%=" + - name: PERCENT_LOWER_I + comment: "%i" + - name: PERCENT_LOWER_W + comment: "%w" + - name: PERCENT_LOWER_X + comment: "%x" + - name: PERCENT_UPPER_I + comment: "%I" + - name: PERCENT_UPPER_W + comment: "%W" + - name: PIPE + comment: "|" + - name: PIPE_EQUAL + comment: "|=" + - name: PIPE_PIPE + comment: "||" + - name: PIPE_PIPE_EQUAL + comment: "||=" + - name: PLUS + comment: "+" + - name: PLUS_EQUAL + comment: "+=" + - name: QUESTION_MARK + comment: "?" + - name: REGEXP_BEGIN + comment: "the beginning of a regular expression" + - name: REGEXP_END + comment: "the end of a regular expression" + - name: SEMICOLON + comment: ";" + - name: SLASH + comment: "/" + - name: SLASH_EQUAL + comment: "/=" + - name: STAR + comment: "*" + - name: STAR_EQUAL + comment: "*=" + - name: STAR_STAR + comment: "**" + - name: STAR_STAR_EQUAL + comment: "**=" + - name: STRING_BEGIN + comment: "the beginning of a string" + - name: STRING_CONTENT + comment: "the contents of a string" + - name: STRING_END + comment: "the end of a string" + - name: SYMBOL_BEGIN + comment: "the beginning of a symbol" + - name: TILDE + comment: "~ or ~@" + - name: UAMPERSAND + comment: "unary &" + - name: UCOLON_COLON + comment: "unary ::" + - name: UDOT_DOT + comment: "unary .. operator" + - name: UDOT_DOT_DOT + comment: "unary ... operator" + - name: UMINUS + comment: "-@" + - name: UMINUS_NUM + comment: "-@ for a number" + - name: UPLUS + comment: "+@" + - name: USTAR + comment: "unary *" + - name: USTAR_STAR + comment: "unary **" + - name: WORDS_SEP + comment: "a separator between words in a list" + - name: __END__ + comment: "marker for the point in the file at which the parser should stop" +flags: + - name: ArgumentsNodeFlags + values: + - name: CONTAINS_FORWARDING + comment: "if the arguments contain forwarding" + - name: CONTAINS_KEYWORDS + comment: "if the arguments contain keywords" + - name: CONTAINS_KEYWORD_SPLAT + comment: "if the arguments contain a keyword splat" + - name: CONTAINS_SPLAT + comment: "if the arguments contain a splat" + - name: CONTAINS_MULTIPLE_SPLATS + comment: "if the arguments contain multiple splats" + comment: Flags for arguments nodes. + - name: ArrayNodeFlags + values: + - name: CONTAINS_SPLAT + comment: "if array contains splat nodes" + comment: Flags for array nodes. + - name: CallNodeFlags + values: + - name: SAFE_NAVIGATION + comment: "&. operator" + - name: VARIABLE_CALL + comment: "a call that could have been a local variable" + - name: ATTRIBUTE_WRITE + comment: "a call that is an attribute write, so the value being written should be returned" + - name: IGNORE_VISIBILITY + comment: "a call that ignores method visibility" + comment: Flags for call nodes. + - name: EncodingFlags + values: + - name: FORCED_UTF8_ENCODING + comment: "internal bytes forced the encoding to UTF-8" + - name: FORCED_BINARY_ENCODING + comment: "internal bytes forced the encoding to binary" + comment: Flags for nodes that have unescaped content. + - name: IntegerBaseFlags + values: + - name: BINARY + comment: "0b prefix" + - name: DECIMAL + comment: "0d or no prefix" + - name: OCTAL + comment: "0o or 0 prefix" + - name: HEXADECIMAL + comment: "0x prefix" + comment: Flags for integer nodes that correspond to the base of the integer. + - name: InterpolatedStringNodeFlags + values: + - name: FROZEN + comment: "frozen by virtue of a `frozen_string_literal: true` comment or `--enable-frozen-string-literal`; only for adjacent string literals like `'a' 'b'`" + - name: MUTABLE + comment: "mutable by virtue of a `frozen_string_literal: false` comment or `--disable-frozen-string-literal`; only for adjacent string literals like `'a' 'b'`" + comment: Flags for interpolated string nodes that indicated mutability if they are also marked as literals. + - name: KeywordHashNodeFlags + values: + - name: SYMBOL_KEYS + comment: "a keyword hash which only has `AssocNode` elements all with symbol keys, which means the elements can be treated as keyword arguments" + comment: Flags for keyword hash nodes. + - name: LoopFlags + values: + - name: BEGIN_MODIFIER + comment: "a loop after a begin statement, so the body is executed first before the condition" + comment: Flags for while and until loop nodes. + - name: ParameterFlags + values: + - name: REPEATED_PARAMETER + comment: "a parameter name that has been repeated in the method signature" + comment: Flags for parameter nodes. + - name: ParenthesesNodeFlags + values: + - name: MULTIPLE_STATEMENTS + comment: "parentheses that contain multiple potentially void statements" + comment: Flags for parentheses nodes. + - name: RangeFlags + values: + - name: EXCLUDE_END + comment: "... operator" + comment: Flags for range and flip-flop nodes. + - name: RegularExpressionFlags + values: + - name: IGNORE_CASE + comment: "i - ignores the case of characters when matching" + - name: EXTENDED + comment: "x - ignores whitespace and allows comments in regular expressions" + - name: MULTI_LINE + comment: "m - allows $ to match the end of lines within strings" + - name: ONCE + comment: "o - only interpolates values into the regular expression once" + - name: EUC_JP + comment: "e - forces the EUC-JP encoding" + - name: ASCII_8BIT + comment: "n - forces the ASCII-8BIT encoding" + - name: WINDOWS_31J + comment: "s - forces the Windows-31J encoding" + - name: UTF_8 + comment: "u - forces the UTF-8 encoding" + - name: FORCED_UTF8_ENCODING + comment: "internal bytes forced the encoding to UTF-8" + - name: FORCED_BINARY_ENCODING + comment: "internal bytes forced the encoding to binary" + - name: FORCED_US_ASCII_ENCODING + comment: "internal bytes forced the encoding to US-ASCII" + comment: Flags for regular expression and match last line nodes. + - name: ShareableConstantNodeFlags + values: + - name: LITERAL + comment: "constant writes that should be modified with shareable constant value literal" + - name: EXPERIMENTAL_EVERYTHING + comment: "constant writes that should be modified with shareable constant value experimental everything" + - name: EXPERIMENTAL_COPY + comment: "constant writes that should be modified with shareable constant value experimental copy" + comment: Flags for shareable constant nodes. + - name: StringFlags + values: + - name: FORCED_UTF8_ENCODING + comment: "internal bytes forced the encoding to UTF-8" + - name: FORCED_BINARY_ENCODING + comment: "internal bytes forced the encoding to binary" + - name: FROZEN + comment: "frozen by virtue of a `frozen_string_literal: true` comment or `--enable-frozen-string-literal`" + - name: MUTABLE + comment: "mutable by virtue of a `frozen_string_literal: false` comment or `--disable-frozen-string-literal`" + comment: Flags for string nodes. + - name: SymbolFlags + values: + - name: FORCED_UTF8_ENCODING + comment: "internal bytes forced the encoding to UTF-8" + - name: FORCED_BINARY_ENCODING + comment: "internal bytes forced the encoding to binary" + - name: FORCED_US_ASCII_ENCODING + comment: "internal bytes forced the encoding to US-ASCII" + comment: Flags for symbol nodes. +nodes: + - name: AliasGlobalVariableNode + fields: + - name: new_name + type: node + kind: + - GlobalVariableReadNode + - BackReferenceReadNode + - NumberedReferenceReadNode + comment: | + Represents the new name of the global variable that can be used after aliasing. + + alias $foo $bar + ^^^^ + - name: old_name + type: node + kind: + - GlobalVariableReadNode + - BackReferenceReadNode + - NumberedReferenceReadNode + - on error: SymbolNode # alias $a b + - on error: MissingNode # alias $a 42 + comment: | + Represents the old name of the global variable that can be used before aliasing. + + alias $foo $bar + ^^^^ + - name: keyword_loc + type: location + comment: | + The location of the `alias` keyword. + + alias $foo $bar + ^^^^^ + comment: | + Represents the use of the `alias` keyword to alias a global variable. + + alias $foo $bar + ^^^^^^^^^^^^^^^ + - name: AliasMethodNode + fields: + - name: new_name + type: node + kind: + - SymbolNode + - InterpolatedSymbolNode + comment: | + Represents the new name of the method that will be aliased. + + alias foo bar + ^^^ + + alias :foo :bar + ^^^^ + + alias :"#{foo}" :"#{bar}" + ^^^^^^^^^ + - name: old_name + type: node + kind: + - SymbolNode + - InterpolatedSymbolNode + - on error: GlobalVariableReadNode # alias a $b + - on error: MissingNode # alias a 42 + comment: | + Represents the old name of the method that will be aliased. + + alias foo bar + ^^^ + + alias :foo :bar + ^^^^ + + alias :"#{foo}" :"#{bar}" + ^^^^^^^^^ + - name: keyword_loc + type: location + comment: | + Represents the location of the `alias` keyword. + + alias foo bar + ^^^^^ + comment: | + Represents the use of the `alias` keyword to alias a method. + + alias foo bar + ^^^^^^^^^^^^^ + - name: AlternationPatternNode + fields: + - name: left + type: node + kind: pattern expression + comment: | + Represents the left side of the expression. + + foo => bar | baz + ^^^ + - name: right + type: node + kind: pattern expression + comment: | + Represents the right side of the expression. + + foo => bar | baz + ^^^ + - name: operator_loc + type: location + comment: | + Represents the alternation operator location. + + foo => bar | baz + ^ + comment: | + Represents an alternation pattern in pattern matching. + + foo => bar | baz + ^^^^^^^^^ + - name: AndNode + fields: + - name: left + type: node + kind: non-void expression + comment: | + Represents the left side of the expression. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + left and right + ^^^^ + + 1 && 2 + ^ + - name: right + type: node + kind: Node + comment: | + Represents the right side of the expression. + + left && right + ^^^^^ + + 1 and 2 + ^ + - name: operator_loc + type: location + comment: | + The location of the `and` keyword or the `&&` operator. + + left and right + ^^^ + comment: | + Represents the use of the `&&` operator or the `and` keyword. + + left and right + ^^^^^^^^^^^^^^ + - name: ArgumentsNode + flags: ArgumentsNodeFlags + fields: + - name: arguments + type: node[] + kind: non-void expression + comment: | + The list of arguments, if present. These can be any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + foo(bar, baz) + ^^^^^^^^ + comment: | + Represents a set of arguments to a method or a keyword. + + return foo, bar, baz + ^^^^^^^^^^^^^ + - name: ArrayNode + flags: ArrayNodeFlags + fields: + - name: elements + type: node[] + kind: non-void expression + comment: Represent the list of zero or more [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression) within the array. + - name: opening_loc + type: location? + comment: | + Represents the optional source location for the opening token. + + [1,2,3] # "[" + %w[foo bar baz] # "%w[" + %I(apple orange banana) # "%I(" + foo = 1, 2, 3 # nil + - name: closing_loc + type: location? + comment: | + Represents the optional source location for the closing token. + + [1,2,3] # "]" + %w[foo bar baz] # "]" + %I(apple orange banana) # ")" + foo = 1, 2, 3 # nil + comment: | + Represents an array literal. This can be a regular array using brackets or a special array using % like %w or %i. + + [1, 2, 3] + ^^^^^^^^^ + - name: ArrayPatternNode + fields: + - name: constant + type: node? + kind: + - ConstantReadNode + - ConstantPathNode + - name: requireds + type: node[] + kind: pattern expression + comment: | + Represents the required elements of the array pattern. + + foo in [1, 2] + ^ ^ + - name: rest + type: node? + kind: pattern expression + comment: | + Represents the rest element of the array pattern. + + foo in *bar + ^^^^ + - name: posts + type: node[] + kind: pattern expression + comment: | + Represents the elements after the rest element of the array pattern. + + foo in *bar, baz + ^^^ + - name: opening_loc + type: location? + comment: | + Represents the opening location of the array pattern. + + foo in [1, 2] + ^ + - name: closing_loc + type: location? + comment: | + Represents the closing location of the array pattern. + + foo in [1, 2] + ^ + comment: | + Represents an array pattern in pattern matching. + + foo in 1, 2 + ^^^^^^^^^^^ + + foo in [1, 2] + ^^^^^^^^^^^^^ + + foo in *bar + ^^^^^^^^^^^ + + foo in Bar[] + ^^^^^^^^^^^^ + + foo in Bar[1, 2, 3] + ^^^^^^^^^^^^^^^^^^^ + - name: AssocNode + fields: + - name: key + type: node + kind: non-void expression + comment: | + The key of the association. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + { a: b } + ^ + + { foo => bar } + ^^^ + + { def a; end => 1 } + ^^^^^^^^^^ + - name: value + type: node + kind: non-void expression + comment: | + The value of the association, if present. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + { foo => bar } + ^^^ + + { x: 1 } + ^ + - name: operator_loc + type: location? + comment: | + The location of the `=>` operator, if present. + + { foo => bar } + ^^ + comment: | + Represents a hash key/value pair. + + { a => b } + ^^^^^^ + - name: AssocSplatNode + fields: + - name: value + type: node? + kind: non-void expression + comment: | + The value to be splatted, if present. Will be missing when keyword rest argument forwarding is used. + + { **foo } + ^^^ + - name: operator_loc + type: location + comment: | + The location of the `**` operator. + + { **x } + ^^ + comment: | + Represents a splat in a hash literal. + + { **foo } + ^^^^^ + - name: BackReferenceReadNode + fields: + - name: name + type: constant + comment: | + The name of the back-reference variable, including the leading `$`. + + $& # name `:$&` + + $+ # name `:$+` + comment: | + Represents reading a reference to a field in the previous match. + + $' + ^^ + - name: BeginNode + fields: + - name: begin_keyword_loc + type: location? + comment: | + Represents the location of the `begin` keyword. + + begin x end + ^^^^^ + - name: statements + type: node? + kind: StatementsNode + comment: | + Represents the statements within the begin block. + + begin x end + ^ + - name: rescue_clause + type: node? + kind: RescueNode + comment: | + Represents the rescue clause within the begin block. + + begin x; rescue y; end + ^^^^^^^^ + - name: else_clause + type: node? + kind: ElseNode + comment: | + Represents the else clause within the begin block. + + begin x; rescue y; else z; end + ^^^^^^ + - name: ensure_clause + type: node? + kind: EnsureNode + comment: | + Represents the ensure clause within the begin block. + + begin x; ensure y; end + ^^^^^^^^ + - name: end_keyword_loc + type: location? + comment: | + Represents the location of the `end` keyword. + + begin x end + ^^^ + newline: false + comment: | + Represents a begin statement. + + begin + foo + end + ^^^^^ + - name: BlockArgumentNode + fields: + - name: expression + type: node? + kind: non-void expression + comment: | + The expression that is being passed as a block argument. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + foo(&args) + ^^^^^ + - name: operator_loc + type: location + comment: | + Represents the location of the `&` operator. + + foo(&args) + ^ + comment: | + Represents a block argument using `&`. + + bar(&args) + ^^^^^^^^^^ + - name: BlockLocalVariableNode + flags: ParameterFlags + fields: + - name: name + type: constant + comment: | + The name of the block local variable. + + a { |; b| } # name `:b` + ^ + comment: | + Represents a block local variable. + + a { |; b| } + ^ + - name: BlockNode + fields: + - name: locals + type: constant[] + comment: | + The local variables declared in the block. + + [1, 2, 3].each { |i| puts x } # locals: [:i] + ^ + - name: parameters + type: node? + kind: + - BlockParametersNode + - NumberedParametersNode + - ItParametersNode + comment: | + The parameters of the block. + + [1, 2, 3].each { |i| puts x } + ^^^ + [1, 2, 3].each { puts _1 } + ^^^^^^^^^^^ + [1, 2, 3].each { puts it } + ^^^^^^^^^^^ + - name: body + type: node? + kind: + - StatementsNode + - BeginNode + comment: | + The body of the block. + + [1, 2, 3].each { |i| puts x } + ^^^^^^ + - name: opening_loc + type: location + comment: | + Represents the location of the opening `|`. + + [1, 2, 3].each { |i| puts x } + ^ + - name: closing_loc + type: location + comment: | + Represents the location of the closing `|`. + + [1, 2, 3].each { |i| puts x } + ^ + comment: | + Represents a block of ruby code. + + [1, 2, 3].each { |i| puts x } + ^^^^^^^^^^^^^^ + - name: BlockParameterNode + flags: ParameterFlags + fields: + - name: name + type: constant? + comment: | + The name of the block parameter. + + def a(&b) # name `:b` + ^ + end + - name: name_loc + type: location? + comment: | + Represents the location of the block parameter name. + + def a(&b) + ^ + - name: operator_loc + type: location + comment: | + Represents the location of the `&` operator. + + def a(&b) + ^ + end + comment: | + Represents a block parameter of a method, block, or lambda definition. + + def a(&b) + ^^ + end + - name: BlockParametersNode + fields: + - name: parameters + type: node? + kind: ParametersNode + comment: | + Represents the parameters of the block. + + -> (a, b = 1; local) { } + ^^^^^^^^ + + foo do |a, b = 1; local| + ^^^^^^^^ + end + - name: locals + type: node[] + kind: BlockLocalVariableNode + comment: | + Represents the local variables of the block. + + -> (a, b = 1; local) { } + ^^^^^ + + foo do |a, b = 1; local| + ^^^^^ + end + - name: opening_loc + type: location? + comment: | + Represents the opening location of the block parameters. + + -> (a, b = 1; local) { } + ^ + + foo do |a, b = 1; local| + ^ + end + - name: closing_loc + type: location? + comment: | + Represents the closing location of the block parameters. + + -> (a, b = 1; local) { } + ^ + + foo do |a, b = 1; local| + ^ + end + comment: | + Represents a block's parameters declaration. + + -> (a, b = 1; local) { } + ^^^^^^^^^^^^^^^^^ + + foo do |a, b = 1; local| + ^^^^^^^^^^^^^^^^^ + end + - name: BreakNode + fields: + - name: arguments + type: node? + kind: ArgumentsNode + comment: | + The arguments to the break statement, if present. These can be any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + break foo + ^^^ + - name: keyword_loc + type: location + comment: | + The location of the `break` keyword. + + break foo + ^^^^^ + comment: | + Represents the use of the `break` keyword. + + break foo + ^^^^^^^^^ + - name: CallAndWriteNode + flags: CallNodeFlags + fields: + - name: receiver + type: node? + kind: non-void expression + comment: | + The object that the method is being called on. This can be either `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + foo.bar &&= value + ^^^ + - name: call_operator_loc + type: location? + comment: | + Represents the location of the call operator. + + foo.bar &&= value + ^ + - name: message_loc + type: location? + comment: | + Represents the location of the message. + + foo.bar &&= value + ^^^ + - name: read_name + type: constant + comment: | + Represents the name of the method being called. + + foo.bar &&= value # read_name `:bar` + ^^^ + - name: write_name + type: constant + comment: | + Represents the name of the method being written to. + + foo.bar &&= value # write_name `:bar=` + ^^^ + - name: operator_loc + type: location + comment: | + Represents the location of the operator. + + foo.bar &&= value + ^^^ + - name: value + type: node + kind: non-void expression + comment: | + Represents the value being assigned. + + foo.bar &&= value + ^^^^^ + comment: | + Represents the use of the `&&=` operator on a call. + + foo.bar &&= value + ^^^^^^^^^^^^^^^^^ + - name: CallNode + flags: CallNodeFlags + fields: + - name: receiver + type: node? + kind: non-void expression + comment: | + The object that the method is being called on. This can be either `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + foo.bar + ^^^ + + +foo + ^^^ + + foo + bar + ^^^ + - name: call_operator_loc + type: location? + comment: | + Represents the location of the call operator. + + foo.bar + ^ + + foo&.bar + ^^ + - name: name + type: constant + comment: | + Represents the name of the method being called. + + foo.bar # name `:foo` + ^^^ + - name: message_loc + type: location? + comment: | + Represents the location of the message. + + foo.bar + ^^^ + - name: opening_loc + type: location? + comment: | + Represents the location of the left parenthesis. + foo(bar) + ^ + - name: arguments + type: node? + kind: ArgumentsNode + comment: | + Represents the arguments to the method call. These can be any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + foo(bar) + ^^^ + - name: closing_loc + type: location? + comment: | + Represents the location of the right parenthesis. + + foo(bar) + ^ + - name: block + type: node? + kind: + - BlockNode + - BlockArgumentNode + comment: | + Represents the block that is being passed to the method. + + foo { |a| a } + ^^^^^^^^^ + comment: | + Represents a method call, in all of the various forms that can take. + + foo + ^^^ + + foo() + ^^^^^ + + +foo + ^^^^ + + foo + bar + ^^^^^^^^^ + + foo.bar + ^^^^^^^ + + foo&.bar + ^^^^^^^^ + - name: CallOperatorWriteNode + flags: CallNodeFlags + fields: + - name: receiver + type: node? + kind: non-void expression + comment: | + The object that the method is being called on. This can be either `nil` or any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + foo.bar += value + ^^^ + - name: call_operator_loc + type: location? + comment: | + Represents the location of the call operator. + + foo.bar += value + ^ + - name: message_loc + type: location? + comment: | + Represents the location of the message. + + foo.bar += value + ^^^ + - name: read_name + type: constant + comment: | + Represents the name of the method being called. + + foo.bar += value # read_name `:bar` + ^^^ + - name: write_name + type: constant + comment: | + Represents the name of the method being written to. + + foo.bar += value # write_name `:bar=` + ^^^ + - name: binary_operator + type: constant + comment: | + Represents the binary operator being used. + + foo.bar += value # binary_operator `:+` + ^ + - name: binary_operator_loc + type: location + comment: | + Represents the location of the binary operator. + + foo.bar += value + ^^ + - name: value + type: node + kind: non-void expression + comment: | + Represents the value being assigned. + + foo.bar += value + ^^^^^ + comment: | + Represents the use of an assignment operator on a call. + + foo.bar += baz + ^^^^^^^^^^^^^^ + - name: CallOrWriteNode + flags: CallNodeFlags + fields: + - name: receiver + type: node? + kind: non-void expression + comment: | + The object that the method is being called on. This can be either `nil` or any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + foo.bar ||= value + ^^^ + - name: call_operator_loc + type: location? + comment: | + Represents the location of the call operator. + + foo.bar ||= value + ^ + - name: message_loc + type: location? + comment: | + Represents the location of the message. + + foo.bar ||= value + ^^^ + - name: read_name + type: constant + comment: | + Represents the name of the method being called. + + foo.bar ||= value # read_name `:bar` + ^^^ + - name: write_name + type: constant + comment: | + Represents the name of the method being written to. + + foo.bar ||= value # write_name `:bar=` + ^^^ + - name: operator_loc + type: location + comment: | + Represents the location of the operator. + + foo.bar ||= value + ^^^ + - name: value + type: node + kind: non-void expression + comment: | + Represents the value being assigned. + + foo.bar ||= value + ^^^^^ + comment: | + Represents the use of the `||=` operator on a call. + + foo.bar ||= value + ^^^^^^^^^^^^^^^^^ + - name: CallTargetNode + flags: CallNodeFlags + fields: + - name: receiver + type: node + kind: non-void expression + comment: | + The object that the method is being called on. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + foo.bar = 1 + ^^^ + - name: call_operator_loc + type: location + comment: | + Represents the location of the call operator. + + foo.bar = 1 + ^ + - name: name + type: constant + comment: | + Represents the name of the method being called. + + foo.bar = 1 # name `:foo` + ^^^ + - name: message_loc + type: location + comment: | + Represents the location of the message. + + foo.bar = 1 + ^^^ + comment: | + Represents assigning to a method call. + + foo.bar, = 1 + ^^^^^^^ + + begin + rescue => foo.bar + ^^^^^^^ + end + + for foo.bar in baz do end + ^^^^^^^ + - name: CapturePatternNode + fields: + - name: value + type: node + kind: pattern expression + comment: | + Represents the value to capture. + + foo => bar + ^^^ + - name: target + type: node + kind: LocalVariableTargetNode + comment: | + Represents the target of the capture. + + foo => bar + ^^^ + - name: operator_loc + type: location + comment: | + Represents the location of the `=>` operator. + + foo => bar + ^^ + comment: | + Represents assigning to a local variable in pattern matching. + + foo => [bar => baz] + ^^^^^^^^^^^^ + - name: CaseMatchNode + fields: + - name: predicate + type: node? + kind: non-void expression + comment: | + Represents the predicate of the case match. This can be either `nil` or any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + case true; in false; end + ^^^^ + - name: conditions + type: node[] + kind: InNode + comment: | + Represents the conditions of the case match. + + case true; in false; end + ^^^^^^^^ + - name: else_clause + type: node? + kind: ElseNode + comment: | + Represents the else clause of the case match. + + case true; in false; else; end + ^^^^ + - name: case_keyword_loc + type: location + comment: | + Represents the location of the `case` keyword. + + case true; in false; end + ^^^^ + - name: end_keyword_loc + type: location + comment: | + Represents the location of the `end` keyword. + + case true; in false; end + ^^^ + comment: | + Represents the use of a case statement for pattern matching. + + case true + in false + end + ^^^^^^^^^ + - name: CaseNode + fields: + - name: predicate + type: node? + kind: non-void expression + comment: | + Represents the predicate of the case statement. This can be either `nil` or any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + case true; when false; end + ^^^^ + - name: conditions + type: node[] + kind: WhenNode + comment: | + Represents the conditions of the case statement. + + case true; when false; end + ^^^^^^^^^^ + - name: else_clause + type: node? + kind: ElseNode + comment: | + Represents the else clause of the case statement. + + case true; when false; else; end + ^^^^ + - name: case_keyword_loc + type: location + comment: | + Represents the location of the `case` keyword. + + case true; when false; end + ^^^^ + - name: end_keyword_loc + type: location + comment: | + Represents the location of the `end` keyword. + + case true; when false; end + ^^^ + comment: | + Represents the use of a case statement. + + case true + when false + end + ^^^^^^^^^^ + - name: ClassNode + fields: + - name: locals + type: constant[] + - name: class_keyword_loc + type: location + - name: constant_path + type: node + kind: + - ConstantReadNode + - ConstantPathNode + - on error: CallNode # class 0.X end + - name: inheritance_operator_loc + type: location? + - name: superclass + type: node? + kind: non-void expression + - name: body + type: node? + kind: + - StatementsNode + - BeginNode + - name: end_keyword_loc + type: location + - name: name + type: constant + comment: | + Represents a class declaration involving the `class` keyword. + + class Foo end + ^^^^^^^^^^^^^ + - name: ClassVariableAndWriteNode + fields: + - name: name + type: constant + comment: | + The name of the class variable, which is a `@@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). + + @@target &&= value # name `:@@target` + ^^^^^^^^ + - name: name_loc + type: location + comment: | + Represents the location of the variable name. + + @@target &&= value + ^^^^^^^^ + - name: operator_loc + type: location + comment: | + Represents the location of the `&&=` operator. + + @@target &&= value + ^^^ + - name: value + type: node + kind: non-void expression + comment: | + Represents the value being assigned. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + @@target &&= value + ^^^^^ + comment: | + Represents the use of the `&&=` operator for assignment to a class variable. + + @@target &&= value + ^^^^^^^^^^^^^^^^^^ + - name: ClassVariableOperatorWriteNode + fields: + - name: name + type: constant + - name: name_loc + type: location + - name: binary_operator_loc + type: location + - name: value + type: node + kind: non-void expression + - name: binary_operator + type: constant + comment: | + Represents assigning to a class variable using an operator that isn't `=`. + + @@target += value + ^^^^^^^^^^^^^^^^^ + - name: ClassVariableOrWriteNode + fields: + - name: name + type: constant + - name: name_loc + type: location + - name: operator_loc + type: location + - name: value + type: node + kind: non-void expression + comment: | + Represents the use of the `||=` operator for assignment to a class variable. + + @@target ||= value + ^^^^^^^^^^^^^^^^^^ + - name: ClassVariableReadNode + fields: + - name: name + type: constant + comment: | + The name of the class variable, which is a `@@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). + + @@abc # name `:@@abc` + + @@_test # name `:@@_test` + comment: | + Represents referencing a class variable. + + @@foo + ^^^^^ + - name: ClassVariableTargetNode + fields: + - name: name + type: constant + comment: | + Represents writing to a class variable in a context that doesn't have an explicit value. + + @@foo, @@bar = baz + ^^^^^ ^^^^^ + - name: ClassVariableWriteNode + fields: + - name: name + type: constant + comment: | + The name of the class variable, which is a `@@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). + + @@abc = 123 # name `@@abc` + + @@_test = :test # name `@@_test` + - name: name_loc + type: location + comment: | + The location of the variable name. + + @@foo = :bar + ^^^^^ + - name: value + type: node + kind: non-void expression + comment: | + The value to write to the class variable. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + @@foo = :bar + ^^^^ + + @@_xyz = 123 + ^^^ + - name: operator_loc + type: location + comment: | + The location of the `=` operator. + + @@foo = :bar + ^ + comment: | + Represents writing to a class variable. + + @@foo = 1 + ^^^^^^^^^ + - name: ConstantAndWriteNode + fields: + - name: name + type: constant + - name: name_loc + type: location + - name: operator_loc + type: location + - name: value + type: node + kind: non-void expression + comment: | + Represents the use of the `&&=` operator for assignment to a constant. + + Target &&= value + ^^^^^^^^^^^^^^^^ + - name: ConstantOperatorWriteNode + fields: + - name: name + type: constant + - name: name_loc + type: location + - name: binary_operator_loc + type: location + - name: value + type: node + kind: non-void expression + - name: binary_operator + type: constant + comment: | + Represents assigning to a constant using an operator that isn't `=`. + + Target += value + ^^^^^^^^^^^^^^^ + - name: ConstantOrWriteNode + fields: + - name: name + type: constant + - name: name_loc + type: location + - name: operator_loc + type: location + - name: value + type: node + kind: non-void expression + comment: | + Represents the use of the `||=` operator for assignment to a constant. + + Target ||= value + ^^^^^^^^^^^^^^^^ + - name: ConstantPathAndWriteNode + fields: + - name: target + type: node + kind: ConstantPathNode + - name: operator_loc + type: location + - name: value + type: node + kind: non-void expression + comment: | + Represents the use of the `&&=` operator for assignment to a constant path. + + Parent::Child &&= value + ^^^^^^^^^^^^^^^^^^^^^^^ + - name: ConstantPathNode + fields: + - name: parent + type: node? + kind: non-void expression + comment: | + The left-hand node of the path, if present. It can be `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). It will be `nil` when the constant lookup is at the root of the module tree. + + Foo::Bar + ^^^ + + self::Test + ^^^^ + + a.b::C + ^^^ + - name: name + type: constant? + comment: The name of the constant being accessed. This could be `nil` in the event of a syntax error. + - name: delimiter_loc + type: location + comment: | + The location of the `::` delimiter. + + ::Foo + ^^ + + One::Two + ^^ + - name: name_loc + type: location + comment: | + The location of the name of the constant. + + ::Foo + ^^^ + + One::Two + ^^^ + comment: | + Represents accessing a constant through a path of `::` operators. + + Foo::Bar + ^^^^^^^^ + - name: ConstantPathOperatorWriteNode + fields: + - name: target + type: node + kind: ConstantPathNode + - name: binary_operator_loc + type: location + - name: value + type: node + kind: non-void expression + - name: binary_operator + type: constant + comment: | + Represents assigning to a constant path using an operator that isn't `=`. + + Parent::Child += value + ^^^^^^^^^^^^^^^^^^^^^^ + - name: ConstantPathOrWriteNode + fields: + - name: target + type: node + kind: ConstantPathNode + - name: operator_loc + type: location + - name: value + type: node + kind: non-void expression + comment: | + Represents the use of the `||=` operator for assignment to a constant path. + + Parent::Child ||= value + ^^^^^^^^^^^^^^^^^^^^^^^ + - name: ConstantPathTargetNode + fields: + - name: parent + type: node? + kind: non-void expression + - name: name + type: constant? + - name: delimiter_loc + type: location + - name: name_loc + type: location + comment: | + Represents writing to a constant path in a context that doesn't have an explicit value. + + Foo::Foo, Bar::Bar = baz + ^^^^^^^^ ^^^^^^^^ + - name: ConstantPathWriteNode + fields: + - name: target + type: node + kind: ConstantPathNode + comment: | + A node representing the constant path being written to. + + Foo::Bar = 1 + ^^^^^^^^ + + ::Foo = :abc + ^^^^^ + - name: operator_loc + type: location + comment: | + The location of the `=` operator. + + ::ABC = 123 + ^ + - name: value + type: node + kind: non-void expression + comment: | + The value to write to the constant path. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + FOO::BAR = :abc + ^^^^ + comment: | + Represents writing to a constant path. + + ::Foo = 1 + ^^^^^^^^^ + + Foo::Bar = 1 + ^^^^^^^^^^^^ + + ::Foo::Bar = 1 + ^^^^^^^^^^^^^^ + - name: ConstantReadNode + fields: + - name: name + type: constant + comment: | + The name of the [constant](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#constants). + + X # name `:X` + + SOME_CONSTANT # name `:SOME_CONSTANT` + comment: | + Represents referencing a constant. + + Foo + ^^^ + - name: ConstantTargetNode + fields: + - name: name + type: constant + comment: | + Represents writing to a constant in a context that doesn't have an explicit value. + + Foo, Bar = baz + ^^^ ^^^ + - name: ConstantWriteNode + fields: + - name: name + type: constant + comment: | + The name of the [constant](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#constants). + + Foo = :bar # name `:Foo` + + XYZ = 1 # name `:XYZ` + - name: name_loc + type: location + comment: | + The location of the constant name. + + FOO = 1 + ^^^ + - name: value + type: node + kind: non-void expression + comment: | + The value to write to the constant. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + FOO = :bar + ^^^^ + + MyClass = Class.new + ^^^^^^^^^ + - name: operator_loc + type: location + comment: | + The location of the `=` operator. + + FOO = :bar + ^ + comment: | + Represents writing to a constant. + + Foo = 1 + ^^^^^^^ + - name: DefNode + fields: + - name: name + type: constant + - name: name_loc + type: location + - name: receiver + type: node? + kind: non-void expression + - name: parameters + type: node? + kind: ParametersNode + - name: body + type: node? + kind: + - StatementsNode + - BeginNode + - name: locals + type: constant[] + - name: def_keyword_loc + type: location + - name: operator_loc + type: location? + - name: lparen_loc + type: location? + - name: rparen_loc + type: location? + - name: equal_loc + type: location? + - name: end_keyword_loc + type: location? + comment: | + Represents a method definition. + + def method + end + ^^^^^^^^^^ + - name: DefinedNode + fields: + - name: lparen_loc + type: location? + - name: value + type: node + kind: Node # More than non-void expression as defined?(return) is allowed, yet defined?(BEGIN{}) is SyntaxError + - name: rparen_loc + type: location? + - name: keyword_loc + type: location + comment: | + Represents the use of the `defined?` keyword. + + defined?(a) + ^^^^^^^^^^^ + - name: ElseNode + fields: + - name: else_keyword_loc + type: location + - name: statements + type: node? + kind: StatementsNode + - name: end_keyword_loc + type: location? + comment: | + Represents an `else` clause in a `case`, `if`, or `unless` statement. + + if a then b else c end + ^^^^^^^^^^ + - name: EmbeddedStatementsNode + fields: + - name: opening_loc + type: location + - name: statements + type: node? + kind: StatementsNode + - name: closing_loc + type: location + comment: | + Represents an interpolated set of statements. + + "foo #{bar}" + ^^^^^^ + - name: EmbeddedVariableNode + fields: + - name: operator_loc + type: location + - name: variable + type: node + kind: + - InstanceVariableReadNode + - ClassVariableReadNode + - GlobalVariableReadNode + - BackReferenceReadNode + - NumberedReferenceReadNode + comment: | + Represents an interpolated variable. + + "foo #@bar" + ^^^^^ + - name: EnsureNode + fields: + - name: ensure_keyword_loc + type: location + - name: statements + type: node? + kind: StatementsNode + - name: end_keyword_loc + type: location + comment: | + Represents an `ensure` clause in a `begin` statement. + + begin + foo + ensure + ^^^^^^ + bar + end + - name: FalseNode + comment: | + Represents the use of the literal `false` keyword. + + false + ^^^^^ + - name: FindPatternNode + fields: + - name: constant + type: node? + kind: + - ConstantReadNode + - ConstantPathNode + - name: left + type: node + kind: SplatNode + - name: requireds + type: node[] + kind: pattern expression + - name: right + type: node + kind: + - SplatNode + - on error: MissingNode + - name: opening_loc + type: location? + - name: closing_loc + type: location? + comment: | + Represents a find pattern in pattern matching. + + foo in *bar, baz, *qux + ^^^^^^^^^^^^^^^ + + foo in [*bar, baz, *qux] + ^^^^^^^^^^^^^^^^^ + + foo in Foo(*bar, baz, *qux) + ^^^^^^^^^^^^^^^^^^^^ + - name: FlipFlopNode + flags: RangeFlags + fields: + - name: left + type: node? + kind: non-void expression + - name: right + type: node? + kind: non-void expression + - name: operator_loc + type: location + comment: | + Represents the use of the `..` or `...` operators to create flip flops. + + baz if foo .. bar + ^^^^^^^^^^ + - name: FloatNode + fields: + - name: value + type: double + comment: The value of the floating point number as a Float. + comment: | + Represents a floating point number literal. + + 1.0 + ^^^ + - name: ForNode + fields: + - name: index + type: node + kind: + - LocalVariableTargetNode + - InstanceVariableTargetNode + - ClassVariableTargetNode + - GlobalVariableTargetNode + - ConstantTargetNode + - ConstantPathTargetNode + - CallTargetNode + - IndexTargetNode + - MultiTargetNode + - on error: BackReferenceReadNode # for $& in a end + - on error: NumberedReferenceReadNode # for $1 in a end + - on error: MissingNode # for in 1..10; end + comment: | + The index expression for `for` loops. + + for i in a end + ^ + - name: collection + type: node + kind: non-void expression + comment: | + The collection to iterate over. + + for i in a end + ^ + - name: statements + type: node? + kind: StatementsNode + comment: | + Represents the body of statements to execute for each iteration of the loop. + + for i in a + foo(i) + ^^^^^^ + end + - name: for_keyword_loc + type: location + comment: | + The location of the `for` keyword. + + for i in a end + ^^^ + - name: in_keyword_loc + type: location + comment: | + The location of the `in` keyword. + + for i in a end + ^^ + - name: do_keyword_loc + type: location? + comment: | + The location of the `do` keyword, if present. + + for i in a do end + ^^ + - name: end_keyword_loc + type: location + comment: | + The location of the `end` keyword. + + for i in a end + ^^^ + comment: | + Represents the use of the `for` keyword. + + for i in a end + ^^^^^^^^^^^^^^ + - name: ForwardingArgumentsNode + comment: | + Represents forwarding all arguments to this method to another method. + + def foo(...) + bar(...) + ^^^ + end + - name: ForwardingParameterNode + comment: | + Represents the use of the forwarding parameter in a method, block, or lambda declaration. + + def foo(...) + ^^^ + end + - name: ForwardingSuperNode + fields: + - name: block + type: node? + kind: BlockNode + comment: | + Represents the use of the `super` keyword without parentheses or arguments. + + super + ^^^^^ + - name: GlobalVariableAndWriteNode + fields: + - name: name + type: constant + - name: name_loc + type: location + - name: operator_loc + type: location + - name: value + type: node + kind: non-void expression + comment: | + Represents the use of the `&&=` operator for assignment to a global variable. + + $target &&= value + ^^^^^^^^^^^^^^^^^ + - name: GlobalVariableOperatorWriteNode + fields: + - name: name + type: constant + - name: name_loc + type: location + - name: binary_operator_loc + type: location + - name: value + type: node + kind: non-void expression + - name: binary_operator + type: constant + comment: | + Represents assigning to a global variable using an operator that isn't `=`. + + $target += value + ^^^^^^^^^^^^^^^^ + - name: GlobalVariableOrWriteNode + fields: + - name: name + type: constant + - name: name_loc + type: location + - name: operator_loc + type: location + - name: value + type: node + kind: non-void expression + comment: | + Represents the use of the `||=` operator for assignment to a global variable. + + $target ||= value + ^^^^^^^^^^^^^^^^^ + - name: GlobalVariableReadNode + fields: + - name: name + type: constant + comment: | + The name of the global variable, which is a `$` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifier). Alternatively, it can be one of the special global variables designated by a symbol. + + $foo # name `:$foo` + + $_Test # name `:$_Test` + comment: | + Represents referencing a global variable. + + $foo + ^^^^ + - name: GlobalVariableTargetNode + fields: + - name: name + type: constant + comment: | + Represents writing to a global variable in a context that doesn't have an explicit value. + + $foo, $bar = baz + ^^^^ ^^^^ + - name: GlobalVariableWriteNode + fields: + - name: name + type: constant + comment: | + The name of the global variable, which is a `$` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifier). Alternatively, it can be one of the special global variables designated by a symbol. + + $foo = :bar # name `:$foo` + + $_Test = 123 # name `:$_Test` + - name: name_loc + type: location + comment: | + The location of the global variable's name. + + $foo = :bar + ^^^^ + - name: value + type: node + kind: non-void expression + comment: | + The value to write to the global variable. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + $foo = :bar + ^^^^ + + $-xyz = 123 + ^^^ + - name: operator_loc + type: location + comment: | + The location of the `=` operator. + + $foo = :bar + ^ + comment: | + Represents writing to a global variable. + + $foo = 1 + ^^^^^^^^ + - name: HashNode + fields: + - name: opening_loc + type: location + comment: | + The location of the opening brace. + + { a => b } + ^ + - name: elements + type: node[] + kind: + - AssocNode + - AssocSplatNode + comment: | + The elements of the hash. These can be either `AssocNode`s or `AssocSplatNode`s. + + { a: b } + ^^^^ + + { **foo } + ^^^^^ + - name: closing_loc + type: location + comment: | + The location of the closing brace. + + { a => b } + ^ + comment: | + Represents a hash literal. + + { a => b } + ^^^^^^^^^^ + - name: HashPatternNode + fields: + - name: constant + type: node? + kind: + - ConstantReadNode + - ConstantPathNode + - name: elements + type: node[] + kind: AssocNode + - name: rest + type: node? + kind: + - AssocSplatNode + - NoKeywordsParameterNode + - name: opening_loc + type: location? + - name: closing_loc + type: location? + comment: | + Represents a hash pattern in pattern matching. + + foo => { a: 1, b: 2 } + ^^^^^^^^^^^^^^ + + foo => { a: 1, b: 2, **c } + ^^^^^^^^^^^^^^^^^^^ + - name: IfNode + fields: + - name: if_keyword_loc + type: location? + comment: | + The location of the `if` keyword if present. + + bar if foo + ^^ + + The `if_keyword_loc` field will be `nil` when the `IfNode` represents a ternary expression. + - name: predicate + type: node + kind: non-void expression + comment: | + The node for the condition the `IfNode` is testing. + + if foo + ^^^ + bar + end + + bar if foo + ^^^ + + foo ? bar : baz + ^^^ + - name: then_keyword_loc + type: location? + comment: | + The location of the `then` keyword (if present) or the `?` in a ternary expression, `nil` otherwise. + + if foo then bar end + ^^^^ + + a ? b : c + ^ + - name: statements + type: node? + kind: StatementsNode + comment: | + Represents the body of statements that will be executed when the predicate is evaluated as truthy. Will be `nil` when no body is provided. + + if foo + bar + ^^^ + baz + ^^^ + end + - name: subsequent + type: node? + kind: + - ElseNode + - IfNode + comment: | + Represents an `ElseNode` or an `IfNode` when there is an `else` or an `elsif` in the `if` statement. + + if foo + bar + elsif baz + ^^^^^^^^^ + qux + ^^^ + end + ^^^ + + if foo then bar else baz end + ^^^^^^^^^^^^ + - name: end_keyword_loc + type: location? + comment: | + The location of the `end` keyword if present, `nil` otherwise. + + if foo + bar + end + ^^^ + newline: predicate + comment: | + Represents the use of the `if` keyword, either in the block form or the modifier form, or a ternary expression. + + bar if foo + ^^^^^^^^^^ + + if foo then bar end + ^^^^^^^^^^^^^^^^^^^ + + foo ? bar : baz + ^^^^^^^^^^^^^^^ + - name: ImaginaryNode + fields: + - name: numeric + type: node + kind: + - FloatNode + - IntegerNode + - RationalNode + comment: | + Represents an imaginary number literal. + + 1.0i + ^^^^ + - name: ImplicitNode + fields: + - name: value + type: node + kind: + - LocalVariableReadNode + - CallNode + - ConstantReadNode + - LocalVariableTargetNode + comment: | + Represents a node that is implicitly being added to the tree but doesn't correspond directly to a node in the source. + + { foo: } + ^^^^ + + { Foo: } + ^^^^ + + foo in { bar: } + ^^^^ + - name: ImplicitRestNode + comment: | + Represents using a trailing comma to indicate an implicit rest parameter. + + foo { |bar,| } + ^ + + foo in [bar,] + ^ + + for foo, in bar do end + ^ + + foo, = bar + ^ + - name: InNode + fields: + - name: pattern + type: node + kind: pattern expression + - name: statements + type: node? + kind: StatementsNode + - name: in_loc + type: location + - name: then_loc + type: location? + comment: | + Represents the use of the `in` keyword in a case statement. + + case a; in b then c end + ^^^^^^^^^^^ + - name: IndexAndWriteNode + flags: CallNodeFlags + fields: + - name: receiver + type: node? + kind: non-void expression + - name: call_operator_loc + type: location? + - name: opening_loc + type: location + - name: arguments + type: node? + kind: ArgumentsNode + - name: closing_loc + type: location + - name: block + type: node? + kind: BlockArgumentNode # foo[&b] &&= value, only valid on Ruby < 3.4 + - name: operator_loc + type: location + - name: value + type: node + kind: non-void expression + comment: | + Represents the use of the `&&=` operator on a call to the `[]` method. + + foo.bar[baz] &&= value + ^^^^^^^^^^^^^^^^^^^^^^ + - name: IndexOperatorWriteNode + flags: CallNodeFlags + fields: + - name: receiver + type: node? + kind: non-void expression + - name: call_operator_loc + type: location? + - name: opening_loc + type: location + - name: arguments + type: node? + kind: ArgumentsNode + - name: closing_loc + type: location + - name: block + type: node? + kind: BlockArgumentNode # foo[&b] += value, only valid on Ruby < 3.4 + - name: binary_operator + type: constant + - name: binary_operator_loc + type: location + - name: value + type: node + kind: non-void expression + comment: | + Represents the use of an assignment operator on a call to `[]`. + + foo.bar[baz] += value + ^^^^^^^^^^^^^^^^^^^^^ + - name: IndexOrWriteNode + flags: CallNodeFlags + fields: + - name: receiver + type: node? + kind: non-void expression + - name: call_operator_loc + type: location? + - name: opening_loc + type: location + - name: arguments + type: node? + kind: ArgumentsNode + - name: closing_loc + type: location + - name: block + type: node? + kind: BlockArgumentNode # foo[&b] ||= value, only valid on Ruby < 3.4 + - name: operator_loc + type: location + - name: value + type: node + kind: non-void expression + comment: | + Represents the use of the `||=` operator on a call to `[]`. + + foo.bar[baz] ||= value + ^^^^^^^^^^^^^^^^^^^^^^ + - name: IndexTargetNode + flags: CallNodeFlags + fields: + - name: receiver + type: node + kind: non-void expression + - name: opening_loc + type: location + - name: arguments + type: node? + kind: ArgumentsNode + - name: closing_loc + type: location + - name: block + type: node? + kind: BlockArgumentNode # foo[&b], = 1, only valid on Ruby < 3.4 + comment: | + Represents assigning to an index. + + foo[bar], = 1 + ^^^^^^^^ + + begin + rescue => foo[bar] + ^^^^^^^^ + end + + for foo[bar] in baz do end + ^^^^^^^^ + - name: InstanceVariableAndWriteNode + fields: + - name: name + type: constant + - name: name_loc + type: location + - name: operator_loc + type: location + - name: value + type: node + kind: non-void expression + comment: | + Represents the use of the `&&=` operator for assignment to an instance variable. + + @target &&= value + ^^^^^^^^^^^^^^^^^ + - name: InstanceVariableOperatorWriteNode + fields: + - name: name + type: constant + - name: name_loc + type: location + - name: binary_operator_loc + type: location + - name: value + type: node + kind: non-void expression + - name: binary_operator + type: constant + comment: | + Represents assigning to an instance variable using an operator that isn't `=`. + + @target += value + ^^^^^^^^^^^^^^^^ + - name: InstanceVariableOrWriteNode + fields: + - name: name + type: constant + - name: name_loc + type: location + - name: operator_loc + type: location + - name: value + type: node + kind: non-void expression + comment: | + Represents the use of the `||=` operator for assignment to an instance variable. + + @target ||= value + ^^^^^^^^^^^^^^^^^ + - name: InstanceVariableReadNode + fields: + - name: name + type: constant + comment: | + The name of the instance variable, which is a `@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). + + @x # name `:@x` + + @_test # name `:@_test` + comment: | + Represents referencing an instance variable. + + @foo + ^^^^ + - name: InstanceVariableTargetNode + fields: + - name: name + type: constant + comment: | + Represents writing to an instance variable in a context that doesn't have an explicit value. + + @foo, @bar = baz + ^^^^ ^^^^ + - name: InstanceVariableWriteNode + fields: + - name: name + type: constant + comment: | + The name of the instance variable, which is a `@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). + + @x = :y # name `:@x` + + @_foo = "bar" # name `@_foo` + - name: name_loc + type: location + comment: | + The location of the variable name. + + @_x = 1 + ^^^ + - name: value + type: node + kind: non-void expression + comment: | + The value to write to the instance variable. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + @foo = :bar + ^^^^ + + @_x = 1234 + ^^^^ + - name: operator_loc + type: location + comment: | + The location of the `=` operator. + + @x = y + ^ + comment: | + Represents writing to an instance variable. + + @foo = 1 + ^^^^^^^^ + - name: IntegerNode + flags: IntegerBaseFlags + fields: + - name: value + type: integer + comment: The value of the integer literal as a number. + comment: | + Represents an integer number literal. + + 1 + ^ + - name: InterpolatedMatchLastLineNode + flags: RegularExpressionFlags + fields: + - name: opening_loc + type: location + - name: parts + type: node[] + kind: + - StringNode + - EmbeddedStatementsNode + - EmbeddedVariableNode + - name: closing_loc + type: location + newline: parts + comment: | + Represents a regular expression literal that contains interpolation that is being used in the predicate of a conditional to implicitly match against the last line read by an IO object. + + if /foo #{bar} baz/ then end + ^^^^^^^^^^^^^^^^ + - name: InterpolatedRegularExpressionNode + flags: RegularExpressionFlags + fields: + - name: opening_loc + type: location + - name: parts + type: node[] + kind: + - StringNode + - EmbeddedStatementsNode + - EmbeddedVariableNode + - name: closing_loc + type: location + newline: parts + comment: | + Represents a regular expression literal that contains interpolation. + + /foo #{bar} baz/ + ^^^^^^^^^^^^^^^^ + - name: InterpolatedStringNode + flags: InterpolatedStringNodeFlags + fields: + - name: opening_loc + type: location? + - name: parts + type: node[] + kind: + - StringNode + - EmbeddedStatementsNode + - EmbeddedVariableNode + - InterpolatedStringNode # `"a" "#{b}"` + - on error: XStringNode # `<<`FOO` "bar" + - name: closing_loc + type: location? + newline: parts + comment: | + Represents a string literal that contains interpolation. + + "foo #{bar} baz" + ^^^^^^^^^^^^^^^^ + - name: InterpolatedSymbolNode + fields: + - name: opening_loc + type: location? + - name: parts + type: node[] + kind: + - StringNode + - EmbeddedStatementsNode + - EmbeddedVariableNode + - name: closing_loc + type: location? + newline: parts + comment: | + Represents a symbol literal that contains interpolation. + + :"foo #{bar} baz" + ^^^^^^^^^^^^^^^^^ + - name: InterpolatedXStringNode + fields: + - name: opening_loc + type: location + - name: parts + type: node[] + kind: + - StringNode + - EmbeddedStatementsNode + - EmbeddedVariableNode + - name: closing_loc + type: location + newline: parts + comment: | + Represents an xstring literal that contains interpolation. + + `foo #{bar} baz` + ^^^^^^^^^^^^^^^^ + - name: ItLocalVariableReadNode + comment: | + Represents reading from the implicit `it` local variable. + + -> { it } + ^^ + - name: ItParametersNode + comment: | + Represents an implicit set of parameters through the use of the `it` keyword within a block or lambda. + + -> { it + it } + ^^^^^^^^^^^^^^ + - name: KeywordHashNode + flags: KeywordHashNodeFlags + fields: + - name: elements + type: node[] + kind: + - AssocNode + - AssocSplatNode + comment: | + Represents a hash literal without opening and closing braces. + + foo(a: b) + ^^^^ + - name: KeywordRestParameterNode + flags: ParameterFlags + fields: + - name: name + type: constant? + - name: name_loc + type: location? + - name: operator_loc + type: location + comment: | + Represents a keyword rest parameter to a method, block, or lambda definition. + + def a(**b) + ^^^ + end + - name: LambdaNode + fields: + - name: locals + type: constant[] + - name: operator_loc + type: location + - name: opening_loc + type: location + - name: closing_loc + type: location + - name: parameters + type: node? + kind: + - BlockParametersNode + - NumberedParametersNode + - ItParametersNode + - name: body + type: node? + kind: + - StatementsNode + - BeginNode + comment: | + Represents using a lambda literal (not the lambda method call). + + ->(value) { value * 2 } + ^^^^^^^^^^^^^^^^^^^^^^^ + - name: LocalVariableAndWriteNode + fields: + - name: name_loc + type: location + - name: operator_loc + type: location + - name: value + type: node + kind: non-void expression + - name: name + type: constant + - name: depth + type: uint32 + comment: | + Represents the use of the `&&=` operator for assignment to a local variable. + + target &&= value + ^^^^^^^^^^^^^^^^ + - name: LocalVariableOperatorWriteNode + fields: + - name: name_loc + type: location + - name: binary_operator_loc + type: location + - name: value + type: node + kind: non-void expression + - name: name + type: constant + - name: binary_operator + type: constant + - name: depth + type: uint32 + comment: | + Represents assigning to a local variable using an operator that isn't `=`. + + target += value + ^^^^^^^^^^^^^^^ + - name: LocalVariableOrWriteNode + fields: + - name: name_loc + type: location + - name: operator_loc + type: location + - name: value + type: node + kind: non-void expression + - name: name + type: constant + - name: depth + type: uint32 + comment: | + Represents the use of the `||=` operator for assignment to a local variable. + + target ||= value + ^^^^^^^^^^^^^^^^ + - name: LocalVariableReadNode + fields: + - name: name + type: constant + comment: | + The name of the local variable, which is an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). + + x # name `:x` + + _Test # name `:_Test` + + Note that this can also be an underscore followed by a number for the default block parameters. + + _1 # name `:_1` + + - name: depth + type: uint32 + comment: | + The number of visible scopes that should be searched to find the origin of this local variable. + + foo = 1; foo # depth 0 + + bar = 2; tap { bar } # depth 1 + + The specific rules for calculating the depth may differ from individual Ruby implementations, as they are not specified by the language. For more information, see [the Prism documentation](https://github.com/ruby/prism/blob/main/docs/local_variable_depth.md). + comment: | + Represents reading a local variable. Note that this requires that a local variable of the same name has already been written to in the same scope, otherwise it is parsed as a method call. + + foo + ^^^ + - name: LocalVariableTargetNode + fields: + - name: name + type: constant + - name: depth + type: uint32 + comment: | + Represents writing to a local variable in a context that doesn't have an explicit value. + + foo, bar = baz + ^^^ ^^^ + - name: LocalVariableWriteNode + fields: + - name: name + type: constant + comment: | + The name of the local variable, which is an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). + + foo = :bar # name `:foo` + + abc = 123 # name `:abc` + - name: depth + type: uint32 + comment: | + The number of semantic scopes we have to traverse to find the declaration of this variable. + + foo = 1 # depth 0 + + tap { foo = 1 } # depth 1 + + The specific rules for calculating the depth may differ from individual Ruby implementations, as they are not specified by the language. For more information, see [the Prism documentation](https://github.com/ruby/prism/blob/main/docs/local_variable_depth.md). + - name: name_loc + type: location + comment: | + The location of the variable name. + + foo = :bar + ^^^ + - name: value + type: node + kind: non-void expression + comment: | + The value to write to the local variable. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + foo = :bar + ^^^^ + + abc = 1234 + ^^^^ + + Note that since the name of a local variable is known before the value is parsed, it is valid for a local variable to appear within the value of its own write. + + foo = foo + - name: operator_loc + type: location + comment: | + The location of the `=` operator. + + x = :y + ^ + comment: | + Represents writing to a local variable. + + foo = 1 + ^^^^^^^ + - name: MatchLastLineNode + flags: RegularExpressionFlags + fields: + - name: opening_loc + type: location + - name: content_loc + type: location + - name: closing_loc + type: location + - name: unescaped + type: string + comment: | + Represents a regular expression literal used in the predicate of a conditional to implicitly match against the last line read by an IO object. + + if /foo/i then end + ^^^^^^ + - name: MatchPredicateNode + fields: + - name: value + type: node + kind: non-void expression + - name: pattern + type: node + kind: pattern expression + - name: operator_loc + type: location + comment: | + Represents the use of the modifier `in` operator. + + foo in bar + ^^^^^^^^^^ + - name: MatchRequiredNode + fields: + - name: value + type: node + kind: non-void expression + - name: pattern + type: node + kind: pattern expression + - name: operator_loc + type: location + comment: | + Represents the use of the `=>` operator. + + foo => bar + ^^^^^^^^^^ + - name: MatchWriteNode + fields: + - name: call + type: node + kind: CallNode + - name: targets + type: node[] + kind: LocalVariableTargetNode + comment: | + Represents writing local variables using a regular expression match with named capture groups. + + /(?bar)/ =~ baz + ^^^^^^^^^^^^^^^^^^^^ + - name: MissingNode + comment: | + Represents a node that is missing from the source and results in a syntax error. + - name: ModuleNode + fields: + - name: locals + type: constant[] + - name: module_keyword_loc + type: location + - name: constant_path + type: node + kind: + - ConstantReadNode + - ConstantPathNode + - on error: MissingNode # module Parent module end + - name: body + type: node? + kind: + - StatementsNode + - BeginNode + - name: end_keyword_loc + type: location + - name: name + type: constant + comment: | + Represents a module declaration involving the `module` keyword. + + module Foo end + ^^^^^^^^^^^^^^ + - name: MultiTargetNode + fields: + - name: lefts + type: node[] + kind: + - LocalVariableTargetNode + - InstanceVariableTargetNode + - ClassVariableTargetNode + - GlobalVariableTargetNode + - ConstantTargetNode + - ConstantPathTargetNode + - CallTargetNode + - IndexTargetNode + - MultiTargetNode + - RequiredParameterNode # def m((a,b)); end + - on error: BackReferenceReadNode # a, (b, $&) = z + - on error: NumberedReferenceReadNode # a, (b, $1) = z + comment: | + Represents the targets expressions before a splat node. + + a, (b, c, *) = 1, 2, 3, 4, 5 + ^^^^ + + The splat node can be absent, in that case all target expressions are in the left field. + + a, (b, c) = 1, 2, 3, 4, 5 + ^^^^ + - name: rest + type: node? + kind: + - ImplicitRestNode + - SplatNode + comment: | + Represents a splat node in the target expression. + + a, (b, *c) = 1, 2, 3, 4 + ^^ + + The variable can be empty, this results in a `SplatNode` with a `nil` expression field. + + a, (b, *) = 1, 2, 3, 4 + ^ + + If the `*` is omitted, this field will contain an `ImplicitRestNode` + + a, (b,) = 1, 2, 3, 4 + ^ + - name: rights + type: node[] + kind: + - LocalVariableTargetNode + - InstanceVariableTargetNode + - ClassVariableTargetNode + - GlobalVariableTargetNode + - ConstantTargetNode + - ConstantPathTargetNode + - CallTargetNode + - IndexTargetNode + - MultiTargetNode + - RequiredParameterNode # def m((*,b)); end + - on error: BackReferenceReadNode # a, (*, $&) = z + - on error: NumberedReferenceReadNode # a, (*, $1) = z + comment: | + Represents the targets expressions after a splat node. + + a, (*, b, c) = 1, 2, 3, 4, 5 + ^^^^ + - name: lparen_loc + type: location? + comment: | + The location of the opening parenthesis. + + a, (b, c) = 1, 2, 3 + ^ + - name: rparen_loc + type: location? + comment: | + The location of the closing parenthesis. + + a, (b, c) = 1, 2, 3 + ^ + comment: | + Represents a multi-target expression. + + a, (b, c) = 1, 2, 3 + ^^^^^^ + + This can be a part of `MultiWriteNode` as above, or the target of a `for` loop + + for a, b in [[1, 2], [3, 4]] + ^^^^ + - name: MultiWriteNode + fields: + - name: lefts + type: node[] + kind: + - LocalVariableTargetNode + - InstanceVariableTargetNode + - ClassVariableTargetNode + - GlobalVariableTargetNode + - ConstantTargetNode + - ConstantPathTargetNode + - CallTargetNode + - IndexTargetNode + - MultiTargetNode + - on error: BackReferenceReadNode # $&, = z + - on error: NumberedReferenceReadNode # $1, = z + comment: | + Represents the targets expressions before a splat node. + + a, b, * = 1, 2, 3, 4, 5 + ^^^^ + + The splat node can be absent, in that case all target expressions are in the left field. + + a, b, c = 1, 2, 3, 4, 5 + ^^^^^^^ + - name: rest + type: node? + kind: + - ImplicitRestNode + - SplatNode + comment: | + Represents a splat node in the target expression. + + a, b, *c = 1, 2, 3, 4 + ^^ + + The variable can be empty, this results in a `SplatNode` with a `nil` expression field. + + a, b, * = 1, 2, 3, 4 + ^ + + If the `*` is omitted, this field will contain an `ImplicitRestNode` + + a, b, = 1, 2, 3, 4 + ^ + - name: rights + type: node[] + kind: + - LocalVariableTargetNode + - InstanceVariableTargetNode + - ClassVariableTargetNode + - GlobalVariableTargetNode + - ConstantTargetNode + - ConstantPathTargetNode + - CallTargetNode + - IndexTargetNode + - MultiTargetNode + - on error: BackReferenceReadNode # *, $& = z + - on error: NumberedReferenceReadNode # *, $1 = z + comment: | + Represents the targets expressions after a splat node. + + a, *, b, c = 1, 2, 3, 4, 5 + ^^^^ + - name: lparen_loc + type: location? + comment: | + The location of the opening parenthesis. + + (a, b, c) = 1, 2, 3 + ^ + - name: rparen_loc + type: location? + comment: | + The location of the closing parenthesis. + + (a, b, c) = 1, 2, 3 + ^ + - name: operator_loc + type: location + comment: | + The location of the operator. + + a, b, c = 1, 2, 3 + ^ + - name: value + type: node + kind: non-void expression + comment: | + The value to write to the targets. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + a, b, c = 1, 2, 3 + ^^^^^^^ + comment: | + Represents a write to a multi-target expression. + + a, b, c = 1, 2, 3 + ^^^^^^^^^^^^^^^^^ + - name: NextNode + fields: + - name: arguments + type: node? + kind: ArgumentsNode + - name: keyword_loc + type: location + comment: | + Represents the use of the `next` keyword. + + next 1 + ^^^^^^ + - name: NilNode + comment: | + Represents the use of the `nil` keyword. + + nil + ^^^ + - name: NoKeywordsParameterNode + fields: + - name: operator_loc + type: location + - name: keyword_loc + type: location + comment: | + Represents the use of `**nil` inside method arguments. + + def a(**nil) + ^^^^^ + end + - name: NumberedParametersNode + fields: + - name: maximum + type: uint8 + comment: | + Represents an implicit set of parameters through the use of numbered parameters within a block or lambda. + + -> { _1 + _2 } + ^^^^^^^^^^^^^^ + - name: NumberedReferenceReadNode + fields: + - name: number + type: uint32 + comment: | + The (1-indexed, from the left) number of the capture group. Numbered references that are too large result in this value being `0`. + + $1 # number `1` + + $5432 # number `5432` + + $4294967296 # number `0` + comment: | + Represents reading a numbered reference to a capture in the previous match. + + $1 + ^^ + - name: OptionalKeywordParameterNode + flags: ParameterFlags + fields: + - name: name + type: constant + - name: name_loc + type: location + - name: value + type: node + kind: non-void expression + comment: | + Represents an optional keyword parameter to a method, block, or lambda definition. + + def a(b: 1) + ^^^^ + end + - name: OptionalParameterNode + flags: ParameterFlags + fields: + - name: name + type: constant + - name: name_loc + type: location + - name: operator_loc + type: location + - name: value + type: node + kind: non-void expression + comment: | + Represents an optional parameter to a method, block, or lambda definition. + + def a(b = 1) + ^^^^^ + end + - name: OrNode + fields: + - name: left + type: node + kind: non-void expression + comment: | + Represents the left side of the expression. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + left or right + ^^^^ + + 1 || 2 + ^ + - name: right + type: node + kind: Node + comment: | + Represents the right side of the expression. + + left || right + ^^^^^ + + 1 or 2 + ^ + - name: operator_loc + type: location + comment: | + The location of the `or` keyword or the `||` operator. + + left or right + ^^ + comment: | + Represents the use of the `||` operator or the `or` keyword. + + left or right + ^^^^^^^^^^^^^ + - name: ParametersNode + fields: + - name: requireds + type: node[] + kind: + - RequiredParameterNode + - MultiTargetNode + - name: optionals + type: node[] + kind: OptionalParameterNode + - name: rest + type: node? + kind: + - RestParameterNode + - ImplicitRestNode # Only in block parameters + - name: posts + type: node[] + kind: + - RequiredParameterNode + - MultiTargetNode + # On parsing error of `f(**kwargs, ...)` or `f(**nil, ...)`, the keyword_rest value is moved here: + - on error: KeywordRestParameterNode + - on error: NoKeywordsParameterNode + # On parsing error of `f(..., ...)`, the first forwarding parameter is moved here: + - on error: ForwardingParameterNode + - name: keywords + type: node[] + kind: + - RequiredKeywordParameterNode + - OptionalKeywordParameterNode + - name: keyword_rest + type: node? + kind: + - KeywordRestParameterNode + - ForwardingParameterNode + - NoKeywordsParameterNode + - name: block + type: node? + kind: BlockParameterNode + comment: | + Represents the list of parameters on a method, block, or lambda definition. + + def a(b, c, d) + ^^^^^^^ + end + - name: ParenthesesNode + flags: ParenthesesNodeFlags + fields: + - name: body + type: node? + kind: non-void expression # Usually a StatementsNode but not always e.g. `1 in (..10)` + - name: opening_loc + type: location + - name: closing_loc + type: location + newline: false + comment: | + Represents a parenthesized expression + + (10 + 34) + ^^^^^^^^^ + - name: PinnedExpressionNode + fields: + - name: expression + type: node + kind: non-void expression + - name: operator_loc + type: location + - name: lparen_loc + type: location + - name: rparen_loc + type: location + comment: | + Represents the use of the `^` operator for pinning an expression in a pattern matching expression. + + foo in ^(bar) + ^^^^^^ + - name: PinnedVariableNode + fields: + - name: variable + type: node + kind: + - LocalVariableReadNode + - InstanceVariableReadNode + - ClassVariableReadNode + - GlobalVariableReadNode # foo in ^$a + - BackReferenceReadNode # foo in ^$& + - NumberedReferenceReadNode # foo in ^$1 + - ItLocalVariableReadNode # proc { 1 in ^it } + - on error: MissingNode # foo in ^Bar + - name: operator_loc + type: location + comment: | + Represents the use of the `^` operator for pinning a variable in a pattern matching expression. + + foo in ^bar + ^^^^ + - name: PostExecutionNode + fields: + - name: statements + type: node? + kind: StatementsNode + - name: keyword_loc + type: location + - name: opening_loc + type: location + - name: closing_loc + type: location + comment: | + Represents the use of the `END` keyword. + + END { foo } + ^^^^^^^^^^^ + - name: PreExecutionNode + fields: + - name: statements + type: node? + kind: StatementsNode + - name: keyword_loc + type: location + - name: opening_loc + type: location + - name: closing_loc + type: location + comment: | + Represents the use of the `BEGIN` keyword. + + BEGIN { foo } + ^^^^^^^^^^^^^ + - name: ProgramNode + fields: + - name: locals + type: constant[] + - name: statements + type: node + kind: StatementsNode + comment: The top level node of any parse tree. + - name: RangeNode + flags: RangeFlags + fields: + - name: left + type: node? + kind: non-void expression + comment: | + The left-hand side of the range, if present. It can be either `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + 1... + ^ + + hello...goodbye + ^^^^^ + - name: right + type: node? + kind: non-void expression + comment: | + The right-hand side of the range, if present. It can be either `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + ..5 + ^ + + 1...foo + ^^^ + If neither right-hand or left-hand side was included, this will be a MissingNode. + - name: operator_loc + type: location + comment: | + The location of the `..` or `...` operator. + comment: | + Represents the use of the `..` or `...` operators. + + 1..2 + ^^^^ + + c if a =~ /left/ ... b =~ /right/ + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + - name: RationalNode + flags: IntegerBaseFlags + fields: + - name: numerator + type: integer + comment: | + The numerator of the rational number. + + 1.5r # numerator 3 + - name: denominator + type: integer + comment: | + The denominator of the rational number. + + 1.5r # denominator 2 + comment: | + Represents a rational number literal. + + 1.0r + ^^^^ + - name: RedoNode + comment: | + Represents the use of the `redo` keyword. + + redo + ^^^^ + - name: RegularExpressionNode + flags: RegularExpressionFlags + fields: + - name: opening_loc + type: location + - name: content_loc + type: location + - name: closing_loc + type: location + - name: unescaped + type: string + comment: | + Represents a regular expression literal with no interpolation. + + /foo/i + ^^^^^^ + - name: RequiredKeywordParameterNode + flags: ParameterFlags + fields: + - name: name + type: constant + - name: name_loc + type: location + comment: | + Represents a required keyword parameter to a method, block, or lambda definition. + + def a(b: ) + ^^ + end + - name: RequiredParameterNode + flags: ParameterFlags + fields: + - name: name + type: constant + comment: | + Represents a required parameter to a method, block, or lambda definition. + + def a(b) + ^ + end + - name: RescueModifierNode + fields: + - name: expression + type: node + kind: Node + - name: keyword_loc + type: location + - name: rescue_expression + type: node + kind: Node + newline: expression + comment: | + Represents an expression modified with a rescue. + + foo rescue nil + ^^^^^^^^^^^^^^ + - name: RescueNode + fields: + - name: keyword_loc + type: location + - name: exceptions + type: node[] + kind: non-void expression + - name: operator_loc + type: location? + - name: reference + type: node? + kind: + - LocalVariableTargetNode + - InstanceVariableTargetNode + - ClassVariableTargetNode + - GlobalVariableTargetNode + - ConstantTargetNode + - ConstantPathTargetNode + - CallTargetNode + - IndexTargetNode + - on error: BackReferenceReadNode # => begin; rescue => $&; end + - on error: NumberedReferenceReadNode # => begin; rescue => $1; end + - on error: MissingNode # begin; rescue =>; end + - name: then_keyword_loc + type: location? + - name: statements + type: node? + kind: StatementsNode + - name: subsequent + type: node? + kind: RescueNode + comment: | + Represents a rescue statement. + + begin + rescue Foo, *splat, Bar => ex + foo + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + end + + `Foo, *splat, Bar` are in the `exceptions` field. `ex` is in the `reference` field. + - name: RestParameterNode + flags: ParameterFlags + fields: + - name: name + type: constant? + - name: name_loc + type: location? + - name: operator_loc + type: location + comment: | + Represents a rest parameter to a method, block, or lambda definition. + + def a(*b) + ^^ + end + - name: RetryNode + comment: | + Represents the use of the `retry` keyword. + + retry + ^^^^^ + - name: ReturnNode + fields: + - name: keyword_loc + type: location + - name: arguments + type: node? + kind: ArgumentsNode + comment: | + Represents the use of the `return` keyword. + + return 1 + ^^^^^^^^ + - name: SelfNode + comment: | + Represents the `self` keyword. + + self + ^^^^ + - name: ShareableConstantNode + flags: ShareableConstantNodeFlags + fields: + - name: write + type: node + kind: + - ConstantWriteNode + - ConstantAndWriteNode + - ConstantOrWriteNode + - ConstantOperatorWriteNode + - ConstantPathWriteNode + - ConstantPathAndWriteNode + - ConstantPathOrWriteNode + - ConstantPathOperatorWriteNode + comment: The constant write that should be modified with the shareability state. + comment: | + This node wraps a constant write to indicate that when the value is written, it should have its shareability state modified. + + # shareable_constant_value: literal + C = { a: 1 } + ^^^^^^^^^^^^ + - name: SingletonClassNode + fields: + - name: locals + type: constant[] + - name: class_keyword_loc + type: location + - name: operator_loc + type: location + - name: expression + type: node + kind: non-void expression + - name: body + type: node? + kind: + - StatementsNode + - BeginNode + - name: end_keyword_loc + type: location + comment: | + Represents a singleton class declaration involving the `class` keyword. + + class << self end + ^^^^^^^^^^^^^^^^^ + - name: SourceEncodingNode + comment: | + Represents the use of the `__ENCODING__` keyword. + + __ENCODING__ + ^^^^^^^^^^^^ + - name: SourceFileNode + flags: StringFlags + fields: + - name: filepath + type: string + comment: Represents the file path being parsed. This corresponds directly to the `filepath` option given to the various `Prism::parse*` APIs. + comment: | + Represents the use of the `__FILE__` keyword. + + __FILE__ + ^^^^^^^^ + - name: SourceLineNode + comment: | + Represents the use of the `__LINE__` keyword. + + __LINE__ + ^^^^^^^^ + - name: SplatNode + fields: + - name: operator_loc + type: location + - name: expression + type: node? + kind: non-void expression + comment: | + Represents the use of the splat operator. + + [*a] + ^^ + - name: StatementsNode + fields: + - name: body + type: node[] + kind: Node + comment: | + Represents a set of statements contained within some scope. + + foo; bar; baz + ^^^^^^^^^^^^^ + - name: StringNode + flags: StringFlags + fields: + - name: opening_loc + type: location? + - name: content_loc + type: location + - name: closing_loc + type: location? + - name: unescaped + type: string + comment: | + Represents a string literal, a string contained within a `%w` list, or plain string content within an interpolated string. + + "foo" + ^^^^^ + + %w[foo] + ^^^ + + "foo #{bar} baz" + ^^^^ ^^^^ + - name: SuperNode + fields: + - name: keyword_loc + type: location + - name: lparen_loc + type: location? + - name: arguments + type: node? + kind: ArgumentsNode + - name: rparen_loc + type: location? + - name: block + type: node? + kind: + - BlockNode + - BlockArgumentNode + comment: | + Represents the use of the `super` keyword with parentheses or arguments. + + super() + ^^^^^^^ + + super foo, bar + ^^^^^^^^^^^^^^ + - name: SymbolNode + flags: SymbolFlags + fields: + - name: opening_loc + type: location? + - name: value_loc + type: location? + - name: closing_loc + type: location? + - name: unescaped + type: string + comment: | + Represents a symbol literal or a symbol contained within a `%i` list. + + :foo + ^^^^ + + %i[foo] + ^^^ + - name: TrueNode + comment: | + Represents the use of the literal `true` keyword. + + true + ^^^^ + - name: UndefNode + fields: + - name: names + type: node[] + kind: + - SymbolNode + - InterpolatedSymbolNode + - name: keyword_loc + type: location + comment: | + Represents the use of the `undef` keyword. + + undef :foo, :bar, :baz + ^^^^^^^^^^^^^^^^^^^^^^ + - name: UnlessNode + fields: + - name: keyword_loc + type: location + comment: | + The location of the `unless` keyword. + + unless cond then bar end + ^^^^^^ + + bar unless cond + ^^^^^^ + - name: predicate + type: node + kind: non-void expression + comment: | + The condition to be evaluated for the unless expression. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + + unless cond then bar end + ^^^^ + + bar unless cond + ^^^^ + - name: then_keyword_loc + type: location? + comment: | + The location of the `then` keyword, if present. + + unless cond then bar end + ^^^^ + - name: statements + type: node? + kind: StatementsNode + comment: | + The body of statements that will executed if the unless condition is + falsey. Will be `nil` if no body is provided. + + unless cond then bar end + ^^^ + - name: else_clause + type: node? + kind: ElseNode + comment: | + The else clause of the unless expression, if present. + + unless cond then bar else baz end + ^^^^^^^^ + - name: end_keyword_loc + type: location? + comment: | + The location of the `end` keyword, if present. + + unless cond then bar end + ^^^ + newline: predicate + comment: | + Represents the use of the `unless` keyword, either in the block form or the modifier form. + + bar unless foo + ^^^^^^^^^^^^^^ + + unless foo then bar end + ^^^^^^^^^^^^^^^^^^^^^^^ + - name: UntilNode + flags: LoopFlags + fields: + - name: keyword_loc + type: location + - name: do_keyword_loc + type: location? + - name: closing_loc + type: location? + - name: predicate + type: node + kind: non-void expression + - name: statements + type: node? + kind: StatementsNode + newline: predicate + comment: | + Represents the use of the `until` keyword, either in the block form or the modifier form. + + bar until foo + ^^^^^^^^^^^^^ + + until foo do bar end + ^^^^^^^^^^^^^^^^^^^^ + - name: WhenNode + fields: + - name: keyword_loc + type: location + - name: conditions + type: node[] + kind: non-void expression + - name: then_keyword_loc + type: location? + - name: statements + type: node? + kind: StatementsNode + comment: | + Represents the use of the `when` keyword within a case statement. + + case true + when true + ^^^^^^^^^ + end + - name: WhileNode + flags: LoopFlags + fields: + - name: keyword_loc + type: location + - name: do_keyword_loc + type: location? + - name: closing_loc + type: location? + - name: predicate + type: node + kind: non-void expression + - name: statements + type: node? + kind: StatementsNode + newline: predicate + comment: | + Represents the use of the `while` keyword, either in the block form or the modifier form. + + bar while foo + ^^^^^^^^^^^^^ + + while foo do bar end + ^^^^^^^^^^^^^^^^^^^^ + - name: XStringNode + flags: EncodingFlags + fields: + - name: opening_loc + type: location + - name: content_loc + type: location + - name: closing_loc + type: location + - name: unescaped + type: string + comment: | + Represents an xstring literal with no interpolation. + + `foo` + ^^^^^ + - name: YieldNode + fields: + - name: keyword_loc + type: location + - name: lparen_loc + type: location? + - name: arguments + type: node? + kind: ArgumentsNode + - name: rparen_loc + type: location? + comment: | + Represents the use of the `yield` keyword. + + yield 1 + ^^^^^^^ diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/build_system.md b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/build_system.md new file mode 100644 index 00000000..98581f38 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/build_system.md @@ -0,0 +1,119 @@ +# Build System + +There are many ways to build prism, which means the build system is a bit more complicated than usual. + +## Requirements + +* It must work to build prism for all 6 uses-cases below. +* It must be possible to build prism without needing ruby/rake/etc. + Because once prism is the single parser in TruffleRuby, JRuby or CRuby there won't be another Ruby parser around to parse such Ruby code. + Most/every Ruby implementations want to avoid depending on another Ruby during the build process as that is very brittle. +* It is desirable to compile prism with the same or very similar compiler flags for all use-cases (e.g. optimization level, warning flags, etc). + Otherwise, there is the risk prism does not work correctly with those different compiler flags. + +The main solution for the second point seems a Makefile, otherwise many of the usages would have to duplicate the logic to build prism. + +## General Design + +1. Templates are generated by `templates/template.rb` +2. The `Makefile` compiles both `libprism.a` and `libprism.{so,dylib,dll}` from the `src/**/*.c` and `include/**/*.h` files +3. The `Rakefile` `:compile` task ensures the above prerequisites are done, then calls `make`, + and uses `Rake::ExtensionTask` to compile the C extension (using its `extconf.rb`) + +This way there is minimal duplication, and each layer builds on the previous one and has its own responsibilities. + +The static library exports no symbols, to avoid any conflict. +The shared library exports some symbols, and this is fine since there should only be one libprism shared library +loaded per process (i.e., at most one version of the prism *gem* loaded in a process, only the gem uses the shared library). + +## The various ways to build prism + +### Building from ruby/prism repository with `bundle exec rake` + +`rake` calls `make` and then uses `Rake::ExtensionTask` to compile the C extension (see above). + +### Building the prism gem by `gem install/bundle install` + +The gem contains the pre-generated templates. + +When installing the gem on CRuby, `extconf.rb` is used and that compiles the C extension with mkmf, including both the extension files and the sources of prism itself. + +When installing the gem on JRuby and TruffleRuby, no C extension is built, so instead the `extconf.rb` runs `make build/libprism.{so,dylib,dll}`. +There is Ruby code using FFI which uses `libprism.{so,dylib,dll}` to implement the same methods as the C extension, but using serialization instead of many native calls/accesses (JRuby does not support C extensions, serialization is faster on TruffleRuby than the C extension). + +### Building the prism gem from git, e.g. `gem "prism", github: "ruby/prism"` + +The same as above, except the `extconf.rb` additionally runs first: +* `templates/template.rb` to generate the templates + +Because of course those files are not part of the git repository. + +### Building prism as part of CRuby + +[This script](https://github.com/ruby/ruby/blob/5124f9ac7513eb590c37717337c430cb93caa151/tool/sync_default_gems.rb#L399-L422) imports prism sources in CRuby. + +The script generates the templates when importing. + +prism's `Makefile` is not used at all in CRuby. Instead, CRuby's `Makefile` is used. + +### Building prism as part of TruffleRuby + +[This script](https://github.com/oracle/truffleruby/blob/master/tool/import-prism.sh) imports prism sources in TruffleRuby. +The script generates the templates when importing. + +Then when `mx build` builds TruffleRuby and the `prism` mx project inside, it runs `make`. + +Then the `prism bindings` mx project is built, which contains the [bindings](https://github.com/oracle/truffleruby/blob/vm-24.1.1/src/main/c/yarp_bindings/src/yarp_bindings.c) +and links to `libprism.a` (to avoid exporting symbols, so no conflict when installing the prism gem). + +### Building prism as part of JRuby + +TODO, similar to TruffleRuby. + +### Building prism for embedded system + +For instance, you can build a static library `libprism.a` targeting the Arm Cortex-M0+ embedded system by the commands below: + +* `templates/template.rb` +* `CFLAGS="-mcpu=cortex-m0plus" make static CC=arm-none-eabi-gcc` + +The build process internally looks up `_POSIX_MAPPED_FILES` and `_WIN32` macros to determine whether the functions of the memory map are available on the target platform. + +### Building prism with custom memory allocator + +If you need to use memory allocation functions implemented outside of the standard library, follow these steps: + +* Add `-D PRISM_XALLOCATOR` to the build options +* Additionally, include `-I [path/to/custom_allocator]` where your `prism_xallocator.h` is located +* Link the implementation of `prism_xallocator.c` that contains functions declared in `prism_xallocator.h` + +For further clarity, refer to `include/prism/defines.h`. + +### Building prism from source as a C library + +All of the source files match `src/**/*.c` and all of the headers match `include/**/*.h`. + +If you want to build prism as a shared library and link against it, you should compile with: + +* `-fPIC -shared` - Compile as a shared library +* `-DPRISM_EXPORT_SYMBOLS` - Export the symbols (by default nothing is exported) + +#### Flags + +`make` respects the `MAKEFLAGS` environment variable. As such, to speed up the build you can run: + +``` +MAKEFLAGS="-j10" bundle exec rake compile +``` + +## Build options + +* `PRISM_BUILD_DEBUG` - Will cause all file reading to copy into its own allocation to allow easier tracking of reading off the end of the buffer. By default this is off. +* `PRISM_BUILD_MINIMAL` - Define all of the `PRISM_EXCLUDE_*` flags at once. +* `PRISM_ENCODING_EXCLUDE_FULL` - Will cause the library to exclude the full encoding API, and only include the minimal number of encodings to support parsing Ruby code without encoding comments. By default this is off. +* `PRISM_EXPORT_SYMBOLS` - Will cause the shared library to export symbols. By default this is off. +* `PRISM_EXCLUDE_JSON` - Will cause the library to exclude the JSON API. By default this is off. +* `PRISM_EXCLUDE_PACK` - Will cause the library to exclude the pack API. By default this is off. +* `PRISM_EXCLUDE_PRETTYPRINT` - Will cause the library to exclude the prettyprint API. By default this is off. +* `PRISM_EXCLUDE_SERIALIZATION` - Will cause the library to exclude the serialization API. By default this is off. +* `PRISM_XALLOCATOR` - Will cause the library to use the custom memory allocator. By default this is off. diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/configuration.md b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/configuration.md new file mode 100644 index 00000000..2e3ff025 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/configuration.md @@ -0,0 +1,68 @@ +# Configuration + +A lot of code in prism's repository is templated from a single configuration file, [config.yml](../config.yml). This file is used to generate the following files: + +* `ext/prism/api_node.c` - for defining how to build Ruby objects for the nodes out of C structs +* `include/prism/ast.h` - for defining the C structs that represent the nodes +* `include/prism/diagnostic.h` - for defining the diagnostics +* `javascript/src/deserialize.js` - for defining how to deserialize the nodes in JavaScript +* `javascript/src/nodes.js` - for defining the nodes in JavaScript +* `java/org/prism/AbstractNodeVisitor.java` - for defining the visitor interface for the nodes in Java +* `java/org/prism/Loader.java` - for defining how to deserialize the nodes in Java +* `java/org/prism/Nodes.java` - for defining the nodes in Java +* `lib/prism/compiler.rb` - for defining the compiler for the nodes in Ruby +* `lib/prism/dispatcher.rb` - for defining the dispatch visitors for the nodes in Ruby +* `lib/prism/dot_visitor.rb` - for defining the dot visitor for the nodes in Ruby +* `lib/prism/dsl.rb` - for defining the DSL for the nodes in Ruby +* `lib/prism/inspect_visitor.rb` - for defining the `#inspect` methods on nodes in Ruby +* `lib/prism/mutation_compiler.rb` - for defining the mutation compiler for the nodes in Ruby +* `lib/prism/node.rb` - for defining the nodes in Ruby +* `lib/prism/reflection.rb` - for defining the reflection API in Ruby +* `lib/prism/serialize.rb` - for defining how to deserialize the nodes in Ruby +* `lib/prism/visitor.rb` - for defining the visitor interface for the nodes in Ruby +* `src/diagnostic.c` - for defining how to build diagnostics +* `src/node.c` - for defining how to free the nodes in C and calculate the size in memory in C +* `src/prettyprint.c` - for defining how to prettyprint the nodes in C +* `src/serialize.c` - for defining how to serialize the nodes in C +* `src/token_type.c` - for defining the names of the token types + +Whenever the structure of the nodes changes, you can run `rake templates` to regenerate these files. Alternatively tasks like `rake test` should pick up on these changes automatically. Every file that is templated will include a comment at the top indicating that it was generated and that changes should be made to the template and not the generated file. + +`config.yml` has a couple of top level fields, which we'll describe below. + +## `tokens` + +This is a list of tokens to be used by the lexer. It is shared here so that it can be templated out into both an enum and a function that is used for debugging that returns the name of the token. + +Each token is expected to have a `name` key and a `comment` key (both as strings). Optionally they can have a `value` key (an integer) which is used to represent the value in the enum. + +In C these tokens will be templated out with the prefix `PM_TOKEN_`. For example, if you have a `name` key with the value `PERCENT`, you can access this in C through `PM_TOKEN_PERCENT`. + +## `flags` + +Sometimes we need to communicate more information in the tree than can be represented by the types of the nodes themselves. For example, we need to represent the flags passed to a regular expression or the type of call that a call node is performing. In these circumstances, it's helpful to reference a bitset of flags. This field is a list of flags that can be used in the nodes. + +Each flag is expected to have a `name` key (a string) and a `values` key (an array). Each value in the `values` key should be an object that contains both a `name` key (a string) that represents the name of the flag and a `comment` key (a string) that represents the comment for the flag. + +In C these flags will get templated out with a `PM_` prefix, then a snake-case version of the flag name, then the flag itself. For example, if you have a flag with the name `RegularExpressionFlags` and a value with the name `IGNORE_CASE`, you can access this in C through `PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE`. + +## `nodes` + +Every node in the tree is defined in `config.yml`. Each node is expected to have a `name` key (a string) and a `comment` key (a string). By convention, the `comment` key uses the multi-line syntax of `: |` because the newlines will get templated into the comments of various files. + +Optionally, every node can define a `child_nodes` key that is an array. This array represents each part of the node that isn't communicated through the type and location of the node itself. Within the `child_nodes` key, each entry should be an object with a `name` key (a string) and a `type` key (a string). The `name` key represents the name of the child node and the `type` is used to determine how it should be represented in each language. + +The available values for `type` are: + +* `node` - A field that is a node. This is a `pm_node_t *` in C. +* `node?` - A field that is a node that is optionally present. This is also a `pm_node_t *` in C, but can be `NULL`. +* `node[]` - A field that is an array of nodes. This is a `pm_node_list_t` in C. +* `string` - A field that is a string. For example, this is used as the name of the method in a call node, since it cannot directly reference the source string (as in `@-` or `foo=`). This is a `pm_string_t` in C. +* `constant` - A field that is an integer that represents an index in the constant pool. This is a `pm_constant_id_t` in C. +* `constant[]` - A field that is an array of constants. This is a `pm_constant_id_list_t` in C. +* `location` - A field that is a location. This is a `pm_location_t` in C. +* `location?` - A field that is a location that is optionally present. This is a `pm_location_t` in C, but if the value is not present then the `start` and `end` fields will be `NULL`. +* `uint8` - A field that is an 8-bit unsigned integer. This is a `uint8_t` in C. +* `uint32` - A field that is a 32-bit unsigned integer. This is a `uint32_t` in C. + +If the type is `node` or `node?` then the value also accepts an optional `kind` key (a string). This key is expected to match to the name of another node type within `config.yml`. This changes a couple of places where code is templated out to use the more specific struct name instead of the generic `pm_node_t`. For example, with `kind: StatementsNode` the `pm_node_t *` in C becomes a `pm_statements_node_t *`. diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/cruby_compilation.md b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/cruby_compilation.md new file mode 100644 index 00000000..8440e905 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/cruby_compilation.md @@ -0,0 +1,27 @@ +# Compiling Prism's AST + +One important class of consumers of Prism's AST is compilers. Currently [CRuby](https://github.com/ruby/ruby), [JRuby](https://github.com/jruby/jruby), [TruffleRuby](https://github.com/oracle/truffleruby), and [Natalie](https://github.com/natalie-lang/natalie) have all built compilation code on top of Prism's AST. + +This document will describe, at a high level, how CRuby's compilation of Prism's AST works. + +As described in the [build system documentation](build_system.md), there is a "push" Webhook set up within the Prism repo triggered on each new commit to send information about the commit to [git.ruby-lang.org](https://github.com/ruby/git.ruby-lang.org). This in turn runs [a script](https://github.com/ruby/ruby/blob/master/tool/sync_default_gems.rb) to sync over new changes in Prism to their corresponding files in Ruby. Any failures in this sync script will show alerts in the #alerts-sync channel in the RubyLang Slack. The result of this step is that files are synced from Prism into ruby/ruby for its use. It is also worth noting that [`common.mk`](https://github.com/ruby/ruby/blob/master/common.mk) contains a list of Prism files which it needs to correctly compile. If there are new Prism files added, this file should also be updated. + +ruby/ruby uses the Prism code to generate an AST from which it can generate instruction sequences. Compilation in ruby/ruby has three main steps: + +1. Compute an AST + +Syncing over the Prism code allows ruby/ruby to compute the AST using Prism. It currently does this within [`iseq.c`](https://github.com/ruby/ruby/blob/master/iseq.c) using the `pm_parser_init` function. + +2. Run a first pass of compilation + +Once the AST has been created, it is recursively descended in order to compute the appropriate instruction sequences. This is the crux of compilation, and we go into more detail about nuances in the following paragraphs. + +The code for this step is almost exclusively in [`prism_compile.c`](https://github.com/ruby/ruby/blob/master/prism_compile.c). The main function used for compilation is `pm_compile_node` which is essentially a huge switch statement over practically every node type which computes the appropriate instruction sequences for that node type. There are several convenience helpers, such as `PM_COMPILE`, `PM_COMPILE_POPPED`, `PM_COMPILE_NOT_POPPED` which all call into the `pm_compile_node` function. + +There are also several functions, like `parse_string`, `parse_integer` which consume Prism nodes and return CRuby values. These are all called for their relevant types within the big switch statement. + +The Prism compiler also uses a concept of "scope nodes" which are not standard Prism nodes in the AST, but instead nodes constructed within the compiler for the sole purpose of making compilation easier. Scope nodes are defined in [`prism_compile.h`](https://github.com/ruby/ruby/blob/master/prism_compile.h) and store information such as locals, local table size, local depth offset and the index lookup tables. Scope nodes can be generated for node types which have their own "scope". + +3. Run an optimization pass of compilation + +After the instruction sequences are initially computed, there is an existing (non-Prism based) optimization pass of the instruction sequences. There are several optimizations currently inlined into step 2, however, most of them happen in this step. Specifically, any peephole optimizations happen in this step. By the end of step 2, however, the instruction sequences take the same form regardless of if the initial AST was generated by Prism or not. Therefore, step 3 is agnostic to the parser, and should not require any Prism specific code. diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/design.md b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/design.md new file mode 100644 index 00000000..15045a10 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/design.md @@ -0,0 +1,53 @@ +# Design + +There are three overall goals for this project: + +* to provide a documented and maintainable parser +* to provide an error-tolerant parser suitable for use in an IDE +* to provide a portable parser that can be used in projects that don't link against CRuby + +The design of the parser is based around these main goals. + +## Structure + +The first piece to understand about the parser is the design of its syntax tree. This is documented in `config.yml`. Every token and node is defined in that file, along with comments about where they are found in what kinds of syntax. This file is used to template out a lot of different files, all found in the `templates` directory. The `templates/template.rb` script performs the templating and outputs all files matching the directory structure found in the templates directory. + +The templated files contain all of the code required to allocate and initialize nodes, pretty print nodes, and serialize nodes. This means for the most part, you will only need to then hook up the parser to call the templated functions to create the nodes in the correct position. That means editing the parser itself, which is housed in `prism.c`. + +## Pratt parsing + +In order to provide the best possible error tolerance, the parser is hand-written. It is structured using Pratt parsing, a technique developed by Vaughan Pratt back in the 1970s. Below are a bunch of links to articles and papers that explain Pratt parsing in more detail. + +* https://web.archive.org/web/20151223215421/http://hall.org.ua/halls/wizzard/pdf/Vaughan.Pratt.TDOP.pdf +* https://tdop.github.io/ +* https://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/ +* https://matklad.github.io/2020/04/13/simple-but-powerful-pratt-parsing.html +* https://chidiwilliams.com/post/on-recursive-descent-and-pratt-parsing/ + +You can find most of the functions that correspond to constructs in the Pratt parsing algorithm in `prism.c`. As a couple of examples: + +* `parse` corresponds to the `parse_expression` function +* `nud` (null denotation) corresponds to the `parse_expression_prefix` function +* `led` (left denotation) corresponds to the `parse_expression_infix` function +* `lbp` (left binding power) corresponds to accessing the `left` field of an element in the `binding_powers` array +* `rbp` (right binding power) corresponds to accessing the `right` field of an element in the `binding_powers` array + +## Portability + +In order to enable using this parser in other projects, the parser is written in C99, and uses only the standard library. This means it can be embedded in most any other project without having to link against CRuby. It can be used directly through its C API to access individual fields, or it can used to parse a syntax tree and then serialize it to a single blob. For more information on serialization, see the [docs/serialization.md](serialization.md) file. + +## Error tolerance + +The design of the error tolerance of this parser is still very much in flux. We are experimenting with various approaches as the parser is being developed to try to determine the best approach. Below are a bunch of links to articles and papers that explain error tolerance in more detail, as well as document some of the approaches that we're evaluating. + +* https://tratt.net/laurie/blog/2020/automatic_syntax_error_recovery.html +* https://diekmann.uk/diekmann_phd.pdf +* https://eelcovisser.org/publications/2012/JongeKVS12.pdf +* https://www.antlr.org/papers/allstar-techreport.pdf +* https://github.com/microsoft/tolerant-php-parser/blob/main/docs/HowItWorks.md + +Currently, there are a couple of mechanisms for error tolerance that are in place: + +* If the parser expects a token in a particular position (for example the `in` keyword in a for loop or the `{` after `BEGIN` or `END`) then it will insert a missing token if one can't be found and continue parsing. +* If the parser expects an expression in a particular position but encounters a token that can't be used as that expression, it checks up the stack to see if that token would close out a parent node. If so, it will close out all of its parent nodes using missing nodes wherever necessary and continue parsing. +* If the parser cannot understand a token in any capacity, it will skip past the token. diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/encoding.md b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/encoding.md new file mode 100644 index 00000000..a9090a98 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/encoding.md @@ -0,0 +1,121 @@ +# Encoding + +When parsing a Ruby file, there are times when the parser must parse identifiers. Identifiers are names of variables, methods, classes, etc. To determine the start of an identifier, the parser must be able to tell if the subsequent bytes form an alphabetic character. To determine the rest of the identifier, the parser must look forward through all alphanumeric characters. + +Determining if a set of bytes comprise an alphabetic or alphanumeric character is encoding-dependent. By default, the parser assumes that all source files are encoded UTF-8. If the file is not encoded in UTF-8, it must be encoded using an encoding that is "ASCII compatible" (i.e., all of the codepoints below 128 match the corresponding codepoints in ASCII and the minimum number of bytes required to represent a codepoint is 1 byte). + +If the file is not encoded in UTF-8, the user must specify the encoding in a "magic" comment at the top of the file. The comment looks like: + +```ruby +# encoding: iso-8859-9 +``` + +The key of the comment can be either "encoding" or "coding". The value of the comment must be a string that is a valid encoding name. The encodings that prism supports by default are: + +* `ASCII-8BIT` +* `Big5` +* `Big5-HKSCS` +* `Big5-UAO` +* `CESU-8` +* `CP51932` +* `CP850` +* `CP852` +* `CP855` +* `CP949` +* `CP950` +* `CP951` +* `Emacs-Mule` +* `EUC-JP` +* `eucJP-ms` +* `EUC-JIS-2004` +* `EUC-KR` +* `EUC-TW` +* `GB12345` +* `GB18030` +* `GB1988` +* `GB2312` +* `GBK` +* `IBM437` +* `IBM720` +* `IBM737` +* `IBM775` +* `IBM852` +* `IBM855` +* `IBM857` +* `IBM860` +* `IBM861` +* `IBM862` +* `IBM863` +* `IBM864` +* `IBM865` +* `IBM866` +* `IBM869` +* `ISO-8859-1` +* `ISO-8859-2` +* `ISO-8859-3` +* `ISO-8859-4` +* `ISO-8859-5` +* `ISO-8859-6` +* `ISO-8859-7` +* `ISO-8859-8` +* `ISO-8859-9` +* `ISO-8859-10` +* `ISO-8859-11` +* `ISO-8859-13` +* `ISO-8859-14` +* `ISO-8859-15` +* `ISO-8859-16` +* `KOI8-R` +* `KOI8-U` +* `macCentEuro` +* `macCroatian` +* `macCyrillic` +* `macGreek` +* `macIceland` +* `MacJapanese` +* `macRoman` +* `macRomania` +* `macThai` +* `macTurkish` +* `macUkraine` +* `Shift_JIS` +* `SJIS-DoCoMo` +* `SJIS-KDDI` +* `SJIS-SoftBank` +* `stateless-ISO-2022-JP` +* `stateless-ISO-2022-JP-KDDI` +* `TIS-620` +* `US-ASCII` +* `UTF-8` +* `UTF8-MAC` +* `UTF8-DoCoMo` +* `UTF8-KDDI` +* `UTF8-SoftBank` +* `Windows-1250` +* `Windows-1251` +* `Windows-1252` +* `Windows-1253` +* `Windows-1254` +* `Windows-1255` +* `Windows-1256` +* `Windows-1257` +* `Windows-1258` +* `Windows-31J` +* `Windows-874` + +For each of these encodings, prism provides functions for checking if the subsequent bytes can be interpreted as a character, and then if that character is alphabetic, alphanumeric, or uppercase. + +## Getting notified when the encoding changes + +You may want to get notified when the encoding changes based on the result of parsing an encoding comment. We use this internally for our `lex` function in order to provide the correct encodings for the tokens that are returned. For that you can register a callback with `pm_parser_register_encoding_changed_callback`. The callback will be called with a pointer to the parser. The encoding can be accessed through `parser->encoding`. + +```c +// When the encoding that is being used to parse the source is changed by prism, +// we provide the ability here to call out to a user-defined function. +typedef void (*pm_encoding_changed_callback_t)(pm_parser_t *parser); + +// Register a callback that will be called whenever prism changes the encoding +// it is using to parse based on the magic comment. +PRISM_EXPORTED_FUNCTION void +pm_parser_register_encoding_changed_callback(pm_parser_t *parser, pm_encoding_changed_callback_t callback); +``` diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/fuzzing.md b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/fuzzing.md new file mode 100644 index 00000000..b6ec6112 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/fuzzing.md @@ -0,0 +1,88 @@ +# Fuzzing + +We use fuzzing to test the various entrypoints to the library. The fuzzer we use is [AFL++](https://aflplus.plus). All files related to fuzzing live within the `fuzz` directory, which has the following structure: + +``` +fuzz +├── corpus +│   ├── parse fuzzing corpus for parsing (a symlink to our fixtures) +│   └── regexp fuzzing corpus for regexp +├── dict a AFL++ dictionary containing various tokens +├── docker +│   └── Dockerfile for building a container with the fuzzer toolchain +├── fuzz.c generic entrypoint for fuzzing +├── heisenbug.c entrypoint for reproducing a crash or hang +├── parse.c fuzz handler for parsing +├── parse.sh script to run parsing fuzzer +├── regexp.c fuzz handler for regular expression parsing +├── regexp.sh script to run regexp fuzzer +└── tools +    ├── backtrace.sh generates backtrace files for a crash directory +    └── minimize.sh generates minimized crash or hang files +``` + +## Usage + +There are currently three fuzzing targets + +- `pm_serialize_parse` (parse) +- `pm_regexp_parse` (regexp) + +Respectively, fuzzing can be performed with + +``` +make fuzz-run-parse +make fuzz-run-regexp +``` + +To end a fuzzing job, interrupt with CTRL+C. To enter a container with the fuzzing toolchain and debug utilities, run + +``` +make fuzz-debug +``` + +# Out-of-bounds reads + +Currently, encoding functionality implementing the `pm_encoding_t` interface can read outside of inputs. For the time being, ASAN instrumentation is disabled for functions from src/enc. See `fuzz/asan.ignore`. + +To disable ASAN read instrumentation globally, use the `FUZZ_FLAGS` environment variable e.g. + +``` +FUZZ_FLAGS="-mllvm -asan-instrument-reads=false" make fuzz-run-parse +``` + +Note, that this may make reproducing bugs difficult as they may depend on memory outside of the input buffer. In that case, try + +``` +make fuzz-debug # enter the docker container with build tools +make build/fuzz.heisenbug.parse # or .regexp +./build/fuzz.heisenbug.parse path-to-problem-input +``` + +# Triaging Crashes and Hangs + +Triaging crashes and hangs is easier when the inputs are as short as possible. In the fuzz container, an entire crash or hang directory can be minimized using + +``` +./fuzz/tools/minimize.sh +``` + +e.g. +``` +./fuzz/tools/minimize.sh fuzz/output/parse/default/crashes +``` + +This may take a long time. In the crash/hang directory, for each input file there will appear a minimized version with the extension `.min` appended. + +Backtraces for crashes (not hangs) can be generated en masse with + +``` +./fuzz/tools/backtrace.sh +``` + +Files with basename equal to the input file name with extension `.bt` will be created e.g. + +``` +id:000000,sig:06,src:000006+000190,time:8480,execs:18929,op:splice,rep:4 +id:000000,sig:06,src:000006+000190,time:8480,execs:18929,op:splice,rep:4.bt +``` diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/heredocs.md b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/heredocs.md new file mode 100644 index 00000000..ea7e1fcf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/heredocs.md @@ -0,0 +1,36 @@ +# Heredocs + +Heredocs are one of the most complicated pieces of this parser. There are many different forms, there can be multiple open at the same time, and they can be nested. In order to support parsing them, we keep track of a lot of metadata. Below is a basic overview of how it works. + +## 1. Lexing the identifier + +When a heredoc identifier is encountered in the regular process of lexing, we push the `PM_LEX_HEREDOC` mode onto the stack with the following metadata: + +* `ident_start`: A pointer to the start of the identifier for the heredoc. We need this to match against the end of the heredoc. +* `ident_length`: The length of the identifier for the heredoc. We also need this to match. +* `next_start`: A pointer to the place in source that the parser should resume lexing once it has completed this heredoc. + +We also set the special `parser.next_start` field which is a pointer to the place in the source where we should start lexing the next token. This is set to the pointer of the character immediately following the next newline. + +Note that if the `parser.heredoc_end` field is already set, then it means we have already encountered a heredoc on this line. In that case the `parser.next_start` field will be set to the `parser.heredoc_end` field. This is because we want to skip past the previous heredocs on this line and instead lex the body of this heredoc. + +## 2. Lexing the body + +The next time the lexer is asked for a token, it will be in the `PM_LEX_HEREDOC` mode. In this mode we are lexing the body of the heredoc. It will start by checking if the `next_start` field is set. If it is, then this is the first token within the body of the heredoc so we'll start lexing from there. Otherwise we'll start lexing from the end of the previous token. + +Lexing these fields is extremely similar to lexing an interpolated string. The only difference is that we also do an additional check at the beginning of each line to check if we have hit the terminator. + +## 3. Lexing the terminator + +On every newline within the body of a heredoc, we check to see if it matches the terminator followed by a newline or a carriage return and a newline. If it does, then we pop the lex mode off the stack and set a couple of fields on the parser: + +* `next_start`: This is set to the value that we previously stored on the heredoc to indicate where the lexer should resume lexing when it is done with this heredoc. +* `heredoc_end`: This is set to the end of the heredoc. When a newline character is found, this indicates that the lexer should skip past to this next point. + +## 4. Lexing the rest of the line + +Once the heredoc has been lexed, the lexer will resume lexing from the `next_start` field. Lexing will continue until the next newline character. When the next newline character is found, it will check to see if the `heredoc_end` field is set. If it is it will skip to that point, unset the field, and continue lexing. + +## Compatibility with Ripper + +The order in which tokens are emitted is different from that of Ripper. Ripper emits each token in the file in the order in which it appears. prism instead will emit the tokens that makes the most sense for the lexer, using the process described above. Therefore to line things up, `Prism.lex_compat` will shuffle the tokens around to match Ripper's output. diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/javascript.md b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/javascript.md new file mode 100644 index 00000000..2ccd5f82 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/javascript.md @@ -0,0 +1,118 @@ +# JavaScript + +Prism provides bindings to JavaScript out of the box. + +## Node + +To use the package from node, install the `@ruby/prism` dependency: + +```sh +npm install @ruby/prism +``` + +Then import the package: + +```js +import { loadPrism } from "@ruby/prism"; +``` + +Then call the load function to get a parse function: + +```js +const parse = await loadPrism(); +``` + +## Browser + +To use the package from the browser, you will need to do some additional work. The [javascript/example.html](../javascript/example.html) file shows an example of running Prism in the browser. You will need to instantiate the WebAssembly module yourself and then pass it to the `parsePrism` function. + +First, get a shim for WASI since not all browsers support it yet. + +```js +import { WASI } from "https://unpkg.com/@bjorn3/browser_wasi_shim@latest/dist/index.js"; +``` + +Next, import the `parsePrism` function from `@ruby/prism`, either through a CDN or by bundling it with your application. + +```js +import { parsePrism } from "https://unpkg.com/@ruby/prism@latest/src/parsePrism.js"; +``` + +Next, fetch and instantiate the WebAssembly module. You can access it through a CDN or by bundling it with your application. + +```js +const wasm = await WebAssembly.compileStreaming(fetch("https://unpkg.com/@ruby/prism@latest/src/prism.wasm")); +``` + +Next, instantiate the module and initialize WASI. + +```js +const wasi = new WASI([], [], []); +const instance = await WebAssembly.instantiate(wasm, { wasi_snapshot_preview1: wasi.wasiImport }); +wasi.initialize(instance); +``` + +Finally, you can create a function that will parse a string of Ruby code. + +```js +function parse(source) { + return parsePrism(instance.exports, source); +} +``` + +## API + +Now that we have access to a `parse` function, we can use it to parse Ruby code: + +```js +const parseResult = parse("1 + 2"); +``` + +A ParseResult object is very similar to the Prism::ParseResult object from Ruby. It has the same properties: `value`, `comments`, `magicComments`, `errors`, and `warnings`. Here we can serialize the AST to JSON. + +```js +console.log(JSON.stringify(parseResult.value, null, 2)); +``` + +## Visitors + +Prism allows you to traverse the AST of parsed Ruby code using visitors. + +Here's an example of a custom `FooCalls` visitor: + +```js +import { loadPrism, Visitor } from "@ruby/prism" + +const parse = await loadPrism(); +const parseResult = parse("foo()"); + +class FooCalls extends Visitor { + visitCallNode(node) { + if (node.name === "foo") { + // Do something with the node + } + + // Call super so that the visitor continues walking the tree + super.visitCallNode(node); + } +} + +const fooVisitor = new FooCalls(); + +parseResult.value.accept(fooVisitor); +``` + +## Building + +To build the WASM package yourself, first obtain a copy of `wasi-sdk`. You can retrieve this here: . Next, run: + +```sh +make wasm WASI_SDK_PATH=path/to/wasi-sdk +``` + +This will generate `javascript/src/prism.wasm`. From there, you can run the tests to verify everything was generated correctly. + +```sh +cd javascript +node test +``` diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/local_variable_depth.md b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/local_variable_depth.md new file mode 100644 index 00000000..42509c6d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/local_variable_depth.md @@ -0,0 +1,229 @@ +# Local variable depth + +One feature of Prism is that it resolves local variables as it parses. It's necessary to do this because of ambiguities in the grammar. For example, consider the following code: + +```ruby +foo / bar#/ +``` + +If `foo` is a local variable, this is a call to `/` with `bar` as an argument, followed by a comment. If it's not a local variable, this is a method call to `foo` with a regular expression argument. + +"Depth" refers to the number of visible scopes that Prism has to go up to find the declaration of a local variable. +Note that this follows the same scoping rules as Ruby, so a local variable is only visible in the scope it is declared in and in blocks nested in that scope. +The rules for calculating the depth are very important to understand because they may differ from individual Ruby implementations since they are not specified by the language. + +Prism uses the minimum number of scopes, i.e., it only creates scopes when necessary semantically, in other words when there must be distinct scopes (which can be observed through `binding.local_variables`). +That are no "transparent/invisible" scopes in Prism. +Some Ruby implementations use those for some language constructs and need to adjust by maintaining a depth offset. + +Below are the places where a local variable can be written/targeted, along with how the depth is calculated at that point. + +## General + +In the course of general Ruby code when reading a local variable, the depth is equal to the number of scopes to go up to find the declaration of that variable. For example: + +```ruby +foo = 1 +bar = 2 +baz = 3 + +foo # depth 0 +tap { bar } # depth 1 +tap { tap { baz } } # depth 2 +``` + +This also includes writing to a local variable, which could be writing to a local variable that is already declared. For example: + +```ruby +foo = 1 +bar = 2 + +foo = 3 # depth 0 +tap { bar = 4 } # depth 1 +``` + +This includes multiple assignment, where the same principle applies. For example: + +```ruby +foo = 1 +bar = 2 + +foo, bar = 3, 4 # depth 0 +tap { foo, bar = 5, 6 } # depth 1 +``` + +## `for` loops + +`for` loops in Ruby break down to calls to `.each` with a block. +However in that case local variable reads and writes within the block will be in the same scope as the scope surrounding the `for` and not in a deeper/separate scope (surprising, but this is Ruby semantics). +For example: + +```ruby +foo = 1 + +for e in baz + foo # depth 0 + bar = 2 # depth 0 +end + +p bar # depth 0, prints 2 +``` + +The local variable(s) used for the index of the `for` are also at the same depth (as variables inside and outside the `for`): + +```ruby +for e in [1, 2] # depth 0 + e # depth 0 +end + +p e # depth 0, prints 2 +``` + +## Pattern matching captures + +You can target a local variable in a pattern matching expression using capture syntax. Using this syntax, you can target local variables in the current scope or in visible parent scopes. For example: + +```ruby +42 => bar # depth 0 +``` + +The example above writes to a local variable in the current scope. If the variable is already declared in a higher visible scope, it will be written to that scope instead. For example: + +```ruby +foo = 1 +tap { 42 => foo } # depth 1 +``` + +## Named capture groups + +You can target local variables through named capture groups in regular expressions if they are used on the left-hand side of a `=~` operator. For example: + +```ruby +/(?\d+)/ =~ "42" # depth 0 +``` + +This will write to a `foo` local variable. If the variable is already declared in a higher visible scope, it will be written to that scope instead. For example: + +```ruby +foo = 1 +tap { /(?\d+)/ =~ "42" } # depth 1 +``` + +## "interpolated once" regular expressions + +Regular expressions that interpolate local variables (unrelated to capture group local variables) and have the `o` flag will only interpolate the local variables once for the runtime of the program. +In CRuby, this is implemented by compiling the regular expression within a nested instruction sequence, which means CRuby thinks the depth is one more than prism does. For example: + +``` +$ ruby --dump=insns -e 'foo = 1; /#{foo}/o' +== disasm: #@-e:1 (1,0)-(1,18)> (catch: false) +local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1]) +[ 1] foo@0 +0000 putobject_INT2FIX_1_ ( 1)[Li] +0001 setlocal_WC_0 foo@0 +0003 once block in
, +0006 leave + +== disasm: #@-e:1 (1,9)-(1,18)> (catch: false) +0000 putobject "" ( 1) +0002 getlocal_WC_1 foo@0 +0004 dup +0005 objtostring +0007 anytostring +0008 toregexp 0, 2 +0011 leave +``` + +In this case CRuby fetches the local variable with `getlocal_WC_1` as the second instruction to the "once" instruction sequence. When compiling CRuby, prism therefore will adjust the depth to account for this difference. + +## `rescue` clauses + +In CRuby, `rescue` clauses are implemented as their own instruction sequence, and therefore CRuby thinks the depth is one more than prism does. For example: + +``` +$ ruby --dump=insns -e 'begin; foo = 1; rescue; foo; end' +== disasm: #@-e:1 (1,0)-(1,32)> (catch: true) +== catch table +| catch type: rescue st: 0000 ed: 0004 sp: 0000 cont: 0005 +| == disasm: #@-e:1 (1,16)-(1,28)> (catch: true) +| local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1]) +| [ 1] $!@0 +| 0000 getlocal_WC_0 $!@0 ( 1) +| 0002 putobject StandardError +| 0004 checkmatch 3 +| 0006 branchunless 11 +| 0008 getlocal_WC_1 foo@0[Li] +| 0010 leave +| 0011 getlocal_WC_0 $!@0 +| 0013 throw 0 +| catch type: retry st: 0004 ed: 0005 sp: 0000 cont: 0000 +|------------------------------------------------------------------------ +local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1]) +[ 1] foo@0 +0000 putobject_INT2FIX_1_ ( 1)[Li] +0001 dup +0002 setlocal_WC_0 foo@0 +0004 nop +0005 leave +``` + +In the catch table, CRuby is reading the `foo` local variable using `getlocal_WC_1` as the fifth instruction to the "rescue" instruction sequence. When compiling CRuby, prism therefore will adjust the depth to account for this difference. + +Note that this includes the error reference, which can target local variables, as in: + +``` +$ ruby --dump=insns -e 'foo = 1; begin; rescue => foo; end' +== disasm: #@-e:1 (1,0)-(1,34)> (catch: true) +== catch table +| catch type: rescue st: 0003 ed: 0004 sp: 0000 cont: 0005 +| == disasm: #@-e:1 (1,16)-(1,30)> (catch: true) +| local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1]) +| [ 1] $!@0 +| 0000 getlocal_WC_0 $!@0 ( 1) +| 0002 putobject StandardError +| 0004 checkmatch 3 +| 0006 branchunless 14 +| 0008 getlocal_WC_0 $!@0 +| 0010 setlocal_WC_1 foo@0 +| 0012 putnil +| 0013 leave +| 0014 getlocal_WC_0 $!@0 +| 0016 throw 0 +| catch type: retry st: 0004 ed: 0005 sp: 0000 cont: 0003 +|------------------------------------------------------------------------ +local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1]) +[ 1] foo@0 +0000 putobject_INT2FIX_1_ ( 1)[Li] +0001 setlocal_WC_0 foo@0 +0003 putnil +0004 nop +0005 leave +``` + +Note that CRuby is writing to the `foo` local variable using the `setlocal_WC_1` instruction as the sixth instruction to the "rescue" instruction sequence. When compiling CRuby, prism therefore will adjust the depth to account for this difference. + +## Post execution blocks + +The `END {}` syntax allows executing code when the program exits. In CRuby, this is implemented as two nested instruction sequences. CRuby therefore thinks the depth is two more than prism does. For example: + +``` +$ ruby --dump=insns -e 'foo = 1; END { foo }' +== disasm: #@-e:1 (1,0)-(1,20)> (catch: false) +local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1]) +[ 1] foo@0 +0000 putobject_INT2FIX_1_ ( 1)[Li] +0001 setlocal_WC_0 foo@0 +0003 once block in
, +0006 leave + +== disasm: #@-e:0 (0,0)-(-1,-1)> (catch: false) +0000 putspecialobject 1 ( 1) +0002 send , block in
+0005 leave + +== disasm: #@-e:1 (1,9)-(1,20)> (catch: false) +0000 getlocal foo@0, 2 ( 1)[LiBc] +0003 leave [Br] +``` + +In the instruction sequence corresponding to the code that gets executed inside the `END` block, CRuby is reading the `foo` local variable using `getlocal` as the second instruction to the `"block in
"` instruction sequence. When compiling CRuby, prism therefore will adjust the depth to account for this difference. diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/mapping.md b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/mapping.md new file mode 100644 index 00000000..b61e9e9f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/mapping.md @@ -0,0 +1,117 @@ +# Mapping + +When considering the previous CRuby parser versus prism, this document should be helpful to understand how various concepts are mapped. + +## Nodes + +The following table shows how the various CRuby nodes are mapped to prism nodes. + +| CRuby | prism | +| --- | --- | +| `NODE_SCOPE` | | +| `NODE_BLOCK` | | +| `NODE_IF` | `PM_IF_NODE` | +| `NODE_UNLESS` | `PM_UNLESS_NODE` | +| `NODE_CASE` | `PM_CASE_NODE` | +| `NODE_CASE2` | `PM_CASE_NODE` (with a null predicate) | +| `NODE_CASE3` | | +| `NODE_WHEN` | `PM_WHEN_NODE` | +| `NODE_IN` | `PM_IN_NODE` | +| `NODE_WHILE` | `PM_WHILE_NODE` | +| `NODE_UNTIL` | `PM_UNTIL_NODE` | +| `NODE_ITER` | `PM_CALL_NODE` (with a non-null block) | +| `NODE_FOR` | `PM_FOR_NODE` | +| `NODE_FOR_MASGN` | `PM_FOR_NODE` (with a multi-write node as the index) | +| `NODE_BREAK` | `PM_BREAK_NODE` | +| `NODE_NEXT` | `PM_NEXT_NODE` | +| `NODE_REDO` | `PM_REDO_NODE` | +| `NODE_RETRY` | `PM_RETRY_NODE` | +| `NODE_BEGIN` | `PM_BEGIN_NODE` | +| `NODE_RESCUE` | `PM_RESCUE_NODE` | +| `NODE_RESBODY` | | +| `NODE_ENSURE` | `PM_ENSURE_NODE` | +| `NODE_AND` | `PM_AND_NODE` | +| `NODE_OR` | `PM_OR_NODE` | +| `NODE_MASGN` | `PM_MULTI_WRITE_NODE` | +| `NODE_LASGN` | `PM_LOCAL_VARIABLE_WRITE_NODE` | +| `NODE_DASGN` | `PM_LOCAL_VARIABLE_WRITE_NODE` | +| `NODE_GASGN` | `PM_GLOBAL_VARIABLE_WRITE_NODE` | +| `NODE_IASGN` | `PM_INSTANCE_VARIABLE_WRITE_NODE` | +| `NODE_CDECL` | `PM_CONSTANT_PATH_WRITE_NODE` | +| `NODE_CVASGN` | `PM_CLASS_VARIABLE_WRITE_NODE` | +| `NODE_OP_ASGN1` | | +| `NODE_OP_ASGN2` | | +| `NODE_OP_ASGN_AND` | `PM_OPERATOR_AND_ASSIGNMENT_NODE` | +| `NODE_OP_ASGN_OR` | `PM_OPERATOR_OR_ASSIGNMENT_NODE` | +| `NODE_OP_CDECL` | | +| `NODE_CALL` | `PM_CALL_NODE` | +| `NODE_OPCALL` | `PM_CALL_NODE` (with an operator as the method) | +| `NODE_FCALL` | `PM_CALL_NODE` (with a null receiver and parentheses) | +| `NODE_VCALL` | `PM_CALL_NODE` (with a null receiver and parentheses or arguments) | +| `NODE_QCALL` | `PM_CALL_NODE` (with a &. operator) | +| `NODE_SUPER` | `PM_SUPER_NODE` | +| `NODE_ZSUPER` | `PM_FORWARDING_SUPER_NODE` | +| `NODE_LIST` | `PM_ARRAY_NODE` | +| `NODE_ZLIST` | `PM_ARRAY_NODE` (with no child elements) | +| `NODE_VALUES` | `PM_ARGUMENTS_NODE` | +| `NODE_HASH` | `PM_HASH_NODE` | +| `NODE_RETURN` | `PM_RETURN_NODE` | +| `NODE_YIELD` | `PM_YIELD_NODE` | +| `NODE_LVAR` | `PM_LOCAL_VARIABLE_READ_NODE` | +| `NODE_DVAR` | `PM_LOCAL_VARIABLE_READ_NODE` | +| `NODE_GVAR` | `PM_GLOBAL_VARIABLE_READ_NODE` | +| `NODE_IVAR` | `PM_INSTANCE_VARIABLE_READ_NODE` | +| `NODE_CONST` | `PM_CONSTANT_PATH_READ_NODE` | +| `NODE_CVAR` | `PM_CLASS_VARIABLE_READ_NODE` | +| `NODE_NTH_REF` | `PM_NUMBERED_REFERENCE_READ_NODE` | +| `NODE_BACK_REF` | `PM_BACK_REFERENCE_READ_NODE` | +| `NODE_MATCH` | | +| `NODE_MATCH2` | `PM_CALL_NODE` (with regular expression as receiver) | +| `NODE_MATCH3` | `PM_CALL_NODE` (with regular expression as only argument) | +| `NODE_LIT` | | +| `NODE_STR` | `PM_STRING_NODE` | +| `NODE_DSTR` | `PM_INTERPOLATED_STRING_NODE` | +| `NODE_XSTR` | `PM_X_STRING_NODE` | +| `NODE_DXSTR` | `PM_INTERPOLATED_X_STRING_NODE` | +| `NODE_EVSTR` | `PM_STRING_INTERPOLATED_NODE` | +| `NODE_DREGX` | `PM_INTERPOLATED_REGULAR_EXPRESSION_NODE` | +| `NODE_ONCE` | | +| `NODE_ARGS` | `PM_PARAMETERS_NODE` | +| `NODE_ARGS_AUX` | | +| `NODE_OPT_ARG` | `PM_OPTIONAL_PARAMETER_NODE` | +| `NODE_KW_ARG` | `PM_KEYWORD_PARAMETER_NODE` | +| `NODE_POSTARG` | `PM_REQUIRED_PARAMETER_NODE` | +| `NODE_ARGSCAT` | | +| `NODE_ARGSPUSH` | | +| `NODE_SPLAT` | `PM_SPLAT_NODE` | +| `NODE_BLOCK_PASS` | `PM_BLOCK_ARGUMENT_NODE` | +| `NODE_DEFN` | `PM_DEF_NODE` (with a null receiver) | +| `NODE_DEFS` | `PM_DEF_NODE` (with a non-null receiver) | +| `NODE_ALIAS` | `PM_ALIAS_NODE` | +| `NODE_VALIAS` | `PM_ALIAS_NODE` (with a global variable first argument) | +| `NODE_UNDEF` | `PM_UNDEF_NODE` | +| `NODE_CLASS` | `PM_CLASS_NODE` | +| `NODE_MODULE` | `PM_MODULE_NODE` | +| `NODE_SCLASS` | `PM_S_CLASS_NODE` | +| `NODE_COLON2` | `PM_CONSTANT_PATH_NODE` | +| `NODE_COLON3` | `PM_CONSTANT_PATH_NODE` (with a null receiver) | +| `NODE_DOT2` | `PM_RANGE_NODE` (with a .. operator) | +| `NODE_DOT3` | `PM_RANGE_NODE` (with a ... operator) | +| `NODE_FLIP2` | `PM_RANGE_NODE` (with a .. operator) | +| `NODE_FLIP3` | `PM_RANGE_NODE` (with a ... operator) | +| `NODE_SELF` | `PM_SELF_NODE` | +| `NODE_NIL` | `PM_NIL_NODE` | +| `NODE_TRUE` | `PM_TRUE_NODE` | +| `NODE_FALSE` | `PM_FALSE_NODE` | +| `NODE_ERRINFO` | | +| `NODE_DEFINED` | `PM_DEFINED_NODE` | +| `NODE_POSTEXE` | `PM_POST_EXECUTION_NODE` | +| `NODE_DSYM` | `PM_INTERPOLATED_SYMBOL_NODE` | +| `NODE_ATTRASGN` | `PM_CALL_NODE` (with a message that ends with =) | +| `NODE_LAMBDA` | `PM_LAMBDA_NODE` | +| `NODE_ARYPTN` | `PM_ARRAY_PATTERN_NODE` | +| `NODE_HSHPTN` | `PM_HASH_PATTERN_NODE` | +| `NODE_FNDPTN` | `PM_FIND_PATTERN_NODE` | +| `NODE_ERROR` | `PM_MISSING_NODE` | +| `NODE_LAST` | | +``` diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/parser_translation.md b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/parser_translation.md new file mode 100644 index 00000000..ab4561e5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/parser_translation.md @@ -0,0 +1,39 @@ +# parser translation + +Prism ships with the ability to translate its syntax tree into the syntax tree used by the [whitequark/parser](https://github.com/whitequark/parser) gem. This allows you to use tools built on top of the `parser` gem with the `prism` parser. + +## Usage + +The `parser` gem provides multiple parsers to support different versions of the Ruby grammar. This includes all of the Ruby versions going back to 1.8, as well as third-party parsers like MacRuby and RubyMotion. The `prism` gem provides another parser that uses the `prism` parser to build the syntax tree. + +You can use the `prism` parser like you would any other. After requiring the parser, you should be able to call any of the regular `Parser::Base` APIs that you would normally use. + +```ruby +require "prism" + +Prism::Translation::Parser.parse_file("path/to/file.rb") +``` + +### RuboCop + +Prism as a parser engine is directly supported since RuboCop 1.62. The class used for parsing is `Prism::Translation::Parser`. + +First, specify `prism` in your Gemfile: + +```ruby +gem "prism" +``` + +To use Prism with RuboCop, specify `ParserEngine` and `TargetRubyVersion` in your RuboCop configuration file: + +```yaml +AllCops: + ParserEngine: parser_prism + TargetRubyVersion: 3.3 +``` + +The default value for `ParserEngine` is `parser_whitequark`, which indicates the Parser gem. You need to explicitly switch it to `parser_prism` to indicate Prism. Additionally, the value for `TargetRubyVersion` must be specified as `3.3` or higher, as Prism supports parsing versions of Ruby 3.3 and higher. +The parser class is determined by the combination of values for `ParserEngine` and `TargetRubyVersion`. For example, if `TargetRubyVersion: 3.3`, parsing is performed by `Prism::Translation::Parser33`, and for `TargetRubyVersion 3.4`, parsing is performed by `Prism::Translation::Parser34`. + +For further information, please refer to the RuboCop documentation: +https://docs.rubocop.org/rubocop/configuration.html#setting-the-parser-engine diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/parsing_rules.md b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/parsing_rules.md new file mode 100644 index 00000000..36475ba4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/parsing_rules.md @@ -0,0 +1,22 @@ +# Rules + +This document contains information related to the rules of the parser for Ruby source code. + +As an example, in the documentation of many of the fields of nodes, it's mentioned that a field follows the lexing rules for `identifier` or `constant`. This document describes what those rules are. + +## Constants + +Constants in Ruby begin with an upper-case letter. This is followed by any number of underscores, alphanumeric, or non-ASCII characters. The definition of "alphanumeric" and "upper-case letter" are encoding-dependent. + +## Non-void expression + +Most expressions in CRuby are non-void. This means the expression they represent resolves to a value. For example, `1 + 2` is a non-void expression, because it resolves to a method call. Even things like `class Foo; end` is a non-void expression, because it returns the last evaluated expression in the body of the class (or `nil`). + +Certain nodes, however, are void expressions, and cannot be combined to form larger expressions. +* `BEGIN {}`, `END {}`, `alias foo bar`, and `undef foo` can only be at a statement position. +* The "jumps": `return`, `break`, `next`, `redo`, `retry` are void expressions. +* `value => pattern` is also considered a void expression. + +## Identifiers + +Identifiers in Ruby begin with an underscore or lower-case letter. This is followed by any number of underscores, alphanumeric, or non-ASCII characters. The definition of "alphanumeric" and "lower-case letter" are encoding-dependent. diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/releasing.md b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/releasing.md new file mode 100644 index 00000000..d17602a3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/releasing.md @@ -0,0 +1,96 @@ +# Releasing + +To release a new version of Prism, perform the following steps: + +## Preparation + +* Update the `CHANGELOG.md` file. + * Add a new section for the new version at the top of the file. + * Fill in the relevant changes — it may be easiest to click the link for the `Unreleased` heading to find the commits. + * Update the links at the bottom of the file. +* Update the version numbers in the various files that reference them: + +```sh +export PRISM_MAJOR="x" +export PRISM_MINOR="y" +export PRISM_PATCH="z" +export PRISM_VERSION="$PRISM_MAJOR.$PRISM_MINOR.$PRISM_PATCH" +ruby -pi -e 'gsub(/spec\.version = ".+?"/, %Q{spec.version = "#{ENV["PRISM_VERSION"]}"})' prism.gemspec +ruby -pi -e 'gsub(/EXPECTED_PRISM_VERSION ".+?"/, %Q{EXPECTED_PRISM_VERSION "#{ENV["PRISM_VERSION"]}"})' ext/prism/extension.h +ruby -pi -e 'gsub(/PRISM_VERSION_MAJOR \d+/, %Q{PRISM_VERSION_MAJOR #{ENV["PRISM_MAJOR"]}})' include/prism/version.h +ruby -pi -e 'gsub(/PRISM_VERSION_MINOR \d+/, %Q{PRISM_VERSION_MINOR #{ENV["PRISM_MINOR"]}})' include/prism/version.h +ruby -pi -e 'gsub(/PRISM_VERSION_PATCH \d+/, %Q{PRISM_VERSION_PATCH #{ENV["PRISM_PATCH"]}})' include/prism/version.h +ruby -pi -e 'gsub(/PRISM_VERSION ".+?"/, %Q{PRISM_VERSION "#{ENV["PRISM_VERSION"]}"})' include/prism/version.h +ruby -pi -e 'gsub(/"version": ".+?"/, %Q{"version": "#{ENV["PRISM_VERSION"]}"})' javascript/package.json +ruby -pi -e 'gsub(/lossy\(\), ".+?"/, %Q{lossy(), "#{ENV["PRISM_VERSION"]}"})' rust/ruby-prism-sys/tests/utils_tests.rs +ruby -pi -e 'gsub(/\d+, "prism major/, %Q{#{ENV["PRISM_MAJOR"]}, "prism major})' templates/java/org/prism/Loader.java.erb +ruby -pi -e 'gsub(/\d+, "prism minor/, %Q{#{ENV["PRISM_MINOR"]}, "prism minor})' templates/java/org/prism/Loader.java.erb +ruby -pi -e 'gsub(/\d+, "prism patch/, %Q{#{ENV["PRISM_PATCH"]}, "prism patch})' templates/java/org/prism/Loader.java.erb +ruby -pi -e 'gsub(/MAJOR_VERSION = \d+/, %Q{MAJOR_VERSION = #{ENV["PRISM_MAJOR"]}})' templates/javascript/src/deserialize.js.erb +ruby -pi -e 'gsub(/MINOR_VERSION = \d+/, %Q{MINOR_VERSION = #{ENV["PRISM_MINOR"]}})' templates/javascript/src/deserialize.js.erb +ruby -pi -e 'gsub(/PATCH_VERSION = \d+/, %Q{PATCH_VERSION = #{ENV["PRISM_PATCH"]}})' templates/javascript/src/deserialize.js.erb +ruby -pi -e 'gsub(/MAJOR_VERSION = \d+/, %Q{MAJOR_VERSION = #{ENV["PRISM_MAJOR"]}})' templates/lib/prism/serialize.rb.erb +ruby -pi -e 'gsub(/MINOR_VERSION = \d+/, %Q{MINOR_VERSION = #{ENV["PRISM_MINOR"]}})' templates/lib/prism/serialize.rb.erb +ruby -pi -e 'gsub(/PATCH_VERSION = \d+/, %Q{PATCH_VERSION = #{ENV["PRISM_PATCH"]}})' templates/lib/prism/serialize.rb.erb +ruby -pi -e 'gsub(/^version = ".+?"/, %Q{version = "#{ENV["PRISM_VERSION"]}"})' rust/ruby-prism-sys/Cargo.toml +ruby -pi -e 'gsub(/^version = ".+?"/, %Q{version = "#{ENV["PRISM_VERSION"]}"})' rust/ruby-prism/Cargo.toml +ruby -pi -e 'gsub(/^ruby-prism-sys = \{ version = ".+?"/, %Q{ruby-prism-sys = \{ version = "#{ENV["PRISM_VERSION"]}"})' rust/ruby-prism/Cargo.toml +``` + +* Update the `Gemfile.lock` file: + +```sh +chruby ruby-3.5.0-dev +bundle install +``` + +* Update the version-specific lockfiles: + +```sh +bin/prism bundle install +``` + +* Update the cargo lockfiles: + +```sh +bundle exec rake cargo:build +``` + +* Commit all of the updated files: + +```sh +git commit -am "Bump to v$PRISM_VERSION" +``` + +* Push up the changes: + +```sh +git push +``` + +## Publishing + +* Update the GitHub release page with a copy of the latest entry in the `CHANGELOG.md` file. +* Publish the gem to [rubygems.org](rubygems.org). Note that you must have access to the `prism` gem to do this. + +```sh +bundle exec rake release +``` + +* Generate the `wasm` artifact (or download it from GitHub actions and put it in `javascript/src/prism.wasm`). + +```sh +make wasm +``` + +* Publish the JavaScript package to [npmjs.com](npmjs.com). Note that you must have access to the `@ruby/prism` package to do this. + +```sh +npm publish +``` + +* Publish the rust crate to [crates.io](crates.io). Note that you must have access to the `ruby-prism-sys` and `ruby-prism` crates to do this. + +```sh +bundle exec rake cargo:publish:real +``` diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/relocation.md b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/relocation.md new file mode 100644 index 00000000..0515f562 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/relocation.md @@ -0,0 +1,34 @@ +# Relocation + +Prism parses deterministically for the same input. This provides a nice property that is exposed through the `#node_id` API on nodes. Effectively this means that for the same input, these values will remain consistent every time the source is parsed. This means we can reparse the source same with a `#node_id` value and find the exact same node again. + +The `Relocation` module provides an API around this property. It allows you to "save" nodes and locations using a minimal amount of memory (just the node_id and a field identifier) and then reify them later. This minimizes the amount of memory you need to allocate to store this information because it does not keep around a pointer to the source string. + +## Getting started + +To get started with the `Relocation` module, you would first instantiate a `Repository` object. You do this through a DSL that chains method calls for configuration. For example, if for every entry in the repository you want to store the start and end lines, the start and end code unit columns for in UTF-16, and the leading comments, you would: + +```ruby +repository = Prism::Relocation.filepath("path/to/file").lines.code_unit_columns(Encoding::UTF_16).leading_comments +``` + +Now that you have the repository, you can pass it into any of the `save*` APIs on nodes or locations to create entries in the repository that will be lazily reified. + +```ruby +# assume that node is a Prism::ClassNode object +entry = node.constant_path.save(repository) +``` + +Now that you have the entry object, you do not need to keep around a reference to the repository, it will be cleaned up on its own when the last entry is reified. Now, whenever you need to, you may call the associated field methods on the entry object, as in: + +```ruby +entry.start_line +entry.end_line + +entry.start_code_units_column +entry.end_code_units_column + +entry.leading_comments +``` + +Note that if you had configured other fields to be saved, you would be able to access them as well. The first time one of these fields is accessed, the repository will reify every entry it knows about and then clean itself up. In this way, you can effectively treat them as if you had kept around lightweight versions of `Prism::Node` or `Prism::Location` objects. diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/ripper_translation.md b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/ripper_translation.md new file mode 100644 index 00000000..af765da5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/ripper_translation.md @@ -0,0 +1,72 @@ +# Ripper translation + +Prism provides the ability to mirror the `Ripper` standard library. You can do this by: + +```ruby +require "prism/translation/ripper/shim" +``` + +This provides the APIs like: + +```ruby +Ripper.lex +Ripper.parse +Ripper.sexp_raw +Ripper.sexp + +Ripper::SexpBuilder +Ripper::SexpBuilderPP +``` + +Briefly, `Ripper` is a streaming parser that allows you to construct your own syntax tree. As an example: + +```ruby +class ArithmeticRipper < Prism::Translation::Ripper + def on_binary(left, operator, right) + left.public_send(operator, right) + end + + def on_int(value) + value.to_i + end + + def on_program(stmts) + stmts + end + + def on_stmts_new + [] + end + + def on_stmts_add(stmts, stmt) + stmts << stmt + stmts + end +end + +ArithmeticRipper.new("1 + 2 - 3").parse # => [0] +``` + +The exact names of the `on_*` methods are listed in the `Ripper` source. + +## Background + +It is helpful to understand the differences between the `Ripper` library and the `Prism` library. Both libraries perform parsing and provide you with APIs to manipulate and understand the resulting syntax tree. However, there are a few key differences. + +### Design + +`Ripper` is a streaming parser. This means as it is parsing Ruby code, it dispatches events back to the consumer. This allows quite a bit of flexibility. You can use it to build your own syntax tree or to find specific patterns in the code. `Prism` on the other hand returns to your the completed syntax tree _before_ it allows you to manipulate it. This means the tree that you get back is the only representation that can be generated by the parser _at parse time_ (but of course can be manipulated later). + +### Fields + +We use the term "field" to mean a piece of information on a syntax tree node. `Ripper` provides the minimal number of fields to accurately represent the syntax tree for the purposes of compilation/interpretation. For example, in the callbacks for nodes that are based on keywords (`class`, `module`, `for`, `while`, etc.) you are not given the keyword itself, you need to attach it on your own. In other cases, tokens are not necessarily dispatched at all, meaning you need to find them yourself. `Prism` provides the opposite: the maximum number of fields on nodes is provided. As a tradeoff, this requires more memory, but this is chosen to make it easier on consumers. + +### Maintainability + +The `Ripper` interface is not guaranteed in any way, and tends to change between patch versions of CRuby. This is largely due to the fact that `Ripper` is a by-product of the generated parser, as opposed to its own parser. As an example, in the expression `foo::bar = baz`, there are three different represents possible for the call operator, including: + +* `:"::"` - Ruby 1.9 to Ruby 3.1.4 +* `73` - Ruby 3.1.5 to Ruby 3.1.6 +* `[:@op, "::", [lineno, column]]` - Ruby 3.2.0 and later + +The `Prism` interface is guaranteed going forward to be the consistent, and the official Ruby syntax tree interface. This means you can rely on this interface without having to worry about individual changes between Ruby versions. It also is a gem, which means it is versioned based on the gem version, as opposed to being versioned based on the Ruby version. Finally, you can use `Prism` to parse multiple versions of Ruby, whereas `Ripper` is tied to the Ruby version it is running on. diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/ruby_api.md b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/ruby_api.md new file mode 100644 index 00000000..6cfde4c1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/ruby_api.md @@ -0,0 +1,44 @@ +# Ruby API + +The `prism` gem provides a Ruby API for accessing the syntax tree. + +For the most part, the API for accessing the tree mirrors that found in the [Syntax Tree](https://github.com/ruby-syntax-tree/syntax_tree) project. This means: + +* Walking the tree involves creating a visitor and passing it to the `#accept` method on any node in the tree +* Nodes in the tree respond to named methods for accessing their children as well as `#child_nodes` +* Nodes respond to the pattern matching interfaces `#deconstruct` and `#deconstruct_keys` + +Every entry in `config.yml` will generate a Ruby class as well as the code that builds the nodes themselves. +Creating a syntax tree involves calling one of the class methods on the `Prism` module. +The full API is documented below. + +## API + +* `Prism.dump(source)` - parse the syntax tree corresponding to the given source string, and serialize it to a string +* `Prism.dump_file(filepath)` - parse the syntax tree corresponding to the given source file and serialize it to a string +* `Prism.lex(source)` - parse the tokens corresponding to the given source string and return them as an array within a parse result +* `Prism.lex_file(filepath)` - parse the tokens corresponding to the given source file and return them as an array within a parse result +* `Prism.parse(source)` - parse the syntax tree corresponding to the given source string and return it within a parse result +* `Prism.parse_file(filepath)` - parse the syntax tree corresponding to the given source file and return it within a parse result +* `Prism.parse_stream(io)` - parse the syntax tree corresponding to the source that is read out of the given IO object using the `#gets` method and return it within a parse result +* `Prism.parse_lex(source)` - parse the syntax tree corresponding to the given source string and return it within a parse result, along with the tokens +* `Prism.parse_lex_file(filepath)` - parse the syntax tree corresponding to the given source file and return it within a parse result, along with the tokens +* `Prism.load(source, serialized, freeze = false)` - load the serialized syntax tree using the source as a reference into a syntax tree +* `Prism.parse_comments(source)` - parse the comments corresponding to the given source string and return them +* `Prism.parse_file_comments(source)` - parse the comments corresponding to the given source file and return them +* `Prism.parse_success?(source)` - parse the syntax tree corresponding to the given source string and return true if it was parsed without errors +* `Prism.parse_file_success?(filepath)` - parse the syntax tree corresponding to the given source file and return true if it was parsed without errors + +## Nodes + +Once you have nodes in hand coming out of a parse result, there are a number of common APIs that are available on each instance. They are: + +* `#accept(visitor)` - a method that will immediately call `visit_*` to specialize for the node type +* `#child_nodes` - a positional array of the child nodes of the node, with `nil` values for any missing children +* `#compact_child_nodes` - a positional array of the child nodes of the node with no `nil` values +* `#copy(**keys)` - a method that allows creating a shallow copy of the node with the given keys overridden +* `#deconstruct`/`#deconstruct_keys(keys)` - the pattern matching interface for nodes +* `#inspect` - a string representation that looks like the syntax tree of the node +* `#location` - a `Location` object that describes the location of the node in the source file +* `#to_dot` - convert the node's syntax tree into graphviz dot notation +* `#type` - a symbol that represents the type of the node, useful for quick comparisons diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/ruby_parser_translation.md b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/ruby_parser_translation.md new file mode 100644 index 00000000..35a4cd3f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/ruby_parser_translation.md @@ -0,0 +1,19 @@ +# ruby_parser translation + +Prism ships with the ability to translate its syntax tree into the syntax tree used by the [seattlerb/ruby_parser](https://github.com/seattlerb/ruby_parser) gem. This allows you to use tools built on top of the `ruby_parser` gem with the `prism` parser. + +## Usage + +You can call the `parse` and `parse_file` methods on the `Prism::Translation::RubyParser` module: + +```ruby +filepath = "path/to/file.rb" +Prism::Translation::RubyParser.parse_file(filepath) +``` + +This will return to you `Sexp` objects that mirror the result of calling `RubyParser` methods, as in: + +```ruby +filepath = "path/to/file.rb" +RubyParser.new.parse(File.read(filepath), filepath) +``` diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/serialization.md b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/serialization.md new file mode 100644 index 00000000..ec395f88 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/serialization.md @@ -0,0 +1,233 @@ +# Serialization + +Prism ships with the ability to serialize a syntax tree to a single string. +The string can then be deserialized back into a syntax tree using a language other than C. +This is useful for using the parsing logic in other tools without having to write a parser in that language. +The syntax tree still requires a copy of the original source, as for the most part it just contains byte offsets into the source string. + +## Types + +Let us define some simple types for readability. + +### varuint + +A variable-length unsigned integer with the value fitting in `uint32_t` using between 1 and 5 bytes, using the [LEB128](https://en.wikipedia.org/wiki/LEB128) encoding. +This drastically cuts down on the size of the serialized string, especially when the source file is large. + +### varsint + +A variable-length signed integer with the value fitting in `int32_t` using between 1 and 5 bytes, using [ZigZag encoding](https://protobuf.dev/programming-guides/encoding/#signed-ints) into [LEB128]. + +### string + +| # bytes | field | +| --- | --- | +| varuint | the length of the string in bytes | +| ... | the string bytes | + +### location + +| # bytes | field | +| --- | --- | +| varuint | byte offset into the source string where this location begins | +| varuint | length of the location in bytes in the source string | + +### comment + +The comment type is one of: + +* 0=`INLINE` (`# comment`) +* 1=`EMBEDDED_DOCUMENT` (`=begin`/`=end`) + +| # bytes | field | +| --- | --- | +| `1` | comment type | +| location | the location in the source of this comment | + +### magic comment + +| # bytes | field | +| --- | --- | +| location | the location of the key of the magic comment | +| location | the location of the value of the magic comment | + +### error + +| # bytes | field | +| --- | --- | +| varuint | type | +| string | error message (ASCII-only characters) | +| location | the location in the source this error applies to | +| `1` | the level of the error: `0` for `fatal`, `1` for `argument`, `2` for `load` | + +### warning + +| # bytes | field | +| --- | --- | +| varuint | type | +| string | warning message (ASCII-only characters) | +| location | the location in the source this warning applies to | +| `1` | the level of the warning: `0` for `default` and `1` for `verbose` | + +### integer + +| # bytes | field | +| --- | --- | +| `1` | `1` if the integer is negative, `0` if the integer is positive | +| varuint | the number of words in this integer | +| varuint+ | the words of the integer, least-significant to most-significant | + +## Structure + +The serialized string representing the syntax tree is composed of three parts: the header, the body, and the constant pool. +The header contains information like the version of prism that serialized the tree. +The body contains the actual nodes in the tree. +The constant pool contains constants that were interned while parsing. + +The header is structured like the following table: + +| # bytes | field | +| --- | --- | +| `5` | "PRISM" | +| `1` | major version number | +| `1` | minor version number | +| `1` | patch version number | +| `1` | 1 indicates only semantics fields were serialized, 0 indicates all fields were serialized (including location fields) | +| string | the encoding name | +| varsint | the start line | +| varuint | number of newline offsets | +| varuint* | newline offsets | +| varuint | number of comments | +| comment* | comments | +| varuint | number of magic comments | +| magic comment* | magic comments | +| location? | the optional location of the `__END__` keyword and its contents | +| varuint | number of errors | +| error* | errors | +| varuint | number of warnings | +| warning* | warnings | +| `4` | content pool offset | +| varuint | content pool size | + +After the header comes the body of the serialized string. +The body consists of a sequence of nodes that is built using a prefix traversal order of the syntax tree. +Each node is structured like the following table: + +| # bytes | field | +| --- | --- | +| `1` | node type | +| varuint | node identifier | +| location | node location | +| varuint | node flags | + +Every field on the node is then appended to the serialized string. The fields can be determined by referencing `config.yml`. Depending on the type of field, it could take a couple of different forms, described below: + +* `double` - A field that is a `double`. This is structured as a sequence of 8 bytes in native endian order. +* `node` - A field that is a node. This is structured just as like parent node. +* `node?` - A field that is a node that is optionally present. If the node is not present, then a single `0` byte will be written in its place. If it is present, then it will be structured just as like parent node. +* `node[]` - A field that is an array of nodes. This is structured as a variable-length integer length, followed by the child nodes themselves. +* `string` - A field that is a string. For example, this is used as the name of the method in a call node, since it cannot directly reference the source string (as in `@-` or `foo=`). This is structured as a variable-length integer byte length, followed by the string itself (_without_ a trailing null byte). +* `constant` - A variable-length integer that represents an index in the constant pool. +* `constant?` - An optional variable-length integer that represents an index in the constant pool. If it's not present, then a single `0` byte will be written in its place. +* `integer` - A field that represents an arbitrary-sized integer. The structure is listed above. +* `location` - A field that is a location. This is structured as a variable-length integer start followed by a variable-length integer length. +* `location?` - A field that is a location that is optionally present. If the location is not present, then a single `0` byte will be written in its place. If it is present, then it will be structured just like the `location` child node. +* `uint8` - A field that is an 8-bit unsigned integer. This is structured as a single byte. +* `uint32` - A field that is a 32-bit unsigned integer. This is structured as a variable-length integer. + +After the syntax tree, the content pool is serialized. This is a list of constants that were referenced from within the tree. The content pool begins at the offset specified in the header. Constants can be either "owned" (in which case their contents are embedded in the serialization) or "shared" (in which case their contents represent a slice of the source string). The most significant bit of the constant indicates whether it is owned or shared. + +In the case that it is owned, the constant is structured as follows: + +| # bytes | field | +| --- | --- | +| `4` | the byte offset in the serialization for the contents of the constant | +| `4` | the byte length in the serialization | + +Note that you will need to mask off the most significant bit for the byte offset in the serialization. In the case that it is shared, the constant is structured as follows: + +| # bytes | field | +| --- | --- | +| `4` | the byte offset in the source string for the contents of the constant | +| `4` | the byte length in the source string | + +After the constant pool, the contents of the owned constants are serialized. This is just a sequence of bytes that represent the contents of the constants. At the end of the serialization, the buffer is null terminated. + +## APIs + +The relevant APIs and struct definitions are listed below: + +```c +// A pm_buffer_t is a simple memory buffer that stores data in a contiguous +// block of memory. It is used to store the serialized representation of a +// prism tree. +typedef struct { + char *value; + size_t length; + size_t capacity; +} pm_buffer_t; + +// Free the memory associated with the buffer. +void pm_buffer_free(pm_buffer_t *); + +// Parse and serialize the AST represented by the given source to the given +// buffer. +void pm_serialize_parse(pm_buffer_t *buffer, const uint8_t *source, size_t length, const char *data); +``` + +Typically you would use a stack-allocated `pm_buffer_t` and call `pm_serialize_parse`, as in: + +```c +void +serialize(const uint8_t *source, size_t length) { + pm_buffer_t buffer = { 0 }; + pm_serialize_parse(&buffer, source, length, NULL); + + // Do something with the serialized string. + + pm_buffer_free(&buffer); +} +``` + +The final argument to `pm_serialize_parse` is an optional string that controls the options to the parse function. This includes all of the normal options that could be passed to `pm_parser_init` through a `pm_options_t` struct, but serialized as a string to make it easier for callers through FFI. Note that no `varuint` are used here to make it easier to produce the data for the caller, and also serialized size is less important here. The format of the data is structured as follows: + +| # bytes | field | +| ------- | -------------------------- | +| `4` | the length of the filepath | +| ... | the filepath bytes | +| `4` | the line number | +| `4` | the length the encoding | +| ... | the encoding bytes | +| `1` | frozen string literal | +| `1` | command line flags | +| `1` | syntax version, see [pm_options_version_t](https://github.com/ruby/prism/blob/main/include/prism/options.h) for valid values | +| `1` | whether or not the encoding is locked (should almost always be false) | +| `4` | the number of scopes | +| ... | the scopes | + +Command line flags are a bitset. By default every flag is `0`. It includes the following values: + +* `0x1` - the `-a` option +* `0x2` - the `-e` option +* `0x4` - the `-l` option +* `0x8` - the `-n` option +* `0x10` - the `-p` option +* `0x20` - the `-x` option + +Scopes are ordered from the outermost scope to the innermost one. + +Each scope is laid out as follows: + +| # bytes | field | +| ------- | -------------------------- | +| `4` | the number of locals | +| ... | the locals | + +Each local is laid out as follows: + +| # bytes | field | +| ------- | -------------------------- | +| `4` | the length of the local | +| ... | the local bytes | + +The data can be `NULL` (as seen in the example above). diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/testing.md b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/testing.md new file mode 100644 index 00000000..a42ee2e2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/docs/testing.md @@ -0,0 +1,55 @@ +# Testing + +This document explains how to test prism, both locally, and against existing test suites. + +## Test suite + +`rake test` will run all of the files in the `test/` directory. This can be conceived of as two parts: unit tests, and snapshot tests. + +### Unit tests + +These test specific prism implementation details like comments, errors, and regular expressions. There are corresponding files for each thing being tested (like `test/errors_test.rb`). + +### Snapshot tests + +Snapshot tests ensure that parsed output is equivalent to previous parsed output. There are many categorized examples of valid syntax within the `test/prism/fixtures/` directory. When the test suite runs, it will parse all of this syntax, and compare it against corresponding files in the `test/prism/snapshots/` directory. For example, `test/prism/fixtures/strings.txt` has a corresponding `test/prism/snapshots/strings.txt`. + +If the parsed files do not match, it will raise an error. If there is not a corresponding file in the `test/prism/snapshots/` directory, one will be created so that it exists for the next test run. + +### Testing against repositories + +To test the parser against a repository, you can run `FILEPATHS='/path/to/repository/**/*.rb' rake lex`. This will run the parser against every file matched by the glob pattern and check its generated tokens against those generated by ripper. + +## Local testing + +As you are working, you will likely want to test your code locally. `test.rb` is ignored by git, so it can be used for local testing. There are also two executables which may help you: + +1. **bin/lex** takes a filepath and compares prism's lexed output to Ripper's lexed output. It prints any lexed output that doesn't match. It does some minor transformations to the lexed output in order to compare them, like split prism's heredoc tokens to mirror Ripper's. + +``` +$ bin/lex test.rb +``` + +If you would like to see the full lexed comparison, and not only the output that doesn't match, you can run with `VERBOSE=1`: + +``` +$ VERBOSE=1 bin/lex test.rb +``` + +`bin/lex` can also be used with `-e` and then source code, like this: + +``` +$ bin/lex -e "1 + 2" +``` + +2. **bin/parse** takes a filepath and outputs prism's parsed node structure generated from reading the file. + +``` +$ bin/parse test.rb +``` + +`bin/parse` can also be used with `-e` and then source code, like this: + +``` +$ bin/parse -e "1 + 2" +``` diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext/prism/Makefile b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext/prism/Makefile new file mode 100644 index 00000000..dfb53313 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext/prism/Makefile @@ -0,0 +1,273 @@ + +SHELL = /bin/sh + +# V=0 quiet, V=1 verbose. other values don't work. +V = 0 +V0 = $(V:0=) +Q1 = $(V:1=) +Q = $(Q1:0=@) +ECHO1 = $(V:1=@ :) +ECHO = $(ECHO1:0=@ echo) +NULLCMD = : + +#### Start of system configuration section. #### + +srcdir = . +topdir = /opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 +hdrdir = $(topdir) +arch_hdrdir = /opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux +PATH_SEPARATOR = : +VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby:$(srcdir)/../../src:$(srcdir)/../../src/util +prefix = $(DESTDIR)/opt/hostedtoolcache/Ruby/3.4.4/x64 +rubysitearchprefix = $(rubylibprefix)/$(sitearch) +rubyarchprefix = $(rubylibprefix)/$(arch) +rubylibprefix = $(libdir)/$(RUBY_BASE_NAME) +exec_prefix = $(prefix) +vendorarchhdrdir = $(vendorhdrdir)/$(sitearch) +sitearchhdrdir = $(sitehdrdir)/$(sitearch) +rubyarchhdrdir = $(rubyhdrdir)/$(arch) +vendorhdrdir = $(rubyhdrdir)/vendor_ruby +sitehdrdir = $(rubyhdrdir)/site_ruby +rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME) +vendorarchdir = $(vendorlibdir)/$(sitearch) +vendorlibdir = $(vendordir)/$(ruby_version) +vendordir = $(rubylibprefix)/vendor_ruby +sitearchdir = $(sitelibdir)/$(sitearch) +sitelibdir = $(sitedir)/$(ruby_version) +sitedir = $(rubylibprefix)/site_ruby +rubyarchdir = $(rubylibdir)/$(arch) +rubylibdir = $(rubylibprefix)/$(ruby_version) +sitearchincludedir = $(includedir)/$(sitearch) +archincludedir = $(includedir)/$(arch) +sitearchlibdir = $(libdir)/$(sitearch) +archlibdir = $(libdir)/$(arch) +ridir = $(datarootdir)/$(RI_BASE_NAME) +modular_gc_dir = $(DESTDIR) +mandir = $(datarootdir)/man +localedir = $(datarootdir)/locale +libdir = $(exec_prefix)/lib +psdir = $(docdir) +pdfdir = $(docdir) +dvidir = $(docdir) +htmldir = $(docdir) +infodir = $(datarootdir)/info +docdir = $(datarootdir)/doc/$(PACKAGE) +oldincludedir = $(DESTDIR)/usr/include +includedir = $(prefix)/include +runstatedir = $(localstatedir)/run +localstatedir = $(prefix)/var +sharedstatedir = $(prefix)/com +sysconfdir = $(prefix)/etc +datadir = $(datarootdir) +datarootdir = $(prefix)/share +libexecdir = $(exec_prefix)/libexec +sbindir = $(exec_prefix)/sbin +bindir = $(exec_prefix)/bin +archdir = $(rubyarchdir) + + +CC_WRAPPER = +CC = gcc +CXX = g++ +LIBRUBY = $(LIBRUBY_SO) +LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a +LIBRUBYARG_SHARED = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME) +LIBRUBYARG_STATIC = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)-static $(MAINLIBS) +empty = +OUTFLAG = -o $(empty) +COUTFLAG = -o $(empty) +CSRCFLAG = $(empty) + +RUBY_EXTCONF_H = +cflags = $(hardenflags) $(optflags) $(debugflags) $(warnflags) +cxxflags = +optflags = -O3 -fno-fast-math +debugflags = -ggdb3 +warnflags = -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef +cppflags = +CCDLFLAGS = -fPIC +CFLAGS = $(CCDLFLAGS) $(cflags) -fPIC -fvisibility=hidden $(ARCH_FLAG) +INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) -I/home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include -I/home/runner/work/hooks/hooks/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext +DEFS = +CPPFLAGS = -DENABLE_PATH_CHECK=0 $(DEFS) $(cppflags) +CXXFLAGS = $(CCDLFLAGS) $(ARCH_FLAG) +ldflags = -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed +dldflags = -Wl,--compress-debug-sections=zlib +ARCH_FLAG = +DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG) +LDSHARED = $(CC) -shared +LDSHAREDXX = $(CXX) -shared +POSTLINK = : +AR = gcc-ar +LD = ld +EXEEXT = + +RUBY_INSTALL_NAME = $(RUBY_BASE_NAME) +RUBY_SO_NAME = ruby +RUBYW_INSTALL_NAME = +RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version) +RUBYW_BASE_NAME = rubyw +RUBY_BASE_NAME = ruby + +arch = x86_64-linux +sitearch = $(arch) +ruby_version = 3.4.0 +ruby = $(bindir)/$(RUBY_BASE_NAME) +RUBY = $(ruby) +BUILTRUBY = $(bindir)/$(RUBY_BASE_NAME) +ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/backward.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h + +RM = rm -f +RM_RF = rm -fr +RMDIRS = rmdir --ignore-fail-on-non-empty -p +MAKEDIRS = /usr/bin/mkdir -p +INSTALL = /usr/bin/install -c +INSTALL_PROG = $(INSTALL) -m 0755 +INSTALL_DATA = $(INSTALL) -m 644 +COPY = cp +TOUCH = exit > + +#### End of system configuration section. #### + +preload = +libpath = . $(libdir) +LIBPATH = -L. -L$(libdir) -Wl,-rpath,$(libdir) +DEFFILE = + +CLEANFILES = mkmf.log +DISTCLEANFILES = +DISTCLEANDIRS = + +extout = +extout_prefix = +target_prefix = /prism +LOCAL_LIBS = +LIBS = $(LIBRUBYARG_SHARED) -lm -lpthread -lc +ORIG_SRCS = api_node.c api_pack.c extension.c +SRCS = $(ORIG_SRCS) diagnostic.c encoding.c node.c options.c pack.c prettyprint.c prism.c regexp.c serialize.c static_literals.c token_type.c pm_buffer.c pm_char.c pm_constant_pool.c pm_integer.c pm_list.c pm_memchr.c pm_newline_list.c pm_string.c pm_strncasecmp.c pm_strpbrk.c +OBJS = api_node.o api_pack.o extension.o diagnostic.o encoding.o node.o options.o pack.o prettyprint.o prism.o regexp.o serialize.o static_literals.o token_type.o pm_buffer.o pm_char.o pm_constant_pool.o pm_integer.o pm_list.o pm_memchr.o pm_newline_list.o pm_string.o pm_strncasecmp.o pm_strpbrk.o +HDRS = $(srcdir)/extension.h +LOCAL_HDRS = +TARGET = prism +TARGET_NAME = prism +TARGET_ENTRY = Init_$(TARGET_NAME) +DLLIB = $(TARGET).so +EXTSTATIC = +STATIC_LIB = + +TIMESTAMP_DIR = . +BINDIR = $(bindir) +RUBYCOMMONDIR = $(sitedir)$(target_prefix) +RUBYLIBDIR = $(sitelibdir)$(target_prefix) +RUBYARCHDIR = $(sitearchdir)$(target_prefix) +HDRDIR = $(sitehdrdir)$(target_prefix) +ARCHHDRDIR = $(sitearchhdrdir)$(target_prefix) +TARGET_SO_DIR = +TARGET_SO = $(TARGET_SO_DIR)$(DLLIB) +CLEANLIBS = $(TARGET_SO) false +CLEANOBJS = $(OBJS) *.bak +TARGET_SO_DIR_TIMESTAMP = $(TIMESTAMP_DIR)/.sitearchdir.-.prism.time + +all: $(DLLIB) +static: $(STATIC_LIB) +.PHONY: all install static install-so install-rb +.PHONY: clean clean-so clean-static clean-rb + +clean-static:: +clean-rb-default:: +clean-rb:: +clean-so:: +clean: clean-so clean-static clean-rb-default clean-rb + -$(Q)$(RM_RF) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time + +distclean-rb-default:: +distclean-rb:: +distclean-so:: +distclean-static:: +distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb + -$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + -$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + -$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true + +realclean: distclean +install: install-so install-rb + +install-so: $(DLLIB) $(TARGET_SO_DIR_TIMESTAMP) + $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) +clean-static:: + -$(Q)$(RM) $(STATIC_LIB) +install-rb: pre-install-rb do-install-rb install-rb-default +install-rb-default: pre-install-rb-default do-install-rb-default +pre-install-rb: Makefile +pre-install-rb-default: Makefile +do-install-rb: +do-install-rb-default: +pre-install-rb-default: + @$(NULLCMD) +$(TARGET_SO_DIR_TIMESTAMP): + $(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR) + $(Q) $(TOUCH) $@ + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + +.SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S + +.cc.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cc.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.mm.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.mm.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cxx.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cxx.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cpp.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cpp.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.c.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.c.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.m.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.m.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +$(TARGET_SO): $(OBJS) Makefile + $(ECHO) linking shared-object prism/$(DLLIB) + -$(Q)$(RM) $(@) + $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) + $(Q) $(POSTLINK) + + + +$(OBJS): $(HDRS) $(ruby_headers) diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext/prism/api_node.c b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext/prism/api_node.c new file mode 100644 index 00000000..c103218f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext/prism/api_node.c @@ -0,0 +1,6939 @@ +/*----------------------------------------------------------------------------*/ +/* This file is generated by the templates/template.rb script and should not */ +/* be modified manually. See */ +/* templates/ext/prism/api_node.c.erb */ +/* if you are looking to modify the */ +/* template */ +/*----------------------------------------------------------------------------*/ + +#line 2 "prism/templates/ext/prism/api_node.c.erb" +#include "prism/extension.h" + +extern VALUE rb_cPrism; +extern VALUE rb_cPrismNode; +extern VALUE rb_cPrismSource; +extern VALUE rb_cPrismToken; +extern VALUE rb_cPrismLocation; + +static VALUE rb_cPrismAliasGlobalVariableNode; +static VALUE rb_cPrismAliasMethodNode; +static VALUE rb_cPrismAlternationPatternNode; +static VALUE rb_cPrismAndNode; +static VALUE rb_cPrismArgumentsNode; +static VALUE rb_cPrismArrayNode; +static VALUE rb_cPrismArrayPatternNode; +static VALUE rb_cPrismAssocNode; +static VALUE rb_cPrismAssocSplatNode; +static VALUE rb_cPrismBackReferenceReadNode; +static VALUE rb_cPrismBeginNode; +static VALUE rb_cPrismBlockArgumentNode; +static VALUE rb_cPrismBlockLocalVariableNode; +static VALUE rb_cPrismBlockNode; +static VALUE rb_cPrismBlockParameterNode; +static VALUE rb_cPrismBlockParametersNode; +static VALUE rb_cPrismBreakNode; +static VALUE rb_cPrismCallAndWriteNode; +static VALUE rb_cPrismCallNode; +static VALUE rb_cPrismCallOperatorWriteNode; +static VALUE rb_cPrismCallOrWriteNode; +static VALUE rb_cPrismCallTargetNode; +static VALUE rb_cPrismCapturePatternNode; +static VALUE rb_cPrismCaseMatchNode; +static VALUE rb_cPrismCaseNode; +static VALUE rb_cPrismClassNode; +static VALUE rb_cPrismClassVariableAndWriteNode; +static VALUE rb_cPrismClassVariableOperatorWriteNode; +static VALUE rb_cPrismClassVariableOrWriteNode; +static VALUE rb_cPrismClassVariableReadNode; +static VALUE rb_cPrismClassVariableTargetNode; +static VALUE rb_cPrismClassVariableWriteNode; +static VALUE rb_cPrismConstantAndWriteNode; +static VALUE rb_cPrismConstantOperatorWriteNode; +static VALUE rb_cPrismConstantOrWriteNode; +static VALUE rb_cPrismConstantPathAndWriteNode; +static VALUE rb_cPrismConstantPathNode; +static VALUE rb_cPrismConstantPathOperatorWriteNode; +static VALUE rb_cPrismConstantPathOrWriteNode; +static VALUE rb_cPrismConstantPathTargetNode; +static VALUE rb_cPrismConstantPathWriteNode; +static VALUE rb_cPrismConstantReadNode; +static VALUE rb_cPrismConstantTargetNode; +static VALUE rb_cPrismConstantWriteNode; +static VALUE rb_cPrismDefNode; +static VALUE rb_cPrismDefinedNode; +static VALUE rb_cPrismElseNode; +static VALUE rb_cPrismEmbeddedStatementsNode; +static VALUE rb_cPrismEmbeddedVariableNode; +static VALUE rb_cPrismEnsureNode; +static VALUE rb_cPrismFalseNode; +static VALUE rb_cPrismFindPatternNode; +static VALUE rb_cPrismFlipFlopNode; +static VALUE rb_cPrismFloatNode; +static VALUE rb_cPrismForNode; +static VALUE rb_cPrismForwardingArgumentsNode; +static VALUE rb_cPrismForwardingParameterNode; +static VALUE rb_cPrismForwardingSuperNode; +static VALUE rb_cPrismGlobalVariableAndWriteNode; +static VALUE rb_cPrismGlobalVariableOperatorWriteNode; +static VALUE rb_cPrismGlobalVariableOrWriteNode; +static VALUE rb_cPrismGlobalVariableReadNode; +static VALUE rb_cPrismGlobalVariableTargetNode; +static VALUE rb_cPrismGlobalVariableWriteNode; +static VALUE rb_cPrismHashNode; +static VALUE rb_cPrismHashPatternNode; +static VALUE rb_cPrismIfNode; +static VALUE rb_cPrismImaginaryNode; +static VALUE rb_cPrismImplicitNode; +static VALUE rb_cPrismImplicitRestNode; +static VALUE rb_cPrismInNode; +static VALUE rb_cPrismIndexAndWriteNode; +static VALUE rb_cPrismIndexOperatorWriteNode; +static VALUE rb_cPrismIndexOrWriteNode; +static VALUE rb_cPrismIndexTargetNode; +static VALUE rb_cPrismInstanceVariableAndWriteNode; +static VALUE rb_cPrismInstanceVariableOperatorWriteNode; +static VALUE rb_cPrismInstanceVariableOrWriteNode; +static VALUE rb_cPrismInstanceVariableReadNode; +static VALUE rb_cPrismInstanceVariableTargetNode; +static VALUE rb_cPrismInstanceVariableWriteNode; +static VALUE rb_cPrismIntegerNode; +static VALUE rb_cPrismInterpolatedMatchLastLineNode; +static VALUE rb_cPrismInterpolatedRegularExpressionNode; +static VALUE rb_cPrismInterpolatedStringNode; +static VALUE rb_cPrismInterpolatedSymbolNode; +static VALUE rb_cPrismInterpolatedXStringNode; +static VALUE rb_cPrismItLocalVariableReadNode; +static VALUE rb_cPrismItParametersNode; +static VALUE rb_cPrismKeywordHashNode; +static VALUE rb_cPrismKeywordRestParameterNode; +static VALUE rb_cPrismLambdaNode; +static VALUE rb_cPrismLocalVariableAndWriteNode; +static VALUE rb_cPrismLocalVariableOperatorWriteNode; +static VALUE rb_cPrismLocalVariableOrWriteNode; +static VALUE rb_cPrismLocalVariableReadNode; +static VALUE rb_cPrismLocalVariableTargetNode; +static VALUE rb_cPrismLocalVariableWriteNode; +static VALUE rb_cPrismMatchLastLineNode; +static VALUE rb_cPrismMatchPredicateNode; +static VALUE rb_cPrismMatchRequiredNode; +static VALUE rb_cPrismMatchWriteNode; +static VALUE rb_cPrismMissingNode; +static VALUE rb_cPrismModuleNode; +static VALUE rb_cPrismMultiTargetNode; +static VALUE rb_cPrismMultiWriteNode; +static VALUE rb_cPrismNextNode; +static VALUE rb_cPrismNilNode; +static VALUE rb_cPrismNoKeywordsParameterNode; +static VALUE rb_cPrismNumberedParametersNode; +static VALUE rb_cPrismNumberedReferenceReadNode; +static VALUE rb_cPrismOptionalKeywordParameterNode; +static VALUE rb_cPrismOptionalParameterNode; +static VALUE rb_cPrismOrNode; +static VALUE rb_cPrismParametersNode; +static VALUE rb_cPrismParenthesesNode; +static VALUE rb_cPrismPinnedExpressionNode; +static VALUE rb_cPrismPinnedVariableNode; +static VALUE rb_cPrismPostExecutionNode; +static VALUE rb_cPrismPreExecutionNode; +static VALUE rb_cPrismProgramNode; +static VALUE rb_cPrismRangeNode; +static VALUE rb_cPrismRationalNode; +static VALUE rb_cPrismRedoNode; +static VALUE rb_cPrismRegularExpressionNode; +static VALUE rb_cPrismRequiredKeywordParameterNode; +static VALUE rb_cPrismRequiredParameterNode; +static VALUE rb_cPrismRescueModifierNode; +static VALUE rb_cPrismRescueNode; +static VALUE rb_cPrismRestParameterNode; +static VALUE rb_cPrismRetryNode; +static VALUE rb_cPrismReturnNode; +static VALUE rb_cPrismSelfNode; +static VALUE rb_cPrismShareableConstantNode; +static VALUE rb_cPrismSingletonClassNode; +static VALUE rb_cPrismSourceEncodingNode; +static VALUE rb_cPrismSourceFileNode; +static VALUE rb_cPrismSourceLineNode; +static VALUE rb_cPrismSplatNode; +static VALUE rb_cPrismStatementsNode; +static VALUE rb_cPrismStringNode; +static VALUE rb_cPrismSuperNode; +static VALUE rb_cPrismSymbolNode; +static VALUE rb_cPrismTrueNode; +static VALUE rb_cPrismUndefNode; +static VALUE rb_cPrismUnlessNode; +static VALUE rb_cPrismUntilNode; +static VALUE rb_cPrismWhenNode; +static VALUE rb_cPrismWhileNode; +static VALUE rb_cPrismXStringNode; +static VALUE rb_cPrismYieldNode; + +static VALUE +pm_location_new(const pm_parser_t *parser, const uint8_t *start, const uint8_t *end, VALUE source, bool freeze) { + if (freeze) { + VALUE location_argv[] = { + source, + LONG2FIX(start - parser->start), + LONG2FIX(end - start) + }; + + return rb_obj_freeze(rb_class_new_instance(3, location_argv, rb_cPrismLocation)); + } else { + uint64_t value = ((((uint64_t) (start - parser->start)) << 32) | ((uint32_t) (end - start))); + return ULL2NUM(value); + } +} + +VALUE +pm_token_new(const pm_parser_t *parser, const pm_token_t *token, rb_encoding *encoding, VALUE source, bool freeze) { + ID type = rb_intern(pm_token_type_name(token->type)); + VALUE location = pm_location_new(parser, token->start, token->end, source, freeze); + + VALUE slice = rb_enc_str_new((const char *) token->start, token->end - token->start, encoding); + if (freeze) rb_obj_freeze(slice); + + VALUE argv[] = { source, ID2SYM(type), slice, location }; + VALUE value = rb_class_new_instance(4, argv, rb_cPrismToken); + if (freeze) rb_obj_freeze(value); + + return value; +} + +static VALUE +pm_string_new(const pm_string_t *string, rb_encoding *encoding) { + return rb_obj_freeze(rb_enc_str_new((const char *) pm_string_source(string), pm_string_length(string), encoding)); +} + +VALUE +pm_integer_new(const pm_integer_t *integer) { + VALUE result; + if (integer->values == NULL) { + result = UINT2NUM(integer->value); + } else { + VALUE string = rb_str_new(NULL, integer->length * 8); + unsigned char *bytes = (unsigned char *) RSTRING_PTR(string); + + size_t offset = integer->length * 8; + for (size_t value_index = 0; value_index < integer->length; value_index++) { + uint32_t value = integer->values[value_index]; + + for (int index = 0; index < 8; index++) { + int byte = (value >> (4 * index)) & 0xf; + bytes[--offset] = byte < 10 ? byte + '0' : byte - 10 + 'a'; + } + } + + result = rb_funcall(string, rb_intern("to_i"), 1, UINT2NUM(16)); + } + + if (integer->negative) { + result = rb_funcall(result, rb_intern("-@"), 0); + } + + return result; +} + +// Create a Prism::Source object from the given parser, after pm_parse() was called. +VALUE +pm_source_new(const pm_parser_t *parser, rb_encoding *encoding, bool freeze) { + VALUE source_string = rb_enc_str_new((const char *) parser->start, parser->end - parser->start, encoding); + + VALUE offsets = rb_ary_new_capa(parser->newline_list.size); + for (size_t index = 0; index < parser->newline_list.size; index++) { + rb_ary_push(offsets, ULONG2NUM(parser->newline_list.offsets[index])); + } + + if (freeze) { + rb_obj_freeze(source_string); + rb_obj_freeze(offsets); + } + + VALUE source = rb_funcall(rb_cPrismSource, rb_intern("for"), 3, source_string, LONG2NUM(parser->start_line), offsets); + if (freeze) rb_obj_freeze(source); + + return source; +} + +typedef struct pm_node_stack_node { + struct pm_node_stack_node *prev; + const pm_node_t *visit; + bool visited; +} pm_node_stack_node_t; + +static void +pm_node_stack_push(pm_node_stack_node_t **stack, const pm_node_t *visit) { + pm_node_stack_node_t *node = xmalloc(sizeof(pm_node_stack_node_t)); + node->prev = *stack; + node->visit = visit; + node->visited = false; + *stack = node; +} + +static const pm_node_t * +pm_node_stack_pop(pm_node_stack_node_t **stack) { + pm_node_stack_node_t *current = *stack; + const pm_node_t *visit = current->visit; + + *stack = current->prev; + xfree(current); + + return visit; +} + +VALUE +pm_ast_new(const pm_parser_t *parser, const pm_node_t *node, rb_encoding *encoding, VALUE source, bool freeze) { + VALUE constants = rb_ary_new_capa(parser->constant_pool.size); + + for (uint32_t index = 0; index < parser->constant_pool.size; index++) { + pm_constant_t *constant = &parser->constant_pool.constants[index]; + int state = 0; + + VALUE string = rb_enc_str_new((const char *) constant->start, constant->length, encoding); + VALUE value = rb_protect(rb_str_intern, string, &state); + + if (state != 0) { + value = ID2SYM(rb_intern_const("?")); + rb_set_errinfo(Qnil); + } + + rb_ary_push(constants, value); + } + + pm_node_stack_node_t *node_stack = NULL; + pm_node_stack_push(&node_stack, node); + VALUE value_stack = rb_ary_new(); + + while (node_stack != NULL) { + if (!node_stack->visited) { + if (node_stack->visit == NULL) { + pm_node_stack_pop(&node_stack); + rb_ary_push(value_stack, Qnil); + continue; + } + + const pm_node_t *node = node_stack->visit; + node_stack->visited = true; + + switch (PM_NODE_TYPE(node)) { +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_ALIAS_GLOBAL_VARIABLE_NODE: { + pm_alias_global_variable_node_t *cast = (pm_alias_global_variable_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->new_name); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->old_name); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_ALIAS_METHOD_NODE: { + pm_alias_method_node_t *cast = (pm_alias_method_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->new_name); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->old_name); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_ALTERNATION_PATTERN_NODE: { + pm_alternation_pattern_node_t *cast = (pm_alternation_pattern_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->left); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->right); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_AND_NODE: { + pm_and_node_t *cast = (pm_and_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->left); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->right); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_ARGUMENTS_NODE: { + pm_arguments_node_t *cast = (pm_arguments_node_t *) node; + for (size_t index = 0; index < cast->arguments.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->arguments.nodes[index]); + } + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_ARRAY_NODE: { + pm_array_node_t *cast = (pm_array_node_t *) node; + for (size_t index = 0; index < cast->elements.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->elements.nodes[index]); + } + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_ARRAY_PATTERN_NODE: { + pm_array_pattern_node_t *cast = (pm_array_pattern_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->constant); + for (size_t index = 0; index < cast->requireds.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->requireds.nodes[index]); + } + pm_node_stack_push(&node_stack, (pm_node_t *) cast->rest); + for (size_t index = 0; index < cast->posts.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->posts.nodes[index]); + } + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_ASSOC_NODE: { + pm_assoc_node_t *cast = (pm_assoc_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->key); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_ASSOC_SPLAT_NODE: { + pm_assoc_splat_node_t *cast = (pm_assoc_splat_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_BEGIN_NODE: { + pm_begin_node_t *cast = (pm_begin_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->statements); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->rescue_clause); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->else_clause); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->ensure_clause); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_BLOCK_ARGUMENT_NODE: { + pm_block_argument_node_t *cast = (pm_block_argument_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->expression); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_BLOCK_NODE: { + pm_block_node_t *cast = (pm_block_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->parameters); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->body); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_BLOCK_PARAMETERS_NODE: { + pm_block_parameters_node_t *cast = (pm_block_parameters_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->parameters); + for (size_t index = 0; index < cast->locals.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->locals.nodes[index]); + } + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_BREAK_NODE: { + pm_break_node_t *cast = (pm_break_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->arguments); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_CALL_AND_WRITE_NODE: { + pm_call_and_write_node_t *cast = (pm_call_and_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->receiver); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_CALL_NODE: { + pm_call_node_t *cast = (pm_call_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->receiver); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->arguments); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->block); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_CALL_OPERATOR_WRITE_NODE: { + pm_call_operator_write_node_t *cast = (pm_call_operator_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->receiver); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_CALL_OR_WRITE_NODE: { + pm_call_or_write_node_t *cast = (pm_call_or_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->receiver); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_CALL_TARGET_NODE: { + pm_call_target_node_t *cast = (pm_call_target_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->receiver); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_CAPTURE_PATTERN_NODE: { + pm_capture_pattern_node_t *cast = (pm_capture_pattern_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->target); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_CASE_MATCH_NODE: { + pm_case_match_node_t *cast = (pm_case_match_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->predicate); + for (size_t index = 0; index < cast->conditions.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->conditions.nodes[index]); + } + pm_node_stack_push(&node_stack, (pm_node_t *) cast->else_clause); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_CASE_NODE: { + pm_case_node_t *cast = (pm_case_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->predicate); + for (size_t index = 0; index < cast->conditions.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->conditions.nodes[index]); + } + pm_node_stack_push(&node_stack, (pm_node_t *) cast->else_clause); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_CLASS_NODE: { + pm_class_node_t *cast = (pm_class_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->constant_path); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->superclass); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->body); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_CLASS_VARIABLE_AND_WRITE_NODE: { + pm_class_variable_and_write_node_t *cast = (pm_class_variable_and_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE: { + pm_class_variable_operator_write_node_t *cast = (pm_class_variable_operator_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_CLASS_VARIABLE_OR_WRITE_NODE: { + pm_class_variable_or_write_node_t *cast = (pm_class_variable_or_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_CLASS_VARIABLE_WRITE_NODE: { + pm_class_variable_write_node_t *cast = (pm_class_variable_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_CONSTANT_AND_WRITE_NODE: { + pm_constant_and_write_node_t *cast = (pm_constant_and_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_CONSTANT_OPERATOR_WRITE_NODE: { + pm_constant_operator_write_node_t *cast = (pm_constant_operator_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_CONSTANT_OR_WRITE_NODE: { + pm_constant_or_write_node_t *cast = (pm_constant_or_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_CONSTANT_PATH_AND_WRITE_NODE: { + pm_constant_path_and_write_node_t *cast = (pm_constant_path_and_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->target); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_CONSTANT_PATH_NODE: { + pm_constant_path_node_t *cast = (pm_constant_path_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->parent); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_CONSTANT_PATH_OPERATOR_WRITE_NODE: { + pm_constant_path_operator_write_node_t *cast = (pm_constant_path_operator_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->target); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_CONSTANT_PATH_OR_WRITE_NODE: { + pm_constant_path_or_write_node_t *cast = (pm_constant_path_or_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->target); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_CONSTANT_PATH_TARGET_NODE: { + pm_constant_path_target_node_t *cast = (pm_constant_path_target_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->parent); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_CONSTANT_PATH_WRITE_NODE: { + pm_constant_path_write_node_t *cast = (pm_constant_path_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->target); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_CONSTANT_WRITE_NODE: { + pm_constant_write_node_t *cast = (pm_constant_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_DEF_NODE: { + pm_def_node_t *cast = (pm_def_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->receiver); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->parameters); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->body); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_DEFINED_NODE: { + pm_defined_node_t *cast = (pm_defined_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_ELSE_NODE: { + pm_else_node_t *cast = (pm_else_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->statements); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_EMBEDDED_STATEMENTS_NODE: { + pm_embedded_statements_node_t *cast = (pm_embedded_statements_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->statements); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_EMBEDDED_VARIABLE_NODE: { + pm_embedded_variable_node_t *cast = (pm_embedded_variable_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->variable); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_ENSURE_NODE: { + pm_ensure_node_t *cast = (pm_ensure_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->statements); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_FIND_PATTERN_NODE: { + pm_find_pattern_node_t *cast = (pm_find_pattern_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->constant); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->left); + for (size_t index = 0; index < cast->requireds.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->requireds.nodes[index]); + } + pm_node_stack_push(&node_stack, (pm_node_t *) cast->right); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_FLIP_FLOP_NODE: { + pm_flip_flop_node_t *cast = (pm_flip_flop_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->left); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->right); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_FOR_NODE: { + pm_for_node_t *cast = (pm_for_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->index); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->collection); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->statements); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_FORWARDING_SUPER_NODE: { + pm_forwarding_super_node_t *cast = (pm_forwarding_super_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->block); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_GLOBAL_VARIABLE_AND_WRITE_NODE: { + pm_global_variable_and_write_node_t *cast = (pm_global_variable_and_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE: { + pm_global_variable_operator_write_node_t *cast = (pm_global_variable_operator_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_GLOBAL_VARIABLE_OR_WRITE_NODE: { + pm_global_variable_or_write_node_t *cast = (pm_global_variable_or_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_GLOBAL_VARIABLE_WRITE_NODE: { + pm_global_variable_write_node_t *cast = (pm_global_variable_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_HASH_NODE: { + pm_hash_node_t *cast = (pm_hash_node_t *) node; + for (size_t index = 0; index < cast->elements.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->elements.nodes[index]); + } + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_HASH_PATTERN_NODE: { + pm_hash_pattern_node_t *cast = (pm_hash_pattern_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->constant); + for (size_t index = 0; index < cast->elements.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->elements.nodes[index]); + } + pm_node_stack_push(&node_stack, (pm_node_t *) cast->rest); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_IF_NODE: { + pm_if_node_t *cast = (pm_if_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->predicate); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->statements); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->subsequent); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_IMAGINARY_NODE: { + pm_imaginary_node_t *cast = (pm_imaginary_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->numeric); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_IMPLICIT_NODE: { + pm_implicit_node_t *cast = (pm_implicit_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_IN_NODE: { + pm_in_node_t *cast = (pm_in_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->pattern); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->statements); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_INDEX_AND_WRITE_NODE: { + pm_index_and_write_node_t *cast = (pm_index_and_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->receiver); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->arguments); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->block); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_INDEX_OPERATOR_WRITE_NODE: { + pm_index_operator_write_node_t *cast = (pm_index_operator_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->receiver); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->arguments); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->block); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_INDEX_OR_WRITE_NODE: { + pm_index_or_write_node_t *cast = (pm_index_or_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->receiver); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->arguments); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->block); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_INDEX_TARGET_NODE: { + pm_index_target_node_t *cast = (pm_index_target_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->receiver); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->arguments); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->block); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_INSTANCE_VARIABLE_AND_WRITE_NODE: { + pm_instance_variable_and_write_node_t *cast = (pm_instance_variable_and_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE: { + pm_instance_variable_operator_write_node_t *cast = (pm_instance_variable_operator_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_INSTANCE_VARIABLE_OR_WRITE_NODE: { + pm_instance_variable_or_write_node_t *cast = (pm_instance_variable_or_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_INSTANCE_VARIABLE_WRITE_NODE: { + pm_instance_variable_write_node_t *cast = (pm_instance_variable_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_INTERPOLATED_MATCH_LAST_LINE_NODE: { + pm_interpolated_match_last_line_node_t *cast = (pm_interpolated_match_last_line_node_t *) node; + for (size_t index = 0; index < cast->parts.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->parts.nodes[index]); + } + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE: { + pm_interpolated_regular_expression_node_t *cast = (pm_interpolated_regular_expression_node_t *) node; + for (size_t index = 0; index < cast->parts.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->parts.nodes[index]); + } + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_INTERPOLATED_STRING_NODE: { + pm_interpolated_string_node_t *cast = (pm_interpolated_string_node_t *) node; + for (size_t index = 0; index < cast->parts.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->parts.nodes[index]); + } + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_INTERPOLATED_SYMBOL_NODE: { + pm_interpolated_symbol_node_t *cast = (pm_interpolated_symbol_node_t *) node; + for (size_t index = 0; index < cast->parts.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->parts.nodes[index]); + } + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_INTERPOLATED_X_STRING_NODE: { + pm_interpolated_x_string_node_t *cast = (pm_interpolated_x_string_node_t *) node; + for (size_t index = 0; index < cast->parts.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->parts.nodes[index]); + } + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_KEYWORD_HASH_NODE: { + pm_keyword_hash_node_t *cast = (pm_keyword_hash_node_t *) node; + for (size_t index = 0; index < cast->elements.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->elements.nodes[index]); + } + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_LAMBDA_NODE: { + pm_lambda_node_t *cast = (pm_lambda_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->parameters); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->body); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_LOCAL_VARIABLE_AND_WRITE_NODE: { + pm_local_variable_and_write_node_t *cast = (pm_local_variable_and_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE: { + pm_local_variable_operator_write_node_t *cast = (pm_local_variable_operator_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_LOCAL_VARIABLE_OR_WRITE_NODE: { + pm_local_variable_or_write_node_t *cast = (pm_local_variable_or_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_LOCAL_VARIABLE_WRITE_NODE: { + pm_local_variable_write_node_t *cast = (pm_local_variable_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_MATCH_PREDICATE_NODE: { + pm_match_predicate_node_t *cast = (pm_match_predicate_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->pattern); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_MATCH_REQUIRED_NODE: { + pm_match_required_node_t *cast = (pm_match_required_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->pattern); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_MATCH_WRITE_NODE: { + pm_match_write_node_t *cast = (pm_match_write_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->call); + for (size_t index = 0; index < cast->targets.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->targets.nodes[index]); + } + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_MODULE_NODE: { + pm_module_node_t *cast = (pm_module_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->constant_path); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->body); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_MULTI_TARGET_NODE: { + pm_multi_target_node_t *cast = (pm_multi_target_node_t *) node; + for (size_t index = 0; index < cast->lefts.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->lefts.nodes[index]); + } + pm_node_stack_push(&node_stack, (pm_node_t *) cast->rest); + for (size_t index = 0; index < cast->rights.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->rights.nodes[index]); + } + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_MULTI_WRITE_NODE: { + pm_multi_write_node_t *cast = (pm_multi_write_node_t *) node; + for (size_t index = 0; index < cast->lefts.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->lefts.nodes[index]); + } + pm_node_stack_push(&node_stack, (pm_node_t *) cast->rest); + for (size_t index = 0; index < cast->rights.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->rights.nodes[index]); + } + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_NEXT_NODE: { + pm_next_node_t *cast = (pm_next_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->arguments); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_OPTIONAL_KEYWORD_PARAMETER_NODE: { + pm_optional_keyword_parameter_node_t *cast = (pm_optional_keyword_parameter_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_OPTIONAL_PARAMETER_NODE: { + pm_optional_parameter_node_t *cast = (pm_optional_parameter_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->value); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_OR_NODE: { + pm_or_node_t *cast = (pm_or_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->left); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->right); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_PARAMETERS_NODE: { + pm_parameters_node_t *cast = (pm_parameters_node_t *) node; + for (size_t index = 0; index < cast->requireds.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->requireds.nodes[index]); + } + for (size_t index = 0; index < cast->optionals.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->optionals.nodes[index]); + } + pm_node_stack_push(&node_stack, (pm_node_t *) cast->rest); + for (size_t index = 0; index < cast->posts.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->posts.nodes[index]); + } + for (size_t index = 0; index < cast->keywords.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->keywords.nodes[index]); + } + pm_node_stack_push(&node_stack, (pm_node_t *) cast->keyword_rest); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->block); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_PARENTHESES_NODE: { + pm_parentheses_node_t *cast = (pm_parentheses_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->body); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_PINNED_EXPRESSION_NODE: { + pm_pinned_expression_node_t *cast = (pm_pinned_expression_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->expression); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_PINNED_VARIABLE_NODE: { + pm_pinned_variable_node_t *cast = (pm_pinned_variable_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->variable); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_POST_EXECUTION_NODE: { + pm_post_execution_node_t *cast = (pm_post_execution_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->statements); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_PRE_EXECUTION_NODE: { + pm_pre_execution_node_t *cast = (pm_pre_execution_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->statements); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_PROGRAM_NODE: { + pm_program_node_t *cast = (pm_program_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->statements); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_RANGE_NODE: { + pm_range_node_t *cast = (pm_range_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->left); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->right); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_RESCUE_MODIFIER_NODE: { + pm_rescue_modifier_node_t *cast = (pm_rescue_modifier_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->expression); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->rescue_expression); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_RESCUE_NODE: { + pm_rescue_node_t *cast = (pm_rescue_node_t *) node; + for (size_t index = 0; index < cast->exceptions.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->exceptions.nodes[index]); + } + pm_node_stack_push(&node_stack, (pm_node_t *) cast->reference); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->statements); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->subsequent); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_RETURN_NODE: { + pm_return_node_t *cast = (pm_return_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->arguments); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_SHAREABLE_CONSTANT_NODE: { + pm_shareable_constant_node_t *cast = (pm_shareable_constant_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->write); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_SINGLETON_CLASS_NODE: { + pm_singleton_class_node_t *cast = (pm_singleton_class_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->expression); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->body); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_SPLAT_NODE: { + pm_splat_node_t *cast = (pm_splat_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->expression); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_STATEMENTS_NODE: { + pm_statements_node_t *cast = (pm_statements_node_t *) node; + for (size_t index = 0; index < cast->body.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->body.nodes[index]); + } + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_SUPER_NODE: { + pm_super_node_t *cast = (pm_super_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->arguments); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->block); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_UNDEF_NODE: { + pm_undef_node_t *cast = (pm_undef_node_t *) node; + for (size_t index = 0; index < cast->names.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->names.nodes[index]); + } + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_UNLESS_NODE: { + pm_unless_node_t *cast = (pm_unless_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->predicate); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->statements); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->else_clause); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_UNTIL_NODE: { + pm_until_node_t *cast = (pm_until_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->predicate); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->statements); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_WHEN_NODE: { + pm_when_node_t *cast = (pm_when_node_t *) node; + for (size_t index = 0; index < cast->conditions.size; index++) { + pm_node_stack_push(&node_stack, (pm_node_t *) cast->conditions.nodes[index]); + } + pm_node_stack_push(&node_stack, (pm_node_t *) cast->statements); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_WHILE_NODE: { + pm_while_node_t *cast = (pm_while_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->predicate); + pm_node_stack_push(&node_stack, (pm_node_t *) cast->statements); + break; + } +#line 164 "prism/templates/ext/prism/api_node.c.erb" + case PM_YIELD_NODE: { + pm_yield_node_t *cast = (pm_yield_node_t *) node; + pm_node_stack_push(&node_stack, (pm_node_t *) cast->arguments); + break; + } + default: + break; + } +#line 184 "prism/templates/ext/prism/api_node.c.erb" + } else { + const pm_node_t *node = pm_node_stack_pop(&node_stack); + + switch (PM_NODE_TYPE(node)) { +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_ALIAS_GLOBAL_VARIABLE_NODE: { + pm_alias_global_variable_node_t *cast = (pm_alias_global_variable_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // new_name +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // old_name +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + // keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismAliasGlobalVariableNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_ALIAS_METHOD_NODE: { + pm_alias_method_node_t *cast = (pm_alias_method_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // new_name +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // old_name +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + // keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismAliasMethodNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_ALTERNATION_PATTERN_NODE: { + pm_alternation_pattern_node_t *cast = (pm_alternation_pattern_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // left +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // right +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismAlternationPatternNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_AND_NODE: { + pm_and_node_t *cast = (pm_and_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // left +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // right +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismAndNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_ARGUMENTS_NODE: { + pm_arguments_node_t *cast = (pm_arguments_node_t *) node; + VALUE argv[5]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // arguments +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_new_capa(cast->arguments.size); + for (size_t index = 0; index < cast->arguments.size; index++) { + rb_ary_push(argv[4], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[4]); + + VALUE value = rb_class_new_instance(5, argv, rb_cPrismArgumentsNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_ARRAY_NODE: { + pm_array_node_t *cast = (pm_array_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // elements +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_new_capa(cast->elements.size); + for (size_t index = 0; index < cast->elements.size; index++) { + rb_ary_push(argv[4], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[4]); + + // opening_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = cast->opening_loc.start == NULL ? Qnil : pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // closing_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = cast->closing_loc.start == NULL ? Qnil : pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismArrayNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_ARRAY_PATTERN_NODE: { + pm_array_pattern_node_t *cast = (pm_array_pattern_node_t *) node; + VALUE argv[10]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // constant +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // requireds +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_new_capa(cast->requireds.size); + for (size_t index = 0; index < cast->requireds.size; index++) { + rb_ary_push(argv[5], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[5]); + + // rest +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + // posts +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_new_capa(cast->posts.size); + for (size_t index = 0; index < cast->posts.size; index++) { + rb_ary_push(argv[7], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[7]); + + // opening_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = cast->opening_loc.start == NULL ? Qnil : pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // closing_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[9] = cast->closing_loc.start == NULL ? Qnil : pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(10, argv, rb_cPrismArrayPatternNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_ASSOC_NODE: { + pm_assoc_node_t *cast = (pm_assoc_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // key +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + // operator_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = cast->operator_loc.start == NULL ? Qnil : pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismAssocNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_ASSOC_SPLAT_NODE: { + pm_assoc_splat_node_t *cast = (pm_assoc_splat_node_t *) node; + VALUE argv[6]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(6, argv, rb_cPrismAssocSplatNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_BACK_REFERENCE_READ_NODE: { + pm_back_reference_read_node_t *cast = (pm_back_reference_read_node_t *) node; + VALUE argv[5]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + VALUE value = rb_class_new_instance(5, argv, rb_cPrismBackReferenceReadNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_BEGIN_NODE: { + pm_begin_node_t *cast = (pm_begin_node_t *) node; + VALUE argv[10]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // begin_keyword_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = cast->begin_keyword_loc.start == NULL ? Qnil : pm_location_new(parser, cast->begin_keyword_loc.start, cast->begin_keyword_loc.end, source, freeze); + + // statements +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + // rescue_clause +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + // else_clause +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + // ensure_clause +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = rb_ary_pop(value_stack); + + // end_keyword_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[9] = cast->end_keyword_loc.start == NULL ? Qnil : pm_location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(10, argv, rb_cPrismBeginNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_BLOCK_ARGUMENT_NODE: { + pm_block_argument_node_t *cast = (pm_block_argument_node_t *) node; + VALUE argv[6]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // expression +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(6, argv, rb_cPrismBlockArgumentNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_BLOCK_LOCAL_VARIABLE_NODE: { + pm_block_local_variable_node_t *cast = (pm_block_local_variable_node_t *) node; + VALUE argv[5]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + VALUE value = rb_class_new_instance(5, argv, rb_cPrismBlockLocalVariableNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_BLOCK_NODE: { + pm_block_node_t *cast = (pm_block_node_t *) node; + VALUE argv[9]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // locals +#line 232 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_new_capa(cast->locals.size); + for (size_t index = 0; index < cast->locals.size; index++) { + assert(cast->locals.ids[index] != 0); + rb_ary_push(argv[4], RARRAY_AREF(constants, cast->locals.ids[index] - 1)); + } + if (freeze) rb_obj_freeze(argv[4]); + + // parameters +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + // body +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + // opening_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // closing_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(9, argv, rb_cPrismBlockNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_BLOCK_PARAMETER_NODE: { + pm_block_parameter_node_t *cast = (pm_block_parameter_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name + argv[4] = cast->name == 0 ? Qnil : RARRAY_AREF(constants, cast->name - 1); + + // name_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = cast->name_loc.start == NULL ? Qnil : pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismBlockParameterNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_BLOCK_PARAMETERS_NODE: { + pm_block_parameters_node_t *cast = (pm_block_parameters_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // parameters +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // locals +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_new_capa(cast->locals.size); + for (size_t index = 0; index < cast->locals.size; index++) { + rb_ary_push(argv[5], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[5]); + + // opening_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = cast->opening_loc.start == NULL ? Qnil : pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // closing_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = cast->closing_loc.start == NULL ? Qnil : pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismBlockParametersNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_BREAK_NODE: { + pm_break_node_t *cast = (pm_break_node_t *) node; + VALUE argv[6]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // arguments +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(6, argv, rb_cPrismBreakNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CALL_AND_WRITE_NODE: { + pm_call_and_write_node_t *cast = (pm_call_and_write_node_t *) node; + VALUE argv[11]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // receiver +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // call_operator_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = cast->call_operator_loc.start == NULL ? Qnil : pm_location_new(parser, cast->call_operator_loc.start, cast->call_operator_loc.end, source, freeze); + + // message_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = cast->message_loc.start == NULL ? Qnil : pm_location_new(parser, cast->message_loc.start, cast->message_loc.end, source, freeze); + + // read_name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->read_name != 0); + argv[7] = RARRAY_AREF(constants, cast->read_name - 1); + + // write_name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->write_name != 0); + argv[8] = RARRAY_AREF(constants, cast->write_name - 1); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[9] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[10] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(11, argv, rb_cPrismCallAndWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CALL_NODE: { + pm_call_node_t *cast = (pm_call_node_t *) node; + VALUE argv[12]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // receiver +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // call_operator_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = cast->call_operator_loc.start == NULL ? Qnil : pm_location_new(parser, cast->call_operator_loc.start, cast->call_operator_loc.end, source, freeze); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[6] = RARRAY_AREF(constants, cast->name - 1); + + // message_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = cast->message_loc.start == NULL ? Qnil : pm_location_new(parser, cast->message_loc.start, cast->message_loc.end, source, freeze); + + // opening_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = cast->opening_loc.start == NULL ? Qnil : pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // arguments +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[9] = rb_ary_pop(value_stack); + + // closing_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[10] = cast->closing_loc.start == NULL ? Qnil : pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + // block +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[11] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(12, argv, rb_cPrismCallNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CALL_OPERATOR_WRITE_NODE: { + pm_call_operator_write_node_t *cast = (pm_call_operator_write_node_t *) node; + VALUE argv[12]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // receiver +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // call_operator_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = cast->call_operator_loc.start == NULL ? Qnil : pm_location_new(parser, cast->call_operator_loc.start, cast->call_operator_loc.end, source, freeze); + + // message_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = cast->message_loc.start == NULL ? Qnil : pm_location_new(parser, cast->message_loc.start, cast->message_loc.end, source, freeze); + + // read_name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->read_name != 0); + argv[7] = RARRAY_AREF(constants, cast->read_name - 1); + + // write_name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->write_name != 0); + argv[8] = RARRAY_AREF(constants, cast->write_name - 1); + + // binary_operator +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->binary_operator != 0); + argv[9] = RARRAY_AREF(constants, cast->binary_operator - 1); + + // binary_operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[10] = pm_location_new(parser, cast->binary_operator_loc.start, cast->binary_operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[11] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(12, argv, rb_cPrismCallOperatorWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CALL_OR_WRITE_NODE: { + pm_call_or_write_node_t *cast = (pm_call_or_write_node_t *) node; + VALUE argv[11]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // receiver +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // call_operator_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = cast->call_operator_loc.start == NULL ? Qnil : pm_location_new(parser, cast->call_operator_loc.start, cast->call_operator_loc.end, source, freeze); + + // message_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = cast->message_loc.start == NULL ? Qnil : pm_location_new(parser, cast->message_loc.start, cast->message_loc.end, source, freeze); + + // read_name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->read_name != 0); + argv[7] = RARRAY_AREF(constants, cast->read_name - 1); + + // write_name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->write_name != 0); + argv[8] = RARRAY_AREF(constants, cast->write_name - 1); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[9] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[10] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(11, argv, rb_cPrismCallOrWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CALL_TARGET_NODE: { + pm_call_target_node_t *cast = (pm_call_target_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // receiver +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // call_operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->call_operator_loc.start, cast->call_operator_loc.end, source, freeze); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[6] = RARRAY_AREF(constants, cast->name - 1); + + // message_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = pm_location_new(parser, cast->message_loc.start, cast->message_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismCallTargetNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CAPTURE_PATTERN_NODE: { + pm_capture_pattern_node_t *cast = (pm_capture_pattern_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // target +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismCapturePatternNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CASE_MATCH_NODE: { + pm_case_match_node_t *cast = (pm_case_match_node_t *) node; + VALUE argv[9]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // predicate +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // conditions +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_new_capa(cast->conditions.size); + for (size_t index = 0; index < cast->conditions.size; index++) { + rb_ary_push(argv[5], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[5]); + + // else_clause +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + // case_keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = pm_location_new(parser, cast->case_keyword_loc.start, cast->case_keyword_loc.end, source, freeze); + + // end_keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = pm_location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(9, argv, rb_cPrismCaseMatchNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CASE_NODE: { + pm_case_node_t *cast = (pm_case_node_t *) node; + VALUE argv[9]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // predicate +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // conditions +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_new_capa(cast->conditions.size); + for (size_t index = 0; index < cast->conditions.size; index++) { + rb_ary_push(argv[5], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[5]); + + // else_clause +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + // case_keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = pm_location_new(parser, cast->case_keyword_loc.start, cast->case_keyword_loc.end, source, freeze); + + // end_keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = pm_location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(9, argv, rb_cPrismCaseNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CLASS_NODE: { + pm_class_node_t *cast = (pm_class_node_t *) node; + VALUE argv[12]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // locals +#line 232 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_new_capa(cast->locals.size); + for (size_t index = 0; index < cast->locals.size; index++) { + assert(cast->locals.ids[index] != 0); + rb_ary_push(argv[4], RARRAY_AREF(constants, cast->locals.ids[index] - 1)); + } + if (freeze) rb_obj_freeze(argv[4]); + + // class_keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->class_keyword_loc.start, cast->class_keyword_loc.end, source, freeze); + + // constant_path +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + // inheritance_operator_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = cast->inheritance_operator_loc.start == NULL ? Qnil : pm_location_new(parser, cast->inheritance_operator_loc.start, cast->inheritance_operator_loc.end, source, freeze); + + // superclass +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = rb_ary_pop(value_stack); + + // body +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[9] = rb_ary_pop(value_stack); + + // end_keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[10] = pm_location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source, freeze); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[11] = RARRAY_AREF(constants, cast->name - 1); + + VALUE value = rb_class_new_instance(12, argv, rb_cPrismClassNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CLASS_VARIABLE_AND_WRITE_NODE: { + pm_class_variable_and_write_node_t *cast = (pm_class_variable_and_write_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismClassVariableAndWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE: { + pm_class_variable_operator_write_node_t *cast = (pm_class_variable_operator_write_node_t *) node; + VALUE argv[9]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // binary_operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->binary_operator_loc.start, cast->binary_operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + // binary_operator +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->binary_operator != 0); + argv[8] = RARRAY_AREF(constants, cast->binary_operator - 1); + + VALUE value = rb_class_new_instance(9, argv, rb_cPrismClassVariableOperatorWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CLASS_VARIABLE_OR_WRITE_NODE: { + pm_class_variable_or_write_node_t *cast = (pm_class_variable_or_write_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismClassVariableOrWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CLASS_VARIABLE_READ_NODE: { + pm_class_variable_read_node_t *cast = (pm_class_variable_read_node_t *) node; + VALUE argv[5]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + VALUE value = rb_class_new_instance(5, argv, rb_cPrismClassVariableReadNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CLASS_VARIABLE_TARGET_NODE: { + pm_class_variable_target_node_t *cast = (pm_class_variable_target_node_t *) node; + VALUE argv[5]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + VALUE value = rb_class_new_instance(5, argv, rb_cPrismClassVariableTargetNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CLASS_VARIABLE_WRITE_NODE: { + pm_class_variable_write_node_t *cast = (pm_class_variable_write_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismClassVariableWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CONSTANT_AND_WRITE_NODE: { + pm_constant_and_write_node_t *cast = (pm_constant_and_write_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismConstantAndWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CONSTANT_OPERATOR_WRITE_NODE: { + pm_constant_operator_write_node_t *cast = (pm_constant_operator_write_node_t *) node; + VALUE argv[9]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // binary_operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->binary_operator_loc.start, cast->binary_operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + // binary_operator +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->binary_operator != 0); + argv[8] = RARRAY_AREF(constants, cast->binary_operator - 1); + + VALUE value = rb_class_new_instance(9, argv, rb_cPrismConstantOperatorWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CONSTANT_OR_WRITE_NODE: { + pm_constant_or_write_node_t *cast = (pm_constant_or_write_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismConstantOrWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CONSTANT_PATH_AND_WRITE_NODE: { + pm_constant_path_and_write_node_t *cast = (pm_constant_path_and_write_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // target +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismConstantPathAndWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CONSTANT_PATH_NODE: { + pm_constant_path_node_t *cast = (pm_constant_path_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // parent +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // name + argv[5] = cast->name == 0 ? Qnil : RARRAY_AREF(constants, cast->name - 1); + + // delimiter_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->delimiter_loc.start, cast->delimiter_loc.end, source, freeze); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismConstantPathNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CONSTANT_PATH_OPERATOR_WRITE_NODE: { + pm_constant_path_operator_write_node_t *cast = (pm_constant_path_operator_write_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // target +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // binary_operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->binary_operator_loc.start, cast->binary_operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + // binary_operator +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->binary_operator != 0); + argv[7] = RARRAY_AREF(constants, cast->binary_operator - 1); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismConstantPathOperatorWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CONSTANT_PATH_OR_WRITE_NODE: { + pm_constant_path_or_write_node_t *cast = (pm_constant_path_or_write_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // target +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismConstantPathOrWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CONSTANT_PATH_TARGET_NODE: { + pm_constant_path_target_node_t *cast = (pm_constant_path_target_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // parent +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // name + argv[5] = cast->name == 0 ? Qnil : RARRAY_AREF(constants, cast->name - 1); + + // delimiter_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->delimiter_loc.start, cast->delimiter_loc.end, source, freeze); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismConstantPathTargetNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CONSTANT_PATH_WRITE_NODE: { + pm_constant_path_write_node_t *cast = (pm_constant_path_write_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // target +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismConstantPathWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CONSTANT_READ_NODE: { + pm_constant_read_node_t *cast = (pm_constant_read_node_t *) node; + VALUE argv[5]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + VALUE value = rb_class_new_instance(5, argv, rb_cPrismConstantReadNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CONSTANT_TARGET_NODE: { + pm_constant_target_node_t *cast = (pm_constant_target_node_t *) node; + VALUE argv[5]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + VALUE value = rb_class_new_instance(5, argv, rb_cPrismConstantTargetNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_CONSTANT_WRITE_NODE: { + pm_constant_write_node_t *cast = (pm_constant_write_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismConstantWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_DEF_NODE: { + pm_def_node_t *cast = (pm_def_node_t *) node; + VALUE argv[16]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // receiver +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + // parameters +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + // body +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = rb_ary_pop(value_stack); + + // locals +#line 232 "prism/templates/ext/prism/api_node.c.erb" + argv[9] = rb_ary_new_capa(cast->locals.size); + for (size_t index = 0; index < cast->locals.size; index++) { + assert(cast->locals.ids[index] != 0); + rb_ary_push(argv[9], RARRAY_AREF(constants, cast->locals.ids[index] - 1)); + } + if (freeze) rb_obj_freeze(argv[9]); + + // def_keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[10] = pm_location_new(parser, cast->def_keyword_loc.start, cast->def_keyword_loc.end, source, freeze); + + // operator_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[11] = cast->operator_loc.start == NULL ? Qnil : pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // lparen_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[12] = cast->lparen_loc.start == NULL ? Qnil : pm_location_new(parser, cast->lparen_loc.start, cast->lparen_loc.end, source, freeze); + + // rparen_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[13] = cast->rparen_loc.start == NULL ? Qnil : pm_location_new(parser, cast->rparen_loc.start, cast->rparen_loc.end, source, freeze); + + // equal_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[14] = cast->equal_loc.start == NULL ? Qnil : pm_location_new(parser, cast->equal_loc.start, cast->equal_loc.end, source, freeze); + + // end_keyword_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[15] = cast->end_keyword_loc.start == NULL ? Qnil : pm_location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(16, argv, rb_cPrismDefNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_DEFINED_NODE: { + pm_defined_node_t *cast = (pm_defined_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // lparen_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = cast->lparen_loc.start == NULL ? Qnil : pm_location_new(parser, cast->lparen_loc.start, cast->lparen_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + // rparen_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = cast->rparen_loc.start == NULL ? Qnil : pm_location_new(parser, cast->rparen_loc.start, cast->rparen_loc.end, source, freeze); + + // keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = pm_location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismDefinedNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_ELSE_NODE: { + pm_else_node_t *cast = (pm_else_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // else_keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_location_new(parser, cast->else_keyword_loc.start, cast->else_keyword_loc.end, source, freeze); + + // statements +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + // end_keyword_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = cast->end_keyword_loc.start == NULL ? Qnil : pm_location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismElseNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_EMBEDDED_STATEMENTS_NODE: { + pm_embedded_statements_node_t *cast = (pm_embedded_statements_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // opening_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // statements +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + // closing_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismEmbeddedStatementsNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_EMBEDDED_VARIABLE_NODE: { + pm_embedded_variable_node_t *cast = (pm_embedded_variable_node_t *) node; + VALUE argv[6]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // variable +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(6, argv, rb_cPrismEmbeddedVariableNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_ENSURE_NODE: { + pm_ensure_node_t *cast = (pm_ensure_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // ensure_keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_location_new(parser, cast->ensure_keyword_loc.start, cast->ensure_keyword_loc.end, source, freeze); + + // statements +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + // end_keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismEnsureNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_FALSE_NODE: { + VALUE argv[4]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + VALUE value = rb_class_new_instance(4, argv, rb_cPrismFalseNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_FIND_PATTERN_NODE: { + pm_find_pattern_node_t *cast = (pm_find_pattern_node_t *) node; + VALUE argv[10]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // constant +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // left +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + // requireds +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_new_capa(cast->requireds.size); + for (size_t index = 0; index < cast->requireds.size; index++) { + rb_ary_push(argv[6], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[6]); + + // right +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + // opening_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = cast->opening_loc.start == NULL ? Qnil : pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // closing_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[9] = cast->closing_loc.start == NULL ? Qnil : pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(10, argv, rb_cPrismFindPatternNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_FLIP_FLOP_NODE: { + pm_flip_flop_node_t *cast = (pm_flip_flop_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // left +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // right +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismFlipFlopNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_FLOAT_NODE: { + pm_float_node_t *cast = (pm_float_node_t *) node; + VALUE argv[5]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // value +#line 255 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = DBL2NUM(cast->value); + + VALUE value = rb_class_new_instance(5, argv, rb_cPrismFloatNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_FOR_NODE: { + pm_for_node_t *cast = (pm_for_node_t *) node; + VALUE argv[11]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // index +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // collection +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + // statements +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + // for_keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = pm_location_new(parser, cast->for_keyword_loc.start, cast->for_keyword_loc.end, source, freeze); + + // in_keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = pm_location_new(parser, cast->in_keyword_loc.start, cast->in_keyword_loc.end, source, freeze); + + // do_keyword_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[9] = cast->do_keyword_loc.start == NULL ? Qnil : pm_location_new(parser, cast->do_keyword_loc.start, cast->do_keyword_loc.end, source, freeze); + + // end_keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[10] = pm_location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(11, argv, rb_cPrismForNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_FORWARDING_ARGUMENTS_NODE: { + VALUE argv[4]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + VALUE value = rb_class_new_instance(4, argv, rb_cPrismForwardingArgumentsNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_FORWARDING_PARAMETER_NODE: { + VALUE argv[4]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + VALUE value = rb_class_new_instance(4, argv, rb_cPrismForwardingParameterNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_FORWARDING_SUPER_NODE: { + VALUE argv[5]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // block +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(5, argv, rb_cPrismForwardingSuperNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_GLOBAL_VARIABLE_AND_WRITE_NODE: { + pm_global_variable_and_write_node_t *cast = (pm_global_variable_and_write_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismGlobalVariableAndWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE: { + pm_global_variable_operator_write_node_t *cast = (pm_global_variable_operator_write_node_t *) node; + VALUE argv[9]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // binary_operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->binary_operator_loc.start, cast->binary_operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + // binary_operator +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->binary_operator != 0); + argv[8] = RARRAY_AREF(constants, cast->binary_operator - 1); + + VALUE value = rb_class_new_instance(9, argv, rb_cPrismGlobalVariableOperatorWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_GLOBAL_VARIABLE_OR_WRITE_NODE: { + pm_global_variable_or_write_node_t *cast = (pm_global_variable_or_write_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismGlobalVariableOrWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_GLOBAL_VARIABLE_READ_NODE: { + pm_global_variable_read_node_t *cast = (pm_global_variable_read_node_t *) node; + VALUE argv[5]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + VALUE value = rb_class_new_instance(5, argv, rb_cPrismGlobalVariableReadNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_GLOBAL_VARIABLE_TARGET_NODE: { + pm_global_variable_target_node_t *cast = (pm_global_variable_target_node_t *) node; + VALUE argv[5]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + VALUE value = rb_class_new_instance(5, argv, rb_cPrismGlobalVariableTargetNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_GLOBAL_VARIABLE_WRITE_NODE: { + pm_global_variable_write_node_t *cast = (pm_global_variable_write_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismGlobalVariableWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_HASH_NODE: { + pm_hash_node_t *cast = (pm_hash_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // opening_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // elements +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_new_capa(cast->elements.size); + for (size_t index = 0; index < cast->elements.size; index++) { + rb_ary_push(argv[5], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[5]); + + // closing_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismHashNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_HASH_PATTERN_NODE: { + pm_hash_pattern_node_t *cast = (pm_hash_pattern_node_t *) node; + VALUE argv[9]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // constant +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // elements +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_new_capa(cast->elements.size); + for (size_t index = 0; index < cast->elements.size; index++) { + rb_ary_push(argv[5], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[5]); + + // rest +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + // opening_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = cast->opening_loc.start == NULL ? Qnil : pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // closing_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = cast->closing_loc.start == NULL ? Qnil : pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(9, argv, rb_cPrismHashPatternNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_IF_NODE: { + pm_if_node_t *cast = (pm_if_node_t *) node; + VALUE argv[10]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // if_keyword_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = cast->if_keyword_loc.start == NULL ? Qnil : pm_location_new(parser, cast->if_keyword_loc.start, cast->if_keyword_loc.end, source, freeze); + + // predicate +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + // then_keyword_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = cast->then_keyword_loc.start == NULL ? Qnil : pm_location_new(parser, cast->then_keyword_loc.start, cast->then_keyword_loc.end, source, freeze); + + // statements +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + // subsequent +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = rb_ary_pop(value_stack); + + // end_keyword_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[9] = cast->end_keyword_loc.start == NULL ? Qnil : pm_location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(10, argv, rb_cPrismIfNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_IMAGINARY_NODE: { + VALUE argv[5]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // numeric +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(5, argv, rb_cPrismImaginaryNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_IMPLICIT_NODE: { + VALUE argv[5]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(5, argv, rb_cPrismImplicitNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_IMPLICIT_REST_NODE: { + VALUE argv[4]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + VALUE value = rb_class_new_instance(4, argv, rb_cPrismImplicitRestNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_IN_NODE: { + pm_in_node_t *cast = (pm_in_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // pattern +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // statements +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + // in_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->in_loc.start, cast->in_loc.end, source, freeze); + + // then_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = cast->then_loc.start == NULL ? Qnil : pm_location_new(parser, cast->then_loc.start, cast->then_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismInNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_INDEX_AND_WRITE_NODE: { + pm_index_and_write_node_t *cast = (pm_index_and_write_node_t *) node; + VALUE argv[12]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // receiver +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // call_operator_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = cast->call_operator_loc.start == NULL ? Qnil : pm_location_new(parser, cast->call_operator_loc.start, cast->call_operator_loc.end, source, freeze); + + // opening_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // arguments +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + // closing_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + // block +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[9] = rb_ary_pop(value_stack); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[10] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[11] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(12, argv, rb_cPrismIndexAndWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_INDEX_OPERATOR_WRITE_NODE: { + pm_index_operator_write_node_t *cast = (pm_index_operator_write_node_t *) node; + VALUE argv[13]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // receiver +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // call_operator_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = cast->call_operator_loc.start == NULL ? Qnil : pm_location_new(parser, cast->call_operator_loc.start, cast->call_operator_loc.end, source, freeze); + + // opening_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // arguments +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + // closing_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + // block +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[9] = rb_ary_pop(value_stack); + + // binary_operator +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->binary_operator != 0); + argv[10] = RARRAY_AREF(constants, cast->binary_operator - 1); + + // binary_operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[11] = pm_location_new(parser, cast->binary_operator_loc.start, cast->binary_operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[12] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(13, argv, rb_cPrismIndexOperatorWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_INDEX_OR_WRITE_NODE: { + pm_index_or_write_node_t *cast = (pm_index_or_write_node_t *) node; + VALUE argv[12]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // receiver +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // call_operator_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = cast->call_operator_loc.start == NULL ? Qnil : pm_location_new(parser, cast->call_operator_loc.start, cast->call_operator_loc.end, source, freeze); + + // opening_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // arguments +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + // closing_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + // block +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[9] = rb_ary_pop(value_stack); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[10] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[11] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(12, argv, rb_cPrismIndexOrWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_INDEX_TARGET_NODE: { + pm_index_target_node_t *cast = (pm_index_target_node_t *) node; + VALUE argv[9]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // receiver +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // opening_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // arguments +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + // closing_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + // block +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(9, argv, rb_cPrismIndexTargetNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_INSTANCE_VARIABLE_AND_WRITE_NODE: { + pm_instance_variable_and_write_node_t *cast = (pm_instance_variable_and_write_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismInstanceVariableAndWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE: { + pm_instance_variable_operator_write_node_t *cast = (pm_instance_variable_operator_write_node_t *) node; + VALUE argv[9]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // binary_operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->binary_operator_loc.start, cast->binary_operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + // binary_operator +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->binary_operator != 0); + argv[8] = RARRAY_AREF(constants, cast->binary_operator - 1); + + VALUE value = rb_class_new_instance(9, argv, rb_cPrismInstanceVariableOperatorWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_INSTANCE_VARIABLE_OR_WRITE_NODE: { + pm_instance_variable_or_write_node_t *cast = (pm_instance_variable_or_write_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismInstanceVariableOrWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_INSTANCE_VARIABLE_READ_NODE: { + pm_instance_variable_read_node_t *cast = (pm_instance_variable_read_node_t *) node; + VALUE argv[5]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + VALUE value = rb_class_new_instance(5, argv, rb_cPrismInstanceVariableReadNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_INSTANCE_VARIABLE_TARGET_NODE: { + pm_instance_variable_target_node_t *cast = (pm_instance_variable_target_node_t *) node; + VALUE argv[5]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + VALUE value = rb_class_new_instance(5, argv, rb_cPrismInstanceVariableTargetNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_INSTANCE_VARIABLE_WRITE_NODE: { + pm_instance_variable_write_node_t *cast = (pm_instance_variable_write_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismInstanceVariableWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_INTEGER_NODE: { + pm_integer_node_t *cast = (pm_integer_node_t *) node; + VALUE argv[5]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // value +#line 252 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_integer_new(&cast->value); + + VALUE value = rb_class_new_instance(5, argv, rb_cPrismIntegerNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_INTERPOLATED_MATCH_LAST_LINE_NODE: { + pm_interpolated_match_last_line_node_t *cast = (pm_interpolated_match_last_line_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // opening_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // parts +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_new_capa(cast->parts.size); + for (size_t index = 0; index < cast->parts.size; index++) { + rb_ary_push(argv[5], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[5]); + + // closing_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismInterpolatedMatchLastLineNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE: { + pm_interpolated_regular_expression_node_t *cast = (pm_interpolated_regular_expression_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // opening_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // parts +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_new_capa(cast->parts.size); + for (size_t index = 0; index < cast->parts.size; index++) { + rb_ary_push(argv[5], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[5]); + + // closing_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismInterpolatedRegularExpressionNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_INTERPOLATED_STRING_NODE: { + pm_interpolated_string_node_t *cast = (pm_interpolated_string_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // opening_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = cast->opening_loc.start == NULL ? Qnil : pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // parts +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_new_capa(cast->parts.size); + for (size_t index = 0; index < cast->parts.size; index++) { + rb_ary_push(argv[5], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[5]); + + // closing_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = cast->closing_loc.start == NULL ? Qnil : pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismInterpolatedStringNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_INTERPOLATED_SYMBOL_NODE: { + pm_interpolated_symbol_node_t *cast = (pm_interpolated_symbol_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // opening_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = cast->opening_loc.start == NULL ? Qnil : pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // parts +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_new_capa(cast->parts.size); + for (size_t index = 0; index < cast->parts.size; index++) { + rb_ary_push(argv[5], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[5]); + + // closing_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = cast->closing_loc.start == NULL ? Qnil : pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismInterpolatedSymbolNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_INTERPOLATED_X_STRING_NODE: { + pm_interpolated_x_string_node_t *cast = (pm_interpolated_x_string_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // opening_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // parts +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_new_capa(cast->parts.size); + for (size_t index = 0; index < cast->parts.size; index++) { + rb_ary_push(argv[5], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[5]); + + // closing_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismInterpolatedXStringNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_IT_LOCAL_VARIABLE_READ_NODE: { + VALUE argv[4]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + VALUE value = rb_class_new_instance(4, argv, rb_cPrismItLocalVariableReadNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_IT_PARAMETERS_NODE: { + VALUE argv[4]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + VALUE value = rb_class_new_instance(4, argv, rb_cPrismItParametersNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_KEYWORD_HASH_NODE: { + pm_keyword_hash_node_t *cast = (pm_keyword_hash_node_t *) node; + VALUE argv[5]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // elements +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_new_capa(cast->elements.size); + for (size_t index = 0; index < cast->elements.size; index++) { + rb_ary_push(argv[4], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[4]); + + VALUE value = rb_class_new_instance(5, argv, rb_cPrismKeywordHashNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_KEYWORD_REST_PARAMETER_NODE: { + pm_keyword_rest_parameter_node_t *cast = (pm_keyword_rest_parameter_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name + argv[4] = cast->name == 0 ? Qnil : RARRAY_AREF(constants, cast->name - 1); + + // name_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = cast->name_loc.start == NULL ? Qnil : pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismKeywordRestParameterNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_LAMBDA_NODE: { + pm_lambda_node_t *cast = (pm_lambda_node_t *) node; + VALUE argv[10]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // locals +#line 232 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_new_capa(cast->locals.size); + for (size_t index = 0; index < cast->locals.size; index++) { + assert(cast->locals.ids[index] != 0); + rb_ary_push(argv[4], RARRAY_AREF(constants, cast->locals.ids[index] - 1)); + } + if (freeze) rb_obj_freeze(argv[4]); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // opening_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // closing_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + // parameters +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = rb_ary_pop(value_stack); + + // body +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[9] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(10, argv, rb_cPrismLambdaNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_LOCAL_VARIABLE_AND_WRITE_NODE: { + pm_local_variable_and_write_node_t *cast = (pm_local_variable_and_write_node_t *) node; + VALUE argv[9]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[7] = RARRAY_AREF(constants, cast->name - 1); + + // depth +#line 249 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = ULONG2NUM(cast->depth); + + VALUE value = rb_class_new_instance(9, argv, rb_cPrismLocalVariableAndWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE: { + pm_local_variable_operator_write_node_t *cast = (pm_local_variable_operator_write_node_t *) node; + VALUE argv[10]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // binary_operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->binary_operator_loc.start, cast->binary_operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[7] = RARRAY_AREF(constants, cast->name - 1); + + // binary_operator +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->binary_operator != 0); + argv[8] = RARRAY_AREF(constants, cast->binary_operator - 1); + + // depth +#line 249 "prism/templates/ext/prism/api_node.c.erb" + argv[9] = ULONG2NUM(cast->depth); + + VALUE value = rb_class_new_instance(10, argv, rb_cPrismLocalVariableOperatorWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_LOCAL_VARIABLE_OR_WRITE_NODE: { + pm_local_variable_or_write_node_t *cast = (pm_local_variable_or_write_node_t *) node; + VALUE argv[9]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[7] = RARRAY_AREF(constants, cast->name - 1); + + // depth +#line 249 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = ULONG2NUM(cast->depth); + + VALUE value = rb_class_new_instance(9, argv, rb_cPrismLocalVariableOrWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_LOCAL_VARIABLE_READ_NODE: { + pm_local_variable_read_node_t *cast = (pm_local_variable_read_node_t *) node; + VALUE argv[6]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + // depth +#line 249 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = ULONG2NUM(cast->depth); + + VALUE value = rb_class_new_instance(6, argv, rb_cPrismLocalVariableReadNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_LOCAL_VARIABLE_TARGET_NODE: { + pm_local_variable_target_node_t *cast = (pm_local_variable_target_node_t *) node; + VALUE argv[6]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + // depth +#line 249 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = ULONG2NUM(cast->depth); + + VALUE value = rb_class_new_instance(6, argv, rb_cPrismLocalVariableTargetNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_LOCAL_VARIABLE_WRITE_NODE: { + pm_local_variable_write_node_t *cast = (pm_local_variable_write_node_t *) node; + VALUE argv[9]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + // depth +#line 249 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = ULONG2NUM(cast->depth); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(9, argv, rb_cPrismLocalVariableWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_MATCH_LAST_LINE_NODE: { + pm_match_last_line_node_t *cast = (pm_match_last_line_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // opening_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // content_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->content_loc.start, cast->content_loc.end, source, freeze); + + // closing_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + // unescaped +#line 223 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = pm_string_new(&cast->unescaped, encoding); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismMatchLastLineNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_MATCH_PREDICATE_NODE: { + pm_match_predicate_node_t *cast = (pm_match_predicate_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // pattern +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismMatchPredicateNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_MATCH_REQUIRED_NODE: { + pm_match_required_node_t *cast = (pm_match_required_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // pattern +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismMatchRequiredNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_MATCH_WRITE_NODE: { + pm_match_write_node_t *cast = (pm_match_write_node_t *) node; + VALUE argv[6]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // call +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // targets +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_new_capa(cast->targets.size); + for (size_t index = 0; index < cast->targets.size; index++) { + rb_ary_push(argv[5], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[5]); + + VALUE value = rb_class_new_instance(6, argv, rb_cPrismMatchWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_MISSING_NODE: { + VALUE argv[4]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + VALUE value = rb_class_new_instance(4, argv, rb_cPrismMissingNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_MODULE_NODE: { + pm_module_node_t *cast = (pm_module_node_t *) node; + VALUE argv[10]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // locals +#line 232 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_new_capa(cast->locals.size); + for (size_t index = 0; index < cast->locals.size; index++) { + assert(cast->locals.ids[index] != 0); + rb_ary_push(argv[4], RARRAY_AREF(constants, cast->locals.ids[index] - 1)); + } + if (freeze) rb_obj_freeze(argv[4]); + + // module_keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->module_keyword_loc.start, cast->module_keyword_loc.end, source, freeze); + + // constant_path +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + // body +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + // end_keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = pm_location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source, freeze); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[9] = RARRAY_AREF(constants, cast->name - 1); + + VALUE value = rb_class_new_instance(10, argv, rb_cPrismModuleNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_MULTI_TARGET_NODE: { + pm_multi_target_node_t *cast = (pm_multi_target_node_t *) node; + VALUE argv[9]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // lefts +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_new_capa(cast->lefts.size); + for (size_t index = 0; index < cast->lefts.size; index++) { + rb_ary_push(argv[4], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[4]); + + // rest +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + // rights +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_new_capa(cast->rights.size); + for (size_t index = 0; index < cast->rights.size; index++) { + rb_ary_push(argv[6], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[6]); + + // lparen_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = cast->lparen_loc.start == NULL ? Qnil : pm_location_new(parser, cast->lparen_loc.start, cast->lparen_loc.end, source, freeze); + + // rparen_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = cast->rparen_loc.start == NULL ? Qnil : pm_location_new(parser, cast->rparen_loc.start, cast->rparen_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(9, argv, rb_cPrismMultiTargetNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_MULTI_WRITE_NODE: { + pm_multi_write_node_t *cast = (pm_multi_write_node_t *) node; + VALUE argv[11]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // lefts +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_new_capa(cast->lefts.size); + for (size_t index = 0; index < cast->lefts.size; index++) { + rb_ary_push(argv[4], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[4]); + + // rest +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + // rights +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_new_capa(cast->rights.size); + for (size_t index = 0; index < cast->rights.size; index++) { + rb_ary_push(argv[6], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[6]); + + // lparen_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = cast->lparen_loc.start == NULL ? Qnil : pm_location_new(parser, cast->lparen_loc.start, cast->lparen_loc.end, source, freeze); + + // rparen_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = cast->rparen_loc.start == NULL ? Qnil : pm_location_new(parser, cast->rparen_loc.start, cast->rparen_loc.end, source, freeze); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[9] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[10] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(11, argv, rb_cPrismMultiWriteNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_NEXT_NODE: { + pm_next_node_t *cast = (pm_next_node_t *) node; + VALUE argv[6]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // arguments +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(6, argv, rb_cPrismNextNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_NIL_NODE: { + VALUE argv[4]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + VALUE value = rb_class_new_instance(4, argv, rb_cPrismNilNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_NO_KEYWORDS_PARAMETER_NODE: { + pm_no_keywords_parameter_node_t *cast = (pm_no_keywords_parameter_node_t *) node; + VALUE argv[6]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(6, argv, rb_cPrismNoKeywordsParameterNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_NUMBERED_PARAMETERS_NODE: { + pm_numbered_parameters_node_t *cast = (pm_numbered_parameters_node_t *) node; + VALUE argv[5]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // maximum +#line 246 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = UINT2NUM(cast->maximum); + + VALUE value = rb_class_new_instance(5, argv, rb_cPrismNumberedParametersNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_NUMBERED_REFERENCE_READ_NODE: { + pm_numbered_reference_read_node_t *cast = (pm_numbered_reference_read_node_t *) node; + VALUE argv[5]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // number +#line 249 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = ULONG2NUM(cast->number); + + VALUE value = rb_class_new_instance(5, argv, rb_cPrismNumberedReferenceReadNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_OPTIONAL_KEYWORD_PARAMETER_NODE: { + pm_optional_keyword_parameter_node_t *cast = (pm_optional_keyword_parameter_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismOptionalKeywordParameterNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_OPTIONAL_PARAMETER_NODE: { + pm_optional_parameter_node_t *cast = (pm_optional_parameter_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // value +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismOptionalParameterNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_OR_NODE: { + pm_or_node_t *cast = (pm_or_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // left +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // right +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismOrNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_PARAMETERS_NODE: { + pm_parameters_node_t *cast = (pm_parameters_node_t *) node; + VALUE argv[11]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // requireds +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_new_capa(cast->requireds.size); + for (size_t index = 0; index < cast->requireds.size; index++) { + rb_ary_push(argv[4], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[4]); + + // optionals +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_new_capa(cast->optionals.size); + for (size_t index = 0; index < cast->optionals.size; index++) { + rb_ary_push(argv[5], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[5]); + + // rest +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + // posts +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_new_capa(cast->posts.size); + for (size_t index = 0; index < cast->posts.size; index++) { + rb_ary_push(argv[7], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[7]); + + // keywords +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = rb_ary_new_capa(cast->keywords.size); + for (size_t index = 0; index < cast->keywords.size; index++) { + rb_ary_push(argv[8], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[8]); + + // keyword_rest +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[9] = rb_ary_pop(value_stack); + + // block +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[10] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(11, argv, rb_cPrismParametersNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_PARENTHESES_NODE: { + pm_parentheses_node_t *cast = (pm_parentheses_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // body +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // opening_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // closing_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismParenthesesNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_PINNED_EXPRESSION_NODE: { + pm_pinned_expression_node_t *cast = (pm_pinned_expression_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // expression +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // lparen_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->lparen_loc.start, cast->lparen_loc.end, source, freeze); + + // rparen_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = pm_location_new(parser, cast->rparen_loc.start, cast->rparen_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismPinnedExpressionNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_PINNED_VARIABLE_NODE: { + pm_pinned_variable_node_t *cast = (pm_pinned_variable_node_t *) node; + VALUE argv[6]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // variable +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(6, argv, rb_cPrismPinnedVariableNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_POST_EXECUTION_NODE: { + pm_post_execution_node_t *cast = (pm_post_execution_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // statements +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source, freeze); + + // opening_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // closing_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismPostExecutionNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_PRE_EXECUTION_NODE: { + pm_pre_execution_node_t *cast = (pm_pre_execution_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // statements +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source, freeze); + + // opening_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // closing_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismPreExecutionNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_PROGRAM_NODE: { + pm_program_node_t *cast = (pm_program_node_t *) node; + VALUE argv[6]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // locals +#line 232 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_new_capa(cast->locals.size); + for (size_t index = 0; index < cast->locals.size; index++) { + assert(cast->locals.ids[index] != 0); + rb_ary_push(argv[4], RARRAY_AREF(constants, cast->locals.ids[index] - 1)); + } + if (freeze) rb_obj_freeze(argv[4]); + + // statements +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(6, argv, rb_cPrismProgramNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_RANGE_NODE: { + pm_range_node_t *cast = (pm_range_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // left +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // right +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismRangeNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_RATIONAL_NODE: { + pm_rational_node_t *cast = (pm_rational_node_t *) node; + VALUE argv[6]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // numerator +#line 252 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_integer_new(&cast->numerator); + + // denominator +#line 252 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_integer_new(&cast->denominator); + + VALUE value = rb_class_new_instance(6, argv, rb_cPrismRationalNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_REDO_NODE: { + VALUE argv[4]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + VALUE value = rb_class_new_instance(4, argv, rb_cPrismRedoNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_REGULAR_EXPRESSION_NODE: { + pm_regular_expression_node_t *cast = (pm_regular_expression_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // opening_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // content_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->content_loc.start, cast->content_loc.end, source, freeze); + + // closing_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + // unescaped +#line 223 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = pm_string_new(&cast->unescaped, encoding); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismRegularExpressionNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_REQUIRED_KEYWORD_PARAMETER_NODE: { + pm_required_keyword_parameter_node_t *cast = (pm_required_keyword_parameter_node_t *) node; + VALUE argv[6]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + // name_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(6, argv, rb_cPrismRequiredKeywordParameterNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_REQUIRED_PARAMETER_NODE: { + pm_required_parameter_node_t *cast = (pm_required_parameter_node_t *) node; + VALUE argv[5]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name +#line 226 "prism/templates/ext/prism/api_node.c.erb" + assert(cast->name != 0); + argv[4] = RARRAY_AREF(constants, cast->name - 1); + + VALUE value = rb_class_new_instance(5, argv, rb_cPrismRequiredParameterNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_RESCUE_MODIFIER_NODE: { + pm_rescue_modifier_node_t *cast = (pm_rescue_modifier_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // expression +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + // keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source, freeze); + + // rescue_expression +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismRescueModifierNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_RESCUE_NODE: { + pm_rescue_node_t *cast = (pm_rescue_node_t *) node; + VALUE argv[11]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source, freeze); + + // exceptions +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_new_capa(cast->exceptions.size); + for (size_t index = 0; index < cast->exceptions.size; index++) { + rb_ary_push(argv[5], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[5]); + + // operator_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = cast->operator_loc.start == NULL ? Qnil : pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // reference +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + // then_keyword_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = cast->then_keyword_loc.start == NULL ? Qnil : pm_location_new(parser, cast->then_keyword_loc.start, cast->then_keyword_loc.end, source, freeze); + + // statements +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[9] = rb_ary_pop(value_stack); + + // subsequent +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[10] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(11, argv, rb_cPrismRescueNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_REST_PARAMETER_NODE: { + pm_rest_parameter_node_t *cast = (pm_rest_parameter_node_t *) node; + VALUE argv[7]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // name + argv[4] = cast->name == 0 ? Qnil : RARRAY_AREF(constants, cast->name - 1); + + // name_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = cast->name_loc.start == NULL ? Qnil : pm_location_new(parser, cast->name_loc.start, cast->name_loc.end, source, freeze); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(7, argv, rb_cPrismRestParameterNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_RETRY_NODE: { + VALUE argv[4]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + VALUE value = rb_class_new_instance(4, argv, rb_cPrismRetryNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_RETURN_NODE: { + pm_return_node_t *cast = (pm_return_node_t *) node; + VALUE argv[6]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source, freeze); + + // arguments +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(6, argv, rb_cPrismReturnNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_SELF_NODE: { + VALUE argv[4]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + VALUE value = rb_class_new_instance(4, argv, rb_cPrismSelfNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_SHAREABLE_CONSTANT_NODE: { + VALUE argv[5]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // write +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(5, argv, rb_cPrismShareableConstantNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_SINGLETON_CLASS_NODE: { + pm_singleton_class_node_t *cast = (pm_singleton_class_node_t *) node; + VALUE argv[10]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // locals +#line 232 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_new_capa(cast->locals.size); + for (size_t index = 0; index < cast->locals.size; index++) { + assert(cast->locals.ids[index] != 0); + rb_ary_push(argv[4], RARRAY_AREF(constants, cast->locals.ids[index] - 1)); + } + if (freeze) rb_obj_freeze(argv[4]); + + // class_keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->class_keyword_loc.start, cast->class_keyword_loc.end, source, freeze); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // expression +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + // body +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = rb_ary_pop(value_stack); + + // end_keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[9] = pm_location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(10, argv, rb_cPrismSingletonClassNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_SOURCE_ENCODING_NODE: { + VALUE argv[4]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + VALUE value = rb_class_new_instance(4, argv, rb_cPrismSourceEncodingNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_SOURCE_FILE_NODE: { + pm_source_file_node_t *cast = (pm_source_file_node_t *) node; + VALUE argv[5]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // filepath +#line 223 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_string_new(&cast->filepath, encoding); + + VALUE value = rb_class_new_instance(5, argv, rb_cPrismSourceFileNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_SOURCE_LINE_NODE: { + VALUE argv[4]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + VALUE value = rb_class_new_instance(4, argv, rb_cPrismSourceLineNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_SPLAT_NODE: { + pm_splat_node_t *cast = (pm_splat_node_t *) node; + VALUE argv[6]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // operator_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source, freeze); + + // expression +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(6, argv, rb_cPrismSplatNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_STATEMENTS_NODE: { + pm_statements_node_t *cast = (pm_statements_node_t *) node; + VALUE argv[5]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // body +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_new_capa(cast->body.size); + for (size_t index = 0; index < cast->body.size; index++) { + rb_ary_push(argv[4], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[4]); + + VALUE value = rb_class_new_instance(5, argv, rb_cPrismStatementsNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_STRING_NODE: { + pm_string_node_t *cast = (pm_string_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // opening_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = cast->opening_loc.start == NULL ? Qnil : pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // content_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->content_loc.start, cast->content_loc.end, source, freeze); + + // closing_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = cast->closing_loc.start == NULL ? Qnil : pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + // unescaped +#line 223 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = pm_string_new(&cast->unescaped, encoding); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismStringNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_SUPER_NODE: { + pm_super_node_t *cast = (pm_super_node_t *) node; + VALUE argv[9]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source, freeze); + + // lparen_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = cast->lparen_loc.start == NULL ? Qnil : pm_location_new(parser, cast->lparen_loc.start, cast->lparen_loc.end, source, freeze); + + // arguments +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + // rparen_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = cast->rparen_loc.start == NULL ? Qnil : pm_location_new(parser, cast->rparen_loc.start, cast->rparen_loc.end, source, freeze); + + // block +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(9, argv, rb_cPrismSuperNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_SYMBOL_NODE: { + pm_symbol_node_t *cast = (pm_symbol_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // opening_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = cast->opening_loc.start == NULL ? Qnil : pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // value_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = cast->value_loc.start == NULL ? Qnil : pm_location_new(parser, cast->value_loc.start, cast->value_loc.end, source, freeze); + + // closing_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = cast->closing_loc.start == NULL ? Qnil : pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + // unescaped +#line 223 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = pm_string_new(&cast->unescaped, encoding); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismSymbolNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_TRUE_NODE: { + VALUE argv[4]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + VALUE value = rb_class_new_instance(4, argv, rb_cPrismTrueNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_UNDEF_NODE: { + pm_undef_node_t *cast = (pm_undef_node_t *) node; + VALUE argv[6]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // names +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = rb_ary_new_capa(cast->names.size); + for (size_t index = 0; index < cast->names.size; index++) { + rb_ary_push(argv[4], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[4]); + + // keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(6, argv, rb_cPrismUndefNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_UNLESS_NODE: { + pm_unless_node_t *cast = (pm_unless_node_t *) node; + VALUE argv[10]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source, freeze); + + // predicate +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_pop(value_stack); + + // then_keyword_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = cast->then_keyword_loc.start == NULL ? Qnil : pm_location_new(parser, cast->then_keyword_loc.start, cast->then_keyword_loc.end, source, freeze); + + // statements +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + // else_clause +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = rb_ary_pop(value_stack); + + // end_keyword_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[9] = cast->end_keyword_loc.start == NULL ? Qnil : pm_location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(10, argv, rb_cPrismUnlessNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_UNTIL_NODE: { + pm_until_node_t *cast = (pm_until_node_t *) node; + VALUE argv[9]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source, freeze); + + // do_keyword_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = cast->do_keyword_loc.start == NULL ? Qnil : pm_location_new(parser, cast->do_keyword_loc.start, cast->do_keyword_loc.end, source, freeze); + + // closing_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = cast->closing_loc.start == NULL ? Qnil : pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + // predicate +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + // statements +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(9, argv, rb_cPrismUntilNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_WHEN_NODE: { + pm_when_node_t *cast = (pm_when_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source, freeze); + + // conditions +#line 216 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = rb_ary_new_capa(cast->conditions.size); + for (size_t index = 0; index < cast->conditions.size; index++) { + rb_ary_push(argv[5], rb_ary_pop(value_stack)); + } + if (freeze) rb_obj_freeze(argv[5]); + + // then_keyword_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = cast->then_keyword_loc.start == NULL ? Qnil : pm_location_new(parser, cast->then_keyword_loc.start, cast->then_keyword_loc.end, source, freeze); + + // statements +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismWhenNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_WHILE_NODE: { + pm_while_node_t *cast = (pm_while_node_t *) node; + VALUE argv[9]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source, freeze); + + // do_keyword_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = cast->do_keyword_loc.start == NULL ? Qnil : pm_location_new(parser, cast->do_keyword_loc.start, cast->do_keyword_loc.end, source, freeze); + + // closing_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = cast->closing_loc.start == NULL ? Qnil : pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + // predicate +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = rb_ary_pop(value_stack); + + // statements +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[8] = rb_ary_pop(value_stack); + + VALUE value = rb_class_new_instance(9, argv, rb_cPrismWhileNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_X_STRING_NODE: { + pm_x_string_node_t *cast = (pm_x_string_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // opening_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source, freeze); + + // content_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = pm_location_new(parser, cast->content_loc.start, cast->content_loc.end, source, freeze); + + // closing_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = pm_location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source, freeze); + + // unescaped +#line 223 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = pm_string_new(&cast->unescaped, encoding); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismXStringNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } +#line 190 "prism/templates/ext/prism/api_node.c.erb" + case PM_YIELD_NODE: { + pm_yield_node_t *cast = (pm_yield_node_t *) node; + VALUE argv[8]; + + // source + argv[0] = source; + + // node_id + argv[1] = ULONG2NUM(node->node_id); + + // location + argv[2] = pm_location_new(parser, node->location.start, node->location.end, source, freeze); + + // flags + argv[3] = ULONG2NUM(node->flags); + + // keyword_loc +#line 240 "prism/templates/ext/prism/api_node.c.erb" + argv[4] = pm_location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source, freeze); + + // lparen_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[5] = cast->lparen_loc.start == NULL ? Qnil : pm_location_new(parser, cast->lparen_loc.start, cast->lparen_loc.end, source, freeze); + + // arguments +#line 213 "prism/templates/ext/prism/api_node.c.erb" + argv[6] = rb_ary_pop(value_stack); + + // rparen_loc +#line 243 "prism/templates/ext/prism/api_node.c.erb" + argv[7] = cast->rparen_loc.start == NULL ? Qnil : pm_location_new(parser, cast->rparen_loc.start, cast->rparen_loc.end, source, freeze); + + VALUE value = rb_class_new_instance(8, argv, rb_cPrismYieldNode); + if (freeze) rb_obj_freeze(value); + + rb_ary_push(value_stack, value); + break; + } + default: + rb_raise(rb_eRuntimeError, "unknown node type: %d", PM_NODE_TYPE(node)); + } + } + } + + return rb_ary_pop(value_stack); +} + +void +Init_prism_api_node(void) { + rb_cPrismAliasGlobalVariableNode = rb_define_class_under(rb_cPrism, "AliasGlobalVariableNode", rb_cPrismNode); + rb_cPrismAliasMethodNode = rb_define_class_under(rb_cPrism, "AliasMethodNode", rb_cPrismNode); + rb_cPrismAlternationPatternNode = rb_define_class_under(rb_cPrism, "AlternationPatternNode", rb_cPrismNode); + rb_cPrismAndNode = rb_define_class_under(rb_cPrism, "AndNode", rb_cPrismNode); + rb_cPrismArgumentsNode = rb_define_class_under(rb_cPrism, "ArgumentsNode", rb_cPrismNode); + rb_cPrismArrayNode = rb_define_class_under(rb_cPrism, "ArrayNode", rb_cPrismNode); + rb_cPrismArrayPatternNode = rb_define_class_under(rb_cPrism, "ArrayPatternNode", rb_cPrismNode); + rb_cPrismAssocNode = rb_define_class_under(rb_cPrism, "AssocNode", rb_cPrismNode); + rb_cPrismAssocSplatNode = rb_define_class_under(rb_cPrism, "AssocSplatNode", rb_cPrismNode); + rb_cPrismBackReferenceReadNode = rb_define_class_under(rb_cPrism, "BackReferenceReadNode", rb_cPrismNode); + rb_cPrismBeginNode = rb_define_class_under(rb_cPrism, "BeginNode", rb_cPrismNode); + rb_cPrismBlockArgumentNode = rb_define_class_under(rb_cPrism, "BlockArgumentNode", rb_cPrismNode); + rb_cPrismBlockLocalVariableNode = rb_define_class_under(rb_cPrism, "BlockLocalVariableNode", rb_cPrismNode); + rb_cPrismBlockNode = rb_define_class_under(rb_cPrism, "BlockNode", rb_cPrismNode); + rb_cPrismBlockParameterNode = rb_define_class_under(rb_cPrism, "BlockParameterNode", rb_cPrismNode); + rb_cPrismBlockParametersNode = rb_define_class_under(rb_cPrism, "BlockParametersNode", rb_cPrismNode); + rb_cPrismBreakNode = rb_define_class_under(rb_cPrism, "BreakNode", rb_cPrismNode); + rb_cPrismCallAndWriteNode = rb_define_class_under(rb_cPrism, "CallAndWriteNode", rb_cPrismNode); + rb_cPrismCallNode = rb_define_class_under(rb_cPrism, "CallNode", rb_cPrismNode); + rb_cPrismCallOperatorWriteNode = rb_define_class_under(rb_cPrism, "CallOperatorWriteNode", rb_cPrismNode); + rb_cPrismCallOrWriteNode = rb_define_class_under(rb_cPrism, "CallOrWriteNode", rb_cPrismNode); + rb_cPrismCallTargetNode = rb_define_class_under(rb_cPrism, "CallTargetNode", rb_cPrismNode); + rb_cPrismCapturePatternNode = rb_define_class_under(rb_cPrism, "CapturePatternNode", rb_cPrismNode); + rb_cPrismCaseMatchNode = rb_define_class_under(rb_cPrism, "CaseMatchNode", rb_cPrismNode); + rb_cPrismCaseNode = rb_define_class_under(rb_cPrism, "CaseNode", rb_cPrismNode); + rb_cPrismClassNode = rb_define_class_under(rb_cPrism, "ClassNode", rb_cPrismNode); + rb_cPrismClassVariableAndWriteNode = rb_define_class_under(rb_cPrism, "ClassVariableAndWriteNode", rb_cPrismNode); + rb_cPrismClassVariableOperatorWriteNode = rb_define_class_under(rb_cPrism, "ClassVariableOperatorWriteNode", rb_cPrismNode); + rb_cPrismClassVariableOrWriteNode = rb_define_class_under(rb_cPrism, "ClassVariableOrWriteNode", rb_cPrismNode); + rb_cPrismClassVariableReadNode = rb_define_class_under(rb_cPrism, "ClassVariableReadNode", rb_cPrismNode); + rb_cPrismClassVariableTargetNode = rb_define_class_under(rb_cPrism, "ClassVariableTargetNode", rb_cPrismNode); + rb_cPrismClassVariableWriteNode = rb_define_class_under(rb_cPrism, "ClassVariableWriteNode", rb_cPrismNode); + rb_cPrismConstantAndWriteNode = rb_define_class_under(rb_cPrism, "ConstantAndWriteNode", rb_cPrismNode); + rb_cPrismConstantOperatorWriteNode = rb_define_class_under(rb_cPrism, "ConstantOperatorWriteNode", rb_cPrismNode); + rb_cPrismConstantOrWriteNode = rb_define_class_under(rb_cPrism, "ConstantOrWriteNode", rb_cPrismNode); + rb_cPrismConstantPathAndWriteNode = rb_define_class_under(rb_cPrism, "ConstantPathAndWriteNode", rb_cPrismNode); + rb_cPrismConstantPathNode = rb_define_class_under(rb_cPrism, "ConstantPathNode", rb_cPrismNode); + rb_cPrismConstantPathOperatorWriteNode = rb_define_class_under(rb_cPrism, "ConstantPathOperatorWriteNode", rb_cPrismNode); + rb_cPrismConstantPathOrWriteNode = rb_define_class_under(rb_cPrism, "ConstantPathOrWriteNode", rb_cPrismNode); + rb_cPrismConstantPathTargetNode = rb_define_class_under(rb_cPrism, "ConstantPathTargetNode", rb_cPrismNode); + rb_cPrismConstantPathWriteNode = rb_define_class_under(rb_cPrism, "ConstantPathWriteNode", rb_cPrismNode); + rb_cPrismConstantReadNode = rb_define_class_under(rb_cPrism, "ConstantReadNode", rb_cPrismNode); + rb_cPrismConstantTargetNode = rb_define_class_under(rb_cPrism, "ConstantTargetNode", rb_cPrismNode); + rb_cPrismConstantWriteNode = rb_define_class_under(rb_cPrism, "ConstantWriteNode", rb_cPrismNode); + rb_cPrismDefNode = rb_define_class_under(rb_cPrism, "DefNode", rb_cPrismNode); + rb_cPrismDefinedNode = rb_define_class_under(rb_cPrism, "DefinedNode", rb_cPrismNode); + rb_cPrismElseNode = rb_define_class_under(rb_cPrism, "ElseNode", rb_cPrismNode); + rb_cPrismEmbeddedStatementsNode = rb_define_class_under(rb_cPrism, "EmbeddedStatementsNode", rb_cPrismNode); + rb_cPrismEmbeddedVariableNode = rb_define_class_under(rb_cPrism, "EmbeddedVariableNode", rb_cPrismNode); + rb_cPrismEnsureNode = rb_define_class_under(rb_cPrism, "EnsureNode", rb_cPrismNode); + rb_cPrismFalseNode = rb_define_class_under(rb_cPrism, "FalseNode", rb_cPrismNode); + rb_cPrismFindPatternNode = rb_define_class_under(rb_cPrism, "FindPatternNode", rb_cPrismNode); + rb_cPrismFlipFlopNode = rb_define_class_under(rb_cPrism, "FlipFlopNode", rb_cPrismNode); + rb_cPrismFloatNode = rb_define_class_under(rb_cPrism, "FloatNode", rb_cPrismNode); + rb_cPrismForNode = rb_define_class_under(rb_cPrism, "ForNode", rb_cPrismNode); + rb_cPrismForwardingArgumentsNode = rb_define_class_under(rb_cPrism, "ForwardingArgumentsNode", rb_cPrismNode); + rb_cPrismForwardingParameterNode = rb_define_class_under(rb_cPrism, "ForwardingParameterNode", rb_cPrismNode); + rb_cPrismForwardingSuperNode = rb_define_class_under(rb_cPrism, "ForwardingSuperNode", rb_cPrismNode); + rb_cPrismGlobalVariableAndWriteNode = rb_define_class_under(rb_cPrism, "GlobalVariableAndWriteNode", rb_cPrismNode); + rb_cPrismGlobalVariableOperatorWriteNode = rb_define_class_under(rb_cPrism, "GlobalVariableOperatorWriteNode", rb_cPrismNode); + rb_cPrismGlobalVariableOrWriteNode = rb_define_class_under(rb_cPrism, "GlobalVariableOrWriteNode", rb_cPrismNode); + rb_cPrismGlobalVariableReadNode = rb_define_class_under(rb_cPrism, "GlobalVariableReadNode", rb_cPrismNode); + rb_cPrismGlobalVariableTargetNode = rb_define_class_under(rb_cPrism, "GlobalVariableTargetNode", rb_cPrismNode); + rb_cPrismGlobalVariableWriteNode = rb_define_class_under(rb_cPrism, "GlobalVariableWriteNode", rb_cPrismNode); + rb_cPrismHashNode = rb_define_class_under(rb_cPrism, "HashNode", rb_cPrismNode); + rb_cPrismHashPatternNode = rb_define_class_under(rb_cPrism, "HashPatternNode", rb_cPrismNode); + rb_cPrismIfNode = rb_define_class_under(rb_cPrism, "IfNode", rb_cPrismNode); + rb_cPrismImaginaryNode = rb_define_class_under(rb_cPrism, "ImaginaryNode", rb_cPrismNode); + rb_cPrismImplicitNode = rb_define_class_under(rb_cPrism, "ImplicitNode", rb_cPrismNode); + rb_cPrismImplicitRestNode = rb_define_class_under(rb_cPrism, "ImplicitRestNode", rb_cPrismNode); + rb_cPrismInNode = rb_define_class_under(rb_cPrism, "InNode", rb_cPrismNode); + rb_cPrismIndexAndWriteNode = rb_define_class_under(rb_cPrism, "IndexAndWriteNode", rb_cPrismNode); + rb_cPrismIndexOperatorWriteNode = rb_define_class_under(rb_cPrism, "IndexOperatorWriteNode", rb_cPrismNode); + rb_cPrismIndexOrWriteNode = rb_define_class_under(rb_cPrism, "IndexOrWriteNode", rb_cPrismNode); + rb_cPrismIndexTargetNode = rb_define_class_under(rb_cPrism, "IndexTargetNode", rb_cPrismNode); + rb_cPrismInstanceVariableAndWriteNode = rb_define_class_under(rb_cPrism, "InstanceVariableAndWriteNode", rb_cPrismNode); + rb_cPrismInstanceVariableOperatorWriteNode = rb_define_class_under(rb_cPrism, "InstanceVariableOperatorWriteNode", rb_cPrismNode); + rb_cPrismInstanceVariableOrWriteNode = rb_define_class_under(rb_cPrism, "InstanceVariableOrWriteNode", rb_cPrismNode); + rb_cPrismInstanceVariableReadNode = rb_define_class_under(rb_cPrism, "InstanceVariableReadNode", rb_cPrismNode); + rb_cPrismInstanceVariableTargetNode = rb_define_class_under(rb_cPrism, "InstanceVariableTargetNode", rb_cPrismNode); + rb_cPrismInstanceVariableWriteNode = rb_define_class_under(rb_cPrism, "InstanceVariableWriteNode", rb_cPrismNode); + rb_cPrismIntegerNode = rb_define_class_under(rb_cPrism, "IntegerNode", rb_cPrismNode); + rb_cPrismInterpolatedMatchLastLineNode = rb_define_class_under(rb_cPrism, "InterpolatedMatchLastLineNode", rb_cPrismNode); + rb_cPrismInterpolatedRegularExpressionNode = rb_define_class_under(rb_cPrism, "InterpolatedRegularExpressionNode", rb_cPrismNode); + rb_cPrismInterpolatedStringNode = rb_define_class_under(rb_cPrism, "InterpolatedStringNode", rb_cPrismNode); + rb_cPrismInterpolatedSymbolNode = rb_define_class_under(rb_cPrism, "InterpolatedSymbolNode", rb_cPrismNode); + rb_cPrismInterpolatedXStringNode = rb_define_class_under(rb_cPrism, "InterpolatedXStringNode", rb_cPrismNode); + rb_cPrismItLocalVariableReadNode = rb_define_class_under(rb_cPrism, "ItLocalVariableReadNode", rb_cPrismNode); + rb_cPrismItParametersNode = rb_define_class_under(rb_cPrism, "ItParametersNode", rb_cPrismNode); + rb_cPrismKeywordHashNode = rb_define_class_under(rb_cPrism, "KeywordHashNode", rb_cPrismNode); + rb_cPrismKeywordRestParameterNode = rb_define_class_under(rb_cPrism, "KeywordRestParameterNode", rb_cPrismNode); + rb_cPrismLambdaNode = rb_define_class_under(rb_cPrism, "LambdaNode", rb_cPrismNode); + rb_cPrismLocalVariableAndWriteNode = rb_define_class_under(rb_cPrism, "LocalVariableAndWriteNode", rb_cPrismNode); + rb_cPrismLocalVariableOperatorWriteNode = rb_define_class_under(rb_cPrism, "LocalVariableOperatorWriteNode", rb_cPrismNode); + rb_cPrismLocalVariableOrWriteNode = rb_define_class_under(rb_cPrism, "LocalVariableOrWriteNode", rb_cPrismNode); + rb_cPrismLocalVariableReadNode = rb_define_class_under(rb_cPrism, "LocalVariableReadNode", rb_cPrismNode); + rb_cPrismLocalVariableTargetNode = rb_define_class_under(rb_cPrism, "LocalVariableTargetNode", rb_cPrismNode); + rb_cPrismLocalVariableWriteNode = rb_define_class_under(rb_cPrism, "LocalVariableWriteNode", rb_cPrismNode); + rb_cPrismMatchLastLineNode = rb_define_class_under(rb_cPrism, "MatchLastLineNode", rb_cPrismNode); + rb_cPrismMatchPredicateNode = rb_define_class_under(rb_cPrism, "MatchPredicateNode", rb_cPrismNode); + rb_cPrismMatchRequiredNode = rb_define_class_under(rb_cPrism, "MatchRequiredNode", rb_cPrismNode); + rb_cPrismMatchWriteNode = rb_define_class_under(rb_cPrism, "MatchWriteNode", rb_cPrismNode); + rb_cPrismMissingNode = rb_define_class_under(rb_cPrism, "MissingNode", rb_cPrismNode); + rb_cPrismModuleNode = rb_define_class_under(rb_cPrism, "ModuleNode", rb_cPrismNode); + rb_cPrismMultiTargetNode = rb_define_class_under(rb_cPrism, "MultiTargetNode", rb_cPrismNode); + rb_cPrismMultiWriteNode = rb_define_class_under(rb_cPrism, "MultiWriteNode", rb_cPrismNode); + rb_cPrismNextNode = rb_define_class_under(rb_cPrism, "NextNode", rb_cPrismNode); + rb_cPrismNilNode = rb_define_class_under(rb_cPrism, "NilNode", rb_cPrismNode); + rb_cPrismNoKeywordsParameterNode = rb_define_class_under(rb_cPrism, "NoKeywordsParameterNode", rb_cPrismNode); + rb_cPrismNumberedParametersNode = rb_define_class_under(rb_cPrism, "NumberedParametersNode", rb_cPrismNode); + rb_cPrismNumberedReferenceReadNode = rb_define_class_under(rb_cPrism, "NumberedReferenceReadNode", rb_cPrismNode); + rb_cPrismOptionalKeywordParameterNode = rb_define_class_under(rb_cPrism, "OptionalKeywordParameterNode", rb_cPrismNode); + rb_cPrismOptionalParameterNode = rb_define_class_under(rb_cPrism, "OptionalParameterNode", rb_cPrismNode); + rb_cPrismOrNode = rb_define_class_under(rb_cPrism, "OrNode", rb_cPrismNode); + rb_cPrismParametersNode = rb_define_class_under(rb_cPrism, "ParametersNode", rb_cPrismNode); + rb_cPrismParenthesesNode = rb_define_class_under(rb_cPrism, "ParenthesesNode", rb_cPrismNode); + rb_cPrismPinnedExpressionNode = rb_define_class_under(rb_cPrism, "PinnedExpressionNode", rb_cPrismNode); + rb_cPrismPinnedVariableNode = rb_define_class_under(rb_cPrism, "PinnedVariableNode", rb_cPrismNode); + rb_cPrismPostExecutionNode = rb_define_class_under(rb_cPrism, "PostExecutionNode", rb_cPrismNode); + rb_cPrismPreExecutionNode = rb_define_class_under(rb_cPrism, "PreExecutionNode", rb_cPrismNode); + rb_cPrismProgramNode = rb_define_class_under(rb_cPrism, "ProgramNode", rb_cPrismNode); + rb_cPrismRangeNode = rb_define_class_under(rb_cPrism, "RangeNode", rb_cPrismNode); + rb_cPrismRationalNode = rb_define_class_under(rb_cPrism, "RationalNode", rb_cPrismNode); + rb_cPrismRedoNode = rb_define_class_under(rb_cPrism, "RedoNode", rb_cPrismNode); + rb_cPrismRegularExpressionNode = rb_define_class_under(rb_cPrism, "RegularExpressionNode", rb_cPrismNode); + rb_cPrismRequiredKeywordParameterNode = rb_define_class_under(rb_cPrism, "RequiredKeywordParameterNode", rb_cPrismNode); + rb_cPrismRequiredParameterNode = rb_define_class_under(rb_cPrism, "RequiredParameterNode", rb_cPrismNode); + rb_cPrismRescueModifierNode = rb_define_class_under(rb_cPrism, "RescueModifierNode", rb_cPrismNode); + rb_cPrismRescueNode = rb_define_class_under(rb_cPrism, "RescueNode", rb_cPrismNode); + rb_cPrismRestParameterNode = rb_define_class_under(rb_cPrism, "RestParameterNode", rb_cPrismNode); + rb_cPrismRetryNode = rb_define_class_under(rb_cPrism, "RetryNode", rb_cPrismNode); + rb_cPrismReturnNode = rb_define_class_under(rb_cPrism, "ReturnNode", rb_cPrismNode); + rb_cPrismSelfNode = rb_define_class_under(rb_cPrism, "SelfNode", rb_cPrismNode); + rb_cPrismShareableConstantNode = rb_define_class_under(rb_cPrism, "ShareableConstantNode", rb_cPrismNode); + rb_cPrismSingletonClassNode = rb_define_class_under(rb_cPrism, "SingletonClassNode", rb_cPrismNode); + rb_cPrismSourceEncodingNode = rb_define_class_under(rb_cPrism, "SourceEncodingNode", rb_cPrismNode); + rb_cPrismSourceFileNode = rb_define_class_under(rb_cPrism, "SourceFileNode", rb_cPrismNode); + rb_cPrismSourceLineNode = rb_define_class_under(rb_cPrism, "SourceLineNode", rb_cPrismNode); + rb_cPrismSplatNode = rb_define_class_under(rb_cPrism, "SplatNode", rb_cPrismNode); + rb_cPrismStatementsNode = rb_define_class_under(rb_cPrism, "StatementsNode", rb_cPrismNode); + rb_cPrismStringNode = rb_define_class_under(rb_cPrism, "StringNode", rb_cPrismNode); + rb_cPrismSuperNode = rb_define_class_under(rb_cPrism, "SuperNode", rb_cPrismNode); + rb_cPrismSymbolNode = rb_define_class_under(rb_cPrism, "SymbolNode", rb_cPrismNode); + rb_cPrismTrueNode = rb_define_class_under(rb_cPrism, "TrueNode", rb_cPrismNode); + rb_cPrismUndefNode = rb_define_class_under(rb_cPrism, "UndefNode", rb_cPrismNode); + rb_cPrismUnlessNode = rb_define_class_under(rb_cPrism, "UnlessNode", rb_cPrismNode); + rb_cPrismUntilNode = rb_define_class_under(rb_cPrism, "UntilNode", rb_cPrismNode); + rb_cPrismWhenNode = rb_define_class_under(rb_cPrism, "WhenNode", rb_cPrismNode); + rb_cPrismWhileNode = rb_define_class_under(rb_cPrism, "WhileNode", rb_cPrismNode); + rb_cPrismXStringNode = rb_define_class_under(rb_cPrism, "XStringNode", rb_cPrismNode); + rb_cPrismYieldNode = rb_define_class_under(rb_cPrism, "YieldNode", rb_cPrismNode); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext/prism/api_pack.c b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext/prism/api_pack.c new file mode 100644 index 00000000..98509ae6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext/prism/api_pack.c @@ -0,0 +1,276 @@ +#include "prism/extension.h" + +#ifdef PRISM_EXCLUDE_PACK + +void +Init_prism_pack(void) {} + +#else + +static VALUE rb_cPrism; +static VALUE rb_cPrismPack; +static VALUE rb_cPrismPackDirective; +static VALUE rb_cPrismPackFormat; + +static VALUE v3_2_0_symbol; +static VALUE pack_symbol; +static VALUE unpack_symbol; + +#if SIZEOF_UINT64_T == SIZEOF_LONG_LONG +# define UINT64T2NUM(x) ULL2NUM(x) +# define NUM2UINT64T(x) (uint64_t)NUM2ULL(x) +#elif SIZEOF_UINT64_T == SIZEOF_LONG +# define UINT64T2NUM(x) ULONG2NUM(x) +# define NUM2UINT64T(x) (uint64_t)NUM2ULONG(x) +#else +// error No uint64_t conversion +#endif + +static VALUE +pack_type_to_symbol(pm_pack_type type) { + switch (type) { + case PM_PACK_SPACE: + return ID2SYM(rb_intern("SPACE")); + case PM_PACK_COMMENT: + return ID2SYM(rb_intern("COMMENT")); + case PM_PACK_INTEGER: + return ID2SYM(rb_intern("INTEGER")); + case PM_PACK_UTF8: + return ID2SYM(rb_intern("UTF8")); + case PM_PACK_BER: + return ID2SYM(rb_intern("BER")); + case PM_PACK_FLOAT: + return ID2SYM(rb_intern("FLOAT")); + case PM_PACK_STRING_SPACE_PADDED: + return ID2SYM(rb_intern("STRING_SPACE_PADDED")); + case PM_PACK_STRING_NULL_PADDED: + return ID2SYM(rb_intern("STRING_NULL_PADDED")); + case PM_PACK_STRING_NULL_TERMINATED: + return ID2SYM(rb_intern("STRING_NULL_TERMINATED")); + case PM_PACK_STRING_MSB: + return ID2SYM(rb_intern("STRING_MSB")); + case PM_PACK_STRING_LSB: + return ID2SYM(rb_intern("STRING_LSB")); + case PM_PACK_STRING_HEX_HIGH: + return ID2SYM(rb_intern("STRING_HEX_HIGH")); + case PM_PACK_STRING_HEX_LOW: + return ID2SYM(rb_intern("STRING_HEX_LOW")); + case PM_PACK_STRING_UU: + return ID2SYM(rb_intern("STRING_UU")); + case PM_PACK_STRING_MIME: + return ID2SYM(rb_intern("STRING_MIME")); + case PM_PACK_STRING_BASE64: + return ID2SYM(rb_intern("STRING_BASE64")); + case PM_PACK_STRING_FIXED: + return ID2SYM(rb_intern("STRING_FIXED")); + case PM_PACK_STRING_POINTER: + return ID2SYM(rb_intern("STRING_POINTER")); + case PM_PACK_MOVE: + return ID2SYM(rb_intern("MOVE")); + case PM_PACK_BACK: + return ID2SYM(rb_intern("BACK")); + case PM_PACK_NULL: + return ID2SYM(rb_intern("NULL")); + default: + return Qnil; + } +} + +static VALUE +pack_signed_to_symbol(pm_pack_signed signed_type) { + switch (signed_type) { + case PM_PACK_UNSIGNED: + return ID2SYM(rb_intern("UNSIGNED")); + case PM_PACK_SIGNED: + return ID2SYM(rb_intern("SIGNED")); + case PM_PACK_SIGNED_NA: + return ID2SYM(rb_intern("SIGNED_NA")); + default: + return Qnil; + } +} + +static VALUE +pack_endian_to_symbol(pm_pack_endian endian) { + switch (endian) { + case PM_PACK_AGNOSTIC_ENDIAN: + return ID2SYM(rb_intern("AGNOSTIC_ENDIAN")); + case PM_PACK_LITTLE_ENDIAN: + return ID2SYM(rb_intern("LITTLE_ENDIAN")); + case PM_PACK_BIG_ENDIAN: + return ID2SYM(rb_intern("BIG_ENDIAN")); + case PM_PACK_NATIVE_ENDIAN: + return ID2SYM(rb_intern("NATIVE_ENDIAN")); + case PM_PACK_ENDIAN_NA: + return ID2SYM(rb_intern("ENDIAN_NA")); + default: + return Qnil; + } +} + +static VALUE +pack_size_to_symbol(pm_pack_size size) { + switch (size) { + case PM_PACK_SIZE_SHORT: + return ID2SYM(rb_intern("SIZE_SHORT")); + case PM_PACK_SIZE_INT: + return ID2SYM(rb_intern("SIZE_INT")); + case PM_PACK_SIZE_LONG: + return ID2SYM(rb_intern("SIZE_LONG")); + case PM_PACK_SIZE_LONG_LONG: + return ID2SYM(rb_intern("SIZE_LONG_LONG")); + case PM_PACK_SIZE_8: + return ID2SYM(rb_intern("SIZE_8")); + case PM_PACK_SIZE_16: + return ID2SYM(rb_intern("SIZE_16")); + case PM_PACK_SIZE_32: + return ID2SYM(rb_intern("SIZE_32")); + case PM_PACK_SIZE_64: + return ID2SYM(rb_intern("SIZE_64")); + case PM_PACK_SIZE_P: + return ID2SYM(rb_intern("SIZE_P")); + case PM_PACK_SIZE_NA: + return ID2SYM(rb_intern("SIZE_NA")); + default: + return Qnil; + } +} + +static VALUE +pack_length_type_to_symbol(pm_pack_length_type length_type) { + switch (length_type) { + case PM_PACK_LENGTH_FIXED: + return ID2SYM(rb_intern("LENGTH_FIXED")); + case PM_PACK_LENGTH_MAX: + return ID2SYM(rb_intern("LENGTH_MAX")); + case PM_PACK_LENGTH_RELATIVE: + return ID2SYM(rb_intern("LENGTH_RELATIVE")); + case PM_PACK_LENGTH_NA: + return ID2SYM(rb_intern("LENGTH_NA")); + default: + return Qnil; + } +} + +static VALUE +pack_encoding_to_ruby(pm_pack_encoding encoding) { + int index; + switch (encoding) { + case PM_PACK_ENCODING_ASCII_8BIT: + index = rb_ascii8bit_encindex(); + break; + case PM_PACK_ENCODING_US_ASCII: + index = rb_usascii_encindex(); + break; + case PM_PACK_ENCODING_UTF_8: + index = rb_utf8_encindex(); + break; + default: + return Qnil; + } + return rb_enc_from_encoding(rb_enc_from_index(index)); +} + +/** + * call-seq: + * Pack::parse(version, variant, source) -> Format + * + * Parse the given source and return a format object. + */ +static VALUE +pack_parse(VALUE self, VALUE version_symbol, VALUE variant_symbol, VALUE format_string) { + if (version_symbol != v3_2_0_symbol) { + rb_raise(rb_eArgError, "invalid version"); + } + + pm_pack_variant variant; + if (variant_symbol == pack_symbol) { + variant = PM_PACK_VARIANT_PACK; + } else if (variant_symbol == unpack_symbol) { + variant = PM_PACK_VARIANT_UNPACK; + } else { + rb_raise(rb_eArgError, "invalid variant"); + } + + StringValue(format_string); + + const char *format = RSTRING_PTR(format_string); + const char *format_end = format + RSTRING_LEN(format_string); + pm_pack_encoding encoding = PM_PACK_ENCODING_START; + + VALUE directives_array = rb_ary_new(); + + while (format < format_end) { + pm_pack_type type; + pm_pack_signed signed_type; + pm_pack_endian endian; + pm_pack_size size; + pm_pack_length_type length_type; + uint64_t length; + + const char *directive_start = format; + + pm_pack_result parse_result = pm_pack_parse(variant, &format, format_end, &type, &signed_type, &endian, + &size, &length_type, &length, &encoding); + + const char *directive_end = format; + + switch (parse_result) { + case PM_PACK_OK: + break; + case PM_PACK_ERROR_UNSUPPORTED_DIRECTIVE: + rb_raise(rb_eArgError, "unsupported directive"); + case PM_PACK_ERROR_UNKNOWN_DIRECTIVE: + rb_raise(rb_eArgError, "unsupported directive"); + case PM_PACK_ERROR_LENGTH_TOO_BIG: + rb_raise(rb_eRangeError, "pack length too big"); + case PM_PACK_ERROR_BANG_NOT_ALLOWED: + rb_raise(rb_eRangeError, "bang not allowed"); + case PM_PACK_ERROR_DOUBLE_ENDIAN: + rb_raise(rb_eRangeError, "double endian"); + default: + rb_bug("parse result"); + } + + if (type == PM_PACK_END) { + break; + } + + VALUE directive_args[9] = { + version_symbol, + variant_symbol, + rb_usascii_str_new(directive_start, directive_end - directive_start), + pack_type_to_symbol(type), + pack_signed_to_symbol(signed_type), + pack_endian_to_symbol(endian), + pack_size_to_symbol(size), + pack_length_type_to_symbol(length_type), + UINT64T2NUM(length) + }; + + rb_ary_push(directives_array, rb_class_new_instance(9, directive_args, rb_cPrismPackDirective)); + } + + VALUE format_args[2]; + format_args[0] = directives_array; + format_args[1] = pack_encoding_to_ruby(encoding); + return rb_class_new_instance(2, format_args, rb_cPrismPackFormat); +} + +/** + * The function that gets called when Ruby initializes the prism extension. + */ +void +Init_prism_pack(void) { + rb_cPrism = rb_define_module("Prism"); + rb_cPrismPack = rb_define_module_under(rb_cPrism, "Pack"); + rb_cPrismPackDirective = rb_define_class_under(rb_cPrismPack, "Directive", rb_cObject); + rb_cPrismPackFormat = rb_define_class_under(rb_cPrismPack, "Format", rb_cObject); + rb_define_singleton_method(rb_cPrismPack, "parse", pack_parse, 3); + + v3_2_0_symbol = ID2SYM(rb_intern("v3_2_0")); + pack_symbol = ID2SYM(rb_intern("pack")); + unpack_symbol = ID2SYM(rb_intern("unpack")); +} + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext/prism/extconf.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext/prism/extconf.rb new file mode 100644 index 00000000..20ba28fe --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext/prism/extconf.rb @@ -0,0 +1,127 @@ +# frozen_string_literal: true + +require "rbconfig" + +if ARGV.delete("--help") + print(<<~TEXT) + USAGE: ruby #{$PROGRAM_NAME} [options] + + Flags that are always valid: + + --enable-build-debug + Enable debug build. + You may also set the PRISM_BUILD_DEBUG environment variable. + + --enable-build-minimal + Enable minimal build. + You may also set the PRISM_BUILD_MINIMAL environment variable. + + --help + Display this message. + + Environment variables used: + + PRISM_BUILD_DEBUG + Equivalent to `--enable-build-debug` when set, even if nil or blank. + + PRISM_BUILD_MINIMAL + Equivalent to `--enable-build-minimal` when set, even if nil or blank. + + TEXT + exit!(0) +end + +# If this gem is being build from a git source, then we need to run +# templating if it hasn't been run yet. In normal packaging, we would have +# shipped the templated files with the gem, so this wouldn't be necessary. +def generate_templates + Dir.chdir(File.expand_path("../..", __dir__)) do + if !File.exist?("include/prism/ast.h") && Dir.exist?(".git") + system("templates/template.rb", exception: true) + end + end +end + +# Runs `make` in the root directory of the project. Note that this is the +# `Makefile` for the overall project, not the `Makefile` that is being generated +# by this script.` +def make(env, target) + puts "Running make #{target} with #{env.inspect}" + Dir.chdir(File.expand_path("../..", __dir__)) do + system( + env, + RUBY_PLATFORM.match?(/openbsd|freebsd/) ? "gmake" : "make", + target, + exception: true + ) + end +end + +# On non-CRuby we only need the shared library since we'll interface with it +# through FFI, so we'll build only that and not the C extension. We also avoid +# `require "mkmf"` as that prepends the GraalVM LLVM toolchain to PATH on TruffleRuby < 24.0, +# but we want to use the system toolchain here since libprism is run natively. +if RUBY_ENGINE != "ruby" + generate_templates + soext = RbConfig::CONFIG["SOEXT"] + # Pass SOEXT to avoid an extra subprocess just to query that + make({ "SOEXT" => soext }, "build/libprism.#{soext}") + File.write("Makefile", "all install clean:\n\t@#{RbConfig::CONFIG["NULLCMD"]}\n") + return +end + +require "mkmf" + +# First, ensure that we can find the header for the prism library. +generate_templates # Templates should be generated before find_header. +unless find_header("prism.h", File.expand_path("../../include", __dir__)) + raise "prism.h is required" +end + +# Next, ensure we can find the header for the C extension. Explicitly look for +# the extension header in the parent directory because we want to consistently +# look for `prism/extension.h` in our source files to line up with our mirroring +# in CRuby. +unless find_header("prism/extension.h", File.expand_path("..", __dir__)) + raise "prism/extension.h is required" +end + +# If `--enable-build-debug` is passed to this script or the +# `PRISM_BUILD_DEBUG` environment variable is defined, we'll build with the +# `PRISM_BUILD_DEBUG` macro defined. This causes parse functions to +# duplicate their input so that they have clearly set bounds, which is useful +# for finding bugs that cause the parser to read off the end of the input. +if enable_config("build-debug", ENV["PRISM_BUILD_DEBUG"] || false) + append_cflags("-DPRISM_BUILD_DEBUG") +end + +# If `--enable-build-minimal` is passed to this script or the +# `PRISM_BUILD_MINIMAL` environment variable is defined, we'll build with the +# set of defines that comprise the minimal set. This causes the parser to be +# built with minimal features, necessary for stripping out functionality when +# the size of the final built artifact is a concern. +if enable_config("build-minimal", ENV["PRISM_BUILD_MINIMAL"] || false) + append_cflags("-DPRISM_BUILD_MINIMAL") +end + +# By default, all symbols are hidden in the shared library. +append_cflags("-fvisibility=hidden") + +def src_list(path) + srcdir = path.dup + RbConfig.expand(srcdir) # mutates srcdir :-/ + Dir[File.join(srcdir, "*.{#{SRC_EXT.join(%q{,})}}")] +end + +def add_libprism_source(path) + $VPATH << path + src_list path +end + +$srcs = src_list("$(srcdir)") + + add_libprism_source("$(srcdir)/../../src") + + add_libprism_source("$(srcdir)/../../src/util") + +# Finally, we'll create the `Makefile` that is going to be used to configure and +# build the C extension. +create_makefile("prism/prism") diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext/prism/extension.c b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext/prism/extension.c new file mode 100644 index 00000000..dca2ee67 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext/prism/extension.c @@ -0,0 +1,1406 @@ +#include "prism/extension.h" + +#ifdef _WIN32 +#include +#endif + +// NOTE: this file should contain only bindings. All non-trivial logic should be +// in libprism so it can be shared its the various callers. + +VALUE rb_cPrism; +VALUE rb_cPrismNode; +VALUE rb_cPrismSource; +VALUE rb_cPrismToken; +VALUE rb_cPrismLocation; + +VALUE rb_cPrismComment; +VALUE rb_cPrismInlineComment; +VALUE rb_cPrismEmbDocComment; +VALUE rb_cPrismMagicComment; +VALUE rb_cPrismParseError; +VALUE rb_cPrismParseWarning; +VALUE rb_cPrismResult; +VALUE rb_cPrismParseResult; +VALUE rb_cPrismLexResult; +VALUE rb_cPrismParseLexResult; +VALUE rb_cPrismStringQuery; +VALUE rb_cPrismScope; + +VALUE rb_cPrismDebugEncoding; + +ID rb_id_option_command_line; +ID rb_id_option_encoding; +ID rb_id_option_filepath; +ID rb_id_option_freeze; +ID rb_id_option_frozen_string_literal; +ID rb_id_option_line; +ID rb_id_option_main_script; +ID rb_id_option_partial_script; +ID rb_id_option_scopes; +ID rb_id_option_version; +ID rb_id_source_for; +ID rb_id_forwarding_positionals; +ID rb_id_forwarding_keywords; +ID rb_id_forwarding_block; +ID rb_id_forwarding_all; + +/******************************************************************************/ +/* IO of Ruby code */ +/******************************************************************************/ + +/** + * Check if the given VALUE is a string. If it's not a string, then raise a + * TypeError. Otherwise return the VALUE as a C string. + */ +static const char * +check_string(VALUE value) { + // Check if the value is a string. If it's not, then raise a type error. + if (!RB_TYPE_P(value, T_STRING)) { + rb_raise(rb_eTypeError, "wrong argument type %" PRIsVALUE " (expected String)", rb_obj_class(value)); + } + + // Otherwise, return the value as a C string. + return RSTRING_PTR(value); +} + +/** + * Load the contents and size of the given string into the given pm_string_t. + */ +static void +input_load_string(pm_string_t *input, VALUE string) { + // Check if the string is a string. If it's not, then raise a type error. + if (!RB_TYPE_P(string, T_STRING)) { + rb_raise(rb_eTypeError, "wrong argument type %" PRIsVALUE " (expected String)", rb_obj_class(string)); + } + + pm_string_constant_init(input, RSTRING_PTR(string), RSTRING_LEN(string)); +} + +/******************************************************************************/ +/* Building C options from Ruby options */ +/******************************************************************************/ + +/** + * Build the scopes associated with the provided Ruby keyword value. + */ +static void +build_options_scopes(pm_options_t *options, VALUE scopes) { + // Check if the value is an array. If it's not, then raise a type error. + if (!RB_TYPE_P(scopes, T_ARRAY)) { + rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected Array)", rb_obj_class(scopes)); + } + + // Initialize the scopes array. + size_t scopes_count = RARRAY_LEN(scopes); + if (!pm_options_scopes_init(options, scopes_count)) { + rb_raise(rb_eNoMemError, "failed to allocate memory"); + } + + // Iterate over the scopes and add them to the options. + for (size_t scope_index = 0; scope_index < scopes_count; scope_index++) { + VALUE scope = rb_ary_entry(scopes, scope_index); + + // The scope can be either an array or it can be a Prism::Scope object. + // Parse out the correct values here from either. + VALUE locals; + uint8_t forwarding = PM_OPTIONS_SCOPE_FORWARDING_NONE; + + if (RB_TYPE_P(scope, T_ARRAY)) { + locals = scope; + } else if (rb_obj_is_kind_of(scope, rb_cPrismScope)) { + locals = rb_ivar_get(scope, rb_intern("@locals")); + if (!RB_TYPE_P(locals, T_ARRAY)) { + rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected Array)", rb_obj_class(locals)); + } + + VALUE names = rb_ivar_get(scope, rb_intern("@forwarding")); + if (!RB_TYPE_P(names, T_ARRAY)) { + rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected Array)", rb_obj_class(names)); + } + + size_t names_count = RARRAY_LEN(names); + for (size_t name_index = 0; name_index < names_count; name_index++) { + VALUE name = rb_ary_entry(names, name_index); + + // Check that the name is a symbol. If it's not, then raise + // a type error. + if (!RB_TYPE_P(name, T_SYMBOL)) { + rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected Symbol)", rb_obj_class(name)); + } + + ID id = SYM2ID(name); + if (id == rb_id_forwarding_positionals) { + forwarding |= PM_OPTIONS_SCOPE_FORWARDING_POSITIONALS; + } else if (id == rb_id_forwarding_keywords) { + forwarding |= PM_OPTIONS_SCOPE_FORWARDING_KEYWORDS; + } else if (id == rb_id_forwarding_block) { + forwarding |= PM_OPTIONS_SCOPE_FORWARDING_BLOCK; + } else if (id == rb_id_forwarding_all) { + forwarding |= PM_OPTIONS_SCOPE_FORWARDING_ALL; + } else { + rb_raise(rb_eArgError, "invalid forwarding value: %" PRIsVALUE, name); + } + } + } else { + rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected Array or Prism::Scope)", rb_obj_class(scope)); + } + + // Initialize the scope array. + size_t locals_count = RARRAY_LEN(locals); + pm_options_scope_t *options_scope = &options->scopes[scope_index]; + if (!pm_options_scope_init(options_scope, locals_count)) { + rb_raise(rb_eNoMemError, "failed to allocate memory"); + } + + // Iterate over the locals and add them to the scope. + for (size_t local_index = 0; local_index < locals_count; local_index++) { + VALUE local = rb_ary_entry(locals, local_index); + + // Check that the local is a symbol. If it's not, then raise a + // type error. + if (!RB_TYPE_P(local, T_SYMBOL)) { + rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected Symbol)", rb_obj_class(local)); + } + + // Add the local to the scope. + pm_string_t *scope_local = &options_scope->locals[local_index]; + const char *name = rb_id2name(SYM2ID(local)); + pm_string_constant_init(scope_local, name, strlen(name)); + } + + // Now set the forwarding options. + pm_options_scope_forwarding_set(options_scope, forwarding); + } +} + +/** + * An iterator function that is called for each key-value in the keywords hash. + */ +static int +build_options_i(VALUE key, VALUE value, VALUE argument) { + pm_options_t *options = (pm_options_t *) argument; + ID key_id = SYM2ID(key); + + if (key_id == rb_id_option_filepath) { + if (!NIL_P(value)) pm_options_filepath_set(options, check_string(value)); + } else if (key_id == rb_id_option_encoding) { + if (!NIL_P(value)) { + if (value == Qfalse) { + pm_options_encoding_locked_set(options, true); + } else { + pm_options_encoding_set(options, rb_enc_name(rb_to_encoding(value))); + } + } + } else if (key_id == rb_id_option_line) { + if (!NIL_P(value)) pm_options_line_set(options, NUM2INT(value)); + } else if (key_id == rb_id_option_frozen_string_literal) { + if (!NIL_P(value)) pm_options_frozen_string_literal_set(options, RTEST(value)); + } else if (key_id == rb_id_option_version) { + if (!NIL_P(value)) { + const char *version = check_string(value); + + if (!pm_options_version_set(options, version, RSTRING_LEN(value))) { + rb_raise(rb_eArgError, "invalid version: %" PRIsVALUE, value); + } + } + } else if (key_id == rb_id_option_scopes) { + if (!NIL_P(value)) build_options_scopes(options, value); + } else if (key_id == rb_id_option_command_line) { + if (!NIL_P(value)) { + const char *string = check_string(value); + uint8_t command_line = 0; + + for (size_t index = 0; index < strlen(string); index++) { + switch (string[index]) { + case 'a': command_line |= PM_OPTIONS_COMMAND_LINE_A; break; + case 'e': command_line |= PM_OPTIONS_COMMAND_LINE_E; break; + case 'l': command_line |= PM_OPTIONS_COMMAND_LINE_L; break; + case 'n': command_line |= PM_OPTIONS_COMMAND_LINE_N; break; + case 'p': command_line |= PM_OPTIONS_COMMAND_LINE_P; break; + case 'x': command_line |= PM_OPTIONS_COMMAND_LINE_X; break; + default: rb_raise(rb_eArgError, "invalid command line flag: '%c'", string[index]); break; + } + } + + pm_options_command_line_set(options, command_line); + } + } else if (key_id == rb_id_option_main_script) { + if (!NIL_P(value)) pm_options_main_script_set(options, RTEST(value)); + } else if (key_id == rb_id_option_partial_script) { + if (!NIL_P(value)) pm_options_partial_script_set(options, RTEST(value)); + } else if (key_id == rb_id_option_freeze) { + if (!NIL_P(value)) pm_options_freeze_set(options, RTEST(value)); + } else { + rb_raise(rb_eArgError, "unknown keyword: %" PRIsVALUE, key); + } + + return ST_CONTINUE; +} + +/** + * We need a struct here to pass through rb_protect and it has to be a single + * value. Because the sizeof(VALUE) == sizeof(void *), we're going to pass this + * through as an opaque pointer and cast it on both sides. + */ +struct build_options_data { + pm_options_t *options; + VALUE keywords; +}; + +/** + * Build the set of options from the given keywords. Note that this can raise a + * Ruby error if the options are not valid. + */ +static VALUE +build_options(VALUE argument) { + struct build_options_data *data = (struct build_options_data *) argument; + rb_hash_foreach(data->keywords, build_options_i, (VALUE) data->options); + return Qnil; +} + +/** + * Extract the options from the given keyword arguments. + */ +static void +extract_options(pm_options_t *options, VALUE filepath, VALUE keywords) { + options->line = 1; // default + + if (!NIL_P(keywords)) { + struct build_options_data data = { .options = options, .keywords = keywords }; + struct build_options_data *argument = &data; + + int state = 0; + rb_protect(build_options, (VALUE) argument, &state); + + if (state != 0) { + pm_options_free(options); + rb_jump_tag(state); + } + } + + if (!NIL_P(filepath)) { + if (!RB_TYPE_P(filepath, T_STRING)) { + pm_options_free(options); + rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected String)", rb_obj_class(filepath)); + } + + pm_options_filepath_set(options, RSTRING_PTR(filepath)); + } +} + +/** + * Read options for methods that look like (source, **options). + */ +static void +string_options(int argc, VALUE *argv, pm_string_t *input, pm_options_t *options) { + VALUE string; + VALUE keywords; + rb_scan_args(argc, argv, "1:", &string, &keywords); + + extract_options(options, Qnil, keywords); + input_load_string(input, string); +} + +/** + * Read options for methods that look like (filepath, **options). + */ +static void +file_options(int argc, VALUE *argv, pm_string_t *input, pm_options_t *options, VALUE *encoded_filepath) { + VALUE filepath; + VALUE keywords; + rb_scan_args(argc, argv, "1:", &filepath, &keywords); + + Check_Type(filepath, T_STRING); + *encoded_filepath = rb_str_encode_ospath(filepath); + extract_options(options, *encoded_filepath, keywords); + + const char *source = (const char *) pm_string_source(&options->filepath); + pm_string_init_result_t result; + + switch (result = pm_string_file_init(input, source)) { + case PM_STRING_INIT_SUCCESS: + break; + case PM_STRING_INIT_ERROR_GENERIC: { + pm_options_free(options); + +#ifdef _WIN32 + int e = rb_w32_map_errno(GetLastError()); +#else + int e = errno; +#endif + + rb_syserr_fail(e, source); + break; + } + case PM_STRING_INIT_ERROR_DIRECTORY: + pm_options_free(options); + rb_syserr_fail(EISDIR, source); + break; + default: + pm_options_free(options); + rb_raise(rb_eRuntimeError, "Unknown error (%d) initializing file: %s", result, source); + break; + } +} + +#ifndef PRISM_EXCLUDE_SERIALIZATION + +/******************************************************************************/ +/* Serializing the AST */ +/******************************************************************************/ + +/** + * Dump the AST corresponding to the given input to a string. + */ +static VALUE +dump_input(pm_string_t *input, const pm_options_t *options) { + pm_buffer_t buffer; + if (!pm_buffer_init(&buffer)) { + rb_raise(rb_eNoMemError, "failed to allocate memory"); + } + + pm_parser_t parser; + pm_parser_init(&parser, pm_string_source(input), pm_string_length(input), options); + + pm_node_t *node = pm_parse(&parser); + pm_serialize(&parser, node, &buffer); + + VALUE result = rb_str_new(pm_buffer_value(&buffer), pm_buffer_length(&buffer)); + pm_node_destroy(&parser, node); + pm_buffer_free(&buffer); + pm_parser_free(&parser); + + return result; +} + +/** + * call-seq: + * Prism::dump(source, **options) -> String + * + * Dump the AST corresponding to the given string to a string. For supported + * options, see Prism::parse. + */ +static VALUE +dump(int argc, VALUE *argv, VALUE self) { + pm_string_t input; + pm_options_t options = { 0 }; + string_options(argc, argv, &input, &options); + +#ifdef PRISM_BUILD_DEBUG + size_t length = pm_string_length(&input); + char* dup = xmalloc(length); + memcpy(dup, pm_string_source(&input), length); + pm_string_constant_init(&input, dup, length); +#endif + + VALUE value = dump_input(&input, &options); + if (options.freeze) rb_obj_freeze(value); + +#ifdef PRISM_BUILD_DEBUG + xfree(dup); +#endif + + pm_string_free(&input); + pm_options_free(&options); + + return value; +} + +/** + * call-seq: + * Prism::dump_file(filepath, **options) -> String + * + * Dump the AST corresponding to the given file to a string. For supported + * options, see Prism::parse. + */ +static VALUE +dump_file(int argc, VALUE *argv, VALUE self) { + pm_string_t input; + pm_options_t options = { 0 }; + + VALUE encoded_filepath; + file_options(argc, argv, &input, &options, &encoded_filepath); + + VALUE value = dump_input(&input, &options); + pm_string_free(&input); + pm_options_free(&options); + + return value; +} + +#endif + +/******************************************************************************/ +/* Extracting values for the parse result */ +/******************************************************************************/ + +/** + * The same as rb_class_new_instance, but accepts an additional boolean to + * indicate whether or not the resulting class instance should be frozen. + */ +static inline VALUE +rb_class_new_instance_freeze(int argc, const VALUE *argv, VALUE klass, bool freeze) { + VALUE value = rb_class_new_instance(argc, argv, klass); + if (freeze) rb_obj_freeze(value); + return value; +} + +/** + * Create a new Location instance from the given parser and bounds. + */ +static inline VALUE +parser_location(const pm_parser_t *parser, VALUE source, bool freeze, const uint8_t *start, size_t length) { + VALUE argv[] = { source, LONG2FIX(start - parser->start), LONG2FIX(length) }; + return rb_class_new_instance_freeze(3, argv, rb_cPrismLocation, freeze); +} + +/** + * Create a new Location instance from the given parser and location. + */ +#define PARSER_LOCATION_LOC(parser, source, freeze, loc) \ + parser_location(parser, source, freeze, loc.start, (size_t) (loc.end - loc.start)) + +/** + * Build a new Comment instance from the given parser and comment. + */ +static inline VALUE +parser_comment(const pm_parser_t *parser, VALUE source, bool freeze, const pm_comment_t *comment) { + VALUE argv[] = { PARSER_LOCATION_LOC(parser, source, freeze, comment->location) }; + VALUE type = (comment->type == PM_COMMENT_EMBDOC) ? rb_cPrismEmbDocComment : rb_cPrismInlineComment; + return rb_class_new_instance_freeze(1, argv, type, freeze); +} + +/** + * Extract the comments out of the parser into an array. + */ +static VALUE +parser_comments(const pm_parser_t *parser, VALUE source, bool freeze) { + VALUE comments = rb_ary_new_capa(parser->comment_list.size); + + for ( + const pm_comment_t *comment = (const pm_comment_t *) parser->comment_list.head; + comment != NULL; + comment = (const pm_comment_t *) comment->node.next + ) { + VALUE value = parser_comment(parser, source, freeze, comment); + rb_ary_push(comments, value); + } + + if (freeze) rb_obj_freeze(comments); + return comments; +} + +/** + * Build a new MagicComment instance from the given parser and magic comment. + */ +static inline VALUE +parser_magic_comment(const pm_parser_t *parser, VALUE source, bool freeze, const pm_magic_comment_t *magic_comment) { + VALUE key_loc = parser_location(parser, source, freeze, magic_comment->key_start, magic_comment->key_length); + VALUE value_loc = parser_location(parser, source, freeze, magic_comment->value_start, magic_comment->value_length); + VALUE argv[] = { key_loc, value_loc }; + return rb_class_new_instance_freeze(2, argv, rb_cPrismMagicComment, freeze); +} + +/** + * Extract the magic comments out of the parser into an array. + */ +static VALUE +parser_magic_comments(const pm_parser_t *parser, VALUE source, bool freeze) { + VALUE magic_comments = rb_ary_new_capa(parser->magic_comment_list.size); + + for ( + const pm_magic_comment_t *magic_comment = (const pm_magic_comment_t *) parser->magic_comment_list.head; + magic_comment != NULL; + magic_comment = (const pm_magic_comment_t *) magic_comment->node.next + ) { + VALUE value = parser_magic_comment(parser, source, freeze, magic_comment); + rb_ary_push(magic_comments, value); + } + + if (freeze) rb_obj_freeze(magic_comments); + return magic_comments; +} + +/** + * Extract out the data location from the parser into a Location instance if one + * exists. + */ +static VALUE +parser_data_loc(const pm_parser_t *parser, VALUE source, bool freeze) { + if (parser->data_loc.end == NULL) { + return Qnil; + } else { + return PARSER_LOCATION_LOC(parser, source, freeze, parser->data_loc); + } +} + +/** + * Extract the errors out of the parser into an array. + */ +static VALUE +parser_errors(const pm_parser_t *parser, rb_encoding *encoding, VALUE source, bool freeze) { + VALUE errors = rb_ary_new_capa(parser->error_list.size); + + for ( + const pm_diagnostic_t *error = (const pm_diagnostic_t *) parser->error_list.head; + error != NULL; + error = (const pm_diagnostic_t *) error->node.next + ) { + VALUE type = ID2SYM(rb_intern(pm_diagnostic_id_human(error->diag_id))); + VALUE message = rb_obj_freeze(rb_enc_str_new_cstr(error->message, encoding)); + VALUE location = PARSER_LOCATION_LOC(parser, source, freeze, error->location); + + VALUE level = Qnil; + switch (error->level) { + case PM_ERROR_LEVEL_SYNTAX: + level = ID2SYM(rb_intern("syntax")); + break; + case PM_ERROR_LEVEL_ARGUMENT: + level = ID2SYM(rb_intern("argument")); + break; + case PM_ERROR_LEVEL_LOAD: + level = ID2SYM(rb_intern("load")); + break; + default: + rb_raise(rb_eRuntimeError, "Unknown level: %" PRIu8, error->level); + } + + VALUE argv[] = { type, message, location, level }; + VALUE value = rb_class_new_instance_freeze(4, argv, rb_cPrismParseError, freeze); + rb_ary_push(errors, value); + } + + if (freeze) rb_obj_freeze(errors); + return errors; +} + +/** + * Extract the warnings out of the parser into an array. + */ +static VALUE +parser_warnings(const pm_parser_t *parser, rb_encoding *encoding, VALUE source, bool freeze) { + VALUE warnings = rb_ary_new_capa(parser->warning_list.size); + + for ( + const pm_diagnostic_t *warning = (const pm_diagnostic_t *) parser->warning_list.head; + warning != NULL; + warning = (const pm_diagnostic_t *) warning->node.next + ) { + VALUE type = ID2SYM(rb_intern(pm_diagnostic_id_human(warning->diag_id))); + VALUE message = rb_obj_freeze(rb_enc_str_new_cstr(warning->message, encoding)); + VALUE location = PARSER_LOCATION_LOC(parser, source, freeze, warning->location); + + VALUE level = Qnil; + switch (warning->level) { + case PM_WARNING_LEVEL_DEFAULT: + level = ID2SYM(rb_intern("default")); + break; + case PM_WARNING_LEVEL_VERBOSE: + level = ID2SYM(rb_intern("verbose")); + break; + default: + rb_raise(rb_eRuntimeError, "Unknown level: %" PRIu8, warning->level); + } + + VALUE argv[] = { type, message, location, level }; + VALUE value = rb_class_new_instance_freeze(4, argv, rb_cPrismParseWarning, freeze); + rb_ary_push(warnings, value); + } + + if (freeze) rb_obj_freeze(warnings); + return warnings; +} + +/** + * Create a new parse result from the given parser, value, encoding, and source. + */ +static VALUE +parse_result_create(VALUE class, const pm_parser_t *parser, VALUE value, rb_encoding *encoding, VALUE source, bool freeze) { + VALUE result_argv[] = { + value, + parser_comments(parser, source, freeze), + parser_magic_comments(parser, source, freeze), + parser_data_loc(parser, source, freeze), + parser_errors(parser, encoding, source, freeze), + parser_warnings(parser, encoding, source, freeze), + source + }; + + return rb_class_new_instance_freeze(7, result_argv, class, freeze); +} + +/******************************************************************************/ +/* Lexing Ruby code */ +/******************************************************************************/ + +/** + * This struct gets stored in the parser and passed in to the lex callback any + * time a new token is found. We use it to store the necessary information to + * initialize a Token instance. + */ +typedef struct { + VALUE source; + VALUE tokens; + rb_encoding *encoding; + bool freeze; +} parse_lex_data_t; + +/** + * This is passed as a callback to the parser. It gets called every time a new + * token is found. Once found, we initialize a new instance of Token and push it + * onto the tokens array. + */ +static void +parse_lex_token(void *data, pm_parser_t *parser, pm_token_t *token) { + parse_lex_data_t *parse_lex_data = (parse_lex_data_t *) parser->lex_callback->data; + + VALUE value = pm_token_new(parser, token, parse_lex_data->encoding, parse_lex_data->source, parse_lex_data->freeze); + VALUE yields = rb_assoc_new(value, INT2FIX(parser->lex_state)); + + if (parse_lex_data->freeze) { + rb_obj_freeze(value); + rb_obj_freeze(yields); + } + + rb_ary_push(parse_lex_data->tokens, yields); +} + +/** + * This is called whenever the encoding changes based on the magic comment at + * the top of the file. We use it to update the encoding that we are using to + * create tokens. + */ +static void +parse_lex_encoding_changed_callback(pm_parser_t *parser) { + parse_lex_data_t *parse_lex_data = (parse_lex_data_t *) parser->lex_callback->data; + parse_lex_data->encoding = rb_enc_find(parser->encoding->name); + + // Since the encoding changed, we need to go back and change the encoding of + // the tokens that were already lexed. This is only going to end up being + // one or two tokens, since the encoding can only change at the top of the + // file. + VALUE tokens = parse_lex_data->tokens; + VALUE next_tokens = rb_ary_new(); + + for (long index = 0; index < RARRAY_LEN(tokens); index++) { + VALUE yields = rb_ary_entry(tokens, index); + VALUE token = rb_ary_entry(yields, 0); + + VALUE value = rb_ivar_get(token, rb_intern("@value")); + VALUE next_value = rb_str_dup(value); + + rb_enc_associate(next_value, parse_lex_data->encoding); + if (parse_lex_data->freeze) rb_obj_freeze(next_value); + + VALUE next_token_argv[] = { + parse_lex_data->source, + rb_ivar_get(token, rb_intern("@type")), + next_value, + rb_ivar_get(token, rb_intern("@location")) + }; + + VALUE next_token = rb_class_new_instance(4, next_token_argv, rb_cPrismToken); + VALUE next_yields = rb_assoc_new(next_token, rb_ary_entry(yields, 1)); + + if (parse_lex_data->freeze) { + rb_obj_freeze(next_token); + rb_obj_freeze(next_yields); + } + + rb_ary_push(next_tokens, next_yields); + } + + rb_ary_replace(parse_lex_data->tokens, next_tokens); +} + +/** + * Parse the given input and return a ParseResult containing just the tokens or + * the nodes and tokens. + */ +static VALUE +parse_lex_input(pm_string_t *input, const pm_options_t *options, bool return_nodes) { + pm_parser_t parser; + pm_parser_init(&parser, pm_string_source(input), pm_string_length(input), options); + pm_parser_register_encoding_changed_callback(&parser, parse_lex_encoding_changed_callback); + + VALUE source_string = rb_str_new((const char *) pm_string_source(input), pm_string_length(input)); + VALUE offsets = rb_ary_new_capa(parser.newline_list.size); + VALUE source = rb_funcall(rb_cPrismSource, rb_id_source_for, 3, source_string, LONG2NUM(parser.start_line), offsets); + + parse_lex_data_t parse_lex_data = { + .source = source, + .tokens = rb_ary_new(), + .encoding = rb_utf8_encoding(), + .freeze = options->freeze, + }; + + parse_lex_data_t *data = &parse_lex_data; + pm_lex_callback_t lex_callback = (pm_lex_callback_t) { + .data = (void *) data, + .callback = parse_lex_token, + }; + + parser.lex_callback = &lex_callback; + pm_node_t *node = pm_parse(&parser); + + // Here we need to update the Source object to have the correct + // encoding for the source string and the correct newline offsets. + // We do it here because we've already created the Source object and given + // it over to all of the tokens, and both of these are only set after pm_parse(). + rb_encoding *encoding = rb_enc_find(parser.encoding->name); + rb_enc_associate(source_string, encoding); + + for (size_t index = 0; index < parser.newline_list.size; index++) { + rb_ary_push(offsets, ULONG2NUM(parser.newline_list.offsets[index])); + } + + if (options->freeze) { + rb_obj_freeze(source_string); + rb_obj_freeze(offsets); + rb_obj_freeze(source); + rb_obj_freeze(parse_lex_data.tokens); + } + + VALUE result; + if (return_nodes) { + VALUE value = rb_ary_new_capa(2); + rb_ary_push(value, pm_ast_new(&parser, node, parse_lex_data.encoding, source, options->freeze)); + rb_ary_push(value, parse_lex_data.tokens); + if (options->freeze) rb_obj_freeze(value); + result = parse_result_create(rb_cPrismParseLexResult, &parser, value, parse_lex_data.encoding, source, options->freeze); + } else { + result = parse_result_create(rb_cPrismLexResult, &parser, parse_lex_data.tokens, parse_lex_data.encoding, source, options->freeze); + } + + pm_node_destroy(&parser, node); + pm_parser_free(&parser); + + return result; +} + +/** + * call-seq: + * Prism::lex(source, **options) -> LexResult + * + * Return a LexResult instance that contains an array of Token instances + * corresponding to the given string. For supported options, see Prism::parse. + */ +static VALUE +lex(int argc, VALUE *argv, VALUE self) { + pm_string_t input; + pm_options_t options = { 0 }; + string_options(argc, argv, &input, &options); + + VALUE result = parse_lex_input(&input, &options, false); + pm_string_free(&input); + pm_options_free(&options); + + return result; +} + +/** + * call-seq: + * Prism::lex_file(filepath, **options) -> LexResult + * + * Return a LexResult instance that contains an array of Token instances + * corresponding to the given file. For supported options, see Prism::parse. + */ +static VALUE +lex_file(int argc, VALUE *argv, VALUE self) { + pm_string_t input; + pm_options_t options = { 0 }; + + VALUE encoded_filepath; + file_options(argc, argv, &input, &options, &encoded_filepath); + + VALUE value = parse_lex_input(&input, &options, false); + pm_string_free(&input); + pm_options_free(&options); + + return value; +} + +/******************************************************************************/ +/* Parsing Ruby code */ +/******************************************************************************/ + +/** + * Parse the given input and return a ParseResult instance. + */ +static VALUE +parse_input(pm_string_t *input, const pm_options_t *options) { + pm_parser_t parser; + pm_parser_init(&parser, pm_string_source(input), pm_string_length(input), options); + + pm_node_t *node = pm_parse(&parser); + rb_encoding *encoding = rb_enc_find(parser.encoding->name); + + VALUE source = pm_source_new(&parser, encoding, options->freeze); + VALUE value = pm_ast_new(&parser, node, encoding, source, options->freeze); + VALUE result = parse_result_create(rb_cPrismParseResult, &parser, value, encoding, source, options->freeze); + + if (options->freeze) { + rb_obj_freeze(source); + } + + pm_node_destroy(&parser, node); + pm_parser_free(&parser); + + return result; +} + +/** + * call-seq: + * Prism::parse(source, **options) -> ParseResult + * + * Parse the given string and return a ParseResult instance. The options that + * are supported are: + * + * * `command_line` - either nil or a string of the various options that were + * set on the command line. Valid values are combinations of "a", "l", + * "n", "p", and "x". + * * `encoding` - the encoding of the source being parsed. This should be an + * encoding or nil. + * * `filepath` - the filepath of the source being parsed. This should be a + * string or nil. + * * `freeze` - whether or not to deeply freeze the AST. This should be a + * boolean or nil. + * * `frozen_string_literal` - whether or not the frozen string literal pragma + * has been set. This should be a boolean or nil. + * * `line` - the line number that the parse starts on. This should be an + * integer or nil. Note that this is 1-indexed. + * * `main_script` - a boolean indicating whether or not the source being parsed + * is the main script being run by the interpreter. This controls whether + * or not shebangs are parsed for additional flags and whether or not the + * parser will attempt to find a matching shebang if the first one does + * not contain the word "ruby". + * * `partial_script` - when the file being parsed is considered a "partial" + * script, jumps will not be marked as errors if they are not contained + * within loops/blocks. This is used in the case that you're parsing a + * script that you know will be embedded inside another script later, but + * you do not have that context yet. For example, when parsing an ERB + * template that will be evaluated inside another script. + * * `scopes` - the locals that are in scope surrounding the code that is being + * parsed. This should be an array of arrays of symbols or nil. Scopes are + * ordered from the outermost scope to the innermost one. + * * `version` - the version of Ruby syntax that prism should used to parse Ruby + * code. By default prism assumes you want to parse with the latest + * version of Ruby syntax (which you can trigger with `nil` or + * `"latest"`). You may also restrict the syntax to a specific version of + * Ruby, e.g., with `"3.3.0"`. To parse with the same syntax version that + * the current Ruby is running use `version: RUBY_VERSION`. Raises + * ArgumentError if the version is not currently supported by Prism. + */ +static VALUE +parse(int argc, VALUE *argv, VALUE self) { + pm_string_t input; + pm_options_t options = { 0 }; + string_options(argc, argv, &input, &options); + +#ifdef PRISM_BUILD_DEBUG + size_t length = pm_string_length(&input); + char* dup = xmalloc(length); + memcpy(dup, pm_string_source(&input), length); + pm_string_constant_init(&input, dup, length); +#endif + + VALUE value = parse_input(&input, &options); + +#ifdef PRISM_BUILD_DEBUG + xfree(dup); +#endif + + pm_string_free(&input); + pm_options_free(&options); + return value; +} + +/** + * call-seq: + * Prism::parse_file(filepath, **options) -> ParseResult + * + * Parse the given file and return a ParseResult instance. For supported + * options, see Prism::parse. + */ +static VALUE +parse_file(int argc, VALUE *argv, VALUE self) { + pm_string_t input; + pm_options_t options = { 0 }; + + VALUE encoded_filepath; + file_options(argc, argv, &input, &options, &encoded_filepath); + + VALUE value = parse_input(&input, &options); + pm_string_free(&input); + pm_options_free(&options); + + return value; +} + +/** + * Parse the given input and return nothing. + */ +static void +profile_input(pm_string_t *input, const pm_options_t *options) { + pm_parser_t parser; + pm_parser_init(&parser, pm_string_source(input), pm_string_length(input), options); + + pm_node_t *node = pm_parse(&parser); + pm_node_destroy(&parser, node); + pm_parser_free(&parser); +} + +/** + * call-seq: + * Prism::profile(source, **options) -> nil + * + * Parse the given string and return nothing. This method is meant to allow + * profilers to avoid the overhead of reifying the AST to Ruby. For supported + * options, see Prism::parse. + */ +static VALUE +profile(int argc, VALUE *argv, VALUE self) { + pm_string_t input; + pm_options_t options = { 0 }; + + string_options(argc, argv, &input, &options); + profile_input(&input, &options); + pm_string_free(&input); + pm_options_free(&options); + + return Qnil; +} + +/** + * call-seq: + * Prism::profile_file(filepath, **options) -> nil + * + * Parse the given file and return nothing. This method is meant to allow + * profilers to avoid the overhead of reifying the AST to Ruby. For supported + * options, see Prism::parse. + */ +static VALUE +profile_file(int argc, VALUE *argv, VALUE self) { + pm_string_t input; + pm_options_t options = { 0 }; + + VALUE encoded_filepath; + file_options(argc, argv, &input, &options, &encoded_filepath); + + profile_input(&input, &options); + pm_string_free(&input); + pm_options_free(&options); + + return Qnil; +} + +/** + * An implementation of fgets that is suitable for use with Ruby IO objects. + */ +static char * +parse_stream_fgets(char *string, int size, void *stream) { + RUBY_ASSERT(size > 0); + + VALUE line = rb_funcall((VALUE) stream, rb_intern("gets"), 1, INT2FIX(size - 1)); + if (NIL_P(line)) { + return NULL; + } + + const char *cstr = RSTRING_PTR(line); + long length = RSTRING_LEN(line); + + memcpy(string, cstr, length); + string[length] = '\0'; + + return string; +} + +/** + * call-seq: + * Prism::parse_stream(stream, **options) -> ParseResult + * + * Parse the given object that responds to `gets` and return a ParseResult + * instance. The options that are supported are the same as Prism::parse. + */ +static VALUE +parse_stream(int argc, VALUE *argv, VALUE self) { + VALUE stream; + VALUE keywords; + rb_scan_args(argc, argv, "1:", &stream, &keywords); + + pm_options_t options = { 0 }; + extract_options(&options, Qnil, keywords); + + pm_parser_t parser; + pm_buffer_t buffer; + + pm_node_t *node = pm_parse_stream(&parser, &buffer, (void *) stream, parse_stream_fgets, &options); + rb_encoding *encoding = rb_enc_find(parser.encoding->name); + + VALUE source = pm_source_new(&parser, encoding, options.freeze); + VALUE value = pm_ast_new(&parser, node, encoding, source, options.freeze); + VALUE result = parse_result_create(rb_cPrismParseResult, &parser, value, encoding, source, options.freeze); + + pm_node_destroy(&parser, node); + pm_buffer_free(&buffer); + pm_parser_free(&parser); + + return result; +} + +/** + * Parse the given input and return an array of Comment objects. + */ +static VALUE +parse_input_comments(pm_string_t *input, const pm_options_t *options) { + pm_parser_t parser; + pm_parser_init(&parser, pm_string_source(input), pm_string_length(input), options); + + pm_node_t *node = pm_parse(&parser); + rb_encoding *encoding = rb_enc_find(parser.encoding->name); + + VALUE source = pm_source_new(&parser, encoding, options->freeze); + VALUE comments = parser_comments(&parser, source, options->freeze); + + pm_node_destroy(&parser, node); + pm_parser_free(&parser); + + return comments; +} + +/** + * call-seq: + * Prism::parse_comments(source, **options) -> Array + * + * Parse the given string and return an array of Comment objects. For supported + * options, see Prism::parse. + */ +static VALUE +parse_comments(int argc, VALUE *argv, VALUE self) { + pm_string_t input; + pm_options_t options = { 0 }; + string_options(argc, argv, &input, &options); + + VALUE result = parse_input_comments(&input, &options); + pm_string_free(&input); + pm_options_free(&options); + + return result; +} + +/** + * call-seq: + * Prism::parse_file_comments(filepath, **options) -> Array + * + * Parse the given file and return an array of Comment objects. For supported + * options, see Prism::parse. + */ +static VALUE +parse_file_comments(int argc, VALUE *argv, VALUE self) { + pm_string_t input; + pm_options_t options = { 0 }; + + VALUE encoded_filepath; + file_options(argc, argv, &input, &options, &encoded_filepath); + + VALUE value = parse_input_comments(&input, &options); + pm_string_free(&input); + pm_options_free(&options); + + return value; +} + +/** + * call-seq: + * Prism::parse_lex(source, **options) -> ParseLexResult + * + * Parse the given string and return a ParseLexResult instance that contains a + * 2-element array, where the first element is the AST and the second element is + * an array of Token instances. + * + * This API is only meant to be used in the case where you need both the AST and + * the tokens. If you only need one or the other, use either Prism::parse or + * Prism::lex. + * + * For supported options, see Prism::parse. + */ +static VALUE +parse_lex(int argc, VALUE *argv, VALUE self) { + pm_string_t input; + pm_options_t options = { 0 }; + string_options(argc, argv, &input, &options); + + VALUE value = parse_lex_input(&input, &options, true); + pm_string_free(&input); + pm_options_free(&options); + + return value; +} + +/** + * call-seq: + * Prism::parse_lex_file(filepath, **options) -> ParseLexResult + * + * Parse the given file and return a ParseLexResult instance that contains a + * 2-element array, where the first element is the AST and the second element is + * an array of Token instances. + * + * This API is only meant to be used in the case where you need both the AST and + * the tokens. If you only need one or the other, use either Prism::parse_file + * or Prism::lex_file. + * + * For supported options, see Prism::parse. + */ +static VALUE +parse_lex_file(int argc, VALUE *argv, VALUE self) { + pm_string_t input; + pm_options_t options = { 0 }; + + VALUE encoded_filepath; + file_options(argc, argv, &input, &options, &encoded_filepath); + + VALUE value = parse_lex_input(&input, &options, true); + pm_string_free(&input); + pm_options_free(&options); + + return value; +} + +/** + * Parse the given input and return true if it parses without errors. + */ +static VALUE +parse_input_success_p(pm_string_t *input, const pm_options_t *options) { + pm_parser_t parser; + pm_parser_init(&parser, pm_string_source(input), pm_string_length(input), options); + + pm_node_t *node = pm_parse(&parser); + pm_node_destroy(&parser, node); + + VALUE result = parser.error_list.size == 0 ? Qtrue : Qfalse; + pm_parser_free(&parser); + + return result; +} + +/** + * call-seq: + * Prism::parse_success?(source, **options) -> bool + * + * Parse the given string and return true if it parses without errors. For + * supported options, see Prism::parse. + */ +static VALUE +parse_success_p(int argc, VALUE *argv, VALUE self) { + pm_string_t input; + pm_options_t options = { 0 }; + string_options(argc, argv, &input, &options); + + VALUE result = parse_input_success_p(&input, &options); + pm_string_free(&input); + pm_options_free(&options); + + return result; +} + +/** + * call-seq: + * Prism::parse_failure?(source, **options) -> bool + * + * Parse the given string and return true if it parses with errors. For + * supported options, see Prism::parse. + */ +static VALUE +parse_failure_p(int argc, VALUE *argv, VALUE self) { + return RTEST(parse_success_p(argc, argv, self)) ? Qfalse : Qtrue; +} + +/** + * call-seq: + * Prism::parse_file_success?(filepath, **options) -> bool + * + * Parse the given file and return true if it parses without errors. For + * supported options, see Prism::parse. + */ +static VALUE +parse_file_success_p(int argc, VALUE *argv, VALUE self) { + pm_string_t input; + pm_options_t options = { 0 }; + + VALUE encoded_filepath; + file_options(argc, argv, &input, &options, &encoded_filepath); + + VALUE result = parse_input_success_p(&input, &options); + pm_string_free(&input); + pm_options_free(&options); + + return result; +} + +/** + * call-seq: + * Prism::parse_file_failure?(filepath, **options) -> bool + * + * Parse the given file and return true if it parses with errors. For + * supported options, see Prism::parse. + */ +static VALUE +parse_file_failure_p(int argc, VALUE *argv, VALUE self) { + return RTEST(parse_file_success_p(argc, argv, self)) ? Qfalse : Qtrue; +} + +/******************************************************************************/ +/* String query methods */ +/******************************************************************************/ + +/** + * Process the result of a call to a string query method and return an + * appropriate value. + */ +static VALUE +string_query(pm_string_query_t result) { + switch (result) { + case PM_STRING_QUERY_ERROR: + rb_raise(rb_eArgError, "Invalid or non ascii-compatible encoding"); + return Qfalse; + case PM_STRING_QUERY_FALSE: + return Qfalse; + case PM_STRING_QUERY_TRUE: + return Qtrue; + } + return Qfalse; +} + +/** + * call-seq: + * Prism::StringQuery::local?(string) -> bool + * + * Returns true if the string constitutes a valid local variable name. Note that + * this means the names that can be set through Binding#local_variable_set, not + * necessarily the ones that can be set through a local variable assignment. + */ +static VALUE +string_query_local_p(VALUE self, VALUE string) { + const uint8_t *source = (const uint8_t *) check_string(string); + return string_query(pm_string_query_local(source, RSTRING_LEN(string), rb_enc_get(string)->name)); +} + +/** + * call-seq: + * Prism::StringQuery::constant?(string) -> bool + * + * Returns true if the string constitutes a valid constant name. Note that this + * means the names that can be set through Module#const_set, not necessarily the + * ones that can be set through a constant assignment. + */ +static VALUE +string_query_constant_p(VALUE self, VALUE string) { + const uint8_t *source = (const uint8_t *) check_string(string); + return string_query(pm_string_query_constant(source, RSTRING_LEN(string), rb_enc_get(string)->name)); +} + +/** + * call-seq: + * Prism::StringQuery::method_name?(string) -> bool + * + * Returns true if the string constitutes a valid method name. + */ +static VALUE +string_query_method_name_p(VALUE self, VALUE string) { + const uint8_t *source = (const uint8_t *) check_string(string); + return string_query(pm_string_query_method_name(source, RSTRING_LEN(string), rb_enc_get(string)->name)); +} + +/******************************************************************************/ +/* Initialization of the extension */ +/******************************************************************************/ + +/** + * The init function that Ruby calls when loading this extension. + */ +RUBY_FUNC_EXPORTED void +Init_prism(void) { + // Make sure that the prism library version matches the expected version. + // Otherwise something was compiled incorrectly. + if (strcmp(pm_version(), EXPECTED_PRISM_VERSION) != 0) { + rb_raise( + rb_eRuntimeError, + "The prism library version (%s) does not match the expected version (%s)", + pm_version(), + EXPECTED_PRISM_VERSION + ); + } + + // Grab up references to all of the constants that we're going to need to + // reference throughout this extension. + rb_cPrism = rb_define_module("Prism"); + rb_cPrismNode = rb_define_class_under(rb_cPrism, "Node", rb_cObject); + rb_cPrismSource = rb_define_class_under(rb_cPrism, "Source", rb_cObject); + rb_cPrismToken = rb_define_class_under(rb_cPrism, "Token", rb_cObject); + rb_cPrismLocation = rb_define_class_under(rb_cPrism, "Location", rb_cObject); + rb_cPrismComment = rb_define_class_under(rb_cPrism, "Comment", rb_cObject); + rb_cPrismInlineComment = rb_define_class_under(rb_cPrism, "InlineComment", rb_cPrismComment); + rb_cPrismEmbDocComment = rb_define_class_under(rb_cPrism, "EmbDocComment", rb_cPrismComment); + rb_cPrismMagicComment = rb_define_class_under(rb_cPrism, "MagicComment", rb_cObject); + rb_cPrismParseError = rb_define_class_under(rb_cPrism, "ParseError", rb_cObject); + rb_cPrismParseWarning = rb_define_class_under(rb_cPrism, "ParseWarning", rb_cObject); + rb_cPrismResult = rb_define_class_under(rb_cPrism, "Result", rb_cObject); + rb_cPrismParseResult = rb_define_class_under(rb_cPrism, "ParseResult", rb_cPrismResult); + rb_cPrismLexResult = rb_define_class_under(rb_cPrism, "LexResult", rb_cPrismResult); + rb_cPrismParseLexResult = rb_define_class_under(rb_cPrism, "ParseLexResult", rb_cPrismResult); + rb_cPrismStringQuery = rb_define_class_under(rb_cPrism, "StringQuery", rb_cObject); + rb_cPrismScope = rb_define_class_under(rb_cPrism, "Scope", rb_cObject); + + // Intern all of the IDs eagerly that we support so that we don't have to do + // it every time we parse. + rb_id_option_command_line = rb_intern_const("command_line"); + rb_id_option_encoding = rb_intern_const("encoding"); + rb_id_option_filepath = rb_intern_const("filepath"); + rb_id_option_freeze = rb_intern_const("freeze"); + rb_id_option_frozen_string_literal = rb_intern_const("frozen_string_literal"); + rb_id_option_line = rb_intern_const("line"); + rb_id_option_main_script = rb_intern_const("main_script"); + rb_id_option_partial_script = rb_intern_const("partial_script"); + rb_id_option_scopes = rb_intern_const("scopes"); + rb_id_option_version = rb_intern_const("version"); + rb_id_source_for = rb_intern("for"); + rb_id_forwarding_positionals = rb_intern("*"); + rb_id_forwarding_keywords = rb_intern("**"); + rb_id_forwarding_block = rb_intern("&"); + rb_id_forwarding_all = rb_intern("..."); + + /** + * The version of the prism library. + */ + rb_define_const(rb_cPrism, "VERSION", rb_str_freeze(rb_str_new_cstr(EXPECTED_PRISM_VERSION))); + + // First, the functions that have to do with lexing and parsing. + rb_define_singleton_method(rb_cPrism, "lex", lex, -1); + rb_define_singleton_method(rb_cPrism, "lex_file", lex_file, -1); + rb_define_singleton_method(rb_cPrism, "parse", parse, -1); + rb_define_singleton_method(rb_cPrism, "parse_file", parse_file, -1); + rb_define_singleton_method(rb_cPrism, "profile", profile, -1); + rb_define_singleton_method(rb_cPrism, "profile_file", profile_file, -1); + rb_define_singleton_method(rb_cPrism, "parse_stream", parse_stream, -1); + rb_define_singleton_method(rb_cPrism, "parse_comments", parse_comments, -1); + rb_define_singleton_method(rb_cPrism, "parse_file_comments", parse_file_comments, -1); + rb_define_singleton_method(rb_cPrism, "parse_lex", parse_lex, -1); + rb_define_singleton_method(rb_cPrism, "parse_lex_file", parse_lex_file, -1); + rb_define_singleton_method(rb_cPrism, "parse_success?", parse_success_p, -1); + rb_define_singleton_method(rb_cPrism, "parse_failure?", parse_failure_p, -1); + rb_define_singleton_method(rb_cPrism, "parse_file_success?", parse_file_success_p, -1); + rb_define_singleton_method(rb_cPrism, "parse_file_failure?", parse_file_failure_p, -1); + +#ifndef PRISM_EXCLUDE_SERIALIZATION + rb_define_singleton_method(rb_cPrism, "dump", dump, -1); + rb_define_singleton_method(rb_cPrism, "dump_file", dump_file, -1); +#endif + + rb_define_singleton_method(rb_cPrismStringQuery, "local?", string_query_local_p, 1); + rb_define_singleton_method(rb_cPrismStringQuery, "constant?", string_query_constant_p, 1); + rb_define_singleton_method(rb_cPrismStringQuery, "method_name?", string_query_method_name_p, 1); + + // Next, initialize the other APIs. + Init_prism_api_node(); + Init_prism_pack(); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext/prism/extension.h b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext/prism/extension.h new file mode 100644 index 00000000..506da2fd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/ext/prism/extension.h @@ -0,0 +1,19 @@ +#ifndef PRISM_EXT_NODE_H +#define PRISM_EXT_NODE_H + +#define EXPECTED_PRISM_VERSION "1.4.0" + +#include +#include +#include "prism.h" + +VALUE pm_source_new(const pm_parser_t *parser, rb_encoding *encoding, bool freeze); +VALUE pm_token_new(const pm_parser_t *parser, const pm_token_t *token, rb_encoding *encoding, VALUE source, bool freeze); +VALUE pm_ast_new(const pm_parser_t *parser, const pm_node_t *node, rb_encoding *encoding, VALUE source, bool freeze); +VALUE pm_integer_new(const pm_integer_t *integer); + +void Init_prism_api_node(void); +void Init_prism_pack(void); +RUBY_FUNC_EXPORTED void Init_prism(void); + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism.h b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism.h new file mode 100644 index 00000000..317568aa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism.h @@ -0,0 +1,383 @@ +/** + * @file prism.h + * + * The main header file for the prism parser. + */ +#ifndef PRISM_H +#define PRISM_H + +#include "prism/defines.h" +#include "prism/util/pm_buffer.h" +#include "prism/util/pm_char.h" +#include "prism/util/pm_integer.h" +#include "prism/util/pm_memchr.h" +#include "prism/util/pm_strncasecmp.h" +#include "prism/util/pm_strpbrk.h" +#include "prism/ast.h" +#include "prism/diagnostic.h" +#include "prism/node.h" +#include "prism/options.h" +#include "prism/pack.h" +#include "prism/parser.h" +#include "prism/prettyprint.h" +#include "prism/regexp.h" +#include "prism/static_literals.h" +#include "prism/version.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef _WIN32 +#include +#endif + +/** + * The prism version and the serialization format. + * + * @returns The prism version as a constant string. + */ +PRISM_EXPORTED_FUNCTION const char * pm_version(void); + +/** + * Initialize a parser with the given start and end pointers. + * + * @param parser The parser to initialize. + * @param source The source to parse. + * @param size The size of the source. + * @param options The optional options to use when parsing. + */ +PRISM_EXPORTED_FUNCTION void pm_parser_init(pm_parser_t *parser, const uint8_t *source, size_t size, const pm_options_t *options); + +/** + * Register a callback that will be called whenever prism changes the encoding + * it is using to parse based on the magic comment. + * + * @param parser The parser to register the callback with. + * @param callback The callback to register. + */ +PRISM_EXPORTED_FUNCTION void pm_parser_register_encoding_changed_callback(pm_parser_t *parser, pm_encoding_changed_callback_t callback); + +/** + * Free any memory associated with the given parser. + * + * @param parser The parser to free. + */ +PRISM_EXPORTED_FUNCTION void pm_parser_free(pm_parser_t *parser); + +/** + * Initiate the parser with the given parser. + * + * @param parser The parser to use. + * @return The AST representing the source. + */ +PRISM_EXPORTED_FUNCTION pm_node_t * pm_parse(pm_parser_t *parser); + +/** + * This function is used in pm_parse_stream to retrieve a line of input from a + * stream. It closely mirrors that of fgets so that fgets can be used as the + * default implementation. + */ +typedef char * (pm_parse_stream_fgets_t)(char *string, int size, void *stream); + +/** + * Parse a stream of Ruby source and return the tree. + * + * @param parser The parser to use. + * @param buffer The buffer to use. + * @param stream The stream to parse. + * @param stream_fgets The function to use to read from the stream. + * @param options The optional options to use when parsing. + * @return The AST representing the source. + */ +PRISM_EXPORTED_FUNCTION pm_node_t * pm_parse_stream(pm_parser_t *parser, pm_buffer_t *buffer, void *stream, pm_parse_stream_fgets_t *stream_fgets, const pm_options_t *options); + +// We optionally support serializing to a binary string. For systems that don't +// want or need this functionality, it can be turned off with the +// PRISM_EXCLUDE_SERIALIZATION define. +#ifndef PRISM_EXCLUDE_SERIALIZATION + +/** + * Parse and serialize the AST represented by the source that is read out of the + * given stream into to the given buffer. + * + * @param buffer The buffer to serialize to. + * @param stream The stream to parse. + * @param stream_fgets The function to use to read from the stream. + * @param data The optional data to pass to the parser. + */ +PRISM_EXPORTED_FUNCTION void pm_serialize_parse_stream(pm_buffer_t *buffer, void *stream, pm_parse_stream_fgets_t *stream_fgets, const char *data); + +/** + * Serialize the given list of comments to the given buffer. + * + * @param parser The parser to serialize. + * @param list The list of comments to serialize. + * @param buffer The buffer to serialize to. + */ +void pm_serialize_comment_list(pm_parser_t *parser, pm_list_t *list, pm_buffer_t *buffer); + +/** + * Serialize the name of the encoding to the buffer. + * + * @param encoding The encoding to serialize. + * @param buffer The buffer to serialize to. + */ +void pm_serialize_encoding(const pm_encoding_t *encoding, pm_buffer_t *buffer); + +/** + * Serialize the encoding, metadata, nodes, and constant pool. + * + * @param parser The parser to serialize. + * @param node The node to serialize. + * @param buffer The buffer to serialize to. + */ +void pm_serialize_content(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer); + +/** + * Serialize the AST represented by the given node to the given buffer. + * + * @param parser The parser to serialize. + * @param node The node to serialize. + * @param buffer The buffer to serialize to. + */ +PRISM_EXPORTED_FUNCTION void pm_serialize(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer); + +/** + * Parse the given source to the AST and dump the AST to the given buffer. + * + * @param buffer The buffer to serialize to. + * @param source The source to parse. + * @param size The size of the source. + * @param data The optional data to pass to the parser. + */ +PRISM_EXPORTED_FUNCTION void pm_serialize_parse(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data); + +/** + * Parse and serialize the comments in the given source to the given buffer. + * + * @param buffer The buffer to serialize to. + * @param source The source to parse. + * @param size The size of the source. + * @param data The optional data to pass to the parser. + */ +PRISM_EXPORTED_FUNCTION void pm_serialize_parse_comments(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data); + +/** + * Lex the given source and serialize to the given buffer. + * + * @param source The source to lex. + * @param size The size of the source. + * @param buffer The buffer to serialize to. + * @param data The optional data to pass to the lexer. + */ +PRISM_EXPORTED_FUNCTION void pm_serialize_lex(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data); + +/** + * Parse and serialize both the AST and the tokens represented by the given + * source to the given buffer. + * + * @param buffer The buffer to serialize to. + * @param source The source to parse. + * @param size The size of the source. + * @param data The optional data to pass to the parser. + */ +PRISM_EXPORTED_FUNCTION void pm_serialize_parse_lex(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data); + +#endif + +/** + * Parse the source and return true if it parses without errors or warnings. + * + * @param source The source to parse. + * @param size The size of the source. + * @param data The optional data to pass to the parser. + * @return True if the source parses without errors or warnings. + */ +PRISM_EXPORTED_FUNCTION bool pm_parse_success_p(const uint8_t *source, size_t size, const char *data); + +/** + * Returns a string representation of the given token type. + * + * @param token_type The token type to convert to a string. + * @return A string representation of the given token type. + */ +PRISM_EXPORTED_FUNCTION const char * pm_token_type_name(pm_token_type_t token_type); + +/** + * Returns the human name of the given token type. + * + * @param token_type The token type to convert to a human name. + * @return The human name of the given token type. + */ +const char * pm_token_type_human(pm_token_type_t token_type); + +// We optionally support dumping to JSON. For systems that don't want or need +// this functionality, it can be turned off with the PRISM_EXCLUDE_JSON define. +#ifndef PRISM_EXCLUDE_JSON + +/** + * Dump JSON to the given buffer. + * + * @param buffer The buffer to serialize to. + * @param parser The parser that parsed the node. + * @param node The node to serialize. + */ +PRISM_EXPORTED_FUNCTION void pm_dump_json(pm_buffer_t *buffer, const pm_parser_t *parser, const pm_node_t *node); + +#endif + +/** + * Represents the results of a slice query. + */ +typedef enum { + /** Returned if the encoding given to a slice query was invalid. */ + PM_STRING_QUERY_ERROR = -1, + + /** Returned if the result of the slice query is false. */ + PM_STRING_QUERY_FALSE, + + /** Returned if the result of the slice query is true. */ + PM_STRING_QUERY_TRUE +} pm_string_query_t; + +/** + * Check that the slice is a valid local variable name. + * + * @param source The source to check. + * @param length The length of the source. + * @param encoding_name The name of the encoding of the source. + * @return PM_STRING_QUERY_TRUE if the query is true, PM_STRING_QUERY_FALSE if + * the query is false, and PM_STRING_QUERY_ERROR if the encoding was invalid. + */ +PRISM_EXPORTED_FUNCTION pm_string_query_t pm_string_query_local(const uint8_t *source, size_t length, const char *encoding_name); + +/** + * Check that the slice is a valid constant name. + * + * @param source The source to check. + * @param length The length of the source. + * @param encoding_name The name of the encoding of the source. + * @return PM_STRING_QUERY_TRUE if the query is true, PM_STRING_QUERY_FALSE if + * the query is false, and PM_STRING_QUERY_ERROR if the encoding was invalid. + */ +PRISM_EXPORTED_FUNCTION pm_string_query_t pm_string_query_constant(const uint8_t *source, size_t length, const char *encoding_name); + +/** + * Check that the slice is a valid method name. + * + * @param source The source to check. + * @param length The length of the source. + * @param encoding_name The name of the encoding of the source. + * @return PM_STRING_QUERY_TRUE if the query is true, PM_STRING_QUERY_FALSE if + * the query is false, and PM_STRING_QUERY_ERROR if the encoding was invalid. + */ +PRISM_EXPORTED_FUNCTION pm_string_query_t pm_string_query_method_name(const uint8_t *source, size_t length, const char *encoding_name); + +/** + * @mainpage + * + * Prism is a parser for the Ruby programming language. It is designed to be + * portable, error tolerant, and maintainable. It is written in C99 and has no + * dependencies. It is currently being integrated into + * [CRuby](https://github.com/ruby/ruby), + * [JRuby](https://github.com/jruby/jruby), + * [TruffleRuby](https://github.com/oracle/truffleruby), + * [Sorbet](https://github.com/sorbet/sorbet), and + * [Syntax Tree](https://github.com/ruby-syntax-tree/syntax_tree). + * + * @section getting-started Getting started + * + * If you're vendoring this project and compiling it statically then as long as + * you have a C99 compiler you will be fine. If you're linking against it as + * shared library, then you should compile with `-fvisibility=hidden` and + * `-DPRISM_EXPORT_SYMBOLS` to tell prism to make only its public interface + * visible. + * + * @section parsing Parsing + * + * In order to parse Ruby code, the structures and functions that you're going + * to want to use and be aware of are: + * + * * `pm_parser_t` - the main parser structure + * * `pm_parser_init` - initialize a parser + * * `pm_parse` - parse and return the root node + * * `pm_node_destroy` - deallocate the root node returned by `pm_parse` + * * `pm_parser_free` - free the internal memory of the parser + * + * Putting all of this together would look something like: + * + * ```c + * void parse(const uint8_t *source, size_t length) { + * pm_parser_t parser; + * pm_parser_init(&parser, source, length, NULL); + * + * pm_node_t *root = pm_parse(&parser); + * printf("PARSED!\n"); + * + * pm_node_destroy(&parser, root); + * pm_parser_free(&parser); + * } + * ``` + * + * All of the nodes "inherit" from `pm_node_t` by embedding those structures as + * their first member. This means you can downcast and upcast any node in the + * tree to a `pm_node_t`. + * + * @section serializing Serializing + * + * Prism provides the ability to serialize the AST and its related metadata into + * a binary format. This format is designed to be portable to different + * languages and runtimes so that you only need to make one FFI call in order to + * parse Ruby code. The structures and functions that you're going to want to + * use and be aware of are: + * + * * `pm_buffer_t` - a small buffer object that will hold the serialized AST + * * `pm_buffer_free` - free the memory associated with the buffer + * * `pm_serialize` - serialize the AST into a buffer + * * `pm_serialize_parse` - parse and serialize the AST into a buffer + * + * Putting all of this together would look something like: + * + * ```c + * void serialize(const uint8_t *source, size_t length) { + * pm_buffer_t buffer = { 0 }; + * + * pm_serialize_parse(&buffer, source, length, NULL); + * printf("SERIALIZED!\n"); + * + * pm_buffer_free(&buffer); + * } + * ``` + * + * @section inspecting Inspecting + * + * Prism provides the ability to inspect the AST by pretty-printing nodes. You + * can do this with the `pm_prettyprint` function, which you would use like: + * + * ```c + * void prettyprint(const uint8_t *source, size_t length) { + * pm_parser_t parser; + * pm_parser_init(&parser, source, length, NULL); + * + * pm_node_t *root = pm_parse(&parser); + * pm_buffer_t buffer = { 0 }; + * + * pm_prettyprint(&buffer, &parser, root); + * printf("%*.s\n", (int) buffer.length, buffer.value); + * + * pm_buffer_free(&buffer); + * pm_node_destroy(&parser, root); + * pm_parser_free(&parser); + * } + * ``` + */ + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/ast.h b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/ast.h new file mode 100644 index 00000000..9c4ad636 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/ast.h @@ -0,0 +1,7964 @@ +/*----------------------------------------------------------------------------*/ +/* This file is generated by the templates/template.rb script and should not */ +/* be modified manually. See */ +/* templates/include/prism/ast.h.erb */ +/* if you are looking to modify the */ +/* template */ +/*----------------------------------------------------------------------------*/ + +/** + * @file ast.h + * + * The abstract syntax tree. + */ +#ifndef PRISM_AST_H +#define PRISM_AST_H + +#include "prism/defines.h" +#include "prism/util/pm_constant_pool.h" +#include "prism/util/pm_integer.h" +#include "prism/util/pm_string.h" + +#include +#include +#include + +/** + * This enum represents every type of token in the Ruby source. + */ +typedef enum pm_token_type { + /** final token in the file */ + PM_TOKEN_EOF = 1, + + /** a token that was expected but not found */ + PM_TOKEN_MISSING, + + /** a token that was not present but it is okay */ + PM_TOKEN_NOT_PROVIDED, + + /** & */ + PM_TOKEN_AMPERSAND, + + /** && */ + PM_TOKEN_AMPERSAND_AMPERSAND, + + /** &&= */ + PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL, + + /** &. */ + PM_TOKEN_AMPERSAND_DOT, + + /** &= */ + PM_TOKEN_AMPERSAND_EQUAL, + + /** ` */ + PM_TOKEN_BACKTICK, + + /** a back reference */ + PM_TOKEN_BACK_REFERENCE, + + /** ! or !@ */ + PM_TOKEN_BANG, + + /** != */ + PM_TOKEN_BANG_EQUAL, + + /** !~ */ + PM_TOKEN_BANG_TILDE, + + /** { */ + PM_TOKEN_BRACE_LEFT, + + /** } */ + PM_TOKEN_BRACE_RIGHT, + + /** [ */ + PM_TOKEN_BRACKET_LEFT, + + /** [ for the beginning of an array */ + PM_TOKEN_BRACKET_LEFT_ARRAY, + + /** [] */ + PM_TOKEN_BRACKET_LEFT_RIGHT, + + /** []= */ + PM_TOKEN_BRACKET_LEFT_RIGHT_EQUAL, + + /** ] */ + PM_TOKEN_BRACKET_RIGHT, + + /** ^ */ + PM_TOKEN_CARET, + + /** ^= */ + PM_TOKEN_CARET_EQUAL, + + /** a character literal */ + PM_TOKEN_CHARACTER_LITERAL, + + /** a class variable */ + PM_TOKEN_CLASS_VARIABLE, + + /** : */ + PM_TOKEN_COLON, + + /** :: */ + PM_TOKEN_COLON_COLON, + + /** , */ + PM_TOKEN_COMMA, + + /** a comment */ + PM_TOKEN_COMMENT, + + /** a constant */ + PM_TOKEN_CONSTANT, + + /** the . call operator */ + PM_TOKEN_DOT, + + /** the .. range operator */ + PM_TOKEN_DOT_DOT, + + /** the ... range operator or forwarding parameter */ + PM_TOKEN_DOT_DOT_DOT, + + /** =begin */ + PM_TOKEN_EMBDOC_BEGIN, + + /** =end */ + PM_TOKEN_EMBDOC_END, + + /** a line inside of embedded documentation */ + PM_TOKEN_EMBDOC_LINE, + + /** #{ */ + PM_TOKEN_EMBEXPR_BEGIN, + + /** } */ + PM_TOKEN_EMBEXPR_END, + + /** # */ + PM_TOKEN_EMBVAR, + + /** = */ + PM_TOKEN_EQUAL, + + /** == */ + PM_TOKEN_EQUAL_EQUAL, + + /** === */ + PM_TOKEN_EQUAL_EQUAL_EQUAL, + + /** => */ + PM_TOKEN_EQUAL_GREATER, + + /** =~ */ + PM_TOKEN_EQUAL_TILDE, + + /** a floating point number */ + PM_TOKEN_FLOAT, + + /** a floating pointer number with an imaginary suffix */ + PM_TOKEN_FLOAT_IMAGINARY, + + /** a floating pointer number with a rational suffix */ + PM_TOKEN_FLOAT_RATIONAL, + + /** a floating pointer number with a rational and imaginary suffix */ + PM_TOKEN_FLOAT_RATIONAL_IMAGINARY, + + /** a global variable */ + PM_TOKEN_GLOBAL_VARIABLE, + + /** > */ + PM_TOKEN_GREATER, + + /** >= */ + PM_TOKEN_GREATER_EQUAL, + + /** >> */ + PM_TOKEN_GREATER_GREATER, + + /** >>= */ + PM_TOKEN_GREATER_GREATER_EQUAL, + + /** the end of a heredoc */ + PM_TOKEN_HEREDOC_END, + + /** the start of a heredoc */ + PM_TOKEN_HEREDOC_START, + + /** an identifier */ + PM_TOKEN_IDENTIFIER, + + /** an ignored newline */ + PM_TOKEN_IGNORED_NEWLINE, + + /** an instance variable */ + PM_TOKEN_INSTANCE_VARIABLE, + + /** an integer (any base) */ + PM_TOKEN_INTEGER, + + /** an integer with an imaginary suffix */ + PM_TOKEN_INTEGER_IMAGINARY, + + /** an integer with a rational suffix */ + PM_TOKEN_INTEGER_RATIONAL, + + /** an integer with a rational and imaginary suffix */ + PM_TOKEN_INTEGER_RATIONAL_IMAGINARY, + + /** alias */ + PM_TOKEN_KEYWORD_ALIAS, + + /** and */ + PM_TOKEN_KEYWORD_AND, + + /** begin */ + PM_TOKEN_KEYWORD_BEGIN, + + /** BEGIN */ + PM_TOKEN_KEYWORD_BEGIN_UPCASE, + + /** break */ + PM_TOKEN_KEYWORD_BREAK, + + /** case */ + PM_TOKEN_KEYWORD_CASE, + + /** class */ + PM_TOKEN_KEYWORD_CLASS, + + /** def */ + PM_TOKEN_KEYWORD_DEF, + + /** defined? */ + PM_TOKEN_KEYWORD_DEFINED, + + /** do */ + PM_TOKEN_KEYWORD_DO, + + /** do keyword for a predicate in a while, until, or for loop */ + PM_TOKEN_KEYWORD_DO_LOOP, + + /** else */ + PM_TOKEN_KEYWORD_ELSE, + + /** elsif */ + PM_TOKEN_KEYWORD_ELSIF, + + /** end */ + PM_TOKEN_KEYWORD_END, + + /** END */ + PM_TOKEN_KEYWORD_END_UPCASE, + + /** ensure */ + PM_TOKEN_KEYWORD_ENSURE, + + /** false */ + PM_TOKEN_KEYWORD_FALSE, + + /** for */ + PM_TOKEN_KEYWORD_FOR, + + /** if */ + PM_TOKEN_KEYWORD_IF, + + /** if in the modifier form */ + PM_TOKEN_KEYWORD_IF_MODIFIER, + + /** in */ + PM_TOKEN_KEYWORD_IN, + + /** module */ + PM_TOKEN_KEYWORD_MODULE, + + /** next */ + PM_TOKEN_KEYWORD_NEXT, + + /** nil */ + PM_TOKEN_KEYWORD_NIL, + + /** not */ + PM_TOKEN_KEYWORD_NOT, + + /** or */ + PM_TOKEN_KEYWORD_OR, + + /** redo */ + PM_TOKEN_KEYWORD_REDO, + + /** rescue */ + PM_TOKEN_KEYWORD_RESCUE, + + /** rescue in the modifier form */ + PM_TOKEN_KEYWORD_RESCUE_MODIFIER, + + /** retry */ + PM_TOKEN_KEYWORD_RETRY, + + /** return */ + PM_TOKEN_KEYWORD_RETURN, + + /** self */ + PM_TOKEN_KEYWORD_SELF, + + /** super */ + PM_TOKEN_KEYWORD_SUPER, + + /** then */ + PM_TOKEN_KEYWORD_THEN, + + /** true */ + PM_TOKEN_KEYWORD_TRUE, + + /** undef */ + PM_TOKEN_KEYWORD_UNDEF, + + /** unless */ + PM_TOKEN_KEYWORD_UNLESS, + + /** unless in the modifier form */ + PM_TOKEN_KEYWORD_UNLESS_MODIFIER, + + /** until */ + PM_TOKEN_KEYWORD_UNTIL, + + /** until in the modifier form */ + PM_TOKEN_KEYWORD_UNTIL_MODIFIER, + + /** when */ + PM_TOKEN_KEYWORD_WHEN, + + /** while */ + PM_TOKEN_KEYWORD_WHILE, + + /** while in the modifier form */ + PM_TOKEN_KEYWORD_WHILE_MODIFIER, + + /** yield */ + PM_TOKEN_KEYWORD_YIELD, + + /** __ENCODING__ */ + PM_TOKEN_KEYWORD___ENCODING__, + + /** __FILE__ */ + PM_TOKEN_KEYWORD___FILE__, + + /** __LINE__ */ + PM_TOKEN_KEYWORD___LINE__, + + /** a label */ + PM_TOKEN_LABEL, + + /** the end of a label */ + PM_TOKEN_LABEL_END, + + /** { */ + PM_TOKEN_LAMBDA_BEGIN, + + /** < */ + PM_TOKEN_LESS, + + /** <= */ + PM_TOKEN_LESS_EQUAL, + + /** <=> */ + PM_TOKEN_LESS_EQUAL_GREATER, + + /** << */ + PM_TOKEN_LESS_LESS, + + /** <<= */ + PM_TOKEN_LESS_LESS_EQUAL, + + /** a method name */ + PM_TOKEN_METHOD_NAME, + + /** - */ + PM_TOKEN_MINUS, + + /** -= */ + PM_TOKEN_MINUS_EQUAL, + + /** -> */ + PM_TOKEN_MINUS_GREATER, + + /** a newline character outside of other tokens */ + PM_TOKEN_NEWLINE, + + /** a numbered reference to a capture group in the previous regular expression match */ + PM_TOKEN_NUMBERED_REFERENCE, + + /** ( */ + PM_TOKEN_PARENTHESIS_LEFT, + + /** ( for a parentheses node */ + PM_TOKEN_PARENTHESIS_LEFT_PARENTHESES, + + /** ) */ + PM_TOKEN_PARENTHESIS_RIGHT, + + /** % */ + PM_TOKEN_PERCENT, + + /** %= */ + PM_TOKEN_PERCENT_EQUAL, + + /** %i */ + PM_TOKEN_PERCENT_LOWER_I, + + /** %w */ + PM_TOKEN_PERCENT_LOWER_W, + + /** %x */ + PM_TOKEN_PERCENT_LOWER_X, + + /** %I */ + PM_TOKEN_PERCENT_UPPER_I, + + /** %W */ + PM_TOKEN_PERCENT_UPPER_W, + + /** | */ + PM_TOKEN_PIPE, + + /** |= */ + PM_TOKEN_PIPE_EQUAL, + + /** || */ + PM_TOKEN_PIPE_PIPE, + + /** ||= */ + PM_TOKEN_PIPE_PIPE_EQUAL, + + /** + */ + PM_TOKEN_PLUS, + + /** += */ + PM_TOKEN_PLUS_EQUAL, + + /** ? */ + PM_TOKEN_QUESTION_MARK, + + /** the beginning of a regular expression */ + PM_TOKEN_REGEXP_BEGIN, + + /** the end of a regular expression */ + PM_TOKEN_REGEXP_END, + + /** ; */ + PM_TOKEN_SEMICOLON, + + /** / */ + PM_TOKEN_SLASH, + + /** /= */ + PM_TOKEN_SLASH_EQUAL, + + /** * */ + PM_TOKEN_STAR, + + /** *= */ + PM_TOKEN_STAR_EQUAL, + + /** ** */ + PM_TOKEN_STAR_STAR, + + /** **= */ + PM_TOKEN_STAR_STAR_EQUAL, + + /** the beginning of a string */ + PM_TOKEN_STRING_BEGIN, + + /** the contents of a string */ + PM_TOKEN_STRING_CONTENT, + + /** the end of a string */ + PM_TOKEN_STRING_END, + + /** the beginning of a symbol */ + PM_TOKEN_SYMBOL_BEGIN, + + /** ~ or ~@ */ + PM_TOKEN_TILDE, + + /** unary & */ + PM_TOKEN_UAMPERSAND, + + /** unary :: */ + PM_TOKEN_UCOLON_COLON, + + /** unary .. operator */ + PM_TOKEN_UDOT_DOT, + + /** unary ... operator */ + PM_TOKEN_UDOT_DOT_DOT, + + /** -@ */ + PM_TOKEN_UMINUS, + + /** -@ for a number */ + PM_TOKEN_UMINUS_NUM, + + /** +@ */ + PM_TOKEN_UPLUS, + + /** unary * */ + PM_TOKEN_USTAR, + + /** unary ** */ + PM_TOKEN_USTAR_STAR, + + /** a separator between words in a list */ + PM_TOKEN_WORDS_SEP, + + /** marker for the point in the file at which the parser should stop */ + PM_TOKEN___END__, + + /** The maximum token value. */ + PM_TOKEN_MAXIMUM, +} pm_token_type_t; + +/** + * This struct represents a token in the Ruby source. We use it to track both + * type and location information. + */ +typedef struct { + /** The type of the token. */ + pm_token_type_t type; + + /** A pointer to the start location of the token in the source. */ + const uint8_t *start; + + /** A pointer to the end location of the token in the source. */ + const uint8_t *end; +} pm_token_t; + +/** + * This represents a range of bytes in the source string to which a node or + * token corresponds. + */ +typedef struct { + /** A pointer to the start location of the range in the source. */ + const uint8_t *start; + + /** A pointer to the end location of the range in the source. */ + const uint8_t *end; +} pm_location_t; + +struct pm_node; + +/** + * A list of nodes in the source, most often used for lists of children. + */ +typedef struct pm_node_list { + /** The number of nodes in the list. */ + size_t size; + + /** The capacity of the list that has been allocated. */ + size_t capacity; + + /** The nodes in the list. */ + struct pm_node **nodes; +} pm_node_list_t; + +/** + * This enum represents every type of node in the Ruby syntax tree. + */ +enum pm_node_type { + /** AliasGlobalVariableNode */ + PM_ALIAS_GLOBAL_VARIABLE_NODE = 1, + + /** AliasMethodNode */ + PM_ALIAS_METHOD_NODE = 2, + + /** AlternationPatternNode */ + PM_ALTERNATION_PATTERN_NODE = 3, + + /** AndNode */ + PM_AND_NODE = 4, + + /** ArgumentsNode */ + PM_ARGUMENTS_NODE = 5, + + /** ArrayNode */ + PM_ARRAY_NODE = 6, + + /** ArrayPatternNode */ + PM_ARRAY_PATTERN_NODE = 7, + + /** AssocNode */ + PM_ASSOC_NODE = 8, + + /** AssocSplatNode */ + PM_ASSOC_SPLAT_NODE = 9, + + /** BackReferenceReadNode */ + PM_BACK_REFERENCE_READ_NODE = 10, + + /** BeginNode */ + PM_BEGIN_NODE = 11, + + /** BlockArgumentNode */ + PM_BLOCK_ARGUMENT_NODE = 12, + + /** BlockLocalVariableNode */ + PM_BLOCK_LOCAL_VARIABLE_NODE = 13, + + /** BlockNode */ + PM_BLOCK_NODE = 14, + + /** BlockParameterNode */ + PM_BLOCK_PARAMETER_NODE = 15, + + /** BlockParametersNode */ + PM_BLOCK_PARAMETERS_NODE = 16, + + /** BreakNode */ + PM_BREAK_NODE = 17, + + /** CallAndWriteNode */ + PM_CALL_AND_WRITE_NODE = 18, + + /** CallNode */ + PM_CALL_NODE = 19, + + /** CallOperatorWriteNode */ + PM_CALL_OPERATOR_WRITE_NODE = 20, + + /** CallOrWriteNode */ + PM_CALL_OR_WRITE_NODE = 21, + + /** CallTargetNode */ + PM_CALL_TARGET_NODE = 22, + + /** CapturePatternNode */ + PM_CAPTURE_PATTERN_NODE = 23, + + /** CaseMatchNode */ + PM_CASE_MATCH_NODE = 24, + + /** CaseNode */ + PM_CASE_NODE = 25, + + /** ClassNode */ + PM_CLASS_NODE = 26, + + /** ClassVariableAndWriteNode */ + PM_CLASS_VARIABLE_AND_WRITE_NODE = 27, + + /** ClassVariableOperatorWriteNode */ + PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE = 28, + + /** ClassVariableOrWriteNode */ + PM_CLASS_VARIABLE_OR_WRITE_NODE = 29, + + /** ClassVariableReadNode */ + PM_CLASS_VARIABLE_READ_NODE = 30, + + /** ClassVariableTargetNode */ + PM_CLASS_VARIABLE_TARGET_NODE = 31, + + /** ClassVariableWriteNode */ + PM_CLASS_VARIABLE_WRITE_NODE = 32, + + /** ConstantAndWriteNode */ + PM_CONSTANT_AND_WRITE_NODE = 33, + + /** ConstantOperatorWriteNode */ + PM_CONSTANT_OPERATOR_WRITE_NODE = 34, + + /** ConstantOrWriteNode */ + PM_CONSTANT_OR_WRITE_NODE = 35, + + /** ConstantPathAndWriteNode */ + PM_CONSTANT_PATH_AND_WRITE_NODE = 36, + + /** ConstantPathNode */ + PM_CONSTANT_PATH_NODE = 37, + + /** ConstantPathOperatorWriteNode */ + PM_CONSTANT_PATH_OPERATOR_WRITE_NODE = 38, + + /** ConstantPathOrWriteNode */ + PM_CONSTANT_PATH_OR_WRITE_NODE = 39, + + /** ConstantPathTargetNode */ + PM_CONSTANT_PATH_TARGET_NODE = 40, + + /** ConstantPathWriteNode */ + PM_CONSTANT_PATH_WRITE_NODE = 41, + + /** ConstantReadNode */ + PM_CONSTANT_READ_NODE = 42, + + /** ConstantTargetNode */ + PM_CONSTANT_TARGET_NODE = 43, + + /** ConstantWriteNode */ + PM_CONSTANT_WRITE_NODE = 44, + + /** DefNode */ + PM_DEF_NODE = 45, + + /** DefinedNode */ + PM_DEFINED_NODE = 46, + + /** ElseNode */ + PM_ELSE_NODE = 47, + + /** EmbeddedStatementsNode */ + PM_EMBEDDED_STATEMENTS_NODE = 48, + + /** EmbeddedVariableNode */ + PM_EMBEDDED_VARIABLE_NODE = 49, + + /** EnsureNode */ + PM_ENSURE_NODE = 50, + + /** FalseNode */ + PM_FALSE_NODE = 51, + + /** FindPatternNode */ + PM_FIND_PATTERN_NODE = 52, + + /** FlipFlopNode */ + PM_FLIP_FLOP_NODE = 53, + + /** FloatNode */ + PM_FLOAT_NODE = 54, + + /** ForNode */ + PM_FOR_NODE = 55, + + /** ForwardingArgumentsNode */ + PM_FORWARDING_ARGUMENTS_NODE = 56, + + /** ForwardingParameterNode */ + PM_FORWARDING_PARAMETER_NODE = 57, + + /** ForwardingSuperNode */ + PM_FORWARDING_SUPER_NODE = 58, + + /** GlobalVariableAndWriteNode */ + PM_GLOBAL_VARIABLE_AND_WRITE_NODE = 59, + + /** GlobalVariableOperatorWriteNode */ + PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE = 60, + + /** GlobalVariableOrWriteNode */ + PM_GLOBAL_VARIABLE_OR_WRITE_NODE = 61, + + /** GlobalVariableReadNode */ + PM_GLOBAL_VARIABLE_READ_NODE = 62, + + /** GlobalVariableTargetNode */ + PM_GLOBAL_VARIABLE_TARGET_NODE = 63, + + /** GlobalVariableWriteNode */ + PM_GLOBAL_VARIABLE_WRITE_NODE = 64, + + /** HashNode */ + PM_HASH_NODE = 65, + + /** HashPatternNode */ + PM_HASH_PATTERN_NODE = 66, + + /** IfNode */ + PM_IF_NODE = 67, + + /** ImaginaryNode */ + PM_IMAGINARY_NODE = 68, + + /** ImplicitNode */ + PM_IMPLICIT_NODE = 69, + + /** ImplicitRestNode */ + PM_IMPLICIT_REST_NODE = 70, + + /** InNode */ + PM_IN_NODE = 71, + + /** IndexAndWriteNode */ + PM_INDEX_AND_WRITE_NODE = 72, + + /** IndexOperatorWriteNode */ + PM_INDEX_OPERATOR_WRITE_NODE = 73, + + /** IndexOrWriteNode */ + PM_INDEX_OR_WRITE_NODE = 74, + + /** IndexTargetNode */ + PM_INDEX_TARGET_NODE = 75, + + /** InstanceVariableAndWriteNode */ + PM_INSTANCE_VARIABLE_AND_WRITE_NODE = 76, + + /** InstanceVariableOperatorWriteNode */ + PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE = 77, + + /** InstanceVariableOrWriteNode */ + PM_INSTANCE_VARIABLE_OR_WRITE_NODE = 78, + + /** InstanceVariableReadNode */ + PM_INSTANCE_VARIABLE_READ_NODE = 79, + + /** InstanceVariableTargetNode */ + PM_INSTANCE_VARIABLE_TARGET_NODE = 80, + + /** InstanceVariableWriteNode */ + PM_INSTANCE_VARIABLE_WRITE_NODE = 81, + + /** IntegerNode */ + PM_INTEGER_NODE = 82, + + /** InterpolatedMatchLastLineNode */ + PM_INTERPOLATED_MATCH_LAST_LINE_NODE = 83, + + /** InterpolatedRegularExpressionNode */ + PM_INTERPOLATED_REGULAR_EXPRESSION_NODE = 84, + + /** InterpolatedStringNode */ + PM_INTERPOLATED_STRING_NODE = 85, + + /** InterpolatedSymbolNode */ + PM_INTERPOLATED_SYMBOL_NODE = 86, + + /** InterpolatedXStringNode */ + PM_INTERPOLATED_X_STRING_NODE = 87, + + /** ItLocalVariableReadNode */ + PM_IT_LOCAL_VARIABLE_READ_NODE = 88, + + /** ItParametersNode */ + PM_IT_PARAMETERS_NODE = 89, + + /** KeywordHashNode */ + PM_KEYWORD_HASH_NODE = 90, + + /** KeywordRestParameterNode */ + PM_KEYWORD_REST_PARAMETER_NODE = 91, + + /** LambdaNode */ + PM_LAMBDA_NODE = 92, + + /** LocalVariableAndWriteNode */ + PM_LOCAL_VARIABLE_AND_WRITE_NODE = 93, + + /** LocalVariableOperatorWriteNode */ + PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE = 94, + + /** LocalVariableOrWriteNode */ + PM_LOCAL_VARIABLE_OR_WRITE_NODE = 95, + + /** LocalVariableReadNode */ + PM_LOCAL_VARIABLE_READ_NODE = 96, + + /** LocalVariableTargetNode */ + PM_LOCAL_VARIABLE_TARGET_NODE = 97, + + /** LocalVariableWriteNode */ + PM_LOCAL_VARIABLE_WRITE_NODE = 98, + + /** MatchLastLineNode */ + PM_MATCH_LAST_LINE_NODE = 99, + + /** MatchPredicateNode */ + PM_MATCH_PREDICATE_NODE = 100, + + /** MatchRequiredNode */ + PM_MATCH_REQUIRED_NODE = 101, + + /** MatchWriteNode */ + PM_MATCH_WRITE_NODE = 102, + + /** MissingNode */ + PM_MISSING_NODE = 103, + + /** ModuleNode */ + PM_MODULE_NODE = 104, + + /** MultiTargetNode */ + PM_MULTI_TARGET_NODE = 105, + + /** MultiWriteNode */ + PM_MULTI_WRITE_NODE = 106, + + /** NextNode */ + PM_NEXT_NODE = 107, + + /** NilNode */ + PM_NIL_NODE = 108, + + /** NoKeywordsParameterNode */ + PM_NO_KEYWORDS_PARAMETER_NODE = 109, + + /** NumberedParametersNode */ + PM_NUMBERED_PARAMETERS_NODE = 110, + + /** NumberedReferenceReadNode */ + PM_NUMBERED_REFERENCE_READ_NODE = 111, + + /** OptionalKeywordParameterNode */ + PM_OPTIONAL_KEYWORD_PARAMETER_NODE = 112, + + /** OptionalParameterNode */ + PM_OPTIONAL_PARAMETER_NODE = 113, + + /** OrNode */ + PM_OR_NODE = 114, + + /** ParametersNode */ + PM_PARAMETERS_NODE = 115, + + /** ParenthesesNode */ + PM_PARENTHESES_NODE = 116, + + /** PinnedExpressionNode */ + PM_PINNED_EXPRESSION_NODE = 117, + + /** PinnedVariableNode */ + PM_PINNED_VARIABLE_NODE = 118, + + /** PostExecutionNode */ + PM_POST_EXECUTION_NODE = 119, + + /** PreExecutionNode */ + PM_PRE_EXECUTION_NODE = 120, + + /** ProgramNode */ + PM_PROGRAM_NODE = 121, + + /** RangeNode */ + PM_RANGE_NODE = 122, + + /** RationalNode */ + PM_RATIONAL_NODE = 123, + + /** RedoNode */ + PM_REDO_NODE = 124, + + /** RegularExpressionNode */ + PM_REGULAR_EXPRESSION_NODE = 125, + + /** RequiredKeywordParameterNode */ + PM_REQUIRED_KEYWORD_PARAMETER_NODE = 126, + + /** RequiredParameterNode */ + PM_REQUIRED_PARAMETER_NODE = 127, + + /** RescueModifierNode */ + PM_RESCUE_MODIFIER_NODE = 128, + + /** RescueNode */ + PM_RESCUE_NODE = 129, + + /** RestParameterNode */ + PM_REST_PARAMETER_NODE = 130, + + /** RetryNode */ + PM_RETRY_NODE = 131, + + /** ReturnNode */ + PM_RETURN_NODE = 132, + + /** SelfNode */ + PM_SELF_NODE = 133, + + /** ShareableConstantNode */ + PM_SHAREABLE_CONSTANT_NODE = 134, + + /** SingletonClassNode */ + PM_SINGLETON_CLASS_NODE = 135, + + /** SourceEncodingNode */ + PM_SOURCE_ENCODING_NODE = 136, + + /** SourceFileNode */ + PM_SOURCE_FILE_NODE = 137, + + /** SourceLineNode */ + PM_SOURCE_LINE_NODE = 138, + + /** SplatNode */ + PM_SPLAT_NODE = 139, + + /** StatementsNode */ + PM_STATEMENTS_NODE = 140, + + /** StringNode */ + PM_STRING_NODE = 141, + + /** SuperNode */ + PM_SUPER_NODE = 142, + + /** SymbolNode */ + PM_SYMBOL_NODE = 143, + + /** TrueNode */ + PM_TRUE_NODE = 144, + + /** UndefNode */ + PM_UNDEF_NODE = 145, + + /** UnlessNode */ + PM_UNLESS_NODE = 146, + + /** UntilNode */ + PM_UNTIL_NODE = 147, + + /** WhenNode */ + PM_WHEN_NODE = 148, + + /** WhileNode */ + PM_WHILE_NODE = 149, + + /** XStringNode */ + PM_X_STRING_NODE = 150, + + /** YieldNode */ + PM_YIELD_NODE = 151, + + /** A special kind of node used for compilation. */ + PM_SCOPE_NODE +}; + +/** + * This is the type of node embedded in the node struct. We explicitly control + * the size of it here to avoid having the variable-width enum. + */ +typedef uint16_t pm_node_type_t; + +/** + * These are the flags embedded in the node struct. We explicitly control the + * size of it here to avoid having the variable-width enum. + */ +typedef uint16_t pm_node_flags_t; + +/** + * We store the flags enum in every node in the tree. Some flags are common to + * all nodes (the ones listed below). Others are specific to certain node types. + */ +static const pm_node_flags_t PM_NODE_FLAG_NEWLINE = 0x1; +static const pm_node_flags_t PM_NODE_FLAG_STATIC_LITERAL = 0x2; + +/** + * Cast the type to an enum to allow the compiler to provide exhaustiveness + * checking. + */ +#define PM_NODE_TYPE(node) ((enum pm_node_type) (node)->type) + +/** + * Return true if the type of the given node matches the given type. + */ +#define PM_NODE_TYPE_P(node, type) (PM_NODE_TYPE(node) == (type)) + +/** + * Return true if the given flag is set on the given node. + */ +#define PM_NODE_FLAG_P(node, flag) ((((pm_node_t *)(node))->flags & (flag)) != 0) + +/** + * This is the base structure that represents a node in the syntax tree. It is + * embedded into every node type. + */ +typedef struct pm_node { + /** + * This represents the type of the node. It somewhat maps to the nodes that + * existed in the original grammar and ripper, but it's not a 1:1 mapping. + */ + pm_node_type_t type; + + /** + * This represents any flags on the node. Some are common to all nodes, and + * some are specific to the type of node. + */ + pm_node_flags_t flags; + + /** + * The unique identifier for this node, which is deterministic based on the + * source. It is used to identify unique nodes across parses. + */ + uint32_t node_id; + + /** + * This is the location of the node in the source. It's a range of bytes + * containing a start and an end. + */ + pm_location_t location; +} pm_node_t; + +/** + * AliasGlobalVariableNode + * + * Represents the use of the `alias` keyword to alias a global variable. + * + * alias $foo $bar + * ^^^^^^^^^^^^^^^ + * + * Type: ::PM_ALIAS_GLOBAL_VARIABLE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_alias_global_variable_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * AliasGlobalVariableNode#new_name + * + * Represents the new name of the global variable that can be used after aliasing. + * + * alias $foo $bar + * ^^^^ + */ + struct pm_node *new_name; + + /** + * AliasGlobalVariableNode#old_name + * + * Represents the old name of the global variable that can be used before aliasing. + * + * alias $foo $bar + * ^^^^ + */ + struct pm_node *old_name; + + /** + * AliasGlobalVariableNode#keyword_loc + * + * The location of the `alias` keyword. + * + * alias $foo $bar + * ^^^^^ + */ + pm_location_t keyword_loc; +} pm_alias_global_variable_node_t; + +/** + * AliasMethodNode + * + * Represents the use of the `alias` keyword to alias a method. + * + * alias foo bar + * ^^^^^^^^^^^^^ + * + * Type: ::PM_ALIAS_METHOD_NODE + * + * @extends pm_node_t + */ +typedef struct pm_alias_method_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * AliasMethodNode#new_name + * + * Represents the new name of the method that will be aliased. + * + * alias foo bar + * ^^^ + * + * alias :foo :bar + * ^^^^ + * + * alias :"#{foo}" :"#{bar}" + * ^^^^^^^^^ + */ + struct pm_node *new_name; + + /** + * AliasMethodNode#old_name + * + * Represents the old name of the method that will be aliased. + * + * alias foo bar + * ^^^ + * + * alias :foo :bar + * ^^^^ + * + * alias :"#{foo}" :"#{bar}" + * ^^^^^^^^^ + */ + struct pm_node *old_name; + + /** + * AliasMethodNode#keyword_loc + * + * Represents the location of the `alias` keyword. + * + * alias foo bar + * ^^^^^ + */ + pm_location_t keyword_loc; +} pm_alias_method_node_t; + +/** + * AlternationPatternNode + * + * Represents an alternation pattern in pattern matching. + * + * foo => bar | baz + * ^^^^^^^^^ + * + * Type: ::PM_ALTERNATION_PATTERN_NODE + * + * @extends pm_node_t + */ +typedef struct pm_alternation_pattern_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * AlternationPatternNode#left + * + * Represents the left side of the expression. + * + * foo => bar | baz + * ^^^ + */ + struct pm_node *left; + + /** + * AlternationPatternNode#right + * + * Represents the right side of the expression. + * + * foo => bar | baz + * ^^^ + */ + struct pm_node *right; + + /** + * AlternationPatternNode#operator_loc + * + * Represents the alternation operator location. + * + * foo => bar | baz + * ^ + */ + pm_location_t operator_loc; +} pm_alternation_pattern_node_t; + +/** + * AndNode + * + * Represents the use of the `&&` operator or the `and` keyword. + * + * left and right + * ^^^^^^^^^^^^^^ + * + * Type: ::PM_AND_NODE + * + * @extends pm_node_t + */ +typedef struct pm_and_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * AndNode#left + * + * Represents the left side of the expression. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * left and right + * ^^^^ + * + * 1 && 2 + * ^ + */ + struct pm_node *left; + + /** + * AndNode#right + * + * Represents the right side of the expression. + * + * left && right + * ^^^^^ + * + * 1 and 2 + * ^ + */ + struct pm_node *right; + + /** + * AndNode#operator_loc + * + * The location of the `and` keyword or the `&&` operator. + * + * left and right + * ^^^ + */ + pm_location_t operator_loc; +} pm_and_node_t; + +/** + * ArgumentsNode + * + * Represents a set of arguments to a method or a keyword. + * + * return foo, bar, baz + * ^^^^^^^^^^^^^ + * + * Type: ::PM_ARGUMENTS_NODE + + * Flags (#pm_arguments_node_flags): + * * ::PM_ARGUMENTS_NODE_FLAGS_CONTAINS_FORWARDING + * * ::PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORDS + * * ::PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORD_SPLAT + * * ::PM_ARGUMENTS_NODE_FLAGS_CONTAINS_SPLAT + * * ::PM_ARGUMENTS_NODE_FLAGS_CONTAINS_MULTIPLE_SPLATS + * + * @extends pm_node_t + */ +typedef struct pm_arguments_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ArgumentsNode#arguments + * + * The list of arguments, if present. These can be any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * foo(bar, baz) + * ^^^^^^^^ + */ + struct pm_node_list arguments; +} pm_arguments_node_t; + +/** + * ArrayNode + * + * Represents an array literal. This can be a regular array using brackets or a special array using % like %w or %i. + * + * [1, 2, 3] + * ^^^^^^^^^ + * + * Type: ::PM_ARRAY_NODE + + * Flags (#pm_array_node_flags): + * * ::PM_ARRAY_NODE_FLAGS_CONTAINS_SPLAT + * + * @extends pm_node_t + */ +typedef struct pm_array_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ArrayNode#elements + * + * Represent the list of zero or more [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression) within the array. + */ + struct pm_node_list elements; + + /** + * ArrayNode#opening_loc + * + * Represents the optional source location for the opening token. + * + * [1,2,3] # "[" + * %w[foo bar baz] # "%w[" + * %I(apple orange banana) # "%I(" + * foo = 1, 2, 3 # nil + */ + pm_location_t opening_loc; + + /** + * ArrayNode#closing_loc + * + * Represents the optional source location for the closing token. + * + * [1,2,3] # "]" + * %w[foo bar baz] # "]" + * %I(apple orange banana) # ")" + * foo = 1, 2, 3 # nil + */ + pm_location_t closing_loc; +} pm_array_node_t; + +/** + * ArrayPatternNode + * + * Represents an array pattern in pattern matching. + * + * foo in 1, 2 + * ^^^^^^^^^^^ + * + * foo in [1, 2] + * ^^^^^^^^^^^^^ + * + * foo in *bar + * ^^^^^^^^^^^ + * + * foo in Bar[] + * ^^^^^^^^^^^^ + * + * foo in Bar[1, 2, 3] + * ^^^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_ARRAY_PATTERN_NODE + * + * @extends pm_node_t + */ +typedef struct pm_array_pattern_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ArrayPatternNode#constant + */ + struct pm_node *constant; + + /** + * ArrayPatternNode#requireds + * + * Represents the required elements of the array pattern. + * + * foo in [1, 2] + * ^ ^ + */ + struct pm_node_list requireds; + + /** + * ArrayPatternNode#rest + * + * Represents the rest element of the array pattern. + * + * foo in *bar + * ^^^^ + */ + struct pm_node *rest; + + /** + * ArrayPatternNode#posts + * + * Represents the elements after the rest element of the array pattern. + * + * foo in *bar, baz + * ^^^ + */ + struct pm_node_list posts; + + /** + * ArrayPatternNode#opening_loc + * + * Represents the opening location of the array pattern. + * + * foo in [1, 2] + * ^ + */ + pm_location_t opening_loc; + + /** + * ArrayPatternNode#closing_loc + * + * Represents the closing location of the array pattern. + * + * foo in [1, 2] + * ^ + */ + pm_location_t closing_loc; +} pm_array_pattern_node_t; + +/** + * AssocNode + * + * Represents a hash key/value pair. + * + * { a => b } + * ^^^^^^ + * + * Type: ::PM_ASSOC_NODE + * + * @extends pm_node_t + */ +typedef struct pm_assoc_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * AssocNode#key + * + * The key of the association. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * { a: b } + * ^ + * + * { foo => bar } + * ^^^ + * + * { def a; end => 1 } + * ^^^^^^^^^^ + */ + struct pm_node *key; + + /** + * AssocNode#value + * + * The value of the association, if present. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * { foo => bar } + * ^^^ + * + * { x: 1 } + * ^ + */ + struct pm_node *value; + + /** + * AssocNode#operator_loc + * + * The location of the `=>` operator, if present. + * + * { foo => bar } + * ^^ + */ + pm_location_t operator_loc; +} pm_assoc_node_t; + +/** + * AssocSplatNode + * + * Represents a splat in a hash literal. + * + * { **foo } + * ^^^^^ + * + * Type: ::PM_ASSOC_SPLAT_NODE + * + * @extends pm_node_t + */ +typedef struct pm_assoc_splat_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * AssocSplatNode#value + * + * The value to be splatted, if present. Will be missing when keyword rest argument forwarding is used. + * + * { **foo } + * ^^^ + */ + struct pm_node *value; + + /** + * AssocSplatNode#operator_loc + * + * The location of the `**` operator. + * + * { **x } + * ^^ + */ + pm_location_t operator_loc; +} pm_assoc_splat_node_t; + +/** + * BackReferenceReadNode + * + * Represents reading a reference to a field in the previous match. + * + * $' + * ^^ + * + * Type: ::PM_BACK_REFERENCE_READ_NODE + * + * @extends pm_node_t + */ +typedef struct pm_back_reference_read_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * BackReferenceReadNode#name + * + * The name of the back-reference variable, including the leading `$`. + * + * $& # name `:$&` + * + * $+ # name `:$+` + */ + pm_constant_id_t name; +} pm_back_reference_read_node_t; + +/** + * BeginNode + * + * Represents a begin statement. + * + * begin + * foo + * end + * ^^^^^ + * + * Type: ::PM_BEGIN_NODE + * + * @extends pm_node_t + */ +typedef struct pm_begin_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * BeginNode#begin_keyword_loc + * + * Represents the location of the `begin` keyword. + * + * begin x end + * ^^^^^ + */ + pm_location_t begin_keyword_loc; + + /** + * BeginNode#statements + * + * Represents the statements within the begin block. + * + * begin x end + * ^ + */ + struct pm_statements_node *statements; + + /** + * BeginNode#rescue_clause + * + * Represents the rescue clause within the begin block. + * + * begin x; rescue y; end + * ^^^^^^^^ + */ + struct pm_rescue_node *rescue_clause; + + /** + * BeginNode#else_clause + * + * Represents the else clause within the begin block. + * + * begin x; rescue y; else z; end + * ^^^^^^ + */ + struct pm_else_node *else_clause; + + /** + * BeginNode#ensure_clause + * + * Represents the ensure clause within the begin block. + * + * begin x; ensure y; end + * ^^^^^^^^ + */ + struct pm_ensure_node *ensure_clause; + + /** + * BeginNode#end_keyword_loc + * + * Represents the location of the `end` keyword. + * + * begin x end + * ^^^ + */ + pm_location_t end_keyword_loc; +} pm_begin_node_t; + +/** + * BlockArgumentNode + * + * Represents a block argument using `&`. + * + * bar(&args) + * ^^^^^^^^^^ + * + * Type: ::PM_BLOCK_ARGUMENT_NODE + * + * @extends pm_node_t + */ +typedef struct pm_block_argument_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * BlockArgumentNode#expression + * + * The expression that is being passed as a block argument. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * foo(&args) + * ^^^^^ + */ + struct pm_node *expression; + + /** + * BlockArgumentNode#operator_loc + * + * Represents the location of the `&` operator. + * + * foo(&args) + * ^ + */ + pm_location_t operator_loc; +} pm_block_argument_node_t; + +/** + * BlockLocalVariableNode + * + * Represents a block local variable. + * + * a { |; b| } + * ^ + * + * Type: ::PM_BLOCK_LOCAL_VARIABLE_NODE + + * Flags (#pm_parameter_flags): + * * ::PM_PARAMETER_FLAGS_REPEATED_PARAMETER + * + * @extends pm_node_t + */ +typedef struct pm_block_local_variable_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * BlockLocalVariableNode#name + * + * The name of the block local variable. + * + * a { |; b| } # name `:b` + * ^ + */ + pm_constant_id_t name; +} pm_block_local_variable_node_t; + +/** + * BlockNode + * + * Represents a block of ruby code. + * + * [1, 2, 3].each { |i| puts x } + * ^^^^^^^^^^^^^^ + * + * Type: ::PM_BLOCK_NODE + * + * @extends pm_node_t + */ +typedef struct pm_block_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * BlockNode#locals + * + * The local variables declared in the block. + * + * [1, 2, 3].each { |i| puts x } # locals: [:i] + * ^ + */ + pm_constant_id_list_t locals; + + /** + * BlockNode#parameters + * + * The parameters of the block. + * + * [1, 2, 3].each { |i| puts x } + * ^^^ + * [1, 2, 3].each { puts _1 } + * ^^^^^^^^^^^ + * [1, 2, 3].each { puts it } + * ^^^^^^^^^^^ + */ + struct pm_node *parameters; + + /** + * BlockNode#body + * + * The body of the block. + * + * [1, 2, 3].each { |i| puts x } + * ^^^^^^ + */ + struct pm_node *body; + + /** + * BlockNode#opening_loc + * + * Represents the location of the opening `|`. + * + * [1, 2, 3].each { |i| puts x } + * ^ + */ + pm_location_t opening_loc; + + /** + * BlockNode#closing_loc + * + * Represents the location of the closing `|`. + * + * [1, 2, 3].each { |i| puts x } + * ^ + */ + pm_location_t closing_loc; +} pm_block_node_t; + +/** + * BlockParameterNode + * + * Represents a block parameter of a method, block, or lambda definition. + * + * def a(&b) + * ^^ + * end + * + * Type: ::PM_BLOCK_PARAMETER_NODE + + * Flags (#pm_parameter_flags): + * * ::PM_PARAMETER_FLAGS_REPEATED_PARAMETER + * + * @extends pm_node_t + */ +typedef struct pm_block_parameter_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * BlockParameterNode#name + * + * The name of the block parameter. + * + * def a(&b) # name `:b` + * ^ + * end + */ + pm_constant_id_t name; + + /** + * BlockParameterNode#name_loc + * + * Represents the location of the block parameter name. + * + * def a(&b) + * ^ + */ + pm_location_t name_loc; + + /** + * BlockParameterNode#operator_loc + * + * Represents the location of the `&` operator. + * + * def a(&b) + * ^ + * end + */ + pm_location_t operator_loc; +} pm_block_parameter_node_t; + +/** + * BlockParametersNode + * + * Represents a block's parameters declaration. + * + * -> (a, b = 1; local) { } + * ^^^^^^^^^^^^^^^^^ + * + * foo do |a, b = 1; local| + * ^^^^^^^^^^^^^^^^^ + * end + * + * Type: ::PM_BLOCK_PARAMETERS_NODE + * + * @extends pm_node_t + */ +typedef struct pm_block_parameters_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * BlockParametersNode#parameters + * + * Represents the parameters of the block. + * + * -> (a, b = 1; local) { } + * ^^^^^^^^ + * + * foo do |a, b = 1; local| + * ^^^^^^^^ + * end + */ + struct pm_parameters_node *parameters; + + /** + * BlockParametersNode#locals + * + * Represents the local variables of the block. + * + * -> (a, b = 1; local) { } + * ^^^^^ + * + * foo do |a, b = 1; local| + * ^^^^^ + * end + */ + struct pm_node_list locals; + + /** + * BlockParametersNode#opening_loc + * + * Represents the opening location of the block parameters. + * + * -> (a, b = 1; local) { } + * ^ + * + * foo do |a, b = 1; local| + * ^ + * end + */ + pm_location_t opening_loc; + + /** + * BlockParametersNode#closing_loc + * + * Represents the closing location of the block parameters. + * + * -> (a, b = 1; local) { } + * ^ + * + * foo do |a, b = 1; local| + * ^ + * end + */ + pm_location_t closing_loc; +} pm_block_parameters_node_t; + +/** + * BreakNode + * + * Represents the use of the `break` keyword. + * + * break foo + * ^^^^^^^^^ + * + * Type: ::PM_BREAK_NODE + * + * @extends pm_node_t + */ +typedef struct pm_break_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * BreakNode#arguments + * + * The arguments to the break statement, if present. These can be any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * break foo + * ^^^ + */ + struct pm_arguments_node *arguments; + + /** + * BreakNode#keyword_loc + * + * The location of the `break` keyword. + * + * break foo + * ^^^^^ + */ + pm_location_t keyword_loc; +} pm_break_node_t; + +/** + * CallAndWriteNode + * + * Represents the use of the `&&=` operator on a call. + * + * foo.bar &&= value + * ^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_CALL_AND_WRITE_NODE + + * Flags (#pm_call_node_flags): + * * ::PM_CALL_NODE_FLAGS_SAFE_NAVIGATION + * * ::PM_CALL_NODE_FLAGS_VARIABLE_CALL + * * ::PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE + * * ::PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY + * + * @extends pm_node_t + */ +typedef struct pm_call_and_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * CallAndWriteNode#receiver + * + * The object that the method is being called on. This can be either `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * foo.bar &&= value + * ^^^ + */ + struct pm_node *receiver; + + /** + * CallAndWriteNode#call_operator_loc + * + * Represents the location of the call operator. + * + * foo.bar &&= value + * ^ + */ + pm_location_t call_operator_loc; + + /** + * CallAndWriteNode#message_loc + * + * Represents the location of the message. + * + * foo.bar &&= value + * ^^^ + */ + pm_location_t message_loc; + + /** + * CallAndWriteNode#read_name + * + * Represents the name of the method being called. + * + * foo.bar &&= value # read_name `:bar` + * ^^^ + */ + pm_constant_id_t read_name; + + /** + * CallAndWriteNode#write_name + * + * Represents the name of the method being written to. + * + * foo.bar &&= value # write_name `:bar=` + * ^^^ + */ + pm_constant_id_t write_name; + + /** + * CallAndWriteNode#operator_loc + * + * Represents the location of the operator. + * + * foo.bar &&= value + * ^^^ + */ + pm_location_t operator_loc; + + /** + * CallAndWriteNode#value + * + * Represents the value being assigned. + * + * foo.bar &&= value + * ^^^^^ + */ + struct pm_node *value; +} pm_call_and_write_node_t; + +/** + * CallNode + * + * Represents a method call, in all of the various forms that can take. + * + * foo + * ^^^ + * + * foo() + * ^^^^^ + * + * +foo + * ^^^^ + * + * foo + bar + * ^^^^^^^^^ + * + * foo.bar + * ^^^^^^^ + * + * foo&.bar + * ^^^^^^^^ + * + * Type: ::PM_CALL_NODE + + * Flags (#pm_call_node_flags): + * * ::PM_CALL_NODE_FLAGS_SAFE_NAVIGATION + * * ::PM_CALL_NODE_FLAGS_VARIABLE_CALL + * * ::PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE + * * ::PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY + * + * @extends pm_node_t + */ +typedef struct pm_call_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * CallNode#receiver + * + * The object that the method is being called on. This can be either `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * foo.bar + * ^^^ + * + * +foo + * ^^^ + * + * foo + bar + * ^^^ + */ + struct pm_node *receiver; + + /** + * CallNode#call_operator_loc + * + * Represents the location of the call operator. + * + * foo.bar + * ^ + * + * foo&.bar + * ^^ + */ + pm_location_t call_operator_loc; + + /** + * CallNode#name + * + * Represents the name of the method being called. + * + * foo.bar # name `:foo` + * ^^^ + */ + pm_constant_id_t name; + + /** + * CallNode#message_loc + * + * Represents the location of the message. + * + * foo.bar + * ^^^ + */ + pm_location_t message_loc; + + /** + * CallNode#opening_loc + * + * Represents the location of the left parenthesis. + * foo(bar) + * ^ + */ + pm_location_t opening_loc; + + /** + * CallNode#arguments + * + * Represents the arguments to the method call. These can be any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * foo(bar) + * ^^^ + */ + struct pm_arguments_node *arguments; + + /** + * CallNode#closing_loc + * + * Represents the location of the right parenthesis. + * + * foo(bar) + * ^ + */ + pm_location_t closing_loc; + + /** + * CallNode#block + * + * Represents the block that is being passed to the method. + * + * foo { |a| a } + * ^^^^^^^^^ + */ + struct pm_node *block; +} pm_call_node_t; + +/** + * CallOperatorWriteNode + * + * Represents the use of an assignment operator on a call. + * + * foo.bar += baz + * ^^^^^^^^^^^^^^ + * + * Type: ::PM_CALL_OPERATOR_WRITE_NODE + + * Flags (#pm_call_node_flags): + * * ::PM_CALL_NODE_FLAGS_SAFE_NAVIGATION + * * ::PM_CALL_NODE_FLAGS_VARIABLE_CALL + * * ::PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE + * * ::PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY + * + * @extends pm_node_t + */ +typedef struct pm_call_operator_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * CallOperatorWriteNode#receiver + * + * The object that the method is being called on. This can be either `nil` or any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * foo.bar += value + * ^^^ + */ + struct pm_node *receiver; + + /** + * CallOperatorWriteNode#call_operator_loc + * + * Represents the location of the call operator. + * + * foo.bar += value + * ^ + */ + pm_location_t call_operator_loc; + + /** + * CallOperatorWriteNode#message_loc + * + * Represents the location of the message. + * + * foo.bar += value + * ^^^ + */ + pm_location_t message_loc; + + /** + * CallOperatorWriteNode#read_name + * + * Represents the name of the method being called. + * + * foo.bar += value # read_name `:bar` + * ^^^ + */ + pm_constant_id_t read_name; + + /** + * CallOperatorWriteNode#write_name + * + * Represents the name of the method being written to. + * + * foo.bar += value # write_name `:bar=` + * ^^^ + */ + pm_constant_id_t write_name; + + /** + * CallOperatorWriteNode#binary_operator + * + * Represents the binary operator being used. + * + * foo.bar += value # binary_operator `:+` + * ^ + */ + pm_constant_id_t binary_operator; + + /** + * CallOperatorWriteNode#binary_operator_loc + * + * Represents the location of the binary operator. + * + * foo.bar += value + * ^^ + */ + pm_location_t binary_operator_loc; + + /** + * CallOperatorWriteNode#value + * + * Represents the value being assigned. + * + * foo.bar += value + * ^^^^^ + */ + struct pm_node *value; +} pm_call_operator_write_node_t; + +/** + * CallOrWriteNode + * + * Represents the use of the `||=` operator on a call. + * + * foo.bar ||= value + * ^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_CALL_OR_WRITE_NODE + + * Flags (#pm_call_node_flags): + * * ::PM_CALL_NODE_FLAGS_SAFE_NAVIGATION + * * ::PM_CALL_NODE_FLAGS_VARIABLE_CALL + * * ::PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE + * * ::PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY + * + * @extends pm_node_t + */ +typedef struct pm_call_or_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * CallOrWriteNode#receiver + * + * The object that the method is being called on. This can be either `nil` or any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * foo.bar ||= value + * ^^^ + */ + struct pm_node *receiver; + + /** + * CallOrWriteNode#call_operator_loc + * + * Represents the location of the call operator. + * + * foo.bar ||= value + * ^ + */ + pm_location_t call_operator_loc; + + /** + * CallOrWriteNode#message_loc + * + * Represents the location of the message. + * + * foo.bar ||= value + * ^^^ + */ + pm_location_t message_loc; + + /** + * CallOrWriteNode#read_name + * + * Represents the name of the method being called. + * + * foo.bar ||= value # read_name `:bar` + * ^^^ + */ + pm_constant_id_t read_name; + + /** + * CallOrWriteNode#write_name + * + * Represents the name of the method being written to. + * + * foo.bar ||= value # write_name `:bar=` + * ^^^ + */ + pm_constant_id_t write_name; + + /** + * CallOrWriteNode#operator_loc + * + * Represents the location of the operator. + * + * foo.bar ||= value + * ^^^ + */ + pm_location_t operator_loc; + + /** + * CallOrWriteNode#value + * + * Represents the value being assigned. + * + * foo.bar ||= value + * ^^^^^ + */ + struct pm_node *value; +} pm_call_or_write_node_t; + +/** + * CallTargetNode + * + * Represents assigning to a method call. + * + * foo.bar, = 1 + * ^^^^^^^ + * + * begin + * rescue => foo.bar + * ^^^^^^^ + * end + * + * for foo.bar in baz do end + * ^^^^^^^ + * + * Type: ::PM_CALL_TARGET_NODE + + * Flags (#pm_call_node_flags): + * * ::PM_CALL_NODE_FLAGS_SAFE_NAVIGATION + * * ::PM_CALL_NODE_FLAGS_VARIABLE_CALL + * * ::PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE + * * ::PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY + * + * @extends pm_node_t + */ +typedef struct pm_call_target_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * CallTargetNode#receiver + * + * The object that the method is being called on. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * foo.bar = 1 + * ^^^ + */ + struct pm_node *receiver; + + /** + * CallTargetNode#call_operator_loc + * + * Represents the location of the call operator. + * + * foo.bar = 1 + * ^ + */ + pm_location_t call_operator_loc; + + /** + * CallTargetNode#name + * + * Represents the name of the method being called. + * + * foo.bar = 1 # name `:foo` + * ^^^ + */ + pm_constant_id_t name; + + /** + * CallTargetNode#message_loc + * + * Represents the location of the message. + * + * foo.bar = 1 + * ^^^ + */ + pm_location_t message_loc; +} pm_call_target_node_t; + +/** + * CapturePatternNode + * + * Represents assigning to a local variable in pattern matching. + * + * foo => [bar => baz] + * ^^^^^^^^^^^^ + * + * Type: ::PM_CAPTURE_PATTERN_NODE + * + * @extends pm_node_t + */ +typedef struct pm_capture_pattern_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * CapturePatternNode#value + * + * Represents the value to capture. + * + * foo => bar + * ^^^ + */ + struct pm_node *value; + + /** + * CapturePatternNode#target + * + * Represents the target of the capture. + * + * foo => bar + * ^^^ + */ + struct pm_local_variable_target_node *target; + + /** + * CapturePatternNode#operator_loc + * + * Represents the location of the `=>` operator. + * + * foo => bar + * ^^ + */ + pm_location_t operator_loc; +} pm_capture_pattern_node_t; + +/** + * CaseMatchNode + * + * Represents the use of a case statement for pattern matching. + * + * case true + * in false + * end + * ^^^^^^^^^ + * + * Type: ::PM_CASE_MATCH_NODE + * + * @extends pm_node_t + */ +typedef struct pm_case_match_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * CaseMatchNode#predicate + * + * Represents the predicate of the case match. This can be either `nil` or any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * case true; in false; end + * ^^^^ + */ + struct pm_node *predicate; + + /** + * CaseMatchNode#conditions + * + * Represents the conditions of the case match. + * + * case true; in false; end + * ^^^^^^^^ + */ + struct pm_node_list conditions; + + /** + * CaseMatchNode#else_clause + * + * Represents the else clause of the case match. + * + * case true; in false; else; end + * ^^^^ + */ + struct pm_else_node *else_clause; + + /** + * CaseMatchNode#case_keyword_loc + * + * Represents the location of the `case` keyword. + * + * case true; in false; end + * ^^^^ + */ + pm_location_t case_keyword_loc; + + /** + * CaseMatchNode#end_keyword_loc + * + * Represents the location of the `end` keyword. + * + * case true; in false; end + * ^^^ + */ + pm_location_t end_keyword_loc; +} pm_case_match_node_t; + +/** + * CaseNode + * + * Represents the use of a case statement. + * + * case true + * when false + * end + * ^^^^^^^^^^ + * + * Type: ::PM_CASE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_case_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * CaseNode#predicate + * + * Represents the predicate of the case statement. This can be either `nil` or any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * case true; when false; end + * ^^^^ + */ + struct pm_node *predicate; + + /** + * CaseNode#conditions + * + * Represents the conditions of the case statement. + * + * case true; when false; end + * ^^^^^^^^^^ + */ + struct pm_node_list conditions; + + /** + * CaseNode#else_clause + * + * Represents the else clause of the case statement. + * + * case true; when false; else; end + * ^^^^ + */ + struct pm_else_node *else_clause; + + /** + * CaseNode#case_keyword_loc + * + * Represents the location of the `case` keyword. + * + * case true; when false; end + * ^^^^ + */ + pm_location_t case_keyword_loc; + + /** + * CaseNode#end_keyword_loc + * + * Represents the location of the `end` keyword. + * + * case true; when false; end + * ^^^ + */ + pm_location_t end_keyword_loc; +} pm_case_node_t; + +/** + * ClassNode + * + * Represents a class declaration involving the `class` keyword. + * + * class Foo end + * ^^^^^^^^^^^^^ + * + * Type: ::PM_CLASS_NODE + * + * @extends pm_node_t + */ +typedef struct pm_class_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ClassNode#locals + */ + pm_constant_id_list_t locals; + + /** + * ClassNode#class_keyword_loc + */ + pm_location_t class_keyword_loc; + + /** + * ClassNode#constant_path + */ + struct pm_node *constant_path; + + /** + * ClassNode#inheritance_operator_loc + */ + pm_location_t inheritance_operator_loc; + + /** + * ClassNode#superclass + */ + struct pm_node *superclass; + + /** + * ClassNode#body + */ + struct pm_node *body; + + /** + * ClassNode#end_keyword_loc + */ + pm_location_t end_keyword_loc; + + /** + * ClassNode#name + */ + pm_constant_id_t name; +} pm_class_node_t; + +/** + * ClassVariableAndWriteNode + * + * Represents the use of the `&&=` operator for assignment to a class variable. + * + * @@target &&= value + * ^^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_CLASS_VARIABLE_AND_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_class_variable_and_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ClassVariableAndWriteNode#name + * + * The name of the class variable, which is a `@@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). + * + * @@target &&= value # name `:@@target` + * ^^^^^^^^ + */ + pm_constant_id_t name; + + /** + * ClassVariableAndWriteNode#name_loc + * + * Represents the location of the variable name. + * + * @@target &&= value + * ^^^^^^^^ + */ + pm_location_t name_loc; + + /** + * ClassVariableAndWriteNode#operator_loc + * + * Represents the location of the `&&=` operator. + * + * @@target &&= value + * ^^^ + */ + pm_location_t operator_loc; + + /** + * ClassVariableAndWriteNode#value + * + * Represents the value being assigned. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * @@target &&= value + * ^^^^^ + */ + struct pm_node *value; +} pm_class_variable_and_write_node_t; + +/** + * ClassVariableOperatorWriteNode + * + * Represents assigning to a class variable using an operator that isn't `=`. + * + * @@target += value + * ^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_class_variable_operator_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ClassVariableOperatorWriteNode#name + */ + pm_constant_id_t name; + + /** + * ClassVariableOperatorWriteNode#name_loc + */ + pm_location_t name_loc; + + /** + * ClassVariableOperatorWriteNode#binary_operator_loc + */ + pm_location_t binary_operator_loc; + + /** + * ClassVariableOperatorWriteNode#value + */ + struct pm_node *value; + + /** + * ClassVariableOperatorWriteNode#binary_operator + */ + pm_constant_id_t binary_operator; +} pm_class_variable_operator_write_node_t; + +/** + * ClassVariableOrWriteNode + * + * Represents the use of the `||=` operator for assignment to a class variable. + * + * @@target ||= value + * ^^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_CLASS_VARIABLE_OR_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_class_variable_or_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ClassVariableOrWriteNode#name + */ + pm_constant_id_t name; + + /** + * ClassVariableOrWriteNode#name_loc + */ + pm_location_t name_loc; + + /** + * ClassVariableOrWriteNode#operator_loc + */ + pm_location_t operator_loc; + + /** + * ClassVariableOrWriteNode#value + */ + struct pm_node *value; +} pm_class_variable_or_write_node_t; + +/** + * ClassVariableReadNode + * + * Represents referencing a class variable. + * + * @@foo + * ^^^^^ + * + * Type: ::PM_CLASS_VARIABLE_READ_NODE + * + * @extends pm_node_t + */ +typedef struct pm_class_variable_read_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ClassVariableReadNode#name + * + * The name of the class variable, which is a `@@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). + * + * @@abc # name `:@@abc` + * + * @@_test # name `:@@_test` + */ + pm_constant_id_t name; +} pm_class_variable_read_node_t; + +/** + * ClassVariableTargetNode + * + * Represents writing to a class variable in a context that doesn't have an explicit value. + * + * @@foo, @@bar = baz + * ^^^^^ ^^^^^ + * + * Type: ::PM_CLASS_VARIABLE_TARGET_NODE + * + * @extends pm_node_t + */ +typedef struct pm_class_variable_target_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ClassVariableTargetNode#name + */ + pm_constant_id_t name; +} pm_class_variable_target_node_t; + +/** + * ClassVariableWriteNode + * + * Represents writing to a class variable. + * + * @@foo = 1 + * ^^^^^^^^^ + * + * Type: ::PM_CLASS_VARIABLE_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_class_variable_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ClassVariableWriteNode#name + * + * The name of the class variable, which is a `@@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). + * + * @@abc = 123 # name `@@abc` + * + * @@_test = :test # name `@@_test` + */ + pm_constant_id_t name; + + /** + * ClassVariableWriteNode#name_loc + * + * The location of the variable name. + * + * @@foo = :bar + * ^^^^^ + */ + pm_location_t name_loc; + + /** + * ClassVariableWriteNode#value + * + * The value to write to the class variable. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * @@foo = :bar + * ^^^^ + * + * @@_xyz = 123 + * ^^^ + */ + struct pm_node *value; + + /** + * ClassVariableWriteNode#operator_loc + * + * The location of the `=` operator. + * + * @@foo = :bar + * ^ + */ + pm_location_t operator_loc; +} pm_class_variable_write_node_t; + +/** + * ConstantAndWriteNode + * + * Represents the use of the `&&=` operator for assignment to a constant. + * + * Target &&= value + * ^^^^^^^^^^^^^^^^ + * + * Type: ::PM_CONSTANT_AND_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_constant_and_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ConstantAndWriteNode#name + */ + pm_constant_id_t name; + + /** + * ConstantAndWriteNode#name_loc + */ + pm_location_t name_loc; + + /** + * ConstantAndWriteNode#operator_loc + */ + pm_location_t operator_loc; + + /** + * ConstantAndWriteNode#value + */ + struct pm_node *value; +} pm_constant_and_write_node_t; + +/** + * ConstantOperatorWriteNode + * + * Represents assigning to a constant using an operator that isn't `=`. + * + * Target += value + * ^^^^^^^^^^^^^^^ + * + * Type: ::PM_CONSTANT_OPERATOR_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_constant_operator_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ConstantOperatorWriteNode#name + */ + pm_constant_id_t name; + + /** + * ConstantOperatorWriteNode#name_loc + */ + pm_location_t name_loc; + + /** + * ConstantOperatorWriteNode#binary_operator_loc + */ + pm_location_t binary_operator_loc; + + /** + * ConstantOperatorWriteNode#value + */ + struct pm_node *value; + + /** + * ConstantOperatorWriteNode#binary_operator + */ + pm_constant_id_t binary_operator; +} pm_constant_operator_write_node_t; + +/** + * ConstantOrWriteNode + * + * Represents the use of the `||=` operator for assignment to a constant. + * + * Target ||= value + * ^^^^^^^^^^^^^^^^ + * + * Type: ::PM_CONSTANT_OR_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_constant_or_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ConstantOrWriteNode#name + */ + pm_constant_id_t name; + + /** + * ConstantOrWriteNode#name_loc + */ + pm_location_t name_loc; + + /** + * ConstantOrWriteNode#operator_loc + */ + pm_location_t operator_loc; + + /** + * ConstantOrWriteNode#value + */ + struct pm_node *value; +} pm_constant_or_write_node_t; + +/** + * ConstantPathAndWriteNode + * + * Represents the use of the `&&=` operator for assignment to a constant path. + * + * Parent::Child &&= value + * ^^^^^^^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_CONSTANT_PATH_AND_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_constant_path_and_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ConstantPathAndWriteNode#target + */ + struct pm_constant_path_node *target; + + /** + * ConstantPathAndWriteNode#operator_loc + */ + pm_location_t operator_loc; + + /** + * ConstantPathAndWriteNode#value + */ + struct pm_node *value; +} pm_constant_path_and_write_node_t; + +/** + * ConstantPathNode + * + * Represents accessing a constant through a path of `::` operators. + * + * Foo::Bar + * ^^^^^^^^ + * + * Type: ::PM_CONSTANT_PATH_NODE + * + * @extends pm_node_t + */ +typedef struct pm_constant_path_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ConstantPathNode#parent + * + * The left-hand node of the path, if present. It can be `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). It will be `nil` when the constant lookup is at the root of the module tree. + * + * Foo::Bar + * ^^^ + * + * self::Test + * ^^^^ + * + * a.b::C + * ^^^ + */ + struct pm_node *parent; + + /** + * ConstantPathNode#name + * + * The name of the constant being accessed. This could be `nil` in the event of a syntax error. + */ + pm_constant_id_t name; + + /** + * ConstantPathNode#delimiter_loc + * + * The location of the `::` delimiter. + * + * ::Foo + * ^^ + * + * One::Two + * ^^ + */ + pm_location_t delimiter_loc; + + /** + * ConstantPathNode#name_loc + * + * The location of the name of the constant. + * + * ::Foo + * ^^^ + * + * One::Two + * ^^^ + */ + pm_location_t name_loc; +} pm_constant_path_node_t; + +/** + * ConstantPathOperatorWriteNode + * + * Represents assigning to a constant path using an operator that isn't `=`. + * + * Parent::Child += value + * ^^^^^^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_CONSTANT_PATH_OPERATOR_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_constant_path_operator_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ConstantPathOperatorWriteNode#target + */ + struct pm_constant_path_node *target; + + /** + * ConstantPathOperatorWriteNode#binary_operator_loc + */ + pm_location_t binary_operator_loc; + + /** + * ConstantPathOperatorWriteNode#value + */ + struct pm_node *value; + + /** + * ConstantPathOperatorWriteNode#binary_operator + */ + pm_constant_id_t binary_operator; +} pm_constant_path_operator_write_node_t; + +/** + * ConstantPathOrWriteNode + * + * Represents the use of the `||=` operator for assignment to a constant path. + * + * Parent::Child ||= value + * ^^^^^^^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_CONSTANT_PATH_OR_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_constant_path_or_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ConstantPathOrWriteNode#target + */ + struct pm_constant_path_node *target; + + /** + * ConstantPathOrWriteNode#operator_loc + */ + pm_location_t operator_loc; + + /** + * ConstantPathOrWriteNode#value + */ + struct pm_node *value; +} pm_constant_path_or_write_node_t; + +/** + * ConstantPathTargetNode + * + * Represents writing to a constant path in a context that doesn't have an explicit value. + * + * Foo::Foo, Bar::Bar = baz + * ^^^^^^^^ ^^^^^^^^ + * + * Type: ::PM_CONSTANT_PATH_TARGET_NODE + * + * @extends pm_node_t + */ +typedef struct pm_constant_path_target_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ConstantPathTargetNode#parent + */ + struct pm_node *parent; + + /** + * ConstantPathTargetNode#name + */ + pm_constant_id_t name; + + /** + * ConstantPathTargetNode#delimiter_loc + */ + pm_location_t delimiter_loc; + + /** + * ConstantPathTargetNode#name_loc + */ + pm_location_t name_loc; +} pm_constant_path_target_node_t; + +/** + * ConstantPathWriteNode + * + * Represents writing to a constant path. + * + * ::Foo = 1 + * ^^^^^^^^^ + * + * Foo::Bar = 1 + * ^^^^^^^^^^^^ + * + * ::Foo::Bar = 1 + * ^^^^^^^^^^^^^^ + * + * Type: ::PM_CONSTANT_PATH_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_constant_path_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ConstantPathWriteNode#target + * + * A node representing the constant path being written to. + * + * Foo::Bar = 1 + * ^^^^^^^^ + * + * ::Foo = :abc + * ^^^^^ + */ + struct pm_constant_path_node *target; + + /** + * ConstantPathWriteNode#operator_loc + * + * The location of the `=` operator. + * + * ::ABC = 123 + * ^ + */ + pm_location_t operator_loc; + + /** + * ConstantPathWriteNode#value + * + * The value to write to the constant path. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * FOO::BAR = :abc + * ^^^^ + */ + struct pm_node *value; +} pm_constant_path_write_node_t; + +/** + * ConstantReadNode + * + * Represents referencing a constant. + * + * Foo + * ^^^ + * + * Type: ::PM_CONSTANT_READ_NODE + * + * @extends pm_node_t + */ +typedef struct pm_constant_read_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ConstantReadNode#name + * + * The name of the [constant](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#constants). + * + * X # name `:X` + * + * SOME_CONSTANT # name `:SOME_CONSTANT` + */ + pm_constant_id_t name; +} pm_constant_read_node_t; + +/** + * ConstantTargetNode + * + * Represents writing to a constant in a context that doesn't have an explicit value. + * + * Foo, Bar = baz + * ^^^ ^^^ + * + * Type: ::PM_CONSTANT_TARGET_NODE + * + * @extends pm_node_t + */ +typedef struct pm_constant_target_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ConstantTargetNode#name + */ + pm_constant_id_t name; +} pm_constant_target_node_t; + +/** + * ConstantWriteNode + * + * Represents writing to a constant. + * + * Foo = 1 + * ^^^^^^^ + * + * Type: ::PM_CONSTANT_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_constant_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ConstantWriteNode#name + * + * The name of the [constant](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#constants). + * + * Foo = :bar # name `:Foo` + * + * XYZ = 1 # name `:XYZ` + */ + pm_constant_id_t name; + + /** + * ConstantWriteNode#name_loc + * + * The location of the constant name. + * + * FOO = 1 + * ^^^ + */ + pm_location_t name_loc; + + /** + * ConstantWriteNode#value + * + * The value to write to the constant. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * FOO = :bar + * ^^^^ + * + * MyClass = Class.new + * ^^^^^^^^^ + */ + struct pm_node *value; + + /** + * ConstantWriteNode#operator_loc + * + * The location of the `=` operator. + * + * FOO = :bar + * ^ + */ + pm_location_t operator_loc; +} pm_constant_write_node_t; + +/** + * DefNode + * + * Represents a method definition. + * + * def method + * end + * ^^^^^^^^^^ + * + * Type: ::PM_DEF_NODE + * + * @extends pm_node_t + */ +typedef struct pm_def_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * DefNode#name + */ + pm_constant_id_t name; + + /** + * DefNode#name_loc + */ + pm_location_t name_loc; + + /** + * DefNode#receiver + */ + struct pm_node *receiver; + + /** + * DefNode#parameters + */ + struct pm_parameters_node *parameters; + + /** + * DefNode#body + */ + struct pm_node *body; + + /** + * DefNode#locals + */ + pm_constant_id_list_t locals; + + /** + * DefNode#def_keyword_loc + */ + pm_location_t def_keyword_loc; + + /** + * DefNode#operator_loc + */ + pm_location_t operator_loc; + + /** + * DefNode#lparen_loc + */ + pm_location_t lparen_loc; + + /** + * DefNode#rparen_loc + */ + pm_location_t rparen_loc; + + /** + * DefNode#equal_loc + */ + pm_location_t equal_loc; + + /** + * DefNode#end_keyword_loc + */ + pm_location_t end_keyword_loc; +} pm_def_node_t; + +/** + * DefinedNode + * + * Represents the use of the `defined?` keyword. + * + * defined?(a) + * ^^^^^^^^^^^ + * + * Type: ::PM_DEFINED_NODE + * + * @extends pm_node_t + */ +typedef struct pm_defined_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * DefinedNode#lparen_loc + */ + pm_location_t lparen_loc; + + /** + * DefinedNode#value + */ + struct pm_node *value; + + /** + * DefinedNode#rparen_loc + */ + pm_location_t rparen_loc; + + /** + * DefinedNode#keyword_loc + */ + pm_location_t keyword_loc; +} pm_defined_node_t; + +/** + * ElseNode + * + * Represents an `else` clause in a `case`, `if`, or `unless` statement. + * + * if a then b else c end + * ^^^^^^^^^^ + * + * Type: ::PM_ELSE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_else_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ElseNode#else_keyword_loc + */ + pm_location_t else_keyword_loc; + + /** + * ElseNode#statements + */ + struct pm_statements_node *statements; + + /** + * ElseNode#end_keyword_loc + */ + pm_location_t end_keyword_loc; +} pm_else_node_t; + +/** + * EmbeddedStatementsNode + * + * Represents an interpolated set of statements. + * + * "foo #{bar}" + * ^^^^^^ + * + * Type: ::PM_EMBEDDED_STATEMENTS_NODE + * + * @extends pm_node_t + */ +typedef struct pm_embedded_statements_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * EmbeddedStatementsNode#opening_loc + */ + pm_location_t opening_loc; + + /** + * EmbeddedStatementsNode#statements + */ + struct pm_statements_node *statements; + + /** + * EmbeddedStatementsNode#closing_loc + */ + pm_location_t closing_loc; +} pm_embedded_statements_node_t; + +/** + * EmbeddedVariableNode + * + * Represents an interpolated variable. + * + * "foo #@bar" + * ^^^^^ + * + * Type: ::PM_EMBEDDED_VARIABLE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_embedded_variable_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * EmbeddedVariableNode#operator_loc + */ + pm_location_t operator_loc; + + /** + * EmbeddedVariableNode#variable + */ + struct pm_node *variable; +} pm_embedded_variable_node_t; + +/** + * EnsureNode + * + * Represents an `ensure` clause in a `begin` statement. + * + * begin + * foo + * ensure + * ^^^^^^ + * bar + * end + * + * Type: ::PM_ENSURE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_ensure_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * EnsureNode#ensure_keyword_loc + */ + pm_location_t ensure_keyword_loc; + + /** + * EnsureNode#statements + */ + struct pm_statements_node *statements; + + /** + * EnsureNode#end_keyword_loc + */ + pm_location_t end_keyword_loc; +} pm_ensure_node_t; + +/** + * FalseNode + * + * Represents the use of the literal `false` keyword. + * + * false + * ^^^^^ + * + * Type: ::PM_FALSE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_false_node { + /** The embedded base node. */ + pm_node_t base; + +} pm_false_node_t; + +/** + * FindPatternNode + * + * Represents a find pattern in pattern matching. + * + * foo in *bar, baz, *qux + * ^^^^^^^^^^^^^^^ + * + * foo in [*bar, baz, *qux] + * ^^^^^^^^^^^^^^^^^ + * + * foo in Foo(*bar, baz, *qux) + * ^^^^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_FIND_PATTERN_NODE + * + * @extends pm_node_t + */ +typedef struct pm_find_pattern_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * FindPatternNode#constant + */ + struct pm_node *constant; + + /** + * FindPatternNode#left + */ + struct pm_splat_node *left; + + /** + * FindPatternNode#requireds + */ + struct pm_node_list requireds; + + /** + * FindPatternNode#right + */ + struct pm_node *right; + + /** + * FindPatternNode#opening_loc + */ + pm_location_t opening_loc; + + /** + * FindPatternNode#closing_loc + */ + pm_location_t closing_loc; +} pm_find_pattern_node_t; + +/** + * FlipFlopNode + * + * Represents the use of the `..` or `...` operators to create flip flops. + * + * baz if foo .. bar + * ^^^^^^^^^^ + * + * Type: ::PM_FLIP_FLOP_NODE + + * Flags (#pm_range_flags): + * * ::PM_RANGE_FLAGS_EXCLUDE_END + * + * @extends pm_node_t + */ +typedef struct pm_flip_flop_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * FlipFlopNode#left + */ + struct pm_node *left; + + /** + * FlipFlopNode#right + */ + struct pm_node *right; + + /** + * FlipFlopNode#operator_loc + */ + pm_location_t operator_loc; +} pm_flip_flop_node_t; + +/** + * FloatNode + * + * Represents a floating point number literal. + * + * 1.0 + * ^^^ + * + * Type: ::PM_FLOAT_NODE + * + * @extends pm_node_t + */ +typedef struct pm_float_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * FloatNode#value + * + * The value of the floating point number as a Float. + */ + double value; +} pm_float_node_t; + +/** + * ForNode + * + * Represents the use of the `for` keyword. + * + * for i in a end + * ^^^^^^^^^^^^^^ + * + * Type: ::PM_FOR_NODE + * + * @extends pm_node_t + */ +typedef struct pm_for_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ForNode#index + * + * The index expression for `for` loops. + * + * for i in a end + * ^ + */ + struct pm_node *index; + + /** + * ForNode#collection + * + * The collection to iterate over. + * + * for i in a end + * ^ + */ + struct pm_node *collection; + + /** + * ForNode#statements + * + * Represents the body of statements to execute for each iteration of the loop. + * + * for i in a + * foo(i) + * ^^^^^^ + * end + */ + struct pm_statements_node *statements; + + /** + * ForNode#for_keyword_loc + * + * The location of the `for` keyword. + * + * for i in a end + * ^^^ + */ + pm_location_t for_keyword_loc; + + /** + * ForNode#in_keyword_loc + * + * The location of the `in` keyword. + * + * for i in a end + * ^^ + */ + pm_location_t in_keyword_loc; + + /** + * ForNode#do_keyword_loc + * + * The location of the `do` keyword, if present. + * + * for i in a do end + * ^^ + */ + pm_location_t do_keyword_loc; + + /** + * ForNode#end_keyword_loc + * + * The location of the `end` keyword. + * + * for i in a end + * ^^^ + */ + pm_location_t end_keyword_loc; +} pm_for_node_t; + +/** + * ForwardingArgumentsNode + * + * Represents forwarding all arguments to this method to another method. + * + * def foo(...) + * bar(...) + * ^^^ + * end + * + * Type: ::PM_FORWARDING_ARGUMENTS_NODE + * + * @extends pm_node_t + */ +typedef struct pm_forwarding_arguments_node { + /** The embedded base node. */ + pm_node_t base; + +} pm_forwarding_arguments_node_t; + +/** + * ForwardingParameterNode + * + * Represents the use of the forwarding parameter in a method, block, or lambda declaration. + * + * def foo(...) + * ^^^ + * end + * + * Type: ::PM_FORWARDING_PARAMETER_NODE + * + * @extends pm_node_t + */ +typedef struct pm_forwarding_parameter_node { + /** The embedded base node. */ + pm_node_t base; + +} pm_forwarding_parameter_node_t; + +/** + * ForwardingSuperNode + * + * Represents the use of the `super` keyword without parentheses or arguments. + * + * super + * ^^^^^ + * + * Type: ::PM_FORWARDING_SUPER_NODE + * + * @extends pm_node_t + */ +typedef struct pm_forwarding_super_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ForwardingSuperNode#block + */ + struct pm_block_node *block; +} pm_forwarding_super_node_t; + +/** + * GlobalVariableAndWriteNode + * + * Represents the use of the `&&=` operator for assignment to a global variable. + * + * $target &&= value + * ^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_GLOBAL_VARIABLE_AND_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_global_variable_and_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * GlobalVariableAndWriteNode#name + */ + pm_constant_id_t name; + + /** + * GlobalVariableAndWriteNode#name_loc + */ + pm_location_t name_loc; + + /** + * GlobalVariableAndWriteNode#operator_loc + */ + pm_location_t operator_loc; + + /** + * GlobalVariableAndWriteNode#value + */ + struct pm_node *value; +} pm_global_variable_and_write_node_t; + +/** + * GlobalVariableOperatorWriteNode + * + * Represents assigning to a global variable using an operator that isn't `=`. + * + * $target += value + * ^^^^^^^^^^^^^^^^ + * + * Type: ::PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_global_variable_operator_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * GlobalVariableOperatorWriteNode#name + */ + pm_constant_id_t name; + + /** + * GlobalVariableOperatorWriteNode#name_loc + */ + pm_location_t name_loc; + + /** + * GlobalVariableOperatorWriteNode#binary_operator_loc + */ + pm_location_t binary_operator_loc; + + /** + * GlobalVariableOperatorWriteNode#value + */ + struct pm_node *value; + + /** + * GlobalVariableOperatorWriteNode#binary_operator + */ + pm_constant_id_t binary_operator; +} pm_global_variable_operator_write_node_t; + +/** + * GlobalVariableOrWriteNode + * + * Represents the use of the `||=` operator for assignment to a global variable. + * + * $target ||= value + * ^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_GLOBAL_VARIABLE_OR_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_global_variable_or_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * GlobalVariableOrWriteNode#name + */ + pm_constant_id_t name; + + /** + * GlobalVariableOrWriteNode#name_loc + */ + pm_location_t name_loc; + + /** + * GlobalVariableOrWriteNode#operator_loc + */ + pm_location_t operator_loc; + + /** + * GlobalVariableOrWriteNode#value + */ + struct pm_node *value; +} pm_global_variable_or_write_node_t; + +/** + * GlobalVariableReadNode + * + * Represents referencing a global variable. + * + * $foo + * ^^^^ + * + * Type: ::PM_GLOBAL_VARIABLE_READ_NODE + * + * @extends pm_node_t + */ +typedef struct pm_global_variable_read_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * GlobalVariableReadNode#name + * + * The name of the global variable, which is a `$` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifier). Alternatively, it can be one of the special global variables designated by a symbol. + * + * $foo # name `:$foo` + * + * $_Test # name `:$_Test` + */ + pm_constant_id_t name; +} pm_global_variable_read_node_t; + +/** + * GlobalVariableTargetNode + * + * Represents writing to a global variable in a context that doesn't have an explicit value. + * + * $foo, $bar = baz + * ^^^^ ^^^^ + * + * Type: ::PM_GLOBAL_VARIABLE_TARGET_NODE + * + * @extends pm_node_t + */ +typedef struct pm_global_variable_target_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * GlobalVariableTargetNode#name + */ + pm_constant_id_t name; +} pm_global_variable_target_node_t; + +/** + * GlobalVariableWriteNode + * + * Represents writing to a global variable. + * + * $foo = 1 + * ^^^^^^^^ + * + * Type: ::PM_GLOBAL_VARIABLE_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_global_variable_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * GlobalVariableWriteNode#name + * + * The name of the global variable, which is a `$` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifier). Alternatively, it can be one of the special global variables designated by a symbol. + * + * $foo = :bar # name `:$foo` + * + * $_Test = 123 # name `:$_Test` + */ + pm_constant_id_t name; + + /** + * GlobalVariableWriteNode#name_loc + * + * The location of the global variable's name. + * + * $foo = :bar + * ^^^^ + */ + pm_location_t name_loc; + + /** + * GlobalVariableWriteNode#value + * + * The value to write to the global variable. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * $foo = :bar + * ^^^^ + * + * $-xyz = 123 + * ^^^ + */ + struct pm_node *value; + + /** + * GlobalVariableWriteNode#operator_loc + * + * The location of the `=` operator. + * + * $foo = :bar + * ^ + */ + pm_location_t operator_loc; +} pm_global_variable_write_node_t; + +/** + * HashNode + * + * Represents a hash literal. + * + * { a => b } + * ^^^^^^^^^^ + * + * Type: ::PM_HASH_NODE + * + * @extends pm_node_t + */ +typedef struct pm_hash_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * HashNode#opening_loc + * + * The location of the opening brace. + * + * { a => b } + * ^ + */ + pm_location_t opening_loc; + + /** + * HashNode#elements + * + * The elements of the hash. These can be either `AssocNode`s or `AssocSplatNode`s. + * + * { a: b } + * ^^^^ + * + * { **foo } + * ^^^^^ + */ + struct pm_node_list elements; + + /** + * HashNode#closing_loc + * + * The location of the closing brace. + * + * { a => b } + * ^ + */ + pm_location_t closing_loc; +} pm_hash_node_t; + +/** + * HashPatternNode + * + * Represents a hash pattern in pattern matching. + * + * foo => { a: 1, b: 2 } + * ^^^^^^^^^^^^^^ + * + * foo => { a: 1, b: 2, **c } + * ^^^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_HASH_PATTERN_NODE + * + * @extends pm_node_t + */ +typedef struct pm_hash_pattern_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * HashPatternNode#constant + */ + struct pm_node *constant; + + /** + * HashPatternNode#elements + */ + struct pm_node_list elements; + + /** + * HashPatternNode#rest + */ + struct pm_node *rest; + + /** + * HashPatternNode#opening_loc + */ + pm_location_t opening_loc; + + /** + * HashPatternNode#closing_loc + */ + pm_location_t closing_loc; +} pm_hash_pattern_node_t; + +/** + * IfNode + * + * Represents the use of the `if` keyword, either in the block form or the modifier form, or a ternary expression. + * + * bar if foo + * ^^^^^^^^^^ + * + * if foo then bar end + * ^^^^^^^^^^^^^^^^^^^ + * + * foo ? bar : baz + * ^^^^^^^^^^^^^^^ + * + * Type: ::PM_IF_NODE + * + * @extends pm_node_t + */ +typedef struct pm_if_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * IfNode#if_keyword_loc + * + * The location of the `if` keyword if present. + * + * bar if foo + * ^^ + * + * The `if_keyword_loc` field will be `nil` when the `IfNode` represents a ternary expression. + */ + pm_location_t if_keyword_loc; + + /** + * IfNode#predicate + * + * The node for the condition the `IfNode` is testing. + * + * if foo + * ^^^ + * bar + * end + * + * bar if foo + * ^^^ + * + * foo ? bar : baz + * ^^^ + */ + struct pm_node *predicate; + + /** + * IfNode#then_keyword_loc + * + * The location of the `then` keyword (if present) or the `?` in a ternary expression, `nil` otherwise. + * + * if foo then bar end + * ^^^^ + * + * a ? b : c + * ^ + */ + pm_location_t then_keyword_loc; + + /** + * IfNode#statements + * + * Represents the body of statements that will be executed when the predicate is evaluated as truthy. Will be `nil` when no body is provided. + * + * if foo + * bar + * ^^^ + * baz + * ^^^ + * end + */ + struct pm_statements_node *statements; + + /** + * IfNode#subsequent + * + * Represents an `ElseNode` or an `IfNode` when there is an `else` or an `elsif` in the `if` statement. + * + * if foo + * bar + * elsif baz + * ^^^^^^^^^ + * qux + * ^^^ + * end + * ^^^ + * + * if foo then bar else baz end + * ^^^^^^^^^^^^ + */ + struct pm_node *subsequent; + + /** + * IfNode#end_keyword_loc + * + * The location of the `end` keyword if present, `nil` otherwise. + * + * if foo + * bar + * end + * ^^^ + */ + pm_location_t end_keyword_loc; +} pm_if_node_t; + +/** + * ImaginaryNode + * + * Represents an imaginary number literal. + * + * 1.0i + * ^^^^ + * + * Type: ::PM_IMAGINARY_NODE + * + * @extends pm_node_t + */ +typedef struct pm_imaginary_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ImaginaryNode#numeric + */ + struct pm_node *numeric; +} pm_imaginary_node_t; + +/** + * ImplicitNode + * + * Represents a node that is implicitly being added to the tree but doesn't correspond directly to a node in the source. + * + * { foo: } + * ^^^^ + * + * { Foo: } + * ^^^^ + * + * foo in { bar: } + * ^^^^ + * + * Type: ::PM_IMPLICIT_NODE + * + * @extends pm_node_t + */ +typedef struct pm_implicit_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ImplicitNode#value + */ + struct pm_node *value; +} pm_implicit_node_t; + +/** + * ImplicitRestNode + * + * Represents using a trailing comma to indicate an implicit rest parameter. + * + * foo { |bar,| } + * ^ + * + * foo in [bar,] + * ^ + * + * for foo, in bar do end + * ^ + * + * foo, = bar + * ^ + * + * Type: ::PM_IMPLICIT_REST_NODE + * + * @extends pm_node_t + */ +typedef struct pm_implicit_rest_node { + /** The embedded base node. */ + pm_node_t base; + +} pm_implicit_rest_node_t; + +/** + * InNode + * + * Represents the use of the `in` keyword in a case statement. + * + * case a; in b then c end + * ^^^^^^^^^^^ + * + * Type: ::PM_IN_NODE + * + * @extends pm_node_t + */ +typedef struct pm_in_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * InNode#pattern + */ + struct pm_node *pattern; + + /** + * InNode#statements + */ + struct pm_statements_node *statements; + + /** + * InNode#in_loc + */ + pm_location_t in_loc; + + /** + * InNode#then_loc + */ + pm_location_t then_loc; +} pm_in_node_t; + +/** + * IndexAndWriteNode + * + * Represents the use of the `&&=` operator on a call to the `[]` method. + * + * foo.bar[baz] &&= value + * ^^^^^^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_INDEX_AND_WRITE_NODE + + * Flags (#pm_call_node_flags): + * * ::PM_CALL_NODE_FLAGS_SAFE_NAVIGATION + * * ::PM_CALL_NODE_FLAGS_VARIABLE_CALL + * * ::PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE + * * ::PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY + * + * @extends pm_node_t + */ +typedef struct pm_index_and_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * IndexAndWriteNode#receiver + */ + struct pm_node *receiver; + + /** + * IndexAndWriteNode#call_operator_loc + */ + pm_location_t call_operator_loc; + + /** + * IndexAndWriteNode#opening_loc + */ + pm_location_t opening_loc; + + /** + * IndexAndWriteNode#arguments + */ + struct pm_arguments_node *arguments; + + /** + * IndexAndWriteNode#closing_loc + */ + pm_location_t closing_loc; + + /** + * IndexAndWriteNode#block + */ + struct pm_block_argument_node *block; + + /** + * IndexAndWriteNode#operator_loc + */ + pm_location_t operator_loc; + + /** + * IndexAndWriteNode#value + */ + struct pm_node *value; +} pm_index_and_write_node_t; + +/** + * IndexOperatorWriteNode + * + * Represents the use of an assignment operator on a call to `[]`. + * + * foo.bar[baz] += value + * ^^^^^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_INDEX_OPERATOR_WRITE_NODE + + * Flags (#pm_call_node_flags): + * * ::PM_CALL_NODE_FLAGS_SAFE_NAVIGATION + * * ::PM_CALL_NODE_FLAGS_VARIABLE_CALL + * * ::PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE + * * ::PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY + * + * @extends pm_node_t + */ +typedef struct pm_index_operator_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * IndexOperatorWriteNode#receiver + */ + struct pm_node *receiver; + + /** + * IndexOperatorWriteNode#call_operator_loc + */ + pm_location_t call_operator_loc; + + /** + * IndexOperatorWriteNode#opening_loc + */ + pm_location_t opening_loc; + + /** + * IndexOperatorWriteNode#arguments + */ + struct pm_arguments_node *arguments; + + /** + * IndexOperatorWriteNode#closing_loc + */ + pm_location_t closing_loc; + + /** + * IndexOperatorWriteNode#block + */ + struct pm_block_argument_node *block; + + /** + * IndexOperatorWriteNode#binary_operator + */ + pm_constant_id_t binary_operator; + + /** + * IndexOperatorWriteNode#binary_operator_loc + */ + pm_location_t binary_operator_loc; + + /** + * IndexOperatorWriteNode#value + */ + struct pm_node *value; +} pm_index_operator_write_node_t; + +/** + * IndexOrWriteNode + * + * Represents the use of the `||=` operator on a call to `[]`. + * + * foo.bar[baz] ||= value + * ^^^^^^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_INDEX_OR_WRITE_NODE + + * Flags (#pm_call_node_flags): + * * ::PM_CALL_NODE_FLAGS_SAFE_NAVIGATION + * * ::PM_CALL_NODE_FLAGS_VARIABLE_CALL + * * ::PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE + * * ::PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY + * + * @extends pm_node_t + */ +typedef struct pm_index_or_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * IndexOrWriteNode#receiver + */ + struct pm_node *receiver; + + /** + * IndexOrWriteNode#call_operator_loc + */ + pm_location_t call_operator_loc; + + /** + * IndexOrWriteNode#opening_loc + */ + pm_location_t opening_loc; + + /** + * IndexOrWriteNode#arguments + */ + struct pm_arguments_node *arguments; + + /** + * IndexOrWriteNode#closing_loc + */ + pm_location_t closing_loc; + + /** + * IndexOrWriteNode#block + */ + struct pm_block_argument_node *block; + + /** + * IndexOrWriteNode#operator_loc + */ + pm_location_t operator_loc; + + /** + * IndexOrWriteNode#value + */ + struct pm_node *value; +} pm_index_or_write_node_t; + +/** + * IndexTargetNode + * + * Represents assigning to an index. + * + * foo[bar], = 1 + * ^^^^^^^^ + * + * begin + * rescue => foo[bar] + * ^^^^^^^^ + * end + * + * for foo[bar] in baz do end + * ^^^^^^^^ + * + * Type: ::PM_INDEX_TARGET_NODE + + * Flags (#pm_call_node_flags): + * * ::PM_CALL_NODE_FLAGS_SAFE_NAVIGATION + * * ::PM_CALL_NODE_FLAGS_VARIABLE_CALL + * * ::PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE + * * ::PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY + * + * @extends pm_node_t + */ +typedef struct pm_index_target_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * IndexTargetNode#receiver + */ + struct pm_node *receiver; + + /** + * IndexTargetNode#opening_loc + */ + pm_location_t opening_loc; + + /** + * IndexTargetNode#arguments + */ + struct pm_arguments_node *arguments; + + /** + * IndexTargetNode#closing_loc + */ + pm_location_t closing_loc; + + /** + * IndexTargetNode#block + */ + struct pm_block_argument_node *block; +} pm_index_target_node_t; + +/** + * InstanceVariableAndWriteNode + * + * Represents the use of the `&&=` operator for assignment to an instance variable. + * + * @target &&= value + * ^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_INSTANCE_VARIABLE_AND_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_instance_variable_and_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * InstanceVariableAndWriteNode#name + */ + pm_constant_id_t name; + + /** + * InstanceVariableAndWriteNode#name_loc + */ + pm_location_t name_loc; + + /** + * InstanceVariableAndWriteNode#operator_loc + */ + pm_location_t operator_loc; + + /** + * InstanceVariableAndWriteNode#value + */ + struct pm_node *value; +} pm_instance_variable_and_write_node_t; + +/** + * InstanceVariableOperatorWriteNode + * + * Represents assigning to an instance variable using an operator that isn't `=`. + * + * @target += value + * ^^^^^^^^^^^^^^^^ + * + * Type: ::PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_instance_variable_operator_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * InstanceVariableOperatorWriteNode#name + */ + pm_constant_id_t name; + + /** + * InstanceVariableOperatorWriteNode#name_loc + */ + pm_location_t name_loc; + + /** + * InstanceVariableOperatorWriteNode#binary_operator_loc + */ + pm_location_t binary_operator_loc; + + /** + * InstanceVariableOperatorWriteNode#value + */ + struct pm_node *value; + + /** + * InstanceVariableOperatorWriteNode#binary_operator + */ + pm_constant_id_t binary_operator; +} pm_instance_variable_operator_write_node_t; + +/** + * InstanceVariableOrWriteNode + * + * Represents the use of the `||=` operator for assignment to an instance variable. + * + * @target ||= value + * ^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_INSTANCE_VARIABLE_OR_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_instance_variable_or_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * InstanceVariableOrWriteNode#name + */ + pm_constant_id_t name; + + /** + * InstanceVariableOrWriteNode#name_loc + */ + pm_location_t name_loc; + + /** + * InstanceVariableOrWriteNode#operator_loc + */ + pm_location_t operator_loc; + + /** + * InstanceVariableOrWriteNode#value + */ + struct pm_node *value; +} pm_instance_variable_or_write_node_t; + +/** + * InstanceVariableReadNode + * + * Represents referencing an instance variable. + * + * @foo + * ^^^^ + * + * Type: ::PM_INSTANCE_VARIABLE_READ_NODE + * + * @extends pm_node_t + */ +typedef struct pm_instance_variable_read_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * InstanceVariableReadNode#name + * + * The name of the instance variable, which is a `@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). + * + * @x # name `:@x` + * + * @_test # name `:@_test` + */ + pm_constant_id_t name; +} pm_instance_variable_read_node_t; + +/** + * InstanceVariableTargetNode + * + * Represents writing to an instance variable in a context that doesn't have an explicit value. + * + * @foo, @bar = baz + * ^^^^ ^^^^ + * + * Type: ::PM_INSTANCE_VARIABLE_TARGET_NODE + * + * @extends pm_node_t + */ +typedef struct pm_instance_variable_target_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * InstanceVariableTargetNode#name + */ + pm_constant_id_t name; +} pm_instance_variable_target_node_t; + +/** + * InstanceVariableWriteNode + * + * Represents writing to an instance variable. + * + * @foo = 1 + * ^^^^^^^^ + * + * Type: ::PM_INSTANCE_VARIABLE_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_instance_variable_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * InstanceVariableWriteNode#name + * + * The name of the instance variable, which is a `@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). + * + * @x = :y # name `:@x` + * + * @_foo = "bar" # name `@_foo` + */ + pm_constant_id_t name; + + /** + * InstanceVariableWriteNode#name_loc + * + * The location of the variable name. + * + * @_x = 1 + * ^^^ + */ + pm_location_t name_loc; + + /** + * InstanceVariableWriteNode#value + * + * The value to write to the instance variable. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * @foo = :bar + * ^^^^ + * + * @_x = 1234 + * ^^^^ + */ + struct pm_node *value; + + /** + * InstanceVariableWriteNode#operator_loc + * + * The location of the `=` operator. + * + * @x = y + * ^ + */ + pm_location_t operator_loc; +} pm_instance_variable_write_node_t; + +/** + * IntegerNode + * + * Represents an integer number literal. + * + * 1 + * ^ + * + * Type: ::PM_INTEGER_NODE + + * Flags (#pm_integer_base_flags): + * * ::PM_INTEGER_BASE_FLAGS_BINARY + * * ::PM_INTEGER_BASE_FLAGS_DECIMAL + * * ::PM_INTEGER_BASE_FLAGS_OCTAL + * * ::PM_INTEGER_BASE_FLAGS_HEXADECIMAL + * + * @extends pm_node_t + */ +typedef struct pm_integer_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * IntegerNode#value + * + * The value of the integer literal as a number. + */ + pm_integer_t value; +} pm_integer_node_t; + +/** + * InterpolatedMatchLastLineNode + * + * Represents a regular expression literal that contains interpolation that is being used in the predicate of a conditional to implicitly match against the last line read by an IO object. + * + * if /foo #{bar} baz/ then end + * ^^^^^^^^^^^^^^^^ + * + * Type: ::PM_INTERPOLATED_MATCH_LAST_LINE_NODE + + * Flags (#pm_regular_expression_flags): + * * ::PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE + * * ::PM_REGULAR_EXPRESSION_FLAGS_EXTENDED + * * ::PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE + * * ::PM_REGULAR_EXPRESSION_FLAGS_ONCE + * * ::PM_REGULAR_EXPRESSION_FLAGS_EUC_JP + * * ::PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT + * * ::PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J + * * ::PM_REGULAR_EXPRESSION_FLAGS_UTF_8 + * * ::PM_REGULAR_EXPRESSION_FLAGS_FORCED_UTF8_ENCODING + * * ::PM_REGULAR_EXPRESSION_FLAGS_FORCED_BINARY_ENCODING + * * ::PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING + * + * @extends pm_node_t + */ +typedef struct pm_interpolated_match_last_line_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * InterpolatedMatchLastLineNode#opening_loc + */ + pm_location_t opening_loc; + + /** + * InterpolatedMatchLastLineNode#parts + */ + struct pm_node_list parts; + + /** + * InterpolatedMatchLastLineNode#closing_loc + */ + pm_location_t closing_loc; +} pm_interpolated_match_last_line_node_t; + +/** + * InterpolatedRegularExpressionNode + * + * Represents a regular expression literal that contains interpolation. + * + * /foo #{bar} baz/ + * ^^^^^^^^^^^^^^^^ + * + * Type: ::PM_INTERPOLATED_REGULAR_EXPRESSION_NODE + + * Flags (#pm_regular_expression_flags): + * * ::PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE + * * ::PM_REGULAR_EXPRESSION_FLAGS_EXTENDED + * * ::PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE + * * ::PM_REGULAR_EXPRESSION_FLAGS_ONCE + * * ::PM_REGULAR_EXPRESSION_FLAGS_EUC_JP + * * ::PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT + * * ::PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J + * * ::PM_REGULAR_EXPRESSION_FLAGS_UTF_8 + * * ::PM_REGULAR_EXPRESSION_FLAGS_FORCED_UTF8_ENCODING + * * ::PM_REGULAR_EXPRESSION_FLAGS_FORCED_BINARY_ENCODING + * * ::PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING + * + * @extends pm_node_t + */ +typedef struct pm_interpolated_regular_expression_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * InterpolatedRegularExpressionNode#opening_loc + */ + pm_location_t opening_loc; + + /** + * InterpolatedRegularExpressionNode#parts + */ + struct pm_node_list parts; + + /** + * InterpolatedRegularExpressionNode#closing_loc + */ + pm_location_t closing_loc; +} pm_interpolated_regular_expression_node_t; + +/** + * InterpolatedStringNode + * + * Represents a string literal that contains interpolation. + * + * "foo #{bar} baz" + * ^^^^^^^^^^^^^^^^ + * + * Type: ::PM_INTERPOLATED_STRING_NODE + + * Flags (#pm_interpolated_string_node_flags): + * * ::PM_INTERPOLATED_STRING_NODE_FLAGS_FROZEN + * * ::PM_INTERPOLATED_STRING_NODE_FLAGS_MUTABLE + * + * @extends pm_node_t + */ +typedef struct pm_interpolated_string_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * InterpolatedStringNode#opening_loc + */ + pm_location_t opening_loc; + + /** + * InterpolatedStringNode#parts + */ + struct pm_node_list parts; + + /** + * InterpolatedStringNode#closing_loc + */ + pm_location_t closing_loc; +} pm_interpolated_string_node_t; + +/** + * InterpolatedSymbolNode + * + * Represents a symbol literal that contains interpolation. + * + * :"foo #{bar} baz" + * ^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_INTERPOLATED_SYMBOL_NODE + * + * @extends pm_node_t + */ +typedef struct pm_interpolated_symbol_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * InterpolatedSymbolNode#opening_loc + */ + pm_location_t opening_loc; + + /** + * InterpolatedSymbolNode#parts + */ + struct pm_node_list parts; + + /** + * InterpolatedSymbolNode#closing_loc + */ + pm_location_t closing_loc; +} pm_interpolated_symbol_node_t; + +/** + * InterpolatedXStringNode + * + * Represents an xstring literal that contains interpolation. + * + * `foo #{bar} baz` + * ^^^^^^^^^^^^^^^^ + * + * Type: ::PM_INTERPOLATED_X_STRING_NODE + * + * @extends pm_node_t + */ +typedef struct pm_interpolated_x_string_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * InterpolatedXStringNode#opening_loc + */ + pm_location_t opening_loc; + + /** + * InterpolatedXStringNode#parts + */ + struct pm_node_list parts; + + /** + * InterpolatedXStringNode#closing_loc + */ + pm_location_t closing_loc; +} pm_interpolated_x_string_node_t; + +/** + * ItLocalVariableReadNode + * + * Represents reading from the implicit `it` local variable. + * + * -> { it } + * ^^ + * + * Type: ::PM_IT_LOCAL_VARIABLE_READ_NODE + * + * @extends pm_node_t + */ +typedef struct pm_it_local_variable_read_node { + /** The embedded base node. */ + pm_node_t base; + +} pm_it_local_variable_read_node_t; + +/** + * ItParametersNode + * + * Represents an implicit set of parameters through the use of the `it` keyword within a block or lambda. + * + * -> { it + it } + * ^^^^^^^^^^^^^^ + * + * Type: ::PM_IT_PARAMETERS_NODE + * + * @extends pm_node_t + */ +typedef struct pm_it_parameters_node { + /** The embedded base node. */ + pm_node_t base; + +} pm_it_parameters_node_t; + +/** + * KeywordHashNode + * + * Represents a hash literal without opening and closing braces. + * + * foo(a: b) + * ^^^^ + * + * Type: ::PM_KEYWORD_HASH_NODE + + * Flags (#pm_keyword_hash_node_flags): + * * ::PM_KEYWORD_HASH_NODE_FLAGS_SYMBOL_KEYS + * + * @extends pm_node_t + */ +typedef struct pm_keyword_hash_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * KeywordHashNode#elements + */ + struct pm_node_list elements; +} pm_keyword_hash_node_t; + +/** + * KeywordRestParameterNode + * + * Represents a keyword rest parameter to a method, block, or lambda definition. + * + * def a(**b) + * ^^^ + * end + * + * Type: ::PM_KEYWORD_REST_PARAMETER_NODE + + * Flags (#pm_parameter_flags): + * * ::PM_PARAMETER_FLAGS_REPEATED_PARAMETER + * + * @extends pm_node_t + */ +typedef struct pm_keyword_rest_parameter_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * KeywordRestParameterNode#name + */ + pm_constant_id_t name; + + /** + * KeywordRestParameterNode#name_loc + */ + pm_location_t name_loc; + + /** + * KeywordRestParameterNode#operator_loc + */ + pm_location_t operator_loc; +} pm_keyword_rest_parameter_node_t; + +/** + * LambdaNode + * + * Represents using a lambda literal (not the lambda method call). + * + * ->(value) { value * 2 } + * ^^^^^^^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_LAMBDA_NODE + * + * @extends pm_node_t + */ +typedef struct pm_lambda_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * LambdaNode#locals + */ + pm_constant_id_list_t locals; + + /** + * LambdaNode#operator_loc + */ + pm_location_t operator_loc; + + /** + * LambdaNode#opening_loc + */ + pm_location_t opening_loc; + + /** + * LambdaNode#closing_loc + */ + pm_location_t closing_loc; + + /** + * LambdaNode#parameters + */ + struct pm_node *parameters; + + /** + * LambdaNode#body + */ + struct pm_node *body; +} pm_lambda_node_t; + +/** + * LocalVariableAndWriteNode + * + * Represents the use of the `&&=` operator for assignment to a local variable. + * + * target &&= value + * ^^^^^^^^^^^^^^^^ + * + * Type: ::PM_LOCAL_VARIABLE_AND_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_local_variable_and_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * LocalVariableAndWriteNode#name_loc + */ + pm_location_t name_loc; + + /** + * LocalVariableAndWriteNode#operator_loc + */ + pm_location_t operator_loc; + + /** + * LocalVariableAndWriteNode#value + */ + struct pm_node *value; + + /** + * LocalVariableAndWriteNode#name + */ + pm_constant_id_t name; + + /** + * LocalVariableAndWriteNode#depth + */ + uint32_t depth; +} pm_local_variable_and_write_node_t; + +/** + * LocalVariableOperatorWriteNode + * + * Represents assigning to a local variable using an operator that isn't `=`. + * + * target += value + * ^^^^^^^^^^^^^^^ + * + * Type: ::PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_local_variable_operator_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * LocalVariableOperatorWriteNode#name_loc + */ + pm_location_t name_loc; + + /** + * LocalVariableOperatorWriteNode#binary_operator_loc + */ + pm_location_t binary_operator_loc; + + /** + * LocalVariableOperatorWriteNode#value + */ + struct pm_node *value; + + /** + * LocalVariableOperatorWriteNode#name + */ + pm_constant_id_t name; + + /** + * LocalVariableOperatorWriteNode#binary_operator + */ + pm_constant_id_t binary_operator; + + /** + * LocalVariableOperatorWriteNode#depth + */ + uint32_t depth; +} pm_local_variable_operator_write_node_t; + +/** + * LocalVariableOrWriteNode + * + * Represents the use of the `||=` operator for assignment to a local variable. + * + * target ||= value + * ^^^^^^^^^^^^^^^^ + * + * Type: ::PM_LOCAL_VARIABLE_OR_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_local_variable_or_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * LocalVariableOrWriteNode#name_loc + */ + pm_location_t name_loc; + + /** + * LocalVariableOrWriteNode#operator_loc + */ + pm_location_t operator_loc; + + /** + * LocalVariableOrWriteNode#value + */ + struct pm_node *value; + + /** + * LocalVariableOrWriteNode#name + */ + pm_constant_id_t name; + + /** + * LocalVariableOrWriteNode#depth + */ + uint32_t depth; +} pm_local_variable_or_write_node_t; + +/** + * LocalVariableReadNode + * + * Represents reading a local variable. Note that this requires that a local variable of the same name has already been written to in the same scope, otherwise it is parsed as a method call. + * + * foo + * ^^^ + * + * Type: ::PM_LOCAL_VARIABLE_READ_NODE + * + * @extends pm_node_t + */ +typedef struct pm_local_variable_read_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * LocalVariableReadNode#name + * + * The name of the local variable, which is an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). + * + * x # name `:x` + * + * _Test # name `:_Test` + * + * Note that this can also be an underscore followed by a number for the default block parameters. + * + * _1 # name `:_1` + */ + pm_constant_id_t name; + + /** + * LocalVariableReadNode#depth + * + * The number of visible scopes that should be searched to find the origin of this local variable. + * + * foo = 1; foo # depth 0 + * + * bar = 2; tap { bar } # depth 1 + * + * The specific rules for calculating the depth may differ from individual Ruby implementations, as they are not specified by the language. For more information, see [the Prism documentation](https://github.com/ruby/prism/blob/main/docs/local_variable_depth.md). + */ + uint32_t depth; +} pm_local_variable_read_node_t; + +/** + * LocalVariableTargetNode + * + * Represents writing to a local variable in a context that doesn't have an explicit value. + * + * foo, bar = baz + * ^^^ ^^^ + * + * Type: ::PM_LOCAL_VARIABLE_TARGET_NODE + * + * @extends pm_node_t + */ +typedef struct pm_local_variable_target_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * LocalVariableTargetNode#name + */ + pm_constant_id_t name; + + /** + * LocalVariableTargetNode#depth + */ + uint32_t depth; +} pm_local_variable_target_node_t; + +/** + * LocalVariableWriteNode + * + * Represents writing to a local variable. + * + * foo = 1 + * ^^^^^^^ + * + * Type: ::PM_LOCAL_VARIABLE_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_local_variable_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * LocalVariableWriteNode#name + * + * The name of the local variable, which is an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). + * + * foo = :bar # name `:foo` + * + * abc = 123 # name `:abc` + */ + pm_constant_id_t name; + + /** + * LocalVariableWriteNode#depth + * + * The number of semantic scopes we have to traverse to find the declaration of this variable. + * + * foo = 1 # depth 0 + * + * tap { foo = 1 } # depth 1 + * + * The specific rules for calculating the depth may differ from individual Ruby implementations, as they are not specified by the language. For more information, see [the Prism documentation](https://github.com/ruby/prism/blob/main/docs/local_variable_depth.md). + */ + uint32_t depth; + + /** + * LocalVariableWriteNode#name_loc + * + * The location of the variable name. + * + * foo = :bar + * ^^^ + */ + pm_location_t name_loc; + + /** + * LocalVariableWriteNode#value + * + * The value to write to the local variable. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * foo = :bar + * ^^^^ + * + * abc = 1234 + * ^^^^ + * + * Note that since the name of a local variable is known before the value is parsed, it is valid for a local variable to appear within the value of its own write. + * + * foo = foo + */ + struct pm_node *value; + + /** + * LocalVariableWriteNode#operator_loc + * + * The location of the `=` operator. + * + * x = :y + * ^ + */ + pm_location_t operator_loc; +} pm_local_variable_write_node_t; + +/** + * MatchLastLineNode + * + * Represents a regular expression literal used in the predicate of a conditional to implicitly match against the last line read by an IO object. + * + * if /foo/i then end + * ^^^^^^ + * + * Type: ::PM_MATCH_LAST_LINE_NODE + + * Flags (#pm_regular_expression_flags): + * * ::PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE + * * ::PM_REGULAR_EXPRESSION_FLAGS_EXTENDED + * * ::PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE + * * ::PM_REGULAR_EXPRESSION_FLAGS_ONCE + * * ::PM_REGULAR_EXPRESSION_FLAGS_EUC_JP + * * ::PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT + * * ::PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J + * * ::PM_REGULAR_EXPRESSION_FLAGS_UTF_8 + * * ::PM_REGULAR_EXPRESSION_FLAGS_FORCED_UTF8_ENCODING + * * ::PM_REGULAR_EXPRESSION_FLAGS_FORCED_BINARY_ENCODING + * * ::PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING + * + * @extends pm_node_t + */ +typedef struct pm_match_last_line_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * MatchLastLineNode#opening_loc + */ + pm_location_t opening_loc; + + /** + * MatchLastLineNode#content_loc + */ + pm_location_t content_loc; + + /** + * MatchLastLineNode#closing_loc + */ + pm_location_t closing_loc; + + /** + * MatchLastLineNode#unescaped + */ + pm_string_t unescaped; +} pm_match_last_line_node_t; + +/** + * MatchPredicateNode + * + * Represents the use of the modifier `in` operator. + * + * foo in bar + * ^^^^^^^^^^ + * + * Type: ::PM_MATCH_PREDICATE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_match_predicate_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * MatchPredicateNode#value + */ + struct pm_node *value; + + /** + * MatchPredicateNode#pattern + */ + struct pm_node *pattern; + + /** + * MatchPredicateNode#operator_loc + */ + pm_location_t operator_loc; +} pm_match_predicate_node_t; + +/** + * MatchRequiredNode + * + * Represents the use of the `=>` operator. + * + * foo => bar + * ^^^^^^^^^^ + * + * Type: ::PM_MATCH_REQUIRED_NODE + * + * @extends pm_node_t + */ +typedef struct pm_match_required_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * MatchRequiredNode#value + */ + struct pm_node *value; + + /** + * MatchRequiredNode#pattern + */ + struct pm_node *pattern; + + /** + * MatchRequiredNode#operator_loc + */ + pm_location_t operator_loc; +} pm_match_required_node_t; + +/** + * MatchWriteNode + * + * Represents writing local variables using a regular expression match with named capture groups. + * + * /(?bar)/ =~ baz + * ^^^^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_MATCH_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_match_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * MatchWriteNode#call + */ + struct pm_call_node *call; + + /** + * MatchWriteNode#targets + */ + struct pm_node_list targets; +} pm_match_write_node_t; + +/** + * MissingNode + * + * Represents a node that is missing from the source and results in a syntax error. + * + * Type: ::PM_MISSING_NODE + * + * @extends pm_node_t + */ +typedef struct pm_missing_node { + /** The embedded base node. */ + pm_node_t base; + +} pm_missing_node_t; + +/** + * ModuleNode + * + * Represents a module declaration involving the `module` keyword. + * + * module Foo end + * ^^^^^^^^^^^^^^ + * + * Type: ::PM_MODULE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_module_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ModuleNode#locals + */ + pm_constant_id_list_t locals; + + /** + * ModuleNode#module_keyword_loc + */ + pm_location_t module_keyword_loc; + + /** + * ModuleNode#constant_path + */ + struct pm_node *constant_path; + + /** + * ModuleNode#body + */ + struct pm_node *body; + + /** + * ModuleNode#end_keyword_loc + */ + pm_location_t end_keyword_loc; + + /** + * ModuleNode#name + */ + pm_constant_id_t name; +} pm_module_node_t; + +/** + * MultiTargetNode + * + * Represents a multi-target expression. + * + * a, (b, c) = 1, 2, 3 + * ^^^^^^ + * + * This can be a part of `MultiWriteNode` as above, or the target of a `for` loop + * + * for a, b in [[1, 2], [3, 4]] + * ^^^^ + * + * Type: ::PM_MULTI_TARGET_NODE + * + * @extends pm_node_t + */ +typedef struct pm_multi_target_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * MultiTargetNode#lefts + * + * Represents the targets expressions before a splat node. + * + * a, (b, c, *) = 1, 2, 3, 4, 5 + * ^^^^ + * + * The splat node can be absent, in that case all target expressions are in the left field. + * + * a, (b, c) = 1, 2, 3, 4, 5 + * ^^^^ + */ + struct pm_node_list lefts; + + /** + * MultiTargetNode#rest + * + * Represents a splat node in the target expression. + * + * a, (b, *c) = 1, 2, 3, 4 + * ^^ + * + * The variable can be empty, this results in a `SplatNode` with a `nil` expression field. + * + * a, (b, *) = 1, 2, 3, 4 + * ^ + * + * If the `*` is omitted, this field will contain an `ImplicitRestNode` + * + * a, (b,) = 1, 2, 3, 4 + * ^ + */ + struct pm_node *rest; + + /** + * MultiTargetNode#rights + * + * Represents the targets expressions after a splat node. + * + * a, (*, b, c) = 1, 2, 3, 4, 5 + * ^^^^ + */ + struct pm_node_list rights; + + /** + * MultiTargetNode#lparen_loc + * + * The location of the opening parenthesis. + * + * a, (b, c) = 1, 2, 3 + * ^ + */ + pm_location_t lparen_loc; + + /** + * MultiTargetNode#rparen_loc + * + * The location of the closing parenthesis. + * + * a, (b, c) = 1, 2, 3 + * ^ + */ + pm_location_t rparen_loc; +} pm_multi_target_node_t; + +/** + * MultiWriteNode + * + * Represents a write to a multi-target expression. + * + * a, b, c = 1, 2, 3 + * ^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_MULTI_WRITE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_multi_write_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * MultiWriteNode#lefts + * + * Represents the targets expressions before a splat node. + * + * a, b, * = 1, 2, 3, 4, 5 + * ^^^^ + * + * The splat node can be absent, in that case all target expressions are in the left field. + * + * a, b, c = 1, 2, 3, 4, 5 + * ^^^^^^^ + */ + struct pm_node_list lefts; + + /** + * MultiWriteNode#rest + * + * Represents a splat node in the target expression. + * + * a, b, *c = 1, 2, 3, 4 + * ^^ + * + * The variable can be empty, this results in a `SplatNode` with a `nil` expression field. + * + * a, b, * = 1, 2, 3, 4 + * ^ + * + * If the `*` is omitted, this field will contain an `ImplicitRestNode` + * + * a, b, = 1, 2, 3, 4 + * ^ + */ + struct pm_node *rest; + + /** + * MultiWriteNode#rights + * + * Represents the targets expressions after a splat node. + * + * a, *, b, c = 1, 2, 3, 4, 5 + * ^^^^ + */ + struct pm_node_list rights; + + /** + * MultiWriteNode#lparen_loc + * + * The location of the opening parenthesis. + * + * (a, b, c) = 1, 2, 3 + * ^ + */ + pm_location_t lparen_loc; + + /** + * MultiWriteNode#rparen_loc + * + * The location of the closing parenthesis. + * + * (a, b, c) = 1, 2, 3 + * ^ + */ + pm_location_t rparen_loc; + + /** + * MultiWriteNode#operator_loc + * + * The location of the operator. + * + * a, b, c = 1, 2, 3 + * ^ + */ + pm_location_t operator_loc; + + /** + * MultiWriteNode#value + * + * The value to write to the targets. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * a, b, c = 1, 2, 3 + * ^^^^^^^ + */ + struct pm_node *value; +} pm_multi_write_node_t; + +/** + * NextNode + * + * Represents the use of the `next` keyword. + * + * next 1 + * ^^^^^^ + * + * Type: ::PM_NEXT_NODE + * + * @extends pm_node_t + */ +typedef struct pm_next_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * NextNode#arguments + */ + struct pm_arguments_node *arguments; + + /** + * NextNode#keyword_loc + */ + pm_location_t keyword_loc; +} pm_next_node_t; + +/** + * NilNode + * + * Represents the use of the `nil` keyword. + * + * nil + * ^^^ + * + * Type: ::PM_NIL_NODE + * + * @extends pm_node_t + */ +typedef struct pm_nil_node { + /** The embedded base node. */ + pm_node_t base; + +} pm_nil_node_t; + +/** + * NoKeywordsParameterNode + * + * Represents the use of `**nil` inside method arguments. + * + * def a(**nil) + * ^^^^^ + * end + * + * Type: ::PM_NO_KEYWORDS_PARAMETER_NODE + * + * @extends pm_node_t + */ +typedef struct pm_no_keywords_parameter_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * NoKeywordsParameterNode#operator_loc + */ + pm_location_t operator_loc; + + /** + * NoKeywordsParameterNode#keyword_loc + */ + pm_location_t keyword_loc; +} pm_no_keywords_parameter_node_t; + +/** + * NumberedParametersNode + * + * Represents an implicit set of parameters through the use of numbered parameters within a block or lambda. + * + * -> { _1 + _2 } + * ^^^^^^^^^^^^^^ + * + * Type: ::PM_NUMBERED_PARAMETERS_NODE + * + * @extends pm_node_t + */ +typedef struct pm_numbered_parameters_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * NumberedParametersNode#maximum + */ + uint8_t maximum; +} pm_numbered_parameters_node_t; + +/** + * NumberedReferenceReadNode + * + * Represents reading a numbered reference to a capture in the previous match. + * + * $1 + * ^^ + * + * Type: ::PM_NUMBERED_REFERENCE_READ_NODE + * + * @extends pm_node_t + */ +typedef struct pm_numbered_reference_read_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * NumberedReferenceReadNode#number + * + * The (1-indexed, from the left) number of the capture group. Numbered references that are too large result in this value being `0`. + * + * $1 # number `1` + * + * $5432 # number `5432` + * + * $4294967296 # number `0` + */ + uint32_t number; +} pm_numbered_reference_read_node_t; + +/** + * OptionalKeywordParameterNode + * + * Represents an optional keyword parameter to a method, block, or lambda definition. + * + * def a(b: 1) + * ^^^^ + * end + * + * Type: ::PM_OPTIONAL_KEYWORD_PARAMETER_NODE + + * Flags (#pm_parameter_flags): + * * ::PM_PARAMETER_FLAGS_REPEATED_PARAMETER + * + * @extends pm_node_t + */ +typedef struct pm_optional_keyword_parameter_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * OptionalKeywordParameterNode#name + */ + pm_constant_id_t name; + + /** + * OptionalKeywordParameterNode#name_loc + */ + pm_location_t name_loc; + + /** + * OptionalKeywordParameterNode#value + */ + struct pm_node *value; +} pm_optional_keyword_parameter_node_t; + +/** + * OptionalParameterNode + * + * Represents an optional parameter to a method, block, or lambda definition. + * + * def a(b = 1) + * ^^^^^ + * end + * + * Type: ::PM_OPTIONAL_PARAMETER_NODE + + * Flags (#pm_parameter_flags): + * * ::PM_PARAMETER_FLAGS_REPEATED_PARAMETER + * + * @extends pm_node_t + */ +typedef struct pm_optional_parameter_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * OptionalParameterNode#name + */ + pm_constant_id_t name; + + /** + * OptionalParameterNode#name_loc + */ + pm_location_t name_loc; + + /** + * OptionalParameterNode#operator_loc + */ + pm_location_t operator_loc; + + /** + * OptionalParameterNode#value + */ + struct pm_node *value; +} pm_optional_parameter_node_t; + +/** + * OrNode + * + * Represents the use of the `||` operator or the `or` keyword. + * + * left or right + * ^^^^^^^^^^^^^ + * + * Type: ::PM_OR_NODE + * + * @extends pm_node_t + */ +typedef struct pm_or_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * OrNode#left + * + * Represents the left side of the expression. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * left or right + * ^^^^ + * + * 1 || 2 + * ^ + */ + struct pm_node *left; + + /** + * OrNode#right + * + * Represents the right side of the expression. + * + * left || right + * ^^^^^ + * + * 1 or 2 + * ^ + */ + struct pm_node *right; + + /** + * OrNode#operator_loc + * + * The location of the `or` keyword or the `||` operator. + * + * left or right + * ^^ + */ + pm_location_t operator_loc; +} pm_or_node_t; + +/** + * ParametersNode + * + * Represents the list of parameters on a method, block, or lambda definition. + * + * def a(b, c, d) + * ^^^^^^^ + * end + * + * Type: ::PM_PARAMETERS_NODE + * + * @extends pm_node_t + */ +typedef struct pm_parameters_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ParametersNode#requireds + */ + struct pm_node_list requireds; + + /** + * ParametersNode#optionals + */ + struct pm_node_list optionals; + + /** + * ParametersNode#rest + */ + struct pm_node *rest; + + /** + * ParametersNode#posts + */ + struct pm_node_list posts; + + /** + * ParametersNode#keywords + */ + struct pm_node_list keywords; + + /** + * ParametersNode#keyword_rest + */ + struct pm_node *keyword_rest; + + /** + * ParametersNode#block + */ + struct pm_block_parameter_node *block; +} pm_parameters_node_t; + +/** + * ParenthesesNode + * + * Represents a parenthesized expression + * + * (10 + 34) + * ^^^^^^^^^ + * + * Type: ::PM_PARENTHESES_NODE + + * Flags (#pm_parentheses_node_flags): + * * ::PM_PARENTHESES_NODE_FLAGS_MULTIPLE_STATEMENTS + * + * @extends pm_node_t + */ +typedef struct pm_parentheses_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ParenthesesNode#body + */ + struct pm_node *body; + + /** + * ParenthesesNode#opening_loc + */ + pm_location_t opening_loc; + + /** + * ParenthesesNode#closing_loc + */ + pm_location_t closing_loc; +} pm_parentheses_node_t; + +/** + * PinnedExpressionNode + * + * Represents the use of the `^` operator for pinning an expression in a pattern matching expression. + * + * foo in ^(bar) + * ^^^^^^ + * + * Type: ::PM_PINNED_EXPRESSION_NODE + * + * @extends pm_node_t + */ +typedef struct pm_pinned_expression_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * PinnedExpressionNode#expression + */ + struct pm_node *expression; + + /** + * PinnedExpressionNode#operator_loc + */ + pm_location_t operator_loc; + + /** + * PinnedExpressionNode#lparen_loc + */ + pm_location_t lparen_loc; + + /** + * PinnedExpressionNode#rparen_loc + */ + pm_location_t rparen_loc; +} pm_pinned_expression_node_t; + +/** + * PinnedVariableNode + * + * Represents the use of the `^` operator for pinning a variable in a pattern matching expression. + * + * foo in ^bar + * ^^^^ + * + * Type: ::PM_PINNED_VARIABLE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_pinned_variable_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * PinnedVariableNode#variable + */ + struct pm_node *variable; + + /** + * PinnedVariableNode#operator_loc + */ + pm_location_t operator_loc; +} pm_pinned_variable_node_t; + +/** + * PostExecutionNode + * + * Represents the use of the `END` keyword. + * + * END { foo } + * ^^^^^^^^^^^ + * + * Type: ::PM_POST_EXECUTION_NODE + * + * @extends pm_node_t + */ +typedef struct pm_post_execution_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * PostExecutionNode#statements + */ + struct pm_statements_node *statements; + + /** + * PostExecutionNode#keyword_loc + */ + pm_location_t keyword_loc; + + /** + * PostExecutionNode#opening_loc + */ + pm_location_t opening_loc; + + /** + * PostExecutionNode#closing_loc + */ + pm_location_t closing_loc; +} pm_post_execution_node_t; + +/** + * PreExecutionNode + * + * Represents the use of the `BEGIN` keyword. + * + * BEGIN { foo } + * ^^^^^^^^^^^^^ + * + * Type: ::PM_PRE_EXECUTION_NODE + * + * @extends pm_node_t + */ +typedef struct pm_pre_execution_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * PreExecutionNode#statements + */ + struct pm_statements_node *statements; + + /** + * PreExecutionNode#keyword_loc + */ + pm_location_t keyword_loc; + + /** + * PreExecutionNode#opening_loc + */ + pm_location_t opening_loc; + + /** + * PreExecutionNode#closing_loc + */ + pm_location_t closing_loc; +} pm_pre_execution_node_t; + +/** + * ProgramNode + * + * The top level node of any parse tree. + * + * Type: ::PM_PROGRAM_NODE + * + * @extends pm_node_t + */ +typedef struct pm_program_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ProgramNode#locals + */ + pm_constant_id_list_t locals; + + /** + * ProgramNode#statements + */ + struct pm_statements_node *statements; +} pm_program_node_t; + +/** + * RangeNode + * + * Represents the use of the `..` or `...` operators. + * + * 1..2 + * ^^^^ + * + * c if a =~ /left/ ... b =~ /right/ + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_RANGE_NODE + + * Flags (#pm_range_flags): + * * ::PM_RANGE_FLAGS_EXCLUDE_END + * + * @extends pm_node_t + */ +typedef struct pm_range_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * RangeNode#left + * + * The left-hand side of the range, if present. It can be either `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * 1... + * ^ + * + * hello...goodbye + * ^^^^^ + */ + struct pm_node *left; + + /** + * RangeNode#right + * + * The right-hand side of the range, if present. It can be either `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * ..5 + * ^ + * + * 1...foo + * ^^^ + * If neither right-hand or left-hand side was included, this will be a MissingNode. + */ + struct pm_node *right; + + /** + * RangeNode#operator_loc + * + * The location of the `..` or `...` operator. + */ + pm_location_t operator_loc; +} pm_range_node_t; + +/** + * RationalNode + * + * Represents a rational number literal. + * + * 1.0r + * ^^^^ + * + * Type: ::PM_RATIONAL_NODE + + * Flags (#pm_integer_base_flags): + * * ::PM_INTEGER_BASE_FLAGS_BINARY + * * ::PM_INTEGER_BASE_FLAGS_DECIMAL + * * ::PM_INTEGER_BASE_FLAGS_OCTAL + * * ::PM_INTEGER_BASE_FLAGS_HEXADECIMAL + * + * @extends pm_node_t + */ +typedef struct pm_rational_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * RationalNode#numerator + * + * The numerator of the rational number. + * + * 1.5r # numerator 3 + */ + pm_integer_t numerator; + + /** + * RationalNode#denominator + * + * The denominator of the rational number. + * + * 1.5r # denominator 2 + */ + pm_integer_t denominator; +} pm_rational_node_t; + +/** + * RedoNode + * + * Represents the use of the `redo` keyword. + * + * redo + * ^^^^ + * + * Type: ::PM_REDO_NODE + * + * @extends pm_node_t + */ +typedef struct pm_redo_node { + /** The embedded base node. */ + pm_node_t base; + +} pm_redo_node_t; + +/** + * RegularExpressionNode + * + * Represents a regular expression literal with no interpolation. + * + * /foo/i + * ^^^^^^ + * + * Type: ::PM_REGULAR_EXPRESSION_NODE + + * Flags (#pm_regular_expression_flags): + * * ::PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE + * * ::PM_REGULAR_EXPRESSION_FLAGS_EXTENDED + * * ::PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE + * * ::PM_REGULAR_EXPRESSION_FLAGS_ONCE + * * ::PM_REGULAR_EXPRESSION_FLAGS_EUC_JP + * * ::PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT + * * ::PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J + * * ::PM_REGULAR_EXPRESSION_FLAGS_UTF_8 + * * ::PM_REGULAR_EXPRESSION_FLAGS_FORCED_UTF8_ENCODING + * * ::PM_REGULAR_EXPRESSION_FLAGS_FORCED_BINARY_ENCODING + * * ::PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING + * + * @extends pm_node_t + */ +typedef struct pm_regular_expression_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * RegularExpressionNode#opening_loc + */ + pm_location_t opening_loc; + + /** + * RegularExpressionNode#content_loc + */ + pm_location_t content_loc; + + /** + * RegularExpressionNode#closing_loc + */ + pm_location_t closing_loc; + + /** + * RegularExpressionNode#unescaped + */ + pm_string_t unescaped; +} pm_regular_expression_node_t; + +/** + * RequiredKeywordParameterNode + * + * Represents a required keyword parameter to a method, block, or lambda definition. + * + * def a(b: ) + * ^^ + * end + * + * Type: ::PM_REQUIRED_KEYWORD_PARAMETER_NODE + + * Flags (#pm_parameter_flags): + * * ::PM_PARAMETER_FLAGS_REPEATED_PARAMETER + * + * @extends pm_node_t + */ +typedef struct pm_required_keyword_parameter_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * RequiredKeywordParameterNode#name + */ + pm_constant_id_t name; + + /** + * RequiredKeywordParameterNode#name_loc + */ + pm_location_t name_loc; +} pm_required_keyword_parameter_node_t; + +/** + * RequiredParameterNode + * + * Represents a required parameter to a method, block, or lambda definition. + * + * def a(b) + * ^ + * end + * + * Type: ::PM_REQUIRED_PARAMETER_NODE + + * Flags (#pm_parameter_flags): + * * ::PM_PARAMETER_FLAGS_REPEATED_PARAMETER + * + * @extends pm_node_t + */ +typedef struct pm_required_parameter_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * RequiredParameterNode#name + */ + pm_constant_id_t name; +} pm_required_parameter_node_t; + +/** + * RescueModifierNode + * + * Represents an expression modified with a rescue. + * + * foo rescue nil + * ^^^^^^^^^^^^^^ + * + * Type: ::PM_RESCUE_MODIFIER_NODE + * + * @extends pm_node_t + */ +typedef struct pm_rescue_modifier_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * RescueModifierNode#expression + */ + struct pm_node *expression; + + /** + * RescueModifierNode#keyword_loc + */ + pm_location_t keyword_loc; + + /** + * RescueModifierNode#rescue_expression + */ + struct pm_node *rescue_expression; +} pm_rescue_modifier_node_t; + +/** + * RescueNode + * + * Represents a rescue statement. + * + * begin + * rescue Foo, *splat, Bar => ex + * foo + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * end + * + * `Foo, *splat, Bar` are in the `exceptions` field. `ex` is in the `reference` field. + * + * Type: ::PM_RESCUE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_rescue_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * RescueNode#keyword_loc + */ + pm_location_t keyword_loc; + + /** + * RescueNode#exceptions + */ + struct pm_node_list exceptions; + + /** + * RescueNode#operator_loc + */ + pm_location_t operator_loc; + + /** + * RescueNode#reference + */ + struct pm_node *reference; + + /** + * RescueNode#then_keyword_loc + */ + pm_location_t then_keyword_loc; + + /** + * RescueNode#statements + */ + struct pm_statements_node *statements; + + /** + * RescueNode#subsequent + */ + struct pm_rescue_node *subsequent; +} pm_rescue_node_t; + +/** + * RestParameterNode + * + * Represents a rest parameter to a method, block, or lambda definition. + * + * def a(*b) + * ^^ + * end + * + * Type: ::PM_REST_PARAMETER_NODE + + * Flags (#pm_parameter_flags): + * * ::PM_PARAMETER_FLAGS_REPEATED_PARAMETER + * + * @extends pm_node_t + */ +typedef struct pm_rest_parameter_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * RestParameterNode#name + */ + pm_constant_id_t name; + + /** + * RestParameterNode#name_loc + */ + pm_location_t name_loc; + + /** + * RestParameterNode#operator_loc + */ + pm_location_t operator_loc; +} pm_rest_parameter_node_t; + +/** + * RetryNode + * + * Represents the use of the `retry` keyword. + * + * retry + * ^^^^^ + * + * Type: ::PM_RETRY_NODE + * + * @extends pm_node_t + */ +typedef struct pm_retry_node { + /** The embedded base node. */ + pm_node_t base; + +} pm_retry_node_t; + +/** + * ReturnNode + * + * Represents the use of the `return` keyword. + * + * return 1 + * ^^^^^^^^ + * + * Type: ::PM_RETURN_NODE + * + * @extends pm_node_t + */ +typedef struct pm_return_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ReturnNode#keyword_loc + */ + pm_location_t keyword_loc; + + /** + * ReturnNode#arguments + */ + struct pm_arguments_node *arguments; +} pm_return_node_t; + +/** + * SelfNode + * + * Represents the `self` keyword. + * + * self + * ^^^^ + * + * Type: ::PM_SELF_NODE + * + * @extends pm_node_t + */ +typedef struct pm_self_node { + /** The embedded base node. */ + pm_node_t base; + +} pm_self_node_t; + +/** + * ShareableConstantNode + * + * This node wraps a constant write to indicate that when the value is written, it should have its shareability state modified. + * + * # shareable_constant_value: literal + * C = { a: 1 } + * ^^^^^^^^^^^^ + * + * Type: ::PM_SHAREABLE_CONSTANT_NODE + + * Flags (#pm_shareable_constant_node_flags): + * * ::PM_SHAREABLE_CONSTANT_NODE_FLAGS_LITERAL + * * ::PM_SHAREABLE_CONSTANT_NODE_FLAGS_EXPERIMENTAL_EVERYTHING + * * ::PM_SHAREABLE_CONSTANT_NODE_FLAGS_EXPERIMENTAL_COPY + * + * @extends pm_node_t + */ +typedef struct pm_shareable_constant_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * ShareableConstantNode#write + * + * The constant write that should be modified with the shareability state. + */ + struct pm_node *write; +} pm_shareable_constant_node_t; + +/** + * SingletonClassNode + * + * Represents a singleton class declaration involving the `class` keyword. + * + * class << self end + * ^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_SINGLETON_CLASS_NODE + * + * @extends pm_node_t + */ +typedef struct pm_singleton_class_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * SingletonClassNode#locals + */ + pm_constant_id_list_t locals; + + /** + * SingletonClassNode#class_keyword_loc + */ + pm_location_t class_keyword_loc; + + /** + * SingletonClassNode#operator_loc + */ + pm_location_t operator_loc; + + /** + * SingletonClassNode#expression + */ + struct pm_node *expression; + + /** + * SingletonClassNode#body + */ + struct pm_node *body; + + /** + * SingletonClassNode#end_keyword_loc + */ + pm_location_t end_keyword_loc; +} pm_singleton_class_node_t; + +/** + * SourceEncodingNode + * + * Represents the use of the `__ENCODING__` keyword. + * + * __ENCODING__ + * ^^^^^^^^^^^^ + * + * Type: ::PM_SOURCE_ENCODING_NODE + * + * @extends pm_node_t + */ +typedef struct pm_source_encoding_node { + /** The embedded base node. */ + pm_node_t base; + +} pm_source_encoding_node_t; + +/** + * SourceFileNode + * + * Represents the use of the `__FILE__` keyword. + * + * __FILE__ + * ^^^^^^^^ + * + * Type: ::PM_SOURCE_FILE_NODE + + * Flags (#pm_string_flags): + * * ::PM_STRING_FLAGS_FORCED_UTF8_ENCODING + * * ::PM_STRING_FLAGS_FORCED_BINARY_ENCODING + * * ::PM_STRING_FLAGS_FROZEN + * * ::PM_STRING_FLAGS_MUTABLE + * + * @extends pm_node_t + */ +typedef struct pm_source_file_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * SourceFileNode#filepath + * + * Represents the file path being parsed. This corresponds directly to the `filepath` option given to the various `Prism::parse*` APIs. + */ + pm_string_t filepath; +} pm_source_file_node_t; + +/** + * SourceLineNode + * + * Represents the use of the `__LINE__` keyword. + * + * __LINE__ + * ^^^^^^^^ + * + * Type: ::PM_SOURCE_LINE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_source_line_node { + /** The embedded base node. */ + pm_node_t base; + +} pm_source_line_node_t; + +/** + * SplatNode + * + * Represents the use of the splat operator. + * + * [*a] + * ^^ + * + * Type: ::PM_SPLAT_NODE + * + * @extends pm_node_t + */ +typedef struct pm_splat_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * SplatNode#operator_loc + */ + pm_location_t operator_loc; + + /** + * SplatNode#expression + */ + struct pm_node *expression; +} pm_splat_node_t; + +/** + * StatementsNode + * + * Represents a set of statements contained within some scope. + * + * foo; bar; baz + * ^^^^^^^^^^^^^ + * + * Type: ::PM_STATEMENTS_NODE + * + * @extends pm_node_t + */ +typedef struct pm_statements_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * StatementsNode#body + */ + struct pm_node_list body; +} pm_statements_node_t; + +/** + * StringNode + * + * Represents a string literal, a string contained within a `%w` list, or plain string content within an interpolated string. + * + * "foo" + * ^^^^^ + * + * %w[foo] + * ^^^ + * + * "foo #{bar} baz" + * ^^^^ ^^^^ + * + * Type: ::PM_STRING_NODE + + * Flags (#pm_string_flags): + * * ::PM_STRING_FLAGS_FORCED_UTF8_ENCODING + * * ::PM_STRING_FLAGS_FORCED_BINARY_ENCODING + * * ::PM_STRING_FLAGS_FROZEN + * * ::PM_STRING_FLAGS_MUTABLE + * + * @extends pm_node_t + */ +typedef struct pm_string_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * StringNode#opening_loc + */ + pm_location_t opening_loc; + + /** + * StringNode#content_loc + */ + pm_location_t content_loc; + + /** + * StringNode#closing_loc + */ + pm_location_t closing_loc; + + /** + * StringNode#unescaped + */ + pm_string_t unescaped; +} pm_string_node_t; + +/** + * SuperNode + * + * Represents the use of the `super` keyword with parentheses or arguments. + * + * super() + * ^^^^^^^ + * + * super foo, bar + * ^^^^^^^^^^^^^^ + * + * Type: ::PM_SUPER_NODE + * + * @extends pm_node_t + */ +typedef struct pm_super_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * SuperNode#keyword_loc + */ + pm_location_t keyword_loc; + + /** + * SuperNode#lparen_loc + */ + pm_location_t lparen_loc; + + /** + * SuperNode#arguments + */ + struct pm_arguments_node *arguments; + + /** + * SuperNode#rparen_loc + */ + pm_location_t rparen_loc; + + /** + * SuperNode#block + */ + struct pm_node *block; +} pm_super_node_t; + +/** + * SymbolNode + * + * Represents a symbol literal or a symbol contained within a `%i` list. + * + * :foo + * ^^^^ + * + * %i[foo] + * ^^^ + * + * Type: ::PM_SYMBOL_NODE + + * Flags (#pm_symbol_flags): + * * ::PM_SYMBOL_FLAGS_FORCED_UTF8_ENCODING + * * ::PM_SYMBOL_FLAGS_FORCED_BINARY_ENCODING + * * ::PM_SYMBOL_FLAGS_FORCED_US_ASCII_ENCODING + * + * @extends pm_node_t + */ +typedef struct pm_symbol_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * SymbolNode#opening_loc + */ + pm_location_t opening_loc; + + /** + * SymbolNode#value_loc + */ + pm_location_t value_loc; + + /** + * SymbolNode#closing_loc + */ + pm_location_t closing_loc; + + /** + * SymbolNode#unescaped + */ + pm_string_t unescaped; +} pm_symbol_node_t; + +/** + * TrueNode + * + * Represents the use of the literal `true` keyword. + * + * true + * ^^^^ + * + * Type: ::PM_TRUE_NODE + * + * @extends pm_node_t + */ +typedef struct pm_true_node { + /** The embedded base node. */ + pm_node_t base; + +} pm_true_node_t; + +/** + * UndefNode + * + * Represents the use of the `undef` keyword. + * + * undef :foo, :bar, :baz + * ^^^^^^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_UNDEF_NODE + * + * @extends pm_node_t + */ +typedef struct pm_undef_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * UndefNode#names + */ + struct pm_node_list names; + + /** + * UndefNode#keyword_loc + */ + pm_location_t keyword_loc; +} pm_undef_node_t; + +/** + * UnlessNode + * + * Represents the use of the `unless` keyword, either in the block form or the modifier form. + * + * bar unless foo + * ^^^^^^^^^^^^^^ + * + * unless foo then bar end + * ^^^^^^^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_UNLESS_NODE + * + * @extends pm_node_t + */ +typedef struct pm_unless_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * UnlessNode#keyword_loc + * + * The location of the `unless` keyword. + * + * unless cond then bar end + * ^^^^^^ + * + * bar unless cond + * ^^^^^^ + */ + pm_location_t keyword_loc; + + /** + * UnlessNode#predicate + * + * The condition to be evaluated for the unless expression. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + * + * unless cond then bar end + * ^^^^ + * + * bar unless cond + * ^^^^ + */ + struct pm_node *predicate; + + /** + * UnlessNode#then_keyword_loc + * + * The location of the `then` keyword, if present. + * + * unless cond then bar end + * ^^^^ + */ + pm_location_t then_keyword_loc; + + /** + * UnlessNode#statements + * + * The body of statements that will executed if the unless condition is + * falsey. Will be `nil` if no body is provided. + * + * unless cond then bar end + * ^^^ + */ + struct pm_statements_node *statements; + + /** + * UnlessNode#else_clause + * + * The else clause of the unless expression, if present. + * + * unless cond then bar else baz end + * ^^^^^^^^ + */ + struct pm_else_node *else_clause; + + /** + * UnlessNode#end_keyword_loc + * + * The location of the `end` keyword, if present. + * + * unless cond then bar end + * ^^^ + */ + pm_location_t end_keyword_loc; +} pm_unless_node_t; + +/** + * UntilNode + * + * Represents the use of the `until` keyword, either in the block form or the modifier form. + * + * bar until foo + * ^^^^^^^^^^^^^ + * + * until foo do bar end + * ^^^^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_UNTIL_NODE + + * Flags (#pm_loop_flags): + * * ::PM_LOOP_FLAGS_BEGIN_MODIFIER + * + * @extends pm_node_t + */ +typedef struct pm_until_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * UntilNode#keyword_loc + */ + pm_location_t keyword_loc; + + /** + * UntilNode#do_keyword_loc + */ + pm_location_t do_keyword_loc; + + /** + * UntilNode#closing_loc + */ + pm_location_t closing_loc; + + /** + * UntilNode#predicate + */ + struct pm_node *predicate; + + /** + * UntilNode#statements + */ + struct pm_statements_node *statements; +} pm_until_node_t; + +/** + * WhenNode + * + * Represents the use of the `when` keyword within a case statement. + * + * case true + * when true + * ^^^^^^^^^ + * end + * + * Type: ::PM_WHEN_NODE + * + * @extends pm_node_t + */ +typedef struct pm_when_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * WhenNode#keyword_loc + */ + pm_location_t keyword_loc; + + /** + * WhenNode#conditions + */ + struct pm_node_list conditions; + + /** + * WhenNode#then_keyword_loc + */ + pm_location_t then_keyword_loc; + + /** + * WhenNode#statements + */ + struct pm_statements_node *statements; +} pm_when_node_t; + +/** + * WhileNode + * + * Represents the use of the `while` keyword, either in the block form or the modifier form. + * + * bar while foo + * ^^^^^^^^^^^^^ + * + * while foo do bar end + * ^^^^^^^^^^^^^^^^^^^^ + * + * Type: ::PM_WHILE_NODE + + * Flags (#pm_loop_flags): + * * ::PM_LOOP_FLAGS_BEGIN_MODIFIER + * + * @extends pm_node_t + */ +typedef struct pm_while_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * WhileNode#keyword_loc + */ + pm_location_t keyword_loc; + + /** + * WhileNode#do_keyword_loc + */ + pm_location_t do_keyword_loc; + + /** + * WhileNode#closing_loc + */ + pm_location_t closing_loc; + + /** + * WhileNode#predicate + */ + struct pm_node *predicate; + + /** + * WhileNode#statements + */ + struct pm_statements_node *statements; +} pm_while_node_t; + +/** + * XStringNode + * + * Represents an xstring literal with no interpolation. + * + * `foo` + * ^^^^^ + * + * Type: ::PM_X_STRING_NODE + + * Flags (#pm_encoding_flags): + * * ::PM_ENCODING_FLAGS_FORCED_UTF8_ENCODING + * * ::PM_ENCODING_FLAGS_FORCED_BINARY_ENCODING + * + * @extends pm_node_t + */ +typedef struct pm_x_string_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * XStringNode#opening_loc + */ + pm_location_t opening_loc; + + /** + * XStringNode#content_loc + */ + pm_location_t content_loc; + + /** + * XStringNode#closing_loc + */ + pm_location_t closing_loc; + + /** + * XStringNode#unescaped + */ + pm_string_t unescaped; +} pm_x_string_node_t; + +/** + * YieldNode + * + * Represents the use of the `yield` keyword. + * + * yield 1 + * ^^^^^^^ + * + * Type: ::PM_YIELD_NODE + * + * @extends pm_node_t + */ +typedef struct pm_yield_node { + /** The embedded base node. */ + pm_node_t base; + + + /** + * YieldNode#keyword_loc + */ + pm_location_t keyword_loc; + + /** + * YieldNode#lparen_loc + */ + pm_location_t lparen_loc; + + /** + * YieldNode#arguments + */ + struct pm_arguments_node *arguments; + + /** + * YieldNode#rparen_loc + */ + pm_location_t rparen_loc; +} pm_yield_node_t; + +/** + * Flags for arguments nodes. + */ +typedef enum pm_arguments_node_flags { + /** if the arguments contain forwarding */ + PM_ARGUMENTS_NODE_FLAGS_CONTAINS_FORWARDING = 4, + + /** if the arguments contain keywords */ + PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORDS = 8, + + /** if the arguments contain a keyword splat */ + PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORD_SPLAT = 16, + + /** if the arguments contain a splat */ + PM_ARGUMENTS_NODE_FLAGS_CONTAINS_SPLAT = 32, + + /** if the arguments contain multiple splats */ + PM_ARGUMENTS_NODE_FLAGS_CONTAINS_MULTIPLE_SPLATS = 64, +} pm_arguments_node_flags_t; + +/** + * Flags for array nodes. + */ +typedef enum pm_array_node_flags { + /** if array contains splat nodes */ + PM_ARRAY_NODE_FLAGS_CONTAINS_SPLAT = 4, +} pm_array_node_flags_t; + +/** + * Flags for call nodes. + */ +typedef enum pm_call_node_flags { + /** &. operator */ + PM_CALL_NODE_FLAGS_SAFE_NAVIGATION = 4, + + /** a call that could have been a local variable */ + PM_CALL_NODE_FLAGS_VARIABLE_CALL = 8, + + /** a call that is an attribute write, so the value being written should be returned */ + PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE = 16, + + /** a call that ignores method visibility */ + PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY = 32, +} pm_call_node_flags_t; + +/** + * Flags for nodes that have unescaped content. + */ +typedef enum pm_encoding_flags { + /** internal bytes forced the encoding to UTF-8 */ + PM_ENCODING_FLAGS_FORCED_UTF8_ENCODING = 4, + + /** internal bytes forced the encoding to binary */ + PM_ENCODING_FLAGS_FORCED_BINARY_ENCODING = 8, +} pm_encoding_flags_t; + +/** + * Flags for integer nodes that correspond to the base of the integer. + */ +typedef enum pm_integer_base_flags { + /** 0b prefix */ + PM_INTEGER_BASE_FLAGS_BINARY = 4, + + /** 0d or no prefix */ + PM_INTEGER_BASE_FLAGS_DECIMAL = 8, + + /** 0o or 0 prefix */ + PM_INTEGER_BASE_FLAGS_OCTAL = 16, + + /** 0x prefix */ + PM_INTEGER_BASE_FLAGS_HEXADECIMAL = 32, +} pm_integer_base_flags_t; + +/** + * Flags for interpolated string nodes that indicated mutability if they are also marked as literals. + */ +typedef enum pm_interpolated_string_node_flags { + /** frozen by virtue of a `frozen_string_literal: true` comment or `--enable-frozen-string-literal`; only for adjacent string literals like `'a' 'b'` */ + PM_INTERPOLATED_STRING_NODE_FLAGS_FROZEN = 4, + + /** mutable by virtue of a `frozen_string_literal: false` comment or `--disable-frozen-string-literal`; only for adjacent string literals like `'a' 'b'` */ + PM_INTERPOLATED_STRING_NODE_FLAGS_MUTABLE = 8, +} pm_interpolated_string_node_flags_t; + +/** + * Flags for keyword hash nodes. + */ +typedef enum pm_keyword_hash_node_flags { + /** a keyword hash which only has `AssocNode` elements all with symbol keys, which means the elements can be treated as keyword arguments */ + PM_KEYWORD_HASH_NODE_FLAGS_SYMBOL_KEYS = 4, +} pm_keyword_hash_node_flags_t; + +/** + * Flags for while and until loop nodes. + */ +typedef enum pm_loop_flags { + /** a loop after a begin statement, so the body is executed first before the condition */ + PM_LOOP_FLAGS_BEGIN_MODIFIER = 4, +} pm_loop_flags_t; + +/** + * Flags for parameter nodes. + */ +typedef enum pm_parameter_flags { + /** a parameter name that has been repeated in the method signature */ + PM_PARAMETER_FLAGS_REPEATED_PARAMETER = 4, +} pm_parameter_flags_t; + +/** + * Flags for parentheses nodes. + */ +typedef enum pm_parentheses_node_flags { + /** parentheses that contain multiple potentially void statements */ + PM_PARENTHESES_NODE_FLAGS_MULTIPLE_STATEMENTS = 4, +} pm_parentheses_node_flags_t; + +/** + * Flags for range and flip-flop nodes. + */ +typedef enum pm_range_flags { + /** ... operator */ + PM_RANGE_FLAGS_EXCLUDE_END = 4, +} pm_range_flags_t; + +/** + * Flags for regular expression and match last line nodes. + */ +typedef enum pm_regular_expression_flags { + /** i - ignores the case of characters when matching */ + PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE = 4, + + /** x - ignores whitespace and allows comments in regular expressions */ + PM_REGULAR_EXPRESSION_FLAGS_EXTENDED = 8, + + /** m - allows $ to match the end of lines within strings */ + PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE = 16, + + /** o - only interpolates values into the regular expression once */ + PM_REGULAR_EXPRESSION_FLAGS_ONCE = 32, + + /** e - forces the EUC-JP encoding */ + PM_REGULAR_EXPRESSION_FLAGS_EUC_JP = 64, + + /** n - forces the ASCII-8BIT encoding */ + PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT = 128, + + /** s - forces the Windows-31J encoding */ + PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J = 256, + + /** u - forces the UTF-8 encoding */ + PM_REGULAR_EXPRESSION_FLAGS_UTF_8 = 512, + + /** internal bytes forced the encoding to UTF-8 */ + PM_REGULAR_EXPRESSION_FLAGS_FORCED_UTF8_ENCODING = 1024, + + /** internal bytes forced the encoding to binary */ + PM_REGULAR_EXPRESSION_FLAGS_FORCED_BINARY_ENCODING = 2048, + + /** internal bytes forced the encoding to US-ASCII */ + PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING = 4096, +} pm_regular_expression_flags_t; + +/** + * Flags for shareable constant nodes. + */ +typedef enum pm_shareable_constant_node_flags { + /** constant writes that should be modified with shareable constant value literal */ + PM_SHAREABLE_CONSTANT_NODE_FLAGS_LITERAL = 4, + + /** constant writes that should be modified with shareable constant value experimental everything */ + PM_SHAREABLE_CONSTANT_NODE_FLAGS_EXPERIMENTAL_EVERYTHING = 8, + + /** constant writes that should be modified with shareable constant value experimental copy */ + PM_SHAREABLE_CONSTANT_NODE_FLAGS_EXPERIMENTAL_COPY = 16, +} pm_shareable_constant_node_flags_t; + +/** + * Flags for string nodes. + */ +typedef enum pm_string_flags { + /** internal bytes forced the encoding to UTF-8 */ + PM_STRING_FLAGS_FORCED_UTF8_ENCODING = 4, + + /** internal bytes forced the encoding to binary */ + PM_STRING_FLAGS_FORCED_BINARY_ENCODING = 8, + + /** frozen by virtue of a `frozen_string_literal: true` comment or `--enable-frozen-string-literal` */ + PM_STRING_FLAGS_FROZEN = 16, + + /** mutable by virtue of a `frozen_string_literal: false` comment or `--disable-frozen-string-literal` */ + PM_STRING_FLAGS_MUTABLE = 32, +} pm_string_flags_t; + +/** + * Flags for symbol nodes. + */ +typedef enum pm_symbol_flags { + /** internal bytes forced the encoding to UTF-8 */ + PM_SYMBOL_FLAGS_FORCED_UTF8_ENCODING = 4, + + /** internal bytes forced the encoding to binary */ + PM_SYMBOL_FLAGS_FORCED_BINARY_ENCODING = 8, + + /** internal bytes forced the encoding to US-ASCII */ + PM_SYMBOL_FLAGS_FORCED_US_ASCII_ENCODING = 16, +} pm_symbol_flags_t; + +/** + * When we're serializing to Java, we want to skip serializing the location + * fields as they won't be used by JRuby or TruffleRuby. This boolean allows us + * to specify that through the environment. It will never be true except for in + * those build systems. + */ +#define PRISM_SERIALIZE_ONLY_SEMANTICS_FIELDS 0 + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/defines.h b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/defines.h new file mode 100644 index 00000000..e31429c7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/defines.h @@ -0,0 +1,260 @@ +/** + * @file defines.h + * + * Macro definitions used throughout the prism library. + * + * This file should be included first by any *.h or *.c in prism for consistency + * and to ensure that the macros are defined before they are used. + */ +#ifndef PRISM_DEFINES_H +#define PRISM_DEFINES_H + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * We want to be able to use the PRI* macros for printing out integers, but on + * some platforms they aren't included unless this is already defined. + */ +#define __STDC_FORMAT_MACROS +// Include sys/types.h before inttypes.h to work around issue with +// certain versions of GCC and newlib which causes omission of PRIx64 +#include +#include + +/** + * When we are parsing using recursive descent, we want to protect against + * malicious payloads that could attempt to crash our parser. We do this by + * specifying a maximum depth to which we are allowed to recurse. + */ +#ifndef PRISM_DEPTH_MAXIMUM + #define PRISM_DEPTH_MAXIMUM 10000 +#endif + +/** + * By default, we compile with -fvisibility=hidden. When this is enabled, we + * need to mark certain functions as being publically-visible. This macro does + * that in a compiler-agnostic way. + */ +#ifndef PRISM_EXPORTED_FUNCTION +# ifdef PRISM_EXPORT_SYMBOLS +# ifdef _WIN32 +# define PRISM_EXPORTED_FUNCTION __declspec(dllexport) extern +# else +# define PRISM_EXPORTED_FUNCTION __attribute__((__visibility__("default"))) extern +# endif +# else +# define PRISM_EXPORTED_FUNCTION +# endif +#endif + +/** + * Certain compilers support specifying that a function accepts variadic + * parameters that look like printf format strings to provide a better developer + * experience when someone is using the function. This macro does that in a + * compiler-agnostic way. + */ +#if defined(__GNUC__) +# if defined(__MINGW_PRINTF_FORMAT) +# define PRISM_ATTRIBUTE_FORMAT(string_index, argument_index) __attribute__((format(__MINGW_PRINTF_FORMAT, string_index, argument_index))) +# else +# define PRISM_ATTRIBUTE_FORMAT(string_index, argument_index) __attribute__((format(printf, string_index, argument_index))) +# endif +#elif defined(__clang__) +# define PRISM_ATTRIBUTE_FORMAT(string_index, argument_index) __attribute__((__format__(__printf__, string_index, argument_index))) +#else +# define PRISM_ATTRIBUTE_FORMAT(string_index, argument_index) +#endif + +/** + * GCC will warn if you specify a function or parameter that is unused at + * runtime. This macro allows you to mark a function or parameter as unused in a + * compiler-agnostic way. + */ +#if defined(__GNUC__) +# define PRISM_ATTRIBUTE_UNUSED __attribute__((unused)) +#else +# define PRISM_ATTRIBUTE_UNUSED +#endif + +/** + * Old Visual Studio versions do not support the inline keyword, so we need to + * define it to be __inline. + */ +#if defined(_MSC_VER) && !defined(inline) +# define inline __inline +#endif + +/** + * Old Visual Studio versions before 2015 do not implement sprintf, but instead + * implement _snprintf. We standard that here. + */ +#if !defined(snprintf) && defined(_MSC_VER) && (_MSC_VER < 1900) +# define snprintf _snprintf +#endif + +/** + * A simple utility macro to concatenate two tokens together, necessary when one + * of the tokens is itself a macro. + */ +#define PM_CONCATENATE(left, right) left ## right + +/** + * We want to be able to use static assertions, but they weren't standardized + * until C11. As such, we polyfill it here by making a hacky typedef that will + * fail to compile due to a negative array size if the condition is false. + */ +#if defined(_Static_assert) +# define PM_STATIC_ASSERT(line, condition, message) _Static_assert(condition, message) +#else +# define PM_STATIC_ASSERT(line, condition, message) typedef char PM_CONCATENATE(static_assert_, line)[(condition) ? 1 : -1] +#endif + +/** + * In general, libc for embedded systems does not support memory-mapped files. + * If the target platform is POSIX or Windows, we can map a file in memory and + * read it in a more efficient manner. + */ +#ifdef _WIN32 +# define PRISM_HAS_MMAP +#else +# include +# ifdef _POSIX_MAPPED_FILES +# define PRISM_HAS_MMAP +# endif +#endif + +/** + * If PRISM_HAS_NO_FILESYSTEM is defined, then we want to exclude all filesystem + * related code from the library. All filesystem related code should be guarded + * by PRISM_HAS_FILESYSTEM. + */ +#ifndef PRISM_HAS_NO_FILESYSTEM +# define PRISM_HAS_FILESYSTEM +#endif + +/** + * isinf on POSIX systems it accepts a float, a double, or a long double. + * But mingw didn't provide an isinf macro, only an isinf function that only + * accepts floats, so we need to use _finite instead. + */ +#ifdef __MINGW64__ + #include + #define PRISM_ISINF(x) (!_finite(x)) +#else + #define PRISM_ISINF(x) isinf(x) +#endif + +/** + * If you build prism with a custom allocator, configure it with + * "-D PRISM_XALLOCATOR" to use your own allocator that defines xmalloc, + * xrealloc, xcalloc, and xfree. + * + * For example, your `prism_xallocator.h` file could look like this: + * + * ``` + * #ifndef PRISM_XALLOCATOR_H + * #define PRISM_XALLOCATOR_H + * #define xmalloc my_malloc + * #define xrealloc my_realloc + * #define xcalloc my_calloc + * #define xfree my_free + * #endif + * ``` + */ +#ifdef PRISM_XALLOCATOR + #include "prism_xallocator.h" +#else + #ifndef xmalloc + /** + * The malloc function that should be used. This can be overridden with + * the PRISM_XALLOCATOR define. + */ + #define xmalloc malloc + #endif + + #ifndef xrealloc + /** + * The realloc function that should be used. This can be overridden with + * the PRISM_XALLOCATOR define. + */ + #define xrealloc realloc + #endif + + #ifndef xcalloc + /** + * The calloc function that should be used. This can be overridden with + * the PRISM_XALLOCATOR define. + */ + #define xcalloc calloc + #endif + + #ifndef xfree + /** + * The free function that should be used. This can be overridden with the + * PRISM_XALLOCATOR define. + */ + #define xfree free + #endif +#endif + +/** + * If PRISM_BUILD_MINIMAL is defined, then we're going to define every possible + * switch that will turn off certain features of prism. + */ +#ifdef PRISM_BUILD_MINIMAL + /** Exclude the serialization API. */ + #define PRISM_EXCLUDE_SERIALIZATION + + /** Exclude the JSON serialization API. */ + #define PRISM_EXCLUDE_JSON + + /** Exclude the Array#pack parser API. */ + #define PRISM_EXCLUDE_PACK + + /** Exclude the prettyprint API. */ + #define PRISM_EXCLUDE_PRETTYPRINT + + /** Exclude the full set of encodings, using the minimal only. */ + #define PRISM_ENCODING_EXCLUDE_FULL +#endif + +/** + * Support PRISM_LIKELY and PRISM_UNLIKELY to help the compiler optimize its + * branch predication. + */ +#if defined(__GNUC__) || defined(__clang__) + /** The compiler should predicate that this branch will be taken. */ + #define PRISM_LIKELY(x) __builtin_expect(!!(x), 1) + + /** The compiler should predicate that this branch will not be taken. */ + #define PRISM_UNLIKELY(x) __builtin_expect(!!(x), 0) +#else + /** Void because this platform does not support branch prediction hints. */ + #define PRISM_LIKELY(x) (x) + + /** Void because this platform does not support branch prediction hints. */ + #define PRISM_UNLIKELY(x) (x) +#endif + +/** + * We use -Wimplicit-fallthrough to guard potentially unintended fall-through between cases of a switch. + * Use PRISM_FALLTHROUGH to explicitly annotate cases where the fallthrough is intentional. + */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L // C23 or later + #define PRISM_FALLTHROUGH [[fallthrough]]; +#elif defined(__GNUC__) || defined(__clang__) + #define PRISM_FALLTHROUGH __attribute__((fallthrough)); +#elif defined(_MSC_VER) + #define PRISM_FALLTHROUGH __fallthrough; +#else + #define PRISM_FALLTHROUGH +#endif + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/diagnostic.h b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/diagnostic.h new file mode 100644 index 00000000..2b1aa9b2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/diagnostic.h @@ -0,0 +1,451 @@ +/*----------------------------------------------------------------------------*/ +/* This file is generated by the templates/template.rb script and should not */ +/* be modified manually. See */ +/* templates/include/prism/diagnostic.h.erb */ +/* if you are looking to modify the */ +/* template */ +/*----------------------------------------------------------------------------*/ + +/** + * @file diagnostic.h + * + * A list of diagnostics generated during parsing. + */ +#ifndef PRISM_DIAGNOSTIC_H +#define PRISM_DIAGNOSTIC_H + +#include "prism/ast.h" +#include "prism/defines.h" +#include "prism/util/pm_list.h" + +#include +#include +#include + +/** + * The diagnostic IDs of all of the diagnostics, used to communicate the types + * of errors between the parser and the user. + */ +typedef enum { + // These are the error diagnostics. + PM_ERR_ALIAS_ARGUMENT, + PM_ERR_ALIAS_ARGUMENT_NUMBERED_REFERENCE, + PM_ERR_AMPAMPEQ_MULTI_ASSIGN, + PM_ERR_ARGUMENT_AFTER_BLOCK, + PM_ERR_ARGUMENT_AFTER_FORWARDING_ELLIPSES, + PM_ERR_ARGUMENT_BARE_HASH, + PM_ERR_ARGUMENT_BLOCK_FORWARDING, + PM_ERR_ARGUMENT_BLOCK_MULTI, + PM_ERR_ARGUMENT_CONFLICT_AMPERSAND, + PM_ERR_ARGUMENT_CONFLICT_STAR, + PM_ERR_ARGUMENT_CONFLICT_STAR_STAR, + PM_ERR_ARGUMENT_FORMAL_CLASS, + PM_ERR_ARGUMENT_FORMAL_CONSTANT, + PM_ERR_ARGUMENT_FORMAL_GLOBAL, + PM_ERR_ARGUMENT_FORMAL_IVAR, + PM_ERR_ARGUMENT_FORWARDING_UNBOUND, + PM_ERR_ARGUMENT_NO_FORWARDING_AMPERSAND, + PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES, + PM_ERR_ARGUMENT_NO_FORWARDING_STAR, + PM_ERR_ARGUMENT_NO_FORWARDING_STAR_STAR, + PM_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT, + PM_ERR_ARGUMENT_SPLAT_AFTER_SPLAT, + PM_ERR_ARGUMENT_TERM_PAREN, + PM_ERR_ARGUMENT_UNEXPECTED_BLOCK, + PM_ERR_ARRAY_ELEMENT, + PM_ERR_ARRAY_EXPRESSION, + PM_ERR_ARRAY_EXPRESSION_AFTER_STAR, + PM_ERR_ARRAY_SEPARATOR, + PM_ERR_ARRAY_TERM, + PM_ERR_BEGIN_LONELY_ELSE, + PM_ERR_BEGIN_TERM, + PM_ERR_BEGIN_UPCASE_BRACE, + PM_ERR_BEGIN_UPCASE_TERM, + PM_ERR_BEGIN_UPCASE_TOPLEVEL, + PM_ERR_BLOCK_PARAM_LOCAL_VARIABLE, + PM_ERR_BLOCK_PARAM_PIPE_TERM, + PM_ERR_BLOCK_TERM_BRACE, + PM_ERR_BLOCK_TERM_END, + PM_ERR_CANNOT_PARSE_EXPRESSION, + PM_ERR_CANNOT_PARSE_STRING_PART, + PM_ERR_CASE_EXPRESSION_AFTER_CASE, + PM_ERR_CASE_EXPRESSION_AFTER_WHEN, + PM_ERR_CASE_MATCH_MISSING_PREDICATE, + PM_ERR_CASE_MISSING_CONDITIONS, + PM_ERR_CASE_TERM, + PM_ERR_CLASS_IN_METHOD, + PM_ERR_CLASS_NAME, + PM_ERR_CLASS_SUPERCLASS, + PM_ERR_CLASS_TERM, + PM_ERR_CLASS_UNEXPECTED_END, + PM_ERR_CLASS_VARIABLE_BARE, + PM_ERR_CONDITIONAL_ELSIF_PREDICATE, + PM_ERR_CONDITIONAL_IF_PREDICATE, + PM_ERR_CONDITIONAL_PREDICATE_TERM, + PM_ERR_CONDITIONAL_TERM, + PM_ERR_CONDITIONAL_TERM_ELSE, + PM_ERR_CONDITIONAL_UNLESS_PREDICATE, + PM_ERR_CONDITIONAL_UNTIL_PREDICATE, + PM_ERR_CONDITIONAL_WHILE_PREDICATE, + PM_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT, + PM_ERR_DEF_ENDLESS, + PM_ERR_DEF_ENDLESS_SETTER, + PM_ERR_DEF_NAME, + PM_ERR_DEF_PARAMS_TERM, + PM_ERR_DEF_PARAMS_TERM_PAREN, + PM_ERR_DEF_RECEIVER, + PM_ERR_DEF_RECEIVER_TERM, + PM_ERR_DEF_TERM, + PM_ERR_DEFINED_EXPRESSION, + PM_ERR_EMBDOC_TERM, + PM_ERR_EMBEXPR_END, + PM_ERR_EMBVAR_INVALID, + PM_ERR_END_UPCASE_BRACE, + PM_ERR_END_UPCASE_TERM, + PM_ERR_ESCAPE_INVALID_CONTROL, + PM_ERR_ESCAPE_INVALID_CONTROL_REPEAT, + PM_ERR_ESCAPE_INVALID_HEXADECIMAL, + PM_ERR_ESCAPE_INVALID_META, + PM_ERR_ESCAPE_INVALID_META_REPEAT, + PM_ERR_ESCAPE_INVALID_UNICODE, + PM_ERR_ESCAPE_INVALID_UNICODE_CM_FLAGS, + PM_ERR_ESCAPE_INVALID_UNICODE_LIST, + PM_ERR_ESCAPE_INVALID_UNICODE_LITERAL, + PM_ERR_ESCAPE_INVALID_UNICODE_LONG, + PM_ERR_ESCAPE_INVALID_UNICODE_SHORT, + PM_ERR_ESCAPE_INVALID_UNICODE_TERM, + PM_ERR_EXPECT_ARGUMENT, + PM_ERR_EXPECT_EOL_AFTER_STATEMENT, + PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ, + PM_ERR_EXPECT_EXPRESSION_AFTER_COMMA, + PM_ERR_EXPECT_EXPRESSION_AFTER_EQUAL, + PM_ERR_EXPECT_EXPRESSION_AFTER_LESS_LESS, + PM_ERR_EXPECT_EXPRESSION_AFTER_LPAREN, + PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, + PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ, + PM_ERR_EXPECT_EXPRESSION_AFTER_QUESTION, + PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT, + PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH, + PM_ERR_EXPECT_EXPRESSION_AFTER_STAR, + PM_ERR_EXPECT_FOR_DELIMITER, + PM_ERR_EXPECT_IDENT_REQ_PARAMETER, + PM_ERR_EXPECT_IN_DELIMITER, + PM_ERR_EXPECT_LPAREN_REQ_PARAMETER, + PM_ERR_EXPECT_MESSAGE, + PM_ERR_EXPECT_RBRACKET, + PM_ERR_EXPECT_RPAREN, + PM_ERR_EXPECT_RPAREN_AFTER_MULTI, + PM_ERR_EXPECT_RPAREN_REQ_PARAMETER, + PM_ERR_EXPECT_SINGLETON_CLASS_DELIMITER, + PM_ERR_EXPECT_STRING_CONTENT, + PM_ERR_EXPECT_WHEN_DELIMITER, + PM_ERR_EXPRESSION_BARE_HASH, + PM_ERR_EXPRESSION_NOT_WRITABLE, + PM_ERR_EXPRESSION_NOT_WRITABLE_ENCODING, + PM_ERR_EXPRESSION_NOT_WRITABLE_FALSE, + PM_ERR_EXPRESSION_NOT_WRITABLE_FILE, + PM_ERR_EXPRESSION_NOT_WRITABLE_LINE, + PM_ERR_EXPRESSION_NOT_WRITABLE_NIL, + PM_ERR_EXPRESSION_NOT_WRITABLE_NUMBERED, + PM_ERR_EXPRESSION_NOT_WRITABLE_SELF, + PM_ERR_EXPRESSION_NOT_WRITABLE_TRUE, + PM_ERR_FLOAT_PARSE, + PM_ERR_FOR_COLLECTION, + PM_ERR_FOR_IN, + PM_ERR_FOR_INDEX, + PM_ERR_FOR_TERM, + PM_ERR_GLOBAL_VARIABLE_BARE, + PM_ERR_HASH_EXPRESSION_AFTER_LABEL, + PM_ERR_HASH_KEY, + PM_ERR_HASH_ROCKET, + PM_ERR_HASH_TERM, + PM_ERR_HASH_VALUE, + PM_ERR_HEREDOC_IDENTIFIER, + PM_ERR_HEREDOC_TERM, + PM_ERR_INCOMPLETE_QUESTION_MARK, + PM_ERR_INCOMPLETE_VARIABLE_CLASS, + PM_ERR_INCOMPLETE_VARIABLE_CLASS_3_3, + PM_ERR_INCOMPLETE_VARIABLE_INSTANCE, + PM_ERR_INCOMPLETE_VARIABLE_INSTANCE_3_3, + PM_ERR_INSTANCE_VARIABLE_BARE, + PM_ERR_INVALID_BLOCK_EXIT, + PM_ERR_INVALID_CHARACTER, + PM_ERR_INVALID_COMMA, + PM_ERR_INVALID_ENCODING_MAGIC_COMMENT, + PM_ERR_INVALID_ESCAPE_CHARACTER, + PM_ERR_INVALID_FLOAT_EXPONENT, + PM_ERR_INVALID_LOCAL_VARIABLE_READ, + PM_ERR_INVALID_LOCAL_VARIABLE_WRITE, + PM_ERR_INVALID_MULTIBYTE_CHAR, + PM_ERR_INVALID_MULTIBYTE_CHARACTER, + PM_ERR_INVALID_MULTIBYTE_ESCAPE, + PM_ERR_INVALID_NUMBER_BINARY, + PM_ERR_INVALID_NUMBER_DECIMAL, + PM_ERR_INVALID_NUMBER_FRACTION, + PM_ERR_INVALID_NUMBER_HEXADECIMAL, + PM_ERR_INVALID_NUMBER_OCTAL, + PM_ERR_INVALID_NUMBER_UNDERSCORE_INNER, + PM_ERR_INVALID_NUMBER_UNDERSCORE_TRAILING, + PM_ERR_INVALID_PERCENT, + PM_ERR_INVALID_PERCENT_EOF, + PM_ERR_INVALID_PRINTABLE_CHARACTER, + PM_ERR_INVALID_RETRY_AFTER_ELSE, + PM_ERR_INVALID_RETRY_AFTER_ENSURE, + PM_ERR_INVALID_RETRY_WITHOUT_RESCUE, + PM_ERR_INVALID_SYMBOL, + PM_ERR_INVALID_VARIABLE_GLOBAL, + PM_ERR_INVALID_VARIABLE_GLOBAL_3_3, + PM_ERR_INVALID_YIELD, + PM_ERR_IT_NOT_ALLOWED_NUMBERED, + PM_ERR_IT_NOT_ALLOWED_ORDINARY, + PM_ERR_LAMBDA_OPEN, + PM_ERR_LAMBDA_TERM_BRACE, + PM_ERR_LAMBDA_TERM_END, + PM_ERR_LIST_I_LOWER_ELEMENT, + PM_ERR_LIST_I_LOWER_TERM, + PM_ERR_LIST_I_UPPER_ELEMENT, + PM_ERR_LIST_I_UPPER_TERM, + PM_ERR_LIST_W_LOWER_ELEMENT, + PM_ERR_LIST_W_LOWER_TERM, + PM_ERR_LIST_W_UPPER_ELEMENT, + PM_ERR_LIST_W_UPPER_TERM, + PM_ERR_MALLOC_FAILED, + PM_ERR_MIXED_ENCODING, + PM_ERR_MODULE_IN_METHOD, + PM_ERR_MODULE_NAME, + PM_ERR_MODULE_TERM, + PM_ERR_MULTI_ASSIGN_MULTI_SPLATS, + PM_ERR_MULTI_ASSIGN_UNEXPECTED_REST, + PM_ERR_NESTING_TOO_DEEP, + PM_ERR_NO_LOCAL_VARIABLE, + PM_ERR_NON_ASSOCIATIVE_OPERATOR, + PM_ERR_NOT_EXPRESSION, + PM_ERR_NUMBER_LITERAL_UNDERSCORE, + PM_ERR_NUMBERED_PARAMETER_INNER_BLOCK, + PM_ERR_NUMBERED_PARAMETER_IT, + PM_ERR_NUMBERED_PARAMETER_ORDINARY, + PM_ERR_NUMBERED_PARAMETER_OUTER_BLOCK, + PM_ERR_OPERATOR_MULTI_ASSIGN, + PM_ERR_OPERATOR_WRITE_ARGUMENTS, + PM_ERR_OPERATOR_WRITE_BLOCK, + PM_ERR_PARAMETER_ASSOC_SPLAT_MULTI, + PM_ERR_PARAMETER_BLOCK_MULTI, + PM_ERR_PARAMETER_CIRCULAR, + PM_ERR_PARAMETER_FORWARDING_AFTER_REST, + PM_ERR_PARAMETER_METHOD_NAME, + PM_ERR_PARAMETER_NAME_DUPLICATED, + PM_ERR_PARAMETER_NO_DEFAULT, + PM_ERR_PARAMETER_NO_DEFAULT_KW, + PM_ERR_PARAMETER_NUMBERED_RESERVED, + PM_ERR_PARAMETER_ORDER, + PM_ERR_PARAMETER_SPLAT_MULTI, + PM_ERR_PARAMETER_STAR, + PM_ERR_PARAMETER_UNEXPECTED_FWD, + PM_ERR_PARAMETER_UNEXPECTED_NO_KW, + PM_ERR_PARAMETER_WILD_LOOSE_COMMA, + PM_ERR_PATTERN_ARRAY_MULTIPLE_RESTS, + PM_ERR_PATTERN_CAPTURE_DUPLICATE, + PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET, + PM_ERR_PATTERN_EXPRESSION_AFTER_COMMA, + PM_ERR_PATTERN_EXPRESSION_AFTER_HROCKET, + PM_ERR_PATTERN_EXPRESSION_AFTER_IN, + PM_ERR_PATTERN_EXPRESSION_AFTER_KEY, + PM_ERR_PATTERN_EXPRESSION_AFTER_PAREN, + PM_ERR_PATTERN_EXPRESSION_AFTER_PIN, + PM_ERR_PATTERN_EXPRESSION_AFTER_PIPE, + PM_ERR_PATTERN_EXPRESSION_AFTER_RANGE, + PM_ERR_PATTERN_EXPRESSION_AFTER_REST, + PM_ERR_PATTERN_FIND_MISSING_INNER, + PM_ERR_PATTERN_HASH_IMPLICIT, + PM_ERR_PATTERN_HASH_KEY, + PM_ERR_PATTERN_HASH_KEY_DUPLICATE, + PM_ERR_PATTERN_HASH_KEY_INTERPOLATED, + PM_ERR_PATTERN_HASH_KEY_LABEL, + PM_ERR_PATTERN_HASH_KEY_LOCALS, + PM_ERR_PATTERN_IDENT_AFTER_HROCKET, + PM_ERR_PATTERN_LABEL_AFTER_COMMA, + PM_ERR_PATTERN_REST, + PM_ERR_PATTERN_TERM_BRACE, + PM_ERR_PATTERN_TERM_BRACKET, + PM_ERR_PATTERN_TERM_PAREN, + PM_ERR_PIPEPIPEEQ_MULTI_ASSIGN, + PM_ERR_REGEXP_ENCODING_OPTION_MISMATCH, + PM_ERR_REGEXP_INCOMPAT_CHAR_ENCODING, + PM_ERR_REGEXP_INVALID_UNICODE_RANGE, + PM_ERR_REGEXP_NON_ESCAPED_MBC, + PM_ERR_REGEXP_PARSE_ERROR, + PM_ERR_REGEXP_TERM, + PM_ERR_REGEXP_UNKNOWN_OPTIONS, + PM_ERR_REGEXP_UTF8_CHAR_NON_UTF8_REGEXP, + PM_ERR_RESCUE_EXPRESSION, + PM_ERR_RESCUE_MODIFIER_VALUE, + PM_ERR_RESCUE_TERM, + PM_ERR_RESCUE_VARIABLE, + PM_ERR_RETURN_INVALID, + PM_ERR_SCRIPT_NOT_FOUND, + PM_ERR_SINGLETON_FOR_LITERALS, + PM_ERR_STATEMENT_ALIAS, + PM_ERR_STATEMENT_POSTEXE_END, + PM_ERR_STATEMENT_PREEXE_BEGIN, + PM_ERR_STATEMENT_UNDEF, + PM_ERR_STRING_CONCATENATION, + PM_ERR_STRING_INTERPOLATED_TERM, + PM_ERR_STRING_LITERAL_EOF, + PM_ERR_STRING_LITERAL_TERM, + PM_ERR_SYMBOL_INVALID, + PM_ERR_SYMBOL_TERM_DYNAMIC, + PM_ERR_SYMBOL_TERM_INTERPOLATED, + PM_ERR_TERNARY_COLON, + PM_ERR_TERNARY_EXPRESSION_FALSE, + PM_ERR_TERNARY_EXPRESSION_TRUE, + PM_ERR_UNARY_DISALLOWED, + PM_ERR_UNARY_RECEIVER, + PM_ERR_UNDEF_ARGUMENT, + PM_ERR_UNEXPECTED_BLOCK_ARGUMENT, + PM_ERR_UNEXPECTED_INDEX_BLOCK, + PM_ERR_UNEXPECTED_INDEX_KEYWORDS, + PM_ERR_UNEXPECTED_LABEL, + PM_ERR_UNEXPECTED_MULTI_WRITE, + PM_ERR_UNEXPECTED_RANGE_OPERATOR, + PM_ERR_UNEXPECTED_SAFE_NAVIGATION, + PM_ERR_UNEXPECTED_TOKEN_CLOSE_CONTEXT, + PM_ERR_UNEXPECTED_TOKEN_IGNORE, + PM_ERR_UNTIL_TERM, + PM_ERR_VOID_EXPRESSION, + PM_ERR_WHILE_TERM, + PM_ERR_WRITE_TARGET_IN_METHOD, + PM_ERR_WRITE_TARGET_READONLY, + PM_ERR_WRITE_TARGET_UNEXPECTED, + PM_ERR_XSTRING_TERM, + + // These are the warning diagnostics. + PM_WARN_AMBIGUOUS_BINARY_OPERATOR, + PM_WARN_AMBIGUOUS_FIRST_ARGUMENT_MINUS, + PM_WARN_AMBIGUOUS_FIRST_ARGUMENT_PLUS, + PM_WARN_AMBIGUOUS_PREFIX_AMPERSAND, + PM_WARN_AMBIGUOUS_PREFIX_STAR, + PM_WARN_AMBIGUOUS_PREFIX_STAR_STAR, + PM_WARN_AMBIGUOUS_SLASH, + PM_WARN_COMPARISON_AFTER_COMPARISON, + PM_WARN_DOT_DOT_DOT_EOL, + PM_WARN_EQUAL_IN_CONDITIONAL, + PM_WARN_EQUAL_IN_CONDITIONAL_3_3, + PM_WARN_END_IN_METHOD, + PM_WARN_DUPLICATED_HASH_KEY, + PM_WARN_DUPLICATED_WHEN_CLAUSE, + PM_WARN_FLOAT_OUT_OF_RANGE, + PM_WARN_IGNORED_FROZEN_STRING_LITERAL, + PM_WARN_INDENTATION_MISMATCH, + PM_WARN_INTEGER_IN_FLIP_FLOP, + PM_WARN_INVALID_CHARACTER, + PM_WARN_INVALID_MAGIC_COMMENT_VALUE, + PM_WARN_INVALID_NUMBERED_REFERENCE, + PM_WARN_KEYWORD_EOL, + PM_WARN_LITERAL_IN_CONDITION_DEFAULT, + PM_WARN_LITERAL_IN_CONDITION_VERBOSE, + PM_WARN_SHAREABLE_CONSTANT_VALUE_LINE, + PM_WARN_SHEBANG_CARRIAGE_RETURN, + PM_WARN_UNEXPECTED_CARRIAGE_RETURN, + PM_WARN_UNREACHABLE_STATEMENT, + PM_WARN_UNUSED_LOCAL_VARIABLE, + PM_WARN_VOID_STATEMENT, +} pm_diagnostic_id_t; + +/** + * This struct represents a diagnostic generated during parsing. + * + * @extends pm_list_node_t + */ +typedef struct { + /** The embedded base node. */ + pm_list_node_t node; + + /** The location of the diagnostic in the source. */ + pm_location_t location; + + /** The ID of the diagnostic. */ + pm_diagnostic_id_t diag_id; + + /** The message associated with the diagnostic. */ + const char *message; + + /** + * Whether or not the memory related to the message of this diagnostic is + * owned by this diagnostic. If it is, it needs to be freed when the + * diagnostic is freed. + */ + bool owned; + + /** + * The level of the diagnostic, see `pm_error_level_t` and + * `pm_warning_level_t` for possible values. + */ + uint8_t level; +} pm_diagnostic_t; + +/** + * The levels of errors generated during parsing. + */ +typedef enum { + /** For errors that should raise a syntax error. */ + PM_ERROR_LEVEL_SYNTAX = 0, + + /** For errors that should raise an argument error. */ + PM_ERROR_LEVEL_ARGUMENT = 1, + + /** For errors that should raise a load error. */ + PM_ERROR_LEVEL_LOAD = 2 +} pm_error_level_t; + +/** + * The levels of warnings generated during parsing. + */ +typedef enum { + /** For warnings which should be emitted if $VERBOSE != nil. */ + PM_WARNING_LEVEL_DEFAULT = 0, + + /** For warnings which should be emitted if $VERBOSE == true. */ + PM_WARNING_LEVEL_VERBOSE = 1 +} pm_warning_level_t; + +/** + * Get the human-readable name of the given diagnostic ID. + * + * @param diag_id The diagnostic ID. + * @return The human-readable name of the diagnostic ID. + */ +const char * pm_diagnostic_id_human(pm_diagnostic_id_t diag_id); + +/** + * Append a diagnostic to the given list of diagnostics that is using shared + * memory for its message. + * + * @param list The list to append to. + * @param start The start of the diagnostic. + * @param end The end of the diagnostic. + * @param diag_id The diagnostic ID. + * @return Whether the diagnostic was successfully appended. + */ +bool pm_diagnostic_list_append(pm_list_t *list, const uint8_t *start, const uint8_t *end, pm_diagnostic_id_t diag_id); + +/** + * Append a diagnostic to the given list of diagnostics that is using a format + * string for its message. + * + * @param list The list to append to. + * @param start The start of the diagnostic. + * @param end The end of the diagnostic. + * @param diag_id The diagnostic ID. + * @param ... The arguments to the format string for the message. + * @return Whether the diagnostic was successfully appended. + */ +bool pm_diagnostic_list_append_format(pm_list_t *list, const uint8_t *start, const uint8_t *end, pm_diagnostic_id_t diag_id, ...); + +/** + * Deallocate the internal state of the given diagnostic list. + * + * @param list The list to deallocate. + */ +void pm_diagnostic_list_free(pm_list_t *list); + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/encoding.h b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/encoding.h new file mode 100644 index 00000000..5f772482 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/encoding.h @@ -0,0 +1,283 @@ +/** + * @file encoding.h + * + * The encoding interface and implementations used by the parser. + */ +#ifndef PRISM_ENCODING_H +#define PRISM_ENCODING_H + +#include "prism/defines.h" +#include "prism/util/pm_strncasecmp.h" + +#include +#include +#include +#include + +/** + * This struct defines the functions necessary to implement the encoding + * interface so we can determine how many bytes the subsequent character takes. + * Each callback should return the number of bytes, or 0 if the next bytes are + * invalid for the encoding and type. + */ +typedef struct { + /** + * Return the number of bytes that the next character takes if it is valid + * in the encoding. Does not read more than n bytes. It is assumed that n is + * at least 1. + */ + size_t (*char_width)(const uint8_t *b, ptrdiff_t n); + + /** + * Return the number of bytes that the next character takes if it is valid + * in the encoding and is alphabetical. Does not read more than n bytes. It + * is assumed that n is at least 1. + */ + size_t (*alpha_char)(const uint8_t *b, ptrdiff_t n); + + /** + * Return the number of bytes that the next character takes if it is valid + * in the encoding and is alphanumeric. Does not read more than n bytes. It + * is assumed that n is at least 1. + */ + size_t (*alnum_char)(const uint8_t *b, ptrdiff_t n); + + /** + * Return true if the next character is valid in the encoding and is an + * uppercase character. Does not read more than n bytes. It is assumed that + * n is at least 1. + */ + bool (*isupper_char)(const uint8_t *b, ptrdiff_t n); + + /** + * The name of the encoding. This should correspond to a value that can be + * passed to Encoding.find in Ruby. + */ + const char *name; + + /** + * Return true if the encoding is a multibyte encoding. + */ + bool multibyte; +} pm_encoding_t; + +/** + * All of the lookup tables use the first bit of each embedded byte to indicate + * whether the codepoint is alphabetical. + */ +#define PRISM_ENCODING_ALPHABETIC_BIT 1 << 0 + +/** + * All of the lookup tables use the second bit of each embedded byte to indicate + * whether the codepoint is alphanumeric. + */ +#define PRISM_ENCODING_ALPHANUMERIC_BIT 1 << 1 + +/** + * All of the lookup tables use the third bit of each embedded byte to indicate + * whether the codepoint is uppercase. + */ +#define PRISM_ENCODING_UPPERCASE_BIT 1 << 2 + +/** + * Return the size of the next character in the UTF-8 encoding. + * + * @param b The bytes to read. + * @param n The number of bytes that can be read. + * @returns The number of bytes that the next character takes if it is valid in + * the encoding, or 0 if it is not. + */ +size_t pm_encoding_utf_8_char_width(const uint8_t *b, ptrdiff_t n); + +/** + * Return the size of the next character in the UTF-8 encoding if it is an + * alphabetical character. + * + * @param b The bytes to read. + * @param n The number of bytes that can be read. + * @returns The number of bytes that the next character takes if it is valid in + * the encoding, or 0 if it is not. + */ +size_t pm_encoding_utf_8_alpha_char(const uint8_t *b, ptrdiff_t n); + +/** + * Return the size of the next character in the UTF-8 encoding if it is an + * alphanumeric character. + * + * @param b The bytes to read. + * @param n The number of bytes that can be read. + * @returns The number of bytes that the next character takes if it is valid in + * the encoding, or 0 if it is not. + */ +size_t pm_encoding_utf_8_alnum_char(const uint8_t *b, ptrdiff_t n); + +/** + * Return true if the next character in the UTF-8 encoding if it is an uppercase + * character. + * + * @param b The bytes to read. + * @param n The number of bytes that can be read. + * @returns True if the next character is valid in the encoding and is an + * uppercase character, or false if it is not. + */ +bool pm_encoding_utf_8_isupper_char(const uint8_t *b, ptrdiff_t n); + +/** + * This lookup table is referenced in both the UTF-8 encoding file and the + * parser directly in order to speed up the default encoding processing. It is + * used to indicate whether a character is alphabetical, alphanumeric, or + * uppercase in unicode mappings. + */ +extern const uint8_t pm_encoding_unicode_table[256]; + +/** + * These are all of the encodings that prism supports. + */ +typedef enum { + PM_ENCODING_UTF_8 = 0, + PM_ENCODING_US_ASCII, + PM_ENCODING_ASCII_8BIT, + PM_ENCODING_EUC_JP, + PM_ENCODING_WINDOWS_31J, + +// We optionally support excluding the full set of encodings to only support the +// minimum necessary to process Ruby code without encoding comments. +#ifndef PRISM_ENCODING_EXCLUDE_FULL + PM_ENCODING_BIG5, + PM_ENCODING_BIG5_HKSCS, + PM_ENCODING_BIG5_UAO, + PM_ENCODING_CESU_8, + PM_ENCODING_CP51932, + PM_ENCODING_CP850, + PM_ENCODING_CP852, + PM_ENCODING_CP855, + PM_ENCODING_CP949, + PM_ENCODING_CP950, + PM_ENCODING_CP951, + PM_ENCODING_EMACS_MULE, + PM_ENCODING_EUC_JP_MS, + PM_ENCODING_EUC_JIS_2004, + PM_ENCODING_EUC_KR, + PM_ENCODING_EUC_TW, + PM_ENCODING_GB12345, + PM_ENCODING_GB18030, + PM_ENCODING_GB1988, + PM_ENCODING_GB2312, + PM_ENCODING_GBK, + PM_ENCODING_IBM437, + PM_ENCODING_IBM720, + PM_ENCODING_IBM737, + PM_ENCODING_IBM775, + PM_ENCODING_IBM852, + PM_ENCODING_IBM855, + PM_ENCODING_IBM857, + PM_ENCODING_IBM860, + PM_ENCODING_IBM861, + PM_ENCODING_IBM862, + PM_ENCODING_IBM863, + PM_ENCODING_IBM864, + PM_ENCODING_IBM865, + PM_ENCODING_IBM866, + PM_ENCODING_IBM869, + PM_ENCODING_ISO_8859_1, + PM_ENCODING_ISO_8859_2, + PM_ENCODING_ISO_8859_3, + PM_ENCODING_ISO_8859_4, + PM_ENCODING_ISO_8859_5, + PM_ENCODING_ISO_8859_6, + PM_ENCODING_ISO_8859_7, + PM_ENCODING_ISO_8859_8, + PM_ENCODING_ISO_8859_9, + PM_ENCODING_ISO_8859_10, + PM_ENCODING_ISO_8859_11, + PM_ENCODING_ISO_8859_13, + PM_ENCODING_ISO_8859_14, + PM_ENCODING_ISO_8859_15, + PM_ENCODING_ISO_8859_16, + PM_ENCODING_KOI8_R, + PM_ENCODING_KOI8_U, + PM_ENCODING_MAC_CENT_EURO, + PM_ENCODING_MAC_CROATIAN, + PM_ENCODING_MAC_CYRILLIC, + PM_ENCODING_MAC_GREEK, + PM_ENCODING_MAC_ICELAND, + PM_ENCODING_MAC_JAPANESE, + PM_ENCODING_MAC_ROMAN, + PM_ENCODING_MAC_ROMANIA, + PM_ENCODING_MAC_THAI, + PM_ENCODING_MAC_TURKISH, + PM_ENCODING_MAC_UKRAINE, + PM_ENCODING_SHIFT_JIS, + PM_ENCODING_SJIS_DOCOMO, + PM_ENCODING_SJIS_KDDI, + PM_ENCODING_SJIS_SOFTBANK, + PM_ENCODING_STATELESS_ISO_2022_JP, + PM_ENCODING_STATELESS_ISO_2022_JP_KDDI, + PM_ENCODING_TIS_620, + PM_ENCODING_UTF8_MAC, + PM_ENCODING_UTF8_DOCOMO, + PM_ENCODING_UTF8_KDDI, + PM_ENCODING_UTF8_SOFTBANK, + PM_ENCODING_WINDOWS_1250, + PM_ENCODING_WINDOWS_1251, + PM_ENCODING_WINDOWS_1252, + PM_ENCODING_WINDOWS_1253, + PM_ENCODING_WINDOWS_1254, + PM_ENCODING_WINDOWS_1255, + PM_ENCODING_WINDOWS_1256, + PM_ENCODING_WINDOWS_1257, + PM_ENCODING_WINDOWS_1258, + PM_ENCODING_WINDOWS_874, +#endif + + PM_ENCODING_MAXIMUM +} pm_encoding_type_t; + +/** + * This is the table of all of the encodings that prism supports. + */ +extern const pm_encoding_t pm_encodings[PM_ENCODING_MAXIMUM]; + +/** + * This is the default UTF-8 encoding. We need a reference to it to quickly + * create parsers. + */ +#define PM_ENCODING_UTF_8_ENTRY (&pm_encodings[PM_ENCODING_UTF_8]) + +/** + * This is the US-ASCII encoding. We need a reference to it to be able to + * compare against it when a string is being created because it could possibly + * need to fall back to ASCII-8BIT. + */ +#define PM_ENCODING_US_ASCII_ENTRY (&pm_encodings[PM_ENCODING_US_ASCII]) + +/** + * This is the ASCII-8BIT encoding. We need a reference to it so that pm_strpbrk + * can compare against it because invalid multibyte characters are not a thing + * in this encoding. It is also needed for handling Regexp encoding flags. + */ +#define PM_ENCODING_ASCII_8BIT_ENTRY (&pm_encodings[PM_ENCODING_ASCII_8BIT]) + +/** + * This is the EUC-JP encoding. We need a reference to it to quickly process + * regular expression modifiers. + */ +#define PM_ENCODING_EUC_JP_ENTRY (&pm_encodings[PM_ENCODING_EUC_JP]) + +/** + * This is the Windows-31J encoding. We need a reference to it to quickly + * process regular expression modifiers. + */ +#define PM_ENCODING_WINDOWS_31J_ENTRY (&pm_encodings[PM_ENCODING_WINDOWS_31J]) + +/** + * Parse the given name of an encoding and return a pointer to the corresponding + * encoding struct if one can be found, otherwise return NULL. + * + * @param start A pointer to the first byte of the name. + * @param end A pointer to the last byte of the name. + * @returns A pointer to the encoding struct if one is found, otherwise NULL. + */ +const pm_encoding_t * pm_encoding_find(const uint8_t *start, const uint8_t *end); + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/node.h b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/node.h new file mode 100644 index 00000000..e8686a32 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/node.h @@ -0,0 +1,129 @@ +/** + * @file node.h + * + * Functions related to nodes in the AST. + */ +#ifndef PRISM_NODE_H +#define PRISM_NODE_H + +#include "prism/defines.h" +#include "prism/parser.h" +#include "prism/util/pm_buffer.h" + +/** + * Loop through each node in the node list, writing each node to the given + * pm_node_t pointer. + */ +#define PM_NODE_LIST_FOREACH(list, index, node) \ + for (size_t index = 0; index < (list)->size && ((node) = (list)->nodes[index]); index++) + +/** + * Append a new node onto the end of the node list. + * + * @param list The list to append to. + * @param node The node to append. + */ +void pm_node_list_append(pm_node_list_t *list, pm_node_t *node); + +/** + * Prepend a new node onto the beginning of the node list. + * + * @param list The list to prepend to. + * @param node The node to prepend. + */ +void pm_node_list_prepend(pm_node_list_t *list, pm_node_t *node); + +/** + * Concatenate the given node list onto the end of the other node list. + * + * @param list The list to concatenate onto. + * @param other The list to concatenate. + */ +void pm_node_list_concat(pm_node_list_t *list, pm_node_list_t *other); + +/** + * Free the internal memory associated with the given node list. + * + * @param list The list to free. + */ +void pm_node_list_free(pm_node_list_t *list); + +/** + * Deallocate a node and all of its children. + * + * @param parser The parser that owns the node. + * @param node The node to deallocate. + */ +PRISM_EXPORTED_FUNCTION void pm_node_destroy(pm_parser_t *parser, struct pm_node *node); + +/** + * Returns a string representation of the given node type. + * + * @param node_type The node type to convert to a string. + * @return A string representation of the given node type. + */ +PRISM_EXPORTED_FUNCTION const char * pm_node_type_to_str(pm_node_type_t node_type); + +/** + * Visit each of the nodes in this subtree using the given visitor callback. The + * callback function will be called for each node in the subtree. If it returns + * false, then that node's children will not be visited. If it returns true, + * then the children will be visited. The data parameter is treated as an opaque + * pointer and is passed to the visitor callback for consumers to use as they + * see fit. + * + * As an example: + * + * ```c + * #include "prism.h" + * + * bool visit(const pm_node_t *node, void *data) { + * size_t *indent = (size_t *) data; + * for (size_t i = 0; i < *indent * 2; i++) putc(' ', stdout); + * printf("%s\n", pm_node_type_to_str(node->type)); + * + * size_t next_indent = *indent + 1; + * size_t *next_data = &next_indent; + * pm_visit_child_nodes(node, visit, next_data); + * + * return false; + * } + * + * int main(void) { + * const char *source = "1 + 2; 3 + 4"; + * size_t size = strlen(source); + * + * pm_parser_t parser; + * pm_options_t options = { 0 }; + * pm_parser_init(&parser, (const uint8_t *) source, size, &options); + * + * size_t indent = 0; + * pm_node_t *node = pm_parse(&parser); + * + * size_t *data = &indent; + * pm_visit_node(node, visit, data); + * + * pm_node_destroy(&parser, node); + * pm_parser_free(&parser); + * return EXIT_SUCCESS; + * } + * ``` + * + * @param node The root node to start visiting from. + * @param visitor The callback to call for each node in the subtree. + * @param data An opaque pointer that is passed to the visitor callback. + */ +PRISM_EXPORTED_FUNCTION void pm_visit_node(const pm_node_t *node, bool (*visitor)(const pm_node_t *node, void *data), void *data); + +/** + * Visit the children of the given node with the given callback. This is the + * default behavior for walking the tree that is called from pm_visit_node if + * the callback returns true. + * + * @param node The node to visit the children of. + * @param visitor The callback to call for each child node. + * @param data An opaque pointer that is passed to the visitor callback. + */ +PRISM_EXPORTED_FUNCTION void pm_visit_child_nodes(const pm_node_t *node, bool (*visitor)(const pm_node_t *node, void *data), void *data); + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/options.h b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/options.h new file mode 100644 index 00000000..2f64701b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/options.h @@ -0,0 +1,442 @@ +/** + * @file options.h + * + * The options that can be passed to parsing. + */ +#ifndef PRISM_OPTIONS_H +#define PRISM_OPTIONS_H + +#include "prism/defines.h" +#include "prism/util/pm_char.h" +#include "prism/util/pm_string.h" + +#include +#include +#include + +/** + * String literals should be made frozen. + */ +#define PM_OPTIONS_FROZEN_STRING_LITERAL_DISABLED ((int8_t) -1) + +/** + * String literals may be frozen or mutable depending on the implementation + * default. + */ +#define PM_OPTIONS_FROZEN_STRING_LITERAL_UNSET ((int8_t) 0) + +/** + * String literals should be made mutable. + */ +#define PM_OPTIONS_FROZEN_STRING_LITERAL_ENABLED ((int8_t) 1) + +/** + * A scope of locals surrounding the code that is being parsed. + */ +typedef struct pm_options_scope { + /** The number of locals in the scope. */ + size_t locals_count; + + /** The names of the locals in the scope. */ + pm_string_t *locals; + + /** Flags for the set of forwarding parameters in this scope. */ + uint8_t forwarding; +} pm_options_scope_t; + +/** The default value for parameters. */ +static const uint8_t PM_OPTIONS_SCOPE_FORWARDING_NONE = 0x0; + +/** When the scope is fowarding with the * parameter. */ +static const uint8_t PM_OPTIONS_SCOPE_FORWARDING_POSITIONALS = 0x1; + +/** When the scope is fowarding with the ** parameter. */ +static const uint8_t PM_OPTIONS_SCOPE_FORWARDING_KEYWORDS = 0x2; + +/** When the scope is fowarding with the & parameter. */ +static const uint8_t PM_OPTIONS_SCOPE_FORWARDING_BLOCK = 0x4; + +/** When the scope is fowarding with the ... parameter. */ +static const uint8_t PM_OPTIONS_SCOPE_FORWARDING_ALL = 0x8; + +// Forward declaration needed by the callback typedef. +struct pm_options; + +/** + * The callback called when additional switches are found in a shebang comment + * that need to be processed by the runtime. + * + * @param options The options struct that may be updated by this callback. + * Certain fields will be checked for changes, specifically encoding, + * command_line, and frozen_string_literal. + * @param source The source of the shebang comment. + * @param length The length of the source. + * @param shebang_callback_data Any additional data that should be passed along + * to the callback. + */ +typedef void (*pm_options_shebang_callback_t)(struct pm_options *options, const uint8_t *source, size_t length, void *shebang_callback_data); + +/** + * The version of Ruby syntax that we should be parsing with. This is used to + * allow consumers to specify which behavior they want in case they need to + * parse in the same way as a specific version of CRuby would have. + */ +typedef enum { + /** The current version of prism. */ + PM_OPTIONS_VERSION_LATEST = 0, + + /** The vendored version of prism in CRuby 3.3.x. */ + PM_OPTIONS_VERSION_CRUBY_3_3 = 1, + + /** The vendored version of prism in CRuby 3.4.x. */ + PM_OPTIONS_VERSION_CRUBY_3_4 = 2 +} pm_options_version_t; + +/** + * The options that can be passed to the parser. + */ +typedef struct pm_options { + /** + * The callback to call when additional switches are found in a shebang + * comment. + */ + pm_options_shebang_callback_t shebang_callback; + + /** + * Any additional data that should be passed along to the shebang callback + * if one was set. + */ + void *shebang_callback_data; + + /** The name of the file that is currently being parsed. */ + pm_string_t filepath; + + /** + * The line within the file that the parse starts on. This value is + * 1-indexed. + */ + int32_t line; + + /** + * The name of the encoding that the source file is in. Note that this must + * correspond to a name that can be found with Encoding.find in Ruby. + */ + pm_string_t encoding; + + /** + * The number of scopes surrounding the code that is being parsed. + */ + size_t scopes_count; + + /** + * The scopes surrounding the code that is being parsed. For most parses + * this will be NULL, but for evals it will be the locals that are in scope + * surrounding the eval. Scopes are ordered from the outermost scope to the + * innermost one. + */ + pm_options_scope_t *scopes; + + /** + * The version of prism that we should be parsing with. This is used to + * allow consumers to specify which behavior they want in case they need to + * parse exactly as a specific version of CRuby. + */ + pm_options_version_t version; + + /** A bitset of the various options that were set on the command line. */ + uint8_t command_line; + + /** + * Whether or not the frozen string literal option has been set. + * May be: + * - PM_OPTIONS_FROZEN_STRING_LITERAL_DISABLED + * - PM_OPTIONS_FROZEN_STRING_LITERAL_ENABLED + * - PM_OPTIONS_FROZEN_STRING_LITERAL_UNSET + */ + int8_t frozen_string_literal; + + /** + * Whether or not the encoding magic comments should be respected. This is a + * niche use-case where you want to parse a file with a specific encoding + * but ignore any encoding magic comments at the top of the file. + */ + bool encoding_locked; + + /** + * When the file being parsed is the main script, the shebang will be + * considered for command-line flags (or for implicit -x). The caller needs + * to pass this information to the parser so that it can behave correctly. + */ + bool main_script; + + /** + * When the file being parsed is considered a "partial" script, jumps will + * not be marked as errors if they are not contained within loops/blocks. + * This is used in the case that you're parsing a script that you know will + * be embedded inside another script later, but you do not have that context + * yet. For example, when parsing an ERB template that will be evaluated + * inside another script. + */ + bool partial_script; + + /** + * Whether or not the parser should freeze the nodes that it creates. This + * makes it possible to have a deeply frozen AST that is safe to share + * between concurrency primitives. + */ + bool freeze; +} pm_options_t; + +/** + * A bit representing whether or not the command line -a option was set. -a + * splits the input line $_ into $F. + */ +static const uint8_t PM_OPTIONS_COMMAND_LINE_A = 0x1; + +/** + * A bit representing whether or not the command line -e option was set. -e + * allow the user to specify a script to be executed. This is necessary for + * prism to know because certain warnings are not generated when -e is used. + */ +static const uint8_t PM_OPTIONS_COMMAND_LINE_E = 0x2; + +/** + * A bit representing whether or not the command line -l option was set. -l + * chomps the input line by default. + */ +static const uint8_t PM_OPTIONS_COMMAND_LINE_L = 0x4; + +/** + * A bit representing whether or not the command line -n option was set. -n + * wraps the script in a while gets loop. + */ +static const uint8_t PM_OPTIONS_COMMAND_LINE_N = 0x8; + +/** + * A bit representing whether or not the command line -p option was set. -p + * prints the value of $_ at the end of each loop. + */ +static const uint8_t PM_OPTIONS_COMMAND_LINE_P = 0x10; + +/** + * A bit representing whether or not the command line -x option was set. -x + * searches the input file for a shebang that matches the current Ruby engine. + */ +static const uint8_t PM_OPTIONS_COMMAND_LINE_X = 0x20; + +/** + * Set the shebang callback option on the given options struct. + * + * @param options The options struct to set the shebang callback on. + * @param shebang_callback The shebang callback to set. + * @param shebang_callback_data Any additional data that should be passed along + * to the callback. + */ +PRISM_EXPORTED_FUNCTION void pm_options_shebang_callback_set(pm_options_t *options, pm_options_shebang_callback_t shebang_callback, void *shebang_callback_data); + +/** + * Set the filepath option on the given options struct. + * + * @param options The options struct to set the filepath on. + * @param filepath The filepath to set. + */ +PRISM_EXPORTED_FUNCTION void pm_options_filepath_set(pm_options_t *options, const char *filepath); + +/** + * Set the line option on the given options struct. + * + * @param options The options struct to set the line on. + * @param line The line to set. + */ +PRISM_EXPORTED_FUNCTION void pm_options_line_set(pm_options_t *options, int32_t line); + +/** + * Set the encoding option on the given options struct. + * + * @param options The options struct to set the encoding on. + * @param encoding The encoding to set. + */ +PRISM_EXPORTED_FUNCTION void pm_options_encoding_set(pm_options_t *options, const char *encoding); + +/** + * Set the encoding_locked option on the given options struct. + * + * @param options The options struct to set the encoding_locked value on. + * @param encoding_locked The encoding_locked value to set. + */ +PRISM_EXPORTED_FUNCTION void pm_options_encoding_locked_set(pm_options_t *options, bool encoding_locked); + +/** + * Set the frozen string literal option on the given options struct. + * + * @param options The options struct to set the frozen string literal value on. + * @param frozen_string_literal The frozen string literal value to set. + */ +PRISM_EXPORTED_FUNCTION void pm_options_frozen_string_literal_set(pm_options_t *options, bool frozen_string_literal); + +/** + * Sets the command line option on the given options struct. + * + * @param options The options struct to set the command line option on. + * @param command_line The command_line value to set. + */ +PRISM_EXPORTED_FUNCTION void pm_options_command_line_set(pm_options_t *options, uint8_t command_line); + +/** + * Set the version option on the given options struct by parsing the given + * string. If the string contains an invalid option, this returns false. + * Otherwise, it returns true. + * + * @param options The options struct to set the version on. + * @param version The version to set. + * @param length The length of the version string. + * @return Whether or not the version was parsed successfully. + */ +PRISM_EXPORTED_FUNCTION bool pm_options_version_set(pm_options_t *options, const char *version, size_t length); + +/** + * Set the main script option on the given options struct. + * + * @param options The options struct to set the main script value on. + * @param main_script The main script value to set. + */ +PRISM_EXPORTED_FUNCTION void pm_options_main_script_set(pm_options_t *options, bool main_script); + +/** + * Set the partial script option on the given options struct. + * + * @param options The options struct to set the partial script value on. + * @param partial_script The partial script value to set. + */ +PRISM_EXPORTED_FUNCTION void pm_options_partial_script_set(pm_options_t *options, bool partial_script); + +/** + * Set the freeze option on the given options struct. + * + * @param options The options struct to set the freeze value on. + * @param freeze The freeze value to set. + */ +PRISM_EXPORTED_FUNCTION void pm_options_freeze_set(pm_options_t *options, bool freeze); + +/** + * Allocate and zero out the scopes array on the given options struct. + * + * @param options The options struct to initialize the scopes array on. + * @param scopes_count The number of scopes to allocate. + * @return Whether or not the scopes array was initialized successfully. + */ +PRISM_EXPORTED_FUNCTION bool pm_options_scopes_init(pm_options_t *options, size_t scopes_count); + +/** + * Return a pointer to the scope at the given index within the given options. + * + * @param options The options struct to get the scope from. + * @param index The index of the scope to get. + * @return A pointer to the scope at the given index. + */ +PRISM_EXPORTED_FUNCTION const pm_options_scope_t * pm_options_scope_get(const pm_options_t *options, size_t index); + +/** + * Create a new options scope struct. This will hold a set of locals that are in + * scope surrounding the code that is being parsed. + * + * @param scope The scope struct to initialize. + * @param locals_count The number of locals to allocate. + * @return Whether or not the scope was initialized successfully. + */ +PRISM_EXPORTED_FUNCTION bool pm_options_scope_init(pm_options_scope_t *scope, size_t locals_count); + +/** + * Return a pointer to the local at the given index within the given scope. + * + * @param scope The scope struct to get the local from. + * @param index The index of the local to get. + * @return A pointer to the local at the given index. + */ +PRISM_EXPORTED_FUNCTION const pm_string_t * pm_options_scope_local_get(const pm_options_scope_t *scope, size_t index); + +/** + * Set the forwarding option on the given scope struct. + * + * @param scope The scope struct to set the forwarding on. + * @param forwarding The forwarding value to set. + */ +PRISM_EXPORTED_FUNCTION void pm_options_scope_forwarding_set(pm_options_scope_t *scope, uint8_t forwarding); + +/** + * Free the internal memory associated with the options. + * + * @param options The options struct whose internal memory should be freed. + */ +PRISM_EXPORTED_FUNCTION void pm_options_free(pm_options_t *options); + +/** + * Deserialize an options struct from the given binary string. This is used to + * pass options to the parser from an FFI call so that consumers of the library + * from an FFI perspective don't have to worry about the structure of our + * options structs. Since the source of these calls will be from Ruby + * implementation internals we assume it is from a trusted source. + * + * `data` is assumed to be a valid pointer pointing to well-formed data. The + * layout of this data should be the same every time, and is described below: + * + * | # bytes | field | + * | ------- | -------------------------- | + * | `4` | the length of the filepath | + * | ... | the filepath bytes | + * | `4` | the line number | + * | `4` | the length the encoding | + * | ... | the encoding bytes | + * | `1` | frozen string literal | + * | `1` | -p command line option | + * | `1` | -n command line option | + * | `1` | -l command line option | + * | `1` | -a command line option | + * | `1` | the version | + * | `1` | encoding locked | + * | `1` | main script | + * | `1` | partial script | + * | `1` | freeze | + * | `4` | the number of scopes | + * | ... | the scopes | + * + * The version field is an enum, so it should be one of the following values: + * + * | value | version | + * | ----- | ------------------------- | + * | `0` | use the latest version of prism | + * | `1` | use the version of prism that is vendored in CRuby 3.3.0 | + * + * Each scope is laid out as follows: + * + * | # bytes | field | + * | ------- | -------------------------- | + * | `4` | the number of locals | + * | `1` | the forwarding flags | + * | ... | the locals | + * + * Each local is laid out as follows: + * + * | # bytes | field | + * | ------- | -------------------------- | + * | `4` | the length of the local | + * | ... | the local bytes | + * + * Some additional things to note about this layout: + * + * * The filepath can have a length of 0, in which case we'll consider it an + * empty string. + * * The line number should be 0-indexed. + * * The encoding can have a length of 0, in which case we'll use the default + * encoding (UTF-8). If it's not 0, it should correspond to a name of an + * encoding that can be passed to `Encoding.find` in Ruby. + * * The frozen string literal, encoding locked, main script, and partial script + * fields are booleans, so their values should be either 0 or 1. + * * The number of scopes can be 0. + * + * @param options The options struct to deserialize into. + * @param data The binary string to deserialize from. + */ +void pm_options_read(pm_options_t *options, const char *data); + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/pack.h b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/pack.h new file mode 100644 index 00000000..0b0b4b19 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/pack.h @@ -0,0 +1,163 @@ +/** + * @file pack.h + * + * A pack template string parser. + */ +#ifndef PRISM_PACK_H +#define PRISM_PACK_H + +#include "prism/defines.h" + +// We optionally support parsing String#pack templates. For systems that don't +// want or need this functionality, it can be turned off with the +// PRISM_EXCLUDE_PACK define. +#ifdef PRISM_EXCLUDE_PACK + +void pm_pack_parse(void); + +#else + +#include +#include + +/** The version of the pack template language that we are parsing. */ +typedef enum pm_pack_version { + PM_PACK_VERSION_3_2_0 +} pm_pack_version; + +/** The type of pack template we are parsing. */ +typedef enum pm_pack_variant { + PM_PACK_VARIANT_PACK, + PM_PACK_VARIANT_UNPACK +} pm_pack_variant; + +/** A directive within the pack template. */ +typedef enum pm_pack_type { + PM_PACK_SPACE, + PM_PACK_COMMENT, + PM_PACK_INTEGER, + PM_PACK_UTF8, + PM_PACK_BER, + PM_PACK_FLOAT, + PM_PACK_STRING_SPACE_PADDED, + PM_PACK_STRING_NULL_PADDED, + PM_PACK_STRING_NULL_TERMINATED, + PM_PACK_STRING_MSB, + PM_PACK_STRING_LSB, + PM_PACK_STRING_HEX_HIGH, + PM_PACK_STRING_HEX_LOW, + PM_PACK_STRING_UU, + PM_PACK_STRING_MIME, + PM_PACK_STRING_BASE64, + PM_PACK_STRING_FIXED, + PM_PACK_STRING_POINTER, + PM_PACK_MOVE, + PM_PACK_BACK, + PM_PACK_NULL, + PM_PACK_END +} pm_pack_type; + +/** The signness of a pack directive. */ +typedef enum pm_pack_signed { + PM_PACK_UNSIGNED, + PM_PACK_SIGNED, + PM_PACK_SIGNED_NA +} pm_pack_signed; + +/** The endianness of a pack directive. */ +typedef enum pm_pack_endian { + PM_PACK_AGNOSTIC_ENDIAN, + PM_PACK_LITTLE_ENDIAN, // aka 'VAX', or 'V' + PM_PACK_BIG_ENDIAN, // aka 'network', or 'N' + PM_PACK_NATIVE_ENDIAN, + PM_PACK_ENDIAN_NA +} pm_pack_endian; + +/** The size of an integer pack directive. */ +typedef enum pm_pack_size { + PM_PACK_SIZE_SHORT, + PM_PACK_SIZE_INT, + PM_PACK_SIZE_LONG, + PM_PACK_SIZE_LONG_LONG, + PM_PACK_SIZE_8, + PM_PACK_SIZE_16, + PM_PACK_SIZE_32, + PM_PACK_SIZE_64, + PM_PACK_SIZE_P, + PM_PACK_SIZE_NA +} pm_pack_size; + +/** The type of length of a pack directive. */ +typedef enum pm_pack_length_type { + PM_PACK_LENGTH_FIXED, + PM_PACK_LENGTH_MAX, + PM_PACK_LENGTH_RELATIVE, // special case for unpack @* + PM_PACK_LENGTH_NA +} pm_pack_length_type; + +/** The type of encoding for a pack template string. */ +typedef enum pm_pack_encoding { + PM_PACK_ENCODING_START, + PM_PACK_ENCODING_ASCII_8BIT, + PM_PACK_ENCODING_US_ASCII, + PM_PACK_ENCODING_UTF_8 +} pm_pack_encoding; + +/** The result of parsing a pack template. */ +typedef enum pm_pack_result { + PM_PACK_OK, + PM_PACK_ERROR_UNSUPPORTED_DIRECTIVE, + PM_PACK_ERROR_UNKNOWN_DIRECTIVE, + PM_PACK_ERROR_LENGTH_TOO_BIG, + PM_PACK_ERROR_BANG_NOT_ALLOWED, + PM_PACK_ERROR_DOUBLE_ENDIAN +} pm_pack_result; + +/** + * Parse a single directive from a pack or unpack format string. + * + * @param variant (in) pack or unpack + * @param format (in, out) the start of the next directive to parse on calling, + * and advanced beyond the parsed directive on return, or as much of it as + * was consumed until an error was encountered + * @param format_end (in) the end of the format string + * @param type (out) the type of the directive + * @param signed_type (out) whether the value is signed + * @param endian (out) the endianness of the value + * @param size (out) the size of the value + * @param length_type (out) what kind of length is specified + * @param length (out) the length of the directive + * @param encoding (in, out) takes the current encoding of the string which + * would result from parsing the whole format string, and returns a possibly + * changed directive - the encoding should be `PM_PACK_ENCODING_START` when + * pm_pack_parse is called for the first directive in a format string + * + * @return `PM_PACK_OK` on success or `PM_PACK_ERROR_*` on error + * @note Consult Ruby documentation for the meaning of directives. + */ +PRISM_EXPORTED_FUNCTION pm_pack_result +pm_pack_parse( + pm_pack_variant variant, + const char **format, + const char *format_end, + pm_pack_type *type, + pm_pack_signed *signed_type, + pm_pack_endian *endian, + pm_pack_size *size, + pm_pack_length_type *length_type, + uint64_t *length, + pm_pack_encoding *encoding +); + +/** + * Prism abstracts sizes away from the native system - this converts an abstract + * size to a native size. + * + * @param size The abstract size to convert. + * @return The native size. + */ +PRISM_EXPORTED_FUNCTION size_t pm_size_to_native(pm_pack_size size); + +#endif + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/parser.h b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/parser.h new file mode 100644 index 00000000..992729d6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/parser.h @@ -0,0 +1,933 @@ +/** + * @file parser.h + * + * The parser used to parse Ruby source. + */ +#ifndef PRISM_PARSER_H +#define PRISM_PARSER_H + +#include "prism/defines.h" +#include "prism/ast.h" +#include "prism/encoding.h" +#include "prism/options.h" +#include "prism/static_literals.h" +#include "prism/util/pm_constant_pool.h" +#include "prism/util/pm_list.h" +#include "prism/util/pm_newline_list.h" +#include "prism/util/pm_string.h" + +#include + +/** + * This enum provides various bits that represent different kinds of states that + * the lexer can track. This is used to determine which kind of token to return + * based on the context of the parser. + */ +typedef enum { + PM_LEX_STATE_BIT_BEG, + PM_LEX_STATE_BIT_END, + PM_LEX_STATE_BIT_ENDARG, + PM_LEX_STATE_BIT_ENDFN, + PM_LEX_STATE_BIT_ARG, + PM_LEX_STATE_BIT_CMDARG, + PM_LEX_STATE_BIT_MID, + PM_LEX_STATE_BIT_FNAME, + PM_LEX_STATE_BIT_DOT, + PM_LEX_STATE_BIT_CLASS, + PM_LEX_STATE_BIT_LABEL, + PM_LEX_STATE_BIT_LABELED, + PM_LEX_STATE_BIT_FITEM +} pm_lex_state_bit_t; + +/** + * This enum combines the various bits from the above enum into individual + * values that represent the various states of the lexer. + */ +typedef enum { + PM_LEX_STATE_NONE = 0, + PM_LEX_STATE_BEG = (1 << PM_LEX_STATE_BIT_BEG), + PM_LEX_STATE_END = (1 << PM_LEX_STATE_BIT_END), + PM_LEX_STATE_ENDARG = (1 << PM_LEX_STATE_BIT_ENDARG), + PM_LEX_STATE_ENDFN = (1 << PM_LEX_STATE_BIT_ENDFN), + PM_LEX_STATE_ARG = (1 << PM_LEX_STATE_BIT_ARG), + PM_LEX_STATE_CMDARG = (1 << PM_LEX_STATE_BIT_CMDARG), + PM_LEX_STATE_MID = (1 << PM_LEX_STATE_BIT_MID), + PM_LEX_STATE_FNAME = (1 << PM_LEX_STATE_BIT_FNAME), + PM_LEX_STATE_DOT = (1 << PM_LEX_STATE_BIT_DOT), + PM_LEX_STATE_CLASS = (1 << PM_LEX_STATE_BIT_CLASS), + PM_LEX_STATE_LABEL = (1 << PM_LEX_STATE_BIT_LABEL), + PM_LEX_STATE_LABELED = (1 << PM_LEX_STATE_BIT_LABELED), + PM_LEX_STATE_FITEM = (1 << PM_LEX_STATE_BIT_FITEM), + PM_LEX_STATE_BEG_ANY = PM_LEX_STATE_BEG | PM_LEX_STATE_MID | PM_LEX_STATE_CLASS, + PM_LEX_STATE_ARG_ANY = PM_LEX_STATE_ARG | PM_LEX_STATE_CMDARG, + PM_LEX_STATE_END_ANY = PM_LEX_STATE_END | PM_LEX_STATE_ENDARG | PM_LEX_STATE_ENDFN +} pm_lex_state_t; + +/** + * The type of quote that a heredoc uses. + */ +typedef enum { + PM_HEREDOC_QUOTE_NONE, + PM_HEREDOC_QUOTE_SINGLE = '\'', + PM_HEREDOC_QUOTE_DOUBLE = '"', + PM_HEREDOC_QUOTE_BACKTICK = '`', +} pm_heredoc_quote_t; + +/** + * The type of indentation that a heredoc uses. + */ +typedef enum { + PM_HEREDOC_INDENT_NONE, + PM_HEREDOC_INDENT_DASH, + PM_HEREDOC_INDENT_TILDE, +} pm_heredoc_indent_t; + +/** + * All of the information necessary to store to lexing a heredoc. + */ +typedef struct { + /** A pointer to the start of the heredoc identifier. */ + const uint8_t *ident_start; + + /** The length of the heredoc identifier. */ + size_t ident_length; + + /** The type of quote that the heredoc uses. */ + pm_heredoc_quote_t quote; + + /** The type of indentation that the heredoc uses. */ + pm_heredoc_indent_t indent; +} pm_heredoc_lex_mode_t; + +/** + * When lexing Ruby source, the lexer has a small amount of state to tell which + * kind of token it is currently lexing. For example, when we find the start of + * a string, the first token that we return is a TOKEN_STRING_BEGIN token. After + * that the lexer is now in the PM_LEX_STRING mode, and will return tokens that + * are found as part of a string. + */ +typedef struct pm_lex_mode { + /** The type of this lex mode. */ + enum { + /** This state is used when any given token is being lexed. */ + PM_LEX_DEFAULT, + + /** + * This state is used when we're lexing as normal but inside an embedded + * expression of a string. + */ + PM_LEX_EMBEXPR, + + /** + * This state is used when we're lexing a variable that is embedded + * directly inside of a string with the # shorthand. + */ + PM_LEX_EMBVAR, + + /** This state is used when you are inside the content of a heredoc. */ + PM_LEX_HEREDOC, + + /** + * This state is used when we are lexing a list of tokens, as in a %w + * word list literal or a %i symbol list literal. + */ + PM_LEX_LIST, + + /** + * This state is used when a regular expression has been begun and we + * are looking for the terminator. + */ + PM_LEX_REGEXP, + + /** + * This state is used when we are lexing a string or a string-like + * token, as in string content with either quote or an xstring. + */ + PM_LEX_STRING + } mode; + + /** The data associated with this type of lex mode. */ + union { + struct { + /** This keeps track of the nesting level of the list. */ + size_t nesting; + + /** Whether or not interpolation is allowed in this list. */ + bool interpolation; + + /** + * When lexing a list, it takes into account balancing the + * terminator if the terminator is one of (), [], {}, or <>. + */ + uint8_t incrementor; + + /** This is the terminator of the list literal. */ + uint8_t terminator; + + /** + * This is the character set that should be used to delimit the + * tokens within the list. + */ + uint8_t breakpoints[11]; + } list; + + struct { + /** + * This keeps track of the nesting level of the regular expression. + */ + size_t nesting; + + /** + * When lexing a regular expression, it takes into account balancing + * the terminator if the terminator is one of (), [], {}, or <>. + */ + uint8_t incrementor; + + /** This is the terminator of the regular expression. */ + uint8_t terminator; + + /** + * This is the character set that should be used to delimit the + * tokens within the regular expression. + */ + uint8_t breakpoints[7]; + } regexp; + + struct { + /** This keeps track of the nesting level of the string. */ + size_t nesting; + + /** Whether or not interpolation is allowed in this string. */ + bool interpolation; + + /** + * Whether or not at the end of the string we should allow a :, + * which would indicate this was a dynamic symbol instead of a + * string. + */ + bool label_allowed; + + /** + * When lexing a string, it takes into account balancing the + * terminator if the terminator is one of (), [], {}, or <>. + */ + uint8_t incrementor; + + /** + * This is the terminator of the string. It is typically either a + * single or double quote. + */ + uint8_t terminator; + + /** + * This is the character set that should be used to delimit the + * tokens within the string. + */ + uint8_t breakpoints[7]; + } string; + + struct { + /** + * All of the data necessary to lex a heredoc. + */ + pm_heredoc_lex_mode_t base; + + /** + * This is the pointer to the character where lexing should resume + * once the heredoc has been completely processed. + */ + const uint8_t *next_start; + + /** + * This is used to track the amount of common whitespace on each + * line so that we know how much to dedent each line in the case of + * a tilde heredoc. + */ + size_t *common_whitespace; + + /** True if the previous token ended with a line continuation. */ + bool line_continuation; + } heredoc; + } as; + + /** The previous lex state so that it knows how to pop. */ + struct pm_lex_mode *prev; +} pm_lex_mode_t; + +/** + * We pre-allocate a certain number of lex states in order to avoid having to + * call malloc too many times while parsing. You really shouldn't need more than + * this because you only really nest deeply when doing string interpolation. + */ +#define PM_LEX_STACK_SIZE 4 + +/** + * The parser used to parse Ruby source. + */ +typedef struct pm_parser pm_parser_t; + +/** + * While parsing, we keep track of a stack of contexts. This is helpful for + * error recovery so that we can pop back to a previous context when we hit a + * token that is understood by a parent context but not by the current context. + */ +typedef enum { + /** a null context, used for returning a value from a function */ + PM_CONTEXT_NONE = 0, + + /** a begin statement */ + PM_CONTEXT_BEGIN, + + /** an ensure statement with an explicit begin */ + PM_CONTEXT_BEGIN_ENSURE, + + /** a rescue else statement with an explicit begin */ + PM_CONTEXT_BEGIN_ELSE, + + /** a rescue statement with an explicit begin */ + PM_CONTEXT_BEGIN_RESCUE, + + /** expressions in block arguments using braces */ + PM_CONTEXT_BLOCK_BRACES, + + /** expressions in block arguments using do..end */ + PM_CONTEXT_BLOCK_KEYWORDS, + + /** an ensure statement within a do..end block */ + PM_CONTEXT_BLOCK_ENSURE, + + /** a rescue else statement within a do..end block */ + PM_CONTEXT_BLOCK_ELSE, + + /** a rescue statement within a do..end block */ + PM_CONTEXT_BLOCK_RESCUE, + + /** a case when statements */ + PM_CONTEXT_CASE_WHEN, + + /** a case in statements */ + PM_CONTEXT_CASE_IN, + + /** a class declaration */ + PM_CONTEXT_CLASS, + + /** an ensure statement within a class statement */ + PM_CONTEXT_CLASS_ENSURE, + + /** a rescue else statement within a class statement */ + PM_CONTEXT_CLASS_ELSE, + + /** a rescue statement within a class statement */ + PM_CONTEXT_CLASS_RESCUE, + + /** a method definition */ + PM_CONTEXT_DEF, + + /** an ensure statement within a method definition */ + PM_CONTEXT_DEF_ENSURE, + + /** a rescue else statement within a method definition */ + PM_CONTEXT_DEF_ELSE, + + /** a rescue statement within a method definition */ + PM_CONTEXT_DEF_RESCUE, + + /** a method definition's parameters */ + PM_CONTEXT_DEF_PARAMS, + + /** a defined? expression */ + PM_CONTEXT_DEFINED, + + /** a method definition's default parameter */ + PM_CONTEXT_DEFAULT_PARAMS, + + /** an else clause */ + PM_CONTEXT_ELSE, + + /** an elsif clause */ + PM_CONTEXT_ELSIF, + + /** an interpolated expression */ + PM_CONTEXT_EMBEXPR, + + /** a for loop */ + PM_CONTEXT_FOR, + + /** a for loop's index */ + PM_CONTEXT_FOR_INDEX, + + /** an if statement */ + PM_CONTEXT_IF, + + /** a lambda expression with braces */ + PM_CONTEXT_LAMBDA_BRACES, + + /** a lambda expression with do..end */ + PM_CONTEXT_LAMBDA_DO_END, + + /** an ensure statement within a lambda expression */ + PM_CONTEXT_LAMBDA_ENSURE, + + /** a rescue else statement within a lambda expression */ + PM_CONTEXT_LAMBDA_ELSE, + + /** a rescue statement within a lambda expression */ + PM_CONTEXT_LAMBDA_RESCUE, + + /** the predicate clause of a loop statement */ + PM_CONTEXT_LOOP_PREDICATE, + + /** the top level context */ + PM_CONTEXT_MAIN, + + /** a module declaration */ + PM_CONTEXT_MODULE, + + /** an ensure statement within a module statement */ + PM_CONTEXT_MODULE_ENSURE, + + /** a rescue else statement within a module statement */ + PM_CONTEXT_MODULE_ELSE, + + /** a rescue statement within a module statement */ + PM_CONTEXT_MODULE_RESCUE, + + /** a multiple target expression */ + PM_CONTEXT_MULTI_TARGET, + + /** a parenthesized expression */ + PM_CONTEXT_PARENS, + + /** an END block */ + PM_CONTEXT_POSTEXE, + + /** a predicate inside an if/elsif/unless statement */ + PM_CONTEXT_PREDICATE, + + /** a BEGIN block */ + PM_CONTEXT_PREEXE, + + /** a modifier rescue clause */ + PM_CONTEXT_RESCUE_MODIFIER, + + /** a singleton class definition */ + PM_CONTEXT_SCLASS, + + /** an ensure statement with a singleton class */ + PM_CONTEXT_SCLASS_ENSURE, + + /** a rescue else statement with a singleton class */ + PM_CONTEXT_SCLASS_ELSE, + + /** a rescue statement with a singleton class */ + PM_CONTEXT_SCLASS_RESCUE, + + /** a ternary expression */ + PM_CONTEXT_TERNARY, + + /** an unless statement */ + PM_CONTEXT_UNLESS, + + /** an until statement */ + PM_CONTEXT_UNTIL, + + /** a while statement */ + PM_CONTEXT_WHILE, +} pm_context_t; + +/** This is a node in a linked list of contexts. */ +typedef struct pm_context_node { + /** The context that this node represents. */ + pm_context_t context; + + /** A pointer to the previous context in the linked list. */ + struct pm_context_node *prev; +} pm_context_node_t; + +/** This is the type of a comment that we've found while parsing. */ +typedef enum { + PM_COMMENT_INLINE, + PM_COMMENT_EMBDOC +} pm_comment_type_t; + +/** + * This is a node in the linked list of comments that we've found while parsing. + * + * @extends pm_list_node_t + */ +typedef struct pm_comment { + /** The embedded base node. */ + pm_list_node_t node; + + /** The location of the comment in the source. */ + pm_location_t location; + + /** The type of comment that we've found. */ + pm_comment_type_t type; +} pm_comment_t; + +/** + * This is a node in the linked list of magic comments that we've found while + * parsing. + * + * @extends pm_list_node_t + */ +typedef struct { + /** The embedded base node. */ + pm_list_node_t node; + + /** A pointer to the start of the key in the source. */ + const uint8_t *key_start; + + /** A pointer to the start of the value in the source. */ + const uint8_t *value_start; + + /** The length of the key in the source. */ + uint32_t key_length; + + /** The length of the value in the source. */ + uint32_t value_length; +} pm_magic_comment_t; + +/** + * When the encoding that is being used to parse the source is changed by prism, + * we provide the ability here to call out to a user-defined function. + */ +typedef void (*pm_encoding_changed_callback_t)(pm_parser_t *parser); + +/** + * When you are lexing through a file, the lexer needs all of the information + * that the parser additionally provides (for example, the local table). So if + * you want to properly lex Ruby, you need to actually lex it in the context of + * the parser. In order to provide this functionality, we optionally allow a + * struct to be attached to the parser that calls back out to a user-provided + * callback when each token is lexed. + */ +typedef struct { + /** + * This opaque pointer is used to provide whatever information the user + * deemed necessary to the callback. In our case we use it to pass the array + * that the tokens get appended into. + */ + void *data; + + /** + * This is the callback that is called when a token is lexed. It is passed + * the opaque data pointer, the parser, and the token that was lexed. + */ + void (*callback)(void *data, pm_parser_t *parser, pm_token_t *token); +} pm_lex_callback_t; + +/** The type of shareable constant value that can be set. */ +typedef uint8_t pm_shareable_constant_value_t; +static const pm_shareable_constant_value_t PM_SCOPE_SHAREABLE_CONSTANT_NONE = 0x0; +static const pm_shareable_constant_value_t PM_SCOPE_SHAREABLE_CONSTANT_LITERAL = PM_SHAREABLE_CONSTANT_NODE_FLAGS_LITERAL; +static const pm_shareable_constant_value_t PM_SCOPE_SHAREABLE_CONSTANT_EXPERIMENTAL_EVERYTHING = PM_SHAREABLE_CONSTANT_NODE_FLAGS_EXPERIMENTAL_EVERYTHING; +static const pm_shareable_constant_value_t PM_SCOPE_SHAREABLE_CONSTANT_EXPERIMENTAL_COPY = PM_SHAREABLE_CONSTANT_NODE_FLAGS_EXPERIMENTAL_COPY; + +/** + * This tracks an individual local variable in a certain lexical context, as + * well as the number of times is it read. + */ +typedef struct { + /** The name of the local variable. */ + pm_constant_id_t name; + + /** The location of the local variable in the source. */ + pm_location_t location; + + /** The index of the local variable in the local table. */ + uint32_t index; + + /** The number of times the local variable is read. */ + uint32_t reads; + + /** The hash of the local variable. */ + uint32_t hash; +} pm_local_t; + +/** + * This is a set of local variables in a certain lexical context (method, class, + * module, etc.). We need to track how many times these variables are read in + * order to warn if they only get written. + */ +typedef struct pm_locals { + /** The number of local variables in the set. */ + uint32_t size; + + /** The capacity of the local variables set. */ + uint32_t capacity; + + /** The nullable allocated memory for the local variables in the set. */ + pm_local_t *locals; +} pm_locals_t; + +/** The flags about scope parameters that can be set. */ +typedef uint8_t pm_scope_parameters_t; +static const pm_scope_parameters_t PM_SCOPE_PARAMETERS_NONE = 0x0; +static const pm_scope_parameters_t PM_SCOPE_PARAMETERS_FORWARDING_POSITIONALS = 0x1; +static const pm_scope_parameters_t PM_SCOPE_PARAMETERS_FORWARDING_KEYWORDS = 0x2; +static const pm_scope_parameters_t PM_SCOPE_PARAMETERS_FORWARDING_BLOCK = 0x4; +static const pm_scope_parameters_t PM_SCOPE_PARAMETERS_FORWARDING_ALL = 0x8; +static const pm_scope_parameters_t PM_SCOPE_PARAMETERS_IMPLICIT_DISALLOWED = 0x10; +static const pm_scope_parameters_t PM_SCOPE_PARAMETERS_NUMBERED_INNER = 0x20; +static const pm_scope_parameters_t PM_SCOPE_PARAMETERS_NUMBERED_FOUND = 0x40; + +/** + * This struct represents a node in a linked list of scopes. Some scopes can see + * into their parent scopes, while others cannot. + */ +typedef struct pm_scope { + /** A pointer to the previous scope in the linked list. */ + struct pm_scope *previous; + + /** The IDs of the locals in the given scope. */ + pm_locals_t locals; + + /** + * This is a list of the implicit parameters contained within the block. + * These will be processed after the block is parsed to determine the kind + * of parameters node that should be used and to check if any errors need to + * be added. + */ + pm_node_list_t implicit_parameters; + + /** + * This is a bitfield that indicates the parameters that are being used in + * this scope. It is a combination of the PM_SCOPE_PARAMETERS_* constants. + * There are three different kinds of parameters that can be used in a + * scope: + * + * - Ordinary parameters (e.g., def foo(bar); end) + * - Numbered parameters (e.g., def foo; _1; end) + * - The it parameter (e.g., def foo; it; end) + * + * If ordinary parameters are being used, then certain parameters can be + * forwarded to another method/structure. Those are indicated by four + * additional bits in the params field. For example, some combinations of: + * + * - def foo(*); end + * - def foo(**); end + * - def foo(&); end + * - def foo(...); end + */ + pm_scope_parameters_t parameters; + + /** + * The current state of constant shareability for this scope. This is + * changed by magic shareable_constant_value comments. + */ + pm_shareable_constant_value_t shareable_constant; + + /** + * A boolean indicating whether or not this scope can see into its parent. + * If closed is true, then the scope cannot see into its parent. + */ + bool closed; +} pm_scope_t; + +/** + * A struct that represents a stack of boolean values. + */ +typedef uint32_t pm_state_stack_t; + +/** + * This struct represents the overall parser. It contains a reference to the + * source file, as well as pointers that indicate where in the source it's + * currently parsing. It also contains the most recent and current token that + * it's considering. + */ +struct pm_parser { + /** + * The next node identifier that will be assigned. This is a unique + * identifier used to track nodes such that the syntax tree can be dropped + * but the node can be found through another parse. + */ + uint32_t node_id; + + /** The current state of the lexer. */ + pm_lex_state_t lex_state; + + /** Tracks the current nesting of (), [], and {}. */ + int enclosure_nesting; + + /** + * Used to temporarily track the nesting of enclosures to determine if a { + * is the beginning of a lambda following the parameters of a lambda. + */ + int lambda_enclosure_nesting; + + /** + * Used to track the nesting of braces to ensure we get the correct value + * when we are interpolating blocks with braces. + */ + int brace_nesting; + + /** + * The stack used to determine if a do keyword belongs to the predicate of a + * while, until, or for loop. + */ + pm_state_stack_t do_loop_stack; + + /** + * The stack used to determine if a do keyword belongs to the beginning of a + * block. + */ + pm_state_stack_t accepts_block_stack; + + /** A stack of lex modes. */ + struct { + /** The current mode of the lexer. */ + pm_lex_mode_t *current; + + /** The stack of lexer modes. */ + pm_lex_mode_t stack[PM_LEX_STACK_SIZE]; + + /** The current index into the lexer mode stack. */ + size_t index; + } lex_modes; + + /** The pointer to the start of the source. */ + const uint8_t *start; + + /** The pointer to the end of the source. */ + const uint8_t *end; + + /** The previous token we were considering. */ + pm_token_t previous; + + /** The current token we're considering. */ + pm_token_t current; + + /** + * This is a special field set on the parser when we need the parser to jump + * to a specific location when lexing the next token, as opposed to just + * using the end of the previous token. Normally this is NULL. + */ + const uint8_t *next_start; + + /** + * This field indicates the end of a heredoc whose identifier was found on + * the current line. If another heredoc is found on the same line, then this + * will be moved forward to the end of that heredoc. If no heredocs are + * found on a line then this is NULL. + */ + const uint8_t *heredoc_end; + + /** The list of comments that have been found while parsing. */ + pm_list_t comment_list; + + /** The list of magic comments that have been found while parsing. */ + pm_list_t magic_comment_list; + + /** + * An optional location that represents the location of the __END__ marker + * and the rest of the content of the file. This content is loaded into the + * DATA constant when the file being parsed is the main file being executed. + */ + pm_location_t data_loc; + + /** The list of warnings that have been found while parsing. */ + pm_list_t warning_list; + + /** The list of errors that have been found while parsing. */ + pm_list_t error_list; + + /** The current local scope. */ + pm_scope_t *current_scope; + + /** The current parsing context. */ + pm_context_node_t *current_context; + + /** + * The hash keys for the hash that is currently being parsed. This is not + * usually necessary because it can pass it down the various call chains, + * but in the event that you're parsing a hash that is being directly + * pushed into another hash with **, we need to share the hash keys so that + * we can warn for the nested hash as well. + */ + pm_static_literals_t *current_hash_keys; + + /** + * The encoding functions for the current file is attached to the parser as + * it's parsing so that it can change with a magic comment. + */ + const pm_encoding_t *encoding; + + /** + * When the encoding that is being used to parse the source is changed by + * prism, we provide the ability here to call out to a user-defined + * function. + */ + pm_encoding_changed_callback_t encoding_changed_callback; + + /** + * This pointer indicates where a comment must start if it is to be + * considered an encoding comment. + */ + const uint8_t *encoding_comment_start; + + /** + * This is an optional callback that can be attached to the parser that will + * be called whenever a new token is lexed by the parser. + */ + pm_lex_callback_t *lex_callback; + + /** + * This is the path of the file being parsed. We use the filepath when + * constructing SourceFileNodes. + */ + pm_string_t filepath; + + /** + * This constant pool keeps all of the constants defined throughout the file + * so that we can reference them later. + */ + pm_constant_pool_t constant_pool; + + /** This is the list of newline offsets in the source file. */ + pm_newline_list_t newline_list; + + /** + * We want to add a flag to integer nodes that indicates their base. We only + * want to parse these once, but we don't have space on the token itself to + * communicate this information. So we store it here and pass it through + * when we find tokens that we need it for. + */ + pm_node_flags_t integer_base; + + /** + * This string is used to pass information from the lexer to the parser. It + * is particularly necessary because of escape sequences. + */ + pm_string_t current_string; + + /** + * The line number at the start of the parse. This will be used to offset + * the line numbers of all of the locations. + */ + int32_t start_line; + + /** + * When a string-like expression is being lexed, any byte or escape sequence + * that resolves to a value whose top bit is set (i.e., >= 0x80) will + * explicitly set the encoding to the same encoding as the source. + * Alternatively, if a unicode escape sequence is used (e.g., \\u{80}) that + * resolves to a value whose top bit is set, then the encoding will be + * explicitly set to UTF-8. + * + * The _next_ time this happens, if the encoding that is about to become the + * explicitly set encoding does not match the previously set explicit + * encoding, a mixed encoding error will be emitted. + * + * When the expression is finished being lexed, the explicit encoding + * controls the encoding of the expression. For the most part this means + * that the expression will either be encoded in the source encoding or + * UTF-8. This holds for all encodings except US-ASCII. If the source is + * US-ASCII and an explicit encoding was set that was _not_ UTF-8, then the + * expression will be encoded as ASCII-8BIT. + * + * Note that if the expression is a list, different elements within the same + * list can have different encodings, so this will get reset between each + * element. Furthermore all of this only applies to lists that support + * interpolation, because otherwise escapes that could change the encoding + * are ignored. + * + * At first glance, it may make more sense for this to live on the lexer + * mode, but we need it here to communicate back to the parser for character + * literals that do not push a new lexer mode. + */ + const pm_encoding_t *explicit_encoding; + + /** + * When parsing block exits (e.g., break, next, redo), we need to validate + * that they are in correct contexts. For the most part we can do this by + * looking at our parent contexts. However, modifier while and until + * expressions can change that context to make block exits valid. In these + * cases, we need to keep track of the block exits and then validate them + * after the expression has been parsed. + * + * We use a pointer here because we don't want to keep a whole list attached + * since this will only be used in the context of begin/end expressions. + */ + pm_node_list_t *current_block_exits; + + /** The version of prism that we should use to parse. */ + pm_options_version_t version; + + /** The command line flags given from the options. */ + uint8_t command_line; + + /** + * Whether or not we have found a frozen_string_literal magic comment with + * a true or false value. + * May be: + * - PM_OPTIONS_FROZEN_STRING_LITERAL_DISABLED + * - PM_OPTIONS_FROZEN_STRING_LITERAL_ENABLED + * - PM_OPTIONS_FROZEN_STRING_LITERAL_UNSET + */ + int8_t frozen_string_literal; + + /** + * Whether or not we are parsing an eval string. This impacts whether or not + * we should evaluate if block exits/yields are valid. + */ + bool parsing_eval; + + /** + * Whether or not we are parsing a "partial" script, which is a script that + * will be evaluated in the context of another script, so we should not + * check jumps (next/break/etc.) for validity. + */ + bool partial_script; + + /** Whether or not we're at the beginning of a command. */ + bool command_start; + + /** Whether or not we're currently recovering from a syntax error. */ + bool recovering; + + /** + * This is very specialized behavior for when you want to parse in a context + * that does not respect encoding comments. Its main use case is translating + * into the whitequark/parser AST which re-encodes source files in UTF-8 + * before they are parsed and ignores encoding comments. + */ + bool encoding_locked; + + /** + * Whether or not the encoding has been changed by a magic comment. We use + * this to provide a fast path for the lexer instead of going through the + * function pointer. + */ + bool encoding_changed; + + /** + * This flag indicates that we are currently parsing a pattern matching + * expression and impacts that calculation of newlines. + */ + bool pattern_matching_newlines; + + /** This flag indicates that we are currently parsing a keyword argument. */ + bool in_keyword_arg; + + /** + * Whether or not the parser has seen a token that has semantic meaning + * (i.e., a token that is not a comment or whitespace). + */ + bool semantic_token_seen; + + /** + * True if the current regular expression being lexed contains only ASCII + * characters. + */ + bool current_regular_expression_ascii_only; + + /** + * By default, Ruby always warns about mismatched indentation. This can be + * toggled with a magic comment. + */ + bool warn_mismatched_indentation; +}; + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/prettyprint.h b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/prettyprint.h new file mode 100644 index 00000000..5a52b2b6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/prettyprint.h @@ -0,0 +1,34 @@ +/** + * @file prettyprint.h + * + * An AST node pretty-printer. + */ +#ifndef PRISM_PRETTYPRINT_H +#define PRISM_PRETTYPRINT_H + +#include "prism/defines.h" + +#ifdef PRISM_EXCLUDE_PRETTYPRINT + +void pm_prettyprint(void); + +#else + +#include + +#include "prism/ast.h" +#include "prism/parser.h" +#include "prism/util/pm_buffer.h" + +/** + * Pretty-prints the AST represented by the given node to the given buffer. + * + * @param output_buffer The buffer to write the pretty-printed AST to. + * @param parser The parser that parsed the AST. + * @param node The root node of the AST to pretty-print. + */ +PRISM_EXPORTED_FUNCTION void pm_prettyprint(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_node_t *node); + +#endif + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/regexp.h b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/regexp.h new file mode 100644 index 00000000..c0b3163e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/regexp.h @@ -0,0 +1,43 @@ +/** + * @file regexp.h + * + * A regular expression parser. + */ +#ifndef PRISM_REGEXP_H +#define PRISM_REGEXP_H + +#include "prism/defines.h" +#include "prism/parser.h" +#include "prism/encoding.h" +#include "prism/util/pm_memchr.h" +#include "prism/util/pm_string.h" + +#include +#include +#include + +/** + * This callback is called when a named capture group is found. + */ +typedef void (*pm_regexp_name_callback_t)(const pm_string_t *name, void *data); + +/** + * This callback is called when a parse error is found. + */ +typedef void (*pm_regexp_error_callback_t)(const uint8_t *start, const uint8_t *end, const char *message, void *data); + +/** + * Parse a regular expression. + * + * @param parser The parser that is currently being used. + * @param source The source code to parse. + * @param size The size of the source code. + * @param extended_mode Whether to parse the regular expression in extended mode. + * @param name_callback The optional callback to call when a named capture group is found. + * @param name_data The optional data to pass to the name callback. + * @param error_callback The callback to call when a parse error is found. + * @param error_data The data to pass to the error callback. + */ +PRISM_EXPORTED_FUNCTION void pm_regexp_parse(pm_parser_t *parser, const uint8_t *source, size_t size, bool extended_mode, pm_regexp_name_callback_t name_callback, void *name_data, pm_regexp_error_callback_t error_callback, void *error_data); + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/static_literals.h b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/static_literals.h new file mode 100644 index 00000000..bd297618 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/static_literals.h @@ -0,0 +1,121 @@ +/** + * @file static_literals.h + * + * A set of static literal nodes that can be checked for duplicates. + */ +#ifndef PRISM_STATIC_LITERALS_H +#define PRISM_STATIC_LITERALS_H + +#include "prism/defines.h" +#include "prism/ast.h" +#include "prism/util/pm_newline_list.h" + +#include +#include + +/** + * An internal hash table for a set of nodes. + */ +typedef struct { + /** The array of nodes in the hash table. */ + pm_node_t **nodes; + + /** The size of the hash table. */ + uint32_t size; + + /** The space that has been allocated in the hash table. */ + uint32_t capacity; +} pm_node_hash_t; + +/** + * Certain sets of nodes (hash keys and when clauses) check for duplicate nodes + * to alert the user of potential issues. To do this, we keep a set of the nodes + * that have been seen so far, and compare whenever we find a new node. + * + * We bucket the nodes based on their type to minimize the number of comparisons + * that need to be performed. + */ +typedef struct { + /** + * This is the set of IntegerNode and SourceLineNode instances. + */ + pm_node_hash_t integer_nodes; + + /** + * This is the set of FloatNode instances. + */ + pm_node_hash_t float_nodes; + + /** + * This is the set of RationalNode and ImaginaryNode instances. + */ + pm_node_hash_t number_nodes; + + /** + * This is the set of StringNode and SourceFileNode instances. + */ + pm_node_hash_t string_nodes; + + /** + * This is the set of RegularExpressionNode instances. + */ + pm_node_hash_t regexp_nodes; + + /** + * This is the set of SymbolNode instances. + */ + pm_node_hash_t symbol_nodes; + + /** + * A pointer to the last TrueNode instance that was inserted, or NULL. + */ + pm_node_t *true_node; + + /** + * A pointer to the last FalseNode instance that was inserted, or NULL. + */ + pm_node_t *false_node; + + /** + * A pointer to the last NilNode instance that was inserted, or NULL. + */ + pm_node_t *nil_node; + + /** + * A pointer to the last SourceEncodingNode instance that was inserted, or + * NULL. + */ + pm_node_t *source_encoding_node; +} pm_static_literals_t; + +/** + * Add a node to the set of static literals. + * + * @param newline_list The list of newline offsets to use to calculate lines. + * @param start_line The line number that the parser starts on. + * @param literals The set of static literals to add the node to. + * @param node The node to add to the set. + * @param replace Whether to replace the previous node if one already exists. + * @return A pointer to the node that is being overwritten, if there is one. + */ +pm_node_t * pm_static_literals_add(const pm_newline_list_t *newline_list, int32_t start_line, pm_static_literals_t *literals, pm_node_t *node, bool replace); + +/** + * Free the internal memory associated with the given static literals set. + * + * @param literals The set of static literals to free. + */ +void pm_static_literals_free(pm_static_literals_t *literals); + +/** + * Create a string-based representation of the given static literal. + * + * @param buffer The buffer to write the string to. + * @param newline_list The list of newline offsets to use to calculate lines. + * @param start_line The line number that the parser starts on. + * @param encoding_name The name of the encoding of the source being parsed. + * @param node The node to create a string representation of. + */ +void pm_static_literal_inspect(pm_buffer_t *buffer, const pm_newline_list_t *newline_list, int32_t start_line, const char *encoding_name, const pm_node_t *node); + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_buffer.h b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_buffer.h new file mode 100644 index 00000000..f3c20ab2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_buffer.h @@ -0,0 +1,228 @@ +/** + * @file pm_buffer.h + * + * A wrapper around a contiguous block of allocated memory. + */ +#ifndef PRISM_BUFFER_H +#define PRISM_BUFFER_H + +#include "prism/defines.h" +#include "prism/util/pm_char.h" + +#include +#include +#include +#include +#include + +/** + * A pm_buffer_t is a simple memory buffer that stores data in a contiguous + * block of memory. + */ +typedef struct { + /** The length of the buffer in bytes. */ + size_t length; + + /** The capacity of the buffer in bytes that has been allocated. */ + size_t capacity; + + /** A pointer to the start of the buffer. */ + char *value; +} pm_buffer_t; + +/** + * Return the size of the pm_buffer_t struct. + * + * @returns The size of the pm_buffer_t struct. + */ +PRISM_EXPORTED_FUNCTION size_t pm_buffer_sizeof(void); + +/** + * Initialize a pm_buffer_t with the given capacity. + * + * @param buffer The buffer to initialize. + * @param capacity The capacity of the buffer. + * @returns True if the buffer was initialized successfully, false otherwise. + */ +bool pm_buffer_init_capacity(pm_buffer_t *buffer, size_t capacity); + +/** + * Initialize a pm_buffer_t with its default values. + * + * @param buffer The buffer to initialize. + * @returns True if the buffer was initialized successfully, false otherwise. + */ +PRISM_EXPORTED_FUNCTION bool pm_buffer_init(pm_buffer_t *buffer); + +/** + * Return the value of the buffer. + * + * @param buffer The buffer to get the value of. + * @returns The value of the buffer. + */ +PRISM_EXPORTED_FUNCTION char * pm_buffer_value(const pm_buffer_t *buffer); + +/** + * Return the length of the buffer. + * + * @param buffer The buffer to get the length of. + * @returns The length of the buffer. + */ +PRISM_EXPORTED_FUNCTION size_t pm_buffer_length(const pm_buffer_t *buffer); + +/** + * Append the given amount of space as zeroes to the buffer. + * + * @param buffer The buffer to append to. + * @param length The amount of space to append and zero. + */ +void pm_buffer_append_zeroes(pm_buffer_t *buffer, size_t length); + +/** + * Append a formatted string to the buffer. + * + * @param buffer The buffer to append to. + * @param format The format string to append. + * @param ... The arguments to the format string. + */ +void pm_buffer_append_format(pm_buffer_t *buffer, const char *format, ...) PRISM_ATTRIBUTE_FORMAT(2, 3); + +/** + * Append a string to the buffer. + * + * @param buffer The buffer to append to. + * @param value The string to append. + * @param length The length of the string to append. + */ +void pm_buffer_append_string(pm_buffer_t *buffer, const char *value, size_t length); + +/** + * Append a list of bytes to the buffer. + * + * @param buffer The buffer to append to. + * @param value The bytes to append. + * @param length The length of the bytes to append. + */ +void pm_buffer_append_bytes(pm_buffer_t *buffer, const uint8_t *value, size_t length); + +/** + * Append a single byte to the buffer. + * + * @param buffer The buffer to append to. + * @param value The byte to append. + */ +void pm_buffer_append_byte(pm_buffer_t *buffer, uint8_t value); + +/** + * Append a 32-bit unsigned integer to the buffer as a variable-length integer. + * + * @param buffer The buffer to append to. + * @param value The integer to append. + */ +void pm_buffer_append_varuint(pm_buffer_t *buffer, uint32_t value); + +/** + * Append a 32-bit signed integer to the buffer as a variable-length integer. + * + * @param buffer The buffer to append to. + * @param value The integer to append. + */ +void pm_buffer_append_varsint(pm_buffer_t *buffer, int32_t value); + +/** + * Append a double to the buffer. + * + * @param buffer The buffer to append to. + * @param value The double to append. + */ +void pm_buffer_append_double(pm_buffer_t *buffer, double value); + +/** + * Append a unicode codepoint to the buffer. + * + * @param buffer The buffer to append to. + * @param value The character to append. + * @returns True if the codepoint was valid and appended successfully, false + * otherwise. + */ +bool pm_buffer_append_unicode_codepoint(pm_buffer_t *buffer, uint32_t value); + +/** + * The different types of escaping that can be performed by the buffer when + * appending a slice of Ruby source code. + */ +typedef enum { + PM_BUFFER_ESCAPING_RUBY, + PM_BUFFER_ESCAPING_JSON +} pm_buffer_escaping_t; + +/** + * Append a slice of source code to the buffer. + * + * @param buffer The buffer to append to. + * @param source The source code to append. + * @param length The length of the source code to append. + * @param escaping The type of escaping to perform. + */ +void pm_buffer_append_source(pm_buffer_t *buffer, const uint8_t *source, size_t length, pm_buffer_escaping_t escaping); + +/** + * Prepend the given string to the buffer. + * + * @param buffer The buffer to prepend to. + * @param value The string to prepend. + * @param length The length of the string to prepend. + */ +void pm_buffer_prepend_string(pm_buffer_t *buffer, const char *value, size_t length); + +/** + * Concatenate one buffer onto another. + * + * @param destination The buffer to concatenate onto. + * @param source The buffer to concatenate. + */ +void pm_buffer_concat(pm_buffer_t *destination, const pm_buffer_t *source); + +/** + * Clear the buffer by reducing its size to 0. This does not free the allocated + * memory, but it does allow the buffer to be reused. + * + * @param buffer The buffer to clear. + */ +void pm_buffer_clear(pm_buffer_t *buffer); + +/** + * Strip the whitespace from the end of the buffer. + * + * @param buffer The buffer to strip. + */ +void pm_buffer_rstrip(pm_buffer_t *buffer); + +/** + * Checks if the buffer includes the given value. + * + * @param buffer The buffer to check. + * @param value The value to check for. + * @returns The index of the first occurrence of the value in the buffer, or + * SIZE_MAX if the value is not found. + */ +size_t pm_buffer_index(const pm_buffer_t *buffer, char value); + +/** + * Insert the given string into the buffer at the given index. + * + * @param buffer The buffer to insert into. + * @param index The index to insert at. + * @param value The string to insert. + * @param length The length of the string to insert. + */ +void pm_buffer_insert(pm_buffer_t *buffer, size_t index, const char *value, size_t length); + +/** + * Free the memory associated with the buffer. + * + * @param buffer The buffer to free. + */ +PRISM_EXPORTED_FUNCTION void pm_buffer_free(pm_buffer_t *buffer); + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_char.h b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_char.h new file mode 100644 index 00000000..deeafd63 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_char.h @@ -0,0 +1,204 @@ +/** + * @file pm_char.h + * + * Functions for working with characters and strings. + */ +#ifndef PRISM_CHAR_H +#define PRISM_CHAR_H + +#include "prism/defines.h" +#include "prism/util/pm_newline_list.h" + +#include +#include + +/** + * Returns the number of characters at the start of the string that are + * whitespace. Disallows searching past the given maximum number of characters. + * + * @param string The string to search. + * @param length The maximum number of characters to search. + * @return The number of characters at the start of the string that are + * whitespace. + */ +size_t pm_strspn_whitespace(const uint8_t *string, ptrdiff_t length); + +/** + * Returns the number of characters at the start of the string that are + * whitespace while also tracking the location of each newline. Disallows + * searching past the given maximum number of characters. + * + * @param string The string to search. + * @param length The maximum number of characters to search. + * @param newline_list The list of newlines to populate. + * @return The number of characters at the start of the string that are + * whitespace. + */ +size_t pm_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length, pm_newline_list_t *newline_list); + +/** + * Returns the number of characters at the start of the string that are inline + * whitespace. Disallows searching past the given maximum number of characters. + * + * @param string The string to search. + * @param length The maximum number of characters to search. + * @return The number of characters at the start of the string that are inline + * whitespace. + */ +size_t pm_strspn_inline_whitespace(const uint8_t *string, ptrdiff_t length); + +/** + * Returns the number of characters at the start of the string that are decimal + * digits. Disallows searching past the given maximum number of characters. + * + * @param string The string to search. + * @param length The maximum number of characters to search. + * @return The number of characters at the start of the string that are decimal + * digits. + */ +size_t pm_strspn_decimal_digit(const uint8_t *string, ptrdiff_t length); + +/** + * Returns the number of characters at the start of the string that are + * hexadecimal digits. Disallows searching past the given maximum number of + * characters. + * + * @param string The string to search. + * @param length The maximum number of characters to search. + * @return The number of characters at the start of the string that are + * hexadecimal digits. + */ +size_t pm_strspn_hexadecimal_digit(const uint8_t *string, ptrdiff_t length); + +/** + * Returns the number of characters at the start of the string that are octal + * digits or underscores. Disallows searching past the given maximum number of + * characters. + * + * If multiple underscores are found in a row or if an underscore is + * found at the end of the number, then the invalid pointer is set to the index + * of the first invalid underscore. + * + * @param string The string to search. + * @param length The maximum number of characters to search. + * @param invalid The pointer to set to the index of the first invalid + * underscore. + * @return The number of characters at the start of the string that are octal + * digits or underscores. + */ +size_t pm_strspn_octal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid); + +/** + * Returns the number of characters at the start of the string that are decimal + * digits or underscores. Disallows searching past the given maximum number of + * characters. + * + * If multiple underscores are found in a row or if an underscore is + * found at the end of the number, then the invalid pointer is set to the index + * of the first invalid underscore. + * + * @param string The string to search. + * @param length The maximum number of characters to search. + * @param invalid The pointer to set to the index of the first invalid + * underscore. + * @return The number of characters at the start of the string that are decimal + * digits or underscores. + */ +size_t pm_strspn_decimal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid); + +/** + * Returns the number of characters at the start of the string that are + * hexadecimal digits or underscores. Disallows searching past the given maximum + * number of characters. + * + * If multiple underscores are found in a row or if an underscore is + * found at the end of the number, then the invalid pointer is set to the index + * of the first invalid underscore. + * + * @param string The string to search. + * @param length The maximum number of characters to search. + * @param invalid The pointer to set to the index of the first invalid + * underscore. + * @return The number of characters at the start of the string that are + * hexadecimal digits or underscores. + */ +size_t pm_strspn_hexadecimal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid); + +/** + * Returns the number of characters at the start of the string that are regexp + * options. Disallows searching past the given maximum number of characters. + * + * @param string The string to search. + * @param length The maximum number of characters to search. + * @return The number of characters at the start of the string that are regexp + * options. + */ +size_t pm_strspn_regexp_option(const uint8_t *string, ptrdiff_t length); + +/** + * Returns the number of characters at the start of the string that are binary + * digits or underscores. Disallows searching past the given maximum number of + * characters. + * + * If multiple underscores are found in a row or if an underscore is + * found at the end of the number, then the invalid pointer is set to the index + * of the first invalid underscore. + * + * @param string The string to search. + * @param length The maximum number of characters to search. + * @param invalid The pointer to set to the index of the first invalid + * underscore. + * @return The number of characters at the start of the string that are binary + * digits or underscores. + */ +size_t pm_strspn_binary_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid); + +/** + * Returns true if the given character is a whitespace character. + * + * @param b The character to check. + * @return True if the given character is a whitespace character. + */ +bool pm_char_is_whitespace(const uint8_t b); + +/** + * Returns true if the given character is an inline whitespace character. + * + * @param b The character to check. + * @return True if the given character is an inline whitespace character. + */ +bool pm_char_is_inline_whitespace(const uint8_t b); + +/** + * Returns true if the given character is a binary digit. + * + * @param b The character to check. + * @return True if the given character is a binary digit. + */ +bool pm_char_is_binary_digit(const uint8_t b); + +/** + * Returns true if the given character is an octal digit. + * + * @param b The character to check. + * @return True if the given character is an octal digit. + */ +bool pm_char_is_octal_digit(const uint8_t b); + +/** + * Returns true if the given character is a decimal digit. + * + * @param b The character to check. + * @return True if the given character is a decimal digit. + */ +bool pm_char_is_decimal_digit(const uint8_t b); + +/** + * Returns true if the given character is a hexadecimal digit. + * + * @param b The character to check. + * @return True if the given character is a hexadecimal digit. + */ +bool pm_char_is_hexadecimal_digit(const uint8_t b); + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_constant_pool.h b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_constant_pool.h new file mode 100644 index 00000000..6df23f8f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_constant_pool.h @@ -0,0 +1,218 @@ +/** + * @file pm_constant_pool.h + * + * A data structure that stores a set of strings. + * + * Each string is assigned a unique id, which can be used to compare strings for + * equality. This comparison ends up being much faster than strcmp, since it + * only requires a single integer comparison. + */ +#ifndef PRISM_CONSTANT_POOL_H +#define PRISM_CONSTANT_POOL_H + +#include "prism/defines.h" + +#include +#include +#include +#include +#include + +/** + * When we allocate constants into the pool, we reserve 0 to mean that the slot + * is not yet filled. This constant is reused in other places to indicate the + * lack of a constant id. + */ +#define PM_CONSTANT_ID_UNSET 0 + +/** + * A constant id is a unique identifier for a constant in the constant pool. + */ +typedef uint32_t pm_constant_id_t; + +/** + * A list of constant IDs. Usually used to represent a set of locals. + */ +typedef struct { + /** The number of constant ids in the list. */ + size_t size; + + /** The number of constant ids that have been allocated in the list. */ + size_t capacity; + + /** The constant ids in the list. */ + pm_constant_id_t *ids; +} pm_constant_id_list_t; + +/** + * Initialize a list of constant ids. + * + * @param list The list to initialize. + */ +void pm_constant_id_list_init(pm_constant_id_list_t *list); + +/** + * Initialize a list of constant ids with a given capacity. + * + * @param list The list to initialize. + * @param capacity The initial capacity of the list. + */ +void pm_constant_id_list_init_capacity(pm_constant_id_list_t *list, size_t capacity); + +/** + * Append a constant id to a list of constant ids. Returns false if any + * potential reallocations fail. + * + * @param list The list to append to. + * @param id The id to append. + * @return Whether the append succeeded. + */ +bool pm_constant_id_list_append(pm_constant_id_list_t *list, pm_constant_id_t id); + +/** + * Insert a constant id into a list of constant ids at the specified index. + * + * @param list The list to insert into. + * @param index The index at which to insert. + * @param id The id to insert. + */ +void pm_constant_id_list_insert(pm_constant_id_list_t *list, size_t index, pm_constant_id_t id); + +/** + * Checks if the current constant id list includes the given constant id. + * + * @param list The list to check. + * @param id The id to check for. + * @return Whether the list includes the given id. + */ +bool pm_constant_id_list_includes(pm_constant_id_list_t *list, pm_constant_id_t id); + +/** + * Free the memory associated with a list of constant ids. + * + * @param list The list to free. + */ +void pm_constant_id_list_free(pm_constant_id_list_t *list); + +/** + * The type of bucket in the constant pool hash map. This determines how the + * bucket should be freed. + */ +typedef unsigned int pm_constant_pool_bucket_type_t; + +/** By default, each constant is a slice of the source. */ +static const pm_constant_pool_bucket_type_t PM_CONSTANT_POOL_BUCKET_DEFAULT = 0; + +/** An owned constant is one for which memory has been allocated. */ +static const pm_constant_pool_bucket_type_t PM_CONSTANT_POOL_BUCKET_OWNED = 1; + +/** A constant constant is known at compile time. */ +static const pm_constant_pool_bucket_type_t PM_CONSTANT_POOL_BUCKET_CONSTANT = 2; + +/** A bucket in the hash map. */ +typedef struct { + /** The incremental ID used for indexing back into the pool. */ + unsigned int id: 30; + + /** The type of the bucket, which determines how to free it. */ + pm_constant_pool_bucket_type_t type: 2; + + /** The hash of the bucket. */ + uint32_t hash; +} pm_constant_pool_bucket_t; + +/** A constant in the pool which effectively stores a string. */ +typedef struct { + /** A pointer to the start of the string. */ + const uint8_t *start; + + /** The length of the string. */ + size_t length; +} pm_constant_t; + +/** The overall constant pool, which stores constants found while parsing. */ +typedef struct { + /** The buckets in the hash map. */ + pm_constant_pool_bucket_t *buckets; + + /** The constants that are stored in the buckets. */ + pm_constant_t *constants; + + /** The number of buckets in the hash map. */ + uint32_t size; + + /** The number of buckets that have been allocated in the hash map. */ + uint32_t capacity; +} pm_constant_pool_t; + +/** + * Initialize a new constant pool with a given capacity. + * + * @param pool The pool to initialize. + * @param capacity The initial capacity of the pool. + * @return Whether the initialization succeeded. + */ +bool pm_constant_pool_init(pm_constant_pool_t *pool, uint32_t capacity); + +/** + * Return a pointer to the constant indicated by the given constant id. + * + * @param pool The pool to get the constant from. + * @param constant_id The id of the constant to get. + * @return A pointer to the constant. + */ +pm_constant_t * pm_constant_pool_id_to_constant(const pm_constant_pool_t *pool, pm_constant_id_t constant_id); + +/** + * Find a constant in a constant pool. Returns the id of the constant, or 0 if + * the constant is not found. + * + * @param pool The pool to find the constant in. + * @param start A pointer to the start of the constant. + * @param length The length of the constant. + * @return The id of the constant. + */ +pm_constant_id_t pm_constant_pool_find(const pm_constant_pool_t *pool, const uint8_t *start, size_t length); + +/** + * Insert a constant into a constant pool that is a slice of a source string. + * Returns the id of the constant, or 0 if any potential calls to resize fail. + * + * @param pool The pool to insert the constant into. + * @param start A pointer to the start of the constant. + * @param length The length of the constant. + * @return The id of the constant. + */ +pm_constant_id_t pm_constant_pool_insert_shared(pm_constant_pool_t *pool, const uint8_t *start, size_t length); + +/** + * Insert a constant into a constant pool from memory that is now owned by the + * constant pool. Returns the id of the constant, or 0 if any potential calls to + * resize fail. + * + * @param pool The pool to insert the constant into. + * @param start A pointer to the start of the constant. + * @param length The length of the constant. + * @return The id of the constant. + */ +pm_constant_id_t pm_constant_pool_insert_owned(pm_constant_pool_t *pool, uint8_t *start, size_t length); + +/** + * Insert a constant into a constant pool from memory that is constant. Returns + * the id of the constant, or 0 if any potential calls to resize fail. + * + * @param pool The pool to insert the constant into. + * @param start A pointer to the start of the constant. + * @param length The length of the constant. + * @return The id of the constant. + */ +pm_constant_id_t pm_constant_pool_insert_constant(pm_constant_pool_t *pool, const uint8_t *start, size_t length); + +/** + * Free the memory associated with a constant pool. + * + * @param pool The pool to free. + */ +void pm_constant_pool_free(pm_constant_pool_t *pool); + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_integer.h b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_integer.h new file mode 100644 index 00000000..a9e29667 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_integer.h @@ -0,0 +1,126 @@ +/** + * @file pm_integer.h + * + * This module provides functions for working with arbitrary-sized integers. + */ +#ifndef PRISM_NUMBER_H +#define PRISM_NUMBER_H + +#include "prism/defines.h" +#include "prism/util/pm_buffer.h" + +#include +#include +#include +#include + +/** + * A structure represents an arbitrary-sized integer. + */ +typedef struct { + /** + * The number of allocated values. length is set to 0 if the integer fits + * into uint32_t. + */ + size_t length; + + /** + * List of 32-bit integers. Set to NULL if the integer fits into uint32_t. + */ + uint32_t *values; + + /** + * Embedded value for small integer. This value is set to 0 if the value + * does not fit into uint32_t. + */ + uint32_t value; + + /** + * Whether or not the integer is negative. It is stored this way so that a + * zeroed pm_integer_t is always positive zero. + */ + bool negative; +} pm_integer_t; + +/** + * An enum controlling the base of an integer. It is expected that the base is + * already known before parsing the integer, even though it could be derived + * from the string itself. + */ +typedef enum { + /** The default decimal base, with no prefix. Leading 0s will be ignored. */ + PM_INTEGER_BASE_DEFAULT, + + /** The binary base, indicated by a 0b or 0B prefix. */ + PM_INTEGER_BASE_BINARY, + + /** The octal base, indicated by a 0, 0o, or 0O prefix. */ + PM_INTEGER_BASE_OCTAL, + + /** The decimal base, indicated by a 0d, 0D, or empty prefix. */ + PM_INTEGER_BASE_DECIMAL, + + /** The hexadecimal base, indicated by a 0x or 0X prefix. */ + PM_INTEGER_BASE_HEXADECIMAL, + + /** + * An unknown base, in which case pm_integer_parse will derive it based on + * the content of the string. This is less efficient and does more + * comparisons, so if callers know the base ahead of time, they should use + * that instead. + */ + PM_INTEGER_BASE_UNKNOWN +} pm_integer_base_t; + +/** + * Parse an integer from a string. This assumes that the format of the integer + * has already been validated, as internal validation checks are not performed + * here. + * + * @param integer The integer to parse into. + * @param base The base of the integer. + * @param start The start of the string. + * @param end The end of the string. + */ +void pm_integer_parse(pm_integer_t *integer, pm_integer_base_t base, const uint8_t *start, const uint8_t *end); + +/** + * Compare two integers. This function returns -1 if the left integer is less + * than the right integer, 0 if they are equal, and 1 if the left integer is + * greater than the right integer. + * + * @param left The left integer to compare. + * @param right The right integer to compare. + * @return The result of the comparison. + */ +int pm_integer_compare(const pm_integer_t *left, const pm_integer_t *right); + +/** + * Reduce a ratio of integers to its simplest form. + * + * If either the numerator or denominator do not fit into a 32-bit integer, then + * this function is a no-op. In the future, we may consider reducing even the + * larger numbers, but for now we're going to keep it simple. + * + * @param numerator The numerator of the ratio. + * @param denominator The denominator of the ratio. + */ +void pm_integers_reduce(pm_integer_t *numerator, pm_integer_t *denominator); + +/** + * Convert an integer to a decimal string. + * + * @param buffer The buffer to append the string to. + * @param integer The integer to convert to a string. + */ +PRISM_EXPORTED_FUNCTION void pm_integer_string(pm_buffer_t *buffer, const pm_integer_t *integer); + +/** + * Free the internal memory of an integer. This memory will only be allocated if + * the integer exceeds the size of a single node in the linked list. + * + * @param integer The integer to free. + */ +PRISM_EXPORTED_FUNCTION void pm_integer_free(pm_integer_t *integer); + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_list.h b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_list.h new file mode 100644 index 00000000..3512dee9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_list.h @@ -0,0 +1,97 @@ +/** + * @file pm_list.h + * + * An abstract linked list. + */ +#ifndef PRISM_LIST_H +#define PRISM_LIST_H + +#include "prism/defines.h" + +#include +#include +#include +#include + +/** + * This struct represents an abstract linked list that provides common + * functionality. It is meant to be used any time a linked list is necessary to + * store data. + * + * The linked list itself operates off a set of pointers. Because the pointers + * are not necessarily sequential, they can be of any size. We use this fact to + * allow the consumer of this linked list to extend the node struct to include + * any data they want. This is done by using the pm_list_node_t as the first + * member of the struct. + * + * For example, if we want to store a list of integers, we can do the following: + * + * ```c + * typedef struct { + * pm_list_node_t node; + * int value; + * } pm_int_node_t; + * + * pm_list_t list = { 0 }; + * pm_int_node_t *node = xmalloc(sizeof(pm_int_node_t)); + * node->value = 5; + * + * pm_list_append(&list, &node->node); + * ``` + * + * The pm_list_t struct is used to represent the overall linked list. It + * contains a pointer to the head and tail of the list. This allows for easy + * iteration and appending of new nodes. + */ +typedef struct pm_list_node { + /** A pointer to the next node in the list. */ + struct pm_list_node *next; +} pm_list_node_t; + +/** + * This represents the overall linked list. It keeps a pointer to the head and + * tail so that iteration is easy and pushing new nodes is easy. + */ +typedef struct { + /** The size of the list. */ + size_t size; + + /** A pointer to the head of the list. */ + pm_list_node_t *head; + + /** A pointer to the tail of the list. */ + pm_list_node_t *tail; +} pm_list_t; + +/** + * Returns true if the given list is empty. + * + * @param list The list to check. + * @return True if the given list is empty, otherwise false. + */ +PRISM_EXPORTED_FUNCTION bool pm_list_empty_p(pm_list_t *list); + +/** + * Returns the size of the list. + * + * @param list The list to check. + * @return The size of the list. + */ +PRISM_EXPORTED_FUNCTION size_t pm_list_size(pm_list_t *list); + +/** + * Append a node to the given list. + * + * @param list The list to append to. + * @param node The node to append. + */ +void pm_list_append(pm_list_t *list, pm_list_node_t *node); + +/** + * Deallocate the internal state of the given list. + * + * @param list The list to free. + */ +PRISM_EXPORTED_FUNCTION void pm_list_free(pm_list_t *list); + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_memchr.h b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_memchr.h new file mode 100644 index 00000000..e0671eae --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_memchr.h @@ -0,0 +1,29 @@ +/** + * @file pm_memchr.h + * + * A custom memchr implementation. + */ +#ifndef PRISM_MEMCHR_H +#define PRISM_MEMCHR_H + +#include "prism/defines.h" +#include "prism/encoding.h" + +#include + +/** + * We need to roll our own memchr to handle cases where the encoding changes and + * we need to search for a character in a buffer that could be the trailing byte + * of a multibyte character. + * + * @param source The source string. + * @param character The character to search for. + * @param number The maximum number of bytes to search. + * @param encoding_changed Whether the encoding changed. + * @param encoding A pointer to the encoding. + * @return A pointer to the first occurrence of the character in the source + * string, or NULL if no such character exists. + */ +void * pm_memchr(const void *source, int character, size_t number, bool encoding_changed, const pm_encoding_t *encoding); + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_newline_list.h b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_newline_list.h new file mode 100644 index 00000000..406abe8b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_newline_list.h @@ -0,0 +1,113 @@ +/** + * @file pm_newline_list.h + * + * A list of byte offsets of newlines in a string. + * + * When compiling the syntax tree, it's necessary to know the line and column + * of many nodes. This is necessary to support things like error messages, + * tracepoints, etc. + * + * It's possible that we could store the start line, start column, end line, and + * end column on every node in addition to the offsets that we already store, + * but that would be quite a lot of memory overhead. + */ +#ifndef PRISM_NEWLINE_LIST_H +#define PRISM_NEWLINE_LIST_H + +#include "prism/defines.h" + +#include +#include +#include +#include + +/** + * A list of offsets of newlines in a string. The offsets are assumed to be + * sorted/inserted in ascending order. + */ +typedef struct { + /** A pointer to the start of the source string. */ + const uint8_t *start; + + /** The number of offsets in the list. */ + size_t size; + + /** The capacity of the list that has been allocated. */ + size_t capacity; + + /** The list of offsets. */ + size_t *offsets; +} pm_newline_list_t; + +/** + * A line and column in a string. + */ +typedef struct { + /** The line number. */ + int32_t line; + + /** The column number. */ + uint32_t column; +} pm_line_column_t; + +/** + * Initialize a new newline list with the given capacity. Returns true if the + * allocation of the offsets succeeds, otherwise returns false. + * + * @param list The list to initialize. + * @param start A pointer to the start of the source string. + * @param capacity The initial capacity of the list. + * @return True if the allocation of the offsets succeeds, otherwise false. + */ +bool pm_newline_list_init(pm_newline_list_t *list, const uint8_t *start, size_t capacity); + +/** + * Clear out the newlines that have been appended to the list. + * + * @param list The list to clear. + */ +void +pm_newline_list_clear(pm_newline_list_t *list); + +/** + * Append a new offset to the newline list. Returns true if the reallocation of + * the offsets succeeds (if one was necessary), otherwise returns false. + * + * @param list The list to append to. + * @param cursor A pointer to the offset to append. + * @return True if the reallocation of the offsets succeeds (if one was + * necessary), otherwise false. + */ +bool pm_newline_list_append(pm_newline_list_t *list, const uint8_t *cursor); + +/** + * Returns the line of the given offset. If the offset is not in the list, the + * line of the closest offset less than the given offset is returned. + * + * @param list The list to search. + * @param cursor A pointer to the offset to search for. + * @param start_line The line to start counting from. + * @return The line of the given offset. + */ +int32_t pm_newline_list_line(const pm_newline_list_t *list, const uint8_t *cursor, int32_t start_line); + +/** + * Returns the line and column of the given offset. If the offset is not in the + * list, the line and column of the closest offset less than the given offset + * are returned. + * + * @param list The list to search. + * @param cursor A pointer to the offset to search for. + * @param start_line The line to start counting from. + * @return The line and column of the given offset. + */ +pm_line_column_t pm_newline_list_line_column(const pm_newline_list_t *list, const uint8_t *cursor, int32_t start_line); + +/** + * Free the internal memory allocated for the newline list. + * + * @param list The list to free. + */ +void pm_newline_list_free(pm_newline_list_t *list); + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_string.h b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_string.h new file mode 100644 index 00000000..f99f1abd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_string.h @@ -0,0 +1,190 @@ +/** + * @file pm_string.h + * + * A generic string type that can have various ownership semantics. + */ +#ifndef PRISM_STRING_H +#define PRISM_STRING_H + +#include "prism/defines.h" + +#include +#include +#include +#include +#include +#include + +// The following headers are necessary to read files using demand paging. +#ifdef _WIN32 +#include +#elif defined(_POSIX_MAPPED_FILES) +#include +#include +#include +#elif defined(PRISM_HAS_FILESYSTEM) +#include +#include +#endif + +/** + * A generic string type that can have various ownership semantics. + */ +typedef struct { + /** A pointer to the start of the string. */ + const uint8_t *source; + + /** The length of the string in bytes of memory. */ + size_t length; + + /** The type of the string. This field determines how the string should be freed. */ + enum { + /** This string is a constant string, and should not be freed. */ + PM_STRING_CONSTANT, + + /** This is a slice of another string, and should not be freed. */ + PM_STRING_SHARED, + + /** This string owns its memory, and should be freed using `pm_string_free`. */ + PM_STRING_OWNED, + +#ifdef PRISM_HAS_MMAP + /** This string is a memory-mapped file, and should be freed using `pm_string_free`. */ + PM_STRING_MAPPED +#endif + } type; +} pm_string_t; + +/** + * Returns the size of the pm_string_t struct. This is necessary to allocate the + * correct amount of memory in the FFI backend. + * + * @return The size of the pm_string_t struct. + */ +PRISM_EXPORTED_FUNCTION size_t pm_string_sizeof(void); + +/** + * Defines an empty string. This is useful for initializing a string that will + * be filled in later. + */ +#define PM_STRING_EMPTY ((pm_string_t) { .type = PM_STRING_CONSTANT, .source = NULL, .length = 0 }) + +/** + * Initialize a shared string that is based on initial input. + * + * @param string The string to initialize. + * @param start The start of the string. + * @param end The end of the string. + */ +void pm_string_shared_init(pm_string_t *string, const uint8_t *start, const uint8_t *end); + +/** + * Initialize an owned string that is responsible for freeing allocated memory. + * + * @param string The string to initialize. + * @param source The source of the string. + * @param length The length of the string. + */ +void pm_string_owned_init(pm_string_t *string, uint8_t *source, size_t length); + +/** + * Initialize a constant string that doesn't own its memory source. + * + * @param string The string to initialize. + * @param source The source of the string. + * @param length The length of the string. + */ +void pm_string_constant_init(pm_string_t *string, const char *source, size_t length); + +/** + * Represents the result of calling pm_string_mapped_init or + * pm_string_file_init. We need this additional information because there is + * not a platform-agnostic way to indicate that the file that was attempted to + * be opened was a directory. + */ +typedef enum { + /** Indicates that the string was successfully initialized. */ + PM_STRING_INIT_SUCCESS = 0, + /** + * Indicates a generic error from a string_*_init function, where the type + * of error should be read from `errno` or `GetLastError()`. + */ + PM_STRING_INIT_ERROR_GENERIC = 1, + /** + * Indicates that the file that was attempted to be opened was a directory. + */ + PM_STRING_INIT_ERROR_DIRECTORY = 2 +} pm_string_init_result_t; + +/** + * Read the file indicated by the filepath parameter into source and load its + * contents and size into the given `pm_string_t`. The given `pm_string_t` + * should be freed using `pm_string_free` when it is no longer used. + * + * We want to use demand paging as much as possible in order to avoid having to + * read the entire file into memory (which could be detrimental to performance + * for large files). This means that if we're on windows we'll use + * `MapViewOfFile`, on POSIX systems that have access to `mmap` we'll use + * `mmap`, and on other POSIX systems we'll use `read`. + * + * @param string The string to initialize. + * @param filepath The filepath to read. + * @return The success of the read, indicated by the value of the enum. + */ +PRISM_EXPORTED_FUNCTION pm_string_init_result_t pm_string_mapped_init(pm_string_t *string, const char *filepath); + +/** + * Read the file indicated by the filepath parameter into source and load its + * contents and size into the given `pm_string_t`. The given `pm_string_t` + * should be freed using `pm_string_free` when it is no longer used. + * + * @param string The string to initialize. + * @param filepath The filepath to read. + * @return The success of the read, indicated by the value of the enum. + */ +PRISM_EXPORTED_FUNCTION pm_string_init_result_t pm_string_file_init(pm_string_t *string, const char *filepath); + +/** + * Ensure the string is owned. If it is not, then reinitialize it as owned and + * copy over the previous source. + * + * @param string The string to ensure is owned. + */ +void pm_string_ensure_owned(pm_string_t *string); + +/** + * Compare the underlying lengths and bytes of two strings. Returns 0 if the + * strings are equal, a negative number if the left string is less than the + * right string, and a positive number if the left string is greater than the + * right string. + * + * @param left The left string to compare. + * @param right The right string to compare. + * @return The comparison result. + */ +int pm_string_compare(const pm_string_t *left, const pm_string_t *right); + +/** + * Returns the length associated with the string. + * + * @param string The string to get the length of. + * @return The length of the string. + */ +PRISM_EXPORTED_FUNCTION size_t pm_string_length(const pm_string_t *string); + +/** + * Returns the start pointer associated with the string. + * + * @param string The string to get the start pointer of. + * @return The start pointer of the string. + */ +PRISM_EXPORTED_FUNCTION const uint8_t * pm_string_source(const pm_string_t *string); + +/** + * Free the associated memory of the given string. + * + * @param string The string to free. + */ +PRISM_EXPORTED_FUNCTION void pm_string_free(pm_string_t *string); + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_strncasecmp.h b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_strncasecmp.h new file mode 100644 index 00000000..5cb88cb5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_strncasecmp.h @@ -0,0 +1,32 @@ +/** + * @file pm_strncasecmp.h + * + * A custom strncasecmp implementation. + */ +#ifndef PRISM_STRNCASECMP_H +#define PRISM_STRNCASECMP_H + +#include "prism/defines.h" + +#include +#include +#include + +/** + * Compare two strings, ignoring case, up to the given length. Returns 0 if the + * strings are equal, a negative number if string1 is less than string2, or a + * positive number if string1 is greater than string2. + * + * Note that this is effectively our own implementation of strncasecmp, but it's + * not available on all of the platforms we want to support so we're rolling it + * here. + * + * @param string1 The first string to compare. + * @param string2 The second string to compare + * @param length The maximum number of characters to compare. + * @return 0 if the strings are equal, a negative number if string1 is less than + * string2, or a positive number if string1 is greater than string2. + */ +int pm_strncasecmp(const uint8_t *string1, const uint8_t *string2, size_t length); + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_strpbrk.h b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_strpbrk.h new file mode 100644 index 00000000..f387bd57 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/util/pm_strpbrk.h @@ -0,0 +1,46 @@ +/** + * @file pm_strpbrk.h + * + * A custom strpbrk implementation. + */ +#ifndef PRISM_STRPBRK_H +#define PRISM_STRPBRK_H + +#include "prism/defines.h" +#include "prism/diagnostic.h" +#include "prism/parser.h" + +#include +#include + +/** + * Here we have rolled our own version of strpbrk. The standard library strpbrk + * has undefined behavior when the source string is not null-terminated. We want + * to support strings that are not null-terminated because pm_parse does not + * have the contract that the string is null-terminated. (This is desirable + * because it means the extension can call pm_parse with the result of a call to + * mmap). + * + * The standard library strpbrk also does not support passing a maximum length + * to search. We want to support this for the reason mentioned above, but we + * also don't want it to stop on null bytes. Ruby actually allows null bytes + * within strings, comments, regular expressions, etc. So we need to be able to + * skip past them. + * + * Finally, we want to support encodings wherein the charset could contain + * characters that are trailing bytes of multi-byte characters. For example, in + * Shift-JIS, the backslash character can be a trailing byte. In that case we + * need to take a slower path and iterate one multi-byte character at a time. + * + * @param parser The parser. + * @param source The source to search. + * @param charset The charset to search for. + * @param length The maximum number of bytes to search. + * @param validate Whether to validate that the source string is valid in the + * current encoding of the parser. + * @return A pointer to the first character in the source string that is in the + * charset, or NULL if no such character exists. + */ +const uint8_t * pm_strpbrk(pm_parser_t *parser, const uint8_t *source, const uint8_t *charset, ptrdiff_t length, bool validate); + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/version.h b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/version.h new file mode 100644 index 00000000..0a2a8c8f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/include/prism/version.h @@ -0,0 +1,29 @@ +/** + * @file version.h + * + * The version of the Prism library. + */ +#ifndef PRISM_VERSION_H +#define PRISM_VERSION_H + +/** + * The major version of the Prism library as an int. + */ +#define PRISM_VERSION_MAJOR 1 + +/** + * The minor version of the Prism library as an int. + */ +#define PRISM_VERSION_MINOR 4 + +/** + * The patch version of the Prism library as an int. + */ +#define PRISM_VERSION_PATCH 0 + +/** + * The version of the Prism library as a constant string. + */ +#define PRISM_VERSION "1.4.0" + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism.rb new file mode 100644 index 00000000..6cae171f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: true + +# The Prism Ruby parser. +# +# "Parsing Ruby is suddenly manageable!" +# - You, hopefully +# +module Prism + # There are many files in prism that are templated to handle every node type, + # which means the files can end up being quite large. We autoload them to make + # our require speed faster since consuming libraries are unlikely to use all + # of these features. + + autoload :BasicVisitor, "prism/visitor" + autoload :Compiler, "prism/compiler" + autoload :DesugarCompiler, "prism/desugar_compiler" + autoload :Dispatcher, "prism/dispatcher" + autoload :DotVisitor, "prism/dot_visitor" + autoload :DSL, "prism/dsl" + autoload :InspectVisitor, "prism/inspect_visitor" + autoload :LexCompat, "prism/lex_compat" + autoload :LexRipper, "prism/lex_compat" + autoload :MutationCompiler, "prism/mutation_compiler" + autoload :Pack, "prism/pack" + autoload :Pattern, "prism/pattern" + autoload :Reflection, "prism/reflection" + autoload :Relocation, "prism/relocation" + autoload :Serialize, "prism/serialize" + autoload :StringQuery, "prism/string_query" + autoload :Translation, "prism/translation" + autoload :Visitor, "prism/visitor" + + # Some of these constants are not meant to be exposed, so marking them as + # private here. + + private_constant :LexCompat + private_constant :LexRipper + + # :call-seq: + # Prism::lex_compat(source, **options) -> LexCompat::Result + # + # Returns a parse result whose value is an array of tokens that closely + # resembles the return value of Ripper::lex. The main difference is that the + # `:on_sp` token is not emitted. + # + # For supported options, see Prism::parse. + def self.lex_compat(source, **options) + LexCompat.new(source, **options).result # steep:ignore + end + + # :call-seq: + # Prism::lex_ripper(source) -> Array + # + # This lexes with the Ripper lex. It drops any space events but otherwise + # returns the same tokens. Raises SyntaxError if the syntax in source is + # invalid. + def self.lex_ripper(source) + LexRipper.new(source).result # steep:ignore + end + + # :call-seq: + # Prism::load(source, serialized, freeze) -> ParseResult + # + # Load the serialized AST using the source as a reference into a tree. + def self.load(source, serialized, freeze = false) + Serialize.load_parse(source, serialized, freeze) + end +end + +require_relative "prism/polyfill/byteindex" +require_relative "prism/node" +require_relative "prism/node_ext" +require_relative "prism/parse_result" + +# This is a Ruby implementation of the prism parser. If we're running on CRuby +# and we haven't explicitly set the PRISM_FFI_BACKEND environment variable, then +# it's going to require the built library. Otherwise, it's going to require a +# module that uses FFI to call into the library. +if RUBY_ENGINE == "ruby" and !ENV["PRISM_FFI_BACKEND"] + # The C extension is the default backend on CRuby. + Prism::BACKEND = :CEXT + + require "prism/prism" +else + # The FFI backend is used on other Ruby implementations. + Prism::BACKEND = :FFI + + require_relative "prism/ffi" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/compiler.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/compiler.rb new file mode 100644 index 00000000..b6771b3b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/compiler.rb @@ -0,0 +1,496 @@ +# frozen_string_literal: true + +=begin +This file is generated by the templates/template.rb script and should not be +modified manually. See templates/lib/prism/compiler.rb.erb +if you are looking to modify the template +=end + +module Prism + # A compiler is a visitor that returns the value of each node as it visits. + # This is as opposed to a visitor which will only walk the tree. This can be + # useful when you are trying to compile a tree into a different format. + # + # For example, to build a representation of the tree as s-expressions, you + # could write: + # + # class SExpressions < Prism::Compiler + # def visit_arguments_node(node) = [:arguments, super] + # def visit_call_node(node) = [:call, super] + # def visit_integer_node(node) = [:integer] + # def visit_program_node(node) = [:program, super] + # end + # + # Prism.parse("1 + 2").value.accept(SExpressions.new) + # # => [:program, [[[:call, [[:integer], [:arguments, [[:integer]]]]]]]] + # + class Compiler < Visitor + # Visit an individual node. + def visit(node) + node&.accept(self) + end + + # Visit a list of nodes. + def visit_all(nodes) + nodes.map { |node| node&.accept(self) } + end + + # Visit the child nodes of the given node. + def visit_child_nodes(node) + node.compact_child_nodes.map { |node| node.accept(self) } + end + + # Compile a AliasGlobalVariableNode node + alias visit_alias_global_variable_node visit_child_nodes + + # Compile a AliasMethodNode node + alias visit_alias_method_node visit_child_nodes + + # Compile a AlternationPatternNode node + alias visit_alternation_pattern_node visit_child_nodes + + # Compile a AndNode node + alias visit_and_node visit_child_nodes + + # Compile a ArgumentsNode node + alias visit_arguments_node visit_child_nodes + + # Compile a ArrayNode node + alias visit_array_node visit_child_nodes + + # Compile a ArrayPatternNode node + alias visit_array_pattern_node visit_child_nodes + + # Compile a AssocNode node + alias visit_assoc_node visit_child_nodes + + # Compile a AssocSplatNode node + alias visit_assoc_splat_node visit_child_nodes + + # Compile a BackReferenceReadNode node + alias visit_back_reference_read_node visit_child_nodes + + # Compile a BeginNode node + alias visit_begin_node visit_child_nodes + + # Compile a BlockArgumentNode node + alias visit_block_argument_node visit_child_nodes + + # Compile a BlockLocalVariableNode node + alias visit_block_local_variable_node visit_child_nodes + + # Compile a BlockNode node + alias visit_block_node visit_child_nodes + + # Compile a BlockParameterNode node + alias visit_block_parameter_node visit_child_nodes + + # Compile a BlockParametersNode node + alias visit_block_parameters_node visit_child_nodes + + # Compile a BreakNode node + alias visit_break_node visit_child_nodes + + # Compile a CallAndWriteNode node + alias visit_call_and_write_node visit_child_nodes + + # Compile a CallNode node + alias visit_call_node visit_child_nodes + + # Compile a CallOperatorWriteNode node + alias visit_call_operator_write_node visit_child_nodes + + # Compile a CallOrWriteNode node + alias visit_call_or_write_node visit_child_nodes + + # Compile a CallTargetNode node + alias visit_call_target_node visit_child_nodes + + # Compile a CapturePatternNode node + alias visit_capture_pattern_node visit_child_nodes + + # Compile a CaseMatchNode node + alias visit_case_match_node visit_child_nodes + + # Compile a CaseNode node + alias visit_case_node visit_child_nodes + + # Compile a ClassNode node + alias visit_class_node visit_child_nodes + + # Compile a ClassVariableAndWriteNode node + alias visit_class_variable_and_write_node visit_child_nodes + + # Compile a ClassVariableOperatorWriteNode node + alias visit_class_variable_operator_write_node visit_child_nodes + + # Compile a ClassVariableOrWriteNode node + alias visit_class_variable_or_write_node visit_child_nodes + + # Compile a ClassVariableReadNode node + alias visit_class_variable_read_node visit_child_nodes + + # Compile a ClassVariableTargetNode node + alias visit_class_variable_target_node visit_child_nodes + + # Compile a ClassVariableWriteNode node + alias visit_class_variable_write_node visit_child_nodes + + # Compile a ConstantAndWriteNode node + alias visit_constant_and_write_node visit_child_nodes + + # Compile a ConstantOperatorWriteNode node + alias visit_constant_operator_write_node visit_child_nodes + + # Compile a ConstantOrWriteNode node + alias visit_constant_or_write_node visit_child_nodes + + # Compile a ConstantPathAndWriteNode node + alias visit_constant_path_and_write_node visit_child_nodes + + # Compile a ConstantPathNode node + alias visit_constant_path_node visit_child_nodes + + # Compile a ConstantPathOperatorWriteNode node + alias visit_constant_path_operator_write_node visit_child_nodes + + # Compile a ConstantPathOrWriteNode node + alias visit_constant_path_or_write_node visit_child_nodes + + # Compile a ConstantPathTargetNode node + alias visit_constant_path_target_node visit_child_nodes + + # Compile a ConstantPathWriteNode node + alias visit_constant_path_write_node visit_child_nodes + + # Compile a ConstantReadNode node + alias visit_constant_read_node visit_child_nodes + + # Compile a ConstantTargetNode node + alias visit_constant_target_node visit_child_nodes + + # Compile a ConstantWriteNode node + alias visit_constant_write_node visit_child_nodes + + # Compile a DefNode node + alias visit_def_node visit_child_nodes + + # Compile a DefinedNode node + alias visit_defined_node visit_child_nodes + + # Compile a ElseNode node + alias visit_else_node visit_child_nodes + + # Compile a EmbeddedStatementsNode node + alias visit_embedded_statements_node visit_child_nodes + + # Compile a EmbeddedVariableNode node + alias visit_embedded_variable_node visit_child_nodes + + # Compile a EnsureNode node + alias visit_ensure_node visit_child_nodes + + # Compile a FalseNode node + alias visit_false_node visit_child_nodes + + # Compile a FindPatternNode node + alias visit_find_pattern_node visit_child_nodes + + # Compile a FlipFlopNode node + alias visit_flip_flop_node visit_child_nodes + + # Compile a FloatNode node + alias visit_float_node visit_child_nodes + + # Compile a ForNode node + alias visit_for_node visit_child_nodes + + # Compile a ForwardingArgumentsNode node + alias visit_forwarding_arguments_node visit_child_nodes + + # Compile a ForwardingParameterNode node + alias visit_forwarding_parameter_node visit_child_nodes + + # Compile a ForwardingSuperNode node + alias visit_forwarding_super_node visit_child_nodes + + # Compile a GlobalVariableAndWriteNode node + alias visit_global_variable_and_write_node visit_child_nodes + + # Compile a GlobalVariableOperatorWriteNode node + alias visit_global_variable_operator_write_node visit_child_nodes + + # Compile a GlobalVariableOrWriteNode node + alias visit_global_variable_or_write_node visit_child_nodes + + # Compile a GlobalVariableReadNode node + alias visit_global_variable_read_node visit_child_nodes + + # Compile a GlobalVariableTargetNode node + alias visit_global_variable_target_node visit_child_nodes + + # Compile a GlobalVariableWriteNode node + alias visit_global_variable_write_node visit_child_nodes + + # Compile a HashNode node + alias visit_hash_node visit_child_nodes + + # Compile a HashPatternNode node + alias visit_hash_pattern_node visit_child_nodes + + # Compile a IfNode node + alias visit_if_node visit_child_nodes + + # Compile a ImaginaryNode node + alias visit_imaginary_node visit_child_nodes + + # Compile a ImplicitNode node + alias visit_implicit_node visit_child_nodes + + # Compile a ImplicitRestNode node + alias visit_implicit_rest_node visit_child_nodes + + # Compile a InNode node + alias visit_in_node visit_child_nodes + + # Compile a IndexAndWriteNode node + alias visit_index_and_write_node visit_child_nodes + + # Compile a IndexOperatorWriteNode node + alias visit_index_operator_write_node visit_child_nodes + + # Compile a IndexOrWriteNode node + alias visit_index_or_write_node visit_child_nodes + + # Compile a IndexTargetNode node + alias visit_index_target_node visit_child_nodes + + # Compile a InstanceVariableAndWriteNode node + alias visit_instance_variable_and_write_node visit_child_nodes + + # Compile a InstanceVariableOperatorWriteNode node + alias visit_instance_variable_operator_write_node visit_child_nodes + + # Compile a InstanceVariableOrWriteNode node + alias visit_instance_variable_or_write_node visit_child_nodes + + # Compile a InstanceVariableReadNode node + alias visit_instance_variable_read_node visit_child_nodes + + # Compile a InstanceVariableTargetNode node + alias visit_instance_variable_target_node visit_child_nodes + + # Compile a InstanceVariableWriteNode node + alias visit_instance_variable_write_node visit_child_nodes + + # Compile a IntegerNode node + alias visit_integer_node visit_child_nodes + + # Compile a InterpolatedMatchLastLineNode node + alias visit_interpolated_match_last_line_node visit_child_nodes + + # Compile a InterpolatedRegularExpressionNode node + alias visit_interpolated_regular_expression_node visit_child_nodes + + # Compile a InterpolatedStringNode node + alias visit_interpolated_string_node visit_child_nodes + + # Compile a InterpolatedSymbolNode node + alias visit_interpolated_symbol_node visit_child_nodes + + # Compile a InterpolatedXStringNode node + alias visit_interpolated_x_string_node visit_child_nodes + + # Compile a ItLocalVariableReadNode node + alias visit_it_local_variable_read_node visit_child_nodes + + # Compile a ItParametersNode node + alias visit_it_parameters_node visit_child_nodes + + # Compile a KeywordHashNode node + alias visit_keyword_hash_node visit_child_nodes + + # Compile a KeywordRestParameterNode node + alias visit_keyword_rest_parameter_node visit_child_nodes + + # Compile a LambdaNode node + alias visit_lambda_node visit_child_nodes + + # Compile a LocalVariableAndWriteNode node + alias visit_local_variable_and_write_node visit_child_nodes + + # Compile a LocalVariableOperatorWriteNode node + alias visit_local_variable_operator_write_node visit_child_nodes + + # Compile a LocalVariableOrWriteNode node + alias visit_local_variable_or_write_node visit_child_nodes + + # Compile a LocalVariableReadNode node + alias visit_local_variable_read_node visit_child_nodes + + # Compile a LocalVariableTargetNode node + alias visit_local_variable_target_node visit_child_nodes + + # Compile a LocalVariableWriteNode node + alias visit_local_variable_write_node visit_child_nodes + + # Compile a MatchLastLineNode node + alias visit_match_last_line_node visit_child_nodes + + # Compile a MatchPredicateNode node + alias visit_match_predicate_node visit_child_nodes + + # Compile a MatchRequiredNode node + alias visit_match_required_node visit_child_nodes + + # Compile a MatchWriteNode node + alias visit_match_write_node visit_child_nodes + + # Compile a MissingNode node + alias visit_missing_node visit_child_nodes + + # Compile a ModuleNode node + alias visit_module_node visit_child_nodes + + # Compile a MultiTargetNode node + alias visit_multi_target_node visit_child_nodes + + # Compile a MultiWriteNode node + alias visit_multi_write_node visit_child_nodes + + # Compile a NextNode node + alias visit_next_node visit_child_nodes + + # Compile a NilNode node + alias visit_nil_node visit_child_nodes + + # Compile a NoKeywordsParameterNode node + alias visit_no_keywords_parameter_node visit_child_nodes + + # Compile a NumberedParametersNode node + alias visit_numbered_parameters_node visit_child_nodes + + # Compile a NumberedReferenceReadNode node + alias visit_numbered_reference_read_node visit_child_nodes + + # Compile a OptionalKeywordParameterNode node + alias visit_optional_keyword_parameter_node visit_child_nodes + + # Compile a OptionalParameterNode node + alias visit_optional_parameter_node visit_child_nodes + + # Compile a OrNode node + alias visit_or_node visit_child_nodes + + # Compile a ParametersNode node + alias visit_parameters_node visit_child_nodes + + # Compile a ParenthesesNode node + alias visit_parentheses_node visit_child_nodes + + # Compile a PinnedExpressionNode node + alias visit_pinned_expression_node visit_child_nodes + + # Compile a PinnedVariableNode node + alias visit_pinned_variable_node visit_child_nodes + + # Compile a PostExecutionNode node + alias visit_post_execution_node visit_child_nodes + + # Compile a PreExecutionNode node + alias visit_pre_execution_node visit_child_nodes + + # Compile a ProgramNode node + alias visit_program_node visit_child_nodes + + # Compile a RangeNode node + alias visit_range_node visit_child_nodes + + # Compile a RationalNode node + alias visit_rational_node visit_child_nodes + + # Compile a RedoNode node + alias visit_redo_node visit_child_nodes + + # Compile a RegularExpressionNode node + alias visit_regular_expression_node visit_child_nodes + + # Compile a RequiredKeywordParameterNode node + alias visit_required_keyword_parameter_node visit_child_nodes + + # Compile a RequiredParameterNode node + alias visit_required_parameter_node visit_child_nodes + + # Compile a RescueModifierNode node + alias visit_rescue_modifier_node visit_child_nodes + + # Compile a RescueNode node + alias visit_rescue_node visit_child_nodes + + # Compile a RestParameterNode node + alias visit_rest_parameter_node visit_child_nodes + + # Compile a RetryNode node + alias visit_retry_node visit_child_nodes + + # Compile a ReturnNode node + alias visit_return_node visit_child_nodes + + # Compile a SelfNode node + alias visit_self_node visit_child_nodes + + # Compile a ShareableConstantNode node + alias visit_shareable_constant_node visit_child_nodes + + # Compile a SingletonClassNode node + alias visit_singleton_class_node visit_child_nodes + + # Compile a SourceEncodingNode node + alias visit_source_encoding_node visit_child_nodes + + # Compile a SourceFileNode node + alias visit_source_file_node visit_child_nodes + + # Compile a SourceLineNode node + alias visit_source_line_node visit_child_nodes + + # Compile a SplatNode node + alias visit_splat_node visit_child_nodes + + # Compile a StatementsNode node + alias visit_statements_node visit_child_nodes + + # Compile a StringNode node + alias visit_string_node visit_child_nodes + + # Compile a SuperNode node + alias visit_super_node visit_child_nodes + + # Compile a SymbolNode node + alias visit_symbol_node visit_child_nodes + + # Compile a TrueNode node + alias visit_true_node visit_child_nodes + + # Compile a UndefNode node + alias visit_undef_node visit_child_nodes + + # Compile a UnlessNode node + alias visit_unless_node visit_child_nodes + + # Compile a UntilNode node + alias visit_until_node visit_child_nodes + + # Compile a WhenNode node + alias visit_when_node visit_child_nodes + + # Compile a WhileNode node + alias visit_while_node visit_child_nodes + + # Compile a XStringNode node + alias visit_x_string_node visit_child_nodes + + # Compile a YieldNode node + alias visit_yield_node visit_child_nodes + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/desugar_compiler.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/desugar_compiler.rb new file mode 100644 index 00000000..e3b15fc3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/desugar_compiler.rb @@ -0,0 +1,391 @@ +# frozen_string_literal: true + +module Prism + class DesugarAndWriteNode # :nodoc: + include DSL + + attr_reader :node, :default_source, :read_class, :write_class, :arguments + + def initialize(node, default_source, read_class, write_class, **arguments) + @node = node + @default_source = default_source + @read_class = read_class + @write_class = write_class + @arguments = arguments + end + + # Desugar `x &&= y` to `x && x = y` + def compile + and_node( + location: node.location, + left: public_send(read_class, location: node.name_loc, **arguments), + right: public_send( + write_class, + location: node.location, + **arguments, + name_loc: node.name_loc, + value: node.value, + operator_loc: node.operator_loc + ), + operator_loc: node.operator_loc + ) + end + end + + class DesugarOrWriteDefinedNode # :nodoc: + include DSL + + attr_reader :node, :default_source, :read_class, :write_class, :arguments + + def initialize(node, default_source, read_class, write_class, **arguments) + @node = node + @default_source = default_source + @read_class = read_class + @write_class = write_class + @arguments = arguments + end + + # Desugar `x ||= y` to `defined?(x) ? x : x = y` + def compile + if_node( + location: node.location, + if_keyword_loc: node.operator_loc, + predicate: defined_node( + location: node.name_loc, + value: public_send(read_class, location: node.name_loc, **arguments), + keyword_loc: node.operator_loc + ), + then_keyword_loc: node.operator_loc, + statements: statements_node( + location: node.location, + body: [public_send(read_class, location: node.name_loc, **arguments)] + ), + subsequent: else_node( + location: node.location, + else_keyword_loc: node.operator_loc, + statements: statements_node( + location: node.location, + body: [ + public_send( + write_class, + location: node.location, + **arguments, + name_loc: node.name_loc, + value: node.value, + operator_loc: node.operator_loc + ) + ] + ), + end_keyword_loc: node.operator_loc + ), + end_keyword_loc: node.operator_loc + ) + end + end + + class DesugarOperatorWriteNode # :nodoc: + include DSL + + attr_reader :node, :default_source, :read_class, :write_class, :arguments + + def initialize(node, default_source, read_class, write_class, **arguments) + @node = node + @default_source = default_source + @read_class = read_class + @write_class = write_class + @arguments = arguments + end + + # Desugar `x += y` to `x = x + y` + def compile + binary_operator_loc = node.binary_operator_loc.chop + + public_send( + write_class, + location: node.location, + **arguments, + name_loc: node.name_loc, + value: call_node( + location: node.location, + receiver: public_send( + read_class, + location: node.name_loc, + **arguments + ), + name: binary_operator_loc.slice.to_sym, + message_loc: binary_operator_loc, + arguments: arguments_node( + location: node.value.location, + arguments: [node.value] + ) + ), + operator_loc: node.binary_operator_loc.copy( + start_offset: node.binary_operator_loc.end_offset - 1, + length: 1 + ) + ) + end + end + + class DesugarOrWriteNode # :nodoc: + include DSL + + attr_reader :node, :default_source, :read_class, :write_class, :arguments + + def initialize(node, default_source, read_class, write_class, **arguments) + @node = node + @default_source = default_source + @read_class = read_class + @write_class = write_class + @arguments = arguments + end + + # Desugar `x ||= y` to `x || x = y` + def compile + or_node( + location: node.location, + left: public_send(read_class, location: node.name_loc, **arguments), + right: public_send( + write_class, + location: node.location, + **arguments, + name_loc: node.name_loc, + value: node.value, + operator_loc: node.operator_loc + ), + operator_loc: node.operator_loc + ) + end + end + + private_constant :DesugarAndWriteNode, :DesugarOrWriteNode, :DesugarOrWriteDefinedNode, :DesugarOperatorWriteNode + + class ClassVariableAndWriteNode + def desugar # :nodoc: + DesugarAndWriteNode.new(self, source, :class_variable_read_node, :class_variable_write_node, name: name).compile + end + end + + class ClassVariableOrWriteNode + def desugar # :nodoc: + DesugarOrWriteDefinedNode.new(self, source, :class_variable_read_node, :class_variable_write_node, name: name).compile + end + end + + class ClassVariableOperatorWriteNode + def desugar # :nodoc: + DesugarOperatorWriteNode.new(self, source, :class_variable_read_node, :class_variable_write_node, name: name).compile + end + end + + class ConstantAndWriteNode + def desugar # :nodoc: + DesugarAndWriteNode.new(self, source, :constant_read_node, :constant_write_node, name: name).compile + end + end + + class ConstantOrWriteNode + def desugar # :nodoc: + DesugarOrWriteDefinedNode.new(self, source, :constant_read_node, :constant_write_node, name: name).compile + end + end + + class ConstantOperatorWriteNode + def desugar # :nodoc: + DesugarOperatorWriteNode.new(self, source, :constant_read_node, :constant_write_node, name: name).compile + end + end + + class GlobalVariableAndWriteNode + def desugar # :nodoc: + DesugarAndWriteNode.new(self, source, :global_variable_read_node, :global_variable_write_node, name: name).compile + end + end + + class GlobalVariableOrWriteNode + def desugar # :nodoc: + DesugarOrWriteDefinedNode.new(self, source, :global_variable_read_node, :global_variable_write_node, name: name).compile + end + end + + class GlobalVariableOperatorWriteNode + def desugar # :nodoc: + DesugarOperatorWriteNode.new(self, source, :global_variable_read_node, :global_variable_write_node, name: name).compile + end + end + + class InstanceVariableAndWriteNode + def desugar # :nodoc: + DesugarAndWriteNode.new(self, source, :instance_variable_read_node, :instance_variable_write_node, name: name).compile + end + end + + class InstanceVariableOrWriteNode + def desugar # :nodoc: + DesugarOrWriteNode.new(self, source, :instance_variable_read_node, :instance_variable_write_node, name: name).compile + end + end + + class InstanceVariableOperatorWriteNode + def desugar # :nodoc: + DesugarOperatorWriteNode.new(self, source, :instance_variable_read_node, :instance_variable_write_node, name: name).compile + end + end + + class LocalVariableAndWriteNode + def desugar # :nodoc: + DesugarAndWriteNode.new(self, source, :local_variable_read_node, :local_variable_write_node, name: name, depth: depth).compile + end + end + + class LocalVariableOrWriteNode + def desugar # :nodoc: + DesugarOrWriteNode.new(self, source, :local_variable_read_node, :local_variable_write_node, name: name, depth: depth).compile + end + end + + class LocalVariableOperatorWriteNode + def desugar # :nodoc: + DesugarOperatorWriteNode.new(self, source, :local_variable_read_node, :local_variable_write_node, name: name, depth: depth).compile + end + end + + # DesugarCompiler is a compiler that desugars Ruby code into a more primitive + # form. This is useful for consumers that want to deal with fewer node types. + class DesugarCompiler < MutationCompiler + # @@foo &&= bar + # + # becomes + # + # @@foo && @@foo = bar + def visit_class_variable_and_write_node(node) + node.desugar + end + + # @@foo ||= bar + # + # becomes + # + # defined?(@@foo) ? @@foo : @@foo = bar + def visit_class_variable_or_write_node(node) + node.desugar + end + + # @@foo += bar + # + # becomes + # + # @@foo = @@foo + bar + def visit_class_variable_operator_write_node(node) + node.desugar + end + + # Foo &&= bar + # + # becomes + # + # Foo && Foo = bar + def visit_constant_and_write_node(node) + node.desugar + end + + # Foo ||= bar + # + # becomes + # + # defined?(Foo) ? Foo : Foo = bar + def visit_constant_or_write_node(node) + node.desugar + end + + # Foo += bar + # + # becomes + # + # Foo = Foo + bar + def visit_constant_operator_write_node(node) + node.desugar + end + + # $foo &&= bar + # + # becomes + # + # $foo && $foo = bar + def visit_global_variable_and_write_node(node) + node.desugar + end + + # $foo ||= bar + # + # becomes + # + # defined?($foo) ? $foo : $foo = bar + def visit_global_variable_or_write_node(node) + node.desugar + end + + # $foo += bar + # + # becomes + # + # $foo = $foo + bar + def visit_global_variable_operator_write_node(node) + node.desugar + end + + # @foo &&= bar + # + # becomes + # + # @foo && @foo = bar + def visit_instance_variable_and_write_node(node) + node.desugar + end + + # @foo ||= bar + # + # becomes + # + # @foo || @foo = bar + def visit_instance_variable_or_write_node(node) + node.desugar + end + + # @foo += bar + # + # becomes + # + # @foo = @foo + bar + def visit_instance_variable_operator_write_node(node) + node.desugar + end + + # foo &&= bar + # + # becomes + # + # foo && foo = bar + def visit_local_variable_and_write_node(node) + node.desugar + end + + # foo ||= bar + # + # becomes + # + # foo || foo = bar + def visit_local_variable_or_write_node(node) + node.desugar + end + + # foo += bar + # + # becomes + # + # foo = foo + bar + def visit_local_variable_operator_write_node(node) + node.desugar + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/dispatcher.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/dispatcher.rb new file mode 100644 index 00000000..21fb14f1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/dispatcher.rb @@ -0,0 +1,2194 @@ +# frozen_string_literal: true + +=begin +This file is generated by the templates/template.rb script and should not be +modified manually. See templates/lib/prism/dispatcher.rb.erb +if you are looking to modify the template +=end + +module Prism + # The dispatcher class fires events for nodes that are found while walking an + # AST to all registered listeners. It's useful for performing different types + # of analysis on the AST while only having to walk the tree once. + # + # To use the dispatcher, you would first instantiate it and register listeners + # for the events you're interested in: + # + # class OctalListener + # def on_integer_node_enter(node) + # if node.octal? && !node.slice.start_with?("0o") + # warn("Octal integers should be written with the 0o prefix") + # end + # end + # end + # + # listener = OctalListener.new + # dispatcher = Prism::Dispatcher.new + # dispatcher.register(listener, :on_integer_node_enter) + # + # Then, you can walk any number of trees and dispatch events to the listeners: + # + # result = Prism.parse("001 + 002 + 003") + # dispatcher.dispatch(result.value) + # + # Optionally, you can also use `#dispatch_once` to dispatch enter and leave + # events for a single node without recursing further down the tree. This can + # be useful in circumstances where you want to reuse the listeners you already + # have registers but want to stop walking the tree at a certain point. + # + # integer = result.value.statements.body.first.receiver.receiver + # dispatcher.dispatch_once(integer) + # + class Dispatcher < Visitor + # attr_reader listeners: Hash[Symbol, Array[Listener]] + attr_reader :listeners + + # Initialize a new dispatcher. + def initialize + @listeners = {} + end + + # Register a listener for one or more events. + # + # def register: (Listener, *Symbol) -> void + def register(listener, *events) + events.each { |event| (listeners[event] ||= []) << listener } + end + + # Walks `root` dispatching events to all registered listeners. + # + # def dispatch: (Node) -> void + alias dispatch visit + + # Dispatches a single event for `node` to all registered listeners. + # + # def dispatch_once: (Node) -> void + def dispatch_once(node) + node.accept(DispatchOnce.new(listeners)) + end + + # Dispatch enter and leave events for AliasGlobalVariableNode nodes and continue + # walking the tree. + def visit_alias_global_variable_node(node) + listeners[:on_alias_global_variable_node_enter]&.each { |listener| listener.on_alias_global_variable_node_enter(node) } + super + listeners[:on_alias_global_variable_node_leave]&.each { |listener| listener.on_alias_global_variable_node_leave(node) } + end + + # Dispatch enter and leave events for AliasMethodNode nodes and continue + # walking the tree. + def visit_alias_method_node(node) + listeners[:on_alias_method_node_enter]&.each { |listener| listener.on_alias_method_node_enter(node) } + super + listeners[:on_alias_method_node_leave]&.each { |listener| listener.on_alias_method_node_leave(node) } + end + + # Dispatch enter and leave events for AlternationPatternNode nodes and continue + # walking the tree. + def visit_alternation_pattern_node(node) + listeners[:on_alternation_pattern_node_enter]&.each { |listener| listener.on_alternation_pattern_node_enter(node) } + super + listeners[:on_alternation_pattern_node_leave]&.each { |listener| listener.on_alternation_pattern_node_leave(node) } + end + + # Dispatch enter and leave events for AndNode nodes and continue + # walking the tree. + def visit_and_node(node) + listeners[:on_and_node_enter]&.each { |listener| listener.on_and_node_enter(node) } + super + listeners[:on_and_node_leave]&.each { |listener| listener.on_and_node_leave(node) } + end + + # Dispatch enter and leave events for ArgumentsNode nodes and continue + # walking the tree. + def visit_arguments_node(node) + listeners[:on_arguments_node_enter]&.each { |listener| listener.on_arguments_node_enter(node) } + super + listeners[:on_arguments_node_leave]&.each { |listener| listener.on_arguments_node_leave(node) } + end + + # Dispatch enter and leave events for ArrayNode nodes and continue + # walking the tree. + def visit_array_node(node) + listeners[:on_array_node_enter]&.each { |listener| listener.on_array_node_enter(node) } + super + listeners[:on_array_node_leave]&.each { |listener| listener.on_array_node_leave(node) } + end + + # Dispatch enter and leave events for ArrayPatternNode nodes and continue + # walking the tree. + def visit_array_pattern_node(node) + listeners[:on_array_pattern_node_enter]&.each { |listener| listener.on_array_pattern_node_enter(node) } + super + listeners[:on_array_pattern_node_leave]&.each { |listener| listener.on_array_pattern_node_leave(node) } + end + + # Dispatch enter and leave events for AssocNode nodes and continue + # walking the tree. + def visit_assoc_node(node) + listeners[:on_assoc_node_enter]&.each { |listener| listener.on_assoc_node_enter(node) } + super + listeners[:on_assoc_node_leave]&.each { |listener| listener.on_assoc_node_leave(node) } + end + + # Dispatch enter and leave events for AssocSplatNode nodes and continue + # walking the tree. + def visit_assoc_splat_node(node) + listeners[:on_assoc_splat_node_enter]&.each { |listener| listener.on_assoc_splat_node_enter(node) } + super + listeners[:on_assoc_splat_node_leave]&.each { |listener| listener.on_assoc_splat_node_leave(node) } + end + + # Dispatch enter and leave events for BackReferenceReadNode nodes and continue + # walking the tree. + def visit_back_reference_read_node(node) + listeners[:on_back_reference_read_node_enter]&.each { |listener| listener.on_back_reference_read_node_enter(node) } + super + listeners[:on_back_reference_read_node_leave]&.each { |listener| listener.on_back_reference_read_node_leave(node) } + end + + # Dispatch enter and leave events for BeginNode nodes and continue + # walking the tree. + def visit_begin_node(node) + listeners[:on_begin_node_enter]&.each { |listener| listener.on_begin_node_enter(node) } + super + listeners[:on_begin_node_leave]&.each { |listener| listener.on_begin_node_leave(node) } + end + + # Dispatch enter and leave events for BlockArgumentNode nodes and continue + # walking the tree. + def visit_block_argument_node(node) + listeners[:on_block_argument_node_enter]&.each { |listener| listener.on_block_argument_node_enter(node) } + super + listeners[:on_block_argument_node_leave]&.each { |listener| listener.on_block_argument_node_leave(node) } + end + + # Dispatch enter and leave events for BlockLocalVariableNode nodes and continue + # walking the tree. + def visit_block_local_variable_node(node) + listeners[:on_block_local_variable_node_enter]&.each { |listener| listener.on_block_local_variable_node_enter(node) } + super + listeners[:on_block_local_variable_node_leave]&.each { |listener| listener.on_block_local_variable_node_leave(node) } + end + + # Dispatch enter and leave events for BlockNode nodes and continue + # walking the tree. + def visit_block_node(node) + listeners[:on_block_node_enter]&.each { |listener| listener.on_block_node_enter(node) } + super + listeners[:on_block_node_leave]&.each { |listener| listener.on_block_node_leave(node) } + end + + # Dispatch enter and leave events for BlockParameterNode nodes and continue + # walking the tree. + def visit_block_parameter_node(node) + listeners[:on_block_parameter_node_enter]&.each { |listener| listener.on_block_parameter_node_enter(node) } + super + listeners[:on_block_parameter_node_leave]&.each { |listener| listener.on_block_parameter_node_leave(node) } + end + + # Dispatch enter and leave events for BlockParametersNode nodes and continue + # walking the tree. + def visit_block_parameters_node(node) + listeners[:on_block_parameters_node_enter]&.each { |listener| listener.on_block_parameters_node_enter(node) } + super + listeners[:on_block_parameters_node_leave]&.each { |listener| listener.on_block_parameters_node_leave(node) } + end + + # Dispatch enter and leave events for BreakNode nodes and continue + # walking the tree. + def visit_break_node(node) + listeners[:on_break_node_enter]&.each { |listener| listener.on_break_node_enter(node) } + super + listeners[:on_break_node_leave]&.each { |listener| listener.on_break_node_leave(node) } + end + + # Dispatch enter and leave events for CallAndWriteNode nodes and continue + # walking the tree. + def visit_call_and_write_node(node) + listeners[:on_call_and_write_node_enter]&.each { |listener| listener.on_call_and_write_node_enter(node) } + super + listeners[:on_call_and_write_node_leave]&.each { |listener| listener.on_call_and_write_node_leave(node) } + end + + # Dispatch enter and leave events for CallNode nodes and continue + # walking the tree. + def visit_call_node(node) + listeners[:on_call_node_enter]&.each { |listener| listener.on_call_node_enter(node) } + super + listeners[:on_call_node_leave]&.each { |listener| listener.on_call_node_leave(node) } + end + + # Dispatch enter and leave events for CallOperatorWriteNode nodes and continue + # walking the tree. + def visit_call_operator_write_node(node) + listeners[:on_call_operator_write_node_enter]&.each { |listener| listener.on_call_operator_write_node_enter(node) } + super + listeners[:on_call_operator_write_node_leave]&.each { |listener| listener.on_call_operator_write_node_leave(node) } + end + + # Dispatch enter and leave events for CallOrWriteNode nodes and continue + # walking the tree. + def visit_call_or_write_node(node) + listeners[:on_call_or_write_node_enter]&.each { |listener| listener.on_call_or_write_node_enter(node) } + super + listeners[:on_call_or_write_node_leave]&.each { |listener| listener.on_call_or_write_node_leave(node) } + end + + # Dispatch enter and leave events for CallTargetNode nodes and continue + # walking the tree. + def visit_call_target_node(node) + listeners[:on_call_target_node_enter]&.each { |listener| listener.on_call_target_node_enter(node) } + super + listeners[:on_call_target_node_leave]&.each { |listener| listener.on_call_target_node_leave(node) } + end + + # Dispatch enter and leave events for CapturePatternNode nodes and continue + # walking the tree. + def visit_capture_pattern_node(node) + listeners[:on_capture_pattern_node_enter]&.each { |listener| listener.on_capture_pattern_node_enter(node) } + super + listeners[:on_capture_pattern_node_leave]&.each { |listener| listener.on_capture_pattern_node_leave(node) } + end + + # Dispatch enter and leave events for CaseMatchNode nodes and continue + # walking the tree. + def visit_case_match_node(node) + listeners[:on_case_match_node_enter]&.each { |listener| listener.on_case_match_node_enter(node) } + super + listeners[:on_case_match_node_leave]&.each { |listener| listener.on_case_match_node_leave(node) } + end + + # Dispatch enter and leave events for CaseNode nodes and continue + # walking the tree. + def visit_case_node(node) + listeners[:on_case_node_enter]&.each { |listener| listener.on_case_node_enter(node) } + super + listeners[:on_case_node_leave]&.each { |listener| listener.on_case_node_leave(node) } + end + + # Dispatch enter and leave events for ClassNode nodes and continue + # walking the tree. + def visit_class_node(node) + listeners[:on_class_node_enter]&.each { |listener| listener.on_class_node_enter(node) } + super + listeners[:on_class_node_leave]&.each { |listener| listener.on_class_node_leave(node) } + end + + # Dispatch enter and leave events for ClassVariableAndWriteNode nodes and continue + # walking the tree. + def visit_class_variable_and_write_node(node) + listeners[:on_class_variable_and_write_node_enter]&.each { |listener| listener.on_class_variable_and_write_node_enter(node) } + super + listeners[:on_class_variable_and_write_node_leave]&.each { |listener| listener.on_class_variable_and_write_node_leave(node) } + end + + # Dispatch enter and leave events for ClassVariableOperatorWriteNode nodes and continue + # walking the tree. + def visit_class_variable_operator_write_node(node) + listeners[:on_class_variable_operator_write_node_enter]&.each { |listener| listener.on_class_variable_operator_write_node_enter(node) } + super + listeners[:on_class_variable_operator_write_node_leave]&.each { |listener| listener.on_class_variable_operator_write_node_leave(node) } + end + + # Dispatch enter and leave events for ClassVariableOrWriteNode nodes and continue + # walking the tree. + def visit_class_variable_or_write_node(node) + listeners[:on_class_variable_or_write_node_enter]&.each { |listener| listener.on_class_variable_or_write_node_enter(node) } + super + listeners[:on_class_variable_or_write_node_leave]&.each { |listener| listener.on_class_variable_or_write_node_leave(node) } + end + + # Dispatch enter and leave events for ClassVariableReadNode nodes and continue + # walking the tree. + def visit_class_variable_read_node(node) + listeners[:on_class_variable_read_node_enter]&.each { |listener| listener.on_class_variable_read_node_enter(node) } + super + listeners[:on_class_variable_read_node_leave]&.each { |listener| listener.on_class_variable_read_node_leave(node) } + end + + # Dispatch enter and leave events for ClassVariableTargetNode nodes and continue + # walking the tree. + def visit_class_variable_target_node(node) + listeners[:on_class_variable_target_node_enter]&.each { |listener| listener.on_class_variable_target_node_enter(node) } + super + listeners[:on_class_variable_target_node_leave]&.each { |listener| listener.on_class_variable_target_node_leave(node) } + end + + # Dispatch enter and leave events for ClassVariableWriteNode nodes and continue + # walking the tree. + def visit_class_variable_write_node(node) + listeners[:on_class_variable_write_node_enter]&.each { |listener| listener.on_class_variable_write_node_enter(node) } + super + listeners[:on_class_variable_write_node_leave]&.each { |listener| listener.on_class_variable_write_node_leave(node) } + end + + # Dispatch enter and leave events for ConstantAndWriteNode nodes and continue + # walking the tree. + def visit_constant_and_write_node(node) + listeners[:on_constant_and_write_node_enter]&.each { |listener| listener.on_constant_and_write_node_enter(node) } + super + listeners[:on_constant_and_write_node_leave]&.each { |listener| listener.on_constant_and_write_node_leave(node) } + end + + # Dispatch enter and leave events for ConstantOperatorWriteNode nodes and continue + # walking the tree. + def visit_constant_operator_write_node(node) + listeners[:on_constant_operator_write_node_enter]&.each { |listener| listener.on_constant_operator_write_node_enter(node) } + super + listeners[:on_constant_operator_write_node_leave]&.each { |listener| listener.on_constant_operator_write_node_leave(node) } + end + + # Dispatch enter and leave events for ConstantOrWriteNode nodes and continue + # walking the tree. + def visit_constant_or_write_node(node) + listeners[:on_constant_or_write_node_enter]&.each { |listener| listener.on_constant_or_write_node_enter(node) } + super + listeners[:on_constant_or_write_node_leave]&.each { |listener| listener.on_constant_or_write_node_leave(node) } + end + + # Dispatch enter and leave events for ConstantPathAndWriteNode nodes and continue + # walking the tree. + def visit_constant_path_and_write_node(node) + listeners[:on_constant_path_and_write_node_enter]&.each { |listener| listener.on_constant_path_and_write_node_enter(node) } + super + listeners[:on_constant_path_and_write_node_leave]&.each { |listener| listener.on_constant_path_and_write_node_leave(node) } + end + + # Dispatch enter and leave events for ConstantPathNode nodes and continue + # walking the tree. + def visit_constant_path_node(node) + listeners[:on_constant_path_node_enter]&.each { |listener| listener.on_constant_path_node_enter(node) } + super + listeners[:on_constant_path_node_leave]&.each { |listener| listener.on_constant_path_node_leave(node) } + end + + # Dispatch enter and leave events for ConstantPathOperatorWriteNode nodes and continue + # walking the tree. + def visit_constant_path_operator_write_node(node) + listeners[:on_constant_path_operator_write_node_enter]&.each { |listener| listener.on_constant_path_operator_write_node_enter(node) } + super + listeners[:on_constant_path_operator_write_node_leave]&.each { |listener| listener.on_constant_path_operator_write_node_leave(node) } + end + + # Dispatch enter and leave events for ConstantPathOrWriteNode nodes and continue + # walking the tree. + def visit_constant_path_or_write_node(node) + listeners[:on_constant_path_or_write_node_enter]&.each { |listener| listener.on_constant_path_or_write_node_enter(node) } + super + listeners[:on_constant_path_or_write_node_leave]&.each { |listener| listener.on_constant_path_or_write_node_leave(node) } + end + + # Dispatch enter and leave events for ConstantPathTargetNode nodes and continue + # walking the tree. + def visit_constant_path_target_node(node) + listeners[:on_constant_path_target_node_enter]&.each { |listener| listener.on_constant_path_target_node_enter(node) } + super + listeners[:on_constant_path_target_node_leave]&.each { |listener| listener.on_constant_path_target_node_leave(node) } + end + + # Dispatch enter and leave events for ConstantPathWriteNode nodes and continue + # walking the tree. + def visit_constant_path_write_node(node) + listeners[:on_constant_path_write_node_enter]&.each { |listener| listener.on_constant_path_write_node_enter(node) } + super + listeners[:on_constant_path_write_node_leave]&.each { |listener| listener.on_constant_path_write_node_leave(node) } + end + + # Dispatch enter and leave events for ConstantReadNode nodes and continue + # walking the tree. + def visit_constant_read_node(node) + listeners[:on_constant_read_node_enter]&.each { |listener| listener.on_constant_read_node_enter(node) } + super + listeners[:on_constant_read_node_leave]&.each { |listener| listener.on_constant_read_node_leave(node) } + end + + # Dispatch enter and leave events for ConstantTargetNode nodes and continue + # walking the tree. + def visit_constant_target_node(node) + listeners[:on_constant_target_node_enter]&.each { |listener| listener.on_constant_target_node_enter(node) } + super + listeners[:on_constant_target_node_leave]&.each { |listener| listener.on_constant_target_node_leave(node) } + end + + # Dispatch enter and leave events for ConstantWriteNode nodes and continue + # walking the tree. + def visit_constant_write_node(node) + listeners[:on_constant_write_node_enter]&.each { |listener| listener.on_constant_write_node_enter(node) } + super + listeners[:on_constant_write_node_leave]&.each { |listener| listener.on_constant_write_node_leave(node) } + end + + # Dispatch enter and leave events for DefNode nodes and continue + # walking the tree. + def visit_def_node(node) + listeners[:on_def_node_enter]&.each { |listener| listener.on_def_node_enter(node) } + super + listeners[:on_def_node_leave]&.each { |listener| listener.on_def_node_leave(node) } + end + + # Dispatch enter and leave events for DefinedNode nodes and continue + # walking the tree. + def visit_defined_node(node) + listeners[:on_defined_node_enter]&.each { |listener| listener.on_defined_node_enter(node) } + super + listeners[:on_defined_node_leave]&.each { |listener| listener.on_defined_node_leave(node) } + end + + # Dispatch enter and leave events for ElseNode nodes and continue + # walking the tree. + def visit_else_node(node) + listeners[:on_else_node_enter]&.each { |listener| listener.on_else_node_enter(node) } + super + listeners[:on_else_node_leave]&.each { |listener| listener.on_else_node_leave(node) } + end + + # Dispatch enter and leave events for EmbeddedStatementsNode nodes and continue + # walking the tree. + def visit_embedded_statements_node(node) + listeners[:on_embedded_statements_node_enter]&.each { |listener| listener.on_embedded_statements_node_enter(node) } + super + listeners[:on_embedded_statements_node_leave]&.each { |listener| listener.on_embedded_statements_node_leave(node) } + end + + # Dispatch enter and leave events for EmbeddedVariableNode nodes and continue + # walking the tree. + def visit_embedded_variable_node(node) + listeners[:on_embedded_variable_node_enter]&.each { |listener| listener.on_embedded_variable_node_enter(node) } + super + listeners[:on_embedded_variable_node_leave]&.each { |listener| listener.on_embedded_variable_node_leave(node) } + end + + # Dispatch enter and leave events for EnsureNode nodes and continue + # walking the tree. + def visit_ensure_node(node) + listeners[:on_ensure_node_enter]&.each { |listener| listener.on_ensure_node_enter(node) } + super + listeners[:on_ensure_node_leave]&.each { |listener| listener.on_ensure_node_leave(node) } + end + + # Dispatch enter and leave events for FalseNode nodes and continue + # walking the tree. + def visit_false_node(node) + listeners[:on_false_node_enter]&.each { |listener| listener.on_false_node_enter(node) } + super + listeners[:on_false_node_leave]&.each { |listener| listener.on_false_node_leave(node) } + end + + # Dispatch enter and leave events for FindPatternNode nodes and continue + # walking the tree. + def visit_find_pattern_node(node) + listeners[:on_find_pattern_node_enter]&.each { |listener| listener.on_find_pattern_node_enter(node) } + super + listeners[:on_find_pattern_node_leave]&.each { |listener| listener.on_find_pattern_node_leave(node) } + end + + # Dispatch enter and leave events for FlipFlopNode nodes and continue + # walking the tree. + def visit_flip_flop_node(node) + listeners[:on_flip_flop_node_enter]&.each { |listener| listener.on_flip_flop_node_enter(node) } + super + listeners[:on_flip_flop_node_leave]&.each { |listener| listener.on_flip_flop_node_leave(node) } + end + + # Dispatch enter and leave events for FloatNode nodes and continue + # walking the tree. + def visit_float_node(node) + listeners[:on_float_node_enter]&.each { |listener| listener.on_float_node_enter(node) } + super + listeners[:on_float_node_leave]&.each { |listener| listener.on_float_node_leave(node) } + end + + # Dispatch enter and leave events for ForNode nodes and continue + # walking the tree. + def visit_for_node(node) + listeners[:on_for_node_enter]&.each { |listener| listener.on_for_node_enter(node) } + super + listeners[:on_for_node_leave]&.each { |listener| listener.on_for_node_leave(node) } + end + + # Dispatch enter and leave events for ForwardingArgumentsNode nodes and continue + # walking the tree. + def visit_forwarding_arguments_node(node) + listeners[:on_forwarding_arguments_node_enter]&.each { |listener| listener.on_forwarding_arguments_node_enter(node) } + super + listeners[:on_forwarding_arguments_node_leave]&.each { |listener| listener.on_forwarding_arguments_node_leave(node) } + end + + # Dispatch enter and leave events for ForwardingParameterNode nodes and continue + # walking the tree. + def visit_forwarding_parameter_node(node) + listeners[:on_forwarding_parameter_node_enter]&.each { |listener| listener.on_forwarding_parameter_node_enter(node) } + super + listeners[:on_forwarding_parameter_node_leave]&.each { |listener| listener.on_forwarding_parameter_node_leave(node) } + end + + # Dispatch enter and leave events for ForwardingSuperNode nodes and continue + # walking the tree. + def visit_forwarding_super_node(node) + listeners[:on_forwarding_super_node_enter]&.each { |listener| listener.on_forwarding_super_node_enter(node) } + super + listeners[:on_forwarding_super_node_leave]&.each { |listener| listener.on_forwarding_super_node_leave(node) } + end + + # Dispatch enter and leave events for GlobalVariableAndWriteNode nodes and continue + # walking the tree. + def visit_global_variable_and_write_node(node) + listeners[:on_global_variable_and_write_node_enter]&.each { |listener| listener.on_global_variable_and_write_node_enter(node) } + super + listeners[:on_global_variable_and_write_node_leave]&.each { |listener| listener.on_global_variable_and_write_node_leave(node) } + end + + # Dispatch enter and leave events for GlobalVariableOperatorWriteNode nodes and continue + # walking the tree. + def visit_global_variable_operator_write_node(node) + listeners[:on_global_variable_operator_write_node_enter]&.each { |listener| listener.on_global_variable_operator_write_node_enter(node) } + super + listeners[:on_global_variable_operator_write_node_leave]&.each { |listener| listener.on_global_variable_operator_write_node_leave(node) } + end + + # Dispatch enter and leave events for GlobalVariableOrWriteNode nodes and continue + # walking the tree. + def visit_global_variable_or_write_node(node) + listeners[:on_global_variable_or_write_node_enter]&.each { |listener| listener.on_global_variable_or_write_node_enter(node) } + super + listeners[:on_global_variable_or_write_node_leave]&.each { |listener| listener.on_global_variable_or_write_node_leave(node) } + end + + # Dispatch enter and leave events for GlobalVariableReadNode nodes and continue + # walking the tree. + def visit_global_variable_read_node(node) + listeners[:on_global_variable_read_node_enter]&.each { |listener| listener.on_global_variable_read_node_enter(node) } + super + listeners[:on_global_variable_read_node_leave]&.each { |listener| listener.on_global_variable_read_node_leave(node) } + end + + # Dispatch enter and leave events for GlobalVariableTargetNode nodes and continue + # walking the tree. + def visit_global_variable_target_node(node) + listeners[:on_global_variable_target_node_enter]&.each { |listener| listener.on_global_variable_target_node_enter(node) } + super + listeners[:on_global_variable_target_node_leave]&.each { |listener| listener.on_global_variable_target_node_leave(node) } + end + + # Dispatch enter and leave events for GlobalVariableWriteNode nodes and continue + # walking the tree. + def visit_global_variable_write_node(node) + listeners[:on_global_variable_write_node_enter]&.each { |listener| listener.on_global_variable_write_node_enter(node) } + super + listeners[:on_global_variable_write_node_leave]&.each { |listener| listener.on_global_variable_write_node_leave(node) } + end + + # Dispatch enter and leave events for HashNode nodes and continue + # walking the tree. + def visit_hash_node(node) + listeners[:on_hash_node_enter]&.each { |listener| listener.on_hash_node_enter(node) } + super + listeners[:on_hash_node_leave]&.each { |listener| listener.on_hash_node_leave(node) } + end + + # Dispatch enter and leave events for HashPatternNode nodes and continue + # walking the tree. + def visit_hash_pattern_node(node) + listeners[:on_hash_pattern_node_enter]&.each { |listener| listener.on_hash_pattern_node_enter(node) } + super + listeners[:on_hash_pattern_node_leave]&.each { |listener| listener.on_hash_pattern_node_leave(node) } + end + + # Dispatch enter and leave events for IfNode nodes and continue + # walking the tree. + def visit_if_node(node) + listeners[:on_if_node_enter]&.each { |listener| listener.on_if_node_enter(node) } + super + listeners[:on_if_node_leave]&.each { |listener| listener.on_if_node_leave(node) } + end + + # Dispatch enter and leave events for ImaginaryNode nodes and continue + # walking the tree. + def visit_imaginary_node(node) + listeners[:on_imaginary_node_enter]&.each { |listener| listener.on_imaginary_node_enter(node) } + super + listeners[:on_imaginary_node_leave]&.each { |listener| listener.on_imaginary_node_leave(node) } + end + + # Dispatch enter and leave events for ImplicitNode nodes and continue + # walking the tree. + def visit_implicit_node(node) + listeners[:on_implicit_node_enter]&.each { |listener| listener.on_implicit_node_enter(node) } + super + listeners[:on_implicit_node_leave]&.each { |listener| listener.on_implicit_node_leave(node) } + end + + # Dispatch enter and leave events for ImplicitRestNode nodes and continue + # walking the tree. + def visit_implicit_rest_node(node) + listeners[:on_implicit_rest_node_enter]&.each { |listener| listener.on_implicit_rest_node_enter(node) } + super + listeners[:on_implicit_rest_node_leave]&.each { |listener| listener.on_implicit_rest_node_leave(node) } + end + + # Dispatch enter and leave events for InNode nodes and continue + # walking the tree. + def visit_in_node(node) + listeners[:on_in_node_enter]&.each { |listener| listener.on_in_node_enter(node) } + super + listeners[:on_in_node_leave]&.each { |listener| listener.on_in_node_leave(node) } + end + + # Dispatch enter and leave events for IndexAndWriteNode nodes and continue + # walking the tree. + def visit_index_and_write_node(node) + listeners[:on_index_and_write_node_enter]&.each { |listener| listener.on_index_and_write_node_enter(node) } + super + listeners[:on_index_and_write_node_leave]&.each { |listener| listener.on_index_and_write_node_leave(node) } + end + + # Dispatch enter and leave events for IndexOperatorWriteNode nodes and continue + # walking the tree. + def visit_index_operator_write_node(node) + listeners[:on_index_operator_write_node_enter]&.each { |listener| listener.on_index_operator_write_node_enter(node) } + super + listeners[:on_index_operator_write_node_leave]&.each { |listener| listener.on_index_operator_write_node_leave(node) } + end + + # Dispatch enter and leave events for IndexOrWriteNode nodes and continue + # walking the tree. + def visit_index_or_write_node(node) + listeners[:on_index_or_write_node_enter]&.each { |listener| listener.on_index_or_write_node_enter(node) } + super + listeners[:on_index_or_write_node_leave]&.each { |listener| listener.on_index_or_write_node_leave(node) } + end + + # Dispatch enter and leave events for IndexTargetNode nodes and continue + # walking the tree. + def visit_index_target_node(node) + listeners[:on_index_target_node_enter]&.each { |listener| listener.on_index_target_node_enter(node) } + super + listeners[:on_index_target_node_leave]&.each { |listener| listener.on_index_target_node_leave(node) } + end + + # Dispatch enter and leave events for InstanceVariableAndWriteNode nodes and continue + # walking the tree. + def visit_instance_variable_and_write_node(node) + listeners[:on_instance_variable_and_write_node_enter]&.each { |listener| listener.on_instance_variable_and_write_node_enter(node) } + super + listeners[:on_instance_variable_and_write_node_leave]&.each { |listener| listener.on_instance_variable_and_write_node_leave(node) } + end + + # Dispatch enter and leave events for InstanceVariableOperatorWriteNode nodes and continue + # walking the tree. + def visit_instance_variable_operator_write_node(node) + listeners[:on_instance_variable_operator_write_node_enter]&.each { |listener| listener.on_instance_variable_operator_write_node_enter(node) } + super + listeners[:on_instance_variable_operator_write_node_leave]&.each { |listener| listener.on_instance_variable_operator_write_node_leave(node) } + end + + # Dispatch enter and leave events for InstanceVariableOrWriteNode nodes and continue + # walking the tree. + def visit_instance_variable_or_write_node(node) + listeners[:on_instance_variable_or_write_node_enter]&.each { |listener| listener.on_instance_variable_or_write_node_enter(node) } + super + listeners[:on_instance_variable_or_write_node_leave]&.each { |listener| listener.on_instance_variable_or_write_node_leave(node) } + end + + # Dispatch enter and leave events for InstanceVariableReadNode nodes and continue + # walking the tree. + def visit_instance_variable_read_node(node) + listeners[:on_instance_variable_read_node_enter]&.each { |listener| listener.on_instance_variable_read_node_enter(node) } + super + listeners[:on_instance_variable_read_node_leave]&.each { |listener| listener.on_instance_variable_read_node_leave(node) } + end + + # Dispatch enter and leave events for InstanceVariableTargetNode nodes and continue + # walking the tree. + def visit_instance_variable_target_node(node) + listeners[:on_instance_variable_target_node_enter]&.each { |listener| listener.on_instance_variable_target_node_enter(node) } + super + listeners[:on_instance_variable_target_node_leave]&.each { |listener| listener.on_instance_variable_target_node_leave(node) } + end + + # Dispatch enter and leave events for InstanceVariableWriteNode nodes and continue + # walking the tree. + def visit_instance_variable_write_node(node) + listeners[:on_instance_variable_write_node_enter]&.each { |listener| listener.on_instance_variable_write_node_enter(node) } + super + listeners[:on_instance_variable_write_node_leave]&.each { |listener| listener.on_instance_variable_write_node_leave(node) } + end + + # Dispatch enter and leave events for IntegerNode nodes and continue + # walking the tree. + def visit_integer_node(node) + listeners[:on_integer_node_enter]&.each { |listener| listener.on_integer_node_enter(node) } + super + listeners[:on_integer_node_leave]&.each { |listener| listener.on_integer_node_leave(node) } + end + + # Dispatch enter and leave events for InterpolatedMatchLastLineNode nodes and continue + # walking the tree. + def visit_interpolated_match_last_line_node(node) + listeners[:on_interpolated_match_last_line_node_enter]&.each { |listener| listener.on_interpolated_match_last_line_node_enter(node) } + super + listeners[:on_interpolated_match_last_line_node_leave]&.each { |listener| listener.on_interpolated_match_last_line_node_leave(node) } + end + + # Dispatch enter and leave events for InterpolatedRegularExpressionNode nodes and continue + # walking the tree. + def visit_interpolated_regular_expression_node(node) + listeners[:on_interpolated_regular_expression_node_enter]&.each { |listener| listener.on_interpolated_regular_expression_node_enter(node) } + super + listeners[:on_interpolated_regular_expression_node_leave]&.each { |listener| listener.on_interpolated_regular_expression_node_leave(node) } + end + + # Dispatch enter and leave events for InterpolatedStringNode nodes and continue + # walking the tree. + def visit_interpolated_string_node(node) + listeners[:on_interpolated_string_node_enter]&.each { |listener| listener.on_interpolated_string_node_enter(node) } + super + listeners[:on_interpolated_string_node_leave]&.each { |listener| listener.on_interpolated_string_node_leave(node) } + end + + # Dispatch enter and leave events for InterpolatedSymbolNode nodes and continue + # walking the tree. + def visit_interpolated_symbol_node(node) + listeners[:on_interpolated_symbol_node_enter]&.each { |listener| listener.on_interpolated_symbol_node_enter(node) } + super + listeners[:on_interpolated_symbol_node_leave]&.each { |listener| listener.on_interpolated_symbol_node_leave(node) } + end + + # Dispatch enter and leave events for InterpolatedXStringNode nodes and continue + # walking the tree. + def visit_interpolated_x_string_node(node) + listeners[:on_interpolated_x_string_node_enter]&.each { |listener| listener.on_interpolated_x_string_node_enter(node) } + super + listeners[:on_interpolated_x_string_node_leave]&.each { |listener| listener.on_interpolated_x_string_node_leave(node) } + end + + # Dispatch enter and leave events for ItLocalVariableReadNode nodes and continue + # walking the tree. + def visit_it_local_variable_read_node(node) + listeners[:on_it_local_variable_read_node_enter]&.each { |listener| listener.on_it_local_variable_read_node_enter(node) } + super + listeners[:on_it_local_variable_read_node_leave]&.each { |listener| listener.on_it_local_variable_read_node_leave(node) } + end + + # Dispatch enter and leave events for ItParametersNode nodes and continue + # walking the tree. + def visit_it_parameters_node(node) + listeners[:on_it_parameters_node_enter]&.each { |listener| listener.on_it_parameters_node_enter(node) } + super + listeners[:on_it_parameters_node_leave]&.each { |listener| listener.on_it_parameters_node_leave(node) } + end + + # Dispatch enter and leave events for KeywordHashNode nodes and continue + # walking the tree. + def visit_keyword_hash_node(node) + listeners[:on_keyword_hash_node_enter]&.each { |listener| listener.on_keyword_hash_node_enter(node) } + super + listeners[:on_keyword_hash_node_leave]&.each { |listener| listener.on_keyword_hash_node_leave(node) } + end + + # Dispatch enter and leave events for KeywordRestParameterNode nodes and continue + # walking the tree. + def visit_keyword_rest_parameter_node(node) + listeners[:on_keyword_rest_parameter_node_enter]&.each { |listener| listener.on_keyword_rest_parameter_node_enter(node) } + super + listeners[:on_keyword_rest_parameter_node_leave]&.each { |listener| listener.on_keyword_rest_parameter_node_leave(node) } + end + + # Dispatch enter and leave events for LambdaNode nodes and continue + # walking the tree. + def visit_lambda_node(node) + listeners[:on_lambda_node_enter]&.each { |listener| listener.on_lambda_node_enter(node) } + super + listeners[:on_lambda_node_leave]&.each { |listener| listener.on_lambda_node_leave(node) } + end + + # Dispatch enter and leave events for LocalVariableAndWriteNode nodes and continue + # walking the tree. + def visit_local_variable_and_write_node(node) + listeners[:on_local_variable_and_write_node_enter]&.each { |listener| listener.on_local_variable_and_write_node_enter(node) } + super + listeners[:on_local_variable_and_write_node_leave]&.each { |listener| listener.on_local_variable_and_write_node_leave(node) } + end + + # Dispatch enter and leave events for LocalVariableOperatorWriteNode nodes and continue + # walking the tree. + def visit_local_variable_operator_write_node(node) + listeners[:on_local_variable_operator_write_node_enter]&.each { |listener| listener.on_local_variable_operator_write_node_enter(node) } + super + listeners[:on_local_variable_operator_write_node_leave]&.each { |listener| listener.on_local_variable_operator_write_node_leave(node) } + end + + # Dispatch enter and leave events for LocalVariableOrWriteNode nodes and continue + # walking the tree. + def visit_local_variable_or_write_node(node) + listeners[:on_local_variable_or_write_node_enter]&.each { |listener| listener.on_local_variable_or_write_node_enter(node) } + super + listeners[:on_local_variable_or_write_node_leave]&.each { |listener| listener.on_local_variable_or_write_node_leave(node) } + end + + # Dispatch enter and leave events for LocalVariableReadNode nodes and continue + # walking the tree. + def visit_local_variable_read_node(node) + listeners[:on_local_variable_read_node_enter]&.each { |listener| listener.on_local_variable_read_node_enter(node) } + super + listeners[:on_local_variable_read_node_leave]&.each { |listener| listener.on_local_variable_read_node_leave(node) } + end + + # Dispatch enter and leave events for LocalVariableTargetNode nodes and continue + # walking the tree. + def visit_local_variable_target_node(node) + listeners[:on_local_variable_target_node_enter]&.each { |listener| listener.on_local_variable_target_node_enter(node) } + super + listeners[:on_local_variable_target_node_leave]&.each { |listener| listener.on_local_variable_target_node_leave(node) } + end + + # Dispatch enter and leave events for LocalVariableWriteNode nodes and continue + # walking the tree. + def visit_local_variable_write_node(node) + listeners[:on_local_variable_write_node_enter]&.each { |listener| listener.on_local_variable_write_node_enter(node) } + super + listeners[:on_local_variable_write_node_leave]&.each { |listener| listener.on_local_variable_write_node_leave(node) } + end + + # Dispatch enter and leave events for MatchLastLineNode nodes and continue + # walking the tree. + def visit_match_last_line_node(node) + listeners[:on_match_last_line_node_enter]&.each { |listener| listener.on_match_last_line_node_enter(node) } + super + listeners[:on_match_last_line_node_leave]&.each { |listener| listener.on_match_last_line_node_leave(node) } + end + + # Dispatch enter and leave events for MatchPredicateNode nodes and continue + # walking the tree. + def visit_match_predicate_node(node) + listeners[:on_match_predicate_node_enter]&.each { |listener| listener.on_match_predicate_node_enter(node) } + super + listeners[:on_match_predicate_node_leave]&.each { |listener| listener.on_match_predicate_node_leave(node) } + end + + # Dispatch enter and leave events for MatchRequiredNode nodes and continue + # walking the tree. + def visit_match_required_node(node) + listeners[:on_match_required_node_enter]&.each { |listener| listener.on_match_required_node_enter(node) } + super + listeners[:on_match_required_node_leave]&.each { |listener| listener.on_match_required_node_leave(node) } + end + + # Dispatch enter and leave events for MatchWriteNode nodes and continue + # walking the tree. + def visit_match_write_node(node) + listeners[:on_match_write_node_enter]&.each { |listener| listener.on_match_write_node_enter(node) } + super + listeners[:on_match_write_node_leave]&.each { |listener| listener.on_match_write_node_leave(node) } + end + + # Dispatch enter and leave events for MissingNode nodes and continue + # walking the tree. + def visit_missing_node(node) + listeners[:on_missing_node_enter]&.each { |listener| listener.on_missing_node_enter(node) } + super + listeners[:on_missing_node_leave]&.each { |listener| listener.on_missing_node_leave(node) } + end + + # Dispatch enter and leave events for ModuleNode nodes and continue + # walking the tree. + def visit_module_node(node) + listeners[:on_module_node_enter]&.each { |listener| listener.on_module_node_enter(node) } + super + listeners[:on_module_node_leave]&.each { |listener| listener.on_module_node_leave(node) } + end + + # Dispatch enter and leave events for MultiTargetNode nodes and continue + # walking the tree. + def visit_multi_target_node(node) + listeners[:on_multi_target_node_enter]&.each { |listener| listener.on_multi_target_node_enter(node) } + super + listeners[:on_multi_target_node_leave]&.each { |listener| listener.on_multi_target_node_leave(node) } + end + + # Dispatch enter and leave events for MultiWriteNode nodes and continue + # walking the tree. + def visit_multi_write_node(node) + listeners[:on_multi_write_node_enter]&.each { |listener| listener.on_multi_write_node_enter(node) } + super + listeners[:on_multi_write_node_leave]&.each { |listener| listener.on_multi_write_node_leave(node) } + end + + # Dispatch enter and leave events for NextNode nodes and continue + # walking the tree. + def visit_next_node(node) + listeners[:on_next_node_enter]&.each { |listener| listener.on_next_node_enter(node) } + super + listeners[:on_next_node_leave]&.each { |listener| listener.on_next_node_leave(node) } + end + + # Dispatch enter and leave events for NilNode nodes and continue + # walking the tree. + def visit_nil_node(node) + listeners[:on_nil_node_enter]&.each { |listener| listener.on_nil_node_enter(node) } + super + listeners[:on_nil_node_leave]&.each { |listener| listener.on_nil_node_leave(node) } + end + + # Dispatch enter and leave events for NoKeywordsParameterNode nodes and continue + # walking the tree. + def visit_no_keywords_parameter_node(node) + listeners[:on_no_keywords_parameter_node_enter]&.each { |listener| listener.on_no_keywords_parameter_node_enter(node) } + super + listeners[:on_no_keywords_parameter_node_leave]&.each { |listener| listener.on_no_keywords_parameter_node_leave(node) } + end + + # Dispatch enter and leave events for NumberedParametersNode nodes and continue + # walking the tree. + def visit_numbered_parameters_node(node) + listeners[:on_numbered_parameters_node_enter]&.each { |listener| listener.on_numbered_parameters_node_enter(node) } + super + listeners[:on_numbered_parameters_node_leave]&.each { |listener| listener.on_numbered_parameters_node_leave(node) } + end + + # Dispatch enter and leave events for NumberedReferenceReadNode nodes and continue + # walking the tree. + def visit_numbered_reference_read_node(node) + listeners[:on_numbered_reference_read_node_enter]&.each { |listener| listener.on_numbered_reference_read_node_enter(node) } + super + listeners[:on_numbered_reference_read_node_leave]&.each { |listener| listener.on_numbered_reference_read_node_leave(node) } + end + + # Dispatch enter and leave events for OptionalKeywordParameterNode nodes and continue + # walking the tree. + def visit_optional_keyword_parameter_node(node) + listeners[:on_optional_keyword_parameter_node_enter]&.each { |listener| listener.on_optional_keyword_parameter_node_enter(node) } + super + listeners[:on_optional_keyword_parameter_node_leave]&.each { |listener| listener.on_optional_keyword_parameter_node_leave(node) } + end + + # Dispatch enter and leave events for OptionalParameterNode nodes and continue + # walking the tree. + def visit_optional_parameter_node(node) + listeners[:on_optional_parameter_node_enter]&.each { |listener| listener.on_optional_parameter_node_enter(node) } + super + listeners[:on_optional_parameter_node_leave]&.each { |listener| listener.on_optional_parameter_node_leave(node) } + end + + # Dispatch enter and leave events for OrNode nodes and continue + # walking the tree. + def visit_or_node(node) + listeners[:on_or_node_enter]&.each { |listener| listener.on_or_node_enter(node) } + super + listeners[:on_or_node_leave]&.each { |listener| listener.on_or_node_leave(node) } + end + + # Dispatch enter and leave events for ParametersNode nodes and continue + # walking the tree. + def visit_parameters_node(node) + listeners[:on_parameters_node_enter]&.each { |listener| listener.on_parameters_node_enter(node) } + super + listeners[:on_parameters_node_leave]&.each { |listener| listener.on_parameters_node_leave(node) } + end + + # Dispatch enter and leave events for ParenthesesNode nodes and continue + # walking the tree. + def visit_parentheses_node(node) + listeners[:on_parentheses_node_enter]&.each { |listener| listener.on_parentheses_node_enter(node) } + super + listeners[:on_parentheses_node_leave]&.each { |listener| listener.on_parentheses_node_leave(node) } + end + + # Dispatch enter and leave events for PinnedExpressionNode nodes and continue + # walking the tree. + def visit_pinned_expression_node(node) + listeners[:on_pinned_expression_node_enter]&.each { |listener| listener.on_pinned_expression_node_enter(node) } + super + listeners[:on_pinned_expression_node_leave]&.each { |listener| listener.on_pinned_expression_node_leave(node) } + end + + # Dispatch enter and leave events for PinnedVariableNode nodes and continue + # walking the tree. + def visit_pinned_variable_node(node) + listeners[:on_pinned_variable_node_enter]&.each { |listener| listener.on_pinned_variable_node_enter(node) } + super + listeners[:on_pinned_variable_node_leave]&.each { |listener| listener.on_pinned_variable_node_leave(node) } + end + + # Dispatch enter and leave events for PostExecutionNode nodes and continue + # walking the tree. + def visit_post_execution_node(node) + listeners[:on_post_execution_node_enter]&.each { |listener| listener.on_post_execution_node_enter(node) } + super + listeners[:on_post_execution_node_leave]&.each { |listener| listener.on_post_execution_node_leave(node) } + end + + # Dispatch enter and leave events for PreExecutionNode nodes and continue + # walking the tree. + def visit_pre_execution_node(node) + listeners[:on_pre_execution_node_enter]&.each { |listener| listener.on_pre_execution_node_enter(node) } + super + listeners[:on_pre_execution_node_leave]&.each { |listener| listener.on_pre_execution_node_leave(node) } + end + + # Dispatch enter and leave events for ProgramNode nodes and continue + # walking the tree. + def visit_program_node(node) + listeners[:on_program_node_enter]&.each { |listener| listener.on_program_node_enter(node) } + super + listeners[:on_program_node_leave]&.each { |listener| listener.on_program_node_leave(node) } + end + + # Dispatch enter and leave events for RangeNode nodes and continue + # walking the tree. + def visit_range_node(node) + listeners[:on_range_node_enter]&.each { |listener| listener.on_range_node_enter(node) } + super + listeners[:on_range_node_leave]&.each { |listener| listener.on_range_node_leave(node) } + end + + # Dispatch enter and leave events for RationalNode nodes and continue + # walking the tree. + def visit_rational_node(node) + listeners[:on_rational_node_enter]&.each { |listener| listener.on_rational_node_enter(node) } + super + listeners[:on_rational_node_leave]&.each { |listener| listener.on_rational_node_leave(node) } + end + + # Dispatch enter and leave events for RedoNode nodes and continue + # walking the tree. + def visit_redo_node(node) + listeners[:on_redo_node_enter]&.each { |listener| listener.on_redo_node_enter(node) } + super + listeners[:on_redo_node_leave]&.each { |listener| listener.on_redo_node_leave(node) } + end + + # Dispatch enter and leave events for RegularExpressionNode nodes and continue + # walking the tree. + def visit_regular_expression_node(node) + listeners[:on_regular_expression_node_enter]&.each { |listener| listener.on_regular_expression_node_enter(node) } + super + listeners[:on_regular_expression_node_leave]&.each { |listener| listener.on_regular_expression_node_leave(node) } + end + + # Dispatch enter and leave events for RequiredKeywordParameterNode nodes and continue + # walking the tree. + def visit_required_keyword_parameter_node(node) + listeners[:on_required_keyword_parameter_node_enter]&.each { |listener| listener.on_required_keyword_parameter_node_enter(node) } + super + listeners[:on_required_keyword_parameter_node_leave]&.each { |listener| listener.on_required_keyword_parameter_node_leave(node) } + end + + # Dispatch enter and leave events for RequiredParameterNode nodes and continue + # walking the tree. + def visit_required_parameter_node(node) + listeners[:on_required_parameter_node_enter]&.each { |listener| listener.on_required_parameter_node_enter(node) } + super + listeners[:on_required_parameter_node_leave]&.each { |listener| listener.on_required_parameter_node_leave(node) } + end + + # Dispatch enter and leave events for RescueModifierNode nodes and continue + # walking the tree. + def visit_rescue_modifier_node(node) + listeners[:on_rescue_modifier_node_enter]&.each { |listener| listener.on_rescue_modifier_node_enter(node) } + super + listeners[:on_rescue_modifier_node_leave]&.each { |listener| listener.on_rescue_modifier_node_leave(node) } + end + + # Dispatch enter and leave events for RescueNode nodes and continue + # walking the tree. + def visit_rescue_node(node) + listeners[:on_rescue_node_enter]&.each { |listener| listener.on_rescue_node_enter(node) } + super + listeners[:on_rescue_node_leave]&.each { |listener| listener.on_rescue_node_leave(node) } + end + + # Dispatch enter and leave events for RestParameterNode nodes and continue + # walking the tree. + def visit_rest_parameter_node(node) + listeners[:on_rest_parameter_node_enter]&.each { |listener| listener.on_rest_parameter_node_enter(node) } + super + listeners[:on_rest_parameter_node_leave]&.each { |listener| listener.on_rest_parameter_node_leave(node) } + end + + # Dispatch enter and leave events for RetryNode nodes and continue + # walking the tree. + def visit_retry_node(node) + listeners[:on_retry_node_enter]&.each { |listener| listener.on_retry_node_enter(node) } + super + listeners[:on_retry_node_leave]&.each { |listener| listener.on_retry_node_leave(node) } + end + + # Dispatch enter and leave events for ReturnNode nodes and continue + # walking the tree. + def visit_return_node(node) + listeners[:on_return_node_enter]&.each { |listener| listener.on_return_node_enter(node) } + super + listeners[:on_return_node_leave]&.each { |listener| listener.on_return_node_leave(node) } + end + + # Dispatch enter and leave events for SelfNode nodes and continue + # walking the tree. + def visit_self_node(node) + listeners[:on_self_node_enter]&.each { |listener| listener.on_self_node_enter(node) } + super + listeners[:on_self_node_leave]&.each { |listener| listener.on_self_node_leave(node) } + end + + # Dispatch enter and leave events for ShareableConstantNode nodes and continue + # walking the tree. + def visit_shareable_constant_node(node) + listeners[:on_shareable_constant_node_enter]&.each { |listener| listener.on_shareable_constant_node_enter(node) } + super + listeners[:on_shareable_constant_node_leave]&.each { |listener| listener.on_shareable_constant_node_leave(node) } + end + + # Dispatch enter and leave events for SingletonClassNode nodes and continue + # walking the tree. + def visit_singleton_class_node(node) + listeners[:on_singleton_class_node_enter]&.each { |listener| listener.on_singleton_class_node_enter(node) } + super + listeners[:on_singleton_class_node_leave]&.each { |listener| listener.on_singleton_class_node_leave(node) } + end + + # Dispatch enter and leave events for SourceEncodingNode nodes and continue + # walking the tree. + def visit_source_encoding_node(node) + listeners[:on_source_encoding_node_enter]&.each { |listener| listener.on_source_encoding_node_enter(node) } + super + listeners[:on_source_encoding_node_leave]&.each { |listener| listener.on_source_encoding_node_leave(node) } + end + + # Dispatch enter and leave events for SourceFileNode nodes and continue + # walking the tree. + def visit_source_file_node(node) + listeners[:on_source_file_node_enter]&.each { |listener| listener.on_source_file_node_enter(node) } + super + listeners[:on_source_file_node_leave]&.each { |listener| listener.on_source_file_node_leave(node) } + end + + # Dispatch enter and leave events for SourceLineNode nodes and continue + # walking the tree. + def visit_source_line_node(node) + listeners[:on_source_line_node_enter]&.each { |listener| listener.on_source_line_node_enter(node) } + super + listeners[:on_source_line_node_leave]&.each { |listener| listener.on_source_line_node_leave(node) } + end + + # Dispatch enter and leave events for SplatNode nodes and continue + # walking the tree. + def visit_splat_node(node) + listeners[:on_splat_node_enter]&.each { |listener| listener.on_splat_node_enter(node) } + super + listeners[:on_splat_node_leave]&.each { |listener| listener.on_splat_node_leave(node) } + end + + # Dispatch enter and leave events for StatementsNode nodes and continue + # walking the tree. + def visit_statements_node(node) + listeners[:on_statements_node_enter]&.each { |listener| listener.on_statements_node_enter(node) } + super + listeners[:on_statements_node_leave]&.each { |listener| listener.on_statements_node_leave(node) } + end + + # Dispatch enter and leave events for StringNode nodes and continue + # walking the tree. + def visit_string_node(node) + listeners[:on_string_node_enter]&.each { |listener| listener.on_string_node_enter(node) } + super + listeners[:on_string_node_leave]&.each { |listener| listener.on_string_node_leave(node) } + end + + # Dispatch enter and leave events for SuperNode nodes and continue + # walking the tree. + def visit_super_node(node) + listeners[:on_super_node_enter]&.each { |listener| listener.on_super_node_enter(node) } + super + listeners[:on_super_node_leave]&.each { |listener| listener.on_super_node_leave(node) } + end + + # Dispatch enter and leave events for SymbolNode nodes and continue + # walking the tree. + def visit_symbol_node(node) + listeners[:on_symbol_node_enter]&.each { |listener| listener.on_symbol_node_enter(node) } + super + listeners[:on_symbol_node_leave]&.each { |listener| listener.on_symbol_node_leave(node) } + end + + # Dispatch enter and leave events for TrueNode nodes and continue + # walking the tree. + def visit_true_node(node) + listeners[:on_true_node_enter]&.each { |listener| listener.on_true_node_enter(node) } + super + listeners[:on_true_node_leave]&.each { |listener| listener.on_true_node_leave(node) } + end + + # Dispatch enter and leave events for UndefNode nodes and continue + # walking the tree. + def visit_undef_node(node) + listeners[:on_undef_node_enter]&.each { |listener| listener.on_undef_node_enter(node) } + super + listeners[:on_undef_node_leave]&.each { |listener| listener.on_undef_node_leave(node) } + end + + # Dispatch enter and leave events for UnlessNode nodes and continue + # walking the tree. + def visit_unless_node(node) + listeners[:on_unless_node_enter]&.each { |listener| listener.on_unless_node_enter(node) } + super + listeners[:on_unless_node_leave]&.each { |listener| listener.on_unless_node_leave(node) } + end + + # Dispatch enter and leave events for UntilNode nodes and continue + # walking the tree. + def visit_until_node(node) + listeners[:on_until_node_enter]&.each { |listener| listener.on_until_node_enter(node) } + super + listeners[:on_until_node_leave]&.each { |listener| listener.on_until_node_leave(node) } + end + + # Dispatch enter and leave events for WhenNode nodes and continue + # walking the tree. + def visit_when_node(node) + listeners[:on_when_node_enter]&.each { |listener| listener.on_when_node_enter(node) } + super + listeners[:on_when_node_leave]&.each { |listener| listener.on_when_node_leave(node) } + end + + # Dispatch enter and leave events for WhileNode nodes and continue + # walking the tree. + def visit_while_node(node) + listeners[:on_while_node_enter]&.each { |listener| listener.on_while_node_enter(node) } + super + listeners[:on_while_node_leave]&.each { |listener| listener.on_while_node_leave(node) } + end + + # Dispatch enter and leave events for XStringNode nodes and continue + # walking the tree. + def visit_x_string_node(node) + listeners[:on_x_string_node_enter]&.each { |listener| listener.on_x_string_node_enter(node) } + super + listeners[:on_x_string_node_leave]&.each { |listener| listener.on_x_string_node_leave(node) } + end + + # Dispatch enter and leave events for YieldNode nodes and continue + # walking the tree. + def visit_yield_node(node) + listeners[:on_yield_node_enter]&.each { |listener| listener.on_yield_node_enter(node) } + super + listeners[:on_yield_node_leave]&.each { |listener| listener.on_yield_node_leave(node) } + end + + class DispatchOnce < Visitor # :nodoc: + attr_reader :listeners + + def initialize(listeners) + @listeners = listeners + end + + # Dispatch enter and leave events for AliasGlobalVariableNode nodes. + def visit_alias_global_variable_node(node) + listeners[:on_alias_global_variable_node_enter]&.each { |listener| listener.on_alias_global_variable_node_enter(node) } + listeners[:on_alias_global_variable_node_leave]&.each { |listener| listener.on_alias_global_variable_node_leave(node) } + end + + # Dispatch enter and leave events for AliasMethodNode nodes. + def visit_alias_method_node(node) + listeners[:on_alias_method_node_enter]&.each { |listener| listener.on_alias_method_node_enter(node) } + listeners[:on_alias_method_node_leave]&.each { |listener| listener.on_alias_method_node_leave(node) } + end + + # Dispatch enter and leave events for AlternationPatternNode nodes. + def visit_alternation_pattern_node(node) + listeners[:on_alternation_pattern_node_enter]&.each { |listener| listener.on_alternation_pattern_node_enter(node) } + listeners[:on_alternation_pattern_node_leave]&.each { |listener| listener.on_alternation_pattern_node_leave(node) } + end + + # Dispatch enter and leave events for AndNode nodes. + def visit_and_node(node) + listeners[:on_and_node_enter]&.each { |listener| listener.on_and_node_enter(node) } + listeners[:on_and_node_leave]&.each { |listener| listener.on_and_node_leave(node) } + end + + # Dispatch enter and leave events for ArgumentsNode nodes. + def visit_arguments_node(node) + listeners[:on_arguments_node_enter]&.each { |listener| listener.on_arguments_node_enter(node) } + listeners[:on_arguments_node_leave]&.each { |listener| listener.on_arguments_node_leave(node) } + end + + # Dispatch enter and leave events for ArrayNode nodes. + def visit_array_node(node) + listeners[:on_array_node_enter]&.each { |listener| listener.on_array_node_enter(node) } + listeners[:on_array_node_leave]&.each { |listener| listener.on_array_node_leave(node) } + end + + # Dispatch enter and leave events for ArrayPatternNode nodes. + def visit_array_pattern_node(node) + listeners[:on_array_pattern_node_enter]&.each { |listener| listener.on_array_pattern_node_enter(node) } + listeners[:on_array_pattern_node_leave]&.each { |listener| listener.on_array_pattern_node_leave(node) } + end + + # Dispatch enter and leave events for AssocNode nodes. + def visit_assoc_node(node) + listeners[:on_assoc_node_enter]&.each { |listener| listener.on_assoc_node_enter(node) } + listeners[:on_assoc_node_leave]&.each { |listener| listener.on_assoc_node_leave(node) } + end + + # Dispatch enter and leave events for AssocSplatNode nodes. + def visit_assoc_splat_node(node) + listeners[:on_assoc_splat_node_enter]&.each { |listener| listener.on_assoc_splat_node_enter(node) } + listeners[:on_assoc_splat_node_leave]&.each { |listener| listener.on_assoc_splat_node_leave(node) } + end + + # Dispatch enter and leave events for BackReferenceReadNode nodes. + def visit_back_reference_read_node(node) + listeners[:on_back_reference_read_node_enter]&.each { |listener| listener.on_back_reference_read_node_enter(node) } + listeners[:on_back_reference_read_node_leave]&.each { |listener| listener.on_back_reference_read_node_leave(node) } + end + + # Dispatch enter and leave events for BeginNode nodes. + def visit_begin_node(node) + listeners[:on_begin_node_enter]&.each { |listener| listener.on_begin_node_enter(node) } + listeners[:on_begin_node_leave]&.each { |listener| listener.on_begin_node_leave(node) } + end + + # Dispatch enter and leave events for BlockArgumentNode nodes. + def visit_block_argument_node(node) + listeners[:on_block_argument_node_enter]&.each { |listener| listener.on_block_argument_node_enter(node) } + listeners[:on_block_argument_node_leave]&.each { |listener| listener.on_block_argument_node_leave(node) } + end + + # Dispatch enter and leave events for BlockLocalVariableNode nodes. + def visit_block_local_variable_node(node) + listeners[:on_block_local_variable_node_enter]&.each { |listener| listener.on_block_local_variable_node_enter(node) } + listeners[:on_block_local_variable_node_leave]&.each { |listener| listener.on_block_local_variable_node_leave(node) } + end + + # Dispatch enter and leave events for BlockNode nodes. + def visit_block_node(node) + listeners[:on_block_node_enter]&.each { |listener| listener.on_block_node_enter(node) } + listeners[:on_block_node_leave]&.each { |listener| listener.on_block_node_leave(node) } + end + + # Dispatch enter and leave events for BlockParameterNode nodes. + def visit_block_parameter_node(node) + listeners[:on_block_parameter_node_enter]&.each { |listener| listener.on_block_parameter_node_enter(node) } + listeners[:on_block_parameter_node_leave]&.each { |listener| listener.on_block_parameter_node_leave(node) } + end + + # Dispatch enter and leave events for BlockParametersNode nodes. + def visit_block_parameters_node(node) + listeners[:on_block_parameters_node_enter]&.each { |listener| listener.on_block_parameters_node_enter(node) } + listeners[:on_block_parameters_node_leave]&.each { |listener| listener.on_block_parameters_node_leave(node) } + end + + # Dispatch enter and leave events for BreakNode nodes. + def visit_break_node(node) + listeners[:on_break_node_enter]&.each { |listener| listener.on_break_node_enter(node) } + listeners[:on_break_node_leave]&.each { |listener| listener.on_break_node_leave(node) } + end + + # Dispatch enter and leave events for CallAndWriteNode nodes. + def visit_call_and_write_node(node) + listeners[:on_call_and_write_node_enter]&.each { |listener| listener.on_call_and_write_node_enter(node) } + listeners[:on_call_and_write_node_leave]&.each { |listener| listener.on_call_and_write_node_leave(node) } + end + + # Dispatch enter and leave events for CallNode nodes. + def visit_call_node(node) + listeners[:on_call_node_enter]&.each { |listener| listener.on_call_node_enter(node) } + listeners[:on_call_node_leave]&.each { |listener| listener.on_call_node_leave(node) } + end + + # Dispatch enter and leave events for CallOperatorWriteNode nodes. + def visit_call_operator_write_node(node) + listeners[:on_call_operator_write_node_enter]&.each { |listener| listener.on_call_operator_write_node_enter(node) } + listeners[:on_call_operator_write_node_leave]&.each { |listener| listener.on_call_operator_write_node_leave(node) } + end + + # Dispatch enter and leave events for CallOrWriteNode nodes. + def visit_call_or_write_node(node) + listeners[:on_call_or_write_node_enter]&.each { |listener| listener.on_call_or_write_node_enter(node) } + listeners[:on_call_or_write_node_leave]&.each { |listener| listener.on_call_or_write_node_leave(node) } + end + + # Dispatch enter and leave events for CallTargetNode nodes. + def visit_call_target_node(node) + listeners[:on_call_target_node_enter]&.each { |listener| listener.on_call_target_node_enter(node) } + listeners[:on_call_target_node_leave]&.each { |listener| listener.on_call_target_node_leave(node) } + end + + # Dispatch enter and leave events for CapturePatternNode nodes. + def visit_capture_pattern_node(node) + listeners[:on_capture_pattern_node_enter]&.each { |listener| listener.on_capture_pattern_node_enter(node) } + listeners[:on_capture_pattern_node_leave]&.each { |listener| listener.on_capture_pattern_node_leave(node) } + end + + # Dispatch enter and leave events for CaseMatchNode nodes. + def visit_case_match_node(node) + listeners[:on_case_match_node_enter]&.each { |listener| listener.on_case_match_node_enter(node) } + listeners[:on_case_match_node_leave]&.each { |listener| listener.on_case_match_node_leave(node) } + end + + # Dispatch enter and leave events for CaseNode nodes. + def visit_case_node(node) + listeners[:on_case_node_enter]&.each { |listener| listener.on_case_node_enter(node) } + listeners[:on_case_node_leave]&.each { |listener| listener.on_case_node_leave(node) } + end + + # Dispatch enter and leave events for ClassNode nodes. + def visit_class_node(node) + listeners[:on_class_node_enter]&.each { |listener| listener.on_class_node_enter(node) } + listeners[:on_class_node_leave]&.each { |listener| listener.on_class_node_leave(node) } + end + + # Dispatch enter and leave events for ClassVariableAndWriteNode nodes. + def visit_class_variable_and_write_node(node) + listeners[:on_class_variable_and_write_node_enter]&.each { |listener| listener.on_class_variable_and_write_node_enter(node) } + listeners[:on_class_variable_and_write_node_leave]&.each { |listener| listener.on_class_variable_and_write_node_leave(node) } + end + + # Dispatch enter and leave events for ClassVariableOperatorWriteNode nodes. + def visit_class_variable_operator_write_node(node) + listeners[:on_class_variable_operator_write_node_enter]&.each { |listener| listener.on_class_variable_operator_write_node_enter(node) } + listeners[:on_class_variable_operator_write_node_leave]&.each { |listener| listener.on_class_variable_operator_write_node_leave(node) } + end + + # Dispatch enter and leave events for ClassVariableOrWriteNode nodes. + def visit_class_variable_or_write_node(node) + listeners[:on_class_variable_or_write_node_enter]&.each { |listener| listener.on_class_variable_or_write_node_enter(node) } + listeners[:on_class_variable_or_write_node_leave]&.each { |listener| listener.on_class_variable_or_write_node_leave(node) } + end + + # Dispatch enter and leave events for ClassVariableReadNode nodes. + def visit_class_variable_read_node(node) + listeners[:on_class_variable_read_node_enter]&.each { |listener| listener.on_class_variable_read_node_enter(node) } + listeners[:on_class_variable_read_node_leave]&.each { |listener| listener.on_class_variable_read_node_leave(node) } + end + + # Dispatch enter and leave events for ClassVariableTargetNode nodes. + def visit_class_variable_target_node(node) + listeners[:on_class_variable_target_node_enter]&.each { |listener| listener.on_class_variable_target_node_enter(node) } + listeners[:on_class_variable_target_node_leave]&.each { |listener| listener.on_class_variable_target_node_leave(node) } + end + + # Dispatch enter and leave events for ClassVariableWriteNode nodes. + def visit_class_variable_write_node(node) + listeners[:on_class_variable_write_node_enter]&.each { |listener| listener.on_class_variable_write_node_enter(node) } + listeners[:on_class_variable_write_node_leave]&.each { |listener| listener.on_class_variable_write_node_leave(node) } + end + + # Dispatch enter and leave events for ConstantAndWriteNode nodes. + def visit_constant_and_write_node(node) + listeners[:on_constant_and_write_node_enter]&.each { |listener| listener.on_constant_and_write_node_enter(node) } + listeners[:on_constant_and_write_node_leave]&.each { |listener| listener.on_constant_and_write_node_leave(node) } + end + + # Dispatch enter and leave events for ConstantOperatorWriteNode nodes. + def visit_constant_operator_write_node(node) + listeners[:on_constant_operator_write_node_enter]&.each { |listener| listener.on_constant_operator_write_node_enter(node) } + listeners[:on_constant_operator_write_node_leave]&.each { |listener| listener.on_constant_operator_write_node_leave(node) } + end + + # Dispatch enter and leave events for ConstantOrWriteNode nodes. + def visit_constant_or_write_node(node) + listeners[:on_constant_or_write_node_enter]&.each { |listener| listener.on_constant_or_write_node_enter(node) } + listeners[:on_constant_or_write_node_leave]&.each { |listener| listener.on_constant_or_write_node_leave(node) } + end + + # Dispatch enter and leave events for ConstantPathAndWriteNode nodes. + def visit_constant_path_and_write_node(node) + listeners[:on_constant_path_and_write_node_enter]&.each { |listener| listener.on_constant_path_and_write_node_enter(node) } + listeners[:on_constant_path_and_write_node_leave]&.each { |listener| listener.on_constant_path_and_write_node_leave(node) } + end + + # Dispatch enter and leave events for ConstantPathNode nodes. + def visit_constant_path_node(node) + listeners[:on_constant_path_node_enter]&.each { |listener| listener.on_constant_path_node_enter(node) } + listeners[:on_constant_path_node_leave]&.each { |listener| listener.on_constant_path_node_leave(node) } + end + + # Dispatch enter and leave events for ConstantPathOperatorWriteNode nodes. + def visit_constant_path_operator_write_node(node) + listeners[:on_constant_path_operator_write_node_enter]&.each { |listener| listener.on_constant_path_operator_write_node_enter(node) } + listeners[:on_constant_path_operator_write_node_leave]&.each { |listener| listener.on_constant_path_operator_write_node_leave(node) } + end + + # Dispatch enter and leave events for ConstantPathOrWriteNode nodes. + def visit_constant_path_or_write_node(node) + listeners[:on_constant_path_or_write_node_enter]&.each { |listener| listener.on_constant_path_or_write_node_enter(node) } + listeners[:on_constant_path_or_write_node_leave]&.each { |listener| listener.on_constant_path_or_write_node_leave(node) } + end + + # Dispatch enter and leave events for ConstantPathTargetNode nodes. + def visit_constant_path_target_node(node) + listeners[:on_constant_path_target_node_enter]&.each { |listener| listener.on_constant_path_target_node_enter(node) } + listeners[:on_constant_path_target_node_leave]&.each { |listener| listener.on_constant_path_target_node_leave(node) } + end + + # Dispatch enter and leave events for ConstantPathWriteNode nodes. + def visit_constant_path_write_node(node) + listeners[:on_constant_path_write_node_enter]&.each { |listener| listener.on_constant_path_write_node_enter(node) } + listeners[:on_constant_path_write_node_leave]&.each { |listener| listener.on_constant_path_write_node_leave(node) } + end + + # Dispatch enter and leave events for ConstantReadNode nodes. + def visit_constant_read_node(node) + listeners[:on_constant_read_node_enter]&.each { |listener| listener.on_constant_read_node_enter(node) } + listeners[:on_constant_read_node_leave]&.each { |listener| listener.on_constant_read_node_leave(node) } + end + + # Dispatch enter and leave events for ConstantTargetNode nodes. + def visit_constant_target_node(node) + listeners[:on_constant_target_node_enter]&.each { |listener| listener.on_constant_target_node_enter(node) } + listeners[:on_constant_target_node_leave]&.each { |listener| listener.on_constant_target_node_leave(node) } + end + + # Dispatch enter and leave events for ConstantWriteNode nodes. + def visit_constant_write_node(node) + listeners[:on_constant_write_node_enter]&.each { |listener| listener.on_constant_write_node_enter(node) } + listeners[:on_constant_write_node_leave]&.each { |listener| listener.on_constant_write_node_leave(node) } + end + + # Dispatch enter and leave events for DefNode nodes. + def visit_def_node(node) + listeners[:on_def_node_enter]&.each { |listener| listener.on_def_node_enter(node) } + listeners[:on_def_node_leave]&.each { |listener| listener.on_def_node_leave(node) } + end + + # Dispatch enter and leave events for DefinedNode nodes. + def visit_defined_node(node) + listeners[:on_defined_node_enter]&.each { |listener| listener.on_defined_node_enter(node) } + listeners[:on_defined_node_leave]&.each { |listener| listener.on_defined_node_leave(node) } + end + + # Dispatch enter and leave events for ElseNode nodes. + def visit_else_node(node) + listeners[:on_else_node_enter]&.each { |listener| listener.on_else_node_enter(node) } + listeners[:on_else_node_leave]&.each { |listener| listener.on_else_node_leave(node) } + end + + # Dispatch enter and leave events for EmbeddedStatementsNode nodes. + def visit_embedded_statements_node(node) + listeners[:on_embedded_statements_node_enter]&.each { |listener| listener.on_embedded_statements_node_enter(node) } + listeners[:on_embedded_statements_node_leave]&.each { |listener| listener.on_embedded_statements_node_leave(node) } + end + + # Dispatch enter and leave events for EmbeddedVariableNode nodes. + def visit_embedded_variable_node(node) + listeners[:on_embedded_variable_node_enter]&.each { |listener| listener.on_embedded_variable_node_enter(node) } + listeners[:on_embedded_variable_node_leave]&.each { |listener| listener.on_embedded_variable_node_leave(node) } + end + + # Dispatch enter and leave events for EnsureNode nodes. + def visit_ensure_node(node) + listeners[:on_ensure_node_enter]&.each { |listener| listener.on_ensure_node_enter(node) } + listeners[:on_ensure_node_leave]&.each { |listener| listener.on_ensure_node_leave(node) } + end + + # Dispatch enter and leave events for FalseNode nodes. + def visit_false_node(node) + listeners[:on_false_node_enter]&.each { |listener| listener.on_false_node_enter(node) } + listeners[:on_false_node_leave]&.each { |listener| listener.on_false_node_leave(node) } + end + + # Dispatch enter and leave events for FindPatternNode nodes. + def visit_find_pattern_node(node) + listeners[:on_find_pattern_node_enter]&.each { |listener| listener.on_find_pattern_node_enter(node) } + listeners[:on_find_pattern_node_leave]&.each { |listener| listener.on_find_pattern_node_leave(node) } + end + + # Dispatch enter and leave events for FlipFlopNode nodes. + def visit_flip_flop_node(node) + listeners[:on_flip_flop_node_enter]&.each { |listener| listener.on_flip_flop_node_enter(node) } + listeners[:on_flip_flop_node_leave]&.each { |listener| listener.on_flip_flop_node_leave(node) } + end + + # Dispatch enter and leave events for FloatNode nodes. + def visit_float_node(node) + listeners[:on_float_node_enter]&.each { |listener| listener.on_float_node_enter(node) } + listeners[:on_float_node_leave]&.each { |listener| listener.on_float_node_leave(node) } + end + + # Dispatch enter and leave events for ForNode nodes. + def visit_for_node(node) + listeners[:on_for_node_enter]&.each { |listener| listener.on_for_node_enter(node) } + listeners[:on_for_node_leave]&.each { |listener| listener.on_for_node_leave(node) } + end + + # Dispatch enter and leave events for ForwardingArgumentsNode nodes. + def visit_forwarding_arguments_node(node) + listeners[:on_forwarding_arguments_node_enter]&.each { |listener| listener.on_forwarding_arguments_node_enter(node) } + listeners[:on_forwarding_arguments_node_leave]&.each { |listener| listener.on_forwarding_arguments_node_leave(node) } + end + + # Dispatch enter and leave events for ForwardingParameterNode nodes. + def visit_forwarding_parameter_node(node) + listeners[:on_forwarding_parameter_node_enter]&.each { |listener| listener.on_forwarding_parameter_node_enter(node) } + listeners[:on_forwarding_parameter_node_leave]&.each { |listener| listener.on_forwarding_parameter_node_leave(node) } + end + + # Dispatch enter and leave events for ForwardingSuperNode nodes. + def visit_forwarding_super_node(node) + listeners[:on_forwarding_super_node_enter]&.each { |listener| listener.on_forwarding_super_node_enter(node) } + listeners[:on_forwarding_super_node_leave]&.each { |listener| listener.on_forwarding_super_node_leave(node) } + end + + # Dispatch enter and leave events for GlobalVariableAndWriteNode nodes. + def visit_global_variable_and_write_node(node) + listeners[:on_global_variable_and_write_node_enter]&.each { |listener| listener.on_global_variable_and_write_node_enter(node) } + listeners[:on_global_variable_and_write_node_leave]&.each { |listener| listener.on_global_variable_and_write_node_leave(node) } + end + + # Dispatch enter and leave events for GlobalVariableOperatorWriteNode nodes. + def visit_global_variable_operator_write_node(node) + listeners[:on_global_variable_operator_write_node_enter]&.each { |listener| listener.on_global_variable_operator_write_node_enter(node) } + listeners[:on_global_variable_operator_write_node_leave]&.each { |listener| listener.on_global_variable_operator_write_node_leave(node) } + end + + # Dispatch enter and leave events for GlobalVariableOrWriteNode nodes. + def visit_global_variable_or_write_node(node) + listeners[:on_global_variable_or_write_node_enter]&.each { |listener| listener.on_global_variable_or_write_node_enter(node) } + listeners[:on_global_variable_or_write_node_leave]&.each { |listener| listener.on_global_variable_or_write_node_leave(node) } + end + + # Dispatch enter and leave events for GlobalVariableReadNode nodes. + def visit_global_variable_read_node(node) + listeners[:on_global_variable_read_node_enter]&.each { |listener| listener.on_global_variable_read_node_enter(node) } + listeners[:on_global_variable_read_node_leave]&.each { |listener| listener.on_global_variable_read_node_leave(node) } + end + + # Dispatch enter and leave events for GlobalVariableTargetNode nodes. + def visit_global_variable_target_node(node) + listeners[:on_global_variable_target_node_enter]&.each { |listener| listener.on_global_variable_target_node_enter(node) } + listeners[:on_global_variable_target_node_leave]&.each { |listener| listener.on_global_variable_target_node_leave(node) } + end + + # Dispatch enter and leave events for GlobalVariableWriteNode nodes. + def visit_global_variable_write_node(node) + listeners[:on_global_variable_write_node_enter]&.each { |listener| listener.on_global_variable_write_node_enter(node) } + listeners[:on_global_variable_write_node_leave]&.each { |listener| listener.on_global_variable_write_node_leave(node) } + end + + # Dispatch enter and leave events for HashNode nodes. + def visit_hash_node(node) + listeners[:on_hash_node_enter]&.each { |listener| listener.on_hash_node_enter(node) } + listeners[:on_hash_node_leave]&.each { |listener| listener.on_hash_node_leave(node) } + end + + # Dispatch enter and leave events for HashPatternNode nodes. + def visit_hash_pattern_node(node) + listeners[:on_hash_pattern_node_enter]&.each { |listener| listener.on_hash_pattern_node_enter(node) } + listeners[:on_hash_pattern_node_leave]&.each { |listener| listener.on_hash_pattern_node_leave(node) } + end + + # Dispatch enter and leave events for IfNode nodes. + def visit_if_node(node) + listeners[:on_if_node_enter]&.each { |listener| listener.on_if_node_enter(node) } + listeners[:on_if_node_leave]&.each { |listener| listener.on_if_node_leave(node) } + end + + # Dispatch enter and leave events for ImaginaryNode nodes. + def visit_imaginary_node(node) + listeners[:on_imaginary_node_enter]&.each { |listener| listener.on_imaginary_node_enter(node) } + listeners[:on_imaginary_node_leave]&.each { |listener| listener.on_imaginary_node_leave(node) } + end + + # Dispatch enter and leave events for ImplicitNode nodes. + def visit_implicit_node(node) + listeners[:on_implicit_node_enter]&.each { |listener| listener.on_implicit_node_enter(node) } + listeners[:on_implicit_node_leave]&.each { |listener| listener.on_implicit_node_leave(node) } + end + + # Dispatch enter and leave events for ImplicitRestNode nodes. + def visit_implicit_rest_node(node) + listeners[:on_implicit_rest_node_enter]&.each { |listener| listener.on_implicit_rest_node_enter(node) } + listeners[:on_implicit_rest_node_leave]&.each { |listener| listener.on_implicit_rest_node_leave(node) } + end + + # Dispatch enter and leave events for InNode nodes. + def visit_in_node(node) + listeners[:on_in_node_enter]&.each { |listener| listener.on_in_node_enter(node) } + listeners[:on_in_node_leave]&.each { |listener| listener.on_in_node_leave(node) } + end + + # Dispatch enter and leave events for IndexAndWriteNode nodes. + def visit_index_and_write_node(node) + listeners[:on_index_and_write_node_enter]&.each { |listener| listener.on_index_and_write_node_enter(node) } + listeners[:on_index_and_write_node_leave]&.each { |listener| listener.on_index_and_write_node_leave(node) } + end + + # Dispatch enter and leave events for IndexOperatorWriteNode nodes. + def visit_index_operator_write_node(node) + listeners[:on_index_operator_write_node_enter]&.each { |listener| listener.on_index_operator_write_node_enter(node) } + listeners[:on_index_operator_write_node_leave]&.each { |listener| listener.on_index_operator_write_node_leave(node) } + end + + # Dispatch enter and leave events for IndexOrWriteNode nodes. + def visit_index_or_write_node(node) + listeners[:on_index_or_write_node_enter]&.each { |listener| listener.on_index_or_write_node_enter(node) } + listeners[:on_index_or_write_node_leave]&.each { |listener| listener.on_index_or_write_node_leave(node) } + end + + # Dispatch enter and leave events for IndexTargetNode nodes. + def visit_index_target_node(node) + listeners[:on_index_target_node_enter]&.each { |listener| listener.on_index_target_node_enter(node) } + listeners[:on_index_target_node_leave]&.each { |listener| listener.on_index_target_node_leave(node) } + end + + # Dispatch enter and leave events for InstanceVariableAndWriteNode nodes. + def visit_instance_variable_and_write_node(node) + listeners[:on_instance_variable_and_write_node_enter]&.each { |listener| listener.on_instance_variable_and_write_node_enter(node) } + listeners[:on_instance_variable_and_write_node_leave]&.each { |listener| listener.on_instance_variable_and_write_node_leave(node) } + end + + # Dispatch enter and leave events for InstanceVariableOperatorWriteNode nodes. + def visit_instance_variable_operator_write_node(node) + listeners[:on_instance_variable_operator_write_node_enter]&.each { |listener| listener.on_instance_variable_operator_write_node_enter(node) } + listeners[:on_instance_variable_operator_write_node_leave]&.each { |listener| listener.on_instance_variable_operator_write_node_leave(node) } + end + + # Dispatch enter and leave events for InstanceVariableOrWriteNode nodes. + def visit_instance_variable_or_write_node(node) + listeners[:on_instance_variable_or_write_node_enter]&.each { |listener| listener.on_instance_variable_or_write_node_enter(node) } + listeners[:on_instance_variable_or_write_node_leave]&.each { |listener| listener.on_instance_variable_or_write_node_leave(node) } + end + + # Dispatch enter and leave events for InstanceVariableReadNode nodes. + def visit_instance_variable_read_node(node) + listeners[:on_instance_variable_read_node_enter]&.each { |listener| listener.on_instance_variable_read_node_enter(node) } + listeners[:on_instance_variable_read_node_leave]&.each { |listener| listener.on_instance_variable_read_node_leave(node) } + end + + # Dispatch enter and leave events for InstanceVariableTargetNode nodes. + def visit_instance_variable_target_node(node) + listeners[:on_instance_variable_target_node_enter]&.each { |listener| listener.on_instance_variable_target_node_enter(node) } + listeners[:on_instance_variable_target_node_leave]&.each { |listener| listener.on_instance_variable_target_node_leave(node) } + end + + # Dispatch enter and leave events for InstanceVariableWriteNode nodes. + def visit_instance_variable_write_node(node) + listeners[:on_instance_variable_write_node_enter]&.each { |listener| listener.on_instance_variable_write_node_enter(node) } + listeners[:on_instance_variable_write_node_leave]&.each { |listener| listener.on_instance_variable_write_node_leave(node) } + end + + # Dispatch enter and leave events for IntegerNode nodes. + def visit_integer_node(node) + listeners[:on_integer_node_enter]&.each { |listener| listener.on_integer_node_enter(node) } + listeners[:on_integer_node_leave]&.each { |listener| listener.on_integer_node_leave(node) } + end + + # Dispatch enter and leave events for InterpolatedMatchLastLineNode nodes. + def visit_interpolated_match_last_line_node(node) + listeners[:on_interpolated_match_last_line_node_enter]&.each { |listener| listener.on_interpolated_match_last_line_node_enter(node) } + listeners[:on_interpolated_match_last_line_node_leave]&.each { |listener| listener.on_interpolated_match_last_line_node_leave(node) } + end + + # Dispatch enter and leave events for InterpolatedRegularExpressionNode nodes. + def visit_interpolated_regular_expression_node(node) + listeners[:on_interpolated_regular_expression_node_enter]&.each { |listener| listener.on_interpolated_regular_expression_node_enter(node) } + listeners[:on_interpolated_regular_expression_node_leave]&.each { |listener| listener.on_interpolated_regular_expression_node_leave(node) } + end + + # Dispatch enter and leave events for InterpolatedStringNode nodes. + def visit_interpolated_string_node(node) + listeners[:on_interpolated_string_node_enter]&.each { |listener| listener.on_interpolated_string_node_enter(node) } + listeners[:on_interpolated_string_node_leave]&.each { |listener| listener.on_interpolated_string_node_leave(node) } + end + + # Dispatch enter and leave events for InterpolatedSymbolNode nodes. + def visit_interpolated_symbol_node(node) + listeners[:on_interpolated_symbol_node_enter]&.each { |listener| listener.on_interpolated_symbol_node_enter(node) } + listeners[:on_interpolated_symbol_node_leave]&.each { |listener| listener.on_interpolated_symbol_node_leave(node) } + end + + # Dispatch enter and leave events for InterpolatedXStringNode nodes. + def visit_interpolated_x_string_node(node) + listeners[:on_interpolated_x_string_node_enter]&.each { |listener| listener.on_interpolated_x_string_node_enter(node) } + listeners[:on_interpolated_x_string_node_leave]&.each { |listener| listener.on_interpolated_x_string_node_leave(node) } + end + + # Dispatch enter and leave events for ItLocalVariableReadNode nodes. + def visit_it_local_variable_read_node(node) + listeners[:on_it_local_variable_read_node_enter]&.each { |listener| listener.on_it_local_variable_read_node_enter(node) } + listeners[:on_it_local_variable_read_node_leave]&.each { |listener| listener.on_it_local_variable_read_node_leave(node) } + end + + # Dispatch enter and leave events for ItParametersNode nodes. + def visit_it_parameters_node(node) + listeners[:on_it_parameters_node_enter]&.each { |listener| listener.on_it_parameters_node_enter(node) } + listeners[:on_it_parameters_node_leave]&.each { |listener| listener.on_it_parameters_node_leave(node) } + end + + # Dispatch enter and leave events for KeywordHashNode nodes. + def visit_keyword_hash_node(node) + listeners[:on_keyword_hash_node_enter]&.each { |listener| listener.on_keyword_hash_node_enter(node) } + listeners[:on_keyword_hash_node_leave]&.each { |listener| listener.on_keyword_hash_node_leave(node) } + end + + # Dispatch enter and leave events for KeywordRestParameterNode nodes. + def visit_keyword_rest_parameter_node(node) + listeners[:on_keyword_rest_parameter_node_enter]&.each { |listener| listener.on_keyword_rest_parameter_node_enter(node) } + listeners[:on_keyword_rest_parameter_node_leave]&.each { |listener| listener.on_keyword_rest_parameter_node_leave(node) } + end + + # Dispatch enter and leave events for LambdaNode nodes. + def visit_lambda_node(node) + listeners[:on_lambda_node_enter]&.each { |listener| listener.on_lambda_node_enter(node) } + listeners[:on_lambda_node_leave]&.each { |listener| listener.on_lambda_node_leave(node) } + end + + # Dispatch enter and leave events for LocalVariableAndWriteNode nodes. + def visit_local_variable_and_write_node(node) + listeners[:on_local_variable_and_write_node_enter]&.each { |listener| listener.on_local_variable_and_write_node_enter(node) } + listeners[:on_local_variable_and_write_node_leave]&.each { |listener| listener.on_local_variable_and_write_node_leave(node) } + end + + # Dispatch enter and leave events for LocalVariableOperatorWriteNode nodes. + def visit_local_variable_operator_write_node(node) + listeners[:on_local_variable_operator_write_node_enter]&.each { |listener| listener.on_local_variable_operator_write_node_enter(node) } + listeners[:on_local_variable_operator_write_node_leave]&.each { |listener| listener.on_local_variable_operator_write_node_leave(node) } + end + + # Dispatch enter and leave events for LocalVariableOrWriteNode nodes. + def visit_local_variable_or_write_node(node) + listeners[:on_local_variable_or_write_node_enter]&.each { |listener| listener.on_local_variable_or_write_node_enter(node) } + listeners[:on_local_variable_or_write_node_leave]&.each { |listener| listener.on_local_variable_or_write_node_leave(node) } + end + + # Dispatch enter and leave events for LocalVariableReadNode nodes. + def visit_local_variable_read_node(node) + listeners[:on_local_variable_read_node_enter]&.each { |listener| listener.on_local_variable_read_node_enter(node) } + listeners[:on_local_variable_read_node_leave]&.each { |listener| listener.on_local_variable_read_node_leave(node) } + end + + # Dispatch enter and leave events for LocalVariableTargetNode nodes. + def visit_local_variable_target_node(node) + listeners[:on_local_variable_target_node_enter]&.each { |listener| listener.on_local_variable_target_node_enter(node) } + listeners[:on_local_variable_target_node_leave]&.each { |listener| listener.on_local_variable_target_node_leave(node) } + end + + # Dispatch enter and leave events for LocalVariableWriteNode nodes. + def visit_local_variable_write_node(node) + listeners[:on_local_variable_write_node_enter]&.each { |listener| listener.on_local_variable_write_node_enter(node) } + listeners[:on_local_variable_write_node_leave]&.each { |listener| listener.on_local_variable_write_node_leave(node) } + end + + # Dispatch enter and leave events for MatchLastLineNode nodes. + def visit_match_last_line_node(node) + listeners[:on_match_last_line_node_enter]&.each { |listener| listener.on_match_last_line_node_enter(node) } + listeners[:on_match_last_line_node_leave]&.each { |listener| listener.on_match_last_line_node_leave(node) } + end + + # Dispatch enter and leave events for MatchPredicateNode nodes. + def visit_match_predicate_node(node) + listeners[:on_match_predicate_node_enter]&.each { |listener| listener.on_match_predicate_node_enter(node) } + listeners[:on_match_predicate_node_leave]&.each { |listener| listener.on_match_predicate_node_leave(node) } + end + + # Dispatch enter and leave events for MatchRequiredNode nodes. + def visit_match_required_node(node) + listeners[:on_match_required_node_enter]&.each { |listener| listener.on_match_required_node_enter(node) } + listeners[:on_match_required_node_leave]&.each { |listener| listener.on_match_required_node_leave(node) } + end + + # Dispatch enter and leave events for MatchWriteNode nodes. + def visit_match_write_node(node) + listeners[:on_match_write_node_enter]&.each { |listener| listener.on_match_write_node_enter(node) } + listeners[:on_match_write_node_leave]&.each { |listener| listener.on_match_write_node_leave(node) } + end + + # Dispatch enter and leave events for MissingNode nodes. + def visit_missing_node(node) + listeners[:on_missing_node_enter]&.each { |listener| listener.on_missing_node_enter(node) } + listeners[:on_missing_node_leave]&.each { |listener| listener.on_missing_node_leave(node) } + end + + # Dispatch enter and leave events for ModuleNode nodes. + def visit_module_node(node) + listeners[:on_module_node_enter]&.each { |listener| listener.on_module_node_enter(node) } + listeners[:on_module_node_leave]&.each { |listener| listener.on_module_node_leave(node) } + end + + # Dispatch enter and leave events for MultiTargetNode nodes. + def visit_multi_target_node(node) + listeners[:on_multi_target_node_enter]&.each { |listener| listener.on_multi_target_node_enter(node) } + listeners[:on_multi_target_node_leave]&.each { |listener| listener.on_multi_target_node_leave(node) } + end + + # Dispatch enter and leave events for MultiWriteNode nodes. + def visit_multi_write_node(node) + listeners[:on_multi_write_node_enter]&.each { |listener| listener.on_multi_write_node_enter(node) } + listeners[:on_multi_write_node_leave]&.each { |listener| listener.on_multi_write_node_leave(node) } + end + + # Dispatch enter and leave events for NextNode nodes. + def visit_next_node(node) + listeners[:on_next_node_enter]&.each { |listener| listener.on_next_node_enter(node) } + listeners[:on_next_node_leave]&.each { |listener| listener.on_next_node_leave(node) } + end + + # Dispatch enter and leave events for NilNode nodes. + def visit_nil_node(node) + listeners[:on_nil_node_enter]&.each { |listener| listener.on_nil_node_enter(node) } + listeners[:on_nil_node_leave]&.each { |listener| listener.on_nil_node_leave(node) } + end + + # Dispatch enter and leave events for NoKeywordsParameterNode nodes. + def visit_no_keywords_parameter_node(node) + listeners[:on_no_keywords_parameter_node_enter]&.each { |listener| listener.on_no_keywords_parameter_node_enter(node) } + listeners[:on_no_keywords_parameter_node_leave]&.each { |listener| listener.on_no_keywords_parameter_node_leave(node) } + end + + # Dispatch enter and leave events for NumberedParametersNode nodes. + def visit_numbered_parameters_node(node) + listeners[:on_numbered_parameters_node_enter]&.each { |listener| listener.on_numbered_parameters_node_enter(node) } + listeners[:on_numbered_parameters_node_leave]&.each { |listener| listener.on_numbered_parameters_node_leave(node) } + end + + # Dispatch enter and leave events for NumberedReferenceReadNode nodes. + def visit_numbered_reference_read_node(node) + listeners[:on_numbered_reference_read_node_enter]&.each { |listener| listener.on_numbered_reference_read_node_enter(node) } + listeners[:on_numbered_reference_read_node_leave]&.each { |listener| listener.on_numbered_reference_read_node_leave(node) } + end + + # Dispatch enter and leave events for OptionalKeywordParameterNode nodes. + def visit_optional_keyword_parameter_node(node) + listeners[:on_optional_keyword_parameter_node_enter]&.each { |listener| listener.on_optional_keyword_parameter_node_enter(node) } + listeners[:on_optional_keyword_parameter_node_leave]&.each { |listener| listener.on_optional_keyword_parameter_node_leave(node) } + end + + # Dispatch enter and leave events for OptionalParameterNode nodes. + def visit_optional_parameter_node(node) + listeners[:on_optional_parameter_node_enter]&.each { |listener| listener.on_optional_parameter_node_enter(node) } + listeners[:on_optional_parameter_node_leave]&.each { |listener| listener.on_optional_parameter_node_leave(node) } + end + + # Dispatch enter and leave events for OrNode nodes. + def visit_or_node(node) + listeners[:on_or_node_enter]&.each { |listener| listener.on_or_node_enter(node) } + listeners[:on_or_node_leave]&.each { |listener| listener.on_or_node_leave(node) } + end + + # Dispatch enter and leave events for ParametersNode nodes. + def visit_parameters_node(node) + listeners[:on_parameters_node_enter]&.each { |listener| listener.on_parameters_node_enter(node) } + listeners[:on_parameters_node_leave]&.each { |listener| listener.on_parameters_node_leave(node) } + end + + # Dispatch enter and leave events for ParenthesesNode nodes. + def visit_parentheses_node(node) + listeners[:on_parentheses_node_enter]&.each { |listener| listener.on_parentheses_node_enter(node) } + listeners[:on_parentheses_node_leave]&.each { |listener| listener.on_parentheses_node_leave(node) } + end + + # Dispatch enter and leave events for PinnedExpressionNode nodes. + def visit_pinned_expression_node(node) + listeners[:on_pinned_expression_node_enter]&.each { |listener| listener.on_pinned_expression_node_enter(node) } + listeners[:on_pinned_expression_node_leave]&.each { |listener| listener.on_pinned_expression_node_leave(node) } + end + + # Dispatch enter and leave events for PinnedVariableNode nodes. + def visit_pinned_variable_node(node) + listeners[:on_pinned_variable_node_enter]&.each { |listener| listener.on_pinned_variable_node_enter(node) } + listeners[:on_pinned_variable_node_leave]&.each { |listener| listener.on_pinned_variable_node_leave(node) } + end + + # Dispatch enter and leave events for PostExecutionNode nodes. + def visit_post_execution_node(node) + listeners[:on_post_execution_node_enter]&.each { |listener| listener.on_post_execution_node_enter(node) } + listeners[:on_post_execution_node_leave]&.each { |listener| listener.on_post_execution_node_leave(node) } + end + + # Dispatch enter and leave events for PreExecutionNode nodes. + def visit_pre_execution_node(node) + listeners[:on_pre_execution_node_enter]&.each { |listener| listener.on_pre_execution_node_enter(node) } + listeners[:on_pre_execution_node_leave]&.each { |listener| listener.on_pre_execution_node_leave(node) } + end + + # Dispatch enter and leave events for ProgramNode nodes. + def visit_program_node(node) + listeners[:on_program_node_enter]&.each { |listener| listener.on_program_node_enter(node) } + listeners[:on_program_node_leave]&.each { |listener| listener.on_program_node_leave(node) } + end + + # Dispatch enter and leave events for RangeNode nodes. + def visit_range_node(node) + listeners[:on_range_node_enter]&.each { |listener| listener.on_range_node_enter(node) } + listeners[:on_range_node_leave]&.each { |listener| listener.on_range_node_leave(node) } + end + + # Dispatch enter and leave events for RationalNode nodes. + def visit_rational_node(node) + listeners[:on_rational_node_enter]&.each { |listener| listener.on_rational_node_enter(node) } + listeners[:on_rational_node_leave]&.each { |listener| listener.on_rational_node_leave(node) } + end + + # Dispatch enter and leave events for RedoNode nodes. + def visit_redo_node(node) + listeners[:on_redo_node_enter]&.each { |listener| listener.on_redo_node_enter(node) } + listeners[:on_redo_node_leave]&.each { |listener| listener.on_redo_node_leave(node) } + end + + # Dispatch enter and leave events for RegularExpressionNode nodes. + def visit_regular_expression_node(node) + listeners[:on_regular_expression_node_enter]&.each { |listener| listener.on_regular_expression_node_enter(node) } + listeners[:on_regular_expression_node_leave]&.each { |listener| listener.on_regular_expression_node_leave(node) } + end + + # Dispatch enter and leave events for RequiredKeywordParameterNode nodes. + def visit_required_keyword_parameter_node(node) + listeners[:on_required_keyword_parameter_node_enter]&.each { |listener| listener.on_required_keyword_parameter_node_enter(node) } + listeners[:on_required_keyword_parameter_node_leave]&.each { |listener| listener.on_required_keyword_parameter_node_leave(node) } + end + + # Dispatch enter and leave events for RequiredParameterNode nodes. + def visit_required_parameter_node(node) + listeners[:on_required_parameter_node_enter]&.each { |listener| listener.on_required_parameter_node_enter(node) } + listeners[:on_required_parameter_node_leave]&.each { |listener| listener.on_required_parameter_node_leave(node) } + end + + # Dispatch enter and leave events for RescueModifierNode nodes. + def visit_rescue_modifier_node(node) + listeners[:on_rescue_modifier_node_enter]&.each { |listener| listener.on_rescue_modifier_node_enter(node) } + listeners[:on_rescue_modifier_node_leave]&.each { |listener| listener.on_rescue_modifier_node_leave(node) } + end + + # Dispatch enter and leave events for RescueNode nodes. + def visit_rescue_node(node) + listeners[:on_rescue_node_enter]&.each { |listener| listener.on_rescue_node_enter(node) } + listeners[:on_rescue_node_leave]&.each { |listener| listener.on_rescue_node_leave(node) } + end + + # Dispatch enter and leave events for RestParameterNode nodes. + def visit_rest_parameter_node(node) + listeners[:on_rest_parameter_node_enter]&.each { |listener| listener.on_rest_parameter_node_enter(node) } + listeners[:on_rest_parameter_node_leave]&.each { |listener| listener.on_rest_parameter_node_leave(node) } + end + + # Dispatch enter and leave events for RetryNode nodes. + def visit_retry_node(node) + listeners[:on_retry_node_enter]&.each { |listener| listener.on_retry_node_enter(node) } + listeners[:on_retry_node_leave]&.each { |listener| listener.on_retry_node_leave(node) } + end + + # Dispatch enter and leave events for ReturnNode nodes. + def visit_return_node(node) + listeners[:on_return_node_enter]&.each { |listener| listener.on_return_node_enter(node) } + listeners[:on_return_node_leave]&.each { |listener| listener.on_return_node_leave(node) } + end + + # Dispatch enter and leave events for SelfNode nodes. + def visit_self_node(node) + listeners[:on_self_node_enter]&.each { |listener| listener.on_self_node_enter(node) } + listeners[:on_self_node_leave]&.each { |listener| listener.on_self_node_leave(node) } + end + + # Dispatch enter and leave events for ShareableConstantNode nodes. + def visit_shareable_constant_node(node) + listeners[:on_shareable_constant_node_enter]&.each { |listener| listener.on_shareable_constant_node_enter(node) } + listeners[:on_shareable_constant_node_leave]&.each { |listener| listener.on_shareable_constant_node_leave(node) } + end + + # Dispatch enter and leave events for SingletonClassNode nodes. + def visit_singleton_class_node(node) + listeners[:on_singleton_class_node_enter]&.each { |listener| listener.on_singleton_class_node_enter(node) } + listeners[:on_singleton_class_node_leave]&.each { |listener| listener.on_singleton_class_node_leave(node) } + end + + # Dispatch enter and leave events for SourceEncodingNode nodes. + def visit_source_encoding_node(node) + listeners[:on_source_encoding_node_enter]&.each { |listener| listener.on_source_encoding_node_enter(node) } + listeners[:on_source_encoding_node_leave]&.each { |listener| listener.on_source_encoding_node_leave(node) } + end + + # Dispatch enter and leave events for SourceFileNode nodes. + def visit_source_file_node(node) + listeners[:on_source_file_node_enter]&.each { |listener| listener.on_source_file_node_enter(node) } + listeners[:on_source_file_node_leave]&.each { |listener| listener.on_source_file_node_leave(node) } + end + + # Dispatch enter and leave events for SourceLineNode nodes. + def visit_source_line_node(node) + listeners[:on_source_line_node_enter]&.each { |listener| listener.on_source_line_node_enter(node) } + listeners[:on_source_line_node_leave]&.each { |listener| listener.on_source_line_node_leave(node) } + end + + # Dispatch enter and leave events for SplatNode nodes. + def visit_splat_node(node) + listeners[:on_splat_node_enter]&.each { |listener| listener.on_splat_node_enter(node) } + listeners[:on_splat_node_leave]&.each { |listener| listener.on_splat_node_leave(node) } + end + + # Dispatch enter and leave events for StatementsNode nodes. + def visit_statements_node(node) + listeners[:on_statements_node_enter]&.each { |listener| listener.on_statements_node_enter(node) } + listeners[:on_statements_node_leave]&.each { |listener| listener.on_statements_node_leave(node) } + end + + # Dispatch enter and leave events for StringNode nodes. + def visit_string_node(node) + listeners[:on_string_node_enter]&.each { |listener| listener.on_string_node_enter(node) } + listeners[:on_string_node_leave]&.each { |listener| listener.on_string_node_leave(node) } + end + + # Dispatch enter and leave events for SuperNode nodes. + def visit_super_node(node) + listeners[:on_super_node_enter]&.each { |listener| listener.on_super_node_enter(node) } + listeners[:on_super_node_leave]&.each { |listener| listener.on_super_node_leave(node) } + end + + # Dispatch enter and leave events for SymbolNode nodes. + def visit_symbol_node(node) + listeners[:on_symbol_node_enter]&.each { |listener| listener.on_symbol_node_enter(node) } + listeners[:on_symbol_node_leave]&.each { |listener| listener.on_symbol_node_leave(node) } + end + + # Dispatch enter and leave events for TrueNode nodes. + def visit_true_node(node) + listeners[:on_true_node_enter]&.each { |listener| listener.on_true_node_enter(node) } + listeners[:on_true_node_leave]&.each { |listener| listener.on_true_node_leave(node) } + end + + # Dispatch enter and leave events for UndefNode nodes. + def visit_undef_node(node) + listeners[:on_undef_node_enter]&.each { |listener| listener.on_undef_node_enter(node) } + listeners[:on_undef_node_leave]&.each { |listener| listener.on_undef_node_leave(node) } + end + + # Dispatch enter and leave events for UnlessNode nodes. + def visit_unless_node(node) + listeners[:on_unless_node_enter]&.each { |listener| listener.on_unless_node_enter(node) } + listeners[:on_unless_node_leave]&.each { |listener| listener.on_unless_node_leave(node) } + end + + # Dispatch enter and leave events for UntilNode nodes. + def visit_until_node(node) + listeners[:on_until_node_enter]&.each { |listener| listener.on_until_node_enter(node) } + listeners[:on_until_node_leave]&.each { |listener| listener.on_until_node_leave(node) } + end + + # Dispatch enter and leave events for WhenNode nodes. + def visit_when_node(node) + listeners[:on_when_node_enter]&.each { |listener| listener.on_when_node_enter(node) } + listeners[:on_when_node_leave]&.each { |listener| listener.on_when_node_leave(node) } + end + + # Dispatch enter and leave events for WhileNode nodes. + def visit_while_node(node) + listeners[:on_while_node_enter]&.each { |listener| listener.on_while_node_enter(node) } + listeners[:on_while_node_leave]&.each { |listener| listener.on_while_node_leave(node) } + end + + # Dispatch enter and leave events for XStringNode nodes. + def visit_x_string_node(node) + listeners[:on_x_string_node_enter]&.each { |listener| listener.on_x_string_node_enter(node) } + listeners[:on_x_string_node_leave]&.each { |listener| listener.on_x_string_node_leave(node) } + end + + # Dispatch enter and leave events for YieldNode nodes. + def visit_yield_node(node) + listeners[:on_yield_node_enter]&.each { |listener| listener.on_yield_node_enter(node) } + listeners[:on_yield_node_leave]&.each { |listener| listener.on_yield_node_leave(node) } + end + end + + private_constant :DispatchOnce + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/dot_visitor.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/dot_visitor.rb new file mode 100644 index 00000000..e289794e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/dot_visitor.rb @@ -0,0 +1,4758 @@ +# frozen_string_literal: true + +=begin +This file is generated by the templates/template.rb script and should not be +modified manually. See templates/lib/prism/dot_visitor.rb.erb +if you are looking to modify the template +=end + +require "cgi" + +module Prism + # This visitor provides the ability to call Node#to_dot, which converts a + # subtree into a graphviz dot graph. + class DotVisitor < Visitor + class Field # :nodoc: + attr_reader :name, :value, :port + + def initialize(name, value, port) + @name = name + @value = value + @port = port + end + + def to_dot + if port + "#{name}" + else + "#{name}#{CGI.escapeHTML(value || raise)}" + end + end + end + + class Table # :nodoc: + attr_reader :name, :fields + + def initialize(name) + @name = name + @fields = [] + end + + def field(name, value = nil, port: false) + fields << Field.new(name, value, port) + end + + def to_dot + dot = <<~DOT + + + DOT + + if fields.any? + "#{dot} #{fields.map(&:to_dot).join("\n ")}\n
#{name}
" + else + "#{dot}" + end + end + end + + class Digraph # :nodoc: + attr_reader :nodes, :waypoints, :edges + + def initialize + @nodes = [] + @waypoints = [] + @edges = [] + end + + def node(value) + nodes << value + end + + def waypoint(value) + waypoints << value + end + + def edge(value) + edges << value + end + + def to_dot + <<~DOT + digraph "Prism" { + node [ + fontname=\"Courier New\" + shape=plain + style=filled + fillcolor=gray95 + ]; + + #{nodes.map { |node| node.gsub(/\n/, "\n ") }.join("\n ")} + node [shape=point]; + #{waypoints.join("\n ")} + + #{edges.join("\n ")} + } + DOT + end + end + + private_constant :Field, :Table, :Digraph + + # The digraph that is being built. + attr_reader :digraph + + # Initialize a new dot visitor. + def initialize + @digraph = Digraph.new + end + + # Convert this visitor into a graphviz dot graph string. + def to_dot + digraph.to_dot + end + + # Visit a AliasGlobalVariableNode node. + def visit_alias_global_variable_node(node) + table = Table.new("AliasGlobalVariableNode") + id = node_id(node) + + # new_name + table.field("new_name", port: true) + digraph.edge("#{id}:new_name -> #{node_id(node.new_name)};") + + # old_name + table.field("old_name", port: true) + digraph.edge("#{id}:old_name -> #{node_id(node.old_name)};") + + # keyword_loc + table.field("keyword_loc", location_inspect(node.keyword_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a AliasMethodNode node. + def visit_alias_method_node(node) + table = Table.new("AliasMethodNode") + id = node_id(node) + + # new_name + table.field("new_name", port: true) + digraph.edge("#{id}:new_name -> #{node_id(node.new_name)};") + + # old_name + table.field("old_name", port: true) + digraph.edge("#{id}:old_name -> #{node_id(node.old_name)};") + + # keyword_loc + table.field("keyword_loc", location_inspect(node.keyword_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a AlternationPatternNode node. + def visit_alternation_pattern_node(node) + table = Table.new("AlternationPatternNode") + id = node_id(node) + + # left + table.field("left", port: true) + digraph.edge("#{id}:left -> #{node_id(node.left)};") + + # right + table.field("right", port: true) + digraph.edge("#{id}:right -> #{node_id(node.right)};") + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a AndNode node. + def visit_and_node(node) + table = Table.new("AndNode") + id = node_id(node) + + # left + table.field("left", port: true) + digraph.edge("#{id}:left -> #{node_id(node.left)};") + + # right + table.field("right", port: true) + digraph.edge("#{id}:right -> #{node_id(node.right)};") + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ArgumentsNode node. + def visit_arguments_node(node) + table = Table.new("ArgumentsNode") + id = node_id(node) + + # flags + table.field("flags", arguments_node_flags_inspect(node)) + + # arguments + if node.arguments.any? + table.field("arguments", port: true) + + waypoint = "#{id}_arguments" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:arguments -> #{waypoint};") + node.arguments.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("arguments", "[]") + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ArrayNode node. + def visit_array_node(node) + table = Table.new("ArrayNode") + id = node_id(node) + + # flags + table.field("flags", array_node_flags_inspect(node)) + + # elements + if node.elements.any? + table.field("elements", port: true) + + waypoint = "#{id}_elements" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:elements -> #{waypoint};") + node.elements.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("elements", "[]") + end + + # opening_loc + unless (opening_loc = node.opening_loc).nil? + table.field("opening_loc", location_inspect(opening_loc)) + end + + # closing_loc + unless (closing_loc = node.closing_loc).nil? + table.field("closing_loc", location_inspect(closing_loc)) + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ArrayPatternNode node. + def visit_array_pattern_node(node) + table = Table.new("ArrayPatternNode") + id = node_id(node) + + # constant + unless (constant = node.constant).nil? + table.field("constant", port: true) + digraph.edge("#{id}:constant -> #{node_id(constant)};") + end + + # requireds + if node.requireds.any? + table.field("requireds", port: true) + + waypoint = "#{id}_requireds" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:requireds -> #{waypoint};") + node.requireds.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("requireds", "[]") + end + + # rest + unless (rest = node.rest).nil? + table.field("rest", port: true) + digraph.edge("#{id}:rest -> #{node_id(rest)};") + end + + # posts + if node.posts.any? + table.field("posts", port: true) + + waypoint = "#{id}_posts" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:posts -> #{waypoint};") + node.posts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("posts", "[]") + end + + # opening_loc + unless (opening_loc = node.opening_loc).nil? + table.field("opening_loc", location_inspect(opening_loc)) + end + + # closing_loc + unless (closing_loc = node.closing_loc).nil? + table.field("closing_loc", location_inspect(closing_loc)) + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a AssocNode node. + def visit_assoc_node(node) + table = Table.new("AssocNode") + id = node_id(node) + + # key + table.field("key", port: true) + digraph.edge("#{id}:key -> #{node_id(node.key)};") + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + # operator_loc + unless (operator_loc = node.operator_loc).nil? + table.field("operator_loc", location_inspect(operator_loc)) + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a AssocSplatNode node. + def visit_assoc_splat_node(node) + table = Table.new("AssocSplatNode") + id = node_id(node) + + # value + unless (value = node.value).nil? + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(value)};") + end + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a BackReferenceReadNode node. + def visit_back_reference_read_node(node) + table = Table.new("BackReferenceReadNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a BeginNode node. + def visit_begin_node(node) + table = Table.new("BeginNode") + id = node_id(node) + + # begin_keyword_loc + unless (begin_keyword_loc = node.begin_keyword_loc).nil? + table.field("begin_keyword_loc", location_inspect(begin_keyword_loc)) + end + + # statements + unless (statements = node.statements).nil? + table.field("statements", port: true) + digraph.edge("#{id}:statements -> #{node_id(statements)};") + end + + # rescue_clause + unless (rescue_clause = node.rescue_clause).nil? + table.field("rescue_clause", port: true) + digraph.edge("#{id}:rescue_clause -> #{node_id(rescue_clause)};") + end + + # else_clause + unless (else_clause = node.else_clause).nil? + table.field("else_clause", port: true) + digraph.edge("#{id}:else_clause -> #{node_id(else_clause)};") + end + + # ensure_clause + unless (ensure_clause = node.ensure_clause).nil? + table.field("ensure_clause", port: true) + digraph.edge("#{id}:ensure_clause -> #{node_id(ensure_clause)};") + end + + # end_keyword_loc + unless (end_keyword_loc = node.end_keyword_loc).nil? + table.field("end_keyword_loc", location_inspect(end_keyword_loc)) + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a BlockArgumentNode node. + def visit_block_argument_node(node) + table = Table.new("BlockArgumentNode") + id = node_id(node) + + # expression + unless (expression = node.expression).nil? + table.field("expression", port: true) + digraph.edge("#{id}:expression -> #{node_id(expression)};") + end + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a BlockLocalVariableNode node. + def visit_block_local_variable_node(node) + table = Table.new("BlockLocalVariableNode") + id = node_id(node) + + # flags + table.field("flags", parameter_flags_inspect(node)) + + # name + table.field("name", node.name.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a BlockNode node. + def visit_block_node(node) + table = Table.new("BlockNode") + id = node_id(node) + + # locals + table.field("locals", node.locals.inspect) + + # parameters + unless (parameters = node.parameters).nil? + table.field("parameters", port: true) + digraph.edge("#{id}:parameters -> #{node_id(parameters)};") + end + + # body + unless (body = node.body).nil? + table.field("body", port: true) + digraph.edge("#{id}:body -> #{node_id(body)};") + end + + # opening_loc + table.field("opening_loc", location_inspect(node.opening_loc)) + + # closing_loc + table.field("closing_loc", location_inspect(node.closing_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a BlockParameterNode node. + def visit_block_parameter_node(node) + table = Table.new("BlockParameterNode") + id = node_id(node) + + # flags + table.field("flags", parameter_flags_inspect(node)) + + # name + table.field("name", node.name.inspect) + + # name_loc + unless (name_loc = node.name_loc).nil? + table.field("name_loc", location_inspect(name_loc)) + end + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a BlockParametersNode node. + def visit_block_parameters_node(node) + table = Table.new("BlockParametersNode") + id = node_id(node) + + # parameters + unless (parameters = node.parameters).nil? + table.field("parameters", port: true) + digraph.edge("#{id}:parameters -> #{node_id(parameters)};") + end + + # locals + if node.locals.any? + table.field("locals", port: true) + + waypoint = "#{id}_locals" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:locals -> #{waypoint};") + node.locals.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("locals", "[]") + end + + # opening_loc + unless (opening_loc = node.opening_loc).nil? + table.field("opening_loc", location_inspect(opening_loc)) + end + + # closing_loc + unless (closing_loc = node.closing_loc).nil? + table.field("closing_loc", location_inspect(closing_loc)) + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a BreakNode node. + def visit_break_node(node) + table = Table.new("BreakNode") + id = node_id(node) + + # arguments + unless (arguments = node.arguments).nil? + table.field("arguments", port: true) + digraph.edge("#{id}:arguments -> #{node_id(arguments)};") + end + + # keyword_loc + table.field("keyword_loc", location_inspect(node.keyword_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a CallAndWriteNode node. + def visit_call_and_write_node(node) + table = Table.new("CallAndWriteNode") + id = node_id(node) + + # flags + table.field("flags", call_node_flags_inspect(node)) + + # receiver + unless (receiver = node.receiver).nil? + table.field("receiver", port: true) + digraph.edge("#{id}:receiver -> #{node_id(receiver)};") + end + + # call_operator_loc + unless (call_operator_loc = node.call_operator_loc).nil? + table.field("call_operator_loc", location_inspect(call_operator_loc)) + end + + # message_loc + unless (message_loc = node.message_loc).nil? + table.field("message_loc", location_inspect(message_loc)) + end + + # read_name + table.field("read_name", node.read_name.inspect) + + # write_name + table.field("write_name", node.write_name.inspect) + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a CallNode node. + def visit_call_node(node) + table = Table.new("CallNode") + id = node_id(node) + + # flags + table.field("flags", call_node_flags_inspect(node)) + + # receiver + unless (receiver = node.receiver).nil? + table.field("receiver", port: true) + digraph.edge("#{id}:receiver -> #{node_id(receiver)};") + end + + # call_operator_loc + unless (call_operator_loc = node.call_operator_loc).nil? + table.field("call_operator_loc", location_inspect(call_operator_loc)) + end + + # name + table.field("name", node.name.inspect) + + # message_loc + unless (message_loc = node.message_loc).nil? + table.field("message_loc", location_inspect(message_loc)) + end + + # opening_loc + unless (opening_loc = node.opening_loc).nil? + table.field("opening_loc", location_inspect(opening_loc)) + end + + # arguments + unless (arguments = node.arguments).nil? + table.field("arguments", port: true) + digraph.edge("#{id}:arguments -> #{node_id(arguments)};") + end + + # closing_loc + unless (closing_loc = node.closing_loc).nil? + table.field("closing_loc", location_inspect(closing_loc)) + end + + # block + unless (block = node.block).nil? + table.field("block", port: true) + digraph.edge("#{id}:block -> #{node_id(block)};") + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a CallOperatorWriteNode node. + def visit_call_operator_write_node(node) + table = Table.new("CallOperatorWriteNode") + id = node_id(node) + + # flags + table.field("flags", call_node_flags_inspect(node)) + + # receiver + unless (receiver = node.receiver).nil? + table.field("receiver", port: true) + digraph.edge("#{id}:receiver -> #{node_id(receiver)};") + end + + # call_operator_loc + unless (call_operator_loc = node.call_operator_loc).nil? + table.field("call_operator_loc", location_inspect(call_operator_loc)) + end + + # message_loc + unless (message_loc = node.message_loc).nil? + table.field("message_loc", location_inspect(message_loc)) + end + + # read_name + table.field("read_name", node.read_name.inspect) + + # write_name + table.field("write_name", node.write_name.inspect) + + # binary_operator + table.field("binary_operator", node.binary_operator.inspect) + + # binary_operator_loc + table.field("binary_operator_loc", location_inspect(node.binary_operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a CallOrWriteNode node. + def visit_call_or_write_node(node) + table = Table.new("CallOrWriteNode") + id = node_id(node) + + # flags + table.field("flags", call_node_flags_inspect(node)) + + # receiver + unless (receiver = node.receiver).nil? + table.field("receiver", port: true) + digraph.edge("#{id}:receiver -> #{node_id(receiver)};") + end + + # call_operator_loc + unless (call_operator_loc = node.call_operator_loc).nil? + table.field("call_operator_loc", location_inspect(call_operator_loc)) + end + + # message_loc + unless (message_loc = node.message_loc).nil? + table.field("message_loc", location_inspect(message_loc)) + end + + # read_name + table.field("read_name", node.read_name.inspect) + + # write_name + table.field("write_name", node.write_name.inspect) + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a CallTargetNode node. + def visit_call_target_node(node) + table = Table.new("CallTargetNode") + id = node_id(node) + + # flags + table.field("flags", call_node_flags_inspect(node)) + + # receiver + table.field("receiver", port: true) + digraph.edge("#{id}:receiver -> #{node_id(node.receiver)};") + + # call_operator_loc + table.field("call_operator_loc", location_inspect(node.call_operator_loc)) + + # name + table.field("name", node.name.inspect) + + # message_loc + table.field("message_loc", location_inspect(node.message_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a CapturePatternNode node. + def visit_capture_pattern_node(node) + table = Table.new("CapturePatternNode") + id = node_id(node) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + # target + table.field("target", port: true) + digraph.edge("#{id}:target -> #{node_id(node.target)};") + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a CaseMatchNode node. + def visit_case_match_node(node) + table = Table.new("CaseMatchNode") + id = node_id(node) + + # predicate + unless (predicate = node.predicate).nil? + table.field("predicate", port: true) + digraph.edge("#{id}:predicate -> #{node_id(predicate)};") + end + + # conditions + if node.conditions.any? + table.field("conditions", port: true) + + waypoint = "#{id}_conditions" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:conditions -> #{waypoint};") + node.conditions.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("conditions", "[]") + end + + # else_clause + unless (else_clause = node.else_clause).nil? + table.field("else_clause", port: true) + digraph.edge("#{id}:else_clause -> #{node_id(else_clause)};") + end + + # case_keyword_loc + table.field("case_keyword_loc", location_inspect(node.case_keyword_loc)) + + # end_keyword_loc + table.field("end_keyword_loc", location_inspect(node.end_keyword_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a CaseNode node. + def visit_case_node(node) + table = Table.new("CaseNode") + id = node_id(node) + + # predicate + unless (predicate = node.predicate).nil? + table.field("predicate", port: true) + digraph.edge("#{id}:predicate -> #{node_id(predicate)};") + end + + # conditions + if node.conditions.any? + table.field("conditions", port: true) + + waypoint = "#{id}_conditions" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:conditions -> #{waypoint};") + node.conditions.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("conditions", "[]") + end + + # else_clause + unless (else_clause = node.else_clause).nil? + table.field("else_clause", port: true) + digraph.edge("#{id}:else_clause -> #{node_id(else_clause)};") + end + + # case_keyword_loc + table.field("case_keyword_loc", location_inspect(node.case_keyword_loc)) + + # end_keyword_loc + table.field("end_keyword_loc", location_inspect(node.end_keyword_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ClassNode node. + def visit_class_node(node) + table = Table.new("ClassNode") + id = node_id(node) + + # locals + table.field("locals", node.locals.inspect) + + # class_keyword_loc + table.field("class_keyword_loc", location_inspect(node.class_keyword_loc)) + + # constant_path + table.field("constant_path", port: true) + digraph.edge("#{id}:constant_path -> #{node_id(node.constant_path)};") + + # inheritance_operator_loc + unless (inheritance_operator_loc = node.inheritance_operator_loc).nil? + table.field("inheritance_operator_loc", location_inspect(inheritance_operator_loc)) + end + + # superclass + unless (superclass = node.superclass).nil? + table.field("superclass", port: true) + digraph.edge("#{id}:superclass -> #{node_id(superclass)};") + end + + # body + unless (body = node.body).nil? + table.field("body", port: true) + digraph.edge("#{id}:body -> #{node_id(body)};") + end + + # end_keyword_loc + table.field("end_keyword_loc", location_inspect(node.end_keyword_loc)) + + # name + table.field("name", node.name.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ClassVariableAndWriteNode node. + def visit_class_variable_and_write_node(node) + table = Table.new("ClassVariableAndWriteNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ClassVariableOperatorWriteNode node. + def visit_class_variable_operator_write_node(node) + table = Table.new("ClassVariableOperatorWriteNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + # binary_operator_loc + table.field("binary_operator_loc", location_inspect(node.binary_operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + # binary_operator + table.field("binary_operator", node.binary_operator.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ClassVariableOrWriteNode node. + def visit_class_variable_or_write_node(node) + table = Table.new("ClassVariableOrWriteNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ClassVariableReadNode node. + def visit_class_variable_read_node(node) + table = Table.new("ClassVariableReadNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ClassVariableTargetNode node. + def visit_class_variable_target_node(node) + table = Table.new("ClassVariableTargetNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ClassVariableWriteNode node. + def visit_class_variable_write_node(node) + table = Table.new("ClassVariableWriteNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ConstantAndWriteNode node. + def visit_constant_and_write_node(node) + table = Table.new("ConstantAndWriteNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ConstantOperatorWriteNode node. + def visit_constant_operator_write_node(node) + table = Table.new("ConstantOperatorWriteNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + # binary_operator_loc + table.field("binary_operator_loc", location_inspect(node.binary_operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + # binary_operator + table.field("binary_operator", node.binary_operator.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ConstantOrWriteNode node. + def visit_constant_or_write_node(node) + table = Table.new("ConstantOrWriteNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ConstantPathAndWriteNode node. + def visit_constant_path_and_write_node(node) + table = Table.new("ConstantPathAndWriteNode") + id = node_id(node) + + # target + table.field("target", port: true) + digraph.edge("#{id}:target -> #{node_id(node.target)};") + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ConstantPathNode node. + def visit_constant_path_node(node) + table = Table.new("ConstantPathNode") + id = node_id(node) + + # parent + unless (parent = node.parent).nil? + table.field("parent", port: true) + digraph.edge("#{id}:parent -> #{node_id(parent)};") + end + + # name + table.field("name", node.name.inspect) + + # delimiter_loc + table.field("delimiter_loc", location_inspect(node.delimiter_loc)) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ConstantPathOperatorWriteNode node. + def visit_constant_path_operator_write_node(node) + table = Table.new("ConstantPathOperatorWriteNode") + id = node_id(node) + + # target + table.field("target", port: true) + digraph.edge("#{id}:target -> #{node_id(node.target)};") + + # binary_operator_loc + table.field("binary_operator_loc", location_inspect(node.binary_operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + # binary_operator + table.field("binary_operator", node.binary_operator.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ConstantPathOrWriteNode node. + def visit_constant_path_or_write_node(node) + table = Table.new("ConstantPathOrWriteNode") + id = node_id(node) + + # target + table.field("target", port: true) + digraph.edge("#{id}:target -> #{node_id(node.target)};") + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ConstantPathTargetNode node. + def visit_constant_path_target_node(node) + table = Table.new("ConstantPathTargetNode") + id = node_id(node) + + # parent + unless (parent = node.parent).nil? + table.field("parent", port: true) + digraph.edge("#{id}:parent -> #{node_id(parent)};") + end + + # name + table.field("name", node.name.inspect) + + # delimiter_loc + table.field("delimiter_loc", location_inspect(node.delimiter_loc)) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ConstantPathWriteNode node. + def visit_constant_path_write_node(node) + table = Table.new("ConstantPathWriteNode") + id = node_id(node) + + # target + table.field("target", port: true) + digraph.edge("#{id}:target -> #{node_id(node.target)};") + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ConstantReadNode node. + def visit_constant_read_node(node) + table = Table.new("ConstantReadNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ConstantTargetNode node. + def visit_constant_target_node(node) + table = Table.new("ConstantTargetNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ConstantWriteNode node. + def visit_constant_write_node(node) + table = Table.new("ConstantWriteNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a DefNode node. + def visit_def_node(node) + table = Table.new("DefNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + # receiver + unless (receiver = node.receiver).nil? + table.field("receiver", port: true) + digraph.edge("#{id}:receiver -> #{node_id(receiver)};") + end + + # parameters + unless (parameters = node.parameters).nil? + table.field("parameters", port: true) + digraph.edge("#{id}:parameters -> #{node_id(parameters)};") + end + + # body + unless (body = node.body).nil? + table.field("body", port: true) + digraph.edge("#{id}:body -> #{node_id(body)};") + end + + # locals + table.field("locals", node.locals.inspect) + + # def_keyword_loc + table.field("def_keyword_loc", location_inspect(node.def_keyword_loc)) + + # operator_loc + unless (operator_loc = node.operator_loc).nil? + table.field("operator_loc", location_inspect(operator_loc)) + end + + # lparen_loc + unless (lparen_loc = node.lparen_loc).nil? + table.field("lparen_loc", location_inspect(lparen_loc)) + end + + # rparen_loc + unless (rparen_loc = node.rparen_loc).nil? + table.field("rparen_loc", location_inspect(rparen_loc)) + end + + # equal_loc + unless (equal_loc = node.equal_loc).nil? + table.field("equal_loc", location_inspect(equal_loc)) + end + + # end_keyword_loc + unless (end_keyword_loc = node.end_keyword_loc).nil? + table.field("end_keyword_loc", location_inspect(end_keyword_loc)) + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a DefinedNode node. + def visit_defined_node(node) + table = Table.new("DefinedNode") + id = node_id(node) + + # lparen_loc + unless (lparen_loc = node.lparen_loc).nil? + table.field("lparen_loc", location_inspect(lparen_loc)) + end + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + # rparen_loc + unless (rparen_loc = node.rparen_loc).nil? + table.field("rparen_loc", location_inspect(rparen_loc)) + end + + # keyword_loc + table.field("keyword_loc", location_inspect(node.keyword_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ElseNode node. + def visit_else_node(node) + table = Table.new("ElseNode") + id = node_id(node) + + # else_keyword_loc + table.field("else_keyword_loc", location_inspect(node.else_keyword_loc)) + + # statements + unless (statements = node.statements).nil? + table.field("statements", port: true) + digraph.edge("#{id}:statements -> #{node_id(statements)};") + end + + # end_keyword_loc + unless (end_keyword_loc = node.end_keyword_loc).nil? + table.field("end_keyword_loc", location_inspect(end_keyword_loc)) + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a EmbeddedStatementsNode node. + def visit_embedded_statements_node(node) + table = Table.new("EmbeddedStatementsNode") + id = node_id(node) + + # opening_loc + table.field("opening_loc", location_inspect(node.opening_loc)) + + # statements + unless (statements = node.statements).nil? + table.field("statements", port: true) + digraph.edge("#{id}:statements -> #{node_id(statements)};") + end + + # closing_loc + table.field("closing_loc", location_inspect(node.closing_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a EmbeddedVariableNode node. + def visit_embedded_variable_node(node) + table = Table.new("EmbeddedVariableNode") + id = node_id(node) + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # variable + table.field("variable", port: true) + digraph.edge("#{id}:variable -> #{node_id(node.variable)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a EnsureNode node. + def visit_ensure_node(node) + table = Table.new("EnsureNode") + id = node_id(node) + + # ensure_keyword_loc + table.field("ensure_keyword_loc", location_inspect(node.ensure_keyword_loc)) + + # statements + unless (statements = node.statements).nil? + table.field("statements", port: true) + digraph.edge("#{id}:statements -> #{node_id(statements)};") + end + + # end_keyword_loc + table.field("end_keyword_loc", location_inspect(node.end_keyword_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a FalseNode node. + def visit_false_node(node) + table = Table.new("FalseNode") + id = node_id(node) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a FindPatternNode node. + def visit_find_pattern_node(node) + table = Table.new("FindPatternNode") + id = node_id(node) + + # constant + unless (constant = node.constant).nil? + table.field("constant", port: true) + digraph.edge("#{id}:constant -> #{node_id(constant)};") + end + + # left + table.field("left", port: true) + digraph.edge("#{id}:left -> #{node_id(node.left)};") + + # requireds + if node.requireds.any? + table.field("requireds", port: true) + + waypoint = "#{id}_requireds" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:requireds -> #{waypoint};") + node.requireds.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("requireds", "[]") + end + + # right + table.field("right", port: true) + digraph.edge("#{id}:right -> #{node_id(node.right)};") + + # opening_loc + unless (opening_loc = node.opening_loc).nil? + table.field("opening_loc", location_inspect(opening_loc)) + end + + # closing_loc + unless (closing_loc = node.closing_loc).nil? + table.field("closing_loc", location_inspect(closing_loc)) + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a FlipFlopNode node. + def visit_flip_flop_node(node) + table = Table.new("FlipFlopNode") + id = node_id(node) + + # flags + table.field("flags", range_flags_inspect(node)) + + # left + unless (left = node.left).nil? + table.field("left", port: true) + digraph.edge("#{id}:left -> #{node_id(left)};") + end + + # right + unless (right = node.right).nil? + table.field("right", port: true) + digraph.edge("#{id}:right -> #{node_id(right)};") + end + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a FloatNode node. + def visit_float_node(node) + table = Table.new("FloatNode") + id = node_id(node) + + # value + table.field("value", node.value.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ForNode node. + def visit_for_node(node) + table = Table.new("ForNode") + id = node_id(node) + + # index + table.field("index", port: true) + digraph.edge("#{id}:index -> #{node_id(node.index)};") + + # collection + table.field("collection", port: true) + digraph.edge("#{id}:collection -> #{node_id(node.collection)};") + + # statements + unless (statements = node.statements).nil? + table.field("statements", port: true) + digraph.edge("#{id}:statements -> #{node_id(statements)};") + end + + # for_keyword_loc + table.field("for_keyword_loc", location_inspect(node.for_keyword_loc)) + + # in_keyword_loc + table.field("in_keyword_loc", location_inspect(node.in_keyword_loc)) + + # do_keyword_loc + unless (do_keyword_loc = node.do_keyword_loc).nil? + table.field("do_keyword_loc", location_inspect(do_keyword_loc)) + end + + # end_keyword_loc + table.field("end_keyword_loc", location_inspect(node.end_keyword_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ForwardingArgumentsNode node. + def visit_forwarding_arguments_node(node) + table = Table.new("ForwardingArgumentsNode") + id = node_id(node) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ForwardingParameterNode node. + def visit_forwarding_parameter_node(node) + table = Table.new("ForwardingParameterNode") + id = node_id(node) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ForwardingSuperNode node. + def visit_forwarding_super_node(node) + table = Table.new("ForwardingSuperNode") + id = node_id(node) + + # block + unless (block = node.block).nil? + table.field("block", port: true) + digraph.edge("#{id}:block -> #{node_id(block)};") + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a GlobalVariableAndWriteNode node. + def visit_global_variable_and_write_node(node) + table = Table.new("GlobalVariableAndWriteNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a GlobalVariableOperatorWriteNode node. + def visit_global_variable_operator_write_node(node) + table = Table.new("GlobalVariableOperatorWriteNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + # binary_operator_loc + table.field("binary_operator_loc", location_inspect(node.binary_operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + # binary_operator + table.field("binary_operator", node.binary_operator.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a GlobalVariableOrWriteNode node. + def visit_global_variable_or_write_node(node) + table = Table.new("GlobalVariableOrWriteNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a GlobalVariableReadNode node. + def visit_global_variable_read_node(node) + table = Table.new("GlobalVariableReadNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a GlobalVariableTargetNode node. + def visit_global_variable_target_node(node) + table = Table.new("GlobalVariableTargetNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a GlobalVariableWriteNode node. + def visit_global_variable_write_node(node) + table = Table.new("GlobalVariableWriteNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a HashNode node. + def visit_hash_node(node) + table = Table.new("HashNode") + id = node_id(node) + + # opening_loc + table.field("opening_loc", location_inspect(node.opening_loc)) + + # elements + if node.elements.any? + table.field("elements", port: true) + + waypoint = "#{id}_elements" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:elements -> #{waypoint};") + node.elements.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("elements", "[]") + end + + # closing_loc + table.field("closing_loc", location_inspect(node.closing_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a HashPatternNode node. + def visit_hash_pattern_node(node) + table = Table.new("HashPatternNode") + id = node_id(node) + + # constant + unless (constant = node.constant).nil? + table.field("constant", port: true) + digraph.edge("#{id}:constant -> #{node_id(constant)};") + end + + # elements + if node.elements.any? + table.field("elements", port: true) + + waypoint = "#{id}_elements" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:elements -> #{waypoint};") + node.elements.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("elements", "[]") + end + + # rest + unless (rest = node.rest).nil? + table.field("rest", port: true) + digraph.edge("#{id}:rest -> #{node_id(rest)};") + end + + # opening_loc + unless (opening_loc = node.opening_loc).nil? + table.field("opening_loc", location_inspect(opening_loc)) + end + + # closing_loc + unless (closing_loc = node.closing_loc).nil? + table.field("closing_loc", location_inspect(closing_loc)) + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a IfNode node. + def visit_if_node(node) + table = Table.new("IfNode") + id = node_id(node) + + # if_keyword_loc + unless (if_keyword_loc = node.if_keyword_loc).nil? + table.field("if_keyword_loc", location_inspect(if_keyword_loc)) + end + + # predicate + table.field("predicate", port: true) + digraph.edge("#{id}:predicate -> #{node_id(node.predicate)};") + + # then_keyword_loc + unless (then_keyword_loc = node.then_keyword_loc).nil? + table.field("then_keyword_loc", location_inspect(then_keyword_loc)) + end + + # statements + unless (statements = node.statements).nil? + table.field("statements", port: true) + digraph.edge("#{id}:statements -> #{node_id(statements)};") + end + + # subsequent + unless (subsequent = node.subsequent).nil? + table.field("subsequent", port: true) + digraph.edge("#{id}:subsequent -> #{node_id(subsequent)};") + end + + # end_keyword_loc + unless (end_keyword_loc = node.end_keyword_loc).nil? + table.field("end_keyword_loc", location_inspect(end_keyword_loc)) + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ImaginaryNode node. + def visit_imaginary_node(node) + table = Table.new("ImaginaryNode") + id = node_id(node) + + # numeric + table.field("numeric", port: true) + digraph.edge("#{id}:numeric -> #{node_id(node.numeric)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ImplicitNode node. + def visit_implicit_node(node) + table = Table.new("ImplicitNode") + id = node_id(node) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ImplicitRestNode node. + def visit_implicit_rest_node(node) + table = Table.new("ImplicitRestNode") + id = node_id(node) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a InNode node. + def visit_in_node(node) + table = Table.new("InNode") + id = node_id(node) + + # pattern + table.field("pattern", port: true) + digraph.edge("#{id}:pattern -> #{node_id(node.pattern)};") + + # statements + unless (statements = node.statements).nil? + table.field("statements", port: true) + digraph.edge("#{id}:statements -> #{node_id(statements)};") + end + + # in_loc + table.field("in_loc", location_inspect(node.in_loc)) + + # then_loc + unless (then_loc = node.then_loc).nil? + table.field("then_loc", location_inspect(then_loc)) + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a IndexAndWriteNode node. + def visit_index_and_write_node(node) + table = Table.new("IndexAndWriteNode") + id = node_id(node) + + # flags + table.field("flags", call_node_flags_inspect(node)) + + # receiver + unless (receiver = node.receiver).nil? + table.field("receiver", port: true) + digraph.edge("#{id}:receiver -> #{node_id(receiver)};") + end + + # call_operator_loc + unless (call_operator_loc = node.call_operator_loc).nil? + table.field("call_operator_loc", location_inspect(call_operator_loc)) + end + + # opening_loc + table.field("opening_loc", location_inspect(node.opening_loc)) + + # arguments + unless (arguments = node.arguments).nil? + table.field("arguments", port: true) + digraph.edge("#{id}:arguments -> #{node_id(arguments)};") + end + + # closing_loc + table.field("closing_loc", location_inspect(node.closing_loc)) + + # block + unless (block = node.block).nil? + table.field("block", port: true) + digraph.edge("#{id}:block -> #{node_id(block)};") + end + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a IndexOperatorWriteNode node. + def visit_index_operator_write_node(node) + table = Table.new("IndexOperatorWriteNode") + id = node_id(node) + + # flags + table.field("flags", call_node_flags_inspect(node)) + + # receiver + unless (receiver = node.receiver).nil? + table.field("receiver", port: true) + digraph.edge("#{id}:receiver -> #{node_id(receiver)};") + end + + # call_operator_loc + unless (call_operator_loc = node.call_operator_loc).nil? + table.field("call_operator_loc", location_inspect(call_operator_loc)) + end + + # opening_loc + table.field("opening_loc", location_inspect(node.opening_loc)) + + # arguments + unless (arguments = node.arguments).nil? + table.field("arguments", port: true) + digraph.edge("#{id}:arguments -> #{node_id(arguments)};") + end + + # closing_loc + table.field("closing_loc", location_inspect(node.closing_loc)) + + # block + unless (block = node.block).nil? + table.field("block", port: true) + digraph.edge("#{id}:block -> #{node_id(block)};") + end + + # binary_operator + table.field("binary_operator", node.binary_operator.inspect) + + # binary_operator_loc + table.field("binary_operator_loc", location_inspect(node.binary_operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a IndexOrWriteNode node. + def visit_index_or_write_node(node) + table = Table.new("IndexOrWriteNode") + id = node_id(node) + + # flags + table.field("flags", call_node_flags_inspect(node)) + + # receiver + unless (receiver = node.receiver).nil? + table.field("receiver", port: true) + digraph.edge("#{id}:receiver -> #{node_id(receiver)};") + end + + # call_operator_loc + unless (call_operator_loc = node.call_operator_loc).nil? + table.field("call_operator_loc", location_inspect(call_operator_loc)) + end + + # opening_loc + table.field("opening_loc", location_inspect(node.opening_loc)) + + # arguments + unless (arguments = node.arguments).nil? + table.field("arguments", port: true) + digraph.edge("#{id}:arguments -> #{node_id(arguments)};") + end + + # closing_loc + table.field("closing_loc", location_inspect(node.closing_loc)) + + # block + unless (block = node.block).nil? + table.field("block", port: true) + digraph.edge("#{id}:block -> #{node_id(block)};") + end + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a IndexTargetNode node. + def visit_index_target_node(node) + table = Table.new("IndexTargetNode") + id = node_id(node) + + # flags + table.field("flags", call_node_flags_inspect(node)) + + # receiver + table.field("receiver", port: true) + digraph.edge("#{id}:receiver -> #{node_id(node.receiver)};") + + # opening_loc + table.field("opening_loc", location_inspect(node.opening_loc)) + + # arguments + unless (arguments = node.arguments).nil? + table.field("arguments", port: true) + digraph.edge("#{id}:arguments -> #{node_id(arguments)};") + end + + # closing_loc + table.field("closing_loc", location_inspect(node.closing_loc)) + + # block + unless (block = node.block).nil? + table.field("block", port: true) + digraph.edge("#{id}:block -> #{node_id(block)};") + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a InstanceVariableAndWriteNode node. + def visit_instance_variable_and_write_node(node) + table = Table.new("InstanceVariableAndWriteNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a InstanceVariableOperatorWriteNode node. + def visit_instance_variable_operator_write_node(node) + table = Table.new("InstanceVariableOperatorWriteNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + # binary_operator_loc + table.field("binary_operator_loc", location_inspect(node.binary_operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + # binary_operator + table.field("binary_operator", node.binary_operator.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a InstanceVariableOrWriteNode node. + def visit_instance_variable_or_write_node(node) + table = Table.new("InstanceVariableOrWriteNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a InstanceVariableReadNode node. + def visit_instance_variable_read_node(node) + table = Table.new("InstanceVariableReadNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a InstanceVariableTargetNode node. + def visit_instance_variable_target_node(node) + table = Table.new("InstanceVariableTargetNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a InstanceVariableWriteNode node. + def visit_instance_variable_write_node(node) + table = Table.new("InstanceVariableWriteNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a IntegerNode node. + def visit_integer_node(node) + table = Table.new("IntegerNode") + id = node_id(node) + + # flags + table.field("flags", integer_base_flags_inspect(node)) + + # value + table.field("value", node.value.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a InterpolatedMatchLastLineNode node. + def visit_interpolated_match_last_line_node(node) + table = Table.new("InterpolatedMatchLastLineNode") + id = node_id(node) + + # flags + table.field("flags", regular_expression_flags_inspect(node)) + + # opening_loc + table.field("opening_loc", location_inspect(node.opening_loc)) + + # parts + if node.parts.any? + table.field("parts", port: true) + + waypoint = "#{id}_parts" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:parts -> #{waypoint};") + node.parts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("parts", "[]") + end + + # closing_loc + table.field("closing_loc", location_inspect(node.closing_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a InterpolatedRegularExpressionNode node. + def visit_interpolated_regular_expression_node(node) + table = Table.new("InterpolatedRegularExpressionNode") + id = node_id(node) + + # flags + table.field("flags", regular_expression_flags_inspect(node)) + + # opening_loc + table.field("opening_loc", location_inspect(node.opening_loc)) + + # parts + if node.parts.any? + table.field("parts", port: true) + + waypoint = "#{id}_parts" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:parts -> #{waypoint};") + node.parts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("parts", "[]") + end + + # closing_loc + table.field("closing_loc", location_inspect(node.closing_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a InterpolatedStringNode node. + def visit_interpolated_string_node(node) + table = Table.new("InterpolatedStringNode") + id = node_id(node) + + # flags + table.field("flags", interpolated_string_node_flags_inspect(node)) + + # opening_loc + unless (opening_loc = node.opening_loc).nil? + table.field("opening_loc", location_inspect(opening_loc)) + end + + # parts + if node.parts.any? + table.field("parts", port: true) + + waypoint = "#{id}_parts" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:parts -> #{waypoint};") + node.parts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("parts", "[]") + end + + # closing_loc + unless (closing_loc = node.closing_loc).nil? + table.field("closing_loc", location_inspect(closing_loc)) + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a InterpolatedSymbolNode node. + def visit_interpolated_symbol_node(node) + table = Table.new("InterpolatedSymbolNode") + id = node_id(node) + + # opening_loc + unless (opening_loc = node.opening_loc).nil? + table.field("opening_loc", location_inspect(opening_loc)) + end + + # parts + if node.parts.any? + table.field("parts", port: true) + + waypoint = "#{id}_parts" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:parts -> #{waypoint};") + node.parts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("parts", "[]") + end + + # closing_loc + unless (closing_loc = node.closing_loc).nil? + table.field("closing_loc", location_inspect(closing_loc)) + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a InterpolatedXStringNode node. + def visit_interpolated_x_string_node(node) + table = Table.new("InterpolatedXStringNode") + id = node_id(node) + + # opening_loc + table.field("opening_loc", location_inspect(node.opening_loc)) + + # parts + if node.parts.any? + table.field("parts", port: true) + + waypoint = "#{id}_parts" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:parts -> #{waypoint};") + node.parts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("parts", "[]") + end + + # closing_loc + table.field("closing_loc", location_inspect(node.closing_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ItLocalVariableReadNode node. + def visit_it_local_variable_read_node(node) + table = Table.new("ItLocalVariableReadNode") + id = node_id(node) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ItParametersNode node. + def visit_it_parameters_node(node) + table = Table.new("ItParametersNode") + id = node_id(node) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a KeywordHashNode node. + def visit_keyword_hash_node(node) + table = Table.new("KeywordHashNode") + id = node_id(node) + + # flags + table.field("flags", keyword_hash_node_flags_inspect(node)) + + # elements + if node.elements.any? + table.field("elements", port: true) + + waypoint = "#{id}_elements" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:elements -> #{waypoint};") + node.elements.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("elements", "[]") + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a KeywordRestParameterNode node. + def visit_keyword_rest_parameter_node(node) + table = Table.new("KeywordRestParameterNode") + id = node_id(node) + + # flags + table.field("flags", parameter_flags_inspect(node)) + + # name + table.field("name", node.name.inspect) + + # name_loc + unless (name_loc = node.name_loc).nil? + table.field("name_loc", location_inspect(name_loc)) + end + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a LambdaNode node. + def visit_lambda_node(node) + table = Table.new("LambdaNode") + id = node_id(node) + + # locals + table.field("locals", node.locals.inspect) + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # opening_loc + table.field("opening_loc", location_inspect(node.opening_loc)) + + # closing_loc + table.field("closing_loc", location_inspect(node.closing_loc)) + + # parameters + unless (parameters = node.parameters).nil? + table.field("parameters", port: true) + digraph.edge("#{id}:parameters -> #{node_id(parameters)};") + end + + # body + unless (body = node.body).nil? + table.field("body", port: true) + digraph.edge("#{id}:body -> #{node_id(body)};") + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a LocalVariableAndWriteNode node. + def visit_local_variable_and_write_node(node) + table = Table.new("LocalVariableAndWriteNode") + id = node_id(node) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + # name + table.field("name", node.name.inspect) + + # depth + table.field("depth", node.depth.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a LocalVariableOperatorWriteNode node. + def visit_local_variable_operator_write_node(node) + table = Table.new("LocalVariableOperatorWriteNode") + id = node_id(node) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + # binary_operator_loc + table.field("binary_operator_loc", location_inspect(node.binary_operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + # name + table.field("name", node.name.inspect) + + # binary_operator + table.field("binary_operator", node.binary_operator.inspect) + + # depth + table.field("depth", node.depth.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a LocalVariableOrWriteNode node. + def visit_local_variable_or_write_node(node) + table = Table.new("LocalVariableOrWriteNode") + id = node_id(node) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + # name + table.field("name", node.name.inspect) + + # depth + table.field("depth", node.depth.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a LocalVariableReadNode node. + def visit_local_variable_read_node(node) + table = Table.new("LocalVariableReadNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + # depth + table.field("depth", node.depth.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a LocalVariableTargetNode node. + def visit_local_variable_target_node(node) + table = Table.new("LocalVariableTargetNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + # depth + table.field("depth", node.depth.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a LocalVariableWriteNode node. + def visit_local_variable_write_node(node) + table = Table.new("LocalVariableWriteNode") + id = node_id(node) + + # name + table.field("name", node.name.inspect) + + # depth + table.field("depth", node.depth.inspect) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a MatchLastLineNode node. + def visit_match_last_line_node(node) + table = Table.new("MatchLastLineNode") + id = node_id(node) + + # flags + table.field("flags", regular_expression_flags_inspect(node)) + + # opening_loc + table.field("opening_loc", location_inspect(node.opening_loc)) + + # content_loc + table.field("content_loc", location_inspect(node.content_loc)) + + # closing_loc + table.field("closing_loc", location_inspect(node.closing_loc)) + + # unescaped + table.field("unescaped", node.unescaped.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a MatchPredicateNode node. + def visit_match_predicate_node(node) + table = Table.new("MatchPredicateNode") + id = node_id(node) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + # pattern + table.field("pattern", port: true) + digraph.edge("#{id}:pattern -> #{node_id(node.pattern)};") + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a MatchRequiredNode node. + def visit_match_required_node(node) + table = Table.new("MatchRequiredNode") + id = node_id(node) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + # pattern + table.field("pattern", port: true) + digraph.edge("#{id}:pattern -> #{node_id(node.pattern)};") + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a MatchWriteNode node. + def visit_match_write_node(node) + table = Table.new("MatchWriteNode") + id = node_id(node) + + # call + table.field("call", port: true) + digraph.edge("#{id}:call -> #{node_id(node.call)};") + + # targets + if node.targets.any? + table.field("targets", port: true) + + waypoint = "#{id}_targets" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:targets -> #{waypoint};") + node.targets.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("targets", "[]") + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a MissingNode node. + def visit_missing_node(node) + table = Table.new("MissingNode") + id = node_id(node) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ModuleNode node. + def visit_module_node(node) + table = Table.new("ModuleNode") + id = node_id(node) + + # locals + table.field("locals", node.locals.inspect) + + # module_keyword_loc + table.field("module_keyword_loc", location_inspect(node.module_keyword_loc)) + + # constant_path + table.field("constant_path", port: true) + digraph.edge("#{id}:constant_path -> #{node_id(node.constant_path)};") + + # body + unless (body = node.body).nil? + table.field("body", port: true) + digraph.edge("#{id}:body -> #{node_id(body)};") + end + + # end_keyword_loc + table.field("end_keyword_loc", location_inspect(node.end_keyword_loc)) + + # name + table.field("name", node.name.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a MultiTargetNode node. + def visit_multi_target_node(node) + table = Table.new("MultiTargetNode") + id = node_id(node) + + # lefts + if node.lefts.any? + table.field("lefts", port: true) + + waypoint = "#{id}_lefts" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:lefts -> #{waypoint};") + node.lefts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("lefts", "[]") + end + + # rest + unless (rest = node.rest).nil? + table.field("rest", port: true) + digraph.edge("#{id}:rest -> #{node_id(rest)};") + end + + # rights + if node.rights.any? + table.field("rights", port: true) + + waypoint = "#{id}_rights" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:rights -> #{waypoint};") + node.rights.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("rights", "[]") + end + + # lparen_loc + unless (lparen_loc = node.lparen_loc).nil? + table.field("lparen_loc", location_inspect(lparen_loc)) + end + + # rparen_loc + unless (rparen_loc = node.rparen_loc).nil? + table.field("rparen_loc", location_inspect(rparen_loc)) + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a MultiWriteNode node. + def visit_multi_write_node(node) + table = Table.new("MultiWriteNode") + id = node_id(node) + + # lefts + if node.lefts.any? + table.field("lefts", port: true) + + waypoint = "#{id}_lefts" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:lefts -> #{waypoint};") + node.lefts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("lefts", "[]") + end + + # rest + unless (rest = node.rest).nil? + table.field("rest", port: true) + digraph.edge("#{id}:rest -> #{node_id(rest)};") + end + + # rights + if node.rights.any? + table.field("rights", port: true) + + waypoint = "#{id}_rights" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:rights -> #{waypoint};") + node.rights.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("rights", "[]") + end + + # lparen_loc + unless (lparen_loc = node.lparen_loc).nil? + table.field("lparen_loc", location_inspect(lparen_loc)) + end + + # rparen_loc + unless (rparen_loc = node.rparen_loc).nil? + table.field("rparen_loc", location_inspect(rparen_loc)) + end + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a NextNode node. + def visit_next_node(node) + table = Table.new("NextNode") + id = node_id(node) + + # arguments + unless (arguments = node.arguments).nil? + table.field("arguments", port: true) + digraph.edge("#{id}:arguments -> #{node_id(arguments)};") + end + + # keyword_loc + table.field("keyword_loc", location_inspect(node.keyword_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a NilNode node. + def visit_nil_node(node) + table = Table.new("NilNode") + id = node_id(node) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a NoKeywordsParameterNode node. + def visit_no_keywords_parameter_node(node) + table = Table.new("NoKeywordsParameterNode") + id = node_id(node) + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # keyword_loc + table.field("keyword_loc", location_inspect(node.keyword_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a NumberedParametersNode node. + def visit_numbered_parameters_node(node) + table = Table.new("NumberedParametersNode") + id = node_id(node) + + # maximum + table.field("maximum", node.maximum.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a NumberedReferenceReadNode node. + def visit_numbered_reference_read_node(node) + table = Table.new("NumberedReferenceReadNode") + id = node_id(node) + + # number + table.field("number", node.number.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a OptionalKeywordParameterNode node. + def visit_optional_keyword_parameter_node(node) + table = Table.new("OptionalKeywordParameterNode") + id = node_id(node) + + # flags + table.field("flags", parameter_flags_inspect(node)) + + # name + table.field("name", node.name.inspect) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a OptionalParameterNode node. + def visit_optional_parameter_node(node) + table = Table.new("OptionalParameterNode") + id = node_id(node) + + # flags + table.field("flags", parameter_flags_inspect(node)) + + # name + table.field("name", node.name.inspect) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # value + table.field("value", port: true) + digraph.edge("#{id}:value -> #{node_id(node.value)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a OrNode node. + def visit_or_node(node) + table = Table.new("OrNode") + id = node_id(node) + + # left + table.field("left", port: true) + digraph.edge("#{id}:left -> #{node_id(node.left)};") + + # right + table.field("right", port: true) + digraph.edge("#{id}:right -> #{node_id(node.right)};") + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ParametersNode node. + def visit_parameters_node(node) + table = Table.new("ParametersNode") + id = node_id(node) + + # requireds + if node.requireds.any? + table.field("requireds", port: true) + + waypoint = "#{id}_requireds" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:requireds -> #{waypoint};") + node.requireds.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("requireds", "[]") + end + + # optionals + if node.optionals.any? + table.field("optionals", port: true) + + waypoint = "#{id}_optionals" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:optionals -> #{waypoint};") + node.optionals.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("optionals", "[]") + end + + # rest + unless (rest = node.rest).nil? + table.field("rest", port: true) + digraph.edge("#{id}:rest -> #{node_id(rest)};") + end + + # posts + if node.posts.any? + table.field("posts", port: true) + + waypoint = "#{id}_posts" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:posts -> #{waypoint};") + node.posts.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("posts", "[]") + end + + # keywords + if node.keywords.any? + table.field("keywords", port: true) + + waypoint = "#{id}_keywords" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:keywords -> #{waypoint};") + node.keywords.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("keywords", "[]") + end + + # keyword_rest + unless (keyword_rest = node.keyword_rest).nil? + table.field("keyword_rest", port: true) + digraph.edge("#{id}:keyword_rest -> #{node_id(keyword_rest)};") + end + + # block + unless (block = node.block).nil? + table.field("block", port: true) + digraph.edge("#{id}:block -> #{node_id(block)};") + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ParenthesesNode node. + def visit_parentheses_node(node) + table = Table.new("ParenthesesNode") + id = node_id(node) + + # flags + table.field("flags", parentheses_node_flags_inspect(node)) + + # body + unless (body = node.body).nil? + table.field("body", port: true) + digraph.edge("#{id}:body -> #{node_id(body)};") + end + + # opening_loc + table.field("opening_loc", location_inspect(node.opening_loc)) + + # closing_loc + table.field("closing_loc", location_inspect(node.closing_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a PinnedExpressionNode node. + def visit_pinned_expression_node(node) + table = Table.new("PinnedExpressionNode") + id = node_id(node) + + # expression + table.field("expression", port: true) + digraph.edge("#{id}:expression -> #{node_id(node.expression)};") + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # lparen_loc + table.field("lparen_loc", location_inspect(node.lparen_loc)) + + # rparen_loc + table.field("rparen_loc", location_inspect(node.rparen_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a PinnedVariableNode node. + def visit_pinned_variable_node(node) + table = Table.new("PinnedVariableNode") + id = node_id(node) + + # variable + table.field("variable", port: true) + digraph.edge("#{id}:variable -> #{node_id(node.variable)};") + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a PostExecutionNode node. + def visit_post_execution_node(node) + table = Table.new("PostExecutionNode") + id = node_id(node) + + # statements + unless (statements = node.statements).nil? + table.field("statements", port: true) + digraph.edge("#{id}:statements -> #{node_id(statements)};") + end + + # keyword_loc + table.field("keyword_loc", location_inspect(node.keyword_loc)) + + # opening_loc + table.field("opening_loc", location_inspect(node.opening_loc)) + + # closing_loc + table.field("closing_loc", location_inspect(node.closing_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a PreExecutionNode node. + def visit_pre_execution_node(node) + table = Table.new("PreExecutionNode") + id = node_id(node) + + # statements + unless (statements = node.statements).nil? + table.field("statements", port: true) + digraph.edge("#{id}:statements -> #{node_id(statements)};") + end + + # keyword_loc + table.field("keyword_loc", location_inspect(node.keyword_loc)) + + # opening_loc + table.field("opening_loc", location_inspect(node.opening_loc)) + + # closing_loc + table.field("closing_loc", location_inspect(node.closing_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ProgramNode node. + def visit_program_node(node) + table = Table.new("ProgramNode") + id = node_id(node) + + # locals + table.field("locals", node.locals.inspect) + + # statements + table.field("statements", port: true) + digraph.edge("#{id}:statements -> #{node_id(node.statements)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a RangeNode node. + def visit_range_node(node) + table = Table.new("RangeNode") + id = node_id(node) + + # flags + table.field("flags", range_flags_inspect(node)) + + # left + unless (left = node.left).nil? + table.field("left", port: true) + digraph.edge("#{id}:left -> #{node_id(left)};") + end + + # right + unless (right = node.right).nil? + table.field("right", port: true) + digraph.edge("#{id}:right -> #{node_id(right)};") + end + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a RationalNode node. + def visit_rational_node(node) + table = Table.new("RationalNode") + id = node_id(node) + + # flags + table.field("flags", integer_base_flags_inspect(node)) + + # numerator + table.field("numerator", node.numerator.inspect) + + # denominator + table.field("denominator", node.denominator.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a RedoNode node. + def visit_redo_node(node) + table = Table.new("RedoNode") + id = node_id(node) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a RegularExpressionNode node. + def visit_regular_expression_node(node) + table = Table.new("RegularExpressionNode") + id = node_id(node) + + # flags + table.field("flags", regular_expression_flags_inspect(node)) + + # opening_loc + table.field("opening_loc", location_inspect(node.opening_loc)) + + # content_loc + table.field("content_loc", location_inspect(node.content_loc)) + + # closing_loc + table.field("closing_loc", location_inspect(node.closing_loc)) + + # unescaped + table.field("unescaped", node.unescaped.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a RequiredKeywordParameterNode node. + def visit_required_keyword_parameter_node(node) + table = Table.new("RequiredKeywordParameterNode") + id = node_id(node) + + # flags + table.field("flags", parameter_flags_inspect(node)) + + # name + table.field("name", node.name.inspect) + + # name_loc + table.field("name_loc", location_inspect(node.name_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a RequiredParameterNode node. + def visit_required_parameter_node(node) + table = Table.new("RequiredParameterNode") + id = node_id(node) + + # flags + table.field("flags", parameter_flags_inspect(node)) + + # name + table.field("name", node.name.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a RescueModifierNode node. + def visit_rescue_modifier_node(node) + table = Table.new("RescueModifierNode") + id = node_id(node) + + # expression + table.field("expression", port: true) + digraph.edge("#{id}:expression -> #{node_id(node.expression)};") + + # keyword_loc + table.field("keyword_loc", location_inspect(node.keyword_loc)) + + # rescue_expression + table.field("rescue_expression", port: true) + digraph.edge("#{id}:rescue_expression -> #{node_id(node.rescue_expression)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a RescueNode node. + def visit_rescue_node(node) + table = Table.new("RescueNode") + id = node_id(node) + + # keyword_loc + table.field("keyword_loc", location_inspect(node.keyword_loc)) + + # exceptions + if node.exceptions.any? + table.field("exceptions", port: true) + + waypoint = "#{id}_exceptions" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:exceptions -> #{waypoint};") + node.exceptions.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("exceptions", "[]") + end + + # operator_loc + unless (operator_loc = node.operator_loc).nil? + table.field("operator_loc", location_inspect(operator_loc)) + end + + # reference + unless (reference = node.reference).nil? + table.field("reference", port: true) + digraph.edge("#{id}:reference -> #{node_id(reference)};") + end + + # then_keyword_loc + unless (then_keyword_loc = node.then_keyword_loc).nil? + table.field("then_keyword_loc", location_inspect(then_keyword_loc)) + end + + # statements + unless (statements = node.statements).nil? + table.field("statements", port: true) + digraph.edge("#{id}:statements -> #{node_id(statements)};") + end + + # subsequent + unless (subsequent = node.subsequent).nil? + table.field("subsequent", port: true) + digraph.edge("#{id}:subsequent -> #{node_id(subsequent)};") + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a RestParameterNode node. + def visit_rest_parameter_node(node) + table = Table.new("RestParameterNode") + id = node_id(node) + + # flags + table.field("flags", parameter_flags_inspect(node)) + + # name + table.field("name", node.name.inspect) + + # name_loc + unless (name_loc = node.name_loc).nil? + table.field("name_loc", location_inspect(name_loc)) + end + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a RetryNode node. + def visit_retry_node(node) + table = Table.new("RetryNode") + id = node_id(node) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ReturnNode node. + def visit_return_node(node) + table = Table.new("ReturnNode") + id = node_id(node) + + # keyword_loc + table.field("keyword_loc", location_inspect(node.keyword_loc)) + + # arguments + unless (arguments = node.arguments).nil? + table.field("arguments", port: true) + digraph.edge("#{id}:arguments -> #{node_id(arguments)};") + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a SelfNode node. + def visit_self_node(node) + table = Table.new("SelfNode") + id = node_id(node) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a ShareableConstantNode node. + def visit_shareable_constant_node(node) + table = Table.new("ShareableConstantNode") + id = node_id(node) + + # flags + table.field("flags", shareable_constant_node_flags_inspect(node)) + + # write + table.field("write", port: true) + digraph.edge("#{id}:write -> #{node_id(node.write)};") + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a SingletonClassNode node. + def visit_singleton_class_node(node) + table = Table.new("SingletonClassNode") + id = node_id(node) + + # locals + table.field("locals", node.locals.inspect) + + # class_keyword_loc + table.field("class_keyword_loc", location_inspect(node.class_keyword_loc)) + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # expression + table.field("expression", port: true) + digraph.edge("#{id}:expression -> #{node_id(node.expression)};") + + # body + unless (body = node.body).nil? + table.field("body", port: true) + digraph.edge("#{id}:body -> #{node_id(body)};") + end + + # end_keyword_loc + table.field("end_keyword_loc", location_inspect(node.end_keyword_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a SourceEncodingNode node. + def visit_source_encoding_node(node) + table = Table.new("SourceEncodingNode") + id = node_id(node) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a SourceFileNode node. + def visit_source_file_node(node) + table = Table.new("SourceFileNode") + id = node_id(node) + + # flags + table.field("flags", string_flags_inspect(node)) + + # filepath + table.field("filepath", node.filepath.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a SourceLineNode node. + def visit_source_line_node(node) + table = Table.new("SourceLineNode") + id = node_id(node) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a SplatNode node. + def visit_splat_node(node) + table = Table.new("SplatNode") + id = node_id(node) + + # operator_loc + table.field("operator_loc", location_inspect(node.operator_loc)) + + # expression + unless (expression = node.expression).nil? + table.field("expression", port: true) + digraph.edge("#{id}:expression -> #{node_id(expression)};") + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a StatementsNode node. + def visit_statements_node(node) + table = Table.new("StatementsNode") + id = node_id(node) + + # body + if node.body.any? + table.field("body", port: true) + + waypoint = "#{id}_body" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:body -> #{waypoint};") + node.body.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("body", "[]") + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a StringNode node. + def visit_string_node(node) + table = Table.new("StringNode") + id = node_id(node) + + # flags + table.field("flags", string_flags_inspect(node)) + + # opening_loc + unless (opening_loc = node.opening_loc).nil? + table.field("opening_loc", location_inspect(opening_loc)) + end + + # content_loc + table.field("content_loc", location_inspect(node.content_loc)) + + # closing_loc + unless (closing_loc = node.closing_loc).nil? + table.field("closing_loc", location_inspect(closing_loc)) + end + + # unescaped + table.field("unescaped", node.unescaped.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a SuperNode node. + def visit_super_node(node) + table = Table.new("SuperNode") + id = node_id(node) + + # keyword_loc + table.field("keyword_loc", location_inspect(node.keyword_loc)) + + # lparen_loc + unless (lparen_loc = node.lparen_loc).nil? + table.field("lparen_loc", location_inspect(lparen_loc)) + end + + # arguments + unless (arguments = node.arguments).nil? + table.field("arguments", port: true) + digraph.edge("#{id}:arguments -> #{node_id(arguments)};") + end + + # rparen_loc + unless (rparen_loc = node.rparen_loc).nil? + table.field("rparen_loc", location_inspect(rparen_loc)) + end + + # block + unless (block = node.block).nil? + table.field("block", port: true) + digraph.edge("#{id}:block -> #{node_id(block)};") + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a SymbolNode node. + def visit_symbol_node(node) + table = Table.new("SymbolNode") + id = node_id(node) + + # flags + table.field("flags", symbol_flags_inspect(node)) + + # opening_loc + unless (opening_loc = node.opening_loc).nil? + table.field("opening_loc", location_inspect(opening_loc)) + end + + # value_loc + unless (value_loc = node.value_loc).nil? + table.field("value_loc", location_inspect(value_loc)) + end + + # closing_loc + unless (closing_loc = node.closing_loc).nil? + table.field("closing_loc", location_inspect(closing_loc)) + end + + # unescaped + table.field("unescaped", node.unescaped.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a TrueNode node. + def visit_true_node(node) + table = Table.new("TrueNode") + id = node_id(node) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a UndefNode node. + def visit_undef_node(node) + table = Table.new("UndefNode") + id = node_id(node) + + # names + if node.names.any? + table.field("names", port: true) + + waypoint = "#{id}_names" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:names -> #{waypoint};") + node.names.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("names", "[]") + end + + # keyword_loc + table.field("keyword_loc", location_inspect(node.keyword_loc)) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a UnlessNode node. + def visit_unless_node(node) + table = Table.new("UnlessNode") + id = node_id(node) + + # keyword_loc + table.field("keyword_loc", location_inspect(node.keyword_loc)) + + # predicate + table.field("predicate", port: true) + digraph.edge("#{id}:predicate -> #{node_id(node.predicate)};") + + # then_keyword_loc + unless (then_keyword_loc = node.then_keyword_loc).nil? + table.field("then_keyword_loc", location_inspect(then_keyword_loc)) + end + + # statements + unless (statements = node.statements).nil? + table.field("statements", port: true) + digraph.edge("#{id}:statements -> #{node_id(statements)};") + end + + # else_clause + unless (else_clause = node.else_clause).nil? + table.field("else_clause", port: true) + digraph.edge("#{id}:else_clause -> #{node_id(else_clause)};") + end + + # end_keyword_loc + unless (end_keyword_loc = node.end_keyword_loc).nil? + table.field("end_keyword_loc", location_inspect(end_keyword_loc)) + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a UntilNode node. + def visit_until_node(node) + table = Table.new("UntilNode") + id = node_id(node) + + # flags + table.field("flags", loop_flags_inspect(node)) + + # keyword_loc + table.field("keyword_loc", location_inspect(node.keyword_loc)) + + # do_keyword_loc + unless (do_keyword_loc = node.do_keyword_loc).nil? + table.field("do_keyword_loc", location_inspect(do_keyword_loc)) + end + + # closing_loc + unless (closing_loc = node.closing_loc).nil? + table.field("closing_loc", location_inspect(closing_loc)) + end + + # predicate + table.field("predicate", port: true) + digraph.edge("#{id}:predicate -> #{node_id(node.predicate)};") + + # statements + unless (statements = node.statements).nil? + table.field("statements", port: true) + digraph.edge("#{id}:statements -> #{node_id(statements)};") + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a WhenNode node. + def visit_when_node(node) + table = Table.new("WhenNode") + id = node_id(node) + + # keyword_loc + table.field("keyword_loc", location_inspect(node.keyword_loc)) + + # conditions + if node.conditions.any? + table.field("conditions", port: true) + + waypoint = "#{id}_conditions" + digraph.waypoint("#{waypoint};") + + digraph.edge("#{id}:conditions -> #{waypoint};") + node.conditions.each { |child| digraph.edge("#{waypoint} -> #{node_id(child)};") } + else + table.field("conditions", "[]") + end + + # then_keyword_loc + unless (then_keyword_loc = node.then_keyword_loc).nil? + table.field("then_keyword_loc", location_inspect(then_keyword_loc)) + end + + # statements + unless (statements = node.statements).nil? + table.field("statements", port: true) + digraph.edge("#{id}:statements -> #{node_id(statements)};") + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a WhileNode node. + def visit_while_node(node) + table = Table.new("WhileNode") + id = node_id(node) + + # flags + table.field("flags", loop_flags_inspect(node)) + + # keyword_loc + table.field("keyword_loc", location_inspect(node.keyword_loc)) + + # do_keyword_loc + unless (do_keyword_loc = node.do_keyword_loc).nil? + table.field("do_keyword_loc", location_inspect(do_keyword_loc)) + end + + # closing_loc + unless (closing_loc = node.closing_loc).nil? + table.field("closing_loc", location_inspect(closing_loc)) + end + + # predicate + table.field("predicate", port: true) + digraph.edge("#{id}:predicate -> #{node_id(node.predicate)};") + + # statements + unless (statements = node.statements).nil? + table.field("statements", port: true) + digraph.edge("#{id}:statements -> #{node_id(statements)};") + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a XStringNode node. + def visit_x_string_node(node) + table = Table.new("XStringNode") + id = node_id(node) + + # flags + table.field("flags", encoding_flags_inspect(node)) + + # opening_loc + table.field("opening_loc", location_inspect(node.opening_loc)) + + # content_loc + table.field("content_loc", location_inspect(node.content_loc)) + + # closing_loc + table.field("closing_loc", location_inspect(node.closing_loc)) + + # unescaped + table.field("unescaped", node.unescaped.inspect) + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + # Visit a YieldNode node. + def visit_yield_node(node) + table = Table.new("YieldNode") + id = node_id(node) + + # keyword_loc + table.field("keyword_loc", location_inspect(node.keyword_loc)) + + # lparen_loc + unless (lparen_loc = node.lparen_loc).nil? + table.field("lparen_loc", location_inspect(lparen_loc)) + end + + # arguments + unless (arguments = node.arguments).nil? + table.field("arguments", port: true) + digraph.edge("#{id}:arguments -> #{node_id(arguments)};") + end + + # rparen_loc + unless (rparen_loc = node.rparen_loc).nil? + table.field("rparen_loc", location_inspect(rparen_loc)) + end + + digraph.nodes << <<~DOT + #{id} [ + label=<#{table.to_dot.gsub(/\n/, "\n ")}> + ]; + DOT + + super + end + + private + + # Generate a unique node ID for a node throughout the digraph. + def node_id(node) + "Node_#{node.object_id}" + end + + # Inspect a location to display the start and end line and column numbers. + def location_inspect(location) + "(#{location.start_line},#{location.start_column})-(#{location.end_line},#{location.end_column})" + end + + # Inspect a node that has arguments_node_flags flags to display the flags as a + # comma-separated list. + def arguments_node_flags_inspect(node) + flags = [] #: Array[String] + flags << "contains_forwarding" if node.contains_forwarding? + flags << "contains_keywords" if node.contains_keywords? + flags << "contains_keyword_splat" if node.contains_keyword_splat? + flags << "contains_splat" if node.contains_splat? + flags << "contains_multiple_splats" if node.contains_multiple_splats? + flags.join(", ") + end + + # Inspect a node that has array_node_flags flags to display the flags as a + # comma-separated list. + def array_node_flags_inspect(node) + flags = [] #: Array[String] + flags << "contains_splat" if node.contains_splat? + flags.join(", ") + end + + # Inspect a node that has call_node_flags flags to display the flags as a + # comma-separated list. + def call_node_flags_inspect(node) + flags = [] #: Array[String] + flags << "safe_navigation" if node.safe_navigation? + flags << "variable_call" if node.variable_call? + flags << "attribute_write" if node.attribute_write? + flags << "ignore_visibility" if node.ignore_visibility? + flags.join(", ") + end + + # Inspect a node that has encoding_flags flags to display the flags as a + # comma-separated list. + def encoding_flags_inspect(node) + flags = [] #: Array[String] + flags << "forced_utf8_encoding" if node.forced_utf8_encoding? + flags << "forced_binary_encoding" if node.forced_binary_encoding? + flags.join(", ") + end + + # Inspect a node that has integer_base_flags flags to display the flags as a + # comma-separated list. + def integer_base_flags_inspect(node) + flags = [] #: Array[String] + flags << "binary" if node.binary? + flags << "decimal" if node.decimal? + flags << "octal" if node.octal? + flags << "hexadecimal" if node.hexadecimal? + flags.join(", ") + end + + # Inspect a node that has interpolated_string_node_flags flags to display the flags as a + # comma-separated list. + def interpolated_string_node_flags_inspect(node) + flags = [] #: Array[String] + flags << "frozen" if node.frozen? + flags << "mutable" if node.mutable? + flags.join(", ") + end + + # Inspect a node that has keyword_hash_node_flags flags to display the flags as a + # comma-separated list. + def keyword_hash_node_flags_inspect(node) + flags = [] #: Array[String] + flags << "symbol_keys" if node.symbol_keys? + flags.join(", ") + end + + # Inspect a node that has loop_flags flags to display the flags as a + # comma-separated list. + def loop_flags_inspect(node) + flags = [] #: Array[String] + flags << "begin_modifier" if node.begin_modifier? + flags.join(", ") + end + + # Inspect a node that has parameter_flags flags to display the flags as a + # comma-separated list. + def parameter_flags_inspect(node) + flags = [] #: Array[String] + flags << "repeated_parameter" if node.repeated_parameter? + flags.join(", ") + end + + # Inspect a node that has parentheses_node_flags flags to display the flags as a + # comma-separated list. + def parentheses_node_flags_inspect(node) + flags = [] #: Array[String] + flags << "multiple_statements" if node.multiple_statements? + flags.join(", ") + end + + # Inspect a node that has range_flags flags to display the flags as a + # comma-separated list. + def range_flags_inspect(node) + flags = [] #: Array[String] + flags << "exclude_end" if node.exclude_end? + flags.join(", ") + end + + # Inspect a node that has regular_expression_flags flags to display the flags as a + # comma-separated list. + def regular_expression_flags_inspect(node) + flags = [] #: Array[String] + flags << "ignore_case" if node.ignore_case? + flags << "extended" if node.extended? + flags << "multi_line" if node.multi_line? + flags << "once" if node.once? + flags << "euc_jp" if node.euc_jp? + flags << "ascii_8bit" if node.ascii_8bit? + flags << "windows_31j" if node.windows_31j? + flags << "utf_8" if node.utf_8? + flags << "forced_utf8_encoding" if node.forced_utf8_encoding? + flags << "forced_binary_encoding" if node.forced_binary_encoding? + flags << "forced_us_ascii_encoding" if node.forced_us_ascii_encoding? + flags.join(", ") + end + + # Inspect a node that has shareable_constant_node_flags flags to display the flags as a + # comma-separated list. + def shareable_constant_node_flags_inspect(node) + flags = [] #: Array[String] + flags << "literal" if node.literal? + flags << "experimental_everything" if node.experimental_everything? + flags << "experimental_copy" if node.experimental_copy? + flags.join(", ") + end + + # Inspect a node that has string_flags flags to display the flags as a + # comma-separated list. + def string_flags_inspect(node) + flags = [] #: Array[String] + flags << "forced_utf8_encoding" if node.forced_utf8_encoding? + flags << "forced_binary_encoding" if node.forced_binary_encoding? + flags << "frozen" if node.frozen? + flags << "mutable" if node.mutable? + flags.join(", ") + end + + # Inspect a node that has symbol_flags flags to display the flags as a + # comma-separated list. + def symbol_flags_inspect(node) + flags = [] #: Array[String] + flags << "forced_utf8_encoding" if node.forced_utf8_encoding? + flags << "forced_binary_encoding" if node.forced_binary_encoding? + flags << "forced_us_ascii_encoding" if node.forced_us_ascii_encoding? + flags.join(", ") + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/dsl.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/dsl.rb new file mode 100644 index 00000000..ac2c4d16 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/dsl.rb @@ -0,0 +1,1000 @@ +# frozen_string_literal: true + +=begin +This file is generated by the templates/template.rb script and should not be +modified manually. See templates/lib/prism/dsl.rb.erb +if you are looking to modify the template +=end + +module Prism + # The DSL module provides a set of methods that can be used to create prism + # nodes in a more concise manner. For example, instead of writing: + # + # source = Prism::Source.for("[1]") + # + # Prism::ArrayNode.new( + # source, + # 0, + # Prism::Location.new(source, 0, 3), + # 0, + # [ + # Prism::IntegerNode.new( + # source, + # 0, + # Prism::Location.new(source, 1, 1), + # Prism::IntegerBaseFlags::DECIMAL, + # 1 + # ) + # ], + # Prism::Location.new(source, 0, 1), + # Prism::Location.new(source, 2, 1) + # ) + # + # you could instead write: + # + # class Builder + # include Prism::DSL + # + # attr_reader :default_source + # + # def initialize + # @default_source = source("[1]") + # end + # + # def build + # array_node( + # location: location(start_offset: 0, length: 3), + # elements: [ + # integer_node( + # location: location(start_offset: 1, length: 1), + # flags: integer_base_flag(:decimal), + # value: 1 + # ) + # ], + # opening_loc: location(start_offset: 0, length: 1), + # closing_loc: location(start_offset: 2, length: 1) + # ) + # end + # end + # + # This is mostly helpful in the context of generating trees programmatically. + module DSL + # Provide all of these methods as module methods as well, to allow for + # building nodes like Prism::DSL.nil_node. + extend self + + # Create a new Source object. + def source(string) + Source.for(string) + end + + # Create a new Location object. + def location(source: default_source, start_offset: 0, length: 0) + Location.new(source, start_offset, length) + end + + # Create a new AliasGlobalVariableNode node. + def alias_global_variable_node(source: default_source, node_id: 0, location: default_location, flags: 0, new_name: global_variable_read_node(source: source), old_name: global_variable_read_node(source: source), keyword_loc: location) + AliasGlobalVariableNode.new(source, node_id, location, flags, new_name, old_name, keyword_loc) + end + + # Create a new AliasMethodNode node. + def alias_method_node(source: default_source, node_id: 0, location: default_location, flags: 0, new_name: symbol_node(source: source), old_name: symbol_node(source: source), keyword_loc: location) + AliasMethodNode.new(source, node_id, location, flags, new_name, old_name, keyword_loc) + end + + # Create a new AlternationPatternNode node. + def alternation_pattern_node(source: default_source, node_id: 0, location: default_location, flags: 0, left: default_node(source, location), right: default_node(source, location), operator_loc: location) + AlternationPatternNode.new(source, node_id, location, flags, left, right, operator_loc) + end + + # Create a new AndNode node. + def and_node(source: default_source, node_id: 0, location: default_location, flags: 0, left: default_node(source, location), right: default_node(source, location), operator_loc: location) + AndNode.new(source, node_id, location, flags, left, right, operator_loc) + end + + # Create a new ArgumentsNode node. + def arguments_node(source: default_source, node_id: 0, location: default_location, flags: 0, arguments: []) + ArgumentsNode.new(source, node_id, location, flags, arguments) + end + + # Create a new ArrayNode node. + def array_node(source: default_source, node_id: 0, location: default_location, flags: 0, elements: [], opening_loc: nil, closing_loc: nil) + ArrayNode.new(source, node_id, location, flags, elements, opening_loc, closing_loc) + end + + # Create a new ArrayPatternNode node. + def array_pattern_node(source: default_source, node_id: 0, location: default_location, flags: 0, constant: nil, requireds: [], rest: nil, posts: [], opening_loc: nil, closing_loc: nil) + ArrayPatternNode.new(source, node_id, location, flags, constant, requireds, rest, posts, opening_loc, closing_loc) + end + + # Create a new AssocNode node. + def assoc_node(source: default_source, node_id: 0, location: default_location, flags: 0, key: default_node(source, location), value: default_node(source, location), operator_loc: nil) + AssocNode.new(source, node_id, location, flags, key, value, operator_loc) + end + + # Create a new AssocSplatNode node. + def assoc_splat_node(source: default_source, node_id: 0, location: default_location, flags: 0, value: nil, operator_loc: location) + AssocSplatNode.new(source, node_id, location, flags, value, operator_loc) + end + + # Create a new BackReferenceReadNode node. + def back_reference_read_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"") + BackReferenceReadNode.new(source, node_id, location, flags, name) + end + + # Create a new BeginNode node. + def begin_node(source: default_source, node_id: 0, location: default_location, flags: 0, begin_keyword_loc: nil, statements: nil, rescue_clause: nil, else_clause: nil, ensure_clause: nil, end_keyword_loc: nil) + BeginNode.new(source, node_id, location, flags, begin_keyword_loc, statements, rescue_clause, else_clause, ensure_clause, end_keyword_loc) + end + + # Create a new BlockArgumentNode node. + def block_argument_node(source: default_source, node_id: 0, location: default_location, flags: 0, expression: nil, operator_loc: location) + BlockArgumentNode.new(source, node_id, location, flags, expression, operator_loc) + end + + # Create a new BlockLocalVariableNode node. + def block_local_variable_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"") + BlockLocalVariableNode.new(source, node_id, location, flags, name) + end + + # Create a new BlockNode node. + def block_node(source: default_source, node_id: 0, location: default_location, flags: 0, locals: [], parameters: nil, body: nil, opening_loc: location, closing_loc: location) + BlockNode.new(source, node_id, location, flags, locals, parameters, body, opening_loc, closing_loc) + end + + # Create a new BlockParameterNode node. + def block_parameter_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: nil, name_loc: nil, operator_loc: location) + BlockParameterNode.new(source, node_id, location, flags, name, name_loc, operator_loc) + end + + # Create a new BlockParametersNode node. + def block_parameters_node(source: default_source, node_id: 0, location: default_location, flags: 0, parameters: nil, locals: [], opening_loc: nil, closing_loc: nil) + BlockParametersNode.new(source, node_id, location, flags, parameters, locals, opening_loc, closing_loc) + end + + # Create a new BreakNode node. + def break_node(source: default_source, node_id: 0, location: default_location, flags: 0, arguments: nil, keyword_loc: location) + BreakNode.new(source, node_id, location, flags, arguments, keyword_loc) + end + + # Create a new CallAndWriteNode node. + def call_and_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, receiver: nil, call_operator_loc: nil, message_loc: nil, read_name: :"", write_name: :"", operator_loc: location, value: default_node(source, location)) + CallAndWriteNode.new(source, node_id, location, flags, receiver, call_operator_loc, message_loc, read_name, write_name, operator_loc, value) + end + + # Create a new CallNode node. + def call_node(source: default_source, node_id: 0, location: default_location, flags: 0, receiver: nil, call_operator_loc: nil, name: :"", message_loc: nil, opening_loc: nil, arguments: nil, closing_loc: nil, block: nil) + CallNode.new(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc, opening_loc, arguments, closing_loc, block) + end + + # Create a new CallOperatorWriteNode node. + def call_operator_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, receiver: nil, call_operator_loc: nil, message_loc: nil, read_name: :"", write_name: :"", binary_operator: :"", binary_operator_loc: location, value: default_node(source, location)) + CallOperatorWriteNode.new(source, node_id, location, flags, receiver, call_operator_loc, message_loc, read_name, write_name, binary_operator, binary_operator_loc, value) + end + + # Create a new CallOrWriteNode node. + def call_or_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, receiver: nil, call_operator_loc: nil, message_loc: nil, read_name: :"", write_name: :"", operator_loc: location, value: default_node(source, location)) + CallOrWriteNode.new(source, node_id, location, flags, receiver, call_operator_loc, message_loc, read_name, write_name, operator_loc, value) + end + + # Create a new CallTargetNode node. + def call_target_node(source: default_source, node_id: 0, location: default_location, flags: 0, receiver: default_node(source, location), call_operator_loc: location, name: :"", message_loc: location) + CallTargetNode.new(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc) + end + + # Create a new CapturePatternNode node. + def capture_pattern_node(source: default_source, node_id: 0, location: default_location, flags: 0, value: default_node(source, location), target: local_variable_target_node(source: source), operator_loc: location) + CapturePatternNode.new(source, node_id, location, flags, value, target, operator_loc) + end + + # Create a new CaseMatchNode node. + def case_match_node(source: default_source, node_id: 0, location: default_location, flags: 0, predicate: nil, conditions: [], else_clause: nil, case_keyword_loc: location, end_keyword_loc: location) + CaseMatchNode.new(source, node_id, location, flags, predicate, conditions, else_clause, case_keyword_loc, end_keyword_loc) + end + + # Create a new CaseNode node. + def case_node(source: default_source, node_id: 0, location: default_location, flags: 0, predicate: nil, conditions: [], else_clause: nil, case_keyword_loc: location, end_keyword_loc: location) + CaseNode.new(source, node_id, location, flags, predicate, conditions, else_clause, case_keyword_loc, end_keyword_loc) + end + + # Create a new ClassNode node. + def class_node(source: default_source, node_id: 0, location: default_location, flags: 0, locals: [], class_keyword_loc: location, constant_path: constant_read_node(source: source), inheritance_operator_loc: nil, superclass: nil, body: nil, end_keyword_loc: location, name: :"") + ClassNode.new(source, node_id, location, flags, locals, class_keyword_loc, constant_path, inheritance_operator_loc, superclass, body, end_keyword_loc, name) + end + + # Create a new ClassVariableAndWriteNode node. + def class_variable_and_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, operator_loc: location, value: default_node(source, location)) + ClassVariableAndWriteNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) + end + + # Create a new ClassVariableOperatorWriteNode node. + def class_variable_operator_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, binary_operator_loc: location, value: default_node(source, location), binary_operator: :"") + ClassVariableOperatorWriteNode.new(source, node_id, location, flags, name, name_loc, binary_operator_loc, value, binary_operator) + end + + # Create a new ClassVariableOrWriteNode node. + def class_variable_or_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, operator_loc: location, value: default_node(source, location)) + ClassVariableOrWriteNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) + end + + # Create a new ClassVariableReadNode node. + def class_variable_read_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"") + ClassVariableReadNode.new(source, node_id, location, flags, name) + end + + # Create a new ClassVariableTargetNode node. + def class_variable_target_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"") + ClassVariableTargetNode.new(source, node_id, location, flags, name) + end + + # Create a new ClassVariableWriteNode node. + def class_variable_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, value: default_node(source, location), operator_loc: location) + ClassVariableWriteNode.new(source, node_id, location, flags, name, name_loc, value, operator_loc) + end + + # Create a new ConstantAndWriteNode node. + def constant_and_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, operator_loc: location, value: default_node(source, location)) + ConstantAndWriteNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) + end + + # Create a new ConstantOperatorWriteNode node. + def constant_operator_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, binary_operator_loc: location, value: default_node(source, location), binary_operator: :"") + ConstantOperatorWriteNode.new(source, node_id, location, flags, name, name_loc, binary_operator_loc, value, binary_operator) + end + + # Create a new ConstantOrWriteNode node. + def constant_or_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, operator_loc: location, value: default_node(source, location)) + ConstantOrWriteNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) + end + + # Create a new ConstantPathAndWriteNode node. + def constant_path_and_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, target: constant_path_node(source: source), operator_loc: location, value: default_node(source, location)) + ConstantPathAndWriteNode.new(source, node_id, location, flags, target, operator_loc, value) + end + + # Create a new ConstantPathNode node. + def constant_path_node(source: default_source, node_id: 0, location: default_location, flags: 0, parent: nil, name: nil, delimiter_loc: location, name_loc: location) + ConstantPathNode.new(source, node_id, location, flags, parent, name, delimiter_loc, name_loc) + end + + # Create a new ConstantPathOperatorWriteNode node. + def constant_path_operator_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, target: constant_path_node(source: source), binary_operator_loc: location, value: default_node(source, location), binary_operator: :"") + ConstantPathOperatorWriteNode.new(source, node_id, location, flags, target, binary_operator_loc, value, binary_operator) + end + + # Create a new ConstantPathOrWriteNode node. + def constant_path_or_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, target: constant_path_node(source: source), operator_loc: location, value: default_node(source, location)) + ConstantPathOrWriteNode.new(source, node_id, location, flags, target, operator_loc, value) + end + + # Create a new ConstantPathTargetNode node. + def constant_path_target_node(source: default_source, node_id: 0, location: default_location, flags: 0, parent: nil, name: nil, delimiter_loc: location, name_loc: location) + ConstantPathTargetNode.new(source, node_id, location, flags, parent, name, delimiter_loc, name_loc) + end + + # Create a new ConstantPathWriteNode node. + def constant_path_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, target: constant_path_node(source: source), operator_loc: location, value: default_node(source, location)) + ConstantPathWriteNode.new(source, node_id, location, flags, target, operator_loc, value) + end + + # Create a new ConstantReadNode node. + def constant_read_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"") + ConstantReadNode.new(source, node_id, location, flags, name) + end + + # Create a new ConstantTargetNode node. + def constant_target_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"") + ConstantTargetNode.new(source, node_id, location, flags, name) + end + + # Create a new ConstantWriteNode node. + def constant_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, value: default_node(source, location), operator_loc: location) + ConstantWriteNode.new(source, node_id, location, flags, name, name_loc, value, operator_loc) + end + + # Create a new DefNode node. + def def_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, receiver: nil, parameters: nil, body: nil, locals: [], def_keyword_loc: location, operator_loc: nil, lparen_loc: nil, rparen_loc: nil, equal_loc: nil, end_keyword_loc: nil) + DefNode.new(source, node_id, location, flags, name, name_loc, receiver, parameters, body, locals, def_keyword_loc, operator_loc, lparen_loc, rparen_loc, equal_loc, end_keyword_loc) + end + + # Create a new DefinedNode node. + def defined_node(source: default_source, node_id: 0, location: default_location, flags: 0, lparen_loc: nil, value: default_node(source, location), rparen_loc: nil, keyword_loc: location) + DefinedNode.new(source, node_id, location, flags, lparen_loc, value, rparen_loc, keyword_loc) + end + + # Create a new ElseNode node. + def else_node(source: default_source, node_id: 0, location: default_location, flags: 0, else_keyword_loc: location, statements: nil, end_keyword_loc: nil) + ElseNode.new(source, node_id, location, flags, else_keyword_loc, statements, end_keyword_loc) + end + + # Create a new EmbeddedStatementsNode node. + def embedded_statements_node(source: default_source, node_id: 0, location: default_location, flags: 0, opening_loc: location, statements: nil, closing_loc: location) + EmbeddedStatementsNode.new(source, node_id, location, flags, opening_loc, statements, closing_loc) + end + + # Create a new EmbeddedVariableNode node. + def embedded_variable_node(source: default_source, node_id: 0, location: default_location, flags: 0, operator_loc: location, variable: instance_variable_read_node(source: source)) + EmbeddedVariableNode.new(source, node_id, location, flags, operator_loc, variable) + end + + # Create a new EnsureNode node. + def ensure_node(source: default_source, node_id: 0, location: default_location, flags: 0, ensure_keyword_loc: location, statements: nil, end_keyword_loc: location) + EnsureNode.new(source, node_id, location, flags, ensure_keyword_loc, statements, end_keyword_loc) + end + + # Create a new FalseNode node. + def false_node(source: default_source, node_id: 0, location: default_location, flags: 0) + FalseNode.new(source, node_id, location, flags) + end + + # Create a new FindPatternNode node. + def find_pattern_node(source: default_source, node_id: 0, location: default_location, flags: 0, constant: nil, left: splat_node(source: source), requireds: [], right: splat_node(source: source), opening_loc: nil, closing_loc: nil) + FindPatternNode.new(source, node_id, location, flags, constant, left, requireds, right, opening_loc, closing_loc) + end + + # Create a new FlipFlopNode node. + def flip_flop_node(source: default_source, node_id: 0, location: default_location, flags: 0, left: nil, right: nil, operator_loc: location) + FlipFlopNode.new(source, node_id, location, flags, left, right, operator_loc) + end + + # Create a new FloatNode node. + def float_node(source: default_source, node_id: 0, location: default_location, flags: 0, value: 0.0) + FloatNode.new(source, node_id, location, flags, value) + end + + # Create a new ForNode node. + def for_node(source: default_source, node_id: 0, location: default_location, flags: 0, index: local_variable_target_node(source: source), collection: default_node(source, location), statements: nil, for_keyword_loc: location, in_keyword_loc: location, do_keyword_loc: nil, end_keyword_loc: location) + ForNode.new(source, node_id, location, flags, index, collection, statements, for_keyword_loc, in_keyword_loc, do_keyword_loc, end_keyword_loc) + end + + # Create a new ForwardingArgumentsNode node. + def forwarding_arguments_node(source: default_source, node_id: 0, location: default_location, flags: 0) + ForwardingArgumentsNode.new(source, node_id, location, flags) + end + + # Create a new ForwardingParameterNode node. + def forwarding_parameter_node(source: default_source, node_id: 0, location: default_location, flags: 0) + ForwardingParameterNode.new(source, node_id, location, flags) + end + + # Create a new ForwardingSuperNode node. + def forwarding_super_node(source: default_source, node_id: 0, location: default_location, flags: 0, block: nil) + ForwardingSuperNode.new(source, node_id, location, flags, block) + end + + # Create a new GlobalVariableAndWriteNode node. + def global_variable_and_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, operator_loc: location, value: default_node(source, location)) + GlobalVariableAndWriteNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) + end + + # Create a new GlobalVariableOperatorWriteNode node. + def global_variable_operator_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, binary_operator_loc: location, value: default_node(source, location), binary_operator: :"") + GlobalVariableOperatorWriteNode.new(source, node_id, location, flags, name, name_loc, binary_operator_loc, value, binary_operator) + end + + # Create a new GlobalVariableOrWriteNode node. + def global_variable_or_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, operator_loc: location, value: default_node(source, location)) + GlobalVariableOrWriteNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) + end + + # Create a new GlobalVariableReadNode node. + def global_variable_read_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"") + GlobalVariableReadNode.new(source, node_id, location, flags, name) + end + + # Create a new GlobalVariableTargetNode node. + def global_variable_target_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"") + GlobalVariableTargetNode.new(source, node_id, location, flags, name) + end + + # Create a new GlobalVariableWriteNode node. + def global_variable_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, value: default_node(source, location), operator_loc: location) + GlobalVariableWriteNode.new(source, node_id, location, flags, name, name_loc, value, operator_loc) + end + + # Create a new HashNode node. + def hash_node(source: default_source, node_id: 0, location: default_location, flags: 0, opening_loc: location, elements: [], closing_loc: location) + HashNode.new(source, node_id, location, flags, opening_loc, elements, closing_loc) + end + + # Create a new HashPatternNode node. + def hash_pattern_node(source: default_source, node_id: 0, location: default_location, flags: 0, constant: nil, elements: [], rest: nil, opening_loc: nil, closing_loc: nil) + HashPatternNode.new(source, node_id, location, flags, constant, elements, rest, opening_loc, closing_loc) + end + + # Create a new IfNode node. + def if_node(source: default_source, node_id: 0, location: default_location, flags: 0, if_keyword_loc: nil, predicate: default_node(source, location), then_keyword_loc: nil, statements: nil, subsequent: nil, end_keyword_loc: nil) + IfNode.new(source, node_id, location, flags, if_keyword_loc, predicate, then_keyword_loc, statements, subsequent, end_keyword_loc) + end + + # Create a new ImaginaryNode node. + def imaginary_node(source: default_source, node_id: 0, location: default_location, flags: 0, numeric: float_node(source: source)) + ImaginaryNode.new(source, node_id, location, flags, numeric) + end + + # Create a new ImplicitNode node. + def implicit_node(source: default_source, node_id: 0, location: default_location, flags: 0, value: local_variable_read_node(source: source)) + ImplicitNode.new(source, node_id, location, flags, value) + end + + # Create a new ImplicitRestNode node. + def implicit_rest_node(source: default_source, node_id: 0, location: default_location, flags: 0) + ImplicitRestNode.new(source, node_id, location, flags) + end + + # Create a new InNode node. + def in_node(source: default_source, node_id: 0, location: default_location, flags: 0, pattern: default_node(source, location), statements: nil, in_loc: location, then_loc: nil) + InNode.new(source, node_id, location, flags, pattern, statements, in_loc, then_loc) + end + + # Create a new IndexAndWriteNode node. + def index_and_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, receiver: nil, call_operator_loc: nil, opening_loc: location, arguments: nil, closing_loc: location, block: nil, operator_loc: location, value: default_node(source, location)) + IndexAndWriteNode.new(source, node_id, location, flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, operator_loc, value) + end + + # Create a new IndexOperatorWriteNode node. + def index_operator_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, receiver: nil, call_operator_loc: nil, opening_loc: location, arguments: nil, closing_loc: location, block: nil, binary_operator: :"", binary_operator_loc: location, value: default_node(source, location)) + IndexOperatorWriteNode.new(source, node_id, location, flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, binary_operator, binary_operator_loc, value) + end + + # Create a new IndexOrWriteNode node. + def index_or_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, receiver: nil, call_operator_loc: nil, opening_loc: location, arguments: nil, closing_loc: location, block: nil, operator_loc: location, value: default_node(source, location)) + IndexOrWriteNode.new(source, node_id, location, flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, operator_loc, value) + end + + # Create a new IndexTargetNode node. + def index_target_node(source: default_source, node_id: 0, location: default_location, flags: 0, receiver: default_node(source, location), opening_loc: location, arguments: nil, closing_loc: location, block: nil) + IndexTargetNode.new(source, node_id, location, flags, receiver, opening_loc, arguments, closing_loc, block) + end + + # Create a new InstanceVariableAndWriteNode node. + def instance_variable_and_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, operator_loc: location, value: default_node(source, location)) + InstanceVariableAndWriteNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) + end + + # Create a new InstanceVariableOperatorWriteNode node. + def instance_variable_operator_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, binary_operator_loc: location, value: default_node(source, location), binary_operator: :"") + InstanceVariableOperatorWriteNode.new(source, node_id, location, flags, name, name_loc, binary_operator_loc, value, binary_operator) + end + + # Create a new InstanceVariableOrWriteNode node. + def instance_variable_or_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, operator_loc: location, value: default_node(source, location)) + InstanceVariableOrWriteNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) + end + + # Create a new InstanceVariableReadNode node. + def instance_variable_read_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"") + InstanceVariableReadNode.new(source, node_id, location, flags, name) + end + + # Create a new InstanceVariableTargetNode node. + def instance_variable_target_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"") + InstanceVariableTargetNode.new(source, node_id, location, flags, name) + end + + # Create a new InstanceVariableWriteNode node. + def instance_variable_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, value: default_node(source, location), operator_loc: location) + InstanceVariableWriteNode.new(source, node_id, location, flags, name, name_loc, value, operator_loc) + end + + # Create a new IntegerNode node. + def integer_node(source: default_source, node_id: 0, location: default_location, flags: 0, value: 0) + IntegerNode.new(source, node_id, location, flags, value) + end + + # Create a new InterpolatedMatchLastLineNode node. + def interpolated_match_last_line_node(source: default_source, node_id: 0, location: default_location, flags: 0, opening_loc: location, parts: [], closing_loc: location) + InterpolatedMatchLastLineNode.new(source, node_id, location, flags, opening_loc, parts, closing_loc) + end + + # Create a new InterpolatedRegularExpressionNode node. + def interpolated_regular_expression_node(source: default_source, node_id: 0, location: default_location, flags: 0, opening_loc: location, parts: [], closing_loc: location) + InterpolatedRegularExpressionNode.new(source, node_id, location, flags, opening_loc, parts, closing_loc) + end + + # Create a new InterpolatedStringNode node. + def interpolated_string_node(source: default_source, node_id: 0, location: default_location, flags: 0, opening_loc: nil, parts: [], closing_loc: nil) + InterpolatedStringNode.new(source, node_id, location, flags, opening_loc, parts, closing_loc) + end + + # Create a new InterpolatedSymbolNode node. + def interpolated_symbol_node(source: default_source, node_id: 0, location: default_location, flags: 0, opening_loc: nil, parts: [], closing_loc: nil) + InterpolatedSymbolNode.new(source, node_id, location, flags, opening_loc, parts, closing_loc) + end + + # Create a new InterpolatedXStringNode node. + def interpolated_x_string_node(source: default_source, node_id: 0, location: default_location, flags: 0, opening_loc: location, parts: [], closing_loc: location) + InterpolatedXStringNode.new(source, node_id, location, flags, opening_loc, parts, closing_loc) + end + + # Create a new ItLocalVariableReadNode node. + def it_local_variable_read_node(source: default_source, node_id: 0, location: default_location, flags: 0) + ItLocalVariableReadNode.new(source, node_id, location, flags) + end + + # Create a new ItParametersNode node. + def it_parameters_node(source: default_source, node_id: 0, location: default_location, flags: 0) + ItParametersNode.new(source, node_id, location, flags) + end + + # Create a new KeywordHashNode node. + def keyword_hash_node(source: default_source, node_id: 0, location: default_location, flags: 0, elements: []) + KeywordHashNode.new(source, node_id, location, flags, elements) + end + + # Create a new KeywordRestParameterNode node. + def keyword_rest_parameter_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: nil, name_loc: nil, operator_loc: location) + KeywordRestParameterNode.new(source, node_id, location, flags, name, name_loc, operator_loc) + end + + # Create a new LambdaNode node. + def lambda_node(source: default_source, node_id: 0, location: default_location, flags: 0, locals: [], operator_loc: location, opening_loc: location, closing_loc: location, parameters: nil, body: nil) + LambdaNode.new(source, node_id, location, flags, locals, operator_loc, opening_loc, closing_loc, parameters, body) + end + + # Create a new LocalVariableAndWriteNode node. + def local_variable_and_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name_loc: location, operator_loc: location, value: default_node(source, location), name: :"", depth: 0) + LocalVariableAndWriteNode.new(source, node_id, location, flags, name_loc, operator_loc, value, name, depth) + end + + # Create a new LocalVariableOperatorWriteNode node. + def local_variable_operator_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name_loc: location, binary_operator_loc: location, value: default_node(source, location), name: :"", binary_operator: :"", depth: 0) + LocalVariableOperatorWriteNode.new(source, node_id, location, flags, name_loc, binary_operator_loc, value, name, binary_operator, depth) + end + + # Create a new LocalVariableOrWriteNode node. + def local_variable_or_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name_loc: location, operator_loc: location, value: default_node(source, location), name: :"", depth: 0) + LocalVariableOrWriteNode.new(source, node_id, location, flags, name_loc, operator_loc, value, name, depth) + end + + # Create a new LocalVariableReadNode node. + def local_variable_read_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", depth: 0) + LocalVariableReadNode.new(source, node_id, location, flags, name, depth) + end + + # Create a new LocalVariableTargetNode node. + def local_variable_target_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", depth: 0) + LocalVariableTargetNode.new(source, node_id, location, flags, name, depth) + end + + # Create a new LocalVariableWriteNode node. + def local_variable_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", depth: 0, name_loc: location, value: default_node(source, location), operator_loc: location) + LocalVariableWriteNode.new(source, node_id, location, flags, name, depth, name_loc, value, operator_loc) + end + + # Create a new MatchLastLineNode node. + def match_last_line_node(source: default_source, node_id: 0, location: default_location, flags: 0, opening_loc: location, content_loc: location, closing_loc: location, unescaped: "") + MatchLastLineNode.new(source, node_id, location, flags, opening_loc, content_loc, closing_loc, unescaped) + end + + # Create a new MatchPredicateNode node. + def match_predicate_node(source: default_source, node_id: 0, location: default_location, flags: 0, value: default_node(source, location), pattern: default_node(source, location), operator_loc: location) + MatchPredicateNode.new(source, node_id, location, flags, value, pattern, operator_loc) + end + + # Create a new MatchRequiredNode node. + def match_required_node(source: default_source, node_id: 0, location: default_location, flags: 0, value: default_node(source, location), pattern: default_node(source, location), operator_loc: location) + MatchRequiredNode.new(source, node_id, location, flags, value, pattern, operator_loc) + end + + # Create a new MatchWriteNode node. + def match_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, call: call_node(source: source), targets: []) + MatchWriteNode.new(source, node_id, location, flags, call, targets) + end + + # Create a new MissingNode node. + def missing_node(source: default_source, node_id: 0, location: default_location, flags: 0) + MissingNode.new(source, node_id, location, flags) + end + + # Create a new ModuleNode node. + def module_node(source: default_source, node_id: 0, location: default_location, flags: 0, locals: [], module_keyword_loc: location, constant_path: constant_read_node(source: source), body: nil, end_keyword_loc: location, name: :"") + ModuleNode.new(source, node_id, location, flags, locals, module_keyword_loc, constant_path, body, end_keyword_loc, name) + end + + # Create a new MultiTargetNode node. + def multi_target_node(source: default_source, node_id: 0, location: default_location, flags: 0, lefts: [], rest: nil, rights: [], lparen_loc: nil, rparen_loc: nil) + MultiTargetNode.new(source, node_id, location, flags, lefts, rest, rights, lparen_loc, rparen_loc) + end + + # Create a new MultiWriteNode node. + def multi_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, lefts: [], rest: nil, rights: [], lparen_loc: nil, rparen_loc: nil, operator_loc: location, value: default_node(source, location)) + MultiWriteNode.new(source, node_id, location, flags, lefts, rest, rights, lparen_loc, rparen_loc, operator_loc, value) + end + + # Create a new NextNode node. + def next_node(source: default_source, node_id: 0, location: default_location, flags: 0, arguments: nil, keyword_loc: location) + NextNode.new(source, node_id, location, flags, arguments, keyword_loc) + end + + # Create a new NilNode node. + def nil_node(source: default_source, node_id: 0, location: default_location, flags: 0) + NilNode.new(source, node_id, location, flags) + end + + # Create a new NoKeywordsParameterNode node. + def no_keywords_parameter_node(source: default_source, node_id: 0, location: default_location, flags: 0, operator_loc: location, keyword_loc: location) + NoKeywordsParameterNode.new(source, node_id, location, flags, operator_loc, keyword_loc) + end + + # Create a new NumberedParametersNode node. + def numbered_parameters_node(source: default_source, node_id: 0, location: default_location, flags: 0, maximum: 0) + NumberedParametersNode.new(source, node_id, location, flags, maximum) + end + + # Create a new NumberedReferenceReadNode node. + def numbered_reference_read_node(source: default_source, node_id: 0, location: default_location, flags: 0, number: 0) + NumberedReferenceReadNode.new(source, node_id, location, flags, number) + end + + # Create a new OptionalKeywordParameterNode node. + def optional_keyword_parameter_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, value: default_node(source, location)) + OptionalKeywordParameterNode.new(source, node_id, location, flags, name, name_loc, value) + end + + # Create a new OptionalParameterNode node. + def optional_parameter_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, operator_loc: location, value: default_node(source, location)) + OptionalParameterNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) + end + + # Create a new OrNode node. + def or_node(source: default_source, node_id: 0, location: default_location, flags: 0, left: default_node(source, location), right: default_node(source, location), operator_loc: location) + OrNode.new(source, node_id, location, flags, left, right, operator_loc) + end + + # Create a new ParametersNode node. + def parameters_node(source: default_source, node_id: 0, location: default_location, flags: 0, requireds: [], optionals: [], rest: nil, posts: [], keywords: [], keyword_rest: nil, block: nil) + ParametersNode.new(source, node_id, location, flags, requireds, optionals, rest, posts, keywords, keyword_rest, block) + end + + # Create a new ParenthesesNode node. + def parentheses_node(source: default_source, node_id: 0, location: default_location, flags: 0, body: nil, opening_loc: location, closing_loc: location) + ParenthesesNode.new(source, node_id, location, flags, body, opening_loc, closing_loc) + end + + # Create a new PinnedExpressionNode node. + def pinned_expression_node(source: default_source, node_id: 0, location: default_location, flags: 0, expression: default_node(source, location), operator_loc: location, lparen_loc: location, rparen_loc: location) + PinnedExpressionNode.new(source, node_id, location, flags, expression, operator_loc, lparen_loc, rparen_loc) + end + + # Create a new PinnedVariableNode node. + def pinned_variable_node(source: default_source, node_id: 0, location: default_location, flags: 0, variable: local_variable_read_node(source: source), operator_loc: location) + PinnedVariableNode.new(source, node_id, location, flags, variable, operator_loc) + end + + # Create a new PostExecutionNode node. + def post_execution_node(source: default_source, node_id: 0, location: default_location, flags: 0, statements: nil, keyword_loc: location, opening_loc: location, closing_loc: location) + PostExecutionNode.new(source, node_id, location, flags, statements, keyword_loc, opening_loc, closing_loc) + end + + # Create a new PreExecutionNode node. + def pre_execution_node(source: default_source, node_id: 0, location: default_location, flags: 0, statements: nil, keyword_loc: location, opening_loc: location, closing_loc: location) + PreExecutionNode.new(source, node_id, location, flags, statements, keyword_loc, opening_loc, closing_loc) + end + + # Create a new ProgramNode node. + def program_node(source: default_source, node_id: 0, location: default_location, flags: 0, locals: [], statements: statements_node(source: source)) + ProgramNode.new(source, node_id, location, flags, locals, statements) + end + + # Create a new RangeNode node. + def range_node(source: default_source, node_id: 0, location: default_location, flags: 0, left: nil, right: nil, operator_loc: location) + RangeNode.new(source, node_id, location, flags, left, right, operator_loc) + end + + # Create a new RationalNode node. + def rational_node(source: default_source, node_id: 0, location: default_location, flags: 0, numerator: 0, denominator: 0) + RationalNode.new(source, node_id, location, flags, numerator, denominator) + end + + # Create a new RedoNode node. + def redo_node(source: default_source, node_id: 0, location: default_location, flags: 0) + RedoNode.new(source, node_id, location, flags) + end + + # Create a new RegularExpressionNode node. + def regular_expression_node(source: default_source, node_id: 0, location: default_location, flags: 0, opening_loc: location, content_loc: location, closing_loc: location, unescaped: "") + RegularExpressionNode.new(source, node_id, location, flags, opening_loc, content_loc, closing_loc, unescaped) + end + + # Create a new RequiredKeywordParameterNode node. + def required_keyword_parameter_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location) + RequiredKeywordParameterNode.new(source, node_id, location, flags, name, name_loc) + end + + # Create a new RequiredParameterNode node. + def required_parameter_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"") + RequiredParameterNode.new(source, node_id, location, flags, name) + end + + # Create a new RescueModifierNode node. + def rescue_modifier_node(source: default_source, node_id: 0, location: default_location, flags: 0, expression: default_node(source, location), keyword_loc: location, rescue_expression: default_node(source, location)) + RescueModifierNode.new(source, node_id, location, flags, expression, keyword_loc, rescue_expression) + end + + # Create a new RescueNode node. + def rescue_node(source: default_source, node_id: 0, location: default_location, flags: 0, keyword_loc: location, exceptions: [], operator_loc: nil, reference: nil, then_keyword_loc: nil, statements: nil, subsequent: nil) + RescueNode.new(source, node_id, location, flags, keyword_loc, exceptions, operator_loc, reference, then_keyword_loc, statements, subsequent) + end + + # Create a new RestParameterNode node. + def rest_parameter_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: nil, name_loc: nil, operator_loc: location) + RestParameterNode.new(source, node_id, location, flags, name, name_loc, operator_loc) + end + + # Create a new RetryNode node. + def retry_node(source: default_source, node_id: 0, location: default_location, flags: 0) + RetryNode.new(source, node_id, location, flags) + end + + # Create a new ReturnNode node. + def return_node(source: default_source, node_id: 0, location: default_location, flags: 0, keyword_loc: location, arguments: nil) + ReturnNode.new(source, node_id, location, flags, keyword_loc, arguments) + end + + # Create a new SelfNode node. + def self_node(source: default_source, node_id: 0, location: default_location, flags: 0) + SelfNode.new(source, node_id, location, flags) + end + + # Create a new ShareableConstantNode node. + def shareable_constant_node(source: default_source, node_id: 0, location: default_location, flags: 0, write: constant_write_node(source: source)) + ShareableConstantNode.new(source, node_id, location, flags, write) + end + + # Create a new SingletonClassNode node. + def singleton_class_node(source: default_source, node_id: 0, location: default_location, flags: 0, locals: [], class_keyword_loc: location, operator_loc: location, expression: default_node(source, location), body: nil, end_keyword_loc: location) + SingletonClassNode.new(source, node_id, location, flags, locals, class_keyword_loc, operator_loc, expression, body, end_keyword_loc) + end + + # Create a new SourceEncodingNode node. + def source_encoding_node(source: default_source, node_id: 0, location: default_location, flags: 0) + SourceEncodingNode.new(source, node_id, location, flags) + end + + # Create a new SourceFileNode node. + def source_file_node(source: default_source, node_id: 0, location: default_location, flags: 0, filepath: "") + SourceFileNode.new(source, node_id, location, flags, filepath) + end + + # Create a new SourceLineNode node. + def source_line_node(source: default_source, node_id: 0, location: default_location, flags: 0) + SourceLineNode.new(source, node_id, location, flags) + end + + # Create a new SplatNode node. + def splat_node(source: default_source, node_id: 0, location: default_location, flags: 0, operator_loc: location, expression: nil) + SplatNode.new(source, node_id, location, flags, operator_loc, expression) + end + + # Create a new StatementsNode node. + def statements_node(source: default_source, node_id: 0, location: default_location, flags: 0, body: []) + StatementsNode.new(source, node_id, location, flags, body) + end + + # Create a new StringNode node. + def string_node(source: default_source, node_id: 0, location: default_location, flags: 0, opening_loc: nil, content_loc: location, closing_loc: nil, unescaped: "") + StringNode.new(source, node_id, location, flags, opening_loc, content_loc, closing_loc, unescaped) + end + + # Create a new SuperNode node. + def super_node(source: default_source, node_id: 0, location: default_location, flags: 0, keyword_loc: location, lparen_loc: nil, arguments: nil, rparen_loc: nil, block: nil) + SuperNode.new(source, node_id, location, flags, keyword_loc, lparen_loc, arguments, rparen_loc, block) + end + + # Create a new SymbolNode node. + def symbol_node(source: default_source, node_id: 0, location: default_location, flags: 0, opening_loc: nil, value_loc: nil, closing_loc: nil, unescaped: "") + SymbolNode.new(source, node_id, location, flags, opening_loc, value_loc, closing_loc, unescaped) + end + + # Create a new TrueNode node. + def true_node(source: default_source, node_id: 0, location: default_location, flags: 0) + TrueNode.new(source, node_id, location, flags) + end + + # Create a new UndefNode node. + def undef_node(source: default_source, node_id: 0, location: default_location, flags: 0, names: [], keyword_loc: location) + UndefNode.new(source, node_id, location, flags, names, keyword_loc) + end + + # Create a new UnlessNode node. + def unless_node(source: default_source, node_id: 0, location: default_location, flags: 0, keyword_loc: location, predicate: default_node(source, location), then_keyword_loc: nil, statements: nil, else_clause: nil, end_keyword_loc: nil) + UnlessNode.new(source, node_id, location, flags, keyword_loc, predicate, then_keyword_loc, statements, else_clause, end_keyword_loc) + end + + # Create a new UntilNode node. + def until_node(source: default_source, node_id: 0, location: default_location, flags: 0, keyword_loc: location, do_keyword_loc: nil, closing_loc: nil, predicate: default_node(source, location), statements: nil) + UntilNode.new(source, node_id, location, flags, keyword_loc, do_keyword_loc, closing_loc, predicate, statements) + end + + # Create a new WhenNode node. + def when_node(source: default_source, node_id: 0, location: default_location, flags: 0, keyword_loc: location, conditions: [], then_keyword_loc: nil, statements: nil) + WhenNode.new(source, node_id, location, flags, keyword_loc, conditions, then_keyword_loc, statements) + end + + # Create a new WhileNode node. + def while_node(source: default_source, node_id: 0, location: default_location, flags: 0, keyword_loc: location, do_keyword_loc: nil, closing_loc: nil, predicate: default_node(source, location), statements: nil) + WhileNode.new(source, node_id, location, flags, keyword_loc, do_keyword_loc, closing_loc, predicate, statements) + end + + # Create a new XStringNode node. + def x_string_node(source: default_source, node_id: 0, location: default_location, flags: 0, opening_loc: location, content_loc: location, closing_loc: location, unescaped: "") + XStringNode.new(source, node_id, location, flags, opening_loc, content_loc, closing_loc, unescaped) + end + + # Create a new YieldNode node. + def yield_node(source: default_source, node_id: 0, location: default_location, flags: 0, keyword_loc: location, lparen_loc: nil, arguments: nil, rparen_loc: nil) + YieldNode.new(source, node_id, location, flags, keyword_loc, lparen_loc, arguments, rparen_loc) + end + + # Retrieve the value of one of the ArgumentsNodeFlags flags. + def arguments_node_flag(name) + case name + when :contains_forwarding then ArgumentsNodeFlags::CONTAINS_FORWARDING + when :contains_keywords then ArgumentsNodeFlags::CONTAINS_KEYWORDS + when :contains_keyword_splat then ArgumentsNodeFlags::CONTAINS_KEYWORD_SPLAT + when :contains_splat then ArgumentsNodeFlags::CONTAINS_SPLAT + when :contains_multiple_splats then ArgumentsNodeFlags::CONTAINS_MULTIPLE_SPLATS + else Kernel.raise ArgumentError, "invalid ArgumentsNodeFlags flag: #{name.inspect}" + end + end + + # Retrieve the value of one of the ArrayNodeFlags flags. + def array_node_flag(name) + case name + when :contains_splat then ArrayNodeFlags::CONTAINS_SPLAT + else Kernel.raise ArgumentError, "invalid ArrayNodeFlags flag: #{name.inspect}" + end + end + + # Retrieve the value of one of the CallNodeFlags flags. + def call_node_flag(name) + case name + when :safe_navigation then CallNodeFlags::SAFE_NAVIGATION + when :variable_call then CallNodeFlags::VARIABLE_CALL + when :attribute_write then CallNodeFlags::ATTRIBUTE_WRITE + when :ignore_visibility then CallNodeFlags::IGNORE_VISIBILITY + else Kernel.raise ArgumentError, "invalid CallNodeFlags flag: #{name.inspect}" + end + end + + # Retrieve the value of one of the EncodingFlags flags. + def encoding_flag(name) + case name + when :forced_utf8_encoding then EncodingFlags::FORCED_UTF8_ENCODING + when :forced_binary_encoding then EncodingFlags::FORCED_BINARY_ENCODING + else Kernel.raise ArgumentError, "invalid EncodingFlags flag: #{name.inspect}" + end + end + + # Retrieve the value of one of the IntegerBaseFlags flags. + def integer_base_flag(name) + case name + when :binary then IntegerBaseFlags::BINARY + when :decimal then IntegerBaseFlags::DECIMAL + when :octal then IntegerBaseFlags::OCTAL + when :hexadecimal then IntegerBaseFlags::HEXADECIMAL + else Kernel.raise ArgumentError, "invalid IntegerBaseFlags flag: #{name.inspect}" + end + end + + # Retrieve the value of one of the InterpolatedStringNodeFlags flags. + def interpolated_string_node_flag(name) + case name + when :frozen then InterpolatedStringNodeFlags::FROZEN + when :mutable then InterpolatedStringNodeFlags::MUTABLE + else Kernel.raise ArgumentError, "invalid InterpolatedStringNodeFlags flag: #{name.inspect}" + end + end + + # Retrieve the value of one of the KeywordHashNodeFlags flags. + def keyword_hash_node_flag(name) + case name + when :symbol_keys then KeywordHashNodeFlags::SYMBOL_KEYS + else Kernel.raise ArgumentError, "invalid KeywordHashNodeFlags flag: #{name.inspect}" + end + end + + # Retrieve the value of one of the LoopFlags flags. + def loop_flag(name) + case name + when :begin_modifier then LoopFlags::BEGIN_MODIFIER + else Kernel.raise ArgumentError, "invalid LoopFlags flag: #{name.inspect}" + end + end + + # Retrieve the value of one of the ParameterFlags flags. + def parameter_flag(name) + case name + when :repeated_parameter then ParameterFlags::REPEATED_PARAMETER + else Kernel.raise ArgumentError, "invalid ParameterFlags flag: #{name.inspect}" + end + end + + # Retrieve the value of one of the ParenthesesNodeFlags flags. + def parentheses_node_flag(name) + case name + when :multiple_statements then ParenthesesNodeFlags::MULTIPLE_STATEMENTS + else Kernel.raise ArgumentError, "invalid ParenthesesNodeFlags flag: #{name.inspect}" + end + end + + # Retrieve the value of one of the RangeFlags flags. + def range_flag(name) + case name + when :exclude_end then RangeFlags::EXCLUDE_END + else Kernel.raise ArgumentError, "invalid RangeFlags flag: #{name.inspect}" + end + end + + # Retrieve the value of one of the RegularExpressionFlags flags. + def regular_expression_flag(name) + case name + when :ignore_case then RegularExpressionFlags::IGNORE_CASE + when :extended then RegularExpressionFlags::EXTENDED + when :multi_line then RegularExpressionFlags::MULTI_LINE + when :once then RegularExpressionFlags::ONCE + when :euc_jp then RegularExpressionFlags::EUC_JP + when :ascii_8bit then RegularExpressionFlags::ASCII_8BIT + when :windows_31j then RegularExpressionFlags::WINDOWS_31J + when :utf_8 then RegularExpressionFlags::UTF_8 + when :forced_utf8_encoding then RegularExpressionFlags::FORCED_UTF8_ENCODING + when :forced_binary_encoding then RegularExpressionFlags::FORCED_BINARY_ENCODING + when :forced_us_ascii_encoding then RegularExpressionFlags::FORCED_US_ASCII_ENCODING + else Kernel.raise ArgumentError, "invalid RegularExpressionFlags flag: #{name.inspect}" + end + end + + # Retrieve the value of one of the ShareableConstantNodeFlags flags. + def shareable_constant_node_flag(name) + case name + when :literal then ShareableConstantNodeFlags::LITERAL + when :experimental_everything then ShareableConstantNodeFlags::EXPERIMENTAL_EVERYTHING + when :experimental_copy then ShareableConstantNodeFlags::EXPERIMENTAL_COPY + else Kernel.raise ArgumentError, "invalid ShareableConstantNodeFlags flag: #{name.inspect}" + end + end + + # Retrieve the value of one of the StringFlags flags. + def string_flag(name) + case name + when :forced_utf8_encoding then StringFlags::FORCED_UTF8_ENCODING + when :forced_binary_encoding then StringFlags::FORCED_BINARY_ENCODING + when :frozen then StringFlags::FROZEN + when :mutable then StringFlags::MUTABLE + else Kernel.raise ArgumentError, "invalid StringFlags flag: #{name.inspect}" + end + end + + # Retrieve the value of one of the SymbolFlags flags. + def symbol_flag(name) + case name + when :forced_utf8_encoding then SymbolFlags::FORCED_UTF8_ENCODING + when :forced_binary_encoding then SymbolFlags::FORCED_BINARY_ENCODING + when :forced_us_ascii_encoding then SymbolFlags::FORCED_US_ASCII_ENCODING + else Kernel.raise ArgumentError, "invalid SymbolFlags flag: #{name.inspect}" + end + end + + private + + # The default source object that gets attached to nodes and locations if no + # source is specified. + def default_source + Source.for("") + end + + # The default location object that gets attached to nodes if no location is + # specified, which uses the given source. + def default_location + Location.new(default_source, 0, 0) + end + + # The default node that gets attached to nodes if no node is specified for a + # required node field. + def default_node(source, location) + MissingNode.new(source, -1, location, 0) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/ffi.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/ffi.rb new file mode 100644 index 00000000..35b91e41 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/ffi.rb @@ -0,0 +1,560 @@ +# frozen_string_literal: true +# typed: ignore + +# This file is responsible for mirroring the API provided by the C extension by +# using FFI to call into the shared library. + +require "rbconfig" +require "ffi" + +module Prism + module LibRubyParser # :nodoc: + extend FFI::Library + + # Define the library that we will be pulling functions from. Note that this + # must align with the build shared library from make/rake. + libprism_in_build = File.expand_path("../../build/libprism.#{RbConfig::CONFIG["SOEXT"]}", __dir__) + libprism_in_libdir = "#{RbConfig::CONFIG["libdir"]}/prism/libprism.#{RbConfig::CONFIG["SOEXT"]}" + + if File.exist?(libprism_in_build) + INCLUDE_DIR = File.expand_path("../../include", __dir__) + ffi_lib libprism_in_build + else + INCLUDE_DIR = "#{RbConfig::CONFIG["libdir"]}/prism/include" + ffi_lib libprism_in_libdir + end + + # Convert a native C type declaration into a symbol that FFI understands. + # For example: + # + # const char * -> :pointer + # bool -> :bool + # size_t -> :size_t + # void -> :void + # + def self.resolve_type(type, callbacks) + type = type.strip + + if !type.end_with?("*") + type.delete_prefix("const ").to_sym + else + type = type.delete_suffix("*").rstrip + callbacks.include?(type.to_sym) ? type.to_sym : :pointer + end + end + + # Read through the given header file and find the declaration of each of the + # given functions. For each one, define a function with the same name and + # signature as the C function. + def self.load_exported_functions_from(header, *functions, callbacks) + File.foreach("#{INCLUDE_DIR}/#{header}") do |line| + # We only want to attempt to load exported functions. + next unless line.start_with?("PRISM_EXPORTED_FUNCTION ") + + # We only want to load the functions that we are interested in. + next unless functions.any? { |function| line.include?(function) } + + # Parse the function declaration. + unless /^PRISM_EXPORTED_FUNCTION (?.+) (?\w+)\((?.+)\);$/ =~ line + raise "Could not parse #{line}" + end + + # Delete the function from the list of functions we are looking for to + # mark it as having been found. + functions.delete(name) + + # Split up the argument types into an array, ensure we handle the case + # where there are no arguments (by explicit void). + arg_types = arg_types.split(",").map(&:strip) + arg_types = [] if arg_types == %w[void] + + # Resolve the type of the argument by dropping the name of the argument + # first if it is present. + arg_types.map! { |type| resolve_type(type.sub(/\w+$/, ""), callbacks) } + + # Attach the function using the FFI library. + attach_function name, arg_types, resolve_type(return_type, []) + end + + # If we didn't find all of the functions, raise an error. + raise "Could not find functions #{functions.inspect}" unless functions.empty? + end + + callback :pm_parse_stream_fgets_t, [:pointer, :int, :pointer], :pointer + enum :pm_string_init_result_t, %i[PM_STRING_INIT_SUCCESS PM_STRING_INIT_ERROR_GENERIC PM_STRING_INIT_ERROR_DIRECTORY] + enum :pm_string_query_t, [:PM_STRING_QUERY_ERROR, -1, :PM_STRING_QUERY_FALSE, :PM_STRING_QUERY_TRUE] + + load_exported_functions_from( + "prism.h", + "pm_version", + "pm_serialize_parse", + "pm_serialize_parse_stream", + "pm_serialize_parse_comments", + "pm_serialize_lex", + "pm_serialize_parse_lex", + "pm_parse_success_p", + "pm_string_query_local", + "pm_string_query_constant", + "pm_string_query_method_name", + [:pm_parse_stream_fgets_t] + ) + + load_exported_functions_from( + "prism/util/pm_buffer.h", + "pm_buffer_sizeof", + "pm_buffer_init", + "pm_buffer_value", + "pm_buffer_length", + "pm_buffer_free", + [] + ) + + load_exported_functions_from( + "prism/util/pm_string.h", + "pm_string_mapped_init", + "pm_string_free", + "pm_string_source", + "pm_string_length", + "pm_string_sizeof", + [] + ) + + # This object represents a pm_buffer_t. We only use it as an opaque pointer, + # so it doesn't need to know the fields of pm_buffer_t. + class PrismBuffer # :nodoc: + SIZEOF = LibRubyParser.pm_buffer_sizeof + + attr_reader :pointer + + def initialize(pointer) + @pointer = pointer + end + + def value + LibRubyParser.pm_buffer_value(pointer) + end + + def length + LibRubyParser.pm_buffer_length(pointer) + end + + def read + value.read_string(length) + end + + # Initialize a new buffer and yield it to the block. The buffer will be + # automatically freed when the block returns. + def self.with + FFI::MemoryPointer.new(SIZEOF) do |pointer| + raise unless LibRubyParser.pm_buffer_init(pointer) + return yield new(pointer) + ensure + LibRubyParser.pm_buffer_free(pointer) + end + end + end + + # This object represents a pm_string_t. We only use it as an opaque pointer, + # so it doesn't have to be an FFI::Struct. + class PrismString # :nodoc: + SIZEOF = LibRubyParser.pm_string_sizeof + + attr_reader :pointer, :length + + def initialize(pointer, length, from_string) + @pointer = pointer + @length = length + @from_string = from_string + end + + def read + raise "should use the original String instead" if @from_string + @pointer.read_string(@length) + end + + # Yields a pm_string_t pointer to the given block. + def self.with_string(string) + raise TypeError unless string.is_a?(String) + + length = string.bytesize + # + 1 to never get an address of 0, which pm_parser_init() asserts + FFI::MemoryPointer.new(:char, length + 1, false) do |pointer| + pointer.write_string(string) + # since we have the extra byte we might as well \0-terminate + pointer.put_char(length, 0) + return yield new(pointer, length, true) + end + end + + # Yields a pm_string_t pointer to the given block. + def self.with_file(filepath) + raise TypeError unless filepath.is_a?(String) + + # On Windows and Mac, it's expected that filepaths will be encoded in + # UTF-8. If they are not, we need to convert them to UTF-8 before + # passing them into pm_string_mapped_init. + if RbConfig::CONFIG["host_os"].match?(/bccwin|cygwin|djgpp|mingw|mswin|wince|darwin/i) && + (encoding = filepath.encoding) != Encoding::ASCII_8BIT && encoding != Encoding::UTF_8 + filepath = filepath.encode(Encoding::UTF_8) + end + + FFI::MemoryPointer.new(SIZEOF) do |pm_string| + case (result = LibRubyParser.pm_string_mapped_init(pm_string, filepath)) + when :PM_STRING_INIT_SUCCESS + pointer = LibRubyParser.pm_string_source(pm_string) + length = LibRubyParser.pm_string_length(pm_string) + return yield new(pointer, length, false) + when :PM_STRING_INIT_ERROR_GENERIC + raise SystemCallError.new(filepath, FFI.errno) + when :PM_STRING_INIT_ERROR_DIRECTORY + raise Errno::EISDIR.new(filepath) + else + raise "Unknown error initializing pm_string_t: #{result.inspect}" + end + ensure + LibRubyParser.pm_string_free(pm_string) + end + end + end + end + + # Mark the LibRubyParser module as private as it should only be called through + # the prism module. + private_constant :LibRubyParser + + # The version constant is set by reading the result of calling pm_version. + VERSION = LibRubyParser.pm_version.read_string + + class << self + # Mirror the Prism.dump API by using the serialization API. + def dump(source, **options) + LibRubyParser::PrismString.with_string(source) { |string| dump_common(string, options) } + end + + # Mirror the Prism.dump_file API by using the serialization API. + def dump_file(filepath, **options) + options[:filepath] = filepath + LibRubyParser::PrismString.with_file(filepath) { |string| dump_common(string, options) } + end + + # Mirror the Prism.lex API by using the serialization API. + def lex(code, **options) + LibRubyParser::PrismString.with_string(code) { |string| lex_common(string, code, options) } + end + + # Mirror the Prism.lex_file API by using the serialization API. + def lex_file(filepath, **options) + options[:filepath] = filepath + LibRubyParser::PrismString.with_file(filepath) { |string| lex_common(string, string.read, options) } + end + + # Mirror the Prism.parse API by using the serialization API. + def parse(code, **options) + LibRubyParser::PrismString.with_string(code) { |string| parse_common(string, code, options) } + end + + # Mirror the Prism.parse_file API by using the serialization API. This uses + # native strings instead of Ruby strings because it allows us to use mmap + # when it is available. + def parse_file(filepath, **options) + options[:filepath] = filepath + LibRubyParser::PrismString.with_file(filepath) { |string| parse_common(string, string.read, options) } + end + + # Mirror the Prism.parse_stream API by using the serialization API. + def parse_stream(stream, **options) + LibRubyParser::PrismBuffer.with do |buffer| + source = +"" + callback = -> (string, size, _) { + raise "Expected size to be >= 0, got: #{size}" if size <= 0 + + if !(line = stream.gets(size - 1)).nil? + source << line + string.write_string("#{line}\x00", line.bytesize + 1) + end + } + + # In the pm_serialize_parse_stream function it accepts a pointer to the + # IO object as a void* and then passes it through to the callback as the + # third argument, but it never touches it itself. As such, since we have + # access to the IO object already through the closure of the lambda, we + # can pass a null pointer here and not worry. + LibRubyParser.pm_serialize_parse_stream(buffer.pointer, nil, callback, dump_options(options)) + Prism.load(source, buffer.read, options.fetch(:freeze, false)) + end + end + + # Mirror the Prism.parse_comments API by using the serialization API. + def parse_comments(code, **options) + LibRubyParser::PrismString.with_string(code) { |string| parse_comments_common(string, code, options) } + end + + # Mirror the Prism.parse_file_comments API by using the serialization + # API. This uses native strings instead of Ruby strings because it allows us + # to use mmap when it is available. + def parse_file_comments(filepath, **options) + options[:filepath] = filepath + LibRubyParser::PrismString.with_file(filepath) { |string| parse_comments_common(string, string.read, options) } + end + + # Mirror the Prism.parse_lex API by using the serialization API. + def parse_lex(code, **options) + LibRubyParser::PrismString.with_string(code) { |string| parse_lex_common(string, code, options) } + end + + # Mirror the Prism.parse_lex_file API by using the serialization API. + def parse_lex_file(filepath, **options) + options[:filepath] = filepath + LibRubyParser::PrismString.with_file(filepath) { |string| parse_lex_common(string, string.read, options) } + end + + # Mirror the Prism.parse_success? API by using the serialization API. + def parse_success?(code, **options) + LibRubyParser::PrismString.with_string(code) { |string| parse_file_success_common(string, options) } + end + + # Mirror the Prism.parse_failure? API by using the serialization API. + def parse_failure?(code, **options) + !parse_success?(code, **options) + end + + # Mirror the Prism.parse_file_success? API by using the serialization API. + def parse_file_success?(filepath, **options) + options[:filepath] = filepath + LibRubyParser::PrismString.with_file(filepath) { |string| parse_file_success_common(string, options) } + end + + # Mirror the Prism.parse_file_failure? API by using the serialization API. + def parse_file_failure?(filepath, **options) + !parse_file_success?(filepath, **options) + end + + # Mirror the Prism.profile API by using the serialization API. + def profile(source, **options) + LibRubyParser::PrismString.with_string(source) do |string| + LibRubyParser::PrismBuffer.with do |buffer| + LibRubyParser.pm_serialize_parse(buffer.pointer, string.pointer, string.length, dump_options(options)) + nil + end + end + end + + # Mirror the Prism.profile_file API by using the serialization API. + def profile_file(filepath, **options) + LibRubyParser::PrismString.with_file(filepath) do |string| + LibRubyParser::PrismBuffer.with do |buffer| + options[:filepath] = filepath + LibRubyParser.pm_serialize_parse(buffer.pointer, string.pointer, string.length, dump_options(options)) + nil + end + end + end + + private + + def dump_common(string, options) # :nodoc: + LibRubyParser::PrismBuffer.with do |buffer| + LibRubyParser.pm_serialize_parse(buffer.pointer, string.pointer, string.length, dump_options(options)) + + dumped = buffer.read + dumped.freeze if options.fetch(:freeze, false) + + dumped + end + end + + def lex_common(string, code, options) # :nodoc: + LibRubyParser::PrismBuffer.with do |buffer| + LibRubyParser.pm_serialize_lex(buffer.pointer, string.pointer, string.length, dump_options(options)) + Serialize.load_lex(code, buffer.read, options.fetch(:freeze, false)) + end + end + + def parse_common(string, code, options) # :nodoc: + serialized = dump_common(string, options) + Serialize.load_parse(code, serialized, options.fetch(:freeze, false)) + end + + def parse_comments_common(string, code, options) # :nodoc: + LibRubyParser::PrismBuffer.with do |buffer| + LibRubyParser.pm_serialize_parse_comments(buffer.pointer, string.pointer, string.length, dump_options(options)) + Serialize.load_parse_comments(code, buffer.read, options.fetch(:freeze, false)) + end + end + + def parse_lex_common(string, code, options) # :nodoc: + LibRubyParser::PrismBuffer.with do |buffer| + LibRubyParser.pm_serialize_parse_lex(buffer.pointer, string.pointer, string.length, dump_options(options)) + Serialize.load_parse_lex(code, buffer.read, options.fetch(:freeze, false)) + end + end + + def parse_file_success_common(string, options) # :nodoc: + LibRubyParser.pm_parse_success_p(string.pointer, string.length, dump_options(options)) + end + + # Return the value that should be dumped for the command_line option. + def dump_options_command_line(options) + command_line = options.fetch(:command_line, "") + raise ArgumentError, "command_line must be a string" unless command_line.is_a?(String) + + command_line.each_char.inject(0) do |value, char| + case char + when "a" then value | 0b000001 + when "e" then value | 0b000010 + when "l" then value | 0b000100 + when "n" then value | 0b001000 + when "p" then value | 0b010000 + when "x" then value | 0b100000 + else raise ArgumentError, "invalid command_line option: #{char}" + end + end + end + + # Return the value that should be dumped for the version option. + def dump_options_version(version) + case version + when nil, "latest" + 0 + when /\A3\.3(\.\d+)?\z/ + 1 + when /\A3\.4(\.\d+)?\z/ + 2 + when /\A3\.5(\.\d+)?\z/ + 0 + else + raise ArgumentError, "invalid version: #{version}" + end + end + + # Convert the given options into a serialized options string. + def dump_options(options) + template = +"" + values = [] + + template << "L" + if (filepath = options[:filepath]) + values.push(filepath.bytesize, filepath.b) + template << "A*" + else + values << 0 + end + + template << "l" + values << options.fetch(:line, 1) + + template << "L" + if (encoding = options[:encoding]) + name = encoding.is_a?(Encoding) ? encoding.name : encoding + values.push(name.bytesize, name.b) + template << "A*" + else + values << 0 + end + + template << "C" + values << (options.fetch(:frozen_string_literal, false) ? 1 : 0) + + template << "C" + values << dump_options_command_line(options) + + template << "C" + values << dump_options_version(options[:version]) + + template << "C" + values << (options[:encoding] == false ? 1 : 0) + + template << "C" + values << (options.fetch(:main_script, false) ? 1 : 0) + + template << "C" + values << (options.fetch(:partial_script, false) ? 1 : 0) + + template << "C" + values << (options.fetch(:freeze, false) ? 1 : 0) + + template << "L" + if (scopes = options[:scopes]) + values << scopes.length + + scopes.each do |scope| + locals = nil + forwarding = 0 + + case scope + when Array + locals = scope + when Scope + locals = scope.locals + + scope.forwarding.each do |forward| + case forward + when :* then forwarding |= 0x1 + when :** then forwarding |= 0x2 + when :& then forwarding |= 0x4 + when :"..." then forwarding |= 0x8 + else raise ArgumentError, "invalid forwarding value: #{forward}" + end + end + else + raise TypeError, "wrong argument type #{scope.class.inspect} (expected Array or Prism::Scope)" + end + + template << "L" + values << locals.length + + template << "C" + values << forwarding + + locals.each do |local| + name = local.name + template << "L" + values << name.bytesize + + template << "A*" + values << name.b + end + end + else + values << 0 + end + + values.pack(template) + end + end + + # Here we are going to patch StringQuery to put in the class-level methods so + # that it can maintain a consistent interface + class StringQuery + class << self + # Mirrors the C extension's StringQuery::local? method. + def local?(string) + query(LibRubyParser.pm_string_query_local(string, string.bytesize, string.encoding.name)) + end + + # Mirrors the C extension's StringQuery::constant? method. + def constant?(string) + query(LibRubyParser.pm_string_query_constant(string, string.bytesize, string.encoding.name)) + end + + # Mirrors the C extension's StringQuery::method_name? method. + def method_name?(string) + query(LibRubyParser.pm_string_query_method_name(string, string.bytesize, string.encoding.name)) + end + + private + + # Parse the enum result and return an appropriate boolean. + def query(result) + case result + when :PM_STRING_QUERY_ERROR + raise ArgumentError, "Invalid or non ascii-compatible encoding" + when :PM_STRING_QUERY_FALSE + false + when :PM_STRING_QUERY_TRUE + true + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/inspect_visitor.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/inspect_visitor.rb new file mode 100644 index 00000000..f984f77a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/inspect_visitor.rb @@ -0,0 +1,2389 @@ +# frozen_string_literal: true + +=begin +This file is generated by the templates/template.rb script and should not be +modified manually. See templates/lib/prism/inspect_visitor.rb.erb +if you are looking to modify the template +=end + +module Prism + # This visitor is responsible for composing the strings that get returned by + # the various #inspect methods defined on each of the nodes. + class InspectVisitor < Visitor + # Most of the time, we can simply pass down the indent to the next node. + # However, when we are inside a list we want some extra special formatting + # when we hit an element in that list. In this case, we have a special + # command that replaces the subsequent indent with the given value. + class Replace # :nodoc: + attr_reader :value + + def initialize(value) + @value = value + end + end + + private_constant :Replace + + # The current prefix string. + attr_reader :indent + + # The list of commands that we need to execute in order to compose the + # final string. + attr_reader :commands + + # Initializes a new instance of the InspectVisitor. + def initialize(indent = +"") + @indent = indent + @commands = [] + end + + # Compose an inspect string for the given node. + def self.compose(node) + visitor = new + node.accept(visitor) + visitor.compose + end + + # Compose the final string. + def compose + buffer = +"" + replace = nil + + until commands.empty? + # @type var command: String | node | Replace + # @type var indent: String + command, indent = *commands.shift + + case command + when String + buffer << (replace || indent) + buffer << command + replace = nil + when Node + visitor = InspectVisitor.new(indent) + command.accept(visitor) + @commands = [*visitor.commands, *@commands] + when Replace + replace = command.value + else + raise "Unknown command: #{command.inspect}" + end + end + + buffer + end + + # Inspect a AliasGlobalVariableNode node. + def visit_alias_global_variable_node(node) + commands << [inspect_node("AliasGlobalVariableNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── new_name:\n", indent] + commands << [node.new_name, "#{indent}│ "] + commands << ["├── old_name:\n", indent] + commands << [node.old_name, "#{indent}│ "] + commands << ["└── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent] + end + + # Inspect a AliasMethodNode node. + def visit_alias_method_node(node) + commands << [inspect_node("AliasMethodNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── new_name:\n", indent] + commands << [node.new_name, "#{indent}│ "] + commands << ["├── old_name:\n", indent] + commands << [node.old_name, "#{indent}│ "] + commands << ["└── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent] + end + + # Inspect a AlternationPatternNode node. + def visit_alternation_pattern_node(node) + commands << [inspect_node("AlternationPatternNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── left:\n", indent] + commands << [node.left, "#{indent}│ "] + commands << ["├── right:\n", indent] + commands << [node.right, "#{indent}│ "] + commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + end + + # Inspect a AndNode node. + def visit_and_node(node) + commands << [inspect_node("AndNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── left:\n", indent] + commands << [node.left, "#{indent}│ "] + commands << ["├── right:\n", indent] + commands << [node.right, "#{indent}│ "] + commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + end + + # Inspect a ArgumentsNode node. + def visit_arguments_node(node) + commands << [inspect_node("ArgumentsNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("contains_forwarding" if node.contains_forwarding?), ("contains_keywords" if node.contains_keywords?), ("contains_keyword_splat" if node.contains_keyword_splat?), ("contains_splat" if node.contains_splat?), ("contains_multiple_splats" if node.contains_multiple_splats?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["└── arguments: (length: #{(arguments = node.arguments).length})\n", indent] + if arguments.any? + arguments[0...-1].each do |child| + commands << [Replace.new("#{indent} ├── "), indent] + commands << [child, "#{indent} │ "] + end + commands << [Replace.new("#{indent} └── "), indent] + commands << [arguments[-1], "#{indent} "] + end + end + + # Inspect a ArrayNode node. + def visit_array_node(node) + commands << [inspect_node("ArrayNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("contains_splat" if node.contains_splat?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── elements: (length: #{(elements = node.elements).length})\n", indent] + if elements.any? + elements[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [elements[-1], "#{indent}│ "] + end + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + end + + # Inspect a ArrayPatternNode node. + def visit_array_pattern_node(node) + commands << [inspect_node("ArrayPatternNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (constant = node.constant).nil? + commands << ["├── constant: ∅\n", indent] + else + commands << ["├── constant:\n", indent] + commands << [constant, "#{indent}│ "] + end + commands << ["├── requireds: (length: #{(requireds = node.requireds).length})\n", indent] + if requireds.any? + requireds[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [requireds[-1], "#{indent}│ "] + end + if (rest = node.rest).nil? + commands << ["├── rest: ∅\n", indent] + else + commands << ["├── rest:\n", indent] + commands << [rest, "#{indent}│ "] + end + commands << ["├── posts: (length: #{(posts = node.posts).length})\n", indent] + if posts.any? + posts[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [posts[-1], "#{indent}│ "] + end + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + end + + # Inspect a AssocNode node. + def visit_assoc_node(node) + commands << [inspect_node("AssocNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── key:\n", indent] + commands << [node.key, "#{indent}│ "] + commands << ["├── value:\n", indent] + commands << [node.value, "#{indent}│ "] + commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + end + + # Inspect a AssocSplatNode node. + def visit_assoc_splat_node(node) + commands << [inspect_node("AssocSplatNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (value = node.value).nil? + commands << ["├── value: ∅\n", indent] + else + commands << ["├── value:\n", indent] + commands << [value, "#{indent}│ "] + end + commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + end + + # Inspect a BackReferenceReadNode node. + def visit_back_reference_read_node(node) + commands << [inspect_node("BackReferenceReadNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["└── name: #{node.name.inspect}\n", indent] + end + + # Inspect a BeginNode node. + def visit_begin_node(node) + commands << [inspect_node("BeginNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── begin_keyword_loc: #{inspect_location(node.begin_keyword_loc)}\n", indent] + if (statements = node.statements).nil? + commands << ["├── statements: ∅\n", indent] + else + commands << ["├── statements:\n", indent] + commands << [statements, "#{indent}│ "] + end + if (rescue_clause = node.rescue_clause).nil? + commands << ["├── rescue_clause: ∅\n", indent] + else + commands << ["├── rescue_clause:\n", indent] + commands << [rescue_clause, "#{indent}│ "] + end + if (else_clause = node.else_clause).nil? + commands << ["├── else_clause: ∅\n", indent] + else + commands << ["├── else_clause:\n", indent] + commands << [else_clause, "#{indent}│ "] + end + if (ensure_clause = node.ensure_clause).nil? + commands << ["├── ensure_clause: ∅\n", indent] + else + commands << ["├── ensure_clause:\n", indent] + commands << [ensure_clause, "#{indent}│ "] + end + commands << ["└── end_keyword_loc: #{inspect_location(node.end_keyword_loc)}\n", indent] + end + + # Inspect a BlockArgumentNode node. + def visit_block_argument_node(node) + commands << [inspect_node("BlockArgumentNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (expression = node.expression).nil? + commands << ["├── expression: ∅\n", indent] + else + commands << ["├── expression:\n", indent] + commands << [expression, "#{indent}│ "] + end + commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + end + + # Inspect a BlockLocalVariableNode node. + def visit_block_local_variable_node(node) + commands << [inspect_node("BlockLocalVariableNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("repeated_parameter" if node.repeated_parameter?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["└── name: #{node.name.inspect}\n", indent] + end + + # Inspect a BlockNode node. + def visit_block_node(node) + commands << [inspect_node("BlockNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── locals: #{node.locals.inspect}\n", indent] + if (parameters = node.parameters).nil? + commands << ["├── parameters: ∅\n", indent] + else + commands << ["├── parameters:\n", indent] + commands << [parameters, "#{indent}│ "] + end + if (body = node.body).nil? + commands << ["├── body: ∅\n", indent] + else + commands << ["├── body:\n", indent] + commands << [body, "#{indent}│ "] + end + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + end + + # Inspect a BlockParameterNode node. + def visit_block_parameter_node(node) + commands << [inspect_node("BlockParameterNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("repeated_parameter" if node.repeated_parameter?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (name = node.name).nil? + commands << ["├── name: ∅\n", indent] + else + commands << ["├── name: #{name.inspect}\n", indent] + end + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + end + + # Inspect a BlockParametersNode node. + def visit_block_parameters_node(node) + commands << [inspect_node("BlockParametersNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (parameters = node.parameters).nil? + commands << ["├── parameters: ∅\n", indent] + else + commands << ["├── parameters:\n", indent] + commands << [parameters, "#{indent}│ "] + end + commands << ["├── locals: (length: #{(locals = node.locals).length})\n", indent] + if locals.any? + locals[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [locals[-1], "#{indent}│ "] + end + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + end + + # Inspect a BreakNode node. + def visit_break_node(node) + commands << [inspect_node("BreakNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (arguments = node.arguments).nil? + commands << ["├── arguments: ∅\n", indent] + else + commands << ["├── arguments:\n", indent] + commands << [arguments, "#{indent}│ "] + end + commands << ["└── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent] + end + + # Inspect a CallAndWriteNode node. + def visit_call_and_write_node(node) + commands << [inspect_node("CallAndWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("safe_navigation" if node.safe_navigation?), ("variable_call" if node.variable_call?), ("attribute_write" if node.attribute_write?), ("ignore_visibility" if node.ignore_visibility?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (receiver = node.receiver).nil? + commands << ["├── receiver: ∅\n", indent] + else + commands << ["├── receiver:\n", indent] + commands << [receiver, "#{indent}│ "] + end + commands << ["├── call_operator_loc: #{inspect_location(node.call_operator_loc)}\n", indent] + commands << ["├── message_loc: #{inspect_location(node.message_loc)}\n", indent] + commands << ["├── read_name: #{node.read_name.inspect}\n", indent] + commands << ["├── write_name: #{node.write_name.inspect}\n", indent] + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["└── value:\n", indent] + commands << [node.value, "#{indent} "] + end + + # Inspect a CallNode node. + def visit_call_node(node) + commands << [inspect_node("CallNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("safe_navigation" if node.safe_navigation?), ("variable_call" if node.variable_call?), ("attribute_write" if node.attribute_write?), ("ignore_visibility" if node.ignore_visibility?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (receiver = node.receiver).nil? + commands << ["├── receiver: ∅\n", indent] + else + commands << ["├── receiver:\n", indent] + commands << [receiver, "#{indent}│ "] + end + commands << ["├── call_operator_loc: #{inspect_location(node.call_operator_loc)}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["├── message_loc: #{inspect_location(node.message_loc)}\n", indent] + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + if (arguments = node.arguments).nil? + commands << ["├── arguments: ∅\n", indent] + else + commands << ["├── arguments:\n", indent] + commands << [arguments, "#{indent}│ "] + end + commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + if (block = node.block).nil? + commands << ["└── block: ∅\n", indent] + else + commands << ["└── block:\n", indent] + commands << [block, "#{indent} "] + end + end + + # Inspect a CallOperatorWriteNode node. + def visit_call_operator_write_node(node) + commands << [inspect_node("CallOperatorWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("safe_navigation" if node.safe_navigation?), ("variable_call" if node.variable_call?), ("attribute_write" if node.attribute_write?), ("ignore_visibility" if node.ignore_visibility?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (receiver = node.receiver).nil? + commands << ["├── receiver: ∅\n", indent] + else + commands << ["├── receiver:\n", indent] + commands << [receiver, "#{indent}│ "] + end + commands << ["├── call_operator_loc: #{inspect_location(node.call_operator_loc)}\n", indent] + commands << ["├── message_loc: #{inspect_location(node.message_loc)}\n", indent] + commands << ["├── read_name: #{node.read_name.inspect}\n", indent] + commands << ["├── write_name: #{node.write_name.inspect}\n", indent] + commands << ["├── binary_operator: #{node.binary_operator.inspect}\n", indent] + commands << ["├── binary_operator_loc: #{inspect_location(node.binary_operator_loc)}\n", indent] + commands << ["└── value:\n", indent] + commands << [node.value, "#{indent} "] + end + + # Inspect a CallOrWriteNode node. + def visit_call_or_write_node(node) + commands << [inspect_node("CallOrWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("safe_navigation" if node.safe_navigation?), ("variable_call" if node.variable_call?), ("attribute_write" if node.attribute_write?), ("ignore_visibility" if node.ignore_visibility?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (receiver = node.receiver).nil? + commands << ["├── receiver: ∅\n", indent] + else + commands << ["├── receiver:\n", indent] + commands << [receiver, "#{indent}│ "] + end + commands << ["├── call_operator_loc: #{inspect_location(node.call_operator_loc)}\n", indent] + commands << ["├── message_loc: #{inspect_location(node.message_loc)}\n", indent] + commands << ["├── read_name: #{node.read_name.inspect}\n", indent] + commands << ["├── write_name: #{node.write_name.inspect}\n", indent] + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["└── value:\n", indent] + commands << [node.value, "#{indent} "] + end + + # Inspect a CallTargetNode node. + def visit_call_target_node(node) + commands << [inspect_node("CallTargetNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("safe_navigation" if node.safe_navigation?), ("variable_call" if node.variable_call?), ("attribute_write" if node.attribute_write?), ("ignore_visibility" if node.ignore_visibility?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── receiver:\n", indent] + commands << [node.receiver, "#{indent}│ "] + commands << ["├── call_operator_loc: #{inspect_location(node.call_operator_loc)}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["└── message_loc: #{inspect_location(node.message_loc)}\n", indent] + end + + # Inspect a CapturePatternNode node. + def visit_capture_pattern_node(node) + commands << [inspect_node("CapturePatternNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── value:\n", indent] + commands << [node.value, "#{indent}│ "] + commands << ["├── target:\n", indent] + commands << [node.target, "#{indent}│ "] + commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + end + + # Inspect a CaseMatchNode node. + def visit_case_match_node(node) + commands << [inspect_node("CaseMatchNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (predicate = node.predicate).nil? + commands << ["├── predicate: ∅\n", indent] + else + commands << ["├── predicate:\n", indent] + commands << [predicate, "#{indent}│ "] + end + commands << ["├── conditions: (length: #{(conditions = node.conditions).length})\n", indent] + if conditions.any? + conditions[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [conditions[-1], "#{indent}│ "] + end + if (else_clause = node.else_clause).nil? + commands << ["├── else_clause: ∅\n", indent] + else + commands << ["├── else_clause:\n", indent] + commands << [else_clause, "#{indent}│ "] + end + commands << ["├── case_keyword_loc: #{inspect_location(node.case_keyword_loc)}\n", indent] + commands << ["└── end_keyword_loc: #{inspect_location(node.end_keyword_loc)}\n", indent] + end + + # Inspect a CaseNode node. + def visit_case_node(node) + commands << [inspect_node("CaseNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (predicate = node.predicate).nil? + commands << ["├── predicate: ∅\n", indent] + else + commands << ["├── predicate:\n", indent] + commands << [predicate, "#{indent}│ "] + end + commands << ["├── conditions: (length: #{(conditions = node.conditions).length})\n", indent] + if conditions.any? + conditions[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [conditions[-1], "#{indent}│ "] + end + if (else_clause = node.else_clause).nil? + commands << ["├── else_clause: ∅\n", indent] + else + commands << ["├── else_clause:\n", indent] + commands << [else_clause, "#{indent}│ "] + end + commands << ["├── case_keyword_loc: #{inspect_location(node.case_keyword_loc)}\n", indent] + commands << ["└── end_keyword_loc: #{inspect_location(node.end_keyword_loc)}\n", indent] + end + + # Inspect a ClassNode node. + def visit_class_node(node) + commands << [inspect_node("ClassNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── locals: #{node.locals.inspect}\n", indent] + commands << ["├── class_keyword_loc: #{inspect_location(node.class_keyword_loc)}\n", indent] + commands << ["├── constant_path:\n", indent] + commands << [node.constant_path, "#{indent}│ "] + commands << ["├── inheritance_operator_loc: #{inspect_location(node.inheritance_operator_loc)}\n", indent] + if (superclass = node.superclass).nil? + commands << ["├── superclass: ∅\n", indent] + else + commands << ["├── superclass:\n", indent] + commands << [superclass, "#{indent}│ "] + end + if (body = node.body).nil? + commands << ["├── body: ∅\n", indent] + else + commands << ["├── body:\n", indent] + commands << [body, "#{indent}│ "] + end + commands << ["├── end_keyword_loc: #{inspect_location(node.end_keyword_loc)}\n", indent] + commands << ["└── name: #{node.name.inspect}\n", indent] + end + + # Inspect a ClassVariableAndWriteNode node. + def visit_class_variable_and_write_node(node) + commands << [inspect_node("ClassVariableAndWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["└── value:\n", indent] + commands << [node.value, "#{indent} "] + end + + # Inspect a ClassVariableOperatorWriteNode node. + def visit_class_variable_operator_write_node(node) + commands << [inspect_node("ClassVariableOperatorWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["├── binary_operator_loc: #{inspect_location(node.binary_operator_loc)}\n", indent] + commands << ["├── value:\n", indent] + commands << [node.value, "#{indent}│ "] + commands << ["└── binary_operator: #{node.binary_operator.inspect}\n", indent] + end + + # Inspect a ClassVariableOrWriteNode node. + def visit_class_variable_or_write_node(node) + commands << [inspect_node("ClassVariableOrWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["└── value:\n", indent] + commands << [node.value, "#{indent} "] + end + + # Inspect a ClassVariableReadNode node. + def visit_class_variable_read_node(node) + commands << [inspect_node("ClassVariableReadNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["└── name: #{node.name.inspect}\n", indent] + end + + # Inspect a ClassVariableTargetNode node. + def visit_class_variable_target_node(node) + commands << [inspect_node("ClassVariableTargetNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["└── name: #{node.name.inspect}\n", indent] + end + + # Inspect a ClassVariableWriteNode node. + def visit_class_variable_write_node(node) + commands << [inspect_node("ClassVariableWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["├── value:\n", indent] + commands << [node.value, "#{indent}│ "] + commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + end + + # Inspect a ConstantAndWriteNode node. + def visit_constant_and_write_node(node) + commands << [inspect_node("ConstantAndWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["└── value:\n", indent] + commands << [node.value, "#{indent} "] + end + + # Inspect a ConstantOperatorWriteNode node. + def visit_constant_operator_write_node(node) + commands << [inspect_node("ConstantOperatorWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["├── binary_operator_loc: #{inspect_location(node.binary_operator_loc)}\n", indent] + commands << ["├── value:\n", indent] + commands << [node.value, "#{indent}│ "] + commands << ["└── binary_operator: #{node.binary_operator.inspect}\n", indent] + end + + # Inspect a ConstantOrWriteNode node. + def visit_constant_or_write_node(node) + commands << [inspect_node("ConstantOrWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["└── value:\n", indent] + commands << [node.value, "#{indent} "] + end + + # Inspect a ConstantPathAndWriteNode node. + def visit_constant_path_and_write_node(node) + commands << [inspect_node("ConstantPathAndWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── target:\n", indent] + commands << [node.target, "#{indent}│ "] + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["└── value:\n", indent] + commands << [node.value, "#{indent} "] + end + + # Inspect a ConstantPathNode node. + def visit_constant_path_node(node) + commands << [inspect_node("ConstantPathNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (parent = node.parent).nil? + commands << ["├── parent: ∅\n", indent] + else + commands << ["├── parent:\n", indent] + commands << [parent, "#{indent}│ "] + end + if (name = node.name).nil? + commands << ["├── name: ∅\n", indent] + else + commands << ["├── name: #{name.inspect}\n", indent] + end + commands << ["├── delimiter_loc: #{inspect_location(node.delimiter_loc)}\n", indent] + commands << ["└── name_loc: #{inspect_location(node.name_loc)}\n", indent] + end + + # Inspect a ConstantPathOperatorWriteNode node. + def visit_constant_path_operator_write_node(node) + commands << [inspect_node("ConstantPathOperatorWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── target:\n", indent] + commands << [node.target, "#{indent}│ "] + commands << ["├── binary_operator_loc: #{inspect_location(node.binary_operator_loc)}\n", indent] + commands << ["├── value:\n", indent] + commands << [node.value, "#{indent}│ "] + commands << ["└── binary_operator: #{node.binary_operator.inspect}\n", indent] + end + + # Inspect a ConstantPathOrWriteNode node. + def visit_constant_path_or_write_node(node) + commands << [inspect_node("ConstantPathOrWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── target:\n", indent] + commands << [node.target, "#{indent}│ "] + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["└── value:\n", indent] + commands << [node.value, "#{indent} "] + end + + # Inspect a ConstantPathTargetNode node. + def visit_constant_path_target_node(node) + commands << [inspect_node("ConstantPathTargetNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (parent = node.parent).nil? + commands << ["├── parent: ∅\n", indent] + else + commands << ["├── parent:\n", indent] + commands << [parent, "#{indent}│ "] + end + if (name = node.name).nil? + commands << ["├── name: ∅\n", indent] + else + commands << ["├── name: #{name.inspect}\n", indent] + end + commands << ["├── delimiter_loc: #{inspect_location(node.delimiter_loc)}\n", indent] + commands << ["└── name_loc: #{inspect_location(node.name_loc)}\n", indent] + end + + # Inspect a ConstantPathWriteNode node. + def visit_constant_path_write_node(node) + commands << [inspect_node("ConstantPathWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── target:\n", indent] + commands << [node.target, "#{indent}│ "] + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["└── value:\n", indent] + commands << [node.value, "#{indent} "] + end + + # Inspect a ConstantReadNode node. + def visit_constant_read_node(node) + commands << [inspect_node("ConstantReadNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["└── name: #{node.name.inspect}\n", indent] + end + + # Inspect a ConstantTargetNode node. + def visit_constant_target_node(node) + commands << [inspect_node("ConstantTargetNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["└── name: #{node.name.inspect}\n", indent] + end + + # Inspect a ConstantWriteNode node. + def visit_constant_write_node(node) + commands << [inspect_node("ConstantWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["├── value:\n", indent] + commands << [node.value, "#{indent}│ "] + commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + end + + # Inspect a DefNode node. + def visit_def_node(node) + commands << [inspect_node("DefNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + if (receiver = node.receiver).nil? + commands << ["├── receiver: ∅\n", indent] + else + commands << ["├── receiver:\n", indent] + commands << [receiver, "#{indent}│ "] + end + if (parameters = node.parameters).nil? + commands << ["├── parameters: ∅\n", indent] + else + commands << ["├── parameters:\n", indent] + commands << [parameters, "#{indent}│ "] + end + if (body = node.body).nil? + commands << ["├── body: ∅\n", indent] + else + commands << ["├── body:\n", indent] + commands << [body, "#{indent}│ "] + end + commands << ["├── locals: #{node.locals.inspect}\n", indent] + commands << ["├── def_keyword_loc: #{inspect_location(node.def_keyword_loc)}\n", indent] + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["├── lparen_loc: #{inspect_location(node.lparen_loc)}\n", indent] + commands << ["├── rparen_loc: #{inspect_location(node.rparen_loc)}\n", indent] + commands << ["├── equal_loc: #{inspect_location(node.equal_loc)}\n", indent] + commands << ["└── end_keyword_loc: #{inspect_location(node.end_keyword_loc)}\n", indent] + end + + # Inspect a DefinedNode node. + def visit_defined_node(node) + commands << [inspect_node("DefinedNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── lparen_loc: #{inspect_location(node.lparen_loc)}\n", indent] + commands << ["├── value:\n", indent] + commands << [node.value, "#{indent}│ "] + commands << ["├── rparen_loc: #{inspect_location(node.rparen_loc)}\n", indent] + commands << ["└── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent] + end + + # Inspect a ElseNode node. + def visit_else_node(node) + commands << [inspect_node("ElseNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── else_keyword_loc: #{inspect_location(node.else_keyword_loc)}\n", indent] + if (statements = node.statements).nil? + commands << ["├── statements: ∅\n", indent] + else + commands << ["├── statements:\n", indent] + commands << [statements, "#{indent}│ "] + end + commands << ["└── end_keyword_loc: #{inspect_location(node.end_keyword_loc)}\n", indent] + end + + # Inspect a EmbeddedStatementsNode node. + def visit_embedded_statements_node(node) + commands << [inspect_node("EmbeddedStatementsNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + if (statements = node.statements).nil? + commands << ["├── statements: ∅\n", indent] + else + commands << ["├── statements:\n", indent] + commands << [statements, "#{indent}│ "] + end + commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + end + + # Inspect a EmbeddedVariableNode node. + def visit_embedded_variable_node(node) + commands << [inspect_node("EmbeddedVariableNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["└── variable:\n", indent] + commands << [node.variable, "#{indent} "] + end + + # Inspect a EnsureNode node. + def visit_ensure_node(node) + commands << [inspect_node("EnsureNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── ensure_keyword_loc: #{inspect_location(node.ensure_keyword_loc)}\n", indent] + if (statements = node.statements).nil? + commands << ["├── statements: ∅\n", indent] + else + commands << ["├── statements:\n", indent] + commands << [statements, "#{indent}│ "] + end + commands << ["└── end_keyword_loc: #{inspect_location(node.end_keyword_loc)}\n", indent] + end + + # Inspect a FalseNode node. + def visit_false_node(node) + commands << [inspect_node("FalseNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + end + + # Inspect a FindPatternNode node. + def visit_find_pattern_node(node) + commands << [inspect_node("FindPatternNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (constant = node.constant).nil? + commands << ["├── constant: ∅\n", indent] + else + commands << ["├── constant:\n", indent] + commands << [constant, "#{indent}│ "] + end + commands << ["├── left:\n", indent] + commands << [node.left, "#{indent}│ "] + commands << ["├── requireds: (length: #{(requireds = node.requireds).length})\n", indent] + if requireds.any? + requireds[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [requireds[-1], "#{indent}│ "] + end + commands << ["├── right:\n", indent] + commands << [node.right, "#{indent}│ "] + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + end + + # Inspect a FlipFlopNode node. + def visit_flip_flop_node(node) + commands << [inspect_node("FlipFlopNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("exclude_end" if node.exclude_end?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (left = node.left).nil? + commands << ["├── left: ∅\n", indent] + else + commands << ["├── left:\n", indent] + commands << [left, "#{indent}│ "] + end + if (right = node.right).nil? + commands << ["├── right: ∅\n", indent] + else + commands << ["├── right:\n", indent] + commands << [right, "#{indent}│ "] + end + commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + end + + # Inspect a FloatNode node. + def visit_float_node(node) + commands << [inspect_node("FloatNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["└── value: #{node.value.inspect}\n", indent] + end + + # Inspect a ForNode node. + def visit_for_node(node) + commands << [inspect_node("ForNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── index:\n", indent] + commands << [node.index, "#{indent}│ "] + commands << ["├── collection:\n", indent] + commands << [node.collection, "#{indent}│ "] + if (statements = node.statements).nil? + commands << ["├── statements: ∅\n", indent] + else + commands << ["├── statements:\n", indent] + commands << [statements, "#{indent}│ "] + end + commands << ["├── for_keyword_loc: #{inspect_location(node.for_keyword_loc)}\n", indent] + commands << ["├── in_keyword_loc: #{inspect_location(node.in_keyword_loc)}\n", indent] + commands << ["├── do_keyword_loc: #{inspect_location(node.do_keyword_loc)}\n", indent] + commands << ["└── end_keyword_loc: #{inspect_location(node.end_keyword_loc)}\n", indent] + end + + # Inspect a ForwardingArgumentsNode node. + def visit_forwarding_arguments_node(node) + commands << [inspect_node("ForwardingArgumentsNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + end + + # Inspect a ForwardingParameterNode node. + def visit_forwarding_parameter_node(node) + commands << [inspect_node("ForwardingParameterNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + end + + # Inspect a ForwardingSuperNode node. + def visit_forwarding_super_node(node) + commands << [inspect_node("ForwardingSuperNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (block = node.block).nil? + commands << ["└── block: ∅\n", indent] + else + commands << ["└── block:\n", indent] + commands << [block, "#{indent} "] + end + end + + # Inspect a GlobalVariableAndWriteNode node. + def visit_global_variable_and_write_node(node) + commands << [inspect_node("GlobalVariableAndWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["└── value:\n", indent] + commands << [node.value, "#{indent} "] + end + + # Inspect a GlobalVariableOperatorWriteNode node. + def visit_global_variable_operator_write_node(node) + commands << [inspect_node("GlobalVariableOperatorWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["├── binary_operator_loc: #{inspect_location(node.binary_operator_loc)}\n", indent] + commands << ["├── value:\n", indent] + commands << [node.value, "#{indent}│ "] + commands << ["└── binary_operator: #{node.binary_operator.inspect}\n", indent] + end + + # Inspect a GlobalVariableOrWriteNode node. + def visit_global_variable_or_write_node(node) + commands << [inspect_node("GlobalVariableOrWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["└── value:\n", indent] + commands << [node.value, "#{indent} "] + end + + # Inspect a GlobalVariableReadNode node. + def visit_global_variable_read_node(node) + commands << [inspect_node("GlobalVariableReadNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["└── name: #{node.name.inspect}\n", indent] + end + + # Inspect a GlobalVariableTargetNode node. + def visit_global_variable_target_node(node) + commands << [inspect_node("GlobalVariableTargetNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["└── name: #{node.name.inspect}\n", indent] + end + + # Inspect a GlobalVariableWriteNode node. + def visit_global_variable_write_node(node) + commands << [inspect_node("GlobalVariableWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["├── value:\n", indent] + commands << [node.value, "#{indent}│ "] + commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + end + + # Inspect a HashNode node. + def visit_hash_node(node) + commands << [inspect_node("HashNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + commands << ["├── elements: (length: #{(elements = node.elements).length})\n", indent] + if elements.any? + elements[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [elements[-1], "#{indent}│ "] + end + commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + end + + # Inspect a HashPatternNode node. + def visit_hash_pattern_node(node) + commands << [inspect_node("HashPatternNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (constant = node.constant).nil? + commands << ["├── constant: ∅\n", indent] + else + commands << ["├── constant:\n", indent] + commands << [constant, "#{indent}│ "] + end + commands << ["├── elements: (length: #{(elements = node.elements).length})\n", indent] + if elements.any? + elements[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [elements[-1], "#{indent}│ "] + end + if (rest = node.rest).nil? + commands << ["├── rest: ∅\n", indent] + else + commands << ["├── rest:\n", indent] + commands << [rest, "#{indent}│ "] + end + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + end + + # Inspect a IfNode node. + def visit_if_node(node) + commands << [inspect_node("IfNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── if_keyword_loc: #{inspect_location(node.if_keyword_loc)}\n", indent] + commands << ["├── predicate:\n", indent] + commands << [node.predicate, "#{indent}│ "] + commands << ["├── then_keyword_loc: #{inspect_location(node.then_keyword_loc)}\n", indent] + if (statements = node.statements).nil? + commands << ["├── statements: ∅\n", indent] + else + commands << ["├── statements:\n", indent] + commands << [statements, "#{indent}│ "] + end + if (subsequent = node.subsequent).nil? + commands << ["├── subsequent: ∅\n", indent] + else + commands << ["├── subsequent:\n", indent] + commands << [subsequent, "#{indent}│ "] + end + commands << ["└── end_keyword_loc: #{inspect_location(node.end_keyword_loc)}\n", indent] + end + + # Inspect a ImaginaryNode node. + def visit_imaginary_node(node) + commands << [inspect_node("ImaginaryNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["└── numeric:\n", indent] + commands << [node.numeric, "#{indent} "] + end + + # Inspect a ImplicitNode node. + def visit_implicit_node(node) + commands << [inspect_node("ImplicitNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["└── value:\n", indent] + commands << [node.value, "#{indent} "] + end + + # Inspect a ImplicitRestNode node. + def visit_implicit_rest_node(node) + commands << [inspect_node("ImplicitRestNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + end + + # Inspect a InNode node. + def visit_in_node(node) + commands << [inspect_node("InNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── pattern:\n", indent] + commands << [node.pattern, "#{indent}│ "] + if (statements = node.statements).nil? + commands << ["├── statements: ∅\n", indent] + else + commands << ["├── statements:\n", indent] + commands << [statements, "#{indent}│ "] + end + commands << ["├── in_loc: #{inspect_location(node.in_loc)}\n", indent] + commands << ["└── then_loc: #{inspect_location(node.then_loc)}\n", indent] + end + + # Inspect a IndexAndWriteNode node. + def visit_index_and_write_node(node) + commands << [inspect_node("IndexAndWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("safe_navigation" if node.safe_navigation?), ("variable_call" if node.variable_call?), ("attribute_write" if node.attribute_write?), ("ignore_visibility" if node.ignore_visibility?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (receiver = node.receiver).nil? + commands << ["├── receiver: ∅\n", indent] + else + commands << ["├── receiver:\n", indent] + commands << [receiver, "#{indent}│ "] + end + commands << ["├── call_operator_loc: #{inspect_location(node.call_operator_loc)}\n", indent] + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + if (arguments = node.arguments).nil? + commands << ["├── arguments: ∅\n", indent] + else + commands << ["├── arguments:\n", indent] + commands << [arguments, "#{indent}│ "] + end + commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + if (block = node.block).nil? + commands << ["├── block: ∅\n", indent] + else + commands << ["├── block:\n", indent] + commands << [block, "#{indent}│ "] + end + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["└── value:\n", indent] + commands << [node.value, "#{indent} "] + end + + # Inspect a IndexOperatorWriteNode node. + def visit_index_operator_write_node(node) + commands << [inspect_node("IndexOperatorWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("safe_navigation" if node.safe_navigation?), ("variable_call" if node.variable_call?), ("attribute_write" if node.attribute_write?), ("ignore_visibility" if node.ignore_visibility?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (receiver = node.receiver).nil? + commands << ["├── receiver: ∅\n", indent] + else + commands << ["├── receiver:\n", indent] + commands << [receiver, "#{indent}│ "] + end + commands << ["├── call_operator_loc: #{inspect_location(node.call_operator_loc)}\n", indent] + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + if (arguments = node.arguments).nil? + commands << ["├── arguments: ∅\n", indent] + else + commands << ["├── arguments:\n", indent] + commands << [arguments, "#{indent}│ "] + end + commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + if (block = node.block).nil? + commands << ["├── block: ∅\n", indent] + else + commands << ["├── block:\n", indent] + commands << [block, "#{indent}│ "] + end + commands << ["├── binary_operator: #{node.binary_operator.inspect}\n", indent] + commands << ["├── binary_operator_loc: #{inspect_location(node.binary_operator_loc)}\n", indent] + commands << ["└── value:\n", indent] + commands << [node.value, "#{indent} "] + end + + # Inspect a IndexOrWriteNode node. + def visit_index_or_write_node(node) + commands << [inspect_node("IndexOrWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("safe_navigation" if node.safe_navigation?), ("variable_call" if node.variable_call?), ("attribute_write" if node.attribute_write?), ("ignore_visibility" if node.ignore_visibility?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (receiver = node.receiver).nil? + commands << ["├── receiver: ∅\n", indent] + else + commands << ["├── receiver:\n", indent] + commands << [receiver, "#{indent}│ "] + end + commands << ["├── call_operator_loc: #{inspect_location(node.call_operator_loc)}\n", indent] + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + if (arguments = node.arguments).nil? + commands << ["├── arguments: ∅\n", indent] + else + commands << ["├── arguments:\n", indent] + commands << [arguments, "#{indent}│ "] + end + commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + if (block = node.block).nil? + commands << ["├── block: ∅\n", indent] + else + commands << ["├── block:\n", indent] + commands << [block, "#{indent}│ "] + end + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["└── value:\n", indent] + commands << [node.value, "#{indent} "] + end + + # Inspect a IndexTargetNode node. + def visit_index_target_node(node) + commands << [inspect_node("IndexTargetNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("safe_navigation" if node.safe_navigation?), ("variable_call" if node.variable_call?), ("attribute_write" if node.attribute_write?), ("ignore_visibility" if node.ignore_visibility?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── receiver:\n", indent] + commands << [node.receiver, "#{indent}│ "] + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + if (arguments = node.arguments).nil? + commands << ["├── arguments: ∅\n", indent] + else + commands << ["├── arguments:\n", indent] + commands << [arguments, "#{indent}│ "] + end + commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + if (block = node.block).nil? + commands << ["└── block: ∅\n", indent] + else + commands << ["└── block:\n", indent] + commands << [block, "#{indent} "] + end + end + + # Inspect a InstanceVariableAndWriteNode node. + def visit_instance_variable_and_write_node(node) + commands << [inspect_node("InstanceVariableAndWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["└── value:\n", indent] + commands << [node.value, "#{indent} "] + end + + # Inspect a InstanceVariableOperatorWriteNode node. + def visit_instance_variable_operator_write_node(node) + commands << [inspect_node("InstanceVariableOperatorWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["├── binary_operator_loc: #{inspect_location(node.binary_operator_loc)}\n", indent] + commands << ["├── value:\n", indent] + commands << [node.value, "#{indent}│ "] + commands << ["└── binary_operator: #{node.binary_operator.inspect}\n", indent] + end + + # Inspect a InstanceVariableOrWriteNode node. + def visit_instance_variable_or_write_node(node) + commands << [inspect_node("InstanceVariableOrWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["└── value:\n", indent] + commands << [node.value, "#{indent} "] + end + + # Inspect a InstanceVariableReadNode node. + def visit_instance_variable_read_node(node) + commands << [inspect_node("InstanceVariableReadNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["└── name: #{node.name.inspect}\n", indent] + end + + # Inspect a InstanceVariableTargetNode node. + def visit_instance_variable_target_node(node) + commands << [inspect_node("InstanceVariableTargetNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["└── name: #{node.name.inspect}\n", indent] + end + + # Inspect a InstanceVariableWriteNode node. + def visit_instance_variable_write_node(node) + commands << [inspect_node("InstanceVariableWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["├── value:\n", indent] + commands << [node.value, "#{indent}│ "] + commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + end + + # Inspect a IntegerNode node. + def visit_integer_node(node) + commands << [inspect_node("IntegerNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("binary" if node.binary?), ("decimal" if node.decimal?), ("octal" if node.octal?), ("hexadecimal" if node.hexadecimal?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["└── value: #{node.value.inspect}\n", indent] + end + + # Inspect a InterpolatedMatchLastLineNode node. + def visit_interpolated_match_last_line_node(node) + commands << [inspect_node("InterpolatedMatchLastLineNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("ignore_case" if node.ignore_case?), ("extended" if node.extended?), ("multi_line" if node.multi_line?), ("once" if node.once?), ("euc_jp" if node.euc_jp?), ("ascii_8bit" if node.ascii_8bit?), ("windows_31j" if node.windows_31j?), ("utf_8" if node.utf_8?), ("forced_utf8_encoding" if node.forced_utf8_encoding?), ("forced_binary_encoding" if node.forced_binary_encoding?), ("forced_us_ascii_encoding" if node.forced_us_ascii_encoding?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + commands << ["├── parts: (length: #{(parts = node.parts).length})\n", indent] + if parts.any? + parts[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [parts[-1], "#{indent}│ "] + end + commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + end + + # Inspect a InterpolatedRegularExpressionNode node. + def visit_interpolated_regular_expression_node(node) + commands << [inspect_node("InterpolatedRegularExpressionNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("ignore_case" if node.ignore_case?), ("extended" if node.extended?), ("multi_line" if node.multi_line?), ("once" if node.once?), ("euc_jp" if node.euc_jp?), ("ascii_8bit" if node.ascii_8bit?), ("windows_31j" if node.windows_31j?), ("utf_8" if node.utf_8?), ("forced_utf8_encoding" if node.forced_utf8_encoding?), ("forced_binary_encoding" if node.forced_binary_encoding?), ("forced_us_ascii_encoding" if node.forced_us_ascii_encoding?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + commands << ["├── parts: (length: #{(parts = node.parts).length})\n", indent] + if parts.any? + parts[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [parts[-1], "#{indent}│ "] + end + commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + end + + # Inspect a InterpolatedStringNode node. + def visit_interpolated_string_node(node) + commands << [inspect_node("InterpolatedStringNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("frozen" if node.frozen?), ("mutable" if node.mutable?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + commands << ["├── parts: (length: #{(parts = node.parts).length})\n", indent] + if parts.any? + parts[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [parts[-1], "#{indent}│ "] + end + commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + end + + # Inspect a InterpolatedSymbolNode node. + def visit_interpolated_symbol_node(node) + commands << [inspect_node("InterpolatedSymbolNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + commands << ["├── parts: (length: #{(parts = node.parts).length})\n", indent] + if parts.any? + parts[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [parts[-1], "#{indent}│ "] + end + commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + end + + # Inspect a InterpolatedXStringNode node. + def visit_interpolated_x_string_node(node) + commands << [inspect_node("InterpolatedXStringNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + commands << ["├── parts: (length: #{(parts = node.parts).length})\n", indent] + if parts.any? + parts[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [parts[-1], "#{indent}│ "] + end + commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + end + + # Inspect a ItLocalVariableReadNode node. + def visit_it_local_variable_read_node(node) + commands << [inspect_node("ItLocalVariableReadNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + end + + # Inspect a ItParametersNode node. + def visit_it_parameters_node(node) + commands << [inspect_node("ItParametersNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + end + + # Inspect a KeywordHashNode node. + def visit_keyword_hash_node(node) + commands << [inspect_node("KeywordHashNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("symbol_keys" if node.symbol_keys?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["└── elements: (length: #{(elements = node.elements).length})\n", indent] + if elements.any? + elements[0...-1].each do |child| + commands << [Replace.new("#{indent} ├── "), indent] + commands << [child, "#{indent} │ "] + end + commands << [Replace.new("#{indent} └── "), indent] + commands << [elements[-1], "#{indent} "] + end + end + + # Inspect a KeywordRestParameterNode node. + def visit_keyword_rest_parameter_node(node) + commands << [inspect_node("KeywordRestParameterNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("repeated_parameter" if node.repeated_parameter?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (name = node.name).nil? + commands << ["├── name: ∅\n", indent] + else + commands << ["├── name: #{name.inspect}\n", indent] + end + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + end + + # Inspect a LambdaNode node. + def visit_lambda_node(node) + commands << [inspect_node("LambdaNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── locals: #{node.locals.inspect}\n", indent] + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + if (parameters = node.parameters).nil? + commands << ["├── parameters: ∅\n", indent] + else + commands << ["├── parameters:\n", indent] + commands << [parameters, "#{indent}│ "] + end + if (body = node.body).nil? + commands << ["└── body: ∅\n", indent] + else + commands << ["└── body:\n", indent] + commands << [body, "#{indent} "] + end + end + + # Inspect a LocalVariableAndWriteNode node. + def visit_local_variable_and_write_node(node) + commands << [inspect_node("LocalVariableAndWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["├── value:\n", indent] + commands << [node.value, "#{indent}│ "] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["└── depth: #{node.depth.inspect}\n", indent] + end + + # Inspect a LocalVariableOperatorWriteNode node. + def visit_local_variable_operator_write_node(node) + commands << [inspect_node("LocalVariableOperatorWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["├── binary_operator_loc: #{inspect_location(node.binary_operator_loc)}\n", indent] + commands << ["├── value:\n", indent] + commands << [node.value, "#{indent}│ "] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["├── binary_operator: #{node.binary_operator.inspect}\n", indent] + commands << ["└── depth: #{node.depth.inspect}\n", indent] + end + + # Inspect a LocalVariableOrWriteNode node. + def visit_local_variable_or_write_node(node) + commands << [inspect_node("LocalVariableOrWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["├── value:\n", indent] + commands << [node.value, "#{indent}│ "] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["└── depth: #{node.depth.inspect}\n", indent] + end + + # Inspect a LocalVariableReadNode node. + def visit_local_variable_read_node(node) + commands << [inspect_node("LocalVariableReadNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["└── depth: #{node.depth.inspect}\n", indent] + end + + # Inspect a LocalVariableTargetNode node. + def visit_local_variable_target_node(node) + commands << [inspect_node("LocalVariableTargetNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["└── depth: #{node.depth.inspect}\n", indent] + end + + # Inspect a LocalVariableWriteNode node. + def visit_local_variable_write_node(node) + commands << [inspect_node("LocalVariableWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["├── depth: #{node.depth.inspect}\n", indent] + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["├── value:\n", indent] + commands << [node.value, "#{indent}│ "] + commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + end + + # Inspect a MatchLastLineNode node. + def visit_match_last_line_node(node) + commands << [inspect_node("MatchLastLineNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("ignore_case" if node.ignore_case?), ("extended" if node.extended?), ("multi_line" if node.multi_line?), ("once" if node.once?), ("euc_jp" if node.euc_jp?), ("ascii_8bit" if node.ascii_8bit?), ("windows_31j" if node.windows_31j?), ("utf_8" if node.utf_8?), ("forced_utf8_encoding" if node.forced_utf8_encoding?), ("forced_binary_encoding" if node.forced_binary_encoding?), ("forced_us_ascii_encoding" if node.forced_us_ascii_encoding?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + commands << ["├── content_loc: #{inspect_location(node.content_loc)}\n", indent] + commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + commands << ["└── unescaped: #{node.unescaped.inspect}\n", indent] + end + + # Inspect a MatchPredicateNode node. + def visit_match_predicate_node(node) + commands << [inspect_node("MatchPredicateNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── value:\n", indent] + commands << [node.value, "#{indent}│ "] + commands << ["├── pattern:\n", indent] + commands << [node.pattern, "#{indent}│ "] + commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + end + + # Inspect a MatchRequiredNode node. + def visit_match_required_node(node) + commands << [inspect_node("MatchRequiredNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── value:\n", indent] + commands << [node.value, "#{indent}│ "] + commands << ["├── pattern:\n", indent] + commands << [node.pattern, "#{indent}│ "] + commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + end + + # Inspect a MatchWriteNode node. + def visit_match_write_node(node) + commands << [inspect_node("MatchWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── call:\n", indent] + commands << [node.call, "#{indent}│ "] + commands << ["└── targets: (length: #{(targets = node.targets).length})\n", indent] + if targets.any? + targets[0...-1].each do |child| + commands << [Replace.new("#{indent} ├── "), indent] + commands << [child, "#{indent} │ "] + end + commands << [Replace.new("#{indent} └── "), indent] + commands << [targets[-1], "#{indent} "] + end + end + + # Inspect a MissingNode node. + def visit_missing_node(node) + commands << [inspect_node("MissingNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + end + + # Inspect a ModuleNode node. + def visit_module_node(node) + commands << [inspect_node("ModuleNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── locals: #{node.locals.inspect}\n", indent] + commands << ["├── module_keyword_loc: #{inspect_location(node.module_keyword_loc)}\n", indent] + commands << ["├── constant_path:\n", indent] + commands << [node.constant_path, "#{indent}│ "] + if (body = node.body).nil? + commands << ["├── body: ∅\n", indent] + else + commands << ["├── body:\n", indent] + commands << [body, "#{indent}│ "] + end + commands << ["├── end_keyword_loc: #{inspect_location(node.end_keyword_loc)}\n", indent] + commands << ["└── name: #{node.name.inspect}\n", indent] + end + + # Inspect a MultiTargetNode node. + def visit_multi_target_node(node) + commands << [inspect_node("MultiTargetNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── lefts: (length: #{(lefts = node.lefts).length})\n", indent] + if lefts.any? + lefts[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [lefts[-1], "#{indent}│ "] + end + if (rest = node.rest).nil? + commands << ["├── rest: ∅\n", indent] + else + commands << ["├── rest:\n", indent] + commands << [rest, "#{indent}│ "] + end + commands << ["├── rights: (length: #{(rights = node.rights).length})\n", indent] + if rights.any? + rights[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [rights[-1], "#{indent}│ "] + end + commands << ["├── lparen_loc: #{inspect_location(node.lparen_loc)}\n", indent] + commands << ["└── rparen_loc: #{inspect_location(node.rparen_loc)}\n", indent] + end + + # Inspect a MultiWriteNode node. + def visit_multi_write_node(node) + commands << [inspect_node("MultiWriteNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── lefts: (length: #{(lefts = node.lefts).length})\n", indent] + if lefts.any? + lefts[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [lefts[-1], "#{indent}│ "] + end + if (rest = node.rest).nil? + commands << ["├── rest: ∅\n", indent] + else + commands << ["├── rest:\n", indent] + commands << [rest, "#{indent}│ "] + end + commands << ["├── rights: (length: #{(rights = node.rights).length})\n", indent] + if rights.any? + rights[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [rights[-1], "#{indent}│ "] + end + commands << ["├── lparen_loc: #{inspect_location(node.lparen_loc)}\n", indent] + commands << ["├── rparen_loc: #{inspect_location(node.rparen_loc)}\n", indent] + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["└── value:\n", indent] + commands << [node.value, "#{indent} "] + end + + # Inspect a NextNode node. + def visit_next_node(node) + commands << [inspect_node("NextNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (arguments = node.arguments).nil? + commands << ["├── arguments: ∅\n", indent] + else + commands << ["├── arguments:\n", indent] + commands << [arguments, "#{indent}│ "] + end + commands << ["└── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent] + end + + # Inspect a NilNode node. + def visit_nil_node(node) + commands << [inspect_node("NilNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + end + + # Inspect a NoKeywordsParameterNode node. + def visit_no_keywords_parameter_node(node) + commands << [inspect_node("NoKeywordsParameterNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["└── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent] + end + + # Inspect a NumberedParametersNode node. + def visit_numbered_parameters_node(node) + commands << [inspect_node("NumberedParametersNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["└── maximum: #{node.maximum.inspect}\n", indent] + end + + # Inspect a NumberedReferenceReadNode node. + def visit_numbered_reference_read_node(node) + commands << [inspect_node("NumberedReferenceReadNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["└── number: #{node.number.inspect}\n", indent] + end + + # Inspect a OptionalKeywordParameterNode node. + def visit_optional_keyword_parameter_node(node) + commands << [inspect_node("OptionalKeywordParameterNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("repeated_parameter" if node.repeated_parameter?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["└── value:\n", indent] + commands << [node.value, "#{indent} "] + end + + # Inspect a OptionalParameterNode node. + def visit_optional_parameter_node(node) + commands << [inspect_node("OptionalParameterNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("repeated_parameter" if node.repeated_parameter?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["└── value:\n", indent] + commands << [node.value, "#{indent} "] + end + + # Inspect a OrNode node. + def visit_or_node(node) + commands << [inspect_node("OrNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── left:\n", indent] + commands << [node.left, "#{indent}│ "] + commands << ["├── right:\n", indent] + commands << [node.right, "#{indent}│ "] + commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + end + + # Inspect a ParametersNode node. + def visit_parameters_node(node) + commands << [inspect_node("ParametersNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── requireds: (length: #{(requireds = node.requireds).length})\n", indent] + if requireds.any? + requireds[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [requireds[-1], "#{indent}│ "] + end + commands << ["├── optionals: (length: #{(optionals = node.optionals).length})\n", indent] + if optionals.any? + optionals[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [optionals[-1], "#{indent}│ "] + end + if (rest = node.rest).nil? + commands << ["├── rest: ∅\n", indent] + else + commands << ["├── rest:\n", indent] + commands << [rest, "#{indent}│ "] + end + commands << ["├── posts: (length: #{(posts = node.posts).length})\n", indent] + if posts.any? + posts[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [posts[-1], "#{indent}│ "] + end + commands << ["├── keywords: (length: #{(keywords = node.keywords).length})\n", indent] + if keywords.any? + keywords[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [keywords[-1], "#{indent}│ "] + end + if (keyword_rest = node.keyword_rest).nil? + commands << ["├── keyword_rest: ∅\n", indent] + else + commands << ["├── keyword_rest:\n", indent] + commands << [keyword_rest, "#{indent}│ "] + end + if (block = node.block).nil? + commands << ["└── block: ∅\n", indent] + else + commands << ["└── block:\n", indent] + commands << [block, "#{indent} "] + end + end + + # Inspect a ParenthesesNode node. + def visit_parentheses_node(node) + commands << [inspect_node("ParenthesesNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("multiple_statements" if node.multiple_statements?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (body = node.body).nil? + commands << ["├── body: ∅\n", indent] + else + commands << ["├── body:\n", indent] + commands << [body, "#{indent}│ "] + end + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + end + + # Inspect a PinnedExpressionNode node. + def visit_pinned_expression_node(node) + commands << [inspect_node("PinnedExpressionNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── expression:\n", indent] + commands << [node.expression, "#{indent}│ "] + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["├── lparen_loc: #{inspect_location(node.lparen_loc)}\n", indent] + commands << ["└── rparen_loc: #{inspect_location(node.rparen_loc)}\n", indent] + end + + # Inspect a PinnedVariableNode node. + def visit_pinned_variable_node(node) + commands << [inspect_node("PinnedVariableNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── variable:\n", indent] + commands << [node.variable, "#{indent}│ "] + commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + end + + # Inspect a PostExecutionNode node. + def visit_post_execution_node(node) + commands << [inspect_node("PostExecutionNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (statements = node.statements).nil? + commands << ["├── statements: ∅\n", indent] + else + commands << ["├── statements:\n", indent] + commands << [statements, "#{indent}│ "] + end + commands << ["├── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent] + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + end + + # Inspect a PreExecutionNode node. + def visit_pre_execution_node(node) + commands << [inspect_node("PreExecutionNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (statements = node.statements).nil? + commands << ["├── statements: ∅\n", indent] + else + commands << ["├── statements:\n", indent] + commands << [statements, "#{indent}│ "] + end + commands << ["├── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent] + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + commands << ["└── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + end + + # Inspect a ProgramNode node. + def visit_program_node(node) + commands << [inspect_node("ProgramNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── locals: #{node.locals.inspect}\n", indent] + commands << ["└── statements:\n", indent] + commands << [node.statements, "#{indent} "] + end + + # Inspect a RangeNode node. + def visit_range_node(node) + commands << [inspect_node("RangeNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("exclude_end" if node.exclude_end?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (left = node.left).nil? + commands << ["├── left: ∅\n", indent] + else + commands << ["├── left:\n", indent] + commands << [left, "#{indent}│ "] + end + if (right = node.right).nil? + commands << ["├── right: ∅\n", indent] + else + commands << ["├── right:\n", indent] + commands << [right, "#{indent}│ "] + end + commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + end + + # Inspect a RationalNode node. + def visit_rational_node(node) + commands << [inspect_node("RationalNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("binary" if node.binary?), ("decimal" if node.decimal?), ("octal" if node.octal?), ("hexadecimal" if node.hexadecimal?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── numerator: #{node.numerator.inspect}\n", indent] + commands << ["└── denominator: #{node.denominator.inspect}\n", indent] + end + + # Inspect a RedoNode node. + def visit_redo_node(node) + commands << [inspect_node("RedoNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + end + + # Inspect a RegularExpressionNode node. + def visit_regular_expression_node(node) + commands << [inspect_node("RegularExpressionNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("ignore_case" if node.ignore_case?), ("extended" if node.extended?), ("multi_line" if node.multi_line?), ("once" if node.once?), ("euc_jp" if node.euc_jp?), ("ascii_8bit" if node.ascii_8bit?), ("windows_31j" if node.windows_31j?), ("utf_8" if node.utf_8?), ("forced_utf8_encoding" if node.forced_utf8_encoding?), ("forced_binary_encoding" if node.forced_binary_encoding?), ("forced_us_ascii_encoding" if node.forced_us_ascii_encoding?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + commands << ["├── content_loc: #{inspect_location(node.content_loc)}\n", indent] + commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + commands << ["└── unescaped: #{node.unescaped.inspect}\n", indent] + end + + # Inspect a RequiredKeywordParameterNode node. + def visit_required_keyword_parameter_node(node) + commands << [inspect_node("RequiredKeywordParameterNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("repeated_parameter" if node.repeated_parameter?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── name: #{node.name.inspect}\n", indent] + commands << ["└── name_loc: #{inspect_location(node.name_loc)}\n", indent] + end + + # Inspect a RequiredParameterNode node. + def visit_required_parameter_node(node) + commands << [inspect_node("RequiredParameterNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("repeated_parameter" if node.repeated_parameter?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["└── name: #{node.name.inspect}\n", indent] + end + + # Inspect a RescueModifierNode node. + def visit_rescue_modifier_node(node) + commands << [inspect_node("RescueModifierNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── expression:\n", indent] + commands << [node.expression, "#{indent}│ "] + commands << ["├── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent] + commands << ["└── rescue_expression:\n", indent] + commands << [node.rescue_expression, "#{indent} "] + end + + # Inspect a RescueNode node. + def visit_rescue_node(node) + commands << [inspect_node("RescueNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent] + commands << ["├── exceptions: (length: #{(exceptions = node.exceptions).length})\n", indent] + if exceptions.any? + exceptions[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [exceptions[-1], "#{indent}│ "] + end + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + if (reference = node.reference).nil? + commands << ["├── reference: ∅\n", indent] + else + commands << ["├── reference:\n", indent] + commands << [reference, "#{indent}│ "] + end + commands << ["├── then_keyword_loc: #{inspect_location(node.then_keyword_loc)}\n", indent] + if (statements = node.statements).nil? + commands << ["├── statements: ∅\n", indent] + else + commands << ["├── statements:\n", indent] + commands << [statements, "#{indent}│ "] + end + if (subsequent = node.subsequent).nil? + commands << ["└── subsequent: ∅\n", indent] + else + commands << ["└── subsequent:\n", indent] + commands << [subsequent, "#{indent} "] + end + end + + # Inspect a RestParameterNode node. + def visit_rest_parameter_node(node) + commands << [inspect_node("RestParameterNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("repeated_parameter" if node.repeated_parameter?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + if (name = node.name).nil? + commands << ["├── name: ∅\n", indent] + else + commands << ["├── name: #{name.inspect}\n", indent] + end + commands << ["├── name_loc: #{inspect_location(node.name_loc)}\n", indent] + commands << ["└── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + end + + # Inspect a RetryNode node. + def visit_retry_node(node) + commands << [inspect_node("RetryNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + end + + # Inspect a ReturnNode node. + def visit_return_node(node) + commands << [inspect_node("ReturnNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent] + if (arguments = node.arguments).nil? + commands << ["└── arguments: ∅\n", indent] + else + commands << ["└── arguments:\n", indent] + commands << [arguments, "#{indent} "] + end + end + + # Inspect a SelfNode node. + def visit_self_node(node) + commands << [inspect_node("SelfNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + end + + # Inspect a ShareableConstantNode node. + def visit_shareable_constant_node(node) + commands << [inspect_node("ShareableConstantNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("literal" if node.literal?), ("experimental_everything" if node.experimental_everything?), ("experimental_copy" if node.experimental_copy?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["└── write:\n", indent] + commands << [node.write, "#{indent} "] + end + + # Inspect a SingletonClassNode node. + def visit_singleton_class_node(node) + commands << [inspect_node("SingletonClassNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── locals: #{node.locals.inspect}\n", indent] + commands << ["├── class_keyword_loc: #{inspect_location(node.class_keyword_loc)}\n", indent] + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + commands << ["├── expression:\n", indent] + commands << [node.expression, "#{indent}│ "] + if (body = node.body).nil? + commands << ["├── body: ∅\n", indent] + else + commands << ["├── body:\n", indent] + commands << [body, "#{indent}│ "] + end + commands << ["└── end_keyword_loc: #{inspect_location(node.end_keyword_loc)}\n", indent] + end + + # Inspect a SourceEncodingNode node. + def visit_source_encoding_node(node) + commands << [inspect_node("SourceEncodingNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + end + + # Inspect a SourceFileNode node. + def visit_source_file_node(node) + commands << [inspect_node("SourceFileNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("forced_utf8_encoding" if node.forced_utf8_encoding?), ("forced_binary_encoding" if node.forced_binary_encoding?), ("frozen" if node.frozen?), ("mutable" if node.mutable?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["└── filepath: #{node.filepath.inspect}\n", indent] + end + + # Inspect a SourceLineNode node. + def visit_source_line_node(node) + commands << [inspect_node("SourceLineNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + end + + # Inspect a SplatNode node. + def visit_splat_node(node) + commands << [inspect_node("SplatNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── operator_loc: #{inspect_location(node.operator_loc)}\n", indent] + if (expression = node.expression).nil? + commands << ["└── expression: ∅\n", indent] + else + commands << ["└── expression:\n", indent] + commands << [expression, "#{indent} "] + end + end + + # Inspect a StatementsNode node. + def visit_statements_node(node) + commands << [inspect_node("StatementsNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["└── body: (length: #{(body = node.body).length})\n", indent] + if body.any? + body[0...-1].each do |child| + commands << [Replace.new("#{indent} ├── "), indent] + commands << [child, "#{indent} │ "] + end + commands << [Replace.new("#{indent} └── "), indent] + commands << [body[-1], "#{indent} "] + end + end + + # Inspect a StringNode node. + def visit_string_node(node) + commands << [inspect_node("StringNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("forced_utf8_encoding" if node.forced_utf8_encoding?), ("forced_binary_encoding" if node.forced_binary_encoding?), ("frozen" if node.frozen?), ("mutable" if node.mutable?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + commands << ["├── content_loc: #{inspect_location(node.content_loc)}\n", indent] + commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + commands << ["└── unescaped: #{node.unescaped.inspect}\n", indent] + end + + # Inspect a SuperNode node. + def visit_super_node(node) + commands << [inspect_node("SuperNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent] + commands << ["├── lparen_loc: #{inspect_location(node.lparen_loc)}\n", indent] + if (arguments = node.arguments).nil? + commands << ["├── arguments: ∅\n", indent] + else + commands << ["├── arguments:\n", indent] + commands << [arguments, "#{indent}│ "] + end + commands << ["├── rparen_loc: #{inspect_location(node.rparen_loc)}\n", indent] + if (block = node.block).nil? + commands << ["└── block: ∅\n", indent] + else + commands << ["└── block:\n", indent] + commands << [block, "#{indent} "] + end + end + + # Inspect a SymbolNode node. + def visit_symbol_node(node) + commands << [inspect_node("SymbolNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("forced_utf8_encoding" if node.forced_utf8_encoding?), ("forced_binary_encoding" if node.forced_binary_encoding?), ("forced_us_ascii_encoding" if node.forced_us_ascii_encoding?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + commands << ["├── value_loc: #{inspect_location(node.value_loc)}\n", indent] + commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + commands << ["└── unescaped: #{node.unescaped.inspect}\n", indent] + end + + # Inspect a TrueNode node. + def visit_true_node(node) + commands << [inspect_node("TrueNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["└── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + end + + # Inspect a UndefNode node. + def visit_undef_node(node) + commands << [inspect_node("UndefNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── names: (length: #{(names = node.names).length})\n", indent] + if names.any? + names[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [names[-1], "#{indent}│ "] + end + commands << ["└── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent] + end + + # Inspect a UnlessNode node. + def visit_unless_node(node) + commands << [inspect_node("UnlessNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent] + commands << ["├── predicate:\n", indent] + commands << [node.predicate, "#{indent}│ "] + commands << ["├── then_keyword_loc: #{inspect_location(node.then_keyword_loc)}\n", indent] + if (statements = node.statements).nil? + commands << ["├── statements: ∅\n", indent] + else + commands << ["├── statements:\n", indent] + commands << [statements, "#{indent}│ "] + end + if (else_clause = node.else_clause).nil? + commands << ["├── else_clause: ∅\n", indent] + else + commands << ["├── else_clause:\n", indent] + commands << [else_clause, "#{indent}│ "] + end + commands << ["└── end_keyword_loc: #{inspect_location(node.end_keyword_loc)}\n", indent] + end + + # Inspect a UntilNode node. + def visit_until_node(node) + commands << [inspect_node("UntilNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("begin_modifier" if node.begin_modifier?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent] + commands << ["├── do_keyword_loc: #{inspect_location(node.do_keyword_loc)}\n", indent] + commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + commands << ["├── predicate:\n", indent] + commands << [node.predicate, "#{indent}│ "] + if (statements = node.statements).nil? + commands << ["└── statements: ∅\n", indent] + else + commands << ["└── statements:\n", indent] + commands << [statements, "#{indent} "] + end + end + + # Inspect a WhenNode node. + def visit_when_node(node) + commands << [inspect_node("WhenNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent] + commands << ["├── conditions: (length: #{(conditions = node.conditions).length})\n", indent] + if conditions.any? + conditions[0...-1].each do |child| + commands << [Replace.new("#{indent}│ ├── "), indent] + commands << [child, "#{indent}│ │ "] + end + commands << [Replace.new("#{indent}│ └── "), indent] + commands << [conditions[-1], "#{indent}│ "] + end + commands << ["├── then_keyword_loc: #{inspect_location(node.then_keyword_loc)}\n", indent] + if (statements = node.statements).nil? + commands << ["└── statements: ∅\n", indent] + else + commands << ["└── statements:\n", indent] + commands << [statements, "#{indent} "] + end + end + + # Inspect a WhileNode node. + def visit_while_node(node) + commands << [inspect_node("WhileNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("begin_modifier" if node.begin_modifier?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent] + commands << ["├── do_keyword_loc: #{inspect_location(node.do_keyword_loc)}\n", indent] + commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + commands << ["├── predicate:\n", indent] + commands << [node.predicate, "#{indent}│ "] + if (statements = node.statements).nil? + commands << ["└── statements: ∅\n", indent] + else + commands << ["└── statements:\n", indent] + commands << [statements, "#{indent} "] + end + end + + # Inspect a XStringNode node. + def visit_x_string_node(node) + commands << [inspect_node("XStringNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ("forced_utf8_encoding" if node.forced_utf8_encoding?), ("forced_binary_encoding" if node.forced_binary_encoding?)].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── opening_loc: #{inspect_location(node.opening_loc)}\n", indent] + commands << ["├── content_loc: #{inspect_location(node.content_loc)}\n", indent] + commands << ["├── closing_loc: #{inspect_location(node.closing_loc)}\n", indent] + commands << ["└── unescaped: #{node.unescaped.inspect}\n", indent] + end + + # Inspect a YieldNode node. + def visit_yield_node(node) + commands << [inspect_node("YieldNode", node), indent] + flags = [("newline" if node.newline?), ("static_literal" if node.static_literal?), ].compact + commands << ["├── flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent] + commands << ["├── keyword_loc: #{inspect_location(node.keyword_loc)}\n", indent] + commands << ["├── lparen_loc: #{inspect_location(node.lparen_loc)}\n", indent] + if (arguments = node.arguments).nil? + commands << ["├── arguments: ∅\n", indent] + else + commands << ["├── arguments:\n", indent] + commands << [arguments, "#{indent}│ "] + end + commands << ["└── rparen_loc: #{inspect_location(node.rparen_loc)}\n", indent] + end + + private + + # Compose a header for the given node. + def inspect_node(name, node) + location = node.location + "@ #{name} (location: (#{location.start_line},#{location.start_column})-(#{location.end_line},#{location.end_column}))\n" + end + + # Compose a string representing the given inner location field. + def inspect_location(location) + if location + "(#{location.start_line},#{location.start_column})-(#{location.end_line},#{location.end_column}) = #{location.slice.inspect}" + else + "∅" + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/lex_compat.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/lex_compat.rb new file mode 100644 index 00000000..a83c24cb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/lex_compat.rb @@ -0,0 +1,927 @@ +# frozen_string_literal: true + +require "delegate" +require "ripper" + +module Prism + # This class is responsible for lexing the source using prism and then + # converting those tokens to be compatible with Ripper. In the vast majority + # of cases, this is a one-to-one mapping of the token type. Everything else + # generally lines up. However, there are a few cases that require special + # handling. + class LexCompat # :nodoc: + # A result class specialized for holding tokens produced by the lexer. + class Result < Prism::Result + # The list of tokens that were produced by the lexer. + attr_reader :value + + # Create a new lex compat result object with the given values. + def initialize(value, comments, magic_comments, data_loc, errors, warnings, source) + @value = value + super(comments, magic_comments, data_loc, errors, warnings, source) + end + + # Implement the hash pattern matching interface for Result. + def deconstruct_keys(keys) + super.merge!(value: value) + end + end + + # This is a mapping of prism token types to Ripper token types. This is a + # many-to-one mapping because we split up our token types, whereas Ripper + # tends to group them. + RIPPER = { + AMPERSAND: :on_op, + AMPERSAND_AMPERSAND: :on_op, + AMPERSAND_AMPERSAND_EQUAL: :on_op, + AMPERSAND_DOT: :on_op, + AMPERSAND_EQUAL: :on_op, + BACK_REFERENCE: :on_backref, + BACKTICK: :on_backtick, + BANG: :on_op, + BANG_EQUAL: :on_op, + BANG_TILDE: :on_op, + BRACE_LEFT: :on_lbrace, + BRACE_RIGHT: :on_rbrace, + BRACKET_LEFT: :on_lbracket, + BRACKET_LEFT_ARRAY: :on_lbracket, + BRACKET_LEFT_RIGHT: :on_op, + BRACKET_LEFT_RIGHT_EQUAL: :on_op, + BRACKET_RIGHT: :on_rbracket, + CARET: :on_op, + CARET_EQUAL: :on_op, + CHARACTER_LITERAL: :on_CHAR, + CLASS_VARIABLE: :on_cvar, + COLON: :on_op, + COLON_COLON: :on_op, + COMMA: :on_comma, + COMMENT: :on_comment, + CONSTANT: :on_const, + DOT: :on_period, + DOT_DOT: :on_op, + DOT_DOT_DOT: :on_op, + EMBDOC_BEGIN: :on_embdoc_beg, + EMBDOC_END: :on_embdoc_end, + EMBDOC_LINE: :on_embdoc, + EMBEXPR_BEGIN: :on_embexpr_beg, + EMBEXPR_END: :on_embexpr_end, + EMBVAR: :on_embvar, + EOF: :on_eof, + EQUAL: :on_op, + EQUAL_EQUAL: :on_op, + EQUAL_EQUAL_EQUAL: :on_op, + EQUAL_GREATER: :on_op, + EQUAL_TILDE: :on_op, + FLOAT: :on_float, + FLOAT_IMAGINARY: :on_imaginary, + FLOAT_RATIONAL: :on_rational, + FLOAT_RATIONAL_IMAGINARY: :on_imaginary, + GREATER: :on_op, + GREATER_EQUAL: :on_op, + GREATER_GREATER: :on_op, + GREATER_GREATER_EQUAL: :on_op, + GLOBAL_VARIABLE: :on_gvar, + HEREDOC_END: :on_heredoc_end, + HEREDOC_START: :on_heredoc_beg, + IDENTIFIER: :on_ident, + IGNORED_NEWLINE: :on_ignored_nl, + INTEGER: :on_int, + INTEGER_IMAGINARY: :on_imaginary, + INTEGER_RATIONAL: :on_rational, + INTEGER_RATIONAL_IMAGINARY: :on_imaginary, + INSTANCE_VARIABLE: :on_ivar, + INVALID: :INVALID, + KEYWORD___ENCODING__: :on_kw, + KEYWORD___LINE__: :on_kw, + KEYWORD___FILE__: :on_kw, + KEYWORD_ALIAS: :on_kw, + KEYWORD_AND: :on_kw, + KEYWORD_BEGIN: :on_kw, + KEYWORD_BEGIN_UPCASE: :on_kw, + KEYWORD_BREAK: :on_kw, + KEYWORD_CASE: :on_kw, + KEYWORD_CLASS: :on_kw, + KEYWORD_DEF: :on_kw, + KEYWORD_DEFINED: :on_kw, + KEYWORD_DO: :on_kw, + KEYWORD_DO_LOOP: :on_kw, + KEYWORD_ELSE: :on_kw, + KEYWORD_ELSIF: :on_kw, + KEYWORD_END: :on_kw, + KEYWORD_END_UPCASE: :on_kw, + KEYWORD_ENSURE: :on_kw, + KEYWORD_FALSE: :on_kw, + KEYWORD_FOR: :on_kw, + KEYWORD_IF: :on_kw, + KEYWORD_IF_MODIFIER: :on_kw, + KEYWORD_IN: :on_kw, + KEYWORD_MODULE: :on_kw, + KEYWORD_NEXT: :on_kw, + KEYWORD_NIL: :on_kw, + KEYWORD_NOT: :on_kw, + KEYWORD_OR: :on_kw, + KEYWORD_REDO: :on_kw, + KEYWORD_RESCUE: :on_kw, + KEYWORD_RESCUE_MODIFIER: :on_kw, + KEYWORD_RETRY: :on_kw, + KEYWORD_RETURN: :on_kw, + KEYWORD_SELF: :on_kw, + KEYWORD_SUPER: :on_kw, + KEYWORD_THEN: :on_kw, + KEYWORD_TRUE: :on_kw, + KEYWORD_UNDEF: :on_kw, + KEYWORD_UNLESS: :on_kw, + KEYWORD_UNLESS_MODIFIER: :on_kw, + KEYWORD_UNTIL: :on_kw, + KEYWORD_UNTIL_MODIFIER: :on_kw, + KEYWORD_WHEN: :on_kw, + KEYWORD_WHILE: :on_kw, + KEYWORD_WHILE_MODIFIER: :on_kw, + KEYWORD_YIELD: :on_kw, + LABEL: :on_label, + LABEL_END: :on_label_end, + LAMBDA_BEGIN: :on_tlambeg, + LESS: :on_op, + LESS_EQUAL: :on_op, + LESS_EQUAL_GREATER: :on_op, + LESS_LESS: :on_op, + LESS_LESS_EQUAL: :on_op, + METHOD_NAME: :on_ident, + MINUS: :on_op, + MINUS_EQUAL: :on_op, + MINUS_GREATER: :on_tlambda, + NEWLINE: :on_nl, + NUMBERED_REFERENCE: :on_backref, + PARENTHESIS_LEFT: :on_lparen, + PARENTHESIS_LEFT_PARENTHESES: :on_lparen, + PARENTHESIS_RIGHT: :on_rparen, + PERCENT: :on_op, + PERCENT_EQUAL: :on_op, + PERCENT_LOWER_I: :on_qsymbols_beg, + PERCENT_LOWER_W: :on_qwords_beg, + PERCENT_LOWER_X: :on_backtick, + PERCENT_UPPER_I: :on_symbols_beg, + PERCENT_UPPER_W: :on_words_beg, + PIPE: :on_op, + PIPE_EQUAL: :on_op, + PIPE_PIPE: :on_op, + PIPE_PIPE_EQUAL: :on_op, + PLUS: :on_op, + PLUS_EQUAL: :on_op, + QUESTION_MARK: :on_op, + RATIONAL_FLOAT: :on_rational, + RATIONAL_INTEGER: :on_rational, + REGEXP_BEGIN: :on_regexp_beg, + REGEXP_END: :on_regexp_end, + SEMICOLON: :on_semicolon, + SLASH: :on_op, + SLASH_EQUAL: :on_op, + STAR: :on_op, + STAR_EQUAL: :on_op, + STAR_STAR: :on_op, + STAR_STAR_EQUAL: :on_op, + STRING_BEGIN: :on_tstring_beg, + STRING_CONTENT: :on_tstring_content, + STRING_END: :on_tstring_end, + SYMBOL_BEGIN: :on_symbeg, + TILDE: :on_op, + UAMPERSAND: :on_op, + UCOLON_COLON: :on_op, + UDOT_DOT: :on_op, + UDOT_DOT_DOT: :on_op, + UMINUS: :on_op, + UMINUS_NUM: :on_op, + UPLUS: :on_op, + USTAR: :on_op, + USTAR_STAR: :on_op, + WORDS_SEP: :on_words_sep, + "__END__": :on___end__ + }.freeze + + # When we produce tokens, we produce the same arrays that Ripper does. + # However, we add a couple of convenience methods onto them to make them a + # little easier to work with. We delegate all other methods to the array. + class Token < SimpleDelegator + # @dynamic initialize, each, [] + + # The location of the token in the source. + def location + self[0] + end + + # The type of the token. + def event + self[1] + end + + # The slice of the source that this token represents. + def value + self[2] + end + + # The state of the lexer when this token was produced. + def state + self[3] + end + end + + # Ripper doesn't include the rest of the token in the event, so we need to + # trim it down to just the content on the first line when comparing. + class EndContentToken < Token + def ==(other) # :nodoc: + [self[0], self[1], self[2][0..self[2].index("\n")], self[3]] == other + end + end + + # Tokens where state should be ignored + # used for :on_comment, :on_heredoc_end, :on_embexpr_end + class IgnoreStateToken < Token + def ==(other) # :nodoc: + self[0...-1] == other[0...-1] + end + end + + # Ident tokens for the most part are exactly the same, except sometimes we + # know an ident is a local when ripper doesn't (when they are introduced + # through named captures in regular expressions). In that case we don't + # compare the state. + class IdentToken < Token + def ==(other) # :nodoc: + (self[0...-1] == other[0...-1]) && ( + (other[3] == Ripper::EXPR_LABEL | Ripper::EXPR_END) || + (other[3] & Ripper::EXPR_ARG_ANY != 0) + ) + end + end + + # Ignored newlines can occasionally have a LABEL state attached to them, so + # we compare the state differently here. + class IgnoredNewlineToken < Token + def ==(other) # :nodoc: + return false unless self[0...-1] == other[0...-1] + + if self[3] == Ripper::EXPR_ARG | Ripper::EXPR_LABELED + other[3] & Ripper::EXPR_ARG | Ripper::EXPR_LABELED != 0 + else + self[3] == other[3] + end + end + end + + # If we have an identifier that follows a method name like: + # + # def foo bar + # + # then Ripper will mark bar as END|LABEL if there is a local in a parent + # scope named bar because it hasn't pushed the local table yet. We do this + # more accurately, so we need to allow comparing against both END and + # END|LABEL. + class ParamToken < Token + def ==(other) # :nodoc: + (self[0...-1] == other[0...-1]) && ( + (other[3] == Ripper::EXPR_END) || + (other[3] == Ripper::EXPR_END | Ripper::EXPR_LABEL) + ) + end + end + + # A heredoc in this case is a list of tokens that belong to the body of the + # heredoc that should be appended onto the list of tokens when the heredoc + # closes. + module Heredoc # :nodoc: + # Heredocs that are no dash or tilde heredocs are just a list of tokens. + # We need to keep them around so that we can insert them in the correct + # order back into the token stream and set the state of the last token to + # the state that the heredoc was opened in. + class PlainHeredoc # :nodoc: + attr_reader :tokens + + def initialize + @tokens = [] + end + + def <<(token) + tokens << token + end + + def to_a + tokens + end + end + + # Dash heredocs are a little more complicated. They are a list of tokens + # that need to be split on "\\\n" to mimic Ripper's behavior. We also need + # to keep track of the state that the heredoc was opened in. + class DashHeredoc # :nodoc: + attr_reader :split, :tokens + + def initialize(split) + @split = split + @tokens = [] + end + + def <<(token) + tokens << token + end + + def to_a + embexpr_balance = 0 + + tokens.each_with_object([]) do |token, results| #$ Array[Token] + case token.event + when :on_embexpr_beg + embexpr_balance += 1 + results << token + when :on_embexpr_end + embexpr_balance -= 1 + results << token + when :on_tstring_content + if embexpr_balance == 0 + lineno = token[0][0] + column = token[0][1] + + if split + # Split on "\\\n" to mimic Ripper's behavior. Use a lookbehind + # to keep the delimiter in the result. + token.value.split(/(?<=[^\\]\\\n)|(?<=[^\\]\\\r\n)/).each_with_index do |value, index| + column = 0 if index > 0 + results << Token.new([[lineno, column], :on_tstring_content, value, token.state]) + lineno += value.count("\n") + end + else + results << token + end + else + results << token + end + else + results << token + end + end + end + end + + # Heredocs that are dedenting heredocs are a little more complicated. + # Ripper outputs on_ignored_sp tokens for the whitespace that is being + # removed from the output. prism only modifies the node itself and keeps + # the token the same. This simplifies prism, but makes comparing against + # Ripper much harder because there is a length mismatch. + # + # Fortunately, we already have to pull out the heredoc tokens in order to + # insert them into the stream in the correct order. As such, we can do + # some extra manipulation on the tokens to make them match Ripper's + # output by mirroring the dedent logic that Ripper uses. + class DedentingHeredoc # :nodoc: + TAB_WIDTH = 8 + + attr_reader :tokens, :dedent_next, :dedent, :embexpr_balance + + def initialize + @tokens = [] + @dedent_next = true + @dedent = nil + @embexpr_balance = 0 + @ended_on_newline = false + end + + # As tokens are coming in, we track the minimum amount of common leading + # whitespace on plain string content tokens. This allows us to later + # remove that amount of whitespace from the beginning of each line. + def <<(token) + case token.event + when :on_embexpr_beg, :on_heredoc_beg + @embexpr_balance += 1 + @dedent = 0 if @dedent_next && @ended_on_newline + when :on_embexpr_end, :on_heredoc_end + @embexpr_balance -= 1 + when :on_tstring_content + if embexpr_balance == 0 + line = token.value + + if dedent_next && !(line.strip.empty? && line.end_with?("\n")) + leading = line[/\A(\s*)\n?/, 1] + next_dedent = 0 + + leading.each_char do |char| + if char == "\t" + next_dedent = next_dedent - (next_dedent % TAB_WIDTH) + TAB_WIDTH + else + next_dedent += 1 + end + end + + @dedent = [dedent, next_dedent].compact.min + @dedent_next = true + @ended_on_newline = line.end_with?("\n") + tokens << token + return + end + end + end + + @dedent_next = token.event == :on_tstring_content && embexpr_balance == 0 + @ended_on_newline = false + tokens << token + end + + def to_a + # If every line in the heredoc is blank, we still need to split up the + # string content token into multiple tokens. + if dedent.nil? + results = [] #: Array[Token] + embexpr_balance = 0 + + tokens.each do |token| + case token.event + when :on_embexpr_beg, :on_heredoc_beg + embexpr_balance += 1 + results << token + when :on_embexpr_end, :on_heredoc_end + embexpr_balance -= 1 + results << token + when :on_tstring_content + if embexpr_balance == 0 + lineno = token[0][0] + column = token[0][1] + + token.value.split(/(?<=\n)/).each_with_index do |value, index| + column = 0 if index > 0 + results << Token.new([[lineno, column], :on_tstring_content, value, token.state]) + lineno += 1 + end + else + results << token + end + else + results << token + end + end + + return results + end + + # If the minimum common whitespace is 0, then we need to concatenate + # string nodes together that are immediately adjacent. + if dedent == 0 + results = [] #: Array[Token] + embexpr_balance = 0 + + index = 0 + max_index = tokens.length + + while index < max_index + token = tokens[index] + results << token + index += 1 + + case token.event + when :on_embexpr_beg, :on_heredoc_beg + embexpr_balance += 1 + when :on_embexpr_end, :on_heredoc_end + embexpr_balance -= 1 + when :on_tstring_content + if embexpr_balance == 0 + while index < max_index && tokens[index].event == :on_tstring_content && !token.value.match?(/\\\r?\n\z/) + token.value << tokens[index].value + index += 1 + end + end + end + end + + return results + end + + # Otherwise, we're going to run through each token in the list and + # insert on_ignored_sp tokens for the amount of dedent that we need to + # perform. We also need to remove the dedent from the beginning of + # each line of plain string content tokens. + results = [] #: Array[Token] + dedent_next = true + embexpr_balance = 0 + + tokens.each do |token| + # Notice that the structure of this conditional largely matches the + # whitespace calculation we performed above. This is because + # checking if the subsequent token needs to be dedented is common to + # both the dedent calculation and the ignored_sp insertion. + case token.event + when :on_embexpr_beg + embexpr_balance += 1 + results << token + when :on_embexpr_end + embexpr_balance -= 1 + results << token + when :on_tstring_content + if embexpr_balance == 0 + # Here we're going to split the string on newlines, but maintain + # the newlines in the resulting array. We'll do that with a look + # behind assertion. + splits = token.value.split(/(?<=\n)/) + index = 0 + + while index < splits.length + line = splits[index] + lineno = token[0][0] + index + column = token[0][1] + + # Blank lines do not count toward common leading whitespace + # calculation and do not need to be dedented. + if dedent_next || index > 0 + column = 0 + end + + # If the dedent is 0 and we're not supposed to dedent the next + # line or this line doesn't start with whitespace, then we + # should concatenate the rest of the string to match ripper. + if dedent == 0 && (!dedent_next || !line.start_with?(/\s/)) + line = splits[index..].join + index = splits.length + end + + # If we are supposed to dedent this line or if this is not the + # first line of the string and this line isn't entirely blank, + # then we need to insert an on_ignored_sp token and remove the + # dedent from the beginning of the line. + if (dedent > 0) && (dedent_next || index > 0) + deleting = 0 + deleted_chars = [] #: Array[String] + + # Gather up all of the characters that we're going to + # delete, stopping when you hit a character that would put + # you over the dedent amount. + line.each_char.with_index do |char, i| + case char + when "\r" + if line[i + 1] == "\n" + break + end + when "\n" + break + when "\t" + deleting = deleting - (deleting % TAB_WIDTH) + TAB_WIDTH + else + deleting += 1 + end + + break if deleting > dedent + deleted_chars << char + end + + # If we have something to delete, then delete it from the + # string and insert an on_ignored_sp token. + if deleted_chars.any? + ignored = deleted_chars.join + line.delete_prefix!(ignored) + + results << Token.new([[lineno, 0], :on_ignored_sp, ignored, token[3]]) + column = ignored.length + end + end + + results << Token.new([[lineno, column], token[1], line, token[3]]) unless line.empty? + index += 1 + end + else + results << token + end + else + results << token + end + + dedent_next = + ((token.event == :on_tstring_content) || (token.event == :on_heredoc_end)) && + embexpr_balance == 0 + end + + results + end + end + + # Here we will split between the two types of heredocs and return the + # object that will store their tokens. + def self.build(opening) + case opening.value[2] + when "~" + DedentingHeredoc.new + when "-" + DashHeredoc.new(opening.value[3] != "'") + else + PlainHeredoc.new + end + end + end + + private_constant :Heredoc + + attr_reader :source, :options + + def initialize(source, **options) + @source = source + @options = options + end + + def result + tokens = [] #: Array[LexCompat::Token] + + state = :default + heredoc_stack = [[]] #: Array[Array[Heredoc::PlainHeredoc | Heredoc::DashHeredoc | Heredoc::DedentingHeredoc]] + + result = Prism.lex(source, **options) + result_value = result.value + previous_state = nil #: Ripper::Lexer::State? + last_heredoc_end = nil #: Integer? + + # In previous versions of Ruby, Ripper wouldn't flush the bom before the + # first token, so we had to have a hack in place to account for that. This + # checks for that behavior. + bom_flushed = Ripper.lex("\xEF\xBB\xBF# test")[0][0][1] == 0 + bom = source.byteslice(0..2) == "\xEF\xBB\xBF" + + result_value.each_with_index do |(token, lex_state), index| + lineno = token.location.start_line + column = token.location.start_column + + # If there's a UTF-8 byte-order mark as the start of the file, then for + # certain tokens ripper sets the first token back by 3 bytes. It also + # keeps the byte order mark in the first token's value. This is weird, + # and I don't want to mirror that in our parser. So instead, we'll match + # up the columns and values here. + if bom && lineno == 1 + column -= 3 + + if index == 0 && column == 0 && !bom_flushed + flushed = + case token.type + when :BACK_REFERENCE, :INSTANCE_VARIABLE, :CLASS_VARIABLE, + :GLOBAL_VARIABLE, :NUMBERED_REFERENCE, :PERCENT_LOWER_I, + :PERCENT_LOWER_X, :PERCENT_LOWER_W, :PERCENT_UPPER_I, + :PERCENT_UPPER_W, :STRING_BEGIN + true + when :REGEXP_BEGIN, :SYMBOL_BEGIN + token.value.start_with?("%") + else + false + end + + unless flushed + column -= 3 + value = token.value + value.prepend(String.new("\xEF\xBB\xBF", encoding: value.encoding)) + end + end + end + + event = RIPPER.fetch(token.type) + value = token.value + lex_state = Ripper::Lexer::State.new(lex_state) + + token = + case event + when :on___end__ + EndContentToken.new([[lineno, column], event, value, lex_state]) + when :on_comment + IgnoreStateToken.new([[lineno, column], event, value, lex_state]) + when :on_heredoc_end + # Heredoc end tokens can be emitted in an odd order, so we don't + # want to bother comparing the state on them. + last_heredoc_end = token.location.end_offset + IgnoreStateToken.new([[lineno, column], event, value, lex_state]) + when :on_ident + if lex_state == Ripper::EXPR_END + # If we have an identifier that follows a method name like: + # + # def foo bar + # + # then Ripper will mark bar as END|LABEL if there is a local in a + # parent scope named bar because it hasn't pushed the local table + # yet. We do this more accurately, so we need to allow comparing + # against both END and END|LABEL. + ParamToken.new([[lineno, column], event, value, lex_state]) + elsif lex_state == Ripper::EXPR_END | Ripper::EXPR_LABEL + # In the event that we're comparing identifiers, we're going to + # allow a little divergence. Ripper doesn't account for local + # variables introduced through named captures in regexes, and we + # do, which accounts for this difference. + IdentToken.new([[lineno, column], event, value, lex_state]) + else + Token.new([[lineno, column], event, value, lex_state]) + end + when :on_embexpr_end + IgnoreStateToken.new([[lineno, column], event, value, lex_state]) + when :on_ignored_nl + # Ignored newlines can occasionally have a LABEL state attached to + # them which doesn't actually impact anything. We don't mirror that + # state so we ignored it. + IgnoredNewlineToken.new([[lineno, column], event, value, lex_state]) + when :on_regexp_end + # On regex end, Ripper scans and then sets end state, so the ripper + # lexed output is begin, when it should be end. prism sets lex state + # correctly to end state, but we want to be able to compare against + # Ripper's lexed state. So here, if it's a regexp end token, we + # output the state as the previous state, solely for the sake of + # comparison. + previous_token = result_value[index - 1][0] + lex_state = + if RIPPER.fetch(previous_token.type) == :on_embexpr_end + # If the previous token is embexpr_end, then we have to do even + # more processing. The end of an embedded expression sets the + # state to the state that it had at the beginning of the + # embedded expression. So we have to go and find that state and + # set it here. + counter = 1 + current_index = index - 1 + + until counter == 0 + current_index -= 1 + current_event = RIPPER.fetch(result_value[current_index][0].type) + counter += { on_embexpr_beg: -1, on_embexpr_end: 1 }[current_event] || 0 + end + + Ripper::Lexer::State.new(result_value[current_index][1]) + else + previous_state + end + + Token.new([[lineno, column], event, value, lex_state]) + when :on_eof + previous_token = result_value[index - 1][0] + + # If we're at the end of the file and the previous token was a + # comment and there is still whitespace after the comment, then + # Ripper will append a on_nl token (even though there isn't + # necessarily a newline). We mirror that here. + if previous_token.type == :COMMENT + # If the comment is at the start of a heredoc: < 1 + flushing = heredoc_stack.pop + heredoc_stack.last.last << token + + flushing.each do |heredoc| + heredoc.to_a.each do |flushed_token| + heredoc_stack.last.last << flushed_token + end + end + + state = :heredoc_opened + next + end + elsif event == :on_heredoc_beg + tokens << token + state = :heredoc_opened + heredoc_stack.last << Heredoc.build(token) + next + elsif heredoc_stack.size > 1 + heredoc_stack[-2].last << token + next + end + + heredoc_stack.last.each do |heredoc| + tokens.concat(heredoc.to_a) + end + + heredoc_stack.last.clear + state = :default + + tokens << token + end + end + + # Drop the EOF token from the list + tokens = tokens[0...-1] + + # We sort by location to compare against Ripper's output + tokens.sort_by!(&:location) + + Result.new(tokens, result.comments, result.magic_comments, result.data_loc, result.errors, result.warnings, Source.for(source)) + end + end + + private_constant :LexCompat + + # This is a class that wraps the Ripper lexer to produce almost exactly the + # same tokens. + class LexRipper # :nodoc: + attr_reader :source + + def initialize(source) + @source = source + end + + def result + previous = [] #: [[Integer, Integer], Symbol, String, untyped] | [] + results = [] #: Array[[[Integer, Integer], Symbol, String, untyped]] + + lex(source).each do |token| + case token[1] + when :on_sp + # skip + when :on_tstring_content + if previous[1] == :on_tstring_content && (token[2].start_with?("\#$") || token[2].start_with?("\#@")) + previous[2] << token[2] + else + results << token + previous = token + end + when :on_words_sep + if previous[1] == :on_words_sep + previous[2] << token[2] + else + results << token + previous = token + end + else + results << token + previous = token + end + end + + results + end + + private + + if Ripper.method(:lex).parameters.assoc(:keyrest) + def lex(source) + Ripper.lex(source, raise_errors: true) + end + else + def lex(source) + ripper = Ripper::Lexer.new(source) + ripper.lex.tap do |result| + raise SyntaxError, ripper.errors.map(&:message).join(' ;') if ripper.errors.any? + end + end + end + end + + private_constant :LexRipper +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/mutation_compiler.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/mutation_compiler.rb new file mode 100644 index 00000000..02fa7774 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/mutation_compiler.rb @@ -0,0 +1,769 @@ +# frozen_string_literal: true + +=begin +This file is generated by the templates/template.rb script and should not be +modified manually. See templates/lib/prism/mutation_compiler.rb.erb +if you are looking to modify the template +=end + +module Prism + # This visitor walks through the tree and copies each node as it is being + # visited. This is useful for consumers that want to mutate the tree, as you + # can change subtrees in place without effecting the rest of the tree. + class MutationCompiler < Compiler + # Copy a AliasGlobalVariableNode node + def visit_alias_global_variable_node(node) + node.copy(new_name: visit(node.new_name), old_name: visit(node.old_name)) + end + + # Copy a AliasMethodNode node + def visit_alias_method_node(node) + node.copy(new_name: visit(node.new_name), old_name: visit(node.old_name)) + end + + # Copy a AlternationPatternNode node + def visit_alternation_pattern_node(node) + node.copy(left: visit(node.left), right: visit(node.right)) + end + + # Copy a AndNode node + def visit_and_node(node) + node.copy(left: visit(node.left), right: visit(node.right)) + end + + # Copy a ArgumentsNode node + def visit_arguments_node(node) + node.copy(arguments: visit_all(node.arguments)) + end + + # Copy a ArrayNode node + def visit_array_node(node) + node.copy(elements: visit_all(node.elements)) + end + + # Copy a ArrayPatternNode node + def visit_array_pattern_node(node) + node.copy(constant: visit(node.constant), requireds: visit_all(node.requireds), rest: visit(node.rest), posts: visit_all(node.posts)) + end + + # Copy a AssocNode node + def visit_assoc_node(node) + node.copy(key: visit(node.key), value: visit(node.value)) + end + + # Copy a AssocSplatNode node + def visit_assoc_splat_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a BackReferenceReadNode node + def visit_back_reference_read_node(node) + node.copy + end + + # Copy a BeginNode node + def visit_begin_node(node) + node.copy(statements: visit(node.statements), rescue_clause: visit(node.rescue_clause), else_clause: visit(node.else_clause), ensure_clause: visit(node.ensure_clause)) + end + + # Copy a BlockArgumentNode node + def visit_block_argument_node(node) + node.copy(expression: visit(node.expression)) + end + + # Copy a BlockLocalVariableNode node + def visit_block_local_variable_node(node) + node.copy + end + + # Copy a BlockNode node + def visit_block_node(node) + node.copy(parameters: visit(node.parameters), body: visit(node.body)) + end + + # Copy a BlockParameterNode node + def visit_block_parameter_node(node) + node.copy + end + + # Copy a BlockParametersNode node + def visit_block_parameters_node(node) + node.copy(parameters: visit(node.parameters), locals: visit_all(node.locals)) + end + + # Copy a BreakNode node + def visit_break_node(node) + node.copy(arguments: visit(node.arguments)) + end + + # Copy a CallAndWriteNode node + def visit_call_and_write_node(node) + node.copy(receiver: visit(node.receiver), value: visit(node.value)) + end + + # Copy a CallNode node + def visit_call_node(node) + node.copy(receiver: visit(node.receiver), arguments: visit(node.arguments), block: visit(node.block)) + end + + # Copy a CallOperatorWriteNode node + def visit_call_operator_write_node(node) + node.copy(receiver: visit(node.receiver), value: visit(node.value)) + end + + # Copy a CallOrWriteNode node + def visit_call_or_write_node(node) + node.copy(receiver: visit(node.receiver), value: visit(node.value)) + end + + # Copy a CallTargetNode node + def visit_call_target_node(node) + node.copy(receiver: visit(node.receiver)) + end + + # Copy a CapturePatternNode node + def visit_capture_pattern_node(node) + node.copy(value: visit(node.value), target: visit(node.target)) + end + + # Copy a CaseMatchNode node + def visit_case_match_node(node) + node.copy(predicate: visit(node.predicate), conditions: visit_all(node.conditions), else_clause: visit(node.else_clause)) + end + + # Copy a CaseNode node + def visit_case_node(node) + node.copy(predicate: visit(node.predicate), conditions: visit_all(node.conditions), else_clause: visit(node.else_clause)) + end + + # Copy a ClassNode node + def visit_class_node(node) + node.copy(constant_path: visit(node.constant_path), superclass: visit(node.superclass), body: visit(node.body)) + end + + # Copy a ClassVariableAndWriteNode node + def visit_class_variable_and_write_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a ClassVariableOperatorWriteNode node + def visit_class_variable_operator_write_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a ClassVariableOrWriteNode node + def visit_class_variable_or_write_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a ClassVariableReadNode node + def visit_class_variable_read_node(node) + node.copy + end + + # Copy a ClassVariableTargetNode node + def visit_class_variable_target_node(node) + node.copy + end + + # Copy a ClassVariableWriteNode node + def visit_class_variable_write_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a ConstantAndWriteNode node + def visit_constant_and_write_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a ConstantOperatorWriteNode node + def visit_constant_operator_write_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a ConstantOrWriteNode node + def visit_constant_or_write_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a ConstantPathAndWriteNode node + def visit_constant_path_and_write_node(node) + node.copy(target: visit(node.target), value: visit(node.value)) + end + + # Copy a ConstantPathNode node + def visit_constant_path_node(node) + node.copy(parent: visit(node.parent)) + end + + # Copy a ConstantPathOperatorWriteNode node + def visit_constant_path_operator_write_node(node) + node.copy(target: visit(node.target), value: visit(node.value)) + end + + # Copy a ConstantPathOrWriteNode node + def visit_constant_path_or_write_node(node) + node.copy(target: visit(node.target), value: visit(node.value)) + end + + # Copy a ConstantPathTargetNode node + def visit_constant_path_target_node(node) + node.copy(parent: visit(node.parent)) + end + + # Copy a ConstantPathWriteNode node + def visit_constant_path_write_node(node) + node.copy(target: visit(node.target), value: visit(node.value)) + end + + # Copy a ConstantReadNode node + def visit_constant_read_node(node) + node.copy + end + + # Copy a ConstantTargetNode node + def visit_constant_target_node(node) + node.copy + end + + # Copy a ConstantWriteNode node + def visit_constant_write_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a DefNode node + def visit_def_node(node) + node.copy(receiver: visit(node.receiver), parameters: visit(node.parameters), body: visit(node.body)) + end + + # Copy a DefinedNode node + def visit_defined_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a ElseNode node + def visit_else_node(node) + node.copy(statements: visit(node.statements)) + end + + # Copy a EmbeddedStatementsNode node + def visit_embedded_statements_node(node) + node.copy(statements: visit(node.statements)) + end + + # Copy a EmbeddedVariableNode node + def visit_embedded_variable_node(node) + node.copy(variable: visit(node.variable)) + end + + # Copy a EnsureNode node + def visit_ensure_node(node) + node.copy(statements: visit(node.statements)) + end + + # Copy a FalseNode node + def visit_false_node(node) + node.copy + end + + # Copy a FindPatternNode node + def visit_find_pattern_node(node) + node.copy(constant: visit(node.constant), left: visit(node.left), requireds: visit_all(node.requireds), right: visit(node.right)) + end + + # Copy a FlipFlopNode node + def visit_flip_flop_node(node) + node.copy(left: visit(node.left), right: visit(node.right)) + end + + # Copy a FloatNode node + def visit_float_node(node) + node.copy + end + + # Copy a ForNode node + def visit_for_node(node) + node.copy(index: visit(node.index), collection: visit(node.collection), statements: visit(node.statements)) + end + + # Copy a ForwardingArgumentsNode node + def visit_forwarding_arguments_node(node) + node.copy + end + + # Copy a ForwardingParameterNode node + def visit_forwarding_parameter_node(node) + node.copy + end + + # Copy a ForwardingSuperNode node + def visit_forwarding_super_node(node) + node.copy(block: visit(node.block)) + end + + # Copy a GlobalVariableAndWriteNode node + def visit_global_variable_and_write_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a GlobalVariableOperatorWriteNode node + def visit_global_variable_operator_write_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a GlobalVariableOrWriteNode node + def visit_global_variable_or_write_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a GlobalVariableReadNode node + def visit_global_variable_read_node(node) + node.copy + end + + # Copy a GlobalVariableTargetNode node + def visit_global_variable_target_node(node) + node.copy + end + + # Copy a GlobalVariableWriteNode node + def visit_global_variable_write_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a HashNode node + def visit_hash_node(node) + node.copy(elements: visit_all(node.elements)) + end + + # Copy a HashPatternNode node + def visit_hash_pattern_node(node) + node.copy(constant: visit(node.constant), elements: visit_all(node.elements), rest: visit(node.rest)) + end + + # Copy a IfNode node + def visit_if_node(node) + node.copy(predicate: visit(node.predicate), statements: visit(node.statements), subsequent: visit(node.subsequent)) + end + + # Copy a ImaginaryNode node + def visit_imaginary_node(node) + node.copy(numeric: visit(node.numeric)) + end + + # Copy a ImplicitNode node + def visit_implicit_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a ImplicitRestNode node + def visit_implicit_rest_node(node) + node.copy + end + + # Copy a InNode node + def visit_in_node(node) + node.copy(pattern: visit(node.pattern), statements: visit(node.statements)) + end + + # Copy a IndexAndWriteNode node + def visit_index_and_write_node(node) + node.copy(receiver: visit(node.receiver), arguments: visit(node.arguments), block: visit(node.block), value: visit(node.value)) + end + + # Copy a IndexOperatorWriteNode node + def visit_index_operator_write_node(node) + node.copy(receiver: visit(node.receiver), arguments: visit(node.arguments), block: visit(node.block), value: visit(node.value)) + end + + # Copy a IndexOrWriteNode node + def visit_index_or_write_node(node) + node.copy(receiver: visit(node.receiver), arguments: visit(node.arguments), block: visit(node.block), value: visit(node.value)) + end + + # Copy a IndexTargetNode node + def visit_index_target_node(node) + node.copy(receiver: visit(node.receiver), arguments: visit(node.arguments), block: visit(node.block)) + end + + # Copy a InstanceVariableAndWriteNode node + def visit_instance_variable_and_write_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a InstanceVariableOperatorWriteNode node + def visit_instance_variable_operator_write_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a InstanceVariableOrWriteNode node + def visit_instance_variable_or_write_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a InstanceVariableReadNode node + def visit_instance_variable_read_node(node) + node.copy + end + + # Copy a InstanceVariableTargetNode node + def visit_instance_variable_target_node(node) + node.copy + end + + # Copy a InstanceVariableWriteNode node + def visit_instance_variable_write_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a IntegerNode node + def visit_integer_node(node) + node.copy + end + + # Copy a InterpolatedMatchLastLineNode node + def visit_interpolated_match_last_line_node(node) + node.copy(parts: visit_all(node.parts)) + end + + # Copy a InterpolatedRegularExpressionNode node + def visit_interpolated_regular_expression_node(node) + node.copy(parts: visit_all(node.parts)) + end + + # Copy a InterpolatedStringNode node + def visit_interpolated_string_node(node) + node.copy(parts: visit_all(node.parts)) + end + + # Copy a InterpolatedSymbolNode node + def visit_interpolated_symbol_node(node) + node.copy(parts: visit_all(node.parts)) + end + + # Copy a InterpolatedXStringNode node + def visit_interpolated_x_string_node(node) + node.copy(parts: visit_all(node.parts)) + end + + # Copy a ItLocalVariableReadNode node + def visit_it_local_variable_read_node(node) + node.copy + end + + # Copy a ItParametersNode node + def visit_it_parameters_node(node) + node.copy + end + + # Copy a KeywordHashNode node + def visit_keyword_hash_node(node) + node.copy(elements: visit_all(node.elements)) + end + + # Copy a KeywordRestParameterNode node + def visit_keyword_rest_parameter_node(node) + node.copy + end + + # Copy a LambdaNode node + def visit_lambda_node(node) + node.copy(parameters: visit(node.parameters), body: visit(node.body)) + end + + # Copy a LocalVariableAndWriteNode node + def visit_local_variable_and_write_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a LocalVariableOperatorWriteNode node + def visit_local_variable_operator_write_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a LocalVariableOrWriteNode node + def visit_local_variable_or_write_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a LocalVariableReadNode node + def visit_local_variable_read_node(node) + node.copy + end + + # Copy a LocalVariableTargetNode node + def visit_local_variable_target_node(node) + node.copy + end + + # Copy a LocalVariableWriteNode node + def visit_local_variable_write_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a MatchLastLineNode node + def visit_match_last_line_node(node) + node.copy + end + + # Copy a MatchPredicateNode node + def visit_match_predicate_node(node) + node.copy(value: visit(node.value), pattern: visit(node.pattern)) + end + + # Copy a MatchRequiredNode node + def visit_match_required_node(node) + node.copy(value: visit(node.value), pattern: visit(node.pattern)) + end + + # Copy a MatchWriteNode node + def visit_match_write_node(node) + node.copy(call: visit(node.call), targets: visit_all(node.targets)) + end + + # Copy a MissingNode node + def visit_missing_node(node) + node.copy + end + + # Copy a ModuleNode node + def visit_module_node(node) + node.copy(constant_path: visit(node.constant_path), body: visit(node.body)) + end + + # Copy a MultiTargetNode node + def visit_multi_target_node(node) + node.copy(lefts: visit_all(node.lefts), rest: visit(node.rest), rights: visit_all(node.rights)) + end + + # Copy a MultiWriteNode node + def visit_multi_write_node(node) + node.copy(lefts: visit_all(node.lefts), rest: visit(node.rest), rights: visit_all(node.rights), value: visit(node.value)) + end + + # Copy a NextNode node + def visit_next_node(node) + node.copy(arguments: visit(node.arguments)) + end + + # Copy a NilNode node + def visit_nil_node(node) + node.copy + end + + # Copy a NoKeywordsParameterNode node + def visit_no_keywords_parameter_node(node) + node.copy + end + + # Copy a NumberedParametersNode node + def visit_numbered_parameters_node(node) + node.copy + end + + # Copy a NumberedReferenceReadNode node + def visit_numbered_reference_read_node(node) + node.copy + end + + # Copy a OptionalKeywordParameterNode node + def visit_optional_keyword_parameter_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a OptionalParameterNode node + def visit_optional_parameter_node(node) + node.copy(value: visit(node.value)) + end + + # Copy a OrNode node + def visit_or_node(node) + node.copy(left: visit(node.left), right: visit(node.right)) + end + + # Copy a ParametersNode node + def visit_parameters_node(node) + node.copy(requireds: visit_all(node.requireds), optionals: visit_all(node.optionals), rest: visit(node.rest), posts: visit_all(node.posts), keywords: visit_all(node.keywords), keyword_rest: visit(node.keyword_rest), block: visit(node.block)) + end + + # Copy a ParenthesesNode node + def visit_parentheses_node(node) + node.copy(body: visit(node.body)) + end + + # Copy a PinnedExpressionNode node + def visit_pinned_expression_node(node) + node.copy(expression: visit(node.expression)) + end + + # Copy a PinnedVariableNode node + def visit_pinned_variable_node(node) + node.copy(variable: visit(node.variable)) + end + + # Copy a PostExecutionNode node + def visit_post_execution_node(node) + node.copy(statements: visit(node.statements)) + end + + # Copy a PreExecutionNode node + def visit_pre_execution_node(node) + node.copy(statements: visit(node.statements)) + end + + # Copy a ProgramNode node + def visit_program_node(node) + node.copy(statements: visit(node.statements)) + end + + # Copy a RangeNode node + def visit_range_node(node) + node.copy(left: visit(node.left), right: visit(node.right)) + end + + # Copy a RationalNode node + def visit_rational_node(node) + node.copy + end + + # Copy a RedoNode node + def visit_redo_node(node) + node.copy + end + + # Copy a RegularExpressionNode node + def visit_regular_expression_node(node) + node.copy + end + + # Copy a RequiredKeywordParameterNode node + def visit_required_keyword_parameter_node(node) + node.copy + end + + # Copy a RequiredParameterNode node + def visit_required_parameter_node(node) + node.copy + end + + # Copy a RescueModifierNode node + def visit_rescue_modifier_node(node) + node.copy(expression: visit(node.expression), rescue_expression: visit(node.rescue_expression)) + end + + # Copy a RescueNode node + def visit_rescue_node(node) + node.copy(exceptions: visit_all(node.exceptions), reference: visit(node.reference), statements: visit(node.statements), subsequent: visit(node.subsequent)) + end + + # Copy a RestParameterNode node + def visit_rest_parameter_node(node) + node.copy + end + + # Copy a RetryNode node + def visit_retry_node(node) + node.copy + end + + # Copy a ReturnNode node + def visit_return_node(node) + node.copy(arguments: visit(node.arguments)) + end + + # Copy a SelfNode node + def visit_self_node(node) + node.copy + end + + # Copy a ShareableConstantNode node + def visit_shareable_constant_node(node) + node.copy(write: visit(node.write)) + end + + # Copy a SingletonClassNode node + def visit_singleton_class_node(node) + node.copy(expression: visit(node.expression), body: visit(node.body)) + end + + # Copy a SourceEncodingNode node + def visit_source_encoding_node(node) + node.copy + end + + # Copy a SourceFileNode node + def visit_source_file_node(node) + node.copy + end + + # Copy a SourceLineNode node + def visit_source_line_node(node) + node.copy + end + + # Copy a SplatNode node + def visit_splat_node(node) + node.copy(expression: visit(node.expression)) + end + + # Copy a StatementsNode node + def visit_statements_node(node) + node.copy(body: visit_all(node.body)) + end + + # Copy a StringNode node + def visit_string_node(node) + node.copy + end + + # Copy a SuperNode node + def visit_super_node(node) + node.copy(arguments: visit(node.arguments), block: visit(node.block)) + end + + # Copy a SymbolNode node + def visit_symbol_node(node) + node.copy + end + + # Copy a TrueNode node + def visit_true_node(node) + node.copy + end + + # Copy a UndefNode node + def visit_undef_node(node) + node.copy(names: visit_all(node.names)) + end + + # Copy a UnlessNode node + def visit_unless_node(node) + node.copy(predicate: visit(node.predicate), statements: visit(node.statements), else_clause: visit(node.else_clause)) + end + + # Copy a UntilNode node + def visit_until_node(node) + node.copy(predicate: visit(node.predicate), statements: visit(node.statements)) + end + + # Copy a WhenNode node + def visit_when_node(node) + node.copy(conditions: visit_all(node.conditions), statements: visit(node.statements)) + end + + # Copy a WhileNode node + def visit_while_node(node) + node.copy(predicate: visit(node.predicate), statements: visit(node.statements)) + end + + # Copy a XStringNode node + def visit_x_string_node(node) + node.copy + end + + # Copy a YieldNode node + def visit_yield_node(node) + node.copy(arguments: visit(node.arguments)) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/node.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/node.rb new file mode 100644 index 00000000..ba3a0968 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/node.rb @@ -0,0 +1,18645 @@ +# frozen_string_literal: true + +=begin +This file is generated by the templates/template.rb script and should not be +modified manually. See templates/lib/prism/node.rb.erb +if you are looking to modify the template +=end + +module Prism + # This represents a node in the tree. It is the parent class of all of the + # various node types. + class Node + # A pointer to the source that this node was created from. + attr_reader :source + private :source + + # A unique identifier for this node. This is used in a very specific + # use case where you want to keep around a reference to a node without + # having to keep around the syntax tree in memory. This unique identifier + # will be consistent across multiple parses of the same source code. + attr_reader :node_id + + # Save this node using a saved source so that it can be retrieved later. + def save(repository) + repository.enter(node_id, :itself) + end + + # A Location instance that represents the location of this node in the + # source. + def location + location = @location + return location if location.is_a?(Location) + @location = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the location using a saved source so that it can be retrieved later. + def save_location(repository) + repository.enter(node_id, :location) + end + + # Delegates to the start_line of the associated location object. + def start_line + location.start_line + end + + # Delegates to the end_line of the associated location object. + def end_line + location.end_line + end + + # The start offset of the node in the source. This method is effectively a + # delegate method to the location object. + def start_offset + location = @location + location.is_a?(Location) ? location.start_offset : location >> 32 + end + + # The end offset of the node in the source. This method is effectively a + # delegate method to the location object. + def end_offset + location = @location + location.is_a?(Location) ? location.end_offset : ((location >> 32) + (location & 0xFFFFFFFF)) + end + + # Delegates to the start_character_offset of the associated location object. + def start_character_offset + location.start_character_offset + end + + # Delegates to the end_character_offset of the associated location object. + def end_character_offset + location.end_character_offset + end + + # Delegates to the cached_start_code_units_offset of the associated location + # object. + def cached_start_code_units_offset(cache) + location.cached_start_code_units_offset(cache) + end + + # Delegates to the cached_end_code_units_offset of the associated location + # object. + def cached_end_code_units_offset(cache) + location.cached_end_code_units_offset(cache) + end + + # Delegates to the start_column of the associated location object. + def start_column + location.start_column + end + + # Delegates to the end_column of the associated location object. + def end_column + location.end_column + end + + # Delegates to the start_character_column of the associated location object. + def start_character_column + location.start_character_column + end + + # Delegates to the end_character_column of the associated location object. + def end_character_column + location.end_character_column + end + + # Delegates to the cached_start_code_units_column of the associated location + # object. + def cached_start_code_units_column(cache) + location.cached_start_code_units_column(cache) + end + + # Delegates to the cached_end_code_units_column of the associated location + # object. + def cached_end_code_units_column(cache) + location.cached_end_code_units_column(cache) + end + + # Delegates to the leading_comments of the associated location object. + def leading_comments + location.leading_comments + end + + # Delegates to the trailing_comments of the associated location object. + def trailing_comments + location.trailing_comments + end + + # Delegates to the comments of the associated location object. + def comments + location.comments + end + + # Returns all of the lines of the source code associated with this node. + def source_lines + location.source_lines + end + + # An alias for source_lines, used to mimic the API from + # RubyVM::AbstractSyntaxTree to make it easier to migrate. + alias script_lines source_lines + + # Slice the location of the node from the source. + def slice + location.slice + end + + # Slice the location of the node from the source, starting at the beginning + # of the line that the location starts on, ending at the end of the line + # that the location ends on. + def slice_lines + location.slice_lines + end + + # An bitset of flags for this node. There are certain flags that are common + # for all nodes, and then some nodes have specific flags. + attr_reader :flags + protected :flags + + # Returns true if the node has the newline flag set. + def newline? + flags.anybits?(NodeFlags::NEWLINE) + end + + # Returns true if the node has the static literal flag set. + def static_literal? + flags.anybits?(NodeFlags::STATIC_LITERAL) + end + + # Similar to inspect, but respects the current level of indentation given by + # the pretty print object. + def pretty_print(q) + q.seplist(inspect.chomp.each_line, -> { q.breakable }) do |line| + q.text(line.chomp) + end + q.current_group.break + end + + # Convert this node into a graphviz dot graph string. + def to_dot + # @type self: node + DotVisitor.new.tap { |visitor| accept(visitor) }.to_dot + end + + # Returns a list of nodes that are descendants of this node that contain the + # given line and column. This is useful for locating a node that is selected + # based on the line and column of the source code. + # + # Important to note is that the column given to this method should be in + # bytes, as opposed to characters or code units. + def tunnel(line, column) + queue = [self] #: Array[Prism::node] + result = [] #: Array[Prism::node] + + while (node = queue.shift) + result << node + + node.compact_child_nodes.each do |child_node| + child_location = child_node.location + + start_line = child_location.start_line + end_line = child_location.end_line + + if start_line == end_line + if line == start_line && column >= child_location.start_column && column < child_location.end_column + queue << child_node + break + end + elsif (line == start_line && column >= child_location.start_column) || (line == end_line && column < child_location.end_column) + queue << child_node + break + elsif line > start_line && line < end_line + queue << child_node + break + end + end + end + + result + end + + # Returns the first node that matches the given block when visited in a + # depth-first search. This is useful for finding a node that matches a + # particular condition. + # + # node.breadth_first_search { |node| node.node_id == node_id } + # + def breadth_first_search(&block) + queue = [self] #: Array[Prism::node] + + while (node = queue.shift) + return node if yield node + queue.concat(node.compact_child_nodes) + end + + nil + end + + # Returns a list of the fields that exist for this node class. Fields + # describe the structure of the node. This kind of reflection is useful for + # things like recursively visiting each node _and_ field in the tree. + def self.fields + # This method should only be called on subclasses of Node, not Node + # itself. + raise NoMethodError, "undefined method `fields' for #{inspect}" if self == Node + + Reflection.fields_for(self) + end + + # -------------------------------------------------------------------------- + # :section: Node interface + # These methods are effectively abstract methods that must be implemented by + # the various subclasses of Node. They are here to make it easier to work + # with typecheckers. + # -------------------------------------------------------------------------- + + # Accepts a visitor and calls back into the specialized visit function. + def accept(visitor) + raise NoMethodError, "undefined method `accept' for #{inspect}" + end + + # Returns an array of child nodes, including `nil`s in the place of optional + # nodes that were not present. + def child_nodes + raise NoMethodError, "undefined method `child_nodes' for #{inspect}" + end + + alias deconstruct child_nodes + + # Returns an array of child nodes, excluding any `nil`s in the place of + # optional nodes that were not present. + def compact_child_nodes + raise NoMethodError, "undefined method `compact_child_nodes' for #{inspect}" + end + + # Returns an array of child nodes and locations that could potentially have + # comments attached to them. + def comment_targets + raise NoMethodError, "undefined method `comment_targets' for #{inspect}" + end + + # Returns a string representation of the node. + def inspect + raise NoMethodError, "undefined method `inspect' for #{inspect}" + end + + # Sometimes you want to check an instance of a node against a list of + # classes to see what kind of behavior to perform. Usually this is done by + # calling `[cls1, cls2].include?(node.class)` or putting the node into a + # case statement and doing `case node; when cls1; when cls2; end`. Both of + # these approaches are relatively slow because of the constant lookups, + # method calls, and/or array allocations. + # + # Instead, you can call #type, which will return to you a symbol that you + # can use for comparison. This is faster than the other approaches because + # it uses a single integer comparison, but also because if you're on CRuby + # you can take advantage of the fact that case statements with all symbol + # keys will use a jump table. + def type + raise NoMethodError, "undefined method `type' for #{inspect}" + end + + # Similar to #type, this method returns a symbol that you can use for + # splitting on the type of the node without having to do a long === chain. + # Note that like #type, it will still be slower than using == for a single + # class, but should be faster in a case statement or an array comparison. + def self.type + raise NoMethodError, "undefined method `type' for #{inspect}" + end + end + + # Represents the use of the `alias` keyword to alias a global variable. + # + # alias $foo $bar + # ^^^^^^^^^^^^^^^ + class AliasGlobalVariableNode < Node + # Initialize a new AliasGlobalVariableNode node. + def initialize(source, node_id, location, flags, new_name, old_name, keyword_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @new_name = new_name + @old_name = old_name + @keyword_loc = keyword_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_alias_global_variable_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [new_name, old_name] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [new_name, old_name] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [new_name, old_name, keyword_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?new_name: GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode, ?old_name: GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode | SymbolNode | MissingNode, ?keyword_loc: Location) -> AliasGlobalVariableNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, new_name: self.new_name, old_name: self.old_name, keyword_loc: self.keyword_loc) + AliasGlobalVariableNode.new(source, node_id, location, flags, new_name, old_name, keyword_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, new_name: GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode, old_name: GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode | SymbolNode | MissingNode, keyword_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, new_name: new_name, old_name: old_name, keyword_loc: keyword_loc } + end + + # Represents the new name of the global variable that can be used after aliasing. + # + # alias $foo $bar + # ^^^^ + attr_reader :new_name + + # Represents the old name of the global variable that can be used before aliasing. + # + # alias $foo $bar + # ^^^^ + attr_reader :old_name + + # The location of the `alias` keyword. + # + # alias $foo $bar + # ^^^^^ + def keyword_loc + location = @keyword_loc + return location if location.is_a?(Location) + @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_keyword_loc(repository) + repository.enter(node_id, :keyword_loc) + end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :alias_global_variable_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :alias_global_variable_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(AliasGlobalVariableNode) && + (new_name === other.new_name) && + (old_name === other.old_name) && + (keyword_loc.nil? == other.keyword_loc.nil?) + end + end + + # Represents the use of the `alias` keyword to alias a method. + # + # alias foo bar + # ^^^^^^^^^^^^^ + class AliasMethodNode < Node + # Initialize a new AliasMethodNode node. + def initialize(source, node_id, location, flags, new_name, old_name, keyword_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @new_name = new_name + @old_name = old_name + @keyword_loc = keyword_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_alias_method_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [new_name, old_name] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [new_name, old_name] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [new_name, old_name, keyword_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?new_name: SymbolNode | InterpolatedSymbolNode, ?old_name: SymbolNode | InterpolatedSymbolNode | GlobalVariableReadNode | MissingNode, ?keyword_loc: Location) -> AliasMethodNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, new_name: self.new_name, old_name: self.old_name, keyword_loc: self.keyword_loc) + AliasMethodNode.new(source, node_id, location, flags, new_name, old_name, keyword_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, new_name: SymbolNode | InterpolatedSymbolNode, old_name: SymbolNode | InterpolatedSymbolNode | GlobalVariableReadNode | MissingNode, keyword_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, new_name: new_name, old_name: old_name, keyword_loc: keyword_loc } + end + + # Represents the new name of the method that will be aliased. + # + # alias foo bar + # ^^^ + # + # alias :foo :bar + # ^^^^ + # + # alias :"#{foo}" :"#{bar}" + # ^^^^^^^^^ + attr_reader :new_name + + # Represents the old name of the method that will be aliased. + # + # alias foo bar + # ^^^ + # + # alias :foo :bar + # ^^^^ + # + # alias :"#{foo}" :"#{bar}" + # ^^^^^^^^^ + attr_reader :old_name + + # Represents the location of the `alias` keyword. + # + # alias foo bar + # ^^^^^ + def keyword_loc + location = @keyword_loc + return location if location.is_a?(Location) + @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_keyword_loc(repository) + repository.enter(node_id, :keyword_loc) + end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :alias_method_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :alias_method_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(AliasMethodNode) && + (new_name === other.new_name) && + (old_name === other.old_name) && + (keyword_loc.nil? == other.keyword_loc.nil?) + end + end + + # Represents an alternation pattern in pattern matching. + # + # foo => bar | baz + # ^^^^^^^^^ + class AlternationPatternNode < Node + # Initialize a new AlternationPatternNode node. + def initialize(source, node_id, location, flags, left, right, operator_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @left = left + @right = right + @operator_loc = operator_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_alternation_pattern_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [left, right] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [left, right] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [left, right, operator_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?left: Prism::node, ?right: Prism::node, ?operator_loc: Location) -> AlternationPatternNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, left: self.left, right: self.right, operator_loc: self.operator_loc) + AlternationPatternNode.new(source, node_id, location, flags, left, right, operator_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, left: Prism::node, right: Prism::node, operator_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, left: left, right: right, operator_loc: operator_loc } + end + + # Represents the left side of the expression. + # + # foo => bar | baz + # ^^^ + attr_reader :left + + # Represents the right side of the expression. + # + # foo => bar | baz + # ^^^ + attr_reader :right + + # Represents the alternation operator location. + # + # foo => bar | baz + # ^ + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :alternation_pattern_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :alternation_pattern_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(AlternationPatternNode) && + (left === other.left) && + (right === other.right) && + (operator_loc.nil? == other.operator_loc.nil?) + end + end + + # Represents the use of the `&&` operator or the `and` keyword. + # + # left and right + # ^^^^^^^^^^^^^^ + class AndNode < Node + # Initialize a new AndNode node. + def initialize(source, node_id, location, flags, left, right, operator_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @left = left + @right = right + @operator_loc = operator_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_and_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [left, right] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [left, right] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [left, right, operator_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?left: Prism::node, ?right: Prism::node, ?operator_loc: Location) -> AndNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, left: self.left, right: self.right, operator_loc: self.operator_loc) + AndNode.new(source, node_id, location, flags, left, right, operator_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, left: Prism::node, right: Prism::node, operator_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, left: left, right: right, operator_loc: operator_loc } + end + + # Represents the left side of the expression. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # left and right + # ^^^^ + # + # 1 && 2 + # ^ + attr_reader :left + + # Represents the right side of the expression. + # + # left && right + # ^^^^^ + # + # 1 and 2 + # ^ + attr_reader :right + + # The location of the `and` keyword or the `&&` operator. + # + # left and right + # ^^^ + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :and_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :and_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(AndNode) && + (left === other.left) && + (right === other.right) && + (operator_loc.nil? == other.operator_loc.nil?) + end + end + + # Represents a set of arguments to a method or a keyword. + # + # return foo, bar, baz + # ^^^^^^^^^^^^^ + class ArgumentsNode < Node + # Initialize a new ArgumentsNode node. + def initialize(source, node_id, location, flags, arguments) + @source = source + @node_id = node_id + @location = location + @flags = flags + @arguments = arguments + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_arguments_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [*arguments] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [*arguments] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*arguments] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?arguments: Array[Prism::node]) -> ArgumentsNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, arguments: self.arguments) + ArgumentsNode.new(source, node_id, location, flags, arguments) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, arguments: Array[Prism::node] } + def deconstruct_keys(keys) + { node_id: node_id, location: location, arguments: arguments } + end + + # def contains_forwarding?: () -> bool + def contains_forwarding? + flags.anybits?(ArgumentsNodeFlags::CONTAINS_FORWARDING) + end + + # def contains_keywords?: () -> bool + def contains_keywords? + flags.anybits?(ArgumentsNodeFlags::CONTAINS_KEYWORDS) + end + + # def contains_keyword_splat?: () -> bool + def contains_keyword_splat? + flags.anybits?(ArgumentsNodeFlags::CONTAINS_KEYWORD_SPLAT) + end + + # def contains_splat?: () -> bool + def contains_splat? + flags.anybits?(ArgumentsNodeFlags::CONTAINS_SPLAT) + end + + # def contains_multiple_splats?: () -> bool + def contains_multiple_splats? + flags.anybits?(ArgumentsNodeFlags::CONTAINS_MULTIPLE_SPLATS) + end + + # The list of arguments, if present. These can be any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # foo(bar, baz) + # ^^^^^^^^ + attr_reader :arguments + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :arguments_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :arguments_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ArgumentsNode) && + (flags === other.flags) && + (arguments.length == other.arguments.length) && + arguments.zip(other.arguments).all? { |left, right| left === right } + end + end + + # Represents an array literal. This can be a regular array using brackets or a special array using % like %w or %i. + # + # [1, 2, 3] + # ^^^^^^^^^ + class ArrayNode < Node + # Initialize a new ArrayNode node. + def initialize(source, node_id, location, flags, elements, opening_loc, closing_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @elements = elements + @opening_loc = opening_loc + @closing_loc = closing_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_array_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [*elements] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [*elements] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*elements, *opening_loc, *closing_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?elements: Array[Prism::node], ?opening_loc: Location?, ?closing_loc: Location?) -> ArrayNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, elements: self.elements, opening_loc: self.opening_loc, closing_loc: self.closing_loc) + ArrayNode.new(source, node_id, location, flags, elements, opening_loc, closing_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, elements: Array[Prism::node], opening_loc: Location?, closing_loc: Location? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, elements: elements, opening_loc: opening_loc, closing_loc: closing_loc } + end + + # def contains_splat?: () -> bool + def contains_splat? + flags.anybits?(ArrayNodeFlags::CONTAINS_SPLAT) + end + + # Represent the list of zero or more [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression) within the array. + attr_reader :elements + + # Represents the optional source location for the opening token. + # + # [1,2,3] # "[" + # %w[foo bar baz] # "%w[" + # %I(apple orange banana) # "%I(" + # foo = 1, 2, 3 # nil + def opening_loc + location = @opening_loc + case location + when nil + nil + when Location + location + else + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) unless @opening_loc.nil? + end + + # Represents the optional source location for the closing token. + # + # [1,2,3] # "]" + # %w[foo bar baz] # "]" + # %I(apple orange banana) # ")" + # foo = 1, 2, 3 # nil + def closing_loc + location = @closing_loc + case location + when nil + nil + when Location + location + else + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) unless @closing_loc.nil? + end + + # def opening: () -> String? + def opening + opening_loc&.slice + end + + # def closing: () -> String? + def closing + closing_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :array_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :array_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ArrayNode) && + (flags === other.flags) && + (elements.length == other.elements.length) && + elements.zip(other.elements).all? { |left, right| left === right } && + (opening_loc.nil? == other.opening_loc.nil?) && + (closing_loc.nil? == other.closing_loc.nil?) + end + end + + # Represents an array pattern in pattern matching. + # + # foo in 1, 2 + # ^^^^^^^^^^^ + # + # foo in [1, 2] + # ^^^^^^^^^^^^^ + # + # foo in *bar + # ^^^^^^^^^^^ + # + # foo in Bar[] + # ^^^^^^^^^^^^ + # + # foo in Bar[1, 2, 3] + # ^^^^^^^^^^^^^^^^^^^ + class ArrayPatternNode < Node + # Initialize a new ArrayPatternNode node. + def initialize(source, node_id, location, flags, constant, requireds, rest, posts, opening_loc, closing_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @constant = constant + @requireds = requireds + @rest = rest + @posts = posts + @opening_loc = opening_loc + @closing_loc = closing_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_array_pattern_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [constant, *requireds, rest, *posts] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << constant if constant + compact.concat(requireds) + compact << rest if rest + compact.concat(posts) + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*constant, *requireds, *rest, *posts, *opening_loc, *closing_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?constant: ConstantReadNode | ConstantPathNode | nil, ?requireds: Array[Prism::node], ?rest: Prism::node?, ?posts: Array[Prism::node], ?opening_loc: Location?, ?closing_loc: Location?) -> ArrayPatternNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, constant: self.constant, requireds: self.requireds, rest: self.rest, posts: self.posts, opening_loc: self.opening_loc, closing_loc: self.closing_loc) + ArrayPatternNode.new(source, node_id, location, flags, constant, requireds, rest, posts, opening_loc, closing_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, constant: ConstantReadNode | ConstantPathNode | nil, requireds: Array[Prism::node], rest: Prism::node?, posts: Array[Prism::node], opening_loc: Location?, closing_loc: Location? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, constant: constant, requireds: requireds, rest: rest, posts: posts, opening_loc: opening_loc, closing_loc: closing_loc } + end + + # attr_reader constant: ConstantReadNode | ConstantPathNode | nil + attr_reader :constant + + # Represents the required elements of the array pattern. + # + # foo in [1, 2] + # ^ ^ + attr_reader :requireds + + # Represents the rest element of the array pattern. + # + # foo in *bar + # ^^^^ + attr_reader :rest + + # Represents the elements after the rest element of the array pattern. + # + # foo in *bar, baz + # ^^^ + attr_reader :posts + + # Represents the opening location of the array pattern. + # + # foo in [1, 2] + # ^ + def opening_loc + location = @opening_loc + case location + when nil + nil + when Location + location + else + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) unless @opening_loc.nil? + end + + # Represents the closing location of the array pattern. + # + # foo in [1, 2] + # ^ + def closing_loc + location = @closing_loc + case location + when nil + nil + when Location + location + else + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) unless @closing_loc.nil? + end + + # def opening: () -> String? + def opening + opening_loc&.slice + end + + # def closing: () -> String? + def closing + closing_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :array_pattern_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :array_pattern_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ArrayPatternNode) && + (constant === other.constant) && + (requireds.length == other.requireds.length) && + requireds.zip(other.requireds).all? { |left, right| left === right } && + (rest === other.rest) && + (posts.length == other.posts.length) && + posts.zip(other.posts).all? { |left, right| left === right } && + (opening_loc.nil? == other.opening_loc.nil?) && + (closing_loc.nil? == other.closing_loc.nil?) + end + end + + # Represents a hash key/value pair. + # + # { a => b } + # ^^^^^^ + class AssocNode < Node + # Initialize a new AssocNode node. + def initialize(source, node_id, location, flags, key, value, operator_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @key = key + @value = value + @operator_loc = operator_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_assoc_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [key, value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [key, value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [key, value, *operator_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?key: Prism::node, ?value: Prism::node, ?operator_loc: Location?) -> AssocNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, key: self.key, value: self.value, operator_loc: self.operator_loc) + AssocNode.new(source, node_id, location, flags, key, value, operator_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, key: Prism::node, value: Prism::node, operator_loc: Location? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, key: key, value: value, operator_loc: operator_loc } + end + + # The key of the association. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # { a: b } + # ^ + # + # { foo => bar } + # ^^^ + # + # { def a; end => 1 } + # ^^^^^^^^^^ + attr_reader :key + + # The value of the association, if present. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # { foo => bar } + # ^^^ + # + # { x: 1 } + # ^ + attr_reader :value + + # The location of the `=>` operator, if present. + # + # { foo => bar } + # ^^ + def operator_loc + location = @operator_loc + case location + when nil + nil + when Location + location + else + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) unless @operator_loc.nil? + end + + # def operator: () -> String? + def operator + operator_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :assoc_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :assoc_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(AssocNode) && + (key === other.key) && + (value === other.value) && + (operator_loc.nil? == other.operator_loc.nil?) + end + end + + # Represents a splat in a hash literal. + # + # { **foo } + # ^^^^^ + class AssocSplatNode < Node + # Initialize a new AssocSplatNode node. + def initialize(source, node_id, location, flags, value, operator_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @value = value + @operator_loc = operator_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_assoc_splat_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << value if value + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*value, operator_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?value: Prism::node?, ?operator_loc: Location) -> AssocSplatNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, value: self.value, operator_loc: self.operator_loc) + AssocSplatNode.new(source, node_id, location, flags, value, operator_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, value: Prism::node?, operator_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, value: value, operator_loc: operator_loc } + end + + # The value to be splatted, if present. Will be missing when keyword rest argument forwarding is used. + # + # { **foo } + # ^^^ + attr_reader :value + + # The location of the `**` operator. + # + # { **x } + # ^^ + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :assoc_splat_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :assoc_splat_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(AssocSplatNode) && + (value === other.value) && + (operator_loc.nil? == other.operator_loc.nil?) + end + end + + # Represents reading a reference to a field in the previous match. + # + # $' + # ^^ + class BackReferenceReadNode < Node + # Initialize a new BackReferenceReadNode node. + def initialize(source, node_id, location, flags, name) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_back_reference_read_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> BackReferenceReadNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name) + BackReferenceReadNode.new(source, node_id, location, flags, name) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name } + end + + # The name of the back-reference variable, including the leading `$`. + # + # $& # name `:$&` + # + # $+ # name `:$+` + attr_reader :name + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :back_reference_read_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :back_reference_read_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(BackReferenceReadNode) && + (name === other.name) + end + end + + # Represents a begin statement. + # + # begin + # foo + # end + # ^^^^^ + class BeginNode < Node + # Initialize a new BeginNode node. + def initialize(source, node_id, location, flags, begin_keyword_loc, statements, rescue_clause, else_clause, ensure_clause, end_keyword_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @begin_keyword_loc = begin_keyword_loc + @statements = statements + @rescue_clause = rescue_clause + @else_clause = else_clause + @ensure_clause = ensure_clause + @end_keyword_loc = end_keyword_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_begin_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [statements, rescue_clause, else_clause, ensure_clause] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << statements if statements + compact << rescue_clause if rescue_clause + compact << else_clause if else_clause + compact << ensure_clause if ensure_clause + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*begin_keyword_loc, *statements, *rescue_clause, *else_clause, *ensure_clause, *end_keyword_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?begin_keyword_loc: Location?, ?statements: StatementsNode?, ?rescue_clause: RescueNode?, ?else_clause: ElseNode?, ?ensure_clause: EnsureNode?, ?end_keyword_loc: Location?) -> BeginNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, begin_keyword_loc: self.begin_keyword_loc, statements: self.statements, rescue_clause: self.rescue_clause, else_clause: self.else_clause, ensure_clause: self.ensure_clause, end_keyword_loc: self.end_keyword_loc) + BeginNode.new(source, node_id, location, flags, begin_keyword_loc, statements, rescue_clause, else_clause, ensure_clause, end_keyword_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, begin_keyword_loc: Location?, statements: StatementsNode?, rescue_clause: RescueNode?, else_clause: ElseNode?, ensure_clause: EnsureNode?, end_keyword_loc: Location? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, begin_keyword_loc: begin_keyword_loc, statements: statements, rescue_clause: rescue_clause, else_clause: else_clause, ensure_clause: ensure_clause, end_keyword_loc: end_keyword_loc } + end + + # Represents the location of the `begin` keyword. + # + # begin x end + # ^^^^^ + def begin_keyword_loc + location = @begin_keyword_loc + case location + when nil + nil + when Location + location + else + @begin_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the begin_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_begin_keyword_loc(repository) + repository.enter(node_id, :begin_keyword_loc) unless @begin_keyword_loc.nil? + end + + # Represents the statements within the begin block. + # + # begin x end + # ^ + attr_reader :statements + + # Represents the rescue clause within the begin block. + # + # begin x; rescue y; end + # ^^^^^^^^ + attr_reader :rescue_clause + + # Represents the else clause within the begin block. + # + # begin x; rescue y; else z; end + # ^^^^^^ + attr_reader :else_clause + + # Represents the ensure clause within the begin block. + # + # begin x; ensure y; end + # ^^^^^^^^ + attr_reader :ensure_clause + + # Represents the location of the `end` keyword. + # + # begin x end + # ^^^ + def end_keyword_loc + location = @end_keyword_loc + case location + when nil + nil + when Location + location + else + @end_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the end_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_end_keyword_loc(repository) + repository.enter(node_id, :end_keyword_loc) unless @end_keyword_loc.nil? + end + + # def begin_keyword: () -> String? + def begin_keyword + begin_keyword_loc&.slice + end + + # def end_keyword: () -> String? + def end_keyword + end_keyword_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :begin_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :begin_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(BeginNode) && + (begin_keyword_loc.nil? == other.begin_keyword_loc.nil?) && + (statements === other.statements) && + (rescue_clause === other.rescue_clause) && + (else_clause === other.else_clause) && + (ensure_clause === other.ensure_clause) && + (end_keyword_loc.nil? == other.end_keyword_loc.nil?) + end + end + + # Represents a block argument using `&`. + # + # bar(&args) + # ^^^^^^^^^^ + class BlockArgumentNode < Node + # Initialize a new BlockArgumentNode node. + def initialize(source, node_id, location, flags, expression, operator_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @expression = expression + @operator_loc = operator_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_block_argument_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [expression] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << expression if expression + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*expression, operator_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?expression: Prism::node?, ?operator_loc: Location) -> BlockArgumentNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, expression: self.expression, operator_loc: self.operator_loc) + BlockArgumentNode.new(source, node_id, location, flags, expression, operator_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, expression: Prism::node?, operator_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, expression: expression, operator_loc: operator_loc } + end + + # The expression that is being passed as a block argument. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # foo(&args) + # ^^^^^ + attr_reader :expression + + # Represents the location of the `&` operator. + # + # foo(&args) + # ^ + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :block_argument_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :block_argument_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(BlockArgumentNode) && + (expression === other.expression) && + (operator_loc.nil? == other.operator_loc.nil?) + end + end + + # Represents a block local variable. + # + # a { |; b| } + # ^ + class BlockLocalVariableNode < Node + # Initialize a new BlockLocalVariableNode node. + def initialize(source, node_id, location, flags, name) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_block_local_variable_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> BlockLocalVariableNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name) + BlockLocalVariableNode.new(source, node_id, location, flags, name) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name } + end + + # def repeated_parameter?: () -> bool + def repeated_parameter? + flags.anybits?(ParameterFlags::REPEATED_PARAMETER) + end + + # The name of the block local variable. + # + # a { |; b| } # name `:b` + # ^ + attr_reader :name + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :block_local_variable_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :block_local_variable_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(BlockLocalVariableNode) && + (flags === other.flags) && + (name === other.name) + end + end + + # Represents a block of ruby code. + # + # [1, 2, 3].each { |i| puts x } + # ^^^^^^^^^^^^^^ + class BlockNode < Node + # Initialize a new BlockNode node. + def initialize(source, node_id, location, flags, locals, parameters, body, opening_loc, closing_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @locals = locals + @parameters = parameters + @body = body + @opening_loc = opening_loc + @closing_loc = closing_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_block_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [parameters, body] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << parameters if parameters + compact << body if body + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*parameters, *body, opening_loc, closing_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?locals: Array[Symbol], ?parameters: BlockParametersNode | NumberedParametersNode | ItParametersNode | nil, ?body: StatementsNode | BeginNode | nil, ?opening_loc: Location, ?closing_loc: Location) -> BlockNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, locals: self.locals, parameters: self.parameters, body: self.body, opening_loc: self.opening_loc, closing_loc: self.closing_loc) + BlockNode.new(source, node_id, location, flags, locals, parameters, body, opening_loc, closing_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, locals: Array[Symbol], parameters: BlockParametersNode | NumberedParametersNode | ItParametersNode | nil, body: StatementsNode | BeginNode | nil, opening_loc: Location, closing_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, locals: locals, parameters: parameters, body: body, opening_loc: opening_loc, closing_loc: closing_loc } + end + + # The local variables declared in the block. + # + # [1, 2, 3].each { |i| puts x } # locals: [:i] + # ^ + attr_reader :locals + + # The parameters of the block. + # + # [1, 2, 3].each { |i| puts x } + # ^^^ + # [1, 2, 3].each { puts _1 } + # ^^^^^^^^^^^ + # [1, 2, 3].each { puts it } + # ^^^^^^^^^^^ + attr_reader :parameters + + # The body of the block. + # + # [1, 2, 3].each { |i| puts x } + # ^^^^^^ + attr_reader :body + + # Represents the location of the opening `|`. + # + # [1, 2, 3].each { |i| puts x } + # ^ + def opening_loc + location = @opening_loc + return location if location.is_a?(Location) + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) + end + + # Represents the location of the closing `|`. + # + # [1, 2, 3].each { |i| puts x } + # ^ + def closing_loc + location = @closing_loc + return location if location.is_a?(Location) + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) + end + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :block_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :block_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(BlockNode) && + (locals.length == other.locals.length) && + locals.zip(other.locals).all? { |left, right| left === right } && + (parameters === other.parameters) && + (body === other.body) && + (opening_loc.nil? == other.opening_loc.nil?) && + (closing_loc.nil? == other.closing_loc.nil?) + end + end + + # Represents a block parameter of a method, block, or lambda definition. + # + # def a(&b) + # ^^ + # end + class BlockParameterNode < Node + # Initialize a new BlockParameterNode node. + def initialize(source, node_id, location, flags, name, name_loc, operator_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @name_loc = name_loc + @operator_loc = operator_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_block_parameter_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*name_loc, operator_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol?, ?name_loc: Location?, ?operator_loc: Location) -> BlockParameterNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc) + BlockParameterNode.new(source, node_id, location, flags, name, name_loc, operator_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol?, name_loc: Location?, operator_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, name_loc: name_loc, operator_loc: operator_loc } + end + + # def repeated_parameter?: () -> bool + def repeated_parameter? + flags.anybits?(ParameterFlags::REPEATED_PARAMETER) + end + + # The name of the block parameter. + # + # def a(&b) # name `:b` + # ^ + # end + attr_reader :name + + # Represents the location of the block parameter name. + # + # def a(&b) + # ^ + def name_loc + location = @name_loc + case location + when nil + nil + when Location + location + else + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) unless @name_loc.nil? + end + + # Represents the location of the `&` operator. + # + # def a(&b) + # ^ + # end + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :block_parameter_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :block_parameter_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(BlockParameterNode) && + (flags === other.flags) && + (name === other.name) && + (name_loc.nil? == other.name_loc.nil?) && + (operator_loc.nil? == other.operator_loc.nil?) + end + end + + # Represents a block's parameters declaration. + # + # -> (a, b = 1; local) { } + # ^^^^^^^^^^^^^^^^^ + # + # foo do |a, b = 1; local| + # ^^^^^^^^^^^^^^^^^ + # end + class BlockParametersNode < Node + # Initialize a new BlockParametersNode node. + def initialize(source, node_id, location, flags, parameters, locals, opening_loc, closing_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @parameters = parameters + @locals = locals + @opening_loc = opening_loc + @closing_loc = closing_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_block_parameters_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [parameters, *locals] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << parameters if parameters + compact.concat(locals) + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*parameters, *locals, *opening_loc, *closing_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?parameters: ParametersNode?, ?locals: Array[BlockLocalVariableNode], ?opening_loc: Location?, ?closing_loc: Location?) -> BlockParametersNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, parameters: self.parameters, locals: self.locals, opening_loc: self.opening_loc, closing_loc: self.closing_loc) + BlockParametersNode.new(source, node_id, location, flags, parameters, locals, opening_loc, closing_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, parameters: ParametersNode?, locals: Array[BlockLocalVariableNode], opening_loc: Location?, closing_loc: Location? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, parameters: parameters, locals: locals, opening_loc: opening_loc, closing_loc: closing_loc } + end + + # Represents the parameters of the block. + # + # -> (a, b = 1; local) { } + # ^^^^^^^^ + # + # foo do |a, b = 1; local| + # ^^^^^^^^ + # end + attr_reader :parameters + + # Represents the local variables of the block. + # + # -> (a, b = 1; local) { } + # ^^^^^ + # + # foo do |a, b = 1; local| + # ^^^^^ + # end + attr_reader :locals + + # Represents the opening location of the block parameters. + # + # -> (a, b = 1; local) { } + # ^ + # + # foo do |a, b = 1; local| + # ^ + # end + def opening_loc + location = @opening_loc + case location + when nil + nil + when Location + location + else + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) unless @opening_loc.nil? + end + + # Represents the closing location of the block parameters. + # + # -> (a, b = 1; local) { } + # ^ + # + # foo do |a, b = 1; local| + # ^ + # end + def closing_loc + location = @closing_loc + case location + when nil + nil + when Location + location + else + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) unless @closing_loc.nil? + end + + # def opening: () -> String? + def opening + opening_loc&.slice + end + + # def closing: () -> String? + def closing + closing_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :block_parameters_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :block_parameters_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(BlockParametersNode) && + (parameters === other.parameters) && + (locals.length == other.locals.length) && + locals.zip(other.locals).all? { |left, right| left === right } && + (opening_loc.nil? == other.opening_loc.nil?) && + (closing_loc.nil? == other.closing_loc.nil?) + end + end + + # Represents the use of the `break` keyword. + # + # break foo + # ^^^^^^^^^ + class BreakNode < Node + # Initialize a new BreakNode node. + def initialize(source, node_id, location, flags, arguments, keyword_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @arguments = arguments + @keyword_loc = keyword_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_break_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [arguments] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << arguments if arguments + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*arguments, keyword_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?arguments: ArgumentsNode?, ?keyword_loc: Location) -> BreakNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, arguments: self.arguments, keyword_loc: self.keyword_loc) + BreakNode.new(source, node_id, location, flags, arguments, keyword_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, arguments: ArgumentsNode?, keyword_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, arguments: arguments, keyword_loc: keyword_loc } + end + + # The arguments to the break statement, if present. These can be any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # break foo + # ^^^ + attr_reader :arguments + + # The location of the `break` keyword. + # + # break foo + # ^^^^^ + def keyword_loc + location = @keyword_loc + return location if location.is_a?(Location) + @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_keyword_loc(repository) + repository.enter(node_id, :keyword_loc) + end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :break_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :break_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(BreakNode) && + (arguments === other.arguments) && + (keyword_loc.nil? == other.keyword_loc.nil?) + end + end + + # Represents the use of the `&&=` operator on a call. + # + # foo.bar &&= value + # ^^^^^^^^^^^^^^^^^ + class CallAndWriteNode < Node + # Initialize a new CallAndWriteNode node. + def initialize(source, node_id, location, flags, receiver, call_operator_loc, message_loc, read_name, write_name, operator_loc, value) + @source = source + @node_id = node_id + @location = location + @flags = flags + @receiver = receiver + @call_operator_loc = call_operator_loc + @message_loc = message_loc + @read_name = read_name + @write_name = write_name + @operator_loc = operator_loc + @value = value + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_call_and_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [receiver, value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << receiver if receiver + compact << value + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*receiver, *call_operator_loc, *message_loc, operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?message_loc: Location?, ?read_name: Symbol, ?write_name: Symbol, ?operator_loc: Location, ?value: Prism::node) -> CallAndWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, message_loc: self.message_loc, read_name: self.read_name, write_name: self.write_name, operator_loc: self.operator_loc, value: self.value) + CallAndWriteNode.new(source, node_id, location, flags, receiver, call_operator_loc, message_loc, read_name, write_name, operator_loc, value) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, message_loc: Location?, read_name: Symbol, write_name: Symbol, operator_loc: Location, value: Prism::node } + def deconstruct_keys(keys) + { node_id: node_id, location: location, receiver: receiver, call_operator_loc: call_operator_loc, message_loc: message_loc, read_name: read_name, write_name: write_name, operator_loc: operator_loc, value: value } + end + + # def safe_navigation?: () -> bool + def safe_navigation? + flags.anybits?(CallNodeFlags::SAFE_NAVIGATION) + end + + # def variable_call?: () -> bool + def variable_call? + flags.anybits?(CallNodeFlags::VARIABLE_CALL) + end + + # def attribute_write?: () -> bool + def attribute_write? + flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE) + end + + # def ignore_visibility?: () -> bool + def ignore_visibility? + flags.anybits?(CallNodeFlags::IGNORE_VISIBILITY) + end + + # The object that the method is being called on. This can be either `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # foo.bar &&= value + # ^^^ + attr_reader :receiver + + # Represents the location of the call operator. + # + # foo.bar &&= value + # ^ + def call_operator_loc + location = @call_operator_loc + case location + when nil + nil + when Location + location + else + @call_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the call_operator_loc location using the given saved source so that + # it can be retrieved later. + def save_call_operator_loc(repository) + repository.enter(node_id, :call_operator_loc) unless @call_operator_loc.nil? + end + + # Represents the location of the message. + # + # foo.bar &&= value + # ^^^ + def message_loc + location = @message_loc + case location + when nil + nil + when Location + location + else + @message_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the message_loc location using the given saved source so that + # it can be retrieved later. + def save_message_loc(repository) + repository.enter(node_id, :message_loc) unless @message_loc.nil? + end + + # Represents the name of the method being called. + # + # foo.bar &&= value # read_name `:bar` + # ^^^ + attr_reader :read_name + + # Represents the name of the method being written to. + # + # foo.bar &&= value # write_name `:bar=` + # ^^^ + attr_reader :write_name + + # Represents the location of the operator. + # + # foo.bar &&= value + # ^^^ + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # Represents the value being assigned. + # + # foo.bar &&= value + # ^^^^^ + attr_reader :value + + # def call_operator: () -> String? + def call_operator + call_operator_loc&.slice + end + + # def message: () -> String? + def message + message_loc&.slice + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :call_and_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :call_and_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(CallAndWriteNode) && + (flags === other.flags) && + (receiver === other.receiver) && + (call_operator_loc.nil? == other.call_operator_loc.nil?) && + (message_loc.nil? == other.message_loc.nil?) && + (read_name === other.read_name) && + (write_name === other.write_name) && + (operator_loc.nil? == other.operator_loc.nil?) && + (value === other.value) + end + end + + # Represents a method call, in all of the various forms that can take. + # + # foo + # ^^^ + # + # foo() + # ^^^^^ + # + # +foo + # ^^^^ + # + # foo + bar + # ^^^^^^^^^ + # + # foo.bar + # ^^^^^^^ + # + # foo&.bar + # ^^^^^^^^ + class CallNode < Node + # Initialize a new CallNode node. + def initialize(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc, opening_loc, arguments, closing_loc, block) + @source = source + @node_id = node_id + @location = location + @flags = flags + @receiver = receiver + @call_operator_loc = call_operator_loc + @name = name + @message_loc = message_loc + @opening_loc = opening_loc + @arguments = arguments + @closing_loc = closing_loc + @block = block + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_call_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [receiver, arguments, block] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << receiver if receiver + compact << arguments if arguments + compact << block if block + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*receiver, *call_operator_loc, *message_loc, *opening_loc, *arguments, *closing_loc, *block] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?name: Symbol, ?message_loc: Location?, ?opening_loc: Location?, ?arguments: ArgumentsNode?, ?closing_loc: Location?, ?block: BlockNode | BlockArgumentNode | nil) -> CallNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, name: self.name, message_loc: self.message_loc, opening_loc: self.opening_loc, arguments: self.arguments, closing_loc: self.closing_loc, block: self.block) + CallNode.new(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc, opening_loc, arguments, closing_loc, block) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, name: Symbol, message_loc: Location?, opening_loc: Location?, arguments: ArgumentsNode?, closing_loc: Location?, block: BlockNode | BlockArgumentNode | nil } + def deconstruct_keys(keys) + { node_id: node_id, location: location, receiver: receiver, call_operator_loc: call_operator_loc, name: name, message_loc: message_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block } + end + + # def safe_navigation?: () -> bool + def safe_navigation? + flags.anybits?(CallNodeFlags::SAFE_NAVIGATION) + end + + # def variable_call?: () -> bool + def variable_call? + flags.anybits?(CallNodeFlags::VARIABLE_CALL) + end + + # def attribute_write?: () -> bool + def attribute_write? + flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE) + end + + # def ignore_visibility?: () -> bool + def ignore_visibility? + flags.anybits?(CallNodeFlags::IGNORE_VISIBILITY) + end + + # The object that the method is being called on. This can be either `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # foo.bar + # ^^^ + # + # +foo + # ^^^ + # + # foo + bar + # ^^^ + attr_reader :receiver + + # Represents the location of the call operator. + # + # foo.bar + # ^ + # + # foo&.bar + # ^^ + def call_operator_loc + location = @call_operator_loc + case location + when nil + nil + when Location + location + else + @call_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the call_operator_loc location using the given saved source so that + # it can be retrieved later. + def save_call_operator_loc(repository) + repository.enter(node_id, :call_operator_loc) unless @call_operator_loc.nil? + end + + # Represents the name of the method being called. + # + # foo.bar # name `:foo` + # ^^^ + attr_reader :name + + # Represents the location of the message. + # + # foo.bar + # ^^^ + def message_loc + location = @message_loc + case location + when nil + nil + when Location + location + else + @message_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the message_loc location using the given saved source so that + # it can be retrieved later. + def save_message_loc(repository) + repository.enter(node_id, :message_loc) unless @message_loc.nil? + end + + # Represents the location of the left parenthesis. + # foo(bar) + # ^ + def opening_loc + location = @opening_loc + case location + when nil + nil + when Location + location + else + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) unless @opening_loc.nil? + end + + # Represents the arguments to the method call. These can be any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # foo(bar) + # ^^^ + attr_reader :arguments + + # Represents the location of the right parenthesis. + # + # foo(bar) + # ^ + def closing_loc + location = @closing_loc + case location + when nil + nil + when Location + location + else + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) unless @closing_loc.nil? + end + + # Represents the block that is being passed to the method. + # + # foo { |a| a } + # ^^^^^^^^^ + attr_reader :block + + # def call_operator: () -> String? + def call_operator + call_operator_loc&.slice + end + + # def message: () -> String? + def message + message_loc&.slice + end + + # def opening: () -> String? + def opening + opening_loc&.slice + end + + # def closing: () -> String? + def closing + closing_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :call_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :call_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(CallNode) && + (flags === other.flags) && + (receiver === other.receiver) && + (call_operator_loc.nil? == other.call_operator_loc.nil?) && + (name === other.name) && + (message_loc.nil? == other.message_loc.nil?) && + (opening_loc.nil? == other.opening_loc.nil?) && + (arguments === other.arguments) && + (closing_loc.nil? == other.closing_loc.nil?) && + (block === other.block) + end + end + + # Represents the use of an assignment operator on a call. + # + # foo.bar += baz + # ^^^^^^^^^^^^^^ + class CallOperatorWriteNode < Node + # Initialize a new CallOperatorWriteNode node. + def initialize(source, node_id, location, flags, receiver, call_operator_loc, message_loc, read_name, write_name, binary_operator, binary_operator_loc, value) + @source = source + @node_id = node_id + @location = location + @flags = flags + @receiver = receiver + @call_operator_loc = call_operator_loc + @message_loc = message_loc + @read_name = read_name + @write_name = write_name + @binary_operator = binary_operator + @binary_operator_loc = binary_operator_loc + @value = value + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_call_operator_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [receiver, value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << receiver if receiver + compact << value + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*receiver, *call_operator_loc, *message_loc, binary_operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?message_loc: Location?, ?read_name: Symbol, ?write_name: Symbol, ?binary_operator: Symbol, ?binary_operator_loc: Location, ?value: Prism::node) -> CallOperatorWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, message_loc: self.message_loc, read_name: self.read_name, write_name: self.write_name, binary_operator: self.binary_operator, binary_operator_loc: self.binary_operator_loc, value: self.value) + CallOperatorWriteNode.new(source, node_id, location, flags, receiver, call_operator_loc, message_loc, read_name, write_name, binary_operator, binary_operator_loc, value) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, message_loc: Location?, read_name: Symbol, write_name: Symbol, binary_operator: Symbol, binary_operator_loc: Location, value: Prism::node } + def deconstruct_keys(keys) + { node_id: node_id, location: location, receiver: receiver, call_operator_loc: call_operator_loc, message_loc: message_loc, read_name: read_name, write_name: write_name, binary_operator: binary_operator, binary_operator_loc: binary_operator_loc, value: value } + end + + # def safe_navigation?: () -> bool + def safe_navigation? + flags.anybits?(CallNodeFlags::SAFE_NAVIGATION) + end + + # def variable_call?: () -> bool + def variable_call? + flags.anybits?(CallNodeFlags::VARIABLE_CALL) + end + + # def attribute_write?: () -> bool + def attribute_write? + flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE) + end + + # def ignore_visibility?: () -> bool + def ignore_visibility? + flags.anybits?(CallNodeFlags::IGNORE_VISIBILITY) + end + + # The object that the method is being called on. This can be either `nil` or any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # foo.bar += value + # ^^^ + attr_reader :receiver + + # Represents the location of the call operator. + # + # foo.bar += value + # ^ + def call_operator_loc + location = @call_operator_loc + case location + when nil + nil + when Location + location + else + @call_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the call_operator_loc location using the given saved source so that + # it can be retrieved later. + def save_call_operator_loc(repository) + repository.enter(node_id, :call_operator_loc) unless @call_operator_loc.nil? + end + + # Represents the location of the message. + # + # foo.bar += value + # ^^^ + def message_loc + location = @message_loc + case location + when nil + nil + when Location + location + else + @message_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the message_loc location using the given saved source so that + # it can be retrieved later. + def save_message_loc(repository) + repository.enter(node_id, :message_loc) unless @message_loc.nil? + end + + # Represents the name of the method being called. + # + # foo.bar += value # read_name `:bar` + # ^^^ + attr_reader :read_name + + # Represents the name of the method being written to. + # + # foo.bar += value # write_name `:bar=` + # ^^^ + attr_reader :write_name + + # Represents the binary operator being used. + # + # foo.bar += value # binary_operator `:+` + # ^ + attr_reader :binary_operator + + # Represents the location of the binary operator. + # + # foo.bar += value + # ^^ + def binary_operator_loc + location = @binary_operator_loc + return location if location.is_a?(Location) + @binary_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the binary_operator_loc location using the given saved source so that + # it can be retrieved later. + def save_binary_operator_loc(repository) + repository.enter(node_id, :binary_operator_loc) + end + + # Represents the value being assigned. + # + # foo.bar += value + # ^^^^^ + attr_reader :value + + # def call_operator: () -> String? + def call_operator + call_operator_loc&.slice + end + + # def message: () -> String? + def message + message_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :call_operator_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :call_operator_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(CallOperatorWriteNode) && + (flags === other.flags) && + (receiver === other.receiver) && + (call_operator_loc.nil? == other.call_operator_loc.nil?) && + (message_loc.nil? == other.message_loc.nil?) && + (read_name === other.read_name) && + (write_name === other.write_name) && + (binary_operator === other.binary_operator) && + (binary_operator_loc.nil? == other.binary_operator_loc.nil?) && + (value === other.value) + end + end + + # Represents the use of the `||=` operator on a call. + # + # foo.bar ||= value + # ^^^^^^^^^^^^^^^^^ + class CallOrWriteNode < Node + # Initialize a new CallOrWriteNode node. + def initialize(source, node_id, location, flags, receiver, call_operator_loc, message_loc, read_name, write_name, operator_loc, value) + @source = source + @node_id = node_id + @location = location + @flags = flags + @receiver = receiver + @call_operator_loc = call_operator_loc + @message_loc = message_loc + @read_name = read_name + @write_name = write_name + @operator_loc = operator_loc + @value = value + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_call_or_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [receiver, value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << receiver if receiver + compact << value + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*receiver, *call_operator_loc, *message_loc, operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?message_loc: Location?, ?read_name: Symbol, ?write_name: Symbol, ?operator_loc: Location, ?value: Prism::node) -> CallOrWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, message_loc: self.message_loc, read_name: self.read_name, write_name: self.write_name, operator_loc: self.operator_loc, value: self.value) + CallOrWriteNode.new(source, node_id, location, flags, receiver, call_operator_loc, message_loc, read_name, write_name, operator_loc, value) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, message_loc: Location?, read_name: Symbol, write_name: Symbol, operator_loc: Location, value: Prism::node } + def deconstruct_keys(keys) + { node_id: node_id, location: location, receiver: receiver, call_operator_loc: call_operator_loc, message_loc: message_loc, read_name: read_name, write_name: write_name, operator_loc: operator_loc, value: value } + end + + # def safe_navigation?: () -> bool + def safe_navigation? + flags.anybits?(CallNodeFlags::SAFE_NAVIGATION) + end + + # def variable_call?: () -> bool + def variable_call? + flags.anybits?(CallNodeFlags::VARIABLE_CALL) + end + + # def attribute_write?: () -> bool + def attribute_write? + flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE) + end + + # def ignore_visibility?: () -> bool + def ignore_visibility? + flags.anybits?(CallNodeFlags::IGNORE_VISIBILITY) + end + + # The object that the method is being called on. This can be either `nil` or any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # foo.bar ||= value + # ^^^ + attr_reader :receiver + + # Represents the location of the call operator. + # + # foo.bar ||= value + # ^ + def call_operator_loc + location = @call_operator_loc + case location + when nil + nil + when Location + location + else + @call_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the call_operator_loc location using the given saved source so that + # it can be retrieved later. + def save_call_operator_loc(repository) + repository.enter(node_id, :call_operator_loc) unless @call_operator_loc.nil? + end + + # Represents the location of the message. + # + # foo.bar ||= value + # ^^^ + def message_loc + location = @message_loc + case location + when nil + nil + when Location + location + else + @message_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the message_loc location using the given saved source so that + # it can be retrieved later. + def save_message_loc(repository) + repository.enter(node_id, :message_loc) unless @message_loc.nil? + end + + # Represents the name of the method being called. + # + # foo.bar ||= value # read_name `:bar` + # ^^^ + attr_reader :read_name + + # Represents the name of the method being written to. + # + # foo.bar ||= value # write_name `:bar=` + # ^^^ + attr_reader :write_name + + # Represents the location of the operator. + # + # foo.bar ||= value + # ^^^ + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # Represents the value being assigned. + # + # foo.bar ||= value + # ^^^^^ + attr_reader :value + + # def call_operator: () -> String? + def call_operator + call_operator_loc&.slice + end + + # def message: () -> String? + def message + message_loc&.slice + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :call_or_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :call_or_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(CallOrWriteNode) && + (flags === other.flags) && + (receiver === other.receiver) && + (call_operator_loc.nil? == other.call_operator_loc.nil?) && + (message_loc.nil? == other.message_loc.nil?) && + (read_name === other.read_name) && + (write_name === other.write_name) && + (operator_loc.nil? == other.operator_loc.nil?) && + (value === other.value) + end + end + + # Represents assigning to a method call. + # + # foo.bar, = 1 + # ^^^^^^^ + # + # begin + # rescue => foo.bar + # ^^^^^^^ + # end + # + # for foo.bar in baz do end + # ^^^^^^^ + class CallTargetNode < Node + # Initialize a new CallTargetNode node. + def initialize(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @receiver = receiver + @call_operator_loc = call_operator_loc + @name = name + @message_loc = message_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_call_target_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [receiver] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [receiver] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [receiver, call_operator_loc, message_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node, ?call_operator_loc: Location, ?name: Symbol, ?message_loc: Location) -> CallTargetNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, name: self.name, message_loc: self.message_loc) + CallTargetNode.new(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node, call_operator_loc: Location, name: Symbol, message_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, receiver: receiver, call_operator_loc: call_operator_loc, name: name, message_loc: message_loc } + end + + # def safe_navigation?: () -> bool + def safe_navigation? + flags.anybits?(CallNodeFlags::SAFE_NAVIGATION) + end + + # def variable_call?: () -> bool + def variable_call? + flags.anybits?(CallNodeFlags::VARIABLE_CALL) + end + + # def attribute_write?: () -> bool + def attribute_write? + flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE) + end + + # def ignore_visibility?: () -> bool + def ignore_visibility? + flags.anybits?(CallNodeFlags::IGNORE_VISIBILITY) + end + + # The object that the method is being called on. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # foo.bar = 1 + # ^^^ + attr_reader :receiver + + # Represents the location of the call operator. + # + # foo.bar = 1 + # ^ + def call_operator_loc + location = @call_operator_loc + return location if location.is_a?(Location) + @call_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the call_operator_loc location using the given saved source so that + # it can be retrieved later. + def save_call_operator_loc(repository) + repository.enter(node_id, :call_operator_loc) + end + + # Represents the name of the method being called. + # + # foo.bar = 1 # name `:foo` + # ^^^ + attr_reader :name + + # Represents the location of the message. + # + # foo.bar = 1 + # ^^^ + def message_loc + location = @message_loc + return location if location.is_a?(Location) + @message_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the message_loc location using the given saved source so that + # it can be retrieved later. + def save_message_loc(repository) + repository.enter(node_id, :message_loc) + end + + # def call_operator: () -> String + def call_operator + call_operator_loc.slice + end + + # def message: () -> String + def message + message_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :call_target_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :call_target_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(CallTargetNode) && + (flags === other.flags) && + (receiver === other.receiver) && + (call_operator_loc.nil? == other.call_operator_loc.nil?) && + (name === other.name) && + (message_loc.nil? == other.message_loc.nil?) + end + end + + # Represents assigning to a local variable in pattern matching. + # + # foo => [bar => baz] + # ^^^^^^^^^^^^ + class CapturePatternNode < Node + # Initialize a new CapturePatternNode node. + def initialize(source, node_id, location, flags, value, target, operator_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @value = value + @target = target + @operator_loc = operator_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_capture_pattern_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value, target] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value, target] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [value, target, operator_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?value: Prism::node, ?target: LocalVariableTargetNode, ?operator_loc: Location) -> CapturePatternNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, value: self.value, target: self.target, operator_loc: self.operator_loc) + CapturePatternNode.new(source, node_id, location, flags, value, target, operator_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, value: Prism::node, target: LocalVariableTargetNode, operator_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, value: value, target: target, operator_loc: operator_loc } + end + + # Represents the value to capture. + # + # foo => bar + # ^^^ + attr_reader :value + + # Represents the target of the capture. + # + # foo => bar + # ^^^ + attr_reader :target + + # Represents the location of the `=>` operator. + # + # foo => bar + # ^^ + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :capture_pattern_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :capture_pattern_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(CapturePatternNode) && + (value === other.value) && + (target === other.target) && + (operator_loc.nil? == other.operator_loc.nil?) + end + end + + # Represents the use of a case statement for pattern matching. + # + # case true + # in false + # end + # ^^^^^^^^^ + class CaseMatchNode < Node + # Initialize a new CaseMatchNode node. + def initialize(source, node_id, location, flags, predicate, conditions, else_clause, case_keyword_loc, end_keyword_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @predicate = predicate + @conditions = conditions + @else_clause = else_clause + @case_keyword_loc = case_keyword_loc + @end_keyword_loc = end_keyword_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_case_match_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [predicate, *conditions, else_clause] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << predicate if predicate + compact.concat(conditions) + compact << else_clause if else_clause + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*predicate, *conditions, *else_clause, case_keyword_loc, end_keyword_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?predicate: Prism::node?, ?conditions: Array[InNode], ?else_clause: ElseNode?, ?case_keyword_loc: Location, ?end_keyword_loc: Location) -> CaseMatchNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, predicate: self.predicate, conditions: self.conditions, else_clause: self.else_clause, case_keyword_loc: self.case_keyword_loc, end_keyword_loc: self.end_keyword_loc) + CaseMatchNode.new(source, node_id, location, flags, predicate, conditions, else_clause, case_keyword_loc, end_keyword_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, predicate: Prism::node?, conditions: Array[InNode], else_clause: ElseNode?, case_keyword_loc: Location, end_keyword_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, predicate: predicate, conditions: conditions, else_clause: else_clause, case_keyword_loc: case_keyword_loc, end_keyword_loc: end_keyword_loc } + end + + # Represents the predicate of the case match. This can be either `nil` or any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # case true; in false; end + # ^^^^ + attr_reader :predicate + + # Represents the conditions of the case match. + # + # case true; in false; end + # ^^^^^^^^ + attr_reader :conditions + + # Represents the else clause of the case match. + # + # case true; in false; else; end + # ^^^^ + attr_reader :else_clause + + # Represents the location of the `case` keyword. + # + # case true; in false; end + # ^^^^ + def case_keyword_loc + location = @case_keyword_loc + return location if location.is_a?(Location) + @case_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the case_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_case_keyword_loc(repository) + repository.enter(node_id, :case_keyword_loc) + end + + # Represents the location of the `end` keyword. + # + # case true; in false; end + # ^^^ + def end_keyword_loc + location = @end_keyword_loc + return location if location.is_a?(Location) + @end_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the end_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_end_keyword_loc(repository) + repository.enter(node_id, :end_keyword_loc) + end + + # def case_keyword: () -> String + def case_keyword + case_keyword_loc.slice + end + + # def end_keyword: () -> String + def end_keyword + end_keyword_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :case_match_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :case_match_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(CaseMatchNode) && + (predicate === other.predicate) && + (conditions.length == other.conditions.length) && + conditions.zip(other.conditions).all? { |left, right| left === right } && + (else_clause === other.else_clause) && + (case_keyword_loc.nil? == other.case_keyword_loc.nil?) && + (end_keyword_loc.nil? == other.end_keyword_loc.nil?) + end + end + + # Represents the use of a case statement. + # + # case true + # when false + # end + # ^^^^^^^^^^ + class CaseNode < Node + # Initialize a new CaseNode node. + def initialize(source, node_id, location, flags, predicate, conditions, else_clause, case_keyword_loc, end_keyword_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @predicate = predicate + @conditions = conditions + @else_clause = else_clause + @case_keyword_loc = case_keyword_loc + @end_keyword_loc = end_keyword_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_case_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [predicate, *conditions, else_clause] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << predicate if predicate + compact.concat(conditions) + compact << else_clause if else_clause + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*predicate, *conditions, *else_clause, case_keyword_loc, end_keyword_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?predicate: Prism::node?, ?conditions: Array[WhenNode], ?else_clause: ElseNode?, ?case_keyword_loc: Location, ?end_keyword_loc: Location) -> CaseNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, predicate: self.predicate, conditions: self.conditions, else_clause: self.else_clause, case_keyword_loc: self.case_keyword_loc, end_keyword_loc: self.end_keyword_loc) + CaseNode.new(source, node_id, location, flags, predicate, conditions, else_clause, case_keyword_loc, end_keyword_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, predicate: Prism::node?, conditions: Array[WhenNode], else_clause: ElseNode?, case_keyword_loc: Location, end_keyword_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, predicate: predicate, conditions: conditions, else_clause: else_clause, case_keyword_loc: case_keyword_loc, end_keyword_loc: end_keyword_loc } + end + + # Represents the predicate of the case statement. This can be either `nil` or any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # case true; when false; end + # ^^^^ + attr_reader :predicate + + # Represents the conditions of the case statement. + # + # case true; when false; end + # ^^^^^^^^^^ + attr_reader :conditions + + # Represents the else clause of the case statement. + # + # case true; when false; else; end + # ^^^^ + attr_reader :else_clause + + # Represents the location of the `case` keyword. + # + # case true; when false; end + # ^^^^ + def case_keyword_loc + location = @case_keyword_loc + return location if location.is_a?(Location) + @case_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the case_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_case_keyword_loc(repository) + repository.enter(node_id, :case_keyword_loc) + end + + # Represents the location of the `end` keyword. + # + # case true; when false; end + # ^^^ + def end_keyword_loc + location = @end_keyword_loc + return location if location.is_a?(Location) + @end_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the end_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_end_keyword_loc(repository) + repository.enter(node_id, :end_keyword_loc) + end + + # def case_keyword: () -> String + def case_keyword + case_keyword_loc.slice + end + + # def end_keyword: () -> String + def end_keyword + end_keyword_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :case_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :case_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(CaseNode) && + (predicate === other.predicate) && + (conditions.length == other.conditions.length) && + conditions.zip(other.conditions).all? { |left, right| left === right } && + (else_clause === other.else_clause) && + (case_keyword_loc.nil? == other.case_keyword_loc.nil?) && + (end_keyword_loc.nil? == other.end_keyword_loc.nil?) + end + end + + # Represents a class declaration involving the `class` keyword. + # + # class Foo end + # ^^^^^^^^^^^^^ + class ClassNode < Node + # Initialize a new ClassNode node. + def initialize(source, node_id, location, flags, locals, class_keyword_loc, constant_path, inheritance_operator_loc, superclass, body, end_keyword_loc, name) + @source = source + @node_id = node_id + @location = location + @flags = flags + @locals = locals + @class_keyword_loc = class_keyword_loc + @constant_path = constant_path + @inheritance_operator_loc = inheritance_operator_loc + @superclass = superclass + @body = body + @end_keyword_loc = end_keyword_loc + @name = name + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_class_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [constant_path, superclass, body] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << constant_path + compact << superclass if superclass + compact << body if body + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [class_keyword_loc, constant_path, *inheritance_operator_loc, *superclass, *body, end_keyword_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?locals: Array[Symbol], ?class_keyword_loc: Location, ?constant_path: ConstantReadNode | ConstantPathNode | CallNode, ?inheritance_operator_loc: Location?, ?superclass: Prism::node?, ?body: StatementsNode | BeginNode | nil, ?end_keyword_loc: Location, ?name: Symbol) -> ClassNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, locals: self.locals, class_keyword_loc: self.class_keyword_loc, constant_path: self.constant_path, inheritance_operator_loc: self.inheritance_operator_loc, superclass: self.superclass, body: self.body, end_keyword_loc: self.end_keyword_loc, name: self.name) + ClassNode.new(source, node_id, location, flags, locals, class_keyword_loc, constant_path, inheritance_operator_loc, superclass, body, end_keyword_loc, name) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, locals: Array[Symbol], class_keyword_loc: Location, constant_path: ConstantReadNode | ConstantPathNode | CallNode, inheritance_operator_loc: Location?, superclass: Prism::node?, body: StatementsNode | BeginNode | nil, end_keyword_loc: Location, name: Symbol } + def deconstruct_keys(keys) + { node_id: node_id, location: location, locals: locals, class_keyword_loc: class_keyword_loc, constant_path: constant_path, inheritance_operator_loc: inheritance_operator_loc, superclass: superclass, body: body, end_keyword_loc: end_keyword_loc, name: name } + end + + # attr_reader locals: Array[Symbol] + attr_reader :locals + + # attr_reader class_keyword_loc: Location + def class_keyword_loc + location = @class_keyword_loc + return location if location.is_a?(Location) + @class_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the class_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_class_keyword_loc(repository) + repository.enter(node_id, :class_keyword_loc) + end + + # attr_reader constant_path: ConstantReadNode | ConstantPathNode | CallNode + attr_reader :constant_path + + # attr_reader inheritance_operator_loc: Location? + def inheritance_operator_loc + location = @inheritance_operator_loc + case location + when nil + nil + when Location + location + else + @inheritance_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the inheritance_operator_loc location using the given saved source so that + # it can be retrieved later. + def save_inheritance_operator_loc(repository) + repository.enter(node_id, :inheritance_operator_loc) unless @inheritance_operator_loc.nil? + end + + # attr_reader superclass: Prism::node? + attr_reader :superclass + + # attr_reader body: StatementsNode | BeginNode | nil + attr_reader :body + + # attr_reader end_keyword_loc: Location + def end_keyword_loc + location = @end_keyword_loc + return location if location.is_a?(Location) + @end_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the end_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_end_keyword_loc(repository) + repository.enter(node_id, :end_keyword_loc) + end + + # attr_reader name: Symbol + attr_reader :name + + # def class_keyword: () -> String + def class_keyword + class_keyword_loc.slice + end + + # def inheritance_operator: () -> String? + def inheritance_operator + inheritance_operator_loc&.slice + end + + # def end_keyword: () -> String + def end_keyword + end_keyword_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :class_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :class_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ClassNode) && + (locals.length == other.locals.length) && + locals.zip(other.locals).all? { |left, right| left === right } && + (class_keyword_loc.nil? == other.class_keyword_loc.nil?) && + (constant_path === other.constant_path) && + (inheritance_operator_loc.nil? == other.inheritance_operator_loc.nil?) && + (superclass === other.superclass) && + (body === other.body) && + (end_keyword_loc.nil? == other.end_keyword_loc.nil?) && + (name === other.name) + end + end + + # Represents the use of the `&&=` operator for assignment to a class variable. + # + # @@target &&= value + # ^^^^^^^^^^^^^^^^^^ + class ClassVariableAndWriteNode < Node + # Initialize a new ClassVariableAndWriteNode node. + def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @name_loc = name_loc + @operator_loc = operator_loc + @value = value + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_class_variable_and_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [name_loc, operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> ClassVariableAndWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value) + ClassVariableAndWriteNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, name_loc: name_loc, operator_loc: operator_loc, value: value } + end + + # The name of the class variable, which is a `@@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). + # + # @@target &&= value # name `:@@target` + # ^^^^^^^^ + attr_reader :name + + # Represents the location of the variable name. + # + # @@target &&= value + # ^^^^^^^^ + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # Represents the location of the `&&=` operator. + # + # @@target &&= value + # ^^^ + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # Represents the value being assigned. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # @@target &&= value + # ^^^^^ + attr_reader :value + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :class_variable_and_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :class_variable_and_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ClassVariableAndWriteNode) && + (name === other.name) && + (name_loc.nil? == other.name_loc.nil?) && + (operator_loc.nil? == other.operator_loc.nil?) && + (value === other.value) + end + end + + # Represents assigning to a class variable using an operator that isn't `=`. + # + # @@target += value + # ^^^^^^^^^^^^^^^^^ + class ClassVariableOperatorWriteNode < Node + # Initialize a new ClassVariableOperatorWriteNode node. + def initialize(source, node_id, location, flags, name, name_loc, binary_operator_loc, value, binary_operator) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @name_loc = name_loc + @binary_operator_loc = binary_operator_loc + @value = value + @binary_operator = binary_operator + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_class_variable_operator_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [name_loc, binary_operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?binary_operator_loc: Location, ?value: Prism::node, ?binary_operator: Symbol) -> ClassVariableOperatorWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, binary_operator_loc: self.binary_operator_loc, value: self.value, binary_operator: self.binary_operator) + ClassVariableOperatorWriteNode.new(source, node_id, location, flags, name, name_loc, binary_operator_loc, value, binary_operator) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, binary_operator_loc: Location, value: Prism::node, binary_operator: Symbol } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, name_loc: name_loc, binary_operator_loc: binary_operator_loc, value: value, binary_operator: binary_operator } + end + + # attr_reader name: Symbol + attr_reader :name + + # attr_reader name_loc: Location + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # attr_reader binary_operator_loc: Location + def binary_operator_loc + location = @binary_operator_loc + return location if location.is_a?(Location) + @binary_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the binary_operator_loc location using the given saved source so that + # it can be retrieved later. + def save_binary_operator_loc(repository) + repository.enter(node_id, :binary_operator_loc) + end + + # attr_reader value: Prism::node + attr_reader :value + + # attr_reader binary_operator: Symbol + attr_reader :binary_operator + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :class_variable_operator_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :class_variable_operator_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ClassVariableOperatorWriteNode) && + (name === other.name) && + (name_loc.nil? == other.name_loc.nil?) && + (binary_operator_loc.nil? == other.binary_operator_loc.nil?) && + (value === other.value) && + (binary_operator === other.binary_operator) + end + end + + # Represents the use of the `||=` operator for assignment to a class variable. + # + # @@target ||= value + # ^^^^^^^^^^^^^^^^^^ + class ClassVariableOrWriteNode < Node + # Initialize a new ClassVariableOrWriteNode node. + def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @name_loc = name_loc + @operator_loc = operator_loc + @value = value + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_class_variable_or_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [name_loc, operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> ClassVariableOrWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value) + ClassVariableOrWriteNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, name_loc: name_loc, operator_loc: operator_loc, value: value } + end + + # attr_reader name: Symbol + attr_reader :name + + # attr_reader name_loc: Location + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # attr_reader value: Prism::node + attr_reader :value + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :class_variable_or_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :class_variable_or_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ClassVariableOrWriteNode) && + (name === other.name) && + (name_loc.nil? == other.name_loc.nil?) && + (operator_loc.nil? == other.operator_loc.nil?) && + (value === other.value) + end + end + + # Represents referencing a class variable. + # + # @@foo + # ^^^^^ + class ClassVariableReadNode < Node + # Initialize a new ClassVariableReadNode node. + def initialize(source, node_id, location, flags, name) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_class_variable_read_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> ClassVariableReadNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name) + ClassVariableReadNode.new(source, node_id, location, flags, name) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name } + end + + # The name of the class variable, which is a `@@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). + # + # @@abc # name `:@@abc` + # + # @@_test # name `:@@_test` + attr_reader :name + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :class_variable_read_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :class_variable_read_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ClassVariableReadNode) && + (name === other.name) + end + end + + # Represents writing to a class variable in a context that doesn't have an explicit value. + # + # @@foo, @@bar = baz + # ^^^^^ ^^^^^ + class ClassVariableTargetNode < Node + # Initialize a new ClassVariableTargetNode node. + def initialize(source, node_id, location, flags, name) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_class_variable_target_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> ClassVariableTargetNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name) + ClassVariableTargetNode.new(source, node_id, location, flags, name) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name } + end + + # attr_reader name: Symbol + attr_reader :name + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :class_variable_target_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :class_variable_target_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ClassVariableTargetNode) && + (name === other.name) + end + end + + # Represents writing to a class variable. + # + # @@foo = 1 + # ^^^^^^^^^ + class ClassVariableWriteNode < Node + # Initialize a new ClassVariableWriteNode node. + def initialize(source, node_id, location, flags, name, name_loc, value, operator_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @name_loc = name_loc + @value = value + @operator_loc = operator_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_class_variable_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [name_loc, value, operator_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?value: Prism::node, ?operator_loc: Location) -> ClassVariableWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, value: self.value, operator_loc: self.operator_loc) + ClassVariableWriteNode.new(source, node_id, location, flags, name, name_loc, value, operator_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, value: Prism::node, operator_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, name_loc: name_loc, value: value, operator_loc: operator_loc } + end + + # The name of the class variable, which is a `@@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). + # + # @@abc = 123 # name `@@abc` + # + # @@_test = :test # name `@@_test` + attr_reader :name + + # The location of the variable name. + # + # @@foo = :bar + # ^^^^^ + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # The value to write to the class variable. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # @@foo = :bar + # ^^^^ + # + # @@_xyz = 123 + # ^^^ + attr_reader :value + + # The location of the `=` operator. + # + # @@foo = :bar + # ^ + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :class_variable_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :class_variable_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ClassVariableWriteNode) && + (name === other.name) && + (name_loc.nil? == other.name_loc.nil?) && + (value === other.value) && + (operator_loc.nil? == other.operator_loc.nil?) + end + end + + # Represents the use of the `&&=` operator for assignment to a constant. + # + # Target &&= value + # ^^^^^^^^^^^^^^^^ + class ConstantAndWriteNode < Node + # Initialize a new ConstantAndWriteNode node. + def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @name_loc = name_loc + @operator_loc = operator_loc + @value = value + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_constant_and_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [name_loc, operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> ConstantAndWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value) + ConstantAndWriteNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, name_loc: name_loc, operator_loc: operator_loc, value: value } + end + + # attr_reader name: Symbol + attr_reader :name + + # attr_reader name_loc: Location + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # attr_reader value: Prism::node + attr_reader :value + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :constant_and_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :constant_and_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ConstantAndWriteNode) && + (name === other.name) && + (name_loc.nil? == other.name_loc.nil?) && + (operator_loc.nil? == other.operator_loc.nil?) && + (value === other.value) + end + end + + # Represents assigning to a constant using an operator that isn't `=`. + # + # Target += value + # ^^^^^^^^^^^^^^^ + class ConstantOperatorWriteNode < Node + # Initialize a new ConstantOperatorWriteNode node. + def initialize(source, node_id, location, flags, name, name_loc, binary_operator_loc, value, binary_operator) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @name_loc = name_loc + @binary_operator_loc = binary_operator_loc + @value = value + @binary_operator = binary_operator + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_constant_operator_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [name_loc, binary_operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?binary_operator_loc: Location, ?value: Prism::node, ?binary_operator: Symbol) -> ConstantOperatorWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, binary_operator_loc: self.binary_operator_loc, value: self.value, binary_operator: self.binary_operator) + ConstantOperatorWriteNode.new(source, node_id, location, flags, name, name_loc, binary_operator_loc, value, binary_operator) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, binary_operator_loc: Location, value: Prism::node, binary_operator: Symbol } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, name_loc: name_loc, binary_operator_loc: binary_operator_loc, value: value, binary_operator: binary_operator } + end + + # attr_reader name: Symbol + attr_reader :name + + # attr_reader name_loc: Location + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # attr_reader binary_operator_loc: Location + def binary_operator_loc + location = @binary_operator_loc + return location if location.is_a?(Location) + @binary_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the binary_operator_loc location using the given saved source so that + # it can be retrieved later. + def save_binary_operator_loc(repository) + repository.enter(node_id, :binary_operator_loc) + end + + # attr_reader value: Prism::node + attr_reader :value + + # attr_reader binary_operator: Symbol + attr_reader :binary_operator + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :constant_operator_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :constant_operator_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ConstantOperatorWriteNode) && + (name === other.name) && + (name_loc.nil? == other.name_loc.nil?) && + (binary_operator_loc.nil? == other.binary_operator_loc.nil?) && + (value === other.value) && + (binary_operator === other.binary_operator) + end + end + + # Represents the use of the `||=` operator for assignment to a constant. + # + # Target ||= value + # ^^^^^^^^^^^^^^^^ + class ConstantOrWriteNode < Node + # Initialize a new ConstantOrWriteNode node. + def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @name_loc = name_loc + @operator_loc = operator_loc + @value = value + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_constant_or_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [name_loc, operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> ConstantOrWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value) + ConstantOrWriteNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, name_loc: name_loc, operator_loc: operator_loc, value: value } + end + + # attr_reader name: Symbol + attr_reader :name + + # attr_reader name_loc: Location + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # attr_reader value: Prism::node + attr_reader :value + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :constant_or_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :constant_or_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ConstantOrWriteNode) && + (name === other.name) && + (name_loc.nil? == other.name_loc.nil?) && + (operator_loc.nil? == other.operator_loc.nil?) && + (value === other.value) + end + end + + # Represents the use of the `&&=` operator for assignment to a constant path. + # + # Parent::Child &&= value + # ^^^^^^^^^^^^^^^^^^^^^^^ + class ConstantPathAndWriteNode < Node + # Initialize a new ConstantPathAndWriteNode node. + def initialize(source, node_id, location, flags, target, operator_loc, value) + @source = source + @node_id = node_id + @location = location + @flags = flags + @target = target + @operator_loc = operator_loc + @value = value + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_constant_path_and_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [target, value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [target, value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [target, operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?target: ConstantPathNode, ?operator_loc: Location, ?value: Prism::node) -> ConstantPathAndWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, target: self.target, operator_loc: self.operator_loc, value: self.value) + ConstantPathAndWriteNode.new(source, node_id, location, flags, target, operator_loc, value) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, target: ConstantPathNode, operator_loc: Location, value: Prism::node } + def deconstruct_keys(keys) + { node_id: node_id, location: location, target: target, operator_loc: operator_loc, value: value } + end + + # attr_reader target: ConstantPathNode + attr_reader :target + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # attr_reader value: Prism::node + attr_reader :value + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :constant_path_and_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :constant_path_and_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ConstantPathAndWriteNode) && + (target === other.target) && + (operator_loc.nil? == other.operator_loc.nil?) && + (value === other.value) + end + end + + # Represents accessing a constant through a path of `::` operators. + # + # Foo::Bar + # ^^^^^^^^ + class ConstantPathNode < Node + # Initialize a new ConstantPathNode node. + def initialize(source, node_id, location, flags, parent, name, delimiter_loc, name_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @parent = parent + @name = name + @delimiter_loc = delimiter_loc + @name_loc = name_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_constant_path_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [parent] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << parent if parent + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*parent, delimiter_loc, name_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?parent: Prism::node?, ?name: Symbol?, ?delimiter_loc: Location, ?name_loc: Location) -> ConstantPathNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, parent: self.parent, name: self.name, delimiter_loc: self.delimiter_loc, name_loc: self.name_loc) + ConstantPathNode.new(source, node_id, location, flags, parent, name, delimiter_loc, name_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, parent: Prism::node?, name: Symbol?, delimiter_loc: Location, name_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, parent: parent, name: name, delimiter_loc: delimiter_loc, name_loc: name_loc } + end + + # The left-hand node of the path, if present. It can be `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). It will be `nil` when the constant lookup is at the root of the module tree. + # + # Foo::Bar + # ^^^ + # + # self::Test + # ^^^^ + # + # a.b::C + # ^^^ + attr_reader :parent + + # The name of the constant being accessed. This could be `nil` in the event of a syntax error. + attr_reader :name + + # The location of the `::` delimiter. + # + # ::Foo + # ^^ + # + # One::Two + # ^^ + def delimiter_loc + location = @delimiter_loc + return location if location.is_a?(Location) + @delimiter_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the delimiter_loc location using the given saved source so that + # it can be retrieved later. + def save_delimiter_loc(repository) + repository.enter(node_id, :delimiter_loc) + end + + # The location of the name of the constant. + # + # ::Foo + # ^^^ + # + # One::Two + # ^^^ + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # def delimiter: () -> String + def delimiter + delimiter_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :constant_path_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :constant_path_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ConstantPathNode) && + (parent === other.parent) && + (name === other.name) && + (delimiter_loc.nil? == other.delimiter_loc.nil?) && + (name_loc.nil? == other.name_loc.nil?) + end + end + + # Represents assigning to a constant path using an operator that isn't `=`. + # + # Parent::Child += value + # ^^^^^^^^^^^^^^^^^^^^^^ + class ConstantPathOperatorWriteNode < Node + # Initialize a new ConstantPathOperatorWriteNode node. + def initialize(source, node_id, location, flags, target, binary_operator_loc, value, binary_operator) + @source = source + @node_id = node_id + @location = location + @flags = flags + @target = target + @binary_operator_loc = binary_operator_loc + @value = value + @binary_operator = binary_operator + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_constant_path_operator_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [target, value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [target, value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [target, binary_operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?target: ConstantPathNode, ?binary_operator_loc: Location, ?value: Prism::node, ?binary_operator: Symbol) -> ConstantPathOperatorWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, target: self.target, binary_operator_loc: self.binary_operator_loc, value: self.value, binary_operator: self.binary_operator) + ConstantPathOperatorWriteNode.new(source, node_id, location, flags, target, binary_operator_loc, value, binary_operator) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, target: ConstantPathNode, binary_operator_loc: Location, value: Prism::node, binary_operator: Symbol } + def deconstruct_keys(keys) + { node_id: node_id, location: location, target: target, binary_operator_loc: binary_operator_loc, value: value, binary_operator: binary_operator } + end + + # attr_reader target: ConstantPathNode + attr_reader :target + + # attr_reader binary_operator_loc: Location + def binary_operator_loc + location = @binary_operator_loc + return location if location.is_a?(Location) + @binary_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the binary_operator_loc location using the given saved source so that + # it can be retrieved later. + def save_binary_operator_loc(repository) + repository.enter(node_id, :binary_operator_loc) + end + + # attr_reader value: Prism::node + attr_reader :value + + # attr_reader binary_operator: Symbol + attr_reader :binary_operator + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :constant_path_operator_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :constant_path_operator_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ConstantPathOperatorWriteNode) && + (target === other.target) && + (binary_operator_loc.nil? == other.binary_operator_loc.nil?) && + (value === other.value) && + (binary_operator === other.binary_operator) + end + end + + # Represents the use of the `||=` operator for assignment to a constant path. + # + # Parent::Child ||= value + # ^^^^^^^^^^^^^^^^^^^^^^^ + class ConstantPathOrWriteNode < Node + # Initialize a new ConstantPathOrWriteNode node. + def initialize(source, node_id, location, flags, target, operator_loc, value) + @source = source + @node_id = node_id + @location = location + @flags = flags + @target = target + @operator_loc = operator_loc + @value = value + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_constant_path_or_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [target, value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [target, value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [target, operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?target: ConstantPathNode, ?operator_loc: Location, ?value: Prism::node) -> ConstantPathOrWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, target: self.target, operator_loc: self.operator_loc, value: self.value) + ConstantPathOrWriteNode.new(source, node_id, location, flags, target, operator_loc, value) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, target: ConstantPathNode, operator_loc: Location, value: Prism::node } + def deconstruct_keys(keys) + { node_id: node_id, location: location, target: target, operator_loc: operator_loc, value: value } + end + + # attr_reader target: ConstantPathNode + attr_reader :target + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # attr_reader value: Prism::node + attr_reader :value + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :constant_path_or_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :constant_path_or_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ConstantPathOrWriteNode) && + (target === other.target) && + (operator_loc.nil? == other.operator_loc.nil?) && + (value === other.value) + end + end + + # Represents writing to a constant path in a context that doesn't have an explicit value. + # + # Foo::Foo, Bar::Bar = baz + # ^^^^^^^^ ^^^^^^^^ + class ConstantPathTargetNode < Node + # Initialize a new ConstantPathTargetNode node. + def initialize(source, node_id, location, flags, parent, name, delimiter_loc, name_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @parent = parent + @name = name + @delimiter_loc = delimiter_loc + @name_loc = name_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_constant_path_target_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [parent] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << parent if parent + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*parent, delimiter_loc, name_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?parent: Prism::node?, ?name: Symbol?, ?delimiter_loc: Location, ?name_loc: Location) -> ConstantPathTargetNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, parent: self.parent, name: self.name, delimiter_loc: self.delimiter_loc, name_loc: self.name_loc) + ConstantPathTargetNode.new(source, node_id, location, flags, parent, name, delimiter_loc, name_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, parent: Prism::node?, name: Symbol?, delimiter_loc: Location, name_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, parent: parent, name: name, delimiter_loc: delimiter_loc, name_loc: name_loc } + end + + # attr_reader parent: Prism::node? + attr_reader :parent + + # attr_reader name: Symbol? + attr_reader :name + + # attr_reader delimiter_loc: Location + def delimiter_loc + location = @delimiter_loc + return location if location.is_a?(Location) + @delimiter_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the delimiter_loc location using the given saved source so that + # it can be retrieved later. + def save_delimiter_loc(repository) + repository.enter(node_id, :delimiter_loc) + end + + # attr_reader name_loc: Location + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # def delimiter: () -> String + def delimiter + delimiter_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :constant_path_target_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :constant_path_target_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ConstantPathTargetNode) && + (parent === other.parent) && + (name === other.name) && + (delimiter_loc.nil? == other.delimiter_loc.nil?) && + (name_loc.nil? == other.name_loc.nil?) + end + end + + # Represents writing to a constant path. + # + # ::Foo = 1 + # ^^^^^^^^^ + # + # Foo::Bar = 1 + # ^^^^^^^^^^^^ + # + # ::Foo::Bar = 1 + # ^^^^^^^^^^^^^^ + class ConstantPathWriteNode < Node + # Initialize a new ConstantPathWriteNode node. + def initialize(source, node_id, location, flags, target, operator_loc, value) + @source = source + @node_id = node_id + @location = location + @flags = flags + @target = target + @operator_loc = operator_loc + @value = value + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_constant_path_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [target, value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [target, value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [target, operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?target: ConstantPathNode, ?operator_loc: Location, ?value: Prism::node) -> ConstantPathWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, target: self.target, operator_loc: self.operator_loc, value: self.value) + ConstantPathWriteNode.new(source, node_id, location, flags, target, operator_loc, value) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, target: ConstantPathNode, operator_loc: Location, value: Prism::node } + def deconstruct_keys(keys) + { node_id: node_id, location: location, target: target, operator_loc: operator_loc, value: value } + end + + # A node representing the constant path being written to. + # + # Foo::Bar = 1 + # ^^^^^^^^ + # + # ::Foo = :abc + # ^^^^^ + attr_reader :target + + # The location of the `=` operator. + # + # ::ABC = 123 + # ^ + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # The value to write to the constant path. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # FOO::BAR = :abc + # ^^^^ + attr_reader :value + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :constant_path_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :constant_path_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ConstantPathWriteNode) && + (target === other.target) && + (operator_loc.nil? == other.operator_loc.nil?) && + (value === other.value) + end + end + + # Represents referencing a constant. + # + # Foo + # ^^^ + class ConstantReadNode < Node + # Initialize a new ConstantReadNode node. + def initialize(source, node_id, location, flags, name) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_constant_read_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> ConstantReadNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name) + ConstantReadNode.new(source, node_id, location, flags, name) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name } + end + + # The name of the [constant](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#constants). + # + # X # name `:X` + # + # SOME_CONSTANT # name `:SOME_CONSTANT` + attr_reader :name + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :constant_read_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :constant_read_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ConstantReadNode) && + (name === other.name) + end + end + + # Represents writing to a constant in a context that doesn't have an explicit value. + # + # Foo, Bar = baz + # ^^^ ^^^ + class ConstantTargetNode < Node + # Initialize a new ConstantTargetNode node. + def initialize(source, node_id, location, flags, name) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_constant_target_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> ConstantTargetNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name) + ConstantTargetNode.new(source, node_id, location, flags, name) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name } + end + + # attr_reader name: Symbol + attr_reader :name + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :constant_target_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :constant_target_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ConstantTargetNode) && + (name === other.name) + end + end + + # Represents writing to a constant. + # + # Foo = 1 + # ^^^^^^^ + class ConstantWriteNode < Node + # Initialize a new ConstantWriteNode node. + def initialize(source, node_id, location, flags, name, name_loc, value, operator_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @name_loc = name_loc + @value = value + @operator_loc = operator_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_constant_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [name_loc, value, operator_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?value: Prism::node, ?operator_loc: Location) -> ConstantWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, value: self.value, operator_loc: self.operator_loc) + ConstantWriteNode.new(source, node_id, location, flags, name, name_loc, value, operator_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, value: Prism::node, operator_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, name_loc: name_loc, value: value, operator_loc: operator_loc } + end + + # The name of the [constant](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#constants). + # + # Foo = :bar # name `:Foo` + # + # XYZ = 1 # name `:XYZ` + attr_reader :name + + # The location of the constant name. + # + # FOO = 1 + # ^^^ + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # The value to write to the constant. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # FOO = :bar + # ^^^^ + # + # MyClass = Class.new + # ^^^^^^^^^ + attr_reader :value + + # The location of the `=` operator. + # + # FOO = :bar + # ^ + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :constant_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :constant_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ConstantWriteNode) && + (name === other.name) && + (name_loc.nil? == other.name_loc.nil?) && + (value === other.value) && + (operator_loc.nil? == other.operator_loc.nil?) + end + end + + # Represents a method definition. + # + # def method + # end + # ^^^^^^^^^^ + class DefNode < Node + # Initialize a new DefNode node. + def initialize(source, node_id, location, flags, name, name_loc, receiver, parameters, body, locals, def_keyword_loc, operator_loc, lparen_loc, rparen_loc, equal_loc, end_keyword_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @name_loc = name_loc + @receiver = receiver + @parameters = parameters + @body = body + @locals = locals + @def_keyword_loc = def_keyword_loc + @operator_loc = operator_loc + @lparen_loc = lparen_loc + @rparen_loc = rparen_loc + @equal_loc = equal_loc + @end_keyword_loc = end_keyword_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_def_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [receiver, parameters, body] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << receiver if receiver + compact << parameters if parameters + compact << body if body + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [name_loc, *receiver, *parameters, *body, def_keyword_loc, *operator_loc, *lparen_loc, *rparen_loc, *equal_loc, *end_keyword_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?receiver: Prism::node?, ?parameters: ParametersNode?, ?body: StatementsNode | BeginNode | nil, ?locals: Array[Symbol], ?def_keyword_loc: Location, ?operator_loc: Location?, ?lparen_loc: Location?, ?rparen_loc: Location?, ?equal_loc: Location?, ?end_keyword_loc: Location?) -> DefNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, receiver: self.receiver, parameters: self.parameters, body: self.body, locals: self.locals, def_keyword_loc: self.def_keyword_loc, operator_loc: self.operator_loc, lparen_loc: self.lparen_loc, rparen_loc: self.rparen_loc, equal_loc: self.equal_loc, end_keyword_loc: self.end_keyword_loc) + DefNode.new(source, node_id, location, flags, name, name_loc, receiver, parameters, body, locals, def_keyword_loc, operator_loc, lparen_loc, rparen_loc, equal_loc, end_keyword_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, receiver: Prism::node?, parameters: ParametersNode?, body: StatementsNode | BeginNode | nil, locals: Array[Symbol], def_keyword_loc: Location, operator_loc: Location?, lparen_loc: Location?, rparen_loc: Location?, equal_loc: Location?, end_keyword_loc: Location? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, name_loc: name_loc, receiver: receiver, parameters: parameters, body: body, locals: locals, def_keyword_loc: def_keyword_loc, operator_loc: operator_loc, lparen_loc: lparen_loc, rparen_loc: rparen_loc, equal_loc: equal_loc, end_keyword_loc: end_keyword_loc } + end + + # attr_reader name: Symbol + attr_reader :name + + # attr_reader name_loc: Location + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # attr_reader receiver: Prism::node? + attr_reader :receiver + + # attr_reader parameters: ParametersNode? + attr_reader :parameters + + # attr_reader body: StatementsNode | BeginNode | nil + attr_reader :body + + # attr_reader locals: Array[Symbol] + attr_reader :locals + + # attr_reader def_keyword_loc: Location + def def_keyword_loc + location = @def_keyword_loc + return location if location.is_a?(Location) + @def_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the def_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_def_keyword_loc(repository) + repository.enter(node_id, :def_keyword_loc) + end + + # attr_reader operator_loc: Location? + def operator_loc + location = @operator_loc + case location + when nil + nil + when Location + location + else + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) unless @operator_loc.nil? + end + + # attr_reader lparen_loc: Location? + def lparen_loc + location = @lparen_loc + case location + when nil + nil + when Location + location + else + @lparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the lparen_loc location using the given saved source so that + # it can be retrieved later. + def save_lparen_loc(repository) + repository.enter(node_id, :lparen_loc) unless @lparen_loc.nil? + end + + # attr_reader rparen_loc: Location? + def rparen_loc + location = @rparen_loc + case location + when nil + nil + when Location + location + else + @rparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the rparen_loc location using the given saved source so that + # it can be retrieved later. + def save_rparen_loc(repository) + repository.enter(node_id, :rparen_loc) unless @rparen_loc.nil? + end + + # attr_reader equal_loc: Location? + def equal_loc + location = @equal_loc + case location + when nil + nil + when Location + location + else + @equal_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the equal_loc location using the given saved source so that + # it can be retrieved later. + def save_equal_loc(repository) + repository.enter(node_id, :equal_loc) unless @equal_loc.nil? + end + + # attr_reader end_keyword_loc: Location? + def end_keyword_loc + location = @end_keyword_loc + case location + when nil + nil + when Location + location + else + @end_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the end_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_end_keyword_loc(repository) + repository.enter(node_id, :end_keyword_loc) unless @end_keyword_loc.nil? + end + + # def def_keyword: () -> String + def def_keyword + def_keyword_loc.slice + end + + # def operator: () -> String? + def operator + operator_loc&.slice + end + + # def lparen: () -> String? + def lparen + lparen_loc&.slice + end + + # def rparen: () -> String? + def rparen + rparen_loc&.slice + end + + # def equal: () -> String? + def equal + equal_loc&.slice + end + + # def end_keyword: () -> String? + def end_keyword + end_keyword_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :def_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :def_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(DefNode) && + (name === other.name) && + (name_loc.nil? == other.name_loc.nil?) && + (receiver === other.receiver) && + (parameters === other.parameters) && + (body === other.body) && + (locals.length == other.locals.length) && + locals.zip(other.locals).all? { |left, right| left === right } && + (def_keyword_loc.nil? == other.def_keyword_loc.nil?) && + (operator_loc.nil? == other.operator_loc.nil?) && + (lparen_loc.nil? == other.lparen_loc.nil?) && + (rparen_loc.nil? == other.rparen_loc.nil?) && + (equal_loc.nil? == other.equal_loc.nil?) && + (end_keyword_loc.nil? == other.end_keyword_loc.nil?) + end + end + + # Represents the use of the `defined?` keyword. + # + # defined?(a) + # ^^^^^^^^^^^ + class DefinedNode < Node + # Initialize a new DefinedNode node. + def initialize(source, node_id, location, flags, lparen_loc, value, rparen_loc, keyword_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @lparen_loc = lparen_loc + @value = value + @rparen_loc = rparen_loc + @keyword_loc = keyword_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_defined_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*lparen_loc, value, *rparen_loc, keyword_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?lparen_loc: Location?, ?value: Prism::node, ?rparen_loc: Location?, ?keyword_loc: Location) -> DefinedNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, lparen_loc: self.lparen_loc, value: self.value, rparen_loc: self.rparen_loc, keyword_loc: self.keyword_loc) + DefinedNode.new(source, node_id, location, flags, lparen_loc, value, rparen_loc, keyword_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, lparen_loc: Location?, value: Prism::node, rparen_loc: Location?, keyword_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, lparen_loc: lparen_loc, value: value, rparen_loc: rparen_loc, keyword_loc: keyword_loc } + end + + # attr_reader lparen_loc: Location? + def lparen_loc + location = @lparen_loc + case location + when nil + nil + when Location + location + else + @lparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the lparen_loc location using the given saved source so that + # it can be retrieved later. + def save_lparen_loc(repository) + repository.enter(node_id, :lparen_loc) unless @lparen_loc.nil? + end + + # attr_reader value: Prism::node + attr_reader :value + + # attr_reader rparen_loc: Location? + def rparen_loc + location = @rparen_loc + case location + when nil + nil + when Location + location + else + @rparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the rparen_loc location using the given saved source so that + # it can be retrieved later. + def save_rparen_loc(repository) + repository.enter(node_id, :rparen_loc) unless @rparen_loc.nil? + end + + # attr_reader keyword_loc: Location + def keyword_loc + location = @keyword_loc + return location if location.is_a?(Location) + @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_keyword_loc(repository) + repository.enter(node_id, :keyword_loc) + end + + # def lparen: () -> String? + def lparen + lparen_loc&.slice + end + + # def rparen: () -> String? + def rparen + rparen_loc&.slice + end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :defined_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :defined_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(DefinedNode) && + (lparen_loc.nil? == other.lparen_loc.nil?) && + (value === other.value) && + (rparen_loc.nil? == other.rparen_loc.nil?) && + (keyword_loc.nil? == other.keyword_loc.nil?) + end + end + + # Represents an `else` clause in a `case`, `if`, or `unless` statement. + # + # if a then b else c end + # ^^^^^^^^^^ + class ElseNode < Node + # Initialize a new ElseNode node. + def initialize(source, node_id, location, flags, else_keyword_loc, statements, end_keyword_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @else_keyword_loc = else_keyword_loc + @statements = statements + @end_keyword_loc = end_keyword_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_else_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [statements] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << statements if statements + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [else_keyword_loc, *statements, *end_keyword_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?else_keyword_loc: Location, ?statements: StatementsNode?, ?end_keyword_loc: Location?) -> ElseNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, else_keyword_loc: self.else_keyword_loc, statements: self.statements, end_keyword_loc: self.end_keyword_loc) + ElseNode.new(source, node_id, location, flags, else_keyword_loc, statements, end_keyword_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, else_keyword_loc: Location, statements: StatementsNode?, end_keyword_loc: Location? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, else_keyword_loc: else_keyword_loc, statements: statements, end_keyword_loc: end_keyword_loc } + end + + # attr_reader else_keyword_loc: Location + def else_keyword_loc + location = @else_keyword_loc + return location if location.is_a?(Location) + @else_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the else_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_else_keyword_loc(repository) + repository.enter(node_id, :else_keyword_loc) + end + + # attr_reader statements: StatementsNode? + attr_reader :statements + + # attr_reader end_keyword_loc: Location? + def end_keyword_loc + location = @end_keyword_loc + case location + when nil + nil + when Location + location + else + @end_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the end_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_end_keyword_loc(repository) + repository.enter(node_id, :end_keyword_loc) unless @end_keyword_loc.nil? + end + + # def else_keyword: () -> String + def else_keyword + else_keyword_loc.slice + end + + # def end_keyword: () -> String? + def end_keyword + end_keyword_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :else_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :else_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ElseNode) && + (else_keyword_loc.nil? == other.else_keyword_loc.nil?) && + (statements === other.statements) && + (end_keyword_loc.nil? == other.end_keyword_loc.nil?) + end + end + + # Represents an interpolated set of statements. + # + # "foo #{bar}" + # ^^^^^^ + class EmbeddedStatementsNode < Node + # Initialize a new EmbeddedStatementsNode node. + def initialize(source, node_id, location, flags, opening_loc, statements, closing_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @opening_loc = opening_loc + @statements = statements + @closing_loc = closing_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_embedded_statements_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [statements] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << statements if statements + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [opening_loc, *statements, closing_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?statements: StatementsNode?, ?closing_loc: Location) -> EmbeddedStatementsNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, statements: self.statements, closing_loc: self.closing_loc) + EmbeddedStatementsNode.new(source, node_id, location, flags, opening_loc, statements, closing_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location, statements: StatementsNode?, closing_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, opening_loc: opening_loc, statements: statements, closing_loc: closing_loc } + end + + # attr_reader opening_loc: Location + def opening_loc + location = @opening_loc + return location if location.is_a?(Location) + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) + end + + # attr_reader statements: StatementsNode? + attr_reader :statements + + # attr_reader closing_loc: Location + def closing_loc + location = @closing_loc + return location if location.is_a?(Location) + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) + end + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :embedded_statements_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :embedded_statements_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(EmbeddedStatementsNode) && + (opening_loc.nil? == other.opening_loc.nil?) && + (statements === other.statements) && + (closing_loc.nil? == other.closing_loc.nil?) + end + end + + # Represents an interpolated variable. + # + # "foo #@bar" + # ^^^^^ + class EmbeddedVariableNode < Node + # Initialize a new EmbeddedVariableNode node. + def initialize(source, node_id, location, flags, operator_loc, variable) + @source = source + @node_id = node_id + @location = location + @flags = flags + @operator_loc = operator_loc + @variable = variable + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_embedded_variable_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [variable] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [variable] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [operator_loc, variable] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?operator_loc: Location, ?variable: InstanceVariableReadNode | ClassVariableReadNode | GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode) -> EmbeddedVariableNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, operator_loc: self.operator_loc, variable: self.variable) + EmbeddedVariableNode.new(source, node_id, location, flags, operator_loc, variable) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, operator_loc: Location, variable: InstanceVariableReadNode | ClassVariableReadNode | GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode } + def deconstruct_keys(keys) + { node_id: node_id, location: location, operator_loc: operator_loc, variable: variable } + end + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # attr_reader variable: InstanceVariableReadNode | ClassVariableReadNode | GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode + attr_reader :variable + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :embedded_variable_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :embedded_variable_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(EmbeddedVariableNode) && + (operator_loc.nil? == other.operator_loc.nil?) && + (variable === other.variable) + end + end + + # Represents an `ensure` clause in a `begin` statement. + # + # begin + # foo + # ensure + # ^^^^^^ + # bar + # end + class EnsureNode < Node + # Initialize a new EnsureNode node. + def initialize(source, node_id, location, flags, ensure_keyword_loc, statements, end_keyword_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @ensure_keyword_loc = ensure_keyword_loc + @statements = statements + @end_keyword_loc = end_keyword_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_ensure_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [statements] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << statements if statements + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [ensure_keyword_loc, *statements, end_keyword_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?ensure_keyword_loc: Location, ?statements: StatementsNode?, ?end_keyword_loc: Location) -> EnsureNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, ensure_keyword_loc: self.ensure_keyword_loc, statements: self.statements, end_keyword_loc: self.end_keyword_loc) + EnsureNode.new(source, node_id, location, flags, ensure_keyword_loc, statements, end_keyword_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, ensure_keyword_loc: Location, statements: StatementsNode?, end_keyword_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, ensure_keyword_loc: ensure_keyword_loc, statements: statements, end_keyword_loc: end_keyword_loc } + end + + # attr_reader ensure_keyword_loc: Location + def ensure_keyword_loc + location = @ensure_keyword_loc + return location if location.is_a?(Location) + @ensure_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the ensure_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_ensure_keyword_loc(repository) + repository.enter(node_id, :ensure_keyword_loc) + end + + # attr_reader statements: StatementsNode? + attr_reader :statements + + # attr_reader end_keyword_loc: Location + def end_keyword_loc + location = @end_keyword_loc + return location if location.is_a?(Location) + @end_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the end_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_end_keyword_loc(repository) + repository.enter(node_id, :end_keyword_loc) + end + + # def ensure_keyword: () -> String + def ensure_keyword + ensure_keyword_loc.slice + end + + # def end_keyword: () -> String + def end_keyword + end_keyword_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :ensure_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :ensure_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(EnsureNode) && + (ensure_keyword_loc.nil? == other.ensure_keyword_loc.nil?) && + (statements === other.statements) && + (end_keyword_loc.nil? == other.end_keyword_loc.nil?) + end + end + + # Represents the use of the literal `false` keyword. + # + # false + # ^^^^^ + class FalseNode < Node + # Initialize a new FalseNode node. + def initialize(source, node_id, location, flags) + @source = source + @node_id = node_id + @location = location + @flags = flags + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_false_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> FalseNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags) + FalseNode.new(source, node_id, location, flags) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location } + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :false_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :false_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(FalseNode) + end + end + + # Represents a find pattern in pattern matching. + # + # foo in *bar, baz, *qux + # ^^^^^^^^^^^^^^^ + # + # foo in [*bar, baz, *qux] + # ^^^^^^^^^^^^^^^^^ + # + # foo in Foo(*bar, baz, *qux) + # ^^^^^^^^^^^^^^^^^^^^ + class FindPatternNode < Node + # Initialize a new FindPatternNode node. + def initialize(source, node_id, location, flags, constant, left, requireds, right, opening_loc, closing_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @constant = constant + @left = left + @requireds = requireds + @right = right + @opening_loc = opening_loc + @closing_loc = closing_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_find_pattern_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [constant, left, *requireds, right] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << constant if constant + compact << left + compact.concat(requireds) + compact << right + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*constant, left, *requireds, right, *opening_loc, *closing_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?constant: ConstantReadNode | ConstantPathNode | nil, ?left: SplatNode, ?requireds: Array[Prism::node], ?right: SplatNode | MissingNode, ?opening_loc: Location?, ?closing_loc: Location?) -> FindPatternNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, constant: self.constant, left: self.left, requireds: self.requireds, right: self.right, opening_loc: self.opening_loc, closing_loc: self.closing_loc) + FindPatternNode.new(source, node_id, location, flags, constant, left, requireds, right, opening_loc, closing_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, constant: ConstantReadNode | ConstantPathNode | nil, left: SplatNode, requireds: Array[Prism::node], right: SplatNode | MissingNode, opening_loc: Location?, closing_loc: Location? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, constant: constant, left: left, requireds: requireds, right: right, opening_loc: opening_loc, closing_loc: closing_loc } + end + + # attr_reader constant: ConstantReadNode | ConstantPathNode | nil + attr_reader :constant + + # attr_reader left: SplatNode + attr_reader :left + + # attr_reader requireds: Array[Prism::node] + attr_reader :requireds + + # attr_reader right: SplatNode | MissingNode + attr_reader :right + + # attr_reader opening_loc: Location? + def opening_loc + location = @opening_loc + case location + when nil + nil + when Location + location + else + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) unless @opening_loc.nil? + end + + # attr_reader closing_loc: Location? + def closing_loc + location = @closing_loc + case location + when nil + nil + when Location + location + else + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) unless @closing_loc.nil? + end + + # def opening: () -> String? + def opening + opening_loc&.slice + end + + # def closing: () -> String? + def closing + closing_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :find_pattern_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :find_pattern_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(FindPatternNode) && + (constant === other.constant) && + (left === other.left) && + (requireds.length == other.requireds.length) && + requireds.zip(other.requireds).all? { |left, right| left === right } && + (right === other.right) && + (opening_loc.nil? == other.opening_loc.nil?) && + (closing_loc.nil? == other.closing_loc.nil?) + end + end + + # Represents the use of the `..` or `...` operators to create flip flops. + # + # baz if foo .. bar + # ^^^^^^^^^^ + class FlipFlopNode < Node + # Initialize a new FlipFlopNode node. + def initialize(source, node_id, location, flags, left, right, operator_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @left = left + @right = right + @operator_loc = operator_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_flip_flop_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [left, right] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << left if left + compact << right if right + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*left, *right, operator_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?left: Prism::node?, ?right: Prism::node?, ?operator_loc: Location) -> FlipFlopNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, left: self.left, right: self.right, operator_loc: self.operator_loc) + FlipFlopNode.new(source, node_id, location, flags, left, right, operator_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, left: Prism::node?, right: Prism::node?, operator_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, left: left, right: right, operator_loc: operator_loc } + end + + # def exclude_end?: () -> bool + def exclude_end? + flags.anybits?(RangeFlags::EXCLUDE_END) + end + + # attr_reader left: Prism::node? + attr_reader :left + + # attr_reader right: Prism::node? + attr_reader :right + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :flip_flop_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :flip_flop_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(FlipFlopNode) && + (flags === other.flags) && + (left === other.left) && + (right === other.right) && + (operator_loc.nil? == other.operator_loc.nil?) + end + end + + # Represents a floating point number literal. + # + # 1.0 + # ^^^ + class FloatNode < Node + # Initialize a new FloatNode node. + def initialize(source, node_id, location, flags, value) + @source = source + @node_id = node_id + @location = location + @flags = flags + @value = value + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_float_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?value: Float) -> FloatNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, value: self.value) + FloatNode.new(source, node_id, location, flags, value) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, value: Float } + def deconstruct_keys(keys) + { node_id: node_id, location: location, value: value } + end + + # The value of the floating point number as a Float. + attr_reader :value + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :float_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :float_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(FloatNode) && + (value === other.value) + end + end + + # Represents the use of the `for` keyword. + # + # for i in a end + # ^^^^^^^^^^^^^^ + class ForNode < Node + # Initialize a new ForNode node. + def initialize(source, node_id, location, flags, index, collection, statements, for_keyword_loc, in_keyword_loc, do_keyword_loc, end_keyword_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @index = index + @collection = collection + @statements = statements + @for_keyword_loc = for_keyword_loc + @in_keyword_loc = in_keyword_loc + @do_keyword_loc = do_keyword_loc + @end_keyword_loc = end_keyword_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_for_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [index, collection, statements] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << index + compact << collection + compact << statements if statements + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [index, collection, *statements, for_keyword_loc, in_keyword_loc, *do_keyword_loc, end_keyword_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?index: LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode | MissingNode, ?collection: Prism::node, ?statements: StatementsNode?, ?for_keyword_loc: Location, ?in_keyword_loc: Location, ?do_keyword_loc: Location?, ?end_keyword_loc: Location) -> ForNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, index: self.index, collection: self.collection, statements: self.statements, for_keyword_loc: self.for_keyword_loc, in_keyword_loc: self.in_keyword_loc, do_keyword_loc: self.do_keyword_loc, end_keyword_loc: self.end_keyword_loc) + ForNode.new(source, node_id, location, flags, index, collection, statements, for_keyword_loc, in_keyword_loc, do_keyword_loc, end_keyword_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, index: LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode | MissingNode, collection: Prism::node, statements: StatementsNode?, for_keyword_loc: Location, in_keyword_loc: Location, do_keyword_loc: Location?, end_keyword_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, index: index, collection: collection, statements: statements, for_keyword_loc: for_keyword_loc, in_keyword_loc: in_keyword_loc, do_keyword_loc: do_keyword_loc, end_keyword_loc: end_keyword_loc } + end + + # The index expression for `for` loops. + # + # for i in a end + # ^ + attr_reader :index + + # The collection to iterate over. + # + # for i in a end + # ^ + attr_reader :collection + + # Represents the body of statements to execute for each iteration of the loop. + # + # for i in a + # foo(i) + # ^^^^^^ + # end + attr_reader :statements + + # The location of the `for` keyword. + # + # for i in a end + # ^^^ + def for_keyword_loc + location = @for_keyword_loc + return location if location.is_a?(Location) + @for_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the for_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_for_keyword_loc(repository) + repository.enter(node_id, :for_keyword_loc) + end + + # The location of the `in` keyword. + # + # for i in a end + # ^^ + def in_keyword_loc + location = @in_keyword_loc + return location if location.is_a?(Location) + @in_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the in_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_in_keyword_loc(repository) + repository.enter(node_id, :in_keyword_loc) + end + + # The location of the `do` keyword, if present. + # + # for i in a do end + # ^^ + def do_keyword_loc + location = @do_keyword_loc + case location + when nil + nil + when Location + location + else + @do_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the do_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_do_keyword_loc(repository) + repository.enter(node_id, :do_keyword_loc) unless @do_keyword_loc.nil? + end + + # The location of the `end` keyword. + # + # for i in a end + # ^^^ + def end_keyword_loc + location = @end_keyword_loc + return location if location.is_a?(Location) + @end_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the end_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_end_keyword_loc(repository) + repository.enter(node_id, :end_keyword_loc) + end + + # def for_keyword: () -> String + def for_keyword + for_keyword_loc.slice + end + + # def in_keyword: () -> String + def in_keyword + in_keyword_loc.slice + end + + # def do_keyword: () -> String? + def do_keyword + do_keyword_loc&.slice + end + + # def end_keyword: () -> String + def end_keyword + end_keyword_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :for_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :for_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ForNode) && + (index === other.index) && + (collection === other.collection) && + (statements === other.statements) && + (for_keyword_loc.nil? == other.for_keyword_loc.nil?) && + (in_keyword_loc.nil? == other.in_keyword_loc.nil?) && + (do_keyword_loc.nil? == other.do_keyword_loc.nil?) && + (end_keyword_loc.nil? == other.end_keyword_loc.nil?) + end + end + + # Represents forwarding all arguments to this method to another method. + # + # def foo(...) + # bar(...) + # ^^^ + # end + class ForwardingArgumentsNode < Node + # Initialize a new ForwardingArgumentsNode node. + def initialize(source, node_id, location, flags) + @source = source + @node_id = node_id + @location = location + @flags = flags + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_forwarding_arguments_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> ForwardingArgumentsNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags) + ForwardingArgumentsNode.new(source, node_id, location, flags) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location } + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :forwarding_arguments_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :forwarding_arguments_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ForwardingArgumentsNode) + end + end + + # Represents the use of the forwarding parameter in a method, block, or lambda declaration. + # + # def foo(...) + # ^^^ + # end + class ForwardingParameterNode < Node + # Initialize a new ForwardingParameterNode node. + def initialize(source, node_id, location, flags) + @source = source + @node_id = node_id + @location = location + @flags = flags + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_forwarding_parameter_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> ForwardingParameterNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags) + ForwardingParameterNode.new(source, node_id, location, flags) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location } + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :forwarding_parameter_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :forwarding_parameter_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ForwardingParameterNode) + end + end + + # Represents the use of the `super` keyword without parentheses or arguments. + # + # super + # ^^^^^ + class ForwardingSuperNode < Node + # Initialize a new ForwardingSuperNode node. + def initialize(source, node_id, location, flags, block) + @source = source + @node_id = node_id + @location = location + @flags = flags + @block = block + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_forwarding_super_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [block] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << block if block + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*block] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?block: BlockNode?) -> ForwardingSuperNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, block: self.block) + ForwardingSuperNode.new(source, node_id, location, flags, block) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, block: BlockNode? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, block: block } + end + + # attr_reader block: BlockNode? + attr_reader :block + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :forwarding_super_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :forwarding_super_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ForwardingSuperNode) && + (block === other.block) + end + end + + # Represents the use of the `&&=` operator for assignment to a global variable. + # + # $target &&= value + # ^^^^^^^^^^^^^^^^^ + class GlobalVariableAndWriteNode < Node + # Initialize a new GlobalVariableAndWriteNode node. + def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @name_loc = name_loc + @operator_loc = operator_loc + @value = value + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_global_variable_and_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [name_loc, operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> GlobalVariableAndWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value) + GlobalVariableAndWriteNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, name_loc: name_loc, operator_loc: operator_loc, value: value } + end + + # attr_reader name: Symbol + attr_reader :name + + # attr_reader name_loc: Location + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # attr_reader value: Prism::node + attr_reader :value + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :global_variable_and_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :global_variable_and_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(GlobalVariableAndWriteNode) && + (name === other.name) && + (name_loc.nil? == other.name_loc.nil?) && + (operator_loc.nil? == other.operator_loc.nil?) && + (value === other.value) + end + end + + # Represents assigning to a global variable using an operator that isn't `=`. + # + # $target += value + # ^^^^^^^^^^^^^^^^ + class GlobalVariableOperatorWriteNode < Node + # Initialize a new GlobalVariableOperatorWriteNode node. + def initialize(source, node_id, location, flags, name, name_loc, binary_operator_loc, value, binary_operator) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @name_loc = name_loc + @binary_operator_loc = binary_operator_loc + @value = value + @binary_operator = binary_operator + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_global_variable_operator_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [name_loc, binary_operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?binary_operator_loc: Location, ?value: Prism::node, ?binary_operator: Symbol) -> GlobalVariableOperatorWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, binary_operator_loc: self.binary_operator_loc, value: self.value, binary_operator: self.binary_operator) + GlobalVariableOperatorWriteNode.new(source, node_id, location, flags, name, name_loc, binary_operator_loc, value, binary_operator) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, binary_operator_loc: Location, value: Prism::node, binary_operator: Symbol } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, name_loc: name_loc, binary_operator_loc: binary_operator_loc, value: value, binary_operator: binary_operator } + end + + # attr_reader name: Symbol + attr_reader :name + + # attr_reader name_loc: Location + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # attr_reader binary_operator_loc: Location + def binary_operator_loc + location = @binary_operator_loc + return location if location.is_a?(Location) + @binary_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the binary_operator_loc location using the given saved source so that + # it can be retrieved later. + def save_binary_operator_loc(repository) + repository.enter(node_id, :binary_operator_loc) + end + + # attr_reader value: Prism::node + attr_reader :value + + # attr_reader binary_operator: Symbol + attr_reader :binary_operator + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :global_variable_operator_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :global_variable_operator_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(GlobalVariableOperatorWriteNode) && + (name === other.name) && + (name_loc.nil? == other.name_loc.nil?) && + (binary_operator_loc.nil? == other.binary_operator_loc.nil?) && + (value === other.value) && + (binary_operator === other.binary_operator) + end + end + + # Represents the use of the `||=` operator for assignment to a global variable. + # + # $target ||= value + # ^^^^^^^^^^^^^^^^^ + class GlobalVariableOrWriteNode < Node + # Initialize a new GlobalVariableOrWriteNode node. + def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @name_loc = name_loc + @operator_loc = operator_loc + @value = value + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_global_variable_or_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [name_loc, operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> GlobalVariableOrWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value) + GlobalVariableOrWriteNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, name_loc: name_loc, operator_loc: operator_loc, value: value } + end + + # attr_reader name: Symbol + attr_reader :name + + # attr_reader name_loc: Location + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # attr_reader value: Prism::node + attr_reader :value + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :global_variable_or_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :global_variable_or_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(GlobalVariableOrWriteNode) && + (name === other.name) && + (name_loc.nil? == other.name_loc.nil?) && + (operator_loc.nil? == other.operator_loc.nil?) && + (value === other.value) + end + end + + # Represents referencing a global variable. + # + # $foo + # ^^^^ + class GlobalVariableReadNode < Node + # Initialize a new GlobalVariableReadNode node. + def initialize(source, node_id, location, flags, name) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_global_variable_read_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> GlobalVariableReadNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name) + GlobalVariableReadNode.new(source, node_id, location, flags, name) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name } + end + + # The name of the global variable, which is a `$` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifier). Alternatively, it can be one of the special global variables designated by a symbol. + # + # $foo # name `:$foo` + # + # $_Test # name `:$_Test` + attr_reader :name + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :global_variable_read_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :global_variable_read_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(GlobalVariableReadNode) && + (name === other.name) + end + end + + # Represents writing to a global variable in a context that doesn't have an explicit value. + # + # $foo, $bar = baz + # ^^^^ ^^^^ + class GlobalVariableTargetNode < Node + # Initialize a new GlobalVariableTargetNode node. + def initialize(source, node_id, location, flags, name) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_global_variable_target_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> GlobalVariableTargetNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name) + GlobalVariableTargetNode.new(source, node_id, location, flags, name) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name } + end + + # attr_reader name: Symbol + attr_reader :name + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :global_variable_target_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :global_variable_target_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(GlobalVariableTargetNode) && + (name === other.name) + end + end + + # Represents writing to a global variable. + # + # $foo = 1 + # ^^^^^^^^ + class GlobalVariableWriteNode < Node + # Initialize a new GlobalVariableWriteNode node. + def initialize(source, node_id, location, flags, name, name_loc, value, operator_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @name_loc = name_loc + @value = value + @operator_loc = operator_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_global_variable_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [name_loc, value, operator_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?value: Prism::node, ?operator_loc: Location) -> GlobalVariableWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, value: self.value, operator_loc: self.operator_loc) + GlobalVariableWriteNode.new(source, node_id, location, flags, name, name_loc, value, operator_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, value: Prism::node, operator_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, name_loc: name_loc, value: value, operator_loc: operator_loc } + end + + # The name of the global variable, which is a `$` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifier). Alternatively, it can be one of the special global variables designated by a symbol. + # + # $foo = :bar # name `:$foo` + # + # $_Test = 123 # name `:$_Test` + attr_reader :name + + # The location of the global variable's name. + # + # $foo = :bar + # ^^^^ + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # The value to write to the global variable. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # $foo = :bar + # ^^^^ + # + # $-xyz = 123 + # ^^^ + attr_reader :value + + # The location of the `=` operator. + # + # $foo = :bar + # ^ + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :global_variable_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :global_variable_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(GlobalVariableWriteNode) && + (name === other.name) && + (name_loc.nil? == other.name_loc.nil?) && + (value === other.value) && + (operator_loc.nil? == other.operator_loc.nil?) + end + end + + # Represents a hash literal. + # + # { a => b } + # ^^^^^^^^^^ + class HashNode < Node + # Initialize a new HashNode node. + def initialize(source, node_id, location, flags, opening_loc, elements, closing_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @opening_loc = opening_loc + @elements = elements + @closing_loc = closing_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_hash_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [*elements] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [*elements] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [opening_loc, *elements, closing_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?elements: Array[AssocNode | AssocSplatNode], ?closing_loc: Location) -> HashNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, elements: self.elements, closing_loc: self.closing_loc) + HashNode.new(source, node_id, location, flags, opening_loc, elements, closing_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location, elements: Array[AssocNode | AssocSplatNode], closing_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, opening_loc: opening_loc, elements: elements, closing_loc: closing_loc } + end + + # The location of the opening brace. + # + # { a => b } + # ^ + def opening_loc + location = @opening_loc + return location if location.is_a?(Location) + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) + end + + # The elements of the hash. These can be either `AssocNode`s or `AssocSplatNode`s. + # + # { a: b } + # ^^^^ + # + # { **foo } + # ^^^^^ + attr_reader :elements + + # The location of the closing brace. + # + # { a => b } + # ^ + def closing_loc + location = @closing_loc + return location if location.is_a?(Location) + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) + end + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :hash_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :hash_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(HashNode) && + (opening_loc.nil? == other.opening_loc.nil?) && + (elements.length == other.elements.length) && + elements.zip(other.elements).all? { |left, right| left === right } && + (closing_loc.nil? == other.closing_loc.nil?) + end + end + + # Represents a hash pattern in pattern matching. + # + # foo => { a: 1, b: 2 } + # ^^^^^^^^^^^^^^ + # + # foo => { a: 1, b: 2, **c } + # ^^^^^^^^^^^^^^^^^^^ + class HashPatternNode < Node + # Initialize a new HashPatternNode node. + def initialize(source, node_id, location, flags, constant, elements, rest, opening_loc, closing_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @constant = constant + @elements = elements + @rest = rest + @opening_loc = opening_loc + @closing_loc = closing_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_hash_pattern_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [constant, *elements, rest] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << constant if constant + compact.concat(elements) + compact << rest if rest + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*constant, *elements, *rest, *opening_loc, *closing_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?constant: ConstantReadNode | ConstantPathNode | nil, ?elements: Array[AssocNode], ?rest: AssocSplatNode | NoKeywordsParameterNode | nil, ?opening_loc: Location?, ?closing_loc: Location?) -> HashPatternNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, constant: self.constant, elements: self.elements, rest: self.rest, opening_loc: self.opening_loc, closing_loc: self.closing_loc) + HashPatternNode.new(source, node_id, location, flags, constant, elements, rest, opening_loc, closing_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, constant: ConstantReadNode | ConstantPathNode | nil, elements: Array[AssocNode], rest: AssocSplatNode | NoKeywordsParameterNode | nil, opening_loc: Location?, closing_loc: Location? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, constant: constant, elements: elements, rest: rest, opening_loc: opening_loc, closing_loc: closing_loc } + end + + # attr_reader constant: ConstantReadNode | ConstantPathNode | nil + attr_reader :constant + + # attr_reader elements: Array[AssocNode] + attr_reader :elements + + # attr_reader rest: AssocSplatNode | NoKeywordsParameterNode | nil + attr_reader :rest + + # attr_reader opening_loc: Location? + def opening_loc + location = @opening_loc + case location + when nil + nil + when Location + location + else + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) unless @opening_loc.nil? + end + + # attr_reader closing_loc: Location? + def closing_loc + location = @closing_loc + case location + when nil + nil + when Location + location + else + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) unless @closing_loc.nil? + end + + # def opening: () -> String? + def opening + opening_loc&.slice + end + + # def closing: () -> String? + def closing + closing_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :hash_pattern_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :hash_pattern_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(HashPatternNode) && + (constant === other.constant) && + (elements.length == other.elements.length) && + elements.zip(other.elements).all? { |left, right| left === right } && + (rest === other.rest) && + (opening_loc.nil? == other.opening_loc.nil?) && + (closing_loc.nil? == other.closing_loc.nil?) + end + end + + # Represents the use of the `if` keyword, either in the block form or the modifier form, or a ternary expression. + # + # bar if foo + # ^^^^^^^^^^ + # + # if foo then bar end + # ^^^^^^^^^^^^^^^^^^^ + # + # foo ? bar : baz + # ^^^^^^^^^^^^^^^ + class IfNode < Node + # Initialize a new IfNode node. + def initialize(source, node_id, location, flags, if_keyword_loc, predicate, then_keyword_loc, statements, subsequent, end_keyword_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @if_keyword_loc = if_keyword_loc + @predicate = predicate + @then_keyword_loc = then_keyword_loc + @statements = statements + @subsequent = subsequent + @end_keyword_loc = end_keyword_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_if_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [predicate, statements, subsequent] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << predicate + compact << statements if statements + compact << subsequent if subsequent + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*if_keyword_loc, predicate, *then_keyword_loc, *statements, *subsequent, *end_keyword_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?if_keyword_loc: Location?, ?predicate: Prism::node, ?then_keyword_loc: Location?, ?statements: StatementsNode?, ?subsequent: ElseNode | IfNode | nil, ?end_keyword_loc: Location?) -> IfNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, if_keyword_loc: self.if_keyword_loc, predicate: self.predicate, then_keyword_loc: self.then_keyword_loc, statements: self.statements, subsequent: self.subsequent, end_keyword_loc: self.end_keyword_loc) + IfNode.new(source, node_id, location, flags, if_keyword_loc, predicate, then_keyword_loc, statements, subsequent, end_keyword_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, if_keyword_loc: Location?, predicate: Prism::node, then_keyword_loc: Location?, statements: StatementsNode?, subsequent: ElseNode | IfNode | nil, end_keyword_loc: Location? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, if_keyword_loc: if_keyword_loc, predicate: predicate, then_keyword_loc: then_keyword_loc, statements: statements, subsequent: subsequent, end_keyword_loc: end_keyword_loc } + end + + # The location of the `if` keyword if present. + # + # bar if foo + # ^^ + # + # The `if_keyword_loc` field will be `nil` when the `IfNode` represents a ternary expression. + def if_keyword_loc + location = @if_keyword_loc + case location + when nil + nil + when Location + location + else + @if_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the if_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_if_keyword_loc(repository) + repository.enter(node_id, :if_keyword_loc) unless @if_keyword_loc.nil? + end + + # The node for the condition the `IfNode` is testing. + # + # if foo + # ^^^ + # bar + # end + # + # bar if foo + # ^^^ + # + # foo ? bar : baz + # ^^^ + attr_reader :predicate + + # The location of the `then` keyword (if present) or the `?` in a ternary expression, `nil` otherwise. + # + # if foo then bar end + # ^^^^ + # + # a ? b : c + # ^ + def then_keyword_loc + location = @then_keyword_loc + case location + when nil + nil + when Location + location + else + @then_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the then_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_then_keyword_loc(repository) + repository.enter(node_id, :then_keyword_loc) unless @then_keyword_loc.nil? + end + + # Represents the body of statements that will be executed when the predicate is evaluated as truthy. Will be `nil` when no body is provided. + # + # if foo + # bar + # ^^^ + # baz + # ^^^ + # end + attr_reader :statements + + # Represents an `ElseNode` or an `IfNode` when there is an `else` or an `elsif` in the `if` statement. + # + # if foo + # bar + # elsif baz + # ^^^^^^^^^ + # qux + # ^^^ + # end + # ^^^ + # + # if foo then bar else baz end + # ^^^^^^^^^^^^ + attr_reader :subsequent + + # The location of the `end` keyword if present, `nil` otherwise. + # + # if foo + # bar + # end + # ^^^ + def end_keyword_loc + location = @end_keyword_loc + case location + when nil + nil + when Location + location + else + @end_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the end_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_end_keyword_loc(repository) + repository.enter(node_id, :end_keyword_loc) unless @end_keyword_loc.nil? + end + + # def if_keyword: () -> String? + def if_keyword + if_keyword_loc&.slice + end + + # def then_keyword: () -> String? + def then_keyword + then_keyword_loc&.slice + end + + # def end_keyword: () -> String? + def end_keyword + end_keyword_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :if_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :if_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(IfNode) && + (if_keyword_loc.nil? == other.if_keyword_loc.nil?) && + (predicate === other.predicate) && + (then_keyword_loc.nil? == other.then_keyword_loc.nil?) && + (statements === other.statements) && + (subsequent === other.subsequent) && + (end_keyword_loc.nil? == other.end_keyword_loc.nil?) + end + end + + # Represents an imaginary number literal. + # + # 1.0i + # ^^^^ + class ImaginaryNode < Node + # Initialize a new ImaginaryNode node. + def initialize(source, node_id, location, flags, numeric) + @source = source + @node_id = node_id + @location = location + @flags = flags + @numeric = numeric + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_imaginary_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [numeric] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [numeric] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [numeric] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?numeric: FloatNode | IntegerNode | RationalNode) -> ImaginaryNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, numeric: self.numeric) + ImaginaryNode.new(source, node_id, location, flags, numeric) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, numeric: FloatNode | IntegerNode | RationalNode } + def deconstruct_keys(keys) + { node_id: node_id, location: location, numeric: numeric } + end + + # attr_reader numeric: FloatNode | IntegerNode | RationalNode + attr_reader :numeric + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :imaginary_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :imaginary_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ImaginaryNode) && + (numeric === other.numeric) + end + end + + # Represents a node that is implicitly being added to the tree but doesn't correspond directly to a node in the source. + # + # { foo: } + # ^^^^ + # + # { Foo: } + # ^^^^ + # + # foo in { bar: } + # ^^^^ + class ImplicitNode < Node + # Initialize a new ImplicitNode node. + def initialize(source, node_id, location, flags, value) + @source = source + @node_id = node_id + @location = location + @flags = flags + @value = value + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_implicit_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?value: LocalVariableReadNode | CallNode | ConstantReadNode | LocalVariableTargetNode) -> ImplicitNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, value: self.value) + ImplicitNode.new(source, node_id, location, flags, value) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, value: LocalVariableReadNode | CallNode | ConstantReadNode | LocalVariableTargetNode } + def deconstruct_keys(keys) + { node_id: node_id, location: location, value: value } + end + + # attr_reader value: LocalVariableReadNode | CallNode | ConstantReadNode | LocalVariableTargetNode + attr_reader :value + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :implicit_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :implicit_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ImplicitNode) && + (value === other.value) + end + end + + # Represents using a trailing comma to indicate an implicit rest parameter. + # + # foo { |bar,| } + # ^ + # + # foo in [bar,] + # ^ + # + # for foo, in bar do end + # ^ + # + # foo, = bar + # ^ + class ImplicitRestNode < Node + # Initialize a new ImplicitRestNode node. + def initialize(source, node_id, location, flags) + @source = source + @node_id = node_id + @location = location + @flags = flags + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_implicit_rest_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> ImplicitRestNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags) + ImplicitRestNode.new(source, node_id, location, flags) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location } + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :implicit_rest_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :implicit_rest_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ImplicitRestNode) + end + end + + # Represents the use of the `in` keyword in a case statement. + # + # case a; in b then c end + # ^^^^^^^^^^^ + class InNode < Node + # Initialize a new InNode node. + def initialize(source, node_id, location, flags, pattern, statements, in_loc, then_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @pattern = pattern + @statements = statements + @in_loc = in_loc + @then_loc = then_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_in_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [pattern, statements] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << pattern + compact << statements if statements + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [pattern, *statements, in_loc, *then_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?pattern: Prism::node, ?statements: StatementsNode?, ?in_loc: Location, ?then_loc: Location?) -> InNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, pattern: self.pattern, statements: self.statements, in_loc: self.in_loc, then_loc: self.then_loc) + InNode.new(source, node_id, location, flags, pattern, statements, in_loc, then_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, pattern: Prism::node, statements: StatementsNode?, in_loc: Location, then_loc: Location? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, pattern: pattern, statements: statements, in_loc: in_loc, then_loc: then_loc } + end + + # attr_reader pattern: Prism::node + attr_reader :pattern + + # attr_reader statements: StatementsNode? + attr_reader :statements + + # attr_reader in_loc: Location + def in_loc + location = @in_loc + return location if location.is_a?(Location) + @in_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the in_loc location using the given saved source so that + # it can be retrieved later. + def save_in_loc(repository) + repository.enter(node_id, :in_loc) + end + + # attr_reader then_loc: Location? + def then_loc + location = @then_loc + case location + when nil + nil + when Location + location + else + @then_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the then_loc location using the given saved source so that + # it can be retrieved later. + def save_then_loc(repository) + repository.enter(node_id, :then_loc) unless @then_loc.nil? + end + + # def in: () -> String + def in + in_loc.slice + end + + # def then: () -> String? + def then + then_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :in_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :in_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(InNode) && + (pattern === other.pattern) && + (statements === other.statements) && + (in_loc.nil? == other.in_loc.nil?) && + (then_loc.nil? == other.then_loc.nil?) + end + end + + # Represents the use of the `&&=` operator on a call to the `[]` method. + # + # foo.bar[baz] &&= value + # ^^^^^^^^^^^^^^^^^^^^^^ + class IndexAndWriteNode < Node + # Initialize a new IndexAndWriteNode node. + def initialize(source, node_id, location, flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, operator_loc, value) + @source = source + @node_id = node_id + @location = location + @flags = flags + @receiver = receiver + @call_operator_loc = call_operator_loc + @opening_loc = opening_loc + @arguments = arguments + @closing_loc = closing_loc + @block = block + @operator_loc = operator_loc + @value = value + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_index_and_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [receiver, arguments, block, value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << receiver if receiver + compact << arguments if arguments + compact << block if block + compact << value + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*receiver, *call_operator_loc, opening_loc, *arguments, closing_loc, *block, operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?opening_loc: Location, ?arguments: ArgumentsNode?, ?closing_loc: Location, ?block: BlockArgumentNode?, ?operator_loc: Location, ?value: Prism::node) -> IndexAndWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, opening_loc: self.opening_loc, arguments: self.arguments, closing_loc: self.closing_loc, block: self.block, operator_loc: self.operator_loc, value: self.value) + IndexAndWriteNode.new(source, node_id, location, flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, operator_loc, value) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, opening_loc: Location, arguments: ArgumentsNode?, closing_loc: Location, block: BlockArgumentNode?, operator_loc: Location, value: Prism::node } + def deconstruct_keys(keys) + { node_id: node_id, location: location, receiver: receiver, call_operator_loc: call_operator_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block, operator_loc: operator_loc, value: value } + end + + # def safe_navigation?: () -> bool + def safe_navigation? + flags.anybits?(CallNodeFlags::SAFE_NAVIGATION) + end + + # def variable_call?: () -> bool + def variable_call? + flags.anybits?(CallNodeFlags::VARIABLE_CALL) + end + + # def attribute_write?: () -> bool + def attribute_write? + flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE) + end + + # def ignore_visibility?: () -> bool + def ignore_visibility? + flags.anybits?(CallNodeFlags::IGNORE_VISIBILITY) + end + + # attr_reader receiver: Prism::node? + attr_reader :receiver + + # attr_reader call_operator_loc: Location? + def call_operator_loc + location = @call_operator_loc + case location + when nil + nil + when Location + location + else + @call_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the call_operator_loc location using the given saved source so that + # it can be retrieved later. + def save_call_operator_loc(repository) + repository.enter(node_id, :call_operator_loc) unless @call_operator_loc.nil? + end + + # attr_reader opening_loc: Location + def opening_loc + location = @opening_loc + return location if location.is_a?(Location) + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) + end + + # attr_reader arguments: ArgumentsNode? + attr_reader :arguments + + # attr_reader closing_loc: Location + def closing_loc + location = @closing_loc + return location if location.is_a?(Location) + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) + end + + # attr_reader block: BlockArgumentNode? + attr_reader :block + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # attr_reader value: Prism::node + attr_reader :value + + # def call_operator: () -> String? + def call_operator + call_operator_loc&.slice + end + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :index_and_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :index_and_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(IndexAndWriteNode) && + (flags === other.flags) && + (receiver === other.receiver) && + (call_operator_loc.nil? == other.call_operator_loc.nil?) && + (opening_loc.nil? == other.opening_loc.nil?) && + (arguments === other.arguments) && + (closing_loc.nil? == other.closing_loc.nil?) && + (block === other.block) && + (operator_loc.nil? == other.operator_loc.nil?) && + (value === other.value) + end + end + + # Represents the use of an assignment operator on a call to `[]`. + # + # foo.bar[baz] += value + # ^^^^^^^^^^^^^^^^^^^^^ + class IndexOperatorWriteNode < Node + # Initialize a new IndexOperatorWriteNode node. + def initialize(source, node_id, location, flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, binary_operator, binary_operator_loc, value) + @source = source + @node_id = node_id + @location = location + @flags = flags + @receiver = receiver + @call_operator_loc = call_operator_loc + @opening_loc = opening_loc + @arguments = arguments + @closing_loc = closing_loc + @block = block + @binary_operator = binary_operator + @binary_operator_loc = binary_operator_loc + @value = value + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_index_operator_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [receiver, arguments, block, value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << receiver if receiver + compact << arguments if arguments + compact << block if block + compact << value + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*receiver, *call_operator_loc, opening_loc, *arguments, closing_loc, *block, binary_operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?opening_loc: Location, ?arguments: ArgumentsNode?, ?closing_loc: Location, ?block: BlockArgumentNode?, ?binary_operator: Symbol, ?binary_operator_loc: Location, ?value: Prism::node) -> IndexOperatorWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, opening_loc: self.opening_loc, arguments: self.arguments, closing_loc: self.closing_loc, block: self.block, binary_operator: self.binary_operator, binary_operator_loc: self.binary_operator_loc, value: self.value) + IndexOperatorWriteNode.new(source, node_id, location, flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, binary_operator, binary_operator_loc, value) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, opening_loc: Location, arguments: ArgumentsNode?, closing_loc: Location, block: BlockArgumentNode?, binary_operator: Symbol, binary_operator_loc: Location, value: Prism::node } + def deconstruct_keys(keys) + { node_id: node_id, location: location, receiver: receiver, call_operator_loc: call_operator_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block, binary_operator: binary_operator, binary_operator_loc: binary_operator_loc, value: value } + end + + # def safe_navigation?: () -> bool + def safe_navigation? + flags.anybits?(CallNodeFlags::SAFE_NAVIGATION) + end + + # def variable_call?: () -> bool + def variable_call? + flags.anybits?(CallNodeFlags::VARIABLE_CALL) + end + + # def attribute_write?: () -> bool + def attribute_write? + flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE) + end + + # def ignore_visibility?: () -> bool + def ignore_visibility? + flags.anybits?(CallNodeFlags::IGNORE_VISIBILITY) + end + + # attr_reader receiver: Prism::node? + attr_reader :receiver + + # attr_reader call_operator_loc: Location? + def call_operator_loc + location = @call_operator_loc + case location + when nil + nil + when Location + location + else + @call_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the call_operator_loc location using the given saved source so that + # it can be retrieved later. + def save_call_operator_loc(repository) + repository.enter(node_id, :call_operator_loc) unless @call_operator_loc.nil? + end + + # attr_reader opening_loc: Location + def opening_loc + location = @opening_loc + return location if location.is_a?(Location) + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) + end + + # attr_reader arguments: ArgumentsNode? + attr_reader :arguments + + # attr_reader closing_loc: Location + def closing_loc + location = @closing_loc + return location if location.is_a?(Location) + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) + end + + # attr_reader block: BlockArgumentNode? + attr_reader :block + + # attr_reader binary_operator: Symbol + attr_reader :binary_operator + + # attr_reader binary_operator_loc: Location + def binary_operator_loc + location = @binary_operator_loc + return location if location.is_a?(Location) + @binary_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the binary_operator_loc location using the given saved source so that + # it can be retrieved later. + def save_binary_operator_loc(repository) + repository.enter(node_id, :binary_operator_loc) + end + + # attr_reader value: Prism::node + attr_reader :value + + # def call_operator: () -> String? + def call_operator + call_operator_loc&.slice + end + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :index_operator_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :index_operator_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(IndexOperatorWriteNode) && + (flags === other.flags) && + (receiver === other.receiver) && + (call_operator_loc.nil? == other.call_operator_loc.nil?) && + (opening_loc.nil? == other.opening_loc.nil?) && + (arguments === other.arguments) && + (closing_loc.nil? == other.closing_loc.nil?) && + (block === other.block) && + (binary_operator === other.binary_operator) && + (binary_operator_loc.nil? == other.binary_operator_loc.nil?) && + (value === other.value) + end + end + + # Represents the use of the `||=` operator on a call to `[]`. + # + # foo.bar[baz] ||= value + # ^^^^^^^^^^^^^^^^^^^^^^ + class IndexOrWriteNode < Node + # Initialize a new IndexOrWriteNode node. + def initialize(source, node_id, location, flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, operator_loc, value) + @source = source + @node_id = node_id + @location = location + @flags = flags + @receiver = receiver + @call_operator_loc = call_operator_loc + @opening_loc = opening_loc + @arguments = arguments + @closing_loc = closing_loc + @block = block + @operator_loc = operator_loc + @value = value + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_index_or_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [receiver, arguments, block, value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << receiver if receiver + compact << arguments if arguments + compact << block if block + compact << value + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*receiver, *call_operator_loc, opening_loc, *arguments, closing_loc, *block, operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?opening_loc: Location, ?arguments: ArgumentsNode?, ?closing_loc: Location, ?block: BlockArgumentNode?, ?operator_loc: Location, ?value: Prism::node) -> IndexOrWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, opening_loc: self.opening_loc, arguments: self.arguments, closing_loc: self.closing_loc, block: self.block, operator_loc: self.operator_loc, value: self.value) + IndexOrWriteNode.new(source, node_id, location, flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, operator_loc, value) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, opening_loc: Location, arguments: ArgumentsNode?, closing_loc: Location, block: BlockArgumentNode?, operator_loc: Location, value: Prism::node } + def deconstruct_keys(keys) + { node_id: node_id, location: location, receiver: receiver, call_operator_loc: call_operator_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block, operator_loc: operator_loc, value: value } + end + + # def safe_navigation?: () -> bool + def safe_navigation? + flags.anybits?(CallNodeFlags::SAFE_NAVIGATION) + end + + # def variable_call?: () -> bool + def variable_call? + flags.anybits?(CallNodeFlags::VARIABLE_CALL) + end + + # def attribute_write?: () -> bool + def attribute_write? + flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE) + end + + # def ignore_visibility?: () -> bool + def ignore_visibility? + flags.anybits?(CallNodeFlags::IGNORE_VISIBILITY) + end + + # attr_reader receiver: Prism::node? + attr_reader :receiver + + # attr_reader call_operator_loc: Location? + def call_operator_loc + location = @call_operator_loc + case location + when nil + nil + when Location + location + else + @call_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the call_operator_loc location using the given saved source so that + # it can be retrieved later. + def save_call_operator_loc(repository) + repository.enter(node_id, :call_operator_loc) unless @call_operator_loc.nil? + end + + # attr_reader opening_loc: Location + def opening_loc + location = @opening_loc + return location if location.is_a?(Location) + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) + end + + # attr_reader arguments: ArgumentsNode? + attr_reader :arguments + + # attr_reader closing_loc: Location + def closing_loc + location = @closing_loc + return location if location.is_a?(Location) + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) + end + + # attr_reader block: BlockArgumentNode? + attr_reader :block + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # attr_reader value: Prism::node + attr_reader :value + + # def call_operator: () -> String? + def call_operator + call_operator_loc&.slice + end + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :index_or_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :index_or_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(IndexOrWriteNode) && + (flags === other.flags) && + (receiver === other.receiver) && + (call_operator_loc.nil? == other.call_operator_loc.nil?) && + (opening_loc.nil? == other.opening_loc.nil?) && + (arguments === other.arguments) && + (closing_loc.nil? == other.closing_loc.nil?) && + (block === other.block) && + (operator_loc.nil? == other.operator_loc.nil?) && + (value === other.value) + end + end + + # Represents assigning to an index. + # + # foo[bar], = 1 + # ^^^^^^^^ + # + # begin + # rescue => foo[bar] + # ^^^^^^^^ + # end + # + # for foo[bar] in baz do end + # ^^^^^^^^ + class IndexTargetNode < Node + # Initialize a new IndexTargetNode node. + def initialize(source, node_id, location, flags, receiver, opening_loc, arguments, closing_loc, block) + @source = source + @node_id = node_id + @location = location + @flags = flags + @receiver = receiver + @opening_loc = opening_loc + @arguments = arguments + @closing_loc = closing_loc + @block = block + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_index_target_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [receiver, arguments, block] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << receiver + compact << arguments if arguments + compact << block if block + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [receiver, opening_loc, *arguments, closing_loc, *block] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node, ?opening_loc: Location, ?arguments: ArgumentsNode?, ?closing_loc: Location, ?block: BlockArgumentNode?) -> IndexTargetNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, opening_loc: self.opening_loc, arguments: self.arguments, closing_loc: self.closing_loc, block: self.block) + IndexTargetNode.new(source, node_id, location, flags, receiver, opening_loc, arguments, closing_loc, block) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node, opening_loc: Location, arguments: ArgumentsNode?, closing_loc: Location, block: BlockArgumentNode? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, receiver: receiver, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block } + end + + # def safe_navigation?: () -> bool + def safe_navigation? + flags.anybits?(CallNodeFlags::SAFE_NAVIGATION) + end + + # def variable_call?: () -> bool + def variable_call? + flags.anybits?(CallNodeFlags::VARIABLE_CALL) + end + + # def attribute_write?: () -> bool + def attribute_write? + flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE) + end + + # def ignore_visibility?: () -> bool + def ignore_visibility? + flags.anybits?(CallNodeFlags::IGNORE_VISIBILITY) + end + + # attr_reader receiver: Prism::node + attr_reader :receiver + + # attr_reader opening_loc: Location + def opening_loc + location = @opening_loc + return location if location.is_a?(Location) + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) + end + + # attr_reader arguments: ArgumentsNode? + attr_reader :arguments + + # attr_reader closing_loc: Location + def closing_loc + location = @closing_loc + return location if location.is_a?(Location) + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) + end + + # attr_reader block: BlockArgumentNode? + attr_reader :block + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :index_target_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :index_target_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(IndexTargetNode) && + (flags === other.flags) && + (receiver === other.receiver) && + (opening_loc.nil? == other.opening_loc.nil?) && + (arguments === other.arguments) && + (closing_loc.nil? == other.closing_loc.nil?) && + (block === other.block) + end + end + + # Represents the use of the `&&=` operator for assignment to an instance variable. + # + # @target &&= value + # ^^^^^^^^^^^^^^^^^ + class InstanceVariableAndWriteNode < Node + # Initialize a new InstanceVariableAndWriteNode node. + def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @name_loc = name_loc + @operator_loc = operator_loc + @value = value + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_instance_variable_and_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [name_loc, operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> InstanceVariableAndWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value) + InstanceVariableAndWriteNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, name_loc: name_loc, operator_loc: operator_loc, value: value } + end + + # attr_reader name: Symbol + attr_reader :name + + # attr_reader name_loc: Location + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # attr_reader value: Prism::node + attr_reader :value + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :instance_variable_and_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :instance_variable_and_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(InstanceVariableAndWriteNode) && + (name === other.name) && + (name_loc.nil? == other.name_loc.nil?) && + (operator_loc.nil? == other.operator_loc.nil?) && + (value === other.value) + end + end + + # Represents assigning to an instance variable using an operator that isn't `=`. + # + # @target += value + # ^^^^^^^^^^^^^^^^ + class InstanceVariableOperatorWriteNode < Node + # Initialize a new InstanceVariableOperatorWriteNode node. + def initialize(source, node_id, location, flags, name, name_loc, binary_operator_loc, value, binary_operator) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @name_loc = name_loc + @binary_operator_loc = binary_operator_loc + @value = value + @binary_operator = binary_operator + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_instance_variable_operator_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [name_loc, binary_operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?binary_operator_loc: Location, ?value: Prism::node, ?binary_operator: Symbol) -> InstanceVariableOperatorWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, binary_operator_loc: self.binary_operator_loc, value: self.value, binary_operator: self.binary_operator) + InstanceVariableOperatorWriteNode.new(source, node_id, location, flags, name, name_loc, binary_operator_loc, value, binary_operator) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, binary_operator_loc: Location, value: Prism::node, binary_operator: Symbol } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, name_loc: name_loc, binary_operator_loc: binary_operator_loc, value: value, binary_operator: binary_operator } + end + + # attr_reader name: Symbol + attr_reader :name + + # attr_reader name_loc: Location + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # attr_reader binary_operator_loc: Location + def binary_operator_loc + location = @binary_operator_loc + return location if location.is_a?(Location) + @binary_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the binary_operator_loc location using the given saved source so that + # it can be retrieved later. + def save_binary_operator_loc(repository) + repository.enter(node_id, :binary_operator_loc) + end + + # attr_reader value: Prism::node + attr_reader :value + + # attr_reader binary_operator: Symbol + attr_reader :binary_operator + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :instance_variable_operator_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :instance_variable_operator_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(InstanceVariableOperatorWriteNode) && + (name === other.name) && + (name_loc.nil? == other.name_loc.nil?) && + (binary_operator_loc.nil? == other.binary_operator_loc.nil?) && + (value === other.value) && + (binary_operator === other.binary_operator) + end + end + + # Represents the use of the `||=` operator for assignment to an instance variable. + # + # @target ||= value + # ^^^^^^^^^^^^^^^^^ + class InstanceVariableOrWriteNode < Node + # Initialize a new InstanceVariableOrWriteNode node. + def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @name_loc = name_loc + @operator_loc = operator_loc + @value = value + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_instance_variable_or_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [name_loc, operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> InstanceVariableOrWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value) + InstanceVariableOrWriteNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, name_loc: name_loc, operator_loc: operator_loc, value: value } + end + + # attr_reader name: Symbol + attr_reader :name + + # attr_reader name_loc: Location + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # attr_reader value: Prism::node + attr_reader :value + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :instance_variable_or_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :instance_variable_or_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(InstanceVariableOrWriteNode) && + (name === other.name) && + (name_loc.nil? == other.name_loc.nil?) && + (operator_loc.nil? == other.operator_loc.nil?) && + (value === other.value) + end + end + + # Represents referencing an instance variable. + # + # @foo + # ^^^^ + class InstanceVariableReadNode < Node + # Initialize a new InstanceVariableReadNode node. + def initialize(source, node_id, location, flags, name) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_instance_variable_read_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> InstanceVariableReadNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name) + InstanceVariableReadNode.new(source, node_id, location, flags, name) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name } + end + + # The name of the instance variable, which is a `@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). + # + # @x # name `:@x` + # + # @_test # name `:@_test` + attr_reader :name + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :instance_variable_read_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :instance_variable_read_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(InstanceVariableReadNode) && + (name === other.name) + end + end + + # Represents writing to an instance variable in a context that doesn't have an explicit value. + # + # @foo, @bar = baz + # ^^^^ ^^^^ + class InstanceVariableTargetNode < Node + # Initialize a new InstanceVariableTargetNode node. + def initialize(source, node_id, location, flags, name) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_instance_variable_target_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> InstanceVariableTargetNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name) + InstanceVariableTargetNode.new(source, node_id, location, flags, name) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name } + end + + # attr_reader name: Symbol + attr_reader :name + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :instance_variable_target_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :instance_variable_target_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(InstanceVariableTargetNode) && + (name === other.name) + end + end + + # Represents writing to an instance variable. + # + # @foo = 1 + # ^^^^^^^^ + class InstanceVariableWriteNode < Node + # Initialize a new InstanceVariableWriteNode node. + def initialize(source, node_id, location, flags, name, name_loc, value, operator_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @name_loc = name_loc + @value = value + @operator_loc = operator_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_instance_variable_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [name_loc, value, operator_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?value: Prism::node, ?operator_loc: Location) -> InstanceVariableWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, value: self.value, operator_loc: self.operator_loc) + InstanceVariableWriteNode.new(source, node_id, location, flags, name, name_loc, value, operator_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, value: Prism::node, operator_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, name_loc: name_loc, value: value, operator_loc: operator_loc } + end + + # The name of the instance variable, which is a `@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). + # + # @x = :y # name `:@x` + # + # @_foo = "bar" # name `@_foo` + attr_reader :name + + # The location of the variable name. + # + # @_x = 1 + # ^^^ + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # The value to write to the instance variable. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # @foo = :bar + # ^^^^ + # + # @_x = 1234 + # ^^^^ + attr_reader :value + + # The location of the `=` operator. + # + # @x = y + # ^ + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :instance_variable_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :instance_variable_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(InstanceVariableWriteNode) && + (name === other.name) && + (name_loc.nil? == other.name_loc.nil?) && + (value === other.value) && + (operator_loc.nil? == other.operator_loc.nil?) + end + end + + # Represents an integer number literal. + # + # 1 + # ^ + class IntegerNode < Node + # Initialize a new IntegerNode node. + def initialize(source, node_id, location, flags, value) + @source = source + @node_id = node_id + @location = location + @flags = flags + @value = value + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_integer_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?value: Integer) -> IntegerNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, value: self.value) + IntegerNode.new(source, node_id, location, flags, value) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, value: Integer } + def deconstruct_keys(keys) + { node_id: node_id, location: location, value: value } + end + + # def binary?: () -> bool + def binary? + flags.anybits?(IntegerBaseFlags::BINARY) + end + + # def decimal?: () -> bool + def decimal? + flags.anybits?(IntegerBaseFlags::DECIMAL) + end + + # def octal?: () -> bool + def octal? + flags.anybits?(IntegerBaseFlags::OCTAL) + end + + # def hexadecimal?: () -> bool + def hexadecimal? + flags.anybits?(IntegerBaseFlags::HEXADECIMAL) + end + + # The value of the integer literal as a number. + attr_reader :value + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :integer_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :integer_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(IntegerNode) && + (flags === other.flags) && + (value === other.value) + end + end + + # Represents a regular expression literal that contains interpolation that is being used in the predicate of a conditional to implicitly match against the last line read by an IO object. + # + # if /foo #{bar} baz/ then end + # ^^^^^^^^^^^^^^^^ + class InterpolatedMatchLastLineNode < Node + # Initialize a new InterpolatedMatchLastLineNode node. + def initialize(source, node_id, location, flags, opening_loc, parts, closing_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @opening_loc = opening_loc + @parts = parts + @closing_loc = closing_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_interpolated_match_last_line_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [*parts] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [*parts] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [opening_loc, *parts, closing_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], ?closing_loc: Location) -> InterpolatedMatchLastLineNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, parts: self.parts, closing_loc: self.closing_loc) + InterpolatedMatchLastLineNode.new(source, node_id, location, flags, opening_loc, parts, closing_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location, parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], closing_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, opening_loc: opening_loc, parts: parts, closing_loc: closing_loc } + end + + # def ignore_case?: () -> bool + def ignore_case? + flags.anybits?(RegularExpressionFlags::IGNORE_CASE) + end + + # def extended?: () -> bool + def extended? + flags.anybits?(RegularExpressionFlags::EXTENDED) + end + + # def multi_line?: () -> bool + def multi_line? + flags.anybits?(RegularExpressionFlags::MULTI_LINE) + end + + # def once?: () -> bool + def once? + flags.anybits?(RegularExpressionFlags::ONCE) + end + + # def euc_jp?: () -> bool + def euc_jp? + flags.anybits?(RegularExpressionFlags::EUC_JP) + end + + # def ascii_8bit?: () -> bool + def ascii_8bit? + flags.anybits?(RegularExpressionFlags::ASCII_8BIT) + end + + # def windows_31j?: () -> bool + def windows_31j? + flags.anybits?(RegularExpressionFlags::WINDOWS_31J) + end + + # def utf_8?: () -> bool + def utf_8? + flags.anybits?(RegularExpressionFlags::UTF_8) + end + + # def forced_utf8_encoding?: () -> bool + def forced_utf8_encoding? + flags.anybits?(RegularExpressionFlags::FORCED_UTF8_ENCODING) + end + + # def forced_binary_encoding?: () -> bool + def forced_binary_encoding? + flags.anybits?(RegularExpressionFlags::FORCED_BINARY_ENCODING) + end + + # def forced_us_ascii_encoding?: () -> bool + def forced_us_ascii_encoding? + flags.anybits?(RegularExpressionFlags::FORCED_US_ASCII_ENCODING) + end + + # attr_reader opening_loc: Location + def opening_loc + location = @opening_loc + return location if location.is_a?(Location) + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) + end + + # attr_reader parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode] + attr_reader :parts + + # attr_reader closing_loc: Location + def closing_loc + location = @closing_loc + return location if location.is_a?(Location) + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) + end + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :interpolated_match_last_line_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :interpolated_match_last_line_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(InterpolatedMatchLastLineNode) && + (flags === other.flags) && + (opening_loc.nil? == other.opening_loc.nil?) && + (parts.length == other.parts.length) && + parts.zip(other.parts).all? { |left, right| left === right } && + (closing_loc.nil? == other.closing_loc.nil?) + end + end + + # Represents a regular expression literal that contains interpolation. + # + # /foo #{bar} baz/ + # ^^^^^^^^^^^^^^^^ + class InterpolatedRegularExpressionNode < Node + # Initialize a new InterpolatedRegularExpressionNode node. + def initialize(source, node_id, location, flags, opening_loc, parts, closing_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @opening_loc = opening_loc + @parts = parts + @closing_loc = closing_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_interpolated_regular_expression_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [*parts] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [*parts] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [opening_loc, *parts, closing_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], ?closing_loc: Location) -> InterpolatedRegularExpressionNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, parts: self.parts, closing_loc: self.closing_loc) + InterpolatedRegularExpressionNode.new(source, node_id, location, flags, opening_loc, parts, closing_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location, parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], closing_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, opening_loc: opening_loc, parts: parts, closing_loc: closing_loc } + end + + # def ignore_case?: () -> bool + def ignore_case? + flags.anybits?(RegularExpressionFlags::IGNORE_CASE) + end + + # def extended?: () -> bool + def extended? + flags.anybits?(RegularExpressionFlags::EXTENDED) + end + + # def multi_line?: () -> bool + def multi_line? + flags.anybits?(RegularExpressionFlags::MULTI_LINE) + end + + # def once?: () -> bool + def once? + flags.anybits?(RegularExpressionFlags::ONCE) + end + + # def euc_jp?: () -> bool + def euc_jp? + flags.anybits?(RegularExpressionFlags::EUC_JP) + end + + # def ascii_8bit?: () -> bool + def ascii_8bit? + flags.anybits?(RegularExpressionFlags::ASCII_8BIT) + end + + # def windows_31j?: () -> bool + def windows_31j? + flags.anybits?(RegularExpressionFlags::WINDOWS_31J) + end + + # def utf_8?: () -> bool + def utf_8? + flags.anybits?(RegularExpressionFlags::UTF_8) + end + + # def forced_utf8_encoding?: () -> bool + def forced_utf8_encoding? + flags.anybits?(RegularExpressionFlags::FORCED_UTF8_ENCODING) + end + + # def forced_binary_encoding?: () -> bool + def forced_binary_encoding? + flags.anybits?(RegularExpressionFlags::FORCED_BINARY_ENCODING) + end + + # def forced_us_ascii_encoding?: () -> bool + def forced_us_ascii_encoding? + flags.anybits?(RegularExpressionFlags::FORCED_US_ASCII_ENCODING) + end + + # attr_reader opening_loc: Location + def opening_loc + location = @opening_loc + return location if location.is_a?(Location) + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) + end + + # attr_reader parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode] + attr_reader :parts + + # attr_reader closing_loc: Location + def closing_loc + location = @closing_loc + return location if location.is_a?(Location) + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) + end + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :interpolated_regular_expression_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :interpolated_regular_expression_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(InterpolatedRegularExpressionNode) && + (flags === other.flags) && + (opening_loc.nil? == other.opening_loc.nil?) && + (parts.length == other.parts.length) && + parts.zip(other.parts).all? { |left, right| left === right } && + (closing_loc.nil? == other.closing_loc.nil?) + end + end + + # Represents a string literal that contains interpolation. + # + # "foo #{bar} baz" + # ^^^^^^^^^^^^^^^^ + class InterpolatedStringNode < Node + # Initialize a new InterpolatedStringNode node. + def initialize(source, node_id, location, flags, opening_loc, parts, closing_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @opening_loc = opening_loc + @parts = parts + @closing_loc = closing_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_interpolated_string_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [*parts] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [*parts] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*opening_loc, *parts, *closing_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location?, ?parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode | InterpolatedStringNode | XStringNode], ?closing_loc: Location?) -> InterpolatedStringNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, parts: self.parts, closing_loc: self.closing_loc) + InterpolatedStringNode.new(source, node_id, location, flags, opening_loc, parts, closing_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location?, parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode | InterpolatedStringNode | XStringNode], closing_loc: Location? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, opening_loc: opening_loc, parts: parts, closing_loc: closing_loc } + end + + # def frozen?: () -> bool + def frozen? + flags.anybits?(InterpolatedStringNodeFlags::FROZEN) + end + + # def mutable?: () -> bool + def mutable? + flags.anybits?(InterpolatedStringNodeFlags::MUTABLE) + end + + # attr_reader opening_loc: Location? + def opening_loc + location = @opening_loc + case location + when nil + nil + when Location + location + else + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) unless @opening_loc.nil? + end + + # attr_reader parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode | InterpolatedStringNode | XStringNode] + attr_reader :parts + + # attr_reader closing_loc: Location? + def closing_loc + location = @closing_loc + case location + when nil + nil + when Location + location + else + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) unless @closing_loc.nil? + end + + # def opening: () -> String? + def opening + opening_loc&.slice + end + + # def closing: () -> String? + def closing + closing_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :interpolated_string_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :interpolated_string_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(InterpolatedStringNode) && + (flags === other.flags) && + (opening_loc.nil? == other.opening_loc.nil?) && + (parts.length == other.parts.length) && + parts.zip(other.parts).all? { |left, right| left === right } && + (closing_loc.nil? == other.closing_loc.nil?) + end + end + + # Represents a symbol literal that contains interpolation. + # + # :"foo #{bar} baz" + # ^^^^^^^^^^^^^^^^^ + class InterpolatedSymbolNode < Node + # Initialize a new InterpolatedSymbolNode node. + def initialize(source, node_id, location, flags, opening_loc, parts, closing_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @opening_loc = opening_loc + @parts = parts + @closing_loc = closing_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_interpolated_symbol_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [*parts] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [*parts] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*opening_loc, *parts, *closing_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location?, ?parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], ?closing_loc: Location?) -> InterpolatedSymbolNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, parts: self.parts, closing_loc: self.closing_loc) + InterpolatedSymbolNode.new(source, node_id, location, flags, opening_loc, parts, closing_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location?, parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], closing_loc: Location? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, opening_loc: opening_loc, parts: parts, closing_loc: closing_loc } + end + + # attr_reader opening_loc: Location? + def opening_loc + location = @opening_loc + case location + when nil + nil + when Location + location + else + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) unless @opening_loc.nil? + end + + # attr_reader parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode] + attr_reader :parts + + # attr_reader closing_loc: Location? + def closing_loc + location = @closing_loc + case location + when nil + nil + when Location + location + else + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) unless @closing_loc.nil? + end + + # def opening: () -> String? + def opening + opening_loc&.slice + end + + # def closing: () -> String? + def closing + closing_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :interpolated_symbol_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :interpolated_symbol_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(InterpolatedSymbolNode) && + (opening_loc.nil? == other.opening_loc.nil?) && + (parts.length == other.parts.length) && + parts.zip(other.parts).all? { |left, right| left === right } && + (closing_loc.nil? == other.closing_loc.nil?) + end + end + + # Represents an xstring literal that contains interpolation. + # + # `foo #{bar} baz` + # ^^^^^^^^^^^^^^^^ + class InterpolatedXStringNode < Node + # Initialize a new InterpolatedXStringNode node. + def initialize(source, node_id, location, flags, opening_loc, parts, closing_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @opening_loc = opening_loc + @parts = parts + @closing_loc = closing_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_interpolated_x_string_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [*parts] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [*parts] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [opening_loc, *parts, closing_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], ?closing_loc: Location) -> InterpolatedXStringNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, parts: self.parts, closing_loc: self.closing_loc) + InterpolatedXStringNode.new(source, node_id, location, flags, opening_loc, parts, closing_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location, parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], closing_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, opening_loc: opening_loc, parts: parts, closing_loc: closing_loc } + end + + # attr_reader opening_loc: Location + def opening_loc + location = @opening_loc + return location if location.is_a?(Location) + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) + end + + # attr_reader parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode] + attr_reader :parts + + # attr_reader closing_loc: Location + def closing_loc + location = @closing_loc + return location if location.is_a?(Location) + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) + end + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :interpolated_x_string_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :interpolated_x_string_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(InterpolatedXStringNode) && + (opening_loc.nil? == other.opening_loc.nil?) && + (parts.length == other.parts.length) && + parts.zip(other.parts).all? { |left, right| left === right } && + (closing_loc.nil? == other.closing_loc.nil?) + end + end + + # Represents reading from the implicit `it` local variable. + # + # -> { it } + # ^^ + class ItLocalVariableReadNode < Node + # Initialize a new ItLocalVariableReadNode node. + def initialize(source, node_id, location, flags) + @source = source + @node_id = node_id + @location = location + @flags = flags + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_it_local_variable_read_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> ItLocalVariableReadNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags) + ItLocalVariableReadNode.new(source, node_id, location, flags) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location } + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :it_local_variable_read_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :it_local_variable_read_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ItLocalVariableReadNode) + end + end + + # Represents an implicit set of parameters through the use of the `it` keyword within a block or lambda. + # + # -> { it + it } + # ^^^^^^^^^^^^^^ + class ItParametersNode < Node + # Initialize a new ItParametersNode node. + def initialize(source, node_id, location, flags) + @source = source + @node_id = node_id + @location = location + @flags = flags + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_it_parameters_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> ItParametersNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags) + ItParametersNode.new(source, node_id, location, flags) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location } + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :it_parameters_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :it_parameters_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ItParametersNode) + end + end + + # Represents a hash literal without opening and closing braces. + # + # foo(a: b) + # ^^^^ + class KeywordHashNode < Node + # Initialize a new KeywordHashNode node. + def initialize(source, node_id, location, flags, elements) + @source = source + @node_id = node_id + @location = location + @flags = flags + @elements = elements + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_keyword_hash_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [*elements] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [*elements] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*elements] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?elements: Array[AssocNode | AssocSplatNode]) -> KeywordHashNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, elements: self.elements) + KeywordHashNode.new(source, node_id, location, flags, elements) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, elements: Array[AssocNode | AssocSplatNode] } + def deconstruct_keys(keys) + { node_id: node_id, location: location, elements: elements } + end + + # def symbol_keys?: () -> bool + def symbol_keys? + flags.anybits?(KeywordHashNodeFlags::SYMBOL_KEYS) + end + + # attr_reader elements: Array[AssocNode | AssocSplatNode] + attr_reader :elements + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :keyword_hash_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :keyword_hash_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(KeywordHashNode) && + (flags === other.flags) && + (elements.length == other.elements.length) && + elements.zip(other.elements).all? { |left, right| left === right } + end + end + + # Represents a keyword rest parameter to a method, block, or lambda definition. + # + # def a(**b) + # ^^^ + # end + class KeywordRestParameterNode < Node + # Initialize a new KeywordRestParameterNode node. + def initialize(source, node_id, location, flags, name, name_loc, operator_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @name_loc = name_loc + @operator_loc = operator_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_keyword_rest_parameter_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*name_loc, operator_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol?, ?name_loc: Location?, ?operator_loc: Location) -> KeywordRestParameterNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc) + KeywordRestParameterNode.new(source, node_id, location, flags, name, name_loc, operator_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol?, name_loc: Location?, operator_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, name_loc: name_loc, operator_loc: operator_loc } + end + + # def repeated_parameter?: () -> bool + def repeated_parameter? + flags.anybits?(ParameterFlags::REPEATED_PARAMETER) + end + + # attr_reader name: Symbol? + attr_reader :name + + # attr_reader name_loc: Location? + def name_loc + location = @name_loc + case location + when nil + nil + when Location + location + else + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) unless @name_loc.nil? + end + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :keyword_rest_parameter_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :keyword_rest_parameter_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(KeywordRestParameterNode) && + (flags === other.flags) && + (name === other.name) && + (name_loc.nil? == other.name_loc.nil?) && + (operator_loc.nil? == other.operator_loc.nil?) + end + end + + # Represents using a lambda literal (not the lambda method call). + # + # ->(value) { value * 2 } + # ^^^^^^^^^^^^^^^^^^^^^^^ + class LambdaNode < Node + # Initialize a new LambdaNode node. + def initialize(source, node_id, location, flags, locals, operator_loc, opening_loc, closing_loc, parameters, body) + @source = source + @node_id = node_id + @location = location + @flags = flags + @locals = locals + @operator_loc = operator_loc + @opening_loc = opening_loc + @closing_loc = closing_loc + @parameters = parameters + @body = body + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_lambda_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [parameters, body] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << parameters if parameters + compact << body if body + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [operator_loc, opening_loc, closing_loc, *parameters, *body] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?locals: Array[Symbol], ?operator_loc: Location, ?opening_loc: Location, ?closing_loc: Location, ?parameters: BlockParametersNode | NumberedParametersNode | ItParametersNode | nil, ?body: StatementsNode | BeginNode | nil) -> LambdaNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, locals: self.locals, operator_loc: self.operator_loc, opening_loc: self.opening_loc, closing_loc: self.closing_loc, parameters: self.parameters, body: self.body) + LambdaNode.new(source, node_id, location, flags, locals, operator_loc, opening_loc, closing_loc, parameters, body) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, locals: Array[Symbol], operator_loc: Location, opening_loc: Location, closing_loc: Location, parameters: BlockParametersNode | NumberedParametersNode | ItParametersNode | nil, body: StatementsNode | BeginNode | nil } + def deconstruct_keys(keys) + { node_id: node_id, location: location, locals: locals, operator_loc: operator_loc, opening_loc: opening_loc, closing_loc: closing_loc, parameters: parameters, body: body } + end + + # attr_reader locals: Array[Symbol] + attr_reader :locals + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # attr_reader opening_loc: Location + def opening_loc + location = @opening_loc + return location if location.is_a?(Location) + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) + end + + # attr_reader closing_loc: Location + def closing_loc + location = @closing_loc + return location if location.is_a?(Location) + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) + end + + # attr_reader parameters: BlockParametersNode | NumberedParametersNode | ItParametersNode | nil + attr_reader :parameters + + # attr_reader body: StatementsNode | BeginNode | nil + attr_reader :body + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :lambda_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :lambda_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(LambdaNode) && + (locals.length == other.locals.length) && + locals.zip(other.locals).all? { |left, right| left === right } && + (operator_loc.nil? == other.operator_loc.nil?) && + (opening_loc.nil? == other.opening_loc.nil?) && + (closing_loc.nil? == other.closing_loc.nil?) && + (parameters === other.parameters) && + (body === other.body) + end + end + + # Represents the use of the `&&=` operator for assignment to a local variable. + # + # target &&= value + # ^^^^^^^^^^^^^^^^ + class LocalVariableAndWriteNode < Node + # Initialize a new LocalVariableAndWriteNode node. + def initialize(source, node_id, location, flags, name_loc, operator_loc, value, name, depth) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name_loc = name_loc + @operator_loc = operator_loc + @value = value + @name = name + @depth = depth + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_local_variable_and_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [name_loc, operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node, ?name: Symbol, ?depth: Integer) -> LocalVariableAndWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value, name: self.name, depth: self.depth) + LocalVariableAndWriteNode.new(source, node_id, location, flags, name_loc, operator_loc, value, name, depth) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name_loc: Location, operator_loc: Location, value: Prism::node, name: Symbol, depth: Integer } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name_loc: name_loc, operator_loc: operator_loc, value: value, name: name, depth: depth } + end + + # attr_reader name_loc: Location + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # attr_reader value: Prism::node + attr_reader :value + + # attr_reader name: Symbol + attr_reader :name + + # attr_reader depth: Integer + attr_reader :depth + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :local_variable_and_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :local_variable_and_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(LocalVariableAndWriteNode) && + (name_loc.nil? == other.name_loc.nil?) && + (operator_loc.nil? == other.operator_loc.nil?) && + (value === other.value) && + (name === other.name) && + (depth === other.depth) + end + end + + # Represents assigning to a local variable using an operator that isn't `=`. + # + # target += value + # ^^^^^^^^^^^^^^^ + class LocalVariableOperatorWriteNode < Node + # Initialize a new LocalVariableOperatorWriteNode node. + def initialize(source, node_id, location, flags, name_loc, binary_operator_loc, value, name, binary_operator, depth) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name_loc = name_loc + @binary_operator_loc = binary_operator_loc + @value = value + @name = name + @binary_operator = binary_operator + @depth = depth + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_local_variable_operator_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [name_loc, binary_operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name_loc: Location, ?binary_operator_loc: Location, ?value: Prism::node, ?name: Symbol, ?binary_operator: Symbol, ?depth: Integer) -> LocalVariableOperatorWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name_loc: self.name_loc, binary_operator_loc: self.binary_operator_loc, value: self.value, name: self.name, binary_operator: self.binary_operator, depth: self.depth) + LocalVariableOperatorWriteNode.new(source, node_id, location, flags, name_loc, binary_operator_loc, value, name, binary_operator, depth) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name_loc: Location, binary_operator_loc: Location, value: Prism::node, name: Symbol, binary_operator: Symbol, depth: Integer } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name_loc: name_loc, binary_operator_loc: binary_operator_loc, value: value, name: name, binary_operator: binary_operator, depth: depth } + end + + # attr_reader name_loc: Location + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # attr_reader binary_operator_loc: Location + def binary_operator_loc + location = @binary_operator_loc + return location if location.is_a?(Location) + @binary_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the binary_operator_loc location using the given saved source so that + # it can be retrieved later. + def save_binary_operator_loc(repository) + repository.enter(node_id, :binary_operator_loc) + end + + # attr_reader value: Prism::node + attr_reader :value + + # attr_reader name: Symbol + attr_reader :name + + # attr_reader binary_operator: Symbol + attr_reader :binary_operator + + # attr_reader depth: Integer + attr_reader :depth + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :local_variable_operator_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :local_variable_operator_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(LocalVariableOperatorWriteNode) && + (name_loc.nil? == other.name_loc.nil?) && + (binary_operator_loc.nil? == other.binary_operator_loc.nil?) && + (value === other.value) && + (name === other.name) && + (binary_operator === other.binary_operator) && + (depth === other.depth) + end + end + + # Represents the use of the `||=` operator for assignment to a local variable. + # + # target ||= value + # ^^^^^^^^^^^^^^^^ + class LocalVariableOrWriteNode < Node + # Initialize a new LocalVariableOrWriteNode node. + def initialize(source, node_id, location, flags, name_loc, operator_loc, value, name, depth) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name_loc = name_loc + @operator_loc = operator_loc + @value = value + @name = name + @depth = depth + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_local_variable_or_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [name_loc, operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node, ?name: Symbol, ?depth: Integer) -> LocalVariableOrWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value, name: self.name, depth: self.depth) + LocalVariableOrWriteNode.new(source, node_id, location, flags, name_loc, operator_loc, value, name, depth) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name_loc: Location, operator_loc: Location, value: Prism::node, name: Symbol, depth: Integer } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name_loc: name_loc, operator_loc: operator_loc, value: value, name: name, depth: depth } + end + + # attr_reader name_loc: Location + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # attr_reader value: Prism::node + attr_reader :value + + # attr_reader name: Symbol + attr_reader :name + + # attr_reader depth: Integer + attr_reader :depth + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :local_variable_or_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :local_variable_or_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(LocalVariableOrWriteNode) && + (name_loc.nil? == other.name_loc.nil?) && + (operator_loc.nil? == other.operator_loc.nil?) && + (value === other.value) && + (name === other.name) && + (depth === other.depth) + end + end + + # Represents reading a local variable. Note that this requires that a local variable of the same name has already been written to in the same scope, otherwise it is parsed as a method call. + # + # foo + # ^^^ + class LocalVariableReadNode < Node + # Initialize a new LocalVariableReadNode node. + def initialize(source, node_id, location, flags, name, depth) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @depth = depth + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_local_variable_read_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?depth: Integer) -> LocalVariableReadNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, depth: self.depth) + LocalVariableReadNode.new(source, node_id, location, flags, name, depth) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, depth: Integer } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, depth: depth } + end + + # The name of the local variable, which is an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). + # + # x # name `:x` + # + # _Test # name `:_Test` + # + # Note that this can also be an underscore followed by a number for the default block parameters. + # + # _1 # name `:_1` + attr_reader :name + + # The number of visible scopes that should be searched to find the origin of this local variable. + # + # foo = 1; foo # depth 0 + # + # bar = 2; tap { bar } # depth 1 + # + # The specific rules for calculating the depth may differ from individual Ruby implementations, as they are not specified by the language. For more information, see [the Prism documentation](https://github.com/ruby/prism/blob/main/docs/local_variable_depth.md). + attr_reader :depth + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :local_variable_read_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :local_variable_read_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(LocalVariableReadNode) && + (name === other.name) && + (depth === other.depth) + end + end + + # Represents writing to a local variable in a context that doesn't have an explicit value. + # + # foo, bar = baz + # ^^^ ^^^ + class LocalVariableTargetNode < Node + # Initialize a new LocalVariableTargetNode node. + def initialize(source, node_id, location, flags, name, depth) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @depth = depth + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_local_variable_target_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?depth: Integer) -> LocalVariableTargetNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, depth: self.depth) + LocalVariableTargetNode.new(source, node_id, location, flags, name, depth) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, depth: Integer } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, depth: depth } + end + + # attr_reader name: Symbol + attr_reader :name + + # attr_reader depth: Integer + attr_reader :depth + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :local_variable_target_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :local_variable_target_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(LocalVariableTargetNode) && + (name === other.name) && + (depth === other.depth) + end + end + + # Represents writing to a local variable. + # + # foo = 1 + # ^^^^^^^ + class LocalVariableWriteNode < Node + # Initialize a new LocalVariableWriteNode node. + def initialize(source, node_id, location, flags, name, depth, name_loc, value, operator_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @depth = depth + @name_loc = name_loc + @value = value + @operator_loc = operator_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_local_variable_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [name_loc, value, operator_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?depth: Integer, ?name_loc: Location, ?value: Prism::node, ?operator_loc: Location) -> LocalVariableWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, depth: self.depth, name_loc: self.name_loc, value: self.value, operator_loc: self.operator_loc) + LocalVariableWriteNode.new(source, node_id, location, flags, name, depth, name_loc, value, operator_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, depth: Integer, name_loc: Location, value: Prism::node, operator_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, depth: depth, name_loc: name_loc, value: value, operator_loc: operator_loc } + end + + # The name of the local variable, which is an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). + # + # foo = :bar # name `:foo` + # + # abc = 123 # name `:abc` + attr_reader :name + + # The number of semantic scopes we have to traverse to find the declaration of this variable. + # + # foo = 1 # depth 0 + # + # tap { foo = 1 } # depth 1 + # + # The specific rules for calculating the depth may differ from individual Ruby implementations, as they are not specified by the language. For more information, see [the Prism documentation](https://github.com/ruby/prism/blob/main/docs/local_variable_depth.md). + attr_reader :depth + + # The location of the variable name. + # + # foo = :bar + # ^^^ + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # The value to write to the local variable. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # foo = :bar + # ^^^^ + # + # abc = 1234 + # ^^^^ + # + # Note that since the name of a local variable is known before the value is parsed, it is valid for a local variable to appear within the value of its own write. + # + # foo = foo + attr_reader :value + + # The location of the `=` operator. + # + # x = :y + # ^ + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :local_variable_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :local_variable_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(LocalVariableWriteNode) && + (name === other.name) && + (depth === other.depth) && + (name_loc.nil? == other.name_loc.nil?) && + (value === other.value) && + (operator_loc.nil? == other.operator_loc.nil?) + end + end + + # Represents a regular expression literal used in the predicate of a conditional to implicitly match against the last line read by an IO object. + # + # if /foo/i then end + # ^^^^^^ + class MatchLastLineNode < Node + # Initialize a new MatchLastLineNode node. + def initialize(source, node_id, location, flags, opening_loc, content_loc, closing_loc, unescaped) + @source = source + @node_id = node_id + @location = location + @flags = flags + @opening_loc = opening_loc + @content_loc = content_loc + @closing_loc = closing_loc + @unescaped = unescaped + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_match_last_line_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [opening_loc, content_loc, closing_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?content_loc: Location, ?closing_loc: Location, ?unescaped: String) -> MatchLastLineNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, content_loc: self.content_loc, closing_loc: self.closing_loc, unescaped: self.unescaped) + MatchLastLineNode.new(source, node_id, location, flags, opening_loc, content_loc, closing_loc, unescaped) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location, content_loc: Location, closing_loc: Location, unescaped: String } + def deconstruct_keys(keys) + { node_id: node_id, location: location, opening_loc: opening_loc, content_loc: content_loc, closing_loc: closing_loc, unescaped: unescaped } + end + + # def ignore_case?: () -> bool + def ignore_case? + flags.anybits?(RegularExpressionFlags::IGNORE_CASE) + end + + # def extended?: () -> bool + def extended? + flags.anybits?(RegularExpressionFlags::EXTENDED) + end + + # def multi_line?: () -> bool + def multi_line? + flags.anybits?(RegularExpressionFlags::MULTI_LINE) + end + + # def once?: () -> bool + def once? + flags.anybits?(RegularExpressionFlags::ONCE) + end + + # def euc_jp?: () -> bool + def euc_jp? + flags.anybits?(RegularExpressionFlags::EUC_JP) + end + + # def ascii_8bit?: () -> bool + def ascii_8bit? + flags.anybits?(RegularExpressionFlags::ASCII_8BIT) + end + + # def windows_31j?: () -> bool + def windows_31j? + flags.anybits?(RegularExpressionFlags::WINDOWS_31J) + end + + # def utf_8?: () -> bool + def utf_8? + flags.anybits?(RegularExpressionFlags::UTF_8) + end + + # def forced_utf8_encoding?: () -> bool + def forced_utf8_encoding? + flags.anybits?(RegularExpressionFlags::FORCED_UTF8_ENCODING) + end + + # def forced_binary_encoding?: () -> bool + def forced_binary_encoding? + flags.anybits?(RegularExpressionFlags::FORCED_BINARY_ENCODING) + end + + # def forced_us_ascii_encoding?: () -> bool + def forced_us_ascii_encoding? + flags.anybits?(RegularExpressionFlags::FORCED_US_ASCII_ENCODING) + end + + # attr_reader opening_loc: Location + def opening_loc + location = @opening_loc + return location if location.is_a?(Location) + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) + end + + # attr_reader content_loc: Location + def content_loc + location = @content_loc + return location if location.is_a?(Location) + @content_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the content_loc location using the given saved source so that + # it can be retrieved later. + def save_content_loc(repository) + repository.enter(node_id, :content_loc) + end + + # attr_reader closing_loc: Location + def closing_loc + location = @closing_loc + return location if location.is_a?(Location) + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) + end + + # attr_reader unescaped: String + attr_reader :unescaped + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def content: () -> String + def content + content_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :match_last_line_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :match_last_line_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(MatchLastLineNode) && + (flags === other.flags) && + (opening_loc.nil? == other.opening_loc.nil?) && + (content_loc.nil? == other.content_loc.nil?) && + (closing_loc.nil? == other.closing_loc.nil?) && + (unescaped === other.unescaped) + end + end + + # Represents the use of the modifier `in` operator. + # + # foo in bar + # ^^^^^^^^^^ + class MatchPredicateNode < Node + # Initialize a new MatchPredicateNode node. + def initialize(source, node_id, location, flags, value, pattern, operator_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @value = value + @pattern = pattern + @operator_loc = operator_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_match_predicate_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value, pattern] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value, pattern] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [value, pattern, operator_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?value: Prism::node, ?pattern: Prism::node, ?operator_loc: Location) -> MatchPredicateNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, value: self.value, pattern: self.pattern, operator_loc: self.operator_loc) + MatchPredicateNode.new(source, node_id, location, flags, value, pattern, operator_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, value: Prism::node, pattern: Prism::node, operator_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, value: value, pattern: pattern, operator_loc: operator_loc } + end + + # attr_reader value: Prism::node + attr_reader :value + + # attr_reader pattern: Prism::node + attr_reader :pattern + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :match_predicate_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :match_predicate_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(MatchPredicateNode) && + (value === other.value) && + (pattern === other.pattern) && + (operator_loc.nil? == other.operator_loc.nil?) + end + end + + # Represents the use of the `=>` operator. + # + # foo => bar + # ^^^^^^^^^^ + class MatchRequiredNode < Node + # Initialize a new MatchRequiredNode node. + def initialize(source, node_id, location, flags, value, pattern, operator_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @value = value + @pattern = pattern + @operator_loc = operator_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_match_required_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value, pattern] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value, pattern] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [value, pattern, operator_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?value: Prism::node, ?pattern: Prism::node, ?operator_loc: Location) -> MatchRequiredNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, value: self.value, pattern: self.pattern, operator_loc: self.operator_loc) + MatchRequiredNode.new(source, node_id, location, flags, value, pattern, operator_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, value: Prism::node, pattern: Prism::node, operator_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, value: value, pattern: pattern, operator_loc: operator_loc } + end + + # attr_reader value: Prism::node + attr_reader :value + + # attr_reader pattern: Prism::node + attr_reader :pattern + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :match_required_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :match_required_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(MatchRequiredNode) && + (value === other.value) && + (pattern === other.pattern) && + (operator_loc.nil? == other.operator_loc.nil?) + end + end + + # Represents writing local variables using a regular expression match with named capture groups. + # + # /(?bar)/ =~ baz + # ^^^^^^^^^^^^^^^^^^^^ + class MatchWriteNode < Node + # Initialize a new MatchWriteNode node. + def initialize(source, node_id, location, flags, call, targets) + @source = source + @node_id = node_id + @location = location + @flags = flags + @call = call + @targets = targets + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_match_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [call, *targets] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [call, *targets] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [call, *targets] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?call: CallNode, ?targets: Array[LocalVariableTargetNode]) -> MatchWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, call: self.call, targets: self.targets) + MatchWriteNode.new(source, node_id, location, flags, call, targets) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, call: CallNode, targets: Array[LocalVariableTargetNode] } + def deconstruct_keys(keys) + { node_id: node_id, location: location, call: call, targets: targets } + end + + # attr_reader call: CallNode + attr_reader :call + + # attr_reader targets: Array[LocalVariableTargetNode] + attr_reader :targets + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :match_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :match_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(MatchWriteNode) && + (call === other.call) && + (targets.length == other.targets.length) && + targets.zip(other.targets).all? { |left, right| left === right } + end + end + + # Represents a node that is missing from the source and results in a syntax error. + class MissingNode < Node + # Initialize a new MissingNode node. + def initialize(source, node_id, location, flags) + @source = source + @node_id = node_id + @location = location + @flags = flags + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_missing_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> MissingNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags) + MissingNode.new(source, node_id, location, flags) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location } + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :missing_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :missing_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(MissingNode) + end + end + + # Represents a module declaration involving the `module` keyword. + # + # module Foo end + # ^^^^^^^^^^^^^^ + class ModuleNode < Node + # Initialize a new ModuleNode node. + def initialize(source, node_id, location, flags, locals, module_keyword_loc, constant_path, body, end_keyword_loc, name) + @source = source + @node_id = node_id + @location = location + @flags = flags + @locals = locals + @module_keyword_loc = module_keyword_loc + @constant_path = constant_path + @body = body + @end_keyword_loc = end_keyword_loc + @name = name + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_module_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [constant_path, body] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << constant_path + compact << body if body + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [module_keyword_loc, constant_path, *body, end_keyword_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?locals: Array[Symbol], ?module_keyword_loc: Location, ?constant_path: ConstantReadNode | ConstantPathNode | MissingNode, ?body: StatementsNode | BeginNode | nil, ?end_keyword_loc: Location, ?name: Symbol) -> ModuleNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, locals: self.locals, module_keyword_loc: self.module_keyword_loc, constant_path: self.constant_path, body: self.body, end_keyword_loc: self.end_keyword_loc, name: self.name) + ModuleNode.new(source, node_id, location, flags, locals, module_keyword_loc, constant_path, body, end_keyword_loc, name) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, locals: Array[Symbol], module_keyword_loc: Location, constant_path: ConstantReadNode | ConstantPathNode | MissingNode, body: StatementsNode | BeginNode | nil, end_keyword_loc: Location, name: Symbol } + def deconstruct_keys(keys) + { node_id: node_id, location: location, locals: locals, module_keyword_loc: module_keyword_loc, constant_path: constant_path, body: body, end_keyword_loc: end_keyword_loc, name: name } + end + + # attr_reader locals: Array[Symbol] + attr_reader :locals + + # attr_reader module_keyword_loc: Location + def module_keyword_loc + location = @module_keyword_loc + return location if location.is_a?(Location) + @module_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the module_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_module_keyword_loc(repository) + repository.enter(node_id, :module_keyword_loc) + end + + # attr_reader constant_path: ConstantReadNode | ConstantPathNode | MissingNode + attr_reader :constant_path + + # attr_reader body: StatementsNode | BeginNode | nil + attr_reader :body + + # attr_reader end_keyword_loc: Location + def end_keyword_loc + location = @end_keyword_loc + return location if location.is_a?(Location) + @end_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the end_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_end_keyword_loc(repository) + repository.enter(node_id, :end_keyword_loc) + end + + # attr_reader name: Symbol + attr_reader :name + + # def module_keyword: () -> String + def module_keyword + module_keyword_loc.slice + end + + # def end_keyword: () -> String + def end_keyword + end_keyword_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :module_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :module_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ModuleNode) && + (locals.length == other.locals.length) && + locals.zip(other.locals).all? { |left, right| left === right } && + (module_keyword_loc.nil? == other.module_keyword_loc.nil?) && + (constant_path === other.constant_path) && + (body === other.body) && + (end_keyword_loc.nil? == other.end_keyword_loc.nil?) && + (name === other.name) + end + end + + # Represents a multi-target expression. + # + # a, (b, c) = 1, 2, 3 + # ^^^^^^ + # + # This can be a part of `MultiWriteNode` as above, or the target of a `for` loop + # + # for a, b in [[1, 2], [3, 4]] + # ^^^^ + class MultiTargetNode < Node + # Initialize a new MultiTargetNode node. + def initialize(source, node_id, location, flags, lefts, rest, rights, lparen_loc, rparen_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @lefts = lefts + @rest = rest + @rights = rights + @lparen_loc = lparen_loc + @rparen_loc = rparen_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_multi_target_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [*lefts, rest, *rights] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact.concat(lefts) + compact << rest if rest + compact.concat(rights) + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*lefts, *rest, *rights, *lparen_loc, *rparen_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?lefts: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | RequiredParameterNode | BackReferenceReadNode | NumberedReferenceReadNode], ?rest: ImplicitRestNode | SplatNode | nil, ?rights: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | RequiredParameterNode | BackReferenceReadNode | NumberedReferenceReadNode], ?lparen_loc: Location?, ?rparen_loc: Location?) -> MultiTargetNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, lefts: self.lefts, rest: self.rest, rights: self.rights, lparen_loc: self.lparen_loc, rparen_loc: self.rparen_loc) + MultiTargetNode.new(source, node_id, location, flags, lefts, rest, rights, lparen_loc, rparen_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, lefts: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | RequiredParameterNode | BackReferenceReadNode | NumberedReferenceReadNode], rest: ImplicitRestNode | SplatNode | nil, rights: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | RequiredParameterNode | BackReferenceReadNode | NumberedReferenceReadNode], lparen_loc: Location?, rparen_loc: Location? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, lefts: lefts, rest: rest, rights: rights, lparen_loc: lparen_loc, rparen_loc: rparen_loc } + end + + # Represents the targets expressions before a splat node. + # + # a, (b, c, *) = 1, 2, 3, 4, 5 + # ^^^^ + # + # The splat node can be absent, in that case all target expressions are in the left field. + # + # a, (b, c) = 1, 2, 3, 4, 5 + # ^^^^ + attr_reader :lefts + + # Represents a splat node in the target expression. + # + # a, (b, *c) = 1, 2, 3, 4 + # ^^ + # + # The variable can be empty, this results in a `SplatNode` with a `nil` expression field. + # + # a, (b, *) = 1, 2, 3, 4 + # ^ + # + # If the `*` is omitted, this field will contain an `ImplicitRestNode` + # + # a, (b,) = 1, 2, 3, 4 + # ^ + attr_reader :rest + + # Represents the targets expressions after a splat node. + # + # a, (*, b, c) = 1, 2, 3, 4, 5 + # ^^^^ + attr_reader :rights + + # The location of the opening parenthesis. + # + # a, (b, c) = 1, 2, 3 + # ^ + def lparen_loc + location = @lparen_loc + case location + when nil + nil + when Location + location + else + @lparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the lparen_loc location using the given saved source so that + # it can be retrieved later. + def save_lparen_loc(repository) + repository.enter(node_id, :lparen_loc) unless @lparen_loc.nil? + end + + # The location of the closing parenthesis. + # + # a, (b, c) = 1, 2, 3 + # ^ + def rparen_loc + location = @rparen_loc + case location + when nil + nil + when Location + location + else + @rparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the rparen_loc location using the given saved source so that + # it can be retrieved later. + def save_rparen_loc(repository) + repository.enter(node_id, :rparen_loc) unless @rparen_loc.nil? + end + + # def lparen: () -> String? + def lparen + lparen_loc&.slice + end + + # def rparen: () -> String? + def rparen + rparen_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :multi_target_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :multi_target_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(MultiTargetNode) && + (lefts.length == other.lefts.length) && + lefts.zip(other.lefts).all? { |left, right| left === right } && + (rest === other.rest) && + (rights.length == other.rights.length) && + rights.zip(other.rights).all? { |left, right| left === right } && + (lparen_loc.nil? == other.lparen_loc.nil?) && + (rparen_loc.nil? == other.rparen_loc.nil?) + end + end + + # Represents a write to a multi-target expression. + # + # a, b, c = 1, 2, 3 + # ^^^^^^^^^^^^^^^^^ + class MultiWriteNode < Node + # Initialize a new MultiWriteNode node. + def initialize(source, node_id, location, flags, lefts, rest, rights, lparen_loc, rparen_loc, operator_loc, value) + @source = source + @node_id = node_id + @location = location + @flags = flags + @lefts = lefts + @rest = rest + @rights = rights + @lparen_loc = lparen_loc + @rparen_loc = rparen_loc + @operator_loc = operator_loc + @value = value + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_multi_write_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [*lefts, rest, *rights, value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact.concat(lefts) + compact << rest if rest + compact.concat(rights) + compact << value + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*lefts, *rest, *rights, *lparen_loc, *rparen_loc, operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?lefts: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode], ?rest: ImplicitRestNode | SplatNode | nil, ?rights: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode], ?lparen_loc: Location?, ?rparen_loc: Location?, ?operator_loc: Location, ?value: Prism::node) -> MultiWriteNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, lefts: self.lefts, rest: self.rest, rights: self.rights, lparen_loc: self.lparen_loc, rparen_loc: self.rparen_loc, operator_loc: self.operator_loc, value: self.value) + MultiWriteNode.new(source, node_id, location, flags, lefts, rest, rights, lparen_loc, rparen_loc, operator_loc, value) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, lefts: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode], rest: ImplicitRestNode | SplatNode | nil, rights: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode], lparen_loc: Location?, rparen_loc: Location?, operator_loc: Location, value: Prism::node } + def deconstruct_keys(keys) + { node_id: node_id, location: location, lefts: lefts, rest: rest, rights: rights, lparen_loc: lparen_loc, rparen_loc: rparen_loc, operator_loc: operator_loc, value: value } + end + + # Represents the targets expressions before a splat node. + # + # a, b, * = 1, 2, 3, 4, 5 + # ^^^^ + # + # The splat node can be absent, in that case all target expressions are in the left field. + # + # a, b, c = 1, 2, 3, 4, 5 + # ^^^^^^^ + attr_reader :lefts + + # Represents a splat node in the target expression. + # + # a, b, *c = 1, 2, 3, 4 + # ^^ + # + # The variable can be empty, this results in a `SplatNode` with a `nil` expression field. + # + # a, b, * = 1, 2, 3, 4 + # ^ + # + # If the `*` is omitted, this field will contain an `ImplicitRestNode` + # + # a, b, = 1, 2, 3, 4 + # ^ + attr_reader :rest + + # Represents the targets expressions after a splat node. + # + # a, *, b, c = 1, 2, 3, 4, 5 + # ^^^^ + attr_reader :rights + + # The location of the opening parenthesis. + # + # (a, b, c) = 1, 2, 3 + # ^ + def lparen_loc + location = @lparen_loc + case location + when nil + nil + when Location + location + else + @lparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the lparen_loc location using the given saved source so that + # it can be retrieved later. + def save_lparen_loc(repository) + repository.enter(node_id, :lparen_loc) unless @lparen_loc.nil? + end + + # The location of the closing parenthesis. + # + # (a, b, c) = 1, 2, 3 + # ^ + def rparen_loc + location = @rparen_loc + case location + when nil + nil + when Location + location + else + @rparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the rparen_loc location using the given saved source so that + # it can be retrieved later. + def save_rparen_loc(repository) + repository.enter(node_id, :rparen_loc) unless @rparen_loc.nil? + end + + # The location of the operator. + # + # a, b, c = 1, 2, 3 + # ^ + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # The value to write to the targets. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # a, b, c = 1, 2, 3 + # ^^^^^^^ + attr_reader :value + + # def lparen: () -> String? + def lparen + lparen_loc&.slice + end + + # def rparen: () -> String? + def rparen + rparen_loc&.slice + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :multi_write_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :multi_write_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(MultiWriteNode) && + (lefts.length == other.lefts.length) && + lefts.zip(other.lefts).all? { |left, right| left === right } && + (rest === other.rest) && + (rights.length == other.rights.length) && + rights.zip(other.rights).all? { |left, right| left === right } && + (lparen_loc.nil? == other.lparen_loc.nil?) && + (rparen_loc.nil? == other.rparen_loc.nil?) && + (operator_loc.nil? == other.operator_loc.nil?) && + (value === other.value) + end + end + + # Represents the use of the `next` keyword. + # + # next 1 + # ^^^^^^ + class NextNode < Node + # Initialize a new NextNode node. + def initialize(source, node_id, location, flags, arguments, keyword_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @arguments = arguments + @keyword_loc = keyword_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_next_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [arguments] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << arguments if arguments + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*arguments, keyword_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?arguments: ArgumentsNode?, ?keyword_loc: Location) -> NextNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, arguments: self.arguments, keyword_loc: self.keyword_loc) + NextNode.new(source, node_id, location, flags, arguments, keyword_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, arguments: ArgumentsNode?, keyword_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, arguments: arguments, keyword_loc: keyword_loc } + end + + # attr_reader arguments: ArgumentsNode? + attr_reader :arguments + + # attr_reader keyword_loc: Location + def keyword_loc + location = @keyword_loc + return location if location.is_a?(Location) + @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_keyword_loc(repository) + repository.enter(node_id, :keyword_loc) + end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :next_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :next_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(NextNode) && + (arguments === other.arguments) && + (keyword_loc.nil? == other.keyword_loc.nil?) + end + end + + # Represents the use of the `nil` keyword. + # + # nil + # ^^^ + class NilNode < Node + # Initialize a new NilNode node. + def initialize(source, node_id, location, flags) + @source = source + @node_id = node_id + @location = location + @flags = flags + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_nil_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> NilNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags) + NilNode.new(source, node_id, location, flags) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location } + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :nil_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :nil_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(NilNode) + end + end + + # Represents the use of `**nil` inside method arguments. + # + # def a(**nil) + # ^^^^^ + # end + class NoKeywordsParameterNode < Node + # Initialize a new NoKeywordsParameterNode node. + def initialize(source, node_id, location, flags, operator_loc, keyword_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @operator_loc = operator_loc + @keyword_loc = keyword_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_no_keywords_parameter_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [operator_loc, keyword_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?operator_loc: Location, ?keyword_loc: Location) -> NoKeywordsParameterNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, operator_loc: self.operator_loc, keyword_loc: self.keyword_loc) + NoKeywordsParameterNode.new(source, node_id, location, flags, operator_loc, keyword_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, operator_loc: Location, keyword_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, operator_loc: operator_loc, keyword_loc: keyword_loc } + end + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # attr_reader keyword_loc: Location + def keyword_loc + location = @keyword_loc + return location if location.is_a?(Location) + @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_keyword_loc(repository) + repository.enter(node_id, :keyword_loc) + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :no_keywords_parameter_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :no_keywords_parameter_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(NoKeywordsParameterNode) && + (operator_loc.nil? == other.operator_loc.nil?) && + (keyword_loc.nil? == other.keyword_loc.nil?) + end + end + + # Represents an implicit set of parameters through the use of numbered parameters within a block or lambda. + # + # -> { _1 + _2 } + # ^^^^^^^^^^^^^^ + class NumberedParametersNode < Node + # Initialize a new NumberedParametersNode node. + def initialize(source, node_id, location, flags, maximum) + @source = source + @node_id = node_id + @location = location + @flags = flags + @maximum = maximum + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_numbered_parameters_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?maximum: Integer) -> NumberedParametersNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, maximum: self.maximum) + NumberedParametersNode.new(source, node_id, location, flags, maximum) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, maximum: Integer } + def deconstruct_keys(keys) + { node_id: node_id, location: location, maximum: maximum } + end + + # attr_reader maximum: Integer + attr_reader :maximum + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :numbered_parameters_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :numbered_parameters_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(NumberedParametersNode) && + (maximum === other.maximum) + end + end + + # Represents reading a numbered reference to a capture in the previous match. + # + # $1 + # ^^ + class NumberedReferenceReadNode < Node + # Initialize a new NumberedReferenceReadNode node. + def initialize(source, node_id, location, flags, number) + @source = source + @node_id = node_id + @location = location + @flags = flags + @number = number + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_numbered_reference_read_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?number: Integer) -> NumberedReferenceReadNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, number: self.number) + NumberedReferenceReadNode.new(source, node_id, location, flags, number) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, number: Integer } + def deconstruct_keys(keys) + { node_id: node_id, location: location, number: number } + end + + # The (1-indexed, from the left) number of the capture group. Numbered references that are too large result in this value being `0`. + # + # $1 # number `1` + # + # $5432 # number `5432` + # + # $4294967296 # number `0` + attr_reader :number + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :numbered_reference_read_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :numbered_reference_read_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(NumberedReferenceReadNode) && + (number === other.number) + end + end + + # Represents an optional keyword parameter to a method, block, or lambda definition. + # + # def a(b: 1) + # ^^^^ + # end + class OptionalKeywordParameterNode < Node + # Initialize a new OptionalKeywordParameterNode node. + def initialize(source, node_id, location, flags, name, name_loc, value) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @name_loc = name_loc + @value = value + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_optional_keyword_parameter_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [name_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?value: Prism::node) -> OptionalKeywordParameterNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, value: self.value) + OptionalKeywordParameterNode.new(source, node_id, location, flags, name, name_loc, value) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, value: Prism::node } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, name_loc: name_loc, value: value } + end + + # def repeated_parameter?: () -> bool + def repeated_parameter? + flags.anybits?(ParameterFlags::REPEATED_PARAMETER) + end + + # attr_reader name: Symbol + attr_reader :name + + # attr_reader name_loc: Location + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # attr_reader value: Prism::node + attr_reader :value + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :optional_keyword_parameter_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :optional_keyword_parameter_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(OptionalKeywordParameterNode) && + (flags === other.flags) && + (name === other.name) && + (name_loc.nil? == other.name_loc.nil?) && + (value === other.value) + end + end + + # Represents an optional parameter to a method, block, or lambda definition. + # + # def a(b = 1) + # ^^^^^ + # end + class OptionalParameterNode < Node + # Initialize a new OptionalParameterNode node. + def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @name_loc = name_loc + @operator_loc = operator_loc + @value = value + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_optional_parameter_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [value] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [value] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [name_loc, operator_loc, value] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> OptionalParameterNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value) + OptionalParameterNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, name_loc: name_loc, operator_loc: operator_loc, value: value } + end + + # def repeated_parameter?: () -> bool + def repeated_parameter? + flags.anybits?(ParameterFlags::REPEATED_PARAMETER) + end + + # attr_reader name: Symbol + attr_reader :name + + # attr_reader name_loc: Location + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # attr_reader value: Prism::node + attr_reader :value + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :optional_parameter_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :optional_parameter_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(OptionalParameterNode) && + (flags === other.flags) && + (name === other.name) && + (name_loc.nil? == other.name_loc.nil?) && + (operator_loc.nil? == other.operator_loc.nil?) && + (value === other.value) + end + end + + # Represents the use of the `||` operator or the `or` keyword. + # + # left or right + # ^^^^^^^^^^^^^ + class OrNode < Node + # Initialize a new OrNode node. + def initialize(source, node_id, location, flags, left, right, operator_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @left = left + @right = right + @operator_loc = operator_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_or_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [left, right] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [left, right] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [left, right, operator_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?left: Prism::node, ?right: Prism::node, ?operator_loc: Location) -> OrNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, left: self.left, right: self.right, operator_loc: self.operator_loc) + OrNode.new(source, node_id, location, flags, left, right, operator_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, left: Prism::node, right: Prism::node, operator_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, left: left, right: right, operator_loc: operator_loc } + end + + # Represents the left side of the expression. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # left or right + # ^^^^ + # + # 1 || 2 + # ^ + attr_reader :left + + # Represents the right side of the expression. + # + # left || right + # ^^^^^ + # + # 1 or 2 + # ^ + attr_reader :right + + # The location of the `or` keyword or the `||` operator. + # + # left or right + # ^^ + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :or_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :or_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(OrNode) && + (left === other.left) && + (right === other.right) && + (operator_loc.nil? == other.operator_loc.nil?) + end + end + + # Represents the list of parameters on a method, block, or lambda definition. + # + # def a(b, c, d) + # ^^^^^^^ + # end + class ParametersNode < Node + # Initialize a new ParametersNode node. + def initialize(source, node_id, location, flags, requireds, optionals, rest, posts, keywords, keyword_rest, block) + @source = source + @node_id = node_id + @location = location + @flags = flags + @requireds = requireds + @optionals = optionals + @rest = rest + @posts = posts + @keywords = keywords + @keyword_rest = keyword_rest + @block = block + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_parameters_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [*requireds, *optionals, rest, *posts, *keywords, keyword_rest, block] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact.concat(requireds) + compact.concat(optionals) + compact << rest if rest + compact.concat(posts) + compact.concat(keywords) + compact << keyword_rest if keyword_rest + compact << block if block + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*requireds, *optionals, *rest, *posts, *keywords, *keyword_rest, *block] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?requireds: Array[RequiredParameterNode | MultiTargetNode], ?optionals: Array[OptionalParameterNode], ?rest: RestParameterNode | ImplicitRestNode | nil, ?posts: Array[RequiredParameterNode | MultiTargetNode | KeywordRestParameterNode | NoKeywordsParameterNode | ForwardingParameterNode], ?keywords: Array[RequiredKeywordParameterNode | OptionalKeywordParameterNode], ?keyword_rest: KeywordRestParameterNode | ForwardingParameterNode | NoKeywordsParameterNode | nil, ?block: BlockParameterNode?) -> ParametersNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, requireds: self.requireds, optionals: self.optionals, rest: self.rest, posts: self.posts, keywords: self.keywords, keyword_rest: self.keyword_rest, block: self.block) + ParametersNode.new(source, node_id, location, flags, requireds, optionals, rest, posts, keywords, keyword_rest, block) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, requireds: Array[RequiredParameterNode | MultiTargetNode], optionals: Array[OptionalParameterNode], rest: RestParameterNode | ImplicitRestNode | nil, posts: Array[RequiredParameterNode | MultiTargetNode | KeywordRestParameterNode | NoKeywordsParameterNode | ForwardingParameterNode], keywords: Array[RequiredKeywordParameterNode | OptionalKeywordParameterNode], keyword_rest: KeywordRestParameterNode | ForwardingParameterNode | NoKeywordsParameterNode | nil, block: BlockParameterNode? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, requireds: requireds, optionals: optionals, rest: rest, posts: posts, keywords: keywords, keyword_rest: keyword_rest, block: block } + end + + # attr_reader requireds: Array[RequiredParameterNode | MultiTargetNode] + attr_reader :requireds + + # attr_reader optionals: Array[OptionalParameterNode] + attr_reader :optionals + + # attr_reader rest: RestParameterNode | ImplicitRestNode | nil + attr_reader :rest + + # attr_reader posts: Array[RequiredParameterNode | MultiTargetNode | KeywordRestParameterNode | NoKeywordsParameterNode | ForwardingParameterNode] + attr_reader :posts + + # attr_reader keywords: Array[RequiredKeywordParameterNode | OptionalKeywordParameterNode] + attr_reader :keywords + + # attr_reader keyword_rest: KeywordRestParameterNode | ForwardingParameterNode | NoKeywordsParameterNode | nil + attr_reader :keyword_rest + + # attr_reader block: BlockParameterNode? + attr_reader :block + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :parameters_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :parameters_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ParametersNode) && + (requireds.length == other.requireds.length) && + requireds.zip(other.requireds).all? { |left, right| left === right } && + (optionals.length == other.optionals.length) && + optionals.zip(other.optionals).all? { |left, right| left === right } && + (rest === other.rest) && + (posts.length == other.posts.length) && + posts.zip(other.posts).all? { |left, right| left === right } && + (keywords.length == other.keywords.length) && + keywords.zip(other.keywords).all? { |left, right| left === right } && + (keyword_rest === other.keyword_rest) && + (block === other.block) + end + end + + # Represents a parenthesized expression + # + # (10 + 34) + # ^^^^^^^^^ + class ParenthesesNode < Node + # Initialize a new ParenthesesNode node. + def initialize(source, node_id, location, flags, body, opening_loc, closing_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @body = body + @opening_loc = opening_loc + @closing_loc = closing_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_parentheses_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [body] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << body if body + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*body, opening_loc, closing_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?body: Prism::node?, ?opening_loc: Location, ?closing_loc: Location) -> ParenthesesNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, body: self.body, opening_loc: self.opening_loc, closing_loc: self.closing_loc) + ParenthesesNode.new(source, node_id, location, flags, body, opening_loc, closing_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, body: Prism::node?, opening_loc: Location, closing_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, body: body, opening_loc: opening_loc, closing_loc: closing_loc } + end + + # def multiple_statements?: () -> bool + def multiple_statements? + flags.anybits?(ParenthesesNodeFlags::MULTIPLE_STATEMENTS) + end + + # attr_reader body: Prism::node? + attr_reader :body + + # attr_reader opening_loc: Location + def opening_loc + location = @opening_loc + return location if location.is_a?(Location) + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) + end + + # attr_reader closing_loc: Location + def closing_loc + location = @closing_loc + return location if location.is_a?(Location) + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) + end + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :parentheses_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :parentheses_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ParenthesesNode) && + (flags === other.flags) && + (body === other.body) && + (opening_loc.nil? == other.opening_loc.nil?) && + (closing_loc.nil? == other.closing_loc.nil?) + end + end + + # Represents the use of the `^` operator for pinning an expression in a pattern matching expression. + # + # foo in ^(bar) + # ^^^^^^ + class PinnedExpressionNode < Node + # Initialize a new PinnedExpressionNode node. + def initialize(source, node_id, location, flags, expression, operator_loc, lparen_loc, rparen_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @expression = expression + @operator_loc = operator_loc + @lparen_loc = lparen_loc + @rparen_loc = rparen_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_pinned_expression_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [expression] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [expression] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [expression, operator_loc, lparen_loc, rparen_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?expression: Prism::node, ?operator_loc: Location, ?lparen_loc: Location, ?rparen_loc: Location) -> PinnedExpressionNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, expression: self.expression, operator_loc: self.operator_loc, lparen_loc: self.lparen_loc, rparen_loc: self.rparen_loc) + PinnedExpressionNode.new(source, node_id, location, flags, expression, operator_loc, lparen_loc, rparen_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, expression: Prism::node, operator_loc: Location, lparen_loc: Location, rparen_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, expression: expression, operator_loc: operator_loc, lparen_loc: lparen_loc, rparen_loc: rparen_loc } + end + + # attr_reader expression: Prism::node + attr_reader :expression + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # attr_reader lparen_loc: Location + def lparen_loc + location = @lparen_loc + return location if location.is_a?(Location) + @lparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the lparen_loc location using the given saved source so that + # it can be retrieved later. + def save_lparen_loc(repository) + repository.enter(node_id, :lparen_loc) + end + + # attr_reader rparen_loc: Location + def rparen_loc + location = @rparen_loc + return location if location.is_a?(Location) + @rparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the rparen_loc location using the given saved source so that + # it can be retrieved later. + def save_rparen_loc(repository) + repository.enter(node_id, :rparen_loc) + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def lparen: () -> String + def lparen + lparen_loc.slice + end + + # def rparen: () -> String + def rparen + rparen_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :pinned_expression_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :pinned_expression_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(PinnedExpressionNode) && + (expression === other.expression) && + (operator_loc.nil? == other.operator_loc.nil?) && + (lparen_loc.nil? == other.lparen_loc.nil?) && + (rparen_loc.nil? == other.rparen_loc.nil?) + end + end + + # Represents the use of the `^` operator for pinning a variable in a pattern matching expression. + # + # foo in ^bar + # ^^^^ + class PinnedVariableNode < Node + # Initialize a new PinnedVariableNode node. + def initialize(source, node_id, location, flags, variable, operator_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @variable = variable + @operator_loc = operator_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_pinned_variable_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [variable] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [variable] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [variable, operator_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?variable: LocalVariableReadNode | InstanceVariableReadNode | ClassVariableReadNode | GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode | ItLocalVariableReadNode | MissingNode, ?operator_loc: Location) -> PinnedVariableNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, variable: self.variable, operator_loc: self.operator_loc) + PinnedVariableNode.new(source, node_id, location, flags, variable, operator_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, variable: LocalVariableReadNode | InstanceVariableReadNode | ClassVariableReadNode | GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode | ItLocalVariableReadNode | MissingNode, operator_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, variable: variable, operator_loc: operator_loc } + end + + # attr_reader variable: LocalVariableReadNode | InstanceVariableReadNode | ClassVariableReadNode | GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode | ItLocalVariableReadNode | MissingNode + attr_reader :variable + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :pinned_variable_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :pinned_variable_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(PinnedVariableNode) && + (variable === other.variable) && + (operator_loc.nil? == other.operator_loc.nil?) + end + end + + # Represents the use of the `END` keyword. + # + # END { foo } + # ^^^^^^^^^^^ + class PostExecutionNode < Node + # Initialize a new PostExecutionNode node. + def initialize(source, node_id, location, flags, statements, keyword_loc, opening_loc, closing_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @statements = statements + @keyword_loc = keyword_loc + @opening_loc = opening_loc + @closing_loc = closing_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_post_execution_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [statements] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << statements if statements + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*statements, keyword_loc, opening_loc, closing_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?statements: StatementsNode?, ?keyword_loc: Location, ?opening_loc: Location, ?closing_loc: Location) -> PostExecutionNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, statements: self.statements, keyword_loc: self.keyword_loc, opening_loc: self.opening_loc, closing_loc: self.closing_loc) + PostExecutionNode.new(source, node_id, location, flags, statements, keyword_loc, opening_loc, closing_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, statements: StatementsNode?, keyword_loc: Location, opening_loc: Location, closing_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, statements: statements, keyword_loc: keyword_loc, opening_loc: opening_loc, closing_loc: closing_loc } + end + + # attr_reader statements: StatementsNode? + attr_reader :statements + + # attr_reader keyword_loc: Location + def keyword_loc + location = @keyword_loc + return location if location.is_a?(Location) + @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_keyword_loc(repository) + repository.enter(node_id, :keyword_loc) + end + + # attr_reader opening_loc: Location + def opening_loc + location = @opening_loc + return location if location.is_a?(Location) + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) + end + + # attr_reader closing_loc: Location + def closing_loc + location = @closing_loc + return location if location.is_a?(Location) + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) + end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :post_execution_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :post_execution_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(PostExecutionNode) && + (statements === other.statements) && + (keyword_loc.nil? == other.keyword_loc.nil?) && + (opening_loc.nil? == other.opening_loc.nil?) && + (closing_loc.nil? == other.closing_loc.nil?) + end + end + + # Represents the use of the `BEGIN` keyword. + # + # BEGIN { foo } + # ^^^^^^^^^^^^^ + class PreExecutionNode < Node + # Initialize a new PreExecutionNode node. + def initialize(source, node_id, location, flags, statements, keyword_loc, opening_loc, closing_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @statements = statements + @keyword_loc = keyword_loc + @opening_loc = opening_loc + @closing_loc = closing_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_pre_execution_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [statements] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << statements if statements + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*statements, keyword_loc, opening_loc, closing_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?statements: StatementsNode?, ?keyword_loc: Location, ?opening_loc: Location, ?closing_loc: Location) -> PreExecutionNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, statements: self.statements, keyword_loc: self.keyword_loc, opening_loc: self.opening_loc, closing_loc: self.closing_loc) + PreExecutionNode.new(source, node_id, location, flags, statements, keyword_loc, opening_loc, closing_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, statements: StatementsNode?, keyword_loc: Location, opening_loc: Location, closing_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, statements: statements, keyword_loc: keyword_loc, opening_loc: opening_loc, closing_loc: closing_loc } + end + + # attr_reader statements: StatementsNode? + attr_reader :statements + + # attr_reader keyword_loc: Location + def keyword_loc + location = @keyword_loc + return location if location.is_a?(Location) + @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_keyword_loc(repository) + repository.enter(node_id, :keyword_loc) + end + + # attr_reader opening_loc: Location + def opening_loc + location = @opening_loc + return location if location.is_a?(Location) + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) + end + + # attr_reader closing_loc: Location + def closing_loc + location = @closing_loc + return location if location.is_a?(Location) + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) + end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :pre_execution_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :pre_execution_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(PreExecutionNode) && + (statements === other.statements) && + (keyword_loc.nil? == other.keyword_loc.nil?) && + (opening_loc.nil? == other.opening_loc.nil?) && + (closing_loc.nil? == other.closing_loc.nil?) + end + end + + # The top level node of any parse tree. + class ProgramNode < Node + # Initialize a new ProgramNode node. + def initialize(source, node_id, location, flags, locals, statements) + @source = source + @node_id = node_id + @location = location + @flags = flags + @locals = locals + @statements = statements + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_program_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [statements] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [statements] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [statements] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?locals: Array[Symbol], ?statements: StatementsNode) -> ProgramNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, locals: self.locals, statements: self.statements) + ProgramNode.new(source, node_id, location, flags, locals, statements) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, locals: Array[Symbol], statements: StatementsNode } + def deconstruct_keys(keys) + { node_id: node_id, location: location, locals: locals, statements: statements } + end + + # attr_reader locals: Array[Symbol] + attr_reader :locals + + # attr_reader statements: StatementsNode + attr_reader :statements + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :program_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :program_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ProgramNode) && + (locals.length == other.locals.length) && + locals.zip(other.locals).all? { |left, right| left === right } && + (statements === other.statements) + end + end + + # Represents the use of the `..` or `...` operators. + # + # 1..2 + # ^^^^ + # + # c if a =~ /left/ ... b =~ /right/ + # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + class RangeNode < Node + # Initialize a new RangeNode node. + def initialize(source, node_id, location, flags, left, right, operator_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @left = left + @right = right + @operator_loc = operator_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_range_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [left, right] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << left if left + compact << right if right + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*left, *right, operator_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?left: Prism::node?, ?right: Prism::node?, ?operator_loc: Location) -> RangeNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, left: self.left, right: self.right, operator_loc: self.operator_loc) + RangeNode.new(source, node_id, location, flags, left, right, operator_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, left: Prism::node?, right: Prism::node?, operator_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, left: left, right: right, operator_loc: operator_loc } + end + + # def exclude_end?: () -> bool + def exclude_end? + flags.anybits?(RangeFlags::EXCLUDE_END) + end + + # The left-hand side of the range, if present. It can be either `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # 1... + # ^ + # + # hello...goodbye + # ^^^^^ + attr_reader :left + + # The right-hand side of the range, if present. It can be either `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # ..5 + # ^ + # + # 1...foo + # ^^^ + # If neither right-hand or left-hand side was included, this will be a MissingNode. + attr_reader :right + + # The location of the `..` or `...` operator. + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :range_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :range_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(RangeNode) && + (flags === other.flags) && + (left === other.left) && + (right === other.right) && + (operator_loc.nil? == other.operator_loc.nil?) + end + end + + # Represents a rational number literal. + # + # 1.0r + # ^^^^ + class RationalNode < Node + # Initialize a new RationalNode node. + def initialize(source, node_id, location, flags, numerator, denominator) + @source = source + @node_id = node_id + @location = location + @flags = flags + @numerator = numerator + @denominator = denominator + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_rational_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?numerator: Integer, ?denominator: Integer) -> RationalNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, numerator: self.numerator, denominator: self.denominator) + RationalNode.new(source, node_id, location, flags, numerator, denominator) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, numerator: Integer, denominator: Integer } + def deconstruct_keys(keys) + { node_id: node_id, location: location, numerator: numerator, denominator: denominator } + end + + # def binary?: () -> bool + def binary? + flags.anybits?(IntegerBaseFlags::BINARY) + end + + # def decimal?: () -> bool + def decimal? + flags.anybits?(IntegerBaseFlags::DECIMAL) + end + + # def octal?: () -> bool + def octal? + flags.anybits?(IntegerBaseFlags::OCTAL) + end + + # def hexadecimal?: () -> bool + def hexadecimal? + flags.anybits?(IntegerBaseFlags::HEXADECIMAL) + end + + # The numerator of the rational number. + # + # 1.5r # numerator 3 + attr_reader :numerator + + # The denominator of the rational number. + # + # 1.5r # denominator 2 + attr_reader :denominator + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :rational_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :rational_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(RationalNode) && + (flags === other.flags) && + (numerator === other.numerator) && + (denominator === other.denominator) + end + end + + # Represents the use of the `redo` keyword. + # + # redo + # ^^^^ + class RedoNode < Node + # Initialize a new RedoNode node. + def initialize(source, node_id, location, flags) + @source = source + @node_id = node_id + @location = location + @flags = flags + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_redo_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> RedoNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags) + RedoNode.new(source, node_id, location, flags) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location } + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :redo_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :redo_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(RedoNode) + end + end + + # Represents a regular expression literal with no interpolation. + # + # /foo/i + # ^^^^^^ + class RegularExpressionNode < Node + # Initialize a new RegularExpressionNode node. + def initialize(source, node_id, location, flags, opening_loc, content_loc, closing_loc, unescaped) + @source = source + @node_id = node_id + @location = location + @flags = flags + @opening_loc = opening_loc + @content_loc = content_loc + @closing_loc = closing_loc + @unescaped = unescaped + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_regular_expression_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [opening_loc, content_loc, closing_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?content_loc: Location, ?closing_loc: Location, ?unescaped: String) -> RegularExpressionNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, content_loc: self.content_loc, closing_loc: self.closing_loc, unescaped: self.unescaped) + RegularExpressionNode.new(source, node_id, location, flags, opening_loc, content_loc, closing_loc, unescaped) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location, content_loc: Location, closing_loc: Location, unescaped: String } + def deconstruct_keys(keys) + { node_id: node_id, location: location, opening_loc: opening_loc, content_loc: content_loc, closing_loc: closing_loc, unescaped: unescaped } + end + + # def ignore_case?: () -> bool + def ignore_case? + flags.anybits?(RegularExpressionFlags::IGNORE_CASE) + end + + # def extended?: () -> bool + def extended? + flags.anybits?(RegularExpressionFlags::EXTENDED) + end + + # def multi_line?: () -> bool + def multi_line? + flags.anybits?(RegularExpressionFlags::MULTI_LINE) + end + + # def once?: () -> bool + def once? + flags.anybits?(RegularExpressionFlags::ONCE) + end + + # def euc_jp?: () -> bool + def euc_jp? + flags.anybits?(RegularExpressionFlags::EUC_JP) + end + + # def ascii_8bit?: () -> bool + def ascii_8bit? + flags.anybits?(RegularExpressionFlags::ASCII_8BIT) + end + + # def windows_31j?: () -> bool + def windows_31j? + flags.anybits?(RegularExpressionFlags::WINDOWS_31J) + end + + # def utf_8?: () -> bool + def utf_8? + flags.anybits?(RegularExpressionFlags::UTF_8) + end + + # def forced_utf8_encoding?: () -> bool + def forced_utf8_encoding? + flags.anybits?(RegularExpressionFlags::FORCED_UTF8_ENCODING) + end + + # def forced_binary_encoding?: () -> bool + def forced_binary_encoding? + flags.anybits?(RegularExpressionFlags::FORCED_BINARY_ENCODING) + end + + # def forced_us_ascii_encoding?: () -> bool + def forced_us_ascii_encoding? + flags.anybits?(RegularExpressionFlags::FORCED_US_ASCII_ENCODING) + end + + # attr_reader opening_loc: Location + def opening_loc + location = @opening_loc + return location if location.is_a?(Location) + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) + end + + # attr_reader content_loc: Location + def content_loc + location = @content_loc + return location if location.is_a?(Location) + @content_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the content_loc location using the given saved source so that + # it can be retrieved later. + def save_content_loc(repository) + repository.enter(node_id, :content_loc) + end + + # attr_reader closing_loc: Location + def closing_loc + location = @closing_loc + return location if location.is_a?(Location) + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) + end + + # attr_reader unescaped: String + attr_reader :unescaped + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def content: () -> String + def content + content_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :regular_expression_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :regular_expression_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(RegularExpressionNode) && + (flags === other.flags) && + (opening_loc.nil? == other.opening_loc.nil?) && + (content_loc.nil? == other.content_loc.nil?) && + (closing_loc.nil? == other.closing_loc.nil?) && + (unescaped === other.unescaped) + end + end + + # Represents a required keyword parameter to a method, block, or lambda definition. + # + # def a(b: ) + # ^^ + # end + class RequiredKeywordParameterNode < Node + # Initialize a new RequiredKeywordParameterNode node. + def initialize(source, node_id, location, flags, name, name_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @name_loc = name_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_required_keyword_parameter_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [name_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location) -> RequiredKeywordParameterNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc) + RequiredKeywordParameterNode.new(source, node_id, location, flags, name, name_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, name_loc: name_loc } + end + + # def repeated_parameter?: () -> bool + def repeated_parameter? + flags.anybits?(ParameterFlags::REPEATED_PARAMETER) + end + + # attr_reader name: Symbol + attr_reader :name + + # attr_reader name_loc: Location + def name_loc + location = @name_loc + return location if location.is_a?(Location) + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :required_keyword_parameter_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :required_keyword_parameter_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(RequiredKeywordParameterNode) && + (flags === other.flags) && + (name === other.name) && + (name_loc.nil? == other.name_loc.nil?) + end + end + + # Represents a required parameter to a method, block, or lambda definition. + # + # def a(b) + # ^ + # end + class RequiredParameterNode < Node + # Initialize a new RequiredParameterNode node. + def initialize(source, node_id, location, flags, name) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_required_parameter_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> RequiredParameterNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name) + RequiredParameterNode.new(source, node_id, location, flags, name) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name } + end + + # def repeated_parameter?: () -> bool + def repeated_parameter? + flags.anybits?(ParameterFlags::REPEATED_PARAMETER) + end + + # attr_reader name: Symbol + attr_reader :name + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :required_parameter_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :required_parameter_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(RequiredParameterNode) && + (flags === other.flags) && + (name === other.name) + end + end + + # Represents an expression modified with a rescue. + # + # foo rescue nil + # ^^^^^^^^^^^^^^ + class RescueModifierNode < Node + # Initialize a new RescueModifierNode node. + def initialize(source, node_id, location, flags, expression, keyword_loc, rescue_expression) + @source = source + @node_id = node_id + @location = location + @flags = flags + @expression = expression + @keyword_loc = keyword_loc + @rescue_expression = rescue_expression + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_rescue_modifier_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [expression, rescue_expression] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [expression, rescue_expression] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [expression, keyword_loc, rescue_expression] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?expression: Prism::node, ?keyword_loc: Location, ?rescue_expression: Prism::node) -> RescueModifierNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, expression: self.expression, keyword_loc: self.keyword_loc, rescue_expression: self.rescue_expression) + RescueModifierNode.new(source, node_id, location, flags, expression, keyword_loc, rescue_expression) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, expression: Prism::node, keyword_loc: Location, rescue_expression: Prism::node } + def deconstruct_keys(keys) + { node_id: node_id, location: location, expression: expression, keyword_loc: keyword_loc, rescue_expression: rescue_expression } + end + + # attr_reader expression: Prism::node + attr_reader :expression + + # attr_reader keyword_loc: Location + def keyword_loc + location = @keyword_loc + return location if location.is_a?(Location) + @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_keyword_loc(repository) + repository.enter(node_id, :keyword_loc) + end + + # attr_reader rescue_expression: Prism::node + attr_reader :rescue_expression + + # def keyword: () -> String + def keyword + keyword_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :rescue_modifier_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :rescue_modifier_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(RescueModifierNode) && + (expression === other.expression) && + (keyword_loc.nil? == other.keyword_loc.nil?) && + (rescue_expression === other.rescue_expression) + end + end + + # Represents a rescue statement. + # + # begin + # rescue Foo, *splat, Bar => ex + # foo + # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + # end + # + # `Foo, *splat, Bar` are in the `exceptions` field. `ex` is in the `reference` field. + class RescueNode < Node + # Initialize a new RescueNode node. + def initialize(source, node_id, location, flags, keyword_loc, exceptions, operator_loc, reference, then_keyword_loc, statements, subsequent) + @source = source + @node_id = node_id + @location = location + @flags = flags + @keyword_loc = keyword_loc + @exceptions = exceptions + @operator_loc = operator_loc + @reference = reference + @then_keyword_loc = then_keyword_loc + @statements = statements + @subsequent = subsequent + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_rescue_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [*exceptions, reference, statements, subsequent] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact.concat(exceptions) + compact << reference if reference + compact << statements if statements + compact << subsequent if subsequent + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [keyword_loc, *exceptions, *operator_loc, *reference, *then_keyword_loc, *statements, *subsequent] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?exceptions: Array[Prism::node], ?operator_loc: Location?, ?reference: LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | BackReferenceReadNode | NumberedReferenceReadNode | MissingNode | nil, ?then_keyword_loc: Location?, ?statements: StatementsNode?, ?subsequent: RescueNode?) -> RescueNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, keyword_loc: self.keyword_loc, exceptions: self.exceptions, operator_loc: self.operator_loc, reference: self.reference, then_keyword_loc: self.then_keyword_loc, statements: self.statements, subsequent: self.subsequent) + RescueNode.new(source, node_id, location, flags, keyword_loc, exceptions, operator_loc, reference, then_keyword_loc, statements, subsequent) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, keyword_loc: Location, exceptions: Array[Prism::node], operator_loc: Location?, reference: LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | BackReferenceReadNode | NumberedReferenceReadNode | MissingNode | nil, then_keyword_loc: Location?, statements: StatementsNode?, subsequent: RescueNode? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, keyword_loc: keyword_loc, exceptions: exceptions, operator_loc: operator_loc, reference: reference, then_keyword_loc: then_keyword_loc, statements: statements, subsequent: subsequent } + end + + # attr_reader keyword_loc: Location + def keyword_loc + location = @keyword_loc + return location if location.is_a?(Location) + @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_keyword_loc(repository) + repository.enter(node_id, :keyword_loc) + end + + # attr_reader exceptions: Array[Prism::node] + attr_reader :exceptions + + # attr_reader operator_loc: Location? + def operator_loc + location = @operator_loc + case location + when nil + nil + when Location + location + else + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) unless @operator_loc.nil? + end + + # attr_reader reference: LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | BackReferenceReadNode | NumberedReferenceReadNode | MissingNode | nil + attr_reader :reference + + # attr_reader then_keyword_loc: Location? + def then_keyword_loc + location = @then_keyword_loc + case location + when nil + nil + when Location + location + else + @then_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the then_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_then_keyword_loc(repository) + repository.enter(node_id, :then_keyword_loc) unless @then_keyword_loc.nil? + end + + # attr_reader statements: StatementsNode? + attr_reader :statements + + # attr_reader subsequent: RescueNode? + attr_reader :subsequent + + # def keyword: () -> String + def keyword + keyword_loc.slice + end + + # def operator: () -> String? + def operator + operator_loc&.slice + end + + # def then_keyword: () -> String? + def then_keyword + then_keyword_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :rescue_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :rescue_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(RescueNode) && + (keyword_loc.nil? == other.keyword_loc.nil?) && + (exceptions.length == other.exceptions.length) && + exceptions.zip(other.exceptions).all? { |left, right| left === right } && + (operator_loc.nil? == other.operator_loc.nil?) && + (reference === other.reference) && + (then_keyword_loc.nil? == other.then_keyword_loc.nil?) && + (statements === other.statements) && + (subsequent === other.subsequent) + end + end + + # Represents a rest parameter to a method, block, or lambda definition. + # + # def a(*b) + # ^^ + # end + class RestParameterNode < Node + # Initialize a new RestParameterNode node. + def initialize(source, node_id, location, flags, name, name_loc, operator_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @name = name + @name_loc = name_loc + @operator_loc = operator_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_rest_parameter_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*name_loc, operator_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol?, ?name_loc: Location?, ?operator_loc: Location) -> RestParameterNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc) + RestParameterNode.new(source, node_id, location, flags, name, name_loc, operator_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol?, name_loc: Location?, operator_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, name: name, name_loc: name_loc, operator_loc: operator_loc } + end + + # def repeated_parameter?: () -> bool + def repeated_parameter? + flags.anybits?(ParameterFlags::REPEATED_PARAMETER) + end + + # attr_reader name: Symbol? + attr_reader :name + + # attr_reader name_loc: Location? + def name_loc + location = @name_loc + case location + when nil + nil + when Location + location + else + @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the name_loc location using the given saved source so that + # it can be retrieved later. + def save_name_loc(repository) + repository.enter(node_id, :name_loc) unless @name_loc.nil? + end + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :rest_parameter_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :rest_parameter_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(RestParameterNode) && + (flags === other.flags) && + (name === other.name) && + (name_loc.nil? == other.name_loc.nil?) && + (operator_loc.nil? == other.operator_loc.nil?) + end + end + + # Represents the use of the `retry` keyword. + # + # retry + # ^^^^^ + class RetryNode < Node + # Initialize a new RetryNode node. + def initialize(source, node_id, location, flags) + @source = source + @node_id = node_id + @location = location + @flags = flags + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_retry_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> RetryNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags) + RetryNode.new(source, node_id, location, flags) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location } + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :retry_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :retry_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(RetryNode) + end + end + + # Represents the use of the `return` keyword. + # + # return 1 + # ^^^^^^^^ + class ReturnNode < Node + # Initialize a new ReturnNode node. + def initialize(source, node_id, location, flags, keyword_loc, arguments) + @source = source + @node_id = node_id + @location = location + @flags = flags + @keyword_loc = keyword_loc + @arguments = arguments + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_return_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [arguments] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << arguments if arguments + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [keyword_loc, *arguments] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?arguments: ArgumentsNode?) -> ReturnNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, keyword_loc: self.keyword_loc, arguments: self.arguments) + ReturnNode.new(source, node_id, location, flags, keyword_loc, arguments) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, keyword_loc: Location, arguments: ArgumentsNode? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, keyword_loc: keyword_loc, arguments: arguments } + end + + # attr_reader keyword_loc: Location + def keyword_loc + location = @keyword_loc + return location if location.is_a?(Location) + @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_keyword_loc(repository) + repository.enter(node_id, :keyword_loc) + end + + # attr_reader arguments: ArgumentsNode? + attr_reader :arguments + + # def keyword: () -> String + def keyword + keyword_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :return_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :return_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ReturnNode) && + (keyword_loc.nil? == other.keyword_loc.nil?) && + (arguments === other.arguments) + end + end + + # Represents the `self` keyword. + # + # self + # ^^^^ + class SelfNode < Node + # Initialize a new SelfNode node. + def initialize(source, node_id, location, flags) + @source = source + @node_id = node_id + @location = location + @flags = flags + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_self_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> SelfNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags) + SelfNode.new(source, node_id, location, flags) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location } + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :self_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :self_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(SelfNode) + end + end + + # This node wraps a constant write to indicate that when the value is written, it should have its shareability state modified. + # + # # shareable_constant_value: literal + # C = { a: 1 } + # ^^^^^^^^^^^^ + class ShareableConstantNode < Node + # Initialize a new ShareableConstantNode node. + def initialize(source, node_id, location, flags, write) + @source = source + @node_id = node_id + @location = location + @flags = flags + @write = write + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_shareable_constant_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [write] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [write] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [write] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?write: ConstantWriteNode | ConstantAndWriteNode | ConstantOrWriteNode | ConstantOperatorWriteNode | ConstantPathWriteNode | ConstantPathAndWriteNode | ConstantPathOrWriteNode | ConstantPathOperatorWriteNode) -> ShareableConstantNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, write: self.write) + ShareableConstantNode.new(source, node_id, location, flags, write) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, write: ConstantWriteNode | ConstantAndWriteNode | ConstantOrWriteNode | ConstantOperatorWriteNode | ConstantPathWriteNode | ConstantPathAndWriteNode | ConstantPathOrWriteNode | ConstantPathOperatorWriteNode } + def deconstruct_keys(keys) + { node_id: node_id, location: location, write: write } + end + + # def literal?: () -> bool + def literal? + flags.anybits?(ShareableConstantNodeFlags::LITERAL) + end + + # def experimental_everything?: () -> bool + def experimental_everything? + flags.anybits?(ShareableConstantNodeFlags::EXPERIMENTAL_EVERYTHING) + end + + # def experimental_copy?: () -> bool + def experimental_copy? + flags.anybits?(ShareableConstantNodeFlags::EXPERIMENTAL_COPY) + end + + # The constant write that should be modified with the shareability state. + attr_reader :write + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :shareable_constant_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :shareable_constant_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(ShareableConstantNode) && + (flags === other.flags) && + (write === other.write) + end + end + + # Represents a singleton class declaration involving the `class` keyword. + # + # class << self end + # ^^^^^^^^^^^^^^^^^ + class SingletonClassNode < Node + # Initialize a new SingletonClassNode node. + def initialize(source, node_id, location, flags, locals, class_keyword_loc, operator_loc, expression, body, end_keyword_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @locals = locals + @class_keyword_loc = class_keyword_loc + @operator_loc = operator_loc + @expression = expression + @body = body + @end_keyword_loc = end_keyword_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_singleton_class_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [expression, body] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << expression + compact << body if body + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [class_keyword_loc, operator_loc, expression, *body, end_keyword_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?locals: Array[Symbol], ?class_keyword_loc: Location, ?operator_loc: Location, ?expression: Prism::node, ?body: StatementsNode | BeginNode | nil, ?end_keyword_loc: Location) -> SingletonClassNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, locals: self.locals, class_keyword_loc: self.class_keyword_loc, operator_loc: self.operator_loc, expression: self.expression, body: self.body, end_keyword_loc: self.end_keyword_loc) + SingletonClassNode.new(source, node_id, location, flags, locals, class_keyword_loc, operator_loc, expression, body, end_keyword_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, locals: Array[Symbol], class_keyword_loc: Location, operator_loc: Location, expression: Prism::node, body: StatementsNode | BeginNode | nil, end_keyword_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, locals: locals, class_keyword_loc: class_keyword_loc, operator_loc: operator_loc, expression: expression, body: body, end_keyword_loc: end_keyword_loc } + end + + # attr_reader locals: Array[Symbol] + attr_reader :locals + + # attr_reader class_keyword_loc: Location + def class_keyword_loc + location = @class_keyword_loc + return location if location.is_a?(Location) + @class_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the class_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_class_keyword_loc(repository) + repository.enter(node_id, :class_keyword_loc) + end + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # attr_reader expression: Prism::node + attr_reader :expression + + # attr_reader body: StatementsNode | BeginNode | nil + attr_reader :body + + # attr_reader end_keyword_loc: Location + def end_keyword_loc + location = @end_keyword_loc + return location if location.is_a?(Location) + @end_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the end_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_end_keyword_loc(repository) + repository.enter(node_id, :end_keyword_loc) + end + + # def class_keyword: () -> String + def class_keyword + class_keyword_loc.slice + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def end_keyword: () -> String + def end_keyword + end_keyword_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :singleton_class_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :singleton_class_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(SingletonClassNode) && + (locals.length == other.locals.length) && + locals.zip(other.locals).all? { |left, right| left === right } && + (class_keyword_loc.nil? == other.class_keyword_loc.nil?) && + (operator_loc.nil? == other.operator_loc.nil?) && + (expression === other.expression) && + (body === other.body) && + (end_keyword_loc.nil? == other.end_keyword_loc.nil?) + end + end + + # Represents the use of the `__ENCODING__` keyword. + # + # __ENCODING__ + # ^^^^^^^^^^^^ + class SourceEncodingNode < Node + # Initialize a new SourceEncodingNode node. + def initialize(source, node_id, location, flags) + @source = source + @node_id = node_id + @location = location + @flags = flags + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_source_encoding_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> SourceEncodingNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags) + SourceEncodingNode.new(source, node_id, location, flags) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location } + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :source_encoding_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :source_encoding_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(SourceEncodingNode) + end + end + + # Represents the use of the `__FILE__` keyword. + # + # __FILE__ + # ^^^^^^^^ + class SourceFileNode < Node + # Initialize a new SourceFileNode node. + def initialize(source, node_id, location, flags, filepath) + @source = source + @node_id = node_id + @location = location + @flags = flags + @filepath = filepath + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_source_file_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?filepath: String) -> SourceFileNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, filepath: self.filepath) + SourceFileNode.new(source, node_id, location, flags, filepath) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, filepath: String } + def deconstruct_keys(keys) + { node_id: node_id, location: location, filepath: filepath } + end + + # def forced_utf8_encoding?: () -> bool + def forced_utf8_encoding? + flags.anybits?(StringFlags::FORCED_UTF8_ENCODING) + end + + # def forced_binary_encoding?: () -> bool + def forced_binary_encoding? + flags.anybits?(StringFlags::FORCED_BINARY_ENCODING) + end + + # def frozen?: () -> bool + def frozen? + flags.anybits?(StringFlags::FROZEN) + end + + # def mutable?: () -> bool + def mutable? + flags.anybits?(StringFlags::MUTABLE) + end + + # Represents the file path being parsed. This corresponds directly to the `filepath` option given to the various `Prism::parse*` APIs. + attr_reader :filepath + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :source_file_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :source_file_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(SourceFileNode) && + (flags === other.flags) && + (filepath === other.filepath) + end + end + + # Represents the use of the `__LINE__` keyword. + # + # __LINE__ + # ^^^^^^^^ + class SourceLineNode < Node + # Initialize a new SourceLineNode node. + def initialize(source, node_id, location, flags) + @source = source + @node_id = node_id + @location = location + @flags = flags + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_source_line_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> SourceLineNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags) + SourceLineNode.new(source, node_id, location, flags) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location } + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :source_line_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :source_line_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(SourceLineNode) + end + end + + # Represents the use of the splat operator. + # + # [*a] + # ^^ + class SplatNode < Node + # Initialize a new SplatNode node. + def initialize(source, node_id, location, flags, operator_loc, expression) + @source = source + @node_id = node_id + @location = location + @flags = flags + @operator_loc = operator_loc + @expression = expression + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_splat_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [expression] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << expression if expression + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [operator_loc, *expression] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?operator_loc: Location, ?expression: Prism::node?) -> SplatNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, operator_loc: self.operator_loc, expression: self.expression) + SplatNode.new(source, node_id, location, flags, operator_loc, expression) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, operator_loc: Location, expression: Prism::node? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, operator_loc: operator_loc, expression: expression } + end + + # attr_reader operator_loc: Location + def operator_loc + location = @operator_loc + return location if location.is_a?(Location) + @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the operator_loc location using the given saved source so that + # it can be retrieved later. + def save_operator_loc(repository) + repository.enter(node_id, :operator_loc) + end + + # attr_reader expression: Prism::node? + attr_reader :expression + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :splat_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :splat_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(SplatNode) && + (operator_loc.nil? == other.operator_loc.nil?) && + (expression === other.expression) + end + end + + # Represents a set of statements contained within some scope. + # + # foo; bar; baz + # ^^^^^^^^^^^^^ + class StatementsNode < Node + # Initialize a new StatementsNode node. + def initialize(source, node_id, location, flags, body) + @source = source + @node_id = node_id + @location = location + @flags = flags + @body = body + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_statements_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [*body] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [*body] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*body] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?body: Array[Prism::node]) -> StatementsNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, body: self.body) + StatementsNode.new(source, node_id, location, flags, body) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, body: Array[Prism::node] } + def deconstruct_keys(keys) + { node_id: node_id, location: location, body: body } + end + + # attr_reader body: Array[Prism::node] + attr_reader :body + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :statements_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :statements_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(StatementsNode) && + (body.length == other.body.length) && + body.zip(other.body).all? { |left, right| left === right } + end + end + + # Represents a string literal, a string contained within a `%w` list, or plain string content within an interpolated string. + # + # "foo" + # ^^^^^ + # + # %w[foo] + # ^^^ + # + # "foo #{bar} baz" + # ^^^^ ^^^^ + class StringNode < Node + # Initialize a new StringNode node. + def initialize(source, node_id, location, flags, opening_loc, content_loc, closing_loc, unescaped) + @source = source + @node_id = node_id + @location = location + @flags = flags + @opening_loc = opening_loc + @content_loc = content_loc + @closing_loc = closing_loc + @unescaped = unescaped + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_string_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*opening_loc, content_loc, *closing_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location?, ?content_loc: Location, ?closing_loc: Location?, ?unescaped: String) -> StringNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, content_loc: self.content_loc, closing_loc: self.closing_loc, unescaped: self.unescaped) + StringNode.new(source, node_id, location, flags, opening_loc, content_loc, closing_loc, unescaped) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location?, content_loc: Location, closing_loc: Location?, unescaped: String } + def deconstruct_keys(keys) + { node_id: node_id, location: location, opening_loc: opening_loc, content_loc: content_loc, closing_loc: closing_loc, unescaped: unescaped } + end + + # def forced_utf8_encoding?: () -> bool + def forced_utf8_encoding? + flags.anybits?(StringFlags::FORCED_UTF8_ENCODING) + end + + # def forced_binary_encoding?: () -> bool + def forced_binary_encoding? + flags.anybits?(StringFlags::FORCED_BINARY_ENCODING) + end + + # def frozen?: () -> bool + def frozen? + flags.anybits?(StringFlags::FROZEN) + end + + # def mutable?: () -> bool + def mutable? + flags.anybits?(StringFlags::MUTABLE) + end + + # attr_reader opening_loc: Location? + def opening_loc + location = @opening_loc + case location + when nil + nil + when Location + location + else + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) unless @opening_loc.nil? + end + + # attr_reader content_loc: Location + def content_loc + location = @content_loc + return location if location.is_a?(Location) + @content_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the content_loc location using the given saved source so that + # it can be retrieved later. + def save_content_loc(repository) + repository.enter(node_id, :content_loc) + end + + # attr_reader closing_loc: Location? + def closing_loc + location = @closing_loc + case location + when nil + nil + when Location + location + else + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) unless @closing_loc.nil? + end + + # attr_reader unescaped: String + attr_reader :unescaped + + # def opening: () -> String? + def opening + opening_loc&.slice + end + + # def content: () -> String + def content + content_loc.slice + end + + # def closing: () -> String? + def closing + closing_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :string_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :string_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(StringNode) && + (flags === other.flags) && + (opening_loc.nil? == other.opening_loc.nil?) && + (content_loc.nil? == other.content_loc.nil?) && + (closing_loc.nil? == other.closing_loc.nil?) && + (unescaped === other.unescaped) + end + end + + # Represents the use of the `super` keyword with parentheses or arguments. + # + # super() + # ^^^^^^^ + # + # super foo, bar + # ^^^^^^^^^^^^^^ + class SuperNode < Node + # Initialize a new SuperNode node. + def initialize(source, node_id, location, flags, keyword_loc, lparen_loc, arguments, rparen_loc, block) + @source = source + @node_id = node_id + @location = location + @flags = flags + @keyword_loc = keyword_loc + @lparen_loc = lparen_loc + @arguments = arguments + @rparen_loc = rparen_loc + @block = block + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_super_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [arguments, block] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << arguments if arguments + compact << block if block + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [keyword_loc, *lparen_loc, *arguments, *rparen_loc, *block] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?lparen_loc: Location?, ?arguments: ArgumentsNode?, ?rparen_loc: Location?, ?block: BlockNode | BlockArgumentNode | nil) -> SuperNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, keyword_loc: self.keyword_loc, lparen_loc: self.lparen_loc, arguments: self.arguments, rparen_loc: self.rparen_loc, block: self.block) + SuperNode.new(source, node_id, location, flags, keyword_loc, lparen_loc, arguments, rparen_loc, block) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, keyword_loc: Location, lparen_loc: Location?, arguments: ArgumentsNode?, rparen_loc: Location?, block: BlockNode | BlockArgumentNode | nil } + def deconstruct_keys(keys) + { node_id: node_id, location: location, keyword_loc: keyword_loc, lparen_loc: lparen_loc, arguments: arguments, rparen_loc: rparen_loc, block: block } + end + + # attr_reader keyword_loc: Location + def keyword_loc + location = @keyword_loc + return location if location.is_a?(Location) + @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_keyword_loc(repository) + repository.enter(node_id, :keyword_loc) + end + + # attr_reader lparen_loc: Location? + def lparen_loc + location = @lparen_loc + case location + when nil + nil + when Location + location + else + @lparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the lparen_loc location using the given saved source so that + # it can be retrieved later. + def save_lparen_loc(repository) + repository.enter(node_id, :lparen_loc) unless @lparen_loc.nil? + end + + # attr_reader arguments: ArgumentsNode? + attr_reader :arguments + + # attr_reader rparen_loc: Location? + def rparen_loc + location = @rparen_loc + case location + when nil + nil + when Location + location + else + @rparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the rparen_loc location using the given saved source so that + # it can be retrieved later. + def save_rparen_loc(repository) + repository.enter(node_id, :rparen_loc) unless @rparen_loc.nil? + end + + # attr_reader block: BlockNode | BlockArgumentNode | nil + attr_reader :block + + # def keyword: () -> String + def keyword + keyword_loc.slice + end + + # def lparen: () -> String? + def lparen + lparen_loc&.slice + end + + # def rparen: () -> String? + def rparen + rparen_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :super_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :super_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(SuperNode) && + (keyword_loc.nil? == other.keyword_loc.nil?) && + (lparen_loc.nil? == other.lparen_loc.nil?) && + (arguments === other.arguments) && + (rparen_loc.nil? == other.rparen_loc.nil?) && + (block === other.block) + end + end + + # Represents a symbol literal or a symbol contained within a `%i` list. + # + # :foo + # ^^^^ + # + # %i[foo] + # ^^^ + class SymbolNode < Node + # Initialize a new SymbolNode node. + def initialize(source, node_id, location, flags, opening_loc, value_loc, closing_loc, unescaped) + @source = source + @node_id = node_id + @location = location + @flags = flags + @opening_loc = opening_loc + @value_loc = value_loc + @closing_loc = closing_loc + @unescaped = unescaped + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_symbol_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*opening_loc, *value_loc, *closing_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location?, ?value_loc: Location?, ?closing_loc: Location?, ?unescaped: String) -> SymbolNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, value_loc: self.value_loc, closing_loc: self.closing_loc, unescaped: self.unescaped) + SymbolNode.new(source, node_id, location, flags, opening_loc, value_loc, closing_loc, unescaped) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location?, value_loc: Location?, closing_loc: Location?, unescaped: String } + def deconstruct_keys(keys) + { node_id: node_id, location: location, opening_loc: opening_loc, value_loc: value_loc, closing_loc: closing_loc, unescaped: unescaped } + end + + # def forced_utf8_encoding?: () -> bool + def forced_utf8_encoding? + flags.anybits?(SymbolFlags::FORCED_UTF8_ENCODING) + end + + # def forced_binary_encoding?: () -> bool + def forced_binary_encoding? + flags.anybits?(SymbolFlags::FORCED_BINARY_ENCODING) + end + + # def forced_us_ascii_encoding?: () -> bool + def forced_us_ascii_encoding? + flags.anybits?(SymbolFlags::FORCED_US_ASCII_ENCODING) + end + + # attr_reader opening_loc: Location? + def opening_loc + location = @opening_loc + case location + when nil + nil + when Location + location + else + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) unless @opening_loc.nil? + end + + # attr_reader value_loc: Location? + def value_loc + location = @value_loc + case location + when nil + nil + when Location + location + else + @value_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the value_loc location using the given saved source so that + # it can be retrieved later. + def save_value_loc(repository) + repository.enter(node_id, :value_loc) unless @value_loc.nil? + end + + # attr_reader closing_loc: Location? + def closing_loc + location = @closing_loc + case location + when nil + nil + when Location + location + else + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) unless @closing_loc.nil? + end + + # attr_reader unescaped: String + attr_reader :unescaped + + # def opening: () -> String? + def opening + opening_loc&.slice + end + + # def value: () -> String? + def value + value_loc&.slice + end + + # def closing: () -> String? + def closing + closing_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :symbol_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :symbol_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(SymbolNode) && + (flags === other.flags) && + (opening_loc.nil? == other.opening_loc.nil?) && + (value_loc.nil? == other.value_loc.nil?) && + (closing_loc.nil? == other.closing_loc.nil?) && + (unescaped === other.unescaped) + end + end + + # Represents the use of the literal `true` keyword. + # + # true + # ^^^^ + class TrueNode < Node + # Initialize a new TrueNode node. + def initialize(source, node_id, location, flags) + @source = source + @node_id = node_id + @location = location + @flags = flags + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_true_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> TrueNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags) + TrueNode.new(source, node_id, location, flags) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location } + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :true_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :true_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(TrueNode) + end + end + + # Represents the use of the `undef` keyword. + # + # undef :foo, :bar, :baz + # ^^^^^^^^^^^^^^^^^^^^^^ + class UndefNode < Node + # Initialize a new UndefNode node. + def initialize(source, node_id, location, flags, names, keyword_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @names = names + @keyword_loc = keyword_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_undef_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [*names] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [*names] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [*names, keyword_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?names: Array[SymbolNode | InterpolatedSymbolNode], ?keyword_loc: Location) -> UndefNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, names: self.names, keyword_loc: self.keyword_loc) + UndefNode.new(source, node_id, location, flags, names, keyword_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, names: Array[SymbolNode | InterpolatedSymbolNode], keyword_loc: Location } + def deconstruct_keys(keys) + { node_id: node_id, location: location, names: names, keyword_loc: keyword_loc } + end + + # attr_reader names: Array[SymbolNode | InterpolatedSymbolNode] + attr_reader :names + + # attr_reader keyword_loc: Location + def keyword_loc + location = @keyword_loc + return location if location.is_a?(Location) + @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_keyword_loc(repository) + repository.enter(node_id, :keyword_loc) + end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :undef_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :undef_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(UndefNode) && + (names.length == other.names.length) && + names.zip(other.names).all? { |left, right| left === right } && + (keyword_loc.nil? == other.keyword_loc.nil?) + end + end + + # Represents the use of the `unless` keyword, either in the block form or the modifier form. + # + # bar unless foo + # ^^^^^^^^^^^^^^ + # + # unless foo then bar end + # ^^^^^^^^^^^^^^^^^^^^^^^ + class UnlessNode < Node + # Initialize a new UnlessNode node. + def initialize(source, node_id, location, flags, keyword_loc, predicate, then_keyword_loc, statements, else_clause, end_keyword_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @keyword_loc = keyword_loc + @predicate = predicate + @then_keyword_loc = then_keyword_loc + @statements = statements + @else_clause = else_clause + @end_keyword_loc = end_keyword_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_unless_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [predicate, statements, else_clause] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << predicate + compact << statements if statements + compact << else_clause if else_clause + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [keyword_loc, predicate, *then_keyword_loc, *statements, *else_clause, *end_keyword_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?predicate: Prism::node, ?then_keyword_loc: Location?, ?statements: StatementsNode?, ?else_clause: ElseNode?, ?end_keyword_loc: Location?) -> UnlessNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, keyword_loc: self.keyword_loc, predicate: self.predicate, then_keyword_loc: self.then_keyword_loc, statements: self.statements, else_clause: self.else_clause, end_keyword_loc: self.end_keyword_loc) + UnlessNode.new(source, node_id, location, flags, keyword_loc, predicate, then_keyword_loc, statements, else_clause, end_keyword_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, keyword_loc: Location, predicate: Prism::node, then_keyword_loc: Location?, statements: StatementsNode?, else_clause: ElseNode?, end_keyword_loc: Location? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, keyword_loc: keyword_loc, predicate: predicate, then_keyword_loc: then_keyword_loc, statements: statements, else_clause: else_clause, end_keyword_loc: end_keyword_loc } + end + + # The location of the `unless` keyword. + # + # unless cond then bar end + # ^^^^^^ + # + # bar unless cond + # ^^^^^^ + def keyword_loc + location = @keyword_loc + return location if location.is_a?(Location) + @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_keyword_loc(repository) + repository.enter(node_id, :keyword_loc) + end + + # The condition to be evaluated for the unless expression. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). + # + # unless cond then bar end + # ^^^^ + # + # bar unless cond + # ^^^^ + attr_reader :predicate + + # The location of the `then` keyword, if present. + # + # unless cond then bar end + # ^^^^ + def then_keyword_loc + location = @then_keyword_loc + case location + when nil + nil + when Location + location + else + @then_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the then_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_then_keyword_loc(repository) + repository.enter(node_id, :then_keyword_loc) unless @then_keyword_loc.nil? + end + + # The body of statements that will executed if the unless condition is + # falsey. Will be `nil` if no body is provided. + # + # unless cond then bar end + # ^^^ + attr_reader :statements + + # The else clause of the unless expression, if present. + # + # unless cond then bar else baz end + # ^^^^^^^^ + attr_reader :else_clause + + # The location of the `end` keyword, if present. + # + # unless cond then bar end + # ^^^ + def end_keyword_loc + location = @end_keyword_loc + case location + when nil + nil + when Location + location + else + @end_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the end_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_end_keyword_loc(repository) + repository.enter(node_id, :end_keyword_loc) unless @end_keyword_loc.nil? + end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end + + # def then_keyword: () -> String? + def then_keyword + then_keyword_loc&.slice + end + + # def end_keyword: () -> String? + def end_keyword + end_keyword_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :unless_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :unless_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(UnlessNode) && + (keyword_loc.nil? == other.keyword_loc.nil?) && + (predicate === other.predicate) && + (then_keyword_loc.nil? == other.then_keyword_loc.nil?) && + (statements === other.statements) && + (else_clause === other.else_clause) && + (end_keyword_loc.nil? == other.end_keyword_loc.nil?) + end + end + + # Represents the use of the `until` keyword, either in the block form or the modifier form. + # + # bar until foo + # ^^^^^^^^^^^^^ + # + # until foo do bar end + # ^^^^^^^^^^^^^^^^^^^^ + class UntilNode < Node + # Initialize a new UntilNode node. + def initialize(source, node_id, location, flags, keyword_loc, do_keyword_loc, closing_loc, predicate, statements) + @source = source + @node_id = node_id + @location = location + @flags = flags + @keyword_loc = keyword_loc + @do_keyword_loc = do_keyword_loc + @closing_loc = closing_loc + @predicate = predicate + @statements = statements + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_until_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [predicate, statements] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << predicate + compact << statements if statements + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [keyword_loc, *do_keyword_loc, *closing_loc, predicate, *statements] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?do_keyword_loc: Location?, ?closing_loc: Location?, ?predicate: Prism::node, ?statements: StatementsNode?) -> UntilNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, keyword_loc: self.keyword_loc, do_keyword_loc: self.do_keyword_loc, closing_loc: self.closing_loc, predicate: self.predicate, statements: self.statements) + UntilNode.new(source, node_id, location, flags, keyword_loc, do_keyword_loc, closing_loc, predicate, statements) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, keyword_loc: Location, do_keyword_loc: Location?, closing_loc: Location?, predicate: Prism::node, statements: StatementsNode? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, keyword_loc: keyword_loc, do_keyword_loc: do_keyword_loc, closing_loc: closing_loc, predicate: predicate, statements: statements } + end + + # def begin_modifier?: () -> bool + def begin_modifier? + flags.anybits?(LoopFlags::BEGIN_MODIFIER) + end + + # attr_reader keyword_loc: Location + def keyword_loc + location = @keyword_loc + return location if location.is_a?(Location) + @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_keyword_loc(repository) + repository.enter(node_id, :keyword_loc) + end + + # attr_reader do_keyword_loc: Location? + def do_keyword_loc + location = @do_keyword_loc + case location + when nil + nil + when Location + location + else + @do_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the do_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_do_keyword_loc(repository) + repository.enter(node_id, :do_keyword_loc) unless @do_keyword_loc.nil? + end + + # attr_reader closing_loc: Location? + def closing_loc + location = @closing_loc + case location + when nil + nil + when Location + location + else + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) unless @closing_loc.nil? + end + + # attr_reader predicate: Prism::node + attr_reader :predicate + + # attr_reader statements: StatementsNode? + attr_reader :statements + + # def keyword: () -> String + def keyword + keyword_loc.slice + end + + # def do_keyword: () -> String? + def do_keyword + do_keyword_loc&.slice + end + + # def closing: () -> String? + def closing + closing_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :until_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :until_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(UntilNode) && + (flags === other.flags) && + (keyword_loc.nil? == other.keyword_loc.nil?) && + (do_keyword_loc.nil? == other.do_keyword_loc.nil?) && + (closing_loc.nil? == other.closing_loc.nil?) && + (predicate === other.predicate) && + (statements === other.statements) + end + end + + # Represents the use of the `when` keyword within a case statement. + # + # case true + # when true + # ^^^^^^^^^ + # end + class WhenNode < Node + # Initialize a new WhenNode node. + def initialize(source, node_id, location, flags, keyword_loc, conditions, then_keyword_loc, statements) + @source = source + @node_id = node_id + @location = location + @flags = flags + @keyword_loc = keyword_loc + @conditions = conditions + @then_keyword_loc = then_keyword_loc + @statements = statements + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_when_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [*conditions, statements] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact.concat(conditions) + compact << statements if statements + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [keyword_loc, *conditions, *then_keyword_loc, *statements] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?conditions: Array[Prism::node], ?then_keyword_loc: Location?, ?statements: StatementsNode?) -> WhenNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, keyword_loc: self.keyword_loc, conditions: self.conditions, then_keyword_loc: self.then_keyword_loc, statements: self.statements) + WhenNode.new(source, node_id, location, flags, keyword_loc, conditions, then_keyword_loc, statements) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, keyword_loc: Location, conditions: Array[Prism::node], then_keyword_loc: Location?, statements: StatementsNode? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, keyword_loc: keyword_loc, conditions: conditions, then_keyword_loc: then_keyword_loc, statements: statements } + end + + # attr_reader keyword_loc: Location + def keyword_loc + location = @keyword_loc + return location if location.is_a?(Location) + @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_keyword_loc(repository) + repository.enter(node_id, :keyword_loc) + end + + # attr_reader conditions: Array[Prism::node] + attr_reader :conditions + + # attr_reader then_keyword_loc: Location? + def then_keyword_loc + location = @then_keyword_loc + case location + when nil + nil + when Location + location + else + @then_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the then_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_then_keyword_loc(repository) + repository.enter(node_id, :then_keyword_loc) unless @then_keyword_loc.nil? + end + + # attr_reader statements: StatementsNode? + attr_reader :statements + + # def keyword: () -> String + def keyword + keyword_loc.slice + end + + # def then_keyword: () -> String? + def then_keyword + then_keyword_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :when_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :when_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(WhenNode) && + (keyword_loc.nil? == other.keyword_loc.nil?) && + (conditions.length == other.conditions.length) && + conditions.zip(other.conditions).all? { |left, right| left === right } && + (then_keyword_loc.nil? == other.then_keyword_loc.nil?) && + (statements === other.statements) + end + end + + # Represents the use of the `while` keyword, either in the block form or the modifier form. + # + # bar while foo + # ^^^^^^^^^^^^^ + # + # while foo do bar end + # ^^^^^^^^^^^^^^^^^^^^ + class WhileNode < Node + # Initialize a new WhileNode node. + def initialize(source, node_id, location, flags, keyword_loc, do_keyword_loc, closing_loc, predicate, statements) + @source = source + @node_id = node_id + @location = location + @flags = flags + @keyword_loc = keyword_loc + @do_keyword_loc = do_keyword_loc + @closing_loc = closing_loc + @predicate = predicate + @statements = statements + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_while_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [predicate, statements] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << predicate + compact << statements if statements + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [keyword_loc, *do_keyword_loc, *closing_loc, predicate, *statements] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?do_keyword_loc: Location?, ?closing_loc: Location?, ?predicate: Prism::node, ?statements: StatementsNode?) -> WhileNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, keyword_loc: self.keyword_loc, do_keyword_loc: self.do_keyword_loc, closing_loc: self.closing_loc, predicate: self.predicate, statements: self.statements) + WhileNode.new(source, node_id, location, flags, keyword_loc, do_keyword_loc, closing_loc, predicate, statements) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, keyword_loc: Location, do_keyword_loc: Location?, closing_loc: Location?, predicate: Prism::node, statements: StatementsNode? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, keyword_loc: keyword_loc, do_keyword_loc: do_keyword_loc, closing_loc: closing_loc, predicate: predicate, statements: statements } + end + + # def begin_modifier?: () -> bool + def begin_modifier? + flags.anybits?(LoopFlags::BEGIN_MODIFIER) + end + + # attr_reader keyword_loc: Location + def keyword_loc + location = @keyword_loc + return location if location.is_a?(Location) + @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_keyword_loc(repository) + repository.enter(node_id, :keyword_loc) + end + + # attr_reader do_keyword_loc: Location? + def do_keyword_loc + location = @do_keyword_loc + case location + when nil + nil + when Location + location + else + @do_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the do_keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_do_keyword_loc(repository) + repository.enter(node_id, :do_keyword_loc) unless @do_keyword_loc.nil? + end + + # attr_reader closing_loc: Location? + def closing_loc + location = @closing_loc + case location + when nil + nil + when Location + location + else + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) unless @closing_loc.nil? + end + + # attr_reader predicate: Prism::node + attr_reader :predicate + + # attr_reader statements: StatementsNode? + attr_reader :statements + + # def keyword: () -> String + def keyword + keyword_loc.slice + end + + # def do_keyword: () -> String? + def do_keyword + do_keyword_loc&.slice + end + + # def closing: () -> String? + def closing + closing_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :while_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :while_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(WhileNode) && + (flags === other.flags) && + (keyword_loc.nil? == other.keyword_loc.nil?) && + (do_keyword_loc.nil? == other.do_keyword_loc.nil?) && + (closing_loc.nil? == other.closing_loc.nil?) && + (predicate === other.predicate) && + (statements === other.statements) + end + end + + # Represents an xstring literal with no interpolation. + # + # `foo` + # ^^^^^ + class XStringNode < Node + # Initialize a new XStringNode node. + def initialize(source, node_id, location, flags, opening_loc, content_loc, closing_loc, unescaped) + @source = source + @node_id = node_id + @location = location + @flags = flags + @opening_loc = opening_loc + @content_loc = content_loc + @closing_loc = closing_loc + @unescaped = unescaped + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_x_string_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + [] + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [opening_loc, content_loc, closing_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?content_loc: Location, ?closing_loc: Location, ?unescaped: String) -> XStringNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, content_loc: self.content_loc, closing_loc: self.closing_loc, unescaped: self.unescaped) + XStringNode.new(source, node_id, location, flags, opening_loc, content_loc, closing_loc, unescaped) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location, content_loc: Location, closing_loc: Location, unescaped: String } + def deconstruct_keys(keys) + { node_id: node_id, location: location, opening_loc: opening_loc, content_loc: content_loc, closing_loc: closing_loc, unescaped: unescaped } + end + + # def forced_utf8_encoding?: () -> bool + def forced_utf8_encoding? + flags.anybits?(EncodingFlags::FORCED_UTF8_ENCODING) + end + + # def forced_binary_encoding?: () -> bool + def forced_binary_encoding? + flags.anybits?(EncodingFlags::FORCED_BINARY_ENCODING) + end + + # attr_reader opening_loc: Location + def opening_loc + location = @opening_loc + return location if location.is_a?(Location) + @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the opening_loc location using the given saved source so that + # it can be retrieved later. + def save_opening_loc(repository) + repository.enter(node_id, :opening_loc) + end + + # attr_reader content_loc: Location + def content_loc + location = @content_loc + return location if location.is_a?(Location) + @content_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the content_loc location using the given saved source so that + # it can be retrieved later. + def save_content_loc(repository) + repository.enter(node_id, :content_loc) + end + + # attr_reader closing_loc: Location + def closing_loc + location = @closing_loc + return location if location.is_a?(Location) + @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the closing_loc location using the given saved source so that + # it can be retrieved later. + def save_closing_loc(repository) + repository.enter(node_id, :closing_loc) + end + + # attr_reader unescaped: String + attr_reader :unescaped + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def content: () -> String + def content + content_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :x_string_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :x_string_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(XStringNode) && + (flags === other.flags) && + (opening_loc.nil? == other.opening_loc.nil?) && + (content_loc.nil? == other.content_loc.nil?) && + (closing_loc.nil? == other.closing_loc.nil?) && + (unescaped === other.unescaped) + end + end + + # Represents the use of the `yield` keyword. + # + # yield 1 + # ^^^^^^^ + class YieldNode < Node + # Initialize a new YieldNode node. + def initialize(source, node_id, location, flags, keyword_loc, lparen_loc, arguments, rparen_loc) + @source = source + @node_id = node_id + @location = location + @flags = flags + @keyword_loc = keyword_loc + @lparen_loc = lparen_loc + @arguments = arguments + @rparen_loc = rparen_loc + end + + # def accept: (Visitor visitor) -> void + def accept(visitor) + visitor.visit_yield_node(self) + end + + # def child_nodes: () -> Array[nil | Node] + def child_nodes + [arguments] + end + + # def compact_child_nodes: () -> Array[Node] + def compact_child_nodes + compact = [] #: Array[Prism::node] + compact << arguments if arguments + compact + end + + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [keyword_loc, *lparen_loc, *arguments, *rparen_loc] #: Array[Prism::node | Location] + end + + # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?lparen_loc: Location?, ?arguments: ArgumentsNode?, ?rparen_loc: Location?) -> YieldNode + def copy(node_id: self.node_id, location: self.location, flags: self.flags, keyword_loc: self.keyword_loc, lparen_loc: self.lparen_loc, arguments: self.arguments, rparen_loc: self.rparen_loc) + YieldNode.new(source, node_id, location, flags, keyword_loc, lparen_loc, arguments, rparen_loc) + end + + # def deconstruct: () -> Array[nil | Node] + alias deconstruct child_nodes + + # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, keyword_loc: Location, lparen_loc: Location?, arguments: ArgumentsNode?, rparen_loc: Location? } + def deconstruct_keys(keys) + { node_id: node_id, location: location, keyword_loc: keyword_loc, lparen_loc: lparen_loc, arguments: arguments, rparen_loc: rparen_loc } + end + + # attr_reader keyword_loc: Location + def keyword_loc + location = @keyword_loc + return location if location.is_a?(Location) + @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Save the keyword_loc location using the given saved source so that + # it can be retrieved later. + def save_keyword_loc(repository) + repository.enter(node_id, :keyword_loc) + end + + # attr_reader lparen_loc: Location? + def lparen_loc + location = @lparen_loc + case location + when nil + nil + when Location + location + else + @lparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the lparen_loc location using the given saved source so that + # it can be retrieved later. + def save_lparen_loc(repository) + repository.enter(node_id, :lparen_loc) unless @lparen_loc.nil? + end + + # attr_reader arguments: ArgumentsNode? + attr_reader :arguments + + # attr_reader rparen_loc: Location? + def rparen_loc + location = @rparen_loc + case location + when nil + nil + when Location + location + else + @rparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + end + + # Save the rparen_loc location using the given saved source so that + # it can be retrieved later. + def save_rparen_loc(repository) + repository.enter(node_id, :rparen_loc) unless @rparen_loc.nil? + end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end + + # def lparen: () -> String? + def lparen + lparen_loc&.slice + end + + # def rparen: () -> String? + def rparen + rparen_loc&.slice + end + + # def inspect -> String + def inspect + InspectVisitor.compose(self) + end + + # Return a symbol representation of this node type. See `Node#type`. + def type + :yield_node + end + + # Return a symbol representation of this node type. See `Node::type`. + def self.type + :yield_node + end + + # Implements case-equality for the node. This is effectively == but without + # comparing the value of locations. Locations are checked only for presence. + def ===(other) + other.is_a?(YieldNode) && + (keyword_loc.nil? == other.keyword_loc.nil?) && + (lparen_loc.nil? == other.lparen_loc.nil?) && + (arguments === other.arguments) && + (rparen_loc.nil? == other.rparen_loc.nil?) + end + end + + # Flags for arguments nodes. + module ArgumentsNodeFlags + # if the arguments contain forwarding + CONTAINS_FORWARDING = 1 << 2 + + # if the arguments contain keywords + CONTAINS_KEYWORDS = 1 << 3 + + # if the arguments contain a keyword splat + CONTAINS_KEYWORD_SPLAT = 1 << 4 + + # if the arguments contain a splat + CONTAINS_SPLAT = 1 << 5 + + # if the arguments contain multiple splats + CONTAINS_MULTIPLE_SPLATS = 1 << 6 + end + + # Flags for array nodes. + module ArrayNodeFlags + # if array contains splat nodes + CONTAINS_SPLAT = 1 << 2 + end + + # Flags for call nodes. + module CallNodeFlags + # &. operator + SAFE_NAVIGATION = 1 << 2 + + # a call that could have been a local variable + VARIABLE_CALL = 1 << 3 + + # a call that is an attribute write, so the value being written should be returned + ATTRIBUTE_WRITE = 1 << 4 + + # a call that ignores method visibility + IGNORE_VISIBILITY = 1 << 5 + end + + # Flags for nodes that have unescaped content. + module EncodingFlags + # internal bytes forced the encoding to UTF-8 + FORCED_UTF8_ENCODING = 1 << 2 + + # internal bytes forced the encoding to binary + FORCED_BINARY_ENCODING = 1 << 3 + end + + # Flags for integer nodes that correspond to the base of the integer. + module IntegerBaseFlags + # 0b prefix + BINARY = 1 << 2 + + # 0d or no prefix + DECIMAL = 1 << 3 + + # 0o or 0 prefix + OCTAL = 1 << 4 + + # 0x prefix + HEXADECIMAL = 1 << 5 + end + + # Flags for interpolated string nodes that indicated mutability if they are also marked as literals. + module InterpolatedStringNodeFlags + # frozen by virtue of a `frozen_string_literal: true` comment or `--enable-frozen-string-literal`; only for adjacent string literals like `'a' 'b'` + FROZEN = 1 << 2 + + # mutable by virtue of a `frozen_string_literal: false` comment or `--disable-frozen-string-literal`; only for adjacent string literals like `'a' 'b'` + MUTABLE = 1 << 3 + end + + # Flags for keyword hash nodes. + module KeywordHashNodeFlags + # a keyword hash which only has `AssocNode` elements all with symbol keys, which means the elements can be treated as keyword arguments + SYMBOL_KEYS = 1 << 2 + end + + # Flags for while and until loop nodes. + module LoopFlags + # a loop after a begin statement, so the body is executed first before the condition + BEGIN_MODIFIER = 1 << 2 + end + + # Flags for parameter nodes. + module ParameterFlags + # a parameter name that has been repeated in the method signature + REPEATED_PARAMETER = 1 << 2 + end + + # Flags for parentheses nodes. + module ParenthesesNodeFlags + # parentheses that contain multiple potentially void statements + MULTIPLE_STATEMENTS = 1 << 2 + end + + # Flags for range and flip-flop nodes. + module RangeFlags + # ... operator + EXCLUDE_END = 1 << 2 + end + + # Flags for regular expression and match last line nodes. + module RegularExpressionFlags + # i - ignores the case of characters when matching + IGNORE_CASE = 1 << 2 + + # x - ignores whitespace and allows comments in regular expressions + EXTENDED = 1 << 3 + + # m - allows $ to match the end of lines within strings + MULTI_LINE = 1 << 4 + + # o - only interpolates values into the regular expression once + ONCE = 1 << 5 + + # e - forces the EUC-JP encoding + EUC_JP = 1 << 6 + + # n - forces the ASCII-8BIT encoding + ASCII_8BIT = 1 << 7 + + # s - forces the Windows-31J encoding + WINDOWS_31J = 1 << 8 + + # u - forces the UTF-8 encoding + UTF_8 = 1 << 9 + + # internal bytes forced the encoding to UTF-8 + FORCED_UTF8_ENCODING = 1 << 10 + + # internal bytes forced the encoding to binary + FORCED_BINARY_ENCODING = 1 << 11 + + # internal bytes forced the encoding to US-ASCII + FORCED_US_ASCII_ENCODING = 1 << 12 + end + + # Flags for shareable constant nodes. + module ShareableConstantNodeFlags + # constant writes that should be modified with shareable constant value literal + LITERAL = 1 << 2 + + # constant writes that should be modified with shareable constant value experimental everything + EXPERIMENTAL_EVERYTHING = 1 << 3 + + # constant writes that should be modified with shareable constant value experimental copy + EXPERIMENTAL_COPY = 1 << 4 + end + + # Flags for string nodes. + module StringFlags + # internal bytes forced the encoding to UTF-8 + FORCED_UTF8_ENCODING = 1 << 2 + + # internal bytes forced the encoding to binary + FORCED_BINARY_ENCODING = 1 << 3 + + # frozen by virtue of a `frozen_string_literal: true` comment or `--enable-frozen-string-literal` + FROZEN = 1 << 4 + + # mutable by virtue of a `frozen_string_literal: false` comment or `--disable-frozen-string-literal` + MUTABLE = 1 << 5 + end + + # Flags for symbol nodes. + module SymbolFlags + # internal bytes forced the encoding to UTF-8 + FORCED_UTF8_ENCODING = 1 << 2 + + # internal bytes forced the encoding to binary + FORCED_BINARY_ENCODING = 1 << 3 + + # internal bytes forced the encoding to US-ASCII + FORCED_US_ASCII_ENCODING = 1 << 4 + end + + # The flags that are common to all nodes. + module NodeFlags + # A flag to indicate that the node is a candidate to emit a :line event + # through tracepoint when compiled. + NEWLINE = 1 + + # A flag to indicate that the value that the node represents is a value that + # can be determined at parse-time. + STATIC_LITERAL = 2 + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/node_ext.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/node_ext.rb new file mode 100644 index 00000000..4dfcebd6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/node_ext.rb @@ -0,0 +1,508 @@ +# frozen_string_literal: true + +# Here we are reopening the prism module to provide methods on nodes that aren't +# templated and are meant as convenience methods. +module Prism + class Node + def deprecated(*replacements) # :nodoc: + location = caller_locations(1, 1) + location = location[0].label if location + suggest = replacements.map { |replacement| "#{self.class}##{replacement}" } + + warn(<<~MSG, category: :deprecated) + [deprecation]: #{self.class}##{location} is deprecated and will be \ + removed in the next major version. Use #{suggest.join("/")} instead. + #{(caller(1, 3) || []).join("\n")} + MSG + end + end + + module RegularExpressionOptions # :nodoc: + # Returns a numeric value that represents the flags that were used to create + # the regular expression. + def options + o = 0 + o |= Regexp::IGNORECASE if flags.anybits?(RegularExpressionFlags::IGNORE_CASE) + o |= Regexp::EXTENDED if flags.anybits?(RegularExpressionFlags::EXTENDED) + o |= Regexp::MULTILINE if flags.anybits?(RegularExpressionFlags::MULTI_LINE) + o |= Regexp::FIXEDENCODING if flags.anybits?(RegularExpressionFlags::EUC_JP | RegularExpressionFlags::WINDOWS_31J | RegularExpressionFlags::UTF_8) + o |= Regexp::NOENCODING if flags.anybits?(RegularExpressionFlags::ASCII_8BIT) + o + end + end + + class InterpolatedMatchLastLineNode < Node + include RegularExpressionOptions + end + + class InterpolatedRegularExpressionNode < Node + include RegularExpressionOptions + end + + class MatchLastLineNode < Node + include RegularExpressionOptions + end + + class RegularExpressionNode < Node + include RegularExpressionOptions + end + + private_constant :RegularExpressionOptions + + module HeredocQuery # :nodoc: + # Returns true if this node was represented as a heredoc in the source code. + def heredoc? + opening&.start_with?("<<") + end + end + + class InterpolatedStringNode < Node + include HeredocQuery + end + + class InterpolatedXStringNode < Node + include HeredocQuery + end + + class StringNode < Node + include HeredocQuery + + # Occasionally it's helpful to treat a string as if it were interpolated so + # that there's a consistent interface for working with strings. + def to_interpolated + InterpolatedStringNode.new( + source, + -1, + location, + frozen? ? InterpolatedStringNodeFlags::FROZEN : 0, + opening_loc, + [copy(location: content_loc, opening_loc: nil, closing_loc: nil)], + closing_loc + ) + end + end + + class XStringNode < Node + include HeredocQuery + + # Occasionally it's helpful to treat a string as if it were interpolated so + # that there's a consistent interface for working with strings. + def to_interpolated + InterpolatedXStringNode.new( + source, + -1, + location, + flags, + opening_loc, + [StringNode.new(source, node_id, content_loc, 0, nil, content_loc, nil, unescaped)], + closing_loc + ) + end + end + + private_constant :HeredocQuery + + class ImaginaryNode < Node + # Returns the value of the node as a Ruby Complex. + def value + Complex(0, numeric.value) + end + end + + class RationalNode < Node + # Returns the value of the node as a Ruby Rational. + def value + Rational(numerator, denominator) + end + + # Returns the value of the node as an IntegerNode or a FloatNode. This + # method is deprecated in favor of #value or #numerator/#denominator. + def numeric + deprecated("value", "numerator", "denominator") + + if denominator == 1 + IntegerNode.new(source, -1, location.chop, flags, numerator) + else + FloatNode.new(source, -1, location.chop, 0, numerator.to_f / denominator) + end + end + end + + class ConstantReadNode < Node + # Returns the list of parts for the full name of this constant. + # For example: [:Foo] + def full_name_parts + [name] + end + + # Returns the full name of this constant. For example: "Foo" + def full_name + name.to_s + end + end + + class ConstantWriteNode < Node + # Returns the list of parts for the full name of this constant. + # For example: [:Foo] + def full_name_parts + [name] + end + + # Returns the full name of this constant. For example: "Foo" + def full_name + name.to_s + end + end + + class ConstantPathNode < Node + # An error class raised when dynamic parts are found while computing a + # constant path's full name. For example: + # Foo::Bar::Baz -> does not raise because all parts of the constant path are + # simple constants + # var::Bar::Baz -> raises because the first part of the constant path is a + # local variable + class DynamicPartsInConstantPathError < StandardError; end + + # An error class raised when missing nodes are found while computing a + # constant path's full name. For example: + # Foo:: -> raises because the constant path is missing the last part + class MissingNodesInConstantPathError < StandardError; end + + # Returns the list of parts for the full name of this constant path. + # For example: [:Foo, :Bar] + def full_name_parts + parts = [] #: Array[Symbol] + current = self #: node? + + while current.is_a?(ConstantPathNode) + name = current.name + if name.nil? + raise MissingNodesInConstantPathError, "Constant path contains missing nodes. Cannot compute full name" + end + + parts.unshift(name) + current = current.parent + end + + if !current.is_a?(ConstantReadNode) && !current.nil? + raise DynamicPartsInConstantPathError, "Constant path contains dynamic parts. Cannot compute full name" + end + + parts.unshift(current&.name || :"") + end + + # Returns the full name of this constant path. For example: "Foo::Bar" + def full_name + full_name_parts.join("::") + end + + # Previously, we had a child node on this class that contained either a + # constant read or a missing node. To not cause a breaking change, we + # continue to supply that API. + def child + deprecated("name", "name_loc") + + if name + ConstantReadNode.new(source, -1, name_loc, 0, name) + else + MissingNode.new(source, -1, location, 0) + end + end + end + + class ConstantPathTargetNode < Node + # Returns the list of parts for the full name of this constant path. + # For example: [:Foo, :Bar] + def full_name_parts + parts = + case parent + when ConstantPathNode, ConstantReadNode + parent.full_name_parts + when nil + [:""] + else + # e.g. self::Foo, (var)::Bar = baz + raise ConstantPathNode::DynamicPartsInConstantPathError, "Constant target path contains dynamic parts. Cannot compute full name" + end + + if name.nil? + raise ConstantPathNode::MissingNodesInConstantPathError, "Constant target path contains missing nodes. Cannot compute full name" + end + + parts.push(name) + end + + # Returns the full name of this constant path. For example: "Foo::Bar" + def full_name + full_name_parts.join("::") + end + + # Previously, we had a child node on this class that contained either a + # constant read or a missing node. To not cause a breaking change, we + # continue to supply that API. + def child + deprecated("name", "name_loc") + + if name + ConstantReadNode.new(source, -1, name_loc, 0, name) + else + MissingNode.new(source, -1, location, 0) + end + end + end + + class ConstantTargetNode < Node + # Returns the list of parts for the full name of this constant. + # For example: [:Foo] + def full_name_parts + [name] + end + + # Returns the full name of this constant. For example: "Foo" + def full_name + name.to_s + end + end + + class ParametersNode < Node + # Mirrors the Method#parameters method. + def signature + names = [] #: Array[[Symbol, Symbol] | [Symbol]] + + requireds.each do |param| + names << (param.is_a?(MultiTargetNode) ? [:req] : [:req, param.name]) + end + + optionals.each { |param| names << [:opt, param.name] } + + if rest && rest.is_a?(RestParameterNode) + names << [:rest, rest.name || :*] + end + + posts.each do |param| + case param + when MultiTargetNode + names << [:req] + when NoKeywordsParameterNode, KeywordRestParameterNode, ForwardingParameterNode + # Invalid syntax, e.g. "def f(**nil, ...)" moves the NoKeywordsParameterNode to posts + raise "Invalid syntax" + else + names << [:req, param.name] + end + end + + # Regardless of the order in which the keywords were defined, the required + # keywords always come first followed by the optional keywords. + keyopt = [] #: Array[OptionalKeywordParameterNode] + keywords.each do |param| + if param.is_a?(OptionalKeywordParameterNode) + keyopt << param + else + names << [:keyreq, param.name] + end + end + + keyopt.each { |param| names << [:key, param.name] } + + case keyword_rest + when ForwardingParameterNode + names.concat([[:rest, :*], [:keyrest, :**], [:block, :&]]) + when KeywordRestParameterNode + names << [:keyrest, keyword_rest.name || :**] + when NoKeywordsParameterNode + names << [:nokey] + end + + names << [:block, block.name || :&] if block + names + end + end + + class CallNode < Node + # When a call node has the attribute_write flag set, it means that the call + # is using the attribute write syntax. This is either a method call to []= + # or a method call to a method that ends with =. Either way, the = sign is + # present in the source. + # + # Prism returns the message_loc _without_ the = sign attached, because there + # can be any amount of space between the message and the = sign. However, + # sometimes you want the location of the full message including the inner + # space and the = sign. This method provides that. + def full_message_loc + attribute_write? ? message_loc&.adjoin("=") : message_loc + end + end + + class CallOperatorWriteNode < Node + # Returns the binary operator used to modify the receiver. This method is + # deprecated in favor of #binary_operator. + def operator + deprecated("binary_operator") + binary_operator + end + + # Returns the location of the binary operator used to modify the receiver. + # This method is deprecated in favor of #binary_operator_loc. + def operator_loc + deprecated("binary_operator_loc") + binary_operator_loc + end + end + + class ClassVariableOperatorWriteNode < Node + # Returns the binary operator used to modify the receiver. This method is + # deprecated in favor of #binary_operator. + def operator + deprecated("binary_operator") + binary_operator + end + + # Returns the location of the binary operator used to modify the receiver. + # This method is deprecated in favor of #binary_operator_loc. + def operator_loc + deprecated("binary_operator_loc") + binary_operator_loc + end + end + + class ConstantOperatorWriteNode < Node + # Returns the binary operator used to modify the receiver. This method is + # deprecated in favor of #binary_operator. + def operator + deprecated("binary_operator") + binary_operator + end + + # Returns the location of the binary operator used to modify the receiver. + # This method is deprecated in favor of #binary_operator_loc. + def operator_loc + deprecated("binary_operator_loc") + binary_operator_loc + end + end + + class ConstantPathOperatorWriteNode < Node + # Returns the binary operator used to modify the receiver. This method is + # deprecated in favor of #binary_operator. + def operator + deprecated("binary_operator") + binary_operator + end + + # Returns the location of the binary operator used to modify the receiver. + # This method is deprecated in favor of #binary_operator_loc. + def operator_loc + deprecated("binary_operator_loc") + binary_operator_loc + end + end + + class GlobalVariableOperatorWriteNode < Node + # Returns the binary operator used to modify the receiver. This method is + # deprecated in favor of #binary_operator. + def operator + deprecated("binary_operator") + binary_operator + end + + # Returns the location of the binary operator used to modify the receiver. + # This method is deprecated in favor of #binary_operator_loc. + def operator_loc + deprecated("binary_operator_loc") + binary_operator_loc + end + end + + class IndexOperatorWriteNode < Node + # Returns the binary operator used to modify the receiver. This method is + # deprecated in favor of #binary_operator. + def operator + deprecated("binary_operator") + binary_operator + end + + # Returns the location of the binary operator used to modify the receiver. + # This method is deprecated in favor of #binary_operator_loc. + def operator_loc + deprecated("binary_operator_loc") + binary_operator_loc + end + end + + class InstanceVariableOperatorWriteNode < Node + # Returns the binary operator used to modify the receiver. This method is + # deprecated in favor of #binary_operator. + def operator + deprecated("binary_operator") + binary_operator + end + + # Returns the location of the binary operator used to modify the receiver. + # This method is deprecated in favor of #binary_operator_loc. + def operator_loc + deprecated("binary_operator_loc") + binary_operator_loc + end + end + + class LocalVariableOperatorWriteNode < Node + # Returns the binary operator used to modify the receiver. This method is + # deprecated in favor of #binary_operator. + def operator + deprecated("binary_operator") + binary_operator + end + + # Returns the location of the binary operator used to modify the receiver. + # This method is deprecated in favor of #binary_operator_loc. + def operator_loc + deprecated("binary_operator_loc") + binary_operator_loc + end + end + + class CaseMatchNode < Node + # Returns the else clause of the case match node. This method is deprecated + # in favor of #else_clause. + def consequent + deprecated("else_clause") + else_clause + end + end + + class CaseNode < Node + # Returns the else clause of the case node. This method is deprecated in + # favor of #else_clause. + def consequent + deprecated("else_clause") + else_clause + end + end + + class IfNode < Node + # Returns the subsequent if/elsif/else clause of the if node. This method is + # deprecated in favor of #subsequent. + def consequent + deprecated("subsequent") + subsequent + end + end + + class RescueNode < Node + # Returns the subsequent rescue clause of the rescue node. This method is + # deprecated in favor of #subsequent. + def consequent + deprecated("subsequent") + subsequent + end + end + + class UnlessNode < Node + # Returns the else clause of the unless node. This method is deprecated in + # favor of #else_clause. + def consequent + deprecated("else_clause") + else_clause + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/pack.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/pack.rb new file mode 100644 index 00000000..c0de8ab8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/pack.rb @@ -0,0 +1,228 @@ +# frozen_string_literal: true +# typed: ignore + +module Prism + # A parser for the pack template language. + module Pack + %i[ + SPACE + COMMENT + INTEGER + UTF8 + BER + FLOAT + STRING_SPACE_PADDED + STRING_NULL_PADDED + STRING_NULL_TERMINATED + STRING_MSB + STRING_LSB + STRING_HEX_HIGH + STRING_HEX_LOW + STRING_UU + STRING_MIME + STRING_BASE64 + STRING_FIXED + STRING_POINTER + MOVE + BACK + NULL + + UNSIGNED + SIGNED + SIGNED_NA + + AGNOSTIC_ENDIAN + LITTLE_ENDIAN + BIG_ENDIAN + NATIVE_ENDIAN + ENDIAN_NA + + SIZE_SHORT + SIZE_INT + SIZE_LONG + SIZE_LONG_LONG + SIZE_8 + SIZE_16 + SIZE_32 + SIZE_64 + SIZE_P + SIZE_NA + + LENGTH_FIXED + LENGTH_MAX + LENGTH_RELATIVE + LENGTH_NA + ].each do |const| + const_set(const, const) + end + + # A directive in the pack template language. + class Directive + # A symbol representing the version of Ruby. + attr_reader :version + + # A symbol representing whether or not we are packing or unpacking. + attr_reader :variant + + # A byteslice of the source string that this directive represents. + attr_reader :source + + # The type of the directive. + attr_reader :type + + # The type of signedness of the directive. + attr_reader :signed + + # The type of endianness of the directive. + attr_reader :endian + + # The size of the directive. + attr_reader :size + + # The length type of this directive (used for integers). + attr_reader :length_type + + # The length of this directive (used for integers). + attr_reader :length + + # Initialize a new directive with the given values. + def initialize(version, variant, source, type, signed, endian, size, length_type, length) + @version = version + @variant = variant + @source = source + @type = type + @signed = signed + @endian = endian + @size = size + @length_type = length_type + @length = length + end + + # The descriptions of the various types of endianness. + ENDIAN_DESCRIPTIONS = { + AGNOSTIC_ENDIAN: "agnostic", + LITTLE_ENDIAN: "little-endian (VAX)", + BIG_ENDIAN: "big-endian (network)", + NATIVE_ENDIAN: "native-endian", + ENDIAN_NA: "n/a" + } + + # The descriptions of the various types of signedness. + SIGNED_DESCRIPTIONS = { + UNSIGNED: "unsigned", + SIGNED: "signed", + SIGNED_NA: "n/a" + } + + # The descriptions of the various types of sizes. + SIZE_DESCRIPTIONS = { + SIZE_SHORT: "short", + SIZE_INT: "int-width", + SIZE_LONG: "long", + SIZE_LONG_LONG: "long long", + SIZE_8: "8-bit", + SIZE_16: "16-bit", + SIZE_32: "32-bit", + SIZE_64: "64-bit", + SIZE_P: "pointer-width" + } + + # Provide a human-readable description of the directive. + def describe + case type + when SPACE + "whitespace" + when COMMENT + "comment" + when INTEGER + if size == SIZE_8 + base = "#{SIGNED_DESCRIPTIONS[signed]} #{SIZE_DESCRIPTIONS[size]} integer" + else + base = "#{SIGNED_DESCRIPTIONS[signed]} #{SIZE_DESCRIPTIONS[size]} #{ENDIAN_DESCRIPTIONS[endian]} integer" + end + case length_type + when LENGTH_FIXED + if length > 1 + base + ", x#{length}" + else + base + end + when LENGTH_MAX + base + ", as many as possible" + else + raise + end + when UTF8 + "UTF-8 character" + when BER + "BER-compressed integer" + when FLOAT + "#{SIZE_DESCRIPTIONS[size]} #{ENDIAN_DESCRIPTIONS[endian]} float" + when STRING_SPACE_PADDED + "arbitrary binary string (space padded)" + when STRING_NULL_PADDED + "arbitrary binary string (null padded, count is width)" + when STRING_NULL_TERMINATED + "arbitrary binary string (null padded, count is width), except that null is added with *" + when STRING_MSB + "bit string (MSB first)" + when STRING_LSB + "bit string (LSB first)" + when STRING_HEX_HIGH + "hex string (high nibble first)" + when STRING_HEX_LOW + "hex string (low nibble first)" + when STRING_UU + "UU-encoded string" + when STRING_MIME + "quoted printable, MIME encoding" + when STRING_BASE64 + "base64 encoded string" + when STRING_FIXED + "pointer to a structure (fixed-length string)" + when STRING_POINTER + "pointer to a null-terminated string" + when MOVE + "move to absolute position" + when BACK + "back up a byte" + when NULL + "null byte" + else + raise + end + end + end + + # The result of parsing a pack template. + class Format + # A list of the directives in the template. + attr_reader :directives + + # The encoding of the template. + attr_reader :encoding + + # Create a new Format with the given directives and encoding. + def initialize(directives, encoding) + @directives = directives + @encoding = encoding + end + + # Provide a human-readable description of the format. + def describe + source_width = directives.map { |d| d.source.inspect.length }.max + directive_lines = directives.map do |directive| + if directive.type == SPACE + source = directive.source.inspect + else + source = directive.source + end + # @type var source_width: Integer + " #{source.ljust(source_width)} #{directive.describe}" + end + + (["Directives:"] + directive_lines + ["Encoding:", " #{encoding}"]).join("\n") + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/parse_result.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/parse_result.rb new file mode 100644 index 00000000..9a3e7c5b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/parse_result.rb @@ -0,0 +1,910 @@ +# frozen_string_literal: true + +module Prism + # This represents a source of Ruby code that has been parsed. It is used in + # conjunction with locations to allow them to resolve line numbers and source + # ranges. + class Source + # Create a new source object with the given source code. This method should + # be used instead of `new` and it will return either a `Source` or a + # specialized and more performant `ASCIISource` if no multibyte characters + # are present in the source code. + def self.for(source, start_line = 1, offsets = []) + if source.ascii_only? + ASCIISource.new(source, start_line, offsets) + elsif source.encoding == Encoding::BINARY + source.force_encoding(Encoding::UTF_8) + + if source.valid_encoding? + new(source, start_line, offsets) + else + # This is an extremely niche use case where the file is marked as + # binary, contains multi-byte characters, and those characters are not + # valid UTF-8. In this case we'll mark it as binary and fall back to + # treating everything as a single-byte character. This _may_ cause + # problems when asking for code units, but it appears to be the + # cleanest solution at the moment. + source.force_encoding(Encoding::BINARY) + ASCIISource.new(source, start_line, offsets) + end + else + new(source, start_line, offsets) + end + end + + # The source code that this source object represents. + attr_reader :source + + # The line number where this source starts. + attr_reader :start_line + + # The list of newline byte offsets in the source code. + attr_reader :offsets + + # Create a new source object with the given source code. + def initialize(source, start_line = 1, offsets = []) + @source = source + @start_line = start_line # set after parsing is done + @offsets = offsets # set after parsing is done + end + + # Replace the value of start_line with the given value. + def replace_start_line(start_line) + @start_line = start_line + end + + # Replace the value of offsets with the given value. + def replace_offsets(offsets) + @offsets.replace(offsets) + end + + # Returns the encoding of the source code, which is set by parameters to the + # parser or by the encoding magic comment. + def encoding + source.encoding + end + + # Returns the lines of the source code as an array of strings. + def lines + source.lines + end + + # Perform a byteslice on the source code using the given byte offset and + # byte length. + def slice(byte_offset, length) + source.byteslice(byte_offset, length) or raise + end + + # Binary search through the offsets to find the line number for the given + # byte offset. + def line(byte_offset) + start_line + find_line(byte_offset) + end + + # Return the byte offset of the start of the line corresponding to the given + # byte offset. + def line_start(byte_offset) + offsets[find_line(byte_offset)] + end + + # Returns the byte offset of the end of the line corresponding to the given + # byte offset. + def line_end(byte_offset) + offsets[find_line(byte_offset) + 1] || source.bytesize + end + + # Return the column number for the given byte offset. + def column(byte_offset) + byte_offset - line_start(byte_offset) + end + + # Return the character offset for the given byte offset. + def character_offset(byte_offset) + (source.byteslice(0, byte_offset) or raise).length + end + + # Return the column number in characters for the given byte offset. + def character_column(byte_offset) + character_offset(byte_offset) - character_offset(line_start(byte_offset)) + end + + # Returns the offset from the start of the file for the given byte offset + # counting in code units for the given encoding. + # + # This method is tested with UTF-8, UTF-16, and UTF-32. If there is the + # concept of code units that differs from the number of characters in other + # encodings, it is not captured here. + # + # We purposefully replace invalid and undefined characters with replacement + # characters in this conversion. This happens for two reasons. First, it's + # possible that the given byte offset will not occur on a character + # boundary. Second, it's possible that the source code will contain a + # character that has no equivalent in the given encoding. + def code_units_offset(byte_offset, encoding) + byteslice = (source.byteslice(0, byte_offset) or raise).encode(encoding, invalid: :replace, undef: :replace) + + if encoding == Encoding::UTF_16LE || encoding == Encoding::UTF_16BE + byteslice.bytesize / 2 + else + byteslice.length + end + end + + # Generate a cache that targets a specific encoding for calculating code + # unit offsets. + def code_units_cache(encoding) + CodeUnitsCache.new(source, encoding) + end + + # Returns the column number in code units for the given encoding for the + # given byte offset. + def code_units_column(byte_offset, encoding) + code_units_offset(byte_offset, encoding) - code_units_offset(line_start(byte_offset), encoding) + end + + # Freeze this object and the objects it contains. + def deep_freeze + source.freeze + offsets.freeze + freeze + end + + private + + # Binary search through the offsets to find the line number for the given + # byte offset. + def find_line(byte_offset) + left = 0 + right = offsets.length - 1 + + while left <= right + mid = left + (right - left) / 2 + return mid if (offset = offsets[mid]) == byte_offset + + if offset < byte_offset + left = mid + 1 + else + right = mid - 1 + end + end + + left - 1 + end + end + + # A cache that can be used to quickly compute code unit offsets from byte + # offsets. It purposefully provides only a single #[] method to access the + # cache in order to minimize surface area. + # + # Note that there are some known issues here that may or may not be addressed + # in the future: + # + # * The first is that there are issues when the cache computes values that are + # not on character boundaries. This can result in subsequent computations + # being off by one or more code units. + # * The second is that this cache is currently unbounded. In theory we could + # introduce some kind of LRU cache to limit the number of entries, but this + # has not yet been implemented. + # + class CodeUnitsCache + class UTF16Counter # :nodoc: + def initialize(source, encoding) + @source = source + @encoding = encoding + end + + def count(byte_offset, byte_length) + @source.byteslice(byte_offset, byte_length).encode(@encoding, invalid: :replace, undef: :replace).bytesize / 2 + end + end + + class LengthCounter # :nodoc: + def initialize(source, encoding) + @source = source + @encoding = encoding + end + + def count(byte_offset, byte_length) + @source.byteslice(byte_offset, byte_length).encode(@encoding, invalid: :replace, undef: :replace).length + end + end + + private_constant :UTF16Counter, :LengthCounter + + # Initialize a new cache with the given source and encoding. + def initialize(source, encoding) + @source = source + @counter = + if encoding == Encoding::UTF_16LE || encoding == Encoding::UTF_16BE + UTF16Counter.new(source, encoding) + else + LengthCounter.new(source, encoding) + end + + @cache = {} #: Hash[Integer, Integer] + @offsets = [] #: Array[Integer] + end + + # Retrieve the code units offset from the given byte offset. + def [](byte_offset) + @cache[byte_offset] ||= + if (index = @offsets.bsearch_index { |offset| offset > byte_offset }).nil? + @offsets << byte_offset + @counter.count(0, byte_offset) + elsif index == 0 + @offsets.unshift(byte_offset) + @counter.count(0, byte_offset) + else + @offsets.insert(index, byte_offset) + offset = @offsets[index - 1] + @cache[offset] + @counter.count(offset, byte_offset - offset) + end + end + end + + # Specialized version of Prism::Source for source code that includes ASCII + # characters only. This class is used to apply performance optimizations that + # cannot be applied to sources that include multibyte characters. + # + # In the extremely rare case that a source includes multi-byte characters but + # is marked as binary because of a magic encoding comment and it cannot be + # eagerly converted to UTF-8, this class will be used as well. This is because + # at that point we will treat everything as single-byte characters. + class ASCIISource < Source + # Return the character offset for the given byte offset. + def character_offset(byte_offset) + byte_offset + end + + # Return the column number in characters for the given byte offset. + def character_column(byte_offset) + byte_offset - line_start(byte_offset) + end + + # Returns the offset from the start of the file for the given byte offset + # counting in code units for the given encoding. + # + # This method is tested with UTF-8, UTF-16, and UTF-32. If there is the + # concept of code units that differs from the number of characters in other + # encodings, it is not captured here. + def code_units_offset(byte_offset, encoding) + byte_offset + end + + # Returns a cache that is the identity function in order to maintain the + # same interface. We can do this because code units are always equivalent to + # byte offsets for ASCII-only sources. + def code_units_cache(encoding) + ->(byte_offset) { byte_offset } + end + + # Specialized version of `code_units_column` that does not depend on + # `code_units_offset`, which is a more expensive operation. This is + # essentially the same as `Prism::Source#column`. + def code_units_column(byte_offset, encoding) + byte_offset - line_start(byte_offset) + end + end + + # This represents a location in the source. + class Location + # A Source object that is used to determine more information from the given + # offset and length. + attr_reader :source + protected :source + + # The byte offset from the beginning of the source where this location + # starts. + attr_reader :start_offset + + # The length of this location in bytes. + attr_reader :length + + # Create a new location object with the given source, start byte offset, and + # byte length. + def initialize(source, start_offset, length) + @source = source + @start_offset = start_offset + @length = length + + # These are used to store comments that are associated with this location. + # They are initialized to `nil` to save on memory when there are no + # comments to be attached and/or the comment-related APIs are not used. + @leading_comments = nil + @trailing_comments = nil + end + + # These are the comments that are associated with this location that exist + # before the start of this location. + def leading_comments + @leading_comments ||= [] + end + + # Attach a comment to the leading comments of this location. + def leading_comment(comment) + leading_comments << comment + end + + # These are the comments that are associated with this location that exist + # after the end of this location. + def trailing_comments + @trailing_comments ||= [] + end + + # Attach a comment to the trailing comments of this location. + def trailing_comment(comment) + trailing_comments << comment + end + + # Returns all comments that are associated with this location (both leading + # and trailing comments). + def comments + [*@leading_comments, *@trailing_comments] + end + + # Create a new location object with the given options. + def copy(source: self.source, start_offset: self.start_offset, length: self.length) + Location.new(source, start_offset, length) + end + + # Returns a new location that is the result of chopping off the last byte. + def chop + copy(length: length == 0 ? length : length - 1) + end + + # Returns a string representation of this location. + def inspect + "#" + end + + # Returns all of the lines of the source code associated with this location. + def source_lines + source.lines + end + + # The source code that this location represents. + def slice + source.slice(start_offset, length) + end + + # The source code that this location represents starting from the beginning + # of the line that this location starts on to the end of the line that this + # location ends on. + def slice_lines + line_start = source.line_start(start_offset) + line_end = source.line_end(end_offset) + source.slice(line_start, line_end - line_start) + end + + # The character offset from the beginning of the source where this location + # starts. + def start_character_offset + source.character_offset(start_offset) + end + + # The offset from the start of the file in code units of the given encoding. + def start_code_units_offset(encoding = Encoding::UTF_16LE) + source.code_units_offset(start_offset, encoding) + end + + # The start offset from the start of the file in code units using the given + # cache to fetch or calculate the value. + def cached_start_code_units_offset(cache) + cache[start_offset] + end + + # The byte offset from the beginning of the source where this location ends. + def end_offset + start_offset + length + end + + # The character offset from the beginning of the source where this location + # ends. + def end_character_offset + source.character_offset(end_offset) + end + + # The offset from the start of the file in code units of the given encoding. + def end_code_units_offset(encoding = Encoding::UTF_16LE) + source.code_units_offset(end_offset, encoding) + end + + # The end offset from the start of the file in code units using the given + # cache to fetch or calculate the value. + def cached_end_code_units_offset(cache) + cache[end_offset] + end + + # The line number where this location starts. + def start_line + source.line(start_offset) + end + + # The content of the line where this location starts before this location. + def start_line_slice + offset = source.line_start(start_offset) + source.slice(offset, start_offset - offset) + end + + # The line number where this location ends. + def end_line + source.line(end_offset) + end + + # The column number in bytes where this location starts from the start of + # the line. + def start_column + source.column(start_offset) + end + + # The column number in characters where this location ends from the start of + # the line. + def start_character_column + source.character_column(start_offset) + end + + # The column number in code units of the given encoding where this location + # starts from the start of the line. + def start_code_units_column(encoding = Encoding::UTF_16LE) + source.code_units_column(start_offset, encoding) + end + + # The start column in code units using the given cache to fetch or calculate + # the value. + def cached_start_code_units_column(cache) + cache[start_offset] - cache[source.line_start(start_offset)] + end + + # The column number in bytes where this location ends from the start of the + # line. + def end_column + source.column(end_offset) + end + + # The column number in characters where this location ends from the start of + # the line. + def end_character_column + source.character_column(end_offset) + end + + # The column number in code units of the given encoding where this location + # ends from the start of the line. + def end_code_units_column(encoding = Encoding::UTF_16LE) + source.code_units_column(end_offset, encoding) + end + + # The end column in code units using the given cache to fetch or calculate + # the value. + def cached_end_code_units_column(cache) + cache[end_offset] - cache[source.line_start(end_offset)] + end + + # Implement the hash pattern matching interface for Location. + def deconstruct_keys(keys) + { start_offset: start_offset, end_offset: end_offset } + end + + # Implement the pretty print interface for Location. + def pretty_print(q) + q.text("(#{start_line},#{start_column})-(#{end_line},#{end_column})") + end + + # Returns true if the given other location is equal to this location. + def ==(other) + Location === other && + other.start_offset == start_offset && + other.end_offset == end_offset + end + + # Returns a new location that stretches from this location to the given + # other location. Raises an error if this location is not before the other + # location or if they don't share the same source. + def join(other) + raise "Incompatible sources" if source != other.source + raise "Incompatible locations" if start_offset > other.start_offset + + Location.new(source, start_offset, other.end_offset - start_offset) + end + + # Join this location with the first occurrence of the string in the source + # that occurs after this location on the same line, and return the new + # location. This will raise an error if the string does not exist. + def adjoin(string) + line_suffix = source.slice(end_offset, source.line_end(end_offset) - end_offset) + + line_suffix_index = line_suffix.byteindex(string) + raise "Could not find #{string}" if line_suffix_index.nil? + + Location.new(source, start_offset, length + line_suffix_index + string.bytesize) + end + end + + # This represents a comment that was encountered during parsing. It is the + # base class for all comment types. + class Comment + # The location of this comment in the source. + attr_reader :location + + # Create a new comment object with the given location. + def initialize(location) + @location = location + end + + # Implement the hash pattern matching interface for Comment. + def deconstruct_keys(keys) + { location: location } + end + + # Returns the content of the comment by slicing it from the source code. + def slice + location.slice + end + end + + # InlineComment objects are the most common. They correspond to comments in + # the source file like this one that start with #. + class InlineComment < Comment + # Returns true if this comment happens on the same line as other code and + # false if the comment is by itself. + def trailing? + !location.start_line_slice.strip.empty? + end + + # Returns a string representation of this comment. + def inspect + "#" + end + end + + # EmbDocComment objects correspond to comments that are surrounded by =begin + # and =end. + class EmbDocComment < Comment + # This can only be true for inline comments. + def trailing? + false + end + + # Returns a string representation of this comment. + def inspect + "#" + end + end + + # This represents a magic comment that was encountered during parsing. + class MagicComment + # A Location object representing the location of the key in the source. + attr_reader :key_loc + + # A Location object representing the location of the value in the source. + attr_reader :value_loc + + # Create a new magic comment object with the given key and value locations. + def initialize(key_loc, value_loc) + @key_loc = key_loc + @value_loc = value_loc + end + + # Returns the key of the magic comment by slicing it from the source code. + def key + key_loc.slice + end + + # Returns the value of the magic comment by slicing it from the source code. + def value + value_loc.slice + end + + # Implement the hash pattern matching interface for MagicComment. + def deconstruct_keys(keys) + { key_loc: key_loc, value_loc: value_loc } + end + + # Returns a string representation of this magic comment. + def inspect + "#" + end + end + + # This represents an error that was encountered during parsing. + class ParseError + # The type of error. This is an _internal_ symbol that is used for + # communicating with translation layers. It is not meant to be public API. + attr_reader :type + + # The message associated with this error. + attr_reader :message + + # A Location object representing the location of this error in the source. + attr_reader :location + + # The level of this error. + attr_reader :level + + # Create a new error object with the given message and location. + def initialize(type, message, location, level) + @type = type + @message = message + @location = location + @level = level + end + + # Implement the hash pattern matching interface for ParseError. + def deconstruct_keys(keys) + { type: type, message: message, location: location, level: level } + end + + # Returns a string representation of this error. + def inspect + "#" + end + end + + # This represents a warning that was encountered during parsing. + class ParseWarning + # The type of warning. This is an _internal_ symbol that is used for + # communicating with translation layers. It is not meant to be public API. + attr_reader :type + + # The message associated with this warning. + attr_reader :message + + # A Location object representing the location of this warning in the source. + attr_reader :location + + # The level of this warning. + attr_reader :level + + # Create a new warning object with the given message and location. + def initialize(type, message, location, level) + @type = type + @message = message + @location = location + @level = level + end + + # Implement the hash pattern matching interface for ParseWarning. + def deconstruct_keys(keys) + { type: type, message: message, location: location, level: level } + end + + # Returns a string representation of this warning. + def inspect + "#" + end + end + + # This represents the result of a call to ::parse or ::parse_file. It contains + # the requested structure, any comments that were encounters, and any errors + # that were encountered. + class Result + # The list of comments that were encountered during parsing. + attr_reader :comments + + # The list of magic comments that were encountered during parsing. + attr_reader :magic_comments + + # An optional location that represents the location of the __END__ marker + # and the rest of the content of the file. This content is loaded into the + # DATA constant when the file being parsed is the main file being executed. + attr_reader :data_loc + + # The list of errors that were generated during parsing. + attr_reader :errors + + # The list of warnings that were generated during parsing. + attr_reader :warnings + + # A Source instance that represents the source code that was parsed. + attr_reader :source + + # Create a new result object with the given values. + def initialize(comments, magic_comments, data_loc, errors, warnings, source) + @comments = comments + @magic_comments = magic_comments + @data_loc = data_loc + @errors = errors + @warnings = warnings + @source = source + end + + # Implement the hash pattern matching interface for Result. + def deconstruct_keys(keys) + { comments: comments, magic_comments: magic_comments, data_loc: data_loc, errors: errors, warnings: warnings } + end + + # Returns the encoding of the source code that was parsed. + def encoding + source.encoding + end + + # Returns true if there were no errors during parsing and false if there + # were. + def success? + errors.empty? + end + + # Returns true if there were errors during parsing and false if there were + # not. + def failure? + !success? + end + + # Create a code units cache for the given encoding. + def code_units_cache(encoding) + source.code_units_cache(encoding) + end + end + + # This is a result specific to the `parse` and `parse_file` methods. + class ParseResult < Result + autoload :Comments, "prism/parse_result/comments" + autoload :Errors, "prism/parse_result/errors" + autoload :Newlines, "prism/parse_result/newlines" + + private_constant :Comments + private_constant :Errors + private_constant :Newlines + + # The syntax tree that was parsed from the source code. + attr_reader :value + + # Create a new parse result object with the given values. + def initialize(value, comments, magic_comments, data_loc, errors, warnings, source) + @value = value + super(comments, magic_comments, data_loc, errors, warnings, source) + end + + # Implement the hash pattern matching interface for ParseResult. + def deconstruct_keys(keys) + super.merge!(value: value) + end + + # Attach the list of comments to their respective locations in the tree. + def attach_comments! + Comments.new(self).attach! # steep:ignore + end + + # Walk the tree and mark nodes that are on a new line, loosely emulating + # the behavior of CRuby's `:line` tracepoint event. + def mark_newlines! + value.accept(Newlines.new(source.offsets.size)) # steep:ignore + end + + # Returns a string representation of the syntax tree with the errors + # displayed inline. + def errors_format + Errors.new(self).format + end + end + + # This is a result specific to the `lex` and `lex_file` methods. + class LexResult < Result + # The list of tokens that were parsed from the source code. + attr_reader :value + + # Create a new lex result object with the given values. + def initialize(value, comments, magic_comments, data_loc, errors, warnings, source) + @value = value + super(comments, magic_comments, data_loc, errors, warnings, source) + end + + # Implement the hash pattern matching interface for LexResult. + def deconstruct_keys(keys) + super.merge!(value: value) + end + end + + # This is a result specific to the `parse_lex` and `parse_lex_file` methods. + class ParseLexResult < Result + # A tuple of the syntax tree and the list of tokens that were parsed from + # the source code. + attr_reader :value + + # Create a new parse lex result object with the given values. + def initialize(value, comments, magic_comments, data_loc, errors, warnings, source) + @value = value + super(comments, magic_comments, data_loc, errors, warnings, source) + end + + # Implement the hash pattern matching interface for ParseLexResult. + def deconstruct_keys(keys) + super.merge!(value: value) + end + end + + # This represents a token from the Ruby source. + class Token + # The Source object that represents the source this token came from. + attr_reader :source + private :source + + # The type of token that this token is. + attr_reader :type + + # A byteslice of the source that this token represents. + attr_reader :value + + # Create a new token object with the given type, value, and location. + def initialize(source, type, value, location) + @source = source + @type = type + @value = value + @location = location + end + + # Implement the hash pattern matching interface for Token. + def deconstruct_keys(keys) + { type: type, value: value, location: location } + end + + # A Location object representing the location of this token in the source. + def location + location = @location + return location if location.is_a?(Location) + @location = Location.new(source, location >> 32, location & 0xFFFFFFFF) + end + + # Implement the pretty print interface for Token. + def pretty_print(q) + q.group do + q.text(type.to_s) + self.location.pretty_print(q) + q.text("(") + q.nest(2) do + q.breakable("") + q.pp(value) + end + q.breakable("") + q.text(")") + end + end + + # Returns true if the given other token is equal to this token. + def ==(other) + Token === other && + other.type == type && + other.value == value + end + + # Returns a string representation of this token. + def inspect + location + super + end + + # Freeze this object and the objects it contains. + def deep_freeze + value.freeze + location.freeze + freeze + end + end + + # This object is passed to the various Prism.* methods that accept the + # `scopes` option as an element of the list. It defines both the local + # variables visible at that scope as well as the forwarding parameters + # available at that scope. + class Scope + # The list of local variables that are defined in this scope. This should be + # defined as an array of symbols. + attr_reader :locals + + # The list of local variables that are forwarded to the next scope. This + # should by defined as an array of symbols containing the specific values of + # :*, :**, :&, or :"...". + attr_reader :forwarding + + # Create a new scope object with the given locals and forwarding. + def initialize(locals, forwarding) + @locals = locals + @forwarding = forwarding + end + end + + # Create a new scope with the given locals and forwarding options that is + # suitable for passing into one of the Prism.* methods that accepts the + # `scopes` option. + def self.scope(locals: [], forwarding: []) + Scope.new(locals, forwarding) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/parse_result/comments.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/parse_result/comments.rb new file mode 100644 index 00000000..22c4148b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/parse_result/comments.rb @@ -0,0 +1,187 @@ +# frozen_string_literal: true + +module Prism + class ParseResult < Result + # When we've parsed the source, we have both the syntax tree and the list of + # comments that we found in the source. This class is responsible for + # walking the tree and finding the nearest location to attach each comment. + # + # It does this by first finding the nearest locations to each comment. + # Locations can either come from nodes directly or from location fields on + # nodes. For example, a `ClassNode` has an overall location encompassing the + # entire class, but it also has a location for the `class` keyword. + # + # Once the nearest locations are found, it determines which one to attach + # to. If it's a trailing comment (a comment on the same line as other source + # code), it will favor attaching to the nearest location that occurs before + # the comment. Otherwise it will favor attaching to the nearest location + # that is after the comment. + class Comments + # A target for attaching comments that is based on a specific node's + # location. + class NodeTarget # :nodoc: + attr_reader :node + + def initialize(node) + @node = node + end + + def start_offset + node.start_offset + end + + def end_offset + node.end_offset + end + + def encloses?(comment) + start_offset <= comment.location.start_offset && + comment.location.end_offset <= end_offset + end + + def leading_comment(comment) + node.location.leading_comment(comment) + end + + def trailing_comment(comment) + node.location.trailing_comment(comment) + end + end + + # A target for attaching comments that is based on a location field on a + # node. For example, the `end` token of a ClassNode. + class LocationTarget # :nodoc: + attr_reader :location + + def initialize(location) + @location = location + end + + def start_offset + location.start_offset + end + + def end_offset + location.end_offset + end + + def encloses?(comment) + false + end + + def leading_comment(comment) + location.leading_comment(comment) + end + + def trailing_comment(comment) + location.trailing_comment(comment) + end + end + + # The parse result that we are attaching comments to. + attr_reader :parse_result + + # Create a new Comments object that will attach comments to the given + # parse result. + def initialize(parse_result) + @parse_result = parse_result + end + + # Attach the comments to their respective locations in the tree by + # mutating the parse result. + def attach! + parse_result.comments.each do |comment| + preceding, enclosing, following = nearest_targets(parse_result.value, comment) + + if comment.trailing? + if preceding + preceding.trailing_comment(comment) + else + (following || enclosing || NodeTarget.new(parse_result.value)).leading_comment(comment) + end + else + # If a comment exists on its own line, prefer a leading comment. + if following + following.leading_comment(comment) + elsif preceding + preceding.trailing_comment(comment) + else + (enclosing || NodeTarget.new(parse_result.value)).leading_comment(comment) + end + end + end + end + + private + + # Responsible for finding the nearest targets to the given comment within + # the context of the given encapsulating node. + def nearest_targets(node, comment) + comment_start = comment.location.start_offset + comment_end = comment.location.end_offset + + targets = [] #: Array[_Target] + node.comment_targets.map do |value| + case value + when StatementsNode + targets.concat(value.body.map { |node| NodeTarget.new(node) }) + when Node + targets << NodeTarget.new(value) + when Location + targets << LocationTarget.new(value) + end + end + + targets.sort_by!(&:start_offset) + preceding = nil #: _Target? + following = nil #: _Target? + + left = 0 + right = targets.length + + # This is a custom binary search that finds the nearest nodes to the + # given comment. When it finds a node that completely encapsulates the + # comment, it recurses downward into the tree. + while left < right + middle = (left + right) / 2 + target = targets[middle] + + target_start = target.start_offset + target_end = target.end_offset + + if target.encloses?(comment) + # @type var target: NodeTarget + # The comment is completely contained by this target. Abandon the + # binary search at this level. + return nearest_targets(target.node, comment) + end + + if target_end <= comment_start + # This target falls completely before the comment. Because we will + # never consider this target or any targets before it again, this + # target must be the closest preceding target we have encountered so + # far. + preceding = target + left = middle + 1 + next + end + + if comment_end <= target_start + # This target falls completely after the comment. Because we will + # never consider this target or any targets after it again, this + # target must be the closest following target we have encountered so + # far. + following = target + right = middle + next + end + + # This should only happen if there is a bug in this parser. + raise "Comment location overlaps with a target location" + end + + [preceding, NodeTarget.new(node), following] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/parse_result/errors.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/parse_result/errors.rb new file mode 100644 index 00000000..eb4f3172 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/parse_result/errors.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +require "stringio" + +module Prism + class ParseResult < Result + # An object to represent the set of errors on a parse result. This object + # can be used to format the errors in a human-readable way. + class Errors + # The parse result that contains the errors. + attr_reader :parse_result + + # Initialize a new set of errors from the given parse result. + def initialize(parse_result) + @parse_result = parse_result + end + + # Formats the errors in a human-readable way and return them as a string. + def format + error_lines = {} #: Hash[Integer, Array[ParseError]] + parse_result.errors.each do |error| + location = error.location + (location.start_line..location.end_line).each do |line| + error_lines[line] ||= [] + error_lines[line] << error + end + end + + source_lines = parse_result.source.source.lines + source_lines << "" if error_lines.key?(source_lines.size + 1) + + io = StringIO.new + source_lines.each.with_index(1) do |line, line_number| + io.puts(line) + + (error_lines.delete(line_number) || []).each do |error| + location = error.location + + case line_number + when location.start_line + io.print(" " * location.start_column + "^") + + if location.start_line == location.end_line + if location.start_column != location.end_column + io.print("~" * (location.end_column - location.start_column - 1)) + end + + io.puts(" " + error.message) + else + io.puts("~" * (line.bytesize - location.start_column)) + end + when location.end_line + io.puts("~" * location.end_column + " " + error.message) + else + io.puts("~" * line.bytesize) + end + end + end + + io.puts + io.string + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/parse_result/newlines.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/parse_result/newlines.rb new file mode 100644 index 00000000..37f64f8a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/parse_result/newlines.rb @@ -0,0 +1,154 @@ +# frozen_string_literal: true + +module Prism + class ParseResult < Result + # The :line tracepoint event gets fired whenever the Ruby VM encounters an + # expression on a new line. The types of expressions that can trigger this + # event are: + # + # * if statements + # * unless statements + # * nodes that are children of statements lists + # + # In order to keep track of the newlines, we have a list of offsets that + # come back from the parser. We assign these offsets to the first nodes that + # we find in the tree that are on those lines. + # + # Note that the logic in this file should be kept in sync with the Java + # MarkNewlinesVisitor, since that visitor is responsible for marking the + # newlines for JRuby/TruffleRuby. + # + # This file is autoloaded only when `mark_newlines!` is called, so the + # re-opening of the various nodes in this file will only be performed in + # that case. We do that to avoid storing the extra `@newline` instance + # variable on every node if we don't need it. + class Newlines < Visitor + # Create a new Newlines visitor with the given newline offsets. + def initialize(lines) + # @type var lines: Integer + @lines = Array.new(1 + lines, false) + end + + # Permit block/lambda nodes to mark newlines within themselves. + def visit_block_node(node) + old_lines = @lines + @lines = Array.new(old_lines.size, false) + + begin + super(node) + ensure + @lines = old_lines + end + end + + alias_method :visit_lambda_node, :visit_block_node + + # Mark if/unless nodes as newlines. + def visit_if_node(node) + node.newline_flag!(@lines) + super(node) + end + + alias_method :visit_unless_node, :visit_if_node + + # Permit statements lists to mark newlines within themselves. + def visit_statements_node(node) + node.body.each do |child| + child.newline_flag!(@lines) + end + super(node) + end + end + end + + class Node + def newline_flag? # :nodoc: + !!defined?(@newline_flag) + end + + def newline_flag!(lines) # :nodoc: + line = location.start_line + unless lines[line] + lines[line] = true + @newline_flag = true + end + end + end + + class BeginNode < Node + def newline_flag!(lines) # :nodoc: + # Never mark BeginNode with a newline flag, mark children instead. + end + end + + class ParenthesesNode < Node + def newline_flag!(lines) # :nodoc: + # Never mark ParenthesesNode with a newline flag, mark children instead. + end + end + + class IfNode < Node + def newline_flag!(lines) # :nodoc: + predicate.newline_flag!(lines) + end + end + + class UnlessNode < Node + def newline_flag!(lines) # :nodoc: + predicate.newline_flag!(lines) + end + end + + class UntilNode < Node + def newline_flag!(lines) # :nodoc: + predicate.newline_flag!(lines) + end + end + + class WhileNode < Node + def newline_flag!(lines) # :nodoc: + predicate.newline_flag!(lines) + end + end + + class RescueModifierNode < Node + def newline_flag!(lines) # :nodoc: + expression.newline_flag!(lines) + end + end + + class InterpolatedMatchLastLineNode < Node + def newline_flag!(lines) # :nodoc: + first = parts.first + first.newline_flag!(lines) if first + end + end + + class InterpolatedRegularExpressionNode < Node + def newline_flag!(lines) # :nodoc: + first = parts.first + first.newline_flag!(lines) if first + end + end + + class InterpolatedStringNode < Node + def newline_flag!(lines) # :nodoc: + first = parts.first + first.newline_flag!(lines) if first + end + end + + class InterpolatedSymbolNode < Node + def newline_flag!(lines) # :nodoc: + first = parts.first + first.newline_flag!(lines) if first + end + end + + class InterpolatedXStringNode < Node + def newline_flag!(lines) # :nodoc: + first = parts.first + first.newline_flag!(lines) if first + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/pattern.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/pattern.rb new file mode 100644 index 00000000..03fec267 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/pattern.rb @@ -0,0 +1,268 @@ +# frozen_string_literal: true + +module Prism + # A pattern is an object that wraps a Ruby pattern matching expression. The + # expression would normally be passed to an `in` clause within a `case` + # expression or a rightward assignment expression. For example, in the + # following snippet: + # + # case node + # in ConstantPathNode[ConstantReadNode[name: :Prism], ConstantReadNode[name: :Pattern]] + # end + # + # the pattern is the ConstantPathNode[...] expression. + # + # The pattern gets compiled into an object that responds to #call by running + # the #compile method. This method itself will run back through Prism to + # parse the expression into a tree, then walk the tree to generate the + # necessary callable objects. For example, if you wanted to compile the + # expression above into a callable, you would: + # + # callable = Prism::Pattern.new("ConstantPathNode[ConstantReadNode[name: :Prism], ConstantReadNode[name: :Pattern]]").compile + # callable.call(node) + # + # The callable object returned by #compile is guaranteed to respond to #call + # with a single argument, which is the node to match against. It also is + # guaranteed to respond to #===, which means it itself can be used in a `case` + # expression, as in: + # + # case node + # when callable + # end + # + # If the query given to the initializer cannot be compiled into a valid + # matcher (either because of a syntax error or because it is using syntax we + # do not yet support) then a Prism::Pattern::CompilationError will be + # raised. + class Pattern + # Raised when the query given to a pattern is either invalid Ruby syntax or + # is using syntax that we don't yet support. + class CompilationError < StandardError + # Create a new CompilationError with the given representation of the node + # that caused the error. + def initialize(repr) + super(<<~ERROR) + prism was unable to compile the pattern you provided into a usable + expression. It failed on to understand the node represented by: + + #{repr} + + Note that not all syntax supported by Ruby's pattern matching syntax + is also supported by prism's patterns. If you're using some syntax + that you believe should be supported, please open an issue on + GitHub at https://github.com/ruby/prism/issues/new. + ERROR + end + end + + # The query that this pattern was initialized with. + attr_reader :query + + # Create a new pattern with the given query. The query should be a string + # containing a Ruby pattern matching expression. + def initialize(query) + @query = query + @compiled = nil + end + + # Compile the query into a callable object that can be used to match against + # nodes. + def compile + result = Prism.parse("case nil\nin #{query}\nend") + + case_match_node = result.value.statements.body.last + raise CompilationError, case_match_node.inspect unless case_match_node.is_a?(CaseMatchNode) + + in_node = case_match_node.conditions.last + raise CompilationError, in_node.inspect unless in_node.is_a?(InNode) + + compile_node(in_node.pattern) + end + + # Scan the given node and all of its children for nodes that match the + # pattern. If a block is given, it will be called with each node that + # matches the pattern. If no block is given, an enumerator will be returned + # that will yield each node that matches the pattern. + def scan(root) + return to_enum(:scan, root) unless block_given? + + @compiled ||= compile + queue = [root] + + while (node = queue.shift) + yield node if @compiled.call(node) # steep:ignore + queue.concat(node.compact_child_nodes) + end + end + + private + + # Shortcut for combining two procs into one that returns true if both return + # true. + def combine_and(left, right) + ->(other) { left.call(other) && right.call(other) } + end + + # Shortcut for combining two procs into one that returns true if either + # returns true. + def combine_or(left, right) + ->(other) { left.call(other) || right.call(other) } + end + + # Raise an error because the given node is not supported. + def compile_error(node) + raise CompilationError, node.inspect + end + + # in [foo, bar, baz] + def compile_array_pattern_node(node) + compile_error(node) if !node.rest.nil? || node.posts.any? + + constant = node.constant + compiled_constant = compile_node(constant) if constant + + preprocessed = node.requireds.map { |required| compile_node(required) } + + compiled_requireds = ->(other) do + deconstructed = other.deconstruct + + deconstructed.length == preprocessed.length && + preprocessed + .zip(deconstructed) + .all? { |(matcher, value)| matcher.call(value) } + end + + if compiled_constant + combine_and(compiled_constant, compiled_requireds) + else + compiled_requireds + end + end + + # in foo | bar + def compile_alternation_pattern_node(node) + combine_or(compile_node(node.left), compile_node(node.right)) + end + + # in Prism::ConstantReadNode + def compile_constant_path_node(node) + parent = node.parent + + if parent.is_a?(ConstantReadNode) && parent.slice == "Prism" + name = node.name + raise CompilationError, node.inspect if name.nil? + + compile_constant_name(node, name) + else + compile_error(node) + end + end + + # in ConstantReadNode + # in String + def compile_constant_read_node(node) + compile_constant_name(node, node.name) + end + + # Compile a name associated with a constant. + def compile_constant_name(node, name) + if Prism.const_defined?(name, false) + clazz = Prism.const_get(name) + + ->(other) { clazz === other } + elsif Object.const_defined?(name, false) + clazz = Object.const_get(name) + + ->(other) { clazz === other } + else + compile_error(node) + end + end + + # in InstanceVariableReadNode[name: Symbol] + # in { name: Symbol } + def compile_hash_pattern_node(node) + compile_error(node) if node.rest + compiled_constant = compile_node(node.constant) if node.constant + + preprocessed = + node.elements.to_h do |element| + key = element.key + if key.is_a?(SymbolNode) + [key.unescaped.to_sym, compile_node(element.value)] + else + raise CompilationError, element.inspect + end + end + + compiled_keywords = ->(other) do + deconstructed = other.deconstruct_keys(preprocessed.keys) + + preprocessed.all? do |keyword, matcher| + deconstructed.key?(keyword) && matcher.call(deconstructed[keyword]) + end + end + + if compiled_constant + combine_and(compiled_constant, compiled_keywords) + else + compiled_keywords + end + end + + # in nil + def compile_nil_node(node) + ->(attribute) { attribute.nil? } + end + + # in /foo/ + def compile_regular_expression_node(node) + regexp = Regexp.new(node.unescaped, node.closing[1..]) + + ->(attribute) { regexp === attribute } + end + + # in "" + # in "foo" + def compile_string_node(node) + string = node.unescaped + + ->(attribute) { string === attribute } + end + + # in :+ + # in :foo + def compile_symbol_node(node) + symbol = node.unescaped.to_sym + + ->(attribute) { symbol === attribute } + end + + # Compile any kind of node. Dispatch out to the individual compilation + # methods based on the type of node. + def compile_node(node) + case node + when AlternationPatternNode + compile_alternation_pattern_node(node) + when ArrayPatternNode + compile_array_pattern_node(node) + when ConstantPathNode + compile_constant_path_node(node) + when ConstantReadNode + compile_constant_read_node(node) + when HashPatternNode + compile_hash_pattern_node(node) + when NilNode + compile_nil_node(node) + when RegularExpressionNode + compile_regular_expression_node(node) + when StringNode + compile_string_node(node) + when SymbolNode + compile_symbol_node(node) + else + compile_error(node) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/polyfill/append_as_bytes.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/polyfill/append_as_bytes.rb new file mode 100644 index 00000000..24218bd1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/polyfill/append_as_bytes.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +# Polyfill for String#append_as_bytes, which didn't exist until Ruby 3.4. +if !("".respond_to?(:append_as_bytes)) + String.include( + Module.new { + def append_as_bytes(*args) + args.each do |arg| + arg = Integer === arg ? [arg].pack("C") : arg.b + self.<<(arg) # steep:ignore + end + end + } + ) +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/polyfill/byteindex.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/polyfill/byteindex.rb new file mode 100644 index 00000000..98c6089f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/polyfill/byteindex.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +# Polyfill for String#byteindex, which didn't exist until Ruby 3.2. +if !("".respond_to?(:byteindex)) + String.include( + Module.new { + def byteindex(needle, offset = 0) + charindex = index(needle, offset) + slice(0...charindex).bytesize if charindex + end + } + ) +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/polyfill/unpack1.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/polyfill/unpack1.rb new file mode 100644 index 00000000..3fa9b5a0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/polyfill/unpack1.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# Polyfill for String#unpack1 with the offset parameter. Not all Ruby engines +# have Method#parameters implemented, so we check the arity instead if +# necessary. +if (unpack1 = String.instance_method(:unpack1)).respond_to?(:parameters) ? unpack1.parameters.none? { |_, name| name == :offset } : (unpack1.arity == 1) + String.prepend( + Module.new { + def unpack1(format, offset: 0) # :nodoc: + offset == 0 ? super(format) : self[offset..].unpack1(format) # steep:ignore + end + } + ) +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/prism.so b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/prism.so new file mode 100755 index 00000000..45b409d9 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/prism.so differ diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/reflection.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/reflection.rb new file mode 100644 index 00000000..cffb01ca --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/reflection.rb @@ -0,0 +1,413 @@ +# frozen_string_literal: true + +=begin +This file is generated by the templates/template.rb script and should not be +modified manually. See templates/lib/prism/reflection.rb.erb +if you are looking to modify the template +=end + +module Prism + # The Reflection module provides the ability to reflect on the structure of + # the syntax tree itself, as opposed to looking at a single syntax tree. This + # is useful in metaprogramming contexts. + module Reflection + # A field represents a single piece of data on a node. It is the base class + # for all other field types. + class Field + # The name of the field. + attr_reader :name + + # Initializes the field with the given name. + def initialize(name) + @name = name + end + end + + # A node field represents a single child node in the syntax tree. It + # resolves to a Prism::Node in Ruby. + class NodeField < Field + end + + # An optional node field represents a single child node in the syntax tree + # that may or may not be present. It resolves to either a Prism::Node or nil + # in Ruby. + class OptionalNodeField < Field + end + + # A node list field represents a list of child nodes in the syntax tree. It + # resolves to an array of Prism::Node instances in Ruby. + class NodeListField < Field + end + + # A constant field represents a constant value on a node. Effectively, it + # represents an identifier found within the source. It resolves to a symbol + # in Ruby. + class ConstantField < Field + end + + # An optional constant field represents a constant value on a node that may + # or may not be present. It resolves to either a symbol or nil in Ruby. + class OptionalConstantField < Field + end + + # A constant list field represents a list of constant values on a node. It + # resolves to an array of symbols in Ruby. + class ConstantListField < Field + end + + # A string field represents a string value on a node. It almost always + # represents the unescaped value of a string-like literal. It resolves to a + # string in Ruby. + class StringField < Field + end + + # A location field represents the location of some part of the node in the + # source code. For example, the location of a keyword or an operator. It + # resolves to a Prism::Location in Ruby. + class LocationField < Field + end + + # An optional location field represents the location of some part of the + # node in the source code that may or may not be present. It resolves to + # either a Prism::Location or nil in Ruby. + class OptionalLocationField < Field + end + + # An integer field represents an integer value. It is used to represent the + # value of an integer literal, the depth of local variables, and the number + # of a numbered reference. It resolves to an Integer in Ruby. + class IntegerField < Field + end + + # A float field represents a double-precision floating point value. It is + # used exclusively to represent the value of a floating point literal. It + # resolves to a Float in Ruby. + class FloatField < Field + end + + # A flags field represents a bitset of flags on a node. It resolves to an + # integer in Ruby. Note that the flags cannot be accessed directly on the + # node because the integer is kept private. Instead, the various flags in + # the bitset should be accessed through their query methods. + class FlagsField < Field + # The names of the flags in the bitset. + attr_reader :flags + + # Initializes the flags field with the given name and flags. + def initialize(name, flags) + super(name) + @flags = flags + end + end + + # Returns the fields for the given node. + def self.fields_for(node) + case node.type + when :alias_global_variable_node + [NodeField.new(:new_name), NodeField.new(:old_name), LocationField.new(:keyword_loc)] + when :alias_method_node + [NodeField.new(:new_name), NodeField.new(:old_name), LocationField.new(:keyword_loc)] + when :alternation_pattern_node + [NodeField.new(:left), NodeField.new(:right), LocationField.new(:operator_loc)] + when :and_node + [NodeField.new(:left), NodeField.new(:right), LocationField.new(:operator_loc)] + when :arguments_node + [FlagsField.new(:flags, [:contains_forwarding?, :contains_keywords?, :contains_keyword_splat?, :contains_splat?, :contains_multiple_splats?]), NodeListField.new(:arguments)] + when :array_node + [FlagsField.new(:flags, [:contains_splat?]), NodeListField.new(:elements), OptionalLocationField.new(:opening_loc), OptionalLocationField.new(:closing_loc)] + when :array_pattern_node + [OptionalNodeField.new(:constant), NodeListField.new(:requireds), OptionalNodeField.new(:rest), NodeListField.new(:posts), OptionalLocationField.new(:opening_loc), OptionalLocationField.new(:closing_loc)] + when :assoc_node + [NodeField.new(:key), NodeField.new(:value), OptionalLocationField.new(:operator_loc)] + when :assoc_splat_node + [OptionalNodeField.new(:value), LocationField.new(:operator_loc)] + when :back_reference_read_node + [ConstantField.new(:name)] + when :begin_node + [OptionalLocationField.new(:begin_keyword_loc), OptionalNodeField.new(:statements), OptionalNodeField.new(:rescue_clause), OptionalNodeField.new(:else_clause), OptionalNodeField.new(:ensure_clause), OptionalLocationField.new(:end_keyword_loc)] + when :block_argument_node + [OptionalNodeField.new(:expression), LocationField.new(:operator_loc)] + when :block_local_variable_node + [FlagsField.new(:flags, [:repeated_parameter?]), ConstantField.new(:name)] + when :block_node + [ConstantListField.new(:locals), OptionalNodeField.new(:parameters), OptionalNodeField.new(:body), LocationField.new(:opening_loc), LocationField.new(:closing_loc)] + when :block_parameter_node + [FlagsField.new(:flags, [:repeated_parameter?]), OptionalConstantField.new(:name), OptionalLocationField.new(:name_loc), LocationField.new(:operator_loc)] + when :block_parameters_node + [OptionalNodeField.new(:parameters), NodeListField.new(:locals), OptionalLocationField.new(:opening_loc), OptionalLocationField.new(:closing_loc)] + when :break_node + [OptionalNodeField.new(:arguments), LocationField.new(:keyword_loc)] + when :call_and_write_node + [FlagsField.new(:flags, [:safe_navigation?, :variable_call?, :attribute_write?, :ignore_visibility?]), OptionalNodeField.new(:receiver), OptionalLocationField.new(:call_operator_loc), OptionalLocationField.new(:message_loc), ConstantField.new(:read_name), ConstantField.new(:write_name), LocationField.new(:operator_loc), NodeField.new(:value)] + when :call_node + [FlagsField.new(:flags, [:safe_navigation?, :variable_call?, :attribute_write?, :ignore_visibility?]), OptionalNodeField.new(:receiver), OptionalLocationField.new(:call_operator_loc), ConstantField.new(:name), OptionalLocationField.new(:message_loc), OptionalLocationField.new(:opening_loc), OptionalNodeField.new(:arguments), OptionalLocationField.new(:closing_loc), OptionalNodeField.new(:block)] + when :call_operator_write_node + [FlagsField.new(:flags, [:safe_navigation?, :variable_call?, :attribute_write?, :ignore_visibility?]), OptionalNodeField.new(:receiver), OptionalLocationField.new(:call_operator_loc), OptionalLocationField.new(:message_loc), ConstantField.new(:read_name), ConstantField.new(:write_name), ConstantField.new(:binary_operator), LocationField.new(:binary_operator_loc), NodeField.new(:value)] + when :call_or_write_node + [FlagsField.new(:flags, [:safe_navigation?, :variable_call?, :attribute_write?, :ignore_visibility?]), OptionalNodeField.new(:receiver), OptionalLocationField.new(:call_operator_loc), OptionalLocationField.new(:message_loc), ConstantField.new(:read_name), ConstantField.new(:write_name), LocationField.new(:operator_loc), NodeField.new(:value)] + when :call_target_node + [FlagsField.new(:flags, [:safe_navigation?, :variable_call?, :attribute_write?, :ignore_visibility?]), NodeField.new(:receiver), LocationField.new(:call_operator_loc), ConstantField.new(:name), LocationField.new(:message_loc)] + when :capture_pattern_node + [NodeField.new(:value), NodeField.new(:target), LocationField.new(:operator_loc)] + when :case_match_node + [OptionalNodeField.new(:predicate), NodeListField.new(:conditions), OptionalNodeField.new(:else_clause), LocationField.new(:case_keyword_loc), LocationField.new(:end_keyword_loc)] + when :case_node + [OptionalNodeField.new(:predicate), NodeListField.new(:conditions), OptionalNodeField.new(:else_clause), LocationField.new(:case_keyword_loc), LocationField.new(:end_keyword_loc)] + when :class_node + [ConstantListField.new(:locals), LocationField.new(:class_keyword_loc), NodeField.new(:constant_path), OptionalLocationField.new(:inheritance_operator_loc), OptionalNodeField.new(:superclass), OptionalNodeField.new(:body), LocationField.new(:end_keyword_loc), ConstantField.new(:name)] + when :class_variable_and_write_node + [ConstantField.new(:name), LocationField.new(:name_loc), LocationField.new(:operator_loc), NodeField.new(:value)] + when :class_variable_operator_write_node + [ConstantField.new(:name), LocationField.new(:name_loc), LocationField.new(:binary_operator_loc), NodeField.new(:value), ConstantField.new(:binary_operator)] + when :class_variable_or_write_node + [ConstantField.new(:name), LocationField.new(:name_loc), LocationField.new(:operator_loc), NodeField.new(:value)] + when :class_variable_read_node + [ConstantField.new(:name)] + when :class_variable_target_node + [ConstantField.new(:name)] + when :class_variable_write_node + [ConstantField.new(:name), LocationField.new(:name_loc), NodeField.new(:value), LocationField.new(:operator_loc)] + when :constant_and_write_node + [ConstantField.new(:name), LocationField.new(:name_loc), LocationField.new(:operator_loc), NodeField.new(:value)] + when :constant_operator_write_node + [ConstantField.new(:name), LocationField.new(:name_loc), LocationField.new(:binary_operator_loc), NodeField.new(:value), ConstantField.new(:binary_operator)] + when :constant_or_write_node + [ConstantField.new(:name), LocationField.new(:name_loc), LocationField.new(:operator_loc), NodeField.new(:value)] + when :constant_path_and_write_node + [NodeField.new(:target), LocationField.new(:operator_loc), NodeField.new(:value)] + when :constant_path_node + [OptionalNodeField.new(:parent), OptionalConstantField.new(:name), LocationField.new(:delimiter_loc), LocationField.new(:name_loc)] + when :constant_path_operator_write_node + [NodeField.new(:target), LocationField.new(:binary_operator_loc), NodeField.new(:value), ConstantField.new(:binary_operator)] + when :constant_path_or_write_node + [NodeField.new(:target), LocationField.new(:operator_loc), NodeField.new(:value)] + when :constant_path_target_node + [OptionalNodeField.new(:parent), OptionalConstantField.new(:name), LocationField.new(:delimiter_loc), LocationField.new(:name_loc)] + when :constant_path_write_node + [NodeField.new(:target), LocationField.new(:operator_loc), NodeField.new(:value)] + when :constant_read_node + [ConstantField.new(:name)] + when :constant_target_node + [ConstantField.new(:name)] + when :constant_write_node + [ConstantField.new(:name), LocationField.new(:name_loc), NodeField.new(:value), LocationField.new(:operator_loc)] + when :def_node + [ConstantField.new(:name), LocationField.new(:name_loc), OptionalNodeField.new(:receiver), OptionalNodeField.new(:parameters), OptionalNodeField.new(:body), ConstantListField.new(:locals), LocationField.new(:def_keyword_loc), OptionalLocationField.new(:operator_loc), OptionalLocationField.new(:lparen_loc), OptionalLocationField.new(:rparen_loc), OptionalLocationField.new(:equal_loc), OptionalLocationField.new(:end_keyword_loc)] + when :defined_node + [OptionalLocationField.new(:lparen_loc), NodeField.new(:value), OptionalLocationField.new(:rparen_loc), LocationField.new(:keyword_loc)] + when :else_node + [LocationField.new(:else_keyword_loc), OptionalNodeField.new(:statements), OptionalLocationField.new(:end_keyword_loc)] + when :embedded_statements_node + [LocationField.new(:opening_loc), OptionalNodeField.new(:statements), LocationField.new(:closing_loc)] + when :embedded_variable_node + [LocationField.new(:operator_loc), NodeField.new(:variable)] + when :ensure_node + [LocationField.new(:ensure_keyword_loc), OptionalNodeField.new(:statements), LocationField.new(:end_keyword_loc)] + when :false_node + [] + when :find_pattern_node + [OptionalNodeField.new(:constant), NodeField.new(:left), NodeListField.new(:requireds), NodeField.new(:right), OptionalLocationField.new(:opening_loc), OptionalLocationField.new(:closing_loc)] + when :flip_flop_node + [FlagsField.new(:flags, [:exclude_end?]), OptionalNodeField.new(:left), OptionalNodeField.new(:right), LocationField.new(:operator_loc)] + when :float_node + [FloatField.new(:value)] + when :for_node + [NodeField.new(:index), NodeField.new(:collection), OptionalNodeField.new(:statements), LocationField.new(:for_keyword_loc), LocationField.new(:in_keyword_loc), OptionalLocationField.new(:do_keyword_loc), LocationField.new(:end_keyword_loc)] + when :forwarding_arguments_node + [] + when :forwarding_parameter_node + [] + when :forwarding_super_node + [OptionalNodeField.new(:block)] + when :global_variable_and_write_node + [ConstantField.new(:name), LocationField.new(:name_loc), LocationField.new(:operator_loc), NodeField.new(:value)] + when :global_variable_operator_write_node + [ConstantField.new(:name), LocationField.new(:name_loc), LocationField.new(:binary_operator_loc), NodeField.new(:value), ConstantField.new(:binary_operator)] + when :global_variable_or_write_node + [ConstantField.new(:name), LocationField.new(:name_loc), LocationField.new(:operator_loc), NodeField.new(:value)] + when :global_variable_read_node + [ConstantField.new(:name)] + when :global_variable_target_node + [ConstantField.new(:name)] + when :global_variable_write_node + [ConstantField.new(:name), LocationField.new(:name_loc), NodeField.new(:value), LocationField.new(:operator_loc)] + when :hash_node + [LocationField.new(:opening_loc), NodeListField.new(:elements), LocationField.new(:closing_loc)] + when :hash_pattern_node + [OptionalNodeField.new(:constant), NodeListField.new(:elements), OptionalNodeField.new(:rest), OptionalLocationField.new(:opening_loc), OptionalLocationField.new(:closing_loc)] + when :if_node + [OptionalLocationField.new(:if_keyword_loc), NodeField.new(:predicate), OptionalLocationField.new(:then_keyword_loc), OptionalNodeField.new(:statements), OptionalNodeField.new(:subsequent), OptionalLocationField.new(:end_keyword_loc)] + when :imaginary_node + [NodeField.new(:numeric)] + when :implicit_node + [NodeField.new(:value)] + when :implicit_rest_node + [] + when :in_node + [NodeField.new(:pattern), OptionalNodeField.new(:statements), LocationField.new(:in_loc), OptionalLocationField.new(:then_loc)] + when :index_and_write_node + [FlagsField.new(:flags, [:safe_navigation?, :variable_call?, :attribute_write?, :ignore_visibility?]), OptionalNodeField.new(:receiver), OptionalLocationField.new(:call_operator_loc), LocationField.new(:opening_loc), OptionalNodeField.new(:arguments), LocationField.new(:closing_loc), OptionalNodeField.new(:block), LocationField.new(:operator_loc), NodeField.new(:value)] + when :index_operator_write_node + [FlagsField.new(:flags, [:safe_navigation?, :variable_call?, :attribute_write?, :ignore_visibility?]), OptionalNodeField.new(:receiver), OptionalLocationField.new(:call_operator_loc), LocationField.new(:opening_loc), OptionalNodeField.new(:arguments), LocationField.new(:closing_loc), OptionalNodeField.new(:block), ConstantField.new(:binary_operator), LocationField.new(:binary_operator_loc), NodeField.new(:value)] + when :index_or_write_node + [FlagsField.new(:flags, [:safe_navigation?, :variable_call?, :attribute_write?, :ignore_visibility?]), OptionalNodeField.new(:receiver), OptionalLocationField.new(:call_operator_loc), LocationField.new(:opening_loc), OptionalNodeField.new(:arguments), LocationField.new(:closing_loc), OptionalNodeField.new(:block), LocationField.new(:operator_loc), NodeField.new(:value)] + when :index_target_node + [FlagsField.new(:flags, [:safe_navigation?, :variable_call?, :attribute_write?, :ignore_visibility?]), NodeField.new(:receiver), LocationField.new(:opening_loc), OptionalNodeField.new(:arguments), LocationField.new(:closing_loc), OptionalNodeField.new(:block)] + when :instance_variable_and_write_node + [ConstantField.new(:name), LocationField.new(:name_loc), LocationField.new(:operator_loc), NodeField.new(:value)] + when :instance_variable_operator_write_node + [ConstantField.new(:name), LocationField.new(:name_loc), LocationField.new(:binary_operator_loc), NodeField.new(:value), ConstantField.new(:binary_operator)] + when :instance_variable_or_write_node + [ConstantField.new(:name), LocationField.new(:name_loc), LocationField.new(:operator_loc), NodeField.new(:value)] + when :instance_variable_read_node + [ConstantField.new(:name)] + when :instance_variable_target_node + [ConstantField.new(:name)] + when :instance_variable_write_node + [ConstantField.new(:name), LocationField.new(:name_loc), NodeField.new(:value), LocationField.new(:operator_loc)] + when :integer_node + [FlagsField.new(:flags, [:binary?, :decimal?, :octal?, :hexadecimal?]), IntegerField.new(:value)] + when :interpolated_match_last_line_node + [FlagsField.new(:flags, [:ignore_case?, :extended?, :multi_line?, :once?, :euc_jp?, :ascii_8bit?, :windows_31j?, :utf_8?, :forced_utf8_encoding?, :forced_binary_encoding?, :forced_us_ascii_encoding?]), LocationField.new(:opening_loc), NodeListField.new(:parts), LocationField.new(:closing_loc)] + when :interpolated_regular_expression_node + [FlagsField.new(:flags, [:ignore_case?, :extended?, :multi_line?, :once?, :euc_jp?, :ascii_8bit?, :windows_31j?, :utf_8?, :forced_utf8_encoding?, :forced_binary_encoding?, :forced_us_ascii_encoding?]), LocationField.new(:opening_loc), NodeListField.new(:parts), LocationField.new(:closing_loc)] + when :interpolated_string_node + [FlagsField.new(:flags, [:frozen?, :mutable?]), OptionalLocationField.new(:opening_loc), NodeListField.new(:parts), OptionalLocationField.new(:closing_loc)] + when :interpolated_symbol_node + [OptionalLocationField.new(:opening_loc), NodeListField.new(:parts), OptionalLocationField.new(:closing_loc)] + when :interpolated_x_string_node + [LocationField.new(:opening_loc), NodeListField.new(:parts), LocationField.new(:closing_loc)] + when :it_local_variable_read_node + [] + when :it_parameters_node + [] + when :keyword_hash_node + [FlagsField.new(:flags, [:symbol_keys?]), NodeListField.new(:elements)] + when :keyword_rest_parameter_node + [FlagsField.new(:flags, [:repeated_parameter?]), OptionalConstantField.new(:name), OptionalLocationField.new(:name_loc), LocationField.new(:operator_loc)] + when :lambda_node + [ConstantListField.new(:locals), LocationField.new(:operator_loc), LocationField.new(:opening_loc), LocationField.new(:closing_loc), OptionalNodeField.new(:parameters), OptionalNodeField.new(:body)] + when :local_variable_and_write_node + [LocationField.new(:name_loc), LocationField.new(:operator_loc), NodeField.new(:value), ConstantField.new(:name), IntegerField.new(:depth)] + when :local_variable_operator_write_node + [LocationField.new(:name_loc), LocationField.new(:binary_operator_loc), NodeField.new(:value), ConstantField.new(:name), ConstantField.new(:binary_operator), IntegerField.new(:depth)] + when :local_variable_or_write_node + [LocationField.new(:name_loc), LocationField.new(:operator_loc), NodeField.new(:value), ConstantField.new(:name), IntegerField.new(:depth)] + when :local_variable_read_node + [ConstantField.new(:name), IntegerField.new(:depth)] + when :local_variable_target_node + [ConstantField.new(:name), IntegerField.new(:depth)] + when :local_variable_write_node + [ConstantField.new(:name), IntegerField.new(:depth), LocationField.new(:name_loc), NodeField.new(:value), LocationField.new(:operator_loc)] + when :match_last_line_node + [FlagsField.new(:flags, [:ignore_case?, :extended?, :multi_line?, :once?, :euc_jp?, :ascii_8bit?, :windows_31j?, :utf_8?, :forced_utf8_encoding?, :forced_binary_encoding?, :forced_us_ascii_encoding?]), LocationField.new(:opening_loc), LocationField.new(:content_loc), LocationField.new(:closing_loc), StringField.new(:unescaped)] + when :match_predicate_node + [NodeField.new(:value), NodeField.new(:pattern), LocationField.new(:operator_loc)] + when :match_required_node + [NodeField.new(:value), NodeField.new(:pattern), LocationField.new(:operator_loc)] + when :match_write_node + [NodeField.new(:call), NodeListField.new(:targets)] + when :missing_node + [] + when :module_node + [ConstantListField.new(:locals), LocationField.new(:module_keyword_loc), NodeField.new(:constant_path), OptionalNodeField.new(:body), LocationField.new(:end_keyword_loc), ConstantField.new(:name)] + when :multi_target_node + [NodeListField.new(:lefts), OptionalNodeField.new(:rest), NodeListField.new(:rights), OptionalLocationField.new(:lparen_loc), OptionalLocationField.new(:rparen_loc)] + when :multi_write_node + [NodeListField.new(:lefts), OptionalNodeField.new(:rest), NodeListField.new(:rights), OptionalLocationField.new(:lparen_loc), OptionalLocationField.new(:rparen_loc), LocationField.new(:operator_loc), NodeField.new(:value)] + when :next_node + [OptionalNodeField.new(:arguments), LocationField.new(:keyword_loc)] + when :nil_node + [] + when :no_keywords_parameter_node + [LocationField.new(:operator_loc), LocationField.new(:keyword_loc)] + when :numbered_parameters_node + [IntegerField.new(:maximum)] + when :numbered_reference_read_node + [IntegerField.new(:number)] + when :optional_keyword_parameter_node + [FlagsField.new(:flags, [:repeated_parameter?]), ConstantField.new(:name), LocationField.new(:name_loc), NodeField.new(:value)] + when :optional_parameter_node + [FlagsField.new(:flags, [:repeated_parameter?]), ConstantField.new(:name), LocationField.new(:name_loc), LocationField.new(:operator_loc), NodeField.new(:value)] + when :or_node + [NodeField.new(:left), NodeField.new(:right), LocationField.new(:operator_loc)] + when :parameters_node + [NodeListField.new(:requireds), NodeListField.new(:optionals), OptionalNodeField.new(:rest), NodeListField.new(:posts), NodeListField.new(:keywords), OptionalNodeField.new(:keyword_rest), OptionalNodeField.new(:block)] + when :parentheses_node + [FlagsField.new(:flags, [:multiple_statements?]), OptionalNodeField.new(:body), LocationField.new(:opening_loc), LocationField.new(:closing_loc)] + when :pinned_expression_node + [NodeField.new(:expression), LocationField.new(:operator_loc), LocationField.new(:lparen_loc), LocationField.new(:rparen_loc)] + when :pinned_variable_node + [NodeField.new(:variable), LocationField.new(:operator_loc)] + when :post_execution_node + [OptionalNodeField.new(:statements), LocationField.new(:keyword_loc), LocationField.new(:opening_loc), LocationField.new(:closing_loc)] + when :pre_execution_node + [OptionalNodeField.new(:statements), LocationField.new(:keyword_loc), LocationField.new(:opening_loc), LocationField.new(:closing_loc)] + when :program_node + [ConstantListField.new(:locals), NodeField.new(:statements)] + when :range_node + [FlagsField.new(:flags, [:exclude_end?]), OptionalNodeField.new(:left), OptionalNodeField.new(:right), LocationField.new(:operator_loc)] + when :rational_node + [FlagsField.new(:flags, [:binary?, :decimal?, :octal?, :hexadecimal?]), IntegerField.new(:numerator), IntegerField.new(:denominator)] + when :redo_node + [] + when :regular_expression_node + [FlagsField.new(:flags, [:ignore_case?, :extended?, :multi_line?, :once?, :euc_jp?, :ascii_8bit?, :windows_31j?, :utf_8?, :forced_utf8_encoding?, :forced_binary_encoding?, :forced_us_ascii_encoding?]), LocationField.new(:opening_loc), LocationField.new(:content_loc), LocationField.new(:closing_loc), StringField.new(:unescaped)] + when :required_keyword_parameter_node + [FlagsField.new(:flags, [:repeated_parameter?]), ConstantField.new(:name), LocationField.new(:name_loc)] + when :required_parameter_node + [FlagsField.new(:flags, [:repeated_parameter?]), ConstantField.new(:name)] + when :rescue_modifier_node + [NodeField.new(:expression), LocationField.new(:keyword_loc), NodeField.new(:rescue_expression)] + when :rescue_node + [LocationField.new(:keyword_loc), NodeListField.new(:exceptions), OptionalLocationField.new(:operator_loc), OptionalNodeField.new(:reference), OptionalLocationField.new(:then_keyword_loc), OptionalNodeField.new(:statements), OptionalNodeField.new(:subsequent)] + when :rest_parameter_node + [FlagsField.new(:flags, [:repeated_parameter?]), OptionalConstantField.new(:name), OptionalLocationField.new(:name_loc), LocationField.new(:operator_loc)] + when :retry_node + [] + when :return_node + [LocationField.new(:keyword_loc), OptionalNodeField.new(:arguments)] + when :self_node + [] + when :shareable_constant_node + [FlagsField.new(:flags, [:literal?, :experimental_everything?, :experimental_copy?]), NodeField.new(:write)] + when :singleton_class_node + [ConstantListField.new(:locals), LocationField.new(:class_keyword_loc), LocationField.new(:operator_loc), NodeField.new(:expression), OptionalNodeField.new(:body), LocationField.new(:end_keyword_loc)] + when :source_encoding_node + [] + when :source_file_node + [FlagsField.new(:flags, [:forced_utf8_encoding?, :forced_binary_encoding?, :frozen?, :mutable?]), StringField.new(:filepath)] + when :source_line_node + [] + when :splat_node + [LocationField.new(:operator_loc), OptionalNodeField.new(:expression)] + when :statements_node + [NodeListField.new(:body)] + when :string_node + [FlagsField.new(:flags, [:forced_utf8_encoding?, :forced_binary_encoding?, :frozen?, :mutable?]), OptionalLocationField.new(:opening_loc), LocationField.new(:content_loc), OptionalLocationField.new(:closing_loc), StringField.new(:unescaped)] + when :super_node + [LocationField.new(:keyword_loc), OptionalLocationField.new(:lparen_loc), OptionalNodeField.new(:arguments), OptionalLocationField.new(:rparen_loc), OptionalNodeField.new(:block)] + when :symbol_node + [FlagsField.new(:flags, [:forced_utf8_encoding?, :forced_binary_encoding?, :forced_us_ascii_encoding?]), OptionalLocationField.new(:opening_loc), OptionalLocationField.new(:value_loc), OptionalLocationField.new(:closing_loc), StringField.new(:unescaped)] + when :true_node + [] + when :undef_node + [NodeListField.new(:names), LocationField.new(:keyword_loc)] + when :unless_node + [LocationField.new(:keyword_loc), NodeField.new(:predicate), OptionalLocationField.new(:then_keyword_loc), OptionalNodeField.new(:statements), OptionalNodeField.new(:else_clause), OptionalLocationField.new(:end_keyword_loc)] + when :until_node + [FlagsField.new(:flags, [:begin_modifier?]), LocationField.new(:keyword_loc), OptionalLocationField.new(:do_keyword_loc), OptionalLocationField.new(:closing_loc), NodeField.new(:predicate), OptionalNodeField.new(:statements)] + when :when_node + [LocationField.new(:keyword_loc), NodeListField.new(:conditions), OptionalLocationField.new(:then_keyword_loc), OptionalNodeField.new(:statements)] + when :while_node + [FlagsField.new(:flags, [:begin_modifier?]), LocationField.new(:keyword_loc), OptionalLocationField.new(:do_keyword_loc), OptionalLocationField.new(:closing_loc), NodeField.new(:predicate), OptionalNodeField.new(:statements)] + when :x_string_node + [FlagsField.new(:flags, [:forced_utf8_encoding?, :forced_binary_encoding?]), LocationField.new(:opening_loc), LocationField.new(:content_loc), LocationField.new(:closing_loc), StringField.new(:unescaped)] + when :yield_node + [LocationField.new(:keyword_loc), OptionalLocationField.new(:lparen_loc), OptionalNodeField.new(:arguments), OptionalLocationField.new(:rparen_loc)] + else + raise "Unknown node type: #{node.type.inspect}" + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/relocation.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/relocation.rb new file mode 100644 index 00000000..163d2012 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/relocation.rb @@ -0,0 +1,504 @@ +# frozen_string_literal: true + +module Prism + # Prism parses deterministically for the same input. This provides a nice + # property that is exposed through the #node_id API on nodes. Effectively this + # means that for the same input, these values will remain consistent every + # time the source is parsed. This means we can reparse the source same with a + # #node_id value and find the exact same node again. + # + # The Relocation module provides an API around this property. It allows you to + # "save" nodes and locations using a minimal amount of memory (just the + # node_id and a field identifier) and then reify them later. + module Relocation + # An entry in a repository that will lazily reify its values when they are + # first accessed. + class Entry + # Raised if a value that could potentially be on an entry is missing + # because it was either not configured on the repository or it has not yet + # been fetched. + class MissingValueError < StandardError + end + + # Initialize a new entry with the given repository. + def initialize(repository) + @repository = repository + @values = nil + end + + # Fetch the filepath of the value. + def filepath + fetch_value(:filepath) + end + + # Fetch the start line of the value. + def start_line + fetch_value(:start_line) + end + + # Fetch the end line of the value. + def end_line + fetch_value(:end_line) + end + + # Fetch the start byte offset of the value. + def start_offset + fetch_value(:start_offset) + end + + # Fetch the end byte offset of the value. + def end_offset + fetch_value(:end_offset) + end + + # Fetch the start character offset of the value. + def start_character_offset + fetch_value(:start_character_offset) + end + + # Fetch the end character offset of the value. + def end_character_offset + fetch_value(:end_character_offset) + end + + # Fetch the start code units offset of the value, for the encoding that + # was configured on the repository. + def start_code_units_offset + fetch_value(:start_code_units_offset) + end + + # Fetch the end code units offset of the value, for the encoding that was + # configured on the repository. + def end_code_units_offset + fetch_value(:end_code_units_offset) + end + + # Fetch the start byte column of the value. + def start_column + fetch_value(:start_column) + end + + # Fetch the end byte column of the value. + def end_column + fetch_value(:end_column) + end + + # Fetch the start character column of the value. + def start_character_column + fetch_value(:start_character_column) + end + + # Fetch the end character column of the value. + def end_character_column + fetch_value(:end_character_column) + end + + # Fetch the start code units column of the value, for the encoding that + # was configured on the repository. + def start_code_units_column + fetch_value(:start_code_units_column) + end + + # Fetch the end code units column of the value, for the encoding that was + # configured on the repository. + def end_code_units_column + fetch_value(:end_code_units_column) + end + + # Fetch the leading comments of the value. + def leading_comments + fetch_value(:leading_comments) + end + + # Fetch the trailing comments of the value. + def trailing_comments + fetch_value(:trailing_comments) + end + + # Fetch the leading and trailing comments of the value. + def comments + leading_comments.concat(trailing_comments) + end + + # Reify the values on this entry with the given values. This is an + # internal-only API that is called from the repository when it is time to + # reify the values. + def reify!(values) # :nodoc: + @repository = nil + @values = values + end + + private + + # Fetch a value from the entry, raising an error if it is missing. + def fetch_value(name) + values.fetch(name) do + raise MissingValueError, "No value for #{name}, make sure the " \ + "repository has been properly configured" + end + end + + # Return the values from the repository, reifying them if necessary. + def values + @values || (@repository.reify!; @values) + end + end + + # Represents the source of a repository that will be reparsed. + class Source + # The value that will need to be reparsed. + attr_reader :value + + # Initialize the source with the given value. + def initialize(value) + @value = value + end + + # Reparse the value and return the parse result. + def result + raise NotImplementedError, "Subclasses must implement #result" + end + + # Create a code units cache for the given encoding. + def code_units_cache(encoding) + result.code_units_cache(encoding) + end + end + + # A source that is represented by a file path. + class SourceFilepath < Source + # Reparse the file and return the parse result. + def result + Prism.parse_file(value) + end + end + + # A source that is represented by a string. + class SourceString < Source + # Reparse the string and return the parse result. + def result + Prism.parse(value) + end + end + + # A field that represents the file path. + class FilepathField + # The file path that this field represents. + attr_reader :value + + # Initialize a new field with the given file path. + def initialize(value) + @value = value + end + + # Fetch the file path. + def fields(_value) + { filepath: value } + end + end + + # A field representing the start and end lines. + class LinesField + # Fetches the start and end line of a value. + def fields(value) + { start_line: value.start_line, end_line: value.end_line } + end + end + + # A field representing the start and end byte offsets. + class OffsetsField + # Fetches the start and end byte offset of a value. + def fields(value) + { start_offset: value.start_offset, end_offset: value.end_offset } + end + end + + # A field representing the start and end character offsets. + class CharacterOffsetsField + # Fetches the start and end character offset of a value. + def fields(value) + { + start_character_offset: value.start_character_offset, + end_character_offset: value.end_character_offset + } + end + end + + # A field representing the start and end code unit offsets. + class CodeUnitOffsetsField + # A pointer to the repository object that is used for lazily creating a + # code units cache. + attr_reader :repository + + # The associated encoding for the code units. + attr_reader :encoding + + # Initialize a new field with the associated repository and encoding. + def initialize(repository, encoding) + @repository = repository + @encoding = encoding + @cache = nil + end + + # Fetches the start and end code units offset of a value for a particular + # encoding. + def fields(value) + { + start_code_units_offset: value.cached_start_code_units_offset(cache), + end_code_units_offset: value.cached_end_code_units_offset(cache) + } + end + + private + + # Lazily create a code units cache for the associated encoding. + def cache + @cache ||= repository.code_units_cache(encoding) + end + end + + # A field representing the start and end byte columns. + class ColumnsField + # Fetches the start and end byte column of a value. + def fields(value) + { start_column: value.start_column, end_column: value.end_column } + end + end + + # A field representing the start and end character columns. + class CharacterColumnsField + # Fetches the start and end character column of a value. + def fields(value) + { + start_character_column: value.start_character_column, + end_character_column: value.end_character_column + } + end + end + + # A field representing the start and end code unit columns for a specific + # encoding. + class CodeUnitColumnsField + # The repository object that is used for lazily creating a code units + # cache. + attr_reader :repository + + # The associated encoding for the code units. + attr_reader :encoding + + # Initialize a new field with the associated repository and encoding. + def initialize(repository, encoding) + @repository = repository + @encoding = encoding + @cache = nil + end + + # Fetches the start and end code units column of a value for a particular + # encoding. + def fields(value) + { + start_code_units_column: value.cached_start_code_units_column(cache), + end_code_units_column: value.cached_end_code_units_column(cache) + } + end + + private + + # Lazily create a code units cache for the associated encoding. + def cache + @cache ||= repository.code_units_cache(encoding) + end + end + + # An abstract field used as the parent class of the two comments fields. + class CommentsField + # An object that represents a slice of a comment. + class Comment + # The slice of the comment. + attr_reader :slice + + # Initialize a new comment with the given slice. + def initialize(slice) + @slice = slice + end + end + + private + + # Create comment objects from the given values. + def comments(values) + values.map { |value| Comment.new(value.slice) } + end + end + + # A field representing the leading comments. + class LeadingCommentsField < CommentsField + # Fetches the leading comments of a value. + def fields(value) + { leading_comments: comments(value.leading_comments) } + end + end + + # A field representing the trailing comments. + class TrailingCommentsField < CommentsField + # Fetches the trailing comments of a value. + def fields(value) + { trailing_comments: comments(value.trailing_comments) } + end + end + + # A repository is a configured collection of fields and a set of entries + # that knows how to reparse a source and reify the values. + class Repository + # Raised when multiple fields of the same type are configured on the same + # repository. + class ConfigurationError < StandardError + end + + # The source associated with this repository. This will be either a + # SourceFilepath (the most common use case) or a SourceString. + attr_reader :source + + # The fields that have been configured on this repository. + attr_reader :fields + + # The entries that have been saved on this repository. + attr_reader :entries + + # Initialize a new repository with the given source. + def initialize(source) + @source = source + @fields = {} + @entries = Hash.new { |hash, node_id| hash[node_id] = {} } + end + + # Create a code units cache for the given encoding from the source. + def code_units_cache(encoding) + source.code_units_cache(encoding) + end + + # Configure the filepath field for this repository and return self. + def filepath + raise ConfigurationError, "Can only specify filepath for a filepath source" unless source.is_a?(SourceFilepath) + field(:filepath, FilepathField.new(source.value)) + end + + # Configure the lines field for this repository and return self. + def lines + field(:lines, LinesField.new) + end + + # Configure the offsets field for this repository and return self. + def offsets + field(:offsets, OffsetsField.new) + end + + # Configure the character offsets field for this repository and return + # self. + def character_offsets + field(:character_offsets, CharacterOffsetsField.new) + end + + # Configure the code unit offsets field for this repository for a specific + # encoding and return self. + def code_unit_offsets(encoding) + field(:code_unit_offsets, CodeUnitOffsetsField.new(self, encoding)) + end + + # Configure the columns field for this repository and return self. + def columns + field(:columns, ColumnsField.new) + end + + # Configure the character columns field for this repository and return + # self. + def character_columns + field(:character_columns, CharacterColumnsField.new) + end + + # Configure the code unit columns field for this repository for a specific + # encoding and return self. + def code_unit_columns(encoding) + field(:code_unit_columns, CodeUnitColumnsField.new(self, encoding)) + end + + # Configure the leading comments field for this repository and return + # self. + def leading_comments + field(:leading_comments, LeadingCommentsField.new) + end + + # Configure the trailing comments field for this repository and return + # self. + def trailing_comments + field(:trailing_comments, TrailingCommentsField.new) + end + + # Configure both the leading and trailing comment fields for this + # repository and return self. + def comments + leading_comments.trailing_comments + end + + # This method is called from nodes and locations when they want to enter + # themselves into the repository. It it internal-only and meant to be + # called from the #save* APIs. + def enter(node_id, field_name) # :nodoc: + entry = Entry.new(self) + @entries[node_id][field_name] = entry + entry + end + + # This method is called from the entries in the repository when they need + # to reify their values. It is internal-only and meant to be called from + # the various value APIs. + def reify! # :nodoc: + result = source.result + + # Attach the comments if they have been requested as part of the + # configuration of this repository. + if fields.key?(:leading_comments) || fields.key?(:trailing_comments) + result.attach_comments! + end + + queue = [result.value] #: Array[Prism::node] + while (node = queue.shift) + @entries[node.node_id].each do |field_name, entry| + value = node.public_send(field_name) + values = {} #: Hash[Symbol, untyped] + + fields.each_value do |field| + values.merge!(field.fields(value)) + end + + entry.reify!(values) + end + + queue.concat(node.compact_child_nodes) + end + + @entries.clear + end + + private + + # Append the given field to the repository and return the repository so + # that these calls can be chained. + def field(name, value) + raise ConfigurationError, "Cannot specify multiple #{name} fields" if @fields.key?(name) + @fields[name] = value + self + end + end + + # Create a new repository for the given filepath. + def self.filepath(value) + Repository.new(SourceFilepath.new(value)) + end + + # Create a new repository for the given string. + def self.string(value) + Repository.new(SourceString.new(value)) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/serialize.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/serialize.rb new file mode 100644 index 00000000..7fd6cb73 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/serialize.rb @@ -0,0 +1,2392 @@ +# frozen_string_literal: true + +=begin +This file is generated by the templates/template.rb script and should not be +modified manually. See templates/lib/prism/serialize.rb.erb +if you are looking to modify the template +=end + +require "stringio" +require_relative "polyfill/unpack1" + +module Prism + # A module responsible for deserializing parse results. + module Serialize + # The major version of prism that we are expecting to find in the serialized + # strings. + MAJOR_VERSION = 1 + + # The minor version of prism that we are expecting to find in the serialized + # strings. + MINOR_VERSION = 4 + + # The patch version of prism that we are expecting to find in the serialized + # strings. + PATCH_VERSION = 0 + + # Deserialize the dumped output from a request to parse or parse_file. + # + # The formatting of the source of this method is purposeful to illustrate + # the structure of the serialized data. + def self.load_parse(input, serialized, freeze) + input = input.dup + source = Source.for(input) + loader = Loader.new(source, serialized) + + loader.load_header + encoding = loader.load_encoding + start_line = loader.load_varsint + offsets = loader.load_line_offsets(freeze) + + source.replace_start_line(start_line) + source.replace_offsets(offsets) + + comments = loader.load_comments(freeze) + magic_comments = loader.load_magic_comments(freeze) + data_loc = loader.load_optional_location_object(freeze) + errors = loader.load_errors(encoding, freeze) + warnings = loader.load_warnings(encoding, freeze) + cpool_base = loader.load_uint32 + cpool_size = loader.load_varuint + + constant_pool = ConstantPool.new(input, serialized, cpool_base, cpool_size) + + node = loader.load_node(constant_pool, encoding, freeze) + loader.load_constant_pool(constant_pool) + raise unless loader.eof? + + result = ParseResult.new(node, comments, magic_comments, data_loc, errors, warnings, source) + result.freeze if freeze + + input.force_encoding(encoding) + + # This is an extremely niche use-case where the file was marked as binary + # but it contained UTF-8-encoded characters. In that case we will actually + # put it back to UTF-8 to give the location APIs the best chance of being + # correct. + if !input.ascii_only? && input.encoding == Encoding::BINARY + input.force_encoding(Encoding::UTF_8) + input.force_encoding(Encoding::BINARY) unless input.valid_encoding? + end + + if freeze + input.freeze + source.deep_freeze + end + + result + end + + # Deserialize the dumped output from a request to lex or lex_file. + # + # The formatting of the source of this method is purposeful to illustrate + # the structure of the serialized data. + def self.load_lex(input, serialized, freeze) + source = Source.for(input) + loader = Loader.new(source, serialized) + + tokens = loader.load_tokens + encoding = loader.load_encoding + start_line = loader.load_varsint + offsets = loader.load_line_offsets(freeze) + + source.replace_start_line(start_line) + source.replace_offsets(offsets) + + comments = loader.load_comments(freeze) + magic_comments = loader.load_magic_comments(freeze) + data_loc = loader.load_optional_location_object(freeze) + errors = loader.load_errors(encoding, freeze) + warnings = loader.load_warnings(encoding, freeze) + raise unless loader.eof? + + result = LexResult.new(tokens, comments, magic_comments, data_loc, errors, warnings, source) + + tokens.each do |token| + token[0].value.force_encoding(encoding) + + if freeze + token[0].deep_freeze + token.freeze + end + end + + if freeze + source.deep_freeze + tokens.freeze + result.freeze + end + + result + end + + # Deserialize the dumped output from a request to parse_comments or + # parse_file_comments. + # + # The formatting of the source of this method is purposeful to illustrate + # the structure of the serialized data. + def self.load_parse_comments(input, serialized, freeze) + source = Source.for(input) + loader = Loader.new(source, serialized) + + loader.load_header + loader.load_encoding + start_line = loader.load_varsint + + source.replace_start_line(start_line) + + result = loader.load_comments(freeze) + raise unless loader.eof? + + source.deep_freeze if freeze + result + end + + # Deserialize the dumped output from a request to parse_lex or + # parse_lex_file. + # + # The formatting of the source of this method is purposeful to illustrate + # the structure of the serialized data. + def self.load_parse_lex(input, serialized, freeze) + source = Source.for(input) + loader = Loader.new(source, serialized) + + tokens = loader.load_tokens + loader.load_header + encoding = loader.load_encoding + start_line = loader.load_varsint + offsets = loader.load_line_offsets(freeze) + + source.replace_start_line(start_line) + source.replace_offsets(offsets) + + comments = loader.load_comments(freeze) + magic_comments = loader.load_magic_comments(freeze) + data_loc = loader.load_optional_location_object(freeze) + errors = loader.load_errors(encoding, freeze) + warnings = loader.load_warnings(encoding, freeze) + cpool_base = loader.load_uint32 + cpool_size = loader.load_varuint + + constant_pool = ConstantPool.new(input, serialized, cpool_base, cpool_size) + + node = loader.load_node(constant_pool, encoding, freeze) + loader.load_constant_pool(constant_pool) + raise unless loader.eof? + + value = [node, tokens] + result = ParseLexResult.new(value, comments, magic_comments, data_loc, errors, warnings, source) + + tokens.each do |token| + token[0].value.force_encoding(encoding) + + if freeze + token[0].deep_freeze + token.freeze + end + end + + if freeze + source.deep_freeze + tokens.freeze + value.freeze + result.freeze + end + + result + end + + class ConstantPool # :nodoc: + attr_reader :size + + def initialize(input, serialized, base, size) + @input = input + @serialized = serialized + @base = base + @size = size + @pool = Array.new(size, nil) + end + + def get(index, encoding) + @pool[index] ||= + begin + offset = @base + index * 8 + start = @serialized.unpack1("L", offset: offset) + length = @serialized.unpack1("L", offset: offset + 4) + + if start.nobits?(1 << 31) + @input.byteslice(start, length).force_encoding(encoding).to_sym + else + @serialized.byteslice(start & ((1 << 31) - 1), length).force_encoding(encoding).to_sym + end + end + end + end + + if RUBY_ENGINE == "truffleruby" + # StringIO is synchronized and that adds a high overhead on TruffleRuby. + class FastStringIO # :nodoc: + attr_accessor :pos + + def initialize(string) + @string = string + @pos = 0 + end + + def getbyte + byte = @string.getbyte(@pos) + @pos += 1 + byte + end + + def read(n) + slice = @string.byteslice(@pos, n) + @pos += n + slice + end + + def eof? + @pos >= @string.bytesize + end + end + else + FastStringIO = ::StringIO # :nodoc: + end + + class Loader # :nodoc: + attr_reader :input, :io, :source + + def initialize(source, serialized) + @input = source.source.dup + raise unless serialized.encoding == Encoding::BINARY + @io = FastStringIO.new(serialized) + @source = source + define_load_node_lambdas if RUBY_ENGINE != "ruby" + end + + def eof? + io.getbyte + io.eof? + end + + def load_constant_pool(constant_pool) + trailer = 0 + + constant_pool.size.times do |index| + start, length = io.read(8).unpack("L2") + trailer += length if start.anybits?(1 << 31) + end + + io.read(trailer) + end + + def load_header + raise "Invalid serialization" if io.read(5) != "PRISM" + raise "Invalid serialization" if io.read(3).unpack("C3") != [MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION] + raise "Invalid serialization (location fields must be included but are not)" if io.getbyte != 0 + end + + def load_encoding + encoding = Encoding.find(io.read(load_varuint)) + @input = input.force_encoding(encoding).freeze + encoding + end + + def load_line_offsets(freeze) + offsets = Array.new(load_varuint) { load_varuint } + offsets.freeze if freeze + offsets + end + + def load_comments(freeze) + comments = + Array.new(load_varuint) do + comment = + case load_varuint + when 0 then InlineComment.new(load_location_object(freeze)) + when 1 then EmbDocComment.new(load_location_object(freeze)) + end + + comment.freeze if freeze + comment + end + + comments.freeze if freeze + comments + end + + def load_magic_comments(freeze) + magic_comments = + Array.new(load_varuint) do + magic_comment = + MagicComment.new( + load_location_object(freeze), + load_location_object(freeze) + ) + + magic_comment.freeze if freeze + magic_comment + end + + magic_comments.freeze if freeze + magic_comments + end + + DIAGNOSTIC_TYPES = [ + :alias_argument, + :alias_argument_numbered_reference, + :ampampeq_multi_assign, + :argument_after_block, + :argument_after_forwarding_ellipses, + :argument_bare_hash, + :argument_block_forwarding, + :argument_block_multi, + :argument_conflict_ampersand, + :argument_conflict_star, + :argument_conflict_star_star, + :argument_formal_class, + :argument_formal_constant, + :argument_formal_global, + :argument_formal_ivar, + :argument_forwarding_unbound, + :argument_no_forwarding_ampersand, + :argument_no_forwarding_ellipses, + :argument_no_forwarding_star, + :argument_no_forwarding_star_star, + :argument_splat_after_assoc_splat, + :argument_splat_after_splat, + :argument_term_paren, + :argument_unexpected_block, + :array_element, + :array_expression, + :array_expression_after_star, + :array_separator, + :array_term, + :begin_lonely_else, + :begin_term, + :begin_upcase_brace, + :begin_upcase_term, + :begin_upcase_toplevel, + :block_param_local_variable, + :block_param_pipe_term, + :block_term_brace, + :block_term_end, + :cannot_parse_expression, + :cannot_parse_string_part, + :case_expression_after_case, + :case_expression_after_when, + :case_match_missing_predicate, + :case_missing_conditions, + :case_term, + :class_in_method, + :class_name, + :class_superclass, + :class_term, + :class_unexpected_end, + :class_variable_bare, + :conditional_elsif_predicate, + :conditional_if_predicate, + :conditional_predicate_term, + :conditional_term, + :conditional_term_else, + :conditional_unless_predicate, + :conditional_until_predicate, + :conditional_while_predicate, + :constant_path_colon_colon_constant, + :def_endless, + :def_endless_setter, + :def_name, + :def_params_term, + :def_params_term_paren, + :def_receiver, + :def_receiver_term, + :def_term, + :defined_expression, + :embdoc_term, + :embexpr_end, + :embvar_invalid, + :end_upcase_brace, + :end_upcase_term, + :escape_invalid_control, + :escape_invalid_control_repeat, + :escape_invalid_hexadecimal, + :escape_invalid_meta, + :escape_invalid_meta_repeat, + :escape_invalid_unicode, + :escape_invalid_unicode_cm_flags, + :escape_invalid_unicode_list, + :escape_invalid_unicode_literal, + :escape_invalid_unicode_long, + :escape_invalid_unicode_short, + :escape_invalid_unicode_term, + :expect_argument, + :expect_eol_after_statement, + :expect_expression_after_ampampeq, + :expect_expression_after_comma, + :expect_expression_after_equal, + :expect_expression_after_less_less, + :expect_expression_after_lparen, + :expect_expression_after_operator, + :expect_expression_after_pipepipeeq, + :expect_expression_after_question, + :expect_expression_after_splat, + :expect_expression_after_splat_hash, + :expect_expression_after_star, + :expect_for_delimiter, + :expect_ident_req_parameter, + :expect_in_delimiter, + :expect_lparen_req_parameter, + :expect_message, + :expect_rbracket, + :expect_rparen, + :expect_rparen_after_multi, + :expect_rparen_req_parameter, + :expect_singleton_class_delimiter, + :expect_string_content, + :expect_when_delimiter, + :expression_bare_hash, + :expression_not_writable, + :expression_not_writable_encoding, + :expression_not_writable_false, + :expression_not_writable_file, + :expression_not_writable_line, + :expression_not_writable_nil, + :expression_not_writable_numbered, + :expression_not_writable_self, + :expression_not_writable_true, + :float_parse, + :for_collection, + :for_in, + :for_index, + :for_term, + :global_variable_bare, + :hash_expression_after_label, + :hash_key, + :hash_rocket, + :hash_term, + :hash_value, + :heredoc_identifier, + :heredoc_term, + :incomplete_question_mark, + :incomplete_variable_class, + :incomplete_variable_class_3_3, + :incomplete_variable_instance, + :incomplete_variable_instance_3_3, + :instance_variable_bare, + :invalid_block_exit, + :invalid_character, + :invalid_comma, + :invalid_encoding_magic_comment, + :invalid_escape_character, + :invalid_float_exponent, + :invalid_local_variable_read, + :invalid_local_variable_write, + :invalid_multibyte_char, + :invalid_multibyte_character, + :invalid_multibyte_escape, + :invalid_number_binary, + :invalid_number_decimal, + :invalid_number_fraction, + :invalid_number_hexadecimal, + :invalid_number_octal, + :invalid_number_underscore_inner, + :invalid_number_underscore_trailing, + :invalid_percent, + :invalid_percent_eof, + :invalid_printable_character, + :invalid_retry_after_else, + :invalid_retry_after_ensure, + :invalid_retry_without_rescue, + :invalid_symbol, + :invalid_variable_global, + :invalid_variable_global_3_3, + :invalid_yield, + :it_not_allowed_numbered, + :it_not_allowed_ordinary, + :lambda_open, + :lambda_term_brace, + :lambda_term_end, + :list_i_lower_element, + :list_i_lower_term, + :list_i_upper_element, + :list_i_upper_term, + :list_w_lower_element, + :list_w_lower_term, + :list_w_upper_element, + :list_w_upper_term, + :malloc_failed, + :mixed_encoding, + :module_in_method, + :module_name, + :module_term, + :multi_assign_multi_splats, + :multi_assign_unexpected_rest, + :nesting_too_deep, + :no_local_variable, + :non_associative_operator, + :not_expression, + :number_literal_underscore, + :numbered_parameter_inner_block, + :numbered_parameter_it, + :numbered_parameter_ordinary, + :numbered_parameter_outer_block, + :operator_multi_assign, + :operator_write_arguments, + :operator_write_block, + :parameter_assoc_splat_multi, + :parameter_block_multi, + :parameter_circular, + :parameter_forwarding_after_rest, + :parameter_method_name, + :parameter_name_duplicated, + :parameter_no_default, + :parameter_no_default_kw, + :parameter_numbered_reserved, + :parameter_order, + :parameter_splat_multi, + :parameter_star, + :parameter_unexpected_fwd, + :parameter_unexpected_no_kw, + :parameter_wild_loose_comma, + :pattern_array_multiple_rests, + :pattern_capture_duplicate, + :pattern_expression_after_bracket, + :pattern_expression_after_comma, + :pattern_expression_after_hrocket, + :pattern_expression_after_in, + :pattern_expression_after_key, + :pattern_expression_after_paren, + :pattern_expression_after_pin, + :pattern_expression_after_pipe, + :pattern_expression_after_range, + :pattern_expression_after_rest, + :pattern_find_missing_inner, + :pattern_hash_implicit, + :pattern_hash_key, + :pattern_hash_key_duplicate, + :pattern_hash_key_interpolated, + :pattern_hash_key_label, + :pattern_hash_key_locals, + :pattern_ident_after_hrocket, + :pattern_label_after_comma, + :pattern_rest, + :pattern_term_brace, + :pattern_term_bracket, + :pattern_term_paren, + :pipepipeeq_multi_assign, + :regexp_encoding_option_mismatch, + :regexp_incompat_char_encoding, + :regexp_invalid_unicode_range, + :regexp_non_escaped_mbc, + :regexp_parse_error, + :regexp_term, + :regexp_unknown_options, + :regexp_utf8_char_non_utf8_regexp, + :rescue_expression, + :rescue_modifier_value, + :rescue_term, + :rescue_variable, + :return_invalid, + :script_not_found, + :singleton_for_literals, + :statement_alias, + :statement_postexe_end, + :statement_preexe_begin, + :statement_undef, + :string_concatenation, + :string_interpolated_term, + :string_literal_eof, + :string_literal_term, + :symbol_invalid, + :symbol_term_dynamic, + :symbol_term_interpolated, + :ternary_colon, + :ternary_expression_false, + :ternary_expression_true, + :unary_disallowed, + :unary_receiver, + :undef_argument, + :unexpected_block_argument, + :unexpected_index_block, + :unexpected_index_keywords, + :unexpected_label, + :unexpected_multi_write, + :unexpected_range_operator, + :unexpected_safe_navigation, + :unexpected_token_close_context, + :unexpected_token_ignore, + :until_term, + :void_expression, + :while_term, + :write_target_in_method, + :write_target_readonly, + :write_target_unexpected, + :xstring_term, + :ambiguous_binary_operator, + :ambiguous_first_argument_minus, + :ambiguous_first_argument_plus, + :ambiguous_prefix_ampersand, + :ambiguous_prefix_star, + :ambiguous_prefix_star_star, + :ambiguous_slash, + :comparison_after_comparison, + :dot_dot_dot_eol, + :equal_in_conditional, + :equal_in_conditional_3_3, + :end_in_method, + :duplicated_hash_key, + :duplicated_when_clause, + :float_out_of_range, + :ignored_frozen_string_literal, + :indentation_mismatch, + :integer_in_flip_flop, + :invalid_character, + :invalid_magic_comment_value, + :invalid_numbered_reference, + :keyword_eol, + :literal_in_condition_default, + :literal_in_condition_verbose, + :shareable_constant_value_line, + :shebang_carriage_return, + :unexpected_carriage_return, + :unreachable_statement, + :unused_local_variable, + :void_statement, + ].freeze + + private_constant :DIAGNOSTIC_TYPES + + def load_error_level + level = io.getbyte + + case level + when 0 + :syntax + when 1 + :argument + when 2 + :load + else + raise "Unknown level: #{level}" + end + end + + def load_errors(encoding, freeze) + errors = + Array.new(load_varuint) do + error = + ParseError.new( + DIAGNOSTIC_TYPES.fetch(load_varuint), + load_embedded_string(encoding), + load_location_object(freeze), + load_error_level + ) + + error.freeze if freeze + error + end + + errors.freeze if freeze + errors + end + + def load_warning_level + level = io.getbyte + + case level + when 0 + :default + when 1 + :verbose + else + raise "Unknown level: #{level}" + end + end + + def load_warnings(encoding, freeze) + warnings = + Array.new(load_varuint) do + warning = + ParseWarning.new( + DIAGNOSTIC_TYPES.fetch(load_varuint), + load_embedded_string(encoding), + load_location_object(freeze), + load_warning_level + ) + + warning.freeze if freeze + warning + end + + warnings.freeze if freeze + warnings + end + + def load_tokens + tokens = [] + + while (type = TOKEN_TYPES.fetch(load_varuint)) + start = load_varuint + length = load_varuint + lex_state = load_varuint + + location = Location.new(@source, start, length) + token = Token.new(@source, type, location.slice, location) + + tokens << [token, lex_state] + end + + tokens + end + + # variable-length integer using https://en.wikipedia.org/wiki/LEB128 + # This is also what protobuf uses: https://protobuf.dev/programming-guides/encoding/#varints + def load_varuint + n = io.getbyte + if n < 128 + n + else + n -= 128 + shift = 0 + while (b = io.getbyte) >= 128 + n += (b - 128) << (shift += 7) + end + n + (b << (shift + 7)) + end + end + + def load_varsint + n = load_varuint + (n >> 1) ^ (-(n & 1)) + end + + def load_integer + negative = io.getbyte != 0 + length = load_varuint + + value = 0 + length.times { |index| value |= (load_varuint << (index * 32)) } + + value = -value if negative + value + end + + def load_double + io.read(8).unpack1("D") + end + + def load_uint32 + io.read(4).unpack1("L") + end + + def load_optional_node(constant_pool, encoding, freeze) + if io.getbyte != 0 + io.pos -= 1 + load_node(constant_pool, encoding, freeze) + end + end + + def load_embedded_string(encoding) + io.read(load_varuint).force_encoding(encoding).freeze + end + + def load_string(encoding) + case (type = io.getbyte) + when 1 + input.byteslice(load_varuint, load_varuint).force_encoding(encoding).freeze + when 2 + load_embedded_string(encoding) + else + raise "Unknown serialized string type: #{type}" + end + end + + def load_location_object(freeze) + location = Location.new(source, load_varuint, load_varuint) + location.freeze if freeze + location + end + + def load_location(freeze) + return load_location_object(freeze) if freeze + (load_varuint << 32) | load_varuint + end + + def load_optional_location(freeze) + load_location(freeze) if io.getbyte != 0 + end + + def load_optional_location_object(freeze) + load_location_object(freeze) if io.getbyte != 0 + end + + def load_constant(constant_pool, encoding) + index = load_varuint + constant_pool.get(index - 1, encoding) + end + + def load_optional_constant(constant_pool, encoding) + index = load_varuint + constant_pool.get(index - 1, encoding) if index != 0 + end + + if RUBY_ENGINE == "ruby" + def load_node(constant_pool, encoding, freeze) + type = io.getbyte + node_id = load_varuint + location = load_location(freeze) + value = case type + when 1 then + AliasGlobalVariableNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + when 2 then + AliasMethodNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + when 3 then + AlternationPatternNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + when 4 then + AndNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + when 5 then + ArgumentsNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }) + when 6 then + ArrayNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, load_optional_location(freeze), load_optional_location(freeze)) + when 7 then + ArrayPatternNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, load_optional_node(constant_pool, encoding, freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, load_optional_location(freeze), load_optional_location(freeze)) + when 8 then + AssocNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_node(constant_pool, encoding, freeze), load_optional_location(freeze)) + when 9 then + AssocSplatNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_location(freeze)) + when 10 then + BackReferenceReadNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding)) + when 11 then + BeginNode.new(source, node_id, location, load_varuint, load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze)) + when 12 then + BlockArgumentNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_location(freeze)) + when 13 then + BlockLocalVariableNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding)) + when 14 then + BlockNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_constant(constant_pool, encoding) }.tap { |constants| constants.freeze if freeze }, load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_location(freeze)) + when 15 then + BlockParameterNode.new(source, node_id, location, load_varuint, load_optional_constant(constant_pool, encoding), load_optional_location(freeze), load_location(freeze)) + when 16 then + BlockParametersNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, load_optional_location(freeze), load_optional_location(freeze)) + when 17 then + BreakNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_location(freeze)) + when 18 then + CallAndWriteNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_location(freeze), load_constant(constant_pool, encoding), load_constant(constant_pool, encoding), load_location(freeze), load_node(constant_pool, encoding, freeze)) + when 19 then + CallNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_constant(constant_pool, encoding), load_optional_location(freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze)) + when 20 then + CallOperatorWriteNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_location(freeze), load_constant(constant_pool, encoding), load_constant(constant_pool, encoding), load_constant(constant_pool, encoding), load_location(freeze), load_node(constant_pool, encoding, freeze)) + when 21 then + CallOrWriteNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_location(freeze), load_constant(constant_pool, encoding), load_constant(constant_pool, encoding), load_location(freeze), load_node(constant_pool, encoding, freeze)) + when 22 then + CallTargetNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_location(freeze), load_constant(constant_pool, encoding), load_location(freeze)) + when 23 then + CapturePatternNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + when 24 then + CaseMatchNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_location(freeze)) + when 25 then + CaseNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_location(freeze)) + when 26 then + ClassNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_constant(constant_pool, encoding) }.tap { |constants| constants.freeze if freeze }, load_location(freeze), load_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_constant(constant_pool, encoding)) + when 27 then + ClassVariableAndWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + when 28 then + ClassVariableOperatorWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze), load_constant(constant_pool, encoding)) + when 29 then + ClassVariableOrWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + when 30 then + ClassVariableReadNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding)) + when 31 then + ClassVariableTargetNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding)) + when 32 then + ClassVariableWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + when 33 then + ConstantAndWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + when 34 then + ConstantOperatorWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze), load_constant(constant_pool, encoding)) + when 35 then + ConstantOrWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + when 36 then + ConstantPathAndWriteNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + when 37 then + ConstantPathNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_constant(constant_pool, encoding), load_location(freeze), load_location(freeze)) + when 38 then + ConstantPathOperatorWriteNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_location(freeze), load_node(constant_pool, encoding, freeze), load_constant(constant_pool, encoding)) + when 39 then + ConstantPathOrWriteNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + when 40 then + ConstantPathTargetNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_constant(constant_pool, encoding), load_location(freeze), load_location(freeze)) + when 41 then + ConstantPathWriteNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + when 42 then + ConstantReadNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding)) + when 43 then + ConstantTargetNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding)) + when 44 then + ConstantWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + when 45 then + load_uint32 + DefNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), Array.new(load_varuint) { load_constant(constant_pool, encoding) }.tap { |constants| constants.freeze if freeze }, load_location(freeze), load_optional_location(freeze), load_optional_location(freeze), load_optional_location(freeze), load_optional_location(freeze), load_optional_location(freeze)) + when 46 then + DefinedNode.new(source, node_id, location, load_varuint, load_optional_location(freeze), load_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_location(freeze)) + when 47 then + ElseNode.new(source, node_id, location, load_varuint, load_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze)) + when 48 then + EmbeddedStatementsNode.new(source, node_id, location, load_varuint, load_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze)) + when 49 then + EmbeddedVariableNode.new(source, node_id, location, load_varuint, load_location(freeze), load_node(constant_pool, encoding, freeze)) + when 50 then + EnsureNode.new(source, node_id, location, load_varuint, load_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze)) + when 51 then + FalseNode.new(source, node_id, location, load_varuint) + when 52 then + FindPatternNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_node(constant_pool, encoding, freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, load_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_location(freeze)) + when 53 then + FlipFlopNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze)) + when 54 then + FloatNode.new(source, node_id, location, load_varuint, load_double) + when 55 then + ForNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_location(freeze), load_optional_location(freeze), load_location(freeze)) + when 56 then + ForwardingArgumentsNode.new(source, node_id, location, load_varuint) + when 57 then + ForwardingParameterNode.new(source, node_id, location, load_varuint) + when 58 then + ForwardingSuperNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze)) + when 59 then + GlobalVariableAndWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + when 60 then + GlobalVariableOperatorWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze), load_constant(constant_pool, encoding)) + when 61 then + GlobalVariableOrWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + when 62 then + GlobalVariableReadNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding)) + when 63 then + GlobalVariableTargetNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding)) + when 64 then + GlobalVariableWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + when 65 then + HashNode.new(source, node_id, location, load_varuint, load_location(freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, load_location(freeze)) + when 66 then + HashPatternNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_location(freeze)) + when 67 then + IfNode.new(source, node_id, location, load_varuint, load_optional_location(freeze), load_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze)) + when 68 then + ImaginaryNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze)) + when 69 then + ImplicitNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze)) + when 70 then + ImplicitRestNode.new(source, node_id, location, load_varuint) + when 71 then + InNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_optional_location(freeze)) + when 72 then + IndexAndWriteNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + when 73 then + IndexOperatorWriteNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_constant(constant_pool, encoding), load_location(freeze), load_node(constant_pool, encoding, freeze)) + when 74 then + IndexOrWriteNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + when 75 then + IndexTargetNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_optional_node(constant_pool, encoding, freeze)) + when 76 then + InstanceVariableAndWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + when 77 then + InstanceVariableOperatorWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze), load_constant(constant_pool, encoding)) + when 78 then + InstanceVariableOrWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + when 79 then + InstanceVariableReadNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding)) + when 80 then + InstanceVariableTargetNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding)) + when 81 then + InstanceVariableWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + when 82 then + IntegerNode.new(source, node_id, location, load_varuint, load_integer) + when 83 then + InterpolatedMatchLastLineNode.new(source, node_id, location, load_varuint, load_location(freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, load_location(freeze)) + when 84 then + InterpolatedRegularExpressionNode.new(source, node_id, location, load_varuint, load_location(freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, load_location(freeze)) + when 85 then + InterpolatedStringNode.new(source, node_id, location, load_varuint, load_optional_location(freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, load_optional_location(freeze)) + when 86 then + InterpolatedSymbolNode.new(source, node_id, location, load_varuint, load_optional_location(freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, load_optional_location(freeze)) + when 87 then + InterpolatedXStringNode.new(source, node_id, location, load_varuint, load_location(freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, load_location(freeze)) + when 88 then + ItLocalVariableReadNode.new(source, node_id, location, load_varuint) + when 89 then + ItParametersNode.new(source, node_id, location, load_varuint) + when 90 then + KeywordHashNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }) + when 91 then + KeywordRestParameterNode.new(source, node_id, location, load_varuint, load_optional_constant(constant_pool, encoding), load_optional_location(freeze), load_location(freeze)) + when 92 then + LambdaNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_constant(constant_pool, encoding) }.tap { |constants| constants.freeze if freeze }, load_location(freeze), load_location(freeze), load_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze)) + when 93 then + LocalVariableAndWriteNode.new(source, node_id, location, load_varuint, load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze), load_constant(constant_pool, encoding), load_varuint) + when 94 then + LocalVariableOperatorWriteNode.new(source, node_id, location, load_varuint, load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze), load_constant(constant_pool, encoding), load_constant(constant_pool, encoding), load_varuint) + when 95 then + LocalVariableOrWriteNode.new(source, node_id, location, load_varuint, load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze), load_constant(constant_pool, encoding), load_varuint) + when 96 then + LocalVariableReadNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_varuint) + when 97 then + LocalVariableTargetNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_varuint) + when 98 then + LocalVariableWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_varuint, load_location(freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + when 99 then + MatchLastLineNode.new(source, node_id, location, load_varuint, load_location(freeze), load_location(freeze), load_location(freeze), load_string(encoding)) + when 100 then + MatchPredicateNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + when 101 then + MatchRequiredNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + when 102 then + MatchWriteNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }) + when 103 then + MissingNode.new(source, node_id, location, load_varuint) + when 104 then + ModuleNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_constant(constant_pool, encoding) }.tap { |constants| constants.freeze if freeze }, load_location(freeze), load_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_constant(constant_pool, encoding)) + when 105 then + MultiTargetNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, load_optional_node(constant_pool, encoding, freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, load_optional_location(freeze), load_optional_location(freeze)) + when 106 then + MultiWriteNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, load_optional_node(constant_pool, encoding, freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, load_optional_location(freeze), load_optional_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + when 107 then + NextNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_location(freeze)) + when 108 then + NilNode.new(source, node_id, location, load_varuint) + when 109 then + NoKeywordsParameterNode.new(source, node_id, location, load_varuint, load_location(freeze), load_location(freeze)) + when 110 then + NumberedParametersNode.new(source, node_id, location, load_varuint, io.getbyte) + when 111 then + NumberedReferenceReadNode.new(source, node_id, location, load_varuint, load_varuint) + when 112 then + OptionalKeywordParameterNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_node(constant_pool, encoding, freeze)) + when 113 then + OptionalParameterNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + when 114 then + OrNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + when 115 then + ParametersNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, load_optional_node(constant_pool, encoding, freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze)) + when 116 then + ParenthesesNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_location(freeze)) + when 117 then + PinnedExpressionNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_location(freeze), load_location(freeze), load_location(freeze)) + when 118 then + PinnedVariableNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_location(freeze)) + when 119 then + PostExecutionNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_location(freeze), load_location(freeze)) + when 120 then + PreExecutionNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_location(freeze), load_location(freeze)) + when 121 then + ProgramNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_constant(constant_pool, encoding) }.tap { |constants| constants.freeze if freeze }, load_node(constant_pool, encoding, freeze)) + when 122 then + RangeNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze)) + when 123 then + RationalNode.new(source, node_id, location, load_varuint, load_integer, load_integer) + when 124 then + RedoNode.new(source, node_id, location, load_varuint) + when 125 then + RegularExpressionNode.new(source, node_id, location, load_varuint, load_location(freeze), load_location(freeze), load_location(freeze), load_string(encoding)) + when 126 then + RequiredKeywordParameterNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze)) + when 127 then + RequiredParameterNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding)) + when 128 then + RescueModifierNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + when 129 then + RescueNode.new(source, node_id, location, load_varuint, load_location(freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze)) + when 130 then + RestParameterNode.new(source, node_id, location, load_varuint, load_optional_constant(constant_pool, encoding), load_optional_location(freeze), load_location(freeze)) + when 131 then + RetryNode.new(source, node_id, location, load_varuint) + when 132 then + ReturnNode.new(source, node_id, location, load_varuint, load_location(freeze), load_optional_node(constant_pool, encoding, freeze)) + when 133 then + SelfNode.new(source, node_id, location, load_varuint) + when 134 then + ShareableConstantNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze)) + when 135 then + SingletonClassNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_constant(constant_pool, encoding) }.tap { |constants| constants.freeze if freeze }, load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze)) + when 136 then + SourceEncodingNode.new(source, node_id, location, load_varuint) + when 137 then + SourceFileNode.new(source, node_id, location, load_varuint, load_string(encoding)) + when 138 then + SourceLineNode.new(source, node_id, location, load_varuint) + when 139 then + SplatNode.new(source, node_id, location, load_varuint, load_location(freeze), load_optional_node(constant_pool, encoding, freeze)) + when 140 then + StatementsNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }) + when 141 then + StringNode.new(source, node_id, location, load_varuint, load_optional_location(freeze), load_location(freeze), load_optional_location(freeze), load_string(encoding)) + when 142 then + SuperNode.new(source, node_id, location, load_varuint, load_location(freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze)) + when 143 then + SymbolNode.new(source, node_id, location, load_varuint, load_optional_location(freeze), load_optional_location(freeze), load_optional_location(freeze), load_string(encoding)) + when 144 then + TrueNode.new(source, node_id, location, load_varuint) + when 145 then + UndefNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, load_location(freeze)) + when 146 then + UnlessNode.new(source, node_id, location, load_varuint, load_location(freeze), load_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze)) + when 147 then + UntilNode.new(source, node_id, location, load_varuint, load_location(freeze), load_optional_location(freeze), load_optional_location(freeze), load_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze)) + when 148 then + WhenNode.new(source, node_id, location, load_varuint, load_location(freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }.tap { |nodes| nodes.freeze if freeze }, load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze)) + when 149 then + WhileNode.new(source, node_id, location, load_varuint, load_location(freeze), load_optional_location(freeze), load_optional_location(freeze), load_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze)) + when 150 then + XStringNode.new(source, node_id, location, load_varuint, load_location(freeze), load_location(freeze), load_location(freeze), load_string(encoding)) + when 151 then + YieldNode.new(source, node_id, location, load_varuint, load_location(freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze)) + end + + value.freeze if freeze + value + end + else + def load_node(constant_pool, encoding, freeze) + @load_node_lambdas[io.getbyte].call(constant_pool, encoding, freeze) + end + + def define_load_node_lambdas + @load_node_lambdas = [ + nil, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = AliasGlobalVariableNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = AliasMethodNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = AlternationPatternNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = AndNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ArgumentsNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ArrayNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, load_optional_location(freeze), load_optional_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ArrayPatternNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, load_optional_node(constant_pool, encoding, freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, load_optional_location(freeze), load_optional_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = AssocNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_node(constant_pool, encoding, freeze), load_optional_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = AssocSplatNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = BackReferenceReadNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = BeginNode.new(source, node_id, location, load_varuint, load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = BlockArgumentNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = BlockLocalVariableNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = BlockNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_constant(constant_pool, encoding) }, load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = BlockParameterNode.new(source, node_id, location, load_varuint, load_optional_constant(constant_pool, encoding), load_optional_location(freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = BlockParametersNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, load_optional_location(freeze), load_optional_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = BreakNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = CallAndWriteNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_location(freeze), load_constant(constant_pool, encoding), load_constant(constant_pool, encoding), load_location(freeze), load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = CallNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_constant(constant_pool, encoding), load_optional_location(freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = CallOperatorWriteNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_location(freeze), load_constant(constant_pool, encoding), load_constant(constant_pool, encoding), load_constant(constant_pool, encoding), load_location(freeze), load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = CallOrWriteNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_location(freeze), load_constant(constant_pool, encoding), load_constant(constant_pool, encoding), load_location(freeze), load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = CallTargetNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_location(freeze), load_constant(constant_pool, encoding), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = CapturePatternNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = CaseMatchNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = CaseNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ClassNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_constant(constant_pool, encoding) }, load_location(freeze), load_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_constant(constant_pool, encoding)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ClassVariableAndWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ClassVariableOperatorWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze), load_constant(constant_pool, encoding)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ClassVariableOrWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ClassVariableReadNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ClassVariableTargetNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ClassVariableWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ConstantAndWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ConstantOperatorWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze), load_constant(constant_pool, encoding)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ConstantOrWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ConstantPathAndWriteNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ConstantPathNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_constant(constant_pool, encoding), load_location(freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ConstantPathOperatorWriteNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_location(freeze), load_node(constant_pool, encoding, freeze), load_constant(constant_pool, encoding)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ConstantPathOrWriteNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ConstantPathTargetNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_constant(constant_pool, encoding), load_location(freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ConstantPathWriteNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ConstantReadNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ConstantTargetNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ConstantWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + load_uint32 + value = DefNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), Array.new(load_varuint) { load_constant(constant_pool, encoding) }, load_location(freeze), load_optional_location(freeze), load_optional_location(freeze), load_optional_location(freeze), load_optional_location(freeze), load_optional_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = DefinedNode.new(source, node_id, location, load_varuint, load_optional_location(freeze), load_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ElseNode.new(source, node_id, location, load_varuint, load_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = EmbeddedStatementsNode.new(source, node_id, location, load_varuint, load_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = EmbeddedVariableNode.new(source, node_id, location, load_varuint, load_location(freeze), load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = EnsureNode.new(source, node_id, location, load_varuint, load_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = FalseNode.new(source, node_id, location, load_varuint) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = FindPatternNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_node(constant_pool, encoding, freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, load_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = FlipFlopNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = FloatNode.new(source, node_id, location, load_varuint, load_double) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ForNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_location(freeze), load_optional_location(freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ForwardingArgumentsNode.new(source, node_id, location, load_varuint) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ForwardingParameterNode.new(source, node_id, location, load_varuint) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ForwardingSuperNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = GlobalVariableAndWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = GlobalVariableOperatorWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze), load_constant(constant_pool, encoding)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = GlobalVariableOrWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = GlobalVariableReadNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = GlobalVariableTargetNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = GlobalVariableWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = HashNode.new(source, node_id, location, load_varuint, load_location(freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = HashPatternNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = IfNode.new(source, node_id, location, load_varuint, load_optional_location(freeze), load_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ImaginaryNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ImplicitNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ImplicitRestNode.new(source, node_id, location, load_varuint) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = InNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_optional_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = IndexAndWriteNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = IndexOperatorWriteNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_constant(constant_pool, encoding), load_location(freeze), load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = IndexOrWriteNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = IndexTargetNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_optional_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = InstanceVariableAndWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = InstanceVariableOperatorWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze), load_constant(constant_pool, encoding)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = InstanceVariableOrWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = InstanceVariableReadNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = InstanceVariableTargetNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = InstanceVariableWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = IntegerNode.new(source, node_id, location, load_varuint, load_integer) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = InterpolatedMatchLastLineNode.new(source, node_id, location, load_varuint, load_location(freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = InterpolatedRegularExpressionNode.new(source, node_id, location, load_varuint, load_location(freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = InterpolatedStringNode.new(source, node_id, location, load_varuint, load_optional_location(freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, load_optional_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = InterpolatedSymbolNode.new(source, node_id, location, load_varuint, load_optional_location(freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, load_optional_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = InterpolatedXStringNode.new(source, node_id, location, load_varuint, load_location(freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ItLocalVariableReadNode.new(source, node_id, location, load_varuint) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ItParametersNode.new(source, node_id, location, load_varuint) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = KeywordHashNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = KeywordRestParameterNode.new(source, node_id, location, load_varuint, load_optional_constant(constant_pool, encoding), load_optional_location(freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = LambdaNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_constant(constant_pool, encoding) }, load_location(freeze), load_location(freeze), load_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = LocalVariableAndWriteNode.new(source, node_id, location, load_varuint, load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze), load_constant(constant_pool, encoding), load_varuint) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = LocalVariableOperatorWriteNode.new(source, node_id, location, load_varuint, load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze), load_constant(constant_pool, encoding), load_constant(constant_pool, encoding), load_varuint) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = LocalVariableOrWriteNode.new(source, node_id, location, load_varuint, load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze), load_constant(constant_pool, encoding), load_varuint) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = LocalVariableReadNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_varuint) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = LocalVariableTargetNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_varuint) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = LocalVariableWriteNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_varuint, load_location(freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = MatchLastLineNode.new(source, node_id, location, load_varuint, load_location(freeze), load_location(freeze), load_location(freeze), load_string(encoding)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = MatchPredicateNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = MatchRequiredNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = MatchWriteNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = MissingNode.new(source, node_id, location, load_varuint) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ModuleNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_constant(constant_pool, encoding) }, load_location(freeze), load_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_constant(constant_pool, encoding)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = MultiTargetNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, load_optional_node(constant_pool, encoding, freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, load_optional_location(freeze), load_optional_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = MultiWriteNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, load_optional_node(constant_pool, encoding, freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, load_optional_location(freeze), load_optional_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = NextNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = NilNode.new(source, node_id, location, load_varuint) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = NoKeywordsParameterNode.new(source, node_id, location, load_varuint, load_location(freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = NumberedParametersNode.new(source, node_id, location, load_varuint, io.getbyte) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = NumberedReferenceReadNode.new(source, node_id, location, load_varuint, load_varuint) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = OptionalKeywordParameterNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = OptionalParameterNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = OrNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_node(constant_pool, encoding, freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ParametersNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, load_optional_node(constant_pool, encoding, freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ParenthesesNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = PinnedExpressionNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_location(freeze), load_location(freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = PinnedVariableNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = PostExecutionNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_location(freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = PreExecutionNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_location(freeze), load_location(freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ProgramNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_constant(constant_pool, encoding) }, load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = RangeNode.new(source, node_id, location, load_varuint, load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = RationalNode.new(source, node_id, location, load_varuint, load_integer, load_integer) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = RedoNode.new(source, node_id, location, load_varuint) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = RegularExpressionNode.new(source, node_id, location, load_varuint, load_location(freeze), load_location(freeze), load_location(freeze), load_string(encoding)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = RequiredKeywordParameterNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = RequiredParameterNode.new(source, node_id, location, load_varuint, load_constant(constant_pool, encoding)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = RescueModifierNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze), load_location(freeze), load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = RescueNode.new(source, node_id, location, load_varuint, load_location(freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = RestParameterNode.new(source, node_id, location, load_varuint, load_optional_constant(constant_pool, encoding), load_optional_location(freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = RetryNode.new(source, node_id, location, load_varuint) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ReturnNode.new(source, node_id, location, load_varuint, load_location(freeze), load_optional_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = SelfNode.new(source, node_id, location, load_varuint) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = ShareableConstantNode.new(source, node_id, location, load_varuint, load_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = SingletonClassNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_constant(constant_pool, encoding) }, load_location(freeze), load_location(freeze), load_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = SourceEncodingNode.new(source, node_id, location, load_varuint) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = SourceFileNode.new(source, node_id, location, load_varuint, load_string(encoding)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = SourceLineNode.new(source, node_id, location, load_varuint) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = SplatNode.new(source, node_id, location, load_varuint, load_location(freeze), load_optional_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = StatementsNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = StringNode.new(source, node_id, location, load_varuint, load_optional_location(freeze), load_location(freeze), load_optional_location(freeze), load_string(encoding)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = SuperNode.new(source, node_id, location, load_varuint, load_location(freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = SymbolNode.new(source, node_id, location, load_varuint, load_optional_location(freeze), load_optional_location(freeze), load_optional_location(freeze), load_string(encoding)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = TrueNode.new(source, node_id, location, load_varuint) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = UndefNode.new(source, node_id, location, load_varuint, Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, load_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = UnlessNode.new(source, node_id, location, load_varuint, load_location(freeze), load_node(constant_pool, encoding, freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = UntilNode.new(source, node_id, location, load_varuint, load_location(freeze), load_optional_location(freeze), load_optional_location(freeze), load_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = WhenNode.new(source, node_id, location, load_varuint, load_location(freeze), Array.new(load_varuint) { load_node(constant_pool, encoding, freeze) }, load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = WhileNode.new(source, node_id, location, load_varuint, load_location(freeze), load_optional_location(freeze), load_optional_location(freeze), load_node(constant_pool, encoding, freeze), load_optional_node(constant_pool, encoding, freeze)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = XStringNode.new(source, node_id, location, load_varuint, load_location(freeze), load_location(freeze), load_location(freeze), load_string(encoding)) + value.freeze if freeze + value + }, + -> (constant_pool, encoding, freeze) { + node_id = load_varuint + location = load_location(freeze) + value = YieldNode.new(source, node_id, location, load_varuint, load_location(freeze), load_optional_location(freeze), load_optional_node(constant_pool, encoding, freeze), load_optional_location(freeze)) + value.freeze if freeze + value + }, + ] + end + end + end + + # The token types that can be indexed by their enum values. + TOKEN_TYPES = [ + nil, + :EOF, + :MISSING, + :NOT_PROVIDED, + :AMPERSAND, + :AMPERSAND_AMPERSAND, + :AMPERSAND_AMPERSAND_EQUAL, + :AMPERSAND_DOT, + :AMPERSAND_EQUAL, + :BACKTICK, + :BACK_REFERENCE, + :BANG, + :BANG_EQUAL, + :BANG_TILDE, + :BRACE_LEFT, + :BRACE_RIGHT, + :BRACKET_LEFT, + :BRACKET_LEFT_ARRAY, + :BRACKET_LEFT_RIGHT, + :BRACKET_LEFT_RIGHT_EQUAL, + :BRACKET_RIGHT, + :CARET, + :CARET_EQUAL, + :CHARACTER_LITERAL, + :CLASS_VARIABLE, + :COLON, + :COLON_COLON, + :COMMA, + :COMMENT, + :CONSTANT, + :DOT, + :DOT_DOT, + :DOT_DOT_DOT, + :EMBDOC_BEGIN, + :EMBDOC_END, + :EMBDOC_LINE, + :EMBEXPR_BEGIN, + :EMBEXPR_END, + :EMBVAR, + :EQUAL, + :EQUAL_EQUAL, + :EQUAL_EQUAL_EQUAL, + :EQUAL_GREATER, + :EQUAL_TILDE, + :FLOAT, + :FLOAT_IMAGINARY, + :FLOAT_RATIONAL, + :FLOAT_RATIONAL_IMAGINARY, + :GLOBAL_VARIABLE, + :GREATER, + :GREATER_EQUAL, + :GREATER_GREATER, + :GREATER_GREATER_EQUAL, + :HEREDOC_END, + :HEREDOC_START, + :IDENTIFIER, + :IGNORED_NEWLINE, + :INSTANCE_VARIABLE, + :INTEGER, + :INTEGER_IMAGINARY, + :INTEGER_RATIONAL, + :INTEGER_RATIONAL_IMAGINARY, + :KEYWORD_ALIAS, + :KEYWORD_AND, + :KEYWORD_BEGIN, + :KEYWORD_BEGIN_UPCASE, + :KEYWORD_BREAK, + :KEYWORD_CASE, + :KEYWORD_CLASS, + :KEYWORD_DEF, + :KEYWORD_DEFINED, + :KEYWORD_DO, + :KEYWORD_DO_LOOP, + :KEYWORD_ELSE, + :KEYWORD_ELSIF, + :KEYWORD_END, + :KEYWORD_END_UPCASE, + :KEYWORD_ENSURE, + :KEYWORD_FALSE, + :KEYWORD_FOR, + :KEYWORD_IF, + :KEYWORD_IF_MODIFIER, + :KEYWORD_IN, + :KEYWORD_MODULE, + :KEYWORD_NEXT, + :KEYWORD_NIL, + :KEYWORD_NOT, + :KEYWORD_OR, + :KEYWORD_REDO, + :KEYWORD_RESCUE, + :KEYWORD_RESCUE_MODIFIER, + :KEYWORD_RETRY, + :KEYWORD_RETURN, + :KEYWORD_SELF, + :KEYWORD_SUPER, + :KEYWORD_THEN, + :KEYWORD_TRUE, + :KEYWORD_UNDEF, + :KEYWORD_UNLESS, + :KEYWORD_UNLESS_MODIFIER, + :KEYWORD_UNTIL, + :KEYWORD_UNTIL_MODIFIER, + :KEYWORD_WHEN, + :KEYWORD_WHILE, + :KEYWORD_WHILE_MODIFIER, + :KEYWORD_YIELD, + :KEYWORD___ENCODING__, + :KEYWORD___FILE__, + :KEYWORD___LINE__, + :LABEL, + :LABEL_END, + :LAMBDA_BEGIN, + :LESS, + :LESS_EQUAL, + :LESS_EQUAL_GREATER, + :LESS_LESS, + :LESS_LESS_EQUAL, + :METHOD_NAME, + :MINUS, + :MINUS_EQUAL, + :MINUS_GREATER, + :NEWLINE, + :NUMBERED_REFERENCE, + :PARENTHESIS_LEFT, + :PARENTHESIS_LEFT_PARENTHESES, + :PARENTHESIS_RIGHT, + :PERCENT, + :PERCENT_EQUAL, + :PERCENT_LOWER_I, + :PERCENT_LOWER_W, + :PERCENT_LOWER_X, + :PERCENT_UPPER_I, + :PERCENT_UPPER_W, + :PIPE, + :PIPE_EQUAL, + :PIPE_PIPE, + :PIPE_PIPE_EQUAL, + :PLUS, + :PLUS_EQUAL, + :QUESTION_MARK, + :REGEXP_BEGIN, + :REGEXP_END, + :SEMICOLON, + :SLASH, + :SLASH_EQUAL, + :STAR, + :STAR_EQUAL, + :STAR_STAR, + :STAR_STAR_EQUAL, + :STRING_BEGIN, + :STRING_CONTENT, + :STRING_END, + :SYMBOL_BEGIN, + :TILDE, + :UAMPERSAND, + :UCOLON_COLON, + :UDOT_DOT, + :UDOT_DOT_DOT, + :UMINUS, + :UMINUS_NUM, + :UPLUS, + :USTAR, + :USTAR_STAR, + :WORDS_SEP, + :__END__, + ] + + private_constant :MAJOR_VERSION, :MINOR_VERSION, :PATCH_VERSION + private_constant :ConstantPool, :FastStringIO, :Loader, :TOKEN_TYPES + end + + private_constant :Serialize +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/string_query.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/string_query.rb new file mode 100644 index 00000000..9011051d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/string_query.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module Prism + # Query methods that allow categorizing strings based on their context for + # where they could be valid in a Ruby syntax tree. + class StringQuery + # The string that this query is wrapping. + attr_reader :string + + # Initialize a new query with the given string. + def initialize(string) + @string = string + end + + # Whether or not this string is a valid local variable name. + def local? + StringQuery.local?(string) + end + + # Whether or not this string is a valid constant name. + def constant? + StringQuery.constant?(string) + end + + # Whether or not this string is a valid method name. + def method_name? + StringQuery.method_name?(string) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation.rb new file mode 100644 index 00000000..f5044b9e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Prism + # This module is responsible for converting the prism syntax tree into other + # syntax trees. + module Translation # steep:ignore + autoload :Parser, "prism/translation/parser" + autoload :Parser33, "prism/translation/parser33" + autoload :Parser34, "prism/translation/parser34" + autoload :Parser35, "prism/translation/parser35" + autoload :Ripper, "prism/translation/ripper" + autoload :RubyParser, "prism/translation/ruby_parser" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/parser.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/parser.rb new file mode 100644 index 00000000..5f2f01db --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/parser.rb @@ -0,0 +1,355 @@ +# frozen_string_literal: true + +begin + require "parser" +rescue LoadError + warn(%q{Error: Unable to load parser. Add `gem "parser"` to your Gemfile.}) + exit(1) +end + +module Prism + module Translation + # This class is the entry-point for converting a prism syntax tree into the + # whitequark/parser gem's syntax tree. It inherits from the base parser for + # the parser gem, and overrides the parse* methods to parse with prism and + # then translate. + class Parser < ::Parser::Base + Diagnostic = ::Parser::Diagnostic # :nodoc: + private_constant :Diagnostic + + # The parser gem has a list of diagnostics with a hard-coded set of error + # messages. We create our own diagnostic class in order to set our own + # error messages. + class PrismDiagnostic < Diagnostic + # This is the cached message coming from prism. + attr_reader :message + + # Initialize a new diagnostic with the given message and location. + def initialize(message, level, reason, location) + @message = message + super(level, reason, {}, location, []) + end + end + + Racc_debug_parser = false # :nodoc: + + # The `builder` argument is used to create the parser using our custom builder class by default. + # + # By using the `:parser` keyword argument, you can translate in a way that is compatible with + # the Parser gem using any parser. + # + # For example, in RuboCop for Ruby LSP, the following approach can be used to improve performance + # by reusing a pre-parsed `Prism::ParseLexResult`: + # + # class PrismPreparsed + # def initialize(prism_result) + # @prism_result = prism_result + # end + # + # def parse_lex(source, **options) + # @prism_result + # end + # end + # + # prism_preparsed = PrismPreparsed.new(prism_result) + # + # Prism::Translation::Ruby34.new(builder, parser: prism_preparsed) + # + # In an object passed to the `:parser` keyword argument, the `parse` and `parse_lex` methods + # should be implemented as needed. + # + def initialize(builder = Prism::Translation::Parser::Builder.new, parser: Prism) + @parser = parser + + super(builder) + end + + def version # :nodoc: + 34 + end + + # The default encoding for Ruby files is UTF-8. + def default_encoding + Encoding::UTF_8 + end + + def yyerror # :nodoc: + end + + # Parses a source buffer and returns the AST. + def parse(source_buffer) + @source_buffer = source_buffer + source = source_buffer.source + + offset_cache = build_offset_cache(source) + result = unwrap(@parser.parse(source, **prism_options), offset_cache) + + build_ast(result.value, offset_cache) + ensure + @source_buffer = nil + end + + # Parses a source buffer and returns the AST and the source code comments. + def parse_with_comments(source_buffer) + @source_buffer = source_buffer + source = source_buffer.source + + offset_cache = build_offset_cache(source) + result = unwrap(@parser.parse(source, **prism_options), offset_cache) + + [ + build_ast(result.value, offset_cache), + build_comments(result.comments, offset_cache) + ] + ensure + @source_buffer = nil + end + + # Parses a source buffer and returns the AST, the source code comments, + # and the tokens emitted by the lexer. + def tokenize(source_buffer, recover = false) + @source_buffer = source_buffer + source = source_buffer.source + + offset_cache = build_offset_cache(source) + result = + begin + unwrap(@parser.parse_lex(source, **prism_options), offset_cache) + rescue ::Parser::SyntaxError + raise if !recover + end + + program, tokens = result.value + ast = build_ast(program, offset_cache) if result.success? + + [ + ast, + build_comments(result.comments, offset_cache), + build_tokens(tokens, offset_cache) + ] + ensure + @source_buffer = nil + end + + # Since prism resolves num params for us, we don't need to support this + # kind of logic here. + def try_declare_numparam(node) + node.children[0].match?(/\A_[1-9]\z/) + end + + private + + # This is a hook to allow consumers to disable some errors if they don't + # want them to block creating the syntax tree. + def valid_error?(error) + true + end + + # This is a hook to allow consumers to disable some warnings if they don't + # want them to block creating the syntax tree. + def valid_warning?(warning) + true + end + + # Build a diagnostic from the given prism parse error. + def error_diagnostic(error, offset_cache) + location = error.location + diagnostic_location = build_range(location, offset_cache) + + case error.type + when :argument_block_multi + Diagnostic.new(:error, :block_and_blockarg, {}, diagnostic_location, []) + when :argument_formal_constant + Diagnostic.new(:error, :argument_const, {}, diagnostic_location, []) + when :argument_formal_class + Diagnostic.new(:error, :argument_cvar, {}, diagnostic_location, []) + when :argument_formal_global + Diagnostic.new(:error, :argument_gvar, {}, diagnostic_location, []) + when :argument_formal_ivar + Diagnostic.new(:error, :argument_ivar, {}, diagnostic_location, []) + when :argument_no_forwarding_amp + Diagnostic.new(:error, :no_anonymous_blockarg, {}, diagnostic_location, []) + when :argument_no_forwarding_star + Diagnostic.new(:error, :no_anonymous_restarg, {}, diagnostic_location, []) + when :argument_no_forwarding_star_star + Diagnostic.new(:error, :no_anonymous_kwrestarg, {}, diagnostic_location, []) + when :begin_lonely_else + location = location.copy(length: 4) + diagnostic_location = build_range(location, offset_cache) + Diagnostic.new(:error, :useless_else, {}, diagnostic_location, []) + when :class_name, :module_name + Diagnostic.new(:error, :module_name_const, {}, diagnostic_location, []) + when :class_in_method + Diagnostic.new(:error, :class_in_def, {}, diagnostic_location, []) + when :def_endless_setter + Diagnostic.new(:error, :endless_setter, {}, diagnostic_location, []) + when :embdoc_term + Diagnostic.new(:error, :embedded_document, {}, diagnostic_location, []) + when :incomplete_variable_class, :incomplete_variable_class_3_3 + location = location.copy(length: location.length + 1) + diagnostic_location = build_range(location, offset_cache) + + Diagnostic.new(:error, :cvar_name, { name: location.slice }, diagnostic_location, []) + when :incomplete_variable_instance, :incomplete_variable_instance_3_3 + location = location.copy(length: location.length + 1) + diagnostic_location = build_range(location, offset_cache) + + Diagnostic.new(:error, :ivar_name, { name: location.slice }, diagnostic_location, []) + when :invalid_variable_global, :invalid_variable_global_3_3 + Diagnostic.new(:error, :gvar_name, { name: location.slice }, diagnostic_location, []) + when :module_in_method + Diagnostic.new(:error, :module_in_def, {}, diagnostic_location, []) + when :numbered_parameter_ordinary + Diagnostic.new(:error, :ordinary_param_defined, {}, diagnostic_location, []) + when :numbered_parameter_outer_scope + Diagnostic.new(:error, :numparam_used_in_outer_scope, {}, diagnostic_location, []) + when :parameter_circular + Diagnostic.new(:error, :circular_argument_reference, { var_name: location.slice }, diagnostic_location, []) + when :parameter_name_repeat + Diagnostic.new(:error, :duplicate_argument, {}, diagnostic_location, []) + when :parameter_numbered_reserved + Diagnostic.new(:error, :reserved_for_numparam, { name: location.slice }, diagnostic_location, []) + when :regexp_unknown_options + Diagnostic.new(:error, :regexp_options, { options: location.slice[1..] }, diagnostic_location, []) + when :singleton_for_literals + Diagnostic.new(:error, :singleton_literal, {}, diagnostic_location, []) + when :string_literal_eof + Diagnostic.new(:error, :string_eof, {}, diagnostic_location, []) + when :unexpected_token_ignore + Diagnostic.new(:error, :unexpected_token, { token: location.slice }, diagnostic_location, []) + when :write_target_in_method + Diagnostic.new(:error, :dynamic_const, {}, diagnostic_location, []) + else + PrismDiagnostic.new(error.message, :error, error.type, diagnostic_location) + end + end + + # Build a diagnostic from the given prism parse warning. + def warning_diagnostic(warning, offset_cache) + diagnostic_location = build_range(warning.location, offset_cache) + + case warning.type + when :ambiguous_first_argument_plus + Diagnostic.new(:warning, :ambiguous_prefix, { prefix: "+" }, diagnostic_location, []) + when :ambiguous_first_argument_minus + Diagnostic.new(:warning, :ambiguous_prefix, { prefix: "-" }, diagnostic_location, []) + when :ambiguous_prefix_ampersand + Diagnostic.new(:warning, :ambiguous_prefix, { prefix: "&" }, diagnostic_location, []) + when :ambiguous_prefix_star + Diagnostic.new(:warning, :ambiguous_prefix, { prefix: "*" }, diagnostic_location, []) + when :ambiguous_prefix_star_star + Diagnostic.new(:warning, :ambiguous_prefix, { prefix: "**" }, diagnostic_location, []) + when :ambiguous_slash + Diagnostic.new(:warning, :ambiguous_regexp, {}, diagnostic_location, []) + when :dot_dot_dot_eol + Diagnostic.new(:warning, :triple_dot_at_eol, {}, diagnostic_location, []) + when :duplicated_hash_key + # skip, parser does this on its own + else + PrismDiagnostic.new(warning.message, :warning, warning.type, diagnostic_location) + end + end + + # If there was a error generated during the parse, then raise an + # appropriate syntax error. Otherwise return the result. + def unwrap(result, offset_cache) + result.errors.each do |error| + next unless valid_error?(error) + diagnostics.process(error_diagnostic(error, offset_cache)) + end + + result.warnings.each do |warning| + next unless valid_warning?(warning) + diagnostic = warning_diagnostic(warning, offset_cache) + diagnostics.process(diagnostic) if diagnostic + end + + result + end + + # Prism deals with offsets in bytes, while the parser gem deals with + # offsets in characters. We need to handle this conversion in order to + # build the parser gem AST. + # + # If the bytesize of the source is the same as the length, then we can + # just use the offset directly. Otherwise, we build an array where the + # index is the byte offset and the value is the character offset. + def build_offset_cache(source) + if source.bytesize == source.length + -> (offset) { offset } + else + offset_cache = [] + offset = 0 + + source.each_char do |char| + char.bytesize.times { offset_cache << offset } + offset += 1 + end + + offset_cache << offset + end + end + + # Build the parser gem AST from the prism AST. + def build_ast(program, offset_cache) + program.accept(Compiler.new(self, offset_cache)) + end + + # Build the parser gem comments from the prism comments. + def build_comments(comments, offset_cache) + comments.map do |comment| + ::Parser::Source::Comment.new(build_range(comment.location, offset_cache)) + end + end + + # Build the parser gem tokens from the prism tokens. + def build_tokens(tokens, offset_cache) + Lexer.new(source_buffer, tokens, offset_cache).to_a + end + + # Build a range from a prism location. + def build_range(location, offset_cache) + ::Parser::Source::Range.new( + source_buffer, + offset_cache[location.start_offset], + offset_cache[location.end_offset] + ) + end + + # Options for how prism should parse/lex the source. + def prism_options + options = { + filepath: @source_buffer.name, + version: convert_for_prism(version), + partial_script: true, + } + # The parser gem always encodes to UTF-8, unless it is binary. + # https://github.com/whitequark/parser/blob/v3.3.6.0/lib/parser/source/buffer.rb#L80-L107 + options[:encoding] = false if @source_buffer.source.encoding != Encoding::BINARY + + options + end + + # Converts the version format handled by Parser to the format handled by Prism. + def convert_for_prism(version) + case version + when 33 + "3.3.1" + when 34 + "3.4.0" + when 35 + "3.5.0" + else + "latest" + end + end + + require_relative "parser/builder" + require_relative "parser/compiler" + require_relative "parser/lexer" + + private_constant :Compiler + private_constant :Lexer + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/parser/builder.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/parser/builder.rb new file mode 100644 index 00000000..d3b51f42 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/parser/builder.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +module Prism + module Translation + class Parser + # A builder that knows how to convert more modern Ruby syntax + # into whitequark/parser gem's syntax tree. + class Builder < ::Parser::Builders::Default + # It represents the `it` block argument, which is not yet implemented in the Parser gem. + def itarg + n(:itarg, [:it], nil) + end + + # The following three lines have been added to support the `it` block parameter syntax in the source code below. + # + # if args.type == :itarg + # block_type = :itblock + # args = :it + # + # https://github.com/whitequark/parser/blob/v3.3.7.1/lib/parser/builders/default.rb#L1122-L1155 + def block(method_call, begin_t, args, body, end_t) + _receiver, _selector, *call_args = *method_call + + if method_call.type == :yield + diagnostic :error, :block_given_to_yield, nil, method_call.loc.keyword, [loc(begin_t)] + end + + last_arg = call_args.last + if last_arg && (last_arg.type == :block_pass || last_arg.type == :forwarded_args) + diagnostic :error, :block_and_blockarg, nil, last_arg.loc.expression, [loc(begin_t)] + end + + if args.type == :itarg + block_type = :itblock + args = :it + elsif args.type == :numargs + block_type = :numblock + args = args.children[0] + else + block_type = :block + end + + if [:send, :csend, :index, :super, :zsuper, :lambda].include?(method_call.type) + n(block_type, [ method_call, args, body ], + block_map(method_call.loc.expression, begin_t, end_t)) + else + # Code like "return foo 1 do end" is reduced in a weird sequence. + # Here, method_call is actually (return). + actual_send, = *method_call + block = + n(block_type, [ actual_send, args, body ], + block_map(actual_send.loc.expression, begin_t, end_t)) + + n(method_call.type, [ block ], + method_call.loc.with_expression(join_exprs(method_call, block))) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/parser/compiler.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/parser/compiler.rb new file mode 100644 index 00000000..aa1cb5d2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/parser/compiler.rb @@ -0,0 +1,2212 @@ +# frozen_string_literal: true + +module Prism + module Translation + class Parser + # A visitor that knows how to convert a prism syntax tree into the + # whitequark/parser gem's syntax tree. + class Compiler < ::Prism::Compiler + # Raised when the tree is malformed or there is a bug in the compiler. + class CompilationError < StandardError + end + + # The Parser::Base instance that is being used to build the AST. + attr_reader :parser + + # The Parser::Builders::Default instance that is being used to build the + # AST. + attr_reader :builder + + # The Parser::Source::Buffer instance that is holding a reference to the + # source code. + attr_reader :source_buffer + + # The offset cache that is used to map between byte and character + # offsets in the file. + attr_reader :offset_cache + + # The types of values that can be forwarded in the current scope. + attr_reader :forwarding + + # Whether or not the current node is in a destructure. + attr_reader :in_destructure + + # Whether or not the current node is in a pattern. + attr_reader :in_pattern + + # Initialize a new compiler with the given parser, offset cache, and + # options. + def initialize(parser, offset_cache, forwarding: [], in_destructure: false, in_pattern: false) + @parser = parser + @builder = parser.builder + @source_buffer = parser.source_buffer + @offset_cache = offset_cache + + @forwarding = forwarding + @in_destructure = in_destructure + @in_pattern = in_pattern + end + + # alias foo bar + # ^^^^^^^^^^^^^ + def visit_alias_method_node(node) + builder.alias(token(node.keyword_loc), visit(node.new_name), visit(node.old_name)) + end + + # alias $foo $bar + # ^^^^^^^^^^^^^^^ + def visit_alias_global_variable_node(node) + builder.alias(token(node.keyword_loc), visit(node.new_name), visit(node.old_name)) + end + + # foo => bar | baz + # ^^^^^^^^^ + def visit_alternation_pattern_node(node) + builder.match_alt(visit(node.left), token(node.operator_loc), visit(node.right)) + end + + # a and b + # ^^^^^^^ + def visit_and_node(node) + builder.logical_op(:and, visit(node.left), token(node.operator_loc), visit(node.right)) + end + + # [] + # ^^ + def visit_array_node(node) + if node.opening&.start_with?("%w", "%W", "%i", "%I") + elements = node.elements.flat_map do |element| + if element.is_a?(StringNode) + if element.content.include?("\n") + string_nodes_from_line_continuations(element.unescaped, element.content, element.content_loc.start_offset, node.opening) + else + [builder.string_internal([element.unescaped, srange(element.content_loc)])] + end + elsif element.is_a?(InterpolatedStringNode) + builder.string_compose( + token(element.opening_loc), + string_nodes_from_interpolation(element, node.opening), + token(element.closing_loc) + ) + else + [visit(element)] + end + end + else + elements = visit_all(node.elements) + end + + builder.array(token(node.opening_loc), elements, token(node.closing_loc)) + end + + # foo => [bar] + # ^^^^^ + def visit_array_pattern_node(node) + elements = [*node.requireds] + elements << node.rest if !node.rest.nil? && !node.rest.is_a?(ImplicitRestNode) + elements.concat(node.posts) + visited = visit_all(elements) + + if node.rest.is_a?(ImplicitRestNode) + visited[-1] = builder.match_with_trailing_comma(visited[-1], token(node.rest.location)) + end + + if node.constant + if visited.empty? + builder.const_pattern(visit(node.constant), token(node.opening_loc), builder.array_pattern(token(node.opening_loc), visited, token(node.closing_loc)), token(node.closing_loc)) + else + builder.const_pattern(visit(node.constant), token(node.opening_loc), builder.array_pattern(nil, visited, nil), token(node.closing_loc)) + end + else + builder.array_pattern(token(node.opening_loc), visited, token(node.closing_loc)) + end + end + + # foo(bar) + # ^^^ + def visit_arguments_node(node) + visit_all(node.arguments) + end + + # { a: 1 } + # ^^^^ + def visit_assoc_node(node) + key = node.key + + if in_pattern + if node.value.is_a?(ImplicitNode) + if key.is_a?(SymbolNode) + if key.opening.nil? + builder.match_hash_var([key.unescaped, srange(key.location)]) + else + builder.match_hash_var_from_str(token(key.opening_loc), [builder.string_internal([key.unescaped, srange(key.value_loc)])], token(key.closing_loc)) + end + else + builder.match_hash_var_from_str(token(key.opening_loc), visit_all(key.parts), token(key.closing_loc)) + end + elsif key.opening.nil? + builder.pair_keyword([key.unescaped, srange(key.location)], visit(node.value)) + else + builder.pair_quoted(token(key.opening_loc), [builder.string_internal([key.unescaped, srange(key.value_loc)])], token(key.closing_loc), visit(node.value)) + end + elsif node.value.is_a?(ImplicitNode) + value = node.value.value + + implicit_value = if value.is_a?(CallNode) + builder.call_method(nil, nil, [value.name, srange(value.message_loc)]) + elsif value.is_a?(ConstantReadNode) + builder.const([value.name, srange(key.value_loc)]) + else + builder.ident([value.name, srange(key.value_loc)]).updated(:lvar) + end + + builder.pair_keyword([key.unescaped, srange(key)], implicit_value) + elsif node.operator_loc + builder.pair(visit(key), token(node.operator_loc), visit(node.value)) + elsif key.is_a?(SymbolNode) && key.opening_loc.nil? + builder.pair_keyword([key.unescaped, srange(key.location)], visit(node.value)) + else + parts = + if key.is_a?(SymbolNode) + [builder.string_internal([key.unescaped, srange(key.value_loc)])] + else + visit_all(key.parts) + end + + builder.pair_quoted(token(key.opening_loc), parts, token(key.closing_loc), visit(node.value)) + end + end + + # def foo(**); bar(**); end + # ^^ + # + # { **foo } + # ^^^^^ + def visit_assoc_splat_node(node) + if in_pattern + builder.match_rest(token(node.operator_loc), token(node.value&.location)) + elsif node.value.nil? && forwarding.include?(:**) + builder.forwarded_kwrestarg(token(node.operator_loc)) + else + builder.kwsplat(token(node.operator_loc), visit(node.value)) + end + end + + # $+ + # ^^ + def visit_back_reference_read_node(node) + builder.back_ref(token(node.location)) + end + + # begin end + # ^^^^^^^^^ + def visit_begin_node(node) + rescue_bodies = [] + + if (rescue_clause = node.rescue_clause) + begin + find_start_offset = (rescue_clause.reference&.location || rescue_clause.exceptions.last&.location || rescue_clause.keyword_loc).end_offset + find_end_offset = ( + rescue_clause.statements&.location&.start_offset || + rescue_clause.subsequent&.location&.start_offset || + node.else_clause&.location&.start_offset || + node.ensure_clause&.location&.start_offset || + node.end_keyword_loc&.start_offset || + find_start_offset + 1 + ) + + rescue_bodies << builder.rescue_body( + token(rescue_clause.keyword_loc), + rescue_clause.exceptions.any? ? builder.array(nil, visit_all(rescue_clause.exceptions), nil) : nil, + token(rescue_clause.operator_loc), + visit(rescue_clause.reference), + srange_find(find_start_offset, find_end_offset, ";"), + visit(rescue_clause.statements) + ) + end until (rescue_clause = rescue_clause.subsequent).nil? + end + + begin_body = + builder.begin_body( + visit(node.statements), + rescue_bodies, + token(node.else_clause&.else_keyword_loc), + visit(node.else_clause), + token(node.ensure_clause&.ensure_keyword_loc), + visit(node.ensure_clause&.statements) + ) + + if node.begin_keyword_loc + builder.begin_keyword(token(node.begin_keyword_loc), begin_body, token(node.end_keyword_loc)) + else + begin_body + end + end + + # foo(&bar) + # ^^^^ + def visit_block_argument_node(node) + builder.block_pass(token(node.operator_loc), visit(node.expression)) + end + + # foo { |; bar| } + # ^^^ + def visit_block_local_variable_node(node) + builder.shadowarg(token(node.location)) + end + + # A block on a keyword or method call. + def visit_block_node(node) + raise CompilationError, "Cannot directly compile block nodes" + end + + # def foo(&bar); end + # ^^^^ + def visit_block_parameter_node(node) + builder.blockarg(token(node.operator_loc), token(node.name_loc)) + end + + # A block's parameters. + def visit_block_parameters_node(node) + [*visit(node.parameters)].concat(visit_all(node.locals)) + end + + # break + # ^^^^^ + # + # break foo + # ^^^^^^^^^ + def visit_break_node(node) + builder.keyword_cmd(:break, token(node.keyword_loc), nil, visit(node.arguments) || [], nil) + end + + # foo + # ^^^ + # + # foo.bar + # ^^^^^^^ + # + # foo.bar() {} + # ^^^^^^^^^^^^ + def visit_call_node(node) + name = node.name + arguments = node.arguments&.arguments || [] + block = node.block + + if block.is_a?(BlockArgumentNode) + arguments = [*arguments, block] + block = nil + end + + if node.call_operator_loc.nil? + case name + when :-@ + case (receiver = node.receiver).type + when :integer_node, :float_node, :rational_node, :imaginary_node + return visit(numeric_negate(node.message_loc, receiver)) + end + when :! + return visit_block(builder.not_op(token(node.message_loc), token(node.opening_loc), visit(node.receiver), token(node.closing_loc)), block) + when :=~ + if (receiver = node.receiver).is_a?(RegularExpressionNode) + return builder.match_op(visit(receiver), token(node.message_loc), visit(node.arguments.arguments.first)) + end + when :[] + return visit_block(builder.index(visit(node.receiver), token(node.opening_loc), visit_all(arguments), token(node.closing_loc)), block) + when :[]= + if node.message != "[]=" && node.arguments && block.nil? && !node.safe_navigation? + arguments = node.arguments.arguments[...-1] + arguments << node.block if node.block + + return visit_block( + builder.assign( + builder.index_asgn( + visit(node.receiver), + token(node.opening_loc), + visit_all(arguments), + token(node.closing_loc), + ), + srange_find(node.message_loc.end_offset, node.arguments.arguments.last.location.start_offset, "="), + visit(node.arguments.arguments.last) + ), + block + ) + end + end + end + + message_loc = node.message_loc + call_operator_loc = node.call_operator_loc + call_operator = [{ "." => :dot, "&." => :anddot, "::" => "::" }.fetch(call_operator_loc.slice), srange(call_operator_loc)] if call_operator_loc + + visit_block( + if name.end_with?("=") && !message_loc.slice.end_with?("=") && node.arguments && block.nil? + builder.assign( + builder.attr_asgn(visit(node.receiver), call_operator, token(message_loc)), + srange_find(message_loc.end_offset, node.arguments.location.start_offset, "="), + visit(node.arguments.arguments.last) + ) + else + builder.call_method( + visit(node.receiver), + call_operator, + message_loc ? [node.name, srange(message_loc)] : nil, + token(node.opening_loc), + visit_all(arguments), + token(node.closing_loc) + ) + end, + block + ) + end + + # foo.bar += baz + # ^^^^^^^^^^^^^^^ + def visit_call_operator_write_node(node) + call_operator_loc = node.call_operator_loc + + builder.op_assign( + builder.call_method( + visit(node.receiver), + call_operator_loc.nil? ? nil : [{ "." => :dot, "&." => :anddot, "::" => "::" }.fetch(call_operator_loc.slice), srange(call_operator_loc)], + node.message_loc ? [node.read_name, srange(node.message_loc)] : nil, + nil, + [], + nil + ), + [node.binary_operator_loc.slice.chomp("="), srange(node.binary_operator_loc)], + visit(node.value) + ) + end + + # foo.bar &&= baz + # ^^^^^^^^^^^^^^^ + def visit_call_and_write_node(node) + call_operator_loc = node.call_operator_loc + + builder.op_assign( + builder.call_method( + visit(node.receiver), + call_operator_loc.nil? ? nil : [{ "." => :dot, "&." => :anddot, "::" => "::" }.fetch(call_operator_loc.slice), srange(call_operator_loc)], + node.message_loc ? [node.read_name, srange(node.message_loc)] : nil, + nil, + [], + nil + ), + [node.operator_loc.slice.chomp("="), srange(node.operator_loc)], + visit(node.value) + ) + end + + # foo.bar ||= baz + # ^^^^^^^^^^^^^^^ + def visit_call_or_write_node(node) + call_operator_loc = node.call_operator_loc + + builder.op_assign( + builder.call_method( + visit(node.receiver), + call_operator_loc.nil? ? nil : [{ "." => :dot, "&." => :anddot, "::" => "::" }.fetch(call_operator_loc.slice), srange(call_operator_loc)], + node.message_loc ? [node.read_name, srange(node.message_loc)] : nil, + nil, + [], + nil + ), + [node.operator_loc.slice.chomp("="), srange(node.operator_loc)], + visit(node.value) + ) + end + + # foo.bar, = 1 + # ^^^^^^^ + def visit_call_target_node(node) + call_operator_loc = node.call_operator_loc + + builder.attr_asgn( + visit(node.receiver), + call_operator_loc.nil? ? nil : [{ "." => :dot, "&." => :anddot, "::" => "::" }.fetch(call_operator_loc.slice), srange(call_operator_loc)], + token(node.message_loc) + ) + end + + # foo => bar => baz + # ^^^^^^^^^^ + def visit_capture_pattern_node(node) + builder.match_as(visit(node.value), token(node.operator_loc), visit(node.target)) + end + + # case foo; when bar; end + # ^^^^^^^^^^^^^^^^^^^^^^^ + def visit_case_node(node) + builder.case( + token(node.case_keyword_loc), + visit(node.predicate), + visit_all(node.conditions), + token(node.else_clause&.else_keyword_loc), + visit(node.else_clause), + token(node.end_keyword_loc) + ) + end + + # case foo; in bar; end + # ^^^^^^^^^^^^^^^^^^^^^ + def visit_case_match_node(node) + builder.case_match( + token(node.case_keyword_loc), + visit(node.predicate), + visit_all(node.conditions), + token(node.else_clause&.else_keyword_loc), + visit(node.else_clause), + token(node.end_keyword_loc) + ) + end + + # class Foo; end + # ^^^^^^^^^^^^^^ + def visit_class_node(node) + builder.def_class( + token(node.class_keyword_loc), + visit(node.constant_path), + token(node.inheritance_operator_loc), + visit(node.superclass), + node.body&.accept(copy_compiler(forwarding: [])), + token(node.end_keyword_loc) + ) + end + + # @@foo + # ^^^^^ + def visit_class_variable_read_node(node) + builder.cvar(token(node.location)) + end + + # @@foo = 1 + # ^^^^^^^^^ + def visit_class_variable_write_node(node) + builder.assign( + builder.assignable(builder.cvar(token(node.name_loc))), + token(node.operator_loc), + visit(node.value) + ) + end + + # @@foo += bar + # ^^^^^^^^^^^^ + def visit_class_variable_operator_write_node(node) + builder.op_assign( + builder.assignable(builder.cvar(token(node.name_loc))), + [node.binary_operator_loc.slice.chomp("="), srange(node.binary_operator_loc)], + visit(node.value) + ) + end + + # @@foo &&= bar + # ^^^^^^^^^^^^^ + def visit_class_variable_and_write_node(node) + builder.op_assign( + builder.assignable(builder.cvar(token(node.name_loc))), + [node.operator_loc.slice.chomp("="), srange(node.operator_loc)], + visit(node.value) + ) + end + + # @@foo ||= bar + # ^^^^^^^^^^^^^ + def visit_class_variable_or_write_node(node) + builder.op_assign( + builder.assignable(builder.cvar(token(node.name_loc))), + [node.operator_loc.slice.chomp("="), srange(node.operator_loc)], + visit(node.value) + ) + end + + # @@foo, = bar + # ^^^^^ + def visit_class_variable_target_node(node) + builder.assignable(builder.cvar(token(node.location))) + end + + # Foo + # ^^^ + def visit_constant_read_node(node) + builder.const([node.name, srange(node.location)]) + end + + # Foo = 1 + # ^^^^^^^ + # + # Foo, Bar = 1 + # ^^^ ^^^ + def visit_constant_write_node(node) + builder.assign(builder.assignable(builder.const([node.name, srange(node.name_loc)])), token(node.operator_loc), visit(node.value)) + end + + # Foo += bar + # ^^^^^^^^^^^ + def visit_constant_operator_write_node(node) + builder.op_assign( + builder.assignable(builder.const([node.name, srange(node.name_loc)])), + [node.binary_operator_loc.slice.chomp("="), srange(node.binary_operator_loc)], + visit(node.value) + ) + end + + # Foo &&= bar + # ^^^^^^^^^^^^ + def visit_constant_and_write_node(node) + builder.op_assign( + builder.assignable(builder.const([node.name, srange(node.name_loc)])), + [node.operator_loc.slice.chomp("="), srange(node.operator_loc)], + visit(node.value) + ) + end + + # Foo ||= bar + # ^^^^^^^^^^^^ + def visit_constant_or_write_node(node) + builder.op_assign( + builder.assignable(builder.const([node.name, srange(node.name_loc)])), + [node.operator_loc.slice.chomp("="), srange(node.operator_loc)], + visit(node.value) + ) + end + + # Foo, = bar + # ^^^ + def visit_constant_target_node(node) + builder.assignable(builder.const([node.name, srange(node.location)])) + end + + # Foo::Bar + # ^^^^^^^^ + def visit_constant_path_node(node) + if node.parent.nil? + builder.const_global( + token(node.delimiter_loc), + [node.name, srange(node.name_loc)] + ) + else + builder.const_fetch( + visit(node.parent), + token(node.delimiter_loc), + [node.name, srange(node.name_loc)] + ) + end + end + + # Foo::Bar = 1 + # ^^^^^^^^^^^^ + # + # Foo::Foo, Bar::Bar = 1 + # ^^^^^^^^ ^^^^^^^^ + def visit_constant_path_write_node(node) + builder.assign( + builder.assignable(visit(node.target)), + token(node.operator_loc), + visit(node.value) + ) + end + + # Foo::Bar += baz + # ^^^^^^^^^^^^^^^ + def visit_constant_path_operator_write_node(node) + builder.op_assign( + builder.assignable(visit(node.target)), + [node.binary_operator_loc.slice.chomp("="), srange(node.binary_operator_loc)], + visit(node.value) + ) + end + + # Foo::Bar &&= baz + # ^^^^^^^^^^^^^^^^ + def visit_constant_path_and_write_node(node) + builder.op_assign( + builder.assignable(visit(node.target)), + [node.operator_loc.slice.chomp("="), srange(node.operator_loc)], + visit(node.value) + ) + end + + # Foo::Bar ||= baz + # ^^^^^^^^^^^^^^^^ + def visit_constant_path_or_write_node(node) + builder.op_assign( + builder.assignable(visit(node.target)), + [node.operator_loc.slice.chomp("="), srange(node.operator_loc)], + visit(node.value) + ) + end + + # Foo::Bar, = baz + # ^^^^^^^^ + def visit_constant_path_target_node(node) + builder.assignable(visit_constant_path_node(node)) + end + + # def foo; end + # ^^^^^^^^^^^^ + # + # def self.foo; end + # ^^^^^^^^^^^^^^^^^ + def visit_def_node(node) + if node.equal_loc + if node.receiver + builder.def_endless_singleton( + token(node.def_keyword_loc), + visit(node.receiver.is_a?(ParenthesesNode) ? node.receiver.body : node.receiver), + token(node.operator_loc), + token(node.name_loc), + builder.args(token(node.lparen_loc), visit(node.parameters) || [], token(node.rparen_loc), false), + token(node.equal_loc), + node.body&.accept(copy_compiler(forwarding: find_forwarding(node.parameters))) + ) + else + builder.def_endless_method( + token(node.def_keyword_loc), + token(node.name_loc), + builder.args(token(node.lparen_loc), visit(node.parameters) || [], token(node.rparen_loc), false), + token(node.equal_loc), + node.body&.accept(copy_compiler(forwarding: find_forwarding(node.parameters))) + ) + end + elsif node.receiver + builder.def_singleton( + token(node.def_keyword_loc), + visit(node.receiver.is_a?(ParenthesesNode) ? node.receiver.body : node.receiver), + token(node.operator_loc), + token(node.name_loc), + builder.args(token(node.lparen_loc), visit(node.parameters) || [], token(node.rparen_loc), false), + node.body&.accept(copy_compiler(forwarding: find_forwarding(node.parameters))), + token(node.end_keyword_loc) + ) + else + builder.def_method( + token(node.def_keyword_loc), + token(node.name_loc), + builder.args(token(node.lparen_loc), visit(node.parameters) || [], token(node.rparen_loc), false), + node.body&.accept(copy_compiler(forwarding: find_forwarding(node.parameters))), + token(node.end_keyword_loc) + ) + end + end + + # defined? a + # ^^^^^^^^^^ + # + # defined?(a) + # ^^^^^^^^^^^ + def visit_defined_node(node) + builder.keyword_cmd( + :defined?, + token(node.keyword_loc), + token(node.lparen_loc), + [visit(node.value)], + token(node.rparen_loc) + ) + end + + # if foo then bar else baz end + # ^^^^^^^^^^^^ + def visit_else_node(node) + visit(node.statements) + end + + # "foo #{bar}" + # ^^^^^^ + def visit_embedded_statements_node(node) + builder.begin( + token(node.opening_loc), + visit(node.statements), + token(node.closing_loc) + ) + end + + # "foo #@bar" + # ^^^^^ + def visit_embedded_variable_node(node) + visit(node.variable) + end + + # begin; foo; ensure; bar; end + # ^^^^^^^^^^^^ + def visit_ensure_node(node) + raise CompilationError, "Cannot directly compile ensure nodes" + end + + # false + # ^^^^^ + def visit_false_node(node) + builder.false(token(node.location)) + end + + # foo => [*, bar, *] + # ^^^^^^^^^^^ + def visit_find_pattern_node(node) + elements = [node.left, *node.requireds, node.right] + + if node.constant + builder.const_pattern(visit(node.constant), token(node.opening_loc), builder.find_pattern(nil, visit_all(elements), nil), token(node.closing_loc)) + else + builder.find_pattern(token(node.opening_loc), visit_all(elements), token(node.closing_loc)) + end + end + + # 1.0 + # ^^^ + def visit_float_node(node) + visit_numeric(node, builder.float([node.value, srange(node.location)])) + end + + # for foo in bar do end + # ^^^^^^^^^^^^^^^^^^^^^ + def visit_for_node(node) + builder.for( + token(node.for_keyword_loc), + visit(node.index), + token(node.in_keyword_loc), + visit(node.collection), + if (do_keyword_loc = node.do_keyword_loc) + token(do_keyword_loc) + else + srange_find(node.collection.location.end_offset, (node.statements&.location || node.end_keyword_loc).start_offset, ";") + end, + visit(node.statements), + token(node.end_keyword_loc) + ) + end + + # def foo(...); bar(...); end + # ^^^ + def visit_forwarding_arguments_node(node) + builder.forwarded_args(token(node.location)) + end + + # def foo(...); end + # ^^^ + def visit_forwarding_parameter_node(node) + builder.forward_arg(token(node.location)) + end + + # super + # ^^^^^ + # + # super {} + # ^^^^^^^^ + def visit_forwarding_super_node(node) + visit_block( + builder.keyword_cmd( + :zsuper, + ["super", srange_offsets(node.location.start_offset, node.location.start_offset + 5)] + ), + node.block + ) + end + + # $foo + # ^^^^ + def visit_global_variable_read_node(node) + builder.gvar(token(node.location)) + end + + # $foo = 1 + # ^^^^^^^^ + def visit_global_variable_write_node(node) + builder.assign( + builder.assignable(builder.gvar(token(node.name_loc))), + token(node.operator_loc), + visit(node.value) + ) + end + + # $foo += bar + # ^^^^^^^^^^^ + def visit_global_variable_operator_write_node(node) + builder.op_assign( + builder.assignable(builder.gvar(token(node.name_loc))), + [node.binary_operator_loc.slice.chomp("="), srange(node.binary_operator_loc)], + visit(node.value) + ) + end + + # $foo &&= bar + # ^^^^^^^^^^^^ + def visit_global_variable_and_write_node(node) + builder.op_assign( + builder.assignable(builder.gvar(token(node.name_loc))), + [node.operator_loc.slice.chomp("="), srange(node.operator_loc)], + visit(node.value) + ) + end + + # $foo ||= bar + # ^^^^^^^^^^^^ + def visit_global_variable_or_write_node(node) + builder.op_assign( + builder.assignable(builder.gvar(token(node.name_loc))), + [node.operator_loc.slice.chomp("="), srange(node.operator_loc)], + visit(node.value) + ) + end + + # $foo, = bar + # ^^^^ + def visit_global_variable_target_node(node) + builder.assignable(builder.gvar([node.slice, srange(node.location)])) + end + + # {} + # ^^ + def visit_hash_node(node) + builder.associate( + token(node.opening_loc), + visit_all(node.elements), + token(node.closing_loc) + ) + end + + # foo => {} + # ^^ + def visit_hash_pattern_node(node) + elements = [*node.elements, *node.rest] + + if node.constant + builder.const_pattern(visit(node.constant), token(node.opening_loc), builder.hash_pattern(nil, visit_all(elements), nil), token(node.closing_loc)) + else + builder.hash_pattern(token(node.opening_loc), visit_all(elements), token(node.closing_loc)) + end + end + + # if foo then bar end + # ^^^^^^^^^^^^^^^^^^^ + # + # bar if foo + # ^^^^^^^^^^ + # + # foo ? bar : baz + # ^^^^^^^^^^^^^^^ + def visit_if_node(node) + if !node.if_keyword_loc + builder.ternary( + visit(node.predicate), + token(node.then_keyword_loc), + visit(node.statements), + token(node.subsequent.else_keyword_loc), + visit(node.subsequent) + ) + elsif node.if_keyword_loc.start_offset == node.location.start_offset + builder.condition( + token(node.if_keyword_loc), + visit(node.predicate), + if (then_keyword_loc = node.then_keyword_loc) + token(then_keyword_loc) + else + srange_find(node.predicate.location.end_offset, (node.statements&.location || node.subsequent&.location || node.end_keyword_loc).start_offset, ";") + end, + visit(node.statements), + case node.subsequent + when IfNode + token(node.subsequent.if_keyword_loc) + when ElseNode + token(node.subsequent.else_keyword_loc) + end, + visit(node.subsequent), + if node.if_keyword != "elsif" + token(node.end_keyword_loc) + end + ) + else + builder.condition_mod( + visit(node.statements), + visit(node.subsequent), + token(node.if_keyword_loc), + visit(node.predicate) + ) + end + end + + # 1i + # ^^ + def visit_imaginary_node(node) + visit_numeric(node, builder.complex([Complex(0, node.numeric.value), srange(node.location)])) + end + + # { foo: } + # ^^^^ + def visit_implicit_node(node) + raise CompilationError, "Cannot directly compile implicit nodes" + end + + # foo { |bar,| } + # ^ + def visit_implicit_rest_node(node) + raise CompilationError, "Cannot compile implicit rest nodes" + end + + # case foo; in bar; end + # ^^^^^^^^^^^^^^^^^^^^^ + def visit_in_node(node) + pattern = nil + guard = nil + + case node.pattern + when IfNode + pattern = within_pattern { |compiler| node.pattern.statements.accept(compiler) } + guard = builder.if_guard(token(node.pattern.if_keyword_loc), visit(node.pattern.predicate)) + when UnlessNode + pattern = within_pattern { |compiler| node.pattern.statements.accept(compiler) } + guard = builder.unless_guard(token(node.pattern.keyword_loc), visit(node.pattern.predicate)) + else + pattern = within_pattern { |compiler| node.pattern.accept(compiler) } + end + + builder.in_pattern( + token(node.in_loc), + pattern, + guard, + if (then_loc = node.then_loc) + token(then_loc) + else + srange_find(node.pattern.location.end_offset, node.statements&.location&.start_offset, ";") + end, + visit(node.statements) + ) + end + + # foo[bar] += baz + # ^^^^^^^^^^^^^^^ + def visit_index_operator_write_node(node) + arguments = node.arguments&.arguments || [] + arguments << node.block if node.block + + builder.op_assign( + builder.index( + visit(node.receiver), + token(node.opening_loc), + visit_all(arguments), + token(node.closing_loc) + ), + [node.binary_operator_loc.slice.chomp("="), srange(node.binary_operator_loc)], + visit(node.value) + ) + end + + # foo[bar] &&= baz + # ^^^^^^^^^^^^^^^^ + def visit_index_and_write_node(node) + arguments = node.arguments&.arguments || [] + arguments << node.block if node.block + + builder.op_assign( + builder.index( + visit(node.receiver), + token(node.opening_loc), + visit_all(arguments), + token(node.closing_loc) + ), + [node.operator_loc.slice.chomp("="), srange(node.operator_loc)], + visit(node.value) + ) + end + + # foo[bar] ||= baz + # ^^^^^^^^^^^^^^^^ + def visit_index_or_write_node(node) + arguments = node.arguments&.arguments || [] + arguments << node.block if node.block + + builder.op_assign( + builder.index( + visit(node.receiver), + token(node.opening_loc), + visit_all(arguments), + token(node.closing_loc) + ), + [node.operator_loc.slice.chomp("="), srange(node.operator_loc)], + visit(node.value) + ) + end + + # foo[bar], = 1 + # ^^^^^^^^ + def visit_index_target_node(node) + builder.index_asgn( + visit(node.receiver), + token(node.opening_loc), + visit_all(node.arguments.arguments), + token(node.closing_loc), + ) + end + + # @foo + # ^^^^ + def visit_instance_variable_read_node(node) + builder.ivar(token(node.location)) + end + + # @foo = 1 + # ^^^^^^^^ + def visit_instance_variable_write_node(node) + builder.assign( + builder.assignable(builder.ivar(token(node.name_loc))), + token(node.operator_loc), + visit(node.value) + ) + end + + # @foo += bar + # ^^^^^^^^^^^ + def visit_instance_variable_operator_write_node(node) + builder.op_assign( + builder.assignable(builder.ivar(token(node.name_loc))), + [node.binary_operator_loc.slice.chomp("="), srange(node.binary_operator_loc)], + visit(node.value) + ) + end + + # @foo &&= bar + # ^^^^^^^^^^^^ + def visit_instance_variable_and_write_node(node) + builder.op_assign( + builder.assignable(builder.ivar(token(node.name_loc))), + [node.operator_loc.slice.chomp("="), srange(node.operator_loc)], + visit(node.value) + ) + end + + # @foo ||= bar + # ^^^^^^^^^^^^ + def visit_instance_variable_or_write_node(node) + builder.op_assign( + builder.assignable(builder.ivar(token(node.name_loc))), + [node.operator_loc.slice.chomp("="), srange(node.operator_loc)], + visit(node.value) + ) + end + + # @foo, = bar + # ^^^^ + def visit_instance_variable_target_node(node) + builder.assignable(builder.ivar(token(node.location))) + end + + # 1 + # ^ + def visit_integer_node(node) + visit_numeric(node, builder.integer([node.value, srange(node.location)])) + end + + # /foo #{bar}/ + # ^^^^^^^^^^^^ + def visit_interpolated_regular_expression_node(node) + builder.regexp_compose( + token(node.opening_loc), + string_nodes_from_interpolation(node, node.opening), + [node.closing[0], srange_offsets(node.closing_loc.start_offset, node.closing_loc.start_offset + 1)], + builder.regexp_options([node.closing[1..], srange_offsets(node.closing_loc.start_offset + 1, node.closing_loc.end_offset)]) + ) + end + + # if /foo #{bar}/ then end + # ^^^^^^^^^^^^ + alias visit_interpolated_match_last_line_node visit_interpolated_regular_expression_node + + # "foo #{bar}" + # ^^^^^^^^^^^^ + def visit_interpolated_string_node(node) + if node.heredoc? + return visit_heredoc(node) { |children, closing| builder.string_compose(token(node.opening_loc), children, closing) } + end + + builder.string_compose( + token(node.opening_loc), + string_nodes_from_interpolation(node, node.opening), + token(node.closing_loc) + ) + end + + # :"foo #{bar}" + # ^^^^^^^^^^^^^ + def visit_interpolated_symbol_node(node) + builder.symbol_compose( + token(node.opening_loc), + string_nodes_from_interpolation(node, node.opening), + token(node.closing_loc) + ) + end + + # `foo #{bar}` + # ^^^^^^^^^^^^ + def visit_interpolated_x_string_node(node) + if node.heredoc? + return visit_heredoc(node) { |children, closing| builder.xstring_compose(token(node.opening_loc), children, closing) } + end + + builder.xstring_compose( + token(node.opening_loc), + string_nodes_from_interpolation(node, node.opening), + token(node.closing_loc) + ) + end + + # -> { it } + # ^^ + def visit_it_local_variable_read_node(node) + builder.ident([:it, srange(node.location)]).updated(:lvar) + end + + # -> { it } + # ^^^^^^^^^ + def visit_it_parameters_node(node) + # FIXME: The builder _should_ always be a subclass of the prism builder. + # Currently RuboCop passes in its own builder that always inherits from the + # parser builder (which is lacking the `itarg` method). Once rubocop-ast + # opts in to use the custom prism builder a warning can be emitted when + # it is not the expected class, and eventually raise. + # https://github.com/rubocop/rubocop-ast/pull/354 + if builder.is_a?(Translation::Parser::Builder) + builder.itarg + else + builder.args(nil, [], nil, false) + end + end + + # foo(bar: baz) + # ^^^^^^^^ + def visit_keyword_hash_node(node) + builder.associate(nil, visit_all(node.elements), nil) + end + + # def foo(**bar); end + # ^^^^^ + # + # def foo(**); end + # ^^ + def visit_keyword_rest_parameter_node(node) + builder.kwrestarg( + token(node.operator_loc), + node.name ? [node.name, srange(node.name_loc)] : nil + ) + end + + # -> {} + # ^^^^^ + def visit_lambda_node(node) + parameters = node.parameters + implicit_parameters = parameters.is_a?(NumberedParametersNode) || parameters.is_a?(ItParametersNode) + + builder.block( + builder.call_lambda(token(node.operator_loc)), + [node.opening, srange(node.opening_loc)], + if parameters.nil? + builder.args(nil, [], nil, false) + elsif implicit_parameters + visit(node.parameters) + else + builder.args( + token(node.parameters.opening_loc), + visit(node.parameters), + token(node.parameters.closing_loc), + false + ) + end, + visit(node.body), + [node.closing, srange(node.closing_loc)] + ) + end + + # foo + # ^^^ + def visit_local_variable_read_node(node) + builder.ident([node.name, srange(node.location)]).updated(:lvar) + end + + # foo = 1 + # ^^^^^^^ + def visit_local_variable_write_node(node) + builder.assign( + builder.assignable(builder.ident(token(node.name_loc))), + token(node.operator_loc), + visit(node.value) + ) + end + + # foo += bar + # ^^^^^^^^^^ + def visit_local_variable_operator_write_node(node) + builder.op_assign( + builder.assignable(builder.ident(token(node.name_loc))), + [node.binary_operator_loc.slice.chomp("="), srange(node.binary_operator_loc)], + visit(node.value) + ) + end + + # foo &&= bar + # ^^^^^^^^^^^ + def visit_local_variable_and_write_node(node) + builder.op_assign( + builder.assignable(builder.ident(token(node.name_loc))), + [node.operator_loc.slice.chomp("="), srange(node.operator_loc)], + visit(node.value) + ) + end + + # foo ||= bar + # ^^^^^^^^^^^ + def visit_local_variable_or_write_node(node) + builder.op_assign( + builder.assignable(builder.ident(token(node.name_loc))), + [node.operator_loc.slice.chomp("="), srange(node.operator_loc)], + visit(node.value) + ) + end + + # foo, = bar + # ^^^ + def visit_local_variable_target_node(node) + if in_pattern + builder.assignable(builder.match_var([node.name, srange(node.location)])) + else + builder.assignable(builder.ident(token(node.location))) + end + end + + # foo in bar + # ^^^^^^^^^^ + def visit_match_predicate_node(node) + builder.match_pattern_p( + visit(node.value), + token(node.operator_loc), + within_pattern { |compiler| node.pattern.accept(compiler) } + ) + end + + # foo => bar + # ^^^^^^^^^^ + def visit_match_required_node(node) + builder.match_pattern( + visit(node.value), + token(node.operator_loc), + within_pattern { |compiler| node.pattern.accept(compiler) } + ) + end + + # /(?foo)/ =~ bar + # ^^^^^^^^^^^^^^^^^^^^ + def visit_match_write_node(node) + builder.match_op( + visit(node.call.receiver), + token(node.call.message_loc), + visit(node.call.arguments.arguments.first) + ) + end + + # A node that is missing from the syntax tree. This is only used in the + # case of a syntax error. The parser gem doesn't have such a concept, so + # we invent our own here. + def visit_missing_node(node) + ::AST::Node.new(:missing, [], location: ::Parser::Source::Map.new(srange(node.location))) + end + + # module Foo; end + # ^^^^^^^^^^^^^^^ + def visit_module_node(node) + builder.def_module( + token(node.module_keyword_loc), + visit(node.constant_path), + node.body&.accept(copy_compiler(forwarding: [])), + token(node.end_keyword_loc) + ) + end + + # foo, bar = baz + # ^^^^^^^^ + def visit_multi_target_node(node) + builder.multi_lhs( + token(node.lparen_loc), + visit_all(multi_target_elements(node)), + token(node.rparen_loc) + ) + end + + # foo, bar = baz + # ^^^^^^^^^^^^^^ + def visit_multi_write_node(node) + elements = multi_target_elements(node) + + if elements.length == 1 && elements.first.is_a?(MultiTargetNode) && !node.rest + elements = multi_target_elements(elements.first) + end + + builder.multi_assign( + builder.multi_lhs( + token(node.lparen_loc), + visit_all(elements), + token(node.rparen_loc) + ), + token(node.operator_loc), + visit(node.value) + ) + end + + # next + # ^^^^ + # + # next foo + # ^^^^^^^^ + def visit_next_node(node) + builder.keyword_cmd( + :next, + token(node.keyword_loc), + nil, + visit(node.arguments) || [], + nil + ) + end + + # nil + # ^^^ + def visit_nil_node(node) + builder.nil(token(node.location)) + end + + # def foo(**nil); end + # ^^^^^ + def visit_no_keywords_parameter_node(node) + if in_pattern + builder.match_nil_pattern(token(node.operator_loc), token(node.keyword_loc)) + else + builder.kwnilarg(token(node.operator_loc), token(node.keyword_loc)) + end + end + + # -> { _1 + _2 } + # ^^^^^^^^^^^^^^ + def visit_numbered_parameters_node(node) + builder.numargs(node.maximum) + end + + # $1 + # ^^ + def visit_numbered_reference_read_node(node) + builder.nth_ref([node.number, srange(node.location)]) + end + + # def foo(bar: baz); end + # ^^^^^^^^ + def visit_optional_keyword_parameter_node(node) + builder.kwoptarg([node.name, srange(node.name_loc)], visit(node.value)) + end + + # def foo(bar = 1); end + # ^^^^^^^ + def visit_optional_parameter_node(node) + builder.optarg(token(node.name_loc), token(node.operator_loc), visit(node.value)) + end + + # a or b + # ^^^^^^ + def visit_or_node(node) + builder.logical_op(:or, visit(node.left), token(node.operator_loc), visit(node.right)) + end + + # def foo(bar, *baz); end + # ^^^^^^^^^ + def visit_parameters_node(node) + params = [] + + if node.requireds.any? + node.requireds.each do |required| + params << + if required.is_a?(RequiredParameterNode) + visit(required) + else + required.accept(copy_compiler(in_destructure: true)) + end + end + end + + params.concat(visit_all(node.optionals)) if node.optionals.any? + params << visit(node.rest) if !node.rest.nil? && !node.rest.is_a?(ImplicitRestNode) + + if node.posts.any? + node.posts.each do |post| + params << + if post.is_a?(RequiredParameterNode) + visit(post) + else + post.accept(copy_compiler(in_destructure: true)) + end + end + end + + params.concat(visit_all(node.keywords)) if node.keywords.any? + params << visit(node.keyword_rest) if !node.keyword_rest.nil? + params << visit(node.block) if !node.block.nil? + params + end + + # () + # ^^ + # + # (1) + # ^^^ + def visit_parentheses_node(node) + builder.begin( + token(node.opening_loc), + visit(node.body), + token(node.closing_loc) + ) + end + + # foo => ^(bar) + # ^^^^^^ + def visit_pinned_expression_node(node) + expression = builder.begin(token(node.lparen_loc), visit(node.expression), token(node.rparen_loc)) + builder.pin(token(node.operator_loc), expression) + end + + # foo = 1 and bar => ^foo + # ^^^^ + def visit_pinned_variable_node(node) + builder.pin(token(node.operator_loc), visit(node.variable)) + end + + # END {} + def visit_post_execution_node(node) + builder.postexe( + token(node.keyword_loc), + token(node.opening_loc), + visit(node.statements), + token(node.closing_loc) + ) + end + + # BEGIN {} + def visit_pre_execution_node(node) + builder.preexe( + token(node.keyword_loc), + token(node.opening_loc), + visit(node.statements), + token(node.closing_loc) + ) + end + + # The top-level program node. + def visit_program_node(node) + visit(node.statements) + end + + # 0..5 + # ^^^^ + def visit_range_node(node) + if node.exclude_end? + builder.range_exclusive( + visit(node.left), + token(node.operator_loc), + visit(node.right) + ) + else + builder.range_inclusive( + visit(node.left), + token(node.operator_loc), + visit(node.right) + ) + end + end + + # if foo .. bar; end + # ^^^^^^^^^^ + alias visit_flip_flop_node visit_range_node + + # 1r + # ^^ + def visit_rational_node(node) + visit_numeric(node, builder.rational([node.value, srange(node.location)])) + end + + # redo + # ^^^^ + def visit_redo_node(node) + builder.keyword_cmd(:redo, token(node.location)) + end + + # /foo/ + # ^^^^^ + def visit_regular_expression_node(node) + parts = + if node.content == "" + [] + elsif node.content.include?("\n") + string_nodes_from_line_continuations(node.unescaped, node.content, node.content_loc.start_offset, node.opening) + else + [builder.string_internal([node.unescaped, srange(node.content_loc)])] + end + + builder.regexp_compose( + token(node.opening_loc), + parts, + [node.closing[0], srange_offsets(node.closing_loc.start_offset, node.closing_loc.start_offset + 1)], + builder.regexp_options([node.closing[1..], srange_offsets(node.closing_loc.start_offset + 1, node.closing_loc.end_offset)]) + ) + end + + # if /foo/ then end + # ^^^^^ + alias visit_match_last_line_node visit_regular_expression_node + + # def foo(bar:); end + # ^^^^ + def visit_required_keyword_parameter_node(node) + builder.kwarg([node.name, srange(node.name_loc)]) + end + + # def foo(bar); end + # ^^^ + def visit_required_parameter_node(node) + builder.arg(token(node.location)) + end + + # foo rescue bar + # ^^^^^^^^^^^^^^ + def visit_rescue_modifier_node(node) + builder.begin_body( + visit(node.expression), + [ + builder.rescue_body( + token(node.keyword_loc), + nil, + nil, + nil, + nil, + visit(node.rescue_expression) + ) + ] + ) + end + + # begin; rescue; end + # ^^^^^^^ + def visit_rescue_node(node) + raise CompilationError, "Cannot directly compile rescue nodes" + end + + # def foo(*bar); end + # ^^^^ + # + # def foo(*); end + # ^ + def visit_rest_parameter_node(node) + builder.restarg(token(node.operator_loc), token(node.name_loc)) + end + + # retry + # ^^^^^ + def visit_retry_node(node) + builder.keyword_cmd(:retry, token(node.location)) + end + + # return + # ^^^^^^ + # + # return 1 + # ^^^^^^^^ + def visit_return_node(node) + builder.keyword_cmd( + :return, + token(node.keyword_loc), + nil, + visit(node.arguments) || [], + nil + ) + end + + # self + # ^^^^ + def visit_self_node(node) + builder.self(token(node.location)) + end + + # A shareable constant. + def visit_shareable_constant_node(node) + visit(node.write) + end + + # class << self; end + # ^^^^^^^^^^^^^^^^^^ + def visit_singleton_class_node(node) + builder.def_sclass( + token(node.class_keyword_loc), + token(node.operator_loc), + visit(node.expression), + node.body&.accept(copy_compiler(forwarding: [])), + token(node.end_keyword_loc) + ) + end + + # __ENCODING__ + # ^^^^^^^^^^^^ + def visit_source_encoding_node(node) + builder.accessible(builder.__ENCODING__(token(node.location))) + end + + # __FILE__ + # ^^^^^^^^ + def visit_source_file_node(node) + builder.accessible(builder.__FILE__(token(node.location))) + end + + # __LINE__ + # ^^^^^^^^ + def visit_source_line_node(node) + builder.accessible(builder.__LINE__(token(node.location))) + end + + # foo(*bar) + # ^^^^ + # + # def foo((bar, *baz)); end + # ^^^^ + # + # def foo(*); bar(*); end + # ^ + def visit_splat_node(node) + if node.expression.nil? && forwarding.include?(:*) + builder.forwarded_restarg(token(node.operator_loc)) + elsif in_destructure + builder.restarg(token(node.operator_loc), token(node.expression&.location)) + elsif in_pattern + builder.match_rest(token(node.operator_loc), token(node.expression&.location)) + else + builder.splat(token(node.operator_loc), visit(node.expression)) + end + end + + # A list of statements. + def visit_statements_node(node) + builder.compstmt(visit_all(node.body)) + end + + # "foo" + # ^^^^^ + def visit_string_node(node) + if node.heredoc? + visit_heredoc(node.to_interpolated) { |children, closing| builder.string_compose(token(node.opening_loc), children, closing) } + elsif node.opening == "?" + builder.character([node.unescaped, srange(node.location)]) + elsif node.opening&.start_with?("%") && node.unescaped.empty? + builder.string_compose(token(node.opening_loc), [], token(node.closing_loc)) + else + parts = + if node.content.include?("\n") + string_nodes_from_line_continuations(node.unescaped, node.content, node.content_loc.start_offset, node.opening) + else + [builder.string_internal([node.unescaped, srange(node.content_loc)])] + end + + builder.string_compose( + token(node.opening_loc), + parts, + token(node.closing_loc) + ) + end + end + + # super(foo) + # ^^^^^^^^^^ + def visit_super_node(node) + arguments = node.arguments&.arguments || [] + block = node.block + + if block.is_a?(BlockArgumentNode) + arguments = [*arguments, block] + block = nil + end + + visit_block( + builder.keyword_cmd( + :super, + token(node.keyword_loc), + token(node.lparen_loc), + visit_all(arguments), + token(node.rparen_loc) + ), + block + ) + end + + # :foo + # ^^^^ + def visit_symbol_node(node) + if node.closing_loc.nil? + if node.opening_loc.nil? + builder.symbol_internal([node.unescaped, srange(node.location)]) + else + builder.symbol([node.unescaped, srange(node.location)]) + end + else + parts = + if node.value == "" + [] + elsif node.value.include?("\n") + string_nodes_from_line_continuations(node.unescaped, node.value, node.value_loc.start_offset, node.opening) + else + [builder.string_internal([node.unescaped, srange(node.value_loc)])] + end + + builder.symbol_compose( + token(node.opening_loc), + parts, + token(node.closing_loc) + ) + end + end + + # true + # ^^^^ + def visit_true_node(node) + builder.true(token(node.location)) + end + + # undef foo + # ^^^^^^^^^ + def visit_undef_node(node) + builder.undef_method(token(node.keyword_loc), visit_all(node.names)) + end + + # unless foo; bar end + # ^^^^^^^^^^^^^^^^^^^ + # + # bar unless foo + # ^^^^^^^^^^^^^^ + def visit_unless_node(node) + if node.keyword_loc.start_offset == node.location.start_offset + builder.condition( + token(node.keyword_loc), + visit(node.predicate), + if (then_keyword_loc = node.then_keyword_loc) + token(then_keyword_loc) + else + srange_find(node.predicate.location.end_offset, (node.statements&.location || node.else_clause&.location || node.end_keyword_loc).start_offset, ";") + end, + visit(node.else_clause), + token(node.else_clause&.else_keyword_loc), + visit(node.statements), + token(node.end_keyword_loc) + ) + else + builder.condition_mod( + visit(node.else_clause), + visit(node.statements), + token(node.keyword_loc), + visit(node.predicate) + ) + end + end + + # until foo; bar end + # ^^^^^^^^^^^^^^^^^^ + # + # bar until foo + # ^^^^^^^^^^^^^ + def visit_until_node(node) + if node.location.start_offset == node.keyword_loc.start_offset + builder.loop( + :until, + token(node.keyword_loc), + visit(node.predicate), + if (do_keyword_loc = node.do_keyword_loc) + token(do_keyword_loc) + else + srange_find(node.predicate.location.end_offset, (node.statements&.location || node.closing_loc).start_offset, ";") + end, + visit(node.statements), + token(node.closing_loc) + ) + else + builder.loop_mod( + :until, + visit(node.statements), + token(node.keyword_loc), + visit(node.predicate) + ) + end + end + + # case foo; when bar; end + # ^^^^^^^^^^^^^ + def visit_when_node(node) + builder.when( + token(node.keyword_loc), + visit_all(node.conditions), + if (then_keyword_loc = node.then_keyword_loc) + token(then_keyword_loc) + else + srange_find(node.conditions.last.location.end_offset, node.statements&.location&.start_offset, ";") + end, + visit(node.statements) + ) + end + + # while foo; bar end + # ^^^^^^^^^^^^^^^^^^ + # + # bar while foo + # ^^^^^^^^^^^^^ + def visit_while_node(node) + if node.location.start_offset == node.keyword_loc.start_offset + builder.loop( + :while, + token(node.keyword_loc), + visit(node.predicate), + if (do_keyword_loc = node.do_keyword_loc) + token(do_keyword_loc) + else + srange_find(node.predicate.location.end_offset, (node.statements&.location || node.closing_loc).start_offset, ";") + end, + visit(node.statements), + token(node.closing_loc) + ) + else + builder.loop_mod( + :while, + visit(node.statements), + token(node.keyword_loc), + visit(node.predicate) + ) + end + end + + # `foo` + # ^^^^^ + def visit_x_string_node(node) + if node.heredoc? + return visit_heredoc(node.to_interpolated) { |children, closing| builder.xstring_compose(token(node.opening_loc), children, closing) } + end + + parts = + if node.content == "" + [] + elsif node.content.include?("\n") + string_nodes_from_line_continuations(node.unescaped, node.content, node.content_loc.start_offset, node.opening) + else + [builder.string_internal([node.unescaped, srange(node.content_loc)])] + end + + builder.xstring_compose( + token(node.opening_loc), + parts, + token(node.closing_loc) + ) + end + + # yield + # ^^^^^ + # + # yield 1 + # ^^^^^^^ + def visit_yield_node(node) + builder.keyword_cmd( + :yield, + token(node.keyword_loc), + token(node.lparen_loc), + visit(node.arguments) || [], + token(node.rparen_loc) + ) + end + + private + + # Initialize a new compiler with the given option overrides, used to + # visit a subtree with the given options. + def copy_compiler(forwarding: self.forwarding, in_destructure: self.in_destructure, in_pattern: self.in_pattern) + Compiler.new(parser, offset_cache, forwarding: forwarding, in_destructure: in_destructure, in_pattern: in_pattern) + end + + # When *, **, &, or ... are used as an argument in a method call, we + # check if they were allowed by the current context. To determine that + # we build this lookup table. + def find_forwarding(node) + return [] if node.nil? + + forwarding = [] + forwarding << :* if node.rest.is_a?(RestParameterNode) && node.rest.name.nil? + forwarding << :** if node.keyword_rest.is_a?(KeywordRestParameterNode) && node.keyword_rest.name.nil? + forwarding << :& if !node.block.nil? && node.block.name.nil? + forwarding |= [:&, :"..."] if node.keyword_rest.is_a?(ForwardingParameterNode) + + forwarding + end + + # Returns the set of targets for a MultiTargetNode or a MultiWriteNode. + def multi_target_elements(node) + elements = [*node.lefts] + elements << node.rest if !node.rest.nil? && !node.rest.is_a?(ImplicitRestNode) + elements.concat(node.rights) + elements + end + + # Negate the value of a numeric node. This is a special case where you + # have a negative sign on one line and then a number on the next line. + # In normal Ruby, this will always be a method call. The parser gem, + # however, marks this as a numeric literal. We have to massage the tree + # here to get it into the correct form. + def numeric_negate(message_loc, receiver) + case receiver.type + when :integer_node, :float_node + receiver.copy(value: -receiver.value, location: message_loc.join(receiver.location)) + when :rational_node + receiver.copy(numerator: -receiver.numerator, location: message_loc.join(receiver.location)) + when :imaginary_node + receiver.copy(numeric: numeric_negate(message_loc, receiver.numeric), location: message_loc.join(receiver.location)) + end + end + + # Blocks can have a special set of parameters that automatically expand + # when given arrays if they have a single required parameter and no + # other parameters. + def procarg0?(parameters) + parameters && + parameters.requireds.length == 1 && + parameters.optionals.empty? && + parameters.rest.nil? && + parameters.posts.empty? && + parameters.keywords.empty? && + parameters.keyword_rest.nil? && + parameters.block.nil? + end + + # Locations in the parser gem AST are generated using this class. We + # store a reference to its constant to make it slightly faster to look + # up. + Range = ::Parser::Source::Range + + # Constructs a new source range from the given start and end offsets. + def srange(location) + Range.new(source_buffer, offset_cache[location.start_offset], offset_cache[location.end_offset]) if location + end + + # Constructs a new source range from the given start and end offsets. + def srange_offsets(start_offset, end_offset) + Range.new(source_buffer, offset_cache[start_offset], offset_cache[end_offset]) + end + + # Constructs a new source range by finding the given character between + # the given start offset and end offset. If the needle is not found, it + # returns nil. Importantly it does not search past newlines or comments. + # + # Note that end_offset is allowed to be nil, in which case this will + # search until the end of the string. + def srange_find(start_offset, end_offset, character) + if (match = source_buffer.source.byteslice(start_offset...end_offset)[/\A\s*#{character}/]) + final_offset = start_offset + match.bytesize + [character, Range.new(source_buffer, offset_cache[final_offset - character.bytesize], offset_cache[final_offset])] + end + end + + # Transform a location into a token that the parser gem expects. + def token(location) + [location.slice, Range.new(source_buffer, offset_cache[location.start_offset], offset_cache[location.end_offset])] if location + end + + # Visit a block node on a call. + def visit_block(call, block) + if block + parameters = block.parameters + implicit_parameters = parameters.is_a?(NumberedParametersNode) || parameters.is_a?(ItParametersNode) + + builder.block( + call, + token(block.opening_loc), + if parameters.nil? + builder.args(nil, [], nil, false) + elsif implicit_parameters + visit(parameters) + else + builder.args( + token(parameters.opening_loc), + if procarg0?(parameters.parameters) + parameter = parameters.parameters.requireds.first + visited = parameter.is_a?(RequiredParameterNode) ? visit(parameter) : parameter.accept(copy_compiler(in_destructure: true)) + [builder.procarg0(visited)].concat(visit_all(parameters.locals)) + else + visit(parameters) + end, + token(parameters.closing_loc), + false + ) + end, + visit(block.body), + token(block.closing_loc) + ) + else + call + end + end + + # Visit a heredoc that can be either a string or an xstring. + def visit_heredoc(node) + children = Array.new + indented = false + + # If this is a dedenting heredoc, then we need to insert the opening + # content into the children as well. + if node.opening.start_with?("<<~") && node.parts.length > 0 && !node.parts.first.is_a?(StringNode) + location = node.parts.first.location + location = location.copy(start_offset: location.start_offset - location.start_line_slice.bytesize) + children << builder.string_internal(token(location)) + indented = true + end + + node.parts.each do |part| + pushing = + if part.is_a?(StringNode) && part.content.include?("\n") + string_nodes_from_line_continuations(part.unescaped, part.content, part.location.start_offset, node.opening) + else + [visit(part)] + end + + pushing.each do |child| + if child.type == :str && child.children.last == "" + # nothing + elsif child.type == :str && children.last && children.last.type == :str && !children.last.children.first.end_with?("\n") + appendee = children[-1] + + location = appendee.loc + location = location.with_expression(location.expression.join(child.loc.expression)) + + children[-1] = appendee.updated(:str, ["#{appendee.children.first}#{child.children.first}"], location: location) + else + children << child + end + end + end + + closing = node.closing + closing_t = [closing.chomp, srange_offsets(node.closing_loc.start_offset, node.closing_loc.end_offset - (closing[/\s+$/]&.length || 0))] + composed = yield children, closing_t + + composed = composed.updated(nil, children[1..-1]) if indented + composed + end + + # Visit a numeric node and account for the optional sign. + def visit_numeric(node, value) + if (slice = node.slice).match?(/^[+-]/) + builder.unary_num( + [slice[0].to_sym, srange_offsets(node.location.start_offset, node.location.start_offset + 1)], + value + ) + else + value + end + end + + # Within the given block, track that we're within a pattern. + def within_pattern + begin + parser.pattern_variables.push + yield copy_compiler(in_pattern: true) + ensure + parser.pattern_variables.pop + end + end + + # When the content of a string node is split across multiple lines, the + # parser gem creates individual string nodes for each line the content is part of. + def string_nodes_from_interpolation(node, opening) + node.parts.flat_map do |part| + if part.type == :string_node && part.content.include?("\n") && part.opening_loc.nil? + string_nodes_from_line_continuations(part.unescaped, part.content, part.content_loc.start_offset, opening) + else + visit(part) + end + end + end + + # Create parser string nodes from a single prism node. The parser gem + # "glues" strings together when a line continuation is encountered. + def string_nodes_from_line_continuations(unescaped, escaped, start_offset, opening) + unescaped = unescaped.lines + escaped = escaped.lines + percent_array = opening&.start_with?("%w", "%W", "%i", "%I") + regex = opening == "/" || opening&.start_with?("%r") + + # Non-interpolating strings + if opening&.end_with?("'") || opening&.start_with?("%q", "%s", "%w", "%i") + current_length = 0 + current_line = +"" + + escaped.filter_map.with_index do |escaped_line, index| + unescaped_line = unescaped.fetch(index, "") + current_length += escaped_line.bytesize + current_line << unescaped_line + + # Glue line continuations together. Only %w and %i arrays can contain these. + if percent_array && escaped_line[/(\\)*\n$/, 1]&.length&.odd? + next unless index == escaped.count - 1 + end + s = builder.string_internal([current_line, srange_offsets(start_offset, start_offset + current_length)]) + start_offset += escaped_line.bytesize + current_line = +"" + current_length = 0 + s + end + else + escaped_lengths = [] + normalized_lengths = [] + # Keeps track of where an unescaped line should start a new token. An unescaped + # \n would otherwise be indistinguishable from the actual newline at the end of + # of the line. The parser gem only emits a new string node at "real" newlines, + # line continuations don't start a new node as well. + do_next_tokens = [] + + escaped + .chunk_while { |before, after| before[/(\\*)\r?\n$/, 1]&.length&.odd? || false } + .each do |lines| + escaped_lengths << lines.sum(&:bytesize) + + unescaped_lines_count = + if regex + 0 # Will always be preserved as is + else + lines.sum do |line| + count = line.scan(/(\\*)n/).count { |(backslashes)| backslashes&.length&.odd? } + count -= 1 if !line.end_with?("\n") && count > 0 + count + end + end + + extra = 1 + extra = lines.count if percent_array # Account for line continuations in percent arrays + + normalized_lengths.concat(Array.new(unescaped_lines_count + extra, 0)) + normalized_lengths[-1] = lines.sum { |line| line.bytesize } + do_next_tokens.concat(Array.new(unescaped_lines_count + extra, false)) + do_next_tokens[-1] = true + end + + current_line = +"" + current_normalized_length = 0 + + emitted_count = 0 + unescaped.filter_map.with_index do |unescaped_line, index| + current_line << unescaped_line + current_normalized_length += normalized_lengths.fetch(index, 0) + + if do_next_tokens[index] + inner_part = builder.string_internal([current_line, srange_offsets(start_offset, start_offset + current_normalized_length)]) + start_offset += escaped_lengths.fetch(emitted_count, 0) + current_line = +"" + current_normalized_length = 0 + emitted_count += 1 + inner_part + else + nil + end + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/parser/lexer.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/parser/lexer.rb new file mode 100644 index 00000000..7db51949 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/parser/lexer.rb @@ -0,0 +1,812 @@ +# frozen_string_literal: true + +require "strscan" +require_relative "../../polyfill/append_as_bytes" + +module Prism + module Translation + class Parser + # Accepts a list of prism tokens and converts them into the expected + # format for the parser gem. + class Lexer + # These tokens are always skipped + TYPES_ALWAYS_SKIP = Set.new(%i[IGNORED_NEWLINE __END__ EOF]) + private_constant :TYPES_ALWAYS_SKIP + + # The direct translating of types between the two lexers. + TYPES = { + # These tokens should never appear in the output of the lexer. + MISSING: nil, + NOT_PROVIDED: nil, + EMBDOC_END: nil, + EMBDOC_LINE: nil, + + # These tokens have more or less direct mappings. + AMPERSAND: :tAMPER2, + AMPERSAND_AMPERSAND: :tANDOP, + AMPERSAND_AMPERSAND_EQUAL: :tOP_ASGN, + AMPERSAND_DOT: :tANDDOT, + AMPERSAND_EQUAL: :tOP_ASGN, + BACK_REFERENCE: :tBACK_REF, + BACKTICK: :tXSTRING_BEG, + BANG: :tBANG, + BANG_EQUAL: :tNEQ, + BANG_TILDE: :tNMATCH, + BRACE_LEFT: :tLCURLY, + BRACE_RIGHT: :tRCURLY, + BRACKET_LEFT: :tLBRACK2, + BRACKET_LEFT_ARRAY: :tLBRACK, + BRACKET_LEFT_RIGHT: :tAREF, + BRACKET_LEFT_RIGHT_EQUAL: :tASET, + BRACKET_RIGHT: :tRBRACK, + CARET: :tCARET, + CARET_EQUAL: :tOP_ASGN, + CHARACTER_LITERAL: :tCHARACTER, + CLASS_VARIABLE: :tCVAR, + COLON: :tCOLON, + COLON_COLON: :tCOLON2, + COMMA: :tCOMMA, + COMMENT: :tCOMMENT, + CONSTANT: :tCONSTANT, + DOT: :tDOT, + DOT_DOT: :tDOT2, + DOT_DOT_DOT: :tDOT3, + EMBDOC_BEGIN: :tCOMMENT, + EMBEXPR_BEGIN: :tSTRING_DBEG, + EMBEXPR_END: :tSTRING_DEND, + EMBVAR: :tSTRING_DVAR, + EQUAL: :tEQL, + EQUAL_EQUAL: :tEQ, + EQUAL_EQUAL_EQUAL: :tEQQ, + EQUAL_GREATER: :tASSOC, + EQUAL_TILDE: :tMATCH, + FLOAT: :tFLOAT, + FLOAT_IMAGINARY: :tIMAGINARY, + FLOAT_RATIONAL: :tRATIONAL, + FLOAT_RATIONAL_IMAGINARY: :tIMAGINARY, + GLOBAL_VARIABLE: :tGVAR, + GREATER: :tGT, + GREATER_EQUAL: :tGEQ, + GREATER_GREATER: :tRSHFT, + GREATER_GREATER_EQUAL: :tOP_ASGN, + HEREDOC_START: :tSTRING_BEG, + HEREDOC_END: :tSTRING_END, + IDENTIFIER: :tIDENTIFIER, + INSTANCE_VARIABLE: :tIVAR, + INTEGER: :tINTEGER, + INTEGER_IMAGINARY: :tIMAGINARY, + INTEGER_RATIONAL: :tRATIONAL, + INTEGER_RATIONAL_IMAGINARY: :tIMAGINARY, + KEYWORD_ALIAS: :kALIAS, + KEYWORD_AND: :kAND, + KEYWORD_BEGIN: :kBEGIN, + KEYWORD_BEGIN_UPCASE: :klBEGIN, + KEYWORD_BREAK: :kBREAK, + KEYWORD_CASE: :kCASE, + KEYWORD_CLASS: :kCLASS, + KEYWORD_DEF: :kDEF, + KEYWORD_DEFINED: :kDEFINED, + KEYWORD_DO: :kDO, + KEYWORD_DO_LOOP: :kDO_COND, + KEYWORD_END: :kEND, + KEYWORD_END_UPCASE: :klEND, + KEYWORD_ENSURE: :kENSURE, + KEYWORD_ELSE: :kELSE, + KEYWORD_ELSIF: :kELSIF, + KEYWORD_FALSE: :kFALSE, + KEYWORD_FOR: :kFOR, + KEYWORD_IF: :kIF, + KEYWORD_IF_MODIFIER: :kIF_MOD, + KEYWORD_IN: :kIN, + KEYWORD_MODULE: :kMODULE, + KEYWORD_NEXT: :kNEXT, + KEYWORD_NIL: :kNIL, + KEYWORD_NOT: :kNOT, + KEYWORD_OR: :kOR, + KEYWORD_REDO: :kREDO, + KEYWORD_RESCUE: :kRESCUE, + KEYWORD_RESCUE_MODIFIER: :kRESCUE_MOD, + KEYWORD_RETRY: :kRETRY, + KEYWORD_RETURN: :kRETURN, + KEYWORD_SELF: :kSELF, + KEYWORD_SUPER: :kSUPER, + KEYWORD_THEN: :kTHEN, + KEYWORD_TRUE: :kTRUE, + KEYWORD_UNDEF: :kUNDEF, + KEYWORD_UNLESS: :kUNLESS, + KEYWORD_UNLESS_MODIFIER: :kUNLESS_MOD, + KEYWORD_UNTIL: :kUNTIL, + KEYWORD_UNTIL_MODIFIER: :kUNTIL_MOD, + KEYWORD_WHEN: :kWHEN, + KEYWORD_WHILE: :kWHILE, + KEYWORD_WHILE_MODIFIER: :kWHILE_MOD, + KEYWORD_YIELD: :kYIELD, + KEYWORD___ENCODING__: :k__ENCODING__, + KEYWORD___FILE__: :k__FILE__, + KEYWORD___LINE__: :k__LINE__, + LABEL: :tLABEL, + LABEL_END: :tLABEL_END, + LAMBDA_BEGIN: :tLAMBEG, + LESS: :tLT, + LESS_EQUAL: :tLEQ, + LESS_EQUAL_GREATER: :tCMP, + LESS_LESS: :tLSHFT, + LESS_LESS_EQUAL: :tOP_ASGN, + METHOD_NAME: :tFID, + MINUS: :tMINUS, + MINUS_EQUAL: :tOP_ASGN, + MINUS_GREATER: :tLAMBDA, + NEWLINE: :tNL, + NUMBERED_REFERENCE: :tNTH_REF, + PARENTHESIS_LEFT: :tLPAREN2, + PARENTHESIS_LEFT_PARENTHESES: :tLPAREN_ARG, + PARENTHESIS_RIGHT: :tRPAREN, + PERCENT: :tPERCENT, + PERCENT_EQUAL: :tOP_ASGN, + PERCENT_LOWER_I: :tQSYMBOLS_BEG, + PERCENT_LOWER_W: :tQWORDS_BEG, + PERCENT_UPPER_I: :tSYMBOLS_BEG, + PERCENT_UPPER_W: :tWORDS_BEG, + PERCENT_LOWER_X: :tXSTRING_BEG, + PLUS: :tPLUS, + PLUS_EQUAL: :tOP_ASGN, + PIPE_EQUAL: :tOP_ASGN, + PIPE: :tPIPE, + PIPE_PIPE: :tOROP, + PIPE_PIPE_EQUAL: :tOP_ASGN, + QUESTION_MARK: :tEH, + REGEXP_BEGIN: :tREGEXP_BEG, + REGEXP_END: :tSTRING_END, + SEMICOLON: :tSEMI, + SLASH: :tDIVIDE, + SLASH_EQUAL: :tOP_ASGN, + STAR: :tSTAR2, + STAR_EQUAL: :tOP_ASGN, + STAR_STAR: :tPOW, + STAR_STAR_EQUAL: :tOP_ASGN, + STRING_BEGIN: :tSTRING_BEG, + STRING_CONTENT: :tSTRING_CONTENT, + STRING_END: :tSTRING_END, + SYMBOL_BEGIN: :tSYMBEG, + TILDE: :tTILDE, + UAMPERSAND: :tAMPER, + UCOLON_COLON: :tCOLON3, + UDOT_DOT: :tBDOT2, + UDOT_DOT_DOT: :tBDOT3, + UMINUS: :tUMINUS, + UMINUS_NUM: :tUNARY_NUM, + UPLUS: :tUPLUS, + USTAR: :tSTAR, + USTAR_STAR: :tDSTAR, + WORDS_SEP: :tSPACE + } + + # These constants represent flags in our lex state. We really, really + # don't want to be using them and we really, really don't want to be + # exposing them as part of our public API. Unfortunately, we don't have + # another way of matching the exact tokens that the parser gem expects + # without them. We should find another way to do this, but in the + # meantime we'll hide them from the documentation and mark them as + # private constants. + EXPR_BEG = 0x1 # :nodoc: + EXPR_LABEL = 0x400 # :nodoc: + + # It is used to determine whether `do` is of the token type `kDO` or `kDO_LAMBDA`. + # + # NOTE: In edge cases like `-> (foo = -> (bar) {}) do end`, please note that `kDO` is still returned + # instead of `kDO_LAMBDA`, which is expected: https://github.com/ruby/prism/pull/3046 + LAMBDA_TOKEN_TYPES = Set.new([:kDO_LAMBDA, :tLAMBDA, :tLAMBEG]) + + # The `PARENTHESIS_LEFT` token in Prism is classified as either `tLPAREN` or `tLPAREN2` in the Parser gem. + # The following token types are listed as those classified as `tLPAREN`. + LPAREN_CONVERSION_TOKEN_TYPES = Set.new([ + :kBREAK, :kCASE, :tDIVIDE, :kFOR, :kIF, :kNEXT, :kRETURN, :kUNTIL, :kWHILE, :tAMPER, :tANDOP, :tBANG, :tCOMMA, :tDOT2, :tDOT3, + :tEQL, :tLPAREN, :tLPAREN2, :tLPAREN_ARG, :tLSHFT, :tNL, :tOP_ASGN, :tOROP, :tPIPE, :tSEMI, :tSTRING_DBEG, :tUMINUS, :tUPLUS + ]) + + # Types of tokens that are allowed to continue a method call with comments in-between. + # For these, the parser gem doesn't emit a newline token after the last comment. + COMMENT_CONTINUATION_TYPES = Set.new([:COMMENT, :AMPERSAND_DOT, :DOT]) + private_constant :COMMENT_CONTINUATION_TYPES + + # Heredocs are complex and require us to keep track of a bit of info to refer to later + HeredocData = Struct.new(:identifier, :common_whitespace, keyword_init: true) + + private_constant :TYPES, :EXPR_BEG, :EXPR_LABEL, :LAMBDA_TOKEN_TYPES, :LPAREN_CONVERSION_TOKEN_TYPES, :HeredocData + + # The Parser::Source::Buffer that the tokens were lexed from. + attr_reader :source_buffer + + # An array of tuples that contain prism tokens and their associated lex + # state when they were lexed. + attr_reader :lexed + + # A hash that maps offsets in bytes to offsets in characters. + attr_reader :offset_cache + + # Initialize the lexer with the given source buffer, prism tokens, and + # offset cache. + def initialize(source_buffer, lexed, offset_cache) + @source_buffer = source_buffer + @lexed = lexed + @offset_cache = offset_cache + end + + Range = ::Parser::Source::Range # :nodoc: + private_constant :Range + + # Convert the prism tokens into the expected format for the parser gem. + def to_a + tokens = [] + + index = 0 + length = lexed.length + + heredoc_stack = [] + quote_stack = [] + + # The parser gem emits the newline tokens for comments out of order. This saves + # that token location to emit at a later time to properly line everything up. + # https://github.com/whitequark/parser/issues/1025 + comment_newline_location = nil + + while index < length + token, state = lexed[index] + index += 1 + next if TYPES_ALWAYS_SKIP.include?(token.type) + + type = TYPES.fetch(token.type) + value = token.value + location = range(token.location.start_offset, token.location.end_offset) + + case type + when :kDO + nearest_lambda_token = tokens.reverse_each.find do |token| + LAMBDA_TOKEN_TYPES.include?(token.first) + end + + if nearest_lambda_token&.first == :tLAMBDA + type = :kDO_LAMBDA + end + when :tCHARACTER + value.delete_prefix!("?") + # Character literals behave similar to double-quoted strings. We can use the same escaping mechanism. + value = unescape_string(value, "?") + when :tCOMMENT + if token.type == :EMBDOC_BEGIN + + while !((next_token = lexed[index][0]) && next_token.type == :EMBDOC_END) && (index < length - 1) + value += next_token.value + index += 1 + end + + value += next_token.value + location = range(token.location.start_offset, lexed[index][0].location.end_offset) + index += 1 + else + is_at_eol = value.chomp!.nil? + location = range(token.location.start_offset, token.location.end_offset + (is_at_eol ? 0 : -1)) + + prev_token = lexed[index - 2][0] if index - 2 >= 0 + next_token = lexed[index][0] + + is_inline_comment = prev_token&.location&.start_line == token.location.start_line + if is_inline_comment && !is_at_eol && !COMMENT_CONTINUATION_TYPES.include?(next_token&.type) + tokens << [:tCOMMENT, [value, location]] + + nl_location = range(token.location.end_offset - 1, token.location.end_offset) + tokens << [:tNL, [nil, nl_location]] + next + elsif is_inline_comment && next_token&.type == :COMMENT + comment_newline_location = range(token.location.end_offset - 1, token.location.end_offset) + elsif comment_newline_location && !COMMENT_CONTINUATION_TYPES.include?(next_token&.type) + tokens << [:tCOMMENT, [value, location]] + tokens << [:tNL, [nil, comment_newline_location]] + comment_newline_location = nil + next + end + end + when :tNL + next_token = next_token = lexed[index][0] + # Newlines after comments are emitted out of order. + if next_token&.type == :COMMENT + comment_newline_location = location + next + end + + value = nil + when :tFLOAT + value = parse_float(value) + when :tIMAGINARY + value = parse_complex(value) + when :tINTEGER + if value.start_with?("+") + tokens << [:tUNARY_NUM, ["+", range(token.location.start_offset, token.location.start_offset + 1)]] + location = range(token.location.start_offset + 1, token.location.end_offset) + end + + value = parse_integer(value) + when :tLABEL + value.chomp!(":") + when :tLABEL_END + value.chomp!(":") + when :tLCURLY + type = :tLBRACE if state == EXPR_BEG | EXPR_LABEL + when :tLPAREN2 + type = :tLPAREN if tokens.empty? || LPAREN_CONVERSION_TOKEN_TYPES.include?(tokens.dig(-1, 0)) + when :tNTH_REF + value = parse_integer(value.delete_prefix("$")) + when :tOP_ASGN + value.chomp!("=") + when :tRATIONAL + value = parse_rational(value) + when :tSPACE + location = range(token.location.start_offset, token.location.start_offset + percent_array_leading_whitespace(value)) + value = nil + when :tSTRING_BEG + next_token = lexed[index][0] + next_next_token = lexed[index + 1][0] + basic_quotes = value == '"' || value == "'" + + if basic_quotes && next_token&.type == :STRING_END + next_location = token.location.join(next_token.location) + type = :tSTRING + value = "" + location = range(next_location.start_offset, next_location.end_offset) + index += 1 + elsif value.start_with?("'", '"', "%") + if next_token&.type == :STRING_CONTENT && next_next_token&.type == :STRING_END + string_value = next_token.value + if simplify_string?(string_value, value) + next_location = token.location.join(next_next_token.location) + if percent_array?(value) + value = percent_array_unescape(string_value) + else + value = unescape_string(string_value, value) + end + type = :tSTRING + location = range(next_location.start_offset, next_location.end_offset) + index += 2 + tokens << [type, [value, location]] + + next + end + end + + quote_stack.push(value) + elsif token.type == :HEREDOC_START + quote = value[2] == "-" || value[2] == "~" ? value[3] : value[2] + heredoc_type = value[2] == "-" || value[2] == "~" ? value[2] : "" + heredoc = HeredocData.new( + identifier: value.match(/<<[-~]?["'`]?(?.*?)["'`]?\z/)[:heredoc_identifier], + common_whitespace: 0, + ) + + if quote == "`" + type = :tXSTRING_BEG + end + + # The parser gem trims whitespace from squiggly heredocs. We must record + # the most common whitespace to later remove. + if heredoc_type == "~" || heredoc_type == "`" + heredoc.common_whitespace = calculate_heredoc_whitespace(index) + end + + if quote == "'" || quote == '"' || quote == "`" + value = "<<#{quote}" + else + value = '<<"' + end + + heredoc_stack.push(heredoc) + quote_stack.push(value) + end + when :tSTRING_CONTENT + is_percent_array = percent_array?(quote_stack.last) + + if (lines = token.value.lines).one? + # Prism usually emits a single token for strings with line continuations. + # For squiggly heredocs they are not joined so we do that manually here. + current_string = +"" + current_length = 0 + start_offset = token.location.start_offset + while token.type == :STRING_CONTENT + current_length += token.value.bytesize + # Heredoc interpolation can have multiple STRING_CONTENT nodes on the same line. + is_first_token_on_line = lexed[index - 1] && token.location.start_line != lexed[index - 2][0].location&.start_line + # The parser gem only removes indentation when the heredoc is not nested + not_nested = heredoc_stack.size == 1 + if is_percent_array + value = percent_array_unescape(token.value) + elsif is_first_token_on_line && not_nested && (current_heredoc = heredoc_stack.last).common_whitespace > 0 + value = trim_heredoc_whitespace(token.value, current_heredoc) + end + + current_string << unescape_string(value, quote_stack.last) + if (backslash_count = token.value[/(\\{1,})\n/, 1]&.length).nil? || backslash_count.even? || !interpolation?(quote_stack.last) + tokens << [:tSTRING_CONTENT, [current_string, range(start_offset, start_offset + current_length)]] + break + end + token = lexed[index][0] + index += 1 + end + else + # When the parser gem encounters a line continuation inside of a multiline string, + # it emits a single string node. The backslash (and remaining newline) is removed. + current_line = +"" + adjustment = 0 + start_offset = token.location.start_offset + emit = false + + lines.each.with_index do |line, index| + chomped_line = line.chomp + backslash_count = chomped_line[/\\{1,}\z/]&.length || 0 + is_interpolation = interpolation?(quote_stack.last) + + if backslash_count.odd? && (is_interpolation || is_percent_array) + if is_percent_array + current_line << percent_array_unescape(line) + adjustment += 1 + else + chomped_line.delete_suffix!("\\") + current_line << chomped_line + adjustment += 2 + end + # If the string ends with a line continuation emit the remainder + emit = index == lines.count - 1 + else + current_line << line + emit = true + end + + if emit + end_offset = start_offset + current_line.bytesize + adjustment + tokens << [:tSTRING_CONTENT, [unescape_string(current_line, quote_stack.last), range(start_offset, end_offset)]] + start_offset = end_offset + current_line = +"" + adjustment = 0 + end + end + end + next + when :tSTRING_DVAR + value = nil + when :tSTRING_END + if token.type == :HEREDOC_END && value.end_with?("\n") + newline_length = value.end_with?("\r\n") ? 2 : 1 + value = heredoc_stack.pop.identifier + location = range(token.location.start_offset, token.location.end_offset - newline_length) + elsif token.type == :REGEXP_END + value = value[0] + location = range(token.location.start_offset, token.location.start_offset + 1) + end + + if percent_array?(quote_stack.pop) + prev_token = lexed[index - 2][0] if index - 2 >= 0 + empty = %i[PERCENT_LOWER_I PERCENT_LOWER_W PERCENT_UPPER_I PERCENT_UPPER_W].include?(prev_token&.type) + ends_with_whitespace = prev_token&.type == :WORDS_SEP + # parser always emits a space token after content in a percent array, even if no actual whitespace is present. + if !empty && !ends_with_whitespace + tokens << [:tSPACE, [nil, range(token.location.start_offset, token.location.start_offset)]] + end + end + when :tSYMBEG + if (next_token = lexed[index][0]) && next_token.type != :STRING_CONTENT && next_token.type != :EMBEXPR_BEGIN && next_token.type != :EMBVAR && next_token.type != :STRING_END + next_location = token.location.join(next_token.location) + type = :tSYMBOL + value = next_token.value + value = { "~@" => "~", "!@" => "!" }.fetch(value, value) + location = range(next_location.start_offset, next_location.end_offset) + index += 1 + else + quote_stack.push(value) + end + when :tFID + if !tokens.empty? && tokens.dig(-1, 0) == :kDEF + type = :tIDENTIFIER + end + when :tXSTRING_BEG + if (next_token = lexed[index][0]) && !%i[STRING_CONTENT STRING_END EMBEXPR_BEGIN].include?(next_token.type) + # self.`() + type = :tBACK_REF2 + end + quote_stack.push(value) + when :tSYMBOLS_BEG, :tQSYMBOLS_BEG, :tWORDS_BEG, :tQWORDS_BEG + if (next_token = lexed[index][0]) && next_token.type == :WORDS_SEP + index += 1 + end + + quote_stack.push(value) + when :tREGEXP_BEG + quote_stack.push(value) + end + + tokens << [type, [value, location]] + + if token.type == :REGEXP_END + tokens << [:tREGEXP_OPT, [token.value[1..], range(token.location.start_offset + 1, token.location.end_offset)]] + end + end + + tokens + end + + private + + # Creates a new parser range, taking prisms byte offsets into account + def range(start_offset, end_offset) + Range.new(source_buffer, offset_cache[start_offset], offset_cache[end_offset]) + end + + # Parse an integer from the string representation. + def parse_integer(value) + Integer(value) + rescue ArgumentError + 0 + end + + # Parse a float from the string representation. + def parse_float(value) + Float(value) + rescue ArgumentError + 0.0 + end + + # Parse a complex from the string representation. + def parse_complex(value) + value.chomp!("i") + + if value.end_with?("r") + Complex(0, parse_rational(value)) + elsif value.start_with?(/0[BbOoDdXx]/) + Complex(0, parse_integer(value)) + else + Complex(0, value) + end + rescue ArgumentError + 0i + end + + # Parse a rational from the string representation. + def parse_rational(value) + value.chomp!("r") + + if value.start_with?(/0[BbOoDdXx]/) + Rational(parse_integer(value)) + else + Rational(value) + end + rescue ArgumentError + 0r + end + + # Wonky heredoc tab/spaces rules. + # https://github.com/ruby/prism/blob/v1.3.0/src/prism.c#L10548-L10558 + def calculate_heredoc_whitespace(heredoc_token_index) + next_token_index = heredoc_token_index + nesting_level = 0 + previous_line = -1 + result = Float::MAX + + while (lexed[next_token_index] && next_token = lexed[next_token_index][0]) + next_token_index += 1 + next_next_token = lexed[next_token_index] && lexed[next_token_index][0] + first_token_on_line = next_token.location.start_column == 0 + + # String content inside nested heredocs and interpolation is ignored + if next_token.type == :HEREDOC_START || next_token.type == :EMBEXPR_BEGIN + # When interpolation is the first token of a line there is no string + # content to check against. There will be no common whitespace. + if nesting_level == 0 && first_token_on_line + result = 0 + end + nesting_level += 1 + elsif next_token.type == :HEREDOC_END || next_token.type == :EMBEXPR_END + nesting_level -= 1 + # When we encountered the matching heredoc end, we can exit + break if nesting_level == -1 + elsif next_token.type == :STRING_CONTENT && nesting_level == 0 && first_token_on_line + common_whitespace = 0 + next_token.value[/^\s*/].each_char do |char| + if char == "\t" + common_whitespace = (common_whitespace / 8 + 1) * 8; + else + common_whitespace += 1 + end + end + + is_first_token_on_line = next_token.location.start_line != previous_line + # Whitespace is significant if followed by interpolation + whitespace_only = common_whitespace == next_token.value.length && next_next_token&.location&.start_line != next_token.location.start_line + if is_first_token_on_line && !whitespace_only && common_whitespace < result + result = common_whitespace + previous_line = next_token.location.start_line + end + end + end + result + end + + # Wonky heredoc tab/spaces rules. + # https://github.com/ruby/prism/blob/v1.3.0/src/prism.c#L16528-L16545 + def trim_heredoc_whitespace(string, heredoc) + trimmed_whitespace = 0 + trimmed_characters = 0 + while (string[trimmed_characters] == "\t" || string[trimmed_characters] == " ") && trimmed_whitespace < heredoc.common_whitespace + if string[trimmed_characters] == "\t" + trimmed_whitespace = (trimmed_whitespace / 8 + 1) * 8; + break if trimmed_whitespace > heredoc.common_whitespace + else + trimmed_whitespace += 1 + end + trimmed_characters += 1 + end + + string[trimmed_characters..] + end + + # Escape sequences that have special and should appear unescaped in the resulting string. + ESCAPES = { + "a" => "\a", "b" => "\b", "e" => "\e", "f" => "\f", + "n" => "\n", "r" => "\r", "s" => "\s", "t" => "\t", + "v" => "\v", "\\" => "\\" + }.freeze + private_constant :ESCAPES + + # When one of these delimiters is encountered, then the other + # one is allowed to be escaped as well. + DELIMITER_SYMETRY = { "[" => "]", "(" => ")", "{" => "}", "<" => ">" }.freeze + private_constant :DELIMITER_SYMETRY + + + # https://github.com/whitequark/parser/blob/v3.3.6.0/lib/parser/lexer-strings.rl#L14 + REGEXP_META_CHARACTERS = ["\\", "$", "(", ")", "*", "+", ".", "<", ">", "?", "[", "]", "^", "{", "|", "}"] + private_constant :REGEXP_META_CHARACTERS + + # Apply Ruby string escaping rules + def unescape_string(string, quote) + # In single-quoted heredocs, everything is taken literally. + return string if quote == "<<'" + + # OPTIMIZATION: Assume that few strings need escaping to speed up the common case. + return string unless string.include?("\\") + + # Enclosing character for the string. `"` for `"foo"`, `{` for `%w{foo}`, etc. + delimiter = quote[-1] + + if regexp?(quote) + # Should be escaped handled to single-quoted heredocs. The only character that is + # allowed to be escaped is the delimiter, except when that also has special meaning + # in the regexp. Since all the symetry delimiters have special meaning, they don't need + # to be considered separately. + if REGEXP_META_CHARACTERS.include?(delimiter) + string + else + # There can never be an even amount of backslashes. It would be a syntax error. + string.gsub(/\\(#{Regexp.escape(delimiter)})/, '\1') + end + elsif interpolation?(quote) + # Appending individual escape sequences may force the string out of its intended + # encoding. Start out with binary and force it back later. + result = "".b + + scanner = StringScanner.new(string) + while (skipped = scanner.skip_until(/\\/)) + # Append what was just skipped over, excluding the found backslash. + result.append_as_bytes(string.byteslice(scanner.pos - skipped, skipped - 1)) + escape_read(result, scanner, false, false) + end + + # Add remaining chars + result.append_as_bytes(string.byteslice(scanner.pos..)) + result.force_encoding(source_buffer.source.encoding) + else + delimiters = Regexp.escape("#{delimiter}#{DELIMITER_SYMETRY[delimiter]}") + string.gsub(/\\([\\#{delimiters}])/, '\1') + end + end + + # Certain strings are merged into a single string token. + def simplify_string?(value, quote) + case quote + when "'" + # Only simplify 'foo' + !value.include?("\n") + when '"' + # Simplify when every line ends with a line continuation, or it is the last line + value.lines.all? do |line| + !line.end_with?("\n") || line[/(\\*)$/, 1]&.length&.odd? + end + else + # %q and similar are never simplified + false + end + end + + # Escape a byte value, given the control and meta flags. + def escape_build(value, control, meta) + value &= 0x9f if control + value |= 0x80 if meta + value + end + + # Read an escape out of the string scanner, given the control and meta + # flags, and push the unescaped value into the result. + def escape_read(result, scanner, control, meta) + if scanner.skip("\n") + # Line continuation + elsif (value = ESCAPES[scanner.peek(1)]) + # Simple single-character escape sequences like \n + result.append_as_bytes(value) + scanner.pos += 1 + elsif (value = scanner.scan(/[0-7]{1,3}/)) + # \nnn + result.append_as_bytes(escape_build(value.to_i(8), control, meta)) + elsif (value = scanner.scan(/x[0-9a-fA-F]{1,2}/)) + # \xnn + result.append_as_bytes(escape_build(value[1..].to_i(16), control, meta)) + elsif (value = scanner.scan(/u[0-9a-fA-F]{4}/)) + # \unnnn + result.append_as_bytes(value[1..].hex.chr(Encoding::UTF_8)) + elsif scanner.skip("u{}") + # https://github.com/whitequark/parser/issues/856 + elsif (value = scanner.scan(/u{.*?}/)) + # \u{nnnn ...} + value[2..-2].split.each do |unicode| + result.append_as_bytes(unicode.hex.chr(Encoding::UTF_8)) + end + elsif (value = scanner.scan(/c\\?(?=[[:print:]])|C-\\?(?=[[:print:]])/)) + # \cx or \C-x where x is an ASCII printable character + escape_read(result, scanner, true, meta) + elsif (value = scanner.scan(/M-\\?(?=[[:print:]])/)) + # \M-x where x is an ASCII printable character + escape_read(result, scanner, control, true) + elsif (byte = scanner.get_byte) + # Something else after an escape. + if control && byte == "?" + result.append_as_bytes(escape_build(0x7f, false, meta)) + else + result.append_as_bytes(escape_build(byte.ord, control, meta)) + end + end + end + + # In a percent array, certain whitespace can be preceeded with a backslash, + # causing the following characters to be part of the previous element. + def percent_array_unescape(string) + string.gsub(/(\\)+[ \f\n\r\t\v]/) do |full_match| + full_match.delete_prefix!("\\") if Regexp.last_match[1].length.odd? + full_match + end + end + + # For %-arrays whitespace, the parser gem only considers whitespace before the newline. + def percent_array_leading_whitespace(string) + return 1 if string.start_with?("\n") + + leading_whitespace = 0 + string.each_char do |c| + break if c == "\n" + leading_whitespace += 1 + end + leading_whitespace + end + + # Determine if characters preceeded by a backslash should be escaped or not + def interpolation?(quote) + !quote.end_with?("'") && !quote.start_with?("%q", "%w", "%i", "%s") + end + + # Regexp allow interpolation but are handled differently during unescaping + def regexp?(quote) + quote == "/" || quote.start_with?("%r") + end + + # Determine if the string is part of a %-style array. + def percent_array?(quote) + quote.start_with?("%w", "%W", "%i", "%I") + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/parser33.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/parser33.rb new file mode 100644 index 00000000..b09266e0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/parser33.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module Prism + module Translation + # This class is the entry-point for Ruby 3.3 of `Prism::Translation::Parser`. + class Parser33 < Parser + def version # :nodoc: + 33 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/parser34.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/parser34.rb new file mode 100644 index 00000000..0ead70ad --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/parser34.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module Prism + module Translation + # This class is the entry-point for Ruby 3.4 of `Prism::Translation::Parser`. + class Parser34 < Parser + def version # :nodoc: + 34 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/parser35.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/parser35.rb new file mode 100644 index 00000000..a6abc125 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/parser35.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module Prism + module Translation + # This class is the entry-point for Ruby 3.5 of `Prism::Translation::Parser`. + class Parser35 < Parser + def version # :nodoc: + 35 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/ripper.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/ripper.rb new file mode 100644 index 00000000..dce96e01 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/ripper.rb @@ -0,0 +1,3458 @@ +# frozen_string_literal: true + +require "ripper" + +module Prism + module Translation + # This class provides a compatibility layer between prism and Ripper. It + # functions by parsing the entire tree first and then walking it and + # executing each of the Ripper callbacks as it goes. To use this class, you + # treat `Prism::Translation::Ripper` effectively as you would treat the + # `Ripper` class. + # + # Note that this class will serve the most common use cases, but Ripper's + # API is extensive and undocumented. It relies on reporting the state of the + # parser at any given time. We do our best to replicate that here, but + # because it is a different architecture it is not possible to perfectly + # replicate the behavior of Ripper. + # + # The main known difference is that we may omit dispatching some events in + # some cases. This impacts the following events: + # + # - on_assign_error + # - on_comma + # - on_ignored_nl + # - on_ignored_sp + # - on_kw + # - on_label_end + # - on_lbrace + # - on_lbracket + # - on_lparen + # - on_nl + # - on_op + # - on_operator_ambiguous + # - on_rbrace + # - on_rbracket + # - on_rparen + # - on_semicolon + # - on_sp + # - on_symbeg + # - on_tstring_beg + # - on_tstring_end + # + class Ripper < Compiler + # Parses the given Ruby program read from +src+. + # +src+ must be a String or an IO or a object with a #gets method. + def self.parse(src, filename = "(ripper)", lineno = 1) + new(src, filename, lineno).parse + end + + # Tokenizes the Ruby program and returns an array of an array, + # which is formatted like + # [[lineno, column], type, token, state]. + # The +filename+ argument is mostly ignored. + # By default, this method does not handle syntax errors in +src+, + # use the +raise_errors+ keyword to raise a SyntaxError for an error in +src+. + # + # require "ripper" + # require "pp" + # + # pp Ripper.lex("def m(a) nil end") + # #=> [[[1, 0], :on_kw, "def", FNAME ], + # [[1, 3], :on_sp, " ", FNAME ], + # [[1, 4], :on_ident, "m", ENDFN ], + # [[1, 5], :on_lparen, "(", BEG|LABEL], + # [[1, 6], :on_ident, "a", ARG ], + # [[1, 7], :on_rparen, ")", ENDFN ], + # [[1, 8], :on_sp, " ", BEG ], + # [[1, 9], :on_kw, "nil", END ], + # [[1, 12], :on_sp, " ", END ], + # [[1, 13], :on_kw, "end", END ]] + # + def self.lex(src, filename = "-", lineno = 1, raise_errors: false) + result = Prism.lex_compat(src, filepath: filename, line: lineno) + + if result.failure? && raise_errors + raise SyntaxError, result.errors.first.message + else + result.value + end + end + + # This contains a table of all of the parser events and their + # corresponding arity. + PARSER_EVENT_TABLE = { + BEGIN: 1, + END: 1, + alias: 2, + alias_error: 2, + aref: 2, + aref_field: 2, + arg_ambiguous: 1, + arg_paren: 1, + args_add: 2, + args_add_block: 2, + args_add_star: 2, + args_forward: 0, + args_new: 0, + array: 1, + aryptn: 4, + assign: 2, + assign_error: 2, + assoc_new: 2, + assoc_splat: 1, + assoclist_from_args: 1, + bare_assoc_hash: 1, + begin: 1, + binary: 3, + block_var: 2, + blockarg: 1, + bodystmt: 4, + brace_block: 2, + break: 1, + call: 3, + case: 2, + class: 3, + class_name_error: 2, + command: 2, + command_call: 4, + const_path_field: 2, + const_path_ref: 2, + const_ref: 1, + def: 3, + defined: 1, + defs: 5, + do_block: 2, + dot2: 2, + dot3: 2, + dyna_symbol: 1, + else: 1, + elsif: 3, + ensure: 1, + excessed_comma: 0, + fcall: 1, + field: 3, + fndptn: 4, + for: 3, + hash: 1, + heredoc_dedent: 2, + hshptn: 3, + if: 3, + if_mod: 2, + ifop: 3, + in: 3, + kwrest_param: 1, + lambda: 2, + magic_comment: 2, + massign: 2, + method_add_arg: 2, + method_add_block: 2, + mlhs_add: 2, + mlhs_add_post: 2, + mlhs_add_star: 2, + mlhs_new: 0, + mlhs_paren: 1, + module: 2, + mrhs_add: 2, + mrhs_add_star: 2, + mrhs_new: 0, + mrhs_new_from_args: 1, + next: 1, + nokw_param: 1, + opassign: 3, + operator_ambiguous: 2, + param_error: 2, + params: 7, + paren: 1, + parse_error: 1, + program: 1, + qsymbols_add: 2, + qsymbols_new: 0, + qwords_add: 2, + qwords_new: 0, + redo: 0, + regexp_add: 2, + regexp_literal: 2, + regexp_new: 0, + rescue: 4, + rescue_mod: 2, + rest_param: 1, + retry: 0, + return: 1, + return0: 0, + sclass: 2, + stmts_add: 2, + stmts_new: 0, + string_add: 2, + string_concat: 2, + string_content: 0, + string_dvar: 1, + string_embexpr: 1, + string_literal: 1, + super: 1, + symbol: 1, + symbol_literal: 1, + symbols_add: 2, + symbols_new: 0, + top_const_field: 1, + top_const_ref: 1, + unary: 2, + undef: 1, + unless: 3, + unless_mod: 2, + until: 2, + until_mod: 2, + var_alias: 2, + var_field: 1, + var_ref: 1, + vcall: 1, + void_stmt: 0, + when: 3, + while: 2, + while_mod: 2, + word_add: 2, + word_new: 0, + words_add: 2, + words_new: 0, + xstring_add: 2, + xstring_literal: 1, + xstring_new: 0, + yield: 1, + yield0: 0, + zsuper: 0 + } + + # This contains a table of all of the scanner events and their + # corresponding arity. + SCANNER_EVENT_TABLE = { + CHAR: 1, + __end__: 1, + backref: 1, + backtick: 1, + comma: 1, + comment: 1, + const: 1, + cvar: 1, + embdoc: 1, + embdoc_beg: 1, + embdoc_end: 1, + embexpr_beg: 1, + embexpr_end: 1, + embvar: 1, + float: 1, + gvar: 1, + heredoc_beg: 1, + heredoc_end: 1, + ident: 1, + ignored_nl: 1, + imaginary: 1, + int: 1, + ivar: 1, + kw: 1, + label: 1, + label_end: 1, + lbrace: 1, + lbracket: 1, + lparen: 1, + nl: 1, + op: 1, + period: 1, + qsymbols_beg: 1, + qwords_beg: 1, + rational: 1, + rbrace: 1, + rbracket: 1, + regexp_beg: 1, + regexp_end: 1, + rparen: 1, + semicolon: 1, + sp: 1, + symbeg: 1, + symbols_beg: 1, + tlambda: 1, + tlambeg: 1, + tstring_beg: 1, + tstring_content: 1, + tstring_end: 1, + words_beg: 1, + words_sep: 1, + ignored_sp: 1 + } + + # This array contains name of parser events. + PARSER_EVENTS = PARSER_EVENT_TABLE.keys + + # This array contains name of scanner events. + SCANNER_EVENTS = SCANNER_EVENT_TABLE.keys + + # This array contains name of all ripper events. + EVENTS = PARSER_EVENTS + SCANNER_EVENTS + + # A list of all of the Ruby keywords. + KEYWORDS = [ + "alias", + "and", + "begin", + "BEGIN", + "break", + "case", + "class", + "def", + "defined?", + "do", + "else", + "elsif", + "end", + "END", + "ensure", + "false", + "for", + "if", + "in", + "module", + "next", + "nil", + "not", + "or", + "redo", + "rescue", + "retry", + "return", + "self", + "super", + "then", + "true", + "undef", + "unless", + "until", + "when", + "while", + "yield", + "__ENCODING__", + "__FILE__", + "__LINE__" + ] + + # A list of all of the Ruby binary operators. + BINARY_OPERATORS = [ + :!=, + :!~, + :=~, + :==, + :===, + :<=>, + :>, + :>=, + :<, + :<=, + :&, + :|, + :^, + :>>, + :<<, + :-, + :+, + :%, + :/, + :*, + :** + ] + + private_constant :KEYWORDS, :BINARY_OPERATORS + + # Parses +src+ and create S-exp tree. + # Returns more readable tree rather than Ripper.sexp_raw. + # This method is mainly for developer use. + # The +filename+ argument is mostly ignored. + # By default, this method does not handle syntax errors in +src+, + # returning +nil+ in such cases. Use the +raise_errors+ keyword + # to raise a SyntaxError for an error in +src+. + # + # require "ripper" + # require "pp" + # + # pp Ripper.sexp("def m(a) nil end") + # #=> [:program, + # [[:def, + # [:@ident, "m", [1, 4]], + # [:paren, [:params, [[:@ident, "a", [1, 6]]], nil, nil, nil, nil, nil, nil]], + # [:bodystmt, [[:var_ref, [:@kw, "nil", [1, 9]]]], nil, nil, nil]]]] + # + def self.sexp(src, filename = "-", lineno = 1, raise_errors: false) + builder = SexpBuilderPP.new(src, filename, lineno) + sexp = builder.parse + if builder.error? + if raise_errors + raise SyntaxError, builder.error + end + else + sexp + end + end + + # Parses +src+ and create S-exp tree. + # This method is mainly for developer use. + # The +filename+ argument is mostly ignored. + # By default, this method does not handle syntax errors in +src+, + # returning +nil+ in such cases. Use the +raise_errors+ keyword + # to raise a SyntaxError for an error in +src+. + # + # require "ripper" + # require "pp" + # + # pp Ripper.sexp_raw("def m(a) nil end") + # #=> [:program, + # [:stmts_add, + # [:stmts_new], + # [:def, + # [:@ident, "m", [1, 4]], + # [:paren, [:params, [[:@ident, "a", [1, 6]]], nil, nil, nil]], + # [:bodystmt, + # [:stmts_add, [:stmts_new], [:var_ref, [:@kw, "nil", [1, 9]]]], + # nil, + # nil, + # nil]]]] + # + def self.sexp_raw(src, filename = "-", lineno = 1, raise_errors: false) + builder = SexpBuilder.new(src, filename, lineno) + sexp = builder.parse + if builder.error? + if raise_errors + raise SyntaxError, builder.error + end + else + sexp + end + end + + autoload :SexpBuilder, "prism/translation/ripper/sexp" + autoload :SexpBuilderPP, "prism/translation/ripper/sexp" + + # The source that is being parsed. + attr_reader :source + + # The filename of the source being parsed. + attr_reader :filename + + # The current line number of the parser. + attr_reader :lineno + + # The current column number of the parser. + attr_reader :column + + # Create a new Translation::Ripper object with the given source. + def initialize(source, filename = "(ripper)", lineno = 1) + @source = source + @filename = filename + @lineno = lineno + @column = 0 + @result = nil + end + + ########################################################################## + # Public interface + ########################################################################## + + # True if the parser encountered an error during parsing. + def error? + result.failure? + end + + # Parse the source and return the result. + def parse + result.comments.each do |comment| + location = comment.location + bounds(location) + + if comment.is_a?(InlineComment) + on_comment(comment.slice) + else + offset = location.start_offset + lines = comment.slice.lines + + lines.each_with_index do |line, index| + bounds(location.copy(start_offset: offset)) + + if index == 0 + on_embdoc_beg(line) + elsif index == lines.size - 1 + on_embdoc_end(line) + else + on_embdoc(line) + end + + offset += line.bytesize + end + end + end + + result.magic_comments.each do |magic_comment| + on_magic_comment(magic_comment.key, magic_comment.value) + end + + unless result.data_loc.nil? + on___end__(result.data_loc.slice.each_line.first) + end + + result.warnings.each do |warning| + bounds(warning.location) + + if warning.level == :default + warning(warning.message) + else + case warning.type + when :ambiguous_first_argument_plus + on_arg_ambiguous("+") + when :ambiguous_first_argument_minus + on_arg_ambiguous("-") + when :ambiguous_slash + on_arg_ambiguous("/") + else + warn(warning.message) + end + end + end + + if error? + result.errors.each do |error| + location = error.location + bounds(location) + + case error.type + when :alias_argument + on_alias_error("can't make alias for the number variables", location.slice) + when :argument_formal_class + on_param_error("formal argument cannot be a class variable", location.slice) + when :argument_format_constant + on_param_error("formal argument cannot be a constant", location.slice) + when :argument_formal_global + on_param_error("formal argument cannot be a global variable", location.slice) + when :argument_formal_ivar + on_param_error("formal argument cannot be an instance variable", location.slice) + when :class_name, :module_name + on_class_name_error("class/module name must be CONSTANT", location.slice) + else + on_parse_error(error.message) + end + end + + nil + else + result.value.accept(self) + end + end + + ########################################################################## + # Visitor methods + ########################################################################## + + # alias foo bar + # ^^^^^^^^^^^^^ + def visit_alias_method_node(node) + new_name = visit(node.new_name) + old_name = visit(node.old_name) + + bounds(node.location) + on_alias(new_name, old_name) + end + + # alias $foo $bar + # ^^^^^^^^^^^^^^^ + def visit_alias_global_variable_node(node) + new_name = visit_alias_global_variable_node_value(node.new_name) + old_name = visit_alias_global_variable_node_value(node.old_name) + + bounds(node.location) + on_var_alias(new_name, old_name) + end + + # Visit one side of an alias global variable node. + private def visit_alias_global_variable_node_value(node) + bounds(node.location) + + case node + when BackReferenceReadNode + on_backref(node.slice) + when GlobalVariableReadNode + on_gvar(node.name.to_s) + else + raise + end + end + + # foo => bar | baz + # ^^^^^^^^^ + def visit_alternation_pattern_node(node) + left = visit_pattern_node(node.left) + right = visit_pattern_node(node.right) + + bounds(node.location) + on_binary(left, :|, right) + end + + # Visit a pattern within a pattern match. This is used to bypass the + # parenthesis node that can be used to wrap patterns. + private def visit_pattern_node(node) + if node.is_a?(ParenthesesNode) + visit(node.body) + else + visit(node) + end + end + + # a and b + # ^^^^^^^ + def visit_and_node(node) + left = visit(node.left) + right = visit(node.right) + + bounds(node.location) + on_binary(left, node.operator.to_sym, right) + end + + # [] + # ^^ + def visit_array_node(node) + case (opening = node.opening) + when /^%w/ + opening_loc = node.opening_loc + bounds(opening_loc) + on_qwords_beg(opening) + + elements = on_qwords_new + previous = nil + + node.elements.each do |element| + visit_words_sep(opening_loc, previous, element) + + bounds(element.location) + elements = on_qwords_add(elements, on_tstring_content(element.content)) + + previous = element + end + + bounds(node.closing_loc) + on_tstring_end(node.closing) + when /^%i/ + opening_loc = node.opening_loc + bounds(opening_loc) + on_qsymbols_beg(opening) + + elements = on_qsymbols_new + previous = nil + + node.elements.each do |element| + visit_words_sep(opening_loc, previous, element) + + bounds(element.location) + elements = on_qsymbols_add(elements, on_tstring_content(element.value)) + + previous = element + end + + bounds(node.closing_loc) + on_tstring_end(node.closing) + when /^%W/ + opening_loc = node.opening_loc + bounds(opening_loc) + on_words_beg(opening) + + elements = on_words_new + previous = nil + + node.elements.each do |element| + visit_words_sep(opening_loc, previous, element) + + bounds(element.location) + elements = + on_words_add( + elements, + if element.is_a?(StringNode) + on_word_add(on_word_new, on_tstring_content(element.content)) + else + element.parts.inject(on_word_new) do |word, part| + word_part = + if part.is_a?(StringNode) + bounds(part.location) + on_tstring_content(part.content) + else + visit(part) + end + + on_word_add(word, word_part) + end + end + ) + + previous = element + end + + bounds(node.closing_loc) + on_tstring_end(node.closing) + when /^%I/ + opening_loc = node.opening_loc + bounds(opening_loc) + on_symbols_beg(opening) + + elements = on_symbols_new + previous = nil + + node.elements.each do |element| + visit_words_sep(opening_loc, previous, element) + + bounds(element.location) + elements = + on_symbols_add( + elements, + if element.is_a?(SymbolNode) + on_word_add(on_word_new, on_tstring_content(element.value)) + else + element.parts.inject(on_word_new) do |word, part| + word_part = + if part.is_a?(StringNode) + bounds(part.location) + on_tstring_content(part.content) + else + visit(part) + end + + on_word_add(word, word_part) + end + end + ) + + previous = element + end + + bounds(node.closing_loc) + on_tstring_end(node.closing) + else + bounds(node.opening_loc) + on_lbracket(opening) + + elements = visit_arguments(node.elements) unless node.elements.empty? + + bounds(node.closing_loc) + on_rbracket(node.closing) + end + + bounds(node.location) + on_array(elements) + end + + # Dispatch a words_sep event that contains the space between the elements + # of list literals. + private def visit_words_sep(opening_loc, previous, current) + end_offset = (previous.nil? ? opening_loc : previous.location).end_offset + start_offset = current.location.start_offset + + if end_offset != start_offset + bounds(current.location.copy(start_offset: end_offset)) + on_words_sep(source.byteslice(end_offset...start_offset)) + end + end + + # Visit a list of elements, like the elements of an array or arguments. + private def visit_arguments(elements) + bounds(elements.first.location) + elements.inject(on_args_new) do |args, element| + arg = visit(element) + bounds(element.location) + + case element + when BlockArgumentNode + on_args_add_block(args, arg) + when SplatNode + on_args_add_star(args, arg) + else + on_args_add(args, arg) + end + end + end + + # foo => [bar] + # ^^^^^ + def visit_array_pattern_node(node) + constant = visit(node.constant) + requireds = visit_all(node.requireds) if node.requireds.any? + rest = + if (rest_node = node.rest).is_a?(SplatNode) + if rest_node.expression.nil? + bounds(rest_node.location) + on_var_field(nil) + else + visit(rest_node.expression) + end + end + + posts = visit_all(node.posts) if node.posts.any? + + bounds(node.location) + on_aryptn(constant, requireds, rest, posts) + end + + # foo(bar) + # ^^^ + def visit_arguments_node(node) + arguments, _ = visit_call_node_arguments(node, nil, false) + arguments + end + + # { a: 1 } + # ^^^^ + def visit_assoc_node(node) + key = visit(node.key) + value = visit(node.value) + + bounds(node.location) + on_assoc_new(key, value) + end + + # def foo(**); bar(**); end + # ^^ + # + # { **foo } + # ^^^^^ + def visit_assoc_splat_node(node) + value = visit(node.value) + + bounds(node.location) + on_assoc_splat(value) + end + + # $+ + # ^^ + def visit_back_reference_read_node(node) + bounds(node.location) + on_backref(node.slice) + end + + # begin end + # ^^^^^^^^^ + def visit_begin_node(node) + clauses = visit_begin_node_clauses(node.begin_keyword_loc, node, false) + + bounds(node.location) + on_begin(clauses) + end + + # Visit the clauses of a begin node to form an on_bodystmt call. + private def visit_begin_node_clauses(location, node, allow_newline) + statements = + if node.statements.nil? + on_stmts_add(on_stmts_new, on_void_stmt) + else + body = node.statements.body + body.unshift(nil) if void_stmt?(location, node.statements.body[0].location, allow_newline) + + bounds(node.statements.location) + visit_statements_node_body(body) + end + + rescue_clause = visit(node.rescue_clause) + else_clause = + unless (else_clause_node = node.else_clause).nil? + else_statements = + if else_clause_node.statements.nil? + [nil] + else + body = else_clause_node.statements.body + body.unshift(nil) if void_stmt?(else_clause_node.else_keyword_loc, else_clause_node.statements.body[0].location, allow_newline) + body + end + + bounds(else_clause_node.location) + visit_statements_node_body(else_statements) + end + ensure_clause = visit(node.ensure_clause) + + bounds(node.location) + on_bodystmt(statements, rescue_clause, else_clause, ensure_clause) + end + + # Visit the body of a structure that can have either a set of statements + # or statements wrapped in rescue/else/ensure. + private def visit_body_node(location, node, allow_newline = false) + case node + when nil + bounds(location) + on_bodystmt(visit_statements_node_body([nil]), nil, nil, nil) + when StatementsNode + body = [*node.body] + body.unshift(nil) if void_stmt?(location, body[0].location, allow_newline) + stmts = visit_statements_node_body(body) + + bounds(node.body.first.location) + on_bodystmt(stmts, nil, nil, nil) + when BeginNode + visit_begin_node_clauses(location, node, allow_newline) + else + raise + end + end + + # foo(&bar) + # ^^^^ + def visit_block_argument_node(node) + visit(node.expression) + end + + # foo { |; bar| } + # ^^^ + def visit_block_local_variable_node(node) + bounds(node.location) + on_ident(node.name.to_s) + end + + # Visit a BlockNode. + def visit_block_node(node) + braces = node.opening == "{" + parameters = visit(node.parameters) + + body = + case node.body + when nil + bounds(node.location) + stmts = on_stmts_add(on_stmts_new, on_void_stmt) + + bounds(node.location) + braces ? stmts : on_bodystmt(stmts, nil, nil, nil) + when StatementsNode + stmts = node.body.body + stmts.unshift(nil) if void_stmt?(node.parameters&.location || node.opening_loc, node.body.location, false) + stmts = visit_statements_node_body(stmts) + + bounds(node.body.location) + braces ? stmts : on_bodystmt(stmts, nil, nil, nil) + when BeginNode + visit_body_node(node.parameters&.location || node.opening_loc, node.body) + else + raise + end + + if braces + bounds(node.location) + on_brace_block(parameters, body) + else + bounds(node.location) + on_do_block(parameters, body) + end + end + + # def foo(&bar); end + # ^^^^ + def visit_block_parameter_node(node) + if node.name_loc.nil? + bounds(node.location) + on_blockarg(nil) + else + bounds(node.name_loc) + name = visit_token(node.name.to_s) + + bounds(node.location) + on_blockarg(name) + end + end + + # A block's parameters. + def visit_block_parameters_node(node) + parameters = + if node.parameters.nil? + on_params(nil, nil, nil, nil, nil, nil, nil) + else + visit(node.parameters) + end + + locals = + if node.locals.any? + visit_all(node.locals) + else + false + end + + bounds(node.location) + on_block_var(parameters, locals) + end + + # break + # ^^^^^ + # + # break foo + # ^^^^^^^^^ + def visit_break_node(node) + if node.arguments.nil? + bounds(node.location) + on_break(on_args_new) + else + arguments = visit(node.arguments) + + bounds(node.location) + on_break(arguments) + end + end + + # foo + # ^^^ + # + # foo.bar + # ^^^^^^^ + # + # foo.bar() {} + # ^^^^^^^^^^^^ + def visit_call_node(node) + if node.call_operator_loc.nil? + case node.name + when :[] + receiver = visit(node.receiver) + arguments, block = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc)) + + bounds(node.location) + call = on_aref(receiver, arguments) + + if block.nil? + call + else + bounds(node.location) + on_method_add_block(call, block) + end + when :[]= + receiver = visit(node.receiver) + + *arguments, last_argument = node.arguments.arguments + arguments << node.block if !node.block.nil? + + arguments = + if arguments.any? + args = visit_arguments(arguments) + + if !node.block.nil? + args + else + bounds(arguments.first.location) + on_args_add_block(args, false) + end + end + + bounds(node.location) + call = on_aref_field(receiver, arguments) + value = visit_write_value(last_argument) + + bounds(last_argument.location) + on_assign(call, value) + when :-@, :+@, :~ + receiver = visit(node.receiver) + + bounds(node.location) + on_unary(node.name, receiver) + when :! + if node.message == "not" + receiver = + if !node.receiver.is_a?(ParenthesesNode) || !node.receiver.body.nil? + visit(node.receiver) + end + + bounds(node.location) + on_unary(:not, receiver) + else + receiver = visit(node.receiver) + + bounds(node.location) + on_unary(:!, receiver) + end + when *BINARY_OPERATORS + receiver = visit(node.receiver) + value = visit(node.arguments.arguments.first) + + bounds(node.location) + on_binary(receiver, node.name, value) + else + bounds(node.message_loc) + message = visit_token(node.message, false) + + if node.variable_call? + on_vcall(message) + else + arguments, block = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc || node.location)) + call = + if node.opening_loc.nil? && arguments&.any? + bounds(node.location) + on_command(message, arguments) + elsif !node.opening_loc.nil? + bounds(node.location) + on_method_add_arg(on_fcall(message), on_arg_paren(arguments)) + else + bounds(node.location) + on_method_add_arg(on_fcall(message), on_args_new) + end + + if block.nil? + call + else + bounds(node.block.location) + on_method_add_block(call, block) + end + end + end + else + receiver = visit(node.receiver) + + bounds(node.call_operator_loc) + call_operator = visit_token(node.call_operator) + + message = + if node.message_loc.nil? + :call + else + bounds(node.message_loc) + visit_token(node.message, false) + end + + if node.name.end_with?("=") && !node.message.end_with?("=") && !node.arguments.nil? && node.block.nil? + value = visit_write_value(node.arguments.arguments.first) + + bounds(node.location) + on_assign(on_field(receiver, call_operator, message), value) + else + arguments, block = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc || node.location)) + call = + if node.opening_loc.nil? + bounds(node.location) + + if node.arguments.nil? && !node.block.is_a?(BlockArgumentNode) + on_call(receiver, call_operator, message) + else + on_command_call(receiver, call_operator, message, arguments) + end + else + bounds(node.opening_loc) + arguments = on_arg_paren(arguments) + + bounds(node.location) + on_method_add_arg(on_call(receiver, call_operator, message), arguments) + end + + if block.nil? + call + else + bounds(node.block.location) + on_method_add_block(call, block) + end + end + end + end + + # Visit the arguments and block of a call node and return the arguments + # and block as they should be used. + private def visit_call_node_arguments(arguments_node, block_node, trailing_comma) + arguments = arguments_node&.arguments || [] + block = block_node + + if block.is_a?(BlockArgumentNode) + arguments << block + block = nil + end + + [ + if arguments.length == 1 && arguments.first.is_a?(ForwardingArgumentsNode) + visit(arguments.first) + elsif arguments.any? + args = visit_arguments(arguments) + + if block_node.is_a?(BlockArgumentNode) || arguments.last.is_a?(ForwardingArgumentsNode) || command?(arguments.last) || trailing_comma + args + else + bounds(arguments.first.location) + on_args_add_block(args, false) + end + end, + visit(block) + ] + end + + # Returns true if the given node is a command node. + private def command?(node) + node.is_a?(CallNode) && + node.opening_loc.nil? && + (!node.arguments.nil? || node.block.is_a?(BlockArgumentNode)) && + !BINARY_OPERATORS.include?(node.name) + end + + # foo.bar += baz + # ^^^^^^^^^^^^^^^ + def visit_call_operator_write_node(node) + receiver = visit(node.receiver) + + bounds(node.call_operator_loc) + call_operator = visit_token(node.call_operator) + + bounds(node.message_loc) + message = visit_token(node.message) + + bounds(node.location) + target = on_field(receiver, call_operator, message) + + bounds(node.binary_operator_loc) + operator = on_op("#{node.binary_operator}=") + value = visit_write_value(node.value) + + bounds(node.location) + on_opassign(target, operator, value) + end + + # foo.bar &&= baz + # ^^^^^^^^^^^^^^^ + def visit_call_and_write_node(node) + receiver = visit(node.receiver) + + bounds(node.call_operator_loc) + call_operator = visit_token(node.call_operator) + + bounds(node.message_loc) + message = visit_token(node.message) + + bounds(node.location) + target = on_field(receiver, call_operator, message) + + bounds(node.operator_loc) + operator = on_op("&&=") + value = visit_write_value(node.value) + + bounds(node.location) + on_opassign(target, operator, value) + end + + # foo.bar ||= baz + # ^^^^^^^^^^^^^^^ + def visit_call_or_write_node(node) + receiver = visit(node.receiver) + + bounds(node.call_operator_loc) + call_operator = visit_token(node.call_operator) + + bounds(node.message_loc) + message = visit_token(node.message) + + bounds(node.location) + target = on_field(receiver, call_operator, message) + + bounds(node.operator_loc) + operator = on_op("||=") + value = visit_write_value(node.value) + + bounds(node.location) + on_opassign(target, operator, value) + end + + # foo.bar, = 1 + # ^^^^^^^ + def visit_call_target_node(node) + if node.call_operator == "::" + receiver = visit(node.receiver) + + bounds(node.message_loc) + message = visit_token(node.message) + + bounds(node.location) + on_const_path_field(receiver, message) + else + receiver = visit(node.receiver) + + bounds(node.call_operator_loc) + call_operator = visit_token(node.call_operator) + + bounds(node.message_loc) + message = visit_token(node.message) + + bounds(node.location) + on_field(receiver, call_operator, message) + end + end + + # foo => bar => baz + # ^^^^^^^^^^ + def visit_capture_pattern_node(node) + value = visit(node.value) + target = visit(node.target) + + bounds(node.location) + on_binary(value, :"=>", target) + end + + # case foo; when bar; end + # ^^^^^^^^^^^^^^^^^^^^^^^ + def visit_case_node(node) + predicate = visit(node.predicate) + clauses = + node.conditions.reverse_each.inject(visit(node.else_clause)) do |current, condition| + on_when(*visit(condition), current) + end + + bounds(node.location) + on_case(predicate, clauses) + end + + # case foo; in bar; end + # ^^^^^^^^^^^^^^^^^^^^^ + def visit_case_match_node(node) + predicate = visit(node.predicate) + clauses = + node.conditions.reverse_each.inject(visit(node.else_clause)) do |current, condition| + on_in(*visit(condition), current) + end + + bounds(node.location) + on_case(predicate, clauses) + end + + # class Foo; end + # ^^^^^^^^^^^^^^ + def visit_class_node(node) + constant_path = + if node.constant_path.is_a?(ConstantReadNode) + bounds(node.constant_path.location) + on_const_ref(on_const(node.constant_path.name.to_s)) + else + visit(node.constant_path) + end + + superclass = visit(node.superclass) + bodystmt = visit_body_node(node.superclass&.location || node.constant_path.location, node.body, node.superclass.nil?) + + bounds(node.location) + on_class(constant_path, superclass, bodystmt) + end + + # @@foo + # ^^^^^ + def visit_class_variable_read_node(node) + bounds(node.location) + on_var_ref(on_cvar(node.slice)) + end + + # @@foo = 1 + # ^^^^^^^^^ + # + # @@foo, @@bar = 1 + # ^^^^^ ^^^^^ + def visit_class_variable_write_node(node) + bounds(node.name_loc) + target = on_var_field(on_cvar(node.name.to_s)) + value = visit_write_value(node.value) + + bounds(node.location) + on_assign(target, value) + end + + # @@foo += bar + # ^^^^^^^^^^^^ + def visit_class_variable_operator_write_node(node) + bounds(node.name_loc) + target = on_var_field(on_cvar(node.name.to_s)) + + bounds(node.binary_operator_loc) + operator = on_op("#{node.binary_operator}=") + value = visit_write_value(node.value) + + bounds(node.location) + on_opassign(target, operator, value) + end + + # @@foo &&= bar + # ^^^^^^^^^^^^^ + def visit_class_variable_and_write_node(node) + bounds(node.name_loc) + target = on_var_field(on_cvar(node.name.to_s)) + + bounds(node.operator_loc) + operator = on_op("&&=") + value = visit_write_value(node.value) + + bounds(node.location) + on_opassign(target, operator, value) + end + + # @@foo ||= bar + # ^^^^^^^^^^^^^ + def visit_class_variable_or_write_node(node) + bounds(node.name_loc) + target = on_var_field(on_cvar(node.name.to_s)) + + bounds(node.operator_loc) + operator = on_op("||=") + value = visit_write_value(node.value) + + bounds(node.location) + on_opassign(target, operator, value) + end + + # @@foo, = bar + # ^^^^^ + def visit_class_variable_target_node(node) + bounds(node.location) + on_var_field(on_cvar(node.name.to_s)) + end + + # Foo + # ^^^ + def visit_constant_read_node(node) + bounds(node.location) + on_var_ref(on_const(node.name.to_s)) + end + + # Foo = 1 + # ^^^^^^^ + # + # Foo, Bar = 1 + # ^^^ ^^^ + def visit_constant_write_node(node) + bounds(node.name_loc) + target = on_var_field(on_const(node.name.to_s)) + value = visit_write_value(node.value) + + bounds(node.location) + on_assign(target, value) + end + + # Foo += bar + # ^^^^^^^^^^^ + def visit_constant_operator_write_node(node) + bounds(node.name_loc) + target = on_var_field(on_const(node.name.to_s)) + + bounds(node.binary_operator_loc) + operator = on_op("#{node.binary_operator}=") + value = visit_write_value(node.value) + + bounds(node.location) + on_opassign(target, operator, value) + end + + # Foo &&= bar + # ^^^^^^^^^^^^ + def visit_constant_and_write_node(node) + bounds(node.name_loc) + target = on_var_field(on_const(node.name.to_s)) + + bounds(node.operator_loc) + operator = on_op("&&=") + value = visit_write_value(node.value) + + bounds(node.location) + on_opassign(target, operator, value) + end + + # Foo ||= bar + # ^^^^^^^^^^^^ + def visit_constant_or_write_node(node) + bounds(node.name_loc) + target = on_var_field(on_const(node.name.to_s)) + + bounds(node.operator_loc) + operator = on_op("||=") + value = visit_write_value(node.value) + + bounds(node.location) + on_opassign(target, operator, value) + end + + # Foo, = bar + # ^^^ + def visit_constant_target_node(node) + bounds(node.location) + on_var_field(on_const(node.name.to_s)) + end + + # Foo::Bar + # ^^^^^^^^ + def visit_constant_path_node(node) + if node.parent.nil? + bounds(node.name_loc) + child = on_const(node.name.to_s) + + bounds(node.location) + on_top_const_ref(child) + else + parent = visit(node.parent) + + bounds(node.name_loc) + child = on_const(node.name.to_s) + + bounds(node.location) + on_const_path_ref(parent, child) + end + end + + # Foo::Bar = 1 + # ^^^^^^^^^^^^ + # + # Foo::Foo, Bar::Bar = 1 + # ^^^^^^^^ ^^^^^^^^ + def visit_constant_path_write_node(node) + target = visit_constant_path_write_node_target(node.target) + value = visit_write_value(node.value) + + bounds(node.location) + on_assign(target, value) + end + + # Visit a constant path that is part of a write node. + private def visit_constant_path_write_node_target(node) + if node.parent.nil? + bounds(node.name_loc) + child = on_const(node.name.to_s) + + bounds(node.location) + on_top_const_field(child) + else + parent = visit(node.parent) + + bounds(node.name_loc) + child = on_const(node.name.to_s) + + bounds(node.location) + on_const_path_field(parent, child) + end + end + + # Foo::Bar += baz + # ^^^^^^^^^^^^^^^ + def visit_constant_path_operator_write_node(node) + target = visit_constant_path_write_node_target(node.target) + value = visit(node.value) + + bounds(node.binary_operator_loc) + operator = on_op("#{node.binary_operator}=") + value = visit_write_value(node.value) + + bounds(node.location) + on_opassign(target, operator, value) + end + + # Foo::Bar &&= baz + # ^^^^^^^^^^^^^^^^ + def visit_constant_path_and_write_node(node) + target = visit_constant_path_write_node_target(node.target) + value = visit(node.value) + + bounds(node.operator_loc) + operator = on_op("&&=") + value = visit_write_value(node.value) + + bounds(node.location) + on_opassign(target, operator, value) + end + + # Foo::Bar ||= baz + # ^^^^^^^^^^^^^^^^ + def visit_constant_path_or_write_node(node) + target = visit_constant_path_write_node_target(node.target) + value = visit(node.value) + + bounds(node.operator_loc) + operator = on_op("||=") + value = visit_write_value(node.value) + + bounds(node.location) + on_opassign(target, operator, value) + end + + # Foo::Bar, = baz + # ^^^^^^^^ + def visit_constant_path_target_node(node) + visit_constant_path_write_node_target(node) + end + + # def foo; end + # ^^^^^^^^^^^^ + # + # def self.foo; end + # ^^^^^^^^^^^^^^^^^ + def visit_def_node(node) + receiver = visit(node.receiver) + operator = + if !node.operator_loc.nil? + bounds(node.operator_loc) + visit_token(node.operator) + end + + bounds(node.name_loc) + name = visit_token(node.name_loc.slice) + + parameters = + if node.parameters.nil? + bounds(node.location) + on_params(nil, nil, nil, nil, nil, nil, nil) + else + visit(node.parameters) + end + + if !node.lparen_loc.nil? + bounds(node.lparen_loc) + parameters = on_paren(parameters) + end + + bodystmt = + if node.equal_loc.nil? + visit_body_node(node.rparen_loc || node.end_keyword_loc, node.body) + else + body = visit(node.body.body.first) + + bounds(node.body.location) + on_bodystmt(body, nil, nil, nil) + end + + bounds(node.location) + if receiver.nil? + on_def(name, parameters, bodystmt) + else + on_defs(receiver, operator, name, parameters, bodystmt) + end + end + + # defined? a + # ^^^^^^^^^^ + # + # defined?(a) + # ^^^^^^^^^^^ + def visit_defined_node(node) + bounds(node.location) + on_defined(visit(node.value)) + end + + # if foo then bar else baz end + # ^^^^^^^^^^^^ + def visit_else_node(node) + statements = + if node.statements.nil? + [nil] + else + body = node.statements.body + body.unshift(nil) if void_stmt?(node.else_keyword_loc, node.statements.body[0].location, false) + body + end + + bounds(node.location) + on_else(visit_statements_node_body(statements)) + end + + # "foo #{bar}" + # ^^^^^^ + def visit_embedded_statements_node(node) + bounds(node.opening_loc) + on_embexpr_beg(node.opening) + + statements = + if node.statements.nil? + bounds(node.location) + on_stmts_add(on_stmts_new, on_void_stmt) + else + visit(node.statements) + end + + bounds(node.closing_loc) + on_embexpr_end(node.closing) + + bounds(node.location) + on_string_embexpr(statements) + end + + # "foo #@bar" + # ^^^^^ + def visit_embedded_variable_node(node) + bounds(node.operator_loc) + on_embvar(node.operator) + + variable = visit(node.variable) + + bounds(node.location) + on_string_dvar(variable) + end + + # Visit an EnsureNode node. + def visit_ensure_node(node) + statements = + if node.statements.nil? + [nil] + else + body = node.statements.body + body.unshift(nil) if void_stmt?(node.ensure_keyword_loc, body[0].location, false) + body + end + + statements = visit_statements_node_body(statements) + + bounds(node.location) + on_ensure(statements) + end + + # false + # ^^^^^ + def visit_false_node(node) + bounds(node.location) + on_var_ref(on_kw("false")) + end + + # foo => [*, bar, *] + # ^^^^^^^^^^^ + def visit_find_pattern_node(node) + constant = visit(node.constant) + left = + if node.left.expression.nil? + bounds(node.left.location) + on_var_field(nil) + else + visit(node.left.expression) + end + + requireds = visit_all(node.requireds) if node.requireds.any? + right = + if node.right.expression.nil? + bounds(node.right.location) + on_var_field(nil) + else + visit(node.right.expression) + end + + bounds(node.location) + on_fndptn(constant, left, requireds, right) + end + + # if foo .. bar; end + # ^^^^^^^^^^ + def visit_flip_flop_node(node) + left = visit(node.left) + right = visit(node.right) + + bounds(node.location) + if node.exclude_end? + on_dot3(left, right) + else + on_dot2(left, right) + end + end + + # 1.0 + # ^^^ + def visit_float_node(node) + visit_number_node(node) { |text| on_float(text) } + end + + # for foo in bar do end + # ^^^^^^^^^^^^^^^^^^^^^ + def visit_for_node(node) + index = visit(node.index) + collection = visit(node.collection) + statements = + if node.statements.nil? + bounds(node.location) + on_stmts_add(on_stmts_new, on_void_stmt) + else + visit(node.statements) + end + + bounds(node.location) + on_for(index, collection, statements) + end + + # def foo(...); bar(...); end + # ^^^ + def visit_forwarding_arguments_node(node) + bounds(node.location) + on_args_forward + end + + # def foo(...); end + # ^^^ + def visit_forwarding_parameter_node(node) + bounds(node.location) + on_args_forward + end + + # super + # ^^^^^ + # + # super {} + # ^^^^^^^^ + def visit_forwarding_super_node(node) + if node.block.nil? + bounds(node.location) + on_zsuper + else + block = visit(node.block) + + bounds(node.location) + on_method_add_block(on_zsuper, block) + end + end + + # $foo + # ^^^^ + def visit_global_variable_read_node(node) + bounds(node.location) + on_var_ref(on_gvar(node.name.to_s)) + end + + # $foo = 1 + # ^^^^^^^^ + # + # $foo, $bar = 1 + # ^^^^ ^^^^ + def visit_global_variable_write_node(node) + bounds(node.name_loc) + target = on_var_field(on_gvar(node.name.to_s)) + value = visit_write_value(node.value) + + bounds(node.location) + on_assign(target, value) + end + + # $foo += bar + # ^^^^^^^^^^^ + def visit_global_variable_operator_write_node(node) + bounds(node.name_loc) + target = on_var_field(on_gvar(node.name.to_s)) + + bounds(node.binary_operator_loc) + operator = on_op("#{node.binary_operator}=") + value = visit_write_value(node.value) + + bounds(node.location) + on_opassign(target, operator, value) + end + + # $foo &&= bar + # ^^^^^^^^^^^^ + def visit_global_variable_and_write_node(node) + bounds(node.name_loc) + target = on_var_field(on_gvar(node.name.to_s)) + + bounds(node.operator_loc) + operator = on_op("&&=") + value = visit_write_value(node.value) + + bounds(node.location) + on_opassign(target, operator, value) + end + + # $foo ||= bar + # ^^^^^^^^^^^^ + def visit_global_variable_or_write_node(node) + bounds(node.name_loc) + target = on_var_field(on_gvar(node.name.to_s)) + + bounds(node.operator_loc) + operator = on_op("||=") + value = visit_write_value(node.value) + + bounds(node.location) + on_opassign(target, operator, value) + end + + # $foo, = bar + # ^^^^ + def visit_global_variable_target_node(node) + bounds(node.location) + on_var_field(on_gvar(node.name.to_s)) + end + + # {} + # ^^ + def visit_hash_node(node) + elements = + if node.elements.any? + args = visit_all(node.elements) + + bounds(node.elements.first.location) + on_assoclist_from_args(args) + end + + bounds(node.location) + on_hash(elements) + end + + # foo => {} + # ^^ + def visit_hash_pattern_node(node) + constant = visit(node.constant) + elements = + if node.elements.any? || !node.rest.nil? + node.elements.map do |element| + [ + if (key = element.key).opening_loc.nil? + visit(key) + else + bounds(key.value_loc) + if (value = key.value).empty? + on_string_content + else + on_string_add(on_string_content, on_tstring_content(value)) + end + end, + visit(element.value) + ] + end + end + + rest = + case node.rest + when AssocSplatNode + visit(node.rest.value) + when NoKeywordsParameterNode + bounds(node.rest.location) + on_var_field(visit(node.rest)) + end + + bounds(node.location) + on_hshptn(constant, elements, rest) + end + + # if foo then bar end + # ^^^^^^^^^^^^^^^^^^^ + # + # bar if foo + # ^^^^^^^^^^ + # + # foo ? bar : baz + # ^^^^^^^^^^^^^^^ + def visit_if_node(node) + if node.then_keyword == "?" + predicate = visit(node.predicate) + truthy = visit(node.statements.body.first) + falsy = visit(node.subsequent.statements.body.first) + + bounds(node.location) + on_ifop(predicate, truthy, falsy) + elsif node.statements.nil? || (node.predicate.location.start_offset < node.statements.location.start_offset) + predicate = visit(node.predicate) + statements = + if node.statements.nil? + bounds(node.location) + on_stmts_add(on_stmts_new, on_void_stmt) + else + visit(node.statements) + end + subsequent = visit(node.subsequent) + + bounds(node.location) + if node.if_keyword == "if" + on_if(predicate, statements, subsequent) + else + on_elsif(predicate, statements, subsequent) + end + else + statements = visit(node.statements.body.first) + predicate = visit(node.predicate) + + bounds(node.location) + on_if_mod(predicate, statements) + end + end + + # 1i + # ^^ + def visit_imaginary_node(node) + visit_number_node(node) { |text| on_imaginary(text) } + end + + # { foo: } + # ^^^^ + def visit_implicit_node(node) + end + + # foo { |bar,| } + # ^ + def visit_implicit_rest_node(node) + bounds(node.location) + on_excessed_comma + end + + # case foo; in bar; end + # ^^^^^^^^^^^^^^^^^^^^^ + def visit_in_node(node) + # This is a special case where we're not going to call on_in directly + # because we don't have access to the subsequent. Instead, we'll return + # the component parts and let the parent node handle it. + pattern = visit_pattern_node(node.pattern) + statements = + if node.statements.nil? + bounds(node.location) + on_stmts_add(on_stmts_new, on_void_stmt) + else + visit(node.statements) + end + + [pattern, statements] + end + + # foo[bar] += baz + # ^^^^^^^^^^^^^^^ + def visit_index_operator_write_node(node) + receiver = visit(node.receiver) + arguments, _ = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc)) + + bounds(node.location) + target = on_aref_field(receiver, arguments) + + bounds(node.binary_operator_loc) + operator = on_op("#{node.binary_operator}=") + value = visit_write_value(node.value) + + bounds(node.location) + on_opassign(target, operator, value) + end + + # foo[bar] &&= baz + # ^^^^^^^^^^^^^^^^ + def visit_index_and_write_node(node) + receiver = visit(node.receiver) + arguments, _ = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc)) + + bounds(node.location) + target = on_aref_field(receiver, arguments) + + bounds(node.operator_loc) + operator = on_op("&&=") + value = visit_write_value(node.value) + + bounds(node.location) + on_opassign(target, operator, value) + end + + # foo[bar] ||= baz + # ^^^^^^^^^^^^^^^^ + def visit_index_or_write_node(node) + receiver = visit(node.receiver) + arguments, _ = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc)) + + bounds(node.location) + target = on_aref_field(receiver, arguments) + + bounds(node.operator_loc) + operator = on_op("||=") + value = visit_write_value(node.value) + + bounds(node.location) + on_opassign(target, operator, value) + end + + # foo[bar], = 1 + # ^^^^^^^^ + def visit_index_target_node(node) + receiver = visit(node.receiver) + arguments, _ = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc)) + + bounds(node.location) + on_aref_field(receiver, arguments) + end + + # @foo + # ^^^^ + def visit_instance_variable_read_node(node) + bounds(node.location) + on_var_ref(on_ivar(node.name.to_s)) + end + + # @foo = 1 + # ^^^^^^^^ + def visit_instance_variable_write_node(node) + bounds(node.name_loc) + target = on_var_field(on_ivar(node.name.to_s)) + value = visit_write_value(node.value) + + bounds(node.location) + on_assign(target, value) + end + + # @foo += bar + # ^^^^^^^^^^^ + def visit_instance_variable_operator_write_node(node) + bounds(node.name_loc) + target = on_var_field(on_ivar(node.name.to_s)) + + bounds(node.binary_operator_loc) + operator = on_op("#{node.binary_operator}=") + value = visit_write_value(node.value) + + bounds(node.location) + on_opassign(target, operator, value) + end + + # @foo &&= bar + # ^^^^^^^^^^^^ + def visit_instance_variable_and_write_node(node) + bounds(node.name_loc) + target = on_var_field(on_ivar(node.name.to_s)) + + bounds(node.operator_loc) + operator = on_op("&&=") + value = visit_write_value(node.value) + + bounds(node.location) + on_opassign(target, operator, value) + end + + # @foo ||= bar + # ^^^^^^^^^^^^ + def visit_instance_variable_or_write_node(node) + bounds(node.name_loc) + target = on_var_field(on_ivar(node.name.to_s)) + + bounds(node.operator_loc) + operator = on_op("||=") + value = visit_write_value(node.value) + + bounds(node.location) + on_opassign(target, operator, value) + end + + # @foo, = bar + # ^^^^ + def visit_instance_variable_target_node(node) + bounds(node.location) + on_var_field(on_ivar(node.name.to_s)) + end + + # 1 + # ^ + def visit_integer_node(node) + visit_number_node(node) { |text| on_int(text) } + end + + # if /foo #{bar}/ then end + # ^^^^^^^^^^^^ + def visit_interpolated_match_last_line_node(node) + bounds(node.opening_loc) + on_regexp_beg(node.opening) + + bounds(node.parts.first.location) + parts = + node.parts.inject(on_regexp_new) do |content, part| + on_regexp_add(content, visit_string_content(part)) + end + + bounds(node.closing_loc) + closing = on_regexp_end(node.closing) + + bounds(node.location) + on_regexp_literal(parts, closing) + end + + # /foo #{bar}/ + # ^^^^^^^^^^^^ + def visit_interpolated_regular_expression_node(node) + bounds(node.opening_loc) + on_regexp_beg(node.opening) + + bounds(node.parts.first.location) + parts = + node.parts.inject(on_regexp_new) do |content, part| + on_regexp_add(content, visit_string_content(part)) + end + + bounds(node.closing_loc) + closing = on_regexp_end(node.closing) + + bounds(node.location) + on_regexp_literal(parts, closing) + end + + # "foo #{bar}" + # ^^^^^^^^^^^^ + def visit_interpolated_string_node(node) + if node.opening&.start_with?("<<~") + heredoc = visit_heredoc_string_node(node) + + bounds(node.location) + on_string_literal(heredoc) + elsif !node.heredoc? && node.parts.length > 1 && node.parts.any? { |part| (part.is_a?(StringNode) || part.is_a?(InterpolatedStringNode)) && !part.opening_loc.nil? } + first, *rest = node.parts + rest.inject(visit(first)) do |content, part| + concat = visit(part) + + bounds(part.location) + on_string_concat(content, concat) + end + else + bounds(node.parts.first.location) + parts = + node.parts.inject(on_string_content) do |content, part| + on_string_add(content, visit_string_content(part)) + end + + bounds(node.location) + on_string_literal(parts) + end + end + + # :"foo #{bar}" + # ^^^^^^^^^^^^^ + def visit_interpolated_symbol_node(node) + bounds(node.parts.first.location) + parts = + node.parts.inject(on_string_content) do |content, part| + on_string_add(content, visit_string_content(part)) + end + + bounds(node.location) + on_dyna_symbol(parts) + end + + # `foo #{bar}` + # ^^^^^^^^^^^^ + def visit_interpolated_x_string_node(node) + if node.opening.start_with?("<<~") + heredoc = visit_heredoc_x_string_node(node) + + bounds(node.location) + on_xstring_literal(heredoc) + else + bounds(node.parts.first.location) + parts = + node.parts.inject(on_xstring_new) do |content, part| + on_xstring_add(content, visit_string_content(part)) + end + + bounds(node.location) + on_xstring_literal(parts) + end + end + + # Visit an individual part of a string-like node. + private def visit_string_content(part) + if part.is_a?(StringNode) + bounds(part.content_loc) + on_tstring_content(part.content) + else + visit(part) + end + end + + # -> { it } + # ^^ + def visit_it_local_variable_read_node(node) + bounds(node.location) + on_vcall(on_ident(node.slice)) + end + + # -> { it } + # ^^^^^^^^^ + def visit_it_parameters_node(node) + end + + # foo(bar: baz) + # ^^^^^^^^ + def visit_keyword_hash_node(node) + elements = visit_all(node.elements) + + bounds(node.location) + on_bare_assoc_hash(elements) + end + + # def foo(**bar); end + # ^^^^^ + # + # def foo(**); end + # ^^ + def visit_keyword_rest_parameter_node(node) + if node.name_loc.nil? + bounds(node.location) + on_kwrest_param(nil) + else + bounds(node.name_loc) + name = on_ident(node.name.to_s) + + bounds(node.location) + on_kwrest_param(name) + end + end + + # -> {} + def visit_lambda_node(node) + bounds(node.operator_loc) + on_tlambda(node.operator) + + parameters = + if node.parameters.is_a?(BlockParametersNode) + # Ripper does not track block-locals within lambdas, so we skip + # directly to the parameters here. + params = + if node.parameters.parameters.nil? + bounds(node.location) + on_params(nil, nil, nil, nil, nil, nil, nil) + else + visit(node.parameters.parameters) + end + + if node.parameters.opening_loc.nil? + params + else + bounds(node.parameters.opening_loc) + on_paren(params) + end + else + bounds(node.location) + on_params(nil, nil, nil, nil, nil, nil, nil) + end + + braces = node.opening == "{" + if braces + bounds(node.opening_loc) + on_tlambeg(node.opening) + end + + body = + case node.body + when nil + bounds(node.location) + stmts = on_stmts_add(on_stmts_new, on_void_stmt) + + bounds(node.location) + braces ? stmts : on_bodystmt(stmts, nil, nil, nil) + when StatementsNode + stmts = node.body.body + stmts.unshift(nil) if void_stmt?(node.parameters&.location || node.opening_loc, node.body.location, false) + stmts = visit_statements_node_body(stmts) + + bounds(node.body.location) + braces ? stmts : on_bodystmt(stmts, nil, nil, nil) + when BeginNode + visit_body_node(node.opening_loc, node.body) + else + raise + end + + bounds(node.location) + on_lambda(parameters, body) + end + + # foo + # ^^^ + def visit_local_variable_read_node(node) + bounds(node.location) + on_var_ref(on_ident(node.slice)) + end + + # foo = 1 + # ^^^^^^^ + def visit_local_variable_write_node(node) + bounds(node.name_loc) + target = on_var_field(on_ident(node.name_loc.slice)) + value = visit_write_value(node.value) + + bounds(node.location) + on_assign(target, value) + end + + # foo += bar + # ^^^^^^^^^^ + def visit_local_variable_operator_write_node(node) + bounds(node.name_loc) + target = on_var_field(on_ident(node.name_loc.slice)) + + bounds(node.binary_operator_loc) + operator = on_op("#{node.binary_operator}=") + value = visit_write_value(node.value) + + bounds(node.location) + on_opassign(target, operator, value) + end + + # foo &&= bar + # ^^^^^^^^^^^ + def visit_local_variable_and_write_node(node) + bounds(node.name_loc) + target = on_var_field(on_ident(node.name_loc.slice)) + + bounds(node.operator_loc) + operator = on_op("&&=") + value = visit_write_value(node.value) + + bounds(node.location) + on_opassign(target, operator, value) + end + + # foo ||= bar + # ^^^^^^^^^^^ + def visit_local_variable_or_write_node(node) + bounds(node.name_loc) + target = on_var_field(on_ident(node.name_loc.slice)) + + bounds(node.operator_loc) + operator = on_op("||=") + value = visit_write_value(node.value) + + bounds(node.location) + on_opassign(target, operator, value) + end + + # foo, = bar + # ^^^ + def visit_local_variable_target_node(node) + bounds(node.location) + on_var_field(on_ident(node.name.to_s)) + end + + # if /foo/ then end + # ^^^^^ + def visit_match_last_line_node(node) + bounds(node.opening_loc) + on_regexp_beg(node.opening) + + bounds(node.content_loc) + tstring_content = on_tstring_content(node.content) + + bounds(node.closing_loc) + closing = on_regexp_end(node.closing) + + on_regexp_literal(on_regexp_add(on_regexp_new, tstring_content), closing) + end + + # foo in bar + # ^^^^^^^^^^ + def visit_match_predicate_node(node) + value = visit(node.value) + pattern = on_in(visit_pattern_node(node.pattern), nil, nil) + + on_case(value, pattern) + end + + # foo => bar + # ^^^^^^^^^^ + def visit_match_required_node(node) + value = visit(node.value) + pattern = on_in(visit_pattern_node(node.pattern), nil, nil) + + on_case(value, pattern) + end + + # /(?foo)/ =~ bar + # ^^^^^^^^^^^^^^^^^^^^ + def visit_match_write_node(node) + visit(node.call) + end + + # A node that is missing from the syntax tree. This is only used in the + # case of a syntax error. + def visit_missing_node(node) + raise "Cannot visit missing nodes directly." + end + + # module Foo; end + # ^^^^^^^^^^^^^^^ + def visit_module_node(node) + constant_path = + if node.constant_path.is_a?(ConstantReadNode) + bounds(node.constant_path.location) + on_const_ref(on_const(node.constant_path.name.to_s)) + else + visit(node.constant_path) + end + + bodystmt = visit_body_node(node.constant_path.location, node.body, true) + + bounds(node.location) + on_module(constant_path, bodystmt) + end + + # (foo, bar), bar = qux + # ^^^^^^^^^^ + def visit_multi_target_node(node) + bounds(node.location) + targets = visit_multi_target_node_targets(node.lefts, node.rest, node.rights, true) + + if node.lparen_loc.nil? + targets + else + bounds(node.lparen_loc) + on_mlhs_paren(targets) + end + end + + # Visit the targets of a multi-target node. + private def visit_multi_target_node_targets(lefts, rest, rights, skippable) + if skippable && lefts.length == 1 && lefts.first.is_a?(MultiTargetNode) && rest.nil? && rights.empty? + return visit(lefts.first) + end + + mlhs = on_mlhs_new + + lefts.each do |left| + bounds(left.location) + mlhs = on_mlhs_add(mlhs, visit(left)) + end + + case rest + when nil + # do nothing + when ImplicitRestNode + # these do not get put into the generated tree + bounds(rest.location) + on_excessed_comma + else + bounds(rest.location) + mlhs = on_mlhs_add_star(mlhs, visit(rest)) + end + + if rights.any? + bounds(rights.first.location) + post = on_mlhs_new + + rights.each do |right| + bounds(right.location) + post = on_mlhs_add(post, visit(right)) + end + + mlhs = on_mlhs_add_post(mlhs, post) + end + + mlhs + end + + # foo, bar = baz + # ^^^^^^^^^^^^^^ + def visit_multi_write_node(node) + bounds(node.location) + targets = visit_multi_target_node_targets(node.lefts, node.rest, node.rights, true) + + unless node.lparen_loc.nil? + bounds(node.lparen_loc) + targets = on_mlhs_paren(targets) + end + + value = visit_write_value(node.value) + + bounds(node.location) + on_massign(targets, value) + end + + # next + # ^^^^ + # + # next foo + # ^^^^^^^^ + def visit_next_node(node) + if node.arguments.nil? + bounds(node.location) + on_next(on_args_new) + else + arguments = visit(node.arguments) + + bounds(node.location) + on_next(arguments) + end + end + + # nil + # ^^^ + def visit_nil_node(node) + bounds(node.location) + on_var_ref(on_kw("nil")) + end + + # def foo(**nil); end + # ^^^^^ + def visit_no_keywords_parameter_node(node) + bounds(node.location) + on_nokw_param(nil) + + :nil + end + + # -> { _1 + _2 } + # ^^^^^^^^^^^^^^ + def visit_numbered_parameters_node(node) + end + + # $1 + # ^^ + def visit_numbered_reference_read_node(node) + bounds(node.location) + on_backref(node.slice) + end + + # def foo(bar: baz); end + # ^^^^^^^^ + def visit_optional_keyword_parameter_node(node) + bounds(node.name_loc) + name = on_label("#{node.name}:") + value = visit(node.value) + + [name, value] + end + + # def foo(bar = 1); end + # ^^^^^^^ + def visit_optional_parameter_node(node) + bounds(node.name_loc) + name = visit_token(node.name.to_s) + value = visit(node.value) + + [name, value] + end + + # a or b + # ^^^^^^ + def visit_or_node(node) + left = visit(node.left) + right = visit(node.right) + + bounds(node.location) + on_binary(left, node.operator.to_sym, right) + end + + # def foo(bar, *baz); end + # ^^^^^^^^^ + def visit_parameters_node(node) + requireds = node.requireds.map { |required| required.is_a?(MultiTargetNode) ? visit_destructured_parameter_node(required) : visit(required) } if node.requireds.any? + optionals = visit_all(node.optionals) if node.optionals.any? + rest = visit(node.rest) + posts = node.posts.map { |post| post.is_a?(MultiTargetNode) ? visit_destructured_parameter_node(post) : visit(post) } if node.posts.any? + keywords = visit_all(node.keywords) if node.keywords.any? + keyword_rest = visit(node.keyword_rest) + block = visit(node.block) + + bounds(node.location) + on_params(requireds, optionals, rest, posts, keywords, keyword_rest, block) + end + + # Visit a destructured positional parameter node. + private def visit_destructured_parameter_node(node) + bounds(node.location) + targets = visit_multi_target_node_targets(node.lefts, node.rest, node.rights, false) + + bounds(node.lparen_loc) + on_mlhs_paren(targets) + end + + # () + # ^^ + # + # (1) + # ^^^ + def visit_parentheses_node(node) + body = + if node.body.nil? + on_stmts_add(on_stmts_new, on_void_stmt) + else + visit(node.body) + end + + bounds(node.location) + on_paren(body) + end + + # foo => ^(bar) + # ^^^^^^ + def visit_pinned_expression_node(node) + expression = visit(node.expression) + + bounds(node.location) + on_begin(expression) + end + + # foo = 1 and bar => ^foo + # ^^^^ + def visit_pinned_variable_node(node) + visit(node.variable) + end + + # END {} + # ^^^^^^ + def visit_post_execution_node(node) + statements = + if node.statements.nil? + bounds(node.location) + on_stmts_add(on_stmts_new, on_void_stmt) + else + visit(node.statements) + end + + bounds(node.location) + on_END(statements) + end + + # BEGIN {} + # ^^^^^^^^ + def visit_pre_execution_node(node) + statements = + if node.statements.nil? + bounds(node.location) + on_stmts_add(on_stmts_new, on_void_stmt) + else + visit(node.statements) + end + + bounds(node.location) + on_BEGIN(statements) + end + + # The top-level program node. + def visit_program_node(node) + body = node.statements.body + body << nil if body.empty? + statements = visit_statements_node_body(body) + + bounds(node.location) + on_program(statements) + end + + # 0..5 + # ^^^^ + def visit_range_node(node) + left = visit(node.left) + right = visit(node.right) + + bounds(node.location) + if node.exclude_end? + on_dot3(left, right) + else + on_dot2(left, right) + end + end + + # 1r + # ^^ + def visit_rational_node(node) + visit_number_node(node) { |text| on_rational(text) } + end + + # redo + # ^^^^ + def visit_redo_node(node) + bounds(node.location) + on_redo + end + + # /foo/ + # ^^^^^ + def visit_regular_expression_node(node) + bounds(node.opening_loc) + on_regexp_beg(node.opening) + + if node.content.empty? + bounds(node.closing_loc) + closing = on_regexp_end(node.closing) + + on_regexp_literal(on_regexp_new, closing) + else + bounds(node.content_loc) + tstring_content = on_tstring_content(node.content) + + bounds(node.closing_loc) + closing = on_regexp_end(node.closing) + + on_regexp_literal(on_regexp_add(on_regexp_new, tstring_content), closing) + end + end + + # def foo(bar:); end + # ^^^^ + def visit_required_keyword_parameter_node(node) + bounds(node.name_loc) + [on_label("#{node.name}:"), false] + end + + # def foo(bar); end + # ^^^ + def visit_required_parameter_node(node) + bounds(node.location) + on_ident(node.name.to_s) + end + + # foo rescue bar + # ^^^^^^^^^^^^^^ + def visit_rescue_modifier_node(node) + expression = visit_write_value(node.expression) + rescue_expression = visit(node.rescue_expression) + + bounds(node.location) + on_rescue_mod(expression, rescue_expression) + end + + # begin; rescue; end + # ^^^^^^^ + def visit_rescue_node(node) + exceptions = + case node.exceptions.length + when 0 + nil + when 1 + if (exception = node.exceptions.first).is_a?(SplatNode) + bounds(exception.location) + on_mrhs_add_star(on_mrhs_new, visit(exception)) + else + [visit(node.exceptions.first)] + end + else + bounds(node.location) + length = node.exceptions.length + + node.exceptions.each_with_index.inject(on_args_new) do |mrhs, (exception, index)| + arg = visit(exception) + + bounds(exception.location) + mrhs = on_mrhs_new_from_args(mrhs) if index == length - 1 + + if exception.is_a?(SplatNode) + if index == length - 1 + on_mrhs_add_star(mrhs, arg) + else + on_args_add_star(mrhs, arg) + end + else + if index == length - 1 + on_mrhs_add(mrhs, arg) + else + on_args_add(mrhs, arg) + end + end + end + end + + reference = visit(node.reference) + statements = + if node.statements.nil? + bounds(node.location) + on_stmts_add(on_stmts_new, on_void_stmt) + else + visit(node.statements) + end + + subsequent = visit(node.subsequent) + + bounds(node.location) + on_rescue(exceptions, reference, statements, subsequent) + end + + # def foo(*bar); end + # ^^^^ + # + # def foo(*); end + # ^ + def visit_rest_parameter_node(node) + if node.name_loc.nil? + bounds(node.location) + on_rest_param(nil) + else + bounds(node.name_loc) + on_rest_param(visit_token(node.name.to_s)) + end + end + + # retry + # ^^^^^ + def visit_retry_node(node) + bounds(node.location) + on_retry + end + + # return + # ^^^^^^ + # + # return 1 + # ^^^^^^^^ + def visit_return_node(node) + if node.arguments.nil? + bounds(node.location) + on_return0 + else + arguments = visit(node.arguments) + + bounds(node.location) + on_return(arguments) + end + end + + # self + # ^^^^ + def visit_self_node(node) + bounds(node.location) + on_var_ref(on_kw("self")) + end + + # A shareable constant. + def visit_shareable_constant_node(node) + visit(node.write) + end + + # class << self; end + # ^^^^^^^^^^^^^^^^^^ + def visit_singleton_class_node(node) + expression = visit(node.expression) + bodystmt = visit_body_node(node.body&.location || node.end_keyword_loc, node.body) + + bounds(node.location) + on_sclass(expression, bodystmt) + end + + # __ENCODING__ + # ^^^^^^^^^^^^ + def visit_source_encoding_node(node) + bounds(node.location) + on_var_ref(on_kw("__ENCODING__")) + end + + # __FILE__ + # ^^^^^^^^ + def visit_source_file_node(node) + bounds(node.location) + on_var_ref(on_kw("__FILE__")) + end + + # __LINE__ + # ^^^^^^^^ + def visit_source_line_node(node) + bounds(node.location) + on_var_ref(on_kw("__LINE__")) + end + + # foo(*bar) + # ^^^^ + # + # def foo((bar, *baz)); end + # ^^^^ + # + # def foo(*); bar(*); end + # ^ + def visit_splat_node(node) + visit(node.expression) + end + + # A list of statements. + def visit_statements_node(node) + bounds(node.location) + visit_statements_node_body(node.body) + end + + # Visit the list of statements of a statements node. We support nil + # statements in the list. This would normally not be allowed by the + # structure of the prism parse tree, but we manually add them here so that + # we can mirror Ripper's void stmt. + private def visit_statements_node_body(body) + body.inject(on_stmts_new) do |stmts, stmt| + on_stmts_add(stmts, stmt.nil? ? on_void_stmt : visit(stmt)) + end + end + + # "foo" + # ^^^^^ + def visit_string_node(node) + if (content = node.content).empty? + bounds(node.location) + on_string_literal(on_string_content) + elsif (opening = node.opening) == "?" + bounds(node.location) + on_CHAR("?#{node.content}") + elsif opening.start_with?("<<~") + heredoc = visit_heredoc_string_node(node.to_interpolated) + + bounds(node.location) + on_string_literal(heredoc) + else + bounds(node.content_loc) + tstring_content = on_tstring_content(content) + + bounds(node.location) + on_string_literal(on_string_add(on_string_content, tstring_content)) + end + end + + # Ripper gives back the escaped string content but strips out the common + # leading whitespace. Prism gives back the unescaped string content and + # a location for the escaped string content. Unfortunately these don't + # work well together, so here we need to re-derive the common leading + # whitespace. + private def visit_heredoc_node_whitespace(parts) + common_whitespace = nil + dedent_next = true + + parts.each do |part| + if part.is_a?(StringNode) + if dedent_next && !(content = part.content).chomp.empty? + common_whitespace = [ + common_whitespace || Float::INFINITY, + content[/\A\s*/].each_char.inject(0) do |part_whitespace, char| + char == "\t" ? ((part_whitespace / 8 + 1) * 8) : (part_whitespace + 1) + end + ].min + end + + dedent_next = true + else + dedent_next = false + end + end + + common_whitespace || 0 + end + + # Visit a string that is expressed using a <<~ heredoc. + private def visit_heredoc_node(parts, base) + common_whitespace = visit_heredoc_node_whitespace(parts) + + if common_whitespace == 0 + bounds(parts.first.location) + + string = [] + result = base + + parts.each do |part| + if part.is_a?(StringNode) + if string.empty? + string = [part] + else + string << part + end + else + unless string.empty? + bounds(string[0].location) + result = yield result, on_tstring_content(string.map(&:content).join) + string = [] + end + + result = yield result, visit(part) + end + end + + unless string.empty? + bounds(string[0].location) + result = yield result, on_tstring_content(string.map(&:content).join) + end + + result + else + bounds(parts.first.location) + result = + parts.inject(base) do |string_content, part| + yield string_content, visit_string_content(part) + end + + bounds(parts.first.location) + on_heredoc_dedent(result, common_whitespace) + end + end + + # Visit a heredoc node that is representing a string. + private def visit_heredoc_string_node(node) + bounds(node.opening_loc) + on_heredoc_beg(node.opening) + + bounds(node.location) + result = + visit_heredoc_node(node.parts, on_string_content) do |parts, part| + on_string_add(parts, part) + end + + bounds(node.closing_loc) + on_heredoc_end(node.closing) + + result + end + + # Visit a heredoc node that is representing an xstring. + private def visit_heredoc_x_string_node(node) + bounds(node.opening_loc) + on_heredoc_beg(node.opening) + + bounds(node.location) + result = + visit_heredoc_node(node.parts, on_xstring_new) do |parts, part| + on_xstring_add(parts, part) + end + + bounds(node.closing_loc) + on_heredoc_end(node.closing) + + result + end + + # super(foo) + # ^^^^^^^^^^ + def visit_super_node(node) + arguments, block = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.rparen_loc || node.location)) + + if !node.lparen_loc.nil? + bounds(node.lparen_loc) + arguments = on_arg_paren(arguments) + end + + bounds(node.location) + call = on_super(arguments) + + if block.nil? + call + else + bounds(node.block.location) + on_method_add_block(call, block) + end + end + + # :foo + # ^^^^ + def visit_symbol_node(node) + if (opening = node.opening)&.match?(/^%s|['"]:?$/) + bounds(node.value_loc) + content = on_string_content + + if !(value = node.value).empty? + content = on_string_add(content, on_tstring_content(value)) + end + + on_dyna_symbol(content) + elsif (closing = node.closing) == ":" + bounds(node.location) + on_label("#{node.value}:") + elsif opening.nil? && node.closing_loc.nil? + bounds(node.value_loc) + on_symbol_literal(visit_token(node.value)) + else + bounds(node.value_loc) + on_symbol_literal(on_symbol(visit_token(node.value))) + end + end + + # true + # ^^^^ + def visit_true_node(node) + bounds(node.location) + on_var_ref(on_kw("true")) + end + + # undef foo + # ^^^^^^^^^ + def visit_undef_node(node) + names = visit_all(node.names) + + bounds(node.location) + on_undef(names) + end + + # unless foo; bar end + # ^^^^^^^^^^^^^^^^^^^ + # + # bar unless foo + # ^^^^^^^^^^^^^^ + def visit_unless_node(node) + if node.statements.nil? || (node.predicate.location.start_offset < node.statements.location.start_offset) + predicate = visit(node.predicate) + statements = + if node.statements.nil? + bounds(node.location) + on_stmts_add(on_stmts_new, on_void_stmt) + else + visit(node.statements) + end + else_clause = visit(node.else_clause) + + bounds(node.location) + on_unless(predicate, statements, else_clause) + else + statements = visit(node.statements.body.first) + predicate = visit(node.predicate) + + bounds(node.location) + on_unless_mod(predicate, statements) + end + end + + # until foo; bar end + # ^^^^^^^^^^^^^^^^^ + # + # bar until foo + # ^^^^^^^^^^^^^ + def visit_until_node(node) + if node.statements.nil? || (node.predicate.location.start_offset < node.statements.location.start_offset) + predicate = visit(node.predicate) + statements = + if node.statements.nil? + bounds(node.location) + on_stmts_add(on_stmts_new, on_void_stmt) + else + visit(node.statements) + end + + bounds(node.location) + on_until(predicate, statements) + else + statements = visit(node.statements.body.first) + predicate = visit(node.predicate) + + bounds(node.location) + on_until_mod(predicate, statements) + end + end + + # case foo; when bar; end + # ^^^^^^^^^^^^^ + def visit_when_node(node) + # This is a special case where we're not going to call on_when directly + # because we don't have access to the subsequent. Instead, we'll return + # the component parts and let the parent node handle it. + conditions = visit_arguments(node.conditions) + statements = + if node.statements.nil? + bounds(node.location) + on_stmts_add(on_stmts_new, on_void_stmt) + else + visit(node.statements) + end + + [conditions, statements] + end + + # while foo; bar end + # ^^^^^^^^^^^^^^^^^^ + # + # bar while foo + # ^^^^^^^^^^^^^ + def visit_while_node(node) + if node.statements.nil? || (node.predicate.location.start_offset < node.statements.location.start_offset) + predicate = visit(node.predicate) + statements = + if node.statements.nil? + bounds(node.location) + on_stmts_add(on_stmts_new, on_void_stmt) + else + visit(node.statements) + end + + bounds(node.location) + on_while(predicate, statements) + else + statements = visit(node.statements.body.first) + predicate = visit(node.predicate) + + bounds(node.location) + on_while_mod(predicate, statements) + end + end + + # `foo` + # ^^^^^ + def visit_x_string_node(node) + if node.unescaped.empty? + bounds(node.location) + on_xstring_literal(on_xstring_new) + elsif node.opening.start_with?("<<~") + heredoc = visit_heredoc_x_string_node(node.to_interpolated) + + bounds(node.location) + on_xstring_literal(heredoc) + else + bounds(node.content_loc) + content = on_tstring_content(node.content) + + bounds(node.location) + on_xstring_literal(on_xstring_add(on_xstring_new, content)) + end + end + + # yield + # ^^^^^ + # + # yield 1 + # ^^^^^^^ + def visit_yield_node(node) + if node.arguments.nil? && node.lparen_loc.nil? + bounds(node.location) + on_yield0 + else + arguments = + if node.arguments.nil? + bounds(node.location) + on_args_new + else + visit(node.arguments) + end + + unless node.lparen_loc.nil? + bounds(node.lparen_loc) + arguments = on_paren(arguments) + end + + bounds(node.location) + on_yield(arguments) + end + end + + private + + # Lazily initialize the parse result. + def result + @result ||= Prism.parse(source, partial_script: true) + end + + ########################################################################## + # Helpers + ########################################################################## + + # Returns true if there is a comma between the two locations. + def trailing_comma?(left, right) + source.byteslice(left.end_offset...right.start_offset).include?(",") + end + + # Returns true if there is a semicolon between the two locations. + def void_stmt?(left, right, allow_newline) + pattern = allow_newline ? /[;\n]/ : /;/ + source.byteslice(left.end_offset...right.start_offset).match?(pattern) + end + + # Visit the string content of a particular node. This method is used to + # split into the various token types. + def visit_token(token, allow_keywords = true) + case token + when "." + on_period(token) + when "`" + on_backtick(token) + when *(allow_keywords ? KEYWORDS : []) + on_kw(token) + when /^_/ + on_ident(token) + when /^[[:upper:]]\w*$/ + on_const(token) + when /^@@/ + on_cvar(token) + when /^@/ + on_ivar(token) + when /^\$/ + on_gvar(token) + when /^[[:punct:]]/ + on_op(token) + else + on_ident(token) + end + end + + # Visit a node that represents a number. We need to explicitly handle the + # unary - operator. + def visit_number_node(node) + slice = node.slice + location = node.location + + if slice[0] == "-" + bounds(location.copy(start_offset: location.start_offset + 1)) + value = yield slice[1..-1] + + bounds(node.location) + on_unary(:-@, value) + else + bounds(location) + yield slice + end + end + + # Visit a node that represents a write value. This is used to handle the + # special case of an implicit array that is generated without brackets. + def visit_write_value(node) + if node.is_a?(ArrayNode) && node.opening_loc.nil? + elements = node.elements + length = elements.length + + bounds(elements.first.location) + elements.each_with_index.inject((elements.first.is_a?(SplatNode) && length == 1) ? on_mrhs_new : on_args_new) do |args, (element, index)| + arg = visit(element) + bounds(element.location) + + if index == length - 1 + if element.is_a?(SplatNode) + mrhs = index == 0 ? args : on_mrhs_new_from_args(args) + on_mrhs_add_star(mrhs, arg) + else + on_mrhs_add(on_mrhs_new_from_args(args), arg) + end + else + case element + when BlockArgumentNode + on_args_add_block(args, arg) + when SplatNode + on_args_add_star(args, arg) + else + on_args_add(args, arg) + end + end + end + else + visit(node) + end + end + + # This method is responsible for updating lineno and column information + # to reflect the current node. + # + # This method could be drastically improved with some caching on the start + # of every line, but for now it's good enough. + def bounds(location) + @lineno = location.start_line + @column = location.start_column + end + + ########################################################################## + # Ripper interface + ########################################################################## + + # :stopdoc: + def _dispatch_0; end + def _dispatch_1(_); end + def _dispatch_2(_, _); end + def _dispatch_3(_, _, _); end + def _dispatch_4(_, _, _, _); end + def _dispatch_5(_, _, _, _, _); end + def _dispatch_7(_, _, _, _, _, _, _); end + # :startdoc: + + # + # Parser Events + # + + PARSER_EVENT_TABLE.each do |id, arity| + alias_method "on_#{id}", "_dispatch_#{arity}" + end + + # This method is called when weak warning is produced by the parser. + # +fmt+ and +args+ is printf style. + def warn(fmt, *args) + end + + # This method is called when strong warning is produced by the parser. + # +fmt+ and +args+ is printf style. + def warning(fmt, *args) + end + + # This method is called when the parser found syntax error. + def compile_error(msg) + end + + # + # Scanner Events + # + + SCANNER_EVENTS.each do |id| + alias_method "on_#{id}", :_dispatch_1 + end + + # This method is provided by the Ripper C extension. It is called when a + # string needs to be dedented because of a tilde heredoc. It is expected + # that it will modify the string in place and return the number of bytes + # that were removed. + def dedent_string(string, width) + whitespace = 0 + cursor = 0 + + while cursor < string.length && string[cursor].match?(/\s/) && whitespace < width + if string[cursor] == "\t" + whitespace = ((whitespace / 8 + 1) * 8) + break if whitespace > width + else + whitespace += 1 + end + + cursor += 1 + end + + string.replace(string[cursor..]) + cursor + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/ripper/sexp.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/ripper/sexp.rb new file mode 100644 index 00000000..dc26a639 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/ripper/sexp.rb @@ -0,0 +1,125 @@ +# frozen_string_literal: true + +require_relative "../ripper" + +module Prism + module Translation + class Ripper + # This class mirrors the ::Ripper::SexpBuilder subclass of ::Ripper that + # returns the arrays of [type, *children]. + class SexpBuilder < Ripper + # :stopdoc: + + attr_reader :error + + private + + def dedent_element(e, width) + if (n = dedent_string(e[1], width)) > 0 + e[2][1] += n + end + e + end + + def on_heredoc_dedent(val, width) + sub = proc do |cont| + cont.map! do |e| + if Array === e + case e[0] + when :@tstring_content + e = dedent_element(e, width) + when /_add\z/ + e[1] = sub[e[1]] + end + elsif String === e + dedent_string(e, width) + end + e + end + end + sub[val] + val + end + + events = private_instance_methods(false).grep(/\Aon_/) {$'.to_sym} + (PARSER_EVENTS - events).each do |event| + module_eval(<<-End, __FILE__, __LINE__ + 1) + def on_#{event}(*args) + args.unshift :#{event} + end + End + end + + SCANNER_EVENTS.each do |event| + module_eval(<<-End, __FILE__, __LINE__ + 1) + def on_#{event}(tok) + [:@#{event}, tok, [lineno(), column()]] + end + End + end + + def on_error(mesg) + @error = mesg + end + remove_method :on_parse_error + alias on_parse_error on_error + alias compile_error on_error + + # :startdoc: + end + + # This class mirrors the ::Ripper::SexpBuilderPP subclass of ::Ripper that + # returns the same values as ::Ripper::SexpBuilder except with a couple of + # niceties that flatten linked lists into arrays. + class SexpBuilderPP < SexpBuilder + # :stopdoc: + + private + + def on_heredoc_dedent(val, width) + val.map! do |e| + next e if Symbol === e and /_content\z/ =~ e + if Array === e and e[0] == :@tstring_content + e = dedent_element(e, width) + elsif String === e + dedent_string(e, width) + end + e + end + val + end + + def _dispatch_event_new + [] + end + + def _dispatch_event_push(list, item) + list.push item + list + end + + def on_mlhs_paren(list) + [:mlhs, *list] + end + + def on_mlhs_add_star(list, star) + list.push([:rest_param, star]) + end + + def on_mlhs_add_post(list, post) + list.concat(post) + end + + PARSER_EVENT_TABLE.each do |event, arity| + if /_new\z/ =~ event and arity == 0 + alias_method "on_#{event}", :_dispatch_event_new + elsif /_add\z/ =~ event + alias_method "on_#{event}", :_dispatch_event_push + end + end + + # :startdoc: + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/ripper/shim.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/ripper/shim.rb new file mode 100644 index 00000000..10e21cd1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/ripper/shim.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +# This writes the prism ripper translation into the Ripper constant so that +# users can transparently use Ripper without any changes. +Ripper = Prism::Translation::Ripper diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/ruby_parser.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/ruby_parser.rb new file mode 100644 index 00000000..8784e22d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/translation/ruby_parser.rb @@ -0,0 +1,1646 @@ +# frozen_string_literal: true + +begin + require "ruby_parser" +rescue LoadError + warn(%q{Error: Unable to load ruby_parser. Add `gem "ruby_parser"` to your Gemfile.}) + exit(1) +end + +module Prism + module Translation + # This module is the entry-point for converting a prism syntax tree into the + # seattlerb/ruby_parser gem's syntax tree. + class RubyParser + # A prism visitor that builds Sexp objects. + class Compiler < ::Prism::Compiler + # This is the name of the file that we are compiling. We set it on every + # Sexp object that is generated, and also use it to compile __FILE__ + # nodes. + attr_reader :file + + # Class variables will change their type based on if they are inside of + # a method definition or not, so we need to track that state. + attr_reader :in_def + + # Some nodes will change their representation if they are inside of a + # pattern, so we need to track that state. + attr_reader :in_pattern + + # Initialize a new compiler with the given file name. + def initialize(file, in_def: false, in_pattern: false) + @file = file + @in_def = in_def + @in_pattern = in_pattern + end + + # alias foo bar + # ^^^^^^^^^^^^^ + def visit_alias_method_node(node) + s(node, :alias, visit(node.new_name), visit(node.old_name)) + end + + # alias $foo $bar + # ^^^^^^^^^^^^^^^ + def visit_alias_global_variable_node(node) + s(node, :valias, node.new_name.name, node.old_name.name) + end + + # foo => bar | baz + # ^^^^^^^^^ + def visit_alternation_pattern_node(node) + s(node, :or, visit(node.left), visit(node.right)) + end + + # a and b + # ^^^^^^^ + def visit_and_node(node) + left = visit(node.left) + + if left[0] == :and + # ruby_parser has the and keyword as right-associative as opposed to + # prism which has it as left-associative. We reverse that + # associativity here. + nest = left + nest = nest[2] while nest[2][0] == :and + nest[2] = s(node, :and, nest[2], visit(node.right)) + left + else + s(node, :and, left, visit(node.right)) + end + end + + # [] + # ^^ + def visit_array_node(node) + if in_pattern + s(node, :array_pat, nil).concat(visit_all(node.elements)) + else + s(node, :array).concat(visit_all(node.elements)) + end + end + + # foo => [bar] + # ^^^^^ + def visit_array_pattern_node(node) + if node.constant.nil? && node.requireds.empty? && node.rest.nil? && node.posts.empty? + s(node, :array_pat) + else + result = s(node, :array_pat, visit_pattern_constant(node.constant)).concat(visit_all(node.requireds)) + + case node.rest + when SplatNode + result << :"*#{node.rest.expression&.name}" + when ImplicitRestNode + result << :* + + # This doesn't make any sense at all, but since we're trying to + # replicate the behavior directly, we'll copy it. + result.line(666) + end + + result.concat(visit_all(node.posts)) + end + end + + # foo(bar) + # ^^^ + def visit_arguments_node(node) + raise "Cannot visit arguments directly" + end + + # { a: 1 } + # ^^^^ + def visit_assoc_node(node) + [visit(node.key), visit(node.value)] + end + + # def foo(**); bar(**); end + # ^^ + # + # { **foo } + # ^^^^^ + def visit_assoc_splat_node(node) + if node.value.nil? + [s(node, :kwsplat)] + else + [s(node, :kwsplat, visit(node.value))] + end + end + + # $+ + # ^^ + def visit_back_reference_read_node(node) + s(node, :back_ref, node.name.name.delete_prefix("$").to_sym) + end + + # begin end + # ^^^^^^^^^ + def visit_begin_node(node) + result = node.statements.nil? ? s(node, :nil) : visit(node.statements) + + if !node.rescue_clause.nil? + if !node.statements.nil? + result = s(node.statements, :rescue, result, visit(node.rescue_clause)) + else + result = s(node.rescue_clause, :rescue, visit(node.rescue_clause)) + end + + current = node.rescue_clause + until (current = current.subsequent).nil? + result << visit(current) + end + end + + if !node.else_clause&.statements.nil? + result << visit(node.else_clause) + end + + if !node.ensure_clause.nil? + if !node.statements.nil? || !node.rescue_clause.nil? || !node.else_clause.nil? + result = s(node.statements || node.rescue_clause || node.else_clause || node.ensure_clause, :ensure, result, visit(node.ensure_clause)) + else + result = s(node.ensure_clause, :ensure, visit(node.ensure_clause)) + end + end + + result + end + + # foo(&bar) + # ^^^^ + def visit_block_argument_node(node) + s(node, :block_pass).tap do |result| + result << visit(node.expression) unless node.expression.nil? + end + end + + # foo { |; bar| } + # ^^^ + def visit_block_local_variable_node(node) + node.name + end + + # A block on a keyword or method call. + def visit_block_node(node) + s(node, :block_pass, visit(node.expression)) + end + + # def foo(&bar); end + # ^^^^ + def visit_block_parameter_node(node) + :"&#{node.name}" + end + + # A block's parameters. + def visit_block_parameters_node(node) + # If this block parameters has no parameters and is using pipes, then + # it inherits its location from its shadow locals, even if they're not + # on the same lines as the pipes. + shadow_loc = true + + result = + if node.parameters.nil? + s(node, :args) + else + shadow_loc = false + visit(node.parameters) + end + + if node.opening == "(" + result.line = node.opening_loc.start_line + result.line_max = node.closing_loc.end_line + shadow_loc = false + end + + if node.locals.any? + shadow = s(node, :shadow).concat(visit_all(node.locals)) + shadow.line = node.locals.first.location.start_line + shadow.line_max = node.locals.last.location.end_line + result << shadow + + if shadow_loc + result.line = shadow.line + result.line_max = shadow.line_max + end + end + + result + end + + # break + # ^^^^^ + # + # break foo + # ^^^^^^^^^ + def visit_break_node(node) + if node.arguments.nil? + s(node, :break) + elsif node.arguments.arguments.length == 1 + s(node, :break, visit(node.arguments.arguments.first)) + else + s(node, :break, s(node.arguments, :array).concat(visit_all(node.arguments.arguments))) + end + end + + # foo + # ^^^ + # + # foo.bar + # ^^^^^^^ + # + # foo.bar() {} + # ^^^^^^^^^^^^ + def visit_call_node(node) + case node.name + when :!~ + return s(node, :not, visit(node.copy(name: :"=~"))) + when :=~ + if node.arguments&.arguments&.length == 1 && node.block.nil? + case node.receiver + when StringNode + return s(node, :match3, visit(node.arguments.arguments.first), visit(node.receiver)) + when RegularExpressionNode, InterpolatedRegularExpressionNode + return s(node, :match2, visit(node.receiver), visit(node.arguments.arguments.first)) + end + + case node.arguments.arguments.first + when RegularExpressionNode, InterpolatedRegularExpressionNode + return s(node, :match3, visit(node.arguments.arguments.first), visit(node.receiver)) + end + end + end + + type = node.attribute_write? ? :attrasgn : :call + type = :"safe_#{type}" if node.safe_navigation? + + arguments = node.arguments&.arguments || [] + write_value = arguments.pop if type == :attrasgn + block = node.block + + if block.is_a?(BlockArgumentNode) + arguments << block + block = nil + end + + result = s(node, type, visit(node.receiver), node.name).concat(visit_all(arguments)) + result << visit_write_value(write_value) unless write_value.nil? + + visit_block(node, result, block) + end + + # foo.bar += baz + # ^^^^^^^^^^^^^^^ + def visit_call_operator_write_node(node) + if op_asgn?(node) + s(node, op_asgn_type(node, :op_asgn), visit(node.receiver), visit_write_value(node.value), node.read_name, node.binary_operator) + else + s(node, op_asgn_type(node, :op_asgn2), visit(node.receiver), node.write_name, node.binary_operator, visit_write_value(node.value)) + end + end + + # foo.bar &&= baz + # ^^^^^^^^^^^^^^^ + def visit_call_and_write_node(node) + if op_asgn?(node) + s(node, op_asgn_type(node, :op_asgn), visit(node.receiver), visit_write_value(node.value), node.read_name, :"&&") + else + s(node, op_asgn_type(node, :op_asgn2), visit(node.receiver), node.write_name, :"&&", visit_write_value(node.value)) + end + end + + # foo.bar ||= baz + # ^^^^^^^^^^^^^^^ + def visit_call_or_write_node(node) + if op_asgn?(node) + s(node, op_asgn_type(node, :op_asgn), visit(node.receiver), visit_write_value(node.value), node.read_name, :"||") + else + s(node, op_asgn_type(node, :op_asgn2), visit(node.receiver), node.write_name, :"||", visit_write_value(node.value)) + end + end + + # Call nodes with operators following them will either be op_asgn or + # op_asgn2 nodes. That is determined by their call operator and their + # right-hand side. + private def op_asgn?(node) + node.call_operator == "::" || (node.value.is_a?(CallNode) && node.value.opening_loc.nil? && !node.value.arguments.nil?) + end + + # Call nodes with operators following them can use &. as an operator, + # which changes their type by prefixing "safe_". + private def op_asgn_type(node, type) + node.safe_navigation? ? :"safe_#{type}" : type + end + + # foo.bar, = 1 + # ^^^^^^^ + def visit_call_target_node(node) + s(node, :attrasgn, visit(node.receiver), node.name) + end + + # foo => bar => baz + # ^^^^^^^^^^ + def visit_capture_pattern_node(node) + visit(node.target) << visit(node.value) + end + + # case foo; when bar; end + # ^^^^^^^^^^^^^^^^^^^^^^^ + def visit_case_node(node) + s(node, :case, visit(node.predicate)).concat(visit_all(node.conditions)) << visit(node.else_clause) + end + + # case foo; in bar; end + # ^^^^^^^^^^^^^^^^^^^^^ + def visit_case_match_node(node) + s(node, :case, visit(node.predicate)).concat(visit_all(node.conditions)) << visit(node.else_clause) + end + + # class Foo; end + # ^^^^^^^^^^^^^^ + def visit_class_node(node) + name = + if node.constant_path.is_a?(ConstantReadNode) + node.name + else + visit(node.constant_path) + end + + if node.body.nil? + s(node, :class, name, visit(node.superclass)) + elsif node.body.is_a?(StatementsNode) + compiler = copy_compiler(in_def: false) + s(node, :class, name, visit(node.superclass)).concat(node.body.body.map { |child| child.accept(compiler) }) + else + s(node, :class, name, visit(node.superclass), node.body.accept(copy_compiler(in_def: false))) + end + end + + # @@foo + # ^^^^^ + def visit_class_variable_read_node(node) + s(node, :cvar, node.name) + end + + # @@foo = 1 + # ^^^^^^^^^ + # + # @@foo, @@bar = 1 + # ^^^^^ ^^^^^ + def visit_class_variable_write_node(node) + s(node, class_variable_write_type, node.name, visit_write_value(node.value)) + end + + # @@foo += bar + # ^^^^^^^^^^^^ + def visit_class_variable_operator_write_node(node) + s(node, class_variable_write_type, node.name, s(node, :call, s(node, :cvar, node.name), node.binary_operator, visit_write_value(node.value))) + end + + # @@foo &&= bar + # ^^^^^^^^^^^^^ + def visit_class_variable_and_write_node(node) + s(node, :op_asgn_and, s(node, :cvar, node.name), s(node, class_variable_write_type, node.name, visit_write_value(node.value))) + end + + # @@foo ||= bar + # ^^^^^^^^^^^^^ + def visit_class_variable_or_write_node(node) + s(node, :op_asgn_or, s(node, :cvar, node.name), s(node, class_variable_write_type, node.name, visit_write_value(node.value))) + end + + # @@foo, = bar + # ^^^^^ + def visit_class_variable_target_node(node) + s(node, class_variable_write_type, node.name) + end + + # If a class variable is written within a method definition, it has a + # different type than everywhere else. + private def class_variable_write_type + in_def ? :cvasgn : :cvdecl + end + + # Foo + # ^^^ + def visit_constant_read_node(node) + s(node, :const, node.name) + end + + # Foo = 1 + # ^^^^^^^ + # + # Foo, Bar = 1 + # ^^^ ^^^ + def visit_constant_write_node(node) + s(node, :cdecl, node.name, visit_write_value(node.value)) + end + + # Foo += bar + # ^^^^^^^^^^^ + def visit_constant_operator_write_node(node) + s(node, :cdecl, node.name, s(node, :call, s(node, :const, node.name), node.binary_operator, visit_write_value(node.value))) + end + + # Foo &&= bar + # ^^^^^^^^^^^^ + def visit_constant_and_write_node(node) + s(node, :op_asgn_and, s(node, :const, node.name), s(node, :cdecl, node.name, visit(node.value))) + end + + # Foo ||= bar + # ^^^^^^^^^^^^ + def visit_constant_or_write_node(node) + s(node, :op_asgn_or, s(node, :const, node.name), s(node, :cdecl, node.name, visit(node.value))) + end + + # Foo, = bar + # ^^^ + def visit_constant_target_node(node) + s(node, :cdecl, node.name) + end + + # Foo::Bar + # ^^^^^^^^ + def visit_constant_path_node(node) + if node.parent.nil? + s(node, :colon3, node.name) + else + s(node, :colon2, visit(node.parent), node.name) + end + end + + # Foo::Bar = 1 + # ^^^^^^^^^^^^ + # + # Foo::Foo, Bar::Bar = 1 + # ^^^^^^^^ ^^^^^^^^ + def visit_constant_path_write_node(node) + s(node, :cdecl, visit(node.target), visit_write_value(node.value)) + end + + # Foo::Bar += baz + # ^^^^^^^^^^^^^^^ + def visit_constant_path_operator_write_node(node) + s(node, :op_asgn, visit(node.target), node.binary_operator, visit_write_value(node.value)) + end + + # Foo::Bar &&= baz + # ^^^^^^^^^^^^^^^^ + def visit_constant_path_and_write_node(node) + s(node, :op_asgn_and, visit(node.target), visit_write_value(node.value)) + end + + # Foo::Bar ||= baz + # ^^^^^^^^^^^^^^^^ + def visit_constant_path_or_write_node(node) + s(node, :op_asgn_or, visit(node.target), visit_write_value(node.value)) + end + + # Foo::Bar, = baz + # ^^^^^^^^ + def visit_constant_path_target_node(node) + inner = + if node.parent.nil? + s(node, :colon3, node.name) + else + s(node, :colon2, visit(node.parent), node.name) + end + + s(node, :const, inner) + end + + # def foo; end + # ^^^^^^^^^^^^ + # + # def self.foo; end + # ^^^^^^^^^^^^^^^^^ + def visit_def_node(node) + name = node.name_loc.slice.to_sym + result = + if node.receiver.nil? + s(node, :defn, name) + else + s(node, :defs, visit(node.receiver), name) + end + + result.line(node.name_loc.start_line) + if node.parameters.nil? + result << s(node, :args).line(node.name_loc.start_line) + else + result << visit(node.parameters) + end + + if node.body.nil? + result << s(node, :nil) + elsif node.body.is_a?(StatementsNode) + compiler = copy_compiler(in_def: true) + result.concat(node.body.body.map { |child| child.accept(compiler) }) + else + result << node.body.accept(copy_compiler(in_def: true)) + end + end + + # defined? a + # ^^^^^^^^^^ + # + # defined?(a) + # ^^^^^^^^^^^ + def visit_defined_node(node) + s(node, :defined, visit(node.value)) + end + + # if foo then bar else baz end + # ^^^^^^^^^^^^ + def visit_else_node(node) + visit(node.statements) + end + + # "foo #{bar}" + # ^^^^^^ + def visit_embedded_statements_node(node) + result = s(node, :evstr) + result << visit(node.statements) unless node.statements.nil? + result + end + + # "foo #@bar" + # ^^^^^ + def visit_embedded_variable_node(node) + s(node, :evstr, visit(node.variable)) + end + + # begin; foo; ensure; bar; end + # ^^^^^^^^^^^^ + def visit_ensure_node(node) + node.statements.nil? ? s(node, :nil) : visit(node.statements) + end + + # false + # ^^^^^ + def visit_false_node(node) + s(node, :false) + end + + # foo => [*, bar, *] + # ^^^^^^^^^^^ + def visit_find_pattern_node(node) + s(node, :find_pat, visit_pattern_constant(node.constant), :"*#{node.left.expression&.name}", *visit_all(node.requireds), :"*#{node.right.expression&.name}") + end + + # if foo .. bar; end + # ^^^^^^^^^^ + def visit_flip_flop_node(node) + if node.left.is_a?(IntegerNode) && node.right.is_a?(IntegerNode) + s(node, :lit, Range.new(node.left.value, node.right.value, node.exclude_end?)) + else + s(node, node.exclude_end? ? :flip3 : :flip2, visit(node.left), visit(node.right)) + end + end + + # 1.0 + # ^^^ + def visit_float_node(node) + s(node, :lit, node.value) + end + + # for foo in bar do end + # ^^^^^^^^^^^^^^^^^^^^^ + def visit_for_node(node) + s(node, :for, visit(node.collection), visit(node.index), visit(node.statements)) + end + + # def foo(...); bar(...); end + # ^^^ + def visit_forwarding_arguments_node(node) + s(node, :forward_args) + end + + # def foo(...); end + # ^^^ + def visit_forwarding_parameter_node(node) + s(node, :forward_args) + end + + # super + # ^^^^^ + # + # super {} + # ^^^^^^^^ + def visit_forwarding_super_node(node) + visit_block(node, s(node, :zsuper), node.block) + end + + # $foo + # ^^^^ + def visit_global_variable_read_node(node) + s(node, :gvar, node.name) + end + + # $foo = 1 + # ^^^^^^^^ + # + # $foo, $bar = 1 + # ^^^^ ^^^^ + def visit_global_variable_write_node(node) + s(node, :gasgn, node.name, visit_write_value(node.value)) + end + + # $foo += bar + # ^^^^^^^^^^^ + def visit_global_variable_operator_write_node(node) + s(node, :gasgn, node.name, s(node, :call, s(node, :gvar, node.name), node.binary_operator, visit(node.value))) + end + + # $foo &&= bar + # ^^^^^^^^^^^^ + def visit_global_variable_and_write_node(node) + s(node, :op_asgn_and, s(node, :gvar, node.name), s(node, :gasgn, node.name, visit_write_value(node.value))) + end + + # $foo ||= bar + # ^^^^^^^^^^^^ + def visit_global_variable_or_write_node(node) + s(node, :op_asgn_or, s(node, :gvar, node.name), s(node, :gasgn, node.name, visit_write_value(node.value))) + end + + # $foo, = bar + # ^^^^ + def visit_global_variable_target_node(node) + s(node, :gasgn, node.name) + end + + # {} + # ^^ + def visit_hash_node(node) + s(node, :hash).concat(node.elements.flat_map { |element| visit(element) }) + end + + # foo => {} + # ^^ + def visit_hash_pattern_node(node) + result = s(node, :hash_pat, visit_pattern_constant(node.constant)).concat(node.elements.flat_map { |element| visit(element) }) + + case node.rest + when AssocSplatNode + result << s(node.rest, :kwrest, :"**#{node.rest.value&.name}") + when NoKeywordsParameterNode + result << visit(node.rest) + end + + result + end + + # if foo then bar end + # ^^^^^^^^^^^^^^^^^^^ + # + # bar if foo + # ^^^^^^^^^^ + # + # foo ? bar : baz + # ^^^^^^^^^^^^^^^ + def visit_if_node(node) + s(node, :if, visit(node.predicate), visit(node.statements), visit(node.subsequent)) + end + + # 1i + def visit_imaginary_node(node) + s(node, :lit, node.value) + end + + # { foo: } + # ^^^^ + def visit_implicit_node(node) + end + + # foo { |bar,| } + # ^ + def visit_implicit_rest_node(node) + end + + # case foo; in bar; end + # ^^^^^^^^^^^^^^^^^^^^^ + def visit_in_node(node) + pattern = + if node.pattern.is_a?(ConstantPathNode) + s(node.pattern, :const, visit(node.pattern)) + else + node.pattern.accept(copy_compiler(in_pattern: true)) + end + + s(node, :in, pattern).concat(node.statements.nil? ? [nil] : visit_all(node.statements.body)) + end + + # foo[bar] += baz + # ^^^^^^^^^^^^^^^ + def visit_index_operator_write_node(node) + arglist = nil + + if !node.arguments.nil? || !node.block.nil? + arglist = s(node, :arglist).concat(visit_all(node.arguments&.arguments || [])) + arglist << visit(node.block) if !node.block.nil? + end + + s(node, :op_asgn1, visit(node.receiver), arglist, node.binary_operator, visit_write_value(node.value)) + end + + # foo[bar] &&= baz + # ^^^^^^^^^^^^^^^^ + def visit_index_and_write_node(node) + arglist = nil + + if !node.arguments.nil? || !node.block.nil? + arglist = s(node, :arglist).concat(visit_all(node.arguments&.arguments || [])) + arglist << visit(node.block) if !node.block.nil? + end + + s(node, :op_asgn1, visit(node.receiver), arglist, :"&&", visit_write_value(node.value)) + end + + # foo[bar] ||= baz + # ^^^^^^^^^^^^^^^^ + def visit_index_or_write_node(node) + arglist = nil + + if !node.arguments.nil? || !node.block.nil? + arglist = s(node, :arglist).concat(visit_all(node.arguments&.arguments || [])) + arglist << visit(node.block) if !node.block.nil? + end + + s(node, :op_asgn1, visit(node.receiver), arglist, :"||", visit_write_value(node.value)) + end + + # foo[bar], = 1 + # ^^^^^^^^ + def visit_index_target_node(node) + arguments = visit_all(node.arguments&.arguments || []) + arguments << visit(node.block) unless node.block.nil? + + s(node, :attrasgn, visit(node.receiver), :[]=).concat(arguments) + end + + # @foo + # ^^^^ + def visit_instance_variable_read_node(node) + s(node, :ivar, node.name) + end + + # @foo = 1 + # ^^^^^^^^ + # + # @foo, @bar = 1 + # ^^^^ ^^^^ + def visit_instance_variable_write_node(node) + s(node, :iasgn, node.name, visit_write_value(node.value)) + end + + # @foo += bar + # ^^^^^^^^^^^ + def visit_instance_variable_operator_write_node(node) + s(node, :iasgn, node.name, s(node, :call, s(node, :ivar, node.name), node.binary_operator, visit_write_value(node.value))) + end + + # @foo &&= bar + # ^^^^^^^^^^^^ + def visit_instance_variable_and_write_node(node) + s(node, :op_asgn_and, s(node, :ivar, node.name), s(node, :iasgn, node.name, visit(node.value))) + end + + # @foo ||= bar + # ^^^^^^^^^^^^ + def visit_instance_variable_or_write_node(node) + s(node, :op_asgn_or, s(node, :ivar, node.name), s(node, :iasgn, node.name, visit(node.value))) + end + + # @foo, = bar + # ^^^^ + def visit_instance_variable_target_node(node) + s(node, :iasgn, node.name) + end + + # 1 + # ^ + def visit_integer_node(node) + s(node, :lit, node.value) + end + + # if /foo #{bar}/ then end + # ^^^^^^^^^^^^ + def visit_interpolated_match_last_line_node(node) + parts = visit_interpolated_parts(node.parts) + regexp = + if parts.length == 1 + s(node, :lit, Regexp.new(parts.first, node.options)) + else + s(node, :dregx).concat(parts).tap do |result| + options = node.options + result << options if options != 0 + end + end + + s(node, :match, regexp) + end + + # /foo #{bar}/ + # ^^^^^^^^^^^^ + def visit_interpolated_regular_expression_node(node) + parts = visit_interpolated_parts(node.parts) + + if parts.length == 1 + s(node, :lit, Regexp.new(parts.first, node.options)) + else + s(node, :dregx).concat(parts).tap do |result| + options = node.options + result << options if options != 0 + end + end + end + + # "foo #{bar}" + # ^^^^^^^^^^^^ + def visit_interpolated_string_node(node) + parts = visit_interpolated_parts(node.parts) + parts.length == 1 ? s(node, :str, parts.first) : s(node, :dstr).concat(parts) + end + + # :"foo #{bar}" + # ^^^^^^^^^^^^^ + def visit_interpolated_symbol_node(node) + parts = visit_interpolated_parts(node.parts) + parts.length == 1 ? s(node, :lit, parts.first.to_sym) : s(node, :dsym).concat(parts) + end + + # `foo #{bar}` + # ^^^^^^^^^^^^ + def visit_interpolated_x_string_node(node) + source = node.heredoc? ? node.parts.first : node + parts = visit_interpolated_parts(node.parts) + parts.length == 1 ? s(source, :xstr, parts.first) : s(source, :dxstr).concat(parts) + end + + # Visit the interpolated content of the string-like node. + private def visit_interpolated_parts(parts) + visited = [] + + parts.each do |part| + result = visit(part) + + if result[0] == :evstr && result[1] + if result[1][0] == :str + visited << result[1] + elsif result[1][0] == :dstr + visited.concat(result[1][1..-1]) + else + visited << result + end + visited << :space + elsif result[0] == :dstr + if !visited.empty? && part.parts[0].is_a?(StringNode) + # If we are in the middle of an implicitly concatenated string, + # we should not have a bare string as the first part. In this + # case we need to visit just that first part and then we can + # push the rest of the parts onto the visited array. + result[1] = visit(part.parts[0]) + end + visited.concat(result[1..-1]) + else + visited << result + end + end + + state = :beginning #: :beginning | :string_content | :interpolated_content + results = [] + + visited.each_with_index do |result, index| + case state + when :beginning + if result.is_a?(String) + results << result + state = :string_content + elsif result.is_a?(Array) && result[0] == :str + results << result[1] + state = :string_content + else + results << "" + results << result + state = :interpolated_content + end + when :string_content + if result == :space + # continue + elsif result.is_a?(String) + results[0] = "#{results[0]}#{result}" + elsif result.is_a?(Array) && result[0] == :str + results[0] = "#{results[0]}#{result[1]}" + else + results << result + state = :interpolated_content + end + when :interpolated_content + if result == :space + # continue + elsif visited[index - 1] != :space && result.is_a?(Array) && result[0] == :str && results[-1][0] == :str && (results[-1].line_max == result.line) + results[-1][1] = "#{results[-1][1]}#{result[1]}" + results[-1].line_max = result.line_max + else + results << result + end + end + end + + results + end + + # -> { it } + # ^^ + def visit_it_local_variable_read_node(node) + s(node, :call, nil, :it) + end + + # foo(bar: baz) + # ^^^^^^^^ + def visit_keyword_hash_node(node) + s(node, :hash).concat(node.elements.flat_map { |element| visit(element) }) + end + + # def foo(**bar); end + # ^^^^^ + # + # def foo(**); end + # ^^ + def visit_keyword_rest_parameter_node(node) + :"**#{node.name}" + end + + # -> {} + def visit_lambda_node(node) + parameters = + case node.parameters + when nil, NumberedParametersNode + s(node, :args) + else + visit(node.parameters) + end + + if node.body.nil? + s(node, :iter, s(node, :lambda), parameters) + else + s(node, :iter, s(node, :lambda), parameters, visit(node.body)) + end + end + + # foo + # ^^^ + def visit_local_variable_read_node(node) + if node.name.match?(/^_\d$/) + s(node, :call, nil, node.name) + else + s(node, :lvar, node.name) + end + end + + # foo = 1 + # ^^^^^^^ + # + # foo, bar = 1 + # ^^^ ^^^ + def visit_local_variable_write_node(node) + s(node, :lasgn, node.name, visit_write_value(node.value)) + end + + # foo += bar + # ^^^^^^^^^^ + def visit_local_variable_operator_write_node(node) + s(node, :lasgn, node.name, s(node, :call, s(node, :lvar, node.name), node.binary_operator, visit_write_value(node.value))) + end + + # foo &&= bar + # ^^^^^^^^^^^ + def visit_local_variable_and_write_node(node) + s(node, :op_asgn_and, s(node, :lvar, node.name), s(node, :lasgn, node.name, visit_write_value(node.value))) + end + + # foo ||= bar + # ^^^^^^^^^^^ + def visit_local_variable_or_write_node(node) + s(node, :op_asgn_or, s(node, :lvar, node.name), s(node, :lasgn, node.name, visit_write_value(node.value))) + end + + # foo, = bar + # ^^^ + def visit_local_variable_target_node(node) + s(node, :lasgn, node.name) + end + + # if /foo/ then end + # ^^^^^ + def visit_match_last_line_node(node) + s(node, :match, s(node, :lit, Regexp.new(node.unescaped, node.options))) + end + + # foo in bar + # ^^^^^^^^^^ + def visit_match_predicate_node(node) + s(node, :case, visit(node.value), s(node, :in, node.pattern.accept(copy_compiler(in_pattern: true)), nil), nil) + end + + # foo => bar + # ^^^^^^^^^^ + def visit_match_required_node(node) + s(node, :case, visit(node.value), s(node, :in, node.pattern.accept(copy_compiler(in_pattern: true)), nil), nil) + end + + # /(?foo)/ =~ bar + # ^^^^^^^^^^^^^^^^^^^^ + def visit_match_write_node(node) + s(node, :match2, visit(node.call.receiver), visit(node.call.arguments.arguments.first)) + end + + # A node that is missing from the syntax tree. This is only used in the + # case of a syntax error. The parser gem doesn't have such a concept, so + # we invent our own here. + def visit_missing_node(node) + raise "Cannot visit missing node directly" + end + + # module Foo; end + # ^^^^^^^^^^^^^^^ + def visit_module_node(node) + name = + if node.constant_path.is_a?(ConstantReadNode) + node.name + else + visit(node.constant_path) + end + + if node.body.nil? + s(node, :module, name) + elsif node.body.is_a?(StatementsNode) + compiler = copy_compiler(in_def: false) + s(node, :module, name).concat(node.body.body.map { |child| child.accept(compiler) }) + else + s(node, :module, name, node.body.accept(copy_compiler(in_def: false))) + end + end + + # foo, bar = baz + # ^^^^^^^^ + def visit_multi_target_node(node) + targets = [*node.lefts] + targets << node.rest if !node.rest.nil? && !node.rest.is_a?(ImplicitRestNode) + targets.concat(node.rights) + + s(node, :masgn, s(node, :array).concat(visit_all(targets))) + end + + # foo, bar = baz + # ^^^^^^^^^^^^^^ + def visit_multi_write_node(node) + targets = [*node.lefts] + targets << node.rest if !node.rest.nil? && !node.rest.is_a?(ImplicitRestNode) + targets.concat(node.rights) + + value = + if node.value.is_a?(ArrayNode) && node.value.opening_loc.nil? + if node.value.elements.length == 1 && node.value.elements.first.is_a?(SplatNode) + visit(node.value.elements.first) + else + visit(node.value) + end + else + s(node.value, :to_ary, visit(node.value)) + end + + s(node, :masgn, s(node, :array).concat(visit_all(targets)), value) + end + + # next + # ^^^^ + # + # next foo + # ^^^^^^^^ + def visit_next_node(node) + if node.arguments.nil? + s(node, :next) + elsif node.arguments.arguments.length == 1 + argument = node.arguments.arguments.first + s(node, :next, argument.is_a?(SplatNode) ? s(node, :svalue, visit(argument)) : visit(argument)) + else + s(node, :next, s(node, :array).concat(visit_all(node.arguments.arguments))) + end + end + + # nil + # ^^^ + def visit_nil_node(node) + s(node, :nil) + end + + # def foo(**nil); end + # ^^^^^ + def visit_no_keywords_parameter_node(node) + in_pattern ? s(node, :kwrest, :"**nil") : :"**nil" + end + + # -> { _1 + _2 } + # ^^^^^^^^^^^^^^ + def visit_numbered_parameters_node(node) + raise "Cannot visit numbered parameters directly" + end + + # $1 + # ^^ + def visit_numbered_reference_read_node(node) + s(node, :nth_ref, node.number) + end + + # def foo(bar: baz); end + # ^^^^^^^^ + def visit_optional_keyword_parameter_node(node) + s(node, :kwarg, node.name, visit(node.value)) + end + + # def foo(bar = 1); end + # ^^^^^^^ + def visit_optional_parameter_node(node) + s(node, :lasgn, node.name, visit(node.value)) + end + + # a or b + # ^^^^^^ + def visit_or_node(node) + left = visit(node.left) + + if left[0] == :or + # ruby_parser has the or keyword as right-associative as opposed to + # prism which has it as left-associative. We reverse that + # associativity here. + nest = left + nest = nest[2] while nest[2][0] == :or + nest[2] = s(node, :or, nest[2], visit(node.right)) + left + else + s(node, :or, left, visit(node.right)) + end + end + + # def foo(bar, *baz); end + # ^^^^^^^^^ + def visit_parameters_node(node) + children = + node.compact_child_nodes.map do |element| + if element.is_a?(MultiTargetNode) + visit_destructured_parameter(element) + else + visit(element) + end + end + + s(node, :args).concat(children) + end + + # def foo((bar, baz)); end + # ^^^^^^^^^^ + private def visit_destructured_parameter(node) + children = + [*node.lefts, *node.rest, *node.rights].map do |child| + case child + when RequiredParameterNode + visit(child) + when MultiTargetNode + visit_destructured_parameter(child) + when SplatNode + :"*#{child.expression&.name}" + else + raise + end + end + + s(node, :masgn).concat(children) + end + + # () + # ^^ + # + # (1) + # ^^^ + def visit_parentheses_node(node) + if node.body.nil? + s(node, :nil) + else + visit(node.body) + end + end + + # foo => ^(bar) + # ^^^^^^ + def visit_pinned_expression_node(node) + node.expression.accept(copy_compiler(in_pattern: false)) + end + + # foo = 1 and bar => ^foo + # ^^^^ + def visit_pinned_variable_node(node) + if node.variable.is_a?(LocalVariableReadNode) && node.variable.name.match?(/^_\d$/) + s(node, :lvar, node.variable.name) + else + visit(node.variable) + end + end + + # END {} + def visit_post_execution_node(node) + s(node, :iter, s(node, :postexe), 0, visit(node.statements)) + end + + # BEGIN {} + def visit_pre_execution_node(node) + s(node, :iter, s(node, :preexe), 0, visit(node.statements)) + end + + # The top-level program node. + def visit_program_node(node) + visit(node.statements) + end + + # 0..5 + # ^^^^ + def visit_range_node(node) + if !in_pattern && !node.left.nil? && !node.right.nil? && ([node.left.type, node.right.type] - %i[nil_node integer_node]).empty? + left = node.left.value if node.left.is_a?(IntegerNode) + right = node.right.value if node.right.is_a?(IntegerNode) + s(node, :lit, Range.new(left, right, node.exclude_end?)) + else + s(node, node.exclude_end? ? :dot3 : :dot2, visit_range_bounds_node(node.left), visit_range_bounds_node(node.right)) + end + end + + # If the bounds of a range node are empty parentheses, then they do not + # get replaced by their usual s(:nil), but instead are s(:begin). + private def visit_range_bounds_node(node) + if node.is_a?(ParenthesesNode) && node.body.nil? + s(node, :begin) + else + visit(node) + end + end + + # 1r + # ^^ + def visit_rational_node(node) + s(node, :lit, node.value) + end + + # redo + # ^^^^ + def visit_redo_node(node) + s(node, :redo) + end + + # /foo/ + # ^^^^^ + def visit_regular_expression_node(node) + s(node, :lit, Regexp.new(node.unescaped, node.options)) + end + + # def foo(bar:); end + # ^^^^ + def visit_required_keyword_parameter_node(node) + s(node, :kwarg, node.name) + end + + # def foo(bar); end + # ^^^ + def visit_required_parameter_node(node) + node.name + end + + # foo rescue bar + # ^^^^^^^^^^^^^^ + def visit_rescue_modifier_node(node) + s(node, :rescue, visit(node.expression), s(node.rescue_expression, :resbody, s(node.rescue_expression, :array), visit(node.rescue_expression))) + end + + # begin; rescue; end + # ^^^^^^^ + def visit_rescue_node(node) + exceptions = + if node.exceptions.length == 1 && node.exceptions.first.is_a?(SplatNode) + visit(node.exceptions.first) + else + s(node, :array).concat(visit_all(node.exceptions)) + end + + if !node.reference.nil? + exceptions << (visit(node.reference) << s(node.reference, :gvar, :"$!")) + end + + s(node, :resbody, exceptions).concat(node.statements.nil? ? [nil] : visit_all(node.statements.body)) + end + + # def foo(*bar); end + # ^^^^ + # + # def foo(*); end + # ^ + def visit_rest_parameter_node(node) + :"*#{node.name}" + end + + # retry + # ^^^^^ + def visit_retry_node(node) + s(node, :retry) + end + + # return + # ^^^^^^ + # + # return 1 + # ^^^^^^^^ + def visit_return_node(node) + if node.arguments.nil? + s(node, :return) + elsif node.arguments.arguments.length == 1 + argument = node.arguments.arguments.first + s(node, :return, argument.is_a?(SplatNode) ? s(node, :svalue, visit(argument)) : visit(argument)) + else + s(node, :return, s(node, :array).concat(visit_all(node.arguments.arguments))) + end + end + + # self + # ^^^^ + def visit_self_node(node) + s(node, :self) + end + + # A shareable constant. + def visit_shareable_constant_node(node) + visit(node.write) + end + + # class << self; end + # ^^^^^^^^^^^^^^^^^^ + def visit_singleton_class_node(node) + s(node, :sclass, visit(node.expression)).tap do |sexp| + sexp << node.body.accept(copy_compiler(in_def: false)) unless node.body.nil? + end + end + + # __ENCODING__ + # ^^^^^^^^^^^^ + def visit_source_encoding_node(node) + # TODO + s(node, :colon2, s(node, :const, :Encoding), :UTF_8) + end + + # __FILE__ + # ^^^^^^^^ + def visit_source_file_node(node) + s(node, :str, node.filepath) + end + + # __LINE__ + # ^^^^^^^^ + def visit_source_line_node(node) + s(node, :lit, node.location.start_line) + end + + # foo(*bar) + # ^^^^ + # + # def foo((bar, *baz)); end + # ^^^^ + # + # def foo(*); bar(*); end + # ^ + def visit_splat_node(node) + if node.expression.nil? + s(node, :splat) + else + s(node, :splat, visit(node.expression)) + end + end + + # A list of statements. + def visit_statements_node(node) + first, *rest = node.body + + if rest.empty? + visit(first) + else + s(node, :block).concat(visit_all(node.body)) + end + end + + # "foo" + # ^^^^^ + def visit_string_node(node) + unescaped = node.unescaped + + if node.forced_binary_encoding? + unescaped = unescaped.dup + unescaped.force_encoding(Encoding::BINARY) + end + + s(node, :str, unescaped) + end + + # super(foo) + # ^^^^^^^^^^ + def visit_super_node(node) + arguments = node.arguments&.arguments || [] + block = node.block + + if block.is_a?(BlockArgumentNode) + arguments << block + block = nil + end + + visit_block(node, s(node, :super).concat(visit_all(arguments)), block) + end + + # :foo + # ^^^^ + def visit_symbol_node(node) + node.value == "!@" ? s(node, :lit, :"!@") : s(node, :lit, node.unescaped.to_sym) + end + + # true + # ^^^^ + def visit_true_node(node) + s(node, :true) + end + + # undef foo + # ^^^^^^^^^ + def visit_undef_node(node) + names = node.names.map { |name| s(node, :undef, visit(name)) } + names.length == 1 ? names.first : s(node, :block).concat(names) + end + + # unless foo; bar end + # ^^^^^^^^^^^^^^^^^^^ + # + # bar unless foo + # ^^^^^^^^^^^^^^ + def visit_unless_node(node) + s(node, :if, visit(node.predicate), visit(node.else_clause), visit(node.statements)) + end + + # until foo; bar end + # ^^^^^^^^^^^^^^^^^ + # + # bar until foo + # ^^^^^^^^^^^^^ + def visit_until_node(node) + s(node, :until, visit(node.predicate), visit(node.statements), !node.begin_modifier?) + end + + # case foo; when bar; end + # ^^^^^^^^^^^^^ + def visit_when_node(node) + s(node, :when, s(node, :array).concat(visit_all(node.conditions))).concat(node.statements.nil? ? [nil] : visit_all(node.statements.body)) + end + + # while foo; bar end + # ^^^^^^^^^^^^^^^^^^ + # + # bar while foo + # ^^^^^^^^^^^^^ + def visit_while_node(node) + s(node, :while, visit(node.predicate), visit(node.statements), !node.begin_modifier?) + end + + # `foo` + # ^^^^^ + def visit_x_string_node(node) + result = s(node, :xstr, node.unescaped) + + if node.heredoc? + result.line = node.content_loc.start_line + result.line_max = node.content_loc.end_line + end + + result + end + + # yield + # ^^^^^ + # + # yield 1 + # ^^^^^^^ + def visit_yield_node(node) + s(node, :yield).concat(visit_all(node.arguments&.arguments || [])) + end + + private + + # Create a new compiler with the given options. + def copy_compiler(in_def: self.in_def, in_pattern: self.in_pattern) + Compiler.new(file, in_def: in_def, in_pattern: in_pattern) + end + + # Create a new Sexp object from the given prism node and arguments. + def s(node, *arguments) + result = Sexp.new(*arguments) + result.file = file + result.line = node.location.start_line + result.line_max = node.location.end_line + result + end + + # Visit a block node, which will modify the AST by wrapping the given + # visited node in an iter node. + def visit_block(node, sexp, block) + if block.nil? + sexp + else + parameters = + case block.parameters + when nil, ItParametersNode, NumberedParametersNode + 0 + else + visit(block.parameters) + end + + if block.body.nil? + s(node, :iter, sexp, parameters) + else + s(node, :iter, sexp, parameters, visit(block.body)) + end + end + end + + # Pattern constants get wrapped in another layer of :const. + def visit_pattern_constant(node) + case node + when nil + # nothing + when ConstantReadNode + visit(node) + else + s(node, :const, visit(node)) + end + end + + # Visit the value of a write, which will be on the right-hand side of + # a write operator. Because implicit arrays can have splats, those could + # potentially be wrapped in an svalue node. + def visit_write_value(node) + if node.is_a?(ArrayNode) && node.opening_loc.nil? + if node.elements.length == 1 && node.elements.first.is_a?(SplatNode) + s(node, :svalue, visit(node.elements.first)) + else + s(node, :svalue, visit(node)) + end + else + visit(node) + end + end + end + + private_constant :Compiler + + # Parse the given source and translate it into the seattlerb/ruby_parser + # gem's Sexp format. + def parse(source, filepath = "(string)") + translate(Prism.parse(source, filepath: filepath, partial_script: true), filepath) + end + + # Parse the given file and translate it into the seattlerb/ruby_parser + # gem's Sexp format. + def parse_file(filepath) + translate(Prism.parse_file(filepath, partial_script: true), filepath) + end + + class << self + # Parse the given source and translate it into the seattlerb/ruby_parser + # gem's Sexp format. + def parse(source, filepath = "(string)") + new.parse(source, filepath) + end + + # Parse the given file and translate it into the seattlerb/ruby_parser + # gem's Sexp format. + def parse_file(filepath) + new.parse_file(filepath) + end + end + + private + + # Translate the given parse result and filepath into the + # seattlerb/ruby_parser gem's Sexp format. + def translate(result, filepath) + if result.failure? + error = result.errors.first + raise ::RubyParser::SyntaxError, "#{filepath}:#{error.location.start_line} :: #{error.message}" + end + + result.value.accept(Compiler.new(filepath)) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/visitor.rb b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/visitor.rb new file mode 100644 index 00000000..dfc2e4a6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/lib/prism/visitor.rb @@ -0,0 +1,508 @@ +# frozen_string_literal: true + +=begin +This file is generated by the templates/template.rb script and should not be +modified manually. See templates/lib/prism/visitor.rb.erb +if you are looking to modify the template +=end + +module Prism + # A class that knows how to walk down the tree. None of the individual visit + # methods are implemented on this visitor, so it forces the consumer to + # implement each one that they need. For a default implementation that + # continues walking the tree, see the Visitor class. + class BasicVisitor + # Calls `accept` on the given node if it is not `nil`, which in turn should + # call back into this visitor by calling the appropriate `visit_*` method. + def visit(node) + # @type self: _Visitor + node&.accept(self) + end + + # Visits each node in `nodes` by calling `accept` on each one. + def visit_all(nodes) + # @type self: _Visitor + nodes.each { |node| node&.accept(self) } + end + + # Visits the child nodes of `node` by calling `accept` on each one. + def visit_child_nodes(node) + # @type self: _Visitor + node.compact_child_nodes.each { |node| node.accept(self) } + end + end + + # A visitor is a class that provides a default implementation for every accept + # method defined on the nodes. This means it can walk a tree without the + # caller needing to define any special handling. This allows you to handle a + # subset of the tree, while still walking the whole tree. + # + # For example, to find all of the method calls that call the `foo` method, you + # could write: + # + # class FooCalls < Prism::Visitor + # def visit_call_node(node) + # if node.name == "foo" + # # Do something with the node + # end + # + # # Call super so that the visitor continues walking the tree + # super + # end + # end + # + class Visitor < BasicVisitor + # Visit a AliasGlobalVariableNode node + alias visit_alias_global_variable_node visit_child_nodes + + # Visit a AliasMethodNode node + alias visit_alias_method_node visit_child_nodes + + # Visit a AlternationPatternNode node + alias visit_alternation_pattern_node visit_child_nodes + + # Visit a AndNode node + alias visit_and_node visit_child_nodes + + # Visit a ArgumentsNode node + alias visit_arguments_node visit_child_nodes + + # Visit a ArrayNode node + alias visit_array_node visit_child_nodes + + # Visit a ArrayPatternNode node + alias visit_array_pattern_node visit_child_nodes + + # Visit a AssocNode node + alias visit_assoc_node visit_child_nodes + + # Visit a AssocSplatNode node + alias visit_assoc_splat_node visit_child_nodes + + # Visit a BackReferenceReadNode node + alias visit_back_reference_read_node visit_child_nodes + + # Visit a BeginNode node + alias visit_begin_node visit_child_nodes + + # Visit a BlockArgumentNode node + alias visit_block_argument_node visit_child_nodes + + # Visit a BlockLocalVariableNode node + alias visit_block_local_variable_node visit_child_nodes + + # Visit a BlockNode node + alias visit_block_node visit_child_nodes + + # Visit a BlockParameterNode node + alias visit_block_parameter_node visit_child_nodes + + # Visit a BlockParametersNode node + alias visit_block_parameters_node visit_child_nodes + + # Visit a BreakNode node + alias visit_break_node visit_child_nodes + + # Visit a CallAndWriteNode node + alias visit_call_and_write_node visit_child_nodes + + # Visit a CallNode node + alias visit_call_node visit_child_nodes + + # Visit a CallOperatorWriteNode node + alias visit_call_operator_write_node visit_child_nodes + + # Visit a CallOrWriteNode node + alias visit_call_or_write_node visit_child_nodes + + # Visit a CallTargetNode node + alias visit_call_target_node visit_child_nodes + + # Visit a CapturePatternNode node + alias visit_capture_pattern_node visit_child_nodes + + # Visit a CaseMatchNode node + alias visit_case_match_node visit_child_nodes + + # Visit a CaseNode node + alias visit_case_node visit_child_nodes + + # Visit a ClassNode node + alias visit_class_node visit_child_nodes + + # Visit a ClassVariableAndWriteNode node + alias visit_class_variable_and_write_node visit_child_nodes + + # Visit a ClassVariableOperatorWriteNode node + alias visit_class_variable_operator_write_node visit_child_nodes + + # Visit a ClassVariableOrWriteNode node + alias visit_class_variable_or_write_node visit_child_nodes + + # Visit a ClassVariableReadNode node + alias visit_class_variable_read_node visit_child_nodes + + # Visit a ClassVariableTargetNode node + alias visit_class_variable_target_node visit_child_nodes + + # Visit a ClassVariableWriteNode node + alias visit_class_variable_write_node visit_child_nodes + + # Visit a ConstantAndWriteNode node + alias visit_constant_and_write_node visit_child_nodes + + # Visit a ConstantOperatorWriteNode node + alias visit_constant_operator_write_node visit_child_nodes + + # Visit a ConstantOrWriteNode node + alias visit_constant_or_write_node visit_child_nodes + + # Visit a ConstantPathAndWriteNode node + alias visit_constant_path_and_write_node visit_child_nodes + + # Visit a ConstantPathNode node + alias visit_constant_path_node visit_child_nodes + + # Visit a ConstantPathOperatorWriteNode node + alias visit_constant_path_operator_write_node visit_child_nodes + + # Visit a ConstantPathOrWriteNode node + alias visit_constant_path_or_write_node visit_child_nodes + + # Visit a ConstantPathTargetNode node + alias visit_constant_path_target_node visit_child_nodes + + # Visit a ConstantPathWriteNode node + alias visit_constant_path_write_node visit_child_nodes + + # Visit a ConstantReadNode node + alias visit_constant_read_node visit_child_nodes + + # Visit a ConstantTargetNode node + alias visit_constant_target_node visit_child_nodes + + # Visit a ConstantWriteNode node + alias visit_constant_write_node visit_child_nodes + + # Visit a DefNode node + alias visit_def_node visit_child_nodes + + # Visit a DefinedNode node + alias visit_defined_node visit_child_nodes + + # Visit a ElseNode node + alias visit_else_node visit_child_nodes + + # Visit a EmbeddedStatementsNode node + alias visit_embedded_statements_node visit_child_nodes + + # Visit a EmbeddedVariableNode node + alias visit_embedded_variable_node visit_child_nodes + + # Visit a EnsureNode node + alias visit_ensure_node visit_child_nodes + + # Visit a FalseNode node + alias visit_false_node visit_child_nodes + + # Visit a FindPatternNode node + alias visit_find_pattern_node visit_child_nodes + + # Visit a FlipFlopNode node + alias visit_flip_flop_node visit_child_nodes + + # Visit a FloatNode node + alias visit_float_node visit_child_nodes + + # Visit a ForNode node + alias visit_for_node visit_child_nodes + + # Visit a ForwardingArgumentsNode node + alias visit_forwarding_arguments_node visit_child_nodes + + # Visit a ForwardingParameterNode node + alias visit_forwarding_parameter_node visit_child_nodes + + # Visit a ForwardingSuperNode node + alias visit_forwarding_super_node visit_child_nodes + + # Visit a GlobalVariableAndWriteNode node + alias visit_global_variable_and_write_node visit_child_nodes + + # Visit a GlobalVariableOperatorWriteNode node + alias visit_global_variable_operator_write_node visit_child_nodes + + # Visit a GlobalVariableOrWriteNode node + alias visit_global_variable_or_write_node visit_child_nodes + + # Visit a GlobalVariableReadNode node + alias visit_global_variable_read_node visit_child_nodes + + # Visit a GlobalVariableTargetNode node + alias visit_global_variable_target_node visit_child_nodes + + # Visit a GlobalVariableWriteNode node + alias visit_global_variable_write_node visit_child_nodes + + # Visit a HashNode node + alias visit_hash_node visit_child_nodes + + # Visit a HashPatternNode node + alias visit_hash_pattern_node visit_child_nodes + + # Visit a IfNode node + alias visit_if_node visit_child_nodes + + # Visit a ImaginaryNode node + alias visit_imaginary_node visit_child_nodes + + # Visit a ImplicitNode node + alias visit_implicit_node visit_child_nodes + + # Visit a ImplicitRestNode node + alias visit_implicit_rest_node visit_child_nodes + + # Visit a InNode node + alias visit_in_node visit_child_nodes + + # Visit a IndexAndWriteNode node + alias visit_index_and_write_node visit_child_nodes + + # Visit a IndexOperatorWriteNode node + alias visit_index_operator_write_node visit_child_nodes + + # Visit a IndexOrWriteNode node + alias visit_index_or_write_node visit_child_nodes + + # Visit a IndexTargetNode node + alias visit_index_target_node visit_child_nodes + + # Visit a InstanceVariableAndWriteNode node + alias visit_instance_variable_and_write_node visit_child_nodes + + # Visit a InstanceVariableOperatorWriteNode node + alias visit_instance_variable_operator_write_node visit_child_nodes + + # Visit a InstanceVariableOrWriteNode node + alias visit_instance_variable_or_write_node visit_child_nodes + + # Visit a InstanceVariableReadNode node + alias visit_instance_variable_read_node visit_child_nodes + + # Visit a InstanceVariableTargetNode node + alias visit_instance_variable_target_node visit_child_nodes + + # Visit a InstanceVariableWriteNode node + alias visit_instance_variable_write_node visit_child_nodes + + # Visit a IntegerNode node + alias visit_integer_node visit_child_nodes + + # Visit a InterpolatedMatchLastLineNode node + alias visit_interpolated_match_last_line_node visit_child_nodes + + # Visit a InterpolatedRegularExpressionNode node + alias visit_interpolated_regular_expression_node visit_child_nodes + + # Visit a InterpolatedStringNode node + alias visit_interpolated_string_node visit_child_nodes + + # Visit a InterpolatedSymbolNode node + alias visit_interpolated_symbol_node visit_child_nodes + + # Visit a InterpolatedXStringNode node + alias visit_interpolated_x_string_node visit_child_nodes + + # Visit a ItLocalVariableReadNode node + alias visit_it_local_variable_read_node visit_child_nodes + + # Visit a ItParametersNode node + alias visit_it_parameters_node visit_child_nodes + + # Visit a KeywordHashNode node + alias visit_keyword_hash_node visit_child_nodes + + # Visit a KeywordRestParameterNode node + alias visit_keyword_rest_parameter_node visit_child_nodes + + # Visit a LambdaNode node + alias visit_lambda_node visit_child_nodes + + # Visit a LocalVariableAndWriteNode node + alias visit_local_variable_and_write_node visit_child_nodes + + # Visit a LocalVariableOperatorWriteNode node + alias visit_local_variable_operator_write_node visit_child_nodes + + # Visit a LocalVariableOrWriteNode node + alias visit_local_variable_or_write_node visit_child_nodes + + # Visit a LocalVariableReadNode node + alias visit_local_variable_read_node visit_child_nodes + + # Visit a LocalVariableTargetNode node + alias visit_local_variable_target_node visit_child_nodes + + # Visit a LocalVariableWriteNode node + alias visit_local_variable_write_node visit_child_nodes + + # Visit a MatchLastLineNode node + alias visit_match_last_line_node visit_child_nodes + + # Visit a MatchPredicateNode node + alias visit_match_predicate_node visit_child_nodes + + # Visit a MatchRequiredNode node + alias visit_match_required_node visit_child_nodes + + # Visit a MatchWriteNode node + alias visit_match_write_node visit_child_nodes + + # Visit a MissingNode node + alias visit_missing_node visit_child_nodes + + # Visit a ModuleNode node + alias visit_module_node visit_child_nodes + + # Visit a MultiTargetNode node + alias visit_multi_target_node visit_child_nodes + + # Visit a MultiWriteNode node + alias visit_multi_write_node visit_child_nodes + + # Visit a NextNode node + alias visit_next_node visit_child_nodes + + # Visit a NilNode node + alias visit_nil_node visit_child_nodes + + # Visit a NoKeywordsParameterNode node + alias visit_no_keywords_parameter_node visit_child_nodes + + # Visit a NumberedParametersNode node + alias visit_numbered_parameters_node visit_child_nodes + + # Visit a NumberedReferenceReadNode node + alias visit_numbered_reference_read_node visit_child_nodes + + # Visit a OptionalKeywordParameterNode node + alias visit_optional_keyword_parameter_node visit_child_nodes + + # Visit a OptionalParameterNode node + alias visit_optional_parameter_node visit_child_nodes + + # Visit a OrNode node + alias visit_or_node visit_child_nodes + + # Visit a ParametersNode node + alias visit_parameters_node visit_child_nodes + + # Visit a ParenthesesNode node + alias visit_parentheses_node visit_child_nodes + + # Visit a PinnedExpressionNode node + alias visit_pinned_expression_node visit_child_nodes + + # Visit a PinnedVariableNode node + alias visit_pinned_variable_node visit_child_nodes + + # Visit a PostExecutionNode node + alias visit_post_execution_node visit_child_nodes + + # Visit a PreExecutionNode node + alias visit_pre_execution_node visit_child_nodes + + # Visit a ProgramNode node + alias visit_program_node visit_child_nodes + + # Visit a RangeNode node + alias visit_range_node visit_child_nodes + + # Visit a RationalNode node + alias visit_rational_node visit_child_nodes + + # Visit a RedoNode node + alias visit_redo_node visit_child_nodes + + # Visit a RegularExpressionNode node + alias visit_regular_expression_node visit_child_nodes + + # Visit a RequiredKeywordParameterNode node + alias visit_required_keyword_parameter_node visit_child_nodes + + # Visit a RequiredParameterNode node + alias visit_required_parameter_node visit_child_nodes + + # Visit a RescueModifierNode node + alias visit_rescue_modifier_node visit_child_nodes + + # Visit a RescueNode node + alias visit_rescue_node visit_child_nodes + + # Visit a RestParameterNode node + alias visit_rest_parameter_node visit_child_nodes + + # Visit a RetryNode node + alias visit_retry_node visit_child_nodes + + # Visit a ReturnNode node + alias visit_return_node visit_child_nodes + + # Visit a SelfNode node + alias visit_self_node visit_child_nodes + + # Visit a ShareableConstantNode node + alias visit_shareable_constant_node visit_child_nodes + + # Visit a SingletonClassNode node + alias visit_singleton_class_node visit_child_nodes + + # Visit a SourceEncodingNode node + alias visit_source_encoding_node visit_child_nodes + + # Visit a SourceFileNode node + alias visit_source_file_node visit_child_nodes + + # Visit a SourceLineNode node + alias visit_source_line_node visit_child_nodes + + # Visit a SplatNode node + alias visit_splat_node visit_child_nodes + + # Visit a StatementsNode node + alias visit_statements_node visit_child_nodes + + # Visit a StringNode node + alias visit_string_node visit_child_nodes + + # Visit a SuperNode node + alias visit_super_node visit_child_nodes + + # Visit a SymbolNode node + alias visit_symbol_node visit_child_nodes + + # Visit a TrueNode node + alias visit_true_node visit_child_nodes + + # Visit a UndefNode node + alias visit_undef_node visit_child_nodes + + # Visit a UnlessNode node + alias visit_unless_node visit_child_nodes + + # Visit a UntilNode node + alias visit_until_node visit_child_nodes + + # Visit a WhenNode node + alias visit_when_node visit_child_nodes + + # Visit a WhileNode node + alias visit_while_node visit_child_nodes + + # Visit a XStringNode node + alias visit_x_string_node visit_child_nodes + + # Visit a YieldNode node + alias visit_yield_node visit_child_nodes + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/prism.gemspec b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/prism.gemspec new file mode 100644 index 00000000..1947eedc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/prism.gemspec @@ -0,0 +1,170 @@ +# frozen_string_literal: true + +Gem::Specification.new do |spec| + spec.name = "prism" + spec.version = "1.4.0" + spec.authors = ["Shopify"] + spec.email = ["ruby@shopify.com"] + + spec.summary = "Prism Ruby parser" + spec.homepage = "https://github.com/ruby/prism" + spec.license = "MIT" + + spec.required_ruby_version = ">= 2.7.0" + + spec.require_paths = ["lib"] + spec.files = [ + "BSDmakefile", + "CHANGELOG.md", + "CODE_OF_CONDUCT.md", + "CONTRIBUTING.md", + "LICENSE.md", + "Makefile", + "README.md", + "config.yml", + "docs/build_system.md", + "docs/configuration.md", + "docs/cruby_compilation.md", + "docs/design.md", + "docs/encoding.md", + "docs/fuzzing.md", + "docs/heredocs.md", + "docs/javascript.md", + "docs/local_variable_depth.md", + "docs/mapping.md", + "docs/parser_translation.md", + "docs/parsing_rules.md", + "docs/releasing.md", + "docs/relocation.md", + "docs/ripper_translation.md", + "docs/ruby_api.md", + "docs/ruby_parser_translation.md", + "docs/serialization.md", + "docs/testing.md", + "ext/prism/api_node.c", + "ext/prism/api_pack.c", + "ext/prism/extension.c", + "ext/prism/extension.h", + "include/prism.h", + "include/prism/ast.h", + "include/prism/defines.h", + "include/prism/diagnostic.h", + "include/prism/encoding.h", + "include/prism/node.h", + "include/prism/options.h", + "include/prism/pack.h", + "include/prism/parser.h", + "include/prism/prettyprint.h", + "include/prism/regexp.h", + "include/prism/static_literals.h", + "include/prism/util/pm_buffer.h", + "include/prism/util/pm_char.h", + "include/prism/util/pm_constant_pool.h", + "include/prism/util/pm_integer.h", + "include/prism/util/pm_list.h", + "include/prism/util/pm_memchr.h", + "include/prism/util/pm_newline_list.h", + "include/prism/util/pm_strncasecmp.h", + "include/prism/util/pm_string.h", + "include/prism/util/pm_strpbrk.h", + "include/prism/version.h", + "lib/prism.rb", + "lib/prism/compiler.rb", + "lib/prism/desugar_compiler.rb", + "lib/prism/dispatcher.rb", + "lib/prism/dot_visitor.rb", + "lib/prism/dsl.rb", + "lib/prism/ffi.rb", + "lib/prism/inspect_visitor.rb", + "lib/prism/lex_compat.rb", + "lib/prism/mutation_compiler.rb", + "lib/prism/node_ext.rb", + "lib/prism/node.rb", + "lib/prism/pack.rb", + "lib/prism/parse_result.rb", + "lib/prism/parse_result/comments.rb", + "lib/prism/parse_result/errors.rb", + "lib/prism/parse_result/newlines.rb", + "lib/prism/pattern.rb", + "lib/prism/polyfill/append_as_bytes.rb", + "lib/prism/polyfill/byteindex.rb", + "lib/prism/polyfill/unpack1.rb", + "lib/prism/reflection.rb", + "lib/prism/relocation.rb", + "lib/prism/serialize.rb", + "lib/prism/string_query.rb", + "lib/prism/translation.rb", + "lib/prism/translation/parser.rb", + "lib/prism/translation/parser33.rb", + "lib/prism/translation/parser34.rb", + "lib/prism/translation/parser35.rb", + "lib/prism/translation/parser/builder.rb", + "lib/prism/translation/parser/compiler.rb", + "lib/prism/translation/parser/lexer.rb", + "lib/prism/translation/ripper.rb", + "lib/prism/translation/ripper/sexp.rb", + "lib/prism/translation/ripper/shim.rb", + "lib/prism/translation/ruby_parser.rb", + "lib/prism/visitor.rb", + "prism.gemspec", + "rbi/prism.rbi", + "rbi/prism/compiler.rbi", + "rbi/prism/dsl.rbi", + "rbi/prism/inspect_visitor.rbi", + "rbi/prism/node_ext.rbi", + "rbi/prism/node.rbi", + "rbi/prism/parse_result.rbi", + "rbi/prism/reflection.rbi", + "rbi/prism/string_query.rbi", + "rbi/prism/translation/parser.rbi", + "rbi/prism/translation/parser33.rbi", + "rbi/prism/translation/parser34.rbi", + "rbi/prism/translation/parser35.rbi", + "rbi/prism/translation/ripper.rbi", + "rbi/prism/visitor.rbi", + "sig/prism.rbs", + "sig/prism/compiler.rbs", + "sig/prism/dispatcher.rbs", + "sig/prism/dot_visitor.rbs", + "sig/prism/dsl.rbs", + "sig/prism/inspect_visitor.rbs", + "sig/prism/lex_compat.rbs", + "sig/prism/mutation_compiler.rbs", + "sig/prism/node_ext.rbs", + "sig/prism/node.rbs", + "sig/prism/pack.rbs", + "sig/prism/parse_result.rbs", + "sig/prism/pattern.rbs", + "sig/prism/reflection.rbs", + "sig/prism/relocation.rbs", + "sig/prism/serialize.rbs", + "sig/prism/string_query.rbs", + "sig/prism/visitor.rbs", + "src/diagnostic.c", + "src/encoding.c", + "src/node.c", + "src/options.c", + "src/pack.c", + "src/prettyprint.c", + "src/prism.c", + "src/regexp.c", + "src/serialize.c", + "src/static_literals.c", + "src/token_type.c", + "src/util/pm_buffer.c", + "src/util/pm_char.c", + "src/util/pm_constant_pool.c", + "src/util/pm_integer.c", + "src/util/pm_list.c", + "src/util/pm_memchr.c", + "src/util/pm_newline_list.c", + "src/util/pm_string.c", + "src/util/pm_strncasecmp.c", + "src/util/pm_strpbrk.c" + ] + + spec.extensions = ["ext/prism/extconf.rb"] + spec.metadata["allowed_push_host"] = "https://rubygems.org" + spec.metadata["source_code_uri"] = "https://github.com/ruby/prism" + spec.metadata["changelog_uri"] = "https://github.com/ruby/prism/blob/main/CHANGELOG.md" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism.rbi b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism.rbi new file mode 100644 index 00000000..8866e7b3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism.rbi @@ -0,0 +1,66 @@ +# typed: strict + +module Prism + sig { params(source: String, command_line: T.nilable(String), encoding: T.nilable(T.any(FalseClass, Encoding)), filepath: T.nilable(String), freeze: T.nilable(T::Boolean), frozen_string_literal: T.nilable(T::Boolean), line: T.nilable(Integer), main_script: T.nilable(T::Boolean), partial_script: T.nilable(T::Boolean), scopes: T.nilable(T::Array[T::Array[Symbol]]), version: T.nilable(String)).returns(String) } + def self.dump(source, command_line: nil, encoding: nil, filepath: nil, freeze: nil, frozen_string_literal: nil, line: nil, main_script: nil, partial_script: nil, scopes: nil, version: nil); end + + sig { params(filepath: String, command_line: T.nilable(String), encoding: T.nilable(T.any(FalseClass, Encoding)), freeze: T.nilable(T::Boolean), frozen_string_literal: T.nilable(T::Boolean), line: T.nilable(Integer), main_script: T.nilable(T::Boolean), partial_script: T.nilable(T::Boolean), scopes: T.nilable(T::Array[T::Array[Symbol]]), version: T.nilable(String)).returns(String) } + def self.dump_file(filepath, command_line: nil, encoding: nil, freeze: nil, frozen_string_literal: nil, line: nil, main_script: nil, partial_script: nil, scopes: nil, version: nil); end + + sig { params(source: String, command_line: T.nilable(String), encoding: T.nilable(T.any(FalseClass, Encoding)), filepath: T.nilable(String), freeze: T.nilable(T::Boolean), frozen_string_literal: T.nilable(T::Boolean), line: T.nilable(Integer), main_script: T.nilable(T::Boolean), partial_script: T.nilable(T::Boolean), scopes: T.nilable(T::Array[T::Array[Symbol]]), version: T.nilable(String)).returns(Prism::LexResult) } + def self.lex(source, command_line: nil, encoding: nil, filepath: nil, freeze: nil, frozen_string_literal: nil, line: nil, main_script: nil, partial_script: nil, scopes: nil, version: nil); end + + sig { params(filepath: String, command_line: T.nilable(String), encoding: T.nilable(T.any(FalseClass, Encoding)), freeze: T.nilable(T::Boolean), frozen_string_literal: T.nilable(T::Boolean), line: T.nilable(Integer), main_script: T.nilable(T::Boolean), partial_script: T.nilable(T::Boolean), scopes: T.nilable(T::Array[T::Array[Symbol]]), version: T.nilable(String)).returns(Prism::LexResult) } + def self.lex_file(filepath, command_line: nil, encoding: nil, freeze: nil, frozen_string_literal: nil, line: nil, main_script: nil, partial_script: nil, scopes: nil, version: nil); end + + sig { params(source: String, options: T::Hash[Symbol, T.untyped]).returns(Prism::LexCompat::Result) } + def self.lex_compat(source, **options); end + + sig { params(source: String).returns(T::Array[T.untyped]) } + def self.lex_ripper(source); end + + sig { params(source: String, serialized: String, freeze: T.nilable(T::Boolean)).returns(Prism::ParseResult) } + def self.load(source, serialized, freeze = false); end + + sig { params(source: String, command_line: T.nilable(String), encoding: T.nilable(T.any(FalseClass, Encoding)), filepath: T.nilable(String), freeze: T.nilable(T::Boolean), frozen_string_literal: T.nilable(T::Boolean), line: T.nilable(Integer), main_script: T.nilable(T::Boolean), partial_script: T.nilable(T::Boolean), scopes: T.nilable(T::Array[T::Array[Symbol]]), version: T.nilable(String)).returns(Prism::ParseResult) } + def self.parse(source, command_line: nil, encoding: nil, filepath: nil, freeze: nil, frozen_string_literal: nil, line: nil, main_script: nil, partial_script: nil, scopes: nil, version: nil); end + + sig { params(filepath: String, command_line: T.nilable(String), encoding: T.nilable(T.any(FalseClass, Encoding)), freeze: T.nilable(T::Boolean), frozen_string_literal: T.nilable(T::Boolean), line: T.nilable(Integer), main_script: T.nilable(T::Boolean), partial_script: T.nilable(T::Boolean), scopes: T.nilable(T::Array[T::Array[Symbol]]), version: T.nilable(String)).returns(Prism::ParseResult) } + def self.parse_file(filepath, command_line: nil, encoding: nil, freeze: nil, frozen_string_literal: nil, line: nil, main_script: nil, partial_script: nil, scopes: nil, version: nil); end + + sig { params(source: String, command_line: T.nilable(String), encoding: T.nilable(T.any(FalseClass, Encoding)), filepath: T.nilable(String), freeze: T.nilable(T::Boolean), frozen_string_literal: T.nilable(T::Boolean), line: T.nilable(Integer), main_script: T.nilable(T::Boolean), partial_script: T.nilable(T::Boolean), scopes: T.nilable(T::Array[T::Array[Symbol]]), version: T.nilable(String)).void } + def self.profile(source, command_line: nil, encoding: nil, filepath: nil, freeze: nil, frozen_string_literal: nil, line: nil, main_script: nil, partial_script: nil, scopes: nil, version: nil); end + + sig { params(filepath: String, command_line: T.nilable(String), encoding: T.nilable(T.any(FalseClass, Encoding)), freeze: T.nilable(T::Boolean), frozen_string_literal: T.nilable(T::Boolean), line: T.nilable(Integer), main_script: T.nilable(T::Boolean), partial_script: T.nilable(T::Boolean), scopes: T.nilable(T::Array[T::Array[Symbol]]), version: T.nilable(String)).void } + def self.profile_file(filepath, command_line: nil, encoding: nil, freeze: nil, frozen_string_literal: nil, line: nil, main_script: nil, partial_script: nil, scopes: nil, version: nil); end + + sig { params(stream: T.any(IO, StringIO), command_line: T.nilable(String), encoding: T.nilable(T.any(FalseClass, Encoding)), filepath: T.nilable(String), freeze: T.nilable(T::Boolean), frozen_string_literal: T.nilable(T::Boolean), line: T.nilable(Integer), main_script: T.nilable(T::Boolean), partial_script: T.nilable(T::Boolean), scopes: T.nilable(T::Array[T::Array[Symbol]]), version: T.nilable(String)).returns(Prism::ParseResult) } + def self.parse_stream(stream, command_line: nil, encoding: nil, filepath: nil, freeze: nil, frozen_string_literal: nil, line: nil, main_script: nil, partial_script: nil, scopes: nil, version: nil); end + + sig { params(source: String, command_line: T.nilable(String), encoding: T.nilable(T.any(String, Encoding)), filepath: T.nilable(String), freeze: T.nilable(T::Boolean), frozen_string_literal: T.nilable(T::Boolean), line: T.nilable(Integer), main_script: T.nilable(T::Boolean), partial_script: T.nilable(T::Boolean), scopes: T.nilable(T::Array[T::Array[Symbol]]), version: T.nilable(String)).returns(T::Array[Prism::Comment]) } + def self.parse_comments(source, command_line: nil, encoding: nil, filepath: nil, freeze: nil, frozen_string_literal: nil, line: nil, main_script: nil, partial_script: nil, scopes: nil, version: nil); end + + sig { params(filepath: String, command_line: T.nilable(String), encoding: T.nilable(T.any(FalseClass, Encoding)), freeze: T.nilable(T::Boolean), frozen_string_literal: T.nilable(T::Boolean), line: T.nilable(Integer), main_script: T.nilable(T::Boolean), partial_script: T.nilable(T::Boolean), scopes: T.nilable(T::Array[T::Array[Symbol]]), version: T.nilable(String)).returns(T::Array[Prism::Comment]) } + def self.parse_file_comments(filepath, command_line: nil, encoding: nil, freeze: nil, frozen_string_literal: nil, line: nil, main_script: nil, partial_script: nil, scopes: nil, version: nil); end + + sig { params(source: String, command_line: T.nilable(String), encoding: T.nilable(T.any(FalseClass, Encoding)), filepath: T.nilable(String), freeze: T.nilable(T::Boolean), frozen_string_literal: T.nilable(T::Boolean), line: T.nilable(Integer), main_script: T.nilable(T::Boolean), partial_script: T.nilable(T::Boolean), scopes: T.nilable(T::Array[T::Array[Symbol]]), version: T.nilable(String)).returns(Prism::ParseLexResult) } + def self.parse_lex(source, command_line: nil, encoding: nil, filepath: nil, freeze: nil, frozen_string_literal: nil, line: nil, main_script: nil, partial_script: nil, scopes: nil, version: nil); end + + sig { params(filepath: String, command_line: T.nilable(String), encoding: T.nilable(T.any(FalseClass, Encoding)), freeze: T.nilable(T::Boolean), frozen_string_literal: T.nilable(T::Boolean), line: T.nilable(Integer), main_script: T.nilable(T::Boolean), partial_script: T.nilable(T::Boolean), scopes: T.nilable(T::Array[T::Array[Symbol]]), version: T.nilable(String)).returns(Prism::ParseLexResult) } + def self.parse_lex_file(filepath, command_line: nil, encoding: nil, freeze: nil, frozen_string_literal: nil, line: nil, main_script: nil, partial_script: nil, scopes: nil, version: nil); end + + sig { params(source: String, command_line: T.nilable(String), encoding: T.nilable(T.any(FalseClass, Encoding)), filepath: T.nilable(String), freeze: T.nilable(T::Boolean), frozen_string_literal: T.nilable(T::Boolean), line: T.nilable(Integer), main_script: T.nilable(T::Boolean), partial_script: T.nilable(T::Boolean), scopes: T.nilable(T::Array[T::Array[Symbol]]), version: T.nilable(String)).returns(T::Boolean) } + def self.parse_success?(source, command_line: nil, encoding: nil, filepath: nil, freeze: nil, frozen_string_literal: nil, line: nil, main_script: nil, partial_script: nil, scopes: nil, version: nil); end + + sig { params(source: String, command_line: T.nilable(String), encoding: T.nilable(T.any(FalseClass, Encoding)), filepath: T.nilable(String), freeze: T.nilable(T::Boolean), frozen_string_literal: T.nilable(T::Boolean), line: T.nilable(Integer), main_script: T.nilable(T::Boolean), partial_script: T.nilable(T::Boolean), scopes: T.nilable(T::Array[T::Array[Symbol]]), version: T.nilable(String)).returns(T::Boolean) } + def self.parse_failure?(source, command_line: nil, encoding: nil, filepath: nil, freeze: nil, frozen_string_literal: nil, line: nil, main_script: nil, partial_script: nil, scopes: nil, version: nil); end + + sig { params(filepath: String, command_line: T.nilable(String), encoding: T.nilable(T.any(FalseClass, Encoding)), freeze: T.nilable(T::Boolean), frozen_string_literal: T.nilable(T::Boolean), line: T.nilable(Integer), main_script: T.nilable(T::Boolean), partial_script: T.nilable(T::Boolean), scopes: T.nilable(T::Array[T::Array[Symbol]]), version: T.nilable(String)).returns(T::Boolean) } + def self.parse_file_success?(filepath, command_line: nil, encoding: nil, freeze: nil, frozen_string_literal: nil, line: nil, main_script: nil, partial_script: nil, scopes: nil, version: nil); end + + sig { params(filepath: String, command_line: T.nilable(String), encoding: T.nilable(T.any(FalseClass, Encoding)), freeze: T.nilable(T::Boolean), frozen_string_literal: T.nilable(T::Boolean), line: T.nilable(Integer), main_script: T.nilable(T::Boolean), partial_script: T.nilable(T::Boolean), scopes: T.nilable(T::Array[T::Array[Symbol]]), version: T.nilable(String)).returns(T::Boolean) } + def self.parse_file_failure?(filepath, command_line: nil, encoding: nil, freeze: nil, frozen_string_literal: nil, line: nil, main_script: nil, partial_script: nil, scopes: nil, version: nil); end + + sig { params(locals: T::Array[Symbol], forwarding: T::Array[Symbol]).returns(Prism::Scope) } + def self.scope(locals: [], forwarding: []); end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/compiler.rbi b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/compiler.rbi new file mode 100644 index 00000000..c738236d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/compiler.rbi @@ -0,0 +1,12 @@ +# typed: strict + +class Prism::Compiler + sig { params(node: T.nilable(Prism::Node)).returns(T.untyped) } + def visit(node); end + + sig { params(nodes: T::Array[T.nilable(Prism::Node)]).returns(T::Array[T.untyped]) } + def visit_all(nodes); end + + sig { params(node: Prism::Node).returns(T::Array[T.untyped]) } + def visit_child_nodes(node); end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/dsl.rbi b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/dsl.rbi new file mode 100644 index 00000000..3d6559c5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/dsl.rbi @@ -0,0 +1,524 @@ +# typed: strict + +=begin +This file is generated by the templates/template.rb script and should not be +modified manually. See templates/rbi/prism/dsl.rbi.erb +if you are looking to modify the template +=end + +module Prism::DSL + sig { params(string: String).returns(Prism::Source) } + def source(string); end + + sig { params(source: Prism::Source, start_offset: Integer, length: Integer).returns(Prism::Location) } + def location(source: default_source, start_offset: 0, length: 0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, new_name: T.any(Prism::GlobalVariableReadNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode), old_name: T.any(Prism::GlobalVariableReadNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode, Prism::SymbolNode, Prism::MissingNode), keyword_loc: Prism::Location).returns(Prism::AliasGlobalVariableNode) } + def alias_global_variable_node(source: default_source, node_id: 0, location: default_location, flags: 0, new_name: global_variable_read_node(source: source), old_name: global_variable_read_node(source: source), keyword_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, new_name: T.any(Prism::SymbolNode, Prism::InterpolatedSymbolNode), old_name: T.any(Prism::SymbolNode, Prism::InterpolatedSymbolNode, Prism::GlobalVariableReadNode, Prism::MissingNode), keyword_loc: Prism::Location).returns(Prism::AliasMethodNode) } + def alias_method_node(source: default_source, node_id: 0, location: default_location, flags: 0, new_name: symbol_node(source: source), old_name: symbol_node(source: source), keyword_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, left: Prism::Node, right: Prism::Node, operator_loc: Prism::Location).returns(Prism::AlternationPatternNode) } + def alternation_pattern_node(source: default_source, node_id: 0, location: default_location, flags: 0, left: default_node(source, location), right: default_node(source, location), operator_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, left: Prism::Node, right: Prism::Node, operator_loc: Prism::Location).returns(Prism::AndNode) } + def and_node(source: default_source, node_id: 0, location: default_location, flags: 0, left: default_node(source, location), right: default_node(source, location), operator_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, arguments: T::Array[Prism::Node]).returns(Prism::ArgumentsNode) } + def arguments_node(source: default_source, node_id: 0, location: default_location, flags: 0, arguments: []); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, elements: T::Array[Prism::Node], opening_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location)).returns(Prism::ArrayNode) } + def array_node(source: default_source, node_id: 0, location: default_location, flags: 0, elements: [], opening_loc: nil, closing_loc: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, constant: T.nilable(T.any(Prism::ConstantReadNode, Prism::ConstantPathNode)), requireds: T::Array[Prism::Node], rest: T.nilable(Prism::Node), posts: T::Array[Prism::Node], opening_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location)).returns(Prism::ArrayPatternNode) } + def array_pattern_node(source: default_source, node_id: 0, location: default_location, flags: 0, constant: nil, requireds: [], rest: nil, posts: [], opening_loc: nil, closing_loc: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, key: Prism::Node, value: Prism::Node, operator_loc: T.nilable(Prism::Location)).returns(Prism::AssocNode) } + def assoc_node(source: default_source, node_id: 0, location: default_location, flags: 0, key: default_node(source, location), value: default_node(source, location), operator_loc: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, value: T.nilable(Prism::Node), operator_loc: Prism::Location).returns(Prism::AssocSplatNode) } + def assoc_splat_node(source: default_source, node_id: 0, location: default_location, flags: 0, value: nil, operator_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).returns(Prism::BackReferenceReadNode) } + def back_reference_read_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :""); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, begin_keyword_loc: T.nilable(Prism::Location), statements: T.nilable(Prism::StatementsNode), rescue_clause: T.nilable(Prism::RescueNode), else_clause: T.nilable(Prism::ElseNode), ensure_clause: T.nilable(Prism::EnsureNode), end_keyword_loc: T.nilable(Prism::Location)).returns(Prism::BeginNode) } + def begin_node(source: default_source, node_id: 0, location: default_location, flags: 0, begin_keyword_loc: nil, statements: nil, rescue_clause: nil, else_clause: nil, ensure_clause: nil, end_keyword_loc: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, expression: T.nilable(Prism::Node), operator_loc: Prism::Location).returns(Prism::BlockArgumentNode) } + def block_argument_node(source: default_source, node_id: 0, location: default_location, flags: 0, expression: nil, operator_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).returns(Prism::BlockLocalVariableNode) } + def block_local_variable_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :""); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, locals: T::Array[Symbol], parameters: T.nilable(T.any(Prism::BlockParametersNode, Prism::NumberedParametersNode, Prism::ItParametersNode)), body: T.nilable(T.any(Prism::StatementsNode, Prism::BeginNode)), opening_loc: Prism::Location, closing_loc: Prism::Location).returns(Prism::BlockNode) } + def block_node(source: default_source, node_id: 0, location: default_location, flags: 0, locals: [], parameters: nil, body: nil, opening_loc: location, closing_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: T.nilable(Symbol), name_loc: T.nilable(Prism::Location), operator_loc: Prism::Location).returns(Prism::BlockParameterNode) } + def block_parameter_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: nil, name_loc: nil, operator_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, parameters: T.nilable(Prism::ParametersNode), locals: T::Array[Prism::BlockLocalVariableNode], opening_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location)).returns(Prism::BlockParametersNode) } + def block_parameters_node(source: default_source, node_id: 0, location: default_location, flags: 0, parameters: nil, locals: [], opening_loc: nil, closing_loc: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, arguments: T.nilable(Prism::ArgumentsNode), keyword_loc: Prism::Location).returns(Prism::BreakNode) } + def break_node(source: default_source, node_id: 0, location: default_location, flags: 0, arguments: nil, keyword_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, receiver: T.nilable(Prism::Node), call_operator_loc: T.nilable(Prism::Location), message_loc: T.nilable(Prism::Location), read_name: Symbol, write_name: Symbol, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::CallAndWriteNode) } + def call_and_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, receiver: nil, call_operator_loc: nil, message_loc: nil, read_name: :"", write_name: :"", operator_loc: location, value: default_node(source, location)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, receiver: T.nilable(Prism::Node), call_operator_loc: T.nilable(Prism::Location), name: Symbol, message_loc: T.nilable(Prism::Location), opening_loc: T.nilable(Prism::Location), arguments: T.nilable(Prism::ArgumentsNode), closing_loc: T.nilable(Prism::Location), block: T.nilable(T.any(Prism::BlockNode, Prism::BlockArgumentNode))).returns(Prism::CallNode) } + def call_node(source: default_source, node_id: 0, location: default_location, flags: 0, receiver: nil, call_operator_loc: nil, name: :"", message_loc: nil, opening_loc: nil, arguments: nil, closing_loc: nil, block: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, receiver: T.nilable(Prism::Node), call_operator_loc: T.nilable(Prism::Location), message_loc: T.nilable(Prism::Location), read_name: Symbol, write_name: Symbol, binary_operator: Symbol, binary_operator_loc: Prism::Location, value: Prism::Node).returns(Prism::CallOperatorWriteNode) } + def call_operator_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, receiver: nil, call_operator_loc: nil, message_loc: nil, read_name: :"", write_name: :"", binary_operator: :"", binary_operator_loc: location, value: default_node(source, location)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, receiver: T.nilable(Prism::Node), call_operator_loc: T.nilable(Prism::Location), message_loc: T.nilable(Prism::Location), read_name: Symbol, write_name: Symbol, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::CallOrWriteNode) } + def call_or_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, receiver: nil, call_operator_loc: nil, message_loc: nil, read_name: :"", write_name: :"", operator_loc: location, value: default_node(source, location)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, receiver: Prism::Node, call_operator_loc: Prism::Location, name: Symbol, message_loc: Prism::Location).returns(Prism::CallTargetNode) } + def call_target_node(source: default_source, node_id: 0, location: default_location, flags: 0, receiver: default_node(source, location), call_operator_loc: location, name: :"", message_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, value: Prism::Node, target: Prism::LocalVariableTargetNode, operator_loc: Prism::Location).returns(Prism::CapturePatternNode) } + def capture_pattern_node(source: default_source, node_id: 0, location: default_location, flags: 0, value: default_node(source, location), target: local_variable_target_node(source: source), operator_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, predicate: T.nilable(Prism::Node), conditions: T::Array[Prism::InNode], else_clause: T.nilable(Prism::ElseNode), case_keyword_loc: Prism::Location, end_keyword_loc: Prism::Location).returns(Prism::CaseMatchNode) } + def case_match_node(source: default_source, node_id: 0, location: default_location, flags: 0, predicate: nil, conditions: [], else_clause: nil, case_keyword_loc: location, end_keyword_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, predicate: T.nilable(Prism::Node), conditions: T::Array[Prism::WhenNode], else_clause: T.nilable(Prism::ElseNode), case_keyword_loc: Prism::Location, end_keyword_loc: Prism::Location).returns(Prism::CaseNode) } + def case_node(source: default_source, node_id: 0, location: default_location, flags: 0, predicate: nil, conditions: [], else_clause: nil, case_keyword_loc: location, end_keyword_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, locals: T::Array[Symbol], class_keyword_loc: Prism::Location, constant_path: T.any(Prism::ConstantReadNode, Prism::ConstantPathNode, Prism::CallNode), inheritance_operator_loc: T.nilable(Prism::Location), superclass: T.nilable(Prism::Node), body: T.nilable(T.any(Prism::StatementsNode, Prism::BeginNode)), end_keyword_loc: Prism::Location, name: Symbol).returns(Prism::ClassNode) } + def class_node(source: default_source, node_id: 0, location: default_location, flags: 0, locals: [], class_keyword_loc: location, constant_path: constant_read_node(source: source), inheritance_operator_loc: nil, superclass: nil, body: nil, end_keyword_loc: location, name: :""); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::ClassVariableAndWriteNode) } + def class_variable_and_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, operator_loc: location, value: default_node(source, location)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, binary_operator_loc: Prism::Location, value: Prism::Node, binary_operator: Symbol).returns(Prism::ClassVariableOperatorWriteNode) } + def class_variable_operator_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, binary_operator_loc: location, value: default_node(source, location), binary_operator: :""); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::ClassVariableOrWriteNode) } + def class_variable_or_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, operator_loc: location, value: default_node(source, location)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).returns(Prism::ClassVariableReadNode) } + def class_variable_read_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :""); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).returns(Prism::ClassVariableTargetNode) } + def class_variable_target_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :""); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, value: Prism::Node, operator_loc: Prism::Location).returns(Prism::ClassVariableWriteNode) } + def class_variable_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, value: default_node(source, location), operator_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::ConstantAndWriteNode) } + def constant_and_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, operator_loc: location, value: default_node(source, location)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, binary_operator_loc: Prism::Location, value: Prism::Node, binary_operator: Symbol).returns(Prism::ConstantOperatorWriteNode) } + def constant_operator_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, binary_operator_loc: location, value: default_node(source, location), binary_operator: :""); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::ConstantOrWriteNode) } + def constant_or_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, operator_loc: location, value: default_node(source, location)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, target: Prism::ConstantPathNode, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::ConstantPathAndWriteNode) } + def constant_path_and_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, target: constant_path_node(source: source), operator_loc: location, value: default_node(source, location)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, parent: T.nilable(Prism::Node), name: T.nilable(Symbol), delimiter_loc: Prism::Location, name_loc: Prism::Location).returns(Prism::ConstantPathNode) } + def constant_path_node(source: default_source, node_id: 0, location: default_location, flags: 0, parent: nil, name: nil, delimiter_loc: location, name_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, target: Prism::ConstantPathNode, binary_operator_loc: Prism::Location, value: Prism::Node, binary_operator: Symbol).returns(Prism::ConstantPathOperatorWriteNode) } + def constant_path_operator_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, target: constant_path_node(source: source), binary_operator_loc: location, value: default_node(source, location), binary_operator: :""); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, target: Prism::ConstantPathNode, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::ConstantPathOrWriteNode) } + def constant_path_or_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, target: constant_path_node(source: source), operator_loc: location, value: default_node(source, location)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, parent: T.nilable(Prism::Node), name: T.nilable(Symbol), delimiter_loc: Prism::Location, name_loc: Prism::Location).returns(Prism::ConstantPathTargetNode) } + def constant_path_target_node(source: default_source, node_id: 0, location: default_location, flags: 0, parent: nil, name: nil, delimiter_loc: location, name_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, target: Prism::ConstantPathNode, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::ConstantPathWriteNode) } + def constant_path_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, target: constant_path_node(source: source), operator_loc: location, value: default_node(source, location)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).returns(Prism::ConstantReadNode) } + def constant_read_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :""); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).returns(Prism::ConstantTargetNode) } + def constant_target_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :""); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, value: Prism::Node, operator_loc: Prism::Location).returns(Prism::ConstantWriteNode) } + def constant_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, value: default_node(source, location), operator_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, receiver: T.nilable(Prism::Node), parameters: T.nilable(Prism::ParametersNode), body: T.nilable(T.any(Prism::StatementsNode, Prism::BeginNode)), locals: T::Array[Symbol], def_keyword_loc: Prism::Location, operator_loc: T.nilable(Prism::Location), lparen_loc: T.nilable(Prism::Location), rparen_loc: T.nilable(Prism::Location), equal_loc: T.nilable(Prism::Location), end_keyword_loc: T.nilable(Prism::Location)).returns(Prism::DefNode) } + def def_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, receiver: nil, parameters: nil, body: nil, locals: [], def_keyword_loc: location, operator_loc: nil, lparen_loc: nil, rparen_loc: nil, equal_loc: nil, end_keyword_loc: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, lparen_loc: T.nilable(Prism::Location), value: Prism::Node, rparen_loc: T.nilable(Prism::Location), keyword_loc: Prism::Location).returns(Prism::DefinedNode) } + def defined_node(source: default_source, node_id: 0, location: default_location, flags: 0, lparen_loc: nil, value: default_node(source, location), rparen_loc: nil, keyword_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, else_keyword_loc: Prism::Location, statements: T.nilable(Prism::StatementsNode), end_keyword_loc: T.nilable(Prism::Location)).returns(Prism::ElseNode) } + def else_node(source: default_source, node_id: 0, location: default_location, flags: 0, else_keyword_loc: location, statements: nil, end_keyword_loc: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: Prism::Location, statements: T.nilable(Prism::StatementsNode), closing_loc: Prism::Location).returns(Prism::EmbeddedStatementsNode) } + def embedded_statements_node(source: default_source, node_id: 0, location: default_location, flags: 0, opening_loc: location, statements: nil, closing_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, operator_loc: Prism::Location, variable: T.any(Prism::InstanceVariableReadNode, Prism::ClassVariableReadNode, Prism::GlobalVariableReadNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode)).returns(Prism::EmbeddedVariableNode) } + def embedded_variable_node(source: default_source, node_id: 0, location: default_location, flags: 0, operator_loc: location, variable: instance_variable_read_node(source: source)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, ensure_keyword_loc: Prism::Location, statements: T.nilable(Prism::StatementsNode), end_keyword_loc: Prism::Location).returns(Prism::EnsureNode) } + def ensure_node(source: default_source, node_id: 0, location: default_location, flags: 0, ensure_keyword_loc: location, statements: nil, end_keyword_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::FalseNode) } + def false_node(source: default_source, node_id: 0, location: default_location, flags: 0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, constant: T.nilable(T.any(Prism::ConstantReadNode, Prism::ConstantPathNode)), left: Prism::SplatNode, requireds: T::Array[Prism::Node], right: T.any(Prism::SplatNode, Prism::MissingNode), opening_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location)).returns(Prism::FindPatternNode) } + def find_pattern_node(source: default_source, node_id: 0, location: default_location, flags: 0, constant: nil, left: splat_node(source: source), requireds: [], right: splat_node(source: source), opening_loc: nil, closing_loc: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, left: T.nilable(Prism::Node), right: T.nilable(Prism::Node), operator_loc: Prism::Location).returns(Prism::FlipFlopNode) } + def flip_flop_node(source: default_source, node_id: 0, location: default_location, flags: 0, left: nil, right: nil, operator_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, value: Float).returns(Prism::FloatNode) } + def float_node(source: default_source, node_id: 0, location: default_location, flags: 0, value: 0.0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, index: T.any(Prism::LocalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::ConstantTargetNode, Prism::ConstantPathTargetNode, Prism::CallTargetNode, Prism::IndexTargetNode, Prism::MultiTargetNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode, Prism::MissingNode), collection: Prism::Node, statements: T.nilable(Prism::StatementsNode), for_keyword_loc: Prism::Location, in_keyword_loc: Prism::Location, do_keyword_loc: T.nilable(Prism::Location), end_keyword_loc: Prism::Location).returns(Prism::ForNode) } + def for_node(source: default_source, node_id: 0, location: default_location, flags: 0, index: local_variable_target_node(source: source), collection: default_node(source, location), statements: nil, for_keyword_loc: location, in_keyword_loc: location, do_keyword_loc: nil, end_keyword_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::ForwardingArgumentsNode) } + def forwarding_arguments_node(source: default_source, node_id: 0, location: default_location, flags: 0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::ForwardingParameterNode) } + def forwarding_parameter_node(source: default_source, node_id: 0, location: default_location, flags: 0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, block: T.nilable(Prism::BlockNode)).returns(Prism::ForwardingSuperNode) } + def forwarding_super_node(source: default_source, node_id: 0, location: default_location, flags: 0, block: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::GlobalVariableAndWriteNode) } + def global_variable_and_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, operator_loc: location, value: default_node(source, location)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, binary_operator_loc: Prism::Location, value: Prism::Node, binary_operator: Symbol).returns(Prism::GlobalVariableOperatorWriteNode) } + def global_variable_operator_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, binary_operator_loc: location, value: default_node(source, location), binary_operator: :""); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::GlobalVariableOrWriteNode) } + def global_variable_or_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, operator_loc: location, value: default_node(source, location)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).returns(Prism::GlobalVariableReadNode) } + def global_variable_read_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :""); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).returns(Prism::GlobalVariableTargetNode) } + def global_variable_target_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :""); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, value: Prism::Node, operator_loc: Prism::Location).returns(Prism::GlobalVariableWriteNode) } + def global_variable_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, value: default_node(source, location), operator_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: Prism::Location, elements: T::Array[T.any(Prism::AssocNode, Prism::AssocSplatNode)], closing_loc: Prism::Location).returns(Prism::HashNode) } + def hash_node(source: default_source, node_id: 0, location: default_location, flags: 0, opening_loc: location, elements: [], closing_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, constant: T.nilable(T.any(Prism::ConstantReadNode, Prism::ConstantPathNode)), elements: T::Array[Prism::AssocNode], rest: T.nilable(T.any(Prism::AssocSplatNode, Prism::NoKeywordsParameterNode)), opening_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location)).returns(Prism::HashPatternNode) } + def hash_pattern_node(source: default_source, node_id: 0, location: default_location, flags: 0, constant: nil, elements: [], rest: nil, opening_loc: nil, closing_loc: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, if_keyword_loc: T.nilable(Prism::Location), predicate: Prism::Node, then_keyword_loc: T.nilable(Prism::Location), statements: T.nilable(Prism::StatementsNode), subsequent: T.nilable(T.any(Prism::ElseNode, Prism::IfNode)), end_keyword_loc: T.nilable(Prism::Location)).returns(Prism::IfNode) } + def if_node(source: default_source, node_id: 0, location: default_location, flags: 0, if_keyword_loc: nil, predicate: default_node(source, location), then_keyword_loc: nil, statements: nil, subsequent: nil, end_keyword_loc: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, numeric: T.any(Prism::FloatNode, Prism::IntegerNode, Prism::RationalNode)).returns(Prism::ImaginaryNode) } + def imaginary_node(source: default_source, node_id: 0, location: default_location, flags: 0, numeric: float_node(source: source)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, value: T.any(Prism::LocalVariableReadNode, Prism::CallNode, Prism::ConstantReadNode, Prism::LocalVariableTargetNode)).returns(Prism::ImplicitNode) } + def implicit_node(source: default_source, node_id: 0, location: default_location, flags: 0, value: local_variable_read_node(source: source)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::ImplicitRestNode) } + def implicit_rest_node(source: default_source, node_id: 0, location: default_location, flags: 0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, pattern: Prism::Node, statements: T.nilable(Prism::StatementsNode), in_loc: Prism::Location, then_loc: T.nilable(Prism::Location)).returns(Prism::InNode) } + def in_node(source: default_source, node_id: 0, location: default_location, flags: 0, pattern: default_node(source, location), statements: nil, in_loc: location, then_loc: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, receiver: T.nilable(Prism::Node), call_operator_loc: T.nilable(Prism::Location), opening_loc: Prism::Location, arguments: T.nilable(Prism::ArgumentsNode), closing_loc: Prism::Location, block: T.nilable(Prism::BlockArgumentNode), operator_loc: Prism::Location, value: Prism::Node).returns(Prism::IndexAndWriteNode) } + def index_and_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, receiver: nil, call_operator_loc: nil, opening_loc: location, arguments: nil, closing_loc: location, block: nil, operator_loc: location, value: default_node(source, location)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, receiver: T.nilable(Prism::Node), call_operator_loc: T.nilable(Prism::Location), opening_loc: Prism::Location, arguments: T.nilable(Prism::ArgumentsNode), closing_loc: Prism::Location, block: T.nilable(Prism::BlockArgumentNode), binary_operator: Symbol, binary_operator_loc: Prism::Location, value: Prism::Node).returns(Prism::IndexOperatorWriteNode) } + def index_operator_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, receiver: nil, call_operator_loc: nil, opening_loc: location, arguments: nil, closing_loc: location, block: nil, binary_operator: :"", binary_operator_loc: location, value: default_node(source, location)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, receiver: T.nilable(Prism::Node), call_operator_loc: T.nilable(Prism::Location), opening_loc: Prism::Location, arguments: T.nilable(Prism::ArgumentsNode), closing_loc: Prism::Location, block: T.nilable(Prism::BlockArgumentNode), operator_loc: Prism::Location, value: Prism::Node).returns(Prism::IndexOrWriteNode) } + def index_or_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, receiver: nil, call_operator_loc: nil, opening_loc: location, arguments: nil, closing_loc: location, block: nil, operator_loc: location, value: default_node(source, location)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, receiver: Prism::Node, opening_loc: Prism::Location, arguments: T.nilable(Prism::ArgumentsNode), closing_loc: Prism::Location, block: T.nilable(Prism::BlockArgumentNode)).returns(Prism::IndexTargetNode) } + def index_target_node(source: default_source, node_id: 0, location: default_location, flags: 0, receiver: default_node(source, location), opening_loc: location, arguments: nil, closing_loc: location, block: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::InstanceVariableAndWriteNode) } + def instance_variable_and_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, operator_loc: location, value: default_node(source, location)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, binary_operator_loc: Prism::Location, value: Prism::Node, binary_operator: Symbol).returns(Prism::InstanceVariableOperatorWriteNode) } + def instance_variable_operator_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, binary_operator_loc: location, value: default_node(source, location), binary_operator: :""); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::InstanceVariableOrWriteNode) } + def instance_variable_or_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, operator_loc: location, value: default_node(source, location)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).returns(Prism::InstanceVariableReadNode) } + def instance_variable_read_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :""); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).returns(Prism::InstanceVariableTargetNode) } + def instance_variable_target_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :""); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, value: Prism::Node, operator_loc: Prism::Location).returns(Prism::InstanceVariableWriteNode) } + def instance_variable_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, value: default_node(source, location), operator_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, value: Integer).returns(Prism::IntegerNode) } + def integer_node(source: default_source, node_id: 0, location: default_location, flags: 0, value: 0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: Prism::Location, parts: T::Array[T.any(Prism::StringNode, Prism::EmbeddedStatementsNode, Prism::EmbeddedVariableNode)], closing_loc: Prism::Location).returns(Prism::InterpolatedMatchLastLineNode) } + def interpolated_match_last_line_node(source: default_source, node_id: 0, location: default_location, flags: 0, opening_loc: location, parts: [], closing_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: Prism::Location, parts: T::Array[T.any(Prism::StringNode, Prism::EmbeddedStatementsNode, Prism::EmbeddedVariableNode)], closing_loc: Prism::Location).returns(Prism::InterpolatedRegularExpressionNode) } + def interpolated_regular_expression_node(source: default_source, node_id: 0, location: default_location, flags: 0, opening_loc: location, parts: [], closing_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: T.nilable(Prism::Location), parts: T::Array[T.any(Prism::StringNode, Prism::EmbeddedStatementsNode, Prism::EmbeddedVariableNode, Prism::InterpolatedStringNode, Prism::XStringNode)], closing_loc: T.nilable(Prism::Location)).returns(Prism::InterpolatedStringNode) } + def interpolated_string_node(source: default_source, node_id: 0, location: default_location, flags: 0, opening_loc: nil, parts: [], closing_loc: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: T.nilable(Prism::Location), parts: T::Array[T.any(Prism::StringNode, Prism::EmbeddedStatementsNode, Prism::EmbeddedVariableNode)], closing_loc: T.nilable(Prism::Location)).returns(Prism::InterpolatedSymbolNode) } + def interpolated_symbol_node(source: default_source, node_id: 0, location: default_location, flags: 0, opening_loc: nil, parts: [], closing_loc: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: Prism::Location, parts: T::Array[T.any(Prism::StringNode, Prism::EmbeddedStatementsNode, Prism::EmbeddedVariableNode)], closing_loc: Prism::Location).returns(Prism::InterpolatedXStringNode) } + def interpolated_x_string_node(source: default_source, node_id: 0, location: default_location, flags: 0, opening_loc: location, parts: [], closing_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::ItLocalVariableReadNode) } + def it_local_variable_read_node(source: default_source, node_id: 0, location: default_location, flags: 0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::ItParametersNode) } + def it_parameters_node(source: default_source, node_id: 0, location: default_location, flags: 0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, elements: T::Array[T.any(Prism::AssocNode, Prism::AssocSplatNode)]).returns(Prism::KeywordHashNode) } + def keyword_hash_node(source: default_source, node_id: 0, location: default_location, flags: 0, elements: []); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: T.nilable(Symbol), name_loc: T.nilable(Prism::Location), operator_loc: Prism::Location).returns(Prism::KeywordRestParameterNode) } + def keyword_rest_parameter_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: nil, name_loc: nil, operator_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, locals: T::Array[Symbol], operator_loc: Prism::Location, opening_loc: Prism::Location, closing_loc: Prism::Location, parameters: T.nilable(T.any(Prism::BlockParametersNode, Prism::NumberedParametersNode, Prism::ItParametersNode)), body: T.nilable(T.any(Prism::StatementsNode, Prism::BeginNode))).returns(Prism::LambdaNode) } + def lambda_node(source: default_source, node_id: 0, location: default_location, flags: 0, locals: [], operator_loc: location, opening_loc: location, closing_loc: location, parameters: nil, body: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node, name: Symbol, depth: Integer).returns(Prism::LocalVariableAndWriteNode) } + def local_variable_and_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name_loc: location, operator_loc: location, value: default_node(source, location), name: :"", depth: 0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name_loc: Prism::Location, binary_operator_loc: Prism::Location, value: Prism::Node, name: Symbol, binary_operator: Symbol, depth: Integer).returns(Prism::LocalVariableOperatorWriteNode) } + def local_variable_operator_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name_loc: location, binary_operator_loc: location, value: default_node(source, location), name: :"", binary_operator: :"", depth: 0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node, name: Symbol, depth: Integer).returns(Prism::LocalVariableOrWriteNode) } + def local_variable_or_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name_loc: location, operator_loc: location, value: default_node(source, location), name: :"", depth: 0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, depth: Integer).returns(Prism::LocalVariableReadNode) } + def local_variable_read_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", depth: 0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, depth: Integer).returns(Prism::LocalVariableTargetNode) } + def local_variable_target_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", depth: 0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, depth: Integer, name_loc: Prism::Location, value: Prism::Node, operator_loc: Prism::Location).returns(Prism::LocalVariableWriteNode) } + def local_variable_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", depth: 0, name_loc: location, value: default_node(source, location), operator_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: Prism::Location, content_loc: Prism::Location, closing_loc: Prism::Location, unescaped: String).returns(Prism::MatchLastLineNode) } + def match_last_line_node(source: default_source, node_id: 0, location: default_location, flags: 0, opening_loc: location, content_loc: location, closing_loc: location, unescaped: ""); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, value: Prism::Node, pattern: Prism::Node, operator_loc: Prism::Location).returns(Prism::MatchPredicateNode) } + def match_predicate_node(source: default_source, node_id: 0, location: default_location, flags: 0, value: default_node(source, location), pattern: default_node(source, location), operator_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, value: Prism::Node, pattern: Prism::Node, operator_loc: Prism::Location).returns(Prism::MatchRequiredNode) } + def match_required_node(source: default_source, node_id: 0, location: default_location, flags: 0, value: default_node(source, location), pattern: default_node(source, location), operator_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, call: Prism::CallNode, targets: T::Array[Prism::LocalVariableTargetNode]).returns(Prism::MatchWriteNode) } + def match_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, call: call_node(source: source), targets: []); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::MissingNode) } + def missing_node(source: default_source, node_id: 0, location: default_location, flags: 0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, locals: T::Array[Symbol], module_keyword_loc: Prism::Location, constant_path: T.any(Prism::ConstantReadNode, Prism::ConstantPathNode, Prism::MissingNode), body: T.nilable(T.any(Prism::StatementsNode, Prism::BeginNode)), end_keyword_loc: Prism::Location, name: Symbol).returns(Prism::ModuleNode) } + def module_node(source: default_source, node_id: 0, location: default_location, flags: 0, locals: [], module_keyword_loc: location, constant_path: constant_read_node(source: source), body: nil, end_keyword_loc: location, name: :""); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, lefts: T::Array[T.any(Prism::LocalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::ConstantTargetNode, Prism::ConstantPathTargetNode, Prism::CallTargetNode, Prism::IndexTargetNode, Prism::MultiTargetNode, Prism::RequiredParameterNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode)], rest: T.nilable(T.any(Prism::ImplicitRestNode, Prism::SplatNode)), rights: T::Array[T.any(Prism::LocalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::ConstantTargetNode, Prism::ConstantPathTargetNode, Prism::CallTargetNode, Prism::IndexTargetNode, Prism::MultiTargetNode, Prism::RequiredParameterNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode)], lparen_loc: T.nilable(Prism::Location), rparen_loc: T.nilable(Prism::Location)).returns(Prism::MultiTargetNode) } + def multi_target_node(source: default_source, node_id: 0, location: default_location, flags: 0, lefts: [], rest: nil, rights: [], lparen_loc: nil, rparen_loc: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, lefts: T::Array[T.any(Prism::LocalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::ConstantTargetNode, Prism::ConstantPathTargetNode, Prism::CallTargetNode, Prism::IndexTargetNode, Prism::MultiTargetNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode)], rest: T.nilable(T.any(Prism::ImplicitRestNode, Prism::SplatNode)), rights: T::Array[T.any(Prism::LocalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::ConstantTargetNode, Prism::ConstantPathTargetNode, Prism::CallTargetNode, Prism::IndexTargetNode, Prism::MultiTargetNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode)], lparen_loc: T.nilable(Prism::Location), rparen_loc: T.nilable(Prism::Location), operator_loc: Prism::Location, value: Prism::Node).returns(Prism::MultiWriteNode) } + def multi_write_node(source: default_source, node_id: 0, location: default_location, flags: 0, lefts: [], rest: nil, rights: [], lparen_loc: nil, rparen_loc: nil, operator_loc: location, value: default_node(source, location)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, arguments: T.nilable(Prism::ArgumentsNode), keyword_loc: Prism::Location).returns(Prism::NextNode) } + def next_node(source: default_source, node_id: 0, location: default_location, flags: 0, arguments: nil, keyword_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::NilNode) } + def nil_node(source: default_source, node_id: 0, location: default_location, flags: 0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, operator_loc: Prism::Location, keyword_loc: Prism::Location).returns(Prism::NoKeywordsParameterNode) } + def no_keywords_parameter_node(source: default_source, node_id: 0, location: default_location, flags: 0, operator_loc: location, keyword_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, maximum: Integer).returns(Prism::NumberedParametersNode) } + def numbered_parameters_node(source: default_source, node_id: 0, location: default_location, flags: 0, maximum: 0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, number: Integer).returns(Prism::NumberedReferenceReadNode) } + def numbered_reference_read_node(source: default_source, node_id: 0, location: default_location, flags: 0, number: 0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, value: Prism::Node).returns(Prism::OptionalKeywordParameterNode) } + def optional_keyword_parameter_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, value: default_node(source, location)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::OptionalParameterNode) } + def optional_parameter_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location, operator_loc: location, value: default_node(source, location)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, left: Prism::Node, right: Prism::Node, operator_loc: Prism::Location).returns(Prism::OrNode) } + def or_node(source: default_source, node_id: 0, location: default_location, flags: 0, left: default_node(source, location), right: default_node(source, location), operator_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, requireds: T::Array[T.any(Prism::RequiredParameterNode, Prism::MultiTargetNode)], optionals: T::Array[Prism::OptionalParameterNode], rest: T.nilable(T.any(Prism::RestParameterNode, Prism::ImplicitRestNode)), posts: T::Array[T.any(Prism::RequiredParameterNode, Prism::MultiTargetNode, Prism::KeywordRestParameterNode, Prism::NoKeywordsParameterNode, Prism::ForwardingParameterNode)], keywords: T::Array[T.any(Prism::RequiredKeywordParameterNode, Prism::OptionalKeywordParameterNode)], keyword_rest: T.nilable(T.any(Prism::KeywordRestParameterNode, Prism::ForwardingParameterNode, Prism::NoKeywordsParameterNode)), block: T.nilable(Prism::BlockParameterNode)).returns(Prism::ParametersNode) } + def parameters_node(source: default_source, node_id: 0, location: default_location, flags: 0, requireds: [], optionals: [], rest: nil, posts: [], keywords: [], keyword_rest: nil, block: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, body: T.nilable(Prism::Node), opening_loc: Prism::Location, closing_loc: Prism::Location).returns(Prism::ParenthesesNode) } + def parentheses_node(source: default_source, node_id: 0, location: default_location, flags: 0, body: nil, opening_loc: location, closing_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, expression: Prism::Node, operator_loc: Prism::Location, lparen_loc: Prism::Location, rparen_loc: Prism::Location).returns(Prism::PinnedExpressionNode) } + def pinned_expression_node(source: default_source, node_id: 0, location: default_location, flags: 0, expression: default_node(source, location), operator_loc: location, lparen_loc: location, rparen_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, variable: T.any(Prism::LocalVariableReadNode, Prism::InstanceVariableReadNode, Prism::ClassVariableReadNode, Prism::GlobalVariableReadNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode, Prism::ItLocalVariableReadNode, Prism::MissingNode), operator_loc: Prism::Location).returns(Prism::PinnedVariableNode) } + def pinned_variable_node(source: default_source, node_id: 0, location: default_location, flags: 0, variable: local_variable_read_node(source: source), operator_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, statements: T.nilable(Prism::StatementsNode), keyword_loc: Prism::Location, opening_loc: Prism::Location, closing_loc: Prism::Location).returns(Prism::PostExecutionNode) } + def post_execution_node(source: default_source, node_id: 0, location: default_location, flags: 0, statements: nil, keyword_loc: location, opening_loc: location, closing_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, statements: T.nilable(Prism::StatementsNode), keyword_loc: Prism::Location, opening_loc: Prism::Location, closing_loc: Prism::Location).returns(Prism::PreExecutionNode) } + def pre_execution_node(source: default_source, node_id: 0, location: default_location, flags: 0, statements: nil, keyword_loc: location, opening_loc: location, closing_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, locals: T::Array[Symbol], statements: Prism::StatementsNode).returns(Prism::ProgramNode) } + def program_node(source: default_source, node_id: 0, location: default_location, flags: 0, locals: [], statements: statements_node(source: source)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, left: T.nilable(Prism::Node), right: T.nilable(Prism::Node), operator_loc: Prism::Location).returns(Prism::RangeNode) } + def range_node(source: default_source, node_id: 0, location: default_location, flags: 0, left: nil, right: nil, operator_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, numerator: Integer, denominator: Integer).returns(Prism::RationalNode) } + def rational_node(source: default_source, node_id: 0, location: default_location, flags: 0, numerator: 0, denominator: 0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::RedoNode) } + def redo_node(source: default_source, node_id: 0, location: default_location, flags: 0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: Prism::Location, content_loc: Prism::Location, closing_loc: Prism::Location, unescaped: String).returns(Prism::RegularExpressionNode) } + def regular_expression_node(source: default_source, node_id: 0, location: default_location, flags: 0, opening_loc: location, content_loc: location, closing_loc: location, unescaped: ""); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location).returns(Prism::RequiredKeywordParameterNode) } + def required_keyword_parameter_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :"", name_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).returns(Prism::RequiredParameterNode) } + def required_parameter_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: :""); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, expression: Prism::Node, keyword_loc: Prism::Location, rescue_expression: Prism::Node).returns(Prism::RescueModifierNode) } + def rescue_modifier_node(source: default_source, node_id: 0, location: default_location, flags: 0, expression: default_node(source, location), keyword_loc: location, rescue_expression: default_node(source, location)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, keyword_loc: Prism::Location, exceptions: T::Array[Prism::Node], operator_loc: T.nilable(Prism::Location), reference: T.nilable(T.any(Prism::LocalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::ConstantTargetNode, Prism::ConstantPathTargetNode, Prism::CallTargetNode, Prism::IndexTargetNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode, Prism::MissingNode)), then_keyword_loc: T.nilable(Prism::Location), statements: T.nilable(Prism::StatementsNode), subsequent: T.nilable(Prism::RescueNode)).returns(Prism::RescueNode) } + def rescue_node(source: default_source, node_id: 0, location: default_location, flags: 0, keyword_loc: location, exceptions: [], operator_loc: nil, reference: nil, then_keyword_loc: nil, statements: nil, subsequent: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: T.nilable(Symbol), name_loc: T.nilable(Prism::Location), operator_loc: Prism::Location).returns(Prism::RestParameterNode) } + def rest_parameter_node(source: default_source, node_id: 0, location: default_location, flags: 0, name: nil, name_loc: nil, operator_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::RetryNode) } + def retry_node(source: default_source, node_id: 0, location: default_location, flags: 0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, keyword_loc: Prism::Location, arguments: T.nilable(Prism::ArgumentsNode)).returns(Prism::ReturnNode) } + def return_node(source: default_source, node_id: 0, location: default_location, flags: 0, keyword_loc: location, arguments: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::SelfNode) } + def self_node(source: default_source, node_id: 0, location: default_location, flags: 0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, write: T.any(Prism::ConstantWriteNode, Prism::ConstantAndWriteNode, Prism::ConstantOrWriteNode, Prism::ConstantOperatorWriteNode, Prism::ConstantPathWriteNode, Prism::ConstantPathAndWriteNode, Prism::ConstantPathOrWriteNode, Prism::ConstantPathOperatorWriteNode)).returns(Prism::ShareableConstantNode) } + def shareable_constant_node(source: default_source, node_id: 0, location: default_location, flags: 0, write: constant_write_node(source: source)); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, locals: T::Array[Symbol], class_keyword_loc: Prism::Location, operator_loc: Prism::Location, expression: Prism::Node, body: T.nilable(T.any(Prism::StatementsNode, Prism::BeginNode)), end_keyword_loc: Prism::Location).returns(Prism::SingletonClassNode) } + def singleton_class_node(source: default_source, node_id: 0, location: default_location, flags: 0, locals: [], class_keyword_loc: location, operator_loc: location, expression: default_node(source, location), body: nil, end_keyword_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::SourceEncodingNode) } + def source_encoding_node(source: default_source, node_id: 0, location: default_location, flags: 0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, filepath: String).returns(Prism::SourceFileNode) } + def source_file_node(source: default_source, node_id: 0, location: default_location, flags: 0, filepath: ""); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::SourceLineNode) } + def source_line_node(source: default_source, node_id: 0, location: default_location, flags: 0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, operator_loc: Prism::Location, expression: T.nilable(Prism::Node)).returns(Prism::SplatNode) } + def splat_node(source: default_source, node_id: 0, location: default_location, flags: 0, operator_loc: location, expression: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, body: T::Array[Prism::Node]).returns(Prism::StatementsNode) } + def statements_node(source: default_source, node_id: 0, location: default_location, flags: 0, body: []); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: T.nilable(Prism::Location), content_loc: Prism::Location, closing_loc: T.nilable(Prism::Location), unescaped: String).returns(Prism::StringNode) } + def string_node(source: default_source, node_id: 0, location: default_location, flags: 0, opening_loc: nil, content_loc: location, closing_loc: nil, unescaped: ""); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, keyword_loc: Prism::Location, lparen_loc: T.nilable(Prism::Location), arguments: T.nilable(Prism::ArgumentsNode), rparen_loc: T.nilable(Prism::Location), block: T.nilable(T.any(Prism::BlockNode, Prism::BlockArgumentNode))).returns(Prism::SuperNode) } + def super_node(source: default_source, node_id: 0, location: default_location, flags: 0, keyword_loc: location, lparen_loc: nil, arguments: nil, rparen_loc: nil, block: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: T.nilable(Prism::Location), value_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location), unescaped: String).returns(Prism::SymbolNode) } + def symbol_node(source: default_source, node_id: 0, location: default_location, flags: 0, opening_loc: nil, value_loc: nil, closing_loc: nil, unescaped: ""); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::TrueNode) } + def true_node(source: default_source, node_id: 0, location: default_location, flags: 0); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, names: T::Array[T.any(Prism::SymbolNode, Prism::InterpolatedSymbolNode)], keyword_loc: Prism::Location).returns(Prism::UndefNode) } + def undef_node(source: default_source, node_id: 0, location: default_location, flags: 0, names: [], keyword_loc: location); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, keyword_loc: Prism::Location, predicate: Prism::Node, then_keyword_loc: T.nilable(Prism::Location), statements: T.nilable(Prism::StatementsNode), else_clause: T.nilable(Prism::ElseNode), end_keyword_loc: T.nilable(Prism::Location)).returns(Prism::UnlessNode) } + def unless_node(source: default_source, node_id: 0, location: default_location, flags: 0, keyword_loc: location, predicate: default_node(source, location), then_keyword_loc: nil, statements: nil, else_clause: nil, end_keyword_loc: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, keyword_loc: Prism::Location, do_keyword_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location), predicate: Prism::Node, statements: T.nilable(Prism::StatementsNode)).returns(Prism::UntilNode) } + def until_node(source: default_source, node_id: 0, location: default_location, flags: 0, keyword_loc: location, do_keyword_loc: nil, closing_loc: nil, predicate: default_node(source, location), statements: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, keyword_loc: Prism::Location, conditions: T::Array[Prism::Node], then_keyword_loc: T.nilable(Prism::Location), statements: T.nilable(Prism::StatementsNode)).returns(Prism::WhenNode) } + def when_node(source: default_source, node_id: 0, location: default_location, flags: 0, keyword_loc: location, conditions: [], then_keyword_loc: nil, statements: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, keyword_loc: Prism::Location, do_keyword_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location), predicate: Prism::Node, statements: T.nilable(Prism::StatementsNode)).returns(Prism::WhileNode) } + def while_node(source: default_source, node_id: 0, location: default_location, flags: 0, keyword_loc: location, do_keyword_loc: nil, closing_loc: nil, predicate: default_node(source, location), statements: nil); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: Prism::Location, content_loc: Prism::Location, closing_loc: Prism::Location, unescaped: String).returns(Prism::XStringNode) } + def x_string_node(source: default_source, node_id: 0, location: default_location, flags: 0, opening_loc: location, content_loc: location, closing_loc: location, unescaped: ""); end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, keyword_loc: Prism::Location, lparen_loc: T.nilable(Prism::Location), arguments: T.nilable(Prism::ArgumentsNode), rparen_loc: T.nilable(Prism::Location)).returns(Prism::YieldNode) } + def yield_node(source: default_source, node_id: 0, location: default_location, flags: 0, keyword_loc: location, lparen_loc: nil, arguments: nil, rparen_loc: nil); end + + sig { params(name: Symbol).returns(Integer) } + def arguments_node_flag(name); end + + sig { params(name: Symbol).returns(Integer) } + def array_node_flag(name); end + + sig { params(name: Symbol).returns(Integer) } + def call_node_flag(name); end + + sig { params(name: Symbol).returns(Integer) } + def encoding_flag(name); end + + sig { params(name: Symbol).returns(Integer) } + def integer_base_flag(name); end + + sig { params(name: Symbol).returns(Integer) } + def interpolated_string_node_flag(name); end + + sig { params(name: Symbol).returns(Integer) } + def keyword_hash_node_flag(name); end + + sig { params(name: Symbol).returns(Integer) } + def loop_flag(name); end + + sig { params(name: Symbol).returns(Integer) } + def parameter_flag(name); end + + sig { params(name: Symbol).returns(Integer) } + def parentheses_node_flag(name); end + + sig { params(name: Symbol).returns(Integer) } + def range_flag(name); end + + sig { params(name: Symbol).returns(Integer) } + def regular_expression_flag(name); end + + sig { params(name: Symbol).returns(Integer) } + def shareable_constant_node_flag(name); end + + sig { params(name: Symbol).returns(Integer) } + def string_flag(name); end + + sig { params(name: Symbol).returns(Integer) } + def symbol_flag(name); end + + private + + sig { returns(Prism::Source) } + def default_source; end + + sig { returns(Prism::Location) } + def default_location; end + + sig { params(source: Prism::Source, location: Prism::Location).returns(Prism::Node) } + def default_node(source, location); end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/inspect_visitor.rbi b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/inspect_visitor.rbi new file mode 100644 index 00000000..bb0c2240 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/inspect_visitor.rbi @@ -0,0 +1,12 @@ +# typed: strict + +class Prism::InspectVisitor < Prism::Visitor + sig { params(indent: String).void } + def initialize(indent = ""); end + + sig { params(node: Prism::Node).returns(String) } + def self.compose(node); end + + sig { returns(String) } + def compose; end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/node.rbi b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/node.rbi new file mode 100644 index 00000000..45030f52 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/node.rbi @@ -0,0 +1,8722 @@ +# typed: strict + +=begin +This file is generated by the templates/template.rb script and should not be +modified manually. See templates/rbi/prism/node.rbi.erb +if you are looking to modify the template +=end + +class Prism::Node + abstract! + + sig { returns(Prism::Source) } + def source; end + + sig { returns(Integer) } + def node_id; end + + sig { returns(Prism::Location) } + def location; end + + sig{ returns(Integer) } + def flags; end + + sig { returns(T::Boolean) } + def newline?; end + + sig { returns(T::Boolean) } + def static_literal?; end + + sig { returns(Integer) } + def start_offset; end + + sig { returns(Integer) } + def end_offset; end + + sig { returns(T::Array[String]) } + def source_lines; end + + sig { returns(T::Array[String]) } + def script_lines; end + + sig { returns(String) } + def slice; end + + sig { returns(String) } + def slice_lines; end + + sig { params(q: T.untyped).void } + def pretty_print(q); end + + sig { returns(String) } + def to_dot; end + + sig { params(line: Integer, column: Integer).returns(T::Array[Prism::Node]) } + def tunnel(line, column); end + + sig { params(block: T.proc.params(node: Prism::Node).returns(T::Boolean)).returns(T.nilable(Prism::Node)) } + def breadth_first_search(&block); end + + sig { abstract.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { abstract.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { abstract.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { abstract.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { abstract.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { abstract.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { abstract.returns(Symbol) } + def type; end + + sig { abstract.returns(String) } + def inspect; end +end + +# Represents the use of the `alias` keyword to alias a global variable. +# +# alias $foo $bar +# ^^^^^^^^^^^^^^^ +class Prism::AliasGlobalVariableNode < Prism::Node + sig { returns(T.any(Prism::GlobalVariableReadNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode)) } + def new_name; end + + sig { returns(T.any(Prism::GlobalVariableReadNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode, Prism::SymbolNode, Prism::MissingNode)) } + def old_name; end + + sig { returns(Prism::Location) } + def keyword_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, new_name: T.any(Prism::GlobalVariableReadNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode), old_name: T.any(Prism::GlobalVariableReadNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode, Prism::SymbolNode, Prism::MissingNode), keyword_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, new_name, old_name, keyword_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, new_name: T.any(Prism::GlobalVariableReadNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode), old_name: T.any(Prism::GlobalVariableReadNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode, Prism::SymbolNode, Prism::MissingNode), keyword_loc: Prism::Location).returns(Prism::AliasGlobalVariableNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, new_name: self.new_name, old_name: self.old_name, keyword_loc: self.keyword_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def keyword; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `alias` keyword to alias a method. +# +# alias foo bar +# ^^^^^^^^^^^^^ +class Prism::AliasMethodNode < Prism::Node + sig { returns(T.any(Prism::SymbolNode, Prism::InterpolatedSymbolNode)) } + def new_name; end + + sig { returns(T.any(Prism::SymbolNode, Prism::InterpolatedSymbolNode, Prism::GlobalVariableReadNode, Prism::MissingNode)) } + def old_name; end + + sig { returns(Prism::Location) } + def keyword_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, new_name: T.any(Prism::SymbolNode, Prism::InterpolatedSymbolNode), old_name: T.any(Prism::SymbolNode, Prism::InterpolatedSymbolNode, Prism::GlobalVariableReadNode, Prism::MissingNode), keyword_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, new_name, old_name, keyword_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, new_name: T.any(Prism::SymbolNode, Prism::InterpolatedSymbolNode), old_name: T.any(Prism::SymbolNode, Prism::InterpolatedSymbolNode, Prism::GlobalVariableReadNode, Prism::MissingNode), keyword_loc: Prism::Location).returns(Prism::AliasMethodNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, new_name: self.new_name, old_name: self.old_name, keyword_loc: self.keyword_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def keyword; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents an alternation pattern in pattern matching. +# +# foo => bar | baz +# ^^^^^^^^^ +class Prism::AlternationPatternNode < Prism::Node + sig { returns(Prism::Node) } + def left; end + + sig { returns(Prism::Node) } + def right; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, left: Prism::Node, right: Prism::Node, operator_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, left, right, operator_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, left: Prism::Node, right: Prism::Node, operator_loc: Prism::Location).returns(Prism::AlternationPatternNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, left: self.left, right: self.right, operator_loc: self.operator_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `&&` operator or the `and` keyword. +# +# left and right +# ^^^^^^^^^^^^^^ +class Prism::AndNode < Prism::Node + sig { returns(Prism::Node) } + def left; end + + sig { returns(Prism::Node) } + def right; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, left: Prism::Node, right: Prism::Node, operator_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, left, right, operator_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, left: Prism::Node, right: Prism::Node, operator_loc: Prism::Location).returns(Prism::AndNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, left: self.left, right: self.right, operator_loc: self.operator_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a set of arguments to a method or a keyword. +# +# return foo, bar, baz +# ^^^^^^^^^^^^^ +class Prism::ArgumentsNode < Prism::Node + sig { returns(T::Boolean) } + def contains_forwarding?; end + + sig { returns(T::Boolean) } + def contains_keywords?; end + + sig { returns(T::Boolean) } + def contains_keyword_splat?; end + + sig { returns(T::Boolean) } + def contains_splat?; end + + sig { returns(T::Boolean) } + def contains_multiple_splats?; end + + sig { returns(T::Array[Prism::Node]) } + def arguments; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, arguments: T::Array[Prism::Node]).void } + def initialize(source, node_id, location, flags, arguments); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, arguments: T::Array[Prism::Node]).returns(Prism::ArgumentsNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, arguments: self.arguments); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents an array literal. This can be a regular array using brackets or a special array using % like %w or %i. +# +# [1, 2, 3] +# ^^^^^^^^^ +class Prism::ArrayNode < Prism::Node + sig { returns(T::Boolean) } + def contains_splat?; end + + sig { returns(T::Array[Prism::Node]) } + def elements; end + + sig { returns(T.nilable(Prism::Location)) } + def opening_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def closing_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, elements: T::Array[Prism::Node], opening_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location)).void } + def initialize(source, node_id, location, flags, elements, opening_loc, closing_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, elements: T::Array[Prism::Node], opening_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location)).returns(Prism::ArrayNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, elements: self.elements, opening_loc: self.opening_loc, closing_loc: self.closing_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(T.nilable(String)) } + def opening; end + + sig { returns(T.nilable(String)) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents an array pattern in pattern matching. +# +# foo in 1, 2 +# ^^^^^^^^^^^ +# +# foo in [1, 2] +# ^^^^^^^^^^^^^ +# +# foo in *bar +# ^^^^^^^^^^^ +# +# foo in Bar[] +# ^^^^^^^^^^^^ +# +# foo in Bar[1, 2, 3] +# ^^^^^^^^^^^^^^^^^^^ +class Prism::ArrayPatternNode < Prism::Node + sig { returns(T.nilable(T.any(Prism::ConstantReadNode, Prism::ConstantPathNode))) } + def constant; end + + sig { returns(T::Array[Prism::Node]) } + def requireds; end + + sig { returns(T.nilable(Prism::Node)) } + def rest; end + + sig { returns(T::Array[Prism::Node]) } + def posts; end + + sig { returns(T.nilable(Prism::Location)) } + def opening_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def closing_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, constant: T.nilable(T.any(Prism::ConstantReadNode, Prism::ConstantPathNode)), requireds: T::Array[Prism::Node], rest: T.nilable(Prism::Node), posts: T::Array[Prism::Node], opening_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location)).void } + def initialize(source, node_id, location, flags, constant, requireds, rest, posts, opening_loc, closing_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, constant: T.nilable(T.any(Prism::ConstantReadNode, Prism::ConstantPathNode)), requireds: T::Array[Prism::Node], rest: T.nilable(Prism::Node), posts: T::Array[Prism::Node], opening_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location)).returns(Prism::ArrayPatternNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, constant: self.constant, requireds: self.requireds, rest: self.rest, posts: self.posts, opening_loc: self.opening_loc, closing_loc: self.closing_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(T.nilable(String)) } + def opening; end + + sig { returns(T.nilable(String)) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a hash key/value pair. +# +# { a => b } +# ^^^^^^ +class Prism::AssocNode < Prism::Node + sig { returns(Prism::Node) } + def key; end + + sig { returns(Prism::Node) } + def value; end + + sig { returns(T.nilable(Prism::Location)) } + def operator_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, key: Prism::Node, value: Prism::Node, operator_loc: T.nilable(Prism::Location)).void } + def initialize(source, node_id, location, flags, key, value, operator_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, key: Prism::Node, value: Prism::Node, operator_loc: T.nilable(Prism::Location)).returns(Prism::AssocNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, key: self.key, value: self.value, operator_loc: self.operator_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(T.nilable(String)) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a splat in a hash literal. +# +# { **foo } +# ^^^^^ +class Prism::AssocSplatNode < Prism::Node + sig { returns(T.nilable(Prism::Node)) } + def value; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, value: T.nilable(Prism::Node), operator_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, value, operator_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, value: T.nilable(Prism::Node), operator_loc: Prism::Location).returns(Prism::AssocSplatNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, value: self.value, operator_loc: self.operator_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents reading a reference to a field in the previous match. +# +# $' +# ^^ +class Prism::BackReferenceReadNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).void } + def initialize(source, node_id, location, flags, name); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).returns(Prism::BackReferenceReadNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a begin statement. +# +# begin +# foo +# end +# ^^^^^ +class Prism::BeginNode < Prism::Node + sig { returns(T.nilable(Prism::Location)) } + def begin_keyword_loc; end + + sig { returns(T.nilable(Prism::StatementsNode)) } + def statements; end + + sig { returns(T.nilable(Prism::RescueNode)) } + def rescue_clause; end + + sig { returns(T.nilable(Prism::ElseNode)) } + def else_clause; end + + sig { returns(T.nilable(Prism::EnsureNode)) } + def ensure_clause; end + + sig { returns(T.nilable(Prism::Location)) } + def end_keyword_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, begin_keyword_loc: T.nilable(Prism::Location), statements: T.nilable(Prism::StatementsNode), rescue_clause: T.nilable(Prism::RescueNode), else_clause: T.nilable(Prism::ElseNode), ensure_clause: T.nilable(Prism::EnsureNode), end_keyword_loc: T.nilable(Prism::Location)).void } + def initialize(source, node_id, location, flags, begin_keyword_loc, statements, rescue_clause, else_clause, ensure_clause, end_keyword_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, begin_keyword_loc: T.nilable(Prism::Location), statements: T.nilable(Prism::StatementsNode), rescue_clause: T.nilable(Prism::RescueNode), else_clause: T.nilable(Prism::ElseNode), ensure_clause: T.nilable(Prism::EnsureNode), end_keyword_loc: T.nilable(Prism::Location)).returns(Prism::BeginNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, begin_keyword_loc: self.begin_keyword_loc, statements: self.statements, rescue_clause: self.rescue_clause, else_clause: self.else_clause, ensure_clause: self.ensure_clause, end_keyword_loc: self.end_keyword_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(T.nilable(String)) } + def begin_keyword; end + + sig { returns(T.nilable(String)) } + def end_keyword; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a block argument using `&`. +# +# bar(&args) +# ^^^^^^^^^^ +class Prism::BlockArgumentNode < Prism::Node + sig { returns(T.nilable(Prism::Node)) } + def expression; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, expression: T.nilable(Prism::Node), operator_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, expression, operator_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, expression: T.nilable(Prism::Node), operator_loc: Prism::Location).returns(Prism::BlockArgumentNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, expression: self.expression, operator_loc: self.operator_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a block local variable. +# +# a { |; b| } +# ^ +class Prism::BlockLocalVariableNode < Prism::Node + sig { returns(T::Boolean) } + def repeated_parameter?; end + + sig { returns(Symbol) } + def name; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).void } + def initialize(source, node_id, location, flags, name); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).returns(Prism::BlockLocalVariableNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a block of ruby code. +# +# [1, 2, 3].each { |i| puts x } +# ^^^^^^^^^^^^^^ +class Prism::BlockNode < Prism::Node + sig { returns(T::Array[Symbol]) } + def locals; end + + sig { returns(T.nilable(T.any(Prism::BlockParametersNode, Prism::NumberedParametersNode, Prism::ItParametersNode))) } + def parameters; end + + sig { returns(T.nilable(T.any(Prism::StatementsNode, Prism::BeginNode))) } + def body; end + + sig { returns(Prism::Location) } + def opening_loc; end + + sig { returns(Prism::Location) } + def closing_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, locals: T::Array[Symbol], parameters: T.nilable(T.any(Prism::BlockParametersNode, Prism::NumberedParametersNode, Prism::ItParametersNode)), body: T.nilable(T.any(Prism::StatementsNode, Prism::BeginNode)), opening_loc: Prism::Location, closing_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, locals, parameters, body, opening_loc, closing_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, locals: T::Array[Symbol], parameters: T.nilable(T.any(Prism::BlockParametersNode, Prism::NumberedParametersNode, Prism::ItParametersNode)), body: T.nilable(T.any(Prism::StatementsNode, Prism::BeginNode)), opening_loc: Prism::Location, closing_loc: Prism::Location).returns(Prism::BlockNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, locals: self.locals, parameters: self.parameters, body: self.body, opening_loc: self.opening_loc, closing_loc: self.closing_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def opening; end + + sig { returns(String) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a block parameter of a method, block, or lambda definition. +# +# def a(&b) +# ^^ +# end +class Prism::BlockParameterNode < Prism::Node + sig { returns(T::Boolean) } + def repeated_parameter?; end + + sig { returns(T.nilable(Symbol)) } + def name; end + + sig { returns(T.nilable(Prism::Location)) } + def name_loc; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: T.nilable(Symbol), name_loc: T.nilable(Prism::Location), operator_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, name, name_loc, operator_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: T.nilable(Symbol), name_loc: T.nilable(Prism::Location), operator_loc: Prism::Location).returns(Prism::BlockParameterNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a block's parameters declaration. +# +# -> (a, b = 1; local) { } +# ^^^^^^^^^^^^^^^^^ +# +# foo do |a, b = 1; local| +# ^^^^^^^^^^^^^^^^^ +# end +class Prism::BlockParametersNode < Prism::Node + sig { returns(T.nilable(Prism::ParametersNode)) } + def parameters; end + + sig { returns(T::Array[Prism::BlockLocalVariableNode]) } + def locals; end + + sig { returns(T.nilable(Prism::Location)) } + def opening_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def closing_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, parameters: T.nilable(Prism::ParametersNode), locals: T::Array[Prism::BlockLocalVariableNode], opening_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location)).void } + def initialize(source, node_id, location, flags, parameters, locals, opening_loc, closing_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, parameters: T.nilable(Prism::ParametersNode), locals: T::Array[Prism::BlockLocalVariableNode], opening_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location)).returns(Prism::BlockParametersNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, parameters: self.parameters, locals: self.locals, opening_loc: self.opening_loc, closing_loc: self.closing_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(T.nilable(String)) } + def opening; end + + sig { returns(T.nilable(String)) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `break` keyword. +# +# break foo +# ^^^^^^^^^ +class Prism::BreakNode < Prism::Node + sig { returns(T.nilable(Prism::ArgumentsNode)) } + def arguments; end + + sig { returns(Prism::Location) } + def keyword_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, arguments: T.nilable(Prism::ArgumentsNode), keyword_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, arguments, keyword_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, arguments: T.nilable(Prism::ArgumentsNode), keyword_loc: Prism::Location).returns(Prism::BreakNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, arguments: self.arguments, keyword_loc: self.keyword_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def keyword; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `&&=` operator on a call. +# +# foo.bar &&= value +# ^^^^^^^^^^^^^^^^^ +class Prism::CallAndWriteNode < Prism::Node + sig { returns(T::Boolean) } + def safe_navigation?; end + + sig { returns(T::Boolean) } + def variable_call?; end + + sig { returns(T::Boolean) } + def attribute_write?; end + + sig { returns(T::Boolean) } + def ignore_visibility?; end + + sig { returns(T.nilable(Prism::Node)) } + def receiver; end + + sig { returns(T.nilable(Prism::Location)) } + def call_operator_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def message_loc; end + + sig { returns(Symbol) } + def read_name; end + + sig { returns(Symbol) } + def write_name; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, receiver: T.nilable(Prism::Node), call_operator_loc: T.nilable(Prism::Location), message_loc: T.nilable(Prism::Location), read_name: Symbol, write_name: Symbol, operator_loc: Prism::Location, value: Prism::Node).void } + def initialize(source, node_id, location, flags, receiver, call_operator_loc, message_loc, read_name, write_name, operator_loc, value); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, receiver: T.nilable(Prism::Node), call_operator_loc: T.nilable(Prism::Location), message_loc: T.nilable(Prism::Location), read_name: Symbol, write_name: Symbol, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::CallAndWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, message_loc: self.message_loc, read_name: self.read_name, write_name: self.write_name, operator_loc: self.operator_loc, value: self.value); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(T.nilable(String)) } + def call_operator; end + + sig { returns(T.nilable(String)) } + def message; end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a method call, in all of the various forms that can take. +# +# foo +# ^^^ +# +# foo() +# ^^^^^ +# +# +foo +# ^^^^ +# +# foo + bar +# ^^^^^^^^^ +# +# foo.bar +# ^^^^^^^ +# +# foo&.bar +# ^^^^^^^^ +class Prism::CallNode < Prism::Node + sig { returns(T::Boolean) } + def safe_navigation?; end + + sig { returns(T::Boolean) } + def variable_call?; end + + sig { returns(T::Boolean) } + def attribute_write?; end + + sig { returns(T::Boolean) } + def ignore_visibility?; end + + sig { returns(T.nilable(Prism::Node)) } + def receiver; end + + sig { returns(T.nilable(Prism::Location)) } + def call_operator_loc; end + + sig { returns(Symbol) } + def name; end + + sig { returns(T.nilable(Prism::Location)) } + def message_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def opening_loc; end + + sig { returns(T.nilable(Prism::ArgumentsNode)) } + def arguments; end + + sig { returns(T.nilable(Prism::Location)) } + def closing_loc; end + + sig { returns(T.nilable(T.any(Prism::BlockNode, Prism::BlockArgumentNode))) } + def block; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, receiver: T.nilable(Prism::Node), call_operator_loc: T.nilable(Prism::Location), name: Symbol, message_loc: T.nilable(Prism::Location), opening_loc: T.nilable(Prism::Location), arguments: T.nilable(Prism::ArgumentsNode), closing_loc: T.nilable(Prism::Location), block: T.nilable(T.any(Prism::BlockNode, Prism::BlockArgumentNode))).void } + def initialize(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc, opening_loc, arguments, closing_loc, block); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, receiver: T.nilable(Prism::Node), call_operator_loc: T.nilable(Prism::Location), name: Symbol, message_loc: T.nilable(Prism::Location), opening_loc: T.nilable(Prism::Location), arguments: T.nilable(Prism::ArgumentsNode), closing_loc: T.nilable(Prism::Location), block: T.nilable(T.any(Prism::BlockNode, Prism::BlockArgumentNode))).returns(Prism::CallNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, name: self.name, message_loc: self.message_loc, opening_loc: self.opening_loc, arguments: self.arguments, closing_loc: self.closing_loc, block: self.block); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(T.nilable(String)) } + def call_operator; end + + sig { returns(T.nilable(String)) } + def message; end + + sig { returns(T.nilable(String)) } + def opening; end + + sig { returns(T.nilable(String)) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of an assignment operator on a call. +# +# foo.bar += baz +# ^^^^^^^^^^^^^^ +class Prism::CallOperatorWriteNode < Prism::Node + sig { returns(T::Boolean) } + def safe_navigation?; end + + sig { returns(T::Boolean) } + def variable_call?; end + + sig { returns(T::Boolean) } + def attribute_write?; end + + sig { returns(T::Boolean) } + def ignore_visibility?; end + + sig { returns(T.nilable(Prism::Node)) } + def receiver; end + + sig { returns(T.nilable(Prism::Location)) } + def call_operator_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def message_loc; end + + sig { returns(Symbol) } + def read_name; end + + sig { returns(Symbol) } + def write_name; end + + sig { returns(Symbol) } + def binary_operator; end + + sig { returns(Prism::Location) } + def binary_operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, receiver: T.nilable(Prism::Node), call_operator_loc: T.nilable(Prism::Location), message_loc: T.nilable(Prism::Location), read_name: Symbol, write_name: Symbol, binary_operator: Symbol, binary_operator_loc: Prism::Location, value: Prism::Node).void } + def initialize(source, node_id, location, flags, receiver, call_operator_loc, message_loc, read_name, write_name, binary_operator, binary_operator_loc, value); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, receiver: T.nilable(Prism::Node), call_operator_loc: T.nilable(Prism::Location), message_loc: T.nilable(Prism::Location), read_name: Symbol, write_name: Symbol, binary_operator: Symbol, binary_operator_loc: Prism::Location, value: Prism::Node).returns(Prism::CallOperatorWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, message_loc: self.message_loc, read_name: self.read_name, write_name: self.write_name, binary_operator: self.binary_operator, binary_operator_loc: self.binary_operator_loc, value: self.value); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(T.nilable(String)) } + def call_operator; end + + sig { returns(T.nilable(String)) } + def message; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `||=` operator on a call. +# +# foo.bar ||= value +# ^^^^^^^^^^^^^^^^^ +class Prism::CallOrWriteNode < Prism::Node + sig { returns(T::Boolean) } + def safe_navigation?; end + + sig { returns(T::Boolean) } + def variable_call?; end + + sig { returns(T::Boolean) } + def attribute_write?; end + + sig { returns(T::Boolean) } + def ignore_visibility?; end + + sig { returns(T.nilable(Prism::Node)) } + def receiver; end + + sig { returns(T.nilable(Prism::Location)) } + def call_operator_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def message_loc; end + + sig { returns(Symbol) } + def read_name; end + + sig { returns(Symbol) } + def write_name; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, receiver: T.nilable(Prism::Node), call_operator_loc: T.nilable(Prism::Location), message_loc: T.nilable(Prism::Location), read_name: Symbol, write_name: Symbol, operator_loc: Prism::Location, value: Prism::Node).void } + def initialize(source, node_id, location, flags, receiver, call_operator_loc, message_loc, read_name, write_name, operator_loc, value); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, receiver: T.nilable(Prism::Node), call_operator_loc: T.nilable(Prism::Location), message_loc: T.nilable(Prism::Location), read_name: Symbol, write_name: Symbol, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::CallOrWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, message_loc: self.message_loc, read_name: self.read_name, write_name: self.write_name, operator_loc: self.operator_loc, value: self.value); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(T.nilable(String)) } + def call_operator; end + + sig { returns(T.nilable(String)) } + def message; end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents assigning to a method call. +# +# foo.bar, = 1 +# ^^^^^^^ +# +# begin +# rescue => foo.bar +# ^^^^^^^ +# end +# +# for foo.bar in baz do end +# ^^^^^^^ +class Prism::CallTargetNode < Prism::Node + sig { returns(T::Boolean) } + def safe_navigation?; end + + sig { returns(T::Boolean) } + def variable_call?; end + + sig { returns(T::Boolean) } + def attribute_write?; end + + sig { returns(T::Boolean) } + def ignore_visibility?; end + + sig { returns(Prism::Node) } + def receiver; end + + sig { returns(Prism::Location) } + def call_operator_loc; end + + sig { returns(Symbol) } + def name; end + + sig { returns(Prism::Location) } + def message_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, receiver: Prism::Node, call_operator_loc: Prism::Location, name: Symbol, message_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, receiver: Prism::Node, call_operator_loc: Prism::Location, name: Symbol, message_loc: Prism::Location).returns(Prism::CallTargetNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, name: self.name, message_loc: self.message_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def call_operator; end + + sig { returns(String) } + def message; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents assigning to a local variable in pattern matching. +# +# foo => [bar => baz] +# ^^^^^^^^^^^^ +class Prism::CapturePatternNode < Prism::Node + sig { returns(Prism::Node) } + def value; end + + sig { returns(Prism::LocalVariableTargetNode) } + def target; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, value: Prism::Node, target: Prism::LocalVariableTargetNode, operator_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, value, target, operator_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, value: Prism::Node, target: Prism::LocalVariableTargetNode, operator_loc: Prism::Location).returns(Prism::CapturePatternNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, value: self.value, target: self.target, operator_loc: self.operator_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of a case statement for pattern matching. +# +# case true +# in false +# end +# ^^^^^^^^^ +class Prism::CaseMatchNode < Prism::Node + sig { returns(T.nilable(Prism::Node)) } + def predicate; end + + sig { returns(T::Array[Prism::InNode]) } + def conditions; end + + sig { returns(T.nilable(Prism::ElseNode)) } + def else_clause; end + + sig { returns(Prism::Location) } + def case_keyword_loc; end + + sig { returns(Prism::Location) } + def end_keyword_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, predicate: T.nilable(Prism::Node), conditions: T::Array[Prism::InNode], else_clause: T.nilable(Prism::ElseNode), case_keyword_loc: Prism::Location, end_keyword_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, predicate, conditions, else_clause, case_keyword_loc, end_keyword_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, predicate: T.nilable(Prism::Node), conditions: T::Array[Prism::InNode], else_clause: T.nilable(Prism::ElseNode), case_keyword_loc: Prism::Location, end_keyword_loc: Prism::Location).returns(Prism::CaseMatchNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, predicate: self.predicate, conditions: self.conditions, else_clause: self.else_clause, case_keyword_loc: self.case_keyword_loc, end_keyword_loc: self.end_keyword_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def case_keyword; end + + sig { returns(String) } + def end_keyword; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of a case statement. +# +# case true +# when false +# end +# ^^^^^^^^^^ +class Prism::CaseNode < Prism::Node + sig { returns(T.nilable(Prism::Node)) } + def predicate; end + + sig { returns(T::Array[Prism::WhenNode]) } + def conditions; end + + sig { returns(T.nilable(Prism::ElseNode)) } + def else_clause; end + + sig { returns(Prism::Location) } + def case_keyword_loc; end + + sig { returns(Prism::Location) } + def end_keyword_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, predicate: T.nilable(Prism::Node), conditions: T::Array[Prism::WhenNode], else_clause: T.nilable(Prism::ElseNode), case_keyword_loc: Prism::Location, end_keyword_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, predicate, conditions, else_clause, case_keyword_loc, end_keyword_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, predicate: T.nilable(Prism::Node), conditions: T::Array[Prism::WhenNode], else_clause: T.nilable(Prism::ElseNode), case_keyword_loc: Prism::Location, end_keyword_loc: Prism::Location).returns(Prism::CaseNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, predicate: self.predicate, conditions: self.conditions, else_clause: self.else_clause, case_keyword_loc: self.case_keyword_loc, end_keyword_loc: self.end_keyword_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def case_keyword; end + + sig { returns(String) } + def end_keyword; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a class declaration involving the `class` keyword. +# +# class Foo end +# ^^^^^^^^^^^^^ +class Prism::ClassNode < Prism::Node + sig { returns(T::Array[Symbol]) } + def locals; end + + sig { returns(Prism::Location) } + def class_keyword_loc; end + + sig { returns(T.any(Prism::ConstantReadNode, Prism::ConstantPathNode, Prism::CallNode)) } + def constant_path; end + + sig { returns(T.nilable(Prism::Location)) } + def inheritance_operator_loc; end + + sig { returns(T.nilable(Prism::Node)) } + def superclass; end + + sig { returns(T.nilable(T.any(Prism::StatementsNode, Prism::BeginNode))) } + def body; end + + sig { returns(Prism::Location) } + def end_keyword_loc; end + + sig { returns(Symbol) } + def name; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, locals: T::Array[Symbol], class_keyword_loc: Prism::Location, constant_path: T.any(Prism::ConstantReadNode, Prism::ConstantPathNode, Prism::CallNode), inheritance_operator_loc: T.nilable(Prism::Location), superclass: T.nilable(Prism::Node), body: T.nilable(T.any(Prism::StatementsNode, Prism::BeginNode)), end_keyword_loc: Prism::Location, name: Symbol).void } + def initialize(source, node_id, location, flags, locals, class_keyword_loc, constant_path, inheritance_operator_loc, superclass, body, end_keyword_loc, name); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, locals: T::Array[Symbol], class_keyword_loc: Prism::Location, constant_path: T.any(Prism::ConstantReadNode, Prism::ConstantPathNode, Prism::CallNode), inheritance_operator_loc: T.nilable(Prism::Location), superclass: T.nilable(Prism::Node), body: T.nilable(T.any(Prism::StatementsNode, Prism::BeginNode)), end_keyword_loc: Prism::Location, name: Symbol).returns(Prism::ClassNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, locals: self.locals, class_keyword_loc: self.class_keyword_loc, constant_path: self.constant_path, inheritance_operator_loc: self.inheritance_operator_loc, superclass: self.superclass, body: self.body, end_keyword_loc: self.end_keyword_loc, name: self.name); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def class_keyword; end + + sig { returns(T.nilable(String)) } + def inheritance_operator; end + + sig { returns(String) } + def end_keyword; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `&&=` operator for assignment to a class variable. +# +# @@target &&= value +# ^^^^^^^^^^^^^^^^^^ +class Prism::ClassVariableAndWriteNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { returns(Prism::Location) } + def name_loc; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).void } + def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::ClassVariableAndWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents assigning to a class variable using an operator that isn't `=`. +# +# @@target += value +# ^^^^^^^^^^^^^^^^^ +class Prism::ClassVariableOperatorWriteNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { returns(Prism::Location) } + def name_loc; end + + sig { returns(Prism::Location) } + def binary_operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { returns(Symbol) } + def binary_operator; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, binary_operator_loc: Prism::Location, value: Prism::Node, binary_operator: Symbol).void } + def initialize(source, node_id, location, flags, name, name_loc, binary_operator_loc, value, binary_operator); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, binary_operator_loc: Prism::Location, value: Prism::Node, binary_operator: Symbol).returns(Prism::ClassVariableOperatorWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, binary_operator_loc: self.binary_operator_loc, value: self.value, binary_operator: self.binary_operator); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `||=` operator for assignment to a class variable. +# +# @@target ||= value +# ^^^^^^^^^^^^^^^^^^ +class Prism::ClassVariableOrWriteNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { returns(Prism::Location) } + def name_loc; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).void } + def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::ClassVariableOrWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents referencing a class variable. +# +# @@foo +# ^^^^^ +class Prism::ClassVariableReadNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).void } + def initialize(source, node_id, location, flags, name); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).returns(Prism::ClassVariableReadNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents writing to a class variable in a context that doesn't have an explicit value. +# +# @@foo, @@bar = baz +# ^^^^^ ^^^^^ +class Prism::ClassVariableTargetNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).void } + def initialize(source, node_id, location, flags, name); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).returns(Prism::ClassVariableTargetNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents writing to a class variable. +# +# @@foo = 1 +# ^^^^^^^^^ +class Prism::ClassVariableWriteNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { returns(Prism::Location) } + def name_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, value: Prism::Node, operator_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, name, name_loc, value, operator_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, value: Prism::Node, operator_loc: Prism::Location).returns(Prism::ClassVariableWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, value: self.value, operator_loc: self.operator_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `&&=` operator for assignment to a constant. +# +# Target &&= value +# ^^^^^^^^^^^^^^^^ +class Prism::ConstantAndWriteNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { returns(Prism::Location) } + def name_loc; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).void } + def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::ConstantAndWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents assigning to a constant using an operator that isn't `=`. +# +# Target += value +# ^^^^^^^^^^^^^^^ +class Prism::ConstantOperatorWriteNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { returns(Prism::Location) } + def name_loc; end + + sig { returns(Prism::Location) } + def binary_operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { returns(Symbol) } + def binary_operator; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, binary_operator_loc: Prism::Location, value: Prism::Node, binary_operator: Symbol).void } + def initialize(source, node_id, location, flags, name, name_loc, binary_operator_loc, value, binary_operator); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, binary_operator_loc: Prism::Location, value: Prism::Node, binary_operator: Symbol).returns(Prism::ConstantOperatorWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, binary_operator_loc: self.binary_operator_loc, value: self.value, binary_operator: self.binary_operator); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `||=` operator for assignment to a constant. +# +# Target ||= value +# ^^^^^^^^^^^^^^^^ +class Prism::ConstantOrWriteNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { returns(Prism::Location) } + def name_loc; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).void } + def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::ConstantOrWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `&&=` operator for assignment to a constant path. +# +# Parent::Child &&= value +# ^^^^^^^^^^^^^^^^^^^^^^^ +class Prism::ConstantPathAndWriteNode < Prism::Node + sig { returns(Prism::ConstantPathNode) } + def target; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, target: Prism::ConstantPathNode, operator_loc: Prism::Location, value: Prism::Node).void } + def initialize(source, node_id, location, flags, target, operator_loc, value); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, target: Prism::ConstantPathNode, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::ConstantPathAndWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, target: self.target, operator_loc: self.operator_loc, value: self.value); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents accessing a constant through a path of `::` operators. +# +# Foo::Bar +# ^^^^^^^^ +class Prism::ConstantPathNode < Prism::Node + sig { returns(T.nilable(Prism::Node)) } + def parent; end + + sig { returns(T.nilable(Symbol)) } + def name; end + + sig { returns(Prism::Location) } + def delimiter_loc; end + + sig { returns(Prism::Location) } + def name_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, parent: T.nilable(Prism::Node), name: T.nilable(Symbol), delimiter_loc: Prism::Location, name_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, parent, name, delimiter_loc, name_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, parent: T.nilable(Prism::Node), name: T.nilable(Symbol), delimiter_loc: Prism::Location, name_loc: Prism::Location).returns(Prism::ConstantPathNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, parent: self.parent, name: self.name, delimiter_loc: self.delimiter_loc, name_loc: self.name_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def delimiter; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents assigning to a constant path using an operator that isn't `=`. +# +# Parent::Child += value +# ^^^^^^^^^^^^^^^^^^^^^^ +class Prism::ConstantPathOperatorWriteNode < Prism::Node + sig { returns(Prism::ConstantPathNode) } + def target; end + + sig { returns(Prism::Location) } + def binary_operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { returns(Symbol) } + def binary_operator; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, target: Prism::ConstantPathNode, binary_operator_loc: Prism::Location, value: Prism::Node, binary_operator: Symbol).void } + def initialize(source, node_id, location, flags, target, binary_operator_loc, value, binary_operator); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, target: Prism::ConstantPathNode, binary_operator_loc: Prism::Location, value: Prism::Node, binary_operator: Symbol).returns(Prism::ConstantPathOperatorWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, target: self.target, binary_operator_loc: self.binary_operator_loc, value: self.value, binary_operator: self.binary_operator); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `||=` operator for assignment to a constant path. +# +# Parent::Child ||= value +# ^^^^^^^^^^^^^^^^^^^^^^^ +class Prism::ConstantPathOrWriteNode < Prism::Node + sig { returns(Prism::ConstantPathNode) } + def target; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, target: Prism::ConstantPathNode, operator_loc: Prism::Location, value: Prism::Node).void } + def initialize(source, node_id, location, flags, target, operator_loc, value); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, target: Prism::ConstantPathNode, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::ConstantPathOrWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, target: self.target, operator_loc: self.operator_loc, value: self.value); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents writing to a constant path in a context that doesn't have an explicit value. +# +# Foo::Foo, Bar::Bar = baz +# ^^^^^^^^ ^^^^^^^^ +class Prism::ConstantPathTargetNode < Prism::Node + sig { returns(T.nilable(Prism::Node)) } + def parent; end + + sig { returns(T.nilable(Symbol)) } + def name; end + + sig { returns(Prism::Location) } + def delimiter_loc; end + + sig { returns(Prism::Location) } + def name_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, parent: T.nilable(Prism::Node), name: T.nilable(Symbol), delimiter_loc: Prism::Location, name_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, parent, name, delimiter_loc, name_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, parent: T.nilable(Prism::Node), name: T.nilable(Symbol), delimiter_loc: Prism::Location, name_loc: Prism::Location).returns(Prism::ConstantPathTargetNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, parent: self.parent, name: self.name, delimiter_loc: self.delimiter_loc, name_loc: self.name_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def delimiter; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents writing to a constant path. +# +# ::Foo = 1 +# ^^^^^^^^^ +# +# Foo::Bar = 1 +# ^^^^^^^^^^^^ +# +# ::Foo::Bar = 1 +# ^^^^^^^^^^^^^^ +class Prism::ConstantPathWriteNode < Prism::Node + sig { returns(Prism::ConstantPathNode) } + def target; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, target: Prism::ConstantPathNode, operator_loc: Prism::Location, value: Prism::Node).void } + def initialize(source, node_id, location, flags, target, operator_loc, value); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, target: Prism::ConstantPathNode, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::ConstantPathWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, target: self.target, operator_loc: self.operator_loc, value: self.value); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents referencing a constant. +# +# Foo +# ^^^ +class Prism::ConstantReadNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).void } + def initialize(source, node_id, location, flags, name); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).returns(Prism::ConstantReadNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents writing to a constant in a context that doesn't have an explicit value. +# +# Foo, Bar = baz +# ^^^ ^^^ +class Prism::ConstantTargetNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).void } + def initialize(source, node_id, location, flags, name); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).returns(Prism::ConstantTargetNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents writing to a constant. +# +# Foo = 1 +# ^^^^^^^ +class Prism::ConstantWriteNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { returns(Prism::Location) } + def name_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, value: Prism::Node, operator_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, name, name_loc, value, operator_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, value: Prism::Node, operator_loc: Prism::Location).returns(Prism::ConstantWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, value: self.value, operator_loc: self.operator_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a method definition. +# +# def method +# end +# ^^^^^^^^^^ +class Prism::DefNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { returns(Prism::Location) } + def name_loc; end + + sig { returns(T.nilable(Prism::Node)) } + def receiver; end + + sig { returns(T.nilable(Prism::ParametersNode)) } + def parameters; end + + sig { returns(T.nilable(T.any(Prism::StatementsNode, Prism::BeginNode))) } + def body; end + + sig { returns(T::Array[Symbol]) } + def locals; end + + sig { returns(Prism::Location) } + def def_keyword_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def operator_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def lparen_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def rparen_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def equal_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def end_keyword_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, receiver: T.nilable(Prism::Node), parameters: T.nilable(Prism::ParametersNode), body: T.nilable(T.any(Prism::StatementsNode, Prism::BeginNode)), locals: T::Array[Symbol], def_keyword_loc: Prism::Location, operator_loc: T.nilable(Prism::Location), lparen_loc: T.nilable(Prism::Location), rparen_loc: T.nilable(Prism::Location), equal_loc: T.nilable(Prism::Location), end_keyword_loc: T.nilable(Prism::Location)).void } + def initialize(source, node_id, location, flags, name, name_loc, receiver, parameters, body, locals, def_keyword_loc, operator_loc, lparen_loc, rparen_loc, equal_loc, end_keyword_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, receiver: T.nilable(Prism::Node), parameters: T.nilable(Prism::ParametersNode), body: T.nilable(T.any(Prism::StatementsNode, Prism::BeginNode)), locals: T::Array[Symbol], def_keyword_loc: Prism::Location, operator_loc: T.nilable(Prism::Location), lparen_loc: T.nilable(Prism::Location), rparen_loc: T.nilable(Prism::Location), equal_loc: T.nilable(Prism::Location), end_keyword_loc: T.nilable(Prism::Location)).returns(Prism::DefNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, receiver: self.receiver, parameters: self.parameters, body: self.body, locals: self.locals, def_keyword_loc: self.def_keyword_loc, operator_loc: self.operator_loc, lparen_loc: self.lparen_loc, rparen_loc: self.rparen_loc, equal_loc: self.equal_loc, end_keyword_loc: self.end_keyword_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def def_keyword; end + + sig { returns(T.nilable(String)) } + def operator; end + + sig { returns(T.nilable(String)) } + def lparen; end + + sig { returns(T.nilable(String)) } + def rparen; end + + sig { returns(T.nilable(String)) } + def equal; end + + sig { returns(T.nilable(String)) } + def end_keyword; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `defined?` keyword. +# +# defined?(a) +# ^^^^^^^^^^^ +class Prism::DefinedNode < Prism::Node + sig { returns(T.nilable(Prism::Location)) } + def lparen_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { returns(T.nilable(Prism::Location)) } + def rparen_loc; end + + sig { returns(Prism::Location) } + def keyword_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, lparen_loc: T.nilable(Prism::Location), value: Prism::Node, rparen_loc: T.nilable(Prism::Location), keyword_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, lparen_loc, value, rparen_loc, keyword_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, lparen_loc: T.nilable(Prism::Location), value: Prism::Node, rparen_loc: T.nilable(Prism::Location), keyword_loc: Prism::Location).returns(Prism::DefinedNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, lparen_loc: self.lparen_loc, value: self.value, rparen_loc: self.rparen_loc, keyword_loc: self.keyword_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(T.nilable(String)) } + def lparen; end + + sig { returns(T.nilable(String)) } + def rparen; end + + sig { returns(String) } + def keyword; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents an `else` clause in a `case`, `if`, or `unless` statement. +# +# if a then b else c end +# ^^^^^^^^^^ +class Prism::ElseNode < Prism::Node + sig { returns(Prism::Location) } + def else_keyword_loc; end + + sig { returns(T.nilable(Prism::StatementsNode)) } + def statements; end + + sig { returns(T.nilable(Prism::Location)) } + def end_keyword_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, else_keyword_loc: Prism::Location, statements: T.nilable(Prism::StatementsNode), end_keyword_loc: T.nilable(Prism::Location)).void } + def initialize(source, node_id, location, flags, else_keyword_loc, statements, end_keyword_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, else_keyword_loc: Prism::Location, statements: T.nilable(Prism::StatementsNode), end_keyword_loc: T.nilable(Prism::Location)).returns(Prism::ElseNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, else_keyword_loc: self.else_keyword_loc, statements: self.statements, end_keyword_loc: self.end_keyword_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def else_keyword; end + + sig { returns(T.nilable(String)) } + def end_keyword; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents an interpolated set of statements. +# +# "foo #{bar}" +# ^^^^^^ +class Prism::EmbeddedStatementsNode < Prism::Node + sig { returns(Prism::Location) } + def opening_loc; end + + sig { returns(T.nilable(Prism::StatementsNode)) } + def statements; end + + sig { returns(Prism::Location) } + def closing_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: Prism::Location, statements: T.nilable(Prism::StatementsNode), closing_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, opening_loc, statements, closing_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: Prism::Location, statements: T.nilable(Prism::StatementsNode), closing_loc: Prism::Location).returns(Prism::EmbeddedStatementsNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, statements: self.statements, closing_loc: self.closing_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def opening; end + + sig { returns(String) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents an interpolated variable. +# +# "foo #@bar" +# ^^^^^ +class Prism::EmbeddedVariableNode < Prism::Node + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(T.any(Prism::InstanceVariableReadNode, Prism::ClassVariableReadNode, Prism::GlobalVariableReadNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode)) } + def variable; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, operator_loc: Prism::Location, variable: T.any(Prism::InstanceVariableReadNode, Prism::ClassVariableReadNode, Prism::GlobalVariableReadNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode)).void } + def initialize(source, node_id, location, flags, operator_loc, variable); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, operator_loc: Prism::Location, variable: T.any(Prism::InstanceVariableReadNode, Prism::ClassVariableReadNode, Prism::GlobalVariableReadNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode)).returns(Prism::EmbeddedVariableNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, operator_loc: self.operator_loc, variable: self.variable); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents an `ensure` clause in a `begin` statement. +# +# begin +# foo +# ensure +# ^^^^^^ +# bar +# end +class Prism::EnsureNode < Prism::Node + sig { returns(Prism::Location) } + def ensure_keyword_loc; end + + sig { returns(T.nilable(Prism::StatementsNode)) } + def statements; end + + sig { returns(Prism::Location) } + def end_keyword_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, ensure_keyword_loc: Prism::Location, statements: T.nilable(Prism::StatementsNode), end_keyword_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, ensure_keyword_loc, statements, end_keyword_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, ensure_keyword_loc: Prism::Location, statements: T.nilable(Prism::StatementsNode), end_keyword_loc: Prism::Location).returns(Prism::EnsureNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, ensure_keyword_loc: self.ensure_keyword_loc, statements: self.statements, end_keyword_loc: self.end_keyword_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def ensure_keyword; end + + sig { returns(String) } + def end_keyword; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the literal `false` keyword. +# +# false +# ^^^^^ +class Prism::FalseNode < Prism::Node + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).void } + def initialize(source, node_id, location, flags); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::FalseNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a find pattern in pattern matching. +# +# foo in *bar, baz, *qux +# ^^^^^^^^^^^^^^^ +# +# foo in [*bar, baz, *qux] +# ^^^^^^^^^^^^^^^^^ +# +# foo in Foo(*bar, baz, *qux) +# ^^^^^^^^^^^^^^^^^^^^ +class Prism::FindPatternNode < Prism::Node + sig { returns(T.nilable(T.any(Prism::ConstantReadNode, Prism::ConstantPathNode))) } + def constant; end + + sig { returns(Prism::SplatNode) } + def left; end + + sig { returns(T::Array[Prism::Node]) } + def requireds; end + + sig { returns(T.any(Prism::SplatNode, Prism::MissingNode)) } + def right; end + + sig { returns(T.nilable(Prism::Location)) } + def opening_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def closing_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, constant: T.nilable(T.any(Prism::ConstantReadNode, Prism::ConstantPathNode)), left: Prism::SplatNode, requireds: T::Array[Prism::Node], right: T.any(Prism::SplatNode, Prism::MissingNode), opening_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location)).void } + def initialize(source, node_id, location, flags, constant, left, requireds, right, opening_loc, closing_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, constant: T.nilable(T.any(Prism::ConstantReadNode, Prism::ConstantPathNode)), left: Prism::SplatNode, requireds: T::Array[Prism::Node], right: T.any(Prism::SplatNode, Prism::MissingNode), opening_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location)).returns(Prism::FindPatternNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, constant: self.constant, left: self.left, requireds: self.requireds, right: self.right, opening_loc: self.opening_loc, closing_loc: self.closing_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(T.nilable(String)) } + def opening; end + + sig { returns(T.nilable(String)) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `..` or `...` operators to create flip flops. +# +# baz if foo .. bar +# ^^^^^^^^^^ +class Prism::FlipFlopNode < Prism::Node + sig { returns(T::Boolean) } + def exclude_end?; end + + sig { returns(T.nilable(Prism::Node)) } + def left; end + + sig { returns(T.nilable(Prism::Node)) } + def right; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, left: T.nilable(Prism::Node), right: T.nilable(Prism::Node), operator_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, left, right, operator_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, left: T.nilable(Prism::Node), right: T.nilable(Prism::Node), operator_loc: Prism::Location).returns(Prism::FlipFlopNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, left: self.left, right: self.right, operator_loc: self.operator_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a floating point number literal. +# +# 1.0 +# ^^^ +class Prism::FloatNode < Prism::Node + sig { returns(Float) } + def value; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, value: Float).void } + def initialize(source, node_id, location, flags, value); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, value: Float).returns(Prism::FloatNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, value: self.value); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `for` keyword. +# +# for i in a end +# ^^^^^^^^^^^^^^ +class Prism::ForNode < Prism::Node + sig { returns(T.any(Prism::LocalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::ConstantTargetNode, Prism::ConstantPathTargetNode, Prism::CallTargetNode, Prism::IndexTargetNode, Prism::MultiTargetNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode, Prism::MissingNode)) } + def index; end + + sig { returns(Prism::Node) } + def collection; end + + sig { returns(T.nilable(Prism::StatementsNode)) } + def statements; end + + sig { returns(Prism::Location) } + def for_keyword_loc; end + + sig { returns(Prism::Location) } + def in_keyword_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def do_keyword_loc; end + + sig { returns(Prism::Location) } + def end_keyword_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, index: T.any(Prism::LocalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::ConstantTargetNode, Prism::ConstantPathTargetNode, Prism::CallTargetNode, Prism::IndexTargetNode, Prism::MultiTargetNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode, Prism::MissingNode), collection: Prism::Node, statements: T.nilable(Prism::StatementsNode), for_keyword_loc: Prism::Location, in_keyword_loc: Prism::Location, do_keyword_loc: T.nilable(Prism::Location), end_keyword_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, index, collection, statements, for_keyword_loc, in_keyword_loc, do_keyword_loc, end_keyword_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, index: T.any(Prism::LocalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::ConstantTargetNode, Prism::ConstantPathTargetNode, Prism::CallTargetNode, Prism::IndexTargetNode, Prism::MultiTargetNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode, Prism::MissingNode), collection: Prism::Node, statements: T.nilable(Prism::StatementsNode), for_keyword_loc: Prism::Location, in_keyword_loc: Prism::Location, do_keyword_loc: T.nilable(Prism::Location), end_keyword_loc: Prism::Location).returns(Prism::ForNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, index: self.index, collection: self.collection, statements: self.statements, for_keyword_loc: self.for_keyword_loc, in_keyword_loc: self.in_keyword_loc, do_keyword_loc: self.do_keyword_loc, end_keyword_loc: self.end_keyword_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def for_keyword; end + + sig { returns(String) } + def in_keyword; end + + sig { returns(T.nilable(String)) } + def do_keyword; end + + sig { returns(String) } + def end_keyword; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents forwarding all arguments to this method to another method. +# +# def foo(...) +# bar(...) +# ^^^ +# end +class Prism::ForwardingArgumentsNode < Prism::Node + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).void } + def initialize(source, node_id, location, flags); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::ForwardingArgumentsNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the forwarding parameter in a method, block, or lambda declaration. +# +# def foo(...) +# ^^^ +# end +class Prism::ForwardingParameterNode < Prism::Node + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).void } + def initialize(source, node_id, location, flags); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::ForwardingParameterNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `super` keyword without parentheses or arguments. +# +# super +# ^^^^^ +class Prism::ForwardingSuperNode < Prism::Node + sig { returns(T.nilable(Prism::BlockNode)) } + def block; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, block: T.nilable(Prism::BlockNode)).void } + def initialize(source, node_id, location, flags, block); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, block: T.nilable(Prism::BlockNode)).returns(Prism::ForwardingSuperNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, block: self.block); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `&&=` operator for assignment to a global variable. +# +# $target &&= value +# ^^^^^^^^^^^^^^^^^ +class Prism::GlobalVariableAndWriteNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { returns(Prism::Location) } + def name_loc; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).void } + def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::GlobalVariableAndWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents assigning to a global variable using an operator that isn't `=`. +# +# $target += value +# ^^^^^^^^^^^^^^^^ +class Prism::GlobalVariableOperatorWriteNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { returns(Prism::Location) } + def name_loc; end + + sig { returns(Prism::Location) } + def binary_operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { returns(Symbol) } + def binary_operator; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, binary_operator_loc: Prism::Location, value: Prism::Node, binary_operator: Symbol).void } + def initialize(source, node_id, location, flags, name, name_loc, binary_operator_loc, value, binary_operator); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, binary_operator_loc: Prism::Location, value: Prism::Node, binary_operator: Symbol).returns(Prism::GlobalVariableOperatorWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, binary_operator_loc: self.binary_operator_loc, value: self.value, binary_operator: self.binary_operator); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `||=` operator for assignment to a global variable. +# +# $target ||= value +# ^^^^^^^^^^^^^^^^^ +class Prism::GlobalVariableOrWriteNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { returns(Prism::Location) } + def name_loc; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).void } + def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::GlobalVariableOrWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents referencing a global variable. +# +# $foo +# ^^^^ +class Prism::GlobalVariableReadNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).void } + def initialize(source, node_id, location, flags, name); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).returns(Prism::GlobalVariableReadNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents writing to a global variable in a context that doesn't have an explicit value. +# +# $foo, $bar = baz +# ^^^^ ^^^^ +class Prism::GlobalVariableTargetNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).void } + def initialize(source, node_id, location, flags, name); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).returns(Prism::GlobalVariableTargetNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents writing to a global variable. +# +# $foo = 1 +# ^^^^^^^^ +class Prism::GlobalVariableWriteNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { returns(Prism::Location) } + def name_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, value: Prism::Node, operator_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, name, name_loc, value, operator_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, value: Prism::Node, operator_loc: Prism::Location).returns(Prism::GlobalVariableWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, value: self.value, operator_loc: self.operator_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a hash literal. +# +# { a => b } +# ^^^^^^^^^^ +class Prism::HashNode < Prism::Node + sig { returns(Prism::Location) } + def opening_loc; end + + sig { returns(T::Array[T.any(Prism::AssocNode, Prism::AssocSplatNode)]) } + def elements; end + + sig { returns(Prism::Location) } + def closing_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: Prism::Location, elements: T::Array[T.any(Prism::AssocNode, Prism::AssocSplatNode)], closing_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, opening_loc, elements, closing_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: Prism::Location, elements: T::Array[T.any(Prism::AssocNode, Prism::AssocSplatNode)], closing_loc: Prism::Location).returns(Prism::HashNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, elements: self.elements, closing_loc: self.closing_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def opening; end + + sig { returns(String) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a hash pattern in pattern matching. +# +# foo => { a: 1, b: 2 } +# ^^^^^^^^^^^^^^ +# +# foo => { a: 1, b: 2, **c } +# ^^^^^^^^^^^^^^^^^^^ +class Prism::HashPatternNode < Prism::Node + sig { returns(T.nilable(T.any(Prism::ConstantReadNode, Prism::ConstantPathNode))) } + def constant; end + + sig { returns(T::Array[Prism::AssocNode]) } + def elements; end + + sig { returns(T.nilable(T.any(Prism::AssocSplatNode, Prism::NoKeywordsParameterNode))) } + def rest; end + + sig { returns(T.nilable(Prism::Location)) } + def opening_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def closing_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, constant: T.nilable(T.any(Prism::ConstantReadNode, Prism::ConstantPathNode)), elements: T::Array[Prism::AssocNode], rest: T.nilable(T.any(Prism::AssocSplatNode, Prism::NoKeywordsParameterNode)), opening_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location)).void } + def initialize(source, node_id, location, flags, constant, elements, rest, opening_loc, closing_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, constant: T.nilable(T.any(Prism::ConstantReadNode, Prism::ConstantPathNode)), elements: T::Array[Prism::AssocNode], rest: T.nilable(T.any(Prism::AssocSplatNode, Prism::NoKeywordsParameterNode)), opening_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location)).returns(Prism::HashPatternNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, constant: self.constant, elements: self.elements, rest: self.rest, opening_loc: self.opening_loc, closing_loc: self.closing_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(T.nilable(String)) } + def opening; end + + sig { returns(T.nilable(String)) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `if` keyword, either in the block form or the modifier form, or a ternary expression. +# +# bar if foo +# ^^^^^^^^^^ +# +# if foo then bar end +# ^^^^^^^^^^^^^^^^^^^ +# +# foo ? bar : baz +# ^^^^^^^^^^^^^^^ +class Prism::IfNode < Prism::Node + sig { returns(T.nilable(Prism::Location)) } + def if_keyword_loc; end + + sig { returns(Prism::Node) } + def predicate; end + + sig { returns(T.nilable(Prism::Location)) } + def then_keyword_loc; end + + sig { returns(T.nilable(Prism::StatementsNode)) } + def statements; end + + sig { returns(T.nilable(T.any(Prism::ElseNode, Prism::IfNode))) } + def subsequent; end + + sig { returns(T.nilable(Prism::Location)) } + def end_keyword_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, if_keyword_loc: T.nilable(Prism::Location), predicate: Prism::Node, then_keyword_loc: T.nilable(Prism::Location), statements: T.nilable(Prism::StatementsNode), subsequent: T.nilable(T.any(Prism::ElseNode, Prism::IfNode)), end_keyword_loc: T.nilable(Prism::Location)).void } + def initialize(source, node_id, location, flags, if_keyword_loc, predicate, then_keyword_loc, statements, subsequent, end_keyword_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, if_keyword_loc: T.nilable(Prism::Location), predicate: Prism::Node, then_keyword_loc: T.nilable(Prism::Location), statements: T.nilable(Prism::StatementsNode), subsequent: T.nilable(T.any(Prism::ElseNode, Prism::IfNode)), end_keyword_loc: T.nilable(Prism::Location)).returns(Prism::IfNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, if_keyword_loc: self.if_keyword_loc, predicate: self.predicate, then_keyword_loc: self.then_keyword_loc, statements: self.statements, subsequent: self.subsequent, end_keyword_loc: self.end_keyword_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(T.nilable(String)) } + def if_keyword; end + + sig { returns(T.nilable(String)) } + def then_keyword; end + + sig { returns(T.nilable(String)) } + def end_keyword; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents an imaginary number literal. +# +# 1.0i +# ^^^^ +class Prism::ImaginaryNode < Prism::Node + sig { returns(T.any(Prism::FloatNode, Prism::IntegerNode, Prism::RationalNode)) } + def numeric; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, numeric: T.any(Prism::FloatNode, Prism::IntegerNode, Prism::RationalNode)).void } + def initialize(source, node_id, location, flags, numeric); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, numeric: T.any(Prism::FloatNode, Prism::IntegerNode, Prism::RationalNode)).returns(Prism::ImaginaryNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, numeric: self.numeric); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a node that is implicitly being added to the tree but doesn't correspond directly to a node in the source. +# +# { foo: } +# ^^^^ +# +# { Foo: } +# ^^^^ +# +# foo in { bar: } +# ^^^^ +class Prism::ImplicitNode < Prism::Node + sig { returns(T.any(Prism::LocalVariableReadNode, Prism::CallNode, Prism::ConstantReadNode, Prism::LocalVariableTargetNode)) } + def value; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, value: T.any(Prism::LocalVariableReadNode, Prism::CallNode, Prism::ConstantReadNode, Prism::LocalVariableTargetNode)).void } + def initialize(source, node_id, location, flags, value); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, value: T.any(Prism::LocalVariableReadNode, Prism::CallNode, Prism::ConstantReadNode, Prism::LocalVariableTargetNode)).returns(Prism::ImplicitNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, value: self.value); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents using a trailing comma to indicate an implicit rest parameter. +# +# foo { |bar,| } +# ^ +# +# foo in [bar,] +# ^ +# +# for foo, in bar do end +# ^ +# +# foo, = bar +# ^ +class Prism::ImplicitRestNode < Prism::Node + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).void } + def initialize(source, node_id, location, flags); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::ImplicitRestNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `in` keyword in a case statement. +# +# case a; in b then c end +# ^^^^^^^^^^^ +class Prism::InNode < Prism::Node + sig { returns(Prism::Node) } + def pattern; end + + sig { returns(T.nilable(Prism::StatementsNode)) } + def statements; end + + sig { returns(Prism::Location) } + def in_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def then_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, pattern: Prism::Node, statements: T.nilable(Prism::StatementsNode), in_loc: Prism::Location, then_loc: T.nilable(Prism::Location)).void } + def initialize(source, node_id, location, flags, pattern, statements, in_loc, then_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, pattern: Prism::Node, statements: T.nilable(Prism::StatementsNode), in_loc: Prism::Location, then_loc: T.nilable(Prism::Location)).returns(Prism::InNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, pattern: self.pattern, statements: self.statements, in_loc: self.in_loc, then_loc: self.then_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def in; end + + sig { returns(T.nilable(String)) } + def then; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `&&=` operator on a call to the `[]` method. +# +# foo.bar[baz] &&= value +# ^^^^^^^^^^^^^^^^^^^^^^ +class Prism::IndexAndWriteNode < Prism::Node + sig { returns(T::Boolean) } + def safe_navigation?; end + + sig { returns(T::Boolean) } + def variable_call?; end + + sig { returns(T::Boolean) } + def attribute_write?; end + + sig { returns(T::Boolean) } + def ignore_visibility?; end + + sig { returns(T.nilable(Prism::Node)) } + def receiver; end + + sig { returns(T.nilable(Prism::Location)) } + def call_operator_loc; end + + sig { returns(Prism::Location) } + def opening_loc; end + + sig { returns(T.nilable(Prism::ArgumentsNode)) } + def arguments; end + + sig { returns(Prism::Location) } + def closing_loc; end + + sig { returns(T.nilable(Prism::BlockArgumentNode)) } + def block; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, receiver: T.nilable(Prism::Node), call_operator_loc: T.nilable(Prism::Location), opening_loc: Prism::Location, arguments: T.nilable(Prism::ArgumentsNode), closing_loc: Prism::Location, block: T.nilable(Prism::BlockArgumentNode), operator_loc: Prism::Location, value: Prism::Node).void } + def initialize(source, node_id, location, flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, operator_loc, value); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, receiver: T.nilable(Prism::Node), call_operator_loc: T.nilable(Prism::Location), opening_loc: Prism::Location, arguments: T.nilable(Prism::ArgumentsNode), closing_loc: Prism::Location, block: T.nilable(Prism::BlockArgumentNode), operator_loc: Prism::Location, value: Prism::Node).returns(Prism::IndexAndWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, opening_loc: self.opening_loc, arguments: self.arguments, closing_loc: self.closing_loc, block: self.block, operator_loc: self.operator_loc, value: self.value); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(T.nilable(String)) } + def call_operator; end + + sig { returns(String) } + def opening; end + + sig { returns(String) } + def closing; end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of an assignment operator on a call to `[]`. +# +# foo.bar[baz] += value +# ^^^^^^^^^^^^^^^^^^^^^ +class Prism::IndexOperatorWriteNode < Prism::Node + sig { returns(T::Boolean) } + def safe_navigation?; end + + sig { returns(T::Boolean) } + def variable_call?; end + + sig { returns(T::Boolean) } + def attribute_write?; end + + sig { returns(T::Boolean) } + def ignore_visibility?; end + + sig { returns(T.nilable(Prism::Node)) } + def receiver; end + + sig { returns(T.nilable(Prism::Location)) } + def call_operator_loc; end + + sig { returns(Prism::Location) } + def opening_loc; end + + sig { returns(T.nilable(Prism::ArgumentsNode)) } + def arguments; end + + sig { returns(Prism::Location) } + def closing_loc; end + + sig { returns(T.nilable(Prism::BlockArgumentNode)) } + def block; end + + sig { returns(Symbol) } + def binary_operator; end + + sig { returns(Prism::Location) } + def binary_operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, receiver: T.nilable(Prism::Node), call_operator_loc: T.nilable(Prism::Location), opening_loc: Prism::Location, arguments: T.nilable(Prism::ArgumentsNode), closing_loc: Prism::Location, block: T.nilable(Prism::BlockArgumentNode), binary_operator: Symbol, binary_operator_loc: Prism::Location, value: Prism::Node).void } + def initialize(source, node_id, location, flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, binary_operator, binary_operator_loc, value); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, receiver: T.nilable(Prism::Node), call_operator_loc: T.nilable(Prism::Location), opening_loc: Prism::Location, arguments: T.nilable(Prism::ArgumentsNode), closing_loc: Prism::Location, block: T.nilable(Prism::BlockArgumentNode), binary_operator: Symbol, binary_operator_loc: Prism::Location, value: Prism::Node).returns(Prism::IndexOperatorWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, opening_loc: self.opening_loc, arguments: self.arguments, closing_loc: self.closing_loc, block: self.block, binary_operator: self.binary_operator, binary_operator_loc: self.binary_operator_loc, value: self.value); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(T.nilable(String)) } + def call_operator; end + + sig { returns(String) } + def opening; end + + sig { returns(String) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `||=` operator on a call to `[]`. +# +# foo.bar[baz] ||= value +# ^^^^^^^^^^^^^^^^^^^^^^ +class Prism::IndexOrWriteNode < Prism::Node + sig { returns(T::Boolean) } + def safe_navigation?; end + + sig { returns(T::Boolean) } + def variable_call?; end + + sig { returns(T::Boolean) } + def attribute_write?; end + + sig { returns(T::Boolean) } + def ignore_visibility?; end + + sig { returns(T.nilable(Prism::Node)) } + def receiver; end + + sig { returns(T.nilable(Prism::Location)) } + def call_operator_loc; end + + sig { returns(Prism::Location) } + def opening_loc; end + + sig { returns(T.nilable(Prism::ArgumentsNode)) } + def arguments; end + + sig { returns(Prism::Location) } + def closing_loc; end + + sig { returns(T.nilable(Prism::BlockArgumentNode)) } + def block; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, receiver: T.nilable(Prism::Node), call_operator_loc: T.nilable(Prism::Location), opening_loc: Prism::Location, arguments: T.nilable(Prism::ArgumentsNode), closing_loc: Prism::Location, block: T.nilable(Prism::BlockArgumentNode), operator_loc: Prism::Location, value: Prism::Node).void } + def initialize(source, node_id, location, flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, operator_loc, value); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, receiver: T.nilable(Prism::Node), call_operator_loc: T.nilable(Prism::Location), opening_loc: Prism::Location, arguments: T.nilable(Prism::ArgumentsNode), closing_loc: Prism::Location, block: T.nilable(Prism::BlockArgumentNode), operator_loc: Prism::Location, value: Prism::Node).returns(Prism::IndexOrWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, opening_loc: self.opening_loc, arguments: self.arguments, closing_loc: self.closing_loc, block: self.block, operator_loc: self.operator_loc, value: self.value); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(T.nilable(String)) } + def call_operator; end + + sig { returns(String) } + def opening; end + + sig { returns(String) } + def closing; end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents assigning to an index. +# +# foo[bar], = 1 +# ^^^^^^^^ +# +# begin +# rescue => foo[bar] +# ^^^^^^^^ +# end +# +# for foo[bar] in baz do end +# ^^^^^^^^ +class Prism::IndexTargetNode < Prism::Node + sig { returns(T::Boolean) } + def safe_navigation?; end + + sig { returns(T::Boolean) } + def variable_call?; end + + sig { returns(T::Boolean) } + def attribute_write?; end + + sig { returns(T::Boolean) } + def ignore_visibility?; end + + sig { returns(Prism::Node) } + def receiver; end + + sig { returns(Prism::Location) } + def opening_loc; end + + sig { returns(T.nilable(Prism::ArgumentsNode)) } + def arguments; end + + sig { returns(Prism::Location) } + def closing_loc; end + + sig { returns(T.nilable(Prism::BlockArgumentNode)) } + def block; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, receiver: Prism::Node, opening_loc: Prism::Location, arguments: T.nilable(Prism::ArgumentsNode), closing_loc: Prism::Location, block: T.nilable(Prism::BlockArgumentNode)).void } + def initialize(source, node_id, location, flags, receiver, opening_loc, arguments, closing_loc, block); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, receiver: Prism::Node, opening_loc: Prism::Location, arguments: T.nilable(Prism::ArgumentsNode), closing_loc: Prism::Location, block: T.nilable(Prism::BlockArgumentNode)).returns(Prism::IndexTargetNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, opening_loc: self.opening_loc, arguments: self.arguments, closing_loc: self.closing_loc, block: self.block); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def opening; end + + sig { returns(String) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `&&=` operator for assignment to an instance variable. +# +# @target &&= value +# ^^^^^^^^^^^^^^^^^ +class Prism::InstanceVariableAndWriteNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { returns(Prism::Location) } + def name_loc; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).void } + def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::InstanceVariableAndWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents assigning to an instance variable using an operator that isn't `=`. +# +# @target += value +# ^^^^^^^^^^^^^^^^ +class Prism::InstanceVariableOperatorWriteNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { returns(Prism::Location) } + def name_loc; end + + sig { returns(Prism::Location) } + def binary_operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { returns(Symbol) } + def binary_operator; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, binary_operator_loc: Prism::Location, value: Prism::Node, binary_operator: Symbol).void } + def initialize(source, node_id, location, flags, name, name_loc, binary_operator_loc, value, binary_operator); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, binary_operator_loc: Prism::Location, value: Prism::Node, binary_operator: Symbol).returns(Prism::InstanceVariableOperatorWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, binary_operator_loc: self.binary_operator_loc, value: self.value, binary_operator: self.binary_operator); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `||=` operator for assignment to an instance variable. +# +# @target ||= value +# ^^^^^^^^^^^^^^^^^ +class Prism::InstanceVariableOrWriteNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { returns(Prism::Location) } + def name_loc; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).void } + def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::InstanceVariableOrWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents referencing an instance variable. +# +# @foo +# ^^^^ +class Prism::InstanceVariableReadNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).void } + def initialize(source, node_id, location, flags, name); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).returns(Prism::InstanceVariableReadNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents writing to an instance variable in a context that doesn't have an explicit value. +# +# @foo, @bar = baz +# ^^^^ ^^^^ +class Prism::InstanceVariableTargetNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).void } + def initialize(source, node_id, location, flags, name); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).returns(Prism::InstanceVariableTargetNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents writing to an instance variable. +# +# @foo = 1 +# ^^^^^^^^ +class Prism::InstanceVariableWriteNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { returns(Prism::Location) } + def name_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, value: Prism::Node, operator_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, name, name_loc, value, operator_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, value: Prism::Node, operator_loc: Prism::Location).returns(Prism::InstanceVariableWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, value: self.value, operator_loc: self.operator_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents an integer number literal. +# +# 1 +# ^ +class Prism::IntegerNode < Prism::Node + sig { returns(T::Boolean) } + def binary?; end + + sig { returns(T::Boolean) } + def decimal?; end + + sig { returns(T::Boolean) } + def octal?; end + + sig { returns(T::Boolean) } + def hexadecimal?; end + + sig { returns(Integer) } + def value; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, value: Integer).void } + def initialize(source, node_id, location, flags, value); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, value: Integer).returns(Prism::IntegerNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, value: self.value); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a regular expression literal that contains interpolation that is being used in the predicate of a conditional to implicitly match against the last line read by an IO object. +# +# if /foo #{bar} baz/ then end +# ^^^^^^^^^^^^^^^^ +class Prism::InterpolatedMatchLastLineNode < Prism::Node + sig { returns(T::Boolean) } + def ignore_case?; end + + sig { returns(T::Boolean) } + def extended?; end + + sig { returns(T::Boolean) } + def multi_line?; end + + sig { returns(T::Boolean) } + def once?; end + + sig { returns(T::Boolean) } + def euc_jp?; end + + sig { returns(T::Boolean) } + def ascii_8bit?; end + + sig { returns(T::Boolean) } + def windows_31j?; end + + sig { returns(T::Boolean) } + def utf_8?; end + + sig { returns(T::Boolean) } + def forced_utf8_encoding?; end + + sig { returns(T::Boolean) } + def forced_binary_encoding?; end + + sig { returns(T::Boolean) } + def forced_us_ascii_encoding?; end + + sig { returns(Prism::Location) } + def opening_loc; end + + sig { returns(T::Array[T.any(Prism::StringNode, Prism::EmbeddedStatementsNode, Prism::EmbeddedVariableNode)]) } + def parts; end + + sig { returns(Prism::Location) } + def closing_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: Prism::Location, parts: T::Array[T.any(Prism::StringNode, Prism::EmbeddedStatementsNode, Prism::EmbeddedVariableNode)], closing_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, opening_loc, parts, closing_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: Prism::Location, parts: T::Array[T.any(Prism::StringNode, Prism::EmbeddedStatementsNode, Prism::EmbeddedVariableNode)], closing_loc: Prism::Location).returns(Prism::InterpolatedMatchLastLineNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, parts: self.parts, closing_loc: self.closing_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def opening; end + + sig { returns(String) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a regular expression literal that contains interpolation. +# +# /foo #{bar} baz/ +# ^^^^^^^^^^^^^^^^ +class Prism::InterpolatedRegularExpressionNode < Prism::Node + sig { returns(T::Boolean) } + def ignore_case?; end + + sig { returns(T::Boolean) } + def extended?; end + + sig { returns(T::Boolean) } + def multi_line?; end + + sig { returns(T::Boolean) } + def once?; end + + sig { returns(T::Boolean) } + def euc_jp?; end + + sig { returns(T::Boolean) } + def ascii_8bit?; end + + sig { returns(T::Boolean) } + def windows_31j?; end + + sig { returns(T::Boolean) } + def utf_8?; end + + sig { returns(T::Boolean) } + def forced_utf8_encoding?; end + + sig { returns(T::Boolean) } + def forced_binary_encoding?; end + + sig { returns(T::Boolean) } + def forced_us_ascii_encoding?; end + + sig { returns(Prism::Location) } + def opening_loc; end + + sig { returns(T::Array[T.any(Prism::StringNode, Prism::EmbeddedStatementsNode, Prism::EmbeddedVariableNode)]) } + def parts; end + + sig { returns(Prism::Location) } + def closing_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: Prism::Location, parts: T::Array[T.any(Prism::StringNode, Prism::EmbeddedStatementsNode, Prism::EmbeddedVariableNode)], closing_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, opening_loc, parts, closing_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: Prism::Location, parts: T::Array[T.any(Prism::StringNode, Prism::EmbeddedStatementsNode, Prism::EmbeddedVariableNode)], closing_loc: Prism::Location).returns(Prism::InterpolatedRegularExpressionNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, parts: self.parts, closing_loc: self.closing_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def opening; end + + sig { returns(String) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a string literal that contains interpolation. +# +# "foo #{bar} baz" +# ^^^^^^^^^^^^^^^^ +class Prism::InterpolatedStringNode < Prism::Node + sig { returns(T::Boolean) } + def frozen?; end + + sig { returns(T::Boolean) } + def mutable?; end + + sig { returns(T.nilable(Prism::Location)) } + def opening_loc; end + + sig { returns(T::Array[T.any(Prism::StringNode, Prism::EmbeddedStatementsNode, Prism::EmbeddedVariableNode, Prism::InterpolatedStringNode, Prism::XStringNode)]) } + def parts; end + + sig { returns(T.nilable(Prism::Location)) } + def closing_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: T.nilable(Prism::Location), parts: T::Array[T.any(Prism::StringNode, Prism::EmbeddedStatementsNode, Prism::EmbeddedVariableNode, Prism::InterpolatedStringNode, Prism::XStringNode)], closing_loc: T.nilable(Prism::Location)).void } + def initialize(source, node_id, location, flags, opening_loc, parts, closing_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: T.nilable(Prism::Location), parts: T::Array[T.any(Prism::StringNode, Prism::EmbeddedStatementsNode, Prism::EmbeddedVariableNode, Prism::InterpolatedStringNode, Prism::XStringNode)], closing_loc: T.nilable(Prism::Location)).returns(Prism::InterpolatedStringNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, parts: self.parts, closing_loc: self.closing_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(T.nilable(String)) } + def opening; end + + sig { returns(T.nilable(String)) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a symbol literal that contains interpolation. +# +# :"foo #{bar} baz" +# ^^^^^^^^^^^^^^^^^ +class Prism::InterpolatedSymbolNode < Prism::Node + sig { returns(T.nilable(Prism::Location)) } + def opening_loc; end + + sig { returns(T::Array[T.any(Prism::StringNode, Prism::EmbeddedStatementsNode, Prism::EmbeddedVariableNode)]) } + def parts; end + + sig { returns(T.nilable(Prism::Location)) } + def closing_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: T.nilable(Prism::Location), parts: T::Array[T.any(Prism::StringNode, Prism::EmbeddedStatementsNode, Prism::EmbeddedVariableNode)], closing_loc: T.nilable(Prism::Location)).void } + def initialize(source, node_id, location, flags, opening_loc, parts, closing_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: T.nilable(Prism::Location), parts: T::Array[T.any(Prism::StringNode, Prism::EmbeddedStatementsNode, Prism::EmbeddedVariableNode)], closing_loc: T.nilable(Prism::Location)).returns(Prism::InterpolatedSymbolNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, parts: self.parts, closing_loc: self.closing_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(T.nilable(String)) } + def opening; end + + sig { returns(T.nilable(String)) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents an xstring literal that contains interpolation. +# +# `foo #{bar} baz` +# ^^^^^^^^^^^^^^^^ +class Prism::InterpolatedXStringNode < Prism::Node + sig { returns(Prism::Location) } + def opening_loc; end + + sig { returns(T::Array[T.any(Prism::StringNode, Prism::EmbeddedStatementsNode, Prism::EmbeddedVariableNode)]) } + def parts; end + + sig { returns(Prism::Location) } + def closing_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: Prism::Location, parts: T::Array[T.any(Prism::StringNode, Prism::EmbeddedStatementsNode, Prism::EmbeddedVariableNode)], closing_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, opening_loc, parts, closing_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: Prism::Location, parts: T::Array[T.any(Prism::StringNode, Prism::EmbeddedStatementsNode, Prism::EmbeddedVariableNode)], closing_loc: Prism::Location).returns(Prism::InterpolatedXStringNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, parts: self.parts, closing_loc: self.closing_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def opening; end + + sig { returns(String) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents reading from the implicit `it` local variable. +# +# -> { it } +# ^^ +class Prism::ItLocalVariableReadNode < Prism::Node + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).void } + def initialize(source, node_id, location, flags); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::ItLocalVariableReadNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents an implicit set of parameters through the use of the `it` keyword within a block or lambda. +# +# -> { it + it } +# ^^^^^^^^^^^^^^ +class Prism::ItParametersNode < Prism::Node + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).void } + def initialize(source, node_id, location, flags); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::ItParametersNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a hash literal without opening and closing braces. +# +# foo(a: b) +# ^^^^ +class Prism::KeywordHashNode < Prism::Node + sig { returns(T::Boolean) } + def symbol_keys?; end + + sig { returns(T::Array[T.any(Prism::AssocNode, Prism::AssocSplatNode)]) } + def elements; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, elements: T::Array[T.any(Prism::AssocNode, Prism::AssocSplatNode)]).void } + def initialize(source, node_id, location, flags, elements); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, elements: T::Array[T.any(Prism::AssocNode, Prism::AssocSplatNode)]).returns(Prism::KeywordHashNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, elements: self.elements); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a keyword rest parameter to a method, block, or lambda definition. +# +# def a(**b) +# ^^^ +# end +class Prism::KeywordRestParameterNode < Prism::Node + sig { returns(T::Boolean) } + def repeated_parameter?; end + + sig { returns(T.nilable(Symbol)) } + def name; end + + sig { returns(T.nilable(Prism::Location)) } + def name_loc; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: T.nilable(Symbol), name_loc: T.nilable(Prism::Location), operator_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, name, name_loc, operator_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: T.nilable(Symbol), name_loc: T.nilable(Prism::Location), operator_loc: Prism::Location).returns(Prism::KeywordRestParameterNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents using a lambda literal (not the lambda method call). +# +# ->(value) { value * 2 } +# ^^^^^^^^^^^^^^^^^^^^^^^ +class Prism::LambdaNode < Prism::Node + sig { returns(T::Array[Symbol]) } + def locals; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(Prism::Location) } + def opening_loc; end + + sig { returns(Prism::Location) } + def closing_loc; end + + sig { returns(T.nilable(T.any(Prism::BlockParametersNode, Prism::NumberedParametersNode, Prism::ItParametersNode))) } + def parameters; end + + sig { returns(T.nilable(T.any(Prism::StatementsNode, Prism::BeginNode))) } + def body; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, locals: T::Array[Symbol], operator_loc: Prism::Location, opening_loc: Prism::Location, closing_loc: Prism::Location, parameters: T.nilable(T.any(Prism::BlockParametersNode, Prism::NumberedParametersNode, Prism::ItParametersNode)), body: T.nilable(T.any(Prism::StatementsNode, Prism::BeginNode))).void } + def initialize(source, node_id, location, flags, locals, operator_loc, opening_loc, closing_loc, parameters, body); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, locals: T::Array[Symbol], operator_loc: Prism::Location, opening_loc: Prism::Location, closing_loc: Prism::Location, parameters: T.nilable(T.any(Prism::BlockParametersNode, Prism::NumberedParametersNode, Prism::ItParametersNode)), body: T.nilable(T.any(Prism::StatementsNode, Prism::BeginNode))).returns(Prism::LambdaNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, locals: self.locals, operator_loc: self.operator_loc, opening_loc: self.opening_loc, closing_loc: self.closing_loc, parameters: self.parameters, body: self.body); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { returns(String) } + def opening; end + + sig { returns(String) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `&&=` operator for assignment to a local variable. +# +# target &&= value +# ^^^^^^^^^^^^^^^^ +class Prism::LocalVariableAndWriteNode < Prism::Node + sig { returns(Prism::Location) } + def name_loc; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { returns(Symbol) } + def name; end + + sig { returns(Integer) } + def depth; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node, name: Symbol, depth: Integer).void } + def initialize(source, node_id, location, flags, name_loc, operator_loc, value, name, depth); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node, name: Symbol, depth: Integer).returns(Prism::LocalVariableAndWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value, name: self.name, depth: self.depth); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents assigning to a local variable using an operator that isn't `=`. +# +# target += value +# ^^^^^^^^^^^^^^^ +class Prism::LocalVariableOperatorWriteNode < Prism::Node + sig { returns(Prism::Location) } + def name_loc; end + + sig { returns(Prism::Location) } + def binary_operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { returns(Symbol) } + def name; end + + sig { returns(Symbol) } + def binary_operator; end + + sig { returns(Integer) } + def depth; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name_loc: Prism::Location, binary_operator_loc: Prism::Location, value: Prism::Node, name: Symbol, binary_operator: Symbol, depth: Integer).void } + def initialize(source, node_id, location, flags, name_loc, binary_operator_loc, value, name, binary_operator, depth); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name_loc: Prism::Location, binary_operator_loc: Prism::Location, value: Prism::Node, name: Symbol, binary_operator: Symbol, depth: Integer).returns(Prism::LocalVariableOperatorWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name_loc: self.name_loc, binary_operator_loc: self.binary_operator_loc, value: self.value, name: self.name, binary_operator: self.binary_operator, depth: self.depth); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `||=` operator for assignment to a local variable. +# +# target ||= value +# ^^^^^^^^^^^^^^^^ +class Prism::LocalVariableOrWriteNode < Prism::Node + sig { returns(Prism::Location) } + def name_loc; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { returns(Symbol) } + def name; end + + sig { returns(Integer) } + def depth; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node, name: Symbol, depth: Integer).void } + def initialize(source, node_id, location, flags, name_loc, operator_loc, value, name, depth); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node, name: Symbol, depth: Integer).returns(Prism::LocalVariableOrWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value, name: self.name, depth: self.depth); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents reading a local variable. Note that this requires that a local variable of the same name has already been written to in the same scope, otherwise it is parsed as a method call. +# +# foo +# ^^^ +class Prism::LocalVariableReadNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { returns(Integer) } + def depth; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, depth: Integer).void } + def initialize(source, node_id, location, flags, name, depth); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, depth: Integer).returns(Prism::LocalVariableReadNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, depth: self.depth); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents writing to a local variable in a context that doesn't have an explicit value. +# +# foo, bar = baz +# ^^^ ^^^ +class Prism::LocalVariableTargetNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { returns(Integer) } + def depth; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, depth: Integer).void } + def initialize(source, node_id, location, flags, name, depth); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, depth: Integer).returns(Prism::LocalVariableTargetNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, depth: self.depth); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents writing to a local variable. +# +# foo = 1 +# ^^^^^^^ +class Prism::LocalVariableWriteNode < Prism::Node + sig { returns(Symbol) } + def name; end + + sig { returns(Integer) } + def depth; end + + sig { returns(Prism::Location) } + def name_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, depth: Integer, name_loc: Prism::Location, value: Prism::Node, operator_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, name, depth, name_loc, value, operator_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, depth: Integer, name_loc: Prism::Location, value: Prism::Node, operator_loc: Prism::Location).returns(Prism::LocalVariableWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, depth: self.depth, name_loc: self.name_loc, value: self.value, operator_loc: self.operator_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a regular expression literal used in the predicate of a conditional to implicitly match against the last line read by an IO object. +# +# if /foo/i then end +# ^^^^^^ +class Prism::MatchLastLineNode < Prism::Node + sig { returns(T::Boolean) } + def ignore_case?; end + + sig { returns(T::Boolean) } + def extended?; end + + sig { returns(T::Boolean) } + def multi_line?; end + + sig { returns(T::Boolean) } + def once?; end + + sig { returns(T::Boolean) } + def euc_jp?; end + + sig { returns(T::Boolean) } + def ascii_8bit?; end + + sig { returns(T::Boolean) } + def windows_31j?; end + + sig { returns(T::Boolean) } + def utf_8?; end + + sig { returns(T::Boolean) } + def forced_utf8_encoding?; end + + sig { returns(T::Boolean) } + def forced_binary_encoding?; end + + sig { returns(T::Boolean) } + def forced_us_ascii_encoding?; end + + sig { returns(Prism::Location) } + def opening_loc; end + + sig { returns(Prism::Location) } + def content_loc; end + + sig { returns(Prism::Location) } + def closing_loc; end + + sig { returns(String) } + def unescaped; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: Prism::Location, content_loc: Prism::Location, closing_loc: Prism::Location, unescaped: String).void } + def initialize(source, node_id, location, flags, opening_loc, content_loc, closing_loc, unescaped); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: Prism::Location, content_loc: Prism::Location, closing_loc: Prism::Location, unescaped: String).returns(Prism::MatchLastLineNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, content_loc: self.content_loc, closing_loc: self.closing_loc, unescaped: self.unescaped); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def opening; end + + sig { returns(String) } + def content; end + + sig { returns(String) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the modifier `in` operator. +# +# foo in bar +# ^^^^^^^^^^ +class Prism::MatchPredicateNode < Prism::Node + sig { returns(Prism::Node) } + def value; end + + sig { returns(Prism::Node) } + def pattern; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, value: Prism::Node, pattern: Prism::Node, operator_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, value, pattern, operator_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, value: Prism::Node, pattern: Prism::Node, operator_loc: Prism::Location).returns(Prism::MatchPredicateNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, value: self.value, pattern: self.pattern, operator_loc: self.operator_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `=>` operator. +# +# foo => bar +# ^^^^^^^^^^ +class Prism::MatchRequiredNode < Prism::Node + sig { returns(Prism::Node) } + def value; end + + sig { returns(Prism::Node) } + def pattern; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, value: Prism::Node, pattern: Prism::Node, operator_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, value, pattern, operator_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, value: Prism::Node, pattern: Prism::Node, operator_loc: Prism::Location).returns(Prism::MatchRequiredNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, value: self.value, pattern: self.pattern, operator_loc: self.operator_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents writing local variables using a regular expression match with named capture groups. +# +# /(?bar)/ =~ baz +# ^^^^^^^^^^^^^^^^^^^^ +class Prism::MatchWriteNode < Prism::Node + sig { returns(Prism::CallNode) } + def call; end + + sig { returns(T::Array[Prism::LocalVariableTargetNode]) } + def targets; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, call: Prism::CallNode, targets: T::Array[Prism::LocalVariableTargetNode]).void } + def initialize(source, node_id, location, flags, call, targets); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, call: Prism::CallNode, targets: T::Array[Prism::LocalVariableTargetNode]).returns(Prism::MatchWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, call: self.call, targets: self.targets); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a node that is missing from the source and results in a syntax error. +class Prism::MissingNode < Prism::Node + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).void } + def initialize(source, node_id, location, flags); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::MissingNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a module declaration involving the `module` keyword. +# +# module Foo end +# ^^^^^^^^^^^^^^ +class Prism::ModuleNode < Prism::Node + sig { returns(T::Array[Symbol]) } + def locals; end + + sig { returns(Prism::Location) } + def module_keyword_loc; end + + sig { returns(T.any(Prism::ConstantReadNode, Prism::ConstantPathNode, Prism::MissingNode)) } + def constant_path; end + + sig { returns(T.nilable(T.any(Prism::StatementsNode, Prism::BeginNode))) } + def body; end + + sig { returns(Prism::Location) } + def end_keyword_loc; end + + sig { returns(Symbol) } + def name; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, locals: T::Array[Symbol], module_keyword_loc: Prism::Location, constant_path: T.any(Prism::ConstantReadNode, Prism::ConstantPathNode, Prism::MissingNode), body: T.nilable(T.any(Prism::StatementsNode, Prism::BeginNode)), end_keyword_loc: Prism::Location, name: Symbol).void } + def initialize(source, node_id, location, flags, locals, module_keyword_loc, constant_path, body, end_keyword_loc, name); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, locals: T::Array[Symbol], module_keyword_loc: Prism::Location, constant_path: T.any(Prism::ConstantReadNode, Prism::ConstantPathNode, Prism::MissingNode), body: T.nilable(T.any(Prism::StatementsNode, Prism::BeginNode)), end_keyword_loc: Prism::Location, name: Symbol).returns(Prism::ModuleNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, locals: self.locals, module_keyword_loc: self.module_keyword_loc, constant_path: self.constant_path, body: self.body, end_keyword_loc: self.end_keyword_loc, name: self.name); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def module_keyword; end + + sig { returns(String) } + def end_keyword; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a multi-target expression. +# +# a, (b, c) = 1, 2, 3 +# ^^^^^^ +# +# This can be a part of `MultiWriteNode` as above, or the target of a `for` loop +# +# for a, b in [[1, 2], [3, 4]] +# ^^^^ +class Prism::MultiTargetNode < Prism::Node + sig { returns(T::Array[T.any(Prism::LocalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::ConstantTargetNode, Prism::ConstantPathTargetNode, Prism::CallTargetNode, Prism::IndexTargetNode, Prism::MultiTargetNode, Prism::RequiredParameterNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode)]) } + def lefts; end + + sig { returns(T.nilable(T.any(Prism::ImplicitRestNode, Prism::SplatNode))) } + def rest; end + + sig { returns(T::Array[T.any(Prism::LocalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::ConstantTargetNode, Prism::ConstantPathTargetNode, Prism::CallTargetNode, Prism::IndexTargetNode, Prism::MultiTargetNode, Prism::RequiredParameterNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode)]) } + def rights; end + + sig { returns(T.nilable(Prism::Location)) } + def lparen_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def rparen_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, lefts: T::Array[T.any(Prism::LocalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::ConstantTargetNode, Prism::ConstantPathTargetNode, Prism::CallTargetNode, Prism::IndexTargetNode, Prism::MultiTargetNode, Prism::RequiredParameterNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode)], rest: T.nilable(T.any(Prism::ImplicitRestNode, Prism::SplatNode)), rights: T::Array[T.any(Prism::LocalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::ConstantTargetNode, Prism::ConstantPathTargetNode, Prism::CallTargetNode, Prism::IndexTargetNode, Prism::MultiTargetNode, Prism::RequiredParameterNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode)], lparen_loc: T.nilable(Prism::Location), rparen_loc: T.nilable(Prism::Location)).void } + def initialize(source, node_id, location, flags, lefts, rest, rights, lparen_loc, rparen_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, lefts: T::Array[T.any(Prism::LocalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::ConstantTargetNode, Prism::ConstantPathTargetNode, Prism::CallTargetNode, Prism::IndexTargetNode, Prism::MultiTargetNode, Prism::RequiredParameterNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode)], rest: T.nilable(T.any(Prism::ImplicitRestNode, Prism::SplatNode)), rights: T::Array[T.any(Prism::LocalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::ConstantTargetNode, Prism::ConstantPathTargetNode, Prism::CallTargetNode, Prism::IndexTargetNode, Prism::MultiTargetNode, Prism::RequiredParameterNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode)], lparen_loc: T.nilable(Prism::Location), rparen_loc: T.nilable(Prism::Location)).returns(Prism::MultiTargetNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, lefts: self.lefts, rest: self.rest, rights: self.rights, lparen_loc: self.lparen_loc, rparen_loc: self.rparen_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(T.nilable(String)) } + def lparen; end + + sig { returns(T.nilable(String)) } + def rparen; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a write to a multi-target expression. +# +# a, b, c = 1, 2, 3 +# ^^^^^^^^^^^^^^^^^ +class Prism::MultiWriteNode < Prism::Node + sig { returns(T::Array[T.any(Prism::LocalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::ConstantTargetNode, Prism::ConstantPathTargetNode, Prism::CallTargetNode, Prism::IndexTargetNode, Prism::MultiTargetNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode)]) } + def lefts; end + + sig { returns(T.nilable(T.any(Prism::ImplicitRestNode, Prism::SplatNode))) } + def rest; end + + sig { returns(T::Array[T.any(Prism::LocalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::ConstantTargetNode, Prism::ConstantPathTargetNode, Prism::CallTargetNode, Prism::IndexTargetNode, Prism::MultiTargetNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode)]) } + def rights; end + + sig { returns(T.nilable(Prism::Location)) } + def lparen_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def rparen_loc; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, lefts: T::Array[T.any(Prism::LocalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::ConstantTargetNode, Prism::ConstantPathTargetNode, Prism::CallTargetNode, Prism::IndexTargetNode, Prism::MultiTargetNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode)], rest: T.nilable(T.any(Prism::ImplicitRestNode, Prism::SplatNode)), rights: T::Array[T.any(Prism::LocalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::ConstantTargetNode, Prism::ConstantPathTargetNode, Prism::CallTargetNode, Prism::IndexTargetNode, Prism::MultiTargetNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode)], lparen_loc: T.nilable(Prism::Location), rparen_loc: T.nilable(Prism::Location), operator_loc: Prism::Location, value: Prism::Node).void } + def initialize(source, node_id, location, flags, lefts, rest, rights, lparen_loc, rparen_loc, operator_loc, value); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, lefts: T::Array[T.any(Prism::LocalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::ConstantTargetNode, Prism::ConstantPathTargetNode, Prism::CallTargetNode, Prism::IndexTargetNode, Prism::MultiTargetNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode)], rest: T.nilable(T.any(Prism::ImplicitRestNode, Prism::SplatNode)), rights: T::Array[T.any(Prism::LocalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::ConstantTargetNode, Prism::ConstantPathTargetNode, Prism::CallTargetNode, Prism::IndexTargetNode, Prism::MultiTargetNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode)], lparen_loc: T.nilable(Prism::Location), rparen_loc: T.nilable(Prism::Location), operator_loc: Prism::Location, value: Prism::Node).returns(Prism::MultiWriteNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, lefts: self.lefts, rest: self.rest, rights: self.rights, lparen_loc: self.lparen_loc, rparen_loc: self.rparen_loc, operator_loc: self.operator_loc, value: self.value); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(T.nilable(String)) } + def lparen; end + + sig { returns(T.nilable(String)) } + def rparen; end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `next` keyword. +# +# next 1 +# ^^^^^^ +class Prism::NextNode < Prism::Node + sig { returns(T.nilable(Prism::ArgumentsNode)) } + def arguments; end + + sig { returns(Prism::Location) } + def keyword_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, arguments: T.nilable(Prism::ArgumentsNode), keyword_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, arguments, keyword_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, arguments: T.nilable(Prism::ArgumentsNode), keyword_loc: Prism::Location).returns(Prism::NextNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, arguments: self.arguments, keyword_loc: self.keyword_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def keyword; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `nil` keyword. +# +# nil +# ^^^ +class Prism::NilNode < Prism::Node + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).void } + def initialize(source, node_id, location, flags); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::NilNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of `**nil` inside method arguments. +# +# def a(**nil) +# ^^^^^ +# end +class Prism::NoKeywordsParameterNode < Prism::Node + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(Prism::Location) } + def keyword_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, operator_loc: Prism::Location, keyword_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, operator_loc, keyword_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, operator_loc: Prism::Location, keyword_loc: Prism::Location).returns(Prism::NoKeywordsParameterNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, operator_loc: self.operator_loc, keyword_loc: self.keyword_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { returns(String) } + def keyword; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents an implicit set of parameters through the use of numbered parameters within a block or lambda. +# +# -> { _1 + _2 } +# ^^^^^^^^^^^^^^ +class Prism::NumberedParametersNode < Prism::Node + sig { returns(Integer) } + def maximum; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, maximum: Integer).void } + def initialize(source, node_id, location, flags, maximum); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, maximum: Integer).returns(Prism::NumberedParametersNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, maximum: self.maximum); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents reading a numbered reference to a capture in the previous match. +# +# $1 +# ^^ +class Prism::NumberedReferenceReadNode < Prism::Node + sig { returns(Integer) } + def number; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, number: Integer).void } + def initialize(source, node_id, location, flags, number); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, number: Integer).returns(Prism::NumberedReferenceReadNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, number: self.number); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents an optional keyword parameter to a method, block, or lambda definition. +# +# def a(b: 1) +# ^^^^ +# end +class Prism::OptionalKeywordParameterNode < Prism::Node + sig { returns(T::Boolean) } + def repeated_parameter?; end + + sig { returns(Symbol) } + def name; end + + sig { returns(Prism::Location) } + def name_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, value: Prism::Node).void } + def initialize(source, node_id, location, flags, name, name_loc, value); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, value: Prism::Node).returns(Prism::OptionalKeywordParameterNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, value: self.value); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents an optional parameter to a method, block, or lambda definition. +# +# def a(b = 1) +# ^^^^^ +# end +class Prism::OptionalParameterNode < Prism::Node + sig { returns(T::Boolean) } + def repeated_parameter?; end + + sig { returns(Symbol) } + def name; end + + sig { returns(Prism::Location) } + def name_loc; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(Prism::Node) } + def value; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).void } + def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location, operator_loc: Prism::Location, value: Prism::Node).returns(Prism::OptionalParameterNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `||` operator or the `or` keyword. +# +# left or right +# ^^^^^^^^^^^^^ +class Prism::OrNode < Prism::Node + sig { returns(Prism::Node) } + def left; end + + sig { returns(Prism::Node) } + def right; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, left: Prism::Node, right: Prism::Node, operator_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, left, right, operator_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, left: Prism::Node, right: Prism::Node, operator_loc: Prism::Location).returns(Prism::OrNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, left: self.left, right: self.right, operator_loc: self.operator_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the list of parameters on a method, block, or lambda definition. +# +# def a(b, c, d) +# ^^^^^^^ +# end +class Prism::ParametersNode < Prism::Node + sig { returns(T::Array[T.any(Prism::RequiredParameterNode, Prism::MultiTargetNode)]) } + def requireds; end + + sig { returns(T::Array[Prism::OptionalParameterNode]) } + def optionals; end + + sig { returns(T.nilable(T.any(Prism::RestParameterNode, Prism::ImplicitRestNode))) } + def rest; end + + sig { returns(T::Array[T.any(Prism::RequiredParameterNode, Prism::MultiTargetNode, Prism::KeywordRestParameterNode, Prism::NoKeywordsParameterNode, Prism::ForwardingParameterNode)]) } + def posts; end + + sig { returns(T::Array[T.any(Prism::RequiredKeywordParameterNode, Prism::OptionalKeywordParameterNode)]) } + def keywords; end + + sig { returns(T.nilable(T.any(Prism::KeywordRestParameterNode, Prism::ForwardingParameterNode, Prism::NoKeywordsParameterNode))) } + def keyword_rest; end + + sig { returns(T.nilable(Prism::BlockParameterNode)) } + def block; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, requireds: T::Array[T.any(Prism::RequiredParameterNode, Prism::MultiTargetNode)], optionals: T::Array[Prism::OptionalParameterNode], rest: T.nilable(T.any(Prism::RestParameterNode, Prism::ImplicitRestNode)), posts: T::Array[T.any(Prism::RequiredParameterNode, Prism::MultiTargetNode, Prism::KeywordRestParameterNode, Prism::NoKeywordsParameterNode, Prism::ForwardingParameterNode)], keywords: T::Array[T.any(Prism::RequiredKeywordParameterNode, Prism::OptionalKeywordParameterNode)], keyword_rest: T.nilable(T.any(Prism::KeywordRestParameterNode, Prism::ForwardingParameterNode, Prism::NoKeywordsParameterNode)), block: T.nilable(Prism::BlockParameterNode)).void } + def initialize(source, node_id, location, flags, requireds, optionals, rest, posts, keywords, keyword_rest, block); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, requireds: T::Array[T.any(Prism::RequiredParameterNode, Prism::MultiTargetNode)], optionals: T::Array[Prism::OptionalParameterNode], rest: T.nilable(T.any(Prism::RestParameterNode, Prism::ImplicitRestNode)), posts: T::Array[T.any(Prism::RequiredParameterNode, Prism::MultiTargetNode, Prism::KeywordRestParameterNode, Prism::NoKeywordsParameterNode, Prism::ForwardingParameterNode)], keywords: T::Array[T.any(Prism::RequiredKeywordParameterNode, Prism::OptionalKeywordParameterNode)], keyword_rest: T.nilable(T.any(Prism::KeywordRestParameterNode, Prism::ForwardingParameterNode, Prism::NoKeywordsParameterNode)), block: T.nilable(Prism::BlockParameterNode)).returns(Prism::ParametersNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, requireds: self.requireds, optionals: self.optionals, rest: self.rest, posts: self.posts, keywords: self.keywords, keyword_rest: self.keyword_rest, block: self.block); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a parenthesized expression +# +# (10 + 34) +# ^^^^^^^^^ +class Prism::ParenthesesNode < Prism::Node + sig { returns(T::Boolean) } + def multiple_statements?; end + + sig { returns(T.nilable(Prism::Node)) } + def body; end + + sig { returns(Prism::Location) } + def opening_loc; end + + sig { returns(Prism::Location) } + def closing_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, body: T.nilable(Prism::Node), opening_loc: Prism::Location, closing_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, body, opening_loc, closing_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, body: T.nilable(Prism::Node), opening_loc: Prism::Location, closing_loc: Prism::Location).returns(Prism::ParenthesesNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, body: self.body, opening_loc: self.opening_loc, closing_loc: self.closing_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def opening; end + + sig { returns(String) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `^` operator for pinning an expression in a pattern matching expression. +# +# foo in ^(bar) +# ^^^^^^ +class Prism::PinnedExpressionNode < Prism::Node + sig { returns(Prism::Node) } + def expression; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(Prism::Location) } + def lparen_loc; end + + sig { returns(Prism::Location) } + def rparen_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, expression: Prism::Node, operator_loc: Prism::Location, lparen_loc: Prism::Location, rparen_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, expression, operator_loc, lparen_loc, rparen_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, expression: Prism::Node, operator_loc: Prism::Location, lparen_loc: Prism::Location, rparen_loc: Prism::Location).returns(Prism::PinnedExpressionNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, expression: self.expression, operator_loc: self.operator_loc, lparen_loc: self.lparen_loc, rparen_loc: self.rparen_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { returns(String) } + def lparen; end + + sig { returns(String) } + def rparen; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `^` operator for pinning a variable in a pattern matching expression. +# +# foo in ^bar +# ^^^^ +class Prism::PinnedVariableNode < Prism::Node + sig { returns(T.any(Prism::LocalVariableReadNode, Prism::InstanceVariableReadNode, Prism::ClassVariableReadNode, Prism::GlobalVariableReadNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode, Prism::ItLocalVariableReadNode, Prism::MissingNode)) } + def variable; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, variable: T.any(Prism::LocalVariableReadNode, Prism::InstanceVariableReadNode, Prism::ClassVariableReadNode, Prism::GlobalVariableReadNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode, Prism::ItLocalVariableReadNode, Prism::MissingNode), operator_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, variable, operator_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, variable: T.any(Prism::LocalVariableReadNode, Prism::InstanceVariableReadNode, Prism::ClassVariableReadNode, Prism::GlobalVariableReadNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode, Prism::ItLocalVariableReadNode, Prism::MissingNode), operator_loc: Prism::Location).returns(Prism::PinnedVariableNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, variable: self.variable, operator_loc: self.operator_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `END` keyword. +# +# END { foo } +# ^^^^^^^^^^^ +class Prism::PostExecutionNode < Prism::Node + sig { returns(T.nilable(Prism::StatementsNode)) } + def statements; end + + sig { returns(Prism::Location) } + def keyword_loc; end + + sig { returns(Prism::Location) } + def opening_loc; end + + sig { returns(Prism::Location) } + def closing_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, statements: T.nilable(Prism::StatementsNode), keyword_loc: Prism::Location, opening_loc: Prism::Location, closing_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, statements, keyword_loc, opening_loc, closing_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, statements: T.nilable(Prism::StatementsNode), keyword_loc: Prism::Location, opening_loc: Prism::Location, closing_loc: Prism::Location).returns(Prism::PostExecutionNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, statements: self.statements, keyword_loc: self.keyword_loc, opening_loc: self.opening_loc, closing_loc: self.closing_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def keyword; end + + sig { returns(String) } + def opening; end + + sig { returns(String) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `BEGIN` keyword. +# +# BEGIN { foo } +# ^^^^^^^^^^^^^ +class Prism::PreExecutionNode < Prism::Node + sig { returns(T.nilable(Prism::StatementsNode)) } + def statements; end + + sig { returns(Prism::Location) } + def keyword_loc; end + + sig { returns(Prism::Location) } + def opening_loc; end + + sig { returns(Prism::Location) } + def closing_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, statements: T.nilable(Prism::StatementsNode), keyword_loc: Prism::Location, opening_loc: Prism::Location, closing_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, statements, keyword_loc, opening_loc, closing_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, statements: T.nilable(Prism::StatementsNode), keyword_loc: Prism::Location, opening_loc: Prism::Location, closing_loc: Prism::Location).returns(Prism::PreExecutionNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, statements: self.statements, keyword_loc: self.keyword_loc, opening_loc: self.opening_loc, closing_loc: self.closing_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def keyword; end + + sig { returns(String) } + def opening; end + + sig { returns(String) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# The top level node of any parse tree. +class Prism::ProgramNode < Prism::Node + sig { returns(T::Array[Symbol]) } + def locals; end + + sig { returns(Prism::StatementsNode) } + def statements; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, locals: T::Array[Symbol], statements: Prism::StatementsNode).void } + def initialize(source, node_id, location, flags, locals, statements); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, locals: T::Array[Symbol], statements: Prism::StatementsNode).returns(Prism::ProgramNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, locals: self.locals, statements: self.statements); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `..` or `...` operators. +# +# 1..2 +# ^^^^ +# +# c if a =~ /left/ ... b =~ /right/ +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +class Prism::RangeNode < Prism::Node + sig { returns(T::Boolean) } + def exclude_end?; end + + sig { returns(T.nilable(Prism::Node)) } + def left; end + + sig { returns(T.nilable(Prism::Node)) } + def right; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, left: T.nilable(Prism::Node), right: T.nilable(Prism::Node), operator_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, left, right, operator_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, left: T.nilable(Prism::Node), right: T.nilable(Prism::Node), operator_loc: Prism::Location).returns(Prism::RangeNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, left: self.left, right: self.right, operator_loc: self.operator_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a rational number literal. +# +# 1.0r +# ^^^^ +class Prism::RationalNode < Prism::Node + sig { returns(T::Boolean) } + def binary?; end + + sig { returns(T::Boolean) } + def decimal?; end + + sig { returns(T::Boolean) } + def octal?; end + + sig { returns(T::Boolean) } + def hexadecimal?; end + + sig { returns(Integer) } + def numerator; end + + sig { returns(Integer) } + def denominator; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, numerator: Integer, denominator: Integer).void } + def initialize(source, node_id, location, flags, numerator, denominator); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, numerator: Integer, denominator: Integer).returns(Prism::RationalNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, numerator: self.numerator, denominator: self.denominator); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `redo` keyword. +# +# redo +# ^^^^ +class Prism::RedoNode < Prism::Node + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).void } + def initialize(source, node_id, location, flags); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::RedoNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a regular expression literal with no interpolation. +# +# /foo/i +# ^^^^^^ +class Prism::RegularExpressionNode < Prism::Node + sig { returns(T::Boolean) } + def ignore_case?; end + + sig { returns(T::Boolean) } + def extended?; end + + sig { returns(T::Boolean) } + def multi_line?; end + + sig { returns(T::Boolean) } + def once?; end + + sig { returns(T::Boolean) } + def euc_jp?; end + + sig { returns(T::Boolean) } + def ascii_8bit?; end + + sig { returns(T::Boolean) } + def windows_31j?; end + + sig { returns(T::Boolean) } + def utf_8?; end + + sig { returns(T::Boolean) } + def forced_utf8_encoding?; end + + sig { returns(T::Boolean) } + def forced_binary_encoding?; end + + sig { returns(T::Boolean) } + def forced_us_ascii_encoding?; end + + sig { returns(Prism::Location) } + def opening_loc; end + + sig { returns(Prism::Location) } + def content_loc; end + + sig { returns(Prism::Location) } + def closing_loc; end + + sig { returns(String) } + def unescaped; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: Prism::Location, content_loc: Prism::Location, closing_loc: Prism::Location, unescaped: String).void } + def initialize(source, node_id, location, flags, opening_loc, content_loc, closing_loc, unescaped); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: Prism::Location, content_loc: Prism::Location, closing_loc: Prism::Location, unescaped: String).returns(Prism::RegularExpressionNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, content_loc: self.content_loc, closing_loc: self.closing_loc, unescaped: self.unescaped); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def opening; end + + sig { returns(String) } + def content; end + + sig { returns(String) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a required keyword parameter to a method, block, or lambda definition. +# +# def a(b: ) +# ^^ +# end +class Prism::RequiredKeywordParameterNode < Prism::Node + sig { returns(T::Boolean) } + def repeated_parameter?; end + + sig { returns(Symbol) } + def name; end + + sig { returns(Prism::Location) } + def name_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, name, name_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol, name_loc: Prism::Location).returns(Prism::RequiredKeywordParameterNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a required parameter to a method, block, or lambda definition. +# +# def a(b) +# ^ +# end +class Prism::RequiredParameterNode < Prism::Node + sig { returns(T::Boolean) } + def repeated_parameter?; end + + sig { returns(Symbol) } + def name; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).void } + def initialize(source, node_id, location, flags, name); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: Symbol).returns(Prism::RequiredParameterNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents an expression modified with a rescue. +# +# foo rescue nil +# ^^^^^^^^^^^^^^ +class Prism::RescueModifierNode < Prism::Node + sig { returns(Prism::Node) } + def expression; end + + sig { returns(Prism::Location) } + def keyword_loc; end + + sig { returns(Prism::Node) } + def rescue_expression; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, expression: Prism::Node, keyword_loc: Prism::Location, rescue_expression: Prism::Node).void } + def initialize(source, node_id, location, flags, expression, keyword_loc, rescue_expression); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, expression: Prism::Node, keyword_loc: Prism::Location, rescue_expression: Prism::Node).returns(Prism::RescueModifierNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, expression: self.expression, keyword_loc: self.keyword_loc, rescue_expression: self.rescue_expression); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def keyword; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a rescue statement. +# +# begin +# rescue Foo, *splat, Bar => ex +# foo +# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +# end +# +# `Foo, *splat, Bar` are in the `exceptions` field. `ex` is in the `reference` field. +class Prism::RescueNode < Prism::Node + sig { returns(Prism::Location) } + def keyword_loc; end + + sig { returns(T::Array[Prism::Node]) } + def exceptions; end + + sig { returns(T.nilable(Prism::Location)) } + def operator_loc; end + + sig { returns(T.nilable(T.any(Prism::LocalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::ConstantTargetNode, Prism::ConstantPathTargetNode, Prism::CallTargetNode, Prism::IndexTargetNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode, Prism::MissingNode))) } + def reference; end + + sig { returns(T.nilable(Prism::Location)) } + def then_keyword_loc; end + + sig { returns(T.nilable(Prism::StatementsNode)) } + def statements; end + + sig { returns(T.nilable(Prism::RescueNode)) } + def subsequent; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, keyword_loc: Prism::Location, exceptions: T::Array[Prism::Node], operator_loc: T.nilable(Prism::Location), reference: T.nilable(T.any(Prism::LocalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::ConstantTargetNode, Prism::ConstantPathTargetNode, Prism::CallTargetNode, Prism::IndexTargetNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode, Prism::MissingNode)), then_keyword_loc: T.nilable(Prism::Location), statements: T.nilable(Prism::StatementsNode), subsequent: T.nilable(Prism::RescueNode)).void } + def initialize(source, node_id, location, flags, keyword_loc, exceptions, operator_loc, reference, then_keyword_loc, statements, subsequent); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, keyword_loc: Prism::Location, exceptions: T::Array[Prism::Node], operator_loc: T.nilable(Prism::Location), reference: T.nilable(T.any(Prism::LocalVariableTargetNode, Prism::InstanceVariableTargetNode, Prism::ClassVariableTargetNode, Prism::GlobalVariableTargetNode, Prism::ConstantTargetNode, Prism::ConstantPathTargetNode, Prism::CallTargetNode, Prism::IndexTargetNode, Prism::BackReferenceReadNode, Prism::NumberedReferenceReadNode, Prism::MissingNode)), then_keyword_loc: T.nilable(Prism::Location), statements: T.nilable(Prism::StatementsNode), subsequent: T.nilable(Prism::RescueNode)).returns(Prism::RescueNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, keyword_loc: self.keyword_loc, exceptions: self.exceptions, operator_loc: self.operator_loc, reference: self.reference, then_keyword_loc: self.then_keyword_loc, statements: self.statements, subsequent: self.subsequent); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def keyword; end + + sig { returns(T.nilable(String)) } + def operator; end + + sig { returns(T.nilable(String)) } + def then_keyword; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a rest parameter to a method, block, or lambda definition. +# +# def a(*b) +# ^^ +# end +class Prism::RestParameterNode < Prism::Node + sig { returns(T::Boolean) } + def repeated_parameter?; end + + sig { returns(T.nilable(Symbol)) } + def name; end + + sig { returns(T.nilable(Prism::Location)) } + def name_loc; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, name: T.nilable(Symbol), name_loc: T.nilable(Prism::Location), operator_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, name, name_loc, operator_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, name: T.nilable(Symbol), name_loc: T.nilable(Prism::Location), operator_loc: Prism::Location).returns(Prism::RestParameterNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `retry` keyword. +# +# retry +# ^^^^^ +class Prism::RetryNode < Prism::Node + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).void } + def initialize(source, node_id, location, flags); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::RetryNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `return` keyword. +# +# return 1 +# ^^^^^^^^ +class Prism::ReturnNode < Prism::Node + sig { returns(Prism::Location) } + def keyword_loc; end + + sig { returns(T.nilable(Prism::ArgumentsNode)) } + def arguments; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, keyword_loc: Prism::Location, arguments: T.nilable(Prism::ArgumentsNode)).void } + def initialize(source, node_id, location, flags, keyword_loc, arguments); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, keyword_loc: Prism::Location, arguments: T.nilable(Prism::ArgumentsNode)).returns(Prism::ReturnNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, keyword_loc: self.keyword_loc, arguments: self.arguments); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def keyword; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the `self` keyword. +# +# self +# ^^^^ +class Prism::SelfNode < Prism::Node + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).void } + def initialize(source, node_id, location, flags); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::SelfNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# This node wraps a constant write to indicate that when the value is written, it should have its shareability state modified. +# +# # shareable_constant_value: literal +# C = { a: 1 } +# ^^^^^^^^^^^^ +class Prism::ShareableConstantNode < Prism::Node + sig { returns(T::Boolean) } + def literal?; end + + sig { returns(T::Boolean) } + def experimental_everything?; end + + sig { returns(T::Boolean) } + def experimental_copy?; end + + sig { returns(T.any(Prism::ConstantWriteNode, Prism::ConstantAndWriteNode, Prism::ConstantOrWriteNode, Prism::ConstantOperatorWriteNode, Prism::ConstantPathWriteNode, Prism::ConstantPathAndWriteNode, Prism::ConstantPathOrWriteNode, Prism::ConstantPathOperatorWriteNode)) } + def write; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, write: T.any(Prism::ConstantWriteNode, Prism::ConstantAndWriteNode, Prism::ConstantOrWriteNode, Prism::ConstantOperatorWriteNode, Prism::ConstantPathWriteNode, Prism::ConstantPathAndWriteNode, Prism::ConstantPathOrWriteNode, Prism::ConstantPathOperatorWriteNode)).void } + def initialize(source, node_id, location, flags, write); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, write: T.any(Prism::ConstantWriteNode, Prism::ConstantAndWriteNode, Prism::ConstantOrWriteNode, Prism::ConstantOperatorWriteNode, Prism::ConstantPathWriteNode, Prism::ConstantPathAndWriteNode, Prism::ConstantPathOrWriteNode, Prism::ConstantPathOperatorWriteNode)).returns(Prism::ShareableConstantNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, write: self.write); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a singleton class declaration involving the `class` keyword. +# +# class << self end +# ^^^^^^^^^^^^^^^^^ +class Prism::SingletonClassNode < Prism::Node + sig { returns(T::Array[Symbol]) } + def locals; end + + sig { returns(Prism::Location) } + def class_keyword_loc; end + + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(Prism::Node) } + def expression; end + + sig { returns(T.nilable(T.any(Prism::StatementsNode, Prism::BeginNode))) } + def body; end + + sig { returns(Prism::Location) } + def end_keyword_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, locals: T::Array[Symbol], class_keyword_loc: Prism::Location, operator_loc: Prism::Location, expression: Prism::Node, body: T.nilable(T.any(Prism::StatementsNode, Prism::BeginNode)), end_keyword_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, locals, class_keyword_loc, operator_loc, expression, body, end_keyword_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, locals: T::Array[Symbol], class_keyword_loc: Prism::Location, operator_loc: Prism::Location, expression: Prism::Node, body: T.nilable(T.any(Prism::StatementsNode, Prism::BeginNode)), end_keyword_loc: Prism::Location).returns(Prism::SingletonClassNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, locals: self.locals, class_keyword_loc: self.class_keyword_loc, operator_loc: self.operator_loc, expression: self.expression, body: self.body, end_keyword_loc: self.end_keyword_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def class_keyword; end + + sig { returns(String) } + def operator; end + + sig { returns(String) } + def end_keyword; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `__ENCODING__` keyword. +# +# __ENCODING__ +# ^^^^^^^^^^^^ +class Prism::SourceEncodingNode < Prism::Node + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).void } + def initialize(source, node_id, location, flags); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::SourceEncodingNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `__FILE__` keyword. +# +# __FILE__ +# ^^^^^^^^ +class Prism::SourceFileNode < Prism::Node + sig { returns(T::Boolean) } + def forced_utf8_encoding?; end + + sig { returns(T::Boolean) } + def forced_binary_encoding?; end + + sig { returns(T::Boolean) } + def frozen?; end + + sig { returns(T::Boolean) } + def mutable?; end + + sig { returns(String) } + def filepath; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, filepath: String).void } + def initialize(source, node_id, location, flags, filepath); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, filepath: String).returns(Prism::SourceFileNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, filepath: self.filepath); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `__LINE__` keyword. +# +# __LINE__ +# ^^^^^^^^ +class Prism::SourceLineNode < Prism::Node + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).void } + def initialize(source, node_id, location, flags); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::SourceLineNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the splat operator. +# +# [*a] +# ^^ +class Prism::SplatNode < Prism::Node + sig { returns(Prism::Location) } + def operator_loc; end + + sig { returns(T.nilable(Prism::Node)) } + def expression; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, operator_loc: Prism::Location, expression: T.nilable(Prism::Node)).void } + def initialize(source, node_id, location, flags, operator_loc, expression); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, operator_loc: Prism::Location, expression: T.nilable(Prism::Node)).returns(Prism::SplatNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, operator_loc: self.operator_loc, expression: self.expression); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def operator; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a set of statements contained within some scope. +# +# foo; bar; baz +# ^^^^^^^^^^^^^ +class Prism::StatementsNode < Prism::Node + sig { returns(T::Array[Prism::Node]) } + def body; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, body: T::Array[Prism::Node]).void } + def initialize(source, node_id, location, flags, body); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, body: T::Array[Prism::Node]).returns(Prism::StatementsNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, body: self.body); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a string literal, a string contained within a `%w` list, or plain string content within an interpolated string. +# +# "foo" +# ^^^^^ +# +# %w[foo] +# ^^^ +# +# "foo #{bar} baz" +# ^^^^ ^^^^ +class Prism::StringNode < Prism::Node + sig { returns(T::Boolean) } + def forced_utf8_encoding?; end + + sig { returns(T::Boolean) } + def forced_binary_encoding?; end + + sig { returns(T::Boolean) } + def frozen?; end + + sig { returns(T::Boolean) } + def mutable?; end + + sig { returns(T.nilable(Prism::Location)) } + def opening_loc; end + + sig { returns(Prism::Location) } + def content_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def closing_loc; end + + sig { returns(String) } + def unescaped; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: T.nilable(Prism::Location), content_loc: Prism::Location, closing_loc: T.nilable(Prism::Location), unescaped: String).void } + def initialize(source, node_id, location, flags, opening_loc, content_loc, closing_loc, unescaped); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: T.nilable(Prism::Location), content_loc: Prism::Location, closing_loc: T.nilable(Prism::Location), unescaped: String).returns(Prism::StringNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, content_loc: self.content_loc, closing_loc: self.closing_loc, unescaped: self.unescaped); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(T.nilable(String)) } + def opening; end + + sig { returns(String) } + def content; end + + sig { returns(T.nilable(String)) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `super` keyword with parentheses or arguments. +# +# super() +# ^^^^^^^ +# +# super foo, bar +# ^^^^^^^^^^^^^^ +class Prism::SuperNode < Prism::Node + sig { returns(Prism::Location) } + def keyword_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def lparen_loc; end + + sig { returns(T.nilable(Prism::ArgumentsNode)) } + def arguments; end + + sig { returns(T.nilable(Prism::Location)) } + def rparen_loc; end + + sig { returns(T.nilable(T.any(Prism::BlockNode, Prism::BlockArgumentNode))) } + def block; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, keyword_loc: Prism::Location, lparen_loc: T.nilable(Prism::Location), arguments: T.nilable(Prism::ArgumentsNode), rparen_loc: T.nilable(Prism::Location), block: T.nilable(T.any(Prism::BlockNode, Prism::BlockArgumentNode))).void } + def initialize(source, node_id, location, flags, keyword_loc, lparen_loc, arguments, rparen_loc, block); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, keyword_loc: Prism::Location, lparen_loc: T.nilable(Prism::Location), arguments: T.nilable(Prism::ArgumentsNode), rparen_loc: T.nilable(Prism::Location), block: T.nilable(T.any(Prism::BlockNode, Prism::BlockArgumentNode))).returns(Prism::SuperNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, keyword_loc: self.keyword_loc, lparen_loc: self.lparen_loc, arguments: self.arguments, rparen_loc: self.rparen_loc, block: self.block); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def keyword; end + + sig { returns(T.nilable(String)) } + def lparen; end + + sig { returns(T.nilable(String)) } + def rparen; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents a symbol literal or a symbol contained within a `%i` list. +# +# :foo +# ^^^^ +# +# %i[foo] +# ^^^ +class Prism::SymbolNode < Prism::Node + sig { returns(T::Boolean) } + def forced_utf8_encoding?; end + + sig { returns(T::Boolean) } + def forced_binary_encoding?; end + + sig { returns(T::Boolean) } + def forced_us_ascii_encoding?; end + + sig { returns(T.nilable(Prism::Location)) } + def opening_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def value_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def closing_loc; end + + sig { returns(String) } + def unescaped; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: T.nilable(Prism::Location), value_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location), unescaped: String).void } + def initialize(source, node_id, location, flags, opening_loc, value_loc, closing_loc, unescaped); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: T.nilable(Prism::Location), value_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location), unescaped: String).returns(Prism::SymbolNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, value_loc: self.value_loc, closing_loc: self.closing_loc, unescaped: self.unescaped); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(T.nilable(String)) } + def opening; end + + sig { returns(T.nilable(String)) } + def value; end + + sig { returns(T.nilable(String)) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the literal `true` keyword. +# +# true +# ^^^^ +class Prism::TrueNode < Prism::Node + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer).void } + def initialize(source, node_id, location, flags); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer).returns(Prism::TrueNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `undef` keyword. +# +# undef :foo, :bar, :baz +# ^^^^^^^^^^^^^^^^^^^^^^ +class Prism::UndefNode < Prism::Node + sig { returns(T::Array[T.any(Prism::SymbolNode, Prism::InterpolatedSymbolNode)]) } + def names; end + + sig { returns(Prism::Location) } + def keyword_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, names: T::Array[T.any(Prism::SymbolNode, Prism::InterpolatedSymbolNode)], keyword_loc: Prism::Location).void } + def initialize(source, node_id, location, flags, names, keyword_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, names: T::Array[T.any(Prism::SymbolNode, Prism::InterpolatedSymbolNode)], keyword_loc: Prism::Location).returns(Prism::UndefNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, names: self.names, keyword_loc: self.keyword_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def keyword; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `unless` keyword, either in the block form or the modifier form. +# +# bar unless foo +# ^^^^^^^^^^^^^^ +# +# unless foo then bar end +# ^^^^^^^^^^^^^^^^^^^^^^^ +class Prism::UnlessNode < Prism::Node + sig { returns(Prism::Location) } + def keyword_loc; end + + sig { returns(Prism::Node) } + def predicate; end + + sig { returns(T.nilable(Prism::Location)) } + def then_keyword_loc; end + + sig { returns(T.nilable(Prism::StatementsNode)) } + def statements; end + + sig { returns(T.nilable(Prism::ElseNode)) } + def else_clause; end + + sig { returns(T.nilable(Prism::Location)) } + def end_keyword_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, keyword_loc: Prism::Location, predicate: Prism::Node, then_keyword_loc: T.nilable(Prism::Location), statements: T.nilable(Prism::StatementsNode), else_clause: T.nilable(Prism::ElseNode), end_keyword_loc: T.nilable(Prism::Location)).void } + def initialize(source, node_id, location, flags, keyword_loc, predicate, then_keyword_loc, statements, else_clause, end_keyword_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, keyword_loc: Prism::Location, predicate: Prism::Node, then_keyword_loc: T.nilable(Prism::Location), statements: T.nilable(Prism::StatementsNode), else_clause: T.nilable(Prism::ElseNode), end_keyword_loc: T.nilable(Prism::Location)).returns(Prism::UnlessNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, keyword_loc: self.keyword_loc, predicate: self.predicate, then_keyword_loc: self.then_keyword_loc, statements: self.statements, else_clause: self.else_clause, end_keyword_loc: self.end_keyword_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def keyword; end + + sig { returns(T.nilable(String)) } + def then_keyword; end + + sig { returns(T.nilable(String)) } + def end_keyword; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `until` keyword, either in the block form or the modifier form. +# +# bar until foo +# ^^^^^^^^^^^^^ +# +# until foo do bar end +# ^^^^^^^^^^^^^^^^^^^^ +class Prism::UntilNode < Prism::Node + sig { returns(T::Boolean) } + def begin_modifier?; end + + sig { returns(Prism::Location) } + def keyword_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def do_keyword_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def closing_loc; end + + sig { returns(Prism::Node) } + def predicate; end + + sig { returns(T.nilable(Prism::StatementsNode)) } + def statements; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, keyword_loc: Prism::Location, do_keyword_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location), predicate: Prism::Node, statements: T.nilable(Prism::StatementsNode)).void } + def initialize(source, node_id, location, flags, keyword_loc, do_keyword_loc, closing_loc, predicate, statements); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, keyword_loc: Prism::Location, do_keyword_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location), predicate: Prism::Node, statements: T.nilable(Prism::StatementsNode)).returns(Prism::UntilNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, keyword_loc: self.keyword_loc, do_keyword_loc: self.do_keyword_loc, closing_loc: self.closing_loc, predicate: self.predicate, statements: self.statements); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def keyword; end + + sig { returns(T.nilable(String)) } + def do_keyword; end + + sig { returns(T.nilable(String)) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `when` keyword within a case statement. +# +# case true +# when true +# ^^^^^^^^^ +# end +class Prism::WhenNode < Prism::Node + sig { returns(Prism::Location) } + def keyword_loc; end + + sig { returns(T::Array[Prism::Node]) } + def conditions; end + + sig { returns(T.nilable(Prism::Location)) } + def then_keyword_loc; end + + sig { returns(T.nilable(Prism::StatementsNode)) } + def statements; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, keyword_loc: Prism::Location, conditions: T::Array[Prism::Node], then_keyword_loc: T.nilable(Prism::Location), statements: T.nilable(Prism::StatementsNode)).void } + def initialize(source, node_id, location, flags, keyword_loc, conditions, then_keyword_loc, statements); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, keyword_loc: Prism::Location, conditions: T::Array[Prism::Node], then_keyword_loc: T.nilable(Prism::Location), statements: T.nilable(Prism::StatementsNode)).returns(Prism::WhenNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, keyword_loc: self.keyword_loc, conditions: self.conditions, then_keyword_loc: self.then_keyword_loc, statements: self.statements); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def keyword; end + + sig { returns(T.nilable(String)) } + def then_keyword; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `while` keyword, either in the block form or the modifier form. +# +# bar while foo +# ^^^^^^^^^^^^^ +# +# while foo do bar end +# ^^^^^^^^^^^^^^^^^^^^ +class Prism::WhileNode < Prism::Node + sig { returns(T::Boolean) } + def begin_modifier?; end + + sig { returns(Prism::Location) } + def keyword_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def do_keyword_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def closing_loc; end + + sig { returns(Prism::Node) } + def predicate; end + + sig { returns(T.nilable(Prism::StatementsNode)) } + def statements; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, keyword_loc: Prism::Location, do_keyword_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location), predicate: Prism::Node, statements: T.nilable(Prism::StatementsNode)).void } + def initialize(source, node_id, location, flags, keyword_loc, do_keyword_loc, closing_loc, predicate, statements); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, keyword_loc: Prism::Location, do_keyword_loc: T.nilable(Prism::Location), closing_loc: T.nilable(Prism::Location), predicate: Prism::Node, statements: T.nilable(Prism::StatementsNode)).returns(Prism::WhileNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, keyword_loc: self.keyword_loc, do_keyword_loc: self.do_keyword_loc, closing_loc: self.closing_loc, predicate: self.predicate, statements: self.statements); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def keyword; end + + sig { returns(T.nilable(String)) } + def do_keyword; end + + sig { returns(T.nilable(String)) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents an xstring literal with no interpolation. +# +# `foo` +# ^^^^^ +class Prism::XStringNode < Prism::Node + sig { returns(T::Boolean) } + def forced_utf8_encoding?; end + + sig { returns(T::Boolean) } + def forced_binary_encoding?; end + + sig { returns(Prism::Location) } + def opening_loc; end + + sig { returns(Prism::Location) } + def content_loc; end + + sig { returns(Prism::Location) } + def closing_loc; end + + sig { returns(String) } + def unescaped; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: Prism::Location, content_loc: Prism::Location, closing_loc: Prism::Location, unescaped: String).void } + def initialize(source, node_id, location, flags, opening_loc, content_loc, closing_loc, unescaped); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, opening_loc: Prism::Location, content_loc: Prism::Location, closing_loc: Prism::Location, unescaped: String).returns(Prism::XStringNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, content_loc: self.content_loc, closing_loc: self.closing_loc, unescaped: self.unescaped); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def opening; end + + sig { returns(String) } + def content; end + + sig { returns(String) } + def closing; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Represents the use of the `yield` keyword. +# +# yield 1 +# ^^^^^^^ +class Prism::YieldNode < Prism::Node + sig { returns(Prism::Location) } + def keyword_loc; end + + sig { returns(T.nilable(Prism::Location)) } + def lparen_loc; end + + sig { returns(T.nilable(Prism::ArgumentsNode)) } + def arguments; end + + sig { returns(T.nilable(Prism::Location)) } + def rparen_loc; end + + sig { params(source: Prism::Source, node_id: Integer, location: Prism::Location, flags: Integer, keyword_loc: Prism::Location, lparen_loc: T.nilable(Prism::Location), arguments: T.nilable(Prism::ArgumentsNode), rparen_loc: T.nilable(Prism::Location)).void } + def initialize(source, node_id, location, flags, keyword_loc, lparen_loc, arguments, rparen_loc); end + + sig { override.params(visitor: Prism::Visitor).returns(T.untyped) } + def accept(visitor); end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def child_nodes; end + + sig { override.returns(T::Array[T.nilable(Prism::Node)]) } + def deconstruct; end + + sig { override.returns(T::Array[Prism::Node]) } + def compact_child_nodes; end + + sig { override.returns(T::Array[T.any(Prism::Node, Prism::Location)]) } + def comment_targets; end + + sig { params(node_id: Integer, location: Prism::Location, flags: Integer, keyword_loc: Prism::Location, lparen_loc: T.nilable(Prism::Location), arguments: T.nilable(Prism::ArgumentsNode), rparen_loc: T.nilable(Prism::Location)).returns(Prism::YieldNode) } + def copy(node_id: self.node_id, location: self.location, flags: self.flags, keyword_loc: self.keyword_loc, lparen_loc: self.lparen_loc, arguments: self.arguments, rparen_loc: self.rparen_loc); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def keyword; end + + sig { returns(T.nilable(String)) } + def lparen; end + + sig { returns(T.nilable(String)) } + def rparen; end + + sig { override.returns(T::Array[Prism::Reflection::Field]) } + def fields; end + + sig { override.returns(String) } + def inspect; end + + sig { override.returns(Symbol) } + def type; end +end + +# Flags for arguments nodes. +module Prism::ArgumentsNodeFlags + # if the arguments contain forwarding + CONTAINS_FORWARDING = T.let(1 << 2, Integer) + # if the arguments contain keywords + CONTAINS_KEYWORDS = T.let(1 << 3, Integer) + # if the arguments contain a keyword splat + CONTAINS_KEYWORD_SPLAT = T.let(1 << 4, Integer) + # if the arguments contain a splat + CONTAINS_SPLAT = T.let(1 << 5, Integer) + # if the arguments contain multiple splats + CONTAINS_MULTIPLE_SPLATS = T.let(1 << 6, Integer) +end + +# Flags for array nodes. +module Prism::ArrayNodeFlags + # if array contains splat nodes + CONTAINS_SPLAT = T.let(1 << 2, Integer) +end + +# Flags for call nodes. +module Prism::CallNodeFlags + # &. operator + SAFE_NAVIGATION = T.let(1 << 2, Integer) + # a call that could have been a local variable + VARIABLE_CALL = T.let(1 << 3, Integer) + # a call that is an attribute write, so the value being written should be returned + ATTRIBUTE_WRITE = T.let(1 << 4, Integer) + # a call that ignores method visibility + IGNORE_VISIBILITY = T.let(1 << 5, Integer) +end + +# Flags for nodes that have unescaped content. +module Prism::EncodingFlags + # internal bytes forced the encoding to UTF-8 + FORCED_UTF8_ENCODING = T.let(1 << 2, Integer) + # internal bytes forced the encoding to binary + FORCED_BINARY_ENCODING = T.let(1 << 3, Integer) +end + +# Flags for integer nodes that correspond to the base of the integer. +module Prism::IntegerBaseFlags + # 0b prefix + BINARY = T.let(1 << 2, Integer) + # 0d or no prefix + DECIMAL = T.let(1 << 3, Integer) + # 0o or 0 prefix + OCTAL = T.let(1 << 4, Integer) + # 0x prefix + HEXADECIMAL = T.let(1 << 5, Integer) +end + +# Flags for interpolated string nodes that indicated mutability if they are also marked as literals. +module Prism::InterpolatedStringNodeFlags + # frozen by virtue of a `frozen_string_literal: true` comment or `--enable-frozen-string-literal`; only for adjacent string literals like `'a' 'b'` + FROZEN = T.let(1 << 2, Integer) + # mutable by virtue of a `frozen_string_literal: false` comment or `--disable-frozen-string-literal`; only for adjacent string literals like `'a' 'b'` + MUTABLE = T.let(1 << 3, Integer) +end + +# Flags for keyword hash nodes. +module Prism::KeywordHashNodeFlags + # a keyword hash which only has `AssocNode` elements all with symbol keys, which means the elements can be treated as keyword arguments + SYMBOL_KEYS = T.let(1 << 2, Integer) +end + +# Flags for while and until loop nodes. +module Prism::LoopFlags + # a loop after a begin statement, so the body is executed first before the condition + BEGIN_MODIFIER = T.let(1 << 2, Integer) +end + +# Flags for parameter nodes. +module Prism::ParameterFlags + # a parameter name that has been repeated in the method signature + REPEATED_PARAMETER = T.let(1 << 2, Integer) +end + +# Flags for parentheses nodes. +module Prism::ParenthesesNodeFlags + # parentheses that contain multiple potentially void statements + MULTIPLE_STATEMENTS = T.let(1 << 2, Integer) +end + +# Flags for range and flip-flop nodes. +module Prism::RangeFlags + # ... operator + EXCLUDE_END = T.let(1 << 2, Integer) +end + +# Flags for regular expression and match last line nodes. +module Prism::RegularExpressionFlags + # i - ignores the case of characters when matching + IGNORE_CASE = T.let(1 << 2, Integer) + # x - ignores whitespace and allows comments in regular expressions + EXTENDED = T.let(1 << 3, Integer) + # m - allows $ to match the end of lines within strings + MULTI_LINE = T.let(1 << 4, Integer) + # o - only interpolates values into the regular expression once + ONCE = T.let(1 << 5, Integer) + # e - forces the EUC-JP encoding + EUC_JP = T.let(1 << 6, Integer) + # n - forces the ASCII-8BIT encoding + ASCII_8BIT = T.let(1 << 7, Integer) + # s - forces the Windows-31J encoding + WINDOWS_31J = T.let(1 << 8, Integer) + # u - forces the UTF-8 encoding + UTF_8 = T.let(1 << 9, Integer) + # internal bytes forced the encoding to UTF-8 + FORCED_UTF8_ENCODING = T.let(1 << 10, Integer) + # internal bytes forced the encoding to binary + FORCED_BINARY_ENCODING = T.let(1 << 11, Integer) + # internal bytes forced the encoding to US-ASCII + FORCED_US_ASCII_ENCODING = T.let(1 << 12, Integer) +end + +# Flags for shareable constant nodes. +module Prism::ShareableConstantNodeFlags + # constant writes that should be modified with shareable constant value literal + LITERAL = T.let(1 << 2, Integer) + # constant writes that should be modified with shareable constant value experimental everything + EXPERIMENTAL_EVERYTHING = T.let(1 << 3, Integer) + # constant writes that should be modified with shareable constant value experimental copy + EXPERIMENTAL_COPY = T.let(1 << 4, Integer) +end + +# Flags for string nodes. +module Prism::StringFlags + # internal bytes forced the encoding to UTF-8 + FORCED_UTF8_ENCODING = T.let(1 << 2, Integer) + # internal bytes forced the encoding to binary + FORCED_BINARY_ENCODING = T.let(1 << 3, Integer) + # frozen by virtue of a `frozen_string_literal: true` comment or `--enable-frozen-string-literal` + FROZEN = T.let(1 << 4, Integer) + # mutable by virtue of a `frozen_string_literal: false` comment or `--disable-frozen-string-literal` + MUTABLE = T.let(1 << 5, Integer) +end + +# Flags for symbol nodes. +module Prism::SymbolFlags + # internal bytes forced the encoding to UTF-8 + FORCED_UTF8_ENCODING = T.let(1 << 2, Integer) + # internal bytes forced the encoding to binary + FORCED_BINARY_ENCODING = T.let(1 << 3, Integer) + # internal bytes forced the encoding to US-ASCII + FORCED_US_ASCII_ENCODING = T.let(1 << 4, Integer) +end + +# The flags that are common to all nodes. +module Prism::NodeFlags + # A flag to indicate that the node is a candidate to emit a :line event + # through tracepoint when compiled. + NEWLINE = T.let(1, Integer) + + # A flag to indicate that the value that the node represents is a value that + # can be determined at parse-time. + STATIC_LITERAL = T.let(2, Integer) +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/node_ext.rbi b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/node_ext.rbi new file mode 100644 index 00000000..e5cf7376 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/node_ext.rbi @@ -0,0 +1,107 @@ +# typed: strict + +class Prism::InterpolatedMatchLastLineNode < Prism::Node + sig { returns(Integer) } + def options; end +end + +class Prism::InterpolatedRegularExpressionNode < Prism::Node + sig { returns(Integer) } + def options; end +end + +class Prism::MatchLastLineNode < Prism::Node + sig { returns(Integer) } + def options; end +end + +class Prism::RegularExpressionNode < Prism::Node + sig { returns(Integer) } + def options; end +end + +class Prism::InterpolatedStringNode < Prism::Node + sig { returns(T::Boolean) } + def heredoc?; end +end + +class Prism::InterpolatedXStringNode < Prism::Node + sig { returns(T::Boolean) } + def heredoc?; end +end + +class Prism::StringNode < Prism::Node + sig { returns(T::Boolean) } + def heredoc?; end + + sig { returns(Prism::InterpolatedStringNode) } + def to_interpolated; end +end + +class Prism::XStringNode < Prism::Node + sig { returns(T::Boolean) } + def heredoc?; end + + sig { returns(Prism::InterpolatedXStringNode) } + def to_interpolated; end +end + +class Prism::ImaginaryNode < Prism::Node + sig { returns(Complex) } + def value; end +end + +class Prism::RationalNode < Prism::Node + sig { returns(Rational) } + def value; end +end + +class Prism::ConstantReadNode < Prism::Node + sig { returns(T::Array[Symbol]) } + def full_name_parts; end + + sig { returns(String) } + def full_name; end +end + +class Prism::ConstantWriteNode < Prism::Node + sig { returns(T::Array[Symbol]) } + def full_name_parts; end + + sig { returns(String) } + def full_name; end +end + +class Prism::ConstantPathNode < Prism::Node + sig { returns(T::Array[Symbol]) } + def full_name_parts; end + + sig { returns(String) } + def full_name; end +end + +class Prism::ConstantPathTargetNode < Prism::Node + sig { returns(T::Array[Symbol]) } + def full_name_parts; end + + sig { returns(String) } + def full_name; end +end + +class Prism::ConstantTargetNode < Prism::Node + sig { returns(T::Array[Symbol]) } + def full_name_parts; end + + sig { returns(String) } + def full_name; end +end + +class Prism::ParametersNode < Prism::Node + sig { returns(T::Array[T.any([Symbol, Symbol], [Symbol])]) } + def signature; end +end + +class Prism::CallNode < Prism::Node + sig { returns(T.nilable(Prism::Location)) } + def full_message_loc; end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/parse_result.rbi b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/parse_result.rbi new file mode 100644 index 00000000..6f2bbb61 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/parse_result.rbi @@ -0,0 +1,404 @@ +# typed: strict + +class Prism::Source + sig { returns(String) } + def source; end + + sig { returns(Integer) } + def start_line; end + + sig { returns(T::Array[Integer]) } + def offsets; end + + sig { params(source: String, start_line: Integer, offsets: T::Array[Integer]).void } + def initialize(source, start_line = 1, offsets = []); end + + sig { params(start_line: Integer).void } + def replace_start_line(start_line); end + + sig { params(offsets: T::Array[Integer]).void } + def replace_offsets(offsets); end + + sig { returns(Encoding) } + def encoding; end + + sig { returns(T::Array[String]) } + def lines; end + + sig { params(byte_offset: Integer, length: Integer).returns(String) } + def slice(byte_offset, length); end + + sig { params(byte_offset: Integer).returns(Integer) } + def line(byte_offset); end + + sig { params(byte_offset: Integer).returns(Integer) } + def line_start(byte_offset); end + + sig { params(byte_offset: Integer).returns(Integer) } + def column(byte_offset); end + + sig { params(byte_offset: Integer).returns(Integer) } + def character_offset(byte_offset); end + + sig { params(byte_offset: Integer).returns(Integer) } + def character_column(byte_offset); end + + sig { params(byte_offset: Integer, encoding: Encoding).returns(Integer) } + def code_units_offset(byte_offset, encoding); end + + sig { params(encoding: Encoding).returns(T.any(Prism::CodeUnitsCache, T.proc.params(byte_offset: Integer).returns(Integer))) } + def code_units_cache(encoding); end + + sig { params(byte_offset: Integer, encoding: Encoding).returns(Integer) } + def code_units_column(byte_offset, encoding); end +end + +class Prism::CodeUnitsCache + sig { params(source: String, encoding: Encoding).void } + def initialize(source, encoding); end + + sig { params(byte_offset: Integer).returns(Integer) } + def [](byte_offset); end +end + +class Prism::ASCIISource < Prism::Source + sig { params(byte_offset: Integer).returns(Integer) } + def character_offset(byte_offset); end + + sig { params(byte_offset: Integer).returns(Integer) } + def character_column(byte_offset); end + + sig { params(byte_offset: Integer, encoding: Encoding).returns(Integer) } + def code_units_offset(byte_offset, encoding); end + + sig { params(encoding: Encoding).returns(T.any(Prism::CodeUnitsCache, T.proc.params(byte_offset: Integer).returns(Integer))) } + def code_units_cache(encoding); end + + sig { params(byte_offset: Integer, encoding: Encoding).returns(Integer) } + def code_units_column(byte_offset, encoding); end +end + +class Prism::Location + sig { returns(Prism::Source) } + def source; end + + sig { returns(Integer) } + def start_offset; end + + sig { returns(Integer) } + def length; end + + sig { params(source: Prism::Source, start_offset: Integer, length: Integer).void } + def initialize(source, start_offset, length); end + + sig { returns(T::Array[Prism::Comment]) } + def leading_comments; end + + sig { params(comment: Prism::Comment).void } + def leading_comment(comment); end + + sig { returns(T::Array[Prism::Comment]) } + def trailing_comments; end + + sig { params(comment: Prism::Comment).void } + def trailing_comment(comment); end + + sig { returns(T::Array[Prism::Comment]) } + def comments; end + + sig { params(source: Prism::Source, start_offset: Integer, length: Integer).returns(Prism::Location) } + def copy(source: self.source, start_offset: self.start_offset, length: self.length); end + + sig { returns(Prism::Location) } + def chop; end + + sig { returns(String) } + def inspect; end + + sig { returns(T::Array[String]) } + def source_lines; end + + sig { returns(String) } + def slice; end + + sig { returns(Integer) } + def start_character_offset; end + + sig { params(encoding: Encoding).returns(Integer) } + def start_code_units_offset(encoding = Encoding::UTF_16LE); end + + sig { params(cache: T.any(Prism::CodeUnitsCache, T.proc.params(byte_offset: Integer).returns(Integer))).returns(Integer) } + def cached_start_code_units_offset(cache); end + + sig { returns(Integer) } + def end_offset; end + + sig { returns(Integer) } + def end_character_offset; end + + sig { params(encoding: Encoding).returns(Integer) } + def end_code_units_offset(encoding = Encoding::UTF_16LE); end + + sig { params(cache: T.any(Prism::CodeUnitsCache, T.proc.params(byte_offset: Integer).returns(Integer))).returns(Integer) } + def cached_end_code_units_offset(cache); end + + sig { returns(Integer) } + def start_line; end + + sig { returns(String) } + def start_line_slice; end + + sig { returns(Integer) } + def end_line; end + + sig { returns(Integer) } + def start_column; end + + sig { returns(Integer) } + def start_character_column; end + + sig { params(encoding: Encoding).returns(Integer) } + def start_code_units_column(encoding = Encoding::UTF_16LE); end + + sig { params(cache: T.any(Prism::CodeUnitsCache, T.proc.params(byte_offset: Integer).returns(Integer))).returns(Integer) } + def cached_start_code_units_column(cache); end + + sig { returns(Integer) } + def end_column; end + + sig { returns(Integer) } + def end_character_column; end + + sig { params(encoding: Encoding).returns(Integer) } + def end_code_units_column(encoding = Encoding::UTF_16LE); end + + sig { params(cache: T.any(Prism::CodeUnitsCache, T.proc.params(byte_offset: Integer).returns(Integer))).returns(Integer) } + def cached_end_code_units_column(cache); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { params(q: T.untyped).void } + def pretty_print(q); end + + sig { params(other: T.untyped).returns(T::Boolean) } + def ==(other); end + + sig { params(other: Prism::Location).returns(Prism::Location) } + def join(other); end + + sig { params(string: String).returns(Prism::Location) } + def adjoin(string); end +end + +class Prism::Comment + abstract! + + sig { returns(Prism::Location) } + def location; end + + sig { params(location: Prism::Location).void } + def initialize(location); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def slice; end + + sig { abstract.returns(T::Boolean) } + def trailing?; end +end + +class Prism::InlineComment < Prism::Comment + sig { override.returns(T::Boolean) } + def trailing?; end + + sig { returns(String) } + def inspect; end +end + +class Prism::EmbDocComment < Prism::Comment + sig { override.returns(T::Boolean) } + def trailing?; end + + sig { returns(String) } + def inspect; end +end + +class Prism::MagicComment + sig { returns(Prism::Location) } + def key_loc; end + + sig { returns(Prism::Location) } + def value_loc; end + + sig { params(key_loc: Prism::Location, value_loc: Prism::Location).void } + def initialize(key_loc, value_loc); end + + sig { returns(String) } + def key; end + + sig { returns(String) } + def value; end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def inspect; end +end + +class Prism::ParseError + sig { returns(Symbol) } + def type; end + + sig { returns(String) } + def message; end + + sig { returns(Prism::Location) } + def location; end + + sig { returns(Symbol) } + def level; end + + sig { params(type: Symbol, message: String, location: Prism::Location, level: Symbol).void } + def initialize(type, message, location, level); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def inspect; end +end + +class Prism::ParseWarning + sig { returns(Symbol) } + def type; end + + sig { returns(String) } + def message; end + + sig { returns(Prism::Location) } + def location; end + + sig { returns(Symbol) } + def level; end + + sig { params(type: Symbol, message: String, location: Prism::Location, level: Symbol).void } + def initialize(type, message, location, level); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(String) } + def inspect; end +end + +class Prism::Result + sig { params(comments: T::Array[Prism::Comment], magic_comments: T::Array[Prism::MagicComment], data_loc: T.nilable(Prism::Location), errors: T::Array[Prism::ParseError], warnings: T::Array[Prism::ParseWarning], source: Prism::Source).void } + def initialize(comments, magic_comments, data_loc, errors, warnings, source); end + + sig { returns(T::Array[Prism::Comment]) } + def comments; end + + sig { returns(T::Array[Prism::MagicComment]) } + def magic_comments; end + + sig { returns(T.nilable(Prism::Location)) } + def data_loc; end + + sig { returns(T::Array[Prism::ParseError]) } + def errors; end + + sig { returns(T::Array[Prism::ParseWarning]) } + def warnings; end + + sig { returns(Prism::Source) } + def source; end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(Encoding) } + def encoding; end + + sig { returns(T::Boolean) } + def success?; end + + sig { returns(T::Boolean) } + def failure?; end + + sig { params(encoding: Encoding).returns(T.any(Prism::CodeUnitsCache, T.proc.params(byte_offset: Integer).returns(Integer))) } + def code_units_cache(encoding); end +end + +class Prism::ParseResult < Prism::Result + sig { params(value: Prism::ProgramNode, comments: T::Array[Prism::Comment], magic_comments: T::Array[Prism::MagicComment], data_loc: T.nilable(Prism::Location), errors: T::Array[Prism::ParseError], warnings: T::Array[Prism::ParseWarning], source: Prism::Source).void } + def initialize(value, comments, magic_comments, data_loc, errors, warnings, source); end + + sig { returns(Prism::ProgramNode) } + def value; end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end +end + +class Prism::LexResult < Prism::Result + sig { params(value: T::Array[T.untyped], comments: T::Array[Prism::Comment], magic_comments: T::Array[Prism::MagicComment], data_loc: T.nilable(Prism::Location), errors: T::Array[Prism::ParseError], warnings: T::Array[Prism::ParseWarning], source: Prism::Source).void } + def initialize(value, comments, magic_comments, data_loc, errors, warnings, source); end + + sig { returns(T::Array[T.untyped]) } + def value; end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end +end + +class Prism::ParseLexResult < Prism::Result + sig { params(value: [Prism::ProgramNode, T::Array[T.untyped]], comments: T::Array[Prism::Comment], magic_comments: T::Array[Prism::MagicComment], data_loc: T.nilable(Prism::Location), errors: T::Array[Prism::ParseError], warnings: T::Array[Prism::ParseWarning], source: Prism::Source).void } + def initialize(value, comments, magic_comments, data_loc, errors, warnings, source); end + + sig { returns([Prism::ProgramNode, T::Array[T.untyped]]) } + def value; end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end +end + +class Prism::Token + sig { returns(Prism::Source) } + def source; end + + sig { returns(Symbol) } + def type; end + + sig { returns(String) } + def value; end + + sig { params(source: Prism::Source, type: Symbol, value: String, location: T.any(Integer, Prism::Location)).void } + def initialize(source, type, value, location); end + + sig { params(keys: T.nilable(T::Array[Symbol])).returns(T::Hash[Symbol, T.untyped]) } + def deconstruct_keys(keys); end + + sig { returns(Prism::Location) } + def location; end + + sig { params(q: T.untyped).void } + def pretty_print(q); end + + sig { params(other: T.untyped).returns(T::Boolean) } + def ==(other); end +end + +class Prism::Scope + sig { returns(T::Array[Symbol]) } + def locals; end + + sig { returns(T::Array[Symbol]) } + def forwarding; end + + sig { params(locals: T::Array[Symbol], forwarding: T::Array[Symbol]).void } + def initialize(locals, forwarding); end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/reflection.rbi b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/reflection.rbi new file mode 100644 index 00000000..b21e9b5d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/reflection.rbi @@ -0,0 +1,58 @@ +# typed: strict + +module Prism::Reflection +end + +class Prism::Reflection::Field + sig { params(name: Symbol).void } + def initialize(name); end + + sig { returns(Symbol) } + def name; end +end + +class Prism::Reflection::NodeField < Prism::Reflection::Field +end + +class Prism::Reflection::OptionalNodeField < Prism::Reflection::Field +end + +class Prism::Reflection::NodeListField < Prism::Reflection::Field +end + +class Prism::Reflection::ConstantField < Prism::Reflection::Field +end + +class Prism::Reflection::OptionalConstantField < Prism::Reflection::Field +end + +class Prism::Reflection::ConstantListField < Prism::Reflection::Field +end + +class Prism::Reflection::StringField < Prism::Reflection::Field +end + +class Prism::Reflection::LocationField < Prism::Reflection::Field +end + +class Prism::Reflection::OptionalLocationField < Prism::Reflection::Field +end + +class Prism::Reflection::IntegerField < Prism::Reflection::Field +end + +class Prism::Reflection::FloatField < Prism::Reflection::Field +end + +class Prism::Reflection::FlagsField < Prism::Reflection::Field + sig { params(name: Symbol, flags: T::Array[Symbol]).void } + def initialize(name, flags); end + + sig { returns(T::Array[Symbol]) } + def flags; end +end + +module Prism::Reflection + sig { params(node: T.class_of(Prism::Node)).returns(T::Array[Prism::Reflection::Field]) } + def self.fields_for(node); end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/string_query.rbi b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/string_query.rbi new file mode 100644 index 00000000..3e5bae15 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/string_query.rbi @@ -0,0 +1,12 @@ +# typed: strict + +class Prism::StringQuery + sig { params(string: String).returns(T::Boolean) } + def self.local?(string); end + + sig { params(string: String).returns(T::Boolean) } + def self.constant?(string); end + + sig { params(string: String).returns(T::Boolean) } + def self.method_name?(string); end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/translation/parser.rbi b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/translation/parser.rbi new file mode 100644 index 00000000..bd60a5a6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/translation/parser.rbi @@ -0,0 +1,11 @@ +# typed: strict + +# We keep these shims in here because our client libraries might not have parser +# in their bundle. +module Parser; end +class Parser::Base; end + +class Prism::Translation::Parser < Parser::Base + sig { overridable.returns(Integer) } + def version; end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/translation/parser33.rbi b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/translation/parser33.rbi new file mode 100644 index 00000000..de3f7313 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/translation/parser33.rbi @@ -0,0 +1,6 @@ +# typed: strict + +class Prism::Translation::Parser33 < Prism::Translation::Parser + sig { override.returns(Integer) } + def version; end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/translation/parser34.rbi b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/translation/parser34.rbi new file mode 100644 index 00000000..34fee503 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/translation/parser34.rbi @@ -0,0 +1,6 @@ +# typed: strict + +class Prism::Translation::Parser34 < Prism::Translation::Parser + sig { override.returns(Integer) } + def version; end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/translation/parser35.rbi b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/translation/parser35.rbi new file mode 100644 index 00000000..0239fc82 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/translation/parser35.rbi @@ -0,0 +1,6 @@ +# typed: strict + +class Prism::Translation::Parser35 < Prism::Translation::Parser + sig { override.returns(Integer) } + def version; end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/translation/ripper.rbi b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/translation/ripper.rbi new file mode 100644 index 00000000..4d239705 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/translation/ripper.rbi @@ -0,0 +1,15 @@ +# typed: strict + +class Prism::Translation::Ripper < Prism::Compiler + sig { returns(T::Boolean) } + def error?; end + + sig { returns(T.untyped) } + def parse; end + + sig { params(source: String, filename: String, lineno: Integer, raise_errors: T.untyped).returns(T.untyped) } + def self.sexp_raw(source, filename = "-", lineno = 1, raise_errors: false); end + + sig { params(source: String, filename: String, lineno: Integer, raise_errors: T.untyped).returns(T.untyped) } + def self.sexp(source, filename = "-", lineno = 1, raise_errors: false); end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/visitor.rbi b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/visitor.rbi new file mode 100644 index 00000000..3f074e10 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/rbi/prism/visitor.rbi @@ -0,0 +1,473 @@ +# typed: strict + +=begin +This file is generated by the templates/template.rb script and should not be +modified manually. See templates/rbi/prism/visitor.rbi.erb +if you are looking to modify the template +=end + +class Prism::BasicVisitor + sig { params(node: T.nilable(Prism::Node)).void } + def visit(node); end + + sig { params(nodes: T::Array[T.nilable(Prism::Node)]).void } + def visit_all(nodes); end + + sig { params(node: Prism::Node).void } + def visit_child_nodes(node); end +end + +class Prism::Visitor < Prism::BasicVisitor + sig { params(node: Prism::AliasGlobalVariableNode).void } + def visit_alias_global_variable_node(node); end + + sig { params(node: Prism::AliasMethodNode).void } + def visit_alias_method_node(node); end + + sig { params(node: Prism::AlternationPatternNode).void } + def visit_alternation_pattern_node(node); end + + sig { params(node: Prism::AndNode).void } + def visit_and_node(node); end + + sig { params(node: Prism::ArgumentsNode).void } + def visit_arguments_node(node); end + + sig { params(node: Prism::ArrayNode).void } + def visit_array_node(node); end + + sig { params(node: Prism::ArrayPatternNode).void } + def visit_array_pattern_node(node); end + + sig { params(node: Prism::AssocNode).void } + def visit_assoc_node(node); end + + sig { params(node: Prism::AssocSplatNode).void } + def visit_assoc_splat_node(node); end + + sig { params(node: Prism::BackReferenceReadNode).void } + def visit_back_reference_read_node(node); end + + sig { params(node: Prism::BeginNode).void } + def visit_begin_node(node); end + + sig { params(node: Prism::BlockArgumentNode).void } + def visit_block_argument_node(node); end + + sig { params(node: Prism::BlockLocalVariableNode).void } + def visit_block_local_variable_node(node); end + + sig { params(node: Prism::BlockNode).void } + def visit_block_node(node); end + + sig { params(node: Prism::BlockParameterNode).void } + def visit_block_parameter_node(node); end + + sig { params(node: Prism::BlockParametersNode).void } + def visit_block_parameters_node(node); end + + sig { params(node: Prism::BreakNode).void } + def visit_break_node(node); end + + sig { params(node: Prism::CallAndWriteNode).void } + def visit_call_and_write_node(node); end + + sig { params(node: Prism::CallNode).void } + def visit_call_node(node); end + + sig { params(node: Prism::CallOperatorWriteNode).void } + def visit_call_operator_write_node(node); end + + sig { params(node: Prism::CallOrWriteNode).void } + def visit_call_or_write_node(node); end + + sig { params(node: Prism::CallTargetNode).void } + def visit_call_target_node(node); end + + sig { params(node: Prism::CapturePatternNode).void } + def visit_capture_pattern_node(node); end + + sig { params(node: Prism::CaseMatchNode).void } + def visit_case_match_node(node); end + + sig { params(node: Prism::CaseNode).void } + def visit_case_node(node); end + + sig { params(node: Prism::ClassNode).void } + def visit_class_node(node); end + + sig { params(node: Prism::ClassVariableAndWriteNode).void } + def visit_class_variable_and_write_node(node); end + + sig { params(node: Prism::ClassVariableOperatorWriteNode).void } + def visit_class_variable_operator_write_node(node); end + + sig { params(node: Prism::ClassVariableOrWriteNode).void } + def visit_class_variable_or_write_node(node); end + + sig { params(node: Prism::ClassVariableReadNode).void } + def visit_class_variable_read_node(node); end + + sig { params(node: Prism::ClassVariableTargetNode).void } + def visit_class_variable_target_node(node); end + + sig { params(node: Prism::ClassVariableWriteNode).void } + def visit_class_variable_write_node(node); end + + sig { params(node: Prism::ConstantAndWriteNode).void } + def visit_constant_and_write_node(node); end + + sig { params(node: Prism::ConstantOperatorWriteNode).void } + def visit_constant_operator_write_node(node); end + + sig { params(node: Prism::ConstantOrWriteNode).void } + def visit_constant_or_write_node(node); end + + sig { params(node: Prism::ConstantPathAndWriteNode).void } + def visit_constant_path_and_write_node(node); end + + sig { params(node: Prism::ConstantPathNode).void } + def visit_constant_path_node(node); end + + sig { params(node: Prism::ConstantPathOperatorWriteNode).void } + def visit_constant_path_operator_write_node(node); end + + sig { params(node: Prism::ConstantPathOrWriteNode).void } + def visit_constant_path_or_write_node(node); end + + sig { params(node: Prism::ConstantPathTargetNode).void } + def visit_constant_path_target_node(node); end + + sig { params(node: Prism::ConstantPathWriteNode).void } + def visit_constant_path_write_node(node); end + + sig { params(node: Prism::ConstantReadNode).void } + def visit_constant_read_node(node); end + + sig { params(node: Prism::ConstantTargetNode).void } + def visit_constant_target_node(node); end + + sig { params(node: Prism::ConstantWriteNode).void } + def visit_constant_write_node(node); end + + sig { params(node: Prism::DefNode).void } + def visit_def_node(node); end + + sig { params(node: Prism::DefinedNode).void } + def visit_defined_node(node); end + + sig { params(node: Prism::ElseNode).void } + def visit_else_node(node); end + + sig { params(node: Prism::EmbeddedStatementsNode).void } + def visit_embedded_statements_node(node); end + + sig { params(node: Prism::EmbeddedVariableNode).void } + def visit_embedded_variable_node(node); end + + sig { params(node: Prism::EnsureNode).void } + def visit_ensure_node(node); end + + sig { params(node: Prism::FalseNode).void } + def visit_false_node(node); end + + sig { params(node: Prism::FindPatternNode).void } + def visit_find_pattern_node(node); end + + sig { params(node: Prism::FlipFlopNode).void } + def visit_flip_flop_node(node); end + + sig { params(node: Prism::FloatNode).void } + def visit_float_node(node); end + + sig { params(node: Prism::ForNode).void } + def visit_for_node(node); end + + sig { params(node: Prism::ForwardingArgumentsNode).void } + def visit_forwarding_arguments_node(node); end + + sig { params(node: Prism::ForwardingParameterNode).void } + def visit_forwarding_parameter_node(node); end + + sig { params(node: Prism::ForwardingSuperNode).void } + def visit_forwarding_super_node(node); end + + sig { params(node: Prism::GlobalVariableAndWriteNode).void } + def visit_global_variable_and_write_node(node); end + + sig { params(node: Prism::GlobalVariableOperatorWriteNode).void } + def visit_global_variable_operator_write_node(node); end + + sig { params(node: Prism::GlobalVariableOrWriteNode).void } + def visit_global_variable_or_write_node(node); end + + sig { params(node: Prism::GlobalVariableReadNode).void } + def visit_global_variable_read_node(node); end + + sig { params(node: Prism::GlobalVariableTargetNode).void } + def visit_global_variable_target_node(node); end + + sig { params(node: Prism::GlobalVariableWriteNode).void } + def visit_global_variable_write_node(node); end + + sig { params(node: Prism::HashNode).void } + def visit_hash_node(node); end + + sig { params(node: Prism::HashPatternNode).void } + def visit_hash_pattern_node(node); end + + sig { params(node: Prism::IfNode).void } + def visit_if_node(node); end + + sig { params(node: Prism::ImaginaryNode).void } + def visit_imaginary_node(node); end + + sig { params(node: Prism::ImplicitNode).void } + def visit_implicit_node(node); end + + sig { params(node: Prism::ImplicitRestNode).void } + def visit_implicit_rest_node(node); end + + sig { params(node: Prism::InNode).void } + def visit_in_node(node); end + + sig { params(node: Prism::IndexAndWriteNode).void } + def visit_index_and_write_node(node); end + + sig { params(node: Prism::IndexOperatorWriteNode).void } + def visit_index_operator_write_node(node); end + + sig { params(node: Prism::IndexOrWriteNode).void } + def visit_index_or_write_node(node); end + + sig { params(node: Prism::IndexTargetNode).void } + def visit_index_target_node(node); end + + sig { params(node: Prism::InstanceVariableAndWriteNode).void } + def visit_instance_variable_and_write_node(node); end + + sig { params(node: Prism::InstanceVariableOperatorWriteNode).void } + def visit_instance_variable_operator_write_node(node); end + + sig { params(node: Prism::InstanceVariableOrWriteNode).void } + def visit_instance_variable_or_write_node(node); end + + sig { params(node: Prism::InstanceVariableReadNode).void } + def visit_instance_variable_read_node(node); end + + sig { params(node: Prism::InstanceVariableTargetNode).void } + def visit_instance_variable_target_node(node); end + + sig { params(node: Prism::InstanceVariableWriteNode).void } + def visit_instance_variable_write_node(node); end + + sig { params(node: Prism::IntegerNode).void } + def visit_integer_node(node); end + + sig { params(node: Prism::InterpolatedMatchLastLineNode).void } + def visit_interpolated_match_last_line_node(node); end + + sig { params(node: Prism::InterpolatedRegularExpressionNode).void } + def visit_interpolated_regular_expression_node(node); end + + sig { params(node: Prism::InterpolatedStringNode).void } + def visit_interpolated_string_node(node); end + + sig { params(node: Prism::InterpolatedSymbolNode).void } + def visit_interpolated_symbol_node(node); end + + sig { params(node: Prism::InterpolatedXStringNode).void } + def visit_interpolated_x_string_node(node); end + + sig { params(node: Prism::ItLocalVariableReadNode).void } + def visit_it_local_variable_read_node(node); end + + sig { params(node: Prism::ItParametersNode).void } + def visit_it_parameters_node(node); end + + sig { params(node: Prism::KeywordHashNode).void } + def visit_keyword_hash_node(node); end + + sig { params(node: Prism::KeywordRestParameterNode).void } + def visit_keyword_rest_parameter_node(node); end + + sig { params(node: Prism::LambdaNode).void } + def visit_lambda_node(node); end + + sig { params(node: Prism::LocalVariableAndWriteNode).void } + def visit_local_variable_and_write_node(node); end + + sig { params(node: Prism::LocalVariableOperatorWriteNode).void } + def visit_local_variable_operator_write_node(node); end + + sig { params(node: Prism::LocalVariableOrWriteNode).void } + def visit_local_variable_or_write_node(node); end + + sig { params(node: Prism::LocalVariableReadNode).void } + def visit_local_variable_read_node(node); end + + sig { params(node: Prism::LocalVariableTargetNode).void } + def visit_local_variable_target_node(node); end + + sig { params(node: Prism::LocalVariableWriteNode).void } + def visit_local_variable_write_node(node); end + + sig { params(node: Prism::MatchLastLineNode).void } + def visit_match_last_line_node(node); end + + sig { params(node: Prism::MatchPredicateNode).void } + def visit_match_predicate_node(node); end + + sig { params(node: Prism::MatchRequiredNode).void } + def visit_match_required_node(node); end + + sig { params(node: Prism::MatchWriteNode).void } + def visit_match_write_node(node); end + + sig { params(node: Prism::MissingNode).void } + def visit_missing_node(node); end + + sig { params(node: Prism::ModuleNode).void } + def visit_module_node(node); end + + sig { params(node: Prism::MultiTargetNode).void } + def visit_multi_target_node(node); end + + sig { params(node: Prism::MultiWriteNode).void } + def visit_multi_write_node(node); end + + sig { params(node: Prism::NextNode).void } + def visit_next_node(node); end + + sig { params(node: Prism::NilNode).void } + def visit_nil_node(node); end + + sig { params(node: Prism::NoKeywordsParameterNode).void } + def visit_no_keywords_parameter_node(node); end + + sig { params(node: Prism::NumberedParametersNode).void } + def visit_numbered_parameters_node(node); end + + sig { params(node: Prism::NumberedReferenceReadNode).void } + def visit_numbered_reference_read_node(node); end + + sig { params(node: Prism::OptionalKeywordParameterNode).void } + def visit_optional_keyword_parameter_node(node); end + + sig { params(node: Prism::OptionalParameterNode).void } + def visit_optional_parameter_node(node); end + + sig { params(node: Prism::OrNode).void } + def visit_or_node(node); end + + sig { params(node: Prism::ParametersNode).void } + def visit_parameters_node(node); end + + sig { params(node: Prism::ParenthesesNode).void } + def visit_parentheses_node(node); end + + sig { params(node: Prism::PinnedExpressionNode).void } + def visit_pinned_expression_node(node); end + + sig { params(node: Prism::PinnedVariableNode).void } + def visit_pinned_variable_node(node); end + + sig { params(node: Prism::PostExecutionNode).void } + def visit_post_execution_node(node); end + + sig { params(node: Prism::PreExecutionNode).void } + def visit_pre_execution_node(node); end + + sig { params(node: Prism::ProgramNode).void } + def visit_program_node(node); end + + sig { params(node: Prism::RangeNode).void } + def visit_range_node(node); end + + sig { params(node: Prism::RationalNode).void } + def visit_rational_node(node); end + + sig { params(node: Prism::RedoNode).void } + def visit_redo_node(node); end + + sig { params(node: Prism::RegularExpressionNode).void } + def visit_regular_expression_node(node); end + + sig { params(node: Prism::RequiredKeywordParameterNode).void } + def visit_required_keyword_parameter_node(node); end + + sig { params(node: Prism::RequiredParameterNode).void } + def visit_required_parameter_node(node); end + + sig { params(node: Prism::RescueModifierNode).void } + def visit_rescue_modifier_node(node); end + + sig { params(node: Prism::RescueNode).void } + def visit_rescue_node(node); end + + sig { params(node: Prism::RestParameterNode).void } + def visit_rest_parameter_node(node); end + + sig { params(node: Prism::RetryNode).void } + def visit_retry_node(node); end + + sig { params(node: Prism::ReturnNode).void } + def visit_return_node(node); end + + sig { params(node: Prism::SelfNode).void } + def visit_self_node(node); end + + sig { params(node: Prism::ShareableConstantNode).void } + def visit_shareable_constant_node(node); end + + sig { params(node: Prism::SingletonClassNode).void } + def visit_singleton_class_node(node); end + + sig { params(node: Prism::SourceEncodingNode).void } + def visit_source_encoding_node(node); end + + sig { params(node: Prism::SourceFileNode).void } + def visit_source_file_node(node); end + + sig { params(node: Prism::SourceLineNode).void } + def visit_source_line_node(node); end + + sig { params(node: Prism::SplatNode).void } + def visit_splat_node(node); end + + sig { params(node: Prism::StatementsNode).void } + def visit_statements_node(node); end + + sig { params(node: Prism::StringNode).void } + def visit_string_node(node); end + + sig { params(node: Prism::SuperNode).void } + def visit_super_node(node); end + + sig { params(node: Prism::SymbolNode).void } + def visit_symbol_node(node); end + + sig { params(node: Prism::TrueNode).void } + def visit_true_node(node); end + + sig { params(node: Prism::UndefNode).void } + def visit_undef_node(node); end + + sig { params(node: Prism::UnlessNode).void } + def visit_unless_node(node); end + + sig { params(node: Prism::UntilNode).void } + def visit_until_node(node); end + + sig { params(node: Prism::WhenNode).void } + def visit_when_node(node); end + + sig { params(node: Prism::WhileNode).void } + def visit_while_node(node); end + + sig { params(node: Prism::XStringNode).void } + def visit_x_string_node(node); end + + sig { params(node: Prism::YieldNode).void } + def visit_yield_node(node); end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism.rbs b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism.rbs new file mode 100644 index 00000000..c97253de --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism.rbs @@ -0,0 +1,254 @@ +# This file is generated by the templates/template.rb script and should not be +# modified manually. See templates/sig/prism.rbs.erb +# if you are looking to modify the template + +module Prism + BACKEND: :CEXT | :FFI + VERSION: String + + # Methods taking a Ruby source code string: + + def self.parse: ( + String source, + ?encoding: Encoding | false, + ?filepath: String, + ?freeze: bool, + ?frozen_string_literal: bool, + ?line: Integer, + ?main_script: bool, + ?offset: Integer, + ?scopes: Array[Array[Symbol]], + ?verbose: bool + ) -> ParseResult + + def self.profile: ( + String source, + ?encoding: Encoding | false, + ?filepath: String, + ?freeze: bool, + ?frozen_string_literal: bool, + ?line: Integer, + ?main_script: bool, + ?offset: Integer, + ?scopes: Array[Array[Symbol]], + ?verbose: bool + ) -> nil + + def self.lex: ( + String source, + ?encoding: Encoding | false, + ?filepath: String, + ?freeze: bool, + ?frozen_string_literal: bool, + ?line: Integer, + ?main_script: bool, + ?offset: Integer, + ?scopes: Array[Array[Symbol]], + ?verbose: bool + ) -> LexResult + + def self.lex_compat: ( + String source, + ?encoding: Encoding | false, + ?filepath: String, + ?freeze: bool, + ?frozen_string_literal: bool, + ?line: Integer, + ?main_script: bool, + ?offset: Integer, + ?scopes: Array[Array[Symbol]], + ?verbose: bool + ) -> LexCompat::Result + + def self.parse_lex: ( + String source, + ?encoding: Encoding | false, + ?filepath: String, + ?freeze: bool, + ?frozen_string_literal: bool, + ?line: Integer, + ?main_script: bool, + ?offset: Integer, + ?scopes: Array[Array[Symbol]], + ?verbose: bool + ) -> ParseLexResult + + def self.dump: ( + String source, + ?encoding: Encoding | false, + ?filepath: String, + ?freeze: bool, + ?frozen_string_literal: bool, + ?line: Integer, + ?main_script: bool, + ?offset: Integer, + ?scopes: Array[Array[Symbol]], + ?verbose: bool + ) -> String + + def self.parse_comments: ( + String source, + ?encoding: Encoding | false, + ?filepath: String, + ?freeze: bool, + ?frozen_string_literal: bool, + ?line: Integer, + ?main_script: bool, + ?offset: Integer, + ?scopes: Array[Array[Symbol]], + ?verbose: bool + ) -> Array[comment] + + def self.parse_success?: ( + String source, + ?encoding: Encoding | false, + ?filepath: String, + ?freeze: bool, + ?frozen_string_literal: bool, + ?line: Integer, + ?main_script: bool, + ?offset: Integer, + ?scopes: Array[Array[Symbol]], + ?verbose: bool + ) -> bool + + def self.parse_failure?: ( + String source, + ?encoding: Encoding | false, + ?filepath: String, + ?freeze: bool, + ?frozen_string_literal: bool, + ?line: Integer, + ?main_script: bool, + ?offset: Integer, + ?scopes: Array[Array[Symbol]], + ?verbose: bool + ) -> bool + + def self.load: ( + String source, + String serialized, + ?bool freeze + ) -> ParseResult + + def self.lex_ripper: ( + String source + ) -> Array[[[Integer, Integer], Symbol, String, untyped]] + + # Methods taking a path to a Ruby file: + + def self.parse_file: ( + String filepath, + ?encoding: Encoding | false, + ?freeze: bool, + ?frozen_string_literal: bool, + ?line: Integer, + ?main_script: bool, + ?offset: Integer, + ?scopes: Array[Array[Symbol]], + ?verbose: bool + ) -> ParseResult + + def self.profile_file: ( + String filepath, + ?encoding: Encoding | false, + ?freeze: bool, + ?frozen_string_literal: bool, + ?line: Integer, + ?main_script: bool, + ?offset: Integer, + ?scopes: Array[Array[Symbol]], + ?verbose: bool + ) -> nil + + def self.lex_file: ( + String filepath, + ?encoding: Encoding | false, + ?freeze: bool, + ?frozen_string_literal: bool, + ?line: Integer, + ?main_script: bool, + ?offset: Integer, + ?scopes: Array[Array[Symbol]], + ?verbose: bool + ) -> LexResult + + def self.parse_lex_file: ( + String filepath, + ?encoding: Encoding | false, + ?freeze: bool, + ?frozen_string_literal: bool, + ?line: Integer, + ?main_script: bool, + ?offset: Integer, + ?scopes: Array[Array[Symbol]], + ?verbose: bool + ) -> ParseLexResult + + def self.dump_file: ( + String filepath, + ?encoding: Encoding | false, + ?freeze: bool, + ?frozen_string_literal: bool, + ?line: Integer, + ?main_script: bool, + ?offset: Integer, + ?scopes: Array[Array[Symbol]], + ?verbose: bool + ) -> String + + def self.parse_file_comments: ( + String filepath, + ?encoding: Encoding | false, + ?freeze: bool, + ?frozen_string_literal: bool, + ?line: Integer, + ?main_script: bool, + ?offset: Integer, + ?scopes: Array[Array[Symbol]], + ?verbose: bool + ) -> Array[comment] + + def self.parse_file_success?: ( + String filepath, + ?encoding: Encoding | false, + ?freeze: bool, + ?frozen_string_literal: bool, + ?line: Integer, + ?main_script: bool, + ?offset: Integer, + ?scopes: Array[Array[Symbol]], + ?verbose: bool + ) -> bool + + def self.parse_file_failure?: ( + String filepath, + ?encoding: Encoding | false, + ?freeze: bool, + ?frozen_string_literal: bool, + ?line: Integer, + ?main_script: bool, + ?offset: Integer, + ?scopes: Array[Array[Symbol]], + ?verbose: bool + ) -> bool + + interface _Stream + def gets: (?Integer integer) -> (String | nil) + end + + def self.parse_stream: ( + _Stream stream, + ?encoding: Encoding | false, + ?filepath: String, + ?freeze: bool, + ?frozen_string_literal: bool, + ?line: Integer, + ?main_script: bool, + ?offset: Integer, + ?scopes: Array[Array[Symbol]], + ?verbose: bool + ) -> ParseResult + + def self.scope: (?locals: Array[Symbol], ?forwarding: Array[Symbol]) -> Scope +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/compiler.rbs b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/compiler.rbs new file mode 100644 index 00000000..1afa7db7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/compiler.rbs @@ -0,0 +1,9 @@ +module Prism + class Compiler + include _Visitor + + def visit: (Prism::node?) -> untyped + def visit_all: (Array[Prism::node?]) -> untyped + def visit_child_nodes: (Prism::node) -> void + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/dispatcher.rbs b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/dispatcher.rbs new file mode 100644 index 00000000..ad5f4eab --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/dispatcher.rbs @@ -0,0 +1,16 @@ +module Prism + class Dispatcher < Visitor + attr_reader listeners: Hash[Symbol, Array[untyped]] + + def initialize: () -> void + def register: (untyped, *Symbol) -> void + def dispatch: (Prism::node) -> void + def dispatch_once: (Prism::node) -> void + + class DispatchOnce < Visitor + attr_reader listeners: Hash[Symbol, Array[untyped]] + + def initialize: (Hash[Symbol, Array[untyped]]) -> void + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/dot_visitor.rbs b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/dot_visitor.rbs new file mode 100644 index 00000000..46b3dbf4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/dot_visitor.rbs @@ -0,0 +1,6 @@ +module Prism + class DotVisitor < Visitor + def initialize: () -> void + def to_dot: () -> String + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/dsl.rbs b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/dsl.rbs new file mode 100644 index 00000000..3e38e657 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/dsl.rbs @@ -0,0 +1,351 @@ +# This file is generated by the templates/template.rb script and should not be +# modified manually. See templates/sig/prism/dsl.rbs.erb +# if you are looking to modify the template + +module Prism + module DSL + def source: (String string) -> Source + + def location: (?source: Source, ?start_offset: Integer, ?length: Integer) -> Location + + def alias_global_variable_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?new_name: GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode, ?old_name: GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode | SymbolNode | MissingNode, ?keyword_loc: Location) -> AliasGlobalVariableNode + + def alias_method_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?new_name: SymbolNode | InterpolatedSymbolNode, ?old_name: SymbolNode | InterpolatedSymbolNode | GlobalVariableReadNode | MissingNode, ?keyword_loc: Location) -> AliasMethodNode + + def alternation_pattern_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?left: Prism::node, ?right: Prism::node, ?operator_loc: Location) -> AlternationPatternNode + + def and_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?left: Prism::node, ?right: Prism::node, ?operator_loc: Location) -> AndNode + + def arguments_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?arguments: Array[Prism::node]) -> ArgumentsNode + + def array_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?elements: Array[Prism::node], ?opening_loc: Location?, ?closing_loc: Location?) -> ArrayNode + + def array_pattern_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?constant: ConstantReadNode | ConstantPathNode | nil, ?requireds: Array[Prism::node], ?rest: Prism::node?, ?posts: Array[Prism::node], ?opening_loc: Location?, ?closing_loc: Location?) -> ArrayPatternNode + + def assoc_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?key: Prism::node, ?value: Prism::node, ?operator_loc: Location?) -> AssocNode + + def assoc_splat_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?value: Prism::node?, ?operator_loc: Location) -> AssocSplatNode + + def back_reference_read_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> BackReferenceReadNode + + def begin_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?begin_keyword_loc: Location?, ?statements: StatementsNode?, ?rescue_clause: RescueNode?, ?else_clause: ElseNode?, ?ensure_clause: EnsureNode?, ?end_keyword_loc: Location?) -> BeginNode + + def block_argument_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?expression: Prism::node?, ?operator_loc: Location) -> BlockArgumentNode + + def block_local_variable_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> BlockLocalVariableNode + + def block_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?locals: Array[Symbol], ?parameters: BlockParametersNode | NumberedParametersNode | ItParametersNode | nil, ?body: StatementsNode | BeginNode | nil, ?opening_loc: Location, ?closing_loc: Location) -> BlockNode + + def block_parameter_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol?, ?name_loc: Location?, ?operator_loc: Location) -> BlockParameterNode + + def block_parameters_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?parameters: ParametersNode?, ?locals: Array[BlockLocalVariableNode], ?opening_loc: Location?, ?closing_loc: Location?) -> BlockParametersNode + + def break_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?arguments: ArgumentsNode?, ?keyword_loc: Location) -> BreakNode + + def call_and_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?message_loc: Location?, ?read_name: Symbol, ?write_name: Symbol, ?operator_loc: Location, ?value: Prism::node) -> CallAndWriteNode + + def call_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?name: Symbol, ?message_loc: Location?, ?opening_loc: Location?, ?arguments: ArgumentsNode?, ?closing_loc: Location?, ?block: BlockNode | BlockArgumentNode | nil) -> CallNode + + def call_operator_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?message_loc: Location?, ?read_name: Symbol, ?write_name: Symbol, ?binary_operator: Symbol, ?binary_operator_loc: Location, ?value: Prism::node) -> CallOperatorWriteNode + + def call_or_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?message_loc: Location?, ?read_name: Symbol, ?write_name: Symbol, ?operator_loc: Location, ?value: Prism::node) -> CallOrWriteNode + + def call_target_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node, ?call_operator_loc: Location, ?name: Symbol, ?message_loc: Location) -> CallTargetNode + + def capture_pattern_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?value: Prism::node, ?target: LocalVariableTargetNode, ?operator_loc: Location) -> CapturePatternNode + + def case_match_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?predicate: Prism::node?, ?conditions: Array[InNode], ?else_clause: ElseNode?, ?case_keyword_loc: Location, ?end_keyword_loc: Location) -> CaseMatchNode + + def case_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?predicate: Prism::node?, ?conditions: Array[WhenNode], ?else_clause: ElseNode?, ?case_keyword_loc: Location, ?end_keyword_loc: Location) -> CaseNode + + def class_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?locals: Array[Symbol], ?class_keyword_loc: Location, ?constant_path: ConstantReadNode | ConstantPathNode | CallNode, ?inheritance_operator_loc: Location?, ?superclass: Prism::node?, ?body: StatementsNode | BeginNode | nil, ?end_keyword_loc: Location, ?name: Symbol) -> ClassNode + + def class_variable_and_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> ClassVariableAndWriteNode + + def class_variable_operator_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?binary_operator_loc: Location, ?value: Prism::node, ?binary_operator: Symbol) -> ClassVariableOperatorWriteNode + + def class_variable_or_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> ClassVariableOrWriteNode + + def class_variable_read_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> ClassVariableReadNode + + def class_variable_target_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> ClassVariableTargetNode + + def class_variable_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?value: Prism::node, ?operator_loc: Location) -> ClassVariableWriteNode + + def constant_and_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> ConstantAndWriteNode + + def constant_operator_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?binary_operator_loc: Location, ?value: Prism::node, ?binary_operator: Symbol) -> ConstantOperatorWriteNode + + def constant_or_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> ConstantOrWriteNode + + def constant_path_and_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?target: ConstantPathNode, ?operator_loc: Location, ?value: Prism::node) -> ConstantPathAndWriteNode + + def constant_path_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?parent: Prism::node?, ?name: Symbol?, ?delimiter_loc: Location, ?name_loc: Location) -> ConstantPathNode + + def constant_path_operator_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?target: ConstantPathNode, ?binary_operator_loc: Location, ?value: Prism::node, ?binary_operator: Symbol) -> ConstantPathOperatorWriteNode + + def constant_path_or_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?target: ConstantPathNode, ?operator_loc: Location, ?value: Prism::node) -> ConstantPathOrWriteNode + + def constant_path_target_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?parent: Prism::node?, ?name: Symbol?, ?delimiter_loc: Location, ?name_loc: Location) -> ConstantPathTargetNode + + def constant_path_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?target: ConstantPathNode, ?operator_loc: Location, ?value: Prism::node) -> ConstantPathWriteNode + + def constant_read_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> ConstantReadNode + + def constant_target_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> ConstantTargetNode + + def constant_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?value: Prism::node, ?operator_loc: Location) -> ConstantWriteNode + + def def_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?receiver: Prism::node?, ?parameters: ParametersNode?, ?body: StatementsNode | BeginNode | nil, ?locals: Array[Symbol], ?def_keyword_loc: Location, ?operator_loc: Location?, ?lparen_loc: Location?, ?rparen_loc: Location?, ?equal_loc: Location?, ?end_keyword_loc: Location?) -> DefNode + + def defined_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?lparen_loc: Location?, ?value: Prism::node, ?rparen_loc: Location?, ?keyword_loc: Location) -> DefinedNode + + def else_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?else_keyword_loc: Location, ?statements: StatementsNode?, ?end_keyword_loc: Location?) -> ElseNode + + def embedded_statements_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?statements: StatementsNode?, ?closing_loc: Location) -> EmbeddedStatementsNode + + def embedded_variable_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?operator_loc: Location, ?variable: InstanceVariableReadNode | ClassVariableReadNode | GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode) -> EmbeddedVariableNode + + def ensure_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?ensure_keyword_loc: Location, ?statements: StatementsNode?, ?end_keyword_loc: Location) -> EnsureNode + + def false_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer) -> FalseNode + + def find_pattern_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?constant: ConstantReadNode | ConstantPathNode | nil, ?left: SplatNode, ?requireds: Array[Prism::node], ?right: SplatNode | MissingNode, ?opening_loc: Location?, ?closing_loc: Location?) -> FindPatternNode + + def flip_flop_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?left: Prism::node?, ?right: Prism::node?, ?operator_loc: Location) -> FlipFlopNode + + def float_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?value: Float) -> FloatNode + + def for_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?index: LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode | MissingNode, ?collection: Prism::node, ?statements: StatementsNode?, ?for_keyword_loc: Location, ?in_keyword_loc: Location, ?do_keyword_loc: Location?, ?end_keyword_loc: Location) -> ForNode + + def forwarding_arguments_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer) -> ForwardingArgumentsNode + + def forwarding_parameter_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer) -> ForwardingParameterNode + + def forwarding_super_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?block: BlockNode?) -> ForwardingSuperNode + + def global_variable_and_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> GlobalVariableAndWriteNode + + def global_variable_operator_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?binary_operator_loc: Location, ?value: Prism::node, ?binary_operator: Symbol) -> GlobalVariableOperatorWriteNode + + def global_variable_or_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> GlobalVariableOrWriteNode + + def global_variable_read_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> GlobalVariableReadNode + + def global_variable_target_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> GlobalVariableTargetNode + + def global_variable_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?value: Prism::node, ?operator_loc: Location) -> GlobalVariableWriteNode + + def hash_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?elements: Array[AssocNode | AssocSplatNode], ?closing_loc: Location) -> HashNode + + def hash_pattern_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?constant: ConstantReadNode | ConstantPathNode | nil, ?elements: Array[AssocNode], ?rest: AssocSplatNode | NoKeywordsParameterNode | nil, ?opening_loc: Location?, ?closing_loc: Location?) -> HashPatternNode + + def if_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?if_keyword_loc: Location?, ?predicate: Prism::node, ?then_keyword_loc: Location?, ?statements: StatementsNode?, ?subsequent: ElseNode | IfNode | nil, ?end_keyword_loc: Location?) -> IfNode + + def imaginary_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?numeric: FloatNode | IntegerNode | RationalNode) -> ImaginaryNode + + def implicit_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?value: LocalVariableReadNode | CallNode | ConstantReadNode | LocalVariableTargetNode) -> ImplicitNode + + def implicit_rest_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer) -> ImplicitRestNode + + def in_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?pattern: Prism::node, ?statements: StatementsNode?, ?in_loc: Location, ?then_loc: Location?) -> InNode + + def index_and_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?opening_loc: Location, ?arguments: ArgumentsNode?, ?closing_loc: Location, ?block: BlockArgumentNode?, ?operator_loc: Location, ?value: Prism::node) -> IndexAndWriteNode + + def index_operator_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?opening_loc: Location, ?arguments: ArgumentsNode?, ?closing_loc: Location, ?block: BlockArgumentNode?, ?binary_operator: Symbol, ?binary_operator_loc: Location, ?value: Prism::node) -> IndexOperatorWriteNode + + def index_or_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?opening_loc: Location, ?arguments: ArgumentsNode?, ?closing_loc: Location, ?block: BlockArgumentNode?, ?operator_loc: Location, ?value: Prism::node) -> IndexOrWriteNode + + def index_target_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node, ?opening_loc: Location, ?arguments: ArgumentsNode?, ?closing_loc: Location, ?block: BlockArgumentNode?) -> IndexTargetNode + + def instance_variable_and_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> InstanceVariableAndWriteNode + + def instance_variable_operator_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?binary_operator_loc: Location, ?value: Prism::node, ?binary_operator: Symbol) -> InstanceVariableOperatorWriteNode + + def instance_variable_or_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> InstanceVariableOrWriteNode + + def instance_variable_read_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> InstanceVariableReadNode + + def instance_variable_target_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> InstanceVariableTargetNode + + def instance_variable_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?value: Prism::node, ?operator_loc: Location) -> InstanceVariableWriteNode + + def integer_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?value: Integer) -> IntegerNode + + def interpolated_match_last_line_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], ?closing_loc: Location) -> InterpolatedMatchLastLineNode + + def interpolated_regular_expression_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], ?closing_loc: Location) -> InterpolatedRegularExpressionNode + + def interpolated_string_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location?, ?parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode | InterpolatedStringNode | XStringNode], ?closing_loc: Location?) -> InterpolatedStringNode + + def interpolated_symbol_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location?, ?parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], ?closing_loc: Location?) -> InterpolatedSymbolNode + + def interpolated_x_string_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], ?closing_loc: Location) -> InterpolatedXStringNode + + def it_local_variable_read_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer) -> ItLocalVariableReadNode + + def it_parameters_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer) -> ItParametersNode + + def keyword_hash_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?elements: Array[AssocNode | AssocSplatNode]) -> KeywordHashNode + + def keyword_rest_parameter_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol?, ?name_loc: Location?, ?operator_loc: Location) -> KeywordRestParameterNode + + def lambda_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?locals: Array[Symbol], ?operator_loc: Location, ?opening_loc: Location, ?closing_loc: Location, ?parameters: BlockParametersNode | NumberedParametersNode | ItParametersNode | nil, ?body: StatementsNode | BeginNode | nil) -> LambdaNode + + def local_variable_and_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node, ?name: Symbol, ?depth: Integer) -> LocalVariableAndWriteNode + + def local_variable_operator_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name_loc: Location, ?binary_operator_loc: Location, ?value: Prism::node, ?name: Symbol, ?binary_operator: Symbol, ?depth: Integer) -> LocalVariableOperatorWriteNode + + def local_variable_or_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node, ?name: Symbol, ?depth: Integer) -> LocalVariableOrWriteNode + + def local_variable_read_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?depth: Integer) -> LocalVariableReadNode + + def local_variable_target_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?depth: Integer) -> LocalVariableTargetNode + + def local_variable_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?depth: Integer, ?name_loc: Location, ?value: Prism::node, ?operator_loc: Location) -> LocalVariableWriteNode + + def match_last_line_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?content_loc: Location, ?closing_loc: Location, ?unescaped: String) -> MatchLastLineNode + + def match_predicate_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?value: Prism::node, ?pattern: Prism::node, ?operator_loc: Location) -> MatchPredicateNode + + def match_required_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?value: Prism::node, ?pattern: Prism::node, ?operator_loc: Location) -> MatchRequiredNode + + def match_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?call: CallNode, ?targets: Array[LocalVariableTargetNode]) -> MatchWriteNode + + def missing_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer) -> MissingNode + + def module_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?locals: Array[Symbol], ?module_keyword_loc: Location, ?constant_path: ConstantReadNode | ConstantPathNode | MissingNode, ?body: StatementsNode | BeginNode | nil, ?end_keyword_loc: Location, ?name: Symbol) -> ModuleNode + + def multi_target_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?lefts: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | RequiredParameterNode | BackReferenceReadNode | NumberedReferenceReadNode], ?rest: ImplicitRestNode | SplatNode | nil, ?rights: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | RequiredParameterNode | BackReferenceReadNode | NumberedReferenceReadNode], ?lparen_loc: Location?, ?rparen_loc: Location?) -> MultiTargetNode + + def multi_write_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?lefts: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode], ?rest: ImplicitRestNode | SplatNode | nil, ?rights: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode], ?lparen_loc: Location?, ?rparen_loc: Location?, ?operator_loc: Location, ?value: Prism::node) -> MultiWriteNode + + def next_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?arguments: ArgumentsNode?, ?keyword_loc: Location) -> NextNode + + def nil_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer) -> NilNode + + def no_keywords_parameter_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?operator_loc: Location, ?keyword_loc: Location) -> NoKeywordsParameterNode + + def numbered_parameters_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?maximum: Integer) -> NumberedParametersNode + + def numbered_reference_read_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?number: Integer) -> NumberedReferenceReadNode + + def optional_keyword_parameter_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?value: Prism::node) -> OptionalKeywordParameterNode + + def optional_parameter_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> OptionalParameterNode + + def or_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?left: Prism::node, ?right: Prism::node, ?operator_loc: Location) -> OrNode + + def parameters_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?requireds: Array[RequiredParameterNode | MultiTargetNode], ?optionals: Array[OptionalParameterNode], ?rest: RestParameterNode | ImplicitRestNode | nil, ?posts: Array[RequiredParameterNode | MultiTargetNode | KeywordRestParameterNode | NoKeywordsParameterNode | ForwardingParameterNode], ?keywords: Array[RequiredKeywordParameterNode | OptionalKeywordParameterNode], ?keyword_rest: KeywordRestParameterNode | ForwardingParameterNode | NoKeywordsParameterNode | nil, ?block: BlockParameterNode?) -> ParametersNode + + def parentheses_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?body: Prism::node?, ?opening_loc: Location, ?closing_loc: Location) -> ParenthesesNode + + def pinned_expression_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?expression: Prism::node, ?operator_loc: Location, ?lparen_loc: Location, ?rparen_loc: Location) -> PinnedExpressionNode + + def pinned_variable_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?variable: LocalVariableReadNode | InstanceVariableReadNode | ClassVariableReadNode | GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode | ItLocalVariableReadNode | MissingNode, ?operator_loc: Location) -> PinnedVariableNode + + def post_execution_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?statements: StatementsNode?, ?keyword_loc: Location, ?opening_loc: Location, ?closing_loc: Location) -> PostExecutionNode + + def pre_execution_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?statements: StatementsNode?, ?keyword_loc: Location, ?opening_loc: Location, ?closing_loc: Location) -> PreExecutionNode + + def program_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?locals: Array[Symbol], ?statements: StatementsNode) -> ProgramNode + + def range_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?left: Prism::node?, ?right: Prism::node?, ?operator_loc: Location) -> RangeNode + + def rational_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?numerator: Integer, ?denominator: Integer) -> RationalNode + + def redo_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer) -> RedoNode + + def regular_expression_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?content_loc: Location, ?closing_loc: Location, ?unescaped: String) -> RegularExpressionNode + + def required_keyword_parameter_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location) -> RequiredKeywordParameterNode + + def required_parameter_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> RequiredParameterNode + + def rescue_modifier_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?expression: Prism::node, ?keyword_loc: Location, ?rescue_expression: Prism::node) -> RescueModifierNode + + def rescue_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?exceptions: Array[Prism::node], ?operator_loc: Location?, ?reference: LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | BackReferenceReadNode | NumberedReferenceReadNode | MissingNode | nil, ?then_keyword_loc: Location?, ?statements: StatementsNode?, ?subsequent: RescueNode?) -> RescueNode + + def rest_parameter_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol?, ?name_loc: Location?, ?operator_loc: Location) -> RestParameterNode + + def retry_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer) -> RetryNode + + def return_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?arguments: ArgumentsNode?) -> ReturnNode + + def self_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer) -> SelfNode + + def shareable_constant_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?write: ConstantWriteNode | ConstantAndWriteNode | ConstantOrWriteNode | ConstantOperatorWriteNode | ConstantPathWriteNode | ConstantPathAndWriteNode | ConstantPathOrWriteNode | ConstantPathOperatorWriteNode) -> ShareableConstantNode + + def singleton_class_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?locals: Array[Symbol], ?class_keyword_loc: Location, ?operator_loc: Location, ?expression: Prism::node, ?body: StatementsNode | BeginNode | nil, ?end_keyword_loc: Location) -> SingletonClassNode + + def source_encoding_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer) -> SourceEncodingNode + + def source_file_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?filepath: String) -> SourceFileNode + + def source_line_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer) -> SourceLineNode + + def splat_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?operator_loc: Location, ?expression: Prism::node?) -> SplatNode + + def statements_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?body: Array[Prism::node]) -> StatementsNode + + def string_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location?, ?content_loc: Location, ?closing_loc: Location?, ?unescaped: String) -> StringNode + + def super_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?lparen_loc: Location?, ?arguments: ArgumentsNode?, ?rparen_loc: Location?, ?block: BlockNode | BlockArgumentNode | nil) -> SuperNode + + def symbol_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location?, ?value_loc: Location?, ?closing_loc: Location?, ?unescaped: String) -> SymbolNode + + def true_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer) -> TrueNode + + def undef_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?names: Array[SymbolNode | InterpolatedSymbolNode], ?keyword_loc: Location) -> UndefNode + + def unless_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?predicate: Prism::node, ?then_keyword_loc: Location?, ?statements: StatementsNode?, ?else_clause: ElseNode?, ?end_keyword_loc: Location?) -> UnlessNode + + def until_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?do_keyword_loc: Location?, ?closing_loc: Location?, ?predicate: Prism::node, ?statements: StatementsNode?) -> UntilNode + + def when_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?conditions: Array[Prism::node], ?then_keyword_loc: Location?, ?statements: StatementsNode?) -> WhenNode + + def while_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?do_keyword_loc: Location?, ?closing_loc: Location?, ?predicate: Prism::node, ?statements: StatementsNode?) -> WhileNode + + def x_string_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?content_loc: Location, ?closing_loc: Location, ?unescaped: String) -> XStringNode + + def yield_node: (?source: Source, ?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?lparen_loc: Location?, ?arguments: ArgumentsNode?, ?rparen_loc: Location?) -> YieldNode + + def arguments_node_flag: (Symbol name) -> Integer + + def array_node_flag: (Symbol name) -> Integer + + def call_node_flag: (Symbol name) -> Integer + + def encoding_flag: (Symbol name) -> Integer + + def integer_base_flag: (Symbol name) -> Integer + + def interpolated_string_node_flag: (Symbol name) -> Integer + + def keyword_hash_node_flag: (Symbol name) -> Integer + + def loop_flag: (Symbol name) -> Integer + + def parameter_flag: (Symbol name) -> Integer + + def parentheses_node_flag: (Symbol name) -> Integer + + def range_flag: (Symbol name) -> Integer + + def regular_expression_flag: (Symbol name) -> Integer + + def shareable_constant_node_flag: (Symbol name) -> Integer + + def string_flag: (Symbol name) -> Integer + + def symbol_flag: (Symbol name) -> Integer + + private + + def default_source: () -> Source + + def default_location: () -> Location + + def default_node: (Source source, Location location) -> node + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/inspect_visitor.rbs b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/inspect_visitor.rbs new file mode 100644 index 00000000..70fa878a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/inspect_visitor.rbs @@ -0,0 +1,22 @@ +module Prism + class InspectVisitor < Visitor + class Replace + attr_reader value: String + + def initialize: (String value) -> void + end + + attr_reader indent: String + attr_reader commands: Array[[String | node | Replace, String]] + + def initialize: (?String indent) -> void + def compose: () -> String + + def self.compose: (node node) -> String + + private + + def inspect_node: (String name, node node) -> String + def inspect_location: (Location? location) -> String + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/lex_compat.rbs b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/lex_compat.rbs new file mode 100644 index 00000000..5dc1f876 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/lex_compat.rbs @@ -0,0 +1,10 @@ +module Prism + class LexCompat + class Result < Prism::Result + attr_reader value: Array[[[Integer, Integer], Symbol, String, untyped]] + + def initialize: (Array[[[Integer, Integer], Symbol, String, untyped]] value, Array[comment] comments, Array[MagicComment] magic_comments, Location? data_loc, Array[ParseError] errors, Array[ParseWarning] warnings, Source source) -> void + def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped] + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/mutation_compiler.rbs b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/mutation_compiler.rbs new file mode 100644 index 00000000..1bb83c3d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/mutation_compiler.rbs @@ -0,0 +1,159 @@ +# This file is generated by the templates/template.rb script and should not be +# modified manually. See templates/sig/prism/mutation_compiler.rbs.erb +# if you are looking to modify the template + +module Prism + class MutationCompiler < Compiler + def visit_alias_global_variable_node: (AliasGlobalVariableNode) -> node? + def visit_alias_method_node: (AliasMethodNode) -> node? + def visit_alternation_pattern_node: (AlternationPatternNode) -> node? + def visit_and_node: (AndNode) -> node? + def visit_arguments_node: (ArgumentsNode) -> node? + def visit_array_node: (ArrayNode) -> node? + def visit_array_pattern_node: (ArrayPatternNode) -> node? + def visit_assoc_node: (AssocNode) -> node? + def visit_assoc_splat_node: (AssocSplatNode) -> node? + def visit_back_reference_read_node: (BackReferenceReadNode) -> node? + def visit_begin_node: (BeginNode) -> node? + def visit_block_argument_node: (BlockArgumentNode) -> node? + def visit_block_local_variable_node: (BlockLocalVariableNode) -> node? + def visit_block_node: (BlockNode) -> node? + def visit_block_parameter_node: (BlockParameterNode) -> node? + def visit_block_parameters_node: (BlockParametersNode) -> node? + def visit_break_node: (BreakNode) -> node? + def visit_call_and_write_node: (CallAndWriteNode) -> node? + def visit_call_node: (CallNode) -> node? + def visit_call_operator_write_node: (CallOperatorWriteNode) -> node? + def visit_call_or_write_node: (CallOrWriteNode) -> node? + def visit_call_target_node: (CallTargetNode) -> node? + def visit_capture_pattern_node: (CapturePatternNode) -> node? + def visit_case_match_node: (CaseMatchNode) -> node? + def visit_case_node: (CaseNode) -> node? + def visit_class_node: (ClassNode) -> node? + def visit_class_variable_and_write_node: (ClassVariableAndWriteNode) -> node? + def visit_class_variable_operator_write_node: (ClassVariableOperatorWriteNode) -> node? + def visit_class_variable_or_write_node: (ClassVariableOrWriteNode) -> node? + def visit_class_variable_read_node: (ClassVariableReadNode) -> node? + def visit_class_variable_target_node: (ClassVariableTargetNode) -> node? + def visit_class_variable_write_node: (ClassVariableWriteNode) -> node? + def visit_constant_and_write_node: (ConstantAndWriteNode) -> node? + def visit_constant_operator_write_node: (ConstantOperatorWriteNode) -> node? + def visit_constant_or_write_node: (ConstantOrWriteNode) -> node? + def visit_constant_path_and_write_node: (ConstantPathAndWriteNode) -> node? + def visit_constant_path_node: (ConstantPathNode) -> node? + def visit_constant_path_operator_write_node: (ConstantPathOperatorWriteNode) -> node? + def visit_constant_path_or_write_node: (ConstantPathOrWriteNode) -> node? + def visit_constant_path_target_node: (ConstantPathTargetNode) -> node? + def visit_constant_path_write_node: (ConstantPathWriteNode) -> node? + def visit_constant_read_node: (ConstantReadNode) -> node? + def visit_constant_target_node: (ConstantTargetNode) -> node? + def visit_constant_write_node: (ConstantWriteNode) -> node? + def visit_def_node: (DefNode) -> node? + def visit_defined_node: (DefinedNode) -> node? + def visit_else_node: (ElseNode) -> node? + def visit_embedded_statements_node: (EmbeddedStatementsNode) -> node? + def visit_embedded_variable_node: (EmbeddedVariableNode) -> node? + def visit_ensure_node: (EnsureNode) -> node? + def visit_false_node: (FalseNode) -> node? + def visit_find_pattern_node: (FindPatternNode) -> node? + def visit_flip_flop_node: (FlipFlopNode) -> node? + def visit_float_node: (FloatNode) -> node? + def visit_for_node: (ForNode) -> node? + def visit_forwarding_arguments_node: (ForwardingArgumentsNode) -> node? + def visit_forwarding_parameter_node: (ForwardingParameterNode) -> node? + def visit_forwarding_super_node: (ForwardingSuperNode) -> node? + def visit_global_variable_and_write_node: (GlobalVariableAndWriteNode) -> node? + def visit_global_variable_operator_write_node: (GlobalVariableOperatorWriteNode) -> node? + def visit_global_variable_or_write_node: (GlobalVariableOrWriteNode) -> node? + def visit_global_variable_read_node: (GlobalVariableReadNode) -> node? + def visit_global_variable_target_node: (GlobalVariableTargetNode) -> node? + def visit_global_variable_write_node: (GlobalVariableWriteNode) -> node? + def visit_hash_node: (HashNode) -> node? + def visit_hash_pattern_node: (HashPatternNode) -> node? + def visit_if_node: (IfNode) -> node? + def visit_imaginary_node: (ImaginaryNode) -> node? + def visit_implicit_node: (ImplicitNode) -> node? + def visit_implicit_rest_node: (ImplicitRestNode) -> node? + def visit_in_node: (InNode) -> node? + def visit_index_and_write_node: (IndexAndWriteNode) -> node? + def visit_index_operator_write_node: (IndexOperatorWriteNode) -> node? + def visit_index_or_write_node: (IndexOrWriteNode) -> node? + def visit_index_target_node: (IndexTargetNode) -> node? + def visit_instance_variable_and_write_node: (InstanceVariableAndWriteNode) -> node? + def visit_instance_variable_operator_write_node: (InstanceVariableOperatorWriteNode) -> node? + def visit_instance_variable_or_write_node: (InstanceVariableOrWriteNode) -> node? + def visit_instance_variable_read_node: (InstanceVariableReadNode) -> node? + def visit_instance_variable_target_node: (InstanceVariableTargetNode) -> node? + def visit_instance_variable_write_node: (InstanceVariableWriteNode) -> node? + def visit_integer_node: (IntegerNode) -> node? + def visit_interpolated_match_last_line_node: (InterpolatedMatchLastLineNode) -> node? + def visit_interpolated_regular_expression_node: (InterpolatedRegularExpressionNode) -> node? + def visit_interpolated_string_node: (InterpolatedStringNode) -> node? + def visit_interpolated_symbol_node: (InterpolatedSymbolNode) -> node? + def visit_interpolated_x_string_node: (InterpolatedXStringNode) -> node? + def visit_it_local_variable_read_node: (ItLocalVariableReadNode) -> node? + def visit_it_parameters_node: (ItParametersNode) -> node? + def visit_keyword_hash_node: (KeywordHashNode) -> node? + def visit_keyword_rest_parameter_node: (KeywordRestParameterNode) -> node? + def visit_lambda_node: (LambdaNode) -> node? + def visit_local_variable_and_write_node: (LocalVariableAndWriteNode) -> node? + def visit_local_variable_operator_write_node: (LocalVariableOperatorWriteNode) -> node? + def visit_local_variable_or_write_node: (LocalVariableOrWriteNode) -> node? + def visit_local_variable_read_node: (LocalVariableReadNode) -> node? + def visit_local_variable_target_node: (LocalVariableTargetNode) -> node? + def visit_local_variable_write_node: (LocalVariableWriteNode) -> node? + def visit_match_last_line_node: (MatchLastLineNode) -> node? + def visit_match_predicate_node: (MatchPredicateNode) -> node? + def visit_match_required_node: (MatchRequiredNode) -> node? + def visit_match_write_node: (MatchWriteNode) -> node? + def visit_missing_node: (MissingNode) -> node? + def visit_module_node: (ModuleNode) -> node? + def visit_multi_target_node: (MultiTargetNode) -> node? + def visit_multi_write_node: (MultiWriteNode) -> node? + def visit_next_node: (NextNode) -> node? + def visit_nil_node: (NilNode) -> node? + def visit_no_keywords_parameter_node: (NoKeywordsParameterNode) -> node? + def visit_numbered_parameters_node: (NumberedParametersNode) -> node? + def visit_numbered_reference_read_node: (NumberedReferenceReadNode) -> node? + def visit_optional_keyword_parameter_node: (OptionalKeywordParameterNode) -> node? + def visit_optional_parameter_node: (OptionalParameterNode) -> node? + def visit_or_node: (OrNode) -> node? + def visit_parameters_node: (ParametersNode) -> node? + def visit_parentheses_node: (ParenthesesNode) -> node? + def visit_pinned_expression_node: (PinnedExpressionNode) -> node? + def visit_pinned_variable_node: (PinnedVariableNode) -> node? + def visit_post_execution_node: (PostExecutionNode) -> node? + def visit_pre_execution_node: (PreExecutionNode) -> node? + def visit_program_node: (ProgramNode) -> node? + def visit_range_node: (RangeNode) -> node? + def visit_rational_node: (RationalNode) -> node? + def visit_redo_node: (RedoNode) -> node? + def visit_regular_expression_node: (RegularExpressionNode) -> node? + def visit_required_keyword_parameter_node: (RequiredKeywordParameterNode) -> node? + def visit_required_parameter_node: (RequiredParameterNode) -> node? + def visit_rescue_modifier_node: (RescueModifierNode) -> node? + def visit_rescue_node: (RescueNode) -> node? + def visit_rest_parameter_node: (RestParameterNode) -> node? + def visit_retry_node: (RetryNode) -> node? + def visit_return_node: (ReturnNode) -> node? + def visit_self_node: (SelfNode) -> node? + def visit_shareable_constant_node: (ShareableConstantNode) -> node? + def visit_singleton_class_node: (SingletonClassNode) -> node? + def visit_source_encoding_node: (SourceEncodingNode) -> node? + def visit_source_file_node: (SourceFileNode) -> node? + def visit_source_line_node: (SourceLineNode) -> node? + def visit_splat_node: (SplatNode) -> node? + def visit_statements_node: (StatementsNode) -> node? + def visit_string_node: (StringNode) -> node? + def visit_super_node: (SuperNode) -> node? + def visit_symbol_node: (SymbolNode) -> node? + def visit_true_node: (TrueNode) -> node? + def visit_undef_node: (UndefNode) -> node? + def visit_unless_node: (UnlessNode) -> node? + def visit_until_node: (UntilNode) -> node? + def visit_when_node: (WhenNode) -> node? + def visit_while_node: (WhileNode) -> node? + def visit_x_string_node: (XStringNode) -> node? + def visit_yield_node: (YieldNode) -> node? + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/node.rbs b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/node.rbs new file mode 100644 index 00000000..b6658eef --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/node.rbs @@ -0,0 +1,3614 @@ +# This file is generated by the templates/template.rb script and should not be +# modified manually. See templates/sig/prism/node.rbs.erb +# if you are looking to modify the template + +module Prism + # Methods implemented on every subclass of a singleton of Node + interface _NodeSingleton + def type: () -> Symbol + end + + class Node + extend _NodeSingleton + + attr_reader source: Source + attr_reader node_id: Integer + attr_reader location: Location + attr_reader flags: Integer + + def newline?: () -> bool + def static_literal?: () -> bool + + def start_offset: () -> Integer + def end_offset: () -> Integer + def source_lines: () -> Array[String] + alias script_lines source_lines + def slice: () -> String + def slice_lines: () -> String + def pretty_print: (untyped q) -> untyped + def to_dot: () -> String + def tunnel: (Integer line, Integer column) -> Array[Prism::node] + def breadth_first_search: () { (Prism::node) -> bool } -> Prism::node? + def deprecated: (*String) -> void + def newline!: (Array[untyped]) -> void + end + + type node_singleton = singleton(Node) & _NodeSingleton + + # Methods implemented by every subclass of Node + interface _Node + def accept: (_Visitor) -> void + def child_nodes: () -> Array[Prism::node?] + def deconstruct: () -> Array[Prism::node?] + def compact_child_nodes: () -> Array[Prism::node] + def comment_targets: () -> Array[Prism::node | Location] + def fields: () -> Array[Prism::Reflection::Field] + def inspect: () -> String + def type: () -> Symbol + end + + type node = Node & _Node + + + # Represents the use of the `alias` keyword to alias a global variable. + # + # alias $foo $bar + # ^^^^^^^^^^^^^^^ + class AliasGlobalVariableNode < Node + include _Node + + attr_reader new_name: GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode + attr_reader old_name: GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode | SymbolNode | MissingNode + attr_reader keyword_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode new_name, GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode | SymbolNode | MissingNode old_name, Location keyword_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?new_name: GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode, ?old_name: GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode | SymbolNode | MissingNode, ?keyword_loc: Location) -> AliasGlobalVariableNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, new_name: GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode, old_name: GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode | SymbolNode | MissingNode, keyword_loc: Location } + def keyword: () -> String + def type: () -> :alias_global_variable_node + | ... + def self.type: () -> :alias_global_variable_node + end + + # Represents the use of the `alias` keyword to alias a method. + # + # alias foo bar + # ^^^^^^^^^^^^^ + class AliasMethodNode < Node + include _Node + + attr_reader new_name: SymbolNode | InterpolatedSymbolNode + attr_reader old_name: SymbolNode | InterpolatedSymbolNode | GlobalVariableReadNode | MissingNode + attr_reader keyword_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, SymbolNode | InterpolatedSymbolNode new_name, SymbolNode | InterpolatedSymbolNode | GlobalVariableReadNode | MissingNode old_name, Location keyword_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?new_name: SymbolNode | InterpolatedSymbolNode, ?old_name: SymbolNode | InterpolatedSymbolNode | GlobalVariableReadNode | MissingNode, ?keyword_loc: Location) -> AliasMethodNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, new_name: SymbolNode | InterpolatedSymbolNode, old_name: SymbolNode | InterpolatedSymbolNode | GlobalVariableReadNode | MissingNode, keyword_loc: Location } + def keyword: () -> String + def type: () -> :alias_method_node + | ... + def self.type: () -> :alias_method_node + end + + # Represents an alternation pattern in pattern matching. + # + # foo => bar | baz + # ^^^^^^^^^ + class AlternationPatternNode < Node + include _Node + + attr_reader left: Prism::node + attr_reader right: Prism::node + attr_reader operator_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node left, Prism::node right, Location operator_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?left: Prism::node, ?right: Prism::node, ?operator_loc: Location) -> AlternationPatternNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, left: Prism::node, right: Prism::node, operator_loc: Location } + def operator: () -> String + def type: () -> :alternation_pattern_node + | ... + def self.type: () -> :alternation_pattern_node + end + + # Represents the use of the `&&` operator or the `and` keyword. + # + # left and right + # ^^^^^^^^^^^^^^ + class AndNode < Node + include _Node + + attr_reader left: Prism::node + attr_reader right: Prism::node + attr_reader operator_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node left, Prism::node right, Location operator_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?left: Prism::node, ?right: Prism::node, ?operator_loc: Location) -> AndNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, left: Prism::node, right: Prism::node, operator_loc: Location } + def operator: () -> String + def type: () -> :and_node + | ... + def self.type: () -> :and_node + end + + # Represents a set of arguments to a method or a keyword. + # + # return foo, bar, baz + # ^^^^^^^^^^^^^ + class ArgumentsNode < Node + include _Node + + def contains_forwarding?: () -> bool + def contains_keywords?: () -> bool + def contains_keyword_splat?: () -> bool + def contains_splat?: () -> bool + def contains_multiple_splats?: () -> bool + + attr_reader arguments: Array[Prism::node] + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Array[Prism::node] arguments) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?arguments: Array[Prism::node]) -> ArgumentsNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, arguments: Array[Prism::node] } + def type: () -> :arguments_node + | ... + def self.type: () -> :arguments_node + end + + # Represents an array literal. This can be a regular array using brackets or a special array using % like %w or %i. + # + # [1, 2, 3] + # ^^^^^^^^^ + class ArrayNode < Node + include _Node + + def contains_splat?: () -> bool + + attr_reader elements: Array[Prism::node] + attr_reader opening_loc: Location? + attr_reader closing_loc: Location? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Array[Prism::node] elements, Location? opening_loc, Location? closing_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?elements: Array[Prism::node], ?opening_loc: Location?, ?closing_loc: Location?) -> ArrayNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, elements: Array[Prism::node], opening_loc: Location?, closing_loc: Location? } + def opening: () -> String? + def closing: () -> String? + def type: () -> :array_node + | ... + def self.type: () -> :array_node + end + + # Represents an array pattern in pattern matching. + # + # foo in 1, 2 + # ^^^^^^^^^^^ + # + # foo in [1, 2] + # ^^^^^^^^^^^^^ + # + # foo in *bar + # ^^^^^^^^^^^ + # + # foo in Bar[] + # ^^^^^^^^^^^^ + # + # foo in Bar[1, 2, 3] + # ^^^^^^^^^^^^^^^^^^^ + class ArrayPatternNode < Node + include _Node + + attr_reader constant: ConstantReadNode | ConstantPathNode | nil + attr_reader requireds: Array[Prism::node] + attr_reader rest: Prism::node? + attr_reader posts: Array[Prism::node] + attr_reader opening_loc: Location? + attr_reader closing_loc: Location? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, ConstantReadNode | ConstantPathNode | nil constant, Array[Prism::node] requireds, Prism::node? rest, Array[Prism::node] posts, Location? opening_loc, Location? closing_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?constant: ConstantReadNode | ConstantPathNode | nil, ?requireds: Array[Prism::node], ?rest: Prism::node?, ?posts: Array[Prism::node], ?opening_loc: Location?, ?closing_loc: Location?) -> ArrayPatternNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, constant: ConstantReadNode | ConstantPathNode | nil, requireds: Array[Prism::node], rest: Prism::node?, posts: Array[Prism::node], opening_loc: Location?, closing_loc: Location? } + def opening: () -> String? + def closing: () -> String? + def type: () -> :array_pattern_node + | ... + def self.type: () -> :array_pattern_node + end + + # Represents a hash key/value pair. + # + # { a => b } + # ^^^^^^ + class AssocNode < Node + include _Node + + attr_reader key: Prism::node + attr_reader value: Prism::node + attr_reader operator_loc: Location? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node key, Prism::node value, Location? operator_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?key: Prism::node, ?value: Prism::node, ?operator_loc: Location?) -> AssocNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, key: Prism::node, value: Prism::node, operator_loc: Location? } + def operator: () -> String? + def type: () -> :assoc_node + | ... + def self.type: () -> :assoc_node + end + + # Represents a splat in a hash literal. + # + # { **foo } + # ^^^^^ + class AssocSplatNode < Node + include _Node + + attr_reader value: Prism::node? + attr_reader operator_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node? value, Location operator_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?value: Prism::node?, ?operator_loc: Location) -> AssocSplatNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, value: Prism::node?, operator_loc: Location } + def operator: () -> String + def type: () -> :assoc_splat_node + | ... + def self.type: () -> :assoc_splat_node + end + + # Represents reading a reference to a field in the previous match. + # + # $' + # ^^ + class BackReferenceReadNode < Node + include _Node + + attr_reader name: Symbol + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> BackReferenceReadNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } + def type: () -> :back_reference_read_node + | ... + def self.type: () -> :back_reference_read_node + end + + # Represents a begin statement. + # + # begin + # foo + # end + # ^^^^^ + class BeginNode < Node + include _Node + + attr_reader begin_keyword_loc: Location? + attr_reader statements: StatementsNode? + attr_reader rescue_clause: RescueNode? + attr_reader else_clause: ElseNode? + attr_reader ensure_clause: EnsureNode? + attr_reader end_keyword_loc: Location? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location? begin_keyword_loc, StatementsNode? statements, RescueNode? rescue_clause, ElseNode? else_clause, EnsureNode? ensure_clause, Location? end_keyword_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?begin_keyword_loc: Location?, ?statements: StatementsNode?, ?rescue_clause: RescueNode?, ?else_clause: ElseNode?, ?ensure_clause: EnsureNode?, ?end_keyword_loc: Location?) -> BeginNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, begin_keyword_loc: Location?, statements: StatementsNode?, rescue_clause: RescueNode?, else_clause: ElseNode?, ensure_clause: EnsureNode?, end_keyword_loc: Location? } + def begin_keyword: () -> String? + def end_keyword: () -> String? + def type: () -> :begin_node + | ... + def self.type: () -> :begin_node + end + + # Represents a block argument using `&`. + # + # bar(&args) + # ^^^^^^^^^^ + class BlockArgumentNode < Node + include _Node + + attr_reader expression: Prism::node? + attr_reader operator_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node? expression, Location operator_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?expression: Prism::node?, ?operator_loc: Location) -> BlockArgumentNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, expression: Prism::node?, operator_loc: Location } + def operator: () -> String + def type: () -> :block_argument_node + | ... + def self.type: () -> :block_argument_node + end + + # Represents a block local variable. + # + # a { |; b| } + # ^ + class BlockLocalVariableNode < Node + include _Node + + def repeated_parameter?: () -> bool + + attr_reader name: Symbol + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> BlockLocalVariableNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } + def type: () -> :block_local_variable_node + | ... + def self.type: () -> :block_local_variable_node + end + + # Represents a block of ruby code. + # + # [1, 2, 3].each { |i| puts x } + # ^^^^^^^^^^^^^^ + class BlockNode < Node + include _Node + + attr_reader locals: Array[Symbol] + attr_reader parameters: BlockParametersNode | NumberedParametersNode | ItParametersNode | nil + attr_reader body: StatementsNode | BeginNode | nil + attr_reader opening_loc: Location + attr_reader closing_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Array[Symbol] locals, BlockParametersNode | NumberedParametersNode | ItParametersNode | nil parameters, StatementsNode | BeginNode | nil body, Location opening_loc, Location closing_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?locals: Array[Symbol], ?parameters: BlockParametersNode | NumberedParametersNode | ItParametersNode | nil, ?body: StatementsNode | BeginNode | nil, ?opening_loc: Location, ?closing_loc: Location) -> BlockNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, locals: Array[Symbol], parameters: BlockParametersNode | NumberedParametersNode | ItParametersNode | nil, body: StatementsNode | BeginNode | nil, opening_loc: Location, closing_loc: Location } + def opening: () -> String + def closing: () -> String + def type: () -> :block_node + | ... + def self.type: () -> :block_node + end + + # Represents a block parameter of a method, block, or lambda definition. + # + # def a(&b) + # ^^ + # end + class BlockParameterNode < Node + include _Node + + def repeated_parameter?: () -> bool + + attr_reader name: Symbol? + attr_reader name_loc: Location? + attr_reader operator_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol? name, Location? name_loc, Location operator_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol?, ?name_loc: Location?, ?operator_loc: Location) -> BlockParameterNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol?, name_loc: Location?, operator_loc: Location } + def operator: () -> String + def type: () -> :block_parameter_node + | ... + def self.type: () -> :block_parameter_node + end + + # Represents a block's parameters declaration. + # + # -> (a, b = 1; local) { } + # ^^^^^^^^^^^^^^^^^ + # + # foo do |a, b = 1; local| + # ^^^^^^^^^^^^^^^^^ + # end + class BlockParametersNode < Node + include _Node + + attr_reader parameters: ParametersNode? + attr_reader locals: Array[BlockLocalVariableNode] + attr_reader opening_loc: Location? + attr_reader closing_loc: Location? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, ParametersNode? parameters, Array[BlockLocalVariableNode] locals, Location? opening_loc, Location? closing_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?parameters: ParametersNode?, ?locals: Array[BlockLocalVariableNode], ?opening_loc: Location?, ?closing_loc: Location?) -> BlockParametersNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, parameters: ParametersNode?, locals: Array[BlockLocalVariableNode], opening_loc: Location?, closing_loc: Location? } + def opening: () -> String? + def closing: () -> String? + def type: () -> :block_parameters_node + | ... + def self.type: () -> :block_parameters_node + end + + # Represents the use of the `break` keyword. + # + # break foo + # ^^^^^^^^^ + class BreakNode < Node + include _Node + + attr_reader arguments: ArgumentsNode? + attr_reader keyword_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, ArgumentsNode? arguments, Location keyword_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?arguments: ArgumentsNode?, ?keyword_loc: Location) -> BreakNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, arguments: ArgumentsNode?, keyword_loc: Location } + def keyword: () -> String + def type: () -> :break_node + | ... + def self.type: () -> :break_node + end + + # Represents the use of the `&&=` operator on a call. + # + # foo.bar &&= value + # ^^^^^^^^^^^^^^^^^ + class CallAndWriteNode < Node + include _Node + + def safe_navigation?: () -> bool + def variable_call?: () -> bool + def attribute_write?: () -> bool + def ignore_visibility?: () -> bool + + attr_reader receiver: Prism::node? + attr_reader call_operator_loc: Location? + attr_reader message_loc: Location? + attr_reader read_name: Symbol + attr_reader write_name: Symbol + attr_reader operator_loc: Location + attr_reader value: Prism::node + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node? receiver, Location? call_operator_loc, Location? message_loc, Symbol read_name, Symbol write_name, Location operator_loc, Prism::node value) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?message_loc: Location?, ?read_name: Symbol, ?write_name: Symbol, ?operator_loc: Location, ?value: Prism::node) -> CallAndWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, message_loc: Location?, read_name: Symbol, write_name: Symbol, operator_loc: Location, value: Prism::node } + def call_operator: () -> String? + def message: () -> String? + def operator: () -> String + def type: () -> :call_and_write_node + | ... + def self.type: () -> :call_and_write_node + end + + # Represents a method call, in all of the various forms that can take. + # + # foo + # ^^^ + # + # foo() + # ^^^^^ + # + # +foo + # ^^^^ + # + # foo + bar + # ^^^^^^^^^ + # + # foo.bar + # ^^^^^^^ + # + # foo&.bar + # ^^^^^^^^ + class CallNode < Node + include _Node + + def safe_navigation?: () -> bool + def variable_call?: () -> bool + def attribute_write?: () -> bool + def ignore_visibility?: () -> bool + + attr_reader receiver: Prism::node? + attr_reader call_operator_loc: Location? + attr_reader name: Symbol + attr_reader message_loc: Location? + attr_reader opening_loc: Location? + attr_reader arguments: ArgumentsNode? + attr_reader closing_loc: Location? + attr_reader block: BlockNode | BlockArgumentNode | nil + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node? receiver, Location? call_operator_loc, Symbol name, Location? message_loc, Location? opening_loc, ArgumentsNode? arguments, Location? closing_loc, BlockNode | BlockArgumentNode | nil block) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?name: Symbol, ?message_loc: Location?, ?opening_loc: Location?, ?arguments: ArgumentsNode?, ?closing_loc: Location?, ?block: BlockNode | BlockArgumentNode | nil) -> CallNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, name: Symbol, message_loc: Location?, opening_loc: Location?, arguments: ArgumentsNode?, closing_loc: Location?, block: BlockNode | BlockArgumentNode | nil } + def call_operator: () -> String? + def message: () -> String? + def opening: () -> String? + def closing: () -> String? + def type: () -> :call_node + | ... + def self.type: () -> :call_node + end + + # Represents the use of an assignment operator on a call. + # + # foo.bar += baz + # ^^^^^^^^^^^^^^ + class CallOperatorWriteNode < Node + include _Node + + def safe_navigation?: () -> bool + def variable_call?: () -> bool + def attribute_write?: () -> bool + def ignore_visibility?: () -> bool + + attr_reader receiver: Prism::node? + attr_reader call_operator_loc: Location? + attr_reader message_loc: Location? + attr_reader read_name: Symbol + attr_reader write_name: Symbol + attr_reader binary_operator: Symbol + attr_reader binary_operator_loc: Location + attr_reader value: Prism::node + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node? receiver, Location? call_operator_loc, Location? message_loc, Symbol read_name, Symbol write_name, Symbol binary_operator, Location binary_operator_loc, Prism::node value) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?message_loc: Location?, ?read_name: Symbol, ?write_name: Symbol, ?binary_operator: Symbol, ?binary_operator_loc: Location, ?value: Prism::node) -> CallOperatorWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, message_loc: Location?, read_name: Symbol, write_name: Symbol, binary_operator: Symbol, binary_operator_loc: Location, value: Prism::node } + def call_operator: () -> String? + def message: () -> String? + def type: () -> :call_operator_write_node + | ... + def self.type: () -> :call_operator_write_node + end + + # Represents the use of the `||=` operator on a call. + # + # foo.bar ||= value + # ^^^^^^^^^^^^^^^^^ + class CallOrWriteNode < Node + include _Node + + def safe_navigation?: () -> bool + def variable_call?: () -> bool + def attribute_write?: () -> bool + def ignore_visibility?: () -> bool + + attr_reader receiver: Prism::node? + attr_reader call_operator_loc: Location? + attr_reader message_loc: Location? + attr_reader read_name: Symbol + attr_reader write_name: Symbol + attr_reader operator_loc: Location + attr_reader value: Prism::node + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node? receiver, Location? call_operator_loc, Location? message_loc, Symbol read_name, Symbol write_name, Location operator_loc, Prism::node value) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?message_loc: Location?, ?read_name: Symbol, ?write_name: Symbol, ?operator_loc: Location, ?value: Prism::node) -> CallOrWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, message_loc: Location?, read_name: Symbol, write_name: Symbol, operator_loc: Location, value: Prism::node } + def call_operator: () -> String? + def message: () -> String? + def operator: () -> String + def type: () -> :call_or_write_node + | ... + def self.type: () -> :call_or_write_node + end + + # Represents assigning to a method call. + # + # foo.bar, = 1 + # ^^^^^^^ + # + # begin + # rescue => foo.bar + # ^^^^^^^ + # end + # + # for foo.bar in baz do end + # ^^^^^^^ + class CallTargetNode < Node + include _Node + + def safe_navigation?: () -> bool + def variable_call?: () -> bool + def attribute_write?: () -> bool + def ignore_visibility?: () -> bool + + attr_reader receiver: Prism::node + attr_reader call_operator_loc: Location + attr_reader name: Symbol + attr_reader message_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node receiver, Location call_operator_loc, Symbol name, Location message_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node, ?call_operator_loc: Location, ?name: Symbol, ?message_loc: Location) -> CallTargetNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node, call_operator_loc: Location, name: Symbol, message_loc: Location } + def call_operator: () -> String + def message: () -> String + def type: () -> :call_target_node + | ... + def self.type: () -> :call_target_node + end + + # Represents assigning to a local variable in pattern matching. + # + # foo => [bar => baz] + # ^^^^^^^^^^^^ + class CapturePatternNode < Node + include _Node + + attr_reader value: Prism::node + attr_reader target: LocalVariableTargetNode + attr_reader operator_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node value, LocalVariableTargetNode target, Location operator_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?value: Prism::node, ?target: LocalVariableTargetNode, ?operator_loc: Location) -> CapturePatternNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, value: Prism::node, target: LocalVariableTargetNode, operator_loc: Location } + def operator: () -> String + def type: () -> :capture_pattern_node + | ... + def self.type: () -> :capture_pattern_node + end + + # Represents the use of a case statement for pattern matching. + # + # case true + # in false + # end + # ^^^^^^^^^ + class CaseMatchNode < Node + include _Node + + attr_reader predicate: Prism::node? + attr_reader conditions: Array[InNode] + attr_reader else_clause: ElseNode? + attr_reader case_keyword_loc: Location + attr_reader end_keyword_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node? predicate, Array[InNode] conditions, ElseNode? else_clause, Location case_keyword_loc, Location end_keyword_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?predicate: Prism::node?, ?conditions: Array[InNode], ?else_clause: ElseNode?, ?case_keyword_loc: Location, ?end_keyword_loc: Location) -> CaseMatchNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, predicate: Prism::node?, conditions: Array[InNode], else_clause: ElseNode?, case_keyword_loc: Location, end_keyword_loc: Location } + def case_keyword: () -> String + def end_keyword: () -> String + def type: () -> :case_match_node + | ... + def self.type: () -> :case_match_node + end + + # Represents the use of a case statement. + # + # case true + # when false + # end + # ^^^^^^^^^^ + class CaseNode < Node + include _Node + + attr_reader predicate: Prism::node? + attr_reader conditions: Array[WhenNode] + attr_reader else_clause: ElseNode? + attr_reader case_keyword_loc: Location + attr_reader end_keyword_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node? predicate, Array[WhenNode] conditions, ElseNode? else_clause, Location case_keyword_loc, Location end_keyword_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?predicate: Prism::node?, ?conditions: Array[WhenNode], ?else_clause: ElseNode?, ?case_keyword_loc: Location, ?end_keyword_loc: Location) -> CaseNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, predicate: Prism::node?, conditions: Array[WhenNode], else_clause: ElseNode?, case_keyword_loc: Location, end_keyword_loc: Location } + def case_keyword: () -> String + def end_keyword: () -> String + def type: () -> :case_node + | ... + def self.type: () -> :case_node + end + + # Represents a class declaration involving the `class` keyword. + # + # class Foo end + # ^^^^^^^^^^^^^ + class ClassNode < Node + include _Node + + attr_reader locals: Array[Symbol] + attr_reader class_keyword_loc: Location + attr_reader constant_path: ConstantReadNode | ConstantPathNode | CallNode + attr_reader inheritance_operator_loc: Location? + attr_reader superclass: Prism::node? + attr_reader body: StatementsNode | BeginNode | nil + attr_reader end_keyword_loc: Location + attr_reader name: Symbol + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Array[Symbol] locals, Location class_keyword_loc, ConstantReadNode | ConstantPathNode | CallNode constant_path, Location? inheritance_operator_loc, Prism::node? superclass, StatementsNode | BeginNode | nil body, Location end_keyword_loc, Symbol name) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?locals: Array[Symbol], ?class_keyword_loc: Location, ?constant_path: ConstantReadNode | ConstantPathNode | CallNode, ?inheritance_operator_loc: Location?, ?superclass: Prism::node?, ?body: StatementsNode | BeginNode | nil, ?end_keyword_loc: Location, ?name: Symbol) -> ClassNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, locals: Array[Symbol], class_keyword_loc: Location, constant_path: ConstantReadNode | ConstantPathNode | CallNode, inheritance_operator_loc: Location?, superclass: Prism::node?, body: StatementsNode | BeginNode | nil, end_keyword_loc: Location, name: Symbol } + def class_keyword: () -> String + def inheritance_operator: () -> String? + def end_keyword: () -> String + def type: () -> :class_node + | ... + def self.type: () -> :class_node + end + + # Represents the use of the `&&=` operator for assignment to a class variable. + # + # @@target &&= value + # ^^^^^^^^^^^^^^^^^^ + class ClassVariableAndWriteNode < Node + include _Node + + attr_reader name: Symbol + attr_reader name_loc: Location + attr_reader operator_loc: Location + attr_reader value: Prism::node + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name, Location name_loc, Location operator_loc, Prism::node value) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> ClassVariableAndWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } + def operator: () -> String + def type: () -> :class_variable_and_write_node + | ... + def self.type: () -> :class_variable_and_write_node + end + + # Represents assigning to a class variable using an operator that isn't `=`. + # + # @@target += value + # ^^^^^^^^^^^^^^^^^ + class ClassVariableOperatorWriteNode < Node + include _Node + + attr_reader name: Symbol + attr_reader name_loc: Location + attr_reader binary_operator_loc: Location + attr_reader value: Prism::node + attr_reader binary_operator: Symbol + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name, Location name_loc, Location binary_operator_loc, Prism::node value, Symbol binary_operator) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?binary_operator_loc: Location, ?value: Prism::node, ?binary_operator: Symbol) -> ClassVariableOperatorWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, binary_operator_loc: Location, value: Prism::node, binary_operator: Symbol } + def type: () -> :class_variable_operator_write_node + | ... + def self.type: () -> :class_variable_operator_write_node + end + + # Represents the use of the `||=` operator for assignment to a class variable. + # + # @@target ||= value + # ^^^^^^^^^^^^^^^^^^ + class ClassVariableOrWriteNode < Node + include _Node + + attr_reader name: Symbol + attr_reader name_loc: Location + attr_reader operator_loc: Location + attr_reader value: Prism::node + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name, Location name_loc, Location operator_loc, Prism::node value) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> ClassVariableOrWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } + def operator: () -> String + def type: () -> :class_variable_or_write_node + | ... + def self.type: () -> :class_variable_or_write_node + end + + # Represents referencing a class variable. + # + # @@foo + # ^^^^^ + class ClassVariableReadNode < Node + include _Node + + attr_reader name: Symbol + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> ClassVariableReadNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } + def type: () -> :class_variable_read_node + | ... + def self.type: () -> :class_variable_read_node + end + + # Represents writing to a class variable in a context that doesn't have an explicit value. + # + # @@foo, @@bar = baz + # ^^^^^ ^^^^^ + class ClassVariableTargetNode < Node + include _Node + + attr_reader name: Symbol + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> ClassVariableTargetNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } + def type: () -> :class_variable_target_node + | ... + def self.type: () -> :class_variable_target_node + end + + # Represents writing to a class variable. + # + # @@foo = 1 + # ^^^^^^^^^ + class ClassVariableWriteNode < Node + include _Node + + attr_reader name: Symbol + attr_reader name_loc: Location + attr_reader value: Prism::node + attr_reader operator_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name, Location name_loc, Prism::node value, Location operator_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?value: Prism::node, ?operator_loc: Location) -> ClassVariableWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, value: Prism::node, operator_loc: Location } + def operator: () -> String + def type: () -> :class_variable_write_node + | ... + def self.type: () -> :class_variable_write_node + end + + # Represents the use of the `&&=` operator for assignment to a constant. + # + # Target &&= value + # ^^^^^^^^^^^^^^^^ + class ConstantAndWriteNode < Node + include _Node + + attr_reader name: Symbol + attr_reader name_loc: Location + attr_reader operator_loc: Location + attr_reader value: Prism::node + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name, Location name_loc, Location operator_loc, Prism::node value) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> ConstantAndWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } + def operator: () -> String + def type: () -> :constant_and_write_node + | ... + def self.type: () -> :constant_and_write_node + end + + # Represents assigning to a constant using an operator that isn't `=`. + # + # Target += value + # ^^^^^^^^^^^^^^^ + class ConstantOperatorWriteNode < Node + include _Node + + attr_reader name: Symbol + attr_reader name_loc: Location + attr_reader binary_operator_loc: Location + attr_reader value: Prism::node + attr_reader binary_operator: Symbol + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name, Location name_loc, Location binary_operator_loc, Prism::node value, Symbol binary_operator) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?binary_operator_loc: Location, ?value: Prism::node, ?binary_operator: Symbol) -> ConstantOperatorWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, binary_operator_loc: Location, value: Prism::node, binary_operator: Symbol } + def type: () -> :constant_operator_write_node + | ... + def self.type: () -> :constant_operator_write_node + end + + # Represents the use of the `||=` operator for assignment to a constant. + # + # Target ||= value + # ^^^^^^^^^^^^^^^^ + class ConstantOrWriteNode < Node + include _Node + + attr_reader name: Symbol + attr_reader name_loc: Location + attr_reader operator_loc: Location + attr_reader value: Prism::node + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name, Location name_loc, Location operator_loc, Prism::node value) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> ConstantOrWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } + def operator: () -> String + def type: () -> :constant_or_write_node + | ... + def self.type: () -> :constant_or_write_node + end + + # Represents the use of the `&&=` operator for assignment to a constant path. + # + # Parent::Child &&= value + # ^^^^^^^^^^^^^^^^^^^^^^^ + class ConstantPathAndWriteNode < Node + include _Node + + attr_reader target: ConstantPathNode + attr_reader operator_loc: Location + attr_reader value: Prism::node + + def initialize: (Source source, Integer node_id, Location location, Integer flags, ConstantPathNode target, Location operator_loc, Prism::node value) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?target: ConstantPathNode, ?operator_loc: Location, ?value: Prism::node) -> ConstantPathAndWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, target: ConstantPathNode, operator_loc: Location, value: Prism::node } + def operator: () -> String + def type: () -> :constant_path_and_write_node + | ... + def self.type: () -> :constant_path_and_write_node + end + + # Represents accessing a constant through a path of `::` operators. + # + # Foo::Bar + # ^^^^^^^^ + class ConstantPathNode < Node + include _Node + + attr_reader parent: Prism::node? + attr_reader name: Symbol? + attr_reader delimiter_loc: Location + attr_reader name_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node? parent, Symbol? name, Location delimiter_loc, Location name_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?parent: Prism::node?, ?name: Symbol?, ?delimiter_loc: Location, ?name_loc: Location) -> ConstantPathNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, parent: Prism::node?, name: Symbol?, delimiter_loc: Location, name_loc: Location } + def delimiter: () -> String + def type: () -> :constant_path_node + | ... + def self.type: () -> :constant_path_node + end + + # Represents assigning to a constant path using an operator that isn't `=`. + # + # Parent::Child += value + # ^^^^^^^^^^^^^^^^^^^^^^ + class ConstantPathOperatorWriteNode < Node + include _Node + + attr_reader target: ConstantPathNode + attr_reader binary_operator_loc: Location + attr_reader value: Prism::node + attr_reader binary_operator: Symbol + + def initialize: (Source source, Integer node_id, Location location, Integer flags, ConstantPathNode target, Location binary_operator_loc, Prism::node value, Symbol binary_operator) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?target: ConstantPathNode, ?binary_operator_loc: Location, ?value: Prism::node, ?binary_operator: Symbol) -> ConstantPathOperatorWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, target: ConstantPathNode, binary_operator_loc: Location, value: Prism::node, binary_operator: Symbol } + def type: () -> :constant_path_operator_write_node + | ... + def self.type: () -> :constant_path_operator_write_node + end + + # Represents the use of the `||=` operator for assignment to a constant path. + # + # Parent::Child ||= value + # ^^^^^^^^^^^^^^^^^^^^^^^ + class ConstantPathOrWriteNode < Node + include _Node + + attr_reader target: ConstantPathNode + attr_reader operator_loc: Location + attr_reader value: Prism::node + + def initialize: (Source source, Integer node_id, Location location, Integer flags, ConstantPathNode target, Location operator_loc, Prism::node value) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?target: ConstantPathNode, ?operator_loc: Location, ?value: Prism::node) -> ConstantPathOrWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, target: ConstantPathNode, operator_loc: Location, value: Prism::node } + def operator: () -> String + def type: () -> :constant_path_or_write_node + | ... + def self.type: () -> :constant_path_or_write_node + end + + # Represents writing to a constant path in a context that doesn't have an explicit value. + # + # Foo::Foo, Bar::Bar = baz + # ^^^^^^^^ ^^^^^^^^ + class ConstantPathTargetNode < Node + include _Node + + attr_reader parent: Prism::node? + attr_reader name: Symbol? + attr_reader delimiter_loc: Location + attr_reader name_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node? parent, Symbol? name, Location delimiter_loc, Location name_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?parent: Prism::node?, ?name: Symbol?, ?delimiter_loc: Location, ?name_loc: Location) -> ConstantPathTargetNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, parent: Prism::node?, name: Symbol?, delimiter_loc: Location, name_loc: Location } + def delimiter: () -> String + def type: () -> :constant_path_target_node + | ... + def self.type: () -> :constant_path_target_node + end + + # Represents writing to a constant path. + # + # ::Foo = 1 + # ^^^^^^^^^ + # + # Foo::Bar = 1 + # ^^^^^^^^^^^^ + # + # ::Foo::Bar = 1 + # ^^^^^^^^^^^^^^ + class ConstantPathWriteNode < Node + include _Node + + attr_reader target: ConstantPathNode + attr_reader operator_loc: Location + attr_reader value: Prism::node + + def initialize: (Source source, Integer node_id, Location location, Integer flags, ConstantPathNode target, Location operator_loc, Prism::node value) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?target: ConstantPathNode, ?operator_loc: Location, ?value: Prism::node) -> ConstantPathWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, target: ConstantPathNode, operator_loc: Location, value: Prism::node } + def operator: () -> String + def type: () -> :constant_path_write_node + | ... + def self.type: () -> :constant_path_write_node + end + + # Represents referencing a constant. + # + # Foo + # ^^^ + class ConstantReadNode < Node + include _Node + + attr_reader name: Symbol + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> ConstantReadNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } + def type: () -> :constant_read_node + | ... + def self.type: () -> :constant_read_node + end + + # Represents writing to a constant in a context that doesn't have an explicit value. + # + # Foo, Bar = baz + # ^^^ ^^^ + class ConstantTargetNode < Node + include _Node + + attr_reader name: Symbol + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> ConstantTargetNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } + def type: () -> :constant_target_node + | ... + def self.type: () -> :constant_target_node + end + + # Represents writing to a constant. + # + # Foo = 1 + # ^^^^^^^ + class ConstantWriteNode < Node + include _Node + + attr_reader name: Symbol + attr_reader name_loc: Location + attr_reader value: Prism::node + attr_reader operator_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name, Location name_loc, Prism::node value, Location operator_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?value: Prism::node, ?operator_loc: Location) -> ConstantWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, value: Prism::node, operator_loc: Location } + def operator: () -> String + def type: () -> :constant_write_node + | ... + def self.type: () -> :constant_write_node + end + + # Represents a method definition. + # + # def method + # end + # ^^^^^^^^^^ + class DefNode < Node + include _Node + + attr_reader name: Symbol + attr_reader name_loc: Location + attr_reader receiver: Prism::node? + attr_reader parameters: ParametersNode? + attr_reader body: StatementsNode | BeginNode | nil + attr_reader locals: Array[Symbol] + attr_reader def_keyword_loc: Location + attr_reader operator_loc: Location? + attr_reader lparen_loc: Location? + attr_reader rparen_loc: Location? + attr_reader equal_loc: Location? + attr_reader end_keyword_loc: Location? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name, Location name_loc, Prism::node? receiver, ParametersNode? parameters, StatementsNode | BeginNode | nil body, Array[Symbol] locals, Location def_keyword_loc, Location? operator_loc, Location? lparen_loc, Location? rparen_loc, Location? equal_loc, Location? end_keyword_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?receiver: Prism::node?, ?parameters: ParametersNode?, ?body: StatementsNode | BeginNode | nil, ?locals: Array[Symbol], ?def_keyword_loc: Location, ?operator_loc: Location?, ?lparen_loc: Location?, ?rparen_loc: Location?, ?equal_loc: Location?, ?end_keyword_loc: Location?) -> DefNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, receiver: Prism::node?, parameters: ParametersNode?, body: StatementsNode | BeginNode | nil, locals: Array[Symbol], def_keyword_loc: Location, operator_loc: Location?, lparen_loc: Location?, rparen_loc: Location?, equal_loc: Location?, end_keyword_loc: Location? } + def def_keyword: () -> String + def operator: () -> String? + def lparen: () -> String? + def rparen: () -> String? + def equal: () -> String? + def end_keyword: () -> String? + def type: () -> :def_node + | ... + def self.type: () -> :def_node + end + + # Represents the use of the `defined?` keyword. + # + # defined?(a) + # ^^^^^^^^^^^ + class DefinedNode < Node + include _Node + + attr_reader lparen_loc: Location? + attr_reader value: Prism::node + attr_reader rparen_loc: Location? + attr_reader keyword_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location? lparen_loc, Prism::node value, Location? rparen_loc, Location keyword_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?lparen_loc: Location?, ?value: Prism::node, ?rparen_loc: Location?, ?keyword_loc: Location) -> DefinedNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, lparen_loc: Location?, value: Prism::node, rparen_loc: Location?, keyword_loc: Location } + def lparen: () -> String? + def rparen: () -> String? + def keyword: () -> String + def type: () -> :defined_node + | ... + def self.type: () -> :defined_node + end + + # Represents an `else` clause in a `case`, `if`, or `unless` statement. + # + # if a then b else c end + # ^^^^^^^^^^ + class ElseNode < Node + include _Node + + attr_reader else_keyword_loc: Location + attr_reader statements: StatementsNode? + attr_reader end_keyword_loc: Location? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location else_keyword_loc, StatementsNode? statements, Location? end_keyword_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?else_keyword_loc: Location, ?statements: StatementsNode?, ?end_keyword_loc: Location?) -> ElseNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, else_keyword_loc: Location, statements: StatementsNode?, end_keyword_loc: Location? } + def else_keyword: () -> String + def end_keyword: () -> String? + def type: () -> :else_node + | ... + def self.type: () -> :else_node + end + + # Represents an interpolated set of statements. + # + # "foo #{bar}" + # ^^^^^^ + class EmbeddedStatementsNode < Node + include _Node + + attr_reader opening_loc: Location + attr_reader statements: StatementsNode? + attr_reader closing_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location opening_loc, StatementsNode? statements, Location closing_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?statements: StatementsNode?, ?closing_loc: Location) -> EmbeddedStatementsNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location, statements: StatementsNode?, closing_loc: Location } + def opening: () -> String + def closing: () -> String + def type: () -> :embedded_statements_node + | ... + def self.type: () -> :embedded_statements_node + end + + # Represents an interpolated variable. + # + # "foo #@bar" + # ^^^^^ + class EmbeddedVariableNode < Node + include _Node + + attr_reader operator_loc: Location + attr_reader variable: InstanceVariableReadNode | ClassVariableReadNode | GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location operator_loc, InstanceVariableReadNode | ClassVariableReadNode | GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode variable) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?operator_loc: Location, ?variable: InstanceVariableReadNode | ClassVariableReadNode | GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode) -> EmbeddedVariableNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, operator_loc: Location, variable: InstanceVariableReadNode | ClassVariableReadNode | GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode } + def operator: () -> String + def type: () -> :embedded_variable_node + | ... + def self.type: () -> :embedded_variable_node + end + + # Represents an `ensure` clause in a `begin` statement. + # + # begin + # foo + # ensure + # ^^^^^^ + # bar + # end + class EnsureNode < Node + include _Node + + attr_reader ensure_keyword_loc: Location + attr_reader statements: StatementsNode? + attr_reader end_keyword_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location ensure_keyword_loc, StatementsNode? statements, Location end_keyword_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?ensure_keyword_loc: Location, ?statements: StatementsNode?, ?end_keyword_loc: Location) -> EnsureNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, ensure_keyword_loc: Location, statements: StatementsNode?, end_keyword_loc: Location } + def ensure_keyword: () -> String + def end_keyword: () -> String + def type: () -> :ensure_node + | ... + def self.type: () -> :ensure_node + end + + # Represents the use of the literal `false` keyword. + # + # false + # ^^^^^ + class FalseNode < Node + include _Node + + + def initialize: (Source source, Integer node_id, Location location, Integer flags) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> FalseNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def type: () -> :false_node + | ... + def self.type: () -> :false_node + end + + # Represents a find pattern in pattern matching. + # + # foo in *bar, baz, *qux + # ^^^^^^^^^^^^^^^ + # + # foo in [*bar, baz, *qux] + # ^^^^^^^^^^^^^^^^^ + # + # foo in Foo(*bar, baz, *qux) + # ^^^^^^^^^^^^^^^^^^^^ + class FindPatternNode < Node + include _Node + + attr_reader constant: ConstantReadNode | ConstantPathNode | nil + attr_reader left: SplatNode + attr_reader requireds: Array[Prism::node] + attr_reader right: SplatNode | MissingNode + attr_reader opening_loc: Location? + attr_reader closing_loc: Location? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, ConstantReadNode | ConstantPathNode | nil constant, SplatNode left, Array[Prism::node] requireds, SplatNode | MissingNode right, Location? opening_loc, Location? closing_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?constant: ConstantReadNode | ConstantPathNode | nil, ?left: SplatNode, ?requireds: Array[Prism::node], ?right: SplatNode | MissingNode, ?opening_loc: Location?, ?closing_loc: Location?) -> FindPatternNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, constant: ConstantReadNode | ConstantPathNode | nil, left: SplatNode, requireds: Array[Prism::node], right: SplatNode | MissingNode, opening_loc: Location?, closing_loc: Location? } + def opening: () -> String? + def closing: () -> String? + def type: () -> :find_pattern_node + | ... + def self.type: () -> :find_pattern_node + end + + # Represents the use of the `..` or `...` operators to create flip flops. + # + # baz if foo .. bar + # ^^^^^^^^^^ + class FlipFlopNode < Node + include _Node + + def exclude_end?: () -> bool + + attr_reader left: Prism::node? + attr_reader right: Prism::node? + attr_reader operator_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node? left, Prism::node? right, Location operator_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?left: Prism::node?, ?right: Prism::node?, ?operator_loc: Location) -> FlipFlopNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, left: Prism::node?, right: Prism::node?, operator_loc: Location } + def operator: () -> String + def type: () -> :flip_flop_node + | ... + def self.type: () -> :flip_flop_node + end + + # Represents a floating point number literal. + # + # 1.0 + # ^^^ + class FloatNode < Node + include _Node + + attr_reader value: Float + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Float value) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?value: Float) -> FloatNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, value: Float } + def type: () -> :float_node + | ... + def self.type: () -> :float_node + end + + # Represents the use of the `for` keyword. + # + # for i in a end + # ^^^^^^^^^^^^^^ + class ForNode < Node + include _Node + + attr_reader index: LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode | MissingNode + attr_reader collection: Prism::node + attr_reader statements: StatementsNode? + attr_reader for_keyword_loc: Location + attr_reader in_keyword_loc: Location + attr_reader do_keyword_loc: Location? + attr_reader end_keyword_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode | MissingNode index, Prism::node collection, StatementsNode? statements, Location for_keyword_loc, Location in_keyword_loc, Location? do_keyword_loc, Location end_keyword_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?index: LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode | MissingNode, ?collection: Prism::node, ?statements: StatementsNode?, ?for_keyword_loc: Location, ?in_keyword_loc: Location, ?do_keyword_loc: Location?, ?end_keyword_loc: Location) -> ForNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, index: LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode | MissingNode, collection: Prism::node, statements: StatementsNode?, for_keyword_loc: Location, in_keyword_loc: Location, do_keyword_loc: Location?, end_keyword_loc: Location } + def for_keyword: () -> String + def in_keyword: () -> String + def do_keyword: () -> String? + def end_keyword: () -> String + def type: () -> :for_node + | ... + def self.type: () -> :for_node + end + + # Represents forwarding all arguments to this method to another method. + # + # def foo(...) + # bar(...) + # ^^^ + # end + class ForwardingArgumentsNode < Node + include _Node + + + def initialize: (Source source, Integer node_id, Location location, Integer flags) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> ForwardingArgumentsNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def type: () -> :forwarding_arguments_node + | ... + def self.type: () -> :forwarding_arguments_node + end + + # Represents the use of the forwarding parameter in a method, block, or lambda declaration. + # + # def foo(...) + # ^^^ + # end + class ForwardingParameterNode < Node + include _Node + + + def initialize: (Source source, Integer node_id, Location location, Integer flags) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> ForwardingParameterNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def type: () -> :forwarding_parameter_node + | ... + def self.type: () -> :forwarding_parameter_node + end + + # Represents the use of the `super` keyword without parentheses or arguments. + # + # super + # ^^^^^ + class ForwardingSuperNode < Node + include _Node + + attr_reader block: BlockNode? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, BlockNode? block) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?block: BlockNode?) -> ForwardingSuperNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, block: BlockNode? } + def type: () -> :forwarding_super_node + | ... + def self.type: () -> :forwarding_super_node + end + + # Represents the use of the `&&=` operator for assignment to a global variable. + # + # $target &&= value + # ^^^^^^^^^^^^^^^^^ + class GlobalVariableAndWriteNode < Node + include _Node + + attr_reader name: Symbol + attr_reader name_loc: Location + attr_reader operator_loc: Location + attr_reader value: Prism::node + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name, Location name_loc, Location operator_loc, Prism::node value) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> GlobalVariableAndWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } + def operator: () -> String + def type: () -> :global_variable_and_write_node + | ... + def self.type: () -> :global_variable_and_write_node + end + + # Represents assigning to a global variable using an operator that isn't `=`. + # + # $target += value + # ^^^^^^^^^^^^^^^^ + class GlobalVariableOperatorWriteNode < Node + include _Node + + attr_reader name: Symbol + attr_reader name_loc: Location + attr_reader binary_operator_loc: Location + attr_reader value: Prism::node + attr_reader binary_operator: Symbol + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name, Location name_loc, Location binary_operator_loc, Prism::node value, Symbol binary_operator) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?binary_operator_loc: Location, ?value: Prism::node, ?binary_operator: Symbol) -> GlobalVariableOperatorWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, binary_operator_loc: Location, value: Prism::node, binary_operator: Symbol } + def type: () -> :global_variable_operator_write_node + | ... + def self.type: () -> :global_variable_operator_write_node + end + + # Represents the use of the `||=` operator for assignment to a global variable. + # + # $target ||= value + # ^^^^^^^^^^^^^^^^^ + class GlobalVariableOrWriteNode < Node + include _Node + + attr_reader name: Symbol + attr_reader name_loc: Location + attr_reader operator_loc: Location + attr_reader value: Prism::node + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name, Location name_loc, Location operator_loc, Prism::node value) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> GlobalVariableOrWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } + def operator: () -> String + def type: () -> :global_variable_or_write_node + | ... + def self.type: () -> :global_variable_or_write_node + end + + # Represents referencing a global variable. + # + # $foo + # ^^^^ + class GlobalVariableReadNode < Node + include _Node + + attr_reader name: Symbol + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> GlobalVariableReadNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } + def type: () -> :global_variable_read_node + | ... + def self.type: () -> :global_variable_read_node + end + + # Represents writing to a global variable in a context that doesn't have an explicit value. + # + # $foo, $bar = baz + # ^^^^ ^^^^ + class GlobalVariableTargetNode < Node + include _Node + + attr_reader name: Symbol + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> GlobalVariableTargetNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } + def type: () -> :global_variable_target_node + | ... + def self.type: () -> :global_variable_target_node + end + + # Represents writing to a global variable. + # + # $foo = 1 + # ^^^^^^^^ + class GlobalVariableWriteNode < Node + include _Node + + attr_reader name: Symbol + attr_reader name_loc: Location + attr_reader value: Prism::node + attr_reader operator_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name, Location name_loc, Prism::node value, Location operator_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?value: Prism::node, ?operator_loc: Location) -> GlobalVariableWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, value: Prism::node, operator_loc: Location } + def operator: () -> String + def type: () -> :global_variable_write_node + | ... + def self.type: () -> :global_variable_write_node + end + + # Represents a hash literal. + # + # { a => b } + # ^^^^^^^^^^ + class HashNode < Node + include _Node + + attr_reader opening_loc: Location + attr_reader elements: Array[AssocNode | AssocSplatNode] + attr_reader closing_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location opening_loc, Array[AssocNode | AssocSplatNode] elements, Location closing_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?elements: Array[AssocNode | AssocSplatNode], ?closing_loc: Location) -> HashNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location, elements: Array[AssocNode | AssocSplatNode], closing_loc: Location } + def opening: () -> String + def closing: () -> String + def type: () -> :hash_node + | ... + def self.type: () -> :hash_node + end + + # Represents a hash pattern in pattern matching. + # + # foo => { a: 1, b: 2 } + # ^^^^^^^^^^^^^^ + # + # foo => { a: 1, b: 2, **c } + # ^^^^^^^^^^^^^^^^^^^ + class HashPatternNode < Node + include _Node + + attr_reader constant: ConstantReadNode | ConstantPathNode | nil + attr_reader elements: Array[AssocNode] + attr_reader rest: AssocSplatNode | NoKeywordsParameterNode | nil + attr_reader opening_loc: Location? + attr_reader closing_loc: Location? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, ConstantReadNode | ConstantPathNode | nil constant, Array[AssocNode] elements, AssocSplatNode | NoKeywordsParameterNode | nil rest, Location? opening_loc, Location? closing_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?constant: ConstantReadNode | ConstantPathNode | nil, ?elements: Array[AssocNode], ?rest: AssocSplatNode | NoKeywordsParameterNode | nil, ?opening_loc: Location?, ?closing_loc: Location?) -> HashPatternNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, constant: ConstantReadNode | ConstantPathNode | nil, elements: Array[AssocNode], rest: AssocSplatNode | NoKeywordsParameterNode | nil, opening_loc: Location?, closing_loc: Location? } + def opening: () -> String? + def closing: () -> String? + def type: () -> :hash_pattern_node + | ... + def self.type: () -> :hash_pattern_node + end + + # Represents the use of the `if` keyword, either in the block form or the modifier form, or a ternary expression. + # + # bar if foo + # ^^^^^^^^^^ + # + # if foo then bar end + # ^^^^^^^^^^^^^^^^^^^ + # + # foo ? bar : baz + # ^^^^^^^^^^^^^^^ + class IfNode < Node + include _Node + + attr_reader if_keyword_loc: Location? + attr_reader predicate: Prism::node + attr_reader then_keyword_loc: Location? + attr_reader statements: StatementsNode? + attr_reader subsequent: ElseNode | IfNode | nil + attr_reader end_keyword_loc: Location? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location? if_keyword_loc, Prism::node predicate, Location? then_keyword_loc, StatementsNode? statements, ElseNode | IfNode | nil subsequent, Location? end_keyword_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?if_keyword_loc: Location?, ?predicate: Prism::node, ?then_keyword_loc: Location?, ?statements: StatementsNode?, ?subsequent: ElseNode | IfNode | nil, ?end_keyword_loc: Location?) -> IfNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, if_keyword_loc: Location?, predicate: Prism::node, then_keyword_loc: Location?, statements: StatementsNode?, subsequent: ElseNode | IfNode | nil, end_keyword_loc: Location? } + def if_keyword: () -> String? + def then_keyword: () -> String? + def end_keyword: () -> String? + def type: () -> :if_node + | ... + def self.type: () -> :if_node + end + + # Represents an imaginary number literal. + # + # 1.0i + # ^^^^ + class ImaginaryNode < Node + include _Node + + attr_reader numeric: FloatNode | IntegerNode | RationalNode + + def initialize: (Source source, Integer node_id, Location location, Integer flags, FloatNode | IntegerNode | RationalNode numeric) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?numeric: FloatNode | IntegerNode | RationalNode) -> ImaginaryNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, numeric: FloatNode | IntegerNode | RationalNode } + def type: () -> :imaginary_node + | ... + def self.type: () -> :imaginary_node + end + + # Represents a node that is implicitly being added to the tree but doesn't correspond directly to a node in the source. + # + # { foo: } + # ^^^^ + # + # { Foo: } + # ^^^^ + # + # foo in { bar: } + # ^^^^ + class ImplicitNode < Node + include _Node + + attr_reader value: LocalVariableReadNode | CallNode | ConstantReadNode | LocalVariableTargetNode + + def initialize: (Source source, Integer node_id, Location location, Integer flags, LocalVariableReadNode | CallNode | ConstantReadNode | LocalVariableTargetNode value) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?value: LocalVariableReadNode | CallNode | ConstantReadNode | LocalVariableTargetNode) -> ImplicitNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, value: LocalVariableReadNode | CallNode | ConstantReadNode | LocalVariableTargetNode } + def type: () -> :implicit_node + | ... + def self.type: () -> :implicit_node + end + + # Represents using a trailing comma to indicate an implicit rest parameter. + # + # foo { |bar,| } + # ^ + # + # foo in [bar,] + # ^ + # + # for foo, in bar do end + # ^ + # + # foo, = bar + # ^ + class ImplicitRestNode < Node + include _Node + + + def initialize: (Source source, Integer node_id, Location location, Integer flags) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> ImplicitRestNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def type: () -> :implicit_rest_node + | ... + def self.type: () -> :implicit_rest_node + end + + # Represents the use of the `in` keyword in a case statement. + # + # case a; in b then c end + # ^^^^^^^^^^^ + class InNode < Node + include _Node + + attr_reader pattern: Prism::node + attr_reader statements: StatementsNode? + attr_reader in_loc: Location + attr_reader then_loc: Location? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node pattern, StatementsNode? statements, Location in_loc, Location? then_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?pattern: Prism::node, ?statements: StatementsNode?, ?in_loc: Location, ?then_loc: Location?) -> InNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, pattern: Prism::node, statements: StatementsNode?, in_loc: Location, then_loc: Location? } + def in: () -> String + def then: () -> String? + def type: () -> :in_node + | ... + def self.type: () -> :in_node + end + + # Represents the use of the `&&=` operator on a call to the `[]` method. + # + # foo.bar[baz] &&= value + # ^^^^^^^^^^^^^^^^^^^^^^ + class IndexAndWriteNode < Node + include _Node + + def safe_navigation?: () -> bool + def variable_call?: () -> bool + def attribute_write?: () -> bool + def ignore_visibility?: () -> bool + + attr_reader receiver: Prism::node? + attr_reader call_operator_loc: Location? + attr_reader opening_loc: Location + attr_reader arguments: ArgumentsNode? + attr_reader closing_loc: Location + attr_reader block: BlockArgumentNode? + attr_reader operator_loc: Location + attr_reader value: Prism::node + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node? receiver, Location? call_operator_loc, Location opening_loc, ArgumentsNode? arguments, Location closing_loc, BlockArgumentNode? block, Location operator_loc, Prism::node value) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?opening_loc: Location, ?arguments: ArgumentsNode?, ?closing_loc: Location, ?block: BlockArgumentNode?, ?operator_loc: Location, ?value: Prism::node) -> IndexAndWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, opening_loc: Location, arguments: ArgumentsNode?, closing_loc: Location, block: BlockArgumentNode?, operator_loc: Location, value: Prism::node } + def call_operator: () -> String? + def opening: () -> String + def closing: () -> String + def operator: () -> String + def type: () -> :index_and_write_node + | ... + def self.type: () -> :index_and_write_node + end + + # Represents the use of an assignment operator on a call to `[]`. + # + # foo.bar[baz] += value + # ^^^^^^^^^^^^^^^^^^^^^ + class IndexOperatorWriteNode < Node + include _Node + + def safe_navigation?: () -> bool + def variable_call?: () -> bool + def attribute_write?: () -> bool + def ignore_visibility?: () -> bool + + attr_reader receiver: Prism::node? + attr_reader call_operator_loc: Location? + attr_reader opening_loc: Location + attr_reader arguments: ArgumentsNode? + attr_reader closing_loc: Location + attr_reader block: BlockArgumentNode? + attr_reader binary_operator: Symbol + attr_reader binary_operator_loc: Location + attr_reader value: Prism::node + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node? receiver, Location? call_operator_loc, Location opening_loc, ArgumentsNode? arguments, Location closing_loc, BlockArgumentNode? block, Symbol binary_operator, Location binary_operator_loc, Prism::node value) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?opening_loc: Location, ?arguments: ArgumentsNode?, ?closing_loc: Location, ?block: BlockArgumentNode?, ?binary_operator: Symbol, ?binary_operator_loc: Location, ?value: Prism::node) -> IndexOperatorWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, opening_loc: Location, arguments: ArgumentsNode?, closing_loc: Location, block: BlockArgumentNode?, binary_operator: Symbol, binary_operator_loc: Location, value: Prism::node } + def call_operator: () -> String? + def opening: () -> String + def closing: () -> String + def type: () -> :index_operator_write_node + | ... + def self.type: () -> :index_operator_write_node + end + + # Represents the use of the `||=` operator on a call to `[]`. + # + # foo.bar[baz] ||= value + # ^^^^^^^^^^^^^^^^^^^^^^ + class IndexOrWriteNode < Node + include _Node + + def safe_navigation?: () -> bool + def variable_call?: () -> bool + def attribute_write?: () -> bool + def ignore_visibility?: () -> bool + + attr_reader receiver: Prism::node? + attr_reader call_operator_loc: Location? + attr_reader opening_loc: Location + attr_reader arguments: ArgumentsNode? + attr_reader closing_loc: Location + attr_reader block: BlockArgumentNode? + attr_reader operator_loc: Location + attr_reader value: Prism::node + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node? receiver, Location? call_operator_loc, Location opening_loc, ArgumentsNode? arguments, Location closing_loc, BlockArgumentNode? block, Location operator_loc, Prism::node value) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?opening_loc: Location, ?arguments: ArgumentsNode?, ?closing_loc: Location, ?block: BlockArgumentNode?, ?operator_loc: Location, ?value: Prism::node) -> IndexOrWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, opening_loc: Location, arguments: ArgumentsNode?, closing_loc: Location, block: BlockArgumentNode?, operator_loc: Location, value: Prism::node } + def call_operator: () -> String? + def opening: () -> String + def closing: () -> String + def operator: () -> String + def type: () -> :index_or_write_node + | ... + def self.type: () -> :index_or_write_node + end + + # Represents assigning to an index. + # + # foo[bar], = 1 + # ^^^^^^^^ + # + # begin + # rescue => foo[bar] + # ^^^^^^^^ + # end + # + # for foo[bar] in baz do end + # ^^^^^^^^ + class IndexTargetNode < Node + include _Node + + def safe_navigation?: () -> bool + def variable_call?: () -> bool + def attribute_write?: () -> bool + def ignore_visibility?: () -> bool + + attr_reader receiver: Prism::node + attr_reader opening_loc: Location + attr_reader arguments: ArgumentsNode? + attr_reader closing_loc: Location + attr_reader block: BlockArgumentNode? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node receiver, Location opening_loc, ArgumentsNode? arguments, Location closing_loc, BlockArgumentNode? block) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node, ?opening_loc: Location, ?arguments: ArgumentsNode?, ?closing_loc: Location, ?block: BlockArgumentNode?) -> IndexTargetNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node, opening_loc: Location, arguments: ArgumentsNode?, closing_loc: Location, block: BlockArgumentNode? } + def opening: () -> String + def closing: () -> String + def type: () -> :index_target_node + | ... + def self.type: () -> :index_target_node + end + + # Represents the use of the `&&=` operator for assignment to an instance variable. + # + # @target &&= value + # ^^^^^^^^^^^^^^^^^ + class InstanceVariableAndWriteNode < Node + include _Node + + attr_reader name: Symbol + attr_reader name_loc: Location + attr_reader operator_loc: Location + attr_reader value: Prism::node + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name, Location name_loc, Location operator_loc, Prism::node value) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> InstanceVariableAndWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } + def operator: () -> String + def type: () -> :instance_variable_and_write_node + | ... + def self.type: () -> :instance_variable_and_write_node + end + + # Represents assigning to an instance variable using an operator that isn't `=`. + # + # @target += value + # ^^^^^^^^^^^^^^^^ + class InstanceVariableOperatorWriteNode < Node + include _Node + + attr_reader name: Symbol + attr_reader name_loc: Location + attr_reader binary_operator_loc: Location + attr_reader value: Prism::node + attr_reader binary_operator: Symbol + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name, Location name_loc, Location binary_operator_loc, Prism::node value, Symbol binary_operator) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?binary_operator_loc: Location, ?value: Prism::node, ?binary_operator: Symbol) -> InstanceVariableOperatorWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, binary_operator_loc: Location, value: Prism::node, binary_operator: Symbol } + def type: () -> :instance_variable_operator_write_node + | ... + def self.type: () -> :instance_variable_operator_write_node + end + + # Represents the use of the `||=` operator for assignment to an instance variable. + # + # @target ||= value + # ^^^^^^^^^^^^^^^^^ + class InstanceVariableOrWriteNode < Node + include _Node + + attr_reader name: Symbol + attr_reader name_loc: Location + attr_reader operator_loc: Location + attr_reader value: Prism::node + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name, Location name_loc, Location operator_loc, Prism::node value) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> InstanceVariableOrWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } + def operator: () -> String + def type: () -> :instance_variable_or_write_node + | ... + def self.type: () -> :instance_variable_or_write_node + end + + # Represents referencing an instance variable. + # + # @foo + # ^^^^ + class InstanceVariableReadNode < Node + include _Node + + attr_reader name: Symbol + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> InstanceVariableReadNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } + def type: () -> :instance_variable_read_node + | ... + def self.type: () -> :instance_variable_read_node + end + + # Represents writing to an instance variable in a context that doesn't have an explicit value. + # + # @foo, @bar = baz + # ^^^^ ^^^^ + class InstanceVariableTargetNode < Node + include _Node + + attr_reader name: Symbol + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> InstanceVariableTargetNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } + def type: () -> :instance_variable_target_node + | ... + def self.type: () -> :instance_variable_target_node + end + + # Represents writing to an instance variable. + # + # @foo = 1 + # ^^^^^^^^ + class InstanceVariableWriteNode < Node + include _Node + + attr_reader name: Symbol + attr_reader name_loc: Location + attr_reader value: Prism::node + attr_reader operator_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name, Location name_loc, Prism::node value, Location operator_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?value: Prism::node, ?operator_loc: Location) -> InstanceVariableWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, value: Prism::node, operator_loc: Location } + def operator: () -> String + def type: () -> :instance_variable_write_node + | ... + def self.type: () -> :instance_variable_write_node + end + + # Represents an integer number literal. + # + # 1 + # ^ + class IntegerNode < Node + include _Node + + def binary?: () -> bool + def decimal?: () -> bool + def octal?: () -> bool + def hexadecimal?: () -> bool + + attr_reader value: Integer + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Integer value) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?value: Integer) -> IntegerNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, value: Integer } + def type: () -> :integer_node + | ... + def self.type: () -> :integer_node + end + + # Represents a regular expression literal that contains interpolation that is being used in the predicate of a conditional to implicitly match against the last line read by an IO object. + # + # if /foo #{bar} baz/ then end + # ^^^^^^^^^^^^^^^^ + class InterpolatedMatchLastLineNode < Node + include _Node + + def ignore_case?: () -> bool + def extended?: () -> bool + def multi_line?: () -> bool + def once?: () -> bool + def euc_jp?: () -> bool + def ascii_8bit?: () -> bool + def windows_31j?: () -> bool + def utf_8?: () -> bool + def forced_utf8_encoding?: () -> bool + def forced_binary_encoding?: () -> bool + def forced_us_ascii_encoding?: () -> bool + + attr_reader opening_loc: Location + attr_reader parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode] + attr_reader closing_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location opening_loc, Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode] parts, Location closing_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], ?closing_loc: Location) -> InterpolatedMatchLastLineNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location, parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], closing_loc: Location } + def opening: () -> String + def closing: () -> String + def type: () -> :interpolated_match_last_line_node + | ... + def self.type: () -> :interpolated_match_last_line_node + end + + # Represents a regular expression literal that contains interpolation. + # + # /foo #{bar} baz/ + # ^^^^^^^^^^^^^^^^ + class InterpolatedRegularExpressionNode < Node + include _Node + + def ignore_case?: () -> bool + def extended?: () -> bool + def multi_line?: () -> bool + def once?: () -> bool + def euc_jp?: () -> bool + def ascii_8bit?: () -> bool + def windows_31j?: () -> bool + def utf_8?: () -> bool + def forced_utf8_encoding?: () -> bool + def forced_binary_encoding?: () -> bool + def forced_us_ascii_encoding?: () -> bool + + attr_reader opening_loc: Location + attr_reader parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode] + attr_reader closing_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location opening_loc, Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode] parts, Location closing_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], ?closing_loc: Location) -> InterpolatedRegularExpressionNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location, parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], closing_loc: Location } + def opening: () -> String + def closing: () -> String + def type: () -> :interpolated_regular_expression_node + | ... + def self.type: () -> :interpolated_regular_expression_node + end + + # Represents a string literal that contains interpolation. + # + # "foo #{bar} baz" + # ^^^^^^^^^^^^^^^^ + class InterpolatedStringNode < Node + include _Node + + def frozen?: () -> bool + def mutable?: () -> bool + + attr_reader opening_loc: Location? + attr_reader parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode | InterpolatedStringNode | XStringNode] + attr_reader closing_loc: Location? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location? opening_loc, Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode | InterpolatedStringNode | XStringNode] parts, Location? closing_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location?, ?parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode | InterpolatedStringNode | XStringNode], ?closing_loc: Location?) -> InterpolatedStringNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location?, parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode | InterpolatedStringNode | XStringNode], closing_loc: Location? } + def opening: () -> String? + def closing: () -> String? + def type: () -> :interpolated_string_node + | ... + def self.type: () -> :interpolated_string_node + end + + # Represents a symbol literal that contains interpolation. + # + # :"foo #{bar} baz" + # ^^^^^^^^^^^^^^^^^ + class InterpolatedSymbolNode < Node + include _Node + + attr_reader opening_loc: Location? + attr_reader parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode] + attr_reader closing_loc: Location? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location? opening_loc, Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode] parts, Location? closing_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location?, ?parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], ?closing_loc: Location?) -> InterpolatedSymbolNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location?, parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], closing_loc: Location? } + def opening: () -> String? + def closing: () -> String? + def type: () -> :interpolated_symbol_node + | ... + def self.type: () -> :interpolated_symbol_node + end + + # Represents an xstring literal that contains interpolation. + # + # `foo #{bar} baz` + # ^^^^^^^^^^^^^^^^ + class InterpolatedXStringNode < Node + include _Node + + attr_reader opening_loc: Location + attr_reader parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode] + attr_reader closing_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location opening_loc, Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode] parts, Location closing_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], ?closing_loc: Location) -> InterpolatedXStringNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location, parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], closing_loc: Location } + def opening: () -> String + def closing: () -> String + def type: () -> :interpolated_x_string_node + | ... + def self.type: () -> :interpolated_x_string_node + end + + # Represents reading from the implicit `it` local variable. + # + # -> { it } + # ^^ + class ItLocalVariableReadNode < Node + include _Node + + + def initialize: (Source source, Integer node_id, Location location, Integer flags) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> ItLocalVariableReadNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def type: () -> :it_local_variable_read_node + | ... + def self.type: () -> :it_local_variable_read_node + end + + # Represents an implicit set of parameters through the use of the `it` keyword within a block or lambda. + # + # -> { it + it } + # ^^^^^^^^^^^^^^ + class ItParametersNode < Node + include _Node + + + def initialize: (Source source, Integer node_id, Location location, Integer flags) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> ItParametersNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def type: () -> :it_parameters_node + | ... + def self.type: () -> :it_parameters_node + end + + # Represents a hash literal without opening and closing braces. + # + # foo(a: b) + # ^^^^ + class KeywordHashNode < Node + include _Node + + def symbol_keys?: () -> bool + + attr_reader elements: Array[AssocNode | AssocSplatNode] + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Array[AssocNode | AssocSplatNode] elements) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?elements: Array[AssocNode | AssocSplatNode]) -> KeywordHashNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, elements: Array[AssocNode | AssocSplatNode] } + def type: () -> :keyword_hash_node + | ... + def self.type: () -> :keyword_hash_node + end + + # Represents a keyword rest parameter to a method, block, or lambda definition. + # + # def a(**b) + # ^^^ + # end + class KeywordRestParameterNode < Node + include _Node + + def repeated_parameter?: () -> bool + + attr_reader name: Symbol? + attr_reader name_loc: Location? + attr_reader operator_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol? name, Location? name_loc, Location operator_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol?, ?name_loc: Location?, ?operator_loc: Location) -> KeywordRestParameterNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol?, name_loc: Location?, operator_loc: Location } + def operator: () -> String + def type: () -> :keyword_rest_parameter_node + | ... + def self.type: () -> :keyword_rest_parameter_node + end + + # Represents using a lambda literal (not the lambda method call). + # + # ->(value) { value * 2 } + # ^^^^^^^^^^^^^^^^^^^^^^^ + class LambdaNode < Node + include _Node + + attr_reader locals: Array[Symbol] + attr_reader operator_loc: Location + attr_reader opening_loc: Location + attr_reader closing_loc: Location + attr_reader parameters: BlockParametersNode | NumberedParametersNode | ItParametersNode | nil + attr_reader body: StatementsNode | BeginNode | nil + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Array[Symbol] locals, Location operator_loc, Location opening_loc, Location closing_loc, BlockParametersNode | NumberedParametersNode | ItParametersNode | nil parameters, StatementsNode | BeginNode | nil body) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?locals: Array[Symbol], ?operator_loc: Location, ?opening_loc: Location, ?closing_loc: Location, ?parameters: BlockParametersNode | NumberedParametersNode | ItParametersNode | nil, ?body: StatementsNode | BeginNode | nil) -> LambdaNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, locals: Array[Symbol], operator_loc: Location, opening_loc: Location, closing_loc: Location, parameters: BlockParametersNode | NumberedParametersNode | ItParametersNode | nil, body: StatementsNode | BeginNode | nil } + def operator: () -> String + def opening: () -> String + def closing: () -> String + def type: () -> :lambda_node + | ... + def self.type: () -> :lambda_node + end + + # Represents the use of the `&&=` operator for assignment to a local variable. + # + # target &&= value + # ^^^^^^^^^^^^^^^^ + class LocalVariableAndWriteNode < Node + include _Node + + attr_reader name_loc: Location + attr_reader operator_loc: Location + attr_reader value: Prism::node + attr_reader name: Symbol + attr_reader depth: Integer + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location name_loc, Location operator_loc, Prism::node value, Symbol name, Integer depth) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node, ?name: Symbol, ?depth: Integer) -> LocalVariableAndWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name_loc: Location, operator_loc: Location, value: Prism::node, name: Symbol, depth: Integer } + def operator: () -> String + def type: () -> :local_variable_and_write_node + | ... + def self.type: () -> :local_variable_and_write_node + end + + # Represents assigning to a local variable using an operator that isn't `=`. + # + # target += value + # ^^^^^^^^^^^^^^^ + class LocalVariableOperatorWriteNode < Node + include _Node + + attr_reader name_loc: Location + attr_reader binary_operator_loc: Location + attr_reader value: Prism::node + attr_reader name: Symbol + attr_reader binary_operator: Symbol + attr_reader depth: Integer + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location name_loc, Location binary_operator_loc, Prism::node value, Symbol name, Symbol binary_operator, Integer depth) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name_loc: Location, ?binary_operator_loc: Location, ?value: Prism::node, ?name: Symbol, ?binary_operator: Symbol, ?depth: Integer) -> LocalVariableOperatorWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name_loc: Location, binary_operator_loc: Location, value: Prism::node, name: Symbol, binary_operator: Symbol, depth: Integer } + def type: () -> :local_variable_operator_write_node + | ... + def self.type: () -> :local_variable_operator_write_node + end + + # Represents the use of the `||=` operator for assignment to a local variable. + # + # target ||= value + # ^^^^^^^^^^^^^^^^ + class LocalVariableOrWriteNode < Node + include _Node + + attr_reader name_loc: Location + attr_reader operator_loc: Location + attr_reader value: Prism::node + attr_reader name: Symbol + attr_reader depth: Integer + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location name_loc, Location operator_loc, Prism::node value, Symbol name, Integer depth) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node, ?name: Symbol, ?depth: Integer) -> LocalVariableOrWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name_loc: Location, operator_loc: Location, value: Prism::node, name: Symbol, depth: Integer } + def operator: () -> String + def type: () -> :local_variable_or_write_node + | ... + def self.type: () -> :local_variable_or_write_node + end + + # Represents reading a local variable. Note that this requires that a local variable of the same name has already been written to in the same scope, otherwise it is parsed as a method call. + # + # foo + # ^^^ + class LocalVariableReadNode < Node + include _Node + + attr_reader name: Symbol + attr_reader depth: Integer + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name, Integer depth) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?depth: Integer) -> LocalVariableReadNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, depth: Integer } + def type: () -> :local_variable_read_node + | ... + def self.type: () -> :local_variable_read_node + end + + # Represents writing to a local variable in a context that doesn't have an explicit value. + # + # foo, bar = baz + # ^^^ ^^^ + class LocalVariableTargetNode < Node + include _Node + + attr_reader name: Symbol + attr_reader depth: Integer + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name, Integer depth) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?depth: Integer) -> LocalVariableTargetNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, depth: Integer } + def type: () -> :local_variable_target_node + | ... + def self.type: () -> :local_variable_target_node + end + + # Represents writing to a local variable. + # + # foo = 1 + # ^^^^^^^ + class LocalVariableWriteNode < Node + include _Node + + attr_reader name: Symbol + attr_reader depth: Integer + attr_reader name_loc: Location + attr_reader value: Prism::node + attr_reader operator_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name, Integer depth, Location name_loc, Prism::node value, Location operator_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?depth: Integer, ?name_loc: Location, ?value: Prism::node, ?operator_loc: Location) -> LocalVariableWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, depth: Integer, name_loc: Location, value: Prism::node, operator_loc: Location } + def operator: () -> String + def type: () -> :local_variable_write_node + | ... + def self.type: () -> :local_variable_write_node + end + + # Represents a regular expression literal used in the predicate of a conditional to implicitly match against the last line read by an IO object. + # + # if /foo/i then end + # ^^^^^^ + class MatchLastLineNode < Node + include _Node + + def ignore_case?: () -> bool + def extended?: () -> bool + def multi_line?: () -> bool + def once?: () -> bool + def euc_jp?: () -> bool + def ascii_8bit?: () -> bool + def windows_31j?: () -> bool + def utf_8?: () -> bool + def forced_utf8_encoding?: () -> bool + def forced_binary_encoding?: () -> bool + def forced_us_ascii_encoding?: () -> bool + + attr_reader opening_loc: Location + attr_reader content_loc: Location + attr_reader closing_loc: Location + attr_reader unescaped: String + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location opening_loc, Location content_loc, Location closing_loc, String unescaped) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?content_loc: Location, ?closing_loc: Location, ?unescaped: String) -> MatchLastLineNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location, content_loc: Location, closing_loc: Location, unescaped: String } + def opening: () -> String + def content: () -> String + def closing: () -> String + def type: () -> :match_last_line_node + | ... + def self.type: () -> :match_last_line_node + end + + # Represents the use of the modifier `in` operator. + # + # foo in bar + # ^^^^^^^^^^ + class MatchPredicateNode < Node + include _Node + + attr_reader value: Prism::node + attr_reader pattern: Prism::node + attr_reader operator_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node value, Prism::node pattern, Location operator_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?value: Prism::node, ?pattern: Prism::node, ?operator_loc: Location) -> MatchPredicateNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, value: Prism::node, pattern: Prism::node, operator_loc: Location } + def operator: () -> String + def type: () -> :match_predicate_node + | ... + def self.type: () -> :match_predicate_node + end + + # Represents the use of the `=>` operator. + # + # foo => bar + # ^^^^^^^^^^ + class MatchRequiredNode < Node + include _Node + + attr_reader value: Prism::node + attr_reader pattern: Prism::node + attr_reader operator_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node value, Prism::node pattern, Location operator_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?value: Prism::node, ?pattern: Prism::node, ?operator_loc: Location) -> MatchRequiredNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, value: Prism::node, pattern: Prism::node, operator_loc: Location } + def operator: () -> String + def type: () -> :match_required_node + | ... + def self.type: () -> :match_required_node + end + + # Represents writing local variables using a regular expression match with named capture groups. + # + # /(?bar)/ =~ baz + # ^^^^^^^^^^^^^^^^^^^^ + class MatchWriteNode < Node + include _Node + + attr_reader call: CallNode + attr_reader targets: Array[LocalVariableTargetNode] + + def initialize: (Source source, Integer node_id, Location location, Integer flags, CallNode call, Array[LocalVariableTargetNode] targets) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?call: CallNode, ?targets: Array[LocalVariableTargetNode]) -> MatchWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, call: CallNode, targets: Array[LocalVariableTargetNode] } + def type: () -> :match_write_node + | ... + def self.type: () -> :match_write_node + end + + # Represents a node that is missing from the source and results in a syntax error. + class MissingNode < Node + include _Node + + + def initialize: (Source source, Integer node_id, Location location, Integer flags) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> MissingNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def type: () -> :missing_node + | ... + def self.type: () -> :missing_node + end + + # Represents a module declaration involving the `module` keyword. + # + # module Foo end + # ^^^^^^^^^^^^^^ + class ModuleNode < Node + include _Node + + attr_reader locals: Array[Symbol] + attr_reader module_keyword_loc: Location + attr_reader constant_path: ConstantReadNode | ConstantPathNode | MissingNode + attr_reader body: StatementsNode | BeginNode | nil + attr_reader end_keyword_loc: Location + attr_reader name: Symbol + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Array[Symbol] locals, Location module_keyword_loc, ConstantReadNode | ConstantPathNode | MissingNode constant_path, StatementsNode | BeginNode | nil body, Location end_keyword_loc, Symbol name) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?locals: Array[Symbol], ?module_keyword_loc: Location, ?constant_path: ConstantReadNode | ConstantPathNode | MissingNode, ?body: StatementsNode | BeginNode | nil, ?end_keyword_loc: Location, ?name: Symbol) -> ModuleNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, locals: Array[Symbol], module_keyword_loc: Location, constant_path: ConstantReadNode | ConstantPathNode | MissingNode, body: StatementsNode | BeginNode | nil, end_keyword_loc: Location, name: Symbol } + def module_keyword: () -> String + def end_keyword: () -> String + def type: () -> :module_node + | ... + def self.type: () -> :module_node + end + + # Represents a multi-target expression. + # + # a, (b, c) = 1, 2, 3 + # ^^^^^^ + # + # This can be a part of `MultiWriteNode` as above, or the target of a `for` loop + # + # for a, b in [[1, 2], [3, 4]] + # ^^^^ + class MultiTargetNode < Node + include _Node + + attr_reader lefts: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | RequiredParameterNode | BackReferenceReadNode | NumberedReferenceReadNode] + attr_reader rest: ImplicitRestNode | SplatNode | nil + attr_reader rights: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | RequiredParameterNode | BackReferenceReadNode | NumberedReferenceReadNode] + attr_reader lparen_loc: Location? + attr_reader rparen_loc: Location? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | RequiredParameterNode | BackReferenceReadNode | NumberedReferenceReadNode] lefts, ImplicitRestNode | SplatNode | nil rest, Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | RequiredParameterNode | BackReferenceReadNode | NumberedReferenceReadNode] rights, Location? lparen_loc, Location? rparen_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?lefts: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | RequiredParameterNode | BackReferenceReadNode | NumberedReferenceReadNode], ?rest: ImplicitRestNode | SplatNode | nil, ?rights: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | RequiredParameterNode | BackReferenceReadNode | NumberedReferenceReadNode], ?lparen_loc: Location?, ?rparen_loc: Location?) -> MultiTargetNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, lefts: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | RequiredParameterNode | BackReferenceReadNode | NumberedReferenceReadNode], rest: ImplicitRestNode | SplatNode | nil, rights: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | RequiredParameterNode | BackReferenceReadNode | NumberedReferenceReadNode], lparen_loc: Location?, rparen_loc: Location? } + def lparen: () -> String? + def rparen: () -> String? + def type: () -> :multi_target_node + | ... + def self.type: () -> :multi_target_node + end + + # Represents a write to a multi-target expression. + # + # a, b, c = 1, 2, 3 + # ^^^^^^^^^^^^^^^^^ + class MultiWriteNode < Node + include _Node + + attr_reader lefts: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode] + attr_reader rest: ImplicitRestNode | SplatNode | nil + attr_reader rights: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode] + attr_reader lparen_loc: Location? + attr_reader rparen_loc: Location? + attr_reader operator_loc: Location + attr_reader value: Prism::node + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode] lefts, ImplicitRestNode | SplatNode | nil rest, Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode] rights, Location? lparen_loc, Location? rparen_loc, Location operator_loc, Prism::node value) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?lefts: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode], ?rest: ImplicitRestNode | SplatNode | nil, ?rights: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode], ?lparen_loc: Location?, ?rparen_loc: Location?, ?operator_loc: Location, ?value: Prism::node) -> MultiWriteNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, lefts: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode], rest: ImplicitRestNode | SplatNode | nil, rights: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode], lparen_loc: Location?, rparen_loc: Location?, operator_loc: Location, value: Prism::node } + def lparen: () -> String? + def rparen: () -> String? + def operator: () -> String + def type: () -> :multi_write_node + | ... + def self.type: () -> :multi_write_node + end + + # Represents the use of the `next` keyword. + # + # next 1 + # ^^^^^^ + class NextNode < Node + include _Node + + attr_reader arguments: ArgumentsNode? + attr_reader keyword_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, ArgumentsNode? arguments, Location keyword_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?arguments: ArgumentsNode?, ?keyword_loc: Location) -> NextNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, arguments: ArgumentsNode?, keyword_loc: Location } + def keyword: () -> String + def type: () -> :next_node + | ... + def self.type: () -> :next_node + end + + # Represents the use of the `nil` keyword. + # + # nil + # ^^^ + class NilNode < Node + include _Node + + + def initialize: (Source source, Integer node_id, Location location, Integer flags) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> NilNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def type: () -> :nil_node + | ... + def self.type: () -> :nil_node + end + + # Represents the use of `**nil` inside method arguments. + # + # def a(**nil) + # ^^^^^ + # end + class NoKeywordsParameterNode < Node + include _Node + + attr_reader operator_loc: Location + attr_reader keyword_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location operator_loc, Location keyword_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?operator_loc: Location, ?keyword_loc: Location) -> NoKeywordsParameterNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, operator_loc: Location, keyword_loc: Location } + def operator: () -> String + def keyword: () -> String + def type: () -> :no_keywords_parameter_node + | ... + def self.type: () -> :no_keywords_parameter_node + end + + # Represents an implicit set of parameters through the use of numbered parameters within a block or lambda. + # + # -> { _1 + _2 } + # ^^^^^^^^^^^^^^ + class NumberedParametersNode < Node + include _Node + + attr_reader maximum: Integer + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Integer maximum) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?maximum: Integer) -> NumberedParametersNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, maximum: Integer } + def type: () -> :numbered_parameters_node + | ... + def self.type: () -> :numbered_parameters_node + end + + # Represents reading a numbered reference to a capture in the previous match. + # + # $1 + # ^^ + class NumberedReferenceReadNode < Node + include _Node + + attr_reader number: Integer + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Integer number) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?number: Integer) -> NumberedReferenceReadNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, number: Integer } + def type: () -> :numbered_reference_read_node + | ... + def self.type: () -> :numbered_reference_read_node + end + + # Represents an optional keyword parameter to a method, block, or lambda definition. + # + # def a(b: 1) + # ^^^^ + # end + class OptionalKeywordParameterNode < Node + include _Node + + def repeated_parameter?: () -> bool + + attr_reader name: Symbol + attr_reader name_loc: Location + attr_reader value: Prism::node + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name, Location name_loc, Prism::node value) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?value: Prism::node) -> OptionalKeywordParameterNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, value: Prism::node } + def type: () -> :optional_keyword_parameter_node + | ... + def self.type: () -> :optional_keyword_parameter_node + end + + # Represents an optional parameter to a method, block, or lambda definition. + # + # def a(b = 1) + # ^^^^^ + # end + class OptionalParameterNode < Node + include _Node + + def repeated_parameter?: () -> bool + + attr_reader name: Symbol + attr_reader name_loc: Location + attr_reader operator_loc: Location + attr_reader value: Prism::node + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name, Location name_loc, Location operator_loc, Prism::node value) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> OptionalParameterNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } + def operator: () -> String + def type: () -> :optional_parameter_node + | ... + def self.type: () -> :optional_parameter_node + end + + # Represents the use of the `||` operator or the `or` keyword. + # + # left or right + # ^^^^^^^^^^^^^ + class OrNode < Node + include _Node + + attr_reader left: Prism::node + attr_reader right: Prism::node + attr_reader operator_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node left, Prism::node right, Location operator_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?left: Prism::node, ?right: Prism::node, ?operator_loc: Location) -> OrNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, left: Prism::node, right: Prism::node, operator_loc: Location } + def operator: () -> String + def type: () -> :or_node + | ... + def self.type: () -> :or_node + end + + # Represents the list of parameters on a method, block, or lambda definition. + # + # def a(b, c, d) + # ^^^^^^^ + # end + class ParametersNode < Node + include _Node + + attr_reader requireds: Array[RequiredParameterNode | MultiTargetNode] + attr_reader optionals: Array[OptionalParameterNode] + attr_reader rest: RestParameterNode | ImplicitRestNode | nil + attr_reader posts: Array[RequiredParameterNode | MultiTargetNode | KeywordRestParameterNode | NoKeywordsParameterNode | ForwardingParameterNode] + attr_reader keywords: Array[RequiredKeywordParameterNode | OptionalKeywordParameterNode] + attr_reader keyword_rest: KeywordRestParameterNode | ForwardingParameterNode | NoKeywordsParameterNode | nil + attr_reader block: BlockParameterNode? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Array[RequiredParameterNode | MultiTargetNode] requireds, Array[OptionalParameterNode] optionals, RestParameterNode | ImplicitRestNode | nil rest, Array[RequiredParameterNode | MultiTargetNode | KeywordRestParameterNode | NoKeywordsParameterNode | ForwardingParameterNode] posts, Array[RequiredKeywordParameterNode | OptionalKeywordParameterNode] keywords, KeywordRestParameterNode | ForwardingParameterNode | NoKeywordsParameterNode | nil keyword_rest, BlockParameterNode? block) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?requireds: Array[RequiredParameterNode | MultiTargetNode], ?optionals: Array[OptionalParameterNode], ?rest: RestParameterNode | ImplicitRestNode | nil, ?posts: Array[RequiredParameterNode | MultiTargetNode | KeywordRestParameterNode | NoKeywordsParameterNode | ForwardingParameterNode], ?keywords: Array[RequiredKeywordParameterNode | OptionalKeywordParameterNode], ?keyword_rest: KeywordRestParameterNode | ForwardingParameterNode | NoKeywordsParameterNode | nil, ?block: BlockParameterNode?) -> ParametersNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, requireds: Array[RequiredParameterNode | MultiTargetNode], optionals: Array[OptionalParameterNode], rest: RestParameterNode | ImplicitRestNode | nil, posts: Array[RequiredParameterNode | MultiTargetNode | KeywordRestParameterNode | NoKeywordsParameterNode | ForwardingParameterNode], keywords: Array[RequiredKeywordParameterNode | OptionalKeywordParameterNode], keyword_rest: KeywordRestParameterNode | ForwardingParameterNode | NoKeywordsParameterNode | nil, block: BlockParameterNode? } + def type: () -> :parameters_node + | ... + def self.type: () -> :parameters_node + end + + # Represents a parenthesized expression + # + # (10 + 34) + # ^^^^^^^^^ + class ParenthesesNode < Node + include _Node + + def multiple_statements?: () -> bool + + attr_reader body: Prism::node? + attr_reader opening_loc: Location + attr_reader closing_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node? body, Location opening_loc, Location closing_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?body: Prism::node?, ?opening_loc: Location, ?closing_loc: Location) -> ParenthesesNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, body: Prism::node?, opening_loc: Location, closing_loc: Location } + def opening: () -> String + def closing: () -> String + def type: () -> :parentheses_node + | ... + def self.type: () -> :parentheses_node + end + + # Represents the use of the `^` operator for pinning an expression in a pattern matching expression. + # + # foo in ^(bar) + # ^^^^^^ + class PinnedExpressionNode < Node + include _Node + + attr_reader expression: Prism::node + attr_reader operator_loc: Location + attr_reader lparen_loc: Location + attr_reader rparen_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node expression, Location operator_loc, Location lparen_loc, Location rparen_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?expression: Prism::node, ?operator_loc: Location, ?lparen_loc: Location, ?rparen_loc: Location) -> PinnedExpressionNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, expression: Prism::node, operator_loc: Location, lparen_loc: Location, rparen_loc: Location } + def operator: () -> String + def lparen: () -> String + def rparen: () -> String + def type: () -> :pinned_expression_node + | ... + def self.type: () -> :pinned_expression_node + end + + # Represents the use of the `^` operator for pinning a variable in a pattern matching expression. + # + # foo in ^bar + # ^^^^ + class PinnedVariableNode < Node + include _Node + + attr_reader variable: LocalVariableReadNode | InstanceVariableReadNode | ClassVariableReadNode | GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode | ItLocalVariableReadNode | MissingNode + attr_reader operator_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, LocalVariableReadNode | InstanceVariableReadNode | ClassVariableReadNode | GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode | ItLocalVariableReadNode | MissingNode variable, Location operator_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?variable: LocalVariableReadNode | InstanceVariableReadNode | ClassVariableReadNode | GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode | ItLocalVariableReadNode | MissingNode, ?operator_loc: Location) -> PinnedVariableNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, variable: LocalVariableReadNode | InstanceVariableReadNode | ClassVariableReadNode | GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode | ItLocalVariableReadNode | MissingNode, operator_loc: Location } + def operator: () -> String + def type: () -> :pinned_variable_node + | ... + def self.type: () -> :pinned_variable_node + end + + # Represents the use of the `END` keyword. + # + # END { foo } + # ^^^^^^^^^^^ + class PostExecutionNode < Node + include _Node + + attr_reader statements: StatementsNode? + attr_reader keyword_loc: Location + attr_reader opening_loc: Location + attr_reader closing_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, StatementsNode? statements, Location keyword_loc, Location opening_loc, Location closing_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?statements: StatementsNode?, ?keyword_loc: Location, ?opening_loc: Location, ?closing_loc: Location) -> PostExecutionNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, statements: StatementsNode?, keyword_loc: Location, opening_loc: Location, closing_loc: Location } + def keyword: () -> String + def opening: () -> String + def closing: () -> String + def type: () -> :post_execution_node + | ... + def self.type: () -> :post_execution_node + end + + # Represents the use of the `BEGIN` keyword. + # + # BEGIN { foo } + # ^^^^^^^^^^^^^ + class PreExecutionNode < Node + include _Node + + attr_reader statements: StatementsNode? + attr_reader keyword_loc: Location + attr_reader opening_loc: Location + attr_reader closing_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, StatementsNode? statements, Location keyword_loc, Location opening_loc, Location closing_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?statements: StatementsNode?, ?keyword_loc: Location, ?opening_loc: Location, ?closing_loc: Location) -> PreExecutionNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, statements: StatementsNode?, keyword_loc: Location, opening_loc: Location, closing_loc: Location } + def keyword: () -> String + def opening: () -> String + def closing: () -> String + def type: () -> :pre_execution_node + | ... + def self.type: () -> :pre_execution_node + end + + # The top level node of any parse tree. + class ProgramNode < Node + include _Node + + attr_reader locals: Array[Symbol] + attr_reader statements: StatementsNode + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Array[Symbol] locals, StatementsNode statements) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?locals: Array[Symbol], ?statements: StatementsNode) -> ProgramNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, locals: Array[Symbol], statements: StatementsNode } + def type: () -> :program_node + | ... + def self.type: () -> :program_node + end + + # Represents the use of the `..` or `...` operators. + # + # 1..2 + # ^^^^ + # + # c if a =~ /left/ ... b =~ /right/ + # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + class RangeNode < Node + include _Node + + def exclude_end?: () -> bool + + attr_reader left: Prism::node? + attr_reader right: Prism::node? + attr_reader operator_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node? left, Prism::node? right, Location operator_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?left: Prism::node?, ?right: Prism::node?, ?operator_loc: Location) -> RangeNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, left: Prism::node?, right: Prism::node?, operator_loc: Location } + def operator: () -> String + def type: () -> :range_node + | ... + def self.type: () -> :range_node + end + + # Represents a rational number literal. + # + # 1.0r + # ^^^^ + class RationalNode < Node + include _Node + + def binary?: () -> bool + def decimal?: () -> bool + def octal?: () -> bool + def hexadecimal?: () -> bool + + attr_reader numerator: Integer + attr_reader denominator: Integer + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Integer numerator, Integer denominator) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?numerator: Integer, ?denominator: Integer) -> RationalNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, numerator: Integer, denominator: Integer } + def type: () -> :rational_node + | ... + def self.type: () -> :rational_node + end + + # Represents the use of the `redo` keyword. + # + # redo + # ^^^^ + class RedoNode < Node + include _Node + + + def initialize: (Source source, Integer node_id, Location location, Integer flags) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> RedoNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def type: () -> :redo_node + | ... + def self.type: () -> :redo_node + end + + # Represents a regular expression literal with no interpolation. + # + # /foo/i + # ^^^^^^ + class RegularExpressionNode < Node + include _Node + + def ignore_case?: () -> bool + def extended?: () -> bool + def multi_line?: () -> bool + def once?: () -> bool + def euc_jp?: () -> bool + def ascii_8bit?: () -> bool + def windows_31j?: () -> bool + def utf_8?: () -> bool + def forced_utf8_encoding?: () -> bool + def forced_binary_encoding?: () -> bool + def forced_us_ascii_encoding?: () -> bool + + attr_reader opening_loc: Location + attr_reader content_loc: Location + attr_reader closing_loc: Location + attr_reader unescaped: String + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location opening_loc, Location content_loc, Location closing_loc, String unescaped) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?content_loc: Location, ?closing_loc: Location, ?unescaped: String) -> RegularExpressionNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location, content_loc: Location, closing_loc: Location, unescaped: String } + def opening: () -> String + def content: () -> String + def closing: () -> String + def type: () -> :regular_expression_node + | ... + def self.type: () -> :regular_expression_node + end + + # Represents a required keyword parameter to a method, block, or lambda definition. + # + # def a(b: ) + # ^^ + # end + class RequiredKeywordParameterNode < Node + include _Node + + def repeated_parameter?: () -> bool + + attr_reader name: Symbol + attr_reader name_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name, Location name_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location) -> RequiredKeywordParameterNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location } + def type: () -> :required_keyword_parameter_node + | ... + def self.type: () -> :required_keyword_parameter_node + end + + # Represents a required parameter to a method, block, or lambda definition. + # + # def a(b) + # ^ + # end + class RequiredParameterNode < Node + include _Node + + def repeated_parameter?: () -> bool + + attr_reader name: Symbol + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol name) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> RequiredParameterNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } + def type: () -> :required_parameter_node + | ... + def self.type: () -> :required_parameter_node + end + + # Represents an expression modified with a rescue. + # + # foo rescue nil + # ^^^^^^^^^^^^^^ + class RescueModifierNode < Node + include _Node + + attr_reader expression: Prism::node + attr_reader keyword_loc: Location + attr_reader rescue_expression: Prism::node + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Prism::node expression, Location keyword_loc, Prism::node rescue_expression) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?expression: Prism::node, ?keyword_loc: Location, ?rescue_expression: Prism::node) -> RescueModifierNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, expression: Prism::node, keyword_loc: Location, rescue_expression: Prism::node } + def keyword: () -> String + def type: () -> :rescue_modifier_node + | ... + def self.type: () -> :rescue_modifier_node + end + + # Represents a rescue statement. + # + # begin + # rescue Foo, *splat, Bar => ex + # foo + # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + # end + # + # `Foo, *splat, Bar` are in the `exceptions` field. `ex` is in the `reference` field. + class RescueNode < Node + include _Node + + attr_reader keyword_loc: Location + attr_reader exceptions: Array[Prism::node] + attr_reader operator_loc: Location? + attr_reader reference: LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | BackReferenceReadNode | NumberedReferenceReadNode | MissingNode | nil + attr_reader then_keyword_loc: Location? + attr_reader statements: StatementsNode? + attr_reader subsequent: RescueNode? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location keyword_loc, Array[Prism::node] exceptions, Location? operator_loc, LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | BackReferenceReadNode | NumberedReferenceReadNode | MissingNode | nil reference, Location? then_keyword_loc, StatementsNode? statements, RescueNode? subsequent) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?exceptions: Array[Prism::node], ?operator_loc: Location?, ?reference: LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | BackReferenceReadNode | NumberedReferenceReadNode | MissingNode | nil, ?then_keyword_loc: Location?, ?statements: StatementsNode?, ?subsequent: RescueNode?) -> RescueNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, keyword_loc: Location, exceptions: Array[Prism::node], operator_loc: Location?, reference: LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | BackReferenceReadNode | NumberedReferenceReadNode | MissingNode | nil, then_keyword_loc: Location?, statements: StatementsNode?, subsequent: RescueNode? } + def keyword: () -> String + def operator: () -> String? + def then_keyword: () -> String? + def type: () -> :rescue_node + | ... + def self.type: () -> :rescue_node + end + + # Represents a rest parameter to a method, block, or lambda definition. + # + # def a(*b) + # ^^ + # end + class RestParameterNode < Node + include _Node + + def repeated_parameter?: () -> bool + + attr_reader name: Symbol? + attr_reader name_loc: Location? + attr_reader operator_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Symbol? name, Location? name_loc, Location operator_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol?, ?name_loc: Location?, ?operator_loc: Location) -> RestParameterNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol?, name_loc: Location?, operator_loc: Location } + def operator: () -> String + def type: () -> :rest_parameter_node + | ... + def self.type: () -> :rest_parameter_node + end + + # Represents the use of the `retry` keyword. + # + # retry + # ^^^^^ + class RetryNode < Node + include _Node + + + def initialize: (Source source, Integer node_id, Location location, Integer flags) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> RetryNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def type: () -> :retry_node + | ... + def self.type: () -> :retry_node + end + + # Represents the use of the `return` keyword. + # + # return 1 + # ^^^^^^^^ + class ReturnNode < Node + include _Node + + attr_reader keyword_loc: Location + attr_reader arguments: ArgumentsNode? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location keyword_loc, ArgumentsNode? arguments) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?arguments: ArgumentsNode?) -> ReturnNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, keyword_loc: Location, arguments: ArgumentsNode? } + def keyword: () -> String + def type: () -> :return_node + | ... + def self.type: () -> :return_node + end + + # Represents the `self` keyword. + # + # self + # ^^^^ + class SelfNode < Node + include _Node + + + def initialize: (Source source, Integer node_id, Location location, Integer flags) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> SelfNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def type: () -> :self_node + | ... + def self.type: () -> :self_node + end + + # This node wraps a constant write to indicate that when the value is written, it should have its shareability state modified. + # + # # shareable_constant_value: literal + # C = { a: 1 } + # ^^^^^^^^^^^^ + class ShareableConstantNode < Node + include _Node + + def literal?: () -> bool + def experimental_everything?: () -> bool + def experimental_copy?: () -> bool + + attr_reader write: ConstantWriteNode | ConstantAndWriteNode | ConstantOrWriteNode | ConstantOperatorWriteNode | ConstantPathWriteNode | ConstantPathAndWriteNode | ConstantPathOrWriteNode | ConstantPathOperatorWriteNode + + def initialize: (Source source, Integer node_id, Location location, Integer flags, ConstantWriteNode | ConstantAndWriteNode | ConstantOrWriteNode | ConstantOperatorWriteNode | ConstantPathWriteNode | ConstantPathAndWriteNode | ConstantPathOrWriteNode | ConstantPathOperatorWriteNode write) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?write: ConstantWriteNode | ConstantAndWriteNode | ConstantOrWriteNode | ConstantOperatorWriteNode | ConstantPathWriteNode | ConstantPathAndWriteNode | ConstantPathOrWriteNode | ConstantPathOperatorWriteNode) -> ShareableConstantNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, write: ConstantWriteNode | ConstantAndWriteNode | ConstantOrWriteNode | ConstantOperatorWriteNode | ConstantPathWriteNode | ConstantPathAndWriteNode | ConstantPathOrWriteNode | ConstantPathOperatorWriteNode } + def type: () -> :shareable_constant_node + | ... + def self.type: () -> :shareable_constant_node + end + + # Represents a singleton class declaration involving the `class` keyword. + # + # class << self end + # ^^^^^^^^^^^^^^^^^ + class SingletonClassNode < Node + include _Node + + attr_reader locals: Array[Symbol] + attr_reader class_keyword_loc: Location + attr_reader operator_loc: Location + attr_reader expression: Prism::node + attr_reader body: StatementsNode | BeginNode | nil + attr_reader end_keyword_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Array[Symbol] locals, Location class_keyword_loc, Location operator_loc, Prism::node expression, StatementsNode | BeginNode | nil body, Location end_keyword_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?locals: Array[Symbol], ?class_keyword_loc: Location, ?operator_loc: Location, ?expression: Prism::node, ?body: StatementsNode | BeginNode | nil, ?end_keyword_loc: Location) -> SingletonClassNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, locals: Array[Symbol], class_keyword_loc: Location, operator_loc: Location, expression: Prism::node, body: StatementsNode | BeginNode | nil, end_keyword_loc: Location } + def class_keyword: () -> String + def operator: () -> String + def end_keyword: () -> String + def type: () -> :singleton_class_node + | ... + def self.type: () -> :singleton_class_node + end + + # Represents the use of the `__ENCODING__` keyword. + # + # __ENCODING__ + # ^^^^^^^^^^^^ + class SourceEncodingNode < Node + include _Node + + + def initialize: (Source source, Integer node_id, Location location, Integer flags) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> SourceEncodingNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def type: () -> :source_encoding_node + | ... + def self.type: () -> :source_encoding_node + end + + # Represents the use of the `__FILE__` keyword. + # + # __FILE__ + # ^^^^^^^^ + class SourceFileNode < Node + include _Node + + def forced_utf8_encoding?: () -> bool + def forced_binary_encoding?: () -> bool + def frozen?: () -> bool + def mutable?: () -> bool + + attr_reader filepath: String + + def initialize: (Source source, Integer node_id, Location location, Integer flags, String filepath) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?filepath: String) -> SourceFileNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, filepath: String } + def type: () -> :source_file_node + | ... + def self.type: () -> :source_file_node + end + + # Represents the use of the `__LINE__` keyword. + # + # __LINE__ + # ^^^^^^^^ + class SourceLineNode < Node + include _Node + + + def initialize: (Source source, Integer node_id, Location location, Integer flags) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> SourceLineNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def type: () -> :source_line_node + | ... + def self.type: () -> :source_line_node + end + + # Represents the use of the splat operator. + # + # [*a] + # ^^ + class SplatNode < Node + include _Node + + attr_reader operator_loc: Location + attr_reader expression: Prism::node? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location operator_loc, Prism::node? expression) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?operator_loc: Location, ?expression: Prism::node?) -> SplatNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, operator_loc: Location, expression: Prism::node? } + def operator: () -> String + def type: () -> :splat_node + | ... + def self.type: () -> :splat_node + end + + # Represents a set of statements contained within some scope. + # + # foo; bar; baz + # ^^^^^^^^^^^^^ + class StatementsNode < Node + include _Node + + attr_reader body: Array[Prism::node] + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Array[Prism::node] body) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?body: Array[Prism::node]) -> StatementsNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, body: Array[Prism::node] } + def type: () -> :statements_node + | ... + def self.type: () -> :statements_node + end + + # Represents a string literal, a string contained within a `%w` list, or plain string content within an interpolated string. + # + # "foo" + # ^^^^^ + # + # %w[foo] + # ^^^ + # + # "foo #{bar} baz" + # ^^^^ ^^^^ + class StringNode < Node + include _Node + + def forced_utf8_encoding?: () -> bool + def forced_binary_encoding?: () -> bool + def frozen?: () -> bool + def mutable?: () -> bool + + attr_reader opening_loc: Location? + attr_reader content_loc: Location + attr_reader closing_loc: Location? + attr_reader unescaped: String + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location? opening_loc, Location content_loc, Location? closing_loc, String unescaped) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location?, ?content_loc: Location, ?closing_loc: Location?, ?unescaped: String) -> StringNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location?, content_loc: Location, closing_loc: Location?, unescaped: String } + def opening: () -> String? + def content: () -> String + def closing: () -> String? + def type: () -> :string_node + | ... + def self.type: () -> :string_node + end + + # Represents the use of the `super` keyword with parentheses or arguments. + # + # super() + # ^^^^^^^ + # + # super foo, bar + # ^^^^^^^^^^^^^^ + class SuperNode < Node + include _Node + + attr_reader keyword_loc: Location + attr_reader lparen_loc: Location? + attr_reader arguments: ArgumentsNode? + attr_reader rparen_loc: Location? + attr_reader block: BlockNode | BlockArgumentNode | nil + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location keyword_loc, Location? lparen_loc, ArgumentsNode? arguments, Location? rparen_loc, BlockNode | BlockArgumentNode | nil block) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?lparen_loc: Location?, ?arguments: ArgumentsNode?, ?rparen_loc: Location?, ?block: BlockNode | BlockArgumentNode | nil) -> SuperNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, keyword_loc: Location, lparen_loc: Location?, arguments: ArgumentsNode?, rparen_loc: Location?, block: BlockNode | BlockArgumentNode | nil } + def keyword: () -> String + def lparen: () -> String? + def rparen: () -> String? + def type: () -> :super_node + | ... + def self.type: () -> :super_node + end + + # Represents a symbol literal or a symbol contained within a `%i` list. + # + # :foo + # ^^^^ + # + # %i[foo] + # ^^^ + class SymbolNode < Node + include _Node + + def forced_utf8_encoding?: () -> bool + def forced_binary_encoding?: () -> bool + def forced_us_ascii_encoding?: () -> bool + + attr_reader opening_loc: Location? + attr_reader value_loc: Location? + attr_reader closing_loc: Location? + attr_reader unescaped: String + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location? opening_loc, Location? value_loc, Location? closing_loc, String unescaped) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location?, ?value_loc: Location?, ?closing_loc: Location?, ?unescaped: String) -> SymbolNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location?, value_loc: Location?, closing_loc: Location?, unescaped: String } + def opening: () -> String? + def value: () -> String? + def closing: () -> String? + def type: () -> :symbol_node + | ... + def self.type: () -> :symbol_node + end + + # Represents the use of the literal `true` keyword. + # + # true + # ^^^^ + class TrueNode < Node + include _Node + + + def initialize: (Source source, Integer node_id, Location location, Integer flags) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> TrueNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } + def type: () -> :true_node + | ... + def self.type: () -> :true_node + end + + # Represents the use of the `undef` keyword. + # + # undef :foo, :bar, :baz + # ^^^^^^^^^^^^^^^^^^^^^^ + class UndefNode < Node + include _Node + + attr_reader names: Array[SymbolNode | InterpolatedSymbolNode] + attr_reader keyword_loc: Location + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Array[SymbolNode | InterpolatedSymbolNode] names, Location keyword_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?names: Array[SymbolNode | InterpolatedSymbolNode], ?keyword_loc: Location) -> UndefNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, names: Array[SymbolNode | InterpolatedSymbolNode], keyword_loc: Location } + def keyword: () -> String + def type: () -> :undef_node + | ... + def self.type: () -> :undef_node + end + + # Represents the use of the `unless` keyword, either in the block form or the modifier form. + # + # bar unless foo + # ^^^^^^^^^^^^^^ + # + # unless foo then bar end + # ^^^^^^^^^^^^^^^^^^^^^^^ + class UnlessNode < Node + include _Node + + attr_reader keyword_loc: Location + attr_reader predicate: Prism::node + attr_reader then_keyword_loc: Location? + attr_reader statements: StatementsNode? + attr_reader else_clause: ElseNode? + attr_reader end_keyword_loc: Location? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location keyword_loc, Prism::node predicate, Location? then_keyword_loc, StatementsNode? statements, ElseNode? else_clause, Location? end_keyword_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?predicate: Prism::node, ?then_keyword_loc: Location?, ?statements: StatementsNode?, ?else_clause: ElseNode?, ?end_keyword_loc: Location?) -> UnlessNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, keyword_loc: Location, predicate: Prism::node, then_keyword_loc: Location?, statements: StatementsNode?, else_clause: ElseNode?, end_keyword_loc: Location? } + def keyword: () -> String + def then_keyword: () -> String? + def end_keyword: () -> String? + def type: () -> :unless_node + | ... + def self.type: () -> :unless_node + end + + # Represents the use of the `until` keyword, either in the block form or the modifier form. + # + # bar until foo + # ^^^^^^^^^^^^^ + # + # until foo do bar end + # ^^^^^^^^^^^^^^^^^^^^ + class UntilNode < Node + include _Node + + def begin_modifier?: () -> bool + + attr_reader keyword_loc: Location + attr_reader do_keyword_loc: Location? + attr_reader closing_loc: Location? + attr_reader predicate: Prism::node + attr_reader statements: StatementsNode? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location keyword_loc, Location? do_keyword_loc, Location? closing_loc, Prism::node predicate, StatementsNode? statements) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?do_keyword_loc: Location?, ?closing_loc: Location?, ?predicate: Prism::node, ?statements: StatementsNode?) -> UntilNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, keyword_loc: Location, do_keyword_loc: Location?, closing_loc: Location?, predicate: Prism::node, statements: StatementsNode? } + def keyword: () -> String + def do_keyword: () -> String? + def closing: () -> String? + def type: () -> :until_node + | ... + def self.type: () -> :until_node + end + + # Represents the use of the `when` keyword within a case statement. + # + # case true + # when true + # ^^^^^^^^^ + # end + class WhenNode < Node + include _Node + + attr_reader keyword_loc: Location + attr_reader conditions: Array[Prism::node] + attr_reader then_keyword_loc: Location? + attr_reader statements: StatementsNode? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location keyword_loc, Array[Prism::node] conditions, Location? then_keyword_loc, StatementsNode? statements) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?conditions: Array[Prism::node], ?then_keyword_loc: Location?, ?statements: StatementsNode?) -> WhenNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, keyword_loc: Location, conditions: Array[Prism::node], then_keyword_loc: Location?, statements: StatementsNode? } + def keyword: () -> String + def then_keyword: () -> String? + def type: () -> :when_node + | ... + def self.type: () -> :when_node + end + + # Represents the use of the `while` keyword, either in the block form or the modifier form. + # + # bar while foo + # ^^^^^^^^^^^^^ + # + # while foo do bar end + # ^^^^^^^^^^^^^^^^^^^^ + class WhileNode < Node + include _Node + + def begin_modifier?: () -> bool + + attr_reader keyword_loc: Location + attr_reader do_keyword_loc: Location? + attr_reader closing_loc: Location? + attr_reader predicate: Prism::node + attr_reader statements: StatementsNode? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location keyword_loc, Location? do_keyword_loc, Location? closing_loc, Prism::node predicate, StatementsNode? statements) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?do_keyword_loc: Location?, ?closing_loc: Location?, ?predicate: Prism::node, ?statements: StatementsNode?) -> WhileNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, keyword_loc: Location, do_keyword_loc: Location?, closing_loc: Location?, predicate: Prism::node, statements: StatementsNode? } + def keyword: () -> String + def do_keyword: () -> String? + def closing: () -> String? + def type: () -> :while_node + | ... + def self.type: () -> :while_node + end + + # Represents an xstring literal with no interpolation. + # + # `foo` + # ^^^^^ + class XStringNode < Node + include _Node + + def forced_utf8_encoding?: () -> bool + def forced_binary_encoding?: () -> bool + + attr_reader opening_loc: Location + attr_reader content_loc: Location + attr_reader closing_loc: Location + attr_reader unescaped: String + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location opening_loc, Location content_loc, Location closing_loc, String unescaped) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?content_loc: Location, ?closing_loc: Location, ?unescaped: String) -> XStringNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location, content_loc: Location, closing_loc: Location, unescaped: String } + def opening: () -> String + def content: () -> String + def closing: () -> String + def type: () -> :x_string_node + | ... + def self.type: () -> :x_string_node + end + + # Represents the use of the `yield` keyword. + # + # yield 1 + # ^^^^^^^ + class YieldNode < Node + include _Node + + attr_reader keyword_loc: Location + attr_reader lparen_loc: Location? + attr_reader arguments: ArgumentsNode? + attr_reader rparen_loc: Location? + + def initialize: (Source source, Integer node_id, Location location, Integer flags, Location keyword_loc, Location? lparen_loc, ArgumentsNode? arguments, Location? rparen_loc) -> void + def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?lparen_loc: Location?, ?arguments: ArgumentsNode?, ?rparen_loc: Location?) -> YieldNode + def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, keyword_loc: Location, lparen_loc: Location?, arguments: ArgumentsNode?, rparen_loc: Location? } + def keyword: () -> String + def lparen: () -> String? + def rparen: () -> String? + def type: () -> :yield_node + | ... + def self.type: () -> :yield_node + end + + # Flags for arguments nodes. + module ArgumentsNodeFlags + # if the arguments contain forwarding + CONTAINS_FORWARDING: Integer + # if the arguments contain keywords + CONTAINS_KEYWORDS: Integer + # if the arguments contain a keyword splat + CONTAINS_KEYWORD_SPLAT: Integer + # if the arguments contain a splat + CONTAINS_SPLAT: Integer + # if the arguments contain multiple splats + CONTAINS_MULTIPLE_SPLATS: Integer + end + + # Flags for array nodes. + module ArrayNodeFlags + # if array contains splat nodes + CONTAINS_SPLAT: Integer + end + + # Flags for call nodes. + module CallNodeFlags + # &. operator + SAFE_NAVIGATION: Integer + # a call that could have been a local variable + VARIABLE_CALL: Integer + # a call that is an attribute write, so the value being written should be returned + ATTRIBUTE_WRITE: Integer + # a call that ignores method visibility + IGNORE_VISIBILITY: Integer + end + + # Flags for nodes that have unescaped content. + module EncodingFlags + # internal bytes forced the encoding to UTF-8 + FORCED_UTF8_ENCODING: Integer + # internal bytes forced the encoding to binary + FORCED_BINARY_ENCODING: Integer + end + + # Flags for integer nodes that correspond to the base of the integer. + module IntegerBaseFlags + # 0b prefix + BINARY: Integer + # 0d or no prefix + DECIMAL: Integer + # 0o or 0 prefix + OCTAL: Integer + # 0x prefix + HEXADECIMAL: Integer + end + + # Flags for interpolated string nodes that indicated mutability if they are also marked as literals. + module InterpolatedStringNodeFlags + # frozen by virtue of a `frozen_string_literal: true` comment or `--enable-frozen-string-literal`; only for adjacent string literals like `'a' 'b'` + FROZEN: Integer + # mutable by virtue of a `frozen_string_literal: false` comment or `--disable-frozen-string-literal`; only for adjacent string literals like `'a' 'b'` + MUTABLE: Integer + end + + # Flags for keyword hash nodes. + module KeywordHashNodeFlags + # a keyword hash which only has `AssocNode` elements all with symbol keys, which means the elements can be treated as keyword arguments + SYMBOL_KEYS: Integer + end + + # Flags for while and until loop nodes. + module LoopFlags + # a loop after a begin statement, so the body is executed first before the condition + BEGIN_MODIFIER: Integer + end + + # Flags for parameter nodes. + module ParameterFlags + # a parameter name that has been repeated in the method signature + REPEATED_PARAMETER: Integer + end + + # Flags for parentheses nodes. + module ParenthesesNodeFlags + # parentheses that contain multiple potentially void statements + MULTIPLE_STATEMENTS: Integer + end + + # Flags for range and flip-flop nodes. + module RangeFlags + # ... operator + EXCLUDE_END: Integer + end + + # Flags for regular expression and match last line nodes. + module RegularExpressionFlags + # i - ignores the case of characters when matching + IGNORE_CASE: Integer + # x - ignores whitespace and allows comments in regular expressions + EXTENDED: Integer + # m - allows $ to match the end of lines within strings + MULTI_LINE: Integer + # o - only interpolates values into the regular expression once + ONCE: Integer + # e - forces the EUC-JP encoding + EUC_JP: Integer + # n - forces the ASCII-8BIT encoding + ASCII_8BIT: Integer + # s - forces the Windows-31J encoding + WINDOWS_31J: Integer + # u - forces the UTF-8 encoding + UTF_8: Integer + # internal bytes forced the encoding to UTF-8 + FORCED_UTF8_ENCODING: Integer + # internal bytes forced the encoding to binary + FORCED_BINARY_ENCODING: Integer + # internal bytes forced the encoding to US-ASCII + FORCED_US_ASCII_ENCODING: Integer + end + + # Flags for shareable constant nodes. + module ShareableConstantNodeFlags + # constant writes that should be modified with shareable constant value literal + LITERAL: Integer + # constant writes that should be modified with shareable constant value experimental everything + EXPERIMENTAL_EVERYTHING: Integer + # constant writes that should be modified with shareable constant value experimental copy + EXPERIMENTAL_COPY: Integer + end + + # Flags for string nodes. + module StringFlags + # internal bytes forced the encoding to UTF-8 + FORCED_UTF8_ENCODING: Integer + # internal bytes forced the encoding to binary + FORCED_BINARY_ENCODING: Integer + # frozen by virtue of a `frozen_string_literal: true` comment or `--enable-frozen-string-literal` + FROZEN: Integer + # mutable by virtue of a `frozen_string_literal: false` comment or `--disable-frozen-string-literal` + MUTABLE: Integer + end + + # Flags for symbol nodes. + module SymbolFlags + # internal bytes forced the encoding to UTF-8 + FORCED_UTF8_ENCODING: Integer + # internal bytes forced the encoding to binary + FORCED_BINARY_ENCODING: Integer + # internal bytes forced the encoding to US-ASCII + FORCED_US_ASCII_ENCODING: Integer + end + + # The flags that are common to all nodes. + module NodeFlags + NEWLINE: Integer + STATIC_LITERAL: Integer + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/node_ext.rbs b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/node_ext.rbs new file mode 100644 index 00000000..d485092f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/node_ext.rbs @@ -0,0 +1,82 @@ +module Prism + class InterpolatedMatchLastLineNode < Node + # Returns a numeric value that represents the flags that were used to create + # the regular expression. + def options: () -> Integer + end + + class InterpolatedRegularExpressionNode < Node + # Returns a numeric value that represents the flags that were used to create + # the regular expression. + def options: () -> Integer + end + + class MatchLastLineNode < Node + # Returns a numeric value that represents the flags that were used to create + # the regular expression. + def options: () -> Integer + end + + class RegularExpressionNode < Node + # Returns a numeric value that represents the flags that were used to create + # the regular expression. + def options: () -> Integer + end + + class InterpolatedStringNode < Node + # Returns true if this node was represented as a heredoc in the source code. + def heredoc?: () -> bool? + end + + class InterpolatedXStringNode < Node + # Returns true if this node was represented as a heredoc in the source code. + def heredoc?: () -> bool? + end + + class StringNode < Node + # Returns true if this node was represented as a heredoc in the source code. + def heredoc?: () -> bool? + end + + class XStringNode < Node + # Returns true if this node was represented as a heredoc in the source code. + def heredoc?: () -> bool? + end + + class ImaginaryNode < Node + def value: () -> Complex + end + + class RationalNode < Node + def value: () -> Rational + end + + class ConstantReadNode < Node + def full_name_parts: () -> [Symbol] + def full_name: () -> String + end + + class ConstantPathNode < Node + class DynamicPartsInConstantPathError < StandardError + end + + class MissingNodesInConstantPathError < StandardError + end + + def full_name_parts: () -> Array[Symbol] + def full_name: () -> String + end + + class ConstantPathTargetNode < Node + def full_name_parts: () -> Array[Symbol] + def full_name: () -> String + end + + class ParametersNode < Node + def signature: () -> Array[[Symbol, Symbol] | [Symbol]] + end + + class CallNode < Node + def full_message_loc: () -> Location? + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/pack.rbs b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/pack.rbs new file mode 100644 index 00000000..acbc92b6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/pack.rbs @@ -0,0 +1,43 @@ +module Prism + module Pack + type variant = :pack | :unpack + + def self.parse: (Symbol version, variant variant, String source) -> Format + + class Directive + type directive_type = :SPACE | :COMMENT | :INTEGER | :UTF8 | :BER | :FLOAT | :STRING_SPACE_PADDED | + :STRING_NULL_PADDED | :STRING_NULL_TERMINATED | :STRING_MSB | :STRING_LSB | + :STRING_HEX_HIGH | :STRING_HEX_LOW | :STRING_UU | :STRING_MIME | :STRING_BASE64 | + :STRING_FIXED | :STRING_POINTER | :MOVE | :BACK | :NULL + + type signness = :UNSIGNED | :SIGNED | :SIGNED_NA + + type endianness = :AGNOSTIC_ENDIAN | :LITTLE_ENDIAN | :BIG_ENDIAN | :NATIVE_ENDIAN | :ENDIAN_NA + + type size = :SIZE_SHORT | :SIZE_INT | :SIZE_LONG | :SIZE_LONG_LONG | :SIZE_8 | :SIZE_16 | :SIZE_32 | + :SIZE_64 | :SIZE_P | :SIZE_NA + + type length_type = :LENGTH_FIXED | :LENGTH_MAX | :LENGTH_RELATIVE | :LENGTH_NA + + + attr_reader version: Symbol + attr_reader variant: variant + attr_reader source: String + attr_reader type: directive_type + attr_reader signed: signness + attr_reader endian: endianness + attr_reader size: size + attr_reader length_type: length_type + attr_reader length: Integer + + def describe: () -> String + end + + class Format + attr_reader directives: Array[Directive] + attr_reader encoding: Encoding + + def describe: () -> String + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/parse_result.rbs b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/parse_result.rbs new file mode 100644 index 00000000..8dea016a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/parse_result.rbs @@ -0,0 +1,192 @@ +module Prism + interface _CodeUnitsCache + def []: (Integer byte_offset) -> Integer + end + + class Source + attr_reader source: String + attr_reader start_line: Integer + attr_reader offsets: Array[Integer] + + def initialize: (String source, ?Integer start_line, ?Array[Integer] offsets) -> void + def replace_start_line: (Integer start_line) -> void + def replace_offsets: (Array[Integer] offsets) -> void + def encoding: () -> Encoding + def lines: () -> Array[String] + def slice: (Integer byte_offset, Integer length) -> String + def line: (Integer byte_offset) -> Integer + def line_start: (Integer byte_offset) -> Integer + def line_end: (Integer byte_offset) -> Integer + def line_offset: (Integer byte_offset) -> Integer + def column: (Integer byte_offset) -> Integer + def character_offset: (Integer byte_offset) -> Integer + def character_column: (Integer byte_offset) -> Integer + def code_units_offset: (Integer byte_offset, Encoding encoding) -> Integer + def code_units_cache: (Encoding encoding) -> _CodeUnitsCache + def code_units_column: (Integer byte_offset, Encoding encoding) -> Integer + + def self.for: (String source) -> Source + end + + class CodeUnitsCache + def initialize: (String source, Encoding encoding) -> void + def []: (Integer byte_offset) -> Integer + end + + class ASCIISource < Source + def character_offset: (Integer byte_offset) -> Integer + def character_column: (Integer byte_offset) -> Integer + def code_units_offset: (Integer byte_offset, Encoding encoding) -> Integer + def code_units_cache: (Encoding encoding) -> _CodeUnitsCache + def code_units_column: (Integer byte_offset, Encoding encoding) -> Integer + end + + class Location + attr_reader source: Source + attr_reader start_offset: Integer + attr_reader length: Integer + + def initialize: (Source source, Integer start_offset, Integer length) -> void + def leading_comments: () -> Array[comment] + def leading_comment: (comment) -> void + def trailing_comments: () -> Array[comment] + def trailing_comment: (comment) -> void + def comments: () -> Array[comment] + def copy: (?source: Source, ?start_offset: Integer, ?length: Integer) -> Location + def chop: () -> Location + def source_lines: () -> Array[String] + def slice: () -> String + def slice_lines: () -> String + def start_character_offset: () -> Integer + def start_code_units_offset: (Encoding encoding) -> Integer + def cached_start_code_units_offset: (_CodeUnitsCache cache) -> Integer + def end_offset: () -> Integer + def end_character_offset: () -> Integer + def end_code_units_offset: (Encoding encoding) -> Integer + def cached_end_code_units_offset: (_CodeUnitsCache cache) -> Integer + def start_line: () -> Integer + def start_line_slice: () -> String + def end_line: () -> Integer + def start_column: () -> Integer + def start_character_column: () -> Integer + def start_code_units_column: (Encoding encoding) -> Integer + def cached_start_code_units_column: (_CodeUnitsCache cache) -> Integer + def end_column: () -> Integer + def end_character_column: () -> Integer + def end_code_units_column: (Encoding encoding) -> Integer + def cached_end_code_units_column: (_CodeUnitsCache cache) -> Integer + def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped] + def pretty_print: (untyped q) -> untyped + def join: (Location other) -> Location + def adjoin: (String string) -> Location + end + + class Comment + attr_reader location: Location + + def initialize: (Location location) -> void + def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped] + def slice: () -> String + end + + interface _Comment + def trailing?: () -> bool + end + + type comment = Comment & _Comment + + class InlineComment < Comment + include _Comment + end + + class EmbDocComment < Comment + include _Comment + end + + class MagicComment + attr_reader key_loc: Location + attr_reader value_loc: Location + + def initialize: (Location key_loc, Location value_loc) -> void + + def key: () -> String + def value: () -> String + + def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped] + end + + class ParseError + attr_reader type: Symbol + attr_reader message: String + attr_reader location: Location + attr_reader level: Symbol + + def initialize: (Symbol type, String message, Location location, Symbol level) -> void + def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped] + end + + class ParseWarning + attr_reader type: Symbol + attr_reader message: String + attr_reader location: Location + attr_reader level: Symbol + + def initialize: (Symbol type, String message, Location location, Symbol level) -> void + def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped] + end + + class Result + attr_reader comments: Array[comment] + attr_reader magic_comments: Array[MagicComment] + attr_reader data_loc: Location? + attr_reader errors: Array[ParseError] + attr_reader warnings: Array[ParseWarning] + attr_reader source: Source + + def initialize: (Array[comment] comments, Array[MagicComment] magic_comments, Location? data_loc, Array[ParseError] errors, Array[ParseWarning] warnings, Source source) -> void + def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped] + def success?: () -> bool + def failure?: () -> bool + def code_units_cache: (Encoding encoding) -> _CodeUnitsCache + end + + class ParseResult < Result + attr_reader value: ProgramNode + + def initialize: (ProgramNode value, Array[comment] comments, Array[MagicComment] magic_comments, Location? data_loc, Array[ParseError] errors, Array[ParseWarning] warnings, Source source) -> void + def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped] + end + + class LexResult < Result + attr_reader value: Array[[Token, Integer]] + + def initialize: (Array[[Token, Integer]] value, Array[comment] comments, Array[MagicComment] magic_comments, Location? data_loc, Array[ParseError] errors, Array[ParseWarning] warnings, Source source) -> void + def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped] + end + + class ParseLexResult < Result + attr_reader value: [ProgramNode, Array[[Token, Integer]]] + + def initialize: ([ProgramNode, Array[[Token, Integer]]] value, Array[comment] comments, Array[MagicComment] magic_comments, Location? data_loc, Array[ParseError] errors, Array[ParseWarning] warnings, Source source) -> void + def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped] + end + + class Token + attr_reader source: Source + attr_reader type: Symbol + attr_reader value: String + attr_reader location: Location + + def initialize: (Source source, Symbol type, String value, Location location) -> void + def deconstruct_keys: (Array[Symbol]? keys) -> Hash[Symbol, untyped] + def pretty_print: (untyped q) -> untyped + def ==: (untyped other) -> bool + end + + class Scope + attr_reader locals: Array[Symbol] + attr_reader forwarding: Array[Symbol] + + def initialize: (Array[Symbol] locals, Array[Symbol] forwarding) -> void + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/pattern.rbs b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/pattern.rbs new file mode 100644 index 00000000..a70293e1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/pattern.rbs @@ -0,0 +1,13 @@ +module Prism + class Pattern + class CompilationError < StandardError + end + + attr_reader query: String + + def initialize: (String query) -> void + def compile: () -> Proc + def scan: (Prism::node root) { (Prism::node) -> void } -> void + | (Prism::node root) -> ::Enumerator[Prism::node, void] + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/reflection.rbs b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/reflection.rbs new file mode 100644 index 00000000..caa612c4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/reflection.rbs @@ -0,0 +1,50 @@ +module Prism + module Reflection + class Field + attr_reader name: Symbol + + def initialize: (Symbol name) -> void + end + + class NodeField < Field + end + + class OptionalNodeField < Field + end + + class NodeListField < Field + end + + class ConstantField < Field + end + + class OptionalConstantField < Field + end + + class ConstantListField < Field + end + + class StringField < Field + end + + class LocationField < Field + end + + class OptionalLocationField < Field + end + + class IntegerField < Field + end + + class FloatField < Field + end + + class FlagsField < Field + attr_reader flags: Array[Symbol] + + def initialize: (Symbol name, Array[Symbol] flags) -> void + end + + def self.fields_for: (node_singleton node) -> Array[Field] + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/relocation.rbs b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/relocation.rbs new file mode 100644 index 00000000..7f5637d5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/relocation.rbs @@ -0,0 +1,185 @@ +module Prism + module Relocation + interface _Value + def start_line: () -> Integer + def end_line: () -> Integer + def start_offset: () -> Integer + def end_offset: () -> Integer + def start_character_offset: () -> Integer + def end_character_offset: () -> Integer + def cached_start_code_units_offset: (_CodeUnitsCache cache) -> Integer + def cached_end_code_units_offset: (_CodeUnitsCache cache) -> Integer + def start_column: () -> Integer + def end_column: () -> Integer + def start_character_column: () -> Integer + def end_character_column: () -> Integer + def cached_start_code_units_column: (_CodeUnitsCache cache) -> Integer + def cached_end_code_units_column: (_CodeUnitsCache cache) -> Integer + def leading_comments: () -> Array[Comment] + def trailing_comments: () -> Array[Comment] + end + + interface _Field + def fields: (_Value value) -> entry_values + end + + type entry_value = untyped + type entry_values = Hash[Symbol, entry_value] + + class Entry + class MissingValueError < StandardError + end + + def initialize: (Repository repository) -> void + + def filepath: () -> String + + def start_line: () -> Integer + def end_line: () -> Integer + + def start_offset: () -> Integer + def end_offset: () -> Integer + def start_character_offset: () -> Integer + def end_character_offset: () -> Integer + def start_code_units_offset: () -> Integer + def end_code_units_offset: () -> Integer + + def start_column: () -> Integer + def end_column: () -> Integer + def start_character_column: () -> Integer + def end_character_column: () -> Integer + def start_code_units_column: () -> Integer + def end_code_units_column: () -> Integer + + def leading_comments: () -> Array[CommentsField::Comment] + def trailing_comments: () -> Array[CommentsField::Comment] + def comments: () -> Array[CommentsField::Comment] + + private + + def fetch_value: (Symbol name) -> entry_value + def values: () -> entry_values + end + + class Source + attr_reader value: untyped + + def initialize: (untyped value) -> void + + def result: () -> ParseResult + def code_units_cache: (Encoding encoding) -> _CodeUnitsCache + end + + class SourceFilepath < Source + def result: () -> ParseResult + end + + class SourceString < Source + def result: () -> ParseResult + end + + class FilepathField + attr_reader value: String + + def initialize: (String value) -> void + + def fields: (_Value value) -> entry_values + end + + class LinesField + def fields: (_Value value) -> entry_values + end + + class OffsetsField + def fields: (_Value value) -> entry_values + end + + class CharacterOffsetsField + def fields: (_Value value) -> entry_values + end + + class CodeUnitOffsetsField + attr_reader repository: Repository + attr_reader encoding: Encoding + + def initialize: (Repository repository, Encoding encoding) -> void + def fields: (_Value value) -> entry_values + + private + + def cache: () -> _CodeUnitsCache + end + + class ColumnsField + def fields: (_Value value) -> entry_values + end + + class CharacterColumnsField + def fields: (_Value value) -> entry_values + end + + class CodeUnitColumnsField + attr_reader repository: Repository + attr_reader encoding: Encoding + + def initialize: (Repository repository, Encoding encoding) -> void + def fields: (_Value value) -> entry_values + + private + + def cache: () -> _CodeUnitsCache + end + + class CommentsField + class Comment + attr_reader slice: String + + def initialize: (String slice) -> void + end + + private + + def comments: (entry_value value) -> Array[Comment] + end + + class LeadingCommentsField < CommentsField + def fields: (_Value value) -> entry_values + end + + class TrailingCommentsField < CommentsField + def fields: (_Value value) -> entry_values + end + + class Repository + class ConfigurationError < StandardError + end + + attr_reader source: Source + attr_reader fields: Hash[Symbol, _Field] + attr_reader entries: Hash[Integer, Hash[Symbol, Entry]] + + def initialize: (Source source) -> void + + def code_units_cache: (Encoding encoding) -> _CodeUnitsCache + + def filepath: () -> self + def lines: () -> self + def offsets: () -> self + def character_offsets: () -> self + def code_unit_offsets: (Encoding encoding) -> self + def columns: () -> self + def character_columns: () -> self + def code_unit_columns: (Encoding encoding) -> self + def leading_comments: () -> self + def trailing_comments: () -> self + def comments: () -> self + + private + + def field: (Symbol name, _Field) -> self + end + + def self.filepath: (String value) -> Repository + def self.string: (String value) -> Repository + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/serialize.rbs b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/serialize.rbs new file mode 100644 index 00000000..71a7c5c1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/serialize.rbs @@ -0,0 +1,8 @@ +module Prism + module Serialize + def self.load_parse: (String, String, bool) -> ParseResult + def self.load_lex: (String, String, bool) -> LexResult + def self.load_parse_comments: (String, String, bool) -> Array[comment] + def self.load_parse_lex: (String, String, bool) -> ParseLexResult + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/string_query.rbs b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/string_query.rbs new file mode 100644 index 00000000..098746e5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/string_query.rbs @@ -0,0 +1,11 @@ +module Prism + class StringQuery + attr_reader string: String + + def initialize: (String string) -> void + + def local?: () -> bool + def constant?: () -> bool + def method_name?: () -> bool + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/visitor.rbs b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/visitor.rbs new file mode 100644 index 00000000..0aa12dc6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/sig/prism/visitor.rbs @@ -0,0 +1,169 @@ +# This file is generated by the templates/template.rb script and should not be +# modified manually. See templates/sig/prism/visitor.rbs.erb +# if you are looking to modify the template + +module Prism + class BasicVisitor + def visit: (Prism::node?) -> void + def visit_all: (Array[Prism::node?]) -> void + def visit_child_nodes: (Prism::node) -> void + end + + interface _Visitor + def visit_alias_global_variable_node: (AliasGlobalVariableNode) -> void + def visit_alias_method_node: (AliasMethodNode) -> void + def visit_alternation_pattern_node: (AlternationPatternNode) -> void + def visit_and_node: (AndNode) -> void + def visit_arguments_node: (ArgumentsNode) -> void + def visit_array_node: (ArrayNode) -> void + def visit_array_pattern_node: (ArrayPatternNode) -> void + def visit_assoc_node: (AssocNode) -> void + def visit_assoc_splat_node: (AssocSplatNode) -> void + def visit_back_reference_read_node: (BackReferenceReadNode) -> void + def visit_begin_node: (BeginNode) -> void + def visit_block_argument_node: (BlockArgumentNode) -> void + def visit_block_local_variable_node: (BlockLocalVariableNode) -> void + def visit_block_node: (BlockNode) -> void + def visit_block_parameter_node: (BlockParameterNode) -> void + def visit_block_parameters_node: (BlockParametersNode) -> void + def visit_break_node: (BreakNode) -> void + def visit_call_and_write_node: (CallAndWriteNode) -> void + def visit_call_node: (CallNode) -> void + def visit_call_operator_write_node: (CallOperatorWriteNode) -> void + def visit_call_or_write_node: (CallOrWriteNode) -> void + def visit_call_target_node: (CallTargetNode) -> void + def visit_capture_pattern_node: (CapturePatternNode) -> void + def visit_case_match_node: (CaseMatchNode) -> void + def visit_case_node: (CaseNode) -> void + def visit_class_node: (ClassNode) -> void + def visit_class_variable_and_write_node: (ClassVariableAndWriteNode) -> void + def visit_class_variable_operator_write_node: (ClassVariableOperatorWriteNode) -> void + def visit_class_variable_or_write_node: (ClassVariableOrWriteNode) -> void + def visit_class_variable_read_node: (ClassVariableReadNode) -> void + def visit_class_variable_target_node: (ClassVariableTargetNode) -> void + def visit_class_variable_write_node: (ClassVariableWriteNode) -> void + def visit_constant_and_write_node: (ConstantAndWriteNode) -> void + def visit_constant_operator_write_node: (ConstantOperatorWriteNode) -> void + def visit_constant_or_write_node: (ConstantOrWriteNode) -> void + def visit_constant_path_and_write_node: (ConstantPathAndWriteNode) -> void + def visit_constant_path_node: (ConstantPathNode) -> void + def visit_constant_path_operator_write_node: (ConstantPathOperatorWriteNode) -> void + def visit_constant_path_or_write_node: (ConstantPathOrWriteNode) -> void + def visit_constant_path_target_node: (ConstantPathTargetNode) -> void + def visit_constant_path_write_node: (ConstantPathWriteNode) -> void + def visit_constant_read_node: (ConstantReadNode) -> void + def visit_constant_target_node: (ConstantTargetNode) -> void + def visit_constant_write_node: (ConstantWriteNode) -> void + def visit_def_node: (DefNode) -> void + def visit_defined_node: (DefinedNode) -> void + def visit_else_node: (ElseNode) -> void + def visit_embedded_statements_node: (EmbeddedStatementsNode) -> void + def visit_embedded_variable_node: (EmbeddedVariableNode) -> void + def visit_ensure_node: (EnsureNode) -> void + def visit_false_node: (FalseNode) -> void + def visit_find_pattern_node: (FindPatternNode) -> void + def visit_flip_flop_node: (FlipFlopNode) -> void + def visit_float_node: (FloatNode) -> void + def visit_for_node: (ForNode) -> void + def visit_forwarding_arguments_node: (ForwardingArgumentsNode) -> void + def visit_forwarding_parameter_node: (ForwardingParameterNode) -> void + def visit_forwarding_super_node: (ForwardingSuperNode) -> void + def visit_global_variable_and_write_node: (GlobalVariableAndWriteNode) -> void + def visit_global_variable_operator_write_node: (GlobalVariableOperatorWriteNode) -> void + def visit_global_variable_or_write_node: (GlobalVariableOrWriteNode) -> void + def visit_global_variable_read_node: (GlobalVariableReadNode) -> void + def visit_global_variable_target_node: (GlobalVariableTargetNode) -> void + def visit_global_variable_write_node: (GlobalVariableWriteNode) -> void + def visit_hash_node: (HashNode) -> void + def visit_hash_pattern_node: (HashPatternNode) -> void + def visit_if_node: (IfNode) -> void + def visit_imaginary_node: (ImaginaryNode) -> void + def visit_implicit_node: (ImplicitNode) -> void + def visit_implicit_rest_node: (ImplicitRestNode) -> void + def visit_in_node: (InNode) -> void + def visit_index_and_write_node: (IndexAndWriteNode) -> void + def visit_index_operator_write_node: (IndexOperatorWriteNode) -> void + def visit_index_or_write_node: (IndexOrWriteNode) -> void + def visit_index_target_node: (IndexTargetNode) -> void + def visit_instance_variable_and_write_node: (InstanceVariableAndWriteNode) -> void + def visit_instance_variable_operator_write_node: (InstanceVariableOperatorWriteNode) -> void + def visit_instance_variable_or_write_node: (InstanceVariableOrWriteNode) -> void + def visit_instance_variable_read_node: (InstanceVariableReadNode) -> void + def visit_instance_variable_target_node: (InstanceVariableTargetNode) -> void + def visit_instance_variable_write_node: (InstanceVariableWriteNode) -> void + def visit_integer_node: (IntegerNode) -> void + def visit_interpolated_match_last_line_node: (InterpolatedMatchLastLineNode) -> void + def visit_interpolated_regular_expression_node: (InterpolatedRegularExpressionNode) -> void + def visit_interpolated_string_node: (InterpolatedStringNode) -> void + def visit_interpolated_symbol_node: (InterpolatedSymbolNode) -> void + def visit_interpolated_x_string_node: (InterpolatedXStringNode) -> void + def visit_it_local_variable_read_node: (ItLocalVariableReadNode) -> void + def visit_it_parameters_node: (ItParametersNode) -> void + def visit_keyword_hash_node: (KeywordHashNode) -> void + def visit_keyword_rest_parameter_node: (KeywordRestParameterNode) -> void + def visit_lambda_node: (LambdaNode) -> void + def visit_local_variable_and_write_node: (LocalVariableAndWriteNode) -> void + def visit_local_variable_operator_write_node: (LocalVariableOperatorWriteNode) -> void + def visit_local_variable_or_write_node: (LocalVariableOrWriteNode) -> void + def visit_local_variable_read_node: (LocalVariableReadNode) -> void + def visit_local_variable_target_node: (LocalVariableTargetNode) -> void + def visit_local_variable_write_node: (LocalVariableWriteNode) -> void + def visit_match_last_line_node: (MatchLastLineNode) -> void + def visit_match_predicate_node: (MatchPredicateNode) -> void + def visit_match_required_node: (MatchRequiredNode) -> void + def visit_match_write_node: (MatchWriteNode) -> void + def visit_missing_node: (MissingNode) -> void + def visit_module_node: (ModuleNode) -> void + def visit_multi_target_node: (MultiTargetNode) -> void + def visit_multi_write_node: (MultiWriteNode) -> void + def visit_next_node: (NextNode) -> void + def visit_nil_node: (NilNode) -> void + def visit_no_keywords_parameter_node: (NoKeywordsParameterNode) -> void + def visit_numbered_parameters_node: (NumberedParametersNode) -> void + def visit_numbered_reference_read_node: (NumberedReferenceReadNode) -> void + def visit_optional_keyword_parameter_node: (OptionalKeywordParameterNode) -> void + def visit_optional_parameter_node: (OptionalParameterNode) -> void + def visit_or_node: (OrNode) -> void + def visit_parameters_node: (ParametersNode) -> void + def visit_parentheses_node: (ParenthesesNode) -> void + def visit_pinned_expression_node: (PinnedExpressionNode) -> void + def visit_pinned_variable_node: (PinnedVariableNode) -> void + def visit_post_execution_node: (PostExecutionNode) -> void + def visit_pre_execution_node: (PreExecutionNode) -> void + def visit_program_node: (ProgramNode) -> void + def visit_range_node: (RangeNode) -> void + def visit_rational_node: (RationalNode) -> void + def visit_redo_node: (RedoNode) -> void + def visit_regular_expression_node: (RegularExpressionNode) -> void + def visit_required_keyword_parameter_node: (RequiredKeywordParameterNode) -> void + def visit_required_parameter_node: (RequiredParameterNode) -> void + def visit_rescue_modifier_node: (RescueModifierNode) -> void + def visit_rescue_node: (RescueNode) -> void + def visit_rest_parameter_node: (RestParameterNode) -> void + def visit_retry_node: (RetryNode) -> void + def visit_return_node: (ReturnNode) -> void + def visit_self_node: (SelfNode) -> void + def visit_shareable_constant_node: (ShareableConstantNode) -> void + def visit_singleton_class_node: (SingletonClassNode) -> void + def visit_source_encoding_node: (SourceEncodingNode) -> void + def visit_source_file_node: (SourceFileNode) -> void + def visit_source_line_node: (SourceLineNode) -> void + def visit_splat_node: (SplatNode) -> void + def visit_statements_node: (StatementsNode) -> void + def visit_string_node: (StringNode) -> void + def visit_super_node: (SuperNode) -> void + def visit_symbol_node: (SymbolNode) -> void + def visit_true_node: (TrueNode) -> void + def visit_undef_node: (UndefNode) -> void + def visit_unless_node: (UnlessNode) -> void + def visit_until_node: (UntilNode) -> void + def visit_when_node: (WhenNode) -> void + def visit_while_node: (WhileNode) -> void + def visit_x_string_node: (XStringNode) -> void + def visit_yield_node: (YieldNode) -> void + end + + class Visitor < BasicVisitor + include _Visitor + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/diagnostic.c b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/diagnostic.c new file mode 100644 index 00000000..be1bd716 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/diagnostic.c @@ -0,0 +1,842 @@ +/*----------------------------------------------------------------------------*/ +/* This file is generated by the templates/template.rb script and should not */ +/* be modified manually. See */ +/* templates/src/diagnostic.c.erb */ +/* if you are looking to modify the */ +/* template */ +/*----------------------------------------------------------------------------*/ + +#include "prism/diagnostic.h" + +#define PM_DIAGNOSTIC_ID_MAX 319 + +/** This struct holds the data for each diagnostic. */ +typedef struct { + /** The message associated with the diagnostic. */ + const char* message; + + /** The level associated with the diagnostic. */ + uint8_t level; +} pm_diagnostic_data_t; + +/** + * ## Message composition + * + * When composing an error message, use sentence fragments. + * + * Try describing the property of the code that caused the error, rather than + * the rule that is being violated. It may help to use a fragment that completes + * a sentence beginning, "the parser encountered (a) ...". If appropriate, add a + * description of the rule violation (or other helpful context) after a + * semicolon. + * + * For example:, instead of "control escape sequence cannot be doubled", prefer: + * + * > "invalid control escape sequence; control cannot be repeated" + * + * In some cases, where the failure is more general or syntax expectations are + * violated, it may make more sense to use a fragment that completes a sentence + * beginning, "the parser ...". + * + * For example: + * + * > "expected an expression after `(`" + * > "cannot parse the expression" + * + * ## Message style guide + * + * - Use articles like "a", "an", and "the" when appropriate. + * - e.g., prefer "cannot parse the expression" to "cannot parse expression". + * - Use the common name for tokens and nodes. + * - e.g., prefer "keyword splat" to "assoc splat" + * - e.g., prefer "embedded document" to "embdoc" + * - Do not capitalize the initial word of the message. + * - Use back ticks around token literals + * - e.g., "Expected a `=>` between the hash key and value" + * - Do not use `.` or other punctuation at the end of the message. + * - Do not use contractions like "can't". Prefer "cannot" to "can not". + * - For tokens that can have multiple meanings, reference the token and its meaning. + * - e.g., "`*` splat argument" is clearer and more complete than "splat argument" or "`*` argument" + * + * ## Error names (PM_ERR_*) + * + * - When appropriate, prefer node name to token name. + * - e.g., prefer "SPLAT" to "STAR" in the context of argument parsing. + * - Prefer token name to common name. + * - e.g., prefer "STAR" to "ASTERISK". + * - Try to order the words in the name from more general to more specific, + * - e.g., "INVALID_NUMBER_DECIMAL" is better than "DECIMAL_INVALID_NUMBER". + * - When in doubt, look for similar patterns and name them so that they are grouped when lexically + * sorted. See PM_ERR_ARGUMENT_NO_FORWARDING_* for an example. + * + * ## Level + * + * For errors, they are: + * + * * `PM_ERROR_LEVEL_SYNTAX` - Errors that should raise SyntaxError. + * * `PM_ERROR_LEVEL_ARGUMENT` - Errors that should raise ArgumentError. + * * `PM_ERROR_LEVEL_LOAD` - Errors that should raise LoadError. + * + * For warnings, they are: + * + * * `PM_WARNING_LEVEL_DEFAULT` - Warnings that appear for `ruby -c -e 'code'`. + * * `PM_WARNING_LEVEL_VERBOSE` - Warnings that appear with `-w`, as in `ruby -w -c -e 'code'`. + */ +static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_MAX] = { + // Special error that can be replaced + [PM_ERR_CANNOT_PARSE_EXPRESSION] = { "cannot parse the expression", PM_ERROR_LEVEL_SYNTAX }, + + // Errors that should raise argument errors + [PM_ERR_INVALID_ENCODING_MAGIC_COMMENT] = { "unknown or invalid encoding in the magic comment", PM_ERROR_LEVEL_ARGUMENT }, + + // Errors that should raise load errors + [PM_ERR_SCRIPT_NOT_FOUND] = { "no Ruby script found in input", PM_ERROR_LEVEL_LOAD }, + + // Errors that should raise syntax errors + [PM_ERR_ALIAS_ARGUMENT] = { "invalid argument being passed to `alias`; expected a bare word, symbol, constant, or global variable", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ALIAS_ARGUMENT_NUMBERED_REFERENCE] = { "invalid argument being passed to `alias`; can't make alias for the number variables", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_AMPAMPEQ_MULTI_ASSIGN] = { "unexpected `&&=` in a multiple assignment", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARGUMENT_AFTER_BLOCK] = { "unexpected argument after a block argument", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARGUMENT_AFTER_FORWARDING_ELLIPSES] = { "unexpected argument after `...`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARGUMENT_BARE_HASH] = { "unexpected bare hash argument", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARGUMENT_BLOCK_MULTI] = { "both block arg and actual block given; only one block is allowed", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARGUMENT_CONFLICT_AMPERSAND] = { "unexpected `&`; anonymous block parameter is also used within block", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARGUMENT_CONFLICT_STAR] = { "unexpected `*`; anonymous rest parameter is also used within block", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARGUMENT_CONFLICT_STAR_STAR] = { "unexpected `**`; anonymous keyword rest parameter is also used within block", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARGUMENT_FORMAL_CLASS] = { "invalid formal argument; formal argument cannot be a class variable", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARGUMENT_FORMAL_CONSTANT] = { "invalid formal argument; formal argument cannot be a constant", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARGUMENT_FORMAL_GLOBAL] = { "invalid formal argument; formal argument cannot be a global variable", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARGUMENT_FORMAL_IVAR] = { "invalid formal argument; formal argument cannot be an instance variable", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARGUMENT_FORWARDING_UNBOUND] = { "unexpected `...` in an non-parenthesized call", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARGUMENT_NO_FORWARDING_AMPERSAND] = { "unexpected `&`; no anonymous block parameter", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES] = { "unexpected ... when the parent method is not forwarding", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARGUMENT_NO_FORWARDING_STAR] = { "unexpected `*`; no anonymous rest parameter", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARGUMENT_NO_FORWARDING_STAR_STAR] = { "unexpected `**`; no anonymous keyword rest parameter", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT] = { "unexpected `*` splat argument after a `**` keyword splat argument", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARGUMENT_SPLAT_AFTER_SPLAT] = { "unexpected `*` splat argument after a `*` splat argument", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARGUMENT_TERM_PAREN] = { "unexpected %s; expected a `)` to close the arguments", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARGUMENT_UNEXPECTED_BLOCK] = { "unexpected '{' after a method call without parenthesis", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARRAY_ELEMENT] = { "expected an element for the array", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARRAY_EXPRESSION] = { "expected an expression for the array element", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARRAY_EXPRESSION_AFTER_STAR] = { "expected an expression after `*` in the array", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARRAY_SEPARATOR] = { "unexpected %s; expected a `,` separator for the array elements", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ARRAY_TERM] = { "unexpected %s; expected a `]` to close the array", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_BEGIN_LONELY_ELSE] = { "unexpected `else` in `begin` block; else without rescue is useless", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_BEGIN_TERM] = { "expected an `end` to close the `begin` statement", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_BEGIN_UPCASE_BRACE] = { "expected a `{` after `BEGIN`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_BEGIN_UPCASE_TERM] = { "expected a `}` to close the `BEGIN` statement", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_BEGIN_UPCASE_TOPLEVEL] = { "BEGIN is permitted only at toplevel", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_BLOCK_PARAM_LOCAL_VARIABLE] = { "expected a local variable name in the block parameters", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_BLOCK_PARAM_PIPE_TERM] = { "expected the block parameters to end with `|`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_BLOCK_TERM_BRACE] = { "expected a block beginning with `{` to end with `}`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_BLOCK_TERM_END] = { "expected a block beginning with `do` to end with `end`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_CANNOT_PARSE_STRING_PART] = { "cannot parse the string part", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_CASE_EXPRESSION_AFTER_CASE] = { "expected an expression after `case`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_CASE_EXPRESSION_AFTER_WHEN] = { "expected an expression after `when`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_CASE_MATCH_MISSING_PREDICATE] = { "expected a predicate for a case matching statement", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_CASE_MISSING_CONDITIONS] = { "expected a `when` or `in` clause after `case`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_CASE_TERM] = { "expected an `end` to close the `case` statement", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_CLASS_IN_METHOD] = { "unexpected class definition in method body", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_CLASS_NAME] = { "unexpected constant path after `class`; class/module name must be CONSTANT", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_CLASS_SUPERCLASS] = { "expected a superclass after `<`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_CLASS_TERM] = { "expected an `end` to close the `class` statement", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_CLASS_UNEXPECTED_END] = { "unexpected `end`, expecting ';' or '\\n'", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_CLASS_VARIABLE_BARE] = { "'@@' without identifiers is not allowed as a class variable name", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_CONDITIONAL_ELSIF_PREDICATE] = { "expected a predicate expression for the `elsif` statement", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_CONDITIONAL_IF_PREDICATE] = { "expected a predicate expression for the `if` statement", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_CONDITIONAL_PREDICATE_TERM] = { "expected `then` or `;` or '\\n'", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_CONDITIONAL_TERM] = { "expected an `end` to close the conditional clause", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_CONDITIONAL_TERM_ELSE] = { "expected an `end` to close the `else` clause", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_CONDITIONAL_UNLESS_PREDICATE] = { "expected a predicate expression for the `unless` statement", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_CONDITIONAL_UNTIL_PREDICATE] = { "expected a predicate expression for the `until` statement", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_CONDITIONAL_WHILE_PREDICATE] = { "expected a predicate expression for the `while` statement", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT] = { "expected a constant after the `::` operator", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_DEF_ENDLESS] = { "could not parse the endless method body", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_DEF_ENDLESS_SETTER] = { "invalid method name; a setter method cannot be defined in an endless method definition", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_DEF_NAME] = { "unexpected %s; expected a method name", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_DEF_PARAMS_TERM] = { "expected a delimiter to close the parameters", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_DEF_PARAMS_TERM_PAREN] = { "unexpected %s; expected a `)` to close the parameters", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_DEF_RECEIVER] = { "expected a receiver for the method definition", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_DEF_RECEIVER_TERM] = { "expected a `.` or `::` after the receiver in a method definition", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_DEF_TERM] = { "expected an `end` to close the `def` statement", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_DEFINED_EXPRESSION] = { "expected an expression after `defined?`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EMBDOC_TERM] = { "embedded document meets end of file", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EMBEXPR_END] = { "expected a `}` to close the embedded expression", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EMBVAR_INVALID] = { "invalid embedded variable", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_END_UPCASE_BRACE] = { "expected a `{` after `END`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_END_UPCASE_TERM] = { "expected a `}` to close the `END` statement", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ESCAPE_INVALID_CONTROL] = { "Invalid escape character syntax", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ESCAPE_INVALID_CONTROL_REPEAT] = { "invalid control escape sequence; control cannot be repeated", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ESCAPE_INVALID_HEXADECIMAL] = { "invalid hex escape sequence", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ESCAPE_INVALID_META] = { "Invalid escape character syntax", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ESCAPE_INVALID_META_REPEAT] = { "invalid meta escape sequence; meta cannot be repeated", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ESCAPE_INVALID_UNICODE] = { "invalid Unicode escape sequence", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ESCAPE_INVALID_UNICODE_CM_FLAGS] = { "invalid Unicode escape sequence; Unicode cannot be combined with control or meta flags", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ESCAPE_INVALID_UNICODE_LIST] = { "invalid Unicode list: %.*s", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ESCAPE_INVALID_UNICODE_LITERAL] = { "invalid Unicode escape sequence; Multiple codepoints at single character literal are disallowed", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ESCAPE_INVALID_UNICODE_LONG] = { "invalid Unicode escape sequence; maximum length is 6 digits", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ESCAPE_INVALID_UNICODE_SHORT] = { "too short escape sequence: %.*s", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_ESCAPE_INVALID_UNICODE_TERM] = { "unterminated Unicode escape", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPECT_ARGUMENT] = { "unexpected %s; expected an argument", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPECT_EOL_AFTER_STATEMENT] = { "unexpected %s, expecting end-of-input", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ] = { "expected an expression after `&&=`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ] = { "expected an expression after `||=`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPECT_EXPRESSION_AFTER_COMMA] = { "expected an expression after `,`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPECT_EXPRESSION_AFTER_EQUAL] = { "expected an expression after `=`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPECT_EXPRESSION_AFTER_LESS_LESS] = { "expected an expression after `<<`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPECT_EXPRESSION_AFTER_LPAREN] = { "expected an expression after `(`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR] = { "unexpected %s; expected an expression after the operator", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT] = { "expected an expression after `*` splat in an argument", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH] = { "expected an expression after `**` in a hash", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPECT_EXPRESSION_AFTER_STAR] = { "expected an expression after `*`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPECT_FOR_DELIMITER] = { "unexpected %s; expected a 'do', newline, or ';' after the 'for' loop collection", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPECT_IDENT_REQ_PARAMETER] = { "expected an identifier for the required parameter", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPECT_IN_DELIMITER] = { "expected a delimiter after the patterns of an `in` clause", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPECT_LPAREN_REQ_PARAMETER] = { "expected a `(` to start a required parameter", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPECT_MESSAGE] = { "unexpected %s; expecting a message to send to the receiver", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPECT_RBRACKET] = { "expected a matching `]`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPECT_RPAREN] = { "expected a matching `)`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPECT_RPAREN_AFTER_MULTI] = { "expected a `)` after multiple assignment", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPECT_RPAREN_REQ_PARAMETER] = { "expected a `)` to end a required parameter", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPECT_SINGLETON_CLASS_DELIMITER] = { "unexpected %s; expected a newline or a ';' after the singleton class", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPECT_STRING_CONTENT] = { "expected string content after opening string delimiter", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPECT_WHEN_DELIMITER] = { "expected a delimiter after the predicates of a `when` clause", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPRESSION_BARE_HASH] = { "unexpected bare hash in expression", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPRESSION_NOT_WRITABLE] = { "unexpected '='; target cannot be written", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPRESSION_NOT_WRITABLE_ENCODING] = { "Can't assign to __ENCODING__", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPRESSION_NOT_WRITABLE_FALSE] = { "Can't assign to false", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPRESSION_NOT_WRITABLE_FILE] = { "Can't assign to __FILE__", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPRESSION_NOT_WRITABLE_LINE] = { "Can't assign to __LINE__", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPRESSION_NOT_WRITABLE_NIL] = { "Can't assign to nil", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPRESSION_NOT_WRITABLE_NUMBERED] = { "Can't assign to numbered parameter %.2s", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPRESSION_NOT_WRITABLE_SELF] = { "Can't change the value of self", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_EXPRESSION_NOT_WRITABLE_TRUE] = { "Can't assign to true", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_FLOAT_PARSE] = { "could not parse the float '%.*s'", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_FOR_COLLECTION] = { "expected a collection after the `in` in a `for` statement", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_FOR_INDEX] = { "expected an index after `for`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_FOR_IN] = { "expected an `in` after the index in a `for` statement", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_FOR_TERM] = { "expected an `end` to close the `for` loop", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_GLOBAL_VARIABLE_BARE] = { "'$' without identifiers is not allowed as a global variable name", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_HASH_EXPRESSION_AFTER_LABEL] = { "expected an expression after the label in a hash", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_HASH_KEY] = { "unexpected %s, expecting '}' or a key in the hash literal", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_HASH_ROCKET] = { "expected a `=>` between the hash key and value", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_HASH_TERM] = { "expected a `}` to close the hash literal", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_HASH_VALUE] = { "unexpected %s; expected a value in the hash literal", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_HEREDOC_IDENTIFIER] = { "unterminated here document identifier", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_HEREDOC_TERM] = { "unterminated heredoc; can't find string \"%.*s\" anywhere before EOF", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INCOMPLETE_QUESTION_MARK] = { "incomplete expression at `?`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INCOMPLETE_VARIABLE_CLASS_3_3] = { "`%.*s' is not allowed as a class variable name", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INCOMPLETE_VARIABLE_CLASS] = { "'%.*s' is not allowed as a class variable name", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INCOMPLETE_VARIABLE_INSTANCE_3_3] = { "`%.*s' is not allowed as an instance variable name", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INCOMPLETE_VARIABLE_INSTANCE] = { "'%.*s' is not allowed as an instance variable name", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INSTANCE_VARIABLE_BARE] = { "'@' without identifiers is not allowed as an instance variable name", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_BLOCK_EXIT] = { "Invalid %s", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_COMMA] = { "invalid comma", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_ESCAPE_CHARACTER] = { "Invalid escape character syntax", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_FLOAT_EXPONENT] = { "invalid exponent", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_LOCAL_VARIABLE_READ] = { "identifier %.*s is not valid to get", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_LOCAL_VARIABLE_WRITE] = { "identifier %.*s is not valid to set", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_NUMBER_BINARY] = { "invalid binary number; numeric literal without digits", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_NUMBER_DECIMAL] = { "invalid decimal number; numeric literal without digits", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_NUMBER_FRACTION] = { "unexpected fraction part after numeric literal", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_NUMBER_HEXADECIMAL] = { "invalid hexadecimal number; numeric literal without digits", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_NUMBER_OCTAL] = { "invalid octal number; numeric literal without digits", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_NUMBER_UNDERSCORE_INNER] = { "invalid underscore placement in number", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_NUMBER_UNDERSCORE_TRAILING] = { "trailing '_' in number", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_CHARACTER] = { "Invalid char '\\x%02X' in expression", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_MULTIBYTE_CHAR] = { "invalid multibyte char (%s)", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_MULTIBYTE_CHARACTER] = { "invalid multibyte character 0x%X", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_MULTIBYTE_ESCAPE] = { "invalid multibyte escape: /%.*s/", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_PRINTABLE_CHARACTER] = { "invalid character `%c`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_PERCENT] = { "unknown type of %string", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_PERCENT_EOF] = { "unterminated quoted string meets end of file", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_RETRY_AFTER_ELSE] = { "Invalid retry after else", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_RETRY_AFTER_ENSURE] = { "Invalid retry after ensure", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_RETRY_WITHOUT_RESCUE] = { "Invalid retry without rescue", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_SYMBOL] = { "invalid symbol", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_VARIABLE_GLOBAL_3_3] = { "`%.*s' is not allowed as a global variable name", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_VARIABLE_GLOBAL] = { "'%.*s' is not allowed as a global variable name", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_INVALID_YIELD] = { "Invalid yield", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_IT_NOT_ALLOWED_NUMBERED] = { "'it' is not allowed when a numbered parameter is already used", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_IT_NOT_ALLOWED_ORDINARY] = { "'it' is not allowed when an ordinary parameter is defined", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_LAMBDA_OPEN] = { "expected a `do` keyword or a `{` to open the lambda block", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_LAMBDA_TERM_BRACE] = { "expected a lambda block beginning with `{` to end with `}`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_LAMBDA_TERM_END] = { "expected a lambda block beginning with `do` to end with `end`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_LIST_I_LOWER_ELEMENT] = { "expected a symbol in a `%i` list", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_LIST_I_LOWER_TERM] = { "unterminated list; expected a closing delimiter for the `%i`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_LIST_I_UPPER_ELEMENT] = { "expected a symbol in a `%I` list", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_LIST_I_UPPER_TERM] = { "unterminated list; expected a closing delimiter for the `%I`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_LIST_W_LOWER_ELEMENT] = { "expected a string in a `%w` list", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_LIST_W_LOWER_TERM] = { "unterminated list; expected a closing delimiter for the `%w`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_LIST_W_UPPER_ELEMENT] = { "expected a string in a `%W` list", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_LIST_W_UPPER_TERM] = { "unterminated list; expected a closing delimiter for the `%W`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_MALLOC_FAILED] = { "failed to allocate memory", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_MIXED_ENCODING] = { "UTF-8 mixed within %s source", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_MODULE_IN_METHOD] = { "unexpected module definition in method body", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_MODULE_NAME] = { "unexpected constant path after `module`; class/module name must be CONSTANT", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_MODULE_TERM] = { "expected an `end` to close the `module` statement", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_MULTI_ASSIGN_MULTI_SPLATS] = { "multiple splats in multiple assignment", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_MULTI_ASSIGN_UNEXPECTED_REST] = { "unexpected '%.*s' resulting in multiple splats in multiple assignment", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_NESTING_TOO_DEEP] = { "nesting too deep", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_NO_LOCAL_VARIABLE] = { "%.*s: no such local variable", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_NON_ASSOCIATIVE_OPERATOR] = { "unexpected %s; %s is a non-associative operator", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_NOT_EXPRESSION] = { "expected an expression after `not`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_NUMBER_LITERAL_UNDERSCORE] = { "number literal ending with a `_`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_NUMBERED_PARAMETER_INNER_BLOCK] = { "numbered parameter is already used in inner block", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_NUMBERED_PARAMETER_IT] = { "numbered parameters are not allowed when 'it' is already used", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_NUMBERED_PARAMETER_ORDINARY] = { "numbered parameters are not allowed when an ordinary parameter is defined", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_NUMBERED_PARAMETER_OUTER_BLOCK] = { "numbered parameter is already used in outer block", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_OPERATOR_MULTI_ASSIGN] = { "unexpected operator for a multiple assignment", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_OPERATOR_WRITE_ARGUMENTS] = { "unexpected operator after a call with arguments", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_OPERATOR_WRITE_BLOCK] = { "unexpected operator after a call with a block", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PARAMETER_ASSOC_SPLAT_MULTI] = { "unexpected multiple `**` splat parameters", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PARAMETER_BLOCK_MULTI] = { "multiple block parameters; only one block is allowed", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PARAMETER_CIRCULAR] = { "circular argument reference - %.*s", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PARAMETER_FORWARDING_AFTER_REST] = { "... after rest argument", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PARAMETER_METHOD_NAME] = { "unexpected name for a parameter", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PARAMETER_NAME_DUPLICATED] = { "duplicated argument name", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PARAMETER_NO_DEFAULT] = { "expected a default value for the parameter", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PARAMETER_NO_DEFAULT_KW] = { "expected a default value for the keyword parameter", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PARAMETER_NUMBERED_RESERVED] = { "%.2s is reserved for numbered parameters", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PARAMETER_ORDER] = { "unexpected parameter order", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PARAMETER_SPLAT_MULTI] = { "unexpected multiple `*` splat parameters", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PARAMETER_STAR] = { "unexpected parameter `*`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PARAMETER_UNEXPECTED_FWD] = { "unexpected `...` in parameters", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PARAMETER_WILD_LOOSE_COMMA] = { "unexpected `,` in parameters", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PARAMETER_UNEXPECTED_NO_KW] = { "unexpected **nil; no keywords marker disallowed after keywords", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_ARRAY_MULTIPLE_RESTS] = { "unexpected multiple '*' rest patterns in an array pattern", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_CAPTURE_DUPLICATE] = { "duplicated variable name", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET] = { "expected a pattern expression after the `[` operator", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_EXPRESSION_AFTER_COMMA] = { "expected a pattern expression after `,`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_EXPRESSION_AFTER_HROCKET] = { "expected a pattern expression after `=>`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_EXPRESSION_AFTER_IN] = { "expected a pattern expression after the `in` keyword", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_EXPRESSION_AFTER_KEY] = { "expected a pattern expression after the key", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_EXPRESSION_AFTER_PAREN] = { "expected a pattern expression after the `(` operator", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_EXPRESSION_AFTER_PIN] = { "expected a pattern expression after the `^` pin operator", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_EXPRESSION_AFTER_PIPE] = { "expected a pattern expression after the `|` operator", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_EXPRESSION_AFTER_RANGE] = { "expected a pattern expression after the range operator", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_EXPRESSION_AFTER_REST] = { "unexpected pattern expression after the `**` expression", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_FIND_MISSING_INNER] = { "find patterns need at least one required inner pattern", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_HASH_IMPLICIT] = { "unexpected implicit hash in pattern; use '{' to delineate", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_HASH_KEY] = { "unexpected %s; expected a key in the hash pattern", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_HASH_KEY_DUPLICATE] = { "duplicated key name", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_HASH_KEY_INTERPOLATED] = { "symbol literal with interpolation is not allowed", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_HASH_KEY_LABEL] = { "expected a label as the key in the hash pattern", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_HASH_KEY_LOCALS] = { "key must be valid as local variables", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_IDENT_AFTER_HROCKET] = { "expected an identifier after the `=>` operator", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_LABEL_AFTER_COMMA] = { "expected a label after the `,` in the hash pattern", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_REST] = { "unexpected rest pattern", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_TERM_BRACE] = { "expected a `}` to close the pattern expression", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_TERM_BRACKET] = { "expected a `]` to close the pattern expression", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PATTERN_TERM_PAREN] = { "expected a `)` to close the pattern expression", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_PIPEPIPEEQ_MULTI_ASSIGN] = { "unexpected `||=` in a multiple assignment", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_REGEXP_ENCODING_OPTION_MISMATCH] = { "regexp encoding option '%c' differs from source encoding '%s'", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_REGEXP_INCOMPAT_CHAR_ENCODING] = { "incompatible character encoding: /%.*s/", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_REGEXP_NON_ESCAPED_MBC] = { "/.../n has a non escaped non ASCII character in non ASCII-8BIT script: /%.*s/", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_REGEXP_INVALID_UNICODE_RANGE] = { "invalid Unicode range: /%.*s/", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_REGEXP_PARSE_ERROR] = { "%s", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_REGEXP_UNKNOWN_OPTIONS] = { "unknown regexp %s - %.*s", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_REGEXP_TERM] = { "unterminated regexp meets end of file; expected a closing delimiter", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_REGEXP_UTF8_CHAR_NON_UTF8_REGEXP] = { "UTF-8 character in non UTF-8 regexp: /%s/", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_RESCUE_EXPRESSION] = { "expected a rescued expression", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_RESCUE_MODIFIER_VALUE] = { "expected a value after the `rescue` modifier", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_RESCUE_TERM] = { "expected a closing delimiter for the `rescue` clause", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_RESCUE_VARIABLE] = { "expected an exception variable after `=>` in a rescue statement", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_RETURN_INVALID] = { "Invalid return in class/module body", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_SINGLETON_FOR_LITERALS] = { "cannot define singleton method for literals", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_STATEMENT_ALIAS] = { "unexpected an `alias` at a non-statement position", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_STATEMENT_POSTEXE_END] = { "unexpected an `END` at a non-statement position", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_STATEMENT_PREEXE_BEGIN] = { "unexpected a `BEGIN` at a non-statement position", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_STATEMENT_UNDEF] = { "unexpected an `undef` at a non-statement position", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_STRING_CONCATENATION] = { "expected a string for concatenation", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_STRING_INTERPOLATED_TERM] = { "unterminated string; expected a closing delimiter for the interpolated string", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_STRING_LITERAL_EOF] = { "unterminated string meets end of file", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_STRING_LITERAL_TERM] = { "unexpected %s, expected a string literal terminator", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_SYMBOL_INVALID] = { "invalid symbol", PM_ERROR_LEVEL_SYNTAX }, // TODO expected symbol? prism.c ~9719 + [PM_ERR_SYMBOL_TERM_DYNAMIC] = { "unterminated quoted string; expected a closing delimiter for the dynamic symbol", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_SYMBOL_TERM_INTERPOLATED] = { "unterminated symbol; expected a closing delimiter for the interpolated symbol", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_TERNARY_COLON] = { "expected a `:` after the true expression of a ternary operator", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_TERNARY_EXPRESSION_FALSE] = { "expected an expression after `:` in the ternary operator", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_TERNARY_EXPRESSION_TRUE] = { "expected an expression after `?` in the ternary operator", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_UNARY_RECEIVER] = { "unexpected %s, expected a receiver for unary `%c`", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_UNARY_DISALLOWED] = { "unexpected %s; unary calls are not allowed in this context", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_UNDEF_ARGUMENT] = { "invalid argument being passed to `undef`; expected a bare word, constant, or symbol argument", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_UNEXPECTED_BLOCK_ARGUMENT] = { "block argument should not be given", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_UNEXPECTED_INDEX_BLOCK] = { "unexpected block arg given in index assignment; blocks are not allowed in index assignment expressions", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_UNEXPECTED_INDEX_KEYWORDS] = { "unexpected keyword arg given in index assignment; keywords are not allowed in index assignment expressions", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_UNEXPECTED_LABEL] = { "unexpected label", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_UNEXPECTED_MULTI_WRITE] = { "unexpected multiple assignment; multiple assignment is not allowed in this context", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_UNEXPECTED_RANGE_OPERATOR] = { "unexpected range operator; .. and ... are non-associative and cannot be chained", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_UNEXPECTED_SAFE_NAVIGATION] = { "&. inside multiple assignment destination", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_UNEXPECTED_TOKEN_CLOSE_CONTEXT] = { "unexpected %s, assuming it is closing the parent %s", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_UNEXPECTED_TOKEN_IGNORE] = { "unexpected %s, ignoring it", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_UNTIL_TERM] = { "expected an `end` to close the `until` statement", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_VOID_EXPRESSION] = { "unexpected void value expression", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_WHILE_TERM] = { "expected an `end` to close the `while` statement", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_WRITE_TARGET_IN_METHOD] = { "dynamic constant assignment", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_WRITE_TARGET_READONLY] = { "Can't set variable %.*s", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_WRITE_TARGET_UNEXPECTED] = { "unexpected write target", PM_ERROR_LEVEL_SYNTAX }, + [PM_ERR_XSTRING_TERM] = { "expected a closing delimiter for the `%x` or backtick string", PM_ERROR_LEVEL_SYNTAX }, + + // Warnings + [PM_WARN_AMBIGUOUS_BINARY_OPERATOR] = { "'%s' after local variable or literal is interpreted as binary operator even though it seems like %s", PM_WARNING_LEVEL_VERBOSE }, + [PM_WARN_AMBIGUOUS_FIRST_ARGUMENT_MINUS] = { "ambiguous first argument; put parentheses or a space even after `-` operator", PM_WARNING_LEVEL_VERBOSE }, + [PM_WARN_AMBIGUOUS_FIRST_ARGUMENT_PLUS] = { "ambiguous first argument; put parentheses or a space even after `+` operator", PM_WARNING_LEVEL_VERBOSE }, + [PM_WARN_AMBIGUOUS_PREFIX_AMPERSAND] = { "ambiguous `&` has been interpreted as an argument prefix", PM_WARNING_LEVEL_VERBOSE }, + [PM_WARN_AMBIGUOUS_PREFIX_STAR] = { "ambiguous `*` has been interpreted as an argument prefix", PM_WARNING_LEVEL_VERBOSE }, + [PM_WARN_AMBIGUOUS_PREFIX_STAR_STAR] = { "ambiguous `**` has been interpreted as an argument prefix", PM_WARNING_LEVEL_VERBOSE }, + [PM_WARN_AMBIGUOUS_SLASH] = { "ambiguous `/`; wrap regexp in parentheses or add a space after `/` operator", PM_WARNING_LEVEL_VERBOSE }, + [PM_WARN_COMPARISON_AFTER_COMPARISON] = { "comparison '%.*s' after comparison", PM_WARNING_LEVEL_VERBOSE }, + [PM_WARN_DOT_DOT_DOT_EOL] = { "... at EOL, should be parenthesized?", PM_WARNING_LEVEL_DEFAULT }, + [PM_WARN_DUPLICATED_HASH_KEY] = { "key %.*s is duplicated and overwritten on line %" PRIi32, PM_WARNING_LEVEL_DEFAULT }, + [PM_WARN_DUPLICATED_WHEN_CLAUSE] = { "'when' clause on line %" PRIi32 " duplicates 'when' clause on line %" PRIi32 " and is ignored", PM_WARNING_LEVEL_VERBOSE }, + [PM_WARN_EQUAL_IN_CONDITIONAL_3_3] = { "found `= literal' in conditional, should be ==", PM_WARNING_LEVEL_DEFAULT }, + [PM_WARN_EQUAL_IN_CONDITIONAL] = { "found '= literal' in conditional, should be ==", PM_WARNING_LEVEL_DEFAULT }, + [PM_WARN_END_IN_METHOD] = { "END in method; use at_exit", PM_WARNING_LEVEL_DEFAULT }, + [PM_WARN_FLOAT_OUT_OF_RANGE] = { "Float %.*s%s out of range", PM_WARNING_LEVEL_VERBOSE }, + [PM_WARN_IGNORED_FROZEN_STRING_LITERAL] = { "'frozen_string_literal' is ignored after any tokens", PM_WARNING_LEVEL_VERBOSE }, + [PM_WARN_INDENTATION_MISMATCH] = { "mismatched indentations at '%.*s' with '%.*s' at %" PRIi32, PM_WARNING_LEVEL_VERBOSE }, + [PM_WARN_INTEGER_IN_FLIP_FLOP] = { "integer literal in flip-flop", PM_WARNING_LEVEL_DEFAULT }, + [PM_WARN_INVALID_CHARACTER] = { "invalid character syntax; use %s%s%s", PM_WARNING_LEVEL_DEFAULT }, + [PM_WARN_INVALID_MAGIC_COMMENT_VALUE] = { "invalid value for %.*s: %.*s", PM_WARNING_LEVEL_VERBOSE }, + [PM_WARN_INVALID_NUMBERED_REFERENCE] = { "'%.*s' is too big for a number variable, always nil", PM_WARNING_LEVEL_DEFAULT }, + [PM_WARN_KEYWORD_EOL] = { "`%.*s` at the end of line without an expression", PM_WARNING_LEVEL_VERBOSE }, + [PM_WARN_LITERAL_IN_CONDITION_DEFAULT] = { "%sliteral in %s", PM_WARNING_LEVEL_DEFAULT }, + [PM_WARN_LITERAL_IN_CONDITION_VERBOSE] = { "%sliteral in %s", PM_WARNING_LEVEL_VERBOSE }, + [PM_WARN_SHAREABLE_CONSTANT_VALUE_LINE] = { "'shareable_constant_value' is ignored unless in comment-only line", PM_WARNING_LEVEL_VERBOSE }, + [PM_WARN_SHEBANG_CARRIAGE_RETURN] = { "shebang line ending with \\r may cause problems", PM_WARNING_LEVEL_DEFAULT }, + [PM_WARN_UNEXPECTED_CARRIAGE_RETURN] = { "encountered \\r in middle of line, treated as a mere space", PM_WARNING_LEVEL_DEFAULT }, + [PM_WARN_UNREACHABLE_STATEMENT] = { "statement not reached", PM_WARNING_LEVEL_VERBOSE }, + [PM_WARN_UNUSED_LOCAL_VARIABLE] = { "assigned but unused variable - %.*s", PM_WARNING_LEVEL_VERBOSE }, + [PM_WARN_VOID_STATEMENT] = { "possibly useless use of %.*s in void context", PM_WARNING_LEVEL_VERBOSE } +}; + +/** + * Get the human-readable name of the given diagnostic ID. + */ +const char * +pm_diagnostic_id_human(pm_diagnostic_id_t diag_id) { + switch (diag_id) { + case PM_ERR_ALIAS_ARGUMENT: return "alias_argument"; + case PM_ERR_ALIAS_ARGUMENT_NUMBERED_REFERENCE: return "alias_argument_numbered_reference"; + case PM_ERR_AMPAMPEQ_MULTI_ASSIGN: return "ampampeq_multi_assign"; + case PM_ERR_ARGUMENT_AFTER_BLOCK: return "argument_after_block"; + case PM_ERR_ARGUMENT_AFTER_FORWARDING_ELLIPSES: return "argument_after_forwarding_ellipses"; + case PM_ERR_ARGUMENT_BARE_HASH: return "argument_bare_hash"; + case PM_ERR_ARGUMENT_BLOCK_FORWARDING: return "argument_block_forwarding"; + case PM_ERR_ARGUMENT_BLOCK_MULTI: return "argument_block_multi"; + case PM_ERR_ARGUMENT_CONFLICT_AMPERSAND: return "argument_conflict_ampersand"; + case PM_ERR_ARGUMENT_CONFLICT_STAR: return "argument_conflict_star"; + case PM_ERR_ARGUMENT_CONFLICT_STAR_STAR: return "argument_conflict_star_star"; + case PM_ERR_ARGUMENT_FORMAL_CLASS: return "argument_formal_class"; + case PM_ERR_ARGUMENT_FORMAL_CONSTANT: return "argument_formal_constant"; + case PM_ERR_ARGUMENT_FORMAL_GLOBAL: return "argument_formal_global"; + case PM_ERR_ARGUMENT_FORMAL_IVAR: return "argument_formal_ivar"; + case PM_ERR_ARGUMENT_FORWARDING_UNBOUND: return "argument_forwarding_unbound"; + case PM_ERR_ARGUMENT_NO_FORWARDING_AMPERSAND: return "argument_no_forwarding_ampersand"; + case PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES: return "argument_no_forwarding_ellipses"; + case PM_ERR_ARGUMENT_NO_FORWARDING_STAR: return "argument_no_forwarding_star"; + case PM_ERR_ARGUMENT_NO_FORWARDING_STAR_STAR: return "argument_no_forwarding_star_star"; + case PM_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT: return "argument_splat_after_assoc_splat"; + case PM_ERR_ARGUMENT_SPLAT_AFTER_SPLAT: return "argument_splat_after_splat"; + case PM_ERR_ARGUMENT_TERM_PAREN: return "argument_term_paren"; + case PM_ERR_ARGUMENT_UNEXPECTED_BLOCK: return "argument_unexpected_block"; + case PM_ERR_ARRAY_ELEMENT: return "array_element"; + case PM_ERR_ARRAY_EXPRESSION: return "array_expression"; + case PM_ERR_ARRAY_EXPRESSION_AFTER_STAR: return "array_expression_after_star"; + case PM_ERR_ARRAY_SEPARATOR: return "array_separator"; + case PM_ERR_ARRAY_TERM: return "array_term"; + case PM_ERR_BEGIN_LONELY_ELSE: return "begin_lonely_else"; + case PM_ERR_BEGIN_TERM: return "begin_term"; + case PM_ERR_BEGIN_UPCASE_BRACE: return "begin_upcase_brace"; + case PM_ERR_BEGIN_UPCASE_TERM: return "begin_upcase_term"; + case PM_ERR_BEGIN_UPCASE_TOPLEVEL: return "begin_upcase_toplevel"; + case PM_ERR_BLOCK_PARAM_LOCAL_VARIABLE: return "block_param_local_variable"; + case PM_ERR_BLOCK_PARAM_PIPE_TERM: return "block_param_pipe_term"; + case PM_ERR_BLOCK_TERM_BRACE: return "block_term_brace"; + case PM_ERR_BLOCK_TERM_END: return "block_term_end"; + case PM_ERR_CANNOT_PARSE_EXPRESSION: return "cannot_parse_expression"; + case PM_ERR_CANNOT_PARSE_STRING_PART: return "cannot_parse_string_part"; + case PM_ERR_CASE_EXPRESSION_AFTER_CASE: return "case_expression_after_case"; + case PM_ERR_CASE_EXPRESSION_AFTER_WHEN: return "case_expression_after_when"; + case PM_ERR_CASE_MATCH_MISSING_PREDICATE: return "case_match_missing_predicate"; + case PM_ERR_CASE_MISSING_CONDITIONS: return "case_missing_conditions"; + case PM_ERR_CASE_TERM: return "case_term"; + case PM_ERR_CLASS_IN_METHOD: return "class_in_method"; + case PM_ERR_CLASS_NAME: return "class_name"; + case PM_ERR_CLASS_SUPERCLASS: return "class_superclass"; + case PM_ERR_CLASS_TERM: return "class_term"; + case PM_ERR_CLASS_UNEXPECTED_END: return "class_unexpected_end"; + case PM_ERR_CLASS_VARIABLE_BARE: return "class_variable_bare"; + case PM_ERR_CONDITIONAL_ELSIF_PREDICATE: return "conditional_elsif_predicate"; + case PM_ERR_CONDITIONAL_IF_PREDICATE: return "conditional_if_predicate"; + case PM_ERR_CONDITIONAL_PREDICATE_TERM: return "conditional_predicate_term"; + case PM_ERR_CONDITIONAL_TERM: return "conditional_term"; + case PM_ERR_CONDITIONAL_TERM_ELSE: return "conditional_term_else"; + case PM_ERR_CONDITIONAL_UNLESS_PREDICATE: return "conditional_unless_predicate"; + case PM_ERR_CONDITIONAL_UNTIL_PREDICATE: return "conditional_until_predicate"; + case PM_ERR_CONDITIONAL_WHILE_PREDICATE: return "conditional_while_predicate"; + case PM_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT: return "constant_path_colon_colon_constant"; + case PM_ERR_DEF_ENDLESS: return "def_endless"; + case PM_ERR_DEF_ENDLESS_SETTER: return "def_endless_setter"; + case PM_ERR_DEF_NAME: return "def_name"; + case PM_ERR_DEF_PARAMS_TERM: return "def_params_term"; + case PM_ERR_DEF_PARAMS_TERM_PAREN: return "def_params_term_paren"; + case PM_ERR_DEF_RECEIVER: return "def_receiver"; + case PM_ERR_DEF_RECEIVER_TERM: return "def_receiver_term"; + case PM_ERR_DEF_TERM: return "def_term"; + case PM_ERR_DEFINED_EXPRESSION: return "defined_expression"; + case PM_ERR_EMBDOC_TERM: return "embdoc_term"; + case PM_ERR_EMBEXPR_END: return "embexpr_end"; + case PM_ERR_EMBVAR_INVALID: return "embvar_invalid"; + case PM_ERR_END_UPCASE_BRACE: return "end_upcase_brace"; + case PM_ERR_END_UPCASE_TERM: return "end_upcase_term"; + case PM_ERR_ESCAPE_INVALID_CONTROL: return "escape_invalid_control"; + case PM_ERR_ESCAPE_INVALID_CONTROL_REPEAT: return "escape_invalid_control_repeat"; + case PM_ERR_ESCAPE_INVALID_HEXADECIMAL: return "escape_invalid_hexadecimal"; + case PM_ERR_ESCAPE_INVALID_META: return "escape_invalid_meta"; + case PM_ERR_ESCAPE_INVALID_META_REPEAT: return "escape_invalid_meta_repeat"; + case PM_ERR_ESCAPE_INVALID_UNICODE: return "escape_invalid_unicode"; + case PM_ERR_ESCAPE_INVALID_UNICODE_CM_FLAGS: return "escape_invalid_unicode_cm_flags"; + case PM_ERR_ESCAPE_INVALID_UNICODE_LIST: return "escape_invalid_unicode_list"; + case PM_ERR_ESCAPE_INVALID_UNICODE_LITERAL: return "escape_invalid_unicode_literal"; + case PM_ERR_ESCAPE_INVALID_UNICODE_LONG: return "escape_invalid_unicode_long"; + case PM_ERR_ESCAPE_INVALID_UNICODE_SHORT: return "escape_invalid_unicode_short"; + case PM_ERR_ESCAPE_INVALID_UNICODE_TERM: return "escape_invalid_unicode_term"; + case PM_ERR_EXPECT_ARGUMENT: return "expect_argument"; + case PM_ERR_EXPECT_EOL_AFTER_STATEMENT: return "expect_eol_after_statement"; + case PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ: return "expect_expression_after_ampampeq"; + case PM_ERR_EXPECT_EXPRESSION_AFTER_COMMA: return "expect_expression_after_comma"; + case PM_ERR_EXPECT_EXPRESSION_AFTER_EQUAL: return "expect_expression_after_equal"; + case PM_ERR_EXPECT_EXPRESSION_AFTER_LESS_LESS: return "expect_expression_after_less_less"; + case PM_ERR_EXPECT_EXPRESSION_AFTER_LPAREN: return "expect_expression_after_lparen"; + case PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR: return "expect_expression_after_operator"; + case PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ: return "expect_expression_after_pipepipeeq"; + case PM_ERR_EXPECT_EXPRESSION_AFTER_QUESTION: return "expect_expression_after_question"; + case PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT: return "expect_expression_after_splat"; + case PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH: return "expect_expression_after_splat_hash"; + case PM_ERR_EXPECT_EXPRESSION_AFTER_STAR: return "expect_expression_after_star"; + case PM_ERR_EXPECT_FOR_DELIMITER: return "expect_for_delimiter"; + case PM_ERR_EXPECT_IDENT_REQ_PARAMETER: return "expect_ident_req_parameter"; + case PM_ERR_EXPECT_IN_DELIMITER: return "expect_in_delimiter"; + case PM_ERR_EXPECT_LPAREN_REQ_PARAMETER: return "expect_lparen_req_parameter"; + case PM_ERR_EXPECT_MESSAGE: return "expect_message"; + case PM_ERR_EXPECT_RBRACKET: return "expect_rbracket"; + case PM_ERR_EXPECT_RPAREN: return "expect_rparen"; + case PM_ERR_EXPECT_RPAREN_AFTER_MULTI: return "expect_rparen_after_multi"; + case PM_ERR_EXPECT_RPAREN_REQ_PARAMETER: return "expect_rparen_req_parameter"; + case PM_ERR_EXPECT_SINGLETON_CLASS_DELIMITER: return "expect_singleton_class_delimiter"; + case PM_ERR_EXPECT_STRING_CONTENT: return "expect_string_content"; + case PM_ERR_EXPECT_WHEN_DELIMITER: return "expect_when_delimiter"; + case PM_ERR_EXPRESSION_BARE_HASH: return "expression_bare_hash"; + case PM_ERR_EXPRESSION_NOT_WRITABLE: return "expression_not_writable"; + case PM_ERR_EXPRESSION_NOT_WRITABLE_ENCODING: return "expression_not_writable_encoding"; + case PM_ERR_EXPRESSION_NOT_WRITABLE_FALSE: return "expression_not_writable_false"; + case PM_ERR_EXPRESSION_NOT_WRITABLE_FILE: return "expression_not_writable_file"; + case PM_ERR_EXPRESSION_NOT_WRITABLE_LINE: return "expression_not_writable_line"; + case PM_ERR_EXPRESSION_NOT_WRITABLE_NIL: return "expression_not_writable_nil"; + case PM_ERR_EXPRESSION_NOT_WRITABLE_NUMBERED: return "expression_not_writable_numbered"; + case PM_ERR_EXPRESSION_NOT_WRITABLE_SELF: return "expression_not_writable_self"; + case PM_ERR_EXPRESSION_NOT_WRITABLE_TRUE: return "expression_not_writable_true"; + case PM_ERR_FLOAT_PARSE: return "float_parse"; + case PM_ERR_FOR_COLLECTION: return "for_collection"; + case PM_ERR_FOR_IN: return "for_in"; + case PM_ERR_FOR_INDEX: return "for_index"; + case PM_ERR_FOR_TERM: return "for_term"; + case PM_ERR_GLOBAL_VARIABLE_BARE: return "global_variable_bare"; + case PM_ERR_HASH_EXPRESSION_AFTER_LABEL: return "hash_expression_after_label"; + case PM_ERR_HASH_KEY: return "hash_key"; + case PM_ERR_HASH_ROCKET: return "hash_rocket"; + case PM_ERR_HASH_TERM: return "hash_term"; + case PM_ERR_HASH_VALUE: return "hash_value"; + case PM_ERR_HEREDOC_IDENTIFIER: return "heredoc_identifier"; + case PM_ERR_HEREDOC_TERM: return "heredoc_term"; + case PM_ERR_INCOMPLETE_QUESTION_MARK: return "incomplete_question_mark"; + case PM_ERR_INCOMPLETE_VARIABLE_CLASS: return "incomplete_variable_class"; + case PM_ERR_INCOMPLETE_VARIABLE_CLASS_3_3: return "incomplete_variable_class_3_3"; + case PM_ERR_INCOMPLETE_VARIABLE_INSTANCE: return "incomplete_variable_instance"; + case PM_ERR_INCOMPLETE_VARIABLE_INSTANCE_3_3: return "incomplete_variable_instance_3_3"; + case PM_ERR_INSTANCE_VARIABLE_BARE: return "instance_variable_bare"; + case PM_ERR_INVALID_BLOCK_EXIT: return "invalid_block_exit"; + case PM_ERR_INVALID_CHARACTER: return "invalid_character"; + case PM_ERR_INVALID_COMMA: return "invalid_comma"; + case PM_ERR_INVALID_ENCODING_MAGIC_COMMENT: return "invalid_encoding_magic_comment"; + case PM_ERR_INVALID_ESCAPE_CHARACTER: return "invalid_escape_character"; + case PM_ERR_INVALID_FLOAT_EXPONENT: return "invalid_float_exponent"; + case PM_ERR_INVALID_LOCAL_VARIABLE_READ: return "invalid_local_variable_read"; + case PM_ERR_INVALID_LOCAL_VARIABLE_WRITE: return "invalid_local_variable_write"; + case PM_ERR_INVALID_MULTIBYTE_CHAR: return "invalid_multibyte_char"; + case PM_ERR_INVALID_MULTIBYTE_CHARACTER: return "invalid_multibyte_character"; + case PM_ERR_INVALID_MULTIBYTE_ESCAPE: return "invalid_multibyte_escape"; + case PM_ERR_INVALID_NUMBER_BINARY: return "invalid_number_binary"; + case PM_ERR_INVALID_NUMBER_DECIMAL: return "invalid_number_decimal"; + case PM_ERR_INVALID_NUMBER_FRACTION: return "invalid_number_fraction"; + case PM_ERR_INVALID_NUMBER_HEXADECIMAL: return "invalid_number_hexadecimal"; + case PM_ERR_INVALID_NUMBER_OCTAL: return "invalid_number_octal"; + case PM_ERR_INVALID_NUMBER_UNDERSCORE_INNER: return "invalid_number_underscore_inner"; + case PM_ERR_INVALID_NUMBER_UNDERSCORE_TRAILING: return "invalid_number_underscore_trailing"; + case PM_ERR_INVALID_PERCENT: return "invalid_percent"; + case PM_ERR_INVALID_PERCENT_EOF: return "invalid_percent_eof"; + case PM_ERR_INVALID_PRINTABLE_CHARACTER: return "invalid_printable_character"; + case PM_ERR_INVALID_RETRY_AFTER_ELSE: return "invalid_retry_after_else"; + case PM_ERR_INVALID_RETRY_AFTER_ENSURE: return "invalid_retry_after_ensure"; + case PM_ERR_INVALID_RETRY_WITHOUT_RESCUE: return "invalid_retry_without_rescue"; + case PM_ERR_INVALID_SYMBOL: return "invalid_symbol"; + case PM_ERR_INVALID_VARIABLE_GLOBAL: return "invalid_variable_global"; + case PM_ERR_INVALID_VARIABLE_GLOBAL_3_3: return "invalid_variable_global_3_3"; + case PM_ERR_INVALID_YIELD: return "invalid_yield"; + case PM_ERR_IT_NOT_ALLOWED_NUMBERED: return "it_not_allowed_numbered"; + case PM_ERR_IT_NOT_ALLOWED_ORDINARY: return "it_not_allowed_ordinary"; + case PM_ERR_LAMBDA_OPEN: return "lambda_open"; + case PM_ERR_LAMBDA_TERM_BRACE: return "lambda_term_brace"; + case PM_ERR_LAMBDA_TERM_END: return "lambda_term_end"; + case PM_ERR_LIST_I_LOWER_ELEMENT: return "list_i_lower_element"; + case PM_ERR_LIST_I_LOWER_TERM: return "list_i_lower_term"; + case PM_ERR_LIST_I_UPPER_ELEMENT: return "list_i_upper_element"; + case PM_ERR_LIST_I_UPPER_TERM: return "list_i_upper_term"; + case PM_ERR_LIST_W_LOWER_ELEMENT: return "list_w_lower_element"; + case PM_ERR_LIST_W_LOWER_TERM: return "list_w_lower_term"; + case PM_ERR_LIST_W_UPPER_ELEMENT: return "list_w_upper_element"; + case PM_ERR_LIST_W_UPPER_TERM: return "list_w_upper_term"; + case PM_ERR_MALLOC_FAILED: return "malloc_failed"; + case PM_ERR_MIXED_ENCODING: return "mixed_encoding"; + case PM_ERR_MODULE_IN_METHOD: return "module_in_method"; + case PM_ERR_MODULE_NAME: return "module_name"; + case PM_ERR_MODULE_TERM: return "module_term"; + case PM_ERR_MULTI_ASSIGN_MULTI_SPLATS: return "multi_assign_multi_splats"; + case PM_ERR_MULTI_ASSIGN_UNEXPECTED_REST: return "multi_assign_unexpected_rest"; + case PM_ERR_NESTING_TOO_DEEP: return "nesting_too_deep"; + case PM_ERR_NO_LOCAL_VARIABLE: return "no_local_variable"; + case PM_ERR_NON_ASSOCIATIVE_OPERATOR: return "non_associative_operator"; + case PM_ERR_NOT_EXPRESSION: return "not_expression"; + case PM_ERR_NUMBER_LITERAL_UNDERSCORE: return "number_literal_underscore"; + case PM_ERR_NUMBERED_PARAMETER_INNER_BLOCK: return "numbered_parameter_inner_block"; + case PM_ERR_NUMBERED_PARAMETER_IT: return "numbered_parameter_it"; + case PM_ERR_NUMBERED_PARAMETER_ORDINARY: return "numbered_parameter_ordinary"; + case PM_ERR_NUMBERED_PARAMETER_OUTER_BLOCK: return "numbered_parameter_outer_block"; + case PM_ERR_OPERATOR_MULTI_ASSIGN: return "operator_multi_assign"; + case PM_ERR_OPERATOR_WRITE_ARGUMENTS: return "operator_write_arguments"; + case PM_ERR_OPERATOR_WRITE_BLOCK: return "operator_write_block"; + case PM_ERR_PARAMETER_ASSOC_SPLAT_MULTI: return "parameter_assoc_splat_multi"; + case PM_ERR_PARAMETER_BLOCK_MULTI: return "parameter_block_multi"; + case PM_ERR_PARAMETER_CIRCULAR: return "parameter_circular"; + case PM_ERR_PARAMETER_FORWARDING_AFTER_REST: return "parameter_forwarding_after_rest"; + case PM_ERR_PARAMETER_METHOD_NAME: return "parameter_method_name"; + case PM_ERR_PARAMETER_NAME_DUPLICATED: return "parameter_name_duplicated"; + case PM_ERR_PARAMETER_NO_DEFAULT: return "parameter_no_default"; + case PM_ERR_PARAMETER_NO_DEFAULT_KW: return "parameter_no_default_kw"; + case PM_ERR_PARAMETER_NUMBERED_RESERVED: return "parameter_numbered_reserved"; + case PM_ERR_PARAMETER_ORDER: return "parameter_order"; + case PM_ERR_PARAMETER_SPLAT_MULTI: return "parameter_splat_multi"; + case PM_ERR_PARAMETER_STAR: return "parameter_star"; + case PM_ERR_PARAMETER_UNEXPECTED_FWD: return "parameter_unexpected_fwd"; + case PM_ERR_PARAMETER_UNEXPECTED_NO_KW: return "parameter_unexpected_no_kw"; + case PM_ERR_PARAMETER_WILD_LOOSE_COMMA: return "parameter_wild_loose_comma"; + case PM_ERR_PATTERN_ARRAY_MULTIPLE_RESTS: return "pattern_array_multiple_rests"; + case PM_ERR_PATTERN_CAPTURE_DUPLICATE: return "pattern_capture_duplicate"; + case PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET: return "pattern_expression_after_bracket"; + case PM_ERR_PATTERN_EXPRESSION_AFTER_COMMA: return "pattern_expression_after_comma"; + case PM_ERR_PATTERN_EXPRESSION_AFTER_HROCKET: return "pattern_expression_after_hrocket"; + case PM_ERR_PATTERN_EXPRESSION_AFTER_IN: return "pattern_expression_after_in"; + case PM_ERR_PATTERN_EXPRESSION_AFTER_KEY: return "pattern_expression_after_key"; + case PM_ERR_PATTERN_EXPRESSION_AFTER_PAREN: return "pattern_expression_after_paren"; + case PM_ERR_PATTERN_EXPRESSION_AFTER_PIN: return "pattern_expression_after_pin"; + case PM_ERR_PATTERN_EXPRESSION_AFTER_PIPE: return "pattern_expression_after_pipe"; + case PM_ERR_PATTERN_EXPRESSION_AFTER_RANGE: return "pattern_expression_after_range"; + case PM_ERR_PATTERN_EXPRESSION_AFTER_REST: return "pattern_expression_after_rest"; + case PM_ERR_PATTERN_FIND_MISSING_INNER: return "pattern_find_missing_inner"; + case PM_ERR_PATTERN_HASH_IMPLICIT: return "pattern_hash_implicit"; + case PM_ERR_PATTERN_HASH_KEY: return "pattern_hash_key"; + case PM_ERR_PATTERN_HASH_KEY_DUPLICATE: return "pattern_hash_key_duplicate"; + case PM_ERR_PATTERN_HASH_KEY_INTERPOLATED: return "pattern_hash_key_interpolated"; + case PM_ERR_PATTERN_HASH_KEY_LABEL: return "pattern_hash_key_label"; + case PM_ERR_PATTERN_HASH_KEY_LOCALS: return "pattern_hash_key_locals"; + case PM_ERR_PATTERN_IDENT_AFTER_HROCKET: return "pattern_ident_after_hrocket"; + case PM_ERR_PATTERN_LABEL_AFTER_COMMA: return "pattern_label_after_comma"; + case PM_ERR_PATTERN_REST: return "pattern_rest"; + case PM_ERR_PATTERN_TERM_BRACE: return "pattern_term_brace"; + case PM_ERR_PATTERN_TERM_BRACKET: return "pattern_term_bracket"; + case PM_ERR_PATTERN_TERM_PAREN: return "pattern_term_paren"; + case PM_ERR_PIPEPIPEEQ_MULTI_ASSIGN: return "pipepipeeq_multi_assign"; + case PM_ERR_REGEXP_ENCODING_OPTION_MISMATCH: return "regexp_encoding_option_mismatch"; + case PM_ERR_REGEXP_INCOMPAT_CHAR_ENCODING: return "regexp_incompat_char_encoding"; + case PM_ERR_REGEXP_INVALID_UNICODE_RANGE: return "regexp_invalid_unicode_range"; + case PM_ERR_REGEXP_NON_ESCAPED_MBC: return "regexp_non_escaped_mbc"; + case PM_ERR_REGEXP_PARSE_ERROR: return "regexp_parse_error"; + case PM_ERR_REGEXP_TERM: return "regexp_term"; + case PM_ERR_REGEXP_UNKNOWN_OPTIONS: return "regexp_unknown_options"; + case PM_ERR_REGEXP_UTF8_CHAR_NON_UTF8_REGEXP: return "regexp_utf8_char_non_utf8_regexp"; + case PM_ERR_RESCUE_EXPRESSION: return "rescue_expression"; + case PM_ERR_RESCUE_MODIFIER_VALUE: return "rescue_modifier_value"; + case PM_ERR_RESCUE_TERM: return "rescue_term"; + case PM_ERR_RESCUE_VARIABLE: return "rescue_variable"; + case PM_ERR_RETURN_INVALID: return "return_invalid"; + case PM_ERR_SCRIPT_NOT_FOUND: return "script_not_found"; + case PM_ERR_SINGLETON_FOR_LITERALS: return "singleton_for_literals"; + case PM_ERR_STATEMENT_ALIAS: return "statement_alias"; + case PM_ERR_STATEMENT_POSTEXE_END: return "statement_postexe_end"; + case PM_ERR_STATEMENT_PREEXE_BEGIN: return "statement_preexe_begin"; + case PM_ERR_STATEMENT_UNDEF: return "statement_undef"; + case PM_ERR_STRING_CONCATENATION: return "string_concatenation"; + case PM_ERR_STRING_INTERPOLATED_TERM: return "string_interpolated_term"; + case PM_ERR_STRING_LITERAL_EOF: return "string_literal_eof"; + case PM_ERR_STRING_LITERAL_TERM: return "string_literal_term"; + case PM_ERR_SYMBOL_INVALID: return "symbol_invalid"; + case PM_ERR_SYMBOL_TERM_DYNAMIC: return "symbol_term_dynamic"; + case PM_ERR_SYMBOL_TERM_INTERPOLATED: return "symbol_term_interpolated"; + case PM_ERR_TERNARY_COLON: return "ternary_colon"; + case PM_ERR_TERNARY_EXPRESSION_FALSE: return "ternary_expression_false"; + case PM_ERR_TERNARY_EXPRESSION_TRUE: return "ternary_expression_true"; + case PM_ERR_UNARY_DISALLOWED: return "unary_disallowed"; + case PM_ERR_UNARY_RECEIVER: return "unary_receiver"; + case PM_ERR_UNDEF_ARGUMENT: return "undef_argument"; + case PM_ERR_UNEXPECTED_BLOCK_ARGUMENT: return "unexpected_block_argument"; + case PM_ERR_UNEXPECTED_INDEX_BLOCK: return "unexpected_index_block"; + case PM_ERR_UNEXPECTED_INDEX_KEYWORDS: return "unexpected_index_keywords"; + case PM_ERR_UNEXPECTED_LABEL: return "unexpected_label"; + case PM_ERR_UNEXPECTED_MULTI_WRITE: return "unexpected_multi_write"; + case PM_ERR_UNEXPECTED_RANGE_OPERATOR: return "unexpected_range_operator"; + case PM_ERR_UNEXPECTED_SAFE_NAVIGATION: return "unexpected_safe_navigation"; + case PM_ERR_UNEXPECTED_TOKEN_CLOSE_CONTEXT: return "unexpected_token_close_context"; + case PM_ERR_UNEXPECTED_TOKEN_IGNORE: return "unexpected_token_ignore"; + case PM_ERR_UNTIL_TERM: return "until_term"; + case PM_ERR_VOID_EXPRESSION: return "void_expression"; + case PM_ERR_WHILE_TERM: return "while_term"; + case PM_ERR_WRITE_TARGET_IN_METHOD: return "write_target_in_method"; + case PM_ERR_WRITE_TARGET_READONLY: return "write_target_readonly"; + case PM_ERR_WRITE_TARGET_UNEXPECTED: return "write_target_unexpected"; + case PM_ERR_XSTRING_TERM: return "xstring_term"; + case PM_WARN_AMBIGUOUS_BINARY_OPERATOR: return "ambiguous_binary_operator"; + case PM_WARN_AMBIGUOUS_FIRST_ARGUMENT_MINUS: return "ambiguous_first_argument_minus"; + case PM_WARN_AMBIGUOUS_FIRST_ARGUMENT_PLUS: return "ambiguous_first_argument_plus"; + case PM_WARN_AMBIGUOUS_PREFIX_AMPERSAND: return "ambiguous_prefix_ampersand"; + case PM_WARN_AMBIGUOUS_PREFIX_STAR: return "ambiguous_prefix_star"; + case PM_WARN_AMBIGUOUS_PREFIX_STAR_STAR: return "ambiguous_prefix_star_star"; + case PM_WARN_AMBIGUOUS_SLASH: return "ambiguous_slash"; + case PM_WARN_COMPARISON_AFTER_COMPARISON: return "comparison_after_comparison"; + case PM_WARN_DOT_DOT_DOT_EOL: return "dot_dot_dot_eol"; + case PM_WARN_EQUAL_IN_CONDITIONAL: return "equal_in_conditional"; + case PM_WARN_EQUAL_IN_CONDITIONAL_3_3: return "equal_in_conditional_3_3"; + case PM_WARN_END_IN_METHOD: return "end_in_method"; + case PM_WARN_DUPLICATED_HASH_KEY: return "duplicated_hash_key"; + case PM_WARN_DUPLICATED_WHEN_CLAUSE: return "duplicated_when_clause"; + case PM_WARN_FLOAT_OUT_OF_RANGE: return "float_out_of_range"; + case PM_WARN_IGNORED_FROZEN_STRING_LITERAL: return "ignored_frozen_string_literal"; + case PM_WARN_INDENTATION_MISMATCH: return "indentation_mismatch"; + case PM_WARN_INTEGER_IN_FLIP_FLOP: return "integer_in_flip_flop"; + case PM_WARN_INVALID_CHARACTER: return "invalid_character"; + case PM_WARN_INVALID_MAGIC_COMMENT_VALUE: return "invalid_magic_comment_value"; + case PM_WARN_INVALID_NUMBERED_REFERENCE: return "invalid_numbered_reference"; + case PM_WARN_KEYWORD_EOL: return "keyword_eol"; + case PM_WARN_LITERAL_IN_CONDITION_DEFAULT: return "literal_in_condition_default"; + case PM_WARN_LITERAL_IN_CONDITION_VERBOSE: return "literal_in_condition_verbose"; + case PM_WARN_SHAREABLE_CONSTANT_VALUE_LINE: return "shareable_constant_value_line"; + case PM_WARN_SHEBANG_CARRIAGE_RETURN: return "shebang_carriage_return"; + case PM_WARN_UNEXPECTED_CARRIAGE_RETURN: return "unexpected_carriage_return"; + case PM_WARN_UNREACHABLE_STATEMENT: return "unreachable_statement"; + case PM_WARN_UNUSED_LOCAL_VARIABLE: return "unused_local_variable"; + case PM_WARN_VOID_STATEMENT: return "void_statement"; + } + + assert(false && "unreachable"); + return ""; +} + +static inline const char * +pm_diagnostic_message(pm_diagnostic_id_t diag_id) { + assert(diag_id < PM_DIAGNOSTIC_ID_MAX); + + const char *message = diagnostic_messages[diag_id].message; + assert(message); + + return message; +} + +static inline uint8_t +pm_diagnostic_level(pm_diagnostic_id_t diag_id) { + assert(diag_id < PM_DIAGNOSTIC_ID_MAX); + + return (uint8_t) diagnostic_messages[diag_id].level; +} + +/** + * Append an error to the given list of diagnostic. + */ +bool +pm_diagnostic_list_append(pm_list_t *list, const uint8_t *start, const uint8_t *end, pm_diagnostic_id_t diag_id) { + pm_diagnostic_t *diagnostic = (pm_diagnostic_t *) xcalloc(1, sizeof(pm_diagnostic_t)); + if (diagnostic == NULL) return false; + + *diagnostic = (pm_diagnostic_t) { + .location = { start, end }, + .diag_id = diag_id, + .message = pm_diagnostic_message(diag_id), + .owned = false, + .level = pm_diagnostic_level(diag_id) + }; + + pm_list_append(list, (pm_list_node_t *) diagnostic); + return true; +} + +/** + * Append a diagnostic to the given list of diagnostics that is using a format + * string for its message. + */ +bool +pm_diagnostic_list_append_format(pm_list_t *list, const uint8_t *start, const uint8_t *end, pm_diagnostic_id_t diag_id, ...) { + va_list arguments; + va_start(arguments, diag_id); + + const char *format = pm_diagnostic_message(diag_id); + int result = vsnprintf(NULL, 0, format, arguments); + va_end(arguments); + + if (result < 0) { + return false; + } + + pm_diagnostic_t *diagnostic = (pm_diagnostic_t *) xcalloc(1, sizeof(pm_diagnostic_t)); + if (diagnostic == NULL) { + return false; + } + + size_t length = (size_t) (result + 1); + char *message = (char *) xmalloc(length); + if (message == NULL) { + xfree(diagnostic); + return false; + } + + va_start(arguments, diag_id); + vsnprintf(message, length, format, arguments); + va_end(arguments); + + *diagnostic = (pm_diagnostic_t) { + .location = { start, end }, + .diag_id = diag_id, + .message = message, + .owned = true, + .level = pm_diagnostic_level(diag_id) + }; + + pm_list_append(list, (pm_list_node_t *) diagnostic); + return true; +} + +/** + * Deallocate the internal state of the given diagnostic list. + */ +void +pm_diagnostic_list_free(pm_list_t *list) { + pm_diagnostic_t *node = (pm_diagnostic_t *) list->head; + + while (node != NULL) { + pm_diagnostic_t *next = (pm_diagnostic_t *) node->node.next; + + if (node->owned) xfree((void *) node->message); + xfree(node); + + node = next; + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/encoding.c b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/encoding.c new file mode 100644 index 00000000..a4aeed10 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/encoding.c @@ -0,0 +1,5235 @@ +#include "prism/encoding.h" + +typedef uint32_t pm_unicode_codepoint_t; + +#define UNICODE_ALPHA_CODEPOINTS_LENGTH 1450 +static const pm_unicode_codepoint_t unicode_alpha_codepoints[UNICODE_ALPHA_CODEPOINTS_LENGTH] = { + 0x100, 0x2C1, + 0x2C6, 0x2D1, + 0x2E0, 0x2E4, + 0x2EC, 0x2EC, + 0x2EE, 0x2EE, + 0x345, 0x345, + 0x370, 0x374, + 0x376, 0x377, + 0x37A, 0x37D, + 0x37F, 0x37F, + 0x386, 0x386, + 0x388, 0x38A, + 0x38C, 0x38C, + 0x38E, 0x3A1, + 0x3A3, 0x3F5, + 0x3F7, 0x481, + 0x48A, 0x52F, + 0x531, 0x556, + 0x559, 0x559, + 0x560, 0x588, + 0x5B0, 0x5BD, + 0x5BF, 0x5BF, + 0x5C1, 0x5C2, + 0x5C4, 0x5C5, + 0x5C7, 0x5C7, + 0x5D0, 0x5EA, + 0x5EF, 0x5F2, + 0x610, 0x61A, + 0x620, 0x657, + 0x659, 0x65F, + 0x66E, 0x6D3, + 0x6D5, 0x6DC, + 0x6E1, 0x6E8, + 0x6ED, 0x6EF, + 0x6FA, 0x6FC, + 0x6FF, 0x6FF, + 0x710, 0x73F, + 0x74D, 0x7B1, + 0x7CA, 0x7EA, + 0x7F4, 0x7F5, + 0x7FA, 0x7FA, + 0x800, 0x817, + 0x81A, 0x82C, + 0x840, 0x858, + 0x860, 0x86A, + 0x870, 0x887, + 0x889, 0x88E, + 0x8A0, 0x8C9, + 0x8D4, 0x8DF, + 0x8E3, 0x8E9, + 0x8F0, 0x93B, + 0x93D, 0x94C, + 0x94E, 0x950, + 0x955, 0x963, + 0x971, 0x983, + 0x985, 0x98C, + 0x98F, 0x990, + 0x993, 0x9A8, + 0x9AA, 0x9B0, + 0x9B2, 0x9B2, + 0x9B6, 0x9B9, + 0x9BD, 0x9C4, + 0x9C7, 0x9C8, + 0x9CB, 0x9CC, + 0x9CE, 0x9CE, + 0x9D7, 0x9D7, + 0x9DC, 0x9DD, + 0x9DF, 0x9E3, + 0x9F0, 0x9F1, + 0x9FC, 0x9FC, + 0xA01, 0xA03, + 0xA05, 0xA0A, + 0xA0F, 0xA10, + 0xA13, 0xA28, + 0xA2A, 0xA30, + 0xA32, 0xA33, + 0xA35, 0xA36, + 0xA38, 0xA39, + 0xA3E, 0xA42, + 0xA47, 0xA48, + 0xA4B, 0xA4C, + 0xA51, 0xA51, + 0xA59, 0xA5C, + 0xA5E, 0xA5E, + 0xA70, 0xA75, + 0xA81, 0xA83, + 0xA85, 0xA8D, + 0xA8F, 0xA91, + 0xA93, 0xAA8, + 0xAAA, 0xAB0, + 0xAB2, 0xAB3, + 0xAB5, 0xAB9, + 0xABD, 0xAC5, + 0xAC7, 0xAC9, + 0xACB, 0xACC, + 0xAD0, 0xAD0, + 0xAE0, 0xAE3, + 0xAF9, 0xAFC, + 0xB01, 0xB03, + 0xB05, 0xB0C, + 0xB0F, 0xB10, + 0xB13, 0xB28, + 0xB2A, 0xB30, + 0xB32, 0xB33, + 0xB35, 0xB39, + 0xB3D, 0xB44, + 0xB47, 0xB48, + 0xB4B, 0xB4C, + 0xB56, 0xB57, + 0xB5C, 0xB5D, + 0xB5F, 0xB63, + 0xB71, 0xB71, + 0xB82, 0xB83, + 0xB85, 0xB8A, + 0xB8E, 0xB90, + 0xB92, 0xB95, + 0xB99, 0xB9A, + 0xB9C, 0xB9C, + 0xB9E, 0xB9F, + 0xBA3, 0xBA4, + 0xBA8, 0xBAA, + 0xBAE, 0xBB9, + 0xBBE, 0xBC2, + 0xBC6, 0xBC8, + 0xBCA, 0xBCC, + 0xBD0, 0xBD0, + 0xBD7, 0xBD7, + 0xC00, 0xC0C, + 0xC0E, 0xC10, + 0xC12, 0xC28, + 0xC2A, 0xC39, + 0xC3D, 0xC44, + 0xC46, 0xC48, + 0xC4A, 0xC4C, + 0xC55, 0xC56, + 0xC58, 0xC5A, + 0xC5D, 0xC5D, + 0xC60, 0xC63, + 0xC80, 0xC83, + 0xC85, 0xC8C, + 0xC8E, 0xC90, + 0xC92, 0xCA8, + 0xCAA, 0xCB3, + 0xCB5, 0xCB9, + 0xCBD, 0xCC4, + 0xCC6, 0xCC8, + 0xCCA, 0xCCC, + 0xCD5, 0xCD6, + 0xCDD, 0xCDE, + 0xCE0, 0xCE3, + 0xCF1, 0xCF3, + 0xD00, 0xD0C, + 0xD0E, 0xD10, + 0xD12, 0xD3A, + 0xD3D, 0xD44, + 0xD46, 0xD48, + 0xD4A, 0xD4C, + 0xD4E, 0xD4E, + 0xD54, 0xD57, + 0xD5F, 0xD63, + 0xD7A, 0xD7F, + 0xD81, 0xD83, + 0xD85, 0xD96, + 0xD9A, 0xDB1, + 0xDB3, 0xDBB, + 0xDBD, 0xDBD, + 0xDC0, 0xDC6, + 0xDCF, 0xDD4, + 0xDD6, 0xDD6, + 0xDD8, 0xDDF, + 0xDF2, 0xDF3, + 0xE01, 0xE3A, + 0xE40, 0xE46, + 0xE4D, 0xE4D, + 0xE81, 0xE82, + 0xE84, 0xE84, + 0xE86, 0xE8A, + 0xE8C, 0xEA3, + 0xEA5, 0xEA5, + 0xEA7, 0xEB9, + 0xEBB, 0xEBD, + 0xEC0, 0xEC4, + 0xEC6, 0xEC6, + 0xECD, 0xECD, + 0xEDC, 0xEDF, + 0xF00, 0xF00, + 0xF40, 0xF47, + 0xF49, 0xF6C, + 0xF71, 0xF83, + 0xF88, 0xF97, + 0xF99, 0xFBC, + 0x1000, 0x1036, + 0x1038, 0x1038, + 0x103B, 0x103F, + 0x1050, 0x108F, + 0x109A, 0x109D, + 0x10A0, 0x10C5, + 0x10C7, 0x10C7, + 0x10CD, 0x10CD, + 0x10D0, 0x10FA, + 0x10FC, 0x1248, + 0x124A, 0x124D, + 0x1250, 0x1256, + 0x1258, 0x1258, + 0x125A, 0x125D, + 0x1260, 0x1288, + 0x128A, 0x128D, + 0x1290, 0x12B0, + 0x12B2, 0x12B5, + 0x12B8, 0x12BE, + 0x12C0, 0x12C0, + 0x12C2, 0x12C5, + 0x12C8, 0x12D6, + 0x12D8, 0x1310, + 0x1312, 0x1315, + 0x1318, 0x135A, + 0x1380, 0x138F, + 0x13A0, 0x13F5, + 0x13F8, 0x13FD, + 0x1401, 0x166C, + 0x166F, 0x167F, + 0x1681, 0x169A, + 0x16A0, 0x16EA, + 0x16EE, 0x16F8, + 0x1700, 0x1713, + 0x171F, 0x1733, + 0x1740, 0x1753, + 0x1760, 0x176C, + 0x176E, 0x1770, + 0x1772, 0x1773, + 0x1780, 0x17B3, + 0x17B6, 0x17C8, + 0x17D7, 0x17D7, + 0x17DC, 0x17DC, + 0x1820, 0x1878, + 0x1880, 0x18AA, + 0x18B0, 0x18F5, + 0x1900, 0x191E, + 0x1920, 0x192B, + 0x1930, 0x1938, + 0x1950, 0x196D, + 0x1970, 0x1974, + 0x1980, 0x19AB, + 0x19B0, 0x19C9, + 0x1A00, 0x1A1B, + 0x1A20, 0x1A5E, + 0x1A61, 0x1A74, + 0x1AA7, 0x1AA7, + 0x1ABF, 0x1AC0, + 0x1ACC, 0x1ACE, + 0x1B00, 0x1B33, + 0x1B35, 0x1B43, + 0x1B45, 0x1B4C, + 0x1B80, 0x1BA9, + 0x1BAC, 0x1BAF, + 0x1BBA, 0x1BE5, + 0x1BE7, 0x1BF1, + 0x1C00, 0x1C36, + 0x1C4D, 0x1C4F, + 0x1C5A, 0x1C7D, + 0x1C80, 0x1C88, + 0x1C90, 0x1CBA, + 0x1CBD, 0x1CBF, + 0x1CE9, 0x1CEC, + 0x1CEE, 0x1CF3, + 0x1CF5, 0x1CF6, + 0x1CFA, 0x1CFA, + 0x1D00, 0x1DBF, + 0x1DE7, 0x1DF4, + 0x1E00, 0x1F15, + 0x1F18, 0x1F1D, + 0x1F20, 0x1F45, + 0x1F48, 0x1F4D, + 0x1F50, 0x1F57, + 0x1F59, 0x1F59, + 0x1F5B, 0x1F5B, + 0x1F5D, 0x1F5D, + 0x1F5F, 0x1F7D, + 0x1F80, 0x1FB4, + 0x1FB6, 0x1FBC, + 0x1FBE, 0x1FBE, + 0x1FC2, 0x1FC4, + 0x1FC6, 0x1FCC, + 0x1FD0, 0x1FD3, + 0x1FD6, 0x1FDB, + 0x1FE0, 0x1FEC, + 0x1FF2, 0x1FF4, + 0x1FF6, 0x1FFC, + 0x2071, 0x2071, + 0x207F, 0x207F, + 0x2090, 0x209C, + 0x2102, 0x2102, + 0x2107, 0x2107, + 0x210A, 0x2113, + 0x2115, 0x2115, + 0x2119, 0x211D, + 0x2124, 0x2124, + 0x2126, 0x2126, + 0x2128, 0x2128, + 0x212A, 0x212D, + 0x212F, 0x2139, + 0x213C, 0x213F, + 0x2145, 0x2149, + 0x214E, 0x214E, + 0x2160, 0x2188, + 0x24B6, 0x24E9, + 0x2C00, 0x2CE4, + 0x2CEB, 0x2CEE, + 0x2CF2, 0x2CF3, + 0x2D00, 0x2D25, + 0x2D27, 0x2D27, + 0x2D2D, 0x2D2D, + 0x2D30, 0x2D67, + 0x2D6F, 0x2D6F, + 0x2D80, 0x2D96, + 0x2DA0, 0x2DA6, + 0x2DA8, 0x2DAE, + 0x2DB0, 0x2DB6, + 0x2DB8, 0x2DBE, + 0x2DC0, 0x2DC6, + 0x2DC8, 0x2DCE, + 0x2DD0, 0x2DD6, + 0x2DD8, 0x2DDE, + 0x2DE0, 0x2DFF, + 0x2E2F, 0x2E2F, + 0x3005, 0x3007, + 0x3021, 0x3029, + 0x3031, 0x3035, + 0x3038, 0x303C, + 0x3041, 0x3096, + 0x309D, 0x309F, + 0x30A1, 0x30FA, + 0x30FC, 0x30FF, + 0x3105, 0x312F, + 0x3131, 0x318E, + 0x31A0, 0x31BF, + 0x31F0, 0x31FF, + 0x3400, 0x4DBF, + 0x4E00, 0xA48C, + 0xA4D0, 0xA4FD, + 0xA500, 0xA60C, + 0xA610, 0xA61F, + 0xA62A, 0xA62B, + 0xA640, 0xA66E, + 0xA674, 0xA67B, + 0xA67F, 0xA6EF, + 0xA717, 0xA71F, + 0xA722, 0xA788, + 0xA78B, 0xA7CA, + 0xA7D0, 0xA7D1, + 0xA7D3, 0xA7D3, + 0xA7D5, 0xA7D9, + 0xA7F2, 0xA805, + 0xA807, 0xA827, + 0xA840, 0xA873, + 0xA880, 0xA8C3, + 0xA8C5, 0xA8C5, + 0xA8F2, 0xA8F7, + 0xA8FB, 0xA8FB, + 0xA8FD, 0xA8FF, + 0xA90A, 0xA92A, + 0xA930, 0xA952, + 0xA960, 0xA97C, + 0xA980, 0xA9B2, + 0xA9B4, 0xA9BF, + 0xA9CF, 0xA9CF, + 0xA9E0, 0xA9EF, + 0xA9FA, 0xA9FE, + 0xAA00, 0xAA36, + 0xAA40, 0xAA4D, + 0xAA60, 0xAA76, + 0xAA7A, 0xAABE, + 0xAAC0, 0xAAC0, + 0xAAC2, 0xAAC2, + 0xAADB, 0xAADD, + 0xAAE0, 0xAAEF, + 0xAAF2, 0xAAF5, + 0xAB01, 0xAB06, + 0xAB09, 0xAB0E, + 0xAB11, 0xAB16, + 0xAB20, 0xAB26, + 0xAB28, 0xAB2E, + 0xAB30, 0xAB5A, + 0xAB5C, 0xAB69, + 0xAB70, 0xABEA, + 0xAC00, 0xD7A3, + 0xD7B0, 0xD7C6, + 0xD7CB, 0xD7FB, + 0xF900, 0xFA6D, + 0xFA70, 0xFAD9, + 0xFB00, 0xFB06, + 0xFB13, 0xFB17, + 0xFB1D, 0xFB28, + 0xFB2A, 0xFB36, + 0xFB38, 0xFB3C, + 0xFB3E, 0xFB3E, + 0xFB40, 0xFB41, + 0xFB43, 0xFB44, + 0xFB46, 0xFBB1, + 0xFBD3, 0xFD3D, + 0xFD50, 0xFD8F, + 0xFD92, 0xFDC7, + 0xFDF0, 0xFDFB, + 0xFE70, 0xFE74, + 0xFE76, 0xFEFC, + 0xFF21, 0xFF3A, + 0xFF41, 0xFF5A, + 0xFF66, 0xFFBE, + 0xFFC2, 0xFFC7, + 0xFFCA, 0xFFCF, + 0xFFD2, 0xFFD7, + 0xFFDA, 0xFFDC, + 0x10000, 0x1000B, + 0x1000D, 0x10026, + 0x10028, 0x1003A, + 0x1003C, 0x1003D, + 0x1003F, 0x1004D, + 0x10050, 0x1005D, + 0x10080, 0x100FA, + 0x10140, 0x10174, + 0x10280, 0x1029C, + 0x102A0, 0x102D0, + 0x10300, 0x1031F, + 0x1032D, 0x1034A, + 0x10350, 0x1037A, + 0x10380, 0x1039D, + 0x103A0, 0x103C3, + 0x103C8, 0x103CF, + 0x103D1, 0x103D5, + 0x10400, 0x1049D, + 0x104B0, 0x104D3, + 0x104D8, 0x104FB, + 0x10500, 0x10527, + 0x10530, 0x10563, + 0x10570, 0x1057A, + 0x1057C, 0x1058A, + 0x1058C, 0x10592, + 0x10594, 0x10595, + 0x10597, 0x105A1, + 0x105A3, 0x105B1, + 0x105B3, 0x105B9, + 0x105BB, 0x105BC, + 0x10600, 0x10736, + 0x10740, 0x10755, + 0x10760, 0x10767, + 0x10780, 0x10785, + 0x10787, 0x107B0, + 0x107B2, 0x107BA, + 0x10800, 0x10805, + 0x10808, 0x10808, + 0x1080A, 0x10835, + 0x10837, 0x10838, + 0x1083C, 0x1083C, + 0x1083F, 0x10855, + 0x10860, 0x10876, + 0x10880, 0x1089E, + 0x108E0, 0x108F2, + 0x108F4, 0x108F5, + 0x10900, 0x10915, + 0x10920, 0x10939, + 0x10980, 0x109B7, + 0x109BE, 0x109BF, + 0x10A00, 0x10A03, + 0x10A05, 0x10A06, + 0x10A0C, 0x10A13, + 0x10A15, 0x10A17, + 0x10A19, 0x10A35, + 0x10A60, 0x10A7C, + 0x10A80, 0x10A9C, + 0x10AC0, 0x10AC7, + 0x10AC9, 0x10AE4, + 0x10B00, 0x10B35, + 0x10B40, 0x10B55, + 0x10B60, 0x10B72, + 0x10B80, 0x10B91, + 0x10C00, 0x10C48, + 0x10C80, 0x10CB2, + 0x10CC0, 0x10CF2, + 0x10D00, 0x10D27, + 0x10E80, 0x10EA9, + 0x10EAB, 0x10EAC, + 0x10EB0, 0x10EB1, + 0x10F00, 0x10F1C, + 0x10F27, 0x10F27, + 0x10F30, 0x10F45, + 0x10F70, 0x10F81, + 0x10FB0, 0x10FC4, + 0x10FE0, 0x10FF6, + 0x11000, 0x11045, + 0x11071, 0x11075, + 0x11080, 0x110B8, + 0x110C2, 0x110C2, + 0x110D0, 0x110E8, + 0x11100, 0x11132, + 0x11144, 0x11147, + 0x11150, 0x11172, + 0x11176, 0x11176, + 0x11180, 0x111BF, + 0x111C1, 0x111C4, + 0x111CE, 0x111CF, + 0x111DA, 0x111DA, + 0x111DC, 0x111DC, + 0x11200, 0x11211, + 0x11213, 0x11234, + 0x11237, 0x11237, + 0x1123E, 0x11241, + 0x11280, 0x11286, + 0x11288, 0x11288, + 0x1128A, 0x1128D, + 0x1128F, 0x1129D, + 0x1129F, 0x112A8, + 0x112B0, 0x112E8, + 0x11300, 0x11303, + 0x11305, 0x1130C, + 0x1130F, 0x11310, + 0x11313, 0x11328, + 0x1132A, 0x11330, + 0x11332, 0x11333, + 0x11335, 0x11339, + 0x1133D, 0x11344, + 0x11347, 0x11348, + 0x1134B, 0x1134C, + 0x11350, 0x11350, + 0x11357, 0x11357, + 0x1135D, 0x11363, + 0x11400, 0x11441, + 0x11443, 0x11445, + 0x11447, 0x1144A, + 0x1145F, 0x11461, + 0x11480, 0x114C1, + 0x114C4, 0x114C5, + 0x114C7, 0x114C7, + 0x11580, 0x115B5, + 0x115B8, 0x115BE, + 0x115D8, 0x115DD, + 0x11600, 0x1163E, + 0x11640, 0x11640, + 0x11644, 0x11644, + 0x11680, 0x116B5, + 0x116B8, 0x116B8, + 0x11700, 0x1171A, + 0x1171D, 0x1172A, + 0x11740, 0x11746, + 0x11800, 0x11838, + 0x118A0, 0x118DF, + 0x118FF, 0x11906, + 0x11909, 0x11909, + 0x1190C, 0x11913, + 0x11915, 0x11916, + 0x11918, 0x11935, + 0x11937, 0x11938, + 0x1193B, 0x1193C, + 0x1193F, 0x11942, + 0x119A0, 0x119A7, + 0x119AA, 0x119D7, + 0x119DA, 0x119DF, + 0x119E1, 0x119E1, + 0x119E3, 0x119E4, + 0x11A00, 0x11A32, + 0x11A35, 0x11A3E, + 0x11A50, 0x11A97, + 0x11A9D, 0x11A9D, + 0x11AB0, 0x11AF8, + 0x11C00, 0x11C08, + 0x11C0A, 0x11C36, + 0x11C38, 0x11C3E, + 0x11C40, 0x11C40, + 0x11C72, 0x11C8F, + 0x11C92, 0x11CA7, + 0x11CA9, 0x11CB6, + 0x11D00, 0x11D06, + 0x11D08, 0x11D09, + 0x11D0B, 0x11D36, + 0x11D3A, 0x11D3A, + 0x11D3C, 0x11D3D, + 0x11D3F, 0x11D41, + 0x11D43, 0x11D43, + 0x11D46, 0x11D47, + 0x11D60, 0x11D65, + 0x11D67, 0x11D68, + 0x11D6A, 0x11D8E, + 0x11D90, 0x11D91, + 0x11D93, 0x11D96, + 0x11D98, 0x11D98, + 0x11EE0, 0x11EF6, + 0x11F00, 0x11F10, + 0x11F12, 0x11F3A, + 0x11F3E, 0x11F40, + 0x11FB0, 0x11FB0, + 0x12000, 0x12399, + 0x12400, 0x1246E, + 0x12480, 0x12543, + 0x12F90, 0x12FF0, + 0x13000, 0x1342F, + 0x13441, 0x13446, + 0x14400, 0x14646, + 0x16800, 0x16A38, + 0x16A40, 0x16A5E, + 0x16A70, 0x16ABE, + 0x16AD0, 0x16AED, + 0x16B00, 0x16B2F, + 0x16B40, 0x16B43, + 0x16B63, 0x16B77, + 0x16B7D, 0x16B8F, + 0x16E40, 0x16E7F, + 0x16F00, 0x16F4A, + 0x16F4F, 0x16F87, + 0x16F8F, 0x16F9F, + 0x16FE0, 0x16FE1, + 0x16FE3, 0x16FE3, + 0x16FF0, 0x16FF1, + 0x17000, 0x187F7, + 0x18800, 0x18CD5, + 0x18D00, 0x18D08, + 0x1AFF0, 0x1AFF3, + 0x1AFF5, 0x1AFFB, + 0x1AFFD, 0x1AFFE, + 0x1B000, 0x1B122, + 0x1B132, 0x1B132, + 0x1B150, 0x1B152, + 0x1B155, 0x1B155, + 0x1B164, 0x1B167, + 0x1B170, 0x1B2FB, + 0x1BC00, 0x1BC6A, + 0x1BC70, 0x1BC7C, + 0x1BC80, 0x1BC88, + 0x1BC90, 0x1BC99, + 0x1BC9E, 0x1BC9E, + 0x1D400, 0x1D454, + 0x1D456, 0x1D49C, + 0x1D49E, 0x1D49F, + 0x1D4A2, 0x1D4A2, + 0x1D4A5, 0x1D4A6, + 0x1D4A9, 0x1D4AC, + 0x1D4AE, 0x1D4B9, + 0x1D4BB, 0x1D4BB, + 0x1D4BD, 0x1D4C3, + 0x1D4C5, 0x1D505, + 0x1D507, 0x1D50A, + 0x1D50D, 0x1D514, + 0x1D516, 0x1D51C, + 0x1D51E, 0x1D539, + 0x1D53B, 0x1D53E, + 0x1D540, 0x1D544, + 0x1D546, 0x1D546, + 0x1D54A, 0x1D550, + 0x1D552, 0x1D6A5, + 0x1D6A8, 0x1D6C0, + 0x1D6C2, 0x1D6DA, + 0x1D6DC, 0x1D6FA, + 0x1D6FC, 0x1D714, + 0x1D716, 0x1D734, + 0x1D736, 0x1D74E, + 0x1D750, 0x1D76E, + 0x1D770, 0x1D788, + 0x1D78A, 0x1D7A8, + 0x1D7AA, 0x1D7C2, + 0x1D7C4, 0x1D7CB, + 0x1DF00, 0x1DF1E, + 0x1DF25, 0x1DF2A, + 0x1E000, 0x1E006, + 0x1E008, 0x1E018, + 0x1E01B, 0x1E021, + 0x1E023, 0x1E024, + 0x1E026, 0x1E02A, + 0x1E030, 0x1E06D, + 0x1E08F, 0x1E08F, + 0x1E100, 0x1E12C, + 0x1E137, 0x1E13D, + 0x1E14E, 0x1E14E, + 0x1E290, 0x1E2AD, + 0x1E2C0, 0x1E2EB, + 0x1E4D0, 0x1E4EB, + 0x1E7E0, 0x1E7E6, + 0x1E7E8, 0x1E7EB, + 0x1E7ED, 0x1E7EE, + 0x1E7F0, 0x1E7FE, + 0x1E800, 0x1E8C4, + 0x1E900, 0x1E943, + 0x1E947, 0x1E947, + 0x1E94B, 0x1E94B, + 0x1EE00, 0x1EE03, + 0x1EE05, 0x1EE1F, + 0x1EE21, 0x1EE22, + 0x1EE24, 0x1EE24, + 0x1EE27, 0x1EE27, + 0x1EE29, 0x1EE32, + 0x1EE34, 0x1EE37, + 0x1EE39, 0x1EE39, + 0x1EE3B, 0x1EE3B, + 0x1EE42, 0x1EE42, + 0x1EE47, 0x1EE47, + 0x1EE49, 0x1EE49, + 0x1EE4B, 0x1EE4B, + 0x1EE4D, 0x1EE4F, + 0x1EE51, 0x1EE52, + 0x1EE54, 0x1EE54, + 0x1EE57, 0x1EE57, + 0x1EE59, 0x1EE59, + 0x1EE5B, 0x1EE5B, + 0x1EE5D, 0x1EE5D, + 0x1EE5F, 0x1EE5F, + 0x1EE61, 0x1EE62, + 0x1EE64, 0x1EE64, + 0x1EE67, 0x1EE6A, + 0x1EE6C, 0x1EE72, + 0x1EE74, 0x1EE77, + 0x1EE79, 0x1EE7C, + 0x1EE7E, 0x1EE7E, + 0x1EE80, 0x1EE89, + 0x1EE8B, 0x1EE9B, + 0x1EEA1, 0x1EEA3, + 0x1EEA5, 0x1EEA9, + 0x1EEAB, 0x1EEBB, + 0x1F130, 0x1F149, + 0x1F150, 0x1F169, + 0x1F170, 0x1F189, + 0x20000, 0x2A6DF, + 0x2A700, 0x2B739, + 0x2B740, 0x2B81D, + 0x2B820, 0x2CEA1, + 0x2CEB0, 0x2EBE0, + 0x2F800, 0x2FA1D, + 0x30000, 0x3134A, + 0x31350, 0x323AF, +}; + +#define UNICODE_ALNUM_CODEPOINTS_LENGTH 1528 +static const pm_unicode_codepoint_t unicode_alnum_codepoints[UNICODE_ALNUM_CODEPOINTS_LENGTH] = { + 0x100, 0x2C1, + 0x2C6, 0x2D1, + 0x2E0, 0x2E4, + 0x2EC, 0x2EC, + 0x2EE, 0x2EE, + 0x345, 0x345, + 0x370, 0x374, + 0x376, 0x377, + 0x37A, 0x37D, + 0x37F, 0x37F, + 0x386, 0x386, + 0x388, 0x38A, + 0x38C, 0x38C, + 0x38E, 0x3A1, + 0x3A3, 0x3F5, + 0x3F7, 0x481, + 0x48A, 0x52F, + 0x531, 0x556, + 0x559, 0x559, + 0x560, 0x588, + 0x5B0, 0x5BD, + 0x5BF, 0x5BF, + 0x5C1, 0x5C2, + 0x5C4, 0x5C5, + 0x5C7, 0x5C7, + 0x5D0, 0x5EA, + 0x5EF, 0x5F2, + 0x610, 0x61A, + 0x620, 0x657, + 0x659, 0x669, + 0x66E, 0x6D3, + 0x6D5, 0x6DC, + 0x6E1, 0x6E8, + 0x6ED, 0x6FC, + 0x6FF, 0x6FF, + 0x710, 0x73F, + 0x74D, 0x7B1, + 0x7C0, 0x7EA, + 0x7F4, 0x7F5, + 0x7FA, 0x7FA, + 0x800, 0x817, + 0x81A, 0x82C, + 0x840, 0x858, + 0x860, 0x86A, + 0x870, 0x887, + 0x889, 0x88E, + 0x8A0, 0x8C9, + 0x8D4, 0x8DF, + 0x8E3, 0x8E9, + 0x8F0, 0x93B, + 0x93D, 0x94C, + 0x94E, 0x950, + 0x955, 0x963, + 0x966, 0x96F, + 0x971, 0x983, + 0x985, 0x98C, + 0x98F, 0x990, + 0x993, 0x9A8, + 0x9AA, 0x9B0, + 0x9B2, 0x9B2, + 0x9B6, 0x9B9, + 0x9BD, 0x9C4, + 0x9C7, 0x9C8, + 0x9CB, 0x9CC, + 0x9CE, 0x9CE, + 0x9D7, 0x9D7, + 0x9DC, 0x9DD, + 0x9DF, 0x9E3, + 0x9E6, 0x9F1, + 0x9FC, 0x9FC, + 0xA01, 0xA03, + 0xA05, 0xA0A, + 0xA0F, 0xA10, + 0xA13, 0xA28, + 0xA2A, 0xA30, + 0xA32, 0xA33, + 0xA35, 0xA36, + 0xA38, 0xA39, + 0xA3E, 0xA42, + 0xA47, 0xA48, + 0xA4B, 0xA4C, + 0xA51, 0xA51, + 0xA59, 0xA5C, + 0xA5E, 0xA5E, + 0xA66, 0xA75, + 0xA81, 0xA83, + 0xA85, 0xA8D, + 0xA8F, 0xA91, + 0xA93, 0xAA8, + 0xAAA, 0xAB0, + 0xAB2, 0xAB3, + 0xAB5, 0xAB9, + 0xABD, 0xAC5, + 0xAC7, 0xAC9, + 0xACB, 0xACC, + 0xAD0, 0xAD0, + 0xAE0, 0xAE3, + 0xAE6, 0xAEF, + 0xAF9, 0xAFC, + 0xB01, 0xB03, + 0xB05, 0xB0C, + 0xB0F, 0xB10, + 0xB13, 0xB28, + 0xB2A, 0xB30, + 0xB32, 0xB33, + 0xB35, 0xB39, + 0xB3D, 0xB44, + 0xB47, 0xB48, + 0xB4B, 0xB4C, + 0xB56, 0xB57, + 0xB5C, 0xB5D, + 0xB5F, 0xB63, + 0xB66, 0xB6F, + 0xB71, 0xB71, + 0xB82, 0xB83, + 0xB85, 0xB8A, + 0xB8E, 0xB90, + 0xB92, 0xB95, + 0xB99, 0xB9A, + 0xB9C, 0xB9C, + 0xB9E, 0xB9F, + 0xBA3, 0xBA4, + 0xBA8, 0xBAA, + 0xBAE, 0xBB9, + 0xBBE, 0xBC2, + 0xBC6, 0xBC8, + 0xBCA, 0xBCC, + 0xBD0, 0xBD0, + 0xBD7, 0xBD7, + 0xBE6, 0xBEF, + 0xC00, 0xC0C, + 0xC0E, 0xC10, + 0xC12, 0xC28, + 0xC2A, 0xC39, + 0xC3D, 0xC44, + 0xC46, 0xC48, + 0xC4A, 0xC4C, + 0xC55, 0xC56, + 0xC58, 0xC5A, + 0xC5D, 0xC5D, + 0xC60, 0xC63, + 0xC66, 0xC6F, + 0xC80, 0xC83, + 0xC85, 0xC8C, + 0xC8E, 0xC90, + 0xC92, 0xCA8, + 0xCAA, 0xCB3, + 0xCB5, 0xCB9, + 0xCBD, 0xCC4, + 0xCC6, 0xCC8, + 0xCCA, 0xCCC, + 0xCD5, 0xCD6, + 0xCDD, 0xCDE, + 0xCE0, 0xCE3, + 0xCE6, 0xCEF, + 0xCF1, 0xCF3, + 0xD00, 0xD0C, + 0xD0E, 0xD10, + 0xD12, 0xD3A, + 0xD3D, 0xD44, + 0xD46, 0xD48, + 0xD4A, 0xD4C, + 0xD4E, 0xD4E, + 0xD54, 0xD57, + 0xD5F, 0xD63, + 0xD66, 0xD6F, + 0xD7A, 0xD7F, + 0xD81, 0xD83, + 0xD85, 0xD96, + 0xD9A, 0xDB1, + 0xDB3, 0xDBB, + 0xDBD, 0xDBD, + 0xDC0, 0xDC6, + 0xDCF, 0xDD4, + 0xDD6, 0xDD6, + 0xDD8, 0xDDF, + 0xDE6, 0xDEF, + 0xDF2, 0xDF3, + 0xE01, 0xE3A, + 0xE40, 0xE46, + 0xE4D, 0xE4D, + 0xE50, 0xE59, + 0xE81, 0xE82, + 0xE84, 0xE84, + 0xE86, 0xE8A, + 0xE8C, 0xEA3, + 0xEA5, 0xEA5, + 0xEA7, 0xEB9, + 0xEBB, 0xEBD, + 0xEC0, 0xEC4, + 0xEC6, 0xEC6, + 0xECD, 0xECD, + 0xED0, 0xED9, + 0xEDC, 0xEDF, + 0xF00, 0xF00, + 0xF20, 0xF29, + 0xF40, 0xF47, + 0xF49, 0xF6C, + 0xF71, 0xF83, + 0xF88, 0xF97, + 0xF99, 0xFBC, + 0x1000, 0x1036, + 0x1038, 0x1038, + 0x103B, 0x1049, + 0x1050, 0x109D, + 0x10A0, 0x10C5, + 0x10C7, 0x10C7, + 0x10CD, 0x10CD, + 0x10D0, 0x10FA, + 0x10FC, 0x1248, + 0x124A, 0x124D, + 0x1250, 0x1256, + 0x1258, 0x1258, + 0x125A, 0x125D, + 0x1260, 0x1288, + 0x128A, 0x128D, + 0x1290, 0x12B0, + 0x12B2, 0x12B5, + 0x12B8, 0x12BE, + 0x12C0, 0x12C0, + 0x12C2, 0x12C5, + 0x12C8, 0x12D6, + 0x12D8, 0x1310, + 0x1312, 0x1315, + 0x1318, 0x135A, + 0x1380, 0x138F, + 0x13A0, 0x13F5, + 0x13F8, 0x13FD, + 0x1401, 0x166C, + 0x166F, 0x167F, + 0x1681, 0x169A, + 0x16A0, 0x16EA, + 0x16EE, 0x16F8, + 0x1700, 0x1713, + 0x171F, 0x1733, + 0x1740, 0x1753, + 0x1760, 0x176C, + 0x176E, 0x1770, + 0x1772, 0x1773, + 0x1780, 0x17B3, + 0x17B6, 0x17C8, + 0x17D7, 0x17D7, + 0x17DC, 0x17DC, + 0x17E0, 0x17E9, + 0x1810, 0x1819, + 0x1820, 0x1878, + 0x1880, 0x18AA, + 0x18B0, 0x18F5, + 0x1900, 0x191E, + 0x1920, 0x192B, + 0x1930, 0x1938, + 0x1946, 0x196D, + 0x1970, 0x1974, + 0x1980, 0x19AB, + 0x19B0, 0x19C9, + 0x19D0, 0x19D9, + 0x1A00, 0x1A1B, + 0x1A20, 0x1A5E, + 0x1A61, 0x1A74, + 0x1A80, 0x1A89, + 0x1A90, 0x1A99, + 0x1AA7, 0x1AA7, + 0x1ABF, 0x1AC0, + 0x1ACC, 0x1ACE, + 0x1B00, 0x1B33, + 0x1B35, 0x1B43, + 0x1B45, 0x1B4C, + 0x1B50, 0x1B59, + 0x1B80, 0x1BA9, + 0x1BAC, 0x1BE5, + 0x1BE7, 0x1BF1, + 0x1C00, 0x1C36, + 0x1C40, 0x1C49, + 0x1C4D, 0x1C7D, + 0x1C80, 0x1C88, + 0x1C90, 0x1CBA, + 0x1CBD, 0x1CBF, + 0x1CE9, 0x1CEC, + 0x1CEE, 0x1CF3, + 0x1CF5, 0x1CF6, + 0x1CFA, 0x1CFA, + 0x1D00, 0x1DBF, + 0x1DE7, 0x1DF4, + 0x1E00, 0x1F15, + 0x1F18, 0x1F1D, + 0x1F20, 0x1F45, + 0x1F48, 0x1F4D, + 0x1F50, 0x1F57, + 0x1F59, 0x1F59, + 0x1F5B, 0x1F5B, + 0x1F5D, 0x1F5D, + 0x1F5F, 0x1F7D, + 0x1F80, 0x1FB4, + 0x1FB6, 0x1FBC, + 0x1FBE, 0x1FBE, + 0x1FC2, 0x1FC4, + 0x1FC6, 0x1FCC, + 0x1FD0, 0x1FD3, + 0x1FD6, 0x1FDB, + 0x1FE0, 0x1FEC, + 0x1FF2, 0x1FF4, + 0x1FF6, 0x1FFC, + 0x2071, 0x2071, + 0x207F, 0x207F, + 0x2090, 0x209C, + 0x2102, 0x2102, + 0x2107, 0x2107, + 0x210A, 0x2113, + 0x2115, 0x2115, + 0x2119, 0x211D, + 0x2124, 0x2124, + 0x2126, 0x2126, + 0x2128, 0x2128, + 0x212A, 0x212D, + 0x212F, 0x2139, + 0x213C, 0x213F, + 0x2145, 0x2149, + 0x214E, 0x214E, + 0x2160, 0x2188, + 0x24B6, 0x24E9, + 0x2C00, 0x2CE4, + 0x2CEB, 0x2CEE, + 0x2CF2, 0x2CF3, + 0x2D00, 0x2D25, + 0x2D27, 0x2D27, + 0x2D2D, 0x2D2D, + 0x2D30, 0x2D67, + 0x2D6F, 0x2D6F, + 0x2D80, 0x2D96, + 0x2DA0, 0x2DA6, + 0x2DA8, 0x2DAE, + 0x2DB0, 0x2DB6, + 0x2DB8, 0x2DBE, + 0x2DC0, 0x2DC6, + 0x2DC8, 0x2DCE, + 0x2DD0, 0x2DD6, + 0x2DD8, 0x2DDE, + 0x2DE0, 0x2DFF, + 0x2E2F, 0x2E2F, + 0x3005, 0x3007, + 0x3021, 0x3029, + 0x3031, 0x3035, + 0x3038, 0x303C, + 0x3041, 0x3096, + 0x309D, 0x309F, + 0x30A1, 0x30FA, + 0x30FC, 0x30FF, + 0x3105, 0x312F, + 0x3131, 0x318E, + 0x31A0, 0x31BF, + 0x31F0, 0x31FF, + 0x3400, 0x4DBF, + 0x4E00, 0xA48C, + 0xA4D0, 0xA4FD, + 0xA500, 0xA60C, + 0xA610, 0xA62B, + 0xA640, 0xA66E, + 0xA674, 0xA67B, + 0xA67F, 0xA6EF, + 0xA717, 0xA71F, + 0xA722, 0xA788, + 0xA78B, 0xA7CA, + 0xA7D0, 0xA7D1, + 0xA7D3, 0xA7D3, + 0xA7D5, 0xA7D9, + 0xA7F2, 0xA805, + 0xA807, 0xA827, + 0xA840, 0xA873, + 0xA880, 0xA8C3, + 0xA8C5, 0xA8C5, + 0xA8D0, 0xA8D9, + 0xA8F2, 0xA8F7, + 0xA8FB, 0xA8FB, + 0xA8FD, 0xA92A, + 0xA930, 0xA952, + 0xA960, 0xA97C, + 0xA980, 0xA9B2, + 0xA9B4, 0xA9BF, + 0xA9CF, 0xA9D9, + 0xA9E0, 0xA9FE, + 0xAA00, 0xAA36, + 0xAA40, 0xAA4D, + 0xAA50, 0xAA59, + 0xAA60, 0xAA76, + 0xAA7A, 0xAABE, + 0xAAC0, 0xAAC0, + 0xAAC2, 0xAAC2, + 0xAADB, 0xAADD, + 0xAAE0, 0xAAEF, + 0xAAF2, 0xAAF5, + 0xAB01, 0xAB06, + 0xAB09, 0xAB0E, + 0xAB11, 0xAB16, + 0xAB20, 0xAB26, + 0xAB28, 0xAB2E, + 0xAB30, 0xAB5A, + 0xAB5C, 0xAB69, + 0xAB70, 0xABEA, + 0xABF0, 0xABF9, + 0xAC00, 0xD7A3, + 0xD7B0, 0xD7C6, + 0xD7CB, 0xD7FB, + 0xF900, 0xFA6D, + 0xFA70, 0xFAD9, + 0xFB00, 0xFB06, + 0xFB13, 0xFB17, + 0xFB1D, 0xFB28, + 0xFB2A, 0xFB36, + 0xFB38, 0xFB3C, + 0xFB3E, 0xFB3E, + 0xFB40, 0xFB41, + 0xFB43, 0xFB44, + 0xFB46, 0xFBB1, + 0xFBD3, 0xFD3D, + 0xFD50, 0xFD8F, + 0xFD92, 0xFDC7, + 0xFDF0, 0xFDFB, + 0xFE70, 0xFE74, + 0xFE76, 0xFEFC, + 0xFF10, 0xFF19, + 0xFF21, 0xFF3A, + 0xFF41, 0xFF5A, + 0xFF66, 0xFFBE, + 0xFFC2, 0xFFC7, + 0xFFCA, 0xFFCF, + 0xFFD2, 0xFFD7, + 0xFFDA, 0xFFDC, + 0x10000, 0x1000B, + 0x1000D, 0x10026, + 0x10028, 0x1003A, + 0x1003C, 0x1003D, + 0x1003F, 0x1004D, + 0x10050, 0x1005D, + 0x10080, 0x100FA, + 0x10140, 0x10174, + 0x10280, 0x1029C, + 0x102A0, 0x102D0, + 0x10300, 0x1031F, + 0x1032D, 0x1034A, + 0x10350, 0x1037A, + 0x10380, 0x1039D, + 0x103A0, 0x103C3, + 0x103C8, 0x103CF, + 0x103D1, 0x103D5, + 0x10400, 0x1049D, + 0x104A0, 0x104A9, + 0x104B0, 0x104D3, + 0x104D8, 0x104FB, + 0x10500, 0x10527, + 0x10530, 0x10563, + 0x10570, 0x1057A, + 0x1057C, 0x1058A, + 0x1058C, 0x10592, + 0x10594, 0x10595, + 0x10597, 0x105A1, + 0x105A3, 0x105B1, + 0x105B3, 0x105B9, + 0x105BB, 0x105BC, + 0x10600, 0x10736, + 0x10740, 0x10755, + 0x10760, 0x10767, + 0x10780, 0x10785, + 0x10787, 0x107B0, + 0x107B2, 0x107BA, + 0x10800, 0x10805, + 0x10808, 0x10808, + 0x1080A, 0x10835, + 0x10837, 0x10838, + 0x1083C, 0x1083C, + 0x1083F, 0x10855, + 0x10860, 0x10876, + 0x10880, 0x1089E, + 0x108E0, 0x108F2, + 0x108F4, 0x108F5, + 0x10900, 0x10915, + 0x10920, 0x10939, + 0x10980, 0x109B7, + 0x109BE, 0x109BF, + 0x10A00, 0x10A03, + 0x10A05, 0x10A06, + 0x10A0C, 0x10A13, + 0x10A15, 0x10A17, + 0x10A19, 0x10A35, + 0x10A60, 0x10A7C, + 0x10A80, 0x10A9C, + 0x10AC0, 0x10AC7, + 0x10AC9, 0x10AE4, + 0x10B00, 0x10B35, + 0x10B40, 0x10B55, + 0x10B60, 0x10B72, + 0x10B80, 0x10B91, + 0x10C00, 0x10C48, + 0x10C80, 0x10CB2, + 0x10CC0, 0x10CF2, + 0x10D00, 0x10D27, + 0x10D30, 0x10D39, + 0x10E80, 0x10EA9, + 0x10EAB, 0x10EAC, + 0x10EB0, 0x10EB1, + 0x10F00, 0x10F1C, + 0x10F27, 0x10F27, + 0x10F30, 0x10F45, + 0x10F70, 0x10F81, + 0x10FB0, 0x10FC4, + 0x10FE0, 0x10FF6, + 0x11000, 0x11045, + 0x11066, 0x1106F, + 0x11071, 0x11075, + 0x11080, 0x110B8, + 0x110C2, 0x110C2, + 0x110D0, 0x110E8, + 0x110F0, 0x110F9, + 0x11100, 0x11132, + 0x11136, 0x1113F, + 0x11144, 0x11147, + 0x11150, 0x11172, + 0x11176, 0x11176, + 0x11180, 0x111BF, + 0x111C1, 0x111C4, + 0x111CE, 0x111DA, + 0x111DC, 0x111DC, + 0x11200, 0x11211, + 0x11213, 0x11234, + 0x11237, 0x11237, + 0x1123E, 0x11241, + 0x11280, 0x11286, + 0x11288, 0x11288, + 0x1128A, 0x1128D, + 0x1128F, 0x1129D, + 0x1129F, 0x112A8, + 0x112B0, 0x112E8, + 0x112F0, 0x112F9, + 0x11300, 0x11303, + 0x11305, 0x1130C, + 0x1130F, 0x11310, + 0x11313, 0x11328, + 0x1132A, 0x11330, + 0x11332, 0x11333, + 0x11335, 0x11339, + 0x1133D, 0x11344, + 0x11347, 0x11348, + 0x1134B, 0x1134C, + 0x11350, 0x11350, + 0x11357, 0x11357, + 0x1135D, 0x11363, + 0x11400, 0x11441, + 0x11443, 0x11445, + 0x11447, 0x1144A, + 0x11450, 0x11459, + 0x1145F, 0x11461, + 0x11480, 0x114C1, + 0x114C4, 0x114C5, + 0x114C7, 0x114C7, + 0x114D0, 0x114D9, + 0x11580, 0x115B5, + 0x115B8, 0x115BE, + 0x115D8, 0x115DD, + 0x11600, 0x1163E, + 0x11640, 0x11640, + 0x11644, 0x11644, + 0x11650, 0x11659, + 0x11680, 0x116B5, + 0x116B8, 0x116B8, + 0x116C0, 0x116C9, + 0x11700, 0x1171A, + 0x1171D, 0x1172A, + 0x11730, 0x11739, + 0x11740, 0x11746, + 0x11800, 0x11838, + 0x118A0, 0x118E9, + 0x118FF, 0x11906, + 0x11909, 0x11909, + 0x1190C, 0x11913, + 0x11915, 0x11916, + 0x11918, 0x11935, + 0x11937, 0x11938, + 0x1193B, 0x1193C, + 0x1193F, 0x11942, + 0x11950, 0x11959, + 0x119A0, 0x119A7, + 0x119AA, 0x119D7, + 0x119DA, 0x119DF, + 0x119E1, 0x119E1, + 0x119E3, 0x119E4, + 0x11A00, 0x11A32, + 0x11A35, 0x11A3E, + 0x11A50, 0x11A97, + 0x11A9D, 0x11A9D, + 0x11AB0, 0x11AF8, + 0x11C00, 0x11C08, + 0x11C0A, 0x11C36, + 0x11C38, 0x11C3E, + 0x11C40, 0x11C40, + 0x11C50, 0x11C59, + 0x11C72, 0x11C8F, + 0x11C92, 0x11CA7, + 0x11CA9, 0x11CB6, + 0x11D00, 0x11D06, + 0x11D08, 0x11D09, + 0x11D0B, 0x11D36, + 0x11D3A, 0x11D3A, + 0x11D3C, 0x11D3D, + 0x11D3F, 0x11D41, + 0x11D43, 0x11D43, + 0x11D46, 0x11D47, + 0x11D50, 0x11D59, + 0x11D60, 0x11D65, + 0x11D67, 0x11D68, + 0x11D6A, 0x11D8E, + 0x11D90, 0x11D91, + 0x11D93, 0x11D96, + 0x11D98, 0x11D98, + 0x11DA0, 0x11DA9, + 0x11EE0, 0x11EF6, + 0x11F00, 0x11F10, + 0x11F12, 0x11F3A, + 0x11F3E, 0x11F40, + 0x11F50, 0x11F59, + 0x11FB0, 0x11FB0, + 0x12000, 0x12399, + 0x12400, 0x1246E, + 0x12480, 0x12543, + 0x12F90, 0x12FF0, + 0x13000, 0x1342F, + 0x13441, 0x13446, + 0x14400, 0x14646, + 0x16800, 0x16A38, + 0x16A40, 0x16A5E, + 0x16A60, 0x16A69, + 0x16A70, 0x16ABE, + 0x16AC0, 0x16AC9, + 0x16AD0, 0x16AED, + 0x16B00, 0x16B2F, + 0x16B40, 0x16B43, + 0x16B50, 0x16B59, + 0x16B63, 0x16B77, + 0x16B7D, 0x16B8F, + 0x16E40, 0x16E7F, + 0x16F00, 0x16F4A, + 0x16F4F, 0x16F87, + 0x16F8F, 0x16F9F, + 0x16FE0, 0x16FE1, + 0x16FE3, 0x16FE3, + 0x16FF0, 0x16FF1, + 0x17000, 0x187F7, + 0x18800, 0x18CD5, + 0x18D00, 0x18D08, + 0x1AFF0, 0x1AFF3, + 0x1AFF5, 0x1AFFB, + 0x1AFFD, 0x1AFFE, + 0x1B000, 0x1B122, + 0x1B132, 0x1B132, + 0x1B150, 0x1B152, + 0x1B155, 0x1B155, + 0x1B164, 0x1B167, + 0x1B170, 0x1B2FB, + 0x1BC00, 0x1BC6A, + 0x1BC70, 0x1BC7C, + 0x1BC80, 0x1BC88, + 0x1BC90, 0x1BC99, + 0x1BC9E, 0x1BC9E, + 0x1D400, 0x1D454, + 0x1D456, 0x1D49C, + 0x1D49E, 0x1D49F, + 0x1D4A2, 0x1D4A2, + 0x1D4A5, 0x1D4A6, + 0x1D4A9, 0x1D4AC, + 0x1D4AE, 0x1D4B9, + 0x1D4BB, 0x1D4BB, + 0x1D4BD, 0x1D4C3, + 0x1D4C5, 0x1D505, + 0x1D507, 0x1D50A, + 0x1D50D, 0x1D514, + 0x1D516, 0x1D51C, + 0x1D51E, 0x1D539, + 0x1D53B, 0x1D53E, + 0x1D540, 0x1D544, + 0x1D546, 0x1D546, + 0x1D54A, 0x1D550, + 0x1D552, 0x1D6A5, + 0x1D6A8, 0x1D6C0, + 0x1D6C2, 0x1D6DA, + 0x1D6DC, 0x1D6FA, + 0x1D6FC, 0x1D714, + 0x1D716, 0x1D734, + 0x1D736, 0x1D74E, + 0x1D750, 0x1D76E, + 0x1D770, 0x1D788, + 0x1D78A, 0x1D7A8, + 0x1D7AA, 0x1D7C2, + 0x1D7C4, 0x1D7CB, + 0x1D7CE, 0x1D7FF, + 0x1DF00, 0x1DF1E, + 0x1DF25, 0x1DF2A, + 0x1E000, 0x1E006, + 0x1E008, 0x1E018, + 0x1E01B, 0x1E021, + 0x1E023, 0x1E024, + 0x1E026, 0x1E02A, + 0x1E030, 0x1E06D, + 0x1E08F, 0x1E08F, + 0x1E100, 0x1E12C, + 0x1E137, 0x1E13D, + 0x1E140, 0x1E149, + 0x1E14E, 0x1E14E, + 0x1E290, 0x1E2AD, + 0x1E2C0, 0x1E2EB, + 0x1E2F0, 0x1E2F9, + 0x1E4D0, 0x1E4EB, + 0x1E4F0, 0x1E4F9, + 0x1E7E0, 0x1E7E6, + 0x1E7E8, 0x1E7EB, + 0x1E7ED, 0x1E7EE, + 0x1E7F0, 0x1E7FE, + 0x1E800, 0x1E8C4, + 0x1E900, 0x1E943, + 0x1E947, 0x1E947, + 0x1E94B, 0x1E94B, + 0x1E950, 0x1E959, + 0x1EE00, 0x1EE03, + 0x1EE05, 0x1EE1F, + 0x1EE21, 0x1EE22, + 0x1EE24, 0x1EE24, + 0x1EE27, 0x1EE27, + 0x1EE29, 0x1EE32, + 0x1EE34, 0x1EE37, + 0x1EE39, 0x1EE39, + 0x1EE3B, 0x1EE3B, + 0x1EE42, 0x1EE42, + 0x1EE47, 0x1EE47, + 0x1EE49, 0x1EE49, + 0x1EE4B, 0x1EE4B, + 0x1EE4D, 0x1EE4F, + 0x1EE51, 0x1EE52, + 0x1EE54, 0x1EE54, + 0x1EE57, 0x1EE57, + 0x1EE59, 0x1EE59, + 0x1EE5B, 0x1EE5B, + 0x1EE5D, 0x1EE5D, + 0x1EE5F, 0x1EE5F, + 0x1EE61, 0x1EE62, + 0x1EE64, 0x1EE64, + 0x1EE67, 0x1EE6A, + 0x1EE6C, 0x1EE72, + 0x1EE74, 0x1EE77, + 0x1EE79, 0x1EE7C, + 0x1EE7E, 0x1EE7E, + 0x1EE80, 0x1EE89, + 0x1EE8B, 0x1EE9B, + 0x1EEA1, 0x1EEA3, + 0x1EEA5, 0x1EEA9, + 0x1EEAB, 0x1EEBB, + 0x1F130, 0x1F149, + 0x1F150, 0x1F169, + 0x1F170, 0x1F189, + 0x1FBF0, 0x1FBF9, + 0x20000, 0x2A6DF, + 0x2A700, 0x2B739, + 0x2B740, 0x2B81D, + 0x2B820, 0x2CEA1, + 0x2CEB0, 0x2EBE0, + 0x2F800, 0x2FA1D, + 0x30000, 0x3134A, + 0x31350, 0x323AF, +}; + +#define UNICODE_ISUPPER_CODEPOINTS_LENGTH 1302 +static const pm_unicode_codepoint_t unicode_isupper_codepoints[UNICODE_ISUPPER_CODEPOINTS_LENGTH] = { + 0x100, 0x100, + 0x102, 0x102, + 0x104, 0x104, + 0x106, 0x106, + 0x108, 0x108, + 0x10A, 0x10A, + 0x10C, 0x10C, + 0x10E, 0x10E, + 0x110, 0x110, + 0x112, 0x112, + 0x114, 0x114, + 0x116, 0x116, + 0x118, 0x118, + 0x11A, 0x11A, + 0x11C, 0x11C, + 0x11E, 0x11E, + 0x120, 0x120, + 0x122, 0x122, + 0x124, 0x124, + 0x126, 0x126, + 0x128, 0x128, + 0x12A, 0x12A, + 0x12C, 0x12C, + 0x12E, 0x12E, + 0x130, 0x130, + 0x132, 0x132, + 0x134, 0x134, + 0x136, 0x136, + 0x139, 0x139, + 0x13B, 0x13B, + 0x13D, 0x13D, + 0x13F, 0x13F, + 0x141, 0x141, + 0x143, 0x143, + 0x145, 0x145, + 0x147, 0x147, + 0x14A, 0x14A, + 0x14C, 0x14C, + 0x14E, 0x14E, + 0x150, 0x150, + 0x152, 0x152, + 0x154, 0x154, + 0x156, 0x156, + 0x158, 0x158, + 0x15A, 0x15A, + 0x15C, 0x15C, + 0x15E, 0x15E, + 0x160, 0x160, + 0x162, 0x162, + 0x164, 0x164, + 0x166, 0x166, + 0x168, 0x168, + 0x16A, 0x16A, + 0x16C, 0x16C, + 0x16E, 0x16E, + 0x170, 0x170, + 0x172, 0x172, + 0x174, 0x174, + 0x176, 0x176, + 0x178, 0x179, + 0x17B, 0x17B, + 0x17D, 0x17D, + 0x181, 0x182, + 0x184, 0x184, + 0x186, 0x187, + 0x189, 0x18B, + 0x18E, 0x191, + 0x193, 0x194, + 0x196, 0x198, + 0x19C, 0x19D, + 0x19F, 0x1A0, + 0x1A2, 0x1A2, + 0x1A4, 0x1A4, + 0x1A6, 0x1A7, + 0x1A9, 0x1A9, + 0x1AC, 0x1AC, + 0x1AE, 0x1AF, + 0x1B1, 0x1B3, + 0x1B5, 0x1B5, + 0x1B7, 0x1B8, + 0x1BC, 0x1BC, + 0x1C4, 0x1C5, + 0x1C7, 0x1C8, + 0x1CA, 0x1CB, + 0x1CD, 0x1CD, + 0x1CF, 0x1CF, + 0x1D1, 0x1D1, + 0x1D3, 0x1D3, + 0x1D5, 0x1D5, + 0x1D7, 0x1D7, + 0x1D9, 0x1D9, + 0x1DB, 0x1DB, + 0x1DE, 0x1DE, + 0x1E0, 0x1E0, + 0x1E2, 0x1E2, + 0x1E4, 0x1E4, + 0x1E6, 0x1E6, + 0x1E8, 0x1E8, + 0x1EA, 0x1EA, + 0x1EC, 0x1EC, + 0x1EE, 0x1EE, + 0x1F1, 0x1F2, + 0x1F4, 0x1F4, + 0x1F6, 0x1F8, + 0x1FA, 0x1FA, + 0x1FC, 0x1FC, + 0x1FE, 0x1FE, + 0x200, 0x200, + 0x202, 0x202, + 0x204, 0x204, + 0x206, 0x206, + 0x208, 0x208, + 0x20A, 0x20A, + 0x20C, 0x20C, + 0x20E, 0x20E, + 0x210, 0x210, + 0x212, 0x212, + 0x214, 0x214, + 0x216, 0x216, + 0x218, 0x218, + 0x21A, 0x21A, + 0x21C, 0x21C, + 0x21E, 0x21E, + 0x220, 0x220, + 0x222, 0x222, + 0x224, 0x224, + 0x226, 0x226, + 0x228, 0x228, + 0x22A, 0x22A, + 0x22C, 0x22C, + 0x22E, 0x22E, + 0x230, 0x230, + 0x232, 0x232, + 0x23A, 0x23B, + 0x23D, 0x23E, + 0x241, 0x241, + 0x243, 0x246, + 0x248, 0x248, + 0x24A, 0x24A, + 0x24C, 0x24C, + 0x24E, 0x24E, + 0x370, 0x370, + 0x372, 0x372, + 0x376, 0x376, + 0x37F, 0x37F, + 0x386, 0x386, + 0x388, 0x38A, + 0x38C, 0x38C, + 0x38E, 0x38F, + 0x391, 0x3A1, + 0x3A3, 0x3AB, + 0x3CF, 0x3CF, + 0x3D2, 0x3D4, + 0x3D8, 0x3D8, + 0x3DA, 0x3DA, + 0x3DC, 0x3DC, + 0x3DE, 0x3DE, + 0x3E0, 0x3E0, + 0x3E2, 0x3E2, + 0x3E4, 0x3E4, + 0x3E6, 0x3E6, + 0x3E8, 0x3E8, + 0x3EA, 0x3EA, + 0x3EC, 0x3EC, + 0x3EE, 0x3EE, + 0x3F4, 0x3F4, + 0x3F7, 0x3F7, + 0x3F9, 0x3FA, + 0x3FD, 0x42F, + 0x460, 0x460, + 0x462, 0x462, + 0x464, 0x464, + 0x466, 0x466, + 0x468, 0x468, + 0x46A, 0x46A, + 0x46C, 0x46C, + 0x46E, 0x46E, + 0x470, 0x470, + 0x472, 0x472, + 0x474, 0x474, + 0x476, 0x476, + 0x478, 0x478, + 0x47A, 0x47A, + 0x47C, 0x47C, + 0x47E, 0x47E, + 0x480, 0x480, + 0x48A, 0x48A, + 0x48C, 0x48C, + 0x48E, 0x48E, + 0x490, 0x490, + 0x492, 0x492, + 0x494, 0x494, + 0x496, 0x496, + 0x498, 0x498, + 0x49A, 0x49A, + 0x49C, 0x49C, + 0x49E, 0x49E, + 0x4A0, 0x4A0, + 0x4A2, 0x4A2, + 0x4A4, 0x4A4, + 0x4A6, 0x4A6, + 0x4A8, 0x4A8, + 0x4AA, 0x4AA, + 0x4AC, 0x4AC, + 0x4AE, 0x4AE, + 0x4B0, 0x4B0, + 0x4B2, 0x4B2, + 0x4B4, 0x4B4, + 0x4B6, 0x4B6, + 0x4B8, 0x4B8, + 0x4BA, 0x4BA, + 0x4BC, 0x4BC, + 0x4BE, 0x4BE, + 0x4C0, 0x4C1, + 0x4C3, 0x4C3, + 0x4C5, 0x4C5, + 0x4C7, 0x4C7, + 0x4C9, 0x4C9, + 0x4CB, 0x4CB, + 0x4CD, 0x4CD, + 0x4D0, 0x4D0, + 0x4D2, 0x4D2, + 0x4D4, 0x4D4, + 0x4D6, 0x4D6, + 0x4D8, 0x4D8, + 0x4DA, 0x4DA, + 0x4DC, 0x4DC, + 0x4DE, 0x4DE, + 0x4E0, 0x4E0, + 0x4E2, 0x4E2, + 0x4E4, 0x4E4, + 0x4E6, 0x4E6, + 0x4E8, 0x4E8, + 0x4EA, 0x4EA, + 0x4EC, 0x4EC, + 0x4EE, 0x4EE, + 0x4F0, 0x4F0, + 0x4F2, 0x4F2, + 0x4F4, 0x4F4, + 0x4F6, 0x4F6, + 0x4F8, 0x4F8, + 0x4FA, 0x4FA, + 0x4FC, 0x4FC, + 0x4FE, 0x4FE, + 0x500, 0x500, + 0x502, 0x502, + 0x504, 0x504, + 0x506, 0x506, + 0x508, 0x508, + 0x50A, 0x50A, + 0x50C, 0x50C, + 0x50E, 0x50E, + 0x510, 0x510, + 0x512, 0x512, + 0x514, 0x514, + 0x516, 0x516, + 0x518, 0x518, + 0x51A, 0x51A, + 0x51C, 0x51C, + 0x51E, 0x51E, + 0x520, 0x520, + 0x522, 0x522, + 0x524, 0x524, + 0x526, 0x526, + 0x528, 0x528, + 0x52A, 0x52A, + 0x52C, 0x52C, + 0x52E, 0x52E, + 0x531, 0x556, + 0x10A0, 0x10C5, + 0x10C7, 0x10C7, + 0x10CD, 0x10CD, + 0x13A0, 0x13F5, + 0x1C90, 0x1CBA, + 0x1CBD, 0x1CBF, + 0x1E00, 0x1E00, + 0x1E02, 0x1E02, + 0x1E04, 0x1E04, + 0x1E06, 0x1E06, + 0x1E08, 0x1E08, + 0x1E0A, 0x1E0A, + 0x1E0C, 0x1E0C, + 0x1E0E, 0x1E0E, + 0x1E10, 0x1E10, + 0x1E12, 0x1E12, + 0x1E14, 0x1E14, + 0x1E16, 0x1E16, + 0x1E18, 0x1E18, + 0x1E1A, 0x1E1A, + 0x1E1C, 0x1E1C, + 0x1E1E, 0x1E1E, + 0x1E20, 0x1E20, + 0x1E22, 0x1E22, + 0x1E24, 0x1E24, + 0x1E26, 0x1E26, + 0x1E28, 0x1E28, + 0x1E2A, 0x1E2A, + 0x1E2C, 0x1E2C, + 0x1E2E, 0x1E2E, + 0x1E30, 0x1E30, + 0x1E32, 0x1E32, + 0x1E34, 0x1E34, + 0x1E36, 0x1E36, + 0x1E38, 0x1E38, + 0x1E3A, 0x1E3A, + 0x1E3C, 0x1E3C, + 0x1E3E, 0x1E3E, + 0x1E40, 0x1E40, + 0x1E42, 0x1E42, + 0x1E44, 0x1E44, + 0x1E46, 0x1E46, + 0x1E48, 0x1E48, + 0x1E4A, 0x1E4A, + 0x1E4C, 0x1E4C, + 0x1E4E, 0x1E4E, + 0x1E50, 0x1E50, + 0x1E52, 0x1E52, + 0x1E54, 0x1E54, + 0x1E56, 0x1E56, + 0x1E58, 0x1E58, + 0x1E5A, 0x1E5A, + 0x1E5C, 0x1E5C, + 0x1E5E, 0x1E5E, + 0x1E60, 0x1E60, + 0x1E62, 0x1E62, + 0x1E64, 0x1E64, + 0x1E66, 0x1E66, + 0x1E68, 0x1E68, + 0x1E6A, 0x1E6A, + 0x1E6C, 0x1E6C, + 0x1E6E, 0x1E6E, + 0x1E70, 0x1E70, + 0x1E72, 0x1E72, + 0x1E74, 0x1E74, + 0x1E76, 0x1E76, + 0x1E78, 0x1E78, + 0x1E7A, 0x1E7A, + 0x1E7C, 0x1E7C, + 0x1E7E, 0x1E7E, + 0x1E80, 0x1E80, + 0x1E82, 0x1E82, + 0x1E84, 0x1E84, + 0x1E86, 0x1E86, + 0x1E88, 0x1E88, + 0x1E8A, 0x1E8A, + 0x1E8C, 0x1E8C, + 0x1E8E, 0x1E8E, + 0x1E90, 0x1E90, + 0x1E92, 0x1E92, + 0x1E94, 0x1E94, + 0x1E9E, 0x1E9E, + 0x1EA0, 0x1EA0, + 0x1EA2, 0x1EA2, + 0x1EA4, 0x1EA4, + 0x1EA6, 0x1EA6, + 0x1EA8, 0x1EA8, + 0x1EAA, 0x1EAA, + 0x1EAC, 0x1EAC, + 0x1EAE, 0x1EAE, + 0x1EB0, 0x1EB0, + 0x1EB2, 0x1EB2, + 0x1EB4, 0x1EB4, + 0x1EB6, 0x1EB6, + 0x1EB8, 0x1EB8, + 0x1EBA, 0x1EBA, + 0x1EBC, 0x1EBC, + 0x1EBE, 0x1EBE, + 0x1EC0, 0x1EC0, + 0x1EC2, 0x1EC2, + 0x1EC4, 0x1EC4, + 0x1EC6, 0x1EC6, + 0x1EC8, 0x1EC8, + 0x1ECA, 0x1ECA, + 0x1ECC, 0x1ECC, + 0x1ECE, 0x1ECE, + 0x1ED0, 0x1ED0, + 0x1ED2, 0x1ED2, + 0x1ED4, 0x1ED4, + 0x1ED6, 0x1ED6, + 0x1ED8, 0x1ED8, + 0x1EDA, 0x1EDA, + 0x1EDC, 0x1EDC, + 0x1EDE, 0x1EDE, + 0x1EE0, 0x1EE0, + 0x1EE2, 0x1EE2, + 0x1EE4, 0x1EE4, + 0x1EE6, 0x1EE6, + 0x1EE8, 0x1EE8, + 0x1EEA, 0x1EEA, + 0x1EEC, 0x1EEC, + 0x1EEE, 0x1EEE, + 0x1EF0, 0x1EF0, + 0x1EF2, 0x1EF2, + 0x1EF4, 0x1EF4, + 0x1EF6, 0x1EF6, + 0x1EF8, 0x1EF8, + 0x1EFA, 0x1EFA, + 0x1EFC, 0x1EFC, + 0x1EFE, 0x1EFE, + 0x1F08, 0x1F0F, + 0x1F18, 0x1F1D, + 0x1F28, 0x1F2F, + 0x1F38, 0x1F3F, + 0x1F48, 0x1F4D, + 0x1F59, 0x1F59, + 0x1F5B, 0x1F5B, + 0x1F5D, 0x1F5D, + 0x1F5F, 0x1F5F, + 0x1F68, 0x1F6F, + 0x1F88, 0x1F8F, + 0x1F98, 0x1F9F, + 0x1FA8, 0x1FAF, + 0x1FB8, 0x1FBC, + 0x1FC8, 0x1FCC, + 0x1FD8, 0x1FDB, + 0x1FE8, 0x1FEC, + 0x1FF8, 0x1FFC, + 0x2102, 0x2102, + 0x2107, 0x2107, + 0x210B, 0x210D, + 0x2110, 0x2112, + 0x2115, 0x2115, + 0x2119, 0x211D, + 0x2124, 0x2124, + 0x2126, 0x2126, + 0x2128, 0x2128, + 0x212A, 0x212D, + 0x2130, 0x2133, + 0x213E, 0x213F, + 0x2145, 0x2145, + 0x2160, 0x216F, + 0x2183, 0x2183, + 0x24B6, 0x24CF, + 0x2C00, 0x2C2F, + 0x2C60, 0x2C60, + 0x2C62, 0x2C64, + 0x2C67, 0x2C67, + 0x2C69, 0x2C69, + 0x2C6B, 0x2C6B, + 0x2C6D, 0x2C70, + 0x2C72, 0x2C72, + 0x2C75, 0x2C75, + 0x2C7E, 0x2C80, + 0x2C82, 0x2C82, + 0x2C84, 0x2C84, + 0x2C86, 0x2C86, + 0x2C88, 0x2C88, + 0x2C8A, 0x2C8A, + 0x2C8C, 0x2C8C, + 0x2C8E, 0x2C8E, + 0x2C90, 0x2C90, + 0x2C92, 0x2C92, + 0x2C94, 0x2C94, + 0x2C96, 0x2C96, + 0x2C98, 0x2C98, + 0x2C9A, 0x2C9A, + 0x2C9C, 0x2C9C, + 0x2C9E, 0x2C9E, + 0x2CA0, 0x2CA0, + 0x2CA2, 0x2CA2, + 0x2CA4, 0x2CA4, + 0x2CA6, 0x2CA6, + 0x2CA8, 0x2CA8, + 0x2CAA, 0x2CAA, + 0x2CAC, 0x2CAC, + 0x2CAE, 0x2CAE, + 0x2CB0, 0x2CB0, + 0x2CB2, 0x2CB2, + 0x2CB4, 0x2CB4, + 0x2CB6, 0x2CB6, + 0x2CB8, 0x2CB8, + 0x2CBA, 0x2CBA, + 0x2CBC, 0x2CBC, + 0x2CBE, 0x2CBE, + 0x2CC0, 0x2CC0, + 0x2CC2, 0x2CC2, + 0x2CC4, 0x2CC4, + 0x2CC6, 0x2CC6, + 0x2CC8, 0x2CC8, + 0x2CCA, 0x2CCA, + 0x2CCC, 0x2CCC, + 0x2CCE, 0x2CCE, + 0x2CD0, 0x2CD0, + 0x2CD2, 0x2CD2, + 0x2CD4, 0x2CD4, + 0x2CD6, 0x2CD6, + 0x2CD8, 0x2CD8, + 0x2CDA, 0x2CDA, + 0x2CDC, 0x2CDC, + 0x2CDE, 0x2CDE, + 0x2CE0, 0x2CE0, + 0x2CE2, 0x2CE2, + 0x2CEB, 0x2CEB, + 0x2CED, 0x2CED, + 0x2CF2, 0x2CF2, + 0xA640, 0xA640, + 0xA642, 0xA642, + 0xA644, 0xA644, + 0xA646, 0xA646, + 0xA648, 0xA648, + 0xA64A, 0xA64A, + 0xA64C, 0xA64C, + 0xA64E, 0xA64E, + 0xA650, 0xA650, + 0xA652, 0xA652, + 0xA654, 0xA654, + 0xA656, 0xA656, + 0xA658, 0xA658, + 0xA65A, 0xA65A, + 0xA65C, 0xA65C, + 0xA65E, 0xA65E, + 0xA660, 0xA660, + 0xA662, 0xA662, + 0xA664, 0xA664, + 0xA666, 0xA666, + 0xA668, 0xA668, + 0xA66A, 0xA66A, + 0xA66C, 0xA66C, + 0xA680, 0xA680, + 0xA682, 0xA682, + 0xA684, 0xA684, + 0xA686, 0xA686, + 0xA688, 0xA688, + 0xA68A, 0xA68A, + 0xA68C, 0xA68C, + 0xA68E, 0xA68E, + 0xA690, 0xA690, + 0xA692, 0xA692, + 0xA694, 0xA694, + 0xA696, 0xA696, + 0xA698, 0xA698, + 0xA69A, 0xA69A, + 0xA722, 0xA722, + 0xA724, 0xA724, + 0xA726, 0xA726, + 0xA728, 0xA728, + 0xA72A, 0xA72A, + 0xA72C, 0xA72C, + 0xA72E, 0xA72E, + 0xA732, 0xA732, + 0xA734, 0xA734, + 0xA736, 0xA736, + 0xA738, 0xA738, + 0xA73A, 0xA73A, + 0xA73C, 0xA73C, + 0xA73E, 0xA73E, + 0xA740, 0xA740, + 0xA742, 0xA742, + 0xA744, 0xA744, + 0xA746, 0xA746, + 0xA748, 0xA748, + 0xA74A, 0xA74A, + 0xA74C, 0xA74C, + 0xA74E, 0xA74E, + 0xA750, 0xA750, + 0xA752, 0xA752, + 0xA754, 0xA754, + 0xA756, 0xA756, + 0xA758, 0xA758, + 0xA75A, 0xA75A, + 0xA75C, 0xA75C, + 0xA75E, 0xA75E, + 0xA760, 0xA760, + 0xA762, 0xA762, + 0xA764, 0xA764, + 0xA766, 0xA766, + 0xA768, 0xA768, + 0xA76A, 0xA76A, + 0xA76C, 0xA76C, + 0xA76E, 0xA76E, + 0xA779, 0xA779, + 0xA77B, 0xA77B, + 0xA77D, 0xA77E, + 0xA780, 0xA780, + 0xA782, 0xA782, + 0xA784, 0xA784, + 0xA786, 0xA786, + 0xA78B, 0xA78B, + 0xA78D, 0xA78D, + 0xA790, 0xA790, + 0xA792, 0xA792, + 0xA796, 0xA796, + 0xA798, 0xA798, + 0xA79A, 0xA79A, + 0xA79C, 0xA79C, + 0xA79E, 0xA79E, + 0xA7A0, 0xA7A0, + 0xA7A2, 0xA7A2, + 0xA7A4, 0xA7A4, + 0xA7A6, 0xA7A6, + 0xA7A8, 0xA7A8, + 0xA7AA, 0xA7AE, + 0xA7B0, 0xA7B4, + 0xA7B6, 0xA7B6, + 0xA7B8, 0xA7B8, + 0xA7BA, 0xA7BA, + 0xA7BC, 0xA7BC, + 0xA7BE, 0xA7BE, + 0xA7C0, 0xA7C0, + 0xA7C2, 0xA7C2, + 0xA7C4, 0xA7C7, + 0xA7C9, 0xA7C9, + 0xA7D0, 0xA7D0, + 0xA7D6, 0xA7D6, + 0xA7D8, 0xA7D8, + 0xA7F5, 0xA7F5, + 0xFF21, 0xFF3A, + 0x10400, 0x10427, + 0x104B0, 0x104D3, + 0x10570, 0x1057A, + 0x1057C, 0x1058A, + 0x1058C, 0x10592, + 0x10594, 0x10595, + 0x10C80, 0x10CB2, + 0x118A0, 0x118BF, + 0x16E40, 0x16E5F, + 0x1D400, 0x1D419, + 0x1D434, 0x1D44D, + 0x1D468, 0x1D481, + 0x1D49C, 0x1D49C, + 0x1D49E, 0x1D49F, + 0x1D4A2, 0x1D4A2, + 0x1D4A5, 0x1D4A6, + 0x1D4A9, 0x1D4AC, + 0x1D4AE, 0x1D4B5, + 0x1D4D0, 0x1D4E9, + 0x1D504, 0x1D505, + 0x1D507, 0x1D50A, + 0x1D50D, 0x1D514, + 0x1D516, 0x1D51C, + 0x1D538, 0x1D539, + 0x1D53B, 0x1D53E, + 0x1D540, 0x1D544, + 0x1D546, 0x1D546, + 0x1D54A, 0x1D550, + 0x1D56C, 0x1D585, + 0x1D5A0, 0x1D5B9, + 0x1D5D4, 0x1D5ED, + 0x1D608, 0x1D621, + 0x1D63C, 0x1D655, + 0x1D670, 0x1D689, + 0x1D6A8, 0x1D6C0, + 0x1D6E2, 0x1D6FA, + 0x1D71C, 0x1D734, + 0x1D756, 0x1D76E, + 0x1D790, 0x1D7A8, + 0x1D7CA, 0x1D7CA, + 0x1E900, 0x1E921, + 0x1F130, 0x1F149, + 0x1F150, 0x1F169, + 0x1F170, 0x1F189, +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding unicode codepoint. Note that + * this table is different from other encodings where we used a lookup table + * because the indices of those tables are the byte representations, not the + * codepoints themselves. + */ +const uint8_t pm_encoding_unicode_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, // Bx + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx + 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 3, // Dx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, // Fx +}; + +/** + * Binary search through the given list of codepoints to see if the given + * codepoint is in the list. + */ +static bool +pm_unicode_codepoint_match(pm_unicode_codepoint_t codepoint, const pm_unicode_codepoint_t *codepoints, size_t size) { + size_t start = 0; + size_t end = size; + + while (start < end) { + size_t middle = start + (end - start) / 2; + if ((middle % 2) != 0) middle--; + + if (codepoint >= codepoints[middle] && codepoint <= codepoints[middle + 1]) { + return true; + } + + if (codepoint < codepoints[middle]) { + end = middle; + } else { + start = middle + 2; + } + } + + return false; +} + +/** + * A state transition table for decoding UTF-8. + * + * Copyright (c) 2008-2009 Bjoern Hoehrmann + * + * 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 + * AUTHORS OR COPYRIGHT HOLDERS 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. + */ +static const uint8_t pm_utf_8_dfa[] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 00..1f + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 20..3f + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 40..5f + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 60..7f + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, // 80..9f + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, // a0..bf + 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // c0..df + 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, // e0..ef + 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, // f0..ff + 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, // s0..s0 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, // s1..s2 + 1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, // s3..s4 + 1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, // s5..s6 + 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // s7..s8 +}; + +/** + * Given a pointer to a string and the number of bytes remaining in the string, + * decode the next UTF-8 codepoint and return it. The number of bytes consumed + * is returned in the width out parameter. + */ +static pm_unicode_codepoint_t +pm_utf_8_codepoint(const uint8_t *b, ptrdiff_t n, size_t *width) { + assert(n >= 0); + + size_t maximum = (n > 4) ? 4 : ((size_t) n); + uint32_t codepoint; + uint32_t state = 0; + + for (size_t index = 0; index < maximum; index++) { + uint32_t byte = b[index]; + uint32_t type = pm_utf_8_dfa[byte]; + + codepoint = (state != 0) ? + (byte & 0x3fu) | (codepoint << 6) : + (0xffu >> type) & (byte); + + state = pm_utf_8_dfa[256 + (state * 16) + type]; + if (state == 0) { + *width = index + 1; + return (pm_unicode_codepoint_t) codepoint; + } + } + + *width = 0; + return 0; +} + +/** + * Return the size of the next character in the UTF-8 encoding. + */ +size_t +pm_encoding_utf_8_char_width(const uint8_t *b, ptrdiff_t n) { + assert(n >= 0); + + size_t maximum = (n > 4) ? 4 : ((size_t) n); + uint32_t state = 0; + + for (size_t index = 0; index < maximum; index++) { + state = pm_utf_8_dfa[256 + (state * 16) + pm_utf_8_dfa[b[index]]]; + if (state == 0) return index + 1; + } + + return 0; +} + +/** + * Return the size of the next character in the UTF-8 encoding if it is an + * alphabetical character. + */ +size_t +pm_encoding_utf_8_alpha_char(const uint8_t *b, ptrdiff_t n) { + if (*b < 0x80) { + return (pm_encoding_unicode_table[*b] & PRISM_ENCODING_ALPHABETIC_BIT) ? 1 : 0; + } + + size_t width; + pm_unicode_codepoint_t codepoint = pm_utf_8_codepoint(b, n, &width); + + if (codepoint <= 0xFF) { + return (pm_encoding_unicode_table[(uint8_t) codepoint] & PRISM_ENCODING_ALPHABETIC_BIT) ? width : 0; + } else { + return pm_unicode_codepoint_match(codepoint, unicode_alpha_codepoints, UNICODE_ALPHA_CODEPOINTS_LENGTH) ? width : 0; + } +} + +/** + * Return the size of the next character in the UTF-8 encoding if it is an + * alphanumeric character. + */ +size_t +pm_encoding_utf_8_alnum_char(const uint8_t *b, ptrdiff_t n) { + if (*b < 0x80) { + return (pm_encoding_unicode_table[*b] & (PRISM_ENCODING_ALPHANUMERIC_BIT)) ? 1 : 0; + } + + size_t width; + pm_unicode_codepoint_t codepoint = pm_utf_8_codepoint(b, n, &width); + + if (codepoint <= 0xFF) { + return (pm_encoding_unicode_table[(uint8_t) codepoint] & (PRISM_ENCODING_ALPHANUMERIC_BIT)) ? width : 0; + } else { + return pm_unicode_codepoint_match(codepoint, unicode_alnum_codepoints, UNICODE_ALNUM_CODEPOINTS_LENGTH) ? width : 0; + } +} + +/** + * Return true if the next character in the UTF-8 encoding if it is an uppercase + * character. + */ +bool +pm_encoding_utf_8_isupper_char(const uint8_t *b, ptrdiff_t n) { + if (*b < 0x80) { + return (pm_encoding_unicode_table[*b] & PRISM_ENCODING_UPPERCASE_BIT) ? true : false; + } + + size_t width; + pm_unicode_codepoint_t codepoint = pm_utf_8_codepoint(b, n, &width); + + if (codepoint <= 0xFF) { + return (pm_encoding_unicode_table[(uint8_t) codepoint] & PRISM_ENCODING_UPPERCASE_BIT) ? true : false; + } else { + return pm_unicode_codepoint_match(codepoint, unicode_isupper_codepoints, UNICODE_ISUPPER_CODEPOINTS_LENGTH) ? true : false; + } +} + +#ifndef PRISM_ENCODING_EXCLUDE_FULL + +static pm_unicode_codepoint_t +pm_cesu_8_codepoint(const uint8_t *b, ptrdiff_t n, size_t *width) { + if (b[0] < 0x80) { + *width = 1; + return (pm_unicode_codepoint_t) b[0]; + } + + if (n > 1 && b[0] >= 0xC2 && b[0] <= 0xDF && b[1] >= 0x80 && b[1] <= 0xBF) { + *width = 2; + + // 110xxxxx 10xxxxxx + return (pm_unicode_codepoint_t) (((b[0] & 0x1F) << 6) | (b[1] & 0x3F)); + } + + if (n > 5 && b[0] == 0xED && b[1] >= 0xA0 && b[1] <= 0xAF && b[2] >= 0x80 && b[2] <= 0xBF && b[3] == 0xED && b[4] >= 0xB0 && b[4] <= 0xBF && b[5] >= 0x80 && b[5] <= 0xBF) { + *width = 6; + + // 11101101 1010xxxx 10xxxxxx 11101101 1011xxxx 10xxxxxx + return (pm_unicode_codepoint_t) (0x10000 + (((b[1] & 0xF) << 16) | ((b[2] & 0x3F) << 10) | ((b[4] & 0xF) << 6) | (b[5] & 0x3F))); + } + + if (n > 2 && b[0] == 0xED && b[1] >= 0xA0 && b[1] <= 0xBF) { + *width = 3; + + // 11101101 1010xxxx 10xxxxx + return (pm_unicode_codepoint_t) (0x10000 + (((b[0] & 0x03) << 16) | ((b[1] & 0x3F) << 10) | (b[2] & 0x3F))); + } + + if (n > 2 && ((b[0] == 0xE0 && b[1] >= 0xA0) || (b[0] >= 0xE1 && b[0] <= 0xEF && b[1] >= 0x80)) && b[1] <= 0xBF && b[2] >= 0x80 && b[2] <= 0xBF) { + *width = 3; + + // 1110xxxx 10xxxxxx 10xxxxx + return (pm_unicode_codepoint_t) (((b[0] & 0xF) << 12) | ((b[1] & 0x3F) << 6) | (b[2] & 0x3F)); + } + + *width = 0; + return 0; +} + +static size_t +pm_encoding_cesu_8_char_width(const uint8_t *b, ptrdiff_t n) { + size_t width; + pm_cesu_8_codepoint(b, n, &width); + return width; +} + +static size_t +pm_encoding_cesu_8_alpha_char(const uint8_t *b, ptrdiff_t n) { + if (*b < 0x80) { + return (pm_encoding_unicode_table[*b] & PRISM_ENCODING_ALPHABETIC_BIT) ? 1 : 0; + } + + size_t width; + pm_unicode_codepoint_t codepoint = pm_cesu_8_codepoint(b, n, &width); + + if (codepoint <= 0xFF) { + return (pm_encoding_unicode_table[(uint8_t) codepoint] & PRISM_ENCODING_ALPHABETIC_BIT) ? width : 0; + } else { + return pm_unicode_codepoint_match(codepoint, unicode_alpha_codepoints, UNICODE_ALPHA_CODEPOINTS_LENGTH) ? width : 0; + } +} + +static size_t +pm_encoding_cesu_8_alnum_char(const uint8_t *b, ptrdiff_t n) { + if (*b < 0x80) { + return (pm_encoding_unicode_table[*b] & (PRISM_ENCODING_ALPHANUMERIC_BIT)) ? 1 : 0; + } + + size_t width; + pm_unicode_codepoint_t codepoint = pm_cesu_8_codepoint(b, n, &width); + + if (codepoint <= 0xFF) { + return (pm_encoding_unicode_table[(uint8_t) codepoint] & (PRISM_ENCODING_ALPHANUMERIC_BIT)) ? width : 0; + } else { + return pm_unicode_codepoint_match(codepoint, unicode_alnum_codepoints, UNICODE_ALNUM_CODEPOINTS_LENGTH) ? width : 0; + } +} + +static bool +pm_encoding_cesu_8_isupper_char(const uint8_t *b, ptrdiff_t n) { + if (*b < 0x80) { + return (pm_encoding_unicode_table[*b] & PRISM_ENCODING_UPPERCASE_BIT) ? true : false; + } + + size_t width; + pm_unicode_codepoint_t codepoint = pm_cesu_8_codepoint(b, n, &width); + + if (codepoint <= 0xFF) { + return (pm_encoding_unicode_table[(uint8_t) codepoint] & PRISM_ENCODING_UPPERCASE_BIT) ? true : false; + } else { + return pm_unicode_codepoint_match(codepoint, unicode_isupper_codepoints, UNICODE_ISUPPER_CODEPOINTS_LENGTH) ? true : false; + } +} + +#endif + +#undef UNICODE_ALPHA_CODEPOINTS_LENGTH +#undef UNICODE_ALNUM_CODEPOINTS_LENGTH +#undef UNICODE_ISUPPER_CODEPOINTS_LENGTH + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding US-ASCII character. + */ +static const uint8_t pm_encoding_ascii_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +#ifndef PRISM_ENCODING_EXCLUDE_FULL + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding CP850 character. + */ +static const uint8_t pm_encoding_cp850_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding CP852 character. + */ +static const uint8_t pm_encoding_cp852_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding CP855 character. + */ +static const uint8_t pm_encoding_cp855_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding GB1988 character. + */ +static const uint8_t pm_encoding_gb1988_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding IBM437 character. + */ +static const uint8_t pm_encoding_ibm437_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding IBM720 character. + */ +static const uint8_t pm_encoding_ibm720_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding IBM737 character. + */ +static const uint8_t pm_encoding_ibm737_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding IBM775 character. + */ +static const uint8_t pm_encoding_ibm775_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding IBM852 character. + */ +static const uint8_t pm_encoding_ibm852_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding IBM855 character. + */ +static const uint8_t pm_encoding_ibm855_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding IBM857 character. + */ +static const uint8_t pm_encoding_ibm857_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding IBM860 character. + */ +static const uint8_t pm_encoding_ibm860_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding IBM861 character. + */ +static const uint8_t pm_encoding_ibm861_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding IBM862 character. + */ +static const uint8_t pm_encoding_ibm862_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding IBM863 character. + */ +static const uint8_t pm_encoding_ibm863_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding IBM864 character. + */ +static const uint8_t pm_encoding_ibm864_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding IBM865 character. + */ +static const uint8_t pm_encoding_ibm865_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding IBM866 character. + */ +static const uint8_t pm_encoding_ibm866_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding IBM869 character. + */ +static const uint8_t pm_encoding_ibm869_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding ISO-8859-1 character. + */ +static const uint8_t pm_encoding_iso_8859_1_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, // Bx + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx + 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 3, // Dx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding ISO-8859-2 character. + */ +static const uint8_t pm_encoding_iso_8859_2_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 7, 0, 7, 0, 7, 7, 0, 0, 7, 7, 7, 7, 0, 7, 7, // Ax + 0, 3, 0, 3, 0, 3, 3, 0, 0, 3, 3, 3, 3, 0, 3, 3, // Bx + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx + 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 3, // Dx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding ISO-8859-3 character. + */ +static const uint8_t pm_encoding_iso_8859_3_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 7, 0, 0, 0, 0, 7, 0, 0, 7, 7, 7, 7, 0, 0, 7, // Ax + 0, 3, 0, 0, 0, 3, 3, 0, 0, 3, 3, 3, 3, 0, 0, 3, // Bx + 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx + 0, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 3, // Dx + 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding ISO-8859-4 character. + */ +static const uint8_t pm_encoding_iso_8859_4_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 7, 3, 7, 0, 7, 7, 0, 0, 7, 7, 7, 7, 0, 7, 0, // Ax + 0, 3, 0, 3, 0, 3, 3, 0, 0, 3, 3, 3, 3, 7, 3, 3, // Bx + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx + 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 3, // Dx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding ISO-8859-5 character. + */ +static const uint8_t pm_encoding_iso_8859_5_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, // Ax + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Bx + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Dx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding ISO-8859-6 character. + */ +static const uint8_t pm_encoding_iso_8859_6_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Cx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // Dx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding ISO-8859-7 character. + */ +static const uint8_t pm_encoding_iso_8859_7_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 7, 0, 7, 7, 7, 0, 7, 0, 7, 7, // Bx + 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx + 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 3, 3, 3, 3, // Dx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding ISO-8859-8 character. + */ +static const uint8_t pm_encoding_iso_8859_8_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding ISO-8859-9 character. + */ +static const uint8_t pm_encoding_iso_8859_9_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, // Bx + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx + 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 3, // Dx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding ISO-8859-10 character. + */ +static const uint8_t pm_encoding_iso_8859_10_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 0, 7, 7, // Ax + 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 0, 3, 3, // Bx + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 3, // Dx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding ISO-8859-11 character. + */ +static const uint8_t pm_encoding_iso_8859_11_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ax + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Bx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Cx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 3, // Dx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding ISO-8859-13 character. + */ +static const uint8_t pm_encoding_iso_8859_13_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 0, 0, 0, 0, 7, // Ax + 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 0, 0, 0, 3, // Bx + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx + 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 3, // Dx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding ISO-8859-14 character. + */ +static const uint8_t pm_encoding_iso_8859_14_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 7, 3, 0, 7, 3, 7, 0, 7, 0, 7, 3, 7, 0, 0, 7, // Ax + 7, 3, 7, 3, 7, 3, 0, 7, 3, 3, 3, 7, 3, 7, 3, 3, // Bx + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 3, // Dx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding ISO-8859-15 character. + */ +static const uint8_t pm_encoding_iso_8859_15_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 7, 0, 3, 0, 3, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 7, 3, 0, 0, 3, 0, 3, 0, 7, 3, 7, 0, // Bx + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx + 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 3, // Dx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding ISO-8859-16 character. + */ +static const uint8_t pm_encoding_iso_8859_16_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 7, 3, 7, 0, 0, 7, 0, 3, 0, 7, 0, 7, 0, 3, 7, // Ax + 0, 0, 7, 3, 7, 0, 0, 0, 3, 3, 3, 0, 7, 3, 7, 3, // Bx + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 3, // Dx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding KOI8-R character. + */ +static const uint8_t pm_encoding_koi8_r_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Cx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Dx + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Ex + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding KOI8-U character. + */ +static const uint8_t pm_encoding_koi8_u_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 3, 3, 0, 3, 3, 0, 0, 0, 0, 0, 3, 0, 0, // Ax + 0, 0, 0, 7, 7, 0, 7, 7, 0, 0, 0, 0, 0, 7, 0, 0, // Bx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Cx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Dx + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Ex + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding macCentEuro character. + */ +static const uint8_t pm_encoding_mac_cent_euro_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding macCroatian character. + */ +static const uint8_t pm_encoding_mac_croatian_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + + /** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding macCyrillic character. + */ +static const uint8_t pm_encoding_mac_cyrillic_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding macGreek character. + */ +static const uint8_t pm_encoding_mac_greek_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding macIceland character. + */ +static const uint8_t pm_encoding_mac_iceland_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding macRoman character. + */ +static const uint8_t pm_encoding_mac_roman_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding macRomania character. + */ +static const uint8_t pm_encoding_mac_romania_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding macThai character. + */ +static const uint8_t pm_encoding_mac_thai_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding TIS-620 character. + */ +static const uint8_t pm_encoding_tis_620_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ax + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Bx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Cx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 3, // Dx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding macTurkish character. + */ +static const uint8_t pm_encoding_mac_turkish_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding macUkraine character. + */ +static const uint8_t pm_encoding_mac_ukraine_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding windows-1250 character. + */ +static const uint8_t pm_encoding_windows_1250_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 7, 7, 7, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 3, 3, 3, // 9x + 0, 0, 0, 7, 0, 7, 0, 0, 0, 0, 7, 0, 0, 0, 0, 7, // Ax + 0, 0, 0, 3, 0, 3, 0, 0, 0, 3, 3, 0, 7, 0, 3, 3, // Bx + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 3, // Dx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding windows-1251 character. + */ +static const uint8_t pm_encoding_windows_1251_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 7, 7, 0, 3, 0, 0, 0, 0, 0, 0, 7, 0, 7, 7, 7, 7, // 8x + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 3, 3, 3, // 9x + 0, 7, 3, 7, 0, 7, 0, 0, 7, 0, 7, 0, 0, 0, 0, 7, // Ax + 0, 0, 7, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 7, 3, 3, // Bx + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Dx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding windows-1252 character. + */ +static const uint8_t pm_encoding_windows_1252_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 0, 7, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 0, 3, 7, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, // Bx + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 3, // Dx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding windows-1253 character. + */ +static const uint8_t pm_encoding_windows_1253_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 3, 7, 0, 7, 7, 7, 0, 7, 0, 7, 7, // Bx + 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx + 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 3, 3, 3, 3, // Dx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding windows-1254 character. + */ +static const uint8_t pm_encoding_windows_1254_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 0, 0, 7, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, // Bx + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx + 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 3, // Dx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding windows-1255 character. + */ +static const uint8_t pm_encoding_windows_1255_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding windows-1256 character. + */ +static const uint8_t pm_encoding_windows_1256_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Cx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // Dx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding windows-1257 character. + */ +static const uint8_t pm_encoding_windows_1257_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 7, 0, 0, 0, 0, 7, // Ax + 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 3, 0, 0, 0, 0, 3, // Bx + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // Cx + 7, 7, 7, 7, 7, 7, 7, 0, 7, 7, 7, 7, 7, 7, 7, 3, // Dx + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // Ex + 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding windows-1258 character. + */ +static const uint8_t pm_encoding_windows_1258_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +/** + * Each element of the following table contains a bitfield that indicates a + * piece of information about the corresponding windows-874 character. + */ +static const uint8_t pm_encoding_windows_874_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, // 3x + 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, // 4x + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, // 5x + 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 6x + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +#define PRISM_ENCODING_TABLE(name) \ + static size_t pm_encoding_ ##name ## _alpha_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) { \ + return (pm_encoding_ ##name ## _table[*b] & PRISM_ENCODING_ALPHABETIC_BIT); \ + } \ + static size_t pm_encoding_ ##name ## _alnum_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) { \ + return (pm_encoding_ ##name ## _table[*b] & PRISM_ENCODING_ALPHANUMERIC_BIT) ? 1 : 0; \ + } \ + static bool pm_encoding_ ##name ## _isupper_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) { \ + return (pm_encoding_ ##name ## _table[*b] & PRISM_ENCODING_UPPERCASE_BIT); \ + } + +PRISM_ENCODING_TABLE(cp850) +PRISM_ENCODING_TABLE(cp852) +PRISM_ENCODING_TABLE(cp855) +PRISM_ENCODING_TABLE(gb1988) +PRISM_ENCODING_TABLE(ibm437) +PRISM_ENCODING_TABLE(ibm720) +PRISM_ENCODING_TABLE(ibm737) +PRISM_ENCODING_TABLE(ibm775) +PRISM_ENCODING_TABLE(ibm852) +PRISM_ENCODING_TABLE(ibm855) +PRISM_ENCODING_TABLE(ibm857) +PRISM_ENCODING_TABLE(ibm860) +PRISM_ENCODING_TABLE(ibm861) +PRISM_ENCODING_TABLE(ibm862) +PRISM_ENCODING_TABLE(ibm863) +PRISM_ENCODING_TABLE(ibm864) +PRISM_ENCODING_TABLE(ibm865) +PRISM_ENCODING_TABLE(ibm866) +PRISM_ENCODING_TABLE(ibm869) +PRISM_ENCODING_TABLE(iso_8859_1) +PRISM_ENCODING_TABLE(iso_8859_2) +PRISM_ENCODING_TABLE(iso_8859_3) +PRISM_ENCODING_TABLE(iso_8859_4) +PRISM_ENCODING_TABLE(iso_8859_5) +PRISM_ENCODING_TABLE(iso_8859_6) +PRISM_ENCODING_TABLE(iso_8859_7) +PRISM_ENCODING_TABLE(iso_8859_8) +PRISM_ENCODING_TABLE(iso_8859_9) +PRISM_ENCODING_TABLE(iso_8859_10) +PRISM_ENCODING_TABLE(iso_8859_11) +PRISM_ENCODING_TABLE(iso_8859_13) +PRISM_ENCODING_TABLE(iso_8859_14) +PRISM_ENCODING_TABLE(iso_8859_15) +PRISM_ENCODING_TABLE(iso_8859_16) +PRISM_ENCODING_TABLE(koi8_r) +PRISM_ENCODING_TABLE(koi8_u) +PRISM_ENCODING_TABLE(mac_cent_euro) +PRISM_ENCODING_TABLE(mac_croatian) +PRISM_ENCODING_TABLE(mac_cyrillic) +PRISM_ENCODING_TABLE(mac_greek) +PRISM_ENCODING_TABLE(mac_iceland) +PRISM_ENCODING_TABLE(mac_roman) +PRISM_ENCODING_TABLE(mac_romania) +PRISM_ENCODING_TABLE(mac_thai) +PRISM_ENCODING_TABLE(mac_turkish) +PRISM_ENCODING_TABLE(mac_ukraine) +PRISM_ENCODING_TABLE(tis_620) +PRISM_ENCODING_TABLE(windows_1250) +PRISM_ENCODING_TABLE(windows_1251) +PRISM_ENCODING_TABLE(windows_1252) +PRISM_ENCODING_TABLE(windows_1253) +PRISM_ENCODING_TABLE(windows_1254) +PRISM_ENCODING_TABLE(windows_1255) +PRISM_ENCODING_TABLE(windows_1256) +PRISM_ENCODING_TABLE(windows_1257) +PRISM_ENCODING_TABLE(windows_1258) +PRISM_ENCODING_TABLE(windows_874) + +#undef PRISM_ENCODING_TABLE +#endif + +/** + * Returns the size of the next character in the ASCII encoding. This basically + * means that if the top bit is not set, the character is 1 byte long. + */ +static size_t +pm_encoding_ascii_char_width(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) { + return *b < 0x80 ? 1 : 0; +} + +/** + * Return the size of the next character in the ASCII encoding if it is an + * alphabetical character. + */ +static size_t +pm_encoding_ascii_alpha_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) { + return (pm_encoding_ascii_table[*b] & PRISM_ENCODING_ALPHABETIC_BIT); +} + +/** + * Certain encodings are equivalent to ASCII below 0x80, so it works for our + * purposes to have a function here that first checks the bounds and then falls + * back to checking the ASCII lookup table. + */ +static size_t +pm_encoding_ascii_alpha_char_7bit(const uint8_t *b, ptrdiff_t n) { + return (*b < 0x80) ? pm_encoding_ascii_alpha_char(b, n) : 0; +} + +/** + * Return the size of the next character in the ASCII encoding if it is an + * alphanumeric character. + */ +static size_t +pm_encoding_ascii_alnum_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) { + return (pm_encoding_ascii_table[*b] & PRISM_ENCODING_ALPHANUMERIC_BIT) ? 1 : 0; +} + +/** + * Certain encodings are equivalent to ASCII below 0x80, so it works for our + * purposes to have a function here that first checks the bounds and then falls + * back to checking the ASCII lookup table. + */ +static size_t +pm_encoding_ascii_alnum_char_7bit(const uint8_t *b, ptrdiff_t n) { + return (*b < 0x80) ? pm_encoding_ascii_alnum_char(b, n) : 0; +} + +/** + * Return true if the next character in the ASCII encoding if it is an uppercase + * character. + */ +static bool +pm_encoding_ascii_isupper_char(const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) { + return (pm_encoding_ascii_table[*b] & PRISM_ENCODING_UPPERCASE_BIT); +} + +/** + * For a lot of encodings the default is that they are a single byte long no + * matter what the codepoint, so this function is shared between them. + */ +static size_t +pm_encoding_single_char_width(PRISM_ATTRIBUTE_UNUSED const uint8_t *b, PRISM_ATTRIBUTE_UNUSED ptrdiff_t n) { + return 1; +} + +/** + * Returns the size of the next character in the EUC-JP encoding, or 0 if a + * character cannot be decoded from the given bytes. + */ +static size_t +pm_encoding_euc_jp_char_width(const uint8_t *b, ptrdiff_t n) { + // These are the single byte characters. + if (*b < 0x80) { + return 1; + } + + // These are the double byte characters. + if ((n > 1) && ((b[0] == 0x8E) || (b[0] >= 0xA1 && b[0] <= 0xFE)) && (b[1] >= 0xA1 && b[1] <= 0xFE)) { + return 2; + } + + // These are the triple byte characters. + if ((n > 2) && (b[0] == 0x8F) && (b[1] >= 0xA1 && b[2] <= 0xFE) && (b[2] >= 0xA1 && b[2] <= 0xFE)) { + return 3; + } + + return 0; +} + +/** + * Returns the size of the next character in the EUC-JP encoding if it is an + * uppercase character. + */ +static bool +pm_encoding_euc_jp_isupper_char(const uint8_t *b, ptrdiff_t n) { + size_t width = pm_encoding_euc_jp_char_width(b, n); + + if (width == 1) { + return pm_encoding_ascii_isupper_char(b, n); + } else if (width == 2) { + return ( + (b[0] == 0xA3 && b[1] >= 0xC1 && b[1] <= 0xDA) || + (b[0] == 0xA6 && b[1] >= 0xA1 && b[1] <= 0xB8) || + (b[0] == 0xA7 && b[1] >= 0xA1 && b[1] <= 0xC1) + ); + } else { + return false; + } +} + +/** + * Returns the size of the next character in the Shift_JIS encoding, or 0 if a + * character cannot be decoded from the given bytes. + */ +static size_t +pm_encoding_shift_jis_char_width(const uint8_t *b, ptrdiff_t n) { + // These are the single byte characters. + if (b[0] < 0x80 || (b[0] >= 0xA1 && b[0] <= 0xDF)) { + return 1; + } + + // These are the double byte characters. + if ((n > 1) && ((b[0] >= 0x81 && b[0] <= 0x9F) || (b[0] >= 0xE0 && b[0] <= 0xFC)) && (b[1] >= 0x40 && b[1] <= 0xFC && b[1] != 0x7F)) { + return 2; + } + + return 0; +} + +/** + * Returns the size of the next character in the Shift_JIS encoding if it is an + * alphanumeric character. + */ +static size_t +pm_encoding_shift_jis_alnum_char(const uint8_t *b, ptrdiff_t n) { + size_t width = pm_encoding_shift_jis_char_width(b, n); + return width == 1 ? ((b[0] >= 0x80) || pm_encoding_ascii_alnum_char(b, n)) : width; +} + +/** + * Returns the size of the next character in the Shift_JIS encoding if it is an + * alphabetical character. + */ +static size_t +pm_encoding_shift_jis_alpha_char(const uint8_t *b, ptrdiff_t n) { + size_t width = pm_encoding_shift_jis_char_width(b, n); + return width == 1 ? ((b[0] >= 0x80) || pm_encoding_ascii_alpha_char(b, n)) : width; +} + +/** + * Returns the size of the next character in the Shift_JIS encoding if it is an + * uppercase character. + */ +static bool +pm_encoding_shift_jis_isupper_char(const uint8_t *b, ptrdiff_t n) { + size_t width = pm_encoding_shift_jis_char_width(b, n); + + if (width == 1) { + return pm_encoding_ascii_isupper_char(b, n); + } else if (width == 2) { + return ( + ((b[0] == 0x82) && (b[1] >= 0x60 && b[1] <= 0x79)) || + ((b[0] == 0x83) && (b[1] >= 0x9F && b[1] <= 0xB6)) || + ((b[0] == 0x84) && (b[1] >= 0x40 && b[1] <= 0x60)) + ); + } else { + return width; + } +} + +#ifndef PRISM_ENCODING_EXCLUDE_FULL + +/** + * Certain encodings are equivalent to ASCII below 0x80, so it works for our + * purposes to have a function here that first checks the bounds and then falls + * back to checking the ASCII lookup table. + */ +static bool +pm_encoding_ascii_isupper_char_7bit(const uint8_t *b, ptrdiff_t n) { + return (*b < 0x80) && pm_encoding_ascii_isupper_char(b, n); +} + +/** + * Returns the size of the next character in the Big5 encoding, or 0 if a + * character cannot be decoded from the given bytes. + */ +static size_t +pm_encoding_big5_char_width(const uint8_t *b, ptrdiff_t n) { + // These are the single byte characters. + if (*b < 0x80) { + return 1; + } + + // These are the double byte characters. + if ((n > 1) && (b[0] >= 0xA1 && b[0] <= 0xFE) && ((b[1] >= 0x40 && b[1] <= 0x7E) || (b[1] >= 0xA1 && b[1] <= 0xFE))) { + return 2; + } + + return 0; +} + +/** + * Returns the size of the next character in the CP949 encoding, or 0 if a + * character cannot be decoded from the given bytes. + */ +static size_t +pm_encoding_cp949_char_width(const uint8_t *b, ptrdiff_t n) { + // These are the single byte characters + if (*b <= 0x80) { + return 1; + } + + // These are the double byte characters + if ((n > 1) && (b[0] >= 0x81 && b[0] <= 0xFE) && ((b[1] >= 0x41 && b[1] <= 0x5A) || (b[1] >= 0x61 && b[1] <= 0x7A) || (b[1] >= 0x81 && b[1] <= 0xFE))) { + return 2; + } + + return 0; +} + +/** + * Returns the size of the next character in the Emacs MULE encoding, or 0 if a + * character cannot be decoded from the given bytes. + */ +static size_t +pm_encoding_emacs_mule_char_width(const uint8_t *b, ptrdiff_t n) { + // These are the 1 byte characters. + if (*b < 0x80) { + return 1; + } + + // These are the 2 byte characters. + if ((n > 1) && (b[0] >= 0x81 && b[0] <= 0x8F) && (b[1] >= 0xA0)) { + return 2; + } + + // These are the 3 byte characters. + if ( + (n > 2) && + ( + ((b[0] >= 0x90 && b[0] <= 0x99) && (b[1] >= 0xA0)) || + ((b[0] == 0x9A || b[0] == 0x9B) && (b[1] >= 0xE0 && b[1] <= 0xEF)) + ) && + (b[2] >= 0xA0) + ) { + return 3; + } + + // These are the 4 byte characters. + if ( + (n > 3) && + ( + ((b[0] == 0x9C) && (b[1] >= 0xF0) && (b[1] <= 0xF4)) || + ((b[0] == 0x9D) && (b[1] >= 0xF5) && (b[1] <= 0xFE)) + ) && + (b[2] >= 0xA0) && (b[3] >= 0xA0) + ) { + return 4; + } + + return 0; +} + +/** + * Returns the size of the next character in the EUC-KR encoding, or 0 if a + * character cannot be decoded from the given bytes. + */ +static size_t +pm_encoding_euc_kr_char_width(const uint8_t *b, ptrdiff_t n) { + // These are the single byte characters. + if (*b < 0x80) { + return 1; + } + + // These are the double byte characters. + if ((n > 1) && (b[0] >= 0xA1 && b[0] <= 0xFE) && (b[1] >= 0xA1 && b[1] <= 0xFE)) { + return 2; + } + + return 0; +} + +/** + * Returns the size of the next character in the EUC-TW encoding, or 0 if a + * character cannot be decoded from the given bytes. + */ +static size_t +pm_encoding_euc_tw_char_width(const uint8_t *b, ptrdiff_t n) { + // These are the single byte characters. + if (*b < 0x80) { + return 1; + } + + // These are the double byte characters. + if ((n > 1) && (b[0] >= 0xA1) && (b[0] <= 0xFE) && (b[1] >= 0xA1) && (b[1] <= 0xFE)) { + return 2; + } + + // These are the quadruple byte characters. + if ((n > 3) && (b[0] == 0x8E) && (b[1] >= 0xA1) && (b[1] <= 0xB0) && (b[2] >= 0xA1) && (b[2] <= 0xFE) && (b[3] >= 0xA1) && (b[3] <= 0xFE)) { + return 4; + } + + return 0; +} + +/** + * Returns the size of the next character in the GB18030 encoding, or 0 if a + * character cannot be decoded from the given bytes. + */ +static size_t +pm_encoding_gb18030_char_width(const uint8_t *b, ptrdiff_t n) { + // These are the 1 byte characters. + if (*b < 0x80) { + return 1; + } + + // These are the 2 byte characters. + if ((n > 1) && (b[0] >= 0x81 && b[0] <= 0xFE) && (b[1] >= 0x40 && b[1] <= 0xFE && b[1] != 0x7F)) { + return 2; + } + + // These are the 4 byte characters. + if ((n > 3) && ((b[0] >= 0x81 && b[0] <= 0xFE) && (b[1] >= 0x30 && b[1] <= 0x39) && (b[2] >= 0x81 && b[2] <= 0xFE) && (b[3] >= 0x30 && b[3] <= 0x39))) { + return 4; + } + + return 0; +} + +/** + * Returns the size of the next character in the GBK encoding, or 0 if a + * character cannot be decoded from the given bytes. + */ +static size_t +pm_encoding_gbk_char_width(const uint8_t *b, ptrdiff_t n) { + // These are the single byte characters. + if (*b <= 0x80) { + return 1; + } + + // These are the double byte characters. + if ( + (n > 1) && + ( + ((b[0] >= 0xA1 && b[0] <= 0xA9) && (b[1] >= 0xA1 && b[1] <= 0xFE)) || // GBK/1 + ((b[0] >= 0xB0 && b[0] <= 0xF7) && (b[1] >= 0xA1 && b[1] <= 0xFE)) || // GBK/2 + ((b[0] >= 0x81 && b[0] <= 0xA0) && (b[1] >= 0x40 && b[1] <= 0xFE) && (b[1] != 0x7F)) || // GBK/3 + ((b[0] >= 0xAA && b[0] <= 0xFE) && (b[1] >= 0x40 && b[1] <= 0xA0) && (b[1] != 0x7F)) || // GBK/4 + ((b[0] >= 0xA8 && b[0] <= 0xA9) && (b[1] >= 0x40 && b[1] <= 0xA0) && (b[1] != 0x7F)) || // GBK/5 + ((b[0] >= 0xAA && b[0] <= 0xAF) && (b[1] >= 0xA1 && b[1] <= 0xFE)) || // user-defined 1 + ((b[0] >= 0xF8 && b[0] <= 0xFE) && (b[1] >= 0xA1 && b[1] <= 0xFE)) || // user-defined 2 + ((b[0] >= 0xA1 && b[0] <= 0xA7) && (b[1] >= 0x40 && b[1] <= 0xA0) && (b[1] != 0x7F)) // user-defined 3 + ) + ) { + return 2; + } + + return 0; +} + +#endif + +/** + * This is the table of all of the encodings that prism supports. + */ +const pm_encoding_t pm_encodings[] = { + [PM_ENCODING_UTF_8] = { + .name = "UTF-8", + .char_width = pm_encoding_utf_8_char_width, + .alnum_char = pm_encoding_utf_8_alnum_char, + .alpha_char = pm_encoding_utf_8_alpha_char, + .isupper_char = pm_encoding_utf_8_isupper_char, + .multibyte = true + }, + [PM_ENCODING_US_ASCII] = { + .name = "US-ASCII", + .char_width = pm_encoding_ascii_char_width, + .alnum_char = pm_encoding_ascii_alnum_char, + .alpha_char = pm_encoding_ascii_alpha_char, + .isupper_char = pm_encoding_ascii_isupper_char, + .multibyte = false + }, + [PM_ENCODING_ASCII_8BIT] = { + .name = "ASCII-8BIT", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_ascii_alnum_char, + .alpha_char = pm_encoding_ascii_alpha_char, + .isupper_char = pm_encoding_ascii_isupper_char, + .multibyte = false + }, + [PM_ENCODING_EUC_JP] = { + .name = "EUC-JP", + .char_width = pm_encoding_euc_jp_char_width, + .alnum_char = pm_encoding_ascii_alnum_char_7bit, + .alpha_char = pm_encoding_ascii_alpha_char_7bit, + .isupper_char = pm_encoding_euc_jp_isupper_char, + .multibyte = true + }, + [PM_ENCODING_WINDOWS_31J] = { + .name = "Windows-31J", + .char_width = pm_encoding_shift_jis_char_width, + .alnum_char = pm_encoding_shift_jis_alnum_char, + .alpha_char = pm_encoding_shift_jis_alpha_char, + .isupper_char = pm_encoding_shift_jis_isupper_char, + .multibyte = true + }, + +#ifndef PRISM_ENCODING_EXCLUDE_FULL + [PM_ENCODING_BIG5] = { + .name = "Big5", + .char_width = pm_encoding_big5_char_width, + .alnum_char = pm_encoding_ascii_alnum_char_7bit, + .alpha_char = pm_encoding_ascii_alpha_char_7bit, + .isupper_char = pm_encoding_ascii_isupper_char_7bit, + .multibyte = true + }, + [PM_ENCODING_BIG5_HKSCS] = { + .name = "Big5-HKSCS", + .char_width = pm_encoding_big5_char_width, + .alnum_char = pm_encoding_ascii_alnum_char_7bit, + .alpha_char = pm_encoding_ascii_alpha_char_7bit, + .isupper_char = pm_encoding_ascii_isupper_char_7bit, + .multibyte = true + }, + [PM_ENCODING_BIG5_UAO] = { + .name = "Big5-UAO", + .char_width = pm_encoding_big5_char_width, + .alnum_char = pm_encoding_ascii_alnum_char_7bit, + .alpha_char = pm_encoding_ascii_alpha_char_7bit, + .isupper_char = pm_encoding_ascii_isupper_char_7bit, + .multibyte = true + }, + [PM_ENCODING_CESU_8] = { + .name = "CESU-8", + .char_width = pm_encoding_cesu_8_char_width, + .alnum_char = pm_encoding_cesu_8_alnum_char, + .alpha_char = pm_encoding_cesu_8_alpha_char, + .isupper_char = pm_encoding_cesu_8_isupper_char, + .multibyte = true + }, + [PM_ENCODING_CP51932] = { + .name = "CP51932", + .char_width = pm_encoding_euc_jp_char_width, + .alnum_char = pm_encoding_ascii_alnum_char_7bit, + .alpha_char = pm_encoding_ascii_alpha_char_7bit, + .isupper_char = pm_encoding_euc_jp_isupper_char, + .multibyte = true + }, + [PM_ENCODING_CP850] = { + .name = "CP850", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_cp850_alnum_char, + .alpha_char = pm_encoding_cp850_alpha_char, + .isupper_char = pm_encoding_cp850_isupper_char, + .multibyte = false + }, + [PM_ENCODING_CP852] = { + .name = "CP852", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_cp852_alnum_char, + .alpha_char = pm_encoding_cp852_alpha_char, + .isupper_char = pm_encoding_cp852_isupper_char, + .multibyte = false + }, + [PM_ENCODING_CP855] = { + .name = "CP855", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_cp855_alnum_char, + .alpha_char = pm_encoding_cp855_alpha_char, + .isupper_char = pm_encoding_cp855_isupper_char, + .multibyte = false + }, + [PM_ENCODING_CP949] = { + .name = "CP949", + .char_width = pm_encoding_cp949_char_width, + .alnum_char = pm_encoding_ascii_alnum_char_7bit, + .alpha_char = pm_encoding_ascii_alpha_char_7bit, + .isupper_char = pm_encoding_ascii_isupper_char_7bit, + .multibyte = true + }, + [PM_ENCODING_CP950] = { + .name = "CP950", + .char_width = pm_encoding_big5_char_width, + .alnum_char = pm_encoding_ascii_alnum_char_7bit, + .alpha_char = pm_encoding_ascii_alpha_char_7bit, + .isupper_char = pm_encoding_ascii_isupper_char_7bit, + .multibyte = true + }, + [PM_ENCODING_CP951] = { + .name = "CP951", + .char_width = pm_encoding_big5_char_width, + .alnum_char = pm_encoding_ascii_alnum_char_7bit, + .alpha_char = pm_encoding_ascii_alpha_char_7bit, + .isupper_char = pm_encoding_ascii_isupper_char_7bit, + .multibyte = true + }, + [PM_ENCODING_EMACS_MULE] = { + .name = "Emacs-Mule", + .char_width = pm_encoding_emacs_mule_char_width, + .alnum_char = pm_encoding_ascii_alnum_char_7bit, + .alpha_char = pm_encoding_ascii_alpha_char_7bit, + .isupper_char = pm_encoding_ascii_isupper_char_7bit, + .multibyte = true + }, + [PM_ENCODING_EUC_JP_MS] = { + .name = "eucJP-ms", + .char_width = pm_encoding_euc_jp_char_width, + .alnum_char = pm_encoding_ascii_alnum_char_7bit, + .alpha_char = pm_encoding_ascii_alpha_char_7bit, + .isupper_char = pm_encoding_euc_jp_isupper_char, + .multibyte = true + }, + [PM_ENCODING_EUC_JIS_2004] = { + .name = "EUC-JIS-2004", + .char_width = pm_encoding_euc_jp_char_width, + .alnum_char = pm_encoding_ascii_alnum_char_7bit, + .alpha_char = pm_encoding_ascii_alpha_char_7bit, + .isupper_char = pm_encoding_euc_jp_isupper_char, + .multibyte = true + }, + [PM_ENCODING_EUC_KR] = { + .name = "EUC-KR", + .char_width = pm_encoding_euc_kr_char_width, + .alnum_char = pm_encoding_ascii_alnum_char_7bit, + .alpha_char = pm_encoding_ascii_alpha_char_7bit, + .isupper_char = pm_encoding_ascii_isupper_char_7bit, + .multibyte = true + }, + [PM_ENCODING_EUC_TW] = { + .name = "EUC-TW", + .char_width = pm_encoding_euc_tw_char_width, + .alnum_char = pm_encoding_ascii_alnum_char_7bit, + .alpha_char = pm_encoding_ascii_alpha_char_7bit, + .isupper_char = pm_encoding_ascii_isupper_char_7bit, + .multibyte = true + }, + [PM_ENCODING_GB12345] = { + .name = "GB12345", + .char_width = pm_encoding_euc_kr_char_width, + .alnum_char = pm_encoding_ascii_alnum_char_7bit, + .alpha_char = pm_encoding_ascii_alpha_char_7bit, + .isupper_char = pm_encoding_ascii_isupper_char_7bit, + .multibyte = true + }, + [PM_ENCODING_GB18030] = { + .name = "GB18030", + .char_width = pm_encoding_gb18030_char_width, + .alnum_char = pm_encoding_ascii_alnum_char_7bit, + .alpha_char = pm_encoding_ascii_alpha_char_7bit, + .isupper_char = pm_encoding_ascii_isupper_char_7bit, + .multibyte = true + }, + [PM_ENCODING_GB1988] = { + .name = "GB1988", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_gb1988_alnum_char, + .alpha_char = pm_encoding_gb1988_alpha_char, + .isupper_char = pm_encoding_gb1988_isupper_char, + .multibyte = false + }, + [PM_ENCODING_GB2312] = { + .name = "GB2312", + .char_width = pm_encoding_euc_kr_char_width, + .alnum_char = pm_encoding_ascii_alnum_char_7bit, + .alpha_char = pm_encoding_ascii_alpha_char_7bit, + .isupper_char = pm_encoding_ascii_isupper_char_7bit, + .multibyte = true + }, + [PM_ENCODING_GBK] = { + .name = "GBK", + .char_width = pm_encoding_gbk_char_width, + .alnum_char = pm_encoding_ascii_alnum_char_7bit, + .alpha_char = pm_encoding_ascii_alpha_char_7bit, + .isupper_char = pm_encoding_ascii_isupper_char_7bit, + .multibyte = true + }, + [PM_ENCODING_IBM437] = { + .name = "IBM437", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_ibm437_alnum_char, + .alpha_char = pm_encoding_ibm437_alpha_char, + .isupper_char = pm_encoding_ibm437_isupper_char, + .multibyte = false + }, + [PM_ENCODING_IBM720] = { + .name = "IBM720", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_ibm720_alnum_char, + .alpha_char = pm_encoding_ibm720_alpha_char, + .isupper_char = pm_encoding_ibm720_isupper_char, + .multibyte = false + }, + [PM_ENCODING_IBM737] = { + .name = "IBM737", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_ibm737_alnum_char, + .alpha_char = pm_encoding_ibm737_alpha_char, + .isupper_char = pm_encoding_ibm737_isupper_char, + .multibyte = false + }, + [PM_ENCODING_IBM775] = { + .name = "IBM775", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_ibm775_alnum_char, + .alpha_char = pm_encoding_ibm775_alpha_char, + .isupper_char = pm_encoding_ibm775_isupper_char, + .multibyte = false + }, + [PM_ENCODING_IBM852] = { + .name = "IBM852", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_ibm852_alnum_char, + .alpha_char = pm_encoding_ibm852_alpha_char, + .isupper_char = pm_encoding_ibm852_isupper_char, + .multibyte = false + }, + [PM_ENCODING_IBM855] = { + .name = "IBM855", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_ibm855_alnum_char, + .alpha_char = pm_encoding_ibm855_alpha_char, + .isupper_char = pm_encoding_ibm855_isupper_char, + .multibyte = false + }, + [PM_ENCODING_IBM857] = { + .name = "IBM857", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_ibm857_alnum_char, + .alpha_char = pm_encoding_ibm857_alpha_char, + .isupper_char = pm_encoding_ibm857_isupper_char, + .multibyte = false + }, + [PM_ENCODING_IBM860] = { + .name = "IBM860", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_ibm860_alnum_char, + .alpha_char = pm_encoding_ibm860_alpha_char, + .isupper_char = pm_encoding_ibm860_isupper_char, + .multibyte = false + }, + [PM_ENCODING_IBM861] = { + .name = "IBM861", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_ibm861_alnum_char, + .alpha_char = pm_encoding_ibm861_alpha_char, + .isupper_char = pm_encoding_ibm861_isupper_char, + .multibyte = false + }, + [PM_ENCODING_IBM862] = { + .name = "IBM862", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_ibm862_alnum_char, + .alpha_char = pm_encoding_ibm862_alpha_char, + .isupper_char = pm_encoding_ibm862_isupper_char, + .multibyte = false + }, + [PM_ENCODING_IBM863] = { + .name = "IBM863", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_ibm863_alnum_char, + .alpha_char = pm_encoding_ibm863_alpha_char, + .isupper_char = pm_encoding_ibm863_isupper_char, + .multibyte = false + }, + [PM_ENCODING_IBM864] = { + .name = "IBM864", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_ibm864_alnum_char, + .alpha_char = pm_encoding_ibm864_alpha_char, + .isupper_char = pm_encoding_ibm864_isupper_char, + .multibyte = false + }, + [PM_ENCODING_IBM865] = { + .name = "IBM865", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_ibm865_alnum_char, + .alpha_char = pm_encoding_ibm865_alpha_char, + .isupper_char = pm_encoding_ibm865_isupper_char, + .multibyte = false + }, + [PM_ENCODING_IBM866] = { + .name = "IBM866", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_ibm866_alnum_char, + .alpha_char = pm_encoding_ibm866_alpha_char, + .isupper_char = pm_encoding_ibm866_isupper_char, + .multibyte = false + }, + [PM_ENCODING_IBM869] = { + .name = "IBM869", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_ibm869_alnum_char, + .alpha_char = pm_encoding_ibm869_alpha_char, + .isupper_char = pm_encoding_ibm869_isupper_char, + .multibyte = false + }, + [PM_ENCODING_ISO_8859_1] = { + .name = "ISO-8859-1", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_iso_8859_1_alnum_char, + .alpha_char = pm_encoding_iso_8859_1_alpha_char, + .isupper_char = pm_encoding_iso_8859_1_isupper_char, + .multibyte = false + }, + [PM_ENCODING_ISO_8859_2] = { + .name = "ISO-8859-2", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_iso_8859_2_alnum_char, + .alpha_char = pm_encoding_iso_8859_2_alpha_char, + .isupper_char = pm_encoding_iso_8859_2_isupper_char, + .multibyte = false + }, + [PM_ENCODING_ISO_8859_3] = { + .name = "ISO-8859-3", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_iso_8859_3_alnum_char, + .alpha_char = pm_encoding_iso_8859_3_alpha_char, + .isupper_char = pm_encoding_iso_8859_3_isupper_char, + .multibyte = false + }, + [PM_ENCODING_ISO_8859_4] = { + .name = "ISO-8859-4", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_iso_8859_4_alnum_char, + .alpha_char = pm_encoding_iso_8859_4_alpha_char, + .isupper_char = pm_encoding_iso_8859_4_isupper_char, + .multibyte = false + }, + [PM_ENCODING_ISO_8859_5] = { + .name = "ISO-8859-5", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_iso_8859_5_alnum_char, + .alpha_char = pm_encoding_iso_8859_5_alpha_char, + .isupper_char = pm_encoding_iso_8859_5_isupper_char, + .multibyte = false + }, + [PM_ENCODING_ISO_8859_6] = { + .name = "ISO-8859-6", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_iso_8859_6_alnum_char, + .alpha_char = pm_encoding_iso_8859_6_alpha_char, + .isupper_char = pm_encoding_iso_8859_6_isupper_char, + .multibyte = false + }, + [PM_ENCODING_ISO_8859_7] = { + .name = "ISO-8859-7", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_iso_8859_7_alnum_char, + .alpha_char = pm_encoding_iso_8859_7_alpha_char, + .isupper_char = pm_encoding_iso_8859_7_isupper_char, + .multibyte = false + }, + [PM_ENCODING_ISO_8859_8] = { + .name = "ISO-8859-8", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_iso_8859_8_alnum_char, + .alpha_char = pm_encoding_iso_8859_8_alpha_char, + .isupper_char = pm_encoding_iso_8859_8_isupper_char, + .multibyte = false + }, + [PM_ENCODING_ISO_8859_9] = { + .name = "ISO-8859-9", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_iso_8859_9_alnum_char, + .alpha_char = pm_encoding_iso_8859_9_alpha_char, + .isupper_char = pm_encoding_iso_8859_9_isupper_char, + .multibyte = false + }, + [PM_ENCODING_ISO_8859_10] = { + .name = "ISO-8859-10", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_iso_8859_10_alnum_char, + .alpha_char = pm_encoding_iso_8859_10_alpha_char, + .isupper_char = pm_encoding_iso_8859_10_isupper_char, + .multibyte = false + }, + [PM_ENCODING_ISO_8859_11] = { + .name = "ISO-8859-11", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_iso_8859_11_alnum_char, + .alpha_char = pm_encoding_iso_8859_11_alpha_char, + .isupper_char = pm_encoding_iso_8859_11_isupper_char, + .multibyte = false + }, + [PM_ENCODING_ISO_8859_13] = { + .name = "ISO-8859-13", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_iso_8859_13_alnum_char, + .alpha_char = pm_encoding_iso_8859_13_alpha_char, + .isupper_char = pm_encoding_iso_8859_13_isupper_char, + .multibyte = false + }, + [PM_ENCODING_ISO_8859_14] = { + .name = "ISO-8859-14", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_iso_8859_14_alnum_char, + .alpha_char = pm_encoding_iso_8859_14_alpha_char, + .isupper_char = pm_encoding_iso_8859_14_isupper_char, + .multibyte = false + }, + [PM_ENCODING_ISO_8859_15] = { + .name = "ISO-8859-15", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_iso_8859_15_alnum_char, + .alpha_char = pm_encoding_iso_8859_15_alpha_char, + .isupper_char = pm_encoding_iso_8859_15_isupper_char, + .multibyte = false + }, + [PM_ENCODING_ISO_8859_16] = { + .name = "ISO-8859-16", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_iso_8859_16_alnum_char, + .alpha_char = pm_encoding_iso_8859_16_alpha_char, + .isupper_char = pm_encoding_iso_8859_16_isupper_char, + .multibyte = false + }, + [PM_ENCODING_KOI8_R] = { + .name = "KOI8-R", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_koi8_r_alnum_char, + .alpha_char = pm_encoding_koi8_r_alpha_char, + .isupper_char = pm_encoding_koi8_r_isupper_char, + .multibyte = false + }, + [PM_ENCODING_KOI8_U] = { + .name = "KOI8-U", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_koi8_u_alnum_char, + .alpha_char = pm_encoding_koi8_u_alpha_char, + .isupper_char = pm_encoding_koi8_u_isupper_char, + .multibyte = false + }, + [PM_ENCODING_MAC_CENT_EURO] = { + .name = "macCentEuro", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_mac_cent_euro_alnum_char, + .alpha_char = pm_encoding_mac_cent_euro_alpha_char, + .isupper_char = pm_encoding_mac_cent_euro_isupper_char, + .multibyte = false + }, + [PM_ENCODING_MAC_CROATIAN] = { + .name = "macCroatian", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_mac_croatian_alnum_char, + .alpha_char = pm_encoding_mac_croatian_alpha_char, + .isupper_char = pm_encoding_mac_croatian_isupper_char, + .multibyte = false + }, + [PM_ENCODING_MAC_CYRILLIC] = { + .name = "macCyrillic", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_mac_cyrillic_alnum_char, + .alpha_char = pm_encoding_mac_cyrillic_alpha_char, + .isupper_char = pm_encoding_mac_cyrillic_isupper_char, + .multibyte = false + }, + [PM_ENCODING_MAC_GREEK] = { + .name = "macGreek", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_mac_greek_alnum_char, + .alpha_char = pm_encoding_mac_greek_alpha_char, + .isupper_char = pm_encoding_mac_greek_isupper_char, + .multibyte = false + }, + [PM_ENCODING_MAC_ICELAND] = { + .name = "macIceland", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_mac_iceland_alnum_char, + .alpha_char = pm_encoding_mac_iceland_alpha_char, + .isupper_char = pm_encoding_mac_iceland_isupper_char, + .multibyte = false + }, + [PM_ENCODING_MAC_JAPANESE] = { + .name = "MacJapanese", + .char_width = pm_encoding_shift_jis_char_width, + .alnum_char = pm_encoding_shift_jis_alnum_char, + .alpha_char = pm_encoding_shift_jis_alpha_char, + .isupper_char = pm_encoding_shift_jis_isupper_char, + .multibyte = true + }, + [PM_ENCODING_MAC_ROMAN] = { + .name = "macRoman", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_mac_roman_alnum_char, + .alpha_char = pm_encoding_mac_roman_alpha_char, + .isupper_char = pm_encoding_mac_roman_isupper_char, + .multibyte = false + }, + [PM_ENCODING_MAC_ROMANIA] = { + .name = "macRomania", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_mac_romania_alnum_char, + .alpha_char = pm_encoding_mac_romania_alpha_char, + .isupper_char = pm_encoding_mac_romania_isupper_char, + .multibyte = false + }, + [PM_ENCODING_MAC_THAI] = { + .name = "macThai", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_mac_thai_alnum_char, + .alpha_char = pm_encoding_mac_thai_alpha_char, + .isupper_char = pm_encoding_mac_thai_isupper_char, + .multibyte = false + }, + [PM_ENCODING_MAC_TURKISH] = { + .name = "macTurkish", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_mac_turkish_alnum_char, + .alpha_char = pm_encoding_mac_turkish_alpha_char, + .isupper_char = pm_encoding_mac_turkish_isupper_char, + .multibyte = false + }, + [PM_ENCODING_MAC_UKRAINE] = { + .name = "macUkraine", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_mac_ukraine_alnum_char, + .alpha_char = pm_encoding_mac_ukraine_alpha_char, + .isupper_char = pm_encoding_mac_ukraine_isupper_char, + .multibyte = false + }, + [PM_ENCODING_SHIFT_JIS] = { + .name = "Shift_JIS", + .char_width = pm_encoding_shift_jis_char_width, + .alnum_char = pm_encoding_shift_jis_alnum_char, + .alpha_char = pm_encoding_shift_jis_alpha_char, + .isupper_char = pm_encoding_shift_jis_isupper_char, + .multibyte = true + }, + [PM_ENCODING_SJIS_DOCOMO] = { + .name = "SJIS-DoCoMo", + .char_width = pm_encoding_shift_jis_char_width, + .alnum_char = pm_encoding_shift_jis_alnum_char, + .alpha_char = pm_encoding_shift_jis_alpha_char, + .isupper_char = pm_encoding_shift_jis_isupper_char, + .multibyte = true + }, + [PM_ENCODING_SJIS_KDDI] = { + .name = "SJIS-KDDI", + .char_width = pm_encoding_shift_jis_char_width, + .alnum_char = pm_encoding_shift_jis_alnum_char, + .alpha_char = pm_encoding_shift_jis_alpha_char, + .isupper_char = pm_encoding_shift_jis_isupper_char, + .multibyte = true + }, + [PM_ENCODING_SJIS_SOFTBANK] = { + .name = "SJIS-SoftBank", + .char_width = pm_encoding_shift_jis_char_width, + .alnum_char = pm_encoding_shift_jis_alnum_char, + .alpha_char = pm_encoding_shift_jis_alpha_char, + .isupper_char = pm_encoding_shift_jis_isupper_char, + .multibyte = true + }, + [PM_ENCODING_STATELESS_ISO_2022_JP] = { + .name = "stateless-ISO-2022-JP", + .char_width = pm_encoding_emacs_mule_char_width, + .alnum_char = pm_encoding_ascii_alnum_char_7bit, + .alpha_char = pm_encoding_ascii_alpha_char_7bit, + .isupper_char = pm_encoding_ascii_isupper_char_7bit, + .multibyte = true + }, + [PM_ENCODING_STATELESS_ISO_2022_JP_KDDI] = { + .name = "stateless-ISO-2022-JP-KDDI", + .char_width = pm_encoding_emacs_mule_char_width, + .alnum_char = pm_encoding_ascii_alnum_char_7bit, + .alpha_char = pm_encoding_ascii_alpha_char_7bit, + .isupper_char = pm_encoding_ascii_isupper_char_7bit, + .multibyte = true + }, + [PM_ENCODING_TIS_620] = { + .name = "TIS-620", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_tis_620_alnum_char, + .alpha_char = pm_encoding_tis_620_alpha_char, + .isupper_char = pm_encoding_tis_620_isupper_char, + .multibyte = false + }, + [PM_ENCODING_UTF8_MAC] = { + .name = "UTF8-MAC", + .char_width = pm_encoding_utf_8_char_width, + .alnum_char = pm_encoding_utf_8_alnum_char, + .alpha_char = pm_encoding_utf_8_alpha_char, + .isupper_char = pm_encoding_utf_8_isupper_char, + .multibyte = true + }, + [PM_ENCODING_UTF8_DOCOMO] = { + .name = "UTF8-DoCoMo", + .char_width = pm_encoding_utf_8_char_width, + .alnum_char = pm_encoding_utf_8_alnum_char, + .alpha_char = pm_encoding_utf_8_alpha_char, + .isupper_char = pm_encoding_utf_8_isupper_char, + .multibyte = true + }, + [PM_ENCODING_UTF8_KDDI] = { + .name = "UTF8-KDDI", + .char_width = pm_encoding_utf_8_char_width, + .alnum_char = pm_encoding_utf_8_alnum_char, + .alpha_char = pm_encoding_utf_8_alpha_char, + .isupper_char = pm_encoding_utf_8_isupper_char, + .multibyte = true + }, + [PM_ENCODING_UTF8_SOFTBANK] = { + .name = "UTF8-SoftBank", + .char_width = pm_encoding_utf_8_char_width, + .alnum_char = pm_encoding_utf_8_alnum_char, + .alpha_char = pm_encoding_utf_8_alpha_char, + .isupper_char = pm_encoding_utf_8_isupper_char, + .multibyte = true + }, + [PM_ENCODING_WINDOWS_1250] = { + .name = "Windows-1250", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_windows_1250_alnum_char, + .alpha_char = pm_encoding_windows_1250_alpha_char, + .isupper_char = pm_encoding_windows_1250_isupper_char, + .multibyte = false + }, + [PM_ENCODING_WINDOWS_1251] = { + .name = "Windows-1251", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_windows_1251_alnum_char, + .alpha_char = pm_encoding_windows_1251_alpha_char, + .isupper_char = pm_encoding_windows_1251_isupper_char, + .multibyte = false + }, + [PM_ENCODING_WINDOWS_1252] = { + .name = "Windows-1252", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_windows_1252_alnum_char, + .alpha_char = pm_encoding_windows_1252_alpha_char, + .isupper_char = pm_encoding_windows_1252_isupper_char, + .multibyte = false + }, + [PM_ENCODING_WINDOWS_1253] = { + .name = "Windows-1253", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_windows_1253_alnum_char, + .alpha_char = pm_encoding_windows_1253_alpha_char, + .isupper_char = pm_encoding_windows_1253_isupper_char, + .multibyte = false + }, + [PM_ENCODING_WINDOWS_1254] = { + .name = "Windows-1254", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_windows_1254_alnum_char, + .alpha_char = pm_encoding_windows_1254_alpha_char, + .isupper_char = pm_encoding_windows_1254_isupper_char, + .multibyte = false + }, + [PM_ENCODING_WINDOWS_1255] = { + .name = "Windows-1255", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_windows_1255_alnum_char, + .alpha_char = pm_encoding_windows_1255_alpha_char, + .isupper_char = pm_encoding_windows_1255_isupper_char, + .multibyte = false + }, + [PM_ENCODING_WINDOWS_1256] = { + .name = "Windows-1256", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_windows_1256_alnum_char, + .alpha_char = pm_encoding_windows_1256_alpha_char, + .isupper_char = pm_encoding_windows_1256_isupper_char, + .multibyte = false + }, + [PM_ENCODING_WINDOWS_1257] = { + .name = "Windows-1257", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_windows_1257_alnum_char, + .alpha_char = pm_encoding_windows_1257_alpha_char, + .isupper_char = pm_encoding_windows_1257_isupper_char, + .multibyte = false + }, + [PM_ENCODING_WINDOWS_1258] = { + .name = "Windows-1258", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_windows_1258_alnum_char, + .alpha_char = pm_encoding_windows_1258_alpha_char, + .isupper_char = pm_encoding_windows_1258_isupper_char, + .multibyte = false + }, + [PM_ENCODING_WINDOWS_874] = { + .name = "Windows-874", + .char_width = pm_encoding_single_char_width, + .alnum_char = pm_encoding_windows_874_alnum_char, + .alpha_char = pm_encoding_windows_874_alpha_char, + .isupper_char = pm_encoding_windows_874_isupper_char, + .multibyte = false + } +#endif +}; + +/** + * Parse the given name of an encoding and return a pointer to the corresponding + * encoding struct if one can be found, otherwise return NULL. + */ +const pm_encoding_t * +pm_encoding_find(const uint8_t *start, const uint8_t *end) { + size_t width = (size_t) (end - start); + + // First, we're going to check for UTF-8. This is the most common encoding. + // UTF-8 can contain extra information at the end about the platform it is + // encoded on, such as UTF-8-MAC or UTF-8-UNIX. We'll ignore those suffixes. + if ((start + 5 <= end) && (pm_strncasecmp(start, (const uint8_t *) "UTF-8", 5) == 0)) { +#ifndef PRISM_ENCODING_EXCLUDE_FULL + // We need to explicitly handle UTF-8-HFS, as that one needs to switch + // over to being UTF8-MAC. + if (width == 9 && (pm_strncasecmp(start + 5, (const uint8_t *) "-HFS", 4) == 0)) { + return &pm_encodings[PM_ENCODING_UTF8_MAC]; + } +#endif + + // Otherwise we'll return the default UTF-8 encoding. + return PM_ENCODING_UTF_8_ENTRY; + } + + // Next, we're going to loop through each of the encodings that we handle + // explicitly. If we found one that we understand, we'll use that value. +#define ENCODING1(name, encoding) if (width == sizeof(name) - 1 && pm_strncasecmp(start, (const uint8_t *) name, width) == 0) return &pm_encodings[encoding]; +#define ENCODING2(name1, name2, encoding) ENCODING1(name1, encoding) ENCODING1(name2, encoding) + + if (width >= 3) { + switch (*start) { + case 'A': case 'a': + ENCODING1("ASCII", PM_ENCODING_US_ASCII); + ENCODING1("ASCII-8BIT", PM_ENCODING_ASCII_8BIT); + ENCODING1("ANSI_X3.4-1968", PM_ENCODING_US_ASCII); + break; + case 'B': case 'b': + ENCODING1("BINARY", PM_ENCODING_ASCII_8BIT); +#ifndef PRISM_ENCODING_EXCLUDE_FULL + ENCODING1("Big5", PM_ENCODING_BIG5); + ENCODING2("Big5-HKSCS", "Big5-HKSCS:2008", PM_ENCODING_BIG5_HKSCS); + ENCODING1("Big5-UAO", PM_ENCODING_BIG5_UAO); +#endif + break; + case 'C': case 'c': + ENCODING1("CP65001", PM_ENCODING_UTF_8); + ENCODING2("CP932", "csWindows31J", PM_ENCODING_WINDOWS_31J); +#ifndef PRISM_ENCODING_EXCLUDE_FULL + ENCODING1("CESU-8", PM_ENCODING_CESU_8); + ENCODING1("CP437", PM_ENCODING_IBM437); + ENCODING1("CP720", PM_ENCODING_IBM720); + ENCODING1("CP737", PM_ENCODING_IBM737); + ENCODING1("CP775", PM_ENCODING_IBM775); + ENCODING1("CP850", PM_ENCODING_CP850); + ENCODING1("CP852", PM_ENCODING_CP852); + ENCODING1("CP855", PM_ENCODING_CP855); + ENCODING1("CP857", PM_ENCODING_IBM857); + ENCODING1("CP860", PM_ENCODING_IBM860); + ENCODING1("CP861", PM_ENCODING_IBM861); + ENCODING1("CP862", PM_ENCODING_IBM862); + ENCODING1("CP864", PM_ENCODING_IBM864); + ENCODING1("CP865", PM_ENCODING_IBM865); + ENCODING1("CP866", PM_ENCODING_IBM866); + ENCODING1("CP869", PM_ENCODING_IBM869); + ENCODING1("CP874", PM_ENCODING_WINDOWS_874); + ENCODING1("CP878", PM_ENCODING_KOI8_R); + ENCODING1("CP863", PM_ENCODING_IBM863); + ENCODING1("CP936", PM_ENCODING_GBK); + ENCODING1("CP949", PM_ENCODING_CP949); + ENCODING1("CP950", PM_ENCODING_CP950); + ENCODING1("CP951", PM_ENCODING_CP951); + ENCODING1("CP1250", PM_ENCODING_WINDOWS_1250); + ENCODING1("CP1251", PM_ENCODING_WINDOWS_1251); + ENCODING1("CP1252", PM_ENCODING_WINDOWS_1252); + ENCODING1("CP1253", PM_ENCODING_WINDOWS_1253); + ENCODING1("CP1254", PM_ENCODING_WINDOWS_1254); + ENCODING1("CP1255", PM_ENCODING_WINDOWS_1255); + ENCODING1("CP1256", PM_ENCODING_WINDOWS_1256); + ENCODING1("CP1257", PM_ENCODING_WINDOWS_1257); + ENCODING1("CP1258", PM_ENCODING_WINDOWS_1258); + ENCODING1("CP51932", PM_ENCODING_CP51932); +#endif + break; + case 'E': case 'e': + ENCODING2("EUC-JP", "eucJP", PM_ENCODING_EUC_JP); +#ifndef PRISM_ENCODING_EXCLUDE_FULL + ENCODING2("eucJP-ms", "euc-jp-ms", PM_ENCODING_EUC_JP_MS); + ENCODING2("EUC-JIS-2004", "EUC-JISX0213", PM_ENCODING_EUC_JIS_2004); + ENCODING2("EUC-KR", "eucKR", PM_ENCODING_EUC_KR); + ENCODING2("EUC-CN", "eucCN", PM_ENCODING_GB2312); + ENCODING2("EUC-TW", "eucTW", PM_ENCODING_EUC_TW); + ENCODING1("Emacs-Mule", PM_ENCODING_EMACS_MULE); +#endif + break; + case 'G': case 'g': +#ifndef PRISM_ENCODING_EXCLUDE_FULL + ENCODING1("GBK", PM_ENCODING_GBK); + ENCODING1("GB12345", PM_ENCODING_GB12345); + ENCODING1("GB18030", PM_ENCODING_GB18030); + ENCODING1("GB1988", PM_ENCODING_GB1988); + ENCODING1("GB2312", PM_ENCODING_GB2312); +#endif + break; + case 'I': case 'i': +#ifndef PRISM_ENCODING_EXCLUDE_FULL + ENCODING1("IBM437", PM_ENCODING_IBM437); + ENCODING1("IBM720", PM_ENCODING_IBM720); + ENCODING1("IBM737", PM_ENCODING_IBM737); + ENCODING1("IBM775", PM_ENCODING_IBM775); + ENCODING1("IBM850", PM_ENCODING_CP850); + ENCODING1("IBM852", PM_ENCODING_IBM852); + ENCODING1("IBM855", PM_ENCODING_IBM855); + ENCODING1("IBM857", PM_ENCODING_IBM857); + ENCODING1("IBM860", PM_ENCODING_IBM860); + ENCODING1("IBM861", PM_ENCODING_IBM861); + ENCODING1("IBM862", PM_ENCODING_IBM862); + ENCODING1("IBM863", PM_ENCODING_IBM863); + ENCODING1("IBM864", PM_ENCODING_IBM864); + ENCODING1("IBM865", PM_ENCODING_IBM865); + ENCODING1("IBM866", PM_ENCODING_IBM866); + ENCODING1("IBM869", PM_ENCODING_IBM869); + ENCODING2("ISO-8859-1", "ISO8859-1", PM_ENCODING_ISO_8859_1); + ENCODING2("ISO-8859-2", "ISO8859-2", PM_ENCODING_ISO_8859_2); + ENCODING2("ISO-8859-3", "ISO8859-3", PM_ENCODING_ISO_8859_3); + ENCODING2("ISO-8859-4", "ISO8859-4", PM_ENCODING_ISO_8859_4); + ENCODING2("ISO-8859-5", "ISO8859-5", PM_ENCODING_ISO_8859_5); + ENCODING2("ISO-8859-6", "ISO8859-6", PM_ENCODING_ISO_8859_6); + ENCODING2("ISO-8859-7", "ISO8859-7", PM_ENCODING_ISO_8859_7); + ENCODING2("ISO-8859-8", "ISO8859-8", PM_ENCODING_ISO_8859_8); + ENCODING2("ISO-8859-9", "ISO8859-9", PM_ENCODING_ISO_8859_9); + ENCODING2("ISO-8859-10", "ISO8859-10", PM_ENCODING_ISO_8859_10); + ENCODING2("ISO-8859-11", "ISO8859-11", PM_ENCODING_ISO_8859_11); + ENCODING2("ISO-8859-13", "ISO8859-13", PM_ENCODING_ISO_8859_13); + ENCODING2("ISO-8859-14", "ISO8859-14", PM_ENCODING_ISO_8859_14); + ENCODING2("ISO-8859-15", "ISO8859-15", PM_ENCODING_ISO_8859_15); + ENCODING2("ISO-8859-16", "ISO8859-16", PM_ENCODING_ISO_8859_16); +#endif + break; + case 'K': case 'k': +#ifndef PRISM_ENCODING_EXCLUDE_FULL + ENCODING1("KOI8-R", PM_ENCODING_KOI8_R); + ENCODING1("KOI8-U", PM_ENCODING_KOI8_U); +#endif + break; + case 'M': case 'm': +#ifndef PRISM_ENCODING_EXCLUDE_FULL + ENCODING1("macCentEuro", PM_ENCODING_MAC_CENT_EURO); + ENCODING1("macCroatian", PM_ENCODING_MAC_CROATIAN); + ENCODING1("macCyrillic", PM_ENCODING_MAC_CYRILLIC); + ENCODING1("macGreek", PM_ENCODING_MAC_GREEK); + ENCODING1("macIceland", PM_ENCODING_MAC_ICELAND); + ENCODING1("MacJapanese", PM_ENCODING_MAC_JAPANESE); + ENCODING1("MacJapan", PM_ENCODING_MAC_JAPANESE); + ENCODING1("macRoman", PM_ENCODING_MAC_ROMAN); + ENCODING1("macRomania", PM_ENCODING_MAC_ROMANIA); + ENCODING1("macThai", PM_ENCODING_MAC_THAI); + ENCODING1("macTurkish", PM_ENCODING_MAC_TURKISH); + ENCODING1("macUkraine", PM_ENCODING_MAC_UKRAINE); +#endif + break; + case 'P': case 'p': + ENCODING1("PCK", PM_ENCODING_WINDOWS_31J); + break; + case 'S': case 's': + ENCODING1("SJIS", PM_ENCODING_WINDOWS_31J); +#ifndef PRISM_ENCODING_EXCLUDE_FULL + ENCODING1("Shift_JIS", PM_ENCODING_SHIFT_JIS); + ENCODING1("SJIS-DoCoMo", PM_ENCODING_SJIS_DOCOMO); + ENCODING1("SJIS-KDDI", PM_ENCODING_SJIS_KDDI); + ENCODING1("SJIS-SoftBank", PM_ENCODING_SJIS_SOFTBANK); + ENCODING1("stateless-ISO-2022-JP", PM_ENCODING_STATELESS_ISO_2022_JP); + ENCODING1("stateless-ISO-2022-JP-KDDI", PM_ENCODING_STATELESS_ISO_2022_JP_KDDI); +#endif + break; + case 'T': case 't': +#ifndef PRISM_ENCODING_EXCLUDE_FULL + ENCODING1("TIS-620", PM_ENCODING_TIS_620); +#endif + break; + case 'U': case 'u': + ENCODING1("US-ASCII", PM_ENCODING_US_ASCII); +#ifndef PRISM_ENCODING_EXCLUDE_FULL + ENCODING2("UTF8-MAC", "UTF-8-HFS", PM_ENCODING_UTF8_MAC); + ENCODING1("UTF8-DoCoMo", PM_ENCODING_UTF8_DOCOMO); + ENCODING1("UTF8-KDDI", PM_ENCODING_UTF8_KDDI); + ENCODING1("UTF8-SoftBank", PM_ENCODING_UTF8_SOFTBANK); +#endif + break; + case 'W': case 'w': + ENCODING1("Windows-31J", PM_ENCODING_WINDOWS_31J); +#ifndef PRISM_ENCODING_EXCLUDE_FULL + ENCODING1("Windows-874", PM_ENCODING_WINDOWS_874); + ENCODING1("Windows-1250", PM_ENCODING_WINDOWS_1250); + ENCODING1("Windows-1251", PM_ENCODING_WINDOWS_1251); + ENCODING1("Windows-1252", PM_ENCODING_WINDOWS_1252); + ENCODING1("Windows-1253", PM_ENCODING_WINDOWS_1253); + ENCODING1("Windows-1254", PM_ENCODING_WINDOWS_1254); + ENCODING1("Windows-1255", PM_ENCODING_WINDOWS_1255); + ENCODING1("Windows-1256", PM_ENCODING_WINDOWS_1256); + ENCODING1("Windows-1257", PM_ENCODING_WINDOWS_1257); + ENCODING1("Windows-1258", PM_ENCODING_WINDOWS_1258); +#endif + break; + case '6': + ENCODING1("646", PM_ENCODING_US_ASCII); + break; + } + } + +#undef ENCODING2 +#undef ENCODING1 + + // If we didn't match any encodings, return NULL. + return NULL; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/node.c b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/node.c new file mode 100644 index 00000000..9c666b80 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/node.c @@ -0,0 +1,8674 @@ +/*----------------------------------------------------------------------------*/ +/* This file is generated by the templates/template.rb script and should not */ +/* be modified manually. See */ +/* templates/src/node.c.erb */ +/* if you are looking to modify the */ +/* template */ +/*----------------------------------------------------------------------------*/ + +#line 2 "prism/templates/src/node.c.erb" +#include "prism/node.h" + +/** + * Attempts to grow the node list to the next size. If there is already + * capacity in the list, this function does nothing. Otherwise it reallocates + * the list to be twice as large as it was before. If the reallocation fails, + * this function returns false, otherwise it returns true. + */ +static bool +pm_node_list_grow(pm_node_list_t *list, size_t size) { + size_t requested_size = list->size + size; + + // If the requested size caused overflow, return false. + if (requested_size < list->size) return false; + + // If the requested size is within the existing capacity, return true. + if (requested_size < list->capacity) return true; + + // Otherwise, reallocate the list to be twice as large as it was before. + size_t next_capacity = list->capacity == 0 ? 4 : list->capacity * 2; + + // If multiplying by 2 caused overflow, return false. + if (next_capacity < list->capacity) return false; + + // If we didn't get enough by doubling, keep doubling until we do. + while (requested_size > next_capacity) { + size_t double_capacity = next_capacity * 2; + + // Ensure we didn't overflow by multiplying by 2. + if (double_capacity < next_capacity) return false; + next_capacity = double_capacity; + } + + pm_node_t **nodes = (pm_node_t **) xrealloc(list->nodes, sizeof(pm_node_t *) * next_capacity); + if (nodes == NULL) return false; + + list->nodes = nodes; + list->capacity = next_capacity; + return true; +} + +/** + * Append a new node onto the end of the node list. + */ +void +pm_node_list_append(pm_node_list_t *list, pm_node_t *node) { + if (pm_node_list_grow(list, 1)) { + list->nodes[list->size++] = node; + } +} + +/** + * Prepend a new node onto the beginning of the node list. + */ +void +pm_node_list_prepend(pm_node_list_t *list, pm_node_t *node) { + if (pm_node_list_grow(list, 1)) { + memmove(list->nodes + 1, list->nodes, list->size * sizeof(pm_node_t *)); + list->nodes[0] = node; + list->size++; + } +} + +/** + * Concatenate the given node list onto the end of the other node list. + */ +void +pm_node_list_concat(pm_node_list_t *list, pm_node_list_t *other) { + if (other->size > 0 && pm_node_list_grow(list, other->size)) { + memcpy(list->nodes + list->size, other->nodes, other->size * sizeof(pm_node_t *)); + list->size += other->size; + } +} + +/** + * Free the internal memory associated with the given node list. + */ +void +pm_node_list_free(pm_node_list_t *list) { + if (list->capacity > 0) { + xfree(list->nodes); + *list = (pm_node_list_t) { 0 }; + } +} + +PRISM_EXPORTED_FUNCTION void +pm_node_destroy(pm_parser_t *parser, pm_node_t *node); + +/** + * Destroy the nodes that are contained within the given node list. + */ +static void +pm_node_list_destroy(pm_parser_t *parser, pm_node_list_t *list) { + pm_node_t *node; + PM_NODE_LIST_FOREACH(list, index, node) pm_node_destroy(parser, node); + pm_node_list_free(list); +} + +/** + * Deallocate the space for a pm_node_t. Similarly to pm_node_alloc, we're not + * using the parser argument, but it's there to allow for the future possibility + * of pre-allocating larger memory pools. + */ +PRISM_EXPORTED_FUNCTION void +pm_node_destroy(pm_parser_t *parser, pm_node_t *node) { + switch (PM_NODE_TYPE(node)) { +#line 110 "prism/templates/src/node.c.erb" + case PM_ALIAS_GLOBAL_VARIABLE_NODE: { + pm_alias_global_variable_node_t *cast = (pm_alias_global_variable_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->new_name); + pm_node_destroy(parser, (pm_node_t *)cast->old_name); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_ALIAS_METHOD_NODE: { + pm_alias_method_node_t *cast = (pm_alias_method_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->new_name); + pm_node_destroy(parser, (pm_node_t *)cast->old_name); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_ALTERNATION_PATTERN_NODE: { + pm_alternation_pattern_node_t *cast = (pm_alternation_pattern_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->left); + pm_node_destroy(parser, (pm_node_t *)cast->right); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_AND_NODE: { + pm_and_node_t *cast = (pm_and_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->left); + pm_node_destroy(parser, (pm_node_t *)cast->right); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_ARGUMENTS_NODE: { + pm_arguments_node_t *cast = (pm_arguments_node_t *) node; + pm_node_list_destroy(parser, &cast->arguments); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_ARRAY_NODE: { + pm_array_node_t *cast = (pm_array_node_t *) node; + pm_node_list_destroy(parser, &cast->elements); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_ARRAY_PATTERN_NODE: { + pm_array_pattern_node_t *cast = (pm_array_pattern_node_t *) node; + if (cast->constant != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->constant); + } + pm_node_list_destroy(parser, &cast->requireds); + if (cast->rest != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->rest); + } + pm_node_list_destroy(parser, &cast->posts); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_ASSOC_NODE: { + pm_assoc_node_t *cast = (pm_assoc_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->key); + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_ASSOC_SPLAT_NODE: { + pm_assoc_splat_node_t *cast = (pm_assoc_splat_node_t *) node; + if (cast->value != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->value); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_BACK_REFERENCE_READ_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_BEGIN_NODE: { + pm_begin_node_t *cast = (pm_begin_node_t *) node; + if (cast->statements != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->statements); + } + if (cast->rescue_clause != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->rescue_clause); + } + if (cast->else_clause != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->else_clause); + } + if (cast->ensure_clause != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->ensure_clause); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_BLOCK_ARGUMENT_NODE: { + pm_block_argument_node_t *cast = (pm_block_argument_node_t *) node; + if (cast->expression != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->expression); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_BLOCK_LOCAL_VARIABLE_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_BLOCK_NODE: { + pm_block_node_t *cast = (pm_block_node_t *) node; + pm_constant_id_list_free(&cast->locals); + if (cast->parameters != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->parameters); + } + if (cast->body != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->body); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_BLOCK_PARAMETER_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_BLOCK_PARAMETERS_NODE: { + pm_block_parameters_node_t *cast = (pm_block_parameters_node_t *) node; + if (cast->parameters != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->parameters); + } + pm_node_list_destroy(parser, &cast->locals); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_BREAK_NODE: { + pm_break_node_t *cast = (pm_break_node_t *) node; + if (cast->arguments != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->arguments); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CALL_AND_WRITE_NODE: { + pm_call_and_write_node_t *cast = (pm_call_and_write_node_t *) node; + if (cast->receiver != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->receiver); + } + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CALL_NODE: { + pm_call_node_t *cast = (pm_call_node_t *) node; + if (cast->receiver != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->receiver); + } + if (cast->arguments != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->arguments); + } + if (cast->block != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->block); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CALL_OPERATOR_WRITE_NODE: { + pm_call_operator_write_node_t *cast = (pm_call_operator_write_node_t *) node; + if (cast->receiver != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->receiver); + } + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CALL_OR_WRITE_NODE: { + pm_call_or_write_node_t *cast = (pm_call_or_write_node_t *) node; + if (cast->receiver != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->receiver); + } + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CALL_TARGET_NODE: { + pm_call_target_node_t *cast = (pm_call_target_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->receiver); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CAPTURE_PATTERN_NODE: { + pm_capture_pattern_node_t *cast = (pm_capture_pattern_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + pm_node_destroy(parser, (pm_node_t *)cast->target); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CASE_MATCH_NODE: { + pm_case_match_node_t *cast = (pm_case_match_node_t *) node; + if (cast->predicate != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->predicate); + } + pm_node_list_destroy(parser, &cast->conditions); + if (cast->else_clause != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->else_clause); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CASE_NODE: { + pm_case_node_t *cast = (pm_case_node_t *) node; + if (cast->predicate != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->predicate); + } + pm_node_list_destroy(parser, &cast->conditions); + if (cast->else_clause != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->else_clause); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CLASS_NODE: { + pm_class_node_t *cast = (pm_class_node_t *) node; + pm_constant_id_list_free(&cast->locals); + pm_node_destroy(parser, (pm_node_t *)cast->constant_path); + if (cast->superclass != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->superclass); + } + if (cast->body != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->body); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CLASS_VARIABLE_AND_WRITE_NODE: { + pm_class_variable_and_write_node_t *cast = (pm_class_variable_and_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE: { + pm_class_variable_operator_write_node_t *cast = (pm_class_variable_operator_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CLASS_VARIABLE_OR_WRITE_NODE: { + pm_class_variable_or_write_node_t *cast = (pm_class_variable_or_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CLASS_VARIABLE_READ_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CLASS_VARIABLE_TARGET_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CLASS_VARIABLE_WRITE_NODE: { + pm_class_variable_write_node_t *cast = (pm_class_variable_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CONSTANT_AND_WRITE_NODE: { + pm_constant_and_write_node_t *cast = (pm_constant_and_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CONSTANT_OPERATOR_WRITE_NODE: { + pm_constant_operator_write_node_t *cast = (pm_constant_operator_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CONSTANT_OR_WRITE_NODE: { + pm_constant_or_write_node_t *cast = (pm_constant_or_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CONSTANT_PATH_AND_WRITE_NODE: { + pm_constant_path_and_write_node_t *cast = (pm_constant_path_and_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->target); + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CONSTANT_PATH_NODE: { + pm_constant_path_node_t *cast = (pm_constant_path_node_t *) node; + if (cast->parent != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->parent); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CONSTANT_PATH_OPERATOR_WRITE_NODE: { + pm_constant_path_operator_write_node_t *cast = (pm_constant_path_operator_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->target); + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CONSTANT_PATH_OR_WRITE_NODE: { + pm_constant_path_or_write_node_t *cast = (pm_constant_path_or_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->target); + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CONSTANT_PATH_TARGET_NODE: { + pm_constant_path_target_node_t *cast = (pm_constant_path_target_node_t *) node; + if (cast->parent != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->parent); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CONSTANT_PATH_WRITE_NODE: { + pm_constant_path_write_node_t *cast = (pm_constant_path_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->target); + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CONSTANT_READ_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CONSTANT_TARGET_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_CONSTANT_WRITE_NODE: { + pm_constant_write_node_t *cast = (pm_constant_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_DEF_NODE: { + pm_def_node_t *cast = (pm_def_node_t *) node; + if (cast->receiver != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->receiver); + } + if (cast->parameters != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->parameters); + } + if (cast->body != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->body); + } + pm_constant_id_list_free(&cast->locals); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_DEFINED_NODE: { + pm_defined_node_t *cast = (pm_defined_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_ELSE_NODE: { + pm_else_node_t *cast = (pm_else_node_t *) node; + if (cast->statements != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->statements); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_EMBEDDED_STATEMENTS_NODE: { + pm_embedded_statements_node_t *cast = (pm_embedded_statements_node_t *) node; + if (cast->statements != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->statements); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_EMBEDDED_VARIABLE_NODE: { + pm_embedded_variable_node_t *cast = (pm_embedded_variable_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->variable); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_ENSURE_NODE: { + pm_ensure_node_t *cast = (pm_ensure_node_t *) node; + if (cast->statements != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->statements); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_FALSE_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_FIND_PATTERN_NODE: { + pm_find_pattern_node_t *cast = (pm_find_pattern_node_t *) node; + if (cast->constant != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->constant); + } + pm_node_destroy(parser, (pm_node_t *)cast->left); + pm_node_list_destroy(parser, &cast->requireds); + pm_node_destroy(parser, (pm_node_t *)cast->right); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_FLIP_FLOP_NODE: { + pm_flip_flop_node_t *cast = (pm_flip_flop_node_t *) node; + if (cast->left != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->left); + } + if (cast->right != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->right); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_FLOAT_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_FOR_NODE: { + pm_for_node_t *cast = (pm_for_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->index); + pm_node_destroy(parser, (pm_node_t *)cast->collection); + if (cast->statements != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->statements); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_FORWARDING_ARGUMENTS_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_FORWARDING_PARAMETER_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_FORWARDING_SUPER_NODE: { + pm_forwarding_super_node_t *cast = (pm_forwarding_super_node_t *) node; + if (cast->block != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->block); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_GLOBAL_VARIABLE_AND_WRITE_NODE: { + pm_global_variable_and_write_node_t *cast = (pm_global_variable_and_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE: { + pm_global_variable_operator_write_node_t *cast = (pm_global_variable_operator_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_GLOBAL_VARIABLE_OR_WRITE_NODE: { + pm_global_variable_or_write_node_t *cast = (pm_global_variable_or_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_GLOBAL_VARIABLE_READ_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_GLOBAL_VARIABLE_TARGET_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_GLOBAL_VARIABLE_WRITE_NODE: { + pm_global_variable_write_node_t *cast = (pm_global_variable_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_HASH_NODE: { + pm_hash_node_t *cast = (pm_hash_node_t *) node; + pm_node_list_destroy(parser, &cast->elements); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_HASH_PATTERN_NODE: { + pm_hash_pattern_node_t *cast = (pm_hash_pattern_node_t *) node; + if (cast->constant != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->constant); + } + pm_node_list_destroy(parser, &cast->elements); + if (cast->rest != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->rest); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_IF_NODE: { + pm_if_node_t *cast = (pm_if_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->predicate); + if (cast->statements != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->statements); + } + if (cast->subsequent != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->subsequent); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_IMAGINARY_NODE: { + pm_imaginary_node_t *cast = (pm_imaginary_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->numeric); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_IMPLICIT_NODE: { + pm_implicit_node_t *cast = (pm_implicit_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_IMPLICIT_REST_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_IN_NODE: { + pm_in_node_t *cast = (pm_in_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->pattern); + if (cast->statements != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->statements); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_INDEX_AND_WRITE_NODE: { + pm_index_and_write_node_t *cast = (pm_index_and_write_node_t *) node; + if (cast->receiver != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->receiver); + } + if (cast->arguments != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->arguments); + } + if (cast->block != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->block); + } + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_INDEX_OPERATOR_WRITE_NODE: { + pm_index_operator_write_node_t *cast = (pm_index_operator_write_node_t *) node; + if (cast->receiver != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->receiver); + } + if (cast->arguments != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->arguments); + } + if (cast->block != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->block); + } + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_INDEX_OR_WRITE_NODE: { + pm_index_or_write_node_t *cast = (pm_index_or_write_node_t *) node; + if (cast->receiver != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->receiver); + } + if (cast->arguments != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->arguments); + } + if (cast->block != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->block); + } + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_INDEX_TARGET_NODE: { + pm_index_target_node_t *cast = (pm_index_target_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->receiver); + if (cast->arguments != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->arguments); + } + if (cast->block != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->block); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_INSTANCE_VARIABLE_AND_WRITE_NODE: { + pm_instance_variable_and_write_node_t *cast = (pm_instance_variable_and_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE: { + pm_instance_variable_operator_write_node_t *cast = (pm_instance_variable_operator_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_INSTANCE_VARIABLE_OR_WRITE_NODE: { + pm_instance_variable_or_write_node_t *cast = (pm_instance_variable_or_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_INSTANCE_VARIABLE_READ_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_INSTANCE_VARIABLE_TARGET_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_INSTANCE_VARIABLE_WRITE_NODE: { + pm_instance_variable_write_node_t *cast = (pm_instance_variable_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_INTEGER_NODE: { + pm_integer_node_t *cast = (pm_integer_node_t *) node; + pm_integer_free(&cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_INTERPOLATED_MATCH_LAST_LINE_NODE: { + pm_interpolated_match_last_line_node_t *cast = (pm_interpolated_match_last_line_node_t *) node; + pm_node_list_destroy(parser, &cast->parts); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE: { + pm_interpolated_regular_expression_node_t *cast = (pm_interpolated_regular_expression_node_t *) node; + pm_node_list_destroy(parser, &cast->parts); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_INTERPOLATED_STRING_NODE: { + pm_interpolated_string_node_t *cast = (pm_interpolated_string_node_t *) node; + pm_node_list_destroy(parser, &cast->parts); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_INTERPOLATED_SYMBOL_NODE: { + pm_interpolated_symbol_node_t *cast = (pm_interpolated_symbol_node_t *) node; + pm_node_list_destroy(parser, &cast->parts); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_INTERPOLATED_X_STRING_NODE: { + pm_interpolated_x_string_node_t *cast = (pm_interpolated_x_string_node_t *) node; + pm_node_list_destroy(parser, &cast->parts); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_IT_LOCAL_VARIABLE_READ_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_IT_PARAMETERS_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_KEYWORD_HASH_NODE: { + pm_keyword_hash_node_t *cast = (pm_keyword_hash_node_t *) node; + pm_node_list_destroy(parser, &cast->elements); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_KEYWORD_REST_PARAMETER_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_LAMBDA_NODE: { + pm_lambda_node_t *cast = (pm_lambda_node_t *) node; + pm_constant_id_list_free(&cast->locals); + if (cast->parameters != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->parameters); + } + if (cast->body != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->body); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_LOCAL_VARIABLE_AND_WRITE_NODE: { + pm_local_variable_and_write_node_t *cast = (pm_local_variable_and_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE: { + pm_local_variable_operator_write_node_t *cast = (pm_local_variable_operator_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_LOCAL_VARIABLE_OR_WRITE_NODE: { + pm_local_variable_or_write_node_t *cast = (pm_local_variable_or_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_LOCAL_VARIABLE_READ_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_LOCAL_VARIABLE_TARGET_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_LOCAL_VARIABLE_WRITE_NODE: { + pm_local_variable_write_node_t *cast = (pm_local_variable_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_MATCH_LAST_LINE_NODE: { + pm_match_last_line_node_t *cast = (pm_match_last_line_node_t *) node; + pm_string_free(&cast->unescaped); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_MATCH_PREDICATE_NODE: { + pm_match_predicate_node_t *cast = (pm_match_predicate_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + pm_node_destroy(parser, (pm_node_t *)cast->pattern); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_MATCH_REQUIRED_NODE: { + pm_match_required_node_t *cast = (pm_match_required_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + pm_node_destroy(parser, (pm_node_t *)cast->pattern); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_MATCH_WRITE_NODE: { + pm_match_write_node_t *cast = (pm_match_write_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->call); + pm_node_list_destroy(parser, &cast->targets); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_MISSING_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_MODULE_NODE: { + pm_module_node_t *cast = (pm_module_node_t *) node; + pm_constant_id_list_free(&cast->locals); + pm_node_destroy(parser, (pm_node_t *)cast->constant_path); + if (cast->body != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->body); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_MULTI_TARGET_NODE: { + pm_multi_target_node_t *cast = (pm_multi_target_node_t *) node; + pm_node_list_destroy(parser, &cast->lefts); + if (cast->rest != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->rest); + } + pm_node_list_destroy(parser, &cast->rights); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_MULTI_WRITE_NODE: { + pm_multi_write_node_t *cast = (pm_multi_write_node_t *) node; + pm_node_list_destroy(parser, &cast->lefts); + if (cast->rest != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->rest); + } + pm_node_list_destroy(parser, &cast->rights); + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_NEXT_NODE: { + pm_next_node_t *cast = (pm_next_node_t *) node; + if (cast->arguments != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->arguments); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_NIL_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_NO_KEYWORDS_PARAMETER_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_NUMBERED_PARAMETERS_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_NUMBERED_REFERENCE_READ_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_OPTIONAL_KEYWORD_PARAMETER_NODE: { + pm_optional_keyword_parameter_node_t *cast = (pm_optional_keyword_parameter_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_OPTIONAL_PARAMETER_NODE: { + pm_optional_parameter_node_t *cast = (pm_optional_parameter_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->value); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_OR_NODE: { + pm_or_node_t *cast = (pm_or_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->left); + pm_node_destroy(parser, (pm_node_t *)cast->right); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_PARAMETERS_NODE: { + pm_parameters_node_t *cast = (pm_parameters_node_t *) node; + pm_node_list_destroy(parser, &cast->requireds); + pm_node_list_destroy(parser, &cast->optionals); + if (cast->rest != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->rest); + } + pm_node_list_destroy(parser, &cast->posts); + pm_node_list_destroy(parser, &cast->keywords); + if (cast->keyword_rest != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->keyword_rest); + } + if (cast->block != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->block); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_PARENTHESES_NODE: { + pm_parentheses_node_t *cast = (pm_parentheses_node_t *) node; + if (cast->body != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->body); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_PINNED_EXPRESSION_NODE: { + pm_pinned_expression_node_t *cast = (pm_pinned_expression_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->expression); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_PINNED_VARIABLE_NODE: { + pm_pinned_variable_node_t *cast = (pm_pinned_variable_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->variable); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_POST_EXECUTION_NODE: { + pm_post_execution_node_t *cast = (pm_post_execution_node_t *) node; + if (cast->statements != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->statements); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_PRE_EXECUTION_NODE: { + pm_pre_execution_node_t *cast = (pm_pre_execution_node_t *) node; + if (cast->statements != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->statements); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_PROGRAM_NODE: { + pm_program_node_t *cast = (pm_program_node_t *) node; + pm_constant_id_list_free(&cast->locals); + pm_node_destroy(parser, (pm_node_t *)cast->statements); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_RANGE_NODE: { + pm_range_node_t *cast = (pm_range_node_t *) node; + if (cast->left != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->left); + } + if (cast->right != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->right); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_RATIONAL_NODE: { + pm_rational_node_t *cast = (pm_rational_node_t *) node; + pm_integer_free(&cast->numerator); + pm_integer_free(&cast->denominator); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_REDO_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_REGULAR_EXPRESSION_NODE: { + pm_regular_expression_node_t *cast = (pm_regular_expression_node_t *) node; + pm_string_free(&cast->unescaped); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_REQUIRED_KEYWORD_PARAMETER_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_REQUIRED_PARAMETER_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_RESCUE_MODIFIER_NODE: { + pm_rescue_modifier_node_t *cast = (pm_rescue_modifier_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->expression); + pm_node_destroy(parser, (pm_node_t *)cast->rescue_expression); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_RESCUE_NODE: { + pm_rescue_node_t *cast = (pm_rescue_node_t *) node; + pm_node_list_destroy(parser, &cast->exceptions); + if (cast->reference != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->reference); + } + if (cast->statements != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->statements); + } + if (cast->subsequent != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->subsequent); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_REST_PARAMETER_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_RETRY_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_RETURN_NODE: { + pm_return_node_t *cast = (pm_return_node_t *) node; + if (cast->arguments != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->arguments); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_SELF_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_SHAREABLE_CONSTANT_NODE: { + pm_shareable_constant_node_t *cast = (pm_shareable_constant_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->write); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_SINGLETON_CLASS_NODE: { + pm_singleton_class_node_t *cast = (pm_singleton_class_node_t *) node; + pm_constant_id_list_free(&cast->locals); + pm_node_destroy(parser, (pm_node_t *)cast->expression); + if (cast->body != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->body); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_SOURCE_ENCODING_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_SOURCE_FILE_NODE: { + pm_source_file_node_t *cast = (pm_source_file_node_t *) node; + pm_string_free(&cast->filepath); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_SOURCE_LINE_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_SPLAT_NODE: { + pm_splat_node_t *cast = (pm_splat_node_t *) node; + if (cast->expression != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->expression); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_STATEMENTS_NODE: { + pm_statements_node_t *cast = (pm_statements_node_t *) node; + pm_node_list_destroy(parser, &cast->body); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_STRING_NODE: { + pm_string_node_t *cast = (pm_string_node_t *) node; + pm_string_free(&cast->unescaped); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_SUPER_NODE: { + pm_super_node_t *cast = (pm_super_node_t *) node; + if (cast->arguments != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->arguments); + } + if (cast->block != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->block); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_SYMBOL_NODE: { + pm_symbol_node_t *cast = (pm_symbol_node_t *) node; + pm_string_free(&cast->unescaped); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_TRUE_NODE: { + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_UNDEF_NODE: { + pm_undef_node_t *cast = (pm_undef_node_t *) node; + pm_node_list_destroy(parser, &cast->names); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_UNLESS_NODE: { + pm_unless_node_t *cast = (pm_unless_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->predicate); + if (cast->statements != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->statements); + } + if (cast->else_clause != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->else_clause); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_UNTIL_NODE: { + pm_until_node_t *cast = (pm_until_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->predicate); + if (cast->statements != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->statements); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_WHEN_NODE: { + pm_when_node_t *cast = (pm_when_node_t *) node; + pm_node_list_destroy(parser, &cast->conditions); + if (cast->statements != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->statements); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_WHILE_NODE: { + pm_while_node_t *cast = (pm_while_node_t *) node; + pm_node_destroy(parser, (pm_node_t *)cast->predicate); + if (cast->statements != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->statements); + } + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_X_STRING_NODE: { + pm_x_string_node_t *cast = (pm_x_string_node_t *) node; + pm_string_free(&cast->unescaped); + break; + } +#line 110 "prism/templates/src/node.c.erb" + case PM_YIELD_NODE: { + pm_yield_node_t *cast = (pm_yield_node_t *) node; + if (cast->arguments != NULL) { + pm_node_destroy(parser, (pm_node_t *)cast->arguments); + } + break; + } +#line 139 "prism/templates/src/node.c.erb" + default: + assert(false && "unreachable"); + break; + } + xfree(node); +} + +/** + * Returns a string representation of the given node type. + */ +PRISM_EXPORTED_FUNCTION const char * +pm_node_type_to_str(pm_node_type_t node_type) +{ + switch (node_type) { + case PM_ALIAS_GLOBAL_VARIABLE_NODE: + return "PM_ALIAS_GLOBAL_VARIABLE_NODE"; + case PM_ALIAS_METHOD_NODE: + return "PM_ALIAS_METHOD_NODE"; + case PM_ALTERNATION_PATTERN_NODE: + return "PM_ALTERNATION_PATTERN_NODE"; + case PM_AND_NODE: + return "PM_AND_NODE"; + case PM_ARGUMENTS_NODE: + return "PM_ARGUMENTS_NODE"; + case PM_ARRAY_NODE: + return "PM_ARRAY_NODE"; + case PM_ARRAY_PATTERN_NODE: + return "PM_ARRAY_PATTERN_NODE"; + case PM_ASSOC_NODE: + return "PM_ASSOC_NODE"; + case PM_ASSOC_SPLAT_NODE: + return "PM_ASSOC_SPLAT_NODE"; + case PM_BACK_REFERENCE_READ_NODE: + return "PM_BACK_REFERENCE_READ_NODE"; + case PM_BEGIN_NODE: + return "PM_BEGIN_NODE"; + case PM_BLOCK_ARGUMENT_NODE: + return "PM_BLOCK_ARGUMENT_NODE"; + case PM_BLOCK_LOCAL_VARIABLE_NODE: + return "PM_BLOCK_LOCAL_VARIABLE_NODE"; + case PM_BLOCK_NODE: + return "PM_BLOCK_NODE"; + case PM_BLOCK_PARAMETER_NODE: + return "PM_BLOCK_PARAMETER_NODE"; + case PM_BLOCK_PARAMETERS_NODE: + return "PM_BLOCK_PARAMETERS_NODE"; + case PM_BREAK_NODE: + return "PM_BREAK_NODE"; + case PM_CALL_AND_WRITE_NODE: + return "PM_CALL_AND_WRITE_NODE"; + case PM_CALL_NODE: + return "PM_CALL_NODE"; + case PM_CALL_OPERATOR_WRITE_NODE: + return "PM_CALL_OPERATOR_WRITE_NODE"; + case PM_CALL_OR_WRITE_NODE: + return "PM_CALL_OR_WRITE_NODE"; + case PM_CALL_TARGET_NODE: + return "PM_CALL_TARGET_NODE"; + case PM_CAPTURE_PATTERN_NODE: + return "PM_CAPTURE_PATTERN_NODE"; + case PM_CASE_MATCH_NODE: + return "PM_CASE_MATCH_NODE"; + case PM_CASE_NODE: + return "PM_CASE_NODE"; + case PM_CLASS_NODE: + return "PM_CLASS_NODE"; + case PM_CLASS_VARIABLE_AND_WRITE_NODE: + return "PM_CLASS_VARIABLE_AND_WRITE_NODE"; + case PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE: + return "PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE"; + case PM_CLASS_VARIABLE_OR_WRITE_NODE: + return "PM_CLASS_VARIABLE_OR_WRITE_NODE"; + case PM_CLASS_VARIABLE_READ_NODE: + return "PM_CLASS_VARIABLE_READ_NODE"; + case PM_CLASS_VARIABLE_TARGET_NODE: + return "PM_CLASS_VARIABLE_TARGET_NODE"; + case PM_CLASS_VARIABLE_WRITE_NODE: + return "PM_CLASS_VARIABLE_WRITE_NODE"; + case PM_CONSTANT_AND_WRITE_NODE: + return "PM_CONSTANT_AND_WRITE_NODE"; + case PM_CONSTANT_OPERATOR_WRITE_NODE: + return "PM_CONSTANT_OPERATOR_WRITE_NODE"; + case PM_CONSTANT_OR_WRITE_NODE: + return "PM_CONSTANT_OR_WRITE_NODE"; + case PM_CONSTANT_PATH_AND_WRITE_NODE: + return "PM_CONSTANT_PATH_AND_WRITE_NODE"; + case PM_CONSTANT_PATH_NODE: + return "PM_CONSTANT_PATH_NODE"; + case PM_CONSTANT_PATH_OPERATOR_WRITE_NODE: + return "PM_CONSTANT_PATH_OPERATOR_WRITE_NODE"; + case PM_CONSTANT_PATH_OR_WRITE_NODE: + return "PM_CONSTANT_PATH_OR_WRITE_NODE"; + case PM_CONSTANT_PATH_TARGET_NODE: + return "PM_CONSTANT_PATH_TARGET_NODE"; + case PM_CONSTANT_PATH_WRITE_NODE: + return "PM_CONSTANT_PATH_WRITE_NODE"; + case PM_CONSTANT_READ_NODE: + return "PM_CONSTANT_READ_NODE"; + case PM_CONSTANT_TARGET_NODE: + return "PM_CONSTANT_TARGET_NODE"; + case PM_CONSTANT_WRITE_NODE: + return "PM_CONSTANT_WRITE_NODE"; + case PM_DEF_NODE: + return "PM_DEF_NODE"; + case PM_DEFINED_NODE: + return "PM_DEFINED_NODE"; + case PM_ELSE_NODE: + return "PM_ELSE_NODE"; + case PM_EMBEDDED_STATEMENTS_NODE: + return "PM_EMBEDDED_STATEMENTS_NODE"; + case PM_EMBEDDED_VARIABLE_NODE: + return "PM_EMBEDDED_VARIABLE_NODE"; + case PM_ENSURE_NODE: + return "PM_ENSURE_NODE"; + case PM_FALSE_NODE: + return "PM_FALSE_NODE"; + case PM_FIND_PATTERN_NODE: + return "PM_FIND_PATTERN_NODE"; + case PM_FLIP_FLOP_NODE: + return "PM_FLIP_FLOP_NODE"; + case PM_FLOAT_NODE: + return "PM_FLOAT_NODE"; + case PM_FOR_NODE: + return "PM_FOR_NODE"; + case PM_FORWARDING_ARGUMENTS_NODE: + return "PM_FORWARDING_ARGUMENTS_NODE"; + case PM_FORWARDING_PARAMETER_NODE: + return "PM_FORWARDING_PARAMETER_NODE"; + case PM_FORWARDING_SUPER_NODE: + return "PM_FORWARDING_SUPER_NODE"; + case PM_GLOBAL_VARIABLE_AND_WRITE_NODE: + return "PM_GLOBAL_VARIABLE_AND_WRITE_NODE"; + case PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE: + return "PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE"; + case PM_GLOBAL_VARIABLE_OR_WRITE_NODE: + return "PM_GLOBAL_VARIABLE_OR_WRITE_NODE"; + case PM_GLOBAL_VARIABLE_READ_NODE: + return "PM_GLOBAL_VARIABLE_READ_NODE"; + case PM_GLOBAL_VARIABLE_TARGET_NODE: + return "PM_GLOBAL_VARIABLE_TARGET_NODE"; + case PM_GLOBAL_VARIABLE_WRITE_NODE: + return "PM_GLOBAL_VARIABLE_WRITE_NODE"; + case PM_HASH_NODE: + return "PM_HASH_NODE"; + case PM_HASH_PATTERN_NODE: + return "PM_HASH_PATTERN_NODE"; + case PM_IF_NODE: + return "PM_IF_NODE"; + case PM_IMAGINARY_NODE: + return "PM_IMAGINARY_NODE"; + case PM_IMPLICIT_NODE: + return "PM_IMPLICIT_NODE"; + case PM_IMPLICIT_REST_NODE: + return "PM_IMPLICIT_REST_NODE"; + case PM_IN_NODE: + return "PM_IN_NODE"; + case PM_INDEX_AND_WRITE_NODE: + return "PM_INDEX_AND_WRITE_NODE"; + case PM_INDEX_OPERATOR_WRITE_NODE: + return "PM_INDEX_OPERATOR_WRITE_NODE"; + case PM_INDEX_OR_WRITE_NODE: + return "PM_INDEX_OR_WRITE_NODE"; + case PM_INDEX_TARGET_NODE: + return "PM_INDEX_TARGET_NODE"; + case PM_INSTANCE_VARIABLE_AND_WRITE_NODE: + return "PM_INSTANCE_VARIABLE_AND_WRITE_NODE"; + case PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE: + return "PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE"; + case PM_INSTANCE_VARIABLE_OR_WRITE_NODE: + return "PM_INSTANCE_VARIABLE_OR_WRITE_NODE"; + case PM_INSTANCE_VARIABLE_READ_NODE: + return "PM_INSTANCE_VARIABLE_READ_NODE"; + case PM_INSTANCE_VARIABLE_TARGET_NODE: + return "PM_INSTANCE_VARIABLE_TARGET_NODE"; + case PM_INSTANCE_VARIABLE_WRITE_NODE: + return "PM_INSTANCE_VARIABLE_WRITE_NODE"; + case PM_INTEGER_NODE: + return "PM_INTEGER_NODE"; + case PM_INTERPOLATED_MATCH_LAST_LINE_NODE: + return "PM_INTERPOLATED_MATCH_LAST_LINE_NODE"; + case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE: + return "PM_INTERPOLATED_REGULAR_EXPRESSION_NODE"; + case PM_INTERPOLATED_STRING_NODE: + return "PM_INTERPOLATED_STRING_NODE"; + case PM_INTERPOLATED_SYMBOL_NODE: + return "PM_INTERPOLATED_SYMBOL_NODE"; + case PM_INTERPOLATED_X_STRING_NODE: + return "PM_INTERPOLATED_X_STRING_NODE"; + case PM_IT_LOCAL_VARIABLE_READ_NODE: + return "PM_IT_LOCAL_VARIABLE_READ_NODE"; + case PM_IT_PARAMETERS_NODE: + return "PM_IT_PARAMETERS_NODE"; + case PM_KEYWORD_HASH_NODE: + return "PM_KEYWORD_HASH_NODE"; + case PM_KEYWORD_REST_PARAMETER_NODE: + return "PM_KEYWORD_REST_PARAMETER_NODE"; + case PM_LAMBDA_NODE: + return "PM_LAMBDA_NODE"; + case PM_LOCAL_VARIABLE_AND_WRITE_NODE: + return "PM_LOCAL_VARIABLE_AND_WRITE_NODE"; + case PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE: + return "PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE"; + case PM_LOCAL_VARIABLE_OR_WRITE_NODE: + return "PM_LOCAL_VARIABLE_OR_WRITE_NODE"; + case PM_LOCAL_VARIABLE_READ_NODE: + return "PM_LOCAL_VARIABLE_READ_NODE"; + case PM_LOCAL_VARIABLE_TARGET_NODE: + return "PM_LOCAL_VARIABLE_TARGET_NODE"; + case PM_LOCAL_VARIABLE_WRITE_NODE: + return "PM_LOCAL_VARIABLE_WRITE_NODE"; + case PM_MATCH_LAST_LINE_NODE: + return "PM_MATCH_LAST_LINE_NODE"; + case PM_MATCH_PREDICATE_NODE: + return "PM_MATCH_PREDICATE_NODE"; + case PM_MATCH_REQUIRED_NODE: + return "PM_MATCH_REQUIRED_NODE"; + case PM_MATCH_WRITE_NODE: + return "PM_MATCH_WRITE_NODE"; + case PM_MISSING_NODE: + return "PM_MISSING_NODE"; + case PM_MODULE_NODE: + return "PM_MODULE_NODE"; + case PM_MULTI_TARGET_NODE: + return "PM_MULTI_TARGET_NODE"; + case PM_MULTI_WRITE_NODE: + return "PM_MULTI_WRITE_NODE"; + case PM_NEXT_NODE: + return "PM_NEXT_NODE"; + case PM_NIL_NODE: + return "PM_NIL_NODE"; + case PM_NO_KEYWORDS_PARAMETER_NODE: + return "PM_NO_KEYWORDS_PARAMETER_NODE"; + case PM_NUMBERED_PARAMETERS_NODE: + return "PM_NUMBERED_PARAMETERS_NODE"; + case PM_NUMBERED_REFERENCE_READ_NODE: + return "PM_NUMBERED_REFERENCE_READ_NODE"; + case PM_OPTIONAL_KEYWORD_PARAMETER_NODE: + return "PM_OPTIONAL_KEYWORD_PARAMETER_NODE"; + case PM_OPTIONAL_PARAMETER_NODE: + return "PM_OPTIONAL_PARAMETER_NODE"; + case PM_OR_NODE: + return "PM_OR_NODE"; + case PM_PARAMETERS_NODE: + return "PM_PARAMETERS_NODE"; + case PM_PARENTHESES_NODE: + return "PM_PARENTHESES_NODE"; + case PM_PINNED_EXPRESSION_NODE: + return "PM_PINNED_EXPRESSION_NODE"; + case PM_PINNED_VARIABLE_NODE: + return "PM_PINNED_VARIABLE_NODE"; + case PM_POST_EXECUTION_NODE: + return "PM_POST_EXECUTION_NODE"; + case PM_PRE_EXECUTION_NODE: + return "PM_PRE_EXECUTION_NODE"; + case PM_PROGRAM_NODE: + return "PM_PROGRAM_NODE"; + case PM_RANGE_NODE: + return "PM_RANGE_NODE"; + case PM_RATIONAL_NODE: + return "PM_RATIONAL_NODE"; + case PM_REDO_NODE: + return "PM_REDO_NODE"; + case PM_REGULAR_EXPRESSION_NODE: + return "PM_REGULAR_EXPRESSION_NODE"; + case PM_REQUIRED_KEYWORD_PARAMETER_NODE: + return "PM_REQUIRED_KEYWORD_PARAMETER_NODE"; + case PM_REQUIRED_PARAMETER_NODE: + return "PM_REQUIRED_PARAMETER_NODE"; + case PM_RESCUE_MODIFIER_NODE: + return "PM_RESCUE_MODIFIER_NODE"; + case PM_RESCUE_NODE: + return "PM_RESCUE_NODE"; + case PM_REST_PARAMETER_NODE: + return "PM_REST_PARAMETER_NODE"; + case PM_RETRY_NODE: + return "PM_RETRY_NODE"; + case PM_RETURN_NODE: + return "PM_RETURN_NODE"; + case PM_SELF_NODE: + return "PM_SELF_NODE"; + case PM_SHAREABLE_CONSTANT_NODE: + return "PM_SHAREABLE_CONSTANT_NODE"; + case PM_SINGLETON_CLASS_NODE: + return "PM_SINGLETON_CLASS_NODE"; + case PM_SOURCE_ENCODING_NODE: + return "PM_SOURCE_ENCODING_NODE"; + case PM_SOURCE_FILE_NODE: + return "PM_SOURCE_FILE_NODE"; + case PM_SOURCE_LINE_NODE: + return "PM_SOURCE_LINE_NODE"; + case PM_SPLAT_NODE: + return "PM_SPLAT_NODE"; + case PM_STATEMENTS_NODE: + return "PM_STATEMENTS_NODE"; + case PM_STRING_NODE: + return "PM_STRING_NODE"; + case PM_SUPER_NODE: + return "PM_SUPER_NODE"; + case PM_SYMBOL_NODE: + return "PM_SYMBOL_NODE"; + case PM_TRUE_NODE: + return "PM_TRUE_NODE"; + case PM_UNDEF_NODE: + return "PM_UNDEF_NODE"; + case PM_UNLESS_NODE: + return "PM_UNLESS_NODE"; + case PM_UNTIL_NODE: + return "PM_UNTIL_NODE"; + case PM_WHEN_NODE: + return "PM_WHEN_NODE"; + case PM_WHILE_NODE: + return "PM_WHILE_NODE"; + case PM_X_STRING_NODE: + return "PM_X_STRING_NODE"; + case PM_YIELD_NODE: + return "PM_YIELD_NODE"; + } + return ""; +} + +/** + * Visit each of the nodes in this subtree using the given visitor callback. The + * callback function will be called for each node in the subtree. If it returns + * false, then that node's children will not be visited. If it returns true, + * then the children will be visited. The data parameter is treated as an opaque + * pointer and is passed to the visitor callback for consumers to use as they + * see fit. + */ +PRISM_EXPORTED_FUNCTION void +pm_visit_node(const pm_node_t *node, bool (*visitor)(const pm_node_t *node, void *data), void *data) { + if (visitor(node, data)) pm_visit_child_nodes(node, visitor, data); +} + +/** + * Visit the children of the given node with the given callback. This is the + * default behavior for walking the tree that is called from pm_visit_node if + * the callback returns true. + */ +PRISM_EXPORTED_FUNCTION void +pm_visit_child_nodes(const pm_node_t *node, bool (*visitor)(const pm_node_t *node, void *data), void *data) { + switch (PM_NODE_TYPE(node)) { + case PM_ALIAS_GLOBAL_VARIABLE_NODE: { + const pm_alias_global_variable_node_t *cast = (const pm_alias_global_variable_node_t *) node; + + // Visit the new_name field + pm_visit_node((const pm_node_t *) cast->new_name, visitor, data); + + // Visit the old_name field + pm_visit_node((const pm_node_t *) cast->old_name, visitor, data); + + break; + } + case PM_ALIAS_METHOD_NODE: { + const pm_alias_method_node_t *cast = (const pm_alias_method_node_t *) node; + + // Visit the new_name field + pm_visit_node((const pm_node_t *) cast->new_name, visitor, data); + + // Visit the old_name field + pm_visit_node((const pm_node_t *) cast->old_name, visitor, data); + + break; + } + case PM_ALTERNATION_PATTERN_NODE: { + const pm_alternation_pattern_node_t *cast = (const pm_alternation_pattern_node_t *) node; + + // Visit the left field + pm_visit_node((const pm_node_t *) cast->left, visitor, data); + + // Visit the right field + pm_visit_node((const pm_node_t *) cast->right, visitor, data); + + break; + } + case PM_AND_NODE: { + const pm_and_node_t *cast = (const pm_and_node_t *) node; + + // Visit the left field + pm_visit_node((const pm_node_t *) cast->left, visitor, data); + + // Visit the right field + pm_visit_node((const pm_node_t *) cast->right, visitor, data); + + break; + } + case PM_ARGUMENTS_NODE: { + const pm_arguments_node_t *cast = (const pm_arguments_node_t *) node; + + // Visit the arguments field + const pm_node_list_t *arguments = &cast->arguments; + for (size_t index = 0; index < arguments->size; index++) { + pm_visit_node(arguments->nodes[index], visitor, data); + } + + break; + } + case PM_ARRAY_NODE: { + const pm_array_node_t *cast = (const pm_array_node_t *) node; + + // Visit the elements field + const pm_node_list_t *elements = &cast->elements; + for (size_t index = 0; index < elements->size; index++) { + pm_visit_node(elements->nodes[index], visitor, data); + } + + break; + } + case PM_ARRAY_PATTERN_NODE: { + const pm_array_pattern_node_t *cast = (const pm_array_pattern_node_t *) node; + + // Visit the constant field + if (cast->constant != NULL) { + pm_visit_node((const pm_node_t *) cast->constant, visitor, data); + } + + // Visit the requireds field + const pm_node_list_t *requireds = &cast->requireds; + for (size_t index = 0; index < requireds->size; index++) { + pm_visit_node(requireds->nodes[index], visitor, data); + } + + // Visit the rest field + if (cast->rest != NULL) { + pm_visit_node((const pm_node_t *) cast->rest, visitor, data); + } + + // Visit the posts field + const pm_node_list_t *posts = &cast->posts; + for (size_t index = 0; index < posts->size; index++) { + pm_visit_node(posts->nodes[index], visitor, data); + } + + break; + } + case PM_ASSOC_NODE: { + const pm_assoc_node_t *cast = (const pm_assoc_node_t *) node; + + // Visit the key field + pm_visit_node((const pm_node_t *) cast->key, visitor, data); + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_ASSOC_SPLAT_NODE: { + const pm_assoc_splat_node_t *cast = (const pm_assoc_splat_node_t *) node; + + // Visit the value field + if (cast->value != NULL) { + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + } + + break; + } + case PM_BACK_REFERENCE_READ_NODE: + break; + case PM_BEGIN_NODE: { + const pm_begin_node_t *cast = (const pm_begin_node_t *) node; + + // Visit the statements field + if (cast->statements != NULL) { + pm_visit_node((const pm_node_t *) cast->statements, visitor, data); + } + + // Visit the rescue_clause field + if (cast->rescue_clause != NULL) { + pm_visit_node((const pm_node_t *) cast->rescue_clause, visitor, data); + } + + // Visit the else_clause field + if (cast->else_clause != NULL) { + pm_visit_node((const pm_node_t *) cast->else_clause, visitor, data); + } + + // Visit the ensure_clause field + if (cast->ensure_clause != NULL) { + pm_visit_node((const pm_node_t *) cast->ensure_clause, visitor, data); + } + + break; + } + case PM_BLOCK_ARGUMENT_NODE: { + const pm_block_argument_node_t *cast = (const pm_block_argument_node_t *) node; + + // Visit the expression field + if (cast->expression != NULL) { + pm_visit_node((const pm_node_t *) cast->expression, visitor, data); + } + + break; + } + case PM_BLOCK_LOCAL_VARIABLE_NODE: + break; + case PM_BLOCK_NODE: { + const pm_block_node_t *cast = (const pm_block_node_t *) node; + + // Visit the parameters field + if (cast->parameters != NULL) { + pm_visit_node((const pm_node_t *) cast->parameters, visitor, data); + } + + // Visit the body field + if (cast->body != NULL) { + pm_visit_node((const pm_node_t *) cast->body, visitor, data); + } + + break; + } + case PM_BLOCK_PARAMETER_NODE: + break; + case PM_BLOCK_PARAMETERS_NODE: { + const pm_block_parameters_node_t *cast = (const pm_block_parameters_node_t *) node; + + // Visit the parameters field + if (cast->parameters != NULL) { + pm_visit_node((const pm_node_t *) cast->parameters, visitor, data); + } + + // Visit the locals field + const pm_node_list_t *locals = &cast->locals; + for (size_t index = 0; index < locals->size; index++) { + pm_visit_node(locals->nodes[index], visitor, data); + } + + break; + } + case PM_BREAK_NODE: { + const pm_break_node_t *cast = (const pm_break_node_t *) node; + + // Visit the arguments field + if (cast->arguments != NULL) { + pm_visit_node((const pm_node_t *) cast->arguments, visitor, data); + } + + break; + } + case PM_CALL_AND_WRITE_NODE: { + const pm_call_and_write_node_t *cast = (const pm_call_and_write_node_t *) node; + + // Visit the receiver field + if (cast->receiver != NULL) { + pm_visit_node((const pm_node_t *) cast->receiver, visitor, data); + } + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_CALL_NODE: { + const pm_call_node_t *cast = (const pm_call_node_t *) node; + + // Visit the receiver field + if (cast->receiver != NULL) { + pm_visit_node((const pm_node_t *) cast->receiver, visitor, data); + } + + // Visit the arguments field + if (cast->arguments != NULL) { + pm_visit_node((const pm_node_t *) cast->arguments, visitor, data); + } + + // Visit the block field + if (cast->block != NULL) { + pm_visit_node((const pm_node_t *) cast->block, visitor, data); + } + + break; + } + case PM_CALL_OPERATOR_WRITE_NODE: { + const pm_call_operator_write_node_t *cast = (const pm_call_operator_write_node_t *) node; + + // Visit the receiver field + if (cast->receiver != NULL) { + pm_visit_node((const pm_node_t *) cast->receiver, visitor, data); + } + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_CALL_OR_WRITE_NODE: { + const pm_call_or_write_node_t *cast = (const pm_call_or_write_node_t *) node; + + // Visit the receiver field + if (cast->receiver != NULL) { + pm_visit_node((const pm_node_t *) cast->receiver, visitor, data); + } + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_CALL_TARGET_NODE: { + const pm_call_target_node_t *cast = (const pm_call_target_node_t *) node; + + // Visit the receiver field + pm_visit_node((const pm_node_t *) cast->receiver, visitor, data); + + break; + } + case PM_CAPTURE_PATTERN_NODE: { + const pm_capture_pattern_node_t *cast = (const pm_capture_pattern_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + // Visit the target field + pm_visit_node((const pm_node_t *) cast->target, visitor, data); + + break; + } + case PM_CASE_MATCH_NODE: { + const pm_case_match_node_t *cast = (const pm_case_match_node_t *) node; + + // Visit the predicate field + if (cast->predicate != NULL) { + pm_visit_node((const pm_node_t *) cast->predicate, visitor, data); + } + + // Visit the conditions field + const pm_node_list_t *conditions = &cast->conditions; + for (size_t index = 0; index < conditions->size; index++) { + pm_visit_node(conditions->nodes[index], visitor, data); + } + + // Visit the else_clause field + if (cast->else_clause != NULL) { + pm_visit_node((const pm_node_t *) cast->else_clause, visitor, data); + } + + break; + } + case PM_CASE_NODE: { + const pm_case_node_t *cast = (const pm_case_node_t *) node; + + // Visit the predicate field + if (cast->predicate != NULL) { + pm_visit_node((const pm_node_t *) cast->predicate, visitor, data); + } + + // Visit the conditions field + const pm_node_list_t *conditions = &cast->conditions; + for (size_t index = 0; index < conditions->size; index++) { + pm_visit_node(conditions->nodes[index], visitor, data); + } + + // Visit the else_clause field + if (cast->else_clause != NULL) { + pm_visit_node((const pm_node_t *) cast->else_clause, visitor, data); + } + + break; + } + case PM_CLASS_NODE: { + const pm_class_node_t *cast = (const pm_class_node_t *) node; + + // Visit the constant_path field + pm_visit_node((const pm_node_t *) cast->constant_path, visitor, data); + + // Visit the superclass field + if (cast->superclass != NULL) { + pm_visit_node((const pm_node_t *) cast->superclass, visitor, data); + } + + // Visit the body field + if (cast->body != NULL) { + pm_visit_node((const pm_node_t *) cast->body, visitor, data); + } + + break; + } + case PM_CLASS_VARIABLE_AND_WRITE_NODE: { + const pm_class_variable_and_write_node_t *cast = (const pm_class_variable_and_write_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE: { + const pm_class_variable_operator_write_node_t *cast = (const pm_class_variable_operator_write_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_CLASS_VARIABLE_OR_WRITE_NODE: { + const pm_class_variable_or_write_node_t *cast = (const pm_class_variable_or_write_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_CLASS_VARIABLE_READ_NODE: + break; + case PM_CLASS_VARIABLE_TARGET_NODE: + break; + case PM_CLASS_VARIABLE_WRITE_NODE: { + const pm_class_variable_write_node_t *cast = (const pm_class_variable_write_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_CONSTANT_AND_WRITE_NODE: { + const pm_constant_and_write_node_t *cast = (const pm_constant_and_write_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_CONSTANT_OPERATOR_WRITE_NODE: { + const pm_constant_operator_write_node_t *cast = (const pm_constant_operator_write_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_CONSTANT_OR_WRITE_NODE: { + const pm_constant_or_write_node_t *cast = (const pm_constant_or_write_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_CONSTANT_PATH_AND_WRITE_NODE: { + const pm_constant_path_and_write_node_t *cast = (const pm_constant_path_and_write_node_t *) node; + + // Visit the target field + pm_visit_node((const pm_node_t *) cast->target, visitor, data); + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_CONSTANT_PATH_NODE: { + const pm_constant_path_node_t *cast = (const pm_constant_path_node_t *) node; + + // Visit the parent field + if (cast->parent != NULL) { + pm_visit_node((const pm_node_t *) cast->parent, visitor, data); + } + + break; + } + case PM_CONSTANT_PATH_OPERATOR_WRITE_NODE: { + const pm_constant_path_operator_write_node_t *cast = (const pm_constant_path_operator_write_node_t *) node; + + // Visit the target field + pm_visit_node((const pm_node_t *) cast->target, visitor, data); + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_CONSTANT_PATH_OR_WRITE_NODE: { + const pm_constant_path_or_write_node_t *cast = (const pm_constant_path_or_write_node_t *) node; + + // Visit the target field + pm_visit_node((const pm_node_t *) cast->target, visitor, data); + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_CONSTANT_PATH_TARGET_NODE: { + const pm_constant_path_target_node_t *cast = (const pm_constant_path_target_node_t *) node; + + // Visit the parent field + if (cast->parent != NULL) { + pm_visit_node((const pm_node_t *) cast->parent, visitor, data); + } + + break; + } + case PM_CONSTANT_PATH_WRITE_NODE: { + const pm_constant_path_write_node_t *cast = (const pm_constant_path_write_node_t *) node; + + // Visit the target field + pm_visit_node((const pm_node_t *) cast->target, visitor, data); + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_CONSTANT_READ_NODE: + break; + case PM_CONSTANT_TARGET_NODE: + break; + case PM_CONSTANT_WRITE_NODE: { + const pm_constant_write_node_t *cast = (const pm_constant_write_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_DEF_NODE: { + const pm_def_node_t *cast = (const pm_def_node_t *) node; + + // Visit the receiver field + if (cast->receiver != NULL) { + pm_visit_node((const pm_node_t *) cast->receiver, visitor, data); + } + + // Visit the parameters field + if (cast->parameters != NULL) { + pm_visit_node((const pm_node_t *) cast->parameters, visitor, data); + } + + // Visit the body field + if (cast->body != NULL) { + pm_visit_node((const pm_node_t *) cast->body, visitor, data); + } + + break; + } + case PM_DEFINED_NODE: { + const pm_defined_node_t *cast = (const pm_defined_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_ELSE_NODE: { + const pm_else_node_t *cast = (const pm_else_node_t *) node; + + // Visit the statements field + if (cast->statements != NULL) { + pm_visit_node((const pm_node_t *) cast->statements, visitor, data); + } + + break; + } + case PM_EMBEDDED_STATEMENTS_NODE: { + const pm_embedded_statements_node_t *cast = (const pm_embedded_statements_node_t *) node; + + // Visit the statements field + if (cast->statements != NULL) { + pm_visit_node((const pm_node_t *) cast->statements, visitor, data); + } + + break; + } + case PM_EMBEDDED_VARIABLE_NODE: { + const pm_embedded_variable_node_t *cast = (const pm_embedded_variable_node_t *) node; + + // Visit the variable field + pm_visit_node((const pm_node_t *) cast->variable, visitor, data); + + break; + } + case PM_ENSURE_NODE: { + const pm_ensure_node_t *cast = (const pm_ensure_node_t *) node; + + // Visit the statements field + if (cast->statements != NULL) { + pm_visit_node((const pm_node_t *) cast->statements, visitor, data); + } + + break; + } + case PM_FALSE_NODE: + break; + case PM_FIND_PATTERN_NODE: { + const pm_find_pattern_node_t *cast = (const pm_find_pattern_node_t *) node; + + // Visit the constant field + if (cast->constant != NULL) { + pm_visit_node((const pm_node_t *) cast->constant, visitor, data); + } + + // Visit the left field + pm_visit_node((const pm_node_t *) cast->left, visitor, data); + + // Visit the requireds field + const pm_node_list_t *requireds = &cast->requireds; + for (size_t index = 0; index < requireds->size; index++) { + pm_visit_node(requireds->nodes[index], visitor, data); + } + + // Visit the right field + pm_visit_node((const pm_node_t *) cast->right, visitor, data); + + break; + } + case PM_FLIP_FLOP_NODE: { + const pm_flip_flop_node_t *cast = (const pm_flip_flop_node_t *) node; + + // Visit the left field + if (cast->left != NULL) { + pm_visit_node((const pm_node_t *) cast->left, visitor, data); + } + + // Visit the right field + if (cast->right != NULL) { + pm_visit_node((const pm_node_t *) cast->right, visitor, data); + } + + break; + } + case PM_FLOAT_NODE: + break; + case PM_FOR_NODE: { + const pm_for_node_t *cast = (const pm_for_node_t *) node; + + // Visit the index field + pm_visit_node((const pm_node_t *) cast->index, visitor, data); + + // Visit the collection field + pm_visit_node((const pm_node_t *) cast->collection, visitor, data); + + // Visit the statements field + if (cast->statements != NULL) { + pm_visit_node((const pm_node_t *) cast->statements, visitor, data); + } + + break; + } + case PM_FORWARDING_ARGUMENTS_NODE: + break; + case PM_FORWARDING_PARAMETER_NODE: + break; + case PM_FORWARDING_SUPER_NODE: { + const pm_forwarding_super_node_t *cast = (const pm_forwarding_super_node_t *) node; + + // Visit the block field + if (cast->block != NULL) { + pm_visit_node((const pm_node_t *) cast->block, visitor, data); + } + + break; + } + case PM_GLOBAL_VARIABLE_AND_WRITE_NODE: { + const pm_global_variable_and_write_node_t *cast = (const pm_global_variable_and_write_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE: { + const pm_global_variable_operator_write_node_t *cast = (const pm_global_variable_operator_write_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_GLOBAL_VARIABLE_OR_WRITE_NODE: { + const pm_global_variable_or_write_node_t *cast = (const pm_global_variable_or_write_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_GLOBAL_VARIABLE_READ_NODE: + break; + case PM_GLOBAL_VARIABLE_TARGET_NODE: + break; + case PM_GLOBAL_VARIABLE_WRITE_NODE: { + const pm_global_variable_write_node_t *cast = (const pm_global_variable_write_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_HASH_NODE: { + const pm_hash_node_t *cast = (const pm_hash_node_t *) node; + + // Visit the elements field + const pm_node_list_t *elements = &cast->elements; + for (size_t index = 0; index < elements->size; index++) { + pm_visit_node(elements->nodes[index], visitor, data); + } + + break; + } + case PM_HASH_PATTERN_NODE: { + const pm_hash_pattern_node_t *cast = (const pm_hash_pattern_node_t *) node; + + // Visit the constant field + if (cast->constant != NULL) { + pm_visit_node((const pm_node_t *) cast->constant, visitor, data); + } + + // Visit the elements field + const pm_node_list_t *elements = &cast->elements; + for (size_t index = 0; index < elements->size; index++) { + pm_visit_node(elements->nodes[index], visitor, data); + } + + // Visit the rest field + if (cast->rest != NULL) { + pm_visit_node((const pm_node_t *) cast->rest, visitor, data); + } + + break; + } + case PM_IF_NODE: { + const pm_if_node_t *cast = (const pm_if_node_t *) node; + + // Visit the predicate field + pm_visit_node((const pm_node_t *) cast->predicate, visitor, data); + + // Visit the statements field + if (cast->statements != NULL) { + pm_visit_node((const pm_node_t *) cast->statements, visitor, data); + } + + // Visit the subsequent field + if (cast->subsequent != NULL) { + pm_visit_node((const pm_node_t *) cast->subsequent, visitor, data); + } + + break; + } + case PM_IMAGINARY_NODE: { + const pm_imaginary_node_t *cast = (const pm_imaginary_node_t *) node; + + // Visit the numeric field + pm_visit_node((const pm_node_t *) cast->numeric, visitor, data); + + break; + } + case PM_IMPLICIT_NODE: { + const pm_implicit_node_t *cast = (const pm_implicit_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_IMPLICIT_REST_NODE: + break; + case PM_IN_NODE: { + const pm_in_node_t *cast = (const pm_in_node_t *) node; + + // Visit the pattern field + pm_visit_node((const pm_node_t *) cast->pattern, visitor, data); + + // Visit the statements field + if (cast->statements != NULL) { + pm_visit_node((const pm_node_t *) cast->statements, visitor, data); + } + + break; + } + case PM_INDEX_AND_WRITE_NODE: { + const pm_index_and_write_node_t *cast = (const pm_index_and_write_node_t *) node; + + // Visit the receiver field + if (cast->receiver != NULL) { + pm_visit_node((const pm_node_t *) cast->receiver, visitor, data); + } + + // Visit the arguments field + if (cast->arguments != NULL) { + pm_visit_node((const pm_node_t *) cast->arguments, visitor, data); + } + + // Visit the block field + if (cast->block != NULL) { + pm_visit_node((const pm_node_t *) cast->block, visitor, data); + } + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_INDEX_OPERATOR_WRITE_NODE: { + const pm_index_operator_write_node_t *cast = (const pm_index_operator_write_node_t *) node; + + // Visit the receiver field + if (cast->receiver != NULL) { + pm_visit_node((const pm_node_t *) cast->receiver, visitor, data); + } + + // Visit the arguments field + if (cast->arguments != NULL) { + pm_visit_node((const pm_node_t *) cast->arguments, visitor, data); + } + + // Visit the block field + if (cast->block != NULL) { + pm_visit_node((const pm_node_t *) cast->block, visitor, data); + } + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_INDEX_OR_WRITE_NODE: { + const pm_index_or_write_node_t *cast = (const pm_index_or_write_node_t *) node; + + // Visit the receiver field + if (cast->receiver != NULL) { + pm_visit_node((const pm_node_t *) cast->receiver, visitor, data); + } + + // Visit the arguments field + if (cast->arguments != NULL) { + pm_visit_node((const pm_node_t *) cast->arguments, visitor, data); + } + + // Visit the block field + if (cast->block != NULL) { + pm_visit_node((const pm_node_t *) cast->block, visitor, data); + } + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_INDEX_TARGET_NODE: { + const pm_index_target_node_t *cast = (const pm_index_target_node_t *) node; + + // Visit the receiver field + pm_visit_node((const pm_node_t *) cast->receiver, visitor, data); + + // Visit the arguments field + if (cast->arguments != NULL) { + pm_visit_node((const pm_node_t *) cast->arguments, visitor, data); + } + + // Visit the block field + if (cast->block != NULL) { + pm_visit_node((const pm_node_t *) cast->block, visitor, data); + } + + break; + } + case PM_INSTANCE_VARIABLE_AND_WRITE_NODE: { + const pm_instance_variable_and_write_node_t *cast = (const pm_instance_variable_and_write_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE: { + const pm_instance_variable_operator_write_node_t *cast = (const pm_instance_variable_operator_write_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_INSTANCE_VARIABLE_OR_WRITE_NODE: { + const pm_instance_variable_or_write_node_t *cast = (const pm_instance_variable_or_write_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_INSTANCE_VARIABLE_READ_NODE: + break; + case PM_INSTANCE_VARIABLE_TARGET_NODE: + break; + case PM_INSTANCE_VARIABLE_WRITE_NODE: { + const pm_instance_variable_write_node_t *cast = (const pm_instance_variable_write_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_INTEGER_NODE: + break; + case PM_INTERPOLATED_MATCH_LAST_LINE_NODE: { + const pm_interpolated_match_last_line_node_t *cast = (const pm_interpolated_match_last_line_node_t *) node; + + // Visit the parts field + const pm_node_list_t *parts = &cast->parts; + for (size_t index = 0; index < parts->size; index++) { + pm_visit_node(parts->nodes[index], visitor, data); + } + + break; + } + case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE: { + const pm_interpolated_regular_expression_node_t *cast = (const pm_interpolated_regular_expression_node_t *) node; + + // Visit the parts field + const pm_node_list_t *parts = &cast->parts; + for (size_t index = 0; index < parts->size; index++) { + pm_visit_node(parts->nodes[index], visitor, data); + } + + break; + } + case PM_INTERPOLATED_STRING_NODE: { + const pm_interpolated_string_node_t *cast = (const pm_interpolated_string_node_t *) node; + + // Visit the parts field + const pm_node_list_t *parts = &cast->parts; + for (size_t index = 0; index < parts->size; index++) { + pm_visit_node(parts->nodes[index], visitor, data); + } + + break; + } + case PM_INTERPOLATED_SYMBOL_NODE: { + const pm_interpolated_symbol_node_t *cast = (const pm_interpolated_symbol_node_t *) node; + + // Visit the parts field + const pm_node_list_t *parts = &cast->parts; + for (size_t index = 0; index < parts->size; index++) { + pm_visit_node(parts->nodes[index], visitor, data); + } + + break; + } + case PM_INTERPOLATED_X_STRING_NODE: { + const pm_interpolated_x_string_node_t *cast = (const pm_interpolated_x_string_node_t *) node; + + // Visit the parts field + const pm_node_list_t *parts = &cast->parts; + for (size_t index = 0; index < parts->size; index++) { + pm_visit_node(parts->nodes[index], visitor, data); + } + + break; + } + case PM_IT_LOCAL_VARIABLE_READ_NODE: + break; + case PM_IT_PARAMETERS_NODE: + break; + case PM_KEYWORD_HASH_NODE: { + const pm_keyword_hash_node_t *cast = (const pm_keyword_hash_node_t *) node; + + // Visit the elements field + const pm_node_list_t *elements = &cast->elements; + for (size_t index = 0; index < elements->size; index++) { + pm_visit_node(elements->nodes[index], visitor, data); + } + + break; + } + case PM_KEYWORD_REST_PARAMETER_NODE: + break; + case PM_LAMBDA_NODE: { + const pm_lambda_node_t *cast = (const pm_lambda_node_t *) node; + + // Visit the parameters field + if (cast->parameters != NULL) { + pm_visit_node((const pm_node_t *) cast->parameters, visitor, data); + } + + // Visit the body field + if (cast->body != NULL) { + pm_visit_node((const pm_node_t *) cast->body, visitor, data); + } + + break; + } + case PM_LOCAL_VARIABLE_AND_WRITE_NODE: { + const pm_local_variable_and_write_node_t *cast = (const pm_local_variable_and_write_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE: { + const pm_local_variable_operator_write_node_t *cast = (const pm_local_variable_operator_write_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_LOCAL_VARIABLE_OR_WRITE_NODE: { + const pm_local_variable_or_write_node_t *cast = (const pm_local_variable_or_write_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_LOCAL_VARIABLE_READ_NODE: + break; + case PM_LOCAL_VARIABLE_TARGET_NODE: + break; + case PM_LOCAL_VARIABLE_WRITE_NODE: { + const pm_local_variable_write_node_t *cast = (const pm_local_variable_write_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_MATCH_LAST_LINE_NODE: + break; + case PM_MATCH_PREDICATE_NODE: { + const pm_match_predicate_node_t *cast = (const pm_match_predicate_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + // Visit the pattern field + pm_visit_node((const pm_node_t *) cast->pattern, visitor, data); + + break; + } + case PM_MATCH_REQUIRED_NODE: { + const pm_match_required_node_t *cast = (const pm_match_required_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + // Visit the pattern field + pm_visit_node((const pm_node_t *) cast->pattern, visitor, data); + + break; + } + case PM_MATCH_WRITE_NODE: { + const pm_match_write_node_t *cast = (const pm_match_write_node_t *) node; + + // Visit the call field + pm_visit_node((const pm_node_t *) cast->call, visitor, data); + + // Visit the targets field + const pm_node_list_t *targets = &cast->targets; + for (size_t index = 0; index < targets->size; index++) { + pm_visit_node(targets->nodes[index], visitor, data); + } + + break; + } + case PM_MISSING_NODE: + break; + case PM_MODULE_NODE: { + const pm_module_node_t *cast = (const pm_module_node_t *) node; + + // Visit the constant_path field + pm_visit_node((const pm_node_t *) cast->constant_path, visitor, data); + + // Visit the body field + if (cast->body != NULL) { + pm_visit_node((const pm_node_t *) cast->body, visitor, data); + } + + break; + } + case PM_MULTI_TARGET_NODE: { + const pm_multi_target_node_t *cast = (const pm_multi_target_node_t *) node; + + // Visit the lefts field + const pm_node_list_t *lefts = &cast->lefts; + for (size_t index = 0; index < lefts->size; index++) { + pm_visit_node(lefts->nodes[index], visitor, data); + } + + // Visit the rest field + if (cast->rest != NULL) { + pm_visit_node((const pm_node_t *) cast->rest, visitor, data); + } + + // Visit the rights field + const pm_node_list_t *rights = &cast->rights; + for (size_t index = 0; index < rights->size; index++) { + pm_visit_node(rights->nodes[index], visitor, data); + } + + break; + } + case PM_MULTI_WRITE_NODE: { + const pm_multi_write_node_t *cast = (const pm_multi_write_node_t *) node; + + // Visit the lefts field + const pm_node_list_t *lefts = &cast->lefts; + for (size_t index = 0; index < lefts->size; index++) { + pm_visit_node(lefts->nodes[index], visitor, data); + } + + // Visit the rest field + if (cast->rest != NULL) { + pm_visit_node((const pm_node_t *) cast->rest, visitor, data); + } + + // Visit the rights field + const pm_node_list_t *rights = &cast->rights; + for (size_t index = 0; index < rights->size; index++) { + pm_visit_node(rights->nodes[index], visitor, data); + } + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_NEXT_NODE: { + const pm_next_node_t *cast = (const pm_next_node_t *) node; + + // Visit the arguments field + if (cast->arguments != NULL) { + pm_visit_node((const pm_node_t *) cast->arguments, visitor, data); + } + + break; + } + case PM_NIL_NODE: + break; + case PM_NO_KEYWORDS_PARAMETER_NODE: + break; + case PM_NUMBERED_PARAMETERS_NODE: + break; + case PM_NUMBERED_REFERENCE_READ_NODE: + break; + case PM_OPTIONAL_KEYWORD_PARAMETER_NODE: { + const pm_optional_keyword_parameter_node_t *cast = (const pm_optional_keyword_parameter_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_OPTIONAL_PARAMETER_NODE: { + const pm_optional_parameter_node_t *cast = (const pm_optional_parameter_node_t *) node; + + // Visit the value field + pm_visit_node((const pm_node_t *) cast->value, visitor, data); + + break; + } + case PM_OR_NODE: { + const pm_or_node_t *cast = (const pm_or_node_t *) node; + + // Visit the left field + pm_visit_node((const pm_node_t *) cast->left, visitor, data); + + // Visit the right field + pm_visit_node((const pm_node_t *) cast->right, visitor, data); + + break; + } + case PM_PARAMETERS_NODE: { + const pm_parameters_node_t *cast = (const pm_parameters_node_t *) node; + + // Visit the requireds field + const pm_node_list_t *requireds = &cast->requireds; + for (size_t index = 0; index < requireds->size; index++) { + pm_visit_node(requireds->nodes[index], visitor, data); + } + + // Visit the optionals field + const pm_node_list_t *optionals = &cast->optionals; + for (size_t index = 0; index < optionals->size; index++) { + pm_visit_node(optionals->nodes[index], visitor, data); + } + + // Visit the rest field + if (cast->rest != NULL) { + pm_visit_node((const pm_node_t *) cast->rest, visitor, data); + } + + // Visit the posts field + const pm_node_list_t *posts = &cast->posts; + for (size_t index = 0; index < posts->size; index++) { + pm_visit_node(posts->nodes[index], visitor, data); + } + + // Visit the keywords field + const pm_node_list_t *keywords = &cast->keywords; + for (size_t index = 0; index < keywords->size; index++) { + pm_visit_node(keywords->nodes[index], visitor, data); + } + + // Visit the keyword_rest field + if (cast->keyword_rest != NULL) { + pm_visit_node((const pm_node_t *) cast->keyword_rest, visitor, data); + } + + // Visit the block field + if (cast->block != NULL) { + pm_visit_node((const pm_node_t *) cast->block, visitor, data); + } + + break; + } + case PM_PARENTHESES_NODE: { + const pm_parentheses_node_t *cast = (const pm_parentheses_node_t *) node; + + // Visit the body field + if (cast->body != NULL) { + pm_visit_node((const pm_node_t *) cast->body, visitor, data); + } + + break; + } + case PM_PINNED_EXPRESSION_NODE: { + const pm_pinned_expression_node_t *cast = (const pm_pinned_expression_node_t *) node; + + // Visit the expression field + pm_visit_node((const pm_node_t *) cast->expression, visitor, data); + + break; + } + case PM_PINNED_VARIABLE_NODE: { + const pm_pinned_variable_node_t *cast = (const pm_pinned_variable_node_t *) node; + + // Visit the variable field + pm_visit_node((const pm_node_t *) cast->variable, visitor, data); + + break; + } + case PM_POST_EXECUTION_NODE: { + const pm_post_execution_node_t *cast = (const pm_post_execution_node_t *) node; + + // Visit the statements field + if (cast->statements != NULL) { + pm_visit_node((const pm_node_t *) cast->statements, visitor, data); + } + + break; + } + case PM_PRE_EXECUTION_NODE: { + const pm_pre_execution_node_t *cast = (const pm_pre_execution_node_t *) node; + + // Visit the statements field + if (cast->statements != NULL) { + pm_visit_node((const pm_node_t *) cast->statements, visitor, data); + } + + break; + } + case PM_PROGRAM_NODE: { + const pm_program_node_t *cast = (const pm_program_node_t *) node; + + // Visit the statements field + pm_visit_node((const pm_node_t *) cast->statements, visitor, data); + + break; + } + case PM_RANGE_NODE: { + const pm_range_node_t *cast = (const pm_range_node_t *) node; + + // Visit the left field + if (cast->left != NULL) { + pm_visit_node((const pm_node_t *) cast->left, visitor, data); + } + + // Visit the right field + if (cast->right != NULL) { + pm_visit_node((const pm_node_t *) cast->right, visitor, data); + } + + break; + } + case PM_RATIONAL_NODE: + break; + case PM_REDO_NODE: + break; + case PM_REGULAR_EXPRESSION_NODE: + break; + case PM_REQUIRED_KEYWORD_PARAMETER_NODE: + break; + case PM_REQUIRED_PARAMETER_NODE: + break; + case PM_RESCUE_MODIFIER_NODE: { + const pm_rescue_modifier_node_t *cast = (const pm_rescue_modifier_node_t *) node; + + // Visit the expression field + pm_visit_node((const pm_node_t *) cast->expression, visitor, data); + + // Visit the rescue_expression field + pm_visit_node((const pm_node_t *) cast->rescue_expression, visitor, data); + + break; + } + case PM_RESCUE_NODE: { + const pm_rescue_node_t *cast = (const pm_rescue_node_t *) node; + + // Visit the exceptions field + const pm_node_list_t *exceptions = &cast->exceptions; + for (size_t index = 0; index < exceptions->size; index++) { + pm_visit_node(exceptions->nodes[index], visitor, data); + } + + // Visit the reference field + if (cast->reference != NULL) { + pm_visit_node((const pm_node_t *) cast->reference, visitor, data); + } + + // Visit the statements field + if (cast->statements != NULL) { + pm_visit_node((const pm_node_t *) cast->statements, visitor, data); + } + + // Visit the subsequent field + if (cast->subsequent != NULL) { + pm_visit_node((const pm_node_t *) cast->subsequent, visitor, data); + } + + break; + } + case PM_REST_PARAMETER_NODE: + break; + case PM_RETRY_NODE: + break; + case PM_RETURN_NODE: { + const pm_return_node_t *cast = (const pm_return_node_t *) node; + + // Visit the arguments field + if (cast->arguments != NULL) { + pm_visit_node((const pm_node_t *) cast->arguments, visitor, data); + } + + break; + } + case PM_SELF_NODE: + break; + case PM_SHAREABLE_CONSTANT_NODE: { + const pm_shareable_constant_node_t *cast = (const pm_shareable_constant_node_t *) node; + + // Visit the write field + pm_visit_node((const pm_node_t *) cast->write, visitor, data); + + break; + } + case PM_SINGLETON_CLASS_NODE: { + const pm_singleton_class_node_t *cast = (const pm_singleton_class_node_t *) node; + + // Visit the expression field + pm_visit_node((const pm_node_t *) cast->expression, visitor, data); + + // Visit the body field + if (cast->body != NULL) { + pm_visit_node((const pm_node_t *) cast->body, visitor, data); + } + + break; + } + case PM_SOURCE_ENCODING_NODE: + break; + case PM_SOURCE_FILE_NODE: + break; + case PM_SOURCE_LINE_NODE: + break; + case PM_SPLAT_NODE: { + const pm_splat_node_t *cast = (const pm_splat_node_t *) node; + + // Visit the expression field + if (cast->expression != NULL) { + pm_visit_node((const pm_node_t *) cast->expression, visitor, data); + } + + break; + } + case PM_STATEMENTS_NODE: { + const pm_statements_node_t *cast = (const pm_statements_node_t *) node; + + // Visit the body field + const pm_node_list_t *body = &cast->body; + for (size_t index = 0; index < body->size; index++) { + pm_visit_node(body->nodes[index], visitor, data); + } + + break; + } + case PM_STRING_NODE: + break; + case PM_SUPER_NODE: { + const pm_super_node_t *cast = (const pm_super_node_t *) node; + + // Visit the arguments field + if (cast->arguments != NULL) { + pm_visit_node((const pm_node_t *) cast->arguments, visitor, data); + } + + // Visit the block field + if (cast->block != NULL) { + pm_visit_node((const pm_node_t *) cast->block, visitor, data); + } + + break; + } + case PM_SYMBOL_NODE: + break; + case PM_TRUE_NODE: + break; + case PM_UNDEF_NODE: { + const pm_undef_node_t *cast = (const pm_undef_node_t *) node; + + // Visit the names field + const pm_node_list_t *names = &cast->names; + for (size_t index = 0; index < names->size; index++) { + pm_visit_node(names->nodes[index], visitor, data); + } + + break; + } + case PM_UNLESS_NODE: { + const pm_unless_node_t *cast = (const pm_unless_node_t *) node; + + // Visit the predicate field + pm_visit_node((const pm_node_t *) cast->predicate, visitor, data); + + // Visit the statements field + if (cast->statements != NULL) { + pm_visit_node((const pm_node_t *) cast->statements, visitor, data); + } + + // Visit the else_clause field + if (cast->else_clause != NULL) { + pm_visit_node((const pm_node_t *) cast->else_clause, visitor, data); + } + + break; + } + case PM_UNTIL_NODE: { + const pm_until_node_t *cast = (const pm_until_node_t *) node; + + // Visit the predicate field + pm_visit_node((const pm_node_t *) cast->predicate, visitor, data); + + // Visit the statements field + if (cast->statements != NULL) { + pm_visit_node((const pm_node_t *) cast->statements, visitor, data); + } + + break; + } + case PM_WHEN_NODE: { + const pm_when_node_t *cast = (const pm_when_node_t *) node; + + // Visit the conditions field + const pm_node_list_t *conditions = &cast->conditions; + for (size_t index = 0; index < conditions->size; index++) { + pm_visit_node(conditions->nodes[index], visitor, data); + } + + // Visit the statements field + if (cast->statements != NULL) { + pm_visit_node((const pm_node_t *) cast->statements, visitor, data); + } + + break; + } + case PM_WHILE_NODE: { + const pm_while_node_t *cast = (const pm_while_node_t *) node; + + // Visit the predicate field + pm_visit_node((const pm_node_t *) cast->predicate, visitor, data); + + // Visit the statements field + if (cast->statements != NULL) { + pm_visit_node((const pm_node_t *) cast->statements, visitor, data); + } + + break; + } + case PM_X_STRING_NODE: + break; + case PM_YIELD_NODE: { + const pm_yield_node_t *cast = (const pm_yield_node_t *) node; + + // Visit the arguments field + if (cast->arguments != NULL) { + pm_visit_node((const pm_node_t *) cast->arguments, visitor, data); + } + + break; + } + case PM_SCOPE_NODE: + break; + } +} + +// We optionally support dumping to JSON. For systems that don't want or need +// this functionality, it can be turned off with the PRISM_EXCLUDE_JSON define. +#ifndef PRISM_EXCLUDE_JSON + +static void +pm_dump_json_constant(pm_buffer_t *buffer, const pm_parser_t *parser, pm_constant_id_t constant_id) { + const pm_constant_t *constant = pm_constant_pool_id_to_constant(&parser->constant_pool, constant_id); + pm_buffer_append_byte(buffer, '"'); + pm_buffer_append_source(buffer, constant->start, constant->length, PM_BUFFER_ESCAPING_JSON); + pm_buffer_append_byte(buffer, '"'); +} + +static void +pm_dump_json_location(pm_buffer_t *buffer, const pm_parser_t *parser, const pm_location_t *location) { + uint32_t start = (uint32_t) (location->start - parser->start); + uint32_t end = (uint32_t) (location->end - parser->start); + pm_buffer_append_format(buffer, "{\"start\":%" PRIu32 ",\"end\":%" PRIu32 "}", start, end); +} + +/** + * Dump JSON to the given buffer. + */ +PRISM_EXPORTED_FUNCTION void +pm_dump_json(pm_buffer_t *buffer, const pm_parser_t *parser, const pm_node_t *node) { + switch (PM_NODE_TYPE(node)) { + case PM_ALIAS_GLOBAL_VARIABLE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"AliasGlobalVariableNode\",\"location\":", 45); + + const pm_alias_global_variable_node_t *cast = (const pm_alias_global_variable_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the new_name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"new_name\":", 11); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->new_name); + + // Dump the old_name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"old_name\":", 11); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->old_name); + + // Dump the keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"keyword_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->keyword_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_ALIAS_METHOD_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"AliasMethodNode\",\"location\":", 37); + + const pm_alias_method_node_t *cast = (const pm_alias_method_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the new_name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"new_name\":", 11); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->new_name); + + // Dump the old_name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"old_name\":", 11); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->old_name); + + // Dump the keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"keyword_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->keyword_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_ALTERNATION_PATTERN_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"AlternationPatternNode\",\"location\":", 44); + + const pm_alternation_pattern_node_t *cast = (const pm_alternation_pattern_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the left field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"left\":", 7); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->left); + + // Dump the right field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"right\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->right); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_AND_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"AndNode\",\"location\":", 29); + + const pm_and_node_t *cast = (const pm_and_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the left field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"left\":", 7); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->left); + + // Dump the right field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"right\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->right); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_ARGUMENTS_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ArgumentsNode\",\"location\":", 35); + + const pm_arguments_node_t *cast = (const pm_arguments_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the ArgumentsNodeFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ArgumentsNodeFlags\":", 21); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_FORWARDING)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"CONTAINS_FORWARDING\"", 21); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORDS)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"CONTAINS_KEYWORDS\"", 19); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORD_SPLAT)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"CONTAINS_KEYWORD_SPLAT\"", 24); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_SPLAT)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"CONTAINS_SPLAT\"", 16); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_MULTIPLE_SPLATS)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"CONTAINS_MULTIPLE_SPLATS\"", 26); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the arguments field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"arguments\":", 12); + const pm_node_list_t *arguments = &cast->arguments; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < arguments->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, arguments->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_ARRAY_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ArrayNode\",\"location\":", 31); + + const pm_array_node_t *cast = (const pm_array_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the ArrayNodeFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ArrayNodeFlags\":", 17); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_ARRAY_NODE_FLAGS_CONTAINS_SPLAT)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"CONTAINS_SPLAT\"", 16); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the elements field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"elements\":", 11); + const pm_node_list_t *elements = &cast->elements; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < elements->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, elements->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + if (cast->opening_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->opening_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + if (cast->closing_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->closing_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_ARRAY_PATTERN_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ArrayPatternNode\",\"location\":", 38); + + const pm_array_pattern_node_t *cast = (const pm_array_pattern_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the constant field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"constant\":", 11); + if (cast->constant != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->constant); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the requireds field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"requireds\":", 12); + const pm_node_list_t *requireds = &cast->requireds; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < requireds->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, requireds->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the rest field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"rest\":", 7); + if (cast->rest != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->rest); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the posts field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"posts\":", 8); + const pm_node_list_t *posts = &cast->posts; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < posts->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, posts->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + if (cast->opening_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->opening_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + if (cast->closing_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->closing_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_ASSOC_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"AssocNode\",\"location\":", 31); + + const pm_assoc_node_t *cast = (const pm_assoc_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the key field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"key\":", 6); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->key); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + if (cast->operator_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->operator_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_ASSOC_SPLAT_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"AssocSplatNode\",\"location\":", 36); + + const pm_assoc_splat_node_t *cast = (const pm_assoc_splat_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + if (cast->value != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_BACK_REFERENCE_READ_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"BackReferenceReadNode\",\"location\":", 43); + + const pm_back_reference_read_node_t *cast = (const pm_back_reference_read_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_BEGIN_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"BeginNode\",\"location\":", 31); + + const pm_begin_node_t *cast = (const pm_begin_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the begin_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"begin_keyword_loc\":", 20); + if (cast->begin_keyword_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->begin_keyword_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the statements field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"statements\":", 13); + if (cast->statements != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->statements); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the rescue_clause field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"rescue_clause\":", 16); + if (cast->rescue_clause != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->rescue_clause); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the else_clause field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"else_clause\":", 14); + if (cast->else_clause != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->else_clause); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the ensure_clause field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ensure_clause\":", 16); + if (cast->ensure_clause != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->ensure_clause); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the end_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"end_keyword_loc\":", 18); + if (cast->end_keyword_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->end_keyword_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_BLOCK_ARGUMENT_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"BlockArgumentNode\",\"location\":", 39); + + const pm_block_argument_node_t *cast = (const pm_block_argument_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the expression field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"expression\":", 13); + if (cast->expression != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->expression); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_BLOCK_LOCAL_VARIABLE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"BlockLocalVariableNode\",\"location\":", 44); + + const pm_block_local_variable_node_t *cast = (const pm_block_local_variable_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the ParameterFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ParameterFlags\":", 17); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_PARAMETER_FLAGS_REPEATED_PARAMETER)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"REPEATED_PARAMETER\"", 20); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_BLOCK_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"BlockNode\",\"location\":", 31); + + const pm_block_node_t *cast = (const pm_block_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the locals field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"locals\":", 9); + const pm_constant_id_list_t *locals = &cast->locals; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < locals->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json_constant(buffer, parser, locals->ids[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the parameters field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"parameters\":", 13); + if (cast->parameters != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->parameters); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the body field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"body\":", 7); + if (cast->body != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->body); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->opening_loc); + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->closing_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_BLOCK_PARAMETER_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"BlockParameterNode\",\"location\":", 40); + + const pm_block_parameter_node_t *cast = (const pm_block_parameter_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the ParameterFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ParameterFlags\":", 17); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_PARAMETER_FLAGS_REPEATED_PARAMETER)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"REPEATED_PARAMETER\"", 20); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + if (cast->name != PM_CONSTANT_ID_UNSET) { + pm_dump_json_constant(buffer, parser, cast->name); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + if (cast->name_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->name_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_BLOCK_PARAMETERS_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"BlockParametersNode\",\"location\":", 41); + + const pm_block_parameters_node_t *cast = (const pm_block_parameters_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the parameters field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"parameters\":", 13); + if (cast->parameters != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->parameters); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the locals field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"locals\":", 9); + const pm_node_list_t *locals = &cast->locals; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < locals->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, locals->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + if (cast->opening_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->opening_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + if (cast->closing_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->closing_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_BREAK_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"BreakNode\",\"location\":", 31); + + const pm_break_node_t *cast = (const pm_break_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the arguments field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"arguments\":", 12); + if (cast->arguments != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->arguments); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"keyword_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->keyword_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CALL_AND_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"CallAndWriteNode\",\"location\":", 38); + + const pm_call_and_write_node_t *cast = (const pm_call_and_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the CallNodeFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"CallNodeFlags\":", 16); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"SAFE_NAVIGATION\"", 17); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_VARIABLE_CALL)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"VARIABLE_CALL\"", 15); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ATTRIBUTE_WRITE\"", 17); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"IGNORE_VISIBILITY\"", 19); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the receiver field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"receiver\":", 11); + if (cast->receiver != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->receiver); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the call_operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"call_operator_loc\":", 20); + if (cast->call_operator_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->call_operator_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the message_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"message_loc\":", 14); + if (cast->message_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->message_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the read_name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"read_name\":", 12); + pm_dump_json_constant(buffer, parser, cast->read_name); + + // Dump the write_name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"write_name\":", 13); + pm_dump_json_constant(buffer, parser, cast->write_name); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CALL_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"CallNode\",\"location\":", 30); + + const pm_call_node_t *cast = (const pm_call_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the CallNodeFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"CallNodeFlags\":", 16); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"SAFE_NAVIGATION\"", 17); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_VARIABLE_CALL)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"VARIABLE_CALL\"", 15); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ATTRIBUTE_WRITE\"", 17); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"IGNORE_VISIBILITY\"", 19); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the receiver field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"receiver\":", 11); + if (cast->receiver != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->receiver); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the call_operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"call_operator_loc\":", 20); + if (cast->call_operator_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->call_operator_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the message_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"message_loc\":", 14); + if (cast->message_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->message_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + if (cast->opening_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->opening_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the arguments field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"arguments\":", 12); + if (cast->arguments != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->arguments); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + if (cast->closing_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->closing_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the block field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"block\":", 8); + if (cast->block != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->block); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CALL_OPERATOR_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"CallOperatorWriteNode\",\"location\":", 43); + + const pm_call_operator_write_node_t *cast = (const pm_call_operator_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the CallNodeFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"CallNodeFlags\":", 16); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"SAFE_NAVIGATION\"", 17); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_VARIABLE_CALL)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"VARIABLE_CALL\"", 15); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ATTRIBUTE_WRITE\"", 17); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"IGNORE_VISIBILITY\"", 19); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the receiver field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"receiver\":", 11); + if (cast->receiver != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->receiver); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the call_operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"call_operator_loc\":", 20); + if (cast->call_operator_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->call_operator_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the message_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"message_loc\":", 14); + if (cast->message_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->message_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the read_name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"read_name\":", 12); + pm_dump_json_constant(buffer, parser, cast->read_name); + + // Dump the write_name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"write_name\":", 13); + pm_dump_json_constant(buffer, parser, cast->write_name); + + // Dump the binary_operator field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"binary_operator\":", 18); + pm_dump_json_constant(buffer, parser, cast->binary_operator); + + // Dump the binary_operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"binary_operator_loc\":", 22); + pm_dump_json_location(buffer, parser, &cast->binary_operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CALL_OR_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"CallOrWriteNode\",\"location\":", 37); + + const pm_call_or_write_node_t *cast = (const pm_call_or_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the CallNodeFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"CallNodeFlags\":", 16); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"SAFE_NAVIGATION\"", 17); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_VARIABLE_CALL)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"VARIABLE_CALL\"", 15); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ATTRIBUTE_WRITE\"", 17); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"IGNORE_VISIBILITY\"", 19); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the receiver field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"receiver\":", 11); + if (cast->receiver != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->receiver); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the call_operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"call_operator_loc\":", 20); + if (cast->call_operator_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->call_operator_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the message_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"message_loc\":", 14); + if (cast->message_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->message_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the read_name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"read_name\":", 12); + pm_dump_json_constant(buffer, parser, cast->read_name); + + // Dump the write_name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"write_name\":", 13); + pm_dump_json_constant(buffer, parser, cast->write_name); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CALL_TARGET_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"CallTargetNode\",\"location\":", 36); + + const pm_call_target_node_t *cast = (const pm_call_target_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the CallNodeFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"CallNodeFlags\":", 16); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"SAFE_NAVIGATION\"", 17); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_VARIABLE_CALL)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"VARIABLE_CALL\"", 15); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ATTRIBUTE_WRITE\"", 17); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"IGNORE_VISIBILITY\"", 19); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the receiver field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"receiver\":", 11); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->receiver); + + // Dump the call_operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"call_operator_loc\":", 20); + pm_dump_json_location(buffer, parser, &cast->call_operator_loc); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the message_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"message_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->message_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CAPTURE_PATTERN_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"CapturePatternNode\",\"location\":", 40); + + const pm_capture_pattern_node_t *cast = (const pm_capture_pattern_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + // Dump the target field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"target\":", 9); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->target); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CASE_MATCH_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"CaseMatchNode\",\"location\":", 35); + + const pm_case_match_node_t *cast = (const pm_case_match_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the predicate field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"predicate\":", 12); + if (cast->predicate != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->predicate); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the conditions field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"conditions\":", 13); + const pm_node_list_t *conditions = &cast->conditions; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < conditions->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, conditions->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the else_clause field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"else_clause\":", 14); + if (cast->else_clause != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->else_clause); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the case_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"case_keyword_loc\":", 19); + pm_dump_json_location(buffer, parser, &cast->case_keyword_loc); + + // Dump the end_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"end_keyword_loc\":", 18); + pm_dump_json_location(buffer, parser, &cast->end_keyword_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CASE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"CaseNode\",\"location\":", 30); + + const pm_case_node_t *cast = (const pm_case_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the predicate field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"predicate\":", 12); + if (cast->predicate != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->predicate); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the conditions field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"conditions\":", 13); + const pm_node_list_t *conditions = &cast->conditions; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < conditions->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, conditions->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the else_clause field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"else_clause\":", 14); + if (cast->else_clause != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->else_clause); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the case_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"case_keyword_loc\":", 19); + pm_dump_json_location(buffer, parser, &cast->case_keyword_loc); + + // Dump the end_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"end_keyword_loc\":", 18); + pm_dump_json_location(buffer, parser, &cast->end_keyword_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CLASS_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ClassNode\",\"location\":", 31); + + const pm_class_node_t *cast = (const pm_class_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the locals field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"locals\":", 9); + const pm_constant_id_list_t *locals = &cast->locals; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < locals->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json_constant(buffer, parser, locals->ids[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the class_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"class_keyword_loc\":", 20); + pm_dump_json_location(buffer, parser, &cast->class_keyword_loc); + + // Dump the constant_path field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"constant_path\":", 16); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->constant_path); + + // Dump the inheritance_operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"inheritance_operator_loc\":", 27); + if (cast->inheritance_operator_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->inheritance_operator_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the superclass field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"superclass\":", 13); + if (cast->superclass != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->superclass); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the body field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"body\":", 7); + if (cast->body != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->body); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the end_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"end_keyword_loc\":", 18); + pm_dump_json_location(buffer, parser, &cast->end_keyword_loc); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CLASS_VARIABLE_AND_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ClassVariableAndWriteNode\",\"location\":", 47); + + const pm_class_variable_and_write_node_t *cast = (const pm_class_variable_and_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ClassVariableOperatorWriteNode\",\"location\":", 52); + + const pm_class_variable_operator_write_node_t *cast = (const pm_class_variable_operator_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + // Dump the binary_operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"binary_operator_loc\":", 22); + pm_dump_json_location(buffer, parser, &cast->binary_operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + // Dump the binary_operator field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"binary_operator\":", 18); + pm_dump_json_constant(buffer, parser, cast->binary_operator); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CLASS_VARIABLE_OR_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ClassVariableOrWriteNode\",\"location\":", 46); + + const pm_class_variable_or_write_node_t *cast = (const pm_class_variable_or_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CLASS_VARIABLE_READ_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ClassVariableReadNode\",\"location\":", 43); + + const pm_class_variable_read_node_t *cast = (const pm_class_variable_read_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CLASS_VARIABLE_TARGET_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ClassVariableTargetNode\",\"location\":", 45); + + const pm_class_variable_target_node_t *cast = (const pm_class_variable_target_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CLASS_VARIABLE_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ClassVariableWriteNode\",\"location\":", 44); + + const pm_class_variable_write_node_t *cast = (const pm_class_variable_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CONSTANT_AND_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ConstantAndWriteNode\",\"location\":", 42); + + const pm_constant_and_write_node_t *cast = (const pm_constant_and_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CONSTANT_OPERATOR_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ConstantOperatorWriteNode\",\"location\":", 47); + + const pm_constant_operator_write_node_t *cast = (const pm_constant_operator_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + // Dump the binary_operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"binary_operator_loc\":", 22); + pm_dump_json_location(buffer, parser, &cast->binary_operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + // Dump the binary_operator field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"binary_operator\":", 18); + pm_dump_json_constant(buffer, parser, cast->binary_operator); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CONSTANT_OR_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ConstantOrWriteNode\",\"location\":", 41); + + const pm_constant_or_write_node_t *cast = (const pm_constant_or_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CONSTANT_PATH_AND_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ConstantPathAndWriteNode\",\"location\":", 46); + + const pm_constant_path_and_write_node_t *cast = (const pm_constant_path_and_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the target field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"target\":", 9); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->target); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CONSTANT_PATH_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ConstantPathNode\",\"location\":", 38); + + const pm_constant_path_node_t *cast = (const pm_constant_path_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the parent field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"parent\":", 9); + if (cast->parent != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->parent); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + if (cast->name != PM_CONSTANT_ID_UNSET) { + pm_dump_json_constant(buffer, parser, cast->name); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the delimiter_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"delimiter_loc\":", 16); + pm_dump_json_location(buffer, parser, &cast->delimiter_loc); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CONSTANT_PATH_OPERATOR_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ConstantPathOperatorWriteNode\",\"location\":", 51); + + const pm_constant_path_operator_write_node_t *cast = (const pm_constant_path_operator_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the target field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"target\":", 9); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->target); + + // Dump the binary_operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"binary_operator_loc\":", 22); + pm_dump_json_location(buffer, parser, &cast->binary_operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + // Dump the binary_operator field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"binary_operator\":", 18); + pm_dump_json_constant(buffer, parser, cast->binary_operator); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CONSTANT_PATH_OR_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ConstantPathOrWriteNode\",\"location\":", 45); + + const pm_constant_path_or_write_node_t *cast = (const pm_constant_path_or_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the target field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"target\":", 9); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->target); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CONSTANT_PATH_TARGET_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ConstantPathTargetNode\",\"location\":", 44); + + const pm_constant_path_target_node_t *cast = (const pm_constant_path_target_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the parent field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"parent\":", 9); + if (cast->parent != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->parent); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + if (cast->name != PM_CONSTANT_ID_UNSET) { + pm_dump_json_constant(buffer, parser, cast->name); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the delimiter_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"delimiter_loc\":", 16); + pm_dump_json_location(buffer, parser, &cast->delimiter_loc); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CONSTANT_PATH_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ConstantPathWriteNode\",\"location\":", 43); + + const pm_constant_path_write_node_t *cast = (const pm_constant_path_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the target field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"target\":", 9); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->target); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CONSTANT_READ_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ConstantReadNode\",\"location\":", 38); + + const pm_constant_read_node_t *cast = (const pm_constant_read_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CONSTANT_TARGET_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ConstantTargetNode\",\"location\":", 40); + + const pm_constant_target_node_t *cast = (const pm_constant_target_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_CONSTANT_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ConstantWriteNode\",\"location\":", 39); + + const pm_constant_write_node_t *cast = (const pm_constant_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_DEF_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"DefNode\",\"location\":", 29); + + const pm_def_node_t *cast = (const pm_def_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + // Dump the receiver field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"receiver\":", 11); + if (cast->receiver != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->receiver); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the parameters field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"parameters\":", 13); + if (cast->parameters != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->parameters); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the body field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"body\":", 7); + if (cast->body != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->body); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the locals field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"locals\":", 9); + const pm_constant_id_list_t *locals = &cast->locals; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < locals->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json_constant(buffer, parser, locals->ids[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the def_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"def_keyword_loc\":", 18); + pm_dump_json_location(buffer, parser, &cast->def_keyword_loc); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + if (cast->operator_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->operator_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the lparen_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"lparen_loc\":", 13); + if (cast->lparen_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->lparen_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the rparen_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"rparen_loc\":", 13); + if (cast->rparen_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->rparen_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the equal_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"equal_loc\":", 12); + if (cast->equal_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->equal_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the end_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"end_keyword_loc\":", 18); + if (cast->end_keyword_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->end_keyword_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_DEFINED_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"DefinedNode\",\"location\":", 33); + + const pm_defined_node_t *cast = (const pm_defined_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the lparen_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"lparen_loc\":", 13); + if (cast->lparen_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->lparen_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + // Dump the rparen_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"rparen_loc\":", 13); + if (cast->rparen_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->rparen_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"keyword_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->keyword_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_ELSE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ElseNode\",\"location\":", 30); + + const pm_else_node_t *cast = (const pm_else_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the else_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"else_keyword_loc\":", 19); + pm_dump_json_location(buffer, parser, &cast->else_keyword_loc); + + // Dump the statements field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"statements\":", 13); + if (cast->statements != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->statements); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the end_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"end_keyword_loc\":", 18); + if (cast->end_keyword_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->end_keyword_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_EMBEDDED_STATEMENTS_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"EmbeddedStatementsNode\",\"location\":", 44); + + const pm_embedded_statements_node_t *cast = (const pm_embedded_statements_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->opening_loc); + + // Dump the statements field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"statements\":", 13); + if (cast->statements != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->statements); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->closing_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_EMBEDDED_VARIABLE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"EmbeddedVariableNode\",\"location\":", 42); + + const pm_embedded_variable_node_t *cast = (const pm_embedded_variable_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the variable field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"variable\":", 11); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->variable); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_ENSURE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"EnsureNode\",\"location\":", 32); + + const pm_ensure_node_t *cast = (const pm_ensure_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the ensure_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ensure_keyword_loc\":", 21); + pm_dump_json_location(buffer, parser, &cast->ensure_keyword_loc); + + // Dump the statements field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"statements\":", 13); + if (cast->statements != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->statements); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the end_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"end_keyword_loc\":", 18); + pm_dump_json_location(buffer, parser, &cast->end_keyword_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_FALSE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"FalseNode\",\"location\":", 31); + + const pm_false_node_t *cast = (const pm_false_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_FIND_PATTERN_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"FindPatternNode\",\"location\":", 37); + + const pm_find_pattern_node_t *cast = (const pm_find_pattern_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the constant field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"constant\":", 11); + if (cast->constant != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->constant); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the left field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"left\":", 7); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->left); + + // Dump the requireds field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"requireds\":", 12); + const pm_node_list_t *requireds = &cast->requireds; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < requireds->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, requireds->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the right field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"right\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->right); + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + if (cast->opening_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->opening_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + if (cast->closing_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->closing_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_FLIP_FLOP_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"FlipFlopNode\",\"location\":", 34); + + const pm_flip_flop_node_t *cast = (const pm_flip_flop_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the RangeFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"RangeFlags\":", 13); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_RANGE_FLAGS_EXCLUDE_END)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"EXCLUDE_END\"", 13); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the left field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"left\":", 7); + if (cast->left != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->left); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the right field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"right\":", 8); + if (cast->right != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->right); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_FLOAT_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"FloatNode\",\"location\":", 31); + + const pm_float_node_t *cast = (const pm_float_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_buffer_append_format(buffer, "%f", cast->value); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_FOR_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ForNode\",\"location\":", 29); + + const pm_for_node_t *cast = (const pm_for_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the index field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"index\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->index); + + // Dump the collection field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"collection\":", 13); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->collection); + + // Dump the statements field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"statements\":", 13); + if (cast->statements != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->statements); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the for_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"for_keyword_loc\":", 18); + pm_dump_json_location(buffer, parser, &cast->for_keyword_loc); + + // Dump the in_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"in_keyword_loc\":", 17); + pm_dump_json_location(buffer, parser, &cast->in_keyword_loc); + + // Dump the do_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"do_keyword_loc\":", 17); + if (cast->do_keyword_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->do_keyword_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the end_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"end_keyword_loc\":", 18); + pm_dump_json_location(buffer, parser, &cast->end_keyword_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_FORWARDING_ARGUMENTS_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ForwardingArgumentsNode\",\"location\":", 45); + + const pm_forwarding_arguments_node_t *cast = (const pm_forwarding_arguments_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_FORWARDING_PARAMETER_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ForwardingParameterNode\",\"location\":", 45); + + const pm_forwarding_parameter_node_t *cast = (const pm_forwarding_parameter_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_FORWARDING_SUPER_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ForwardingSuperNode\",\"location\":", 41); + + const pm_forwarding_super_node_t *cast = (const pm_forwarding_super_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the block field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"block\":", 8); + if (cast->block != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->block); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_GLOBAL_VARIABLE_AND_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"GlobalVariableAndWriteNode\",\"location\":", 48); + + const pm_global_variable_and_write_node_t *cast = (const pm_global_variable_and_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"GlobalVariableOperatorWriteNode\",\"location\":", 53); + + const pm_global_variable_operator_write_node_t *cast = (const pm_global_variable_operator_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + // Dump the binary_operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"binary_operator_loc\":", 22); + pm_dump_json_location(buffer, parser, &cast->binary_operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + // Dump the binary_operator field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"binary_operator\":", 18); + pm_dump_json_constant(buffer, parser, cast->binary_operator); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_GLOBAL_VARIABLE_OR_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"GlobalVariableOrWriteNode\",\"location\":", 47); + + const pm_global_variable_or_write_node_t *cast = (const pm_global_variable_or_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_GLOBAL_VARIABLE_READ_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"GlobalVariableReadNode\",\"location\":", 44); + + const pm_global_variable_read_node_t *cast = (const pm_global_variable_read_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_GLOBAL_VARIABLE_TARGET_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"GlobalVariableTargetNode\",\"location\":", 46); + + const pm_global_variable_target_node_t *cast = (const pm_global_variable_target_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_GLOBAL_VARIABLE_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"GlobalVariableWriteNode\",\"location\":", 45); + + const pm_global_variable_write_node_t *cast = (const pm_global_variable_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_HASH_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"HashNode\",\"location\":", 30); + + const pm_hash_node_t *cast = (const pm_hash_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->opening_loc); + + // Dump the elements field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"elements\":", 11); + const pm_node_list_t *elements = &cast->elements; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < elements->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, elements->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->closing_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_HASH_PATTERN_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"HashPatternNode\",\"location\":", 37); + + const pm_hash_pattern_node_t *cast = (const pm_hash_pattern_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the constant field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"constant\":", 11); + if (cast->constant != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->constant); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the elements field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"elements\":", 11); + const pm_node_list_t *elements = &cast->elements; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < elements->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, elements->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the rest field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"rest\":", 7); + if (cast->rest != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->rest); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + if (cast->opening_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->opening_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + if (cast->closing_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->closing_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_IF_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"IfNode\",\"location\":", 28); + + const pm_if_node_t *cast = (const pm_if_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the if_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"if_keyword_loc\":", 17); + if (cast->if_keyword_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->if_keyword_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the predicate field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"predicate\":", 12); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->predicate); + + // Dump the then_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"then_keyword_loc\":", 19); + if (cast->then_keyword_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->then_keyword_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the statements field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"statements\":", 13); + if (cast->statements != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->statements); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the subsequent field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"subsequent\":", 13); + if (cast->subsequent != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->subsequent); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the end_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"end_keyword_loc\":", 18); + if (cast->end_keyword_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->end_keyword_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_IMAGINARY_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ImaginaryNode\",\"location\":", 35); + + const pm_imaginary_node_t *cast = (const pm_imaginary_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the numeric field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"numeric\":", 10); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->numeric); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_IMPLICIT_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ImplicitNode\",\"location\":", 34); + + const pm_implicit_node_t *cast = (const pm_implicit_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_IMPLICIT_REST_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ImplicitRestNode\",\"location\":", 38); + + const pm_implicit_rest_node_t *cast = (const pm_implicit_rest_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_IN_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"InNode\",\"location\":", 28); + + const pm_in_node_t *cast = (const pm_in_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the pattern field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"pattern\":", 10); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->pattern); + + // Dump the statements field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"statements\":", 13); + if (cast->statements != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->statements); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the in_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"in_loc\":", 9); + pm_dump_json_location(buffer, parser, &cast->in_loc); + + // Dump the then_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"then_loc\":", 11); + if (cast->then_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->then_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_INDEX_AND_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"IndexAndWriteNode\",\"location\":", 39); + + const pm_index_and_write_node_t *cast = (const pm_index_and_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the CallNodeFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"CallNodeFlags\":", 16); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"SAFE_NAVIGATION\"", 17); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_VARIABLE_CALL)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"VARIABLE_CALL\"", 15); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ATTRIBUTE_WRITE\"", 17); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"IGNORE_VISIBILITY\"", 19); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the receiver field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"receiver\":", 11); + if (cast->receiver != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->receiver); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the call_operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"call_operator_loc\":", 20); + if (cast->call_operator_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->call_operator_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->opening_loc); + + // Dump the arguments field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"arguments\":", 12); + if (cast->arguments != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->arguments); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->closing_loc); + + // Dump the block field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"block\":", 8); + if (cast->block != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->block); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_INDEX_OPERATOR_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"IndexOperatorWriteNode\",\"location\":", 44); + + const pm_index_operator_write_node_t *cast = (const pm_index_operator_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the CallNodeFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"CallNodeFlags\":", 16); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"SAFE_NAVIGATION\"", 17); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_VARIABLE_CALL)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"VARIABLE_CALL\"", 15); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ATTRIBUTE_WRITE\"", 17); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"IGNORE_VISIBILITY\"", 19); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the receiver field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"receiver\":", 11); + if (cast->receiver != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->receiver); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the call_operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"call_operator_loc\":", 20); + if (cast->call_operator_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->call_operator_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->opening_loc); + + // Dump the arguments field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"arguments\":", 12); + if (cast->arguments != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->arguments); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->closing_loc); + + // Dump the block field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"block\":", 8); + if (cast->block != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->block); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the binary_operator field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"binary_operator\":", 18); + pm_dump_json_constant(buffer, parser, cast->binary_operator); + + // Dump the binary_operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"binary_operator_loc\":", 22); + pm_dump_json_location(buffer, parser, &cast->binary_operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_INDEX_OR_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"IndexOrWriteNode\",\"location\":", 38); + + const pm_index_or_write_node_t *cast = (const pm_index_or_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the CallNodeFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"CallNodeFlags\":", 16); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"SAFE_NAVIGATION\"", 17); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_VARIABLE_CALL)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"VARIABLE_CALL\"", 15); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ATTRIBUTE_WRITE\"", 17); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"IGNORE_VISIBILITY\"", 19); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the receiver field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"receiver\":", 11); + if (cast->receiver != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->receiver); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the call_operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"call_operator_loc\":", 20); + if (cast->call_operator_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->call_operator_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->opening_loc); + + // Dump the arguments field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"arguments\":", 12); + if (cast->arguments != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->arguments); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->closing_loc); + + // Dump the block field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"block\":", 8); + if (cast->block != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->block); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_INDEX_TARGET_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"IndexTargetNode\",\"location\":", 37); + + const pm_index_target_node_t *cast = (const pm_index_target_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the CallNodeFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"CallNodeFlags\":", 16); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"SAFE_NAVIGATION\"", 17); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_VARIABLE_CALL)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"VARIABLE_CALL\"", 15); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ATTRIBUTE_WRITE\"", 17); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"IGNORE_VISIBILITY\"", 19); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the receiver field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"receiver\":", 11); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->receiver); + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->opening_loc); + + // Dump the arguments field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"arguments\":", 12); + if (cast->arguments != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->arguments); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->closing_loc); + + // Dump the block field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"block\":", 8); + if (cast->block != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->block); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_INSTANCE_VARIABLE_AND_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"InstanceVariableAndWriteNode\",\"location\":", 50); + + const pm_instance_variable_and_write_node_t *cast = (const pm_instance_variable_and_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"InstanceVariableOperatorWriteNode\",\"location\":", 55); + + const pm_instance_variable_operator_write_node_t *cast = (const pm_instance_variable_operator_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + // Dump the binary_operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"binary_operator_loc\":", 22); + pm_dump_json_location(buffer, parser, &cast->binary_operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + // Dump the binary_operator field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"binary_operator\":", 18); + pm_dump_json_constant(buffer, parser, cast->binary_operator); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_INSTANCE_VARIABLE_OR_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"InstanceVariableOrWriteNode\",\"location\":", 49); + + const pm_instance_variable_or_write_node_t *cast = (const pm_instance_variable_or_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_INSTANCE_VARIABLE_READ_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"InstanceVariableReadNode\",\"location\":", 46); + + const pm_instance_variable_read_node_t *cast = (const pm_instance_variable_read_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_INSTANCE_VARIABLE_TARGET_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"InstanceVariableTargetNode\",\"location\":", 48); + + const pm_instance_variable_target_node_t *cast = (const pm_instance_variable_target_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_INSTANCE_VARIABLE_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"InstanceVariableWriteNode\",\"location\":", 47); + + const pm_instance_variable_write_node_t *cast = (const pm_instance_variable_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_INTEGER_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"IntegerNode\",\"location\":", 33); + + const pm_integer_node_t *cast = (const pm_integer_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the IntegerBaseFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"IntegerBaseFlags\":", 19); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_INTEGER_BASE_FLAGS_BINARY)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"BINARY\"", 8); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_INTEGER_BASE_FLAGS_DECIMAL)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"DECIMAL\"", 9); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_INTEGER_BASE_FLAGS_OCTAL)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"OCTAL\"", 7); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_INTEGER_BASE_FLAGS_HEXADECIMAL)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"HEXADECIMAL\"", 13); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_integer_string(buffer, &cast->value); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_INTERPOLATED_MATCH_LAST_LINE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"InterpolatedMatchLastLineNode\",\"location\":", 51); + + const pm_interpolated_match_last_line_node_t *cast = (const pm_interpolated_match_last_line_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the RegularExpressionFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"RegularExpressionFlags\":", 25); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"IGNORE_CASE\"", 13); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_EXTENDED)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"EXTENDED\"", 10); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"MULTI_LINE\"", 12); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_ONCE)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ONCE\"", 6); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_EUC_JP)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"EUC_JP\"", 8); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ASCII_8BIT\"", 12); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"WINDOWS_31J\"", 13); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_UTF_8)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"UTF_8\"", 7); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_FORCED_UTF8_ENCODING)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"FORCED_UTF8_ENCODING\"", 22); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_FORCED_BINARY_ENCODING)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"FORCED_BINARY_ENCODING\"", 24); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"FORCED_US_ASCII_ENCODING\"", 26); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->opening_loc); + + // Dump the parts field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"parts\":", 8); + const pm_node_list_t *parts = &cast->parts; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < parts->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, parts->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->closing_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"InterpolatedRegularExpressionNode\",\"location\":", 55); + + const pm_interpolated_regular_expression_node_t *cast = (const pm_interpolated_regular_expression_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the RegularExpressionFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"RegularExpressionFlags\":", 25); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"IGNORE_CASE\"", 13); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_EXTENDED)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"EXTENDED\"", 10); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"MULTI_LINE\"", 12); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_ONCE)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ONCE\"", 6); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_EUC_JP)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"EUC_JP\"", 8); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ASCII_8BIT\"", 12); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"WINDOWS_31J\"", 13); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_UTF_8)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"UTF_8\"", 7); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_FORCED_UTF8_ENCODING)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"FORCED_UTF8_ENCODING\"", 22); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_FORCED_BINARY_ENCODING)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"FORCED_BINARY_ENCODING\"", 24); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"FORCED_US_ASCII_ENCODING\"", 26); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->opening_loc); + + // Dump the parts field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"parts\":", 8); + const pm_node_list_t *parts = &cast->parts; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < parts->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, parts->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->closing_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_INTERPOLATED_STRING_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"InterpolatedStringNode\",\"location\":", 44); + + const pm_interpolated_string_node_t *cast = (const pm_interpolated_string_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the InterpolatedStringNodeFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"InterpolatedStringNodeFlags\":", 30); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_INTERPOLATED_STRING_NODE_FLAGS_FROZEN)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"FROZEN\"", 8); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_INTERPOLATED_STRING_NODE_FLAGS_MUTABLE)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"MUTABLE\"", 9); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + if (cast->opening_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->opening_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the parts field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"parts\":", 8); + const pm_node_list_t *parts = &cast->parts; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < parts->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, parts->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + if (cast->closing_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->closing_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_INTERPOLATED_SYMBOL_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"InterpolatedSymbolNode\",\"location\":", 44); + + const pm_interpolated_symbol_node_t *cast = (const pm_interpolated_symbol_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + if (cast->opening_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->opening_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the parts field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"parts\":", 8); + const pm_node_list_t *parts = &cast->parts; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < parts->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, parts->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + if (cast->closing_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->closing_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_INTERPOLATED_X_STRING_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"InterpolatedXStringNode\",\"location\":", 45); + + const pm_interpolated_x_string_node_t *cast = (const pm_interpolated_x_string_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->opening_loc); + + // Dump the parts field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"parts\":", 8); + const pm_node_list_t *parts = &cast->parts; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < parts->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, parts->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->closing_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_IT_LOCAL_VARIABLE_READ_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ItLocalVariableReadNode\",\"location\":", 45); + + const pm_it_local_variable_read_node_t *cast = (const pm_it_local_variable_read_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_IT_PARAMETERS_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ItParametersNode\",\"location\":", 38); + + const pm_it_parameters_node_t *cast = (const pm_it_parameters_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_KEYWORD_HASH_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"KeywordHashNode\",\"location\":", 37); + + const pm_keyword_hash_node_t *cast = (const pm_keyword_hash_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the KeywordHashNodeFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"KeywordHashNodeFlags\":", 23); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_KEYWORD_HASH_NODE_FLAGS_SYMBOL_KEYS)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"SYMBOL_KEYS\"", 13); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the elements field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"elements\":", 11); + const pm_node_list_t *elements = &cast->elements; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < elements->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, elements->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_KEYWORD_REST_PARAMETER_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"KeywordRestParameterNode\",\"location\":", 46); + + const pm_keyword_rest_parameter_node_t *cast = (const pm_keyword_rest_parameter_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the ParameterFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ParameterFlags\":", 17); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_PARAMETER_FLAGS_REPEATED_PARAMETER)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"REPEATED_PARAMETER\"", 20); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + if (cast->name != PM_CONSTANT_ID_UNSET) { + pm_dump_json_constant(buffer, parser, cast->name); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + if (cast->name_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->name_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_LAMBDA_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"LambdaNode\",\"location\":", 32); + + const pm_lambda_node_t *cast = (const pm_lambda_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the locals field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"locals\":", 9); + const pm_constant_id_list_t *locals = &cast->locals; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < locals->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json_constant(buffer, parser, locals->ids[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->opening_loc); + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->closing_loc); + + // Dump the parameters field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"parameters\":", 13); + if (cast->parameters != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->parameters); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the body field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"body\":", 7); + if (cast->body != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->body); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_LOCAL_VARIABLE_AND_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"LocalVariableAndWriteNode\",\"location\":", 47); + + const pm_local_variable_and_write_node_t *cast = (const pm_local_variable_and_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the depth field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"depth\":", 8); + pm_buffer_append_format(buffer, "%" PRIu32, cast->depth); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"LocalVariableOperatorWriteNode\",\"location\":", 52); + + const pm_local_variable_operator_write_node_t *cast = (const pm_local_variable_operator_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + // Dump the binary_operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"binary_operator_loc\":", 22); + pm_dump_json_location(buffer, parser, &cast->binary_operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the binary_operator field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"binary_operator\":", 18); + pm_dump_json_constant(buffer, parser, cast->binary_operator); + + // Dump the depth field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"depth\":", 8); + pm_buffer_append_format(buffer, "%" PRIu32, cast->depth); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_LOCAL_VARIABLE_OR_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"LocalVariableOrWriteNode\",\"location\":", 46); + + const pm_local_variable_or_write_node_t *cast = (const pm_local_variable_or_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the depth field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"depth\":", 8); + pm_buffer_append_format(buffer, "%" PRIu32, cast->depth); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_LOCAL_VARIABLE_READ_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"LocalVariableReadNode\",\"location\":", 43); + + const pm_local_variable_read_node_t *cast = (const pm_local_variable_read_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the depth field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"depth\":", 8); + pm_buffer_append_format(buffer, "%" PRIu32, cast->depth); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_LOCAL_VARIABLE_TARGET_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"LocalVariableTargetNode\",\"location\":", 45); + + const pm_local_variable_target_node_t *cast = (const pm_local_variable_target_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the depth field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"depth\":", 8); + pm_buffer_append_format(buffer, "%" PRIu32, cast->depth); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_LOCAL_VARIABLE_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"LocalVariableWriteNode\",\"location\":", 44); + + const pm_local_variable_write_node_t *cast = (const pm_local_variable_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the depth field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"depth\":", 8); + pm_buffer_append_format(buffer, "%" PRIu32, cast->depth); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_MATCH_LAST_LINE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"MatchLastLineNode\",\"location\":", 39); + + const pm_match_last_line_node_t *cast = (const pm_match_last_line_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the RegularExpressionFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"RegularExpressionFlags\":", 25); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"IGNORE_CASE\"", 13); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_EXTENDED)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"EXTENDED\"", 10); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"MULTI_LINE\"", 12); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_ONCE)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ONCE\"", 6); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_EUC_JP)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"EUC_JP\"", 8); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ASCII_8BIT\"", 12); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"WINDOWS_31J\"", 13); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_UTF_8)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"UTF_8\"", 7); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_FORCED_UTF8_ENCODING)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"FORCED_UTF8_ENCODING\"", 22); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_FORCED_BINARY_ENCODING)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"FORCED_BINARY_ENCODING\"", 24); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"FORCED_US_ASCII_ENCODING\"", 26); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->opening_loc); + + // Dump the content_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"content_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->content_loc); + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->closing_loc); + + // Dump the unescaped field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"unescaped\":", 12); + const pm_string_t *unescaped = &cast->unescaped; + pm_buffer_append_byte(buffer, '"'); + pm_buffer_append_source(buffer, pm_string_source(unescaped), pm_string_length(unescaped), PM_BUFFER_ESCAPING_JSON); + pm_buffer_append_byte(buffer, '"'); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_MATCH_PREDICATE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"MatchPredicateNode\",\"location\":", 40); + + const pm_match_predicate_node_t *cast = (const pm_match_predicate_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + // Dump the pattern field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"pattern\":", 10); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->pattern); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_MATCH_REQUIRED_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"MatchRequiredNode\",\"location\":", 39); + + const pm_match_required_node_t *cast = (const pm_match_required_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + // Dump the pattern field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"pattern\":", 10); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->pattern); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_MATCH_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"MatchWriteNode\",\"location\":", 36); + + const pm_match_write_node_t *cast = (const pm_match_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the call field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"call\":", 7); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->call); + + // Dump the targets field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"targets\":", 10); + const pm_node_list_t *targets = &cast->targets; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < targets->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, targets->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_MISSING_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"MissingNode\",\"location\":", 33); + + const pm_missing_node_t *cast = (const pm_missing_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_MODULE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ModuleNode\",\"location\":", 32); + + const pm_module_node_t *cast = (const pm_module_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the locals field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"locals\":", 9); + const pm_constant_id_list_t *locals = &cast->locals; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < locals->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json_constant(buffer, parser, locals->ids[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the module_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"module_keyword_loc\":", 21); + pm_dump_json_location(buffer, parser, &cast->module_keyword_loc); + + // Dump the constant_path field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"constant_path\":", 16); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->constant_path); + + // Dump the body field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"body\":", 7); + if (cast->body != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->body); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the end_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"end_keyword_loc\":", 18); + pm_dump_json_location(buffer, parser, &cast->end_keyword_loc); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_MULTI_TARGET_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"MultiTargetNode\",\"location\":", 37); + + const pm_multi_target_node_t *cast = (const pm_multi_target_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the lefts field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"lefts\":", 8); + const pm_node_list_t *lefts = &cast->lefts; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < lefts->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, lefts->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the rest field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"rest\":", 7); + if (cast->rest != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->rest); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the rights field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"rights\":", 9); + const pm_node_list_t *rights = &cast->rights; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < rights->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, rights->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the lparen_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"lparen_loc\":", 13); + if (cast->lparen_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->lparen_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the rparen_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"rparen_loc\":", 13); + if (cast->rparen_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->rparen_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_MULTI_WRITE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"MultiWriteNode\",\"location\":", 36); + + const pm_multi_write_node_t *cast = (const pm_multi_write_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the lefts field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"lefts\":", 8); + const pm_node_list_t *lefts = &cast->lefts; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < lefts->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, lefts->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the rest field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"rest\":", 7); + if (cast->rest != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->rest); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the rights field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"rights\":", 9); + const pm_node_list_t *rights = &cast->rights; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < rights->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, rights->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the lparen_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"lparen_loc\":", 13); + if (cast->lparen_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->lparen_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the rparen_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"rparen_loc\":", 13); + if (cast->rparen_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->rparen_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_NEXT_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"NextNode\",\"location\":", 30); + + const pm_next_node_t *cast = (const pm_next_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the arguments field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"arguments\":", 12); + if (cast->arguments != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->arguments); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"keyword_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->keyword_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_NIL_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"NilNode\",\"location\":", 29); + + const pm_nil_node_t *cast = (const pm_nil_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_NO_KEYWORDS_PARAMETER_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"NoKeywordsParameterNode\",\"location\":", 45); + + const pm_no_keywords_parameter_node_t *cast = (const pm_no_keywords_parameter_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"keyword_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->keyword_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_NUMBERED_PARAMETERS_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"NumberedParametersNode\",\"location\":", 44); + + const pm_numbered_parameters_node_t *cast = (const pm_numbered_parameters_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the maximum field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"maximum\":", 10); + pm_buffer_append_format(buffer, "%" PRIu8, cast->maximum); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_NUMBERED_REFERENCE_READ_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"NumberedReferenceReadNode\",\"location\":", 47); + + const pm_numbered_reference_read_node_t *cast = (const pm_numbered_reference_read_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the number field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"number\":", 9); + pm_buffer_append_format(buffer, "%" PRIu32, cast->number); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_OPTIONAL_KEYWORD_PARAMETER_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"OptionalKeywordParameterNode\",\"location\":", 50); + + const pm_optional_keyword_parameter_node_t *cast = (const pm_optional_keyword_parameter_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the ParameterFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ParameterFlags\":", 17); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_PARAMETER_FLAGS_REPEATED_PARAMETER)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"REPEATED_PARAMETER\"", 20); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_OPTIONAL_PARAMETER_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"OptionalParameterNode\",\"location\":", 43); + + const pm_optional_parameter_node_t *cast = (const pm_optional_parameter_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the ParameterFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ParameterFlags\":", 17); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_PARAMETER_FLAGS_REPEATED_PARAMETER)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"REPEATED_PARAMETER\"", 20); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the value field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->value); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_OR_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"OrNode\",\"location\":", 28); + + const pm_or_node_t *cast = (const pm_or_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the left field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"left\":", 7); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->left); + + // Dump the right field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"right\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->right); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_PARAMETERS_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ParametersNode\",\"location\":", 36); + + const pm_parameters_node_t *cast = (const pm_parameters_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the requireds field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"requireds\":", 12); + const pm_node_list_t *requireds = &cast->requireds; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < requireds->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, requireds->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the optionals field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"optionals\":", 12); + const pm_node_list_t *optionals = &cast->optionals; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < optionals->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, optionals->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the rest field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"rest\":", 7); + if (cast->rest != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->rest); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the posts field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"posts\":", 8); + const pm_node_list_t *posts = &cast->posts; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < posts->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, posts->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the keywords field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"keywords\":", 11); + const pm_node_list_t *keywords = &cast->keywords; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < keywords->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, keywords->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the keyword_rest field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"keyword_rest\":", 15); + if (cast->keyword_rest != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->keyword_rest); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the block field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"block\":", 8); + if (cast->block != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->block); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_PARENTHESES_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ParenthesesNode\",\"location\":", 37); + + const pm_parentheses_node_t *cast = (const pm_parentheses_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the ParenthesesNodeFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ParenthesesNodeFlags\":", 23); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_PARENTHESES_NODE_FLAGS_MULTIPLE_STATEMENTS)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"MULTIPLE_STATEMENTS\"", 21); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the body field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"body\":", 7); + if (cast->body != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->body); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->opening_loc); + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->closing_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_PINNED_EXPRESSION_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"PinnedExpressionNode\",\"location\":", 42); + + const pm_pinned_expression_node_t *cast = (const pm_pinned_expression_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the expression field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"expression\":", 13); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->expression); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the lparen_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"lparen_loc\":", 13); + pm_dump_json_location(buffer, parser, &cast->lparen_loc); + + // Dump the rparen_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"rparen_loc\":", 13); + pm_dump_json_location(buffer, parser, &cast->rparen_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_PINNED_VARIABLE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"PinnedVariableNode\",\"location\":", 40); + + const pm_pinned_variable_node_t *cast = (const pm_pinned_variable_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the variable field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"variable\":", 11); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->variable); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_POST_EXECUTION_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"PostExecutionNode\",\"location\":", 39); + + const pm_post_execution_node_t *cast = (const pm_post_execution_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the statements field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"statements\":", 13); + if (cast->statements != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->statements); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"keyword_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->keyword_loc); + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->opening_loc); + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->closing_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_PRE_EXECUTION_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"PreExecutionNode\",\"location\":", 38); + + const pm_pre_execution_node_t *cast = (const pm_pre_execution_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the statements field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"statements\":", 13); + if (cast->statements != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->statements); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"keyword_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->keyword_loc); + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->opening_loc); + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->closing_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_PROGRAM_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ProgramNode\",\"location\":", 33); + + const pm_program_node_t *cast = (const pm_program_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the locals field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"locals\":", 9); + const pm_constant_id_list_t *locals = &cast->locals; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < locals->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json_constant(buffer, parser, locals->ids[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the statements field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"statements\":", 13); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->statements); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_RANGE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"RangeNode\",\"location\":", 31); + + const pm_range_node_t *cast = (const pm_range_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the RangeFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"RangeFlags\":", 13); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_RANGE_FLAGS_EXCLUDE_END)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"EXCLUDE_END\"", 13); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the left field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"left\":", 7); + if (cast->left != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->left); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the right field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"right\":", 8); + if (cast->right != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->right); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_RATIONAL_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"RationalNode\",\"location\":", 34); + + const pm_rational_node_t *cast = (const pm_rational_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the IntegerBaseFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"IntegerBaseFlags\":", 19); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_INTEGER_BASE_FLAGS_BINARY)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"BINARY\"", 8); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_INTEGER_BASE_FLAGS_DECIMAL)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"DECIMAL\"", 9); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_INTEGER_BASE_FLAGS_OCTAL)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"OCTAL\"", 7); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_INTEGER_BASE_FLAGS_HEXADECIMAL)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"HEXADECIMAL\"", 13); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the numerator field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"numerator\":", 12); + pm_integer_string(buffer, &cast->numerator); + + // Dump the denominator field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"denominator\":", 14); + pm_integer_string(buffer, &cast->denominator); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_REDO_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"RedoNode\",\"location\":", 30); + + const pm_redo_node_t *cast = (const pm_redo_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_REGULAR_EXPRESSION_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"RegularExpressionNode\",\"location\":", 43); + + const pm_regular_expression_node_t *cast = (const pm_regular_expression_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the RegularExpressionFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"RegularExpressionFlags\":", 25); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"IGNORE_CASE\"", 13); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_EXTENDED)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"EXTENDED\"", 10); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"MULTI_LINE\"", 12); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_ONCE)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ONCE\"", 6); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_EUC_JP)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"EUC_JP\"", 8); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ASCII_8BIT\"", 12); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"WINDOWS_31J\"", 13); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_UTF_8)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"UTF_8\"", 7); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_FORCED_UTF8_ENCODING)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"FORCED_UTF8_ENCODING\"", 22); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_FORCED_BINARY_ENCODING)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"FORCED_BINARY_ENCODING\"", 24); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"FORCED_US_ASCII_ENCODING\"", 26); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->opening_loc); + + // Dump the content_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"content_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->content_loc); + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->closing_loc); + + // Dump the unescaped field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"unescaped\":", 12); + const pm_string_t *unescaped = &cast->unescaped; + pm_buffer_append_byte(buffer, '"'); + pm_buffer_append_source(buffer, pm_string_source(unescaped), pm_string_length(unescaped), PM_BUFFER_ESCAPING_JSON); + pm_buffer_append_byte(buffer, '"'); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_REQUIRED_KEYWORD_PARAMETER_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"RequiredKeywordParameterNode\",\"location\":", 50); + + const pm_required_keyword_parameter_node_t *cast = (const pm_required_keyword_parameter_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the ParameterFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ParameterFlags\":", 17); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_PARAMETER_FLAGS_REPEATED_PARAMETER)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"REPEATED_PARAMETER\"", 20); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + pm_dump_json_location(buffer, parser, &cast->name_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_REQUIRED_PARAMETER_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"RequiredParameterNode\",\"location\":", 43); + + const pm_required_parameter_node_t *cast = (const pm_required_parameter_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the ParameterFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ParameterFlags\":", 17); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_PARAMETER_FLAGS_REPEATED_PARAMETER)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"REPEATED_PARAMETER\"", 20); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + pm_dump_json_constant(buffer, parser, cast->name); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_RESCUE_MODIFIER_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"RescueModifierNode\",\"location\":", 40); + + const pm_rescue_modifier_node_t *cast = (const pm_rescue_modifier_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the expression field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"expression\":", 13); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->expression); + + // Dump the keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"keyword_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->keyword_loc); + + // Dump the rescue_expression field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"rescue_expression\":", 20); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->rescue_expression); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_RESCUE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"RescueNode\",\"location\":", 32); + + const pm_rescue_node_t *cast = (const pm_rescue_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"keyword_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->keyword_loc); + + // Dump the exceptions field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"exceptions\":", 13); + const pm_node_list_t *exceptions = &cast->exceptions; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < exceptions->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, exceptions->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + if (cast->operator_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->operator_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the reference field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"reference\":", 12); + if (cast->reference != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->reference); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the then_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"then_keyword_loc\":", 19); + if (cast->then_keyword_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->then_keyword_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the statements field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"statements\":", 13); + if (cast->statements != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->statements); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the subsequent field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"subsequent\":", 13); + if (cast->subsequent != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->subsequent); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_REST_PARAMETER_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"RestParameterNode\",\"location\":", 39); + + const pm_rest_parameter_node_t *cast = (const pm_rest_parameter_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the ParameterFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ParameterFlags\":", 17); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_PARAMETER_FLAGS_REPEATED_PARAMETER)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"REPEATED_PARAMETER\"", 20); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the name field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name\":", 7); + if (cast->name != PM_CONSTANT_ID_UNSET) { + pm_dump_json_constant(buffer, parser, cast->name); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the name_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"name_loc\":", 11); + if (cast->name_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->name_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_RETRY_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"RetryNode\",\"location\":", 31); + + const pm_retry_node_t *cast = (const pm_retry_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_RETURN_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ReturnNode\",\"location\":", 32); + + const pm_return_node_t *cast = (const pm_return_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"keyword_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->keyword_loc); + + // Dump the arguments field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"arguments\":", 12); + if (cast->arguments != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->arguments); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_SELF_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"SelfNode\",\"location\":", 30); + + const pm_self_node_t *cast = (const pm_self_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_SHAREABLE_CONSTANT_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"ShareableConstantNode\",\"location\":", 43); + + const pm_shareable_constant_node_t *cast = (const pm_shareable_constant_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the ShareableConstantNodeFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"ShareableConstantNodeFlags\":", 29); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_SHAREABLE_CONSTANT_NODE_FLAGS_LITERAL)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"LITERAL\"", 9); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_SHAREABLE_CONSTANT_NODE_FLAGS_EXPERIMENTAL_EVERYTHING)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"EXPERIMENTAL_EVERYTHING\"", 25); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_SHAREABLE_CONSTANT_NODE_FLAGS_EXPERIMENTAL_COPY)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"EXPERIMENTAL_COPY\"", 19); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the write field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"write\":", 8); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->write); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_SINGLETON_CLASS_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"SingletonClassNode\",\"location\":", 40); + + const pm_singleton_class_node_t *cast = (const pm_singleton_class_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the locals field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"locals\":", 9); + const pm_constant_id_list_t *locals = &cast->locals; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < locals->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json_constant(buffer, parser, locals->ids[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the class_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"class_keyword_loc\":", 20); + pm_dump_json_location(buffer, parser, &cast->class_keyword_loc); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the expression field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"expression\":", 13); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->expression); + + // Dump the body field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"body\":", 7); + if (cast->body != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->body); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the end_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"end_keyword_loc\":", 18); + pm_dump_json_location(buffer, parser, &cast->end_keyword_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_SOURCE_ENCODING_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"SourceEncodingNode\",\"location\":", 40); + + const pm_source_encoding_node_t *cast = (const pm_source_encoding_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_SOURCE_FILE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"SourceFileNode\",\"location\":", 36); + + const pm_source_file_node_t *cast = (const pm_source_file_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the StringFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"StringFlags\":", 14); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_STRING_FLAGS_FORCED_UTF8_ENCODING)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"FORCED_UTF8_ENCODING\"", 22); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_STRING_FLAGS_FORCED_BINARY_ENCODING)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"FORCED_BINARY_ENCODING\"", 24); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_STRING_FLAGS_FROZEN)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"FROZEN\"", 8); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_STRING_FLAGS_MUTABLE)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"MUTABLE\"", 9); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the filepath field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"filepath\":", 11); + const pm_string_t *filepath = &cast->filepath; + pm_buffer_append_byte(buffer, '"'); + pm_buffer_append_source(buffer, pm_string_source(filepath), pm_string_length(filepath), PM_BUFFER_ESCAPING_JSON); + pm_buffer_append_byte(buffer, '"'); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_SOURCE_LINE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"SourceLineNode\",\"location\":", 36); + + const pm_source_line_node_t *cast = (const pm_source_line_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_SPLAT_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"SplatNode\",\"location\":", 31); + + const pm_splat_node_t *cast = (const pm_splat_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the operator_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"operator_loc\":", 15); + pm_dump_json_location(buffer, parser, &cast->operator_loc); + + // Dump the expression field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"expression\":", 13); + if (cast->expression != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->expression); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_STATEMENTS_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"StatementsNode\",\"location\":", 36); + + const pm_statements_node_t *cast = (const pm_statements_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the body field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"body\":", 7); + const pm_node_list_t *body = &cast->body; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < body->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, body->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_STRING_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"StringNode\",\"location\":", 32); + + const pm_string_node_t *cast = (const pm_string_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the StringFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"StringFlags\":", 14); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_STRING_FLAGS_FORCED_UTF8_ENCODING)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"FORCED_UTF8_ENCODING\"", 22); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_STRING_FLAGS_FORCED_BINARY_ENCODING)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"FORCED_BINARY_ENCODING\"", 24); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_STRING_FLAGS_FROZEN)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"FROZEN\"", 8); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_STRING_FLAGS_MUTABLE)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"MUTABLE\"", 9); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + if (cast->opening_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->opening_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the content_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"content_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->content_loc); + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + if (cast->closing_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->closing_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the unescaped field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"unescaped\":", 12); + const pm_string_t *unescaped = &cast->unescaped; + pm_buffer_append_byte(buffer, '"'); + pm_buffer_append_source(buffer, pm_string_source(unescaped), pm_string_length(unescaped), PM_BUFFER_ESCAPING_JSON); + pm_buffer_append_byte(buffer, '"'); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_SUPER_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"SuperNode\",\"location\":", 31); + + const pm_super_node_t *cast = (const pm_super_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"keyword_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->keyword_loc); + + // Dump the lparen_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"lparen_loc\":", 13); + if (cast->lparen_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->lparen_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the arguments field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"arguments\":", 12); + if (cast->arguments != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->arguments); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the rparen_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"rparen_loc\":", 13); + if (cast->rparen_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->rparen_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the block field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"block\":", 8); + if (cast->block != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->block); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_SYMBOL_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"SymbolNode\",\"location\":", 32); + + const pm_symbol_node_t *cast = (const pm_symbol_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the SymbolFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"SymbolFlags\":", 14); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_SYMBOL_FLAGS_FORCED_UTF8_ENCODING)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"FORCED_UTF8_ENCODING\"", 22); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_SYMBOL_FLAGS_FORCED_BINARY_ENCODING)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"FORCED_BINARY_ENCODING\"", 24); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_SYMBOL_FLAGS_FORCED_US_ASCII_ENCODING)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"FORCED_US_ASCII_ENCODING\"", 26); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + if (cast->opening_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->opening_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the value_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"value_loc\":", 12); + if (cast->value_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->value_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + if (cast->closing_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->closing_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the unescaped field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"unescaped\":", 12); + const pm_string_t *unescaped = &cast->unescaped; + pm_buffer_append_byte(buffer, '"'); + pm_buffer_append_source(buffer, pm_string_source(unescaped), pm_string_length(unescaped), PM_BUFFER_ESCAPING_JSON); + pm_buffer_append_byte(buffer, '"'); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_TRUE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"TrueNode\",\"location\":", 30); + + const pm_true_node_t *cast = (const pm_true_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_UNDEF_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"UndefNode\",\"location\":", 31); + + const pm_undef_node_t *cast = (const pm_undef_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the names field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"names\":", 8); + const pm_node_list_t *names = &cast->names; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < names->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, names->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"keyword_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->keyword_loc); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_UNLESS_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"UnlessNode\",\"location\":", 32); + + const pm_unless_node_t *cast = (const pm_unless_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"keyword_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->keyword_loc); + + // Dump the predicate field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"predicate\":", 12); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->predicate); + + // Dump the then_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"then_keyword_loc\":", 19); + if (cast->then_keyword_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->then_keyword_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the statements field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"statements\":", 13); + if (cast->statements != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->statements); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the else_clause field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"else_clause\":", 14); + if (cast->else_clause != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->else_clause); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the end_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"end_keyword_loc\":", 18); + if (cast->end_keyword_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->end_keyword_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_UNTIL_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"UntilNode\",\"location\":", 31); + + const pm_until_node_t *cast = (const pm_until_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the LoopFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"LoopFlags\":", 12); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_LOOP_FLAGS_BEGIN_MODIFIER)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"BEGIN_MODIFIER\"", 16); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"keyword_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->keyword_loc); + + // Dump the do_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"do_keyword_loc\":", 17); + if (cast->do_keyword_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->do_keyword_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + if (cast->closing_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->closing_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the predicate field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"predicate\":", 12); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->predicate); + + // Dump the statements field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"statements\":", 13); + if (cast->statements != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->statements); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_WHEN_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"WhenNode\",\"location\":", 30); + + const pm_when_node_t *cast = (const pm_when_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"keyword_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->keyword_loc); + + // Dump the conditions field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"conditions\":", 13); + const pm_node_list_t *conditions = &cast->conditions; + pm_buffer_append_byte(buffer, '['); + + for (size_t index = 0; index < conditions->size; index++) { + if (index != 0) pm_buffer_append_byte(buffer, ','); + pm_dump_json(buffer, parser, conditions->nodes[index]); + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the then_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"then_keyword_loc\":", 19); + if (cast->then_keyword_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->then_keyword_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the statements field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"statements\":", 13); + if (cast->statements != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->statements); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_WHILE_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"WhileNode\",\"location\":", 31); + + const pm_while_node_t *cast = (const pm_while_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the LoopFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"LoopFlags\":", 12); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_LOOP_FLAGS_BEGIN_MODIFIER)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"BEGIN_MODIFIER\"", 16); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"keyword_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->keyword_loc); + + // Dump the do_keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"do_keyword_loc\":", 17); + if (cast->do_keyword_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->do_keyword_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + if (cast->closing_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->closing_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the predicate field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"predicate\":", 12); + pm_dump_json(buffer, parser, (const pm_node_t *) cast->predicate); + + // Dump the statements field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"statements\":", 13); + if (cast->statements != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->statements); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_X_STRING_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"XStringNode\",\"location\":", 33); + + const pm_x_string_node_t *cast = (const pm_x_string_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the EncodingFlags field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"EncodingFlags\":", 16); + size_t flags = 0; + pm_buffer_append_byte(buffer, '['); + if (PM_NODE_FLAG_P(cast, PM_ENCODING_FLAGS_FORCED_UTF8_ENCODING)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"FORCED_UTF8_ENCODING\"", 22); + flags++; + } + if (PM_NODE_FLAG_P(cast, PM_ENCODING_FLAGS_FORCED_BINARY_ENCODING)) { + if (flags != 0) pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"FORCED_BINARY_ENCODING\"", 24); + flags++; + } + pm_buffer_append_byte(buffer, ']'); + + // Dump the opening_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"opening_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->opening_loc); + + // Dump the content_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"content_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->content_loc); + + // Dump the closing_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"closing_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->closing_loc); + + // Dump the unescaped field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"unescaped\":", 12); + const pm_string_t *unescaped = &cast->unescaped; + pm_buffer_append_byte(buffer, '"'); + pm_buffer_append_source(buffer, pm_string_source(unescaped), pm_string_length(unescaped), PM_BUFFER_ESCAPING_JSON); + pm_buffer_append_byte(buffer, '"'); + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_YIELD_NODE: { + pm_buffer_append_string(buffer, "{\"type\":\"YieldNode\",\"location\":", 31); + + const pm_yield_node_t *cast = (const pm_yield_node_t *) node; + pm_dump_json_location(buffer, parser, &cast->base.location); + + // Dump the keyword_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"keyword_loc\":", 14); + pm_dump_json_location(buffer, parser, &cast->keyword_loc); + + // Dump the lparen_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"lparen_loc\":", 13); + if (cast->lparen_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->lparen_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the arguments field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"arguments\":", 12); + if (cast->arguments != NULL) { + pm_dump_json(buffer, parser, (const pm_node_t *) cast->arguments); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + // Dump the rparen_loc field + pm_buffer_append_byte(buffer, ','); + pm_buffer_append_string(buffer, "\"rparen_loc\":", 13); + if (cast->rparen_loc.start != NULL) { + pm_dump_json_location(buffer, parser, &cast->rparen_loc); + } else { + pm_buffer_append_string(buffer, "null", 4); + } + + pm_buffer_append_byte(buffer, '}'); + break; + } + case PM_SCOPE_NODE: + break; + } +} + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/options.c b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/options.c new file mode 100644 index 00000000..a457178c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/options.c @@ -0,0 +1,328 @@ +#include "prism/options.h" + +/** + * Set the shebang callback option on the given options struct. + */ +PRISM_EXPORTED_FUNCTION void +pm_options_shebang_callback_set(pm_options_t *options, pm_options_shebang_callback_t shebang_callback, void *shebang_callback_data) { + options->shebang_callback = shebang_callback; + options->shebang_callback_data = shebang_callback_data; +} + +/** + * Set the filepath option on the given options struct. + */ +PRISM_EXPORTED_FUNCTION void +pm_options_filepath_set(pm_options_t *options, const char *filepath) { + pm_string_constant_init(&options->filepath, filepath, strlen(filepath)); +} + +/** + * Set the encoding option on the given options struct. + */ +PRISM_EXPORTED_FUNCTION void +pm_options_encoding_set(pm_options_t *options, const char *encoding) { + pm_string_constant_init(&options->encoding, encoding, strlen(encoding)); +} + +/** + * Set the encoding_locked option on the given options struct. + */ +PRISM_EXPORTED_FUNCTION void +pm_options_encoding_locked_set(pm_options_t *options, bool encoding_locked) { + options->encoding_locked = encoding_locked; +} + +/** + * Set the line option on the given options struct. + */ +PRISM_EXPORTED_FUNCTION void +pm_options_line_set(pm_options_t *options, int32_t line) { + options->line = line; +} + +/** + * Set the frozen string literal option on the given options struct. + */ +PRISM_EXPORTED_FUNCTION void +pm_options_frozen_string_literal_set(pm_options_t *options, bool frozen_string_literal) { + options->frozen_string_literal = frozen_string_literal ? PM_OPTIONS_FROZEN_STRING_LITERAL_ENABLED : PM_OPTIONS_FROZEN_STRING_LITERAL_DISABLED; +} + +/** + * Sets the command line option on the given options struct. + */ +PRISM_EXPORTED_FUNCTION void +pm_options_command_line_set(pm_options_t *options, uint8_t command_line) { + options->command_line = command_line; +} + +/** + * Checks if the given slice represents a number. + */ +static inline bool +is_number(const char *string, size_t length) { + return pm_strspn_decimal_digit((const uint8_t *) string, (ptrdiff_t) length) == length; +} + +/** + * Set the version option on the given options struct by parsing the given + * string. If the string contains an invalid option, this returns false. + * Otherwise, it returns true. + */ +PRISM_EXPORTED_FUNCTION bool +pm_options_version_set(pm_options_t *options, const char *version, size_t length) { + if (version == NULL) { + options->version = PM_OPTIONS_VERSION_LATEST; + return true; + } + + if (length == 3) { + if (strncmp(version, "3.3", 3) == 0) { + options->version = PM_OPTIONS_VERSION_CRUBY_3_3; + return true; + } + + if (strncmp(version, "3.4", 3) == 0) { + options->version = PM_OPTIONS_VERSION_CRUBY_3_4; + return true; + } + + if (strncmp(version, "3.5", 3) == 0) { + options->version = PM_OPTIONS_VERSION_LATEST; + return true; + } + + return false; + } + + if (length >= 4) { + if (strncmp(version, "3.3.", 4) == 0 && is_number(version + 4, length - 4)) { + options->version = PM_OPTIONS_VERSION_CRUBY_3_3; + return true; + } + + if (strncmp(version, "3.4.", 4) == 0 && is_number(version + 4, length - 4)) { + options->version = PM_OPTIONS_VERSION_CRUBY_3_4; + return true; + } + + if (strncmp(version, "3.5.", 4) == 0 && is_number(version + 4, length - 4)) { + options->version = PM_OPTIONS_VERSION_LATEST; + return true; + } + } + + if (length >= 6) { + if (strncmp(version, "latest", 7) == 0) { // 7 to compare the \0 as well + options->version = PM_OPTIONS_VERSION_LATEST; + return true; + } + } + + return false; +} + +/** + * Set the main script option on the given options struct. + */ +PRISM_EXPORTED_FUNCTION void +pm_options_main_script_set(pm_options_t *options, bool main_script) { + options->main_script = main_script; +} + +/** + * Set the partial script option on the given options struct. + */ +PRISM_EXPORTED_FUNCTION void +pm_options_partial_script_set(pm_options_t *options, bool partial_script) { + options->partial_script = partial_script; +} + +/** + * Set the freeze option on the given options struct. + */ +PRISM_EXPORTED_FUNCTION void +pm_options_freeze_set(pm_options_t *options, bool freeze) { + options->freeze = freeze; +} + +// For some reason, GCC analyzer thinks we're leaking allocated scopes and +// locals here, even though we definitely aren't. This is a false positive. +// Ideally we wouldn't need to suppress this. +#if defined(__GNUC__) && (__GNUC__ >= 10) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak" +#endif + +/** + * Allocate and zero out the scopes array on the given options struct. + */ +PRISM_EXPORTED_FUNCTION bool +pm_options_scopes_init(pm_options_t *options, size_t scopes_count) { + options->scopes_count = scopes_count; + options->scopes = xcalloc(scopes_count, sizeof(pm_options_scope_t)); + return options->scopes != NULL; +} + +/** + * Return a pointer to the scope at the given index within the given options. + */ +PRISM_EXPORTED_FUNCTION const pm_options_scope_t * +pm_options_scope_get(const pm_options_t *options, size_t index) { + return &options->scopes[index]; +} + +/** + * Create a new options scope struct. This will hold a set of locals that are in + * scope surrounding the code that is being parsed. + */ +PRISM_EXPORTED_FUNCTION bool +pm_options_scope_init(pm_options_scope_t *scope, size_t locals_count) { + scope->locals_count = locals_count; + scope->locals = xcalloc(locals_count, sizeof(pm_string_t)); + scope->forwarding = PM_OPTIONS_SCOPE_FORWARDING_NONE; + return scope->locals != NULL; +} + +/** + * Return a pointer to the local at the given index within the given scope. + */ +PRISM_EXPORTED_FUNCTION const pm_string_t * +pm_options_scope_local_get(const pm_options_scope_t *scope, size_t index) { + return &scope->locals[index]; +} + +/** + * Set the forwarding option on the given scope struct. + */ +PRISM_EXPORTED_FUNCTION void +pm_options_scope_forwarding_set(pm_options_scope_t *scope, uint8_t forwarding) { + scope->forwarding = forwarding; +} + +/** + * Free the internal memory associated with the options. + */ +PRISM_EXPORTED_FUNCTION void +pm_options_free(pm_options_t *options) { + pm_string_free(&options->filepath); + pm_string_free(&options->encoding); + + for (size_t scope_index = 0; scope_index < options->scopes_count; scope_index++) { + pm_options_scope_t *scope = &options->scopes[scope_index]; + + for (size_t local_index = 0; local_index < scope->locals_count; local_index++) { + pm_string_free(&scope->locals[local_index]); + } + + xfree(scope->locals); + } + + xfree(options->scopes); +} + +/** + * Read a 32-bit unsigned integer from a pointer. This function is used to read + * the options that are passed into the parser from the Ruby implementation. It + * handles aligned and unaligned reads. + */ +static uint32_t +pm_options_read_u32(const char *data) { + if (((uintptr_t) data) % sizeof(uint32_t) == 0) { + return *((uint32_t *) data); + } else { + uint32_t value; + memcpy(&value, data, sizeof(uint32_t)); + return value; + } +} + +/** + * Read a 32-bit signed integer from a pointer. This function is used to read + * the options that are passed into the parser from the Ruby implementation. It + * handles aligned and unaligned reads. + */ +static int32_t +pm_options_read_s32(const char *data) { + if (((uintptr_t) data) % sizeof(int32_t) == 0) { + return *((int32_t *) data); + } else { + int32_t value; + memcpy(&value, data, sizeof(int32_t)); + return value; + } +} + +/** + * Deserialize an options struct from the given binary string. This is used to + * pass options to the parser from an FFI call so that consumers of the library + * from an FFI perspective don't have to worry about the structure of our + * options structs. Since the source of these calls will be from Ruby + * implementation internals we assume it is from a trusted source. + */ +void +pm_options_read(pm_options_t *options, const char *data) { + options->line = 1; // default + if (data == NULL) return; + + uint32_t filepath_length = pm_options_read_u32(data); + data += 4; + + if (filepath_length > 0) { + pm_string_constant_init(&options->filepath, data, filepath_length); + data += filepath_length; + } + + options->line = pm_options_read_s32(data); + data += 4; + + uint32_t encoding_length = pm_options_read_u32(data); + data += 4; + + if (encoding_length > 0) { + pm_string_constant_init(&options->encoding, data, encoding_length); + data += encoding_length; + } + + options->frozen_string_literal = (int8_t) *data++; + options->command_line = (uint8_t) *data++; + options->version = (pm_options_version_t) *data++; + options->encoding_locked = ((uint8_t) *data++) > 0; + options->main_script = ((uint8_t) *data++) > 0; + options->partial_script = ((uint8_t) *data++) > 0; + options->freeze = ((uint8_t) *data++) > 0; + + uint32_t scopes_count = pm_options_read_u32(data); + data += 4; + + if (scopes_count > 0) { + if (!pm_options_scopes_init(options, scopes_count)) return; + + for (size_t scope_index = 0; scope_index < scopes_count; scope_index++) { + uint32_t locals_count = pm_options_read_u32(data); + data += 4; + + pm_options_scope_t *scope = &options->scopes[scope_index]; + if (!pm_options_scope_init(scope, locals_count)) { + pm_options_free(options); + return; + } + + uint8_t forwarding = (uint8_t) *data++; + pm_options_scope_forwarding_set(&options->scopes[scope_index], forwarding); + + for (size_t local_index = 0; local_index < locals_count; local_index++) { + uint32_t local_length = pm_options_read_u32(data); + data += 4; + + pm_string_constant_init(&scope->locals[local_index], data, local_length); + data += local_length; + } + } + } +} + +#if defined(__GNUC__) && (__GNUC__ >= 10) +#pragma GCC diagnostic pop +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/pack.c b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/pack.c new file mode 100644 index 00000000..1388ca8a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/pack.c @@ -0,0 +1,509 @@ +#include "prism/pack.h" + +// We optionally support parsing String#pack templates. For systems that don't +// want or need this functionality, it can be turned off with the +// PRISM_EXCLUDE_PACK define. +#ifdef PRISM_EXCLUDE_PACK + +void pm_pack_parse(void) {} + +#else + +#include +#include + +static uintmax_t +strtoumaxc(const char **format) { + uintmax_t value = 0; + while (**format >= '0' && **format <= '9') { + if (value > UINTMAX_MAX / 10) { + errno = ERANGE; + } + value = value * 10 + ((uintmax_t) (**format - '0')); + (*format)++; + } + return value; +} + +PRISM_EXPORTED_FUNCTION pm_pack_result +pm_pack_parse( + pm_pack_variant variant, + const char **format, + const char *format_end, + pm_pack_type *type, + pm_pack_signed *signed_type, + pm_pack_endian *endian, + pm_pack_size *size, + pm_pack_length_type *length_type, + uint64_t *length, + pm_pack_encoding *encoding +) { + if (*encoding == PM_PACK_ENCODING_START) { + *encoding = PM_PACK_ENCODING_US_ASCII; + } + + if (*format == format_end) { + *type = PM_PACK_END; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_ENDIAN_NA; + *size = PM_PACK_SIZE_NA; + *length_type = PM_PACK_LENGTH_NA; + return PM_PACK_OK; + } + + *length_type = PM_PACK_LENGTH_FIXED; + *length = 1; + bool length_changed_allowed = true; + + char directive = **format; + (*format)++; + switch (directive) { + case ' ': + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + *type = PM_PACK_SPACE; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_ENDIAN_NA; + *size = PM_PACK_SIZE_NA; + *length_type = PM_PACK_LENGTH_NA; + *length = 0; + return PM_PACK_OK; + case '#': + while ((*format < format_end) && (**format != '\n')) { + (*format)++; + } + *type = PM_PACK_COMMENT; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_ENDIAN_NA; + *size = PM_PACK_SIZE_NA; + *length_type = PM_PACK_LENGTH_NA; + *length = 0; + return PM_PACK_OK; + case 'C': + *type = PM_PACK_INTEGER; + *signed_type = PM_PACK_UNSIGNED; + *endian = PM_PACK_AGNOSTIC_ENDIAN; + *size = PM_PACK_SIZE_8; + break; + case 'S': + *type = PM_PACK_INTEGER; + *signed_type = PM_PACK_UNSIGNED; + *endian = PM_PACK_NATIVE_ENDIAN; + *size = PM_PACK_SIZE_16; + break; + case 'L': + *type = PM_PACK_INTEGER; + *signed_type = PM_PACK_UNSIGNED; + *endian = PM_PACK_NATIVE_ENDIAN; + *size = PM_PACK_SIZE_32; + break; + case 'Q': + *type = PM_PACK_INTEGER; + *signed_type = PM_PACK_UNSIGNED; + *endian = PM_PACK_NATIVE_ENDIAN; + *size = PM_PACK_SIZE_64; + break; + case 'J': + *type = PM_PACK_INTEGER; + *signed_type = PM_PACK_UNSIGNED; + *endian = PM_PACK_NATIVE_ENDIAN; + *size = PM_PACK_SIZE_P; + break; + case 'c': + *type = PM_PACK_INTEGER; + *signed_type = PM_PACK_SIGNED; + *endian = PM_PACK_AGNOSTIC_ENDIAN; + *size = PM_PACK_SIZE_8; + break; + case 's': + *type = PM_PACK_INTEGER; + *signed_type = PM_PACK_SIGNED; + *endian = PM_PACK_NATIVE_ENDIAN; + *size = PM_PACK_SIZE_16; + break; + case 'l': + *type = PM_PACK_INTEGER; + *signed_type = PM_PACK_SIGNED; + *endian = PM_PACK_NATIVE_ENDIAN; + *size = PM_PACK_SIZE_32; + break; + case 'q': + *type = PM_PACK_INTEGER; + *signed_type = PM_PACK_SIGNED; + *endian = PM_PACK_NATIVE_ENDIAN; + *size = PM_PACK_SIZE_64; + break; + case 'j': + *type = PM_PACK_INTEGER; + *signed_type = PM_PACK_SIGNED; + *endian = PM_PACK_NATIVE_ENDIAN; + *size = PM_PACK_SIZE_P; + break; + case 'I': + *type = PM_PACK_INTEGER; + *signed_type = PM_PACK_UNSIGNED; + *endian = PM_PACK_NATIVE_ENDIAN; + *size = PM_PACK_SIZE_INT; + break; + case 'i': + *type = PM_PACK_INTEGER; + *signed_type = PM_PACK_SIGNED; + *endian = PM_PACK_NATIVE_ENDIAN; + *size = PM_PACK_SIZE_INT; + break; + case 'n': + *type = PM_PACK_INTEGER; + *signed_type = PM_PACK_UNSIGNED; + *endian = PM_PACK_BIG_ENDIAN; + *size = PM_PACK_SIZE_16; + length_changed_allowed = false; + break; + case 'N': + *type = PM_PACK_INTEGER; + *signed_type = PM_PACK_UNSIGNED; + *endian = PM_PACK_BIG_ENDIAN; + *size = PM_PACK_SIZE_32; + length_changed_allowed = false; + break; + case 'v': + *type = PM_PACK_INTEGER; + *signed_type = PM_PACK_UNSIGNED; + *endian = PM_PACK_LITTLE_ENDIAN; + *size = PM_PACK_SIZE_16; + length_changed_allowed = false; + break; + case 'V': + *type = PM_PACK_INTEGER; + *signed_type = PM_PACK_UNSIGNED; + *endian = PM_PACK_LITTLE_ENDIAN; + *size = PM_PACK_SIZE_32; + length_changed_allowed = false; + break; + case 'U': + *type = PM_PACK_UTF8; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_ENDIAN_NA; + *size = PM_PACK_SIZE_NA; + break; + case 'w': + *type = PM_PACK_BER; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_ENDIAN_NA; + *size = PM_PACK_SIZE_NA; + break; + case 'D': + case 'd': + *type = PM_PACK_FLOAT; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_NATIVE_ENDIAN; + *size = PM_PACK_SIZE_64; + break; + case 'F': + case 'f': + *type = PM_PACK_FLOAT; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_NATIVE_ENDIAN; + *size = PM_PACK_SIZE_32; + break; + case 'E': + *type = PM_PACK_FLOAT; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_LITTLE_ENDIAN; + *size = PM_PACK_SIZE_64; + break; + case 'e': + *type = PM_PACK_FLOAT; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_LITTLE_ENDIAN; + *size = PM_PACK_SIZE_32; + break; + case 'G': + *type = PM_PACK_FLOAT; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_BIG_ENDIAN; + *size = PM_PACK_SIZE_64; + break; + case 'g': + *type = PM_PACK_FLOAT; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_BIG_ENDIAN; + *size = PM_PACK_SIZE_32; + break; + case 'A': + *type = PM_PACK_STRING_SPACE_PADDED; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_ENDIAN_NA; + *size = PM_PACK_SIZE_NA; + break; + case 'a': + *type = PM_PACK_STRING_NULL_PADDED; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_ENDIAN_NA; + *size = PM_PACK_SIZE_NA; + break; + case 'Z': + *type = PM_PACK_STRING_NULL_TERMINATED; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_ENDIAN_NA; + *size = PM_PACK_SIZE_NA; + break; + case 'B': + *type = PM_PACK_STRING_MSB; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_ENDIAN_NA; + *size = PM_PACK_SIZE_NA; + break; + case 'b': + *type = PM_PACK_STRING_LSB; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_ENDIAN_NA; + *size = PM_PACK_SIZE_NA; + break; + case 'H': + *type = PM_PACK_STRING_HEX_HIGH; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_ENDIAN_NA; + *size = PM_PACK_SIZE_NA; + break; + case 'h': + *type = PM_PACK_STRING_HEX_LOW; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_ENDIAN_NA; + *size = PM_PACK_SIZE_NA; + break; + case 'u': + *type = PM_PACK_STRING_UU; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_ENDIAN_NA; + *size = PM_PACK_SIZE_NA; + break; + case 'M': + *type = PM_PACK_STRING_MIME; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_ENDIAN_NA; + *size = PM_PACK_SIZE_NA; + break; + case 'm': + *type = PM_PACK_STRING_BASE64; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_ENDIAN_NA; + *size = PM_PACK_SIZE_NA; + break; + case 'P': + *type = PM_PACK_STRING_FIXED; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_ENDIAN_NA; + *size = PM_PACK_SIZE_NA; + break; + case 'p': + *type = PM_PACK_STRING_POINTER; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_ENDIAN_NA; + *size = PM_PACK_SIZE_NA; + break; + case '@': + *type = PM_PACK_MOVE; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_ENDIAN_NA; + *size = PM_PACK_SIZE_NA; + break; + case 'X': + *type = PM_PACK_BACK; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_ENDIAN_NA; + *size = PM_PACK_SIZE_NA; + break; + case 'x': + *type = PM_PACK_NULL; + *signed_type = PM_PACK_SIGNED_NA; + *endian = PM_PACK_ENDIAN_NA; + *size = PM_PACK_SIZE_NA; + break; + case '%': + return PM_PACK_ERROR_UNSUPPORTED_DIRECTIVE; + default: + return PM_PACK_ERROR_UNKNOWN_DIRECTIVE; + } + + bool explicit_endian = false; + + while (*format < format_end) { + switch (**format) { + case '_': + case '!': + (*format)++; + if (*type != PM_PACK_INTEGER || !length_changed_allowed) { + return PM_PACK_ERROR_BANG_NOT_ALLOWED; + } + switch (*size) { + case PM_PACK_SIZE_SHORT: + case PM_PACK_SIZE_INT: + case PM_PACK_SIZE_LONG: + case PM_PACK_SIZE_LONG_LONG: + break; + case PM_PACK_SIZE_16: + *size = PM_PACK_SIZE_SHORT; + break; + case PM_PACK_SIZE_32: + *size = PM_PACK_SIZE_LONG; + break; + case PM_PACK_SIZE_64: + *size = PM_PACK_SIZE_LONG_LONG; + break; + case PM_PACK_SIZE_P: + break; + default: + return PM_PACK_ERROR_BANG_NOT_ALLOWED; + } + break; + case '<': + (*format)++; + if (explicit_endian) { + return PM_PACK_ERROR_DOUBLE_ENDIAN; + } + *endian = PM_PACK_LITTLE_ENDIAN; + explicit_endian = true; + break; + case '>': + (*format)++; + if (explicit_endian) { + return PM_PACK_ERROR_DOUBLE_ENDIAN; + } + *endian = PM_PACK_BIG_ENDIAN; + explicit_endian = true; + break; + default: + goto exit_modifier_loop; + } + } + +exit_modifier_loop: + + if (variant == PM_PACK_VARIANT_UNPACK && *type == PM_PACK_MOVE) { + *length = 0; + } + + if (*format < format_end) { + if (**format == '*') { + switch (*type) { + case PM_PACK_NULL: + case PM_PACK_BACK: + switch (variant) { + case PM_PACK_VARIANT_PACK: + *length_type = PM_PACK_LENGTH_FIXED; + break; + case PM_PACK_VARIANT_UNPACK: + *length_type = PM_PACK_LENGTH_MAX; + break; + } + *length = 0; + break; + + case PM_PACK_MOVE: + switch (variant) { + case PM_PACK_VARIANT_PACK: + *length_type = PM_PACK_LENGTH_FIXED; + break; + case PM_PACK_VARIANT_UNPACK: + *length_type = PM_PACK_LENGTH_RELATIVE; + break; + } + *length = 0; + break; + + case PM_PACK_STRING_UU: + *length_type = PM_PACK_LENGTH_FIXED; + *length = 0; + break; + + case PM_PACK_STRING_FIXED: + switch (variant) { + case PM_PACK_VARIANT_PACK: + *length_type = PM_PACK_LENGTH_FIXED; + *length = 1; + break; + case PM_PACK_VARIANT_UNPACK: + *length_type = PM_PACK_LENGTH_MAX; + *length = 0; + break; + } + break; + + case PM_PACK_STRING_MIME: + case PM_PACK_STRING_BASE64: + *length_type = PM_PACK_LENGTH_FIXED; + *length = 1; + break; + + default: + *length_type = PM_PACK_LENGTH_MAX; + *length = 0; + break; + } + + (*format)++; + } else if (**format >= '0' && **format <= '9') { + errno = 0; + *length_type = PM_PACK_LENGTH_FIXED; + #if UINTMAX_MAX < UINT64_MAX + #error "prism's design assumes uintmax_t is at least as large as uint64_t" + #endif + uintmax_t length_max = strtoumaxc(format); + if (errno || length_max > UINT64_MAX) { + return PM_PACK_ERROR_LENGTH_TOO_BIG; + } + *length = (uint64_t) length_max; + } + } + + switch (*type) { + case PM_PACK_UTF8: + /* if encoding is US-ASCII, upgrade to UTF-8 */ + if (*encoding == PM_PACK_ENCODING_US_ASCII) { + *encoding = PM_PACK_ENCODING_UTF_8; + } + break; + case PM_PACK_STRING_MIME: + case PM_PACK_STRING_BASE64: + case PM_PACK_STRING_UU: + /* keep US-ASCII (do nothing) */ + break; + default: + /* fall back to BINARY */ + *encoding = PM_PACK_ENCODING_ASCII_8BIT; + break; + } + + return PM_PACK_OK; +} + +PRISM_EXPORTED_FUNCTION size_t +pm_size_to_native(pm_pack_size size) { + switch (size) { + case PM_PACK_SIZE_SHORT: + return sizeof(short); + case PM_PACK_SIZE_INT: + return sizeof(int); + case PM_PACK_SIZE_LONG: + return sizeof(long); + case PM_PACK_SIZE_LONG_LONG: + return sizeof(long long); + case PM_PACK_SIZE_8: + return 1; + case PM_PACK_SIZE_16: + return 2; + case PM_PACK_SIZE_32: + return 4; + case PM_PACK_SIZE_64: + return 8; + case PM_PACK_SIZE_P: + return sizeof(void *); + default: + return 0; + } +} + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/prettyprint.c b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/prettyprint.c new file mode 100644 index 00000000..d3224004 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/prettyprint.c @@ -0,0 +1,8939 @@ +/*----------------------------------------------------------------------------*/ +/* This file is generated by the templates/template.rb script and should not */ +/* be modified manually. See */ +/* templates/src/prettyprint.c.erb */ +/* if you are looking to modify the */ +/* template */ +/*----------------------------------------------------------------------------*/ + +#include "prism/prettyprint.h" + +// We optionally support pretty printing nodes. For systems that don't want or +// need this functionality, it can be turned off with the +// PRISM_EXCLUDE_PRETTYPRINT define. +#ifdef PRISM_EXCLUDE_PRETTYPRINT + +void pm_prettyprint(void) {} + +#else + +static inline void +prettyprint_location(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_location_t *location) { + pm_line_column_t start = pm_newline_list_line_column(&parser->newline_list, location->start, parser->start_line); + pm_line_column_t end = pm_newline_list_line_column(&parser->newline_list, location->end, parser->start_line); + pm_buffer_append_format(output_buffer, "(%" PRIi32 ",%" PRIu32 ")-(%" PRIi32 ",%" PRIu32 ")", start.line, start.column, end.line, end.column); +} + +static inline void +prettyprint_constant(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_constant_id_t constant_id) { + pm_constant_t *constant = pm_constant_pool_id_to_constant(&parser->constant_pool, constant_id); + pm_buffer_append_format(output_buffer, ":%.*s", (int) constant->length, constant->start); +} + +static void +prettyprint_node(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_node_t *node, pm_buffer_t *prefix_buffer) { + switch (PM_NODE_TYPE(node)) { + case PM_SCOPE_NODE: + // We do not need to print a ScopeNode as it's not part of the AST. + return; + case PM_ALIAS_GLOBAL_VARIABLE_NODE: { + pm_alias_global_variable_node_t *cast = (pm_alias_global_variable_node_t *) node; + pm_buffer_append_string(output_buffer, "@ AliasGlobalVariableNode (location: ", 37); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // new_name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- new_name:", 13); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->new_name, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // old_name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- old_name:", 13); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->old_name, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- keyword_loc:", 16); + pm_location_t *location = &cast->keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_ALIAS_METHOD_NODE: { + pm_alias_method_node_t *cast = (pm_alias_method_node_t *) node; + pm_buffer_append_string(output_buffer, "@ AliasMethodNode (location: ", 29); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // new_name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- new_name:", 13); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->new_name, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // old_name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- old_name:", 13); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->old_name, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- keyword_loc:", 16); + pm_location_t *location = &cast->keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_ALTERNATION_PATTERN_NODE: { + pm_alternation_pattern_node_t *cast = (pm_alternation_pattern_node_t *) node; + pm_buffer_append_string(output_buffer, "@ AlternationPatternNode (location: ", 36); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // left + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- left:", 9); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->left, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // right + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- right:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->right, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_AND_NODE: { + pm_and_node_t *cast = (pm_and_node_t *) node; + pm_buffer_append_string(output_buffer, "@ AndNode (location: ", 21); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // left + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- left:", 9); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->left, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // right + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- right:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->right, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_ARGUMENTS_NODE: { + pm_arguments_node_t *cast = (pm_arguments_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ArgumentsNode (location: ", 27); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // ArgumentsNodeFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ArgumentsNodeFlags:", 23); + bool found = false; + if (cast->base.flags & PM_ARGUMENTS_NODE_FLAGS_CONTAINS_FORWARDING) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " contains_forwarding", 20); + found = true; + } + if (cast->base.flags & PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORDS) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " contains_keywords", 18); + found = true; + } + if (cast->base.flags & PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORD_SPLAT) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " contains_keyword_splat", 23); + found = true; + } + if (cast->base.flags & PM_ARGUMENTS_NODE_FLAGS_CONTAINS_SPLAT) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " contains_splat", 15); + found = true; + } + if (cast->base.flags & PM_ARGUMENTS_NODE_FLAGS_CONTAINS_MULTIPLE_SPLATS) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " contains_multiple_splats", 25); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // arguments + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- arguments:", 14); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->arguments.size)); + + size_t last_index = cast->arguments.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->arguments.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + break; + } + case PM_ARRAY_NODE: { + pm_array_node_t *cast = (pm_array_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ArrayNode (location: ", 23); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // ArrayNodeFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ArrayNodeFlags:", 19); + bool found = false; + if (cast->base.flags & PM_ARRAY_NODE_FLAGS_CONTAINS_SPLAT) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " contains_splat", 15); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // elements + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- elements:", 13); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->elements.size)); + + size_t last_index = cast->elements.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->elements.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + break; + } + case PM_ARRAY_PATTERN_NODE: { + pm_array_pattern_node_t *cast = (pm_array_pattern_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ArrayPatternNode (location: ", 30); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // constant + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- constant:", 13); + if (cast->constant == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->constant, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // requireds + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- requireds:", 14); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->requireds.size)); + + size_t last_index = cast->requireds.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->requireds.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // rest + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- rest:", 9); + if (cast->rest == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->rest, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // posts + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- posts:", 10); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->posts.size)); + + size_t last_index = cast->posts.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->posts.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + break; + } + case PM_ASSOC_NODE: { + pm_assoc_node_t *cast = (pm_assoc_node_t *) node; + pm_buffer_append_string(output_buffer, "@ AssocNode (location: ", 23); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // key + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- key:", 8); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->key, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + break; + } + case PM_ASSOC_SPLAT_NODE: { + pm_assoc_splat_node_t *cast = (pm_assoc_splat_node_t *) node; + pm_buffer_append_string(output_buffer, "@ AssocSplatNode (location: ", 28); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + if (cast->value == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_BACK_REFERENCE_READ_NODE: { + pm_back_reference_read_node_t *cast = (pm_back_reference_read_node_t *) node; + pm_buffer_append_string(output_buffer, "@ BackReferenceReadNode (location: ", 35); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + break; + } + case PM_BEGIN_NODE: { + pm_begin_node_t *cast = (pm_begin_node_t *) node; + pm_buffer_append_string(output_buffer, "@ BeginNode (location: ", 23); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // begin_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- begin_keyword_loc:", 22); + pm_location_t *location = &cast->begin_keyword_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // statements + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- statements:", 15); + if (cast->statements == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // rescue_clause + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- rescue_clause:", 18); + if (cast->rescue_clause == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->rescue_clause, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // else_clause + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- else_clause:", 16); + if (cast->else_clause == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->else_clause, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // ensure_clause + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ensure_clause:", 18); + if (cast->ensure_clause == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->ensure_clause, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // end_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- end_keyword_loc:", 20); + pm_location_t *location = &cast->end_keyword_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + break; + } + case PM_BLOCK_ARGUMENT_NODE: { + pm_block_argument_node_t *cast = (pm_block_argument_node_t *) node; + pm_buffer_append_string(output_buffer, "@ BlockArgumentNode (location: ", 31); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // expression + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- expression:", 15); + if (cast->expression == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->expression, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_BLOCK_LOCAL_VARIABLE_NODE: { + pm_block_local_variable_node_t *cast = (pm_block_local_variable_node_t *) node; + pm_buffer_append_string(output_buffer, "@ BlockLocalVariableNode (location: ", 36); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // ParameterFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ParameterFlags:", 19); + bool found = false; + if (cast->base.flags & PM_PARAMETER_FLAGS_REPEATED_PARAMETER) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " repeated_parameter", 19); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + break; + } + case PM_BLOCK_NODE: { + pm_block_node_t *cast = (pm_block_node_t *) node; + pm_buffer_append_string(output_buffer, "@ BlockNode (location: ", 23); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // locals + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- locals:", 11); + pm_buffer_append_string(output_buffer, " [", 2); + for (uint32_t index = 0; index < cast->locals.size; index++) { + if (index != 0) pm_buffer_append_string(output_buffer, ", ", 2); + prettyprint_constant(output_buffer, parser, cast->locals.ids[index]); + } + pm_buffer_append_string(output_buffer, "]\n", 2); + } + + // parameters + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- parameters:", 15); + if (cast->parameters == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->parameters, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // body + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- body:", 9); + if (cast->body == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->body, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_BLOCK_PARAMETER_NODE: { + pm_block_parameter_node_t *cast = (pm_block_parameter_node_t *) node; + pm_buffer_append_string(output_buffer, "@ BlockParameterNode (location: ", 32); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // ParameterFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ParameterFlags:", 19); + bool found = false; + if (cast->base.flags & PM_PARAMETER_FLAGS_REPEATED_PARAMETER) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " repeated_parameter", 19); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + if (cast->name == 0) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_BLOCK_PARAMETERS_NODE: { + pm_block_parameters_node_t *cast = (pm_block_parameters_node_t *) node; + pm_buffer_append_string(output_buffer, "@ BlockParametersNode (location: ", 33); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // parameters + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- parameters:", 15); + if (cast->parameters == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->parameters, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // locals + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- locals:", 11); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->locals.size)); + + size_t last_index = cast->locals.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->locals.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + break; + } + case PM_BREAK_NODE: { + pm_break_node_t *cast = (pm_break_node_t *) node; + pm_buffer_append_string(output_buffer, "@ BreakNode (location: ", 23); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // arguments + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- arguments:", 14); + if (cast->arguments == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->arguments, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- keyword_loc:", 16); + pm_location_t *location = &cast->keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_CALL_AND_WRITE_NODE: { + pm_call_and_write_node_t *cast = (pm_call_and_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ CallAndWriteNode (location: ", 30); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // CallNodeFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- CallNodeFlags:", 18); + bool found = false; + if (cast->base.flags & PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " safe_navigation", 16); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_VARIABLE_CALL) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " variable_call", 14); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " attribute_write", 16); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " ignore_visibility", 18); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // receiver + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- receiver:", 13); + if (cast->receiver == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->receiver, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // call_operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- call_operator_loc:", 22); + pm_location_t *location = &cast->call_operator_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // message_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- message_loc:", 16); + pm_location_t *location = &cast->message_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // read_name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- read_name:", 14); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->read_name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // write_name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- write_name:", 15); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->write_name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_CALL_NODE: { + pm_call_node_t *cast = (pm_call_node_t *) node; + pm_buffer_append_string(output_buffer, "@ CallNode (location: ", 22); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // CallNodeFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- CallNodeFlags:", 18); + bool found = false; + if (cast->base.flags & PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " safe_navigation", 16); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_VARIABLE_CALL) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " variable_call", 14); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " attribute_write", 16); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " ignore_visibility", 18); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // receiver + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- receiver:", 13); + if (cast->receiver == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->receiver, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // call_operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- call_operator_loc:", 22); + pm_location_t *location = &cast->call_operator_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // message_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- message_loc:", 16); + pm_location_t *location = &cast->message_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // arguments + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- arguments:", 14); + if (cast->arguments == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->arguments, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // block + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- block:", 10); + if (cast->block == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->block, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + break; + } + case PM_CALL_OPERATOR_WRITE_NODE: { + pm_call_operator_write_node_t *cast = (pm_call_operator_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ CallOperatorWriteNode (location: ", 35); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // CallNodeFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- CallNodeFlags:", 18); + bool found = false; + if (cast->base.flags & PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " safe_navigation", 16); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_VARIABLE_CALL) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " variable_call", 14); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " attribute_write", 16); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " ignore_visibility", 18); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // receiver + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- receiver:", 13); + if (cast->receiver == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->receiver, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // call_operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- call_operator_loc:", 22); + pm_location_t *location = &cast->call_operator_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // message_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- message_loc:", 16); + pm_location_t *location = &cast->message_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // read_name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- read_name:", 14); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->read_name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // write_name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- write_name:", 15); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->write_name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // binary_operator + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- binary_operator:", 20); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->binary_operator); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // binary_operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- binary_operator_loc:", 24); + pm_location_t *location = &cast->binary_operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_CALL_OR_WRITE_NODE: { + pm_call_or_write_node_t *cast = (pm_call_or_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ CallOrWriteNode (location: ", 29); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // CallNodeFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- CallNodeFlags:", 18); + bool found = false; + if (cast->base.flags & PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " safe_navigation", 16); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_VARIABLE_CALL) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " variable_call", 14); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " attribute_write", 16); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " ignore_visibility", 18); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // receiver + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- receiver:", 13); + if (cast->receiver == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->receiver, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // call_operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- call_operator_loc:", 22); + pm_location_t *location = &cast->call_operator_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // message_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- message_loc:", 16); + pm_location_t *location = &cast->message_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // read_name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- read_name:", 14); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->read_name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // write_name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- write_name:", 15); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->write_name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_CALL_TARGET_NODE: { + pm_call_target_node_t *cast = (pm_call_target_node_t *) node; + pm_buffer_append_string(output_buffer, "@ CallTargetNode (location: ", 28); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // CallNodeFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- CallNodeFlags:", 18); + bool found = false; + if (cast->base.flags & PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " safe_navigation", 16); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_VARIABLE_CALL) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " variable_call", 14); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " attribute_write", 16); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " ignore_visibility", 18); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // receiver + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- receiver:", 13); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->receiver, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // call_operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- call_operator_loc:", 22); + pm_location_t *location = &cast->call_operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // message_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- message_loc:", 16); + pm_location_t *location = &cast->message_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_CAPTURE_PATTERN_NODE: { + pm_capture_pattern_node_t *cast = (pm_capture_pattern_node_t *) node; + pm_buffer_append_string(output_buffer, "@ CapturePatternNode (location: ", 32); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // target + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- target:", 11); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->target, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_CASE_MATCH_NODE: { + pm_case_match_node_t *cast = (pm_case_match_node_t *) node; + pm_buffer_append_string(output_buffer, "@ CaseMatchNode (location: ", 27); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // predicate + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- predicate:", 14); + if (cast->predicate == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->predicate, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // conditions + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- conditions:", 15); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->conditions.size)); + + size_t last_index = cast->conditions.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->conditions.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // else_clause + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- else_clause:", 16); + if (cast->else_clause == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->else_clause, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // case_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- case_keyword_loc:", 21); + pm_location_t *location = &cast->case_keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // end_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- end_keyword_loc:", 20); + pm_location_t *location = &cast->end_keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_CASE_NODE: { + pm_case_node_t *cast = (pm_case_node_t *) node; + pm_buffer_append_string(output_buffer, "@ CaseNode (location: ", 22); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // predicate + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- predicate:", 14); + if (cast->predicate == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->predicate, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // conditions + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- conditions:", 15); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->conditions.size)); + + size_t last_index = cast->conditions.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->conditions.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // else_clause + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- else_clause:", 16); + if (cast->else_clause == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->else_clause, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // case_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- case_keyword_loc:", 21); + pm_location_t *location = &cast->case_keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // end_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- end_keyword_loc:", 20); + pm_location_t *location = &cast->end_keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_CLASS_NODE: { + pm_class_node_t *cast = (pm_class_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ClassNode (location: ", 23); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // locals + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- locals:", 11); + pm_buffer_append_string(output_buffer, " [", 2); + for (uint32_t index = 0; index < cast->locals.size; index++) { + if (index != 0) pm_buffer_append_string(output_buffer, ", ", 2); + prettyprint_constant(output_buffer, parser, cast->locals.ids[index]); + } + pm_buffer_append_string(output_buffer, "]\n", 2); + } + + // class_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- class_keyword_loc:", 22); + pm_location_t *location = &cast->class_keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // constant_path + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- constant_path:", 18); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->constant_path, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // inheritance_operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- inheritance_operator_loc:", 29); + pm_location_t *location = &cast->inheritance_operator_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // superclass + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- superclass:", 15); + if (cast->superclass == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->superclass, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // body + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- body:", 9); + if (cast->body == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->body, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // end_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- end_keyword_loc:", 20); + pm_location_t *location = &cast->end_keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + break; + } + case PM_CLASS_VARIABLE_AND_WRITE_NODE: { + pm_class_variable_and_write_node_t *cast = (pm_class_variable_and_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ClassVariableAndWriteNode (location: ", 39); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE: { + pm_class_variable_operator_write_node_t *cast = (pm_class_variable_operator_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ClassVariableOperatorWriteNode (location: ", 44); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // binary_operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- binary_operator_loc:", 24); + pm_location_t *location = &cast->binary_operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // binary_operator + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- binary_operator:", 20); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->binary_operator); + pm_buffer_append_byte(output_buffer, '\n'); + } + + break; + } + case PM_CLASS_VARIABLE_OR_WRITE_NODE: { + pm_class_variable_or_write_node_t *cast = (pm_class_variable_or_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ClassVariableOrWriteNode (location: ", 38); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_CLASS_VARIABLE_READ_NODE: { + pm_class_variable_read_node_t *cast = (pm_class_variable_read_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ClassVariableReadNode (location: ", 35); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + break; + } + case PM_CLASS_VARIABLE_TARGET_NODE: { + pm_class_variable_target_node_t *cast = (pm_class_variable_target_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ClassVariableTargetNode (location: ", 37); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + break; + } + case PM_CLASS_VARIABLE_WRITE_NODE: { + pm_class_variable_write_node_t *cast = (pm_class_variable_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ClassVariableWriteNode (location: ", 36); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_CONSTANT_AND_WRITE_NODE: { + pm_constant_and_write_node_t *cast = (pm_constant_and_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ConstantAndWriteNode (location: ", 34); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_CONSTANT_OPERATOR_WRITE_NODE: { + pm_constant_operator_write_node_t *cast = (pm_constant_operator_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ConstantOperatorWriteNode (location: ", 39); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // binary_operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- binary_operator_loc:", 24); + pm_location_t *location = &cast->binary_operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // binary_operator + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- binary_operator:", 20); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->binary_operator); + pm_buffer_append_byte(output_buffer, '\n'); + } + + break; + } + case PM_CONSTANT_OR_WRITE_NODE: { + pm_constant_or_write_node_t *cast = (pm_constant_or_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ConstantOrWriteNode (location: ", 33); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_CONSTANT_PATH_AND_WRITE_NODE: { + pm_constant_path_and_write_node_t *cast = (pm_constant_path_and_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ConstantPathAndWriteNode (location: ", 38); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // target + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- target:", 11); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->target, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_CONSTANT_PATH_NODE: { + pm_constant_path_node_t *cast = (pm_constant_path_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ConstantPathNode (location: ", 30); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // parent + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- parent:", 11); + if (cast->parent == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->parent, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + if (cast->name == 0) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + } + + // delimiter_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- delimiter_loc:", 18); + pm_location_t *location = &cast->delimiter_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_CONSTANT_PATH_OPERATOR_WRITE_NODE: { + pm_constant_path_operator_write_node_t *cast = (pm_constant_path_operator_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ConstantPathOperatorWriteNode (location: ", 43); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // target + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- target:", 11); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->target, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // binary_operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- binary_operator_loc:", 24); + pm_location_t *location = &cast->binary_operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // binary_operator + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- binary_operator:", 20); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->binary_operator); + pm_buffer_append_byte(output_buffer, '\n'); + } + + break; + } + case PM_CONSTANT_PATH_OR_WRITE_NODE: { + pm_constant_path_or_write_node_t *cast = (pm_constant_path_or_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ConstantPathOrWriteNode (location: ", 37); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // target + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- target:", 11); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->target, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_CONSTANT_PATH_TARGET_NODE: { + pm_constant_path_target_node_t *cast = (pm_constant_path_target_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ConstantPathTargetNode (location: ", 36); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // parent + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- parent:", 11); + if (cast->parent == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->parent, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + if (cast->name == 0) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + } + + // delimiter_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- delimiter_loc:", 18); + pm_location_t *location = &cast->delimiter_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_CONSTANT_PATH_WRITE_NODE: { + pm_constant_path_write_node_t *cast = (pm_constant_path_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ConstantPathWriteNode (location: ", 35); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // target + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- target:", 11); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->target, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_CONSTANT_READ_NODE: { + pm_constant_read_node_t *cast = (pm_constant_read_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ConstantReadNode (location: ", 30); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + break; + } + case PM_CONSTANT_TARGET_NODE: { + pm_constant_target_node_t *cast = (pm_constant_target_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ConstantTargetNode (location: ", 32); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + break; + } + case PM_CONSTANT_WRITE_NODE: { + pm_constant_write_node_t *cast = (pm_constant_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ConstantWriteNode (location: ", 31); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_DEF_NODE: { + pm_def_node_t *cast = (pm_def_node_t *) node; + pm_buffer_append_string(output_buffer, "@ DefNode (location: ", 21); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // receiver + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- receiver:", 13); + if (cast->receiver == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->receiver, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // parameters + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- parameters:", 15); + if (cast->parameters == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->parameters, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // body + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- body:", 9); + if (cast->body == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->body, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // locals + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- locals:", 11); + pm_buffer_append_string(output_buffer, " [", 2); + for (uint32_t index = 0; index < cast->locals.size; index++) { + if (index != 0) pm_buffer_append_string(output_buffer, ", ", 2); + prettyprint_constant(output_buffer, parser, cast->locals.ids[index]); + } + pm_buffer_append_string(output_buffer, "]\n", 2); + } + + // def_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- def_keyword_loc:", 20); + pm_location_t *location = &cast->def_keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // lparen_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- lparen_loc:", 15); + pm_location_t *location = &cast->lparen_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // rparen_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- rparen_loc:", 15); + pm_location_t *location = &cast->rparen_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // equal_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- equal_loc:", 14); + pm_location_t *location = &cast->equal_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // end_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- end_keyword_loc:", 20); + pm_location_t *location = &cast->end_keyword_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + break; + } + case PM_DEFINED_NODE: { + pm_defined_node_t *cast = (pm_defined_node_t *) node; + pm_buffer_append_string(output_buffer, "@ DefinedNode (location: ", 25); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // lparen_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- lparen_loc:", 15); + pm_location_t *location = &cast->lparen_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // rparen_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- rparen_loc:", 15); + pm_location_t *location = &cast->rparen_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- keyword_loc:", 16); + pm_location_t *location = &cast->keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_ELSE_NODE: { + pm_else_node_t *cast = (pm_else_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ElseNode (location: ", 22); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // else_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- else_keyword_loc:", 21); + pm_location_t *location = &cast->else_keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // statements + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- statements:", 15); + if (cast->statements == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // end_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- end_keyword_loc:", 20); + pm_location_t *location = &cast->end_keyword_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + break; + } + case PM_EMBEDDED_STATEMENTS_NODE: { + pm_embedded_statements_node_t *cast = (pm_embedded_statements_node_t *) node; + pm_buffer_append_string(output_buffer, "@ EmbeddedStatementsNode (location: ", 36); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // statements + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- statements:", 15); + if (cast->statements == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_EMBEDDED_VARIABLE_NODE: { + pm_embedded_variable_node_t *cast = (pm_embedded_variable_node_t *) node; + pm_buffer_append_string(output_buffer, "@ EmbeddedVariableNode (location: ", 34); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // variable + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- variable:", 13); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->variable, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_ENSURE_NODE: { + pm_ensure_node_t *cast = (pm_ensure_node_t *) node; + pm_buffer_append_string(output_buffer, "@ EnsureNode (location: ", 24); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // ensure_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ensure_keyword_loc:", 23); + pm_location_t *location = &cast->ensure_keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // statements + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- statements:", 15); + if (cast->statements == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // end_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- end_keyword_loc:", 20); + pm_location_t *location = &cast->end_keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_FALSE_NODE: { + pm_buffer_append_string(output_buffer, "@ FalseNode (location: ", 23); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + break; + } + case PM_FIND_PATTERN_NODE: { + pm_find_pattern_node_t *cast = (pm_find_pattern_node_t *) node; + pm_buffer_append_string(output_buffer, "@ FindPatternNode (location: ", 29); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // constant + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- constant:", 13); + if (cast->constant == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->constant, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // left + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- left:", 9); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->left, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // requireds + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- requireds:", 14); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->requireds.size)); + + size_t last_index = cast->requireds.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->requireds.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // right + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- right:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->right, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + break; + } + case PM_FLIP_FLOP_NODE: { + pm_flip_flop_node_t *cast = (pm_flip_flop_node_t *) node; + pm_buffer_append_string(output_buffer, "@ FlipFlopNode (location: ", 26); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // RangeFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- RangeFlags:", 15); + bool found = false; + if (cast->base.flags & PM_RANGE_FLAGS_EXCLUDE_END) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " exclude_end", 12); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // left + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- left:", 9); + if (cast->left == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->left, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // right + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- right:", 10); + if (cast->right == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->right, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_FLOAT_NODE: { + pm_float_node_t *cast = (pm_float_node_t *) node; + pm_buffer_append_string(output_buffer, "@ FloatNode (location: ", 23); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_format(output_buffer, " %f\n", cast->value); + } + + break; + } + case PM_FOR_NODE: { + pm_for_node_t *cast = (pm_for_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ForNode (location: ", 21); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // index + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- index:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->index, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // collection + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- collection:", 15); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->collection, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // statements + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- statements:", 15); + if (cast->statements == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // for_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- for_keyword_loc:", 20); + pm_location_t *location = &cast->for_keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // in_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- in_keyword_loc:", 19); + pm_location_t *location = &cast->in_keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // do_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- do_keyword_loc:", 19); + pm_location_t *location = &cast->do_keyword_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // end_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- end_keyword_loc:", 20); + pm_location_t *location = &cast->end_keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_FORWARDING_ARGUMENTS_NODE: { + pm_buffer_append_string(output_buffer, "@ ForwardingArgumentsNode (location: ", 37); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + break; + } + case PM_FORWARDING_PARAMETER_NODE: { + pm_buffer_append_string(output_buffer, "@ ForwardingParameterNode (location: ", 37); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + break; + } + case PM_FORWARDING_SUPER_NODE: { + pm_forwarding_super_node_t *cast = (pm_forwarding_super_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ForwardingSuperNode (location: ", 33); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // block + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- block:", 10); + if (cast->block == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->block, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + break; + } + case PM_GLOBAL_VARIABLE_AND_WRITE_NODE: { + pm_global_variable_and_write_node_t *cast = (pm_global_variable_and_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ GlobalVariableAndWriteNode (location: ", 40); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE: { + pm_global_variable_operator_write_node_t *cast = (pm_global_variable_operator_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ GlobalVariableOperatorWriteNode (location: ", 45); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // binary_operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- binary_operator_loc:", 24); + pm_location_t *location = &cast->binary_operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // binary_operator + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- binary_operator:", 20); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->binary_operator); + pm_buffer_append_byte(output_buffer, '\n'); + } + + break; + } + case PM_GLOBAL_VARIABLE_OR_WRITE_NODE: { + pm_global_variable_or_write_node_t *cast = (pm_global_variable_or_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ GlobalVariableOrWriteNode (location: ", 39); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_GLOBAL_VARIABLE_READ_NODE: { + pm_global_variable_read_node_t *cast = (pm_global_variable_read_node_t *) node; + pm_buffer_append_string(output_buffer, "@ GlobalVariableReadNode (location: ", 36); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + break; + } + case PM_GLOBAL_VARIABLE_TARGET_NODE: { + pm_global_variable_target_node_t *cast = (pm_global_variable_target_node_t *) node; + pm_buffer_append_string(output_buffer, "@ GlobalVariableTargetNode (location: ", 38); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + break; + } + case PM_GLOBAL_VARIABLE_WRITE_NODE: { + pm_global_variable_write_node_t *cast = (pm_global_variable_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ GlobalVariableWriteNode (location: ", 37); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_HASH_NODE: { + pm_hash_node_t *cast = (pm_hash_node_t *) node; + pm_buffer_append_string(output_buffer, "@ HashNode (location: ", 22); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // elements + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- elements:", 13); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->elements.size)); + + size_t last_index = cast->elements.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->elements.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_HASH_PATTERN_NODE: { + pm_hash_pattern_node_t *cast = (pm_hash_pattern_node_t *) node; + pm_buffer_append_string(output_buffer, "@ HashPatternNode (location: ", 29); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // constant + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- constant:", 13); + if (cast->constant == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->constant, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // elements + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- elements:", 13); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->elements.size)); + + size_t last_index = cast->elements.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->elements.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // rest + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- rest:", 9); + if (cast->rest == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->rest, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + break; + } + case PM_IF_NODE: { + pm_if_node_t *cast = (pm_if_node_t *) node; + pm_buffer_append_string(output_buffer, "@ IfNode (location: ", 20); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // if_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- if_keyword_loc:", 19); + pm_location_t *location = &cast->if_keyword_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // predicate + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- predicate:", 14); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->predicate, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // then_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- then_keyword_loc:", 21); + pm_location_t *location = &cast->then_keyword_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // statements + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- statements:", 15); + if (cast->statements == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // subsequent + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- subsequent:", 15); + if (cast->subsequent == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->subsequent, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // end_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- end_keyword_loc:", 20); + pm_location_t *location = &cast->end_keyword_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + break; + } + case PM_IMAGINARY_NODE: { + pm_imaginary_node_t *cast = (pm_imaginary_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ImaginaryNode (location: ", 27); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // numeric + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- numeric:", 12); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->numeric, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_IMPLICIT_NODE: { + pm_implicit_node_t *cast = (pm_implicit_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ImplicitNode (location: ", 26); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_IMPLICIT_REST_NODE: { + pm_buffer_append_string(output_buffer, "@ ImplicitRestNode (location: ", 30); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + break; + } + case PM_IN_NODE: { + pm_in_node_t *cast = (pm_in_node_t *) node; + pm_buffer_append_string(output_buffer, "@ InNode (location: ", 20); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // pattern + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- pattern:", 12); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->pattern, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // statements + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- statements:", 15); + if (cast->statements == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // in_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- in_loc:", 11); + pm_location_t *location = &cast->in_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // then_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- then_loc:", 13); + pm_location_t *location = &cast->then_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + break; + } + case PM_INDEX_AND_WRITE_NODE: { + pm_index_and_write_node_t *cast = (pm_index_and_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ IndexAndWriteNode (location: ", 31); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // CallNodeFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- CallNodeFlags:", 18); + bool found = false; + if (cast->base.flags & PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " safe_navigation", 16); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_VARIABLE_CALL) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " variable_call", 14); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " attribute_write", 16); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " ignore_visibility", 18); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // receiver + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- receiver:", 13); + if (cast->receiver == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->receiver, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // call_operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- call_operator_loc:", 22); + pm_location_t *location = &cast->call_operator_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // arguments + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- arguments:", 14); + if (cast->arguments == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->arguments, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // block + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- block:", 10); + if (cast->block == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->block, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_INDEX_OPERATOR_WRITE_NODE: { + pm_index_operator_write_node_t *cast = (pm_index_operator_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ IndexOperatorWriteNode (location: ", 36); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // CallNodeFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- CallNodeFlags:", 18); + bool found = false; + if (cast->base.flags & PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " safe_navigation", 16); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_VARIABLE_CALL) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " variable_call", 14); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " attribute_write", 16); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " ignore_visibility", 18); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // receiver + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- receiver:", 13); + if (cast->receiver == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->receiver, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // call_operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- call_operator_loc:", 22); + pm_location_t *location = &cast->call_operator_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // arguments + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- arguments:", 14); + if (cast->arguments == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->arguments, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // block + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- block:", 10); + if (cast->block == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->block, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // binary_operator + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- binary_operator:", 20); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->binary_operator); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // binary_operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- binary_operator_loc:", 24); + pm_location_t *location = &cast->binary_operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_INDEX_OR_WRITE_NODE: { + pm_index_or_write_node_t *cast = (pm_index_or_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ IndexOrWriteNode (location: ", 30); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // CallNodeFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- CallNodeFlags:", 18); + bool found = false; + if (cast->base.flags & PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " safe_navigation", 16); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_VARIABLE_CALL) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " variable_call", 14); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " attribute_write", 16); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " ignore_visibility", 18); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // receiver + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- receiver:", 13); + if (cast->receiver == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->receiver, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // call_operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- call_operator_loc:", 22); + pm_location_t *location = &cast->call_operator_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // arguments + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- arguments:", 14); + if (cast->arguments == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->arguments, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // block + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- block:", 10); + if (cast->block == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->block, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_INDEX_TARGET_NODE: { + pm_index_target_node_t *cast = (pm_index_target_node_t *) node; + pm_buffer_append_string(output_buffer, "@ IndexTargetNode (location: ", 29); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // CallNodeFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- CallNodeFlags:", 18); + bool found = false; + if (cast->base.flags & PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " safe_navigation", 16); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_VARIABLE_CALL) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " variable_call", 14); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " attribute_write", 16); + found = true; + } + if (cast->base.flags & PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " ignore_visibility", 18); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // receiver + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- receiver:", 13); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->receiver, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // arguments + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- arguments:", 14); + if (cast->arguments == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->arguments, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // block + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- block:", 10); + if (cast->block == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->block, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + break; + } + case PM_INSTANCE_VARIABLE_AND_WRITE_NODE: { + pm_instance_variable_and_write_node_t *cast = (pm_instance_variable_and_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ InstanceVariableAndWriteNode (location: ", 42); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE: { + pm_instance_variable_operator_write_node_t *cast = (pm_instance_variable_operator_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ InstanceVariableOperatorWriteNode (location: ", 47); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // binary_operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- binary_operator_loc:", 24); + pm_location_t *location = &cast->binary_operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // binary_operator + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- binary_operator:", 20); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->binary_operator); + pm_buffer_append_byte(output_buffer, '\n'); + } + + break; + } + case PM_INSTANCE_VARIABLE_OR_WRITE_NODE: { + pm_instance_variable_or_write_node_t *cast = (pm_instance_variable_or_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ InstanceVariableOrWriteNode (location: ", 41); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_INSTANCE_VARIABLE_READ_NODE: { + pm_instance_variable_read_node_t *cast = (pm_instance_variable_read_node_t *) node; + pm_buffer_append_string(output_buffer, "@ InstanceVariableReadNode (location: ", 38); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + break; + } + case PM_INSTANCE_VARIABLE_TARGET_NODE: { + pm_instance_variable_target_node_t *cast = (pm_instance_variable_target_node_t *) node; + pm_buffer_append_string(output_buffer, "@ InstanceVariableTargetNode (location: ", 40); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + break; + } + case PM_INSTANCE_VARIABLE_WRITE_NODE: { + pm_instance_variable_write_node_t *cast = (pm_instance_variable_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ InstanceVariableWriteNode (location: ", 39); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_INTEGER_NODE: { + pm_integer_node_t *cast = (pm_integer_node_t *) node; + pm_buffer_append_string(output_buffer, "@ IntegerNode (location: ", 25); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // IntegerBaseFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- IntegerBaseFlags:", 21); + bool found = false; + if (cast->base.flags & PM_INTEGER_BASE_FLAGS_BINARY) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " binary", 7); + found = true; + } + if (cast->base.flags & PM_INTEGER_BASE_FLAGS_DECIMAL) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " decimal", 8); + found = true; + } + if (cast->base.flags & PM_INTEGER_BASE_FLAGS_OCTAL) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " octal", 6); + found = true; + } + if (cast->base.flags & PM_INTEGER_BASE_FLAGS_HEXADECIMAL) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " hexadecimal", 12); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + const pm_integer_t *integer = &cast->value; + pm_buffer_append_byte(output_buffer, ' '); + pm_integer_string(output_buffer, integer); + pm_buffer_append_byte(output_buffer, '\n'); + } + + break; + } + case PM_INTERPOLATED_MATCH_LAST_LINE_NODE: { + pm_interpolated_match_last_line_node_t *cast = (pm_interpolated_match_last_line_node_t *) node; + pm_buffer_append_string(output_buffer, "@ InterpolatedMatchLastLineNode (location: ", 43); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // RegularExpressionFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- RegularExpressionFlags:", 27); + bool found = false; + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " ignore_case", 12); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_EXTENDED) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " extended", 9); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " multi_line", 11); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_ONCE) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " once", 5); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_EUC_JP) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " euc_jp", 7); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " ascii_8bit", 11); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " windows_31j", 12); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_UTF_8) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " utf_8", 6); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_FORCED_UTF8_ENCODING) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " forced_utf8_encoding", 21); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_FORCED_BINARY_ENCODING) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " forced_binary_encoding", 23); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " forced_us_ascii_encoding", 25); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // parts + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- parts:", 10); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->parts.size)); + + size_t last_index = cast->parts.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->parts.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE: { + pm_interpolated_regular_expression_node_t *cast = (pm_interpolated_regular_expression_node_t *) node; + pm_buffer_append_string(output_buffer, "@ InterpolatedRegularExpressionNode (location: ", 47); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // RegularExpressionFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- RegularExpressionFlags:", 27); + bool found = false; + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " ignore_case", 12); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_EXTENDED) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " extended", 9); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " multi_line", 11); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_ONCE) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " once", 5); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_EUC_JP) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " euc_jp", 7); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " ascii_8bit", 11); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " windows_31j", 12); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_UTF_8) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " utf_8", 6); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_FORCED_UTF8_ENCODING) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " forced_utf8_encoding", 21); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_FORCED_BINARY_ENCODING) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " forced_binary_encoding", 23); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " forced_us_ascii_encoding", 25); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // parts + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- parts:", 10); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->parts.size)); + + size_t last_index = cast->parts.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->parts.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_INTERPOLATED_STRING_NODE: { + pm_interpolated_string_node_t *cast = (pm_interpolated_string_node_t *) node; + pm_buffer_append_string(output_buffer, "@ InterpolatedStringNode (location: ", 36); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // InterpolatedStringNodeFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- InterpolatedStringNodeFlags:", 32); + bool found = false; + if (cast->base.flags & PM_INTERPOLATED_STRING_NODE_FLAGS_FROZEN) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " frozen", 7); + found = true; + } + if (cast->base.flags & PM_INTERPOLATED_STRING_NODE_FLAGS_MUTABLE) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " mutable", 8); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // parts + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- parts:", 10); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->parts.size)); + + size_t last_index = cast->parts.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->parts.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + break; + } + case PM_INTERPOLATED_SYMBOL_NODE: { + pm_interpolated_symbol_node_t *cast = (pm_interpolated_symbol_node_t *) node; + pm_buffer_append_string(output_buffer, "@ InterpolatedSymbolNode (location: ", 36); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // parts + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- parts:", 10); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->parts.size)); + + size_t last_index = cast->parts.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->parts.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + break; + } + case PM_INTERPOLATED_X_STRING_NODE: { + pm_interpolated_x_string_node_t *cast = (pm_interpolated_x_string_node_t *) node; + pm_buffer_append_string(output_buffer, "@ InterpolatedXStringNode (location: ", 37); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // parts + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- parts:", 10); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->parts.size)); + + size_t last_index = cast->parts.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->parts.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_IT_LOCAL_VARIABLE_READ_NODE: { + pm_buffer_append_string(output_buffer, "@ ItLocalVariableReadNode (location: ", 37); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + break; + } + case PM_IT_PARAMETERS_NODE: { + pm_buffer_append_string(output_buffer, "@ ItParametersNode (location: ", 30); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + break; + } + case PM_KEYWORD_HASH_NODE: { + pm_keyword_hash_node_t *cast = (pm_keyword_hash_node_t *) node; + pm_buffer_append_string(output_buffer, "@ KeywordHashNode (location: ", 29); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // KeywordHashNodeFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- KeywordHashNodeFlags:", 25); + bool found = false; + if (cast->base.flags & PM_KEYWORD_HASH_NODE_FLAGS_SYMBOL_KEYS) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " symbol_keys", 12); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // elements + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- elements:", 13); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->elements.size)); + + size_t last_index = cast->elements.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->elements.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + break; + } + case PM_KEYWORD_REST_PARAMETER_NODE: { + pm_keyword_rest_parameter_node_t *cast = (pm_keyword_rest_parameter_node_t *) node; + pm_buffer_append_string(output_buffer, "@ KeywordRestParameterNode (location: ", 38); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // ParameterFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ParameterFlags:", 19); + bool found = false; + if (cast->base.flags & PM_PARAMETER_FLAGS_REPEATED_PARAMETER) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " repeated_parameter", 19); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + if (cast->name == 0) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_LAMBDA_NODE: { + pm_lambda_node_t *cast = (pm_lambda_node_t *) node; + pm_buffer_append_string(output_buffer, "@ LambdaNode (location: ", 24); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // locals + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- locals:", 11); + pm_buffer_append_string(output_buffer, " [", 2); + for (uint32_t index = 0; index < cast->locals.size; index++) { + if (index != 0) pm_buffer_append_string(output_buffer, ", ", 2); + prettyprint_constant(output_buffer, parser, cast->locals.ids[index]); + } + pm_buffer_append_string(output_buffer, "]\n", 2); + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // parameters + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- parameters:", 15); + if (cast->parameters == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->parameters, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // body + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- body:", 9); + if (cast->body == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->body, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + break; + } + case PM_LOCAL_VARIABLE_AND_WRITE_NODE: { + pm_local_variable_and_write_node_t *cast = (pm_local_variable_and_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ LocalVariableAndWriteNode (location: ", 39); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // depth + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- depth:", 10); + pm_buffer_append_format(output_buffer, " %" PRIu32 "\n", cast->depth); + } + + break; + } + case PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE: { + pm_local_variable_operator_write_node_t *cast = (pm_local_variable_operator_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ LocalVariableOperatorWriteNode (location: ", 44); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // binary_operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- binary_operator_loc:", 24); + pm_location_t *location = &cast->binary_operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // binary_operator + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- binary_operator:", 20); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->binary_operator); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // depth + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- depth:", 10); + pm_buffer_append_format(output_buffer, " %" PRIu32 "\n", cast->depth); + } + + break; + } + case PM_LOCAL_VARIABLE_OR_WRITE_NODE: { + pm_local_variable_or_write_node_t *cast = (pm_local_variable_or_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ LocalVariableOrWriteNode (location: ", 38); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // depth + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- depth:", 10); + pm_buffer_append_format(output_buffer, " %" PRIu32 "\n", cast->depth); + } + + break; + } + case PM_LOCAL_VARIABLE_READ_NODE: { + pm_local_variable_read_node_t *cast = (pm_local_variable_read_node_t *) node; + pm_buffer_append_string(output_buffer, "@ LocalVariableReadNode (location: ", 35); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // depth + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- depth:", 10); + pm_buffer_append_format(output_buffer, " %" PRIu32 "\n", cast->depth); + } + + break; + } + case PM_LOCAL_VARIABLE_TARGET_NODE: { + pm_local_variable_target_node_t *cast = (pm_local_variable_target_node_t *) node; + pm_buffer_append_string(output_buffer, "@ LocalVariableTargetNode (location: ", 37); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // depth + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- depth:", 10); + pm_buffer_append_format(output_buffer, " %" PRIu32 "\n", cast->depth); + } + + break; + } + case PM_LOCAL_VARIABLE_WRITE_NODE: { + pm_local_variable_write_node_t *cast = (pm_local_variable_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ LocalVariableWriteNode (location: ", 36); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // depth + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- depth:", 10); + pm_buffer_append_format(output_buffer, " %" PRIu32 "\n", cast->depth); + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_MATCH_LAST_LINE_NODE: { + pm_match_last_line_node_t *cast = (pm_match_last_line_node_t *) node; + pm_buffer_append_string(output_buffer, "@ MatchLastLineNode (location: ", 31); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // RegularExpressionFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- RegularExpressionFlags:", 27); + bool found = false; + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " ignore_case", 12); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_EXTENDED) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " extended", 9); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " multi_line", 11); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_ONCE) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " once", 5); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_EUC_JP) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " euc_jp", 7); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " ascii_8bit", 11); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " windows_31j", 12); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_UTF_8) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " utf_8", 6); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_FORCED_UTF8_ENCODING) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " forced_utf8_encoding", 21); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_FORCED_BINARY_ENCODING) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " forced_binary_encoding", 23); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " forced_us_ascii_encoding", 25); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // content_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- content_loc:", 16); + pm_location_t *location = &cast->content_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // unescaped + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- unescaped:", 14); + pm_buffer_append_string(output_buffer, " \"", 2); + pm_buffer_append_source(output_buffer, pm_string_source(&cast->unescaped), pm_string_length(&cast->unescaped), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_MATCH_PREDICATE_NODE: { + pm_match_predicate_node_t *cast = (pm_match_predicate_node_t *) node; + pm_buffer_append_string(output_buffer, "@ MatchPredicateNode (location: ", 32); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // pattern + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- pattern:", 12); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->pattern, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_MATCH_REQUIRED_NODE: { + pm_match_required_node_t *cast = (pm_match_required_node_t *) node; + pm_buffer_append_string(output_buffer, "@ MatchRequiredNode (location: ", 31); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // pattern + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- pattern:", 12); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->pattern, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_MATCH_WRITE_NODE: { + pm_match_write_node_t *cast = (pm_match_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ MatchWriteNode (location: ", 28); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // call + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- call:", 9); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->call, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // targets + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- targets:", 12); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->targets.size)); + + size_t last_index = cast->targets.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->targets.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + break; + } + case PM_MISSING_NODE: { + pm_buffer_append_string(output_buffer, "@ MissingNode (location: ", 25); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + break; + } + case PM_MODULE_NODE: { + pm_module_node_t *cast = (pm_module_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ModuleNode (location: ", 24); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // locals + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- locals:", 11); + pm_buffer_append_string(output_buffer, " [", 2); + for (uint32_t index = 0; index < cast->locals.size; index++) { + if (index != 0) pm_buffer_append_string(output_buffer, ", ", 2); + prettyprint_constant(output_buffer, parser, cast->locals.ids[index]); + } + pm_buffer_append_string(output_buffer, "]\n", 2); + } + + // module_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- module_keyword_loc:", 23); + pm_location_t *location = &cast->module_keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // constant_path + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- constant_path:", 18); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->constant_path, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // body + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- body:", 9); + if (cast->body == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->body, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // end_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- end_keyword_loc:", 20); + pm_location_t *location = &cast->end_keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + break; + } + case PM_MULTI_TARGET_NODE: { + pm_multi_target_node_t *cast = (pm_multi_target_node_t *) node; + pm_buffer_append_string(output_buffer, "@ MultiTargetNode (location: ", 29); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // lefts + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- lefts:", 10); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->lefts.size)); + + size_t last_index = cast->lefts.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->lefts.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // rest + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- rest:", 9); + if (cast->rest == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->rest, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // rights + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- rights:", 11); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->rights.size)); + + size_t last_index = cast->rights.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->rights.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // lparen_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- lparen_loc:", 15); + pm_location_t *location = &cast->lparen_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // rparen_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- rparen_loc:", 15); + pm_location_t *location = &cast->rparen_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + break; + } + case PM_MULTI_WRITE_NODE: { + pm_multi_write_node_t *cast = (pm_multi_write_node_t *) node; + pm_buffer_append_string(output_buffer, "@ MultiWriteNode (location: ", 28); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // lefts + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- lefts:", 10); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->lefts.size)); + + size_t last_index = cast->lefts.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->lefts.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // rest + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- rest:", 9); + if (cast->rest == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->rest, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // rights + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- rights:", 11); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->rights.size)); + + size_t last_index = cast->rights.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->rights.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // lparen_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- lparen_loc:", 15); + pm_location_t *location = &cast->lparen_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // rparen_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- rparen_loc:", 15); + pm_location_t *location = &cast->rparen_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_NEXT_NODE: { + pm_next_node_t *cast = (pm_next_node_t *) node; + pm_buffer_append_string(output_buffer, "@ NextNode (location: ", 22); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // arguments + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- arguments:", 14); + if (cast->arguments == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->arguments, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- keyword_loc:", 16); + pm_location_t *location = &cast->keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_NIL_NODE: { + pm_buffer_append_string(output_buffer, "@ NilNode (location: ", 21); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + break; + } + case PM_NO_KEYWORDS_PARAMETER_NODE: { + pm_no_keywords_parameter_node_t *cast = (pm_no_keywords_parameter_node_t *) node; + pm_buffer_append_string(output_buffer, "@ NoKeywordsParameterNode (location: ", 37); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- keyword_loc:", 16); + pm_location_t *location = &cast->keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_NUMBERED_PARAMETERS_NODE: { + pm_numbered_parameters_node_t *cast = (pm_numbered_parameters_node_t *) node; + pm_buffer_append_string(output_buffer, "@ NumberedParametersNode (location: ", 36); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // maximum + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- maximum:", 12); + pm_buffer_append_format(output_buffer, " %" PRIu8 "\n", cast->maximum); + } + + break; + } + case PM_NUMBERED_REFERENCE_READ_NODE: { + pm_numbered_reference_read_node_t *cast = (pm_numbered_reference_read_node_t *) node; + pm_buffer_append_string(output_buffer, "@ NumberedReferenceReadNode (location: ", 39); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // number + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- number:", 11); + pm_buffer_append_format(output_buffer, " %" PRIu32 "\n", cast->number); + } + + break; + } + case PM_OPTIONAL_KEYWORD_PARAMETER_NODE: { + pm_optional_keyword_parameter_node_t *cast = (pm_optional_keyword_parameter_node_t *) node; + pm_buffer_append_string(output_buffer, "@ OptionalKeywordParameterNode (location: ", 42); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // ParameterFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ParameterFlags:", 19); + bool found = false; + if (cast->base.flags & PM_PARAMETER_FLAGS_REPEATED_PARAMETER) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " repeated_parameter", 19); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_OPTIONAL_PARAMETER_NODE: { + pm_optional_parameter_node_t *cast = (pm_optional_parameter_node_t *) node; + pm_buffer_append_string(output_buffer, "@ OptionalParameterNode (location: ", 35); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // ParameterFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ParameterFlags:", 19); + bool found = false; + if (cast->base.flags & PM_PARAMETER_FLAGS_REPEATED_PARAMETER) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " repeated_parameter", 19); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // value + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->value, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_OR_NODE: { + pm_or_node_t *cast = (pm_or_node_t *) node; + pm_buffer_append_string(output_buffer, "@ OrNode (location: ", 20); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // left + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- left:", 9); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->left, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // right + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- right:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->right, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_PARAMETERS_NODE: { + pm_parameters_node_t *cast = (pm_parameters_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ParametersNode (location: ", 28); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // requireds + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- requireds:", 14); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->requireds.size)); + + size_t last_index = cast->requireds.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->requireds.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // optionals + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- optionals:", 14); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->optionals.size)); + + size_t last_index = cast->optionals.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->optionals.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // rest + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- rest:", 9); + if (cast->rest == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->rest, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // posts + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- posts:", 10); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->posts.size)); + + size_t last_index = cast->posts.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->posts.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // keywords + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- keywords:", 13); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->keywords.size)); + + size_t last_index = cast->keywords.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->keywords.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // keyword_rest + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- keyword_rest:", 17); + if (cast->keyword_rest == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->keyword_rest, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // block + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- block:", 10); + if (cast->block == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->block, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + break; + } + case PM_PARENTHESES_NODE: { + pm_parentheses_node_t *cast = (pm_parentheses_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ParenthesesNode (location: ", 29); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // ParenthesesNodeFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ParenthesesNodeFlags:", 25); + bool found = false; + if (cast->base.flags & PM_PARENTHESES_NODE_FLAGS_MULTIPLE_STATEMENTS) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " multiple_statements", 20); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // body + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- body:", 9); + if (cast->body == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->body, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_PINNED_EXPRESSION_NODE: { + pm_pinned_expression_node_t *cast = (pm_pinned_expression_node_t *) node; + pm_buffer_append_string(output_buffer, "@ PinnedExpressionNode (location: ", 34); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // expression + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- expression:", 15); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->expression, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // lparen_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- lparen_loc:", 15); + pm_location_t *location = &cast->lparen_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // rparen_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- rparen_loc:", 15); + pm_location_t *location = &cast->rparen_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_PINNED_VARIABLE_NODE: { + pm_pinned_variable_node_t *cast = (pm_pinned_variable_node_t *) node; + pm_buffer_append_string(output_buffer, "@ PinnedVariableNode (location: ", 32); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // variable + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- variable:", 13); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->variable, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_POST_EXECUTION_NODE: { + pm_post_execution_node_t *cast = (pm_post_execution_node_t *) node; + pm_buffer_append_string(output_buffer, "@ PostExecutionNode (location: ", 31); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // statements + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- statements:", 15); + if (cast->statements == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- keyword_loc:", 16); + pm_location_t *location = &cast->keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_PRE_EXECUTION_NODE: { + pm_pre_execution_node_t *cast = (pm_pre_execution_node_t *) node; + pm_buffer_append_string(output_buffer, "@ PreExecutionNode (location: ", 30); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // statements + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- statements:", 15); + if (cast->statements == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- keyword_loc:", 16); + pm_location_t *location = &cast->keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_PROGRAM_NODE: { + pm_program_node_t *cast = (pm_program_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ProgramNode (location: ", 25); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // locals + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- locals:", 11); + pm_buffer_append_string(output_buffer, " [", 2); + for (uint32_t index = 0; index < cast->locals.size; index++) { + if (index != 0) pm_buffer_append_string(output_buffer, ", ", 2); + prettyprint_constant(output_buffer, parser, cast->locals.ids[index]); + } + pm_buffer_append_string(output_buffer, "]\n", 2); + } + + // statements + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- statements:", 15); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_RANGE_NODE: { + pm_range_node_t *cast = (pm_range_node_t *) node; + pm_buffer_append_string(output_buffer, "@ RangeNode (location: ", 23); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // RangeFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- RangeFlags:", 15); + bool found = false; + if (cast->base.flags & PM_RANGE_FLAGS_EXCLUDE_END) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " exclude_end", 12); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // left + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- left:", 9); + if (cast->left == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->left, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // right + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- right:", 10); + if (cast->right == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->right, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_RATIONAL_NODE: { + pm_rational_node_t *cast = (pm_rational_node_t *) node; + pm_buffer_append_string(output_buffer, "@ RationalNode (location: ", 26); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // IntegerBaseFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- IntegerBaseFlags:", 21); + bool found = false; + if (cast->base.flags & PM_INTEGER_BASE_FLAGS_BINARY) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " binary", 7); + found = true; + } + if (cast->base.flags & PM_INTEGER_BASE_FLAGS_DECIMAL) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " decimal", 8); + found = true; + } + if (cast->base.flags & PM_INTEGER_BASE_FLAGS_OCTAL) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " octal", 6); + found = true; + } + if (cast->base.flags & PM_INTEGER_BASE_FLAGS_HEXADECIMAL) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " hexadecimal", 12); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // numerator + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- numerator:", 14); + const pm_integer_t *integer = &cast->numerator; + pm_buffer_append_byte(output_buffer, ' '); + pm_integer_string(output_buffer, integer); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // denominator + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- denominator:", 16); + const pm_integer_t *integer = &cast->denominator; + pm_buffer_append_byte(output_buffer, ' '); + pm_integer_string(output_buffer, integer); + pm_buffer_append_byte(output_buffer, '\n'); + } + + break; + } + case PM_REDO_NODE: { + pm_buffer_append_string(output_buffer, "@ RedoNode (location: ", 22); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + break; + } + case PM_REGULAR_EXPRESSION_NODE: { + pm_regular_expression_node_t *cast = (pm_regular_expression_node_t *) node; + pm_buffer_append_string(output_buffer, "@ RegularExpressionNode (location: ", 35); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // RegularExpressionFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- RegularExpressionFlags:", 27); + bool found = false; + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " ignore_case", 12); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_EXTENDED) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " extended", 9); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " multi_line", 11); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_ONCE) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " once", 5); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_EUC_JP) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " euc_jp", 7); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " ascii_8bit", 11); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " windows_31j", 12); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_UTF_8) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " utf_8", 6); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_FORCED_UTF8_ENCODING) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " forced_utf8_encoding", 21); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_FORCED_BINARY_ENCODING) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " forced_binary_encoding", 23); + found = true; + } + if (cast->base.flags & PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " forced_us_ascii_encoding", 25); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // content_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- content_loc:", 16); + pm_location_t *location = &cast->content_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // unescaped + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- unescaped:", 14); + pm_buffer_append_string(output_buffer, " \"", 2); + pm_buffer_append_source(output_buffer, pm_string_source(&cast->unescaped), pm_string_length(&cast->unescaped), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_REQUIRED_KEYWORD_PARAMETER_NODE: { + pm_required_keyword_parameter_node_t *cast = (pm_required_keyword_parameter_node_t *) node; + pm_buffer_append_string(output_buffer, "@ RequiredKeywordParameterNode (location: ", 42); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // ParameterFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ParameterFlags:", 19); + bool found = false; + if (cast->base.flags & PM_PARAMETER_FLAGS_REPEATED_PARAMETER) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " repeated_parameter", 19); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_REQUIRED_PARAMETER_NODE: { + pm_required_parameter_node_t *cast = (pm_required_parameter_node_t *) node; + pm_buffer_append_string(output_buffer, "@ RequiredParameterNode (location: ", 35); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // ParameterFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ParameterFlags:", 19); + bool found = false; + if (cast->base.flags & PM_PARAMETER_FLAGS_REPEATED_PARAMETER) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " repeated_parameter", 19); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + + break; + } + case PM_RESCUE_MODIFIER_NODE: { + pm_rescue_modifier_node_t *cast = (pm_rescue_modifier_node_t *) node; + pm_buffer_append_string(output_buffer, "@ RescueModifierNode (location: ", 32); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // expression + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- expression:", 15); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->expression, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- keyword_loc:", 16); + pm_location_t *location = &cast->keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // rescue_expression + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- rescue_expression:", 22); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->rescue_expression, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_RESCUE_NODE: { + pm_rescue_node_t *cast = (pm_rescue_node_t *) node; + pm_buffer_append_string(output_buffer, "@ RescueNode (location: ", 24); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- keyword_loc:", 16); + pm_location_t *location = &cast->keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // exceptions + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- exceptions:", 15); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->exceptions.size)); + + size_t last_index = cast->exceptions.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->exceptions.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // reference + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- reference:", 14); + if (cast->reference == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->reference, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // then_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- then_keyword_loc:", 21); + pm_location_t *location = &cast->then_keyword_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // statements + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- statements:", 15); + if (cast->statements == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // subsequent + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- subsequent:", 15); + if (cast->subsequent == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->subsequent, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + break; + } + case PM_REST_PARAMETER_NODE: { + pm_rest_parameter_node_t *cast = (pm_rest_parameter_node_t *) node; + pm_buffer_append_string(output_buffer, "@ RestParameterNode (location: ", 31); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // ParameterFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ParameterFlags:", 19); + bool found = false; + if (cast->base.flags & PM_PARAMETER_FLAGS_REPEATED_PARAMETER) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " repeated_parameter", 19); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // name + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name:", 9); + if (cast->name == 0) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_constant(output_buffer, parser, cast->name); + pm_buffer_append_byte(output_buffer, '\n'); + } + } + + // name_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- name_loc:", 13); + pm_location_t *location = &cast->name_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_RETRY_NODE: { + pm_buffer_append_string(output_buffer, "@ RetryNode (location: ", 23); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + break; + } + case PM_RETURN_NODE: { + pm_return_node_t *cast = (pm_return_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ReturnNode (location: ", 24); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- keyword_loc:", 16); + pm_location_t *location = &cast->keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // arguments + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- arguments:", 14); + if (cast->arguments == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->arguments, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + break; + } + case PM_SELF_NODE: { + pm_buffer_append_string(output_buffer, "@ SelfNode (location: ", 22); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + break; + } + case PM_SHAREABLE_CONSTANT_NODE: { + pm_shareable_constant_node_t *cast = (pm_shareable_constant_node_t *) node; + pm_buffer_append_string(output_buffer, "@ ShareableConstantNode (location: ", 35); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // ShareableConstantNodeFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ShareableConstantNodeFlags:", 31); + bool found = false; + if (cast->base.flags & PM_SHAREABLE_CONSTANT_NODE_FLAGS_LITERAL) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " literal", 8); + found = true; + } + if (cast->base.flags & PM_SHAREABLE_CONSTANT_NODE_FLAGS_EXPERIMENTAL_EVERYTHING) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " experimental_everything", 24); + found = true; + } + if (cast->base.flags & PM_SHAREABLE_CONSTANT_NODE_FLAGS_EXPERIMENTAL_COPY) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " experimental_copy", 18); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // write + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- write:", 10); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->write, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + break; + } + case PM_SINGLETON_CLASS_NODE: { + pm_singleton_class_node_t *cast = (pm_singleton_class_node_t *) node; + pm_buffer_append_string(output_buffer, "@ SingletonClassNode (location: ", 32); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // locals + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- locals:", 11); + pm_buffer_append_string(output_buffer, " [", 2); + for (uint32_t index = 0; index < cast->locals.size; index++) { + if (index != 0) pm_buffer_append_string(output_buffer, ", ", 2); + prettyprint_constant(output_buffer, parser, cast->locals.ids[index]); + } + pm_buffer_append_string(output_buffer, "]\n", 2); + } + + // class_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- class_keyword_loc:", 22); + pm_location_t *location = &cast->class_keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // expression + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- expression:", 15); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->expression, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // body + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- body:", 9); + if (cast->body == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->body, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // end_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- end_keyword_loc:", 20); + pm_location_t *location = &cast->end_keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_SOURCE_ENCODING_NODE: { + pm_buffer_append_string(output_buffer, "@ SourceEncodingNode (location: ", 32); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + break; + } + case PM_SOURCE_FILE_NODE: { + pm_source_file_node_t *cast = (pm_source_file_node_t *) node; + pm_buffer_append_string(output_buffer, "@ SourceFileNode (location: ", 28); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // StringFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- StringFlags:", 16); + bool found = false; + if (cast->base.flags & PM_STRING_FLAGS_FORCED_UTF8_ENCODING) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " forced_utf8_encoding", 21); + found = true; + } + if (cast->base.flags & PM_STRING_FLAGS_FORCED_BINARY_ENCODING) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " forced_binary_encoding", 23); + found = true; + } + if (cast->base.flags & PM_STRING_FLAGS_FROZEN) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " frozen", 7); + found = true; + } + if (cast->base.flags & PM_STRING_FLAGS_MUTABLE) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " mutable", 8); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // filepath + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- filepath:", 13); + pm_buffer_append_string(output_buffer, " \"", 2); + pm_buffer_append_source(output_buffer, pm_string_source(&cast->filepath), pm_string_length(&cast->filepath), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_SOURCE_LINE_NODE: { + pm_buffer_append_string(output_buffer, "@ SourceLineNode (location: ", 28); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + break; + } + case PM_SPLAT_NODE: { + pm_splat_node_t *cast = (pm_splat_node_t *) node; + pm_buffer_append_string(output_buffer, "@ SplatNode (location: ", 23); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // operator_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- operator_loc:", 17); + pm_location_t *location = &cast->operator_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // expression + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- expression:", 15); + if (cast->expression == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->expression, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + break; + } + case PM_STATEMENTS_NODE: { + pm_statements_node_t *cast = (pm_statements_node_t *) node; + pm_buffer_append_string(output_buffer, "@ StatementsNode (location: ", 28); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // body + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- body:", 9); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->body.size)); + + size_t last_index = cast->body.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->body.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + break; + } + case PM_STRING_NODE: { + pm_string_node_t *cast = (pm_string_node_t *) node; + pm_buffer_append_string(output_buffer, "@ StringNode (location: ", 24); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // StringFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- StringFlags:", 16); + bool found = false; + if (cast->base.flags & PM_STRING_FLAGS_FORCED_UTF8_ENCODING) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " forced_utf8_encoding", 21); + found = true; + } + if (cast->base.flags & PM_STRING_FLAGS_FORCED_BINARY_ENCODING) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " forced_binary_encoding", 23); + found = true; + } + if (cast->base.flags & PM_STRING_FLAGS_FROZEN) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " frozen", 7); + found = true; + } + if (cast->base.flags & PM_STRING_FLAGS_MUTABLE) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " mutable", 8); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // content_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- content_loc:", 16); + pm_location_t *location = &cast->content_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // unescaped + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- unescaped:", 14); + pm_buffer_append_string(output_buffer, " \"", 2); + pm_buffer_append_source(output_buffer, pm_string_source(&cast->unescaped), pm_string_length(&cast->unescaped), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_SUPER_NODE: { + pm_super_node_t *cast = (pm_super_node_t *) node; + pm_buffer_append_string(output_buffer, "@ SuperNode (location: ", 23); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- keyword_loc:", 16); + pm_location_t *location = &cast->keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // lparen_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- lparen_loc:", 15); + pm_location_t *location = &cast->lparen_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // arguments + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- arguments:", 14); + if (cast->arguments == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->arguments, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // rparen_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- rparen_loc:", 15); + pm_location_t *location = &cast->rparen_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // block + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- block:", 10); + if (cast->block == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->block, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + break; + } + case PM_SYMBOL_NODE: { + pm_symbol_node_t *cast = (pm_symbol_node_t *) node; + pm_buffer_append_string(output_buffer, "@ SymbolNode (location: ", 24); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // SymbolFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- SymbolFlags:", 16); + bool found = false; + if (cast->base.flags & PM_SYMBOL_FLAGS_FORCED_UTF8_ENCODING) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " forced_utf8_encoding", 21); + found = true; + } + if (cast->base.flags & PM_SYMBOL_FLAGS_FORCED_BINARY_ENCODING) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " forced_binary_encoding", 23); + found = true; + } + if (cast->base.flags & PM_SYMBOL_FLAGS_FORCED_US_ASCII_ENCODING) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " forced_us_ascii_encoding", 25); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // value_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- value_loc:", 14); + pm_location_t *location = &cast->value_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // unescaped + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- unescaped:", 14); + pm_buffer_append_string(output_buffer, " \"", 2); + pm_buffer_append_source(output_buffer, pm_string_source(&cast->unescaped), pm_string_length(&cast->unescaped), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_TRUE_NODE: { + pm_buffer_append_string(output_buffer, "@ TrueNode (location: ", 22); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + break; + } + case PM_UNDEF_NODE: { + pm_undef_node_t *cast = (pm_undef_node_t *) node; + pm_buffer_append_string(output_buffer, "@ UndefNode (location: ", 23); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // names + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- names:", 10); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->names.size)); + + size_t last_index = cast->names.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->names.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- keyword_loc:", 16); + pm_location_t *location = &cast->keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_UNLESS_NODE: { + pm_unless_node_t *cast = (pm_unless_node_t *) node; + pm_buffer_append_string(output_buffer, "@ UnlessNode (location: ", 24); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- keyword_loc:", 16); + pm_location_t *location = &cast->keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // predicate + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- predicate:", 14); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->predicate, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // then_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- then_keyword_loc:", 21); + pm_location_t *location = &cast->then_keyword_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // statements + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- statements:", 15); + if (cast->statements == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // else_clause + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- else_clause:", 16); + if (cast->else_clause == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->else_clause, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // end_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- end_keyword_loc:", 20); + pm_location_t *location = &cast->end_keyword_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + break; + } + case PM_UNTIL_NODE: { + pm_until_node_t *cast = (pm_until_node_t *) node; + pm_buffer_append_string(output_buffer, "@ UntilNode (location: ", 23); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // LoopFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- LoopFlags:", 14); + bool found = false; + if (cast->base.flags & PM_LOOP_FLAGS_BEGIN_MODIFIER) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " begin_modifier", 15); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- keyword_loc:", 16); + pm_location_t *location = &cast->keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // do_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- do_keyword_loc:", 19); + pm_location_t *location = &cast->do_keyword_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // predicate + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- predicate:", 14); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->predicate, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // statements + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- statements:", 15); + if (cast->statements == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + break; + } + case PM_WHEN_NODE: { + pm_when_node_t *cast = (pm_when_node_t *) node; + pm_buffer_append_string(output_buffer, "@ WhenNode (location: ", 22); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- keyword_loc:", 16); + pm_location_t *location = &cast->keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // conditions + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- conditions:", 15); + pm_buffer_append_format(output_buffer, " (length: %lu)\n", (unsigned long) (cast->conditions.size)); + + size_t last_index = cast->conditions.size; + for (uint32_t index = 0; index < last_index; index++) { + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- ", 4); + pm_buffer_append_string(prefix_buffer, (index == last_index - 1) ? " " : "| ", 4); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->conditions.nodes[index], prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // then_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- then_keyword_loc:", 21); + pm_location_t *location = &cast->then_keyword_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // statements + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- statements:", 15); + if (cast->statements == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + break; + } + case PM_WHILE_NODE: { + pm_while_node_t *cast = (pm_while_node_t *) node; + pm_buffer_append_string(output_buffer, "@ WhileNode (location: ", 23); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // LoopFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- LoopFlags:", 14); + bool found = false; + if (cast->base.flags & PM_LOOP_FLAGS_BEGIN_MODIFIER) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " begin_modifier", 15); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- keyword_loc:", 16); + pm_location_t *location = &cast->keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // do_keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- do_keyword_loc:", 19); + pm_location_t *location = &cast->do_keyword_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // predicate + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- predicate:", 14); + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->predicate, prefix_buffer); + prefix_buffer->length = prefix_length; + } + + // statements + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- statements:", 15); + if (cast->statements == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, " ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->statements, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + break; + } + case PM_X_STRING_NODE: { + pm_x_string_node_t *cast = (pm_x_string_node_t *) node; + pm_buffer_append_string(output_buffer, "@ XStringNode (location: ", 25); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // EncodingFlags + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- EncodingFlags:", 18); + bool found = false; + if (cast->base.flags & PM_ENCODING_FLAGS_FORCED_UTF8_ENCODING) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " forced_utf8_encoding", 21); + found = true; + } + if (cast->base.flags & PM_ENCODING_FLAGS_FORCED_BINARY_ENCODING) { + if (found) pm_buffer_append_byte(output_buffer, ','); + pm_buffer_append_string(output_buffer, " forced_binary_encoding", 23); + found = true; + } + if (!found) pm_buffer_append_string(output_buffer, " nil", 4); + pm_buffer_append_byte(output_buffer, '\n'); + } + + // opening_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- opening_loc:", 16); + pm_location_t *location = &cast->opening_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // content_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- content_loc:", 16); + pm_location_t *location = &cast->content_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // closing_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- closing_loc:", 16); + pm_location_t *location = &cast->closing_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // unescaped + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- unescaped:", 14); + pm_buffer_append_string(output_buffer, " \"", 2); + pm_buffer_append_source(output_buffer, pm_string_source(&cast->unescaped), pm_string_length(&cast->unescaped), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + break; + } + case PM_YIELD_NODE: { + pm_yield_node_t *cast = (pm_yield_node_t *) node; + pm_buffer_append_string(output_buffer, "@ YieldNode (location: ", 23); + prettyprint_location(output_buffer, parser, &node->location); + pm_buffer_append_string(output_buffer, ")\n", 2); + + // keyword_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- keyword_loc:", 16); + pm_location_t *location = &cast->keyword_loc; + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + + // lparen_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- lparen_loc:", 15); + pm_location_t *location = &cast->lparen_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + // arguments + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- arguments:", 14); + if (cast->arguments == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, '\n'); + + size_t prefix_length = prefix_buffer->length; + pm_buffer_append_string(prefix_buffer, "| ", 4); + pm_buffer_concat(output_buffer, prefix_buffer); + prettyprint_node(output_buffer, parser, (pm_node_t *) cast->arguments, prefix_buffer); + prefix_buffer->length = prefix_length; + } + } + + // rparen_loc + { + pm_buffer_concat(output_buffer, prefix_buffer); + pm_buffer_append_string(output_buffer, "+-- rparen_loc:", 15); + pm_location_t *location = &cast->rparen_loc; + if (location->start == NULL) { + pm_buffer_append_string(output_buffer, " nil\n", 5); + } else { + pm_buffer_append_byte(output_buffer, ' '); + prettyprint_location(output_buffer, parser, location); + pm_buffer_append_string(output_buffer, " = \"", 4); + pm_buffer_append_source(output_buffer, location->start, (size_t) (location->end - location->start), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_string(output_buffer, "\"\n", 2); + } + } + + break; + } + } +} + +/** + * Pretty-prints the AST represented by the given node to the given buffer. + */ +PRISM_EXPORTED_FUNCTION void +pm_prettyprint(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm_node_t *node) { + pm_buffer_t prefix_buffer = { 0 }; + prettyprint_node(output_buffer, parser, node, &prefix_buffer); + pm_buffer_free(&prefix_buffer); +} + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/prism.c b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/prism.c new file mode 100644 index 00000000..c4cab8f0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/prism.c @@ -0,0 +1,23184 @@ +#include "prism.h" + +/** + * The prism version and the serialization format. + */ +const char * +pm_version(void) { + return PRISM_VERSION; +} + +/** + * In heredocs, tabs automatically complete up to the next 8 spaces. This is + * defined in CRuby as TAB_WIDTH. + */ +#define PM_TAB_WHITESPACE_SIZE 8 + +// Macros for min/max. +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MAX(a,b) (((a)>(b))?(a):(b)) + +/******************************************************************************/ +/* Lex mode manipulations */ +/******************************************************************************/ + +/** + * Returns the incrementor character that should be used to increment the + * nesting count if one is possible. + */ +static inline uint8_t +lex_mode_incrementor(const uint8_t start) { + switch (start) { + case '(': + case '[': + case '{': + case '<': + return start; + default: + return '\0'; + } +} + +/** + * Returns the matching character that should be used to terminate a list + * beginning with the given character. + */ +static inline uint8_t +lex_mode_terminator(const uint8_t start) { + switch (start) { + case '(': + return ')'; + case '[': + return ']'; + case '{': + return '}'; + case '<': + return '>'; + default: + return start; + } +} + +/** + * Push a new lex state onto the stack. If we're still within the pre-allocated + * space of the lex state stack, then we'll just use a new slot. Otherwise we'll + * allocate a new pointer and use that. + */ +static bool +lex_mode_push(pm_parser_t *parser, pm_lex_mode_t lex_mode) { + lex_mode.prev = parser->lex_modes.current; + parser->lex_modes.index++; + + if (parser->lex_modes.index > PM_LEX_STACK_SIZE - 1) { + parser->lex_modes.current = (pm_lex_mode_t *) xmalloc(sizeof(pm_lex_mode_t)); + if (parser->lex_modes.current == NULL) return false; + + *parser->lex_modes.current = lex_mode; + } else { + parser->lex_modes.stack[parser->lex_modes.index] = lex_mode; + parser->lex_modes.current = &parser->lex_modes.stack[parser->lex_modes.index]; + } + + return true; +} + +/** + * Push on a new list lex mode. + */ +static inline bool +lex_mode_push_list(pm_parser_t *parser, bool interpolation, uint8_t delimiter) { + uint8_t incrementor = lex_mode_incrementor(delimiter); + uint8_t terminator = lex_mode_terminator(delimiter); + + pm_lex_mode_t lex_mode = { + .mode = PM_LEX_LIST, + .as.list = { + .nesting = 0, + .interpolation = interpolation, + .incrementor = incrementor, + .terminator = terminator + } + }; + + // These are the places where we need to split up the content of the list. + // We'll use strpbrk to find the first of these characters. + uint8_t *breakpoints = lex_mode.as.list.breakpoints; + memcpy(breakpoints, "\\ \t\f\r\v\n\0\0\0", sizeof(lex_mode.as.list.breakpoints)); + size_t index = 7; + + // Now we'll add the terminator to the list of breakpoints. If the + // terminator is not already a NULL byte, add it to the list. + if (terminator != '\0') { + breakpoints[index++] = terminator; + } + + // If interpolation is allowed, then we're going to check for the # + // character. Otherwise we'll only look for escapes and the terminator. + if (interpolation) { + breakpoints[index++] = '#'; + } + + // If there is an incrementor, then we'll check for that as well. + if (incrementor != '\0') { + breakpoints[index++] = incrementor; + } + + parser->explicit_encoding = NULL; + return lex_mode_push(parser, lex_mode); +} + +/** + * Push on a new list lex mode that is only used for compatibility. This is + * called when we're at the end of the file. We want the parser to be able to + * perform its normal error tolerance. + */ +static inline bool +lex_mode_push_list_eof(pm_parser_t *parser) { + return lex_mode_push_list(parser, false, '\0'); +} + +/** + * Push on a new regexp lex mode. + */ +static inline bool +lex_mode_push_regexp(pm_parser_t *parser, uint8_t incrementor, uint8_t terminator) { + pm_lex_mode_t lex_mode = { + .mode = PM_LEX_REGEXP, + .as.regexp = { + .nesting = 0, + .incrementor = incrementor, + .terminator = terminator + } + }; + + // These are the places where we need to split up the content of the + // regular expression. We'll use strpbrk to find the first of these + // characters. + uint8_t *breakpoints = lex_mode.as.regexp.breakpoints; + memcpy(breakpoints, "\r\n\\#\0\0", sizeof(lex_mode.as.regexp.breakpoints)); + size_t index = 4; + + // First we'll add the terminator. + if (terminator != '\0') { + breakpoints[index++] = terminator; + } + + // Next, if there is an incrementor, then we'll check for that as well. + if (incrementor != '\0') { + breakpoints[index++] = incrementor; + } + + parser->explicit_encoding = NULL; + return lex_mode_push(parser, lex_mode); +} + +/** + * Push on a new string lex mode. + */ +static inline bool +lex_mode_push_string(pm_parser_t *parser, bool interpolation, bool label_allowed, uint8_t incrementor, uint8_t terminator) { + pm_lex_mode_t lex_mode = { + .mode = PM_LEX_STRING, + .as.string = { + .nesting = 0, + .interpolation = interpolation, + .label_allowed = label_allowed, + .incrementor = incrementor, + .terminator = terminator + } + }; + + // These are the places where we need to split up the content of the + // string. We'll use strpbrk to find the first of these characters. + uint8_t *breakpoints = lex_mode.as.string.breakpoints; + memcpy(breakpoints, "\r\n\\\0\0\0", sizeof(lex_mode.as.string.breakpoints)); + size_t index = 3; + + // Now add in the terminator. If the terminator is not already a NULL byte, + // then we'll add it. + if (terminator != '\0') { + breakpoints[index++] = terminator; + } + + // If interpolation is allowed, then we're going to check for the # + // character. Otherwise we'll only look for escapes and the terminator. + if (interpolation) { + breakpoints[index++] = '#'; + } + + // If we have an incrementor, then we'll add that in as a breakpoint as + // well. + if (incrementor != '\0') { + breakpoints[index++] = incrementor; + } + + parser->explicit_encoding = NULL; + return lex_mode_push(parser, lex_mode); +} + +/** + * Push on a new string lex mode that is only used for compatibility. This is + * called when we're at the end of the file. We want the parser to be able to + * perform its normal error tolerance. + */ +static inline bool +lex_mode_push_string_eof(pm_parser_t *parser) { + return lex_mode_push_string(parser, false, false, '\0', '\0'); +} + +/** + * Pop the current lex state off the stack. If we're within the pre-allocated + * space of the lex state stack, then we'll just decrement the index. Otherwise + * we'll free the current pointer and use the previous pointer. + */ +static void +lex_mode_pop(pm_parser_t *parser) { + if (parser->lex_modes.index == 0) { + parser->lex_modes.current->mode = PM_LEX_DEFAULT; + } else if (parser->lex_modes.index < PM_LEX_STACK_SIZE) { + parser->lex_modes.index--; + parser->lex_modes.current = &parser->lex_modes.stack[parser->lex_modes.index]; + } else { + parser->lex_modes.index--; + pm_lex_mode_t *prev = parser->lex_modes.current->prev; + xfree(parser->lex_modes.current); + parser->lex_modes.current = prev; + } +} + +/** + * This is the equivalent of IS_lex_state is CRuby. + */ +static inline bool +lex_state_p(const pm_parser_t *parser, pm_lex_state_t state) { + return parser->lex_state & state; +} + +typedef enum { + PM_IGNORED_NEWLINE_NONE = 0, + PM_IGNORED_NEWLINE_ALL, + PM_IGNORED_NEWLINE_PATTERN +} pm_ignored_newline_type_t; + +static inline pm_ignored_newline_type_t +lex_state_ignored_p(pm_parser_t *parser) { + bool ignored = lex_state_p(parser, PM_LEX_STATE_BEG | PM_LEX_STATE_CLASS | PM_LEX_STATE_FNAME | PM_LEX_STATE_DOT) && !lex_state_p(parser, PM_LEX_STATE_LABELED); + + if (ignored) { + return PM_IGNORED_NEWLINE_ALL; + } else if ((parser->lex_state & ~((unsigned int) PM_LEX_STATE_LABEL)) == (PM_LEX_STATE_ARG | PM_LEX_STATE_LABELED)) { + return PM_IGNORED_NEWLINE_PATTERN; + } else { + return PM_IGNORED_NEWLINE_NONE; + } +} + +static inline bool +lex_state_beg_p(pm_parser_t *parser) { + return lex_state_p(parser, PM_LEX_STATE_BEG_ANY) || ((parser->lex_state & (PM_LEX_STATE_ARG | PM_LEX_STATE_LABELED)) == (PM_LEX_STATE_ARG | PM_LEX_STATE_LABELED)); +} + +static inline bool +lex_state_arg_p(pm_parser_t *parser) { + return lex_state_p(parser, PM_LEX_STATE_ARG_ANY); +} + +static inline bool +lex_state_spcarg_p(pm_parser_t *parser, bool space_seen) { + if (parser->current.end >= parser->end) { + return false; + } + return lex_state_arg_p(parser) && space_seen && !pm_char_is_whitespace(*parser->current.end); +} + +static inline bool +lex_state_end_p(pm_parser_t *parser) { + return lex_state_p(parser, PM_LEX_STATE_END_ANY); +} + +/** + * This is the equivalent of IS_AFTER_OPERATOR in CRuby. + */ +static inline bool +lex_state_operator_p(pm_parser_t *parser) { + return lex_state_p(parser, PM_LEX_STATE_FNAME | PM_LEX_STATE_DOT); +} + +/** + * Set the state of the lexer. This is defined as a function to be able to put a + * breakpoint in it. + */ +static inline void +lex_state_set(pm_parser_t *parser, pm_lex_state_t state) { + parser->lex_state = state; +} + +#ifndef PM_DEBUG_LOGGING +/** + * Debugging logging will print additional information to stdout whenever the + * lexer state changes. + */ +#define PM_DEBUG_LOGGING 0 +#endif + +#if PM_DEBUG_LOGGING +PRISM_ATTRIBUTE_UNUSED static void +debug_state(pm_parser_t *parser) { + fprintf(stderr, "STATE: "); + bool first = true; + + if (parser->lex_state == PM_LEX_STATE_NONE) { + fprintf(stderr, "NONE\n"); + return; + } + +#define CHECK_STATE(state) \ + if (parser->lex_state & state) { \ + if (!first) fprintf(stderr, "|"); \ + fprintf(stderr, "%s", #state); \ + first = false; \ + } + + CHECK_STATE(PM_LEX_STATE_BEG) + CHECK_STATE(PM_LEX_STATE_END) + CHECK_STATE(PM_LEX_STATE_ENDARG) + CHECK_STATE(PM_LEX_STATE_ENDFN) + CHECK_STATE(PM_LEX_STATE_ARG) + CHECK_STATE(PM_LEX_STATE_CMDARG) + CHECK_STATE(PM_LEX_STATE_MID) + CHECK_STATE(PM_LEX_STATE_FNAME) + CHECK_STATE(PM_LEX_STATE_DOT) + CHECK_STATE(PM_LEX_STATE_CLASS) + CHECK_STATE(PM_LEX_STATE_LABEL) + CHECK_STATE(PM_LEX_STATE_LABELED) + CHECK_STATE(PM_LEX_STATE_FITEM) + +#undef CHECK_STATE + + fprintf(stderr, "\n"); +} + +static void +debug_lex_state_set(pm_parser_t *parser, pm_lex_state_t state, char const * caller_name, int line_number) { + fprintf(stderr, "Caller: %s:%d\nPrevious: ", caller_name, line_number); + debug_state(parser); + lex_state_set(parser, state); + fprintf(stderr, "Now: "); + debug_state(parser); + fprintf(stderr, "\n"); +} + +#define lex_state_set(parser, state) debug_lex_state_set(parser, state, __func__, __LINE__) +#endif + +/******************************************************************************/ +/* Command-line macro helpers */ +/******************************************************************************/ + +/** True if the parser has the given command-line option. */ +#define PM_PARSER_COMMAND_LINE_OPTION(parser, option) ((parser)->command_line & (option)) + +/** True if the -a command line option was given. */ +#define PM_PARSER_COMMAND_LINE_OPTION_A(parser) PM_PARSER_COMMAND_LINE_OPTION(parser, PM_OPTIONS_COMMAND_LINE_A) + +/** True if the -e command line option was given. */ +#define PM_PARSER_COMMAND_LINE_OPTION_E(parser) PM_PARSER_COMMAND_LINE_OPTION(parser, PM_OPTIONS_COMMAND_LINE_E) + +/** True if the -l command line option was given. */ +#define PM_PARSER_COMMAND_LINE_OPTION_L(parser) PM_PARSER_COMMAND_LINE_OPTION(parser, PM_OPTIONS_COMMAND_LINE_L) + +/** True if the -n command line option was given. */ +#define PM_PARSER_COMMAND_LINE_OPTION_N(parser) PM_PARSER_COMMAND_LINE_OPTION(parser, PM_OPTIONS_COMMAND_LINE_N) + +/** True if the -p command line option was given. */ +#define PM_PARSER_COMMAND_LINE_OPTION_P(parser) PM_PARSER_COMMAND_LINE_OPTION(parser, PM_OPTIONS_COMMAND_LINE_P) + +/** True if the -x command line option was given. */ +#define PM_PARSER_COMMAND_LINE_OPTION_X(parser) PM_PARSER_COMMAND_LINE_OPTION(parser, PM_OPTIONS_COMMAND_LINE_X) + +/******************************************************************************/ +/* Diagnostic-related functions */ +/******************************************************************************/ + +/** + * Append an error to the list of errors on the parser. + */ +static inline void +pm_parser_err(pm_parser_t *parser, const uint8_t *start, const uint8_t *end, pm_diagnostic_id_t diag_id) { + pm_diagnostic_list_append(&parser->error_list, start, end, diag_id); +} + +/** + * Append an error to the list of errors on the parser using a format string. + */ +#define PM_PARSER_ERR_FORMAT(parser, start, end, diag_id, ...) \ + pm_diagnostic_list_append_format(&parser->error_list, start, end, diag_id, __VA_ARGS__) + +/** + * Append an error to the list of errors on the parser using the location of the + * current token. + */ +static inline void +pm_parser_err_current(pm_parser_t *parser, pm_diagnostic_id_t diag_id) { + pm_parser_err(parser, parser->current.start, parser->current.end, diag_id); +} + +/** + * Append an error to the list of errors on the parser using the given location + * using a format string. + */ +#define PM_PARSER_ERR_LOCATION_FORMAT(parser, location, diag_id, ...) \ + PM_PARSER_ERR_FORMAT(parser, (location)->start, (location)->end, diag_id, __VA_ARGS__) + +/** + * Append an error to the list of errors on the parser using the location of the + * given node. + */ +static inline void +pm_parser_err_node(pm_parser_t *parser, const pm_node_t *node, pm_diagnostic_id_t diag_id) { + pm_parser_err(parser, node->location.start, node->location.end, diag_id); +} + +/** + * Append an error to the list of errors on the parser using the location of the + * given node and a format string. + */ +#define PM_PARSER_ERR_NODE_FORMAT(parser, node, diag_id, ...) \ + PM_PARSER_ERR_FORMAT(parser, (node)->location.start, (node)->location.end, diag_id, __VA_ARGS__) + +/** + * Append an error to the list of errors on the parser using the location of the + * given node and a format string, and add on the content of the node. + */ +#define PM_PARSER_ERR_NODE_FORMAT_CONTENT(parser, node, diag_id) \ + PM_PARSER_ERR_NODE_FORMAT(parser, node, diag_id, (int) ((node)->location.end - (node)->location.start), (const char *) (node)->location.start) + +/** + * Append an error to the list of errors on the parser using the location of the + * previous token. + */ +static inline void +pm_parser_err_previous(pm_parser_t *parser, pm_diagnostic_id_t diag_id) { + pm_parser_err(parser, parser->previous.start, parser->previous.end, diag_id); +} + +/** + * Append an error to the list of errors on the parser using the location of the + * given token. + */ +static inline void +pm_parser_err_token(pm_parser_t *parser, const pm_token_t *token, pm_diagnostic_id_t diag_id) { + pm_parser_err(parser, token->start, token->end, diag_id); +} + +/** + * Append an error to the list of errors on the parser using the location of the + * given token and a format string. + */ +#define PM_PARSER_ERR_TOKEN_FORMAT(parser, token, diag_id, ...) \ + PM_PARSER_ERR_FORMAT(parser, (token).start, (token).end, diag_id, __VA_ARGS__) + +/** + * Append an error to the list of errors on the parser using the location of the + * given token and a format string, and add on the content of the token. + */ +#define PM_PARSER_ERR_TOKEN_FORMAT_CONTENT(parser, token, diag_id) \ + PM_PARSER_ERR_TOKEN_FORMAT(parser, token, diag_id, (int) ((token).end - (token).start), (const char *) (token).start) + +/** + * Append a warning to the list of warnings on the parser. + */ +static inline void +pm_parser_warn(pm_parser_t *parser, const uint8_t *start, const uint8_t *end, pm_diagnostic_id_t diag_id) { + pm_diagnostic_list_append(&parser->warning_list, start, end, diag_id); +} + +/** + * Append a warning to the list of warnings on the parser using the location of + * the given token. + */ +static inline void +pm_parser_warn_token(pm_parser_t *parser, const pm_token_t *token, pm_diagnostic_id_t diag_id) { + pm_parser_warn(parser, token->start, token->end, diag_id); +} + +/** + * Append a warning to the list of warnings on the parser using the location of + * the given node. + */ +static inline void +pm_parser_warn_node(pm_parser_t *parser, const pm_node_t *node, pm_diagnostic_id_t diag_id) { + pm_parser_warn(parser, node->location.start, node->location.end, diag_id); +} + +/** + * Append a warning to the list of warnings on the parser using a format string. + */ +#define PM_PARSER_WARN_FORMAT(parser, start, end, diag_id, ...) \ + pm_diagnostic_list_append_format(&parser->warning_list, start, end, diag_id, __VA_ARGS__) + +/** + * Append a warning to the list of warnings on the parser using the location of + * the given token and a format string. + */ +#define PM_PARSER_WARN_TOKEN_FORMAT(parser, token, diag_id, ...) \ + PM_PARSER_WARN_FORMAT(parser, (token).start, (token).end, diag_id, __VA_ARGS__) + +/** + * Append a warning to the list of warnings on the parser using the location of + * the given token and a format string, and add on the content of the token. + */ +#define PM_PARSER_WARN_TOKEN_FORMAT_CONTENT(parser, token, diag_id) \ + PM_PARSER_WARN_TOKEN_FORMAT(parser, token, diag_id, (int) ((token).end - (token).start), (const char *) (token).start) + +/** + * Append a warning to the list of warnings on the parser using the location of + * the given node and a format string. + */ +#define PM_PARSER_WARN_NODE_FORMAT(parser, node, diag_id, ...) \ + PM_PARSER_WARN_FORMAT(parser, (node)->location.start, (node)->location.end, diag_id, __VA_ARGS__) + +/** + * Add an error for an expected heredoc terminator. This is a special function + * only because it grabs its location off of a lex mode instead of a node or a + * token. + */ +static void +pm_parser_err_heredoc_term(pm_parser_t *parser, const uint8_t *ident_start, size_t ident_length) { + PM_PARSER_ERR_FORMAT( + parser, + ident_start, + ident_start + ident_length, + PM_ERR_HEREDOC_TERM, + (int) ident_length, + (const char *) ident_start + ); +} + +/******************************************************************************/ +/* Scope-related functions */ +/******************************************************************************/ + +/** + * Allocate and initialize a new scope. Push it onto the scope stack. + */ +static bool +pm_parser_scope_push(pm_parser_t *parser, bool closed) { + pm_scope_t *scope = (pm_scope_t *) xmalloc(sizeof(pm_scope_t)); + if (scope == NULL) return false; + + *scope = (pm_scope_t) { + .previous = parser->current_scope, + .locals = { 0 }, + .parameters = PM_SCOPE_PARAMETERS_NONE, + .implicit_parameters = { 0 }, + .shareable_constant = parser->current_scope == NULL ? PM_SCOPE_SHAREABLE_CONSTANT_NONE : parser->current_scope->shareable_constant, + .closed = closed + }; + + parser->current_scope = scope; + return true; +} + +/** + * Determine if the current scope is at the top level. This means it is either + * the top-level scope or it is open to the top-level. + */ +static bool +pm_parser_scope_toplevel_p(pm_parser_t *parser) { + pm_scope_t *scope = parser->current_scope; + + do { + if (scope->previous == NULL) return true; + if (scope->closed) return false; + } while ((scope = scope->previous) != NULL); + + assert(false && "unreachable"); + return true; +} + +/** + * Retrieve the scope at the given depth. + */ +static pm_scope_t * +pm_parser_scope_find(pm_parser_t *parser, uint32_t depth) { + pm_scope_t *scope = parser->current_scope; + + while (depth-- > 0) { + assert(scope != NULL); + scope = scope->previous; + } + + return scope; +} + +typedef enum { + PM_SCOPE_FORWARDING_PARAM_CHECK_RESULT_PASS, + PM_SCOPE_FORWARDING_PARAM_CHECK_RESULT_CONFLICT, + PM_SCOPE_FORWARDING_PARAM_CHECK_RESULT_FAIL +} pm_scope_forwarding_param_check_result_t; + +static pm_scope_forwarding_param_check_result_t +pm_parser_scope_forwarding_param_check(pm_parser_t *parser, const uint8_t mask) { + pm_scope_t *scope = parser->current_scope; + bool conflict = false; + + while (scope != NULL) { + if (scope->parameters & mask) { + if (scope->closed) { + if (conflict) { + return PM_SCOPE_FORWARDING_PARAM_CHECK_RESULT_CONFLICT; + } else { + return PM_SCOPE_FORWARDING_PARAM_CHECK_RESULT_PASS; + } + } + + conflict = true; + } + + if (scope->closed) break; + scope = scope->previous; + } + + return PM_SCOPE_FORWARDING_PARAM_CHECK_RESULT_FAIL; +} + +static void +pm_parser_scope_forwarding_block_check(pm_parser_t *parser, const pm_token_t * token) { + switch (pm_parser_scope_forwarding_param_check(parser, PM_SCOPE_PARAMETERS_FORWARDING_BLOCK)) { + case PM_SCOPE_FORWARDING_PARAM_CHECK_RESULT_PASS: + // Pass. + break; + case PM_SCOPE_FORWARDING_PARAM_CHECK_RESULT_CONFLICT: + pm_parser_err_token(parser, token, PM_ERR_ARGUMENT_CONFLICT_AMPERSAND); + break; + case PM_SCOPE_FORWARDING_PARAM_CHECK_RESULT_FAIL: + pm_parser_err_token(parser, token, PM_ERR_ARGUMENT_NO_FORWARDING_AMPERSAND); + break; + } +} + +static void +pm_parser_scope_forwarding_positionals_check(pm_parser_t *parser, const pm_token_t * token) { + switch (pm_parser_scope_forwarding_param_check(parser, PM_SCOPE_PARAMETERS_FORWARDING_POSITIONALS)) { + case PM_SCOPE_FORWARDING_PARAM_CHECK_RESULT_PASS: + // Pass. + break; + case PM_SCOPE_FORWARDING_PARAM_CHECK_RESULT_CONFLICT: + pm_parser_err_token(parser, token, PM_ERR_ARGUMENT_CONFLICT_STAR); + break; + case PM_SCOPE_FORWARDING_PARAM_CHECK_RESULT_FAIL: + pm_parser_err_token(parser, token, PM_ERR_ARGUMENT_NO_FORWARDING_STAR); + break; + } +} + +static void +pm_parser_scope_forwarding_all_check(pm_parser_t *parser, const pm_token_t *token) { + switch (pm_parser_scope_forwarding_param_check(parser, PM_SCOPE_PARAMETERS_FORWARDING_ALL)) { + case PM_SCOPE_FORWARDING_PARAM_CHECK_RESULT_PASS: + // Pass. + break; + case PM_SCOPE_FORWARDING_PARAM_CHECK_RESULT_CONFLICT: + // This shouldn't happen, because ... is not allowed in the + // declaration of blocks. If we get here, we assume we already have + // an error for this. + break; + case PM_SCOPE_FORWARDING_PARAM_CHECK_RESULT_FAIL: + pm_parser_err_token(parser, token, PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES); + break; + } +} + +static void +pm_parser_scope_forwarding_keywords_check(pm_parser_t *parser, const pm_token_t * token) { + switch (pm_parser_scope_forwarding_param_check(parser, PM_SCOPE_PARAMETERS_FORWARDING_KEYWORDS)) { + case PM_SCOPE_FORWARDING_PARAM_CHECK_RESULT_PASS: + // Pass. + break; + case PM_SCOPE_FORWARDING_PARAM_CHECK_RESULT_CONFLICT: + pm_parser_err_token(parser, token, PM_ERR_ARGUMENT_CONFLICT_STAR_STAR); + break; + case PM_SCOPE_FORWARDING_PARAM_CHECK_RESULT_FAIL: + pm_parser_err_token(parser, token, PM_ERR_ARGUMENT_NO_FORWARDING_STAR_STAR); + break; + } +} + +/** + * Get the current state of constant shareability. + */ +static inline pm_shareable_constant_value_t +pm_parser_scope_shareable_constant_get(pm_parser_t *parser) { + return parser->current_scope->shareable_constant; +} + +/** + * Set the current state of constant shareability. We'll set it on all of the + * open scopes so that reads are quick. + */ +static void +pm_parser_scope_shareable_constant_set(pm_parser_t *parser, pm_shareable_constant_value_t shareable_constant) { + pm_scope_t *scope = parser->current_scope; + + do { + scope->shareable_constant = shareable_constant; + } while (!scope->closed && (scope = scope->previous) != NULL); +} + +/******************************************************************************/ +/* Local variable-related functions */ +/******************************************************************************/ + +/** + * The point at which the set of locals switches from being a list to a hash. + */ +#define PM_LOCALS_HASH_THRESHOLD 9 + +static void +pm_locals_free(pm_locals_t *locals) { + if (locals->capacity > 0) { + xfree(locals->locals); + } +} + +/** + * Use as simple and fast a hash function as we can that still properly mixes + * the bits. + */ +static uint32_t +pm_locals_hash(pm_constant_id_t name) { + name = ((name >> 16) ^ name) * 0x45d9f3b; + name = ((name >> 16) ^ name) * 0x45d9f3b; + name = (name >> 16) ^ name; + return name; +} + +/** + * Resize the locals list to be twice its current size. If the next capacity is + * above the threshold for switching to a hash, then we'll switch to a hash. + */ +static void +pm_locals_resize(pm_locals_t *locals) { + uint32_t next_capacity = locals->capacity == 0 ? 4 : (locals->capacity * 2); + assert(next_capacity > locals->capacity); + + pm_local_t *next_locals = xcalloc(next_capacity, sizeof(pm_local_t)); + if (next_locals == NULL) abort(); + + if (next_capacity < PM_LOCALS_HASH_THRESHOLD) { + if (locals->size > 0) { + memcpy(next_locals, locals->locals, locals->size * sizeof(pm_local_t)); + } + } else { + // If we just switched from a list to a hash, then we need to fill in + // the hash values of all of the locals. + bool hash_needed = (locals->capacity <= PM_LOCALS_HASH_THRESHOLD); + uint32_t mask = next_capacity - 1; + + for (uint32_t index = 0; index < locals->capacity; index++) { + pm_local_t *local = &locals->locals[index]; + + if (local->name != PM_CONSTANT_ID_UNSET) { + if (hash_needed) local->hash = pm_locals_hash(local->name); + + uint32_t hash = local->hash; + while (next_locals[hash & mask].name != PM_CONSTANT_ID_UNSET) hash++; + next_locals[hash & mask] = *local; + } + } + } + + pm_locals_free(locals); + locals->locals = next_locals; + locals->capacity = next_capacity; +} + +/** + * Add a new local to the set of locals. This will automatically rehash the + * locals if the size is greater than 3/4 of the capacity. + * + * @param locals The set of locals to add to. + * @param name The name of the local. + * @param start The source location that represents the start of the local. This + * is used for the location of the warning in case this local is not read. + * @param end The source location that represents the end of the local. This is + * used for the location of the warning in case this local is not read. + * @param reads The initial number of reads for this local. Usually this is set + * to 0, but for some locals (like parameters) we want to initialize it with + * 1 so that we never warn on unused parameters. + * @return True if the local was added, and false if the local already exists. + */ +static bool +pm_locals_write(pm_locals_t *locals, pm_constant_id_t name, const uint8_t *start, const uint8_t *end, uint32_t reads) { + if (locals->size >= (locals->capacity / 4 * 3)) { + pm_locals_resize(locals); + } + + if (locals->capacity < PM_LOCALS_HASH_THRESHOLD) { + for (uint32_t index = 0; index < locals->capacity; index++) { + pm_local_t *local = &locals->locals[index]; + + if (local->name == PM_CONSTANT_ID_UNSET) { + *local = (pm_local_t) { + .name = name, + .location = { .start = start, .end = end }, + .index = locals->size++, + .reads = reads, + .hash = 0 + }; + return true; + } else if (local->name == name) { + return false; + } + } + } else { + uint32_t mask = locals->capacity - 1; + uint32_t hash = pm_locals_hash(name); + uint32_t initial_hash = hash; + + do { + pm_local_t *local = &locals->locals[hash & mask]; + + if (local->name == PM_CONSTANT_ID_UNSET) { + *local = (pm_local_t) { + .name = name, + .location = { .start = start, .end = end }, + .index = locals->size++, + .reads = reads, + .hash = initial_hash + }; + return true; + } else if (local->name == name) { + return false; + } else { + hash++; + } + } while ((hash & mask) != initial_hash); + } + + assert(false && "unreachable"); + return true; +} + +/** + * Finds the index of a local variable in the locals set. If it is not found, + * this returns UINT32_MAX. + */ +static uint32_t +pm_locals_find(pm_locals_t *locals, pm_constant_id_t name) { + if (locals->capacity < PM_LOCALS_HASH_THRESHOLD) { + for (uint32_t index = 0; index < locals->size; index++) { + pm_local_t *local = &locals->locals[index]; + if (local->name == name) return index; + } + } else { + uint32_t mask = locals->capacity - 1; + uint32_t hash = pm_locals_hash(name); + uint32_t initial_hash = hash & mask; + + do { + pm_local_t *local = &locals->locals[hash & mask]; + + if (local->name == PM_CONSTANT_ID_UNSET) { + return UINT32_MAX; + } else if (local->name == name) { + return hash & mask; + } else { + hash++; + } + } while ((hash & mask) != initial_hash); + } + + return UINT32_MAX; +} + +/** + * Called when a variable is read in a certain lexical context. Tracks the read + * by adding to the reads count. + */ +static void +pm_locals_read(pm_locals_t *locals, pm_constant_id_t name) { + uint32_t index = pm_locals_find(locals, name); + assert(index != UINT32_MAX); + + pm_local_t *local = &locals->locals[index]; + assert(local->reads < UINT32_MAX); + + local->reads++; +} + +/** + * Called when a variable read is transformed into a variable write, because a + * write operator is found after the variable name. + */ +static void +pm_locals_unread(pm_locals_t *locals, pm_constant_id_t name) { + uint32_t index = pm_locals_find(locals, name); + assert(index != UINT32_MAX); + + pm_local_t *local = &locals->locals[index]; + assert(local->reads > 0); + + local->reads--; +} + +/** + * Returns the current number of reads for a local variable. + */ +static uint32_t +pm_locals_reads(pm_locals_t *locals, pm_constant_id_t name) { + uint32_t index = pm_locals_find(locals, name); + assert(index != UINT32_MAX); + + return locals->locals[index].reads; +} + +/** + * Write out the locals into the given list of constant ids in the correct + * order. This is used to set the list of locals on the nodes in the tree once + * we're sure no additional locals will be added to the set. + * + * This function is also responsible for warning when a local variable has been + * written but not read in certain contexts. + */ +static void +pm_locals_order(PRISM_ATTRIBUTE_UNUSED pm_parser_t *parser, pm_locals_t *locals, pm_constant_id_list_t *list, bool toplevel) { + pm_constant_id_list_init_capacity(list, locals->size); + + // If we're still below the threshold for switching to a hash, then we only + // need to loop over the locals until we hit the size because the locals are + // stored in a list. + uint32_t capacity = locals->capacity < PM_LOCALS_HASH_THRESHOLD ? locals->size : locals->capacity; + + // We will only warn for unused variables if we're not at the top level, or + // if we're parsing a file outside of eval or -e. + bool warn_unused = !toplevel || (!parser->parsing_eval && !PM_PARSER_COMMAND_LINE_OPTION_E(parser)); + + for (uint32_t index = 0; index < capacity; index++) { + pm_local_t *local = &locals->locals[index]; + + if (local->name != PM_CONSTANT_ID_UNSET) { + pm_constant_id_list_insert(list, (size_t) local->index, local->name); + + if (warn_unused && local->reads == 0 && ((parser->start_line >= 0) || (pm_newline_list_line(&parser->newline_list, local->location.start, parser->start_line) >= 0))) { + pm_constant_t *constant = pm_constant_pool_id_to_constant(&parser->constant_pool, local->name); + + if (constant->length >= 1 && *constant->start != '_') { + PM_PARSER_WARN_FORMAT( + parser, + local->location.start, + local->location.end, + PM_WARN_UNUSED_LOCAL_VARIABLE, + (int) constant->length, + (const char *) constant->start + ); + } + } + } + } +} + +/******************************************************************************/ +/* Node-related functions */ +/******************************************************************************/ + +/** + * Retrieve the constant pool id for the given location. + */ +static inline pm_constant_id_t +pm_parser_constant_id_location(pm_parser_t *parser, const uint8_t *start, const uint8_t *end) { + return pm_constant_pool_insert_shared(&parser->constant_pool, start, (size_t) (end - start)); +} + +/** + * Retrieve the constant pool id for the given string. + */ +static inline pm_constant_id_t +pm_parser_constant_id_owned(pm_parser_t *parser, uint8_t *start, size_t length) { + return pm_constant_pool_insert_owned(&parser->constant_pool, start, length); +} + +/** + * Retrieve the constant pool id for the given static literal C string. + */ +static inline pm_constant_id_t +pm_parser_constant_id_constant(pm_parser_t *parser, const char *start, size_t length) { + return pm_constant_pool_insert_constant(&parser->constant_pool, (const uint8_t *) start, length); +} + +/** + * Retrieve the constant pool id for the given token. + */ +static inline pm_constant_id_t +pm_parser_constant_id_token(pm_parser_t *parser, const pm_token_t *token) { + return pm_parser_constant_id_location(parser, token->start, token->end); +} + +/** + * Retrieve the constant pool id for the given token. If the token is not + * provided, then return 0. + */ +static inline pm_constant_id_t +pm_parser_optional_constant_id_token(pm_parser_t *parser, const pm_token_t *token) { + return token->type == PM_TOKEN_NOT_PROVIDED ? 0 : pm_parser_constant_id_token(parser, token); +} + +/** + * Check whether or not the given node is value expression. + * If the node is value node, it returns NULL. + * If not, it returns the pointer to the node to be inspected as "void expression". + */ +static pm_node_t * +pm_check_value_expression(pm_parser_t *parser, pm_node_t *node) { + pm_node_t *void_node = NULL; + + while (node != NULL) { + switch (PM_NODE_TYPE(node)) { + case PM_RETURN_NODE: + case PM_BREAK_NODE: + case PM_NEXT_NODE: + case PM_REDO_NODE: + case PM_RETRY_NODE: + case PM_MATCH_REQUIRED_NODE: + return void_node != NULL ? void_node : node; + case PM_MATCH_PREDICATE_NODE: + return NULL; + case PM_BEGIN_NODE: { + pm_begin_node_t *cast = (pm_begin_node_t *) node; + + if (cast->ensure_clause != NULL) { + if (cast->rescue_clause != NULL) { + pm_node_t *vn = pm_check_value_expression(parser, (pm_node_t *) cast->rescue_clause); + if (vn != NULL) return vn; + } + + if (cast->statements != NULL) { + pm_node_t *vn = pm_check_value_expression(parser, (pm_node_t *) cast->statements); + if (vn != NULL) return vn; + } + + node = (pm_node_t *) cast->ensure_clause; + } else if (cast->rescue_clause != NULL) { + if (cast->statements == NULL) return NULL; + + pm_node_t *vn = pm_check_value_expression(parser, (pm_node_t *) cast->statements); + if (vn == NULL) return NULL; + if (void_node == NULL) void_node = vn; + + for (pm_rescue_node_t *rescue_clause = cast->rescue_clause; rescue_clause != NULL; rescue_clause = rescue_clause->subsequent) { + pm_node_t *vn = pm_check_value_expression(parser, (pm_node_t *) rescue_clause->statements); + if (vn == NULL) { + void_node = NULL; + break; + } + if (void_node == NULL) { + void_node = vn; + } + } + + if (cast->else_clause != NULL) { + node = (pm_node_t *) cast->else_clause; + } else { + return void_node; + } + } else { + node = (pm_node_t *) cast->statements; + } + + break; + } + case PM_ENSURE_NODE: { + pm_ensure_node_t *cast = (pm_ensure_node_t *) node; + node = (pm_node_t *) cast->statements; + break; + } + case PM_PARENTHESES_NODE: { + pm_parentheses_node_t *cast = (pm_parentheses_node_t *) node; + node = (pm_node_t *) cast->body; + break; + } + case PM_STATEMENTS_NODE: { + pm_statements_node_t *cast = (pm_statements_node_t *) node; + node = cast->body.nodes[cast->body.size - 1]; + break; + } + case PM_IF_NODE: { + pm_if_node_t *cast = (pm_if_node_t *) node; + if (cast->statements == NULL || cast->subsequent == NULL) { + return NULL; + } + pm_node_t *vn = pm_check_value_expression(parser, (pm_node_t *) cast->statements); + if (vn == NULL) { + return NULL; + } + if (void_node == NULL) { + void_node = vn; + } + node = cast->subsequent; + break; + } + case PM_UNLESS_NODE: { + pm_unless_node_t *cast = (pm_unless_node_t *) node; + if (cast->statements == NULL || cast->else_clause == NULL) { + return NULL; + } + pm_node_t *vn = pm_check_value_expression(parser, (pm_node_t *) cast->statements); + if (vn == NULL) { + return NULL; + } + if (void_node == NULL) { + void_node = vn; + } + node = (pm_node_t *) cast->else_clause; + break; + } + case PM_ELSE_NODE: { + pm_else_node_t *cast = (pm_else_node_t *) node; + node = (pm_node_t *) cast->statements; + break; + } + case PM_AND_NODE: { + pm_and_node_t *cast = (pm_and_node_t *) node; + node = cast->left; + break; + } + case PM_OR_NODE: { + pm_or_node_t *cast = (pm_or_node_t *) node; + node = cast->left; + break; + } + case PM_LOCAL_VARIABLE_WRITE_NODE: { + pm_local_variable_write_node_t *cast = (pm_local_variable_write_node_t *) node; + + pm_scope_t *scope = parser->current_scope; + for (uint32_t depth = 0; depth < cast->depth; depth++) scope = scope->previous; + + pm_locals_read(&scope->locals, cast->name); + return NULL; + } + default: + return NULL; + } + } + + return NULL; +} + +static inline void +pm_assert_value_expression(pm_parser_t *parser, pm_node_t *node) { + pm_node_t *void_node = pm_check_value_expression(parser, node); + if (void_node != NULL) { + pm_parser_err_node(parser, void_node, PM_ERR_VOID_EXPRESSION); + } +} + +/** + * Warn if the given node is a "void" statement. + */ +static void +pm_void_statement_check(pm_parser_t *parser, const pm_node_t *node) { + const char *type = NULL; + int length = 0; + + switch (PM_NODE_TYPE(node)) { + case PM_BACK_REFERENCE_READ_NODE: + case PM_CLASS_VARIABLE_READ_NODE: + case PM_GLOBAL_VARIABLE_READ_NODE: + case PM_INSTANCE_VARIABLE_READ_NODE: + case PM_LOCAL_VARIABLE_READ_NODE: + case PM_NUMBERED_REFERENCE_READ_NODE: + type = "a variable"; + length = 10; + break; + case PM_CALL_NODE: { + const pm_call_node_t *cast = (const pm_call_node_t *) node; + if (cast->call_operator_loc.start != NULL || cast->message_loc.start == NULL) break; + + const pm_constant_t *message = pm_constant_pool_id_to_constant(&parser->constant_pool, cast->name); + switch (message->length) { + case 1: + switch (message->start[0]) { + case '+': + case '-': + case '*': + case '/': + case '%': + case '|': + case '^': + case '&': + case '>': + case '<': + type = (const char *) message->start; + length = 1; + break; + } + break; + case 2: + switch (message->start[1]) { + case '=': + if (message->start[0] == '<' || message->start[0] == '>' || message->start[0] == '!' || message->start[0] == '=') { + type = (const char *) message->start; + length = 2; + } + break; + case '@': + if (message->start[0] == '+' || message->start[0] == '-') { + type = (const char *) message->start; + length = 2; + } + break; + case '*': + if (message->start[0] == '*') { + type = (const char *) message->start; + length = 2; + } + break; + } + break; + case 3: + if (memcmp(message->start, "<=>", 3) == 0) { + type = "<=>"; + length = 3; + } + break; + } + + break; + } + case PM_CONSTANT_PATH_NODE: + type = "::"; + length = 2; + break; + case PM_CONSTANT_READ_NODE: + type = "a constant"; + length = 10; + break; + case PM_DEFINED_NODE: + type = "defined?"; + length = 8; + break; + case PM_FALSE_NODE: + type = "false"; + length = 5; + break; + case PM_FLOAT_NODE: + case PM_IMAGINARY_NODE: + case PM_INTEGER_NODE: + case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE: + case PM_INTERPOLATED_STRING_NODE: + case PM_RATIONAL_NODE: + case PM_REGULAR_EXPRESSION_NODE: + case PM_SOURCE_ENCODING_NODE: + case PM_SOURCE_FILE_NODE: + case PM_SOURCE_LINE_NODE: + case PM_STRING_NODE: + case PM_SYMBOL_NODE: + type = "a literal"; + length = 9; + break; + case PM_NIL_NODE: + type = "nil"; + length = 3; + break; + case PM_RANGE_NODE: { + const pm_range_node_t *cast = (const pm_range_node_t *) node; + + if (PM_NODE_FLAG_P(cast, PM_RANGE_FLAGS_EXCLUDE_END)) { + type = "..."; + length = 3; + } else { + type = ".."; + length = 2; + } + + break; + } + case PM_SELF_NODE: + type = "self"; + length = 4; + break; + case PM_TRUE_NODE: + type = "true"; + length = 4; + break; + default: + break; + } + + if (type != NULL) { + PM_PARSER_WARN_NODE_FORMAT(parser, node, PM_WARN_VOID_STATEMENT, length, type); + } +} + +/** + * Warn if any of the statements that are not the last statement in the list are + * a "void" statement. + */ +static void +pm_void_statements_check(pm_parser_t *parser, const pm_statements_node_t *node, bool last_value) { + assert(node->body.size > 0); + const size_t size = node->body.size - (last_value ? 1 : 0); + for (size_t index = 0; index < size; index++) { + pm_void_statement_check(parser, node->body.nodes[index]); + } +} + +/** + * When we're handling the predicate of a conditional, we need to know our + * context in order to determine the kind of warning we should deliver to the + * user. + */ +typedef enum { + PM_CONDITIONAL_PREDICATE_TYPE_CONDITIONAL, + PM_CONDITIONAL_PREDICATE_TYPE_FLIP_FLOP, + PM_CONDITIONAL_PREDICATE_TYPE_NOT +} pm_conditional_predicate_type_t; + +/** + * Add a warning to the parser if the predicate of a conditional is a literal. + */ +static void +pm_parser_warn_conditional_predicate_literal(pm_parser_t *parser, pm_node_t *node, pm_conditional_predicate_type_t type, pm_diagnostic_id_t diag_id, const char *prefix) { + switch (type) { + case PM_CONDITIONAL_PREDICATE_TYPE_CONDITIONAL: + PM_PARSER_WARN_NODE_FORMAT(parser, node, diag_id, prefix, "condition"); + break; + case PM_CONDITIONAL_PREDICATE_TYPE_FLIP_FLOP: + PM_PARSER_WARN_NODE_FORMAT(parser, node, diag_id, prefix, "flip-flop"); + break; + case PM_CONDITIONAL_PREDICATE_TYPE_NOT: + break; + } +} + +/** + * Return true if the value being written within the predicate of a conditional + * is a literal value. + */ +static bool +pm_conditional_predicate_warn_write_literal_p(const pm_node_t *node) { + switch (PM_NODE_TYPE(node)) { + case PM_ARRAY_NODE: { + if (PM_NODE_FLAG_P(node, PM_NODE_FLAG_STATIC_LITERAL)) return true; + + const pm_array_node_t *cast = (const pm_array_node_t *) node; + for (size_t index = 0; index < cast->elements.size; index++) { + if (!pm_conditional_predicate_warn_write_literal_p(cast->elements.nodes[index])) return false; + } + + return true; + } + case PM_HASH_NODE: { + if (PM_NODE_FLAG_P(node, PM_NODE_FLAG_STATIC_LITERAL)) return true; + + const pm_hash_node_t *cast = (const pm_hash_node_t *) node; + for (size_t index = 0; index < cast->elements.size; index++) { + const pm_node_t *element = cast->elements.nodes[index]; + if (!PM_NODE_TYPE_P(element, PM_ASSOC_NODE)) return false; + + const pm_assoc_node_t *assoc = (const pm_assoc_node_t *) element; + if (!pm_conditional_predicate_warn_write_literal_p(assoc->key) || !pm_conditional_predicate_warn_write_literal_p(assoc->value)) return false; + } + + return true; + } + case PM_FALSE_NODE: + case PM_FLOAT_NODE: + case PM_IMAGINARY_NODE: + case PM_INTEGER_NODE: + case PM_NIL_NODE: + case PM_RATIONAL_NODE: + case PM_REGULAR_EXPRESSION_NODE: + case PM_SOURCE_ENCODING_NODE: + case PM_SOURCE_FILE_NODE: + case PM_SOURCE_LINE_NODE: + case PM_STRING_NODE: + case PM_SYMBOL_NODE: + case PM_TRUE_NODE: + return true; + default: + return false; + } +} + +/** + * Add a warning to the parser if the value that is being written inside of a + * predicate to a conditional is a literal. + */ +static inline void +pm_conditional_predicate_warn_write_literal(pm_parser_t *parser, const pm_node_t *node) { + if (pm_conditional_predicate_warn_write_literal_p(node)) { + pm_parser_warn_node(parser, node, parser->version == PM_OPTIONS_VERSION_CRUBY_3_3 ? PM_WARN_EQUAL_IN_CONDITIONAL_3_3 : PM_WARN_EQUAL_IN_CONDITIONAL); + } +} + +/** + * The predicate of conditional nodes can change what would otherwise be regular + * nodes into specialized nodes. For example: + * + * if foo .. bar => RangeNode becomes FlipFlopNode + * if foo and bar .. baz => RangeNode becomes FlipFlopNode + * if /foo/ => RegularExpressionNode becomes MatchLastLineNode + * if /foo #{bar}/ => InterpolatedRegularExpressionNode becomes InterpolatedMatchLastLineNode + * + * We also want to warn the user if they're using a static literal as a + * predicate or writing a static literal as the predicate. + */ +static void +pm_conditional_predicate(pm_parser_t *parser, pm_node_t *node, pm_conditional_predicate_type_t type) { + switch (PM_NODE_TYPE(node)) { + case PM_AND_NODE: { + pm_and_node_t *cast = (pm_and_node_t *) node; + pm_conditional_predicate(parser, cast->left, PM_CONDITIONAL_PREDICATE_TYPE_CONDITIONAL); + pm_conditional_predicate(parser, cast->right, PM_CONDITIONAL_PREDICATE_TYPE_CONDITIONAL); + break; + } + case PM_OR_NODE: { + pm_or_node_t *cast = (pm_or_node_t *) node; + pm_conditional_predicate(parser, cast->left, PM_CONDITIONAL_PREDICATE_TYPE_CONDITIONAL); + pm_conditional_predicate(parser, cast->right, PM_CONDITIONAL_PREDICATE_TYPE_CONDITIONAL); + break; + } + case PM_PARENTHESES_NODE: { + pm_parentheses_node_t *cast = (pm_parentheses_node_t *) node; + + if ((cast->body != NULL) && PM_NODE_TYPE_P(cast->body, PM_STATEMENTS_NODE)) { + pm_statements_node_t *statements = (pm_statements_node_t *) cast->body; + if (statements->body.size == 1) pm_conditional_predicate(parser, statements->body.nodes[0], type); + } + + break; + } + case PM_BEGIN_NODE: { + pm_begin_node_t *cast = (pm_begin_node_t *) node; + if (cast->statements != NULL) { + pm_statements_node_t *statements = cast->statements; + if (statements->body.size == 1) pm_conditional_predicate(parser, statements->body.nodes[0], type); + } + break; + } + case PM_RANGE_NODE: { + pm_range_node_t *cast = (pm_range_node_t *) node; + + if (cast->left != NULL) pm_conditional_predicate(parser, cast->left, PM_CONDITIONAL_PREDICATE_TYPE_FLIP_FLOP); + if (cast->right != NULL) pm_conditional_predicate(parser, cast->right, PM_CONDITIONAL_PREDICATE_TYPE_FLIP_FLOP); + + // Here we change the range node into a flip flop node. We can do + // this since the nodes are exactly the same except for the type. + // We're only asserting against the size when we should probably + // assert against the entire layout, but we'll assume tests will + // catch this. + assert(sizeof(pm_range_node_t) == sizeof(pm_flip_flop_node_t)); + node->type = PM_FLIP_FLOP_NODE; + + break; + } + case PM_REGULAR_EXPRESSION_NODE: + // Here we change the regular expression node into a match last line + // node. We can do this since the nodes are exactly the same except + // for the type. + assert(sizeof(pm_regular_expression_node_t) == sizeof(pm_match_last_line_node_t)); + node->type = PM_MATCH_LAST_LINE_NODE; + + if (!PM_PARSER_COMMAND_LINE_OPTION_E(parser)) { + pm_parser_warn_conditional_predicate_literal(parser, node, type, PM_WARN_LITERAL_IN_CONDITION_DEFAULT, "regex "); + } + + break; + case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE: + // Here we change the interpolated regular expression node into an + // interpolated match last line node. We can do this since the nodes + // are exactly the same except for the type. + assert(sizeof(pm_interpolated_regular_expression_node_t) == sizeof(pm_interpolated_match_last_line_node_t)); + node->type = PM_INTERPOLATED_MATCH_LAST_LINE_NODE; + + if (!PM_PARSER_COMMAND_LINE_OPTION_E(parser)) { + pm_parser_warn_conditional_predicate_literal(parser, node, type, PM_WARN_LITERAL_IN_CONDITION_VERBOSE, "regex "); + } + + break; + case PM_INTEGER_NODE: + if (type == PM_CONDITIONAL_PREDICATE_TYPE_FLIP_FLOP) { + if (!PM_PARSER_COMMAND_LINE_OPTION_E(parser)) { + pm_parser_warn_node(parser, node, PM_WARN_INTEGER_IN_FLIP_FLOP); + } + } else { + pm_parser_warn_conditional_predicate_literal(parser, node, type, PM_WARN_LITERAL_IN_CONDITION_VERBOSE, ""); + } + break; + case PM_STRING_NODE: + case PM_SOURCE_FILE_NODE: + case PM_INTERPOLATED_STRING_NODE: + pm_parser_warn_conditional_predicate_literal(parser, node, type, PM_WARN_LITERAL_IN_CONDITION_DEFAULT, "string "); + break; + case PM_SYMBOL_NODE: + case PM_INTERPOLATED_SYMBOL_NODE: + pm_parser_warn_conditional_predicate_literal(parser, node, type, PM_WARN_LITERAL_IN_CONDITION_VERBOSE, "symbol "); + break; + case PM_SOURCE_LINE_NODE: + case PM_SOURCE_ENCODING_NODE: + case PM_FLOAT_NODE: + case PM_RATIONAL_NODE: + case PM_IMAGINARY_NODE: + pm_parser_warn_conditional_predicate_literal(parser, node, type, PM_WARN_LITERAL_IN_CONDITION_VERBOSE, ""); + break; + case PM_CLASS_VARIABLE_WRITE_NODE: + pm_conditional_predicate_warn_write_literal(parser, ((pm_class_variable_write_node_t *) node)->value); + break; + case PM_CONSTANT_WRITE_NODE: + pm_conditional_predicate_warn_write_literal(parser, ((pm_constant_write_node_t *) node)->value); + break; + case PM_GLOBAL_VARIABLE_WRITE_NODE: + pm_conditional_predicate_warn_write_literal(parser, ((pm_global_variable_write_node_t *) node)->value); + break; + case PM_INSTANCE_VARIABLE_WRITE_NODE: + pm_conditional_predicate_warn_write_literal(parser, ((pm_instance_variable_write_node_t *) node)->value); + break; + case PM_LOCAL_VARIABLE_WRITE_NODE: + pm_conditional_predicate_warn_write_literal(parser, ((pm_local_variable_write_node_t *) node)->value); + break; + case PM_MULTI_WRITE_NODE: + pm_conditional_predicate_warn_write_literal(parser, ((pm_multi_write_node_t *) node)->value); + break; + default: + break; + } +} + +/** + * In a lot of places in the tree you can have tokens that are not provided but + * that do not cause an error. For example, this happens in a method call + * without parentheses. In these cases we set the token to the "not provided" type. + * For example: + * + * pm_token_t token = not_provided(parser); + */ +static inline pm_token_t +not_provided(pm_parser_t *parser) { + return (pm_token_t) { .type = PM_TOKEN_NOT_PROVIDED, .start = parser->start, .end = parser->start }; +} + +#define PM_LOCATION_NULL_VALUE(parser) ((pm_location_t) { .start = (parser)->start, .end = (parser)->start }) +#define PM_LOCATION_TOKEN_VALUE(token) ((pm_location_t) { .start = (token)->start, .end = (token)->end }) +#define PM_LOCATION_NODE_VALUE(node) ((pm_location_t) { .start = (node)->location.start, .end = (node)->location.end }) +#define PM_LOCATION_NODE_BASE_VALUE(node) ((pm_location_t) { .start = (node)->base.location.start, .end = (node)->base.location.end }) +#define PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE ((pm_location_t) { .start = NULL, .end = NULL }) +#define PM_OPTIONAL_LOCATION_TOKEN_VALUE(token) ((token)->type == PM_TOKEN_NOT_PROVIDED ? PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE : PM_LOCATION_TOKEN_VALUE(token)) + +/** + * This is a special out parameter to the parse_arguments_list function that + * includes opening and closing parentheses in addition to the arguments since + * it's so common. It is handy to use when passing argument information to one + * of the call node creation functions. + */ +typedef struct { + /** The optional location of the opening parenthesis or bracket. */ + pm_location_t opening_loc; + + /** The lazily-allocated optional arguments node. */ + pm_arguments_node_t *arguments; + + /** The optional location of the closing parenthesis or bracket. */ + pm_location_t closing_loc; + + /** The optional block attached to the call. */ + pm_node_t *block; + + /** The flag indicating whether this arguments list has forwarding argument. */ + bool has_forwarding; +} pm_arguments_t; + +/** + * Retrieve the end location of a `pm_arguments_t` object. + */ +static inline const uint8_t * +pm_arguments_end(pm_arguments_t *arguments) { + if (arguments->block != NULL) { + const uint8_t *end = arguments->block->location.end; + if (arguments->closing_loc.start != NULL && arguments->closing_loc.end > end) { + end = arguments->closing_loc.end; + } + return end; + } + if (arguments->closing_loc.start != NULL) { + return arguments->closing_loc.end; + } + if (arguments->arguments != NULL) { + return arguments->arguments->base.location.end; + } + return arguments->closing_loc.end; +} + +/** + * Check that we're not about to attempt to attach a brace block to a call that + * has arguments without parentheses. + */ +static void +pm_arguments_validate_block(pm_parser_t *parser, pm_arguments_t *arguments, pm_block_node_t *block) { + // First, check that we have arguments and that we don't have a closing + // location for them. + if (arguments->arguments == NULL || arguments->closing_loc.start != NULL) { + return; + } + + // Next, check that we don't have a single parentheses argument. This would + // look like: + // + // foo (1) {} + // + // In this case, it's actually okay for the block to be attached to the + // call, even though it looks like it's attached to the argument. + if (arguments->arguments->arguments.size == 1 && PM_NODE_TYPE_P(arguments->arguments->arguments.nodes[0], PM_PARENTHESES_NODE)) { + return; + } + + // If we didn't hit a case before this check, then at this point we need to + // add a syntax error. + pm_parser_err_node(parser, (pm_node_t *) block, PM_ERR_ARGUMENT_UNEXPECTED_BLOCK); +} + +/******************************************************************************/ +/* Basic character checks */ +/******************************************************************************/ + +/** + * This function is used extremely frequently to lex all of the identifiers in a + * source file, so it's important that it be as fast as possible. For this + * reason we have the encoding_changed boolean to check if we need to go through + * the function pointer or can just directly use the UTF-8 functions. + */ +static inline size_t +char_is_identifier_start(const pm_parser_t *parser, const uint8_t *b, ptrdiff_t n) { + if (n <= 0) return 0; + + if (parser->encoding_changed) { + size_t width; + + if ((width = parser->encoding->alpha_char(b, n)) != 0) { + return width; + } else if (*b == '_') { + return 1; + } else if (*b >= 0x80) { + return parser->encoding->char_width(b, n); + } else { + return 0; + } + } else if (*b < 0x80) { + return (pm_encoding_unicode_table[*b] & PRISM_ENCODING_ALPHABETIC_BIT ? 1 : 0) || (*b == '_'); + } else { + return pm_encoding_utf_8_char_width(b, n); + } +} + +/** + * Similar to char_is_identifier but this function assumes that the encoding + * has not been changed. + */ +static inline size_t +char_is_identifier_utf8(const uint8_t *b, ptrdiff_t n) { + if (n <= 0) { + return 0; + } else if (*b < 0x80) { + return (*b == '_') || (pm_encoding_unicode_table[*b] & PRISM_ENCODING_ALPHANUMERIC_BIT ? 1 : 0); + } else { + return pm_encoding_utf_8_char_width(b, n); + } +} + +/** + * Like the above, this function is also used extremely frequently to lex all of + * the identifiers in a source file once the first character has been found. So + * it's important that it be as fast as possible. + */ +static inline size_t +char_is_identifier(const pm_parser_t *parser, const uint8_t *b, ptrdiff_t n) { + if (n <= 0) { + return 0; + } else if (parser->encoding_changed) { + size_t width; + + if ((width = parser->encoding->alnum_char(b, n)) != 0) { + return width; + } else if (*b == '_') { + return 1; + } else if (*b >= 0x80) { + return parser->encoding->char_width(b, n); + } else { + return 0; + } + } else { + return char_is_identifier_utf8(b, n); + } +} + +// Here we're defining a perfect hash for the characters that are allowed in +// global names. This is used to quickly check the next character after a $ to +// see if it's a valid character for a global name. +#define BIT(c, idx) (((c) / 32 - 1 == idx) ? (1U << ((c) % 32)) : 0) +#define PUNCT(idx) ( \ + BIT('~', idx) | BIT('*', idx) | BIT('$', idx) | BIT('?', idx) | \ + BIT('!', idx) | BIT('@', idx) | BIT('/', idx) | BIT('\\', idx) | \ + BIT(';', idx) | BIT(',', idx) | BIT('.', idx) | BIT('=', idx) | \ + BIT(':', idx) | BIT('<', idx) | BIT('>', idx) | BIT('\"', idx) | \ + BIT('&', idx) | BIT('`', idx) | BIT('\'', idx) | BIT('+', idx) | \ + BIT('0', idx)) + +const unsigned int pm_global_name_punctuation_hash[(0x7e - 0x20 + 31) / 32] = { PUNCT(0), PUNCT(1), PUNCT(2) }; + +#undef BIT +#undef PUNCT + +static inline bool +char_is_global_name_punctuation(const uint8_t b) { + const unsigned int i = (const unsigned int) b; + if (i <= 0x20 || 0x7e < i) return false; + + return (pm_global_name_punctuation_hash[(i - 0x20) / 32] >> (i % 32)) & 1; +} + +static inline bool +token_is_setter_name(pm_token_t *token) { + return ( + (token->type == PM_TOKEN_BRACKET_LEFT_RIGHT_EQUAL) || + ((token->type == PM_TOKEN_IDENTIFIER) && + (token->end - token->start >= 2) && + (token->end[-1] == '=')) + ); +} + +/** + * Returns true if the given local variable is a keyword. + */ +static bool +pm_local_is_keyword(const char *source, size_t length) { +#define KEYWORD(name) if (memcmp(source, name, length) == 0) return true + + switch (length) { + case 2: + switch (source[0]) { + case 'd': KEYWORD("do"); return false; + case 'i': KEYWORD("if"); KEYWORD("in"); return false; + case 'o': KEYWORD("or"); return false; + default: return false; + } + case 3: + switch (source[0]) { + case 'a': KEYWORD("and"); return false; + case 'd': KEYWORD("def"); return false; + case 'e': KEYWORD("end"); return false; + case 'f': KEYWORD("for"); return false; + case 'n': KEYWORD("nil"); KEYWORD("not"); return false; + default: return false; + } + case 4: + switch (source[0]) { + case 'c': KEYWORD("case"); return false; + case 'e': KEYWORD("else"); return false; + case 'n': KEYWORD("next"); return false; + case 'r': KEYWORD("redo"); return false; + case 's': KEYWORD("self"); return false; + case 't': KEYWORD("then"); KEYWORD("true"); return false; + case 'w': KEYWORD("when"); return false; + default: return false; + } + case 5: + switch (source[0]) { + case 'a': KEYWORD("alias"); return false; + case 'b': KEYWORD("begin"); KEYWORD("break"); return false; + case 'c': KEYWORD("class"); return false; + case 'e': KEYWORD("elsif"); return false; + case 'f': KEYWORD("false"); return false; + case 'r': KEYWORD("retry"); return false; + case 's': KEYWORD("super"); return false; + case 'u': KEYWORD("undef"); KEYWORD("until"); return false; + case 'w': KEYWORD("while"); return false; + case 'y': KEYWORD("yield"); return false; + default: return false; + } + case 6: + switch (source[0]) { + case 'e': KEYWORD("ensure"); return false; + case 'm': KEYWORD("module"); return false; + case 'r': KEYWORD("rescue"); KEYWORD("return"); return false; + case 'u': KEYWORD("unless"); return false; + default: return false; + } + case 8: + KEYWORD("__LINE__"); + KEYWORD("__FILE__"); + return false; + case 12: + KEYWORD("__ENCODING__"); + return false; + default: + return false; + } + +#undef KEYWORD +} + +/******************************************************************************/ +/* Node flag handling functions */ +/******************************************************************************/ + +/** + * Set the given flag on the given node. + */ +static inline void +pm_node_flag_set(pm_node_t *node, pm_node_flags_t flag) { + node->flags |= flag; +} + +/** + * Remove the given flag from the given node. + */ +static inline void +pm_node_flag_unset(pm_node_t *node, pm_node_flags_t flag) { + node->flags &= (pm_node_flags_t) ~flag; +} + +/** + * Set the repeated parameter flag on the given node. + */ +static inline void +pm_node_flag_set_repeated_parameter(pm_node_t *node) { + assert(PM_NODE_TYPE(node) == PM_BLOCK_LOCAL_VARIABLE_NODE || + PM_NODE_TYPE(node) == PM_BLOCK_PARAMETER_NODE || + PM_NODE_TYPE(node) == PM_KEYWORD_REST_PARAMETER_NODE || + PM_NODE_TYPE(node) == PM_OPTIONAL_KEYWORD_PARAMETER_NODE || + PM_NODE_TYPE(node) == PM_OPTIONAL_PARAMETER_NODE || + PM_NODE_TYPE(node) == PM_REQUIRED_KEYWORD_PARAMETER_NODE || + PM_NODE_TYPE(node) == PM_REQUIRED_PARAMETER_NODE || + PM_NODE_TYPE(node) == PM_REST_PARAMETER_NODE); + + pm_node_flag_set(node, PM_PARAMETER_FLAGS_REPEATED_PARAMETER); +} + +/******************************************************************************/ +/* Node creation functions */ +/******************************************************************************/ + +/** + * When you have an encoding flag on a regular expression, it takes precedence + * over all of the previously set encoding flags. So we need to mask off any + * previously set encoding flags before setting the new one. + */ +#define PM_REGULAR_EXPRESSION_ENCODING_MASK ~(PM_REGULAR_EXPRESSION_FLAGS_EUC_JP | PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT | PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J | PM_REGULAR_EXPRESSION_FLAGS_UTF_8) + +/** + * Parse out the options for a regular expression. + */ +static inline pm_node_flags_t +pm_regular_expression_flags_create(pm_parser_t *parser, const pm_token_t *closing) { + pm_node_flags_t flags = 0; + + if (closing->type == PM_TOKEN_REGEXP_END) { + pm_buffer_t unknown_flags = { 0 }; + + for (const uint8_t *flag = closing->start + 1; flag < closing->end; flag++) { + switch (*flag) { + case 'i': flags |= PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE; break; + case 'm': flags |= PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE; break; + case 'x': flags |= PM_REGULAR_EXPRESSION_FLAGS_EXTENDED; break; + case 'o': flags |= PM_REGULAR_EXPRESSION_FLAGS_ONCE; break; + + case 'e': flags = (pm_node_flags_t) (((pm_node_flags_t) (flags & PM_REGULAR_EXPRESSION_ENCODING_MASK)) | PM_REGULAR_EXPRESSION_FLAGS_EUC_JP); break; + case 'n': flags = (pm_node_flags_t) (((pm_node_flags_t) (flags & PM_REGULAR_EXPRESSION_ENCODING_MASK)) | PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT); break; + case 's': flags = (pm_node_flags_t) (((pm_node_flags_t) (flags & PM_REGULAR_EXPRESSION_ENCODING_MASK)) | PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J); break; + case 'u': flags = (pm_node_flags_t) (((pm_node_flags_t) (flags & PM_REGULAR_EXPRESSION_ENCODING_MASK)) | PM_REGULAR_EXPRESSION_FLAGS_UTF_8); break; + + default: pm_buffer_append_byte(&unknown_flags, *flag); + } + } + + size_t unknown_flags_length = pm_buffer_length(&unknown_flags); + if (unknown_flags_length != 0) { + const char *word = unknown_flags_length >= 2 ? "options" : "option"; + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->previous, PM_ERR_REGEXP_UNKNOWN_OPTIONS, word, unknown_flags_length, pm_buffer_value(&unknown_flags)); + } + pm_buffer_free(&unknown_flags); + } + + return flags; +} + +#undef PM_REGULAR_EXPRESSION_ENCODING_MASK + +static pm_statements_node_t * +pm_statements_node_create(pm_parser_t *parser); + +static void +pm_statements_node_body_append(pm_parser_t *parser, pm_statements_node_t *node, pm_node_t *statement, bool newline); + +static size_t +pm_statements_node_body_length(pm_statements_node_t *node); + +/** + * This function is here to allow us a place to extend in the future when we + * implement our own arena allocation. + */ +static inline void * +pm_node_alloc(PRISM_ATTRIBUTE_UNUSED pm_parser_t *parser, size_t size) { + void *memory = xcalloc(1, size); + if (memory == NULL) { + fprintf(stderr, "Failed to allocate %d bytes\n", (int) size); + abort(); + } + return memory; +} + +#define PM_NODE_ALLOC(parser, type) (type *) pm_node_alloc(parser, sizeof(type)) +#define PM_NODE_IDENTIFY(parser) (++parser->node_id) + +/** + * Allocate a new MissingNode node. + */ +static pm_missing_node_t * +pm_missing_node_create(pm_parser_t *parser, const uint8_t *start, const uint8_t *end) { + pm_missing_node_t *node = PM_NODE_ALLOC(parser, pm_missing_node_t); + + *node = (pm_missing_node_t) {{ + .type = PM_MISSING_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { .start = start, .end = end } + }}; + + return node; +} + +/** + * Allocate and initialize a new AliasGlobalVariableNode node. + */ +static pm_alias_global_variable_node_t * +pm_alias_global_variable_node_create(pm_parser_t *parser, const pm_token_t *keyword, pm_node_t *new_name, pm_node_t *old_name) { + assert(keyword->type == PM_TOKEN_KEYWORD_ALIAS); + pm_alias_global_variable_node_t *node = PM_NODE_ALLOC(parser, pm_alias_global_variable_node_t); + + *node = (pm_alias_global_variable_node_t) { + { + .type = PM_ALIAS_GLOBAL_VARIABLE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = keyword->start, + .end = old_name->location.end + }, + }, + .new_name = new_name, + .old_name = old_name, + .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword) + }; + + return node; +} + +/** + * Allocate and initialize a new AliasMethodNode node. + */ +static pm_alias_method_node_t * +pm_alias_method_node_create(pm_parser_t *parser, const pm_token_t *keyword, pm_node_t *new_name, pm_node_t *old_name) { + assert(keyword->type == PM_TOKEN_KEYWORD_ALIAS); + pm_alias_method_node_t *node = PM_NODE_ALLOC(parser, pm_alias_method_node_t); + + *node = (pm_alias_method_node_t) { + { + .type = PM_ALIAS_METHOD_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = keyword->start, + .end = old_name->location.end + }, + }, + .new_name = new_name, + .old_name = old_name, + .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword) + }; + + return node; +} + +/** + * Allocate a new AlternationPatternNode node. + */ +static pm_alternation_pattern_node_t * +pm_alternation_pattern_node_create(pm_parser_t *parser, pm_node_t *left, pm_node_t *right, const pm_token_t *operator) { + pm_alternation_pattern_node_t *node = PM_NODE_ALLOC(parser, pm_alternation_pattern_node_t); + + *node = (pm_alternation_pattern_node_t) { + { + .type = PM_ALTERNATION_PATTERN_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = left->location.start, + .end = right->location.end + }, + }, + .left = left, + .right = right, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator) + }; + + return node; +} + +/** + * Allocate and initialize a new and node. + */ +static pm_and_node_t * +pm_and_node_create(pm_parser_t *parser, pm_node_t *left, const pm_token_t *operator, pm_node_t *right) { + pm_assert_value_expression(parser, left); + + pm_and_node_t *node = PM_NODE_ALLOC(parser, pm_and_node_t); + + *node = (pm_and_node_t) { + { + .type = PM_AND_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = left->location.start, + .end = right->location.end + }, + }, + .left = left, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .right = right + }; + + return node; +} + +/** + * Allocate an initialize a new arguments node. + */ +static pm_arguments_node_t * +pm_arguments_node_create(pm_parser_t *parser) { + pm_arguments_node_t *node = PM_NODE_ALLOC(parser, pm_arguments_node_t); + + *node = (pm_arguments_node_t) { + { + .type = PM_ARGUMENTS_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_NULL_VALUE(parser) + }, + .arguments = { 0 } + }; + + return node; +} + +/** + * Return the size of the given arguments node. + */ +static size_t +pm_arguments_node_size(pm_arguments_node_t *node) { + return node->arguments.size; +} + +/** + * Append an argument to an arguments node. + */ +static void +pm_arguments_node_arguments_append(pm_arguments_node_t *node, pm_node_t *argument) { + if (pm_arguments_node_size(node) == 0) { + node->base.location.start = argument->location.start; + } + + node->base.location.end = argument->location.end; + pm_node_list_append(&node->arguments, argument); + + if (PM_NODE_TYPE_P(argument, PM_SPLAT_NODE)) { + if (PM_NODE_FLAG_P(node, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_SPLAT)) { + pm_node_flag_set((pm_node_t *) node, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_MULTIPLE_SPLATS); + } else { + pm_node_flag_set((pm_node_t *) node, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_SPLAT); + } + } +} + +/** + * Allocate and initialize a new ArrayNode node. + */ +static pm_array_node_t * +pm_array_node_create(pm_parser_t *parser, const pm_token_t *opening) { + pm_array_node_t *node = PM_NODE_ALLOC(parser, pm_array_node_t); + + *node = (pm_array_node_t) { + { + .type = PM_ARRAY_NODE, + .flags = PM_NODE_FLAG_STATIC_LITERAL, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(opening) + }, + .opening_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(opening), + .closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(opening), + .elements = { 0 } + }; + + return node; +} + +/** + * Append an argument to an array node. + */ +static inline void +pm_array_node_elements_append(pm_array_node_t *node, pm_node_t *element) { + if (!node->elements.size && !node->opening_loc.start) { + node->base.location.start = element->location.start; + } + + pm_node_list_append(&node->elements, element); + node->base.location.end = element->location.end; + + // If the element is not a static literal, then the array is not a static + // literal. Turn that flag off. + if (PM_NODE_TYPE_P(element, PM_ARRAY_NODE) || PM_NODE_TYPE_P(element, PM_HASH_NODE) || PM_NODE_TYPE_P(element, PM_RANGE_NODE) || !PM_NODE_FLAG_P(element, PM_NODE_FLAG_STATIC_LITERAL)) { + pm_node_flag_unset((pm_node_t *)node, PM_NODE_FLAG_STATIC_LITERAL); + } + + if (PM_NODE_TYPE_P(element, PM_SPLAT_NODE)) { + pm_node_flag_set((pm_node_t *)node, PM_ARRAY_NODE_FLAGS_CONTAINS_SPLAT); + } +} + +/** + * Set the closing token and end location of an array node. + */ +static void +pm_array_node_close_set(pm_array_node_t *node, const pm_token_t *closing) { + assert(closing->type == PM_TOKEN_BRACKET_RIGHT || closing->type == PM_TOKEN_STRING_END || closing->type == PM_TOKEN_MISSING || closing->type == PM_TOKEN_NOT_PROVIDED); + node->base.location.end = closing->end; + node->closing_loc = PM_LOCATION_TOKEN_VALUE(closing); +} + +/** + * Allocate and initialize a new array pattern node. The node list given in the + * nodes parameter is guaranteed to have at least two nodes. + */ +static pm_array_pattern_node_t * +pm_array_pattern_node_node_list_create(pm_parser_t *parser, pm_node_list_t *nodes) { + pm_array_pattern_node_t *node = PM_NODE_ALLOC(parser, pm_array_pattern_node_t); + + *node = (pm_array_pattern_node_t) { + { + .type = PM_ARRAY_PATTERN_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = nodes->nodes[0]->location.start, + .end = nodes->nodes[nodes->size - 1]->location.end + }, + }, + .constant = NULL, + .rest = NULL, + .requireds = { 0 }, + .posts = { 0 }, + .opening_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .closing_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE + }; + + // For now we're going to just copy over each pointer manually. This could be + // much more efficient, as we could instead resize the node list. + bool found_rest = false; + pm_node_t *child; + + PM_NODE_LIST_FOREACH(nodes, index, child) { + if (!found_rest && (PM_NODE_TYPE_P(child, PM_SPLAT_NODE) || PM_NODE_TYPE_P(child, PM_IMPLICIT_REST_NODE))) { + node->rest = child; + found_rest = true; + } else if (found_rest) { + pm_node_list_append(&node->posts, child); + } else { + pm_node_list_append(&node->requireds, child); + } + } + + return node; +} + +/** + * Allocate and initialize a new array pattern node from a single rest node. + */ +static pm_array_pattern_node_t * +pm_array_pattern_node_rest_create(pm_parser_t *parser, pm_node_t *rest) { + pm_array_pattern_node_t *node = PM_NODE_ALLOC(parser, pm_array_pattern_node_t); + + *node = (pm_array_pattern_node_t) { + { + .type = PM_ARRAY_PATTERN_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = rest->location, + }, + .constant = NULL, + .rest = rest, + .requireds = { 0 }, + .posts = { 0 }, + .opening_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .closing_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE + }; + + return node; +} + +/** + * Allocate and initialize a new array pattern node from a constant and opening + * and closing tokens. + */ +static pm_array_pattern_node_t * +pm_array_pattern_node_constant_create(pm_parser_t *parser, pm_node_t *constant, const pm_token_t *opening, const pm_token_t *closing) { + pm_array_pattern_node_t *node = PM_NODE_ALLOC(parser, pm_array_pattern_node_t); + + *node = (pm_array_pattern_node_t) { + { + .type = PM_ARRAY_PATTERN_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = constant->location.start, + .end = closing->end + }, + }, + .constant = constant, + .rest = NULL, + .opening_loc = PM_LOCATION_TOKEN_VALUE(opening), + .closing_loc = PM_LOCATION_TOKEN_VALUE(closing), + .requireds = { 0 }, + .posts = { 0 } + }; + + return node; +} + +/** + * Allocate and initialize a new array pattern node from an opening and closing + * token. + */ +static pm_array_pattern_node_t * +pm_array_pattern_node_empty_create(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *closing) { + pm_array_pattern_node_t *node = PM_NODE_ALLOC(parser, pm_array_pattern_node_t); + + *node = (pm_array_pattern_node_t) { + { + .type = PM_ARRAY_PATTERN_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = opening->start, + .end = closing->end + }, + }, + .constant = NULL, + .rest = NULL, + .opening_loc = PM_LOCATION_TOKEN_VALUE(opening), + .closing_loc = PM_LOCATION_TOKEN_VALUE(closing), + .requireds = { 0 }, + .posts = { 0 } + }; + + return node; +} + +static inline void +pm_array_pattern_node_requireds_append(pm_array_pattern_node_t *node, pm_node_t *inner) { + pm_node_list_append(&node->requireds, inner); +} + +/** + * Allocate and initialize a new assoc node. + */ +static pm_assoc_node_t * +pm_assoc_node_create(pm_parser_t *parser, pm_node_t *key, const pm_token_t *operator, pm_node_t *value) { + pm_assoc_node_t *node = PM_NODE_ALLOC(parser, pm_assoc_node_t); + const uint8_t *end; + + if (value != NULL && value->location.end > key->location.end) { + end = value->location.end; + } else if (operator->type != PM_TOKEN_NOT_PROVIDED) { + end = operator->end; + } else { + end = key->location.end; + } + + // Hash string keys will be frozen, so we can mark them as frozen here so + // that the compiler picks them up and also when we check for static literal + // on the keys it gets factored in. + if (PM_NODE_TYPE_P(key, PM_STRING_NODE)) { + key->flags |= PM_STRING_FLAGS_FROZEN | PM_NODE_FLAG_STATIC_LITERAL; + } + + // If the key and value of this assoc node are both static literals, then + // we can mark this node as a static literal. + pm_node_flags_t flags = 0; + if ( + !PM_NODE_TYPE_P(key, PM_ARRAY_NODE) && !PM_NODE_TYPE_P(key, PM_HASH_NODE) && !PM_NODE_TYPE_P(key, PM_RANGE_NODE) && + value && !PM_NODE_TYPE_P(value, PM_ARRAY_NODE) && !PM_NODE_TYPE_P(value, PM_HASH_NODE) && !PM_NODE_TYPE_P(value, PM_RANGE_NODE) + ) { + flags = key->flags & value->flags & PM_NODE_FLAG_STATIC_LITERAL; + } + + *node = (pm_assoc_node_t) { + { + .type = PM_ASSOC_NODE, + .flags = flags, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = key->location.start, + .end = end + }, + }, + .key = key, + .operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + return node; +} + +/** + * Allocate and initialize a new assoc splat node. + */ +static pm_assoc_splat_node_t * +pm_assoc_splat_node_create(pm_parser_t *parser, pm_node_t *value, const pm_token_t *operator) { + assert(operator->type == PM_TOKEN_USTAR_STAR); + pm_assoc_splat_node_t *node = PM_NODE_ALLOC(parser, pm_assoc_splat_node_t); + + *node = (pm_assoc_splat_node_t) { + { + .type = PM_ASSOC_SPLAT_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = operator->start, + .end = value == NULL ? operator->end : value->location.end + }, + }, + .value = value, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator) + }; + + return node; +} + +/** + * Allocate a new BackReferenceReadNode node. + */ +static pm_back_reference_read_node_t * +pm_back_reference_read_node_create(pm_parser_t *parser, const pm_token_t *name) { + assert(name->type == PM_TOKEN_BACK_REFERENCE); + pm_back_reference_read_node_t *node = PM_NODE_ALLOC(parser, pm_back_reference_read_node_t); + + *node = (pm_back_reference_read_node_t) { + { + .type = PM_BACK_REFERENCE_READ_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(name), + }, + .name = pm_parser_constant_id_token(parser, name) + }; + + return node; +} + +/** + * Allocate and initialize new a begin node. + */ +static pm_begin_node_t * +pm_begin_node_create(pm_parser_t *parser, const pm_token_t *begin_keyword, pm_statements_node_t *statements) { + pm_begin_node_t *node = PM_NODE_ALLOC(parser, pm_begin_node_t); + + *node = (pm_begin_node_t) { + { + .type = PM_BEGIN_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = begin_keyword->start, + .end = statements == NULL ? begin_keyword->end : statements->base.location.end + }, + }, + .begin_keyword_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(begin_keyword), + .statements = statements, + .end_keyword_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE + }; + + return node; +} + +/** + * Set the rescue clause, optionally start, and end location of a begin node. + */ +static void +pm_begin_node_rescue_clause_set(pm_begin_node_t *node, pm_rescue_node_t *rescue_clause) { + // If the begin keyword doesn't exist, we set the start on the begin_node + if (!node->begin_keyword_loc.start) { + node->base.location.start = rescue_clause->base.location.start; + } + node->base.location.end = rescue_clause->base.location.end; + node->rescue_clause = rescue_clause; +} + +/** + * Set the else clause and end location of a begin node. + */ +static void +pm_begin_node_else_clause_set(pm_begin_node_t *node, pm_else_node_t *else_clause) { + node->base.location.end = else_clause->base.location.end; + node->else_clause = else_clause; +} + +/** + * Set the ensure clause and end location of a begin node. + */ +static void +pm_begin_node_ensure_clause_set(pm_begin_node_t *node, pm_ensure_node_t *ensure_clause) { + node->base.location.end = ensure_clause->base.location.end; + node->ensure_clause = ensure_clause; +} + +/** + * Set the end keyword and end location of a begin node. + */ +static void +pm_begin_node_end_keyword_set(pm_begin_node_t *node, const pm_token_t *end_keyword) { + assert(end_keyword->type == PM_TOKEN_KEYWORD_END || end_keyword->type == PM_TOKEN_MISSING); + + node->base.location.end = end_keyword->end; + node->end_keyword_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(end_keyword); +} + +/** + * Allocate and initialize a new BlockArgumentNode node. + */ +static pm_block_argument_node_t * +pm_block_argument_node_create(pm_parser_t *parser, const pm_token_t *operator, pm_node_t *expression) { + pm_block_argument_node_t *node = PM_NODE_ALLOC(parser, pm_block_argument_node_t); + + *node = (pm_block_argument_node_t) { + { + .type = PM_BLOCK_ARGUMENT_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = operator->start, + .end = expression == NULL ? operator->end : expression->location.end + }, + }, + .expression = expression, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator) + }; + + return node; +} + +/** + * Allocate and initialize a new BlockNode node. + */ +static pm_block_node_t * +pm_block_node_create(pm_parser_t *parser, pm_constant_id_list_t *locals, const pm_token_t *opening, pm_node_t *parameters, pm_node_t *body, const pm_token_t *closing) { + pm_block_node_t *node = PM_NODE_ALLOC(parser, pm_block_node_t); + + *node = (pm_block_node_t) { + { + .type = PM_BLOCK_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { .start = opening->start, .end = closing->end }, + }, + .locals = *locals, + .parameters = parameters, + .body = body, + .opening_loc = PM_LOCATION_TOKEN_VALUE(opening), + .closing_loc = PM_LOCATION_TOKEN_VALUE(closing) + }; + + return node; +} + +/** + * Allocate and initialize a new BlockParameterNode node. + */ +static pm_block_parameter_node_t * +pm_block_parameter_node_create(pm_parser_t *parser, const pm_token_t *name, const pm_token_t *operator) { + assert(operator->type == PM_TOKEN_NOT_PROVIDED || operator->type == PM_TOKEN_UAMPERSAND || operator->type == PM_TOKEN_AMPERSAND); + pm_block_parameter_node_t *node = PM_NODE_ALLOC(parser, pm_block_parameter_node_t); + + *node = (pm_block_parameter_node_t) { + { + .type = PM_BLOCK_PARAMETER_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = operator->start, + .end = (name->type == PM_TOKEN_NOT_PROVIDED ? operator->end : name->end) + }, + }, + .name = pm_parser_optional_constant_id_token(parser, name), + .name_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(name), + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator) + }; + + return node; +} + +/** + * Allocate and initialize a new BlockParametersNode node. + */ +static pm_block_parameters_node_t * +pm_block_parameters_node_create(pm_parser_t *parser, pm_parameters_node_t *parameters, const pm_token_t *opening) { + pm_block_parameters_node_t *node = PM_NODE_ALLOC(parser, pm_block_parameters_node_t); + + const uint8_t *start; + if (opening->type != PM_TOKEN_NOT_PROVIDED) { + start = opening->start; + } else if (parameters != NULL) { + start = parameters->base.location.start; + } else { + start = NULL; + } + + const uint8_t *end; + if (parameters != NULL) { + end = parameters->base.location.end; + } else if (opening->type != PM_TOKEN_NOT_PROVIDED) { + end = opening->end; + } else { + end = NULL; + } + + *node = (pm_block_parameters_node_t) { + { + .type = PM_BLOCK_PARAMETERS_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = start, + .end = end + } + }, + .parameters = parameters, + .opening_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(opening), + .closing_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .locals = { 0 } + }; + + return node; +} + +/** + * Set the closing location of a BlockParametersNode node. + */ +static void +pm_block_parameters_node_closing_set(pm_block_parameters_node_t *node, const pm_token_t *closing) { + assert(closing->type == PM_TOKEN_PIPE || closing->type == PM_TOKEN_PARENTHESIS_RIGHT || closing->type == PM_TOKEN_MISSING); + + node->base.location.end = closing->end; + node->closing_loc = PM_LOCATION_TOKEN_VALUE(closing); +} + +/** + * Allocate and initialize a new BlockLocalVariableNode node. + */ +static pm_block_local_variable_node_t * +pm_block_local_variable_node_create(pm_parser_t *parser, const pm_token_t *name) { + pm_block_local_variable_node_t *node = PM_NODE_ALLOC(parser, pm_block_local_variable_node_t); + + *node = (pm_block_local_variable_node_t) { + { + .type = PM_BLOCK_LOCAL_VARIABLE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(name), + }, + .name = pm_parser_constant_id_token(parser, name) + }; + + return node; +} + +/** + * Append a new block-local variable to a BlockParametersNode node. + */ +static void +pm_block_parameters_node_append_local(pm_block_parameters_node_t *node, const pm_block_local_variable_node_t *local) { + pm_node_list_append(&node->locals, (pm_node_t *) local); + + if (node->base.location.start == NULL) node->base.location.start = local->base.location.start; + node->base.location.end = local->base.location.end; +} + +/** + * Allocate and initialize a new BreakNode node. + */ +static pm_break_node_t * +pm_break_node_create(pm_parser_t *parser, const pm_token_t *keyword, pm_arguments_node_t *arguments) { + assert(keyword->type == PM_TOKEN_KEYWORD_BREAK); + pm_break_node_t *node = PM_NODE_ALLOC(parser, pm_break_node_t); + + *node = (pm_break_node_t) { + { + .type = PM_BREAK_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = keyword->start, + .end = (arguments == NULL ? keyword->end : arguments->base.location.end) + }, + }, + .arguments = arguments, + .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword) + }; + + return node; +} + +// There are certain flags that we want to use internally but don't want to +// expose because they are not relevant beyond parsing. Therefore we'll define +// them here and not define them in config.yml/a header file. +static const pm_node_flags_t PM_WRITE_NODE_FLAGS_IMPLICIT_ARRAY = 0x4; +static const pm_node_flags_t PM_CALL_NODE_FLAGS_IMPLICIT_ARRAY = 0x40; +static const pm_node_flags_t PM_CALL_NODE_FLAGS_COMPARISON = 0x80; +static const pm_node_flags_t PM_CALL_NODE_FLAGS_INDEX = 0x100; + +/** + * Allocate and initialize a new CallNode node. This sets everything to NULL or + * PM_TOKEN_NOT_PROVIDED as appropriate such that its values can be overridden + * in the various specializations of this function. + */ +static pm_call_node_t * +pm_call_node_create(pm_parser_t *parser, pm_node_flags_t flags) { + pm_call_node_t *node = PM_NODE_ALLOC(parser, pm_call_node_t); + + *node = (pm_call_node_t) { + { + .type = PM_CALL_NODE, + .flags = flags, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_NULL_VALUE(parser), + }, + .receiver = NULL, + .call_operator_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .message_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .opening_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .arguments = NULL, + .closing_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .block = NULL, + .name = 0 + }; + + return node; +} + +/** + * Returns the value that the ignore visibility flag should be set to for the + * given receiver. + */ +static inline pm_node_flags_t +pm_call_node_ignore_visibility_flag(const pm_node_t *receiver) { + return PM_NODE_TYPE_P(receiver, PM_SELF_NODE) ? PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY : 0; +} + +/** + * Allocate and initialize a new CallNode node from an aref or an aset + * expression. + */ +static pm_call_node_t * +pm_call_node_aref_create(pm_parser_t *parser, pm_node_t *receiver, pm_arguments_t *arguments) { + pm_assert_value_expression(parser, receiver); + + pm_node_flags_t flags = pm_call_node_ignore_visibility_flag(receiver); + if (arguments->block == NULL || PM_NODE_TYPE_P(arguments->block, PM_BLOCK_ARGUMENT_NODE)) { + flags |= PM_CALL_NODE_FLAGS_INDEX; + } + + pm_call_node_t *node = pm_call_node_create(parser, flags); + + node->base.location.start = receiver->location.start; + node->base.location.end = pm_arguments_end(arguments); + + node->receiver = receiver; + node->message_loc.start = arguments->opening_loc.start; + node->message_loc.end = arguments->closing_loc.end; + + node->opening_loc = arguments->opening_loc; + node->arguments = arguments->arguments; + node->closing_loc = arguments->closing_loc; + node->block = arguments->block; + + node->name = pm_parser_constant_id_constant(parser, "[]", 2); + return node; +} + +/** + * Allocate and initialize a new CallNode node from a binary expression. + */ +static pm_call_node_t * +pm_call_node_binary_create(pm_parser_t *parser, pm_node_t *receiver, pm_token_t *operator, pm_node_t *argument, pm_node_flags_t flags) { + pm_assert_value_expression(parser, receiver); + pm_assert_value_expression(parser, argument); + + pm_call_node_t *node = pm_call_node_create(parser, pm_call_node_ignore_visibility_flag(receiver) | flags); + + node->base.location.start = MIN(receiver->location.start, argument->location.start); + node->base.location.end = MAX(receiver->location.end, argument->location.end); + + node->receiver = receiver; + node->message_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator); + + pm_arguments_node_t *arguments = pm_arguments_node_create(parser); + pm_arguments_node_arguments_append(arguments, argument); + node->arguments = arguments; + + node->name = pm_parser_constant_id_token(parser, operator); + return node; +} + +/** + * Allocate and initialize a new CallNode node from a call expression. + */ +static pm_call_node_t * +pm_call_node_call_create(pm_parser_t *parser, pm_node_t *receiver, pm_token_t *operator, pm_token_t *message, pm_arguments_t *arguments) { + pm_assert_value_expression(parser, receiver); + + pm_call_node_t *node = pm_call_node_create(parser, pm_call_node_ignore_visibility_flag(receiver)); + + node->base.location.start = receiver->location.start; + const uint8_t *end = pm_arguments_end(arguments); + if (end == NULL) { + end = message->end; + } + node->base.location.end = end; + + node->receiver = receiver; + node->call_operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator); + node->message_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(message); + node->opening_loc = arguments->opening_loc; + node->arguments = arguments->arguments; + node->closing_loc = arguments->closing_loc; + node->block = arguments->block; + + if (operator->type == PM_TOKEN_AMPERSAND_DOT) { + pm_node_flag_set((pm_node_t *)node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION); + } + + node->name = pm_parser_constant_id_token(parser, message); + return node; +} + +/** + * Allocate and initialize a new synthesized CallNode node from a call expression. + */ +static pm_call_node_t * +pm_call_node_call_synthesized_create(pm_parser_t *parser, pm_node_t *receiver, const char *message, pm_arguments_node_t *arguments) { + pm_call_node_t *node = pm_call_node_create(parser, 0); + node->base.location.start = parser->start; + node->base.location.end = parser->end; + + node->receiver = receiver; + node->call_operator_loc = (pm_location_t) { .start = NULL, .end = NULL }; + node->message_loc = (pm_location_t) { .start = NULL, .end = NULL }; + node->arguments = arguments; + + node->name = pm_parser_constant_id_constant(parser, message, strlen(message)); + return node; +} + +/** + * Allocate and initialize a new CallNode node from a call to a method name + * without a receiver that could not have been a local variable read. + */ +static pm_call_node_t * +pm_call_node_fcall_create(pm_parser_t *parser, pm_token_t *message, pm_arguments_t *arguments) { + pm_call_node_t *node = pm_call_node_create(parser, PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY); + + node->base.location.start = message->start; + node->base.location.end = pm_arguments_end(arguments); + + node->message_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(message); + node->opening_loc = arguments->opening_loc; + node->arguments = arguments->arguments; + node->closing_loc = arguments->closing_loc; + node->block = arguments->block; + + node->name = pm_parser_constant_id_token(parser, message); + return node; +} + +/** + * Allocate and initialize a new CallNode node from a synthesized call to a + * method name with the given arguments. + */ +static pm_call_node_t * +pm_call_node_fcall_synthesized_create(pm_parser_t *parser, pm_arguments_node_t *arguments, pm_constant_id_t name) { + pm_call_node_t *node = pm_call_node_create(parser, PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY); + + node->base.location = PM_LOCATION_NULL_VALUE(parser); + node->arguments = arguments; + + node->name = name; + return node; +} + +/** + * Allocate and initialize a new CallNode node from a not expression. + */ +static pm_call_node_t * +pm_call_node_not_create(pm_parser_t *parser, pm_node_t *receiver, pm_token_t *message, pm_arguments_t *arguments) { + pm_assert_value_expression(parser, receiver); + if (receiver != NULL) pm_conditional_predicate(parser, receiver, PM_CONDITIONAL_PREDICATE_TYPE_NOT); + + pm_call_node_t *node = pm_call_node_create(parser, receiver == NULL ? 0 : pm_call_node_ignore_visibility_flag(receiver)); + + node->base.location.start = message->start; + if (arguments->closing_loc.start != NULL) { + node->base.location.end = arguments->closing_loc.end; + } else { + assert(receiver != NULL); + node->base.location.end = receiver->location.end; + } + + node->receiver = receiver; + node->message_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(message); + node->opening_loc = arguments->opening_loc; + node->arguments = arguments->arguments; + node->closing_loc = arguments->closing_loc; + + node->name = pm_parser_constant_id_constant(parser, "!", 1); + return node; +} + +/** + * Allocate and initialize a new CallNode node from a call shorthand expression. + */ +static pm_call_node_t * +pm_call_node_shorthand_create(pm_parser_t *parser, pm_node_t *receiver, pm_token_t *operator, pm_arguments_t *arguments) { + pm_assert_value_expression(parser, receiver); + + pm_call_node_t *node = pm_call_node_create(parser, pm_call_node_ignore_visibility_flag(receiver)); + + node->base.location.start = receiver->location.start; + node->base.location.end = pm_arguments_end(arguments); + + node->receiver = receiver; + node->call_operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator); + node->opening_loc = arguments->opening_loc; + node->arguments = arguments->arguments; + node->closing_loc = arguments->closing_loc; + node->block = arguments->block; + + if (operator->type == PM_TOKEN_AMPERSAND_DOT) { + pm_node_flag_set((pm_node_t *)node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION); + } + + node->name = pm_parser_constant_id_constant(parser, "call", 4); + return node; +} + +/** + * Allocate and initialize a new CallNode node from a unary operator expression. + */ +static pm_call_node_t * +pm_call_node_unary_create(pm_parser_t *parser, pm_token_t *operator, pm_node_t *receiver, const char *name) { + pm_assert_value_expression(parser, receiver); + + pm_call_node_t *node = pm_call_node_create(parser, pm_call_node_ignore_visibility_flag(receiver)); + + node->base.location.start = operator->start; + node->base.location.end = receiver->location.end; + + node->receiver = receiver; + node->message_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator); + + node->name = pm_parser_constant_id_constant(parser, name, strlen(name)); + return node; +} + +/** + * Allocate and initialize a new CallNode node from a call to a method name + * without a receiver that could also have been a local variable read. + */ +static pm_call_node_t * +pm_call_node_variable_call_create(pm_parser_t *parser, pm_token_t *message) { + pm_call_node_t *node = pm_call_node_create(parser, PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY); + + node->base.location = PM_LOCATION_TOKEN_VALUE(message); + node->message_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(message); + + node->name = pm_parser_constant_id_token(parser, message); + return node; +} + +/** + * Returns whether or not this call can be used on the left-hand side of an + * operator assignment. + */ +static inline bool +pm_call_node_writable_p(const pm_parser_t *parser, const pm_call_node_t *node) { + return ( + (node->message_loc.start != NULL) && + (node->message_loc.end[-1] != '!') && + (node->message_loc.end[-1] != '?') && + char_is_identifier_start(parser, node->message_loc.start, parser->end - node->message_loc.start) && + (node->opening_loc.start == NULL) && + (node->arguments == NULL) && + (node->block == NULL) + ); +} + +/** + * Initialize the read name by reading the write name and chopping off the '='. + */ +static void +pm_call_write_read_name_init(pm_parser_t *parser, pm_constant_id_t *read_name, pm_constant_id_t *write_name) { + pm_constant_t *write_constant = pm_constant_pool_id_to_constant(&parser->constant_pool, *write_name); + + if (write_constant->length > 0) { + size_t length = write_constant->length - 1; + + void *memory = xmalloc(length); + memcpy(memory, write_constant->start, length); + + *read_name = pm_constant_pool_insert_owned(&parser->constant_pool, (uint8_t *) memory, length); + } else { + // We can get here if the message was missing because of a syntax error. + *read_name = pm_parser_constant_id_constant(parser, "", 0); + } +} + +/** + * Allocate and initialize a new CallAndWriteNode node. + */ +static pm_call_and_write_node_t * +pm_call_and_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const pm_token_t *operator, pm_node_t *value) { + assert(target->block == NULL); + assert(operator->type == PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL); + pm_call_and_write_node_t *node = PM_NODE_ALLOC(parser, pm_call_and_write_node_t); + + *node = (pm_call_and_write_node_t) { + { + .type = PM_CALL_AND_WRITE_NODE, + .flags = target->base.flags, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->base.location.start, + .end = value->location.end + } + }, + .receiver = target->receiver, + .call_operator_loc = target->call_operator_loc, + .message_loc = target->message_loc, + .read_name = 0, + .write_name = target->name, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + pm_call_write_read_name_init(parser, &node->read_name, &node->write_name); + + // Here we're going to free the target, since it is no longer necessary. + // However, we don't want to call `pm_node_destroy` because we want to keep + // around all of its children since we just reused them. + xfree(target); + + return node; +} + +/** + * Validate that index expressions do not have keywords or blocks if we are + * parsing as Ruby 3.4+. + */ +static void +pm_index_arguments_check(pm_parser_t *parser, const pm_arguments_node_t *arguments, const pm_node_t *block) { + if (parser->version != PM_OPTIONS_VERSION_CRUBY_3_3) { + if (arguments != NULL && PM_NODE_FLAG_P(arguments, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORDS)) { + pm_node_t *node; + PM_NODE_LIST_FOREACH(&arguments->arguments, index, node) { + if (PM_NODE_TYPE_P(node, PM_KEYWORD_HASH_NODE)) { + pm_parser_err_node(parser, node, PM_ERR_UNEXPECTED_INDEX_KEYWORDS); + break; + } + } + } + + if (block != NULL) { + pm_parser_err_node(parser, block, PM_ERR_UNEXPECTED_INDEX_BLOCK); + } + } +} + +/** + * Allocate and initialize a new IndexAndWriteNode node. + */ +static pm_index_and_write_node_t * +pm_index_and_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const pm_token_t *operator, pm_node_t *value) { + assert(operator->type == PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL); + pm_index_and_write_node_t *node = PM_NODE_ALLOC(parser, pm_index_and_write_node_t); + + pm_index_arguments_check(parser, target->arguments, target->block); + + assert(!target->block || PM_NODE_TYPE_P(target->block, PM_BLOCK_ARGUMENT_NODE)); + *node = (pm_index_and_write_node_t) { + { + .type = PM_INDEX_AND_WRITE_NODE, + .flags = target->base.flags, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->base.location.start, + .end = value->location.end + } + }, + .receiver = target->receiver, + .call_operator_loc = target->call_operator_loc, + .opening_loc = target->opening_loc, + .arguments = target->arguments, + .closing_loc = target->closing_loc, + .block = (pm_block_argument_node_t *) target->block, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + // Here we're going to free the target, since it is no longer necessary. + // However, we don't want to call `pm_node_destroy` because we want to keep + // around all of its children since we just reused them. + xfree(target); + + return node; +} + +/** + * Allocate a new CallOperatorWriteNode node. + */ +static pm_call_operator_write_node_t * +pm_call_operator_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const pm_token_t *operator, pm_node_t *value) { + assert(target->block == NULL); + pm_call_operator_write_node_t *node = PM_NODE_ALLOC(parser, pm_call_operator_write_node_t); + + *node = (pm_call_operator_write_node_t) { + { + .type = PM_CALL_OPERATOR_WRITE_NODE, + .flags = target->base.flags, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->base.location.start, + .end = value->location.end + } + }, + .receiver = target->receiver, + .call_operator_loc = target->call_operator_loc, + .message_loc = target->message_loc, + .read_name = 0, + .write_name = target->name, + .binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1), + .binary_operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + pm_call_write_read_name_init(parser, &node->read_name, &node->write_name); + + // Here we're going to free the target, since it is no longer necessary. + // However, we don't want to call `pm_node_destroy` because we want to keep + // around all of its children since we just reused them. + xfree(target); + + return node; +} + +/** + * Allocate a new IndexOperatorWriteNode node. + */ +static pm_index_operator_write_node_t * +pm_index_operator_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const pm_token_t *operator, pm_node_t *value) { + pm_index_operator_write_node_t *node = PM_NODE_ALLOC(parser, pm_index_operator_write_node_t); + + pm_index_arguments_check(parser, target->arguments, target->block); + + assert(!target->block || PM_NODE_TYPE_P(target->block, PM_BLOCK_ARGUMENT_NODE)); + *node = (pm_index_operator_write_node_t) { + { + .type = PM_INDEX_OPERATOR_WRITE_NODE, + .flags = target->base.flags, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->base.location.start, + .end = value->location.end + } + }, + .receiver = target->receiver, + .call_operator_loc = target->call_operator_loc, + .opening_loc = target->opening_loc, + .arguments = target->arguments, + .closing_loc = target->closing_loc, + .block = (pm_block_argument_node_t *) target->block, + .binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1), + .binary_operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + // Here we're going to free the target, since it is no longer necessary. + // However, we don't want to call `pm_node_destroy` because we want to keep + // around all of its children since we just reused them. + xfree(target); + + return node; +} + +/** + * Allocate and initialize a new CallOrWriteNode node. + */ +static pm_call_or_write_node_t * +pm_call_or_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const pm_token_t *operator, pm_node_t *value) { + assert(target->block == NULL); + assert(operator->type == PM_TOKEN_PIPE_PIPE_EQUAL); + pm_call_or_write_node_t *node = PM_NODE_ALLOC(parser, pm_call_or_write_node_t); + + *node = (pm_call_or_write_node_t) { + { + .type = PM_CALL_OR_WRITE_NODE, + .flags = target->base.flags, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->base.location.start, + .end = value->location.end + } + }, + .receiver = target->receiver, + .call_operator_loc = target->call_operator_loc, + .message_loc = target->message_loc, + .read_name = 0, + .write_name = target->name, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + pm_call_write_read_name_init(parser, &node->read_name, &node->write_name); + + // Here we're going to free the target, since it is no longer necessary. + // However, we don't want to call `pm_node_destroy` because we want to keep + // around all of its children since we just reused them. + xfree(target); + + return node; +} + +/** + * Allocate and initialize a new IndexOrWriteNode node. + */ +static pm_index_or_write_node_t * +pm_index_or_write_node_create(pm_parser_t *parser, pm_call_node_t *target, const pm_token_t *operator, pm_node_t *value) { + assert(operator->type == PM_TOKEN_PIPE_PIPE_EQUAL); + pm_index_or_write_node_t *node = PM_NODE_ALLOC(parser, pm_index_or_write_node_t); + + pm_index_arguments_check(parser, target->arguments, target->block); + + assert(!target->block || PM_NODE_TYPE_P(target->block, PM_BLOCK_ARGUMENT_NODE)); + *node = (pm_index_or_write_node_t) { + { + .type = PM_INDEX_OR_WRITE_NODE, + .flags = target->base.flags, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->base.location.start, + .end = value->location.end + } + }, + .receiver = target->receiver, + .call_operator_loc = target->call_operator_loc, + .opening_loc = target->opening_loc, + .arguments = target->arguments, + .closing_loc = target->closing_loc, + .block = (pm_block_argument_node_t *) target->block, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + // Here we're going to free the target, since it is no longer necessary. + // However, we don't want to call `pm_node_destroy` because we want to keep + // around all of its children since we just reused them. + xfree(target); + + return node; +} + +/** + * Allocate and initialize a new CallTargetNode node from an existing call + * node. + */ +static pm_call_target_node_t * +pm_call_target_node_create(pm_parser_t *parser, pm_call_node_t *target) { + pm_call_target_node_t *node = PM_NODE_ALLOC(parser, pm_call_target_node_t); + + *node = (pm_call_target_node_t) { + { + .type = PM_CALL_TARGET_NODE, + .flags = target->base.flags, + .node_id = PM_NODE_IDENTIFY(parser), + .location = target->base.location + }, + .receiver = target->receiver, + .call_operator_loc = target->call_operator_loc, + .name = target->name, + .message_loc = target->message_loc + }; + + // Here we're going to free the target, since it is no longer necessary. + // However, we don't want to call `pm_node_destroy` because we want to keep + // around all of its children since we just reused them. + xfree(target); + + return node; +} + +/** + * Allocate and initialize a new IndexTargetNode node from an existing call + * node. + */ +static pm_index_target_node_t * +pm_index_target_node_create(pm_parser_t *parser, pm_call_node_t *target) { + pm_index_target_node_t *node = PM_NODE_ALLOC(parser, pm_index_target_node_t); + pm_node_flags_t flags = target->base.flags; + + pm_index_arguments_check(parser, target->arguments, target->block); + + assert(!target->block || PM_NODE_TYPE_P(target->block, PM_BLOCK_ARGUMENT_NODE)); + *node = (pm_index_target_node_t) { + { + .type = PM_INDEX_TARGET_NODE, + .flags = flags | PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = target->base.location + }, + .receiver = target->receiver, + .opening_loc = target->opening_loc, + .arguments = target->arguments, + .closing_loc = target->closing_loc, + .block = (pm_block_argument_node_t *) target->block, + }; + + // Here we're going to free the target, since it is no longer necessary. + // However, we don't want to call `pm_node_destroy` because we want to keep + // around all of its children since we just reused them. + xfree(target); + + return node; +} + +/** + * Allocate and initialize a new CapturePatternNode node. + */ +static pm_capture_pattern_node_t * +pm_capture_pattern_node_create(pm_parser_t *parser, pm_node_t *value, pm_local_variable_target_node_t *target, const pm_token_t *operator) { + pm_capture_pattern_node_t *node = PM_NODE_ALLOC(parser, pm_capture_pattern_node_t); + + *node = (pm_capture_pattern_node_t) { + { + .type = PM_CAPTURE_PATTERN_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = value->location.start, + .end = target->base.location.end + }, + }, + .value = value, + .target = target, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator) + }; + + return node; +} + +/** + * Allocate and initialize a new CaseNode node. + */ +static pm_case_node_t * +pm_case_node_create(pm_parser_t *parser, const pm_token_t *case_keyword, pm_node_t *predicate, const pm_token_t *end_keyword) { + pm_case_node_t *node = PM_NODE_ALLOC(parser, pm_case_node_t); + + *node = (pm_case_node_t) { + { + .type = PM_CASE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = case_keyword->start, + .end = end_keyword->end + }, + }, + .predicate = predicate, + .else_clause = NULL, + .case_keyword_loc = PM_LOCATION_TOKEN_VALUE(case_keyword), + .end_keyword_loc = PM_LOCATION_TOKEN_VALUE(end_keyword), + .conditions = { 0 } + }; + + return node; +} + +/** + * Append a new condition to a CaseNode node. + */ +static void +pm_case_node_condition_append(pm_case_node_t *node, pm_node_t *condition) { + assert(PM_NODE_TYPE_P(condition, PM_WHEN_NODE)); + + pm_node_list_append(&node->conditions, condition); + node->base.location.end = condition->location.end; +} + +/** + * Set the else clause of a CaseNode node. + */ +static void +pm_case_node_else_clause_set(pm_case_node_t *node, pm_else_node_t *else_clause) { + node->else_clause = else_clause; + node->base.location.end = else_clause->base.location.end; +} + +/** + * Set the end location for a CaseNode node. + */ +static void +pm_case_node_end_keyword_loc_set(pm_case_node_t *node, const pm_token_t *end_keyword) { + node->base.location.end = end_keyword->end; + node->end_keyword_loc = PM_LOCATION_TOKEN_VALUE(end_keyword); +} + +/** + * Allocate and initialize a new CaseMatchNode node. + */ +static pm_case_match_node_t * +pm_case_match_node_create(pm_parser_t *parser, const pm_token_t *case_keyword, pm_node_t *predicate, const pm_token_t *end_keyword) { + pm_case_match_node_t *node = PM_NODE_ALLOC(parser, pm_case_match_node_t); + + *node = (pm_case_match_node_t) { + { + .type = PM_CASE_MATCH_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = case_keyword->start, + .end = end_keyword->end + }, + }, + .predicate = predicate, + .else_clause = NULL, + .case_keyword_loc = PM_LOCATION_TOKEN_VALUE(case_keyword), + .end_keyword_loc = PM_LOCATION_TOKEN_VALUE(end_keyword), + .conditions = { 0 } + }; + + return node; +} + +/** + * Append a new condition to a CaseMatchNode node. + */ +static void +pm_case_match_node_condition_append(pm_case_match_node_t *node, pm_node_t *condition) { + assert(PM_NODE_TYPE_P(condition, PM_IN_NODE)); + + pm_node_list_append(&node->conditions, condition); + node->base.location.end = condition->location.end; +} + +/** + * Set the else clause of a CaseMatchNode node. + */ +static void +pm_case_match_node_else_clause_set(pm_case_match_node_t *node, pm_else_node_t *else_clause) { + node->else_clause = else_clause; + node->base.location.end = else_clause->base.location.end; +} + +/** + * Set the end location for a CaseMatchNode node. + */ +static void +pm_case_match_node_end_keyword_loc_set(pm_case_match_node_t *node, const pm_token_t *end_keyword) { + node->base.location.end = end_keyword->end; + node->end_keyword_loc = PM_LOCATION_TOKEN_VALUE(end_keyword); +} + +/** + * Allocate a new ClassNode node. + */ +static pm_class_node_t * +pm_class_node_create(pm_parser_t *parser, pm_constant_id_list_t *locals, const pm_token_t *class_keyword, pm_node_t *constant_path, const pm_token_t *name, const pm_token_t *inheritance_operator, pm_node_t *superclass, pm_node_t *body, const pm_token_t *end_keyword) { + pm_class_node_t *node = PM_NODE_ALLOC(parser, pm_class_node_t); + + *node = (pm_class_node_t) { + { + .type = PM_CLASS_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { .start = class_keyword->start, .end = end_keyword->end }, + }, + .locals = *locals, + .class_keyword_loc = PM_LOCATION_TOKEN_VALUE(class_keyword), + .constant_path = constant_path, + .inheritance_operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(inheritance_operator), + .superclass = superclass, + .body = body, + .end_keyword_loc = PM_LOCATION_TOKEN_VALUE(end_keyword), + .name = pm_parser_constant_id_token(parser, name) + }; + + return node; +} + +/** + * Allocate and initialize a new ClassVariableAndWriteNode node. + */ +static pm_class_variable_and_write_node_t * +pm_class_variable_and_write_node_create(pm_parser_t *parser, pm_class_variable_read_node_t *target, const pm_token_t *operator, pm_node_t *value) { + assert(operator->type == PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL); + pm_class_variable_and_write_node_t *node = PM_NODE_ALLOC(parser, pm_class_variable_and_write_node_t); + + *node = (pm_class_variable_and_write_node_t) { + { + .type = PM_CLASS_VARIABLE_AND_WRITE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->base.location.start, + .end = value->location.end + } + }, + .name = target->name, + .name_loc = target->base.location, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + return node; +} + +/** + * Allocate and initialize a new ClassVariableOperatorWriteNode node. + */ +static pm_class_variable_operator_write_node_t * +pm_class_variable_operator_write_node_create(pm_parser_t *parser, pm_class_variable_read_node_t *target, const pm_token_t *operator, pm_node_t *value) { + pm_class_variable_operator_write_node_t *node = PM_NODE_ALLOC(parser, pm_class_variable_operator_write_node_t); + + *node = (pm_class_variable_operator_write_node_t) { + { + .type = PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->base.location.start, + .end = value->location.end + } + }, + .name = target->name, + .name_loc = target->base.location, + .binary_operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value, + .binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1) + }; + + return node; +} + +/** + * Allocate and initialize a new ClassVariableOrWriteNode node. + */ +static pm_class_variable_or_write_node_t * +pm_class_variable_or_write_node_create(pm_parser_t *parser, pm_class_variable_read_node_t *target, const pm_token_t *operator, pm_node_t *value) { + assert(operator->type == PM_TOKEN_PIPE_PIPE_EQUAL); + pm_class_variable_or_write_node_t *node = PM_NODE_ALLOC(parser, pm_class_variable_or_write_node_t); + + *node = (pm_class_variable_or_write_node_t) { + { + .type = PM_CLASS_VARIABLE_OR_WRITE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->base.location.start, + .end = value->location.end + } + }, + .name = target->name, + .name_loc = target->base.location, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + return node; +} + +/** + * Allocate and initialize a new ClassVariableReadNode node. + */ +static pm_class_variable_read_node_t * +pm_class_variable_read_node_create(pm_parser_t *parser, const pm_token_t *token) { + assert(token->type == PM_TOKEN_CLASS_VARIABLE); + pm_class_variable_read_node_t *node = PM_NODE_ALLOC(parser, pm_class_variable_read_node_t); + + *node = (pm_class_variable_read_node_t) { + { + .type = PM_CLASS_VARIABLE_READ_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(token) + }, + .name = pm_parser_constant_id_token(parser, token) + }; + + return node; +} + +/** + * True if the given node is an implicit array node on a write, as in: + * + * a = *b + * a = 1, 2, 3 + */ +static inline pm_node_flags_t +pm_implicit_array_write_flags(const pm_node_t *node, pm_node_flags_t flags) { + if (PM_NODE_TYPE_P(node, PM_ARRAY_NODE) && ((const pm_array_node_t *) node)->opening_loc.start == NULL) { + return flags; + } + return 0; +} + +/** + * Initialize a new ClassVariableWriteNode node from a ClassVariableRead node. + */ +static pm_class_variable_write_node_t * +pm_class_variable_write_node_create(pm_parser_t *parser, pm_class_variable_read_node_t *read_node, pm_token_t *operator, pm_node_t *value) { + pm_class_variable_write_node_t *node = PM_NODE_ALLOC(parser, pm_class_variable_write_node_t); + + *node = (pm_class_variable_write_node_t) { + { + .type = PM_CLASS_VARIABLE_WRITE_NODE, + .flags = pm_implicit_array_write_flags(value, PM_WRITE_NODE_FLAGS_IMPLICIT_ARRAY), + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = read_node->base.location.start, + .end = value->location.end + }, + }, + .name = read_node->name, + .name_loc = PM_LOCATION_NODE_VALUE((pm_node_t *) read_node), + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + return node; +} + +/** + * Allocate and initialize a new ConstantPathAndWriteNode node. + */ +static pm_constant_path_and_write_node_t * +pm_constant_path_and_write_node_create(pm_parser_t *parser, pm_constant_path_node_t *target, const pm_token_t *operator, pm_node_t *value) { + assert(operator->type == PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL); + pm_constant_path_and_write_node_t *node = PM_NODE_ALLOC(parser, pm_constant_path_and_write_node_t); + + *node = (pm_constant_path_and_write_node_t) { + { + .type = PM_CONSTANT_PATH_AND_WRITE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->base.location.start, + .end = value->location.end + } + }, + .target = target, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + return node; +} + +/** + * Allocate and initialize a new ConstantPathOperatorWriteNode node. + */ +static pm_constant_path_operator_write_node_t * +pm_constant_path_operator_write_node_create(pm_parser_t *parser, pm_constant_path_node_t *target, const pm_token_t *operator, pm_node_t *value) { + pm_constant_path_operator_write_node_t *node = PM_NODE_ALLOC(parser, pm_constant_path_operator_write_node_t); + + *node = (pm_constant_path_operator_write_node_t) { + { + .type = PM_CONSTANT_PATH_OPERATOR_WRITE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->base.location.start, + .end = value->location.end + } + }, + .target = target, + .binary_operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value, + .binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1) + }; + + return node; +} + +/** + * Allocate and initialize a new ConstantPathOrWriteNode node. + */ +static pm_constant_path_or_write_node_t * +pm_constant_path_or_write_node_create(pm_parser_t *parser, pm_constant_path_node_t *target, const pm_token_t *operator, pm_node_t *value) { + assert(operator->type == PM_TOKEN_PIPE_PIPE_EQUAL); + pm_constant_path_or_write_node_t *node = PM_NODE_ALLOC(parser, pm_constant_path_or_write_node_t); + + *node = (pm_constant_path_or_write_node_t) { + { + .type = PM_CONSTANT_PATH_OR_WRITE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->base.location.start, + .end = value->location.end + } + }, + .target = target, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + return node; +} + +/** + * Allocate and initialize a new ConstantPathNode node. + */ +static pm_constant_path_node_t * +pm_constant_path_node_create(pm_parser_t *parser, pm_node_t *parent, const pm_token_t *delimiter, const pm_token_t *name_token) { + pm_assert_value_expression(parser, parent); + pm_constant_path_node_t *node = PM_NODE_ALLOC(parser, pm_constant_path_node_t); + + pm_constant_id_t name = PM_CONSTANT_ID_UNSET; + if (name_token->type == PM_TOKEN_CONSTANT) { + name = pm_parser_constant_id_token(parser, name_token); + } + + *node = (pm_constant_path_node_t) { + { + .type = PM_CONSTANT_PATH_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = parent == NULL ? delimiter->start : parent->location.start, + .end = name_token->end + }, + }, + .parent = parent, + .name = name, + .delimiter_loc = PM_LOCATION_TOKEN_VALUE(delimiter), + .name_loc = PM_LOCATION_TOKEN_VALUE(name_token) + }; + + return node; +} + +/** + * Allocate a new ConstantPathWriteNode node. + */ +static pm_constant_path_write_node_t * +pm_constant_path_write_node_create(pm_parser_t *parser, pm_constant_path_node_t *target, const pm_token_t *operator, pm_node_t *value) { + pm_constant_path_write_node_t *node = PM_NODE_ALLOC(parser, pm_constant_path_write_node_t); + + *node = (pm_constant_path_write_node_t) { + { + .type = PM_CONSTANT_PATH_WRITE_NODE, + .flags = pm_implicit_array_write_flags(value, PM_WRITE_NODE_FLAGS_IMPLICIT_ARRAY), + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->base.location.start, + .end = value->location.end + }, + }, + .target = target, + .operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + return node; +} + +/** + * Allocate and initialize a new ConstantAndWriteNode node. + */ +static pm_constant_and_write_node_t * +pm_constant_and_write_node_create(pm_parser_t *parser, pm_constant_read_node_t *target, const pm_token_t *operator, pm_node_t *value) { + assert(operator->type == PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL); + pm_constant_and_write_node_t *node = PM_NODE_ALLOC(parser, pm_constant_and_write_node_t); + + *node = (pm_constant_and_write_node_t) { + { + .type = PM_CONSTANT_AND_WRITE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->base.location.start, + .end = value->location.end + } + }, + .name = target->name, + .name_loc = target->base.location, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + return node; +} + +/** + * Allocate and initialize a new ConstantOperatorWriteNode node. + */ +static pm_constant_operator_write_node_t * +pm_constant_operator_write_node_create(pm_parser_t *parser, pm_constant_read_node_t *target, const pm_token_t *operator, pm_node_t *value) { + pm_constant_operator_write_node_t *node = PM_NODE_ALLOC(parser, pm_constant_operator_write_node_t); + + *node = (pm_constant_operator_write_node_t) { + { + .type = PM_CONSTANT_OPERATOR_WRITE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->base.location.start, + .end = value->location.end + } + }, + .name = target->name, + .name_loc = target->base.location, + .binary_operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value, + .binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1) + }; + + return node; +} + +/** + * Allocate and initialize a new ConstantOrWriteNode node. + */ +static pm_constant_or_write_node_t * +pm_constant_or_write_node_create(pm_parser_t *parser, pm_constant_read_node_t *target, const pm_token_t *operator, pm_node_t *value) { + assert(operator->type == PM_TOKEN_PIPE_PIPE_EQUAL); + pm_constant_or_write_node_t *node = PM_NODE_ALLOC(parser, pm_constant_or_write_node_t); + + *node = (pm_constant_or_write_node_t) { + { + .type = PM_CONSTANT_OR_WRITE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->base.location.start, + .end = value->location.end + } + }, + .name = target->name, + .name_loc = target->base.location, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + return node; +} + +/** + * Allocate and initialize a new ConstantReadNode node. + */ +static pm_constant_read_node_t * +pm_constant_read_node_create(pm_parser_t *parser, const pm_token_t *name) { + assert(name->type == PM_TOKEN_CONSTANT || name->type == PM_TOKEN_MISSING); + pm_constant_read_node_t *node = PM_NODE_ALLOC(parser, pm_constant_read_node_t); + + *node = (pm_constant_read_node_t) { + { + .type = PM_CONSTANT_READ_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(name) + }, + .name = pm_parser_constant_id_token(parser, name) + }; + + return node; +} + +/** + * Allocate a new ConstantWriteNode node. + */ +static pm_constant_write_node_t * +pm_constant_write_node_create(pm_parser_t *parser, pm_constant_read_node_t *target, const pm_token_t *operator, pm_node_t *value) { + pm_constant_write_node_t *node = PM_NODE_ALLOC(parser, pm_constant_write_node_t); + + *node = (pm_constant_write_node_t) { + { + .type = PM_CONSTANT_WRITE_NODE, + .flags = pm_implicit_array_write_flags(value, PM_WRITE_NODE_FLAGS_IMPLICIT_ARRAY), + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->base.location.start, + .end = value->location.end + } + }, + .name = target->name, + .name_loc = target->base.location, + .operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + return node; +} + +/** + * Check if the receiver of a `def` node is allowed. + */ +static void +pm_def_node_receiver_check(pm_parser_t *parser, const pm_node_t *node) { + switch (PM_NODE_TYPE(node)) { + case PM_BEGIN_NODE: { + const pm_begin_node_t *cast = (pm_begin_node_t *) node; + if (cast->statements != NULL) pm_def_node_receiver_check(parser, (pm_node_t *) cast->statements); + break; + } + case PM_PARENTHESES_NODE: { + const pm_parentheses_node_t *cast = (const pm_parentheses_node_t *) node; + if (cast->body != NULL) pm_def_node_receiver_check(parser, cast->body); + break; + } + case PM_STATEMENTS_NODE: { + const pm_statements_node_t *cast = (const pm_statements_node_t *) node; + pm_def_node_receiver_check(parser, cast->body.nodes[cast->body.size - 1]); + break; + } + case PM_ARRAY_NODE: + case PM_FLOAT_NODE: + case PM_IMAGINARY_NODE: + case PM_INTEGER_NODE: + case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE: + case PM_INTERPOLATED_STRING_NODE: + case PM_INTERPOLATED_SYMBOL_NODE: + case PM_INTERPOLATED_X_STRING_NODE: + case PM_RATIONAL_NODE: + case PM_REGULAR_EXPRESSION_NODE: + case PM_SOURCE_ENCODING_NODE: + case PM_SOURCE_FILE_NODE: + case PM_SOURCE_LINE_NODE: + case PM_STRING_NODE: + case PM_SYMBOL_NODE: + case PM_X_STRING_NODE: + pm_parser_err_node(parser, node, PM_ERR_SINGLETON_FOR_LITERALS); + break; + default: + break; + } +} + +/** + * Allocate and initialize a new DefNode node. + */ +static pm_def_node_t * +pm_def_node_create( + pm_parser_t *parser, + pm_constant_id_t name, + const pm_token_t *name_loc, + pm_node_t *receiver, + pm_parameters_node_t *parameters, + pm_node_t *body, + pm_constant_id_list_t *locals, + const pm_token_t *def_keyword, + const pm_token_t *operator, + const pm_token_t *lparen, + const pm_token_t *rparen, + const pm_token_t *equal, + const pm_token_t *end_keyword +) { + pm_def_node_t *node = PM_NODE_ALLOC(parser, pm_def_node_t); + const uint8_t *end; + + if (end_keyword->type == PM_TOKEN_NOT_PROVIDED) { + end = body->location.end; + } else { + end = end_keyword->end; + } + + if ((receiver != NULL) && PM_NODE_TYPE_P(receiver, PM_PARENTHESES_NODE)) { + pm_def_node_receiver_check(parser, receiver); + } + + *node = (pm_def_node_t) { + { + .type = PM_DEF_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { .start = def_keyword->start, .end = end }, + }, + .name = name, + .name_loc = PM_LOCATION_TOKEN_VALUE(name_loc), + .receiver = receiver, + .parameters = parameters, + .body = body, + .locals = *locals, + .def_keyword_loc = PM_LOCATION_TOKEN_VALUE(def_keyword), + .operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator), + .lparen_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(lparen), + .rparen_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(rparen), + .equal_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(equal), + .end_keyword_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(end_keyword) + }; + + return node; +} + +/** + * Allocate a new DefinedNode node. + */ +static pm_defined_node_t * +pm_defined_node_create(pm_parser_t *parser, const pm_token_t *lparen, pm_node_t *value, const pm_token_t *rparen, const pm_location_t *keyword_loc) { + pm_defined_node_t *node = PM_NODE_ALLOC(parser, pm_defined_node_t); + + *node = (pm_defined_node_t) { + { + .type = PM_DEFINED_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = keyword_loc->start, + .end = (rparen->type == PM_TOKEN_NOT_PROVIDED ? value->location.end : rparen->end) + }, + }, + .lparen_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(lparen), + .value = value, + .rparen_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(rparen), + .keyword_loc = *keyword_loc + }; + + return node; +} + +/** + * Allocate and initialize a new ElseNode node. + */ +static pm_else_node_t * +pm_else_node_create(pm_parser_t *parser, const pm_token_t *else_keyword, pm_statements_node_t *statements, const pm_token_t *end_keyword) { + pm_else_node_t *node = PM_NODE_ALLOC(parser, pm_else_node_t); + const uint8_t *end = NULL; + if ((end_keyword->type == PM_TOKEN_NOT_PROVIDED) && (statements != NULL)) { + end = statements->base.location.end; + } else { + end = end_keyword->end; + } + + *node = (pm_else_node_t) { + { + .type = PM_ELSE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = else_keyword->start, + .end = end, + }, + }, + .else_keyword_loc = PM_LOCATION_TOKEN_VALUE(else_keyword), + .statements = statements, + .end_keyword_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(end_keyword) + }; + + return node; +} + +/** + * Allocate and initialize a new EmbeddedStatementsNode node. + */ +static pm_embedded_statements_node_t * +pm_embedded_statements_node_create(pm_parser_t *parser, const pm_token_t *opening, pm_statements_node_t *statements, const pm_token_t *closing) { + pm_embedded_statements_node_t *node = PM_NODE_ALLOC(parser, pm_embedded_statements_node_t); + + *node = (pm_embedded_statements_node_t) { + { + .type = PM_EMBEDDED_STATEMENTS_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = opening->start, + .end = closing->end + } + }, + .opening_loc = PM_LOCATION_TOKEN_VALUE(opening), + .statements = statements, + .closing_loc = PM_LOCATION_TOKEN_VALUE(closing) + }; + + return node; +} + +/** + * Allocate and initialize a new EmbeddedVariableNode node. + */ +static pm_embedded_variable_node_t * +pm_embedded_variable_node_create(pm_parser_t *parser, const pm_token_t *operator, pm_node_t *variable) { + pm_embedded_variable_node_t *node = PM_NODE_ALLOC(parser, pm_embedded_variable_node_t); + + *node = (pm_embedded_variable_node_t) { + { + .type = PM_EMBEDDED_VARIABLE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = operator->start, + .end = variable->location.end + } + }, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .variable = variable + }; + + return node; +} + +/** + * Allocate a new EnsureNode node. + */ +static pm_ensure_node_t * +pm_ensure_node_create(pm_parser_t *parser, const pm_token_t *ensure_keyword, pm_statements_node_t *statements, const pm_token_t *end_keyword) { + pm_ensure_node_t *node = PM_NODE_ALLOC(parser, pm_ensure_node_t); + + *node = (pm_ensure_node_t) { + { + .type = PM_ENSURE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = ensure_keyword->start, + .end = end_keyword->end + }, + }, + .ensure_keyword_loc = PM_LOCATION_TOKEN_VALUE(ensure_keyword), + .statements = statements, + .end_keyword_loc = PM_LOCATION_TOKEN_VALUE(end_keyword) + }; + + return node; +} + +/** + * Allocate and initialize a new FalseNode node. + */ +static pm_false_node_t * +pm_false_node_create(pm_parser_t *parser, const pm_token_t *token) { + assert(token->type == PM_TOKEN_KEYWORD_FALSE); + pm_false_node_t *node = PM_NODE_ALLOC(parser, pm_false_node_t); + + *node = (pm_false_node_t) {{ + .type = PM_FALSE_NODE, + .flags = PM_NODE_FLAG_STATIC_LITERAL, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(token) + }}; + + return node; +} + +/** + * Allocate and initialize a new find pattern node. The node list given in the + * nodes parameter is guaranteed to have at least two nodes. + */ +static pm_find_pattern_node_t * +pm_find_pattern_node_create(pm_parser_t *parser, pm_node_list_t *nodes) { + pm_find_pattern_node_t *node = PM_NODE_ALLOC(parser, pm_find_pattern_node_t); + + pm_node_t *left = nodes->nodes[0]; + assert(PM_NODE_TYPE_P(left, PM_SPLAT_NODE)); + pm_splat_node_t *left_splat_node = (pm_splat_node_t *) left; + + pm_node_t *right; + + if (nodes->size == 1) { + right = (pm_node_t *) pm_missing_node_create(parser, left->location.end, left->location.end); + } else { + right = nodes->nodes[nodes->size - 1]; + assert(PM_NODE_TYPE_P(right, PM_SPLAT_NODE)); + } + +#if PRISM_SERIALIZE_ONLY_SEMANTICS_FIELDS + // FindPatternNode#right is typed as SplatNode in this case, so replace the potential MissingNode with a SplatNode. + // The resulting AST will anyway be ignored, but this file still needs to compile. + pm_splat_node_t *right_splat_node = PM_NODE_TYPE_P(right, PM_SPLAT_NODE) ? (pm_splat_node_t *) right : left_splat_node; +#else + pm_node_t *right_splat_node = right; +#endif + *node = (pm_find_pattern_node_t) { + { + .type = PM_FIND_PATTERN_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = left->location.start, + .end = right->location.end, + }, + }, + .constant = NULL, + .left = left_splat_node, + .right = right_splat_node, + .requireds = { 0 }, + .opening_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .closing_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE + }; + + // For now we're going to just copy over each pointer manually. This could be + // much more efficient, as we could instead resize the node list to only point + // to 1...-1. + for (size_t index = 1; index < nodes->size - 1; index++) { + pm_node_list_append(&node->requireds, nodes->nodes[index]); + } + + return node; +} + +/** + * Parse the value of a double, add appropriate errors if there is an issue, and + * return the value that should be saved on the PM_FLOAT_NODE node. + */ +static double +pm_double_parse(pm_parser_t *parser, const pm_token_t *token) { + ptrdiff_t diff = token->end - token->start; + if (diff <= 0) return 0.0; + + // First, get a buffer of the content. + size_t length = (size_t) diff; + char *buffer = xmalloc(sizeof(char) * (length + 1)); + memcpy((void *) buffer, token->start, length); + + // Next, determine if we need to replace the decimal point because of + // locale-specific options, and then normalize them if we have to. + char decimal_point = *localeconv()->decimal_point; + if (decimal_point != '.') { + for (size_t index = 0; index < length; index++) { + if (buffer[index] == '.') buffer[index] = decimal_point; + } + } + + // Next, handle underscores by removing them from the buffer. + for (size_t index = 0; index < length; index++) { + if (buffer[index] == '_') { + memmove((void *) (buffer + index), (void *) (buffer + index + 1), length - index); + length--; + } + } + + // Null-terminate the buffer so that strtod cannot read off the end. + buffer[length] = '\0'; + + // Now, call strtod to parse the value. Note that CRuby has their own + // version of strtod which avoids locales. We're okay using the locale-aware + // version because we've already validated through the parser that the token + // is in a valid format. + errno = 0; + char *eptr; + double value = strtod(buffer, &eptr); + + // This should never happen, because we've already checked that the token + // is in a valid format. However it's good to be safe. + if ((eptr != buffer + length) || (errno != 0 && errno != ERANGE)) { + PM_PARSER_ERR_TOKEN_FORMAT_CONTENT(parser, (*token), PM_ERR_FLOAT_PARSE); + xfree((void *) buffer); + return 0.0; + } + + // If errno is set, then it should only be ERANGE. At this point we need to + // check if it's infinity (it should be). + if (errno == ERANGE && PRISM_ISINF(value)) { + int warn_width; + const char *ellipsis; + + if (length > 20) { + warn_width = 20; + ellipsis = "..."; + } else { + warn_width = (int) length; + ellipsis = ""; + } + + pm_diagnostic_list_append_format(&parser->warning_list, token->start, token->end, PM_WARN_FLOAT_OUT_OF_RANGE, warn_width, (const char *) token->start, ellipsis); + value = (value < 0.0) ? -HUGE_VAL : HUGE_VAL; + } + + // Finally we can free the buffer and return the value. + xfree((void *) buffer); + return value; +} + +/** + * Allocate and initialize a new FloatNode node. + */ +static pm_float_node_t * +pm_float_node_create(pm_parser_t *parser, const pm_token_t *token) { + assert(token->type == PM_TOKEN_FLOAT); + pm_float_node_t *node = PM_NODE_ALLOC(parser, pm_float_node_t); + + *node = (pm_float_node_t) { + { + .type = PM_FLOAT_NODE, + .flags = PM_NODE_FLAG_STATIC_LITERAL, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(token) + }, + .value = pm_double_parse(parser, token) + }; + + return node; +} + +/** + * Allocate and initialize a new FloatNode node from a FLOAT_IMAGINARY token. + */ +static pm_imaginary_node_t * +pm_float_node_imaginary_create(pm_parser_t *parser, const pm_token_t *token) { + assert(token->type == PM_TOKEN_FLOAT_IMAGINARY); + + pm_imaginary_node_t *node = PM_NODE_ALLOC(parser, pm_imaginary_node_t); + *node = (pm_imaginary_node_t) { + { + .type = PM_IMAGINARY_NODE, + .flags = PM_NODE_FLAG_STATIC_LITERAL, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(token) + }, + .numeric = (pm_node_t *) pm_float_node_create(parser, &((pm_token_t) { + .type = PM_TOKEN_FLOAT, + .start = token->start, + .end = token->end - 1 + })) + }; + + return node; +} + +/** + * Allocate and initialize a new RationalNode node from a FLOAT_RATIONAL token. + */ +static pm_rational_node_t * +pm_float_node_rational_create(pm_parser_t *parser, const pm_token_t *token) { + assert(token->type == PM_TOKEN_FLOAT_RATIONAL); + + pm_rational_node_t *node = PM_NODE_ALLOC(parser, pm_rational_node_t); + *node = (pm_rational_node_t) { + { + .type = PM_RATIONAL_NODE, + .flags = PM_INTEGER_BASE_FLAGS_DECIMAL | PM_NODE_FLAG_STATIC_LITERAL, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(token) + }, + .numerator = { 0 }, + .denominator = { 0 } + }; + + const uint8_t *start = token->start; + const uint8_t *end = token->end - 1; // r + + while (start < end && *start == '0') start++; // 0.1 -> .1 + while (end > start && end[-1] == '0') end--; // 1.0 -> 1. + + size_t length = (size_t) (end - start); + if (length == 1) { + node->denominator.value = 1; + return node; + } + + const uint8_t *point = memchr(start, '.', length); + assert(point && "should have a decimal point"); + + uint8_t *digits = malloc(length); + if (digits == NULL) { + fputs("[pm_float_node_rational_create] Failed to allocate memory", stderr); + abort(); + } + + memcpy(digits, start, (unsigned long) (point - start)); + memcpy(digits + (point - start), point + 1, (unsigned long) (end - point - 1)); + pm_integer_parse(&node->numerator, PM_INTEGER_BASE_DEFAULT, digits, digits + length - 1); + + digits[0] = '1'; + if (end - point > 1) memset(digits + 1, '0', (size_t) (end - point - 1)); + pm_integer_parse(&node->denominator, PM_INTEGER_BASE_DEFAULT, digits, digits + (end - point)); + free(digits); + + pm_integers_reduce(&node->numerator, &node->denominator); + return node; +} + +/** + * Allocate and initialize a new FloatNode node from a FLOAT_RATIONAL_IMAGINARY + * token. + */ +static pm_imaginary_node_t * +pm_float_node_rational_imaginary_create(pm_parser_t *parser, const pm_token_t *token) { + assert(token->type == PM_TOKEN_FLOAT_RATIONAL_IMAGINARY); + + pm_imaginary_node_t *node = PM_NODE_ALLOC(parser, pm_imaginary_node_t); + *node = (pm_imaginary_node_t) { + { + .type = PM_IMAGINARY_NODE, + .flags = PM_NODE_FLAG_STATIC_LITERAL, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(token) + }, + .numeric = (pm_node_t *) pm_float_node_rational_create(parser, &((pm_token_t) { + .type = PM_TOKEN_FLOAT_RATIONAL, + .start = token->start, + .end = token->end - 1 + })) + }; + + return node; +} + +/** + * Allocate and initialize a new ForNode node. + */ +static pm_for_node_t * +pm_for_node_create( + pm_parser_t *parser, + pm_node_t *index, + pm_node_t *collection, + pm_statements_node_t *statements, + const pm_token_t *for_keyword, + const pm_token_t *in_keyword, + const pm_token_t *do_keyword, + const pm_token_t *end_keyword +) { + pm_for_node_t *node = PM_NODE_ALLOC(parser, pm_for_node_t); + + *node = (pm_for_node_t) { + { + .type = PM_FOR_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = for_keyword->start, + .end = end_keyword->end + }, + }, + .index = index, + .collection = collection, + .statements = statements, + .for_keyword_loc = PM_LOCATION_TOKEN_VALUE(for_keyword), + .in_keyword_loc = PM_LOCATION_TOKEN_VALUE(in_keyword), + .do_keyword_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(do_keyword), + .end_keyword_loc = PM_LOCATION_TOKEN_VALUE(end_keyword) + }; + + return node; +} + +/** + * Allocate and initialize a new ForwardingArgumentsNode node. + */ +static pm_forwarding_arguments_node_t * +pm_forwarding_arguments_node_create(pm_parser_t *parser, const pm_token_t *token) { + assert(token->type == PM_TOKEN_UDOT_DOT_DOT); + pm_forwarding_arguments_node_t *node = PM_NODE_ALLOC(parser, pm_forwarding_arguments_node_t); + + *node = (pm_forwarding_arguments_node_t) {{ + .type = PM_FORWARDING_ARGUMENTS_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(token) + }}; + + return node; +} + +/** + * Allocate and initialize a new ForwardingParameterNode node. + */ +static pm_forwarding_parameter_node_t * +pm_forwarding_parameter_node_create(pm_parser_t *parser, const pm_token_t *token) { + assert(token->type == PM_TOKEN_UDOT_DOT_DOT); + pm_forwarding_parameter_node_t *node = PM_NODE_ALLOC(parser, pm_forwarding_parameter_node_t); + + *node = (pm_forwarding_parameter_node_t) {{ + .type = PM_FORWARDING_PARAMETER_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(token) + }}; + + return node; +} + +/** + * Allocate and initialize a new ForwardingSuper node. + */ +static pm_forwarding_super_node_t * +pm_forwarding_super_node_create(pm_parser_t *parser, const pm_token_t *token, pm_arguments_t *arguments) { + assert(arguments->block == NULL || PM_NODE_TYPE_P(arguments->block, PM_BLOCK_NODE)); + assert(token->type == PM_TOKEN_KEYWORD_SUPER); + pm_forwarding_super_node_t *node = PM_NODE_ALLOC(parser, pm_forwarding_super_node_t); + + pm_block_node_t *block = NULL; + if (arguments->block != NULL) { + block = (pm_block_node_t *) arguments->block; + } + + *node = (pm_forwarding_super_node_t) { + { + .type = PM_FORWARDING_SUPER_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = token->start, + .end = block != NULL ? block->base.location.end : token->end + }, + }, + .block = block + }; + + return node; +} + +/** + * Allocate and initialize a new hash pattern node from an opening and closing + * token. + */ +static pm_hash_pattern_node_t * +pm_hash_pattern_node_empty_create(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *closing) { + pm_hash_pattern_node_t *node = PM_NODE_ALLOC(parser, pm_hash_pattern_node_t); + + *node = (pm_hash_pattern_node_t) { + { + .type = PM_HASH_PATTERN_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = opening->start, + .end = closing->end + }, + }, + .constant = NULL, + .opening_loc = PM_LOCATION_TOKEN_VALUE(opening), + .closing_loc = PM_LOCATION_TOKEN_VALUE(closing), + .elements = { 0 }, + .rest = NULL + }; + + return node; +} + +/** + * Allocate and initialize a new hash pattern node. + */ +static pm_hash_pattern_node_t * +pm_hash_pattern_node_node_list_create(pm_parser_t *parser, pm_node_list_t *elements, pm_node_t *rest) { + pm_hash_pattern_node_t *node = PM_NODE_ALLOC(parser, pm_hash_pattern_node_t); + + const uint8_t *start; + const uint8_t *end; + + if (elements->size > 0) { + if (rest) { + start = elements->nodes[0]->location.start; + end = rest->location.end; + } else { + start = elements->nodes[0]->location.start; + end = elements->nodes[elements->size - 1]->location.end; + } + } else { + assert(rest != NULL); + start = rest->location.start; + end = rest->location.end; + } + + *node = (pm_hash_pattern_node_t) { + { + .type = PM_HASH_PATTERN_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = start, + .end = end + }, + }, + .constant = NULL, + .elements = { 0 }, + .rest = rest, + .opening_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .closing_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE + }; + + pm_node_t *element; + PM_NODE_LIST_FOREACH(elements, index, element) { + pm_node_list_append(&node->elements, element); + } + + return node; +} + +/** + * Retrieve the name from a node that will become a global variable write node. + */ +static pm_constant_id_t +pm_global_variable_write_name(pm_parser_t *parser, const pm_node_t *target) { + switch (PM_NODE_TYPE(target)) { + case PM_GLOBAL_VARIABLE_READ_NODE: + return ((pm_global_variable_read_node_t *) target)->name; + case PM_BACK_REFERENCE_READ_NODE: + return ((pm_back_reference_read_node_t *) target)->name; + case PM_NUMBERED_REFERENCE_READ_NODE: + // This will only ever happen in the event of a syntax error, but we + // still need to provide something for the node. + return pm_parser_constant_id_location(parser, target->location.start, target->location.end); + default: + assert(false && "unreachable"); + return (pm_constant_id_t) -1; + } +} + +/** + * Allocate and initialize a new GlobalVariableAndWriteNode node. + */ +static pm_global_variable_and_write_node_t * +pm_global_variable_and_write_node_create(pm_parser_t *parser, pm_node_t *target, const pm_token_t *operator, pm_node_t *value) { + assert(operator->type == PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL); + pm_global_variable_and_write_node_t *node = PM_NODE_ALLOC(parser, pm_global_variable_and_write_node_t); + + *node = (pm_global_variable_and_write_node_t) { + { + .type = PM_GLOBAL_VARIABLE_AND_WRITE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->location.start, + .end = value->location.end + } + }, + .name = pm_global_variable_write_name(parser, target), + .name_loc = target->location, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + return node; +} + +/** + * Allocate and initialize a new GlobalVariableOperatorWriteNode node. + */ +static pm_global_variable_operator_write_node_t * +pm_global_variable_operator_write_node_create(pm_parser_t *parser, pm_node_t *target, const pm_token_t *operator, pm_node_t *value) { + pm_global_variable_operator_write_node_t *node = PM_NODE_ALLOC(parser, pm_global_variable_operator_write_node_t); + + *node = (pm_global_variable_operator_write_node_t) { + { + .type = PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->location.start, + .end = value->location.end + } + }, + .name = pm_global_variable_write_name(parser, target), + .name_loc = target->location, + .binary_operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value, + .binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1) + }; + + return node; +} + +/** + * Allocate and initialize a new GlobalVariableOrWriteNode node. + */ +static pm_global_variable_or_write_node_t * +pm_global_variable_or_write_node_create(pm_parser_t *parser, pm_node_t *target, const pm_token_t *operator, pm_node_t *value) { + assert(operator->type == PM_TOKEN_PIPE_PIPE_EQUAL); + pm_global_variable_or_write_node_t *node = PM_NODE_ALLOC(parser, pm_global_variable_or_write_node_t); + + *node = (pm_global_variable_or_write_node_t) { + { + .type = PM_GLOBAL_VARIABLE_OR_WRITE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->location.start, + .end = value->location.end + } + }, + .name = pm_global_variable_write_name(parser, target), + .name_loc = target->location, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + return node; +} + +/** + * Allocate a new GlobalVariableReadNode node. + */ +static pm_global_variable_read_node_t * +pm_global_variable_read_node_create(pm_parser_t *parser, const pm_token_t *name) { + pm_global_variable_read_node_t *node = PM_NODE_ALLOC(parser, pm_global_variable_read_node_t); + + *node = (pm_global_variable_read_node_t) { + { + .type = PM_GLOBAL_VARIABLE_READ_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(name), + }, + .name = pm_parser_constant_id_token(parser, name) + }; + + return node; +} + +/** + * Allocate and initialize a new synthesized GlobalVariableReadNode node. + */ +static pm_global_variable_read_node_t * +pm_global_variable_read_node_synthesized_create(pm_parser_t *parser, pm_constant_id_t name) { + pm_global_variable_read_node_t *node = PM_NODE_ALLOC(parser, pm_global_variable_read_node_t); + + *node = (pm_global_variable_read_node_t) { + { + .type = PM_GLOBAL_VARIABLE_READ_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_NULL_VALUE(parser) + }, + .name = name + }; + + return node; +} + +/** + * Allocate and initialize a new GlobalVariableWriteNode node. + */ +static pm_global_variable_write_node_t * +pm_global_variable_write_node_create(pm_parser_t *parser, pm_node_t *target, const pm_token_t *operator, pm_node_t *value) { + pm_global_variable_write_node_t *node = PM_NODE_ALLOC(parser, pm_global_variable_write_node_t); + + *node = (pm_global_variable_write_node_t) { + { + .type = PM_GLOBAL_VARIABLE_WRITE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .flags = pm_implicit_array_write_flags(value, PM_WRITE_NODE_FLAGS_IMPLICIT_ARRAY), + .location = { + .start = target->location.start, + .end = value->location.end + }, + }, + .name = pm_global_variable_write_name(parser, target), + .name_loc = PM_LOCATION_NODE_VALUE(target), + .operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + return node; +} + +/** + * Allocate and initialize a new synthesized GlobalVariableWriteNode node. + */ +static pm_global_variable_write_node_t * +pm_global_variable_write_node_synthesized_create(pm_parser_t *parser, pm_constant_id_t name, pm_node_t *value) { + pm_global_variable_write_node_t *node = PM_NODE_ALLOC(parser, pm_global_variable_write_node_t); + + *node = (pm_global_variable_write_node_t) { + { + .type = PM_GLOBAL_VARIABLE_WRITE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_NULL_VALUE(parser) + }, + .name = name, + .name_loc = PM_LOCATION_NULL_VALUE(parser), + .operator_loc = PM_LOCATION_NULL_VALUE(parser), + .value = value + }; + + return node; +} + +/** + * Allocate a new HashNode node. + */ +static pm_hash_node_t * +pm_hash_node_create(pm_parser_t *parser, const pm_token_t *opening) { + assert(opening != NULL); + pm_hash_node_t *node = PM_NODE_ALLOC(parser, pm_hash_node_t); + + *node = (pm_hash_node_t) { + { + .type = PM_HASH_NODE, + .flags = PM_NODE_FLAG_STATIC_LITERAL, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(opening) + }, + .opening_loc = PM_LOCATION_TOKEN_VALUE(opening), + .closing_loc = PM_LOCATION_NULL_VALUE(parser), + .elements = { 0 } + }; + + return node; +} + +/** + * Append a new element to a hash node. + */ +static inline void +pm_hash_node_elements_append(pm_hash_node_t *hash, pm_node_t *element) { + pm_node_list_append(&hash->elements, element); + + bool static_literal = PM_NODE_TYPE_P(element, PM_ASSOC_NODE); + if (static_literal) { + pm_assoc_node_t *assoc = (pm_assoc_node_t *) element; + static_literal = !PM_NODE_TYPE_P(assoc->key, PM_ARRAY_NODE) && !PM_NODE_TYPE_P(assoc->key, PM_HASH_NODE) && !PM_NODE_TYPE_P(assoc->key, PM_RANGE_NODE); + static_literal = static_literal && PM_NODE_FLAG_P(assoc->key, PM_NODE_FLAG_STATIC_LITERAL); + static_literal = static_literal && PM_NODE_FLAG_P(assoc, PM_NODE_FLAG_STATIC_LITERAL); + } + + if (!static_literal) { + pm_node_flag_unset((pm_node_t *)hash, PM_NODE_FLAG_STATIC_LITERAL); + } +} + +static inline void +pm_hash_node_closing_loc_set(pm_hash_node_t *hash, pm_token_t *token) { + hash->base.location.end = token->end; + hash->closing_loc = PM_LOCATION_TOKEN_VALUE(token); +} + +/** + * Allocate a new IfNode node. + */ +static pm_if_node_t * +pm_if_node_create(pm_parser_t *parser, + const pm_token_t *if_keyword, + pm_node_t *predicate, + const pm_token_t *then_keyword, + pm_statements_node_t *statements, + pm_node_t *subsequent, + const pm_token_t *end_keyword +) { + pm_conditional_predicate(parser, predicate, PM_CONDITIONAL_PREDICATE_TYPE_CONDITIONAL); + pm_if_node_t *node = PM_NODE_ALLOC(parser, pm_if_node_t); + + const uint8_t *end; + if (end_keyword->type != PM_TOKEN_NOT_PROVIDED) { + end = end_keyword->end; + } else if (subsequent != NULL) { + end = subsequent->location.end; + } else if (pm_statements_node_body_length(statements) != 0) { + end = statements->base.location.end; + } else { + end = predicate->location.end; + } + + *node = (pm_if_node_t) { + { + .type = PM_IF_NODE, + .flags = PM_NODE_FLAG_NEWLINE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = if_keyword->start, + .end = end + }, + }, + .if_keyword_loc = PM_LOCATION_TOKEN_VALUE(if_keyword), + .predicate = predicate, + .then_keyword_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(then_keyword), + .statements = statements, + .subsequent = subsequent, + .end_keyword_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(end_keyword) + }; + + return node; +} + +/** + * Allocate and initialize new IfNode node in the modifier form. + */ +static pm_if_node_t * +pm_if_node_modifier_create(pm_parser_t *parser, pm_node_t *statement, const pm_token_t *if_keyword, pm_node_t *predicate) { + pm_conditional_predicate(parser, predicate, PM_CONDITIONAL_PREDICATE_TYPE_CONDITIONAL); + pm_if_node_t *node = PM_NODE_ALLOC(parser, pm_if_node_t); + + pm_statements_node_t *statements = pm_statements_node_create(parser); + pm_statements_node_body_append(parser, statements, statement, true); + + *node = (pm_if_node_t) { + { + .type = PM_IF_NODE, + .flags = PM_NODE_FLAG_NEWLINE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = statement->location.start, + .end = predicate->location.end + }, + }, + .if_keyword_loc = PM_LOCATION_TOKEN_VALUE(if_keyword), + .predicate = predicate, + .then_keyword_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .statements = statements, + .subsequent = NULL, + .end_keyword_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE + }; + + return node; +} + +/** + * Allocate and initialize an if node from a ternary expression. + */ +static pm_if_node_t * +pm_if_node_ternary_create(pm_parser_t *parser, pm_node_t *predicate, const pm_token_t *qmark, pm_node_t *true_expression, const pm_token_t *colon, pm_node_t *false_expression) { + pm_assert_value_expression(parser, predicate); + pm_conditional_predicate(parser, predicate, PM_CONDITIONAL_PREDICATE_TYPE_CONDITIONAL); + + pm_statements_node_t *if_statements = pm_statements_node_create(parser); + pm_statements_node_body_append(parser, if_statements, true_expression, true); + + pm_statements_node_t *else_statements = pm_statements_node_create(parser); + pm_statements_node_body_append(parser, else_statements, false_expression, true); + + pm_token_t end_keyword = not_provided(parser); + pm_else_node_t *else_node = pm_else_node_create(parser, colon, else_statements, &end_keyword); + + pm_if_node_t *node = PM_NODE_ALLOC(parser, pm_if_node_t); + + *node = (pm_if_node_t) { + { + .type = PM_IF_NODE, + .flags = PM_NODE_FLAG_NEWLINE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = predicate->location.start, + .end = false_expression->location.end, + }, + }, + .if_keyword_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .predicate = predicate, + .then_keyword_loc = PM_LOCATION_TOKEN_VALUE(qmark), + .statements = if_statements, + .subsequent = (pm_node_t *) else_node, + .end_keyword_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE + }; + + return node; + +} + +static inline void +pm_if_node_end_keyword_loc_set(pm_if_node_t *node, const pm_token_t *keyword) { + node->base.location.end = keyword->end; + node->end_keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword); +} + +static inline void +pm_else_node_end_keyword_loc_set(pm_else_node_t *node, const pm_token_t *keyword) { + node->base.location.end = keyword->end; + node->end_keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword); +} + +/** + * Allocate and initialize a new ImplicitNode node. + */ +static pm_implicit_node_t * +pm_implicit_node_create(pm_parser_t *parser, pm_node_t *value) { + pm_implicit_node_t *node = PM_NODE_ALLOC(parser, pm_implicit_node_t); + + *node = (pm_implicit_node_t) { + { + .type = PM_IMPLICIT_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = value->location + }, + .value = value + }; + + return node; +} + +/** + * Allocate and initialize a new ImplicitRestNode node. + */ +static pm_implicit_rest_node_t * +pm_implicit_rest_node_create(pm_parser_t *parser, const pm_token_t *token) { + assert(token->type == PM_TOKEN_COMMA); + + pm_implicit_rest_node_t *node = PM_NODE_ALLOC(parser, pm_implicit_rest_node_t); + + *node = (pm_implicit_rest_node_t) { + { + .type = PM_IMPLICIT_REST_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(token) + } + }; + + return node; +} + +/** + * Allocate and initialize a new IntegerNode node. + */ +static pm_integer_node_t * +pm_integer_node_create(pm_parser_t *parser, pm_node_flags_t base, const pm_token_t *token) { + assert(token->type == PM_TOKEN_INTEGER); + pm_integer_node_t *node = PM_NODE_ALLOC(parser, pm_integer_node_t); + + *node = (pm_integer_node_t) { + { + .type = PM_INTEGER_NODE, + .flags = base | PM_NODE_FLAG_STATIC_LITERAL, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(token) + }, + .value = { 0 } + }; + + pm_integer_base_t integer_base = PM_INTEGER_BASE_DECIMAL; + switch (base) { + case PM_INTEGER_BASE_FLAGS_BINARY: integer_base = PM_INTEGER_BASE_BINARY; break; + case PM_INTEGER_BASE_FLAGS_OCTAL: integer_base = PM_INTEGER_BASE_OCTAL; break; + case PM_INTEGER_BASE_FLAGS_DECIMAL: break; + case PM_INTEGER_BASE_FLAGS_HEXADECIMAL: integer_base = PM_INTEGER_BASE_HEXADECIMAL; break; + default: assert(false && "unreachable"); break; + } + + pm_integer_parse(&node->value, integer_base, token->start, token->end); + return node; +} + +/** + * Allocate and initialize a new IntegerNode node from an INTEGER_IMAGINARY + * token. + */ +static pm_imaginary_node_t * +pm_integer_node_imaginary_create(pm_parser_t *parser, pm_node_flags_t base, const pm_token_t *token) { + assert(token->type == PM_TOKEN_INTEGER_IMAGINARY); + + pm_imaginary_node_t *node = PM_NODE_ALLOC(parser, pm_imaginary_node_t); + *node = (pm_imaginary_node_t) { + { + .type = PM_IMAGINARY_NODE, + .flags = PM_NODE_FLAG_STATIC_LITERAL, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(token) + }, + .numeric = (pm_node_t *) pm_integer_node_create(parser, base, &((pm_token_t) { + .type = PM_TOKEN_INTEGER, + .start = token->start, + .end = token->end - 1 + })) + }; + + return node; +} + +/** + * Allocate and initialize a new RationalNode node from an INTEGER_RATIONAL + * token. + */ +static pm_rational_node_t * +pm_integer_node_rational_create(pm_parser_t *parser, pm_node_flags_t base, const pm_token_t *token) { + assert(token->type == PM_TOKEN_INTEGER_RATIONAL); + + pm_rational_node_t *node = PM_NODE_ALLOC(parser, pm_rational_node_t); + *node = (pm_rational_node_t) { + { + .type = PM_RATIONAL_NODE, + .flags = base | PM_NODE_FLAG_STATIC_LITERAL, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(token) + }, + .numerator = { 0 }, + .denominator = { .value = 1, 0 } + }; + + pm_integer_base_t integer_base = PM_INTEGER_BASE_DECIMAL; + switch (base) { + case PM_INTEGER_BASE_FLAGS_BINARY: integer_base = PM_INTEGER_BASE_BINARY; break; + case PM_INTEGER_BASE_FLAGS_OCTAL: integer_base = PM_INTEGER_BASE_OCTAL; break; + case PM_INTEGER_BASE_FLAGS_DECIMAL: break; + case PM_INTEGER_BASE_FLAGS_HEXADECIMAL: integer_base = PM_INTEGER_BASE_HEXADECIMAL; break; + default: assert(false && "unreachable"); break; + } + + pm_integer_parse(&node->numerator, integer_base, token->start, token->end - 1); + + return node; +} + +/** + * Allocate and initialize a new IntegerNode node from an + * INTEGER_RATIONAL_IMAGINARY token. + */ +static pm_imaginary_node_t * +pm_integer_node_rational_imaginary_create(pm_parser_t *parser, pm_node_flags_t base, const pm_token_t *token) { + assert(token->type == PM_TOKEN_INTEGER_RATIONAL_IMAGINARY); + + pm_imaginary_node_t *node = PM_NODE_ALLOC(parser, pm_imaginary_node_t); + *node = (pm_imaginary_node_t) { + { + .type = PM_IMAGINARY_NODE, + .flags = PM_NODE_FLAG_STATIC_LITERAL, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(token) + }, + .numeric = (pm_node_t *) pm_integer_node_rational_create(parser, base, &((pm_token_t) { + .type = PM_TOKEN_INTEGER_RATIONAL, + .start = token->start, + .end = token->end - 1 + })) + }; + + return node; +} + +/** + * Allocate and initialize a new InNode node. + */ +static pm_in_node_t * +pm_in_node_create(pm_parser_t *parser, pm_node_t *pattern, pm_statements_node_t *statements, const pm_token_t *in_keyword, const pm_token_t *then_keyword) { + pm_in_node_t *node = PM_NODE_ALLOC(parser, pm_in_node_t); + + const uint8_t *end; + if (statements != NULL) { + end = statements->base.location.end; + } else if (then_keyword->type != PM_TOKEN_NOT_PROVIDED) { + end = then_keyword->end; + } else { + end = pattern->location.end; + } + + *node = (pm_in_node_t) { + { + .type = PM_IN_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = in_keyword->start, + .end = end + }, + }, + .pattern = pattern, + .statements = statements, + .in_loc = PM_LOCATION_TOKEN_VALUE(in_keyword), + .then_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(then_keyword) + }; + + return node; +} + +/** + * Allocate and initialize a new InstanceVariableAndWriteNode node. + */ +static pm_instance_variable_and_write_node_t * +pm_instance_variable_and_write_node_create(pm_parser_t *parser, pm_instance_variable_read_node_t *target, const pm_token_t *operator, pm_node_t *value) { + assert(operator->type == PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL); + pm_instance_variable_and_write_node_t *node = PM_NODE_ALLOC(parser, pm_instance_variable_and_write_node_t); + + *node = (pm_instance_variable_and_write_node_t) { + { + .type = PM_INSTANCE_VARIABLE_AND_WRITE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->base.location.start, + .end = value->location.end + } + }, + .name = target->name, + .name_loc = target->base.location, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + return node; +} + +/** + * Allocate and initialize a new InstanceVariableOperatorWriteNode node. + */ +static pm_instance_variable_operator_write_node_t * +pm_instance_variable_operator_write_node_create(pm_parser_t *parser, pm_instance_variable_read_node_t *target, const pm_token_t *operator, pm_node_t *value) { + pm_instance_variable_operator_write_node_t *node = PM_NODE_ALLOC(parser, pm_instance_variable_operator_write_node_t); + + *node = (pm_instance_variable_operator_write_node_t) { + { + .type = PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->base.location.start, + .end = value->location.end + } + }, + .name = target->name, + .name_loc = target->base.location, + .binary_operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value, + .binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1) + }; + + return node; +} + +/** + * Allocate and initialize a new InstanceVariableOrWriteNode node. + */ +static pm_instance_variable_or_write_node_t * +pm_instance_variable_or_write_node_create(pm_parser_t *parser, pm_instance_variable_read_node_t *target, const pm_token_t *operator, pm_node_t *value) { + assert(operator->type == PM_TOKEN_PIPE_PIPE_EQUAL); + pm_instance_variable_or_write_node_t *node = PM_NODE_ALLOC(parser, pm_instance_variable_or_write_node_t); + + *node = (pm_instance_variable_or_write_node_t) { + { + .type = PM_INSTANCE_VARIABLE_OR_WRITE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->base.location.start, + .end = value->location.end + } + }, + .name = target->name, + .name_loc = target->base.location, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + return node; +} + +/** + * Allocate and initialize a new InstanceVariableReadNode node. + */ +static pm_instance_variable_read_node_t * +pm_instance_variable_read_node_create(pm_parser_t *parser, const pm_token_t *token) { + assert(token->type == PM_TOKEN_INSTANCE_VARIABLE); + pm_instance_variable_read_node_t *node = PM_NODE_ALLOC(parser, pm_instance_variable_read_node_t); + + *node = (pm_instance_variable_read_node_t) { + { + .type = PM_INSTANCE_VARIABLE_READ_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(token) + }, + .name = pm_parser_constant_id_token(parser, token) + }; + + return node; +} + +/** + * Initialize a new InstanceVariableWriteNode node from an InstanceVariableRead + * node. + */ +static pm_instance_variable_write_node_t * +pm_instance_variable_write_node_create(pm_parser_t *parser, pm_instance_variable_read_node_t *read_node, pm_token_t *operator, pm_node_t *value) { + pm_instance_variable_write_node_t *node = PM_NODE_ALLOC(parser, pm_instance_variable_write_node_t); + *node = (pm_instance_variable_write_node_t) { + { + .type = PM_INSTANCE_VARIABLE_WRITE_NODE, + .flags = pm_implicit_array_write_flags(value, PM_WRITE_NODE_FLAGS_IMPLICIT_ARRAY), + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = read_node->base.location.start, + .end = value->location.end + } + }, + .name = read_node->name, + .name_loc = PM_LOCATION_NODE_BASE_VALUE(read_node), + .operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + return node; +} + +/** + * Append a part into a list of string parts. Importantly this handles nested + * interpolated strings by not necessarily removing the marker for static + * literals. + */ +static void +pm_interpolated_node_append(pm_node_t *node, pm_node_list_t *parts, pm_node_t *part) { + switch (PM_NODE_TYPE(part)) { + case PM_STRING_NODE: + pm_node_flag_set(part, PM_NODE_FLAG_STATIC_LITERAL | PM_STRING_FLAGS_FROZEN); + break; + case PM_EMBEDDED_STATEMENTS_NODE: { + pm_embedded_statements_node_t *cast = (pm_embedded_statements_node_t *) part; + pm_node_t *embedded = (cast->statements != NULL && cast->statements->body.size == 1) ? cast->statements->body.nodes[0] : NULL; + + if (embedded == NULL) { + // If there are no statements or more than one statement, then + // we lose the static literal flag. + pm_node_flag_unset(node, PM_NODE_FLAG_STATIC_LITERAL); + } else if (PM_NODE_TYPE_P(embedded, PM_STRING_NODE)) { + // If the embedded statement is a string, then we can keep the + // static literal flag and mark the string as frozen. + pm_node_flag_set(embedded, PM_NODE_FLAG_STATIC_LITERAL | PM_STRING_FLAGS_FROZEN); + } else if (PM_NODE_TYPE_P(embedded, PM_INTERPOLATED_STRING_NODE) && PM_NODE_FLAG_P(embedded, PM_NODE_FLAG_STATIC_LITERAL)) { + // If the embedded statement is an interpolated string and it's + // a static literal, then we can keep the static literal flag. + } else { + // Otherwise we lose the static literal flag. + pm_node_flag_unset(node, PM_NODE_FLAG_STATIC_LITERAL); + } + + break; + } + case PM_EMBEDDED_VARIABLE_NODE: + pm_node_flag_unset((pm_node_t *) node, PM_NODE_FLAG_STATIC_LITERAL); + break; + default: + assert(false && "unexpected node type"); + break; + } + + pm_node_list_append(parts, part); +} + +/** + * Allocate a new InterpolatedRegularExpressionNode node. + */ +static pm_interpolated_regular_expression_node_t * +pm_interpolated_regular_expression_node_create(pm_parser_t *parser, const pm_token_t *opening) { + pm_interpolated_regular_expression_node_t *node = PM_NODE_ALLOC(parser, pm_interpolated_regular_expression_node_t); + + *node = (pm_interpolated_regular_expression_node_t) { + { + .type = PM_INTERPOLATED_REGULAR_EXPRESSION_NODE, + .flags = PM_NODE_FLAG_STATIC_LITERAL, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = opening->start, + .end = NULL, + }, + }, + .opening_loc = PM_LOCATION_TOKEN_VALUE(opening), + .closing_loc = PM_LOCATION_TOKEN_VALUE(opening), + .parts = { 0 } + }; + + return node; +} + +static inline void +pm_interpolated_regular_expression_node_append(pm_interpolated_regular_expression_node_t *node, pm_node_t *part) { + if (node->base.location.start > part->location.start) { + node->base.location.start = part->location.start; + } + if (node->base.location.end < part->location.end) { + node->base.location.end = part->location.end; + } + + pm_interpolated_node_append((pm_node_t *) node, &node->parts, part); +} + +static inline void +pm_interpolated_regular_expression_node_closing_set(pm_parser_t *parser, pm_interpolated_regular_expression_node_t *node, const pm_token_t *closing) { + node->closing_loc = PM_LOCATION_TOKEN_VALUE(closing); + node->base.location.end = closing->end; + pm_node_flag_set((pm_node_t *) node, pm_regular_expression_flags_create(parser, closing)); +} + +/** + * Append a part to an InterpolatedStringNode node. + * + * This has some somewhat complicated semantics, because we need to update + * multiple flags that have somewhat confusing interactions. + * + * PM_NODE_FLAG_STATIC_LITERAL indicates that the node should be treated as a + * single static literal string that can be pushed onto the stack on its own. + * Note that this doesn't necessarily mean that the string will be frozen or + * not; the instructions in CRuby will be either putobject or putstring, + * depending on the combination of `--enable-frozen-string-literal`, + * `# frozen_string_literal: true`, and whether or not there is interpolation. + * + * PM_INTERPOLATED_STRING_NODE_FLAGS_FROZEN indicates that the string should be + * explicitly frozen. This will only happen if the string is comprised entirely + * of string parts that are themselves static literals and frozen. + * + * PM_INTERPOLATED_STRING_NODE_FLAGS_MUTABLE indicates that the string should + * be explicitly marked as mutable. This will happen from + * `--disable-frozen-string-literal` or `# frozen_string_literal: false`. This + * is necessary to indicate that the string should be left up to the runtime, + * which could potentially use a chilled string otherwise. + */ +static inline void +pm_interpolated_string_node_append(pm_interpolated_string_node_t *node, pm_node_t *part) { +#define CLEAR_FLAGS(node) \ + node->base.flags = (pm_node_flags_t) (node->base.flags & ~(PM_NODE_FLAG_STATIC_LITERAL | PM_INTERPOLATED_STRING_NODE_FLAGS_FROZEN | PM_INTERPOLATED_STRING_NODE_FLAGS_MUTABLE)) + +#define MUTABLE_FLAGS(node) \ + node->base.flags = (pm_node_flags_t) ((node->base.flags | PM_INTERPOLATED_STRING_NODE_FLAGS_MUTABLE) & ~PM_INTERPOLATED_STRING_NODE_FLAGS_FROZEN); + + if (node->parts.size == 0 && node->opening_loc.start == NULL) { + node->base.location.start = part->location.start; + } + + node->base.location.end = MAX(node->base.location.end, part->location.end); + + switch (PM_NODE_TYPE(part)) { + case PM_STRING_NODE: + part->flags = (pm_node_flags_t) ((part->flags | PM_NODE_FLAG_STATIC_LITERAL | PM_STRING_FLAGS_FROZEN) & ~PM_STRING_FLAGS_MUTABLE); + break; + case PM_INTERPOLATED_STRING_NODE: + if (PM_NODE_FLAG_P(part, PM_NODE_FLAG_STATIC_LITERAL)) { + // If the string that we're concatenating is a static literal, + // then we can keep the static literal flag for this string. + } else { + // Otherwise, we lose the static literal flag here and we should + // also clear the mutability flags. + CLEAR_FLAGS(node); + } + break; + case PM_EMBEDDED_STATEMENTS_NODE: { + pm_embedded_statements_node_t *cast = (pm_embedded_statements_node_t *) part; + pm_node_t *embedded = (cast->statements != NULL && cast->statements->body.size == 1) ? cast->statements->body.nodes[0] : NULL; + + if (embedded == NULL) { + // If we're embedding multiple statements or no statements, then + // the string is not longer a static literal. + CLEAR_FLAGS(node); + } else if (PM_NODE_TYPE_P(embedded, PM_STRING_NODE)) { + // If the embedded statement is a string, then we can make that + // string as frozen and static literal, and not touch the static + // literal status of this string. + embedded->flags = (pm_node_flags_t) ((embedded->flags | PM_NODE_FLAG_STATIC_LITERAL | PM_STRING_FLAGS_FROZEN) & ~PM_STRING_FLAGS_MUTABLE); + + if (PM_NODE_FLAG_P(node, PM_NODE_FLAG_STATIC_LITERAL)) { + MUTABLE_FLAGS(node); + } + } else if (PM_NODE_TYPE_P(embedded, PM_INTERPOLATED_STRING_NODE) && PM_NODE_FLAG_P(embedded, PM_NODE_FLAG_STATIC_LITERAL)) { + // If the embedded statement is an interpolated string, but that + // string is marked as static literal, then we can keep our + // static literal status for this string. + if (PM_NODE_FLAG_P(node, PM_NODE_FLAG_STATIC_LITERAL)) { + MUTABLE_FLAGS(node); + } + } else { + // In all other cases, we lose the static literal flag here and + // become mutable. + CLEAR_FLAGS(node); + } + + break; + } + case PM_EMBEDDED_VARIABLE_NODE: + // Embedded variables clear static literal, which means we also + // should clear the mutability flags. + CLEAR_FLAGS(node); + break; + case PM_X_STRING_NODE: + case PM_INTERPOLATED_X_STRING_NODE: + // If this is an x string, then this is a syntax error. But we want + // to handle it here so that we don't fail the assertion. + CLEAR_FLAGS(node); + break; + default: + assert(false && "unexpected node type"); + break; + } + + pm_node_list_append(&node->parts, part); + +#undef CLEAR_FLAGS +#undef MUTABLE_FLAGS +} + +/** + * Allocate and initialize a new InterpolatedStringNode node. + */ +static pm_interpolated_string_node_t * +pm_interpolated_string_node_create(pm_parser_t *parser, const pm_token_t *opening, const pm_node_list_t *parts, const pm_token_t *closing) { + pm_interpolated_string_node_t *node = PM_NODE_ALLOC(parser, pm_interpolated_string_node_t); + pm_node_flags_t flags = PM_NODE_FLAG_STATIC_LITERAL; + + switch (parser->frozen_string_literal) { + case PM_OPTIONS_FROZEN_STRING_LITERAL_DISABLED: + flags |= PM_INTERPOLATED_STRING_NODE_FLAGS_MUTABLE; + break; + case PM_OPTIONS_FROZEN_STRING_LITERAL_ENABLED: + flags |= PM_INTERPOLATED_STRING_NODE_FLAGS_FROZEN; + break; + } + + *node = (pm_interpolated_string_node_t) { + { + .type = PM_INTERPOLATED_STRING_NODE, + .flags = flags, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = opening->start, + .end = closing->end, + }, + }, + .opening_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(opening), + .closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(closing), + .parts = { 0 } + }; + + if (parts != NULL) { + pm_node_t *part; + PM_NODE_LIST_FOREACH(parts, index, part) { + pm_interpolated_string_node_append(node, part); + } + } + + return node; +} + +/** + * Set the closing token of the given InterpolatedStringNode node. + */ +static void +pm_interpolated_string_node_closing_set(pm_interpolated_string_node_t *node, const pm_token_t *closing) { + node->closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(closing); + node->base.location.end = closing->end; +} + +static void +pm_interpolated_symbol_node_append(pm_interpolated_symbol_node_t *node, pm_node_t *part) { + if (node->parts.size == 0 && node->opening_loc.start == NULL) { + node->base.location.start = part->location.start; + } + + pm_interpolated_node_append((pm_node_t *) node, &node->parts, part); + node->base.location.end = MAX(node->base.location.end, part->location.end); +} + +static void +pm_interpolated_symbol_node_closing_loc_set(pm_interpolated_symbol_node_t *node, const pm_token_t *closing) { + node->closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(closing); + node->base.location.end = closing->end; +} + +/** + * Allocate and initialize a new InterpolatedSymbolNode node. + */ +static pm_interpolated_symbol_node_t * +pm_interpolated_symbol_node_create(pm_parser_t *parser, const pm_token_t *opening, const pm_node_list_t *parts, const pm_token_t *closing) { + pm_interpolated_symbol_node_t *node = PM_NODE_ALLOC(parser, pm_interpolated_symbol_node_t); + + *node = (pm_interpolated_symbol_node_t) { + { + .type = PM_INTERPOLATED_SYMBOL_NODE, + .flags = PM_NODE_FLAG_STATIC_LITERAL, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = opening->start, + .end = closing->end, + }, + }, + .opening_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(opening), + .closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(closing), + .parts = { 0 } + }; + + if (parts != NULL) { + pm_node_t *part; + PM_NODE_LIST_FOREACH(parts, index, part) { + pm_interpolated_symbol_node_append(node, part); + } + } + + return node; +} + +/** + * Allocate a new InterpolatedXStringNode node. + */ +static pm_interpolated_x_string_node_t * +pm_interpolated_xstring_node_create(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *closing) { + pm_interpolated_x_string_node_t *node = PM_NODE_ALLOC(parser, pm_interpolated_x_string_node_t); + + *node = (pm_interpolated_x_string_node_t) { + { + .type = PM_INTERPOLATED_X_STRING_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = opening->start, + .end = closing->end + }, + }, + .opening_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(opening), + .closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(closing), + .parts = { 0 } + }; + + return node; +} + +static inline void +pm_interpolated_xstring_node_append(pm_interpolated_x_string_node_t *node, pm_node_t *part) { + pm_interpolated_node_append((pm_node_t *) node, &node->parts, part); + node->base.location.end = part->location.end; +} + +static inline void +pm_interpolated_xstring_node_closing_set(pm_interpolated_x_string_node_t *node, const pm_token_t *closing) { + node->closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(closing); + node->base.location.end = closing->end; +} + +/** + * Create a local variable read that is reading the implicit 'it' variable. + */ +static pm_it_local_variable_read_node_t * +pm_it_local_variable_read_node_create(pm_parser_t *parser, const pm_token_t *name) { + pm_it_local_variable_read_node_t *node = PM_NODE_ALLOC(parser, pm_it_local_variable_read_node_t); + + *node = (pm_it_local_variable_read_node_t) { + { + .type = PM_IT_LOCAL_VARIABLE_READ_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(name) + } + }; + + return node; +} + +/** + * Allocate and initialize a new ItParametersNode node. + */ +static pm_it_parameters_node_t * +pm_it_parameters_node_create(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *closing) { + pm_it_parameters_node_t *node = PM_NODE_ALLOC(parser, pm_it_parameters_node_t); + + *node = (pm_it_parameters_node_t) { + { + .type = PM_IT_PARAMETERS_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = opening->start, + .end = closing->end + } + } + }; + + return node; +} + +/** + * Allocate a new KeywordHashNode node. + */ +static pm_keyword_hash_node_t * +pm_keyword_hash_node_create(pm_parser_t *parser) { + pm_keyword_hash_node_t *node = PM_NODE_ALLOC(parser, pm_keyword_hash_node_t); + + *node = (pm_keyword_hash_node_t) { + .base = { + .type = PM_KEYWORD_HASH_NODE, + .flags = PM_KEYWORD_HASH_NODE_FLAGS_SYMBOL_KEYS, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE + }, + .elements = { 0 } + }; + + return node; +} + +/** + * Append an element to a KeywordHashNode node. + */ +static void +pm_keyword_hash_node_elements_append(pm_keyword_hash_node_t *hash, pm_node_t *element) { + // If the element being added is not an AssocNode or does not have a symbol + // key, then we want to turn the SYMBOL_KEYS flag off. + if (!PM_NODE_TYPE_P(element, PM_ASSOC_NODE) || !PM_NODE_TYPE_P(((pm_assoc_node_t *) element)->key, PM_SYMBOL_NODE)) { + pm_node_flag_unset((pm_node_t *)hash, PM_KEYWORD_HASH_NODE_FLAGS_SYMBOL_KEYS); + } + + pm_node_list_append(&hash->elements, element); + if (hash->base.location.start == NULL) { + hash->base.location.start = element->location.start; + } + hash->base.location.end = element->location.end; +} + +/** + * Allocate and initialize a new RequiredKeywordParameterNode node. + */ +static pm_required_keyword_parameter_node_t * +pm_required_keyword_parameter_node_create(pm_parser_t *parser, const pm_token_t *name) { + pm_required_keyword_parameter_node_t *node = PM_NODE_ALLOC(parser, pm_required_keyword_parameter_node_t); + + *node = (pm_required_keyword_parameter_node_t) { + { + .type = PM_REQUIRED_KEYWORD_PARAMETER_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = name->start, + .end = name->end + }, + }, + .name = pm_parser_constant_id_location(parser, name->start, name->end - 1), + .name_loc = PM_LOCATION_TOKEN_VALUE(name), + }; + + return node; +} + +/** + * Allocate a new OptionalKeywordParameterNode node. + */ +static pm_optional_keyword_parameter_node_t * +pm_optional_keyword_parameter_node_create(pm_parser_t *parser, const pm_token_t *name, pm_node_t *value) { + pm_optional_keyword_parameter_node_t *node = PM_NODE_ALLOC(parser, pm_optional_keyword_parameter_node_t); + + *node = (pm_optional_keyword_parameter_node_t) { + { + .type = PM_OPTIONAL_KEYWORD_PARAMETER_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = name->start, + .end = value->location.end + }, + }, + .name = pm_parser_constant_id_location(parser, name->start, name->end - 1), + .name_loc = PM_LOCATION_TOKEN_VALUE(name), + .value = value + }; + + return node; +} + +/** + * Allocate a new KeywordRestParameterNode node. + */ +static pm_keyword_rest_parameter_node_t * +pm_keyword_rest_parameter_node_create(pm_parser_t *parser, const pm_token_t *operator, const pm_token_t *name) { + pm_keyword_rest_parameter_node_t *node = PM_NODE_ALLOC(parser, pm_keyword_rest_parameter_node_t); + + *node = (pm_keyword_rest_parameter_node_t) { + { + .type = PM_KEYWORD_REST_PARAMETER_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = operator->start, + .end = (name->type == PM_TOKEN_NOT_PROVIDED ? operator->end : name->end) + }, + }, + .name = pm_parser_optional_constant_id_token(parser, name), + .name_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(name), + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator) + }; + + return node; +} + +/** + * Allocate a new LambdaNode node. + */ +static pm_lambda_node_t * +pm_lambda_node_create( + pm_parser_t *parser, + pm_constant_id_list_t *locals, + const pm_token_t *operator, + const pm_token_t *opening, + const pm_token_t *closing, + pm_node_t *parameters, + pm_node_t *body +) { + pm_lambda_node_t *node = PM_NODE_ALLOC(parser, pm_lambda_node_t); + + *node = (pm_lambda_node_t) { + { + .type = PM_LAMBDA_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = operator->start, + .end = closing->end + }, + }, + .locals = *locals, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .opening_loc = PM_LOCATION_TOKEN_VALUE(opening), + .closing_loc = PM_LOCATION_TOKEN_VALUE(closing), + .parameters = parameters, + .body = body + }; + + return node; +} + +/** + * Allocate and initialize a new LocalVariableAndWriteNode node. + */ +static pm_local_variable_and_write_node_t * +pm_local_variable_and_write_node_create(pm_parser_t *parser, pm_node_t *target, const pm_token_t *operator, pm_node_t *value, pm_constant_id_t name, uint32_t depth) { + assert(PM_NODE_TYPE_P(target, PM_LOCAL_VARIABLE_READ_NODE) || PM_NODE_TYPE_P(target, PM_IT_LOCAL_VARIABLE_READ_NODE) || PM_NODE_TYPE_P(target, PM_CALL_NODE)); + assert(operator->type == PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL); + pm_local_variable_and_write_node_t *node = PM_NODE_ALLOC(parser, pm_local_variable_and_write_node_t); + + *node = (pm_local_variable_and_write_node_t) { + { + .type = PM_LOCAL_VARIABLE_AND_WRITE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->location.start, + .end = value->location.end + } + }, + .name_loc = target->location, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value, + .name = name, + .depth = depth + }; + + return node; +} + +/** + * Allocate and initialize a new LocalVariableOperatorWriteNode node. + */ +static pm_local_variable_operator_write_node_t * +pm_local_variable_operator_write_node_create(pm_parser_t *parser, pm_node_t *target, const pm_token_t *operator, pm_node_t *value, pm_constant_id_t name, uint32_t depth) { + pm_local_variable_operator_write_node_t *node = PM_NODE_ALLOC(parser, pm_local_variable_operator_write_node_t); + + *node = (pm_local_variable_operator_write_node_t) { + { + .type = PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->location.start, + .end = value->location.end + } + }, + .name_loc = target->location, + .binary_operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value, + .name = name, + .binary_operator = pm_parser_constant_id_location(parser, operator->start, operator->end - 1), + .depth = depth + }; + + return node; +} + +/** + * Allocate and initialize a new LocalVariableOrWriteNode node. + */ +static pm_local_variable_or_write_node_t * +pm_local_variable_or_write_node_create(pm_parser_t *parser, pm_node_t *target, const pm_token_t *operator, pm_node_t *value, pm_constant_id_t name, uint32_t depth) { + assert(PM_NODE_TYPE_P(target, PM_LOCAL_VARIABLE_READ_NODE) || PM_NODE_TYPE_P(target, PM_IT_LOCAL_VARIABLE_READ_NODE) || PM_NODE_TYPE_P(target, PM_CALL_NODE)); + assert(operator->type == PM_TOKEN_PIPE_PIPE_EQUAL); + pm_local_variable_or_write_node_t *node = PM_NODE_ALLOC(parser, pm_local_variable_or_write_node_t); + + *node = (pm_local_variable_or_write_node_t) { + { + .type = PM_LOCAL_VARIABLE_OR_WRITE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->location.start, + .end = value->location.end + } + }, + .name_loc = target->location, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value, + .name = name, + .depth = depth + }; + + return node; +} + +/** + * Allocate a new LocalVariableReadNode node with constant_id. + */ +static pm_local_variable_read_node_t * +pm_local_variable_read_node_create_constant_id(pm_parser_t *parser, const pm_token_t *name, pm_constant_id_t name_id, uint32_t depth, bool missing) { + if (!missing) pm_locals_read(&pm_parser_scope_find(parser, depth)->locals, name_id); + + pm_local_variable_read_node_t *node = PM_NODE_ALLOC(parser, pm_local_variable_read_node_t); + + *node = (pm_local_variable_read_node_t) { + { + .type = PM_LOCAL_VARIABLE_READ_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(name) + }, + .name = name_id, + .depth = depth + }; + + return node; +} + +/** + * Allocate and initialize a new LocalVariableReadNode node. + */ +static pm_local_variable_read_node_t * +pm_local_variable_read_node_create(pm_parser_t *parser, const pm_token_t *name, uint32_t depth) { + pm_constant_id_t name_id = pm_parser_constant_id_token(parser, name); + return pm_local_variable_read_node_create_constant_id(parser, name, name_id, depth, false); +} + +/** + * Allocate and initialize a new LocalVariableReadNode node for a missing local + * variable. (This will only happen when there is a syntax error.) + */ +static pm_local_variable_read_node_t * +pm_local_variable_read_node_missing_create(pm_parser_t *parser, const pm_token_t *name, uint32_t depth) { + pm_constant_id_t name_id = pm_parser_constant_id_token(parser, name); + return pm_local_variable_read_node_create_constant_id(parser, name, name_id, depth, true); +} + +/** + * Allocate and initialize a new LocalVariableWriteNode node. + */ +static pm_local_variable_write_node_t * +pm_local_variable_write_node_create(pm_parser_t *parser, pm_constant_id_t name, uint32_t depth, pm_node_t *value, const pm_location_t *name_loc, const pm_token_t *operator) { + pm_local_variable_write_node_t *node = PM_NODE_ALLOC(parser, pm_local_variable_write_node_t); + + *node = (pm_local_variable_write_node_t) { + { + .type = PM_LOCAL_VARIABLE_WRITE_NODE, + .flags = pm_implicit_array_write_flags(value, PM_WRITE_NODE_FLAGS_IMPLICIT_ARRAY), + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = name_loc->start, + .end = value->location.end + } + }, + .name = name, + .depth = depth, + .value = value, + .name_loc = *name_loc, + .operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator) + }; + + return node; +} + +/** + * Returns true if the given bounds comprise `it`. + */ +static inline bool +pm_token_is_it(const uint8_t *start, const uint8_t *end) { + return (end - start == 2) && (start[0] == 'i') && (start[1] == 't'); +} + +/** + * Returns true if the given bounds comprise a numbered parameter (i.e., they + * are of the form /^_\d$/). + */ +static inline bool +pm_token_is_numbered_parameter(const uint8_t *start, const uint8_t *end) { + return (end - start == 2) && (start[0] == '_') && (start[1] != '0') && (pm_char_is_decimal_digit(start[1])); +} + +/** + * Ensure the given bounds do not comprise a numbered parameter. If they do, add + * an appropriate error message to the parser. + */ +static inline void +pm_refute_numbered_parameter(pm_parser_t *parser, const uint8_t *start, const uint8_t *end) { + if (pm_token_is_numbered_parameter(start, end)) { + PM_PARSER_ERR_FORMAT(parser, start, end, PM_ERR_PARAMETER_NUMBERED_RESERVED, start); + } +} + +/** + * Allocate and initialize a new LocalVariableTargetNode node with the given + * name and depth. + */ +static pm_local_variable_target_node_t * +pm_local_variable_target_node_create(pm_parser_t *parser, const pm_location_t *location, pm_constant_id_t name, uint32_t depth) { + pm_refute_numbered_parameter(parser, location->start, location->end); + pm_local_variable_target_node_t *node = PM_NODE_ALLOC(parser, pm_local_variable_target_node_t); + + *node = (pm_local_variable_target_node_t) { + { + .type = PM_LOCAL_VARIABLE_TARGET_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = *location + }, + .name = name, + .depth = depth + }; + + return node; +} + +/** + * Allocate and initialize a new MatchPredicateNode node. + */ +static pm_match_predicate_node_t * +pm_match_predicate_node_create(pm_parser_t *parser, pm_node_t *value, pm_node_t *pattern, const pm_token_t *operator) { + pm_assert_value_expression(parser, value); + + pm_match_predicate_node_t *node = PM_NODE_ALLOC(parser, pm_match_predicate_node_t); + + *node = (pm_match_predicate_node_t) { + { + .type = PM_MATCH_PREDICATE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = value->location.start, + .end = pattern->location.end + } + }, + .value = value, + .pattern = pattern, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator) + }; + + return node; +} + +/** + * Allocate and initialize a new MatchRequiredNode node. + */ +static pm_match_required_node_t * +pm_match_required_node_create(pm_parser_t *parser, pm_node_t *value, pm_node_t *pattern, const pm_token_t *operator) { + pm_assert_value_expression(parser, value); + + pm_match_required_node_t *node = PM_NODE_ALLOC(parser, pm_match_required_node_t); + + *node = (pm_match_required_node_t) { + { + .type = PM_MATCH_REQUIRED_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = value->location.start, + .end = pattern->location.end + } + }, + .value = value, + .pattern = pattern, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator) + }; + + return node; +} + +/** + * Allocate and initialize a new MatchWriteNode node. + */ +static pm_match_write_node_t * +pm_match_write_node_create(pm_parser_t *parser, pm_call_node_t *call) { + pm_match_write_node_t *node = PM_NODE_ALLOC(parser, pm_match_write_node_t); + + *node = (pm_match_write_node_t) { + { + .type = PM_MATCH_WRITE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = call->base.location + }, + .call = call, + .targets = { 0 } + }; + + return node; +} + +/** + * Allocate a new ModuleNode node. + */ +static pm_module_node_t * +pm_module_node_create(pm_parser_t *parser, pm_constant_id_list_t *locals, const pm_token_t *module_keyword, pm_node_t *constant_path, const pm_token_t *name, pm_node_t *body, const pm_token_t *end_keyword) { + pm_module_node_t *node = PM_NODE_ALLOC(parser, pm_module_node_t); + + *node = (pm_module_node_t) { + { + .type = PM_MODULE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = module_keyword->start, + .end = end_keyword->end + } + }, + .locals = (locals == NULL ? ((pm_constant_id_list_t) { .ids = NULL, .size = 0, .capacity = 0 }) : *locals), + .module_keyword_loc = PM_LOCATION_TOKEN_VALUE(module_keyword), + .constant_path = constant_path, + .body = body, + .end_keyword_loc = PM_LOCATION_TOKEN_VALUE(end_keyword), + .name = pm_parser_constant_id_token(parser, name) + }; + + return node; +} + +/** + * Allocate and initialize new MultiTargetNode node. + */ +static pm_multi_target_node_t * +pm_multi_target_node_create(pm_parser_t *parser) { + pm_multi_target_node_t *node = PM_NODE_ALLOC(parser, pm_multi_target_node_t); + + *node = (pm_multi_target_node_t) { + { + .type = PM_MULTI_TARGET_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { .start = NULL, .end = NULL } + }, + .lefts = { 0 }, + .rest = NULL, + .rights = { 0 }, + .lparen_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .rparen_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE + }; + + return node; +} + +/** + * Append a target to a MultiTargetNode node. + */ +static void +pm_multi_target_node_targets_append(pm_parser_t *parser, pm_multi_target_node_t *node, pm_node_t *target) { + if (PM_NODE_TYPE_P(target, PM_SPLAT_NODE)) { + if (node->rest == NULL) { + node->rest = target; + } else { + pm_parser_err_node(parser, target, PM_ERR_MULTI_ASSIGN_MULTI_SPLATS); + pm_node_list_append(&node->rights, target); + } + } else if (PM_NODE_TYPE_P(target, PM_IMPLICIT_REST_NODE)) { + if (node->rest == NULL) { + node->rest = target; + } else { + PM_PARSER_ERR_TOKEN_FORMAT_CONTENT(parser, parser->current, PM_ERR_MULTI_ASSIGN_UNEXPECTED_REST); + pm_node_list_append(&node->rights, target); + } + } else if (node->rest == NULL) { + pm_node_list_append(&node->lefts, target); + } else { + pm_node_list_append(&node->rights, target); + } + + if (node->base.location.start == NULL || (node->base.location.start > target->location.start)) { + node->base.location.start = target->location.start; + } + + if (node->base.location.end == NULL || (node->base.location.end < target->location.end)) { + node->base.location.end = target->location.end; + } +} + +/** + * Set the opening of a MultiTargetNode node. + */ +static void +pm_multi_target_node_opening_set(pm_multi_target_node_t *node, const pm_token_t *lparen) { + node->base.location.start = lparen->start; + node->lparen_loc = PM_LOCATION_TOKEN_VALUE(lparen); +} + +/** + * Set the closing of a MultiTargetNode node. + */ +static void +pm_multi_target_node_closing_set(pm_multi_target_node_t *node, const pm_token_t *rparen) { + node->base.location.end = rparen->end; + node->rparen_loc = PM_LOCATION_TOKEN_VALUE(rparen); +} + +/** + * Allocate a new MultiWriteNode node. + */ +static pm_multi_write_node_t * +pm_multi_write_node_create(pm_parser_t *parser, pm_multi_target_node_t *target, const pm_token_t *operator, pm_node_t *value) { + pm_multi_write_node_t *node = PM_NODE_ALLOC(parser, pm_multi_write_node_t); + + *node = (pm_multi_write_node_t) { + { + .type = PM_MULTI_WRITE_NODE, + .flags = pm_implicit_array_write_flags(value, PM_WRITE_NODE_FLAGS_IMPLICIT_ARRAY), + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = target->base.location.start, + .end = value->location.end + } + }, + .lefts = target->lefts, + .rest = target->rest, + .rights = target->rights, + .lparen_loc = target->lparen_loc, + .rparen_loc = target->rparen_loc, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + // Explicitly do not call pm_node_destroy here because we want to keep + // around all of the information within the MultiWriteNode node. + xfree(target); + + return node; +} + +/** + * Allocate and initialize a new NextNode node. + */ +static pm_next_node_t * +pm_next_node_create(pm_parser_t *parser, const pm_token_t *keyword, pm_arguments_node_t *arguments) { + assert(keyword->type == PM_TOKEN_KEYWORD_NEXT); + pm_next_node_t *node = PM_NODE_ALLOC(parser, pm_next_node_t); + + *node = (pm_next_node_t) { + { + .type = PM_NEXT_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = keyword->start, + .end = (arguments == NULL ? keyword->end : arguments->base.location.end) + } + }, + .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword), + .arguments = arguments + }; + + return node; +} + +/** + * Allocate and initialize a new NilNode node. + */ +static pm_nil_node_t * +pm_nil_node_create(pm_parser_t *parser, const pm_token_t *token) { + assert(token->type == PM_TOKEN_KEYWORD_NIL); + pm_nil_node_t *node = PM_NODE_ALLOC(parser, pm_nil_node_t); + + *node = (pm_nil_node_t) {{ + .type = PM_NIL_NODE, + .flags = PM_NODE_FLAG_STATIC_LITERAL, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(token) + }}; + + return node; +} + +/** + * Allocate and initialize a new NoKeywordsParameterNode node. + */ +static pm_no_keywords_parameter_node_t * +pm_no_keywords_parameter_node_create(pm_parser_t *parser, const pm_token_t *operator, const pm_token_t *keyword) { + assert(operator->type == PM_TOKEN_USTAR_STAR || operator->type == PM_TOKEN_STAR_STAR); + assert(keyword->type == PM_TOKEN_KEYWORD_NIL); + pm_no_keywords_parameter_node_t *node = PM_NODE_ALLOC(parser, pm_no_keywords_parameter_node_t); + + *node = (pm_no_keywords_parameter_node_t) { + { + .type = PM_NO_KEYWORDS_PARAMETER_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = operator->start, + .end = keyword->end + } + }, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword) + }; + + return node; +} + +/** + * Allocate and initialize a new NumberedParametersNode node. + */ +static pm_numbered_parameters_node_t * +pm_numbered_parameters_node_create(pm_parser_t *parser, const pm_location_t *location, uint8_t maximum) { + pm_numbered_parameters_node_t *node = PM_NODE_ALLOC(parser, pm_numbered_parameters_node_t); + + *node = (pm_numbered_parameters_node_t) { + { + .type = PM_NUMBERED_PARAMETERS_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = *location + }, + .maximum = maximum + }; + + return node; +} + +/** + * The maximum numbered reference value is defined as the maximum value that an + * integer can hold minus 1 bit for CRuby instruction sequence operand tagging. + */ +#define NTH_REF_MAX ((uint32_t) (INT_MAX >> 1)) + +/** + * Parse the decimal number represented by the range of bytes. Returns + * 0 if the number fails to parse or if the number is greater than the maximum + * value representable by a numbered reference. This function assumes that the + * range of bytes has already been validated to contain only decimal digits. + */ +static uint32_t +pm_numbered_reference_read_node_number(pm_parser_t *parser, const pm_token_t *token) { + const uint8_t *start = token->start + 1; + const uint8_t *end = token->end; + + ptrdiff_t diff = end - start; + assert(diff > 0); +#if PTRDIFF_MAX > SIZE_MAX + assert(diff < (ptrdiff_t) SIZE_MAX); +#endif + size_t length = (size_t) diff; + + char *digits = xcalloc(length + 1, sizeof(char)); + memcpy(digits, start, length); + digits[length] = '\0'; + + char *endptr; + errno = 0; + unsigned long value = strtoul(digits, &endptr, 10); + + if ((digits == endptr) || (*endptr != '\0')) { + pm_parser_err(parser, start, end, PM_ERR_INVALID_NUMBER_DECIMAL); + value = 0; + } + + xfree(digits); + + if ((errno == ERANGE) || (value > NTH_REF_MAX)) { + PM_PARSER_WARN_FORMAT(parser, start, end, PM_WARN_INVALID_NUMBERED_REFERENCE, (int) (length + 1), (const char *) token->start); + value = 0; + } + + return (uint32_t) value; +} + +#undef NTH_REF_MAX + +/** + * Allocate and initialize a new NthReferenceReadNode node. + */ +static pm_numbered_reference_read_node_t * +pm_numbered_reference_read_node_create(pm_parser_t *parser, const pm_token_t *name) { + assert(name->type == PM_TOKEN_NUMBERED_REFERENCE); + pm_numbered_reference_read_node_t *node = PM_NODE_ALLOC(parser, pm_numbered_reference_read_node_t); + + *node = (pm_numbered_reference_read_node_t) { + { + .type = PM_NUMBERED_REFERENCE_READ_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(name), + }, + .number = pm_numbered_reference_read_node_number(parser, name) + }; + + return node; +} + +/** + * Allocate a new OptionalParameterNode node. + */ +static pm_optional_parameter_node_t * +pm_optional_parameter_node_create(pm_parser_t *parser, const pm_token_t *name, const pm_token_t *operator, pm_node_t *value) { + pm_optional_parameter_node_t *node = PM_NODE_ALLOC(parser, pm_optional_parameter_node_t); + + *node = (pm_optional_parameter_node_t) { + { + .type = PM_OPTIONAL_PARAMETER_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = name->start, + .end = value->location.end + } + }, + .name = pm_parser_constant_id_token(parser, name), + .name_loc = PM_LOCATION_TOKEN_VALUE(name), + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + return node; +} + +/** + * Allocate and initialize a new OrNode node. + */ +static pm_or_node_t * +pm_or_node_create(pm_parser_t *parser, pm_node_t *left, const pm_token_t *operator, pm_node_t *right) { + pm_assert_value_expression(parser, left); + + pm_or_node_t *node = PM_NODE_ALLOC(parser, pm_or_node_t); + + *node = (pm_or_node_t) { + { + .type = PM_OR_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = left->location.start, + .end = right->location.end + } + }, + .left = left, + .right = right, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator) + }; + + return node; +} + +/** + * Allocate and initialize a new ParametersNode node. + */ +static pm_parameters_node_t * +pm_parameters_node_create(pm_parser_t *parser) { + pm_parameters_node_t *node = PM_NODE_ALLOC(parser, pm_parameters_node_t); + + *node = (pm_parameters_node_t) { + { + .type = PM_PARAMETERS_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(&parser->current) + }, + .rest = NULL, + .keyword_rest = NULL, + .block = NULL, + .requireds = { 0 }, + .optionals = { 0 }, + .posts = { 0 }, + .keywords = { 0 } + }; + + return node; +} + +/** + * Set the location properly for the parameters node. + */ +static void +pm_parameters_node_location_set(pm_parameters_node_t *params, pm_node_t *param) { + if (params->base.location.start == NULL) { + params->base.location.start = param->location.start; + } else { + params->base.location.start = params->base.location.start < param->location.start ? params->base.location.start : param->location.start; + } + + if (params->base.location.end == NULL) { + params->base.location.end = param->location.end; + } else { + params->base.location.end = params->base.location.end > param->location.end ? params->base.location.end : param->location.end; + } +} + +/** + * Append a required parameter to a ParametersNode node. + */ +static void +pm_parameters_node_requireds_append(pm_parameters_node_t *params, pm_node_t *param) { + pm_parameters_node_location_set(params, param); + pm_node_list_append(¶ms->requireds, param); +} + +/** + * Append an optional parameter to a ParametersNode node. + */ +static void +pm_parameters_node_optionals_append(pm_parameters_node_t *params, pm_optional_parameter_node_t *param) { + pm_parameters_node_location_set(params, (pm_node_t *) param); + pm_node_list_append(¶ms->optionals, (pm_node_t *) param); +} + +/** + * Append a post optional arguments parameter to a ParametersNode node. + */ +static void +pm_parameters_node_posts_append(pm_parameters_node_t *params, pm_node_t *param) { + pm_parameters_node_location_set(params, param); + pm_node_list_append(¶ms->posts, param); +} + +/** + * Set the rest parameter on a ParametersNode node. + */ +static void +pm_parameters_node_rest_set(pm_parameters_node_t *params, pm_node_t *param) { + pm_parameters_node_location_set(params, param); + params->rest = param; +} + +/** + * Append a keyword parameter to a ParametersNode node. + */ +static void +pm_parameters_node_keywords_append(pm_parameters_node_t *params, pm_node_t *param) { + pm_parameters_node_location_set(params, param); + pm_node_list_append(¶ms->keywords, param); +} + +/** + * Set the keyword rest parameter on a ParametersNode node. + */ +static void +pm_parameters_node_keyword_rest_set(pm_parameters_node_t *params, pm_node_t *param) { + assert(params->keyword_rest == NULL); + pm_parameters_node_location_set(params, param); + params->keyword_rest = param; +} + +/** + * Set the block parameter on a ParametersNode node. + */ +static void +pm_parameters_node_block_set(pm_parameters_node_t *params, pm_block_parameter_node_t *param) { + assert(params->block == NULL); + pm_parameters_node_location_set(params, (pm_node_t *) param); + params->block = param; +} + +/** + * Allocate a new ProgramNode node. + */ +static pm_program_node_t * +pm_program_node_create(pm_parser_t *parser, pm_constant_id_list_t *locals, pm_statements_node_t *statements) { + pm_program_node_t *node = PM_NODE_ALLOC(parser, pm_program_node_t); + + *node = (pm_program_node_t) { + { + .type = PM_PROGRAM_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = statements == NULL ? parser->start : statements->base.location.start, + .end = statements == NULL ? parser->end : statements->base.location.end + } + }, + .locals = *locals, + .statements = statements + }; + + return node; +} + +/** + * Allocate and initialize new ParenthesesNode node. + */ +static pm_parentheses_node_t * +pm_parentheses_node_create(pm_parser_t *parser, const pm_token_t *opening, pm_node_t *body, const pm_token_t *closing, pm_node_flags_t flags) { + pm_parentheses_node_t *node = PM_NODE_ALLOC(parser, pm_parentheses_node_t); + + *node = (pm_parentheses_node_t) { + { + .type = PM_PARENTHESES_NODE, + .flags = flags, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = opening->start, + .end = closing->end + } + }, + .body = body, + .opening_loc = PM_LOCATION_TOKEN_VALUE(opening), + .closing_loc = PM_LOCATION_TOKEN_VALUE(closing) + }; + + return node; +} + +/** + * Allocate and initialize a new PinnedExpressionNode node. + */ +static pm_pinned_expression_node_t * +pm_pinned_expression_node_create(pm_parser_t *parser, pm_node_t *expression, const pm_token_t *operator, const pm_token_t *lparen, const pm_token_t *rparen) { + pm_pinned_expression_node_t *node = PM_NODE_ALLOC(parser, pm_pinned_expression_node_t); + + *node = (pm_pinned_expression_node_t) { + { + .type = PM_PINNED_EXPRESSION_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = operator->start, + .end = rparen->end + } + }, + .expression = expression, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .lparen_loc = PM_LOCATION_TOKEN_VALUE(lparen), + .rparen_loc = PM_LOCATION_TOKEN_VALUE(rparen) + }; + + return node; +} + +/** + * Allocate and initialize a new PinnedVariableNode node. + */ +static pm_pinned_variable_node_t * +pm_pinned_variable_node_create(pm_parser_t *parser, const pm_token_t *operator, pm_node_t *variable) { + pm_pinned_variable_node_t *node = PM_NODE_ALLOC(parser, pm_pinned_variable_node_t); + + *node = (pm_pinned_variable_node_t) { + { + .type = PM_PINNED_VARIABLE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = operator->start, + .end = variable->location.end + } + }, + .variable = variable, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator) + }; + + return node; +} + +/** + * Allocate and initialize a new PostExecutionNode node. + */ +static pm_post_execution_node_t * +pm_post_execution_node_create(pm_parser_t *parser, const pm_token_t *keyword, const pm_token_t *opening, pm_statements_node_t *statements, const pm_token_t *closing) { + pm_post_execution_node_t *node = PM_NODE_ALLOC(parser, pm_post_execution_node_t); + + *node = (pm_post_execution_node_t) { + { + .type = PM_POST_EXECUTION_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = keyword->start, + .end = closing->end + } + }, + .statements = statements, + .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword), + .opening_loc = PM_LOCATION_TOKEN_VALUE(opening), + .closing_loc = PM_LOCATION_TOKEN_VALUE(closing) + }; + + return node; +} + +/** + * Allocate and initialize a new PreExecutionNode node. + */ +static pm_pre_execution_node_t * +pm_pre_execution_node_create(pm_parser_t *parser, const pm_token_t *keyword, const pm_token_t *opening, pm_statements_node_t *statements, const pm_token_t *closing) { + pm_pre_execution_node_t *node = PM_NODE_ALLOC(parser, pm_pre_execution_node_t); + + *node = (pm_pre_execution_node_t) { + { + .type = PM_PRE_EXECUTION_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = keyword->start, + .end = closing->end + } + }, + .statements = statements, + .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword), + .opening_loc = PM_LOCATION_TOKEN_VALUE(opening), + .closing_loc = PM_LOCATION_TOKEN_VALUE(closing) + }; + + return node; +} + +/** + * Allocate and initialize new RangeNode node. + */ +static pm_range_node_t * +pm_range_node_create(pm_parser_t *parser, pm_node_t *left, const pm_token_t *operator, pm_node_t *right) { + pm_assert_value_expression(parser, left); + pm_assert_value_expression(parser, right); + + pm_range_node_t *node = PM_NODE_ALLOC(parser, pm_range_node_t); + pm_node_flags_t flags = 0; + + // Indicate that this node is an exclusive range if the operator is `...`. + if (operator->type == PM_TOKEN_DOT_DOT_DOT || operator->type == PM_TOKEN_UDOT_DOT_DOT) { + flags |= PM_RANGE_FLAGS_EXCLUDE_END; + } + + // Indicate that this node is a static literal (i.e., can be compiled with + // a putobject in CRuby) if the left and right are implicit nil, explicit + // nil, or integers. + if ( + (left == NULL || PM_NODE_TYPE_P(left, PM_NIL_NODE) || PM_NODE_TYPE_P(left, PM_INTEGER_NODE)) && + (right == NULL || PM_NODE_TYPE_P(right, PM_NIL_NODE) || PM_NODE_TYPE_P(right, PM_INTEGER_NODE)) + ) { + flags |= PM_NODE_FLAG_STATIC_LITERAL; + } + + *node = (pm_range_node_t) { + { + .type = PM_RANGE_NODE, + .flags = flags, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = (left == NULL ? operator->start : left->location.start), + .end = (right == NULL ? operator->end : right->location.end) + } + }, + .left = left, + .right = right, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator) + }; + + return node; +} + +/** + * Allocate and initialize a new RedoNode node. + */ +static pm_redo_node_t * +pm_redo_node_create(pm_parser_t *parser, const pm_token_t *token) { + assert(token->type == PM_TOKEN_KEYWORD_REDO); + pm_redo_node_t *node = PM_NODE_ALLOC(parser, pm_redo_node_t); + + *node = (pm_redo_node_t) {{ + .type = PM_REDO_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(token) + }}; + + return node; +} + +/** + * Allocate a new initialize a new RegularExpressionNode node with the given + * unescaped string. + */ +static pm_regular_expression_node_t * +pm_regular_expression_node_create_unescaped(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *content, const pm_token_t *closing, const pm_string_t *unescaped) { + pm_regular_expression_node_t *node = PM_NODE_ALLOC(parser, pm_regular_expression_node_t); + + *node = (pm_regular_expression_node_t) { + { + .type = PM_REGULAR_EXPRESSION_NODE, + .flags = pm_regular_expression_flags_create(parser, closing) | PM_NODE_FLAG_STATIC_LITERAL, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = MIN(opening->start, closing->start), + .end = MAX(opening->end, closing->end) + } + }, + .opening_loc = PM_LOCATION_TOKEN_VALUE(opening), + .content_loc = PM_LOCATION_TOKEN_VALUE(content), + .closing_loc = PM_LOCATION_TOKEN_VALUE(closing), + .unescaped = *unescaped + }; + + return node; +} + +/** + * Allocate a new initialize a new RegularExpressionNode node. + */ +static inline pm_regular_expression_node_t * +pm_regular_expression_node_create(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *content, const pm_token_t *closing) { + return pm_regular_expression_node_create_unescaped(parser, opening, content, closing, &PM_STRING_EMPTY); +} + +/** + * Allocate a new RequiredParameterNode node. + */ +static pm_required_parameter_node_t * +pm_required_parameter_node_create(pm_parser_t *parser, const pm_token_t *token) { + pm_required_parameter_node_t *node = PM_NODE_ALLOC(parser, pm_required_parameter_node_t); + + *node = (pm_required_parameter_node_t) { + { + .type = PM_REQUIRED_PARAMETER_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(token) + }, + .name = pm_parser_constant_id_token(parser, token) + }; + + return node; +} + +/** + * Allocate a new RescueModifierNode node. + */ +static pm_rescue_modifier_node_t * +pm_rescue_modifier_node_create(pm_parser_t *parser, pm_node_t *expression, const pm_token_t *keyword, pm_node_t *rescue_expression) { + pm_rescue_modifier_node_t *node = PM_NODE_ALLOC(parser, pm_rescue_modifier_node_t); + + *node = (pm_rescue_modifier_node_t) { + { + .type = PM_RESCUE_MODIFIER_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = expression->location.start, + .end = rescue_expression->location.end + } + }, + .expression = expression, + .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword), + .rescue_expression = rescue_expression + }; + + return node; +} + +/** + * Allocate and initialize a new RescueNode node. + */ +static pm_rescue_node_t * +pm_rescue_node_create(pm_parser_t *parser, const pm_token_t *keyword) { + pm_rescue_node_t *node = PM_NODE_ALLOC(parser, pm_rescue_node_t); + + *node = (pm_rescue_node_t) { + { + .type = PM_RESCUE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(keyword) + }, + .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword), + .operator_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .then_keyword_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .reference = NULL, + .statements = NULL, + .subsequent = NULL, + .exceptions = { 0 } + }; + + return node; +} + +static inline void +pm_rescue_node_operator_set(pm_rescue_node_t *node, const pm_token_t *operator) { + node->operator_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator); +} + +/** + * Set the reference of a rescue node, and update the location of the node. + */ +static void +pm_rescue_node_reference_set(pm_rescue_node_t *node, pm_node_t *reference) { + node->reference = reference; + node->base.location.end = reference->location.end; +} + +/** + * Set the statements of a rescue node, and update the location of the node. + */ +static void +pm_rescue_node_statements_set(pm_rescue_node_t *node, pm_statements_node_t *statements) { + node->statements = statements; + if (pm_statements_node_body_length(statements) > 0) { + node->base.location.end = statements->base.location.end; + } +} + +/** + * Set the subsequent of a rescue node, and update the location. + */ +static void +pm_rescue_node_subsequent_set(pm_rescue_node_t *node, pm_rescue_node_t *subsequent) { + node->subsequent = subsequent; + node->base.location.end = subsequent->base.location.end; +} + +/** + * Append an exception node to a rescue node, and update the location. + */ +static void +pm_rescue_node_exceptions_append(pm_rescue_node_t *node, pm_node_t *exception) { + pm_node_list_append(&node->exceptions, exception); + node->base.location.end = exception->location.end; +} + +/** + * Allocate a new RestParameterNode node. + */ +static pm_rest_parameter_node_t * +pm_rest_parameter_node_create(pm_parser_t *parser, const pm_token_t *operator, const pm_token_t *name) { + pm_rest_parameter_node_t *node = PM_NODE_ALLOC(parser, pm_rest_parameter_node_t); + + *node = (pm_rest_parameter_node_t) { + { + .type = PM_REST_PARAMETER_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = operator->start, + .end = (name->type == PM_TOKEN_NOT_PROVIDED ? operator->end : name->end) + } + }, + .name = pm_parser_optional_constant_id_token(parser, name), + .name_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(name), + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator) + }; + + return node; +} + +/** + * Allocate and initialize a new RetryNode node. + */ +static pm_retry_node_t * +pm_retry_node_create(pm_parser_t *parser, const pm_token_t *token) { + assert(token->type == PM_TOKEN_KEYWORD_RETRY); + pm_retry_node_t *node = PM_NODE_ALLOC(parser, pm_retry_node_t); + + *node = (pm_retry_node_t) {{ + .type = PM_RETRY_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(token) + }}; + + return node; +} + +/** + * Allocate a new ReturnNode node. + */ +static pm_return_node_t * +pm_return_node_create(pm_parser_t *parser, const pm_token_t *keyword, pm_arguments_node_t *arguments) { + pm_return_node_t *node = PM_NODE_ALLOC(parser, pm_return_node_t); + + *node = (pm_return_node_t) { + { + .type = PM_RETURN_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = keyword->start, + .end = (arguments == NULL ? keyword->end : arguments->base.location.end) + } + }, + .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword), + .arguments = arguments + }; + + return node; +} + +/** + * Allocate and initialize a new SelfNode node. + */ +static pm_self_node_t * +pm_self_node_create(pm_parser_t *parser, const pm_token_t *token) { + assert(token->type == PM_TOKEN_KEYWORD_SELF); + pm_self_node_t *node = PM_NODE_ALLOC(parser, pm_self_node_t); + + *node = (pm_self_node_t) {{ + .type = PM_SELF_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(token) + }}; + + return node; +} + +/** + * Allocate and initialize a new ShareableConstantNode node. + */ +static pm_shareable_constant_node_t * +pm_shareable_constant_node_create(pm_parser_t *parser, pm_node_t *write, pm_shareable_constant_value_t value) { + pm_shareable_constant_node_t *node = PM_NODE_ALLOC(parser, pm_shareable_constant_node_t); + + *node = (pm_shareable_constant_node_t) { + { + .type = PM_SHAREABLE_CONSTANT_NODE, + .flags = (pm_node_flags_t) value, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_NODE_VALUE(write) + }, + .write = write + }; + + return node; +} + +/** + * Allocate a new SingletonClassNode node. + */ +static pm_singleton_class_node_t * +pm_singleton_class_node_create(pm_parser_t *parser, pm_constant_id_list_t *locals, const pm_token_t *class_keyword, const pm_token_t *operator, pm_node_t *expression, pm_node_t *body, const pm_token_t *end_keyword) { + pm_singleton_class_node_t *node = PM_NODE_ALLOC(parser, pm_singleton_class_node_t); + + *node = (pm_singleton_class_node_t) { + { + .type = PM_SINGLETON_CLASS_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = class_keyword->start, + .end = end_keyword->end + } + }, + .locals = *locals, + .class_keyword_loc = PM_LOCATION_TOKEN_VALUE(class_keyword), + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .expression = expression, + .body = body, + .end_keyword_loc = PM_LOCATION_TOKEN_VALUE(end_keyword) + }; + + return node; +} + +/** + * Allocate and initialize a new SourceEncodingNode node. + */ +static pm_source_encoding_node_t * +pm_source_encoding_node_create(pm_parser_t *parser, const pm_token_t *token) { + assert(token->type == PM_TOKEN_KEYWORD___ENCODING__); + pm_source_encoding_node_t *node = PM_NODE_ALLOC(parser, pm_source_encoding_node_t); + + *node = (pm_source_encoding_node_t) {{ + .type = PM_SOURCE_ENCODING_NODE, + .flags = PM_NODE_FLAG_STATIC_LITERAL, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(token) + }}; + + return node; +} + +/** + * Allocate and initialize a new SourceFileNode node. + */ +static pm_source_file_node_t* +pm_source_file_node_create(pm_parser_t *parser, const pm_token_t *file_keyword) { + pm_source_file_node_t *node = PM_NODE_ALLOC(parser, pm_source_file_node_t); + assert(file_keyword->type == PM_TOKEN_KEYWORD___FILE__); + + pm_node_flags_t flags = 0; + + switch (parser->frozen_string_literal) { + case PM_OPTIONS_FROZEN_STRING_LITERAL_DISABLED: + flags |= PM_STRING_FLAGS_MUTABLE; + break; + case PM_OPTIONS_FROZEN_STRING_LITERAL_ENABLED: + flags |= PM_NODE_FLAG_STATIC_LITERAL | PM_STRING_FLAGS_FROZEN; + break; + } + + *node = (pm_source_file_node_t) { + { + .type = PM_SOURCE_FILE_NODE, + .flags = flags, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(file_keyword), + }, + .filepath = parser->filepath + }; + + return node; +} + +/** + * Allocate and initialize a new SourceLineNode node. + */ +static pm_source_line_node_t * +pm_source_line_node_create(pm_parser_t *parser, const pm_token_t *token) { + assert(token->type == PM_TOKEN_KEYWORD___LINE__); + pm_source_line_node_t *node = PM_NODE_ALLOC(parser, pm_source_line_node_t); + + *node = (pm_source_line_node_t) {{ + .type = PM_SOURCE_LINE_NODE, + .flags = PM_NODE_FLAG_STATIC_LITERAL, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(token) + }}; + + return node; +} + +/** + * Allocate a new SplatNode node. + */ +static pm_splat_node_t * +pm_splat_node_create(pm_parser_t *parser, const pm_token_t *operator, pm_node_t *expression) { + pm_splat_node_t *node = PM_NODE_ALLOC(parser, pm_splat_node_t); + + *node = (pm_splat_node_t) { + { + .type = PM_SPLAT_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = operator->start, + .end = (expression == NULL ? operator->end : expression->location.end) + } + }, + .operator_loc = PM_LOCATION_TOKEN_VALUE(operator), + .expression = expression + }; + + return node; +} + +/** + * Allocate and initialize a new StatementsNode node. + */ +static pm_statements_node_t * +pm_statements_node_create(pm_parser_t *parser) { + pm_statements_node_t *node = PM_NODE_ALLOC(parser, pm_statements_node_t); + + *node = (pm_statements_node_t) { + { + .type = PM_STATEMENTS_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_NULL_VALUE(parser) + }, + .body = { 0 } + }; + + return node; +} + +/** + * Get the length of the given StatementsNode node's body. + */ +static size_t +pm_statements_node_body_length(pm_statements_node_t *node) { + return node && node->body.size; +} + +/** + * Set the location of the given StatementsNode. + */ +static void +pm_statements_node_location_set(pm_statements_node_t *node, const uint8_t *start, const uint8_t *end) { + node->base.location = (pm_location_t) { .start = start, .end = end }; +} + +/** + * Update the location of the statements node based on the statement that is + * being added to the list. + */ +static inline void +pm_statements_node_body_update(pm_statements_node_t *node, pm_node_t *statement) { + if (pm_statements_node_body_length(node) == 0 || statement->location.start < node->base.location.start) { + node->base.location.start = statement->location.start; + } + + if (statement->location.end > node->base.location.end) { + node->base.location.end = statement->location.end; + } +} + +/** + * Append a new node to the given StatementsNode node's body. + */ +static void +pm_statements_node_body_append(pm_parser_t *parser, pm_statements_node_t *node, pm_node_t *statement, bool newline) { + pm_statements_node_body_update(node, statement); + + if (node->body.size > 0) { + const pm_node_t *previous = node->body.nodes[node->body.size - 1]; + + switch (PM_NODE_TYPE(previous)) { + case PM_BREAK_NODE: + case PM_NEXT_NODE: + case PM_REDO_NODE: + case PM_RETRY_NODE: + case PM_RETURN_NODE: + pm_parser_warn_node(parser, statement, PM_WARN_UNREACHABLE_STATEMENT); + break; + default: + break; + } + } + + pm_node_list_append(&node->body, statement); + if (newline) pm_node_flag_set(statement, PM_NODE_FLAG_NEWLINE); +} + +/** + * Prepend a new node to the given StatementsNode node's body. + */ +static void +pm_statements_node_body_prepend(pm_statements_node_t *node, pm_node_t *statement) { + pm_statements_node_body_update(node, statement); + pm_node_list_prepend(&node->body, statement); + pm_node_flag_set(statement, PM_NODE_FLAG_NEWLINE); +} + +/** + * Allocate a new StringNode node with the current string on the parser. + */ +static inline pm_string_node_t * +pm_string_node_create_unescaped(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *content, const pm_token_t *closing, const pm_string_t *string) { + pm_string_node_t *node = PM_NODE_ALLOC(parser, pm_string_node_t); + pm_node_flags_t flags = 0; + + switch (parser->frozen_string_literal) { + case PM_OPTIONS_FROZEN_STRING_LITERAL_DISABLED: + flags = PM_STRING_FLAGS_MUTABLE; + break; + case PM_OPTIONS_FROZEN_STRING_LITERAL_ENABLED: + flags = PM_NODE_FLAG_STATIC_LITERAL | PM_STRING_FLAGS_FROZEN; + break; + } + + *node = (pm_string_node_t) { + { + .type = PM_STRING_NODE, + .flags = flags, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = (opening->type == PM_TOKEN_NOT_PROVIDED ? content->start : opening->start), + .end = (closing->type == PM_TOKEN_NOT_PROVIDED ? content->end : closing->end) + } + }, + .opening_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(opening), + .content_loc = PM_LOCATION_TOKEN_VALUE(content), + .closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(closing), + .unescaped = *string + }; + + return node; +} + +/** + * Allocate a new StringNode node. + */ +static pm_string_node_t * +pm_string_node_create(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *content, const pm_token_t *closing) { + return pm_string_node_create_unescaped(parser, opening, content, closing, &PM_STRING_EMPTY); +} + +/** + * Allocate a new StringNode node and create it using the current string on the + * parser. + */ +static pm_string_node_t * +pm_string_node_create_current_string(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *content, const pm_token_t *closing) { + pm_string_node_t *node = pm_string_node_create_unescaped(parser, opening, content, closing, &parser->current_string); + parser->current_string = PM_STRING_EMPTY; + return node; +} + +/** + * Allocate and initialize a new SuperNode node. + */ +static pm_super_node_t * +pm_super_node_create(pm_parser_t *parser, const pm_token_t *keyword, pm_arguments_t *arguments) { + assert(keyword->type == PM_TOKEN_KEYWORD_SUPER); + pm_super_node_t *node = PM_NODE_ALLOC(parser, pm_super_node_t); + + const uint8_t *end = pm_arguments_end(arguments); + if (end == NULL) { + assert(false && "unreachable"); + } + + *node = (pm_super_node_t) { + { + .type = PM_SUPER_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = keyword->start, + .end = end, + } + }, + .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword), + .lparen_loc = arguments->opening_loc, + .arguments = arguments->arguments, + .rparen_loc = arguments->closing_loc, + .block = arguments->block + }; + + return node; +} + +/** + * Read through the contents of a string and check if it consists solely of + * US-ASCII code points. + */ +static bool +pm_ascii_only_p(const pm_string_t *contents) { + const size_t length = pm_string_length(contents); + const uint8_t *source = pm_string_source(contents); + + for (size_t index = 0; index < length; index++) { + if (source[index] & 0x80) return false; + } + + return true; +} + +/** + * Validate that the contents of the given symbol are all valid UTF-8. + */ +static void +parse_symbol_encoding_validate_utf8(pm_parser_t *parser, const pm_token_t *location, const pm_string_t *contents) { + for (const uint8_t *cursor = pm_string_source(contents), *end = cursor + pm_string_length(contents); cursor < end;) { + size_t width = pm_encoding_utf_8_char_width(cursor, end - cursor); + + if (width == 0) { + pm_parser_err(parser, location->start, location->end, PM_ERR_INVALID_SYMBOL); + break; + } + + cursor += width; + } +} + +/** + * Validate that the contents of the given symbol are all valid in the encoding + * of the parser. + */ +static void +parse_symbol_encoding_validate_other(pm_parser_t *parser, const pm_token_t *location, const pm_string_t *contents) { + const pm_encoding_t *encoding = parser->encoding; + + for (const uint8_t *cursor = pm_string_source(contents), *end = cursor + pm_string_length(contents); cursor < end;) { + size_t width = encoding->char_width(cursor, end - cursor); + + if (width == 0) { + pm_parser_err(parser, location->start, location->end, PM_ERR_INVALID_SYMBOL); + break; + } + + cursor += width; + } +} + +/** + * Ruby "downgrades" the encoding of Symbols to US-ASCII if the associated + * encoding is ASCII-compatible and the Symbol consists only of US-ASCII code + * points. Otherwise, the encoding may be explicitly set with an escape + * sequence. + * + * If the validate flag is set, then it will check the contents of the symbol + * to ensure that all characters are valid in the encoding. + */ +static inline pm_node_flags_t +parse_symbol_encoding(pm_parser_t *parser, const pm_token_t *location, const pm_string_t *contents, bool validate) { + if (parser->explicit_encoding != NULL) { + // A Symbol may optionally have its encoding explicitly set. This will + // happen if an escape sequence results in a non-ASCII code point. + if (parser->explicit_encoding == PM_ENCODING_UTF_8_ENTRY) { + if (validate) parse_symbol_encoding_validate_utf8(parser, location, contents); + return PM_SYMBOL_FLAGS_FORCED_UTF8_ENCODING; + } else if (parser->encoding == PM_ENCODING_US_ASCII_ENTRY) { + return PM_SYMBOL_FLAGS_FORCED_BINARY_ENCODING; + } else if (validate) { + parse_symbol_encoding_validate_other(parser, location, contents); + } + } else if (pm_ascii_only_p(contents)) { + // Ruby stipulates that all source files must use an ASCII-compatible + // encoding. Thus, all symbols appearing in source are eligible for + // "downgrading" to US-ASCII. + return PM_SYMBOL_FLAGS_FORCED_US_ASCII_ENCODING; + } else if (validate) { + parse_symbol_encoding_validate_other(parser, location, contents); + } + + return 0; +} + +static pm_node_flags_t +parse_and_validate_regular_expression_encoding_modifier(pm_parser_t *parser, const pm_string_t *source, bool ascii_only, pm_node_flags_t flags, char modifier, const pm_encoding_t *modifier_encoding) { + assert ((modifier == 'n' && modifier_encoding == PM_ENCODING_ASCII_8BIT_ENTRY) || + (modifier == 'u' && modifier_encoding == PM_ENCODING_UTF_8_ENTRY) || + (modifier == 'e' && modifier_encoding == PM_ENCODING_EUC_JP_ENTRY) || + (modifier == 's' && modifier_encoding == PM_ENCODING_WINDOWS_31J_ENTRY)); + + // There's special validation logic used if a string does not contain any character escape sequences. + if (parser->explicit_encoding == NULL) { + // If an ASCII-only string without character escapes is used with an encoding modifier, then resulting Regexp + // has the modifier encoding, unless the ASCII-8BIT modifier is used, in which case the Regexp "downgrades" to + // the US-ASCII encoding. + if (ascii_only) { + return modifier == 'n' ? PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING : flags; + } + + if (parser->encoding == PM_ENCODING_US_ASCII_ENTRY) { + if (!ascii_only) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_INVALID_MULTIBYTE_CHAR, parser->encoding->name); + } + } else if (parser->encoding != modifier_encoding) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_REGEXP_ENCODING_OPTION_MISMATCH, modifier, parser->encoding->name); + + if (modifier == 'n' && !ascii_only) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_REGEXP_NON_ESCAPED_MBC, (int) pm_string_length(source), (const char *) pm_string_source(source)); + } + } + + return flags; + } + + // TODO (nirvdrum 21-Feb-2024): To validate regexp sources with character escape sequences we need to know whether hex or Unicode escape sequences were used and Prism doesn't currently provide that data. We handle a subset of unambiguous cases in the meanwhile. + bool mixed_encoding = false; + + if (mixed_encoding) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_INVALID_MULTIBYTE_ESCAPE, (int) pm_string_length(source), (const char *) pm_string_source(source)); + } else if (modifier != 'n' && parser->explicit_encoding == PM_ENCODING_ASCII_8BIT_ENTRY) { + // TODO (nirvdrum 21-Feb-2024): Validate the content is valid in the modifier encoding. Do this on-demand so we don't pay the cost of computation unnecessarily. + bool valid_string_in_modifier_encoding = true; + + if (!valid_string_in_modifier_encoding) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_INVALID_MULTIBYTE_ESCAPE, (int) pm_string_length(source), (const char *) pm_string_source(source)); + } + } else if (modifier != 'u' && parser->explicit_encoding == PM_ENCODING_UTF_8_ENTRY) { + // TODO (nirvdrum 21-Feb-2024): There's currently no way to tell if the source used hex or Unicode character escapes from `explicit_encoding` alone. If the source encoding was already UTF-8, both character escape types would set `explicit_encoding` to UTF-8, but need to be processed differently. Skip for now. + if (parser->encoding != PM_ENCODING_UTF_8_ENTRY) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_REGEXP_INCOMPAT_CHAR_ENCODING, (int) pm_string_length(source), (const char *) pm_string_source(source)); + } + } + + // We've determined the encoding would naturally be EUC-JP and there is no need to force the encoding to anything else. + return flags; +} + +/** + * Ruby "downgrades" the encoding of Regexps to US-ASCII if the associated encoding is ASCII-compatible and + * the unescaped representation of a Regexp source consists only of US-ASCII code points. This is true even + * when the Regexp is explicitly given an ASCII-8BIT encoding via the (/n) modifier. Otherwise, the encoding + * may be explicitly set with an escape sequence. + */ +static pm_node_flags_t +parse_and_validate_regular_expression_encoding(pm_parser_t *parser, const pm_string_t *source, bool ascii_only, pm_node_flags_t flags) { + // TODO (nirvdrum 22-Feb-2024): CRuby reports a special Regexp-specific error for invalid Unicode ranges. We either need to scan again or modify the "invalid Unicode escape sequence" message we already report. + bool valid_unicode_range = true; + if (parser->explicit_encoding == PM_ENCODING_UTF_8_ENTRY && !valid_unicode_range) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_REGEXP_INVALID_UNICODE_RANGE, (int) pm_string_length(source), (const char *) pm_string_source(source)); + return flags; + } + + // US-ASCII strings do not admit multi-byte character literals. However, character escape sequences corresponding + // to multi-byte characters are allowed. + if (parser->encoding == PM_ENCODING_US_ASCII_ENTRY && parser->explicit_encoding == NULL && !ascii_only) { + // CRuby will continue processing even though a SyntaxError has already been detected. It may result in the + // following error message appearing twice. We do the same for compatibility. + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_INVALID_MULTIBYTE_CHAR, parser->encoding->name); + } + + /** + * Start checking modifier flags. We need to process these before considering any explicit encodings that may have + * been set by character literals. The order in which the encoding modifiers is checked does not matter. In the + * event that both an encoding modifier and an explicit encoding would result in the same encoding we do not set + * the corresponding "forced_" flag. Instead, the caller should check the encoding modifier flag and + * determine the encoding that way. + */ + + if (flags & PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT) { + return parse_and_validate_regular_expression_encoding_modifier(parser, source, ascii_only, flags, 'n', PM_ENCODING_ASCII_8BIT_ENTRY); + } + + if (flags & PM_REGULAR_EXPRESSION_FLAGS_UTF_8) { + return parse_and_validate_regular_expression_encoding_modifier(parser, source, ascii_only, flags, 'u', PM_ENCODING_UTF_8_ENTRY); + } + + if (flags & PM_REGULAR_EXPRESSION_FLAGS_EUC_JP) { + return parse_and_validate_regular_expression_encoding_modifier(parser, source, ascii_only, flags, 'e', PM_ENCODING_EUC_JP_ENTRY); + } + + if (flags & PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J) { + return parse_and_validate_regular_expression_encoding_modifier(parser, source, ascii_only, flags, 's', PM_ENCODING_WINDOWS_31J_ENTRY); + } + + // At this point no encoding modifiers will be present on the regular expression as they would have already + // been processed. Ruby stipulates that all source files must use an ASCII-compatible encoding. Thus, all + // regular expressions without an encoding modifier appearing in source are eligible for "downgrading" to US-ASCII. + if (ascii_only) { + return PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING; + } + + // A Regexp may optionally have its encoding explicitly set via a character escape sequence in the source string + // or by specifying a modifier. + // + // NB: an explicitly set encoding is ignored by Ruby if the Regexp consists of only US ASCII code points. + if (parser->explicit_encoding != NULL) { + if (parser->explicit_encoding == PM_ENCODING_UTF_8_ENTRY) { + return PM_REGULAR_EXPRESSION_FLAGS_FORCED_UTF8_ENCODING; + } else if (parser->encoding == PM_ENCODING_US_ASCII_ENTRY) { + return PM_REGULAR_EXPRESSION_FLAGS_FORCED_BINARY_ENCODING; + } + } + + return 0; +} + +/** + * Allocate and initialize a new SymbolNode node with the given unescaped + * string. + */ +static pm_symbol_node_t * +pm_symbol_node_create_unescaped(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *value, const pm_token_t *closing, const pm_string_t *unescaped, pm_node_flags_t flags) { + pm_symbol_node_t *node = PM_NODE_ALLOC(parser, pm_symbol_node_t); + + *node = (pm_symbol_node_t) { + { + .type = PM_SYMBOL_NODE, + .flags = PM_NODE_FLAG_STATIC_LITERAL | flags, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = (opening->type == PM_TOKEN_NOT_PROVIDED ? value->start : opening->start), + .end = (closing->type == PM_TOKEN_NOT_PROVIDED ? value->end : closing->end) + } + }, + .opening_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(opening), + .value_loc = PM_LOCATION_TOKEN_VALUE(value), + .closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(closing), + .unescaped = *unescaped + }; + + return node; +} + +/** + * Allocate and initialize a new SymbolNode node. + */ +static inline pm_symbol_node_t * +pm_symbol_node_create(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *value, const pm_token_t *closing) { + return pm_symbol_node_create_unescaped(parser, opening, value, closing, &PM_STRING_EMPTY, 0); +} + +/** + * Allocate and initialize a new SymbolNode node with the current string. + */ +static pm_symbol_node_t * +pm_symbol_node_create_current_string(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *value, const pm_token_t *closing) { + pm_symbol_node_t *node = pm_symbol_node_create_unescaped(parser, opening, value, closing, &parser->current_string, parse_symbol_encoding(parser, value, &parser->current_string, false)); + parser->current_string = PM_STRING_EMPTY; + return node; +} + +/** + * Allocate and initialize a new SymbolNode node from a label. + */ +static pm_symbol_node_t * +pm_symbol_node_label_create(pm_parser_t *parser, const pm_token_t *token) { + pm_symbol_node_t *node; + + switch (token->type) { + case PM_TOKEN_LABEL: { + pm_token_t opening = not_provided(parser); + pm_token_t closing = { .type = PM_TOKEN_LABEL_END, .start = token->end - 1, .end = token->end }; + + pm_token_t label = { .type = PM_TOKEN_LABEL, .start = token->start, .end = token->end - 1 }; + node = pm_symbol_node_create(parser, &opening, &label, &closing); + + assert((label.end - label.start) >= 0); + pm_string_shared_init(&node->unescaped, label.start, label.end); + pm_node_flag_set((pm_node_t *) node, parse_symbol_encoding(parser, &label, &node->unescaped, false)); + + break; + } + case PM_TOKEN_MISSING: { + pm_token_t opening = not_provided(parser); + pm_token_t closing = not_provided(parser); + + pm_token_t label = { .type = PM_TOKEN_LABEL, .start = token->start, .end = token->end }; + node = pm_symbol_node_create(parser, &opening, &label, &closing); + break; + } + default: + assert(false && "unreachable"); + node = NULL; + break; + } + + return node; +} + +/** + * Allocate and initialize a new synthesized SymbolNode node. + */ +static pm_symbol_node_t * +pm_symbol_node_synthesized_create(pm_parser_t *parser, const char *content) { + pm_symbol_node_t *node = PM_NODE_ALLOC(parser, pm_symbol_node_t); + + *node = (pm_symbol_node_t) { + { + .type = PM_SYMBOL_NODE, + .flags = PM_NODE_FLAG_STATIC_LITERAL | PM_SYMBOL_FLAGS_FORCED_US_ASCII_ENCODING, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_NULL_VALUE(parser) + }, + .value_loc = PM_LOCATION_NULL_VALUE(parser), + .unescaped = { 0 } + }; + + pm_string_constant_init(&node->unescaped, content, strlen(content)); + return node; +} + +/** + * Check if the given node is a label in a hash. + */ +static bool +pm_symbol_node_label_p(pm_node_t *node) { + const uint8_t *end = NULL; + + switch (PM_NODE_TYPE(node)) { + case PM_SYMBOL_NODE: + end = ((pm_symbol_node_t *) node)->closing_loc.end; + break; + case PM_INTERPOLATED_SYMBOL_NODE: + end = ((pm_interpolated_symbol_node_t *) node)->closing_loc.end; + break; + default: + return false; + } + + return (end != NULL) && (end[-1] == ':'); +} + +/** + * Convert the given StringNode node to a SymbolNode node. + */ +static pm_symbol_node_t * +pm_string_node_to_symbol_node(pm_parser_t *parser, pm_string_node_t *node, const pm_token_t *opening, const pm_token_t *closing) { + pm_symbol_node_t *new_node = PM_NODE_ALLOC(parser, pm_symbol_node_t); + + *new_node = (pm_symbol_node_t) { + { + .type = PM_SYMBOL_NODE, + .flags = PM_NODE_FLAG_STATIC_LITERAL, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = opening->start, + .end = closing->end + } + }, + .opening_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(opening), + .value_loc = node->content_loc, + .closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(closing), + .unescaped = node->unescaped + }; + + pm_token_t content = { .type = PM_TOKEN_IDENTIFIER, .start = node->content_loc.start, .end = node->content_loc.end }; + pm_node_flag_set((pm_node_t *) new_node, parse_symbol_encoding(parser, &content, &node->unescaped, true)); + + // We are explicitly _not_ using pm_node_destroy here because we don't want + // to trash the unescaped string. We could instead copy the string if we + // know that it is owned, but we're taking the fast path for now. + xfree(node); + + return new_node; +} + +/** + * Convert the given SymbolNode node to a StringNode node. + */ +static pm_string_node_t * +pm_symbol_node_to_string_node(pm_parser_t *parser, pm_symbol_node_t *node) { + pm_string_node_t *new_node = PM_NODE_ALLOC(parser, pm_string_node_t); + pm_node_flags_t flags = 0; + + switch (parser->frozen_string_literal) { + case PM_OPTIONS_FROZEN_STRING_LITERAL_DISABLED: + flags = PM_STRING_FLAGS_MUTABLE; + break; + case PM_OPTIONS_FROZEN_STRING_LITERAL_ENABLED: + flags = PM_NODE_FLAG_STATIC_LITERAL | PM_STRING_FLAGS_FROZEN; + break; + } + + *new_node = (pm_string_node_t) { + { + .type = PM_STRING_NODE, + .flags = flags, + .node_id = PM_NODE_IDENTIFY(parser), + .location = node->base.location + }, + .opening_loc = node->opening_loc, + .content_loc = node->value_loc, + .closing_loc = node->closing_loc, + .unescaped = node->unescaped + }; + + // We are explicitly _not_ using pm_node_destroy here because we don't want + // to trash the unescaped string. We could instead copy the string if we + // know that it is owned, but we're taking the fast path for now. + xfree(node); + + return new_node; +} + +/** + * Allocate and initialize a new TrueNode node. + */ +static pm_true_node_t * +pm_true_node_create(pm_parser_t *parser, const pm_token_t *token) { + assert(token->type == PM_TOKEN_KEYWORD_TRUE); + pm_true_node_t *node = PM_NODE_ALLOC(parser, pm_true_node_t); + + *node = (pm_true_node_t) {{ + .type = PM_TRUE_NODE, + .flags = PM_NODE_FLAG_STATIC_LITERAL, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(token) + }}; + + return node; +} + +/** + * Allocate and initialize a new synthesized TrueNode node. + */ +static pm_true_node_t * +pm_true_node_synthesized_create(pm_parser_t *parser) { + pm_true_node_t *node = PM_NODE_ALLOC(parser, pm_true_node_t); + + *node = (pm_true_node_t) {{ + .type = PM_TRUE_NODE, + .flags = PM_NODE_FLAG_STATIC_LITERAL, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { .start = parser->start, .end = parser->end } + }}; + + return node; +} + +/** + * Allocate and initialize a new UndefNode node. + */ +static pm_undef_node_t * +pm_undef_node_create(pm_parser_t *parser, const pm_token_t *token) { + assert(token->type == PM_TOKEN_KEYWORD_UNDEF); + pm_undef_node_t *node = PM_NODE_ALLOC(parser, pm_undef_node_t); + + *node = (pm_undef_node_t) { + { + .type = PM_UNDEF_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_TOKEN_VALUE(token), + }, + .keyword_loc = PM_LOCATION_TOKEN_VALUE(token), + .names = { 0 } + }; + + return node; +} + +/** + * Append a name to an undef node. + */ +static void +pm_undef_node_append(pm_undef_node_t *node, pm_node_t *name) { + node->base.location.end = name->location.end; + pm_node_list_append(&node->names, name); +} + +/** + * Allocate a new UnlessNode node. + */ +static pm_unless_node_t * +pm_unless_node_create(pm_parser_t *parser, const pm_token_t *keyword, pm_node_t *predicate, const pm_token_t *then_keyword, pm_statements_node_t *statements) { + pm_conditional_predicate(parser, predicate, PM_CONDITIONAL_PREDICATE_TYPE_CONDITIONAL); + pm_unless_node_t *node = PM_NODE_ALLOC(parser, pm_unless_node_t); + + const uint8_t *end; + if (statements != NULL) { + end = statements->base.location.end; + } else { + end = predicate->location.end; + } + + *node = (pm_unless_node_t) { + { + .type = PM_UNLESS_NODE, + .flags = PM_NODE_FLAG_NEWLINE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = keyword->start, + .end = end + }, + }, + .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword), + .predicate = predicate, + .then_keyword_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(then_keyword), + .statements = statements, + .else_clause = NULL, + .end_keyword_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE + }; + + return node; +} + +/** + * Allocate and initialize new UnlessNode node in the modifier form. + */ +static pm_unless_node_t * +pm_unless_node_modifier_create(pm_parser_t *parser, pm_node_t *statement, const pm_token_t *unless_keyword, pm_node_t *predicate) { + pm_conditional_predicate(parser, predicate, PM_CONDITIONAL_PREDICATE_TYPE_CONDITIONAL); + pm_unless_node_t *node = PM_NODE_ALLOC(parser, pm_unless_node_t); + + pm_statements_node_t *statements = pm_statements_node_create(parser); + pm_statements_node_body_append(parser, statements, statement, true); + + *node = (pm_unless_node_t) { + { + .type = PM_UNLESS_NODE, + .flags = PM_NODE_FLAG_NEWLINE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = statement->location.start, + .end = predicate->location.end + }, + }, + .keyword_loc = PM_LOCATION_TOKEN_VALUE(unless_keyword), + .predicate = predicate, + .then_keyword_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .statements = statements, + .else_clause = NULL, + .end_keyword_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE + }; + + return node; +} + +static inline void +pm_unless_node_end_keyword_loc_set(pm_unless_node_t *node, const pm_token_t *end_keyword) { + node->end_keyword_loc = PM_LOCATION_TOKEN_VALUE(end_keyword); + node->base.location.end = end_keyword->end; +} + +/** + * Loop modifiers could potentially modify an expression that contains block + * exits. In this case we need to loop through them and remove them from the + * list of block exits so that they do not later get marked as invalid. + */ +static void +pm_loop_modifier_block_exits(pm_parser_t *parser, pm_statements_node_t *statements) { + assert(parser->current_block_exits != NULL); + + // All of the block exits that we want to remove should be within the + // statements, and since we are modifying the statements, we shouldn't have + // to check the end location. + const uint8_t *start = statements->base.location.start; + + for (size_t index = parser->current_block_exits->size; index > 0; index--) { + pm_node_t *block_exit = parser->current_block_exits->nodes[index - 1]; + if (block_exit->location.start < start) break; + + // Implicitly remove from the list by lowering the size. + parser->current_block_exits->size--; + } +} + +/** + * Allocate a new UntilNode node. + */ +static pm_until_node_t * +pm_until_node_create(pm_parser_t *parser, const pm_token_t *keyword, const pm_token_t *do_keyword, const pm_token_t *closing, pm_node_t *predicate, pm_statements_node_t *statements, pm_node_flags_t flags) { + pm_until_node_t *node = PM_NODE_ALLOC(parser, pm_until_node_t); + pm_conditional_predicate(parser, predicate, PM_CONDITIONAL_PREDICATE_TYPE_CONDITIONAL); + + *node = (pm_until_node_t) { + { + .type = PM_UNTIL_NODE, + .flags = flags, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = keyword->start, + .end = closing->end, + }, + }, + .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword), + .do_keyword_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(do_keyword), + .closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(closing), + .predicate = predicate, + .statements = statements + }; + + return node; +} + +/** + * Allocate a new UntilNode node. + */ +static pm_until_node_t * +pm_until_node_modifier_create(pm_parser_t *parser, const pm_token_t *keyword, pm_node_t *predicate, pm_statements_node_t *statements, pm_node_flags_t flags) { + pm_until_node_t *node = PM_NODE_ALLOC(parser, pm_until_node_t); + pm_conditional_predicate(parser, predicate, PM_CONDITIONAL_PREDICATE_TYPE_CONDITIONAL); + pm_loop_modifier_block_exits(parser, statements); + + *node = (pm_until_node_t) { + { + .type = PM_UNTIL_NODE, + .flags = flags, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = statements->base.location.start, + .end = predicate->location.end, + }, + }, + .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword), + .do_keyword_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .closing_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .predicate = predicate, + .statements = statements + }; + + return node; +} + +/** + * Allocate and initialize a new WhenNode node. + */ +static pm_when_node_t * +pm_when_node_create(pm_parser_t *parser, const pm_token_t *keyword) { + pm_when_node_t *node = PM_NODE_ALLOC(parser, pm_when_node_t); + + *node = (pm_when_node_t) { + { + .type = PM_WHEN_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = keyword->start, + .end = NULL + } + }, + .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword), + .statements = NULL, + .then_keyword_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .conditions = { 0 } + }; + + return node; +} + +/** + * Append a new condition to a when node. + */ +static void +pm_when_node_conditions_append(pm_when_node_t *node, pm_node_t *condition) { + node->base.location.end = condition->location.end; + pm_node_list_append(&node->conditions, condition); +} + +/** + * Set the location of the then keyword of a when node. + */ +static inline void +pm_when_node_then_keyword_loc_set(pm_when_node_t *node, const pm_token_t *then_keyword) { + node->base.location.end = then_keyword->end; + node->then_keyword_loc = PM_LOCATION_TOKEN_VALUE(then_keyword); +} + +/** + * Set the statements list of a when node. + */ +static void +pm_when_node_statements_set(pm_when_node_t *node, pm_statements_node_t *statements) { + if (statements->base.location.end > node->base.location.end) { + node->base.location.end = statements->base.location.end; + } + + node->statements = statements; +} + +/** + * Allocate a new WhileNode node. + */ +static pm_while_node_t * +pm_while_node_create(pm_parser_t *parser, const pm_token_t *keyword, const pm_token_t *do_keyword, const pm_token_t *closing, pm_node_t *predicate, pm_statements_node_t *statements, pm_node_flags_t flags) { + pm_while_node_t *node = PM_NODE_ALLOC(parser, pm_while_node_t); + pm_conditional_predicate(parser, predicate, PM_CONDITIONAL_PREDICATE_TYPE_CONDITIONAL); + + *node = (pm_while_node_t) { + { + .type = PM_WHILE_NODE, + .flags = flags, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = keyword->start, + .end = closing->end + }, + }, + .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword), + .do_keyword_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(do_keyword), + .closing_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(closing), + .predicate = predicate, + .statements = statements + }; + + return node; +} + +/** + * Allocate a new WhileNode node. + */ +static pm_while_node_t * +pm_while_node_modifier_create(pm_parser_t *parser, const pm_token_t *keyword, pm_node_t *predicate, pm_statements_node_t *statements, pm_node_flags_t flags) { + pm_while_node_t *node = PM_NODE_ALLOC(parser, pm_while_node_t); + pm_conditional_predicate(parser, predicate, PM_CONDITIONAL_PREDICATE_TYPE_CONDITIONAL); + pm_loop_modifier_block_exits(parser, statements); + + *node = (pm_while_node_t) { + { + .type = PM_WHILE_NODE, + .flags = flags, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = statements->base.location.start, + .end = predicate->location.end + }, + }, + .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword), + .do_keyword_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .closing_loc = PM_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .predicate = predicate, + .statements = statements + }; + + return node; +} + +/** + * Allocate and initialize a new synthesized while loop. + */ +static pm_while_node_t * +pm_while_node_synthesized_create(pm_parser_t *parser, pm_node_t *predicate, pm_statements_node_t *statements) { + pm_while_node_t *node = PM_NODE_ALLOC(parser, pm_while_node_t); + + *node = (pm_while_node_t) { + { + .type = PM_WHILE_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = PM_LOCATION_NULL_VALUE(parser) + }, + .keyword_loc = PM_LOCATION_NULL_VALUE(parser), + .do_keyword_loc = PM_LOCATION_NULL_VALUE(parser), + .closing_loc = PM_LOCATION_NULL_VALUE(parser), + .predicate = predicate, + .statements = statements + }; + + return node; +} + +/** + * Allocate and initialize a new XStringNode node with the given unescaped + * string. + */ +static pm_x_string_node_t * +pm_xstring_node_create_unescaped(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *content, const pm_token_t *closing, const pm_string_t *unescaped) { + pm_x_string_node_t *node = PM_NODE_ALLOC(parser, pm_x_string_node_t); + + *node = (pm_x_string_node_t) { + { + .type = PM_X_STRING_NODE, + .flags = PM_STRING_FLAGS_FROZEN, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = opening->start, + .end = closing->end + }, + }, + .opening_loc = PM_LOCATION_TOKEN_VALUE(opening), + .content_loc = PM_LOCATION_TOKEN_VALUE(content), + .closing_loc = PM_LOCATION_TOKEN_VALUE(closing), + .unescaped = *unescaped + }; + + return node; +} + +/** + * Allocate and initialize a new XStringNode node. + */ +static inline pm_x_string_node_t * +pm_xstring_node_create(pm_parser_t *parser, const pm_token_t *opening, const pm_token_t *content, const pm_token_t *closing) { + return pm_xstring_node_create_unescaped(parser, opening, content, closing, &PM_STRING_EMPTY); +} + +/** + * Allocate a new YieldNode node. + */ +static pm_yield_node_t * +pm_yield_node_create(pm_parser_t *parser, const pm_token_t *keyword, const pm_location_t *lparen_loc, pm_arguments_node_t *arguments, const pm_location_t *rparen_loc) { + pm_yield_node_t *node = PM_NODE_ALLOC(parser, pm_yield_node_t); + + const uint8_t *end; + if (rparen_loc->start != NULL) { + end = rparen_loc->end; + } else if (arguments != NULL) { + end = arguments->base.location.end; + } else if (lparen_loc->start != NULL) { + end = lparen_loc->end; + } else { + end = keyword->end; + } + + *node = (pm_yield_node_t) { + { + .type = PM_YIELD_NODE, + .node_id = PM_NODE_IDENTIFY(parser), + .location = { + .start = keyword->start, + .end = end + }, + }, + .keyword_loc = PM_LOCATION_TOKEN_VALUE(keyword), + .lparen_loc = *lparen_loc, + .arguments = arguments, + .rparen_loc = *rparen_loc + }; + + return node; +} + +#undef PM_NODE_ALLOC +#undef PM_NODE_IDENTIFY + +/** + * Check if any of the currently visible scopes contain a local variable + * described by the given constant id. + */ +static int +pm_parser_local_depth_constant_id(pm_parser_t *parser, pm_constant_id_t constant_id) { + pm_scope_t *scope = parser->current_scope; + int depth = 0; + + while (scope != NULL) { + if (pm_locals_find(&scope->locals, constant_id) != UINT32_MAX) return depth; + if (scope->closed) break; + + scope = scope->previous; + depth++; + } + + return -1; +} + +/** + * Check if any of the currently visible scopes contain a local variable + * described by the given token. This function implicitly inserts a constant + * into the constant pool. + */ +static inline int +pm_parser_local_depth(pm_parser_t *parser, pm_token_t *token) { + return pm_parser_local_depth_constant_id(parser, pm_parser_constant_id_token(parser, token)); +} + +/** + * Add a constant id to the local table of the current scope. + */ +static inline void +pm_parser_local_add(pm_parser_t *parser, pm_constant_id_t constant_id, const uint8_t *start, const uint8_t *end, uint32_t reads) { + pm_locals_write(&parser->current_scope->locals, constant_id, start, end, reads); +} + +/** + * Add a local variable from a location to the current scope. + */ +static pm_constant_id_t +pm_parser_local_add_location(pm_parser_t *parser, const uint8_t *start, const uint8_t *end, uint32_t reads) { + pm_constant_id_t constant_id = pm_parser_constant_id_location(parser, start, end); + if (constant_id != 0) pm_parser_local_add(parser, constant_id, start, end, reads); + return constant_id; +} + +/** + * Add a local variable from a token to the current scope. + */ +static inline pm_constant_id_t +pm_parser_local_add_token(pm_parser_t *parser, pm_token_t *token, uint32_t reads) { + return pm_parser_local_add_location(parser, token->start, token->end, reads); +} + +/** + * Add a local variable from an owned string to the current scope. + */ +static pm_constant_id_t +pm_parser_local_add_owned(pm_parser_t *parser, uint8_t *start, size_t length) { + pm_constant_id_t constant_id = pm_parser_constant_id_owned(parser, start, length); + if (constant_id != 0) pm_parser_local_add(parser, constant_id, parser->start, parser->start, 1); + return constant_id; +} + +/** + * Add a local variable from a constant string to the current scope. + */ +static pm_constant_id_t +pm_parser_local_add_constant(pm_parser_t *parser, const char *start, size_t length) { + pm_constant_id_t constant_id = pm_parser_constant_id_constant(parser, start, length); + if (constant_id != 0) pm_parser_local_add(parser, constant_id, parser->start, parser->start, 1); + return constant_id; +} + +/** + * Add a parameter name to the current scope and check whether the name of the + * parameter is unique or not. + * + * Returns `true` if this is a duplicate parameter name, otherwise returns + * false. + */ +static bool +pm_parser_parameter_name_check(pm_parser_t *parser, const pm_token_t *name) { + // We want to check whether the parameter name is a numbered parameter or + // not. + pm_refute_numbered_parameter(parser, name->start, name->end); + + // Otherwise we'll fetch the constant id for the parameter name and check + // whether it's already in the current scope. + pm_constant_id_t constant_id = pm_parser_constant_id_token(parser, name); + + if (pm_locals_find(&parser->current_scope->locals, constant_id) != UINT32_MAX) { + // Add an error if the parameter doesn't start with _ and has been seen before + if ((name->start < name->end) && (*name->start != '_')) { + pm_parser_err_token(parser, name, PM_ERR_PARAMETER_NAME_DUPLICATED); + } + return true; + } + return false; +} + +/** + * Pop the current scope off the scope stack. + */ +static void +pm_parser_scope_pop(pm_parser_t *parser) { + pm_scope_t *scope = parser->current_scope; + parser->current_scope = scope->previous; + pm_locals_free(&scope->locals); + pm_node_list_free(&scope->implicit_parameters); + xfree(scope); +} + +/******************************************************************************/ +/* Stack helpers */ +/******************************************************************************/ + +/** + * Pushes a value onto the stack. + */ +static inline void +pm_state_stack_push(pm_state_stack_t *stack, bool value) { + *stack = (*stack << 1) | (value & 1); +} + +/** + * Pops a value off the stack. + */ +static inline void +pm_state_stack_pop(pm_state_stack_t *stack) { + *stack >>= 1; +} + +/** + * Returns the value at the top of the stack. + */ +static inline bool +pm_state_stack_p(const pm_state_stack_t *stack) { + return *stack & 1; +} + +static inline void +pm_accepts_block_stack_push(pm_parser_t *parser, bool value) { + // Use the negation of the value to prevent stack overflow. + pm_state_stack_push(&parser->accepts_block_stack, !value); +} + +static inline void +pm_accepts_block_stack_pop(pm_parser_t *parser) { + pm_state_stack_pop(&parser->accepts_block_stack); +} + +static inline bool +pm_accepts_block_stack_p(pm_parser_t *parser) { + return !pm_state_stack_p(&parser->accepts_block_stack); +} + +static inline void +pm_do_loop_stack_push(pm_parser_t *parser, bool value) { + pm_state_stack_push(&parser->do_loop_stack, value); +} + +static inline void +pm_do_loop_stack_pop(pm_parser_t *parser) { + pm_state_stack_pop(&parser->do_loop_stack); +} + +static inline bool +pm_do_loop_stack_p(pm_parser_t *parser) { + return pm_state_stack_p(&parser->do_loop_stack); +} + +/******************************************************************************/ +/* Lexer check helpers */ +/******************************************************************************/ + +/** + * Get the next character in the source starting from +cursor+. If that position + * is beyond the end of the source then return '\0'. + */ +static inline uint8_t +peek_at(const pm_parser_t *parser, const uint8_t *cursor) { + if (cursor < parser->end) { + return *cursor; + } else { + return '\0'; + } +} + +/** + * Get the next character in the source starting from parser->current.end and + * adding the given offset. If that position is beyond the end of the source + * then return '\0'. + */ +static inline uint8_t +peek_offset(pm_parser_t *parser, ptrdiff_t offset) { + return peek_at(parser, parser->current.end + offset); +} + +/** + * Get the next character in the source starting from parser->current.end. If + * that position is beyond the end of the source then return '\0'. + */ +static inline uint8_t +peek(const pm_parser_t *parser) { + return peek_at(parser, parser->current.end); +} + +/** + * If the character to be read matches the given value, then returns true and + * advances the current pointer. + */ +static inline bool +match(pm_parser_t *parser, uint8_t value) { + if (peek(parser) == value) { + parser->current.end++; + return true; + } + return false; +} + +/** + * Return the length of the line ending string starting at +cursor+, or 0 if it + * is not a line ending. This function is intended to be CRLF/LF agnostic. + */ +static inline size_t +match_eol_at(pm_parser_t *parser, const uint8_t *cursor) { + if (peek_at(parser, cursor) == '\n') { + return 1; + } + if (peek_at(parser, cursor) == '\r' && peek_at(parser, cursor + 1) == '\n') { + return 2; + } + return 0; +} + +/** + * Return the length of the line ending string starting at + * `parser->current.end + offset`, or 0 if it is not a line ending. This + * function is intended to be CRLF/LF agnostic. + */ +static inline size_t +match_eol_offset(pm_parser_t *parser, ptrdiff_t offset) { + return match_eol_at(parser, parser->current.end + offset); +} + +/** + * Return the length of the line ending string starting at parser->current.end, + * or 0 if it is not a line ending. This function is intended to be CRLF/LF + * agnostic. + */ +static inline size_t +match_eol(pm_parser_t *parser) { + return match_eol_at(parser, parser->current.end); +} + +/** + * Skip to the next newline character or NUL byte. + */ +static inline const uint8_t * +next_newline(const uint8_t *cursor, ptrdiff_t length) { + assert(length >= 0); + + // Note that it's okay for us to use memchr here to look for \n because none + // of the encodings that we support have \n as a component of a multi-byte + // character. + return memchr(cursor, '\n', (size_t) length); +} + +/** + * This is equivalent to the predicate of warn_balanced in CRuby. + */ +static inline bool +ambiguous_operator_p(const pm_parser_t *parser, bool space_seen) { + return !lex_state_p(parser, PM_LEX_STATE_CLASS | PM_LEX_STATE_DOT | PM_LEX_STATE_FNAME | PM_LEX_STATE_ENDFN) && space_seen && !pm_char_is_whitespace(peek(parser)); +} + +/** + * Here we're going to check if this is a "magic" comment, and perform whatever + * actions are necessary for it here. + */ +static bool +parser_lex_magic_comment_encoding_value(pm_parser_t *parser, const uint8_t *start, const uint8_t *end) { + const pm_encoding_t *encoding = pm_encoding_find(start, end); + + if (encoding != NULL) { + if (parser->encoding != encoding) { + parser->encoding = encoding; + if (parser->encoding_changed_callback != NULL) parser->encoding_changed_callback(parser); + } + + parser->encoding_changed = (encoding != PM_ENCODING_UTF_8_ENTRY); + return true; + } + + return false; +} + +/** + * Look for a specific pattern of "coding" and potentially set the encoding on + * the parser. + */ +static void +parser_lex_magic_comment_encoding(pm_parser_t *parser) { + const uint8_t *cursor = parser->current.start + 1; + const uint8_t *end = parser->current.end; + + bool separator = false; + while (true) { + if (end - cursor <= 6) return; + switch (cursor[6]) { + case 'C': case 'c': cursor += 6; continue; + case 'O': case 'o': cursor += 5; continue; + case 'D': case 'd': cursor += 4; continue; + case 'I': case 'i': cursor += 3; continue; + case 'N': case 'n': cursor += 2; continue; + case 'G': case 'g': cursor += 1; continue; + case '=': case ':': + separator = true; + cursor += 6; + break; + default: + cursor += 6; + if (pm_char_is_whitespace(*cursor)) break; + continue; + } + if (pm_strncasecmp(cursor - 6, (const uint8_t *) "coding", 6) == 0) break; + separator = false; + } + + while (true) { + do { + if (++cursor >= end) return; + } while (pm_char_is_whitespace(*cursor)); + + if (separator) break; + if (*cursor != '=' && *cursor != ':') return; + + separator = true; + cursor++; + } + + const uint8_t *value_start = cursor; + while ((*cursor == '-' || *cursor == '_' || parser->encoding->alnum_char(cursor, 1)) && ++cursor < end); + + if (!parser_lex_magic_comment_encoding_value(parser, value_start, cursor)) { + // If we were unable to parse the encoding value, then we've got an + // issue because we didn't understand the encoding that the user was + // trying to use. In this case we'll keep using the default encoding but + // add an error to the parser to indicate an unsuccessful parse. + pm_parser_err(parser, value_start, cursor, PM_ERR_INVALID_ENCODING_MAGIC_COMMENT); + } +} + +typedef enum { + PM_MAGIC_COMMENT_BOOLEAN_VALUE_TRUE, + PM_MAGIC_COMMENT_BOOLEAN_VALUE_FALSE, + PM_MAGIC_COMMENT_BOOLEAN_VALUE_INVALID +} pm_magic_comment_boolean_value_t; + +/** + * Check if this is a magic comment that includes the frozen_string_literal + * pragma. If it does, set that field on the parser. + */ +static pm_magic_comment_boolean_value_t +parser_lex_magic_comment_boolean_value(const uint8_t *value_start, uint32_t value_length) { + if (value_length == 4 && pm_strncasecmp(value_start, (const uint8_t *) "true", 4) == 0) { + return PM_MAGIC_COMMENT_BOOLEAN_VALUE_TRUE; + } else if (value_length == 5 && pm_strncasecmp(value_start, (const uint8_t *) "false", 5) == 0) { + return PM_MAGIC_COMMENT_BOOLEAN_VALUE_FALSE; + } else { + return PM_MAGIC_COMMENT_BOOLEAN_VALUE_INVALID; + } +} + +static inline bool +pm_char_is_magic_comment_key_delimiter(const uint8_t b) { + return b == '\'' || b == '"' || b == ':' || b == ';'; +} + +/** + * Find an emacs magic comment marker (-*-) within the given bounds. If one is + * found, it returns a pointer to the start of the marker. Otherwise it returns + * NULL. + */ +static inline const uint8_t * +parser_lex_magic_comment_emacs_marker(pm_parser_t *parser, const uint8_t *cursor, const uint8_t *end) { + while ((cursor + 3 <= end) && (cursor = pm_memchr(cursor, '-', (size_t) (end - cursor), parser->encoding_changed, parser->encoding)) != NULL) { + if (cursor + 3 <= end && cursor[1] == '*' && cursor[2] == '-') { + return cursor; + } + cursor++; + } + return NULL; +} + +/** + * Parse the current token on the parser to see if it's a magic comment and + * potentially perform some action based on that. A regular expression that this + * function is effectively matching is: + * + * %r"([^\\s\'\":;]+)\\s*:\\s*(\"(?:\\\\.|[^\"])*\"|[^\"\\s;]+)[\\s;]*" + * + * It returns true if it consumes the entire comment. Otherwise it returns + * false. + */ +static inline bool +parser_lex_magic_comment(pm_parser_t *parser, bool semantic_token_seen) { + bool result = true; + + const uint8_t *start = parser->current.start + 1; + const uint8_t *end = parser->current.end; + if (end - start <= 7) return false; + + const uint8_t *cursor; + bool indicator = false; + + if ((cursor = parser_lex_magic_comment_emacs_marker(parser, start, end)) != NULL) { + start = cursor + 3; + + if ((cursor = parser_lex_magic_comment_emacs_marker(parser, start, end)) != NULL) { + end = cursor; + indicator = true; + } else { + // If we have a start marker but not an end marker, then we cannot + // have a magic comment. + return false; + } + } + + cursor = start; + while (cursor < end) { + while (cursor < end && (pm_char_is_magic_comment_key_delimiter(*cursor) || pm_char_is_whitespace(*cursor))) cursor++; + + const uint8_t *key_start = cursor; + while (cursor < end && (!pm_char_is_magic_comment_key_delimiter(*cursor) && !pm_char_is_whitespace(*cursor))) cursor++; + + const uint8_t *key_end = cursor; + while (cursor < end && pm_char_is_whitespace(*cursor)) cursor++; + if (cursor == end) break; + + if (*cursor == ':') { + cursor++; + } else { + if (!indicator) return false; + continue; + } + + while (cursor < end && pm_char_is_whitespace(*cursor)) cursor++; + if (cursor == end) break; + + const uint8_t *value_start; + const uint8_t *value_end; + + if (*cursor == '"') { + value_start = ++cursor; + for (; cursor < end && *cursor != '"'; cursor++) { + if (*cursor == '\\' && (cursor + 1 < end)) cursor++; + } + value_end = cursor; + if (*cursor == '"') cursor++; + } else { + value_start = cursor; + while (cursor < end && *cursor != '"' && *cursor != ';' && !pm_char_is_whitespace(*cursor)) cursor++; + value_end = cursor; + } + + if (indicator) { + while (cursor < end && (*cursor == ';' || pm_char_is_whitespace(*cursor))) cursor++; + } else { + while (cursor < end && pm_char_is_whitespace(*cursor)) cursor++; + if (cursor != end) return false; + } + + // Here, we need to do some processing on the key to swap out dashes for + // underscores. We only need to do this if there _is_ a dash in the key. + pm_string_t key; + const size_t key_length = (size_t) (key_end - key_start); + const uint8_t *dash = pm_memchr(key_start, '-', key_length, parser->encoding_changed, parser->encoding); + + if (dash == NULL) { + pm_string_shared_init(&key, key_start, key_end); + } else { + uint8_t *buffer = xmalloc(key_length); + if (buffer == NULL) break; + + memcpy(buffer, key_start, key_length); + buffer[dash - key_start] = '_'; + + while ((dash = pm_memchr(dash + 1, '-', (size_t) (key_end - dash - 1), parser->encoding_changed, parser->encoding)) != NULL) { + buffer[dash - key_start] = '_'; + } + + pm_string_owned_init(&key, buffer, key_length); + } + + // Finally, we can start checking the key against the list of known + // magic comment keys, and potentially change state based on that. + const uint8_t *key_source = pm_string_source(&key); + uint32_t value_length = (uint32_t) (value_end - value_start); + + // We only want to attempt to compare against encoding comments if it's + // the first line in the file (or the second in the case of a shebang). + if (parser->current.start == parser->encoding_comment_start && !parser->encoding_locked) { + if ( + (key_length == 8 && pm_strncasecmp(key_source, (const uint8_t *) "encoding", 8) == 0) || + (key_length == 6 && pm_strncasecmp(key_source, (const uint8_t *) "coding", 6) == 0) + ) { + result = parser_lex_magic_comment_encoding_value(parser, value_start, value_end); + } + } + + if (key_length == 11) { + if (pm_strncasecmp(key_source, (const uint8_t *) "warn_indent", 11) == 0) { + switch (parser_lex_magic_comment_boolean_value(value_start, value_length)) { + case PM_MAGIC_COMMENT_BOOLEAN_VALUE_INVALID: + PM_PARSER_WARN_TOKEN_FORMAT( + parser, + parser->current, + PM_WARN_INVALID_MAGIC_COMMENT_VALUE, + (int) key_length, + (const char *) key_source, + (int) value_length, + (const char *) value_start + ); + break; + case PM_MAGIC_COMMENT_BOOLEAN_VALUE_FALSE: + parser->warn_mismatched_indentation = false; + break; + case PM_MAGIC_COMMENT_BOOLEAN_VALUE_TRUE: + parser->warn_mismatched_indentation = true; + break; + } + } + } else if (key_length == 21) { + if (pm_strncasecmp(key_source, (const uint8_t *) "frozen_string_literal", 21) == 0) { + // We only want to handle frozen string literal comments if it's + // before any semantic tokens have been seen. + if (semantic_token_seen) { + pm_parser_warn_token(parser, &parser->current, PM_WARN_IGNORED_FROZEN_STRING_LITERAL); + } else { + switch (parser_lex_magic_comment_boolean_value(value_start, value_length)) { + case PM_MAGIC_COMMENT_BOOLEAN_VALUE_INVALID: + PM_PARSER_WARN_TOKEN_FORMAT( + parser, + parser->current, + PM_WARN_INVALID_MAGIC_COMMENT_VALUE, + (int) key_length, + (const char *) key_source, + (int) value_length, + (const char *) value_start + ); + break; + case PM_MAGIC_COMMENT_BOOLEAN_VALUE_FALSE: + parser->frozen_string_literal = PM_OPTIONS_FROZEN_STRING_LITERAL_DISABLED; + break; + case PM_MAGIC_COMMENT_BOOLEAN_VALUE_TRUE: + parser->frozen_string_literal = PM_OPTIONS_FROZEN_STRING_LITERAL_ENABLED; + break; + } + } + } + } else if (key_length == 24) { + if (pm_strncasecmp(key_source, (const uint8_t *) "shareable_constant_value", 24) == 0) { + const uint8_t *cursor = parser->current.start; + while ((cursor > parser->start) && ((cursor[-1] == ' ') || (cursor[-1] == '\t'))) cursor--; + + if (!((cursor == parser->start) || (cursor[-1] == '\n'))) { + pm_parser_warn_token(parser, &parser->current, PM_WARN_SHAREABLE_CONSTANT_VALUE_LINE); + } else if (value_length == 4 && pm_strncasecmp(value_start, (const uint8_t *) "none", 4) == 0) { + pm_parser_scope_shareable_constant_set(parser, PM_SCOPE_SHAREABLE_CONSTANT_NONE); + } else if (value_length == 7 && pm_strncasecmp(value_start, (const uint8_t *) "literal", 7) == 0) { + pm_parser_scope_shareable_constant_set(parser, PM_SCOPE_SHAREABLE_CONSTANT_LITERAL); + } else if (value_length == 23 && pm_strncasecmp(value_start, (const uint8_t *) "experimental_everything", 23) == 0) { + pm_parser_scope_shareable_constant_set(parser, PM_SCOPE_SHAREABLE_CONSTANT_EXPERIMENTAL_EVERYTHING); + } else if (value_length == 17 && pm_strncasecmp(value_start, (const uint8_t *) "experimental_copy", 17) == 0) { + pm_parser_scope_shareable_constant_set(parser, PM_SCOPE_SHAREABLE_CONSTANT_EXPERIMENTAL_COPY); + } else { + PM_PARSER_WARN_TOKEN_FORMAT( + parser, + parser->current, + PM_WARN_INVALID_MAGIC_COMMENT_VALUE, + (int) key_length, + (const char *) key_source, + (int) value_length, + (const char *) value_start + ); + } + } + } + + // When we're done, we want to free the string in case we had to + // allocate memory for it. + pm_string_free(&key); + + // Allocate a new magic comment node to append to the parser's list. + pm_magic_comment_t *magic_comment; + if ((magic_comment = (pm_magic_comment_t *) xcalloc(1, sizeof(pm_magic_comment_t))) != NULL) { + magic_comment->key_start = key_start; + magic_comment->value_start = value_start; + magic_comment->key_length = (uint32_t) key_length; + magic_comment->value_length = value_length; + pm_list_append(&parser->magic_comment_list, (pm_list_node_t *) magic_comment); + } + } + + return result; +} + +/******************************************************************************/ +/* Context manipulations */ +/******************************************************************************/ + +static bool +context_terminator(pm_context_t context, pm_token_t *token) { + switch (context) { + case PM_CONTEXT_MAIN: + case PM_CONTEXT_DEF_PARAMS: + case PM_CONTEXT_DEFINED: + case PM_CONTEXT_MULTI_TARGET: + case PM_CONTEXT_TERNARY: + case PM_CONTEXT_RESCUE_MODIFIER: + return token->type == PM_TOKEN_EOF; + case PM_CONTEXT_DEFAULT_PARAMS: + return token->type == PM_TOKEN_COMMA || token->type == PM_TOKEN_PARENTHESIS_RIGHT; + case PM_CONTEXT_PREEXE: + case PM_CONTEXT_POSTEXE: + return token->type == PM_TOKEN_BRACE_RIGHT; + case PM_CONTEXT_MODULE: + case PM_CONTEXT_CLASS: + case PM_CONTEXT_SCLASS: + case PM_CONTEXT_LAMBDA_DO_END: + case PM_CONTEXT_DEF: + case PM_CONTEXT_BLOCK_KEYWORDS: + return token->type == PM_TOKEN_KEYWORD_END || token->type == PM_TOKEN_KEYWORD_RESCUE || token->type == PM_TOKEN_KEYWORD_ENSURE; + case PM_CONTEXT_WHILE: + case PM_CONTEXT_UNTIL: + case PM_CONTEXT_ELSE: + case PM_CONTEXT_FOR: + case PM_CONTEXT_BEGIN_ENSURE: + case PM_CONTEXT_BLOCK_ENSURE: + case PM_CONTEXT_CLASS_ENSURE: + case PM_CONTEXT_DEF_ENSURE: + case PM_CONTEXT_LAMBDA_ENSURE: + case PM_CONTEXT_MODULE_ENSURE: + case PM_CONTEXT_SCLASS_ENSURE: + return token->type == PM_TOKEN_KEYWORD_END; + case PM_CONTEXT_LOOP_PREDICATE: + return token->type == PM_TOKEN_KEYWORD_DO || token->type == PM_TOKEN_KEYWORD_THEN; + case PM_CONTEXT_FOR_INDEX: + return token->type == PM_TOKEN_KEYWORD_IN; + case PM_CONTEXT_CASE_WHEN: + return token->type == PM_TOKEN_KEYWORD_WHEN || token->type == PM_TOKEN_KEYWORD_END || token->type == PM_TOKEN_KEYWORD_ELSE; + case PM_CONTEXT_CASE_IN: + return token->type == PM_TOKEN_KEYWORD_IN || token->type == PM_TOKEN_KEYWORD_END || token->type == PM_TOKEN_KEYWORD_ELSE; + case PM_CONTEXT_IF: + case PM_CONTEXT_ELSIF: + return token->type == PM_TOKEN_KEYWORD_ELSE || token->type == PM_TOKEN_KEYWORD_ELSIF || token->type == PM_TOKEN_KEYWORD_END; + case PM_CONTEXT_UNLESS: + return token->type == PM_TOKEN_KEYWORD_ELSE || token->type == PM_TOKEN_KEYWORD_END; + case PM_CONTEXT_EMBEXPR: + return token->type == PM_TOKEN_EMBEXPR_END; + case PM_CONTEXT_BLOCK_BRACES: + return token->type == PM_TOKEN_BRACE_RIGHT; + case PM_CONTEXT_PARENS: + return token->type == PM_TOKEN_PARENTHESIS_RIGHT; + case PM_CONTEXT_BEGIN: + case PM_CONTEXT_BEGIN_RESCUE: + case PM_CONTEXT_BLOCK_RESCUE: + case PM_CONTEXT_CLASS_RESCUE: + case PM_CONTEXT_DEF_RESCUE: + case PM_CONTEXT_LAMBDA_RESCUE: + case PM_CONTEXT_MODULE_RESCUE: + case PM_CONTEXT_SCLASS_RESCUE: + return token->type == PM_TOKEN_KEYWORD_ENSURE || token->type == PM_TOKEN_KEYWORD_RESCUE || token->type == PM_TOKEN_KEYWORD_ELSE || token->type == PM_TOKEN_KEYWORD_END; + case PM_CONTEXT_BEGIN_ELSE: + case PM_CONTEXT_BLOCK_ELSE: + case PM_CONTEXT_CLASS_ELSE: + case PM_CONTEXT_DEF_ELSE: + case PM_CONTEXT_LAMBDA_ELSE: + case PM_CONTEXT_MODULE_ELSE: + case PM_CONTEXT_SCLASS_ELSE: + return token->type == PM_TOKEN_KEYWORD_ENSURE || token->type == PM_TOKEN_KEYWORD_END; + case PM_CONTEXT_LAMBDA_BRACES: + return token->type == PM_TOKEN_BRACE_RIGHT; + case PM_CONTEXT_PREDICATE: + return token->type == PM_TOKEN_KEYWORD_THEN || token->type == PM_TOKEN_NEWLINE || token->type == PM_TOKEN_SEMICOLON; + case PM_CONTEXT_NONE: + return false; + } + + return false; +} + +/** + * Returns the context that the given token is found to be terminating, or + * returns PM_CONTEXT_NONE. + */ +static pm_context_t +context_recoverable(const pm_parser_t *parser, pm_token_t *token) { + pm_context_node_t *context_node = parser->current_context; + + while (context_node != NULL) { + if (context_terminator(context_node->context, token)) return context_node->context; + context_node = context_node->prev; + } + + return PM_CONTEXT_NONE; +} + +static bool +context_push(pm_parser_t *parser, pm_context_t context) { + pm_context_node_t *context_node = (pm_context_node_t *) xmalloc(sizeof(pm_context_node_t)); + if (context_node == NULL) return false; + + *context_node = (pm_context_node_t) { .context = context, .prev = NULL }; + + if (parser->current_context == NULL) { + parser->current_context = context_node; + } else { + context_node->prev = parser->current_context; + parser->current_context = context_node; + } + + return true; +} + +static void +context_pop(pm_parser_t *parser) { + pm_context_node_t *prev = parser->current_context->prev; + xfree(parser->current_context); + parser->current_context = prev; +} + +static bool +context_p(const pm_parser_t *parser, pm_context_t context) { + pm_context_node_t *context_node = parser->current_context; + + while (context_node != NULL) { + if (context_node->context == context) return true; + context_node = context_node->prev; + } + + return false; +} + +static bool +context_def_p(const pm_parser_t *parser) { + pm_context_node_t *context_node = parser->current_context; + + while (context_node != NULL) { + switch (context_node->context) { + case PM_CONTEXT_DEF: + case PM_CONTEXT_DEF_PARAMS: + case PM_CONTEXT_DEF_ENSURE: + case PM_CONTEXT_DEF_RESCUE: + case PM_CONTEXT_DEF_ELSE: + return true; + case PM_CONTEXT_CLASS: + case PM_CONTEXT_CLASS_ENSURE: + case PM_CONTEXT_CLASS_RESCUE: + case PM_CONTEXT_CLASS_ELSE: + case PM_CONTEXT_MODULE: + case PM_CONTEXT_MODULE_ENSURE: + case PM_CONTEXT_MODULE_RESCUE: + case PM_CONTEXT_MODULE_ELSE: + case PM_CONTEXT_SCLASS: + case PM_CONTEXT_SCLASS_ENSURE: + case PM_CONTEXT_SCLASS_RESCUE: + case PM_CONTEXT_SCLASS_ELSE: + return false; + default: + context_node = context_node->prev; + } + } + + return false; +} + +/** + * Returns a human readable string for the given context, used in error + * messages. + */ +static const char * +context_human(pm_context_t context) { + switch (context) { + case PM_CONTEXT_NONE: + assert(false && "unreachable"); + return ""; + case PM_CONTEXT_BEGIN: return "begin statement"; + case PM_CONTEXT_BLOCK_BRACES: return "'{'..'}' block"; + case PM_CONTEXT_BLOCK_KEYWORDS: return "'do'..'end' block"; + case PM_CONTEXT_CASE_WHEN: return "'when' clause"; + case PM_CONTEXT_CASE_IN: return "'in' clause"; + case PM_CONTEXT_CLASS: return "class definition"; + case PM_CONTEXT_DEF: return "method definition"; + case PM_CONTEXT_DEF_PARAMS: return "method parameters"; + case PM_CONTEXT_DEFAULT_PARAMS: return "parameter default value"; + case PM_CONTEXT_DEFINED: return "'defined?' expression"; + case PM_CONTEXT_ELSE: + case PM_CONTEXT_BEGIN_ELSE: + case PM_CONTEXT_BLOCK_ELSE: + case PM_CONTEXT_CLASS_ELSE: + case PM_CONTEXT_DEF_ELSE: + case PM_CONTEXT_LAMBDA_ELSE: + case PM_CONTEXT_MODULE_ELSE: + case PM_CONTEXT_SCLASS_ELSE: return "'else' clause"; + case PM_CONTEXT_ELSIF: return "'elsif' clause"; + case PM_CONTEXT_EMBEXPR: return "embedded expression"; + case PM_CONTEXT_BEGIN_ENSURE: + case PM_CONTEXT_BLOCK_ENSURE: + case PM_CONTEXT_CLASS_ENSURE: + case PM_CONTEXT_DEF_ENSURE: + case PM_CONTEXT_LAMBDA_ENSURE: + case PM_CONTEXT_MODULE_ENSURE: + case PM_CONTEXT_SCLASS_ENSURE: return "'ensure' clause"; + case PM_CONTEXT_FOR: return "for loop"; + case PM_CONTEXT_FOR_INDEX: return "for loop index"; + case PM_CONTEXT_IF: return "if statement"; + case PM_CONTEXT_LAMBDA_BRACES: return "'{'..'}' lambda block"; + case PM_CONTEXT_LAMBDA_DO_END: return "'do'..'end' lambda block"; + case PM_CONTEXT_LOOP_PREDICATE: return "loop predicate"; + case PM_CONTEXT_MAIN: return "top level context"; + case PM_CONTEXT_MODULE: return "module definition"; + case PM_CONTEXT_MULTI_TARGET: return "multiple targets"; + case PM_CONTEXT_PARENS: return "parentheses"; + case PM_CONTEXT_POSTEXE: return "'END' block"; + case PM_CONTEXT_PREDICATE: return "predicate"; + case PM_CONTEXT_PREEXE: return "'BEGIN' block"; + case PM_CONTEXT_BEGIN_RESCUE: + case PM_CONTEXT_BLOCK_RESCUE: + case PM_CONTEXT_CLASS_RESCUE: + case PM_CONTEXT_DEF_RESCUE: + case PM_CONTEXT_LAMBDA_RESCUE: + case PM_CONTEXT_MODULE_RESCUE: + case PM_CONTEXT_RESCUE_MODIFIER: + case PM_CONTEXT_SCLASS_RESCUE: return "'rescue' clause"; + case PM_CONTEXT_SCLASS: return "singleton class definition"; + case PM_CONTEXT_TERNARY: return "ternary expression"; + case PM_CONTEXT_UNLESS: return "unless statement"; + case PM_CONTEXT_UNTIL: return "until statement"; + case PM_CONTEXT_WHILE: return "while statement"; + } + + assert(false && "unreachable"); + return ""; +} + +/******************************************************************************/ +/* Specific token lexers */ +/******************************************************************************/ + +static inline void +pm_strspn_number_validate(pm_parser_t *parser, const uint8_t *string, size_t length, const uint8_t *invalid) { + if (invalid != NULL) { + pm_diagnostic_id_t diag_id = (invalid == (string + length - 1)) ? PM_ERR_INVALID_NUMBER_UNDERSCORE_TRAILING : PM_ERR_INVALID_NUMBER_UNDERSCORE_INNER; + pm_parser_err(parser, invalid, invalid + 1, diag_id); + } +} + +static size_t +pm_strspn_binary_number_validate(pm_parser_t *parser, const uint8_t *string) { + const uint8_t *invalid = NULL; + size_t length = pm_strspn_binary_number(string, parser->end - string, &invalid); + pm_strspn_number_validate(parser, string, length, invalid); + return length; +} + +static size_t +pm_strspn_octal_number_validate(pm_parser_t *parser, const uint8_t *string) { + const uint8_t *invalid = NULL; + size_t length = pm_strspn_octal_number(string, parser->end - string, &invalid); + pm_strspn_number_validate(parser, string, length, invalid); + return length; +} + +static size_t +pm_strspn_decimal_number_validate(pm_parser_t *parser, const uint8_t *string) { + const uint8_t *invalid = NULL; + size_t length = pm_strspn_decimal_number(string, parser->end - string, &invalid); + pm_strspn_number_validate(parser, string, length, invalid); + return length; +} + +static size_t +pm_strspn_hexadecimal_number_validate(pm_parser_t *parser, const uint8_t *string) { + const uint8_t *invalid = NULL; + size_t length = pm_strspn_hexadecimal_number(string, parser->end - string, &invalid); + pm_strspn_number_validate(parser, string, length, invalid); + return length; +} + +static pm_token_type_t +lex_optional_float_suffix(pm_parser_t *parser, bool* seen_e) { + pm_token_type_t type = PM_TOKEN_INTEGER; + + // Here we're going to attempt to parse the optional decimal portion of a + // float. If it's not there, then it's okay and we'll just continue on. + if (peek(parser) == '.') { + if (pm_char_is_decimal_digit(peek_offset(parser, 1))) { + parser->current.end += 2; + parser->current.end += pm_strspn_decimal_number_validate(parser, parser->current.end); + type = PM_TOKEN_FLOAT; + } else { + // If we had a . and then something else, then it's not a float + // suffix on a number it's a method call or something else. + return type; + } + } + + // Here we're going to attempt to parse the optional exponent portion of a + // float. If it's not there, it's okay and we'll just continue on. + if ((peek(parser) == 'e') || (peek(parser) == 'E')) { + if ((peek_offset(parser, 1) == '+') || (peek_offset(parser, 1) == '-')) { + parser->current.end += 2; + + if (pm_char_is_decimal_digit(peek(parser))) { + parser->current.end++; + parser->current.end += pm_strspn_decimal_number_validate(parser, parser->current.end); + } else { + pm_parser_err_current(parser, PM_ERR_INVALID_FLOAT_EXPONENT); + } + } else if (pm_char_is_decimal_digit(peek_offset(parser, 1))) { + parser->current.end++; + parser->current.end += pm_strspn_decimal_number_validate(parser, parser->current.end); + } else { + return type; + } + + *seen_e = true; + type = PM_TOKEN_FLOAT; + } + + return type; +} + +static pm_token_type_t +lex_numeric_prefix(pm_parser_t *parser, bool* seen_e) { + pm_token_type_t type = PM_TOKEN_INTEGER; + *seen_e = false; + + if (peek_offset(parser, -1) == '0') { + switch (*parser->current.end) { + // 0d1111 is a decimal number + case 'd': + case 'D': + parser->current.end++; + if (pm_char_is_decimal_digit(peek(parser))) { + parser->current.end += pm_strspn_decimal_number_validate(parser, parser->current.end); + } else { + match(parser, '_'); + pm_parser_err_current(parser, PM_ERR_INVALID_NUMBER_DECIMAL); + } + + break; + + // 0b1111 is a binary number + case 'b': + case 'B': + parser->current.end++; + if (pm_char_is_binary_digit(peek(parser))) { + parser->current.end += pm_strspn_binary_number_validate(parser, parser->current.end); + } else { + match(parser, '_'); + pm_parser_err_current(parser, PM_ERR_INVALID_NUMBER_BINARY); + } + + parser->integer_base = PM_INTEGER_BASE_FLAGS_BINARY; + break; + + // 0o1111 is an octal number + case 'o': + case 'O': + parser->current.end++; + if (pm_char_is_octal_digit(peek(parser))) { + parser->current.end += pm_strspn_octal_number_validate(parser, parser->current.end); + } else { + match(parser, '_'); + pm_parser_err_current(parser, PM_ERR_INVALID_NUMBER_OCTAL); + } + + parser->integer_base = PM_INTEGER_BASE_FLAGS_OCTAL; + break; + + // 01111 is an octal number + case '_': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + parser->current.end += pm_strspn_octal_number_validate(parser, parser->current.end); + parser->integer_base = PM_INTEGER_BASE_FLAGS_OCTAL; + break; + + // 0x1111 is a hexadecimal number + case 'x': + case 'X': + parser->current.end++; + if (pm_char_is_hexadecimal_digit(peek(parser))) { + parser->current.end += pm_strspn_hexadecimal_number_validate(parser, parser->current.end); + } else { + match(parser, '_'); + pm_parser_err_current(parser, PM_ERR_INVALID_NUMBER_HEXADECIMAL); + } + + parser->integer_base = PM_INTEGER_BASE_FLAGS_HEXADECIMAL; + break; + + // 0.xxx is a float + case '.': { + type = lex_optional_float_suffix(parser, seen_e); + break; + } + + // 0exxx is a float + case 'e': + case 'E': { + type = lex_optional_float_suffix(parser, seen_e); + break; + } + } + } else { + // If it didn't start with a 0, then we'll lex as far as we can into a + // decimal number. + parser->current.end += pm_strspn_decimal_number_validate(parser, parser->current.end); + + // Afterward, we'll lex as far as we can into an optional float suffix. + type = lex_optional_float_suffix(parser, seen_e); + } + + // At this point we have a completed number, but we want to provide the user + // with a good experience if they put an additional .xxx fractional + // component on the end, so we'll check for that here. + if (peek_offset(parser, 0) == '.' && pm_char_is_decimal_digit(peek_offset(parser, 1))) { + const uint8_t *fraction_start = parser->current.end; + const uint8_t *fraction_end = parser->current.end + 2; + fraction_end += pm_strspn_decimal_digit(fraction_end, parser->end - fraction_end); + pm_parser_err(parser, fraction_start, fraction_end, PM_ERR_INVALID_NUMBER_FRACTION); + } + + return type; +} + +static pm_token_type_t +lex_numeric(pm_parser_t *parser) { + pm_token_type_t type = PM_TOKEN_INTEGER; + parser->integer_base = PM_INTEGER_BASE_FLAGS_DECIMAL; + + if (parser->current.end < parser->end) { + bool seen_e = false; + type = lex_numeric_prefix(parser, &seen_e); + + const uint8_t *end = parser->current.end; + pm_token_type_t suffix_type = type; + + if (type == PM_TOKEN_INTEGER) { + if (match(parser, 'r')) { + suffix_type = PM_TOKEN_INTEGER_RATIONAL; + + if (match(parser, 'i')) { + suffix_type = PM_TOKEN_INTEGER_RATIONAL_IMAGINARY; + } + } else if (match(parser, 'i')) { + suffix_type = PM_TOKEN_INTEGER_IMAGINARY; + } + } else { + if (!seen_e && match(parser, 'r')) { + suffix_type = PM_TOKEN_FLOAT_RATIONAL; + + if (match(parser, 'i')) { + suffix_type = PM_TOKEN_FLOAT_RATIONAL_IMAGINARY; + } + } else if (match(parser, 'i')) { + suffix_type = PM_TOKEN_FLOAT_IMAGINARY; + } + } + + const uint8_t b = peek(parser); + if (b != '\0' && (b >= 0x80 || ((b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z')) || b == '_')) { + parser->current.end = end; + } else { + type = suffix_type; + } + } + + return type; +} + +static pm_token_type_t +lex_global_variable(pm_parser_t *parser) { + if (parser->current.end >= parser->end) { + pm_parser_err_token(parser, &parser->current, PM_ERR_GLOBAL_VARIABLE_BARE); + return PM_TOKEN_GLOBAL_VARIABLE; + } + + // True if multiple characters are allowed after the declaration of the + // global variable. Not true when it starts with "$-". + bool allow_multiple = true; + + switch (*parser->current.end) { + case '~': // $~: match-data + case '*': // $*: argv + case '$': // $$: pid + case '?': // $?: last status + case '!': // $!: error string + case '@': // $@: error position + case '/': // $/: input record separator + case '\\': // $\: output record separator + case ';': // $;: field separator + case ',': // $,: output field separator + case '.': // $.: last read line number + case '=': // $=: ignorecase + case ':': // $:: load path + case '<': // $<: reading filename + case '>': // $>: default output handle + case '\"': // $": already loaded files + parser->current.end++; + return PM_TOKEN_GLOBAL_VARIABLE; + + case '&': // $&: last match + case '`': // $`: string before last match + case '\'': // $': string after last match + case '+': // $+: string matches last paren. + parser->current.end++; + return lex_state_p(parser, PM_LEX_STATE_FNAME) ? PM_TOKEN_GLOBAL_VARIABLE : PM_TOKEN_BACK_REFERENCE; + + case '0': { + parser->current.end++; + size_t width; + + if ((width = char_is_identifier(parser, parser->current.end, parser->end - parser->current.end)) > 0) { + do { + parser->current.end += width; + } while ((width = char_is_identifier(parser, parser->current.end, parser->end - parser->current.end)) > 0); + + // $0 isn't allowed to be followed by anything. + pm_diagnostic_id_t diag_id = parser->version == PM_OPTIONS_VERSION_CRUBY_3_3 ? PM_ERR_INVALID_VARIABLE_GLOBAL_3_3 : PM_ERR_INVALID_VARIABLE_GLOBAL; + PM_PARSER_ERR_TOKEN_FORMAT_CONTENT(parser, parser->current, diag_id); + } + + return PM_TOKEN_GLOBAL_VARIABLE; + } + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + parser->current.end += pm_strspn_decimal_digit(parser->current.end, parser->end - parser->current.end); + return lex_state_p(parser, PM_LEX_STATE_FNAME) ? PM_TOKEN_GLOBAL_VARIABLE : PM_TOKEN_NUMBERED_REFERENCE; + + case '-': + parser->current.end++; + allow_multiple = false; + PRISM_FALLTHROUGH + default: { + size_t width; + + if ((width = char_is_identifier(parser, parser->current.end, parser->end - parser->current.end)) > 0) { + do { + parser->current.end += width; + } while (allow_multiple && (width = char_is_identifier(parser, parser->current.end, parser->end - parser->current.end)) > 0); + } else if (pm_char_is_whitespace(peek(parser))) { + // If we get here, then we have a $ followed by whitespace, + // which is not allowed. + pm_parser_err_token(parser, &parser->current, PM_ERR_GLOBAL_VARIABLE_BARE); + } else { + // If we get here, then we have a $ followed by something that + // isn't recognized as a global variable. + pm_diagnostic_id_t diag_id = parser->version == PM_OPTIONS_VERSION_CRUBY_3_3 ? PM_ERR_INVALID_VARIABLE_GLOBAL_3_3 : PM_ERR_INVALID_VARIABLE_GLOBAL; + const uint8_t *end = parser->current.end + parser->encoding->char_width(parser->current.end, parser->end - parser->current.end); + PM_PARSER_ERR_FORMAT(parser, parser->current.start, end, diag_id, (int) (end - parser->current.start), (const char *) parser->current.start); + } + + return PM_TOKEN_GLOBAL_VARIABLE; + } + } +} + +/** + * This function checks if the current token matches a keyword. If it does, it + * returns the token type. Otherwise, it returns PM_TOKEN_EOF. The arguments are as follows: + * + * * `parser` - the parser object + * * `current_start` - pointer to the start of the current token + * * `value` - the literal string that we're checking for + * * `vlen` - the length of the token + * * `state` - the state that we should transition to if the token matches + * * `type` - the expected token type + * * `modifier_type` - the expected modifier token type + */ +static inline pm_token_type_t +lex_keyword(pm_parser_t *parser, const uint8_t *current_start, const char *value, size_t vlen, pm_lex_state_t state, pm_token_type_t type, pm_token_type_t modifier_type) { + if (memcmp(current_start, value, vlen) == 0) { + pm_lex_state_t last_state = parser->lex_state; + + if (parser->lex_state & PM_LEX_STATE_FNAME) { + lex_state_set(parser, PM_LEX_STATE_ENDFN); + } else { + lex_state_set(parser, state); + if (state == PM_LEX_STATE_BEG) { + parser->command_start = true; + } + + if ((modifier_type != PM_TOKEN_EOF) && !(last_state & (PM_LEX_STATE_BEG | PM_LEX_STATE_LABELED | PM_LEX_STATE_CLASS))) { + lex_state_set(parser, PM_LEX_STATE_BEG | PM_LEX_STATE_LABEL); + return modifier_type; + } + } + + return type; + } + + return PM_TOKEN_EOF; +} + +static pm_token_type_t +lex_identifier(pm_parser_t *parser, bool previous_command_start) { + // Lex as far as we can into the current identifier. + size_t width; + const uint8_t *end = parser->end; + const uint8_t *current_start = parser->current.start; + const uint8_t *current_end = parser->current.end; + bool encoding_changed = parser->encoding_changed; + + if (encoding_changed) { + while ((width = char_is_identifier(parser, current_end, end - current_end)) > 0) { + current_end += width; + } + } else { + while ((width = char_is_identifier_utf8(current_end, end - current_end)) > 0) { + current_end += width; + } + } + parser->current.end = current_end; + + // Now cache the length of the identifier so that we can quickly compare it + // against known keywords. + width = (size_t) (current_end - current_start); + + if (current_end < end) { + if (((current_end + 1 >= end) || (current_end[1] != '=')) && (match(parser, '!') || match(parser, '?'))) { + // First we'll attempt to extend the identifier by a ! or ?. Then we'll + // check if we're returning the defined? keyword or just an identifier. + width++; + + if ( + ((lex_state_p(parser, PM_LEX_STATE_LABEL | PM_LEX_STATE_ENDFN) && !previous_command_start) || lex_state_arg_p(parser)) && + (peek(parser) == ':') && (peek_offset(parser, 1) != ':') + ) { + // If we're in a position where we can accept a : at the end of an + // identifier, then we'll optionally accept it. + lex_state_set(parser, PM_LEX_STATE_ARG | PM_LEX_STATE_LABELED); + (void) match(parser, ':'); + return PM_TOKEN_LABEL; + } + + if (parser->lex_state != PM_LEX_STATE_DOT) { + if (width == 8 && (lex_keyword(parser, current_start, "defined?", width, PM_LEX_STATE_ARG, PM_TOKEN_KEYWORD_DEFINED, PM_TOKEN_EOF) != PM_TOKEN_EOF)) { + return PM_TOKEN_KEYWORD_DEFINED; + } + } + + return PM_TOKEN_METHOD_NAME; + } + + if (lex_state_p(parser, PM_LEX_STATE_FNAME) && peek_offset(parser, 1) != '~' && peek_offset(parser, 1) != '>' && (peek_offset(parser, 1) != '=' || peek_offset(parser, 2) == '>') && match(parser, '=')) { + // If we're in a position where we can accept a = at the end of an + // identifier, then we'll optionally accept it. + return PM_TOKEN_IDENTIFIER; + } + + if ( + ((lex_state_p(parser, PM_LEX_STATE_LABEL | PM_LEX_STATE_ENDFN) && !previous_command_start) || lex_state_arg_p(parser)) && + peek(parser) == ':' && peek_offset(parser, 1) != ':' + ) { + // If we're in a position where we can accept a : at the end of an + // identifier, then we'll optionally accept it. + lex_state_set(parser, PM_LEX_STATE_ARG | PM_LEX_STATE_LABELED); + (void) match(parser, ':'); + return PM_TOKEN_LABEL; + } + } + + if (parser->lex_state != PM_LEX_STATE_DOT) { + pm_token_type_t type; + switch (width) { + case 2: + if (lex_keyword(parser, current_start, "do", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_DO, PM_TOKEN_EOF) != PM_TOKEN_EOF) { + if (pm_do_loop_stack_p(parser)) { + return PM_TOKEN_KEYWORD_DO_LOOP; + } + return PM_TOKEN_KEYWORD_DO; + } + + if ((type = lex_keyword(parser, current_start, "if", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_IF, PM_TOKEN_KEYWORD_IF_MODIFIER)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "in", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_IN, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "or", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_OR, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + break; + case 3: + if ((type = lex_keyword(parser, current_start, "and", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_AND, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "def", width, PM_LEX_STATE_FNAME, PM_TOKEN_KEYWORD_DEF, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "end", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_END, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "END", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_END_UPCASE, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "for", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_FOR, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "nil", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_NIL, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "not", width, PM_LEX_STATE_ARG, PM_TOKEN_KEYWORD_NOT, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + break; + case 4: + if ((type = lex_keyword(parser, current_start, "case", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_CASE, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "else", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "next", width, PM_LEX_STATE_MID, PM_TOKEN_KEYWORD_NEXT, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "redo", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_REDO, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "self", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_SELF, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "then", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_THEN, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "true", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_TRUE, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "when", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_WHEN, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + break; + case 5: + if ((type = lex_keyword(parser, current_start, "alias", width, PM_LEX_STATE_FNAME | PM_LEX_STATE_FITEM, PM_TOKEN_KEYWORD_ALIAS, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "begin", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_BEGIN, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "BEGIN", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_BEGIN_UPCASE, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "break", width, PM_LEX_STATE_MID, PM_TOKEN_KEYWORD_BREAK, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "class", width, PM_LEX_STATE_CLASS, PM_TOKEN_KEYWORD_CLASS, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "elsif", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_ELSIF, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "false", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_FALSE, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "retry", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD_RETRY, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "super", width, PM_LEX_STATE_ARG, PM_TOKEN_KEYWORD_SUPER, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "undef", width, PM_LEX_STATE_FNAME | PM_LEX_STATE_FITEM, PM_TOKEN_KEYWORD_UNDEF, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "until", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_UNTIL, PM_TOKEN_KEYWORD_UNTIL_MODIFIER)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "while", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_WHILE, PM_TOKEN_KEYWORD_WHILE_MODIFIER)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "yield", width, PM_LEX_STATE_ARG, PM_TOKEN_KEYWORD_YIELD, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + break; + case 6: + if ((type = lex_keyword(parser, current_start, "ensure", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "module", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_MODULE, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "rescue", width, PM_LEX_STATE_MID, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_RESCUE_MODIFIER)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "return", width, PM_LEX_STATE_MID, PM_TOKEN_KEYWORD_RETURN, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "unless", width, PM_LEX_STATE_BEG, PM_TOKEN_KEYWORD_UNLESS, PM_TOKEN_KEYWORD_UNLESS_MODIFIER)) != PM_TOKEN_EOF) return type; + break; + case 8: + if ((type = lex_keyword(parser, current_start, "__LINE__", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD___LINE__, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + if ((type = lex_keyword(parser, current_start, "__FILE__", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD___FILE__, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + break; + case 12: + if ((type = lex_keyword(parser, current_start, "__ENCODING__", width, PM_LEX_STATE_END, PM_TOKEN_KEYWORD___ENCODING__, PM_TOKEN_EOF)) != PM_TOKEN_EOF) return type; + break; + } + } + + if (encoding_changed) { + return parser->encoding->isupper_char(current_start, end - current_start) ? PM_TOKEN_CONSTANT : PM_TOKEN_IDENTIFIER; + } + return pm_encoding_utf_8_isupper_char(current_start, end - current_start) ? PM_TOKEN_CONSTANT : PM_TOKEN_IDENTIFIER; +} + +/** + * Returns true if the current token that the parser is considering is at the + * beginning of a line or the beginning of the source. + */ +static bool +current_token_starts_line(pm_parser_t *parser) { + return (parser->current.start == parser->start) || (parser->current.start[-1] == '\n'); +} + +/** + * When we hit a # while lexing something like a string, we need to potentially + * handle interpolation. This function performs that check. It returns a token + * type representing what it found. Those cases are: + * + * * PM_TOKEN_NOT_PROVIDED - No interpolation was found at this point. The + * caller should keep lexing. + * * PM_TOKEN_STRING_CONTENT - No interpolation was found at this point. The + * caller should return this token type. + * * PM_TOKEN_EMBEXPR_BEGIN - An embedded expression was found. The caller + * should return this token type. + * * PM_TOKEN_EMBVAR - An embedded variable was found. The caller should return + * this token type. + */ +static pm_token_type_t +lex_interpolation(pm_parser_t *parser, const uint8_t *pound) { + // If there is no content following this #, then we're at the end of + // the string and we can safely return string content. + if (pound + 1 >= parser->end) { + parser->current.end = pound + 1; + return PM_TOKEN_STRING_CONTENT; + } + + // Now we'll check against the character that follows the #. If it constitutes + // valid interplation, we'll handle that, otherwise we'll return + // PM_TOKEN_NOT_PROVIDED. + switch (pound[1]) { + case '@': { + // In this case we may have hit an embedded instance or class variable. + if (pound + 2 >= parser->end) { + parser->current.end = pound + 1; + return PM_TOKEN_STRING_CONTENT; + } + + // If we're looking at a @ and there's another @, then we'll skip past the + // second @. + const uint8_t *variable = pound + 2; + if (*variable == '@' && pound + 3 < parser->end) variable++; + + if (char_is_identifier_start(parser, variable, parser->end - variable)) { + // At this point we're sure that we've either hit an embedded instance + // or class variable. In this case we'll first need to check if we've + // already consumed content. + if (pound > parser->current.start) { + parser->current.end = pound; + return PM_TOKEN_STRING_CONTENT; + } + + // Otherwise we need to return the embedded variable token + // and then switch to the embedded variable lex mode. + lex_mode_push(parser, (pm_lex_mode_t) { .mode = PM_LEX_EMBVAR }); + parser->current.end = pound + 1; + return PM_TOKEN_EMBVAR; + } + + // If we didn't get a valid interpolation, then this is just regular + // string content. This is like if we get "#@-". In this case the caller + // should keep lexing. + parser->current.end = pound + 1; + return PM_TOKEN_NOT_PROVIDED; + } + case '$': + // In this case we may have hit an embedded global variable. If there's + // not enough room, then we'll just return string content. + if (pound + 2 >= parser->end) { + parser->current.end = pound + 1; + return PM_TOKEN_STRING_CONTENT; + } + + // This is the character that we're going to check to see if it is the + // start of an identifier that would indicate that this is a global + // variable. + const uint8_t *check = pound + 2; + + if (pound[2] == '-') { + if (pound + 3 >= parser->end) { + parser->current.end = pound + 2; + return PM_TOKEN_STRING_CONTENT; + } + + check++; + } + + // If the character that we're going to check is the start of an + // identifier, or we don't have a - and the character is a decimal number + // or a global name punctuation character, then we've hit an embedded + // global variable. + if ( + char_is_identifier_start(parser, check, parser->end - check) || + (pound[2] != '-' && (pm_char_is_decimal_digit(pound[2]) || char_is_global_name_punctuation(pound[2]))) + ) { + // In this case we've hit an embedded global variable. First check to + // see if we've already consumed content. If we have, then we need to + // return that content as string content first. + if (pound > parser->current.start) { + parser->current.end = pound; + return PM_TOKEN_STRING_CONTENT; + } + + // Otherwise, we need to return the embedded variable token and switch + // to the embedded variable lex mode. + lex_mode_push(parser, (pm_lex_mode_t) { .mode = PM_LEX_EMBVAR }); + parser->current.end = pound + 1; + return PM_TOKEN_EMBVAR; + } + + // In this case we've hit a #$ that does not indicate a global variable. + // In this case we'll continue lexing past it. + parser->current.end = pound + 1; + return PM_TOKEN_NOT_PROVIDED; + case '{': + // In this case it's the start of an embedded expression. If we have + // already consumed content, then we need to return that content as string + // content first. + if (pound > parser->current.start) { + parser->current.end = pound; + return PM_TOKEN_STRING_CONTENT; + } + + parser->enclosure_nesting++; + + // Otherwise we'll skip past the #{ and begin lexing the embedded + // expression. + lex_mode_push(parser, (pm_lex_mode_t) { .mode = PM_LEX_EMBEXPR }); + parser->current.end = pound + 2; + parser->command_start = true; + pm_do_loop_stack_push(parser, false); + return PM_TOKEN_EMBEXPR_BEGIN; + default: + // In this case we've hit a # that doesn't constitute interpolation. We'll + // mark that by returning the not provided token type. This tells the + // consumer to keep lexing forward. + parser->current.end = pound + 1; + return PM_TOKEN_NOT_PROVIDED; + } +} + +static const uint8_t PM_ESCAPE_FLAG_NONE = 0x0; +static const uint8_t PM_ESCAPE_FLAG_CONTROL = 0x1; +static const uint8_t PM_ESCAPE_FLAG_META = 0x2; +static const uint8_t PM_ESCAPE_FLAG_SINGLE = 0x4; +static const uint8_t PM_ESCAPE_FLAG_REGEXP = 0x8; + +/** + * This is a lookup table for whether or not an ASCII character is printable. + */ +static const bool ascii_printable_chars[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 +}; + +static inline bool +char_is_ascii_printable(const uint8_t b) { + return (b < 0x80) && ascii_printable_chars[b]; +} + +/** + * Return the value that a hexadecimal digit character represents. For example, + * transform 'a' into 10, 'b' into 11, etc. + */ +static inline uint8_t +escape_hexadecimal_digit(const uint8_t value) { + return (uint8_t) ((value <= '9') ? (value - '0') : (value & 0x7) + 9); +} + +/** + * Scan the 4 digits of a Unicode escape into the value. Returns the number of + * digits scanned. This function assumes that the characters have already been + * validated. + */ +static inline uint32_t +escape_unicode(pm_parser_t *parser, const uint8_t *string, size_t length) { + uint32_t value = 0; + for (size_t index = 0; index < length; index++) { + if (index != 0) value <<= 4; + value |= escape_hexadecimal_digit(string[index]); + } + + // Here we're going to verify that the value is actually a valid Unicode + // codepoint and not a surrogate pair. + if (value >= 0xD800 && value <= 0xDFFF) { + pm_parser_err(parser, string, string + length, PM_ERR_ESCAPE_INVALID_UNICODE); + return 0xFFFD; + } + + return value; +} + +/** + * Escape a single character value based on the given flags. + */ +static inline uint8_t +escape_byte(uint8_t value, const uint8_t flags) { + if (flags & PM_ESCAPE_FLAG_CONTROL) value &= 0x9f; + if (flags & PM_ESCAPE_FLAG_META) value |= 0x80; + return value; +} + +/** + * Write a unicode codepoint to the given buffer. + */ +static inline void +escape_write_unicode(pm_parser_t *parser, pm_buffer_t *buffer, const uint8_t flags, const uint8_t *start, const uint8_t *end, uint32_t value) { + // \u escape sequences in string-like structures implicitly change the + // encoding to UTF-8 if they are >= 0x80 or if they are used in a character + // literal. + if (value >= 0x80 || flags & PM_ESCAPE_FLAG_SINGLE) { + if (parser->explicit_encoding != NULL && parser->explicit_encoding != PM_ENCODING_UTF_8_ENTRY) { + PM_PARSER_ERR_FORMAT(parser, start, end, PM_ERR_MIXED_ENCODING, parser->explicit_encoding->name); + } + + parser->explicit_encoding = PM_ENCODING_UTF_8_ENTRY; + } + + if (!pm_buffer_append_unicode_codepoint(buffer, value)) { + pm_parser_err(parser, start, end, PM_ERR_ESCAPE_INVALID_UNICODE); + pm_buffer_append_byte(buffer, 0xEF); + pm_buffer_append_byte(buffer, 0xBF); + pm_buffer_append_byte(buffer, 0xBD); + } +} + +/** + * When you're writing a byte to the unescape buffer, if the byte is non-ASCII + * (i.e., the top bit is set) then it locks in the encoding. + */ +static inline void +escape_write_byte_encoded(pm_parser_t *parser, pm_buffer_t *buffer, uint8_t byte) { + if (byte >= 0x80) { + if (parser->explicit_encoding != NULL && parser->explicit_encoding == PM_ENCODING_UTF_8_ENTRY && parser->encoding != PM_ENCODING_UTF_8_ENTRY) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_MIXED_ENCODING, parser->encoding->name); + } + + parser->explicit_encoding = parser->encoding; + } + + pm_buffer_append_byte(buffer, byte); +} + +/** + * The regular expression engine doesn't support the same escape sequences as + * Ruby does. So first we have to read the escape sequence, and then we have to + * format it like the regular expression engine expects it. For example, in Ruby + * if we have: + * + * /\M-\C-?/ + * + * then the first byte is actually 255, so we have to rewrite this as: + * + * /\xFF/ + * + * Note that in this case there is a literal \ byte in the regular expression + * source so that the regular expression engine will perform its own unescaping. + */ +static inline void +escape_write_byte(pm_parser_t *parser, pm_buffer_t *buffer, pm_buffer_t *regular_expression_buffer, uint8_t flags, uint8_t byte) { + if (flags & PM_ESCAPE_FLAG_REGEXP) { + pm_buffer_append_format(regular_expression_buffer, "\\x%02X", byte); + } + + escape_write_byte_encoded(parser, buffer, byte); +} + +/** + * Write each byte of the given escaped character into the buffer. + */ +static inline void +escape_write_escape_encoded(pm_parser_t *parser, pm_buffer_t *buffer, pm_buffer_t *regular_expression_buffer, uint8_t flags) { + size_t width; + if (parser->encoding_changed) { + width = parser->encoding->char_width(parser->current.end, parser->end - parser->current.end); + } else { + width = pm_encoding_utf_8_char_width(parser->current.end, parser->end - parser->current.end); + } + + if (width == 1) { + escape_write_byte(parser, buffer, regular_expression_buffer, flags, escape_byte(*parser->current.end++, flags)); + } else if (width > 1) { + // Valid multibyte character. Just ignore escape. + pm_buffer_t *b = (flags & PM_ESCAPE_FLAG_REGEXP) ? regular_expression_buffer : buffer; + pm_buffer_append_bytes(b, parser->current.end, width); + parser->current.end += width; + } else { + // Assume the next character wasn't meant to be part of this escape + // sequence since it is invalid. Add an error and move on. + parser->current.end++; + pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_CONTROL); + } +} + +/** + * Warn about using a space or a tab character in an escape, as opposed to using + * \\s or \\t. Note that we can quite copy the source because the warning + * message replaces \\c with \\C. + */ +static void +escape_read_warn(pm_parser_t *parser, uint8_t flags, uint8_t flag, const char *type) { +#define FLAG(value) ((value & PM_ESCAPE_FLAG_CONTROL) ? "\\C-" : (value & PM_ESCAPE_FLAG_META) ? "\\M-" : "") + + PM_PARSER_WARN_TOKEN_FORMAT( + parser, + parser->current, + PM_WARN_INVALID_CHARACTER, + FLAG(flags), + FLAG(flag), + type + ); + +#undef FLAG +} + +/** + * Read the value of an escape into the buffer. + */ +static void +escape_read(pm_parser_t *parser, pm_buffer_t *buffer, pm_buffer_t *regular_expression_buffer, uint8_t flags) { + uint8_t peeked = peek(parser); + switch (peeked) { + case '\\': { + parser->current.end++; + escape_write_byte(parser, buffer, regular_expression_buffer, flags, escape_byte('\\', flags)); + return; + } + case '\'': { + parser->current.end++; + escape_write_byte(parser, buffer, regular_expression_buffer, flags, escape_byte('\'', flags)); + return; + } + case 'a': { + parser->current.end++; + escape_write_byte(parser, buffer, regular_expression_buffer, flags, escape_byte('\a', flags)); + return; + } + case 'b': { + parser->current.end++; + escape_write_byte(parser, buffer, regular_expression_buffer, flags, escape_byte('\b', flags)); + return; + } + case 'e': { + parser->current.end++; + escape_write_byte(parser, buffer, regular_expression_buffer, flags, escape_byte('\033', flags)); + return; + } + case 'f': { + parser->current.end++; + escape_write_byte(parser, buffer, regular_expression_buffer, flags, escape_byte('\f', flags)); + return; + } + case 'n': { + parser->current.end++; + escape_write_byte(parser, buffer, regular_expression_buffer, flags, escape_byte('\n', flags)); + return; + } + case 'r': { + parser->current.end++; + escape_write_byte(parser, buffer, regular_expression_buffer, flags, escape_byte('\r', flags)); + return; + } + case 's': { + parser->current.end++; + escape_write_byte(parser, buffer, regular_expression_buffer, flags, escape_byte(' ', flags)); + return; + } + case 't': { + parser->current.end++; + escape_write_byte(parser, buffer, regular_expression_buffer, flags, escape_byte('\t', flags)); + return; + } + case 'v': { + parser->current.end++; + escape_write_byte(parser, buffer, regular_expression_buffer, flags, escape_byte('\v', flags)); + return; + } + case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': { + uint8_t value = (uint8_t) (*parser->current.end - '0'); + parser->current.end++; + + if (pm_char_is_octal_digit(peek(parser))) { + value = ((uint8_t) (value << 3)) | ((uint8_t) (*parser->current.end - '0')); + parser->current.end++; + + if (pm_char_is_octal_digit(peek(parser))) { + value = ((uint8_t) (value << 3)) | ((uint8_t) (*parser->current.end - '0')); + parser->current.end++; + } + } + + value = escape_byte(value, flags); + escape_write_byte(parser, buffer, regular_expression_buffer, flags, value); + return; + } + case 'x': { + const uint8_t *start = parser->current.end - 1; + + parser->current.end++; + uint8_t byte = peek(parser); + + if (pm_char_is_hexadecimal_digit(byte)) { + uint8_t value = escape_hexadecimal_digit(byte); + parser->current.end++; + + byte = peek(parser); + if (pm_char_is_hexadecimal_digit(byte)) { + value = (uint8_t) ((value << 4) | escape_hexadecimal_digit(byte)); + parser->current.end++; + } + + value = escape_byte(value, flags); + if (flags & PM_ESCAPE_FLAG_REGEXP) { + if (flags & (PM_ESCAPE_FLAG_CONTROL | PM_ESCAPE_FLAG_META)) { + pm_buffer_append_format(regular_expression_buffer, "\\x%02X", value); + } else { + pm_buffer_append_bytes(regular_expression_buffer, start, (size_t) (parser->current.end - start)); + } + } + + escape_write_byte_encoded(parser, buffer, value); + } else { + pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_HEXADECIMAL); + } + + return; + } + case 'u': { + const uint8_t *start = parser->current.end - 1; + parser->current.end++; + + if (parser->current.end == parser->end) { + const uint8_t *start = parser->current.end - 2; + PM_PARSER_ERR_FORMAT(parser, start, parser->current.end, PM_ERR_ESCAPE_INVALID_UNICODE_SHORT, 2, start); + } else if (peek(parser) == '{') { + const uint8_t *unicode_codepoints_start = parser->current.end - 2; + parser->current.end++; + + size_t whitespace; + while (true) { + if ((whitespace = pm_strspn_inline_whitespace(parser->current.end, parser->end - parser->current.end)) > 0) { + parser->current.end += whitespace; + } else if (peek(parser) == '\\' && peek_offset(parser, 1) == 'n') { + // This is super hacky, but it gets us nicer error + // messages because we can still pass it off to the + // regular expression engine even if we hit an + // unterminated regular expression. + parser->current.end += 2; + } else { + break; + } + } + + const uint8_t *extra_codepoints_start = NULL; + int codepoints_count = 0; + + while ((parser->current.end < parser->end) && (*parser->current.end != '}')) { + const uint8_t *unicode_start = parser->current.end; + size_t hexadecimal_length = pm_strspn_hexadecimal_digit(parser->current.end, parser->end - parser->current.end); + + if (hexadecimal_length > 6) { + // \u{nnnn} character literal allows only 1-6 hexadecimal digits + pm_parser_err(parser, unicode_start, unicode_start + hexadecimal_length, PM_ERR_ESCAPE_INVALID_UNICODE_LONG); + } else if (hexadecimal_length == 0) { + // there are not hexadecimal characters + + if (flags & PM_ESCAPE_FLAG_REGEXP) { + // If this is a regular expression, we are going to + // let the regular expression engine handle this + // error instead of us. + pm_buffer_append_bytes(regular_expression_buffer, start, (size_t) (parser->current.end - start)); + } else { + pm_parser_err(parser, parser->current.end, parser->current.end, PM_ERR_ESCAPE_INVALID_UNICODE); + pm_parser_err(parser, parser->current.end, parser->current.end, PM_ERR_ESCAPE_INVALID_UNICODE_TERM); + } + + return; + } + + parser->current.end += hexadecimal_length; + codepoints_count++; + if (flags & PM_ESCAPE_FLAG_SINGLE && codepoints_count == 2) { + extra_codepoints_start = unicode_start; + } + + uint32_t value = escape_unicode(parser, unicode_start, hexadecimal_length); + escape_write_unicode(parser, buffer, flags, unicode_start, parser->current.end, value); + + parser->current.end += pm_strspn_inline_whitespace(parser->current.end, parser->end - parser->current.end); + } + + // ?\u{nnnn} character literal should contain only one codepoint + // and cannot be like ?\u{nnnn mmmm}. + if (flags & PM_ESCAPE_FLAG_SINGLE && codepoints_count > 1) { + pm_parser_err(parser, extra_codepoints_start, parser->current.end - 1, PM_ERR_ESCAPE_INVALID_UNICODE_LITERAL); + } + + if (parser->current.end == parser->end) { + PM_PARSER_ERR_FORMAT(parser, start, parser->current.end, PM_ERR_ESCAPE_INVALID_UNICODE_LIST, (int) (parser->current.end - start), start); + } else if (peek(parser) == '}') { + parser->current.end++; + } else { + if (flags & PM_ESCAPE_FLAG_REGEXP) { + // If this is a regular expression, we are going to let + // the regular expression engine handle this error + // instead of us. + pm_buffer_append_bytes(regular_expression_buffer, start, (size_t) (parser->current.end - start)); + } else { + pm_parser_err(parser, unicode_codepoints_start, parser->current.end, PM_ERR_ESCAPE_INVALID_UNICODE_TERM); + } + } + + if (flags & PM_ESCAPE_FLAG_REGEXP) { + pm_buffer_append_bytes(regular_expression_buffer, unicode_codepoints_start, (size_t) (parser->current.end - unicode_codepoints_start)); + } + } else { + size_t length = pm_strspn_hexadecimal_digit(parser->current.end, MIN(parser->end - parser->current.end, 4)); + + if (length == 0) { + if (flags & PM_ESCAPE_FLAG_REGEXP) { + pm_buffer_append_bytes(regular_expression_buffer, start, (size_t) (parser->current.end - start)); + } else { + const uint8_t *start = parser->current.end - 2; + PM_PARSER_ERR_FORMAT(parser, start, parser->current.end, PM_ERR_ESCAPE_INVALID_UNICODE_SHORT, 2, start); + } + } else if (length == 4) { + uint32_t value = escape_unicode(parser, parser->current.end, 4); + + if (flags & PM_ESCAPE_FLAG_REGEXP) { + pm_buffer_append_bytes(regular_expression_buffer, start, (size_t) (parser->current.end + 4 - start)); + } + + escape_write_unicode(parser, buffer, flags, start, parser->current.end + 4, value); + parser->current.end += 4; + } else { + parser->current.end += length; + + if (flags & PM_ESCAPE_FLAG_REGEXP) { + // If this is a regular expression, we are going to let + // the regular expression engine handle this error + // instead of us. + pm_buffer_append_bytes(regular_expression_buffer, start, (size_t) (parser->current.end - start)); + } else { + pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_UNICODE); + } + } + } + + return; + } + case 'c': { + parser->current.end++; + if (flags & PM_ESCAPE_FLAG_CONTROL) { + pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_CONTROL_REPEAT); + } + + if (parser->current.end == parser->end) { + pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_CONTROL); + return; + } + + uint8_t peeked = peek(parser); + switch (peeked) { + case '?': { + parser->current.end++; + escape_write_byte(parser, buffer, regular_expression_buffer, flags, escape_byte(0x7f, flags)); + return; + } + case '\\': + parser->current.end++; + + if (match(parser, 'u') || match(parser, 'U')) { + pm_parser_err(parser, parser->current.start, parser->current.end, PM_ERR_INVALID_ESCAPE_CHARACTER); + return; + } + + escape_read(parser, buffer, regular_expression_buffer, flags | PM_ESCAPE_FLAG_CONTROL); + return; + case ' ': + parser->current.end++; + escape_read_warn(parser, flags, PM_ESCAPE_FLAG_CONTROL, "\\s"); + escape_write_byte(parser, buffer, regular_expression_buffer, flags, escape_byte(peeked, flags | PM_ESCAPE_FLAG_CONTROL)); + return; + case '\t': + parser->current.end++; + escape_read_warn(parser, flags, 0, "\\t"); + escape_write_byte(parser, buffer, regular_expression_buffer, flags, escape_byte(peeked, flags | PM_ESCAPE_FLAG_CONTROL)); + return; + default: { + if (!char_is_ascii_printable(peeked)) { + pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_CONTROL); + return; + } + + parser->current.end++; + escape_write_byte(parser, buffer, regular_expression_buffer, flags, escape_byte(peeked, flags | PM_ESCAPE_FLAG_CONTROL)); + return; + } + } + } + case 'C': { + parser->current.end++; + if (flags & PM_ESCAPE_FLAG_CONTROL) { + pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_CONTROL_REPEAT); + } + + if (peek(parser) != '-') { + size_t width = parser->encoding->char_width(parser->current.end, parser->end - parser->current.end); + pm_parser_err(parser, parser->current.start, parser->current.end + width, PM_ERR_ESCAPE_INVALID_CONTROL); + return; + } + + parser->current.end++; + if (parser->current.end == parser->end) { + pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_CONTROL); + return; + } + + uint8_t peeked = peek(parser); + switch (peeked) { + case '?': { + parser->current.end++; + escape_write_byte(parser, buffer, regular_expression_buffer, flags, escape_byte(0x7f, flags)); + return; + } + case '\\': + parser->current.end++; + + if (match(parser, 'u') || match(parser, 'U')) { + pm_parser_err(parser, parser->current.start, parser->current.end, PM_ERR_INVALID_ESCAPE_CHARACTER); + return; + } + + escape_read(parser, buffer, regular_expression_buffer, flags | PM_ESCAPE_FLAG_CONTROL); + return; + case ' ': + parser->current.end++; + escape_read_warn(parser, flags, PM_ESCAPE_FLAG_CONTROL, "\\s"); + escape_write_byte(parser, buffer, regular_expression_buffer, flags, escape_byte(peeked, flags | PM_ESCAPE_FLAG_CONTROL)); + return; + case '\t': + parser->current.end++; + escape_read_warn(parser, flags, 0, "\\t"); + escape_write_byte(parser, buffer, regular_expression_buffer, flags, escape_byte(peeked, flags | PM_ESCAPE_FLAG_CONTROL)); + return; + default: { + if (!char_is_ascii_printable(peeked)) { + size_t width = parser->encoding->char_width(parser->current.end, parser->end - parser->current.end); + pm_parser_err(parser, parser->current.start, parser->current.end + width, PM_ERR_ESCAPE_INVALID_CONTROL); + return; + } + + parser->current.end++; + escape_write_byte(parser, buffer, regular_expression_buffer, flags, escape_byte(peeked, flags | PM_ESCAPE_FLAG_CONTROL)); + return; + } + } + } + case 'M': { + parser->current.end++; + if (flags & PM_ESCAPE_FLAG_META) { + pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_META_REPEAT); + } + + if (peek(parser) != '-') { + size_t width = parser->encoding->char_width(parser->current.end, parser->end - parser->current.end); + pm_parser_err(parser, parser->current.start, parser->current.end + width, PM_ERR_ESCAPE_INVALID_META); + return; + } + + parser->current.end++; + if (parser->current.end == parser->end) { + pm_parser_err_current(parser, PM_ERR_ESCAPE_INVALID_META); + return; + } + + uint8_t peeked = peek(parser); + switch (peeked) { + case '\\': + parser->current.end++; + + if (match(parser, 'u') || match(parser, 'U')) { + pm_parser_err(parser, parser->current.start, parser->current.end, PM_ERR_INVALID_ESCAPE_CHARACTER); + return; + } + + escape_read(parser, buffer, regular_expression_buffer, flags | PM_ESCAPE_FLAG_META); + return; + case ' ': + parser->current.end++; + escape_read_warn(parser, flags, PM_ESCAPE_FLAG_META, "\\s"); + escape_write_byte(parser, buffer, regular_expression_buffer, flags, escape_byte(peeked, flags | PM_ESCAPE_FLAG_META)); + return; + case '\t': + parser->current.end++; + escape_read_warn(parser, flags & ((uint8_t) ~PM_ESCAPE_FLAG_CONTROL), PM_ESCAPE_FLAG_META, "\\t"); + escape_write_byte(parser, buffer, regular_expression_buffer, flags, escape_byte(peeked, flags | PM_ESCAPE_FLAG_META)); + return; + default: + if (!char_is_ascii_printable(peeked)) { + size_t width = parser->encoding->char_width(parser->current.end, parser->end - parser->current.end); + pm_parser_err(parser, parser->current.start, parser->current.end + width, PM_ERR_ESCAPE_INVALID_META); + return; + } + + parser->current.end++; + escape_write_byte(parser, buffer, regular_expression_buffer, flags, escape_byte(peeked, flags | PM_ESCAPE_FLAG_META)); + return; + } + } + case '\r': { + if (peek_offset(parser, 1) == '\n') { + parser->current.end += 2; + escape_write_byte_encoded(parser, buffer, escape_byte('\n', flags)); + return; + } + PRISM_FALLTHROUGH + } + default: { + if ((flags & (PM_ESCAPE_FLAG_CONTROL | PM_ESCAPE_FLAG_META)) && !char_is_ascii_printable(peeked)) { + size_t width = parser->encoding->char_width(parser->current.end, parser->end - parser->current.end); + pm_parser_err(parser, parser->current.start, parser->current.end + width, PM_ERR_ESCAPE_INVALID_META); + return; + } + if (parser->current.end < parser->end) { + escape_write_escape_encoded(parser, buffer, regular_expression_buffer, flags); + } else { + pm_parser_err_current(parser, PM_ERR_INVALID_ESCAPE_CHARACTER); + } + return; + } + } +} + +/** + * This function is responsible for lexing either a character literal or the ? + * operator. The supported character literals are described below. + * + * \\a bell, ASCII 07h (BEL) + * \\b backspace, ASCII 08h (BS) + * \t horizontal tab, ASCII 09h (TAB) + * \\n newline (line feed), ASCII 0Ah (LF) + * \v vertical tab, ASCII 0Bh (VT) + * \f form feed, ASCII 0Ch (FF) + * \r carriage return, ASCII 0Dh (CR) + * \\e escape, ASCII 1Bh (ESC) + * \s space, ASCII 20h (SPC) + * \\ backslash + * \nnn octal bit pattern, where nnn is 1-3 octal digits ([0-7]) + * \xnn hexadecimal bit pattern, where nn is 1-2 hexadecimal digits ([0-9a-fA-F]) + * \unnnn Unicode character, where nnnn is exactly 4 hexadecimal digits ([0-9a-fA-F]) + * \u{nnnn ...} Unicode character(s), where each nnnn is 1-6 hexadecimal digits ([0-9a-fA-F]) + * \cx or \C-x control character, where x is an ASCII printable character + * \M-x meta character, where x is an ASCII printable character + * \M-\C-x meta control character, where x is an ASCII printable character + * \M-\cx same as above + * \\c\M-x same as above + * \\c? or \C-? delete, ASCII 7Fh (DEL) + */ +static pm_token_type_t +lex_question_mark(pm_parser_t *parser) { + if (lex_state_end_p(parser)) { + lex_state_set(parser, PM_LEX_STATE_BEG); + return PM_TOKEN_QUESTION_MARK; + } + + if (parser->current.end >= parser->end) { + pm_parser_err_current(parser, PM_ERR_INCOMPLETE_QUESTION_MARK); + pm_string_shared_init(&parser->current_string, parser->current.start + 1, parser->current.end); + return PM_TOKEN_CHARACTER_LITERAL; + } + + if (pm_char_is_whitespace(*parser->current.end)) { + lex_state_set(parser, PM_LEX_STATE_BEG); + return PM_TOKEN_QUESTION_MARK; + } + + lex_state_set(parser, PM_LEX_STATE_BEG); + + if (match(parser, '\\')) { + lex_state_set(parser, PM_LEX_STATE_END); + + pm_buffer_t buffer; + pm_buffer_init_capacity(&buffer, 3); + + escape_read(parser, &buffer, NULL, PM_ESCAPE_FLAG_SINGLE); + pm_string_owned_init(&parser->current_string, (uint8_t *) buffer.value, buffer.length); + + return PM_TOKEN_CHARACTER_LITERAL; + } else { + size_t encoding_width = parser->encoding->char_width(parser->current.end, parser->end - parser->current.end); + + // Ternary operators can have a ? immediately followed by an identifier + // which starts with an underscore. We check for this case here. + if ( + !(parser->encoding->alnum_char(parser->current.end, parser->end - parser->current.end) || peek(parser) == '_') || + ( + (parser->current.end + encoding_width >= parser->end) || + !char_is_identifier(parser, parser->current.end + encoding_width, parser->end - (parser->current.end + encoding_width)) + ) + ) { + lex_state_set(parser, PM_LEX_STATE_END); + parser->current.end += encoding_width; + pm_string_shared_init(&parser->current_string, parser->current.start + 1, parser->current.end); + return PM_TOKEN_CHARACTER_LITERAL; + } + } + + return PM_TOKEN_QUESTION_MARK; +} + +/** + * Lex a variable that starts with an @ sign (either an instance or class + * variable). + */ +static pm_token_type_t +lex_at_variable(pm_parser_t *parser) { + pm_token_type_t type = match(parser, '@') ? PM_TOKEN_CLASS_VARIABLE : PM_TOKEN_INSTANCE_VARIABLE; + const uint8_t *end = parser->end; + + size_t width; + if ((width = char_is_identifier_start(parser, parser->current.end, end - parser->current.end)) > 0) { + parser->current.end += width; + + while ((width = char_is_identifier(parser, parser->current.end, end - parser->current.end)) > 0) { + parser->current.end += width; + } + } else if (parser->current.end < end && pm_char_is_decimal_digit(*parser->current.end)) { + pm_diagnostic_id_t diag_id = (type == PM_TOKEN_CLASS_VARIABLE) ? PM_ERR_INCOMPLETE_VARIABLE_CLASS : PM_ERR_INCOMPLETE_VARIABLE_INSTANCE; + if (parser->version == PM_OPTIONS_VERSION_CRUBY_3_3) { + diag_id = (type == PM_TOKEN_CLASS_VARIABLE) ? PM_ERR_INCOMPLETE_VARIABLE_CLASS_3_3 : PM_ERR_INCOMPLETE_VARIABLE_INSTANCE_3_3; + } + + size_t width = parser->encoding->char_width(parser->current.end, end - parser->current.end); + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, diag_id, (int) ((parser->current.end + width) - parser->current.start), (const char *) parser->current.start); + } else { + pm_diagnostic_id_t diag_id = (type == PM_TOKEN_CLASS_VARIABLE) ? PM_ERR_CLASS_VARIABLE_BARE : PM_ERR_INSTANCE_VARIABLE_BARE; + pm_parser_err_token(parser, &parser->current, diag_id); + } + + // If we're lexing an embedded variable, then we need to pop back into the + // parent lex context. + if (parser->lex_modes.current->mode == PM_LEX_EMBVAR) { + lex_mode_pop(parser); + } + + return type; +} + +/** + * Optionally call out to the lex callback if one is provided. + */ +static inline void +parser_lex_callback(pm_parser_t *parser) { + if (parser->lex_callback) { + parser->lex_callback->callback(parser->lex_callback->data, parser, &parser->current); + } +} + +/** + * Return a new comment node of the specified type. + */ +static inline pm_comment_t * +parser_comment(pm_parser_t *parser, pm_comment_type_t type) { + pm_comment_t *comment = (pm_comment_t *) xcalloc(1, sizeof(pm_comment_t)); + if (comment == NULL) return NULL; + + *comment = (pm_comment_t) { + .type = type, + .location = { parser->current.start, parser->current.end } + }; + + return comment; +} + +/** + * Lex out embedded documentation, and return when we have either hit the end of + * the file or the end of the embedded documentation. This calls the callback + * manually because only the lexer should see these tokens, not the parser. + */ +static pm_token_type_t +lex_embdoc(pm_parser_t *parser) { + // First, lex out the EMBDOC_BEGIN token. + const uint8_t *newline = next_newline(parser->current.end, parser->end - parser->current.end); + + if (newline == NULL) { + parser->current.end = parser->end; + } else { + pm_newline_list_append(&parser->newline_list, newline); + parser->current.end = newline + 1; + } + + parser->current.type = PM_TOKEN_EMBDOC_BEGIN; + parser_lex_callback(parser); + + // Now, create a comment that is going to be attached to the parser. + pm_comment_t *comment = parser_comment(parser, PM_COMMENT_EMBDOC); + if (comment == NULL) return PM_TOKEN_EOF; + + // Now, loop until we find the end of the embedded documentation or the end + // of the file. + while (parser->current.end + 4 <= parser->end) { + parser->current.start = parser->current.end; + + // If we've hit the end of the embedded documentation then we'll return + // that token here. + if ( + (memcmp(parser->current.end, "=end", 4) == 0) && + ( + (parser->current.end + 4 == parser->end) || // end of file + pm_char_is_whitespace(parser->current.end[4]) || // whitespace + (parser->current.end[4] == '\0') || // NUL or end of script + (parser->current.end[4] == '\004') || // ^D + (parser->current.end[4] == '\032') // ^Z + ) + ) { + const uint8_t *newline = next_newline(parser->current.end, parser->end - parser->current.end); + + if (newline == NULL) { + parser->current.end = parser->end; + } else { + pm_newline_list_append(&parser->newline_list, newline); + parser->current.end = newline + 1; + } + + parser->current.type = PM_TOKEN_EMBDOC_END; + parser_lex_callback(parser); + + comment->location.end = parser->current.end; + pm_list_append(&parser->comment_list, (pm_list_node_t *) comment); + + return PM_TOKEN_EMBDOC_END; + } + + // Otherwise, we'll parse until the end of the line and return a line of + // embedded documentation. + const uint8_t *newline = next_newline(parser->current.end, parser->end - parser->current.end); + + if (newline == NULL) { + parser->current.end = parser->end; + } else { + pm_newline_list_append(&parser->newline_list, newline); + parser->current.end = newline + 1; + } + + parser->current.type = PM_TOKEN_EMBDOC_LINE; + parser_lex_callback(parser); + } + + pm_parser_err_current(parser, PM_ERR_EMBDOC_TERM); + + comment->location.end = parser->current.end; + pm_list_append(&parser->comment_list, (pm_list_node_t *) comment); + + return PM_TOKEN_EOF; +} + +/** + * Set the current type to an ignored newline and then call the lex callback. + * This happens in a couple places depending on whether or not we have already + * lexed a comment. + */ +static inline void +parser_lex_ignored_newline(pm_parser_t *parser) { + parser->current.type = PM_TOKEN_IGNORED_NEWLINE; + parser_lex_callback(parser); +} + +/** + * This function will be called when a newline is encountered. In some newlines, + * we need to check if there is a heredoc or heredocs that we have already lexed + * the body of that we need to now skip past. That will be indicated by the + * heredoc_end field on the parser. + * + * If it is set, then we need to skip past the heredoc body and then clear the + * heredoc_end field. + */ +static inline void +parser_flush_heredoc_end(pm_parser_t *parser) { + assert(parser->heredoc_end <= parser->end); + parser->next_start = parser->heredoc_end; + parser->heredoc_end = NULL; +} + +/** + * Returns true if the parser has lexed the last token on the current line. +*/ +static bool +parser_end_of_line_p(const pm_parser_t *parser) { + const uint8_t *cursor = parser->current.end; + + while (cursor < parser->end && *cursor != '\n' && *cursor != '#') { + if (!pm_char_is_inline_whitespace(*cursor++)) return false; + } + + return true; +} + +/** + * When we're lexing certain types (strings, symbols, lists, etc.) we have + * string content associated with the tokens. For example: + * + * "foo" + * + * In this case, the string content is foo. Since there is no escaping, there's + * no need to track additional information and the token can be returned as + * normal. However, if we have escape sequences: + * + * "foo\n" + * + * then the bytes in the string are "f", "o", "o", "\", "n", but we want to + * provide our consumers with the string content "f", "o", "o", "\n". In these + * cases, when we find the first escape sequence, we initialize a pm_buffer_t + * to keep track of the string content. Then in the parser, it will + * automatically attach the string content to the node that it belongs to. + */ +typedef struct { + /** + * The buffer that we're using to keep track of the string content. It will + * only be initialized if we receive an escape sequence. + */ + pm_buffer_t buffer; + + /** + * The cursor into the source string that points to how far we have + * currently copied into the buffer. + */ + const uint8_t *cursor; +} pm_token_buffer_t; + +/** + * In order to properly set a regular expression's encoding and to validate + * the byte sequence for the underlying encoding we must process any escape + * sequences. The unescaped byte sequence will be stored in `buffer` just like + * for other string-like types. However, we also need to store the regular + * expression's source string. That string may be different from what we see + * during lexing because some escape sequences rewrite the source. + * + * This value will only be initialized for regular expressions and only if we + * receive an escape sequence. It will contain the regular expression's source + * string's byte sequence. + */ +typedef struct { + /** The embedded base buffer. */ + pm_token_buffer_t base; + + /** The buffer holding the regexp source. */ + pm_buffer_t regexp_buffer; +} pm_regexp_token_buffer_t; + +/** + * Push the given byte into the token buffer. + */ +static inline void +pm_token_buffer_push_byte(pm_token_buffer_t *token_buffer, uint8_t byte) { + pm_buffer_append_byte(&token_buffer->buffer, byte); +} + +static inline void +pm_regexp_token_buffer_push_byte(pm_regexp_token_buffer_t *token_buffer, uint8_t byte) { + pm_buffer_append_byte(&token_buffer->regexp_buffer, byte); +} + +/** + * Return the width of the character at the end of the current token. + */ +static inline size_t +parser_char_width(const pm_parser_t *parser) { + size_t width; + if (parser->encoding_changed) { + width = parser->encoding->char_width(parser->current.end, parser->end - parser->current.end); + } else { + width = pm_encoding_utf_8_char_width(parser->current.end, parser->end - parser->current.end); + } + + // TODO: If the character is invalid in the given encoding, then we'll just + // push one byte into the buffer. This should actually be an error. + return (width == 0 ? 1 : width); +} + +/** + * Push an escaped character into the token buffer. + */ +static void +pm_token_buffer_push_escaped(pm_token_buffer_t *token_buffer, pm_parser_t *parser) { + size_t width = parser_char_width(parser); + pm_buffer_append_bytes(&token_buffer->buffer, parser->current.end, width); + parser->current.end += width; +} + +static void +pm_regexp_token_buffer_push_escaped(pm_regexp_token_buffer_t *token_buffer, pm_parser_t *parser) { + size_t width = parser_char_width(parser); + pm_buffer_append_bytes(&token_buffer->base.buffer, parser->current.end, width); + pm_buffer_append_bytes(&token_buffer->regexp_buffer, parser->current.end, width); + parser->current.end += width; +} + +static bool +pm_slice_ascii_only_p(const uint8_t *value, size_t length) { + for (size_t index = 0; index < length; index++) { + if (value[index] & 0x80) return false; + } + + return true; +} + +/** + * When we're about to return from lexing the current token and we know for sure + * that we have found an escape sequence, this function is called to copy the + * contents of the token buffer into the current string on the parser so that it + * can be attached to the correct node. + */ +static inline void +pm_token_buffer_copy(pm_parser_t *parser, pm_token_buffer_t *token_buffer) { + pm_string_owned_init(&parser->current_string, (uint8_t *) pm_buffer_value(&token_buffer->buffer), pm_buffer_length(&token_buffer->buffer)); +} + +static inline void +pm_regexp_token_buffer_copy(pm_parser_t *parser, pm_regexp_token_buffer_t *token_buffer) { + pm_string_owned_init(&parser->current_string, (uint8_t *) pm_buffer_value(&token_buffer->base.buffer), pm_buffer_length(&token_buffer->base.buffer)); + parser->current_regular_expression_ascii_only = pm_slice_ascii_only_p((const uint8_t *) pm_buffer_value(&token_buffer->regexp_buffer), pm_buffer_length(&token_buffer->regexp_buffer)); + pm_buffer_free(&token_buffer->regexp_buffer); +} + +/** + * When we're about to return from lexing the current token, we need to flush + * all of the content that we have pushed into the buffer into the current + * string. If we haven't pushed anything into the buffer, this means that we + * never found an escape sequence, so we can directly reference the bounds of + * the current string. Either way, at the return of this function it is expected + * that parser->current_string is established in such a way that it can be + * attached to a node. + */ +static void +pm_token_buffer_flush(pm_parser_t *parser, pm_token_buffer_t *token_buffer) { + if (token_buffer->cursor == NULL) { + pm_string_shared_init(&parser->current_string, parser->current.start, parser->current.end); + } else { + pm_buffer_append_bytes(&token_buffer->buffer, token_buffer->cursor, (size_t) (parser->current.end - token_buffer->cursor)); + pm_token_buffer_copy(parser, token_buffer); + } +} + +static void +pm_regexp_token_buffer_flush(pm_parser_t *parser, pm_regexp_token_buffer_t *token_buffer) { + if (token_buffer->base.cursor == NULL) { + pm_string_shared_init(&parser->current_string, parser->current.start, parser->current.end); + parser->current_regular_expression_ascii_only = pm_slice_ascii_only_p(parser->current.start, (size_t) (parser->current.end - parser->current.start)); + } else { + pm_buffer_append_bytes(&token_buffer->base.buffer, token_buffer->base.cursor, (size_t) (parser->current.end - token_buffer->base.cursor)); + pm_buffer_append_bytes(&token_buffer->regexp_buffer, token_buffer->base.cursor, (size_t) (parser->current.end - token_buffer->base.cursor)); + pm_regexp_token_buffer_copy(parser, token_buffer); + } +} + +#define PM_TOKEN_BUFFER_DEFAULT_SIZE 16 + +/** + * When we've found an escape sequence, we need to copy everything up to this + * point into the buffer because we're about to provide a string that has + * different content than a direct slice of the source. + * + * It is expected that the parser's current token end will be pointing at one + * byte past the backslash that starts the escape sequence. + */ +static void +pm_token_buffer_escape(pm_parser_t *parser, pm_token_buffer_t *token_buffer) { + const uint8_t *start; + if (token_buffer->cursor == NULL) { + pm_buffer_init_capacity(&token_buffer->buffer, PM_TOKEN_BUFFER_DEFAULT_SIZE); + start = parser->current.start; + } else { + start = token_buffer->cursor; + } + + const uint8_t *end = parser->current.end - 1; + assert(end >= start); + pm_buffer_append_bytes(&token_buffer->buffer, start, (size_t) (end - start)); + + token_buffer->cursor = end; +} + +static void +pm_regexp_token_buffer_escape(pm_parser_t *parser, pm_regexp_token_buffer_t *token_buffer) { + const uint8_t *start; + if (token_buffer->base.cursor == NULL) { + pm_buffer_init_capacity(&token_buffer->base.buffer, PM_TOKEN_BUFFER_DEFAULT_SIZE); + pm_buffer_init_capacity(&token_buffer->regexp_buffer, PM_TOKEN_BUFFER_DEFAULT_SIZE); + start = parser->current.start; + } else { + start = token_buffer->base.cursor; + } + + const uint8_t *end = parser->current.end - 1; + pm_buffer_append_bytes(&token_buffer->base.buffer, start, (size_t) (end - start)); + pm_buffer_append_bytes(&token_buffer->regexp_buffer, start, (size_t) (end - start)); + + token_buffer->base.cursor = end; +} + +#undef PM_TOKEN_BUFFER_DEFAULT_SIZE + +/** + * Effectively the same thing as pm_strspn_inline_whitespace, but in the case of + * a tilde heredoc expands out tab characters to the nearest tab boundaries. + */ +static inline size_t +pm_heredoc_strspn_inline_whitespace(pm_parser_t *parser, const uint8_t **cursor, pm_heredoc_indent_t indent) { + size_t whitespace = 0; + + switch (indent) { + case PM_HEREDOC_INDENT_NONE: + // Do nothing, we can't match a terminator with + // indentation and there's no need to calculate common + // whitespace. + break; + case PM_HEREDOC_INDENT_DASH: + // Skip past inline whitespace. + *cursor += pm_strspn_inline_whitespace(*cursor, parser->end - *cursor); + break; + case PM_HEREDOC_INDENT_TILDE: + // Skip past inline whitespace and calculate common + // whitespace. + while (*cursor < parser->end && pm_char_is_inline_whitespace(**cursor)) { + if (**cursor == '\t') { + whitespace = (whitespace / PM_TAB_WHITESPACE_SIZE + 1) * PM_TAB_WHITESPACE_SIZE; + } else { + whitespace++; + } + (*cursor)++; + } + + break; + } + + return whitespace; +} + +/** + * Lex past the delimiter of a percent literal. Handle newlines and heredocs + * appropriately. + */ +static uint8_t +pm_lex_percent_delimiter(pm_parser_t *parser) { + size_t eol_length = match_eol(parser); + + if (eol_length) { + if (parser->heredoc_end) { + // If we have already lexed a heredoc, then the newline has already + // been added to the list. In this case we want to just flush the + // heredoc end. + parser_flush_heredoc_end(parser); + } else { + // Otherwise, we'll add the newline to the list of newlines. + pm_newline_list_append(&parser->newline_list, parser->current.end + eol_length - 1); + } + + uint8_t delimiter = *parser->current.end; + + // If our delimiter is \r\n, we want to treat it as if it's \n. + // For example, %\r\nfoo\r\n should be "foo" + if (eol_length == 2) { + delimiter = *(parser->current.end + 1); + } + + parser->current.end += eol_length; + return delimiter; + } + + return *parser->current.end++; +} + +/** + * This is a convenience macro that will set the current token type, call the + * lex callback, and then return from the parser_lex function. + */ +#define LEX(token_type) parser->current.type = token_type; parser_lex_callback(parser); return + +/** + * Called when the parser requires a new token. The parser maintains a moving + * window of two tokens at a time: parser.previous and parser.current. This + * function will move the current token into the previous token and then + * lex a new token into the current token. + */ +static void +parser_lex(pm_parser_t *parser) { + assert(parser->current.end <= parser->end); + parser->previous = parser->current; + + // This value mirrors cmd_state from CRuby. + bool previous_command_start = parser->command_start; + parser->command_start = false; + + // This is used to communicate to the newline lexing function that we've + // already seen a comment. + bool lexed_comment = false; + + // Here we cache the current value of the semantic token seen flag. This is + // used to reset it in case we find a token that shouldn't flip this flag. + unsigned int semantic_token_seen = parser->semantic_token_seen; + parser->semantic_token_seen = true; + + switch (parser->lex_modes.current->mode) { + case PM_LEX_DEFAULT: + case PM_LEX_EMBEXPR: + case PM_LEX_EMBVAR: + + // We have a specific named label here because we are going to jump back to + // this location in the event that we have lexed a token that should not be + // returned to the parser. This includes comments, ignored newlines, and + // invalid tokens of some form. + lex_next_token: { + // If we have the special next_start pointer set, then we're going to jump + // to that location and start lexing from there. + if (parser->next_start != NULL) { + parser->current.end = parser->next_start; + parser->next_start = NULL; + } + + // This value mirrors space_seen from CRuby. It tracks whether or not + // space has been eaten before the start of the next token. + bool space_seen = false; + + // First, we're going to skip past any whitespace at the front of the next + // token. + bool chomping = true; + while (parser->current.end < parser->end && chomping) { + switch (*parser->current.end) { + case ' ': + case '\t': + case '\f': + case '\v': + parser->current.end++; + space_seen = true; + break; + case '\r': + if (match_eol_offset(parser, 1)) { + chomping = false; + } else { + pm_parser_warn(parser, parser->current.end, parser->current.end + 1, PM_WARN_UNEXPECTED_CARRIAGE_RETURN); + parser->current.end++; + space_seen = true; + } + break; + case '\\': { + size_t eol_length = match_eol_offset(parser, 1); + if (eol_length) { + if (parser->heredoc_end) { + parser->current.end = parser->heredoc_end; + parser->heredoc_end = NULL; + } else { + parser->current.end += eol_length + 1; + pm_newline_list_append(&parser->newline_list, parser->current.end - 1); + space_seen = true; + } + } else if (pm_char_is_inline_whitespace(*parser->current.end)) { + parser->current.end += 2; + } else { + chomping = false; + } + + break; + } + default: + chomping = false; + break; + } + } + + // Next, we'll set to start of this token to be the current end. + parser->current.start = parser->current.end; + + // We'll check if we're at the end of the file. If we are, then we + // need to return the EOF token. + if (parser->current.end >= parser->end) { + // If we hit EOF, but the EOF came immediately after a newline, + // set the start of the token to the newline. This way any EOF + // errors will be reported as happening on that line rather than + // a line after. For example "foo(\n" should report an error + // on line 1 even though EOF technically occurs on line 2. + if (parser->current.start > parser->start && (*(parser->current.start - 1) == '\n')) { + parser->current.start -= 1; + } + LEX(PM_TOKEN_EOF); + } + + // Finally, we'll check the current character to determine the next + // token. + switch (*parser->current.end++) { + case '\0': // NUL or end of script + case '\004': // ^D + case '\032': // ^Z + parser->current.end--; + LEX(PM_TOKEN_EOF); + + case '#': { // comments + const uint8_t *ending = next_newline(parser->current.end, parser->end - parser->current.end); + parser->current.end = ending == NULL ? parser->end : ending; + + // If we found a comment while lexing, then we're going to + // add it to the list of comments in the file and keep + // lexing. + pm_comment_t *comment = parser_comment(parser, PM_COMMENT_INLINE); + pm_list_append(&parser->comment_list, (pm_list_node_t *) comment); + + if (ending) parser->current.end++; + parser->current.type = PM_TOKEN_COMMENT; + parser_lex_callback(parser); + + // Here, parse the comment to see if it's a magic comment + // and potentially change state on the parser. + if (!parser_lex_magic_comment(parser, semantic_token_seen) && (parser->current.start == parser->encoding_comment_start)) { + ptrdiff_t length = parser->current.end - parser->current.start; + + // If we didn't find a magic comment within the first + // pass and we're at the start of the file, then we need + // to do another pass to potentially find other patterns + // for encoding comments. + if (length >= 10 && !parser->encoding_locked) { + parser_lex_magic_comment_encoding(parser); + } + } + + lexed_comment = true; + } + PRISM_FALLTHROUGH + case '\r': + case '\n': { + parser->semantic_token_seen = semantic_token_seen & 0x1; + size_t eol_length = match_eol_at(parser, parser->current.end - 1); + + if (eol_length) { + // The only way you can have carriage returns in this + // particular loop is if you have a carriage return + // followed by a newline. In that case we'll just skip + // over the carriage return and continue lexing, in + // order to make it so that the newline token + // encapsulates both the carriage return and the + // newline. Note that we need to check that we haven't + // already lexed a comment here because that falls + // through into here as well. + if (!lexed_comment) { + parser->current.end += eol_length - 1; // skip CR + } + + if (parser->heredoc_end == NULL) { + pm_newline_list_append(&parser->newline_list, parser->current.end - 1); + } + } + + if (parser->heredoc_end) { + parser_flush_heredoc_end(parser); + } + + // If this is an ignored newline, then we can continue lexing after + // calling the callback with the ignored newline token. + switch (lex_state_ignored_p(parser)) { + case PM_IGNORED_NEWLINE_NONE: + break; + case PM_IGNORED_NEWLINE_PATTERN: + if (parser->pattern_matching_newlines || parser->in_keyword_arg) { + if (!lexed_comment) parser_lex_ignored_newline(parser); + lex_state_set(parser, PM_LEX_STATE_BEG); + parser->command_start = true; + parser->current.type = PM_TOKEN_NEWLINE; + return; + } + PRISM_FALLTHROUGH + case PM_IGNORED_NEWLINE_ALL: + if (!lexed_comment) parser_lex_ignored_newline(parser); + lexed_comment = false; + goto lex_next_token; + } + + // Here we need to look ahead and see if there is a call operator + // (either . or &.) that starts the next line. If there is, then this + // is going to become an ignored newline and we're going to instead + // return the call operator. + const uint8_t *next_content = parser->next_start == NULL ? parser->current.end : parser->next_start; + next_content += pm_strspn_inline_whitespace(next_content, parser->end - next_content); + + if (next_content < parser->end) { + // If we hit a comment after a newline, then we're going to check + // if it's ignored or if it's followed by a method call ('.'). + // If it is, then we're going to call the + // callback with an ignored newline and then continue lexing. + // Otherwise we'll return a regular newline. + if (next_content[0] == '#') { + // Here we look for a "." or "&." following a "\n". + const uint8_t *following = next_newline(next_content, parser->end - next_content); + + while (following && (following + 1 < parser->end)) { + following++; + following += pm_strspn_inline_whitespace(following, parser->end - following); + + // If this is not followed by a comment, then we can break out + // of this loop. + if (peek_at(parser, following) != '#') break; + + // If there is a comment, then we need to find the end of the + // comment and continue searching from there. + following = next_newline(following, parser->end - following); + } + + // If the lex state was ignored, or we hit a '.' or a '&.', + // we will lex the ignored newline + if ( + lex_state_ignored_p(parser) || + (following && ( + (peek_at(parser, following) == '.') || + (peek_at(parser, following) == '&' && peek_at(parser, following + 1) == '.') + )) + ) { + if (!lexed_comment) parser_lex_ignored_newline(parser); + lexed_comment = false; + goto lex_next_token; + } + } + + // If we hit a . after a newline, then we're in a call chain and + // we need to return the call operator. + if (next_content[0] == '.') { + // To match ripper, we need to emit an ignored newline even though + // it's a real newline in the case that we have a beginless range + // on a subsequent line. + if (peek_at(parser, next_content + 1) == '.') { + if (!lexed_comment) parser_lex_ignored_newline(parser); + lex_state_set(parser, PM_LEX_STATE_BEG); + parser->command_start = true; + parser->current.type = PM_TOKEN_NEWLINE; + return; + } + + if (!lexed_comment) parser_lex_ignored_newline(parser); + lex_state_set(parser, PM_LEX_STATE_DOT); + parser->current.start = next_content; + parser->current.end = next_content + 1; + parser->next_start = NULL; + LEX(PM_TOKEN_DOT); + } + + // If we hit a &. after a newline, then we're in a call chain and + // we need to return the call operator. + if (peek_at(parser, next_content) == '&' && peek_at(parser, next_content + 1) == '.') { + if (!lexed_comment) parser_lex_ignored_newline(parser); + lex_state_set(parser, PM_LEX_STATE_DOT); + parser->current.start = next_content; + parser->current.end = next_content + 2; + parser->next_start = NULL; + LEX(PM_TOKEN_AMPERSAND_DOT); + } + } + + // At this point we know this is a regular newline, and we can set the + // necessary state and return the token. + lex_state_set(parser, PM_LEX_STATE_BEG); + parser->command_start = true; + parser->current.type = PM_TOKEN_NEWLINE; + if (!lexed_comment) parser_lex_callback(parser); + return; + } + + // , + case ',': + if ((parser->previous.type == PM_TOKEN_COMMA) && (parser->enclosure_nesting > 0)) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_ARRAY_TERM, pm_token_type_human(parser->current.type)); + } + + lex_state_set(parser, PM_LEX_STATE_BEG | PM_LEX_STATE_LABEL); + LEX(PM_TOKEN_COMMA); + + // ( + case '(': { + pm_token_type_t type = PM_TOKEN_PARENTHESIS_LEFT; + + if (space_seen && (lex_state_arg_p(parser) || parser->lex_state == (PM_LEX_STATE_END | PM_LEX_STATE_LABEL))) { + type = PM_TOKEN_PARENTHESIS_LEFT_PARENTHESES; + } + + parser->enclosure_nesting++; + lex_state_set(parser, PM_LEX_STATE_BEG | PM_LEX_STATE_LABEL); + pm_do_loop_stack_push(parser, false); + LEX(type); + } + + // ) + case ')': + parser->enclosure_nesting--; + lex_state_set(parser, PM_LEX_STATE_ENDFN); + pm_do_loop_stack_pop(parser); + LEX(PM_TOKEN_PARENTHESIS_RIGHT); + + // ; + case ';': + lex_state_set(parser, PM_LEX_STATE_BEG); + parser->command_start = true; + LEX(PM_TOKEN_SEMICOLON); + + // [ [] []= + case '[': + parser->enclosure_nesting++; + pm_token_type_t type = PM_TOKEN_BRACKET_LEFT; + + if (lex_state_operator_p(parser)) { + if (match(parser, ']')) { + parser->enclosure_nesting--; + lex_state_set(parser, PM_LEX_STATE_ARG); + LEX(match(parser, '=') ? PM_TOKEN_BRACKET_LEFT_RIGHT_EQUAL : PM_TOKEN_BRACKET_LEFT_RIGHT); + } + + lex_state_set(parser, PM_LEX_STATE_ARG | PM_LEX_STATE_LABEL); + LEX(type); + } + + if (lex_state_beg_p(parser) || (lex_state_arg_p(parser) && (space_seen || lex_state_p(parser, PM_LEX_STATE_LABELED)))) { + type = PM_TOKEN_BRACKET_LEFT_ARRAY; + } + + lex_state_set(parser, PM_LEX_STATE_BEG | PM_LEX_STATE_LABEL); + pm_do_loop_stack_push(parser, false); + LEX(type); + + // ] + case ']': + parser->enclosure_nesting--; + lex_state_set(parser, PM_LEX_STATE_END); + pm_do_loop_stack_pop(parser); + LEX(PM_TOKEN_BRACKET_RIGHT); + + // { + case '{': { + pm_token_type_t type = PM_TOKEN_BRACE_LEFT; + + if (parser->enclosure_nesting == parser->lambda_enclosure_nesting) { + // This { begins a lambda + parser->command_start = true; + lex_state_set(parser, PM_LEX_STATE_BEG); + type = PM_TOKEN_LAMBDA_BEGIN; + } else if (lex_state_p(parser, PM_LEX_STATE_LABELED)) { + // This { begins a hash literal + lex_state_set(parser, PM_LEX_STATE_BEG | PM_LEX_STATE_LABEL); + } else if (lex_state_p(parser, PM_LEX_STATE_ARG_ANY | PM_LEX_STATE_END | PM_LEX_STATE_ENDFN)) { + // This { begins a block + parser->command_start = true; + lex_state_set(parser, PM_LEX_STATE_BEG); + } else if (lex_state_p(parser, PM_LEX_STATE_ENDARG)) { + // This { begins a block on a command + parser->command_start = true; + lex_state_set(parser, PM_LEX_STATE_BEG); + } else { + // This { begins a hash literal + lex_state_set(parser, PM_LEX_STATE_BEG | PM_LEX_STATE_LABEL); + } + + parser->enclosure_nesting++; + parser->brace_nesting++; + pm_do_loop_stack_push(parser, false); + + LEX(type); + } + + // } + case '}': + parser->enclosure_nesting--; + pm_do_loop_stack_pop(parser); + + if ((parser->lex_modes.current->mode == PM_LEX_EMBEXPR) && (parser->brace_nesting == 0)) { + lex_mode_pop(parser); + LEX(PM_TOKEN_EMBEXPR_END); + } + + parser->brace_nesting--; + lex_state_set(parser, PM_LEX_STATE_END); + LEX(PM_TOKEN_BRACE_RIGHT); + + // * ** **= *= + case '*': { + if (match(parser, '*')) { + if (match(parser, '=')) { + lex_state_set(parser, PM_LEX_STATE_BEG); + LEX(PM_TOKEN_STAR_STAR_EQUAL); + } + + pm_token_type_t type = PM_TOKEN_STAR_STAR; + + if (lex_state_spcarg_p(parser, space_seen)) { + pm_parser_warn_token(parser, &parser->current, PM_WARN_AMBIGUOUS_PREFIX_STAR_STAR); + type = PM_TOKEN_USTAR_STAR; + } else if (lex_state_beg_p(parser)) { + type = PM_TOKEN_USTAR_STAR; + } else if (ambiguous_operator_p(parser, space_seen)) { + PM_PARSER_WARN_TOKEN_FORMAT(parser, parser->current, PM_WARN_AMBIGUOUS_BINARY_OPERATOR, "**", "argument prefix"); + } + + if (lex_state_operator_p(parser)) { + lex_state_set(parser, PM_LEX_STATE_ARG); + } else { + lex_state_set(parser, PM_LEX_STATE_BEG); + } + + LEX(type); + } + + if (match(parser, '=')) { + lex_state_set(parser, PM_LEX_STATE_BEG); + LEX(PM_TOKEN_STAR_EQUAL); + } + + pm_token_type_t type = PM_TOKEN_STAR; + + if (lex_state_spcarg_p(parser, space_seen)) { + pm_parser_warn_token(parser, &parser->current, PM_WARN_AMBIGUOUS_PREFIX_STAR); + type = PM_TOKEN_USTAR; + } else if (lex_state_beg_p(parser)) { + type = PM_TOKEN_USTAR; + } else if (ambiguous_operator_p(parser, space_seen)) { + PM_PARSER_WARN_TOKEN_FORMAT(parser, parser->current, PM_WARN_AMBIGUOUS_BINARY_OPERATOR, "*", "argument prefix"); + } + + if (lex_state_operator_p(parser)) { + lex_state_set(parser, PM_LEX_STATE_ARG); + } else { + lex_state_set(parser, PM_LEX_STATE_BEG); + } + + LEX(type); + } + + // ! != !~ !@ + case '!': + if (lex_state_operator_p(parser)) { + lex_state_set(parser, PM_LEX_STATE_ARG); + if (match(parser, '@')) { + LEX(PM_TOKEN_BANG); + } + } else { + lex_state_set(parser, PM_LEX_STATE_BEG); + } + + if (match(parser, '=')) { + LEX(PM_TOKEN_BANG_EQUAL); + } + + if (match(parser, '~')) { + LEX(PM_TOKEN_BANG_TILDE); + } + + LEX(PM_TOKEN_BANG); + + // = => =~ == === =begin + case '=': + if ( + current_token_starts_line(parser) && + (parser->current.end + 5 <= parser->end) && + memcmp(parser->current.end, "begin", 5) == 0 && + (pm_char_is_whitespace(peek_offset(parser, 5)) || (peek_offset(parser, 5) == '\0')) + ) { + pm_token_type_t type = lex_embdoc(parser); + if (type == PM_TOKEN_EOF) { + LEX(type); + } + + goto lex_next_token; + } + + if (lex_state_operator_p(parser)) { + lex_state_set(parser, PM_LEX_STATE_ARG); + } else { + lex_state_set(parser, PM_LEX_STATE_BEG); + } + + if (match(parser, '>')) { + LEX(PM_TOKEN_EQUAL_GREATER); + } + + if (match(parser, '~')) { + LEX(PM_TOKEN_EQUAL_TILDE); + } + + if (match(parser, '=')) { + LEX(match(parser, '=') ? PM_TOKEN_EQUAL_EQUAL_EQUAL : PM_TOKEN_EQUAL_EQUAL); + } + + LEX(PM_TOKEN_EQUAL); + + // < << <<= <= <=> + case '<': + if (match(parser, '<')) { + if ( + !lex_state_p(parser, PM_LEX_STATE_DOT | PM_LEX_STATE_CLASS) && + !lex_state_end_p(parser) && + (!lex_state_p(parser, PM_LEX_STATE_ARG_ANY) || lex_state_p(parser, PM_LEX_STATE_LABELED) || space_seen) + ) { + const uint8_t *end = parser->current.end; + + pm_heredoc_quote_t quote = PM_HEREDOC_QUOTE_NONE; + pm_heredoc_indent_t indent = PM_HEREDOC_INDENT_NONE; + + if (match(parser, '-')) { + indent = PM_HEREDOC_INDENT_DASH; + } + else if (match(parser, '~')) { + indent = PM_HEREDOC_INDENT_TILDE; + } + + if (match(parser, '`')) { + quote = PM_HEREDOC_QUOTE_BACKTICK; + } + else if (match(parser, '"')) { + quote = PM_HEREDOC_QUOTE_DOUBLE; + } + else if (match(parser, '\'')) { + quote = PM_HEREDOC_QUOTE_SINGLE; + } + + const uint8_t *ident_start = parser->current.end; + size_t width = 0; + + if (parser->current.end >= parser->end) { + parser->current.end = end; + } else if (quote == PM_HEREDOC_QUOTE_NONE && (width = char_is_identifier(parser, parser->current.end, parser->end - parser->current.end)) == 0) { + parser->current.end = end; + } else { + if (quote == PM_HEREDOC_QUOTE_NONE) { + parser->current.end += width; + + while ((width = char_is_identifier(parser, parser->current.end, parser->end - parser->current.end))) { + parser->current.end += width; + } + } else { + // If we have quotes, then we're going to go until we find the + // end quote. + while ((parser->current.end < parser->end) && quote != (pm_heredoc_quote_t) (*parser->current.end)) { + if (*parser->current.end == '\r' || *parser->current.end == '\n') break; + parser->current.end++; + } + } + + size_t ident_length = (size_t) (parser->current.end - ident_start); + bool ident_error = false; + + if (quote != PM_HEREDOC_QUOTE_NONE && !match(parser, (uint8_t) quote)) { + pm_parser_err(parser, ident_start, ident_start + ident_length, PM_ERR_HEREDOC_IDENTIFIER); + ident_error = true; + } + + parser->explicit_encoding = NULL; + lex_mode_push(parser, (pm_lex_mode_t) { + .mode = PM_LEX_HEREDOC, + .as.heredoc = { + .base = { + .ident_start = ident_start, + .ident_length = ident_length, + .quote = quote, + .indent = indent + }, + .next_start = parser->current.end, + .common_whitespace = NULL, + .line_continuation = false + } + }); + + if (parser->heredoc_end == NULL) { + const uint8_t *body_start = next_newline(parser->current.end, parser->end - parser->current.end); + + if (body_start == NULL) { + // If there is no newline after the heredoc identifier, then + // this is not a valid heredoc declaration. In this case we + // will add an error, but we will still return a heredoc + // start. + if (!ident_error) pm_parser_err_heredoc_term(parser, ident_start, ident_length); + body_start = parser->end; + } else { + // Otherwise, we want to indicate that the body of the + // heredoc starts on the character after the next newline. + pm_newline_list_append(&parser->newline_list, body_start); + body_start++; + } + + parser->next_start = body_start; + } else { + parser->next_start = parser->heredoc_end; + } + + LEX(PM_TOKEN_HEREDOC_START); + } + } + + if (match(parser, '=')) { + lex_state_set(parser, PM_LEX_STATE_BEG); + LEX(PM_TOKEN_LESS_LESS_EQUAL); + } + + if (ambiguous_operator_p(parser, space_seen)) { + PM_PARSER_WARN_TOKEN_FORMAT(parser, parser->current, PM_WARN_AMBIGUOUS_BINARY_OPERATOR, "<<", "here document"); + } + + if (lex_state_operator_p(parser)) { + lex_state_set(parser, PM_LEX_STATE_ARG); + } else { + if (lex_state_p(parser, PM_LEX_STATE_CLASS)) parser->command_start = true; + lex_state_set(parser, PM_LEX_STATE_BEG); + } + + LEX(PM_TOKEN_LESS_LESS); + } + + if (lex_state_operator_p(parser)) { + lex_state_set(parser, PM_LEX_STATE_ARG); + } else { + if (lex_state_p(parser, PM_LEX_STATE_CLASS)) parser->command_start = true; + lex_state_set(parser, PM_LEX_STATE_BEG); + } + + if (match(parser, '=')) { + if (match(parser, '>')) { + LEX(PM_TOKEN_LESS_EQUAL_GREATER); + } + + LEX(PM_TOKEN_LESS_EQUAL); + } + + LEX(PM_TOKEN_LESS); + + // > >> >>= >= + case '>': + if (match(parser, '>')) { + if (lex_state_operator_p(parser)) { + lex_state_set(parser, PM_LEX_STATE_ARG); + } else { + lex_state_set(parser, PM_LEX_STATE_BEG); + } + LEX(match(parser, '=') ? PM_TOKEN_GREATER_GREATER_EQUAL : PM_TOKEN_GREATER_GREATER); + } + + if (lex_state_operator_p(parser)) { + lex_state_set(parser, PM_LEX_STATE_ARG); + } else { + lex_state_set(parser, PM_LEX_STATE_BEG); + } + + LEX(match(parser, '=') ? PM_TOKEN_GREATER_EQUAL : PM_TOKEN_GREATER); + + // double-quoted string literal + case '"': { + bool label_allowed = (lex_state_p(parser, PM_LEX_STATE_LABEL | PM_LEX_STATE_ENDFN) && !previous_command_start) || lex_state_arg_p(parser); + lex_mode_push_string(parser, true, label_allowed, '\0', '"'); + LEX(PM_TOKEN_STRING_BEGIN); + } + + // xstring literal + case '`': { + if (lex_state_p(parser, PM_LEX_STATE_FNAME)) { + lex_state_set(parser, PM_LEX_STATE_ENDFN); + LEX(PM_TOKEN_BACKTICK); + } + + if (lex_state_p(parser, PM_LEX_STATE_DOT)) { + if (previous_command_start) { + lex_state_set(parser, PM_LEX_STATE_CMDARG); + } else { + lex_state_set(parser, PM_LEX_STATE_ARG); + } + + LEX(PM_TOKEN_BACKTICK); + } + + lex_mode_push_string(parser, true, false, '\0', '`'); + LEX(PM_TOKEN_BACKTICK); + } + + // single-quoted string literal + case '\'': { + bool label_allowed = (lex_state_p(parser, PM_LEX_STATE_LABEL | PM_LEX_STATE_ENDFN) && !previous_command_start) || lex_state_arg_p(parser); + lex_mode_push_string(parser, false, label_allowed, '\0', '\''); + LEX(PM_TOKEN_STRING_BEGIN); + } + + // ? character literal + case '?': + LEX(lex_question_mark(parser)); + + // & && &&= &= + case '&': { + if (match(parser, '&')) { + lex_state_set(parser, PM_LEX_STATE_BEG); + + if (match(parser, '=')) { + LEX(PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL); + } + + LEX(PM_TOKEN_AMPERSAND_AMPERSAND); + } + + if (match(parser, '=')) { + lex_state_set(parser, PM_LEX_STATE_BEG); + LEX(PM_TOKEN_AMPERSAND_EQUAL); + } + + if (match(parser, '.')) { + lex_state_set(parser, PM_LEX_STATE_DOT); + LEX(PM_TOKEN_AMPERSAND_DOT); + } + + pm_token_type_t type = PM_TOKEN_AMPERSAND; + if (lex_state_spcarg_p(parser, space_seen)) { + if ((peek(parser) != ':') || (peek_offset(parser, 1) == '\0')) { + pm_parser_warn_token(parser, &parser->current, PM_WARN_AMBIGUOUS_PREFIX_AMPERSAND); + } else { + const uint8_t delim = peek_offset(parser, 1); + + if ((delim != '\'') && (delim != '"') && !char_is_identifier(parser, parser->current.end + 1, parser->end - (parser->current.end + 1))) { + pm_parser_warn_token(parser, &parser->current, PM_WARN_AMBIGUOUS_PREFIX_AMPERSAND); + } + } + + type = PM_TOKEN_UAMPERSAND; + } else if (lex_state_beg_p(parser)) { + type = PM_TOKEN_UAMPERSAND; + } else if (ambiguous_operator_p(parser, space_seen)) { + PM_PARSER_WARN_TOKEN_FORMAT(parser, parser->current, PM_WARN_AMBIGUOUS_BINARY_OPERATOR, "&", "argument prefix"); + } + + if (lex_state_operator_p(parser)) { + lex_state_set(parser, PM_LEX_STATE_ARG); + } else { + lex_state_set(parser, PM_LEX_STATE_BEG); + } + + LEX(type); + } + + // | || ||= |= + case '|': + if (match(parser, '|')) { + if (match(parser, '=')) { + lex_state_set(parser, PM_LEX_STATE_BEG); + LEX(PM_TOKEN_PIPE_PIPE_EQUAL); + } + + if (lex_state_p(parser, PM_LEX_STATE_BEG)) { + parser->current.end--; + LEX(PM_TOKEN_PIPE); + } + + lex_state_set(parser, PM_LEX_STATE_BEG); + LEX(PM_TOKEN_PIPE_PIPE); + } + + if (match(parser, '=')) { + lex_state_set(parser, PM_LEX_STATE_BEG); + LEX(PM_TOKEN_PIPE_EQUAL); + } + + if (lex_state_operator_p(parser)) { + lex_state_set(parser, PM_LEX_STATE_ARG); + } else { + lex_state_set(parser, PM_LEX_STATE_BEG | PM_LEX_STATE_LABEL); + } + + LEX(PM_TOKEN_PIPE); + + // + += +@ + case '+': { + if (lex_state_operator_p(parser)) { + lex_state_set(parser, PM_LEX_STATE_ARG); + + if (match(parser, '@')) { + LEX(PM_TOKEN_UPLUS); + } + + LEX(PM_TOKEN_PLUS); + } + + if (match(parser, '=')) { + lex_state_set(parser, PM_LEX_STATE_BEG); + LEX(PM_TOKEN_PLUS_EQUAL); + } + + if ( + lex_state_beg_p(parser) || + (lex_state_spcarg_p(parser, space_seen) ? (pm_parser_warn_token(parser, &parser->current, PM_WARN_AMBIGUOUS_FIRST_ARGUMENT_PLUS), true) : false) + ) { + lex_state_set(parser, PM_LEX_STATE_BEG); + + if (pm_char_is_decimal_digit(peek(parser))) { + parser->current.end++; + pm_token_type_t type = lex_numeric(parser); + lex_state_set(parser, PM_LEX_STATE_END); + LEX(type); + } + + LEX(PM_TOKEN_UPLUS); + } + + if (ambiguous_operator_p(parser, space_seen)) { + PM_PARSER_WARN_TOKEN_FORMAT(parser, parser->current, PM_WARN_AMBIGUOUS_BINARY_OPERATOR, "+", "unary operator"); + } + + lex_state_set(parser, PM_LEX_STATE_BEG); + LEX(PM_TOKEN_PLUS); + } + + // - -= -@ + case '-': { + if (lex_state_operator_p(parser)) { + lex_state_set(parser, PM_LEX_STATE_ARG); + + if (match(parser, '@')) { + LEX(PM_TOKEN_UMINUS); + } + + LEX(PM_TOKEN_MINUS); + } + + if (match(parser, '=')) { + lex_state_set(parser, PM_LEX_STATE_BEG); + LEX(PM_TOKEN_MINUS_EQUAL); + } + + if (match(parser, '>')) { + lex_state_set(parser, PM_LEX_STATE_ENDFN); + LEX(PM_TOKEN_MINUS_GREATER); + } + + bool spcarg = lex_state_spcarg_p(parser, space_seen); + bool is_beg = lex_state_beg_p(parser); + if (!is_beg && spcarg) { + pm_parser_warn_token(parser, &parser->current, PM_WARN_AMBIGUOUS_FIRST_ARGUMENT_MINUS); + } + + if (is_beg || spcarg) { + lex_state_set(parser, PM_LEX_STATE_BEG); + LEX(pm_char_is_decimal_digit(peek(parser)) ? PM_TOKEN_UMINUS_NUM : PM_TOKEN_UMINUS); + } + + if (ambiguous_operator_p(parser, space_seen)) { + PM_PARSER_WARN_TOKEN_FORMAT(parser, parser->current, PM_WARN_AMBIGUOUS_BINARY_OPERATOR, "-", "unary operator"); + } + + lex_state_set(parser, PM_LEX_STATE_BEG); + LEX(PM_TOKEN_MINUS); + } + + // . .. ... + case '.': { + bool beg_p = lex_state_beg_p(parser); + + if (match(parser, '.')) { + if (match(parser, '.')) { + // If we're _not_ inside a range within default parameters + if (!context_p(parser, PM_CONTEXT_DEFAULT_PARAMS) && context_p(parser, PM_CONTEXT_DEF_PARAMS)) { + if (lex_state_p(parser, PM_LEX_STATE_END)) { + lex_state_set(parser, PM_LEX_STATE_BEG); + } else { + lex_state_set(parser, PM_LEX_STATE_ENDARG); + } + LEX(PM_TOKEN_UDOT_DOT_DOT); + } + + if (parser->enclosure_nesting == 0 && parser_end_of_line_p(parser)) { + pm_parser_warn_token(parser, &parser->current, PM_WARN_DOT_DOT_DOT_EOL); + } + + lex_state_set(parser, PM_LEX_STATE_BEG); + LEX(beg_p ? PM_TOKEN_UDOT_DOT_DOT : PM_TOKEN_DOT_DOT_DOT); + } + + lex_state_set(parser, PM_LEX_STATE_BEG); + LEX(beg_p ? PM_TOKEN_UDOT_DOT : PM_TOKEN_DOT_DOT); + } + + lex_state_set(parser, PM_LEX_STATE_DOT); + LEX(PM_TOKEN_DOT); + } + + // integer + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': { + pm_token_type_t type = lex_numeric(parser); + lex_state_set(parser, PM_LEX_STATE_END); + LEX(type); + } + + // :: symbol + case ':': + if (match(parser, ':')) { + if (lex_state_beg_p(parser) || lex_state_p(parser, PM_LEX_STATE_CLASS) || (lex_state_p(parser, PM_LEX_STATE_ARG_ANY) && space_seen)) { + lex_state_set(parser, PM_LEX_STATE_BEG); + LEX(PM_TOKEN_UCOLON_COLON); + } + + lex_state_set(parser, PM_LEX_STATE_DOT); + LEX(PM_TOKEN_COLON_COLON); + } + + if (lex_state_end_p(parser) || pm_char_is_whitespace(peek(parser)) || peek(parser) == '#') { + lex_state_set(parser, PM_LEX_STATE_BEG); + LEX(PM_TOKEN_COLON); + } + + if (peek(parser) == '"' || peek(parser) == '\'') { + lex_mode_push_string(parser, peek(parser) == '"', false, '\0', *parser->current.end); + parser->current.end++; + } + + lex_state_set(parser, PM_LEX_STATE_FNAME); + LEX(PM_TOKEN_SYMBOL_BEGIN); + + // / /= + case '/': + if (lex_state_beg_p(parser)) { + lex_mode_push_regexp(parser, '\0', '/'); + LEX(PM_TOKEN_REGEXP_BEGIN); + } + + if (match(parser, '=')) { + lex_state_set(parser, PM_LEX_STATE_BEG); + LEX(PM_TOKEN_SLASH_EQUAL); + } + + if (lex_state_spcarg_p(parser, space_seen)) { + pm_parser_warn_token(parser, &parser->current, PM_WARN_AMBIGUOUS_SLASH); + lex_mode_push_regexp(parser, '\0', '/'); + LEX(PM_TOKEN_REGEXP_BEGIN); + } + + if (ambiguous_operator_p(parser, space_seen)) { + PM_PARSER_WARN_TOKEN_FORMAT(parser, parser->current, PM_WARN_AMBIGUOUS_BINARY_OPERATOR, "/", "regexp literal"); + } + + if (lex_state_operator_p(parser)) { + lex_state_set(parser, PM_LEX_STATE_ARG); + } else { + lex_state_set(parser, PM_LEX_STATE_BEG); + } + + LEX(PM_TOKEN_SLASH); + + // ^ ^= + case '^': + if (lex_state_operator_p(parser)) { + lex_state_set(parser, PM_LEX_STATE_ARG); + } else { + lex_state_set(parser, PM_LEX_STATE_BEG); + } + LEX(match(parser, '=') ? PM_TOKEN_CARET_EQUAL : PM_TOKEN_CARET); + + // ~ ~@ + case '~': + if (lex_state_operator_p(parser)) { + (void) match(parser, '@'); + lex_state_set(parser, PM_LEX_STATE_ARG); + } else { + lex_state_set(parser, PM_LEX_STATE_BEG); + } + + LEX(PM_TOKEN_TILDE); + + // % %= %i %I %q %Q %w %W + case '%': { + // If there is no subsequent character then we have an + // invalid token. We're going to say it's the percent + // operator because we don't want to move into the string + // lex mode unnecessarily. + if ((lex_state_beg_p(parser) || lex_state_arg_p(parser)) && (parser->current.end >= parser->end)) { + pm_parser_err_current(parser, PM_ERR_INVALID_PERCENT_EOF); + LEX(PM_TOKEN_PERCENT); + } + + if (!lex_state_beg_p(parser) && match(parser, '=')) { + lex_state_set(parser, PM_LEX_STATE_BEG); + LEX(PM_TOKEN_PERCENT_EQUAL); + } else if ( + lex_state_beg_p(parser) || + (lex_state_p(parser, PM_LEX_STATE_FITEM) && (peek(parser) == 's')) || + lex_state_spcarg_p(parser, space_seen) + ) { + if (!parser->encoding->alnum_char(parser->current.end, parser->end - parser->current.end)) { + if (*parser->current.end >= 0x80) { + pm_parser_err_current(parser, PM_ERR_INVALID_PERCENT); + } + + const uint8_t delimiter = pm_lex_percent_delimiter(parser); + lex_mode_push_string(parser, true, false, lex_mode_incrementor(delimiter), lex_mode_terminator(delimiter)); + LEX(PM_TOKEN_STRING_BEGIN); + } + + // Delimiters for %-literals cannot be alphanumeric. We + // validate that here. + uint8_t delimiter = peek_offset(parser, 1); + if (delimiter >= 0x80 || parser->encoding->alnum_char(&delimiter, 1)) { + pm_parser_err_current(parser, PM_ERR_INVALID_PERCENT); + goto lex_next_token; + } + + switch (peek(parser)) { + case 'i': { + parser->current.end++; + + if (parser->current.end < parser->end) { + lex_mode_push_list(parser, false, pm_lex_percent_delimiter(parser)); + } else { + lex_mode_push_list_eof(parser); + } + + LEX(PM_TOKEN_PERCENT_LOWER_I); + } + case 'I': { + parser->current.end++; + + if (parser->current.end < parser->end) { + lex_mode_push_list(parser, true, pm_lex_percent_delimiter(parser)); + } else { + lex_mode_push_list_eof(parser); + } + + LEX(PM_TOKEN_PERCENT_UPPER_I); + } + case 'r': { + parser->current.end++; + + if (parser->current.end < parser->end) { + const uint8_t delimiter = pm_lex_percent_delimiter(parser); + lex_mode_push_regexp(parser, lex_mode_incrementor(delimiter), lex_mode_terminator(delimiter)); + } else { + lex_mode_push_regexp(parser, '\0', '\0'); + } + + LEX(PM_TOKEN_REGEXP_BEGIN); + } + case 'q': { + parser->current.end++; + + if (parser->current.end < parser->end) { + const uint8_t delimiter = pm_lex_percent_delimiter(parser); + lex_mode_push_string(parser, false, false, lex_mode_incrementor(delimiter), lex_mode_terminator(delimiter)); + } else { + lex_mode_push_string_eof(parser); + } + + LEX(PM_TOKEN_STRING_BEGIN); + } + case 'Q': { + parser->current.end++; + + if (parser->current.end < parser->end) { + const uint8_t delimiter = pm_lex_percent_delimiter(parser); + lex_mode_push_string(parser, true, false, lex_mode_incrementor(delimiter), lex_mode_terminator(delimiter)); + } else { + lex_mode_push_string_eof(parser); + } + + LEX(PM_TOKEN_STRING_BEGIN); + } + case 's': { + parser->current.end++; + + if (parser->current.end < parser->end) { + const uint8_t delimiter = pm_lex_percent_delimiter(parser); + lex_mode_push_string(parser, false, false, lex_mode_incrementor(delimiter), lex_mode_terminator(delimiter)); + lex_state_set(parser, PM_LEX_STATE_FNAME | PM_LEX_STATE_FITEM); + } else { + lex_mode_push_string_eof(parser); + } + + LEX(PM_TOKEN_SYMBOL_BEGIN); + } + case 'w': { + parser->current.end++; + + if (parser->current.end < parser->end) { + lex_mode_push_list(parser, false, pm_lex_percent_delimiter(parser)); + } else { + lex_mode_push_list_eof(parser); + } + + LEX(PM_TOKEN_PERCENT_LOWER_W); + } + case 'W': { + parser->current.end++; + + if (parser->current.end < parser->end) { + lex_mode_push_list(parser, true, pm_lex_percent_delimiter(parser)); + } else { + lex_mode_push_list_eof(parser); + } + + LEX(PM_TOKEN_PERCENT_UPPER_W); + } + case 'x': { + parser->current.end++; + + if (parser->current.end < parser->end) { + const uint8_t delimiter = pm_lex_percent_delimiter(parser); + lex_mode_push_string(parser, true, false, lex_mode_incrementor(delimiter), lex_mode_terminator(delimiter)); + } else { + lex_mode_push_string_eof(parser); + } + + LEX(PM_TOKEN_PERCENT_LOWER_X); + } + default: + // If we get to this point, then we have a % that is completely + // unparsable. In this case we'll just drop it from the parser + // and skip past it and hope that the next token is something + // that we can parse. + pm_parser_err_current(parser, PM_ERR_INVALID_PERCENT); + goto lex_next_token; + } + } + + if (ambiguous_operator_p(parser, space_seen)) { + PM_PARSER_WARN_TOKEN_FORMAT(parser, parser->current, PM_WARN_AMBIGUOUS_BINARY_OPERATOR, "%", "string literal"); + } + + lex_state_set(parser, lex_state_operator_p(parser) ? PM_LEX_STATE_ARG : PM_LEX_STATE_BEG); + LEX(PM_TOKEN_PERCENT); + } + + // global variable + case '$': { + pm_token_type_t type = lex_global_variable(parser); + + // If we're lexing an embedded variable, then we need to pop back into + // the parent lex context. + if (parser->lex_modes.current->mode == PM_LEX_EMBVAR) { + lex_mode_pop(parser); + } + + lex_state_set(parser, PM_LEX_STATE_END); + LEX(type); + } + + // instance variable, class variable + case '@': + lex_state_set(parser, parser->lex_state & PM_LEX_STATE_FNAME ? PM_LEX_STATE_ENDFN : PM_LEX_STATE_END); + LEX(lex_at_variable(parser)); + + default: { + if (*parser->current.start != '_') { + size_t width = char_is_identifier_start(parser, parser->current.start, parser->end - parser->current.start); + + // If this isn't the beginning of an identifier, then + // it's an invalid token as we've exhausted all of the + // other options. We'll skip past it and return the next + // token after adding an appropriate error message. + if (!width) { + if (*parser->current.start >= 0x80) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_INVALID_MULTIBYTE_CHARACTER, *parser->current.start); + } else if (*parser->current.start == '\\') { + switch (peek_at(parser, parser->current.start + 1)) { + case ' ': + parser->current.end++; + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_UNEXPECTED_TOKEN_IGNORE, "escaped space"); + break; + case '\f': + parser->current.end++; + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_UNEXPECTED_TOKEN_IGNORE, "escaped form feed"); + break; + case '\t': + parser->current.end++; + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_UNEXPECTED_TOKEN_IGNORE, "escaped horizontal tab"); + break; + case '\v': + parser->current.end++; + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_UNEXPECTED_TOKEN_IGNORE, "escaped vertical tab"); + break; + case '\r': + if (peek_at(parser, parser->current.start + 2) != '\n') { + parser->current.end++; + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_UNEXPECTED_TOKEN_IGNORE, "escaped carriage return"); + break; + } + PRISM_FALLTHROUGH + default: + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_UNEXPECTED_TOKEN_IGNORE, "backslash"); + break; + } + } else if (char_is_ascii_printable(*parser->current.start)) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_INVALID_PRINTABLE_CHARACTER, *parser->current.start); + } else { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_INVALID_CHARACTER, *parser->current.start); + } + + goto lex_next_token; + } + + parser->current.end = parser->current.start + width; + } + + pm_token_type_t type = lex_identifier(parser, previous_command_start); + + // If we've hit a __END__ and it was at the start of the + // line or the start of the file and it is followed by + // either a \n or a \r\n, then this is the last token of the + // file. + if ( + ((parser->current.end - parser->current.start) == 7) && + current_token_starts_line(parser) && + (memcmp(parser->current.start, "__END__", 7) == 0) && + (parser->current.end == parser->end || match_eol(parser)) + ) { + // Since we know we're about to add an __END__ comment, + // we know we need to add all of the newlines to get the + // correct column information for it. + const uint8_t *cursor = parser->current.end; + while ((cursor = next_newline(cursor, parser->end - cursor)) != NULL) { + pm_newline_list_append(&parser->newline_list, cursor++); + } + + parser->current.end = parser->end; + parser->current.type = PM_TOKEN___END__; + parser_lex_callback(parser); + + parser->data_loc.start = parser->current.start; + parser->data_loc.end = parser->current.end; + + LEX(PM_TOKEN_EOF); + } + + pm_lex_state_t last_state = parser->lex_state; + + if (type == PM_TOKEN_IDENTIFIER || type == PM_TOKEN_CONSTANT || type == PM_TOKEN_METHOD_NAME) { + if (lex_state_p(parser, PM_LEX_STATE_BEG_ANY | PM_LEX_STATE_ARG_ANY | PM_LEX_STATE_DOT)) { + if (previous_command_start) { + lex_state_set(parser, PM_LEX_STATE_CMDARG); + } else { + lex_state_set(parser, PM_LEX_STATE_ARG); + } + } else if (parser->lex_state == PM_LEX_STATE_FNAME) { + lex_state_set(parser, PM_LEX_STATE_ENDFN); + } else { + lex_state_set(parser, PM_LEX_STATE_END); + } + } + + if ( + !(last_state & (PM_LEX_STATE_DOT | PM_LEX_STATE_FNAME)) && + (type == PM_TOKEN_IDENTIFIER) && + ((pm_parser_local_depth(parser, &parser->current) != -1) || + pm_token_is_numbered_parameter(parser->current.start, parser->current.end)) + ) { + lex_state_set(parser, PM_LEX_STATE_END | PM_LEX_STATE_LABEL); + } + + LEX(type); + } + } + } + case PM_LEX_LIST: { + if (parser->next_start != NULL) { + parser->current.end = parser->next_start; + parser->next_start = NULL; + } + + // First we'll set the beginning of the token. + parser->current.start = parser->current.end; + + // If there's any whitespace at the start of the list, then we're + // going to trim it off the beginning and create a new token. + size_t whitespace; + + if (parser->heredoc_end) { + whitespace = pm_strspn_inline_whitespace(parser->current.end, parser->end - parser->current.end); + if (peek_offset(parser, (ptrdiff_t)whitespace) == '\n') { + whitespace += 1; + } + } else { + whitespace = pm_strspn_whitespace_newlines(parser->current.end, parser->end - parser->current.end, &parser->newline_list); + } + + if (whitespace > 0) { + parser->current.end += whitespace; + if (peek_offset(parser, -1) == '\n') { + // mutates next_start + parser_flush_heredoc_end(parser); + } + LEX(PM_TOKEN_WORDS_SEP); + } + + // We'll check if we're at the end of the file. If we are, then we + // need to return the EOF token. + if (parser->current.end >= parser->end) { + LEX(PM_TOKEN_EOF); + } + + // Here we'll get a list of the places where strpbrk should break, + // and then find the first one. + pm_lex_mode_t *lex_mode = parser->lex_modes.current; + const uint8_t *breakpoints = lex_mode->as.list.breakpoints; + const uint8_t *breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, true); + + // If we haven't found an escape yet, then this buffer will be + // unallocated since we can refer directly to the source string. + pm_token_buffer_t token_buffer = { 0 }; + + while (breakpoint != NULL) { + // If we hit whitespace, then we must have received content by + // now, so we can return an element of the list. + if (pm_char_is_whitespace(*breakpoint)) { + parser->current.end = breakpoint; + pm_token_buffer_flush(parser, &token_buffer); + LEX(PM_TOKEN_STRING_CONTENT); + } + + // If we hit the terminator, we need to check which token to + // return. + if (*breakpoint == lex_mode->as.list.terminator) { + // If this terminator doesn't actually close the list, then + // we need to continue on past it. + if (lex_mode->as.list.nesting > 0) { + parser->current.end = breakpoint + 1; + breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, true); + lex_mode->as.list.nesting--; + continue; + } + + // If we've hit the terminator and we've already skipped + // past content, then we can return a list node. + if (breakpoint > parser->current.start) { + parser->current.end = breakpoint; + pm_token_buffer_flush(parser, &token_buffer); + LEX(PM_TOKEN_STRING_CONTENT); + } + + // Otherwise, switch back to the default state and return + // the end of the list. + parser->current.end = breakpoint + 1; + lex_mode_pop(parser); + lex_state_set(parser, PM_LEX_STATE_END); + LEX(PM_TOKEN_STRING_END); + } + + // If we hit a null byte, skip directly past it. + if (*breakpoint == '\0') { + breakpoint = pm_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1), true); + continue; + } + + // If we hit escapes, then we need to treat the next token + // literally. In this case we'll skip past the next character + // and find the next breakpoint. + if (*breakpoint == '\\') { + parser->current.end = breakpoint + 1; + + // If we've hit the end of the file, then break out of the + // loop by setting the breakpoint to NULL. + if (parser->current.end == parser->end) { + breakpoint = NULL; + continue; + } + + pm_token_buffer_escape(parser, &token_buffer); + uint8_t peeked = peek(parser); + + switch (peeked) { + case ' ': + case '\f': + case '\t': + case '\v': + case '\\': + pm_token_buffer_push_byte(&token_buffer, peeked); + parser->current.end++; + break; + case '\r': + parser->current.end++; + if (peek(parser) != '\n') { + pm_token_buffer_push_byte(&token_buffer, '\r'); + break; + } + PRISM_FALLTHROUGH + case '\n': + pm_token_buffer_push_byte(&token_buffer, '\n'); + + if (parser->heredoc_end) { + // ... if we are on the same line as a heredoc, + // flush the heredoc and continue parsing after + // heredoc_end. + parser_flush_heredoc_end(parser); + pm_token_buffer_copy(parser, &token_buffer); + LEX(PM_TOKEN_STRING_CONTENT); + } else { + // ... else track the newline. + pm_newline_list_append(&parser->newline_list, parser->current.end); + } + + parser->current.end++; + break; + default: + if (peeked == lex_mode->as.list.incrementor || peeked == lex_mode->as.list.terminator) { + pm_token_buffer_push_byte(&token_buffer, peeked); + parser->current.end++; + } else if (lex_mode->as.list.interpolation) { + escape_read(parser, &token_buffer.buffer, NULL, PM_ESCAPE_FLAG_NONE); + } else { + pm_token_buffer_push_byte(&token_buffer, '\\'); + pm_token_buffer_push_escaped(&token_buffer, parser); + } + + break; + } + + token_buffer.cursor = parser->current.end; + breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, true); + continue; + } + + // If we hit a #, then we will attempt to lex interpolation. + if (*breakpoint == '#') { + pm_token_type_t type = lex_interpolation(parser, breakpoint); + + if (type == PM_TOKEN_NOT_PROVIDED) { + // If we haven't returned at this point then we had something + // that looked like an interpolated class or instance variable + // like "#@" but wasn't actually. In this case we'll just skip + // to the next breakpoint. + breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, true); + continue; + } + + if (type == PM_TOKEN_STRING_CONTENT) { + pm_token_buffer_flush(parser, &token_buffer); + } + + LEX(type); + } + + // If we've hit the incrementor, then we need to skip past it + // and find the next breakpoint. + assert(*breakpoint == lex_mode->as.list.incrementor); + parser->current.end = breakpoint + 1; + breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, true); + lex_mode->as.list.nesting++; + continue; + } + + if (parser->current.end > parser->current.start) { + pm_token_buffer_flush(parser, &token_buffer); + LEX(PM_TOKEN_STRING_CONTENT); + } + + // If we were unable to find a breakpoint, then this token hits the + // end of the file. + parser->current.end = parser->end; + pm_token_buffer_flush(parser, &token_buffer); + LEX(PM_TOKEN_STRING_CONTENT); + } + case PM_LEX_REGEXP: { + // First, we'll set to start of this token to be the current end. + if (parser->next_start == NULL) { + parser->current.start = parser->current.end; + } else { + parser->current.start = parser->next_start; + parser->current.end = parser->next_start; + parser->next_start = NULL; + } + + // We'll check if we're at the end of the file. If we are, then we + // need to return the EOF token. + if (parser->current.end >= parser->end) { + LEX(PM_TOKEN_EOF); + } + + // Get a reference to the current mode. + pm_lex_mode_t *lex_mode = parser->lex_modes.current; + + // These are the places where we need to split up the content of the + // regular expression. We'll use strpbrk to find the first of these + // characters. + const uint8_t *breakpoints = lex_mode->as.regexp.breakpoints; + const uint8_t *breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, false); + pm_regexp_token_buffer_t token_buffer = { 0 }; + + while (breakpoint != NULL) { + uint8_t term = lex_mode->as.regexp.terminator; + bool is_terminator = (*breakpoint == term); + + // If the terminator is newline, we need to consider \r\n _also_ a newline + // For example: `%\nfoo\r\n` + // The string should be "foo", not "foo\r" + if (*breakpoint == '\r' && peek_at(parser, breakpoint + 1) == '\n') { + if (term == '\n') { + is_terminator = true; + } + + // If the terminator is a CR, but we see a CRLF, we need to + // treat the CRLF as a newline, meaning this is _not_ the + // terminator + if (term == '\r') { + is_terminator = false; + } + } + + // If we hit the terminator, we need to determine what kind of + // token to return. + if (is_terminator) { + if (lex_mode->as.regexp.nesting > 0) { + parser->current.end = breakpoint + 1; + breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, false); + lex_mode->as.regexp.nesting--; + continue; + } + + // Here we've hit the terminator. If we have already consumed + // content then we need to return that content as string content + // first. + if (breakpoint > parser->current.start) { + parser->current.end = breakpoint; + pm_regexp_token_buffer_flush(parser, &token_buffer); + LEX(PM_TOKEN_STRING_CONTENT); + } + + // Check here if we need to track the newline. + size_t eol_length = match_eol_at(parser, breakpoint); + if (eol_length) { + parser->current.end = breakpoint + eol_length; + pm_newline_list_append(&parser->newline_list, parser->current.end - 1); + } else { + parser->current.end = breakpoint + 1; + } + + // Since we've hit the terminator of the regular expression, + // we now need to parse the options. + parser->current.end += pm_strspn_regexp_option(parser->current.end, parser->end - parser->current.end); + + lex_mode_pop(parser); + lex_state_set(parser, PM_LEX_STATE_END); + LEX(PM_TOKEN_REGEXP_END); + } + + // If we've hit the incrementor, then we need to skip past it + // and find the next breakpoint. + if (*breakpoint && *breakpoint == lex_mode->as.regexp.incrementor) { + parser->current.end = breakpoint + 1; + breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, false); + lex_mode->as.regexp.nesting++; + continue; + } + + switch (*breakpoint) { + case '\0': + // If we hit a null byte, skip directly past it. + parser->current.end = breakpoint + 1; + breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, false); + break; + case '\r': + if (peek_at(parser, breakpoint + 1) != '\n') { + parser->current.end = breakpoint + 1; + breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, false); + break; + } + + breakpoint++; + parser->current.end = breakpoint; + pm_regexp_token_buffer_escape(parser, &token_buffer); + token_buffer.base.cursor = breakpoint; + + PRISM_FALLTHROUGH + case '\n': + // If we've hit a newline, then we need to track that in + // the list of newlines. + if (parser->heredoc_end == NULL) { + pm_newline_list_append(&parser->newline_list, breakpoint); + parser->current.end = breakpoint + 1; + breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, false); + break; + } + + parser->current.end = breakpoint + 1; + parser_flush_heredoc_end(parser); + pm_regexp_token_buffer_flush(parser, &token_buffer); + LEX(PM_TOKEN_STRING_CONTENT); + case '\\': { + // If we hit escapes, then we need to treat the next + // token literally. In this case we'll skip past the + // next character and find the next breakpoint. + parser->current.end = breakpoint + 1; + + // If we've hit the end of the file, then break out of + // the loop by setting the breakpoint to NULL. + if (parser->current.end == parser->end) { + breakpoint = NULL; + break; + } + + pm_regexp_token_buffer_escape(parser, &token_buffer); + uint8_t peeked = peek(parser); + + switch (peeked) { + case '\r': + parser->current.end++; + if (peek(parser) != '\n') { + if (lex_mode->as.regexp.terminator != '\r') { + pm_token_buffer_push_byte(&token_buffer.base, '\\'); + } + pm_regexp_token_buffer_push_byte(&token_buffer, '\r'); + pm_token_buffer_push_byte(&token_buffer.base, '\r'); + break; + } + PRISM_FALLTHROUGH + case '\n': + if (parser->heredoc_end) { + // ... if we are on the same line as a heredoc, + // flush the heredoc and continue parsing after + // heredoc_end. + parser_flush_heredoc_end(parser); + pm_regexp_token_buffer_copy(parser, &token_buffer); + LEX(PM_TOKEN_STRING_CONTENT); + } else { + // ... else track the newline. + pm_newline_list_append(&parser->newline_list, parser->current.end); + } + + parser->current.end++; + break; + case 'c': + case 'C': + case 'M': + case 'u': + case 'x': + escape_read(parser, &token_buffer.regexp_buffer, &token_buffer.base.buffer, PM_ESCAPE_FLAG_REGEXP); + break; + default: + if (lex_mode->as.regexp.terminator == peeked) { + // Some characters when they are used as the + // terminator also receive an escape. They are + // enumerated here. + switch (peeked) { + case '$': case ')': case '*': case '+': + case '.': case '>': case '?': case ']': + case '^': case '|': case '}': + pm_token_buffer_push_byte(&token_buffer.base, '\\'); + break; + default: + break; + } + + pm_regexp_token_buffer_push_byte(&token_buffer, peeked); + pm_token_buffer_push_byte(&token_buffer.base, peeked); + parser->current.end++; + break; + } + + if (peeked < 0x80) pm_token_buffer_push_byte(&token_buffer.base, '\\'); + pm_regexp_token_buffer_push_escaped(&token_buffer, parser); + break; + } + + token_buffer.base.cursor = parser->current.end; + breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, false); + break; + } + case '#': { + // If we hit a #, then we will attempt to lex + // interpolation. + pm_token_type_t type = lex_interpolation(parser, breakpoint); + + if (type == PM_TOKEN_NOT_PROVIDED) { + // If we haven't returned at this point then we had + // something that looked like an interpolated class or + // instance variable like "#@" but wasn't actually. In + // this case we'll just skip to the next breakpoint. + breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, false); + break; + } + + if (type == PM_TOKEN_STRING_CONTENT) { + pm_regexp_token_buffer_flush(parser, &token_buffer); + } + + LEX(type); + } + default: + assert(false && "unreachable"); + break; + } + } + + if (parser->current.end > parser->current.start) { + pm_regexp_token_buffer_flush(parser, &token_buffer); + LEX(PM_TOKEN_STRING_CONTENT); + } + + // If we were unable to find a breakpoint, then this token hits the + // end of the file. + parser->current.end = parser->end; + pm_regexp_token_buffer_flush(parser, &token_buffer); + LEX(PM_TOKEN_STRING_CONTENT); + } + case PM_LEX_STRING: { + // First, we'll set to start of this token to be the current end. + if (parser->next_start == NULL) { + parser->current.start = parser->current.end; + } else { + parser->current.start = parser->next_start; + parser->current.end = parser->next_start; + parser->next_start = NULL; + } + + // We'll check if we're at the end of the file. If we are, then we need to + // return the EOF token. + if (parser->current.end >= parser->end) { + LEX(PM_TOKEN_EOF); + } + + // These are the places where we need to split up the content of the + // string. We'll use strpbrk to find the first of these characters. + pm_lex_mode_t *lex_mode = parser->lex_modes.current; + const uint8_t *breakpoints = lex_mode->as.string.breakpoints; + const uint8_t *breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, true); + + // If we haven't found an escape yet, then this buffer will be + // unallocated since we can refer directly to the source string. + pm_token_buffer_t token_buffer = { 0 }; + + while (breakpoint != NULL) { + // If we hit the incrementor, then we'll increment then nesting and + // continue lexing. + if (lex_mode->as.string.incrementor != '\0' && *breakpoint == lex_mode->as.string.incrementor) { + lex_mode->as.string.nesting++; + parser->current.end = breakpoint + 1; + breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, true); + continue; + } + + uint8_t term = lex_mode->as.string.terminator; + bool is_terminator = (*breakpoint == term); + + // If the terminator is newline, we need to consider \r\n _also_ a newline + // For example: `%r\nfoo\r\n` + // The string should be /foo/, not /foo\r/ + if (*breakpoint == '\r' && peek_at(parser, breakpoint + 1) == '\n') { + if (term == '\n') { + is_terminator = true; + } + + // If the terminator is a CR, but we see a CRLF, we need to + // treat the CRLF as a newline, meaning this is _not_ the + // terminator + if (term == '\r') { + is_terminator = false; + } + } + + // Note that we have to check the terminator here first because we could + // potentially be parsing a % string that has a # character as the + // terminator. + if (is_terminator) { + // If this terminator doesn't actually close the string, then we need + // to continue on past it. + if (lex_mode->as.string.nesting > 0) { + parser->current.end = breakpoint + 1; + breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, true); + lex_mode->as.string.nesting--; + continue; + } + + // Here we've hit the terminator. If we have already consumed content + // then we need to return that content as string content first. + if (breakpoint > parser->current.start) { + parser->current.end = breakpoint; + pm_token_buffer_flush(parser, &token_buffer); + LEX(PM_TOKEN_STRING_CONTENT); + } + + // Otherwise we need to switch back to the parent lex mode and + // return the end of the string. + size_t eol_length = match_eol_at(parser, breakpoint); + if (eol_length) { + parser->current.end = breakpoint + eol_length; + pm_newline_list_append(&parser->newline_list, parser->current.end - 1); + } else { + parser->current.end = breakpoint + 1; + } + + if (lex_mode->as.string.label_allowed && (peek(parser) == ':') && (peek_offset(parser, 1) != ':')) { + parser->current.end++; + lex_state_set(parser, PM_LEX_STATE_ARG | PM_LEX_STATE_LABELED); + lex_mode_pop(parser); + LEX(PM_TOKEN_LABEL_END); + } + + lex_state_set(parser, PM_LEX_STATE_END); + lex_mode_pop(parser); + LEX(PM_TOKEN_STRING_END); + } + + switch (*breakpoint) { + case '\0': + // Skip directly past the null character. + parser->current.end = breakpoint + 1; + breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, true); + break; + case '\r': + if (peek_at(parser, breakpoint + 1) != '\n') { + parser->current.end = breakpoint + 1; + breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, true); + break; + } + + // If we hit a \r\n sequence, then we need to treat it + // as a newline. + breakpoint++; + parser->current.end = breakpoint; + pm_token_buffer_escape(parser, &token_buffer); + token_buffer.cursor = breakpoint; + + PRISM_FALLTHROUGH + case '\n': + // When we hit a newline, we need to flush any potential + // heredocs. Note that this has to happen after we check + // for the terminator in case the terminator is a + // newline character. + if (parser->heredoc_end == NULL) { + pm_newline_list_append(&parser->newline_list, breakpoint); + parser->current.end = breakpoint + 1; + breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, true); + break; + } + + parser->current.end = breakpoint + 1; + parser_flush_heredoc_end(parser); + pm_token_buffer_flush(parser, &token_buffer); + LEX(PM_TOKEN_STRING_CONTENT); + case '\\': { + // Here we hit escapes. + parser->current.end = breakpoint + 1; + + // If we've hit the end of the file, then break out of + // the loop by setting the breakpoint to NULL. + if (parser->current.end == parser->end) { + breakpoint = NULL; + continue; + } + + pm_token_buffer_escape(parser, &token_buffer); + uint8_t peeked = peek(parser); + + switch (peeked) { + case '\\': + pm_token_buffer_push_byte(&token_buffer, '\\'); + parser->current.end++; + break; + case '\r': + parser->current.end++; + if (peek(parser) != '\n') { + if (!lex_mode->as.string.interpolation) { + pm_token_buffer_push_byte(&token_buffer, '\\'); + } + pm_token_buffer_push_byte(&token_buffer, '\r'); + break; + } + PRISM_FALLTHROUGH + case '\n': + if (!lex_mode->as.string.interpolation) { + pm_token_buffer_push_byte(&token_buffer, '\\'); + pm_token_buffer_push_byte(&token_buffer, '\n'); + } + + if (parser->heredoc_end) { + // ... if we are on the same line as a heredoc, + // flush the heredoc and continue parsing after + // heredoc_end. + parser_flush_heredoc_end(parser); + pm_token_buffer_copy(parser, &token_buffer); + LEX(PM_TOKEN_STRING_CONTENT); + } else { + // ... else track the newline. + pm_newline_list_append(&parser->newline_list, parser->current.end); + } + + parser->current.end++; + break; + default: + if (lex_mode->as.string.incrementor != '\0' && peeked == lex_mode->as.string.incrementor) { + pm_token_buffer_push_byte(&token_buffer, peeked); + parser->current.end++; + } else if (lex_mode->as.string.terminator != '\0' && peeked == lex_mode->as.string.terminator) { + pm_token_buffer_push_byte(&token_buffer, peeked); + parser->current.end++; + } else if (lex_mode->as.string.interpolation) { + escape_read(parser, &token_buffer.buffer, NULL, PM_ESCAPE_FLAG_NONE); + } else { + pm_token_buffer_push_byte(&token_buffer, '\\'); + pm_token_buffer_push_escaped(&token_buffer, parser); + } + + break; + } + + token_buffer.cursor = parser->current.end; + breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, true); + break; + } + case '#': { + pm_token_type_t type = lex_interpolation(parser, breakpoint); + + if (type == PM_TOKEN_NOT_PROVIDED) { + // If we haven't returned at this point then we had something that + // looked like an interpolated class or instance variable like "#@" + // but wasn't actually. In this case we'll just skip to the next + // breakpoint. + breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, true); + break; + } + + if (type == PM_TOKEN_STRING_CONTENT) { + pm_token_buffer_flush(parser, &token_buffer); + } + + LEX(type); + } + default: + assert(false && "unreachable"); + } + } + + if (parser->current.end > parser->current.start) { + pm_token_buffer_flush(parser, &token_buffer); + LEX(PM_TOKEN_STRING_CONTENT); + } + + // If we've hit the end of the string, then this is an unterminated + // string. In that case we'll return a string content token. + parser->current.end = parser->end; + pm_token_buffer_flush(parser, &token_buffer); + LEX(PM_TOKEN_STRING_CONTENT); + } + case PM_LEX_HEREDOC: { + // First, we'll set to start of this token. + if (parser->next_start == NULL) { + parser->current.start = parser->current.end; + } else { + parser->current.start = parser->next_start; + parser->current.end = parser->next_start; + parser->heredoc_end = NULL; + parser->next_start = NULL; + } + + // Now let's grab the information about the identifier off of the + // current lex mode. + pm_lex_mode_t *lex_mode = parser->lex_modes.current; + pm_heredoc_lex_mode_t *heredoc_lex_mode = &lex_mode->as.heredoc.base; + + bool line_continuation = lex_mode->as.heredoc.line_continuation; + lex_mode->as.heredoc.line_continuation = false; + + // We'll check if we're at the end of the file. If we are, then we + // will add an error (because we weren't able to find the + // terminator) but still continue parsing so that content after the + // declaration of the heredoc can be parsed. + if (parser->current.end >= parser->end) { + pm_parser_err_heredoc_term(parser, heredoc_lex_mode->ident_start, heredoc_lex_mode->ident_length); + parser->next_start = lex_mode->as.heredoc.next_start; + parser->heredoc_end = parser->current.end; + lex_state_set(parser, PM_LEX_STATE_END); + lex_mode_pop(parser); + LEX(PM_TOKEN_HEREDOC_END); + } + + const uint8_t *ident_start = heredoc_lex_mode->ident_start; + size_t ident_length = heredoc_lex_mode->ident_length; + + // If we are immediately following a newline and we have hit the + // terminator, then we need to return the ending of the heredoc. + if (current_token_starts_line(parser)) { + const uint8_t *start = parser->current.start; + + if (!line_continuation && (start + ident_length <= parser->end)) { + const uint8_t *newline = next_newline(start, parser->end - start); + const uint8_t *ident_end = newline; + const uint8_t *terminator_end = newline; + + if (newline == NULL) { + terminator_end = parser->end; + ident_end = parser->end; + } else { + terminator_end++; + if (newline[-1] == '\r') { + ident_end--; // Remove \r + } + } + + const uint8_t *terminator_start = ident_end - ident_length; + const uint8_t *cursor = start; + + if (heredoc_lex_mode->indent == PM_HEREDOC_INDENT_DASH || heredoc_lex_mode->indent == PM_HEREDOC_INDENT_TILDE) { + while (cursor < terminator_start && pm_char_is_inline_whitespace(*cursor)) { + cursor++; + } + } + + if ( + (cursor == terminator_start) && + (memcmp(terminator_start, ident_start, ident_length) == 0) + ) { + if (newline != NULL) { + pm_newline_list_append(&parser->newline_list, newline); + } + + parser->current.end = terminator_end; + if (*lex_mode->as.heredoc.next_start == '\\') { + parser->next_start = NULL; + } else { + parser->next_start = lex_mode->as.heredoc.next_start; + parser->heredoc_end = parser->current.end; + } + + lex_state_set(parser, PM_LEX_STATE_END); + lex_mode_pop(parser); + LEX(PM_TOKEN_HEREDOC_END); + } + } + + size_t whitespace = pm_heredoc_strspn_inline_whitespace(parser, &start, heredoc_lex_mode->indent); + if ( + heredoc_lex_mode->indent == PM_HEREDOC_INDENT_TILDE && + lex_mode->as.heredoc.common_whitespace != NULL && + (*lex_mode->as.heredoc.common_whitespace > whitespace) && + peek_at(parser, start) != '\n' + ) { + *lex_mode->as.heredoc.common_whitespace = whitespace; + } + } + + // Otherwise we'll be parsing string content. These are the places + // where we need to split up the content of the heredoc. We'll use + // strpbrk to find the first of these characters. + uint8_t breakpoints[] = "\r\n\\#"; + + pm_heredoc_quote_t quote = heredoc_lex_mode->quote; + if (quote == PM_HEREDOC_QUOTE_SINGLE) { + breakpoints[3] = '\0'; + } + + const uint8_t *breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, true); + pm_token_buffer_t token_buffer = { 0 }; + bool was_line_continuation = false; + + while (breakpoint != NULL) { + switch (*breakpoint) { + case '\0': + // Skip directly past the null character. + parser->current.end = breakpoint + 1; + breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, true); + break; + case '\r': + parser->current.end = breakpoint + 1; + + if (peek_at(parser, breakpoint + 1) != '\n') { + breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, true); + break; + } + + // If we hit a \r\n sequence, then we want to replace it + // with a single \n character in the final string. + breakpoint++; + pm_token_buffer_escape(parser, &token_buffer); + token_buffer.cursor = breakpoint; + + PRISM_FALLTHROUGH + case '\n': { + if (parser->heredoc_end != NULL && (parser->heredoc_end > breakpoint)) { + parser_flush_heredoc_end(parser); + parser->current.end = breakpoint + 1; + pm_token_buffer_flush(parser, &token_buffer); + LEX(PM_TOKEN_STRING_CONTENT); + } + + pm_newline_list_append(&parser->newline_list, breakpoint); + + // If we have a - or ~ heredoc, then we can match after + // some leading whitespace. + const uint8_t *start = breakpoint + 1; + + if (!was_line_continuation && (start + ident_length <= parser->end)) { + // We want to match the terminator starting from the end of the line in case + // there is whitespace in the ident such as <<-' DOC' or <<~' DOC'. + const uint8_t *newline = next_newline(start, parser->end - start); + + if (newline == NULL) { + newline = parser->end; + } else if (newline[-1] == '\r') { + newline--; // Remove \r + } + + // Start of a possible terminator. + const uint8_t *terminator_start = newline - ident_length; + + // Cursor to check for the leading whitespace. We skip the + // leading whitespace if we have a - or ~ heredoc. + const uint8_t *cursor = start; + + if (heredoc_lex_mode->indent == PM_HEREDOC_INDENT_DASH || heredoc_lex_mode->indent == PM_HEREDOC_INDENT_TILDE) { + while (cursor < terminator_start && pm_char_is_inline_whitespace(*cursor)) { + cursor++; + } + } + + if ( + cursor == terminator_start && + (memcmp(terminator_start, ident_start, ident_length) == 0) + ) { + parser->current.end = breakpoint + 1; + pm_token_buffer_flush(parser, &token_buffer); + LEX(PM_TOKEN_STRING_CONTENT); + } + } + + size_t whitespace = pm_heredoc_strspn_inline_whitespace(parser, &start, lex_mode->as.heredoc.base.indent); + + // If we have hit a newline that is followed by a valid + // terminator, then we need to return the content of the + // heredoc here as string content. Then, the next time a + // token is lexed, it will match again and return the + // end of the heredoc. + if (lex_mode->as.heredoc.base.indent == PM_HEREDOC_INDENT_TILDE) { + if ((lex_mode->as.heredoc.common_whitespace != NULL) && (*lex_mode->as.heredoc.common_whitespace > whitespace) && peek_at(parser, start) != '\n') { + *lex_mode->as.heredoc.common_whitespace = whitespace; + } + + parser->current.end = breakpoint + 1; + pm_token_buffer_flush(parser, &token_buffer); + LEX(PM_TOKEN_STRING_CONTENT); + } + + // Otherwise we hit a newline and it wasn't followed by + // a terminator, so we can continue parsing. + parser->current.end = breakpoint + 1; + breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, true); + break; + } + case '\\': { + // If we hit an escape, then we need to skip past + // however many characters the escape takes up. However + // it's important that if \n or \r\n are escaped, we + // stop looping before the newline and not after the + // newline so that we can still potentially find the + // terminator of the heredoc. + parser->current.end = breakpoint + 1; + + // If we've hit the end of the file, then break out of + // the loop by setting the breakpoint to NULL. + if (parser->current.end == parser->end) { + breakpoint = NULL; + continue; + } + + pm_token_buffer_escape(parser, &token_buffer); + uint8_t peeked = peek(parser); + + if (quote == PM_HEREDOC_QUOTE_SINGLE) { + switch (peeked) { + case '\r': + parser->current.end++; + if (peek(parser) != '\n') { + pm_token_buffer_push_byte(&token_buffer, '\\'); + pm_token_buffer_push_byte(&token_buffer, '\r'); + break; + } + PRISM_FALLTHROUGH + case '\n': + pm_token_buffer_push_byte(&token_buffer, '\\'); + pm_token_buffer_push_byte(&token_buffer, '\n'); + token_buffer.cursor = parser->current.end + 1; + breakpoint = parser->current.end; + continue; + default: + pm_token_buffer_push_byte(&token_buffer, '\\'); + pm_token_buffer_push_escaped(&token_buffer, parser); + break; + } + } else { + switch (peeked) { + case '\r': + parser->current.end++; + if (peek(parser) != '\n') { + pm_token_buffer_push_byte(&token_buffer, '\r'); + break; + } + PRISM_FALLTHROUGH + case '\n': + // If we are in a tilde here, we should + // break out of the loop and return the + // string content. + if (heredoc_lex_mode->indent == PM_HEREDOC_INDENT_TILDE) { + const uint8_t *end = parser->current.end; + pm_newline_list_append(&parser->newline_list, end); + + // Here we want the buffer to only + // include up to the backslash. + parser->current.end = breakpoint; + pm_token_buffer_flush(parser, &token_buffer); + + // Now we can advance the end of the + // token past the newline. + parser->current.end = end + 1; + lex_mode->as.heredoc.line_continuation = true; + LEX(PM_TOKEN_STRING_CONTENT); + } + + was_line_continuation = true; + token_buffer.cursor = parser->current.end + 1; + breakpoint = parser->current.end; + continue; + default: + escape_read(parser, &token_buffer.buffer, NULL, PM_ESCAPE_FLAG_NONE); + break; + } + } + + token_buffer.cursor = parser->current.end; + breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, true); + break; + } + case '#': { + pm_token_type_t type = lex_interpolation(parser, breakpoint); + + if (type == PM_TOKEN_NOT_PROVIDED) { + // If we haven't returned at this point then we had + // something that looked like an interpolated class + // or instance variable like "#@" but wasn't + // actually. In this case we'll just skip to the + // next breakpoint. + breakpoint = pm_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end, true); + break; + } + + if (type == PM_TOKEN_STRING_CONTENT) { + pm_token_buffer_flush(parser, &token_buffer); + } + + LEX(type); + } + default: + assert(false && "unreachable"); + } + + was_line_continuation = false; + } + + if (parser->current.end > parser->current.start) { + parser->current.end = parser->end; + pm_token_buffer_flush(parser, &token_buffer); + LEX(PM_TOKEN_STRING_CONTENT); + } + + // If we've hit the end of the string, then this is an unterminated + // heredoc. In that case we'll return a string content token. + parser->current.end = parser->end; + pm_token_buffer_flush(parser, &token_buffer); + LEX(PM_TOKEN_STRING_CONTENT); + } + } + + assert(false && "unreachable"); +} + +#undef LEX + +/******************************************************************************/ +/* Parse functions */ +/******************************************************************************/ + +/** + * These are the various precedence rules. Because we are using a Pratt parser, + * they are named binding power to represent the manner in which nodes are bound + * together in the stack. + * + * We increment by 2 because we want to leave room for the infix operators to + * specify their associativity by adding or subtracting one. + */ +typedef enum { + PM_BINDING_POWER_UNSET = 0, // used to indicate this token cannot be used as an infix operator + PM_BINDING_POWER_STATEMENT = 2, + PM_BINDING_POWER_MODIFIER_RESCUE = 4, // rescue + PM_BINDING_POWER_MODIFIER = 6, // if unless until while + PM_BINDING_POWER_COMPOSITION = 8, // and or + PM_BINDING_POWER_NOT = 10, // not + PM_BINDING_POWER_MATCH = 12, // => in + PM_BINDING_POWER_DEFINED = 14, // defined? + PM_BINDING_POWER_MULTI_ASSIGNMENT = 16, // = + PM_BINDING_POWER_ASSIGNMENT = 18, // = += -= *= /= %= &= |= ^= &&= ||= <<= >>= **= + PM_BINDING_POWER_TERNARY = 20, // ?: + PM_BINDING_POWER_RANGE = 22, // .. ... + PM_BINDING_POWER_LOGICAL_OR = 24, // || + PM_BINDING_POWER_LOGICAL_AND = 26, // && + PM_BINDING_POWER_EQUALITY = 28, // <=> == === != =~ !~ + PM_BINDING_POWER_COMPARISON = 30, // > >= < <= + PM_BINDING_POWER_BITWISE_OR = 32, // | ^ + PM_BINDING_POWER_BITWISE_AND = 34, // & + PM_BINDING_POWER_SHIFT = 36, // << >> + PM_BINDING_POWER_TERM = 38, // + - + PM_BINDING_POWER_FACTOR = 40, // * / % + PM_BINDING_POWER_UMINUS = 42, // -@ + PM_BINDING_POWER_EXPONENT = 44, // ** + PM_BINDING_POWER_UNARY = 46, // ! ~ +@ + PM_BINDING_POWER_INDEX = 48, // [] []= + PM_BINDING_POWER_CALL = 50, // :: . + PM_BINDING_POWER_MAX = 52 +} pm_binding_power_t; + +/** + * This struct represents a set of binding powers used for a given token. They + * are combined in this way to make it easier to represent associativity. + */ +typedef struct { + /** The left binding power. */ + pm_binding_power_t left; + + /** The right binding power. */ + pm_binding_power_t right; + + /** Whether or not this token can be used as a binary operator. */ + bool binary; + + /** + * Whether or not this token can be used as non-associative binary operator. + * Non-associative operators (e.g. in and =>) need special treatment in parse_expression. + */ + bool nonassoc; +} pm_binding_powers_t; + +#define BINDING_POWER_ASSIGNMENT { PM_BINDING_POWER_UNARY, PM_BINDING_POWER_ASSIGNMENT, true, false } +#define LEFT_ASSOCIATIVE(precedence) { precedence, precedence + 1, true, false } +#define RIGHT_ASSOCIATIVE(precedence) { precedence, precedence, true, false } +#define NON_ASSOCIATIVE(precedence) { precedence, precedence + 1, true, true } +#define RIGHT_ASSOCIATIVE_UNARY(precedence) { precedence, precedence, false, false } + +pm_binding_powers_t pm_binding_powers[PM_TOKEN_MAXIMUM] = { + // rescue + [PM_TOKEN_KEYWORD_RESCUE_MODIFIER] = { PM_BINDING_POWER_MODIFIER_RESCUE, PM_BINDING_POWER_COMPOSITION, true, false }, + + // if unless until while + [PM_TOKEN_KEYWORD_IF_MODIFIER] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_MODIFIER), + [PM_TOKEN_KEYWORD_UNLESS_MODIFIER] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_MODIFIER), + [PM_TOKEN_KEYWORD_UNTIL_MODIFIER] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_MODIFIER), + [PM_TOKEN_KEYWORD_WHILE_MODIFIER] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_MODIFIER), + + // and or + [PM_TOKEN_KEYWORD_AND] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_COMPOSITION), + [PM_TOKEN_KEYWORD_OR] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_COMPOSITION), + + // => in + [PM_TOKEN_EQUAL_GREATER] = NON_ASSOCIATIVE(PM_BINDING_POWER_MATCH), + [PM_TOKEN_KEYWORD_IN] = NON_ASSOCIATIVE(PM_BINDING_POWER_MATCH), + + // &&= &= ^= = >>= <<= -= %= |= ||= += /= *= **= + [PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL] = BINDING_POWER_ASSIGNMENT, + [PM_TOKEN_AMPERSAND_EQUAL] = BINDING_POWER_ASSIGNMENT, + [PM_TOKEN_CARET_EQUAL] = BINDING_POWER_ASSIGNMENT, + [PM_TOKEN_EQUAL] = BINDING_POWER_ASSIGNMENT, + [PM_TOKEN_GREATER_GREATER_EQUAL] = BINDING_POWER_ASSIGNMENT, + [PM_TOKEN_LESS_LESS_EQUAL] = BINDING_POWER_ASSIGNMENT, + [PM_TOKEN_MINUS_EQUAL] = BINDING_POWER_ASSIGNMENT, + [PM_TOKEN_PERCENT_EQUAL] = BINDING_POWER_ASSIGNMENT, + [PM_TOKEN_PIPE_EQUAL] = BINDING_POWER_ASSIGNMENT, + [PM_TOKEN_PIPE_PIPE_EQUAL] = BINDING_POWER_ASSIGNMENT, + [PM_TOKEN_PLUS_EQUAL] = BINDING_POWER_ASSIGNMENT, + [PM_TOKEN_SLASH_EQUAL] = BINDING_POWER_ASSIGNMENT, + [PM_TOKEN_STAR_EQUAL] = BINDING_POWER_ASSIGNMENT, + [PM_TOKEN_STAR_STAR_EQUAL] = BINDING_POWER_ASSIGNMENT, + + // ?: + [PM_TOKEN_QUESTION_MARK] = RIGHT_ASSOCIATIVE(PM_BINDING_POWER_TERNARY), + + // .. ... + [PM_TOKEN_DOT_DOT] = NON_ASSOCIATIVE(PM_BINDING_POWER_RANGE), + [PM_TOKEN_DOT_DOT_DOT] = NON_ASSOCIATIVE(PM_BINDING_POWER_RANGE), + [PM_TOKEN_UDOT_DOT] = RIGHT_ASSOCIATIVE_UNARY(PM_BINDING_POWER_LOGICAL_OR), + [PM_TOKEN_UDOT_DOT_DOT] = RIGHT_ASSOCIATIVE_UNARY(PM_BINDING_POWER_LOGICAL_OR), + + // || + [PM_TOKEN_PIPE_PIPE] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_LOGICAL_OR), + + // && + [PM_TOKEN_AMPERSAND_AMPERSAND] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_LOGICAL_AND), + + // != !~ == === =~ <=> + [PM_TOKEN_BANG_EQUAL] = NON_ASSOCIATIVE(PM_BINDING_POWER_EQUALITY), + [PM_TOKEN_BANG_TILDE] = NON_ASSOCIATIVE(PM_BINDING_POWER_EQUALITY), + [PM_TOKEN_EQUAL_EQUAL] = NON_ASSOCIATIVE(PM_BINDING_POWER_EQUALITY), + [PM_TOKEN_EQUAL_EQUAL_EQUAL] = NON_ASSOCIATIVE(PM_BINDING_POWER_EQUALITY), + [PM_TOKEN_EQUAL_TILDE] = NON_ASSOCIATIVE(PM_BINDING_POWER_EQUALITY), + [PM_TOKEN_LESS_EQUAL_GREATER] = NON_ASSOCIATIVE(PM_BINDING_POWER_EQUALITY), + + // > >= < <= + [PM_TOKEN_GREATER] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_COMPARISON), + [PM_TOKEN_GREATER_EQUAL] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_COMPARISON), + [PM_TOKEN_LESS] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_COMPARISON), + [PM_TOKEN_LESS_EQUAL] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_COMPARISON), + + // ^ | + [PM_TOKEN_CARET] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_BITWISE_OR), + [PM_TOKEN_PIPE] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_BITWISE_OR), + + // & + [PM_TOKEN_AMPERSAND] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_BITWISE_AND), + + // >> << + [PM_TOKEN_GREATER_GREATER] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_SHIFT), + [PM_TOKEN_LESS_LESS] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_SHIFT), + + // - + + [PM_TOKEN_MINUS] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_TERM), + [PM_TOKEN_PLUS] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_TERM), + + // % / * + [PM_TOKEN_PERCENT] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_FACTOR), + [PM_TOKEN_SLASH] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_FACTOR), + [PM_TOKEN_STAR] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_FACTOR), + [PM_TOKEN_USTAR] = RIGHT_ASSOCIATIVE_UNARY(PM_BINDING_POWER_FACTOR), + + // -@ + [PM_TOKEN_UMINUS] = RIGHT_ASSOCIATIVE_UNARY(PM_BINDING_POWER_UMINUS), + [PM_TOKEN_UMINUS_NUM] = { PM_BINDING_POWER_UMINUS, PM_BINDING_POWER_MAX, false, false }, + + // ** + [PM_TOKEN_STAR_STAR] = RIGHT_ASSOCIATIVE(PM_BINDING_POWER_EXPONENT), + [PM_TOKEN_USTAR_STAR] = RIGHT_ASSOCIATIVE_UNARY(PM_BINDING_POWER_UNARY), + + // ! ~ +@ + [PM_TOKEN_BANG] = RIGHT_ASSOCIATIVE_UNARY(PM_BINDING_POWER_UNARY), + [PM_TOKEN_TILDE] = RIGHT_ASSOCIATIVE_UNARY(PM_BINDING_POWER_UNARY), + [PM_TOKEN_UPLUS] = RIGHT_ASSOCIATIVE_UNARY(PM_BINDING_POWER_UNARY), + + // [ + [PM_TOKEN_BRACKET_LEFT] = LEFT_ASSOCIATIVE(PM_BINDING_POWER_INDEX), + + // :: . &. + [PM_TOKEN_COLON_COLON] = RIGHT_ASSOCIATIVE(PM_BINDING_POWER_CALL), + [PM_TOKEN_DOT] = RIGHT_ASSOCIATIVE(PM_BINDING_POWER_CALL), + [PM_TOKEN_AMPERSAND_DOT] = RIGHT_ASSOCIATIVE(PM_BINDING_POWER_CALL) +}; + +#undef BINDING_POWER_ASSIGNMENT +#undef LEFT_ASSOCIATIVE +#undef RIGHT_ASSOCIATIVE +#undef RIGHT_ASSOCIATIVE_UNARY + +/** + * Returns true if the current token is of the given type. + */ +static inline bool +match1(const pm_parser_t *parser, pm_token_type_t type) { + return parser->current.type == type; +} + +/** + * Returns true if the current token is of either of the given types. + */ +static inline bool +match2(const pm_parser_t *parser, pm_token_type_t type1, pm_token_type_t type2) { + return match1(parser, type1) || match1(parser, type2); +} + +/** + * Returns true if the current token is any of the three given types. + */ +static inline bool +match3(const pm_parser_t *parser, pm_token_type_t type1, pm_token_type_t type2, pm_token_type_t type3) { + return match1(parser, type1) || match1(parser, type2) || match1(parser, type3); +} + +/** + * Returns true if the current token is any of the four given types. + */ +static inline bool +match4(const pm_parser_t *parser, pm_token_type_t type1, pm_token_type_t type2, pm_token_type_t type3, pm_token_type_t type4) { + return match1(parser, type1) || match1(parser, type2) || match1(parser, type3) || match1(parser, type4); +} + +/** + * Returns true if the current token is any of the seven given types. + */ +static inline bool +match7(const pm_parser_t *parser, pm_token_type_t type1, pm_token_type_t type2, pm_token_type_t type3, pm_token_type_t type4, pm_token_type_t type5, pm_token_type_t type6, pm_token_type_t type7) { + return match1(parser, type1) || match1(parser, type2) || match1(parser, type3) || match1(parser, type4) || match1(parser, type5) || match1(parser, type6) || match1(parser, type7); +} + +/** + * Returns true if the current token is any of the eight given types. + */ +static inline bool +match8(const pm_parser_t *parser, pm_token_type_t type1, pm_token_type_t type2, pm_token_type_t type3, pm_token_type_t type4, pm_token_type_t type5, pm_token_type_t type6, pm_token_type_t type7, pm_token_type_t type8) { + return match1(parser, type1) || match1(parser, type2) || match1(parser, type3) || match1(parser, type4) || match1(parser, type5) || match1(parser, type6) || match1(parser, type7) || match1(parser, type8); +} + +/** + * Returns true if the current token is any of the nine given types. + */ +static inline bool +match9(const pm_parser_t *parser, pm_token_type_t type1, pm_token_type_t type2, pm_token_type_t type3, pm_token_type_t type4, pm_token_type_t type5, pm_token_type_t type6, pm_token_type_t type7, pm_token_type_t type8, pm_token_type_t type9) { + return match1(parser, type1) || match1(parser, type2) || match1(parser, type3) || match1(parser, type4) || match1(parser, type5) || match1(parser, type6) || match1(parser, type7) || match1(parser, type8) || match1(parser, type9); +} + +/** + * If the current token is of the specified type, lex forward by one token and + * return true. Otherwise, return false. For example: + * + * if (accept1(parser, PM_TOKEN_COLON)) { ... } + */ +static bool +accept1(pm_parser_t *parser, pm_token_type_t type) { + if (match1(parser, type)) { + parser_lex(parser); + return true; + } + return false; +} + +/** + * If the current token is either of the two given types, lex forward by one + * token and return true. Otherwise return false. + */ +static inline bool +accept2(pm_parser_t *parser, pm_token_type_t type1, pm_token_type_t type2) { + if (match2(parser, type1, type2)) { + parser_lex(parser); + return true; + } + return false; +} + +/** + * This function indicates that the parser expects a token in a specific + * position. For example, if you're parsing a BEGIN block, you know that a { is + * expected immediately after the keyword. In that case you would call this + * function to indicate that that token should be found. + * + * If we didn't find the token that we were expecting, then we're going to add + * an error to the parser's list of errors (to indicate that the tree is not + * valid) and create an artificial token instead. This allows us to recover from + * the fact that the token isn't present and continue parsing. + */ +static void +expect1(pm_parser_t *parser, pm_token_type_t type, pm_diagnostic_id_t diag_id) { + if (accept1(parser, type)) return; + + const uint8_t *location = parser->previous.end; + pm_parser_err(parser, location, location, diag_id); + + parser->previous.start = location; + parser->previous.type = PM_TOKEN_MISSING; +} + +/** + * This function is the same as expect1, but it expects either of two token + * types. + */ +static void +expect2(pm_parser_t *parser, pm_token_type_t type1, pm_token_type_t type2, pm_diagnostic_id_t diag_id) { + if (accept2(parser, type1, type2)) return; + + const uint8_t *location = parser->previous.end; + pm_parser_err(parser, location, location, diag_id); + + parser->previous.start = location; + parser->previous.type = PM_TOKEN_MISSING; +} + +/** + * A special expect1 that expects a heredoc terminator and handles popping the + * lex mode accordingly. + */ +static void +expect1_heredoc_term(pm_parser_t *parser, const uint8_t *ident_start, size_t ident_length) { + if (match1(parser, PM_TOKEN_HEREDOC_END)) { + parser_lex(parser); + } else { + pm_parser_err_heredoc_term(parser, ident_start, ident_length); + parser->previous.start = parser->previous.end; + parser->previous.type = PM_TOKEN_MISSING; + } +} + +static pm_node_t * +parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call, bool accepts_label, pm_diagnostic_id_t diag_id, uint16_t depth); + +/** + * This is a wrapper of parse_expression, which also checks whether the + * resulting node is a value expression. + */ +static pm_node_t * +parse_value_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call, bool accepts_label, pm_diagnostic_id_t diag_id, uint16_t depth) { + pm_node_t *node = parse_expression(parser, binding_power, accepts_command_call, accepts_label, diag_id, depth); + pm_assert_value_expression(parser, node); + return node; +} + +/** + * This function controls whether or not we will attempt to parse an expression + * beginning at the subsequent token. It is used when we are in a context where + * an expression is optional. + * + * For example, looking at a range object when we've already lexed the operator, + * we need to know if we should attempt to parse an expression on the right. + * + * For another example, if we've parsed an identifier or a method call and we do + * not have parentheses, then the next token may be the start of an argument or + * it may not. + * + * CRuby parsers that are generated would resolve this by using a lookahead and + * potentially backtracking. We attempt to do this by just looking at the next + * token and making a decision based on that. I am not sure if this is going to + * work in all cases, it may need to be refactored later. But it appears to work + * for now. + */ +static inline bool +token_begins_expression_p(pm_token_type_t type) { + switch (type) { + case PM_TOKEN_EQUAL_GREATER: + case PM_TOKEN_KEYWORD_IN: + // We need to special case this because it is a binary operator that + // should not be marked as beginning an expression. + return false; + case PM_TOKEN_BRACE_RIGHT: + case PM_TOKEN_BRACKET_RIGHT: + case PM_TOKEN_COLON: + case PM_TOKEN_COMMA: + case PM_TOKEN_EMBEXPR_END: + case PM_TOKEN_EOF: + case PM_TOKEN_LAMBDA_BEGIN: + case PM_TOKEN_KEYWORD_DO: + case PM_TOKEN_KEYWORD_DO_LOOP: + case PM_TOKEN_KEYWORD_END: + case PM_TOKEN_KEYWORD_ELSE: + case PM_TOKEN_KEYWORD_ELSIF: + case PM_TOKEN_KEYWORD_ENSURE: + case PM_TOKEN_KEYWORD_THEN: + case PM_TOKEN_KEYWORD_RESCUE: + case PM_TOKEN_KEYWORD_WHEN: + case PM_TOKEN_NEWLINE: + case PM_TOKEN_PARENTHESIS_RIGHT: + case PM_TOKEN_SEMICOLON: + // The reason we need this short-circuit is because we're using the + // binding powers table to tell us if the subsequent token could + // potentially be the start of an expression. If there _is_ a binding + // power for one of these tokens, then we should remove it from this list + // and let it be handled by the default case below. + assert(pm_binding_powers[type].left == PM_BINDING_POWER_UNSET); + return false; + case PM_TOKEN_UAMPERSAND: + // This is a special case because this unary operator cannot appear + // as a general operator, it only appears in certain circumstances. + return false; + case PM_TOKEN_UCOLON_COLON: + case PM_TOKEN_UMINUS: + case PM_TOKEN_UMINUS_NUM: + case PM_TOKEN_UPLUS: + case PM_TOKEN_BANG: + case PM_TOKEN_TILDE: + case PM_TOKEN_UDOT_DOT: + case PM_TOKEN_UDOT_DOT_DOT: + // These unary tokens actually do have binding power associated with them + // so that we can correctly place them into the precedence order. But we + // want them to be marked as beginning an expression, so we need to + // special case them here. + return true; + default: + return pm_binding_powers[type].left == PM_BINDING_POWER_UNSET; + } +} + +/** + * Parse an expression with the given binding power that may be optionally + * prefixed by the * operator. + */ +static pm_node_t * +parse_starred_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call, pm_diagnostic_id_t diag_id, uint16_t depth) { + if (accept1(parser, PM_TOKEN_USTAR)) { + pm_token_t operator = parser->previous; + pm_node_t *expression = parse_value_expression(parser, binding_power, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR, (uint16_t) (depth + 1)); + return (pm_node_t *) pm_splat_node_create(parser, &operator, expression); + } + + return parse_value_expression(parser, binding_power, accepts_command_call, false, diag_id, depth); +} + +/** + * Convert the name of a method into the corresponding write method name. For + * example, foo would be turned into foo=. + */ +static void +parse_write_name(pm_parser_t *parser, pm_constant_id_t *name_field) { + // The method name needs to change. If we previously had + // foo, we now need foo=. In this case we'll allocate a new + // owned string, copy the previous method name in, and + // append an =. + pm_constant_t *constant = pm_constant_pool_id_to_constant(&parser->constant_pool, *name_field); + size_t length = constant->length; + uint8_t *name = xcalloc(length + 1, sizeof(uint8_t)); + if (name == NULL) return; + + memcpy(name, constant->start, length); + name[length] = '='; + + // Now switch the name to the new string. + // This silences clang analyzer warning about leak of memory pointed by `name`. + // NOLINTNEXTLINE(clang-analyzer-*) + *name_field = pm_constant_pool_insert_owned(&parser->constant_pool, name, length + 1); +} + +/** + * Certain expressions are not targetable, but in order to provide a better + * experience we give a specific error message. In order to maintain as much + * information in the tree as possible, we replace them with local variable + * writes. + */ +static pm_node_t * +parse_unwriteable_target(pm_parser_t *parser, pm_node_t *target) { + switch (PM_NODE_TYPE(target)) { + case PM_SOURCE_ENCODING_NODE: pm_parser_err_node(parser, target, PM_ERR_EXPRESSION_NOT_WRITABLE_ENCODING); break; + case PM_FALSE_NODE: pm_parser_err_node(parser, target, PM_ERR_EXPRESSION_NOT_WRITABLE_FALSE); break; + case PM_SOURCE_FILE_NODE: pm_parser_err_node(parser, target, PM_ERR_EXPRESSION_NOT_WRITABLE_FILE); break; + case PM_SOURCE_LINE_NODE: pm_parser_err_node(parser, target, PM_ERR_EXPRESSION_NOT_WRITABLE_LINE); break; + case PM_NIL_NODE: pm_parser_err_node(parser, target, PM_ERR_EXPRESSION_NOT_WRITABLE_NIL); break; + case PM_SELF_NODE: pm_parser_err_node(parser, target, PM_ERR_EXPRESSION_NOT_WRITABLE_SELF); break; + case PM_TRUE_NODE: pm_parser_err_node(parser, target, PM_ERR_EXPRESSION_NOT_WRITABLE_TRUE); break; + default: break; + } + + pm_constant_id_t name = pm_parser_constant_id_location(parser, target->location.start, target->location.end); + pm_local_variable_target_node_t *result = pm_local_variable_target_node_create(parser, &target->location, name, 0); + + pm_node_destroy(parser, target); + return (pm_node_t *) result; +} + +/** + * When an implicit local variable is written to or targeted, it becomes a + * regular, named local variable. This function removes it from the list of + * implicit parameters when that happens. + */ +static void +parse_target_implicit_parameter(pm_parser_t *parser, pm_node_t *node) { + pm_node_list_t *implicit_parameters = &parser->current_scope->implicit_parameters; + + for (size_t index = 0; index < implicit_parameters->size; index++) { + if (implicit_parameters->nodes[index] == node) { + // If the node is not the last one in the list, we need to shift the + // remaining nodes down to fill the gap. This is extremely unlikely + // to happen. + if (index != implicit_parameters->size - 1) { + memcpy(&implicit_parameters->nodes[index], &implicit_parameters->nodes[index + 1], (implicit_parameters->size - index - 1) * sizeof(pm_node_t *)); + } + + implicit_parameters->size--; + break; + } + } +} + +/** + * Convert the given node into a valid target node. + * + * @param multiple Whether or not this target is part of a larger set of + * targets. If it is, then the &. operator is not allowed. + * @param splat Whether or not this target is a child of a splat target. If it + * is, then fewer patterns are allowed. + */ +static pm_node_t * +parse_target(pm_parser_t *parser, pm_node_t *target, bool multiple, bool splat_parent) { + switch (PM_NODE_TYPE(target)) { + case PM_MISSING_NODE: + return target; + case PM_SOURCE_ENCODING_NODE: + case PM_FALSE_NODE: + case PM_SOURCE_FILE_NODE: + case PM_SOURCE_LINE_NODE: + case PM_NIL_NODE: + case PM_SELF_NODE: + case PM_TRUE_NODE: { + // In these special cases, we have specific error messages and we + // will replace them with local variable writes. + return parse_unwriteable_target(parser, target); + } + case PM_CLASS_VARIABLE_READ_NODE: + assert(sizeof(pm_class_variable_target_node_t) == sizeof(pm_class_variable_read_node_t)); + target->type = PM_CLASS_VARIABLE_TARGET_NODE; + return target; + case PM_CONSTANT_PATH_NODE: + if (context_def_p(parser)) { + pm_parser_err_node(parser, target, PM_ERR_WRITE_TARGET_IN_METHOD); + } + + assert(sizeof(pm_constant_path_target_node_t) == sizeof(pm_constant_path_node_t)); + target->type = PM_CONSTANT_PATH_TARGET_NODE; + + return target; + case PM_CONSTANT_READ_NODE: + if (context_def_p(parser)) { + pm_parser_err_node(parser, target, PM_ERR_WRITE_TARGET_IN_METHOD); + } + + assert(sizeof(pm_constant_target_node_t) == sizeof(pm_constant_read_node_t)); + target->type = PM_CONSTANT_TARGET_NODE; + + return target; + case PM_BACK_REFERENCE_READ_NODE: + case PM_NUMBERED_REFERENCE_READ_NODE: + PM_PARSER_ERR_NODE_FORMAT_CONTENT(parser, target, PM_ERR_WRITE_TARGET_READONLY); + return target; + case PM_GLOBAL_VARIABLE_READ_NODE: + assert(sizeof(pm_global_variable_target_node_t) == sizeof(pm_global_variable_read_node_t)); + target->type = PM_GLOBAL_VARIABLE_TARGET_NODE; + return target; + case PM_LOCAL_VARIABLE_READ_NODE: { + if (pm_token_is_numbered_parameter(target->location.start, target->location.end)) { + PM_PARSER_ERR_FORMAT(parser, target->location.start, target->location.end, PM_ERR_PARAMETER_NUMBERED_RESERVED, target->location.start); + parse_target_implicit_parameter(parser, target); + } + + const pm_local_variable_read_node_t *cast = (const pm_local_variable_read_node_t *) target; + uint32_t name = cast->name; + uint32_t depth = cast->depth; + pm_locals_unread(&pm_parser_scope_find(parser, depth)->locals, name); + + assert(sizeof(pm_local_variable_target_node_t) == sizeof(pm_local_variable_read_node_t)); + target->type = PM_LOCAL_VARIABLE_TARGET_NODE; + + return target; + } + case PM_IT_LOCAL_VARIABLE_READ_NODE: { + pm_constant_id_t name = pm_parser_local_add_constant(parser, "it", 2); + pm_node_t *node = (pm_node_t *) pm_local_variable_target_node_create(parser, &target->location, name, 0); + + parse_target_implicit_parameter(parser, target); + pm_node_destroy(parser, target); + + return node; + } + case PM_INSTANCE_VARIABLE_READ_NODE: + assert(sizeof(pm_instance_variable_target_node_t) == sizeof(pm_instance_variable_read_node_t)); + target->type = PM_INSTANCE_VARIABLE_TARGET_NODE; + return target; + case PM_MULTI_TARGET_NODE: + if (splat_parent) { + // Multi target is not accepted in all positions. If this is one + // of them, then we need to add an error. + pm_parser_err_node(parser, target, PM_ERR_WRITE_TARGET_UNEXPECTED); + } + + return target; + case PM_SPLAT_NODE: { + pm_splat_node_t *splat = (pm_splat_node_t *) target; + + if (splat->expression != NULL) { + splat->expression = parse_target(parser, splat->expression, multiple, true); + } + + return (pm_node_t *) splat; + } + case PM_CALL_NODE: { + pm_call_node_t *call = (pm_call_node_t *) target; + + // If we have no arguments to the call node and we need this to be a + // target then this is either a method call or a local variable + // write. + if ( + (call->message_loc.start != NULL) && + (call->message_loc.end[-1] != '!') && + (call->message_loc.end[-1] != '?') && + (call->opening_loc.start == NULL) && + (call->arguments == NULL) && + (call->block == NULL) + ) { + if (call->receiver == NULL) { + // When we get here, we have a local variable write, because it + // was previously marked as a method call but now we have an =. + // This looks like: + // + // foo = 1 + // + // When it was parsed in the prefix position, foo was seen as a + // method call with no receiver and no arguments. Now we have an + // =, so we know it's a local variable write. + const pm_location_t message_loc = call->message_loc; + + pm_constant_id_t name = pm_parser_local_add_location(parser, message_loc.start, message_loc.end, 0); + pm_node_destroy(parser, target); + + return (pm_node_t *) pm_local_variable_target_node_create(parser, &message_loc, name, 0); + } + + if (*call->message_loc.start == '_' || parser->encoding->alnum_char(call->message_loc.start, call->message_loc.end - call->message_loc.start)) { + if (multiple && PM_NODE_FLAG_P(call, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION)) { + pm_parser_err_node(parser, (const pm_node_t *) call, PM_ERR_UNEXPECTED_SAFE_NAVIGATION); + } + + parse_write_name(parser, &call->name); + return (pm_node_t *) pm_call_target_node_create(parser, call); + } + } + + // If there is no call operator and the message is "[]" then this is + // an aref expression, and we can transform it into an aset + // expression. + if (PM_NODE_FLAG_P(call, PM_CALL_NODE_FLAGS_INDEX)) { + return (pm_node_t *) pm_index_target_node_create(parser, call); + } + } + PRISM_FALLTHROUGH + default: + // In this case we have a node that we don't know how to convert + // into a target. We need to treat it as an error. For now, we'll + // mark it as an error and just skip right past it. + pm_parser_err_node(parser, target, PM_ERR_WRITE_TARGET_UNEXPECTED); + return target; + } +} + +/** + * Parse a write target and validate that it is in a valid position for + * assignment. + */ +static pm_node_t * +parse_target_validate(pm_parser_t *parser, pm_node_t *target, bool multiple) { + pm_node_t *result = parse_target(parser, target, multiple, false); + + // Ensure that we have one of an =, an 'in' in for indexes, and a ')' in + // parens after the targets. + if ( + !match1(parser, PM_TOKEN_EQUAL) && + !(context_p(parser, PM_CONTEXT_FOR_INDEX) && match1(parser, PM_TOKEN_KEYWORD_IN)) && + !(context_p(parser, PM_CONTEXT_PARENS) && match1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) + ) { + pm_parser_err_node(parser, result, PM_ERR_WRITE_TARGET_UNEXPECTED); + } + + return result; +} + +/** + * Potentially wrap a constant write node in a shareable constant node depending + * on the current state. + */ +static pm_node_t * +parse_shareable_constant_write(pm_parser_t *parser, pm_node_t *write) { + pm_shareable_constant_value_t shareable_constant = pm_parser_scope_shareable_constant_get(parser); + + if (shareable_constant != PM_SCOPE_SHAREABLE_CONSTANT_NONE) { + return (pm_node_t *) pm_shareable_constant_node_create(parser, write, shareable_constant); + } + + return write; +} + +/** + * Convert the given node into a valid write node. + */ +static pm_node_t * +parse_write(pm_parser_t *parser, pm_node_t *target, pm_token_t *operator, pm_node_t *value) { + switch (PM_NODE_TYPE(target)) { + case PM_MISSING_NODE: + pm_node_destroy(parser, value); + return target; + case PM_CLASS_VARIABLE_READ_NODE: { + pm_class_variable_write_node_t *node = pm_class_variable_write_node_create(parser, (pm_class_variable_read_node_t *) target, operator, value); + pm_node_destroy(parser, target); + return (pm_node_t *) node; + } + case PM_CONSTANT_PATH_NODE: { + pm_node_t *node = (pm_node_t *) pm_constant_path_write_node_create(parser, (pm_constant_path_node_t *) target, operator, value); + + if (context_def_p(parser)) { + pm_parser_err_node(parser, node, PM_ERR_WRITE_TARGET_IN_METHOD); + } + + return parse_shareable_constant_write(parser, node); + } + case PM_CONSTANT_READ_NODE: { + pm_node_t *node = (pm_node_t *) pm_constant_write_node_create(parser, (pm_constant_read_node_t *) target, operator, value); + + if (context_def_p(parser)) { + pm_parser_err_node(parser, node, PM_ERR_WRITE_TARGET_IN_METHOD); + } + + pm_node_destroy(parser, target); + return parse_shareable_constant_write(parser, node); + } + case PM_BACK_REFERENCE_READ_NODE: + case PM_NUMBERED_REFERENCE_READ_NODE: + PM_PARSER_ERR_NODE_FORMAT_CONTENT(parser, target, PM_ERR_WRITE_TARGET_READONLY); + PRISM_FALLTHROUGH + case PM_GLOBAL_VARIABLE_READ_NODE: { + pm_global_variable_write_node_t *node = pm_global_variable_write_node_create(parser, target, operator, value); + pm_node_destroy(parser, target); + return (pm_node_t *) node; + } + case PM_LOCAL_VARIABLE_READ_NODE: { + pm_local_variable_read_node_t *local_read = (pm_local_variable_read_node_t *) target; + + pm_constant_id_t name = local_read->name; + pm_location_t name_loc = target->location; + + uint32_t depth = local_read->depth; + pm_scope_t *scope = pm_parser_scope_find(parser, depth); + + if (pm_token_is_numbered_parameter(target->location.start, target->location.end)) { + pm_diagnostic_id_t diag_id = (scope->parameters & PM_SCOPE_PARAMETERS_NUMBERED_FOUND) ? PM_ERR_EXPRESSION_NOT_WRITABLE_NUMBERED : PM_ERR_PARAMETER_NUMBERED_RESERVED; + PM_PARSER_ERR_FORMAT(parser, target->location.start, target->location.end, diag_id, target->location.start); + parse_target_implicit_parameter(parser, target); + } + + pm_locals_unread(&scope->locals, name); + pm_node_destroy(parser, target); + + return (pm_node_t *) pm_local_variable_write_node_create(parser, name, depth, value, &name_loc, operator); + } + case PM_IT_LOCAL_VARIABLE_READ_NODE: { + pm_constant_id_t name = pm_parser_local_add_constant(parser, "it", 2); + pm_node_t *node = (pm_node_t *) pm_local_variable_write_node_create(parser, name, 0, value, &target->location, operator); + + parse_target_implicit_parameter(parser, target); + pm_node_destroy(parser, target); + + return node; + } + case PM_INSTANCE_VARIABLE_READ_NODE: { + pm_node_t *write_node = (pm_node_t *) pm_instance_variable_write_node_create(parser, (pm_instance_variable_read_node_t *) target, operator, value); + pm_node_destroy(parser, target); + return write_node; + } + case PM_MULTI_TARGET_NODE: + return (pm_node_t *) pm_multi_write_node_create(parser, (pm_multi_target_node_t *) target, operator, value); + case PM_SPLAT_NODE: { + pm_splat_node_t *splat = (pm_splat_node_t *) target; + + if (splat->expression != NULL) { + splat->expression = parse_write(parser, splat->expression, operator, value); + } + + pm_multi_target_node_t *multi_target = pm_multi_target_node_create(parser); + pm_multi_target_node_targets_append(parser, multi_target, (pm_node_t *) splat); + + return (pm_node_t *) pm_multi_write_node_create(parser, multi_target, operator, value); + } + case PM_CALL_NODE: { + pm_call_node_t *call = (pm_call_node_t *) target; + + // If we have no arguments to the call node and we need this to be a + // target then this is either a method call or a local variable + // write. + if ( + (call->message_loc.start != NULL) && + (call->message_loc.end[-1] != '!') && + (call->message_loc.end[-1] != '?') && + (call->opening_loc.start == NULL) && + (call->arguments == NULL) && + (call->block == NULL) + ) { + if (call->receiver == NULL) { + // When we get here, we have a local variable write, because it + // was previously marked as a method call but now we have an =. + // This looks like: + // + // foo = 1 + // + // When it was parsed in the prefix position, foo was seen as a + // method call with no receiver and no arguments. Now we have an + // =, so we know it's a local variable write. + const pm_location_t message = call->message_loc; + + pm_parser_local_add_location(parser, message.start, message.end, 0); + pm_node_destroy(parser, target); + + pm_constant_id_t constant_id = pm_parser_constant_id_location(parser, message.start, message.end); + target = (pm_node_t *) pm_local_variable_write_node_create(parser, constant_id, 0, value, &message, operator); + + pm_refute_numbered_parameter(parser, message.start, message.end); + return target; + } + + if (char_is_identifier_start(parser, call->message_loc.start, parser->end - call->message_loc.start)) { + // When we get here, we have a method call, because it was + // previously marked as a method call but now we have an =. This + // looks like: + // + // foo.bar = 1 + // + // When it was parsed in the prefix position, foo.bar was seen as a + // method call with no arguments. Now we have an =, so we know it's + // a method call with an argument. In this case we will create the + // arguments node, parse the argument, and add it to the list. + pm_arguments_node_t *arguments = pm_arguments_node_create(parser); + call->arguments = arguments; + + pm_arguments_node_arguments_append(arguments, value); + call->base.location.end = arguments->base.location.end; + + parse_write_name(parser, &call->name); + pm_node_flag_set((pm_node_t *) call, PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE | pm_implicit_array_write_flags(value, PM_CALL_NODE_FLAGS_IMPLICIT_ARRAY)); + + return (pm_node_t *) call; + } + } + + // If there is no call operator and the message is "[]" then this is + // an aref expression, and we can transform it into an aset + // expression. + if (PM_NODE_FLAG_P(call, PM_CALL_NODE_FLAGS_INDEX)) { + if (call->arguments == NULL) { + call->arguments = pm_arguments_node_create(parser); + } + + pm_arguments_node_arguments_append(call->arguments, value); + target->location.end = value->location.end; + + // Replace the name with "[]=". + call->name = pm_parser_constant_id_constant(parser, "[]=", 3); + + // Ensure that the arguments for []= don't contain keywords + pm_index_arguments_check(parser, call->arguments, call->block); + pm_node_flag_set((pm_node_t *) call, PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE | pm_implicit_array_write_flags(value, PM_CALL_NODE_FLAGS_IMPLICIT_ARRAY)); + + return target; + } + + // If there are arguments on the call node, then it can't be a method + // call ending with = or a local variable write, so it must be a + // syntax error. In this case we'll fall through to our default + // handling. We need to free the value that we parsed because there + // is no way for us to attach it to the tree at this point. + pm_node_destroy(parser, value); + } + PRISM_FALLTHROUGH + default: + // In this case we have a node that we don't know how to convert into a + // target. We need to treat it as an error. For now, we'll mark it as an + // error and just skip right past it. + pm_parser_err_token(parser, operator, PM_ERR_WRITE_TARGET_UNEXPECTED); + return target; + } +} + +/** + * Certain expressions are not writable, but in order to provide a better + * experience we give a specific error message. In order to maintain as much + * information in the tree as possible, we replace them with local variable + * writes. + */ +static pm_node_t * +parse_unwriteable_write(pm_parser_t *parser, pm_node_t *target, const pm_token_t *equals, pm_node_t *value) { + switch (PM_NODE_TYPE(target)) { + case PM_SOURCE_ENCODING_NODE: pm_parser_err_token(parser, equals, PM_ERR_EXPRESSION_NOT_WRITABLE_ENCODING); break; + case PM_FALSE_NODE: pm_parser_err_token(parser, equals, PM_ERR_EXPRESSION_NOT_WRITABLE_FALSE); break; + case PM_SOURCE_FILE_NODE: pm_parser_err_token(parser, equals, PM_ERR_EXPRESSION_NOT_WRITABLE_FILE); break; + case PM_SOURCE_LINE_NODE: pm_parser_err_token(parser, equals, PM_ERR_EXPRESSION_NOT_WRITABLE_LINE); break; + case PM_NIL_NODE: pm_parser_err_token(parser, equals, PM_ERR_EXPRESSION_NOT_WRITABLE_NIL); break; + case PM_SELF_NODE: pm_parser_err_token(parser, equals, PM_ERR_EXPRESSION_NOT_WRITABLE_SELF); break; + case PM_TRUE_NODE: pm_parser_err_token(parser, equals, PM_ERR_EXPRESSION_NOT_WRITABLE_TRUE); break; + default: break; + } + + pm_constant_id_t name = pm_parser_local_add_location(parser, target->location.start, target->location.end, 1); + pm_local_variable_write_node_t *result = pm_local_variable_write_node_create(parser, name, 0, value, &target->location, equals); + + pm_node_destroy(parser, target); + return (pm_node_t *) result; +} + +/** + * Parse a list of targets for assignment. This is used in the case of a for + * loop or a multi-assignment. For example, in the following code: + * + * for foo, bar in baz + * ^^^^^^^^ + * + * The targets are `foo` and `bar`. This function will either return a single + * target node or a multi-target node. + */ +static pm_node_t * +parse_targets(pm_parser_t *parser, pm_node_t *first_target, pm_binding_power_t binding_power, uint16_t depth) { + bool has_rest = PM_NODE_TYPE_P(first_target, PM_SPLAT_NODE); + + pm_multi_target_node_t *result = pm_multi_target_node_create(parser); + pm_multi_target_node_targets_append(parser, result, parse_target(parser, first_target, true, false)); + + while (accept1(parser, PM_TOKEN_COMMA)) { + if (accept1(parser, PM_TOKEN_USTAR)) { + // Here we have a splat operator. It can have a name or be + // anonymous. It can be the final target or be in the middle if + // there haven't been any others yet. + if (has_rest) { + pm_parser_err_previous(parser, PM_ERR_MULTI_ASSIGN_MULTI_SPLATS); + } + + pm_token_t star_operator = parser->previous; + pm_node_t *name = NULL; + + if (token_begins_expression_p(parser->current.type)) { + name = parse_expression(parser, binding_power, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR, (uint16_t) (depth + 1)); + name = parse_target(parser, name, true, true); + } + + pm_node_t *splat = (pm_node_t *) pm_splat_node_create(parser, &star_operator, name); + pm_multi_target_node_targets_append(parser, result, splat); + has_rest = true; + } else if (match1(parser, PM_TOKEN_PARENTHESIS_LEFT)) { + context_push(parser, PM_CONTEXT_MULTI_TARGET); + pm_node_t *target = parse_expression(parser, binding_power, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_COMMA, (uint16_t) (depth + 1)); + target = parse_target(parser, target, true, false); + + pm_multi_target_node_targets_append(parser, result, target); + context_pop(parser); + } else if (token_begins_expression_p(parser->current.type)) { + pm_node_t *target = parse_expression(parser, binding_power, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_COMMA, (uint16_t) (depth + 1)); + target = parse_target(parser, target, true, false); + + pm_multi_target_node_targets_append(parser, result, target); + } else if (!match1(parser, PM_TOKEN_EOF)) { + // If we get here, then we have a trailing , in a multi target node. + // We'll add an implicit rest node to represent this. + pm_node_t *rest = (pm_node_t *) pm_implicit_rest_node_create(parser, &parser->previous); + pm_multi_target_node_targets_append(parser, result, rest); + break; + } + } + + return (pm_node_t *) result; +} + +/** + * Parse a list of targets and validate that it is in a valid position for + * assignment. + */ +static pm_node_t * +parse_targets_validate(pm_parser_t *parser, pm_node_t *first_target, pm_binding_power_t binding_power, uint16_t depth) { + pm_node_t *result = parse_targets(parser, first_target, binding_power, depth); + accept1(parser, PM_TOKEN_NEWLINE); + + // Ensure that we have either an = or a ) after the targets. + if (!match2(parser, PM_TOKEN_EQUAL, PM_TOKEN_PARENTHESIS_RIGHT)) { + pm_parser_err_node(parser, result, PM_ERR_WRITE_TARGET_UNEXPECTED); + } + + return result; +} + +/** + * Parse a list of statements separated by newlines or semicolons. + */ +static pm_statements_node_t * +parse_statements(pm_parser_t *parser, pm_context_t context, uint16_t depth) { + // First, skip past any optional terminators that might be at the beginning + // of the statements. + while (accept2(parser, PM_TOKEN_SEMICOLON, PM_TOKEN_NEWLINE)); + + // If we have a terminator, then we can just return NULL. + if (context_terminator(context, &parser->current)) return NULL; + + pm_statements_node_t *statements = pm_statements_node_create(parser); + + // At this point we know we have at least one statement, and that it + // immediately follows the current token. + context_push(parser, context); + + while (true) { + pm_node_t *node = parse_expression(parser, PM_BINDING_POWER_STATEMENT, true, false, PM_ERR_CANNOT_PARSE_EXPRESSION, (uint16_t) (depth + 1)); + pm_statements_node_body_append(parser, statements, node, true); + + // If we're recovering from a syntax error, then we need to stop parsing + // the statements now. + if (parser->recovering) { + // If this is the level of context where the recovery has happened, + // then we can mark the parser as done recovering. + if (context_terminator(context, &parser->current)) parser->recovering = false; + break; + } + + // If we have a terminator, then we will parse all consecutive + // terminators and then continue parsing the statements list. + if (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)) { + // If we have a terminator, then we will continue parsing the + // statements list. + while (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)); + if (context_terminator(context, &parser->current)) break; + + // Now we can continue parsing the list of statements. + continue; + } + + // At this point we have a list of statements that are not terminated by + // a newline or semicolon. At this point we need to check if we're at + // the end of the statements list. If we are, then we should break out + // of the loop. + if (context_terminator(context, &parser->current)) break; + + // At this point, we have a syntax error, because the statement was not + // terminated by a newline or semicolon, and we're not at the end of the + // statements list. Ideally we should scan forward to determine if we + // should insert a missing terminator or break out of parsing the + // statements list at this point. + // + // We don't have that yet, so instead we'll do a more naive approach. If + // we were unable to parse an expression, then we will skip past this + // token and continue parsing the statements list. Otherwise we'll add + // an error and continue parsing the statements list. + if (PM_NODE_TYPE_P(node, PM_MISSING_NODE)) { + parser_lex(parser); + + // If we are at the end of the file, then we need to stop parsing + // the statements entirely at this point. Mark the parser as + // recovering, as we know that EOF closes the top-level context, and + // then break out of the loop. + if (match1(parser, PM_TOKEN_EOF)) { + parser->recovering = true; + break; + } + + while (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)); + if (context_terminator(context, &parser->current)) break; + } else if (!accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_EOF)) { + // This is an inlined version of accept1 because the error that we + // want to add has varargs. If this happens again, we should + // probably extract a helper function. + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_EXPECT_EOL_AFTER_STATEMENT, pm_token_type_human(parser->current.type)); + parser->previous.start = parser->previous.end; + parser->previous.type = PM_TOKEN_MISSING; + } + } + + context_pop(parser); + bool last_value = true; + switch (context) { + case PM_CONTEXT_BEGIN_ENSURE: + case PM_CONTEXT_DEF_ENSURE: + last_value = false; + break; + default: + break; + } + pm_void_statements_check(parser, statements, last_value); + + return statements; +} + +/** + * Add a node to a set of static literals that holds a set of hash keys. If the + * node is a duplicate, then add an appropriate warning. + */ +static void +pm_hash_key_static_literals_add(pm_parser_t *parser, pm_static_literals_t *literals, pm_node_t *node) { + const pm_node_t *duplicated = pm_static_literals_add(&parser->newline_list, parser->start_line, literals, node, true); + + if (duplicated != NULL) { + pm_buffer_t buffer = { 0 }; + pm_static_literal_inspect(&buffer, &parser->newline_list, parser->start_line, parser->encoding->name, duplicated); + + pm_diagnostic_list_append_format( + &parser->warning_list, + duplicated->location.start, + duplicated->location.end, + PM_WARN_DUPLICATED_HASH_KEY, + (int) pm_buffer_length(&buffer), + pm_buffer_value(&buffer), + pm_newline_list_line_column(&parser->newline_list, node->location.start, parser->start_line).line + ); + + pm_buffer_free(&buffer); + } +} + +/** + * Add a node to a set of static literals that holds a set of hash keys. If the + * node is a duplicate, then add an appropriate warning. + */ +static void +pm_when_clause_static_literals_add(pm_parser_t *parser, pm_static_literals_t *literals, pm_node_t *node) { + pm_node_t *previous; + + if ((previous = pm_static_literals_add(&parser->newline_list, parser->start_line, literals, node, false)) != NULL) { + pm_diagnostic_list_append_format( + &parser->warning_list, + node->location.start, + node->location.end, + PM_WARN_DUPLICATED_WHEN_CLAUSE, + pm_newline_list_line_column(&parser->newline_list, node->location.start, parser->start_line).line, + pm_newline_list_line_column(&parser->newline_list, previous->location.start, parser->start_line).line + ); + } +} + +/** + * Parse all of the elements of a hash. Return true if a double splat was found. + */ +static bool +parse_assocs(pm_parser_t *parser, pm_static_literals_t *literals, pm_node_t *node, uint16_t depth) { + assert(PM_NODE_TYPE_P(node, PM_HASH_NODE) || PM_NODE_TYPE_P(node, PM_KEYWORD_HASH_NODE)); + bool contains_keyword_splat = false; + + while (true) { + pm_node_t *element; + + switch (parser->current.type) { + case PM_TOKEN_USTAR_STAR: { + parser_lex(parser); + pm_token_t operator = parser->previous; + pm_node_t *value = NULL; + + if (match1(parser, PM_TOKEN_BRACE_LEFT)) { + // If we're about to parse a nested hash that is being + // pushed into this hash directly with **, then we want the + // inner hash to share the static literals with the outer + // hash. + parser->current_hash_keys = literals; + value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH, (uint16_t) (depth + 1)); + } else if (token_begins_expression_p(parser->current.type)) { + value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH, (uint16_t) (depth + 1)); + } else { + pm_parser_scope_forwarding_keywords_check(parser, &operator); + } + + element = (pm_node_t *) pm_assoc_splat_node_create(parser, value, &operator); + contains_keyword_splat = true; + break; + } + case PM_TOKEN_LABEL: { + pm_token_t label = parser->current; + parser_lex(parser); + + pm_node_t *key = (pm_node_t *) pm_symbol_node_label_create(parser, &label); + pm_hash_key_static_literals_add(parser, literals, key); + + pm_token_t operator = not_provided(parser); + pm_node_t *value = NULL; + + if (token_begins_expression_p(parser->current.type)) { + value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_HASH_EXPRESSION_AFTER_LABEL, (uint16_t) (depth + 1)); + } else { + if (parser->encoding->isupper_char(label.start, (label.end - 1) - label.start)) { + pm_token_t constant = { .type = PM_TOKEN_CONSTANT, .start = label.start, .end = label.end - 1 }; + value = (pm_node_t *) pm_constant_read_node_create(parser, &constant); + } else { + int depth = -1; + pm_token_t identifier = { .type = PM_TOKEN_IDENTIFIER, .start = label.start, .end = label.end - 1 }; + + if (identifier.end[-1] == '!' || identifier.end[-1] == '?') { + PM_PARSER_ERR_TOKEN_FORMAT_CONTENT(parser, identifier, PM_ERR_INVALID_LOCAL_VARIABLE_READ); + } else { + depth = pm_parser_local_depth(parser, &identifier); + } + + if (depth == -1) { + value = (pm_node_t *) pm_call_node_variable_call_create(parser, &identifier); + } else { + value = (pm_node_t *) pm_local_variable_read_node_create(parser, &identifier, (uint32_t) depth); + } + } + + value->location.end++; + value = (pm_node_t *) pm_implicit_node_create(parser, value); + } + + element = (pm_node_t *) pm_assoc_node_create(parser, key, &operator, value); + break; + } + default: { + pm_node_t *key = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, true, PM_ERR_HASH_KEY, (uint16_t) (depth + 1)); + + // Hash keys that are strings are automatically frozen. We will + // mark that here. + if (PM_NODE_TYPE_P(key, PM_STRING_NODE)) { + pm_node_flag_set(key, PM_STRING_FLAGS_FROZEN | PM_NODE_FLAG_STATIC_LITERAL); + } + + pm_hash_key_static_literals_add(parser, literals, key); + + pm_token_t operator; + if (pm_symbol_node_label_p(key)) { + operator = not_provided(parser); + } else { + expect1(parser, PM_TOKEN_EQUAL_GREATER, PM_ERR_HASH_ROCKET); + operator = parser->previous; + } + + pm_node_t *value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_HASH_VALUE, (uint16_t) (depth + 1)); + element = (pm_node_t *) pm_assoc_node_create(parser, key, &operator, value); + break; + } + } + + if (PM_NODE_TYPE_P(node, PM_HASH_NODE)) { + pm_hash_node_elements_append((pm_hash_node_t *) node, element); + } else { + pm_keyword_hash_node_elements_append((pm_keyword_hash_node_t *) node, element); + } + + // If there's no comma after the element, then we're done. + if (!accept1(parser, PM_TOKEN_COMMA)) break; + + // If the next element starts with a label or a **, then we know we have + // another element in the hash, so we'll continue parsing. + if (match2(parser, PM_TOKEN_USTAR_STAR, PM_TOKEN_LABEL)) continue; + + // Otherwise we need to check if the subsequent token begins an expression. + // If it does, then we'll continue parsing. + if (token_begins_expression_p(parser->current.type)) continue; + + // Otherwise by default we will exit out of this loop. + break; + } + + return contains_keyword_splat; +} + +/** + * Append an argument to a list of arguments. + */ +static inline void +parse_arguments_append(pm_parser_t *parser, pm_arguments_t *arguments, pm_node_t *argument) { + if (arguments->arguments == NULL) { + arguments->arguments = pm_arguments_node_create(parser); + } + + pm_arguments_node_arguments_append(arguments->arguments, argument); +} + +/** + * Parse a list of arguments. + */ +static void +parse_arguments(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_forwarding, pm_token_type_t terminator, uint16_t depth) { + pm_binding_power_t binding_power = pm_binding_powers[parser->current.type].left; + + // First we need to check if the next token is one that could be the start + // of an argument. If it's not, then we can just return. + if ( + match2(parser, terminator, PM_TOKEN_EOF) || + (binding_power != PM_BINDING_POWER_UNSET && binding_power < PM_BINDING_POWER_RANGE) || + context_terminator(parser->current_context->context, &parser->current) + ) { + return; + } + + bool parsed_first_argument = false; + bool parsed_bare_hash = false; + bool parsed_block_argument = false; + bool parsed_forwarding_arguments = false; + + while (!match1(parser, PM_TOKEN_EOF)) { + if (parsed_forwarding_arguments) { + pm_parser_err_current(parser, PM_ERR_ARGUMENT_AFTER_FORWARDING_ELLIPSES); + } + + pm_node_t *argument = NULL; + + switch (parser->current.type) { + case PM_TOKEN_USTAR_STAR: + case PM_TOKEN_LABEL: { + if (parsed_bare_hash) { + pm_parser_err_current(parser, PM_ERR_ARGUMENT_BARE_HASH); + } + + pm_keyword_hash_node_t *hash = pm_keyword_hash_node_create(parser); + argument = (pm_node_t *) hash; + + pm_static_literals_t hash_keys = { 0 }; + bool contains_keyword_splat = parse_assocs(parser, &hash_keys, (pm_node_t *) hash, (uint16_t) (depth + 1)); + + parse_arguments_append(parser, arguments, argument); + + pm_node_flags_t flags = PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORDS; + if (contains_keyword_splat) flags |= PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORD_SPLAT; + pm_node_flag_set((pm_node_t *) arguments->arguments, flags); + + pm_static_literals_free(&hash_keys); + parsed_bare_hash = true; + + break; + } + case PM_TOKEN_UAMPERSAND: { + parser_lex(parser); + pm_token_t operator = parser->previous; + pm_node_t *expression = NULL; + + if (token_begins_expression_p(parser->current.type)) { + expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_EXPECT_ARGUMENT, (uint16_t) (depth + 1)); + } else { + pm_parser_scope_forwarding_block_check(parser, &operator); + } + + argument = (pm_node_t *) pm_block_argument_node_create(parser, &operator, expression); + if (parsed_block_argument) { + parse_arguments_append(parser, arguments, argument); + } else { + arguments->block = argument; + } + + if (match1(parser, PM_TOKEN_COMMA)) { + pm_parser_err_current(parser, PM_ERR_ARGUMENT_AFTER_BLOCK); + } + + parsed_block_argument = true; + break; + } + case PM_TOKEN_USTAR: { + parser_lex(parser); + pm_token_t operator = parser->previous; + + if (match4(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_TOKEN_COMMA, PM_TOKEN_SEMICOLON, PM_TOKEN_BRACKET_RIGHT)) { + pm_parser_scope_forwarding_positionals_check(parser, &operator); + argument = (pm_node_t *) pm_splat_node_create(parser, &operator, NULL); + if (parsed_bare_hash) { + pm_parser_err_previous(parser, PM_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT); + } + } else { + pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_SPLAT, (uint16_t) (depth + 1)); + + if (parsed_bare_hash) { + pm_parser_err(parser, operator.start, expression->location.end, PM_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT); + } + + argument = (pm_node_t *) pm_splat_node_create(parser, &operator, expression); + } + + parse_arguments_append(parser, arguments, argument); + break; + } + case PM_TOKEN_UDOT_DOT_DOT: { + if (accepts_forwarding) { + parser_lex(parser); + + if (token_begins_expression_p(parser->current.type)) { + // If the token begins an expression then this ... was + // not actually argument forwarding but was instead a + // range. + pm_token_t operator = parser->previous; + pm_node_t *right = parse_expression(parser, PM_BINDING_POWER_RANGE, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1)); + + // If we parse a range, we need to validate that we + // didn't accidentally violate the nonassoc rules of the + // ... operator. + if (PM_NODE_TYPE_P(right, PM_RANGE_NODE)) { + pm_range_node_t *range = (pm_range_node_t *) right; + pm_parser_err(parser, range->operator_loc.start, range->operator_loc.end, PM_ERR_UNEXPECTED_RANGE_OPERATOR); + } + + argument = (pm_node_t *) pm_range_node_create(parser, NULL, &operator, right); + } else { + pm_parser_scope_forwarding_all_check(parser, &parser->previous); + if (parsed_first_argument && terminator == PM_TOKEN_EOF) { + pm_parser_err_previous(parser, PM_ERR_ARGUMENT_FORWARDING_UNBOUND); + } + + argument = (pm_node_t *) pm_forwarding_arguments_node_create(parser, &parser->previous); + parse_arguments_append(parser, arguments, argument); + pm_node_flag_set((pm_node_t *) arguments->arguments, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_FORWARDING); + arguments->has_forwarding = true; + parsed_forwarding_arguments = true; + break; + } + } + } + PRISM_FALLTHROUGH + default: { + if (argument == NULL) { + argument = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, !parsed_first_argument, true, PM_ERR_EXPECT_ARGUMENT, (uint16_t) (depth + 1)); + } + + bool contains_keywords = false; + bool contains_keyword_splat = false; + + if (pm_symbol_node_label_p(argument) || accept1(parser, PM_TOKEN_EQUAL_GREATER)) { + if (parsed_bare_hash) { + pm_parser_err_previous(parser, PM_ERR_ARGUMENT_BARE_HASH); + } + + pm_token_t operator; + if (parser->previous.type == PM_TOKEN_EQUAL_GREATER) { + operator = parser->previous; + } else { + operator = not_provided(parser); + } + + pm_keyword_hash_node_t *bare_hash = pm_keyword_hash_node_create(parser); + contains_keywords = true; + + // Create the set of static literals for this hash. + pm_static_literals_t hash_keys = { 0 }; + pm_hash_key_static_literals_add(parser, &hash_keys, argument); + + // Finish parsing the one we are part way through. + pm_node_t *value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_HASH_VALUE, (uint16_t) (depth + 1)); + argument = (pm_node_t *) pm_assoc_node_create(parser, argument, &operator, value); + + pm_keyword_hash_node_elements_append(bare_hash, argument); + argument = (pm_node_t *) bare_hash; + + // Then parse more if we have a comma + if (accept1(parser, PM_TOKEN_COMMA) && ( + token_begins_expression_p(parser->current.type) || + match2(parser, PM_TOKEN_USTAR_STAR, PM_TOKEN_LABEL) + )) { + contains_keyword_splat = parse_assocs(parser, &hash_keys, (pm_node_t *) bare_hash, (uint16_t) (depth + 1)); + } + + pm_static_literals_free(&hash_keys); + parsed_bare_hash = true; + } + + parse_arguments_append(parser, arguments, argument); + + pm_node_flags_t flags = 0; + if (contains_keywords) flags |= PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORDS; + if (contains_keyword_splat) flags |= PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORD_SPLAT; + pm_node_flag_set((pm_node_t *) arguments->arguments, flags); + + break; + } + } + + parsed_first_argument = true; + + // If parsing the argument failed, we need to stop parsing arguments. + if (PM_NODE_TYPE_P(argument, PM_MISSING_NODE) || parser->recovering) break; + + // If the terminator of these arguments is not EOF, then we have a + // specific token we're looking for. In that case we can accept a + // newline here because it is not functioning as a statement terminator. + bool accepted_newline = false; + if (terminator != PM_TOKEN_EOF) { + accepted_newline = accept1(parser, PM_TOKEN_NEWLINE); + } + + if (parser->previous.type == PM_TOKEN_COMMA && parsed_bare_hash) { + // If we previously were on a comma and we just parsed a bare hash, + // then we want to continue parsing arguments. This is because the + // comma was grabbed up by the hash parser. + } else if (accept1(parser, PM_TOKEN_COMMA)) { + // If there was a comma, then we need to check if we also accepted a + // newline. If we did, then this is a syntax error. + if (accepted_newline) { + pm_parser_err_previous(parser, PM_ERR_INVALID_COMMA); + } + } else { + // If there is no comma at the end of the argument list then we're + // done parsing arguments and can break out of this loop. + break; + } + + // If we hit the terminator, then that means we have a trailing comma so + // we can accept that output as well. + if (match1(parser, terminator)) break; + } +} + +/** + * Required parameters on method, block, and lambda declarations can be + * destructured using parentheses. This looks like: + * + * def foo((bar, baz)) + * end + * + * + * It can recurse infinitely down, and splats are allowed to group arguments. + */ +static pm_multi_target_node_t * +parse_required_destructured_parameter(pm_parser_t *parser) { + expect1(parser, PM_TOKEN_PARENTHESIS_LEFT, PM_ERR_EXPECT_LPAREN_REQ_PARAMETER); + + pm_multi_target_node_t *node = pm_multi_target_node_create(parser); + pm_multi_target_node_opening_set(node, &parser->previous); + + do { + pm_node_t *param; + + // If we get here then we have a trailing comma, which isn't allowed in + // the grammar. In other places, multi targets _do_ allow trailing + // commas, so here we'll assume this is a mistake of the user not + // knowing it's not allowed here. + if (node->lefts.size > 0 && match1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) { + param = (pm_node_t *) pm_implicit_rest_node_create(parser, &parser->previous); + pm_multi_target_node_targets_append(parser, node, param); + pm_parser_err_current(parser, PM_ERR_PARAMETER_WILD_LOOSE_COMMA); + break; + } + + if (match1(parser, PM_TOKEN_PARENTHESIS_LEFT)) { + param = (pm_node_t *) parse_required_destructured_parameter(parser); + } else if (accept1(parser, PM_TOKEN_USTAR)) { + pm_token_t star = parser->previous; + pm_node_t *value = NULL; + + if (accept1(parser, PM_TOKEN_IDENTIFIER)) { + pm_token_t name = parser->previous; + value = (pm_node_t *) pm_required_parameter_node_create(parser, &name); + if (pm_parser_parameter_name_check(parser, &name)) { + pm_node_flag_set_repeated_parameter(value); + } + pm_parser_local_add_token(parser, &name, 1); + } + + param = (pm_node_t *) pm_splat_node_create(parser, &star, value); + } else { + expect1(parser, PM_TOKEN_IDENTIFIER, PM_ERR_EXPECT_IDENT_REQ_PARAMETER); + pm_token_t name = parser->previous; + + param = (pm_node_t *) pm_required_parameter_node_create(parser, &name); + if (pm_parser_parameter_name_check(parser, &name)) { + pm_node_flag_set_repeated_parameter(param); + } + pm_parser_local_add_token(parser, &name, 1); + } + + pm_multi_target_node_targets_append(parser, node, param); + } while (accept1(parser, PM_TOKEN_COMMA)); + + accept1(parser, PM_TOKEN_NEWLINE); + expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_EXPECT_RPAREN_REQ_PARAMETER); + pm_multi_target_node_closing_set(node, &parser->previous); + + return node; +} + +/** + * This represents the different order states we can be in when parsing + * method parameters. + */ +typedef enum { + PM_PARAMETERS_NO_CHANGE = 0, // Extra state for tokens that should not change the state + PM_PARAMETERS_ORDER_NOTHING_AFTER = 1, + PM_PARAMETERS_ORDER_KEYWORDS_REST, + PM_PARAMETERS_ORDER_KEYWORDS, + PM_PARAMETERS_ORDER_REST, + PM_PARAMETERS_ORDER_AFTER_OPTIONAL, + PM_PARAMETERS_ORDER_OPTIONAL, + PM_PARAMETERS_ORDER_NAMED, + PM_PARAMETERS_ORDER_NONE, +} pm_parameters_order_t; + +/** + * This matches parameters tokens with parameters state. + */ +static pm_parameters_order_t parameters_ordering[PM_TOKEN_MAXIMUM] = { + [0] = PM_PARAMETERS_NO_CHANGE, + [PM_TOKEN_UAMPERSAND] = PM_PARAMETERS_ORDER_NOTHING_AFTER, + [PM_TOKEN_AMPERSAND] = PM_PARAMETERS_ORDER_NOTHING_AFTER, + [PM_TOKEN_UDOT_DOT_DOT] = PM_PARAMETERS_ORDER_NOTHING_AFTER, + [PM_TOKEN_IDENTIFIER] = PM_PARAMETERS_ORDER_NAMED, + [PM_TOKEN_PARENTHESIS_LEFT] = PM_PARAMETERS_ORDER_NAMED, + [PM_TOKEN_EQUAL] = PM_PARAMETERS_ORDER_OPTIONAL, + [PM_TOKEN_LABEL] = PM_PARAMETERS_ORDER_KEYWORDS, + [PM_TOKEN_USTAR] = PM_PARAMETERS_ORDER_AFTER_OPTIONAL, + [PM_TOKEN_STAR] = PM_PARAMETERS_ORDER_AFTER_OPTIONAL, + [PM_TOKEN_USTAR_STAR] = PM_PARAMETERS_ORDER_KEYWORDS_REST, + [PM_TOKEN_STAR_STAR] = PM_PARAMETERS_ORDER_KEYWORDS_REST +}; + +/** + * Check if current parameter follows valid parameters ordering. If not it adds + * an error to the list without stopping the parsing, otherwise sets the + * parameters state to the one corresponding to the current parameter. + * + * It returns true if it was successful, and false otherwise. + */ +static bool +update_parameter_state(pm_parser_t *parser, pm_token_t *token, pm_parameters_order_t *current) { + pm_parameters_order_t state = parameters_ordering[token->type]; + if (state == PM_PARAMETERS_NO_CHANGE) return true; + + // If we see another ordered argument after a optional argument + // we only continue parsing ordered arguments until we stop seeing ordered arguments. + if (*current == PM_PARAMETERS_ORDER_OPTIONAL && state == PM_PARAMETERS_ORDER_NAMED) { + *current = PM_PARAMETERS_ORDER_AFTER_OPTIONAL; + return true; + } else if (*current == PM_PARAMETERS_ORDER_AFTER_OPTIONAL && state == PM_PARAMETERS_ORDER_NAMED) { + return true; + } + + if (token->type == PM_TOKEN_USTAR && *current == PM_PARAMETERS_ORDER_AFTER_OPTIONAL) { + pm_parser_err_token(parser, token, PM_ERR_PARAMETER_STAR); + return false; + } else if (token->type == PM_TOKEN_UDOT_DOT_DOT && (*current >= PM_PARAMETERS_ORDER_KEYWORDS_REST && *current <= PM_PARAMETERS_ORDER_AFTER_OPTIONAL)) { + pm_parser_err_token(parser, token, *current == PM_PARAMETERS_ORDER_AFTER_OPTIONAL ? PM_ERR_PARAMETER_FORWARDING_AFTER_REST : PM_ERR_PARAMETER_ORDER); + return false; + } else if (*current == PM_PARAMETERS_ORDER_NOTHING_AFTER || state > *current) { + // We know what transition we failed on, so we can provide a better error here. + pm_parser_err_token(parser, token, PM_ERR_PARAMETER_ORDER); + return false; + } + + if (state < *current) *current = state; + return true; +} + +/** + * Parse a list of parameters on a method definition. + */ +static pm_parameters_node_t * +parse_parameters( + pm_parser_t *parser, + pm_binding_power_t binding_power, + bool uses_parentheses, + bool allows_trailing_comma, + bool allows_forwarding_parameters, + bool accepts_blocks_in_defaults, + bool in_block, + uint16_t depth +) { + pm_do_loop_stack_push(parser, false); + + pm_parameters_node_t *params = pm_parameters_node_create(parser); + pm_parameters_order_t order = PM_PARAMETERS_ORDER_NONE; + + while (true) { + bool parsing = true; + + switch (parser->current.type) { + case PM_TOKEN_PARENTHESIS_LEFT: { + update_parameter_state(parser, &parser->current, &order); + pm_node_t *param = (pm_node_t *) parse_required_destructured_parameter(parser); + + if (order > PM_PARAMETERS_ORDER_AFTER_OPTIONAL) { + pm_parameters_node_requireds_append(params, param); + } else { + pm_parameters_node_posts_append(params, param); + } + break; + } + case PM_TOKEN_UAMPERSAND: + case PM_TOKEN_AMPERSAND: { + update_parameter_state(parser, &parser->current, &order); + parser_lex(parser); + + pm_token_t operator = parser->previous; + pm_token_t name; + + bool repeated = false; + if (accept1(parser, PM_TOKEN_IDENTIFIER)) { + name = parser->previous; + repeated = pm_parser_parameter_name_check(parser, &name); + pm_parser_local_add_token(parser, &name, 1); + } else { + name = not_provided(parser); + parser->current_scope->parameters |= PM_SCOPE_PARAMETERS_FORWARDING_BLOCK; + } + + pm_block_parameter_node_t *param = pm_block_parameter_node_create(parser, &name, &operator); + if (repeated) { + pm_node_flag_set_repeated_parameter((pm_node_t *)param); + } + if (params->block == NULL) { + pm_parameters_node_block_set(params, param); + } else { + pm_parser_err_node(parser, (pm_node_t *) param, PM_ERR_PARAMETER_BLOCK_MULTI); + pm_parameters_node_posts_append(params, (pm_node_t *) param); + } + + break; + } + case PM_TOKEN_UDOT_DOT_DOT: { + if (!allows_forwarding_parameters) { + pm_parser_err_current(parser, PM_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES); + } + + bool succeeded = update_parameter_state(parser, &parser->current, &order); + parser_lex(parser); + + parser->current_scope->parameters |= PM_SCOPE_PARAMETERS_FORWARDING_ALL; + pm_forwarding_parameter_node_t *param = pm_forwarding_parameter_node_create(parser, &parser->previous); + + if (params->keyword_rest != NULL) { + // If we already have a keyword rest parameter, then we replace it with the + // forwarding parameter and move the keyword rest parameter to the posts list. + pm_node_t *keyword_rest = params->keyword_rest; + pm_parameters_node_posts_append(params, keyword_rest); + if (succeeded) pm_parser_err_previous(parser, PM_ERR_PARAMETER_UNEXPECTED_FWD); + params->keyword_rest = NULL; + } + + pm_parameters_node_keyword_rest_set(params, (pm_node_t *) param); + break; + } + case PM_TOKEN_CLASS_VARIABLE: + case PM_TOKEN_IDENTIFIER: + case PM_TOKEN_CONSTANT: + case PM_TOKEN_INSTANCE_VARIABLE: + case PM_TOKEN_GLOBAL_VARIABLE: + case PM_TOKEN_METHOD_NAME: { + parser_lex(parser); + switch (parser->previous.type) { + case PM_TOKEN_CONSTANT: + pm_parser_err_previous(parser, PM_ERR_ARGUMENT_FORMAL_CONSTANT); + break; + case PM_TOKEN_INSTANCE_VARIABLE: + pm_parser_err_previous(parser, PM_ERR_ARGUMENT_FORMAL_IVAR); + break; + case PM_TOKEN_GLOBAL_VARIABLE: + pm_parser_err_previous(parser, PM_ERR_ARGUMENT_FORMAL_GLOBAL); + break; + case PM_TOKEN_CLASS_VARIABLE: + pm_parser_err_previous(parser, PM_ERR_ARGUMENT_FORMAL_CLASS); + break; + case PM_TOKEN_METHOD_NAME: + pm_parser_err_previous(parser, PM_ERR_PARAMETER_METHOD_NAME); + break; + default: break; + } + + if (parser->current.type == PM_TOKEN_EQUAL) { + update_parameter_state(parser, &parser->current, &order); + } else { + update_parameter_state(parser, &parser->previous, &order); + } + + pm_token_t name = parser->previous; + bool repeated = pm_parser_parameter_name_check(parser, &name); + pm_parser_local_add_token(parser, &name, 1); + + if (match1(parser, PM_TOKEN_EQUAL)) { + pm_token_t operator = parser->current; + context_push(parser, PM_CONTEXT_DEFAULT_PARAMS); + parser_lex(parser); + + pm_constant_id_t name_id = pm_parser_constant_id_token(parser, &name); + uint32_t reads = parser->version == PM_OPTIONS_VERSION_CRUBY_3_3 ? pm_locals_reads(&parser->current_scope->locals, name_id) : 0; + + if (accepts_blocks_in_defaults) pm_accepts_block_stack_push(parser, true); + pm_node_t *value = parse_value_expression(parser, binding_power, false, false, PM_ERR_PARAMETER_NO_DEFAULT, (uint16_t) (depth + 1)); + if (accepts_blocks_in_defaults) pm_accepts_block_stack_pop(parser); + + pm_optional_parameter_node_t *param = pm_optional_parameter_node_create(parser, &name, &operator, value); + + if (repeated) { + pm_node_flag_set_repeated_parameter((pm_node_t *) param); + } + pm_parameters_node_optionals_append(params, param); + + // If the value of the parameter increased the number of + // reads of that parameter, then we need to warn that we + // have a circular definition. + if ((parser->version == PM_OPTIONS_VERSION_CRUBY_3_3) && (pm_locals_reads(&parser->current_scope->locals, name_id) != reads)) { + PM_PARSER_ERR_TOKEN_FORMAT_CONTENT(parser, name, PM_ERR_PARAMETER_CIRCULAR); + } + + context_pop(parser); + + // If parsing the value of the parameter resulted in error recovery, + // then we can put a missing node in its place and stop parsing the + // parameters entirely now. + if (parser->recovering) { + parsing = false; + break; + } + } else if (order > PM_PARAMETERS_ORDER_AFTER_OPTIONAL) { + pm_required_parameter_node_t *param = pm_required_parameter_node_create(parser, &name); + if (repeated) { + pm_node_flag_set_repeated_parameter((pm_node_t *)param); + } + pm_parameters_node_requireds_append(params, (pm_node_t *) param); + } else { + pm_required_parameter_node_t *param = pm_required_parameter_node_create(parser, &name); + if (repeated) { + pm_node_flag_set_repeated_parameter((pm_node_t *)param); + } + pm_parameters_node_posts_append(params, (pm_node_t *) param); + } + + break; + } + case PM_TOKEN_LABEL: { + if (!uses_parentheses && !in_block) parser->in_keyword_arg = true; + update_parameter_state(parser, &parser->current, &order); + + context_push(parser, PM_CONTEXT_DEFAULT_PARAMS); + parser_lex(parser); + + pm_token_t name = parser->previous; + pm_token_t local = name; + local.end -= 1; + + if (parser->encoding_changed ? parser->encoding->isupper_char(local.start, local.end - local.start) : pm_encoding_utf_8_isupper_char(local.start, local.end - local.start)) { + pm_parser_err(parser, local.start, local.end, PM_ERR_ARGUMENT_FORMAL_CONSTANT); + } else if (local.end[-1] == '!' || local.end[-1] == '?') { + PM_PARSER_ERR_TOKEN_FORMAT_CONTENT(parser, local, PM_ERR_INVALID_LOCAL_VARIABLE_WRITE); + } + + bool repeated = pm_parser_parameter_name_check(parser, &local); + pm_parser_local_add_token(parser, &local, 1); + + switch (parser->current.type) { + case PM_TOKEN_COMMA: + case PM_TOKEN_PARENTHESIS_RIGHT: + case PM_TOKEN_PIPE: { + context_pop(parser); + + pm_node_t *param = (pm_node_t *) pm_required_keyword_parameter_node_create(parser, &name); + if (repeated) { + pm_node_flag_set_repeated_parameter(param); + } + + pm_parameters_node_keywords_append(params, param); + break; + } + case PM_TOKEN_SEMICOLON: + case PM_TOKEN_NEWLINE: { + context_pop(parser); + + if (uses_parentheses) { + parsing = false; + break; + } + + pm_node_t *param = (pm_node_t *) pm_required_keyword_parameter_node_create(parser, &name); + if (repeated) { + pm_node_flag_set_repeated_parameter(param); + } + + pm_parameters_node_keywords_append(params, param); + break; + } + default: { + pm_node_t *param; + + if (token_begins_expression_p(parser->current.type)) { + pm_constant_id_t name_id = pm_parser_constant_id_token(parser, &local); + uint32_t reads = parser->version == PM_OPTIONS_VERSION_CRUBY_3_3 ? pm_locals_reads(&parser->current_scope->locals, name_id) : 0; + + if (accepts_blocks_in_defaults) pm_accepts_block_stack_push(parser, true); + pm_node_t *value = parse_value_expression(parser, binding_power, false, false, PM_ERR_PARAMETER_NO_DEFAULT_KW, (uint16_t) (depth + 1)); + if (accepts_blocks_in_defaults) pm_accepts_block_stack_pop(parser); + + if (parser->version == PM_OPTIONS_VERSION_CRUBY_3_3 && (pm_locals_reads(&parser->current_scope->locals, name_id) != reads)) { + PM_PARSER_ERR_TOKEN_FORMAT_CONTENT(parser, local, PM_ERR_PARAMETER_CIRCULAR); + } + + param = (pm_node_t *) pm_optional_keyword_parameter_node_create(parser, &name, value); + } + else { + param = (pm_node_t *) pm_required_keyword_parameter_node_create(parser, &name); + } + + if (repeated) { + pm_node_flag_set_repeated_parameter(param); + } + + context_pop(parser); + pm_parameters_node_keywords_append(params, param); + + // If parsing the value of the parameter resulted in error recovery, + // then we can put a missing node in its place and stop parsing the + // parameters entirely now. + if (parser->recovering) { + parsing = false; + break; + } + } + } + + parser->in_keyword_arg = false; + break; + } + case PM_TOKEN_USTAR: + case PM_TOKEN_STAR: { + update_parameter_state(parser, &parser->current, &order); + parser_lex(parser); + + pm_token_t operator = parser->previous; + pm_token_t name; + bool repeated = false; + + if (accept1(parser, PM_TOKEN_IDENTIFIER)) { + name = parser->previous; + repeated = pm_parser_parameter_name_check(parser, &name); + pm_parser_local_add_token(parser, &name, 1); + } else { + name = not_provided(parser); + parser->current_scope->parameters |= PM_SCOPE_PARAMETERS_FORWARDING_POSITIONALS; + } + + pm_node_t *param = (pm_node_t *) pm_rest_parameter_node_create(parser, &operator, &name); + if (repeated) { + pm_node_flag_set_repeated_parameter(param); + } + + if (params->rest == NULL) { + pm_parameters_node_rest_set(params, param); + } else { + pm_parser_err_node(parser, param, PM_ERR_PARAMETER_SPLAT_MULTI); + pm_parameters_node_posts_append(params, param); + } + + break; + } + case PM_TOKEN_STAR_STAR: + case PM_TOKEN_USTAR_STAR: { + pm_parameters_order_t previous_order = order; + update_parameter_state(parser, &parser->current, &order); + parser_lex(parser); + + pm_token_t operator = parser->previous; + pm_node_t *param; + + if (accept1(parser, PM_TOKEN_KEYWORD_NIL)) { + if (previous_order <= PM_PARAMETERS_ORDER_KEYWORDS) { + pm_parser_err_previous(parser, PM_ERR_PARAMETER_UNEXPECTED_NO_KW); + } + + param = (pm_node_t *) pm_no_keywords_parameter_node_create(parser, &operator, &parser->previous); + } else { + pm_token_t name; + + bool repeated = false; + if (accept1(parser, PM_TOKEN_IDENTIFIER)) { + name = parser->previous; + repeated = pm_parser_parameter_name_check(parser, &name); + pm_parser_local_add_token(parser, &name, 1); + } else { + name = not_provided(parser); + parser->current_scope->parameters |= PM_SCOPE_PARAMETERS_FORWARDING_KEYWORDS; + } + + param = (pm_node_t *) pm_keyword_rest_parameter_node_create(parser, &operator, &name); + if (repeated) { + pm_node_flag_set_repeated_parameter(param); + } + } + + if (params->keyword_rest == NULL) { + pm_parameters_node_keyword_rest_set(params, param); + } else { + pm_parser_err_node(parser, param, PM_ERR_PARAMETER_ASSOC_SPLAT_MULTI); + pm_parameters_node_posts_append(params, param); + } + + break; + } + default: + if (parser->previous.type == PM_TOKEN_COMMA) { + if (allows_trailing_comma && order >= PM_PARAMETERS_ORDER_NAMED) { + // If we get here, then we have a trailing comma in a + // block parameter list. + pm_node_t *param = (pm_node_t *) pm_implicit_rest_node_create(parser, &parser->previous); + + if (params->rest == NULL) { + pm_parameters_node_rest_set(params, param); + } else { + pm_parser_err_node(parser, (pm_node_t *) param, PM_ERR_PARAMETER_SPLAT_MULTI); + pm_parameters_node_posts_append(params, (pm_node_t *) param); + } + } else { + pm_parser_err_previous(parser, PM_ERR_PARAMETER_WILD_LOOSE_COMMA); + } + } + + parsing = false; + break; + } + + // If we hit some kind of issue while parsing the parameter, this would + // have been set to false. In that case, we need to break out of the + // loop. + if (!parsing) break; + + bool accepted_newline = false; + if (uses_parentheses) { + accepted_newline = accept1(parser, PM_TOKEN_NEWLINE); + } + + if (accept1(parser, PM_TOKEN_COMMA)) { + // If there was a comma, but we also accepted a newline, then this + // is a syntax error. + if (accepted_newline) { + pm_parser_err_previous(parser, PM_ERR_INVALID_COMMA); + } + } else { + // If there was no comma, then we're done parsing parameters. + break; + } + } + + pm_do_loop_stack_pop(parser); + + // If we don't have any parameters, return `NULL` instead of an empty `ParametersNode`. + if (params->base.location.start == params->base.location.end) { + pm_node_destroy(parser, (pm_node_t *) params); + return NULL; + } + + return params; +} + +/** + * Accepts a parser returns the index of the last newline in the file that was + * ecorded before the current token within the newline list. + */ +static size_t +token_newline_index(const pm_parser_t *parser) { + if (parser->heredoc_end == NULL) { + // This is the common case. In this case we can look at the previously + // recorded newline in the newline list and subtract from the current + // offset. + return parser->newline_list.size - 1; + } else { + // This is unlikely. This is the case that we have already parsed the + // start of a heredoc, so we cannot rely on looking at the previous + // offset of the newline list, and instead must go through the whole + // process of a binary search for the line number. + return (size_t) pm_newline_list_line(&parser->newline_list, parser->current.start, 0); + } +} + +/** + * Accepts a parser, a newline index, and a token and returns the column. The + * important piece of this is that it expands tabs out to the next tab stop. + */ +static int64_t +token_column(const pm_parser_t *parser, size_t newline_index, const pm_token_t *token, bool break_on_non_space) { + const uint8_t *cursor = parser->start + parser->newline_list.offsets[newline_index]; + const uint8_t *end = token->start; + + // Skip over the BOM if it is present. + if ( + newline_index == 0 && + parser->start[0] == 0xef && + parser->start[1] == 0xbb && + parser->start[2] == 0xbf + ) cursor += 3; + + int64_t column = 0; + for (; cursor < end; cursor++) { + switch (*cursor) { + case '\t': + column = ((column / PM_TAB_WHITESPACE_SIZE) + 1) * PM_TAB_WHITESPACE_SIZE; + break; + case ' ': + column++; + break; + default: + column++; + if (break_on_non_space) return -1; + break; + } + } + + return column; +} + +/** + * Accepts a parser, two newline indices, and pointers to two tokens. This + * function warns if the indentation of the two tokens does not match. + */ +static void +parser_warn_indentation_mismatch(pm_parser_t *parser, size_t opening_newline_index, const pm_token_t *opening_token, bool if_after_else, bool allow_indent) { + // If these warnings are disabled (unlikely), then we can just return. + if (!parser->warn_mismatched_indentation) return; + + // If the tokens are on the same line, we do not warn. + size_t closing_newline_index = token_newline_index(parser); + if (opening_newline_index == closing_newline_index) return; + + // If the opening token has anything other than spaces or tabs before it, + // then we do not warn. This is unless we are matching up an `if`/`end` pair + // and the `if` immediately follows an `else` keyword. + int64_t opening_column = token_column(parser, opening_newline_index, opening_token, !if_after_else); + if (!if_after_else && (opening_column == -1)) return; + + // Get a reference to the closing token off the current parser. This assumes + // that the caller has placed this in the correct position. + pm_token_t *closing_token = &parser->current; + + // If the tokens are at the same indentation, we do not warn. + int64_t closing_column = token_column(parser, closing_newline_index, closing_token, true); + if ((closing_column == -1) || (opening_column == closing_column)) return; + + // If the closing column is greater than the opening column and we are + // allowing indentation, then we do not warn. + if (allow_indent && (closing_column > opening_column)) return; + + // Otherwise, add a warning. + PM_PARSER_WARN_FORMAT( + parser, + closing_token->start, + closing_token->end, + PM_WARN_INDENTATION_MISMATCH, + (int) (closing_token->end - closing_token->start), + (const char *) closing_token->start, + (int) (opening_token->end - opening_token->start), + (const char *) opening_token->start, + ((int32_t) opening_newline_index) + parser->start_line + ); +} + +typedef enum { + PM_RESCUES_BEGIN = 1, + PM_RESCUES_BLOCK, + PM_RESCUES_CLASS, + PM_RESCUES_DEF, + PM_RESCUES_LAMBDA, + PM_RESCUES_MODULE, + PM_RESCUES_SCLASS +} pm_rescues_type_t; + +/** + * Parse any number of rescue clauses. This will form a linked list of if + * nodes pointing to each other from the top. + */ +static inline void +parse_rescues(pm_parser_t *parser, size_t opening_newline_index, const pm_token_t *opening, pm_begin_node_t *parent_node, pm_rescues_type_t type, uint16_t depth) { + pm_rescue_node_t *current = NULL; + + while (match1(parser, PM_TOKEN_KEYWORD_RESCUE)) { + if (opening != NULL) parser_warn_indentation_mismatch(parser, opening_newline_index, opening, false, false); + parser_lex(parser); + + pm_rescue_node_t *rescue = pm_rescue_node_create(parser, &parser->previous); + + switch (parser->current.type) { + case PM_TOKEN_EQUAL_GREATER: { + // Here we have an immediate => after the rescue keyword, in which case + // we're going to have an empty list of exceptions to rescue (which + // implies StandardError). + parser_lex(parser); + pm_rescue_node_operator_set(rescue, &parser->previous); + + pm_node_t *reference = parse_expression(parser, PM_BINDING_POWER_INDEX, false, false, PM_ERR_RESCUE_VARIABLE, (uint16_t) (depth + 1)); + reference = parse_target(parser, reference, false, false); + + pm_rescue_node_reference_set(rescue, reference); + break; + } + case PM_TOKEN_NEWLINE: + case PM_TOKEN_SEMICOLON: + case PM_TOKEN_KEYWORD_THEN: + // Here we have a terminator for the rescue keyword, in which + // case we're going to just continue on. + break; + default: { + if (token_begins_expression_p(parser->current.type) || match1(parser, PM_TOKEN_USTAR)) { + // Here we have something that could be an exception expression, so + // we'll attempt to parse it here and any others delimited by commas. + + do { + pm_node_t *expression = parse_starred_expression(parser, PM_BINDING_POWER_DEFINED, false, PM_ERR_RESCUE_EXPRESSION, (uint16_t) (depth + 1)); + pm_rescue_node_exceptions_append(rescue, expression); + + // If we hit a newline, then this is the end of the rescue expression. We + // can continue on to parse the statements. + if (match3(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON, PM_TOKEN_KEYWORD_THEN)) break; + + // If we hit a `=>` then we're going to parse the exception variable. Once + // we've done that, we'll break out of the loop and parse the statements. + if (accept1(parser, PM_TOKEN_EQUAL_GREATER)) { + pm_rescue_node_operator_set(rescue, &parser->previous); + + pm_node_t *reference = parse_expression(parser, PM_BINDING_POWER_INDEX, false, false, PM_ERR_RESCUE_VARIABLE, (uint16_t) (depth + 1)); + reference = parse_target(parser, reference, false, false); + + pm_rescue_node_reference_set(rescue, reference); + break; + } + } while (accept1(parser, PM_TOKEN_COMMA)); + } + } + } + + if (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)) { + if (accept1(parser, PM_TOKEN_KEYWORD_THEN)) { + rescue->then_keyword_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(&parser->previous); + } + } else { + expect1(parser, PM_TOKEN_KEYWORD_THEN, PM_ERR_RESCUE_TERM); + rescue->then_keyword_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(&parser->previous); + } + + if (!match3(parser, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_KEYWORD_END)) { + pm_accepts_block_stack_push(parser, true); + pm_context_t context; + + switch (type) { + case PM_RESCUES_BEGIN: context = PM_CONTEXT_BEGIN_RESCUE; break; + case PM_RESCUES_BLOCK: context = PM_CONTEXT_BLOCK_RESCUE; break; + case PM_RESCUES_CLASS: context = PM_CONTEXT_CLASS_RESCUE; break; + case PM_RESCUES_DEF: context = PM_CONTEXT_DEF_RESCUE; break; + case PM_RESCUES_LAMBDA: context = PM_CONTEXT_LAMBDA_RESCUE; break; + case PM_RESCUES_MODULE: context = PM_CONTEXT_MODULE_RESCUE; break; + case PM_RESCUES_SCLASS: context = PM_CONTEXT_SCLASS_RESCUE; break; + default: assert(false && "unreachable"); context = PM_CONTEXT_BEGIN_RESCUE; break; + } + + pm_statements_node_t *statements = parse_statements(parser, context, (uint16_t) (depth + 1)); + if (statements != NULL) pm_rescue_node_statements_set(rescue, statements); + + pm_accepts_block_stack_pop(parser); + accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON); + } + + if (current == NULL) { + pm_begin_node_rescue_clause_set(parent_node, rescue); + } else { + pm_rescue_node_subsequent_set(current, rescue); + } + + current = rescue; + } + + // The end node locations on rescue nodes will not be set correctly + // since we won't know the end until we've found all subsequent + // clauses. This sets the end location on all rescues once we know it. + if (current != NULL) { + const uint8_t *end_to_set = current->base.location.end; + pm_rescue_node_t *clause = parent_node->rescue_clause; + + while (clause != NULL) { + clause->base.location.end = end_to_set; + clause = clause->subsequent; + } + } + + pm_token_t else_keyword; + if (match1(parser, PM_TOKEN_KEYWORD_ELSE)) { + if (opening != NULL) parser_warn_indentation_mismatch(parser, opening_newline_index, opening, false, false); + opening_newline_index = token_newline_index(parser); + + else_keyword = parser->current; + opening = &else_keyword; + + parser_lex(parser); + accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON); + + pm_statements_node_t *else_statements = NULL; + if (!match2(parser, PM_TOKEN_KEYWORD_END, PM_TOKEN_KEYWORD_ENSURE)) { + pm_accepts_block_stack_push(parser, true); + pm_context_t context; + + switch (type) { + case PM_RESCUES_BEGIN: context = PM_CONTEXT_BEGIN_ELSE; break; + case PM_RESCUES_BLOCK: context = PM_CONTEXT_BLOCK_ELSE; break; + case PM_RESCUES_CLASS: context = PM_CONTEXT_CLASS_ELSE; break; + case PM_RESCUES_DEF: context = PM_CONTEXT_DEF_ELSE; break; + case PM_RESCUES_LAMBDA: context = PM_CONTEXT_LAMBDA_ELSE; break; + case PM_RESCUES_MODULE: context = PM_CONTEXT_MODULE_ELSE; break; + case PM_RESCUES_SCLASS: context = PM_CONTEXT_SCLASS_ELSE; break; + default: assert(false && "unreachable"); context = PM_CONTEXT_BEGIN_ELSE; break; + } + + else_statements = parse_statements(parser, context, (uint16_t) (depth + 1)); + pm_accepts_block_stack_pop(parser); + + accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON); + } + + pm_else_node_t *else_clause = pm_else_node_create(parser, &else_keyword, else_statements, &parser->current); + pm_begin_node_else_clause_set(parent_node, else_clause); + + // If we don't have a `current` rescue node, then this is a dangling + // else, and it's an error. + if (current == NULL) pm_parser_err_node(parser, (pm_node_t *) else_clause, PM_ERR_BEGIN_LONELY_ELSE); + } + + if (match1(parser, PM_TOKEN_KEYWORD_ENSURE)) { + if (opening != NULL) parser_warn_indentation_mismatch(parser, opening_newline_index, opening, false, false); + pm_token_t ensure_keyword = parser->current; + + parser_lex(parser); + accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON); + + pm_statements_node_t *ensure_statements = NULL; + if (!match1(parser, PM_TOKEN_KEYWORD_END)) { + pm_accepts_block_stack_push(parser, true); + pm_context_t context; + + switch (type) { + case PM_RESCUES_BEGIN: context = PM_CONTEXT_BEGIN_ENSURE; break; + case PM_RESCUES_BLOCK: context = PM_CONTEXT_BLOCK_ENSURE; break; + case PM_RESCUES_CLASS: context = PM_CONTEXT_CLASS_ENSURE; break; + case PM_RESCUES_DEF: context = PM_CONTEXT_DEF_ENSURE; break; + case PM_RESCUES_LAMBDA: context = PM_CONTEXT_LAMBDA_ENSURE; break; + case PM_RESCUES_MODULE: context = PM_CONTEXT_MODULE_ENSURE; break; + case PM_RESCUES_SCLASS: context = PM_CONTEXT_SCLASS_ENSURE; break; + default: assert(false && "unreachable"); context = PM_CONTEXT_BEGIN_RESCUE; break; + } + + ensure_statements = parse_statements(parser, context, (uint16_t) (depth + 1)); + pm_accepts_block_stack_pop(parser); + + accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON); + } + + pm_ensure_node_t *ensure_clause = pm_ensure_node_create(parser, &ensure_keyword, ensure_statements, &parser->current); + pm_begin_node_ensure_clause_set(parent_node, ensure_clause); + } + + if (match1(parser, PM_TOKEN_KEYWORD_END)) { + if (opening != NULL) parser_warn_indentation_mismatch(parser, opening_newline_index, opening, false, false); + pm_begin_node_end_keyword_set(parent_node, &parser->current); + } else { + pm_token_t end_keyword = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end }; + pm_begin_node_end_keyword_set(parent_node, &end_keyword); + } +} + +/** + * Parse a set of rescue clauses with an implicit begin (for example when on a + * class, module, def, etc.). + */ +static pm_begin_node_t * +parse_rescues_implicit_begin(pm_parser_t *parser, size_t opening_newline_index, const pm_token_t *opening, const uint8_t *start, pm_statements_node_t *statements, pm_rescues_type_t type, uint16_t depth) { + pm_token_t begin_keyword = not_provided(parser); + pm_begin_node_t *node = pm_begin_node_create(parser, &begin_keyword, statements); + + parse_rescues(parser, opening_newline_index, opening, node, type, (uint16_t) (depth + 1)); + node->base.location.start = start; + + return node; +} + +/** + * Parse a list of parameters and local on a block definition. + */ +static pm_block_parameters_node_t * +parse_block_parameters( + pm_parser_t *parser, + bool allows_trailing_comma, + const pm_token_t *opening, + bool is_lambda_literal, + bool accepts_blocks_in_defaults, + uint16_t depth +) { + pm_parameters_node_t *parameters = NULL; + if (!match1(parser, PM_TOKEN_SEMICOLON)) { + parameters = parse_parameters( + parser, + is_lambda_literal ? PM_BINDING_POWER_DEFINED : PM_BINDING_POWER_INDEX, + false, + allows_trailing_comma, + false, + accepts_blocks_in_defaults, + true, + (uint16_t) (depth + 1) + ); + } + + pm_block_parameters_node_t *block_parameters = pm_block_parameters_node_create(parser, parameters, opening); + if ((opening->type != PM_TOKEN_NOT_PROVIDED)) { + accept1(parser, PM_TOKEN_NEWLINE); + + if (accept1(parser, PM_TOKEN_SEMICOLON)) { + do { + switch (parser->current.type) { + case PM_TOKEN_CONSTANT: + pm_parser_err_current(parser, PM_ERR_ARGUMENT_FORMAL_CONSTANT); + parser_lex(parser); + break; + case PM_TOKEN_INSTANCE_VARIABLE: + pm_parser_err_current(parser, PM_ERR_ARGUMENT_FORMAL_IVAR); + parser_lex(parser); + break; + case PM_TOKEN_GLOBAL_VARIABLE: + pm_parser_err_current(parser, PM_ERR_ARGUMENT_FORMAL_GLOBAL); + parser_lex(parser); + break; + case PM_TOKEN_CLASS_VARIABLE: + pm_parser_err_current(parser, PM_ERR_ARGUMENT_FORMAL_CLASS); + parser_lex(parser); + break; + default: + expect1(parser, PM_TOKEN_IDENTIFIER, PM_ERR_BLOCK_PARAM_LOCAL_VARIABLE); + break; + } + + bool repeated = pm_parser_parameter_name_check(parser, &parser->previous); + pm_parser_local_add_token(parser, &parser->previous, 1); + + pm_block_local_variable_node_t *local = pm_block_local_variable_node_create(parser, &parser->previous); + if (repeated) pm_node_flag_set_repeated_parameter((pm_node_t *) local); + + pm_block_parameters_node_append_local(block_parameters, local); + } while (accept1(parser, PM_TOKEN_COMMA)); + } + } + + return block_parameters; +} + +/** + * Return true if any of the visible scopes to the current context are using + * numbered parameters. + */ +static bool +outer_scope_using_numbered_parameters_p(pm_parser_t *parser) { + for (pm_scope_t *scope = parser->current_scope->previous; scope != NULL && !scope->closed; scope = scope->previous) { + if (scope->parameters & PM_SCOPE_PARAMETERS_NUMBERED_FOUND) return true; + } + + return false; +} + +/** + * These are the names of the various numbered parameters. We have them here so + * that when we insert them into the constant pool we can use a constant string + * and not have to allocate. + */ +static const char * const pm_numbered_parameter_names[] = { + "_1", "_2", "_3", "_4", "_5", "_6", "_7", "_8", "_9" +}; + +/** + * Return the node that should be used in the parameters field of a block-like + * (block or lambda) node, depending on the kind of parameters that were + * declared in the current scope. + */ +static pm_node_t * +parse_blocklike_parameters(pm_parser_t *parser, pm_node_t *parameters, const pm_token_t *opening, const pm_token_t *closing) { + pm_node_list_t *implicit_parameters = &parser->current_scope->implicit_parameters; + + // If we have ordinary parameters, then we will return them as the set of + // parameters. + if (parameters != NULL) { + // If we also have implicit parameters, then this is an error. + if (implicit_parameters->size > 0) { + pm_node_t *node = implicit_parameters->nodes[0]; + + if (PM_NODE_TYPE_P(node, PM_LOCAL_VARIABLE_READ_NODE)) { + pm_parser_err_node(parser, node, PM_ERR_NUMBERED_PARAMETER_ORDINARY); + } else if (PM_NODE_TYPE_P(node, PM_IT_LOCAL_VARIABLE_READ_NODE)) { + pm_parser_err_node(parser, node, PM_ERR_IT_NOT_ALLOWED_ORDINARY); + } else { + assert(false && "unreachable"); + } + } + + return parameters; + } + + // If we don't have any implicit parameters, then the set of parameters is + // NULL. + if (implicit_parameters->size == 0) { + return NULL; + } + + // If we don't have ordinary parameters, then we now must validate our set + // of implicit parameters. We can only have numbered parameters or it, but + // they cannot be mixed. + uint8_t numbered_parameter = 0; + bool it_parameter = false; + + for (size_t index = 0; index < implicit_parameters->size; index++) { + pm_node_t *node = implicit_parameters->nodes[index]; + + if (PM_NODE_TYPE_P(node, PM_LOCAL_VARIABLE_READ_NODE)) { + if (it_parameter) { + pm_parser_err_node(parser, node, PM_ERR_NUMBERED_PARAMETER_IT); + } else if (outer_scope_using_numbered_parameters_p(parser)) { + pm_parser_err_node(parser, node, PM_ERR_NUMBERED_PARAMETER_OUTER_BLOCK); + } else if (parser->current_scope->parameters & PM_SCOPE_PARAMETERS_NUMBERED_INNER) { + pm_parser_err_node(parser, node, PM_ERR_NUMBERED_PARAMETER_INNER_BLOCK); + } else if (pm_token_is_numbered_parameter(node->location.start, node->location.end)) { + numbered_parameter = MAX(numbered_parameter, (uint8_t) (node->location.start[1] - '0')); + } else { + assert(false && "unreachable"); + } + } else if (PM_NODE_TYPE_P(node, PM_IT_LOCAL_VARIABLE_READ_NODE)) { + if (numbered_parameter > 0) { + pm_parser_err_node(parser, node, PM_ERR_IT_NOT_ALLOWED_NUMBERED); + } else { + it_parameter = true; + } + } + } + + if (numbered_parameter > 0) { + // Go through the parent scopes and mark them as being disallowed from + // using numbered parameters because this inner scope is using them. + for (pm_scope_t *scope = parser->current_scope->previous; scope != NULL && !scope->closed; scope = scope->previous) { + scope->parameters |= PM_SCOPE_PARAMETERS_NUMBERED_INNER; + } + + const pm_location_t location = { .start = opening->start, .end = closing->end }; + return (pm_node_t *) pm_numbered_parameters_node_create(parser, &location, numbered_parameter); + } + + if (it_parameter) { + return (pm_node_t *) pm_it_parameters_node_create(parser, opening, closing); + } + + return NULL; +} + +/** + * Parse a block. + */ +static pm_block_node_t * +parse_block(pm_parser_t *parser, uint16_t depth) { + pm_token_t opening = parser->previous; + accept1(parser, PM_TOKEN_NEWLINE); + + pm_accepts_block_stack_push(parser, true); + pm_parser_scope_push(parser, false); + + pm_block_parameters_node_t *block_parameters = NULL; + + if (accept1(parser, PM_TOKEN_PIPE)) { + pm_token_t block_parameters_opening = parser->previous; + if (match1(parser, PM_TOKEN_PIPE)) { + block_parameters = pm_block_parameters_node_create(parser, NULL, &block_parameters_opening); + parser->command_start = true; + parser_lex(parser); + } else { + block_parameters = parse_block_parameters(parser, true, &block_parameters_opening, false, true, (uint16_t) (depth + 1)); + accept1(parser, PM_TOKEN_NEWLINE); + parser->command_start = true; + expect1(parser, PM_TOKEN_PIPE, PM_ERR_BLOCK_PARAM_PIPE_TERM); + } + + pm_block_parameters_node_closing_set(block_parameters, &parser->previous); + } + + accept1(parser, PM_TOKEN_NEWLINE); + pm_node_t *statements = NULL; + + if (opening.type == PM_TOKEN_BRACE_LEFT) { + if (!match1(parser, PM_TOKEN_BRACE_RIGHT)) { + statements = (pm_node_t *) parse_statements(parser, PM_CONTEXT_BLOCK_BRACES, (uint16_t) (depth + 1)); + } + + expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_BLOCK_TERM_BRACE); + } else { + if (!match1(parser, PM_TOKEN_KEYWORD_END)) { + if (!match3(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_ENSURE)) { + pm_accepts_block_stack_push(parser, true); + statements = (pm_node_t *) parse_statements(parser, PM_CONTEXT_BLOCK_KEYWORDS, (uint16_t) (depth + 1)); + pm_accepts_block_stack_pop(parser); + } + + if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) { + assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE)); + statements = (pm_node_t *) parse_rescues_implicit_begin(parser, 0, NULL, opening.start, (pm_statements_node_t *) statements, PM_RESCUES_BLOCK, (uint16_t) (depth + 1)); + } + } + + expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_BLOCK_TERM_END); + } + + pm_constant_id_list_t locals; + pm_locals_order(parser, &parser->current_scope->locals, &locals, pm_parser_scope_toplevel_p(parser)); + pm_node_t *parameters = parse_blocklike_parameters(parser, (pm_node_t *) block_parameters, &opening, &parser->previous); + + pm_parser_scope_pop(parser); + pm_accepts_block_stack_pop(parser); + + return pm_block_node_create(parser, &locals, &opening, parameters, statements, &parser->previous); +} + +/** + * Parse a list of arguments and their surrounding parentheses if they are + * present. It returns true if it found any pieces of arguments (parentheses, + * arguments, or blocks). + */ +static bool +parse_arguments_list(pm_parser_t *parser, pm_arguments_t *arguments, bool accepts_block, bool accepts_command_call, uint16_t depth) { + bool found = false; + + if (accept1(parser, PM_TOKEN_PARENTHESIS_LEFT)) { + found |= true; + arguments->opening_loc = PM_LOCATION_TOKEN_VALUE(&parser->previous); + + if (accept1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) { + arguments->closing_loc = PM_LOCATION_TOKEN_VALUE(&parser->previous); + } else { + pm_accepts_block_stack_push(parser, true); + parse_arguments(parser, arguments, accepts_block, PM_TOKEN_PARENTHESIS_RIGHT, (uint16_t) (depth + 1)); + + if (!accept1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_ARGUMENT_TERM_PAREN, pm_token_type_human(parser->current.type)); + parser->previous.start = parser->previous.end; + parser->previous.type = PM_TOKEN_MISSING; + } + + pm_accepts_block_stack_pop(parser); + arguments->closing_loc = PM_LOCATION_TOKEN_VALUE(&parser->previous); + } + } else if (accepts_command_call && (token_begins_expression_p(parser->current.type) || match3(parser, PM_TOKEN_USTAR, PM_TOKEN_USTAR_STAR, PM_TOKEN_UAMPERSAND)) && !match1(parser, PM_TOKEN_BRACE_LEFT)) { + found |= true; + pm_accepts_block_stack_push(parser, false); + + // If we get here, then the subsequent token cannot be used as an infix + // operator. In this case we assume the subsequent token is part of an + // argument to this method call. + parse_arguments(parser, arguments, accepts_block, PM_TOKEN_EOF, (uint16_t) (depth + 1)); + + // If we have done with the arguments and still not consumed the comma, + // then we have a trailing comma where we need to check whether it is + // allowed or not. + if (parser->previous.type == PM_TOKEN_COMMA && !match1(parser, PM_TOKEN_SEMICOLON)) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->previous, PM_ERR_EXPECT_ARGUMENT, pm_token_type_human(parser->current.type)); + } + + pm_accepts_block_stack_pop(parser); + } + + // If we're at the end of the arguments, we can now check if there is a block + // node that starts with a {. If there is, then we can parse it and add it to + // the arguments. + if (accepts_block) { + pm_block_node_t *block = NULL; + + if (accept1(parser, PM_TOKEN_BRACE_LEFT)) { + found |= true; + block = parse_block(parser, (uint16_t) (depth + 1)); + pm_arguments_validate_block(parser, arguments, block); + } else if (pm_accepts_block_stack_p(parser) && accept1(parser, PM_TOKEN_KEYWORD_DO)) { + found |= true; + block = parse_block(parser, (uint16_t) (depth + 1)); + } + + if (block != NULL) { + if (arguments->block == NULL && !arguments->has_forwarding) { + arguments->block = (pm_node_t *) block; + } else { + pm_parser_err_node(parser, (pm_node_t *) block, PM_ERR_ARGUMENT_BLOCK_MULTI); + + if (arguments->block != NULL) { + if (arguments->arguments == NULL) { + arguments->arguments = pm_arguments_node_create(parser); + } + pm_arguments_node_arguments_append(arguments->arguments, arguments->block); + } + arguments->block = (pm_node_t *) block; + } + } + } + + return found; +} + +/** + * Check that the return is allowed in the current context. If it isn't, add an + * error to the parser. + */ +static void +parse_return(pm_parser_t *parser, pm_node_t *node) { + bool in_sclass = false; + for (pm_context_node_t *context_node = parser->current_context; context_node != NULL; context_node = context_node->prev) { + switch (context_node->context) { + case PM_CONTEXT_BEGIN_ELSE: + case PM_CONTEXT_BEGIN_ENSURE: + case PM_CONTEXT_BEGIN_RESCUE: + case PM_CONTEXT_BEGIN: + case PM_CONTEXT_CASE_IN: + case PM_CONTEXT_CASE_WHEN: + case PM_CONTEXT_DEFAULT_PARAMS: + case PM_CONTEXT_DEFINED: + case PM_CONTEXT_ELSE: + case PM_CONTEXT_ELSIF: + case PM_CONTEXT_EMBEXPR: + case PM_CONTEXT_FOR_INDEX: + case PM_CONTEXT_FOR: + case PM_CONTEXT_IF: + case PM_CONTEXT_LOOP_PREDICATE: + case PM_CONTEXT_MAIN: + case PM_CONTEXT_MULTI_TARGET: + case PM_CONTEXT_PARENS: + case PM_CONTEXT_POSTEXE: + case PM_CONTEXT_PREDICATE: + case PM_CONTEXT_PREEXE: + case PM_CONTEXT_RESCUE_MODIFIER: + case PM_CONTEXT_TERNARY: + case PM_CONTEXT_UNLESS: + case PM_CONTEXT_UNTIL: + case PM_CONTEXT_WHILE: + // Keep iterating up the lists of contexts, because returns can + // see through these. + continue; + case PM_CONTEXT_SCLASS_ELSE: + case PM_CONTEXT_SCLASS_ENSURE: + case PM_CONTEXT_SCLASS_RESCUE: + case PM_CONTEXT_SCLASS: + in_sclass = true; + continue; + case PM_CONTEXT_CLASS_ELSE: + case PM_CONTEXT_CLASS_ENSURE: + case PM_CONTEXT_CLASS_RESCUE: + case PM_CONTEXT_CLASS: + case PM_CONTEXT_MODULE_ELSE: + case PM_CONTEXT_MODULE_ENSURE: + case PM_CONTEXT_MODULE_RESCUE: + case PM_CONTEXT_MODULE: + // These contexts are invalid for a return. + pm_parser_err_node(parser, node, PM_ERR_RETURN_INVALID); + return; + case PM_CONTEXT_BLOCK_BRACES: + case PM_CONTEXT_BLOCK_ELSE: + case PM_CONTEXT_BLOCK_ENSURE: + case PM_CONTEXT_BLOCK_KEYWORDS: + case PM_CONTEXT_BLOCK_RESCUE: + case PM_CONTEXT_DEF_ELSE: + case PM_CONTEXT_DEF_ENSURE: + case PM_CONTEXT_DEF_PARAMS: + case PM_CONTEXT_DEF_RESCUE: + case PM_CONTEXT_DEF: + case PM_CONTEXT_LAMBDA_BRACES: + case PM_CONTEXT_LAMBDA_DO_END: + case PM_CONTEXT_LAMBDA_ELSE: + case PM_CONTEXT_LAMBDA_ENSURE: + case PM_CONTEXT_LAMBDA_RESCUE: + // These contexts are valid for a return, and we should not + // continue to loop. + return; + case PM_CONTEXT_NONE: + // This case should never happen. + assert(false && "unreachable"); + break; + } + } + if (in_sclass) { + pm_parser_err_node(parser, node, PM_ERR_RETURN_INVALID); + } +} + +/** + * Check that the block exit (next, break, redo) is allowed in the current + * context. If it isn't, add an error to the parser. + */ +static void +parse_block_exit(pm_parser_t *parser, pm_node_t *node) { + for (pm_context_node_t *context_node = parser->current_context; context_node != NULL; context_node = context_node->prev) { + switch (context_node->context) { + case PM_CONTEXT_BLOCK_BRACES: + case PM_CONTEXT_BLOCK_KEYWORDS: + case PM_CONTEXT_BLOCK_ELSE: + case PM_CONTEXT_BLOCK_ENSURE: + case PM_CONTEXT_BLOCK_RESCUE: + case PM_CONTEXT_DEFINED: + case PM_CONTEXT_FOR: + case PM_CONTEXT_LAMBDA_BRACES: + case PM_CONTEXT_LAMBDA_DO_END: + case PM_CONTEXT_LAMBDA_ELSE: + case PM_CONTEXT_LAMBDA_ENSURE: + case PM_CONTEXT_LAMBDA_RESCUE: + case PM_CONTEXT_LOOP_PREDICATE: + case PM_CONTEXT_POSTEXE: + case PM_CONTEXT_UNTIL: + case PM_CONTEXT_WHILE: + // These are the good cases. We're allowed to have a block exit + // in these contexts. + return; + case PM_CONTEXT_DEF: + case PM_CONTEXT_DEF_PARAMS: + case PM_CONTEXT_DEF_ELSE: + case PM_CONTEXT_DEF_ENSURE: + case PM_CONTEXT_DEF_RESCUE: + case PM_CONTEXT_MAIN: + case PM_CONTEXT_PREEXE: + case PM_CONTEXT_SCLASS: + case PM_CONTEXT_SCLASS_ELSE: + case PM_CONTEXT_SCLASS_ENSURE: + case PM_CONTEXT_SCLASS_RESCUE: + // These are the bad cases. We're not allowed to have a block + // exit in these contexts. + // + // If we get here, then we're about to mark this block exit + // as invalid. However, it could later _become_ valid if we + // find a trailing while/until on the expression. In this + // case instead of adding the error here, we'll add the + // block exit to the list of exits for the expression, and + // the node parsing will handle validating it instead. + assert(parser->current_block_exits != NULL); + pm_node_list_append(parser->current_block_exits, node); + return; + case PM_CONTEXT_BEGIN_ELSE: + case PM_CONTEXT_BEGIN_ENSURE: + case PM_CONTEXT_BEGIN_RESCUE: + case PM_CONTEXT_BEGIN: + case PM_CONTEXT_CASE_IN: + case PM_CONTEXT_CASE_WHEN: + case PM_CONTEXT_CLASS_ELSE: + case PM_CONTEXT_CLASS_ENSURE: + case PM_CONTEXT_CLASS_RESCUE: + case PM_CONTEXT_CLASS: + case PM_CONTEXT_DEFAULT_PARAMS: + case PM_CONTEXT_ELSE: + case PM_CONTEXT_ELSIF: + case PM_CONTEXT_EMBEXPR: + case PM_CONTEXT_FOR_INDEX: + case PM_CONTEXT_IF: + case PM_CONTEXT_MODULE_ELSE: + case PM_CONTEXT_MODULE_ENSURE: + case PM_CONTEXT_MODULE_RESCUE: + case PM_CONTEXT_MODULE: + case PM_CONTEXT_MULTI_TARGET: + case PM_CONTEXT_PARENS: + case PM_CONTEXT_PREDICATE: + case PM_CONTEXT_RESCUE_MODIFIER: + case PM_CONTEXT_TERNARY: + case PM_CONTEXT_UNLESS: + // In these contexts we should continue walking up the list of + // contexts. + break; + case PM_CONTEXT_NONE: + // This case should never happen. + assert(false && "unreachable"); + break; + } + } +} + +/** + * When we hit an expression that could contain block exits, we need to stash + * the previous set and create a new one. + */ +static pm_node_list_t * +push_block_exits(pm_parser_t *parser, pm_node_list_t *current_block_exits) { + pm_node_list_t *previous_block_exits = parser->current_block_exits; + parser->current_block_exits = current_block_exits; + return previous_block_exits; +} + +/** + * If we did not match a trailing while/until and this was the last chance to do + * so, then all of the block exits in the list are invalid and we need to add an + * error for each of them. + */ +static void +flush_block_exits(pm_parser_t *parser, pm_node_list_t *previous_block_exits) { + pm_node_t *block_exit; + PM_NODE_LIST_FOREACH(parser->current_block_exits, index, block_exit) { + const char *type; + + switch (PM_NODE_TYPE(block_exit)) { + case PM_BREAK_NODE: type = "break"; break; + case PM_NEXT_NODE: type = "next"; break; + case PM_REDO_NODE: type = "redo"; break; + default: assert(false && "unreachable"); type = ""; break; + } + + PM_PARSER_ERR_NODE_FORMAT(parser, block_exit, PM_ERR_INVALID_BLOCK_EXIT, type); + } + + parser->current_block_exits = previous_block_exits; +} + +/** + * Pop the current level of block exits from the parser, and add errors to the + * parser if any of them are deemed to be invalid. + */ +static void +pop_block_exits(pm_parser_t *parser, pm_node_list_t *previous_block_exits) { + if (match2(parser, PM_TOKEN_KEYWORD_WHILE_MODIFIER, PM_TOKEN_KEYWORD_UNTIL_MODIFIER)) { + // If we matched a trailing while/until, then all of the block exits in + // the contained list are valid. In this case we do not need to do + // anything. + parser->current_block_exits = previous_block_exits; + } else if (previous_block_exits != NULL) { + // If we did not matching a trailing while/until, then all of the block + // exits contained in the list are invalid for this specific context. + // However, they could still become valid in a higher level context if + // there is another list above this one. In this case we'll push all of + // the block exits up to the previous list. + pm_node_list_concat(previous_block_exits, parser->current_block_exits); + parser->current_block_exits = previous_block_exits; + } else { + // If we did not match a trailing while/until and this was the last + // chance to do so, then all of the block exits in the list are invalid + // and we need to add an error for each of them. + flush_block_exits(parser, previous_block_exits); + } +} + +static inline pm_node_t * +parse_predicate(pm_parser_t *parser, pm_binding_power_t binding_power, pm_context_t context, pm_token_t *then_keyword, uint16_t depth) { + context_push(parser, PM_CONTEXT_PREDICATE); + pm_diagnostic_id_t error_id = context == PM_CONTEXT_IF ? PM_ERR_CONDITIONAL_IF_PREDICATE : PM_ERR_CONDITIONAL_UNLESS_PREDICATE; + pm_node_t *predicate = parse_value_expression(parser, binding_power, true, false, error_id, (uint16_t) (depth + 1)); + + // Predicates are closed by a term, a "then", or a term and then a "then". + bool predicate_closed = accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON); + + if (accept1(parser, PM_TOKEN_KEYWORD_THEN)) { + predicate_closed = true; + *then_keyword = parser->previous; + } + + if (!predicate_closed) { + pm_parser_err_current(parser, PM_ERR_CONDITIONAL_PREDICATE_TERM); + } + + context_pop(parser); + return predicate; +} + +static inline pm_node_t * +parse_conditional(pm_parser_t *parser, pm_context_t context, size_t opening_newline_index, bool if_after_else, uint16_t depth) { + pm_node_list_t current_block_exits = { 0 }; + pm_node_list_t *previous_block_exits = push_block_exits(parser, ¤t_block_exits); + + pm_token_t keyword = parser->previous; + pm_token_t then_keyword = not_provided(parser); + + pm_node_t *predicate = parse_predicate(parser, PM_BINDING_POWER_MODIFIER, context, &then_keyword, (uint16_t) (depth + 1)); + pm_statements_node_t *statements = NULL; + + if (!match3(parser, PM_TOKEN_KEYWORD_ELSIF, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_END)) { + pm_accepts_block_stack_push(parser, true); + statements = parse_statements(parser, context, (uint16_t) (depth + 1)); + pm_accepts_block_stack_pop(parser); + accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON); + } + + pm_token_t end_keyword = not_provided(parser); + pm_node_t *parent = NULL; + + switch (context) { + case PM_CONTEXT_IF: + parent = (pm_node_t *) pm_if_node_create(parser, &keyword, predicate, &then_keyword, statements, NULL, &end_keyword); + break; + case PM_CONTEXT_UNLESS: + parent = (pm_node_t *) pm_unless_node_create(parser, &keyword, predicate, &then_keyword, statements); + break; + default: + assert(false && "unreachable"); + break; + } + + pm_node_t *current = parent; + + // Parse any number of elsif clauses. This will form a linked list of if + // nodes pointing to each other from the top. + if (context == PM_CONTEXT_IF) { + while (match1(parser, PM_TOKEN_KEYWORD_ELSIF)) { + if (parser_end_of_line_p(parser)) { + PM_PARSER_WARN_TOKEN_FORMAT_CONTENT(parser, parser->current, PM_WARN_KEYWORD_EOL); + } + + parser_warn_indentation_mismatch(parser, opening_newline_index, &keyword, false, false); + pm_token_t elsif_keyword = parser->current; + parser_lex(parser); + + pm_node_t *predicate = parse_predicate(parser, PM_BINDING_POWER_MODIFIER, PM_CONTEXT_ELSIF, &then_keyword, (uint16_t) (depth + 1)); + pm_accepts_block_stack_push(parser, true); + + pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_ELSIF, (uint16_t) (depth + 1)); + pm_accepts_block_stack_pop(parser); + accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON); + + pm_node_t *elsif = (pm_node_t *) pm_if_node_create(parser, &elsif_keyword, predicate, &then_keyword, statements, NULL, &end_keyword); + ((pm_if_node_t *) current)->subsequent = elsif; + current = elsif; + } + } + + if (match1(parser, PM_TOKEN_KEYWORD_ELSE)) { + parser_warn_indentation_mismatch(parser, opening_newline_index, &keyword, false, false); + opening_newline_index = token_newline_index(parser); + + parser_lex(parser); + pm_token_t else_keyword = parser->previous; + + pm_accepts_block_stack_push(parser, true); + pm_statements_node_t *else_statements = parse_statements(parser, PM_CONTEXT_ELSE, (uint16_t) (depth + 1)); + pm_accepts_block_stack_pop(parser); + + accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON); + parser_warn_indentation_mismatch(parser, opening_newline_index, &else_keyword, false, false); + expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CONDITIONAL_TERM_ELSE); + + pm_else_node_t *else_node = pm_else_node_create(parser, &else_keyword, else_statements, &parser->previous); + + switch (context) { + case PM_CONTEXT_IF: + ((pm_if_node_t *) current)->subsequent = (pm_node_t *) else_node; + break; + case PM_CONTEXT_UNLESS: + ((pm_unless_node_t *) parent)->else_clause = else_node; + break; + default: + assert(false && "unreachable"); + break; + } + } else { + parser_warn_indentation_mismatch(parser, opening_newline_index, &keyword, if_after_else, false); + expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CONDITIONAL_TERM); + } + + // Set the appropriate end location for all of the nodes in the subtree. + switch (context) { + case PM_CONTEXT_IF: { + pm_node_t *current = parent; + bool recursing = true; + + while (recursing) { + switch (PM_NODE_TYPE(current)) { + case PM_IF_NODE: + pm_if_node_end_keyword_loc_set((pm_if_node_t *) current, &parser->previous); + current = ((pm_if_node_t *) current)->subsequent; + recursing = current != NULL; + break; + case PM_ELSE_NODE: + pm_else_node_end_keyword_loc_set((pm_else_node_t *) current, &parser->previous); + recursing = false; + break; + default: { + recursing = false; + break; + } + } + } + break; + } + case PM_CONTEXT_UNLESS: + pm_unless_node_end_keyword_loc_set((pm_unless_node_t *) parent, &parser->previous); + break; + default: + assert(false && "unreachable"); + break; + } + + pop_block_exits(parser, previous_block_exits); + pm_node_list_free(¤t_block_exits); + + return parent; +} + +/** + * This macro allows you to define a case statement for all of the keywords. + * It's meant to be used in a switch statement. + */ +#define PM_CASE_KEYWORD PM_TOKEN_KEYWORD___ENCODING__: case PM_TOKEN_KEYWORD___FILE__: case PM_TOKEN_KEYWORD___LINE__: \ + case PM_TOKEN_KEYWORD_ALIAS: case PM_TOKEN_KEYWORD_AND: case PM_TOKEN_KEYWORD_BEGIN: case PM_TOKEN_KEYWORD_BEGIN_UPCASE: \ + case PM_TOKEN_KEYWORD_BREAK: case PM_TOKEN_KEYWORD_CASE: case PM_TOKEN_KEYWORD_CLASS: case PM_TOKEN_KEYWORD_DEF: \ + case PM_TOKEN_KEYWORD_DEFINED: case PM_TOKEN_KEYWORD_DO: case PM_TOKEN_KEYWORD_DO_LOOP: case PM_TOKEN_KEYWORD_ELSE: \ + case PM_TOKEN_KEYWORD_ELSIF: case PM_TOKEN_KEYWORD_END: case PM_TOKEN_KEYWORD_END_UPCASE: case PM_TOKEN_KEYWORD_ENSURE: \ + case PM_TOKEN_KEYWORD_FALSE: case PM_TOKEN_KEYWORD_FOR: case PM_TOKEN_KEYWORD_IF: case PM_TOKEN_KEYWORD_IN: \ + case PM_TOKEN_KEYWORD_MODULE: case PM_TOKEN_KEYWORD_NEXT: case PM_TOKEN_KEYWORD_NIL: case PM_TOKEN_KEYWORD_NOT: \ + case PM_TOKEN_KEYWORD_OR: case PM_TOKEN_KEYWORD_REDO: case PM_TOKEN_KEYWORD_RESCUE: case PM_TOKEN_KEYWORD_RETRY: \ + case PM_TOKEN_KEYWORD_RETURN: case PM_TOKEN_KEYWORD_SELF: case PM_TOKEN_KEYWORD_SUPER: case PM_TOKEN_KEYWORD_THEN: \ + case PM_TOKEN_KEYWORD_TRUE: case PM_TOKEN_KEYWORD_UNDEF: case PM_TOKEN_KEYWORD_UNLESS: case PM_TOKEN_KEYWORD_UNTIL: \ + case PM_TOKEN_KEYWORD_WHEN: case PM_TOKEN_KEYWORD_WHILE: case PM_TOKEN_KEYWORD_YIELD + +/** + * This macro allows you to define a case statement for all of the operators. + * It's meant to be used in a switch statement. + */ +#define PM_CASE_OPERATOR PM_TOKEN_AMPERSAND: case PM_TOKEN_BACKTICK: case PM_TOKEN_BANG_EQUAL: \ + case PM_TOKEN_BANG_TILDE: case PM_TOKEN_BANG: case PM_TOKEN_BRACKET_LEFT_RIGHT_EQUAL: \ + case PM_TOKEN_BRACKET_LEFT_RIGHT: case PM_TOKEN_CARET: case PM_TOKEN_EQUAL_EQUAL_EQUAL: case PM_TOKEN_EQUAL_EQUAL: \ + case PM_TOKEN_EQUAL_TILDE: case PM_TOKEN_GREATER_EQUAL: case PM_TOKEN_GREATER_GREATER: case PM_TOKEN_GREATER: \ + case PM_TOKEN_LESS_EQUAL_GREATER: case PM_TOKEN_LESS_EQUAL: case PM_TOKEN_LESS_LESS: case PM_TOKEN_LESS: \ + case PM_TOKEN_MINUS: case PM_TOKEN_PERCENT: case PM_TOKEN_PIPE: case PM_TOKEN_PLUS: case PM_TOKEN_SLASH: \ + case PM_TOKEN_STAR_STAR: case PM_TOKEN_STAR: case PM_TOKEN_TILDE: case PM_TOKEN_UAMPERSAND: case PM_TOKEN_UMINUS: \ + case PM_TOKEN_UMINUS_NUM: case PM_TOKEN_UPLUS: case PM_TOKEN_USTAR: case PM_TOKEN_USTAR_STAR + +/** + * This macro allows you to define a case statement for all of the token types + * that represent the beginning of nodes that are "primitives" in a pattern + * matching expression. + */ +#define PM_CASE_PRIMITIVE PM_TOKEN_INTEGER: case PM_TOKEN_INTEGER_IMAGINARY: case PM_TOKEN_INTEGER_RATIONAL: \ + case PM_TOKEN_INTEGER_RATIONAL_IMAGINARY: case PM_TOKEN_FLOAT: case PM_TOKEN_FLOAT_IMAGINARY: \ + case PM_TOKEN_FLOAT_RATIONAL: case PM_TOKEN_FLOAT_RATIONAL_IMAGINARY: case PM_TOKEN_SYMBOL_BEGIN: \ + case PM_TOKEN_REGEXP_BEGIN: case PM_TOKEN_BACKTICK: case PM_TOKEN_PERCENT_LOWER_X: case PM_TOKEN_PERCENT_LOWER_I: \ + case PM_TOKEN_PERCENT_LOWER_W: case PM_TOKEN_PERCENT_UPPER_I: case PM_TOKEN_PERCENT_UPPER_W: \ + case PM_TOKEN_STRING_BEGIN: case PM_TOKEN_KEYWORD_NIL: case PM_TOKEN_KEYWORD_SELF: case PM_TOKEN_KEYWORD_TRUE: \ + case PM_TOKEN_KEYWORD_FALSE: case PM_TOKEN_KEYWORD___FILE__: case PM_TOKEN_KEYWORD___LINE__: \ + case PM_TOKEN_KEYWORD___ENCODING__: case PM_TOKEN_MINUS_GREATER: case PM_TOKEN_HEREDOC_START: \ + case PM_TOKEN_UMINUS_NUM: case PM_TOKEN_CHARACTER_LITERAL + +/** + * This macro allows you to define a case statement for all of the token types + * that could begin a parameter. + */ +#define PM_CASE_PARAMETER PM_TOKEN_UAMPERSAND: case PM_TOKEN_AMPERSAND: case PM_TOKEN_UDOT_DOT_DOT: \ + case PM_TOKEN_IDENTIFIER: case PM_TOKEN_LABEL: case PM_TOKEN_USTAR: case PM_TOKEN_STAR: case PM_TOKEN_STAR_STAR: \ + case PM_TOKEN_USTAR_STAR: case PM_TOKEN_CONSTANT: case PM_TOKEN_INSTANCE_VARIABLE: case PM_TOKEN_GLOBAL_VARIABLE: \ + case PM_TOKEN_CLASS_VARIABLE + +/** + * This macro allows you to define a case statement for all of the nodes that + * can be transformed into write targets. + */ +#define PM_CASE_WRITABLE PM_CLASS_VARIABLE_READ_NODE: case PM_CONSTANT_PATH_NODE: \ + case PM_CONSTANT_READ_NODE: case PM_GLOBAL_VARIABLE_READ_NODE: case PM_LOCAL_VARIABLE_READ_NODE: \ + case PM_INSTANCE_VARIABLE_READ_NODE: case PM_MULTI_TARGET_NODE: case PM_BACK_REFERENCE_READ_NODE: \ + case PM_NUMBERED_REFERENCE_READ_NODE: case PM_IT_LOCAL_VARIABLE_READ_NODE + +// Assert here that the flags are the same so that we can safely switch the type +// of the node without having to move the flags. +PM_STATIC_ASSERT(__LINE__, ((int) PM_STRING_FLAGS_FORCED_UTF8_ENCODING) == ((int) PM_ENCODING_FLAGS_FORCED_UTF8_ENCODING), "Expected the flags to match."); + +/** + * If the encoding was explicitly set through the lexing process, then we need + * to potentially mark the string's flags to indicate how to encode it. + */ +static inline pm_node_flags_t +parse_unescaped_encoding(const pm_parser_t *parser) { + if (parser->explicit_encoding != NULL) { + if (parser->explicit_encoding == PM_ENCODING_UTF_8_ENTRY) { + // If the there's an explicit encoding and it's using a UTF-8 escape + // sequence, then mark the string as UTF-8. + return PM_STRING_FLAGS_FORCED_UTF8_ENCODING; + } else if (parser->encoding == PM_ENCODING_US_ASCII_ENTRY) { + // If there's a non-UTF-8 escape sequence being used, then the + // string uses the source encoding, unless the source is marked as + // US-ASCII. In that case the string is forced as ASCII-8BIT in + // order to keep the string valid. + return PM_STRING_FLAGS_FORCED_BINARY_ENCODING; + } + } + return 0; +} + +/** + * Parse a node that is part of a string. If the subsequent tokens cannot be + * parsed as a string part, then NULL is returned. + */ +static pm_node_t * +parse_string_part(pm_parser_t *parser, uint16_t depth) { + switch (parser->current.type) { + // Here the lexer has returned to us plain string content. In this case + // we'll create a string node that has no opening or closing and return that + // as the part. These kinds of parts look like: + // + // "aaa #{bbb} #@ccc ddd" + // ^^^^ ^ ^^^^ + case PM_TOKEN_STRING_CONTENT: { + pm_token_t opening = not_provided(parser); + pm_token_t closing = not_provided(parser); + + pm_node_t *node = (pm_node_t *) pm_string_node_create_current_string(parser, &opening, &parser->current, &closing); + pm_node_flag_set(node, parse_unescaped_encoding(parser)); + + parser_lex(parser); + return node; + } + // Here the lexer has returned the beginning of an embedded expression. In + // that case we'll parse the inner statements and return that as the part. + // These kinds of parts look like: + // + // "aaa #{bbb} #@ccc ddd" + // ^^^^^^ + case PM_TOKEN_EMBEXPR_BEGIN: { + // Ruby disallows seeing encoding around interpolation in strings, + // even though it is known at parse time. + parser->explicit_encoding = NULL; + + pm_lex_state_t state = parser->lex_state; + int brace_nesting = parser->brace_nesting; + + parser->brace_nesting = 0; + lex_state_set(parser, PM_LEX_STATE_BEG); + parser_lex(parser); + + pm_token_t opening = parser->previous; + pm_statements_node_t *statements = NULL; + + if (!match1(parser, PM_TOKEN_EMBEXPR_END)) { + pm_accepts_block_stack_push(parser, true); + statements = parse_statements(parser, PM_CONTEXT_EMBEXPR, (uint16_t) (depth + 1)); + pm_accepts_block_stack_pop(parser); + } + + parser->brace_nesting = brace_nesting; + lex_state_set(parser, state); + + expect1(parser, PM_TOKEN_EMBEXPR_END, PM_ERR_EMBEXPR_END); + pm_token_t closing = parser->previous; + + // If this set of embedded statements only contains a single + // statement, then Ruby does not consider it as a possible statement + // that could emit a line event. + if (statements != NULL && statements->body.size == 1) { + pm_node_flag_unset(statements->body.nodes[0], PM_NODE_FLAG_NEWLINE); + } + + return (pm_node_t *) pm_embedded_statements_node_create(parser, &opening, statements, &closing); + } + + // Here the lexer has returned the beginning of an embedded variable. + // In that case we'll parse the variable and create an appropriate node + // for it and then return that node. These kinds of parts look like: + // + // "aaa #{bbb} #@ccc ddd" + // ^^^^^ + case PM_TOKEN_EMBVAR: { + // Ruby disallows seeing encoding around interpolation in strings, + // even though it is known at parse time. + parser->explicit_encoding = NULL; + + lex_state_set(parser, PM_LEX_STATE_BEG); + parser_lex(parser); + + pm_token_t operator = parser->previous; + pm_node_t *variable; + + switch (parser->current.type) { + // In this case a back reference is being interpolated. We'll + // create a global variable read node. + case PM_TOKEN_BACK_REFERENCE: + parser_lex(parser); + variable = (pm_node_t *) pm_back_reference_read_node_create(parser, &parser->previous); + break; + // In this case an nth reference is being interpolated. We'll + // create a global variable read node. + case PM_TOKEN_NUMBERED_REFERENCE: + parser_lex(parser); + variable = (pm_node_t *) pm_numbered_reference_read_node_create(parser, &parser->previous); + break; + // In this case a global variable is being interpolated. We'll + // create a global variable read node. + case PM_TOKEN_GLOBAL_VARIABLE: + parser_lex(parser); + variable = (pm_node_t *) pm_global_variable_read_node_create(parser, &parser->previous); + break; + // In this case an instance variable is being interpolated. + // We'll create an instance variable read node. + case PM_TOKEN_INSTANCE_VARIABLE: + parser_lex(parser); + variable = (pm_node_t *) pm_instance_variable_read_node_create(parser, &parser->previous); + break; + // In this case a class variable is being interpolated. We'll + // create a class variable read node. + case PM_TOKEN_CLASS_VARIABLE: + parser_lex(parser); + variable = (pm_node_t *) pm_class_variable_read_node_create(parser, &parser->previous); + break; + // We can hit here if we got an invalid token. In that case + // we'll not attempt to lex this token and instead just return a + // missing node. + default: + expect1(parser, PM_TOKEN_IDENTIFIER, PM_ERR_EMBVAR_INVALID); + variable = (pm_node_t *) pm_missing_node_create(parser, parser->current.start, parser->current.end); + break; + } + + return (pm_node_t *) pm_embedded_variable_node_create(parser, &operator, variable); + } + default: + parser_lex(parser); + pm_parser_err_previous(parser, PM_ERR_CANNOT_PARSE_STRING_PART); + return NULL; + } +} + +/** + * When creating a symbol, unary operators that cannot be binary operators + * automatically drop trailing `@` characters. This happens at the parser level, + * such that `~@` is parsed as `~` and `!@` is parsed as `!`. We do that here. + */ +static const uint8_t * +parse_operator_symbol_name(const pm_token_t *name) { + switch (name->type) { + case PM_TOKEN_TILDE: + case PM_TOKEN_BANG: + if (name->end[-1] == '@') return name->end - 1; + PRISM_FALLTHROUGH + default: + return name->end; + } +} + +static pm_node_t * +parse_operator_symbol(pm_parser_t *parser, const pm_token_t *opening, pm_lex_state_t next_state) { + pm_token_t closing = not_provided(parser); + pm_symbol_node_t *symbol = pm_symbol_node_create(parser, opening, &parser->current, &closing); + + const uint8_t *end = parse_operator_symbol_name(&parser->current); + + if (next_state != PM_LEX_STATE_NONE) lex_state_set(parser, next_state); + parser_lex(parser); + + pm_string_shared_init(&symbol->unescaped, parser->previous.start, end); + pm_node_flag_set((pm_node_t *) symbol, PM_SYMBOL_FLAGS_FORCED_US_ASCII_ENCODING); + + return (pm_node_t *) symbol; +} + +/** + * Parse a symbol node. This function will get called immediately after finding + * a symbol opening token. This handles parsing bare symbols and interpolated + * symbols. + */ +static pm_node_t * +parse_symbol(pm_parser_t *parser, pm_lex_mode_t *lex_mode, pm_lex_state_t next_state, uint16_t depth) { + const pm_token_t opening = parser->previous; + + if (lex_mode->mode != PM_LEX_STRING) { + if (next_state != PM_LEX_STATE_NONE) lex_state_set(parser, next_state); + + switch (parser->current.type) { + case PM_CASE_OPERATOR: + return parse_operator_symbol(parser, &opening, next_state == PM_LEX_STATE_NONE ? PM_LEX_STATE_ENDFN : next_state); + case PM_TOKEN_IDENTIFIER: + case PM_TOKEN_CONSTANT: + case PM_TOKEN_INSTANCE_VARIABLE: + case PM_TOKEN_METHOD_NAME: + case PM_TOKEN_CLASS_VARIABLE: + case PM_TOKEN_GLOBAL_VARIABLE: + case PM_TOKEN_NUMBERED_REFERENCE: + case PM_TOKEN_BACK_REFERENCE: + case PM_CASE_KEYWORD: + parser_lex(parser); + break; + default: + expect2(parser, PM_TOKEN_IDENTIFIER, PM_TOKEN_METHOD_NAME, PM_ERR_SYMBOL_INVALID); + break; + } + + pm_token_t closing = not_provided(parser); + pm_symbol_node_t *symbol = pm_symbol_node_create(parser, &opening, &parser->previous, &closing); + + pm_string_shared_init(&symbol->unescaped, parser->previous.start, parser->previous.end); + pm_node_flag_set((pm_node_t *) symbol, parse_symbol_encoding(parser, &parser->previous, &symbol->unescaped, false)); + + return (pm_node_t *) symbol; + } + + if (lex_mode->as.string.interpolation) { + // If we have the end of the symbol, then we can return an empty symbol. + if (match1(parser, PM_TOKEN_STRING_END)) { + if (next_state != PM_LEX_STATE_NONE) lex_state_set(parser, next_state); + parser_lex(parser); + + pm_token_t content = not_provided(parser); + pm_token_t closing = parser->previous; + return (pm_node_t *) pm_symbol_node_create(parser, &opening, &content, &closing); + } + + // Now we can parse the first part of the symbol. + pm_node_t *part = parse_string_part(parser, (uint16_t) (depth + 1)); + + // If we got a string part, then it's possible that we could transform + // what looks like an interpolated symbol into a regular symbol. + if (part && PM_NODE_TYPE_P(part, PM_STRING_NODE) && match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) { + if (next_state != PM_LEX_STATE_NONE) lex_state_set(parser, next_state); + expect1(parser, PM_TOKEN_STRING_END, PM_ERR_SYMBOL_TERM_INTERPOLATED); + + return (pm_node_t *) pm_string_node_to_symbol_node(parser, (pm_string_node_t *) part, &opening, &parser->previous); + } + + pm_interpolated_symbol_node_t *symbol = pm_interpolated_symbol_node_create(parser, &opening, NULL, &opening); + if (part) pm_interpolated_symbol_node_append(symbol, part); + + while (!match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) { + if ((part = parse_string_part(parser, (uint16_t) (depth + 1))) != NULL) { + pm_interpolated_symbol_node_append(symbol, part); + } + } + + if (next_state != PM_LEX_STATE_NONE) lex_state_set(parser, next_state); + if (match1(parser, PM_TOKEN_EOF)) { + pm_parser_err_token(parser, &opening, PM_ERR_SYMBOL_TERM_INTERPOLATED); + } else { + expect1(parser, PM_TOKEN_STRING_END, PM_ERR_SYMBOL_TERM_INTERPOLATED); + } + + pm_interpolated_symbol_node_closing_loc_set(symbol, &parser->previous); + return (pm_node_t *) symbol; + } + + pm_token_t content; + pm_string_t unescaped; + + if (match1(parser, PM_TOKEN_STRING_CONTENT)) { + content = parser->current; + unescaped = parser->current_string; + parser_lex(parser); + + // If we have two string contents in a row, then the content of this + // symbol is split because of heredoc contents. This looks like: + // + // <current, &bounds, &parser->current_string); + pm_interpolated_symbol_node_append(symbol, part); + + if (next_state != PM_LEX_STATE_NONE) { + lex_state_set(parser, next_state); + } + + parser_lex(parser); + expect1(parser, PM_TOKEN_STRING_END, PM_ERR_SYMBOL_TERM_DYNAMIC); + + pm_interpolated_symbol_node_closing_loc_set(symbol, &parser->previous); + return (pm_node_t *) symbol; + } + } else { + content = (pm_token_t) { .type = PM_TOKEN_STRING_CONTENT, .start = parser->previous.end, .end = parser->previous.end }; + pm_string_shared_init(&unescaped, content.start, content.end); + } + + if (next_state != PM_LEX_STATE_NONE) { + lex_state_set(parser, next_state); + } + + if (match1(parser, PM_TOKEN_EOF)) { + pm_parser_err_token(parser, &opening, PM_ERR_SYMBOL_TERM_DYNAMIC); + } else { + expect1(parser, PM_TOKEN_STRING_END, PM_ERR_SYMBOL_TERM_DYNAMIC); + } + + return (pm_node_t *) pm_symbol_node_create_unescaped(parser, &opening, &content, &parser->previous, &unescaped, parse_symbol_encoding(parser, &content, &unescaped, false)); +} + +/** + * Parse an argument to undef which can either be a bare word, a symbol, a + * constant, or an interpolated symbol. + */ +static inline pm_node_t * +parse_undef_argument(pm_parser_t *parser, uint16_t depth) { + switch (parser->current.type) { + case PM_CASE_OPERATOR: { + const pm_token_t opening = not_provided(parser); + return parse_operator_symbol(parser, &opening, PM_LEX_STATE_NONE); + } + case PM_CASE_KEYWORD: + case PM_TOKEN_CONSTANT: + case PM_TOKEN_IDENTIFIER: + case PM_TOKEN_METHOD_NAME: { + parser_lex(parser); + + pm_token_t opening = not_provided(parser); + pm_token_t closing = not_provided(parser); + pm_symbol_node_t *symbol = pm_symbol_node_create(parser, &opening, &parser->previous, &closing); + + pm_string_shared_init(&symbol->unescaped, parser->previous.start, parser->previous.end); + pm_node_flag_set((pm_node_t *) symbol, parse_symbol_encoding(parser, &parser->previous, &symbol->unescaped, false)); + + return (pm_node_t *) symbol; + } + case PM_TOKEN_SYMBOL_BEGIN: { + pm_lex_mode_t lex_mode = *parser->lex_modes.current; + parser_lex(parser); + + return parse_symbol(parser, &lex_mode, PM_LEX_STATE_NONE, (uint16_t) (depth + 1)); + } + default: + pm_parser_err_current(parser, PM_ERR_UNDEF_ARGUMENT); + return (pm_node_t *) pm_missing_node_create(parser, parser->current.start, parser->current.end); + } +} + +/** + * Parse an argument to alias which can either be a bare word, a symbol, an + * interpolated symbol or a global variable. If this is the first argument, then + * we need to set the lex state to PM_LEX_STATE_FNAME | PM_LEX_STATE_FITEM + * between the first and second arguments. + */ +static inline pm_node_t * +parse_alias_argument(pm_parser_t *parser, bool first, uint16_t depth) { + switch (parser->current.type) { + case PM_CASE_OPERATOR: { + const pm_token_t opening = not_provided(parser); + return parse_operator_symbol(parser, &opening, first ? PM_LEX_STATE_FNAME | PM_LEX_STATE_FITEM : PM_LEX_STATE_NONE); + } + case PM_CASE_KEYWORD: + case PM_TOKEN_CONSTANT: + case PM_TOKEN_IDENTIFIER: + case PM_TOKEN_METHOD_NAME: { + if (first) lex_state_set(parser, PM_LEX_STATE_FNAME | PM_LEX_STATE_FITEM); + parser_lex(parser); + + pm_token_t opening = not_provided(parser); + pm_token_t closing = not_provided(parser); + pm_symbol_node_t *symbol = pm_symbol_node_create(parser, &opening, &parser->previous, &closing); + + pm_string_shared_init(&symbol->unescaped, parser->previous.start, parser->previous.end); + pm_node_flag_set((pm_node_t *) symbol, parse_symbol_encoding(parser, &parser->previous, &symbol->unescaped, false)); + + return (pm_node_t *) symbol; + } + case PM_TOKEN_SYMBOL_BEGIN: { + pm_lex_mode_t lex_mode = *parser->lex_modes.current; + parser_lex(parser); + + return parse_symbol(parser, &lex_mode, first ? PM_LEX_STATE_FNAME | PM_LEX_STATE_FITEM : PM_LEX_STATE_NONE, (uint16_t) (depth + 1)); + } + case PM_TOKEN_BACK_REFERENCE: + parser_lex(parser); + return (pm_node_t *) pm_back_reference_read_node_create(parser, &parser->previous); + case PM_TOKEN_NUMBERED_REFERENCE: + parser_lex(parser); + return (pm_node_t *) pm_numbered_reference_read_node_create(parser, &parser->previous); + case PM_TOKEN_GLOBAL_VARIABLE: + parser_lex(parser); + return (pm_node_t *) pm_global_variable_read_node_create(parser, &parser->previous); + default: + pm_parser_err_current(parser, PM_ERR_ALIAS_ARGUMENT); + return (pm_node_t *) pm_missing_node_create(parser, parser->current.start, parser->current.end); + } +} + +/** + * Parse an identifier into either a local variable read. If the local variable + * is not found, it returns NULL instead. + */ +static pm_node_t * +parse_variable(pm_parser_t *parser) { + pm_constant_id_t name_id = pm_parser_constant_id_token(parser, &parser->previous); + int depth; + bool is_numbered_param = pm_token_is_numbered_parameter(parser->previous.start, parser->previous.end); + + if (!is_numbered_param && ((depth = pm_parser_local_depth_constant_id(parser, name_id)) != -1)) { + return (pm_node_t *) pm_local_variable_read_node_create_constant_id(parser, &parser->previous, name_id, (uint32_t) depth, false); + } + + pm_scope_t *current_scope = parser->current_scope; + if (!current_scope->closed && !(current_scope->parameters & PM_SCOPE_PARAMETERS_IMPLICIT_DISALLOWED)) { + if (is_numbered_param) { + // When you use a numbered parameter, it implies the existence of + // all of the locals that exist before it. For example, referencing + // _2 means that _1 must exist. Therefore here we loop through all + // of the possibilities and add them into the constant pool. + uint8_t maximum = (uint8_t) (parser->previous.start[1] - '0'); + for (uint8_t number = 1; number <= maximum; number++) { + pm_parser_local_add_constant(parser, pm_numbered_parameter_names[number - 1], 2); + } + + if (!match1(parser, PM_TOKEN_EQUAL)) { + parser->current_scope->parameters |= PM_SCOPE_PARAMETERS_NUMBERED_FOUND; + } + + pm_node_t *node = (pm_node_t *) pm_local_variable_read_node_create_constant_id(parser, &parser->previous, name_id, 0, false); + pm_node_list_append(¤t_scope->implicit_parameters, node); + + return node; + } else if ((parser->version != PM_OPTIONS_VERSION_CRUBY_3_3) && pm_token_is_it(parser->previous.start, parser->previous.end)) { + pm_node_t *node = (pm_node_t *) pm_it_local_variable_read_node_create(parser, &parser->previous); + pm_node_list_append(¤t_scope->implicit_parameters, node); + + return node; + } + } + + return NULL; +} + +/** + * Parse an identifier into either a local variable read or a call. + */ +static pm_node_t * +parse_variable_call(pm_parser_t *parser) { + pm_node_flags_t flags = 0; + + if (!match1(parser, PM_TOKEN_PARENTHESIS_LEFT) && (parser->previous.end[-1] != '!') && (parser->previous.end[-1] != '?')) { + pm_node_t *node = parse_variable(parser); + if (node != NULL) return node; + flags |= PM_CALL_NODE_FLAGS_VARIABLE_CALL; + } + + pm_call_node_t *node = pm_call_node_variable_call_create(parser, &parser->previous); + pm_node_flag_set((pm_node_t *)node, flags); + + return (pm_node_t *) node; +} + +/** + * Parse the method definition name based on the current token available on the + * parser. If it does not match a valid method definition name, then a missing + * token is returned. + */ +static inline pm_token_t +parse_method_definition_name(pm_parser_t *parser) { + switch (parser->current.type) { + case PM_CASE_KEYWORD: + case PM_TOKEN_CONSTANT: + case PM_TOKEN_METHOD_NAME: + parser_lex(parser); + return parser->previous; + case PM_TOKEN_IDENTIFIER: + pm_refute_numbered_parameter(parser, parser->current.start, parser->current.end); + parser_lex(parser); + return parser->previous; + case PM_CASE_OPERATOR: + lex_state_set(parser, PM_LEX_STATE_ENDFN); + parser_lex(parser); + return parser->previous; + default: + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_DEF_NAME, pm_token_type_human(parser->current.type)); + return (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->current.start, .end = parser->current.end }; + } +} + +static void +parse_heredoc_dedent_string(pm_string_t *string, size_t common_whitespace) { + // Get a reference to the string struct that is being held by the string + // node. This is the value we're going to actually manipulate. + pm_string_ensure_owned(string); + + // Now get the bounds of the existing string. We'll use this as a + // destination to move bytes into. We'll also use it for bounds checking + // since we don't require that these strings be null terminated. + size_t dest_length = pm_string_length(string); + const uint8_t *source_cursor = (uint8_t *) string->source; + const uint8_t *source_end = source_cursor + dest_length; + + // We're going to move bytes backward in the string when we get leading + // whitespace, so we'll maintain a pointer to the current position in the + // string that we're writing to. + size_t trimmed_whitespace = 0; + + // While we haven't reached the amount of common whitespace that we need to + // trim and we haven't reached the end of the string, we'll keep trimming + // whitespace. Trimming in this context means skipping over these bytes such + // that they aren't copied into the new string. + while ((source_cursor < source_end) && pm_char_is_inline_whitespace(*source_cursor) && trimmed_whitespace < common_whitespace) { + if (*source_cursor == '\t') { + trimmed_whitespace = (trimmed_whitespace / PM_TAB_WHITESPACE_SIZE + 1) * PM_TAB_WHITESPACE_SIZE; + if (trimmed_whitespace > common_whitespace) break; + } else { + trimmed_whitespace++; + } + + source_cursor++; + dest_length--; + } + + memmove((uint8_t *) string->source, source_cursor, (size_t) (source_end - source_cursor)); + string->length = dest_length; +} + +/** + * Take a heredoc node that is indented by a ~ and trim the leading whitespace. + */ +static void +parse_heredoc_dedent(pm_parser_t *parser, pm_node_list_t *nodes, size_t common_whitespace) { + // The next node should be dedented if it's the first node in the list or if + // it follows a string node. + bool dedent_next = true; + + // Iterate over all nodes, and trim whitespace accordingly. We're going to + // keep around two indices: a read and a write. If we end up trimming all of + // the whitespace from a node, then we'll drop it from the list entirely. + size_t write_index = 0; + + pm_node_t *node; + PM_NODE_LIST_FOREACH(nodes, read_index, node) { + // We're not manipulating child nodes that aren't strings. In this case + // we'll skip past it and indicate that the subsequent node should not + // be dedented. + if (!PM_NODE_TYPE_P(node, PM_STRING_NODE)) { + nodes->nodes[write_index++] = node; + dedent_next = false; + continue; + } + + pm_string_node_t *string_node = ((pm_string_node_t *) node); + if (dedent_next) { + parse_heredoc_dedent_string(&string_node->unescaped, common_whitespace); + } + + if (string_node->unescaped.length == 0) { + pm_node_destroy(parser, node); + } else { + nodes->nodes[write_index++] = node; + } + + // We always dedent the next node if it follows a string node. + dedent_next = true; + } + + nodes->size = write_index; +} + +/** + * Return a string content token at a particular location that is empty. + */ +static pm_token_t +parse_strings_empty_content(const uint8_t *location) { + return (pm_token_t) { .type = PM_TOKEN_STRING_CONTENT, .start = location, .end = location }; +} + +/** + * Parse a set of strings that could be concatenated together. + */ +static inline pm_node_t * +parse_strings(pm_parser_t *parser, pm_node_t *current, bool accepts_label, uint16_t depth) { + assert(parser->current.type == PM_TOKEN_STRING_BEGIN); + bool concating = false; + + while (match1(parser, PM_TOKEN_STRING_BEGIN)) { + pm_node_t *node = NULL; + + // Here we have found a string literal. We'll parse it and add it to + // the list of strings. + const pm_lex_mode_t *lex_mode = parser->lex_modes.current; + assert(lex_mode->mode == PM_LEX_STRING); + bool lex_interpolation = lex_mode->as.string.interpolation; + bool label_allowed = lex_mode->as.string.label_allowed && accepts_label; + + pm_token_t opening = parser->current; + parser_lex(parser); + + if (match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) { + expect1(parser, PM_TOKEN_STRING_END, PM_ERR_STRING_LITERAL_EOF); + // If we get here, then we have an end immediately after a + // start. In that case we'll create an empty content token and + // return an uninterpolated string. + pm_token_t content = parse_strings_empty_content(parser->previous.start); + pm_string_node_t *string = pm_string_node_create(parser, &opening, &content, &parser->previous); + + pm_string_shared_init(&string->unescaped, content.start, content.end); + node = (pm_node_t *) string; + } else if (accept1(parser, PM_TOKEN_LABEL_END)) { + // If we get here, then we have an end of a label immediately + // after a start. In that case we'll create an empty symbol + // node. + pm_token_t content = parse_strings_empty_content(parser->previous.start); + pm_symbol_node_t *symbol = pm_symbol_node_create(parser, &opening, &content, &parser->previous); + + pm_string_shared_init(&symbol->unescaped, content.start, content.end); + node = (pm_node_t *) symbol; + + if (!label_allowed) pm_parser_err_node(parser, node, PM_ERR_UNEXPECTED_LABEL); + } else if (!lex_interpolation) { + // If we don't accept interpolation then we expect the string to + // start with a single string content node. + pm_string_t unescaped; + pm_token_t content; + + if (match1(parser, PM_TOKEN_EOF)) { + unescaped = PM_STRING_EMPTY; + content = not_provided(parser); + } else { + unescaped = parser->current_string; + expect1(parser, PM_TOKEN_STRING_CONTENT, PM_ERR_EXPECT_STRING_CONTENT); + content = parser->previous; + } + + // It is unfortunately possible to have multiple string content + // nodes in a row in the case that there's heredoc content in + // the middle of the string, like this cursed example: + // + // <<-END+'b + // a + // END + // c'+'d' + // + // In that case we need to switch to an interpolated string to + // be able to contain all of the parts. + if (match1(parser, PM_TOKEN_STRING_CONTENT)) { + pm_node_list_t parts = { 0 }; + + pm_token_t delimiters = not_provided(parser); + pm_node_t *part = (pm_node_t *) pm_string_node_create_unescaped(parser, &delimiters, &content, &delimiters, &unescaped); + pm_node_list_append(&parts, part); + + do { + part = (pm_node_t *) pm_string_node_create_current_string(parser, &delimiters, &parser->current, &delimiters); + pm_node_list_append(&parts, part); + parser_lex(parser); + } while (match1(parser, PM_TOKEN_STRING_CONTENT)); + + expect1(parser, PM_TOKEN_STRING_END, PM_ERR_STRING_LITERAL_EOF); + node = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, &parts, &parser->previous); + + pm_node_list_free(&parts); + } else if (accept1(parser, PM_TOKEN_LABEL_END)) { + node = (pm_node_t *) pm_symbol_node_create_unescaped(parser, &opening, &content, &parser->previous, &unescaped, parse_symbol_encoding(parser, &content, &unescaped, true)); + if (!label_allowed) pm_parser_err_node(parser, node, PM_ERR_UNEXPECTED_LABEL); + } else if (match1(parser, PM_TOKEN_EOF)) { + pm_parser_err_token(parser, &opening, PM_ERR_STRING_LITERAL_EOF); + node = (pm_node_t *) pm_string_node_create_unescaped(parser, &opening, &content, &parser->current, &unescaped); + } else if (accept1(parser, PM_TOKEN_STRING_END)) { + node = (pm_node_t *) pm_string_node_create_unescaped(parser, &opening, &content, &parser->previous, &unescaped); + } else { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->previous, PM_ERR_STRING_LITERAL_TERM, pm_token_type_human(parser->previous.type)); + parser->previous.start = parser->previous.end; + parser->previous.type = PM_TOKEN_MISSING; + node = (pm_node_t *) pm_string_node_create_unescaped(parser, &opening, &content, &parser->previous, &unescaped); + } + } else if (match1(parser, PM_TOKEN_STRING_CONTENT)) { + // In this case we've hit string content so we know the string + // at least has something in it. We'll need to check if the + // following token is the end (in which case we can return a + // plain string) or if it's not then it has interpolation. + pm_token_t content = parser->current; + pm_string_t unescaped = parser->current_string; + parser_lex(parser); + + if (match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) { + node = (pm_node_t *) pm_string_node_create_unescaped(parser, &opening, &content, &parser->current, &unescaped); + pm_node_flag_set(node, parse_unescaped_encoding(parser)); + + // Kind of odd behavior, but basically if we have an + // unterminated string and it ends in a newline, we back up one + // character so that the error message is on the last line of + // content in the string. + if (!accept1(parser, PM_TOKEN_STRING_END)) { + const uint8_t *location = parser->previous.end; + if (location > parser->start && location[-1] == '\n') location--; + pm_parser_err(parser, location, location, PM_ERR_STRING_LITERAL_EOF); + + parser->previous.start = parser->previous.end; + parser->previous.type = PM_TOKEN_MISSING; + } + } else if (accept1(parser, PM_TOKEN_LABEL_END)) { + node = (pm_node_t *) pm_symbol_node_create_unescaped(parser, &opening, &content, &parser->previous, &unescaped, parse_symbol_encoding(parser, &content, &unescaped, true)); + if (!label_allowed) pm_parser_err_node(parser, node, PM_ERR_UNEXPECTED_LABEL); + } else { + // If we get here, then we have interpolation so we'll need + // to create a string or symbol node with interpolation. + pm_node_list_t parts = { 0 }; + pm_token_t string_opening = not_provided(parser); + pm_token_t string_closing = not_provided(parser); + + pm_node_t *part = (pm_node_t *) pm_string_node_create_unescaped(parser, &string_opening, &parser->previous, &string_closing, &unescaped); + pm_node_flag_set(part, parse_unescaped_encoding(parser)); + pm_node_list_append(&parts, part); + + while (!match3(parser, PM_TOKEN_STRING_END, PM_TOKEN_LABEL_END, PM_TOKEN_EOF)) { + if ((part = parse_string_part(parser, (uint16_t) (depth + 1))) != NULL) { + pm_node_list_append(&parts, part); + } + } + + if (accept1(parser, PM_TOKEN_LABEL_END)) { + node = (pm_node_t *) pm_interpolated_symbol_node_create(parser, &opening, &parts, &parser->previous); + if (!label_allowed) pm_parser_err_node(parser, node, PM_ERR_UNEXPECTED_LABEL); + } else if (match1(parser, PM_TOKEN_EOF)) { + pm_parser_err_token(parser, &opening, PM_ERR_STRING_INTERPOLATED_TERM); + node = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, &parts, &parser->current); + } else { + expect1(parser, PM_TOKEN_STRING_END, PM_ERR_STRING_INTERPOLATED_TERM); + node = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, &parts, &parser->previous); + } + + pm_node_list_free(&parts); + } + } else { + // If we get here, then the first part of the string is not plain + // string content, in which case we need to parse the string as an + // interpolated string. + pm_node_list_t parts = { 0 }; + pm_node_t *part; + + while (!match3(parser, PM_TOKEN_STRING_END, PM_TOKEN_LABEL_END, PM_TOKEN_EOF)) { + if ((part = parse_string_part(parser, (uint16_t) (depth + 1))) != NULL) { + pm_node_list_append(&parts, part); + } + } + + if (accept1(parser, PM_TOKEN_LABEL_END)) { + node = (pm_node_t *) pm_interpolated_symbol_node_create(parser, &opening, &parts, &parser->previous); + if (!label_allowed) pm_parser_err_node(parser, node, PM_ERR_UNEXPECTED_LABEL); + } else if (match1(parser, PM_TOKEN_EOF)) { + pm_parser_err_token(parser, &opening, PM_ERR_STRING_INTERPOLATED_TERM); + node = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, &parts, &parser->current); + } else { + expect1(parser, PM_TOKEN_STRING_END, PM_ERR_STRING_INTERPOLATED_TERM); + node = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, &parts, &parser->previous); + } + + pm_node_list_free(&parts); + } + + if (current == NULL) { + // If the node we just parsed is a symbol node, then we can't + // concatenate it with anything else, so we can now return that + // node. + if (PM_NODE_TYPE_P(node, PM_SYMBOL_NODE) || PM_NODE_TYPE_P(node, PM_INTERPOLATED_SYMBOL_NODE)) { + return node; + } + + // If we don't already have a node, then it's fine and we can just + // set the result to be the node we just parsed. + current = node; + } else { + // Otherwise we need to check the type of the node we just parsed. + // If it cannot be concatenated with the previous node, then we'll + // need to add a syntax error. + if (!PM_NODE_TYPE_P(node, PM_STRING_NODE) && !PM_NODE_TYPE_P(node, PM_INTERPOLATED_STRING_NODE)) { + pm_parser_err_node(parser, node, PM_ERR_STRING_CONCATENATION); + } + + // If we haven't already created our container for concatenation, + // we'll do that now. + if (!concating) { + if (!PM_NODE_TYPE_P(current, PM_STRING_NODE) && !PM_NODE_TYPE_P(current, PM_INTERPOLATED_STRING_NODE)) { + pm_parser_err_node(parser, current, PM_ERR_STRING_CONCATENATION); + } + + concating = true; + pm_token_t bounds = not_provided(parser); + + pm_interpolated_string_node_t *container = pm_interpolated_string_node_create(parser, &bounds, NULL, &bounds); + pm_interpolated_string_node_append(container, current); + current = (pm_node_t *) container; + } + + pm_interpolated_string_node_append((pm_interpolated_string_node_t *) current, node); + } + } + + return current; +} + +#define PM_PARSE_PATTERN_SINGLE 0 +#define PM_PARSE_PATTERN_TOP 1 +#define PM_PARSE_PATTERN_MULTI 2 + +static pm_node_t * +parse_pattern(pm_parser_t *parser, pm_constant_id_list_t *captures, uint8_t flags, pm_diagnostic_id_t diag_id, uint16_t depth); + +/** + * Add the newly created local to the list of captures for this pattern matching + * expression. If it is duplicated from a previous local, then we'll need to add + * an error to the parser. + */ +static void +parse_pattern_capture(pm_parser_t *parser, pm_constant_id_list_t *captures, pm_constant_id_t capture, const pm_location_t *location) { + // Skip this capture if it starts with an underscore. + if (*location->start == '_') return; + + if (pm_constant_id_list_includes(captures, capture)) { + pm_parser_err(parser, location->start, location->end, PM_ERR_PATTERN_CAPTURE_DUPLICATE); + } else { + pm_constant_id_list_append(captures, capture); + } +} + +/** + * Accept any number of constants joined by :: delimiters. + */ +static pm_node_t * +parse_pattern_constant_path(pm_parser_t *parser, pm_constant_id_list_t *captures, pm_node_t *node, uint16_t depth) { + // Now, if there are any :: operators that follow, parse them as constant + // path nodes. + while (accept1(parser, PM_TOKEN_COLON_COLON)) { + pm_token_t delimiter = parser->previous; + expect1(parser, PM_TOKEN_CONSTANT, PM_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT); + node = (pm_node_t *) pm_constant_path_node_create(parser, node, &delimiter, &parser->previous); + } + + // If there is a [ or ( that follows, then this is part of a larger pattern + // expression. We'll parse the inner pattern here, then modify the returned + // inner pattern with our constant path attached. + if (!match2(parser, PM_TOKEN_BRACKET_LEFT, PM_TOKEN_PARENTHESIS_LEFT)) { + return node; + } + + pm_token_t opening; + pm_token_t closing; + pm_node_t *inner = NULL; + + if (accept1(parser, PM_TOKEN_BRACKET_LEFT)) { + opening = parser->previous; + accept1(parser, PM_TOKEN_NEWLINE); + + if (!accept1(parser, PM_TOKEN_BRACKET_RIGHT)) { + inner = parse_pattern(parser, captures, PM_PARSE_PATTERN_TOP | PM_PARSE_PATTERN_MULTI, PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET, (uint16_t) (depth + 1)); + accept1(parser, PM_TOKEN_NEWLINE); + expect1(parser, PM_TOKEN_BRACKET_RIGHT, PM_ERR_PATTERN_TERM_BRACKET); + } + + closing = parser->previous; + } else { + parser_lex(parser); + opening = parser->previous; + accept1(parser, PM_TOKEN_NEWLINE); + + if (!accept1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) { + inner = parse_pattern(parser, captures, PM_PARSE_PATTERN_TOP | PM_PARSE_PATTERN_MULTI, PM_ERR_PATTERN_EXPRESSION_AFTER_PAREN, (uint16_t) (depth + 1)); + accept1(parser, PM_TOKEN_NEWLINE); + expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_PATTERN_TERM_PAREN); + } + + closing = parser->previous; + } + + if (!inner) { + // If there was no inner pattern, then we have something like Foo() or + // Foo[]. In that case we'll create an array pattern with no requireds. + return (pm_node_t *) pm_array_pattern_node_constant_create(parser, node, &opening, &closing); + } + + // Now that we have the inner pattern, check to see if it's an array, find, + // or hash pattern. If it is, then we'll attach our constant path to it if + // it doesn't already have a constant. If it's not one of those node types + // or it does have a constant, then we'll create an array pattern. + switch (PM_NODE_TYPE(inner)) { + case PM_ARRAY_PATTERN_NODE: { + pm_array_pattern_node_t *pattern_node = (pm_array_pattern_node_t *) inner; + + if (pattern_node->constant == NULL && pattern_node->opening_loc.start == NULL) { + pattern_node->base.location.start = node->location.start; + pattern_node->base.location.end = closing.end; + + pattern_node->constant = node; + pattern_node->opening_loc = PM_LOCATION_TOKEN_VALUE(&opening); + pattern_node->closing_loc = PM_LOCATION_TOKEN_VALUE(&closing); + + return (pm_node_t *) pattern_node; + } + + break; + } + case PM_FIND_PATTERN_NODE: { + pm_find_pattern_node_t *pattern_node = (pm_find_pattern_node_t *) inner; + + if (pattern_node->constant == NULL && pattern_node->opening_loc.start == NULL) { + pattern_node->base.location.start = node->location.start; + pattern_node->base.location.end = closing.end; + + pattern_node->constant = node; + pattern_node->opening_loc = PM_LOCATION_TOKEN_VALUE(&opening); + pattern_node->closing_loc = PM_LOCATION_TOKEN_VALUE(&closing); + + return (pm_node_t *) pattern_node; + } + + break; + } + case PM_HASH_PATTERN_NODE: { + pm_hash_pattern_node_t *pattern_node = (pm_hash_pattern_node_t *) inner; + + if (pattern_node->constant == NULL && pattern_node->opening_loc.start == NULL) { + pattern_node->base.location.start = node->location.start; + pattern_node->base.location.end = closing.end; + + pattern_node->constant = node; + pattern_node->opening_loc = PM_LOCATION_TOKEN_VALUE(&opening); + pattern_node->closing_loc = PM_LOCATION_TOKEN_VALUE(&closing); + + return (pm_node_t *) pattern_node; + } + + break; + } + default: + break; + } + + // If we got here, then we didn't return one of the inner patterns by + // attaching its constant. In this case we'll create an array pattern and + // attach our constant to it. + pm_array_pattern_node_t *pattern_node = pm_array_pattern_node_constant_create(parser, node, &opening, &closing); + pm_array_pattern_node_requireds_append(pattern_node, inner); + return (pm_node_t *) pattern_node; +} + +/** + * Parse a rest pattern. + */ +static pm_splat_node_t * +parse_pattern_rest(pm_parser_t *parser, pm_constant_id_list_t *captures) { + assert(parser->previous.type == PM_TOKEN_USTAR); + pm_token_t operator = parser->previous; + pm_node_t *name = NULL; + + // Rest patterns don't necessarily have a name associated with them. So we + // will check for that here. If they do, then we'll add it to the local + // table since this pattern will cause it to become a local variable. + if (accept1(parser, PM_TOKEN_IDENTIFIER)) { + pm_token_t identifier = parser->previous; + pm_constant_id_t constant_id = pm_parser_constant_id_token(parser, &identifier); + + int depth; + if ((depth = pm_parser_local_depth_constant_id(parser, constant_id)) == -1) { + pm_parser_local_add(parser, constant_id, identifier.start, identifier.end, 0); + } + + parse_pattern_capture(parser, captures, constant_id, &PM_LOCATION_TOKEN_VALUE(&identifier)); + name = (pm_node_t *) pm_local_variable_target_node_create( + parser, + &PM_LOCATION_TOKEN_VALUE(&identifier), + constant_id, + (uint32_t) (depth == -1 ? 0 : depth) + ); + } + + // Finally we can return the created node. + return pm_splat_node_create(parser, &operator, name); +} + +/** + * Parse a keyword rest node. + */ +static pm_node_t * +parse_pattern_keyword_rest(pm_parser_t *parser, pm_constant_id_list_t *captures) { + assert(parser->current.type == PM_TOKEN_USTAR_STAR); + parser_lex(parser); + + pm_token_t operator = parser->previous; + pm_node_t *value = NULL; + + if (accept1(parser, PM_TOKEN_KEYWORD_NIL)) { + return (pm_node_t *) pm_no_keywords_parameter_node_create(parser, &operator, &parser->previous); + } + + if (accept1(parser, PM_TOKEN_IDENTIFIER)) { + pm_constant_id_t constant_id = pm_parser_constant_id_token(parser, &parser->previous); + + int depth; + if ((depth = pm_parser_local_depth_constant_id(parser, constant_id)) == -1) { + pm_parser_local_add(parser, constant_id, parser->previous.start, parser->previous.end, 0); + } + + parse_pattern_capture(parser, captures, constant_id, &PM_LOCATION_TOKEN_VALUE(&parser->previous)); + value = (pm_node_t *) pm_local_variable_target_node_create( + parser, + &PM_LOCATION_TOKEN_VALUE(&parser->previous), + constant_id, + (uint32_t) (depth == -1 ? 0 : depth) + ); + } + + return (pm_node_t *) pm_assoc_splat_node_create(parser, value, &operator); +} + +/** + * Check that the slice of the source given by the bounds parameters constitutes + * a valid local variable name. + */ +static bool +pm_slice_is_valid_local(const pm_parser_t *parser, const uint8_t *start, const uint8_t *end) { + ptrdiff_t length = end - start; + if (length == 0) return false; + + // First ensure that it starts with a valid identifier starting character. + size_t width = char_is_identifier_start(parser, start, end - start); + if (width == 0) return false; + + // Next, ensure that it's not an uppercase character. + if (parser->encoding_changed) { + if (parser->encoding->isupper_char(start, length)) return false; + } else { + if (pm_encoding_utf_8_isupper_char(start, length)) return false; + } + + // Next, iterate through all of the bytes of the string to ensure that they + // are all valid identifier characters. + const uint8_t *cursor = start + width; + while ((width = char_is_identifier(parser, cursor, end - cursor))) cursor += width; + return cursor == end; +} + +/** + * Create an implicit node for the value of a hash pattern that has omitted the + * value. This will use an implicit local variable target. + */ +static pm_node_t * +parse_pattern_hash_implicit_value(pm_parser_t *parser, pm_constant_id_list_t *captures, pm_symbol_node_t *key) { + const pm_location_t *value_loc = &((pm_symbol_node_t *) key)->value_loc; + + pm_constant_id_t constant_id = pm_parser_constant_id_location(parser, value_loc->start, value_loc->end); + int depth = -1; + + if (pm_slice_is_valid_local(parser, value_loc->start, value_loc->end)) { + depth = pm_parser_local_depth_constant_id(parser, constant_id); + } else { + pm_parser_err(parser, key->base.location.start, key->base.location.end, PM_ERR_PATTERN_HASH_KEY_LOCALS); + + if ((value_loc->end > value_loc->start) && ((value_loc->end[-1] == '!') || (value_loc->end[-1] == '?'))) { + PM_PARSER_ERR_LOCATION_FORMAT(parser, value_loc, PM_ERR_INVALID_LOCAL_VARIABLE_WRITE, (int) (value_loc->end - value_loc->start), (const char *) value_loc->start); + } + } + + if (depth == -1) { + pm_parser_local_add(parser, constant_id, value_loc->start, value_loc->end, 0); + } + + parse_pattern_capture(parser, captures, constant_id, value_loc); + pm_local_variable_target_node_t *target = pm_local_variable_target_node_create( + parser, + value_loc, + constant_id, + (uint32_t) (depth == -1 ? 0 : depth) + ); + + return (pm_node_t *) pm_implicit_node_create(parser, (pm_node_t *) target); +} + +/** + * Add a node to the list of keys for a hash pattern, and if it is a duplicate + * then add an error to the parser. + */ +static void +parse_pattern_hash_key(pm_parser_t *parser, pm_static_literals_t *keys, pm_node_t *node) { + if (pm_static_literals_add(&parser->newline_list, parser->start_line, keys, node, true) != NULL) { + pm_parser_err_node(parser, node, PM_ERR_PATTERN_HASH_KEY_DUPLICATE); + } +} + +/** + * Parse a hash pattern. + */ +static pm_hash_pattern_node_t * +parse_pattern_hash(pm_parser_t *parser, pm_constant_id_list_t *captures, pm_node_t *first_node, uint16_t depth) { + pm_node_list_t assocs = { 0 }; + pm_static_literals_t keys = { 0 }; + pm_node_t *rest = NULL; + + switch (PM_NODE_TYPE(first_node)) { + case PM_ASSOC_SPLAT_NODE: + case PM_NO_KEYWORDS_PARAMETER_NODE: + rest = first_node; + break; + case PM_SYMBOL_NODE: { + if (pm_symbol_node_label_p(first_node)) { + parse_pattern_hash_key(parser, &keys, first_node); + pm_node_t *value; + + if (match8(parser, PM_TOKEN_COMMA, PM_TOKEN_KEYWORD_THEN, PM_TOKEN_BRACE_RIGHT, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_PARENTHESIS_RIGHT, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON, PM_TOKEN_EOF)) { + // Otherwise, we will create an implicit local variable + // target for the value. + value = parse_pattern_hash_implicit_value(parser, captures, (pm_symbol_node_t *) first_node); + } else { + // Here we have a value for the first assoc in the list, so + // we will parse it now. + value = parse_pattern(parser, captures, PM_PARSE_PATTERN_SINGLE, PM_ERR_PATTERN_EXPRESSION_AFTER_KEY, (uint16_t) (depth + 1)); + } + + pm_token_t operator = not_provided(parser); + pm_node_t *assoc = (pm_node_t *) pm_assoc_node_create(parser, first_node, &operator, value); + + pm_node_list_append(&assocs, assoc); + break; + } + } + PRISM_FALLTHROUGH + default: { + // If we get anything else, then this is an error. For this we'll + // create a missing node for the value and create an assoc node for + // the first node in the list. + pm_diagnostic_id_t diag_id = PM_NODE_TYPE_P(first_node, PM_INTERPOLATED_SYMBOL_NODE) ? PM_ERR_PATTERN_HASH_KEY_INTERPOLATED : PM_ERR_PATTERN_HASH_KEY_LABEL; + pm_parser_err_node(parser, first_node, diag_id); + + pm_token_t operator = not_provided(parser); + pm_node_t *value = (pm_node_t *) pm_missing_node_create(parser, first_node->location.start, first_node->location.end); + pm_node_t *assoc = (pm_node_t *) pm_assoc_node_create(parser, first_node, &operator, value); + + pm_node_list_append(&assocs, assoc); + break; + } + } + + // If there are any other assocs, then we'll parse them now. + while (accept1(parser, PM_TOKEN_COMMA)) { + // Here we need to break to support trailing commas. + if (match7(parser, PM_TOKEN_KEYWORD_THEN, PM_TOKEN_BRACE_RIGHT, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_PARENTHESIS_RIGHT, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON, PM_TOKEN_EOF)) { + // Trailing commas are not allowed to follow a rest pattern. + if (rest != NULL) { + pm_parser_err_token(parser, &parser->current, PM_ERR_PATTERN_EXPRESSION_AFTER_REST); + } + + break; + } + + if (match1(parser, PM_TOKEN_USTAR_STAR)) { + pm_node_t *assoc = parse_pattern_keyword_rest(parser, captures); + + if (rest == NULL) { + rest = assoc; + } else { + pm_parser_err_node(parser, assoc, PM_ERR_PATTERN_EXPRESSION_AFTER_REST); + pm_node_list_append(&assocs, assoc); + } + } else { + pm_node_t *key; + + if (match1(parser, PM_TOKEN_STRING_BEGIN)) { + key = parse_strings(parser, NULL, true, (uint16_t) (depth + 1)); + + if (PM_NODE_TYPE_P(key, PM_INTERPOLATED_SYMBOL_NODE)) { + pm_parser_err_node(parser, key, PM_ERR_PATTERN_HASH_KEY_INTERPOLATED); + } else if (!pm_symbol_node_label_p(key)) { + pm_parser_err_node(parser, key, PM_ERR_PATTERN_LABEL_AFTER_COMMA); + } + } else { + expect1(parser, PM_TOKEN_LABEL, PM_ERR_PATTERN_LABEL_AFTER_COMMA); + key = (pm_node_t *) pm_symbol_node_label_create(parser, &parser->previous); + } + + parse_pattern_hash_key(parser, &keys, key); + pm_node_t *value = NULL; + + if (match7(parser, PM_TOKEN_COMMA, PM_TOKEN_KEYWORD_THEN, PM_TOKEN_BRACE_RIGHT, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_PARENTHESIS_RIGHT, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)) { + value = parse_pattern_hash_implicit_value(parser, captures, (pm_symbol_node_t *) key); + } else { + value = parse_pattern(parser, captures, PM_PARSE_PATTERN_SINGLE, PM_ERR_PATTERN_EXPRESSION_AFTER_KEY, (uint16_t) (depth + 1)); + } + + pm_token_t operator = not_provided(parser); + pm_node_t *assoc = (pm_node_t *) pm_assoc_node_create(parser, key, &operator, value); + + if (rest != NULL) { + pm_parser_err_node(parser, assoc, PM_ERR_PATTERN_EXPRESSION_AFTER_REST); + } + + pm_node_list_append(&assocs, assoc); + } + } + + pm_hash_pattern_node_t *node = pm_hash_pattern_node_node_list_create(parser, &assocs, rest); + xfree(assocs.nodes); + + pm_static_literals_free(&keys); + return node; +} + +/** + * Parse a pattern expression primitive. + */ +static pm_node_t * +parse_pattern_primitive(pm_parser_t *parser, pm_constant_id_list_t *captures, pm_diagnostic_id_t diag_id, uint16_t depth) { + switch (parser->current.type) { + case PM_TOKEN_IDENTIFIER: + case PM_TOKEN_METHOD_NAME: { + parser_lex(parser); + pm_constant_id_t constant_id = pm_parser_constant_id_token(parser, &parser->previous); + + int depth; + if ((depth = pm_parser_local_depth_constant_id(parser, constant_id)) == -1) { + pm_parser_local_add(parser, constant_id, parser->previous.start, parser->previous.end, 0); + } + + parse_pattern_capture(parser, captures, constant_id, &PM_LOCATION_TOKEN_VALUE(&parser->previous)); + return (pm_node_t *) pm_local_variable_target_node_create( + parser, + &PM_LOCATION_TOKEN_VALUE(&parser->previous), + constant_id, + (uint32_t) (depth == -1 ? 0 : depth) + ); + } + case PM_TOKEN_BRACKET_LEFT_ARRAY: { + pm_token_t opening = parser->current; + parser_lex(parser); + + if (accept1(parser, PM_TOKEN_BRACKET_RIGHT)) { + // If we have an empty array pattern, then we'll just return a new + // array pattern node. + return (pm_node_t *) pm_array_pattern_node_empty_create(parser, &opening, &parser->previous); + } + + // Otherwise, we'll parse the inner pattern, then deal with it depending + // on the type it returns. + pm_node_t *inner = parse_pattern(parser, captures, PM_PARSE_PATTERN_MULTI, PM_ERR_PATTERN_EXPRESSION_AFTER_BRACKET, (uint16_t) (depth + 1)); + + accept1(parser, PM_TOKEN_NEWLINE); + expect1(parser, PM_TOKEN_BRACKET_RIGHT, PM_ERR_PATTERN_TERM_BRACKET); + pm_token_t closing = parser->previous; + + switch (PM_NODE_TYPE(inner)) { + case PM_ARRAY_PATTERN_NODE: { + pm_array_pattern_node_t *pattern_node = (pm_array_pattern_node_t *) inner; + if (pattern_node->opening_loc.start == NULL) { + pattern_node->base.location.start = opening.start; + pattern_node->base.location.end = closing.end; + + pattern_node->opening_loc = PM_LOCATION_TOKEN_VALUE(&opening); + pattern_node->closing_loc = PM_LOCATION_TOKEN_VALUE(&closing); + + return (pm_node_t *) pattern_node; + } + + break; + } + case PM_FIND_PATTERN_NODE: { + pm_find_pattern_node_t *pattern_node = (pm_find_pattern_node_t *) inner; + if (pattern_node->opening_loc.start == NULL) { + pattern_node->base.location.start = opening.start; + pattern_node->base.location.end = closing.end; + + pattern_node->opening_loc = PM_LOCATION_TOKEN_VALUE(&opening); + pattern_node->closing_loc = PM_LOCATION_TOKEN_VALUE(&closing); + + return (pm_node_t *) pattern_node; + } + + break; + } + default: + break; + } + + pm_array_pattern_node_t *node = pm_array_pattern_node_empty_create(parser, &opening, &closing); + pm_array_pattern_node_requireds_append(node, inner); + return (pm_node_t *) node; + } + case PM_TOKEN_BRACE_LEFT: { + bool previous_pattern_matching_newlines = parser->pattern_matching_newlines; + parser->pattern_matching_newlines = false; + + pm_hash_pattern_node_t *node; + pm_token_t opening = parser->current; + parser_lex(parser); + + if (accept1(parser, PM_TOKEN_BRACE_RIGHT)) { + // If we have an empty hash pattern, then we'll just return a new hash + // pattern node. + node = pm_hash_pattern_node_empty_create(parser, &opening, &parser->previous); + } else { + pm_node_t *first_node; + + switch (parser->current.type) { + case PM_TOKEN_LABEL: + parser_lex(parser); + first_node = (pm_node_t *) pm_symbol_node_label_create(parser, &parser->previous); + break; + case PM_TOKEN_USTAR_STAR: + first_node = parse_pattern_keyword_rest(parser, captures); + break; + case PM_TOKEN_STRING_BEGIN: + first_node = parse_expression(parser, PM_BINDING_POWER_MAX, false, true, PM_ERR_PATTERN_HASH_KEY_LABEL, (uint16_t) (depth + 1)); + break; + default: { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_PATTERN_HASH_KEY, pm_token_type_human(parser->current.type)); + parser_lex(parser); + + first_node = (pm_node_t *) pm_missing_node_create(parser, parser->previous.start, parser->previous.end); + break; + } + } + + node = parse_pattern_hash(parser, captures, first_node, (uint16_t) (depth + 1)); + + accept1(parser, PM_TOKEN_NEWLINE); + expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_PATTERN_TERM_BRACE); + pm_token_t closing = parser->previous; + + node->base.location.start = opening.start; + node->base.location.end = closing.end; + + node->opening_loc = PM_LOCATION_TOKEN_VALUE(&opening); + node->closing_loc = PM_LOCATION_TOKEN_VALUE(&closing); + } + + parser->pattern_matching_newlines = previous_pattern_matching_newlines; + return (pm_node_t *) node; + } + case PM_TOKEN_UDOT_DOT: + case PM_TOKEN_UDOT_DOT_DOT: { + pm_token_t operator = parser->current; + parser_lex(parser); + + // Since we have a unary range operator, we need to parse the subsequent + // expression as the right side of the range. + switch (parser->current.type) { + case PM_CASE_PRIMITIVE: { + pm_node_t *right = parse_expression(parser, PM_BINDING_POWER_MAX, false, false, PM_ERR_PATTERN_EXPRESSION_AFTER_RANGE, (uint16_t) (depth + 1)); + return (pm_node_t *) pm_range_node_create(parser, NULL, &operator, right); + } + default: { + pm_parser_err_token(parser, &operator, PM_ERR_PATTERN_EXPRESSION_AFTER_RANGE); + pm_node_t *right = (pm_node_t *) pm_missing_node_create(parser, operator.start, operator.end); + return (pm_node_t *) pm_range_node_create(parser, NULL, &operator, right); + } + } + } + case PM_CASE_PRIMITIVE: { + pm_node_t *node = parse_expression(parser, PM_BINDING_POWER_MAX, false, true, diag_id, (uint16_t) (depth + 1)); + + // If we found a label, we need to immediately return to the caller. + if (pm_symbol_node_label_p(node)) return node; + + // Now that we have a primitive, we need to check if it's part of a range. + if (accept2(parser, PM_TOKEN_DOT_DOT, PM_TOKEN_DOT_DOT_DOT)) { + pm_token_t operator = parser->previous; + + // Now that we have the operator, we need to check if this is followed + // by another expression. If it is, then we will create a full range + // node. Otherwise, we'll create an endless range. + switch (parser->current.type) { + case PM_CASE_PRIMITIVE: { + pm_node_t *right = parse_expression(parser, PM_BINDING_POWER_MAX, false, false, PM_ERR_PATTERN_EXPRESSION_AFTER_RANGE, (uint16_t) (depth + 1)); + return (pm_node_t *) pm_range_node_create(parser, node, &operator, right); + } + default: + return (pm_node_t *) pm_range_node_create(parser, node, &operator, NULL); + } + } + + return node; + } + case PM_TOKEN_CARET: { + parser_lex(parser); + pm_token_t operator = parser->previous; + + // At this point we have a pin operator. We need to check the subsequent + // expression to determine if it's a variable or an expression. + switch (parser->current.type) { + case PM_TOKEN_IDENTIFIER: { + parser_lex(parser); + pm_node_t *variable = (pm_node_t *) parse_variable(parser); + + if (variable == NULL) { + PM_PARSER_ERR_TOKEN_FORMAT_CONTENT(parser, parser->previous, PM_ERR_NO_LOCAL_VARIABLE); + variable = (pm_node_t *) pm_local_variable_read_node_missing_create(parser, &parser->previous, 0); + } + + return (pm_node_t *) pm_pinned_variable_node_create(parser, &operator, variable); + } + case PM_TOKEN_INSTANCE_VARIABLE: { + parser_lex(parser); + pm_node_t *variable = (pm_node_t *) pm_instance_variable_read_node_create(parser, &parser->previous); + + return (pm_node_t *) pm_pinned_variable_node_create(parser, &operator, variable); + } + case PM_TOKEN_CLASS_VARIABLE: { + parser_lex(parser); + pm_node_t *variable = (pm_node_t *) pm_class_variable_read_node_create(parser, &parser->previous); + + return (pm_node_t *) pm_pinned_variable_node_create(parser, &operator, variable); + } + case PM_TOKEN_GLOBAL_VARIABLE: { + parser_lex(parser); + pm_node_t *variable = (pm_node_t *) pm_global_variable_read_node_create(parser, &parser->previous); + + return (pm_node_t *) pm_pinned_variable_node_create(parser, &operator, variable); + } + case PM_TOKEN_NUMBERED_REFERENCE: { + parser_lex(parser); + pm_node_t *variable = (pm_node_t *) pm_numbered_reference_read_node_create(parser, &parser->previous); + + return (pm_node_t *) pm_pinned_variable_node_create(parser, &operator, variable); + } + case PM_TOKEN_BACK_REFERENCE: { + parser_lex(parser); + pm_node_t *variable = (pm_node_t *) pm_back_reference_read_node_create(parser, &parser->previous); + + return (pm_node_t *) pm_pinned_variable_node_create(parser, &operator, variable); + } + case PM_TOKEN_PARENTHESIS_LEFT: { + bool previous_pattern_matching_newlines = parser->pattern_matching_newlines; + parser->pattern_matching_newlines = false; + + pm_token_t lparen = parser->current; + parser_lex(parser); + + pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_STATEMENT, true, false, PM_ERR_PATTERN_EXPRESSION_AFTER_PIN, (uint16_t) (depth + 1)); + parser->pattern_matching_newlines = previous_pattern_matching_newlines; + + accept1(parser, PM_TOKEN_NEWLINE); + expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_PATTERN_TERM_PAREN); + return (pm_node_t *) pm_pinned_expression_node_create(parser, expression, &operator, &lparen, &parser->previous); + } + default: { + // If we get here, then we have a pin operator followed by something + // not understood. We'll create a missing node and return that. + pm_parser_err_token(parser, &operator, PM_ERR_PATTERN_EXPRESSION_AFTER_PIN); + pm_node_t *variable = (pm_node_t *) pm_missing_node_create(parser, operator.start, operator.end); + return (pm_node_t *) pm_pinned_variable_node_create(parser, &operator, variable); + } + } + } + case PM_TOKEN_UCOLON_COLON: { + pm_token_t delimiter = parser->current; + parser_lex(parser); + + expect1(parser, PM_TOKEN_CONSTANT, PM_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT); + pm_constant_path_node_t *node = pm_constant_path_node_create(parser, NULL, &delimiter, &parser->previous); + + return parse_pattern_constant_path(parser, captures, (pm_node_t *) node, (uint16_t) (depth + 1)); + } + case PM_TOKEN_CONSTANT: { + pm_token_t constant = parser->current; + parser_lex(parser); + + pm_node_t *node = (pm_node_t *) pm_constant_read_node_create(parser, &constant); + return parse_pattern_constant_path(parser, captures, node, (uint16_t) (depth + 1)); + } + default: + pm_parser_err_current(parser, diag_id); + return (pm_node_t *) pm_missing_node_create(parser, parser->current.start, parser->current.end); + } +} + +/** + * Parse any number of primitives joined by alternation and ended optionally by + * assignment. + */ +static pm_node_t * +parse_pattern_primitives(pm_parser_t *parser, pm_constant_id_list_t *captures, pm_node_t *first_node, pm_diagnostic_id_t diag_id, uint16_t depth) { + pm_node_t *node = first_node; + + while ((node == NULL) || accept1(parser, PM_TOKEN_PIPE)) { + pm_token_t operator = parser->previous; + + switch (parser->current.type) { + case PM_TOKEN_IDENTIFIER: + case PM_TOKEN_BRACKET_LEFT_ARRAY: + case PM_TOKEN_BRACE_LEFT: + case PM_TOKEN_CARET: + case PM_TOKEN_CONSTANT: + case PM_TOKEN_UCOLON_COLON: + case PM_TOKEN_UDOT_DOT: + case PM_TOKEN_UDOT_DOT_DOT: + case PM_CASE_PRIMITIVE: { + if (node == NULL) { + node = parse_pattern_primitive(parser, captures, diag_id, (uint16_t) (depth + 1)); + } else { + pm_node_t *right = parse_pattern_primitive(parser, captures, PM_ERR_PATTERN_EXPRESSION_AFTER_PIPE, (uint16_t) (depth + 1)); + node = (pm_node_t *) pm_alternation_pattern_node_create(parser, node, right, &operator); + } + + break; + } + case PM_TOKEN_PARENTHESIS_LEFT: + case PM_TOKEN_PARENTHESIS_LEFT_PARENTHESES: { + pm_token_t opening = parser->current; + parser_lex(parser); + + pm_node_t *body = parse_pattern(parser, captures, PM_PARSE_PATTERN_SINGLE, PM_ERR_PATTERN_EXPRESSION_AFTER_PAREN, (uint16_t) (depth + 1)); + accept1(parser, PM_TOKEN_NEWLINE); + expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_PATTERN_TERM_PAREN); + pm_node_t *right = (pm_node_t *) pm_parentheses_node_create(parser, &opening, body, &parser->previous, 0); + + if (node == NULL) { + node = right; + } else { + node = (pm_node_t *) pm_alternation_pattern_node_create(parser, node, right, &operator); + } + + break; + } + default: { + pm_parser_err_current(parser, diag_id); + pm_node_t *right = (pm_node_t *) pm_missing_node_create(parser, parser->current.start, parser->current.end); + + if (node == NULL) { + node = right; + } else { + node = (pm_node_t *) pm_alternation_pattern_node_create(parser, node, right, &operator); + } + + break; + } + } + } + + // If we have an =>, then we are assigning this pattern to a variable. + // In this case we should create an assignment node. + while (accept1(parser, PM_TOKEN_EQUAL_GREATER)) { + pm_token_t operator = parser->previous; + expect1(parser, PM_TOKEN_IDENTIFIER, PM_ERR_PATTERN_IDENT_AFTER_HROCKET); + + pm_constant_id_t constant_id = pm_parser_constant_id_token(parser, &parser->previous); + int depth; + + if ((depth = pm_parser_local_depth_constant_id(parser, constant_id)) == -1) { + pm_parser_local_add(parser, constant_id, parser->previous.start, parser->previous.end, 0); + } + + parse_pattern_capture(parser, captures, constant_id, &PM_LOCATION_TOKEN_VALUE(&parser->previous)); + pm_local_variable_target_node_t *target = pm_local_variable_target_node_create( + parser, + &PM_LOCATION_TOKEN_VALUE(&parser->previous), + constant_id, + (uint32_t) (depth == -1 ? 0 : depth) + ); + + node = (pm_node_t *) pm_capture_pattern_node_create(parser, node, target, &operator); + } + + return node; +} + +/** + * Parse a pattern matching expression. + */ +static pm_node_t * +parse_pattern(pm_parser_t *parser, pm_constant_id_list_t *captures, uint8_t flags, pm_diagnostic_id_t diag_id, uint16_t depth) { + pm_node_t *node = NULL; + + bool leading_rest = false; + bool trailing_rest = false; + + switch (parser->current.type) { + case PM_TOKEN_LABEL: { + parser_lex(parser); + pm_node_t *key = (pm_node_t *) pm_symbol_node_label_create(parser, &parser->previous); + node = (pm_node_t *) parse_pattern_hash(parser, captures, key, (uint16_t) (depth + 1)); + + if (!(flags & PM_PARSE_PATTERN_TOP)) { + pm_parser_err_node(parser, node, PM_ERR_PATTERN_HASH_IMPLICIT); + } + + return node; + } + case PM_TOKEN_USTAR_STAR: { + node = parse_pattern_keyword_rest(parser, captures); + node = (pm_node_t *) parse_pattern_hash(parser, captures, node, (uint16_t) (depth + 1)); + + if (!(flags & PM_PARSE_PATTERN_TOP)) { + pm_parser_err_node(parser, node, PM_ERR_PATTERN_HASH_IMPLICIT); + } + + return node; + } + case PM_TOKEN_STRING_BEGIN: { + // We need special handling for string beginnings because they could + // be dynamic symbols leading to hash patterns. + node = parse_pattern_primitive(parser, captures, diag_id, (uint16_t) (depth + 1)); + + if (pm_symbol_node_label_p(node)) { + node = (pm_node_t *) parse_pattern_hash(parser, captures, node, (uint16_t) (depth + 1)); + + if (!(flags & PM_PARSE_PATTERN_TOP)) { + pm_parser_err_node(parser, node, PM_ERR_PATTERN_HASH_IMPLICIT); + } + + return node; + } + + node = parse_pattern_primitives(parser, captures, node, diag_id, (uint16_t) (depth + 1)); + break; + } + case PM_TOKEN_USTAR: { + if (flags & (PM_PARSE_PATTERN_TOP | PM_PARSE_PATTERN_MULTI)) { + parser_lex(parser); + node = (pm_node_t *) parse_pattern_rest(parser, captures); + leading_rest = true; + break; + } + } + PRISM_FALLTHROUGH + default: + node = parse_pattern_primitives(parser, captures, NULL, diag_id, (uint16_t) (depth + 1)); + break; + } + + // If we got a dynamic label symbol, then we need to treat it like the + // beginning of a hash pattern. + if (pm_symbol_node_label_p(node)) { + return (pm_node_t *) parse_pattern_hash(parser, captures, node, (uint16_t) (depth + 1)); + } + + if ((flags & PM_PARSE_PATTERN_MULTI) && match1(parser, PM_TOKEN_COMMA)) { + // If we have a comma, then we are now parsing either an array pattern + // or a find pattern. We need to parse all of the patterns, put them + // into a big list, and then determine which type of node we have. + pm_node_list_t nodes = { 0 }; + pm_node_list_append(&nodes, node); + + // Gather up all of the patterns into the list. + while (accept1(parser, PM_TOKEN_COMMA)) { + // Break early here in case we have a trailing comma. + if (match9(parser, PM_TOKEN_KEYWORD_THEN, PM_TOKEN_BRACE_RIGHT, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_PARENTHESIS_RIGHT, PM_TOKEN_SEMICOLON, PM_TOKEN_NEWLINE, PM_TOKEN_EOF,PM_TOKEN_KEYWORD_AND, PM_TOKEN_KEYWORD_OR)) { + node = (pm_node_t *) pm_implicit_rest_node_create(parser, &parser->previous); + pm_node_list_append(&nodes, node); + trailing_rest = true; + break; + } + + if (accept1(parser, PM_TOKEN_USTAR)) { + node = (pm_node_t *) parse_pattern_rest(parser, captures); + + // If we have already parsed a splat pattern, then this is an + // error. We will continue to parse the rest of the patterns, + // but we will indicate it as an error. + if (trailing_rest) { + pm_parser_err_previous(parser, PM_ERR_PATTERN_REST); + } + + trailing_rest = true; + } else { + node = parse_pattern_primitives(parser, captures, NULL, PM_ERR_PATTERN_EXPRESSION_AFTER_COMMA, (uint16_t) (depth + 1)); + } + + pm_node_list_append(&nodes, node); + } + + // If the first pattern and the last pattern are rest patterns, then we + // will call this a find pattern, regardless of how many rest patterns + // are in between because we know we already added the appropriate + // errors. Otherwise we will create an array pattern. + if (leading_rest && PM_NODE_TYPE_P(nodes.nodes[nodes.size - 1], PM_SPLAT_NODE)) { + node = (pm_node_t *) pm_find_pattern_node_create(parser, &nodes); + + if (nodes.size == 2) { + pm_parser_err_node(parser, node, PM_ERR_PATTERN_FIND_MISSING_INNER); + } + } else { + node = (pm_node_t *) pm_array_pattern_node_node_list_create(parser, &nodes); + + if (leading_rest && trailing_rest) { + pm_parser_err_node(parser, node, PM_ERR_PATTERN_ARRAY_MULTIPLE_RESTS); + } + } + + xfree(nodes.nodes); + } else if (leading_rest) { + // Otherwise, if we parsed a single splat pattern, then we know we have + // an array pattern, so we can go ahead and create that node. + node = (pm_node_t *) pm_array_pattern_node_rest_create(parser, node); + } + + return node; +} + +/** + * Incorporate a negative sign into a numeric node by subtracting 1 character + * from its start bounds. If it's a compound node, then we will recursively + * apply this function to its value. + */ +static inline void +parse_negative_numeric(pm_node_t *node) { + switch (PM_NODE_TYPE(node)) { + case PM_INTEGER_NODE: { + pm_integer_node_t *cast = (pm_integer_node_t *) node; + cast->base.location.start--; + cast->value.negative = true; + break; + } + case PM_FLOAT_NODE: { + pm_float_node_t *cast = (pm_float_node_t *) node; + cast->base.location.start--; + cast->value = -cast->value; + break; + } + case PM_RATIONAL_NODE: { + pm_rational_node_t *cast = (pm_rational_node_t *) node; + cast->base.location.start--; + cast->numerator.negative = true; + break; + } + case PM_IMAGINARY_NODE: + node->location.start--; + parse_negative_numeric(((pm_imaginary_node_t *) node)->numeric); + break; + default: + assert(false && "unreachable"); + break; + } +} + +/** + * Append an error to the error list on the parser using the given diagnostic + * ID. This function is a specialization that handles formatting the specific + * kind of error that is being appended. + */ +static void +pm_parser_err_prefix(pm_parser_t *parser, pm_diagnostic_id_t diag_id) { + switch (diag_id) { + case PM_ERR_HASH_KEY: { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->previous, diag_id, pm_token_type_human(parser->previous.type)); + break; + } + case PM_ERR_HASH_VALUE: + case PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR: { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, diag_id, pm_token_type_human(parser->current.type)); + break; + } + case PM_ERR_UNARY_RECEIVER: { + const char *human = (parser->current.type == PM_TOKEN_EOF ? "end-of-input" : pm_token_type_human(parser->current.type)); + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->previous, diag_id, human, parser->previous.start[0]); + break; + } + case PM_ERR_UNARY_DISALLOWED: + case PM_ERR_EXPECT_ARGUMENT: { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, diag_id, pm_token_type_human(parser->current.type)); + break; + } + default: + pm_parser_err_previous(parser, diag_id); + break; + } +} + +/** + * Ensures that the current retry token is valid in the current context. + */ +static void +parse_retry(pm_parser_t *parser, const pm_node_t *node) { +#define CONTEXT_NONE 0 +#define CONTEXT_THROUGH_ENSURE 1 +#define CONTEXT_THROUGH_ELSE 2 + + pm_context_node_t *context_node = parser->current_context; + int context = CONTEXT_NONE; + + while (context_node != NULL) { + switch (context_node->context) { + case PM_CONTEXT_BEGIN_RESCUE: + case PM_CONTEXT_BLOCK_RESCUE: + case PM_CONTEXT_CLASS_RESCUE: + case PM_CONTEXT_DEF_RESCUE: + case PM_CONTEXT_LAMBDA_RESCUE: + case PM_CONTEXT_MODULE_RESCUE: + case PM_CONTEXT_SCLASS_RESCUE: + case PM_CONTEXT_DEFINED: + case PM_CONTEXT_RESCUE_MODIFIER: + // These are the good cases. We're allowed to have a retry here. + return; + case PM_CONTEXT_CLASS: + case PM_CONTEXT_DEF: + case PM_CONTEXT_DEF_PARAMS: + case PM_CONTEXT_MAIN: + case PM_CONTEXT_MODULE: + case PM_CONTEXT_PREEXE: + case PM_CONTEXT_SCLASS: + // These are the bad cases. We're not allowed to have a retry in + // these contexts. + if (context == CONTEXT_NONE) { + pm_parser_err_node(parser, node, PM_ERR_INVALID_RETRY_WITHOUT_RESCUE); + } else if (context == CONTEXT_THROUGH_ENSURE) { + pm_parser_err_node(parser, node, PM_ERR_INVALID_RETRY_AFTER_ENSURE); + } else if (context == CONTEXT_THROUGH_ELSE) { + pm_parser_err_node(parser, node, PM_ERR_INVALID_RETRY_AFTER_ELSE); + } + return; + case PM_CONTEXT_BEGIN_ELSE: + case PM_CONTEXT_BLOCK_ELSE: + case PM_CONTEXT_CLASS_ELSE: + case PM_CONTEXT_DEF_ELSE: + case PM_CONTEXT_LAMBDA_ELSE: + case PM_CONTEXT_MODULE_ELSE: + case PM_CONTEXT_SCLASS_ELSE: + // These are also bad cases, but with a more specific error + // message indicating the else. + context = CONTEXT_THROUGH_ELSE; + break; + case PM_CONTEXT_BEGIN_ENSURE: + case PM_CONTEXT_BLOCK_ENSURE: + case PM_CONTEXT_CLASS_ENSURE: + case PM_CONTEXT_DEF_ENSURE: + case PM_CONTEXT_LAMBDA_ENSURE: + case PM_CONTEXT_MODULE_ENSURE: + case PM_CONTEXT_SCLASS_ENSURE: + // These are also bad cases, but with a more specific error + // message indicating the ensure. + context = CONTEXT_THROUGH_ENSURE; + break; + case PM_CONTEXT_NONE: + // This case should never happen. + assert(false && "unreachable"); + break; + case PM_CONTEXT_BEGIN: + case PM_CONTEXT_BLOCK_BRACES: + case PM_CONTEXT_BLOCK_KEYWORDS: + case PM_CONTEXT_CASE_IN: + case PM_CONTEXT_CASE_WHEN: + case PM_CONTEXT_DEFAULT_PARAMS: + case PM_CONTEXT_ELSE: + case PM_CONTEXT_ELSIF: + case PM_CONTEXT_EMBEXPR: + case PM_CONTEXT_FOR_INDEX: + case PM_CONTEXT_FOR: + case PM_CONTEXT_IF: + case PM_CONTEXT_LAMBDA_BRACES: + case PM_CONTEXT_LAMBDA_DO_END: + case PM_CONTEXT_LOOP_PREDICATE: + case PM_CONTEXT_MULTI_TARGET: + case PM_CONTEXT_PARENS: + case PM_CONTEXT_POSTEXE: + case PM_CONTEXT_PREDICATE: + case PM_CONTEXT_TERNARY: + case PM_CONTEXT_UNLESS: + case PM_CONTEXT_UNTIL: + case PM_CONTEXT_WHILE: + // In these contexts we should continue walking up the list of + // contexts. + break; + } + + context_node = context_node->prev; + } + +#undef CONTEXT_NONE +#undef CONTEXT_ENSURE +#undef CONTEXT_ELSE +} + +/** + * Ensures that the current yield token is valid in the current context. + */ +static void +parse_yield(pm_parser_t *parser, const pm_node_t *node) { + pm_context_node_t *context_node = parser->current_context; + + while (context_node != NULL) { + switch (context_node->context) { + case PM_CONTEXT_DEF: + case PM_CONTEXT_DEF_PARAMS: + case PM_CONTEXT_DEFINED: + case PM_CONTEXT_DEF_ENSURE: + case PM_CONTEXT_DEF_RESCUE: + case PM_CONTEXT_DEF_ELSE: + // These are the good cases. We're allowed to have a block exit + // in these contexts. + return; + case PM_CONTEXT_CLASS: + case PM_CONTEXT_CLASS_ENSURE: + case PM_CONTEXT_CLASS_RESCUE: + case PM_CONTEXT_CLASS_ELSE: + case PM_CONTEXT_MAIN: + case PM_CONTEXT_MODULE: + case PM_CONTEXT_MODULE_ENSURE: + case PM_CONTEXT_MODULE_RESCUE: + case PM_CONTEXT_MODULE_ELSE: + case PM_CONTEXT_SCLASS: + case PM_CONTEXT_SCLASS_RESCUE: + case PM_CONTEXT_SCLASS_ENSURE: + case PM_CONTEXT_SCLASS_ELSE: + // These are the bad cases. We're not allowed to have a retry in + // these contexts. + pm_parser_err_node(parser, node, PM_ERR_INVALID_YIELD); + return; + case PM_CONTEXT_NONE: + // This case should never happen. + assert(false && "unreachable"); + break; + case PM_CONTEXT_BEGIN: + case PM_CONTEXT_BEGIN_ELSE: + case PM_CONTEXT_BEGIN_ENSURE: + case PM_CONTEXT_BEGIN_RESCUE: + case PM_CONTEXT_BLOCK_BRACES: + case PM_CONTEXT_BLOCK_KEYWORDS: + case PM_CONTEXT_BLOCK_ELSE: + case PM_CONTEXT_BLOCK_ENSURE: + case PM_CONTEXT_BLOCK_RESCUE: + case PM_CONTEXT_CASE_IN: + case PM_CONTEXT_CASE_WHEN: + case PM_CONTEXT_DEFAULT_PARAMS: + case PM_CONTEXT_ELSE: + case PM_CONTEXT_ELSIF: + case PM_CONTEXT_EMBEXPR: + case PM_CONTEXT_FOR_INDEX: + case PM_CONTEXT_FOR: + case PM_CONTEXT_IF: + case PM_CONTEXT_LAMBDA_BRACES: + case PM_CONTEXT_LAMBDA_DO_END: + case PM_CONTEXT_LAMBDA_ELSE: + case PM_CONTEXT_LAMBDA_ENSURE: + case PM_CONTEXT_LAMBDA_RESCUE: + case PM_CONTEXT_LOOP_PREDICATE: + case PM_CONTEXT_MULTI_TARGET: + case PM_CONTEXT_PARENS: + case PM_CONTEXT_POSTEXE: + case PM_CONTEXT_PREDICATE: + case PM_CONTEXT_PREEXE: + case PM_CONTEXT_RESCUE_MODIFIER: + case PM_CONTEXT_TERNARY: + case PM_CONTEXT_UNLESS: + case PM_CONTEXT_UNTIL: + case PM_CONTEXT_WHILE: + // In these contexts we should continue walking up the list of + // contexts. + break; + } + + context_node = context_node->prev; + } +} + +/** + * This struct is used to pass information between the regular expression parser + * and the error callback. + */ +typedef struct { + /** The parser that we are parsing the regular expression for. */ + pm_parser_t *parser; + + /** The start of the regular expression. */ + const uint8_t *start; + + /** The end of the regular expression. */ + const uint8_t *end; + + /** + * Whether or not the source of the regular expression is shared. This + * impacts the location of error messages, because if it is shared then we + * can use the location directly and if it is not, then we use the bounds of + * the regular expression itself. + */ + bool shared; +} parse_regular_expression_error_data_t; + +/** + * This callback is called when the regular expression parser encounters a + * syntax error. + */ +static void +parse_regular_expression_error(const uint8_t *start, const uint8_t *end, const char *message, void *data) { + parse_regular_expression_error_data_t *callback_data = (parse_regular_expression_error_data_t *) data; + pm_location_t location; + + if (callback_data->shared) { + location = (pm_location_t) { .start = start, .end = end }; + } else { + location = (pm_location_t) { .start = callback_data->start, .end = callback_data->end }; + } + + PM_PARSER_ERR_FORMAT(callback_data->parser, location.start, location.end, PM_ERR_REGEXP_PARSE_ERROR, message); +} + +/** + * Parse the errors for the regular expression and add them to the parser. + */ +static void +parse_regular_expression_errors(pm_parser_t *parser, pm_regular_expression_node_t *node) { + const pm_string_t *unescaped = &node->unescaped; + parse_regular_expression_error_data_t error_data = { + .parser = parser, + .start = node->base.location.start, + .end = node->base.location.end, + .shared = unescaped->type == PM_STRING_SHARED + }; + + pm_regexp_parse(parser, pm_string_source(unescaped), pm_string_length(unescaped), PM_NODE_FLAG_P(node, PM_REGULAR_EXPRESSION_FLAGS_EXTENDED), NULL, NULL, parse_regular_expression_error, &error_data); +} + +/** + * Parse an expression that begins with the previous node that we just lexed. + */ +static inline pm_node_t * +parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call, bool accepts_label, pm_diagnostic_id_t diag_id, uint16_t depth) { + switch (parser->current.type) { + case PM_TOKEN_BRACKET_LEFT_ARRAY: { + parser_lex(parser); + + pm_array_node_t *array = pm_array_node_create(parser, &parser->previous); + pm_accepts_block_stack_push(parser, true); + bool parsed_bare_hash = false; + + while (!match2(parser, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_EOF)) { + bool accepted_newline = accept1(parser, PM_TOKEN_NEWLINE); + + // Handle the case where we don't have a comma and we have a + // newline followed by a right bracket. + if (accepted_newline && match1(parser, PM_TOKEN_BRACKET_RIGHT)) { + break; + } + + // Ensure that we have a comma between elements in the array. + if (array->elements.size > 0) { + if (accept1(parser, PM_TOKEN_COMMA)) { + // If there was a comma but we also accepts a newline, + // then this is a syntax error. + if (accepted_newline) { + pm_parser_err_previous(parser, PM_ERR_INVALID_COMMA); + } + } else { + // If there was no comma, then we need to add a syntax + // error. + const uint8_t *location = parser->previous.end; + PM_PARSER_ERR_FORMAT(parser, location, location, PM_ERR_ARRAY_SEPARATOR, pm_token_type_human(parser->current.type)); + + parser->previous.start = location; + parser->previous.type = PM_TOKEN_MISSING; + } + } + + // If we have a right bracket immediately following a comma, + // this is allowed since it's a trailing comma. In this case we + // can break out of the loop. + if (match1(parser, PM_TOKEN_BRACKET_RIGHT)) break; + + pm_node_t *element; + + if (accept1(parser, PM_TOKEN_USTAR)) { + pm_token_t operator = parser->previous; + pm_node_t *expression = NULL; + + if (match3(parser, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_COMMA, PM_TOKEN_EOF)) { + pm_parser_scope_forwarding_positionals_check(parser, &operator); + } else { + expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_ARRAY_EXPRESSION_AFTER_STAR, (uint16_t) (depth + 1)); + } + + element = (pm_node_t *) pm_splat_node_create(parser, &operator, expression); + } else if (match2(parser, PM_TOKEN_LABEL, PM_TOKEN_USTAR_STAR)) { + if (parsed_bare_hash) { + pm_parser_err_current(parser, PM_ERR_EXPRESSION_BARE_HASH); + } + + element = (pm_node_t *) pm_keyword_hash_node_create(parser); + pm_static_literals_t hash_keys = { 0 }; + + if (!match8(parser, PM_TOKEN_EOF, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON, PM_TOKEN_EOF, PM_TOKEN_BRACE_RIGHT, PM_TOKEN_BRACKET_RIGHT, PM_TOKEN_KEYWORD_DO, PM_TOKEN_PARENTHESIS_RIGHT)) { + parse_assocs(parser, &hash_keys, element, (uint16_t) (depth + 1)); + } + + pm_static_literals_free(&hash_keys); + parsed_bare_hash = true; + } else { + element = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, true, PM_ERR_ARRAY_EXPRESSION, (uint16_t) (depth + 1)); + + if (pm_symbol_node_label_p(element) || accept1(parser, PM_TOKEN_EQUAL_GREATER)) { + if (parsed_bare_hash) { + pm_parser_err_previous(parser, PM_ERR_EXPRESSION_BARE_HASH); + } + + pm_keyword_hash_node_t *hash = pm_keyword_hash_node_create(parser); + pm_static_literals_t hash_keys = { 0 }; + pm_hash_key_static_literals_add(parser, &hash_keys, element); + + pm_token_t operator; + if (parser->previous.type == PM_TOKEN_EQUAL_GREATER) { + operator = parser->previous; + } else { + operator = not_provided(parser); + } + + pm_node_t *value = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_HASH_VALUE, (uint16_t) (depth + 1)); + pm_node_t *assoc = (pm_node_t *) pm_assoc_node_create(parser, element, &operator, value); + pm_keyword_hash_node_elements_append(hash, assoc); + + element = (pm_node_t *) hash; + if (accept1(parser, PM_TOKEN_COMMA) && !match1(parser, PM_TOKEN_BRACKET_RIGHT)) { + parse_assocs(parser, &hash_keys, element, (uint16_t) (depth + 1)); + } + + pm_static_literals_free(&hash_keys); + parsed_bare_hash = true; + } + } + + pm_array_node_elements_append(array, element); + if (PM_NODE_TYPE_P(element, PM_MISSING_NODE)) break; + } + + accept1(parser, PM_TOKEN_NEWLINE); + + if (!accept1(parser, PM_TOKEN_BRACKET_RIGHT)) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_ARRAY_TERM, pm_token_type_human(parser->current.type)); + parser->previous.start = parser->previous.end; + parser->previous.type = PM_TOKEN_MISSING; + } + + pm_array_node_close_set(array, &parser->previous); + pm_accepts_block_stack_pop(parser); + + return (pm_node_t *) array; + } + case PM_TOKEN_PARENTHESIS_LEFT: + case PM_TOKEN_PARENTHESIS_LEFT_PARENTHESES: { + pm_token_t opening = parser->current; + pm_node_flags_t flags = 0; + + pm_node_list_t current_block_exits = { 0 }; + pm_node_list_t *previous_block_exits = push_block_exits(parser, ¤t_block_exits); + + parser_lex(parser); + while (true) { + if (accept1(parser, PM_TOKEN_SEMICOLON)) { + flags |= PM_PARENTHESES_NODE_FLAGS_MULTIPLE_STATEMENTS; + } else if (!accept1(parser, PM_TOKEN_NEWLINE)) { + break; + } + } + + // If this is the end of the file or we match a right parenthesis, then + // we have an empty parentheses node, and we can immediately return. + if (match2(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_TOKEN_EOF)) { + expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_EXPECT_RPAREN); + + pop_block_exits(parser, previous_block_exits); + pm_node_list_free(¤t_block_exits); + + return (pm_node_t *) pm_parentheses_node_create(parser, &opening, NULL, &parser->previous, flags); + } + + // Otherwise, we're going to parse the first statement in the list + // of statements within the parentheses. + pm_accepts_block_stack_push(parser, true); + context_push(parser, PM_CONTEXT_PARENS); + pm_node_t *statement = parse_expression(parser, PM_BINDING_POWER_STATEMENT, true, false, PM_ERR_CANNOT_PARSE_EXPRESSION, (uint16_t) (depth + 1)); + context_pop(parser); + + // Determine if this statement is followed by a terminator. In the + // case of a single statement, this is fine. But in the case of + // multiple statements it's required. + bool terminator_found = false; + + if (accept1(parser, PM_TOKEN_SEMICOLON)) { + terminator_found = true; + flags |= PM_PARENTHESES_NODE_FLAGS_MULTIPLE_STATEMENTS; + } else if (accept1(parser, PM_TOKEN_NEWLINE)) { + terminator_found = true; + } + + if (terminator_found) { + while (true) { + if (accept1(parser, PM_TOKEN_SEMICOLON)) { + flags |= PM_PARENTHESES_NODE_FLAGS_MULTIPLE_STATEMENTS; + } else if (!accept1(parser, PM_TOKEN_NEWLINE)) { + break; + } + } + } + + // If we hit a right parenthesis, then we're done parsing the + // parentheses node, and we can check which kind of node we should + // return. + if (match1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) { + if (opening.type == PM_TOKEN_PARENTHESIS_LEFT_PARENTHESES) { + lex_state_set(parser, PM_LEX_STATE_ENDARG); + } + + parser_lex(parser); + pm_accepts_block_stack_pop(parser); + + pop_block_exits(parser, previous_block_exits); + pm_node_list_free(¤t_block_exits); + + if (PM_NODE_TYPE_P(statement, PM_MULTI_TARGET_NODE) || PM_NODE_TYPE_P(statement, PM_SPLAT_NODE)) { + // If we have a single statement and are ending on a right + // parenthesis, then we need to check if this is possibly a + // multiple target node. + pm_multi_target_node_t *multi_target; + + if (PM_NODE_TYPE_P(statement, PM_MULTI_TARGET_NODE) && ((pm_multi_target_node_t *) statement)->lparen_loc.start == NULL) { + multi_target = (pm_multi_target_node_t *) statement; + } else { + multi_target = pm_multi_target_node_create(parser); + pm_multi_target_node_targets_append(parser, multi_target, statement); + } + + pm_location_t lparen_loc = PM_LOCATION_TOKEN_VALUE(&opening); + pm_location_t rparen_loc = PM_LOCATION_TOKEN_VALUE(&parser->previous); + + multi_target->lparen_loc = lparen_loc; + multi_target->rparen_loc = rparen_loc; + multi_target->base.location.start = lparen_loc.start; + multi_target->base.location.end = rparen_loc.end; + + pm_node_t *result; + if (match1(parser, PM_TOKEN_COMMA) && (binding_power == PM_BINDING_POWER_STATEMENT)) { + result = parse_targets(parser, (pm_node_t *) multi_target, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1)); + accept1(parser, PM_TOKEN_NEWLINE); + } else { + result = (pm_node_t *) multi_target; + } + + if (context_p(parser, PM_CONTEXT_MULTI_TARGET)) { + // All set, this is explicitly allowed by the parent + // context. + } else if (context_p(parser, PM_CONTEXT_FOR_INDEX) && match1(parser, PM_TOKEN_KEYWORD_IN)) { + // All set, we're inside a for loop and we're parsing + // multiple targets. + } else if (binding_power != PM_BINDING_POWER_STATEMENT) { + // Multi targets are not allowed when it's not a + // statement level. + pm_parser_err_node(parser, result, PM_ERR_WRITE_TARGET_UNEXPECTED); + } else if (!match2(parser, PM_TOKEN_EQUAL, PM_TOKEN_PARENTHESIS_RIGHT)) { + // Multi targets must be followed by an equal sign in + // order to be valid (or a right parenthesis if they are + // nested). + pm_parser_err_node(parser, result, PM_ERR_WRITE_TARGET_UNEXPECTED); + } + + return result; + } + + // If we have a single statement and are ending on a right parenthesis + // and we didn't return a multiple assignment node, then we can return a + // regular parentheses node now. + pm_statements_node_t *statements = pm_statements_node_create(parser); + pm_statements_node_body_append(parser, statements, statement, true); + + return (pm_node_t *) pm_parentheses_node_create(parser, &opening, (pm_node_t *) statements, &parser->previous, flags); + } + + // If we have more than one statement in the set of parentheses, + // then we are going to parse all of them as a list of statements. + // We'll do that here. + context_push(parser, PM_CONTEXT_PARENS); + flags |= PM_PARENTHESES_NODE_FLAGS_MULTIPLE_STATEMENTS; + + pm_statements_node_t *statements = pm_statements_node_create(parser); + pm_statements_node_body_append(parser, statements, statement, true); + + // If we didn't find a terminator and we didn't find a right + // parenthesis, then this is a syntax error. + if (!terminator_found && !match1(parser, PM_TOKEN_EOF)) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_EXPECT_EOL_AFTER_STATEMENT, pm_token_type_human(parser->current.type)); + } + + // Parse each statement within the parentheses. + while (true) { + pm_node_t *node = parse_expression(parser, PM_BINDING_POWER_STATEMENT, true, false, PM_ERR_CANNOT_PARSE_EXPRESSION, (uint16_t) (depth + 1)); + pm_statements_node_body_append(parser, statements, node, true); + + // If we're recovering from a syntax error, then we need to stop + // parsing the statements now. + if (parser->recovering) { + // If this is the level of context where the recovery has + // happened, then we can mark the parser as done recovering. + if (match1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) parser->recovering = false; + break; + } + + // If we couldn't parse an expression at all, then we need to + // bail out of the loop. + if (PM_NODE_TYPE_P(node, PM_MISSING_NODE)) break; + + // If we successfully parsed a statement, then we are going to + // need terminator to delimit them. + if (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)) { + while (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)); + if (match1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) break; + } else if (match1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) { + break; + } else if (!match1(parser, PM_TOKEN_EOF)) { + // If we're at the end of the file, then we're going to add + // an error after this for the ) anyway. + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_EXPECT_EOL_AFTER_STATEMENT, pm_token_type_human(parser->current.type)); + } + } + + context_pop(parser); + pm_accepts_block_stack_pop(parser); + expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_EXPECT_RPAREN); + + // When we're parsing multi targets, we allow them to be followed by + // a right parenthesis if they are at the statement level. This is + // only possible if they are the final statement in a parentheses. + // We need to explicitly reject that here. + { + pm_node_t *statement = statements->body.nodes[statements->body.size - 1]; + + if (PM_NODE_TYPE_P(statement, PM_SPLAT_NODE)) { + pm_multi_target_node_t *multi_target = pm_multi_target_node_create(parser); + pm_multi_target_node_targets_append(parser, multi_target, statement); + + statement = (pm_node_t *) multi_target; + statements->body.nodes[statements->body.size - 1] = statement; + } + + if (PM_NODE_TYPE_P(statement, PM_MULTI_TARGET_NODE)) { + const uint8_t *offset = statement->location.end; + pm_token_t operator = { .type = PM_TOKEN_EQUAL, .start = offset, .end = offset }; + pm_node_t *value = (pm_node_t *) pm_missing_node_create(parser, offset, offset); + + statement = (pm_node_t *) pm_multi_write_node_create(parser, (pm_multi_target_node_t *) statement, &operator, value); + statements->body.nodes[statements->body.size - 1] = statement; + + pm_parser_err_node(parser, statement, PM_ERR_WRITE_TARGET_UNEXPECTED); + } + } + + pop_block_exits(parser, previous_block_exits); + pm_node_list_free(¤t_block_exits); + + pm_void_statements_check(parser, statements, true); + return (pm_node_t *) pm_parentheses_node_create(parser, &opening, (pm_node_t *) statements, &parser->previous, flags); + } + case PM_TOKEN_BRACE_LEFT: { + // If we were passed a current_hash_keys via the parser, then that + // means we're already parsing a hash and we want to share the set + // of hash keys with this inner hash we're about to parse for the + // sake of warnings. We'll set it to NULL after we grab it to make + // sure subsequent expressions don't use it. Effectively this is a + // way of getting around passing it to every call to + // parse_expression. + pm_static_literals_t *current_hash_keys = parser->current_hash_keys; + parser->current_hash_keys = NULL; + + pm_accepts_block_stack_push(parser, true); + parser_lex(parser); + + pm_hash_node_t *node = pm_hash_node_create(parser, &parser->previous); + + if (!match2(parser, PM_TOKEN_BRACE_RIGHT, PM_TOKEN_EOF)) { + if (current_hash_keys != NULL) { + parse_assocs(parser, current_hash_keys, (pm_node_t *) node, (uint16_t) (depth + 1)); + } else { + pm_static_literals_t hash_keys = { 0 }; + parse_assocs(parser, &hash_keys, (pm_node_t *) node, (uint16_t) (depth + 1)); + pm_static_literals_free(&hash_keys); + } + + accept1(parser, PM_TOKEN_NEWLINE); + } + + pm_accepts_block_stack_pop(parser); + expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_HASH_TERM); + pm_hash_node_closing_loc_set(node, &parser->previous); + + return (pm_node_t *) node; + } + case PM_TOKEN_CHARACTER_LITERAL: { + parser_lex(parser); + + pm_token_t opening = parser->previous; + opening.type = PM_TOKEN_STRING_BEGIN; + opening.end = opening.start + 1; + + pm_token_t content = parser->previous; + content.type = PM_TOKEN_STRING_CONTENT; + content.start = content.start + 1; + + pm_token_t closing = not_provided(parser); + pm_node_t *node = (pm_node_t *) pm_string_node_create_current_string(parser, &opening, &content, &closing); + pm_node_flag_set(node, parse_unescaped_encoding(parser)); + + // Characters can be followed by strings in which case they are + // automatically concatenated. + if (match1(parser, PM_TOKEN_STRING_BEGIN)) { + return parse_strings(parser, node, false, (uint16_t) (depth + 1)); + } + + return node; + } + case PM_TOKEN_CLASS_VARIABLE: { + parser_lex(parser); + pm_node_t *node = (pm_node_t *) pm_class_variable_read_node_create(parser, &parser->previous); + + if (binding_power == PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_COMMA)) { + node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1)); + } + + return node; + } + case PM_TOKEN_CONSTANT: { + parser_lex(parser); + pm_token_t constant = parser->previous; + + // If a constant is immediately followed by parentheses, then this is in + // fact a method call, not a constant read. + if ( + match1(parser, PM_TOKEN_PARENTHESIS_LEFT) || + (accepts_command_call && (token_begins_expression_p(parser->current.type) || match3(parser, PM_TOKEN_UAMPERSAND, PM_TOKEN_USTAR, PM_TOKEN_USTAR_STAR))) || + (pm_accepts_block_stack_p(parser) && match1(parser, PM_TOKEN_KEYWORD_DO)) || + match1(parser, PM_TOKEN_BRACE_LEFT) + ) { + pm_arguments_t arguments = { 0 }; + parse_arguments_list(parser, &arguments, true, accepts_command_call, (uint16_t) (depth + 1)); + return (pm_node_t *) pm_call_node_fcall_create(parser, &constant, &arguments); + } + + pm_node_t *node = (pm_node_t *) pm_constant_read_node_create(parser, &parser->previous); + + if ((binding_power == PM_BINDING_POWER_STATEMENT) && match1(parser, PM_TOKEN_COMMA)) { + // If we get here, then we have a comma immediately following a + // constant, so we're going to parse this as a multiple assignment. + node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1)); + } + + return node; + } + case PM_TOKEN_UCOLON_COLON: { + parser_lex(parser); + pm_token_t delimiter = parser->previous; + + expect1(parser, PM_TOKEN_CONSTANT, PM_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT); + pm_node_t *node = (pm_node_t *) pm_constant_path_node_create(parser, NULL, &delimiter, &parser->previous); + + if ((binding_power == PM_BINDING_POWER_STATEMENT) && match1(parser, PM_TOKEN_COMMA)) { + node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1)); + } + + return node; + } + case PM_TOKEN_UDOT_DOT: + case PM_TOKEN_UDOT_DOT_DOT: { + pm_token_t operator = parser->current; + parser_lex(parser); + + pm_node_t *right = parse_expression(parser, pm_binding_powers[operator.type].left, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1)); + + // Unary .. and ... are special because these are non-associative + // operators that can also be unary operators. In this case we need + // to explicitly reject code that has a .. or ... that follows this + // expression. + if (match2(parser, PM_TOKEN_DOT_DOT, PM_TOKEN_DOT_DOT_DOT)) { + pm_parser_err_current(parser, PM_ERR_UNEXPECTED_RANGE_OPERATOR); + } + + return (pm_node_t *) pm_range_node_create(parser, NULL, &operator, right); + } + case PM_TOKEN_FLOAT: + parser_lex(parser); + return (pm_node_t *) pm_float_node_create(parser, &parser->previous); + case PM_TOKEN_FLOAT_IMAGINARY: + parser_lex(parser); + return (pm_node_t *) pm_float_node_imaginary_create(parser, &parser->previous); + case PM_TOKEN_FLOAT_RATIONAL: + parser_lex(parser); + return (pm_node_t *) pm_float_node_rational_create(parser, &parser->previous); + case PM_TOKEN_FLOAT_RATIONAL_IMAGINARY: + parser_lex(parser); + return (pm_node_t *) pm_float_node_rational_imaginary_create(parser, &parser->previous); + case PM_TOKEN_NUMBERED_REFERENCE: { + parser_lex(parser); + pm_node_t *node = (pm_node_t *) pm_numbered_reference_read_node_create(parser, &parser->previous); + + if (binding_power == PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_COMMA)) { + node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1)); + } + + return node; + } + case PM_TOKEN_GLOBAL_VARIABLE: { + parser_lex(parser); + pm_node_t *node = (pm_node_t *) pm_global_variable_read_node_create(parser, &parser->previous); + + if (binding_power == PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_COMMA)) { + node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1)); + } + + return node; + } + case PM_TOKEN_BACK_REFERENCE: { + parser_lex(parser); + pm_node_t *node = (pm_node_t *) pm_back_reference_read_node_create(parser, &parser->previous); + + if (binding_power == PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_COMMA)) { + node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1)); + } + + return node; + } + case PM_TOKEN_IDENTIFIER: + case PM_TOKEN_METHOD_NAME: { + parser_lex(parser); + pm_token_t identifier = parser->previous; + pm_node_t *node = parse_variable_call(parser); + + if (PM_NODE_TYPE_P(node, PM_CALL_NODE)) { + // If parse_variable_call returned with a call node, then we + // know the identifier is not in the local table. In that case + // we need to check if there are arguments following the + // identifier. + pm_call_node_t *call = (pm_call_node_t *) node; + pm_arguments_t arguments = { 0 }; + + if (parse_arguments_list(parser, &arguments, true, accepts_command_call, (uint16_t) (depth + 1))) { + // Since we found arguments, we need to turn off the + // variable call bit in the flags. + pm_node_flag_unset((pm_node_t *)call, PM_CALL_NODE_FLAGS_VARIABLE_CALL); + + call->opening_loc = arguments.opening_loc; + call->arguments = arguments.arguments; + call->closing_loc = arguments.closing_loc; + call->block = arguments.block; + + if (arguments.block != NULL) { + call->base.location.end = arguments.block->location.end; + } else if (arguments.closing_loc.start == NULL) { + if (arguments.arguments != NULL) { + call->base.location.end = arguments.arguments->base.location.end; + } else { + call->base.location.end = call->message_loc.end; + } + } else { + call->base.location.end = arguments.closing_loc.end; + } + } + } else { + // Otherwise, we know the identifier is in the local table. This + // can still be a method call if it is followed by arguments or + // a block, so we need to check for that here. + if ( + (accepts_command_call && (token_begins_expression_p(parser->current.type) || match3(parser, PM_TOKEN_UAMPERSAND, PM_TOKEN_USTAR, PM_TOKEN_USTAR_STAR))) || + (pm_accepts_block_stack_p(parser) && match1(parser, PM_TOKEN_KEYWORD_DO)) || + match1(parser, PM_TOKEN_BRACE_LEFT) + ) { + pm_arguments_t arguments = { 0 }; + parse_arguments_list(parser, &arguments, true, accepts_command_call, (uint16_t) (depth + 1)); + pm_call_node_t *fcall = pm_call_node_fcall_create(parser, &identifier, &arguments); + + if (PM_NODE_TYPE_P(node, PM_IT_LOCAL_VARIABLE_READ_NODE)) { + // If we're about to convert an 'it' implicit local + // variable read into a method call, we need to remove + // it from the list of implicit local variables. + parse_target_implicit_parameter(parser, node); + } else { + // Otherwise, we're about to convert a regular local + // variable read into a method call, in which case we + // need to indicate that this was not a read for the + // purposes of warnings. + assert(PM_NODE_TYPE_P(node, PM_LOCAL_VARIABLE_READ_NODE)); + + if (pm_token_is_numbered_parameter(identifier.start, identifier.end)) { + parse_target_implicit_parameter(parser, node); + } else { + pm_local_variable_read_node_t *cast = (pm_local_variable_read_node_t *) node; + pm_locals_unread(&pm_parser_scope_find(parser, cast->depth)->locals, cast->name); + } + } + + pm_node_destroy(parser, node); + return (pm_node_t *) fcall; + } + } + + if ((binding_power == PM_BINDING_POWER_STATEMENT) && match1(parser, PM_TOKEN_COMMA)) { + node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1)); + } + + return node; + } + case PM_TOKEN_HEREDOC_START: { + // Here we have found a heredoc. We'll parse it and add it to the + // list of strings. + assert(parser->lex_modes.current->mode == PM_LEX_HEREDOC); + pm_heredoc_lex_mode_t lex_mode = parser->lex_modes.current->as.heredoc.base; + + size_t common_whitespace = (size_t) -1; + parser->lex_modes.current->as.heredoc.common_whitespace = &common_whitespace; + + parser_lex(parser); + pm_token_t opening = parser->previous; + + pm_node_t *node; + pm_node_t *part; + + if (match2(parser, PM_TOKEN_HEREDOC_END, PM_TOKEN_EOF)) { + // If we get here, then we have an empty heredoc. We'll create + // an empty content token and return an empty string node. + expect1_heredoc_term(parser, lex_mode.ident_start, lex_mode.ident_length); + pm_token_t content = parse_strings_empty_content(parser->previous.start); + + if (lex_mode.quote == PM_HEREDOC_QUOTE_BACKTICK) { + node = (pm_node_t *) pm_xstring_node_create_unescaped(parser, &opening, &content, &parser->previous, &PM_STRING_EMPTY); + } else { + node = (pm_node_t *) pm_string_node_create_unescaped(parser, &opening, &content, &parser->previous, &PM_STRING_EMPTY); + } + + node->location.end = opening.end; + } else if ((part = parse_string_part(parser, (uint16_t) (depth + 1))) == NULL) { + // If we get here, then we tried to find something in the + // heredoc but couldn't actually parse anything, so we'll just + // return a missing node. + // + // parse_string_part handles its own errors, so there is no need + // for us to add one here. + node = (pm_node_t *) pm_missing_node_create(parser, parser->previous.start, parser->previous.end); + } else if (PM_NODE_TYPE_P(part, PM_STRING_NODE) && match2(parser, PM_TOKEN_HEREDOC_END, PM_TOKEN_EOF)) { + // If we get here, then the part that we parsed was plain string + // content and we're at the end of the heredoc, so we can return + // just a string node with the heredoc opening and closing as + // its opening and closing. + pm_node_flag_set(part, parse_unescaped_encoding(parser)); + pm_string_node_t *cast = (pm_string_node_t *) part; + + cast->opening_loc = PM_LOCATION_TOKEN_VALUE(&opening); + cast->closing_loc = PM_LOCATION_TOKEN_VALUE(&parser->current); + cast->base.location = cast->opening_loc; + + if (lex_mode.quote == PM_HEREDOC_QUOTE_BACKTICK) { + assert(sizeof(pm_string_node_t) == sizeof(pm_x_string_node_t)); + cast->base.type = PM_X_STRING_NODE; + } + + if (lex_mode.indent == PM_HEREDOC_INDENT_TILDE && (common_whitespace != (size_t) -1) && (common_whitespace != 0)) { + parse_heredoc_dedent_string(&cast->unescaped, common_whitespace); + } + + node = (pm_node_t *) cast; + expect1_heredoc_term(parser, lex_mode.ident_start, lex_mode.ident_length); + } else { + // If we get here, then we have multiple parts in the heredoc, + // so we'll need to create an interpolated string node to hold + // them all. + pm_node_list_t parts = { 0 }; + pm_node_list_append(&parts, part); + + while (!match2(parser, PM_TOKEN_HEREDOC_END, PM_TOKEN_EOF)) { + if ((part = parse_string_part(parser, (uint16_t) (depth + 1))) != NULL) { + pm_node_list_append(&parts, part); + } + } + + // Now that we have all of the parts, create the correct type of + // interpolated node. + if (lex_mode.quote == PM_HEREDOC_QUOTE_BACKTICK) { + pm_interpolated_x_string_node_t *cast = pm_interpolated_xstring_node_create(parser, &opening, &opening); + cast->parts = parts; + + expect1_heredoc_term(parser, lex_mode.ident_start, lex_mode.ident_length); + pm_interpolated_xstring_node_closing_set(cast, &parser->previous); + + cast->base.location = cast->opening_loc; + node = (pm_node_t *) cast; + } else { + pm_interpolated_string_node_t *cast = pm_interpolated_string_node_create(parser, &opening, &parts, &opening); + pm_node_list_free(&parts); + + expect1_heredoc_term(parser, lex_mode.ident_start, lex_mode.ident_length); + pm_interpolated_string_node_closing_set(cast, &parser->previous); + + cast->base.location = cast->opening_loc; + node = (pm_node_t *) cast; + } + + // If this is a heredoc that is indented with a ~, then we need + // to dedent each line by the common leading whitespace. + if (lex_mode.indent == PM_HEREDOC_INDENT_TILDE && (common_whitespace != (size_t) -1) && (common_whitespace != 0)) { + pm_node_list_t *nodes; + if (lex_mode.quote == PM_HEREDOC_QUOTE_BACKTICK) { + nodes = &((pm_interpolated_x_string_node_t *) node)->parts; + } else { + nodes = &((pm_interpolated_string_node_t *) node)->parts; + } + + parse_heredoc_dedent(parser, nodes, common_whitespace); + } + } + + if (match1(parser, PM_TOKEN_STRING_BEGIN)) { + return parse_strings(parser, node, false, (uint16_t) (depth + 1)); + } + + return node; + } + case PM_TOKEN_INSTANCE_VARIABLE: { + parser_lex(parser); + pm_node_t *node = (pm_node_t *) pm_instance_variable_read_node_create(parser, &parser->previous); + + if (binding_power == PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_COMMA)) { + node = parse_targets_validate(parser, node, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1)); + } + + return node; + } + case PM_TOKEN_INTEGER: { + pm_node_flags_t base = parser->integer_base; + parser_lex(parser); + return (pm_node_t *) pm_integer_node_create(parser, base, &parser->previous); + } + case PM_TOKEN_INTEGER_IMAGINARY: { + pm_node_flags_t base = parser->integer_base; + parser_lex(parser); + return (pm_node_t *) pm_integer_node_imaginary_create(parser, base, &parser->previous); + } + case PM_TOKEN_INTEGER_RATIONAL: { + pm_node_flags_t base = parser->integer_base; + parser_lex(parser); + return (pm_node_t *) pm_integer_node_rational_create(parser, base, &parser->previous); + } + case PM_TOKEN_INTEGER_RATIONAL_IMAGINARY: { + pm_node_flags_t base = parser->integer_base; + parser_lex(parser); + return (pm_node_t *) pm_integer_node_rational_imaginary_create(parser, base, &parser->previous); + } + case PM_TOKEN_KEYWORD___ENCODING__: + parser_lex(parser); + return (pm_node_t *) pm_source_encoding_node_create(parser, &parser->previous); + case PM_TOKEN_KEYWORD___FILE__: + parser_lex(parser); + return (pm_node_t *) pm_source_file_node_create(parser, &parser->previous); + case PM_TOKEN_KEYWORD___LINE__: + parser_lex(parser); + return (pm_node_t *) pm_source_line_node_create(parser, &parser->previous); + case PM_TOKEN_KEYWORD_ALIAS: { + if (binding_power != PM_BINDING_POWER_STATEMENT) { + pm_parser_err_current(parser, PM_ERR_STATEMENT_ALIAS); + } + + parser_lex(parser); + pm_token_t keyword = parser->previous; + + pm_node_t *new_name = parse_alias_argument(parser, true, (uint16_t) (depth + 1)); + pm_node_t *old_name = parse_alias_argument(parser, false, (uint16_t) (depth + 1)); + + switch (PM_NODE_TYPE(new_name)) { + case PM_BACK_REFERENCE_READ_NODE: + case PM_NUMBERED_REFERENCE_READ_NODE: + case PM_GLOBAL_VARIABLE_READ_NODE: { + if (PM_NODE_TYPE_P(old_name, PM_BACK_REFERENCE_READ_NODE) || PM_NODE_TYPE_P(old_name, PM_NUMBERED_REFERENCE_READ_NODE) || PM_NODE_TYPE_P(old_name, PM_GLOBAL_VARIABLE_READ_NODE)) { + if (PM_NODE_TYPE_P(old_name, PM_NUMBERED_REFERENCE_READ_NODE)) { + pm_parser_err_node(parser, old_name, PM_ERR_ALIAS_ARGUMENT_NUMBERED_REFERENCE); + } + } else { + pm_parser_err_node(parser, old_name, PM_ERR_ALIAS_ARGUMENT); + } + + return (pm_node_t *) pm_alias_global_variable_node_create(parser, &keyword, new_name, old_name); + } + case PM_SYMBOL_NODE: + case PM_INTERPOLATED_SYMBOL_NODE: { + if (!PM_NODE_TYPE_P(old_name, PM_SYMBOL_NODE) && !PM_NODE_TYPE_P(old_name, PM_INTERPOLATED_SYMBOL_NODE)) { + pm_parser_err_node(parser, old_name, PM_ERR_ALIAS_ARGUMENT); + } + } + PRISM_FALLTHROUGH + default: + return (pm_node_t *) pm_alias_method_node_create(parser, &keyword, new_name, old_name); + } + } + case PM_TOKEN_KEYWORD_CASE: { + size_t opening_newline_index = token_newline_index(parser); + parser_lex(parser); + + pm_token_t case_keyword = parser->previous; + pm_node_t *predicate = NULL; + + pm_node_list_t current_block_exits = { 0 }; + pm_node_list_t *previous_block_exits = push_block_exits(parser, ¤t_block_exits); + + if (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)) { + while (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)); + predicate = NULL; + } else if (match3(parser, PM_TOKEN_KEYWORD_WHEN, PM_TOKEN_KEYWORD_IN, PM_TOKEN_KEYWORD_END)) { + predicate = NULL; + } else if (!token_begins_expression_p(parser->current.type)) { + predicate = NULL; + } else { + predicate = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_CASE_EXPRESSION_AFTER_CASE, (uint16_t) (depth + 1)); + while (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)); + } + + if (match1(parser, PM_TOKEN_KEYWORD_END)) { + parser_warn_indentation_mismatch(parser, opening_newline_index, &case_keyword, false, false); + parser_lex(parser); + + pop_block_exits(parser, previous_block_exits); + pm_node_list_free(¤t_block_exits); + + pm_parser_err_token(parser, &case_keyword, PM_ERR_CASE_MISSING_CONDITIONS); + return (pm_node_t *) pm_case_node_create(parser, &case_keyword, predicate, &parser->previous); + } + + // At this point we can create a case node, though we don't yet know + // if it is a case-in or case-when node. + pm_token_t end_keyword = not_provided(parser); + pm_node_t *node; + + if (match1(parser, PM_TOKEN_KEYWORD_WHEN)) { + pm_case_node_t *case_node = pm_case_node_create(parser, &case_keyword, predicate, &end_keyword); + pm_static_literals_t literals = { 0 }; + + // At this point we've seen a when keyword, so we know this is a + // case-when node. We will continue to parse the when nodes + // until we hit the end of the list. + while (match1(parser, PM_TOKEN_KEYWORD_WHEN)) { + parser_warn_indentation_mismatch(parser, opening_newline_index, &case_keyword, false, true); + parser_lex(parser); + + pm_token_t when_keyword = parser->previous; + pm_when_node_t *when_node = pm_when_node_create(parser, &when_keyword); + + do { + if (accept1(parser, PM_TOKEN_USTAR)) { + pm_token_t operator = parser->previous; + pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR, (uint16_t) (depth + 1)); + + pm_splat_node_t *splat_node = pm_splat_node_create(parser, &operator, expression); + pm_when_node_conditions_append(when_node, (pm_node_t *) splat_node); + + if (PM_NODE_TYPE_P(expression, PM_MISSING_NODE)) break; + } else { + pm_node_t *condition = parse_value_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_CASE_EXPRESSION_AFTER_WHEN, (uint16_t) (depth + 1)); + pm_when_node_conditions_append(when_node, condition); + + // If we found a missing node, then this is a syntax + // error and we should stop looping. + if (PM_NODE_TYPE_P(condition, PM_MISSING_NODE)) break; + + // If this is a string node, then we need to mark it + // as frozen because when clause strings are frozen. + if (PM_NODE_TYPE_P(condition, PM_STRING_NODE)) { + pm_node_flag_set(condition, PM_STRING_FLAGS_FROZEN | PM_NODE_FLAG_STATIC_LITERAL); + } else if (PM_NODE_TYPE_P(condition, PM_SOURCE_FILE_NODE)) { + pm_node_flag_set(condition, PM_NODE_FLAG_STATIC_LITERAL); + } + + pm_when_clause_static_literals_add(parser, &literals, condition); + } + } while (accept1(parser, PM_TOKEN_COMMA)); + + if (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)) { + if (accept1(parser, PM_TOKEN_KEYWORD_THEN)) { + pm_when_node_then_keyword_loc_set(when_node, &parser->previous); + } + } else { + expect1(parser, PM_TOKEN_KEYWORD_THEN, PM_ERR_EXPECT_WHEN_DELIMITER); + pm_when_node_then_keyword_loc_set(when_node, &parser->previous); + } + + if (!match3(parser, PM_TOKEN_KEYWORD_WHEN, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_END)) { + pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_CASE_WHEN, (uint16_t) (depth + 1)); + if (statements != NULL) { + pm_when_node_statements_set(when_node, statements); + } + } + + pm_case_node_condition_append(case_node, (pm_node_t *) when_node); + } + + // If we didn't parse any conditions (in or when) then we need + // to indicate that we have an error. + if (case_node->conditions.size == 0) { + pm_parser_err_token(parser, &case_keyword, PM_ERR_CASE_MISSING_CONDITIONS); + } + + pm_static_literals_free(&literals); + node = (pm_node_t *) case_node; + } else { + pm_case_match_node_t *case_node = pm_case_match_node_create(parser, &case_keyword, predicate, &end_keyword); + + // If this is a case-match node (i.e., it is a pattern matching + // case statement) then we must have a predicate. + if (predicate == NULL) { + pm_parser_err_token(parser, &case_keyword, PM_ERR_CASE_MATCH_MISSING_PREDICATE); + } + + // At this point we expect that we're parsing a case-in node. We + // will continue to parse the in nodes until we hit the end of + // the list. + while (match1(parser, PM_TOKEN_KEYWORD_IN)) { + parser_warn_indentation_mismatch(parser, opening_newline_index, &case_keyword, false, true); + + bool previous_pattern_matching_newlines = parser->pattern_matching_newlines; + parser->pattern_matching_newlines = true; + + lex_state_set(parser, PM_LEX_STATE_BEG | PM_LEX_STATE_LABEL); + parser->command_start = false; + parser_lex(parser); + + pm_token_t in_keyword = parser->previous; + + pm_constant_id_list_t captures = { 0 }; + pm_node_t *pattern = parse_pattern(parser, &captures, PM_PARSE_PATTERN_TOP | PM_PARSE_PATTERN_MULTI, PM_ERR_PATTERN_EXPRESSION_AFTER_IN, (uint16_t) (depth + 1)); + + parser->pattern_matching_newlines = previous_pattern_matching_newlines; + pm_constant_id_list_free(&captures); + + // Since we're in the top-level of the case-in node we need + // to check for guard clauses in the form of `if` or + // `unless` statements. + if (accept1(parser, PM_TOKEN_KEYWORD_IF_MODIFIER)) { + pm_token_t keyword = parser->previous; + pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_CONDITIONAL_IF_PREDICATE, (uint16_t) (depth + 1)); + pattern = (pm_node_t *) pm_if_node_modifier_create(parser, pattern, &keyword, predicate); + } else if (accept1(parser, PM_TOKEN_KEYWORD_UNLESS_MODIFIER)) { + pm_token_t keyword = parser->previous; + pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_CONDITIONAL_UNLESS_PREDICATE, (uint16_t) (depth + 1)); + pattern = (pm_node_t *) pm_unless_node_modifier_create(parser, pattern, &keyword, predicate); + } + + // Now we need to check for the terminator of the in node's + // pattern. It can be a newline or semicolon optionally + // followed by a `then` keyword. + pm_token_t then_keyword; + if (accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)) { + if (accept1(parser, PM_TOKEN_KEYWORD_THEN)) { + then_keyword = parser->previous; + } else { + then_keyword = not_provided(parser); + } + } else { + expect1(parser, PM_TOKEN_KEYWORD_THEN, PM_ERR_EXPECT_IN_DELIMITER); + then_keyword = parser->previous; + } + + // Now we can actually parse the statements associated with + // the in node. + pm_statements_node_t *statements; + if (match3(parser, PM_TOKEN_KEYWORD_IN, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_END)) { + statements = NULL; + } else { + statements = parse_statements(parser, PM_CONTEXT_CASE_IN, (uint16_t) (depth + 1)); + } + + // Now that we have the full pattern and statements, we can + // create the node and attach it to the case node. + pm_node_t *condition = (pm_node_t *) pm_in_node_create(parser, pattern, statements, &in_keyword, &then_keyword); + pm_case_match_node_condition_append(case_node, condition); + } + + // If we didn't parse any conditions (in or when) then we need + // to indicate that we have an error. + if (case_node->conditions.size == 0) { + pm_parser_err_token(parser, &case_keyword, PM_ERR_CASE_MISSING_CONDITIONS); + } + + node = (pm_node_t *) case_node; + } + + accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON); + if (accept1(parser, PM_TOKEN_KEYWORD_ELSE)) { + pm_token_t else_keyword = parser->previous; + pm_else_node_t *else_node; + + if (!match1(parser, PM_TOKEN_KEYWORD_END)) { + else_node = pm_else_node_create(parser, &else_keyword, parse_statements(parser, PM_CONTEXT_ELSE, (uint16_t) (depth + 1)), &parser->current); + } else { + else_node = pm_else_node_create(parser, &else_keyword, NULL, &parser->current); + } + + if (PM_NODE_TYPE_P(node, PM_CASE_NODE)) { + pm_case_node_else_clause_set((pm_case_node_t *) node, else_node); + } else { + pm_case_match_node_else_clause_set((pm_case_match_node_t *) node, else_node); + } + } + + parser_warn_indentation_mismatch(parser, opening_newline_index, &case_keyword, false, false); + expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CASE_TERM); + + if (PM_NODE_TYPE_P(node, PM_CASE_NODE)) { + pm_case_node_end_keyword_loc_set((pm_case_node_t *) node, &parser->previous); + } else { + pm_case_match_node_end_keyword_loc_set((pm_case_match_node_t *) node, &parser->previous); + } + + pop_block_exits(parser, previous_block_exits); + pm_node_list_free(¤t_block_exits); + + return node; + } + case PM_TOKEN_KEYWORD_BEGIN: { + size_t opening_newline_index = token_newline_index(parser); + parser_lex(parser); + + pm_token_t begin_keyword = parser->previous; + accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON); + + pm_node_list_t current_block_exits = { 0 }; + pm_node_list_t *previous_block_exits = push_block_exits(parser, ¤t_block_exits); + pm_statements_node_t *begin_statements = NULL; + + if (!match4(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_END)) { + pm_accepts_block_stack_push(parser, true); + begin_statements = parse_statements(parser, PM_CONTEXT_BEGIN, (uint16_t) (depth + 1)); + pm_accepts_block_stack_pop(parser); + accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON); + } + + pm_begin_node_t *begin_node = pm_begin_node_create(parser, &begin_keyword, begin_statements); + parse_rescues(parser, opening_newline_index, &begin_keyword, begin_node, PM_RESCUES_BEGIN, (uint16_t) (depth + 1)); + expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_BEGIN_TERM); + + begin_node->base.location.end = parser->previous.end; + pm_begin_node_end_keyword_set(begin_node, &parser->previous); + + pop_block_exits(parser, previous_block_exits); + pm_node_list_free(¤t_block_exits); + + return (pm_node_t *) begin_node; + } + case PM_TOKEN_KEYWORD_BEGIN_UPCASE: { + pm_node_list_t current_block_exits = { 0 }; + pm_node_list_t *previous_block_exits = push_block_exits(parser, ¤t_block_exits); + + if (binding_power != PM_BINDING_POWER_STATEMENT) { + pm_parser_err_current(parser, PM_ERR_STATEMENT_PREEXE_BEGIN); + } + + parser_lex(parser); + pm_token_t keyword = parser->previous; + + expect1(parser, PM_TOKEN_BRACE_LEFT, PM_ERR_BEGIN_UPCASE_BRACE); + pm_token_t opening = parser->previous; + pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_PREEXE, (uint16_t) (depth + 1)); + + expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_BEGIN_UPCASE_TERM); + pm_context_t context = parser->current_context->context; + if ((context != PM_CONTEXT_MAIN) && (context != PM_CONTEXT_PREEXE)) { + pm_parser_err_token(parser, &keyword, PM_ERR_BEGIN_UPCASE_TOPLEVEL); + } + + flush_block_exits(parser, previous_block_exits); + pm_node_list_free(¤t_block_exits); + + return (pm_node_t *) pm_pre_execution_node_create(parser, &keyword, &opening, statements, &parser->previous); + } + case PM_TOKEN_KEYWORD_BREAK: + case PM_TOKEN_KEYWORD_NEXT: + case PM_TOKEN_KEYWORD_RETURN: { + parser_lex(parser); + + pm_token_t keyword = parser->previous; + pm_arguments_t arguments = { 0 }; + + if ( + token_begins_expression_p(parser->current.type) || + match2(parser, PM_TOKEN_USTAR, PM_TOKEN_USTAR_STAR) + ) { + pm_binding_power_t binding_power = pm_binding_powers[parser->current.type].left; + + if (binding_power == PM_BINDING_POWER_UNSET || binding_power >= PM_BINDING_POWER_RANGE) { + parse_arguments(parser, &arguments, false, PM_TOKEN_EOF, (uint16_t) (depth + 1)); + } + } + + switch (keyword.type) { + case PM_TOKEN_KEYWORD_BREAK: { + pm_node_t *node = (pm_node_t *) pm_break_node_create(parser, &keyword, arguments.arguments); + if (!parser->partial_script) parse_block_exit(parser, node); + return node; + } + case PM_TOKEN_KEYWORD_NEXT: { + pm_node_t *node = (pm_node_t *) pm_next_node_create(parser, &keyword, arguments.arguments); + if (!parser->partial_script) parse_block_exit(parser, node); + return node; + } + case PM_TOKEN_KEYWORD_RETURN: { + pm_node_t *node = (pm_node_t *) pm_return_node_create(parser, &keyword, arguments.arguments); + parse_return(parser, node); + return node; + } + default: + assert(false && "unreachable"); + return (pm_node_t *) pm_missing_node_create(parser, parser->previous.start, parser->previous.end); + } + } + case PM_TOKEN_KEYWORD_SUPER: { + parser_lex(parser); + + pm_token_t keyword = parser->previous; + pm_arguments_t arguments = { 0 }; + parse_arguments_list(parser, &arguments, true, accepts_command_call, (uint16_t) (depth + 1)); + + if ( + arguments.opening_loc.start == NULL && + arguments.arguments == NULL && + ((arguments.block == NULL) || PM_NODE_TYPE_P(arguments.block, PM_BLOCK_NODE)) + ) { + return (pm_node_t *) pm_forwarding_super_node_create(parser, &keyword, &arguments); + } + + return (pm_node_t *) pm_super_node_create(parser, &keyword, &arguments); + } + case PM_TOKEN_KEYWORD_YIELD: { + parser_lex(parser); + + pm_token_t keyword = parser->previous; + pm_arguments_t arguments = { 0 }; + parse_arguments_list(parser, &arguments, false, accepts_command_call, (uint16_t) (depth + 1)); + + // It's possible that we've parsed a block argument through our + // call to parse_arguments_list. If we found one, we should mark it + // as invalid and destroy it, as we don't have a place for it on the + // yield node. + if (arguments.block != NULL) { + pm_parser_err_node(parser, arguments.block, PM_ERR_UNEXPECTED_BLOCK_ARGUMENT); + pm_node_destroy(parser, arguments.block); + arguments.block = NULL; + } + + pm_node_t *node = (pm_node_t *) pm_yield_node_create(parser, &keyword, &arguments.opening_loc, arguments.arguments, &arguments.closing_loc); + if (!parser->parsing_eval && !parser->partial_script) parse_yield(parser, node); + + return node; + } + case PM_TOKEN_KEYWORD_CLASS: { + size_t opening_newline_index = token_newline_index(parser); + parser_lex(parser); + + pm_token_t class_keyword = parser->previous; + pm_do_loop_stack_push(parser, false); + + pm_node_list_t current_block_exits = { 0 }; + pm_node_list_t *previous_block_exits = push_block_exits(parser, ¤t_block_exits); + + if (accept1(parser, PM_TOKEN_LESS_LESS)) { + pm_token_t operator = parser->previous; + pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_EXPECT_EXPRESSION_AFTER_LESS_LESS, (uint16_t) (depth + 1)); + + pm_parser_scope_push(parser, true); + if (!match2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON)) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_EXPECT_SINGLETON_CLASS_DELIMITER, pm_token_type_human(parser->current.type)); + } + + pm_node_t *statements = NULL; + if (!match4(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_END)) { + pm_accepts_block_stack_push(parser, true); + statements = (pm_node_t *) parse_statements(parser, PM_CONTEXT_SCLASS, (uint16_t) (depth + 1)); + pm_accepts_block_stack_pop(parser); + } + + if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) { + assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE)); + statements = (pm_node_t *) parse_rescues_implicit_begin(parser, opening_newline_index, &class_keyword, class_keyword.start, (pm_statements_node_t *) statements, PM_RESCUES_SCLASS, (uint16_t) (depth + 1)); + } else { + parser_warn_indentation_mismatch(parser, opening_newline_index, &class_keyword, false, false); + } + + expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CLASS_TERM); + + pm_constant_id_list_t locals; + pm_locals_order(parser, &parser->current_scope->locals, &locals, false); + + pm_parser_scope_pop(parser); + pm_do_loop_stack_pop(parser); + + flush_block_exits(parser, previous_block_exits); + pm_node_list_free(¤t_block_exits); + + return (pm_node_t *) pm_singleton_class_node_create(parser, &locals, &class_keyword, &operator, expression, statements, &parser->previous); + } + + pm_node_t *constant_path = parse_expression(parser, PM_BINDING_POWER_INDEX, false, false, PM_ERR_CLASS_NAME, (uint16_t) (depth + 1)); + pm_token_t name = parser->previous; + if (name.type != PM_TOKEN_CONSTANT) { + pm_parser_err_token(parser, &name, PM_ERR_CLASS_NAME); + } + + pm_token_t inheritance_operator; + pm_node_t *superclass; + + if (match1(parser, PM_TOKEN_LESS)) { + inheritance_operator = parser->current; + lex_state_set(parser, PM_LEX_STATE_BEG); + + parser->command_start = true; + parser_lex(parser); + + superclass = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_CLASS_SUPERCLASS, (uint16_t) (depth + 1)); + } else { + inheritance_operator = not_provided(parser); + superclass = NULL; + } + + pm_parser_scope_push(parser, true); + + if (inheritance_operator.type != PM_TOKEN_NOT_PROVIDED) { + expect2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON, PM_ERR_CLASS_UNEXPECTED_END); + } else { + accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON); + } + pm_node_t *statements = NULL; + + if (!match4(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_END)) { + pm_accepts_block_stack_push(parser, true); + statements = (pm_node_t *) parse_statements(parser, PM_CONTEXT_CLASS, (uint16_t) (depth + 1)); + pm_accepts_block_stack_pop(parser); + } + + if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) { + assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE)); + statements = (pm_node_t *) parse_rescues_implicit_begin(parser, opening_newline_index, &class_keyword, class_keyword.start, (pm_statements_node_t *) statements, PM_RESCUES_CLASS, (uint16_t) (depth + 1)); + } else { + parser_warn_indentation_mismatch(parser, opening_newline_index, &class_keyword, false, false); + } + + expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_CLASS_TERM); + + if (context_def_p(parser)) { + pm_parser_err_token(parser, &class_keyword, PM_ERR_CLASS_IN_METHOD); + } + + pm_constant_id_list_t locals; + pm_locals_order(parser, &parser->current_scope->locals, &locals, false); + + pm_parser_scope_pop(parser); + pm_do_loop_stack_pop(parser); + + if (!PM_NODE_TYPE_P(constant_path, PM_CONSTANT_PATH_NODE) && !(PM_NODE_TYPE_P(constant_path, PM_CONSTANT_READ_NODE))) { + pm_parser_err_node(parser, constant_path, PM_ERR_CLASS_NAME); + } + + pop_block_exits(parser, previous_block_exits); + pm_node_list_free(¤t_block_exits); + + return (pm_node_t *) pm_class_node_create(parser, &locals, &class_keyword, constant_path, &name, &inheritance_operator, superclass, statements, &parser->previous); + } + case PM_TOKEN_KEYWORD_DEF: { + pm_node_list_t current_block_exits = { 0 }; + pm_node_list_t *previous_block_exits = push_block_exits(parser, ¤t_block_exits); + + pm_token_t def_keyword = parser->current; + size_t opening_newline_index = token_newline_index(parser); + + pm_node_t *receiver = NULL; + pm_token_t operator = not_provided(parser); + pm_token_t name; + + // This context is necessary for lexing `...` in a bare params + // correctly. It must be pushed before lexing the first param, so it + // is here. + context_push(parser, PM_CONTEXT_DEF_PARAMS); + parser_lex(parser); + + // This will be false if the method name is not a valid identifier + // but could be followed by an operator. + bool valid_name = true; + + switch (parser->current.type) { + case PM_CASE_OPERATOR: + pm_parser_scope_push(parser, true); + lex_state_set(parser, PM_LEX_STATE_ENDFN); + parser_lex(parser); + + name = parser->previous; + break; + case PM_TOKEN_IDENTIFIER: { + parser_lex(parser); + + if (match2(parser, PM_TOKEN_DOT, PM_TOKEN_COLON_COLON)) { + receiver = parse_variable_call(parser); + + pm_parser_scope_push(parser, true); + lex_state_set(parser, PM_LEX_STATE_FNAME); + parser_lex(parser); + + operator = parser->previous; + name = parse_method_definition_name(parser); + } else { + pm_refute_numbered_parameter(parser, parser->previous.start, parser->previous.end); + pm_parser_scope_push(parser, true); + + name = parser->previous; + } + + break; + } + case PM_TOKEN_INSTANCE_VARIABLE: + case PM_TOKEN_CLASS_VARIABLE: + case PM_TOKEN_GLOBAL_VARIABLE: + valid_name = false; + PRISM_FALLTHROUGH + case PM_TOKEN_CONSTANT: + case PM_TOKEN_KEYWORD_NIL: + case PM_TOKEN_KEYWORD_SELF: + case PM_TOKEN_KEYWORD_TRUE: + case PM_TOKEN_KEYWORD_FALSE: + case PM_TOKEN_KEYWORD___FILE__: + case PM_TOKEN_KEYWORD___LINE__: + case PM_TOKEN_KEYWORD___ENCODING__: { + pm_parser_scope_push(parser, true); + parser_lex(parser); + + pm_token_t identifier = parser->previous; + + if (match2(parser, PM_TOKEN_DOT, PM_TOKEN_COLON_COLON)) { + lex_state_set(parser, PM_LEX_STATE_FNAME); + parser_lex(parser); + operator = parser->previous; + + switch (identifier.type) { + case PM_TOKEN_CONSTANT: + receiver = (pm_node_t *) pm_constant_read_node_create(parser, &identifier); + break; + case PM_TOKEN_INSTANCE_VARIABLE: + receiver = (pm_node_t *) pm_instance_variable_read_node_create(parser, &identifier); + break; + case PM_TOKEN_CLASS_VARIABLE: + receiver = (pm_node_t *) pm_class_variable_read_node_create(parser, &identifier); + break; + case PM_TOKEN_GLOBAL_VARIABLE: + receiver = (pm_node_t *) pm_global_variable_read_node_create(parser, &identifier); + break; + case PM_TOKEN_KEYWORD_NIL: + receiver = (pm_node_t *) pm_nil_node_create(parser, &identifier); + break; + case PM_TOKEN_KEYWORD_SELF: + receiver = (pm_node_t *) pm_self_node_create(parser, &identifier); + break; + case PM_TOKEN_KEYWORD_TRUE: + receiver = (pm_node_t *) pm_true_node_create(parser, &identifier); + break; + case PM_TOKEN_KEYWORD_FALSE: + receiver = (pm_node_t *) pm_false_node_create(parser, &identifier); + break; + case PM_TOKEN_KEYWORD___FILE__: + receiver = (pm_node_t *) pm_source_file_node_create(parser, &identifier); + break; + case PM_TOKEN_KEYWORD___LINE__: + receiver = (pm_node_t *) pm_source_line_node_create(parser, &identifier); + break; + case PM_TOKEN_KEYWORD___ENCODING__: + receiver = (pm_node_t *) pm_source_encoding_node_create(parser, &identifier); + break; + default: + break; + } + + name = parse_method_definition_name(parser); + } else { + if (!valid_name) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, identifier, PM_ERR_DEF_NAME, pm_token_type_human(identifier.type)); + } + + name = identifier; + } + break; + } + case PM_TOKEN_PARENTHESIS_LEFT: { + // The current context is `PM_CONTEXT_DEF_PARAMS`, however + // the inner expression of this parenthesis should not be + // processed under this context. Thus, the context is popped + // here. + context_pop(parser); + parser_lex(parser); + + pm_token_t lparen = parser->previous; + pm_node_t *expression = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_DEF_RECEIVER, (uint16_t) (depth + 1)); + + accept1(parser, PM_TOKEN_NEWLINE); + expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_EXPECT_RPAREN); + pm_token_t rparen = parser->previous; + + lex_state_set(parser, PM_LEX_STATE_FNAME); + expect2(parser, PM_TOKEN_DOT, PM_TOKEN_COLON_COLON, PM_ERR_DEF_RECEIVER_TERM); + + operator = parser->previous; + receiver = (pm_node_t *) pm_parentheses_node_create(parser, &lparen, expression, &rparen, 0); + + // To push `PM_CONTEXT_DEF_PARAMS` again is for the same + // reason as described the above. + pm_parser_scope_push(parser, true); + context_push(parser, PM_CONTEXT_DEF_PARAMS); + name = parse_method_definition_name(parser); + break; + } + default: + pm_parser_scope_push(parser, true); + name = parse_method_definition_name(parser); + break; + } + + pm_token_t lparen; + pm_token_t rparen; + pm_parameters_node_t *params; + + switch (parser->current.type) { + case PM_TOKEN_PARENTHESIS_LEFT: { + parser_lex(parser); + lparen = parser->previous; + + if (match1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) { + params = NULL; + } else { + params = parse_parameters(parser, PM_BINDING_POWER_DEFINED, true, false, true, true, false, (uint16_t) (depth + 1)); + } + + lex_state_set(parser, PM_LEX_STATE_BEG); + parser->command_start = true; + + context_pop(parser); + if (!accept1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_DEF_PARAMS_TERM_PAREN, pm_token_type_human(parser->current.type)); + parser->previous.start = parser->previous.end; + parser->previous.type = PM_TOKEN_MISSING; + } + + rparen = parser->previous; + break; + } + case PM_CASE_PARAMETER: { + // If we're about to lex a label, we need to add the label + // state to make sure the next newline is ignored. + if (parser->current.type == PM_TOKEN_LABEL) { + lex_state_set(parser, parser->lex_state | PM_LEX_STATE_LABEL); + } + + lparen = not_provided(parser); + rparen = not_provided(parser); + params = parse_parameters(parser, PM_BINDING_POWER_DEFINED, false, false, true, true, false, (uint16_t) (depth + 1)); + + context_pop(parser); + break; + } + default: { + lparen = not_provided(parser); + rparen = not_provided(parser); + params = NULL; + + context_pop(parser); + break; + } + } + + pm_node_t *statements = NULL; + pm_token_t equal; + pm_token_t end_keyword; + + if (accept1(parser, PM_TOKEN_EQUAL)) { + if (token_is_setter_name(&name)) { + pm_parser_err_token(parser, &name, PM_ERR_DEF_ENDLESS_SETTER); + } + equal = parser->previous; + + context_push(parser, PM_CONTEXT_DEF); + pm_do_loop_stack_push(parser, false); + statements = (pm_node_t *) pm_statements_node_create(parser); + + pm_node_t *statement = parse_expression(parser, PM_BINDING_POWER_DEFINED + 1, binding_power < PM_BINDING_POWER_COMPOSITION, false, PM_ERR_DEF_ENDLESS, (uint16_t) (depth + 1)); + + if (accept1(parser, PM_TOKEN_KEYWORD_RESCUE_MODIFIER)) { + context_push(parser, PM_CONTEXT_RESCUE_MODIFIER); + + pm_token_t rescue_keyword = parser->previous; + pm_node_t *value = parse_expression(parser, pm_binding_powers[PM_TOKEN_KEYWORD_RESCUE_MODIFIER].right, false, false, PM_ERR_RESCUE_MODIFIER_VALUE, (uint16_t) (depth + 1)); + context_pop(parser); + + statement = (pm_node_t *) pm_rescue_modifier_node_create(parser, statement, &rescue_keyword, value); + } + + pm_statements_node_body_append(parser, (pm_statements_node_t *) statements, statement, false); + pm_do_loop_stack_pop(parser); + context_pop(parser); + end_keyword = not_provided(parser); + } else { + equal = not_provided(parser); + + if (lparen.type == PM_TOKEN_NOT_PROVIDED) { + lex_state_set(parser, PM_LEX_STATE_BEG); + parser->command_start = true; + expect2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON, PM_ERR_DEF_PARAMS_TERM); + } else { + accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON); + } + + pm_accepts_block_stack_push(parser, true); + pm_do_loop_stack_push(parser, false); + + if (!match4(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_END)) { + pm_accepts_block_stack_push(parser, true); + statements = (pm_node_t *) parse_statements(parser, PM_CONTEXT_DEF, (uint16_t) (depth + 1)); + pm_accepts_block_stack_pop(parser); + } + + if (match3(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_KEYWORD_ELSE)) { + assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE)); + statements = (pm_node_t *) parse_rescues_implicit_begin(parser, opening_newline_index, &def_keyword, def_keyword.start, (pm_statements_node_t *) statements, PM_RESCUES_DEF, (uint16_t) (depth + 1)); + } else { + parser_warn_indentation_mismatch(parser, opening_newline_index, &def_keyword, false, false); + } + + pm_accepts_block_stack_pop(parser); + pm_do_loop_stack_pop(parser); + + expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_DEF_TERM); + end_keyword = parser->previous; + } + + pm_constant_id_list_t locals; + pm_locals_order(parser, &parser->current_scope->locals, &locals, false); + pm_parser_scope_pop(parser); + + /** + * If the final character is @. As is the case when defining + * methods to override the unary operators, we should ignore + * the @ in the same way we do for symbols. + */ + pm_constant_id_t name_id = pm_parser_constant_id_location(parser, name.start, parse_operator_symbol_name(&name)); + + flush_block_exits(parser, previous_block_exits); + pm_node_list_free(¤t_block_exits); + + return (pm_node_t *) pm_def_node_create( + parser, + name_id, + &name, + receiver, + params, + statements, + &locals, + &def_keyword, + &operator, + &lparen, + &rparen, + &equal, + &end_keyword + ); + } + case PM_TOKEN_KEYWORD_DEFINED: { + parser_lex(parser); + pm_token_t keyword = parser->previous; + + pm_token_t lparen; + pm_token_t rparen; + pm_node_t *expression; + context_push(parser, PM_CONTEXT_DEFINED); + + if (accept1(parser, PM_TOKEN_PARENTHESIS_LEFT)) { + lparen = parser->previous; + expression = parse_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_DEFINED_EXPRESSION, (uint16_t) (depth + 1)); + + if (parser->recovering) { + rparen = not_provided(parser); + } else { + accept1(parser, PM_TOKEN_NEWLINE); + expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_EXPECT_RPAREN); + rparen = parser->previous; + } + } else { + lparen = not_provided(parser); + rparen = not_provided(parser); + expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_DEFINED_EXPRESSION, (uint16_t) (depth + 1)); + } + + context_pop(parser); + return (pm_node_t *) pm_defined_node_create( + parser, + &lparen, + expression, + &rparen, + &PM_LOCATION_TOKEN_VALUE(&keyword) + ); + } + case PM_TOKEN_KEYWORD_END_UPCASE: { + if (binding_power != PM_BINDING_POWER_STATEMENT) { + pm_parser_err_current(parser, PM_ERR_STATEMENT_POSTEXE_END); + } + + parser_lex(parser); + pm_token_t keyword = parser->previous; + + if (context_def_p(parser)) { + pm_parser_warn_token(parser, &keyword, PM_WARN_END_IN_METHOD); + } + + expect1(parser, PM_TOKEN_BRACE_LEFT, PM_ERR_END_UPCASE_BRACE); + pm_token_t opening = parser->previous; + pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_POSTEXE, (uint16_t) (depth + 1)); + + expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_END_UPCASE_TERM); + return (pm_node_t *) pm_post_execution_node_create(parser, &keyword, &opening, statements, &parser->previous); + } + case PM_TOKEN_KEYWORD_FALSE: + parser_lex(parser); + return (pm_node_t *) pm_false_node_create(parser, &parser->previous); + case PM_TOKEN_KEYWORD_FOR: { + size_t opening_newline_index = token_newline_index(parser); + parser_lex(parser); + + pm_token_t for_keyword = parser->previous; + pm_node_t *index; + + context_push(parser, PM_CONTEXT_FOR_INDEX); + + // First, parse out the first index expression. + if (accept1(parser, PM_TOKEN_USTAR)) { + pm_token_t star_operator = parser->previous; + pm_node_t *name = NULL; + + if (token_begins_expression_p(parser->current.type)) { + name = parse_expression(parser, PM_BINDING_POWER_INDEX, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR, (uint16_t) (depth + 1)); + } + + index = (pm_node_t *) pm_splat_node_create(parser, &star_operator, name); + } else if (token_begins_expression_p(parser->current.type)) { + index = parse_expression(parser, PM_BINDING_POWER_INDEX, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_COMMA, (uint16_t) (depth + 1)); + } else { + pm_parser_err_token(parser, &for_keyword, PM_ERR_FOR_INDEX); + index = (pm_node_t *) pm_missing_node_create(parser, for_keyword.start, for_keyword.end); + } + + // Now, if there are multiple index expressions, parse them out. + if (match1(parser, PM_TOKEN_COMMA)) { + index = parse_targets(parser, index, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1)); + } else { + index = parse_target(parser, index, false, false); + } + + context_pop(parser); + pm_do_loop_stack_push(parser, true); + + expect1(parser, PM_TOKEN_KEYWORD_IN, PM_ERR_FOR_IN); + pm_token_t in_keyword = parser->previous; + + pm_node_t *collection = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_FOR_COLLECTION, (uint16_t) (depth + 1)); + pm_do_loop_stack_pop(parser); + + pm_token_t do_keyword; + if (accept1(parser, PM_TOKEN_KEYWORD_DO_LOOP)) { + do_keyword = parser->previous; + } else { + do_keyword = not_provided(parser); + if (!match2(parser, PM_TOKEN_SEMICOLON, PM_TOKEN_NEWLINE)) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_EXPECT_FOR_DELIMITER, pm_token_type_human(parser->current.type)); + } + } + + pm_statements_node_t *statements = NULL; + if (!match1(parser, PM_TOKEN_KEYWORD_END)) { + statements = parse_statements(parser, PM_CONTEXT_FOR, (uint16_t) (depth + 1)); + } + + parser_warn_indentation_mismatch(parser, opening_newline_index, &for_keyword, false, false); + expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_FOR_TERM); + + return (pm_node_t *) pm_for_node_create(parser, index, collection, statements, &for_keyword, &in_keyword, &do_keyword, &parser->previous); + } + case PM_TOKEN_KEYWORD_IF: + if (parser_end_of_line_p(parser)) { + PM_PARSER_WARN_TOKEN_FORMAT_CONTENT(parser, parser->current, PM_WARN_KEYWORD_EOL); + } + + size_t opening_newline_index = token_newline_index(parser); + bool if_after_else = parser->previous.type == PM_TOKEN_KEYWORD_ELSE; + parser_lex(parser); + + return parse_conditional(parser, PM_CONTEXT_IF, opening_newline_index, if_after_else, (uint16_t) (depth + 1)); + case PM_TOKEN_KEYWORD_UNDEF: { + if (binding_power != PM_BINDING_POWER_STATEMENT) { + pm_parser_err_current(parser, PM_ERR_STATEMENT_UNDEF); + } + + parser_lex(parser); + pm_undef_node_t *undef = pm_undef_node_create(parser, &parser->previous); + pm_node_t *name = parse_undef_argument(parser, (uint16_t) (depth + 1)); + + if (PM_NODE_TYPE_P(name, PM_MISSING_NODE)) { + pm_node_destroy(parser, name); + } else { + pm_undef_node_append(undef, name); + + while (match1(parser, PM_TOKEN_COMMA)) { + lex_state_set(parser, PM_LEX_STATE_FNAME | PM_LEX_STATE_FITEM); + parser_lex(parser); + name = parse_undef_argument(parser, (uint16_t) (depth + 1)); + + if (PM_NODE_TYPE_P(name, PM_MISSING_NODE)) { + pm_node_destroy(parser, name); + break; + } + + pm_undef_node_append(undef, name); + } + } + + return (pm_node_t *) undef; + } + case PM_TOKEN_KEYWORD_NOT: { + parser_lex(parser); + + pm_token_t message = parser->previous; + pm_arguments_t arguments = { 0 }; + pm_node_t *receiver = NULL; + + accept1(parser, PM_TOKEN_NEWLINE); + + if (accept1(parser, PM_TOKEN_PARENTHESIS_LEFT)) { + pm_token_t lparen = parser->previous; + + if (accept1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) { + receiver = (pm_node_t *) pm_parentheses_node_create(parser, &lparen, NULL, &parser->previous, 0); + } else { + arguments.opening_loc = PM_LOCATION_TOKEN_VALUE(&lparen); + receiver = parse_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_NOT_EXPRESSION, (uint16_t) (depth + 1)); + + if (!parser->recovering) { + accept1(parser, PM_TOKEN_NEWLINE); + expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_EXPECT_RPAREN); + arguments.closing_loc = PM_LOCATION_TOKEN_VALUE(&parser->previous); + } + } + } else { + receiver = parse_expression(parser, PM_BINDING_POWER_NOT, true, false, PM_ERR_NOT_EXPRESSION, (uint16_t) (depth + 1)); + } + + return (pm_node_t *) pm_call_node_not_create(parser, receiver, &message, &arguments); + } + case PM_TOKEN_KEYWORD_UNLESS: { + size_t opening_newline_index = token_newline_index(parser); + parser_lex(parser); + + return parse_conditional(parser, PM_CONTEXT_UNLESS, opening_newline_index, false, (uint16_t) (depth + 1)); + } + case PM_TOKEN_KEYWORD_MODULE: { + pm_node_list_t current_block_exits = { 0 }; + pm_node_list_t *previous_block_exits = push_block_exits(parser, ¤t_block_exits); + + size_t opening_newline_index = token_newline_index(parser); + parser_lex(parser); + pm_token_t module_keyword = parser->previous; + + pm_node_t *constant_path = parse_expression(parser, PM_BINDING_POWER_INDEX, false, false, PM_ERR_MODULE_NAME, (uint16_t) (depth + 1)); + pm_token_t name; + + // If we can recover from a syntax error that occurred while parsing + // the name of the module, then we'll handle that here. + if (PM_NODE_TYPE_P(constant_path, PM_MISSING_NODE)) { + pop_block_exits(parser, previous_block_exits); + pm_node_list_free(¤t_block_exits); + + pm_token_t missing = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end }; + return (pm_node_t *) pm_module_node_create(parser, NULL, &module_keyword, constant_path, &missing, NULL, &missing); + } + + while (accept1(parser, PM_TOKEN_COLON_COLON)) { + pm_token_t double_colon = parser->previous; + + expect1(parser, PM_TOKEN_CONSTANT, PM_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT); + constant_path = (pm_node_t *) pm_constant_path_node_create(parser, constant_path, &double_colon, &parser->previous); + } + + // Here we retrieve the name of the module. If it wasn't a constant, + // then it's possible that `module foo` was passed, which is a + // syntax error. We handle that here as well. + name = parser->previous; + if (name.type != PM_TOKEN_CONSTANT) { + pm_parser_err_token(parser, &name, PM_ERR_MODULE_NAME); + } + + pm_parser_scope_push(parser, true); + accept2(parser, PM_TOKEN_SEMICOLON, PM_TOKEN_NEWLINE); + pm_node_t *statements = NULL; + + if (!match4(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_KEYWORD_ELSE, PM_TOKEN_KEYWORD_END)) { + pm_accepts_block_stack_push(parser, true); + statements = (pm_node_t *) parse_statements(parser, PM_CONTEXT_MODULE, (uint16_t) (depth + 1)); + pm_accepts_block_stack_pop(parser); + } + + if (match3(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE, PM_TOKEN_KEYWORD_ELSE)) { + assert(statements == NULL || PM_NODE_TYPE_P(statements, PM_STATEMENTS_NODE)); + statements = (pm_node_t *) parse_rescues_implicit_begin(parser, opening_newline_index, &module_keyword, module_keyword.start, (pm_statements_node_t *) statements, PM_RESCUES_MODULE, (uint16_t) (depth + 1)); + } else { + parser_warn_indentation_mismatch(parser, opening_newline_index, &module_keyword, false, false); + } + + pm_constant_id_list_t locals; + pm_locals_order(parser, &parser->current_scope->locals, &locals, false); + + pm_parser_scope_pop(parser); + expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_MODULE_TERM); + + if (context_def_p(parser)) { + pm_parser_err_token(parser, &module_keyword, PM_ERR_MODULE_IN_METHOD); + } + + pop_block_exits(parser, previous_block_exits); + pm_node_list_free(¤t_block_exits); + + return (pm_node_t *) pm_module_node_create(parser, &locals, &module_keyword, constant_path, &name, statements, &parser->previous); + } + case PM_TOKEN_KEYWORD_NIL: + parser_lex(parser); + return (pm_node_t *) pm_nil_node_create(parser, &parser->previous); + case PM_TOKEN_KEYWORD_REDO: { + parser_lex(parser); + + pm_node_t *node = (pm_node_t *) pm_redo_node_create(parser, &parser->previous); + if (!parser->partial_script) parse_block_exit(parser, node); + + return node; + } + case PM_TOKEN_KEYWORD_RETRY: { + parser_lex(parser); + + pm_node_t *node = (pm_node_t *) pm_retry_node_create(parser, &parser->previous); + parse_retry(parser, node); + + return node; + } + case PM_TOKEN_KEYWORD_SELF: + parser_lex(parser); + return (pm_node_t *) pm_self_node_create(parser, &parser->previous); + case PM_TOKEN_KEYWORD_TRUE: + parser_lex(parser); + return (pm_node_t *) pm_true_node_create(parser, &parser->previous); + case PM_TOKEN_KEYWORD_UNTIL: { + size_t opening_newline_index = token_newline_index(parser); + + context_push(parser, PM_CONTEXT_LOOP_PREDICATE); + pm_do_loop_stack_push(parser, true); + + parser_lex(parser); + pm_token_t keyword = parser->previous; + pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_CONDITIONAL_UNTIL_PREDICATE, (uint16_t) (depth + 1)); + + pm_do_loop_stack_pop(parser); + context_pop(parser); + + pm_token_t do_keyword; + if (accept1(parser, PM_TOKEN_KEYWORD_DO_LOOP)) { + do_keyword = parser->previous; + } else { + do_keyword = not_provided(parser); + expect2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON, PM_ERR_CONDITIONAL_UNTIL_PREDICATE); + } + + pm_statements_node_t *statements = NULL; + if (!match1(parser, PM_TOKEN_KEYWORD_END)) { + pm_accepts_block_stack_push(parser, true); + statements = parse_statements(parser, PM_CONTEXT_UNTIL, (uint16_t) (depth + 1)); + pm_accepts_block_stack_pop(parser); + accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON); + } + + parser_warn_indentation_mismatch(parser, opening_newline_index, &keyword, false, false); + expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_UNTIL_TERM); + + return (pm_node_t *) pm_until_node_create(parser, &keyword, &do_keyword, &parser->previous, predicate, statements, 0); + } + case PM_TOKEN_KEYWORD_WHILE: { + size_t opening_newline_index = token_newline_index(parser); + + context_push(parser, PM_CONTEXT_LOOP_PREDICATE); + pm_do_loop_stack_push(parser, true); + + parser_lex(parser); + pm_token_t keyword = parser->previous; + pm_node_t *predicate = parse_value_expression(parser, PM_BINDING_POWER_COMPOSITION, true, false, PM_ERR_CONDITIONAL_WHILE_PREDICATE, (uint16_t) (depth + 1)); + + pm_do_loop_stack_pop(parser); + context_pop(parser); + + pm_token_t do_keyword; + if (accept1(parser, PM_TOKEN_KEYWORD_DO_LOOP)) { + do_keyword = parser->previous; + } else { + do_keyword = not_provided(parser); + expect2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON, PM_ERR_CONDITIONAL_WHILE_PREDICATE); + } + + pm_statements_node_t *statements = NULL; + if (!match1(parser, PM_TOKEN_KEYWORD_END)) { + pm_accepts_block_stack_push(parser, true); + statements = parse_statements(parser, PM_CONTEXT_WHILE, (uint16_t) (depth + 1)); + pm_accepts_block_stack_pop(parser); + accept2(parser, PM_TOKEN_NEWLINE, PM_TOKEN_SEMICOLON); + } + + parser_warn_indentation_mismatch(parser, opening_newline_index, &keyword, false, false); + expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_WHILE_TERM); + + return (pm_node_t *) pm_while_node_create(parser, &keyword, &do_keyword, &parser->previous, predicate, statements, 0); + } + case PM_TOKEN_PERCENT_LOWER_I: { + parser_lex(parser); + pm_token_t opening = parser->previous; + pm_array_node_t *array = pm_array_node_create(parser, &opening); + + while (!match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) { + accept1(parser, PM_TOKEN_WORDS_SEP); + if (match1(parser, PM_TOKEN_STRING_END)) break; + + if (match1(parser, PM_TOKEN_STRING_CONTENT)) { + pm_token_t opening = not_provided(parser); + pm_token_t closing = not_provided(parser); + pm_array_node_elements_append(array, (pm_node_t *) pm_symbol_node_create_current_string(parser, &opening, &parser->current, &closing)); + } + + expect1(parser, PM_TOKEN_STRING_CONTENT, PM_ERR_LIST_I_LOWER_ELEMENT); + } + + pm_token_t closing = parser->current; + if (match1(parser, PM_TOKEN_EOF)) { + pm_parser_err_token(parser, &opening, PM_ERR_LIST_I_LOWER_TERM); + closing = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end }; + } else { + expect1(parser, PM_TOKEN_STRING_END, PM_ERR_LIST_I_LOWER_TERM); + } + pm_array_node_close_set(array, &closing); + + return (pm_node_t *) array; + } + case PM_TOKEN_PERCENT_UPPER_I: { + parser_lex(parser); + pm_token_t opening = parser->previous; + pm_array_node_t *array = pm_array_node_create(parser, &opening); + + // This is the current node that we are parsing that will be added to the + // list of elements. + pm_node_t *current = NULL; + + while (!match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) { + switch (parser->current.type) { + case PM_TOKEN_WORDS_SEP: { + if (current == NULL) { + // If we hit a separator before we have any content, then we don't + // need to do anything. + } else { + // If we hit a separator after we've hit content, then we need to + // append that content to the list and reset the current node. + pm_array_node_elements_append(array, current); + current = NULL; + } + + parser_lex(parser); + break; + } + case PM_TOKEN_STRING_CONTENT: { + pm_token_t opening = not_provided(parser); + pm_token_t closing = not_provided(parser); + + if (current == NULL) { + // If we hit content and the current node is NULL, then this is + // the first string content we've seen. In that case we're going + // to create a new string node and set that to the current. + current = (pm_node_t *) pm_symbol_node_create_current_string(parser, &opening, &parser->current, &closing); + parser_lex(parser); + } else if (PM_NODE_TYPE_P(current, PM_INTERPOLATED_SYMBOL_NODE)) { + // If we hit string content and the current node is an + // interpolated string, then we need to append the string content + // to the list of child nodes. + pm_node_t *string = (pm_node_t *) pm_string_node_create_current_string(parser, &opening, &parser->current, &closing); + parser_lex(parser); + + pm_interpolated_symbol_node_append((pm_interpolated_symbol_node_t *) current, string); + } else if (PM_NODE_TYPE_P(current, PM_SYMBOL_NODE)) { + // If we hit string content and the current node is a symbol node, + // then we need to convert the current node into an interpolated + // string and add the string content to the list of child nodes. + pm_symbol_node_t *cast = (pm_symbol_node_t *) current; + pm_token_t bounds = not_provided(parser); + + pm_token_t content = { .type = PM_TOKEN_STRING_CONTENT, .start = cast->value_loc.start, .end = cast->value_loc.end }; + pm_node_t *first_string = (pm_node_t *) pm_string_node_create_unescaped(parser, &bounds, &content, &bounds, &cast->unescaped); + pm_node_t *second_string = (pm_node_t *) pm_string_node_create_current_string(parser, &opening, &parser->previous, &closing); + parser_lex(parser); + + pm_interpolated_symbol_node_t *interpolated = pm_interpolated_symbol_node_create(parser, &opening, NULL, &closing); + pm_interpolated_symbol_node_append(interpolated, first_string); + pm_interpolated_symbol_node_append(interpolated, second_string); + + xfree(current); + current = (pm_node_t *) interpolated; + } else { + assert(false && "unreachable"); + } + + break; + } + case PM_TOKEN_EMBVAR: { + bool start_location_set = false; + if (current == NULL) { + // If we hit an embedded variable and the current node is NULL, + // then this is the start of a new string. We'll set the current + // node to a new interpolated string. + pm_token_t opening = not_provided(parser); + pm_token_t closing = not_provided(parser); + current = (pm_node_t *) pm_interpolated_symbol_node_create(parser, &opening, NULL, &closing); + } else if (PM_NODE_TYPE_P(current, PM_SYMBOL_NODE)) { + // If we hit an embedded variable and the current node is a string + // node, then we'll convert the current into an interpolated + // string and add the string node to the list of parts. + pm_token_t opening = not_provided(parser); + pm_token_t closing = not_provided(parser); + pm_interpolated_symbol_node_t *interpolated = pm_interpolated_symbol_node_create(parser, &opening, NULL, &closing); + + current = (pm_node_t *) pm_symbol_node_to_string_node(parser, (pm_symbol_node_t *) current); + pm_interpolated_symbol_node_append(interpolated, current); + interpolated->base.location.start = current->location.start; + start_location_set = true; + current = (pm_node_t *) interpolated; + } else { + // If we hit an embedded variable and the current node is an + // interpolated string, then we'll just add the embedded variable. + } + + pm_node_t *part = parse_string_part(parser, (uint16_t) (depth + 1)); + pm_interpolated_symbol_node_append((pm_interpolated_symbol_node_t *) current, part); + if (!start_location_set) { + current->location.start = part->location.start; + } + break; + } + case PM_TOKEN_EMBEXPR_BEGIN: { + bool start_location_set = false; + if (current == NULL) { + // If we hit an embedded expression and the current node is NULL, + // then this is the start of a new string. We'll set the current + // node to a new interpolated string. + pm_token_t opening = not_provided(parser); + pm_token_t closing = not_provided(parser); + current = (pm_node_t *) pm_interpolated_symbol_node_create(parser, &opening, NULL, &closing); + } else if (PM_NODE_TYPE_P(current, PM_SYMBOL_NODE)) { + // If we hit an embedded expression and the current node is a + // string node, then we'll convert the current into an + // interpolated string and add the string node to the list of + // parts. + pm_token_t opening = not_provided(parser); + pm_token_t closing = not_provided(parser); + pm_interpolated_symbol_node_t *interpolated = pm_interpolated_symbol_node_create(parser, &opening, NULL, &closing); + + current = (pm_node_t *) pm_symbol_node_to_string_node(parser, (pm_symbol_node_t *) current); + pm_interpolated_symbol_node_append(interpolated, current); + interpolated->base.location.start = current->location.start; + start_location_set = true; + current = (pm_node_t *) interpolated; + } else if (PM_NODE_TYPE_P(current, PM_INTERPOLATED_SYMBOL_NODE)) { + // If we hit an embedded expression and the current node is an + // interpolated string, then we'll just continue on. + } else { + assert(false && "unreachable"); + } + + pm_node_t *part = parse_string_part(parser, (uint16_t) (depth + 1)); + pm_interpolated_symbol_node_append((pm_interpolated_symbol_node_t *) current, part); + if (!start_location_set) { + current->location.start = part->location.start; + } + break; + } + default: + expect1(parser, PM_TOKEN_STRING_CONTENT, PM_ERR_LIST_I_UPPER_ELEMENT); + parser_lex(parser); + break; + } + } + + // If we have a current node, then we need to append it to the list. + if (current) { + pm_array_node_elements_append(array, current); + } + + pm_token_t closing = parser->current; + if (match1(parser, PM_TOKEN_EOF)) { + pm_parser_err_token(parser, &opening, PM_ERR_LIST_I_UPPER_TERM); + closing = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end }; + } else { + expect1(parser, PM_TOKEN_STRING_END, PM_ERR_LIST_I_UPPER_TERM); + } + pm_array_node_close_set(array, &closing); + + return (pm_node_t *) array; + } + case PM_TOKEN_PERCENT_LOWER_W: { + parser_lex(parser); + pm_token_t opening = parser->previous; + pm_array_node_t *array = pm_array_node_create(parser, &opening); + + // skip all leading whitespaces + accept1(parser, PM_TOKEN_WORDS_SEP); + + while (!match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) { + accept1(parser, PM_TOKEN_WORDS_SEP); + if (match1(parser, PM_TOKEN_STRING_END)) break; + + if (match1(parser, PM_TOKEN_STRING_CONTENT)) { + pm_token_t opening = not_provided(parser); + pm_token_t closing = not_provided(parser); + + pm_node_t *string = (pm_node_t *) pm_string_node_create_current_string(parser, &opening, &parser->current, &closing); + pm_array_node_elements_append(array, string); + } + + expect1(parser, PM_TOKEN_STRING_CONTENT, PM_ERR_LIST_W_LOWER_ELEMENT); + } + + pm_token_t closing = parser->current; + if (match1(parser, PM_TOKEN_EOF)) { + pm_parser_err_token(parser, &opening, PM_ERR_LIST_W_LOWER_TERM); + closing = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end }; + } else { + expect1(parser, PM_TOKEN_STRING_END, PM_ERR_LIST_W_LOWER_TERM); + } + + pm_array_node_close_set(array, &closing); + return (pm_node_t *) array; + } + case PM_TOKEN_PERCENT_UPPER_W: { + parser_lex(parser); + pm_token_t opening = parser->previous; + pm_array_node_t *array = pm_array_node_create(parser, &opening); + + // This is the current node that we are parsing that will be added + // to the list of elements. + pm_node_t *current = NULL; + + while (!match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) { + switch (parser->current.type) { + case PM_TOKEN_WORDS_SEP: { + // Reset the explicit encoding if we hit a separator + // since each element can have its own encoding. + parser->explicit_encoding = NULL; + + if (current == NULL) { + // If we hit a separator before we have any content, + // then we don't need to do anything. + } else { + // If we hit a separator after we've hit content, + // then we need to append that content to the list + // and reset the current node. + pm_array_node_elements_append(array, current); + current = NULL; + } + + parser_lex(parser); + break; + } + case PM_TOKEN_STRING_CONTENT: { + pm_token_t opening = not_provided(parser); + pm_token_t closing = not_provided(parser); + + pm_node_t *string = (pm_node_t *) pm_string_node_create_current_string(parser, &opening, &parser->current, &closing); + pm_node_flag_set(string, parse_unescaped_encoding(parser)); + parser_lex(parser); + + if (current == NULL) { + // If we hit content and the current node is NULL, + // then this is the first string content we've seen. + // In that case we're going to create a new string + // node and set that to the current. + current = string; + } else if (PM_NODE_TYPE_P(current, PM_INTERPOLATED_STRING_NODE)) { + // If we hit string content and the current node is + // an interpolated string, then we need to append + // the string content to the list of child nodes. + pm_interpolated_string_node_append((pm_interpolated_string_node_t *) current, string); + } else if (PM_NODE_TYPE_P(current, PM_STRING_NODE)) { + // If we hit string content and the current node is + // a string node, then we need to convert the + // current node into an interpolated string and add + // the string content to the list of child nodes. + pm_interpolated_string_node_t *interpolated = pm_interpolated_string_node_create(parser, &opening, NULL, &closing); + pm_interpolated_string_node_append(interpolated, current); + pm_interpolated_string_node_append(interpolated, string); + current = (pm_node_t *) interpolated; + } else { + assert(false && "unreachable"); + } + + break; + } + case PM_TOKEN_EMBVAR: { + if (current == NULL) { + // If we hit an embedded variable and the current + // node is NULL, then this is the start of a new + // string. We'll set the current node to a new + // interpolated string. + pm_token_t opening = not_provided(parser); + pm_token_t closing = not_provided(parser); + current = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, NULL, &closing); + } else if (PM_NODE_TYPE_P(current, PM_STRING_NODE)) { + // If we hit an embedded variable and the current + // node is a string node, then we'll convert the + // current into an interpolated string and add the + // string node to the list of parts. + pm_token_t opening = not_provided(parser); + pm_token_t closing = not_provided(parser); + pm_interpolated_string_node_t *interpolated = pm_interpolated_string_node_create(parser, &opening, NULL, &closing); + pm_interpolated_string_node_append(interpolated, current); + current = (pm_node_t *) interpolated; + } else { + // If we hit an embedded variable and the current + // node is an interpolated string, then we'll just + // add the embedded variable. + } + + pm_node_t *part = parse_string_part(parser, (uint16_t) (depth + 1)); + pm_interpolated_string_node_append((pm_interpolated_string_node_t *) current, part); + break; + } + case PM_TOKEN_EMBEXPR_BEGIN: { + if (current == NULL) { + // If we hit an embedded expression and the current + // node is NULL, then this is the start of a new + // string. We'll set the current node to a new + // interpolated string. + pm_token_t opening = not_provided(parser); + pm_token_t closing = not_provided(parser); + current = (pm_node_t *) pm_interpolated_string_node_create(parser, &opening, NULL, &closing); + } else if (PM_NODE_TYPE_P(current, PM_STRING_NODE)) { + // If we hit an embedded expression and the current + // node is a string node, then we'll convert the + // current into an interpolated string and add the + // string node to the list of parts. + pm_token_t opening = not_provided(parser); + pm_token_t closing = not_provided(parser); + pm_interpolated_string_node_t *interpolated = pm_interpolated_string_node_create(parser, &opening, NULL, &closing); + pm_interpolated_string_node_append(interpolated, current); + current = (pm_node_t *) interpolated; + } else if (PM_NODE_TYPE_P(current, PM_INTERPOLATED_STRING_NODE)) { + // If we hit an embedded expression and the current + // node is an interpolated string, then we'll just + // continue on. + } else { + assert(false && "unreachable"); + } + + pm_node_t *part = parse_string_part(parser, (uint16_t) (depth + 1)); + pm_interpolated_string_node_append((pm_interpolated_string_node_t *) current, part); + break; + } + default: + expect1(parser, PM_TOKEN_STRING_CONTENT, PM_ERR_LIST_W_UPPER_ELEMENT); + parser_lex(parser); + break; + } + } + + // If we have a current node, then we need to append it to the list. + if (current) { + pm_array_node_elements_append(array, current); + } + + pm_token_t closing = parser->current; + if (match1(parser, PM_TOKEN_EOF)) { + pm_parser_err_token(parser, &opening, PM_ERR_LIST_W_UPPER_TERM); + closing = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end }; + } else { + expect1(parser, PM_TOKEN_STRING_END, PM_ERR_LIST_W_UPPER_TERM); + } + + pm_array_node_close_set(array, &closing); + return (pm_node_t *) array; + } + case PM_TOKEN_REGEXP_BEGIN: { + pm_token_t opening = parser->current; + parser_lex(parser); + + if (match1(parser, PM_TOKEN_REGEXP_END)) { + // If we get here, then we have an end immediately after a start. In + // that case we'll create an empty content token and return an + // uninterpolated regular expression. + pm_token_t content = (pm_token_t) { + .type = PM_TOKEN_STRING_CONTENT, + .start = parser->previous.end, + .end = parser->previous.end + }; + + parser_lex(parser); + + pm_node_t *node = (pm_node_t *) pm_regular_expression_node_create(parser, &opening, &content, &parser->previous); + pm_node_flag_set(node, PM_REGULAR_EXPRESSION_FLAGS_FORCED_US_ASCII_ENCODING); + + return node; + } + + pm_interpolated_regular_expression_node_t *interpolated; + + if (match1(parser, PM_TOKEN_STRING_CONTENT)) { + // In this case we've hit string content so we know the regular + // expression at least has something in it. We'll need to check if the + // following token is the end (in which case we can return a plain + // regular expression) or if it's not then it has interpolation. + pm_string_t unescaped = parser->current_string; + pm_token_t content = parser->current; + bool ascii_only = parser->current_regular_expression_ascii_only; + parser_lex(parser); + + // If we hit an end, then we can create a regular expression + // node without interpolation, which can be represented more + // succinctly and more easily compiled. + if (accept1(parser, PM_TOKEN_REGEXP_END)) { + pm_regular_expression_node_t *node = (pm_regular_expression_node_t *) pm_regular_expression_node_create_unescaped(parser, &opening, &content, &parser->previous, &unescaped); + + // If we're not immediately followed by a =~, then we want + // to parse all of the errors at this point. If it is + // followed by a =~, then it will get parsed higher up while + // parsing the named captures as well. + if (!match1(parser, PM_TOKEN_EQUAL_TILDE)) { + parse_regular_expression_errors(parser, node); + } + + pm_node_flag_set((pm_node_t *) node, parse_and_validate_regular_expression_encoding(parser, &unescaped, ascii_only, node->base.flags)); + return (pm_node_t *) node; + } + + // If we get here, then we have interpolation so we'll need to create + // a regular expression node with interpolation. + interpolated = pm_interpolated_regular_expression_node_create(parser, &opening); + + pm_token_t opening = not_provided(parser); + pm_token_t closing = not_provided(parser); + pm_node_t *part = (pm_node_t *) pm_string_node_create_unescaped(parser, &opening, &parser->previous, &closing, &unescaped); + + if (parser->encoding == PM_ENCODING_US_ASCII_ENTRY) { + // This is extremely strange, but the first string part of a + // regular expression will always be tagged as binary if we + // are in a US-ASCII file, no matter its contents. + pm_node_flag_set(part, PM_STRING_FLAGS_FORCED_BINARY_ENCODING); + } + + pm_interpolated_regular_expression_node_append(interpolated, part); + } else { + // If the first part of the body of the regular expression is not a + // string content, then we have interpolation and we need to create an + // interpolated regular expression node. + interpolated = pm_interpolated_regular_expression_node_create(parser, &opening); + } + + // Now that we're here and we have interpolation, we'll parse all of the + // parts into the list. + pm_node_t *part; + while (!match2(parser, PM_TOKEN_REGEXP_END, PM_TOKEN_EOF)) { + if ((part = parse_string_part(parser, (uint16_t) (depth + 1))) != NULL) { + pm_interpolated_regular_expression_node_append(interpolated, part); + } + } + + pm_token_t closing = parser->current; + if (match1(parser, PM_TOKEN_EOF)) { + pm_parser_err_token(parser, &opening, PM_ERR_REGEXP_TERM); + closing = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end }; + } else { + expect1(parser, PM_TOKEN_REGEXP_END, PM_ERR_REGEXP_TERM); + } + + pm_interpolated_regular_expression_node_closing_set(parser, interpolated, &closing); + return (pm_node_t *) interpolated; + } + case PM_TOKEN_BACKTICK: + case PM_TOKEN_PERCENT_LOWER_X: { + parser_lex(parser); + pm_token_t opening = parser->previous; + + // When we get here, we don't know if this string is going to have + // interpolation or not, even though it is allowed. Still, we want to be + // able to return a string node without interpolation if we can since + // it'll be faster. + if (match1(parser, PM_TOKEN_STRING_END)) { + // If we get here, then we have an end immediately after a start. In + // that case we'll create an empty content token and return an + // uninterpolated string. + pm_token_t content = (pm_token_t) { + .type = PM_TOKEN_STRING_CONTENT, + .start = parser->previous.end, + .end = parser->previous.end + }; + + parser_lex(parser); + return (pm_node_t *) pm_xstring_node_create(parser, &opening, &content, &parser->previous); + } + + pm_interpolated_x_string_node_t *node; + + if (match1(parser, PM_TOKEN_STRING_CONTENT)) { + // In this case we've hit string content so we know the string + // at least has something in it. We'll need to check if the + // following token is the end (in which case we can return a + // plain string) or if it's not then it has interpolation. + pm_string_t unescaped = parser->current_string; + pm_token_t content = parser->current; + parser_lex(parser); + + if (match1(parser, PM_TOKEN_STRING_END)) { + pm_node_t *node = (pm_node_t *) pm_xstring_node_create_unescaped(parser, &opening, &content, &parser->current, &unescaped); + pm_node_flag_set(node, parse_unescaped_encoding(parser)); + parser_lex(parser); + return node; + } + + // If we get here, then we have interpolation so we'll need to + // create a string node with interpolation. + node = pm_interpolated_xstring_node_create(parser, &opening, &opening); + + pm_token_t opening = not_provided(parser); + pm_token_t closing = not_provided(parser); + + pm_node_t *part = (pm_node_t *) pm_string_node_create_unescaped(parser, &opening, &parser->previous, &closing, &unescaped); + pm_node_flag_set(part, parse_unescaped_encoding(parser)); + + pm_interpolated_xstring_node_append(node, part); + } else { + // If the first part of the body of the string is not a string + // content, then we have interpolation and we need to create an + // interpolated string node. + node = pm_interpolated_xstring_node_create(parser, &opening, &opening); + } + + pm_node_t *part; + while (!match2(parser, PM_TOKEN_STRING_END, PM_TOKEN_EOF)) { + if ((part = parse_string_part(parser, (uint16_t) (depth + 1))) != NULL) { + pm_interpolated_xstring_node_append(node, part); + } + } + + pm_token_t closing = parser->current; + if (match1(parser, PM_TOKEN_EOF)) { + pm_parser_err_token(parser, &opening, PM_ERR_XSTRING_TERM); + closing = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end }; + } else { + expect1(parser, PM_TOKEN_STRING_END, PM_ERR_XSTRING_TERM); + } + pm_interpolated_xstring_node_closing_set(node, &closing); + + return (pm_node_t *) node; + } + case PM_TOKEN_USTAR: { + parser_lex(parser); + + // * operators at the beginning of expressions are only valid in the + // context of a multiple assignment. We enforce that here. We'll + // still lex past it though and create a missing node place. + if (binding_power != PM_BINDING_POWER_STATEMENT) { + pm_parser_err_prefix(parser, diag_id); + return (pm_node_t *) pm_missing_node_create(parser, parser->previous.start, parser->previous.end); + } + + pm_token_t operator = parser->previous; + pm_node_t *name = NULL; + + if (token_begins_expression_p(parser->current.type)) { + name = parse_expression(parser, PM_BINDING_POWER_INDEX, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_STAR, (uint16_t) (depth + 1)); + } + + pm_node_t *splat = (pm_node_t *) pm_splat_node_create(parser, &operator, name); + + if (match1(parser, PM_TOKEN_COMMA)) { + return parse_targets_validate(parser, splat, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1)); + } else { + return parse_target_validate(parser, splat, true); + } + } + case PM_TOKEN_BANG: { + if (binding_power > PM_BINDING_POWER_UNARY) { + pm_parser_err_prefix(parser, PM_ERR_UNARY_DISALLOWED); + } + + parser_lex(parser); + + pm_token_t operator = parser->previous; + pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, binding_power < PM_BINDING_POWER_MATCH, false, PM_ERR_UNARY_RECEIVER, (uint16_t) (depth + 1)); + pm_call_node_t *node = pm_call_node_unary_create(parser, &operator, receiver, "!"); + + pm_conditional_predicate(parser, receiver, PM_CONDITIONAL_PREDICATE_TYPE_NOT); + return (pm_node_t *) node; + } + case PM_TOKEN_TILDE: { + if (binding_power > PM_BINDING_POWER_UNARY) { + pm_parser_err_prefix(parser, PM_ERR_UNARY_DISALLOWED); + } + parser_lex(parser); + + pm_token_t operator = parser->previous; + pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, false, false, PM_ERR_UNARY_RECEIVER, (uint16_t) (depth + 1)); + pm_call_node_t *node = pm_call_node_unary_create(parser, &operator, receiver, "~"); + + return (pm_node_t *) node; + } + case PM_TOKEN_UMINUS: { + if (binding_power > PM_BINDING_POWER_UNARY) { + pm_parser_err_prefix(parser, PM_ERR_UNARY_DISALLOWED); + } + parser_lex(parser); + + pm_token_t operator = parser->previous; + pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, false, false, PM_ERR_UNARY_RECEIVER, (uint16_t) (depth + 1)); + pm_call_node_t *node = pm_call_node_unary_create(parser, &operator, receiver, "-@"); + + return (pm_node_t *) node; + } + case PM_TOKEN_UMINUS_NUM: { + parser_lex(parser); + + pm_token_t operator = parser->previous; + pm_node_t *node = parse_expression(parser, pm_binding_powers[parser->previous.type].right, false, false, PM_ERR_UNARY_RECEIVER, (uint16_t) (depth + 1)); + + if (accept1(parser, PM_TOKEN_STAR_STAR)) { + pm_token_t exponent_operator = parser->previous; + pm_node_t *exponent = parse_expression(parser, pm_binding_powers[exponent_operator.type].right, false, false, PM_ERR_EXPECT_ARGUMENT, (uint16_t) (depth + 1)); + node = (pm_node_t *) pm_call_node_binary_create(parser, node, &exponent_operator, exponent, 0); + node = (pm_node_t *) pm_call_node_unary_create(parser, &operator, node, "-@"); + } else { + switch (PM_NODE_TYPE(node)) { + case PM_INTEGER_NODE: + case PM_FLOAT_NODE: + case PM_RATIONAL_NODE: + case PM_IMAGINARY_NODE: + parse_negative_numeric(node); + break; + default: + node = (pm_node_t *) pm_call_node_unary_create(parser, &operator, node, "-@"); + break; + } + } + + return node; + } + case PM_TOKEN_MINUS_GREATER: { + int previous_lambda_enclosure_nesting = parser->lambda_enclosure_nesting; + parser->lambda_enclosure_nesting = parser->enclosure_nesting; + + size_t opening_newline_index = token_newline_index(parser); + pm_accepts_block_stack_push(parser, true); + parser_lex(parser); + + pm_token_t operator = parser->previous; + pm_parser_scope_push(parser, false); + + pm_block_parameters_node_t *block_parameters; + + switch (parser->current.type) { + case PM_TOKEN_PARENTHESIS_LEFT: { + pm_token_t opening = parser->current; + parser_lex(parser); + + if (match1(parser, PM_TOKEN_PARENTHESIS_RIGHT)) { + block_parameters = pm_block_parameters_node_create(parser, NULL, &opening); + } else { + block_parameters = parse_block_parameters(parser, false, &opening, true, true, (uint16_t) (depth + 1)); + } + + accept1(parser, PM_TOKEN_NEWLINE); + expect1(parser, PM_TOKEN_PARENTHESIS_RIGHT, PM_ERR_EXPECT_RPAREN); + + pm_block_parameters_node_closing_set(block_parameters, &parser->previous); + break; + } + case PM_CASE_PARAMETER: { + pm_accepts_block_stack_push(parser, false); + pm_token_t opening = not_provided(parser); + block_parameters = parse_block_parameters(parser, false, &opening, true, false, (uint16_t) (depth + 1)); + pm_accepts_block_stack_pop(parser); + break; + } + default: { + block_parameters = NULL; + break; + } + } + + pm_token_t opening; + pm_node_t *body = NULL; + parser->lambda_enclosure_nesting = previous_lambda_enclosure_nesting; + + if (accept1(parser, PM_TOKEN_LAMBDA_BEGIN)) { + opening = parser->previous; + + if (!match1(parser, PM_TOKEN_BRACE_RIGHT)) { + body = (pm_node_t *) parse_statements(parser, PM_CONTEXT_LAMBDA_BRACES, (uint16_t) (depth + 1)); + } + + parser_warn_indentation_mismatch(parser, opening_newline_index, &operator, false, false); + expect1(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_LAMBDA_TERM_BRACE); + } else { + expect1(parser, PM_TOKEN_KEYWORD_DO, PM_ERR_LAMBDA_OPEN); + opening = parser->previous; + + if (!match3(parser, PM_TOKEN_KEYWORD_END, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) { + pm_accepts_block_stack_push(parser, true); + body = (pm_node_t *) parse_statements(parser, PM_CONTEXT_LAMBDA_DO_END, (uint16_t) (depth + 1)); + pm_accepts_block_stack_pop(parser); + } + + if (match2(parser, PM_TOKEN_KEYWORD_RESCUE, PM_TOKEN_KEYWORD_ENSURE)) { + assert(body == NULL || PM_NODE_TYPE_P(body, PM_STATEMENTS_NODE)); + body = (pm_node_t *) parse_rescues_implicit_begin(parser, opening_newline_index, &operator, opening.start, (pm_statements_node_t *) body, PM_RESCUES_LAMBDA, (uint16_t) (depth + 1)); + } else { + parser_warn_indentation_mismatch(parser, opening_newline_index, &operator, false, false); + } + + expect1(parser, PM_TOKEN_KEYWORD_END, PM_ERR_LAMBDA_TERM_END); + } + + pm_constant_id_list_t locals; + pm_locals_order(parser, &parser->current_scope->locals, &locals, pm_parser_scope_toplevel_p(parser)); + pm_node_t *parameters = parse_blocklike_parameters(parser, (pm_node_t *) block_parameters, &operator, &parser->previous); + + pm_parser_scope_pop(parser); + pm_accepts_block_stack_pop(parser); + + return (pm_node_t *) pm_lambda_node_create(parser, &locals, &operator, &opening, &parser->previous, parameters, body); + } + case PM_TOKEN_UPLUS: { + if (binding_power > PM_BINDING_POWER_UNARY) { + pm_parser_err_prefix(parser, PM_ERR_UNARY_DISALLOWED); + } + parser_lex(parser); + + pm_token_t operator = parser->previous; + pm_node_t *receiver = parse_expression(parser, pm_binding_powers[parser->previous.type].right, false, false, PM_ERR_UNARY_RECEIVER, (uint16_t) (depth + 1)); + pm_call_node_t *node = pm_call_node_unary_create(parser, &operator, receiver, "+@"); + + return (pm_node_t *) node; + } + case PM_TOKEN_STRING_BEGIN: + return parse_strings(parser, NULL, accepts_label, (uint16_t) (depth + 1)); + case PM_TOKEN_SYMBOL_BEGIN: { + pm_lex_mode_t lex_mode = *parser->lex_modes.current; + parser_lex(parser); + + return parse_symbol(parser, &lex_mode, PM_LEX_STATE_END, (uint16_t) (depth + 1)); + } + default: { + pm_context_t recoverable = context_recoverable(parser, &parser->current); + + if (recoverable != PM_CONTEXT_NONE) { + parser->recovering = true; + + // If the given error is not the generic one, then we'll add it + // here because it will provide more context in addition to the + // recoverable error that we will also add. + if (diag_id != PM_ERR_CANNOT_PARSE_EXPRESSION) { + pm_parser_err_prefix(parser, diag_id); + } + + // If we get here, then we are assuming this token is closing a + // parent context, so we'll indicate that to the user so that + // they know how we behaved. + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_UNEXPECTED_TOKEN_CLOSE_CONTEXT, pm_token_type_human(parser->current.type), context_human(recoverable)); + } else if (diag_id == PM_ERR_CANNOT_PARSE_EXPRESSION) { + // We're going to make a special case here, because "cannot + // parse expression" is pretty generic, and we know here that we + // have an unexpected token. + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_UNEXPECTED_TOKEN_IGNORE, pm_token_type_human(parser->current.type)); + } else { + pm_parser_err_prefix(parser, diag_id); + } + + return (pm_node_t *) pm_missing_node_create(parser, parser->previous.start, parser->previous.end); + } + } +} + +/** + * Parse a value that is going to be written to some kind of variable or method + * call. We need to handle this separately because the rescue modifier is + * permitted on the end of the these expressions, which is a deviation from its + * normal binding power. + * + * Note that this will only be called after an operator write, as in &&=, ||=, + * or any of the binary operators that can be written to a variable. + */ +static pm_node_t * +parse_assignment_value(pm_parser_t *parser, pm_binding_power_t previous_binding_power, pm_binding_power_t binding_power, bool accepts_command_call, pm_diagnostic_id_t diag_id, uint16_t depth) { + pm_node_t *value = parse_value_expression(parser, binding_power, previous_binding_power == PM_BINDING_POWER_ASSIGNMENT ? accepts_command_call : previous_binding_power < PM_BINDING_POWER_MATCH, false, diag_id, (uint16_t) (depth + 1)); + + // Contradicting binding powers, the right-hand-side value of the assignment + // allows the `rescue` modifier. + if (match1(parser, PM_TOKEN_KEYWORD_RESCUE_MODIFIER)) { + context_push(parser, PM_CONTEXT_RESCUE_MODIFIER); + + pm_token_t rescue = parser->current; + parser_lex(parser); + + pm_node_t *right = parse_expression(parser, pm_binding_powers[PM_TOKEN_KEYWORD_RESCUE_MODIFIER].right, false, false, PM_ERR_RESCUE_MODIFIER_VALUE, (uint16_t) (depth + 1)); + context_pop(parser); + + return (pm_node_t *) pm_rescue_modifier_node_create(parser, value, &rescue, right); + } + + return value; +} + +/** + * When a local variable write node is the value being written in a different + * write, the local variable is considered "used". + */ +static void +parse_assignment_value_local(pm_parser_t *parser, const pm_node_t *node) { + switch (PM_NODE_TYPE(node)) { + case PM_BEGIN_NODE: { + const pm_begin_node_t *cast = (const pm_begin_node_t *) node; + if (cast->statements != NULL) parse_assignment_value_local(parser, (const pm_node_t *) cast->statements); + break; + } + case PM_LOCAL_VARIABLE_WRITE_NODE: { + const pm_local_variable_write_node_t *cast = (const pm_local_variable_write_node_t *) node; + pm_locals_read(&pm_parser_scope_find(parser, cast->depth)->locals, cast->name); + break; + } + case PM_PARENTHESES_NODE: { + const pm_parentheses_node_t *cast = (const pm_parentheses_node_t *) node; + if (cast->body != NULL) parse_assignment_value_local(parser, cast->body); + break; + } + case PM_STATEMENTS_NODE: { + const pm_statements_node_t *cast = (const pm_statements_node_t *) node; + const pm_node_t *statement; + + PM_NODE_LIST_FOREACH(&cast->body, index, statement) { + parse_assignment_value_local(parser, statement); + } + break; + } + default: + break; + } +} + +/** + * Parse the value (or values, through an implicit array) that is going to be + * written to some kind of variable or method call. We need to handle this + * separately because the rescue modifier is permitted on the end of the these + * expressions, which is a deviation from its normal binding power. + * + * Additionally, if the value is a local variable write node (e.g., a = a = 1), + * the "a" is marked as being used so the parser should not warn on it. + * + * Note that this will only be called after an = operator, as that is the only + * operator that allows multiple values after it. + */ +static pm_node_t * +parse_assignment_values(pm_parser_t *parser, pm_binding_power_t previous_binding_power, pm_binding_power_t binding_power, bool accepts_command_call, pm_diagnostic_id_t diag_id, uint16_t depth) { + bool permitted = true; + if (previous_binding_power != PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_USTAR)) permitted = false; + + pm_node_t *value = parse_starred_expression(parser, binding_power, previous_binding_power == PM_BINDING_POWER_ASSIGNMENT ? accepts_command_call : previous_binding_power < PM_BINDING_POWER_MATCH, diag_id, (uint16_t) (depth + 1)); + if (!permitted) pm_parser_err_node(parser, value, PM_ERR_UNEXPECTED_MULTI_WRITE); + + parse_assignment_value_local(parser, value); + bool single_value = true; + + if (previous_binding_power == PM_BINDING_POWER_STATEMENT && (PM_NODE_TYPE_P(value, PM_SPLAT_NODE) || match1(parser, PM_TOKEN_COMMA))) { + single_value = false; + + pm_token_t opening = not_provided(parser); + pm_array_node_t *array = pm_array_node_create(parser, &opening); + + pm_array_node_elements_append(array, value); + value = (pm_node_t *) array; + + while (accept1(parser, PM_TOKEN_COMMA)) { + pm_node_t *element = parse_starred_expression(parser, binding_power, false, PM_ERR_ARRAY_ELEMENT, (uint16_t) (depth + 1)); + + pm_array_node_elements_append(array, element); + if (PM_NODE_TYPE_P(element, PM_MISSING_NODE)) break; + + parse_assignment_value_local(parser, element); + } + } + + // Contradicting binding powers, the right-hand-side value of the assignment + // allows the `rescue` modifier. + if ((single_value || (binding_power == (PM_BINDING_POWER_MULTI_ASSIGNMENT + 1))) && match1(parser, PM_TOKEN_KEYWORD_RESCUE_MODIFIER)) { + context_push(parser, PM_CONTEXT_RESCUE_MODIFIER); + + pm_token_t rescue = parser->current; + parser_lex(parser); + + bool accepts_command_call_inner = false; + + // RHS can accept command call iff the value is a call with arguments + // but without parenthesis. + if (PM_NODE_TYPE_P(value, PM_CALL_NODE)) { + pm_call_node_t *call_node = (pm_call_node_t *) value; + if ((call_node->arguments != NULL) && (call_node->opening_loc.start == NULL)) { + accepts_command_call_inner = true; + } + } + + pm_node_t *right = parse_expression(parser, pm_binding_powers[PM_TOKEN_KEYWORD_RESCUE_MODIFIER].right, accepts_command_call_inner, false, PM_ERR_RESCUE_MODIFIER_VALUE, (uint16_t) (depth + 1)); + context_pop(parser); + + return (pm_node_t *) pm_rescue_modifier_node_create(parser, value, &rescue, right); + } + + return value; +} + +/** + * Ensure a call node that is about to become a call operator node does not + * have arguments or a block attached. If it does, then we'll need to add an + * error message and destroy the arguments/block. Ideally we would keep the node + * around so that consumers would still have access to it, but we don't have a + * great structure for that at the moment. + */ +static void +parse_call_operator_write(pm_parser_t *parser, pm_call_node_t *call_node, const pm_token_t *operator) { + if (call_node->arguments != NULL) { + pm_parser_err_token(parser, operator, PM_ERR_OPERATOR_WRITE_ARGUMENTS); + pm_node_destroy(parser, (pm_node_t *) call_node->arguments); + call_node->arguments = NULL; + } + + if (call_node->block != NULL) { + pm_parser_err_token(parser, operator, PM_ERR_OPERATOR_WRITE_BLOCK); + pm_node_destroy(parser, (pm_node_t *) call_node->block); + call_node->block = NULL; + } +} + +/** + * This struct is used to pass information between the regular expression parser + * and the named capture callback. + */ +typedef struct { + /** The parser that is parsing the regular expression. */ + pm_parser_t *parser; + + /** The call node wrapping the regular expression node. */ + pm_call_node_t *call; + + /** The match write node that is being created. */ + pm_match_write_node_t *match; + + /** The list of names that have been parsed. */ + pm_constant_id_list_t names; + + /** + * Whether the content of the regular expression is shared. This impacts + * whether or not we used owned constants or shared constants in the + * constant pool for the names of the captures. + */ + bool shared; +} parse_regular_expression_named_capture_data_t; + +static inline const uint8_t * +pm_named_capture_escape_hex(pm_buffer_t *unescaped, const uint8_t *cursor, const uint8_t *end) { + cursor++; + + if (cursor < end && pm_char_is_hexadecimal_digit(*cursor)) { + uint8_t value = escape_hexadecimal_digit(*cursor); + cursor++; + + if (cursor < end && pm_char_is_hexadecimal_digit(*cursor)) { + value = (uint8_t) ((value << 4) | escape_hexadecimal_digit(*cursor)); + cursor++; + } + + pm_buffer_append_byte(unescaped, value); + } else { + pm_buffer_append_string(unescaped, "\\x", 2); + } + + return cursor; +} + +static inline const uint8_t * +pm_named_capture_escape_octal(pm_buffer_t *unescaped, const uint8_t *cursor, const uint8_t *end) { + uint8_t value = (uint8_t) (*cursor - '0'); + cursor++; + + if (cursor < end && pm_char_is_octal_digit(*cursor)) { + value = ((uint8_t) (value << 3)) | ((uint8_t) (*cursor - '0')); + cursor++; + + if (cursor < end && pm_char_is_octal_digit(*cursor)) { + value = ((uint8_t) (value << 3)) | ((uint8_t) (*cursor - '0')); + cursor++; + } + } + + pm_buffer_append_byte(unescaped, value); + return cursor; +} + +static inline const uint8_t * +pm_named_capture_escape_unicode(pm_parser_t *parser, pm_buffer_t *unescaped, const uint8_t *cursor, const uint8_t *end) { + const uint8_t *start = cursor - 1; + cursor++; + + if (cursor >= end) { + pm_buffer_append_string(unescaped, "\\u", 2); + return cursor; + } + + if (*cursor != '{') { + size_t length = pm_strspn_hexadecimal_digit(cursor, MIN(end - cursor, 4)); + uint32_t value = escape_unicode(parser, cursor, length); + + if (!pm_buffer_append_unicode_codepoint(unescaped, value)) { + pm_buffer_append_string(unescaped, (const char *) start, (size_t) ((cursor + length) - start)); + } + + return cursor + length; + } + + cursor++; + for (;;) { + while (cursor < end && *cursor == ' ') cursor++; + + if (cursor >= end) break; + if (*cursor == '}') { + cursor++; + break; + } + + size_t length = pm_strspn_hexadecimal_digit(cursor, end - cursor); + uint32_t value = escape_unicode(parser, cursor, length); + + (void) pm_buffer_append_unicode_codepoint(unescaped, value); + cursor += length; + } + + return cursor; +} + +static void +pm_named_capture_escape(pm_parser_t *parser, pm_buffer_t *unescaped, const uint8_t *source, const size_t length, const uint8_t *cursor) { + const uint8_t *end = source + length; + pm_buffer_append_string(unescaped, (const char *) source, (size_t) (cursor - source)); + + for (;;) { + if (++cursor >= end) { + pm_buffer_append_byte(unescaped, '\\'); + return; + } + + switch (*cursor) { + case 'x': + cursor = pm_named_capture_escape_hex(unescaped, cursor, end); + break; + case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': + cursor = pm_named_capture_escape_octal(unescaped, cursor, end); + break; + case 'u': + cursor = pm_named_capture_escape_unicode(parser, unescaped, cursor, end); + break; + default: + pm_buffer_append_byte(unescaped, '\\'); + break; + } + + const uint8_t *next_cursor = pm_memchr(cursor, '\\', (size_t) (end - cursor), parser->encoding_changed, parser->encoding); + if (next_cursor == NULL) break; + + pm_buffer_append_string(unescaped, (const char *) cursor, (size_t) (next_cursor - cursor)); + cursor = next_cursor; + } + + pm_buffer_append_string(unescaped, (const char *) cursor, (size_t) (end - cursor)); +} + +/** + * This callback is called when the regular expression parser encounters a named + * capture group. + */ +static void +parse_regular_expression_named_capture(const pm_string_t *capture, void *data) { + parse_regular_expression_named_capture_data_t *callback_data = (parse_regular_expression_named_capture_data_t *) data; + + pm_parser_t *parser = callback_data->parser; + pm_call_node_t *call = callback_data->call; + pm_constant_id_list_t *names = &callback_data->names; + + const uint8_t *source = pm_string_source(capture); + size_t length = pm_string_length(capture); + pm_buffer_t unescaped = { 0 }; + + // First, we need to handle escapes within the name of the capture group. + // This is because regular expressions have three different representations + // in prism. The first is the plain source code. The second is the + // representation that will be sent to the regular expression engine, which + // is the value of the "unescaped" field. This is poorly named, because it + // actually still contains escapes, just a subset of them that the regular + // expression engine knows how to handle. The third representation is fully + // unescaped, which is what we need. + const uint8_t *cursor = pm_memchr(source, '\\', length, parser->encoding_changed, parser->encoding); + if (PRISM_UNLIKELY(cursor != NULL)) { + pm_named_capture_escape(parser, &unescaped, source, length, cursor); + source = (const uint8_t *) pm_buffer_value(&unescaped); + length = pm_buffer_length(&unescaped); + } + + pm_location_t location; + pm_constant_id_t name; + + // If the name of the capture group isn't a valid identifier, we do + // not add it to the local table. + if (!pm_slice_is_valid_local(parser, source, source + length)) { + pm_buffer_free(&unescaped); + return; + } + + if (callback_data->shared) { + // If the unescaped string is a slice of the source, then we can + // copy the names directly. The pointers will line up. + location = (pm_location_t) { .start = source, .end = source + length }; + name = pm_parser_constant_id_location(parser, location.start, location.end); + } else { + // Otherwise, the name is a slice of the malloc-ed owned string, + // in which case we need to copy it out into a new string. + location = (pm_location_t) { .start = call->receiver->location.start, .end = call->receiver->location.end }; + + void *memory = xmalloc(length); + if (memory == NULL) abort(); + + memcpy(memory, source, length); + name = pm_parser_constant_id_owned(parser, (uint8_t *) memory, length); + } + + // Add this name to the list of constants if it is valid, not duplicated, + // and not a keyword. + if (name != 0 && !pm_constant_id_list_includes(names, name)) { + pm_constant_id_list_append(names, name); + + int depth; + if ((depth = pm_parser_local_depth_constant_id(parser, name)) == -1) { + // If the local is not already a local but it is a keyword, then we + // do not want to add a capture for this. + if (pm_local_is_keyword((const char *) source, length)) { + pm_buffer_free(&unescaped); + return; + } + + // If the identifier is not already a local, then we will add it to + // the local table. + pm_parser_local_add(parser, name, location.start, location.end, 0); + } + + // Here we lazily create the MatchWriteNode since we know we're + // about to add a target. + if (callback_data->match == NULL) { + callback_data->match = pm_match_write_node_create(parser, call); + } + + // Next, create the local variable target and add it to the list of + // targets for the match. + pm_node_t *target = (pm_node_t *) pm_local_variable_target_node_create(parser, &location, name, depth == -1 ? 0 : (uint32_t) depth); + pm_node_list_append(&callback_data->match->targets, target); + } + + pm_buffer_free(&unescaped); +} + +/** + * Potentially change a =~ with a regular expression with named captures into a + * match write node. + */ +static pm_node_t * +parse_regular_expression_named_captures(pm_parser_t *parser, const pm_string_t *content, pm_call_node_t *call, bool extended_mode) { + parse_regular_expression_named_capture_data_t callback_data = { + .parser = parser, + .call = call, + .names = { 0 }, + .shared = content->type == PM_STRING_SHARED + }; + + parse_regular_expression_error_data_t error_data = { + .parser = parser, + .start = call->receiver->location.start, + .end = call->receiver->location.end, + .shared = content->type == PM_STRING_SHARED + }; + + pm_regexp_parse(parser, pm_string_source(content), pm_string_length(content), extended_mode, parse_regular_expression_named_capture, &callback_data, parse_regular_expression_error, &error_data); + pm_constant_id_list_free(&callback_data.names); + + if (callback_data.match != NULL) { + return (pm_node_t *) callback_data.match; + } else { + return (pm_node_t *) call; + } +} + +static inline pm_node_t * +parse_expression_infix(pm_parser_t *parser, pm_node_t *node, pm_binding_power_t previous_binding_power, pm_binding_power_t binding_power, bool accepts_command_call, uint16_t depth) { + pm_token_t token = parser->current; + + switch (token.type) { + case PM_TOKEN_EQUAL: { + switch (PM_NODE_TYPE(node)) { + case PM_CALL_NODE: { + // If we have no arguments to the call node and we need this + // to be a target then this is either a method call or a + // local variable write. This _must_ happen before the value + // is parsed because it could be referenced in the value. + pm_call_node_t *call_node = (pm_call_node_t *) node; + if (PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_VARIABLE_CALL)) { + pm_parser_local_add_location(parser, call_node->message_loc.start, call_node->message_loc.end, 0); + } + } + PRISM_FALLTHROUGH + case PM_CASE_WRITABLE: { + parser_lex(parser); + pm_node_t *value = parse_assignment_values(parser, previous_binding_power, PM_NODE_TYPE_P(node, PM_MULTI_TARGET_NODE) ? PM_BINDING_POWER_MULTI_ASSIGNMENT + 1 : binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_EQUAL, (uint16_t) (depth + 1)); + + if (PM_NODE_TYPE_P(node, PM_MULTI_TARGET_NODE) && previous_binding_power != PM_BINDING_POWER_STATEMENT) { + pm_parser_err_node(parser, node, PM_ERR_UNEXPECTED_MULTI_WRITE); + } + + return parse_write(parser, node, &token, value); + } + case PM_SPLAT_NODE: { + pm_multi_target_node_t *multi_target = pm_multi_target_node_create(parser); + pm_multi_target_node_targets_append(parser, multi_target, node); + + parser_lex(parser); + pm_node_t *value = parse_assignment_values(parser, previous_binding_power, PM_BINDING_POWER_MULTI_ASSIGNMENT + 1, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_EQUAL, (uint16_t) (depth + 1)); + return parse_write(parser, (pm_node_t *) multi_target, &token, value); + } + case PM_SOURCE_ENCODING_NODE: + case PM_FALSE_NODE: + case PM_SOURCE_FILE_NODE: + case PM_SOURCE_LINE_NODE: + case PM_NIL_NODE: + case PM_SELF_NODE: + case PM_TRUE_NODE: { + // In these special cases, we have specific error messages + // and we will replace them with local variable writes. + parser_lex(parser); + pm_node_t *value = parse_assignment_values(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_EQUAL, (uint16_t) (depth + 1)); + return parse_unwriteable_write(parser, node, &token, value); + } + default: + // In this case we have an = sign, but we don't know what + // it's for. We need to treat it as an error. We'll mark it + // as an error and skip past it. + parser_lex(parser); + pm_parser_err_token(parser, &token, PM_ERR_EXPRESSION_NOT_WRITABLE); + return node; + } + } + case PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL: { + switch (PM_NODE_TYPE(node)) { + case PM_BACK_REFERENCE_READ_NODE: + case PM_NUMBERED_REFERENCE_READ_NODE: + PM_PARSER_ERR_NODE_FORMAT_CONTENT(parser, node, PM_ERR_WRITE_TARGET_READONLY); + PRISM_FALLTHROUGH + case PM_GLOBAL_VARIABLE_READ_NODE: { + parser_lex(parser); + + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ, (uint16_t) (depth + 1)); + pm_node_t *result = (pm_node_t *) pm_global_variable_and_write_node_create(parser, node, &token, value); + + pm_node_destroy(parser, node); + return result; + } + case PM_CLASS_VARIABLE_READ_NODE: { + parser_lex(parser); + + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ, (uint16_t) (depth + 1)); + pm_node_t *result = (pm_node_t *) pm_class_variable_and_write_node_create(parser, (pm_class_variable_read_node_t *) node, &token, value); + + pm_node_destroy(parser, node); + return result; + } + case PM_CONSTANT_PATH_NODE: { + parser_lex(parser); + + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ, (uint16_t) (depth + 1)); + pm_node_t *write = (pm_node_t *) pm_constant_path_and_write_node_create(parser, (pm_constant_path_node_t *) node, &token, value); + + return parse_shareable_constant_write(parser, write); + } + case PM_CONSTANT_READ_NODE: { + parser_lex(parser); + + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ, (uint16_t) (depth + 1)); + pm_node_t *write = (pm_node_t *) pm_constant_and_write_node_create(parser, (pm_constant_read_node_t *) node, &token, value); + + pm_node_destroy(parser, node); + return parse_shareable_constant_write(parser, write); + } + case PM_INSTANCE_VARIABLE_READ_NODE: { + parser_lex(parser); + + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ, (uint16_t) (depth + 1)); + pm_node_t *result = (pm_node_t *) pm_instance_variable_and_write_node_create(parser, (pm_instance_variable_read_node_t *) node, &token, value); + + pm_node_destroy(parser, node); + return result; + } + case PM_IT_LOCAL_VARIABLE_READ_NODE: { + pm_constant_id_t name = pm_parser_local_add_constant(parser, "it", 2); + parser_lex(parser); + + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ, (uint16_t) (depth + 1)); + pm_node_t *result = (pm_node_t *) pm_local_variable_and_write_node_create(parser, node, &token, value, name, 0); + + parse_target_implicit_parameter(parser, node); + pm_node_destroy(parser, node); + return result; + } + case PM_LOCAL_VARIABLE_READ_NODE: { + if (pm_token_is_numbered_parameter(node->location.start, node->location.end)) { + PM_PARSER_ERR_FORMAT(parser, node->location.start, node->location.end, PM_ERR_PARAMETER_NUMBERED_RESERVED, node->location.start); + parse_target_implicit_parameter(parser, node); + } + + pm_local_variable_read_node_t *cast = (pm_local_variable_read_node_t *) node; + parser_lex(parser); + + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ, (uint16_t) (depth + 1)); + pm_node_t *result = (pm_node_t *) pm_local_variable_and_write_node_create(parser, node, &token, value, cast->name, cast->depth); + + pm_node_destroy(parser, node); + return result; + } + case PM_CALL_NODE: { + pm_call_node_t *cast = (pm_call_node_t *) node; + + // If we have a vcall (a method with no arguments and no + // receiver that could have been a local variable) then we + // will transform it into a local variable write. + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_VARIABLE_CALL)) { + pm_location_t *message_loc = &cast->message_loc; + pm_refute_numbered_parameter(parser, message_loc->start, message_loc->end); + + pm_constant_id_t constant_id = pm_parser_local_add_location(parser, message_loc->start, message_loc->end, 1); + parser_lex(parser); + + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ, (uint16_t) (depth + 1)); + pm_node_t *result = (pm_node_t *) pm_local_variable_and_write_node_create(parser, (pm_node_t *) cast, &token, value, constant_id, 0); + + pm_node_destroy(parser, (pm_node_t *) cast); + return result; + } + + // Move past the token here so that we have already added + // the local variable by this point. + parser_lex(parser); + + // If there is no call operator and the message is "[]" then + // this is an aref expression, and we can transform it into + // an aset expression. + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_INDEX)) { + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ, (uint16_t) (depth + 1)); + return (pm_node_t *) pm_index_and_write_node_create(parser, cast, &token, value); + } + + // If this node cannot be writable, then we have an error. + if (pm_call_node_writable_p(parser, cast)) { + parse_write_name(parser, &cast->name); + } else { + pm_parser_err_node(parser, node, PM_ERR_WRITE_TARGET_UNEXPECTED); + } + + parse_call_operator_write(parser, cast, &token); + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ, (uint16_t) (depth + 1)); + return (pm_node_t *) pm_call_and_write_node_create(parser, cast, &token, value); + } + case PM_MULTI_WRITE_NODE: { + parser_lex(parser); + pm_parser_err_token(parser, &token, PM_ERR_AMPAMPEQ_MULTI_ASSIGN); + return node; + } + default: + parser_lex(parser); + + // In this case we have an &&= sign, but we don't know what it's for. + // We need to treat it as an error. For now, we'll mark it as an error + // and just skip right past it. + pm_parser_err_token(parser, &token, PM_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ); + return node; + } + } + case PM_TOKEN_PIPE_PIPE_EQUAL: { + switch (PM_NODE_TYPE(node)) { + case PM_BACK_REFERENCE_READ_NODE: + case PM_NUMBERED_REFERENCE_READ_NODE: + PM_PARSER_ERR_NODE_FORMAT_CONTENT(parser, node, PM_ERR_WRITE_TARGET_READONLY); + PRISM_FALLTHROUGH + case PM_GLOBAL_VARIABLE_READ_NODE: { + parser_lex(parser); + + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ, (uint16_t) (depth + 1)); + pm_node_t *result = (pm_node_t *) pm_global_variable_or_write_node_create(parser, node, &token, value); + + pm_node_destroy(parser, node); + return result; + } + case PM_CLASS_VARIABLE_READ_NODE: { + parser_lex(parser); + + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ, (uint16_t) (depth + 1)); + pm_node_t *result = (pm_node_t *) pm_class_variable_or_write_node_create(parser, (pm_class_variable_read_node_t *) node, &token, value); + + pm_node_destroy(parser, node); + return result; + } + case PM_CONSTANT_PATH_NODE: { + parser_lex(parser); + + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ, (uint16_t) (depth + 1)); + pm_node_t *write = (pm_node_t *) pm_constant_path_or_write_node_create(parser, (pm_constant_path_node_t *) node, &token, value); + + return parse_shareable_constant_write(parser, write); + } + case PM_CONSTANT_READ_NODE: { + parser_lex(parser); + + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ, (uint16_t) (depth + 1)); + pm_node_t *write = (pm_node_t *) pm_constant_or_write_node_create(parser, (pm_constant_read_node_t *) node, &token, value); + + pm_node_destroy(parser, node); + return parse_shareable_constant_write(parser, write); + } + case PM_INSTANCE_VARIABLE_READ_NODE: { + parser_lex(parser); + + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ, (uint16_t) (depth + 1)); + pm_node_t *result = (pm_node_t *) pm_instance_variable_or_write_node_create(parser, (pm_instance_variable_read_node_t *) node, &token, value); + + pm_node_destroy(parser, node); + return result; + } + case PM_IT_LOCAL_VARIABLE_READ_NODE: { + pm_constant_id_t name = pm_parser_local_add_constant(parser, "it", 2); + parser_lex(parser); + + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ, (uint16_t) (depth + 1)); + pm_node_t *result = (pm_node_t *) pm_local_variable_or_write_node_create(parser, node, &token, value, name, 0); + + parse_target_implicit_parameter(parser, node); + pm_node_destroy(parser, node); + return result; + } + case PM_LOCAL_VARIABLE_READ_NODE: { + if (pm_token_is_numbered_parameter(node->location.start, node->location.end)) { + PM_PARSER_ERR_FORMAT(parser, node->location.start, node->location.end, PM_ERR_PARAMETER_NUMBERED_RESERVED, node->location.start); + parse_target_implicit_parameter(parser, node); + } + + pm_local_variable_read_node_t *cast = (pm_local_variable_read_node_t *) node; + parser_lex(parser); + + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ, (uint16_t) (depth + 1)); + pm_node_t *result = (pm_node_t *) pm_local_variable_or_write_node_create(parser, node, &token, value, cast->name, cast->depth); + + pm_node_destroy(parser, node); + return result; + } + case PM_CALL_NODE: { + pm_call_node_t *cast = (pm_call_node_t *) node; + + // If we have a vcall (a method with no arguments and no + // receiver that could have been a local variable) then we + // will transform it into a local variable write. + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_VARIABLE_CALL)) { + pm_location_t *message_loc = &cast->message_loc; + pm_refute_numbered_parameter(parser, message_loc->start, message_loc->end); + + pm_constant_id_t constant_id = pm_parser_local_add_location(parser, message_loc->start, message_loc->end, 1); + parser_lex(parser); + + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ, (uint16_t) (depth + 1)); + pm_node_t *result = (pm_node_t *) pm_local_variable_or_write_node_create(parser, (pm_node_t *) cast, &token, value, constant_id, 0); + + pm_node_destroy(parser, (pm_node_t *) cast); + return result; + } + + // Move past the token here so that we have already added + // the local variable by this point. + parser_lex(parser); + + // If there is no call operator and the message is "[]" then + // this is an aref expression, and we can transform it into + // an aset expression. + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_INDEX)) { + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ, (uint16_t) (depth + 1)); + return (pm_node_t *) pm_index_or_write_node_create(parser, cast, &token, value); + } + + // If this node cannot be writable, then we have an error. + if (pm_call_node_writable_p(parser, cast)) { + parse_write_name(parser, &cast->name); + } else { + pm_parser_err_node(parser, node, PM_ERR_WRITE_TARGET_UNEXPECTED); + } + + parse_call_operator_write(parser, cast, &token); + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ, (uint16_t) (depth + 1)); + return (pm_node_t *) pm_call_or_write_node_create(parser, cast, &token, value); + } + case PM_MULTI_WRITE_NODE: { + parser_lex(parser); + pm_parser_err_token(parser, &token, PM_ERR_PIPEPIPEEQ_MULTI_ASSIGN); + return node; + } + default: + parser_lex(parser); + + // In this case we have an ||= sign, but we don't know what it's for. + // We need to treat it as an error. For now, we'll mark it as an error + // and just skip right past it. + pm_parser_err_token(parser, &token, PM_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ); + return node; + } + } + case PM_TOKEN_AMPERSAND_EQUAL: + case PM_TOKEN_CARET_EQUAL: + case PM_TOKEN_GREATER_GREATER_EQUAL: + case PM_TOKEN_LESS_LESS_EQUAL: + case PM_TOKEN_MINUS_EQUAL: + case PM_TOKEN_PERCENT_EQUAL: + case PM_TOKEN_PIPE_EQUAL: + case PM_TOKEN_PLUS_EQUAL: + case PM_TOKEN_SLASH_EQUAL: + case PM_TOKEN_STAR_EQUAL: + case PM_TOKEN_STAR_STAR_EQUAL: { + switch (PM_NODE_TYPE(node)) { + case PM_BACK_REFERENCE_READ_NODE: + case PM_NUMBERED_REFERENCE_READ_NODE: + PM_PARSER_ERR_NODE_FORMAT_CONTENT(parser, node, PM_ERR_WRITE_TARGET_READONLY); + PRISM_FALLTHROUGH + case PM_GLOBAL_VARIABLE_READ_NODE: { + parser_lex(parser); + + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1)); + pm_node_t *result = (pm_node_t *) pm_global_variable_operator_write_node_create(parser, node, &token, value); + + pm_node_destroy(parser, node); + return result; + } + case PM_CLASS_VARIABLE_READ_NODE: { + parser_lex(parser); + + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1)); + pm_node_t *result = (pm_node_t *) pm_class_variable_operator_write_node_create(parser, (pm_class_variable_read_node_t *) node, &token, value); + + pm_node_destroy(parser, node); + return result; + } + case PM_CONSTANT_PATH_NODE: { + parser_lex(parser); + + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1)); + pm_node_t *write = (pm_node_t *) pm_constant_path_operator_write_node_create(parser, (pm_constant_path_node_t *) node, &token, value); + + return parse_shareable_constant_write(parser, write); + } + case PM_CONSTANT_READ_NODE: { + parser_lex(parser); + + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1)); + pm_node_t *write = (pm_node_t *) pm_constant_operator_write_node_create(parser, (pm_constant_read_node_t *) node, &token, value); + + pm_node_destroy(parser, node); + return parse_shareable_constant_write(parser, write); + } + case PM_INSTANCE_VARIABLE_READ_NODE: { + parser_lex(parser); + + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1)); + pm_node_t *result = (pm_node_t *) pm_instance_variable_operator_write_node_create(parser, (pm_instance_variable_read_node_t *) node, &token, value); + + pm_node_destroy(parser, node); + return result; + } + case PM_IT_LOCAL_VARIABLE_READ_NODE: { + pm_constant_id_t name = pm_parser_local_add_constant(parser, "it", 2); + parser_lex(parser); + + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1)); + pm_node_t *result = (pm_node_t *) pm_local_variable_operator_write_node_create(parser, node, &token, value, name, 0); + + parse_target_implicit_parameter(parser, node); + pm_node_destroy(parser, node); + return result; + } + case PM_LOCAL_VARIABLE_READ_NODE: { + if (pm_token_is_numbered_parameter(node->location.start, node->location.end)) { + PM_PARSER_ERR_FORMAT(parser, node->location.start, node->location.end, PM_ERR_PARAMETER_NUMBERED_RESERVED, node->location.start); + parse_target_implicit_parameter(parser, node); + } + + pm_local_variable_read_node_t *cast = (pm_local_variable_read_node_t *) node; + parser_lex(parser); + + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1)); + pm_node_t *result = (pm_node_t *) pm_local_variable_operator_write_node_create(parser, node, &token, value, cast->name, cast->depth); + + pm_node_destroy(parser, node); + return result; + } + case PM_CALL_NODE: { + parser_lex(parser); + pm_call_node_t *cast = (pm_call_node_t *) node; + + // If we have a vcall (a method with no arguments and no + // receiver that could have been a local variable) then we + // will transform it into a local variable write. + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_VARIABLE_CALL)) { + pm_location_t *message_loc = &cast->message_loc; + pm_refute_numbered_parameter(parser, message_loc->start, message_loc->end); + + pm_constant_id_t constant_id = pm_parser_local_add_location(parser, message_loc->start, message_loc->end, 1); + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1)); + pm_node_t *result = (pm_node_t *) pm_local_variable_operator_write_node_create(parser, (pm_node_t *) cast, &token, value, constant_id, 0); + + pm_node_destroy(parser, (pm_node_t *) cast); + return result; + } + + // If there is no call operator and the message is "[]" then + // this is an aref expression, and we can transform it into + // an aset expression. + if (PM_NODE_FLAG_P(cast, PM_CALL_NODE_FLAGS_INDEX)) { + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1)); + return (pm_node_t *) pm_index_operator_write_node_create(parser, cast, &token, value); + } + + // If this node cannot be writable, then we have an error. + if (pm_call_node_writable_p(parser, cast)) { + parse_write_name(parser, &cast->name); + } else { + pm_parser_err_node(parser, node, PM_ERR_WRITE_TARGET_UNEXPECTED); + } + + parse_call_operator_write(parser, cast, &token); + pm_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, accepts_command_call, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1)); + return (pm_node_t *) pm_call_operator_write_node_create(parser, cast, &token, value); + } + case PM_MULTI_WRITE_NODE: { + parser_lex(parser); + pm_parser_err_token(parser, &token, PM_ERR_OPERATOR_MULTI_ASSIGN); + return node; + } + default: + parser_lex(parser); + + // In this case we have an operator but we don't know what it's for. + // We need to treat it as an error. For now, we'll mark it as an error + // and just skip right past it. + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->previous, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, pm_token_type_human(parser->current.type)); + return node; + } + } + case PM_TOKEN_AMPERSAND_AMPERSAND: + case PM_TOKEN_KEYWORD_AND: { + parser_lex(parser); + + pm_node_t *right = parse_expression(parser, binding_power, parser->previous.type == PM_TOKEN_KEYWORD_AND, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1)); + return (pm_node_t *) pm_and_node_create(parser, node, &token, right); + } + case PM_TOKEN_KEYWORD_OR: + case PM_TOKEN_PIPE_PIPE: { + parser_lex(parser); + + pm_node_t *right = parse_expression(parser, binding_power, parser->previous.type == PM_TOKEN_KEYWORD_OR, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1)); + return (pm_node_t *) pm_or_node_create(parser, node, &token, right); + } + case PM_TOKEN_EQUAL_TILDE: { + // Note that we _must_ parse the value before adding the local + // variables in order to properly mirror the behavior of Ruby. For + // example, + // + // /(?bar)/ =~ foo + // + // In this case, `foo` should be a method call and not a local yet. + parser_lex(parser); + pm_node_t *argument = parse_expression(parser, binding_power, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1)); + + // By default, we're going to create a call node and then return it. + pm_call_node_t *call = pm_call_node_binary_create(parser, node, &token, argument, 0); + pm_node_t *result = (pm_node_t *) call; + + // If the receiver of this =~ is a regular expression node, then we + // need to introduce local variables for it based on its named + // capture groups. + if (PM_NODE_TYPE_P(node, PM_INTERPOLATED_REGULAR_EXPRESSION_NODE)) { + // It's possible to have an interpolated regular expression node + // that only contains strings. This is because it can be split + // up by a heredoc. In this case we need to concat the unescaped + // strings together and then parse them as a regular expression. + pm_node_list_t *parts = &((pm_interpolated_regular_expression_node_t *) node)->parts; + + bool interpolated = false; + size_t total_length = 0; + + pm_node_t *part; + PM_NODE_LIST_FOREACH(parts, index, part) { + if (PM_NODE_TYPE_P(part, PM_STRING_NODE)) { + total_length += pm_string_length(&((pm_string_node_t *) part)->unescaped); + } else { + interpolated = true; + break; + } + } + + if (!interpolated && total_length > 0) { + void *memory = xmalloc(total_length); + if (!memory) abort(); + + uint8_t *cursor = memory; + PM_NODE_LIST_FOREACH(parts, index, part) { + pm_string_t *unescaped = &((pm_string_node_t *) part)->unescaped; + size_t length = pm_string_length(unescaped); + + memcpy(cursor, pm_string_source(unescaped), length); + cursor += length; + } + + pm_string_t owned; + pm_string_owned_init(&owned, (uint8_t *) memory, total_length); + + result = parse_regular_expression_named_captures(parser, &owned, call, PM_NODE_FLAG_P(node, PM_REGULAR_EXPRESSION_FLAGS_EXTENDED)); + pm_string_free(&owned); + } + } else if (PM_NODE_TYPE_P(node, PM_REGULAR_EXPRESSION_NODE)) { + // If we have a regular expression node, then we can just parse + // the named captures directly off the unescaped string. + const pm_string_t *content = &((pm_regular_expression_node_t *) node)->unescaped; + result = parse_regular_expression_named_captures(parser, content, call, PM_NODE_FLAG_P(node, PM_REGULAR_EXPRESSION_FLAGS_EXTENDED)); + } + + return result; + } + case PM_TOKEN_UAMPERSAND: + case PM_TOKEN_USTAR: + case PM_TOKEN_USTAR_STAR: + // The only times this will occur are when we are in an error state, + // but we'll put them in here so that errors can propagate. + case PM_TOKEN_BANG_EQUAL: + case PM_TOKEN_BANG_TILDE: + case PM_TOKEN_EQUAL_EQUAL: + case PM_TOKEN_EQUAL_EQUAL_EQUAL: + case PM_TOKEN_LESS_EQUAL_GREATER: + case PM_TOKEN_CARET: + case PM_TOKEN_PIPE: + case PM_TOKEN_AMPERSAND: + case PM_TOKEN_GREATER_GREATER: + case PM_TOKEN_LESS_LESS: + case PM_TOKEN_MINUS: + case PM_TOKEN_PLUS: + case PM_TOKEN_PERCENT: + case PM_TOKEN_SLASH: + case PM_TOKEN_STAR: + case PM_TOKEN_STAR_STAR: { + parser_lex(parser); + pm_token_t operator = parser->previous; + switch (PM_NODE_TYPE(node)) { + case PM_RESCUE_MODIFIER_NODE: { + pm_rescue_modifier_node_t *cast = (pm_rescue_modifier_node_t *) node; + if (PM_NODE_TYPE_P(cast->rescue_expression, PM_MATCH_PREDICATE_NODE) || PM_NODE_TYPE_P(cast->rescue_expression, PM_MATCH_REQUIRED_NODE)) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, operator, PM_ERR_EXPECT_EOL_AFTER_STATEMENT, pm_token_type_human(operator.type)); + } + break; + } + case PM_AND_NODE: { + pm_and_node_t *cast = (pm_and_node_t *) node; + if (PM_NODE_TYPE_P(cast->right, PM_MATCH_PREDICATE_NODE) || PM_NODE_TYPE_P(cast->right, PM_MATCH_REQUIRED_NODE)) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, operator, PM_ERR_EXPECT_EOL_AFTER_STATEMENT, pm_token_type_human(operator.type)); + } + break; + } + case PM_OR_NODE: { + pm_or_node_t *cast = (pm_or_node_t *) node; + if (PM_NODE_TYPE_P(cast->right, PM_MATCH_PREDICATE_NODE) || PM_NODE_TYPE_P(cast->right, PM_MATCH_REQUIRED_NODE)) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, operator, PM_ERR_EXPECT_EOL_AFTER_STATEMENT, pm_token_type_human(operator.type)); + } + break; + } + default: + break; + } + + pm_node_t *argument = parse_expression(parser, binding_power, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1)); + return (pm_node_t *) pm_call_node_binary_create(parser, node, &token, argument, 0); + } + case PM_TOKEN_GREATER: + case PM_TOKEN_GREATER_EQUAL: + case PM_TOKEN_LESS: + case PM_TOKEN_LESS_EQUAL: { + if (PM_NODE_TYPE_P(node, PM_CALL_NODE) && PM_NODE_FLAG_P(node, PM_CALL_NODE_FLAGS_COMPARISON)) { + PM_PARSER_WARN_TOKEN_FORMAT_CONTENT(parser, parser->current, PM_WARN_COMPARISON_AFTER_COMPARISON); + } + + parser_lex(parser); + pm_node_t *argument = parse_expression(parser, binding_power, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1)); + return (pm_node_t *) pm_call_node_binary_create(parser, node, &token, argument, PM_CALL_NODE_FLAGS_COMPARISON); + } + case PM_TOKEN_AMPERSAND_DOT: + case PM_TOKEN_DOT: { + parser_lex(parser); + pm_token_t operator = parser->previous; + pm_arguments_t arguments = { 0 }; + + // This if statement handles the foo.() syntax. + if (match1(parser, PM_TOKEN_PARENTHESIS_LEFT)) { + parse_arguments_list(parser, &arguments, true, false, (uint16_t) (depth + 1)); + return (pm_node_t *) pm_call_node_shorthand_create(parser, node, &operator, &arguments); + } + + switch (PM_NODE_TYPE(node)) { + case PM_RESCUE_MODIFIER_NODE: { + pm_rescue_modifier_node_t *cast = (pm_rescue_modifier_node_t *) node; + if (PM_NODE_TYPE_P(cast->rescue_expression, PM_MATCH_PREDICATE_NODE) || PM_NODE_TYPE_P(cast->rescue_expression, PM_MATCH_REQUIRED_NODE)) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, operator, PM_ERR_EXPECT_EOL_AFTER_STATEMENT, pm_token_type_human(operator.type)); + } + break; + } + case PM_AND_NODE: { + pm_and_node_t *cast = (pm_and_node_t *) node; + if (PM_NODE_TYPE_P(cast->right, PM_MATCH_PREDICATE_NODE) || PM_NODE_TYPE_P(cast->right, PM_MATCH_REQUIRED_NODE)) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, operator, PM_ERR_EXPECT_EOL_AFTER_STATEMENT, pm_token_type_human(operator.type)); + } + break; + } + case PM_OR_NODE: { + pm_or_node_t *cast = (pm_or_node_t *) node; + if (PM_NODE_TYPE_P(cast->right, PM_MATCH_PREDICATE_NODE) || PM_NODE_TYPE_P(cast->right, PM_MATCH_REQUIRED_NODE)) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, operator, PM_ERR_EXPECT_EOL_AFTER_STATEMENT, pm_token_type_human(operator.type)); + } + break; + } + default: + break; + } + + pm_token_t message; + + switch (parser->current.type) { + case PM_CASE_OPERATOR: + case PM_CASE_KEYWORD: + case PM_TOKEN_CONSTANT: + case PM_TOKEN_IDENTIFIER: + case PM_TOKEN_METHOD_NAME: { + parser_lex(parser); + message = parser->previous; + break; + } + default: { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_EXPECT_MESSAGE, pm_token_type_human(parser->current.type)); + message = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end }; + } + } + + parse_arguments_list(parser, &arguments, true, accepts_command_call, (uint16_t) (depth + 1)); + pm_call_node_t *call = pm_call_node_call_create(parser, node, &operator, &message, &arguments); + + if ( + (previous_binding_power == PM_BINDING_POWER_STATEMENT) && + arguments.arguments == NULL && + arguments.opening_loc.start == NULL && + match1(parser, PM_TOKEN_COMMA) + ) { + return parse_targets_validate(parser, (pm_node_t *) call, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1)); + } else { + return (pm_node_t *) call; + } + } + case PM_TOKEN_DOT_DOT: + case PM_TOKEN_DOT_DOT_DOT: { + parser_lex(parser); + + pm_node_t *right = NULL; + if (token_begins_expression_p(parser->current.type)) { + right = parse_expression(parser, binding_power, false, false, PM_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, (uint16_t) (depth + 1)); + } + + return (pm_node_t *) pm_range_node_create(parser, node, &token, right); + } + case PM_TOKEN_KEYWORD_IF_MODIFIER: { + pm_token_t keyword = parser->current; + parser_lex(parser); + + pm_node_t *predicate = parse_value_expression(parser, binding_power, true, false, PM_ERR_CONDITIONAL_IF_PREDICATE, (uint16_t) (depth + 1)); + return (pm_node_t *) pm_if_node_modifier_create(parser, node, &keyword, predicate); + } + case PM_TOKEN_KEYWORD_UNLESS_MODIFIER: { + pm_token_t keyword = parser->current; + parser_lex(parser); + + pm_node_t *predicate = parse_value_expression(parser, binding_power, true, false, PM_ERR_CONDITIONAL_UNLESS_PREDICATE, (uint16_t) (depth + 1)); + return (pm_node_t *) pm_unless_node_modifier_create(parser, node, &keyword, predicate); + } + case PM_TOKEN_KEYWORD_UNTIL_MODIFIER: { + parser_lex(parser); + pm_statements_node_t *statements = pm_statements_node_create(parser); + pm_statements_node_body_append(parser, statements, node, true); + + pm_node_t *predicate = parse_value_expression(parser, binding_power, true, false, PM_ERR_CONDITIONAL_UNTIL_PREDICATE, (uint16_t) (depth + 1)); + return (pm_node_t *) pm_until_node_modifier_create(parser, &token, predicate, statements, PM_NODE_TYPE_P(node, PM_BEGIN_NODE) ? PM_LOOP_FLAGS_BEGIN_MODIFIER : 0); + } + case PM_TOKEN_KEYWORD_WHILE_MODIFIER: { + parser_lex(parser); + pm_statements_node_t *statements = pm_statements_node_create(parser); + pm_statements_node_body_append(parser, statements, node, true); + + pm_node_t *predicate = parse_value_expression(parser, binding_power, true, false, PM_ERR_CONDITIONAL_WHILE_PREDICATE, (uint16_t) (depth + 1)); + return (pm_node_t *) pm_while_node_modifier_create(parser, &token, predicate, statements, PM_NODE_TYPE_P(node, PM_BEGIN_NODE) ? PM_LOOP_FLAGS_BEGIN_MODIFIER : 0); + } + case PM_TOKEN_QUESTION_MARK: { + context_push(parser, PM_CONTEXT_TERNARY); + pm_node_list_t current_block_exits = { 0 }; + pm_node_list_t *previous_block_exits = push_block_exits(parser, ¤t_block_exits); + + pm_token_t qmark = parser->current; + parser_lex(parser); + + pm_node_t *true_expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_TERNARY_EXPRESSION_TRUE, (uint16_t) (depth + 1)); + + if (parser->recovering) { + // If parsing the true expression of this ternary resulted in a syntax + // error that we can recover from, then we're going to put missing nodes + // and tokens into the remaining places. We want to be sure to do this + // before the `expect` function call to make sure it doesn't + // accidentally move past a ':' token that occurs after the syntax + // error. + pm_token_t colon = (pm_token_t) { .type = PM_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end }; + pm_node_t *false_expression = (pm_node_t *) pm_missing_node_create(parser, colon.start, colon.end); + + context_pop(parser); + pop_block_exits(parser, previous_block_exits); + pm_node_list_free(¤t_block_exits); + + return (pm_node_t *) pm_if_node_ternary_create(parser, node, &qmark, true_expression, &colon, false_expression); + } + + accept1(parser, PM_TOKEN_NEWLINE); + expect1(parser, PM_TOKEN_COLON, PM_ERR_TERNARY_COLON); + + pm_token_t colon = parser->previous; + pm_node_t *false_expression = parse_expression(parser, PM_BINDING_POWER_DEFINED, false, false, PM_ERR_TERNARY_EXPRESSION_FALSE, (uint16_t) (depth + 1)); + + context_pop(parser); + pop_block_exits(parser, previous_block_exits); + pm_node_list_free(¤t_block_exits); + + return (pm_node_t *) pm_if_node_ternary_create(parser, node, &qmark, true_expression, &colon, false_expression); + } + case PM_TOKEN_COLON_COLON: { + parser_lex(parser); + pm_token_t delimiter = parser->previous; + + switch (parser->current.type) { + case PM_TOKEN_CONSTANT: { + parser_lex(parser); + pm_node_t *path; + + if ( + (parser->current.type == PM_TOKEN_PARENTHESIS_LEFT) || + (accepts_command_call && (token_begins_expression_p(parser->current.type) || match3(parser, PM_TOKEN_UAMPERSAND, PM_TOKEN_USTAR, PM_TOKEN_USTAR_STAR))) + ) { + // If we have a constant immediately following a '::' operator, then + // this can either be a constant path or a method call, depending on + // what follows the constant. + // + // If we have parentheses, then this is a method call. That would + // look like Foo::Bar(). + pm_token_t message = parser->previous; + pm_arguments_t arguments = { 0 }; + + parse_arguments_list(parser, &arguments, true, accepts_command_call, (uint16_t) (depth + 1)); + path = (pm_node_t *) pm_call_node_call_create(parser, node, &delimiter, &message, &arguments); + } else { + // Otherwise, this is a constant path. That would look like Foo::Bar. + path = (pm_node_t *) pm_constant_path_node_create(parser, node, &delimiter, &parser->previous); + } + + // If this is followed by a comma then it is a multiple assignment. + if (previous_binding_power == PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_COMMA)) { + return parse_targets_validate(parser, path, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1)); + } + + return path; + } + case PM_CASE_OPERATOR: + case PM_CASE_KEYWORD: + case PM_TOKEN_IDENTIFIER: + case PM_TOKEN_METHOD_NAME: { + parser_lex(parser); + pm_token_t message = parser->previous; + + // If we have an identifier following a '::' operator, then it is for + // sure a method call. + pm_arguments_t arguments = { 0 }; + parse_arguments_list(parser, &arguments, true, accepts_command_call, (uint16_t) (depth + 1)); + pm_call_node_t *call = pm_call_node_call_create(parser, node, &delimiter, &message, &arguments); + + // If this is followed by a comma then it is a multiple assignment. + if (previous_binding_power == PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_COMMA)) { + return parse_targets_validate(parser, (pm_node_t *) call, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1)); + } + + return (pm_node_t *) call; + } + case PM_TOKEN_PARENTHESIS_LEFT: { + // If we have a parenthesis following a '::' operator, then it is the + // method call shorthand. That would look like Foo::(bar). + pm_arguments_t arguments = { 0 }; + parse_arguments_list(parser, &arguments, true, false, (uint16_t) (depth + 1)); + + return (pm_node_t *) pm_call_node_shorthand_create(parser, node, &delimiter, &arguments); + } + default: { + expect1(parser, PM_TOKEN_CONSTANT, PM_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT); + return (pm_node_t *) pm_constant_path_node_create(parser, node, &delimiter, &parser->previous); + } + } + } + case PM_TOKEN_KEYWORD_RESCUE_MODIFIER: { + context_push(parser, PM_CONTEXT_RESCUE_MODIFIER); + parser_lex(parser); + accept1(parser, PM_TOKEN_NEWLINE); + + pm_node_t *value = parse_expression(parser, binding_power, true, false, PM_ERR_RESCUE_MODIFIER_VALUE, (uint16_t) (depth + 1)); + context_pop(parser); + + return (pm_node_t *) pm_rescue_modifier_node_create(parser, node, &token, value); + } + case PM_TOKEN_BRACKET_LEFT: { + parser_lex(parser); + + pm_arguments_t arguments = { 0 }; + arguments.opening_loc = PM_LOCATION_TOKEN_VALUE(&parser->previous); + + if (!accept1(parser, PM_TOKEN_BRACKET_RIGHT)) { + pm_accepts_block_stack_push(parser, true); + parse_arguments(parser, &arguments, false, PM_TOKEN_BRACKET_RIGHT, (uint16_t) (depth + 1)); + pm_accepts_block_stack_pop(parser); + expect1(parser, PM_TOKEN_BRACKET_RIGHT, PM_ERR_EXPECT_RBRACKET); + } + + arguments.closing_loc = PM_LOCATION_TOKEN_VALUE(&parser->previous); + + // If we have a comma after the closing bracket then this is a multiple + // assignment and we should parse the targets. + if (previous_binding_power == PM_BINDING_POWER_STATEMENT && match1(parser, PM_TOKEN_COMMA)) { + pm_call_node_t *aref = pm_call_node_aref_create(parser, node, &arguments); + return parse_targets_validate(parser, (pm_node_t *) aref, PM_BINDING_POWER_INDEX, (uint16_t) (depth + 1)); + } + + // If we're at the end of the arguments, we can now check if there is a + // block node that starts with a {. If there is, then we can parse it and + // add it to the arguments. + pm_block_node_t *block = NULL; + if (accept1(parser, PM_TOKEN_BRACE_LEFT)) { + block = parse_block(parser, (uint16_t) (depth + 1)); + pm_arguments_validate_block(parser, &arguments, block); + } else if (pm_accepts_block_stack_p(parser) && accept1(parser, PM_TOKEN_KEYWORD_DO)) { + block = parse_block(parser, (uint16_t) (depth + 1)); + } + + if (block != NULL) { + if (arguments.block != NULL) { + pm_parser_err_node(parser, (pm_node_t *) block, PM_ERR_ARGUMENT_AFTER_BLOCK); + if (arguments.arguments == NULL) { + arguments.arguments = pm_arguments_node_create(parser); + } + pm_arguments_node_arguments_append(arguments.arguments, arguments.block); + } + + arguments.block = (pm_node_t *) block; + } + + return (pm_node_t *) pm_call_node_aref_create(parser, node, &arguments); + } + case PM_TOKEN_KEYWORD_IN: { + bool previous_pattern_matching_newlines = parser->pattern_matching_newlines; + parser->pattern_matching_newlines = true; + + pm_token_t operator = parser->current; + parser->command_start = false; + lex_state_set(parser, PM_LEX_STATE_BEG | PM_LEX_STATE_LABEL); + parser_lex(parser); + + pm_constant_id_list_t captures = { 0 }; + pm_node_t *pattern = parse_pattern(parser, &captures, PM_PARSE_PATTERN_TOP | PM_PARSE_PATTERN_MULTI, PM_ERR_PATTERN_EXPRESSION_AFTER_IN, (uint16_t) (depth + 1)); + + parser->pattern_matching_newlines = previous_pattern_matching_newlines; + pm_constant_id_list_free(&captures); + + return (pm_node_t *) pm_match_predicate_node_create(parser, node, pattern, &operator); + } + case PM_TOKEN_EQUAL_GREATER: { + bool previous_pattern_matching_newlines = parser->pattern_matching_newlines; + parser->pattern_matching_newlines = true; + + pm_token_t operator = parser->current; + parser->command_start = false; + lex_state_set(parser, PM_LEX_STATE_BEG | PM_LEX_STATE_LABEL); + parser_lex(parser); + + pm_constant_id_list_t captures = { 0 }; + pm_node_t *pattern = parse_pattern(parser, &captures, PM_PARSE_PATTERN_TOP | PM_PARSE_PATTERN_MULTI, PM_ERR_PATTERN_EXPRESSION_AFTER_HROCKET, (uint16_t) (depth + 1)); + + parser->pattern_matching_newlines = previous_pattern_matching_newlines; + pm_constant_id_list_free(&captures); + + return (pm_node_t *) pm_match_required_node_create(parser, node, pattern, &operator); + } + default: + assert(false && "unreachable"); + return NULL; + } +} + +#undef PM_PARSE_PATTERN_SINGLE +#undef PM_PARSE_PATTERN_TOP +#undef PM_PARSE_PATTERN_MULTI + +/** + * Determine if a given call node looks like a "command", which means it has + * arguments but does not have parentheses. + */ +static inline bool +pm_call_node_command_p(const pm_call_node_t *node) { + return ( + (node->opening_loc.start == NULL) && + (node->block == NULL || PM_NODE_TYPE_P(node->block, PM_BLOCK_ARGUMENT_NODE)) && + (node->arguments != NULL || node->block != NULL) + ); +} + +/** + * Parse an expression at the given point of the parser using the given binding + * power to parse subsequent chains. If this function finds a syntax error, it + * will append the error message to the parser's error list. + * + * Consumers of this function should always check parser->recovering to + * determine if they need to perform additional cleanup. + */ +static pm_node_t * +parse_expression(pm_parser_t *parser, pm_binding_power_t binding_power, bool accepts_command_call, bool accepts_label, pm_diagnostic_id_t diag_id, uint16_t depth) { + if (PRISM_UNLIKELY(depth >= PRISM_DEPTH_MAXIMUM)) { + pm_parser_err_current(parser, PM_ERR_NESTING_TOO_DEEP); + return (pm_node_t *) pm_missing_node_create(parser, parser->current.start, parser->current.end); + } + + pm_node_t *node = parse_expression_prefix(parser, binding_power, accepts_command_call, accepts_label, diag_id, depth); + + switch (PM_NODE_TYPE(node)) { + case PM_MISSING_NODE: + // If we found a syntax error, then the type of node returned by + // parse_expression_prefix is going to be a missing node. + return node; + case PM_PRE_EXECUTION_NODE: + case PM_POST_EXECUTION_NODE: + case PM_ALIAS_GLOBAL_VARIABLE_NODE: + case PM_ALIAS_METHOD_NODE: + case PM_MULTI_WRITE_NODE: + case PM_UNDEF_NODE: + // These expressions are statements, and cannot be followed by + // operators (except modifiers). + if (pm_binding_powers[parser->current.type].left > PM_BINDING_POWER_MODIFIER) { + return node; + } + break; + case PM_CALL_NODE: + // If we have a call node, then we need to check if it looks like a + // method call without parentheses that contains arguments. If it + // does, then it has different rules for parsing infix operators, + // namely that it only accepts composition (and/or) and modifiers + // (if/unless/etc.). + if ((pm_binding_powers[parser->current.type].left > PM_BINDING_POWER_COMPOSITION) && pm_call_node_command_p((pm_call_node_t *) node)) { + return node; + } + break; + case PM_SYMBOL_NODE: + // If we have a symbol node that is being parsed as a label, then we + // need to immediately return, because there should never be an + // infix operator following this node. + if (pm_symbol_node_label_p(node)) { + return node; + } + break; + default: + break; + } + + // Otherwise we'll look and see if the next token can be parsed as an infix + // operator. If it can, then we'll parse it using parse_expression_infix. + pm_binding_powers_t current_binding_powers; + pm_token_type_t current_token_type; + + while ( + current_token_type = parser->current.type, + current_binding_powers = pm_binding_powers[current_token_type], + binding_power <= current_binding_powers.left && + current_binding_powers.binary + ) { + node = parse_expression_infix(parser, node, binding_power, current_binding_powers.right, accepts_command_call, (uint16_t) (depth + 1)); + + switch (PM_NODE_TYPE(node)) { + case PM_MULTI_WRITE_NODE: + // Multi-write nodes are statements, and cannot be followed by + // operators except modifiers. + if (pm_binding_powers[parser->current.type].left > PM_BINDING_POWER_MODIFIER) { + return node; + } + break; + case PM_CLASS_VARIABLE_WRITE_NODE: + case PM_CONSTANT_PATH_WRITE_NODE: + case PM_CONSTANT_WRITE_NODE: + case PM_GLOBAL_VARIABLE_WRITE_NODE: + case PM_INSTANCE_VARIABLE_WRITE_NODE: + case PM_LOCAL_VARIABLE_WRITE_NODE: + // These expressions are statements, by virtue of the right-hand + // side of their write being an implicit array. + if (PM_NODE_FLAG_P(node, PM_WRITE_NODE_FLAGS_IMPLICIT_ARRAY) && pm_binding_powers[parser->current.type].left > PM_BINDING_POWER_MODIFIER) { + return node; + } + break; + case PM_CALL_NODE: + // These expressions are also statements, by virtue of the + // right-hand side of the expression (i.e., the last argument to + // the call node) being an implicit array. + if (PM_NODE_FLAG_P(node, PM_CALL_NODE_FLAGS_IMPLICIT_ARRAY) && pm_binding_powers[parser->current.type].left > PM_BINDING_POWER_MODIFIER) { + return node; + } + break; + default: + break; + } + + // If the operator is nonassoc and we should not be able to parse the + // upcoming infix operator, break. + if (current_binding_powers.nonassoc) { + // If this is a non-assoc operator and we are about to parse the + // exact same operator, then we need to add an error. + if (match1(parser, current_token_type)) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_NON_ASSOCIATIVE_OPERATOR, pm_token_type_human(parser->current.type), pm_token_type_human(current_token_type)); + break; + } + + // If this is an endless range, then we need to reject a couple of + // additional operators because it violates the normal operator + // precedence rules. Those patterns are: + // + // 1.. & 2 + // 1.. * 2 + // + if (PM_NODE_TYPE_P(node, PM_RANGE_NODE) && ((pm_range_node_t *) node)->right == NULL) { + if (match4(parser, PM_TOKEN_UAMPERSAND, PM_TOKEN_USTAR, PM_TOKEN_DOT, PM_TOKEN_AMPERSAND_DOT)) { + PM_PARSER_ERR_TOKEN_FORMAT(parser, parser->current, PM_ERR_NON_ASSOCIATIVE_OPERATOR, pm_token_type_human(parser->current.type), pm_token_type_human(current_token_type)); + break; + } + + if (PM_BINDING_POWER_TERM <= pm_binding_powers[parser->current.type].left) { + break; + } + } else if (current_binding_powers.left <= pm_binding_powers[parser->current.type].left) { + break; + } + } + + if (accepts_command_call) { + // A command-style method call is only accepted on method chains. + // Thus, we check whether the parsed node can continue method chains. + // The method chain can continue if the parsed node is one of the following five kinds: + // (1) index access: foo[1] + // (2) attribute access: foo.bar + // (3) method call with parenthesis: foo.bar(1) + // (4) method call with a block: foo.bar do end + // (5) constant path: foo::Bar + switch (node->type) { + case PM_CALL_NODE: { + pm_call_node_t *cast = (pm_call_node_t *)node; + if ( + // (1) foo[1] + !( + cast->call_operator_loc.start == NULL && + cast->message_loc.start != NULL && + cast->message_loc.start[0] == '[' && + cast->message_loc.end[-1] == ']' + ) && + // (2) foo.bar + !( + cast->call_operator_loc.start != NULL && + cast->arguments == NULL && + cast->block == NULL && + cast->opening_loc.start == NULL + ) && + // (3) foo.bar(1) + !( + cast->call_operator_loc.start != NULL && + cast->opening_loc.start != NULL + ) && + // (4) foo.bar do end + !( + cast->block != NULL && PM_NODE_TYPE_P(cast->block, PM_BLOCK_NODE) + ) + ) { + accepts_command_call = false; + } + break; + } + // (5) foo::Bar + case PM_CONSTANT_PATH_NODE: + break; + default: + accepts_command_call = false; + break; + } + } + } + + return node; +} + +/** + * ruby -p, ruby -n, ruby -a, and ruby -l options will mutate the AST. We + * perform that mutation here. + */ +static pm_statements_node_t * +wrap_statements(pm_parser_t *parser, pm_statements_node_t *statements) { + if (PM_PARSER_COMMAND_LINE_OPTION_P(parser)) { + if (statements == NULL) { + statements = pm_statements_node_create(parser); + } + + pm_arguments_node_t *arguments = pm_arguments_node_create(parser); + pm_arguments_node_arguments_append( + arguments, + (pm_node_t *) pm_global_variable_read_node_synthesized_create(parser, pm_parser_constant_id_constant(parser, "$_", 2)) + ); + + pm_statements_node_body_append(parser, statements, (pm_node_t *) pm_call_node_fcall_synthesized_create( + parser, + arguments, + pm_parser_constant_id_constant(parser, "print", 5) + ), true); + } + + if (PM_PARSER_COMMAND_LINE_OPTION_N(parser)) { + if (PM_PARSER_COMMAND_LINE_OPTION_A(parser)) { + if (statements == NULL) { + statements = pm_statements_node_create(parser); + } + + pm_arguments_node_t *arguments = pm_arguments_node_create(parser); + pm_arguments_node_arguments_append( + arguments, + (pm_node_t *) pm_global_variable_read_node_synthesized_create(parser, pm_parser_constant_id_constant(parser, "$;", 2)) + ); + + pm_global_variable_read_node_t *receiver = pm_global_variable_read_node_synthesized_create(parser, pm_parser_constant_id_constant(parser, "$_", 2)); + pm_call_node_t *call = pm_call_node_call_synthesized_create(parser, (pm_node_t *) receiver, "split", arguments); + + pm_global_variable_write_node_t *write = pm_global_variable_write_node_synthesized_create( + parser, + pm_parser_constant_id_constant(parser, "$F", 2), + (pm_node_t *) call + ); + + pm_statements_node_body_prepend(statements, (pm_node_t *) write); + } + + pm_arguments_node_t *arguments = pm_arguments_node_create(parser); + pm_arguments_node_arguments_append( + arguments, + (pm_node_t *) pm_global_variable_read_node_synthesized_create(parser, pm_parser_constant_id_constant(parser, "$/", 2)) + ); + + if (PM_PARSER_COMMAND_LINE_OPTION_L(parser)) { + pm_keyword_hash_node_t *keywords = pm_keyword_hash_node_create(parser); + pm_keyword_hash_node_elements_append(keywords, (pm_node_t *) pm_assoc_node_create( + parser, + (pm_node_t *) pm_symbol_node_synthesized_create(parser, "chomp"), + &(pm_token_t) { .type = PM_TOKEN_NOT_PROVIDED, .start = parser->start, .end = parser->start }, + (pm_node_t *) pm_true_node_synthesized_create(parser) + )); + + pm_arguments_node_arguments_append(arguments, (pm_node_t *) keywords); + pm_node_flag_set((pm_node_t *) arguments, PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORDS); + } + + pm_statements_node_t *wrapped_statements = pm_statements_node_create(parser); + pm_statements_node_body_append(parser, wrapped_statements, (pm_node_t *) pm_while_node_synthesized_create( + parser, + (pm_node_t *) pm_call_node_fcall_synthesized_create(parser, arguments, pm_parser_constant_id_constant(parser, "gets", 4)), + statements + ), true); + + statements = wrapped_statements; + } + + return statements; +} + +/** + * Parse the top-level program node. + */ +static pm_node_t * +parse_program(pm_parser_t *parser) { + // If the current scope is NULL, then we want to push a new top level scope. + // The current scope could exist in the event that we are parsing an eval + // and the user has passed into scopes that already exist. + if (parser->current_scope == NULL) { + pm_parser_scope_push(parser, true); + } + + pm_node_list_t current_block_exits = { 0 }; + pm_node_list_t *previous_block_exits = push_block_exits(parser, ¤t_block_exits); + + parser_lex(parser); + pm_statements_node_t *statements = parse_statements(parser, PM_CONTEXT_MAIN, 0); + + if (statements != NULL && !parser->parsing_eval) { + // If we have statements, then the top-level statement should be + // explicitly checked as well. We have to do this here because + // everywhere else we check all but the last statement. + assert(statements->body.size > 0); + pm_void_statement_check(parser, statements->body.nodes[statements->body.size - 1]); + } + + pm_constant_id_list_t locals; + pm_locals_order(parser, &parser->current_scope->locals, &locals, true); + pm_parser_scope_pop(parser); + + // At the top level, see if we need to wrap the statements in a program + // node with a while loop based on the options. + if (parser->command_line & (PM_OPTIONS_COMMAND_LINE_P | PM_OPTIONS_COMMAND_LINE_N)) { + statements = wrap_statements(parser, statements); + } else { + flush_block_exits(parser, previous_block_exits); + pm_node_list_free(¤t_block_exits); + } + + // If this is an empty file, then we're still going to parse all of the + // statements in order to gather up all of the comments and such. Here we'll + // correct the location information. + if (statements == NULL) { + statements = pm_statements_node_create(parser); + pm_statements_node_location_set(statements, parser->start, parser->start); + } + + return (pm_node_t *) pm_program_node_create(parser, &locals, statements); +} + +/******************************************************************************/ +/* External functions */ +/******************************************************************************/ + +/** + * A vendored version of strnstr that is used to find a substring within a + * string with a given length. This function is used to search for the Ruby + * engine name within a shebang when the -x option is passed to Ruby. + * + * The only modification that we made here is that we don't do NULL byte checks + * because we know the little parameter will not have a NULL byte and we allow + * the big parameter to have them. + */ +static const char * +pm_strnstr(const char *big, const char *little, size_t big_length) { + size_t little_length = strlen(little); + + for (const char *big_end = big + big_length; big < big_end; big++) { + if (*big == *little && memcmp(big, little, little_length) == 0) return big; + } + + return NULL; +} + +#ifdef _WIN32 +#define pm_parser_warn_shebang_carriage_return(parser, start, length) ((void) 0) +#else +/** + * Potentially warn the user if the shebang that has been found to include + * "ruby" has a carriage return at the end, as that can cause problems on some + * platforms. + */ +static void +pm_parser_warn_shebang_carriage_return(pm_parser_t *parser, const uint8_t *start, size_t length) { + if (length > 2 && start[length - 2] == '\r' && start[length - 1] == '\n') { + pm_parser_warn(parser, start, start + length, PM_WARN_SHEBANG_CARRIAGE_RETURN); + } +} +#endif + +/** + * Process the shebang when initializing the parser. This function assumes that + * the shebang_callback option has already been checked for nullability. + */ +static void +pm_parser_init_shebang(pm_parser_t *parser, const pm_options_t *options, const char *engine, size_t length) { + const char *switches = pm_strnstr(engine, " -", length); + if (switches == NULL) return; + + pm_options_t next_options = *options; + options->shebang_callback( + &next_options, + (const uint8_t *) (switches + 1), + length - ((size_t) (switches - engine)) - 1, + options->shebang_callback_data + ); + + size_t encoding_length; + if ((encoding_length = pm_string_length(&next_options.encoding)) > 0) { + const uint8_t *encoding_source = pm_string_source(&next_options.encoding); + parser_lex_magic_comment_encoding_value(parser, encoding_source, encoding_source + encoding_length); + } + + parser->command_line = next_options.command_line; + parser->frozen_string_literal = next_options.frozen_string_literal; +} + +/** + * Initialize a parser with the given start and end pointers. + */ +PRISM_EXPORTED_FUNCTION void +pm_parser_init(pm_parser_t *parser, const uint8_t *source, size_t size, const pm_options_t *options) { + assert(source != NULL); + + *parser = (pm_parser_t) { + .node_id = 0, + .lex_state = PM_LEX_STATE_BEG, + .enclosure_nesting = 0, + .lambda_enclosure_nesting = -1, + .brace_nesting = 0, + .do_loop_stack = 0, + .accepts_block_stack = 0, + .lex_modes = { + .index = 0, + .stack = {{ .mode = PM_LEX_DEFAULT }}, + .current = &parser->lex_modes.stack[0], + }, + .start = source, + .end = source + size, + .previous = { .type = PM_TOKEN_EOF, .start = source, .end = source }, + .current = { .type = PM_TOKEN_EOF, .start = source, .end = source }, + .next_start = NULL, + .heredoc_end = NULL, + .data_loc = { .start = NULL, .end = NULL }, + .comment_list = { 0 }, + .magic_comment_list = { 0 }, + .warning_list = { 0 }, + .error_list = { 0 }, + .current_scope = NULL, + .current_context = NULL, + .encoding = PM_ENCODING_UTF_8_ENTRY, + .encoding_changed_callback = NULL, + .encoding_comment_start = source, + .lex_callback = NULL, + .filepath = { 0 }, + .constant_pool = { 0 }, + .newline_list = { 0 }, + .integer_base = 0, + .current_string = PM_STRING_EMPTY, + .start_line = 1, + .explicit_encoding = NULL, + .command_line = 0, + .parsing_eval = false, + .partial_script = false, + .command_start = true, + .recovering = false, + .encoding_locked = false, + .encoding_changed = false, + .pattern_matching_newlines = false, + .in_keyword_arg = false, + .current_block_exits = NULL, + .semantic_token_seen = false, + .frozen_string_literal = PM_OPTIONS_FROZEN_STRING_LITERAL_UNSET, + .current_regular_expression_ascii_only = false, + .warn_mismatched_indentation = true + }; + + // Initialize the constant pool. We're going to completely guess as to the + // number of constants that we'll need based on the size of the input. The + // ratio we chose here is actually less arbitrary than you might think. + // + // We took ~50K Ruby files and measured the size of the file versus the + // number of constants that were found in those files. Then we found the + // average and standard deviation of the ratios of constants/bytesize. Then + // we added 1.34 standard deviations to the average to get a ratio that + // would fit 75% of the files (for a two-tailed distribution). This works + // because there was about a 0.77 correlation and the distribution was + // roughly normal. + // + // This ratio will need to change if we add more constants to the constant + // pool for another node type. + uint32_t constant_size = ((uint32_t) size) / 95; + pm_constant_pool_init(&parser->constant_pool, constant_size < 4 ? 4 : constant_size); + + // Initialize the newline list. Similar to the constant pool, we're going to + // guess at the number of newlines that we'll need based on the size of the + // input. + size_t newline_size = size / 22; + pm_newline_list_init(&parser->newline_list, source, newline_size < 4 ? 4 : newline_size); + + // If options were provided to this parse, establish them here. + if (options != NULL) { + // filepath option + parser->filepath = options->filepath; + + // line option + parser->start_line = options->line; + + // encoding option + size_t encoding_length = pm_string_length(&options->encoding); + if (encoding_length > 0) { + const uint8_t *encoding_source = pm_string_source(&options->encoding); + parser_lex_magic_comment_encoding_value(parser, encoding_source, encoding_source + encoding_length); + } + + // encoding_locked option + parser->encoding_locked = options->encoding_locked; + + // frozen_string_literal option + parser->frozen_string_literal = options->frozen_string_literal; + + // command_line option + parser->command_line = options->command_line; + + // version option + parser->version = options->version; + + // partial_script + parser->partial_script = options->partial_script; + + // scopes option + parser->parsing_eval = options->scopes_count > 0; + if (parser->parsing_eval) parser->warn_mismatched_indentation = false; + + for (size_t scope_index = 0; scope_index < options->scopes_count; scope_index++) { + const pm_options_scope_t *scope = pm_options_scope_get(options, scope_index); + pm_parser_scope_push(parser, scope_index == 0); + + // Scopes given from the outside are not allowed to have numbered + // parameters. + parser->current_scope->parameters = ((pm_scope_parameters_t) scope->forwarding) | PM_SCOPE_PARAMETERS_IMPLICIT_DISALLOWED; + + for (size_t local_index = 0; local_index < scope->locals_count; local_index++) { + const pm_string_t *local = pm_options_scope_local_get(scope, local_index); + + const uint8_t *source = pm_string_source(local); + size_t length = pm_string_length(local); + + void *allocated = xmalloc(length); + if (allocated == NULL) continue; + + memcpy(allocated, source, length); + pm_parser_local_add_owned(parser, (uint8_t *) allocated, length); + } + } + } + + pm_accepts_block_stack_push(parser, true); + + // Skip past the UTF-8 BOM if it exists. + if (size >= 3 && source[0] == 0xef && source[1] == 0xbb && source[2] == 0xbf) { + parser->current.end += 3; + parser->encoding_comment_start += 3; + + if (parser->encoding != PM_ENCODING_UTF_8_ENTRY) { + parser->encoding = PM_ENCODING_UTF_8_ENTRY; + if (parser->encoding_changed_callback != NULL) parser->encoding_changed_callback(parser); + } + } + + // If the -x command line flag is set, or the first shebang of the file does + // not include "ruby", then we'll search for a shebang that does include + // "ruby" and start parsing from there. + bool search_shebang = PM_PARSER_COMMAND_LINE_OPTION_X(parser); + + // If the first two bytes of the source are a shebang, then we will do a bit + // of extra processing. + // + // First, we'll indicate that the encoding comment is at the end of the + // shebang. This means that when a shebang is present the encoding comment + // can begin on the second line. + // + // Second, we will check if the shebang includes "ruby". If it does, then we + // we will start parsing from there. We will also potentially warning the + // user if there is a carriage return at the end of the shebang. We will + // also potentially call the shebang callback if this is the main script to + // allow the caller to parse the shebang and find any command-line options. + // If the shebang does not include "ruby" and this is the main script being + // parsed, then we will start searching the file for a shebang that does + // contain "ruby" as if -x were passed on the command line. + const uint8_t *newline = next_newline(parser->start, parser->end - parser->start); + size_t length = (size_t) ((newline != NULL ? newline : parser->end) - parser->start); + + if (length > 2 && parser->current.end[0] == '#' && parser->current.end[1] == '!') { + const char *engine; + + if ((engine = pm_strnstr((const char *) parser->start, "ruby", length)) != NULL) { + if (newline != NULL) { + parser->encoding_comment_start = newline + 1; + + if (options == NULL || options->main_script) { + pm_parser_warn_shebang_carriage_return(parser, parser->start, length + 1); + } + } + + if (options != NULL && options->main_script && options->shebang_callback != NULL) { + pm_parser_init_shebang(parser, options, engine, length - ((size_t) (engine - (const char *) parser->start))); + } + + search_shebang = false; + } else if (options->main_script && !parser->parsing_eval) { + search_shebang = true; + } + } + + // Here we're going to find the first shebang that includes "ruby" and start + // parsing from there. + if (search_shebang) { + // If a shebang that includes "ruby" is not found, then we're going to a + // a load error to the list of errors on the parser. + bool found_shebang = false; + + // This is going to point to the start of each line as we check it. + // We'll maintain a moving window looking at each line at they come. + const uint8_t *cursor = parser->start; + + // The newline pointer points to the end of the current line that we're + // considering. If it is NULL, then we're at the end of the file. + const uint8_t *newline = next_newline(cursor, parser->end - cursor); + + while (newline != NULL) { + pm_newline_list_append(&parser->newline_list, newline); + + cursor = newline + 1; + newline = next_newline(cursor, parser->end - cursor); + + size_t length = (size_t) ((newline != NULL ? newline : parser->end) - cursor); + if (length > 2 && cursor[0] == '#' && cursor[1] == '!') { + const char *engine; + if ((engine = pm_strnstr((const char *) cursor, "ruby", length)) != NULL) { + found_shebang = true; + + if (newline != NULL) { + pm_parser_warn_shebang_carriage_return(parser, cursor, length + 1); + parser->encoding_comment_start = newline + 1; + } + + if (options != NULL && options->shebang_callback != NULL) { + pm_parser_init_shebang(parser, options, engine, length - ((size_t) (engine - (const char *) cursor))); + } + + break; + } + } + } + + if (found_shebang) { + parser->previous = (pm_token_t) { .type = PM_TOKEN_EOF, .start = cursor, .end = cursor }; + parser->current = (pm_token_t) { .type = PM_TOKEN_EOF, .start = cursor, .end = cursor }; + } else { + pm_parser_err(parser, parser->start, parser->start, PM_ERR_SCRIPT_NOT_FOUND); + pm_newline_list_clear(&parser->newline_list); + } + } + + // The encoding comment can start after any amount of inline whitespace, so + // here we'll advance it to the first non-inline-whitespace character so + // that it is ready for future comparisons. + parser->encoding_comment_start += pm_strspn_inline_whitespace(parser->encoding_comment_start, parser->end - parser->encoding_comment_start); +} + +/** + * Register a callback that will be called whenever prism changes the encoding + * it is using to parse based on the magic comment. + */ +PRISM_EXPORTED_FUNCTION void +pm_parser_register_encoding_changed_callback(pm_parser_t *parser, pm_encoding_changed_callback_t callback) { + parser->encoding_changed_callback = callback; +} + +/** + * Free all of the memory associated with the comment list. + */ +static inline void +pm_comment_list_free(pm_list_t *list) { + pm_list_node_t *node, *next; + + for (node = list->head; node != NULL; node = next) { + next = node->next; + + pm_comment_t *comment = (pm_comment_t *) node; + xfree(comment); + } +} + +/** + * Free all of the memory associated with the magic comment list. + */ +static inline void +pm_magic_comment_list_free(pm_list_t *list) { + pm_list_node_t *node, *next; + + for (node = list->head; node != NULL; node = next) { + next = node->next; + + pm_magic_comment_t *magic_comment = (pm_magic_comment_t *) node; + xfree(magic_comment); + } +} + +/** + * Free any memory associated with the given parser. + */ +PRISM_EXPORTED_FUNCTION void +pm_parser_free(pm_parser_t *parser) { + pm_string_free(&parser->filepath); + pm_diagnostic_list_free(&parser->error_list); + pm_diagnostic_list_free(&parser->warning_list); + pm_comment_list_free(&parser->comment_list); + pm_magic_comment_list_free(&parser->magic_comment_list); + pm_constant_pool_free(&parser->constant_pool); + pm_newline_list_free(&parser->newline_list); + + while (parser->current_scope != NULL) { + // Normally, popping the scope doesn't free the locals since it is + // assumed that ownership has transferred to the AST. However if we have + // scopes while we're freeing the parser, it's likely they came from + // eval scopes and we need to free them explicitly here. + pm_parser_scope_pop(parser); + } + + while (parser->lex_modes.index >= PM_LEX_STACK_SIZE) { + lex_mode_pop(parser); + } +} + +/** + * Parse the Ruby source associated with the given parser and return the tree. + */ +PRISM_EXPORTED_FUNCTION pm_node_t * +pm_parse(pm_parser_t *parser) { + return parse_program(parser); +} + +/** + * Read into the stream until the gets callback returns false. If the last read + * line from the stream matches an __END__ marker, then halt and return false, + * otherwise return true. + */ +static bool +pm_parse_stream_read(pm_buffer_t *buffer, void *stream, pm_parse_stream_fgets_t *stream_fgets) { +#define LINE_SIZE 4096 + char line[LINE_SIZE]; + + while (memset(line, '\n', LINE_SIZE), stream_fgets(line, LINE_SIZE, stream) != NULL) { + size_t length = LINE_SIZE; + while (length > 0 && line[length - 1] == '\n') length--; + + if (length == LINE_SIZE) { + // If we read a line that is the maximum size and it doesn't end + // with a newline, then we'll just append it to the buffer and + // continue reading. + length--; + pm_buffer_append_string(buffer, line, length); + continue; + } + + // Append the line to the buffer. + length--; + pm_buffer_append_string(buffer, line, length); + + // Check if the line matches the __END__ marker. If it does, then stop + // reading and return false. In most circumstances, this means we should + // stop reading from the stream so that the DATA constant can pick it + // up. + switch (length) { + case 7: + if (strncmp(line, "__END__", 7) == 0) return false; + break; + case 8: + if (strncmp(line, "__END__\n", 8) == 0) return false; + break; + case 9: + if (strncmp(line, "__END__\r\n", 9) == 0) return false; + break; + } + } + + return true; +#undef LINE_SIZE +} + +/** + * Determine if there was an unterminated heredoc at the end of the input, which + * would mean the stream isn't finished and we should keep reading. + * + * For the other lex modes we can check if the lex mode has been closed, but for + * heredocs when we hit EOF we close the lex mode and then go back to parse the + * rest of the line after the heredoc declaration so that we get more of the + * syntax tree. + */ +static bool +pm_parse_stream_unterminated_heredoc_p(pm_parser_t *parser) { + pm_diagnostic_t *diagnostic = (pm_diagnostic_t *) parser->error_list.head; + + for (; diagnostic != NULL; diagnostic = (pm_diagnostic_t *) diagnostic->node.next) { + if (diagnostic->diag_id == PM_ERR_HEREDOC_TERM) { + return true; + } + } + + return false; +} + +/** + * Parse a stream of Ruby source and return the tree. + * + * Prism is designed around having the entire source in memory at once, but you + * can stream stdin in to Ruby so we need to support a streaming API. + */ +PRISM_EXPORTED_FUNCTION pm_node_t * +pm_parse_stream(pm_parser_t *parser, pm_buffer_t *buffer, void *stream, pm_parse_stream_fgets_t *stream_fgets, const pm_options_t *options) { + pm_buffer_init(buffer); + + bool eof = pm_parse_stream_read(buffer, stream, stream_fgets); + pm_parser_init(parser, (const uint8_t *) pm_buffer_value(buffer), pm_buffer_length(buffer), options); + pm_node_t *node = pm_parse(parser); + + while (!eof && parser->error_list.size > 0 && (parser->lex_modes.index > 0 || pm_parse_stream_unterminated_heredoc_p(parser))) { + pm_node_destroy(parser, node); + eof = pm_parse_stream_read(buffer, stream, stream_fgets); + + pm_parser_free(parser); + pm_parser_init(parser, (const uint8_t *) pm_buffer_value(buffer), pm_buffer_length(buffer), options); + node = pm_parse(parser); + } + + return node; +} + +/** + * Parse the source and return true if it parses without errors or warnings. + */ +PRISM_EXPORTED_FUNCTION bool +pm_parse_success_p(const uint8_t *source, size_t size, const char *data) { + pm_options_t options = { 0 }; + pm_options_read(&options, data); + + pm_parser_t parser; + pm_parser_init(&parser, source, size, &options); + + pm_node_t *node = pm_parse(&parser); + pm_node_destroy(&parser, node); + + bool result = parser.error_list.size == 0; + pm_parser_free(&parser); + pm_options_free(&options); + + return result; +} + +#undef PM_CASE_KEYWORD +#undef PM_CASE_OPERATOR +#undef PM_CASE_WRITABLE +#undef PM_STRING_EMPTY +#undef PM_LOCATION_NODE_BASE_VALUE +#undef PM_LOCATION_NODE_VALUE +#undef PM_LOCATION_NULL_VALUE +#undef PM_LOCATION_TOKEN_VALUE + +// We optionally support serializing to a binary string. For systems that don't +// want or need this functionality, it can be turned off with the +// PRISM_EXCLUDE_SERIALIZATION define. +#ifndef PRISM_EXCLUDE_SERIALIZATION + +static inline void +pm_serialize_header(pm_buffer_t *buffer) { + pm_buffer_append_string(buffer, "PRISM", 5); + pm_buffer_append_byte(buffer, PRISM_VERSION_MAJOR); + pm_buffer_append_byte(buffer, PRISM_VERSION_MINOR); + pm_buffer_append_byte(buffer, PRISM_VERSION_PATCH); + pm_buffer_append_byte(buffer, PRISM_SERIALIZE_ONLY_SEMANTICS_FIELDS ? 1 : 0); +} + +/** + * Serialize the AST represented by the given node to the given buffer. + */ +PRISM_EXPORTED_FUNCTION void +pm_serialize(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) { + pm_serialize_header(buffer); + pm_serialize_content(parser, node, buffer); + pm_buffer_append_byte(buffer, '\0'); +} + +/** + * Parse and serialize the AST represented by the given source to the given + * buffer. + */ +PRISM_EXPORTED_FUNCTION void +pm_serialize_parse(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data) { + pm_options_t options = { 0 }; + pm_options_read(&options, data); + + pm_parser_t parser; + pm_parser_init(&parser, source, size, &options); + + pm_node_t *node = pm_parse(&parser); + + pm_serialize_header(buffer); + pm_serialize_content(&parser, node, buffer); + pm_buffer_append_byte(buffer, '\0'); + + pm_node_destroy(&parser, node); + pm_parser_free(&parser); + pm_options_free(&options); +} + +/** + * Parse and serialize the AST represented by the source that is read out of the + * given stream into to the given buffer. + */ +PRISM_EXPORTED_FUNCTION void +pm_serialize_parse_stream(pm_buffer_t *buffer, void *stream, pm_parse_stream_fgets_t *stream_fgets, const char *data) { + pm_parser_t parser; + pm_options_t options = { 0 }; + pm_options_read(&options, data); + + pm_buffer_t parser_buffer; + pm_node_t *node = pm_parse_stream(&parser, &parser_buffer, stream, stream_fgets, &options); + pm_serialize_header(buffer); + pm_serialize_content(&parser, node, buffer); + pm_buffer_append_byte(buffer, '\0'); + + pm_node_destroy(&parser, node); + pm_buffer_free(&parser_buffer); + pm_parser_free(&parser); + pm_options_free(&options); +} + +/** + * Parse and serialize the comments in the given source to the given buffer. + */ +PRISM_EXPORTED_FUNCTION void +pm_serialize_parse_comments(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data) { + pm_options_t options = { 0 }; + pm_options_read(&options, data); + + pm_parser_t parser; + pm_parser_init(&parser, source, size, &options); + + pm_node_t *node = pm_parse(&parser); + pm_serialize_header(buffer); + pm_serialize_encoding(parser.encoding, buffer); + pm_buffer_append_varsint(buffer, parser.start_line); + pm_serialize_comment_list(&parser, &parser.comment_list, buffer); + + pm_node_destroy(&parser, node); + pm_parser_free(&parser); + pm_options_free(&options); +} + +#endif + +/******************************************************************************/ +/* Slice queries for the Ruby API */ +/******************************************************************************/ + +/** The category of slice returned from pm_slice_type. */ +typedef enum { + /** Returned when the given encoding name is invalid. */ + PM_SLICE_TYPE_ERROR = -1, + + /** Returned when no other types apply to the slice. */ + PM_SLICE_TYPE_NONE, + + /** Returned when the slice is a valid local variable name. */ + PM_SLICE_TYPE_LOCAL, + + /** Returned when the slice is a valid constant name. */ + PM_SLICE_TYPE_CONSTANT, + + /** Returned when the slice is a valid method name. */ + PM_SLICE_TYPE_METHOD_NAME +} pm_slice_type_t; + +/** + * Check that the slice is a valid local variable name or constant. + */ +pm_slice_type_t +pm_slice_type(const uint8_t *source, size_t length, const char *encoding_name) { + // first, get the right encoding object + const pm_encoding_t *encoding = pm_encoding_find((const uint8_t *) encoding_name, (const uint8_t *) (encoding_name + strlen(encoding_name))); + if (encoding == NULL) return PM_SLICE_TYPE_ERROR; + + // check that there is at least one character + if (length == 0) return PM_SLICE_TYPE_NONE; + + size_t width; + if ((width = encoding->alpha_char(source, (ptrdiff_t) length)) != 0) { + // valid because alphabetical + } else if (*source == '_') { + // valid because underscore + width = 1; + } else if ((*source >= 0x80) && ((width = encoding->char_width(source, (ptrdiff_t) length)) > 0)) { + // valid because multibyte + } else { + // invalid because no match + return PM_SLICE_TYPE_NONE; + } + + // determine the type of the slice based on the first character + const uint8_t *end = source + length; + pm_slice_type_t result = encoding->isupper_char(source, end - source) ? PM_SLICE_TYPE_CONSTANT : PM_SLICE_TYPE_LOCAL; + + // next, iterate through all of the bytes of the string to ensure that they + // are all valid identifier characters + source += width; + + while (source < end) { + if ((width = encoding->alnum_char(source, end - source)) != 0) { + // valid because alphanumeric + source += width; + } else if (*source == '_') { + // valid because underscore + source++; + } else if ((*source >= 0x80) && ((width = encoding->char_width(source, end - source)) > 0)) { + // valid because multibyte + source += width; + } else { + // invalid because no match + break; + } + } + + // accept a ! or ? at the end of the slice as a method name + if (*source == '!' || *source == '?' || *source == '=') { + source++; + result = PM_SLICE_TYPE_METHOD_NAME; + } + + // valid if we are at the end of the slice + return source == end ? result : PM_SLICE_TYPE_NONE; +} + +/** + * Check that the slice is a valid local variable name. + */ +PRISM_EXPORTED_FUNCTION pm_string_query_t +pm_string_query_local(const uint8_t *source, size_t length, const char *encoding_name) { + switch (pm_slice_type(source, length, encoding_name)) { + case PM_SLICE_TYPE_ERROR: + return PM_STRING_QUERY_ERROR; + case PM_SLICE_TYPE_NONE: + case PM_SLICE_TYPE_CONSTANT: + case PM_SLICE_TYPE_METHOD_NAME: + return PM_STRING_QUERY_FALSE; + case PM_SLICE_TYPE_LOCAL: + return PM_STRING_QUERY_TRUE; + } + + assert(false && "unreachable"); + return PM_STRING_QUERY_FALSE; +} + +/** + * Check that the slice is a valid constant name. + */ +PRISM_EXPORTED_FUNCTION pm_string_query_t +pm_string_query_constant(const uint8_t *source, size_t length, const char *encoding_name) { + switch (pm_slice_type(source, length, encoding_name)) { + case PM_SLICE_TYPE_ERROR: + return PM_STRING_QUERY_ERROR; + case PM_SLICE_TYPE_NONE: + case PM_SLICE_TYPE_LOCAL: + case PM_SLICE_TYPE_METHOD_NAME: + return PM_STRING_QUERY_FALSE; + case PM_SLICE_TYPE_CONSTANT: + return PM_STRING_QUERY_TRUE; + } + + assert(false && "unreachable"); + return PM_STRING_QUERY_FALSE; +} + +/** + * Check that the slice is a valid method name. + */ +PRISM_EXPORTED_FUNCTION pm_string_query_t +pm_string_query_method_name(const uint8_t *source, size_t length, const char *encoding_name) { +#define B(p) ((p) ? PM_STRING_QUERY_TRUE : PM_STRING_QUERY_FALSE) +#define C1(c) (*source == c) +#define C2(s) (memcmp(source, s, 2) == 0) +#define C3(s) (memcmp(source, s, 3) == 0) + + switch (pm_slice_type(source, length, encoding_name)) { + case PM_SLICE_TYPE_ERROR: + return PM_STRING_QUERY_ERROR; + case PM_SLICE_TYPE_NONE: + break; + case PM_SLICE_TYPE_LOCAL: + // numbered parameters are not valid method names + return B((length != 2) || (source[0] != '_') || (source[1] == '0') || !pm_char_is_decimal_digit(source[1])); + case PM_SLICE_TYPE_CONSTANT: + // all constants are valid method names + case PM_SLICE_TYPE_METHOD_NAME: + // all method names are valid method names + return PM_STRING_QUERY_TRUE; + } + + switch (length) { + case 1: + return B(C1('&') || C1('`') || C1('!') || C1('^') || C1('>') || C1('<') || C1('-') || C1('%') || C1('|') || C1('+') || C1('/') || C1('*') || C1('~')); + case 2: + return B(C2("!=") || C2("!~") || C2("[]") || C2("==") || C2("=~") || C2(">=") || C2(">>") || C2("<=") || C2("<<") || C2("**")); + case 3: + return B(C3("===") || C3("<=>") || C3("[]=")); + default: + return PM_STRING_QUERY_FALSE; + } + +#undef B +#undef C1 +#undef C2 +#undef C3 +} diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/regexp.c b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/regexp.c new file mode 100644 index 00000000..dcc74762 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/regexp.c @@ -0,0 +1,790 @@ +#include "prism/regexp.h" + +#define PM_REGEXP_PARSE_DEPTH_MAX 4096 + +/** + * This is the parser that is going to handle parsing regular expressions. + */ +typedef struct { + /** The parser that is currently being used. */ + pm_parser_t *parser; + + /** A pointer to the start of the source that we are parsing. */ + const uint8_t *start; + + /** A pointer to the current position in the source. */ + const uint8_t *cursor; + + /** A pointer to the end of the source that we are parsing. */ + const uint8_t *end; + + /** + * Whether or not the regular expression currently being parsed is in + * extended mode, wherein whitespace is ignored and comments are allowed. + */ + bool extended_mode; + + /** Whether the encoding has changed from the default. */ + bool encoding_changed; + + /** The encoding of the source. */ + const pm_encoding_t *encoding; + + /** The callback to call when a named capture group is found. */ + pm_regexp_name_callback_t name_callback; + + /** The data to pass to the name callback. */ + void *name_data; + + /** The callback to call when a parse error is found. */ + pm_regexp_error_callback_t error_callback; + + /** The data to pass to the error callback. */ + void *error_data; +} pm_regexp_parser_t; + +/** + * Append an error to the parser. + */ +static inline void +pm_regexp_parse_error(pm_regexp_parser_t *parser, const uint8_t *start, const uint8_t *end, const char *message) { + parser->error_callback(start, end, message, parser->error_data); +} + +/** + * This appends a new string to the list of named captures. This function + * assumes the caller has already checked the validity of the name callback. + */ +static void +pm_regexp_parser_named_capture(pm_regexp_parser_t *parser, const uint8_t *start, const uint8_t *end) { + pm_string_t string; + pm_string_shared_init(&string, start, end); + parser->name_callback(&string, parser->name_data); + pm_string_free(&string); +} + +/** + * Returns true if the next character is the end of the source. + */ +static inline bool +pm_regexp_char_is_eof(pm_regexp_parser_t *parser) { + return parser->cursor >= parser->end; +} + +/** + * Optionally accept a char and consume it if it exists. + */ +static inline bool +pm_regexp_char_accept(pm_regexp_parser_t *parser, uint8_t value) { + if (!pm_regexp_char_is_eof(parser) && *parser->cursor == value) { + parser->cursor++; + return true; + } + return false; +} + +/** + * Expect a character to be present and consume it. + */ +static inline bool +pm_regexp_char_expect(pm_regexp_parser_t *parser, uint8_t value) { + if (!pm_regexp_char_is_eof(parser) && *parser->cursor == value) { + parser->cursor++; + return true; + } + return false; +} + +/** + * This advances the current token to the next instance of the given character. + */ +static bool +pm_regexp_char_find(pm_regexp_parser_t *parser, uint8_t value) { + if (pm_regexp_char_is_eof(parser)) { + return false; + } + + const uint8_t *end = (const uint8_t *) pm_memchr(parser->cursor, value, (size_t) (parser->end - parser->cursor), parser->encoding_changed, parser->encoding); + if (end == NULL) { + return false; + } + + parser->cursor = end + 1; + return true; +} + +/** + * Range quantifiers are a special class of quantifiers that look like + * + * * {digit} + * * {digit,} + * * {digit,digit} + * * {,digit} + * + * Unfortunately, if there are any spaces in between, then this just becomes a + * regular character match expression and we have to backtrack. So when this + * function first starts running, we'll create a "save" point and then attempt + * to parse the quantifier. If it fails, we'll restore the save point and + * return. + * + * The properly track everything, we're going to build a little state machine. + * It looks something like the following: + * + * +-------+ +---------+ ------------+ + * ---- lbrace ---> | start | ---- digit ---> | minimum | | + * +-------+ +---------+ <--- digit -+ + * | | | + * +-------+ | | rbrace + * | comma | <----- comma +---- comma -------+ | + * +-------+ V V + * | +---------+ +---------+ + * +-- digit --> | maximum | -- rbrace --> || final || + * +---------+ +---------+ + * | ^ + * +- digit -+ + * + * Note that by the time we've hit this function, the lbrace has already been + * consumed so we're in the start state. + */ +static bool +pm_regexp_parse_range_quantifier(pm_regexp_parser_t *parser) { + const uint8_t *savepoint = parser->cursor; + + enum { + PM_REGEXP_RANGE_QUANTIFIER_STATE_START, + PM_REGEXP_RANGE_QUANTIFIER_STATE_MINIMUM, + PM_REGEXP_RANGE_QUANTIFIER_STATE_MAXIMUM, + PM_REGEXP_RANGE_QUANTIFIER_STATE_COMMA + } state = PM_REGEXP_RANGE_QUANTIFIER_STATE_START; + + while (1) { + if (parser->cursor >= parser->end) { + parser->cursor = savepoint; + return true; + } + + switch (state) { + case PM_REGEXP_RANGE_QUANTIFIER_STATE_START: + switch (*parser->cursor) { + case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': + parser->cursor++; + state = PM_REGEXP_RANGE_QUANTIFIER_STATE_MINIMUM; + break; + case ',': + parser->cursor++; + state = PM_REGEXP_RANGE_QUANTIFIER_STATE_COMMA; + break; + default: + parser->cursor = savepoint; + return true; + } + break; + case PM_REGEXP_RANGE_QUANTIFIER_STATE_MINIMUM: + switch (*parser->cursor) { + case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': + parser->cursor++; + break; + case ',': + parser->cursor++; + state = PM_REGEXP_RANGE_QUANTIFIER_STATE_MAXIMUM; + break; + case '}': + parser->cursor++; + return true; + default: + parser->cursor = savepoint; + return true; + } + break; + case PM_REGEXP_RANGE_QUANTIFIER_STATE_COMMA: + switch (*parser->cursor) { + case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': + parser->cursor++; + state = PM_REGEXP_RANGE_QUANTIFIER_STATE_MAXIMUM; + break; + default: + parser->cursor = savepoint; + return true; + } + break; + case PM_REGEXP_RANGE_QUANTIFIER_STATE_MAXIMUM: + switch (*parser->cursor) { + case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': + parser->cursor++; + break; + case '}': + parser->cursor++; + return true; + default: + parser->cursor = savepoint; + return true; + } + break; + } + } + + return true; +} + +/** + * quantifier : star-quantifier + * | plus-quantifier + * | optional-quantifier + * | range-quantifier + * | + * ; + */ +static bool +pm_regexp_parse_quantifier(pm_regexp_parser_t *parser) { + while (!pm_regexp_char_is_eof(parser)) { + switch (*parser->cursor) { + case '*': + case '+': + case '?': + parser->cursor++; + break; + case '{': + parser->cursor++; + if (!pm_regexp_parse_range_quantifier(parser)) return false; + break; + default: + // In this case there is no quantifier. + return true; + } + } + + return true; +} + +/** + * match-posix-class : '[' '[' ':' '^'? CHAR+ ':' ']' ']' + * ; + */ +static bool +pm_regexp_parse_posix_class(pm_regexp_parser_t *parser) { + if (!pm_regexp_char_expect(parser, ':')) { + return false; + } + + pm_regexp_char_accept(parser, '^'); + + return ( + pm_regexp_char_find(parser, ':') && + pm_regexp_char_expect(parser, ']') && + pm_regexp_char_expect(parser, ']') + ); +} + +// Forward declaration because character sets can be nested. +static bool +pm_regexp_parse_lbracket(pm_regexp_parser_t *parser, uint16_t depth); + +/** + * match-char-set : '[' '^'? (match-range | match-char)* ']' + * ; + */ +static bool +pm_regexp_parse_character_set(pm_regexp_parser_t *parser, uint16_t depth) { + pm_regexp_char_accept(parser, '^'); + + while (!pm_regexp_char_is_eof(parser) && *parser->cursor != ']') { + switch (*parser->cursor++) { + case '[': + pm_regexp_parse_lbracket(parser, (uint16_t) (depth + 1)); + break; + case '\\': + if (!pm_regexp_char_is_eof(parser)) { + parser->cursor++; + } + break; + default: + // do nothing, we've already advanced the cursor + break; + } + } + + return pm_regexp_char_expect(parser, ']'); +} + +/** + * A left bracket can either mean a POSIX class or a character set. + */ +static bool +pm_regexp_parse_lbracket(pm_regexp_parser_t *parser, uint16_t depth) { + if (depth >= PM_REGEXP_PARSE_DEPTH_MAX) { + pm_regexp_parse_error(parser, parser->start, parser->end, "parse depth limit over"); + return false; + } + + if ((parser->cursor < parser->end) && parser->cursor[0] == ']') { + parser->cursor++; + pm_regexp_parse_error(parser, parser->cursor - 1, parser->cursor, "empty char-class"); + return true; + } + + const uint8_t *reset = parser->cursor; + + if ((parser->cursor + 2 < parser->end) && parser->cursor[0] == '[' && parser->cursor[1] == ':') { + parser->cursor++; + if (pm_regexp_parse_posix_class(parser)) return true; + + parser->cursor = reset; + } + + return pm_regexp_parse_character_set(parser, depth); +} + +// Forward declaration here since parsing groups needs to go back up the grammar +// to parse expressions within them. +static bool +pm_regexp_parse_expression(pm_regexp_parser_t *parser, uint16_t depth); + +/** + * These are the states of the options that are configurable on the regular + * expression (or from within a group). + */ +typedef enum { + PM_REGEXP_OPTION_STATE_INVALID, + PM_REGEXP_OPTION_STATE_TOGGLEABLE, + PM_REGEXP_OPTION_STATE_ADDABLE, + PM_REGEXP_OPTION_STATE_ADDED, + PM_REGEXP_OPTION_STATE_REMOVED +} pm_regexp_option_state_t; + +// These are the options that are configurable on the regular expression (or +// from within a group). + +#define PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM 'a' +#define PRISM_REGEXP_OPTION_STATE_SLOT_MAXIMUM 'x' +#define PRISM_REGEXP_OPTION_STATE_SLOTS (PRISM_REGEXP_OPTION_STATE_SLOT_MAXIMUM - PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM + 1) + +/** + * This is the set of options that are configurable on the regular expression. + */ +typedef struct { + /** The current state of each option. */ + uint8_t values[PRISM_REGEXP_OPTION_STATE_SLOTS]; +} pm_regexp_options_t; + +/** + * Initialize a new set of options to their default values. + */ +static void +pm_regexp_options_init(pm_regexp_options_t *options) { + memset(options, PM_REGEXP_OPTION_STATE_INVALID, sizeof(uint8_t) * PRISM_REGEXP_OPTION_STATE_SLOTS); + options->values['i' - PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM] = PM_REGEXP_OPTION_STATE_TOGGLEABLE; + options->values['m' - PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM] = PM_REGEXP_OPTION_STATE_TOGGLEABLE; + options->values['x' - PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM] = PM_REGEXP_OPTION_STATE_TOGGLEABLE; + options->values['d' - PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM] = PM_REGEXP_OPTION_STATE_ADDABLE; + options->values['a' - PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM] = PM_REGEXP_OPTION_STATE_ADDABLE; + options->values['u' - PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM] = PM_REGEXP_OPTION_STATE_ADDABLE; +} + +/** + * Attempt to add the given option to the set of options. Returns true if it was + * added, false if it was already present. + */ +static bool +pm_regexp_options_add(pm_regexp_options_t *options, uint8_t key) { + if (key >= PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM && key <= PRISM_REGEXP_OPTION_STATE_SLOT_MAXIMUM) { + key = (uint8_t) (key - PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM); + + switch (options->values[key]) { + case PM_REGEXP_OPTION_STATE_INVALID: + case PM_REGEXP_OPTION_STATE_REMOVED: + return false; + case PM_REGEXP_OPTION_STATE_TOGGLEABLE: + case PM_REGEXP_OPTION_STATE_ADDABLE: + options->values[key] = PM_REGEXP_OPTION_STATE_ADDED; + return true; + case PM_REGEXP_OPTION_STATE_ADDED: + return true; + } + } + + return false; +} + +/** + * Attempt to remove the given option from the set of options. Returns true if + * it was removed, false if it was already absent. + */ +static bool +pm_regexp_options_remove(pm_regexp_options_t *options, uint8_t key) { + if (key >= PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM && key <= PRISM_REGEXP_OPTION_STATE_SLOT_MAXIMUM) { + key = (uint8_t) (key - PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM); + + switch (options->values[key]) { + case PM_REGEXP_OPTION_STATE_INVALID: + case PM_REGEXP_OPTION_STATE_ADDABLE: + return false; + case PM_REGEXP_OPTION_STATE_TOGGLEABLE: + case PM_REGEXP_OPTION_STATE_ADDED: + case PM_REGEXP_OPTION_STATE_REMOVED: + options->values[key] = PM_REGEXP_OPTION_STATE_REMOVED; + return true; + } + } + + return false; +} + +/** + * True if the given key is set in the options. + */ +static uint8_t +pm_regexp_options_state(pm_regexp_options_t *options, uint8_t key) { + if (key >= PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM && key <= PRISM_REGEXP_OPTION_STATE_SLOT_MAXIMUM) { + key = (uint8_t) (key - PRISM_REGEXP_OPTION_STATE_SLOT_MINIMUM); + return options->values[key]; + } + + return false; +} + +/** + * Groups can have quite a few different patterns for syntax. They basically + * just wrap a set of expressions, but they can potentially have options after a + * question mark. If there _isn't_ a question mark, then it's just a set of + * expressions. If there _is_, then here are the options: + * + * * (?#...) - inline comments + * * (?:subexp) - non-capturing group + * * (?=subexp) - positive lookahead + * * (?!subexp) - negative lookahead + * * (?>subexp) - atomic group + * * (?~subexp) - absence operator + * * (?<=subexp) - positive lookbehind + * * (?subexp) - named capturing group + * * (?'name'subexp) - named capturing group + * * (?(cond)yes-subexp) - conditional expression + * * (?(cond)yes-subexp|no-subexp) - conditional expression + * * (?imxdau-imx) - turn on and off configuration + * * (?imxdau-imx:subexp) - turn on and off configuration for an expression + */ +static bool +pm_regexp_parse_group(pm_regexp_parser_t *parser, uint16_t depth) { + const uint8_t *group_start = parser->cursor; + + pm_regexp_options_t options; + pm_regexp_options_init(&options); + + // First, parse any options for the group. + if (pm_regexp_char_accept(parser, '?')) { + if (pm_regexp_char_is_eof(parser)) { + pm_regexp_parse_error(parser, group_start, parser->cursor, "end pattern in group"); + return false; + } + + switch (*parser->cursor) { + case '#': { // inline comments + parser->cursor++; + if (pm_regexp_char_is_eof(parser)) { + pm_regexp_parse_error(parser, group_start, parser->cursor, "end pattern in group"); + return false; + } + + if (parser->encoding_changed && parser->encoding->multibyte) { + bool escaped = false; + + // Here we're going to take a slow path and iterate through + // each multibyte character to find the close paren. We do + // this because \ can be a trailing byte in some encodings. + while (parser->cursor < parser->end) { + if (!escaped && *parser->cursor == ')') { + parser->cursor++; + return true; + } + + size_t width = parser->encoding->char_width(parser->cursor, (ptrdiff_t) (parser->end - parser->cursor)); + if (width == 0) return false; + + escaped = (width == 1) && (*parser->cursor == '\\'); + parser->cursor += width; + } + + return false; + } else { + // Here we can take the fast path and use memchr to find the + // next ) because we are safe checking backward for \ since + // it cannot be a trailing character. + bool found = pm_regexp_char_find(parser, ')'); + + while (found && (parser->start <= parser->cursor - 2) && (*(parser->cursor - 2) == '\\')) { + found = pm_regexp_char_find(parser, ')'); + } + + return found; + } + } + case ':': // non-capturing group + case '=': // positive lookahead + case '!': // negative lookahead + case '>': // atomic group + case '~': // absence operator + parser->cursor++; + break; + case '<': + parser->cursor++; + if (pm_regexp_char_is_eof(parser)) { + pm_regexp_parse_error(parser, group_start, parser->cursor, "end pattern with unmatched parenthesis"); + return false; + } + + switch (*parser->cursor) { + case '=': // positive lookbehind + case '!': // negative lookbehind + parser->cursor++; + break; + default: { // named capture group + const uint8_t *start = parser->cursor; + if (!pm_regexp_char_find(parser, '>')) { + return false; + } + + if (parser->cursor - start == 1) { + pm_regexp_parse_error(parser, start, parser->cursor, "group name is empty"); + } + + if (parser->name_callback != NULL) { + pm_regexp_parser_named_capture(parser, start, parser->cursor - 1); + } + + break; + } + } + break; + case '\'': { // named capture group + const uint8_t *start = ++parser->cursor; + if (!pm_regexp_char_find(parser, '\'')) { + return false; + } + + if (parser->name_callback != NULL) { + pm_regexp_parser_named_capture(parser, start, parser->cursor - 1); + } + + break; + } + case '(': // conditional expression + if (!pm_regexp_char_find(parser, ')')) { + return false; + } + break; + case 'i': case 'm': case 'x': case 'd': case 'a': case 'u': // options + while (!pm_regexp_char_is_eof(parser) && *parser->cursor != '-' && *parser->cursor != ':' && *parser->cursor != ')') { + if (!pm_regexp_options_add(&options, *parser->cursor)) { + return false; + } + parser->cursor++; + } + + if (pm_regexp_char_is_eof(parser)) { + return false; + } + + // If we are at the end of the group of options and there is no + // subexpression, then we are going to be setting the options + // for the parent group. In this case we are safe to return now. + if (*parser->cursor == ')') { + if (pm_regexp_options_state(&options, 'x') == PM_REGEXP_OPTION_STATE_ADDED) { + parser->extended_mode = true; + } + + parser->cursor++; + return true; + } + + // If we hit a -, then we're done parsing options. + if (*parser->cursor != '-') break; + + PRISM_FALLTHROUGH + case '-': + parser->cursor++; + while (!pm_regexp_char_is_eof(parser) && *parser->cursor != ':' && *parser->cursor != ')') { + if (!pm_regexp_options_remove(&options, *parser->cursor)) { + return false; + } + parser->cursor++; + } + + if (pm_regexp_char_is_eof(parser)) { + return false; + } + + // If we are at the end of the group of options and there is no + // subexpression, then we are going to be setting the options + // for the parent group. In this case we are safe to return now. + if (*parser->cursor == ')') { + switch (pm_regexp_options_state(&options, 'x')) { + case PM_REGEXP_OPTION_STATE_ADDED: + parser->extended_mode = true; + break; + case PM_REGEXP_OPTION_STATE_REMOVED: + parser->extended_mode = false; + break; + } + + parser->cursor++; + return true; + } + + break; + default: + parser->cursor++; + pm_regexp_parse_error(parser, parser->cursor - 1, parser->cursor, "undefined group option"); + break; + } + } + + bool extended_mode = parser->extended_mode; + switch (pm_regexp_options_state(&options, 'x')) { + case PM_REGEXP_OPTION_STATE_ADDED: + parser->extended_mode = true; + break; + case PM_REGEXP_OPTION_STATE_REMOVED: + parser->extended_mode = false; + break; + } + + // Now, parse the expressions within this group. + while (!pm_regexp_char_is_eof(parser) && *parser->cursor != ')') { + if (!pm_regexp_parse_expression(parser, (uint16_t) (depth + 1))) { + parser->extended_mode = extended_mode; + return false; + } + pm_regexp_char_accept(parser, '|'); + } + + // Finally, make sure we have a closing parenthesis. + parser->extended_mode = extended_mode; + if (pm_regexp_char_expect(parser, ')')) return true; + + pm_regexp_parse_error(parser, group_start, parser->cursor, "end pattern with unmatched parenthesis"); + return false; +} + +/** + * item : anchor + * | match-posix-class + * | match-char-set + * | match-char-class + * | match-char-prop + * | match-char + * | match-any + * | group + * | quantified + * ; + */ +static bool +pm_regexp_parse_item(pm_regexp_parser_t *parser, uint16_t depth) { + switch (*parser->cursor) { + case '^': + case '$': + parser->cursor++; + return pm_regexp_parse_quantifier(parser); + case '\\': + parser->cursor++; + if (!pm_regexp_char_is_eof(parser)) { + parser->cursor++; + } + return pm_regexp_parse_quantifier(parser); + case '(': + parser->cursor++; + return pm_regexp_parse_group(parser, depth) && pm_regexp_parse_quantifier(parser); + case '[': + parser->cursor++; + return pm_regexp_parse_lbracket(parser, depth) && pm_regexp_parse_quantifier(parser); + case '*': + case '?': + case '+': + parser->cursor++; + pm_regexp_parse_error(parser, parser->cursor - 1, parser->cursor, "target of repeat operator is not specified"); + return true; + case ')': + parser->cursor++; + pm_regexp_parse_error(parser, parser->cursor - 1, parser->cursor, "unmatched close parenthesis"); + return true; + case '#': + if (parser->extended_mode) { + if (!pm_regexp_char_find(parser, '\n')) parser->cursor = parser->end; + return true; + } + PRISM_FALLTHROUGH + default: { + size_t width; + if (!parser->encoding_changed) { + width = pm_encoding_utf_8_char_width(parser->cursor, (ptrdiff_t) (parser->end - parser->cursor)); + } else { + width = parser->encoding->char_width(parser->cursor, (ptrdiff_t) (parser->end - parser->cursor)); + } + + if (width == 0) return false; // TODO: add appropriate error + parser->cursor += width; + + return pm_regexp_parse_quantifier(parser); + } + } +} + +/** + * expression : item+ + * ; + */ +static bool +pm_regexp_parse_expression(pm_regexp_parser_t *parser, uint16_t depth) { + if (depth >= PM_REGEXP_PARSE_DEPTH_MAX) { + pm_regexp_parse_error(parser, parser->start, parser->end, "parse depth limit over"); + return false; + } + + if (!pm_regexp_parse_item(parser, depth)) { + return false; + } + + while (!pm_regexp_char_is_eof(parser) && *parser->cursor != ')' && *parser->cursor != '|') { + if (!pm_regexp_parse_item(parser, depth)) { + return false; + } + } + + return true; +} + +/** + * pattern : EOF + * | expression EOF + * | expression '|' pattern + * ; + */ +static bool +pm_regexp_parse_pattern(pm_regexp_parser_t *parser) { + do { + if (pm_regexp_char_is_eof(parser)) return true; + if (!pm_regexp_parse_expression(parser, 0)) return false; + } while (pm_regexp_char_accept(parser, '|')); + + return pm_regexp_char_is_eof(parser); +} + +/** + * Parse a regular expression and extract the names of all of the named capture + * groups. + */ +PRISM_EXPORTED_FUNCTION void +pm_regexp_parse(pm_parser_t *parser, const uint8_t *source, size_t size, bool extended_mode, pm_regexp_name_callback_t name_callback, void *name_data, pm_regexp_error_callback_t error_callback, void *error_data) { + pm_regexp_parse_pattern(&(pm_regexp_parser_t) { + .parser = parser, + .start = source, + .cursor = source, + .end = source + size, + .extended_mode = extended_mode, + .encoding_changed = parser->encoding_changed, + .encoding = parser->encoding, + .name_callback = name_callback, + .name_data = name_data, + .error_callback = error_callback, + .error_data = error_data + }); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/serialize.c b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/serialize.c new file mode 100644 index 00000000..8bfed8f8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/serialize.c @@ -0,0 +1,2266 @@ +/*----------------------------------------------------------------------------*/ +/* This file is generated by the templates/template.rb script and should not */ +/* be modified manually. See */ +/* templates/src/serialize.c.erb */ +/* if you are looking to modify the */ +/* template */ +/*----------------------------------------------------------------------------*/ + +#include "prism.h" + +// We optionally support serializing to a binary string. For systems that don't +// want or need this functionality, it can be turned off with the +// PRISM_EXCLUDE_SERIALIZATION define. +#ifndef PRISM_EXCLUDE_SERIALIZATION + +#include + +static inline uint32_t +pm_ptrdifft_to_u32(ptrdiff_t value) { + assert(value >= 0 && ((unsigned long) value) < UINT32_MAX); + return (uint32_t) value; +} + +static inline uint32_t +pm_sizet_to_u32(size_t value) { + assert(value < UINT32_MAX); + return (uint32_t) value; +} + +static void +pm_serialize_location(const pm_parser_t *parser, const pm_location_t *location, pm_buffer_t *buffer) { + assert(location->start); + assert(location->end); + assert(location->start <= location->end); + + pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(location->start - parser->start)); + pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(location->end - location->start)); +} + +static void +pm_serialize_string(const pm_parser_t *parser, const pm_string_t *string, pm_buffer_t *buffer) { + switch (string->type) { + case PM_STRING_SHARED: { + pm_buffer_append_byte(buffer, 1); + pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(pm_string_source(string) - parser->start)); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(pm_string_length(string))); + break; + } + case PM_STRING_OWNED: + case PM_STRING_CONSTANT: { + uint32_t length = pm_sizet_to_u32(pm_string_length(string)); + pm_buffer_append_byte(buffer, 2); + pm_buffer_append_varuint(buffer, length); + pm_buffer_append_bytes(buffer, pm_string_source(string), length); + break; + } +#ifdef PRISM_HAS_MMAP + case PM_STRING_MAPPED: + assert(false && "Cannot serialize mapped strings."); + break; +#endif + } +} + +static void +pm_serialize_integer(const pm_integer_t *integer, pm_buffer_t *buffer) { + pm_buffer_append_byte(buffer, integer->negative ? 1 : 0); + if (integer->values == NULL) { + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(1)); + pm_buffer_append_varuint(buffer, integer->value); + } else { + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(integer->length)); + for (size_t i = 0; i < integer->length; i++) { + pm_buffer_append_varuint(buffer, integer->values[i]); + } + } +} + +static void +pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) { + pm_buffer_append_byte(buffer, (uint8_t) PM_NODE_TYPE(node)); + + size_t offset = buffer->length; + + pm_buffer_append_varuint(buffer, node->node_id); + pm_serialize_location(parser, &node->location, buffer); + + switch (PM_NODE_TYPE(node)) { + // We do not need to serialize a ScopeNode ever as + // it is not part of the AST + case PM_SCOPE_NODE: + return; + case PM_ALIAS_GLOBAL_VARIABLE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_node(parser, (pm_node_t *)((pm_alias_global_variable_node_t *)node)->new_name, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_alias_global_variable_node_t *)node)->old_name, buffer); + pm_serialize_location(parser, &((pm_alias_global_variable_node_t *)node)->keyword_loc, buffer); + break; + } + case PM_ALIAS_METHOD_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_node(parser, (pm_node_t *)((pm_alias_method_node_t *)node)->new_name, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_alias_method_node_t *)node)->old_name, buffer); + pm_serialize_location(parser, &((pm_alias_method_node_t *)node)->keyword_loc, buffer); + break; + } + case PM_ALTERNATION_PATTERN_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_node(parser, (pm_node_t *)((pm_alternation_pattern_node_t *)node)->left, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_alternation_pattern_node_t *)node)->right, buffer); + pm_serialize_location(parser, &((pm_alternation_pattern_node_t *)node)->operator_loc, buffer); + break; + } + case PM_AND_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_node(parser, (pm_node_t *)((pm_and_node_t *)node)->left, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_and_node_t *)node)->right, buffer); + pm_serialize_location(parser, &((pm_and_node_t *)node)->operator_loc, buffer); + break; + } + case PM_ARGUMENTS_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + uint32_t arguments_size = pm_sizet_to_u32(((pm_arguments_node_t *)node)->arguments.size); + pm_buffer_append_varuint(buffer, arguments_size); + for (uint32_t index = 0; index < arguments_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_arguments_node_t *)node)->arguments.nodes[index], buffer); + } + break; + } + case PM_ARRAY_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + uint32_t elements_size = pm_sizet_to_u32(((pm_array_node_t *)node)->elements.size); + pm_buffer_append_varuint(buffer, elements_size); + for (uint32_t index = 0; index < elements_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_array_node_t *)node)->elements.nodes[index], buffer); + } + if (((pm_array_node_t *)node)->opening_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_array_node_t *)node)->opening_loc, buffer); + } + if (((pm_array_node_t *)node)->closing_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_array_node_t *)node)->closing_loc, buffer); + } + break; + } + case PM_ARRAY_PATTERN_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_array_pattern_node_t *)node)->constant == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_array_pattern_node_t *)node)->constant, buffer); + } + uint32_t requireds_size = pm_sizet_to_u32(((pm_array_pattern_node_t *)node)->requireds.size); + pm_buffer_append_varuint(buffer, requireds_size); + for (uint32_t index = 0; index < requireds_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_array_pattern_node_t *)node)->requireds.nodes[index], buffer); + } + if (((pm_array_pattern_node_t *)node)->rest == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_array_pattern_node_t *)node)->rest, buffer); + } + uint32_t posts_size = pm_sizet_to_u32(((pm_array_pattern_node_t *)node)->posts.size); + pm_buffer_append_varuint(buffer, posts_size); + for (uint32_t index = 0; index < posts_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_array_pattern_node_t *)node)->posts.nodes[index], buffer); + } + if (((pm_array_pattern_node_t *)node)->opening_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_array_pattern_node_t *)node)->opening_loc, buffer); + } + if (((pm_array_pattern_node_t *)node)->closing_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_array_pattern_node_t *)node)->closing_loc, buffer); + } + break; + } + case PM_ASSOC_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_node(parser, (pm_node_t *)((pm_assoc_node_t *)node)->key, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_assoc_node_t *)node)->value, buffer); + if (((pm_assoc_node_t *)node)->operator_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_assoc_node_t *)node)->operator_loc, buffer); + } + break; + } + case PM_ASSOC_SPLAT_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_assoc_splat_node_t *)node)->value == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_assoc_splat_node_t *)node)->value, buffer); + } + pm_serialize_location(parser, &((pm_assoc_splat_node_t *)node)->operator_loc, buffer); + break; + } + case PM_BACK_REFERENCE_READ_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_back_reference_read_node_t *)node)->name)); + break; + } + case PM_BEGIN_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_begin_node_t *)node)->begin_keyword_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_begin_node_t *)node)->begin_keyword_loc, buffer); + } + if (((pm_begin_node_t *)node)->statements == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_begin_node_t *)node)->statements, buffer); + } + if (((pm_begin_node_t *)node)->rescue_clause == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_begin_node_t *)node)->rescue_clause, buffer); + } + if (((pm_begin_node_t *)node)->else_clause == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_begin_node_t *)node)->else_clause, buffer); + } + if (((pm_begin_node_t *)node)->ensure_clause == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_begin_node_t *)node)->ensure_clause, buffer); + } + if (((pm_begin_node_t *)node)->end_keyword_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_begin_node_t *)node)->end_keyword_loc, buffer); + } + break; + } + case PM_BLOCK_ARGUMENT_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_block_argument_node_t *)node)->expression == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_block_argument_node_t *)node)->expression, buffer); + } + pm_serialize_location(parser, &((pm_block_argument_node_t *)node)->operator_loc, buffer); + break; + } + case PM_BLOCK_LOCAL_VARIABLE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_block_local_variable_node_t *)node)->name)); + break; + } + case PM_BLOCK_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + uint32_t locals_size = pm_sizet_to_u32(((pm_block_node_t *)node)->locals.size); + pm_buffer_append_varuint(buffer, locals_size); + for (uint32_t index = 0; index < locals_size; index++) { + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_block_node_t *)node)->locals.ids[index])); + } + if (((pm_block_node_t *)node)->parameters == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_block_node_t *)node)->parameters, buffer); + } + if (((pm_block_node_t *)node)->body == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_block_node_t *)node)->body, buffer); + } + pm_serialize_location(parser, &((pm_block_node_t *)node)->opening_loc, buffer); + pm_serialize_location(parser, &((pm_block_node_t *)node)->closing_loc, buffer); + break; + } + case PM_BLOCK_PARAMETER_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_block_parameter_node_t *)node)->name)); + if (((pm_block_parameter_node_t *)node)->name_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_block_parameter_node_t *)node)->name_loc, buffer); + } + pm_serialize_location(parser, &((pm_block_parameter_node_t *)node)->operator_loc, buffer); + break; + } + case PM_BLOCK_PARAMETERS_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_block_parameters_node_t *)node)->parameters == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_block_parameters_node_t *)node)->parameters, buffer); + } + uint32_t locals_size = pm_sizet_to_u32(((pm_block_parameters_node_t *)node)->locals.size); + pm_buffer_append_varuint(buffer, locals_size); + for (uint32_t index = 0; index < locals_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_block_parameters_node_t *)node)->locals.nodes[index], buffer); + } + if (((pm_block_parameters_node_t *)node)->opening_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_block_parameters_node_t *)node)->opening_loc, buffer); + } + if (((pm_block_parameters_node_t *)node)->closing_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_block_parameters_node_t *)node)->closing_loc, buffer); + } + break; + } + case PM_BREAK_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_break_node_t *)node)->arguments == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_break_node_t *)node)->arguments, buffer); + } + pm_serialize_location(parser, &((pm_break_node_t *)node)->keyword_loc, buffer); + break; + } + case PM_CALL_AND_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_call_and_write_node_t *)node)->receiver == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_call_and_write_node_t *)node)->receiver, buffer); + } + if (((pm_call_and_write_node_t *)node)->call_operator_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_call_and_write_node_t *)node)->call_operator_loc, buffer); + } + if (((pm_call_and_write_node_t *)node)->message_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_call_and_write_node_t *)node)->message_loc, buffer); + } + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_call_and_write_node_t *)node)->read_name)); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_call_and_write_node_t *)node)->write_name)); + pm_serialize_location(parser, &((pm_call_and_write_node_t *)node)->operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_call_and_write_node_t *)node)->value, buffer); + break; + } + case PM_CALL_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_call_node_t *)node)->receiver == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_call_node_t *)node)->receiver, buffer); + } + if (((pm_call_node_t *)node)->call_operator_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_call_node_t *)node)->call_operator_loc, buffer); + } + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_call_node_t *)node)->name)); + if (((pm_call_node_t *)node)->message_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_call_node_t *)node)->message_loc, buffer); + } + if (((pm_call_node_t *)node)->opening_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_call_node_t *)node)->opening_loc, buffer); + } + if (((pm_call_node_t *)node)->arguments == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_call_node_t *)node)->arguments, buffer); + } + if (((pm_call_node_t *)node)->closing_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_call_node_t *)node)->closing_loc, buffer); + } + if (((pm_call_node_t *)node)->block == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_call_node_t *)node)->block, buffer); + } + break; + } + case PM_CALL_OPERATOR_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_call_operator_write_node_t *)node)->receiver == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_call_operator_write_node_t *)node)->receiver, buffer); + } + if (((pm_call_operator_write_node_t *)node)->call_operator_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_call_operator_write_node_t *)node)->call_operator_loc, buffer); + } + if (((pm_call_operator_write_node_t *)node)->message_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_call_operator_write_node_t *)node)->message_loc, buffer); + } + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_call_operator_write_node_t *)node)->read_name)); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_call_operator_write_node_t *)node)->write_name)); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_call_operator_write_node_t *)node)->binary_operator)); + pm_serialize_location(parser, &((pm_call_operator_write_node_t *)node)->binary_operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_call_operator_write_node_t *)node)->value, buffer); + break; + } + case PM_CALL_OR_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_call_or_write_node_t *)node)->receiver == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_call_or_write_node_t *)node)->receiver, buffer); + } + if (((pm_call_or_write_node_t *)node)->call_operator_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_call_or_write_node_t *)node)->call_operator_loc, buffer); + } + if (((pm_call_or_write_node_t *)node)->message_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_call_or_write_node_t *)node)->message_loc, buffer); + } + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_call_or_write_node_t *)node)->read_name)); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_call_or_write_node_t *)node)->write_name)); + pm_serialize_location(parser, &((pm_call_or_write_node_t *)node)->operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_call_or_write_node_t *)node)->value, buffer); + break; + } + case PM_CALL_TARGET_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_node(parser, (pm_node_t *)((pm_call_target_node_t *)node)->receiver, buffer); + pm_serialize_location(parser, &((pm_call_target_node_t *)node)->call_operator_loc, buffer); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_call_target_node_t *)node)->name)); + pm_serialize_location(parser, &((pm_call_target_node_t *)node)->message_loc, buffer); + break; + } + case PM_CAPTURE_PATTERN_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_node(parser, (pm_node_t *)((pm_capture_pattern_node_t *)node)->value, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_capture_pattern_node_t *)node)->target, buffer); + pm_serialize_location(parser, &((pm_capture_pattern_node_t *)node)->operator_loc, buffer); + break; + } + case PM_CASE_MATCH_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_case_match_node_t *)node)->predicate == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_case_match_node_t *)node)->predicate, buffer); + } + uint32_t conditions_size = pm_sizet_to_u32(((pm_case_match_node_t *)node)->conditions.size); + pm_buffer_append_varuint(buffer, conditions_size); + for (uint32_t index = 0; index < conditions_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_case_match_node_t *)node)->conditions.nodes[index], buffer); + } + if (((pm_case_match_node_t *)node)->else_clause == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_case_match_node_t *)node)->else_clause, buffer); + } + pm_serialize_location(parser, &((pm_case_match_node_t *)node)->case_keyword_loc, buffer); + pm_serialize_location(parser, &((pm_case_match_node_t *)node)->end_keyword_loc, buffer); + break; + } + case PM_CASE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_case_node_t *)node)->predicate == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_case_node_t *)node)->predicate, buffer); + } + uint32_t conditions_size = pm_sizet_to_u32(((pm_case_node_t *)node)->conditions.size); + pm_buffer_append_varuint(buffer, conditions_size); + for (uint32_t index = 0; index < conditions_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_case_node_t *)node)->conditions.nodes[index], buffer); + } + if (((pm_case_node_t *)node)->else_clause == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_case_node_t *)node)->else_clause, buffer); + } + pm_serialize_location(parser, &((pm_case_node_t *)node)->case_keyword_loc, buffer); + pm_serialize_location(parser, &((pm_case_node_t *)node)->end_keyword_loc, buffer); + break; + } + case PM_CLASS_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + uint32_t locals_size = pm_sizet_to_u32(((pm_class_node_t *)node)->locals.size); + pm_buffer_append_varuint(buffer, locals_size); + for (uint32_t index = 0; index < locals_size; index++) { + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_class_node_t *)node)->locals.ids[index])); + } + pm_serialize_location(parser, &((pm_class_node_t *)node)->class_keyword_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_class_node_t *)node)->constant_path, buffer); + if (((pm_class_node_t *)node)->inheritance_operator_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_class_node_t *)node)->inheritance_operator_loc, buffer); + } + if (((pm_class_node_t *)node)->superclass == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_class_node_t *)node)->superclass, buffer); + } + if (((pm_class_node_t *)node)->body == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_class_node_t *)node)->body, buffer); + } + pm_serialize_location(parser, &((pm_class_node_t *)node)->end_keyword_loc, buffer); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_class_node_t *)node)->name)); + break; + } + case PM_CLASS_VARIABLE_AND_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_class_variable_and_write_node_t *)node)->name)); + pm_serialize_location(parser, &((pm_class_variable_and_write_node_t *)node)->name_loc, buffer); + pm_serialize_location(parser, &((pm_class_variable_and_write_node_t *)node)->operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_class_variable_and_write_node_t *)node)->value, buffer); + break; + } + case PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_class_variable_operator_write_node_t *)node)->name)); + pm_serialize_location(parser, &((pm_class_variable_operator_write_node_t *)node)->name_loc, buffer); + pm_serialize_location(parser, &((pm_class_variable_operator_write_node_t *)node)->binary_operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_class_variable_operator_write_node_t *)node)->value, buffer); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_class_variable_operator_write_node_t *)node)->binary_operator)); + break; + } + case PM_CLASS_VARIABLE_OR_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_class_variable_or_write_node_t *)node)->name)); + pm_serialize_location(parser, &((pm_class_variable_or_write_node_t *)node)->name_loc, buffer); + pm_serialize_location(parser, &((pm_class_variable_or_write_node_t *)node)->operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_class_variable_or_write_node_t *)node)->value, buffer); + break; + } + case PM_CLASS_VARIABLE_READ_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_class_variable_read_node_t *)node)->name)); + break; + } + case PM_CLASS_VARIABLE_TARGET_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_class_variable_target_node_t *)node)->name)); + break; + } + case PM_CLASS_VARIABLE_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_class_variable_write_node_t *)node)->name)); + pm_serialize_location(parser, &((pm_class_variable_write_node_t *)node)->name_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_class_variable_write_node_t *)node)->value, buffer); + pm_serialize_location(parser, &((pm_class_variable_write_node_t *)node)->operator_loc, buffer); + break; + } + case PM_CONSTANT_AND_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_constant_and_write_node_t *)node)->name)); + pm_serialize_location(parser, &((pm_constant_and_write_node_t *)node)->name_loc, buffer); + pm_serialize_location(parser, &((pm_constant_and_write_node_t *)node)->operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_constant_and_write_node_t *)node)->value, buffer); + break; + } + case PM_CONSTANT_OPERATOR_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_constant_operator_write_node_t *)node)->name)); + pm_serialize_location(parser, &((pm_constant_operator_write_node_t *)node)->name_loc, buffer); + pm_serialize_location(parser, &((pm_constant_operator_write_node_t *)node)->binary_operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_constant_operator_write_node_t *)node)->value, buffer); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_constant_operator_write_node_t *)node)->binary_operator)); + break; + } + case PM_CONSTANT_OR_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_constant_or_write_node_t *)node)->name)); + pm_serialize_location(parser, &((pm_constant_or_write_node_t *)node)->name_loc, buffer); + pm_serialize_location(parser, &((pm_constant_or_write_node_t *)node)->operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_constant_or_write_node_t *)node)->value, buffer); + break; + } + case PM_CONSTANT_PATH_AND_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_node(parser, (pm_node_t *)((pm_constant_path_and_write_node_t *)node)->target, buffer); + pm_serialize_location(parser, &((pm_constant_path_and_write_node_t *)node)->operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_constant_path_and_write_node_t *)node)->value, buffer); + break; + } + case PM_CONSTANT_PATH_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_constant_path_node_t *)node)->parent == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_constant_path_node_t *)node)->parent, buffer); + } + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_constant_path_node_t *)node)->name)); + pm_serialize_location(parser, &((pm_constant_path_node_t *)node)->delimiter_loc, buffer); + pm_serialize_location(parser, &((pm_constant_path_node_t *)node)->name_loc, buffer); + break; + } + case PM_CONSTANT_PATH_OPERATOR_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_node(parser, (pm_node_t *)((pm_constant_path_operator_write_node_t *)node)->target, buffer); + pm_serialize_location(parser, &((pm_constant_path_operator_write_node_t *)node)->binary_operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_constant_path_operator_write_node_t *)node)->value, buffer); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_constant_path_operator_write_node_t *)node)->binary_operator)); + break; + } + case PM_CONSTANT_PATH_OR_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_node(parser, (pm_node_t *)((pm_constant_path_or_write_node_t *)node)->target, buffer); + pm_serialize_location(parser, &((pm_constant_path_or_write_node_t *)node)->operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_constant_path_or_write_node_t *)node)->value, buffer); + break; + } + case PM_CONSTANT_PATH_TARGET_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_constant_path_target_node_t *)node)->parent == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_constant_path_target_node_t *)node)->parent, buffer); + } + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_constant_path_target_node_t *)node)->name)); + pm_serialize_location(parser, &((pm_constant_path_target_node_t *)node)->delimiter_loc, buffer); + pm_serialize_location(parser, &((pm_constant_path_target_node_t *)node)->name_loc, buffer); + break; + } + case PM_CONSTANT_PATH_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_node(parser, (pm_node_t *)((pm_constant_path_write_node_t *)node)->target, buffer); + pm_serialize_location(parser, &((pm_constant_path_write_node_t *)node)->operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_constant_path_write_node_t *)node)->value, buffer); + break; + } + case PM_CONSTANT_READ_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_constant_read_node_t *)node)->name)); + break; + } + case PM_CONSTANT_TARGET_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_constant_target_node_t *)node)->name)); + break; + } + case PM_CONSTANT_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_constant_write_node_t *)node)->name)); + pm_serialize_location(parser, &((pm_constant_write_node_t *)node)->name_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_constant_write_node_t *)node)->value, buffer); + pm_serialize_location(parser, &((pm_constant_write_node_t *)node)->operator_loc, buffer); + break; + } + case PM_DEF_NODE: { + // serialize length + // encoding of location u32s make us need to save this offset. + size_t length_offset = buffer->length; + pm_buffer_append_string(buffer, "\0\0\0\0", 4); /* consume 4 bytes, updated below */ + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_def_node_t *)node)->name)); + pm_serialize_location(parser, &((pm_def_node_t *)node)->name_loc, buffer); + if (((pm_def_node_t *)node)->receiver == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_def_node_t *)node)->receiver, buffer); + } + if (((pm_def_node_t *)node)->parameters == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_def_node_t *)node)->parameters, buffer); + } + if (((pm_def_node_t *)node)->body == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_def_node_t *)node)->body, buffer); + } + uint32_t locals_size = pm_sizet_to_u32(((pm_def_node_t *)node)->locals.size); + pm_buffer_append_varuint(buffer, locals_size); + for (uint32_t index = 0; index < locals_size; index++) { + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_def_node_t *)node)->locals.ids[index])); + } + pm_serialize_location(parser, &((pm_def_node_t *)node)->def_keyword_loc, buffer); + if (((pm_def_node_t *)node)->operator_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_def_node_t *)node)->operator_loc, buffer); + } + if (((pm_def_node_t *)node)->lparen_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_def_node_t *)node)->lparen_loc, buffer); + } + if (((pm_def_node_t *)node)->rparen_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_def_node_t *)node)->rparen_loc, buffer); + } + if (((pm_def_node_t *)node)->equal_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_def_node_t *)node)->equal_loc, buffer); + } + if (((pm_def_node_t *)node)->end_keyword_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_def_node_t *)node)->end_keyword_loc, buffer); + } + // serialize length + uint32_t length = pm_sizet_to_u32(buffer->length - offset - sizeof(uint32_t)); + memcpy(buffer->value + length_offset, &length, sizeof(uint32_t)); + break; + } + case PM_DEFINED_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_defined_node_t *)node)->lparen_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_defined_node_t *)node)->lparen_loc, buffer); + } + pm_serialize_node(parser, (pm_node_t *)((pm_defined_node_t *)node)->value, buffer); + if (((pm_defined_node_t *)node)->rparen_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_defined_node_t *)node)->rparen_loc, buffer); + } + pm_serialize_location(parser, &((pm_defined_node_t *)node)->keyword_loc, buffer); + break; + } + case PM_ELSE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_location(parser, &((pm_else_node_t *)node)->else_keyword_loc, buffer); + if (((pm_else_node_t *)node)->statements == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_else_node_t *)node)->statements, buffer); + } + if (((pm_else_node_t *)node)->end_keyword_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_else_node_t *)node)->end_keyword_loc, buffer); + } + break; + } + case PM_EMBEDDED_STATEMENTS_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_location(parser, &((pm_embedded_statements_node_t *)node)->opening_loc, buffer); + if (((pm_embedded_statements_node_t *)node)->statements == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_embedded_statements_node_t *)node)->statements, buffer); + } + pm_serialize_location(parser, &((pm_embedded_statements_node_t *)node)->closing_loc, buffer); + break; + } + case PM_EMBEDDED_VARIABLE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_location(parser, &((pm_embedded_variable_node_t *)node)->operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_embedded_variable_node_t *)node)->variable, buffer); + break; + } + case PM_ENSURE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_location(parser, &((pm_ensure_node_t *)node)->ensure_keyword_loc, buffer); + if (((pm_ensure_node_t *)node)->statements == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_ensure_node_t *)node)->statements, buffer); + } + pm_serialize_location(parser, &((pm_ensure_node_t *)node)->end_keyword_loc, buffer); + break; + } + case PM_FALSE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + break; + } + case PM_FIND_PATTERN_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_find_pattern_node_t *)node)->constant == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_find_pattern_node_t *)node)->constant, buffer); + } + pm_serialize_node(parser, (pm_node_t *)((pm_find_pattern_node_t *)node)->left, buffer); + uint32_t requireds_size = pm_sizet_to_u32(((pm_find_pattern_node_t *)node)->requireds.size); + pm_buffer_append_varuint(buffer, requireds_size); + for (uint32_t index = 0; index < requireds_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_find_pattern_node_t *)node)->requireds.nodes[index], buffer); + } + pm_serialize_node(parser, (pm_node_t *)((pm_find_pattern_node_t *)node)->right, buffer); + if (((pm_find_pattern_node_t *)node)->opening_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_find_pattern_node_t *)node)->opening_loc, buffer); + } + if (((pm_find_pattern_node_t *)node)->closing_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_find_pattern_node_t *)node)->closing_loc, buffer); + } + break; + } + case PM_FLIP_FLOP_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_flip_flop_node_t *)node)->left == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_flip_flop_node_t *)node)->left, buffer); + } + if (((pm_flip_flop_node_t *)node)->right == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_flip_flop_node_t *)node)->right, buffer); + } + pm_serialize_location(parser, &((pm_flip_flop_node_t *)node)->operator_loc, buffer); + break; + } + case PM_FLOAT_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_double(buffer, ((pm_float_node_t *)node)->value); + break; + } + case PM_FOR_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_node(parser, (pm_node_t *)((pm_for_node_t *)node)->index, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_for_node_t *)node)->collection, buffer); + if (((pm_for_node_t *)node)->statements == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_for_node_t *)node)->statements, buffer); + } + pm_serialize_location(parser, &((pm_for_node_t *)node)->for_keyword_loc, buffer); + pm_serialize_location(parser, &((pm_for_node_t *)node)->in_keyword_loc, buffer); + if (((pm_for_node_t *)node)->do_keyword_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_for_node_t *)node)->do_keyword_loc, buffer); + } + pm_serialize_location(parser, &((pm_for_node_t *)node)->end_keyword_loc, buffer); + break; + } + case PM_FORWARDING_ARGUMENTS_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + break; + } + case PM_FORWARDING_PARAMETER_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + break; + } + case PM_FORWARDING_SUPER_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_forwarding_super_node_t *)node)->block == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_forwarding_super_node_t *)node)->block, buffer); + } + break; + } + case PM_GLOBAL_VARIABLE_AND_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_global_variable_and_write_node_t *)node)->name)); + pm_serialize_location(parser, &((pm_global_variable_and_write_node_t *)node)->name_loc, buffer); + pm_serialize_location(parser, &((pm_global_variable_and_write_node_t *)node)->operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_global_variable_and_write_node_t *)node)->value, buffer); + break; + } + case PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_global_variable_operator_write_node_t *)node)->name)); + pm_serialize_location(parser, &((pm_global_variable_operator_write_node_t *)node)->name_loc, buffer); + pm_serialize_location(parser, &((pm_global_variable_operator_write_node_t *)node)->binary_operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_global_variable_operator_write_node_t *)node)->value, buffer); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_global_variable_operator_write_node_t *)node)->binary_operator)); + break; + } + case PM_GLOBAL_VARIABLE_OR_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_global_variable_or_write_node_t *)node)->name)); + pm_serialize_location(parser, &((pm_global_variable_or_write_node_t *)node)->name_loc, buffer); + pm_serialize_location(parser, &((pm_global_variable_or_write_node_t *)node)->operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_global_variable_or_write_node_t *)node)->value, buffer); + break; + } + case PM_GLOBAL_VARIABLE_READ_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_global_variable_read_node_t *)node)->name)); + break; + } + case PM_GLOBAL_VARIABLE_TARGET_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_global_variable_target_node_t *)node)->name)); + break; + } + case PM_GLOBAL_VARIABLE_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_global_variable_write_node_t *)node)->name)); + pm_serialize_location(parser, &((pm_global_variable_write_node_t *)node)->name_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_global_variable_write_node_t *)node)->value, buffer); + pm_serialize_location(parser, &((pm_global_variable_write_node_t *)node)->operator_loc, buffer); + break; + } + case PM_HASH_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_location(parser, &((pm_hash_node_t *)node)->opening_loc, buffer); + uint32_t elements_size = pm_sizet_to_u32(((pm_hash_node_t *)node)->elements.size); + pm_buffer_append_varuint(buffer, elements_size); + for (uint32_t index = 0; index < elements_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_hash_node_t *)node)->elements.nodes[index], buffer); + } + pm_serialize_location(parser, &((pm_hash_node_t *)node)->closing_loc, buffer); + break; + } + case PM_HASH_PATTERN_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_hash_pattern_node_t *)node)->constant == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_hash_pattern_node_t *)node)->constant, buffer); + } + uint32_t elements_size = pm_sizet_to_u32(((pm_hash_pattern_node_t *)node)->elements.size); + pm_buffer_append_varuint(buffer, elements_size); + for (uint32_t index = 0; index < elements_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_hash_pattern_node_t *)node)->elements.nodes[index], buffer); + } + if (((pm_hash_pattern_node_t *)node)->rest == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_hash_pattern_node_t *)node)->rest, buffer); + } + if (((pm_hash_pattern_node_t *)node)->opening_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_hash_pattern_node_t *)node)->opening_loc, buffer); + } + if (((pm_hash_pattern_node_t *)node)->closing_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_hash_pattern_node_t *)node)->closing_loc, buffer); + } + break; + } + case PM_IF_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_if_node_t *)node)->if_keyword_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_if_node_t *)node)->if_keyword_loc, buffer); + } + pm_serialize_node(parser, (pm_node_t *)((pm_if_node_t *)node)->predicate, buffer); + if (((pm_if_node_t *)node)->then_keyword_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_if_node_t *)node)->then_keyword_loc, buffer); + } + if (((pm_if_node_t *)node)->statements == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_if_node_t *)node)->statements, buffer); + } + if (((pm_if_node_t *)node)->subsequent == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_if_node_t *)node)->subsequent, buffer); + } + if (((pm_if_node_t *)node)->end_keyword_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_if_node_t *)node)->end_keyword_loc, buffer); + } + break; + } + case PM_IMAGINARY_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_node(parser, (pm_node_t *)((pm_imaginary_node_t *)node)->numeric, buffer); + break; + } + case PM_IMPLICIT_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_node(parser, (pm_node_t *)((pm_implicit_node_t *)node)->value, buffer); + break; + } + case PM_IMPLICIT_REST_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + break; + } + case PM_IN_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_node(parser, (pm_node_t *)((pm_in_node_t *)node)->pattern, buffer); + if (((pm_in_node_t *)node)->statements == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_in_node_t *)node)->statements, buffer); + } + pm_serialize_location(parser, &((pm_in_node_t *)node)->in_loc, buffer); + if (((pm_in_node_t *)node)->then_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_in_node_t *)node)->then_loc, buffer); + } + break; + } + case PM_INDEX_AND_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_index_and_write_node_t *)node)->receiver == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_index_and_write_node_t *)node)->receiver, buffer); + } + if (((pm_index_and_write_node_t *)node)->call_operator_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_index_and_write_node_t *)node)->call_operator_loc, buffer); + } + pm_serialize_location(parser, &((pm_index_and_write_node_t *)node)->opening_loc, buffer); + if (((pm_index_and_write_node_t *)node)->arguments == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_index_and_write_node_t *)node)->arguments, buffer); + } + pm_serialize_location(parser, &((pm_index_and_write_node_t *)node)->closing_loc, buffer); + if (((pm_index_and_write_node_t *)node)->block == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_index_and_write_node_t *)node)->block, buffer); + } + pm_serialize_location(parser, &((pm_index_and_write_node_t *)node)->operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_index_and_write_node_t *)node)->value, buffer); + break; + } + case PM_INDEX_OPERATOR_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_index_operator_write_node_t *)node)->receiver == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_index_operator_write_node_t *)node)->receiver, buffer); + } + if (((pm_index_operator_write_node_t *)node)->call_operator_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_index_operator_write_node_t *)node)->call_operator_loc, buffer); + } + pm_serialize_location(parser, &((pm_index_operator_write_node_t *)node)->opening_loc, buffer); + if (((pm_index_operator_write_node_t *)node)->arguments == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_index_operator_write_node_t *)node)->arguments, buffer); + } + pm_serialize_location(parser, &((pm_index_operator_write_node_t *)node)->closing_loc, buffer); + if (((pm_index_operator_write_node_t *)node)->block == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_index_operator_write_node_t *)node)->block, buffer); + } + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_index_operator_write_node_t *)node)->binary_operator)); + pm_serialize_location(parser, &((pm_index_operator_write_node_t *)node)->binary_operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_index_operator_write_node_t *)node)->value, buffer); + break; + } + case PM_INDEX_OR_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_index_or_write_node_t *)node)->receiver == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_index_or_write_node_t *)node)->receiver, buffer); + } + if (((pm_index_or_write_node_t *)node)->call_operator_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_index_or_write_node_t *)node)->call_operator_loc, buffer); + } + pm_serialize_location(parser, &((pm_index_or_write_node_t *)node)->opening_loc, buffer); + if (((pm_index_or_write_node_t *)node)->arguments == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_index_or_write_node_t *)node)->arguments, buffer); + } + pm_serialize_location(parser, &((pm_index_or_write_node_t *)node)->closing_loc, buffer); + if (((pm_index_or_write_node_t *)node)->block == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_index_or_write_node_t *)node)->block, buffer); + } + pm_serialize_location(parser, &((pm_index_or_write_node_t *)node)->operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_index_or_write_node_t *)node)->value, buffer); + break; + } + case PM_INDEX_TARGET_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_node(parser, (pm_node_t *)((pm_index_target_node_t *)node)->receiver, buffer); + pm_serialize_location(parser, &((pm_index_target_node_t *)node)->opening_loc, buffer); + if (((pm_index_target_node_t *)node)->arguments == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_index_target_node_t *)node)->arguments, buffer); + } + pm_serialize_location(parser, &((pm_index_target_node_t *)node)->closing_loc, buffer); + if (((pm_index_target_node_t *)node)->block == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_index_target_node_t *)node)->block, buffer); + } + break; + } + case PM_INSTANCE_VARIABLE_AND_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_instance_variable_and_write_node_t *)node)->name)); + pm_serialize_location(parser, &((pm_instance_variable_and_write_node_t *)node)->name_loc, buffer); + pm_serialize_location(parser, &((pm_instance_variable_and_write_node_t *)node)->operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_instance_variable_and_write_node_t *)node)->value, buffer); + break; + } + case PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_instance_variable_operator_write_node_t *)node)->name)); + pm_serialize_location(parser, &((pm_instance_variable_operator_write_node_t *)node)->name_loc, buffer); + pm_serialize_location(parser, &((pm_instance_variable_operator_write_node_t *)node)->binary_operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_instance_variable_operator_write_node_t *)node)->value, buffer); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_instance_variable_operator_write_node_t *)node)->binary_operator)); + break; + } + case PM_INSTANCE_VARIABLE_OR_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_instance_variable_or_write_node_t *)node)->name)); + pm_serialize_location(parser, &((pm_instance_variable_or_write_node_t *)node)->name_loc, buffer); + pm_serialize_location(parser, &((pm_instance_variable_or_write_node_t *)node)->operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_instance_variable_or_write_node_t *)node)->value, buffer); + break; + } + case PM_INSTANCE_VARIABLE_READ_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_instance_variable_read_node_t *)node)->name)); + break; + } + case PM_INSTANCE_VARIABLE_TARGET_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_instance_variable_target_node_t *)node)->name)); + break; + } + case PM_INSTANCE_VARIABLE_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_instance_variable_write_node_t *)node)->name)); + pm_serialize_location(parser, &((pm_instance_variable_write_node_t *)node)->name_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_instance_variable_write_node_t *)node)->value, buffer); + pm_serialize_location(parser, &((pm_instance_variable_write_node_t *)node)->operator_loc, buffer); + break; + } + case PM_INTEGER_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_integer(&((pm_integer_node_t *)node)->value, buffer); + break; + } + case PM_INTERPOLATED_MATCH_LAST_LINE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_location(parser, &((pm_interpolated_match_last_line_node_t *)node)->opening_loc, buffer); + uint32_t parts_size = pm_sizet_to_u32(((pm_interpolated_match_last_line_node_t *)node)->parts.size); + pm_buffer_append_varuint(buffer, parts_size); + for (uint32_t index = 0; index < parts_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_interpolated_match_last_line_node_t *)node)->parts.nodes[index], buffer); + } + pm_serialize_location(parser, &((pm_interpolated_match_last_line_node_t *)node)->closing_loc, buffer); + break; + } + case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_location(parser, &((pm_interpolated_regular_expression_node_t *)node)->opening_loc, buffer); + uint32_t parts_size = pm_sizet_to_u32(((pm_interpolated_regular_expression_node_t *)node)->parts.size); + pm_buffer_append_varuint(buffer, parts_size); + for (uint32_t index = 0; index < parts_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_interpolated_regular_expression_node_t *)node)->parts.nodes[index], buffer); + } + pm_serialize_location(parser, &((pm_interpolated_regular_expression_node_t *)node)->closing_loc, buffer); + break; + } + case PM_INTERPOLATED_STRING_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_interpolated_string_node_t *)node)->opening_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_interpolated_string_node_t *)node)->opening_loc, buffer); + } + uint32_t parts_size = pm_sizet_to_u32(((pm_interpolated_string_node_t *)node)->parts.size); + pm_buffer_append_varuint(buffer, parts_size); + for (uint32_t index = 0; index < parts_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_interpolated_string_node_t *)node)->parts.nodes[index], buffer); + } + if (((pm_interpolated_string_node_t *)node)->closing_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_interpolated_string_node_t *)node)->closing_loc, buffer); + } + break; + } + case PM_INTERPOLATED_SYMBOL_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_interpolated_symbol_node_t *)node)->opening_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_interpolated_symbol_node_t *)node)->opening_loc, buffer); + } + uint32_t parts_size = pm_sizet_to_u32(((pm_interpolated_symbol_node_t *)node)->parts.size); + pm_buffer_append_varuint(buffer, parts_size); + for (uint32_t index = 0; index < parts_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_interpolated_symbol_node_t *)node)->parts.nodes[index], buffer); + } + if (((pm_interpolated_symbol_node_t *)node)->closing_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_interpolated_symbol_node_t *)node)->closing_loc, buffer); + } + break; + } + case PM_INTERPOLATED_X_STRING_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_location(parser, &((pm_interpolated_x_string_node_t *)node)->opening_loc, buffer); + uint32_t parts_size = pm_sizet_to_u32(((pm_interpolated_x_string_node_t *)node)->parts.size); + pm_buffer_append_varuint(buffer, parts_size); + for (uint32_t index = 0; index < parts_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_interpolated_x_string_node_t *)node)->parts.nodes[index], buffer); + } + pm_serialize_location(parser, &((pm_interpolated_x_string_node_t *)node)->closing_loc, buffer); + break; + } + case PM_IT_LOCAL_VARIABLE_READ_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + break; + } + case PM_IT_PARAMETERS_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + break; + } + case PM_KEYWORD_HASH_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + uint32_t elements_size = pm_sizet_to_u32(((pm_keyword_hash_node_t *)node)->elements.size); + pm_buffer_append_varuint(buffer, elements_size); + for (uint32_t index = 0; index < elements_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_keyword_hash_node_t *)node)->elements.nodes[index], buffer); + } + break; + } + case PM_KEYWORD_REST_PARAMETER_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_keyword_rest_parameter_node_t *)node)->name)); + if (((pm_keyword_rest_parameter_node_t *)node)->name_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_keyword_rest_parameter_node_t *)node)->name_loc, buffer); + } + pm_serialize_location(parser, &((pm_keyword_rest_parameter_node_t *)node)->operator_loc, buffer); + break; + } + case PM_LAMBDA_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + uint32_t locals_size = pm_sizet_to_u32(((pm_lambda_node_t *)node)->locals.size); + pm_buffer_append_varuint(buffer, locals_size); + for (uint32_t index = 0; index < locals_size; index++) { + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_lambda_node_t *)node)->locals.ids[index])); + } + pm_serialize_location(parser, &((pm_lambda_node_t *)node)->operator_loc, buffer); + pm_serialize_location(parser, &((pm_lambda_node_t *)node)->opening_loc, buffer); + pm_serialize_location(parser, &((pm_lambda_node_t *)node)->closing_loc, buffer); + if (((pm_lambda_node_t *)node)->parameters == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_lambda_node_t *)node)->parameters, buffer); + } + if (((pm_lambda_node_t *)node)->body == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_lambda_node_t *)node)->body, buffer); + } + break; + } + case PM_LOCAL_VARIABLE_AND_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_location(parser, &((pm_local_variable_and_write_node_t *)node)->name_loc, buffer); + pm_serialize_location(parser, &((pm_local_variable_and_write_node_t *)node)->operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_local_variable_and_write_node_t *)node)->value, buffer); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_local_variable_and_write_node_t *)node)->name)); + pm_buffer_append_varuint(buffer, ((pm_local_variable_and_write_node_t *)node)->depth); + break; + } + case PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_location(parser, &((pm_local_variable_operator_write_node_t *)node)->name_loc, buffer); + pm_serialize_location(parser, &((pm_local_variable_operator_write_node_t *)node)->binary_operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_local_variable_operator_write_node_t *)node)->value, buffer); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_local_variable_operator_write_node_t *)node)->name)); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_local_variable_operator_write_node_t *)node)->binary_operator)); + pm_buffer_append_varuint(buffer, ((pm_local_variable_operator_write_node_t *)node)->depth); + break; + } + case PM_LOCAL_VARIABLE_OR_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_location(parser, &((pm_local_variable_or_write_node_t *)node)->name_loc, buffer); + pm_serialize_location(parser, &((pm_local_variable_or_write_node_t *)node)->operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_local_variable_or_write_node_t *)node)->value, buffer); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_local_variable_or_write_node_t *)node)->name)); + pm_buffer_append_varuint(buffer, ((pm_local_variable_or_write_node_t *)node)->depth); + break; + } + case PM_LOCAL_VARIABLE_READ_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_local_variable_read_node_t *)node)->name)); + pm_buffer_append_varuint(buffer, ((pm_local_variable_read_node_t *)node)->depth); + break; + } + case PM_LOCAL_VARIABLE_TARGET_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_local_variable_target_node_t *)node)->name)); + pm_buffer_append_varuint(buffer, ((pm_local_variable_target_node_t *)node)->depth); + break; + } + case PM_LOCAL_VARIABLE_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_local_variable_write_node_t *)node)->name)); + pm_buffer_append_varuint(buffer, ((pm_local_variable_write_node_t *)node)->depth); + pm_serialize_location(parser, &((pm_local_variable_write_node_t *)node)->name_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_local_variable_write_node_t *)node)->value, buffer); + pm_serialize_location(parser, &((pm_local_variable_write_node_t *)node)->operator_loc, buffer); + break; + } + case PM_MATCH_LAST_LINE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_location(parser, &((pm_match_last_line_node_t *)node)->opening_loc, buffer); + pm_serialize_location(parser, &((pm_match_last_line_node_t *)node)->content_loc, buffer); + pm_serialize_location(parser, &((pm_match_last_line_node_t *)node)->closing_loc, buffer); + pm_serialize_string(parser, &((pm_match_last_line_node_t *)node)->unescaped, buffer); + break; + } + case PM_MATCH_PREDICATE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_node(parser, (pm_node_t *)((pm_match_predicate_node_t *)node)->value, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_match_predicate_node_t *)node)->pattern, buffer); + pm_serialize_location(parser, &((pm_match_predicate_node_t *)node)->operator_loc, buffer); + break; + } + case PM_MATCH_REQUIRED_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_node(parser, (pm_node_t *)((pm_match_required_node_t *)node)->value, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_match_required_node_t *)node)->pattern, buffer); + pm_serialize_location(parser, &((pm_match_required_node_t *)node)->operator_loc, buffer); + break; + } + case PM_MATCH_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_node(parser, (pm_node_t *)((pm_match_write_node_t *)node)->call, buffer); + uint32_t targets_size = pm_sizet_to_u32(((pm_match_write_node_t *)node)->targets.size); + pm_buffer_append_varuint(buffer, targets_size); + for (uint32_t index = 0; index < targets_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_match_write_node_t *)node)->targets.nodes[index], buffer); + } + break; + } + case PM_MISSING_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + break; + } + case PM_MODULE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + uint32_t locals_size = pm_sizet_to_u32(((pm_module_node_t *)node)->locals.size); + pm_buffer_append_varuint(buffer, locals_size); + for (uint32_t index = 0; index < locals_size; index++) { + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_module_node_t *)node)->locals.ids[index])); + } + pm_serialize_location(parser, &((pm_module_node_t *)node)->module_keyword_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_module_node_t *)node)->constant_path, buffer); + if (((pm_module_node_t *)node)->body == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_module_node_t *)node)->body, buffer); + } + pm_serialize_location(parser, &((pm_module_node_t *)node)->end_keyword_loc, buffer); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_module_node_t *)node)->name)); + break; + } + case PM_MULTI_TARGET_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + uint32_t lefts_size = pm_sizet_to_u32(((pm_multi_target_node_t *)node)->lefts.size); + pm_buffer_append_varuint(buffer, lefts_size); + for (uint32_t index = 0; index < lefts_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_multi_target_node_t *)node)->lefts.nodes[index], buffer); + } + if (((pm_multi_target_node_t *)node)->rest == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_multi_target_node_t *)node)->rest, buffer); + } + uint32_t rights_size = pm_sizet_to_u32(((pm_multi_target_node_t *)node)->rights.size); + pm_buffer_append_varuint(buffer, rights_size); + for (uint32_t index = 0; index < rights_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_multi_target_node_t *)node)->rights.nodes[index], buffer); + } + if (((pm_multi_target_node_t *)node)->lparen_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_multi_target_node_t *)node)->lparen_loc, buffer); + } + if (((pm_multi_target_node_t *)node)->rparen_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_multi_target_node_t *)node)->rparen_loc, buffer); + } + break; + } + case PM_MULTI_WRITE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + uint32_t lefts_size = pm_sizet_to_u32(((pm_multi_write_node_t *)node)->lefts.size); + pm_buffer_append_varuint(buffer, lefts_size); + for (uint32_t index = 0; index < lefts_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_multi_write_node_t *)node)->lefts.nodes[index], buffer); + } + if (((pm_multi_write_node_t *)node)->rest == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_multi_write_node_t *)node)->rest, buffer); + } + uint32_t rights_size = pm_sizet_to_u32(((pm_multi_write_node_t *)node)->rights.size); + pm_buffer_append_varuint(buffer, rights_size); + for (uint32_t index = 0; index < rights_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_multi_write_node_t *)node)->rights.nodes[index], buffer); + } + if (((pm_multi_write_node_t *)node)->lparen_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_multi_write_node_t *)node)->lparen_loc, buffer); + } + if (((pm_multi_write_node_t *)node)->rparen_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_multi_write_node_t *)node)->rparen_loc, buffer); + } + pm_serialize_location(parser, &((pm_multi_write_node_t *)node)->operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_multi_write_node_t *)node)->value, buffer); + break; + } + case PM_NEXT_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_next_node_t *)node)->arguments == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_next_node_t *)node)->arguments, buffer); + } + pm_serialize_location(parser, &((pm_next_node_t *)node)->keyword_loc, buffer); + break; + } + case PM_NIL_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + break; + } + case PM_NO_KEYWORDS_PARAMETER_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_location(parser, &((pm_no_keywords_parameter_node_t *)node)->operator_loc, buffer); + pm_serialize_location(parser, &((pm_no_keywords_parameter_node_t *)node)->keyword_loc, buffer); + break; + } + case PM_NUMBERED_PARAMETERS_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_byte(buffer, ((pm_numbered_parameters_node_t *)node)->maximum); + break; + } + case PM_NUMBERED_REFERENCE_READ_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, ((pm_numbered_reference_read_node_t *)node)->number); + break; + } + case PM_OPTIONAL_KEYWORD_PARAMETER_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_optional_keyword_parameter_node_t *)node)->name)); + pm_serialize_location(parser, &((pm_optional_keyword_parameter_node_t *)node)->name_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_optional_keyword_parameter_node_t *)node)->value, buffer); + break; + } + case PM_OPTIONAL_PARAMETER_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_optional_parameter_node_t *)node)->name)); + pm_serialize_location(parser, &((pm_optional_parameter_node_t *)node)->name_loc, buffer); + pm_serialize_location(parser, &((pm_optional_parameter_node_t *)node)->operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_optional_parameter_node_t *)node)->value, buffer); + break; + } + case PM_OR_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_node(parser, (pm_node_t *)((pm_or_node_t *)node)->left, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_or_node_t *)node)->right, buffer); + pm_serialize_location(parser, &((pm_or_node_t *)node)->operator_loc, buffer); + break; + } + case PM_PARAMETERS_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + uint32_t requireds_size = pm_sizet_to_u32(((pm_parameters_node_t *)node)->requireds.size); + pm_buffer_append_varuint(buffer, requireds_size); + for (uint32_t index = 0; index < requireds_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_parameters_node_t *)node)->requireds.nodes[index], buffer); + } + uint32_t optionals_size = pm_sizet_to_u32(((pm_parameters_node_t *)node)->optionals.size); + pm_buffer_append_varuint(buffer, optionals_size); + for (uint32_t index = 0; index < optionals_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_parameters_node_t *)node)->optionals.nodes[index], buffer); + } + if (((pm_parameters_node_t *)node)->rest == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_parameters_node_t *)node)->rest, buffer); + } + uint32_t posts_size = pm_sizet_to_u32(((pm_parameters_node_t *)node)->posts.size); + pm_buffer_append_varuint(buffer, posts_size); + for (uint32_t index = 0; index < posts_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_parameters_node_t *)node)->posts.nodes[index], buffer); + } + uint32_t keywords_size = pm_sizet_to_u32(((pm_parameters_node_t *)node)->keywords.size); + pm_buffer_append_varuint(buffer, keywords_size); + for (uint32_t index = 0; index < keywords_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_parameters_node_t *)node)->keywords.nodes[index], buffer); + } + if (((pm_parameters_node_t *)node)->keyword_rest == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_parameters_node_t *)node)->keyword_rest, buffer); + } + if (((pm_parameters_node_t *)node)->block == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_parameters_node_t *)node)->block, buffer); + } + break; + } + case PM_PARENTHESES_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_parentheses_node_t *)node)->body == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_parentheses_node_t *)node)->body, buffer); + } + pm_serialize_location(parser, &((pm_parentheses_node_t *)node)->opening_loc, buffer); + pm_serialize_location(parser, &((pm_parentheses_node_t *)node)->closing_loc, buffer); + break; + } + case PM_PINNED_EXPRESSION_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_node(parser, (pm_node_t *)((pm_pinned_expression_node_t *)node)->expression, buffer); + pm_serialize_location(parser, &((pm_pinned_expression_node_t *)node)->operator_loc, buffer); + pm_serialize_location(parser, &((pm_pinned_expression_node_t *)node)->lparen_loc, buffer); + pm_serialize_location(parser, &((pm_pinned_expression_node_t *)node)->rparen_loc, buffer); + break; + } + case PM_PINNED_VARIABLE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_node(parser, (pm_node_t *)((pm_pinned_variable_node_t *)node)->variable, buffer); + pm_serialize_location(parser, &((pm_pinned_variable_node_t *)node)->operator_loc, buffer); + break; + } + case PM_POST_EXECUTION_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_post_execution_node_t *)node)->statements == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_post_execution_node_t *)node)->statements, buffer); + } + pm_serialize_location(parser, &((pm_post_execution_node_t *)node)->keyword_loc, buffer); + pm_serialize_location(parser, &((pm_post_execution_node_t *)node)->opening_loc, buffer); + pm_serialize_location(parser, &((pm_post_execution_node_t *)node)->closing_loc, buffer); + break; + } + case PM_PRE_EXECUTION_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_pre_execution_node_t *)node)->statements == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_pre_execution_node_t *)node)->statements, buffer); + } + pm_serialize_location(parser, &((pm_pre_execution_node_t *)node)->keyword_loc, buffer); + pm_serialize_location(parser, &((pm_pre_execution_node_t *)node)->opening_loc, buffer); + pm_serialize_location(parser, &((pm_pre_execution_node_t *)node)->closing_loc, buffer); + break; + } + case PM_PROGRAM_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + uint32_t locals_size = pm_sizet_to_u32(((pm_program_node_t *)node)->locals.size); + pm_buffer_append_varuint(buffer, locals_size); + for (uint32_t index = 0; index < locals_size; index++) { + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_program_node_t *)node)->locals.ids[index])); + } + pm_serialize_node(parser, (pm_node_t *)((pm_program_node_t *)node)->statements, buffer); + break; + } + case PM_RANGE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_range_node_t *)node)->left == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_range_node_t *)node)->left, buffer); + } + if (((pm_range_node_t *)node)->right == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_range_node_t *)node)->right, buffer); + } + pm_serialize_location(parser, &((pm_range_node_t *)node)->operator_loc, buffer); + break; + } + case PM_RATIONAL_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_integer(&((pm_rational_node_t *)node)->numerator, buffer); + pm_serialize_integer(&((pm_rational_node_t *)node)->denominator, buffer); + break; + } + case PM_REDO_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + break; + } + case PM_REGULAR_EXPRESSION_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_location(parser, &((pm_regular_expression_node_t *)node)->opening_loc, buffer); + pm_serialize_location(parser, &((pm_regular_expression_node_t *)node)->content_loc, buffer); + pm_serialize_location(parser, &((pm_regular_expression_node_t *)node)->closing_loc, buffer); + pm_serialize_string(parser, &((pm_regular_expression_node_t *)node)->unescaped, buffer); + break; + } + case PM_REQUIRED_KEYWORD_PARAMETER_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_required_keyword_parameter_node_t *)node)->name)); + pm_serialize_location(parser, &((pm_required_keyword_parameter_node_t *)node)->name_loc, buffer); + break; + } + case PM_REQUIRED_PARAMETER_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_required_parameter_node_t *)node)->name)); + break; + } + case PM_RESCUE_MODIFIER_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_node(parser, (pm_node_t *)((pm_rescue_modifier_node_t *)node)->expression, buffer); + pm_serialize_location(parser, &((pm_rescue_modifier_node_t *)node)->keyword_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_rescue_modifier_node_t *)node)->rescue_expression, buffer); + break; + } + case PM_RESCUE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_location(parser, &((pm_rescue_node_t *)node)->keyword_loc, buffer); + uint32_t exceptions_size = pm_sizet_to_u32(((pm_rescue_node_t *)node)->exceptions.size); + pm_buffer_append_varuint(buffer, exceptions_size); + for (uint32_t index = 0; index < exceptions_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_rescue_node_t *)node)->exceptions.nodes[index], buffer); + } + if (((pm_rescue_node_t *)node)->operator_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_rescue_node_t *)node)->operator_loc, buffer); + } + if (((pm_rescue_node_t *)node)->reference == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_rescue_node_t *)node)->reference, buffer); + } + if (((pm_rescue_node_t *)node)->then_keyword_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_rescue_node_t *)node)->then_keyword_loc, buffer); + } + if (((pm_rescue_node_t *)node)->statements == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_rescue_node_t *)node)->statements, buffer); + } + if (((pm_rescue_node_t *)node)->subsequent == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_rescue_node_t *)node)->subsequent, buffer); + } + break; + } + case PM_REST_PARAMETER_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_rest_parameter_node_t *)node)->name)); + if (((pm_rest_parameter_node_t *)node)->name_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_rest_parameter_node_t *)node)->name_loc, buffer); + } + pm_serialize_location(parser, &((pm_rest_parameter_node_t *)node)->operator_loc, buffer); + break; + } + case PM_RETRY_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + break; + } + case PM_RETURN_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_location(parser, &((pm_return_node_t *)node)->keyword_loc, buffer); + if (((pm_return_node_t *)node)->arguments == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_return_node_t *)node)->arguments, buffer); + } + break; + } + case PM_SELF_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + break; + } + case PM_SHAREABLE_CONSTANT_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_node(parser, (pm_node_t *)((pm_shareable_constant_node_t *)node)->write, buffer); + break; + } + case PM_SINGLETON_CLASS_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + uint32_t locals_size = pm_sizet_to_u32(((pm_singleton_class_node_t *)node)->locals.size); + pm_buffer_append_varuint(buffer, locals_size); + for (uint32_t index = 0; index < locals_size; index++) { + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(((pm_singleton_class_node_t *)node)->locals.ids[index])); + } + pm_serialize_location(parser, &((pm_singleton_class_node_t *)node)->class_keyword_loc, buffer); + pm_serialize_location(parser, &((pm_singleton_class_node_t *)node)->operator_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_singleton_class_node_t *)node)->expression, buffer); + if (((pm_singleton_class_node_t *)node)->body == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_singleton_class_node_t *)node)->body, buffer); + } + pm_serialize_location(parser, &((pm_singleton_class_node_t *)node)->end_keyword_loc, buffer); + break; + } + case PM_SOURCE_ENCODING_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + break; + } + case PM_SOURCE_FILE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_string(parser, &((pm_source_file_node_t *)node)->filepath, buffer); + break; + } + case PM_SOURCE_LINE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + break; + } + case PM_SPLAT_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_location(parser, &((pm_splat_node_t *)node)->operator_loc, buffer); + if (((pm_splat_node_t *)node)->expression == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_splat_node_t *)node)->expression, buffer); + } + break; + } + case PM_STATEMENTS_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + uint32_t body_size = pm_sizet_to_u32(((pm_statements_node_t *)node)->body.size); + pm_buffer_append_varuint(buffer, body_size); + for (uint32_t index = 0; index < body_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_statements_node_t *)node)->body.nodes[index], buffer); + } + break; + } + case PM_STRING_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_string_node_t *)node)->opening_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_string_node_t *)node)->opening_loc, buffer); + } + pm_serialize_location(parser, &((pm_string_node_t *)node)->content_loc, buffer); + if (((pm_string_node_t *)node)->closing_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_string_node_t *)node)->closing_loc, buffer); + } + pm_serialize_string(parser, &((pm_string_node_t *)node)->unescaped, buffer); + break; + } + case PM_SUPER_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_location(parser, &((pm_super_node_t *)node)->keyword_loc, buffer); + if (((pm_super_node_t *)node)->lparen_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_super_node_t *)node)->lparen_loc, buffer); + } + if (((pm_super_node_t *)node)->arguments == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_super_node_t *)node)->arguments, buffer); + } + if (((pm_super_node_t *)node)->rparen_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_super_node_t *)node)->rparen_loc, buffer); + } + if (((pm_super_node_t *)node)->block == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_super_node_t *)node)->block, buffer); + } + break; + } + case PM_SYMBOL_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + if (((pm_symbol_node_t *)node)->opening_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_symbol_node_t *)node)->opening_loc, buffer); + } + if (((pm_symbol_node_t *)node)->value_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_symbol_node_t *)node)->value_loc, buffer); + } + if (((pm_symbol_node_t *)node)->closing_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_symbol_node_t *)node)->closing_loc, buffer); + } + pm_serialize_string(parser, &((pm_symbol_node_t *)node)->unescaped, buffer); + break; + } + case PM_TRUE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + break; + } + case PM_UNDEF_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + uint32_t names_size = pm_sizet_to_u32(((pm_undef_node_t *)node)->names.size); + pm_buffer_append_varuint(buffer, names_size); + for (uint32_t index = 0; index < names_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_undef_node_t *)node)->names.nodes[index], buffer); + } + pm_serialize_location(parser, &((pm_undef_node_t *)node)->keyword_loc, buffer); + break; + } + case PM_UNLESS_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_location(parser, &((pm_unless_node_t *)node)->keyword_loc, buffer); + pm_serialize_node(parser, (pm_node_t *)((pm_unless_node_t *)node)->predicate, buffer); + if (((pm_unless_node_t *)node)->then_keyword_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_unless_node_t *)node)->then_keyword_loc, buffer); + } + if (((pm_unless_node_t *)node)->statements == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_unless_node_t *)node)->statements, buffer); + } + if (((pm_unless_node_t *)node)->else_clause == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_unless_node_t *)node)->else_clause, buffer); + } + if (((pm_unless_node_t *)node)->end_keyword_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_unless_node_t *)node)->end_keyword_loc, buffer); + } + break; + } + case PM_UNTIL_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_location(parser, &((pm_until_node_t *)node)->keyword_loc, buffer); + if (((pm_until_node_t *)node)->do_keyword_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_until_node_t *)node)->do_keyword_loc, buffer); + } + if (((pm_until_node_t *)node)->closing_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_until_node_t *)node)->closing_loc, buffer); + } + pm_serialize_node(parser, (pm_node_t *)((pm_until_node_t *)node)->predicate, buffer); + if (((pm_until_node_t *)node)->statements == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_until_node_t *)node)->statements, buffer); + } + break; + } + case PM_WHEN_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_location(parser, &((pm_when_node_t *)node)->keyword_loc, buffer); + uint32_t conditions_size = pm_sizet_to_u32(((pm_when_node_t *)node)->conditions.size); + pm_buffer_append_varuint(buffer, conditions_size); + for (uint32_t index = 0; index < conditions_size; index++) { + pm_serialize_node(parser, (pm_node_t *) ((pm_when_node_t *)node)->conditions.nodes[index], buffer); + } + if (((pm_when_node_t *)node)->then_keyword_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_when_node_t *)node)->then_keyword_loc, buffer); + } + if (((pm_when_node_t *)node)->statements == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_when_node_t *)node)->statements, buffer); + } + break; + } + case PM_WHILE_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_location(parser, &((pm_while_node_t *)node)->keyword_loc, buffer); + if (((pm_while_node_t *)node)->do_keyword_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_while_node_t *)node)->do_keyword_loc, buffer); + } + if (((pm_while_node_t *)node)->closing_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_while_node_t *)node)->closing_loc, buffer); + } + pm_serialize_node(parser, (pm_node_t *)((pm_while_node_t *)node)->predicate, buffer); + if (((pm_while_node_t *)node)->statements == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_while_node_t *)node)->statements, buffer); + } + break; + } + case PM_X_STRING_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_location(parser, &((pm_x_string_node_t *)node)->opening_loc, buffer); + pm_serialize_location(parser, &((pm_x_string_node_t *)node)->content_loc, buffer); + pm_serialize_location(parser, &((pm_x_string_node_t *)node)->closing_loc, buffer); + pm_serialize_string(parser, &((pm_x_string_node_t *)node)->unescaped, buffer); + break; + } + case PM_YIELD_NODE: { + pm_buffer_append_varuint(buffer, (uint32_t) node->flags); + pm_serialize_location(parser, &((pm_yield_node_t *)node)->keyword_loc, buffer); + if (((pm_yield_node_t *)node)->lparen_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_yield_node_t *)node)->lparen_loc, buffer); + } + if (((pm_yield_node_t *)node)->arguments == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_serialize_node(parser, (pm_node_t *)((pm_yield_node_t *)node)->arguments, buffer); + } + if (((pm_yield_node_t *)node)->rparen_loc.start == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &((pm_yield_node_t *)node)->rparen_loc, buffer); + } + break; + } + } +} + +static void +pm_serialize_newline_list(pm_newline_list_t *list, pm_buffer_t *buffer) { + uint32_t size = pm_sizet_to_u32(list->size); + pm_buffer_append_varuint(buffer, size); + + for (uint32_t i = 0; i < size; i++) { + uint32_t offset = pm_sizet_to_u32(list->offsets[i]); + pm_buffer_append_varuint(buffer, offset); + } +} + +static void +pm_serialize_comment(pm_parser_t *parser, pm_comment_t *comment, pm_buffer_t *buffer) { + // serialize type + pm_buffer_append_byte(buffer, (uint8_t) comment->type); + + // serialize location + pm_serialize_location(parser, &comment->location, buffer); +} + +/** + * Serialize the given list of comments to the given buffer. + */ +void +pm_serialize_comment_list(pm_parser_t *parser, pm_list_t *list, pm_buffer_t *buffer) { + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(pm_list_size(list))); + + pm_comment_t *comment; + for (comment = (pm_comment_t *) list->head; comment != NULL; comment = (pm_comment_t *) comment->node.next) { + pm_serialize_comment(parser, comment, buffer); + } +} + +static void +pm_serialize_magic_comment(pm_parser_t *parser, pm_magic_comment_t *magic_comment, pm_buffer_t *buffer) { + // serialize key location + pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(magic_comment->key_start - parser->start)); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(magic_comment->key_length)); + + // serialize value location + pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(magic_comment->value_start - parser->start)); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(magic_comment->value_length)); +} + +static void +pm_serialize_magic_comment_list(pm_parser_t *parser, pm_list_t *list, pm_buffer_t *buffer) { + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(pm_list_size(list))); + + pm_magic_comment_t *magic_comment; + for (magic_comment = (pm_magic_comment_t *) list->head; magic_comment != NULL; magic_comment = (pm_magic_comment_t *) magic_comment->node.next) { + pm_serialize_magic_comment(parser, magic_comment, buffer); + } +} + +static void +pm_serialize_data_loc(const pm_parser_t *parser, pm_buffer_t *buffer) { + if (parser->data_loc.end == NULL) { + pm_buffer_append_byte(buffer, 0); + } else { + pm_buffer_append_byte(buffer, 1); + pm_serialize_location(parser, &parser->data_loc, buffer); + } +} + +static void +pm_serialize_diagnostic(pm_parser_t *parser, pm_diagnostic_t *diagnostic, pm_buffer_t *buffer) { + // serialize the type + pm_buffer_append_varuint(buffer, (uint32_t) diagnostic->diag_id); + + // serialize message + size_t message_length = strlen(diagnostic->message); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(message_length)); + pm_buffer_append_string(buffer, diagnostic->message, message_length); + + // serialize location + pm_serialize_location(parser, &diagnostic->location, buffer); + + pm_buffer_append_byte(buffer, diagnostic->level); +} + +static void +pm_serialize_diagnostic_list(pm_parser_t *parser, pm_list_t *list, pm_buffer_t *buffer) { + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(pm_list_size(list))); + + pm_diagnostic_t *diagnostic; + for (diagnostic = (pm_diagnostic_t *) list->head; diagnostic != NULL; diagnostic = (pm_diagnostic_t *) diagnostic->node.next) { + pm_serialize_diagnostic(parser, diagnostic, buffer); + } +} + +/** + * Serialize the name of the encoding to the buffer. + */ +void +pm_serialize_encoding(const pm_encoding_t *encoding, pm_buffer_t *buffer) { + size_t encoding_length = strlen(encoding->name); + pm_buffer_append_varuint(buffer, pm_sizet_to_u32(encoding_length)); + pm_buffer_append_string(buffer, encoding->name, encoding_length); +} + +static void +pm_serialize_metadata(pm_parser_t *parser, pm_buffer_t *buffer) { + pm_serialize_encoding(parser->encoding, buffer); + pm_buffer_append_varsint(buffer, parser->start_line); + pm_serialize_newline_list(&parser->newline_list, buffer); + pm_serialize_comment_list(parser, &parser->comment_list, buffer); + pm_serialize_magic_comment_list(parser, &parser->magic_comment_list, buffer); + pm_serialize_data_loc(parser, buffer); + pm_serialize_diagnostic_list(parser, &parser->error_list, buffer); + pm_serialize_diagnostic_list(parser, &parser->warning_list, buffer); +} + +#line 275 "prism/templates/src/serialize.c.erb" +/** + * Serialize the metadata, nodes, and constant pool. + */ +void +pm_serialize_content(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) { + pm_serialize_metadata(parser, buffer); + + // Here we're going to leave space for the offset of the constant pool in + // the buffer. + size_t offset = buffer->length; + pm_buffer_append_zeroes(buffer, 4); + + // Next, encode the length of the constant pool. + pm_buffer_append_varuint(buffer, parser->constant_pool.size); + + // Now we're going to serialize the content of the node. + pm_serialize_node(parser, node, buffer); + + // Now we're going to serialize the offset of the constant pool back where + // we left space for it. + uint32_t length = pm_sizet_to_u32(buffer->length); + memcpy(buffer->value + offset, &length, sizeof(uint32_t)); + + // Now we're going to serialize the constant pool. + offset = buffer->length; + pm_buffer_append_zeroes(buffer, parser->constant_pool.size * 8); + + for (uint32_t index = 0; index < parser->constant_pool.capacity; index++) { + pm_constant_pool_bucket_t *bucket = &parser->constant_pool.buckets[index]; + + // If we find a constant at this index, serialize it at the correct + // index in the buffer. + if (bucket->id != 0) { + pm_constant_t *constant = &parser->constant_pool.constants[bucket->id - 1]; + size_t buffer_offset = offset + ((((size_t)bucket->id) - 1) * 8); + + if (bucket->type == PM_CONSTANT_POOL_BUCKET_OWNED || bucket->type == PM_CONSTANT_POOL_BUCKET_CONSTANT) { + // Since this is an owned or constant constant, we are going to + // write its contents into the buffer after the constant pool. + // So effectively in place of the source offset, we have a + // buffer offset. We will add a leading 1 to indicate that this + // is a buffer offset. + uint32_t content_offset = pm_sizet_to_u32(buffer->length); + uint32_t owned_mask = (uint32_t) (1 << 31); + + assert(content_offset < owned_mask); + content_offset |= owned_mask; + + memcpy(buffer->value + buffer_offset, &content_offset, 4); + pm_buffer_append_bytes(buffer, constant->start, constant->length); + } else { + // Since this is a shared constant, we are going to write its + // source offset directly into the buffer. + uint32_t source_offset = pm_ptrdifft_to_u32(constant->start - parser->start); + memcpy(buffer->value + buffer_offset, &source_offset, 4); + } + + // Now we can write the length of the constant into the buffer. + uint32_t constant_length = pm_sizet_to_u32(constant->length); + memcpy(buffer->value + buffer_offset + 4, &constant_length, 4); + } + } +} + +static void +serialize_token(void *data, pm_parser_t *parser, pm_token_t *token) { + pm_buffer_t *buffer = (pm_buffer_t *) data; + + pm_buffer_append_varuint(buffer, token->type); + pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(token->start - parser->start)); + pm_buffer_append_varuint(buffer, pm_ptrdifft_to_u32(token->end - token->start)); + pm_buffer_append_varuint(buffer, parser->lex_state); +} + +/** + * Lex the given source and serialize to the given buffer. + */ +PRISM_EXPORTED_FUNCTION void +pm_serialize_lex(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data) { + pm_options_t options = { 0 }; + pm_options_read(&options, data); + + pm_parser_t parser; + pm_parser_init(&parser, source, size, &options); + + pm_lex_callback_t lex_callback = (pm_lex_callback_t) { + .data = (void *) buffer, + .callback = serialize_token, + }; + + parser.lex_callback = &lex_callback; + pm_node_t *node = pm_parse(&parser); + + // Append 0 to mark end of tokens. + pm_buffer_append_byte(buffer, 0); + + pm_serialize_metadata(&parser, buffer); + + pm_node_destroy(&parser, node); + pm_parser_free(&parser); + pm_options_free(&options); +} + +/** + * Parse and serialize both the AST and the tokens represented by the given + * source to the given buffer. + */ +PRISM_EXPORTED_FUNCTION void +pm_serialize_parse_lex(pm_buffer_t *buffer, const uint8_t *source, size_t size, const char *data) { + pm_options_t options = { 0 }; + pm_options_read(&options, data); + + pm_parser_t parser; + pm_parser_init(&parser, source, size, &options); + + pm_lex_callback_t lex_callback = (pm_lex_callback_t) { + .data = (void *) buffer, + .callback = serialize_token, + }; + + parser.lex_callback = &lex_callback; + pm_node_t *node = pm_parse(&parser); + + pm_buffer_append_byte(buffer, 0); + pm_serialize(&parser, node, buffer); + + pm_node_destroy(&parser, node); + pm_parser_free(&parser); + pm_options_free(&options); +} + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/static_literals.c b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/static_literals.c new file mode 100644 index 00000000..9fa37b99 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/static_literals.c @@ -0,0 +1,617 @@ +#include "prism/static_literals.h" + +/** + * A small struct used for passing around a subset of the information that is + * stored on the parser. We use this to avoid having static literals explicitly + * depend on the parser struct. + */ +typedef struct { + /** The list of newline offsets to use to calculate line numbers. */ + const pm_newline_list_t *newline_list; + + /** The line number that the parser starts on. */ + int32_t start_line; + + /** The name of the encoding that the parser is using. */ + const char *encoding_name; +} pm_static_literals_metadata_t; + +static inline uint32_t +murmur_scramble(uint32_t value) { + value *= 0xcc9e2d51; + value = (value << 15) | (value >> 17); + value *= 0x1b873593; + return value; +} + +/** + * Murmur hash (https://en.wikipedia.org/wiki/MurmurHash) is a non-cryptographic + * general-purpose hash function. It is fast, which is what we care about in + * this case. + */ +static uint32_t +murmur_hash(const uint8_t *key, size_t length) { + uint32_t hash = 0x9747b28c; + uint32_t segment; + + for (size_t index = length >> 2; index; index--) { + memcpy(&segment, key, sizeof(uint32_t)); + key += sizeof(uint32_t); + hash ^= murmur_scramble(segment); + hash = (hash << 13) | (hash >> 19); + hash = hash * 5 + 0xe6546b64; + } + + segment = 0; + for (size_t index = length & 3; index; index--) { + segment <<= 8; + segment |= key[index - 1]; + } + + hash ^= murmur_scramble(segment); + hash ^= (uint32_t) length; + hash ^= hash >> 16; + hash *= 0x85ebca6b; + hash ^= hash >> 13; + hash *= 0xc2b2ae35; + hash ^= hash >> 16; + return hash; +} + +/** + * Hash the value of an integer and return it. + */ +static uint32_t +integer_hash(const pm_integer_t *integer) { + uint32_t hash; + if (integer->values) { + hash = murmur_hash((const uint8_t *) integer->values, sizeof(uint32_t) * integer->length); + } else { + hash = murmur_hash((const uint8_t *) &integer->value, sizeof(uint32_t)); + } + + if (integer->negative) { + hash ^= murmur_scramble((uint32_t) 1); + } + + return hash; +} + +/** + * Return the hash of the given node. It is important that nodes that have + * equivalent static literal values have the same hash. This is because we use + * these hashes to look for duplicates. + */ +static uint32_t +node_hash(const pm_static_literals_metadata_t *metadata, const pm_node_t *node) { + switch (PM_NODE_TYPE(node)) { + case PM_INTEGER_NODE: { + // Integers hash their value. + const pm_integer_node_t *cast = (const pm_integer_node_t *) node; + return integer_hash(&cast->value); + } + case PM_SOURCE_LINE_NODE: { + // Source lines hash their line number. + const pm_line_column_t line_column = pm_newline_list_line_column(metadata->newline_list, node->location.start, metadata->start_line); + const int32_t *value = &line_column.line; + return murmur_hash((const uint8_t *) value, sizeof(int32_t)); + } + case PM_FLOAT_NODE: { + // Floats hash their value. + const double *value = &((const pm_float_node_t *) node)->value; + return murmur_hash((const uint8_t *) value, sizeof(double)); + } + case PM_RATIONAL_NODE: { + // Rationals hash their numerator and denominator. + const pm_rational_node_t *cast = (const pm_rational_node_t *) node; + return integer_hash(&cast->numerator) ^ integer_hash(&cast->denominator) ^ murmur_scramble((uint32_t) cast->base.type); + } + case PM_IMAGINARY_NODE: { + // Imaginaries hash their numeric value. Because their numeric value + // is stored as a subnode, we hash that node and then mix in the + // fact that this is an imaginary node. + const pm_node_t *numeric = ((const pm_imaginary_node_t *) node)->numeric; + return node_hash(metadata, numeric) ^ murmur_scramble((uint32_t) node->type); + } + case PM_STRING_NODE: { + // Strings hash their value and mix in their flags so that different + // encodings are not considered equal. + const pm_string_t *value = &((const pm_string_node_t *) node)->unescaped; + + pm_node_flags_t flags = node->flags; + flags &= (PM_STRING_FLAGS_FORCED_BINARY_ENCODING | PM_STRING_FLAGS_FORCED_UTF8_ENCODING); + + return murmur_hash(pm_string_source(value), pm_string_length(value) * sizeof(uint8_t)) ^ murmur_scramble((uint32_t) flags); + } + case PM_SOURCE_FILE_NODE: { + // Source files hash their value and mix in their flags so that + // different encodings are not considered equal. + const pm_string_t *value = &((const pm_source_file_node_t *) node)->filepath; + return murmur_hash(pm_string_source(value), pm_string_length(value) * sizeof(uint8_t)); + } + case PM_REGULAR_EXPRESSION_NODE: { + // Regular expressions hash their value and mix in their flags so + // that different encodings are not considered equal. + const pm_string_t *value = &((const pm_regular_expression_node_t *) node)->unescaped; + return murmur_hash(pm_string_source(value), pm_string_length(value) * sizeof(uint8_t)) ^ murmur_scramble((uint32_t) node->flags); + } + case PM_SYMBOL_NODE: { + // Symbols hash their value and mix in their flags so that different + // encodings are not considered equal. + const pm_string_t *value = &((const pm_symbol_node_t *) node)->unescaped; + return murmur_hash(pm_string_source(value), pm_string_length(value) * sizeof(uint8_t)) ^ murmur_scramble((uint32_t) node->flags); + } + default: + assert(false && "unreachable"); + return 0; + } +} + +/** + * Insert a node into the node hash. It accepts the hash that should hold the + * new node, the parser that generated the node, the node to insert, and a + * comparison function. The comparison function is used for collision detection, + * and must be able to compare all node types that will be stored in this hash. + */ +static pm_node_t * +pm_node_hash_insert(pm_node_hash_t *hash, const pm_static_literals_metadata_t *metadata, pm_node_t *node, bool replace, int (*compare)(const pm_static_literals_metadata_t *metadata, const pm_node_t *left, const pm_node_t *right)) { + // If we are out of space, we need to resize the hash. This will cause all + // of the nodes to be rehashed and reinserted into the new hash. + if (hash->size * 2 >= hash->capacity) { + // First, allocate space for the new node list. + uint32_t new_capacity = hash->capacity == 0 ? 4 : hash->capacity * 2; + pm_node_t **new_nodes = xcalloc(new_capacity, sizeof(pm_node_t *)); + if (new_nodes == NULL) return NULL; + + // It turns out to be more efficient to mask the hash value than to use + // the modulo operator. Because our capacities are always powers of two, + // we can use a bitwise AND to get the same result as the modulo + // operator. + uint32_t mask = new_capacity - 1; + + // Now, rehash all of the nodes into the new list. + for (uint32_t index = 0; index < hash->capacity; index++) { + pm_node_t *node = hash->nodes[index]; + + if (node != NULL) { + uint32_t index = node_hash(metadata, node) & mask; + new_nodes[index] = node; + } + } + + // Finally, free the old node list and update the hash. + xfree(hash->nodes); + hash->nodes = new_nodes; + hash->capacity = new_capacity; + } + + // Now, insert the node into the hash. + uint32_t mask = hash->capacity - 1; + uint32_t index = node_hash(metadata, node) & mask; + + // We use linear probing to resolve collisions. This means that if the + // current index is occupied, we will move to the next index and try again. + // We are guaranteed that this will eventually find an empty slot because we + // resize the hash when it gets too full. + while (hash->nodes[index] != NULL) { + if (compare(metadata, hash->nodes[index], node) == 0) break; + index = (index + 1) & mask; + } + + // If the current index is occupied, we need to return the node that was + // already in the hash. Otherwise, we can just increment the size and insert + // the new node. + pm_node_t *result = hash->nodes[index]; + + if (result == NULL) { + hash->size++; + hash->nodes[index] = node; + } else if (replace) { + hash->nodes[index] = node; + } + + return result; +} + +/** + * Free the internal memory associated with the given node hash. + */ +static void +pm_node_hash_free(pm_node_hash_t *hash) { + if (hash->capacity > 0) xfree(hash->nodes); +} + +/** + * Compare two values that can be compared with a simple numeric comparison. + */ +#define PM_NUMERIC_COMPARISON(left, right) ((left < right) ? -1 : (left > right) ? 1 : 0) + +/** + * Return the integer value of the given node as an int64_t. + */ +static int64_t +pm_int64_value(const pm_static_literals_metadata_t *metadata, const pm_node_t *node) { + switch (PM_NODE_TYPE(node)) { + case PM_INTEGER_NODE: { + const pm_integer_t *integer = &((const pm_integer_node_t *) node)->value; + if (integer->values) return integer->negative ? INT64_MIN : INT64_MAX; + + int64_t value = (int64_t) integer->value; + return integer->negative ? -value : value; + } + case PM_SOURCE_LINE_NODE: + return (int64_t) pm_newline_list_line_column(metadata->newline_list, node->location.start, metadata->start_line).line; + default: + assert(false && "unreachable"); + return 0; + } +} + +/** + * A comparison function for comparing two IntegerNode or SourceLineNode + * instances. + */ +static int +pm_compare_integer_nodes(const pm_static_literals_metadata_t *metadata, const pm_node_t *left, const pm_node_t *right) { + if (PM_NODE_TYPE_P(left, PM_SOURCE_LINE_NODE) || PM_NODE_TYPE_P(right, PM_SOURCE_LINE_NODE)) { + int64_t left_value = pm_int64_value(metadata, left); + int64_t right_value = pm_int64_value(metadata, right); + return PM_NUMERIC_COMPARISON(left_value, right_value); + } + + const pm_integer_t *left_integer = &((const pm_integer_node_t *) left)->value; + const pm_integer_t *right_integer = &((const pm_integer_node_t *) right)->value; + return pm_integer_compare(left_integer, right_integer); +} + +/** + * A comparison function for comparing two FloatNode instances. + */ +static int +pm_compare_float_nodes(PRISM_ATTRIBUTE_UNUSED const pm_static_literals_metadata_t *metadata, const pm_node_t *left, const pm_node_t *right) { + const double left_value = ((const pm_float_node_t *) left)->value; + const double right_value = ((const pm_float_node_t *) right)->value; + return PM_NUMERIC_COMPARISON(left_value, right_value); +} + +/** + * A comparison function for comparing two nodes that have attached numbers. + */ +static int +pm_compare_number_nodes(const pm_static_literals_metadata_t *metadata, const pm_node_t *left, const pm_node_t *right) { + if (PM_NODE_TYPE(left) != PM_NODE_TYPE(right)) { + return PM_NUMERIC_COMPARISON(PM_NODE_TYPE(left), PM_NODE_TYPE(right)); + } + + switch (PM_NODE_TYPE(left)) { + case PM_IMAGINARY_NODE: + return pm_compare_number_nodes(metadata, ((const pm_imaginary_node_t *) left)->numeric, ((const pm_imaginary_node_t *) right)->numeric); + case PM_RATIONAL_NODE: { + const pm_rational_node_t *left_rational = (const pm_rational_node_t *) left; + const pm_rational_node_t *right_rational = (const pm_rational_node_t *) right; + + int result = pm_integer_compare(&left_rational->denominator, &right_rational->denominator); + if (result != 0) return result; + + return pm_integer_compare(&left_rational->numerator, &right_rational->numerator); + } + case PM_INTEGER_NODE: + return pm_compare_integer_nodes(metadata, left, right); + case PM_FLOAT_NODE: + return pm_compare_float_nodes(metadata, left, right); + default: + assert(false && "unreachable"); + return 0; + } +} + +/** + * Return a pointer to the string value of the given node. + */ +static const pm_string_t * +pm_string_value(const pm_node_t *node) { + switch (PM_NODE_TYPE(node)) { + case PM_STRING_NODE: + return &((const pm_string_node_t *) node)->unescaped; + case PM_SOURCE_FILE_NODE: + return &((const pm_source_file_node_t *) node)->filepath; + case PM_SYMBOL_NODE: + return &((const pm_symbol_node_t *) node)->unescaped; + default: + assert(false && "unreachable"); + return NULL; + } +} + +/** + * A comparison function for comparing two nodes that have attached strings. + */ +static int +pm_compare_string_nodes(PRISM_ATTRIBUTE_UNUSED const pm_static_literals_metadata_t *metadata, const pm_node_t *left, const pm_node_t *right) { + const pm_string_t *left_string = pm_string_value(left); + const pm_string_t *right_string = pm_string_value(right); + return pm_string_compare(left_string, right_string); +} + +/** + * A comparison function for comparing two RegularExpressionNode instances. + */ +static int +pm_compare_regular_expression_nodes(PRISM_ATTRIBUTE_UNUSED const pm_static_literals_metadata_t *metadata, const pm_node_t *left, const pm_node_t *right) { + const pm_regular_expression_node_t *left_regexp = (const pm_regular_expression_node_t *) left; + const pm_regular_expression_node_t *right_regexp = (const pm_regular_expression_node_t *) right; + + int result = pm_string_compare(&left_regexp->unescaped, &right_regexp->unescaped); + if (result != 0) return result; + + return PM_NUMERIC_COMPARISON(left_regexp->base.flags, right_regexp->base.flags); +} + +#undef PM_NUMERIC_COMPARISON + +/** + * Add a node to the set of static literals. + */ +pm_node_t * +pm_static_literals_add(const pm_newline_list_t *newline_list, int32_t start_line, pm_static_literals_t *literals, pm_node_t *node, bool replace) { + switch (PM_NODE_TYPE(node)) { + case PM_INTEGER_NODE: + case PM_SOURCE_LINE_NODE: + return pm_node_hash_insert( + &literals->integer_nodes, + &(pm_static_literals_metadata_t) { + .newline_list = newline_list, + .start_line = start_line, + .encoding_name = NULL + }, + node, + replace, + pm_compare_integer_nodes + ); + case PM_FLOAT_NODE: + return pm_node_hash_insert( + &literals->float_nodes, + &(pm_static_literals_metadata_t) { + .newline_list = newline_list, + .start_line = start_line, + .encoding_name = NULL + }, + node, + replace, + pm_compare_float_nodes + ); + case PM_RATIONAL_NODE: + case PM_IMAGINARY_NODE: + return pm_node_hash_insert( + &literals->number_nodes, + &(pm_static_literals_metadata_t) { + .newline_list = newline_list, + .start_line = start_line, + .encoding_name = NULL + }, + node, + replace, + pm_compare_number_nodes + ); + case PM_STRING_NODE: + case PM_SOURCE_FILE_NODE: + return pm_node_hash_insert( + &literals->string_nodes, + &(pm_static_literals_metadata_t) { + .newline_list = newline_list, + .start_line = start_line, + .encoding_name = NULL + }, + node, + replace, + pm_compare_string_nodes + ); + case PM_REGULAR_EXPRESSION_NODE: + return pm_node_hash_insert( + &literals->regexp_nodes, + &(pm_static_literals_metadata_t) { + .newline_list = newline_list, + .start_line = start_line, + .encoding_name = NULL + }, + node, + replace, + pm_compare_regular_expression_nodes + ); + case PM_SYMBOL_NODE: + return pm_node_hash_insert( + &literals->symbol_nodes, + &(pm_static_literals_metadata_t) { + .newline_list = newline_list, + .start_line = start_line, + .encoding_name = NULL + }, + node, + replace, + pm_compare_string_nodes + ); + case PM_TRUE_NODE: { + pm_node_t *duplicated = literals->true_node; + if ((duplicated == NULL) || replace) literals->true_node = node; + return duplicated; + } + case PM_FALSE_NODE: { + pm_node_t *duplicated = literals->false_node; + if ((duplicated == NULL) || replace) literals->false_node = node; + return duplicated; + } + case PM_NIL_NODE: { + pm_node_t *duplicated = literals->nil_node; + if ((duplicated == NULL) || replace) literals->nil_node = node; + return duplicated; + } + case PM_SOURCE_ENCODING_NODE: { + pm_node_t *duplicated = literals->source_encoding_node; + if ((duplicated == NULL) || replace) literals->source_encoding_node = node; + return duplicated; + } + default: + return NULL; + } +} + +/** + * Free the internal memory associated with the given static literals set. + */ +void +pm_static_literals_free(pm_static_literals_t *literals) { + pm_node_hash_free(&literals->integer_nodes); + pm_node_hash_free(&literals->float_nodes); + pm_node_hash_free(&literals->number_nodes); + pm_node_hash_free(&literals->string_nodes); + pm_node_hash_free(&literals->regexp_nodes); + pm_node_hash_free(&literals->symbol_nodes); +} + +/** + * A helper to determine if the given node is a static literal that is positive. + * This is used for formatting imaginary nodes. + */ +static bool +pm_static_literal_positive_p(const pm_node_t *node) { + switch (PM_NODE_TYPE(node)) { + case PM_FLOAT_NODE: + return ((const pm_float_node_t *) node)->value > 0; + case PM_INTEGER_NODE: + return !((const pm_integer_node_t *) node)->value.negative; + case PM_RATIONAL_NODE: + return !((const pm_rational_node_t *) node)->numerator.negative; + case PM_IMAGINARY_NODE: + return pm_static_literal_positive_p(((const pm_imaginary_node_t *) node)->numeric); + default: + assert(false && "unreachable"); + return false; + } +} + +/** + * Create a string-based representation of the given static literal. + */ +static inline void +pm_static_literal_inspect_node(pm_buffer_t *buffer, const pm_static_literals_metadata_t *metadata, const pm_node_t *node) { + switch (PM_NODE_TYPE(node)) { + case PM_FALSE_NODE: + pm_buffer_append_string(buffer, "false", 5); + break; + case PM_FLOAT_NODE: { + const double value = ((const pm_float_node_t *) node)->value; + + if (PRISM_ISINF(value)) { + if (*node->location.start == '-') { + pm_buffer_append_byte(buffer, '-'); + } + pm_buffer_append_string(buffer, "Infinity", 8); + } else if (value == 0.0) { + if (*node->location.start == '-') { + pm_buffer_append_byte(buffer, '-'); + } + pm_buffer_append_string(buffer, "0.0", 3); + } else { + pm_buffer_append_format(buffer, "%g", value); + + // %g will not insert a .0 for 1e100 (we'll get back 1e+100). So + // we check for the decimal point and add it in here if it's not + // present. + if (pm_buffer_index(buffer, '.') == SIZE_MAX) { + size_t exponent_index = pm_buffer_index(buffer, 'e'); + size_t index = exponent_index == SIZE_MAX ? pm_buffer_length(buffer) : exponent_index; + pm_buffer_insert(buffer, index, ".0", 2); + } + } + + break; + } + case PM_IMAGINARY_NODE: { + const pm_node_t *numeric = ((const pm_imaginary_node_t *) node)->numeric; + pm_buffer_append_string(buffer, "(0", 2); + if (pm_static_literal_positive_p(numeric)) pm_buffer_append_byte(buffer, '+'); + pm_static_literal_inspect_node(buffer, metadata, numeric); + if (PM_NODE_TYPE_P(numeric, PM_RATIONAL_NODE)) { + pm_buffer_append_byte(buffer, '*'); + } + pm_buffer_append_string(buffer, "i)", 2); + break; + } + case PM_INTEGER_NODE: + pm_integer_string(buffer, &((const pm_integer_node_t *) node)->value); + break; + case PM_NIL_NODE: + pm_buffer_append_string(buffer, "nil", 3); + break; + case PM_RATIONAL_NODE: { + const pm_rational_node_t *rational = (const pm_rational_node_t *) node; + pm_buffer_append_byte(buffer, '('); + pm_integer_string(buffer, &rational->numerator); + pm_buffer_append_byte(buffer, '/'); + pm_integer_string(buffer, &rational->denominator); + pm_buffer_append_byte(buffer, ')'); + break; + } + case PM_REGULAR_EXPRESSION_NODE: { + const pm_string_t *unescaped = &((const pm_regular_expression_node_t *) node)->unescaped; + pm_buffer_append_byte(buffer, '/'); + pm_buffer_append_source(buffer, pm_string_source(unescaped), pm_string_length(unescaped), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_byte(buffer, '/'); + + if (PM_NODE_FLAG_P(node, PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE)) pm_buffer_append_string(buffer, "m", 1); + if (PM_NODE_FLAG_P(node, PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE)) pm_buffer_append_string(buffer, "i", 1); + if (PM_NODE_FLAG_P(node, PM_REGULAR_EXPRESSION_FLAGS_EXTENDED)) pm_buffer_append_string(buffer, "x", 1); + if (PM_NODE_FLAG_P(node, PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT)) pm_buffer_append_string(buffer, "n", 1); + + break; + } + case PM_SOURCE_ENCODING_NODE: + pm_buffer_append_format(buffer, "#", metadata->encoding_name); + break; + case PM_SOURCE_FILE_NODE: { + const pm_string_t *filepath = &((const pm_source_file_node_t *) node)->filepath; + pm_buffer_append_byte(buffer, '"'); + pm_buffer_append_source(buffer, pm_string_source(filepath), pm_string_length(filepath), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_byte(buffer, '"'); + break; + } + case PM_SOURCE_LINE_NODE: + pm_buffer_append_format(buffer, "%d", pm_newline_list_line_column(metadata->newline_list, node->location.start, metadata->start_line).line); + break; + case PM_STRING_NODE: { + const pm_string_t *unescaped = &((const pm_string_node_t *) node)->unescaped; + pm_buffer_append_byte(buffer, '"'); + pm_buffer_append_source(buffer, pm_string_source(unescaped), pm_string_length(unescaped), PM_BUFFER_ESCAPING_RUBY); + pm_buffer_append_byte(buffer, '"'); + break; + } + case PM_SYMBOL_NODE: { + const pm_string_t *unescaped = &((const pm_symbol_node_t *) node)->unescaped; + pm_buffer_append_byte(buffer, ':'); + pm_buffer_append_source(buffer, pm_string_source(unescaped), pm_string_length(unescaped), PM_BUFFER_ESCAPING_RUBY); + break; + } + case PM_TRUE_NODE: + pm_buffer_append_string(buffer, "true", 4); + break; + default: + assert(false && "unreachable"); + break; + } +} + +/** + * Create a string-based representation of the given static literal. + */ +void +pm_static_literal_inspect(pm_buffer_t *buffer, const pm_newline_list_t *newline_list, int32_t start_line, const char *encoding_name, const pm_node_t *node) { + pm_static_literal_inspect_node( + buffer, + &(pm_static_literals_metadata_t) { + .newline_list = newline_list, + .start_line = start_line, + .encoding_name = encoding_name + }, + node + ); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/token_type.c b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/token_type.c new file mode 100644 index 00000000..ba2d7514 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/token_type.c @@ -0,0 +1,701 @@ +/*----------------------------------------------------------------------------*/ +/* This file is generated by the templates/template.rb script and should not */ +/* be modified manually. See */ +/* templates/src/token_type.c.erb */ +/* if you are looking to modify the */ +/* template */ +/*----------------------------------------------------------------------------*/ + +#include + +#include "prism/ast.h" + +/** + * Returns a string representation of the given token type. + */ +PRISM_EXPORTED_FUNCTION const char * +pm_token_type_name(pm_token_type_t token_type) { + switch (token_type) { + case PM_TOKEN_EOF: + return "EOF"; + case PM_TOKEN_MISSING: + return "MISSING"; + case PM_TOKEN_NOT_PROVIDED: + return "NOT_PROVIDED"; + case PM_TOKEN_AMPERSAND: + return "AMPERSAND"; + case PM_TOKEN_AMPERSAND_AMPERSAND: + return "AMPERSAND_AMPERSAND"; + case PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL: + return "AMPERSAND_AMPERSAND_EQUAL"; + case PM_TOKEN_AMPERSAND_DOT: + return "AMPERSAND_DOT"; + case PM_TOKEN_AMPERSAND_EQUAL: + return "AMPERSAND_EQUAL"; + case PM_TOKEN_BACKTICK: + return "BACKTICK"; + case PM_TOKEN_BACK_REFERENCE: + return "BACK_REFERENCE"; + case PM_TOKEN_BANG: + return "BANG"; + case PM_TOKEN_BANG_EQUAL: + return "BANG_EQUAL"; + case PM_TOKEN_BANG_TILDE: + return "BANG_TILDE"; + case PM_TOKEN_BRACE_LEFT: + return "BRACE_LEFT"; + case PM_TOKEN_BRACE_RIGHT: + return "BRACE_RIGHT"; + case PM_TOKEN_BRACKET_LEFT: + return "BRACKET_LEFT"; + case PM_TOKEN_BRACKET_LEFT_ARRAY: + return "BRACKET_LEFT_ARRAY"; + case PM_TOKEN_BRACKET_LEFT_RIGHT: + return "BRACKET_LEFT_RIGHT"; + case PM_TOKEN_BRACKET_LEFT_RIGHT_EQUAL: + return "BRACKET_LEFT_RIGHT_EQUAL"; + case PM_TOKEN_BRACKET_RIGHT: + return "BRACKET_RIGHT"; + case PM_TOKEN_CARET: + return "CARET"; + case PM_TOKEN_CARET_EQUAL: + return "CARET_EQUAL"; + case PM_TOKEN_CHARACTER_LITERAL: + return "CHARACTER_LITERAL"; + case PM_TOKEN_CLASS_VARIABLE: + return "CLASS_VARIABLE"; + case PM_TOKEN_COLON: + return "COLON"; + case PM_TOKEN_COLON_COLON: + return "COLON_COLON"; + case PM_TOKEN_COMMA: + return "COMMA"; + case PM_TOKEN_COMMENT: + return "COMMENT"; + case PM_TOKEN_CONSTANT: + return "CONSTANT"; + case PM_TOKEN_DOT: + return "DOT"; + case PM_TOKEN_DOT_DOT: + return "DOT_DOT"; + case PM_TOKEN_DOT_DOT_DOT: + return "DOT_DOT_DOT"; + case PM_TOKEN_EMBDOC_BEGIN: + return "EMBDOC_BEGIN"; + case PM_TOKEN_EMBDOC_END: + return "EMBDOC_END"; + case PM_TOKEN_EMBDOC_LINE: + return "EMBDOC_LINE"; + case PM_TOKEN_EMBEXPR_BEGIN: + return "EMBEXPR_BEGIN"; + case PM_TOKEN_EMBEXPR_END: + return "EMBEXPR_END"; + case PM_TOKEN_EMBVAR: + return "EMBVAR"; + case PM_TOKEN_EQUAL: + return "EQUAL"; + case PM_TOKEN_EQUAL_EQUAL: + return "EQUAL_EQUAL"; + case PM_TOKEN_EQUAL_EQUAL_EQUAL: + return "EQUAL_EQUAL_EQUAL"; + case PM_TOKEN_EQUAL_GREATER: + return "EQUAL_GREATER"; + case PM_TOKEN_EQUAL_TILDE: + return "EQUAL_TILDE"; + case PM_TOKEN_FLOAT: + return "FLOAT"; + case PM_TOKEN_FLOAT_IMAGINARY: + return "FLOAT_IMAGINARY"; + case PM_TOKEN_FLOAT_RATIONAL: + return "FLOAT_RATIONAL"; + case PM_TOKEN_FLOAT_RATIONAL_IMAGINARY: + return "FLOAT_RATIONAL_IMAGINARY"; + case PM_TOKEN_GLOBAL_VARIABLE: + return "GLOBAL_VARIABLE"; + case PM_TOKEN_GREATER: + return "GREATER"; + case PM_TOKEN_GREATER_EQUAL: + return "GREATER_EQUAL"; + case PM_TOKEN_GREATER_GREATER: + return "GREATER_GREATER"; + case PM_TOKEN_GREATER_GREATER_EQUAL: + return "GREATER_GREATER_EQUAL"; + case PM_TOKEN_HEREDOC_END: + return "HEREDOC_END"; + case PM_TOKEN_HEREDOC_START: + return "HEREDOC_START"; + case PM_TOKEN_IDENTIFIER: + return "IDENTIFIER"; + case PM_TOKEN_IGNORED_NEWLINE: + return "IGNORED_NEWLINE"; + case PM_TOKEN_INSTANCE_VARIABLE: + return "INSTANCE_VARIABLE"; + case PM_TOKEN_INTEGER: + return "INTEGER"; + case PM_TOKEN_INTEGER_IMAGINARY: + return "INTEGER_IMAGINARY"; + case PM_TOKEN_INTEGER_RATIONAL: + return "INTEGER_RATIONAL"; + case PM_TOKEN_INTEGER_RATIONAL_IMAGINARY: + return "INTEGER_RATIONAL_IMAGINARY"; + case PM_TOKEN_KEYWORD_ALIAS: + return "KEYWORD_ALIAS"; + case PM_TOKEN_KEYWORD_AND: + return "KEYWORD_AND"; + case PM_TOKEN_KEYWORD_BEGIN: + return "KEYWORD_BEGIN"; + case PM_TOKEN_KEYWORD_BEGIN_UPCASE: + return "KEYWORD_BEGIN_UPCASE"; + case PM_TOKEN_KEYWORD_BREAK: + return "KEYWORD_BREAK"; + case PM_TOKEN_KEYWORD_CASE: + return "KEYWORD_CASE"; + case PM_TOKEN_KEYWORD_CLASS: + return "KEYWORD_CLASS"; + case PM_TOKEN_KEYWORD_DEF: + return "KEYWORD_DEF"; + case PM_TOKEN_KEYWORD_DEFINED: + return "KEYWORD_DEFINED"; + case PM_TOKEN_KEYWORD_DO: + return "KEYWORD_DO"; + case PM_TOKEN_KEYWORD_DO_LOOP: + return "KEYWORD_DO_LOOP"; + case PM_TOKEN_KEYWORD_ELSE: + return "KEYWORD_ELSE"; + case PM_TOKEN_KEYWORD_ELSIF: + return "KEYWORD_ELSIF"; + case PM_TOKEN_KEYWORD_END: + return "KEYWORD_END"; + case PM_TOKEN_KEYWORD_END_UPCASE: + return "KEYWORD_END_UPCASE"; + case PM_TOKEN_KEYWORD_ENSURE: + return "KEYWORD_ENSURE"; + case PM_TOKEN_KEYWORD_FALSE: + return "KEYWORD_FALSE"; + case PM_TOKEN_KEYWORD_FOR: + return "KEYWORD_FOR"; + case PM_TOKEN_KEYWORD_IF: + return "KEYWORD_IF"; + case PM_TOKEN_KEYWORD_IF_MODIFIER: + return "KEYWORD_IF_MODIFIER"; + case PM_TOKEN_KEYWORD_IN: + return "KEYWORD_IN"; + case PM_TOKEN_KEYWORD_MODULE: + return "KEYWORD_MODULE"; + case PM_TOKEN_KEYWORD_NEXT: + return "KEYWORD_NEXT"; + case PM_TOKEN_KEYWORD_NIL: + return "KEYWORD_NIL"; + case PM_TOKEN_KEYWORD_NOT: + return "KEYWORD_NOT"; + case PM_TOKEN_KEYWORD_OR: + return "KEYWORD_OR"; + case PM_TOKEN_KEYWORD_REDO: + return "KEYWORD_REDO"; + case PM_TOKEN_KEYWORD_RESCUE: + return "KEYWORD_RESCUE"; + case PM_TOKEN_KEYWORD_RESCUE_MODIFIER: + return "KEYWORD_RESCUE_MODIFIER"; + case PM_TOKEN_KEYWORD_RETRY: + return "KEYWORD_RETRY"; + case PM_TOKEN_KEYWORD_RETURN: + return "KEYWORD_RETURN"; + case PM_TOKEN_KEYWORD_SELF: + return "KEYWORD_SELF"; + case PM_TOKEN_KEYWORD_SUPER: + return "KEYWORD_SUPER"; + case PM_TOKEN_KEYWORD_THEN: + return "KEYWORD_THEN"; + case PM_TOKEN_KEYWORD_TRUE: + return "KEYWORD_TRUE"; + case PM_TOKEN_KEYWORD_UNDEF: + return "KEYWORD_UNDEF"; + case PM_TOKEN_KEYWORD_UNLESS: + return "KEYWORD_UNLESS"; + case PM_TOKEN_KEYWORD_UNLESS_MODIFIER: + return "KEYWORD_UNLESS_MODIFIER"; + case PM_TOKEN_KEYWORD_UNTIL: + return "KEYWORD_UNTIL"; + case PM_TOKEN_KEYWORD_UNTIL_MODIFIER: + return "KEYWORD_UNTIL_MODIFIER"; + case PM_TOKEN_KEYWORD_WHEN: + return "KEYWORD_WHEN"; + case PM_TOKEN_KEYWORD_WHILE: + return "KEYWORD_WHILE"; + case PM_TOKEN_KEYWORD_WHILE_MODIFIER: + return "KEYWORD_WHILE_MODIFIER"; + case PM_TOKEN_KEYWORD_YIELD: + return "KEYWORD_YIELD"; + case PM_TOKEN_KEYWORD___ENCODING__: + return "KEYWORD___ENCODING__"; + case PM_TOKEN_KEYWORD___FILE__: + return "KEYWORD___FILE__"; + case PM_TOKEN_KEYWORD___LINE__: + return "KEYWORD___LINE__"; + case PM_TOKEN_LABEL: + return "LABEL"; + case PM_TOKEN_LABEL_END: + return "LABEL_END"; + case PM_TOKEN_LAMBDA_BEGIN: + return "LAMBDA_BEGIN"; + case PM_TOKEN_LESS: + return "LESS"; + case PM_TOKEN_LESS_EQUAL: + return "LESS_EQUAL"; + case PM_TOKEN_LESS_EQUAL_GREATER: + return "LESS_EQUAL_GREATER"; + case PM_TOKEN_LESS_LESS: + return "LESS_LESS"; + case PM_TOKEN_LESS_LESS_EQUAL: + return "LESS_LESS_EQUAL"; + case PM_TOKEN_METHOD_NAME: + return "METHOD_NAME"; + case PM_TOKEN_MINUS: + return "MINUS"; + case PM_TOKEN_MINUS_EQUAL: + return "MINUS_EQUAL"; + case PM_TOKEN_MINUS_GREATER: + return "MINUS_GREATER"; + case PM_TOKEN_NEWLINE: + return "NEWLINE"; + case PM_TOKEN_NUMBERED_REFERENCE: + return "NUMBERED_REFERENCE"; + case PM_TOKEN_PARENTHESIS_LEFT: + return "PARENTHESIS_LEFT"; + case PM_TOKEN_PARENTHESIS_LEFT_PARENTHESES: + return "PARENTHESIS_LEFT_PARENTHESES"; + case PM_TOKEN_PARENTHESIS_RIGHT: + return "PARENTHESIS_RIGHT"; + case PM_TOKEN_PERCENT: + return "PERCENT"; + case PM_TOKEN_PERCENT_EQUAL: + return "PERCENT_EQUAL"; + case PM_TOKEN_PERCENT_LOWER_I: + return "PERCENT_LOWER_I"; + case PM_TOKEN_PERCENT_LOWER_W: + return "PERCENT_LOWER_W"; + case PM_TOKEN_PERCENT_LOWER_X: + return "PERCENT_LOWER_X"; + case PM_TOKEN_PERCENT_UPPER_I: + return "PERCENT_UPPER_I"; + case PM_TOKEN_PERCENT_UPPER_W: + return "PERCENT_UPPER_W"; + case PM_TOKEN_PIPE: + return "PIPE"; + case PM_TOKEN_PIPE_EQUAL: + return "PIPE_EQUAL"; + case PM_TOKEN_PIPE_PIPE: + return "PIPE_PIPE"; + case PM_TOKEN_PIPE_PIPE_EQUAL: + return "PIPE_PIPE_EQUAL"; + case PM_TOKEN_PLUS: + return "PLUS"; + case PM_TOKEN_PLUS_EQUAL: + return "PLUS_EQUAL"; + case PM_TOKEN_QUESTION_MARK: + return "QUESTION_MARK"; + case PM_TOKEN_REGEXP_BEGIN: + return "REGEXP_BEGIN"; + case PM_TOKEN_REGEXP_END: + return "REGEXP_END"; + case PM_TOKEN_SEMICOLON: + return "SEMICOLON"; + case PM_TOKEN_SLASH: + return "SLASH"; + case PM_TOKEN_SLASH_EQUAL: + return "SLASH_EQUAL"; + case PM_TOKEN_STAR: + return "STAR"; + case PM_TOKEN_STAR_EQUAL: + return "STAR_EQUAL"; + case PM_TOKEN_STAR_STAR: + return "STAR_STAR"; + case PM_TOKEN_STAR_STAR_EQUAL: + return "STAR_STAR_EQUAL"; + case PM_TOKEN_STRING_BEGIN: + return "STRING_BEGIN"; + case PM_TOKEN_STRING_CONTENT: + return "STRING_CONTENT"; + case PM_TOKEN_STRING_END: + return "STRING_END"; + case PM_TOKEN_SYMBOL_BEGIN: + return "SYMBOL_BEGIN"; + case PM_TOKEN_TILDE: + return "TILDE"; + case PM_TOKEN_UAMPERSAND: + return "UAMPERSAND"; + case PM_TOKEN_UCOLON_COLON: + return "UCOLON_COLON"; + case PM_TOKEN_UDOT_DOT: + return "UDOT_DOT"; + case PM_TOKEN_UDOT_DOT_DOT: + return "UDOT_DOT_DOT"; + case PM_TOKEN_UMINUS: + return "UMINUS"; + case PM_TOKEN_UMINUS_NUM: + return "UMINUS_NUM"; + case PM_TOKEN_UPLUS: + return "UPLUS"; + case PM_TOKEN_USTAR: + return "USTAR"; + case PM_TOKEN_USTAR_STAR: + return "USTAR_STAR"; + case PM_TOKEN_WORDS_SEP: + return "WORDS_SEP"; + case PM_TOKEN___END__: + return "__END__"; + case PM_TOKEN_MAXIMUM: + assert(false && "unreachable"); + return ""; + } + + // Provide a default, because some compilers can't determine that the above + // switch is exhaustive. + assert(false && "unreachable"); + return ""; +} + +/** + * Returns the human name of the given token type. + */ +const char * +pm_token_type_human(pm_token_type_t token_type) { + switch (token_type) { + case PM_TOKEN_EOF: + return "end-of-input"; + case PM_TOKEN_MISSING: + return "missing token"; + case PM_TOKEN_NOT_PROVIDED: + return "not provided token"; + case PM_TOKEN_AMPERSAND: + return "'&'"; + case PM_TOKEN_AMPERSAND_AMPERSAND: + return "'&&'"; + case PM_TOKEN_AMPERSAND_AMPERSAND_EQUAL: + return "'&&='"; + case PM_TOKEN_AMPERSAND_DOT: + return "'&.'"; + case PM_TOKEN_AMPERSAND_EQUAL: + return "'&='"; + case PM_TOKEN_BACKTICK: + return "'`'"; + case PM_TOKEN_BACK_REFERENCE: + return "back reference"; + case PM_TOKEN_BANG: + return "'!'"; + case PM_TOKEN_BANG_EQUAL: + return "'!='"; + case PM_TOKEN_BANG_TILDE: + return "'!~'"; + case PM_TOKEN_BRACE_LEFT: + return "'{'"; + case PM_TOKEN_BRACE_RIGHT: + return "'}'"; + case PM_TOKEN_BRACKET_LEFT: + return "'['"; + case PM_TOKEN_BRACKET_LEFT_ARRAY: + return "'['"; + case PM_TOKEN_BRACKET_LEFT_RIGHT: + return "'[]'"; + case PM_TOKEN_BRACKET_LEFT_RIGHT_EQUAL: + return "'[]='"; + case PM_TOKEN_BRACKET_RIGHT: + return "']'"; + case PM_TOKEN_CARET: + return "'^'"; + case PM_TOKEN_CARET_EQUAL: + return "'^='"; + case PM_TOKEN_CHARACTER_LITERAL: + return "character literal"; + case PM_TOKEN_CLASS_VARIABLE: + return "class variable"; + case PM_TOKEN_COLON: + return "':'"; + case PM_TOKEN_COLON_COLON: + return "'::'"; + case PM_TOKEN_COMMA: + return "','"; + case PM_TOKEN_COMMENT: + return "comment"; + case PM_TOKEN_CONSTANT: + return "constant"; + case PM_TOKEN_DOT: + return "'.'"; + case PM_TOKEN_DOT_DOT: + return ".."; + case PM_TOKEN_DOT_DOT_DOT: + return "..."; + case PM_TOKEN_EMBDOC_BEGIN: + return "'=begin'"; + case PM_TOKEN_EMBDOC_END: + return "'=end'"; + case PM_TOKEN_EMBDOC_LINE: + return "embedded documentation line"; + case PM_TOKEN_EMBEXPR_BEGIN: + return "'#{'"; + case PM_TOKEN_EMBEXPR_END: + return "'}'"; + case PM_TOKEN_EMBVAR: + return "'#'"; + case PM_TOKEN_EQUAL: + return "'='"; + case PM_TOKEN_EQUAL_EQUAL: + return "'=='"; + case PM_TOKEN_EQUAL_EQUAL_EQUAL: + return "'==='"; + case PM_TOKEN_EQUAL_GREATER: + return "'=>'"; + case PM_TOKEN_EQUAL_TILDE: + return "'=~'"; + case PM_TOKEN_FLOAT: + return "float"; + case PM_TOKEN_FLOAT_IMAGINARY: + return "imaginary"; + case PM_TOKEN_FLOAT_RATIONAL: + return "rational"; + case PM_TOKEN_FLOAT_RATIONAL_IMAGINARY: + return "imaginary"; + case PM_TOKEN_GLOBAL_VARIABLE: + return "global variable"; + case PM_TOKEN_GREATER: + return "'>'"; + case PM_TOKEN_GREATER_EQUAL: + return "'>='"; + case PM_TOKEN_GREATER_GREATER: + return ">>"; + case PM_TOKEN_GREATER_GREATER_EQUAL: + return ">>="; + case PM_TOKEN_HEREDOC_END: + return "heredoc ending"; + case PM_TOKEN_HEREDOC_START: + return "heredoc beginning"; + case PM_TOKEN_IDENTIFIER: + return "local variable or method"; + case PM_TOKEN_IGNORED_NEWLINE: + return "ignored newline"; + case PM_TOKEN_INSTANCE_VARIABLE: + return "instance variable"; + case PM_TOKEN_INTEGER: + return "integer"; + case PM_TOKEN_INTEGER_IMAGINARY: + return "imaginary"; + case PM_TOKEN_INTEGER_RATIONAL: + return "rational"; + case PM_TOKEN_INTEGER_RATIONAL_IMAGINARY: + return "imaginary"; + case PM_TOKEN_KEYWORD_ALIAS: + return "'alias'"; + case PM_TOKEN_KEYWORD_AND: + return "'and'"; + case PM_TOKEN_KEYWORD_BEGIN: + return "'begin'"; + case PM_TOKEN_KEYWORD_BEGIN_UPCASE: + return "'BEGIN'"; + case PM_TOKEN_KEYWORD_BREAK: + return "'break'"; + case PM_TOKEN_KEYWORD_CASE: + return "'case'"; + case PM_TOKEN_KEYWORD_CLASS: + return "'class'"; + case PM_TOKEN_KEYWORD_DEF: + return "'def'"; + case PM_TOKEN_KEYWORD_DEFINED: + return "'defined?'"; + case PM_TOKEN_KEYWORD_DO: + return "'do'"; + case PM_TOKEN_KEYWORD_DO_LOOP: + return "'do'"; + case PM_TOKEN_KEYWORD_ELSE: + return "'else'"; + case PM_TOKEN_KEYWORD_ELSIF: + return "'elsif'"; + case PM_TOKEN_KEYWORD_END: + return "'end'"; + case PM_TOKEN_KEYWORD_END_UPCASE: + return "'END'"; + case PM_TOKEN_KEYWORD_ENSURE: + return "'ensure'"; + case PM_TOKEN_KEYWORD_FALSE: + return "'false'"; + case PM_TOKEN_KEYWORD_FOR: + return "'for'"; + case PM_TOKEN_KEYWORD_IF: + return "'if'"; + case PM_TOKEN_KEYWORD_IF_MODIFIER: + return "'if'"; + case PM_TOKEN_KEYWORD_IN: + return "'in'"; + case PM_TOKEN_KEYWORD_MODULE: + return "'module'"; + case PM_TOKEN_KEYWORD_NEXT: + return "'next'"; + case PM_TOKEN_KEYWORD_NIL: + return "'nil'"; + case PM_TOKEN_KEYWORD_NOT: + return "'not'"; + case PM_TOKEN_KEYWORD_OR: + return "'or'"; + case PM_TOKEN_KEYWORD_REDO: + return "'redo'"; + case PM_TOKEN_KEYWORD_RESCUE: + return "'rescue'"; + case PM_TOKEN_KEYWORD_RESCUE_MODIFIER: + return "'rescue' modifier"; + case PM_TOKEN_KEYWORD_RETRY: + return "'retry'"; + case PM_TOKEN_KEYWORD_RETURN: + return "'return'"; + case PM_TOKEN_KEYWORD_SELF: + return "'self'"; + case PM_TOKEN_KEYWORD_SUPER: + return "'super'"; + case PM_TOKEN_KEYWORD_THEN: + return "'then'"; + case PM_TOKEN_KEYWORD_TRUE: + return "'true'"; + case PM_TOKEN_KEYWORD_UNDEF: + return "'undef'"; + case PM_TOKEN_KEYWORD_UNLESS: + return "'unless'"; + case PM_TOKEN_KEYWORD_UNLESS_MODIFIER: + return "'unless'"; + case PM_TOKEN_KEYWORD_UNTIL: + return "'until'"; + case PM_TOKEN_KEYWORD_UNTIL_MODIFIER: + return "'until'"; + case PM_TOKEN_KEYWORD_WHEN: + return "'when'"; + case PM_TOKEN_KEYWORD_WHILE: + return "'while'"; + case PM_TOKEN_KEYWORD_WHILE_MODIFIER: + return "'while'"; + case PM_TOKEN_KEYWORD_YIELD: + return "'yield'"; + case PM_TOKEN_KEYWORD___ENCODING__: + return "'__ENCODING__'"; + case PM_TOKEN_KEYWORD___FILE__: + return "'__FILE__'"; + case PM_TOKEN_KEYWORD___LINE__: + return "'__LINE__'"; + case PM_TOKEN_LABEL: + return "label"; + case PM_TOKEN_LABEL_END: + return "label terminator"; + case PM_TOKEN_LAMBDA_BEGIN: + return "'{'"; + case PM_TOKEN_LESS: + return "'<'"; + case PM_TOKEN_LESS_EQUAL: + return "'<='"; + case PM_TOKEN_LESS_EQUAL_GREATER: + return "'<=>'"; + case PM_TOKEN_LESS_LESS: + return "<<"; + case PM_TOKEN_LESS_LESS_EQUAL: + return "<<="; + case PM_TOKEN_METHOD_NAME: + return "method name"; + case PM_TOKEN_MINUS: + return "'-'"; + case PM_TOKEN_MINUS_EQUAL: + return "'-='"; + case PM_TOKEN_MINUS_GREATER: + return "'->'"; + case PM_TOKEN_NEWLINE: + return "newline"; + case PM_TOKEN_NUMBERED_REFERENCE: + return "numbered reference"; + case PM_TOKEN_PARENTHESIS_LEFT: + return "'('"; + case PM_TOKEN_PARENTHESIS_LEFT_PARENTHESES: + return "'('"; + case PM_TOKEN_PARENTHESIS_RIGHT: + return "')'"; + case PM_TOKEN_PERCENT: + return "'%'"; + case PM_TOKEN_PERCENT_EQUAL: + return "'%='"; + case PM_TOKEN_PERCENT_LOWER_I: + return "'%i'"; + case PM_TOKEN_PERCENT_LOWER_W: + return "'%w'"; + case PM_TOKEN_PERCENT_LOWER_X: + return "'%x'"; + case PM_TOKEN_PERCENT_UPPER_I: + return "'%I'"; + case PM_TOKEN_PERCENT_UPPER_W: + return "'%W'"; + case PM_TOKEN_PIPE: + return "'|'"; + case PM_TOKEN_PIPE_EQUAL: + return "'|='"; + case PM_TOKEN_PIPE_PIPE: + return "'||'"; + case PM_TOKEN_PIPE_PIPE_EQUAL: + return "'||='"; + case PM_TOKEN_PLUS: + return "'+'"; + case PM_TOKEN_PLUS_EQUAL: + return "'+='"; + case PM_TOKEN_QUESTION_MARK: + return "'?'"; + case PM_TOKEN_REGEXP_BEGIN: + return "regular expression beginning"; + case PM_TOKEN_REGEXP_END: + return "regular expression ending"; + case PM_TOKEN_SEMICOLON: + return "';'"; + case PM_TOKEN_SLASH: + return "'/'"; + case PM_TOKEN_SLASH_EQUAL: + return "'/='"; + case PM_TOKEN_STAR: + return "'*'"; + case PM_TOKEN_STAR_EQUAL: + return "'*='"; + case PM_TOKEN_STAR_STAR: + return "'**'"; + case PM_TOKEN_STAR_STAR_EQUAL: + return "'**='"; + case PM_TOKEN_STRING_BEGIN: + return "string literal"; + case PM_TOKEN_STRING_CONTENT: + return "string content"; + case PM_TOKEN_STRING_END: + return "string ending"; + case PM_TOKEN_SYMBOL_BEGIN: + return "symbol literal"; + case PM_TOKEN_TILDE: + return "'~'"; + case PM_TOKEN_UAMPERSAND: + return "'&'"; + case PM_TOKEN_UCOLON_COLON: + return "'::'"; + case PM_TOKEN_UDOT_DOT: + return "'..'"; + case PM_TOKEN_UDOT_DOT_DOT: + return "'...'"; + case PM_TOKEN_UMINUS: + return "'-'"; + case PM_TOKEN_UMINUS_NUM: + return "'-'"; + case PM_TOKEN_UPLUS: + return "'+'"; + case PM_TOKEN_USTAR: + return "*"; + case PM_TOKEN_USTAR_STAR: + return "**"; + case PM_TOKEN_WORDS_SEP: + return "string separator"; + case PM_TOKEN___END__: + return "'__END__'"; + case PM_TOKEN_MAXIMUM: + assert(false && "unreachable"); + return ""; + } + + // Provide a default, because some compilers can't determine that the above + // switch is exhaustive. + assert(false && "unreachable"); + return ""; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_buffer.c b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_buffer.c new file mode 100644 index 00000000..2136a7c4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_buffer.c @@ -0,0 +1,357 @@ +#include "prism/util/pm_buffer.h" + +/** + * Return the size of the pm_buffer_t struct. + */ +size_t +pm_buffer_sizeof(void) { + return sizeof(pm_buffer_t); +} + +/** + * Initialize a pm_buffer_t with the given capacity. + */ +bool +pm_buffer_init_capacity(pm_buffer_t *buffer, size_t capacity) { + buffer->length = 0; + buffer->capacity = capacity; + + buffer->value = (char *) xmalloc(capacity); + return buffer->value != NULL; +} + +/** + * Initialize a pm_buffer_t with its default values. + */ +bool +pm_buffer_init(pm_buffer_t *buffer) { + return pm_buffer_init_capacity(buffer, 1024); +} + +/** + * Return the value of the buffer. + */ +char * +pm_buffer_value(const pm_buffer_t *buffer) { + return buffer->value; +} + +/** + * Return the length of the buffer. + */ +size_t +pm_buffer_length(const pm_buffer_t *buffer) { + return buffer->length; +} + +/** + * Append the given amount of space to the buffer. + */ +static inline bool +pm_buffer_append_length(pm_buffer_t *buffer, size_t length) { + size_t next_length = buffer->length + length; + + if (next_length > buffer->capacity) { + if (buffer->capacity == 0) { + buffer->capacity = 1; + } + + while (next_length > buffer->capacity) { + buffer->capacity *= 2; + } + + buffer->value = xrealloc(buffer->value, buffer->capacity); + if (buffer->value == NULL) return false; + } + + buffer->length = next_length; + return true; +} + +/** + * Append a generic pointer to memory to the buffer. + */ +static inline void +pm_buffer_append(pm_buffer_t *buffer, const void *source, size_t length) { + size_t cursor = buffer->length; + if (pm_buffer_append_length(buffer, length)) { + memcpy(buffer->value + cursor, source, length); + } +} + +/** + * Append the given amount of space as zeroes to the buffer. + */ +void +pm_buffer_append_zeroes(pm_buffer_t *buffer, size_t length) { + size_t cursor = buffer->length; + if (pm_buffer_append_length(buffer, length)) { + memset(buffer->value + cursor, 0, length); + } +} + +/** + * Append a formatted string to the buffer. + */ +void +pm_buffer_append_format(pm_buffer_t *buffer, const char *format, ...) { + va_list arguments; + va_start(arguments, format); + int result = vsnprintf(NULL, 0, format, arguments); + va_end(arguments); + + if (result < 0) return; + size_t length = (size_t) (result + 1); + + size_t cursor = buffer->length; + if (pm_buffer_append_length(buffer, length)) { + va_start(arguments, format); + vsnprintf(buffer->value + cursor, length, format, arguments); + va_end(arguments); + buffer->length--; + } +} + +/** + * Append a string to the buffer. + */ +void +pm_buffer_append_string(pm_buffer_t *buffer, const char *value, size_t length) { + pm_buffer_append(buffer, value, length); +} + +/** + * Append a list of bytes to the buffer. + */ +void +pm_buffer_append_bytes(pm_buffer_t *buffer, const uint8_t *value, size_t length) { + pm_buffer_append(buffer, (const char *) value, length); +} + +/** + * Append a single byte to the buffer. + */ +void +pm_buffer_append_byte(pm_buffer_t *buffer, uint8_t value) { + const void *source = &value; + pm_buffer_append(buffer, source, sizeof(uint8_t)); +} + +/** + * Append a 32-bit unsigned integer to the buffer as a variable-length integer. + */ +void +pm_buffer_append_varuint(pm_buffer_t *buffer, uint32_t value) { + if (value < 128) { + pm_buffer_append_byte(buffer, (uint8_t) value); + } else { + uint32_t n = value; + while (n >= 128) { + pm_buffer_append_byte(buffer, (uint8_t) (n | 128)); + n >>= 7; + } + pm_buffer_append_byte(buffer, (uint8_t) n); + } +} + +/** + * Append a 32-bit signed integer to the buffer as a variable-length integer. + */ +void +pm_buffer_append_varsint(pm_buffer_t *buffer, int32_t value) { + uint32_t unsigned_int = ((uint32_t)(value) << 1) ^ ((uint32_t)(value >> 31)); + pm_buffer_append_varuint(buffer, unsigned_int); +} + +/** + * Append a double to the buffer. + */ +void +pm_buffer_append_double(pm_buffer_t *buffer, double value) { + const void *source = &value; + pm_buffer_append(buffer, source, sizeof(double)); +} + +/** + * Append a unicode codepoint to the buffer. + */ +bool +pm_buffer_append_unicode_codepoint(pm_buffer_t *buffer, uint32_t value) { + if (value <= 0x7F) { + pm_buffer_append_byte(buffer, (uint8_t) value); // 0xxxxxxx + return true; + } else if (value <= 0x7FF) { + uint8_t bytes[] = { + (uint8_t) (0xC0 | ((value >> 6) & 0x3F)), // 110xxxxx + (uint8_t) (0x80 | (value & 0x3F)) // 10xxxxxx + }; + + pm_buffer_append_bytes(buffer, bytes, 2); + return true; + } else if (value <= 0xFFFF) { + uint8_t bytes[] = { + (uint8_t) (0xE0 | ((value >> 12) & 0x3F)), // 1110xxxx + (uint8_t) (0x80 | ((value >> 6) & 0x3F)), // 10xxxxxx + (uint8_t) (0x80 | (value & 0x3F)) // 10xxxxxx + }; + + pm_buffer_append_bytes(buffer, bytes, 3); + return true; + } else if (value <= 0x10FFFF) { + uint8_t bytes[] = { + (uint8_t) (0xF0 | ((value >> 18) & 0x3F)), // 11110xxx + (uint8_t) (0x80 | ((value >> 12) & 0x3F)), // 10xxxxxx + (uint8_t) (0x80 | ((value >> 6) & 0x3F)), // 10xxxxxx + (uint8_t) (0x80 | (value & 0x3F)) // 10xxxxxx + }; + + pm_buffer_append_bytes(buffer, bytes, 4); + return true; + } else { + return false; + } +} + +/** + * Append a slice of source code to the buffer. + */ +void +pm_buffer_append_source(pm_buffer_t *buffer, const uint8_t *source, size_t length, pm_buffer_escaping_t escaping) { + for (size_t index = 0; index < length; index++) { + const uint8_t byte = source[index]; + + if ((byte <= 0x06) || (byte >= 0x0E && byte <= 0x1F) || (byte >= 0x7F)) { + if (escaping == PM_BUFFER_ESCAPING_RUBY) { + pm_buffer_append_format(buffer, "\\x%02X", byte); + } else { + pm_buffer_append_format(buffer, "\\u%04X", byte); + } + } else { + switch (byte) { + case '\a': + if (escaping == PM_BUFFER_ESCAPING_RUBY) { + pm_buffer_append_string(buffer, "\\a", 2); + } else { + pm_buffer_append_format(buffer, "\\u%04X", byte); + } + break; + case '\b': + pm_buffer_append_string(buffer, "\\b", 2); + break; + case '\t': + pm_buffer_append_string(buffer, "\\t", 2); + break; + case '\n': + pm_buffer_append_string(buffer, "\\n", 2); + break; + case '\v': + if (escaping == PM_BUFFER_ESCAPING_RUBY) { + pm_buffer_append_string(buffer, "\\v", 2); + } else { + pm_buffer_append_format(buffer, "\\u%04X", byte); + } + break; + case '\f': + pm_buffer_append_string(buffer, "\\f", 2); + break; + case '\r': + pm_buffer_append_string(buffer, "\\r", 2); + break; + case '"': + pm_buffer_append_string(buffer, "\\\"", 2); + break; + case '#': { + if (escaping == PM_BUFFER_ESCAPING_RUBY && index + 1 < length) { + const uint8_t next_byte = source[index + 1]; + if (next_byte == '{' || next_byte == '@' || next_byte == '$') { + pm_buffer_append_byte(buffer, '\\'); + } + } + + pm_buffer_append_byte(buffer, '#'); + break; + } + case '\\': + pm_buffer_append_string(buffer, "\\\\", 2); + break; + default: + pm_buffer_append_byte(buffer, byte); + break; + } + } + } +} + +/** + * Prepend the given string to the buffer. + */ +void +pm_buffer_prepend_string(pm_buffer_t *buffer, const char *value, size_t length) { + size_t cursor = buffer->length; + if (pm_buffer_append_length(buffer, length)) { + memmove(buffer->value + length, buffer->value, cursor); + memcpy(buffer->value, value, length); + } +} + +/** + * Concatenate one buffer onto another. + */ +void +pm_buffer_concat(pm_buffer_t *destination, const pm_buffer_t *source) { + if (source->length > 0) { + pm_buffer_append(destination, source->value, source->length); + } +} + +/** + * Clear the buffer by reducing its size to 0. This does not free the allocated + * memory, but it does allow the buffer to be reused. + */ +void +pm_buffer_clear(pm_buffer_t *buffer) { + buffer->length = 0; +} + +/** + * Strip the whitespace from the end of the buffer. + */ +void +pm_buffer_rstrip(pm_buffer_t *buffer) { + while (buffer->length > 0 && pm_char_is_whitespace((uint8_t) buffer->value[buffer->length - 1])) { + buffer->length--; + } +} + +/** + * Checks if the buffer includes the given value. + */ +size_t +pm_buffer_index(const pm_buffer_t *buffer, char value) { + const char *first = memchr(buffer->value, value, buffer->length); + return (first == NULL) ? SIZE_MAX : (size_t) (first - buffer->value); +} + +/** + * Insert the given string into the buffer at the given index. + */ +void +pm_buffer_insert(pm_buffer_t *buffer, size_t index, const char *value, size_t length) { + assert(index <= buffer->length); + + if (index == buffer->length) { + pm_buffer_append_string(buffer, value, length); + } else { + pm_buffer_append_zeroes(buffer, length); + memmove(buffer->value + index + length, buffer->value + index, buffer->length - length - index); + memcpy(buffer->value + index, value, length); + } +} + +/** + * Free the memory associated with the buffer. + */ +void +pm_buffer_free(pm_buffer_t *buffer) { + xfree(buffer->value); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_char.c b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_char.c new file mode 100644 index 00000000..a51dc116 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_char.c @@ -0,0 +1,318 @@ +#include "prism/util/pm_char.h" + +#define PRISM_CHAR_BIT_WHITESPACE (1 << 0) +#define PRISM_CHAR_BIT_INLINE_WHITESPACE (1 << 1) +#define PRISM_CHAR_BIT_REGEXP_OPTION (1 << 2) + +#define PRISM_NUMBER_BIT_BINARY_DIGIT (1 << 0) +#define PRISM_NUMBER_BIT_BINARY_NUMBER (1 << 1) +#define PRISM_NUMBER_BIT_OCTAL_DIGIT (1 << 2) +#define PRISM_NUMBER_BIT_OCTAL_NUMBER (1 << 3) +#define PRISM_NUMBER_BIT_DECIMAL_DIGIT (1 << 4) +#define PRISM_NUMBER_BIT_DECIMAL_NUMBER (1 << 5) +#define PRISM_NUMBER_BIT_HEXADECIMAL_DIGIT (1 << 6) +#define PRISM_NUMBER_BIT_HEXADECIMAL_NUMBER (1 << 7) + +static const uint8_t pm_byte_table[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 3, 3, 3, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3x + 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // 4x + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, // 5x + 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, // 6x + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, // 7x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ax + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Bx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Cx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Dx + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Ex + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // Fx +}; + +static const uint8_t pm_number_table[256] = { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 1x + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 2x + 0xff, 0xff, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 3x + 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 4x + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, // 5x + 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 6x + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 7x + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 8x + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 9x + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Ax + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Bx + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Cx + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Dx + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Ex + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Fx +}; + +/** + * Returns the number of characters at the start of the string that match the + * given kind. Disallows searching past the given maximum number of characters. + */ +static inline size_t +pm_strspn_char_kind(const uint8_t *string, ptrdiff_t length, uint8_t kind) { + if (length <= 0) return 0; + + size_t size = 0; + size_t maximum = (size_t) length; + + while (size < maximum && (pm_byte_table[string[size]] & kind)) size++; + return size; +} + +/** + * Returns the number of characters at the start of the string that are + * whitespace. Disallows searching past the given maximum number of characters. + */ +size_t +pm_strspn_whitespace(const uint8_t *string, ptrdiff_t length) { + return pm_strspn_char_kind(string, length, PRISM_CHAR_BIT_WHITESPACE); +} + +/** + * Returns the number of characters at the start of the string that are + * whitespace while also tracking the location of each newline. Disallows + * searching past the given maximum number of characters. + */ +size_t +pm_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length, pm_newline_list_t *newline_list) { + if (length <= 0) return 0; + + size_t size = 0; + size_t maximum = (size_t) length; + + while (size < maximum && (pm_byte_table[string[size]] & PRISM_CHAR_BIT_WHITESPACE)) { + if (string[size] == '\n') { + pm_newline_list_append(newline_list, string + size); + } + + size++; + } + + return size; +} + +/** + * Returns the number of characters at the start of the string that are inline + * whitespace. Disallows searching past the given maximum number of characters. + */ +size_t +pm_strspn_inline_whitespace(const uint8_t *string, ptrdiff_t length) { + return pm_strspn_char_kind(string, length, PRISM_CHAR_BIT_INLINE_WHITESPACE); +} + +/** + * Returns the number of characters at the start of the string that are regexp + * options. Disallows searching past the given maximum number of characters. + */ +size_t +pm_strspn_regexp_option(const uint8_t *string, ptrdiff_t length) { + return pm_strspn_char_kind(string, length, PRISM_CHAR_BIT_REGEXP_OPTION); +} + +/** + * Returns true if the given character matches the given kind. + */ +static inline bool +pm_char_is_char_kind(const uint8_t b, uint8_t kind) { + return (pm_byte_table[b] & kind) != 0; +} + +/** + * Returns true if the given character is a whitespace character. + */ +bool +pm_char_is_whitespace(const uint8_t b) { + return pm_char_is_char_kind(b, PRISM_CHAR_BIT_WHITESPACE); +} + +/** + * Returns true if the given character is an inline whitespace character. + */ +bool +pm_char_is_inline_whitespace(const uint8_t b) { + return pm_char_is_char_kind(b, PRISM_CHAR_BIT_INLINE_WHITESPACE); +} + +/** + * Scan through the string and return the number of characters at the start of + * the string that match the given kind. Disallows searching past the given + * maximum number of characters. + */ +static inline size_t +pm_strspn_number_kind(const uint8_t *string, ptrdiff_t length, uint8_t kind) { + if (length <= 0) return 0; + + size_t size = 0; + size_t maximum = (size_t) length; + + while (size < maximum && (pm_number_table[string[size]] & kind)) size++; + return size; +} + +/** + * Scan through the string and return the number of characters at the start of + * the string that match the given kind. Disallows searching past the given + * maximum number of characters. + * + * Additionally, report the location of the last invalid underscore character + * found in the string through the out invalid parameter. + */ +static inline size_t +pm_strspn_number_kind_underscores(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid, uint8_t kind) { + if (length <= 0) return 0; + + size_t size = 0; + size_t maximum = (size_t) length; + + bool underscore = false; + while (size < maximum && (pm_number_table[string[size]] & kind)) { + if (string[size] == '_') { + if (underscore) *invalid = string + size; + underscore = true; + } else { + underscore = false; + } + + size++; + } + + if (size > 0 && string[size - 1] == '_') *invalid = string + size - 1; + return size; +} + +/** + * Returns the number of characters at the start of the string that are binary + * digits or underscores. Disallows searching past the given maximum number of + * characters. + * + * If multiple underscores are found in a row or if an underscore is + * found at the end of the number, then the invalid pointer is set to the index + * of the first invalid underscore. + */ +size_t +pm_strspn_binary_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid) { + return pm_strspn_number_kind_underscores(string, length, invalid, PRISM_NUMBER_BIT_BINARY_NUMBER); +} + +/** + * Returns the number of characters at the start of the string that are octal + * digits or underscores. Disallows searching past the given maximum number of + * characters. + * + * If multiple underscores are found in a row or if an underscore is + * found at the end of the number, then the invalid pointer is set to the index + * of the first invalid underscore. + */ +size_t +pm_strspn_octal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid) { + return pm_strspn_number_kind_underscores(string, length, invalid, PRISM_NUMBER_BIT_OCTAL_NUMBER); +} + +/** + * Returns the number of characters at the start of the string that are decimal + * digits. Disallows searching past the given maximum number of characters. + */ +size_t +pm_strspn_decimal_digit(const uint8_t *string, ptrdiff_t length) { + return pm_strspn_number_kind(string, length, PRISM_NUMBER_BIT_DECIMAL_DIGIT); +} + +/** + * Returns the number of characters at the start of the string that are decimal + * digits or underscores. Disallows searching past the given maximum number of + * characters. + * + * If multiple underscores are found in a row or if an underscore is + * found at the end of the number, then the invalid pointer is set to the index + * of the first invalid underscore + */ +size_t +pm_strspn_decimal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid) { + return pm_strspn_number_kind_underscores(string, length, invalid, PRISM_NUMBER_BIT_DECIMAL_NUMBER); +} + +/** + * Returns the number of characters at the start of the string that are + * hexadecimal digits. Disallows searching past the given maximum number of + * characters. + */ +size_t +pm_strspn_hexadecimal_digit(const uint8_t *string, ptrdiff_t length) { + return pm_strspn_number_kind(string, length, PRISM_NUMBER_BIT_HEXADECIMAL_DIGIT); +} + +/** + * Returns the number of characters at the start of the string that are + * hexadecimal digits or underscores. Disallows searching past the given maximum + * number of characters. + * + * If multiple underscores are found in a row or if an underscore is + * found at the end of the number, then the invalid pointer is set to the index + * of the first invalid underscore. + */ +size_t +pm_strspn_hexadecimal_number(const uint8_t *string, ptrdiff_t length, const uint8_t **invalid) { + return pm_strspn_number_kind_underscores(string, length, invalid, PRISM_NUMBER_BIT_HEXADECIMAL_NUMBER); +} + +/** + * Returns true if the given character matches the given kind. + */ +static inline bool +pm_char_is_number_kind(const uint8_t b, uint8_t kind) { + return (pm_number_table[b] & kind) != 0; +} + +/** + * Returns true if the given character is a binary digit. + */ +bool +pm_char_is_binary_digit(const uint8_t b) { + return pm_char_is_number_kind(b, PRISM_NUMBER_BIT_BINARY_DIGIT); +} + +/** + * Returns true if the given character is an octal digit. + */ +bool +pm_char_is_octal_digit(const uint8_t b) { + return pm_char_is_number_kind(b, PRISM_NUMBER_BIT_OCTAL_DIGIT); +} + +/** + * Returns true if the given character is a decimal digit. + */ +bool +pm_char_is_decimal_digit(const uint8_t b) { + return pm_char_is_number_kind(b, PRISM_NUMBER_BIT_DECIMAL_DIGIT); +} + +/** + * Returns true if the given character is a hexadecimal digit. + */ +bool +pm_char_is_hexadecimal_digit(const uint8_t b) { + return pm_char_is_number_kind(b, PRISM_NUMBER_BIT_HEXADECIMAL_DIGIT); +} + +#undef PRISM_CHAR_BIT_WHITESPACE +#undef PRISM_CHAR_BIT_INLINE_WHITESPACE +#undef PRISM_CHAR_BIT_REGEXP_OPTION + +#undef PRISM_NUMBER_BIT_BINARY_DIGIT +#undef PRISM_NUMBER_BIT_BINARY_NUMBER +#undef PRISM_NUMBER_BIT_OCTAL_DIGIT +#undef PRISM_NUMBER_BIT_OCTAL_NUMBER +#undef PRISM_NUMBER_BIT_DECIMAL_DIGIT +#undef PRISM_NUMBER_BIT_DECIMAL_NUMBER +#undef PRISM_NUMBER_BIT_HEXADECIMAL_NUMBER +#undef PRISM_NUMBER_BIT_HEXADECIMAL_DIGIT diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_constant_pool.c b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_constant_pool.c new file mode 100644 index 00000000..38ea01a2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_constant_pool.c @@ -0,0 +1,342 @@ +#include "prism/util/pm_constant_pool.h" + +/** + * Initialize a list of constant ids. + */ +void +pm_constant_id_list_init(pm_constant_id_list_t *list) { + list->ids = NULL; + list->size = 0; + list->capacity = 0; +} + +/** + * Initialize a list of constant ids with a given capacity. + */ +void +pm_constant_id_list_init_capacity(pm_constant_id_list_t *list, size_t capacity) { + if (capacity) { + list->ids = xcalloc(capacity, sizeof(pm_constant_id_t)); + if (list->ids == NULL) abort(); + } else { + list->ids = NULL; + } + + list->size = 0; + list->capacity = capacity; +} + +/** + * Append a constant id to a list of constant ids. Returns false if any + * potential reallocations fail. + */ +bool +pm_constant_id_list_append(pm_constant_id_list_t *list, pm_constant_id_t id) { + if (list->size >= list->capacity) { + list->capacity = list->capacity == 0 ? 8 : list->capacity * 2; + list->ids = (pm_constant_id_t *) xrealloc(list->ids, sizeof(pm_constant_id_t) * list->capacity); + if (list->ids == NULL) return false; + } + + list->ids[list->size++] = id; + return true; +} + +/** + * Insert a constant id into a list of constant ids at the specified index. + */ +void +pm_constant_id_list_insert(pm_constant_id_list_t *list, size_t index, pm_constant_id_t id) { + assert(index < list->capacity); + assert(list->ids[index] == PM_CONSTANT_ID_UNSET); + + list->ids[index] = id; + list->size++; +} + +/** + * Checks if the current constant id list includes the given constant id. + */ +bool +pm_constant_id_list_includes(pm_constant_id_list_t *list, pm_constant_id_t id) { + for (size_t index = 0; index < list->size; index++) { + if (list->ids[index] == id) return true; + } + return false; +} + +/** + * Free the memory associated with a list of constant ids. + */ +void +pm_constant_id_list_free(pm_constant_id_list_t *list) { + if (list->ids != NULL) { + xfree(list->ids); + } +} + +/** + * A relatively simple hash function (djb2) that is used to hash strings. We are + * optimizing here for simplicity and speed. + */ +static inline uint32_t +pm_constant_pool_hash(const uint8_t *start, size_t length) { + // This is a prime number used as the initial value for the hash function. + uint32_t value = 5381; + + for (size_t index = 0; index < length; index++) { + value = ((value << 5) + value) + start[index]; + } + + return value; +} + +/** + * https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 + */ +static uint32_t +next_power_of_two(uint32_t v) { + // Avoid underflow in subtraction on next line. + if (v == 0) { + // 1 is the nearest power of 2 to 0 (2^0) + return 1; + } + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v++; + return v; +} + +#ifndef NDEBUG +static bool +is_power_of_two(uint32_t size) { + return (size & (size - 1)) == 0; +} +#endif + +/** + * Resize a constant pool to a given capacity. + */ +static inline bool +pm_constant_pool_resize(pm_constant_pool_t *pool) { + assert(is_power_of_two(pool->capacity)); + + uint32_t next_capacity = pool->capacity * 2; + if (next_capacity < pool->capacity) return false; + + const uint32_t mask = next_capacity - 1; + const size_t element_size = sizeof(pm_constant_pool_bucket_t) + sizeof(pm_constant_t); + + void *next = xcalloc(next_capacity, element_size); + if (next == NULL) return false; + + pm_constant_pool_bucket_t *next_buckets = next; + pm_constant_t *next_constants = (void *)(((char *) next) + next_capacity * sizeof(pm_constant_pool_bucket_t)); + + // For each bucket in the current constant pool, find the index in the + // next constant pool, and insert it. + for (uint32_t index = 0; index < pool->capacity; index++) { + pm_constant_pool_bucket_t *bucket = &pool->buckets[index]; + + // If an id is set on this constant, then we know we have content here. + // In this case we need to insert it into the next constant pool. + if (bucket->id != PM_CONSTANT_ID_UNSET) { + uint32_t next_index = bucket->hash & mask; + + // This implements linear scanning to find the next available slot + // in case this index is already taken. We don't need to bother + // comparing the values since we know that the hash is unique. + while (next_buckets[next_index].id != PM_CONSTANT_ID_UNSET) { + next_index = (next_index + 1) & mask; + } + + // Here we copy over the entire bucket, which includes the id so + // that they are consistent between resizes. + next_buckets[next_index] = *bucket; + } + } + + // The constants are stable with respect to hash table resizes. + memcpy(next_constants, pool->constants, pool->size * sizeof(pm_constant_t)); + + // pool->constants and pool->buckets are allocated out of the same chunk + // of memory, with the buckets coming first. + xfree(pool->buckets); + pool->constants = next_constants; + pool->buckets = next_buckets; + pool->capacity = next_capacity; + return true; +} + +/** + * Initialize a new constant pool with a given capacity. + */ +bool +pm_constant_pool_init(pm_constant_pool_t *pool, uint32_t capacity) { + const uint32_t maximum = (~((uint32_t) 0)); + if (capacity >= ((maximum / 2) + 1)) return false; + + capacity = next_power_of_two(capacity); + const size_t element_size = sizeof(pm_constant_pool_bucket_t) + sizeof(pm_constant_t); + void *memory = xcalloc(capacity, element_size); + if (memory == NULL) return false; + + pool->buckets = memory; + pool->constants = (void *)(((char *)memory) + capacity * sizeof(pm_constant_pool_bucket_t)); + pool->size = 0; + pool->capacity = capacity; + return true; +} + +/** + * Return a pointer to the constant indicated by the given constant id. + */ +pm_constant_t * +pm_constant_pool_id_to_constant(const pm_constant_pool_t *pool, pm_constant_id_t constant_id) { + assert(constant_id != PM_CONSTANT_ID_UNSET && constant_id <= pool->size); + return &pool->constants[constant_id - 1]; +} + +/** + * Find a constant in a constant pool. Returns the id of the constant, or 0 if + * the constant is not found. + */ +pm_constant_id_t +pm_constant_pool_find(const pm_constant_pool_t *pool, const uint8_t *start, size_t length) { + assert(is_power_of_two(pool->capacity)); + const uint32_t mask = pool->capacity - 1; + + uint32_t hash = pm_constant_pool_hash(start, length); + uint32_t index = hash & mask; + pm_constant_pool_bucket_t *bucket; + + while (bucket = &pool->buckets[index], bucket->id != PM_CONSTANT_ID_UNSET) { + pm_constant_t *constant = &pool->constants[bucket->id - 1]; + if ((constant->length == length) && memcmp(constant->start, start, length) == 0) { + return bucket->id; + } + + index = (index + 1) & mask; + } + + return PM_CONSTANT_ID_UNSET; +} + +/** + * Insert a constant into a constant pool and return its index in the pool. + */ +static inline pm_constant_id_t +pm_constant_pool_insert(pm_constant_pool_t *pool, const uint8_t *start, size_t length, pm_constant_pool_bucket_type_t type) { + if (pool->size >= (pool->capacity / 4 * 3)) { + if (!pm_constant_pool_resize(pool)) return PM_CONSTANT_ID_UNSET; + } + + assert(is_power_of_two(pool->capacity)); + const uint32_t mask = pool->capacity - 1; + + uint32_t hash = pm_constant_pool_hash(start, length); + uint32_t index = hash & mask; + pm_constant_pool_bucket_t *bucket; + + while (bucket = &pool->buckets[index], bucket->id != PM_CONSTANT_ID_UNSET) { + // If there is a collision, then we need to check if the content is the + // same as the content we are trying to insert. If it is, then we can + // return the id of the existing constant. + pm_constant_t *constant = &pool->constants[bucket->id - 1]; + + if ((constant->length == length) && memcmp(constant->start, start, length) == 0) { + // Since we have found a match, we need to check if this is + // attempting to insert a shared or an owned constant. We want to + // prefer shared constants since they don't require allocations. + if (type == PM_CONSTANT_POOL_BUCKET_OWNED) { + // If we're attempting to insert an owned constant and we have + // an existing constant, then either way we don't want the given + // memory. Either it's duplicated with the existing constant or + // it's not necessary because we have a shared version. + xfree((void *) start); + } else if (bucket->type == PM_CONSTANT_POOL_BUCKET_OWNED) { + // If we're attempting to insert a shared constant and the + // existing constant is owned, then we can free the owned + // constant and replace it with the shared constant. + xfree((void *) constant->start); + constant->start = start; + bucket->type = (unsigned int) (PM_CONSTANT_POOL_BUCKET_DEFAULT & 0x3); + } + + return bucket->id; + } + + index = (index + 1) & mask; + } + + // IDs are allocated starting at 1, since the value 0 denotes a non-existent + // constant. + uint32_t id = ++pool->size; + assert(pool->size < ((uint32_t) (1 << 30))); + + *bucket = (pm_constant_pool_bucket_t) { + .id = (unsigned int) (id & 0x3fffffff), + .type = (unsigned int) (type & 0x3), + .hash = hash + }; + + pool->constants[id - 1] = (pm_constant_t) { + .start = start, + .length = length, + }; + + return id; +} + +/** + * Insert a constant into a constant pool. Returns the id of the constant, or + * PM_CONSTANT_ID_UNSET if any potential calls to resize fail. + */ +pm_constant_id_t +pm_constant_pool_insert_shared(pm_constant_pool_t *pool, const uint8_t *start, size_t length) { + return pm_constant_pool_insert(pool, start, length, PM_CONSTANT_POOL_BUCKET_DEFAULT); +} + +/** + * Insert a constant into a constant pool from memory that is now owned by the + * constant pool. Returns the id of the constant, or PM_CONSTANT_ID_UNSET if any + * potential calls to resize fail. + */ +pm_constant_id_t +pm_constant_pool_insert_owned(pm_constant_pool_t *pool, uint8_t *start, size_t length) { + return pm_constant_pool_insert(pool, start, length, PM_CONSTANT_POOL_BUCKET_OWNED); +} + +/** + * Insert a constant into a constant pool from memory that is constant. Returns + * the id of the constant, or PM_CONSTANT_ID_UNSET if any potential calls to + * resize fail. + */ +pm_constant_id_t +pm_constant_pool_insert_constant(pm_constant_pool_t *pool, const uint8_t *start, size_t length) { + return pm_constant_pool_insert(pool, start, length, PM_CONSTANT_POOL_BUCKET_CONSTANT); +} + +/** + * Free the memory associated with a constant pool. + */ +void +pm_constant_pool_free(pm_constant_pool_t *pool) { + // For each constant in the current constant pool, free the contents if the + // contents are owned. + for (uint32_t index = 0; index < pool->capacity; index++) { + pm_constant_pool_bucket_t *bucket = &pool->buckets[index]; + + // If an id is set on this constant, then we know we have content here. + if (bucket->id != PM_CONSTANT_ID_UNSET && bucket->type == PM_CONSTANT_POOL_BUCKET_OWNED) { + pm_constant_t *constant = &pool->constants[bucket->id - 1]; + xfree((void *) constant->start); + } + } + + xfree(pool->buckets); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_integer.c b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_integer.c new file mode 100644 index 00000000..4170ecc5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_integer.c @@ -0,0 +1,670 @@ +#include "prism/util/pm_integer.h" + +/** + * Pull out the length and values from the integer, regardless of the form in + * which the length/values are stored. + */ +#define INTEGER_EXTRACT(integer, length_variable, values_variable) \ + if ((integer)->values == NULL) { \ + length_variable = 1; \ + values_variable = &(integer)->value; \ + } else { \ + length_variable = (integer)->length; \ + values_variable = (integer)->values; \ + } + +/** + * Adds two positive pm_integer_t with the given base. + * Return pm_integer_t with values allocated. Not normalized. + */ +static void +big_add(pm_integer_t *destination, pm_integer_t *left, pm_integer_t *right, uint64_t base) { + size_t left_length; + uint32_t *left_values; + INTEGER_EXTRACT(left, left_length, left_values) + + size_t right_length; + uint32_t *right_values; + INTEGER_EXTRACT(right, right_length, right_values) + + size_t length = left_length < right_length ? right_length : left_length; + uint32_t *values = (uint32_t *) xmalloc(sizeof(uint32_t) * (length + 1)); + if (values == NULL) return; + + uint64_t carry = 0; + for (size_t index = 0; index < length; index++) { + uint64_t sum = carry + (index < left_length ? left_values[index] : 0) + (index < right_length ? right_values[index] : 0); + values[index] = (uint32_t) (sum % base); + carry = sum / base; + } + + if (carry > 0) { + values[length] = (uint32_t) carry; + length++; + } + + *destination = (pm_integer_t) { length, values, 0, false }; +} + +/** + * Internal use for karatsuba_multiply. Calculates `a - b - c` with the given + * base. Assume a, b, c, a - b - c all to be positive. + * Return pm_integer_t with values allocated. Not normalized. + */ +static void +big_sub2(pm_integer_t *destination, pm_integer_t *a, pm_integer_t *b, pm_integer_t *c, uint64_t base) { + size_t a_length; + uint32_t *a_values; + INTEGER_EXTRACT(a, a_length, a_values) + + size_t b_length; + uint32_t *b_values; + INTEGER_EXTRACT(b, b_length, b_values) + + size_t c_length; + uint32_t *c_values; + INTEGER_EXTRACT(c, c_length, c_values) + + uint32_t *values = (uint32_t*) xmalloc(sizeof(uint32_t) * a_length); + int64_t carry = 0; + + for (size_t index = 0; index < a_length; index++) { + int64_t sub = ( + carry + + a_values[index] - + (index < b_length ? b_values[index] : 0) - + (index < c_length ? c_values[index] : 0) + ); + + if (sub >= 0) { + values[index] = (uint32_t) sub; + carry = 0; + } else { + sub += 2 * (int64_t) base; + values[index] = (uint32_t) ((uint64_t) sub % base); + carry = sub / (int64_t) base - 2; + } + } + + while (a_length > 1 && values[a_length - 1] == 0) a_length--; + *destination = (pm_integer_t) { a_length, values, 0, false }; +} + +/** + * Multiply two positive integers with the given base using karatsuba algorithm. + * Return pm_integer_t with values allocated. Not normalized. + */ +static void +karatsuba_multiply(pm_integer_t *destination, pm_integer_t *left, pm_integer_t *right, uint64_t base) { + size_t left_length; + uint32_t *left_values; + INTEGER_EXTRACT(left, left_length, left_values) + + size_t right_length; + uint32_t *right_values; + INTEGER_EXTRACT(right, right_length, right_values) + + if (left_length > right_length) { + size_t temporary_length = left_length; + left_length = right_length; + right_length = temporary_length; + + uint32_t *temporary_values = left_values; + left_values = right_values; + right_values = temporary_values; + } + + if (left_length <= 10) { + size_t length = left_length + right_length; + uint32_t *values = (uint32_t *) xcalloc(length, sizeof(uint32_t)); + if (values == NULL) return; + + for (size_t left_index = 0; left_index < left_length; left_index++) { + uint32_t carry = 0; + for (size_t right_index = 0; right_index < right_length; right_index++) { + uint64_t product = (uint64_t) left_values[left_index] * right_values[right_index] + values[left_index + right_index] + carry; + values[left_index + right_index] = (uint32_t) (product % base); + carry = (uint32_t) (product / base); + } + values[left_index + right_length] = carry; + } + + while (length > 1 && values[length - 1] == 0) length--; + *destination = (pm_integer_t) { length, values, 0, false }; + return; + } + + if (left_length * 2 <= right_length) { + uint32_t *values = (uint32_t *) xcalloc(left_length + right_length, sizeof(uint32_t)); + + for (size_t start_offset = 0; start_offset < right_length; start_offset += left_length) { + size_t end_offset = start_offset + left_length; + if (end_offset > right_length) end_offset = right_length; + + pm_integer_t sliced_left = { + .length = left_length, + .values = left_values, + .value = 0, + .negative = false + }; + + pm_integer_t sliced_right = { + .length = end_offset - start_offset, + .values = right_values + start_offset, + .value = 0, + .negative = false + }; + + pm_integer_t product; + karatsuba_multiply(&product, &sliced_left, &sliced_right, base); + + uint32_t carry = 0; + for (size_t index = 0; index < product.length; index++) { + uint64_t sum = (uint64_t) values[start_offset + index] + product.values[index] + carry; + values[start_offset + index] = (uint32_t) (sum % base); + carry = (uint32_t) (sum / base); + } + + if (carry > 0) values[start_offset + product.length] += carry; + pm_integer_free(&product); + } + + *destination = (pm_integer_t) { left_length + right_length, values, 0, false }; + return; + } + + size_t half = left_length / 2; + pm_integer_t x0 = { half, left_values, 0, false }; + pm_integer_t x1 = { left_length - half, left_values + half, 0, false }; + pm_integer_t y0 = { half, right_values, 0, false }; + pm_integer_t y1 = { right_length - half, right_values + half, 0, false }; + + pm_integer_t z0 = { 0 }; + karatsuba_multiply(&z0, &x0, &y0, base); + + pm_integer_t z2 = { 0 }; + karatsuba_multiply(&z2, &x1, &y1, base); + + // For simplicity to avoid considering negative values, + // use `z1 = (x0 + x1) * (y0 + y1) - z0 - z2` instead of original karatsuba algorithm. + pm_integer_t x01 = { 0 }; + big_add(&x01, &x0, &x1, base); + + pm_integer_t y01 = { 0 }; + big_add(&y01, &y0, &y1, base); + + pm_integer_t xy = { 0 }; + karatsuba_multiply(&xy, &x01, &y01, base); + + pm_integer_t z1; + big_sub2(&z1, &xy, &z0, &z2, base); + + size_t length = left_length + right_length; + uint32_t *values = (uint32_t*) xcalloc(length, sizeof(uint32_t)); + + assert(z0.values != NULL); + memcpy(values, z0.values, sizeof(uint32_t) * z0.length); + + assert(z2.values != NULL); + memcpy(values + 2 * half, z2.values, sizeof(uint32_t) * z2.length); + + uint32_t carry = 0; + for(size_t index = 0; index < z1.length; index++) { + uint64_t sum = (uint64_t) carry + values[index + half] + z1.values[index]; + values[index + half] = (uint32_t) (sum % base); + carry = (uint32_t) (sum / base); + } + + for(size_t index = half + z1.length; carry > 0; index++) { + uint64_t sum = (uint64_t) carry + values[index]; + values[index] = (uint32_t) (sum % base); + carry = (uint32_t) (sum / base); + } + + while (length > 1 && values[length - 1] == 0) length--; + pm_integer_free(&z0); + pm_integer_free(&z1); + pm_integer_free(&z2); + pm_integer_free(&x01); + pm_integer_free(&y01); + pm_integer_free(&xy); + + *destination = (pm_integer_t) { length, values, 0, false }; +} + +/** + * The values of a hexadecimal digit, where the index is the ASCII character. + * Note that there's an odd exception here where _ is mapped to 0. This is + * because it's possible for us to end up trying to parse a number that has + * already had an error attached to it, and we want to provide _something_ to + * the user. + */ +static const int8_t pm_integer_parse_digit_values[256] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0x + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 1x + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 2x + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, // 3x + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 4x + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, // 5x + -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 6x + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 7x + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 8x + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 9x + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Ax + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Bx + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Cx + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Dx + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Ex + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // Fx +}; + +/** + * Return the value of a hexadecimal digit in a uint8_t. + */ +static uint8_t +pm_integer_parse_digit(const uint8_t character) { + int8_t value = pm_integer_parse_digit_values[character]; + assert(value != -1 && "invalid digit"); + + return (uint8_t) value; +} + +/** + * Create a pm_integer_t from uint64_t with the given base. It is assumed that + * the memory for the pm_integer_t pointer has been zeroed. + */ +static void +pm_integer_from_uint64(pm_integer_t *integer, uint64_t value, uint64_t base) { + if (value < base) { + integer->value = (uint32_t) value; + return; + } + + size_t length = 0; + uint64_t length_value = value; + while (length_value > 0) { + length++; + length_value /= base; + } + + uint32_t *values = (uint32_t *) xmalloc(sizeof(uint32_t) * length); + if (values == NULL) return; + + for (size_t value_index = 0; value_index < length; value_index++) { + values[value_index] = (uint32_t) (value % base); + value /= base; + } + + integer->length = length; + integer->values = values; +} + +/** + * Normalize pm_integer_t. + * Heading zero values will be removed. If the integer fits into uint32_t, + * values is set to NULL, length is set to 0, and value field will be used. + */ +static void +pm_integer_normalize(pm_integer_t *integer) { + if (integer->values == NULL) { + return; + } + + while (integer->length > 1 && integer->values[integer->length - 1] == 0) { + integer->length--; + } + + if (integer->length > 1) { + return; + } + + uint32_t value = integer->values[0]; + bool negative = integer->negative && value != 0; + + pm_integer_free(integer); + *integer = (pm_integer_t) { .values = NULL, .value = value, .length = 0, .negative = negative }; +} + +/** + * Convert base of the integer. + * In practice, it converts 10**9 to 1<<32 or 1<<32 to 10**9. + */ +static void +pm_integer_convert_base(pm_integer_t *destination, const pm_integer_t *source, uint64_t base_from, uint64_t base_to) { + size_t source_length; + const uint32_t *source_values; + INTEGER_EXTRACT(source, source_length, source_values) + + size_t bigints_length = (source_length + 1) / 2; + assert(bigints_length > 0); + + pm_integer_t *bigints = (pm_integer_t *) xcalloc(bigints_length, sizeof(pm_integer_t)); + if (bigints == NULL) return; + + for (size_t index = 0; index < source_length; index += 2) { + uint64_t value = source_values[index] + base_from * (index + 1 < source_length ? source_values[index + 1] : 0); + pm_integer_from_uint64(&bigints[index / 2], value, base_to); + } + + pm_integer_t base = { 0 }; + pm_integer_from_uint64(&base, base_from, base_to); + + while (bigints_length > 1) { + pm_integer_t next_base; + karatsuba_multiply(&next_base, &base, &base, base_to); + + pm_integer_free(&base); + base = next_base; + + size_t next_length = (bigints_length + 1) / 2; + pm_integer_t *next_bigints = (pm_integer_t *) xcalloc(next_length, sizeof(pm_integer_t)); + + for (size_t bigints_index = 0; bigints_index < bigints_length; bigints_index += 2) { + if (bigints_index + 1 == bigints_length) { + next_bigints[bigints_index / 2] = bigints[bigints_index]; + } else { + pm_integer_t multiplied = { 0 }; + karatsuba_multiply(&multiplied, &base, &bigints[bigints_index + 1], base_to); + + big_add(&next_bigints[bigints_index / 2], &bigints[bigints_index], &multiplied, base_to); + pm_integer_free(&bigints[bigints_index]); + pm_integer_free(&bigints[bigints_index + 1]); + pm_integer_free(&multiplied); + } + } + + xfree(bigints); + bigints = next_bigints; + bigints_length = next_length; + } + + *destination = bigints[0]; + destination->negative = source->negative; + pm_integer_normalize(destination); + + xfree(bigints); + pm_integer_free(&base); +} + +#undef INTEGER_EXTRACT + +/** + * Convert digits to integer with the given power-of-two base. + */ +static void +pm_integer_parse_powof2(pm_integer_t *integer, uint32_t base, const uint8_t *digits, size_t digits_length) { + size_t bit = 1; + while (base > (uint32_t) (1 << bit)) bit++; + + size_t length = (digits_length * bit + 31) / 32; + uint32_t *values = (uint32_t *) xcalloc(length, sizeof(uint32_t)); + + for (size_t digit_index = 0; digit_index < digits_length; digit_index++) { + size_t bit_position = bit * (digits_length - digit_index - 1); + uint32_t value = digits[digit_index]; + + size_t index = bit_position / 32; + size_t shift = bit_position % 32; + + values[index] |= value << shift; + if (32 - shift < bit) values[index + 1] |= value >> (32 - shift); + } + + while (length > 1 && values[length - 1] == 0) length--; + *integer = (pm_integer_t) { .length = length, .values = values, .value = 0, .negative = false }; + pm_integer_normalize(integer); +} + +/** + * Convert decimal digits to pm_integer_t. + */ +static void +pm_integer_parse_decimal(pm_integer_t *integer, const uint8_t *digits, size_t digits_length) { + const size_t batch = 9; + size_t length = (digits_length + batch - 1) / batch; + + uint32_t *values = (uint32_t *) xcalloc(length, sizeof(uint32_t)); + uint32_t value = 0; + + for (size_t digits_index = 0; digits_index < digits_length; digits_index++) { + value = value * 10 + digits[digits_index]; + + size_t reverse_index = digits_length - digits_index - 1; + if (reverse_index % batch == 0) { + values[reverse_index / batch] = value; + value = 0; + } + } + + // Convert base from 10**9 to 1<<32. + pm_integer_convert_base(integer, &((pm_integer_t) { .length = length, .values = values, .value = 0, .negative = false }), 1000000000, ((uint64_t) 1 << 32)); + xfree(values); +} + +/** + * Parse a large integer from a string that does not fit into uint32_t. + */ +static void +pm_integer_parse_big(pm_integer_t *integer, uint32_t multiplier, const uint8_t *start, const uint8_t *end) { + // Allocate an array to store digits. + uint8_t *digits = xmalloc(sizeof(uint8_t) * (size_t) (end - start)); + size_t digits_length = 0; + + for (; start < end; start++) { + if (*start == '_') continue; + digits[digits_length++] = pm_integer_parse_digit(*start); + } + + // Construct pm_integer_t from the digits. + if (multiplier == 10) { + pm_integer_parse_decimal(integer, digits, digits_length); + } else { + pm_integer_parse_powof2(integer, multiplier, digits, digits_length); + } + + xfree(digits); +} + +/** + * Parse an integer from a string. This assumes that the format of the integer + * has already been validated, as internal validation checks are not performed + * here. + */ +void +pm_integer_parse(pm_integer_t *integer, pm_integer_base_t base, const uint8_t *start, const uint8_t *end) { + // Ignore unary +. Unary - is parsed differently and will not end up here. + // Instead, it will modify the parsed integer later. + if (*start == '+') start++; + + // Determine the multiplier from the base, and skip past any prefixes. + uint32_t multiplier = 10; + switch (base) { + case PM_INTEGER_BASE_DEFAULT: + while (*start == '0') start++; // 01 -> 1 + break; + case PM_INTEGER_BASE_BINARY: + start += 2; // 0b + multiplier = 2; + break; + case PM_INTEGER_BASE_OCTAL: + start++; // 0 + if (*start == '_' || *start == 'o' || *start == 'O') start++; // o + multiplier = 8; + break; + case PM_INTEGER_BASE_DECIMAL: + if (*start == '0' && (end - start) > 1) start += 2; // 0d + break; + case PM_INTEGER_BASE_HEXADECIMAL: + start += 2; // 0x + multiplier = 16; + break; + case PM_INTEGER_BASE_UNKNOWN: + if (*start == '0' && (end - start) > 1) { + switch (start[1]) { + case '_': start += 2; multiplier = 8; break; + case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': start++; multiplier = 8; break; + case 'b': case 'B': start += 2; multiplier = 2; break; + case 'o': case 'O': start += 2; multiplier = 8; break; + case 'd': case 'D': start += 2; break; + case 'x': case 'X': start += 2; multiplier = 16; break; + default: assert(false && "unreachable"); break; + } + } + break; + } + + // It's possible that we've consumed everything at this point if there is an + // invalid integer. If this is the case, we'll just return 0. + if (start >= end) return; + + const uint8_t *cursor = start; + uint64_t value = (uint64_t) pm_integer_parse_digit(*cursor++); + + for (; cursor < end; cursor++) { + if (*cursor == '_') continue; + value = value * multiplier + (uint64_t) pm_integer_parse_digit(*cursor); + + if (value > UINT32_MAX) { + // If the integer is too large to fit into a single uint32_t, then + // we'll parse it as a big integer. + pm_integer_parse_big(integer, multiplier, start, end); + return; + } + } + + integer->value = (uint32_t) value; +} + +/** + * Compare two integers. This function returns -1 if the left integer is less + * than the right integer, 0 if they are equal, and 1 if the left integer is + * greater than the right integer. + */ +int +pm_integer_compare(const pm_integer_t *left, const pm_integer_t *right) { + if (left->negative != right->negative) return left->negative ? -1 : 1; + int negative = left->negative ? -1 : 1; + + if (left->values == NULL && right->values == NULL) { + if (left->value < right->value) return -1 * negative; + if (left->value > right->value) return 1 * negative; + return 0; + } + + if (left->values == NULL || left->length < right->length) return -1 * negative; + if (right->values == NULL || left->length > right->length) return 1 * negative; + + for (size_t index = 0; index < left->length; index++) { + size_t value_index = left->length - index - 1; + uint32_t left_value = left->values[value_index]; + uint32_t right_value = right->values[value_index]; + + if (left_value < right_value) return -1 * negative; + if (left_value > right_value) return 1 * negative; + } + + return 0; +} + +/** + * Reduce a ratio of integers to its simplest form. + */ +void pm_integers_reduce(pm_integer_t *numerator, pm_integer_t *denominator) { + // If either the numerator or denominator do not fit into a 32-bit integer, + // then this function is a no-op. In the future, we may consider reducing + // even the larger numbers, but for now we're going to keep it simple. + if ( + // If the numerator doesn't fit into a 32-bit integer, return early. + numerator->length != 0 || + // If the denominator doesn't fit into a 32-bit integer, return early. + denominator->length != 0 || + // If the numerator is 0, then return early. + numerator->value == 0 || + // If the denominator is 1, then return early. + denominator->value == 1 + ) return; + + // Find the greatest common divisor of the numerator and denominator. + uint32_t divisor = numerator->value; + uint32_t remainder = denominator->value; + + while (remainder != 0) { + uint32_t temporary = remainder; + remainder = divisor % remainder; + divisor = temporary; + } + + // Divide the numerator and denominator by the greatest common divisor. + numerator->value /= divisor; + denominator->value /= divisor; +} + +/** + * Convert an integer to a decimal string. + */ +PRISM_EXPORTED_FUNCTION void +pm_integer_string(pm_buffer_t *buffer, const pm_integer_t *integer) { + if (integer->negative) { + pm_buffer_append_byte(buffer, '-'); + } + + // If the integer fits into a single uint32_t, then we can just append the + // value directly to the buffer. + if (integer->values == NULL) { + pm_buffer_append_format(buffer, "%" PRIu32, integer->value); + return; + } + + // If the integer is two uint32_t values, then we can | them together and + // append the result to the buffer. + if (integer->length == 2) { + const uint64_t value = ((uint64_t) integer->values[0]) | ((uint64_t) integer->values[1] << 32); + pm_buffer_append_format(buffer, "%" PRIu64, value); + return; + } + + // Otherwise, first we'll convert the base from 1<<32 to 10**9. + pm_integer_t converted = { 0 }; + pm_integer_convert_base(&converted, integer, (uint64_t) 1 << 32, 1000000000); + + if (converted.values == NULL) { + pm_buffer_append_format(buffer, "%" PRIu32, converted.value); + pm_integer_free(&converted); + return; + } + + // Allocate a buffer that we'll copy the decimal digits into. + size_t digits_length = converted.length * 9; + char *digits = xcalloc(digits_length, sizeof(char)); + if (digits == NULL) return; + + // Pack bigdecimal to digits. + for (size_t value_index = 0; value_index < converted.length; value_index++) { + uint32_t value = converted.values[value_index]; + + for (size_t digit_index = 0; digit_index < 9; digit_index++) { + digits[digits_length - 9 * value_index - digit_index - 1] = (char) ('0' + value % 10); + value /= 10; + } + } + + size_t start_offset = 0; + while (start_offset < digits_length - 1 && digits[start_offset] == '0') start_offset++; + + // Finally, append the string to the buffer and free the digits. + pm_buffer_append_string(buffer, digits + start_offset, digits_length - start_offset); + xfree(digits); + pm_integer_free(&converted); +} + +/** + * Free the internal memory of an integer. This memory will only be allocated if + * the integer exceeds the size of a single uint32_t. + */ +PRISM_EXPORTED_FUNCTION void +pm_integer_free(pm_integer_t *integer) { + if (integer->values) { + xfree(integer->values); + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_list.c b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_list.c new file mode 100644 index 00000000..ad2294cd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_list.c @@ -0,0 +1,49 @@ +#include "prism/util/pm_list.h" + +/** + * Returns true if the given list is empty. + */ +PRISM_EXPORTED_FUNCTION bool +pm_list_empty_p(pm_list_t *list) { + return list->head == NULL; +} + +/** + * Returns the size of the list. + */ +PRISM_EXPORTED_FUNCTION size_t +pm_list_size(pm_list_t *list) { + return list->size; +} + +/** + * Append a node to the given list. + */ +void +pm_list_append(pm_list_t *list, pm_list_node_t *node) { + if (list->head == NULL) { + list->head = node; + } else { + list->tail->next = node; + } + + list->tail = node; + list->size++; +} + +/** + * Deallocate the internal state of the given list. + */ +PRISM_EXPORTED_FUNCTION void +pm_list_free(pm_list_t *list) { + pm_list_node_t *node = list->head; + pm_list_node_t *next; + + while (node != NULL) { + next = node->next; + xfree(node); + node = next; + } + + list->size = 0; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_memchr.c b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_memchr.c new file mode 100644 index 00000000..7ea20ace --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_memchr.c @@ -0,0 +1,35 @@ +#include "prism/util/pm_memchr.h" + +#define PRISM_MEMCHR_TRAILING_BYTE_MINIMUM 0x40 + +/** + * We need to roll our own memchr to handle cases where the encoding changes and + * we need to search for a character in a buffer that could be the trailing byte + * of a multibyte character. + */ +void * +pm_memchr(const void *memory, int character, size_t number, bool encoding_changed, const pm_encoding_t *encoding) { + if (encoding_changed && encoding->multibyte && character >= PRISM_MEMCHR_TRAILING_BYTE_MINIMUM) { + const uint8_t *source = (const uint8_t *) memory; + size_t index = 0; + + while (index < number) { + if (source[index] == character) { + return (void *) (source + index); + } + + size_t width = encoding->char_width(source + index, (ptrdiff_t) (number - index)); + if (width == 0) { + return NULL; + } + + index += width; + } + + return NULL; + } else { + return memchr(memory, character, number); + } +} + +#undef PRISM_MEMCHR_TRAILING_BYTE_MINIMUM diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_newline_list.c b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_newline_list.c new file mode 100644 index 00000000..8331618f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_newline_list.c @@ -0,0 +1,125 @@ +#include "prism/util/pm_newline_list.h" + +/** + * Initialize a new newline list with the given capacity. Returns true if the + * allocation of the offsets succeeds, otherwise returns false. + */ +bool +pm_newline_list_init(pm_newline_list_t *list, const uint8_t *start, size_t capacity) { + list->offsets = (size_t *) xcalloc(capacity, sizeof(size_t)); + if (list->offsets == NULL) return false; + + list->start = start; + + // This is 1 instead of 0 because we want to include the first line of the + // file as having offset 0, which is set because of calloc. + list->size = 1; + list->capacity = capacity; + + return true; +} + +/** + * Clear out the newlines that have been appended to the list. + */ +void +pm_newline_list_clear(pm_newline_list_t *list) { + list->size = 1; +} + +/** + * Append a new offset to the newline list. Returns true if the reallocation of + * the offsets succeeds (if one was necessary), otherwise returns false. + */ +bool +pm_newline_list_append(pm_newline_list_t *list, const uint8_t *cursor) { + if (list->size == list->capacity) { + size_t *original_offsets = list->offsets; + + list->capacity = (list->capacity * 3) / 2; + list->offsets = (size_t *) xcalloc(list->capacity, sizeof(size_t)); + if (list->offsets == NULL) return false; + + memcpy(list->offsets, original_offsets, list->size * sizeof(size_t)); + xfree(original_offsets); + } + + assert(*cursor == '\n'); + assert(cursor >= list->start); + size_t newline_offset = (size_t) (cursor - list->start + 1); + + assert(list->size == 0 || newline_offset > list->offsets[list->size - 1]); + list->offsets[list->size++] = newline_offset; + + return true; +} + +/** + * Returns the line of the given offset. If the offset is not in the list, the + * line of the closest offset less than the given offset is returned. + */ +int32_t +pm_newline_list_line(const pm_newline_list_t *list, const uint8_t *cursor, int32_t start_line) { + assert(cursor >= list->start); + size_t offset = (size_t) (cursor - list->start); + + size_t left = 0; + size_t right = list->size - 1; + + while (left <= right) { + size_t mid = left + (right - left) / 2; + + if (list->offsets[mid] == offset) { + return ((int32_t) mid) + start_line; + } + + if (list->offsets[mid] < offset) { + left = mid + 1; + } else { + right = mid - 1; + } + } + + return ((int32_t) left) + start_line - 1; +} + +/** + * Returns the line and column of the given offset. If the offset is not in the + * list, the line and column of the closest offset less than the given offset + * are returned. + */ +pm_line_column_t +pm_newline_list_line_column(const pm_newline_list_t *list, const uint8_t *cursor, int32_t start_line) { + assert(cursor >= list->start); + size_t offset = (size_t) (cursor - list->start); + + size_t left = 0; + size_t right = list->size - 1; + + while (left <= right) { + size_t mid = left + (right - left) / 2; + + if (list->offsets[mid] == offset) { + return ((pm_line_column_t) { ((int32_t) mid) + start_line, 0 }); + } + + if (list->offsets[mid] < offset) { + left = mid + 1; + } else { + right = mid - 1; + } + } + + return ((pm_line_column_t) { + .line = ((int32_t) left) + start_line - 1, + .column = (uint32_t) (offset - list->offsets[left - 1]) + }); +} + +/** + * Free the internal memory allocated for the newline list. + */ +void +pm_newline_list_free(pm_newline_list_t *list) { + xfree(list->offsets); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_string.c b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_string.c new file mode 100644 index 00000000..75422fbd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_string.c @@ -0,0 +1,383 @@ +#include "prism/util/pm_string.h" + +/** + * Returns the size of the pm_string_t struct. This is necessary to allocate the + * correct amount of memory in the FFI backend. + */ +PRISM_EXPORTED_FUNCTION size_t +pm_string_sizeof(void) { + return sizeof(pm_string_t); +} + +/** + * Initialize a shared string that is based on initial input. + */ +void +pm_string_shared_init(pm_string_t *string, const uint8_t *start, const uint8_t *end) { + assert(start <= end); + + *string = (pm_string_t) { + .type = PM_STRING_SHARED, + .source = start, + .length = (size_t) (end - start) + }; +} + +/** + * Initialize an owned string that is responsible for freeing allocated memory. + */ +void +pm_string_owned_init(pm_string_t *string, uint8_t *source, size_t length) { + *string = (pm_string_t) { + .type = PM_STRING_OWNED, + .source = source, + .length = length + }; +} + +/** + * Initialize a constant string that doesn't own its memory source. + */ +void +pm_string_constant_init(pm_string_t *string, const char *source, size_t length) { + *string = (pm_string_t) { + .type = PM_STRING_CONSTANT, + .source = (const uint8_t *) source, + .length = length + }; +} + +#ifdef _WIN32 +/** + * Represents a file handle on Windows, where the path will need to be freed + * when the file is closed. + */ +typedef struct { + /** The path to the file, which will become allocated memory. */ + WCHAR *path; + + /** The handle to the file, which will start as uninitialized memory. */ + HANDLE file; +} pm_string_file_handle_t; + +/** + * Open the file indicated by the filepath parameter for reading on Windows. + * Perform any kind of normalization that needs to happen on the filepath. + */ +static pm_string_init_result_t +pm_string_file_handle_open(pm_string_file_handle_t *handle, const char *filepath) { + int length = MultiByteToWideChar(CP_UTF8, 0, filepath, -1, NULL, 0); + if (length == 0) return PM_STRING_INIT_ERROR_GENERIC; + + handle->path = xmalloc(sizeof(WCHAR) * ((size_t) length)); + if ((handle->path == NULL) || (MultiByteToWideChar(CP_UTF8, 0, filepath, -1, handle->path, length) == 0)) { + xfree(handle->path); + return PM_STRING_INIT_ERROR_GENERIC; + } + + handle->file = CreateFileW(handle->path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); + if (handle->file == INVALID_HANDLE_VALUE) { + pm_string_init_result_t result = PM_STRING_INIT_ERROR_GENERIC; + + if (GetLastError() == ERROR_ACCESS_DENIED) { + DWORD attributes = GetFileAttributesW(handle->path); + if ((attributes != INVALID_FILE_ATTRIBUTES) && (attributes & FILE_ATTRIBUTE_DIRECTORY)) { + result = PM_STRING_INIT_ERROR_DIRECTORY; + } + } + + xfree(handle->path); + return result; + } + + return PM_STRING_INIT_SUCCESS; +} + +/** + * Close the file handle and free the path. + */ +static void +pm_string_file_handle_close(pm_string_file_handle_t *handle) { + xfree(handle->path); + CloseHandle(handle->file); +} +#endif + +/** + * Read the file indicated by the filepath parameter into source and load its + * contents and size into the given `pm_string_t`. The given `pm_string_t` + * should be freed using `pm_string_free` when it is no longer used. + * + * We want to use demand paging as much as possible in order to avoid having to + * read the entire file into memory (which could be detrimental to performance + * for large files). This means that if we're on windows we'll use + * `MapViewOfFile`, on POSIX systems that have access to `mmap` we'll use + * `mmap`, and on other POSIX systems we'll use `read`. + */ +PRISM_EXPORTED_FUNCTION pm_string_init_result_t +pm_string_mapped_init(pm_string_t *string, const char *filepath) { +#ifdef _WIN32 + // Open the file for reading. + pm_string_file_handle_t handle; + pm_string_init_result_t result = pm_string_file_handle_open(&handle, filepath); + if (result != PM_STRING_INIT_SUCCESS) return result; + + // Get the file size. + DWORD file_size = GetFileSize(handle.file, NULL); + if (file_size == INVALID_FILE_SIZE) { + pm_string_file_handle_close(&handle); + return PM_STRING_INIT_ERROR_GENERIC; + } + + // If the file is empty, then we don't need to do anything else, we'll set + // the source to a constant empty string and return. + if (file_size == 0) { + pm_string_file_handle_close(&handle); + const uint8_t source[] = ""; + *string = (pm_string_t) { .type = PM_STRING_CONSTANT, .source = source, .length = 0 }; + return PM_STRING_INIT_SUCCESS; + } + + // Create a mapping of the file. + HANDLE mapping = CreateFileMapping(handle.file, NULL, PAGE_READONLY, 0, 0, NULL); + if (mapping == NULL) { + pm_string_file_handle_close(&handle); + return PM_STRING_INIT_ERROR_GENERIC; + } + + // Map the file into memory. + uint8_t *source = (uint8_t *) MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0); + CloseHandle(mapping); + pm_string_file_handle_close(&handle); + + if (source == NULL) { + return PM_STRING_INIT_ERROR_GENERIC; + } + + *string = (pm_string_t) { .type = PM_STRING_MAPPED, .source = source, .length = (size_t) file_size }; + return PM_STRING_INIT_SUCCESS; +#elif defined(_POSIX_MAPPED_FILES) + // Open the file for reading + int fd = open(filepath, O_RDONLY); + if (fd == -1) { + return PM_STRING_INIT_ERROR_GENERIC; + } + + // Stat the file to get the file size + struct stat sb; + if (fstat(fd, &sb) == -1) { + close(fd); + return PM_STRING_INIT_ERROR_GENERIC; + } + + // Ensure it is a file and not a directory + if (S_ISDIR(sb.st_mode)) { + close(fd); + return PM_STRING_INIT_ERROR_DIRECTORY; + } + + // mmap the file descriptor to virtually get the contents + size_t size = (size_t) sb.st_size; + uint8_t *source = NULL; + + if (size == 0) { + close(fd); + const uint8_t source[] = ""; + *string = (pm_string_t) { .type = PM_STRING_CONSTANT, .source = source, .length = 0 }; + return PM_STRING_INIT_SUCCESS; + } + + source = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); + if (source == MAP_FAILED) { + close(fd); + return PM_STRING_INIT_ERROR_GENERIC; + } + + close(fd); + *string = (pm_string_t) { .type = PM_STRING_MAPPED, .source = source, .length = size }; + return PM_STRING_INIT_SUCCESS; +#else + return pm_string_file_init(string, filepath); +#endif +} + +/** + * Read the file indicated by the filepath parameter into source and load its + * contents and size into the given `pm_string_t`. The given `pm_string_t` + * should be freed using `pm_string_free` when it is no longer used. + */ +PRISM_EXPORTED_FUNCTION pm_string_init_result_t +pm_string_file_init(pm_string_t *string, const char *filepath) { +#ifdef _WIN32 + // Open the file for reading. + pm_string_file_handle_t handle; + pm_string_init_result_t result = pm_string_file_handle_open(&handle, filepath); + if (result != PM_STRING_INIT_SUCCESS) return result; + + // Get the file size. + DWORD file_size = GetFileSize(handle.file, NULL); + if (file_size == INVALID_FILE_SIZE) { + pm_string_file_handle_close(&handle); + return PM_STRING_INIT_ERROR_GENERIC; + } + + // If the file is empty, then we don't need to do anything else, we'll set + // the source to a constant empty string and return. + if (file_size == 0) { + pm_string_file_handle_close(&handle); + const uint8_t source[] = ""; + *string = (pm_string_t) { .type = PM_STRING_CONSTANT, .source = source, .length = 0 }; + return PM_STRING_INIT_SUCCESS; + } + + // Create a buffer to read the file into. + uint8_t *source = xmalloc(file_size); + if (source == NULL) { + pm_string_file_handle_close(&handle); + return PM_STRING_INIT_ERROR_GENERIC; + } + + // Read the contents of the file + DWORD bytes_read; + if (!ReadFile(handle.file, source, file_size, &bytes_read, NULL)) { + pm_string_file_handle_close(&handle); + return PM_STRING_INIT_ERROR_GENERIC; + } + + // Check the number of bytes read + if (bytes_read != file_size) { + xfree(source); + pm_string_file_handle_close(&handle); + return PM_STRING_INIT_ERROR_GENERIC; + } + + pm_string_file_handle_close(&handle); + *string = (pm_string_t) { .type = PM_STRING_OWNED, .source = source, .length = (size_t) file_size }; + return PM_STRING_INIT_SUCCESS; +#elif defined(PRISM_HAS_FILESYSTEM) + // Open the file for reading + int fd = open(filepath, O_RDONLY); + if (fd == -1) { + return PM_STRING_INIT_ERROR_GENERIC; + } + + // Stat the file to get the file size + struct stat sb; + if (fstat(fd, &sb) == -1) { + close(fd); + return PM_STRING_INIT_ERROR_GENERIC; + } + + // Ensure it is a file and not a directory + if (S_ISDIR(sb.st_mode)) { + close(fd); + return PM_STRING_INIT_ERROR_DIRECTORY; + } + + // Check the size to see if it's empty + size_t size = (size_t) sb.st_size; + if (size == 0) { + close(fd); + const uint8_t source[] = ""; + *string = (pm_string_t) { .type = PM_STRING_CONSTANT, .source = source, .length = 0 }; + return PM_STRING_INIT_SUCCESS; + } + + size_t length = (size_t) size; + uint8_t *source = xmalloc(length); + if (source == NULL) { + close(fd); + return PM_STRING_INIT_ERROR_GENERIC; + } + + long bytes_read = (long) read(fd, source, length); + close(fd); + + if (bytes_read == -1) { + xfree(source); + return PM_STRING_INIT_ERROR_GENERIC; + } + + *string = (pm_string_t) { .type = PM_STRING_OWNED, .source = source, .length = length }; + return PM_STRING_INIT_SUCCESS; +#else + (void) string; + (void) filepath; + perror("pm_string_file_init is not implemented for this platform"); + return PM_STRING_INIT_ERROR_GENERIC; +#endif +} + +/** + * Ensure the string is owned. If it is not, then reinitialize it as owned and + * copy over the previous source. + */ +void +pm_string_ensure_owned(pm_string_t *string) { + if (string->type == PM_STRING_OWNED) return; + + size_t length = pm_string_length(string); + const uint8_t *source = pm_string_source(string); + + uint8_t *memory = xmalloc(length); + if (!memory) return; + + pm_string_owned_init(string, memory, length); + memcpy((void *) string->source, source, length); +} + +/** + * Compare the underlying lengths and bytes of two strings. Returns 0 if the + * strings are equal, a negative number if the left string is less than the + * right string, and a positive number if the left string is greater than the + * right string. + */ +int +pm_string_compare(const pm_string_t *left, const pm_string_t *right) { + size_t left_length = pm_string_length(left); + size_t right_length = pm_string_length(right); + + if (left_length < right_length) { + return -1; + } else if (left_length > right_length) { + return 1; + } + + return memcmp(pm_string_source(left), pm_string_source(right), left_length); +} + +/** + * Returns the length associated with the string. + */ +PRISM_EXPORTED_FUNCTION size_t +pm_string_length(const pm_string_t *string) { + return string->length; +} + +/** + * Returns the start pointer associated with the string. + */ +PRISM_EXPORTED_FUNCTION const uint8_t * +pm_string_source(const pm_string_t *string) { + return string->source; +} + +/** + * Free the associated memory of the given string. + */ +PRISM_EXPORTED_FUNCTION void +pm_string_free(pm_string_t *string) { + void *memory = (void *) string->source; + + if (string->type == PM_STRING_OWNED) { + xfree(memory); +#ifdef PRISM_HAS_MMAP + } else if (string->type == PM_STRING_MAPPED && string->length) { +#if defined(_WIN32) + UnmapViewOfFile(memory); +#elif defined(_POSIX_MAPPED_FILES) + munmap(memory, string->length); +#endif +#endif /* PRISM_HAS_MMAP */ + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_strncasecmp.c b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_strncasecmp.c new file mode 100644 index 00000000..3f584215 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_strncasecmp.c @@ -0,0 +1,36 @@ +#include "prism/util/pm_strncasecmp.h" + +/** + * A locale-insensitive version of `tolower(3)` + */ +static inline int +pm_tolower(int c) +{ + if ('A' <= c && c <= 'Z') { + return c | 0x20; + } + return c; +} + +/** + * Compare two strings, ignoring case, up to the given length. Returns 0 if the + * strings are equal, a negative number if string1 is less than string2, or a + * positive number if string1 is greater than string2. + * + * Note that this is effectively our own implementation of strncasecmp, but it's + * not available on all of the platforms we want to support so we're rolling it + * here. + */ +int +pm_strncasecmp(const uint8_t *string1, const uint8_t *string2, size_t length) { + size_t offset = 0; + int difference = 0; + + while (offset < length && string1[offset] != '\0') { + if (string2[offset] == '\0') return string1[offset]; + if ((difference = pm_tolower(string1[offset]) - pm_tolower(string2[offset])) != 0) return difference; + offset++; + } + + return difference; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_strpbrk.c b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_strpbrk.c new file mode 100644 index 00000000..916a4cc3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/prism-1.4.0/src/util/pm_strpbrk.c @@ -0,0 +1,206 @@ +#include "prism/util/pm_strpbrk.h" + +/** + * Add an invalid multibyte character error to the parser. + */ +static inline void +pm_strpbrk_invalid_multibyte_character(pm_parser_t *parser, const uint8_t *start, const uint8_t *end) { + pm_diagnostic_list_append_format(&parser->error_list, start, end, PM_ERR_INVALID_MULTIBYTE_CHARACTER, *start); +} + +/** + * Set the explicit encoding for the parser to the current encoding. + */ +static inline void +pm_strpbrk_explicit_encoding_set(pm_parser_t *parser, const uint8_t *source, size_t width) { + if (parser->explicit_encoding != NULL) { + if (parser->explicit_encoding == parser->encoding) { + // Okay, we already locked to this encoding. + } else if (parser->explicit_encoding == PM_ENCODING_UTF_8_ENTRY) { + // Not okay, we already found a Unicode escape sequence and this + // conflicts. + pm_diagnostic_list_append_format(&parser->error_list, source, source + width, PM_ERR_MIXED_ENCODING, parser->encoding->name); + } else { + // Should not be anything else. + assert(false && "unreachable"); + } + } + + parser->explicit_encoding = parser->encoding; +} + +/** + * This is the default path. + */ +static inline const uint8_t * +pm_strpbrk_utf8(pm_parser_t *parser, const uint8_t *source, const uint8_t *charset, size_t maximum, bool validate) { + size_t index = 0; + + while (index < maximum) { + if (strchr((const char *) charset, source[index]) != NULL) { + return source + index; + } + + if (source[index] < 0x80) { + index++; + } else { + size_t width = pm_encoding_utf_8_char_width(source + index, (ptrdiff_t) (maximum - index)); + + if (width > 0) { + index += width; + } else if (!validate) { + index++; + } else { + // At this point we know we have an invalid multibyte character. + // We'll walk forward as far as we can until we find the next + // valid character so that we don't spam the user with a ton of + // the same kind of error. + const size_t start = index; + + do { + index++; + } while (index < maximum && pm_encoding_utf_8_char_width(source + index, (ptrdiff_t) (maximum - index)) == 0); + + pm_strpbrk_invalid_multibyte_character(parser, source + start, source + index); + } + } + } + + return NULL; +} + +/** + * This is the path when the encoding is ASCII-8BIT. + */ +static inline const uint8_t * +pm_strpbrk_ascii_8bit(pm_parser_t *parser, const uint8_t *source, const uint8_t *charset, size_t maximum, bool validate) { + size_t index = 0; + + while (index < maximum) { + if (strchr((const char *) charset, source[index]) != NULL) { + return source + index; + } + + if (validate && source[index] >= 0x80) pm_strpbrk_explicit_encoding_set(parser, source, 1); + index++; + } + + return NULL; +} + +/** + * This is the slow path that does care about the encoding. + */ +static inline const uint8_t * +pm_strpbrk_multi_byte(pm_parser_t *parser, const uint8_t *source, const uint8_t *charset, size_t maximum, bool validate) { + size_t index = 0; + const pm_encoding_t *encoding = parser->encoding; + + while (index < maximum) { + if (strchr((const char *) charset, source[index]) != NULL) { + return source + index; + } + + if (source[index] < 0x80) { + index++; + } else { + size_t width = encoding->char_width(source + index, (ptrdiff_t) (maximum - index)); + if (validate) pm_strpbrk_explicit_encoding_set(parser, source, width); + + if (width > 0) { + index += width; + } else if (!validate) { + index++; + } else { + // At this point we know we have an invalid multibyte character. + // We'll walk forward as far as we can until we find the next + // valid character so that we don't spam the user with a ton of + // the same kind of error. + const size_t start = index; + + do { + index++; + } while (index < maximum && encoding->char_width(source + index, (ptrdiff_t) (maximum - index)) == 0); + + pm_strpbrk_invalid_multibyte_character(parser, source + start, source + index); + } + } + } + + return NULL; +} + +/** + * This is the fast path that does not care about the encoding because we know + * the encoding only supports single-byte characters. + */ +static inline const uint8_t * +pm_strpbrk_single_byte(pm_parser_t *parser, const uint8_t *source, const uint8_t *charset, size_t maximum, bool validate) { + size_t index = 0; + const pm_encoding_t *encoding = parser->encoding; + + while (index < maximum) { + if (strchr((const char *) charset, source[index]) != NULL) { + return source + index; + } + + if (source[index] < 0x80 || !validate) { + index++; + } else { + size_t width = encoding->char_width(source + index, (ptrdiff_t) (maximum - index)); + pm_strpbrk_explicit_encoding_set(parser, source, width); + + if (width > 0) { + index += width; + } else { + // At this point we know we have an invalid multibyte character. + // We'll walk forward as far as we can until we find the next + // valid character so that we don't spam the user with a ton of + // the same kind of error. + const size_t start = index; + + do { + index++; + } while (index < maximum && encoding->char_width(source + index, (ptrdiff_t) (maximum - index)) == 0); + + pm_strpbrk_invalid_multibyte_character(parser, source + start, source + index); + } + } + } + + return NULL; +} + +/** + * Here we have rolled our own version of strpbrk. The standard library strpbrk + * has undefined behavior when the source string is not null-terminated. We want + * to support strings that are not null-terminated because pm_parse does not + * have the contract that the string is null-terminated. (This is desirable + * because it means the extension can call pm_parse with the result of a call to + * mmap). + * + * The standard library strpbrk also does not support passing a maximum length + * to search. We want to support this for the reason mentioned above, but we + * also don't want it to stop on null bytes. Ruby actually allows null bytes + * within strings, comments, regular expressions, etc. So we need to be able to + * skip past them. + * + * Finally, we want to support encodings wherein the charset could contain + * characters that are trailing bytes of multi-byte characters. For example, in + * Shift_JIS, the backslash character can be a trailing byte. In that case we + * need to take a slower path and iterate one multi-byte character at a time. + */ +const uint8_t * +pm_strpbrk(pm_parser_t *parser, const uint8_t *source, const uint8_t *charset, ptrdiff_t length, bool validate) { + if (length <= 0) { + return NULL; + } else if (!parser->encoding_changed) { + return pm_strpbrk_utf8(parser, source, charset, (size_t) length, validate); + } else if (parser->encoding == PM_ENCODING_ASCII_8BIT_ENTRY) { + return pm_strpbrk_ascii_8bit(parser, source, charset, (size_t) length, validate); + } else if (parser->encoding->multibyte) { + return pm_strpbrk_multi_byte(parser, source, charset, (size_t) length, validate); + } else { + return pm_strpbrk_single_byte(parser, source, charset, (size_t) length, validate); + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/CONTRIBUTING.md b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/CONTRIBUTING.md new file mode 100644 index 00000000..869d801f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/CONTRIBUTING.md @@ -0,0 +1,24 @@ +## How to contribute to Psych + +Full details [here](https://bugs.ruby-lang.org/projects/ruby/wiki/HowToContribute) + +#### **Did you find a bug?** + +* **Do not open an issue if the bug is a security vulnerability + in Psych**, instead refer to our [security policy](https://www.ruby-lang.org/en/security/) and email [here](security@ruby-lang.org). + +* **Ensure the bug was not already reported** by searching on ruby-core, the ruby github repo and on Psych's github repo. More info [here](https://bugs.ruby-lang.org/projects/ruby/wiki/HowToReport) + +* If you're unable to find an open issue addressing the problem, [open a new one](https://bugs.ruby-lang.org/). Be sure to include a **title and clear description**, as much relevant information as possible, and a **code sample** or an **executable test case** demonstrating the expected behavior that is not occurring. + +#### **Did you write a patch that fixes a bug?** + +* Open a new GitHub pull request with the patch for small fixes. Anything larger look [here](https://bugs.ruby-lang.org/projects/ruby/wiki/HowToContribute); submit a Feature. + +* Ensure you clearly describe the problem and solution. Include the relevant ticket/issue number if applicable. + +Psych is a volunteer effort. We encourage you to pitch in and [join the team](https://github.com/ruby/psych/contributors)! + +Thanks! :heart: :heart: :heart: + +The Psych Team diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/LICENSE b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/LICENSE new file mode 100644 index 00000000..7609df5a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2009 Aaron Patterson, et al. + +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 +AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/README.md b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/README.md new file mode 100644 index 00000000..1d25f3d5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/README.md @@ -0,0 +1,80 @@ +# Psych + +* https://github.com/ruby/psych +* https://docs.ruby-lang.org/en/master/Psych.html + +## Description + +Psych is a YAML parser and emitter. Psych leverages +[libyaml](https://pyyaml.org/wiki/LibYAML) for its YAML parsing and emitting +capabilities. In addition to wrapping libyaml, Psych also knows how to +serialize and de-serialize most Ruby objects to and from the YAML format. + +## Examples + +```ruby +# Safely load YAML in to a Ruby object +Psych.safe_load('--- foo') # => 'foo' + +# Emit YAML from a Ruby object +Psych.dump("foo") # => "--- foo\n...\n" +``` + +## Dependencies + +* libyaml + +## Installation + +Psych has been included with MRI since 1.9.2, and is the default YAML parser +in 1.9.3. + +If you want a newer gem release of Psych, you can use RubyGems: + +```bash +gem install psych +``` + +Psych supported the static build with specific version of libyaml sources. You can build psych with libyaml-0.2.5 like this. + +```bash +gem install psych -- --with-libyaml-source-dir=/path/to/libyaml-0.2.5 +``` + +In order to use the gem release in your app, and not the stdlib version, +you'll need the following: + +```ruby +gem 'psych' +require 'psych' +``` + +Or if you use Bundler add this to your `Gemfile`: + +```ruby +gem 'psych' +``` + +JRuby ships with a pure Java implementation of Psych. + +## License + +Copyright 2009 Aaron Patterson, et al. + +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 +AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/Makefile b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/Makefile new file mode 100644 index 00000000..94daf469 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/Makefile @@ -0,0 +1,295 @@ + +SHELL = /bin/sh + +# V=0 quiet, V=1 verbose. other values don't work. +V = 0 +V0 = $(V:0=) +Q1 = $(V:1=) +Q = $(Q1:0=@) +ECHO1 = $(V:1=@ :) +ECHO = $(ECHO1:0=@ echo) +NULLCMD = : + +#### Start of system configuration section. #### + +srcdir = . +topdir = /opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 +hdrdir = $(topdir) +arch_hdrdir = /opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux +PATH_SEPARATOR = : +VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby +prefix = $(DESTDIR)/opt/hostedtoolcache/Ruby/3.4.4/x64 +rubysitearchprefix = $(rubylibprefix)/$(sitearch) +rubyarchprefix = $(rubylibprefix)/$(arch) +rubylibprefix = $(libdir)/$(RUBY_BASE_NAME) +exec_prefix = $(prefix) +vendorarchhdrdir = $(vendorhdrdir)/$(sitearch) +sitearchhdrdir = $(sitehdrdir)/$(sitearch) +rubyarchhdrdir = $(rubyhdrdir)/$(arch) +vendorhdrdir = $(rubyhdrdir)/vendor_ruby +sitehdrdir = $(rubyhdrdir)/site_ruby +rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME) +vendorarchdir = $(vendorlibdir)/$(sitearch) +vendorlibdir = $(vendordir)/$(ruby_version) +vendordir = $(rubylibprefix)/vendor_ruby +sitearchdir = $(sitelibdir)/$(sitearch) +sitelibdir = $(sitedir)/$(ruby_version) +sitedir = $(rubylibprefix)/site_ruby +rubyarchdir = $(rubylibdir)/$(arch) +rubylibdir = $(rubylibprefix)/$(ruby_version) +sitearchincludedir = $(includedir)/$(sitearch) +archincludedir = $(includedir)/$(arch) +sitearchlibdir = $(libdir)/$(sitearch) +archlibdir = $(libdir)/$(arch) +ridir = $(datarootdir)/$(RI_BASE_NAME) +modular_gc_dir = $(DESTDIR) +mandir = $(datarootdir)/man +localedir = $(datarootdir)/locale +libdir = $(exec_prefix)/lib +psdir = $(docdir) +pdfdir = $(docdir) +dvidir = $(docdir) +htmldir = $(docdir) +infodir = $(datarootdir)/info +docdir = $(datarootdir)/doc/$(PACKAGE) +oldincludedir = $(DESTDIR)/usr/include +includedir = $(prefix)/include +runstatedir = $(localstatedir)/run +localstatedir = $(prefix)/var +sharedstatedir = $(prefix)/com +sysconfdir = $(prefix)/etc +datadir = $(datarootdir) +datarootdir = $(prefix)/share +libexecdir = $(exec_prefix)/libexec +sbindir = $(exec_prefix)/sbin +bindir = $(exec_prefix)/bin +archdir = $(rubyarchdir) + + +CC_WRAPPER = +CC = gcc +CXX = g++ +LIBRUBY = $(LIBRUBY_SO) +LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a +LIBRUBYARG_SHARED = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME) +LIBRUBYARG_STATIC = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)-static $(MAINLIBS) +empty = +OUTFLAG = -o $(empty) +COUTFLAG = -o $(empty) +CSRCFLAG = $(empty) + +RUBY_EXTCONF_H = +cflags = $(hardenflags) $(optflags) $(debugflags) $(warnflags) +cxxflags = +optflags = -O3 -fno-fast-math +debugflags = -ggdb3 +warnflags = -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef +cppflags = +CCDLFLAGS = -fPIC +CFLAGS = $(CCDLFLAGS) $(cflags) -fPIC $(ARCH_FLAG) +INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) +DEFS = +CPPFLAGS = -DENABLE_PATH_CHECK=0 $(DEFS) $(cppflags) +CXXFLAGS = $(CCDLFLAGS) $(ARCH_FLAG) +ldflags = -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed +dldflags = -Wl,--compress-debug-sections=zlib +ARCH_FLAG = +DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG) +LDSHARED = $(CC) -shared +LDSHAREDXX = $(CXX) -shared +POSTLINK = : +AR = gcc-ar +LD = ld +EXEEXT = + +RUBY_INSTALL_NAME = $(RUBY_BASE_NAME) +RUBY_SO_NAME = ruby +RUBYW_INSTALL_NAME = +RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version) +RUBYW_BASE_NAME = rubyw +RUBY_BASE_NAME = ruby + +arch = x86_64-linux +sitearch = $(arch) +ruby_version = 3.4.0 +ruby = $(bindir)/$(RUBY_BASE_NAME) +RUBY = $(ruby) +BUILTRUBY = $(bindir)/$(RUBY_BASE_NAME) +ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/backward.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h + +RM = rm -f +RM_RF = rm -fr +RMDIRS = rmdir --ignore-fail-on-non-empty -p +MAKEDIRS = /usr/bin/mkdir -p +INSTALL = /usr/bin/install -c +INSTALL_PROG = $(INSTALL) -m 0755 +INSTALL_DATA = $(INSTALL) -m 644 +COPY = cp +TOUCH = exit > + +#### End of system configuration section. #### + +preload = +libpath = . $(libdir) +LIBPATH = -L. -L$(libdir) -Wl,-rpath,$(libdir) +DEFFILE = + +CLEANFILES = mkmf.log +DISTCLEANFILES = +DISTCLEANDIRS = + +extout = +extout_prefix = +target_prefix = +LOCAL_LIBS = +LIBS = $(LIBRUBYARG_SHARED) -lyaml -lyaml -lm -lpthread -lc +ORIG_SRCS = psych.c psych_emitter.c psych_parser.c psych_to_ruby.c psych_yaml_tree.c +SRCS = $(ORIG_SRCS) +OBJS = psych.o psych_emitter.o psych_parser.o psych_to_ruby.o psych_yaml_tree.o +HDRS = $(srcdir)/psych.h $(srcdir)/psych_emitter.h $(srcdir)/psych_parser.h $(srcdir)/psych_to_ruby.h $(srcdir)/psych_yaml_tree.h +LOCAL_HDRS = +TARGET = psych +TARGET_NAME = psych +TARGET_ENTRY = Init_$(TARGET_NAME) +DLLIB = $(TARGET).so +EXTSTATIC = +STATIC_LIB = + +TIMESTAMP_DIR = . +BINDIR = $(bindir) +RUBYCOMMONDIR = $(sitedir)$(target_prefix) +RUBYLIBDIR = $(sitelibdir)$(target_prefix) +RUBYARCHDIR = $(sitearchdir)$(target_prefix) +HDRDIR = $(sitehdrdir)$(target_prefix) +ARCHHDRDIR = $(sitearchhdrdir)$(target_prefix) +TARGET_SO_DIR = +TARGET_SO = $(TARGET_SO_DIR)$(DLLIB) +CLEANLIBS = $(TARGET_SO) false +CLEANOBJS = $(OBJS) *.bak +TARGET_SO_DIR_TIMESTAMP = $(TIMESTAMP_DIR)/.sitearchdir.time +LIBYAML = + +LIBYAML_OBJDIR = libyaml/src +OBJEXT = o +RANLIB = gcc-ranlib + +all: $(DLLIB) +static: $(STATIC_LIB) +.PHONY: all install static install-so install-rb +.PHONY: clean clean-so clean-static clean-rb + +clean-static:: +clean-rb-default:: +clean-rb:: +clean-so:: +clean: clean-so clean-static clean-rb-default clean-rb + -$(Q)$(RM_RF) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time + +distclean-rb-default:: +distclean-rb:: +distclean-so:: +distclean-static:: +distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb + -$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + -$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + -$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true + +realclean: distclean +install: install-so install-rb + +install-so: $(DLLIB) $(TARGET_SO_DIR_TIMESTAMP) + $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) +clean-static:: + -$(Q)$(RM) $(STATIC_LIB) +install-rb: pre-install-rb do-install-rb install-rb-default +install-rb-default: pre-install-rb-default do-install-rb-default +pre-install-rb: Makefile +pre-install-rb-default: Makefile +do-install-rb: +do-install-rb-default: +pre-install-rb-default: + @$(NULLCMD) +$(TARGET_SO_DIR_TIMESTAMP): + $(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR) + $(Q) $(TOUCH) $@ + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + +.SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S + +.cc.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cc.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.mm.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.mm.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cxx.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cxx.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cpp.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cpp.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.c.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.c.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.m.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.m.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +$(TARGET_SO): $(OBJS) Makefile + $(ECHO) linking shared-object $(DLLIB) + -$(Q)$(RM) $(@) + $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) + $(Q) $(POSTLINK) + + + +### +$(TARGET_SO): $(LIBYAML) + +libyaml $(LIBYAML): + cd libyaml && $(MAKE) + $(AR) $(ARFLAGS) $(LIBYAML) $(LIBYAML_OBJDIR)/*.$(OBJEXT) + $(RANLIB) $(LIBYAML) + +clean-so:: + -cd libyaml && $(MAKE) clean + +distclean-so:: + -cd libyaml && $(MAKE) distclean + -$(Q)$(RMDIRS) libyaml/* libyaml + +$(OBJS): $(HDRS) $(ruby_headers) \ + $(hdrdir)/ruby/encoding.h \ + $(hdrdir)/ruby/oniguruma.h diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/depend b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/depend new file mode 100644 index 00000000..d0cb1c2e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/depend @@ -0,0 +1,17 @@ +$(TARGET_SO): $(LIBYAML) + +libyaml $(LIBYAML): + cd libyaml && $(MAKE) + $(AR) $(ARFLAGS) $(LIBYAML) $(LIBYAML_OBJDIR)/*.$(OBJEXT) + $(RANLIB) $(LIBYAML) + +clean-so:: + -cd libyaml && $(MAKE) clean + +distclean-so:: + -cd libyaml && $(MAKE) distclean + -$(Q)$(RMDIRS) libyaml/* libyaml + +$(OBJS): $(HDRS) $(ruby_headers) \ + $(hdrdir)/ruby/encoding.h \ + $(hdrdir)/ruby/oniguruma.h diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/extconf.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/extconf.rb new file mode 100644 index 00000000..e7dd0bb6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/extconf.rb @@ -0,0 +1,53 @@ +# -*- coding: us-ascii -*- +# frozen_string_literal: true +require 'mkmf' + +if $mswin or $mingw or $cygwin + $CPPFLAGS << " -DYAML_DECLARE_STATIC" +end + +yaml_source = with_config("libyaml-source-dir") +if yaml_source + yaml_source = yaml_source.gsub(/\$\((\w+)\)|\$\{(\w+)\}/) {ENV[$1||$2]} + yaml_source = yaml_source.chomp("/") + yaml_configure = "#{File.expand_path(yaml_source)}/configure" + unless File.exist?(yaml_configure) + raise "Configure script not found in #{yaml_source.quote}" + end + + puts("Configuring libyaml source in #{yaml_source.quote}") + yaml = "libyaml" + Dir.mkdir(yaml) unless File.directory?(yaml) + shared = $enable_shared || !$static + args = [ + yaml_configure, + "--enable-#{shared ? 'shared' : 'static'}", + "--host=#{RbConfig::CONFIG['host'].sub(/-unknown-/, '-').sub(/arm64/, 'arm')}", + "CC=#{RbConfig::CONFIG['CC']}", + *(["CFLAGS=-w"] if RbConfig::CONFIG["GCC"] == "yes"), + ] + puts(args.quote.join(' ')) + unless system(*args, chdir: yaml) + raise "failed to configure libyaml" + end + inc = yaml_source.start_with?("#$srcdir/") ? "$(srcdir)#{yaml_source[$srcdir.size..-1]}" : yaml_source + $INCFLAGS << " -I#{yaml}/include -I#{inc}/include" + puts("INCFLAGS=#$INCFLAGS") + libyaml = "libyaml.#$LIBEXT" + $cleanfiles << libyaml + $LOCAL_LIBS.prepend("$(LIBYAML) ") +else # default to pre-installed libyaml + pkg_config('yaml-0.1') + dir_config('libyaml') + find_header('yaml.h') or abort "yaml.h not found" + find_library('yaml', 'yaml_get_version') or abort "libyaml not found" +end + +create_makefile 'psych' do |mk| + mk << "LIBYAML = #{libyaml}".strip << "\n" + mk << "LIBYAML_OBJDIR = libyaml/src#{shared ? '/.libs' : ''}\n" + mk << "OBJEXT = #$OBJEXT" + mk << "RANLIB = #{config_string('RANLIB') || config_string('NULLCMD')}\n" +end + +# :startdoc: diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych.c b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych.c new file mode 100644 index 00000000..afbd7a35 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych.c @@ -0,0 +1,36 @@ +#include + +/* call-seq: Psych.libyaml_version + * + * Returns the version of libyaml being used + */ +static VALUE libyaml_version(VALUE module) +{ + int major, minor, patch; + VALUE list[3]; + + yaml_get_version(&major, &minor, &patch); + + list[0] = INT2NUM(major); + list[1] = INT2NUM(minor); + list[2] = INT2NUM(patch); + + return rb_ary_new4((long)3, list); +} + +VALUE mPsych; + +void Init_psych(void) +{ + #ifdef HAVE_RB_EXT_RACTOR_SAFE + RB_EXT_RACTOR_SAFE(true); + #endif + mPsych = rb_define_module("Psych"); + + rb_define_singleton_method(mPsych, "libyaml_version", libyaml_version, 0); + + Init_psych_parser(); + Init_psych_emitter(); + Init_psych_to_ruby(); + Init_psych_yaml_tree(); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych.h b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych.h new file mode 100644 index 00000000..6b3d63f2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych.h @@ -0,0 +1,17 @@ +#ifndef PSYCH_H +#define PSYCH_H + +#include +#include + +#include + +#include +#include +#include +#include + +extern VALUE mPsych; + + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych_emitter.c b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych_emitter.c new file mode 100644 index 00000000..624ab7c5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych_emitter.c @@ -0,0 +1,589 @@ +#include + +#if !defined(RARRAY_CONST_PTR) +#define RARRAY_CONST_PTR(s) (const VALUE *)RARRAY_PTR(s) +#endif +#if !defined(RARRAY_AREF) +#define RARRAY_AREF(a, i) RARRAY_CONST_PTR(a)[i] +#endif + +VALUE cPsychEmitter; +static ID id_io; +static ID id_write; +static ID id_line_width; +static ID id_indentation; +static ID id_canonical; + +static void emit(yaml_emitter_t * emitter, yaml_event_t * event) +{ + if(!yaml_emitter_emit(emitter, event)) + rb_raise(rb_eRuntimeError, "%s", emitter->problem); +} + +static int writer(void *ctx, unsigned char *buffer, size_t size) +{ + VALUE self = (VALUE)ctx, io = rb_attr_get(self, id_io); + VALUE str = rb_enc_str_new((const char *)buffer, (long)size, rb_utf8_encoding()); + VALUE wrote = rb_funcall(io, id_write, 1, str); + return (int)NUM2INT(wrote); +} + +static void dealloc(void * ptr) +{ + yaml_emitter_t * emitter; + + emitter = (yaml_emitter_t *)ptr; + yaml_emitter_delete(emitter); + xfree(emitter); +} + +#if 0 +static size_t memsize(const void *ptr) +{ + const yaml_emitter_t *emitter = ptr; + /* TODO: calculate emitter's size */ + return 0; +} +#endif + +static const rb_data_type_t psych_emitter_type = { + "Psych/emitter", + {0, dealloc, 0,}, + 0, 0, +#ifdef RUBY_TYPED_FREE_IMMEDIATELY + RUBY_TYPED_FREE_IMMEDIATELY, +#endif +}; + +static VALUE allocate(VALUE klass) +{ + yaml_emitter_t * emitter; + VALUE obj = TypedData_Make_Struct(klass, yaml_emitter_t, &psych_emitter_type, emitter); + + yaml_emitter_initialize(emitter); + yaml_emitter_set_unicode(emitter, 1); + yaml_emitter_set_indent(emitter, 2); + + return obj; +} + +/* call-seq: Psych::Emitter.new(io, options = Psych::Emitter::OPTIONS) + * + * Create a new Psych::Emitter that writes to +io+. + */ +static VALUE initialize(int argc, VALUE *argv, VALUE self) +{ + yaml_emitter_t * emitter; + VALUE io, options; + VALUE line_width; + VALUE indent; + VALUE canonical; + + TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter); + + if (rb_scan_args(argc, argv, "11", &io, &options) == 2) { + line_width = rb_funcall(options, id_line_width, 0); + indent = rb_funcall(options, id_indentation, 0); + canonical = rb_funcall(options, id_canonical, 0); + + yaml_emitter_set_width(emitter, NUM2INT(line_width)); + yaml_emitter_set_indent(emitter, NUM2INT(indent)); + yaml_emitter_set_canonical(emitter, Qtrue == canonical ? 1 : 0); + } + + rb_ivar_set(self, id_io, io); + yaml_emitter_set_output(emitter, writer, (void *)self); + + return self; +} + +/* call-seq: emitter.start_stream(encoding) + * + * Start a stream emission with +encoding+ + * + * See Psych::Handler#start_stream + */ +static VALUE start_stream(VALUE self, VALUE encoding) +{ + yaml_emitter_t * emitter; + yaml_event_t event; + TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter); + Check_Type(encoding, T_FIXNUM); + + yaml_stream_start_event_initialize(&event, (yaml_encoding_t)NUM2INT(encoding)); + + emit(emitter, &event); + + return self; +} + +/* call-seq: emitter.end_stream + * + * End a stream emission + * + * See Psych::Handler#end_stream + */ +static VALUE end_stream(VALUE self) +{ + yaml_emitter_t * emitter; + yaml_event_t event; + TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter); + + yaml_stream_end_event_initialize(&event); + + emit(emitter, &event); + + return self; +} + +struct start_document_data { + VALUE self; + VALUE version; + VALUE tags; + VALUE imp; + + yaml_tag_directive_t * head; +}; + +static VALUE start_document_try(VALUE d) +{ + struct start_document_data * data = (struct start_document_data *)d; + VALUE self = data->self; + VALUE version = data->version; + VALUE tags = data->tags; + VALUE imp = data->imp; + + yaml_emitter_t * emitter; + yaml_tag_directive_t * tail = NULL; + yaml_event_t event; + yaml_version_directive_t version_directive; + TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter); + + Check_Type(version, T_ARRAY); + + if(RARRAY_LEN(version) > 0) { + VALUE major = rb_ary_entry(version, (long)0); + VALUE minor = rb_ary_entry(version, (long)1); + + version_directive.major = NUM2INT(major); + version_directive.minor = NUM2INT(minor); + } + + if(RTEST(tags)) { + long i = 0; + long len; + rb_encoding * encoding = rb_utf8_encoding(); + + Check_Type(tags, T_ARRAY); + + len = RARRAY_LEN(tags); + data->head = xcalloc((size_t)len, sizeof(yaml_tag_directive_t)); + tail = data->head; + + for(i = 0; i < len && i < RARRAY_LEN(tags); i++) { + VALUE tuple = RARRAY_AREF(tags, i); + VALUE name; + VALUE value; + + Check_Type(tuple, T_ARRAY); + + if(RARRAY_LEN(tuple) < 2) { + rb_raise(rb_eRuntimeError, "tag tuple must be of length 2"); + } + + name = RARRAY_AREF(tuple, 0); + value = RARRAY_AREF(tuple, 1); + StringValue(name); + StringValue(value); + name = rb_str_export_to_enc(name, encoding); + value = rb_str_export_to_enc(value, encoding); + + tail->handle = (yaml_char_t *)StringValueCStr(name); + tail->prefix = (yaml_char_t *)StringValueCStr(value); + + tail++; + } + } + + yaml_document_start_event_initialize( + &event, + (RARRAY_LEN(version) > 0) ? &version_directive : NULL, + data->head, + tail, + imp ? 1 : 0 + ); + + emit(emitter, &event); + + return self; +} + +static VALUE start_document_ensure(VALUE d) +{ + struct start_document_data * data = (struct start_document_data *)d; + + xfree(data->head); + + return Qnil; +} + +/* call-seq: emitter.start_document(version, tags, implicit) + * + * Start a document emission with YAML +version+, +tags+, and an +implicit+ + * start. + * + * See Psych::Handler#start_document + */ +static VALUE start_document(VALUE self, VALUE version, VALUE tags, VALUE imp) +{ + struct start_document_data data = { + .self = self, + .version = version, + .tags = tags, + .imp = imp, + + .head = NULL, + }; + + return rb_ensure(start_document_try, (VALUE)&data, start_document_ensure, (VALUE)&data); +} + +/* call-seq: emitter.end_document(implicit) + * + * End a document emission with an +implicit+ ending. + * + * See Psych::Handler#end_document + */ +static VALUE end_document(VALUE self, VALUE imp) +{ + yaml_emitter_t * emitter; + yaml_event_t event; + TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter); + + yaml_document_end_event_initialize(&event, imp ? 1 : 0); + + emit(emitter, &event); + + return self; +} + +/* call-seq: emitter.scalar(value, anchor, tag, plain, quoted, style) + * + * Emit a scalar with +value+, +anchor+, +tag+, and a +plain+ or +quoted+ + * string type with +style+. + * + * See Psych::Handler#scalar + */ +static VALUE scalar( + VALUE self, + VALUE value, + VALUE anchor, + VALUE tag, + VALUE plain, + VALUE quoted, + VALUE style + ) { + yaml_emitter_t * emitter; + yaml_event_t event; + rb_encoding *encoding; + TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter); + + Check_Type(value, T_STRING); + + encoding = rb_utf8_encoding(); + + value = rb_str_export_to_enc(value, encoding); + + if(!NIL_P(anchor)) { + Check_Type(anchor, T_STRING); + anchor = rb_str_export_to_enc(anchor, encoding); + } + + if(!NIL_P(tag)) { + Check_Type(tag, T_STRING); + tag = rb_str_export_to_enc(tag, encoding); + } + + const char *value_ptr = StringValuePtr(value); + yaml_scalar_event_initialize( + &event, + (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor)), + (yaml_char_t *)(NIL_P(tag) ? NULL : StringValueCStr(tag)), + (yaml_char_t*)value_ptr, + (int)RSTRING_LEN(value), + plain ? 1 : 0, + quoted ? 1 : 0, + (yaml_scalar_style_t)NUM2INT(style) + ); + + emit(emitter, &event); + + return self; +} + +/* call-seq: emitter.start_sequence(anchor, tag, implicit, style) + * + * Start emitting a sequence with +anchor+, a +tag+, +implicit+ sequence + * start and end, along with +style+. + * + * See Psych::Handler#start_sequence + */ +static VALUE start_sequence( + VALUE self, + VALUE anchor, + VALUE tag, + VALUE implicit, + VALUE style + ) { + yaml_emitter_t * emitter; + yaml_event_t event; + + rb_encoding * encoding = rb_utf8_encoding(); + + if(!NIL_P(anchor)) { + Check_Type(anchor, T_STRING); + anchor = rb_str_export_to_enc(anchor, encoding); + } + + if(!NIL_P(tag)) { + Check_Type(tag, T_STRING); + tag = rb_str_export_to_enc(tag, encoding); + } + + TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter); + + yaml_sequence_start_event_initialize( + &event, + (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor)), + (yaml_char_t *)(NIL_P(tag) ? NULL : StringValueCStr(tag)), + implicit ? 1 : 0, + (yaml_sequence_style_t)NUM2INT(style) + ); + + emit(emitter, &event); + + return self; +} + +/* call-seq: emitter.end_sequence + * + * End sequence emission. + * + * See Psych::Handler#end_sequence + */ +static VALUE end_sequence(VALUE self) +{ + yaml_emitter_t * emitter; + yaml_event_t event; + TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter); + + yaml_sequence_end_event_initialize(&event); + + emit(emitter, &event); + + return self; +} + +/* call-seq: emitter.start_mapping(anchor, tag, implicit, style) + * + * Start emitting a YAML map with +anchor+, +tag+, an +implicit+ start + * and end, and +style+. + * + * See Psych::Handler#start_mapping + */ +static VALUE start_mapping( + VALUE self, + VALUE anchor, + VALUE tag, + VALUE implicit, + VALUE style + ) { + yaml_emitter_t * emitter; + yaml_event_t event; + rb_encoding *encoding; + + TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter); + + encoding = rb_utf8_encoding(); + + if(!NIL_P(anchor)) { + Check_Type(anchor, T_STRING); + anchor = rb_str_export_to_enc(anchor, encoding); + } + + if(!NIL_P(tag)) { + Check_Type(tag, T_STRING); + tag = rb_str_export_to_enc(tag, encoding); + } + + yaml_mapping_start_event_initialize( + &event, + (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor)), + (yaml_char_t *)(NIL_P(tag) ? NULL : StringValueCStr(tag)), + implicit ? 1 : 0, + (yaml_mapping_style_t)NUM2INT(style) + ); + + emit(emitter, &event); + + return self; +} + +/* call-seq: emitter.end_mapping + * + * Emit the end of a mapping. + * + * See Psych::Handler#end_mapping + */ +static VALUE end_mapping(VALUE self) +{ + yaml_emitter_t * emitter; + yaml_event_t event; + TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter); + + yaml_mapping_end_event_initialize(&event); + + emit(emitter, &event); + + return self; +} + +/* call-seq: emitter.alias(anchor) + * + * Emit an alias with +anchor+. + * + * See Psych::Handler#alias + */ +static VALUE alias(VALUE self, VALUE anchor) +{ + yaml_emitter_t * emitter; + yaml_event_t event; + TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter); + + if(!NIL_P(anchor)) { + Check_Type(anchor, T_STRING); + anchor = rb_str_export_to_enc(anchor, rb_utf8_encoding()); + } + + yaml_alias_event_initialize( + &event, + (yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor)) + ); + + emit(emitter, &event); + + return self; +} + +/* call-seq: emitter.canonical = true + * + * Set the output style to canonical, or not. + */ +static VALUE set_canonical(VALUE self, VALUE style) +{ + yaml_emitter_t * emitter; + TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter); + + yaml_emitter_set_canonical(emitter, Qtrue == style ? 1 : 0); + + return style; +} + +/* call-seq: emitter.canonical + * + * Get the output style, canonical or not. + */ +static VALUE canonical(VALUE self) +{ + yaml_emitter_t * emitter; + TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter); + + return (emitter->canonical == 0) ? Qfalse : Qtrue; +} + +/* call-seq: emitter.indentation = level + * + * Set the indentation level to +level+. The level must be less than 10 and + * greater than 1. + */ +static VALUE set_indentation(VALUE self, VALUE level) +{ + yaml_emitter_t * emitter; + TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter); + + yaml_emitter_set_indent(emitter, NUM2INT(level)); + + return level; +} + +/* call-seq: emitter.indentation + * + * Get the indentation level. + */ +static VALUE indentation(VALUE self) +{ + yaml_emitter_t * emitter; + TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter); + + return INT2NUM(emitter->best_indent); +} + +/* call-seq: emitter.line_width + * + * Get the preferred line width. + */ +static VALUE line_width(VALUE self) +{ + yaml_emitter_t * emitter; + TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter); + + return INT2NUM(emitter->best_width); +} + +/* call-seq: emitter.line_width = width + * + * Set the preferred line with to +width+. + */ +static VALUE set_line_width(VALUE self, VALUE width) +{ + yaml_emitter_t * emitter; + TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter); + + yaml_emitter_set_width(emitter, NUM2INT(width)); + + return width; +} + +void Init_psych_emitter(void) +{ +#undef rb_intern + VALUE psych = rb_define_module("Psych"); + VALUE handler = rb_define_class_under(psych, "Handler", rb_cObject); + cPsychEmitter = rb_define_class_under(psych, "Emitter", handler); + + rb_define_alloc_func(cPsychEmitter, allocate); + + rb_define_method(cPsychEmitter, "initialize", initialize, -1); + rb_define_method(cPsychEmitter, "start_stream", start_stream, 1); + rb_define_method(cPsychEmitter, "end_stream", end_stream, 0); + rb_define_method(cPsychEmitter, "start_document", start_document, 3); + rb_define_method(cPsychEmitter, "end_document", end_document, 1); + rb_define_method(cPsychEmitter, "scalar", scalar, 6); + rb_define_method(cPsychEmitter, "start_sequence", start_sequence, 4); + rb_define_method(cPsychEmitter, "end_sequence", end_sequence, 0); + rb_define_method(cPsychEmitter, "start_mapping", start_mapping, 4); + rb_define_method(cPsychEmitter, "end_mapping", end_mapping, 0); + rb_define_method(cPsychEmitter, "alias", alias, 1); + rb_define_method(cPsychEmitter, "canonical", canonical, 0); + rb_define_method(cPsychEmitter, "canonical=", set_canonical, 1); + rb_define_method(cPsychEmitter, "indentation", indentation, 0); + rb_define_method(cPsychEmitter, "indentation=", set_indentation, 1); + rb_define_method(cPsychEmitter, "line_width", line_width, 0); + rb_define_method(cPsychEmitter, "line_width=", set_line_width, 1); + + id_io = rb_intern("io"); + id_write = rb_intern("write"); + id_line_width = rb_intern("line_width"); + id_indentation = rb_intern("indentation"); + id_canonical = rb_intern("canonical"); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych_emitter.h b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych_emitter.h new file mode 100644 index 00000000..4c1482a7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych_emitter.h @@ -0,0 +1,8 @@ +#ifndef PSYCH_EMITTER_H +#define PSYCH_EMITTER_H + +#include + +void Init_psych_emitter(void); + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych_parser.c b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych_parser.c new file mode 100644 index 00000000..d9734962 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych_parser.c @@ -0,0 +1,564 @@ +#include + +VALUE cPsychParser; + +static ID id_read; +static ID id_path; +static ID id_empty; +static ID id_start_stream; +static ID id_end_stream; +static ID id_start_document; +static ID id_end_document; +static ID id_alias; +static ID id_scalar; +static ID id_start_sequence; +static ID id_end_sequence; +static ID id_start_mapping; +static ID id_end_mapping; +static ID id_event_location; + +#define PSYCH_TRANSCODE(_str, _yaml_enc, _internal_enc) \ + do { \ + rb_enc_associate_index((_str), (_yaml_enc)); \ + if(_internal_enc) \ + (_str) = rb_str_export_to_enc((_str), (_internal_enc)); \ + } while (0) + +static int io_reader(void * data, unsigned char *buf, size_t size, size_t *read) +{ + VALUE io = (VALUE)data; + VALUE string = rb_funcall(io, id_read, 1, SIZET2NUM(size)); + + *read = 0; + + if(! NIL_P(string)) { + void * str = (void *)StringValuePtr(string); + *read = (size_t)RSTRING_LEN(string); + memcpy(buf, str, *read); + } + + return 1; +} + +static void dealloc(void * ptr) +{ + yaml_parser_t * parser; + + parser = (yaml_parser_t *)ptr; + yaml_parser_delete(parser); + xfree(parser); +} + +#if 0 +static size_t memsize(const void *ptr) +{ + const yaml_parser_t *parser = ptr; + /* TODO: calculate parser's size */ + return 0; +} +#endif + +static const rb_data_type_t psych_parser_type = { + "Psych/parser", + {0, dealloc, 0,}, + 0, 0, +#ifdef RUBY_TYPED_FREE_IMMEDIATELY + RUBY_TYPED_FREE_IMMEDIATELY, +#endif +}; + +static VALUE allocate(VALUE klass) +{ + yaml_parser_t * parser; + VALUE obj = TypedData_Make_Struct(klass, yaml_parser_t, &psych_parser_type, parser); + + yaml_parser_initialize(parser); + + return obj; +} + +static VALUE make_exception(yaml_parser_t * parser, VALUE path) +{ + if (parser->error == YAML_MEMORY_ERROR) { + return rb_eNoMemError; + } else { + size_t line, column; + VALUE ePsychSyntaxError; + + line = parser->context_mark.line + 1; + column = parser->context_mark.column + 1; + + ePsychSyntaxError = rb_const_get(mPsych, rb_intern("SyntaxError")); + + return rb_funcall(ePsychSyntaxError, rb_intern("new"), 6, + path, + SIZET2NUM(line), + SIZET2NUM(column), + SIZET2NUM(parser->problem_offset), + parser->problem ? rb_usascii_str_new2(parser->problem) : Qnil, + parser->context ? rb_usascii_str_new2(parser->context) : Qnil); + } +} + +static VALUE transcode_string(VALUE src, int * parser_encoding) +{ + int utf8 = rb_utf8_encindex(); + int utf16le = rb_enc_find_index("UTF-16LE"); + int utf16be = rb_enc_find_index("UTF-16BE"); + int source_encoding = rb_enc_get_index(src); + + if (source_encoding == utf8) { + *parser_encoding = YAML_UTF8_ENCODING; + return src; + } + + if (source_encoding == utf16le) { + *parser_encoding = YAML_UTF16LE_ENCODING; + return src; + } + + if (source_encoding == utf16be) { + *parser_encoding = YAML_UTF16BE_ENCODING; + return src; + } + + src = rb_str_export_to_enc(src, rb_utf8_encoding()); + RB_GC_GUARD(src); + + *parser_encoding = YAML_UTF8_ENCODING; + return src; +} + +static VALUE transcode_io(VALUE src, int * parser_encoding) +{ + VALUE io_external_encoding; + int io_external_enc_index; + + io_external_encoding = rb_funcall(src, rb_intern("external_encoding"), 0); + + /* if no encoding is returned, assume ascii8bit. */ + if (NIL_P(io_external_encoding)) { + io_external_enc_index = rb_ascii8bit_encindex(); + } else { + io_external_enc_index = rb_to_encoding_index(io_external_encoding); + } + + /* Treat US-ASCII as utf_8 */ + if (io_external_enc_index == rb_usascii_encindex()) { + *parser_encoding = YAML_UTF8_ENCODING; + return src; + } + + if (io_external_enc_index == rb_utf8_encindex()) { + *parser_encoding = YAML_UTF8_ENCODING; + return src; + } + + if (io_external_enc_index == rb_enc_find_index("UTF-16LE")) { + *parser_encoding = YAML_UTF16LE_ENCODING; + return src; + } + + if (io_external_enc_index == rb_enc_find_index("UTF-16BE")) { + *parser_encoding = YAML_UTF16BE_ENCODING; + return src; + } + + /* Just guess on ASCII-8BIT */ + if (io_external_enc_index == rb_ascii8bit_encindex()) { + *parser_encoding = YAML_ANY_ENCODING; + return src; + } + + /* If the external encoding is something we don't know how to handle, + * fall back to YAML_ANY_ENCODING. */ + *parser_encoding = YAML_ANY_ENCODING; + + return src; +} + +static VALUE protected_start_stream(VALUE pointer) +{ + VALUE *args = (VALUE *)pointer; + return rb_funcall(args[0], id_start_stream, 1, args[1]); +} + +static VALUE protected_start_document(VALUE pointer) +{ + VALUE *args = (VALUE *)pointer; + return rb_funcall3(args[0], id_start_document, 3, args + 1); +} + +static VALUE protected_end_document(VALUE pointer) +{ + VALUE *args = (VALUE *)pointer; + return rb_funcall(args[0], id_end_document, 1, args[1]); +} + +static VALUE protected_alias(VALUE pointer) +{ + VALUE *args = (VALUE *)pointer; + return rb_funcall(args[0], id_alias, 1, args[1]); +} + +static VALUE protected_scalar(VALUE pointer) +{ + VALUE *args = (VALUE *)pointer; + return rb_funcall3(args[0], id_scalar, 6, args + 1); +} + +static VALUE protected_start_sequence(VALUE pointer) +{ + VALUE *args = (VALUE *)pointer; + return rb_funcall3(args[0], id_start_sequence, 4, args + 1); +} + +static VALUE protected_end_sequence(VALUE handler) +{ + return rb_funcall(handler, id_end_sequence, 0); +} + +static VALUE protected_start_mapping(VALUE pointer) +{ + VALUE *args = (VALUE *)pointer; + return rb_funcall3(args[0], id_start_mapping, 4, args + 1); +} + +static VALUE protected_end_mapping(VALUE handler) +{ + return rb_funcall(handler, id_end_mapping, 0); +} + +static VALUE protected_empty(VALUE handler) +{ + return rb_funcall(handler, id_empty, 0); +} + +static VALUE protected_end_stream(VALUE handler) +{ + return rb_funcall(handler, id_end_stream, 0); +} + +static VALUE protected_event_location(VALUE pointer) +{ + VALUE *args = (VALUE *)pointer; + return rb_funcall3(args[0], id_event_location, 4, args + 1); +} + +static VALUE parse(VALUE self, VALUE handler, VALUE yaml, VALUE path) +{ + yaml_parser_t * parser; + yaml_event_t event; + int done = 0; + int state = 0; + int parser_encoding = YAML_ANY_ENCODING; + int encoding = rb_utf8_encindex(); + rb_encoding * internal_enc = rb_default_internal_encoding(); + + TypedData_Get_Struct(self, yaml_parser_t, &psych_parser_type, parser); + + yaml_parser_delete(parser); + yaml_parser_initialize(parser); + + if (rb_respond_to(yaml, id_read)) { + yaml = transcode_io(yaml, &parser_encoding); + yaml_parser_set_encoding(parser, parser_encoding); + yaml_parser_set_input(parser, io_reader, (void *)yaml); + } else { + StringValue(yaml); + yaml = transcode_string(yaml, &parser_encoding); + yaml_parser_set_encoding(parser, parser_encoding); + yaml_parser_set_input_string( + parser, + (const unsigned char *)RSTRING_PTR(yaml), + (size_t)RSTRING_LEN(yaml) + ); + } + + while(!done) { + VALUE event_args[5]; + VALUE start_line, start_column, end_line, end_column; + + if(parser->error || !yaml_parser_parse(parser, &event)) { + VALUE exception; + + exception = make_exception(parser, path); + yaml_parser_delete(parser); + yaml_parser_initialize(parser); + + rb_exc_raise(exception); + } + + start_line = SIZET2NUM(event.start_mark.line); + start_column = SIZET2NUM(event.start_mark.column); + end_line = SIZET2NUM(event.end_mark.line); + end_column = SIZET2NUM(event.end_mark.column); + + event_args[0] = handler; + event_args[1] = start_line; + event_args[2] = start_column; + event_args[3] = end_line; + event_args[4] = end_column; + rb_protect(protected_event_location, (VALUE)event_args, &state); + + switch(event.type) { + case YAML_STREAM_START_EVENT: + { + VALUE args[2]; + + args[0] = handler; + args[1] = INT2NUM(event.data.stream_start.encoding); + rb_protect(protected_start_stream, (VALUE)args, &state); + } + break; + case YAML_DOCUMENT_START_EVENT: + { + VALUE args[4]; + /* Get a list of tag directives (if any) */ + VALUE tag_directives = rb_ary_new(); + /* Grab the document version */ + VALUE version = event.data.document_start.version_directive ? + rb_ary_new3( + (long)2, + INT2NUM(event.data.document_start.version_directive->major), + INT2NUM(event.data.document_start.version_directive->minor) + ) : rb_ary_new(); + + if(event.data.document_start.tag_directives.start) { + yaml_tag_directive_t *start = + event.data.document_start.tag_directives.start; + yaml_tag_directive_t *end = + event.data.document_start.tag_directives.end; + for(; start != end; start++) { + VALUE handle = Qnil; + VALUE prefix = Qnil; + if(start->handle) { + handle = rb_str_new2((const char *)start->handle); + PSYCH_TRANSCODE(handle, encoding, internal_enc); + } + + if(start->prefix) { + prefix = rb_str_new2((const char *)start->prefix); + PSYCH_TRANSCODE(prefix, encoding, internal_enc); + } + + rb_ary_push(tag_directives, rb_ary_new3((long)2, handle, prefix)); + } + } + args[0] = handler; + args[1] = version; + args[2] = tag_directives; + args[3] = event.data.document_start.implicit == 1 ? Qtrue : Qfalse; + rb_protect(protected_start_document, (VALUE)args, &state); + } + break; + case YAML_DOCUMENT_END_EVENT: + { + VALUE args[2]; + + args[0] = handler; + args[1] = event.data.document_end.implicit == 1 ? Qtrue : Qfalse; + rb_protect(protected_end_document, (VALUE)args, &state); + } + break; + case YAML_ALIAS_EVENT: + { + VALUE args[2]; + VALUE alias = Qnil; + if(event.data.alias.anchor) { + alias = rb_str_new2((const char *)event.data.alias.anchor); + PSYCH_TRANSCODE(alias, encoding, internal_enc); + } + + args[0] = handler; + args[1] = alias; + rb_protect(protected_alias, (VALUE)args, &state); + } + break; + case YAML_SCALAR_EVENT: + { + VALUE args[7]; + VALUE anchor = Qnil; + VALUE tag = Qnil; + VALUE plain_implicit, quoted_implicit, style; + VALUE val = rb_str_new( + (const char *)event.data.scalar.value, + (long)event.data.scalar.length + ); + + PSYCH_TRANSCODE(val, encoding, internal_enc); + + if(event.data.scalar.anchor) { + anchor = rb_str_new2((const char *)event.data.scalar.anchor); + PSYCH_TRANSCODE(anchor, encoding, internal_enc); + } + + if(event.data.scalar.tag) { + tag = rb_str_new2((const char *)event.data.scalar.tag); + PSYCH_TRANSCODE(tag, encoding, internal_enc); + } + + plain_implicit = + event.data.scalar.plain_implicit == 0 ? Qfalse : Qtrue; + + quoted_implicit = + event.data.scalar.quoted_implicit == 0 ? Qfalse : Qtrue; + + style = INT2NUM(event.data.scalar.style); + + args[0] = handler; + args[1] = val; + args[2] = anchor; + args[3] = tag; + args[4] = plain_implicit; + args[5] = quoted_implicit; + args[6] = style; + rb_protect(protected_scalar, (VALUE)args, &state); + } + break; + case YAML_SEQUENCE_START_EVENT: + { + VALUE args[5]; + VALUE anchor = Qnil; + VALUE tag = Qnil; + VALUE implicit, style; + if(event.data.sequence_start.anchor) { + anchor = rb_str_new2((const char *)event.data.sequence_start.anchor); + PSYCH_TRANSCODE(anchor, encoding, internal_enc); + } + + tag = Qnil; + if(event.data.sequence_start.tag) { + tag = rb_str_new2((const char *)event.data.sequence_start.tag); + PSYCH_TRANSCODE(tag, encoding, internal_enc); + } + + implicit = + event.data.sequence_start.implicit == 0 ? Qfalse : Qtrue; + + style = INT2NUM(event.data.sequence_start.style); + + args[0] = handler; + args[1] = anchor; + args[2] = tag; + args[3] = implicit; + args[4] = style; + + rb_protect(protected_start_sequence, (VALUE)args, &state); + } + break; + case YAML_SEQUENCE_END_EVENT: + rb_protect(protected_end_sequence, handler, &state); + break; + case YAML_MAPPING_START_EVENT: + { + VALUE args[5]; + VALUE anchor = Qnil; + VALUE tag = Qnil; + VALUE implicit, style; + if(event.data.mapping_start.anchor) { + anchor = rb_str_new2((const char *)event.data.mapping_start.anchor); + PSYCH_TRANSCODE(anchor, encoding, internal_enc); + } + + if(event.data.mapping_start.tag) { + tag = rb_str_new2((const char *)event.data.mapping_start.tag); + PSYCH_TRANSCODE(tag, encoding, internal_enc); + } + + implicit = + event.data.mapping_start.implicit == 0 ? Qfalse : Qtrue; + + style = INT2NUM(event.data.mapping_start.style); + + args[0] = handler; + args[1] = anchor; + args[2] = tag; + args[3] = implicit; + args[4] = style; + + rb_protect(protected_start_mapping, (VALUE)args, &state); + } + break; + case YAML_MAPPING_END_EVENT: + rb_protect(protected_end_mapping, handler, &state); + break; + case YAML_NO_EVENT: + rb_protect(protected_empty, handler, &state); + break; + case YAML_STREAM_END_EVENT: + rb_protect(protected_end_stream, handler, &state); + done = 1; + break; + } + yaml_event_delete(&event); + if (state) rb_jump_tag(state); + } + + return self; +} + +/* + * call-seq: + * parser.mark # => # + * + * Returns a Psych::Parser::Mark object that contains line, column, and index + * information. + */ +static VALUE mark(VALUE self) +{ + VALUE mark_klass; + VALUE args[3]; + yaml_parser_t * parser; + + TypedData_Get_Struct(self, yaml_parser_t, &psych_parser_type, parser); + mark_klass = rb_const_get_at(cPsychParser, rb_intern("Mark")); + args[0] = SIZET2NUM(parser->mark.index); + args[1] = SIZET2NUM(parser->mark.line); + args[2] = SIZET2NUM(parser->mark.column); + + return rb_class_new_instance(3, args, mark_klass); +} + +void Init_psych_parser(void) +{ +#undef rb_intern +#if 0 + mPsych = rb_define_module("Psych"); +#endif + + cPsychParser = rb_define_class_under(mPsych, "Parser", rb_cObject); + rb_define_alloc_func(cPsychParser, allocate); + + /* Any encoding: Let the parser choose the encoding */ + rb_define_const(cPsychParser, "ANY", INT2NUM(YAML_ANY_ENCODING)); + + /* UTF-8 Encoding */ + rb_define_const(cPsychParser, "UTF8", INT2NUM(YAML_UTF8_ENCODING)); + + /* UTF-16-LE Encoding with BOM */ + rb_define_const(cPsychParser, "UTF16LE", INT2NUM(YAML_UTF16LE_ENCODING)); + + /* UTF-16-BE Encoding with BOM */ + rb_define_const(cPsychParser, "UTF16BE", INT2NUM(YAML_UTF16BE_ENCODING)); + + rb_require("psych/syntax_error"); + + rb_define_private_method(cPsychParser, "_native_parse", parse, 3); + rb_define_method(cPsychParser, "mark", mark, 0); + + id_read = rb_intern("read"); + id_path = rb_intern("path"); + id_empty = rb_intern("empty"); + id_start_stream = rb_intern("start_stream"); + id_end_stream = rb_intern("end_stream"); + id_start_document = rb_intern("start_document"); + id_end_document = rb_intern("end_document"); + id_alias = rb_intern("alias"); + id_scalar = rb_intern("scalar"); + id_start_sequence = rb_intern("start_sequence"); + id_end_sequence = rb_intern("end_sequence"); + id_start_mapping = rb_intern("start_mapping"); + id_end_mapping = rb_intern("end_mapping"); + id_event_location = rb_intern("event_location"); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych_parser.h b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych_parser.h new file mode 100644 index 00000000..beb3dd07 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych_parser.h @@ -0,0 +1,6 @@ +#ifndef PSYCH_PARSER_H +#define PSYCH_PARSER_H + +void Init_psych_parser(void); + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych_to_ruby.c b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych_to_ruby.c new file mode 100644 index 00000000..d473a5f8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych_to_ruby.c @@ -0,0 +1,48 @@ +#include + +VALUE cPsychVisitorsToRuby; + +/* call-seq: vis.build_exception(klass, message) + * + * Create an exception with class +klass+ and +message+ + */ +static VALUE build_exception(VALUE self, VALUE klass, VALUE mesg) +{ + VALUE e = rb_obj_alloc(klass); + + rb_iv_set(e, "mesg", mesg); + + return e; +} + +/* call-seq: vis.path2class(path) + * + * Convert +path+ string to a class + */ +static VALUE path2class(VALUE self, VALUE path) +{ + return rb_path_to_class(path); +} + +static VALUE init_struct(VALUE self, VALUE data, VALUE attrs) +{ + VALUE args = rb_ary_new2(1); + rb_ary_push(args, attrs); + rb_struct_initialize(data, args); + + return data; +} + +void Init_psych_to_ruby(void) +{ + VALUE psych = rb_define_module("Psych"); + VALUE class_loader = rb_define_class_under(psych, "ClassLoader", rb_cObject); + + VALUE visitors = rb_define_module_under(psych, "Visitors"); + VALUE visitor = rb_define_class_under(visitors, "Visitor", rb_cObject); + cPsychVisitorsToRuby = rb_define_class_under(visitors, "ToRuby", visitor); + + rb_define_private_method(cPsychVisitorsToRuby, "init_struct", init_struct, 2); + rb_define_private_method(cPsychVisitorsToRuby, "build_exception", build_exception, 2); + rb_define_private_method(class_loader, "path2class", path2class, 1); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych_to_ruby.h b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych_to_ruby.h new file mode 100644 index 00000000..7b8e757a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych_to_ruby.h @@ -0,0 +1,8 @@ +#ifndef PSYCH_TO_RUBY_H +#define PSYCH_TO_RUBY_H + +#include + +void Init_psych_to_ruby(void); + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych_yaml_tree.c b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych_yaml_tree.c new file mode 100644 index 00000000..bbd93f87 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych_yaml_tree.c @@ -0,0 +1,11 @@ +#include + +VALUE cPsychVisitorsYamlTree; + +void Init_psych_yaml_tree(void) +{ + VALUE psych = rb_define_module("Psych"); + VALUE visitors = rb_define_module_under(psych, "Visitors"); + VALUE visitor = rb_define_class_under(visitors, "Visitor", rb_cObject); + cPsychVisitorsYamlTree = rb_define_class_under(visitors, "YAMLTree", visitor); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych_yaml_tree.h b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych_yaml_tree.h new file mode 100644 index 00000000..4628a69d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/ext/psych/psych_yaml_tree.h @@ -0,0 +1,8 @@ +#ifndef PSYCH_YAML_TREE_H +#define PSYCH_YAML_TREE_H + +#include + +void Init_psych_yaml_tree(void); + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych.rb new file mode 100644 index 00000000..0c158c9f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych.rb @@ -0,0 +1,793 @@ +# frozen_string_literal: true +require 'date' + +require_relative 'psych/versions' +case RUBY_ENGINE +when 'jruby' + require_relative 'psych_jars' + if JRuby::Util.respond_to?(:load_ext) + JRuby::Util.load_ext('org.jruby.ext.psych.PsychLibrary') + else + require 'java'; require 'jruby' + org.jruby.ext.psych.PsychLibrary.new.load(JRuby.runtime, false) + end +else + require 'psych.so' +end +require_relative 'psych/nodes' +require_relative 'psych/streaming' +require_relative 'psych/visitors' +require_relative 'psych/handler' +require_relative 'psych/tree_builder' +require_relative 'psych/parser' +require_relative 'psych/omap' +require_relative 'psych/set' +require_relative 'psych/coder' +require_relative 'psych/stream' +require_relative 'psych/json/tree_builder' +require_relative 'psych/json/stream' +require_relative 'psych/handlers/document_stream' +require_relative 'psych/class_loader' + +### +# = Overview +# +# Psych is a YAML parser and emitter. +# Psych leverages libyaml [Home page: https://pyyaml.org/wiki/LibYAML] +# or [git repo: https://github.com/yaml/libyaml] for its YAML parsing +# and emitting capabilities. In addition to wrapping libyaml, Psych also +# knows how to serialize and de-serialize most Ruby objects to and from +# the YAML format. +# +# = I NEED TO PARSE OR EMIT YAML RIGHT NOW! +# +# # Parse some YAML +# Psych.load("--- foo") # => "foo" +# +# # Emit some YAML +# Psych.dump("foo") # => "--- foo\n...\n" +# { :a => 'b'}.to_yaml # => "---\n:a: b\n" +# +# Got more time on your hands? Keep on reading! +# +# == YAML Parsing +# +# Psych provides a range of interfaces for parsing a YAML document ranging from +# low level to high level, depending on your parsing needs. At the lowest +# level, is an event based parser. Mid level is access to the raw YAML AST, +# and at the highest level is the ability to unmarshal YAML to Ruby objects. +# +# == YAML Emitting +# +# Psych provides a range of interfaces ranging from low to high level for +# producing YAML documents. Very similar to the YAML parsing interfaces, Psych +# provides at the lowest level, an event based system, mid-level is building +# a YAML AST, and the highest level is converting a Ruby object straight to +# a YAML document. +# +# == High-level API +# +# === Parsing +# +# The high level YAML parser provided by Psych simply takes YAML as input and +# returns a Ruby data structure. For information on using the high level parser +# see Psych.load +# +# ==== Reading from a string +# +# Psych.safe_load("--- a") # => 'a' +# Psych.safe_load("---\n - a\n - b") # => ['a', 'b'] +# # From a trusted string: +# Psych.load("--- !ruby/range\nbegin: 0\nend: 42\nexcl: false\n") # => 0..42 +# +# ==== Reading from a file +# +# Psych.safe_load_file("data.yml", permitted_classes: [Date]) +# Psych.load_file("trusted_database.yml") +# +# ==== \Exception handling +# +# begin +# # The second argument changes only the exception contents +# Psych.parse("--- `", "file.txt") +# rescue Psych::SyntaxError => ex +# ex.file # => 'file.txt' +# ex.message # => "(file.txt): found character that cannot start any token" +# end +# +# === Emitting +# +# The high level emitter has the easiest interface. Psych simply takes a Ruby +# data structure and converts it to a YAML document. See Psych.dump for more +# information on dumping a Ruby data structure. +# +# ==== Writing to a string +# +# # Dump an array, get back a YAML string +# Psych.dump(['a', 'b']) # => "---\n- a\n- b\n" +# +# # Dump an array to an IO object +# Psych.dump(['a', 'b'], StringIO.new) # => # +# +# # Dump an array with indentation set +# Psych.dump(['a', ['b']], :indentation => 3) # => "---\n- a\n- - b\n" +# +# # Dump an array to an IO with indentation set +# Psych.dump(['a', ['b']], StringIO.new, :indentation => 3) +# +# ==== Writing to a file +# +# Currently there is no direct API for dumping Ruby structure to file: +# +# File.open('database.yml', 'w') do |file| +# file.write(Psych.dump(['a', 'b'])) +# end +# +# == Mid-level API +# +# === Parsing +# +# Psych provides access to an AST produced from parsing a YAML document. This +# tree is built using the Psych::Parser and Psych::TreeBuilder. The AST can +# be examined and manipulated freely. Please see Psych::parse_stream, +# Psych::Nodes, and Psych::Nodes::Node for more information on dealing with +# YAML syntax trees. +# +# ==== Reading from a string +# +# # Returns Psych::Nodes::Stream +# Psych.parse_stream("---\n - a\n - b") +# +# # Returns Psych::Nodes::Document +# Psych.parse("---\n - a\n - b") +# +# ==== Reading from a file +# +# # Returns Psych::Nodes::Stream +# Psych.parse_stream(File.read('database.yml')) +# +# # Returns Psych::Nodes::Document +# Psych.parse_file('database.yml') +# +# ==== \Exception handling +# +# begin +# # The second argument changes only the exception contents +# Psych.parse("--- `", "file.txt") +# rescue Psych::SyntaxError => ex +# ex.file # => 'file.txt' +# ex.message # => "(file.txt): found character that cannot start any token" +# end +# +# === Emitting +# +# At the mid level is building an AST. This AST is exactly the same as the AST +# used when parsing a YAML document. Users can build an AST by hand and the +# AST knows how to emit itself as a YAML document. See Psych::Nodes, +# Psych::Nodes::Node, and Psych::TreeBuilder for more information on building +# a YAML AST. +# +# ==== Writing to a string +# +# # We need Psych::Nodes::Stream (not Psych::Nodes::Document) +# stream = Psych.parse_stream("---\n - a\n - b") +# +# stream.to_yaml # => "---\n- a\n- b\n" +# +# ==== Writing to a file +# +# # We need Psych::Nodes::Stream (not Psych::Nodes::Document) +# stream = Psych.parse_stream(File.read('database.yml')) +# +# File.open('database.yml', 'w') do |file| +# file.write(stream.to_yaml) +# end +# +# == Low-level API +# +# === Parsing +# +# The lowest level parser should be used when the YAML input is already known, +# and the developer does not want to pay the price of building an AST or +# automatic detection and conversion to Ruby objects. See Psych::Parser for +# more information on using the event based parser. +# +# ==== Reading to Psych::Nodes::Stream structure +# +# parser = Psych::Parser.new(TreeBuilder.new) # => # +# parser = Psych.parser # it's an alias for the above +# +# parser.parse("---\n - a\n - b") # => # +# parser.handler # => # +# parser.handler.root # => # +# +# ==== Receiving an events stream +# +# recorder = Psych::Handlers::Recorder.new +# parser = Psych::Parser.new(recorder) +# +# parser.parse("---\n - a\n - b") +# recorder.events # => [list of [event, args] lists] +# # event is one of: Psych::Handler::EVENTS +# # args are the arguments passed to the event +# +# === Emitting +# +# The lowest level emitter is an event based system. Events are sent to a +# Psych::Emitter object. That object knows how to convert the events to a YAML +# document. This interface should be used when document format is known in +# advance or speed is a concern. See Psych::Emitter for more information. +# +# ==== Writing to a Ruby structure +# +# Psych.parser.parse("--- a") # => # +# +# parser.handler.first # => # +# parser.handler.first.to_ruby # => ["a"] +# +# parser.handler.root.first # => # +# parser.handler.root.first.to_ruby # => "a" +# +# # You can instantiate an Emitter manually +# Psych::Visitors::ToRuby.new.accept(parser.handler.root.first) +# # => "a" + +module Psych + # The version of libyaml Psych is using + LIBYAML_VERSION = Psych.libyaml_version.join('.').freeze + + ### + # Load +yaml+ in to a Ruby data structure. If multiple documents are + # provided, the object contained in the first document will be returned. + # +filename+ will be used in the exception message if any exception + # is raised while parsing. If +yaml+ is empty, it returns + # the specified +fallback+ return value, which defaults to +false+. + # + # Raises a Psych::SyntaxError when a YAML syntax error is detected. + # + # Example: + # + # Psych.unsafe_load("--- a") # => 'a' + # Psych.unsafe_load("---\n - a\n - b") # => ['a', 'b'] + # + # begin + # Psych.unsafe_load("--- `", filename: "file.txt") + # rescue Psych::SyntaxError => ex + # ex.file # => 'file.txt' + # ex.message # => "(file.txt): found character that cannot start any token" + # end + # + # When the optional +symbolize_names+ keyword argument is set to a + # true value, returns symbols for keys in Hash objects (default: strings). + # + # Psych.unsafe_load("---\n foo: bar") # => {"foo"=>"bar"} + # Psych.unsafe_load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"} + # + # Raises a TypeError when `yaml` parameter is NilClass + # + # NOTE: This method *should not* be used to parse untrusted documents, such as + # YAML documents that are supplied via user input. Instead, please use the + # load method or the safe_load method. + # + def self.unsafe_load yaml, filename: nil, fallback: false, symbolize_names: false, freeze: false, strict_integer: false + result = parse(yaml, filename: filename) + return fallback unless result + result.to_ruby(symbolize_names: symbolize_names, freeze: freeze, strict_integer: strict_integer) + end + + ### + # Safely load the yaml string in +yaml+. By default, only the following + # classes are allowed to be deserialized: + # + # * TrueClass + # * FalseClass + # * NilClass + # * Integer + # * Float + # * String + # * Array + # * Hash + # + # Recursive data structures are not allowed by default. Arbitrary classes + # can be allowed by adding those classes to the +permitted_classes+ keyword argument. They are + # additive. For example, to allow Date deserialization: + # + # Psych.safe_load(yaml, permitted_classes: [Date]) + # + # Now the Date class can be loaded in addition to the classes listed above. + # + # Aliases can be explicitly allowed by changing the +aliases+ keyword argument. + # For example: + # + # x = [] + # x << x + # yaml = Psych.dump x + # Psych.safe_load yaml # => raises an exception + # Psych.safe_load yaml, aliases: true # => loads the aliases + # + # A Psych::DisallowedClass exception will be raised if the yaml contains a + # class that isn't in the +permitted_classes+ list. + # + # A Psych::AliasesNotEnabled exception will be raised if the yaml contains aliases + # but the +aliases+ keyword argument is set to false. + # + # +filename+ will be used in the exception message if any exception is raised + # while parsing. + # + # When the optional +symbolize_names+ keyword argument is set to a + # true value, returns symbols for keys in Hash objects (default: strings). + # + # Psych.safe_load("---\n foo: bar") # => {"foo"=>"bar"} + # Psych.safe_load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"} + # + def self.safe_load yaml, permitted_classes: [], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false, strict_integer: false + result = parse(yaml, filename: filename) + return fallback unless result + + class_loader = ClassLoader::Restricted.new(permitted_classes.map(&:to_s), + permitted_symbols.map(&:to_s)) + scanner = ScalarScanner.new class_loader, strict_integer: strict_integer + visitor = if aliases + Visitors::ToRuby.new scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze + else + Visitors::NoAliasRuby.new scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze + end + result = visitor.accept result + result + end + + ### + # Load +yaml+ in to a Ruby data structure. If multiple documents are + # provided, the object contained in the first document will be returned. + # +filename+ will be used in the exception message if any exception + # is raised while parsing. If +yaml+ is empty, it returns + # the specified +fallback+ return value, which defaults to +nil+. + # + # Raises a Psych::SyntaxError when a YAML syntax error is detected. + # + # Example: + # + # Psych.load("--- a") # => 'a' + # Psych.load("---\n - a\n - b") # => ['a', 'b'] + # + # begin + # Psych.load("--- `", filename: "file.txt") + # rescue Psych::SyntaxError => ex + # ex.file # => 'file.txt' + # ex.message # => "(file.txt): found character that cannot start any token" + # end + # + # When the optional +symbolize_names+ keyword argument is set to a + # true value, returns symbols for keys in Hash objects (default: strings). + # + # Psych.load("---\n foo: bar") # => {"foo"=>"bar"} + # Psych.load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"} + # + # Raises a TypeError when `yaml` parameter is NilClass. This method is + # similar to `safe_load` except that `Symbol` objects are allowed by default. + # + def self.load yaml, permitted_classes: [Symbol], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false, strict_integer: false + safe_load yaml, permitted_classes: permitted_classes, + permitted_symbols: permitted_symbols, + aliases: aliases, + filename: filename, + fallback: fallback, + symbolize_names: symbolize_names, + freeze: freeze, + strict_integer: strict_integer + end + + ### + # Parse a YAML string in +yaml+. Returns the Psych::Nodes::Document. + # +filename+ is used in the exception message if a Psych::SyntaxError is + # raised. + # + # Raises a Psych::SyntaxError when a YAML syntax error is detected. + # + # Example: + # + # Psych.parse("---\n - a\n - b") # => # + # + # begin + # Psych.parse("--- `", filename: "file.txt") + # rescue Psych::SyntaxError => ex + # ex.file # => 'file.txt' + # ex.message # => "(file.txt): found character that cannot start any token" + # end + # + # See Psych::Nodes for more information about YAML AST. + def self.parse yaml, filename: nil + parse_stream(yaml, filename: filename) do |node| + return node + end + + false + end + + ### + # Parse a file at +filename+. Returns the Psych::Nodes::Document. + # + # Raises a Psych::SyntaxError when a YAML syntax error is detected. + def self.parse_file filename, fallback: false + result = File.open filename, 'r:bom|utf-8' do |f| + parse f, filename: filename + end + result || fallback + end + + ### + # Returns a default parser + def self.parser + Psych::Parser.new(TreeBuilder.new) + end + + ### + # Parse a YAML string in +yaml+. Returns the Psych::Nodes::Stream. + # This method can handle multiple YAML documents contained in +yaml+. + # +filename+ is used in the exception message if a Psych::SyntaxError is + # raised. + # + # If a block is given, a Psych::Nodes::Document node will be yielded to the + # block as it's being parsed. + # + # Raises a Psych::SyntaxError when a YAML syntax error is detected. + # + # Example: + # + # Psych.parse_stream("---\n - a\n - b") # => # + # + # Psych.parse_stream("--- a\n--- b") do |node| + # node # => # + # end + # + # begin + # Psych.parse_stream("--- `", filename: "file.txt") + # rescue Psych::SyntaxError => ex + # ex.file # => 'file.txt' + # ex.message # => "(file.txt): found character that cannot start any token" + # end + # + # Raises a TypeError when NilClass is passed. + # + # See Psych::Nodes for more information about YAML AST. + def self.parse_stream yaml, filename: nil, &block + if block_given? + parser = Psych::Parser.new(Handlers::DocumentStream.new(&block)) + parser.parse yaml, filename + else + parser = self.parser + parser.parse yaml, filename + parser.handler.root + end + end + + ### + # call-seq: + # Psych.dump(o) -> string of yaml + # Psych.dump(o, options) -> string of yaml + # Psych.dump(o, io) -> io object passed in + # Psych.dump(o, io, options) -> io object passed in + # + # Dump Ruby object +o+ to a YAML string. Optional +options+ may be passed in + # to control the output format. If an IO object is passed in, the YAML will + # be dumped to that IO object. + # + # Currently supported options are: + # + # [:indentation] Number of space characters used to indent. + # Acceptable value should be in 0..9 range, + # otherwise option is ignored. + # + # Default: 2. + # [:line_width] Max character to wrap line at. + # For unlimited line width use -1. + # + # Default: 0 (meaning "wrap at 81"). + # [:canonical] Write "canonical" YAML form (very verbose, yet + # strictly formal). + # + # Default: false. + # [:header] Write %YAML [version] at the beginning of document. + # + # Default: false. + # + # [:stringify_names] Dump symbol keys in Hash objects as string. + # + # Default: false. + # + # Example: + # + # # Dump an array, get back a YAML string + # Psych.dump(['a', 'b']) # => "---\n- a\n- b\n" + # + # # Dump an array to an IO object + # Psych.dump(['a', 'b'], StringIO.new) # => # + # + # # Dump an array with indentation set + # Psych.dump(['a', ['b']], indentation: 3) # => "---\n- a\n- - b\n" + # + # # Dump an array to an IO with indentation set + # Psych.dump(['a', ['b']], StringIO.new, indentation: 3) + # + # # Dump hash with symbol keys as string + # Psych.dump({a: "b"}, stringify_names: true) # => "---\na: b\n" + def self.dump o, io = nil, options = {} + if Hash === io + options = io + io = nil + end + + visitor = Psych::Visitors::YAMLTree.create options + visitor << o + visitor.tree.yaml io, options + end + + ### + # call-seq: + # Psych.safe_dump(o) -> string of yaml + # Psych.safe_dump(o, options) -> string of yaml + # Psych.safe_dump(o, io) -> io object passed in + # Psych.safe_dump(o, io, options) -> io object passed in + # + # Safely dump Ruby object +o+ to a YAML string. Optional +options+ may be passed in + # to control the output format. If an IO object is passed in, the YAML will + # be dumped to that IO object. By default, only the following + # classes are allowed to be serialized: + # + # * TrueClass + # * FalseClass + # * NilClass + # * Integer + # * Float + # * String + # * Array + # * Hash + # + # Arbitrary classes can be allowed by adding those classes to the +permitted_classes+ + # keyword argument. They are additive. For example, to allow Date serialization: + # + # Psych.safe_dump(yaml, permitted_classes: [Date]) + # + # Now the Date class can be dumped in addition to the classes listed above. + # + # A Psych::DisallowedClass exception will be raised if the object contains a + # class that isn't in the +permitted_classes+ list. + # + # Currently supported options are: + # + # [:indentation] Number of space characters used to indent. + # Acceptable value should be in 0..9 range, + # otherwise option is ignored. + # + # Default: 2. + # [:line_width] Max character to wrap line at. + # For unlimited line width use -1. + # + # Default: 0 (meaning "wrap at 81"). + # [:canonical] Write "canonical" YAML form (very verbose, yet + # strictly formal). + # + # Default: false. + # [:header] Write %YAML [version] at the beginning of document. + # + # Default: false. + # + # [:stringify_names] Dump symbol keys in Hash objects as string. + # + # Default: false. + # + # Example: + # + # # Dump an array, get back a YAML string + # Psych.safe_dump(['a', 'b']) # => "---\n- a\n- b\n" + # + # # Dump an array to an IO object + # Psych.safe_dump(['a', 'b'], StringIO.new) # => # + # + # # Dump an array with indentation set + # Psych.safe_dump(['a', ['b']], indentation: 3) # => "---\n- a\n- - b\n" + # + # # Dump an array to an IO with indentation set + # Psych.safe_dump(['a', ['b']], StringIO.new, indentation: 3) + # + # # Dump hash with symbol keys as string + # Psych.dump({a: "b"}, stringify_names: true) # => "---\na: b\n" + def self.safe_dump o, io = nil, options = {} + if Hash === io + options = io + io = nil + end + + visitor = Psych::Visitors::RestrictedYAMLTree.create options + visitor << o + visitor.tree.yaml io, options + end + + ### + # Dump a list of objects as separate documents to a document stream. + # + # Example: + # + # Psych.dump_stream("foo\n ", {}) # => "--- ! \"foo\\n \"\n--- {}\n" + def self.dump_stream *objects + visitor = Psych::Visitors::YAMLTree.create({}) + objects.each do |o| + visitor << o + end + visitor.tree.yaml + end + + ### + # Dump Ruby +object+ to a JSON string. + def self.to_json object + visitor = Psych::Visitors::JSONTree.create + visitor << object + visitor.tree.yaml + end + + ### + # Load multiple documents given in +yaml+. Returns the parsed documents + # as a list. If a block is given, each document will be converted to Ruby + # and passed to the block during parsing + # + # Example: + # + # Psych.load_stream("--- foo\n...\n--- bar\n...") # => ['foo', 'bar'] + # + # list = [] + # Psych.load_stream("--- foo\n...\n--- bar\n...") do |ruby| + # list << ruby + # end + # list # => ['foo', 'bar'] + # + def self.load_stream yaml, filename: nil, fallback: [], **kwargs + result = if block_given? + parse_stream(yaml, filename: filename) do |node| + yield node.to_ruby(**kwargs) + end + else + parse_stream(yaml, filename: filename).children.map { |node| node.to_ruby(**kwargs) } + end + + return fallback if result.is_a?(Array) && result.empty? + result + end + + ### + # Load multiple documents given in +yaml+. Returns the parsed documents + # as a list. + # + # Example: + # + # Psych.safe_load_stream("--- foo\n...\n--- bar\n...") # => ['foo', 'bar'] + # + # list = [] + # Psych.safe_load_stream("--- foo\n...\n--- bar\n...") do |ruby| + # list << ruby + # end + # list # => ['foo', 'bar'] + # + def self.safe_load_stream yaml, filename: nil, permitted_classes: [], aliases: false + documents = parse_stream(yaml, filename: filename).children.map do |child| + stream = Psych::Nodes::Stream.new + stream.children << child + safe_load(stream.to_yaml, permitted_classes: permitted_classes, aliases: aliases) + end + + if block_given? + documents.each { |doc| yield doc } + nil + else + documents + end + end + + ### + # Load the document contained in +filename+. Returns the yaml contained in + # +filename+ as a Ruby object, or if the file is empty, it returns + # the specified +fallback+ return value, which defaults to +false+. + # + # NOTE: This method *should not* be used to parse untrusted documents, such as + # YAML documents that are supplied via user input. Instead, please use the + # safe_load_file method. + def self.unsafe_load_file filename, **kwargs + File.open(filename, 'r:bom|utf-8') { |f| + self.unsafe_load f, filename: filename, **kwargs + } + end + + ### + # Safely loads the document contained in +filename+. Returns the yaml contained in + # +filename+ as a Ruby object, or if the file is empty, it returns + # the specified +fallback+ return value, which defaults to +nil+. + # See safe_load for options. + def self.safe_load_file filename, **kwargs + File.open(filename, 'r:bom|utf-8') { |f| + self.safe_load f, filename: filename, **kwargs + } + end + + ### + # Loads the document contained in +filename+. Returns the yaml contained in + # +filename+ as a Ruby object, or if the file is empty, it returns + # the specified +fallback+ return value, which defaults to +nil+. + # See load for options. + def self.load_file filename, **kwargs + File.open(filename, 'r:bom|utf-8') { |f| + self.load f, filename: filename, **kwargs + } + end + + # :stopdoc: + def self.add_domain_type domain, type_tag, &block + key = ['tag', domain, type_tag].join ':' + domain_types[key] = [key, block] + domain_types["tag:#{type_tag}"] = [key, block] + end + + def self.add_builtin_type type_tag, &block + domain = 'yaml.org,2002' + key = ['tag', domain, type_tag].join ':' + domain_types[key] = [key, block] + end + + def self.remove_type type_tag + domain_types.delete type_tag + end + + def self.add_tag tag, klass + load_tags[tag] = klass.name + dump_tags[klass] = tag + end + + class << self + if defined?(Ractor) + class Config + attr_accessor :load_tags, :dump_tags, :domain_types + def initialize + @load_tags = {} + @dump_tags = {} + @domain_types = {} + end + end + + def config + Ractor.current[:PsychConfig] ||= Config.new + end + + def load_tags + config.load_tags + end + + def dump_tags + config.dump_tags + end + + def domain_types + config.domain_types + end + + def load_tags=(value) + config.load_tags = value + end + + def dump_tags=(value) + config.dump_tags = value + end + + def domain_types=(value) + config.domain_types = value + end + else + attr_accessor :load_tags + attr_accessor :dump_tags + attr_accessor :domain_types + end + end + self.load_tags = {} + self.dump_tags = {} + self.domain_types = {} + # :startdoc: +end + +require_relative 'psych/core_ext' diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych.so b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych.so new file mode 100755 index 00000000..969437c2 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych.so differ diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/class_loader.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/class_loader.rb new file mode 100644 index 00000000..c8f50972 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/class_loader.rb @@ -0,0 +1,105 @@ +# frozen_string_literal: true +require_relative 'omap' +require_relative 'set' + +module Psych + class ClassLoader # :nodoc: + BIG_DECIMAL = 'BigDecimal' + COMPLEX = 'Complex' + DATA = 'Data' unless RUBY_VERSION < "3.2" + DATE = 'Date' + DATE_TIME = 'DateTime' + EXCEPTION = 'Exception' + OBJECT = 'Object' + PSYCH_OMAP = 'Psych::Omap' + PSYCH_SET = 'Psych::Set' + RANGE = 'Range' + RATIONAL = 'Rational' + REGEXP = 'Regexp' + STRUCT = 'Struct' + SYMBOL = 'Symbol' + + def initialize + @cache = CACHE.dup + end + + def load klassname + return nil if !klassname || klassname.empty? + + find klassname + end + + def symbolize sym + symbol + sym.to_sym + end + + constants.each do |const| + konst = const_get const + class_eval <<~RUBY, __FILE__, __LINE__ + 1 + def #{const.to_s.downcase} + load #{konst.inspect} + end + RUBY + end + + private + + def find klassname + @cache[klassname] ||= resolve(klassname) + end + + def resolve klassname + name = klassname + retried = false + + begin + path2class(name) + rescue ArgumentError, NameError => ex + unless retried + name = "Struct::#{name}" + retried = ex + retry + end + raise retried + end + end + + CACHE = Hash[constants.map { |const| + val = const_get const + begin + [val, ::Object.const_get(val)] + rescue + nil + end + }.compact].freeze + + class Restricted < ClassLoader + def initialize classes, symbols + @classes = classes + @symbols = symbols + super() + end + + def symbolize sym + return super if @symbols.empty? + + if @symbols.include? sym + super + else + raise DisallowedClass.new('load', 'Symbol') + end + end + + private + + def find klassname + if @classes.include? klassname + super + else + raise DisallowedClass.new('load', klassname) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/coder.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/coder.rb new file mode 100644 index 00000000..96a9c3fb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/coder.rb @@ -0,0 +1,95 @@ +# frozen_string_literal: true +module Psych + ### + # If an object defines +encode_with+, then an instance of Psych::Coder will + # be passed to the method when the object is being serialized. The Coder + # automatically assumes a Psych::Nodes::Mapping is being emitted. Other + # objects like Sequence and Scalar may be emitted if +seq=+ or +scalar=+ are + # called, respectively. + class Coder + attr_accessor :tag, :style, :implicit, :object + attr_reader :type, :seq + + def initialize tag + @map = {} + @seq = [] + @implicit = false + @type = :map + @tag = tag + @style = Psych::Nodes::Mapping::BLOCK + @scalar = nil + @object = nil + end + + def scalar *args + if args.length > 0 + warn "#{caller[0]}: Coder#scalar(a,b,c) is deprecated" if $VERBOSE + @tag, @scalar, _ = args + @type = :scalar + end + @scalar + end + + # Emit a map. The coder will be yielded to the block. + def map tag = @tag, style = @style + @tag = tag + @style = style + yield self if block_given? + @map + end + + # Emit a scalar with +value+ and +tag+ + def represent_scalar tag, value + self.tag = tag + self.scalar = value + end + + # Emit a sequence with +list+ and +tag+ + def represent_seq tag, list + @tag = tag + self.seq = list + end + + # Emit a sequence with +map+ and +tag+ + def represent_map tag, map + @tag = tag + self.map = map + end + + # Emit an arbitrary object +obj+ and +tag+ + def represent_object tag, obj + @tag = tag + @type = :object + @object = obj + end + + # Emit a scalar with +value+ + def scalar= value + @type = :scalar + @scalar = value + end + + # Emit a map with +value+ + def map= map + @type = :map + @map = map + end + + def []= k, v + @type = :map + @map[k] = v + end + alias :add :[]= + + def [] k + @type = :map + @map[k] + end + + # Emit a sequence of +list+ + def seq= list + @type = :seq + @seq = list + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/core_ext.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/core_ext.rb new file mode 100644 index 00000000..fc259fd4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/core_ext.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true +class Object + def self.yaml_tag url + Psych.add_tag(url, self) + end + + ### + # call-seq: to_yaml(options = {}) + # + # Convert an object to YAML. See Psych.dump for more information on the + # available +options+. + def to_yaml options = {} + Psych.dump self, options + end +end + +if defined?(::IRB) + require_relative 'y' +end + +# Up to Ruby 3.4, Set was a regular object and was dumped as such +# by Pysch. +# Starting from Ruby 3.5 it's a core class written in C, so we have to implement +# #encode_with / #init_with to preserve backward compatibility. +if defined?(::Set) && Set.new.instance_variables.empty? + class Set + def encode_with(coder) + hash = {} + each do |m| + hash[m] = true + end + coder["hash"] = hash + coder + end + + def init_with(coder) + replace(coder["hash"].keys) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/exception.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/exception.rb new file mode 100644 index 00000000..d7469a4b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/exception.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true +module Psych + class Exception < RuntimeError + end + + class BadAlias < Exception + end + + # Subclasses `BadAlias` for backwards compatibility + class AliasesNotEnabled < BadAlias + def initialize + super "Alias parsing was not enabled. To enable it, pass `aliases: true` to `Psych::load` or `Psych::safe_load`." + end + end + + # Subclasses `BadAlias` for backwards compatibility + class AnchorNotDefined < BadAlias + def initialize anchor_name + super "An alias referenced an unknown anchor: #{anchor_name}" + end + end + + class DisallowedClass < Exception + def initialize action, klass_name + super "Tried to #{action} unspecified class: #{klass_name}" + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/handler.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/handler.rb new file mode 100644 index 00000000..ad7249ff --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/handler.rb @@ -0,0 +1,255 @@ +# frozen_string_literal: true +module Psych + ### + # Psych::Handler is an abstract base class that defines the events used + # when dealing with Psych::Parser. Clients who want to use Psych::Parser + # should implement a class that inherits from Psych::Handler and define + # events that they can handle. + # + # Psych::Handler defines all events that Psych::Parser can possibly send to + # event handlers. + # + # See Psych::Parser for more details + class Handler + ### + # Configuration options for dumping YAML. + class DumperOptions + attr_accessor :line_width, :indentation, :canonical + + def initialize + @line_width = 0 + @indentation = 2 + @canonical = false + end + end + + # Default dumping options + OPTIONS = DumperOptions.new + + # Events that a Handler should respond to. + EVENTS = [ :alias, + :empty, + :end_document, + :end_mapping, + :end_sequence, + :end_stream, + :scalar, + :start_document, + :start_mapping, + :start_sequence, + :start_stream ] + + ### + # Called with +encoding+ when the YAML stream starts. This method is + # called once per stream. A stream may contain multiple documents. + # + # See the constants in Psych::Parser for the possible values of +encoding+. + def start_stream encoding + end + + ### + # Called when the document starts with the declared +version+, + # +tag_directives+, if the document is +implicit+. + # + # +version+ will be an array of integers indicating the YAML version being + # dealt with, +tag_directives+ is a list of tuples indicating the prefix + # and suffix of each tag, and +implicit+ is a boolean indicating whether + # the document is started implicitly. + # + # === Example + # + # Given the following YAML: + # + # %YAML 1.1 + # %TAG ! tag:tenderlovemaking.com,2009: + # --- !squee + # + # The parameters for start_document must be this: + # + # version # => [1, 1] + # tag_directives # => [["!", "tag:tenderlovemaking.com,2009:"]] + # implicit # => false + def start_document version, tag_directives, implicit + end + + ### + # Called with the document ends. +implicit+ is a boolean value indicating + # whether or not the document has an implicit ending. + # + # === Example + # + # Given the following YAML: + # + # --- + # hello world + # + # +implicit+ will be true. Given this YAML: + # + # --- + # hello world + # ... + # + # +implicit+ will be false. + def end_document implicit + end + + ### + # Called when an alias is found to +anchor+. +anchor+ will be the name + # of the anchor found. + # + # === Example + # + # Here we have an example of an array that references itself in YAML: + # + # --- &ponies + # - first element + # - *ponies + # + # &ponies is the anchor, *ponies is the alias. In this case, alias is + # called with "ponies". + def alias anchor + end + + ### + # Called when a scalar +value+ is found. The scalar may have an + # +anchor+, a +tag+, be implicitly +plain+ or implicitly +quoted+ + # + # +value+ is the string value of the scalar + # +anchor+ is an associated anchor or nil + # +tag+ is an associated tag or nil + # +plain+ is a boolean value + # +quoted+ is a boolean value + # +style+ is an integer indicating the string style + # + # See the constants in Psych::Nodes::Scalar for the possible values of + # +style+ + # + # === Example + # + # Here is a YAML document that exercises most of the possible ways this + # method can be called: + # + # --- + # - !str "foo" + # - &anchor fun + # - many + # lines + # - | + # many + # newlines + # + # The above YAML document contains a list with four strings. Here are + # the parameters sent to this method in the same order: + # + # # value anchor tag plain quoted style + # ["foo", nil, "!str", false, false, 3 ] + # ["fun", "anchor", nil, true, false, 1 ] + # ["many lines", nil, nil, true, false, 1 ] + # ["many\nnewlines\n", nil, nil, false, true, 4 ] + # + def scalar value, anchor, tag, plain, quoted, style + end + + ### + # Called when a sequence is started. + # + # +anchor+ is the anchor associated with the sequence or nil. + # +tag+ is the tag associated with the sequence or nil. + # +implicit+ a boolean indicating whether or not the sequence was implicitly + # started. + # +style+ is an integer indicating the list style. + # + # See the constants in Psych::Nodes::Sequence for the possible values of + # +style+. + # + # === Example + # + # Here is a YAML document that exercises most of the possible ways this + # method can be called: + # + # --- + # - !!seq [ + # a + # ] + # - &pewpew + # - b + # + # The above YAML document consists of three lists, an outer list that + # contains two inner lists. Here is a matrix of the parameters sent + # to represent these lists: + # + # # anchor tag implicit style + # [nil, nil, true, 1 ] + # [nil, "tag:yaml.org,2002:seq", false, 2 ] + # ["pewpew", nil, true, 1 ] + + def start_sequence anchor, tag, implicit, style + end + + ### + # Called when a sequence ends. + def end_sequence + end + + ### + # Called when a map starts. + # + # +anchor+ is the anchor associated with the map or +nil+. + # +tag+ is the tag associated with the map or +nil+. + # +implicit+ is a boolean indicating whether or not the map was implicitly + # started. + # +style+ is an integer indicating the mapping style. + # + # See the constants in Psych::Nodes::Mapping for the possible values of + # +style+. + # + # === Example + # + # Here is a YAML document that exercises most of the possible ways this + # method can be called: + # + # --- + # k: !!map { hello: world } + # v: &pewpew + # hello: world + # + # The above YAML document consists of three maps, an outer map that contains + # two inner maps. Below is a matrix of the parameters sent in order to + # represent these three maps: + # + # # anchor tag implicit style + # [nil, nil, true, 1 ] + # [nil, "tag:yaml.org,2002:map", false, 2 ] + # ["pewpew", nil, true, 1 ] + + def start_mapping anchor, tag, implicit, style + end + + ### + # Called when a map ends + def end_mapping + end + + ### + # Called when an empty event happens. (Which, as far as I can tell, is + # never). + def empty + end + + ### + # Called when the YAML stream ends + def end_stream + end + + ### + # Called before each event with line/column information. + def event_location(start_line, start_column, end_line, end_column) + end + + ### + # Is this handler a streaming handler? + def streaming? + false + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/handlers/document_stream.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/handlers/document_stream.rb new file mode 100644 index 00000000..b77115d0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/handlers/document_stream.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true +require_relative '../tree_builder' + +module Psych + module Handlers + class DocumentStream < Psych::TreeBuilder # :nodoc: + def initialize &block + super + @block = block + end + + def start_document version, tag_directives, implicit + n = Nodes::Document.new version, tag_directives, implicit + push n + end + + def end_document implicit_end = !streaming? + @last.implicit_end = implicit_end + @block.call pop + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/handlers/recorder.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/handlers/recorder.rb new file mode 100644 index 00000000..c98724cb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/handlers/recorder.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true +require_relative '../handler' + +module Psych + module Handlers + ### + # This handler will capture an event and record the event. Recorder events + # are available vial Psych::Handlers::Recorder#events. + # + # For example: + # + # recorder = Psych::Handlers::Recorder.new + # parser = Psych::Parser.new recorder + # parser.parse '--- foo' + # + # recorder.events # => [list of events] + # + # # Replay the events + # + # emitter = Psych::Emitter.new $stdout + # recorder.events.each do |m, args| + # emitter.send m, *args + # end + + class Recorder < Psych::Handler + attr_reader :events + + def initialize + @events = [] + super + end + + EVENTS.each do |event| + define_method event do |*args| + @events << [event, args] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/json/ruby_events.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/json/ruby_events.rb new file mode 100644 index 00000000..17b7ddc3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/json/ruby_events.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true +module Psych + module JSON + module RubyEvents # :nodoc: + def visit_Time o + formatted = format_time o + @emitter.scalar formatted, nil, nil, false, true, Nodes::Scalar::DOUBLE_QUOTED + end + + def visit_DateTime o + visit_Time o.to_time + end + + def visit_String o + @emitter.scalar o.to_s, nil, nil, false, true, Nodes::Scalar::DOUBLE_QUOTED + end + alias :visit_Symbol :visit_String + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/json/stream.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/json/stream.rb new file mode 100644 index 00000000..24dd4b9b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/json/stream.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true +require_relative 'ruby_events' +require_relative 'yaml_events' + +module Psych + module JSON + class Stream < Psych::Visitors::JSONTree + include Psych::JSON::RubyEvents + include Psych::Streaming + extend Psych::Streaming::ClassMethods + + class Emitter < Psych::Stream::Emitter # :nodoc: + include Psych::JSON::YAMLEvents + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/json/tree_builder.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/json/tree_builder.rb new file mode 100644 index 00000000..9a45f6b9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/json/tree_builder.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true +require_relative 'yaml_events' + +module Psych + module JSON + ### + # Psych::JSON::TreeBuilder is an event based AST builder. Events are sent + # to an instance of Psych::JSON::TreeBuilder and a JSON AST is constructed. + class TreeBuilder < Psych::TreeBuilder + include Psych::JSON::YAMLEvents + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/json/yaml_events.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/json/yaml_events.rb new file mode 100644 index 00000000..eb973f53 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/json/yaml_events.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true +module Psych + module JSON + module YAMLEvents # :nodoc: + def start_document version, tag_directives, implicit + super(version, tag_directives, !streaming?) + end + + def end_document implicit_end = !streaming? + super(implicit_end) + end + + def start_mapping anchor, tag, implicit, style + super(anchor, nil, true, Nodes::Mapping::FLOW) + end + + def start_sequence anchor, tag, implicit, style + super(anchor, nil, true, Nodes::Sequence::FLOW) + end + + def scalar value, anchor, tag, plain, quoted, style + if "tag:yaml.org,2002:null" == tag + super('null', nil, nil, true, false, Nodes::Scalar::PLAIN) + else + super + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/nodes.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/nodes.rb new file mode 100644 index 00000000..2fa52e00 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/nodes.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true +require_relative 'nodes/node' +require_relative 'nodes/stream' +require_relative 'nodes/document' +require_relative 'nodes/sequence' +require_relative 'nodes/scalar' +require_relative 'nodes/mapping' +require_relative 'nodes/alias' + +module Psych + ### + # = Overview + # + # When using Psych.load to deserialize a YAML document, the document is + # translated to an intermediary AST. That intermediary AST is then + # translated in to a Ruby object graph. + # + # In the opposite direction, when using Psych.dump, the Ruby object graph is + # translated to an intermediary AST which is then converted to a YAML + # document. + # + # Psych::Nodes contains all of the classes that make up the nodes of a YAML + # AST. You can manually build an AST and use one of the visitors (see + # Psych::Visitors) to convert that AST to either a YAML document or to a + # Ruby object graph. + # + # Here is an example of building an AST that represents a list with one + # scalar: + # + # # Create our nodes + # stream = Psych::Nodes::Stream.new + # doc = Psych::Nodes::Document.new + # seq = Psych::Nodes::Sequence.new + # scalar = Psych::Nodes::Scalar.new('foo') + # + # # Build up our tree + # stream.children << doc + # doc.children << seq + # seq.children << scalar + # + # The stream is the root of the tree. We can then convert the tree to YAML: + # + # stream.to_yaml => "---\n- foo\n" + # + # Or convert it to Ruby: + # + # stream.to_ruby => [["foo"]] + # + # == YAML AST Requirements + # + # A valid YAML AST *must* have one Psych::Nodes::Stream at the root. A + # Psych::Nodes::Stream node must have 1 or more Psych::Nodes::Document nodes + # as children. + # + # Psych::Nodes::Document nodes must have one and *only* one child. That child + # may be one of: + # + # * Psych::Nodes::Sequence + # * Psych::Nodes::Mapping + # * Psych::Nodes::Scalar + # + # Psych::Nodes::Sequence and Psych::Nodes::Mapping nodes may have many + # children, but Psych::Nodes::Mapping nodes should have an even number of + # children. + # + # All of these are valid children for Psych::Nodes::Sequence and + # Psych::Nodes::Mapping nodes: + # + # * Psych::Nodes::Sequence + # * Psych::Nodes::Mapping + # * Psych::Nodes::Scalar + # * Psych::Nodes::Alias + # + # Psych::Nodes::Scalar and Psych::Nodes::Alias are both terminal nodes and + # should not have any children. + module Nodes + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/nodes/alias.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/nodes/alias.rb new file mode 100644 index 00000000..6da655f0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/nodes/alias.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true +module Psych + module Nodes + ### + # This class represents a {YAML Alias}[http://yaml.org/spec/1.1/#alias]. + # It points to an +anchor+. + # + # A Psych::Nodes::Alias is a terminal node and may have no children. + class Alias < Psych::Nodes::Node + # The anchor this alias links to + attr_accessor :anchor + + # Create a new Alias that points to an +anchor+ + def initialize anchor + @anchor = anchor + end + + def alias?; true; end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/nodes/document.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/nodes/document.rb new file mode 100644 index 00000000..f57410d6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/nodes/document.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true +module Psych + module Nodes + ### + # This represents a YAML Document. This node must be a child of + # Psych::Nodes::Stream. A Psych::Nodes::Document must have one child, + # and that child may be one of the following: + # + # * Psych::Nodes::Sequence + # * Psych::Nodes::Mapping + # * Psych::Nodes::Scalar + class Document < Psych::Nodes::Node + # The version of the YAML document + attr_accessor :version + + # A list of tag directives for this document + attr_accessor :tag_directives + + # Was this document implicitly created? + attr_accessor :implicit + + # Is the end of the document implicit? + attr_accessor :implicit_end + + ### + # Create a new Psych::Nodes::Document object. + # + # +version+ is a list indicating the YAML version. + # +tags_directives+ is a list of tag directive declarations + # +implicit+ is a flag indicating whether the document will be implicitly + # started. + # + # == Example: + # This creates a YAML document object that represents a YAML 1.1 document + # with one tag directive, and has an implicit start: + # + # Psych::Nodes::Document.new( + # [1,1], + # [["!", "tag:tenderlovemaking.com,2009:"]], + # true + # ) + # + # == See Also + # See also Psych::Handler#start_document + def initialize version = [], tag_directives = [], implicit = false + super() + @version = version + @tag_directives = tag_directives + @implicit = implicit + @implicit_end = true + end + + ### + # Returns the root node. A Document may only have one root node: + # http://yaml.org/spec/1.1/#id898031 + def root + children.first + end + + def document?; true; end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/nodes/mapping.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/nodes/mapping.rb new file mode 100644 index 00000000..d49678cb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/nodes/mapping.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true +module Psych + module Nodes + ### + # This class represents a {YAML Mapping}[http://yaml.org/spec/1.1/#mapping]. + # + # A Psych::Nodes::Mapping node may have 0 or more children, but must have + # an even number of children. Here are the valid children a + # Psych::Nodes::Mapping node may have: + # + # * Psych::Nodes::Sequence + # * Psych::Nodes::Mapping + # * Psych::Nodes::Scalar + # * Psych::Nodes::Alias + class Mapping < Psych::Nodes::Node + # Any Map Style + ANY = 0 + + # Block Map Style + BLOCK = 1 + + # Flow Map Style + FLOW = 2 + + # The optional anchor for this mapping + attr_accessor :anchor + + # The optional tag for this mapping + attr_accessor :tag + + # Is this an implicit mapping? + attr_accessor :implicit + + # The style of this mapping + attr_accessor :style + + ### + # Create a new Psych::Nodes::Mapping object. + # + # +anchor+ is the anchor associated with the map or +nil+. + # +tag+ is the tag associated with the map or +nil+. + # +implicit+ is a boolean indicating whether or not the map was implicitly + # started. + # +style+ is an integer indicating the mapping style. + # + # == See Also + # See also Psych::Handler#start_mapping + def initialize anchor = nil, tag = nil, implicit = true, style = BLOCK + super() + @anchor = anchor + @tag = tag + @implicit = implicit + @style = style + end + + def mapping?; true; end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/nodes/node.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/nodes/node.rb new file mode 100644 index 00000000..6ae5c591 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/nodes/node.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true +require_relative '../class_loader' +require_relative '../scalar_scanner' + +module Psych + module Nodes + ### + # The base class for any Node in a YAML parse tree. This class should + # never be instantiated. + class Node + include Enumerable + + # The children of this node + attr_reader :children + + # An associated tag + attr_reader :tag + + # The line number where this node start + attr_accessor :start_line + + # The column number where this node start + attr_accessor :start_column + + # The line number where this node ends + attr_accessor :end_line + + # The column number where this node ends + attr_accessor :end_column + + # Create a new Psych::Nodes::Node + def initialize + @children = [] + end + + ### + # Iterate over each node in the tree. Yields each node to +block+ depth + # first. + def each &block + return enum_for :each unless block_given? + Visitors::DepthFirst.new(block).accept self + end + + ### + # Convert this node to Ruby. + # + # See also Psych::Visitors::ToRuby + def to_ruby(symbolize_names: false, freeze: false, strict_integer: false) + Visitors::ToRuby.create(symbolize_names: symbolize_names, freeze: freeze, strict_integer: strict_integer).accept(self) + end + alias :transform :to_ruby + + ### + # Convert this node to YAML. + # + # See also Psych::Visitors::Emitter + def yaml io = nil, options = {} + require "stringio" unless defined?(StringIO) + + real_io = io || StringIO.new(''.encode('utf-8')) + + Visitors::Emitter.new(real_io, options).accept self + return real_io.string unless io + io + end + alias :to_yaml :yaml + + def alias?; false; end + def document?; false; end + def mapping?; false; end + def scalar?; false; end + def sequence?; false; end + def stream?; false; end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/nodes/scalar.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/nodes/scalar.rb new file mode 100644 index 00000000..5550b616 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/nodes/scalar.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true +module Psych + module Nodes + ### + # This class represents a {YAML Scalar}[http://yaml.org/spec/1.1/#id858081]. + # + # This node type is a terminal node and should not have any children. + class Scalar < Psych::Nodes::Node + # Any style scalar, the emitter chooses + ANY = 0 + + # Plain scalar style + PLAIN = 1 + + # Single quoted style + SINGLE_QUOTED = 2 + + # Double quoted style + DOUBLE_QUOTED = 3 + + # Literal style + LITERAL = 4 + + # Folded style + FOLDED = 5 + + # The scalar value + attr_accessor :value + + # The anchor value (if there is one) + attr_accessor :anchor + + # The tag value (if there is one) + attr_accessor :tag + + # Is this a plain scalar? + attr_accessor :plain + + # Is this scalar quoted? + attr_accessor :quoted + + # The style of this scalar + attr_accessor :style + + ### + # Create a new Psych::Nodes::Scalar object. + # + # +value+ is the string value of the scalar + # +anchor+ is an associated anchor or nil + # +tag+ is an associated tag or nil + # +plain+ is a boolean value + # +quoted+ is a boolean value + # +style+ is an integer indicating the string style + # + # == See Also + # + # See also Psych::Handler#scalar + def initialize value, anchor = nil, tag = nil, plain = true, quoted = false, style = ANY + @value = value + @anchor = anchor + @tag = tag + @plain = plain + @quoted = quoted + @style = style + end + + def scalar?; true; end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/nodes/sequence.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/nodes/sequence.rb new file mode 100644 index 00000000..740f1938 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/nodes/sequence.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: true +module Psych + module Nodes + ### + # This class represents a + # {YAML sequence}[http://yaml.org/spec/1.1/#sequence/syntax]. + # + # A YAML sequence is basically a list, and looks like this: + # + # %YAML 1.1 + # --- + # - I am + # - a Sequence + # + # A YAML sequence may have an anchor like this: + # + # %YAML 1.1 + # --- + # &A [ + # "This sequence", + # "has an anchor" + # ] + # + # A YAML sequence may also have a tag like this: + # + # %YAML 1.1 + # --- + # !!seq [ + # "This sequence", + # "has a tag" + # ] + # + # This class represents a sequence in a YAML document. A + # Psych::Nodes::Sequence node may have 0 or more children. Valid children + # for this node are: + # + # * Psych::Nodes::Sequence + # * Psych::Nodes::Mapping + # * Psych::Nodes::Scalar + # * Psych::Nodes::Alias + class Sequence < Psych::Nodes::Node + # Any Styles, emitter chooses + ANY = 0 + + # Block style sequence + BLOCK = 1 + + # Flow style sequence + FLOW = 2 + + # The anchor for this sequence (if any) + attr_accessor :anchor + + # The tag name for this sequence (if any) + attr_accessor :tag + + # Is this sequence started implicitly? + attr_accessor :implicit + + # The sequence style used + attr_accessor :style + + ### + # Create a new object representing a YAML sequence. + # + # +anchor+ is the anchor associated with the sequence or nil. + # +tag+ is the tag associated with the sequence or nil. + # +implicit+ a boolean indicating whether or not the sequence was + # implicitly started. + # +style+ is an integer indicating the list style. + # + # See Psych::Handler#start_sequence + def initialize anchor = nil, tag = nil, implicit = true, style = BLOCK + super() + @anchor = anchor + @tag = tag + @implicit = implicit + @style = style + end + + def sequence?; true; end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/nodes/stream.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/nodes/stream.rb new file mode 100644 index 00000000..b5252178 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/nodes/stream.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true +module Psych + module Nodes + ### + # Represents a YAML stream. This is the root node for any YAML parse + # tree. This node must have one or more child nodes. The only valid + # child node for a Psych::Nodes::Stream node is Psych::Nodes::Document. + class Stream < Psych::Nodes::Node + + # Encodings supported by Psych (and libyaml) + + # Any encoding + ANY = Psych::Parser::ANY + + # UTF-8 encoding + UTF8 = Psych::Parser::UTF8 + + # UTF-16LE encoding + UTF16LE = Psych::Parser::UTF16LE + + # UTF-16BE encoding + UTF16BE = Psych::Parser::UTF16BE + + # The encoding used for this stream + attr_accessor :encoding + + ### + # Create a new Psych::Nodes::Stream node with an +encoding+ that + # defaults to Psych::Nodes::Stream::UTF8. + # + # See also Psych::Handler#start_stream + def initialize encoding = UTF8 + super() + @encoding = encoding + end + + def stream?; true; end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/omap.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/omap.rb new file mode 100644 index 00000000..29cde0be --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/omap.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true +module Psych + class Omap < ::Hash + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/parser.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/parser.rb new file mode 100644 index 00000000..2181c730 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/parser.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true +module Psych + ### + # YAML event parser class. This class parses a YAML document and calls + # events on the handler that is passed to the constructor. The events can + # be used for things such as constructing a YAML AST or deserializing YAML + # documents. It can even be fed back to Psych::Emitter to emit the same + # document that was parsed. + # + # See Psych::Handler for documentation on the events that Psych::Parser emits. + # + # Here is an example that prints out ever scalar found in a YAML document: + # + # # Handler for detecting scalar values + # class ScalarHandler < Psych::Handler + # def scalar value, anchor, tag, plain, quoted, style + # puts value + # end + # end + # + # parser = Psych::Parser.new(ScalarHandler.new) + # parser.parse(yaml_document) + # + # Here is an example that feeds the parser back in to Psych::Emitter. The + # YAML document is read from STDIN and written back out to STDERR: + # + # parser = Psych::Parser.new(Psych::Emitter.new($stderr)) + # parser.parse($stdin) + # + # Psych uses Psych::Parser in combination with Psych::TreeBuilder to + # construct an AST of the parsed YAML document. + + class Parser + class Mark < Struct.new(:index, :line, :column) + end + + # The handler on which events will be called + attr_accessor :handler + + # Set the encoding for this parser to +encoding+ + attr_writer :external_encoding + + ### + # Creates a new Psych::Parser instance with +handler+. YAML events will + # be called on +handler+. See Psych::Parser for more details. + + def initialize handler = Handler.new + @handler = handler + @external_encoding = ANY + end + + ### + # call-seq: + # parser.parse(yaml) + # + # Parse the YAML document contained in +yaml+. Events will be called on + # the handler set on the parser instance. + # + # See Psych::Parser and Psych::Parser#handler + + def parse yaml, path = yaml.respond_to?(:path) ? yaml.path : "" + _native_parse @handler, yaml, path + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/scalar_scanner.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/scalar_scanner.rb new file mode 100644 index 00000000..8cf868f8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/scalar_scanner.rb @@ -0,0 +1,141 @@ +# frozen_string_literal: true + +module Psych + ### + # Scan scalars for built in types + class ScalarScanner + # Taken from http://yaml.org/type/timestamp.html + TIME = /^-?\d{4}-\d{1,2}-\d{1,2}(?:[Tt]|\s+)\d{1,2}:\d\d:\d\d(?:\.\d*)?(?:\s*(?:Z|[-+]\d{1,2}:?(?:\d\d)?))?$/ + + # Taken from http://yaml.org/type/float.html + # Base 60, [-+]inf and NaN are handled separately + FLOAT = /^(?:[-+]?([0-9][0-9_,]*)?\.[0-9]*([eE][-+][0-9]+)?(?# base 10))$/x + + # Taken from http://yaml.org/type/int.html and modified to ensure at least one numerical symbol exists + INTEGER_STRICT = /^(?:[-+]?0b[_]*[0-1][0-1_]* (?# base 2) + |[-+]?0[_]*[0-7][0-7_]* (?# base 8) + |[-+]?(0|[1-9][0-9_]*) (?# base 10) + |[-+]?0x[_]*[0-9a-fA-F][0-9a-fA-F_]* (?# base 16))$/x + + # Same as above, but allows commas. + # Not to YML spec, but kept for backwards compatibility + INTEGER_LEGACY = /^(?:[-+]?0b[_,]*[0-1][0-1_,]* (?# base 2) + |[-+]?0[_,]*[0-7][0-7_,]* (?# base 8) + |[-+]?(?:0|[1-9](?:[0-9]|,[0-9]|_[0-9])*) (?# base 10) + |[-+]?0x[_,]*[0-9a-fA-F][0-9a-fA-F_,]* (?# base 16))$/x + + attr_reader :class_loader + + # Create a new scanner + def initialize class_loader, strict_integer: false + @symbol_cache = {} + @class_loader = class_loader + @strict_integer = strict_integer + end + + # Tokenize +string+ returning the Ruby object + def tokenize string + return nil if string.empty? + return @symbol_cache[string] if @symbol_cache.key?(string) + integer_regex = @strict_integer ? INTEGER_STRICT : INTEGER_LEGACY + # Check for a String type, being careful not to get caught by hash keys, hex values, and + # special floats (e.g., -.inf). + if string.match?(%r{^[^\d.:-]?[[:alpha:]_\s!@#$%\^&*(){}<>|/\\~;=]+}) || string.match?(/\n/) + return string if string.length > 5 + + if string.match?(/^[^ytonf~]/i) + string + elsif string == '~' || string.match?(/^null$/i) + nil + elsif string.match?(/^(yes|true|on)$/i) + true + elsif string.match?(/^(no|false|off)$/i) + false + else + string + end + elsif string.match?(TIME) + begin + parse_time string + rescue ArgumentError + string + end + elsif string.match?(/^\d{4}-(?:1[012]|0\d|\d)-(?:[12]\d|3[01]|0\d|\d)$/) + begin + class_loader.date.strptime(string, '%F', Date::GREGORIAN) + rescue ArgumentError + string + end + elsif string.match?(/^\+?\.inf$/i) + Float::INFINITY + elsif string.match?(/^-\.inf$/i) + -Float::INFINITY + elsif string.match?(/^\.nan$/i) + Float::NAN + elsif string.match?(/^:./) + if string =~ /^:(["'])(.*)\1/ + @symbol_cache[string] = class_loader.symbolize($2.sub(/^:/, '')) + else + @symbol_cache[string] = class_loader.symbolize(string.sub(/^:/, '')) + end + elsif string.match?(/^[-+]?[0-9][0-9_]*(:[0-5]?[0-9]){1,2}$/) + i = 0 + string.split(':').each_with_index do |n,e| + i += (n.to_i * 60 ** (e - 2).abs) + end + i + elsif string.match?(/^[-+]?[0-9][0-9_]*(:[0-5]?[0-9]){1,2}\.[0-9_]*$/) + i = 0 + string.split(':').each_with_index do |n,e| + i += (n.to_f * 60 ** (e - 2).abs) + end + i + elsif string.match?(FLOAT) + if string.match?(/\A[-+]?\.\Z/) + string + else + Float(string.delete(',_').gsub(/\.([Ee]|$)/, '\1')) + end + elsif string.match?(integer_regex) + parse_int string + else + string + end + end + + ### + # Parse and return an int from +string+ + def parse_int string + Integer(string.delete(',_')) + end + + ### + # Parse and return a Time from +string+ + def parse_time string + klass = class_loader.load 'Time' + + date, time = *(string.split(/[ tT]/, 2)) + (yy, m, dd) = date.match(/^(-?\d{4})-(\d{1,2})-(\d{1,2})/).captures.map { |x| x.to_i } + md = time.match(/(\d+:\d+:\d+)(?:\.(\d*))?\s*(Z|[-+]\d+(:\d\d)?)?/) + + (hh, mm, ss) = md[1].split(':').map { |x| x.to_i } + us = (md[2] ? Rational("0.#{md[2]}") : 0) * 1000000 + + time = klass.utc(yy, m, dd, hh, mm, ss, us) + + return time if 'Z' == md[3] + return klass.at(time.to_i, us) unless md[3] + + tz = md[3].match(/^([+\-]?\d{1,2})\:?(\d{1,2})?$/)[1..-1].compact.map { |digit| Integer(digit, 10) } + offset = tz.first * 3600 + + if offset < 0 + offset -= ((tz[1] || 0) * 60) + else + offset += ((tz[1] || 0) * 60) + end + + klass.new(yy, m, dd, hh, mm, ss+us/(1_000_000r), offset) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/set.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/set.rb new file mode 100644 index 00000000..760d2170 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/set.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true +module Psych + class Set < ::Hash + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/stream.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/stream.rb new file mode 100644 index 00000000..24e45afc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/stream.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true +module Psych + ### + # Psych::Stream is a streaming YAML emitter. It will not buffer your YAML, + # but send it straight to an IO. + # + # Here is an example use: + # + # stream = Psych::Stream.new($stdout) + # stream.start + # stream.push({:foo => 'bar'}) + # stream.finish + # + # YAML will be immediately emitted to $stdout with no buffering. + # + # Psych::Stream#start will take a block and ensure that Psych::Stream#finish + # is called, so you can do this form: + # + # stream = Psych::Stream.new($stdout) + # stream.start do |em| + # em.push(:foo => 'bar') + # end + # + class Stream < Psych::Visitors::YAMLTree + class Emitter < Psych::Emitter # :nodoc: + def end_document implicit_end = !streaming? + super + end + + def streaming? + true + end + end + + include Psych::Streaming + extend Psych::Streaming::ClassMethods + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/streaming.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/streaming.rb new file mode 100644 index 00000000..eb19792a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/streaming.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true +module Psych + module Streaming + module ClassMethods + ### + # Create a new streaming emitter. Emitter will print to +io+. See + # Psych::Stream for an example. + def new io + emitter = const_get(:Emitter).new(io) + class_loader = ClassLoader.new + ss = ScalarScanner.new class_loader + super(emitter, ss, {}) + end + end + + ### + # Start streaming using +encoding+ + def start encoding = Nodes::Stream::UTF8 + super.tap { yield self if block_given? } + ensure + finish if block_given? + end + + private + def register target, obj + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/syntax_error.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/syntax_error.rb new file mode 100644 index 00000000..a4c9c4a3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/syntax_error.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true +require_relative 'exception' + +module Psych + class SyntaxError < Psych::Exception + attr_reader :file, :line, :column, :offset, :problem, :context + + def initialize file, line, col, offset, problem, context + err = [problem, context].compact.join ' ' + filename = file || '' + message = "(%s): %s at line %d column %d" % [filename, err, line, col] + + @file = file + @line = line + @column = col + @offset = offset + @problem = problem + @context = context + super(message) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/tree_builder.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/tree_builder.rb new file mode 100644 index 00000000..83115bd7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/tree_builder.rb @@ -0,0 +1,137 @@ +# frozen_string_literal: true +require_relative 'handler' + +module Psych + ### + # This class works in conjunction with Psych::Parser to build an in-memory + # parse tree that represents a YAML document. + # + # == Example + # + # parser = Psych::Parser.new Psych::TreeBuilder.new + # parser.parse('--- foo') + # tree = parser.handler.root + # + # See Psych::Handler for documentation on the event methods used in this + # class. + class TreeBuilder < Psych::Handler + # Returns the root node for the built tree + attr_reader :root + + # Create a new TreeBuilder instance + def initialize + @stack = [] + @last = nil + @root = nil + + @start_line = nil + @start_column = nil + @end_line = nil + @end_column = nil + end + + def event_location(start_line, start_column, end_line, end_column) + @start_line = start_line + @start_column = start_column + @end_line = end_line + @end_column = end_column + end + + %w{ + Sequence + Mapping + }.each do |node| + class_eval <<~RUBY, __FILE__, __LINE__ + 1 + def start_#{node.downcase}(anchor, tag, implicit, style) + n = Nodes::#{node}.new(anchor, tag, implicit, style) + set_start_location(n) + @last.children << n + push n + end + + def end_#{node.downcase} + n = pop + set_end_location(n) + n + end + RUBY + end + + ### + # Handles start_document events with +version+, +tag_directives+, + # and +implicit+ styling. + # + # See Psych::Handler#start_document + def start_document version, tag_directives, implicit + n = Nodes::Document.new version, tag_directives, implicit + set_start_location(n) + @last.children << n + push n + end + + ### + # Handles end_document events with +version+, +tag_directives+, + # and +implicit+ styling. + # + # See Psych::Handler#start_document + def end_document implicit_end = !streaming? + @last.implicit_end = implicit_end + n = pop + set_end_location(n) + n + end + + def start_stream encoding + @root = Nodes::Stream.new(encoding) + set_start_location(@root) + push @root + end + + def end_stream + n = pop + set_end_location(n) + n + end + + def scalar value, anchor, tag, plain, quoted, style + s = Nodes::Scalar.new(value,anchor,tag,plain,quoted,style) + set_location(s) + @last.children << s + s + end + + def alias anchor + a = Nodes::Alias.new(anchor) + set_location(a) + @last.children << a + a + end + + private + def push value + @stack.push value + @last = value + end + + def pop + x = @stack.pop + @last = @stack.last + x + end + + def set_location(node) + set_start_location(node) + set_end_location(node) + end + + def set_start_location(node) + node.start_line = @start_line + node.start_column = @start_column + end + + def set_end_location(node) + node.end_line = @end_line + node.end_column = @end_column + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/versions.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/versions.rb new file mode 100644 index 00000000..3202b102 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/versions.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module Psych + # The version of Psych you are using + VERSION = '5.2.6' + + if RUBY_ENGINE == 'jruby' + DEFAULT_SNAKEYAML_VERSION = '2.9'.freeze + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/visitors.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/visitors.rb new file mode 100644 index 00000000..508290d8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/visitors.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true +require_relative 'visitors/visitor' +require_relative 'visitors/to_ruby' +require_relative 'visitors/emitter' +require_relative 'visitors/yaml_tree' +require_relative 'visitors/json_tree' +require_relative 'visitors/depth_first' diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/visitors/depth_first.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/visitors/depth_first.rb new file mode 100644 index 00000000..b4ff9e40 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/visitors/depth_first.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true +module Psych + module Visitors + class DepthFirst < Psych::Visitors::Visitor + def initialize block + @block = block + end + + private + + def nary o + o.children.each { |x| visit x } + @block.call o + end + alias :visit_Psych_Nodes_Stream :nary + alias :visit_Psych_Nodes_Document :nary + alias :visit_Psych_Nodes_Sequence :nary + alias :visit_Psych_Nodes_Mapping :nary + + def terminal o + @block.call o + end + alias :visit_Psych_Nodes_Scalar :terminal + alias :visit_Psych_Nodes_Alias :terminal + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/visitors/emitter.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/visitors/emitter.rb new file mode 100644 index 00000000..e3b92b7d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/visitors/emitter.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true +module Psych + module Visitors + class Emitter < Psych::Visitors::Visitor + def initialize io, options = {} + opts = [:indentation, :canonical, :line_width].find_all { |opt| + options.key?(opt) + } + + if opts.empty? + @handler = Psych::Emitter.new io + else + du = Handler::DumperOptions.new + opts.each { |option| du.send :"#{option}=", options[option] } + @handler = Psych::Emitter.new io, du + end + end + + def visit_Psych_Nodes_Stream o + @handler.start_stream o.encoding + o.children.each { |c| accept c } + @handler.end_stream + end + + def visit_Psych_Nodes_Document o + @handler.start_document o.version, o.tag_directives, o.implicit + o.children.each { |c| accept c } + @handler.end_document o.implicit_end + end + + def visit_Psych_Nodes_Scalar o + @handler.scalar o.value, o.anchor, o.tag, o.plain, o.quoted, o.style + end + + def visit_Psych_Nodes_Sequence o + @handler.start_sequence o.anchor, o.tag, o.implicit, o.style + o.children.each { |c| accept c } + @handler.end_sequence + end + + def visit_Psych_Nodes_Mapping o + @handler.start_mapping o.anchor, o.tag, o.implicit, o.style + o.children.each { |c| accept c } + @handler.end_mapping + end + + def visit_Psych_Nodes_Alias o + @handler.alias o.anchor + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/visitors/json_tree.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/visitors/json_tree.rb new file mode 100644 index 00000000..979fc100 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/visitors/json_tree.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true +require_relative '../json/ruby_events' + +module Psych + module Visitors + class JSONTree < YAMLTree + include Psych::JSON::RubyEvents + + def self.create options = {} + emitter = Psych::JSON::TreeBuilder.new + class_loader = ClassLoader.new + ss = ScalarScanner.new class_loader + new(emitter, ss, options) + end + + def accept target + if target.respond_to?(:encode_with) + dump_coder target + else + send(@dispatch_cache[target.class], target) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/visitors/to_ruby.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/visitors/to_ruby.rb new file mode 100644 index 00000000..580a74e9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/visitors/to_ruby.rb @@ -0,0 +1,475 @@ +# frozen_string_literal: true +require_relative '../scalar_scanner' +require_relative '../class_loader' +require_relative '../exception' + +unless defined?(Regexp::NOENCODING) + Regexp::NOENCODING = 32 +end + +module Psych + module Visitors + ### + # This class walks a YAML AST, converting each node to Ruby + class ToRuby < Psych::Visitors::Visitor + def self.create(symbolize_names: false, freeze: false, strict_integer: false) + class_loader = ClassLoader.new + scanner = ScalarScanner.new class_loader, strict_integer: strict_integer + new(scanner, class_loader, symbolize_names: symbolize_names, freeze: freeze) + end + + attr_reader :class_loader + + def initialize ss, class_loader, symbolize_names: false, freeze: false + super() + @st = {} + @ss = ss + @load_tags = Psych.load_tags + @domain_types = Psych.domain_types + @class_loader = class_loader + @symbolize_names = symbolize_names + @freeze = freeze + end + + def accept target + result = super + + unless @domain_types.empty? || !target.tag + key = target.tag.sub(/^[!\/]*/, '').sub(/(,\d+)\//, '\1:') + key = "tag:#{key}" unless key.match?(/^(?:tag:|x-private)/) + + if @domain_types.key? key + value, block = @domain_types[key] + result = block.call value, result + end + end + + result = deduplicate(result).freeze if @freeze + result + end + + def deserialize o + if klass = resolve_class(@load_tags[o.tag]) + instance = klass.allocate + + if instance.respond_to?(:init_with) + coder = Psych::Coder.new(o.tag) + coder.scalar = o.value + instance.init_with coder + end + + return instance + end + + return o.value if o.quoted + return @ss.tokenize(o.value) unless o.tag + + case o.tag + when '!binary', 'tag:yaml.org,2002:binary' + o.value.unpack('m').first + when /^!(?:str|ruby\/string)(?::(.*))?$/, 'tag:yaml.org,2002:str' + klass = resolve_class($1) + if klass + klass.allocate.replace o.value + else + o.value + end + when '!ruby/object:BigDecimal' + require 'bigdecimal' unless defined? BigDecimal + class_loader.big_decimal._load o.value + when "!ruby/object:DateTime" + class_loader.date_time + t = @ss.parse_time(o.value) + DateTime.civil(*t.to_a[0, 6].reverse, Rational(t.utc_offset, 86400)) + + (t.subsec/86400) + when '!ruby/encoding' + ::Encoding.find o.value + when "!ruby/object:Complex" + class_loader.complex + Complex(o.value) + when "!ruby/object:Rational" + class_loader.rational + Rational(o.value) + when "!ruby/class", "!ruby/module" + resolve_class o.value + when "tag:yaml.org,2002:float", "!float" + Float(@ss.tokenize(o.value)) + when "!ruby/regexp" + klass = class_loader.regexp + matches = /^\/(?.*)\/(?[mixn]*)$/m.match(o.value) + source = matches[:string].gsub('\/', '/') + options = 0 + lang = nil + matches[:options].each_char do |option| + case option + when 'x' then options |= Regexp::EXTENDED + when 'i' then options |= Regexp::IGNORECASE + when 'm' then options |= Regexp::MULTILINE + when 'n' then options |= Regexp::NOENCODING + else lang = option + end + end + klass.new(*[source, options, lang].compact) + when "!ruby/range" + klass = class_loader.range + args = o.value.split(/([.]{2,3})/, 2).map { |s| + accept Nodes::Scalar.new(s) + } + args.push(args.delete_at(1) == '...') + klass.new(*args) + when /^!ruby\/sym(bol)?:?(.*)?$/ + class_loader.symbolize o.value + else + @ss.tokenize o.value + end + end + private :deserialize + + def visit_Psych_Nodes_Scalar o + register o, deserialize(o) + end + + def visit_Psych_Nodes_Sequence o + if klass = resolve_class(@load_tags[o.tag]) + instance = klass.allocate + + if instance.respond_to?(:init_with) + coder = Psych::Coder.new(o.tag) + coder.seq = o.children.map { |c| accept c } + instance.init_with coder + end + + return instance + end + + case o.tag + when nil + register_empty(o) + when '!omap', 'tag:yaml.org,2002:omap' + map = register(o, Psych::Omap.new) + o.children.each { |a| + map[accept(a.children.first)] = accept a.children.last + } + map + when /^!(?:seq|ruby\/array):(.*)$/ + klass = resolve_class($1) + list = register(o, klass.allocate) + o.children.each { |c| list.push accept c } + list + else + register_empty(o) + end + end + + def visit_Psych_Nodes_Mapping o + if @load_tags[o.tag] + return revive(resolve_class(@load_tags[o.tag]), o) + end + return revive_hash(register(o, {}), o) unless o.tag + + case o.tag + when /^!ruby\/struct:?(.*)?$/ + klass = resolve_class($1) if $1 + + if klass + s = register(o, klass.allocate) + + members = {} + struct_members = s.members.map { |x| class_loader.symbolize x } + o.children.each_slice(2) do |k,v| + member = accept(k) + value = accept(v) + if struct_members.include?(class_loader.symbolize(member)) + s.send("#{member}=", value) + else + members[member.to_s.sub(/^@/, '')] = value + end + end + init_with(s, members, o) + else + klass = class_loader.struct + members = o.children.map { |c| accept c } + h = Hash[*members] + s = klass.new(*h.map { |k,v| + class_loader.symbolize k + }).new(*h.map { |k,v| v }) + register(o, s) + s + end + + when /^!ruby\/data(-with-ivars)?(?::(.*))?$/ + data = register(o, resolve_class($2).allocate) if $2 + members = {} + + if $1 # data-with-ivars + ivars = {} + o.children.each_slice(2) do |type, vars| + case accept(type) + when 'members' + revive_data_members(members, vars) + data ||= allocate_anon_data(o, members) + when 'ivars' + revive_hash(ivars, vars) + end + end + ivars.each do |ivar, v| + data.instance_variable_set ivar, v + end + else + revive_data_members(members, o) + end + data ||= allocate_anon_data(o, members) + init_struct(data, **members) + data.freeze + data + + when /^!ruby\/object:?(.*)?$/ + name = $1 || 'Object' + + if name == 'Complex' + class_loader.complex + h = Hash[*o.children.map { |c| accept c }] + register o, Complex(h['real'], h['image']) + elsif name == 'Rational' + class_loader.rational + h = Hash[*o.children.map { |c| accept c }] + register o, Rational(h['numerator'], h['denominator']) + elsif name == 'Hash' + revive_hash(register(o, {}), o) + else + obj = revive((resolve_class(name) || class_loader.object), o) + obj + end + + when /^!(?:str|ruby\/string)(?::(.*))?$/, 'tag:yaml.org,2002:str' + klass = resolve_class($1) + members = {} + string = nil + + o.children.each_slice(2) do |k,v| + key = accept k + value = accept v + + if key == 'str' + if klass + string = klass.allocate.replace value + else + string = value + end + register(o, string) + else + members[key] = value + end + end + init_with(string, members.map { |k,v| [k.to_s.sub(/^@/, ''),v] }, o) + when /^!ruby\/array:(.*)$/ + klass = resolve_class($1) + list = register(o, klass.allocate) + + members = Hash[o.children.map { |c| accept c }.each_slice(2).to_a] + list.replace members['internal'] + + members['ivars'].each do |ivar, v| + list.instance_variable_set ivar, v + end + list + + when '!ruby/range' + klass = class_loader.range + h = Hash[*o.children.map { |c| accept c }] + register o, klass.new(h['begin'], h['end'], h['excl']) + + when /^!ruby\/exception:?(.*)?$/ + h = Hash[*o.children.map { |c| accept c }] + + e = build_exception((resolve_class($1) || class_loader.exception), + h.delete('message')) + + e.set_backtrace h.delete('backtrace') if h.key? 'backtrace' + init_with(e, h, o) + + when '!set', 'tag:yaml.org,2002:set' + set = class_loader.psych_set.new + @st[o.anchor] = set if o.anchor + o.children.each_slice(2) do |k,v| + set[accept(k)] = accept(v) + end + set + + when /^!ruby\/hash-with-ivars(?::(.*))?$/ + hash = $1 ? resolve_class($1).allocate : {} + register o, hash + o.children.each_slice(2) do |key, value| + case key.value + when 'elements' + revive_hash hash, value + when 'ivars' + value.children.each_slice(2) do |k,v| + hash.instance_variable_set accept(k), accept(v) + end + end + end + hash + + when /^!map:(.*)$/, /^!ruby\/hash:(.*)$/ + revive_hash register(o, resolve_class($1).allocate), o + + when '!omap', 'tag:yaml.org,2002:omap' + map = register(o, class_loader.psych_omap.new) + o.children.each_slice(2) do |l,r| + map[accept(l)] = accept r + end + map + + when /^!ruby\/marshalable:(.*)$/ + name = $1 + klass = resolve_class(name) + obj = register(o, klass.allocate) + + if obj.respond_to?(:init_with) + init_with(obj, revive_hash({}, o), o) + elsif obj.respond_to?(:marshal_load) + marshal_data = o.children.map(&method(:accept)) + obj.marshal_load(marshal_data) + obj + else + raise ArgumentError, "Cannot deserialize #{name}" + end + + else + revive_hash(register(o, {}), o) + end + end + + def visit_Psych_Nodes_Document o + accept o.root + end + + def visit_Psych_Nodes_Stream o + o.children.map { |c| accept c } + end + + def visit_Psych_Nodes_Alias o + @st.fetch(o.anchor) { raise AnchorNotDefined, o.anchor } + end + + private + + def register node, object + @st[node.anchor] = object if node.anchor + object + end + + def register_empty object + list = register(object, []) + object.children.each { |c| list.push accept c } + list + end + + def allocate_anon_data node, members + klass = class_loader.data.define(*members.keys) + register(node, klass.allocate) + end + + def revive_data_members hash, o + o.children.each_slice(2) do |k,v| + name = accept(k) + value = accept(v) + hash[class_loader.symbolize(name)] = value + end + hash + end + + def revive_hash hash, o, tagged= false + o.children.each_slice(2) { |k,v| + key = accept(k) + val = accept(v) + + if key == '<<' && k.tag != "tag:yaml.org,2002:str" + case v + when Nodes::Alias, Nodes::Mapping + begin + hash.merge! val + rescue TypeError + hash[key] = val + end + when Nodes::Sequence + begin + h = {} + val.reverse_each do |value| + h.merge! value + end + hash.merge! h + rescue TypeError + hash[key] = val + end + else + hash[key] = val + end + else + if !tagged && @symbolize_names && key.is_a?(String) + key = key.to_sym + elsif !@freeze + key = deduplicate(key) + end + + hash[key] = val + end + + } + hash + end + + if RUBY_VERSION < '2.7' + def deduplicate key + if key.is_a?(String) + # It is important to untaint the string, otherwise it won't + # be deduplicated into an fstring, but simply frozen. + -(key.untaint) + else + key + end + end + else + def deduplicate key + if key.is_a?(String) + -key + else + key + end + end + end + + def merge_key hash, key, val + end + + def revive klass, node + s = register(node, klass.allocate) + init_with(s, revive_hash({}, node, true), node) + end + + def init_with o, h, node + c = Psych::Coder.new(node.tag) + c.map = h + + if o.respond_to?(:init_with) + o.init_with c + else + h.each { |k,v| o.instance_variable_set(:"@#{k}", v) } + end + o + end + + # Convert +klassname+ to a Class + def resolve_class klassname + class_loader.load klassname + end + end + + class NoAliasRuby < ToRuby + def visit_Psych_Nodes_Alias o + raise AliasesNotEnabled + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/visitors/visitor.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/visitors/visitor.rb new file mode 100644 index 00000000..21052aa6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/visitors/visitor.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true +module Psych + module Visitors + class Visitor + def accept target + visit target + end + + private + + # @api private + def self.dispatch_cache + Hash.new do |hash, klass| + hash[klass] = :"visit_#{klass.name.gsub('::', '_')}" + end.compare_by_identity + end + + if defined?(Ractor) + def dispatch + @dispatch_cache ||= (Ractor.current[:Psych_Visitors_Visitor] ||= Visitor.dispatch_cache) + end + else + DISPATCH = dispatch_cache + def dispatch + DISPATCH + end + end + + def visit target + send dispatch[target.class], target + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/visitors/yaml_tree.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/visitors/yaml_tree.rb new file mode 100644 index 00000000..b6c86f4c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/visitors/yaml_tree.rb @@ -0,0 +1,626 @@ +# frozen_string_literal: true +require_relative '../tree_builder' +require_relative '../scalar_scanner' +require_relative '../class_loader' + +module Psych + module Visitors + ### + # YAMLTree builds a YAML ast given a Ruby object. For example: + # + # builder = Psych::Visitors::YAMLTree.new + # builder << { :foo => 'bar' } + # builder.tree # => # v } + @emitter.end_sequence + end + + def visit_Encoding o + tag = "!ruby/encoding" + @emitter.scalar o.name, nil, tag, false, false, Nodes::Scalar::ANY + end + + def visit_Object o + tag = Psych.dump_tags[o.class] + unless tag + klass = o.class == Object ? nil : o.class.name + tag = ['!ruby/object', klass].compact.join(':') + end + + map = @emitter.start_mapping(nil, tag, false, Nodes::Mapping::BLOCK) + register(o, map) + + dump_ivars o + @emitter.end_mapping + end + + alias :visit_Delegator :visit_Object + + def visit_Data o + ivars = o.instance_variables + if ivars.empty? + tag = ['!ruby/data', o.class.name].compact.join(':') + register o, @emitter.start_mapping(nil, tag, false, Nodes::Mapping::BLOCK) + o.members.each do |member| + @emitter.scalar member.to_s, nil, nil, true, false, Nodes::Scalar::ANY + accept o.send member + end + @emitter.end_mapping + + else + tag = ['!ruby/data-with-ivars', o.class.name].compact.join(':') + node = @emitter.start_mapping(nil, tag, false, Psych::Nodes::Mapping::BLOCK) + register(o, node) + + # Dump the members + accept 'members' + @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK + o.members.each do |member| + @emitter.scalar member.to_s, nil, nil, true, false, Nodes::Scalar::ANY + accept o.send member + end + @emitter.end_mapping + + # Dump the ivars + accept 'ivars' + @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK + ivars.each do |ivar| + accept ivar.to_s + accept o.instance_variable_get ivar + end + @emitter.end_mapping + + @emitter.end_mapping + end + end unless RUBY_VERSION < "3.2" + + def visit_Struct o + tag = ['!ruby/struct', o.class.name].compact.join(':') + + register o, @emitter.start_mapping(nil, tag, false, Nodes::Mapping::BLOCK) + o.members.each do |member| + @emitter.scalar member.to_s, nil, nil, true, false, Nodes::Scalar::ANY + accept o[member] + end + + dump_ivars o + + @emitter.end_mapping + end + + def visit_Exception o + dump_exception o, o.message.to_s + end + + def visit_NameError o + dump_exception o, o.message.to_s + end + + def visit_Regexp o + register o, @emitter.scalar(o.inspect, nil, '!ruby/regexp', false, false, Nodes::Scalar::ANY) + end + + def visit_Date o + formatted = format_date o + register o, @emitter.scalar(formatted, nil, nil, true, false, Nodes::Scalar::ANY) + end + + def visit_DateTime o + t = o.italy + formatted = format_time t, t.offset.zero? + tag = '!ruby/object:DateTime' + register o, @emitter.scalar(formatted, nil, tag, false, false, Nodes::Scalar::ANY) + end + + def visit_Time o + formatted = format_time o + register o, @emitter.scalar(formatted, nil, nil, true, false, Nodes::Scalar::ANY) + end + + def visit_Rational o + register o, @emitter.start_mapping(nil, '!ruby/object:Rational', false, Nodes::Mapping::BLOCK) + + [ + 'denominator', o.denominator.to_s, + 'numerator', o.numerator.to_s + ].each do |m| + @emitter.scalar m, nil, nil, true, false, Nodes::Scalar::ANY + end + + @emitter.end_mapping + end + + def visit_Complex o + register o, @emitter.start_mapping(nil, '!ruby/object:Complex', false, Nodes::Mapping::BLOCK) + + ['real', o.real.to_s, 'image', o.imag.to_s].each do |m| + @emitter.scalar m, nil, nil, true, false, Nodes::Scalar::ANY + end + + @emitter.end_mapping + end + + def visit_Integer o + @emitter.scalar o.to_s, nil, nil, true, false, Nodes::Scalar::ANY + end + alias :visit_TrueClass :visit_Integer + alias :visit_FalseClass :visit_Integer + + def visit_Float o + if o.nan? + @emitter.scalar '.nan', nil, nil, true, false, Nodes::Scalar::ANY + elsif o.infinite? + @emitter.scalar((o.infinite? > 0 ? '.inf' : '-.inf'), + nil, nil, true, false, Nodes::Scalar::ANY) + else + @emitter.scalar o.to_s, nil, nil, true, false, Nodes::Scalar::ANY + end + end + + def visit_BigDecimal o + @emitter.scalar o._dump, nil, '!ruby/object:BigDecimal', false, false, Nodes::Scalar::ANY + end + + def visit_String o + plain = true + quote = true + style = Nodes::Scalar::PLAIN + tag = nil + + if binary?(o) + o = [o].pack('m0') + tag = '!binary' # FIXME: change to below when syck is removed + #tag = 'tag:yaml.org,2002:binary' + style = Nodes::Scalar::LITERAL + plain = false + quote = false + elsif o.match?(/\n(?!\Z)/) # match \n except blank line at the end of string + style = Nodes::Scalar::LITERAL + elsif o == '<<' + style = Nodes::Scalar::SINGLE_QUOTED + tag = 'tag:yaml.org,2002:str' + plain = false + quote = false + elsif o == 'y' || o == 'Y' || o == 'n' || o == 'N' + style = Nodes::Scalar::DOUBLE_QUOTED + elsif @line_width && o.length > @line_width + style = Nodes::Scalar::FOLDED + elsif o.match?(/^[^[:word:]][^"]*$/) + style = Nodes::Scalar::DOUBLE_QUOTED + elsif not String === @ss.tokenize(o) or /\A0[0-7]*[89]/.match?(o) + style = Nodes::Scalar::SINGLE_QUOTED + end + + is_primitive = o.class == ::String + ivars = is_primitive ? [] : o.instance_variables + + if ivars.empty? + unless is_primitive + tag = "!ruby/string:#{o.class}" + plain = false + quote = false + end + @emitter.scalar o, nil, tag, plain, quote, style + else + maptag = '!ruby/string'.dup + maptag << ":#{o.class}" unless o.class == ::String + + register o, @emitter.start_mapping(nil, maptag, false, Nodes::Mapping::BLOCK) + @emitter.scalar 'str', nil, nil, true, false, Nodes::Scalar::ANY + @emitter.scalar o, nil, tag, plain, quote, style + + dump_ivars o + + @emitter.end_mapping + end + end + + def visit_Module o + raise TypeError, "can't dump anonymous module: #{o}" unless o.name + register o, @emitter.scalar(o.name, nil, '!ruby/module', false, false, Nodes::Scalar::SINGLE_QUOTED) + end + + def visit_Class o + raise TypeError, "can't dump anonymous class: #{o}" unless o.name + register o, @emitter.scalar(o.name, nil, '!ruby/class', false, false, Nodes::Scalar::SINGLE_QUOTED) + end + + def visit_Range o + register o, @emitter.start_mapping(nil, '!ruby/range', false, Nodes::Mapping::BLOCK) + ['begin', o.begin, 'end', o.end, 'excl', o.exclude_end?].each do |m| + accept m + end + @emitter.end_mapping + end + + def visit_Hash o + if o.class == ::Hash + register(o, @emitter.start_mapping(nil, nil, true, Psych::Nodes::Mapping::BLOCK)) + o.each do |k,v| + accept(@stringify_names && Symbol === k ? k.to_s : k) + accept v + end + @emitter.end_mapping + else + visit_hash_subclass o + end + end + + def visit_Psych_Set o + register(o, @emitter.start_mapping(nil, '!set', false, Psych::Nodes::Mapping::BLOCK)) + + o.each do |k,v| + accept(@stringify_names && Symbol === k ? k.to_s : k) + accept v + end + + @emitter.end_mapping + end + + def visit_Array o + if o.class == ::Array + visit_Enumerator o + else + visit_array_subclass o + end + end + + def visit_Enumerator o + register o, @emitter.start_sequence(nil, nil, true, Nodes::Sequence::BLOCK) + o.each { |c| accept c } + @emitter.end_sequence + end + + def visit_NilClass o + @emitter.scalar('', nil, 'tag:yaml.org,2002:null', true, false, Nodes::Scalar::ANY) + end + + def visit_Symbol o + if o.empty? + @emitter.scalar "", nil, '!ruby/symbol', false, false, Nodes::Scalar::ANY + else + @emitter.scalar ":#{o}", nil, nil, true, false, Nodes::Scalar::ANY + end + end + + def visit_BasicObject o + tag = Psych.dump_tags[o.class] + tag ||= "!ruby/marshalable:#{o.class.name}" + + map = @emitter.start_mapping(nil, tag, false, Nodes::Mapping::BLOCK) + register(o, map) + + o.marshal_dump.each(&method(:accept)) + + @emitter.end_mapping + end + + private + + def binary? string + string.encoding == Encoding::ASCII_8BIT && !string.ascii_only? + end + + def visit_array_subclass o + tag = "!ruby/array:#{o.class}" + ivars = o.instance_variables + if ivars.empty? + node = @emitter.start_sequence(nil, tag, false, Nodes::Sequence::BLOCK) + register o, node + o.each { |c| accept c } + @emitter.end_sequence + else + node = @emitter.start_mapping(nil, tag, false, Nodes::Sequence::BLOCK) + register o, node + + # Dump the internal list + accept 'internal' + @emitter.start_sequence(nil, nil, true, Nodes::Sequence::BLOCK) + o.each { |c| accept c } + @emitter.end_sequence + + # Dump the ivars + accept 'ivars' + @emitter.start_mapping(nil, nil, true, Nodes::Sequence::BLOCK) + ivars.each do |ivar| + accept ivar + accept o.instance_variable_get ivar + end + @emitter.end_mapping + + @emitter.end_mapping + end + end + + def visit_hash_subclass o + ivars = o.instance_variables + if ivars.any? + tag = "!ruby/hash-with-ivars:#{o.class}" + node = @emitter.start_mapping(nil, tag, false, Psych::Nodes::Mapping::BLOCK) + register(o, node) + + # Dump the ivars + accept 'ivars' + @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK + o.instance_variables.each do |ivar| + accept ivar + accept o.instance_variable_get ivar + end + @emitter.end_mapping + + # Dump the elements + accept 'elements' + @emitter.start_mapping nil, nil, true, Nodes::Mapping::BLOCK + o.each do |k,v| + accept k + accept v + end + @emitter.end_mapping + + @emitter.end_mapping + else + tag = "!ruby/hash:#{o.class}" + node = @emitter.start_mapping(nil, tag, false, Psych::Nodes::Mapping::BLOCK) + register(o, node) + o.each do |k,v| + accept k + accept v + end + @emitter.end_mapping + end + end + + def dump_list o + end + + def dump_exception o, msg + tag = ['!ruby/exception', o.class.name].join ':' + + @emitter.start_mapping nil, tag, false, Nodes::Mapping::BLOCK + + if msg + @emitter.scalar 'message', nil, nil, true, false, Nodes::Scalar::ANY + accept msg + end + + @emitter.scalar 'backtrace', nil, nil, true, false, Nodes::Scalar::ANY + accept o.backtrace + + dump_ivars o + + @emitter.end_mapping + end + + def format_time time, utc = time.utc? + if utc + time.strftime("%Y-%m-%d %H:%M:%S.%9N Z") + else + time.strftime("%Y-%m-%d %H:%M:%S.%9N %:z") + end + end + + def format_date date + date.strftime("%Y-%m-%d") + end + + def register target, yaml_obj + @st.register target, yaml_obj + yaml_obj + end + + def dump_coder o + @coders << o + tag = Psych.dump_tags[o.class] + unless tag + klass = o.class == Object ? nil : o.class.name + tag = ['!ruby/object', klass].compact.join(':') + end + + c = Psych::Coder.new(tag) + o.encode_with(c) + emit_coder c, o + end + + def emit_coder c, o + case c.type + when :scalar + @emitter.scalar c.scalar, nil, c.tag, c.tag.nil?, false, c.style + when :seq + @emitter.start_sequence nil, c.tag, c.tag.nil?, c.style + c.seq.each do |thing| + accept thing + end + @emitter.end_sequence + when :map + register o, @emitter.start_mapping(nil, c.tag, c.implicit, c.style) + c.map.each do |k,v| + accept k + accept v + end + @emitter.end_mapping + when :object + accept c.object + end + end + + def dump_ivars target + target.instance_variables.each do |iv| + @emitter.scalar("#{iv.to_s.sub(/^@/, '')}", nil, nil, true, false, Nodes::Scalar::ANY) + accept target.instance_variable_get(iv) + end + end + end + + class RestrictedYAMLTree < YAMLTree + DEFAULT_PERMITTED_CLASSES = { + TrueClass => true, + FalseClass => true, + NilClass => true, + Integer => true, + Float => true, + String => true, + Array => true, + Hash => true, + }.compare_by_identity.freeze + + def initialize emitter, ss, options + super + @permitted_classes = DEFAULT_PERMITTED_CLASSES.dup + Array(options[:permitted_classes]).each do |klass| + @permitted_classes[klass] = true + end + @permitted_symbols = {}.compare_by_identity + Array(options[:permitted_symbols]).each do |symbol| + @permitted_symbols[symbol] = true + end + @aliases = options.fetch(:aliases, false) + end + + def accept target + if !@aliases && @st.key?(target) + raise BadAlias, "Tried to dump an aliased object" + end + + unless Symbol === target || @permitted_classes[target.class] + raise DisallowedClass.new('dump', target.class.name || target.class.inspect) + end + + super + end + + def visit_Symbol sym + unless @permitted_classes[Symbol] || @permitted_symbols[sym] + raise DisallowedClass.new('dump', "Symbol(#{sym.inspect})") + end + + super + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/y.rb b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/y.rb new file mode 100644 index 00000000..e857953c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/psych-5.2.6/lib/psych/y.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true +module Kernel + ### + # An alias for Psych.dump_stream meant to be used with IRB. + def y *objects + puts Psych.dump_stream(*objects) + end + private :y +end + diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/.yardopts b/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/.yardopts new file mode 100644 index 00000000..0a782de2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/.yardopts @@ -0,0 +1 @@ +--title 'Ruby Public Suffix API Documentation' diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/CHANGELOG.md b/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/CHANGELOG.md new file mode 100644 index 00000000..4166f72c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/CHANGELOG.md @@ -0,0 +1,498 @@ +# Changelog + +This project uses [Semantic Versioning 2.0.0](https://semver.org/). + + +## 6.0.2 + +### Changed + +- Updated definitions. + + +## 6.0.1 + +### Changed + +- Updated definitions. + + +## 6.0.0 + +Same as 5.1.0. Re-releasing as a major version change due to a major ruby version requirement change. + +### Changed + +- Updated definitions. +- Minimum Ruby version is 3.0 + + +## 5.1.1 + +No significant changes. Releasing a mini version to address 5.1.0 release with major ruby requirement change (GH-315). + + +## 5.1.0 + +### Changed + +- Updated definitions. +- Minimum Ruby version is 3.0 + + +## 5.0.5 + +### Changed + +- Updated definitions. + + +## 5.0.4 + +### Changed + +- Reduced .gem file size (GH-258). [Thanks @ybiquitous] +- Updated definitions. + + +## 5.0.3 + +### Fixed + +- Fixed automated release workflow. + + +## 5.0.2 + +### Changed + +- Updated definitions. + + +## 5.0.1 + +### Changed + +- Updated definitions. + + +## 5.0.0 + +### Changed + +- Minimum Ruby version is 2.6 +- Updated definitions. + + +## 4.0.7 + +### Fixes + +- Fixed YARD rake task (GH-179) + +### Changed + +- Updated definitions. + + +## 4.0.6 + +### Changed + +- Updated definitions. + + +## 4.0.5 + +### Changed + +- Updated definitions. + + +## 4.0.4 + +### Changed + +- Updated definitions. + + +## 4.0.3 + +### Fixed + +- Fixed 2.7 deprecations and warnings (GH-167). [Thanks @BrianHawley] + + +## 4.0.2 + +### Changed + +- Updated definitions. + + +## 4.0.1 + +### Changed + +- Updated definitions. + + +## 4.0.0 + +### Changed + +- Minimum Ruby version is 2.3 + + +## Release 3.1.1 + +- CHANGED: Updated definitions. +- CHANGED: Rolled back support for Ruby 2.3 (GH-161, GH-162) + +IMPORTANT: 3.x is the latest version compatible with Ruby 2.1 and Ruby 2.2. + + +## Release 3.1.0 + +- CHANGED: Updated definitions. +- CHANGED: Minimum Ruby version is 2.3 +- CHANGED: Upgraded to Bundler 2.x + + +## Release 3.0.3 + +- CHANGED: Updated definitions. + + +## Release 3.0.2 + +- CHANGED: Updated definitions. + + +## Release 3.0.1 + +- CHANGED: Updated definitions. +- CHANGED: Improve performance and avoid allocation (GH-146). [Thanks @robholland] + + +## Release 3.0.0 + +This new version includes a major redesign of the library internals, with the goal to drastically +improve the lookup time while reducing storage space. + +For this reason, several public methods that are no longer applicable have been deprecated +and/or removed. You can find more information at GH-133. + +- CHANGED: Updated definitions. +- CHANGED: Dropped support for Ruby < 2.1 +- CHANGED: `PublicSuffix::List#rules` is now protected. You should not rely on it as the internal rule representation is subject to change to optimize performances. +- CHANGED: Removed `PublicSuffix::List.clear`, it was an unnecessary accessor method. Use `PublicSuffix::List.default = nil` if you **really** need to reset the default list. You shouldn't. +- CHANGED: `PublicSuffix::List#select` is now private. You should not use it, instead use `PublicSuffix::List#find`. +- CHANGED: `PublicSuffix::List` no longer implements Enumerable. Instead, use `#each` to loop over, or get an Enumerator. +- CHANGED: Redesigned internal list storage and lookup algorithm to achieve O(1) lookup time (see GH-133). + + +## Release 2.0.5 + +- CHANGED: Updated definitions. +- CHANGED: Initialization performance improvements (GH-128). [Thanks @casperisfine] + + +## Release 2.0.4 + +- FIXED: Fix a bug that caused the GEM to be published with the wrong version number in the gemspec (GH-121). + +- CHANGED: Updated definitions. + + +## Release 2.0.3 + +- CHANGED: Updated definitions. + + +## Release 2.0.2 + +- CHANGED: Updated definitions. + + +## Release 2.0.1 + +- FIXED: Fix bug that prevented .valid? to reset the default rule + + +## Release 2.0.0 + +- NEW: Added PublicSuffix.domain # => sld.tld +- NEW: Added the ability to disable the use of private domains either at runtime, in addition to the ability to not load the private domains section when reading the list (`private_domains: false`). This feature also superseded the `private_domains` class-level attribute, that is no longer available. + +- CHANGED: Considerable performance improvements (GH-92) +- CHANGED: Updated definitions. +- CHANGED: Removed deprecated PublicSuffix::InvalidDomain exception +- CHANGED: If the suffix is now listed, then the prevaling rule is "*" as defined by the PSL algorithm (GH-91) +- CHANGED: Input validation is performed only if you call `PublicSuffix.parse` or `PublicSuffix.list` +- CHANGED: Input with leading dot is invalid per PSL acceptance tests +- CHANGED: Removed `private_domains` class-level attribute. It is replaced by the `private_domains: false` option in the list parse method. +- CHANGED: The default list now assumes you use UTF-8 for reading the input (GH-94), + +- REMOVED: Removed futile utility helpers such as `Domain#rule`, `Domain#is_a_domain?`, `Domain#is_a_subdomain?`, `Domain#valid?`. You can easily obtain the same result by having a custom method that reconstructs the logic, and/or calling `PublicSuffix.{domain|parse}(domain.to_s)`. + + +## Release 1.5.3 + +- FIXED: Don't duplicate rule indices when creating index (GH-77). [Thanks @ags] + +- CHANGED: Updated definitions. + + +## Release 1.5.2 + +- CHANGED: Updated definitions. + + +## Release 1.5.1 + +- FIXED: Ignore case for parsing and validating (GH-62) + +- CHANGED: Updated definitions. + + +## Release 1.5.0 + +- CHANGED: Dropped support for Ruby < 2.0 + +- CHANGED: Updated definitions. + + +## Release 1.4.6 + +- CHANGED: Updated definitions. + + +## Release 1.4.5 + +- CHANGED: Updated definitions. + + +## Release 1.4.4 + +- CHANGED: Updated definitions. + + +## Release 1.4.3 + +- CHANGED: Updated definitions. + + +## Release 1.4.2 + +- CHANGED: Updated definitions. + + +## Release 1.4.1 + +- CHANGED: Updated definitions. + + +## Release 1.4.0 + +- CHANGED: Moved the definitions in the lib folder. + +- CHANGED: Updated definitions. + + +## Release 1.3.3 + +- CHANGED: Updated definitions. + + +## Release 1.3.2 + +- CHANGED: Updated definitions. + + +## Release 1.3.1 + +- CHANGED: Updated definitions. + + +## Release 1.3.0 + +- NEW: Ability to skip Private Domains (GH-28). [Thanks @rb2k] + +- CHANGED: Updated definitions. + + +## Release 1.2.1 + +- CHANGED: Updated definitions. + + +## Release 1.2.0 + +- NEW: Allow a custom List on `PublicSuffix.parse` (GH-26). [Thanks @itspriddle] + +- FIXED: PublicSuffix.parse and PublicSuffix.valid? crashes when input is nil (GH-20). + +- CHANGED: Updated definitions. + + +## Release 1.1.3 + +- CHANGED: Updated definitions. + + +## Release 1.1.2 + +- CHANGED: Updated definitions. + + +## Release 1.1.1 + +- CHANGED: Updated definitions. + + +## Release 1.1.0 + +- FIXED: #valid? and #parse consider URIs as valid domains (GH-15) + +- CHANGED: Updated definitions. + +- CHANGED: Removed deprecatd PublicSuffixService::RuleList. + + +## Release 1.0.0 + +- CHANGED: Updated definitions. + + +## Release 1.0.0.rc1 + +The library is now known as PublicSuffix. + + +## Release 0.9.1 + +- CHANGED: Renamed PublicSuffixService::RuleList to PublicSuffixService::List. + +- CHANGED: Renamed PublicSuffixService::List#list to PublicSuffixService::List#rules. + +- CHANGED: Renamed PublicSuffixService to PublicSuffix. + +- CHANGED: Updated definitions. + + +## Release 0.9.0 + +- CHANGED: Minimum Ruby version increased to Ruby 1.8.7. + +- CHANGED: rake/gempackagetask is deprecated. Use rubygems/package_task instead. + + +## Release 0.8.4 + +- FIXED: Reverted bugfix for issue #12 for Ruby 1.8.6. + This is the latest version compatible with Ruby 1.8.6. + + +## Release 0.8.3 + +- FIXED: Fixed ArgumentError: invalid byte sequence in US-ASCII with Ruby 1.9.2 (#12). + +- CHANGED: Updated definitions (#11). + +- CHANGED: Renamed definitions.txt to definitions.dat. + + +## Release 0.8.2 + +- NEW: Added support for rubygems-test. + +- CHANGED: Integrated Bundler. + +- CHANGED: Updated definitions. + + +## Release 0.8.1 + +- FIXED: The files in the release 0.8.0 have wrong permission 600 and can't be loaded (#10). + + +## Release 0.8.0 + +- CHANGED: Update public suffix list to d1a5599b49fa 2010-10-25 15:10 +0100 (#9) + +- NEW: Add support for Fully Qualified Domain Names (#7) + + +## Release 0.7.0 + +- CHANGED: Using YARD to document the code instead of RDoc. + +- FIXED: RuleList cache is not recreated when a new rule is appended to the list (#6) + +- FIXED: PublicSuffixService.valid? should return false if the domain is not defined or not allowed (#4, #5) + + +## Release 0.6.0 + +- NEW: PublicSuffixService.parse raises DomainNotAllowed when trying to parse a domain name + which exists, but is not allowed by the current definition list (#3) + + PublicSuffixService.parse("nic.do") + # => PublicSuffixService::DomainNotAllowed + +- CHANGED: Renamed PublicSuffixService::InvalidDomain to PublicSuffixService::DomainInvalid + + +## Release 0.5.2 + +- CHANGED: Update public suffix list to 248ea690d671 2010-09-16 18:02 +0100 + + +## Release 0.5.1 + +- CHANGED: Update public suffix list to 14dc66dd53c1 2010-09-15 17:09 +0100 + + +## Release 0.5.0 + +- CHANGED: Improve documentation for Domain#domain and Domain#subdomain (#1). + +- CHANGED: Performance improvements (#2). + + +## Release 0.4.0 + +- CHANGED: Rename library from DomainName to PublicSuffixService to reduce the probability of name conflicts. + + +## Release 0.3.1 + +- Deprecated DomainName library. + + +## Release 0.3.0 + +- CHANGED: DomainName#domain and DomainName#subdomain are no longer alias of Domain#sld and Domain#tld. + +- CHANGED: Removed DomainName#labels and decoupled Rule from DomainName. + +- CHANGED: DomainName#valid? no longer instantiates new DomainName objects. This means less overhead. + +- CHANGED: Refactoring the entire DomainName API. Removed the internal on-the-fly parsing. Added a bunch of new methods to check and validate the DomainName. + + +## Release 0.2.0 + +- NEW: DomainName#valid? + +- NEW: DomainName#parse and DomainName#parse! + +- NEW: DomainName#valid_domain? and DomainName#valid_subdomain? + +- CHANGED: Make sure RuleList lookup is only performed once. + + +## Release 0.1.0 + +- Initial version diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/LICENSE.txt b/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/LICENSE.txt new file mode 100644 index 00000000..046480ee --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (c) 2009-2025 Simone Carletti + +MIT License + +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 AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/README.md b/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/README.md new file mode 100644 index 00000000..f4cde83a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/README.md @@ -0,0 +1,222 @@ +# Public Suffix for Ruby + +PublicSuffix is a Ruby domain name parser based on the [Public Suffix List](https://publicsuffix.org/). + +[![Build Status](https://github.com/weppos/publicsuffix-ruby/actions/workflows/tests.yml/badge.svg)](https://github.com/weppos/publicsuffix-ruby/actions/workflows/tests.yml) +[![Tidelift dependencies](https://tidelift.com/badges/package/rubygems/public_suffix)](https://tidelift.com/subscription/pkg/rubygems-public-suffix?utm_source=rubygems-public-suffix&utm_medium=referral&utm_campaign=enterprise) + + +## Links + +- [Homepage](https://simonecarletti.com/code/publicsuffix-ruby) +- [Repository](https://github.com/weppos/publicsuffix-ruby) +- [API Documentation](https://rubydoc.info/gems/public_suffix) +- [Introducing the Public Suffix List library for Ruby](https://simonecarletti.com/blog/2010/06/public-suffix-list-library-for-ruby/) + + +## Requirements + +PublicSuffix requires **Ruby >= 3.0**. For an older versions of Ruby use a previous release. + + +## Installation + +You can install the gem manually: + +```shell +gem install public_suffix +``` + +Or use Bundler and define it as a dependency in your `Gemfile`: + +```ruby +gem 'public_suffix' +``` + +## Usage + +Extract the domain out from a name: + +```ruby +PublicSuffix.domain("google.com") +# => "google.com" +PublicSuffix.domain("www.google.com") +# => "google.com" +PublicSuffix.domain("www.google.co.uk") +# => "google.co.uk" +``` + +Parse a domain without subdomains: + +```ruby +domain = PublicSuffix.parse("google.com") +# => # +domain.tld +# => "com" +domain.sld +# => "google" +domain.trd +# => nil +domain.domain +# => "google.com" +domain.subdomain +# => nil +``` + +Parse a domain with subdomains: + +```ruby +domain = PublicSuffix.parse("www.google.com") +# => # +domain.tld +# => "com" +domain.sld +# => "google" +domain.trd +# => "www" +domain.domain +# => "google.com" +domain.subdomain +# => "www.google.com" +``` + +Simple validation example: + +```ruby +PublicSuffix.valid?("google.com") +# => true + +PublicSuffix.valid?("www.google.com") +# => true + +# Explicitly forbidden, it is listed as a private domain +PublicSuffix.valid?("blogspot.com") +# => false + +# Unknown/not-listed TLD domains are valid by default +PublicSuffix.valid?("example.tldnotlisted") +# => true +``` + +Strict validation (without applying the default * rule): + +```ruby +PublicSuffix.valid?("example.tldnotlisted", default_rule: nil) +# => false +``` + + +## Fully Qualified Domain Names + +This library automatically recognizes Fully Qualified Domain Names. A FQDN is a domain name that end with a trailing dot. + +```ruby +# Parse a standard domain name +PublicSuffix.domain("www.google.com") +# => "google.com" + +# Parse a fully qualified domain name +PublicSuffix.domain("www.google.com.") +# => "google.com" +``` + +## Private domains + +This library has support for switching off support for private (non-ICANN). + +```ruby +# Extract a domain including private domains (by default) +PublicSuffix.domain("something.blogspot.com") +# => "something.blogspot.com" + +# Extract a domain excluding private domains +PublicSuffix.domain("something.blogspot.com", ignore_private: true) +# => "blogspot.com" + +# It also works for #parse and #valid? +PublicSuffix.parse("something.blogspot.com", ignore_private: true) +PublicSuffix.valid?("something.blogspot.com", ignore_private: true) +``` + +If you don't care about private domains at all, it's more efficient to exclude them when the list is parsed: + +```ruby +# Disable support for private TLDs +PublicSuffix::List.default = PublicSuffix::List.parse(File.read(PublicSuffix::List::DEFAULT_LIST_PATH), private_domains: false) +# => "blogspot.com" +PublicSuffix.domain("something.blogspot.com") +# => "blogspot.com" +``` + +## Add domain to list + +If you want to manually add a domain to the list just run: + +```ruby +PublicSuffix::List.default << PublicSuffix::Rule.factory('onmicrosoft.com') +``` + +## What is the Public Suffix List? + +The [Public Suffix List](https://publicsuffix.org) is a cross-vendor initiative to provide an accurate list of domain name suffixes. + +The Public Suffix List is an initiative of the Mozilla Project, but is maintained as a community resource. It is available for use in any software, but was originally created to meet the needs of browser manufacturers. + +A "public suffix" is one under which Internet users can directly register names. Some examples of public suffixes are ".com", ".co.uk" and "pvt.k12.wy.us". The Public Suffix List is a list of all known public suffixes. + + +## Why the Public Suffix List is better than any available Regular Expression parser? + +Previously, browsers used an algorithm which basically only denied setting wide-ranging cookies for top-level domains with no dots (e.g. com or org). However, this did not work for top-level domains where only third-level registrations are allowed (e.g. co.uk). In these cases, websites could set a cookie for co.uk which will be passed onto every website registered under co.uk. + +Clearly, this was a security risk as it allowed websites other than the one setting the cookie to read it, and therefore potentially extract sensitive information. + +Since there is no algorithmic method of finding the highest level at which a domain may be registered for a particular top-level domain (the policies differ with each registry), the only method is to create a list of all top-level domains and the level at which domains can be registered. This is the aim of the effective TLD list. + +As well as being used to prevent cookies from being set where they shouldn't be, the list can also potentially be used for other applications where the registry controlled and privately controlled parts of a domain name need to be known, for example when grouping by top-level domains. + +Source: https://wiki.mozilla.org/Public_Suffix_List + +Not convinced yet? Check out [this real world example](https://stackoverflow.com/q/288810/123527). + + +## Does PublicSuffix make requests to Public Suffix List website? + +No. PublicSuffix comes with a bundled list. It does not make any HTTP requests to parse or validate a domain. + + +## Support + +Library documentation is auto-generated from the [README](https://github.com/weppos/publicsuffix-ruby/blob/master/README.md) and the source code, and it's available at https://rubydoc.info/gems/public_suffix. + +- The PublicSuffix bug tracker is here: https://github.com/weppos/publicsuffix-ruby/issues +- The PublicSuffix code repository is here: https://github.com/weppos/publicsuffix-ruby. Contributions are welcome! Please include tests and/or feature coverage for every patch, and create a topic branch for every separate change you make. + +[Consider subscribing to Tidelift which provides Enterprise support for this project](https://tidelift.com/subscription/pkg/rubygems-public-suffix?utm_source=rubygems-public-suffix&utm_medium=referral&utm_campaign=readme) as part of the Tidelift Subscription. Tidelift subscriptions also help the maintainers by funding the project, which in turn allows us to ship releases, bugfixes, and security updates more often. + + +## Security and Vulnerability Reporting + +Full information and description of our security policy please visit [`SECURITY.md`](SECURITY.md) + + +## Changelog + +See the [CHANGELOG.md](CHANGELOG.md) file for details. + + +## License + +Copyright (c) 2009-2025 Simone Carletti. This is Free Software distributed under the MIT license. + +The [Public Suffix List source](https://publicsuffix.org/list/) is subject to the terms of the Mozilla Public License, v. 2.0. + +## Definitions + +tld = Top level domain, this is in reference to the last segment of a domain, sometimes the part that is directly after the "dot" symbol. For example, `mozilla.org`, the `.org` portion is the tld. + +sld = Second level domain, a domain that is directly below a top-level domain. For example, in `https://www.mozilla.org/en-US/`, `mozilla` is the second-level domain of the .org tld. + +trd = Transit routing domain, or known as a subdomain. This is the part of the domain that is before the sld or root domain. For example, in `https://www.mozilla.org/en-US/`, `www` is the trd. + +FQDN = Fully Qualified Domain Names, are domain names that are written with the hostname and the domain name, and include the top-level domain, the format looks like `[hostname].[domain].[tld].` for ex. `[www].[mozilla].[org]`. diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/SECURITY.md b/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/SECURITY.md new file mode 100644 index 00000000..da6e619f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/SECURITY.md @@ -0,0 +1,24 @@ +# Security Policy + +## Supported Versions + +Security updates are provided only for the current minor version. + +If you are using a previous minor version, we recommend to upgrade to the current minor version. This project uses [semantic versioning](https://semver.org/), therefore you can upgrade to a more recent minor version without incurring into breaking changes. + +Exceptionally, we may support previous minor versions upon request if there are significant reasons preventing to immediately switch the latest minor version. + +Older major versions are no longer supported. + + +## Reporting a Vulnerability + +To make a report, please email weppos@weppos.net. + +> [!IMPORTANT] +> Please consider encrypting your report with GPG using the key [0x420da82a989398df](https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x420da82a989398df). + + +## Tracking Security Updates + +Information about security vulnerabilities are published in the [Security Advisories](https://github.com/weppos/publicsuffix-ruby/security/advisories) page. diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/data/list.txt b/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/data/list.txt new file mode 100644 index 00000000..e708fc4f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/data/list.txt @@ -0,0 +1,15791 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +// Please pull this list from, and only from https://publicsuffix.org/list/public_suffix_list.dat, +// rather than any other VCS sites. Pulling from any other URL is not guaranteed to be supported. + +// Instructions on pulling and using this list can be found at https://publicsuffix.org/list/. + +// ===BEGIN ICANN DOMAINS=== + +// ac : http://nic.ac/rules.htm +ac +com.ac +edu.ac +gov.ac +mil.ac +net.ac +org.ac + +// ad : https://www.iana.org/domains/root/db/ad.html +// Confirmed by Amadeu Abril i Abril (CORE) 2024-11-17 +ad + +// ae : https://www.iana.org/domains/root/db/ae.html +ae +ac.ae +co.ae +gov.ae +mil.ae +net.ae +org.ae +sch.ae + +// aero : https://information.aero/registration/policies/dmp +aero +// 2LDs +airline.aero +airport.aero +// 2LDs (currently not accepting registration, seemingly never have) +// As of 2024-07, these are marked as reserved for potential 3LD +// registrations (clause 11 "allocated subdomains" in the 2006 TLD +// policy), but the relevant industry partners have not opened them up +// for registration. Current status can be determined from the TLD's +// policy document: 2LDs that are open for registration must list +// their policy in the TLD's policy. Any 2LD without such a policy is +// not open for registrations. +accident-investigation.aero +accident-prevention.aero +aerobatic.aero +aeroclub.aero +aerodrome.aero +agents.aero +air-surveillance.aero +air-traffic-control.aero +aircraft.aero +airtraffic.aero +ambulance.aero +association.aero +author.aero +ballooning.aero +broker.aero +caa.aero +cargo.aero +catering.aero +certification.aero +championship.aero +charter.aero +civilaviation.aero +club.aero +conference.aero +consultant.aero +consulting.aero +control.aero +council.aero +crew.aero +design.aero +dgca.aero +educator.aero +emergency.aero +engine.aero +engineer.aero +entertainment.aero +equipment.aero +exchange.aero +express.aero +federation.aero +flight.aero +freight.aero +fuel.aero +gliding.aero +government.aero +groundhandling.aero +group.aero +hanggliding.aero +homebuilt.aero +insurance.aero +journal.aero +journalist.aero +leasing.aero +logistics.aero +magazine.aero +maintenance.aero +marketplace.aero +media.aero +microlight.aero +modelling.aero +navigation.aero +parachuting.aero +paragliding.aero +passenger-association.aero +pilot.aero +press.aero +production.aero +recreation.aero +repbody.aero +res.aero +research.aero +rotorcraft.aero +safety.aero +scientist.aero +services.aero +show.aero +skydiving.aero +software.aero +student.aero +taxi.aero +trader.aero +trading.aero +trainer.aero +union.aero +workinggroup.aero +works.aero + +// af : https://www.nic.af/domain-price +af +com.af +edu.af +gov.af +net.af +org.af + +// ag : http://www.nic.ag/prices.htm +ag +co.ag +com.ag +net.ag +nom.ag +org.ag + +// ai : http://nic.com.ai/ +ai +com.ai +net.ai +off.ai +org.ai + +// al : http://www.ert.gov.al/ert_alb/faq_det.html?Id=31 +al +com.al +edu.al +gov.al +mil.al +net.al +org.al + +// am : https://www.amnic.net/policy/en/Policy_EN.pdf +// Confirmed by ISOC AM 2024-11-18 +am +co.am +com.am +commune.am +net.am +org.am + +// ao : https://www.iana.org/domains/root/db/ao.html +// https://www.dns.ao/ao/ +ao +co.ao +ed.ao +edu.ao +gov.ao +gv.ao +it.ao +og.ao +org.ao +pb.ao + +// aq : https://www.iana.org/domains/root/db/aq.html +aq + +// ar : https://nic.ar/es/nic-argentina/normativa +ar +bet.ar +com.ar +coop.ar +edu.ar +gob.ar +gov.ar +int.ar +mil.ar +musica.ar +mutual.ar +net.ar +org.ar +seg.ar +senasa.ar +tur.ar + +// arpa : https://www.iana.org/domains/root/db/arpa.html +// Confirmed by registry 2008-06-18 +arpa +e164.arpa +home.arpa +in-addr.arpa +ip6.arpa +iris.arpa +uri.arpa +urn.arpa + +// as : https://www.iana.org/domains/root/db/as.html +as +gov.as + +// asia : https://www.iana.org/domains/root/db/asia.html +asia + +// at : https://www.iana.org/domains/root/db/at.html +// Confirmed by registry 2008-06-17 +at +ac.at +sth.ac.at +co.at +gv.at +or.at + +// au : https://www.iana.org/domains/root/db/au.html +// https://www.auda.org.au/ +// Confirmed by registry 2024-11-17 +au +// 2LDs +asn.au +com.au +edu.au +gov.au +id.au +net.au +org.au +// Historic 2LDs (closed to new registration, but sites still exist) +conf.au +oz.au +// CGDNs : https://www.auda.org.au/au-domain-names/the-different-au-domain-names/state-and-territory-domain-names/ +act.au +nsw.au +nt.au +qld.au +sa.au +tas.au +vic.au +wa.au +// 3LDs +act.edu.au +catholic.edu.au +// eq.edu.au - Removed at the request of the Queensland Department of Education +nsw.edu.au +nt.edu.au +qld.edu.au +sa.edu.au +tas.edu.au +vic.edu.au +wa.edu.au +// act.gov.au - Bug 984824 - Removed at request of Greg Tankard +// nsw.gov.au - Bug 547985 - Removed at request of +// nt.gov.au - Bug 940478 - Removed at request of Greg Connors +qld.gov.au +sa.gov.au +tas.gov.au +vic.gov.au +wa.gov.au +// 4LDs +// education.tas.edu.au - Removed at the request of the Department of Education Tasmania +schools.nsw.edu.au + +// aw : https://www.iana.org/domains/root/db/aw.html +aw +com.aw + +// ax : https://www.iana.org/domains/root/db/ax.html +ax + +// az : https://www.iana.org/domains/root/db/az.html +// Confirmed via https://whois.az/?page_id=10 2024-12-11 +az +biz.az +co.az +com.az +edu.az +gov.az +info.az +int.az +mil.az +name.az +net.az +org.az +pp.az +// No longer available for registration, however domains exist as of 2024-12-11 +// see https://whois.az/?page_id=783 +pro.az + +// ba : https://www.iana.org/domains/root/db/ba.html +ba +com.ba +edu.ba +gov.ba +mil.ba +net.ba +org.ba + +// bb : https://www.iana.org/domains/root/db/bb.html +bb +biz.bb +co.bb +com.bb +edu.bb +gov.bb +info.bb +net.bb +org.bb +store.bb +tv.bb + +// bd : https://www.iana.org/domains/root/db/bd.html +*.bd + +// be : https://www.iana.org/domains/root/db/be.html +// Confirmed by registry 2008-06-08 +be +ac.be + +// bf : https://www.iana.org/domains/root/db/bf.html +bf +gov.bf + +// bg : https://www.iana.org/domains/root/db/bg.html +// https://www.register.bg/user/static/rules/en/index.html +bg +0.bg +1.bg +2.bg +3.bg +4.bg +5.bg +6.bg +7.bg +8.bg +9.bg +a.bg +b.bg +c.bg +d.bg +e.bg +f.bg +g.bg +h.bg +i.bg +j.bg +k.bg +l.bg +m.bg +n.bg +o.bg +p.bg +q.bg +r.bg +s.bg +t.bg +u.bg +v.bg +w.bg +x.bg +y.bg +z.bg + +// bh : https://www.iana.org/domains/root/db/bh.html +bh +com.bh +edu.bh +gov.bh +net.bh +org.bh + +// bi : https://www.iana.org/domains/root/db/bi.html +// http://whois.nic.bi/ +bi +co.bi +com.bi +edu.bi +or.bi +org.bi + +// biz : https://www.iana.org/domains/root/db/biz.html +biz + +// bj : https://nic.bj/bj-suffixes.txt +// Submitted by registry +bj +africa.bj +agro.bj +architectes.bj +assur.bj +avocats.bj +co.bj +com.bj +eco.bj +econo.bj +edu.bj +info.bj +loisirs.bj +money.bj +net.bj +org.bj +ote.bj +restaurant.bj +resto.bj +tourism.bj +univ.bj + +// bm : https://www.bermudanic.bm/domain-registration/index.php +bm +com.bm +edu.bm +gov.bm +net.bm +org.bm + +// bn : http://www.bnnic.bn/faqs +bn +com.bn +edu.bn +gov.bn +net.bn +org.bn + +// bo : https://nic.bo +// Confirmed by registry 2024-11-19 +bo +com.bo +edu.bo +gob.bo +int.bo +mil.bo +net.bo +org.bo +tv.bo +web.bo +// Social Domains +academia.bo +agro.bo +arte.bo +blog.bo +bolivia.bo +ciencia.bo +cooperativa.bo +democracia.bo +deporte.bo +ecologia.bo +economia.bo +empresa.bo +indigena.bo +industria.bo +info.bo +medicina.bo +movimiento.bo +musica.bo +natural.bo +nombre.bo +noticias.bo +patria.bo +plurinacional.bo +politica.bo +profesional.bo +pueblo.bo +revista.bo +salud.bo +tecnologia.bo +tksat.bo +transporte.bo +wiki.bo + +// br : http://registro.br/dominio/categoria.html +// Submitted by registry +br +9guacu.br +abc.br +adm.br +adv.br +agr.br +aju.br +am.br +anani.br +aparecida.br +app.br +arq.br +art.br +ato.br +b.br +barueri.br +belem.br +bet.br +bhz.br +bib.br +bio.br +blog.br +bmd.br +boavista.br +bsb.br +campinagrande.br +campinas.br +caxias.br +cim.br +cng.br +cnt.br +com.br +contagem.br +coop.br +coz.br +cri.br +cuiaba.br +curitiba.br +def.br +des.br +det.br +dev.br +ecn.br +eco.br +edu.br +emp.br +enf.br +eng.br +esp.br +etc.br +eti.br +far.br +feira.br +flog.br +floripa.br +fm.br +fnd.br +fortal.br +fot.br +foz.br +fst.br +g12.br +geo.br +ggf.br +goiania.br +gov.br +// gov.br 26 states + df https://en.wikipedia.org/wiki/States_of_Brazil +ac.gov.br +al.gov.br +am.gov.br +ap.gov.br +ba.gov.br +ce.gov.br +df.gov.br +es.gov.br +go.gov.br +ma.gov.br +mg.gov.br +ms.gov.br +mt.gov.br +pa.gov.br +pb.gov.br +pe.gov.br +pi.gov.br +pr.gov.br +rj.gov.br +rn.gov.br +ro.gov.br +rr.gov.br +rs.gov.br +sc.gov.br +se.gov.br +sp.gov.br +to.gov.br +gru.br +imb.br +ind.br +inf.br +jab.br +jampa.br +jdf.br +joinville.br +jor.br +jus.br +leg.br +leilao.br +lel.br +log.br +londrina.br +macapa.br +maceio.br +manaus.br +maringa.br +mat.br +med.br +mil.br +morena.br +mp.br +mus.br +natal.br +net.br +niteroi.br +*.nom.br +not.br +ntr.br +odo.br +ong.br +org.br +osasco.br +palmas.br +poa.br +ppg.br +pro.br +psc.br +psi.br +pvh.br +qsl.br +radio.br +rec.br +recife.br +rep.br +ribeirao.br +rio.br +riobranco.br +riopreto.br +salvador.br +sampa.br +santamaria.br +santoandre.br +saobernardo.br +saogonca.br +seg.br +sjc.br +slg.br +slz.br +sorocaba.br +srv.br +taxi.br +tc.br +tec.br +teo.br +the.br +tmp.br +trd.br +tur.br +tv.br +udi.br +vet.br +vix.br +vlog.br +wiki.br +zlg.br + +// bs : http://www.nic.bs/rules.html +bs +com.bs +edu.bs +gov.bs +net.bs +org.bs + +// bt : https://www.iana.org/domains/root/db/bt.html +bt +com.bt +edu.bt +gov.bt +net.bt +org.bt + +// bv : No registrations at this time. +// Submitted by registry +bv + +// bw : https://www.iana.org/domains/root/db/bw.html +// https://nic.net.bw/bw-name-structure +bw +ac.bw +co.bw +gov.bw +net.bw +org.bw + +// by : https://www.iana.org/domains/root/db/by.html +// http://tld.by/rules_2006_en.html +// list of other 2nd level tlds ? +by +gov.by +mil.by +// Official information does not indicate that com.by is a reserved +// second-level domain, but it's being used as one (see www.google.com.by and +// www.yahoo.com.by, for example), so we list it here for safety's sake. +com.by +// http://hoster.by/ +of.by + +// bz : https://www.iana.org/domains/root/db/bz.html +// http://www.belizenic.bz/ +bz +co.bz +com.bz +edu.bz +gov.bz +net.bz +org.bz + +// ca : https://www.iana.org/domains/root/db/ca.html +ca +// ca geographical names +ab.ca +bc.ca +mb.ca +nb.ca +nf.ca +nl.ca +ns.ca +nt.ca +nu.ca +on.ca +pe.ca +qc.ca +sk.ca +yk.ca +// gc.ca: https://en.wikipedia.org/wiki/.gc.ca +// see also: http://registry.gc.ca/en/SubdomainFAQ +gc.ca + +// cat : https://www.iana.org/domains/root/db/cat.html +cat + +// cc : https://www.iana.org/domains/root/db/cc.html +cc + +// cd : https://www.iana.org/domains/root/db/cd.html +// https://www.nic.cd +cd +gov.cd + +// cf : https://www.iana.org/domains/root/db/cf.html +cf + +// cg : https://www.iana.org/domains/root/db/cg.html +cg + +// ch : https://www.iana.org/domains/root/db/ch.html +ch + +// ci : https://www.iana.org/domains/root/db/ci.html +ci +ac.ci +aéroport.ci +asso.ci +co.ci +com.ci +ed.ci +edu.ci +go.ci +gouv.ci +int.ci +net.ci +or.ci +org.ci + +// ck : https://www.iana.org/domains/root/db/ck.html +*.ck +!www.ck + +// cl : https://www.nic.cl +// Confirmed by .CL registry +cl +co.cl +gob.cl +gov.cl +mil.cl + +// cm : https://www.iana.org/domains/root/db/cm.html plus bug 981927 +cm +co.cm +com.cm +gov.cm +net.cm + +// cn : https://www.iana.org/domains/root/db/cn.html +// Submitted by registry +cn +ac.cn +com.cn +edu.cn +gov.cn +mil.cn +net.cn +org.cn +公司.cn +網絡.cn +网络.cn +// cn geographic names +ah.cn +bj.cn +cq.cn +fj.cn +gd.cn +gs.cn +gx.cn +gz.cn +ha.cn +hb.cn +he.cn +hi.cn +hk.cn +hl.cn +hn.cn +jl.cn +js.cn +jx.cn +ln.cn +mo.cn +nm.cn +nx.cn +qh.cn +sc.cn +sd.cn +sh.cn +sn.cn +sx.cn +tj.cn +tw.cn +xj.cn +xz.cn +yn.cn +zj.cn + +// co : https://www.iana.org/domains/root/db/co.html +// https://www.cointernet.com.co/como-funciona-un-dominio-restringido +// Confirmed by registry 2024-11-18 +co +com.co +edu.co +gov.co +mil.co +net.co +nom.co +org.co + +// com : https://www.iana.org/domains/root/db/com.html +com + +// coop : https://www.iana.org/domains/root/db/coop.html +coop + +// cr : https://nic.cr/capitulo-1-registro-de-un-nombre-de-dominio/ +cr +ac.cr +co.cr +ed.cr +fi.cr +go.cr +or.cr +sa.cr + +// cu : https://www.iana.org/domains/root/db/cu.html +cu +com.cu +edu.cu +gob.cu +inf.cu +nat.cu +net.cu +org.cu + +// cv : https://www.iana.org/domains/root/db/cv.html +// https://ola.cv/domain-extensions-under-cv/ +// Confirmed by registry 2024-11-26 +cv +com.cv +edu.cv +id.cv +int.cv +net.cv +nome.cv +org.cv +publ.cv + +// cw : https://www.uoc.cw/cw-registry +// Confirmed by registry 2024-11-19 +cw +com.cw +edu.cw +net.cw +org.cw + +// cx : https://www.iana.org/domains/root/db/cx.html +// list of other 2nd level tlds ? +cx +gov.cx + +// cy : http://www.nic.cy/ +// Submitted by Panayiotou Fotia +// https://nic.cy/wp-content/uploads/2024/01/Create-Request-for-domain-name-registration-1.pdf +cy +ac.cy +biz.cy +com.cy +ekloges.cy +gov.cy +ltd.cy +mil.cy +net.cy +org.cy +press.cy +pro.cy +tm.cy + +// cz : https://www.iana.org/domains/root/db/cz.html +cz + +// de : https://www.iana.org/domains/root/db/de.html +// Confirmed by registry (with technical +// reservations) 2008-07-01 +de + +// dj : https://www.iana.org/domains/root/db/dj.html +dj + +// dk : https://www.iana.org/domains/root/db/dk.html +// Confirmed by registry 2008-06-17 +dk + +// dm : https://www.iana.org/domains/root/db/dm.html +// https://nic.dm/policies/pdf/DMRulesandGuidelines2024v1.pdf +// Confirmed by registry 2024-11-19 +dm +co.dm +com.dm +edu.dm +gov.dm +net.dm +org.dm + +// do : https://www.iana.org/domains/root/db/do.html +do +art.do +com.do +edu.do +gob.do +gov.do +mil.do +net.do +org.do +sld.do +web.do + +// dz : http://www.nic.dz/images/pdf_nic/charte.pdf +dz +art.dz +asso.dz +com.dz +edu.dz +gov.dz +net.dz +org.dz +pol.dz +soc.dz +tm.dz + +// ec : https://www.nic.ec/ +// Submitted by registry +ec +com.ec +edu.ec +fin.ec +gob.ec +gov.ec +info.ec +k12.ec +med.ec +mil.ec +net.ec +org.ec +pro.ec + +// edu : https://www.iana.org/domains/root/db/edu.html +edu + +// ee : https://www.internet.ee/domains/general-domains-and-procedure-for-registration-of-sub-domains-under-general-domains +ee +aip.ee +com.ee +edu.ee +fie.ee +gov.ee +lib.ee +med.ee +org.ee +pri.ee +riik.ee + +// eg : https://www.iana.org/domains/root/db/eg.html +// https://domain.eg/en/domain-rules/subdomain-names-types/ +eg +ac.eg +com.eg +edu.eg +eun.eg +gov.eg +info.eg +me.eg +mil.eg +name.eg +net.eg +org.eg +sci.eg +sport.eg +tv.eg + +// er : https://www.iana.org/domains/root/db/er.html +*.er + +// es : https://www.dominios.es/en +es +com.es +edu.es +gob.es +nom.es +org.es + +// et : https://www.iana.org/domains/root/db/et.html +et +biz.et +com.et +edu.et +gov.et +info.et +name.et +net.et +org.et + +// eu : https://www.iana.org/domains/root/db/eu.html +eu + +// fi : https://www.iana.org/domains/root/db/fi.html +fi +// aland.fi : https://www.iana.org/domains/root/db/ax.html +// This domain is being phased out in favor of .ax. As there are still many +// domains under aland.fi, we still keep it on the list until aland.fi is +// completely removed. +aland.fi + +// fj : http://domains.fj/ +// Submitted by registry 2020-02-11 +fj +ac.fj +biz.fj +com.fj +gov.fj +info.fj +mil.fj +name.fj +net.fj +org.fj +pro.fj + +// fk : https://www.iana.org/domains/root/db/fk.html +*.fk + +// fm : https://www.iana.org/domains/root/db/fm.html +fm +com.fm +edu.fm +net.fm +org.fm + +// fo : https://www.iana.org/domains/root/db/fo.html +fo + +// fr : https://www.afnic.fr/ https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf +fr +asso.fr +com.fr +gouv.fr +nom.fr +prd.fr +tm.fr +// Other SLDs now selfmanaged out of AFNIC range. Former "domaines sectoriels", still registration suffixes +avoues.fr +cci.fr +greta.fr +huissier-justice.fr + +// ga : https://www.iana.org/domains/root/db/ga.html +ga + +// gb : This registry is effectively dormant +// Submitted by registry +gb + +// gd : https://www.iana.org/domains/root/db/gd.html +gd +edu.gd +gov.gd + +// ge : https://nic.ge/en/administrator/the-ge-domain-regulations +// Confirmed by registry 2024-11-20 +ge +com.ge +edu.ge +gov.ge +net.ge +org.ge +pvt.ge +school.ge + +// gf : https://www.iana.org/domains/root/db/gf.html +gf + +// gg : https://www.channelisles.net/register-1/register-direct +// Confirmed by registry 2013-11-28 +gg +co.gg +net.gg +org.gg + +// gh : https://www.iana.org/domains/root/db/gh.html +// https://www.nic.gh/ +// Although domains directly at second level are not possible at the moment, +// they have been possible for some time and may come back. +gh +com.gh +edu.gh +gov.gh +mil.gh +org.gh + +// gi : http://www.nic.gi/rules.html +gi +com.gi +edu.gi +gov.gi +ltd.gi +mod.gi +org.gi + +// gl : https://www.iana.org/domains/root/db/gl.html +// http://nic.gl +gl +co.gl +com.gl +edu.gl +net.gl +org.gl + +// gm : http://www.nic.gm/htmlpages%5Cgm-policy.htm +gm + +// gn : http://psg.com/dns/gn/gn.txt +// Submitted by registry +gn +ac.gn +com.gn +edu.gn +gov.gn +net.gn +org.gn + +// gov : https://www.iana.org/domains/root/db/gov.html +gov + +// gp : http://www.nic.gp/index.php?lang=en +gp +asso.gp +com.gp +edu.gp +mobi.gp +net.gp +org.gp + +// gq : https://www.iana.org/domains/root/db/gq.html +gq + +// gr : https://www.iana.org/domains/root/db/gr.html +// Submitted by registry +gr +com.gr +edu.gr +gov.gr +net.gr +org.gr + +// gs : https://www.iana.org/domains/root/db/gs.html +gs + +// gt : https://www.gt/sitio/registration_policy.php?lang=en +gt +com.gt +edu.gt +gob.gt +ind.gt +mil.gt +net.gt +org.gt + +// gu : http://gadao.gov.gu/register.html +// University of Guam : https://www.uog.edu +// Submitted by uognoc@triton.uog.edu +gu +com.gu +edu.gu +gov.gu +guam.gu +info.gu +net.gu +org.gu +web.gu + +// gw : https://www.iana.org/domains/root/db/gw.html +// gw : https://nic.gw/regras/ +gw + +// gy : https://www.iana.org/domains/root/db/gy.html +// http://registry.gy/ +gy +co.gy +com.gy +edu.gy +gov.gy +net.gy +org.gy + +// hk : https://www.hkirc.hk +// Submitted by registry +hk +com.hk +edu.hk +gov.hk +idv.hk +net.hk +org.hk +个人.hk +個人.hk +公司.hk +政府.hk +敎育.hk +教育.hk +箇人.hk +組織.hk +組织.hk +網絡.hk +網络.hk +组織.hk +组织.hk +网絡.hk +网络.hk + +// hm : https://www.iana.org/domains/root/db/hm.html +hm + +// hn : https://www.iana.org/domains/root/db/hn.html +hn +com.hn +edu.hn +gob.hn +mil.hn +net.hn +org.hn + +// hr : http://www.dns.hr/documents/pdf/HRTLD-regulations.pdf +hr +com.hr +from.hr +iz.hr +name.hr + +// ht : http://www.nic.ht/info/charte.cfm +ht +adult.ht +art.ht +asso.ht +com.ht +coop.ht +edu.ht +firm.ht +gouv.ht +info.ht +med.ht +net.ht +org.ht +perso.ht +pol.ht +pro.ht +rel.ht +shop.ht + +// hu : https://www.iana.org/domains/root/db/hu.html +// Confirmed by registry 2008-06-12 +hu +2000.hu +agrar.hu +bolt.hu +casino.hu +city.hu +co.hu +erotica.hu +erotika.hu +film.hu +forum.hu +games.hu +hotel.hu +info.hu +ingatlan.hu +jogasz.hu +konyvelo.hu +lakas.hu +media.hu +news.hu +org.hu +priv.hu +reklam.hu +sex.hu +shop.hu +sport.hu +suli.hu +szex.hu +tm.hu +tozsde.hu +utazas.hu +video.hu + +// id : https://www.iana.org/domains/root/db/id.html +id +ac.id +biz.id +co.id +desa.id +go.id +mil.id +my.id +net.id +or.id +ponpes.id +sch.id +web.id + +// ie : https://www.iana.org/domains/root/db/ie.html +ie +gov.ie + +// il : http://www.isoc.org.il/domains/ +// see also: https://en.isoc.org.il/il-cctld/registration-rules +// ISOC-IL (operated by .il Registry) +il +ac.il +co.il +gov.il +idf.il +k12.il +muni.il +net.il +org.il +// xn--4dbrk0ce ("Israel", Hebrew) : IL +ישראל +// xn--4dbgdty6c.xn--4dbrk0ce. +אקדמיה.ישראל +// xn--5dbhl8d.xn--4dbrk0ce. +ישוב.ישראל +// xn--8dbq2a.xn--4dbrk0ce. +צהל.ישראל +// xn--hebda8b.xn--4dbrk0ce. +ממשל.ישראל + +// im : https://www.nic.im/ +// Submitted by registry +im +ac.im +co.im +ltd.co.im +plc.co.im +com.im +net.im +org.im +tt.im +tv.im + +// in : https://www.iana.org/domains/root/db/in.html +// see also: https://registry.in/policies +// Please note, that nic.in is not an official eTLD, but used by most +// government institutions. +in +5g.in +6g.in +ac.in +ai.in +am.in +bihar.in +biz.in +business.in +ca.in +cn.in +co.in +com.in +coop.in +cs.in +delhi.in +dr.in +edu.in +er.in +firm.in +gen.in +gov.in +gujarat.in +ind.in +info.in +int.in +internet.in +io.in +me.in +mil.in +net.in +nic.in +org.in +pg.in +post.in +pro.in +res.in +travel.in +tv.in +uk.in +up.in +us.in + +// info : https://www.iana.org/domains/root/db/info.html +info + +// int : https://www.iana.org/domains/root/db/int.html +// Confirmed by registry 2008-06-18 +int +eu.int + +// io : http://www.nic.io/rules.htm +io +co.io +com.io +edu.io +gov.io +mil.io +net.io +nom.io +org.io + +// iq : http://www.cmc.iq/english/iq/iqregister1.htm +iq +com.iq +edu.iq +gov.iq +mil.iq +net.iq +org.iq + +// ir : http://www.nic.ir/Terms_and_Conditions_ir,_Appendix_1_Domain_Rules +// Also see http://www.nic.ir/Internationalized_Domain_Names +// Two .ir entries added at request of , 2010-04-16 +ir +ac.ir +co.ir +gov.ir +id.ir +net.ir +org.ir +sch.ir +// xn--mgba3a4f16a.ir (.ir, Persian YEH) +ایران.ir +// xn--mgba3a4fra.ir (.ir, Arabic YEH) +ايران.ir + +// is : http://www.isnic.is/domain/rules.php +// Confirmed by registry 2024-11-17 +is + +// it : https://www.iana.org/domains/root/db/it.html +// https://www.nic.it/ +it +edu.it +gov.it +// Regions (3.3.1) +// https://www.nic.it/en/manage-your-it/forms-and-docs -> "Assignment and Management of domain names" +abr.it +abruzzo.it +aosta-valley.it +aostavalley.it +bas.it +basilicata.it +cal.it +calabria.it +cam.it +campania.it +emilia-romagna.it +emiliaromagna.it +emr.it +friuli-v-giulia.it +friuli-ve-giulia.it +friuli-vegiulia.it +friuli-venezia-giulia.it +friuli-veneziagiulia.it +friuli-vgiulia.it +friuliv-giulia.it +friulive-giulia.it +friulivegiulia.it +friulivenezia-giulia.it +friuliveneziagiulia.it +friulivgiulia.it +fvg.it +laz.it +lazio.it +lig.it +liguria.it +lom.it +lombardia.it +lombardy.it +lucania.it +mar.it +marche.it +mol.it +molise.it +piedmont.it +piemonte.it +pmn.it +pug.it +puglia.it +sar.it +sardegna.it +sardinia.it +sic.it +sicilia.it +sicily.it +taa.it +tos.it +toscana.it +trentin-sud-tirol.it +trentin-süd-tirol.it +trentin-sudtirol.it +trentin-südtirol.it +trentin-sued-tirol.it +trentin-suedtirol.it +trentino.it +trentino-a-adige.it +trentino-aadige.it +trentino-alto-adige.it +trentino-altoadige.it +trentino-s-tirol.it +trentino-stirol.it +trentino-sud-tirol.it +trentino-süd-tirol.it +trentino-sudtirol.it +trentino-südtirol.it +trentino-sued-tirol.it +trentino-suedtirol.it +trentinoa-adige.it +trentinoaadige.it +trentinoalto-adige.it +trentinoaltoadige.it +trentinos-tirol.it +trentinostirol.it +trentinosud-tirol.it +trentinosüd-tirol.it +trentinosudtirol.it +trentinosüdtirol.it +trentinosued-tirol.it +trentinosuedtirol.it +trentinsud-tirol.it +trentinsüd-tirol.it +trentinsudtirol.it +trentinsüdtirol.it +trentinsued-tirol.it +trentinsuedtirol.it +tuscany.it +umb.it +umbria.it +val-d-aosta.it +val-daosta.it +vald-aosta.it +valdaosta.it +valle-aosta.it +valle-d-aosta.it +valle-daosta.it +valleaosta.it +valled-aosta.it +valledaosta.it +vallee-aoste.it +vallée-aoste.it +vallee-d-aoste.it +vallée-d-aoste.it +valleeaoste.it +valléeaoste.it +valleedaoste.it +valléedaoste.it +vao.it +vda.it +ven.it +veneto.it +// Provinces (3.3.2) +ag.it +agrigento.it +al.it +alessandria.it +alto-adige.it +altoadige.it +an.it +ancona.it +andria-barletta-trani.it +andria-trani-barletta.it +andriabarlettatrani.it +andriatranibarletta.it +ao.it +aosta.it +aoste.it +ap.it +aq.it +aquila.it +ar.it +arezzo.it +ascoli-piceno.it +ascolipiceno.it +asti.it +at.it +av.it +avellino.it +ba.it +balsan.it +balsan-sudtirol.it +balsan-südtirol.it +balsan-suedtirol.it +bari.it +barletta-trani-andria.it +barlettatraniandria.it +belluno.it +benevento.it +bergamo.it +bg.it +bi.it +biella.it +bl.it +bn.it +bo.it +bologna.it +bolzano.it +bolzano-altoadige.it +bozen.it +bozen-sudtirol.it +bozen-südtirol.it +bozen-suedtirol.it +br.it +brescia.it +brindisi.it +bs.it +bt.it +bulsan.it +bulsan-sudtirol.it +bulsan-südtirol.it +bulsan-suedtirol.it +bz.it +ca.it +cagliari.it +caltanissetta.it +campidano-medio.it +campidanomedio.it +campobasso.it +carbonia-iglesias.it +carboniaiglesias.it +carrara-massa.it +carraramassa.it +caserta.it +catania.it +catanzaro.it +cb.it +ce.it +cesena-forli.it +cesena-forlì.it +cesenaforli.it +cesenaforlì.it +ch.it +chieti.it +ci.it +cl.it +cn.it +co.it +como.it +cosenza.it +cr.it +cremona.it +crotone.it +cs.it +ct.it +cuneo.it +cz.it +dell-ogliastra.it +dellogliastra.it +en.it +enna.it +fc.it +fe.it +fermo.it +ferrara.it +fg.it +fi.it +firenze.it +florence.it +fm.it +foggia.it +forli-cesena.it +forlì-cesena.it +forlicesena.it +forlìcesena.it +fr.it +frosinone.it +ge.it +genoa.it +genova.it +go.it +gorizia.it +gr.it +grosseto.it +iglesias-carbonia.it +iglesiascarbonia.it +im.it +imperia.it +is.it +isernia.it +kr.it +la-spezia.it +laquila.it +laspezia.it +latina.it +lc.it +le.it +lecce.it +lecco.it +li.it +livorno.it +lo.it +lodi.it +lt.it +lu.it +lucca.it +macerata.it +mantova.it +massa-carrara.it +massacarrara.it +matera.it +mb.it +mc.it +me.it +medio-campidano.it +mediocampidano.it +messina.it +mi.it +milan.it +milano.it +mn.it +mo.it +modena.it +monza.it +monza-brianza.it +monza-e-della-brianza.it +monzabrianza.it +monzaebrianza.it +monzaedellabrianza.it +ms.it +mt.it +na.it +naples.it +napoli.it +no.it +novara.it +nu.it +nuoro.it +og.it +ogliastra.it +olbia-tempio.it +olbiatempio.it +or.it +oristano.it +ot.it +pa.it +padova.it +padua.it +palermo.it +parma.it +pavia.it +pc.it +pd.it +pe.it +perugia.it +pesaro-urbino.it +pesarourbino.it +pescara.it +pg.it +pi.it +piacenza.it +pisa.it +pistoia.it +pn.it +po.it +pordenone.it +potenza.it +pr.it +prato.it +pt.it +pu.it +pv.it +pz.it +ra.it +ragusa.it +ravenna.it +rc.it +re.it +reggio-calabria.it +reggio-emilia.it +reggiocalabria.it +reggioemilia.it +rg.it +ri.it +rieti.it +rimini.it +rm.it +rn.it +ro.it +roma.it +rome.it +rovigo.it +sa.it +salerno.it +sassari.it +savona.it +si.it +siena.it +siracusa.it +so.it +sondrio.it +sp.it +sr.it +ss.it +südtirol.it +suedtirol.it +sv.it +ta.it +taranto.it +te.it +tempio-olbia.it +tempioolbia.it +teramo.it +terni.it +tn.it +to.it +torino.it +tp.it +tr.it +trani-andria-barletta.it +trani-barletta-andria.it +traniandriabarletta.it +tranibarlettaandria.it +trapani.it +trento.it +treviso.it +trieste.it +ts.it +turin.it +tv.it +ud.it +udine.it +urbino-pesaro.it +urbinopesaro.it +va.it +varese.it +vb.it +vc.it +ve.it +venezia.it +venice.it +verbania.it +vercelli.it +verona.it +vi.it +vibo-valentia.it +vibovalentia.it +vicenza.it +viterbo.it +vr.it +vs.it +vt.it +vv.it + +// je : https://www.iana.org/domains/root/db/je.html +// Confirmed by registry 2013-11-28 +je +co.je +net.je +org.je + +// jm : http://www.com.jm/register.html +*.jm + +// jo : https://www.dns.jo/JoFamily.aspx +// Confirmed by registry 2024-11-17 +jo +agri.jo +ai.jo +com.jo +edu.jo +eng.jo +fm.jo +gov.jo +mil.jo +net.jo +org.jo +per.jo +phd.jo +sch.jo +tv.jo + +// jobs : https://www.iana.org/domains/root/db/jobs.html +jobs + +// jp : https://www.iana.org/domains/root/db/jp.html +// http://jprs.co.jp/en/jpdomain.html +// Confirmed by registry 2024-11-22 +jp +// jp organizational type names +ac.jp +ad.jp +co.jp +ed.jp +go.jp +gr.jp +lg.jp +ne.jp +or.jp +// jp prefecture type names +aichi.jp +akita.jp +aomori.jp +chiba.jp +ehime.jp +fukui.jp +fukuoka.jp +fukushima.jp +gifu.jp +gunma.jp +hiroshima.jp +hokkaido.jp +hyogo.jp +ibaraki.jp +ishikawa.jp +iwate.jp +kagawa.jp +kagoshima.jp +kanagawa.jp +kochi.jp +kumamoto.jp +kyoto.jp +mie.jp +miyagi.jp +miyazaki.jp +nagano.jp +nagasaki.jp +nara.jp +niigata.jp +oita.jp +okayama.jp +okinawa.jp +osaka.jp +saga.jp +saitama.jp +shiga.jp +shimane.jp +shizuoka.jp +tochigi.jp +tokushima.jp +tokyo.jp +tottori.jp +toyama.jp +wakayama.jp +yamagata.jp +yamaguchi.jp +yamanashi.jp +三重.jp +京都.jp +佐賀.jp +兵庫.jp +北海道.jp +千葉.jp +和歌山.jp +埼玉.jp +大分.jp +大阪.jp +奈良.jp +宮城.jp +宮崎.jp +富山.jp +山口.jp +山形.jp +山梨.jp +岐阜.jp +岡山.jp +岩手.jp +島根.jp +広島.jp +徳島.jp +愛媛.jp +愛知.jp +新潟.jp +東京.jp +栃木.jp +沖縄.jp +滋賀.jp +熊本.jp +石川.jp +神奈川.jp +福井.jp +福岡.jp +福島.jp +秋田.jp +群馬.jp +茨城.jp +長崎.jp +長野.jp +青森.jp +静岡.jp +香川.jp +高知.jp +鳥取.jp +鹿児島.jp +// jp geographic type names +// http://jprs.jp/doc/rule/saisoku-1.html +// 2024-11-22: JPRS confirmed that jp geographic type names no longer accept new registrations. +// Once all existing registrations expire (marking full discontinuation), these suffixes +// will be removed from the PSL. +*.kawasaki.jp +!city.kawasaki.jp +*.kitakyushu.jp +!city.kitakyushu.jp +*.kobe.jp +!city.kobe.jp +*.nagoya.jp +!city.nagoya.jp +*.sapporo.jp +!city.sapporo.jp +*.sendai.jp +!city.sendai.jp +*.yokohama.jp +!city.yokohama.jp +// 4th level registration +aisai.aichi.jp +ama.aichi.jp +anjo.aichi.jp +asuke.aichi.jp +chiryu.aichi.jp +chita.aichi.jp +fuso.aichi.jp +gamagori.aichi.jp +handa.aichi.jp +hazu.aichi.jp +hekinan.aichi.jp +higashiura.aichi.jp +ichinomiya.aichi.jp +inazawa.aichi.jp +inuyama.aichi.jp +isshiki.aichi.jp +iwakura.aichi.jp +kanie.aichi.jp +kariya.aichi.jp +kasugai.aichi.jp +kira.aichi.jp +kiyosu.aichi.jp +komaki.aichi.jp +konan.aichi.jp +kota.aichi.jp +mihama.aichi.jp +miyoshi.aichi.jp +nishio.aichi.jp +nisshin.aichi.jp +obu.aichi.jp +oguchi.aichi.jp +oharu.aichi.jp +okazaki.aichi.jp +owariasahi.aichi.jp +seto.aichi.jp +shikatsu.aichi.jp +shinshiro.aichi.jp +shitara.aichi.jp +tahara.aichi.jp +takahama.aichi.jp +tobishima.aichi.jp +toei.aichi.jp +togo.aichi.jp +tokai.aichi.jp +tokoname.aichi.jp +toyoake.aichi.jp +toyohashi.aichi.jp +toyokawa.aichi.jp +toyone.aichi.jp +toyota.aichi.jp +tsushima.aichi.jp +yatomi.aichi.jp +akita.akita.jp +daisen.akita.jp +fujisato.akita.jp +gojome.akita.jp +hachirogata.akita.jp +happou.akita.jp +higashinaruse.akita.jp +honjo.akita.jp +honjyo.akita.jp +ikawa.akita.jp +kamikoani.akita.jp +kamioka.akita.jp +katagami.akita.jp +kazuno.akita.jp +kitaakita.akita.jp +kosaka.akita.jp +kyowa.akita.jp +misato.akita.jp +mitane.akita.jp +moriyoshi.akita.jp +nikaho.akita.jp +noshiro.akita.jp +odate.akita.jp +oga.akita.jp +ogata.akita.jp +semboku.akita.jp +yokote.akita.jp +yurihonjo.akita.jp +aomori.aomori.jp +gonohe.aomori.jp +hachinohe.aomori.jp +hashikami.aomori.jp +hiranai.aomori.jp +hirosaki.aomori.jp +itayanagi.aomori.jp +kuroishi.aomori.jp +misawa.aomori.jp +mutsu.aomori.jp +nakadomari.aomori.jp +noheji.aomori.jp +oirase.aomori.jp +owani.aomori.jp +rokunohe.aomori.jp +sannohe.aomori.jp +shichinohe.aomori.jp +shingo.aomori.jp +takko.aomori.jp +towada.aomori.jp +tsugaru.aomori.jp +tsuruta.aomori.jp +abiko.chiba.jp +asahi.chiba.jp +chonan.chiba.jp +chosei.chiba.jp +choshi.chiba.jp +chuo.chiba.jp +funabashi.chiba.jp +futtsu.chiba.jp +hanamigawa.chiba.jp +ichihara.chiba.jp +ichikawa.chiba.jp +ichinomiya.chiba.jp +inzai.chiba.jp +isumi.chiba.jp +kamagaya.chiba.jp +kamogawa.chiba.jp +kashiwa.chiba.jp +katori.chiba.jp +katsuura.chiba.jp +kimitsu.chiba.jp +kisarazu.chiba.jp +kozaki.chiba.jp +kujukuri.chiba.jp +kyonan.chiba.jp +matsudo.chiba.jp +midori.chiba.jp +mihama.chiba.jp +minamiboso.chiba.jp +mobara.chiba.jp +mutsuzawa.chiba.jp +nagara.chiba.jp +nagareyama.chiba.jp +narashino.chiba.jp +narita.chiba.jp +noda.chiba.jp +oamishirasato.chiba.jp +omigawa.chiba.jp +onjuku.chiba.jp +otaki.chiba.jp +sakae.chiba.jp +sakura.chiba.jp +shimofusa.chiba.jp +shirako.chiba.jp +shiroi.chiba.jp +shisui.chiba.jp +sodegaura.chiba.jp +sosa.chiba.jp +tako.chiba.jp +tateyama.chiba.jp +togane.chiba.jp +tohnosho.chiba.jp +tomisato.chiba.jp +urayasu.chiba.jp +yachimata.chiba.jp +yachiyo.chiba.jp +yokaichiba.chiba.jp +yokoshibahikari.chiba.jp +yotsukaido.chiba.jp +ainan.ehime.jp +honai.ehime.jp +ikata.ehime.jp +imabari.ehime.jp +iyo.ehime.jp +kamijima.ehime.jp +kihoku.ehime.jp +kumakogen.ehime.jp +masaki.ehime.jp +matsuno.ehime.jp +matsuyama.ehime.jp +namikata.ehime.jp +niihama.ehime.jp +ozu.ehime.jp +saijo.ehime.jp +seiyo.ehime.jp +shikokuchuo.ehime.jp +tobe.ehime.jp +toon.ehime.jp +uchiko.ehime.jp +uwajima.ehime.jp +yawatahama.ehime.jp +echizen.fukui.jp +eiheiji.fukui.jp +fukui.fukui.jp +ikeda.fukui.jp +katsuyama.fukui.jp +mihama.fukui.jp +minamiechizen.fukui.jp +obama.fukui.jp +ohi.fukui.jp +ono.fukui.jp +sabae.fukui.jp +sakai.fukui.jp +takahama.fukui.jp +tsuruga.fukui.jp +wakasa.fukui.jp +ashiya.fukuoka.jp +buzen.fukuoka.jp +chikugo.fukuoka.jp +chikuho.fukuoka.jp +chikujo.fukuoka.jp +chikushino.fukuoka.jp +chikuzen.fukuoka.jp +chuo.fukuoka.jp +dazaifu.fukuoka.jp +fukuchi.fukuoka.jp +hakata.fukuoka.jp +higashi.fukuoka.jp +hirokawa.fukuoka.jp +hisayama.fukuoka.jp +iizuka.fukuoka.jp +inatsuki.fukuoka.jp +kaho.fukuoka.jp +kasuga.fukuoka.jp +kasuya.fukuoka.jp +kawara.fukuoka.jp +keisen.fukuoka.jp +koga.fukuoka.jp +kurate.fukuoka.jp +kurogi.fukuoka.jp +kurume.fukuoka.jp +minami.fukuoka.jp +miyako.fukuoka.jp +miyama.fukuoka.jp +miyawaka.fukuoka.jp +mizumaki.fukuoka.jp +munakata.fukuoka.jp +nakagawa.fukuoka.jp +nakama.fukuoka.jp +nishi.fukuoka.jp +nogata.fukuoka.jp +ogori.fukuoka.jp +okagaki.fukuoka.jp +okawa.fukuoka.jp +oki.fukuoka.jp +omuta.fukuoka.jp +onga.fukuoka.jp +onojo.fukuoka.jp +oto.fukuoka.jp +saigawa.fukuoka.jp +sasaguri.fukuoka.jp +shingu.fukuoka.jp +shinyoshitomi.fukuoka.jp +shonai.fukuoka.jp +soeda.fukuoka.jp +sue.fukuoka.jp +tachiarai.fukuoka.jp +tagawa.fukuoka.jp +takata.fukuoka.jp +toho.fukuoka.jp +toyotsu.fukuoka.jp +tsuiki.fukuoka.jp +ukiha.fukuoka.jp +umi.fukuoka.jp +usui.fukuoka.jp +yamada.fukuoka.jp +yame.fukuoka.jp +yanagawa.fukuoka.jp +yukuhashi.fukuoka.jp +aizubange.fukushima.jp +aizumisato.fukushima.jp +aizuwakamatsu.fukushima.jp +asakawa.fukushima.jp +bandai.fukushima.jp +date.fukushima.jp +fukushima.fukushima.jp +furudono.fukushima.jp +futaba.fukushima.jp +hanawa.fukushima.jp +higashi.fukushima.jp +hirata.fukushima.jp +hirono.fukushima.jp +iitate.fukushima.jp +inawashiro.fukushima.jp +ishikawa.fukushima.jp +iwaki.fukushima.jp +izumizaki.fukushima.jp +kagamiishi.fukushima.jp +kaneyama.fukushima.jp +kawamata.fukushima.jp +kitakata.fukushima.jp +kitashiobara.fukushima.jp +koori.fukushima.jp +koriyama.fukushima.jp +kunimi.fukushima.jp +miharu.fukushima.jp +mishima.fukushima.jp +namie.fukushima.jp +nango.fukushima.jp +nishiaizu.fukushima.jp +nishigo.fukushima.jp +okuma.fukushima.jp +omotego.fukushima.jp +ono.fukushima.jp +otama.fukushima.jp +samegawa.fukushima.jp +shimogo.fukushima.jp +shirakawa.fukushima.jp +showa.fukushima.jp +soma.fukushima.jp +sukagawa.fukushima.jp +taishin.fukushima.jp +tamakawa.fukushima.jp +tanagura.fukushima.jp +tenei.fukushima.jp +yabuki.fukushima.jp +yamato.fukushima.jp +yamatsuri.fukushima.jp +yanaizu.fukushima.jp +yugawa.fukushima.jp +anpachi.gifu.jp +ena.gifu.jp +gifu.gifu.jp +ginan.gifu.jp +godo.gifu.jp +gujo.gifu.jp +hashima.gifu.jp +hichiso.gifu.jp +hida.gifu.jp +higashishirakawa.gifu.jp +ibigawa.gifu.jp +ikeda.gifu.jp +kakamigahara.gifu.jp +kani.gifu.jp +kasahara.gifu.jp +kasamatsu.gifu.jp +kawaue.gifu.jp +kitagata.gifu.jp +mino.gifu.jp +minokamo.gifu.jp +mitake.gifu.jp +mizunami.gifu.jp +motosu.gifu.jp +nakatsugawa.gifu.jp +ogaki.gifu.jp +sakahogi.gifu.jp +seki.gifu.jp +sekigahara.gifu.jp +shirakawa.gifu.jp +tajimi.gifu.jp +takayama.gifu.jp +tarui.gifu.jp +toki.gifu.jp +tomika.gifu.jp +wanouchi.gifu.jp +yamagata.gifu.jp +yaotsu.gifu.jp +yoro.gifu.jp +annaka.gunma.jp +chiyoda.gunma.jp +fujioka.gunma.jp +higashiagatsuma.gunma.jp +isesaki.gunma.jp +itakura.gunma.jp +kanna.gunma.jp +kanra.gunma.jp +katashina.gunma.jp +kawaba.gunma.jp +kiryu.gunma.jp +kusatsu.gunma.jp +maebashi.gunma.jp +meiwa.gunma.jp +midori.gunma.jp +minakami.gunma.jp +naganohara.gunma.jp +nakanojo.gunma.jp +nanmoku.gunma.jp +numata.gunma.jp +oizumi.gunma.jp +ora.gunma.jp +ota.gunma.jp +shibukawa.gunma.jp +shimonita.gunma.jp +shinto.gunma.jp +showa.gunma.jp +takasaki.gunma.jp +takayama.gunma.jp +tamamura.gunma.jp +tatebayashi.gunma.jp +tomioka.gunma.jp +tsukiyono.gunma.jp +tsumagoi.gunma.jp +ueno.gunma.jp +yoshioka.gunma.jp +asaminami.hiroshima.jp +daiwa.hiroshima.jp +etajima.hiroshima.jp +fuchu.hiroshima.jp +fukuyama.hiroshima.jp +hatsukaichi.hiroshima.jp +higashihiroshima.hiroshima.jp +hongo.hiroshima.jp +jinsekikogen.hiroshima.jp +kaita.hiroshima.jp +kui.hiroshima.jp +kumano.hiroshima.jp +kure.hiroshima.jp +mihara.hiroshima.jp +miyoshi.hiroshima.jp +naka.hiroshima.jp +onomichi.hiroshima.jp +osakikamijima.hiroshima.jp +otake.hiroshima.jp +saka.hiroshima.jp +sera.hiroshima.jp +seranishi.hiroshima.jp +shinichi.hiroshima.jp +shobara.hiroshima.jp +takehara.hiroshima.jp +abashiri.hokkaido.jp +abira.hokkaido.jp +aibetsu.hokkaido.jp +akabira.hokkaido.jp +akkeshi.hokkaido.jp +asahikawa.hokkaido.jp +ashibetsu.hokkaido.jp +ashoro.hokkaido.jp +assabu.hokkaido.jp +atsuma.hokkaido.jp +bibai.hokkaido.jp +biei.hokkaido.jp +bifuka.hokkaido.jp +bihoro.hokkaido.jp +biratori.hokkaido.jp +chippubetsu.hokkaido.jp +chitose.hokkaido.jp +date.hokkaido.jp +ebetsu.hokkaido.jp +embetsu.hokkaido.jp +eniwa.hokkaido.jp +erimo.hokkaido.jp +esan.hokkaido.jp +esashi.hokkaido.jp +fukagawa.hokkaido.jp +fukushima.hokkaido.jp +furano.hokkaido.jp +furubira.hokkaido.jp +haboro.hokkaido.jp +hakodate.hokkaido.jp +hamatonbetsu.hokkaido.jp +hidaka.hokkaido.jp +higashikagura.hokkaido.jp +higashikawa.hokkaido.jp +hiroo.hokkaido.jp +hokuryu.hokkaido.jp +hokuto.hokkaido.jp +honbetsu.hokkaido.jp +horokanai.hokkaido.jp +horonobe.hokkaido.jp +ikeda.hokkaido.jp +imakane.hokkaido.jp +ishikari.hokkaido.jp +iwamizawa.hokkaido.jp +iwanai.hokkaido.jp +kamifurano.hokkaido.jp +kamikawa.hokkaido.jp +kamishihoro.hokkaido.jp +kamisunagawa.hokkaido.jp +kamoenai.hokkaido.jp +kayabe.hokkaido.jp +kembuchi.hokkaido.jp +kikonai.hokkaido.jp +kimobetsu.hokkaido.jp +kitahiroshima.hokkaido.jp +kitami.hokkaido.jp +kiyosato.hokkaido.jp +koshimizu.hokkaido.jp +kunneppu.hokkaido.jp +kuriyama.hokkaido.jp +kuromatsunai.hokkaido.jp +kushiro.hokkaido.jp +kutchan.hokkaido.jp +kyowa.hokkaido.jp +mashike.hokkaido.jp +matsumae.hokkaido.jp +mikasa.hokkaido.jp +minamifurano.hokkaido.jp +mombetsu.hokkaido.jp +moseushi.hokkaido.jp +mukawa.hokkaido.jp +muroran.hokkaido.jp +naie.hokkaido.jp +nakagawa.hokkaido.jp +nakasatsunai.hokkaido.jp +nakatombetsu.hokkaido.jp +nanae.hokkaido.jp +nanporo.hokkaido.jp +nayoro.hokkaido.jp +nemuro.hokkaido.jp +niikappu.hokkaido.jp +niki.hokkaido.jp +nishiokoppe.hokkaido.jp +noboribetsu.hokkaido.jp +numata.hokkaido.jp +obihiro.hokkaido.jp +obira.hokkaido.jp +oketo.hokkaido.jp +okoppe.hokkaido.jp +otaru.hokkaido.jp +otobe.hokkaido.jp +otofuke.hokkaido.jp +otoineppu.hokkaido.jp +oumu.hokkaido.jp +ozora.hokkaido.jp +pippu.hokkaido.jp +rankoshi.hokkaido.jp +rebun.hokkaido.jp +rikubetsu.hokkaido.jp +rishiri.hokkaido.jp +rishirifuji.hokkaido.jp +saroma.hokkaido.jp +sarufutsu.hokkaido.jp +shakotan.hokkaido.jp +shari.hokkaido.jp +shibecha.hokkaido.jp +shibetsu.hokkaido.jp +shikabe.hokkaido.jp +shikaoi.hokkaido.jp +shimamaki.hokkaido.jp +shimizu.hokkaido.jp +shimokawa.hokkaido.jp +shinshinotsu.hokkaido.jp +shintoku.hokkaido.jp +shiranuka.hokkaido.jp +shiraoi.hokkaido.jp +shiriuchi.hokkaido.jp +sobetsu.hokkaido.jp +sunagawa.hokkaido.jp +taiki.hokkaido.jp +takasu.hokkaido.jp +takikawa.hokkaido.jp +takinoue.hokkaido.jp +teshikaga.hokkaido.jp +tobetsu.hokkaido.jp +tohma.hokkaido.jp +tomakomai.hokkaido.jp +tomari.hokkaido.jp +toya.hokkaido.jp +toyako.hokkaido.jp +toyotomi.hokkaido.jp +toyoura.hokkaido.jp +tsubetsu.hokkaido.jp +tsukigata.hokkaido.jp +urakawa.hokkaido.jp +urausu.hokkaido.jp +uryu.hokkaido.jp +utashinai.hokkaido.jp +wakkanai.hokkaido.jp +wassamu.hokkaido.jp +yakumo.hokkaido.jp +yoichi.hokkaido.jp +aioi.hyogo.jp +akashi.hyogo.jp +ako.hyogo.jp +amagasaki.hyogo.jp +aogaki.hyogo.jp +asago.hyogo.jp +ashiya.hyogo.jp +awaji.hyogo.jp +fukusaki.hyogo.jp +goshiki.hyogo.jp +harima.hyogo.jp +himeji.hyogo.jp +ichikawa.hyogo.jp +inagawa.hyogo.jp +itami.hyogo.jp +kakogawa.hyogo.jp +kamigori.hyogo.jp +kamikawa.hyogo.jp +kasai.hyogo.jp +kasuga.hyogo.jp +kawanishi.hyogo.jp +miki.hyogo.jp +minamiawaji.hyogo.jp +nishinomiya.hyogo.jp +nishiwaki.hyogo.jp +ono.hyogo.jp +sanda.hyogo.jp +sannan.hyogo.jp +sasayama.hyogo.jp +sayo.hyogo.jp +shingu.hyogo.jp +shinonsen.hyogo.jp +shiso.hyogo.jp +sumoto.hyogo.jp +taishi.hyogo.jp +taka.hyogo.jp +takarazuka.hyogo.jp +takasago.hyogo.jp +takino.hyogo.jp +tamba.hyogo.jp +tatsuno.hyogo.jp +toyooka.hyogo.jp +yabu.hyogo.jp +yashiro.hyogo.jp +yoka.hyogo.jp +yokawa.hyogo.jp +ami.ibaraki.jp +asahi.ibaraki.jp +bando.ibaraki.jp +chikusei.ibaraki.jp +daigo.ibaraki.jp +fujishiro.ibaraki.jp +hitachi.ibaraki.jp +hitachinaka.ibaraki.jp +hitachiomiya.ibaraki.jp +hitachiota.ibaraki.jp +ibaraki.ibaraki.jp +ina.ibaraki.jp +inashiki.ibaraki.jp +itako.ibaraki.jp +iwama.ibaraki.jp +joso.ibaraki.jp +kamisu.ibaraki.jp +kasama.ibaraki.jp +kashima.ibaraki.jp +kasumigaura.ibaraki.jp +koga.ibaraki.jp +miho.ibaraki.jp +mito.ibaraki.jp +moriya.ibaraki.jp +naka.ibaraki.jp +namegata.ibaraki.jp +oarai.ibaraki.jp +ogawa.ibaraki.jp +omitama.ibaraki.jp +ryugasaki.ibaraki.jp +sakai.ibaraki.jp +sakuragawa.ibaraki.jp +shimodate.ibaraki.jp +shimotsuma.ibaraki.jp +shirosato.ibaraki.jp +sowa.ibaraki.jp +suifu.ibaraki.jp +takahagi.ibaraki.jp +tamatsukuri.ibaraki.jp +tokai.ibaraki.jp +tomobe.ibaraki.jp +tone.ibaraki.jp +toride.ibaraki.jp +tsuchiura.ibaraki.jp +tsukuba.ibaraki.jp +uchihara.ibaraki.jp +ushiku.ibaraki.jp +yachiyo.ibaraki.jp +yamagata.ibaraki.jp +yawara.ibaraki.jp +yuki.ibaraki.jp +anamizu.ishikawa.jp +hakui.ishikawa.jp +hakusan.ishikawa.jp +kaga.ishikawa.jp +kahoku.ishikawa.jp +kanazawa.ishikawa.jp +kawakita.ishikawa.jp +komatsu.ishikawa.jp +nakanoto.ishikawa.jp +nanao.ishikawa.jp +nomi.ishikawa.jp +nonoichi.ishikawa.jp +noto.ishikawa.jp +shika.ishikawa.jp +suzu.ishikawa.jp +tsubata.ishikawa.jp +tsurugi.ishikawa.jp +uchinada.ishikawa.jp +wajima.ishikawa.jp +fudai.iwate.jp +fujisawa.iwate.jp +hanamaki.iwate.jp +hiraizumi.iwate.jp +hirono.iwate.jp +ichinohe.iwate.jp +ichinoseki.iwate.jp +iwaizumi.iwate.jp +iwate.iwate.jp +joboji.iwate.jp +kamaishi.iwate.jp +kanegasaki.iwate.jp +karumai.iwate.jp +kawai.iwate.jp +kitakami.iwate.jp +kuji.iwate.jp +kunohe.iwate.jp +kuzumaki.iwate.jp +miyako.iwate.jp +mizusawa.iwate.jp +morioka.iwate.jp +ninohe.iwate.jp +noda.iwate.jp +ofunato.iwate.jp +oshu.iwate.jp +otsuchi.iwate.jp +rikuzentakata.iwate.jp +shiwa.iwate.jp +shizukuishi.iwate.jp +sumita.iwate.jp +tanohata.iwate.jp +tono.iwate.jp +yahaba.iwate.jp +yamada.iwate.jp +ayagawa.kagawa.jp +higashikagawa.kagawa.jp +kanonji.kagawa.jp +kotohira.kagawa.jp +manno.kagawa.jp +marugame.kagawa.jp +mitoyo.kagawa.jp +naoshima.kagawa.jp +sanuki.kagawa.jp +tadotsu.kagawa.jp +takamatsu.kagawa.jp +tonosho.kagawa.jp +uchinomi.kagawa.jp +utazu.kagawa.jp +zentsuji.kagawa.jp +akune.kagoshima.jp +amami.kagoshima.jp +hioki.kagoshima.jp +isa.kagoshima.jp +isen.kagoshima.jp +izumi.kagoshima.jp +kagoshima.kagoshima.jp +kanoya.kagoshima.jp +kawanabe.kagoshima.jp +kinko.kagoshima.jp +kouyama.kagoshima.jp +makurazaki.kagoshima.jp +matsumoto.kagoshima.jp +minamitane.kagoshima.jp +nakatane.kagoshima.jp +nishinoomote.kagoshima.jp +satsumasendai.kagoshima.jp +soo.kagoshima.jp +tarumizu.kagoshima.jp +yusui.kagoshima.jp +aikawa.kanagawa.jp +atsugi.kanagawa.jp +ayase.kanagawa.jp +chigasaki.kanagawa.jp +ebina.kanagawa.jp +fujisawa.kanagawa.jp +hadano.kanagawa.jp +hakone.kanagawa.jp +hiratsuka.kanagawa.jp +isehara.kanagawa.jp +kaisei.kanagawa.jp +kamakura.kanagawa.jp +kiyokawa.kanagawa.jp +matsuda.kanagawa.jp +minamiashigara.kanagawa.jp +miura.kanagawa.jp +nakai.kanagawa.jp +ninomiya.kanagawa.jp +odawara.kanagawa.jp +oi.kanagawa.jp +oiso.kanagawa.jp +sagamihara.kanagawa.jp +samukawa.kanagawa.jp +tsukui.kanagawa.jp +yamakita.kanagawa.jp +yamato.kanagawa.jp +yokosuka.kanagawa.jp +yugawara.kanagawa.jp +zama.kanagawa.jp +zushi.kanagawa.jp +aki.kochi.jp +geisei.kochi.jp +hidaka.kochi.jp +higashitsuno.kochi.jp +ino.kochi.jp +kagami.kochi.jp +kami.kochi.jp +kitagawa.kochi.jp +kochi.kochi.jp +mihara.kochi.jp +motoyama.kochi.jp +muroto.kochi.jp +nahari.kochi.jp +nakamura.kochi.jp +nankoku.kochi.jp +nishitosa.kochi.jp +niyodogawa.kochi.jp +ochi.kochi.jp +okawa.kochi.jp +otoyo.kochi.jp +otsuki.kochi.jp +sakawa.kochi.jp +sukumo.kochi.jp +susaki.kochi.jp +tosa.kochi.jp +tosashimizu.kochi.jp +toyo.kochi.jp +tsuno.kochi.jp +umaji.kochi.jp +yasuda.kochi.jp +yusuhara.kochi.jp +amakusa.kumamoto.jp +arao.kumamoto.jp +aso.kumamoto.jp +choyo.kumamoto.jp +gyokuto.kumamoto.jp +kamiamakusa.kumamoto.jp +kikuchi.kumamoto.jp +kumamoto.kumamoto.jp +mashiki.kumamoto.jp +mifune.kumamoto.jp +minamata.kumamoto.jp +minamioguni.kumamoto.jp +nagasu.kumamoto.jp +nishihara.kumamoto.jp +oguni.kumamoto.jp +ozu.kumamoto.jp +sumoto.kumamoto.jp +takamori.kumamoto.jp +uki.kumamoto.jp +uto.kumamoto.jp +yamaga.kumamoto.jp +yamato.kumamoto.jp +yatsushiro.kumamoto.jp +ayabe.kyoto.jp +fukuchiyama.kyoto.jp +higashiyama.kyoto.jp +ide.kyoto.jp +ine.kyoto.jp +joyo.kyoto.jp +kameoka.kyoto.jp +kamo.kyoto.jp +kita.kyoto.jp +kizu.kyoto.jp +kumiyama.kyoto.jp +kyotamba.kyoto.jp +kyotanabe.kyoto.jp +kyotango.kyoto.jp +maizuru.kyoto.jp +minami.kyoto.jp +minamiyamashiro.kyoto.jp +miyazu.kyoto.jp +muko.kyoto.jp +nagaokakyo.kyoto.jp +nakagyo.kyoto.jp +nantan.kyoto.jp +oyamazaki.kyoto.jp +sakyo.kyoto.jp +seika.kyoto.jp +tanabe.kyoto.jp +uji.kyoto.jp +ujitawara.kyoto.jp +wazuka.kyoto.jp +yamashina.kyoto.jp +yawata.kyoto.jp +asahi.mie.jp +inabe.mie.jp +ise.mie.jp +kameyama.mie.jp +kawagoe.mie.jp +kiho.mie.jp +kisosaki.mie.jp +kiwa.mie.jp +komono.mie.jp +kumano.mie.jp +kuwana.mie.jp +matsusaka.mie.jp +meiwa.mie.jp +mihama.mie.jp +minamiise.mie.jp +misugi.mie.jp +miyama.mie.jp +nabari.mie.jp +shima.mie.jp +suzuka.mie.jp +tado.mie.jp +taiki.mie.jp +taki.mie.jp +tamaki.mie.jp +toba.mie.jp +tsu.mie.jp +udono.mie.jp +ureshino.mie.jp +watarai.mie.jp +yokkaichi.mie.jp +furukawa.miyagi.jp +higashimatsushima.miyagi.jp +ishinomaki.miyagi.jp +iwanuma.miyagi.jp +kakuda.miyagi.jp +kami.miyagi.jp +kawasaki.miyagi.jp +marumori.miyagi.jp +matsushima.miyagi.jp +minamisanriku.miyagi.jp +misato.miyagi.jp +murata.miyagi.jp +natori.miyagi.jp +ogawara.miyagi.jp +ohira.miyagi.jp +onagawa.miyagi.jp +osaki.miyagi.jp +rifu.miyagi.jp +semine.miyagi.jp +shibata.miyagi.jp +shichikashuku.miyagi.jp +shikama.miyagi.jp +shiogama.miyagi.jp +shiroishi.miyagi.jp +tagajo.miyagi.jp +taiwa.miyagi.jp +tome.miyagi.jp +tomiya.miyagi.jp +wakuya.miyagi.jp +watari.miyagi.jp +yamamoto.miyagi.jp +zao.miyagi.jp +aya.miyazaki.jp +ebino.miyazaki.jp +gokase.miyazaki.jp +hyuga.miyazaki.jp +kadogawa.miyazaki.jp +kawaminami.miyazaki.jp +kijo.miyazaki.jp +kitagawa.miyazaki.jp +kitakata.miyazaki.jp +kitaura.miyazaki.jp +kobayashi.miyazaki.jp +kunitomi.miyazaki.jp +kushima.miyazaki.jp +mimata.miyazaki.jp +miyakonojo.miyazaki.jp +miyazaki.miyazaki.jp +morotsuka.miyazaki.jp +nichinan.miyazaki.jp +nishimera.miyazaki.jp +nobeoka.miyazaki.jp +saito.miyazaki.jp +shiiba.miyazaki.jp +shintomi.miyazaki.jp +takaharu.miyazaki.jp +takanabe.miyazaki.jp +takazaki.miyazaki.jp +tsuno.miyazaki.jp +achi.nagano.jp +agematsu.nagano.jp +anan.nagano.jp +aoki.nagano.jp +asahi.nagano.jp +azumino.nagano.jp +chikuhoku.nagano.jp +chikuma.nagano.jp +chino.nagano.jp +fujimi.nagano.jp +hakuba.nagano.jp +hara.nagano.jp +hiraya.nagano.jp +iida.nagano.jp +iijima.nagano.jp +iiyama.nagano.jp +iizuna.nagano.jp +ikeda.nagano.jp +ikusaka.nagano.jp +ina.nagano.jp +karuizawa.nagano.jp +kawakami.nagano.jp +kiso.nagano.jp +kisofukushima.nagano.jp +kitaaiki.nagano.jp +komagane.nagano.jp +komoro.nagano.jp +matsukawa.nagano.jp +matsumoto.nagano.jp +miasa.nagano.jp +minamiaiki.nagano.jp +minamimaki.nagano.jp +minamiminowa.nagano.jp +minowa.nagano.jp +miyada.nagano.jp +miyota.nagano.jp +mochizuki.nagano.jp +nagano.nagano.jp +nagawa.nagano.jp +nagiso.nagano.jp +nakagawa.nagano.jp +nakano.nagano.jp +nozawaonsen.nagano.jp +obuse.nagano.jp +ogawa.nagano.jp +okaya.nagano.jp +omachi.nagano.jp +omi.nagano.jp +ookuwa.nagano.jp +ooshika.nagano.jp +otaki.nagano.jp +otari.nagano.jp +sakae.nagano.jp +sakaki.nagano.jp +saku.nagano.jp +sakuho.nagano.jp +shimosuwa.nagano.jp +shinanomachi.nagano.jp +shiojiri.nagano.jp +suwa.nagano.jp +suzaka.nagano.jp +takagi.nagano.jp +takamori.nagano.jp +takayama.nagano.jp +tateshina.nagano.jp +tatsuno.nagano.jp +togakushi.nagano.jp +togura.nagano.jp +tomi.nagano.jp +ueda.nagano.jp +wada.nagano.jp +yamagata.nagano.jp +yamanouchi.nagano.jp +yasaka.nagano.jp +yasuoka.nagano.jp +chijiwa.nagasaki.jp +futsu.nagasaki.jp +goto.nagasaki.jp +hasami.nagasaki.jp +hirado.nagasaki.jp +iki.nagasaki.jp +isahaya.nagasaki.jp +kawatana.nagasaki.jp +kuchinotsu.nagasaki.jp +matsuura.nagasaki.jp +nagasaki.nagasaki.jp +obama.nagasaki.jp +omura.nagasaki.jp +oseto.nagasaki.jp +saikai.nagasaki.jp +sasebo.nagasaki.jp +seihi.nagasaki.jp +shimabara.nagasaki.jp +shinkamigoto.nagasaki.jp +togitsu.nagasaki.jp +tsushima.nagasaki.jp +unzen.nagasaki.jp +ando.nara.jp +gose.nara.jp +heguri.nara.jp +higashiyoshino.nara.jp +ikaruga.nara.jp +ikoma.nara.jp +kamikitayama.nara.jp +kanmaki.nara.jp +kashiba.nara.jp +kashihara.nara.jp +katsuragi.nara.jp +kawai.nara.jp +kawakami.nara.jp +kawanishi.nara.jp +koryo.nara.jp +kurotaki.nara.jp +mitsue.nara.jp +miyake.nara.jp +nara.nara.jp +nosegawa.nara.jp +oji.nara.jp +ouda.nara.jp +oyodo.nara.jp +sakurai.nara.jp +sango.nara.jp +shimoichi.nara.jp +shimokitayama.nara.jp +shinjo.nara.jp +soni.nara.jp +takatori.nara.jp +tawaramoto.nara.jp +tenkawa.nara.jp +tenri.nara.jp +uda.nara.jp +yamatokoriyama.nara.jp +yamatotakada.nara.jp +yamazoe.nara.jp +yoshino.nara.jp +aga.niigata.jp +agano.niigata.jp +gosen.niigata.jp +itoigawa.niigata.jp +izumozaki.niigata.jp +joetsu.niigata.jp +kamo.niigata.jp +kariwa.niigata.jp +kashiwazaki.niigata.jp +minamiuonuma.niigata.jp +mitsuke.niigata.jp +muika.niigata.jp +murakami.niigata.jp +myoko.niigata.jp +nagaoka.niigata.jp +niigata.niigata.jp +ojiya.niigata.jp +omi.niigata.jp +sado.niigata.jp +sanjo.niigata.jp +seiro.niigata.jp +seirou.niigata.jp +sekikawa.niigata.jp +shibata.niigata.jp +tagami.niigata.jp +tainai.niigata.jp +tochio.niigata.jp +tokamachi.niigata.jp +tsubame.niigata.jp +tsunan.niigata.jp +uonuma.niigata.jp +yahiko.niigata.jp +yoita.niigata.jp +yuzawa.niigata.jp +beppu.oita.jp +bungoono.oita.jp +bungotakada.oita.jp +hasama.oita.jp +hiji.oita.jp +himeshima.oita.jp +hita.oita.jp +kamitsue.oita.jp +kokonoe.oita.jp +kuju.oita.jp +kunisaki.oita.jp +kusu.oita.jp +oita.oita.jp +saiki.oita.jp +taketa.oita.jp +tsukumi.oita.jp +usa.oita.jp +usuki.oita.jp +yufu.oita.jp +akaiwa.okayama.jp +asakuchi.okayama.jp +bizen.okayama.jp +hayashima.okayama.jp +ibara.okayama.jp +kagamino.okayama.jp +kasaoka.okayama.jp +kibichuo.okayama.jp +kumenan.okayama.jp +kurashiki.okayama.jp +maniwa.okayama.jp +misaki.okayama.jp +nagi.okayama.jp +niimi.okayama.jp +nishiawakura.okayama.jp +okayama.okayama.jp +satosho.okayama.jp +setouchi.okayama.jp +shinjo.okayama.jp +shoo.okayama.jp +soja.okayama.jp +takahashi.okayama.jp +tamano.okayama.jp +tsuyama.okayama.jp +wake.okayama.jp +yakage.okayama.jp +aguni.okinawa.jp +ginowan.okinawa.jp +ginoza.okinawa.jp +gushikami.okinawa.jp +haebaru.okinawa.jp +higashi.okinawa.jp +hirara.okinawa.jp +iheya.okinawa.jp +ishigaki.okinawa.jp +ishikawa.okinawa.jp +itoman.okinawa.jp +izena.okinawa.jp +kadena.okinawa.jp +kin.okinawa.jp +kitadaito.okinawa.jp +kitanakagusuku.okinawa.jp +kumejima.okinawa.jp +kunigami.okinawa.jp +minamidaito.okinawa.jp +motobu.okinawa.jp +nago.okinawa.jp +naha.okinawa.jp +nakagusuku.okinawa.jp +nakijin.okinawa.jp +nanjo.okinawa.jp +nishihara.okinawa.jp +ogimi.okinawa.jp +okinawa.okinawa.jp +onna.okinawa.jp +shimoji.okinawa.jp +taketomi.okinawa.jp +tarama.okinawa.jp +tokashiki.okinawa.jp +tomigusuku.okinawa.jp +tonaki.okinawa.jp +urasoe.okinawa.jp +uruma.okinawa.jp +yaese.okinawa.jp +yomitan.okinawa.jp +yonabaru.okinawa.jp +yonaguni.okinawa.jp +zamami.okinawa.jp +abeno.osaka.jp +chihayaakasaka.osaka.jp +chuo.osaka.jp +daito.osaka.jp +fujiidera.osaka.jp +habikino.osaka.jp +hannan.osaka.jp +higashiosaka.osaka.jp +higashisumiyoshi.osaka.jp +higashiyodogawa.osaka.jp +hirakata.osaka.jp +ibaraki.osaka.jp +ikeda.osaka.jp +izumi.osaka.jp +izumiotsu.osaka.jp +izumisano.osaka.jp +kadoma.osaka.jp +kaizuka.osaka.jp +kanan.osaka.jp +kashiwara.osaka.jp +katano.osaka.jp +kawachinagano.osaka.jp +kishiwada.osaka.jp +kita.osaka.jp +kumatori.osaka.jp +matsubara.osaka.jp +minato.osaka.jp +minoh.osaka.jp +misaki.osaka.jp +moriguchi.osaka.jp +neyagawa.osaka.jp +nishi.osaka.jp +nose.osaka.jp +osakasayama.osaka.jp +sakai.osaka.jp +sayama.osaka.jp +sennan.osaka.jp +settsu.osaka.jp +shijonawate.osaka.jp +shimamoto.osaka.jp +suita.osaka.jp +tadaoka.osaka.jp +taishi.osaka.jp +tajiri.osaka.jp +takaishi.osaka.jp +takatsuki.osaka.jp +tondabayashi.osaka.jp +toyonaka.osaka.jp +toyono.osaka.jp +yao.osaka.jp +ariake.saga.jp +arita.saga.jp +fukudomi.saga.jp +genkai.saga.jp +hamatama.saga.jp +hizen.saga.jp +imari.saga.jp +kamimine.saga.jp +kanzaki.saga.jp +karatsu.saga.jp +kashima.saga.jp +kitagata.saga.jp +kitahata.saga.jp +kiyama.saga.jp +kouhoku.saga.jp +kyuragi.saga.jp +nishiarita.saga.jp +ogi.saga.jp +omachi.saga.jp +ouchi.saga.jp +saga.saga.jp +shiroishi.saga.jp +taku.saga.jp +tara.saga.jp +tosu.saga.jp +yoshinogari.saga.jp +arakawa.saitama.jp +asaka.saitama.jp +chichibu.saitama.jp +fujimi.saitama.jp +fujimino.saitama.jp +fukaya.saitama.jp +hanno.saitama.jp +hanyu.saitama.jp +hasuda.saitama.jp +hatogaya.saitama.jp +hatoyama.saitama.jp +hidaka.saitama.jp +higashichichibu.saitama.jp +higashimatsuyama.saitama.jp +honjo.saitama.jp +ina.saitama.jp +iruma.saitama.jp +iwatsuki.saitama.jp +kamiizumi.saitama.jp +kamikawa.saitama.jp +kamisato.saitama.jp +kasukabe.saitama.jp +kawagoe.saitama.jp +kawaguchi.saitama.jp +kawajima.saitama.jp +kazo.saitama.jp +kitamoto.saitama.jp +koshigaya.saitama.jp +kounosu.saitama.jp +kuki.saitama.jp +kumagaya.saitama.jp +matsubushi.saitama.jp +minano.saitama.jp +misato.saitama.jp +miyashiro.saitama.jp +miyoshi.saitama.jp +moroyama.saitama.jp +nagatoro.saitama.jp +namegawa.saitama.jp +niiza.saitama.jp +ogano.saitama.jp +ogawa.saitama.jp +ogose.saitama.jp +okegawa.saitama.jp +omiya.saitama.jp +otaki.saitama.jp +ranzan.saitama.jp +ryokami.saitama.jp +saitama.saitama.jp +sakado.saitama.jp +satte.saitama.jp +sayama.saitama.jp +shiki.saitama.jp +shiraoka.saitama.jp +soka.saitama.jp +sugito.saitama.jp +toda.saitama.jp +tokigawa.saitama.jp +tokorozawa.saitama.jp +tsurugashima.saitama.jp +urawa.saitama.jp +warabi.saitama.jp +yashio.saitama.jp +yokoze.saitama.jp +yono.saitama.jp +yorii.saitama.jp +yoshida.saitama.jp +yoshikawa.saitama.jp +yoshimi.saitama.jp +aisho.shiga.jp +gamo.shiga.jp +higashiomi.shiga.jp +hikone.shiga.jp +koka.shiga.jp +konan.shiga.jp +kosei.shiga.jp +koto.shiga.jp +kusatsu.shiga.jp +maibara.shiga.jp +moriyama.shiga.jp +nagahama.shiga.jp +nishiazai.shiga.jp +notogawa.shiga.jp +omihachiman.shiga.jp +otsu.shiga.jp +ritto.shiga.jp +ryuoh.shiga.jp +takashima.shiga.jp +takatsuki.shiga.jp +torahime.shiga.jp +toyosato.shiga.jp +yasu.shiga.jp +akagi.shimane.jp +ama.shimane.jp +gotsu.shimane.jp +hamada.shimane.jp +higashiizumo.shimane.jp +hikawa.shimane.jp +hikimi.shimane.jp +izumo.shimane.jp +kakinoki.shimane.jp +masuda.shimane.jp +matsue.shimane.jp +misato.shimane.jp +nishinoshima.shimane.jp +ohda.shimane.jp +okinoshima.shimane.jp +okuizumo.shimane.jp +shimane.shimane.jp +tamayu.shimane.jp +tsuwano.shimane.jp +unnan.shimane.jp +yakumo.shimane.jp +yasugi.shimane.jp +yatsuka.shimane.jp +arai.shizuoka.jp +atami.shizuoka.jp +fuji.shizuoka.jp +fujieda.shizuoka.jp +fujikawa.shizuoka.jp +fujinomiya.shizuoka.jp +fukuroi.shizuoka.jp +gotemba.shizuoka.jp +haibara.shizuoka.jp +hamamatsu.shizuoka.jp +higashiizu.shizuoka.jp +ito.shizuoka.jp +iwata.shizuoka.jp +izu.shizuoka.jp +izunokuni.shizuoka.jp +kakegawa.shizuoka.jp +kannami.shizuoka.jp +kawanehon.shizuoka.jp +kawazu.shizuoka.jp +kikugawa.shizuoka.jp +kosai.shizuoka.jp +makinohara.shizuoka.jp +matsuzaki.shizuoka.jp +minamiizu.shizuoka.jp +mishima.shizuoka.jp +morimachi.shizuoka.jp +nishiizu.shizuoka.jp +numazu.shizuoka.jp +omaezaki.shizuoka.jp +shimada.shizuoka.jp +shimizu.shizuoka.jp +shimoda.shizuoka.jp +shizuoka.shizuoka.jp +susono.shizuoka.jp +yaizu.shizuoka.jp +yoshida.shizuoka.jp +ashikaga.tochigi.jp +bato.tochigi.jp +haga.tochigi.jp +ichikai.tochigi.jp +iwafune.tochigi.jp +kaminokawa.tochigi.jp +kanuma.tochigi.jp +karasuyama.tochigi.jp +kuroiso.tochigi.jp +mashiko.tochigi.jp +mibu.tochigi.jp +moka.tochigi.jp +motegi.tochigi.jp +nasu.tochigi.jp +nasushiobara.tochigi.jp +nikko.tochigi.jp +nishikata.tochigi.jp +nogi.tochigi.jp +ohira.tochigi.jp +ohtawara.tochigi.jp +oyama.tochigi.jp +sakura.tochigi.jp +sano.tochigi.jp +shimotsuke.tochigi.jp +shioya.tochigi.jp +takanezawa.tochigi.jp +tochigi.tochigi.jp +tsuga.tochigi.jp +ujiie.tochigi.jp +utsunomiya.tochigi.jp +yaita.tochigi.jp +aizumi.tokushima.jp +anan.tokushima.jp +ichiba.tokushima.jp +itano.tokushima.jp +kainan.tokushima.jp +komatsushima.tokushima.jp +matsushige.tokushima.jp +mima.tokushima.jp +minami.tokushima.jp +miyoshi.tokushima.jp +mugi.tokushima.jp +nakagawa.tokushima.jp +naruto.tokushima.jp +sanagochi.tokushima.jp +shishikui.tokushima.jp +tokushima.tokushima.jp +wajiki.tokushima.jp +adachi.tokyo.jp +akiruno.tokyo.jp +akishima.tokyo.jp +aogashima.tokyo.jp +arakawa.tokyo.jp +bunkyo.tokyo.jp +chiyoda.tokyo.jp +chofu.tokyo.jp +chuo.tokyo.jp +edogawa.tokyo.jp +fuchu.tokyo.jp +fussa.tokyo.jp +hachijo.tokyo.jp +hachioji.tokyo.jp +hamura.tokyo.jp +higashikurume.tokyo.jp +higashimurayama.tokyo.jp +higashiyamato.tokyo.jp +hino.tokyo.jp +hinode.tokyo.jp +hinohara.tokyo.jp +inagi.tokyo.jp +itabashi.tokyo.jp +katsushika.tokyo.jp +kita.tokyo.jp +kiyose.tokyo.jp +kodaira.tokyo.jp +koganei.tokyo.jp +kokubunji.tokyo.jp +komae.tokyo.jp +koto.tokyo.jp +kouzushima.tokyo.jp +kunitachi.tokyo.jp +machida.tokyo.jp +meguro.tokyo.jp +minato.tokyo.jp +mitaka.tokyo.jp +mizuho.tokyo.jp +musashimurayama.tokyo.jp +musashino.tokyo.jp +nakano.tokyo.jp +nerima.tokyo.jp +ogasawara.tokyo.jp +okutama.tokyo.jp +ome.tokyo.jp +oshima.tokyo.jp +ota.tokyo.jp +setagaya.tokyo.jp +shibuya.tokyo.jp +shinagawa.tokyo.jp +shinjuku.tokyo.jp +suginami.tokyo.jp +sumida.tokyo.jp +tachikawa.tokyo.jp +taito.tokyo.jp +tama.tokyo.jp +toshima.tokyo.jp +chizu.tottori.jp +hino.tottori.jp +kawahara.tottori.jp +koge.tottori.jp +kotoura.tottori.jp +misasa.tottori.jp +nanbu.tottori.jp +nichinan.tottori.jp +sakaiminato.tottori.jp +tottori.tottori.jp +wakasa.tottori.jp +yazu.tottori.jp +yonago.tottori.jp +asahi.toyama.jp +fuchu.toyama.jp +fukumitsu.toyama.jp +funahashi.toyama.jp +himi.toyama.jp +imizu.toyama.jp +inami.toyama.jp +johana.toyama.jp +kamiichi.toyama.jp +kurobe.toyama.jp +nakaniikawa.toyama.jp +namerikawa.toyama.jp +nanto.toyama.jp +nyuzen.toyama.jp +oyabe.toyama.jp +taira.toyama.jp +takaoka.toyama.jp +tateyama.toyama.jp +toga.toyama.jp +tonami.toyama.jp +toyama.toyama.jp +unazuki.toyama.jp +uozu.toyama.jp +yamada.toyama.jp +arida.wakayama.jp +aridagawa.wakayama.jp +gobo.wakayama.jp +hashimoto.wakayama.jp +hidaka.wakayama.jp +hirogawa.wakayama.jp +inami.wakayama.jp +iwade.wakayama.jp +kainan.wakayama.jp +kamitonda.wakayama.jp +katsuragi.wakayama.jp +kimino.wakayama.jp +kinokawa.wakayama.jp +kitayama.wakayama.jp +koya.wakayama.jp +koza.wakayama.jp +kozagawa.wakayama.jp +kudoyama.wakayama.jp +kushimoto.wakayama.jp +mihama.wakayama.jp +misato.wakayama.jp +nachikatsuura.wakayama.jp +shingu.wakayama.jp +shirahama.wakayama.jp +taiji.wakayama.jp +tanabe.wakayama.jp +wakayama.wakayama.jp +yuasa.wakayama.jp +yura.wakayama.jp +asahi.yamagata.jp +funagata.yamagata.jp +higashine.yamagata.jp +iide.yamagata.jp +kahoku.yamagata.jp +kaminoyama.yamagata.jp +kaneyama.yamagata.jp +kawanishi.yamagata.jp +mamurogawa.yamagata.jp +mikawa.yamagata.jp +murayama.yamagata.jp +nagai.yamagata.jp +nakayama.yamagata.jp +nanyo.yamagata.jp +nishikawa.yamagata.jp +obanazawa.yamagata.jp +oe.yamagata.jp +oguni.yamagata.jp +ohkura.yamagata.jp +oishida.yamagata.jp +sagae.yamagata.jp +sakata.yamagata.jp +sakegawa.yamagata.jp +shinjo.yamagata.jp +shirataka.yamagata.jp +shonai.yamagata.jp +takahata.yamagata.jp +tendo.yamagata.jp +tozawa.yamagata.jp +tsuruoka.yamagata.jp +yamagata.yamagata.jp +yamanobe.yamagata.jp +yonezawa.yamagata.jp +yuza.yamagata.jp +abu.yamaguchi.jp +hagi.yamaguchi.jp +hikari.yamaguchi.jp +hofu.yamaguchi.jp +iwakuni.yamaguchi.jp +kudamatsu.yamaguchi.jp +mitou.yamaguchi.jp +nagato.yamaguchi.jp +oshima.yamaguchi.jp +shimonoseki.yamaguchi.jp +shunan.yamaguchi.jp +tabuse.yamaguchi.jp +tokuyama.yamaguchi.jp +toyota.yamaguchi.jp +ube.yamaguchi.jp +yuu.yamaguchi.jp +chuo.yamanashi.jp +doshi.yamanashi.jp +fuefuki.yamanashi.jp +fujikawa.yamanashi.jp +fujikawaguchiko.yamanashi.jp +fujiyoshida.yamanashi.jp +hayakawa.yamanashi.jp +hokuto.yamanashi.jp +ichikawamisato.yamanashi.jp +kai.yamanashi.jp +kofu.yamanashi.jp +koshu.yamanashi.jp +kosuge.yamanashi.jp +minami-alps.yamanashi.jp +minobu.yamanashi.jp +nakamichi.yamanashi.jp +nanbu.yamanashi.jp +narusawa.yamanashi.jp +nirasaki.yamanashi.jp +nishikatsura.yamanashi.jp +oshino.yamanashi.jp +otsuki.yamanashi.jp +showa.yamanashi.jp +tabayama.yamanashi.jp +tsuru.yamanashi.jp +uenohara.yamanashi.jp +yamanakako.yamanashi.jp +yamanashi.yamanashi.jp + +// ke : http://www.kenic.or.ke/index.php/en/ke-domains/ke-domains +ke +ac.ke +co.ke +go.ke +info.ke +me.ke +mobi.ke +ne.ke +or.ke +sc.ke + +// kg : http://www.domain.kg/dmn_n.html +kg +com.kg +edu.kg +gov.kg +mil.kg +net.kg +org.kg + +// kh : http://www.mptc.gov.kh/dns_registration.htm +*.kh + +// ki : https://www.iana.org/domains/root/db/ki.html +ki +biz.ki +com.ki +edu.ki +gov.ki +info.ki +net.ki +org.ki + +// km : https://www.iana.org/domains/root/db/km.html +// http://www.domaine.km/documents/charte.doc +km +ass.km +com.km +edu.km +gov.km +mil.km +nom.km +org.km +prd.km +tm.km +// These are only mentioned as proposed suggestions at domaine.km, but +// https://www.iana.org/domains/root/db/km.html says they're available for registration: +asso.km +coop.km +gouv.km +medecin.km +notaires.km +pharmaciens.km +presse.km +veterinaire.km + +// kn : https://www.iana.org/domains/root/db/kn.html +// http://www.dot.kn/domainRules.html +kn +edu.kn +gov.kn +net.kn +org.kn + +// kp : http://www.kcce.kp/en_index.php +kp +com.kp +edu.kp +gov.kp +org.kp +rep.kp +tra.kp + +// kr : https://www.iana.org/domains/root/db/kr.html +// see also: https://krnic.kisa.or.kr/jsp/infoboard/law/domBylawsReg.jsp +kr +ac.kr +ai.kr +co.kr +es.kr +go.kr +hs.kr +io.kr +it.kr +kg.kr +me.kr +mil.kr +ms.kr +ne.kr +or.kr +pe.kr +re.kr +sc.kr +// kr geographical names +busan.kr +chungbuk.kr +chungnam.kr +daegu.kr +daejeon.kr +gangwon.kr +gwangju.kr +gyeongbuk.kr +gyeonggi.kr +gyeongnam.kr +incheon.kr +jeju.kr +jeonbuk.kr +jeonnam.kr +seoul.kr +ulsan.kr + +// kw : https://www.nic.kw/policies/ +// Confirmed by registry +kw +com.kw +edu.kw +emb.kw +gov.kw +ind.kw +net.kw +org.kw + +// ky : http://www.icta.ky/da_ky_reg_dom.php +// Confirmed by registry 2008-06-17 +ky +com.ky +edu.ky +net.ky +org.ky + +// kz : https://www.iana.org/domains/root/db/kz.html +// see also: http://www.nic.kz/rules/index.jsp +kz +com.kz +edu.kz +gov.kz +mil.kz +net.kz +org.kz + +// la : https://www.iana.org/domains/root/db/la.html +// Submitted by registry +la +com.la +edu.la +gov.la +info.la +int.la +net.la +org.la +per.la + +// lb : https://www.iana.org/domains/root/db/lb.html +// Submitted by registry +lb +com.lb +edu.lb +gov.lb +net.lb +org.lb + +// lc : https://www.iana.org/domains/root/db/lc.html +// see also: http://www.nic.lc/rules.htm +lc +co.lc +com.lc +edu.lc +gov.lc +net.lc +org.lc + +// li : https://www.iana.org/domains/root/db/li.html +li + +// lk : https://www.iana.org/domains/root/db/lk.html +lk +ac.lk +assn.lk +com.lk +edu.lk +gov.lk +grp.lk +hotel.lk +int.lk +ltd.lk +net.lk +ngo.lk +org.lk +sch.lk +soc.lk +web.lk + +// lr : http://psg.com/dns/lr/lr.txt +// Submitted by registry +lr +com.lr +edu.lr +gov.lr +net.lr +org.lr + +// ls : http://www.nic.ls/ +// Confirmed by registry +ls +ac.ls +biz.ls +co.ls +edu.ls +gov.ls +info.ls +net.ls +org.ls +sc.ls + +// lt : https://www.iana.org/domains/root/db/lt.html +lt +// gov.lt : http://www.gov.lt/index_en.php +gov.lt + +// lu : http://www.dns.lu/en/ +lu + +// lv : https://www.iana.org/domains/root/db/lv.html +lv +asn.lv +com.lv +conf.lv +edu.lv +gov.lv +id.lv +mil.lv +net.lv +org.lv + +// ly : http://www.nic.ly/regulations.php +ly +com.ly +edu.ly +gov.ly +id.ly +med.ly +net.ly +org.ly +plc.ly +sch.ly + +// ma : https://www.iana.org/domains/root/db/ma.html +// http://www.anrt.ma/fr/admin/download/upload/file_fr782.pdf +ma +ac.ma +co.ma +gov.ma +net.ma +org.ma +press.ma + +// mc : http://www.nic.mc/ +mc +asso.mc +tm.mc + +// md : https://www.iana.org/domains/root/db/md.html +md + +// me : https://www.iana.org/domains/root/db/me.html +me +ac.me +co.me +edu.me +gov.me +its.me +net.me +org.me +priv.me + +// mg : https://nic.mg +mg +co.mg +com.mg +edu.mg +gov.mg +mil.mg +nom.mg +org.mg +prd.mg + +// mh : https://www.iana.org/domains/root/db/mh.html +mh + +// mil : https://www.iana.org/domains/root/db/mil.html +mil + +// mk : https://www.iana.org/domains/root/db/mk.html +// see also: http://dns.marnet.net.mk/postapka.php +mk +com.mk +edu.mk +gov.mk +inf.mk +name.mk +net.mk +org.mk + +// ml : https://www.iana.org/domains/root/db/ml.html +// Confirmed by Boubacar NDIAYE 2024-12-31 +ml +ac.ml +art.ml +asso.ml +com.ml +edu.ml +gouv.ml +gov.ml +info.ml +inst.ml +net.ml +org.ml +pr.ml +presse.ml + +// mm : https://www.iana.org/domains/root/db/mm.html +*.mm + +// mn : https://www.iana.org/domains/root/db/mn.html +mn +edu.mn +gov.mn +org.mn + +// mo : http://www.monic.net.mo/ +mo +com.mo +edu.mo +gov.mo +net.mo +org.mo + +// mobi : https://www.iana.org/domains/root/db/mobi.html +mobi + +// mp : http://www.dot.mp/ +// Confirmed by registry 2008-06-17 +mp + +// mq : https://www.iana.org/domains/root/db/mq.html +mq + +// mr : https://www.iana.org/domains/root/db/mr.html +mr +gov.mr + +// ms : https://www.iana.org/domains/root/db/ms.html +ms +com.ms +edu.ms +gov.ms +net.ms +org.ms + +// mt : https://www.nic.org.mt/go/policy +// Submitted by registry +mt +com.mt +edu.mt +net.mt +org.mt + +// mu : https://www.iana.org/domains/root/db/mu.html +mu +ac.mu +co.mu +com.mu +gov.mu +net.mu +or.mu +org.mu + +// museum : https://welcome.museum/wp-content/uploads/2018/05/20180525-Registration-Policy-MUSEUM-EN_VF-2.pdf https://welcome.museum/buy-your-dot-museum-2/ +museum + +// mv : https://www.iana.org/domains/root/db/mv.html +// "mv" included because, contra Wikipedia, google.mv exists. +mv +aero.mv +biz.mv +com.mv +coop.mv +edu.mv +gov.mv +info.mv +int.mv +mil.mv +museum.mv +name.mv +net.mv +org.mv +pro.mv + +// mw : http://www.registrar.mw/ +mw +ac.mw +biz.mw +co.mw +com.mw +coop.mw +edu.mw +gov.mw +int.mw +net.mw +org.mw + +// mx : http://www.nic.mx/ +// Submitted by registry +mx +com.mx +edu.mx +gob.mx +net.mx +org.mx + +// my : http://www.mynic.my/ +// Available strings: https://mynic.my/resources/domains/buying-a-domain/ +my +biz.my +com.my +edu.my +gov.my +mil.my +name.my +net.my +org.my + +// mz : http://www.uem.mz/ +// Submitted by registry +mz +ac.mz +adv.mz +co.mz +edu.mz +gov.mz +mil.mz +net.mz +org.mz + +// na : http://www.na-nic.com.na/ +na +alt.na +co.na +com.na +gov.na +net.na +org.na + +// name : http://www.nic.name/ +// Regarding 2LDs: https://github.com/publicsuffix/list/issues/2306 +name + +// nc : http://www.cctld.nc/ +nc +asso.nc +nom.nc + +// ne : https://www.iana.org/domains/root/db/ne.html +ne + +// net : https://www.iana.org/domains/root/db/net.html +net + +// nf : https://www.iana.org/domains/root/db/nf.html +nf +arts.nf +com.nf +firm.nf +info.nf +net.nf +other.nf +per.nf +rec.nf +store.nf +web.nf + +// ng : http://www.nira.org.ng/index.php/join-us/register-ng-domain/189-nira-slds +ng +com.ng +edu.ng +gov.ng +i.ng +mil.ng +mobi.ng +name.ng +net.ng +org.ng +sch.ng + +// ni : http://www.nic.ni/ +ni +ac.ni +biz.ni +co.ni +com.ni +edu.ni +gob.ni +in.ni +info.ni +int.ni +mil.ni +net.ni +nom.ni +org.ni +web.ni + +// nl : https://www.iana.org/domains/root/db/nl.html +// https://www.sidn.nl/ +nl + +// no : https://www.norid.no/en/om-domenenavn/regelverk-for-no/ +// Norid geographical second level domains : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-b/ +// Norid category second level domains : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-c/ +// Norid category second-level domains managed by parties other than Norid : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-d/ +// RSS feed: https://teknisk.norid.no/en/feed/ +no +// Norid category second level domains : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-c/ +fhs.no +folkebibl.no +fylkesbibl.no +idrett.no +museum.no +priv.no +vgs.no +// Norid category second-level domains managed by parties other than Norid : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-d/ +dep.no +herad.no +kommune.no +mil.no +stat.no +// Norid geographical second level domains : https://www.norid.no/en/om-domenenavn/regelverk-for-no/vedlegg-b/ +// counties +aa.no +ah.no +bu.no +fm.no +hl.no +hm.no +jan-mayen.no +mr.no +nl.no +nt.no +of.no +ol.no +oslo.no +rl.no +sf.no +st.no +svalbard.no +tm.no +tr.no +va.no +vf.no +// primary and lower secondary schools per county +gs.aa.no +gs.ah.no +gs.bu.no +gs.fm.no +gs.hl.no +gs.hm.no +gs.jan-mayen.no +gs.mr.no +gs.nl.no +gs.nt.no +gs.of.no +gs.ol.no +gs.oslo.no +gs.rl.no +gs.sf.no +gs.st.no +gs.svalbard.no +gs.tm.no +gs.tr.no +gs.va.no +gs.vf.no +// cities +akrehamn.no +åkrehamn.no +algard.no +ålgård.no +arna.no +bronnoysund.no +brønnøysund.no +brumunddal.no +bryne.no +drobak.no +drøbak.no +egersund.no +fetsund.no +floro.no +florø.no +fredrikstad.no +hokksund.no +honefoss.no +hønefoss.no +jessheim.no +jorpeland.no +jørpeland.no +kirkenes.no +kopervik.no +krokstadelva.no +langevag.no +langevåg.no +leirvik.no +mjondalen.no +mjøndalen.no +mo-i-rana.no +mosjoen.no +mosjøen.no +nesoddtangen.no +orkanger.no +osoyro.no +osøyro.no +raholt.no +råholt.no +sandnessjoen.no +sandnessjøen.no +skedsmokorset.no +slattum.no +spjelkavik.no +stathelle.no +stavern.no +stjordalshalsen.no +stjørdalshalsen.no +tananger.no +tranby.no +vossevangen.no +// communities +aarborte.no +aejrie.no +afjord.no +åfjord.no +agdenes.no +nes.akershus.no +aknoluokta.no +ákŋoluokta.no +al.no +ål.no +alaheadju.no +álaheadju.no +alesund.no +ålesund.no +alstahaug.no +alta.no +áltá.no +alvdal.no +amli.no +åmli.no +amot.no +åmot.no +andasuolo.no +andebu.no +andoy.no +andøy.no +ardal.no +årdal.no +aremark.no +arendal.no +ås.no +aseral.no +åseral.no +asker.no +askim.no +askoy.no +askøy.no +askvoll.no +asnes.no +åsnes.no +audnedaln.no +aukra.no +aure.no +aurland.no +aurskog-holand.no +aurskog-høland.no +austevoll.no +austrheim.no +averoy.no +averøy.no +badaddja.no +bådåddjå.no +bærum.no +bahcavuotna.no +báhcavuotna.no +bahccavuotna.no +báhccavuotna.no +baidar.no +báidár.no +bajddar.no +bájddar.no +balat.no +bálát.no +balestrand.no +ballangen.no +balsfjord.no +bamble.no +bardu.no +barum.no +batsfjord.no +båtsfjord.no +bearalvahki.no +bearalváhki.no +beardu.no +beiarn.no +berg.no +bergen.no +berlevag.no +berlevåg.no +bievat.no +bievát.no +bindal.no +birkenes.no +bjarkoy.no +bjarkøy.no +bjerkreim.no +bjugn.no +bodo.no +bodø.no +bokn.no +bomlo.no +bømlo.no +bremanger.no +bronnoy.no +brønnøy.no +budejju.no +nes.buskerud.no +bygland.no +bykle.no +cahcesuolo.no +čáhcesuolo.no +davvenjarga.no +davvenjárga.no +davvesiida.no +deatnu.no +dielddanuorri.no +divtasvuodna.no +divttasvuotna.no +donna.no +dønna.no +dovre.no +drammen.no +drangedal.no +dyroy.no +dyrøy.no +eid.no +eidfjord.no +eidsberg.no +eidskog.no +eidsvoll.no +eigersund.no +elverum.no +enebakk.no +engerdal.no +etne.no +etnedal.no +evenassi.no +evenášši.no +evenes.no +evje-og-hornnes.no +farsund.no +fauske.no +fedje.no +fet.no +finnoy.no +finnøy.no +fitjar.no +fjaler.no +fjell.no +fla.no +flå.no +flakstad.no +flatanger.no +flekkefjord.no +flesberg.no +flora.no +folldal.no +forde.no +førde.no +forsand.no +fosnes.no +fræna.no +frana.no +frei.no +frogn.no +froland.no +frosta.no +froya.no +frøya.no +fuoisku.no +fuossko.no +fusa.no +fyresdal.no +gaivuotna.no +gáivuotna.no +galsa.no +gálsá.no +gamvik.no +gangaviika.no +gáŋgaviika.no +gaular.no +gausdal.no +giehtavuoatna.no +gildeskal.no +gildeskål.no +giske.no +gjemnes.no +gjerdrum.no +gjerstad.no +gjesdal.no +gjovik.no +gjøvik.no +gloppen.no +gol.no +gran.no +grane.no +granvin.no +gratangen.no +grimstad.no +grong.no +grue.no +gulen.no +guovdageaidnu.no +ha.no +hå.no +habmer.no +hábmer.no +hadsel.no +hægebostad.no +hagebostad.no +halden.no +halsa.no +hamar.no +hamaroy.no +hammarfeasta.no +hámmárfeasta.no +hammerfest.no +hapmir.no +hápmir.no +haram.no +hareid.no +harstad.no +hasvik.no +hattfjelldal.no +haugesund.no +os.hedmark.no +valer.hedmark.no +våler.hedmark.no +hemne.no +hemnes.no +hemsedal.no +hitra.no +hjartdal.no +hjelmeland.no +hobol.no +hobøl.no +hof.no +hol.no +hole.no +holmestrand.no +holtalen.no +holtålen.no +os.hordaland.no +hornindal.no +horten.no +hoyanger.no +høyanger.no +hoylandet.no +høylandet.no +hurdal.no +hurum.no +hvaler.no +hyllestad.no +ibestad.no +inderoy.no +inderøy.no +iveland.no +ivgu.no +jevnaker.no +jolster.no +jølster.no +jondal.no +kafjord.no +kåfjord.no +karasjohka.no +kárášjohka.no +karasjok.no +karlsoy.no +karmoy.no +karmøy.no +kautokeino.no +klabu.no +klæbu.no +klepp.no +kongsberg.no +kongsvinger.no +kraanghke.no +kråanghke.no +kragero.no +kragerø.no +kristiansand.no +kristiansund.no +krodsherad.no +krødsherad.no +kvæfjord.no +kvænangen.no +kvafjord.no +kvalsund.no +kvam.no +kvanangen.no +kvinesdal.no +kvinnherad.no +kviteseid.no +kvitsoy.no +kvitsøy.no +laakesvuemie.no +lærdal.no +lahppi.no +láhppi.no +lardal.no +larvik.no +lavagis.no +lavangen.no +leangaviika.no +leaŋgaviika.no +lebesby.no +leikanger.no +leirfjord.no +leka.no +leksvik.no +lenvik.no +lerdal.no +lesja.no +levanger.no +lier.no +lierne.no +lillehammer.no +lillesand.no +lindas.no +lindås.no +lindesnes.no +loabat.no +loabát.no +lodingen.no +lødingen.no +lom.no +loppa.no +lorenskog.no +lørenskog.no +loten.no +løten.no +lund.no +lunner.no +luroy.no +lurøy.no +luster.no +lyngdal.no +lyngen.no +malatvuopmi.no +málatvuopmi.no +malselv.no +målselv.no +malvik.no +mandal.no +marker.no +marnardal.no +masfjorden.no +masoy.no +måsøy.no +matta-varjjat.no +mátta-várjjat.no +meland.no +meldal.no +melhus.no +meloy.no +meløy.no +meraker.no +meråker.no +midsund.no +midtre-gauldal.no +moareke.no +moåreke.no +modalen.no +modum.no +molde.no +heroy.more-og-romsdal.no +sande.more-og-romsdal.no +herøy.møre-og-romsdal.no +sande.møre-og-romsdal.no +moskenes.no +moss.no +mosvik.no +muosat.no +muosát.no +naamesjevuemie.no +nååmesjevuemie.no +nærøy.no +namdalseid.no +namsos.no +namsskogan.no +nannestad.no +naroy.no +narviika.no +narvik.no +naustdal.no +navuotna.no +návuotna.no +nedre-eiker.no +nesna.no +nesodden.no +nesseby.no +nesset.no +nissedal.no +nittedal.no +nord-aurdal.no +nord-fron.no +nord-odal.no +norddal.no +nordkapp.no +bo.nordland.no +bø.nordland.no +heroy.nordland.no +herøy.nordland.no +nordre-land.no +nordreisa.no +nore-og-uvdal.no +notodden.no +notteroy.no +nøtterøy.no +odda.no +oksnes.no +øksnes.no +omasvuotna.no +oppdal.no +oppegard.no +oppegård.no +orkdal.no +orland.no +ørland.no +orskog.no +ørskog.no +orsta.no +ørsta.no +osen.no +osteroy.no +osterøy.no +valer.ostfold.no +våler.østfold.no +ostre-toten.no +østre-toten.no +overhalla.no +ovre-eiker.no +øvre-eiker.no +oyer.no +øyer.no +oygarden.no +øygarden.no +oystre-slidre.no +øystre-slidre.no +porsanger.no +porsangu.no +porsáŋgu.no +porsgrunn.no +rade.no +råde.no +radoy.no +radøy.no +rælingen.no +rahkkeravju.no +ráhkkerávju.no +raisa.no +ráisa.no +rakkestad.no +ralingen.no +rana.no +randaberg.no +rauma.no +rendalen.no +rennebu.no +rennesoy.no +rennesøy.no +rindal.no +ringebu.no +ringerike.no +ringsaker.no +risor.no +risør.no +rissa.no +roan.no +rodoy.no +rødøy.no +rollag.no +romsa.no +romskog.no +rømskog.no +roros.no +røros.no +rost.no +røst.no +royken.no +røyken.no +royrvik.no +røyrvik.no +ruovat.no +rygge.no +salangen.no +salat.no +sálat.no +sálát.no +saltdal.no +samnanger.no +sandefjord.no +sandnes.no +sandoy.no +sandøy.no +sarpsborg.no +sauda.no +sauherad.no +sel.no +selbu.no +selje.no +seljord.no +siellak.no +sigdal.no +siljan.no +sirdal.no +skanit.no +skánit.no +skanland.no +skånland.no +skaun.no +skedsmo.no +ski.no +skien.no +skierva.no +skiervá.no +skiptvet.no +skjak.no +skjåk.no +skjervoy.no +skjervøy.no +skodje.no +smola.no +smøla.no +snaase.no +snåase.no +snasa.no +snåsa.no +snillfjord.no +snoasa.no +sogndal.no +sogne.no +søgne.no +sokndal.no +sola.no +solund.no +somna.no +sømna.no +sondre-land.no +søndre-land.no +songdalen.no +sor-aurdal.no +sør-aurdal.no +sor-fron.no +sør-fron.no +sor-odal.no +sør-odal.no +sor-varanger.no +sør-varanger.no +sorfold.no +sørfold.no +sorreisa.no +sørreisa.no +sortland.no +sorum.no +sørum.no +spydeberg.no +stange.no +stavanger.no +steigen.no +steinkjer.no +stjordal.no +stjørdal.no +stokke.no +stor-elvdal.no +stord.no +stordal.no +storfjord.no +strand.no +stranda.no +stryn.no +sula.no +suldal.no +sund.no +sunndal.no +surnadal.no +sveio.no +svelvik.no +sykkylven.no +tana.no +bo.telemark.no +bø.telemark.no +time.no +tingvoll.no +tinn.no +tjeldsund.no +tjome.no +tjøme.no +tokke.no +tolga.no +tonsberg.no +tønsberg.no +torsken.no +træna.no +trana.no +tranoy.no +tranøy.no +troandin.no +trogstad.no +trøgstad.no +tromsa.no +tromso.no +tromsø.no +trondheim.no +trysil.no +tvedestrand.no +tydal.no +tynset.no +tysfjord.no +tysnes.no +tysvær.no +tysvar.no +ullensaker.no +ullensvang.no +ulvik.no +unjarga.no +unjárga.no +utsira.no +vaapste.no +vadso.no +vadsø.no +værøy.no +vaga.no +vågå.no +vagan.no +vågan.no +vagsoy.no +vågsøy.no +vaksdal.no +valle.no +vang.no +vanylven.no +vardo.no +vardø.no +varggat.no +várggát.no +varoy.no +vefsn.no +vega.no +vegarshei.no +vegårshei.no +vennesla.no +verdal.no +verran.no +vestby.no +sande.vestfold.no +vestnes.no +vestre-slidre.no +vestre-toten.no +vestvagoy.no +vestvågøy.no +vevelstad.no +vik.no +vikna.no +vindafjord.no +voagat.no +volda.no +voss.no + +// np : http://www.mos.com.np/register.html +*.np + +// nr : http://cenpac.net.nr/dns/index.html +// Submitted by registry +nr +biz.nr +com.nr +edu.nr +gov.nr +info.nr +net.nr +org.nr + +// nu : https://www.iana.org/domains/root/db/nu.html +nu + +// nz : https://www.iana.org/domains/root/db/nz.html +// Submitted by registry +nz +ac.nz +co.nz +cri.nz +geek.nz +gen.nz +govt.nz +health.nz +iwi.nz +kiwi.nz +maori.nz +māori.nz +mil.nz +net.nz +org.nz +parliament.nz +school.nz + +// om : https://www.iana.org/domains/root/db/om.html +om +co.om +com.om +edu.om +gov.om +med.om +museum.om +net.om +org.om +pro.om + +// onion : https://tools.ietf.org/html/rfc7686 +onion + +// org : https://www.iana.org/domains/root/db/org.html +org + +// pa : http://www.nic.pa/ +// Some additional second level "domains" resolve directly as hostnames, such as +// pannet.pa, so we add a rule for "pa". +pa +abo.pa +ac.pa +com.pa +edu.pa +gob.pa +ing.pa +med.pa +net.pa +nom.pa +org.pa +sld.pa + +// pe : https://www.nic.pe/InformeFinalComision.pdf +pe +com.pe +edu.pe +gob.pe +mil.pe +net.pe +nom.pe +org.pe + +// pf : http://www.gobin.info/domainname/formulaire-pf.pdf +pf +com.pf +edu.pf +org.pf + +// pg : https://www.iana.org/domains/root/db/pg.html +*.pg + +// ph : https://www.iana.org/domains/root/db/ph.html +// Submitted by registry +ph +com.ph +edu.ph +gov.ph +i.ph +mil.ph +net.ph +ngo.ph +org.ph + +// pk : https://pk5.pknic.net.pk/pk5/msgNamepk.PK +// Contact Email: staff@pknic.net.pk +pk +ac.pk +biz.pk +com.pk +edu.pk +fam.pk +gkp.pk +gob.pk +gog.pk +gok.pk +gop.pk +gos.pk +gov.pk +net.pk +org.pk +web.pk + +// pl : https://www.dns.pl/en/ +// Confirmed by registry 2024-11-18 +pl +com.pl +net.pl +org.pl +// pl functional domains : https://www.dns.pl/en/list_of_functional_domain_names +agro.pl +aid.pl +atm.pl +auto.pl +biz.pl +edu.pl +gmina.pl +gsm.pl +info.pl +mail.pl +media.pl +miasta.pl +mil.pl +nieruchomosci.pl +nom.pl +pc.pl +powiat.pl +priv.pl +realestate.pl +rel.pl +sex.pl +shop.pl +sklep.pl +sos.pl +szkola.pl +targi.pl +tm.pl +tourism.pl +travel.pl +turystyka.pl +// Government domains : https://www.dns.pl/informacje_o_rejestracji_domen_gov_pl +// In accordance with the .gov.pl Domain Name Regulations : https://www.dns.pl/regulamin_gov_pl +gov.pl +ap.gov.pl +griw.gov.pl +ic.gov.pl +is.gov.pl +kmpsp.gov.pl +konsulat.gov.pl +kppsp.gov.pl +kwp.gov.pl +kwpsp.gov.pl +mup.gov.pl +mw.gov.pl +oia.gov.pl +oirm.gov.pl +oke.gov.pl +oow.gov.pl +oschr.gov.pl +oum.gov.pl +pa.gov.pl +pinb.gov.pl +piw.gov.pl +po.gov.pl +pr.gov.pl +psp.gov.pl +psse.gov.pl +pup.gov.pl +rzgw.gov.pl +sa.gov.pl +sdn.gov.pl +sko.gov.pl +so.gov.pl +sr.gov.pl +starostwo.gov.pl +ug.gov.pl +ugim.gov.pl +um.gov.pl +umig.gov.pl +upow.gov.pl +uppo.gov.pl +us.gov.pl +uw.gov.pl +uzs.gov.pl +wif.gov.pl +wiih.gov.pl +winb.gov.pl +wios.gov.pl +witd.gov.pl +wiw.gov.pl +wkz.gov.pl +wsa.gov.pl +wskr.gov.pl +wsse.gov.pl +wuoz.gov.pl +wzmiuw.gov.pl +zp.gov.pl +zpisdn.gov.pl +// pl regional domains : https://www.dns.pl/en/list_of_regional_domain_names +augustow.pl +babia-gora.pl +bedzin.pl +beskidy.pl +bialowieza.pl +bialystok.pl +bielawa.pl +bieszczady.pl +boleslawiec.pl +bydgoszcz.pl +bytom.pl +cieszyn.pl +czeladz.pl +czest.pl +dlugoleka.pl +elblag.pl +elk.pl +glogow.pl +gniezno.pl +gorlice.pl +grajewo.pl +ilawa.pl +jaworzno.pl +jelenia-gora.pl +jgora.pl +kalisz.pl +karpacz.pl +kartuzy.pl +kaszuby.pl +katowice.pl +kazimierz-dolny.pl +kepno.pl +ketrzyn.pl +klodzko.pl +kobierzyce.pl +kolobrzeg.pl +konin.pl +konskowola.pl +kutno.pl +lapy.pl +lebork.pl +legnica.pl +lezajsk.pl +limanowa.pl +lomza.pl +lowicz.pl +lubin.pl +lukow.pl +malbork.pl +malopolska.pl +mazowsze.pl +mazury.pl +mielec.pl +mielno.pl +mragowo.pl +naklo.pl +nowaruda.pl +nysa.pl +olawa.pl +olecko.pl +olkusz.pl +olsztyn.pl +opoczno.pl +opole.pl +ostroda.pl +ostroleka.pl +ostrowiec.pl +ostrowwlkp.pl +pila.pl +pisz.pl +podhale.pl +podlasie.pl +polkowice.pl +pomorskie.pl +pomorze.pl +prochowice.pl +pruszkow.pl +przeworsk.pl +pulawy.pl +radom.pl +rawa-maz.pl +rybnik.pl +rzeszow.pl +sanok.pl +sejny.pl +skoczow.pl +slask.pl +slupsk.pl +sosnowiec.pl +stalowa-wola.pl +starachowice.pl +stargard.pl +suwalki.pl +swidnica.pl +swiebodzin.pl +swinoujscie.pl +szczecin.pl +szczytno.pl +tarnobrzeg.pl +tgory.pl +turek.pl +tychy.pl +ustka.pl +walbrzych.pl +warmia.pl +warszawa.pl +waw.pl +wegrow.pl +wielun.pl +wlocl.pl +wloclawek.pl +wodzislaw.pl +wolomin.pl +wroclaw.pl +zachpomor.pl +zagan.pl +zarow.pl +zgora.pl +zgorzelec.pl + +// pm : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf +pm + +// pn : https://www.iana.org/domains/root/db/pn.html +pn +co.pn +edu.pn +gov.pn +net.pn +org.pn + +// post : https://www.iana.org/domains/root/db/post.html +post + +// pr : http://www.nic.pr/index.asp?f=1 +pr +biz.pr +com.pr +edu.pr +gov.pr +info.pr +isla.pr +name.pr +net.pr +org.pr +pro.pr +// these aren't mentioned on nic.pr, but on https://www.iana.org/domains/root/db/pr.html +ac.pr +est.pr +prof.pr + +// pro : http://registry.pro/get-pro +pro +aaa.pro +aca.pro +acct.pro +avocat.pro +bar.pro +cpa.pro +eng.pro +jur.pro +law.pro +med.pro +recht.pro + +// ps : https://www.iana.org/domains/root/db/ps.html +// http://www.nic.ps/registration/policy.html#reg +ps +com.ps +edu.ps +gov.ps +net.ps +org.ps +plo.ps +sec.ps + +// pt : https://www.dns.pt/en/domain/pt-terms-and-conditions-registration-rules/ +pt +com.pt +edu.pt +gov.pt +int.pt +net.pt +nome.pt +org.pt +publ.pt + +// pw : https://www.iana.org/domains/root/db/pw.html +// Confirmed by registry in private correspondence with @dnsguru 2024-12-09 +pw +gov.pw + +// py : https://www.iana.org/domains/root/db/py.html +// Submitted by registry +py +com.py +coop.py +edu.py +gov.py +mil.py +net.py +org.py + +// qa : http://domains.qa/en/ +qa +com.qa +edu.qa +gov.qa +mil.qa +name.qa +net.qa +org.qa +sch.qa + +// re : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf +// Confirmed by registry 2024-11-18 +re +// Closed for registration on 2013-03-15 but domains are still maintained +asso.re +com.re + +// ro : http://www.rotld.ro/ +ro +arts.ro +com.ro +firm.ro +info.ro +nom.ro +nt.ro +org.ro +rec.ro +store.ro +tm.ro +www.ro + +// rs : https://www.rnids.rs/en/domains/national-domains +rs +ac.rs +co.rs +edu.rs +gov.rs +in.rs +org.rs + +// ru : https://cctld.ru/files/pdf/docs/en/rules_ru-rf.pdf +// Submitted by George Georgievsky +ru + +// rw : https://www.iana.org/domains/root/db/rw.html +rw +ac.rw +co.rw +coop.rw +gov.rw +mil.rw +net.rw +org.rw + +// sa : http://www.nic.net.sa/ +sa +com.sa +edu.sa +gov.sa +med.sa +net.sa +org.sa +pub.sa +sch.sa + +// sb : http://www.sbnic.net.sb/ +// Submitted by registry +sb +com.sb +edu.sb +gov.sb +net.sb +org.sb + +// sc : http://www.nic.sc/ +sc +com.sc +edu.sc +gov.sc +net.sc +org.sc + +// sd : https://www.iana.org/domains/root/db/sd.html +// Submitted by registry +sd +com.sd +edu.sd +gov.sd +info.sd +med.sd +net.sd +org.sd +tv.sd + +// se : https://www.iana.org/domains/root/db/se.html +// https://data.internetstiftelsen.se/barred_domains_list.txt -> Second level domains & Sub-domains +// Confirmed by Registry Services 2024-11-20 +se +a.se +ac.se +b.se +bd.se +brand.se +c.se +d.se +e.se +f.se +fh.se +fhsk.se +fhv.se +g.se +h.se +i.se +k.se +komforb.se +kommunalforbund.se +komvux.se +l.se +lanbib.se +m.se +n.se +naturbruksgymn.se +o.se +org.se +p.se +parti.se +pp.se +press.se +r.se +s.se +t.se +tm.se +u.se +w.se +x.se +y.se +z.se + +// sg : https://www.sgnic.sg/domain-registration/sg-categories-rules +// Confirmed by registry 2024-11-19 +sg +com.sg +edu.sg +gov.sg +net.sg +org.sg + +// sh : http://nic.sh/rules.htm +sh +com.sh +gov.sh +mil.sh +net.sh +org.sh + +// si : https://www.iana.org/domains/root/db/si.html +si + +// sj : No registrations at this time. +// Submitted by registry +sj + +// sk : https://www.iana.org/domains/root/db/sk.html +sk + +// sl : http://www.nic.sl +// Submitted by registry +sl +com.sl +edu.sl +gov.sl +net.sl +org.sl + +// sm : https://www.iana.org/domains/root/db/sm.html +sm + +// sn : https://www.iana.org/domains/root/db/sn.html +sn +art.sn +com.sn +edu.sn +gouv.sn +org.sn +perso.sn +univ.sn + +// so : http://sonic.so/policies/ +so +com.so +edu.so +gov.so +me.so +net.so +org.so + +// sr : https://www.iana.org/domains/root/db/sr.html +sr + +// ss : https://registry.nic.ss/ +// Submitted by registry +ss +biz.ss +co.ss +com.ss +edu.ss +gov.ss +me.ss +net.ss +org.ss +sch.ss + +// st : http://www.nic.st/html/policyrules/ +st +co.st +com.st +consulado.st +edu.st +embaixada.st +mil.st +net.st +org.st +principe.st +saotome.st +store.st + +// su : https://www.iana.org/domains/root/db/su.html +su + +// sv : https://www.iana.org/domains/root/db/sv.html +sv +com.sv +edu.sv +gob.sv +org.sv +red.sv + +// sx : https://www.iana.org/domains/root/db/sx.html +// Submitted by registry +sx +gov.sx + +// sy : https://www.iana.org/domains/root/db/sy.html +sy +com.sy +edu.sy +gov.sy +mil.sy +net.sy +org.sy + +// sz : https://www.iana.org/domains/root/db/sz.html +// http://www.sispa.org.sz/ +sz +ac.sz +co.sz +org.sz + +// tc : https://www.iana.org/domains/root/db/tc.html +tc + +// td : https://www.iana.org/domains/root/db/td.html +td + +// tel : https://www.iana.org/domains/root/db/tel.html +// http://www.telnic.org/ +tel + +// tf : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf +tf + +// tg : https://www.iana.org/domains/root/db/tg.html +// http://www.nic.tg/ +tg + +// th : https://www.iana.org/domains/root/db/th.html +// Submitted by registry +th +ac.th +co.th +go.th +in.th +mi.th +net.th +or.th + +// tj : http://www.nic.tj/policy.html +tj +ac.tj +biz.tj +co.tj +com.tj +edu.tj +go.tj +gov.tj +int.tj +mil.tj +name.tj +net.tj +nic.tj +org.tj +test.tj +web.tj + +// tk : https://www.iana.org/domains/root/db/tk.html +tk + +// tl : https://www.iana.org/domains/root/db/tl.html +tl +gov.tl + +// tm : https://www.nic.tm/local.html +// Confirmed by registry 2024-11-19 +tm +co.tm +com.tm +edu.tm +gov.tm +mil.tm +net.tm +nom.tm +org.tm + +// tn : http://www.registre.tn/fr/ +// https://whois.ati.tn/ +tn +com.tn +ens.tn +fin.tn +gov.tn +ind.tn +info.tn +intl.tn +mincom.tn +nat.tn +net.tn +org.tn +perso.tn +tourism.tn + +// to : https://www.iana.org/domains/root/db/to.html +// Submitted by registry +to +com.to +edu.to +gov.to +mil.to +net.to +org.to + +// tr : https://nic.tr/ +// https://nic.tr/forms/eng/policies.pdf +// https://nic.tr/index.php?USRACTN=PRICELST +tr +av.tr +bbs.tr +bel.tr +biz.tr +com.tr +dr.tr +edu.tr +gen.tr +gov.tr +info.tr +k12.tr +kep.tr +mil.tr +name.tr +net.tr +org.tr +pol.tr +tel.tr +tsk.tr +tv.tr +web.tr +// Used by Northern Cyprus +nc.tr +// Used by government agencies of Northern Cyprus +gov.nc.tr + +// tt : https://www.nic.tt/ +// Confirmed by registry 2024-11-19 +tt +biz.tt +co.tt +com.tt +edu.tt +gov.tt +info.tt +mil.tt +name.tt +net.tt +org.tt +pro.tt + +// tv : https://www.iana.org/domains/root/db/tv.html +// Not listing any 2LDs as reserved since none seem to exist in practice, +// Wikipedia notwithstanding. +tv + +// tw : https://www.iana.org/domains/root/db/tw.html +// https://twnic.tw/dnservice_catag.php +// Confirmed by registry 2024-11-26 +tw +club.tw +com.tw +ebiz.tw +edu.tw +game.tw +gov.tw +idv.tw +mil.tw +net.tw +org.tw + +// tz : http://www.tznic.or.tz/index.php/domains +// Submitted by registry +tz +ac.tz +co.tz +go.tz +hotel.tz +info.tz +me.tz +mil.tz +mobi.tz +ne.tz +or.tz +sc.tz +tv.tz + +// ua : https://hostmaster.ua/policy/?ua +// Submitted by registry +ua +// ua 2LD +com.ua +edu.ua +gov.ua +in.ua +net.ua +org.ua +// ua geographic names +// https://hostmaster.ua/2ld/ +cherkassy.ua +cherkasy.ua +chernigov.ua +chernihiv.ua +chernivtsi.ua +chernovtsy.ua +ck.ua +cn.ua +cr.ua +crimea.ua +cv.ua +dn.ua +dnepropetrovsk.ua +dnipropetrovsk.ua +donetsk.ua +dp.ua +if.ua +ivano-frankivsk.ua +kh.ua +kharkiv.ua +kharkov.ua +kherson.ua +khmelnitskiy.ua +khmelnytskyi.ua +kiev.ua +kirovograd.ua +km.ua +kr.ua +kropyvnytskyi.ua +krym.ua +ks.ua +kv.ua +kyiv.ua +lg.ua +lt.ua +lugansk.ua +luhansk.ua +lutsk.ua +lv.ua +lviv.ua +mk.ua +mykolaiv.ua +nikolaev.ua +od.ua +odesa.ua +odessa.ua +pl.ua +poltava.ua +rivne.ua +rovno.ua +rv.ua +sb.ua +sebastopol.ua +sevastopol.ua +sm.ua +sumy.ua +te.ua +ternopil.ua +uz.ua +uzhgorod.ua +uzhhorod.ua +vinnica.ua +vinnytsia.ua +vn.ua +volyn.ua +yalta.ua +zakarpattia.ua +zaporizhzhe.ua +zaporizhzhia.ua +zhitomir.ua +zhytomyr.ua +zp.ua +zt.ua + +// ug : https://www.registry.co.ug/ +// https://www.registry.co.ug, https://whois.co.ug +// Confirmed by registry 2025-01-20 +ug +ac.ug +co.ug +com.ug +edu.ug +go.ug +gov.ug +mil.ug +ne.ug +or.ug +org.ug +sc.ug +us.ug + +// uk : https://www.iana.org/domains/root/db/uk.html +// Submitted by registry +uk +ac.uk +co.uk +gov.uk +ltd.uk +me.uk +net.uk +nhs.uk +org.uk +plc.uk +police.uk +*.sch.uk + +// us : https://www.iana.org/domains/root/db/us.html +// Confirmed via the .us zone file by William Harrison 2024-12-10 +us +dni.us +isa.us +nsn.us +// Geographic Names +ak.us +al.us +ar.us +as.us +az.us +ca.us +co.us +ct.us +dc.us +de.us +fl.us +ga.us +gu.us +hi.us +ia.us +id.us +il.us +in.us +ks.us +ky.us +la.us +ma.us +md.us +me.us +mi.us +mn.us +mo.us +ms.us +mt.us +nc.us +nd.us +ne.us +nh.us +nj.us +nm.us +nv.us +ny.us +oh.us +ok.us +or.us +pa.us +pr.us +ri.us +sc.us +sd.us +tn.us +tx.us +ut.us +va.us +vi.us +vt.us +wa.us +wi.us +wv.us +wy.us +// The registrar notes several more specific domains available in each state, +// such as state.*.us, dst.*.us, etc., but resolution of these is somewhat +// haphazard; in some states these domains resolve as addresses, while in others +// only subdomains are available, or even nothing at all. We include the +// most common ones where it's clear that different sites are different +// entities. +k12.ak.us +k12.al.us +k12.ar.us +k12.as.us +k12.az.us +k12.ca.us +k12.co.us +k12.ct.us +k12.dc.us +k12.fl.us +k12.ga.us +k12.gu.us +// k12.hi.us - Bug 614565 - Hawaii has a state-wide DOE login +k12.ia.us +k12.id.us +k12.il.us +k12.in.us +k12.ks.us +k12.ky.us +k12.la.us +k12.ma.us +k12.md.us +k12.me.us +k12.mi.us +k12.mn.us +k12.mo.us +k12.ms.us +k12.mt.us +k12.nc.us +// k12.nd.us - Bug 1028347 - Removed at request of Travis Rosso +k12.ne.us +k12.nh.us +k12.nj.us +k12.nm.us +k12.nv.us +k12.ny.us +k12.oh.us +k12.ok.us +k12.or.us +k12.pa.us +k12.pr.us +// k12.ri.us - Removed at request of Kim Cournoyer +k12.sc.us +// k12.sd.us - Bug 934131 - Removed at request of James Booze +k12.tn.us +k12.tx.us +k12.ut.us +k12.va.us +k12.vi.us +k12.vt.us +k12.wa.us +k12.wi.us +// k12.wv.us - Bug 947705 - Removed at request of Verne Britton +cc.ak.us +lib.ak.us +cc.al.us +lib.al.us +cc.ar.us +lib.ar.us +cc.as.us +lib.as.us +cc.az.us +lib.az.us +cc.ca.us +lib.ca.us +cc.co.us +lib.co.us +cc.ct.us +lib.ct.us +cc.dc.us +lib.dc.us +cc.de.us +cc.fl.us +cc.ga.us +cc.gu.us +cc.hi.us +cc.ia.us +cc.id.us +cc.il.us +cc.in.us +cc.ks.us +cc.ky.us +cc.la.us +cc.ma.us +cc.md.us +cc.me.us +cc.mi.us +cc.mn.us +cc.mo.us +cc.ms.us +cc.mt.us +cc.nc.us +cc.nd.us +cc.ne.us +cc.nh.us +cc.nj.us +cc.nm.us +cc.nv.us +cc.ny.us +cc.oh.us +cc.ok.us +cc.or.us +cc.pa.us +cc.pr.us +cc.ri.us +cc.sc.us +cc.sd.us +cc.tn.us +cc.tx.us +cc.ut.us +cc.va.us +cc.vi.us +cc.vt.us +cc.wa.us +cc.wi.us +cc.wv.us +cc.wy.us +k12.wy.us +// lib.de.us - Issue #243 - Moved to Private section at request of Ed Moore +lib.fl.us +lib.ga.us +lib.gu.us +lib.hi.us +lib.ia.us +lib.id.us +lib.il.us +lib.in.us +lib.ks.us +lib.ky.us +lib.la.us +lib.ma.us +lib.md.us +lib.me.us +lib.mi.us +lib.mn.us +lib.mo.us +lib.ms.us +lib.mt.us +lib.nc.us +lib.nd.us +lib.ne.us +lib.nh.us +lib.nj.us +lib.nm.us +lib.nv.us +lib.ny.us +lib.oh.us +lib.ok.us +lib.or.us +lib.pa.us +lib.pr.us +lib.ri.us +lib.sc.us +lib.sd.us +lib.tn.us +lib.tx.us +lib.ut.us +lib.va.us +lib.vi.us +lib.vt.us +lib.wa.us +lib.wi.us +// lib.wv.us - Bug 941670 - Removed at request of Larry W Arnold +lib.wy.us +// k12.ma.us contains school districts in Massachusetts. The 4LDs are +// managed independently except for private (PVT), charter (CHTR) and +// parochial (PAROCH) schools. Those are delegated directly to the +// 5LD operators. +chtr.k12.ma.us +paroch.k12.ma.us +pvt.k12.ma.us +// Merit Network, Inc. maintains the registry for =~ /(k12|cc|lib).mi.us/ and the following +// see also: https://domreg.merit.edu : domreg@merit.edu +// see also: whois -h whois.domreg.merit.edu help +ann-arbor.mi.us +cog.mi.us +dst.mi.us +eaton.mi.us +gen.mi.us +mus.mi.us +tec.mi.us +washtenaw.mi.us + +// uy : http://www.nic.org.uy/ +uy +com.uy +edu.uy +gub.uy +mil.uy +net.uy +org.uy + +// uz : http://www.reg.uz/ +uz +co.uz +com.uz +net.uz +org.uz + +// va : https://www.iana.org/domains/root/db/va.html +va + +// vc : https://www.iana.org/domains/root/db/vc.html +// Submitted by registry +vc +com.vc +edu.vc +gov.vc +mil.vc +net.vc +org.vc + +// ve : https://registro.nic.ve/ +// Submitted by registry nic@nic.ve and nicve@conatel.gob.ve +ve +arts.ve +bib.ve +co.ve +com.ve +e12.ve +edu.ve +emprende.ve +firm.ve +gob.ve +gov.ve +info.ve +int.ve +mil.ve +net.ve +nom.ve +org.ve +rar.ve +rec.ve +store.ve +tec.ve +web.ve + +// vg : https://www.iana.org/domains/root/db/vg.html +// Confirmed by registry 2025-01-10 +vg +edu.vg + +// vi : https://www.iana.org/domains/root/db/vi.html +vi +co.vi +com.vi +k12.vi +net.vi +org.vi + +// vn : https://www.vnnic.vn/en/domain/cctld-vn +// https://vnnic.vn/sites/default/files/tailieu/vn.cctld.domains.txt +vn +ac.vn +ai.vn +biz.vn +com.vn +edu.vn +gov.vn +health.vn +id.vn +info.vn +int.vn +io.vn +name.vn +net.vn +org.vn +pro.vn + +// vn geographical names +angiang.vn +bacgiang.vn +backan.vn +baclieu.vn +bacninh.vn +baria-vungtau.vn +bentre.vn +binhdinh.vn +binhduong.vn +binhphuoc.vn +binhthuan.vn +camau.vn +cantho.vn +caobang.vn +daklak.vn +daknong.vn +danang.vn +dienbien.vn +dongnai.vn +dongthap.vn +gialai.vn +hagiang.vn +haiduong.vn +haiphong.vn +hanam.vn +hanoi.vn +hatinh.vn +haugiang.vn +hoabinh.vn +hungyen.vn +khanhhoa.vn +kiengiang.vn +kontum.vn +laichau.vn +lamdong.vn +langson.vn +laocai.vn +longan.vn +namdinh.vn +nghean.vn +ninhbinh.vn +ninhthuan.vn +phutho.vn +phuyen.vn +quangbinh.vn +quangnam.vn +quangngai.vn +quangninh.vn +quangtri.vn +soctrang.vn +sonla.vn +tayninh.vn +thaibinh.vn +thainguyen.vn +thanhhoa.vn +thanhphohochiminh.vn +thuathienhue.vn +tiengiang.vn +travinh.vn +tuyenquang.vn +vinhlong.vn +vinhphuc.vn +yenbai.vn + +// vu : https://www.iana.org/domains/root/db/vu.html +// http://www.vunic.vu/ +vu +com.vu +edu.vu +net.vu +org.vu + +// wf : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf +wf + +// ws : https://www.iana.org/domains/root/db/ws.html +// http://samoanic.ws/index.dhtml +ws +com.ws +edu.ws +gov.ws +net.ws +org.ws + +// yt : https://www.afnic.fr/wp-media/uploads/2022/12/afnic-naming-policy-2023-01-01.pdf +yt + +// IDN ccTLDs +// When submitting patches, please maintain a sort by ISO 3166 ccTLD, then +// U-label, and follow this format: +// // A-Label ("", [, variant info]) : +// // [sponsoring org] +// U-Label + +// xn--mgbaam7a8h ("Emerat", Arabic) : AE +// http://nic.ae/english/arabicdomain/rules.jsp +امارات + +// xn--y9a3aq ("hye", Armenian) : AM +// ISOC AM (operated by .am Registry) +հայ + +// xn--54b7fta0cc ("Bangla", Bangla) : BD +বাংলা + +// xn--90ae ("bg", Bulgarian) : BG +бг + +// xn--mgbcpq6gpa1a ("albahrain", Arabic) : BH +البحرين + +// xn--90ais ("bel", Belarusian/Russian Cyrillic) : BY +// Operated by .by registry +бел + +// xn--fiqs8s ("Zhongguo/China", Chinese, Simplified) : CN +// CNNIC +// https://www.cnnic.cn/11/192/index.html +中国 + +// xn--fiqz9s ("Zhongguo/China", Chinese, Traditional) : CN +// CNNIC +// https://www.cnnic.com.cn/AU/MediaC/Announcement/201609/t20160905_54470.htm +中國 + +// xn--lgbbat1ad8j ("Algeria/Al Jazair", Arabic) : DZ +الجزائر + +// xn--wgbh1c ("Egypt/Masr", Arabic) : EG +// http://www.dotmasr.eg/ +مصر + +// xn--e1a4c ("eu", Cyrillic) : EU +// https://eurid.eu +ею + +// xn--qxa6a ("eu", Greek) : EU +// https://eurid.eu +ευ + +// xn--mgbah1a3hjkrd ("Mauritania", Arabic) : MR +موريتانيا + +// xn--node ("ge", Georgian Mkhedruli) : GE +გე + +// xn--qxam ("el", Greek) : GR +// Hellenic Ministry of Infrastructure, Transport, and Networks +ελ + +// xn--j6w193g ("Hong Kong", Chinese) : HK +// https://www.hkirc.hk +// Submitted by registry +// https://www.hkirc.hk/content.jsp?id=30#!/34 +香港 +個人.香港 +公司.香港 +政府.香港 +教育.香港 +組織.香港 +網絡.香港 + +// xn--2scrj9c ("Bharat", Kannada) : IN +// India +ಭಾರತ + +// xn--3hcrj9c ("Bharat", Oriya) : IN +// India +ଭାରତ + +// xn--45br5cyl ("Bharatam", Assamese) : IN +// India +ভাৰত + +// xn--h2breg3eve ("Bharatam", Sanskrit) : IN +// India +भारतम् + +// xn--h2brj9c8c ("Bharot", Santali) : IN +// India +भारोत + +// xn--mgbgu82a ("Bharat", Sindhi) : IN +// India +ڀارت + +// xn--rvc1e0am3e ("Bharatam", Malayalam) : IN +// India +ഭാരതം + +// xn--h2brj9c ("Bharat", Devanagari) : IN +// India +भारत + +// xn--mgbbh1a ("Bharat", Kashmiri) : IN +// India +بارت + +// xn--mgbbh1a71e ("Bharat", Arabic) : IN +// India +بھارت + +// xn--fpcrj9c3d ("Bharat", Telugu) : IN +// India +భారత్ + +// xn--gecrj9c ("Bharat", Gujarati) : IN +// India +ભારત + +// xn--s9brj9c ("Bharat", Gurmukhi) : IN +// India +ਭਾਰਤ + +// xn--45brj9c ("Bharat", Bengali) : IN +// India +ভারত + +// xn--xkc2dl3a5ee0h ("India", Tamil) : IN +// India +இந்தியா + +// xn--mgba3a4f16a ("Iran", Persian) : IR +ایران + +// xn--mgba3a4fra ("Iran", Arabic) : IR +ايران + +// xn--mgbtx2b ("Iraq", Arabic) : IQ +// Communications and Media Commission +عراق + +// xn--mgbayh7gpa ("al-Ordon", Arabic) : JO +// National Information Technology Center (NITC) +// Royal Scientific Society, Al-Jubeiha +الاردن + +// xn--3e0b707e ("Republic of Korea", Hangul) : KR +한국 + +// xn--80ao21a ("Kaz", Kazakh) : KZ +қаз + +// xn--q7ce6a ("Lao", Lao) : LA +ລາວ + +// xn--fzc2c9e2c ("Lanka", Sinhalese-Sinhala) : LK +// https://nic.lk +ලංකා + +// xn--xkc2al3hye2a ("Ilangai", Tamil) : LK +// https://nic.lk +இலங்கை + +// xn--mgbc0a9azcg ("Morocco/al-Maghrib", Arabic) : MA +المغرب + +// xn--d1alf ("mkd", Macedonian) : MK +// MARnet +мкд + +// xn--l1acc ("mon", Mongolian) : MN +мон + +// xn--mix891f ("Macao", Chinese, Traditional) : MO +// MONIC / HNET Asia (Registry Operator for .mo) +澳門 + +// xn--mix082f ("Macao", Chinese, Simplified) : MO +澳门 + +// xn--mgbx4cd0ab ("Malaysia", Malay) : MY +مليسيا + +// xn--mgb9awbf ("Oman", Arabic) : OM +عمان + +// xn--mgbai9azgqp6j ("Pakistan", Urdu/Arabic) : PK +پاکستان + +// xn--mgbai9a5eva00b ("Pakistan", Urdu/Arabic, variant) : PK +پاكستان + +// xn--ygbi2ammx ("Falasteen", Arabic) : PS +// The Palestinian National Internet Naming Authority (PNINA) +// http://www.pnina.ps +فلسطين + +// xn--90a3ac ("srb", Cyrillic) : RS +// https://www.rnids.rs/en/domains/national-domains +срб +ак.срб +обр.срб +од.срб +орг.срб +пр.срб +упр.срб + +// xn--p1ai ("rf", Russian-Cyrillic) : RU +// https://cctld.ru/files/pdf/docs/en/rules_ru-rf.pdf +// Submitted by George Georgievsky +рф + +// xn--wgbl6a ("Qatar", Arabic) : QA +// http://www.ict.gov.qa/ +قطر + +// xn--mgberp4a5d4ar ("AlSaudiah", Arabic) : SA +// http://www.nic.net.sa/ +السعودية + +// xn--mgberp4a5d4a87g ("AlSaudiah", Arabic, variant): SA +السعودیة + +// xn--mgbqly7c0a67fbc ("AlSaudiah", Arabic, variant) : SA +السعودیۃ + +// xn--mgbqly7cvafr ("AlSaudiah", Arabic, variant) : SA +السعوديه + +// xn--mgbpl2fh ("sudan", Arabic) : SD +// Operated by .sd registry +سودان + +// xn--yfro4i67o Singapore ("Singapore", Chinese) : SG +新加坡 + +// xn--clchc0ea0b2g2a9gcd ("Singapore", Tamil) : SG +சிங்கப்பூர் + +// xn--ogbpf8fl ("Syria", Arabic) : SY +سورية + +// xn--mgbtf8fl ("Syria", Arabic, variant) : SY +سوريا + +// xn--o3cw4h ("Thai", Thai) : TH +// http://www.thnic.co.th +ไทย +ทหาร.ไทย +ธุรกิจ.ไทย +เน็ต.ไทย +รัฐบาล.ไทย +ศึกษา.ไทย +องค์กร.ไทย + +// xn--pgbs0dh ("Tunisia", Arabic) : TN +// http://nic.tn +تونس + +// xn--kpry57d ("Taiwan", Chinese, Traditional) : TW +// https://twnic.tw/dnservice_catag.php +台灣 + +// xn--kprw13d ("Taiwan", Chinese, Simplified) : TW +// http://www.twnic.net/english/dn/dn_07a.htm +台湾 + +// xn--nnx388a ("Taiwan", Chinese, variant) : TW +臺灣 + +// xn--j1amh ("ukr", Cyrillic) : UA +укр + +// xn--mgb2ddes ("AlYemen", Arabic) : YE +اليمن + +// xxx : http://icmregistry.com +xxx + +// ye : http://www.y.net.ye/services/domain_name.htm +ye +com.ye +edu.ye +gov.ye +mil.ye +net.ye +org.ye + +// za : https://www.iana.org/domains/root/db/za.html +ac.za +agric.za +alt.za +co.za +edu.za +gov.za +grondar.za +law.za +mil.za +net.za +ngo.za +nic.za +nis.za +nom.za +org.za +school.za +tm.za +web.za + +// zm : https://zicta.zm/ +// Submitted by registry +zm +ac.zm +biz.zm +co.zm +com.zm +edu.zm +gov.zm +info.zm +mil.zm +net.zm +org.zm +sch.zm + +// zw : https://www.potraz.gov.zw/ +// Confirmed by registry 2017-01-25 +zw +ac.zw +co.zw +gov.zw +mil.zw +org.zw + +// newGTLDs + +// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2025-04-26T15:16:32Z +// This list is auto-generated, don't edit it manually. +// aaa : American Automobile Association, Inc. +// https://www.iana.org/domains/root/db/aaa.html +aaa + +// aarp : AARP +// https://www.iana.org/domains/root/db/aarp.html +aarp + +// abb : ABB Ltd +// https://www.iana.org/domains/root/db/abb.html +abb + +// abbott : Abbott Laboratories, Inc. +// https://www.iana.org/domains/root/db/abbott.html +abbott + +// abbvie : AbbVie Inc. +// https://www.iana.org/domains/root/db/abbvie.html +abbvie + +// abc : Disney Enterprises, Inc. +// https://www.iana.org/domains/root/db/abc.html +abc + +// able : Able Inc. +// https://www.iana.org/domains/root/db/able.html +able + +// abogado : Registry Services, LLC +// https://www.iana.org/domains/root/db/abogado.html +abogado + +// abudhabi : Abu Dhabi Systems and Information Centre +// https://www.iana.org/domains/root/db/abudhabi.html +abudhabi + +// academy : Binky Moon, LLC +// https://www.iana.org/domains/root/db/academy.html +academy + +// accenture : Accenture plc +// https://www.iana.org/domains/root/db/accenture.html +accenture + +// accountant : dot Accountant Limited +// https://www.iana.org/domains/root/db/accountant.html +accountant + +// accountants : Binky Moon, LLC +// https://www.iana.org/domains/root/db/accountants.html +accountants + +// aco : ACO Severin Ahlmann GmbH & Co. KG +// https://www.iana.org/domains/root/db/aco.html +aco + +// actor : Dog Beach, LLC +// https://www.iana.org/domains/root/db/actor.html +actor + +// ads : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/ads.html +ads + +// adult : ICM Registry AD LLC +// https://www.iana.org/domains/root/db/adult.html +adult + +// aeg : Aktiebolaget Electrolux +// https://www.iana.org/domains/root/db/aeg.html +aeg + +// aetna : Aetna Life Insurance Company +// https://www.iana.org/domains/root/db/aetna.html +aetna + +// afl : Australian Football League +// https://www.iana.org/domains/root/db/afl.html +afl + +// africa : ZA Central Registry NPC trading as Registry.Africa +// https://www.iana.org/domains/root/db/africa.html +africa + +// agakhan : Fondation Aga Khan (Aga Khan Foundation) +// https://www.iana.org/domains/root/db/agakhan.html +agakhan + +// agency : Binky Moon, LLC +// https://www.iana.org/domains/root/db/agency.html +agency + +// aig : American International Group, Inc. +// https://www.iana.org/domains/root/db/aig.html +aig + +// airbus : Airbus S.A.S. +// https://www.iana.org/domains/root/db/airbus.html +airbus + +// airforce : Dog Beach, LLC +// https://www.iana.org/domains/root/db/airforce.html +airforce + +// airtel : Bharti Airtel Limited +// https://www.iana.org/domains/root/db/airtel.html +airtel + +// akdn : Fondation Aga Khan (Aga Khan Foundation) +// https://www.iana.org/domains/root/db/akdn.html +akdn + +// alibaba : Alibaba Group Holding Limited +// https://www.iana.org/domains/root/db/alibaba.html +alibaba + +// alipay : Alibaba Group Holding Limited +// https://www.iana.org/domains/root/db/alipay.html +alipay + +// allfinanz : Allfinanz Deutsche Vermögensberatung Aktiengesellschaft +// https://www.iana.org/domains/root/db/allfinanz.html +allfinanz + +// allstate : Allstate Fire and Casualty Insurance Company +// https://www.iana.org/domains/root/db/allstate.html +allstate + +// ally : Ally Financial Inc. +// https://www.iana.org/domains/root/db/ally.html +ally + +// alsace : Region Grand Est +// https://www.iana.org/domains/root/db/alsace.html +alsace + +// alstom : ALSTOM +// https://www.iana.org/domains/root/db/alstom.html +alstom + +// amazon : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/amazon.html +amazon + +// americanexpress : American Express Travel Related Services Company, Inc. +// https://www.iana.org/domains/root/db/americanexpress.html +americanexpress + +// americanfamily : AmFam, Inc. +// https://www.iana.org/domains/root/db/americanfamily.html +americanfamily + +// amex : American Express Travel Related Services Company, Inc. +// https://www.iana.org/domains/root/db/amex.html +amex + +// amfam : AmFam, Inc. +// https://www.iana.org/domains/root/db/amfam.html +amfam + +// amica : Amica Mutual Insurance Company +// https://www.iana.org/domains/root/db/amica.html +amica + +// amsterdam : Gemeente Amsterdam +// https://www.iana.org/domains/root/db/amsterdam.html +amsterdam + +// analytics : Campus IP LLC +// https://www.iana.org/domains/root/db/analytics.html +analytics + +// android : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/android.html +android + +// anquan : Beijing Qihu Keji Co., Ltd. +// https://www.iana.org/domains/root/db/anquan.html +anquan + +// anz : Australia and New Zealand Banking Group Limited +// https://www.iana.org/domains/root/db/anz.html +anz + +// aol : Yahoo Inc. +// https://www.iana.org/domains/root/db/aol.html +aol + +// apartments : Binky Moon, LLC +// https://www.iana.org/domains/root/db/apartments.html +apartments + +// app : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/app.html +app + +// apple : Apple Inc. +// https://www.iana.org/domains/root/db/apple.html +apple + +// aquarelle : Aquarelle.com +// https://www.iana.org/domains/root/db/aquarelle.html +aquarelle + +// arab : League of Arab States +// https://www.iana.org/domains/root/db/arab.html +arab + +// aramco : Aramco Services Company +// https://www.iana.org/domains/root/db/aramco.html +aramco + +// archi : Identity Digital Limited +// https://www.iana.org/domains/root/db/archi.html +archi + +// army : Dog Beach, LLC +// https://www.iana.org/domains/root/db/army.html +army + +// art : UK Creative Ideas Limited +// https://www.iana.org/domains/root/db/art.html +art + +// arte : Association Relative à la Télévision Européenne G.E.I.E. +// https://www.iana.org/domains/root/db/arte.html +arte + +// asda : Asda Stores Limited +// https://www.iana.org/domains/root/db/asda.html +asda + +// associates : Binky Moon, LLC +// https://www.iana.org/domains/root/db/associates.html +associates + +// athleta : The Gap, Inc. +// https://www.iana.org/domains/root/db/athleta.html +athleta + +// attorney : Dog Beach, LLC +// https://www.iana.org/domains/root/db/attorney.html +attorney + +// auction : Dog Beach, LLC +// https://www.iana.org/domains/root/db/auction.html +auction + +// audi : AUDI Aktiengesellschaft +// https://www.iana.org/domains/root/db/audi.html +audi + +// audible : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/audible.html +audible + +// audio : XYZ.COM LLC +// https://www.iana.org/domains/root/db/audio.html +audio + +// auspost : Australian Postal Corporation +// https://www.iana.org/domains/root/db/auspost.html +auspost + +// author : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/author.html +author + +// auto : XYZ.COM LLC +// https://www.iana.org/domains/root/db/auto.html +auto + +// autos : XYZ.COM LLC +// https://www.iana.org/domains/root/db/autos.html +autos + +// aws : AWS Registry LLC +// https://www.iana.org/domains/root/db/aws.html +aws + +// axa : AXA Group Operations SAS +// https://www.iana.org/domains/root/db/axa.html +axa + +// azure : Microsoft Corporation +// https://www.iana.org/domains/root/db/azure.html +azure + +// baby : XYZ.COM LLC +// https://www.iana.org/domains/root/db/baby.html +baby + +// baidu : Baidu, Inc. +// https://www.iana.org/domains/root/db/baidu.html +baidu + +// banamex : Citigroup Inc. +// https://www.iana.org/domains/root/db/banamex.html +banamex + +// band : Dog Beach, LLC +// https://www.iana.org/domains/root/db/band.html +band + +// bank : fTLD Registry Services LLC +// https://www.iana.org/domains/root/db/bank.html +bank + +// bar : Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable +// https://www.iana.org/domains/root/db/bar.html +bar + +// barcelona : Municipi de Barcelona +// https://www.iana.org/domains/root/db/barcelona.html +barcelona + +// barclaycard : Barclays Bank PLC +// https://www.iana.org/domains/root/db/barclaycard.html +barclaycard + +// barclays : Barclays Bank PLC +// https://www.iana.org/domains/root/db/barclays.html +barclays + +// barefoot : Gallo Vineyards, Inc. +// https://www.iana.org/domains/root/db/barefoot.html +barefoot + +// bargains : Binky Moon, LLC +// https://www.iana.org/domains/root/db/bargains.html +bargains + +// baseball : MLB Advanced Media DH, LLC +// https://www.iana.org/domains/root/db/baseball.html +baseball + +// basketball : Fédération Internationale de Basketball (FIBA) +// https://www.iana.org/domains/root/db/basketball.html +basketball + +// bauhaus : Werkhaus GmbH +// https://www.iana.org/domains/root/db/bauhaus.html +bauhaus + +// bayern : Bayern Connect GmbH +// https://www.iana.org/domains/root/db/bayern.html +bayern + +// bbc : British Broadcasting Corporation +// https://www.iana.org/domains/root/db/bbc.html +bbc + +// bbt : BB&T Corporation +// https://www.iana.org/domains/root/db/bbt.html +bbt + +// bbva : BANCO BILBAO VIZCAYA ARGENTARIA, S.A. +// https://www.iana.org/domains/root/db/bbva.html +bbva + +// bcg : The Boston Consulting Group, Inc. +// https://www.iana.org/domains/root/db/bcg.html +bcg + +// bcn : Municipi de Barcelona +// https://www.iana.org/domains/root/db/bcn.html +bcn + +// beats : Beats Electronics, LLC +// https://www.iana.org/domains/root/db/beats.html +beats + +// beauty : XYZ.COM LLC +// https://www.iana.org/domains/root/db/beauty.html +beauty + +// beer : Registry Services, LLC +// https://www.iana.org/domains/root/db/beer.html +beer + +// berlin : dotBERLIN GmbH & Co. KG +// https://www.iana.org/domains/root/db/berlin.html +berlin + +// best : BestTLD Pty Ltd +// https://www.iana.org/domains/root/db/best.html +best + +// bestbuy : BBY Solutions, Inc. +// https://www.iana.org/domains/root/db/bestbuy.html +bestbuy + +// bet : Identity Digital Limited +// https://www.iana.org/domains/root/db/bet.html +bet + +// bharti : Bharti Enterprises (Holding) Private Limited +// https://www.iana.org/domains/root/db/bharti.html +bharti + +// bible : American Bible Society +// https://www.iana.org/domains/root/db/bible.html +bible + +// bid : dot Bid Limited +// https://www.iana.org/domains/root/db/bid.html +bid + +// bike : Binky Moon, LLC +// https://www.iana.org/domains/root/db/bike.html +bike + +// bing : Microsoft Corporation +// https://www.iana.org/domains/root/db/bing.html +bing + +// bingo : Binky Moon, LLC +// https://www.iana.org/domains/root/db/bingo.html +bingo + +// bio : Identity Digital Limited +// https://www.iana.org/domains/root/db/bio.html +bio + +// black : Identity Digital Limited +// https://www.iana.org/domains/root/db/black.html +black + +// blackfriday : Registry Services, LLC +// https://www.iana.org/domains/root/db/blackfriday.html +blackfriday + +// blockbuster : Dish DBS Corporation +// https://www.iana.org/domains/root/db/blockbuster.html +blockbuster + +// blog : Knock Knock WHOIS There, LLC +// https://www.iana.org/domains/root/db/blog.html +blog + +// bloomberg : Bloomberg IP Holdings LLC +// https://www.iana.org/domains/root/db/bloomberg.html +bloomberg + +// blue : Identity Digital Limited +// https://www.iana.org/domains/root/db/blue.html +blue + +// bms : Bristol-Myers Squibb Company +// https://www.iana.org/domains/root/db/bms.html +bms + +// bmw : Bayerische Motoren Werke Aktiengesellschaft +// https://www.iana.org/domains/root/db/bmw.html +bmw + +// bnpparibas : BNP Paribas +// https://www.iana.org/domains/root/db/bnpparibas.html +bnpparibas + +// boats : XYZ.COM LLC +// https://www.iana.org/domains/root/db/boats.html +boats + +// boehringer : Boehringer Ingelheim International GmbH +// https://www.iana.org/domains/root/db/boehringer.html +boehringer + +// bofa : Bank of America Corporation +// https://www.iana.org/domains/root/db/bofa.html +bofa + +// bom : Núcleo de Informação e Coordenação do Ponto BR - NIC.br +// https://www.iana.org/domains/root/db/bom.html +bom + +// bond : ShortDot SA +// https://www.iana.org/domains/root/db/bond.html +bond + +// boo : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/boo.html +boo + +// book : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/book.html +book + +// booking : Booking.com B.V. +// https://www.iana.org/domains/root/db/booking.html +booking + +// bosch : Robert Bosch GMBH +// https://www.iana.org/domains/root/db/bosch.html +bosch + +// bostik : Bostik SA +// https://www.iana.org/domains/root/db/bostik.html +bostik + +// boston : Registry Services, LLC +// https://www.iana.org/domains/root/db/boston.html +boston + +// bot : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/bot.html +bot + +// boutique : Binky Moon, LLC +// https://www.iana.org/domains/root/db/boutique.html +boutique + +// box : Intercap Registry Inc. +// https://www.iana.org/domains/root/db/box.html +box + +// bradesco : Banco Bradesco S.A. +// https://www.iana.org/domains/root/db/bradesco.html +bradesco + +// bridgestone : Bridgestone Corporation +// https://www.iana.org/domains/root/db/bridgestone.html +bridgestone + +// broadway : Celebrate Broadway, Inc. +// https://www.iana.org/domains/root/db/broadway.html +broadway + +// broker : Dog Beach, LLC +// https://www.iana.org/domains/root/db/broker.html +broker + +// brother : Brother Industries, Ltd. +// https://www.iana.org/domains/root/db/brother.html +brother + +// brussels : DNS.be vzw +// https://www.iana.org/domains/root/db/brussels.html +brussels + +// build : Plan Bee LLC +// https://www.iana.org/domains/root/db/build.html +build + +// builders : Binky Moon, LLC +// https://www.iana.org/domains/root/db/builders.html +builders + +// business : Binky Moon, LLC +// https://www.iana.org/domains/root/db/business.html +business + +// buy : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/buy.html +buy + +// buzz : DOTSTRATEGY CO. +// https://www.iana.org/domains/root/db/buzz.html +buzz + +// bzh : Association www.bzh +// https://www.iana.org/domains/root/db/bzh.html +bzh + +// cab : Binky Moon, LLC +// https://www.iana.org/domains/root/db/cab.html +cab + +// cafe : Binky Moon, LLC +// https://www.iana.org/domains/root/db/cafe.html +cafe + +// cal : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/cal.html +cal + +// call : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/call.html +call + +// calvinklein : PVH gTLD Holdings LLC +// https://www.iana.org/domains/root/db/calvinklein.html +calvinklein + +// cam : Cam Connecting SARL +// https://www.iana.org/domains/root/db/cam.html +cam + +// camera : Binky Moon, LLC +// https://www.iana.org/domains/root/db/camera.html +camera + +// camp : Binky Moon, LLC +// https://www.iana.org/domains/root/db/camp.html +camp + +// canon : Canon Inc. +// https://www.iana.org/domains/root/db/canon.html +canon + +// capetown : ZA Central Registry NPC trading as ZA Central Registry +// https://www.iana.org/domains/root/db/capetown.html +capetown + +// capital : Binky Moon, LLC +// https://www.iana.org/domains/root/db/capital.html +capital + +// capitalone : Capital One Financial Corporation +// https://www.iana.org/domains/root/db/capitalone.html +capitalone + +// car : XYZ.COM LLC +// https://www.iana.org/domains/root/db/car.html +car + +// caravan : Caravan International, Inc. +// https://www.iana.org/domains/root/db/caravan.html +caravan + +// cards : Binky Moon, LLC +// https://www.iana.org/domains/root/db/cards.html +cards + +// care : Binky Moon, LLC +// https://www.iana.org/domains/root/db/care.html +care + +// career : dotCareer LLC +// https://www.iana.org/domains/root/db/career.html +career + +// careers : Binky Moon, LLC +// https://www.iana.org/domains/root/db/careers.html +careers + +// cars : XYZ.COM LLC +// https://www.iana.org/domains/root/db/cars.html +cars + +// casa : Registry Services, LLC +// https://www.iana.org/domains/root/db/casa.html +casa + +// case : Digity, LLC +// https://www.iana.org/domains/root/db/case.html +case + +// cash : Binky Moon, LLC +// https://www.iana.org/domains/root/db/cash.html +cash + +// casino : Binky Moon, LLC +// https://www.iana.org/domains/root/db/casino.html +casino + +// catering : Binky Moon, LLC +// https://www.iana.org/domains/root/db/catering.html +catering + +// catholic : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) +// https://www.iana.org/domains/root/db/catholic.html +catholic + +// cba : COMMONWEALTH BANK OF AUSTRALIA +// https://www.iana.org/domains/root/db/cba.html +cba + +// cbn : The Christian Broadcasting Network, Inc. +// https://www.iana.org/domains/root/db/cbn.html +cbn + +// cbre : CBRE, Inc. +// https://www.iana.org/domains/root/db/cbre.html +cbre + +// center : Binky Moon, LLC +// https://www.iana.org/domains/root/db/center.html +center + +// ceo : XYZ.COM LLC +// https://www.iana.org/domains/root/db/ceo.html +ceo + +// cern : European Organization for Nuclear Research ("CERN") +// https://www.iana.org/domains/root/db/cern.html +cern + +// cfa : CFA Institute +// https://www.iana.org/domains/root/db/cfa.html +cfa + +// cfd : ShortDot SA +// https://www.iana.org/domains/root/db/cfd.html +cfd + +// chanel : Chanel International B.V. +// https://www.iana.org/domains/root/db/chanel.html +chanel + +// channel : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/channel.html +channel + +// charity : Public Interest Registry +// https://www.iana.org/domains/root/db/charity.html +charity + +// chase : JPMorgan Chase Bank, National Association +// https://www.iana.org/domains/root/db/chase.html +chase + +// chat : Binky Moon, LLC +// https://www.iana.org/domains/root/db/chat.html +chat + +// cheap : Binky Moon, LLC +// https://www.iana.org/domains/root/db/cheap.html +cheap + +// chintai : CHINTAI Corporation +// https://www.iana.org/domains/root/db/chintai.html +chintai + +// christmas : XYZ.COM LLC +// https://www.iana.org/domains/root/db/christmas.html +christmas + +// chrome : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/chrome.html +chrome + +// church : Binky Moon, LLC +// https://www.iana.org/domains/root/db/church.html +church + +// cipriani : Hotel Cipriani Srl +// https://www.iana.org/domains/root/db/cipriani.html +cipriani + +// circle : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/circle.html +circle + +// cisco : Cisco Technology, Inc. +// https://www.iana.org/domains/root/db/cisco.html +cisco + +// citadel : Citadel Domain LLC +// https://www.iana.org/domains/root/db/citadel.html +citadel + +// citi : Citigroup Inc. +// https://www.iana.org/domains/root/db/citi.html +citi + +// citic : CITIC Group Corporation +// https://www.iana.org/domains/root/db/citic.html +citic + +// city : Binky Moon, LLC +// https://www.iana.org/domains/root/db/city.html +city + +// claims : Binky Moon, LLC +// https://www.iana.org/domains/root/db/claims.html +claims + +// cleaning : Binky Moon, LLC +// https://www.iana.org/domains/root/db/cleaning.html +cleaning + +// click : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/click.html +click + +// clinic : Binky Moon, LLC +// https://www.iana.org/domains/root/db/clinic.html +clinic + +// clinique : The Estée Lauder Companies Inc. +// https://www.iana.org/domains/root/db/clinique.html +clinique + +// clothing : Binky Moon, LLC +// https://www.iana.org/domains/root/db/clothing.html +clothing + +// cloud : Aruba PEC S.p.A. +// https://www.iana.org/domains/root/db/cloud.html +cloud + +// club : Registry Services, LLC +// https://www.iana.org/domains/root/db/club.html +club + +// clubmed : Club Méditerranée S.A. +// https://www.iana.org/domains/root/db/clubmed.html +clubmed + +// coach : Binky Moon, LLC +// https://www.iana.org/domains/root/db/coach.html +coach + +// codes : Binky Moon, LLC +// https://www.iana.org/domains/root/db/codes.html +codes + +// coffee : Binky Moon, LLC +// https://www.iana.org/domains/root/db/coffee.html +coffee + +// college : XYZ.COM LLC +// https://www.iana.org/domains/root/db/college.html +college + +// cologne : dotKoeln GmbH +// https://www.iana.org/domains/root/db/cologne.html +cologne + +// commbank : COMMONWEALTH BANK OF AUSTRALIA +// https://www.iana.org/domains/root/db/commbank.html +commbank + +// community : Binky Moon, LLC +// https://www.iana.org/domains/root/db/community.html +community + +// company : Binky Moon, LLC +// https://www.iana.org/domains/root/db/company.html +company + +// compare : Registry Services, LLC +// https://www.iana.org/domains/root/db/compare.html +compare + +// computer : Binky Moon, LLC +// https://www.iana.org/domains/root/db/computer.html +computer + +// comsec : VeriSign, Inc. +// https://www.iana.org/domains/root/db/comsec.html +comsec + +// condos : Binky Moon, LLC +// https://www.iana.org/domains/root/db/condos.html +condos + +// construction : Binky Moon, LLC +// https://www.iana.org/domains/root/db/construction.html +construction + +// consulting : Dog Beach, LLC +// https://www.iana.org/domains/root/db/consulting.html +consulting + +// contact : Dog Beach, LLC +// https://www.iana.org/domains/root/db/contact.html +contact + +// contractors : Binky Moon, LLC +// https://www.iana.org/domains/root/db/contractors.html +contractors + +// cooking : Registry Services, LLC +// https://www.iana.org/domains/root/db/cooking.html +cooking + +// cool : Binky Moon, LLC +// https://www.iana.org/domains/root/db/cool.html +cool + +// corsica : Collectivité de Corse +// https://www.iana.org/domains/root/db/corsica.html +corsica + +// country : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/country.html +country + +// coupon : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/coupon.html +coupon + +// coupons : Binky Moon, LLC +// https://www.iana.org/domains/root/db/coupons.html +coupons + +// courses : Registry Services, LLC +// https://www.iana.org/domains/root/db/courses.html +courses + +// cpa : American Institute of Certified Public Accountants +// https://www.iana.org/domains/root/db/cpa.html +cpa + +// credit : Binky Moon, LLC +// https://www.iana.org/domains/root/db/credit.html +credit + +// creditcard : Binky Moon, LLC +// https://www.iana.org/domains/root/db/creditcard.html +creditcard + +// creditunion : DotCooperation LLC +// https://www.iana.org/domains/root/db/creditunion.html +creditunion + +// cricket : dot Cricket Limited +// https://www.iana.org/domains/root/db/cricket.html +cricket + +// crown : Crown Equipment Corporation +// https://www.iana.org/domains/root/db/crown.html +crown + +// crs : Federated Co-operatives Limited +// https://www.iana.org/domains/root/db/crs.html +crs + +// cruise : Viking River Cruises (Bermuda) Ltd. +// https://www.iana.org/domains/root/db/cruise.html +cruise + +// cruises : Binky Moon, LLC +// https://www.iana.org/domains/root/db/cruises.html +cruises + +// cuisinella : SCHMIDT GROUPE S.A.S. +// https://www.iana.org/domains/root/db/cuisinella.html +cuisinella + +// cymru : Nominet UK +// https://www.iana.org/domains/root/db/cymru.html +cymru + +// cyou : ShortDot SA +// https://www.iana.org/domains/root/db/cyou.html +cyou + +// dad : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/dad.html +dad + +// dance : Dog Beach, LLC +// https://www.iana.org/domains/root/db/dance.html +dance + +// data : Dish DBS Corporation +// https://www.iana.org/domains/root/db/data.html +data + +// date : dot Date Limited +// https://www.iana.org/domains/root/db/date.html +date + +// dating : Binky Moon, LLC +// https://www.iana.org/domains/root/db/dating.html +dating + +// datsun : NISSAN MOTOR CO., LTD. +// https://www.iana.org/domains/root/db/datsun.html +datsun + +// day : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/day.html +day + +// dclk : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/dclk.html +dclk + +// dds : Registry Services, LLC +// https://www.iana.org/domains/root/db/dds.html +dds + +// deal : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/deal.html +deal + +// dealer : Intercap Registry Inc. +// https://www.iana.org/domains/root/db/dealer.html +dealer + +// deals : Binky Moon, LLC +// https://www.iana.org/domains/root/db/deals.html +deals + +// degree : Dog Beach, LLC +// https://www.iana.org/domains/root/db/degree.html +degree + +// delivery : Binky Moon, LLC +// https://www.iana.org/domains/root/db/delivery.html +delivery + +// dell : Dell Inc. +// https://www.iana.org/domains/root/db/dell.html +dell + +// deloitte : Deloitte Touche Tohmatsu +// https://www.iana.org/domains/root/db/deloitte.html +deloitte + +// delta : Delta Air Lines, Inc. +// https://www.iana.org/domains/root/db/delta.html +delta + +// democrat : Dog Beach, LLC +// https://www.iana.org/domains/root/db/democrat.html +democrat + +// dental : Binky Moon, LLC +// https://www.iana.org/domains/root/db/dental.html +dental + +// dentist : Dog Beach, LLC +// https://www.iana.org/domains/root/db/dentist.html +dentist + +// desi +// https://www.iana.org/domains/root/db/desi.html +desi + +// design : Registry Services, LLC +// https://www.iana.org/domains/root/db/design.html +design + +// dev : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/dev.html +dev + +// dhl : Deutsche Post AG +// https://www.iana.org/domains/root/db/dhl.html +dhl + +// diamonds : Binky Moon, LLC +// https://www.iana.org/domains/root/db/diamonds.html +diamonds + +// diet : XYZ.COM LLC +// https://www.iana.org/domains/root/db/diet.html +diet + +// digital : Binky Moon, LLC +// https://www.iana.org/domains/root/db/digital.html +digital + +// direct : Binky Moon, LLC +// https://www.iana.org/domains/root/db/direct.html +direct + +// directory : Binky Moon, LLC +// https://www.iana.org/domains/root/db/directory.html +directory + +// discount : Binky Moon, LLC +// https://www.iana.org/domains/root/db/discount.html +discount + +// discover : Discover Financial Services +// https://www.iana.org/domains/root/db/discover.html +discover + +// dish : Dish DBS Corporation +// https://www.iana.org/domains/root/db/dish.html +dish + +// diy : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/diy.html +diy + +// dnp : Dai Nippon Printing Co., Ltd. +// https://www.iana.org/domains/root/db/dnp.html +dnp + +// docs : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/docs.html +docs + +// doctor : Binky Moon, LLC +// https://www.iana.org/domains/root/db/doctor.html +doctor + +// dog : Binky Moon, LLC +// https://www.iana.org/domains/root/db/dog.html +dog + +// domains : Binky Moon, LLC +// https://www.iana.org/domains/root/db/domains.html +domains + +// dot : Dish DBS Corporation +// https://www.iana.org/domains/root/db/dot.html +dot + +// download : dot Support Limited +// https://www.iana.org/domains/root/db/download.html +download + +// drive : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/drive.html +drive + +// dtv : Dish DBS Corporation +// https://www.iana.org/domains/root/db/dtv.html +dtv + +// dubai : Dubai Smart Government Department +// https://www.iana.org/domains/root/db/dubai.html +dubai + +// dunlop : The Goodyear Tire & Rubber Company +// https://www.iana.org/domains/root/db/dunlop.html +dunlop + +// dupont : DuPont Specialty Products USA, LLC +// https://www.iana.org/domains/root/db/dupont.html +dupont + +// durban : ZA Central Registry NPC trading as ZA Central Registry +// https://www.iana.org/domains/root/db/durban.html +durban + +// dvag : Deutsche Vermögensberatung Aktiengesellschaft DVAG +// https://www.iana.org/domains/root/db/dvag.html +dvag + +// dvr : DISH Technologies L.L.C. +// https://www.iana.org/domains/root/db/dvr.html +dvr + +// earth : Interlink Systems Innovation Institute K.K. +// https://www.iana.org/domains/root/db/earth.html +earth + +// eat : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/eat.html +eat + +// eco : Big Room Inc. +// https://www.iana.org/domains/root/db/eco.html +eco + +// edeka : EDEKA Verband kaufmännischer Genossenschaften e.V. +// https://www.iana.org/domains/root/db/edeka.html +edeka + +// education : Binky Moon, LLC +// https://www.iana.org/domains/root/db/education.html +education + +// email : Binky Moon, LLC +// https://www.iana.org/domains/root/db/email.html +email + +// emerck : Merck KGaA +// https://www.iana.org/domains/root/db/emerck.html +emerck + +// energy : Binky Moon, LLC +// https://www.iana.org/domains/root/db/energy.html +energy + +// engineer : Dog Beach, LLC +// https://www.iana.org/domains/root/db/engineer.html +engineer + +// engineering : Binky Moon, LLC +// https://www.iana.org/domains/root/db/engineering.html +engineering + +// enterprises : Binky Moon, LLC +// https://www.iana.org/domains/root/db/enterprises.html +enterprises + +// epson : Seiko Epson Corporation +// https://www.iana.org/domains/root/db/epson.html +epson + +// equipment : Binky Moon, LLC +// https://www.iana.org/domains/root/db/equipment.html +equipment + +// ericsson : Telefonaktiebolaget L M Ericsson +// https://www.iana.org/domains/root/db/ericsson.html +ericsson + +// erni : ERNI Group Holding AG +// https://www.iana.org/domains/root/db/erni.html +erni + +// esq : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/esq.html +esq + +// estate : Binky Moon, LLC +// https://www.iana.org/domains/root/db/estate.html +estate + +// eurovision : European Broadcasting Union (EBU) +// https://www.iana.org/domains/root/db/eurovision.html +eurovision + +// eus : Puntueus Fundazioa +// https://www.iana.org/domains/root/db/eus.html +eus + +// events : Binky Moon, LLC +// https://www.iana.org/domains/root/db/events.html +events + +// exchange : Binky Moon, LLC +// https://www.iana.org/domains/root/db/exchange.html +exchange + +// expert : Binky Moon, LLC +// https://www.iana.org/domains/root/db/expert.html +expert + +// exposed : Binky Moon, LLC +// https://www.iana.org/domains/root/db/exposed.html +exposed + +// express : Binky Moon, LLC +// https://www.iana.org/domains/root/db/express.html +express + +// extraspace : Extra Space Storage LLC +// https://www.iana.org/domains/root/db/extraspace.html +extraspace + +// fage : Fage International S.A. +// https://www.iana.org/domains/root/db/fage.html +fage + +// fail : Binky Moon, LLC +// https://www.iana.org/domains/root/db/fail.html +fail + +// fairwinds : FairWinds Partners, LLC +// https://www.iana.org/domains/root/db/fairwinds.html +fairwinds + +// faith : dot Faith Limited +// https://www.iana.org/domains/root/db/faith.html +faith + +// family : Dog Beach, LLC +// https://www.iana.org/domains/root/db/family.html +family + +// fan : Dog Beach, LLC +// https://www.iana.org/domains/root/db/fan.html +fan + +// fans : ZDNS International Limited +// https://www.iana.org/domains/root/db/fans.html +fans + +// farm : Binky Moon, LLC +// https://www.iana.org/domains/root/db/farm.html +farm + +// farmers : Farmers Insurance Exchange +// https://www.iana.org/domains/root/db/farmers.html +farmers + +// fashion : Registry Services, LLC +// https://www.iana.org/domains/root/db/fashion.html +fashion + +// fast : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/fast.html +fast + +// fedex : Federal Express Corporation +// https://www.iana.org/domains/root/db/fedex.html +fedex + +// feedback : Top Level Spectrum, Inc. +// https://www.iana.org/domains/root/db/feedback.html +feedback + +// ferrari : Fiat Chrysler Automobiles N.V. +// https://www.iana.org/domains/root/db/ferrari.html +ferrari + +// ferrero : Ferrero Trading Lux S.A. +// https://www.iana.org/domains/root/db/ferrero.html +ferrero + +// fidelity : Fidelity Brokerage Services LLC +// https://www.iana.org/domains/root/db/fidelity.html +fidelity + +// fido : Rogers Communications Canada Inc. +// https://www.iana.org/domains/root/db/fido.html +fido + +// film : Motion Picture Domain Registry Pty Ltd +// https://www.iana.org/domains/root/db/film.html +film + +// final : Núcleo de Informação e Coordenação do Ponto BR - NIC.br +// https://www.iana.org/domains/root/db/final.html +final + +// finance : Binky Moon, LLC +// https://www.iana.org/domains/root/db/finance.html +finance + +// financial : Binky Moon, LLC +// https://www.iana.org/domains/root/db/financial.html +financial + +// fire : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/fire.html +fire + +// firestone : Bridgestone Licensing Services, Inc +// https://www.iana.org/domains/root/db/firestone.html +firestone + +// firmdale : Firmdale Holdings Limited +// https://www.iana.org/domains/root/db/firmdale.html +firmdale + +// fish : Binky Moon, LLC +// https://www.iana.org/domains/root/db/fish.html +fish + +// fishing : Registry Services, LLC +// https://www.iana.org/domains/root/db/fishing.html +fishing + +// fit : Registry Services, LLC +// https://www.iana.org/domains/root/db/fit.html +fit + +// fitness : Binky Moon, LLC +// https://www.iana.org/domains/root/db/fitness.html +fitness + +// flickr : Flickr, Inc. +// https://www.iana.org/domains/root/db/flickr.html +flickr + +// flights : Binky Moon, LLC +// https://www.iana.org/domains/root/db/flights.html +flights + +// flir : FLIR Systems, Inc. +// https://www.iana.org/domains/root/db/flir.html +flir + +// florist : Binky Moon, LLC +// https://www.iana.org/domains/root/db/florist.html +florist + +// flowers : XYZ.COM LLC +// https://www.iana.org/domains/root/db/flowers.html +flowers + +// fly : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/fly.html +fly + +// foo : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/foo.html +foo + +// food : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/food.html +food + +// football : Binky Moon, LLC +// https://www.iana.org/domains/root/db/football.html +football + +// ford : Ford Motor Company +// https://www.iana.org/domains/root/db/ford.html +ford + +// forex : Dog Beach, LLC +// https://www.iana.org/domains/root/db/forex.html +forex + +// forsale : Dog Beach, LLC +// https://www.iana.org/domains/root/db/forsale.html +forsale + +// forum : Waterford Limited +// https://www.iana.org/domains/root/db/forum.html +forum + +// foundation : Public Interest Registry +// https://www.iana.org/domains/root/db/foundation.html +foundation + +// fox : FOX Registry, LLC +// https://www.iana.org/domains/root/db/fox.html +fox + +// free : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/free.html +free + +// fresenius : Fresenius Immobilien-Verwaltungs-GmbH +// https://www.iana.org/domains/root/db/fresenius.html +fresenius + +// frl : FRLregistry B.V. +// https://www.iana.org/domains/root/db/frl.html +frl + +// frogans : OP3FT +// https://www.iana.org/domains/root/db/frogans.html +frogans + +// frontier : Frontier Communications Corporation +// https://www.iana.org/domains/root/db/frontier.html +frontier + +// ftr : Frontier Communications Corporation +// https://www.iana.org/domains/root/db/ftr.html +ftr + +// fujitsu : Fujitsu Limited +// https://www.iana.org/domains/root/db/fujitsu.html +fujitsu + +// fun : Radix Technologies Inc SEZC +// https://www.iana.org/domains/root/db/fun.html +fun + +// fund : Binky Moon, LLC +// https://www.iana.org/domains/root/db/fund.html +fund + +// furniture : Binky Moon, LLC +// https://www.iana.org/domains/root/db/furniture.html +furniture + +// futbol : Dog Beach, LLC +// https://www.iana.org/domains/root/db/futbol.html +futbol + +// fyi : Binky Moon, LLC +// https://www.iana.org/domains/root/db/fyi.html +fyi + +// gal : Asociación puntoGAL +// https://www.iana.org/domains/root/db/gal.html +gal + +// gallery : Binky Moon, LLC +// https://www.iana.org/domains/root/db/gallery.html +gallery + +// gallo : Gallo Vineyards, Inc. +// https://www.iana.org/domains/root/db/gallo.html +gallo + +// gallup : Gallup, Inc. +// https://www.iana.org/domains/root/db/gallup.html +gallup + +// game : XYZ.COM LLC +// https://www.iana.org/domains/root/db/game.html +game + +// games : Dog Beach, LLC +// https://www.iana.org/domains/root/db/games.html +games + +// gap : The Gap, Inc. +// https://www.iana.org/domains/root/db/gap.html +gap + +// garden : Registry Services, LLC +// https://www.iana.org/domains/root/db/garden.html +garden + +// gay : Registry Services, LLC +// https://www.iana.org/domains/root/db/gay.html +gay + +// gbiz : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/gbiz.html +gbiz + +// gdn : Joint Stock Company "Navigation-information systems" +// https://www.iana.org/domains/root/db/gdn.html +gdn + +// gea : GEA Group Aktiengesellschaft +// https://www.iana.org/domains/root/db/gea.html +gea + +// gent : Easyhost BV +// https://www.iana.org/domains/root/db/gent.html +gent + +// genting : Resorts World Inc Pte. Ltd. +// https://www.iana.org/domains/root/db/genting.html +genting + +// george : Wal-Mart Stores, Inc. +// https://www.iana.org/domains/root/db/george.html +george + +// ggee : GMO Internet, Inc. +// https://www.iana.org/domains/root/db/ggee.html +ggee + +// gift : DotGift, LLC +// https://www.iana.org/domains/root/db/gift.html +gift + +// gifts : Binky Moon, LLC +// https://www.iana.org/domains/root/db/gifts.html +gifts + +// gives : Public Interest Registry +// https://www.iana.org/domains/root/db/gives.html +gives + +// giving : Public Interest Registry +// https://www.iana.org/domains/root/db/giving.html +giving + +// glass : Binky Moon, LLC +// https://www.iana.org/domains/root/db/glass.html +glass + +// gle : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/gle.html +gle + +// global : Identity Digital Limited +// https://www.iana.org/domains/root/db/global.html +global + +// globo : Globo Comunicação e Participações S.A +// https://www.iana.org/domains/root/db/globo.html +globo + +// gmail : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/gmail.html +gmail + +// gmbh : Binky Moon, LLC +// https://www.iana.org/domains/root/db/gmbh.html +gmbh + +// gmo : GMO Internet, Inc. +// https://www.iana.org/domains/root/db/gmo.html +gmo + +// gmx : 1&1 Mail & Media GmbH +// https://www.iana.org/domains/root/db/gmx.html +gmx + +// godaddy : Go Daddy East, LLC +// https://www.iana.org/domains/root/db/godaddy.html +godaddy + +// gold : Binky Moon, LLC +// https://www.iana.org/domains/root/db/gold.html +gold + +// goldpoint : YODOBASHI CAMERA CO.,LTD. +// https://www.iana.org/domains/root/db/goldpoint.html +goldpoint + +// golf : Binky Moon, LLC +// https://www.iana.org/domains/root/db/golf.html +golf + +// goo : NTT DOCOMO, INC. +// https://www.iana.org/domains/root/db/goo.html +goo + +// goodyear : The Goodyear Tire & Rubber Company +// https://www.iana.org/domains/root/db/goodyear.html +goodyear + +// goog : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/goog.html +goog + +// google : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/google.html +google + +// gop : Republican State Leadership Committee, Inc. +// https://www.iana.org/domains/root/db/gop.html +gop + +// got : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/got.html +got + +// grainger : Grainger Registry Services, LLC +// https://www.iana.org/domains/root/db/grainger.html +grainger + +// graphics : Binky Moon, LLC +// https://www.iana.org/domains/root/db/graphics.html +graphics + +// gratis : Binky Moon, LLC +// https://www.iana.org/domains/root/db/gratis.html +gratis + +// green : Identity Digital Limited +// https://www.iana.org/domains/root/db/green.html +green + +// gripe : Binky Moon, LLC +// https://www.iana.org/domains/root/db/gripe.html +gripe + +// grocery : Wal-Mart Stores, Inc. +// https://www.iana.org/domains/root/db/grocery.html +grocery + +// group : Binky Moon, LLC +// https://www.iana.org/domains/root/db/group.html +group + +// gucci : Guccio Gucci S.p.a. +// https://www.iana.org/domains/root/db/gucci.html +gucci + +// guge : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/guge.html +guge + +// guide : Binky Moon, LLC +// https://www.iana.org/domains/root/db/guide.html +guide + +// guitars : XYZ.COM LLC +// https://www.iana.org/domains/root/db/guitars.html +guitars + +// guru : Binky Moon, LLC +// https://www.iana.org/domains/root/db/guru.html +guru + +// hair : XYZ.COM LLC +// https://www.iana.org/domains/root/db/hair.html +hair + +// hamburg : Hamburg Top-Level-Domain GmbH +// https://www.iana.org/domains/root/db/hamburg.html +hamburg + +// hangout : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/hangout.html +hangout + +// haus : Dog Beach, LLC +// https://www.iana.org/domains/root/db/haus.html +haus + +// hbo : HBO Registry Services, Inc. +// https://www.iana.org/domains/root/db/hbo.html +hbo + +// hdfc : HDFC BANK LIMITED +// https://www.iana.org/domains/root/db/hdfc.html +hdfc + +// hdfcbank : HDFC BANK LIMITED +// https://www.iana.org/domains/root/db/hdfcbank.html +hdfcbank + +// health : Registry Services, LLC +// https://www.iana.org/domains/root/db/health.html +health + +// healthcare : Binky Moon, LLC +// https://www.iana.org/domains/root/db/healthcare.html +healthcare + +// help : Innovation service Limited +// https://www.iana.org/domains/root/db/help.html +help + +// helsinki : City of Helsinki +// https://www.iana.org/domains/root/db/helsinki.html +helsinki + +// here : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/here.html +here + +// hermes : HERMES INTERNATIONAL +// https://www.iana.org/domains/root/db/hermes.html +hermes + +// hiphop : Dot Hip Hop, LLC +// https://www.iana.org/domains/root/db/hiphop.html +hiphop + +// hisamitsu : Hisamitsu Pharmaceutical Co.,Inc. +// https://www.iana.org/domains/root/db/hisamitsu.html +hisamitsu + +// hitachi : Hitachi, Ltd. +// https://www.iana.org/domains/root/db/hitachi.html +hitachi + +// hiv : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/hiv.html +hiv + +// hkt : PCCW-HKT DataCom Services Limited +// https://www.iana.org/domains/root/db/hkt.html +hkt + +// hockey : Binky Moon, LLC +// https://www.iana.org/domains/root/db/hockey.html +hockey + +// holdings : Binky Moon, LLC +// https://www.iana.org/domains/root/db/holdings.html +holdings + +// holiday : Binky Moon, LLC +// https://www.iana.org/domains/root/db/holiday.html +holiday + +// homedepot : Home Depot Product Authority, LLC +// https://www.iana.org/domains/root/db/homedepot.html +homedepot + +// homegoods : The TJX Companies, Inc. +// https://www.iana.org/domains/root/db/homegoods.html +homegoods + +// homes : XYZ.COM LLC +// https://www.iana.org/domains/root/db/homes.html +homes + +// homesense : The TJX Companies, Inc. +// https://www.iana.org/domains/root/db/homesense.html +homesense + +// honda : Honda Motor Co., Ltd. +// https://www.iana.org/domains/root/db/honda.html +honda + +// horse : Registry Services, LLC +// https://www.iana.org/domains/root/db/horse.html +horse + +// hospital : Binky Moon, LLC +// https://www.iana.org/domains/root/db/hospital.html +hospital + +// host : Radix Technologies Inc SEZC +// https://www.iana.org/domains/root/db/host.html +host + +// hosting : XYZ.COM LLC +// https://www.iana.org/domains/root/db/hosting.html +hosting + +// hot : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/hot.html +hot + +// hotels : Booking.com B.V. +// https://www.iana.org/domains/root/db/hotels.html +hotels + +// hotmail : Microsoft Corporation +// https://www.iana.org/domains/root/db/hotmail.html +hotmail + +// house : Binky Moon, LLC +// https://www.iana.org/domains/root/db/house.html +house + +// how : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/how.html +how + +// hsbc : HSBC Global Services (UK) Limited +// https://www.iana.org/domains/root/db/hsbc.html +hsbc + +// hughes : Hughes Satellite Systems Corporation +// https://www.iana.org/domains/root/db/hughes.html +hughes + +// hyatt : Hyatt GTLD, L.L.C. +// https://www.iana.org/domains/root/db/hyatt.html +hyatt + +// hyundai : Hyundai Motor Company +// https://www.iana.org/domains/root/db/hyundai.html +hyundai + +// ibm : International Business Machines Corporation +// https://www.iana.org/domains/root/db/ibm.html +ibm + +// icbc : Industrial and Commercial Bank of China Limited +// https://www.iana.org/domains/root/db/icbc.html +icbc + +// ice : IntercontinentalExchange, Inc. +// https://www.iana.org/domains/root/db/ice.html +ice + +// icu : ShortDot SA +// https://www.iana.org/domains/root/db/icu.html +icu + +// ieee : IEEE Global LLC +// https://www.iana.org/domains/root/db/ieee.html +ieee + +// ifm : ifm electronic gmbh +// https://www.iana.org/domains/root/db/ifm.html +ifm + +// ikano : Ikano S.A. +// https://www.iana.org/domains/root/db/ikano.html +ikano + +// imamat : Fondation Aga Khan (Aga Khan Foundation) +// https://www.iana.org/domains/root/db/imamat.html +imamat + +// imdb : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/imdb.html +imdb + +// immo : Binky Moon, LLC +// https://www.iana.org/domains/root/db/immo.html +immo + +// immobilien : Dog Beach, LLC +// https://www.iana.org/domains/root/db/immobilien.html +immobilien + +// inc : Intercap Registry Inc. +// https://www.iana.org/domains/root/db/inc.html +inc + +// industries : Binky Moon, LLC +// https://www.iana.org/domains/root/db/industries.html +industries + +// infiniti : NISSAN MOTOR CO., LTD. +// https://www.iana.org/domains/root/db/infiniti.html +infiniti + +// ing : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/ing.html +ing + +// ink : Registry Services, LLC +// https://www.iana.org/domains/root/db/ink.html +ink + +// institute : Binky Moon, LLC +// https://www.iana.org/domains/root/db/institute.html +institute + +// insurance : fTLD Registry Services LLC +// https://www.iana.org/domains/root/db/insurance.html +insurance + +// insure : Binky Moon, LLC +// https://www.iana.org/domains/root/db/insure.html +insure + +// international : Binky Moon, LLC +// https://www.iana.org/domains/root/db/international.html +international + +// intuit : Intuit Administrative Services, Inc. +// https://www.iana.org/domains/root/db/intuit.html +intuit + +// investments : Binky Moon, LLC +// https://www.iana.org/domains/root/db/investments.html +investments + +// ipiranga : Ipiranga Produtos de Petroleo S.A. +// https://www.iana.org/domains/root/db/ipiranga.html +ipiranga + +// irish : Binky Moon, LLC +// https://www.iana.org/domains/root/db/irish.html +irish + +// ismaili : Fondation Aga Khan (Aga Khan Foundation) +// https://www.iana.org/domains/root/db/ismaili.html +ismaili + +// ist : Istanbul Metropolitan Municipality +// https://www.iana.org/domains/root/db/ist.html +ist + +// istanbul : Istanbul Metropolitan Municipality +// https://www.iana.org/domains/root/db/istanbul.html +istanbul + +// itau : Itau Unibanco Holding S.A. +// https://www.iana.org/domains/root/db/itau.html +itau + +// itv : ITV Services Limited +// https://www.iana.org/domains/root/db/itv.html +itv + +// jaguar : Jaguar Land Rover Ltd +// https://www.iana.org/domains/root/db/jaguar.html +jaguar + +// java : Oracle Corporation +// https://www.iana.org/domains/root/db/java.html +java + +// jcb : JCB Co., Ltd. +// https://www.iana.org/domains/root/db/jcb.html +jcb + +// jeep : FCA US LLC. +// https://www.iana.org/domains/root/db/jeep.html +jeep + +// jetzt : Binky Moon, LLC +// https://www.iana.org/domains/root/db/jetzt.html +jetzt + +// jewelry : Binky Moon, LLC +// https://www.iana.org/domains/root/db/jewelry.html +jewelry + +// jio : Reliance Industries Limited +// https://www.iana.org/domains/root/db/jio.html +jio + +// jll : Jones Lang LaSalle Incorporated +// https://www.iana.org/domains/root/db/jll.html +jll + +// jmp : Matrix IP LLC +// https://www.iana.org/domains/root/db/jmp.html +jmp + +// jnj : Johnson & Johnson Services, Inc. +// https://www.iana.org/domains/root/db/jnj.html +jnj + +// joburg : ZA Central Registry NPC trading as ZA Central Registry +// https://www.iana.org/domains/root/db/joburg.html +joburg + +// jot : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/jot.html +jot + +// joy : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/joy.html +joy + +// jpmorgan : JPMorgan Chase Bank, National Association +// https://www.iana.org/domains/root/db/jpmorgan.html +jpmorgan + +// jprs : Japan Registry Services Co., Ltd. +// https://www.iana.org/domains/root/db/jprs.html +jprs + +// juegos : Dog Beach, LLC +// https://www.iana.org/domains/root/db/juegos.html +juegos + +// juniper : JUNIPER NETWORKS, INC. +// https://www.iana.org/domains/root/db/juniper.html +juniper + +// kaufen : Dog Beach, LLC +// https://www.iana.org/domains/root/db/kaufen.html +kaufen + +// kddi : KDDI CORPORATION +// https://www.iana.org/domains/root/db/kddi.html +kddi + +// kerryhotels : Kerry Trading Co. Limited +// https://www.iana.org/domains/root/db/kerryhotels.html +kerryhotels + +// kerryproperties : Kerry Trading Co. Limited +// https://www.iana.org/domains/root/db/kerryproperties.html +kerryproperties + +// kfh : Kuwait Finance House +// https://www.iana.org/domains/root/db/kfh.html +kfh + +// kia : KIA MOTORS CORPORATION +// https://www.iana.org/domains/root/db/kia.html +kia + +// kids : DotKids Foundation Limited +// https://www.iana.org/domains/root/db/kids.html +kids + +// kim : Identity Digital Limited +// https://www.iana.org/domains/root/db/kim.html +kim + +// kindle : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/kindle.html +kindle + +// kitchen : Binky Moon, LLC +// https://www.iana.org/domains/root/db/kitchen.html +kitchen + +// kiwi : DOT KIWI LIMITED +// https://www.iana.org/domains/root/db/kiwi.html +kiwi + +// koeln : dotKoeln GmbH +// https://www.iana.org/domains/root/db/koeln.html +koeln + +// komatsu : Komatsu Ltd. +// https://www.iana.org/domains/root/db/komatsu.html +komatsu + +// kosher : Kosher Marketing Assets LLC +// https://www.iana.org/domains/root/db/kosher.html +kosher + +// kpmg : KPMG International Cooperative (KPMG International Genossenschaft) +// https://www.iana.org/domains/root/db/kpmg.html +kpmg + +// kpn : Koninklijke KPN N.V. +// https://www.iana.org/domains/root/db/kpn.html +kpn + +// krd : KRG Department of Information Technology +// https://www.iana.org/domains/root/db/krd.html +krd + +// kred : KredTLD Pty Ltd +// https://www.iana.org/domains/root/db/kred.html +kred + +// kuokgroup : Kerry Trading Co. Limited +// https://www.iana.org/domains/root/db/kuokgroup.html +kuokgroup + +// kyoto : Academic Institution: Kyoto Jyoho Gakuen +// https://www.iana.org/domains/root/db/kyoto.html +kyoto + +// lacaixa : Fundación Bancaria Caixa d’Estalvis i Pensions de Barcelona, “la Caixa” +// https://www.iana.org/domains/root/db/lacaixa.html +lacaixa + +// lamborghini : Automobili Lamborghini S.p.A. +// https://www.iana.org/domains/root/db/lamborghini.html +lamborghini + +// lamer : The Estée Lauder Companies Inc. +// https://www.iana.org/domains/root/db/lamer.html +lamer + +// lancaster : LANCASTER +// https://www.iana.org/domains/root/db/lancaster.html +lancaster + +// land : Binky Moon, LLC +// https://www.iana.org/domains/root/db/land.html +land + +// landrover : Jaguar Land Rover Ltd +// https://www.iana.org/domains/root/db/landrover.html +landrover + +// lanxess : LANXESS Corporation +// https://www.iana.org/domains/root/db/lanxess.html +lanxess + +// lasalle : Jones Lang LaSalle Incorporated +// https://www.iana.org/domains/root/db/lasalle.html +lasalle + +// lat : XYZ.COM LLC +// https://www.iana.org/domains/root/db/lat.html +lat + +// latino : Dish DBS Corporation +// https://www.iana.org/domains/root/db/latino.html +latino + +// latrobe : La Trobe University +// https://www.iana.org/domains/root/db/latrobe.html +latrobe + +// law : Registry Services, LLC +// https://www.iana.org/domains/root/db/law.html +law + +// lawyer : Dog Beach, LLC +// https://www.iana.org/domains/root/db/lawyer.html +lawyer + +// lds : IRI Domain Management, LLC +// https://www.iana.org/domains/root/db/lds.html +lds + +// lease : Binky Moon, LLC +// https://www.iana.org/domains/root/db/lease.html +lease + +// leclerc : A.C.D. LEC Association des Centres Distributeurs Edouard Leclerc +// https://www.iana.org/domains/root/db/leclerc.html +leclerc + +// lefrak : LeFrak Organization, Inc. +// https://www.iana.org/domains/root/db/lefrak.html +lefrak + +// legal : Binky Moon, LLC +// https://www.iana.org/domains/root/db/legal.html +legal + +// lego : LEGO Juris A/S +// https://www.iana.org/domains/root/db/lego.html +lego + +// lexus : TOYOTA MOTOR CORPORATION +// https://www.iana.org/domains/root/db/lexus.html +lexus + +// lgbt : Identity Digital Limited +// https://www.iana.org/domains/root/db/lgbt.html +lgbt + +// lidl : Schwarz Domains und Services GmbH & Co. KG +// https://www.iana.org/domains/root/db/lidl.html +lidl + +// life : Binky Moon, LLC +// https://www.iana.org/domains/root/db/life.html +life + +// lifeinsurance : American Council of Life Insurers +// https://www.iana.org/domains/root/db/lifeinsurance.html +lifeinsurance + +// lifestyle : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/lifestyle.html +lifestyle + +// lighting : Binky Moon, LLC +// https://www.iana.org/domains/root/db/lighting.html +lighting + +// like : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/like.html +like + +// lilly : Eli Lilly and Company +// https://www.iana.org/domains/root/db/lilly.html +lilly + +// limited : Binky Moon, LLC +// https://www.iana.org/domains/root/db/limited.html +limited + +// limo : Binky Moon, LLC +// https://www.iana.org/domains/root/db/limo.html +limo + +// lincoln : Ford Motor Company +// https://www.iana.org/domains/root/db/lincoln.html +lincoln + +// link : Nova Registry Ltd +// https://www.iana.org/domains/root/db/link.html +link + +// live : Dog Beach, LLC +// https://www.iana.org/domains/root/db/live.html +live + +// living : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/living.html +living + +// llc : Identity Digital Limited +// https://www.iana.org/domains/root/db/llc.html +llc + +// llp : Intercap Registry Inc. +// https://www.iana.org/domains/root/db/llp.html +llp + +// loan : dot Loan Limited +// https://www.iana.org/domains/root/db/loan.html +loan + +// loans : Binky Moon, LLC +// https://www.iana.org/domains/root/db/loans.html +loans + +// locker : Orange Domains LLC +// https://www.iana.org/domains/root/db/locker.html +locker + +// locus : Locus Analytics LLC +// https://www.iana.org/domains/root/db/locus.html +locus + +// lol : XYZ.COM LLC +// https://www.iana.org/domains/root/db/lol.html +lol + +// london : Dot London Domains Limited +// https://www.iana.org/domains/root/db/london.html +london + +// lotte : Lotte Holdings Co., Ltd. +// https://www.iana.org/domains/root/db/lotte.html +lotte + +// lotto : Identity Digital Limited +// https://www.iana.org/domains/root/db/lotto.html +lotto + +// love : Waterford Limited +// https://www.iana.org/domains/root/db/love.html +love + +// lpl : LPL Holdings, Inc. +// https://www.iana.org/domains/root/db/lpl.html +lpl + +// lplfinancial : LPL Holdings, Inc. +// https://www.iana.org/domains/root/db/lplfinancial.html +lplfinancial + +// ltd : Binky Moon, LLC +// https://www.iana.org/domains/root/db/ltd.html +ltd + +// ltda : InterNetX, Corp +// https://www.iana.org/domains/root/db/ltda.html +ltda + +// lundbeck : H. Lundbeck A/S +// https://www.iana.org/domains/root/db/lundbeck.html +lundbeck + +// luxe : Registry Services, LLC +// https://www.iana.org/domains/root/db/luxe.html +luxe + +// luxury : Luxury Partners, LLC +// https://www.iana.org/domains/root/db/luxury.html +luxury + +// madrid : Comunidad de Madrid +// https://www.iana.org/domains/root/db/madrid.html +madrid + +// maif : Mutuelle Assurance Instituteur France (MAIF) +// https://www.iana.org/domains/root/db/maif.html +maif + +// maison : Binky Moon, LLC +// https://www.iana.org/domains/root/db/maison.html +maison + +// makeup : XYZ.COM LLC +// https://www.iana.org/domains/root/db/makeup.html +makeup + +// man : MAN Truck & Bus SE +// https://www.iana.org/domains/root/db/man.html +man + +// management : Binky Moon, LLC +// https://www.iana.org/domains/root/db/management.html +management + +// mango : PUNTO FA S.L. +// https://www.iana.org/domains/root/db/mango.html +mango + +// map : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/map.html +map + +// market : Dog Beach, LLC +// https://www.iana.org/domains/root/db/market.html +market + +// marketing : Binky Moon, LLC +// https://www.iana.org/domains/root/db/marketing.html +marketing + +// markets : Dog Beach, LLC +// https://www.iana.org/domains/root/db/markets.html +markets + +// marriott : Marriott Worldwide Corporation +// https://www.iana.org/domains/root/db/marriott.html +marriott + +// marshalls : The TJX Companies, Inc. +// https://www.iana.org/domains/root/db/marshalls.html +marshalls + +// mattel : Mattel IT Services, Inc. +// https://www.iana.org/domains/root/db/mattel.html +mattel + +// mba : Binky Moon, LLC +// https://www.iana.org/domains/root/db/mba.html +mba + +// mckinsey : McKinsey Holdings, Inc. +// https://www.iana.org/domains/root/db/mckinsey.html +mckinsey + +// med : Medistry LLC +// https://www.iana.org/domains/root/db/med.html +med + +// media : Binky Moon, LLC +// https://www.iana.org/domains/root/db/media.html +media + +// meet : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/meet.html +meet + +// melbourne : The Crown in right of the State of Victoria, represented by its Department of State Development, Business and Innovation +// https://www.iana.org/domains/root/db/melbourne.html +melbourne + +// meme : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/meme.html +meme + +// memorial : Dog Beach, LLC +// https://www.iana.org/domains/root/db/memorial.html +memorial + +// men : Exclusive Registry Limited +// https://www.iana.org/domains/root/db/men.html +men + +// menu : Dot Menu Registry, LLC +// https://www.iana.org/domains/root/db/menu.html +menu + +// merck : Merck Registry Holdings, Inc. +// https://www.iana.org/domains/root/db/merck.html +merck + +// merckmsd : MSD Registry Holdings, Inc. +// https://www.iana.org/domains/root/db/merckmsd.html +merckmsd + +// miami : Registry Services, LLC +// https://www.iana.org/domains/root/db/miami.html +miami + +// microsoft : Microsoft Corporation +// https://www.iana.org/domains/root/db/microsoft.html +microsoft + +// mini : Bayerische Motoren Werke Aktiengesellschaft +// https://www.iana.org/domains/root/db/mini.html +mini + +// mint : Intuit Administrative Services, Inc. +// https://www.iana.org/domains/root/db/mint.html +mint + +// mit : Massachusetts Institute of Technology +// https://www.iana.org/domains/root/db/mit.html +mit + +// mitsubishi : Mitsubishi Corporation +// https://www.iana.org/domains/root/db/mitsubishi.html +mitsubishi + +// mlb : MLB Advanced Media DH, LLC +// https://www.iana.org/domains/root/db/mlb.html +mlb + +// mls : The Canadian Real Estate Association +// https://www.iana.org/domains/root/db/mls.html +mls + +// mma : MMA IARD +// https://www.iana.org/domains/root/db/mma.html +mma + +// mobile : Dish DBS Corporation +// https://www.iana.org/domains/root/db/mobile.html +mobile + +// moda : Dog Beach, LLC +// https://www.iana.org/domains/root/db/moda.html +moda + +// moe : Interlink Systems Innovation Institute K.K. +// https://www.iana.org/domains/root/db/moe.html +moe + +// moi : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/moi.html +moi + +// mom : XYZ.COM LLC +// https://www.iana.org/domains/root/db/mom.html +mom + +// monash : Monash University +// https://www.iana.org/domains/root/db/monash.html +monash + +// money : Binky Moon, LLC +// https://www.iana.org/domains/root/db/money.html +money + +// monster : XYZ.COM LLC +// https://www.iana.org/domains/root/db/monster.html +monster + +// mormon : IRI Domain Management, LLC +// https://www.iana.org/domains/root/db/mormon.html +mormon + +// mortgage : Dog Beach, LLC +// https://www.iana.org/domains/root/db/mortgage.html +mortgage + +// moscow : Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID) +// https://www.iana.org/domains/root/db/moscow.html +moscow + +// moto : Motorola Trademark Holdings, LLC +// https://www.iana.org/domains/root/db/moto.html +moto + +// motorcycles : XYZ.COM LLC +// https://www.iana.org/domains/root/db/motorcycles.html +motorcycles + +// mov : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/mov.html +mov + +// movie : Binky Moon, LLC +// https://www.iana.org/domains/root/db/movie.html +movie + +// msd : MSD Registry Holdings, Inc. +// https://www.iana.org/domains/root/db/msd.html +msd + +// mtn : MTN Dubai Limited +// https://www.iana.org/domains/root/db/mtn.html +mtn + +// mtr : MTR Corporation Limited +// https://www.iana.org/domains/root/db/mtr.html +mtr + +// music : DotMusic Limited +// https://www.iana.org/domains/root/db/music.html +music + +// nab : National Australia Bank Limited +// https://www.iana.org/domains/root/db/nab.html +nab + +// nagoya : GMO Registry, Inc. +// https://www.iana.org/domains/root/db/nagoya.html +nagoya + +// navy : Dog Beach, LLC +// https://www.iana.org/domains/root/db/navy.html +navy + +// nba : NBA REGISTRY, LLC +// https://www.iana.org/domains/root/db/nba.html +nba + +// nec : NEC Corporation +// https://www.iana.org/domains/root/db/nec.html +nec + +// netbank : COMMONWEALTH BANK OF AUSTRALIA +// https://www.iana.org/domains/root/db/netbank.html +netbank + +// netflix : Netflix, Inc. +// https://www.iana.org/domains/root/db/netflix.html +netflix + +// network : Binky Moon, LLC +// https://www.iana.org/domains/root/db/network.html +network + +// neustar : NeuStar, Inc. +// https://www.iana.org/domains/root/db/neustar.html +neustar + +// new : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/new.html +new + +// news : Dog Beach, LLC +// https://www.iana.org/domains/root/db/news.html +news + +// next : Next plc +// https://www.iana.org/domains/root/db/next.html +next + +// nextdirect : Next plc +// https://www.iana.org/domains/root/db/nextdirect.html +nextdirect + +// nexus : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/nexus.html +nexus + +// nfl : NFL Reg Ops LLC +// https://www.iana.org/domains/root/db/nfl.html +nfl + +// ngo : Public Interest Registry +// https://www.iana.org/domains/root/db/ngo.html +ngo + +// nhk : Japan Broadcasting Corporation (NHK) +// https://www.iana.org/domains/root/db/nhk.html +nhk + +// nico : DWANGO Co., Ltd. +// https://www.iana.org/domains/root/db/nico.html +nico + +// nike : NIKE, Inc. +// https://www.iana.org/domains/root/db/nike.html +nike + +// nikon : NIKON CORPORATION +// https://www.iana.org/domains/root/db/nikon.html +nikon + +// ninja : Dog Beach, LLC +// https://www.iana.org/domains/root/db/ninja.html +ninja + +// nissan : NISSAN MOTOR CO., LTD. +// https://www.iana.org/domains/root/db/nissan.html +nissan + +// nissay : Nippon Life Insurance Company +// https://www.iana.org/domains/root/db/nissay.html +nissay + +// nokia : Nokia Corporation +// https://www.iana.org/domains/root/db/nokia.html +nokia + +// norton : Gen Digital Inc. +// https://www.iana.org/domains/root/db/norton.html +norton + +// now : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/now.html +now + +// nowruz +// https://www.iana.org/domains/root/db/nowruz.html +nowruz + +// nowtv : Starbucks (HK) Limited +// https://www.iana.org/domains/root/db/nowtv.html +nowtv + +// nra : NRA Holdings Company, INC. +// https://www.iana.org/domains/root/db/nra.html +nra + +// nrw : Minds + Machines GmbH +// https://www.iana.org/domains/root/db/nrw.html +nrw + +// ntt : NIPPON TELEGRAPH AND TELEPHONE CORPORATION +// https://www.iana.org/domains/root/db/ntt.html +ntt + +// nyc : The City of New York by and through the New York City Department of Information Technology & Telecommunications +// https://www.iana.org/domains/root/db/nyc.html +nyc + +// obi : OBI Group Holding SE & Co. KGaA +// https://www.iana.org/domains/root/db/obi.html +obi + +// observer : Fegistry, LLC +// https://www.iana.org/domains/root/db/observer.html +observer + +// office : Microsoft Corporation +// https://www.iana.org/domains/root/db/office.html +office + +// okinawa : BRregistry, Inc. +// https://www.iana.org/domains/root/db/okinawa.html +okinawa + +// olayan : Competrol (Luxembourg) Sarl +// https://www.iana.org/domains/root/db/olayan.html +olayan + +// olayangroup : Competrol (Luxembourg) Sarl +// https://www.iana.org/domains/root/db/olayangroup.html +olayangroup + +// ollo : Dish DBS Corporation +// https://www.iana.org/domains/root/db/ollo.html +ollo + +// omega : The Swatch Group Ltd +// https://www.iana.org/domains/root/db/omega.html +omega + +// one : One.com A/S +// https://www.iana.org/domains/root/db/one.html +one + +// ong : Public Interest Registry +// https://www.iana.org/domains/root/db/ong.html +ong + +// onl : iRegistry GmbH +// https://www.iana.org/domains/root/db/onl.html +onl + +// online : Radix Technologies Inc SEZC +// https://www.iana.org/domains/root/db/online.html +online + +// ooo : INFIBEAM AVENUES LIMITED +// https://www.iana.org/domains/root/db/ooo.html +ooo + +// open : American Express Travel Related Services Company, Inc. +// https://www.iana.org/domains/root/db/open.html +open + +// oracle : Oracle Corporation +// https://www.iana.org/domains/root/db/oracle.html +oracle + +// orange : Orange Brand Services Limited +// https://www.iana.org/domains/root/db/orange.html +orange + +// organic : Identity Digital Limited +// https://www.iana.org/domains/root/db/organic.html +organic + +// origins : The Estée Lauder Companies Inc. +// https://www.iana.org/domains/root/db/origins.html +origins + +// osaka : Osaka Registry Co., Ltd. +// https://www.iana.org/domains/root/db/osaka.html +osaka + +// otsuka : Otsuka Holdings Co., Ltd. +// https://www.iana.org/domains/root/db/otsuka.html +otsuka + +// ott : Dish DBS Corporation +// https://www.iana.org/domains/root/db/ott.html +ott + +// ovh : MédiaBC +// https://www.iana.org/domains/root/db/ovh.html +ovh + +// page : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/page.html +page + +// panasonic : Panasonic Holdings Corporation +// https://www.iana.org/domains/root/db/panasonic.html +panasonic + +// paris : City of Paris +// https://www.iana.org/domains/root/db/paris.html +paris + +// pars +// https://www.iana.org/domains/root/db/pars.html +pars + +// partners : Binky Moon, LLC +// https://www.iana.org/domains/root/db/partners.html +partners + +// parts : Binky Moon, LLC +// https://www.iana.org/domains/root/db/parts.html +parts + +// party : Blue Sky Registry Limited +// https://www.iana.org/domains/root/db/party.html +party + +// pay : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/pay.html +pay + +// pccw : PCCW Enterprises Limited +// https://www.iana.org/domains/root/db/pccw.html +pccw + +// pet : Identity Digital Limited +// https://www.iana.org/domains/root/db/pet.html +pet + +// pfizer : Pfizer Inc. +// https://www.iana.org/domains/root/db/pfizer.html +pfizer + +// pharmacy : National Association of Boards of Pharmacy +// https://www.iana.org/domains/root/db/pharmacy.html +pharmacy + +// phd : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/phd.html +phd + +// philips : Koninklijke Philips N.V. +// https://www.iana.org/domains/root/db/philips.html +philips + +// phone : Dish DBS Corporation +// https://www.iana.org/domains/root/db/phone.html +phone + +// photo : Registry Services, LLC +// https://www.iana.org/domains/root/db/photo.html +photo + +// photography : Binky Moon, LLC +// https://www.iana.org/domains/root/db/photography.html +photography + +// photos : Binky Moon, LLC +// https://www.iana.org/domains/root/db/photos.html +photos + +// physio : PhysBiz Pty Ltd +// https://www.iana.org/domains/root/db/physio.html +physio + +// pics : XYZ.COM LLC +// https://www.iana.org/domains/root/db/pics.html +pics + +// pictet : Banque Pictet & Cie SA +// https://www.iana.org/domains/root/db/pictet.html +pictet + +// pictures : Binky Moon, LLC +// https://www.iana.org/domains/root/db/pictures.html +pictures + +// pid : Top Level Spectrum, Inc. +// https://www.iana.org/domains/root/db/pid.html +pid + +// pin : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/pin.html +pin + +// ping : Ping Registry Provider, Inc. +// https://www.iana.org/domains/root/db/ping.html +ping + +// pink : Identity Digital Limited +// https://www.iana.org/domains/root/db/pink.html +pink + +// pioneer : Pioneer Corporation +// https://www.iana.org/domains/root/db/pioneer.html +pioneer + +// pizza : Binky Moon, LLC +// https://www.iana.org/domains/root/db/pizza.html +pizza + +// place : Binky Moon, LLC +// https://www.iana.org/domains/root/db/place.html +place + +// play : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/play.html +play + +// playstation : Sony Interactive Entertainment Inc. +// https://www.iana.org/domains/root/db/playstation.html +playstation + +// plumbing : Binky Moon, LLC +// https://www.iana.org/domains/root/db/plumbing.html +plumbing + +// plus : Binky Moon, LLC +// https://www.iana.org/domains/root/db/plus.html +plus + +// pnc : PNC Domain Co., LLC +// https://www.iana.org/domains/root/db/pnc.html +pnc + +// pohl : Deutsche Vermögensberatung Aktiengesellschaft DVAG +// https://www.iana.org/domains/root/db/pohl.html +pohl + +// poker : Identity Digital Limited +// https://www.iana.org/domains/root/db/poker.html +poker + +// politie : Politie Nederland +// https://www.iana.org/domains/root/db/politie.html +politie + +// porn : ICM Registry PN LLC +// https://www.iana.org/domains/root/db/porn.html +porn + +// pramerica : Prudential Financial, Inc. +// https://www.iana.org/domains/root/db/pramerica.html +pramerica + +// praxi : Praxi S.p.A. +// https://www.iana.org/domains/root/db/praxi.html +praxi + +// press : Radix Technologies Inc SEZC +// https://www.iana.org/domains/root/db/press.html +press + +// prime : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/prime.html +prime + +// prod : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/prod.html +prod + +// productions : Binky Moon, LLC +// https://www.iana.org/domains/root/db/productions.html +productions + +// prof : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/prof.html +prof + +// progressive : Progressive Casualty Insurance Company +// https://www.iana.org/domains/root/db/progressive.html +progressive + +// promo : Identity Digital Limited +// https://www.iana.org/domains/root/db/promo.html +promo + +// properties : Binky Moon, LLC +// https://www.iana.org/domains/root/db/properties.html +properties + +// property : Digital Property Infrastructure Limited +// https://www.iana.org/domains/root/db/property.html +property + +// protection : XYZ.COM LLC +// https://www.iana.org/domains/root/db/protection.html +protection + +// pru : Prudential Financial, Inc. +// https://www.iana.org/domains/root/db/pru.html +pru + +// prudential : Prudential Financial, Inc. +// https://www.iana.org/domains/root/db/prudential.html +prudential + +// pub : Dog Beach, LLC +// https://www.iana.org/domains/root/db/pub.html +pub + +// pwc : PricewaterhouseCoopers LLP +// https://www.iana.org/domains/root/db/pwc.html +pwc + +// qpon : dotQPON LLC +// https://www.iana.org/domains/root/db/qpon.html +qpon + +// quebec : PointQuébec Inc +// https://www.iana.org/domains/root/db/quebec.html +quebec + +// quest : XYZ.COM LLC +// https://www.iana.org/domains/root/db/quest.html +quest + +// racing : Premier Registry Limited +// https://www.iana.org/domains/root/db/racing.html +racing + +// radio : European Broadcasting Union (EBU) +// https://www.iana.org/domains/root/db/radio.html +radio + +// read : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/read.html +read + +// realestate : dotRealEstate LLC +// https://www.iana.org/domains/root/db/realestate.html +realestate + +// realtor : Real Estate Domains LLC +// https://www.iana.org/domains/root/db/realtor.html +realtor + +// realty : Waterford Limited +// https://www.iana.org/domains/root/db/realty.html +realty + +// recipes : Binky Moon, LLC +// https://www.iana.org/domains/root/db/recipes.html +recipes + +// red : Identity Digital Limited +// https://www.iana.org/domains/root/db/red.html +red + +// redstone : Redstone Haute Couture Co., Ltd. +// https://www.iana.org/domains/root/db/redstone.html +redstone + +// redumbrella : Travelers TLD, LLC +// https://www.iana.org/domains/root/db/redumbrella.html +redumbrella + +// rehab : Dog Beach, LLC +// https://www.iana.org/domains/root/db/rehab.html +rehab + +// reise : Binky Moon, LLC +// https://www.iana.org/domains/root/db/reise.html +reise + +// reisen : Binky Moon, LLC +// https://www.iana.org/domains/root/db/reisen.html +reisen + +// reit : National Association of Real Estate Investment Trusts, Inc. +// https://www.iana.org/domains/root/db/reit.html +reit + +// reliance : Reliance Industries Limited +// https://www.iana.org/domains/root/db/reliance.html +reliance + +// ren : ZDNS International Limited +// https://www.iana.org/domains/root/db/ren.html +ren + +// rent : XYZ.COM LLC +// https://www.iana.org/domains/root/db/rent.html +rent + +// rentals : Binky Moon, LLC +// https://www.iana.org/domains/root/db/rentals.html +rentals + +// repair : Binky Moon, LLC +// https://www.iana.org/domains/root/db/repair.html +repair + +// report : Binky Moon, LLC +// https://www.iana.org/domains/root/db/report.html +report + +// republican : Dog Beach, LLC +// https://www.iana.org/domains/root/db/republican.html +republican + +// rest : Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable +// https://www.iana.org/domains/root/db/rest.html +rest + +// restaurant : Binky Moon, LLC +// https://www.iana.org/domains/root/db/restaurant.html +restaurant + +// review : dot Review Limited +// https://www.iana.org/domains/root/db/review.html +review + +// reviews : Dog Beach, LLC +// https://www.iana.org/domains/root/db/reviews.html +reviews + +// rexroth : Robert Bosch GMBH +// https://www.iana.org/domains/root/db/rexroth.html +rexroth + +// rich : iRegistry GmbH +// https://www.iana.org/domains/root/db/rich.html +rich + +// richardli : Pacific Century Asset Management (HK) Limited +// https://www.iana.org/domains/root/db/richardli.html +richardli + +// ricoh : Ricoh Company, Ltd. +// https://www.iana.org/domains/root/db/ricoh.html +ricoh + +// ril : Reliance Industries Limited +// https://www.iana.org/domains/root/db/ril.html +ril + +// rio : Empresa Municipal de Informática SA - IPLANRIO +// https://www.iana.org/domains/root/db/rio.html +rio + +// rip : Dog Beach, LLC +// https://www.iana.org/domains/root/db/rip.html +rip + +// rocks : Dog Beach, LLC +// https://www.iana.org/domains/root/db/rocks.html +rocks + +// rodeo : Registry Services, LLC +// https://www.iana.org/domains/root/db/rodeo.html +rodeo + +// rogers : Rogers Communications Canada Inc. +// https://www.iana.org/domains/root/db/rogers.html +rogers + +// room : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/room.html +room + +// rsvp : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/rsvp.html +rsvp + +// rugby : World Rugby Strategic Developments Limited +// https://www.iana.org/domains/root/db/rugby.html +rugby + +// ruhr : dotSaarland GmbH +// https://www.iana.org/domains/root/db/ruhr.html +ruhr + +// run : Binky Moon, LLC +// https://www.iana.org/domains/root/db/run.html +run + +// rwe : RWE AG +// https://www.iana.org/domains/root/db/rwe.html +rwe + +// ryukyu : BRregistry, Inc. +// https://www.iana.org/domains/root/db/ryukyu.html +ryukyu + +// saarland : dotSaarland GmbH +// https://www.iana.org/domains/root/db/saarland.html +saarland + +// safe : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/safe.html +safe + +// safety : Safety Registry Services, LLC. +// https://www.iana.org/domains/root/db/safety.html +safety + +// sakura : SAKURA Internet Inc. +// https://www.iana.org/domains/root/db/sakura.html +sakura + +// sale : Dog Beach, LLC +// https://www.iana.org/domains/root/db/sale.html +sale + +// salon : Binky Moon, LLC +// https://www.iana.org/domains/root/db/salon.html +salon + +// samsclub : Wal-Mart Stores, Inc. +// https://www.iana.org/domains/root/db/samsclub.html +samsclub + +// samsung : SAMSUNG SDS CO., LTD +// https://www.iana.org/domains/root/db/samsung.html +samsung + +// sandvik : Sandvik AB +// https://www.iana.org/domains/root/db/sandvik.html +sandvik + +// sandvikcoromant : Sandvik AB +// https://www.iana.org/domains/root/db/sandvikcoromant.html +sandvikcoromant + +// sanofi : Sanofi +// https://www.iana.org/domains/root/db/sanofi.html +sanofi + +// sap : SAP AG +// https://www.iana.org/domains/root/db/sap.html +sap + +// sarl : Binky Moon, LLC +// https://www.iana.org/domains/root/db/sarl.html +sarl + +// sas : Research IP LLC +// https://www.iana.org/domains/root/db/sas.html +sas + +// save : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/save.html +save + +// saxo : Saxo Bank A/S +// https://www.iana.org/domains/root/db/saxo.html +saxo + +// sbi : STATE BANK OF INDIA +// https://www.iana.org/domains/root/db/sbi.html +sbi + +// sbs : ShortDot SA +// https://www.iana.org/domains/root/db/sbs.html +sbs + +// scb : The Siam Commercial Bank Public Company Limited ("SCB") +// https://www.iana.org/domains/root/db/scb.html +scb + +// schaeffler : Schaeffler Technologies AG & Co. KG +// https://www.iana.org/domains/root/db/schaeffler.html +schaeffler + +// schmidt : SCHMIDT GROUPE S.A.S. +// https://www.iana.org/domains/root/db/schmidt.html +schmidt + +// scholarships : Scholarships.com, LLC +// https://www.iana.org/domains/root/db/scholarships.html +scholarships + +// school : Binky Moon, LLC +// https://www.iana.org/domains/root/db/school.html +school + +// schule : Binky Moon, LLC +// https://www.iana.org/domains/root/db/schule.html +schule + +// schwarz : Schwarz Domains und Services GmbH & Co. KG +// https://www.iana.org/domains/root/db/schwarz.html +schwarz + +// science : dot Science Limited +// https://www.iana.org/domains/root/db/science.html +science + +// scot : Dot Scot Registry Limited +// https://www.iana.org/domains/root/db/scot.html +scot + +// search : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/search.html +search + +// seat : SEAT, S.A. (Sociedad Unipersonal) +// https://www.iana.org/domains/root/db/seat.html +seat + +// secure : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/secure.html +secure + +// security : XYZ.COM LLC +// https://www.iana.org/domains/root/db/security.html +security + +// seek : Seek Limited +// https://www.iana.org/domains/root/db/seek.html +seek + +// select : Registry Services, LLC +// https://www.iana.org/domains/root/db/select.html +select + +// sener : Sener Ingeniería y Sistemas, S.A. +// https://www.iana.org/domains/root/db/sener.html +sener + +// services : Binky Moon, LLC +// https://www.iana.org/domains/root/db/services.html +services + +// seven : Seven West Media Ltd +// https://www.iana.org/domains/root/db/seven.html +seven + +// sew : SEW-EURODRIVE GmbH & Co KG +// https://www.iana.org/domains/root/db/sew.html +sew + +// sex : ICM Registry SX LLC +// https://www.iana.org/domains/root/db/sex.html +sex + +// sexy : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/sexy.html +sexy + +// sfr : Societe Francaise du Radiotelephone - SFR +// https://www.iana.org/domains/root/db/sfr.html +sfr + +// shangrila : Shangri‐La International Hotel Management Limited +// https://www.iana.org/domains/root/db/shangrila.html +shangrila + +// sharp : Sharp Corporation +// https://www.iana.org/domains/root/db/sharp.html +sharp + +// shell : Shell Information Technology International Inc +// https://www.iana.org/domains/root/db/shell.html +shell + +// shia +// https://www.iana.org/domains/root/db/shia.html +shia + +// shiksha : Identity Digital Limited +// https://www.iana.org/domains/root/db/shiksha.html +shiksha + +// shoes : Binky Moon, LLC +// https://www.iana.org/domains/root/db/shoes.html +shoes + +// shop : GMO Registry, Inc. +// https://www.iana.org/domains/root/db/shop.html +shop + +// shopping : Binky Moon, LLC +// https://www.iana.org/domains/root/db/shopping.html +shopping + +// shouji : Beijing Qihu Keji Co., Ltd. +// https://www.iana.org/domains/root/db/shouji.html +shouji + +// show : Binky Moon, LLC +// https://www.iana.org/domains/root/db/show.html +show + +// silk : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/silk.html +silk + +// sina : Sina Corporation +// https://www.iana.org/domains/root/db/sina.html +sina + +// singles : Binky Moon, LLC +// https://www.iana.org/domains/root/db/singles.html +singles + +// site : Radix Technologies Inc SEZC +// https://www.iana.org/domains/root/db/site.html +site + +// ski : Identity Digital Limited +// https://www.iana.org/domains/root/db/ski.html +ski + +// skin : XYZ.COM LLC +// https://www.iana.org/domains/root/db/skin.html +skin + +// sky : Sky UK Limited +// https://www.iana.org/domains/root/db/sky.html +sky + +// skype : Microsoft Corporation +// https://www.iana.org/domains/root/db/skype.html +skype + +// sling : DISH Technologies L.L.C. +// https://www.iana.org/domains/root/db/sling.html +sling + +// smart : Smart Communications, Inc. (SMART) +// https://www.iana.org/domains/root/db/smart.html +smart + +// smile : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/smile.html +smile + +// sncf : Société Nationale SNCF +// https://www.iana.org/domains/root/db/sncf.html +sncf + +// soccer : Binky Moon, LLC +// https://www.iana.org/domains/root/db/soccer.html +soccer + +// social : Dog Beach, LLC +// https://www.iana.org/domains/root/db/social.html +social + +// softbank : SoftBank Group Corp. +// https://www.iana.org/domains/root/db/softbank.html +softbank + +// software : Dog Beach, LLC +// https://www.iana.org/domains/root/db/software.html +software + +// sohu : Sohu.com Limited +// https://www.iana.org/domains/root/db/sohu.html +sohu + +// solar : Binky Moon, LLC +// https://www.iana.org/domains/root/db/solar.html +solar + +// solutions : Binky Moon, LLC +// https://www.iana.org/domains/root/db/solutions.html +solutions + +// song : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/song.html +song + +// sony : Sony Corporation +// https://www.iana.org/domains/root/db/sony.html +sony + +// soy : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/soy.html +soy + +// spa : Asia Spa and Wellness Promotion Council Limited +// https://www.iana.org/domains/root/db/spa.html +spa + +// space : Radix Technologies Inc SEZC +// https://www.iana.org/domains/root/db/space.html +space + +// sport : SportAccord +// https://www.iana.org/domains/root/db/sport.html +sport + +// spot : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/spot.html +spot + +// srl : InterNetX, Corp +// https://www.iana.org/domains/root/db/srl.html +srl + +// stada : STADA Arzneimittel AG +// https://www.iana.org/domains/root/db/stada.html +stada + +// staples : Staples, Inc. +// https://www.iana.org/domains/root/db/staples.html +staples + +// star : Star India Private Limited +// https://www.iana.org/domains/root/db/star.html +star + +// statebank : STATE BANK OF INDIA +// https://www.iana.org/domains/root/db/statebank.html +statebank + +// statefarm : State Farm Mutual Automobile Insurance Company +// https://www.iana.org/domains/root/db/statefarm.html +statefarm + +// stc : Saudi Telecom Company +// https://www.iana.org/domains/root/db/stc.html +stc + +// stcgroup : Saudi Telecom Company +// https://www.iana.org/domains/root/db/stcgroup.html +stcgroup + +// stockholm : Stockholms kommun +// https://www.iana.org/domains/root/db/stockholm.html +stockholm + +// storage : XYZ.COM LLC +// https://www.iana.org/domains/root/db/storage.html +storage + +// store : Radix Technologies Inc SEZC +// https://www.iana.org/domains/root/db/store.html +store + +// stream : dot Stream Limited +// https://www.iana.org/domains/root/db/stream.html +stream + +// studio : Dog Beach, LLC +// https://www.iana.org/domains/root/db/studio.html +studio + +// study : Registry Services, LLC +// https://www.iana.org/domains/root/db/study.html +study + +// style : Binky Moon, LLC +// https://www.iana.org/domains/root/db/style.html +style + +// sucks : Vox Populi Registry Ltd. +// https://www.iana.org/domains/root/db/sucks.html +sucks + +// supplies : Binky Moon, LLC +// https://www.iana.org/domains/root/db/supplies.html +supplies + +// supply : Binky Moon, LLC +// https://www.iana.org/domains/root/db/supply.html +supply + +// support : Binky Moon, LLC +// https://www.iana.org/domains/root/db/support.html +support + +// surf : Registry Services, LLC +// https://www.iana.org/domains/root/db/surf.html +surf + +// surgery : Binky Moon, LLC +// https://www.iana.org/domains/root/db/surgery.html +surgery + +// suzuki : SUZUKI MOTOR CORPORATION +// https://www.iana.org/domains/root/db/suzuki.html +suzuki + +// swatch : The Swatch Group Ltd +// https://www.iana.org/domains/root/db/swatch.html +swatch + +// swiss : Swiss Confederation +// https://www.iana.org/domains/root/db/swiss.html +swiss + +// sydney : State of New South Wales, Department of Premier and Cabinet +// https://www.iana.org/domains/root/db/sydney.html +sydney + +// systems : Binky Moon, LLC +// https://www.iana.org/domains/root/db/systems.html +systems + +// tab : Tabcorp Holdings Limited +// https://www.iana.org/domains/root/db/tab.html +tab + +// taipei : Taipei City Government +// https://www.iana.org/domains/root/db/taipei.html +taipei + +// talk : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/talk.html +talk + +// taobao : Alibaba Group Holding Limited +// https://www.iana.org/domains/root/db/taobao.html +taobao + +// target : Target Domain Holdings, LLC +// https://www.iana.org/domains/root/db/target.html +target + +// tatamotors : Tata Motors Ltd +// https://www.iana.org/domains/root/db/tatamotors.html +tatamotors + +// tatar : Limited Liability Company "Coordination Center of Regional Domain of Tatarstan Republic" +// https://www.iana.org/domains/root/db/tatar.html +tatar + +// tattoo : Registry Services, LLC +// https://www.iana.org/domains/root/db/tattoo.html +tattoo + +// tax : Binky Moon, LLC +// https://www.iana.org/domains/root/db/tax.html +tax + +// taxi : Binky Moon, LLC +// https://www.iana.org/domains/root/db/taxi.html +taxi + +// tci +// https://www.iana.org/domains/root/db/tci.html +tci + +// tdk : TDK Corporation +// https://www.iana.org/domains/root/db/tdk.html +tdk + +// team : Binky Moon, LLC +// https://www.iana.org/domains/root/db/team.html +team + +// tech : Radix Technologies Inc SEZC +// https://www.iana.org/domains/root/db/tech.html +tech + +// technology : Binky Moon, LLC +// https://www.iana.org/domains/root/db/technology.html +technology + +// temasek : Temasek Holdings (Private) Limited +// https://www.iana.org/domains/root/db/temasek.html +temasek + +// tennis : Binky Moon, LLC +// https://www.iana.org/domains/root/db/tennis.html +tennis + +// teva : Teva Pharmaceutical Industries Limited +// https://www.iana.org/domains/root/db/teva.html +teva + +// thd : Home Depot Product Authority, LLC +// https://www.iana.org/domains/root/db/thd.html +thd + +// theater : Binky Moon, LLC +// https://www.iana.org/domains/root/db/theater.html +theater + +// theatre : XYZ.COM LLC +// https://www.iana.org/domains/root/db/theatre.html +theatre + +// tiaa : Teachers Insurance and Annuity Association of America +// https://www.iana.org/domains/root/db/tiaa.html +tiaa + +// tickets : XYZ.COM LLC +// https://www.iana.org/domains/root/db/tickets.html +tickets + +// tienda : Binky Moon, LLC +// https://www.iana.org/domains/root/db/tienda.html +tienda + +// tips : Binky Moon, LLC +// https://www.iana.org/domains/root/db/tips.html +tips + +// tires : Binky Moon, LLC +// https://www.iana.org/domains/root/db/tires.html +tires + +// tirol : punkt Tirol GmbH +// https://www.iana.org/domains/root/db/tirol.html +tirol + +// tjmaxx : The TJX Companies, Inc. +// https://www.iana.org/domains/root/db/tjmaxx.html +tjmaxx + +// tjx : The TJX Companies, Inc. +// https://www.iana.org/domains/root/db/tjx.html +tjx + +// tkmaxx : The TJX Companies, Inc. +// https://www.iana.org/domains/root/db/tkmaxx.html +tkmaxx + +// tmall : Alibaba Group Holding Limited +// https://www.iana.org/domains/root/db/tmall.html +tmall + +// today : Binky Moon, LLC +// https://www.iana.org/domains/root/db/today.html +today + +// tokyo : GMO Registry, Inc. +// https://www.iana.org/domains/root/db/tokyo.html +tokyo + +// tools : Binky Moon, LLC +// https://www.iana.org/domains/root/db/tools.html +tools + +// top : .TOP Registry +// https://www.iana.org/domains/root/db/top.html +top + +// toray : Toray Industries, Inc. +// https://www.iana.org/domains/root/db/toray.html +toray + +// toshiba : TOSHIBA Corporation +// https://www.iana.org/domains/root/db/toshiba.html +toshiba + +// total : TotalEnergies SE +// https://www.iana.org/domains/root/db/total.html +total + +// tours : Binky Moon, LLC +// https://www.iana.org/domains/root/db/tours.html +tours + +// town : Binky Moon, LLC +// https://www.iana.org/domains/root/db/town.html +town + +// toyota : TOYOTA MOTOR CORPORATION +// https://www.iana.org/domains/root/db/toyota.html +toyota + +// toys : Binky Moon, LLC +// https://www.iana.org/domains/root/db/toys.html +toys + +// trade : Elite Registry Limited +// https://www.iana.org/domains/root/db/trade.html +trade + +// trading : Dog Beach, LLC +// https://www.iana.org/domains/root/db/trading.html +trading + +// training : Binky Moon, LLC +// https://www.iana.org/domains/root/db/training.html +training + +// travel : Dog Beach, LLC +// https://www.iana.org/domains/root/db/travel.html +travel + +// travelers : Travelers TLD, LLC +// https://www.iana.org/domains/root/db/travelers.html +travelers + +// travelersinsurance : Travelers TLD, LLC +// https://www.iana.org/domains/root/db/travelersinsurance.html +travelersinsurance + +// trust : Internet Naming Company LLC +// https://www.iana.org/domains/root/db/trust.html +trust + +// trv : Travelers TLD, LLC +// https://www.iana.org/domains/root/db/trv.html +trv + +// tube : Latin American Telecom LLC +// https://www.iana.org/domains/root/db/tube.html +tube + +// tui : TUI AG +// https://www.iana.org/domains/root/db/tui.html +tui + +// tunes : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/tunes.html +tunes + +// tushu : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/tushu.html +tushu + +// tvs : T V SUNDRAM IYENGAR & SONS LIMITED +// https://www.iana.org/domains/root/db/tvs.html +tvs + +// ubank : National Australia Bank Limited +// https://www.iana.org/domains/root/db/ubank.html +ubank + +// ubs : UBS AG +// https://www.iana.org/domains/root/db/ubs.html +ubs + +// unicom : China United Network Communications Corporation Limited +// https://www.iana.org/domains/root/db/unicom.html +unicom + +// university : Binky Moon, LLC +// https://www.iana.org/domains/root/db/university.html +university + +// uno : Radix Technologies Inc SEZC +// https://www.iana.org/domains/root/db/uno.html +uno + +// uol : UBN INTERNET LTDA. +// https://www.iana.org/domains/root/db/uol.html +uol + +// ups : UPS Market Driver, Inc. +// https://www.iana.org/domains/root/db/ups.html +ups + +// vacations : Binky Moon, LLC +// https://www.iana.org/domains/root/db/vacations.html +vacations + +// vana : D3 Registry LLC +// https://www.iana.org/domains/root/db/vana.html +vana + +// vanguard : The Vanguard Group, Inc. +// https://www.iana.org/domains/root/db/vanguard.html +vanguard + +// vegas : Dot Vegas, Inc. +// https://www.iana.org/domains/root/db/vegas.html +vegas + +// ventures : Binky Moon, LLC +// https://www.iana.org/domains/root/db/ventures.html +ventures + +// verisign : VeriSign, Inc. +// https://www.iana.org/domains/root/db/verisign.html +verisign + +// versicherung : tldbox GmbH +// https://www.iana.org/domains/root/db/versicherung.html +versicherung + +// vet : Dog Beach, LLC +// https://www.iana.org/domains/root/db/vet.html +vet + +// viajes : Binky Moon, LLC +// https://www.iana.org/domains/root/db/viajes.html +viajes + +// video : Dog Beach, LLC +// https://www.iana.org/domains/root/db/video.html +video + +// vig : VIENNA INSURANCE GROUP AG Wiener Versicherung Gruppe +// https://www.iana.org/domains/root/db/vig.html +vig + +// viking : Viking River Cruises (Bermuda) Ltd. +// https://www.iana.org/domains/root/db/viking.html +viking + +// villas : Binky Moon, LLC +// https://www.iana.org/domains/root/db/villas.html +villas + +// vin : Binky Moon, LLC +// https://www.iana.org/domains/root/db/vin.html +vin + +// vip : Registry Services, LLC +// https://www.iana.org/domains/root/db/vip.html +vip + +// virgin : Virgin Enterprises Limited +// https://www.iana.org/domains/root/db/virgin.html +virgin + +// visa : Visa Worldwide Pte. Limited +// https://www.iana.org/domains/root/db/visa.html +visa + +// vision : Binky Moon, LLC +// https://www.iana.org/domains/root/db/vision.html +vision + +// viva : Saudi Telecom Company +// https://www.iana.org/domains/root/db/viva.html +viva + +// vivo : Telefonica Brasil S.A. +// https://www.iana.org/domains/root/db/vivo.html +vivo + +// vlaanderen : DNS.be vzw +// https://www.iana.org/domains/root/db/vlaanderen.html +vlaanderen + +// vodka : Registry Services, LLC +// https://www.iana.org/domains/root/db/vodka.html +vodka + +// volvo : Volvo Holding Sverige Aktiebolag +// https://www.iana.org/domains/root/db/volvo.html +volvo + +// vote : Monolith Registry LLC +// https://www.iana.org/domains/root/db/vote.html +vote + +// voting : Valuetainment Corp. +// https://www.iana.org/domains/root/db/voting.html +voting + +// voto : Monolith Registry LLC +// https://www.iana.org/domains/root/db/voto.html +voto + +// voyage : Binky Moon, LLC +// https://www.iana.org/domains/root/db/voyage.html +voyage + +// wales : Nominet UK +// https://www.iana.org/domains/root/db/wales.html +wales + +// walmart : Wal-Mart Stores, Inc. +// https://www.iana.org/domains/root/db/walmart.html +walmart + +// walter : Sandvik AB +// https://www.iana.org/domains/root/db/walter.html +walter + +// wang : Zodiac Wang Limited +// https://www.iana.org/domains/root/db/wang.html +wang + +// wanggou : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/wanggou.html +wanggou + +// watch : Binky Moon, LLC +// https://www.iana.org/domains/root/db/watch.html +watch + +// watches : Identity Digital Limited +// https://www.iana.org/domains/root/db/watches.html +watches + +// weather : International Business Machines Corporation +// https://www.iana.org/domains/root/db/weather.html +weather + +// weatherchannel : International Business Machines Corporation +// https://www.iana.org/domains/root/db/weatherchannel.html +weatherchannel + +// webcam : dot Webcam Limited +// https://www.iana.org/domains/root/db/webcam.html +webcam + +// weber : Saint-Gobain Weber SA +// https://www.iana.org/domains/root/db/weber.html +weber + +// website : Radix Technologies Inc SEZC +// https://www.iana.org/domains/root/db/website.html +website + +// wed +// https://www.iana.org/domains/root/db/wed.html +wed + +// wedding : Registry Services, LLC +// https://www.iana.org/domains/root/db/wedding.html +wedding + +// weibo : Sina Corporation +// https://www.iana.org/domains/root/db/weibo.html +weibo + +// weir : Weir Group IP Limited +// https://www.iana.org/domains/root/db/weir.html +weir + +// whoswho : Who's Who Registry +// https://www.iana.org/domains/root/db/whoswho.html +whoswho + +// wien : punkt.wien GmbH +// https://www.iana.org/domains/root/db/wien.html +wien + +// wiki : Registry Services, LLC +// https://www.iana.org/domains/root/db/wiki.html +wiki + +// williamhill : William Hill Organization Limited +// https://www.iana.org/domains/root/db/williamhill.html +williamhill + +// win : First Registry Limited +// https://www.iana.org/domains/root/db/win.html +win + +// windows : Microsoft Corporation +// https://www.iana.org/domains/root/db/windows.html +windows + +// wine : Binky Moon, LLC +// https://www.iana.org/domains/root/db/wine.html +wine + +// winners : The TJX Companies, Inc. +// https://www.iana.org/domains/root/db/winners.html +winners + +// wme : William Morris Endeavor Entertainment, LLC +// https://www.iana.org/domains/root/db/wme.html +wme + +// wolterskluwer : Wolters Kluwer N.V. +// https://www.iana.org/domains/root/db/wolterskluwer.html +wolterskluwer + +// woodside : Woodside Petroleum Limited +// https://www.iana.org/domains/root/db/woodside.html +woodside + +// work : Registry Services, LLC +// https://www.iana.org/domains/root/db/work.html +work + +// works : Binky Moon, LLC +// https://www.iana.org/domains/root/db/works.html +works + +// world : Binky Moon, LLC +// https://www.iana.org/domains/root/db/world.html +world + +// wow : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/wow.html +wow + +// wtc : World Trade Centers Association, Inc. +// https://www.iana.org/domains/root/db/wtc.html +wtc + +// wtf : Binky Moon, LLC +// https://www.iana.org/domains/root/db/wtf.html +wtf + +// xbox : Microsoft Corporation +// https://www.iana.org/domains/root/db/xbox.html +xbox + +// xerox : Xerox DNHC LLC +// https://www.iana.org/domains/root/db/xerox.html +xerox + +// xihuan : Beijing Qihu Keji Co., Ltd. +// https://www.iana.org/domains/root/db/xihuan.html +xihuan + +// xin : Elegant Leader Limited +// https://www.iana.org/domains/root/db/xin.html +xin + +// xn--11b4c3d : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--11b4c3d.html +कॉम + +// xn--1ck2e1b : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--1ck2e1b.html +セール + +// xn--1qqw23a : Guangzhou YU Wei Information Technology Co., Ltd. +// https://www.iana.org/domains/root/db/xn--1qqw23a.html +佛山 + +// xn--30rr7y : Excellent First Limited +// https://www.iana.org/domains/root/db/xn--30rr7y.html +慈善 + +// xn--3bst00m : Eagle Horizon Limited +// https://www.iana.org/domains/root/db/xn--3bst00m.html +集团 + +// xn--3ds443g : Beijing TLD Registry Technology Limited +// https://www.iana.org/domains/root/db/xn--3ds443g.html +在线 + +// xn--3pxu8k : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--3pxu8k.html +点看 + +// xn--42c2d9a : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--42c2d9a.html +คอม + +// xn--45q11c : Zodiac Gemini Ltd +// https://www.iana.org/domains/root/db/xn--45q11c.html +八卦 + +// xn--4gbrim : Helium TLDs Ltd +// https://www.iana.org/domains/root/db/xn--4gbrim.html +موقع + +// xn--55qw42g : China Organizational Name Administration Center +// https://www.iana.org/domains/root/db/xn--55qw42g.html +公益 + +// xn--55qx5d : China Internet Network Information Center (CNNIC) +// https://www.iana.org/domains/root/db/xn--55qx5d.html +公司 + +// xn--5su34j936bgsg : Shangri‐La International Hotel Management Limited +// https://www.iana.org/domains/root/db/xn--5su34j936bgsg.html +香格里拉 + +// xn--5tzm5g : Global Website TLD Asia Limited +// https://www.iana.org/domains/root/db/xn--5tzm5g.html +网站 + +// xn--6frz82g : Identity Digital Limited +// https://www.iana.org/domains/root/db/xn--6frz82g.html +移动 + +// xn--6qq986b3xl : Tycoon Treasure Limited +// https://www.iana.org/domains/root/db/xn--6qq986b3xl.html +我爱你 + +// xn--80adxhks : Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID) +// https://www.iana.org/domains/root/db/xn--80adxhks.html +москва + +// xn--80aqecdr1a : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) +// https://www.iana.org/domains/root/db/xn--80aqecdr1a.html +католик + +// xn--80asehdb : CORE Association +// https://www.iana.org/domains/root/db/xn--80asehdb.html +онлайн + +// xn--80aswg : CORE Association +// https://www.iana.org/domains/root/db/xn--80aswg.html +сайт + +// xn--8y0a063a : China United Network Communications Corporation Limited +// https://www.iana.org/domains/root/db/xn--8y0a063a.html +联通 + +// xn--9dbq2a : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--9dbq2a.html +קום + +// xn--9et52u : RISE VICTORY LIMITED +// https://www.iana.org/domains/root/db/xn--9et52u.html +时尚 + +// xn--9krt00a : Sina Corporation +// https://www.iana.org/domains/root/db/xn--9krt00a.html +微博 + +// xn--b4w605ferd : Temasek Holdings (Private) Limited +// https://www.iana.org/domains/root/db/xn--b4w605ferd.html +淡马锡 + +// xn--bck1b9a5dre4c : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--bck1b9a5dre4c.html +ファッション + +// xn--c1avg : Public Interest Registry +// https://www.iana.org/domains/root/db/xn--c1avg.html +орг + +// xn--c2br7g : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--c2br7g.html +नेट + +// xn--cck2b3b : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--cck2b3b.html +ストア + +// xn--cckwcxetd : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--cckwcxetd.html +アマゾン + +// xn--cg4bki : SAMSUNG SDS CO., LTD +// https://www.iana.org/domains/root/db/xn--cg4bki.html +삼성 + +// xn--czr694b : Internet DotTrademark Organisation Limited +// https://www.iana.org/domains/root/db/xn--czr694b.html +商标 + +// xn--czrs0t : Binky Moon, LLC +// https://www.iana.org/domains/root/db/xn--czrs0t.html +商店 + +// xn--czru2d : Zodiac Aquarius Limited +// https://www.iana.org/domains/root/db/xn--czru2d.html +商城 + +// xn--d1acj3b : The Foundation for Network Initiatives “The Smart Internet” +// https://www.iana.org/domains/root/db/xn--d1acj3b.html +дети + +// xn--eckvdtc9d : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--eckvdtc9d.html +ポイント + +// xn--efvy88h : Guangzhou YU Wei Information Technology Co., Ltd. +// https://www.iana.org/domains/root/db/xn--efvy88h.html +新闻 + +// xn--fct429k : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--fct429k.html +家電 + +// xn--fhbei : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--fhbei.html +كوم + +// xn--fiq228c5hs : TLD REGISTRY LIMITED OY +// https://www.iana.org/domains/root/db/xn--fiq228c5hs.html +中文网 + +// xn--fiq64b : CITIC Group Corporation +// https://www.iana.org/domains/root/db/xn--fiq64b.html +中信 + +// xn--fjq720a : Binky Moon, LLC +// https://www.iana.org/domains/root/db/xn--fjq720a.html +娱乐 + +// xn--flw351e : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/xn--flw351e.html +谷歌 + +// xn--fzys8d69uvgm : PCCW Enterprises Limited +// https://www.iana.org/domains/root/db/xn--fzys8d69uvgm.html +電訊盈科 + +// xn--g2xx48c : Nawang Heli(Xiamen) Network Service Co., LTD. +// https://www.iana.org/domains/root/db/xn--g2xx48c.html +购物 + +// xn--gckr3f0f : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--gckr3f0f.html +クラウド + +// xn--gk3at1e : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--gk3at1e.html +通販 + +// xn--hxt814e : Zodiac Taurus Limited +// https://www.iana.org/domains/root/db/xn--hxt814e.html +网店 + +// xn--i1b6b1a6a2e : Public Interest Registry +// https://www.iana.org/domains/root/db/xn--i1b6b1a6a2e.html +संगठन + +// xn--imr513n : Internet DotTrademark Organisation Limited +// https://www.iana.org/domains/root/db/xn--imr513n.html +餐厅 + +// xn--io0a7i : China Internet Network Information Center (CNNIC) +// https://www.iana.org/domains/root/db/xn--io0a7i.html +网络 + +// xn--j1aef : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--j1aef.html +ком + +// xn--jlq480n2rg : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--jlq480n2rg.html +亚马逊 + +// xn--jvr189m : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--jvr189m.html +食品 + +// xn--kcrx77d1x4a : Koninklijke Philips N.V. +// https://www.iana.org/domains/root/db/xn--kcrx77d1x4a.html +飞利浦 + +// xn--kput3i : Beijing RITT-Net Technology Development Co., Ltd +// https://www.iana.org/domains/root/db/xn--kput3i.html +手机 + +// xn--mgba3a3ejt : Aramco Services Company +// https://www.iana.org/domains/root/db/xn--mgba3a3ejt.html +ارامكو + +// xn--mgba7c0bbn0a : Competrol (Luxembourg) Sarl +// https://www.iana.org/domains/root/db/xn--mgba7c0bbn0a.html +العليان + +// xn--mgbab2bd : CORE Association +// https://www.iana.org/domains/root/db/xn--mgbab2bd.html +بازار + +// xn--mgbca7dzdo : Abu Dhabi Systems and Information Centre +// https://www.iana.org/domains/root/db/xn--mgbca7dzdo.html +ابوظبي + +// xn--mgbi4ecexp : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) +// https://www.iana.org/domains/root/db/xn--mgbi4ecexp.html +كاثوليك + +// xn--mgbt3dhd +// https://www.iana.org/domains/root/db/xn--mgbt3dhd.html +همراه + +// xn--mk1bu44c : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--mk1bu44c.html +닷컴 + +// xn--mxtq1m : Net-Chinese Co., Ltd. +// https://www.iana.org/domains/root/db/xn--mxtq1m.html +政府 + +// xn--ngbc5azd : International Domain Registry Pty. Ltd. +// https://www.iana.org/domains/root/db/xn--ngbc5azd.html +شبكة + +// xn--ngbe9e0a : Kuwait Finance House +// https://www.iana.org/domains/root/db/xn--ngbe9e0a.html +بيتك + +// xn--ngbrx : League of Arab States +// https://www.iana.org/domains/root/db/xn--ngbrx.html +عرب + +// xn--nqv7f : Public Interest Registry +// https://www.iana.org/domains/root/db/xn--nqv7f.html +机构 + +// xn--nqv7fs00ema : Public Interest Registry +// https://www.iana.org/domains/root/db/xn--nqv7fs00ema.html +组织机构 + +// xn--nyqy26a : Stable Tone Limited +// https://www.iana.org/domains/root/db/xn--nyqy26a.html +健康 + +// xn--otu796d : Jiang Yu Liang Cai Technology Company Limited +// https://www.iana.org/domains/root/db/xn--otu796d.html +招聘 + +// xn--p1acf : Rusnames Limited +// https://www.iana.org/domains/root/db/xn--p1acf.html +рус + +// xn--pssy2u : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--pssy2u.html +大拿 + +// xn--q9jyb4c : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/xn--q9jyb4c.html +みんな + +// xn--qcka1pmc : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/xn--qcka1pmc.html +グーグル + +// xn--rhqv96g : Stable Tone Limited +// https://www.iana.org/domains/root/db/xn--rhqv96g.html +世界 + +// xn--rovu88b : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/xn--rovu88b.html +書籍 + +// xn--ses554g : KNET Co., Ltd. +// https://www.iana.org/domains/root/db/xn--ses554g.html +网址 + +// xn--t60b56a : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--t60b56a.html +닷넷 + +// xn--tckwe : VeriSign Sarl +// https://www.iana.org/domains/root/db/xn--tckwe.html +コム + +// xn--tiq49xqyj : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication) +// https://www.iana.org/domains/root/db/xn--tiq49xqyj.html +天主教 + +// xn--unup4y : Binky Moon, LLC +// https://www.iana.org/domains/root/db/xn--unup4y.html +游戏 + +// xn--vermgensberater-ctb : Deutsche Vermögensberatung Aktiengesellschaft DVAG +// https://www.iana.org/domains/root/db/xn--vermgensberater-ctb.html +vermögensberater + +// xn--vermgensberatung-pwb : Deutsche Vermögensberatung Aktiengesellschaft DVAG +// https://www.iana.org/domains/root/db/xn--vermgensberatung-pwb.html +vermögensberatung + +// xn--vhquv : Binky Moon, LLC +// https://www.iana.org/domains/root/db/xn--vhquv.html +企业 + +// xn--vuq861b : Beijing Tele-info Technology Co., Ltd. +// https://www.iana.org/domains/root/db/xn--vuq861b.html +信息 + +// xn--w4r85el8fhu5dnra : Kerry Trading Co. Limited +// https://www.iana.org/domains/root/db/xn--w4r85el8fhu5dnra.html +嘉里大酒店 + +// xn--w4rs40l : Kerry Trading Co. Limited +// https://www.iana.org/domains/root/db/xn--w4rs40l.html +嘉里 + +// xn--xhq521b : Guangzhou YU Wei Information Technology Co., Ltd. +// https://www.iana.org/domains/root/db/xn--xhq521b.html +广东 + +// xn--zfr164b : China Organizational Name Administration Center +// https://www.iana.org/domains/root/db/xn--zfr164b.html +政务 + +// xyz : XYZ.COM LLC +// https://www.iana.org/domains/root/db/xyz.html +xyz + +// yachts : XYZ.COM LLC +// https://www.iana.org/domains/root/db/yachts.html +yachts + +// yahoo : Yahoo Inc. +// https://www.iana.org/domains/root/db/yahoo.html +yahoo + +// yamaxun : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/yamaxun.html +yamaxun + +// yandex : YANDEX, LLC +// https://www.iana.org/domains/root/db/yandex.html +yandex + +// yodobashi : YODOBASHI CAMERA CO.,LTD. +// https://www.iana.org/domains/root/db/yodobashi.html +yodobashi + +// yoga : Registry Services, LLC +// https://www.iana.org/domains/root/db/yoga.html +yoga + +// yokohama : GMO Registry, Inc. +// https://www.iana.org/domains/root/db/yokohama.html +yokohama + +// you : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/you.html +you + +// youtube : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/youtube.html +youtube + +// yun : Beijing Qihu Keji Co., Ltd. +// https://www.iana.org/domains/root/db/yun.html +yun + +// zappos : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/zappos.html +zappos + +// zara : Industria de Diseño Textil, S.A. (INDITEX, S.A.) +// https://www.iana.org/domains/root/db/zara.html +zara + +// zero : Amazon Registry Services, Inc. +// https://www.iana.org/domains/root/db/zero.html +zero + +// zip : Charleston Road Registry Inc. +// https://www.iana.org/domains/root/db/zip.html +zip + +// zone : Binky Moon, LLC +// https://www.iana.org/domains/root/db/zone.html +zone + +// zuerich : Kanton Zürich (Canton of Zurich) +// https://www.iana.org/domains/root/db/zuerich.html +zuerich + +// ===END ICANN DOMAINS=== + +// ===BEGIN PRIVATE DOMAINS=== + +// (Note: these are in alphabetical order by company name) + +// .KRD : https://nic.krd +co.krd +edu.krd + +// .pl domains (grandfathered) +art.pl +gliwice.pl +krakow.pl +poznan.pl +wroc.pl +zakopane.pl + +// .US +// Submitted by Ed Moore +lib.de.us + +// 12CHARS : https://12chars.com +// Submitted by Kenny Niehage +12chars.dev +12chars.it +12chars.pro + +// 1GB LLC : https://www.1gb.ua/ +// Submitted by 1GB LLC +cc.ua +inf.ua +ltd.ua + +// 611 blockchain domain name system : https://611project.net/ +611.to + +// A2 Hosting +// Submitted by Tyler Hall +a2hosted.com +cpserver.com + +// Acorn Labs : https://acorn.io +// Submitted by Craig Jellick +*.on-acorn.io + +// ActiveTrail : https://www.activetrail.biz/ +// Submitted by Ofer Kalaora +activetrail.biz + +// Adaptable.io : https://adaptable.io +// Submitted by Mark Terrel +adaptable.app + +// addr.tools : https://addr.tools/ +// Submitted by Brian Shea +myaddr.dev +myaddr.io +dyn.addr.tools +myaddr.tools + +// Adobe : https://www.adobe.com/ +// Submitted by Ian Boston and Lars Trieloff +adobeaemcloud.com +*.dev.adobeaemcloud.com +aem.live +hlx.live +adobeaemcloud.net +aem.page +hlx.page +hlx3.page + +// Adobe Developer Platform : https://developer.adobe.com +// Submitted by Jesse MacFadyen +adobeio-static.net +adobeioruntime.net + +// Africa.com Web Solutions Ltd : https://registry.africa.com +// Submitted by Gavin Brown +africa.com + +// Agnat sp. z o.o. : https://domena.pl +// Submitted by Przemyslaw Plewa +beep.pl + +// Airkit : https://www.airkit.com/ +// Submitted by Grant Cooksey +airkitapps.com +airkitapps-au.com +airkitapps.eu + +// Aiven : https://aiven.io/ +// Submitted by Aiven Security Team +aiven.app +aivencloud.com + +// Akamai : https://www.akamai.com/ +// Submitted by Akamai Team +akadns.net +akamai.net +akamai-staging.net +akamaiedge.net +akamaiedge-staging.net +akamaihd.net +akamaihd-staging.net +akamaiorigin.net +akamaiorigin-staging.net +akamaized.net +akamaized-staging.net +edgekey.net +edgekey-staging.net +edgesuite.net +edgesuite-staging.net + +// alboto.ca : http://alboto.ca +// Submitted by Anton Avramov +barsy.ca + +// Alces Software Ltd : http://alces-software.com +// Submitted by Mark J. Titorenko +*.compute.estate +*.alces.network + +// Alibaba Cloud API Gateway +// Submitted by Alibaba Cloud Security +alibabacloudcs.com + +// all-inkl.com : https://all-inkl.com +// Submitted by Werner Kaltofen +kasserver.com + +// Altervista : https://www.altervista.org +// Submitted by Carlo Cannas +altervista.org + +// alwaysdata : https://www.alwaysdata.com +// Submitted by Cyril +alwaysdata.net + +// Amaze Software : https://amaze.co +// Submitted by Domain Admin +myamaze.net + +// Amazon : https://www.amazon.com/ +// Submitted by AWS Security +// Subsections of Amazon/subsidiaries will appear until "concludes" tag + +// Amazon API Gateway +// Submitted by AWS Security +// Reference: 6a4f5a95-8c7d-4077-a7af-9cf1abec0a53 +execute-api.cn-north-1.amazonaws.com.cn +execute-api.cn-northwest-1.amazonaws.com.cn +execute-api.af-south-1.amazonaws.com +execute-api.ap-east-1.amazonaws.com +execute-api.ap-northeast-1.amazonaws.com +execute-api.ap-northeast-2.amazonaws.com +execute-api.ap-northeast-3.amazonaws.com +execute-api.ap-south-1.amazonaws.com +execute-api.ap-south-2.amazonaws.com +execute-api.ap-southeast-1.amazonaws.com +execute-api.ap-southeast-2.amazonaws.com +execute-api.ap-southeast-3.amazonaws.com +execute-api.ap-southeast-4.amazonaws.com +execute-api.ap-southeast-5.amazonaws.com +execute-api.ca-central-1.amazonaws.com +execute-api.ca-west-1.amazonaws.com +execute-api.eu-central-1.amazonaws.com +execute-api.eu-central-2.amazonaws.com +execute-api.eu-north-1.amazonaws.com +execute-api.eu-south-1.amazonaws.com +execute-api.eu-south-2.amazonaws.com +execute-api.eu-west-1.amazonaws.com +execute-api.eu-west-2.amazonaws.com +execute-api.eu-west-3.amazonaws.com +execute-api.il-central-1.amazonaws.com +execute-api.me-central-1.amazonaws.com +execute-api.me-south-1.amazonaws.com +execute-api.sa-east-1.amazonaws.com +execute-api.us-east-1.amazonaws.com +execute-api.us-east-2.amazonaws.com +execute-api.us-gov-east-1.amazonaws.com +execute-api.us-gov-west-1.amazonaws.com +execute-api.us-west-1.amazonaws.com +execute-api.us-west-2.amazonaws.com + +// Amazon CloudFront +// Submitted by Donavan Miller +// Reference: 54144616-fd49-4435-8535-19c6a601bdb3 +cloudfront.net + +// Amazon Cognito +// Submitted by AWS Security +// Reference: eb4652f0-20f0-43f5-b323-e6cc6ae02ad7 +auth.af-south-1.amazoncognito.com +auth.ap-east-1.amazoncognito.com +auth.ap-northeast-1.amazoncognito.com +auth.ap-northeast-2.amazoncognito.com +auth.ap-northeast-3.amazoncognito.com +auth.ap-south-1.amazoncognito.com +auth.ap-south-2.amazoncognito.com +auth.ap-southeast-1.amazoncognito.com +auth.ap-southeast-2.amazoncognito.com +auth.ap-southeast-3.amazoncognito.com +auth.ap-southeast-4.amazoncognito.com +auth.ap-southeast-5.amazoncognito.com +auth.ca-central-1.amazoncognito.com +auth.ca-west-1.amazoncognito.com +auth.eu-central-1.amazoncognito.com +auth.eu-central-2.amazoncognito.com +auth.eu-north-1.amazoncognito.com +auth.eu-south-1.amazoncognito.com +auth.eu-south-2.amazoncognito.com +auth.eu-west-1.amazoncognito.com +auth.eu-west-2.amazoncognito.com +auth.eu-west-3.amazoncognito.com +auth.il-central-1.amazoncognito.com +auth.me-central-1.amazoncognito.com +auth.me-south-1.amazoncognito.com +auth.sa-east-1.amazoncognito.com +auth.us-east-1.amazoncognito.com +auth-fips.us-east-1.amazoncognito.com +auth.us-east-2.amazoncognito.com +auth-fips.us-east-2.amazoncognito.com +auth-fips.us-gov-east-1.amazoncognito.com +auth-fips.us-gov-west-1.amazoncognito.com +auth.us-west-1.amazoncognito.com +auth-fips.us-west-1.amazoncognito.com +auth.us-west-2.amazoncognito.com +auth-fips.us-west-2.amazoncognito.com + +// Amazon EC2 +// Submitted by Luke Wells +// Reference: 4c38fa71-58ac-4768-99e5-689c1767e537 +*.compute.amazonaws.com.cn +*.compute.amazonaws.com +*.compute-1.amazonaws.com +us-east-1.amazonaws.com + +// Amazon EMR +// Submitted by AWS Security +// Reference: 82f43f9f-bbb8-400e-8349-854f5a62f20d +emrappui-prod.cn-north-1.amazonaws.com.cn +emrnotebooks-prod.cn-north-1.amazonaws.com.cn +emrstudio-prod.cn-north-1.amazonaws.com.cn +emrappui-prod.cn-northwest-1.amazonaws.com.cn +emrnotebooks-prod.cn-northwest-1.amazonaws.com.cn +emrstudio-prod.cn-northwest-1.amazonaws.com.cn +emrappui-prod.af-south-1.amazonaws.com +emrnotebooks-prod.af-south-1.amazonaws.com +emrstudio-prod.af-south-1.amazonaws.com +emrappui-prod.ap-east-1.amazonaws.com +emrnotebooks-prod.ap-east-1.amazonaws.com +emrstudio-prod.ap-east-1.amazonaws.com +emrappui-prod.ap-northeast-1.amazonaws.com +emrnotebooks-prod.ap-northeast-1.amazonaws.com +emrstudio-prod.ap-northeast-1.amazonaws.com +emrappui-prod.ap-northeast-2.amazonaws.com +emrnotebooks-prod.ap-northeast-2.amazonaws.com +emrstudio-prod.ap-northeast-2.amazonaws.com +emrappui-prod.ap-northeast-3.amazonaws.com +emrnotebooks-prod.ap-northeast-3.amazonaws.com +emrstudio-prod.ap-northeast-3.amazonaws.com +emrappui-prod.ap-south-1.amazonaws.com +emrnotebooks-prod.ap-south-1.amazonaws.com +emrstudio-prod.ap-south-1.amazonaws.com +emrappui-prod.ap-south-2.amazonaws.com +emrnotebooks-prod.ap-south-2.amazonaws.com +emrstudio-prod.ap-south-2.amazonaws.com +emrappui-prod.ap-southeast-1.amazonaws.com +emrnotebooks-prod.ap-southeast-1.amazonaws.com +emrstudio-prod.ap-southeast-1.amazonaws.com +emrappui-prod.ap-southeast-2.amazonaws.com +emrnotebooks-prod.ap-southeast-2.amazonaws.com +emrstudio-prod.ap-southeast-2.amazonaws.com +emrappui-prod.ap-southeast-3.amazonaws.com +emrnotebooks-prod.ap-southeast-3.amazonaws.com +emrstudio-prod.ap-southeast-3.amazonaws.com +emrappui-prod.ap-southeast-4.amazonaws.com +emrnotebooks-prod.ap-southeast-4.amazonaws.com +emrstudio-prod.ap-southeast-4.amazonaws.com +emrappui-prod.ca-central-1.amazonaws.com +emrnotebooks-prod.ca-central-1.amazonaws.com +emrstudio-prod.ca-central-1.amazonaws.com +emrappui-prod.ca-west-1.amazonaws.com +emrnotebooks-prod.ca-west-1.amazonaws.com +emrstudio-prod.ca-west-1.amazonaws.com +emrappui-prod.eu-central-1.amazonaws.com +emrnotebooks-prod.eu-central-1.amazonaws.com +emrstudio-prod.eu-central-1.amazonaws.com +emrappui-prod.eu-central-2.amazonaws.com +emrnotebooks-prod.eu-central-2.amazonaws.com +emrstudio-prod.eu-central-2.amazonaws.com +emrappui-prod.eu-north-1.amazonaws.com +emrnotebooks-prod.eu-north-1.amazonaws.com +emrstudio-prod.eu-north-1.amazonaws.com +emrappui-prod.eu-south-1.amazonaws.com +emrnotebooks-prod.eu-south-1.amazonaws.com +emrstudio-prod.eu-south-1.amazonaws.com +emrappui-prod.eu-south-2.amazonaws.com +emrnotebooks-prod.eu-south-2.amazonaws.com +emrstudio-prod.eu-south-2.amazonaws.com +emrappui-prod.eu-west-1.amazonaws.com +emrnotebooks-prod.eu-west-1.amazonaws.com +emrstudio-prod.eu-west-1.amazonaws.com +emrappui-prod.eu-west-2.amazonaws.com +emrnotebooks-prod.eu-west-2.amazonaws.com +emrstudio-prod.eu-west-2.amazonaws.com +emrappui-prod.eu-west-3.amazonaws.com +emrnotebooks-prod.eu-west-3.amazonaws.com +emrstudio-prod.eu-west-3.amazonaws.com +emrappui-prod.il-central-1.amazonaws.com +emrnotebooks-prod.il-central-1.amazonaws.com +emrstudio-prod.il-central-1.amazonaws.com +emrappui-prod.me-central-1.amazonaws.com +emrnotebooks-prod.me-central-1.amazonaws.com +emrstudio-prod.me-central-1.amazonaws.com +emrappui-prod.me-south-1.amazonaws.com +emrnotebooks-prod.me-south-1.amazonaws.com +emrstudio-prod.me-south-1.amazonaws.com +emrappui-prod.sa-east-1.amazonaws.com +emrnotebooks-prod.sa-east-1.amazonaws.com +emrstudio-prod.sa-east-1.amazonaws.com +emrappui-prod.us-east-1.amazonaws.com +emrnotebooks-prod.us-east-1.amazonaws.com +emrstudio-prod.us-east-1.amazonaws.com +emrappui-prod.us-east-2.amazonaws.com +emrnotebooks-prod.us-east-2.amazonaws.com +emrstudio-prod.us-east-2.amazonaws.com +emrappui-prod.us-gov-east-1.amazonaws.com +emrnotebooks-prod.us-gov-east-1.amazonaws.com +emrstudio-prod.us-gov-east-1.amazonaws.com +emrappui-prod.us-gov-west-1.amazonaws.com +emrnotebooks-prod.us-gov-west-1.amazonaws.com +emrstudio-prod.us-gov-west-1.amazonaws.com +emrappui-prod.us-west-1.amazonaws.com +emrnotebooks-prod.us-west-1.amazonaws.com +emrstudio-prod.us-west-1.amazonaws.com +emrappui-prod.us-west-2.amazonaws.com +emrnotebooks-prod.us-west-2.amazonaws.com +emrstudio-prod.us-west-2.amazonaws.com + +// Amazon Managed Workflows for Apache Airflow +// Submitted by AWS Security +// Reference: f5ea5d0a-ec6a-4f23-ac1c-553fbff13f5c +*.cn-north-1.airflow.amazonaws.com.cn +*.cn-northwest-1.airflow.amazonaws.com.cn +*.af-south-1.airflow.amazonaws.com +*.ap-east-1.airflow.amazonaws.com +*.ap-northeast-1.airflow.amazonaws.com +*.ap-northeast-2.airflow.amazonaws.com +*.ap-northeast-3.airflow.amazonaws.com +*.ap-south-1.airflow.amazonaws.com +*.ap-south-2.airflow.amazonaws.com +*.ap-southeast-1.airflow.amazonaws.com +*.ap-southeast-2.airflow.amazonaws.com +*.ap-southeast-3.airflow.amazonaws.com +*.ap-southeast-4.airflow.amazonaws.com +*.ca-central-1.airflow.amazonaws.com +*.ca-west-1.airflow.amazonaws.com +*.eu-central-1.airflow.amazonaws.com +*.eu-central-2.airflow.amazonaws.com +*.eu-north-1.airflow.amazonaws.com +*.eu-south-1.airflow.amazonaws.com +*.eu-south-2.airflow.amazonaws.com +*.eu-west-1.airflow.amazonaws.com +*.eu-west-2.airflow.amazonaws.com +*.eu-west-3.airflow.amazonaws.com +*.il-central-1.airflow.amazonaws.com +*.me-central-1.airflow.amazonaws.com +*.me-south-1.airflow.amazonaws.com +*.sa-east-1.airflow.amazonaws.com +*.us-east-1.airflow.amazonaws.com +*.us-east-2.airflow.amazonaws.com +*.us-west-1.airflow.amazonaws.com +*.us-west-2.airflow.amazonaws.com + +// Amazon S3 +// Submitted by AWS Security +// Reference: ada5c9df-55e1-4195-a1ce-732d6c81e357 +s3.dualstack.cn-north-1.amazonaws.com.cn +s3-accesspoint.dualstack.cn-north-1.amazonaws.com.cn +s3-website.dualstack.cn-north-1.amazonaws.com.cn +s3.cn-north-1.amazonaws.com.cn +s3-accesspoint.cn-north-1.amazonaws.com.cn +s3-deprecated.cn-north-1.amazonaws.com.cn +s3-object-lambda.cn-north-1.amazonaws.com.cn +s3-website.cn-north-1.amazonaws.com.cn +s3.dualstack.cn-northwest-1.amazonaws.com.cn +s3-accesspoint.dualstack.cn-northwest-1.amazonaws.com.cn +s3.cn-northwest-1.amazonaws.com.cn +s3-accesspoint.cn-northwest-1.amazonaws.com.cn +s3-object-lambda.cn-northwest-1.amazonaws.com.cn +s3-website.cn-northwest-1.amazonaws.com.cn +s3.dualstack.af-south-1.amazonaws.com +s3-accesspoint.dualstack.af-south-1.amazonaws.com +s3-website.dualstack.af-south-1.amazonaws.com +s3.af-south-1.amazonaws.com +s3-accesspoint.af-south-1.amazonaws.com +s3-object-lambda.af-south-1.amazonaws.com +s3-website.af-south-1.amazonaws.com +s3.dualstack.ap-east-1.amazonaws.com +s3-accesspoint.dualstack.ap-east-1.amazonaws.com +s3.ap-east-1.amazonaws.com +s3-accesspoint.ap-east-1.amazonaws.com +s3-object-lambda.ap-east-1.amazonaws.com +s3-website.ap-east-1.amazonaws.com +s3.dualstack.ap-northeast-1.amazonaws.com +s3-accesspoint.dualstack.ap-northeast-1.amazonaws.com +s3-website.dualstack.ap-northeast-1.amazonaws.com +s3.ap-northeast-1.amazonaws.com +s3-accesspoint.ap-northeast-1.amazonaws.com +s3-object-lambda.ap-northeast-1.amazonaws.com +s3-website.ap-northeast-1.amazonaws.com +s3.dualstack.ap-northeast-2.amazonaws.com +s3-accesspoint.dualstack.ap-northeast-2.amazonaws.com +s3-website.dualstack.ap-northeast-2.amazonaws.com +s3.ap-northeast-2.amazonaws.com +s3-accesspoint.ap-northeast-2.amazonaws.com +s3-object-lambda.ap-northeast-2.amazonaws.com +s3-website.ap-northeast-2.amazonaws.com +s3.dualstack.ap-northeast-3.amazonaws.com +s3-accesspoint.dualstack.ap-northeast-3.amazonaws.com +s3-website.dualstack.ap-northeast-3.amazonaws.com +s3.ap-northeast-3.amazonaws.com +s3-accesspoint.ap-northeast-3.amazonaws.com +s3-object-lambda.ap-northeast-3.amazonaws.com +s3-website.ap-northeast-3.amazonaws.com +s3.dualstack.ap-south-1.amazonaws.com +s3-accesspoint.dualstack.ap-south-1.amazonaws.com +s3-website.dualstack.ap-south-1.amazonaws.com +s3.ap-south-1.amazonaws.com +s3-accesspoint.ap-south-1.amazonaws.com +s3-object-lambda.ap-south-1.amazonaws.com +s3-website.ap-south-1.amazonaws.com +s3.dualstack.ap-south-2.amazonaws.com +s3-accesspoint.dualstack.ap-south-2.amazonaws.com +s3-website.dualstack.ap-south-2.amazonaws.com +s3.ap-south-2.amazonaws.com +s3-accesspoint.ap-south-2.amazonaws.com +s3-object-lambda.ap-south-2.amazonaws.com +s3-website.ap-south-2.amazonaws.com +s3.dualstack.ap-southeast-1.amazonaws.com +s3-accesspoint.dualstack.ap-southeast-1.amazonaws.com +s3-website.dualstack.ap-southeast-1.amazonaws.com +s3.ap-southeast-1.amazonaws.com +s3-accesspoint.ap-southeast-1.amazonaws.com +s3-object-lambda.ap-southeast-1.amazonaws.com +s3-website.ap-southeast-1.amazonaws.com +s3.dualstack.ap-southeast-2.amazonaws.com +s3-accesspoint.dualstack.ap-southeast-2.amazonaws.com +s3-website.dualstack.ap-southeast-2.amazonaws.com +s3.ap-southeast-2.amazonaws.com +s3-accesspoint.ap-southeast-2.amazonaws.com +s3-object-lambda.ap-southeast-2.amazonaws.com +s3-website.ap-southeast-2.amazonaws.com +s3.dualstack.ap-southeast-3.amazonaws.com +s3-accesspoint.dualstack.ap-southeast-3.amazonaws.com +s3-website.dualstack.ap-southeast-3.amazonaws.com +s3.ap-southeast-3.amazonaws.com +s3-accesspoint.ap-southeast-3.amazonaws.com +s3-object-lambda.ap-southeast-3.amazonaws.com +s3-website.ap-southeast-3.amazonaws.com +s3.dualstack.ap-southeast-4.amazonaws.com +s3-accesspoint.dualstack.ap-southeast-4.amazonaws.com +s3-website.dualstack.ap-southeast-4.amazonaws.com +s3.ap-southeast-4.amazonaws.com +s3-accesspoint.ap-southeast-4.amazonaws.com +s3-object-lambda.ap-southeast-4.amazonaws.com +s3-website.ap-southeast-4.amazonaws.com +s3.dualstack.ap-southeast-5.amazonaws.com +s3-accesspoint.dualstack.ap-southeast-5.amazonaws.com +s3-website.dualstack.ap-southeast-5.amazonaws.com +s3.ap-southeast-5.amazonaws.com +s3-accesspoint.ap-southeast-5.amazonaws.com +s3-deprecated.ap-southeast-5.amazonaws.com +s3-object-lambda.ap-southeast-5.amazonaws.com +s3-website.ap-southeast-5.amazonaws.com +s3.dualstack.ca-central-1.amazonaws.com +s3-accesspoint.dualstack.ca-central-1.amazonaws.com +s3-accesspoint-fips.dualstack.ca-central-1.amazonaws.com +s3-fips.dualstack.ca-central-1.amazonaws.com +s3-website.dualstack.ca-central-1.amazonaws.com +s3.ca-central-1.amazonaws.com +s3-accesspoint.ca-central-1.amazonaws.com +s3-accesspoint-fips.ca-central-1.amazonaws.com +s3-fips.ca-central-1.amazonaws.com +s3-object-lambda.ca-central-1.amazonaws.com +s3-website.ca-central-1.amazonaws.com +s3.dualstack.ca-west-1.amazonaws.com +s3-accesspoint.dualstack.ca-west-1.amazonaws.com +s3-accesspoint-fips.dualstack.ca-west-1.amazonaws.com +s3-fips.dualstack.ca-west-1.amazonaws.com +s3-website.dualstack.ca-west-1.amazonaws.com +s3.ca-west-1.amazonaws.com +s3-accesspoint.ca-west-1.amazonaws.com +s3-accesspoint-fips.ca-west-1.amazonaws.com +s3-fips.ca-west-1.amazonaws.com +s3-object-lambda.ca-west-1.amazonaws.com +s3-website.ca-west-1.amazonaws.com +s3.dualstack.eu-central-1.amazonaws.com +s3-accesspoint.dualstack.eu-central-1.amazonaws.com +s3-website.dualstack.eu-central-1.amazonaws.com +s3.eu-central-1.amazonaws.com +s3-accesspoint.eu-central-1.amazonaws.com +s3-object-lambda.eu-central-1.amazonaws.com +s3-website.eu-central-1.amazonaws.com +s3.dualstack.eu-central-2.amazonaws.com +s3-accesspoint.dualstack.eu-central-2.amazonaws.com +s3-website.dualstack.eu-central-2.amazonaws.com +s3.eu-central-2.amazonaws.com +s3-accesspoint.eu-central-2.amazonaws.com +s3-object-lambda.eu-central-2.amazonaws.com +s3-website.eu-central-2.amazonaws.com +s3.dualstack.eu-north-1.amazonaws.com +s3-accesspoint.dualstack.eu-north-1.amazonaws.com +s3.eu-north-1.amazonaws.com +s3-accesspoint.eu-north-1.amazonaws.com +s3-object-lambda.eu-north-1.amazonaws.com +s3-website.eu-north-1.amazonaws.com +s3.dualstack.eu-south-1.amazonaws.com +s3-accesspoint.dualstack.eu-south-1.amazonaws.com +s3-website.dualstack.eu-south-1.amazonaws.com +s3.eu-south-1.amazonaws.com +s3-accesspoint.eu-south-1.amazonaws.com +s3-object-lambda.eu-south-1.amazonaws.com +s3-website.eu-south-1.amazonaws.com +s3.dualstack.eu-south-2.amazonaws.com +s3-accesspoint.dualstack.eu-south-2.amazonaws.com +s3-website.dualstack.eu-south-2.amazonaws.com +s3.eu-south-2.amazonaws.com +s3-accesspoint.eu-south-2.amazonaws.com +s3-object-lambda.eu-south-2.amazonaws.com +s3-website.eu-south-2.amazonaws.com +s3.dualstack.eu-west-1.amazonaws.com +s3-accesspoint.dualstack.eu-west-1.amazonaws.com +s3-website.dualstack.eu-west-1.amazonaws.com +s3.eu-west-1.amazonaws.com +s3-accesspoint.eu-west-1.amazonaws.com +s3-deprecated.eu-west-1.amazonaws.com +s3-object-lambda.eu-west-1.amazonaws.com +s3-website.eu-west-1.amazonaws.com +s3.dualstack.eu-west-2.amazonaws.com +s3-accesspoint.dualstack.eu-west-2.amazonaws.com +s3.eu-west-2.amazonaws.com +s3-accesspoint.eu-west-2.amazonaws.com +s3-object-lambda.eu-west-2.amazonaws.com +s3-website.eu-west-2.amazonaws.com +s3.dualstack.eu-west-3.amazonaws.com +s3-accesspoint.dualstack.eu-west-3.amazonaws.com +s3-website.dualstack.eu-west-3.amazonaws.com +s3.eu-west-3.amazonaws.com +s3-accesspoint.eu-west-3.amazonaws.com +s3-object-lambda.eu-west-3.amazonaws.com +s3-website.eu-west-3.amazonaws.com +s3.dualstack.il-central-1.amazonaws.com +s3-accesspoint.dualstack.il-central-1.amazonaws.com +s3-website.dualstack.il-central-1.amazonaws.com +s3.il-central-1.amazonaws.com +s3-accesspoint.il-central-1.amazonaws.com +s3-object-lambda.il-central-1.amazonaws.com +s3-website.il-central-1.amazonaws.com +s3.dualstack.me-central-1.amazonaws.com +s3-accesspoint.dualstack.me-central-1.amazonaws.com +s3-website.dualstack.me-central-1.amazonaws.com +s3.me-central-1.amazonaws.com +s3-accesspoint.me-central-1.amazonaws.com +s3-object-lambda.me-central-1.amazonaws.com +s3-website.me-central-1.amazonaws.com +s3.dualstack.me-south-1.amazonaws.com +s3-accesspoint.dualstack.me-south-1.amazonaws.com +s3.me-south-1.amazonaws.com +s3-accesspoint.me-south-1.amazonaws.com +s3-object-lambda.me-south-1.amazonaws.com +s3-website.me-south-1.amazonaws.com +s3.amazonaws.com +s3-1.amazonaws.com +s3-ap-east-1.amazonaws.com +s3-ap-northeast-1.amazonaws.com +s3-ap-northeast-2.amazonaws.com +s3-ap-northeast-3.amazonaws.com +s3-ap-south-1.amazonaws.com +s3-ap-southeast-1.amazonaws.com +s3-ap-southeast-2.amazonaws.com +s3-ca-central-1.amazonaws.com +s3-eu-central-1.amazonaws.com +s3-eu-north-1.amazonaws.com +s3-eu-west-1.amazonaws.com +s3-eu-west-2.amazonaws.com +s3-eu-west-3.amazonaws.com +s3-external-1.amazonaws.com +s3-fips-us-gov-east-1.amazonaws.com +s3-fips-us-gov-west-1.amazonaws.com +mrap.accesspoint.s3-global.amazonaws.com +s3-me-south-1.amazonaws.com +s3-sa-east-1.amazonaws.com +s3-us-east-2.amazonaws.com +s3-us-gov-east-1.amazonaws.com +s3-us-gov-west-1.amazonaws.com +s3-us-west-1.amazonaws.com +s3-us-west-2.amazonaws.com +s3-website-ap-northeast-1.amazonaws.com +s3-website-ap-southeast-1.amazonaws.com +s3-website-ap-southeast-2.amazonaws.com +s3-website-eu-west-1.amazonaws.com +s3-website-sa-east-1.amazonaws.com +s3-website-us-east-1.amazonaws.com +s3-website-us-gov-west-1.amazonaws.com +s3-website-us-west-1.amazonaws.com +s3-website-us-west-2.amazonaws.com +s3.dualstack.sa-east-1.amazonaws.com +s3-accesspoint.dualstack.sa-east-1.amazonaws.com +s3-website.dualstack.sa-east-1.amazonaws.com +s3.sa-east-1.amazonaws.com +s3-accesspoint.sa-east-1.amazonaws.com +s3-object-lambda.sa-east-1.amazonaws.com +s3-website.sa-east-1.amazonaws.com +s3.dualstack.us-east-1.amazonaws.com +s3-accesspoint.dualstack.us-east-1.amazonaws.com +s3-accesspoint-fips.dualstack.us-east-1.amazonaws.com +s3-fips.dualstack.us-east-1.amazonaws.com +s3-website.dualstack.us-east-1.amazonaws.com +s3.us-east-1.amazonaws.com +s3-accesspoint.us-east-1.amazonaws.com +s3-accesspoint-fips.us-east-1.amazonaws.com +s3-deprecated.us-east-1.amazonaws.com +s3-fips.us-east-1.amazonaws.com +s3-object-lambda.us-east-1.amazonaws.com +s3-website.us-east-1.amazonaws.com +s3.dualstack.us-east-2.amazonaws.com +s3-accesspoint.dualstack.us-east-2.amazonaws.com +s3-accesspoint-fips.dualstack.us-east-2.amazonaws.com +s3-fips.dualstack.us-east-2.amazonaws.com +s3-website.dualstack.us-east-2.amazonaws.com +s3.us-east-2.amazonaws.com +s3-accesspoint.us-east-2.amazonaws.com +s3-accesspoint-fips.us-east-2.amazonaws.com +s3-deprecated.us-east-2.amazonaws.com +s3-fips.us-east-2.amazonaws.com +s3-object-lambda.us-east-2.amazonaws.com +s3-website.us-east-2.amazonaws.com +s3.dualstack.us-gov-east-1.amazonaws.com +s3-accesspoint.dualstack.us-gov-east-1.amazonaws.com +s3-accesspoint-fips.dualstack.us-gov-east-1.amazonaws.com +s3-fips.dualstack.us-gov-east-1.amazonaws.com +s3.us-gov-east-1.amazonaws.com +s3-accesspoint.us-gov-east-1.amazonaws.com +s3-accesspoint-fips.us-gov-east-1.amazonaws.com +s3-fips.us-gov-east-1.amazonaws.com +s3-object-lambda.us-gov-east-1.amazonaws.com +s3-website.us-gov-east-1.amazonaws.com +s3.dualstack.us-gov-west-1.amazonaws.com +s3-accesspoint.dualstack.us-gov-west-1.amazonaws.com +s3-accesspoint-fips.dualstack.us-gov-west-1.amazonaws.com +s3-fips.dualstack.us-gov-west-1.amazonaws.com +s3.us-gov-west-1.amazonaws.com +s3-accesspoint.us-gov-west-1.amazonaws.com +s3-accesspoint-fips.us-gov-west-1.amazonaws.com +s3-fips.us-gov-west-1.amazonaws.com +s3-object-lambda.us-gov-west-1.amazonaws.com +s3-website.us-gov-west-1.amazonaws.com +s3.dualstack.us-west-1.amazonaws.com +s3-accesspoint.dualstack.us-west-1.amazonaws.com +s3-accesspoint-fips.dualstack.us-west-1.amazonaws.com +s3-fips.dualstack.us-west-1.amazonaws.com +s3-website.dualstack.us-west-1.amazonaws.com +s3.us-west-1.amazonaws.com +s3-accesspoint.us-west-1.amazonaws.com +s3-accesspoint-fips.us-west-1.amazonaws.com +s3-fips.us-west-1.amazonaws.com +s3-object-lambda.us-west-1.amazonaws.com +s3-website.us-west-1.amazonaws.com +s3.dualstack.us-west-2.amazonaws.com +s3-accesspoint.dualstack.us-west-2.amazonaws.com +s3-accesspoint-fips.dualstack.us-west-2.amazonaws.com +s3-fips.dualstack.us-west-2.amazonaws.com +s3-website.dualstack.us-west-2.amazonaws.com +s3.us-west-2.amazonaws.com +s3-accesspoint.us-west-2.amazonaws.com +s3-accesspoint-fips.us-west-2.amazonaws.com +s3-deprecated.us-west-2.amazonaws.com +s3-fips.us-west-2.amazonaws.com +s3-object-lambda.us-west-2.amazonaws.com +s3-website.us-west-2.amazonaws.com + +// Amazon SageMaker Ground Truth +// Submitted by AWS Security +// Reference: 98dbfde4-7802-48c3-8751-b60f204e0d9c +labeling.ap-northeast-1.sagemaker.aws +labeling.ap-northeast-2.sagemaker.aws +labeling.ap-south-1.sagemaker.aws +labeling.ap-southeast-1.sagemaker.aws +labeling.ap-southeast-2.sagemaker.aws +labeling.ca-central-1.sagemaker.aws +labeling.eu-central-1.sagemaker.aws +labeling.eu-west-1.sagemaker.aws +labeling.eu-west-2.sagemaker.aws +labeling.us-east-1.sagemaker.aws +labeling.us-east-2.sagemaker.aws +labeling.us-west-2.sagemaker.aws + +// Amazon SageMaker Notebook Instances +// Submitted by AWS Security +// Reference: b5ea56df-669e-43cc-9537-14aa172f5dfc +notebook.af-south-1.sagemaker.aws +notebook.ap-east-1.sagemaker.aws +notebook.ap-northeast-1.sagemaker.aws +notebook.ap-northeast-2.sagemaker.aws +notebook.ap-northeast-3.sagemaker.aws +notebook.ap-south-1.sagemaker.aws +notebook.ap-south-2.sagemaker.aws +notebook.ap-southeast-1.sagemaker.aws +notebook.ap-southeast-2.sagemaker.aws +notebook.ap-southeast-3.sagemaker.aws +notebook.ap-southeast-4.sagemaker.aws +notebook.ca-central-1.sagemaker.aws +notebook-fips.ca-central-1.sagemaker.aws +notebook.ca-west-1.sagemaker.aws +notebook-fips.ca-west-1.sagemaker.aws +notebook.eu-central-1.sagemaker.aws +notebook.eu-central-2.sagemaker.aws +notebook.eu-north-1.sagemaker.aws +notebook.eu-south-1.sagemaker.aws +notebook.eu-south-2.sagemaker.aws +notebook.eu-west-1.sagemaker.aws +notebook.eu-west-2.sagemaker.aws +notebook.eu-west-3.sagemaker.aws +notebook.il-central-1.sagemaker.aws +notebook.me-central-1.sagemaker.aws +notebook.me-south-1.sagemaker.aws +notebook.sa-east-1.sagemaker.aws +notebook.us-east-1.sagemaker.aws +notebook-fips.us-east-1.sagemaker.aws +notebook.us-east-2.sagemaker.aws +notebook-fips.us-east-2.sagemaker.aws +notebook.us-gov-east-1.sagemaker.aws +notebook-fips.us-gov-east-1.sagemaker.aws +notebook.us-gov-west-1.sagemaker.aws +notebook-fips.us-gov-west-1.sagemaker.aws +notebook.us-west-1.sagemaker.aws +notebook-fips.us-west-1.sagemaker.aws +notebook.us-west-2.sagemaker.aws +notebook-fips.us-west-2.sagemaker.aws +notebook.cn-north-1.sagemaker.com.cn +notebook.cn-northwest-1.sagemaker.com.cn + +// Amazon SageMaker Studio +// Submitted by AWS Security +// Reference: 475f237e-ab88-4041-9f41-7cfccdf66aeb +studio.af-south-1.sagemaker.aws +studio.ap-east-1.sagemaker.aws +studio.ap-northeast-1.sagemaker.aws +studio.ap-northeast-2.sagemaker.aws +studio.ap-northeast-3.sagemaker.aws +studio.ap-south-1.sagemaker.aws +studio.ap-southeast-1.sagemaker.aws +studio.ap-southeast-2.sagemaker.aws +studio.ap-southeast-3.sagemaker.aws +studio.ca-central-1.sagemaker.aws +studio.eu-central-1.sagemaker.aws +studio.eu-central-2.sagemaker.aws +studio.eu-north-1.sagemaker.aws +studio.eu-south-1.sagemaker.aws +studio.eu-south-2.sagemaker.aws +studio.eu-west-1.sagemaker.aws +studio.eu-west-2.sagemaker.aws +studio.eu-west-3.sagemaker.aws +studio.il-central-1.sagemaker.aws +studio.me-central-1.sagemaker.aws +studio.me-south-1.sagemaker.aws +studio.sa-east-1.sagemaker.aws +studio.us-east-1.sagemaker.aws +studio.us-east-2.sagemaker.aws +studio.us-gov-east-1.sagemaker.aws +studio-fips.us-gov-east-1.sagemaker.aws +studio.us-gov-west-1.sagemaker.aws +studio-fips.us-gov-west-1.sagemaker.aws +studio.us-west-1.sagemaker.aws +studio.us-west-2.sagemaker.aws +studio.cn-north-1.sagemaker.com.cn +studio.cn-northwest-1.sagemaker.com.cn + +// Amazon SageMaker with MLflow +// Submited by: AWS Security +// Reference: c19f92b3-a82a-452d-8189-831b572eea7e +*.experiments.sagemaker.aws + +// Analytics on AWS +// Submitted by AWS Security +// Reference: 955f9f40-a495-4e73-ae85-67b77ac9cadd +analytics-gateway.ap-northeast-1.amazonaws.com +analytics-gateway.ap-northeast-2.amazonaws.com +analytics-gateway.ap-south-1.amazonaws.com +analytics-gateway.ap-southeast-1.amazonaws.com +analytics-gateway.ap-southeast-2.amazonaws.com +analytics-gateway.eu-central-1.amazonaws.com +analytics-gateway.eu-west-1.amazonaws.com +analytics-gateway.us-east-1.amazonaws.com +analytics-gateway.us-east-2.amazonaws.com +analytics-gateway.us-west-2.amazonaws.com + +// Appwrite : https://appwrite.io +// Submitted by Steven Nguyen +appwrite.global +*.appwrite.run + +// AWS Amplify +// Submitted by AWS Security +// Reference: c35bed18-6f4f-424f-9298-5756f2f7d72b +amplifyapp.com + +// AWS App Runner +// Submitted by AWS Security +// Reference: 6828c008-ba5d-442f-ade5-48da4e7c2316 +*.awsapprunner.com + +// AWS Cloud9 +// Submitted by: AWS Security +// Reference: 30717f72-4007-4f0f-8ed4-864c6f2efec9 +webview-assets.aws-cloud9.af-south-1.amazonaws.com +vfs.cloud9.af-south-1.amazonaws.com +webview-assets.cloud9.af-south-1.amazonaws.com +webview-assets.aws-cloud9.ap-east-1.amazonaws.com +vfs.cloud9.ap-east-1.amazonaws.com +webview-assets.cloud9.ap-east-1.amazonaws.com +webview-assets.aws-cloud9.ap-northeast-1.amazonaws.com +vfs.cloud9.ap-northeast-1.amazonaws.com +webview-assets.cloud9.ap-northeast-1.amazonaws.com +webview-assets.aws-cloud9.ap-northeast-2.amazonaws.com +vfs.cloud9.ap-northeast-2.amazonaws.com +webview-assets.cloud9.ap-northeast-2.amazonaws.com +webview-assets.aws-cloud9.ap-northeast-3.amazonaws.com +vfs.cloud9.ap-northeast-3.amazonaws.com +webview-assets.cloud9.ap-northeast-3.amazonaws.com +webview-assets.aws-cloud9.ap-south-1.amazonaws.com +vfs.cloud9.ap-south-1.amazonaws.com +webview-assets.cloud9.ap-south-1.amazonaws.com +webview-assets.aws-cloud9.ap-southeast-1.amazonaws.com +vfs.cloud9.ap-southeast-1.amazonaws.com +webview-assets.cloud9.ap-southeast-1.amazonaws.com +webview-assets.aws-cloud9.ap-southeast-2.amazonaws.com +vfs.cloud9.ap-southeast-2.amazonaws.com +webview-assets.cloud9.ap-southeast-2.amazonaws.com +webview-assets.aws-cloud9.ca-central-1.amazonaws.com +vfs.cloud9.ca-central-1.amazonaws.com +webview-assets.cloud9.ca-central-1.amazonaws.com +webview-assets.aws-cloud9.eu-central-1.amazonaws.com +vfs.cloud9.eu-central-1.amazonaws.com +webview-assets.cloud9.eu-central-1.amazonaws.com +webview-assets.aws-cloud9.eu-north-1.amazonaws.com +vfs.cloud9.eu-north-1.amazonaws.com +webview-assets.cloud9.eu-north-1.amazonaws.com +webview-assets.aws-cloud9.eu-south-1.amazonaws.com +vfs.cloud9.eu-south-1.amazonaws.com +webview-assets.cloud9.eu-south-1.amazonaws.com +webview-assets.aws-cloud9.eu-west-1.amazonaws.com +vfs.cloud9.eu-west-1.amazonaws.com +webview-assets.cloud9.eu-west-1.amazonaws.com +webview-assets.aws-cloud9.eu-west-2.amazonaws.com +vfs.cloud9.eu-west-2.amazonaws.com +webview-assets.cloud9.eu-west-2.amazonaws.com +webview-assets.aws-cloud9.eu-west-3.amazonaws.com +vfs.cloud9.eu-west-3.amazonaws.com +webview-assets.cloud9.eu-west-3.amazonaws.com +webview-assets.aws-cloud9.il-central-1.amazonaws.com +vfs.cloud9.il-central-1.amazonaws.com +webview-assets.aws-cloud9.me-south-1.amazonaws.com +vfs.cloud9.me-south-1.amazonaws.com +webview-assets.cloud9.me-south-1.amazonaws.com +webview-assets.aws-cloud9.sa-east-1.amazonaws.com +vfs.cloud9.sa-east-1.amazonaws.com +webview-assets.cloud9.sa-east-1.amazonaws.com +webview-assets.aws-cloud9.us-east-1.amazonaws.com +vfs.cloud9.us-east-1.amazonaws.com +webview-assets.cloud9.us-east-1.amazonaws.com +webview-assets.aws-cloud9.us-east-2.amazonaws.com +vfs.cloud9.us-east-2.amazonaws.com +webview-assets.cloud9.us-east-2.amazonaws.com +webview-assets.aws-cloud9.us-west-1.amazonaws.com +vfs.cloud9.us-west-1.amazonaws.com +webview-assets.cloud9.us-west-1.amazonaws.com +webview-assets.aws-cloud9.us-west-2.amazonaws.com +vfs.cloud9.us-west-2.amazonaws.com +webview-assets.cloud9.us-west-2.amazonaws.com + +// AWS Directory Service +// Submitted by AWS Security +// Reference: a13203e8-42dc-4045-a0d2-2ee67bed1068 +awsapps.com + +// AWS Elastic Beanstalk +// Submitted by AWS Security +// Reference: bb5a965c-dec3-4967-aa22-e306ad064797 +cn-north-1.eb.amazonaws.com.cn +cn-northwest-1.eb.amazonaws.com.cn +elasticbeanstalk.com +af-south-1.elasticbeanstalk.com +ap-east-1.elasticbeanstalk.com +ap-northeast-1.elasticbeanstalk.com +ap-northeast-2.elasticbeanstalk.com +ap-northeast-3.elasticbeanstalk.com +ap-south-1.elasticbeanstalk.com +ap-southeast-1.elasticbeanstalk.com +ap-southeast-2.elasticbeanstalk.com +ap-southeast-3.elasticbeanstalk.com +ca-central-1.elasticbeanstalk.com +eu-central-1.elasticbeanstalk.com +eu-north-1.elasticbeanstalk.com +eu-south-1.elasticbeanstalk.com +eu-west-1.elasticbeanstalk.com +eu-west-2.elasticbeanstalk.com +eu-west-3.elasticbeanstalk.com +il-central-1.elasticbeanstalk.com +me-south-1.elasticbeanstalk.com +sa-east-1.elasticbeanstalk.com +us-east-1.elasticbeanstalk.com +us-east-2.elasticbeanstalk.com +us-gov-east-1.elasticbeanstalk.com +us-gov-west-1.elasticbeanstalk.com +us-west-1.elasticbeanstalk.com +us-west-2.elasticbeanstalk.com + +// (AWS) Elastic Load Balancing +// Submitted by Luke Wells +// Reference: 12a3d528-1bac-4433-a359-a395867ffed2 +*.elb.amazonaws.com.cn +*.elb.amazonaws.com + +// AWS Global Accelerator +// Submitted by Daniel Massaguer +// Reference: d916759d-a08b-4241-b536-4db887383a6a +awsglobalaccelerator.com + +// AWS re:Post Private +// Submitted by AWS Security +// Reference: 83385945-225f-416e-9aa0-ad0632bfdcee +*.private.repost.aws + +// AWS Transfer Family web apps +// Submitted by AWS Security +// Reference: 67e9cfe6-ac57-49c7-b197-6652711c8e8d +transfer-webapp.ap-northeast-1.on.aws +transfer-webapp.ap-southeast-1.on.aws +transfer-webapp.ap-southeast-2.on.aws +transfer-webapp.eu-central-1.on.aws +transfer-webapp.eu-north-1.on.aws +transfer-webapp.eu-west-1.on.aws +transfer-webapp.us-east-1.on.aws +transfer-webapp.us-east-2.on.aws +transfer-webapp.us-west-2.on.aws + +// eero +// Submitted by Yue Kang +// Reference: 264afe70-f62c-4c02-8ab9-b5281ed24461 +eero.online +eero-stage.online + +// concludes Amazon + +// Apigee : https://apigee.com/ +// Submitted by Apigee Security Team +apigee.io + +// Apis Networks : https://apisnetworks.com +// Submitted by Matt Saladna +panel.dev + +// Apphud : https://apphud.com +// Submitted by Alexander Selivanov +siiites.com + +// Appspace : https://www.appspace.com +// Submitted by Appspace Security Team +appspacehosted.com +appspaceusercontent.com + +// Appudo UG (haftungsbeschränkt) : https://www.appudo.com +// Submitted by Alexander Hochbaum +appudo.net + +// Aptible : https://www.aptible.com/ +// Submitted by Thomas Orozco +on-aptible.com + +// Aquapal : https://aquapal.net/ +// Submitted by Aki Ueno +f5.si + +// ArvanCloud EdgeCompute +// Submitted by ArvanCloud CDN +arvanedge.ir + +// ASEINet : https://www.aseinet.com/ +// Submitted by Asei SEKIGUCHI +user.aseinet.ne.jp +gv.vc +d.gv.vc + +// Asociación Amigos de la Informática "Euskalamiga" : http://encounter.eus/ +// Submitted by Hector Martin +user.party.eus + +// Association potager.org : https://potager.org/ +// Submitted by Lunar +pimienta.org +poivron.org +potager.org +sweetpepper.org + +// ASUSTOR Inc. : http://www.asustor.com +// Submitted by Vincent Tseng +myasustor.com + +// Atlassian : https://atlassian.com +// Submitted by Sam Smyth +cdn.prod.atlassian-dev.net + +// Authentick UG (haftungsbeschränkt) : https://authentick.net +// Submitted by Lukas Reschke +translated.page + +// AVM : https://avm.de +// Submitted by Andreas Weise +myfritz.link +myfritz.net + +// AVStack Pte. Ltd. : https://avstack.io +// Submitted by Jasper Hugo +onavstack.net + +// AW AdvisorWebsites.com Software Inc : https://advisorwebsites.com +// Submitted by James Kennedy +*.awdev.ca +*.advisor.ws + +// AZ.pl sp. z.o.o : https://az.pl +// Submitted by Krzysztof Wolski +ecommerce-shop.pl + +// b-data GmbH : https://www.b-data.io +// Submitted by Olivier Benz +b-data.io + +// Balena : https://www.balena.io +// Submitted by Petros Angelatos +balena-devices.com + +// BASE, Inc. : https://binc.jp +// Submitted by Yuya NAGASAWA +base.ec +official.ec +buyshop.jp +fashionstore.jp +handcrafted.jp +kawaiishop.jp +supersale.jp +theshop.jp +shopselect.net +base.shop + +// BeagleBoard.org Foundation : https://beagleboard.org +// Submitted by Jason Kridner +beagleboard.io + +// Beget Ltd +// Submitted by Lev Nekrasov +*.beget.app + +// Besties : https://besties.house +// Submitted by Hazel Cora +pages.gay + +// BinaryLane : http://www.binarylane.com +// Submitted by Nathan O'Sullivan +bnr.la + +// Bitbucket : http://bitbucket.org +// Submitted by Andy Ortlieb +bitbucket.io + +// Blackbaud, Inc. : https://www.blackbaud.com +// Submitted by Paul Crowder +blackbaudcdn.net + +// Blatech : http://www.blatech.net +// Submitted by Luke Bratch +of.je + +// Block, Inc. : https://block.xyz +// Submitted by Jonathan Boice +square.site + +// Blue Bite, LLC : https://bluebite.com +// Submitted by Joshua Weiss +bluebite.io + +// Boomla : https://boomla.com +// Submitted by Tibor Halter +boomla.net + +// Boutir : https://www.boutir.com +// Submitted by Eric Ng Ka Ka +boutir.com + +// Boxfuse : https://boxfuse.com +// Submitted by Axel Fontaine +boxfuse.io + +// bplaced : https://www.bplaced.net/ +// Submitted by Miroslav Bozic +square7.ch +bplaced.com +bplaced.de +square7.de +bplaced.net +square7.net + +// Brave : https://brave.com +// Submitted by Andrea Brancaleoni +brave.app +*.s.brave.app +brave.io +*.s.brave.io + +// Brendly : https://brendly.rs +// Submitted by Dusan Radovanovic +shop.brendly.hr +shop.brendly.rs + +// BrowserSafetyMark +// Submitted by Dave Tharp +browsersafetymark.io + +// BRS Media : https://brsmedia.com/ +// Submitted by Gavin Brown +radio.am +radio.fm + +// Bubble : https://bubble.io/ +// Submitted by Merlin Zhao +cdn.bubble.io +bubbleapps.io + +// Bytemark Hosting : https://www.bytemark.co.uk +// Submitted by Paul Cammish +uk0.bigv.io +dh.bytemark.co.uk +vm.bytemark.co.uk + +// Caf.js Labs LLC : https://www.cafjs.com +// Submitted by Antonio Lain +cafjs.com + +// Canva Pty Ltd : https://canva.com/ +// Submitted by Joel Aquilina +canva-apps.cn +*.my.canvasite.cn +canva-apps.com +*.my.canva.site + +// Carrd : https://carrd.co +// Submitted by AJ +drr.ac +uwu.ai +carrd.co +crd.co +ju.mp + +// CDDO : https://www.gov.uk/guidance/get-an-api-domain-on-govuk +// Submitted by Jamie Tanna +api.gov.uk + +// CDN77.com : http://www.cdn77.com +// Submitted by Jan Krpes +cdn77-storage.com +rsc.contentproxy9.cz +r.cdn77.net +cdn77-ssl.net +c.cdn77.org +rsc.cdn77.org +ssl.origin.cdn77-secure.org + +// CentralNic : https://teaminternet.com/ +// Submitted by registry +za.bz +br.com +cn.com +de.com +eu.com +jpn.com +mex.com +ru.com +sa.com +uk.com +us.com +za.com +com.de +gb.net +hu.net +jp.net +se.net +uk.net +ae.org +com.se + +// Cityhost LLC : https://cityhost.ua +// Submitted by Maksym Rivtin +cx.ua + +// Civilized Discourse Construction Kit, Inc. : https://www.discourse.org/ +// Submitted by Rishabh Nambiar & Michael Brown +discourse.group +discourse.team + +// Clerk : https://www.clerk.dev +// Submitted by Colin Sidoti +clerk.app +clerkstage.app +*.lcl.dev +*.lclstage.dev +*.stg.dev +*.stgstage.dev + +// Clever Cloud : https://www.clever-cloud.com/ +// Submitted by Quentin Adam +cleverapps.cc +*.services.clever-cloud.com +cleverapps.io +cleverapps.tech + +// ClickRising : https://clickrising.com/ +// Submitted by Umut Gumeli +clickrising.net + +// Cloud DNS Ltd : http://www.cloudns.net +// Submitted by Aleksander Hristov & Boyan Peychev +cloudns.asia +cloudns.be +cloud-ip.biz +cloudns.biz +cloudns.cc +cloudns.ch +cloudns.cl +cloudns.club +dnsabr.com +ip-ddns.com +cloudns.cx +cloudns.eu +cloudns.in +cloudns.info +ddns-ip.net +dns-cloud.net +dns-dynamic.net +cloudns.nz +cloudns.org +ip-dynamic.org +cloudns.ph +cloudns.pro +cloudns.pw +cloudns.us + +// Cloud66 : https://www.cloud66.com/ +// Submitted by Khash Sajadi +c66.me +cloud66.ws +cloud66.zone + +// CloudAccess.net : https://www.cloudaccess.net/ +// Submitted by Pawel Panek +jdevcloud.com +wpdevcloud.com +cloudaccess.host +freesite.host +cloudaccess.net + +// Cloudbees, Inc. : https://www.cloudbees.com/ +// Submitted by Mohideen Shajith +cloudbeesusercontent.io + +// Cloudera, Inc. : https://www.cloudera.com/ +// Submitted by Kedarnath Waikar +*.cloudera.site + +// Cloudflare, Inc. : https://www.cloudflare.com/ +// Submitted by Cloudflare Team +cf-ipfs.com +cloudflare-ipfs.com +trycloudflare.com +pages.dev +r2.dev +workers.dev +cloudflare.net +cdn.cloudflare.net +cdn.cloudflareanycast.net +cdn.cloudflarecn.net +cdn.cloudflareglobal.net + +// cloudscale.ch AG : https://www.cloudscale.ch/ +// Submitted by Gaudenz Steinlin +cust.cloudscale.ch +objects.lpg.cloudscale.ch +objects.rma.cloudscale.ch +lpg.objectstorage.ch +rma.objectstorage.ch + +// Clovyr : https://clovyr.io +// Submitted by Patrick Nielsen +wnext.app + +// CNPY : https://cnpy.gdn +// Submitted by Angelo Gladding +cnpy.gdn + +// Co & Co : https://co-co.nl/ +// Submitted by Govert Versluis +*.otap.co + +// co.ca : http://registry.co.ca/ +co.ca + +// co.com Registry, LLC : https://registry.co.com +// Submitted by Gavin Brown +co.com + +// Codeberg e. V. : https://codeberg.org +// Submitted by Moritz Marquardt +codeberg.page + +// CodeSandbox B.V. : https://codesandbox.io +// Submitted by Ives van Hoorne +csb.app +preview.csb.app + +// CoDNS B.V. +co.nl +co.no + +// Cognition AI, Inc. : https://cognition.ai +// Submitted by Philip Papurt +*.devinapps.com + +// Combell.com : https://www.combell.com +// Submitted by Thomas Wouters +webhosting.be +hosting-cluster.nl + +// Contentful GmbH : https://www.contentful.com +// Submitted by Contentful Developer Experience Team +ctfcloud.net + +// Convex : https://convex.dev/ +// Submitted by James Cowling +convex.app +convex.cloud +convex.site + +// Coordination Center for TLD RU and XN--P1AI : https://cctld.ru/en/domains/domens_ru/reserved/ +// Submitted by George Georgievsky +ac.ru +edu.ru +gov.ru +int.ru +mil.ru + +// COSIMO GmbH : http://www.cosimo.de +// Submitted by Rene Marticke +dyn.cosidns.de +dnsupdater.de +dynamisches-dns.de +internet-dns.de +l-o-g-i-n.de +dynamic-dns.info +feste-ip.net +knx-server.net +static-access.net + +// Craft Docs Ltd : https://www.craft.do/ +// Submitted by Zsombor Fuszenecker +craft.me + +// Craynic, s.r.o. : http://www.craynic.com/ +// Submitted by Ales Krajnik +realm.cz + +// Crisp IM SAS : https://crisp.chat/ +// Submitted by Baptiste Jamin +on.crisp.email + +// Cryptonomic : https://cryptonomic.net/ +// Submitted by Andrew Cady +*.cryptonomic.net + +// cyber_Folks S.A. : https://cyberfolks.pl +// Submitted by Bartlomiej Kida +cfolks.pl + +// cyon GmbH : https://www.cyon.ch/ +// Submitted by Dominic Luechinger +cyon.link +cyon.site + +// Dansk.net : http://www.dansk.net/ +// Submitted by Anani Voule +biz.dk +co.dk +firm.dk +reg.dk +store.dk + +// dappnode.io : https://dappnode.io/ +// Submitted by Abel Boldu / DAppNode Team +dyndns.dappnode.io + +// Dark, Inc. : https://darklang.com +// Submitted by Paul Biggar +builtwithdark.com +darklang.io + +// DataDetect, LLC. : https://datadetect.com +// Submitted by Andrew Banchich +demo.datadetect.com +instance.datadetect.com + +// Datawire, Inc : https://www.datawire.io +// Submitted by Richard Li +edgestack.me + +// Datto, Inc. : https://www.datto.com/ +// Submitted by Philipp Heckel +dattolocal.com +dattorelay.com +dattoweb.com +mydatto.com +dattolocal.net +mydatto.net + +// ddnss.de : https://www.ddnss.de/ +// Submitted by Robert Niedziela +ddnss.de +dyn.ddnss.de +dyndns.ddnss.de +dyn-ip24.de +dyndns1.de +home-webserver.de +dyn.home-webserver.de +myhome-server.de +ddnss.org + +// Debian : https://www.debian.org/ +// Submitted by Peter Palfrader / Debian Sysadmin Team +debian.net + +// Definima : http://www.definima.com/ +// Submitted by Maxence Bitterli +definima.io +definima.net + +// Deno Land Inc : https://deno.com/ +// Submitted by Luca Casonato +deno.dev +deno-staging.dev +deno.net + +// deSEC : https://desec.io/ +// Submitted by Peter Thomassen +dedyn.io + +// Deta : https://www.deta.sh/ +// Submitted by Aavash Shrestha +deta.app +deta.dev + +// dhosting.pl Sp. z o.o. : https://dhosting.pl/ +// Submitted by Michal Kokoszkiewicz +dfirma.pl +dkonto.pl +you2.pl + +// DigitalOcean App Platform : https://www.digitalocean.com/products/app-platform/ +// Submitted by Braxton Huggins +ondigitalocean.app + +// DigitalOcean Spaces : https://www.digitalocean.com/products/spaces/ +// Submitted by Robin H. Johnson +*.digitaloceanspaces.com + +// DigitalPlat : https://www.digitalplat.org/ +// Submitted by Edward Hsing +us.kg +dpdns.org + +// Discord Inc : https://discord.com +// Submitted by Sahn Lam +discordsays.com +discordsez.com + +// DNS Africa Ltd : https://dns.business +// Submitted by Calvin Browne +jozi.biz + +// DNShome : https://www.dnshome.de/ +// Submitted by Norbert Auler +dnshome.de + +// DotArai : https://www.dotarai.com/ +// Submitted by Atsadawat Netcharadsang +online.th +shop.th + +// DrayTek Corp. : https://www.draytek.com/ +// Submitted by Paul Fang +drayddns.com + +// DreamCommerce : https://shoper.pl/ +// Submitted by Konrad Kotarba +shoparena.pl + +// DreamHost : http://www.dreamhost.com/ +// Submitted by Andrew Farmer +dreamhosters.com + +// Dreamyoungs, Inc. : https://durumis.com +// Submitted by Infra Team +durumis.com + +// Drobo : http://www.drobo.com/ +// Submitted by Ricardo Padilha +mydrobo.com + +// DuckDNS : http://www.duckdns.org/ +// Submitted by Richard Harper +duckdns.org + +// dy.fi : http://dy.fi/ +// Submitted by Heikki Hannikainen +dy.fi +tunk.org + +// DynDNS.com : http://www.dyndns.com/services/dns/dyndns/ +dyndns.biz +for-better.biz +for-more.biz +for-some.biz +for-the.biz +selfip.biz +webhop.biz +ftpaccess.cc +game-server.cc +myphotos.cc +scrapping.cc +blogdns.com +cechire.com +dnsalias.com +dnsdojo.com +doesntexist.com +dontexist.com +doomdns.com +dyn-o-saur.com +dynalias.com +dyndns-at-home.com +dyndns-at-work.com +dyndns-blog.com +dyndns-free.com +dyndns-home.com +dyndns-ip.com +dyndns-mail.com +dyndns-office.com +dyndns-pics.com +dyndns-remote.com +dyndns-server.com +dyndns-web.com +dyndns-wiki.com +dyndns-work.com +est-a-la-maison.com +est-a-la-masion.com +est-le-patron.com +est-mon-blogueur.com +from-ak.com +from-al.com +from-ar.com +from-ca.com +from-ct.com +from-dc.com +from-de.com +from-fl.com +from-ga.com +from-hi.com +from-ia.com +from-id.com +from-il.com +from-in.com +from-ks.com +from-ky.com +from-ma.com +from-md.com +from-mi.com +from-mn.com +from-mo.com +from-ms.com +from-mt.com +from-nc.com +from-nd.com +from-ne.com +from-nh.com +from-nj.com +from-nm.com +from-nv.com +from-oh.com +from-ok.com +from-or.com +from-pa.com +from-pr.com +from-ri.com +from-sc.com +from-sd.com +from-tn.com +from-tx.com +from-ut.com +from-va.com +from-vt.com +from-wa.com +from-wi.com +from-wv.com +from-wy.com +getmyip.com +gotdns.com +hobby-site.com +homelinux.com +homeunix.com +iamallama.com +is-a-anarchist.com +is-a-blogger.com +is-a-bookkeeper.com +is-a-bulls-fan.com +is-a-caterer.com +is-a-chef.com +is-a-conservative.com +is-a-cpa.com +is-a-cubicle-slave.com +is-a-democrat.com +is-a-designer.com +is-a-doctor.com +is-a-financialadvisor.com +is-a-geek.com +is-a-green.com +is-a-guru.com +is-a-hard-worker.com +is-a-hunter.com +is-a-landscaper.com +is-a-lawyer.com +is-a-liberal.com +is-a-libertarian.com +is-a-llama.com +is-a-musician.com +is-a-nascarfan.com +is-a-nurse.com +is-a-painter.com +is-a-personaltrainer.com +is-a-photographer.com +is-a-player.com +is-a-republican.com +is-a-rockstar.com +is-a-socialist.com +is-a-student.com +is-a-teacher.com +is-a-techie.com +is-a-therapist.com +is-an-accountant.com +is-an-actor.com +is-an-actress.com +is-an-anarchist.com +is-an-artist.com +is-an-engineer.com +is-an-entertainer.com +is-certified.com +is-gone.com +is-into-anime.com +is-into-cars.com +is-into-cartoons.com +is-into-games.com +is-leet.com +is-not-certified.com +is-slick.com +is-uberleet.com +is-with-theband.com +isa-geek.com +isa-hockeynut.com +issmarterthanyou.com +likes-pie.com +likescandy.com +neat-url.com +saves-the-whales.com +selfip.com +sells-for-less.com +sells-for-u.com +servebbs.com +simple-url.com +space-to-rent.com +teaches-yoga.com +writesthisblog.com +ath.cx +fuettertdasnetz.de +isteingeek.de +istmein.de +lebtimnetz.de +leitungsen.de +traeumtgerade.de +barrel-of-knowledge.info +barrell-of-knowledge.info +dyndns.info +for-our.info +groks-the.info +groks-this.info +here-for-more.info +knowsitall.info +selfip.info +webhop.info +forgot.her.name +forgot.his.name +at-band-camp.net +blogdns.net +broke-it.net +buyshouses.net +dnsalias.net +dnsdojo.net +does-it.net +dontexist.net +dynalias.net +dynathome.net +endofinternet.net +from-az.net +from-co.net +from-la.net +from-ny.net +gets-it.net +ham-radio-op.net +homeftp.net +homeip.net +homelinux.net +homeunix.net +in-the-band.net +is-a-chef.net +is-a-geek.net +isa-geek.net +kicks-ass.net +office-on-the.net +podzone.net +scrapper-site.net +selfip.net +sells-it.net +servebbs.net +serveftp.net +thruhere.net +webhop.net +merseine.nu +mine.nu +shacknet.nu +blogdns.org +blogsite.org +boldlygoingnowhere.org +dnsalias.org +dnsdojo.org +doesntexist.org +dontexist.org +doomdns.org +dvrdns.org +dynalias.org +dyndns.org +go.dyndns.org +home.dyndns.org +endofinternet.org +endoftheinternet.org +from-me.org +game-host.org +gotdns.org +hobby-site.org +homedns.org +homeftp.org +homelinux.org +homeunix.org +is-a-bruinsfan.org +is-a-candidate.org +is-a-celticsfan.org +is-a-chef.org +is-a-geek.org +is-a-knight.org +is-a-linux-user.org +is-a-patsfan.org +is-a-soxfan.org +is-found.org +is-lost.org +is-saved.org +is-very-bad.org +is-very-evil.org +is-very-good.org +is-very-nice.org +is-very-sweet.org +isa-geek.org +kicks-ass.org +misconfused.org +podzone.org +readmyblog.org +selfip.org +sellsyourhome.org +servebbs.org +serveftp.org +servegame.org +stuff-4-sale.org +webhop.org +better-than.tv +dyndns.tv +on-the-web.tv +worse-than.tv +is-by.us +land-4-sale.us +stuff-4-sale.us +dyndns.ws +mypets.ws + +// Dynu.com : https://www.dynu.com/ +// Submitted by Sue Ye +ddnsfree.com +ddnsgeek.com +giize.com +gleeze.com +kozow.com +loseyourip.com +ooguy.com +theworkpc.com +casacam.net +dynu.net +accesscam.org +camdvr.org +freeddns.org +mywire.org +webredirect.org +myddns.rocks + +// dynv6 : https://dynv6.com +// Submitted by Dominik Menke +dynv6.net + +// E4YOU spol. s.r.o. : https://e4you.cz/ +// Submitted by Vladimir Dudr +e4.cz + +// Easypanel : https://easypanel.io +// Submitted by Andrei Canta +easypanel.app +easypanel.host + +// EasyWP : https://www.easywp.com +// Submitted by +*.ewp.live + +// eDirect Corp. : https://hosting.url.com.tw/ +// Submitted by C.S. chang +twmail.cc +twmail.net +twmail.org +mymailer.com.tw +url.tw + +// Electromagnetic Field : https://www.emfcamp.org +// Submitted by +at.emf.camp + +// Elefunc, Inc. : https://elefunc.com +// Submitted by Cetin Sert +rt.ht + +// Elementor : Elementor Ltd. +// Submitted by Anton Barkan +elementor.cloud +elementor.cool + +// En root‽ : https://en-root.org +// Submitted by Emmanuel Raviart +en-root.fr + +// Enalean SAS : https://www.enalean.com +// Submitted by Enalean Security Team +mytuleap.com +tuleap-partners.com + +// Encoretivity AB : https://encore.cloud +// Submitted by André Eriksson +encr.app +encoreapi.com +lp.dev + +// encoway GmbH : https://www.encoway.de +// Submitted by Marcel Daus +eu.encoway.cloud + +// EU.org : https://eu.org/ +// Submitted by Pierre Beyssac +eu.org +al.eu.org +asso.eu.org +at.eu.org +au.eu.org +be.eu.org +bg.eu.org +ca.eu.org +cd.eu.org +ch.eu.org +cn.eu.org +cy.eu.org +cz.eu.org +de.eu.org +dk.eu.org +edu.eu.org +ee.eu.org +es.eu.org +fi.eu.org +fr.eu.org +gr.eu.org +hr.eu.org +hu.eu.org +ie.eu.org +il.eu.org +in.eu.org +int.eu.org +is.eu.org +it.eu.org +jp.eu.org +kr.eu.org +lt.eu.org +lu.eu.org +lv.eu.org +me.eu.org +mk.eu.org +mt.eu.org +my.eu.org +net.eu.org +ng.eu.org +nl.eu.org +no.eu.org +nz.eu.org +pl.eu.org +pt.eu.org +ro.eu.org +ru.eu.org +se.eu.org +si.eu.org +sk.eu.org +tr.eu.org +uk.eu.org +us.eu.org + +// Eurobyte : https://eurobyte.ru +// Submitted by Evgeniy Subbotin +eurodir.ru + +// Evennode : http://www.evennode.com/ +// Submitted by Michal Kralik +eu-1.evennode.com +eu-2.evennode.com +eu-3.evennode.com +eu-4.evennode.com +us-1.evennode.com +us-2.evennode.com +us-3.evennode.com +us-4.evennode.com + +// Evervault : https://evervault.com +// Submitted by Hannah Neary +relay.evervault.app +relay.evervault.dev + +// Expo : https://expo.dev/ +// Submitted by James Ide +expo.app +staging.expo.app + +// Fabrica Technologies, Inc. : https://www.fabrica.dev/ +// Submitted by Eric Jiang +onfabrica.com + +// FAITID : https://faitid.org/ +// Submitted by Maxim Alzoba +// https://www.flexireg.net/stat_info +ru.net +adygeya.ru +bashkiria.ru +bir.ru +cbg.ru +com.ru +dagestan.ru +grozny.ru +kalmykia.ru +kustanai.ru +marine.ru +mordovia.ru +msk.ru +mytis.ru +nalchik.ru +nov.ru +pyatigorsk.ru +spb.ru +vladikavkaz.ru +vladimir.ru +abkhazia.su +adygeya.su +aktyubinsk.su +arkhangelsk.su +armenia.su +ashgabad.su +azerbaijan.su +balashov.su +bashkiria.su +bryansk.su +bukhara.su +chimkent.su +dagestan.su +east-kazakhstan.su +exnet.su +georgia.su +grozny.su +ivanovo.su +jambyl.su +kalmykia.su +kaluga.su +karacol.su +karaganda.su +karelia.su +khakassia.su +krasnodar.su +kurgan.su +kustanai.su +lenug.su +mangyshlak.su +mordovia.su +msk.su +murmansk.su +nalchik.su +navoi.su +north-kazakhstan.su +nov.su +obninsk.su +penza.su +pokrovsk.su +sochi.su +spb.su +tashkent.su +termez.su +togliatti.su +troitsk.su +tselinograd.su +tula.su +tuva.su +vladikavkaz.su +vladimir.su +vologda.su + +// Fancy Bits, LLC : http://getchannels.com +// Submitted by Aman Gupta +channelsdvr.net +u.channelsdvr.net + +// Fastly Inc. : http://www.fastly.com/ +// Submitted by Fastly Security +edgecompute.app +fastly-edge.com +fastly-terrarium.com +freetls.fastly.net +map.fastly.net +a.prod.fastly.net +global.prod.fastly.net +a.ssl.fastly.net +b.ssl.fastly.net +global.ssl.fastly.net +fastlylb.net +map.fastlylb.net + +// Fastmail : https://www.fastmail.com/ +// Submitted by Marc Bradshaw +*.user.fm + +// FASTVPS EESTI OU : https://fastvps.ru/ +// Submitted by Likhachev Vasiliy +fastvps-server.com +fastvps.host +myfast.host +fastvps.site +myfast.space + +// FearWorks Media Ltd. : https://fearworksmedia.co.uk +// Submitted by Keith Fairley +conn.uk +copro.uk +hosp.uk + +// Fedora : https://fedoraproject.org/ +// Submitted by Patrick Uiterwijk +fedorainfracloud.org +fedorapeople.org +cloud.fedoraproject.org +app.os.fedoraproject.org +app.os.stg.fedoraproject.org + +// Fermax : https://fermax.com/ +// Submitted by Koen Van Isterdael +mydobiss.com + +// FH Muenster : https://www.fh-muenster.de +// Submitted by Robin Naundorf +fh-muenster.io + +// Figma : https://www.figma.com +// Submitted by Nick Frost +figma.site +preview.site + +// Filegear Inc. : https://www.filegear.com +// Submitted by Jason Zhu +filegear.me + +// Firebase, Inc. +// Submitted by Chris Raynor +firebaseapp.com + +// FlashDrive : https://flashdrive.io +// Submitted by Eric Chan +fldrv.com + +// Fleek Labs Inc : https://fleek.xyz +// Submitted by Parsa Ghadimi +on-fleek.app + +// FlutterFlow : https://flutterflow.io +// Submitted by Anton Emelyanov +flutterflow.app + +// fly.io : https://fly.io +// Submitted by Kurt Mackey +fly.dev +shw.io +edgeapp.net + +// Forgerock : https://www.forgerock.com +// Submitted by Roderick Parr +forgeblocks.com +id.forgerock.io + +// FoundryLabs, Inc : https://e2b.dev/ +// Submitted by Jiri Sveceny +e2b.app + +// Framer : https://www.framer.com +// Submitted by Koen Rouwhorst +framer.ai +framer.app +framercanvas.com +framer.media +framer.photos +framer.website +framer.wiki + +// Frederik Braun : https://frederik-braun.com +// Submitted by Frederik Braun +*.0e.vc + +// Freebox : http://www.freebox.fr +// Submitted by Romain Fliedel +freebox-os.com +freeboxos.com +fbx-os.fr +fbxos.fr +freebox-os.fr +freeboxos.fr + +// freedesktop.org : https://www.freedesktop.org +// Submitted by Daniel Stone +freedesktop.org + +// freemyip.com : https://freemyip.com +// Submitted by Cadence +freemyip.com + +// Frusky MEDIA&PR : https://www.frusky.de +// Submitted by Victor Pupynin +*.frusky.de + +// FunkFeuer - Verein zur Förderung freier Netze : https://www.funkfeuer.at +// Submitted by Daniel A. Maierhofer +wien.funkfeuer.at + +// Future Versatile Group. : https://www.fvg-on.net/ +// T.Kabu +daemon.asia +dix.asia +mydns.bz +0am.jp +0g0.jp +0j0.jp +0t0.jp +mydns.jp +pgw.jp +wjg.jp +keyword-on.net +live-on.net +server-on.net +mydns.tw +mydns.vc + +// Futureweb GmbH : https://www.futureweb.at +// Submitted by Andreas Schnederle-Wagner +*.futurecms.at +*.ex.futurecms.at +*.in.futurecms.at +futurehosting.at +futuremailing.at +*.ex.ortsinfo.at +*.kunden.ortsinfo.at +*.statics.cloud + +// GCom Internet : https://www.gcom.net.au +// Submitted by Leo Julius +aliases121.com + +// GDS : https://www.gov.uk/service-manual/technology/managing-domain-names +// Submitted by Stephen Ford +campaign.gov.uk +service.gov.uk +independent-commission.uk +independent-inquest.uk +independent-inquiry.uk +independent-panel.uk +independent-review.uk +public-inquiry.uk +royal-commission.uk + +// Gehirn Inc. : https://www.gehirn.co.jp/ +// Submitted by Kohei YOSHIDA +gehirn.ne.jp +usercontent.jp + +// Gentlent, Inc. : https://www.gentlent.com +// Submitted by Tom Klein +gentapps.com +gentlentapis.com +cdn-edges.net + +// GignoSystemJapan : http://gsj.bz +// Submitted by GignoSystemJapan +gsj.bz + +// GitHub, Inc. +// Submitted by Patrick Toomey +githubusercontent.com +githubpreview.dev +github.io + +// GitLab, Inc. : https://about.gitlab.com/ +// Submitted by Alex Hanselka +gitlab.io + +// Gitplac.si : https://gitplac.si +// Submitted by Aljaž Starc +gitapp.si +gitpage.si + +// Glitch, Inc : https://glitch.com +// Submitted by Mads Hartmann +glitch.me + +// Global NOG Alliance : https://nogalliance.org/ +// Submitted by Sander Steffann +nog.community + +// Globe Hosting SRL : https://www.globehosting.com/ +// Submitted by Gavin Brown +co.ro +shop.ro + +// GMO Pepabo, Inc. : https://pepabo.com/ +// Submitted by Hosting Div +lolipop.io +angry.jp +babyblue.jp +babymilk.jp +backdrop.jp +bambina.jp +bitter.jp +blush.jp +boo.jp +boy.jp +boyfriend.jp +but.jp +candypop.jp +capoo.jp +catfood.jp +cheap.jp +chicappa.jp +chillout.jp +chips.jp +chowder.jp +chu.jp +ciao.jp +cocotte.jp +coolblog.jp +cranky.jp +cutegirl.jp +daa.jp +deca.jp +deci.jp +digick.jp +egoism.jp +fakefur.jp +fem.jp +flier.jp +floppy.jp +fool.jp +frenchkiss.jp +girlfriend.jp +girly.jp +gloomy.jp +gonna.jp +greater.jp +hacca.jp +heavy.jp +her.jp +hiho.jp +hippy.jp +holy.jp +hungry.jp +icurus.jp +itigo.jp +jellybean.jp +kikirara.jp +kill.jp +kilo.jp +kuron.jp +littlestar.jp +lolipopmc.jp +lolitapunk.jp +lomo.jp +lovepop.jp +lovesick.jp +main.jp +mods.jp +mond.jp +mongolian.jp +moo.jp +namaste.jp +nikita.jp +nobushi.jp +noor.jp +oops.jp +parallel.jp +parasite.jp +pecori.jp +peewee.jp +penne.jp +pepper.jp +perma.jp +pigboat.jp +pinoko.jp +punyu.jp +pupu.jp +pussycat.jp +pya.jp +raindrop.jp +readymade.jp +sadist.jp +schoolbus.jp +secret.jp +staba.jp +stripper.jp +sub.jp +sunnyday.jp +thick.jp +tonkotsu.jp +under.jp +upper.jp +velvet.jp +verse.jp +versus.jp +vivian.jp +watson.jp +weblike.jp +whitesnow.jp +zombie.jp +heteml.net + +// GoDaddy Registry : https://registry.godaddy +// Submitted by Rohan Durrant +graphic.design + +// GoIP DNS Services : http://www.goip.de +// Submitted by Christian Poulter +goip.de + +// Google, Inc. +// Submitted by Shannon McCabe +*.hosted.app +*.run.app +web.app +*.0emm.com +appspot.com +*.r.appspot.com +blogspot.com +codespot.com +googleapis.com +googlecode.com +pagespeedmobilizer.com +withgoogle.com +withyoutube.com +*.gateway.dev +cloud.goog +translate.goog +*.usercontent.goog +cloudfunctions.net + +// Goupile : https://goupile.fr +// Submitted by Niels Martignene +goupile.fr + +// GOV.UK Pay : https://www.payments.service.gov.uk/ +// Submitted by Richard Baker +pymnt.uk + +// GOV.UK Platform as a Service : https://www.cloud.service.gov.uk/ +// Submitted by Tom Whitwell +cloudapps.digital +london.cloudapps.digital + +// Government of the Netherlands : https://www.government.nl +// Submitted by +gov.nl + +// Grafana Labs : https://grafana.com/ +// Submitted by Platform Engineering +grafana-dev.net + +// GrayJay Web Solutions Inc. : https://grayjaysports.ca +// Submitted by Matt Yamkowy +grayjayleagues.com + +// GünstigBestellen : https://günstigbestellen.de +// Submitted by Furkan Akkoc +günstigbestellen.de +günstigliefern.de + +// Häkkinen.fi : https://www.häkkinen.fi/ +// Submitted by Eero Häkkinen +häkkinen.fi + +// Harrison Network : https://hrsn.net +// Submitted by William Harrison +hrsn.dev + +// Hashbang : https://hashbang.sh +hashbang.sh + +// Hasura : https://hasura.io +// Submitted by Shahidh K Muhammed +hasura.app +hasura-app.io + +// Hatena Co., Ltd. : https://hatena.co.jp +// Submitted by Masato Nakamura +hatenablog.com +hatenadiary.com +hateblo.jp +hatenablog.jp +hatenadiary.jp +hatenadiary.org + +// Heilbronn University of Applied Sciences - Faculty Informatics (GitLab Pages) : https://www.hs-heilbronn.de +// Submitted by Richard Zowalla +pages.it.hs-heilbronn.de +pages-research.it.hs-heilbronn.de + +// HeiyuSpace : https://lazycat.cloud +// Submitted by Xia Bin +heiyu.space + +// Helio Networks : https://heliohost.org +// Submitted by Ben Frede +helioho.st +heliohost.us + +// Hepforge : https://www.hepforge.org +// Submitted by David Grellscheid +hepforge.org + +// Heroku : https://www.heroku.com/ +// Submitted by Shumon Huque +herokuapp.com + +// Heyflow : https://www.heyflow.com +// Submitted by Mirko Nitschke +heyflow.page +heyflow.site + +// Hibernating Rhinos +// Submitted by Oren Eini +ravendb.cloud +ravendb.community +development.run +ravendb.run + +// home.pl S.A. : https://home.pl +// Submitted by Krzysztof Wolski +homesklep.pl + +// Homebase : https://homebase.id/ +// Submitted by Jason Babo +*.kin.one +*.id.pub +*.kin.pub + +// Hoplix : https://www.hoplix.com +// Submitted by Danilo De Franco +hoplix.shop + +// HOSTBIP REGISTRY : https://www.hostbip.com/ +// Submitted by Atanunu Igbunuroghene +orx.biz +biz.gl +biz.ng +co.biz.ng +dl.biz.ng +go.biz.ng +lg.biz.ng +on.biz.ng +col.ng +firm.ng +gen.ng +ltd.ng +ngo.ng +plc.ng + +// HostyHosting : https://hostyhosting.com +hostyhosting.io + +// Hugging Face : https://huggingface.co +// Submitted by Eliott Coyac +hf.space +static.hf.space + +// Hypernode B.V. : https://www.hypernode.com/ +// Submitted by Cipriano Groenendal +hypernode.io + +// I-O DATA DEVICE, INC. : http://www.iodata.com/ +// Submitted by Yuji Minagawa +iobb.net + +// i-registry s.r.o. : http://www.i-registry.cz/ +// Submitted by Martin Semrad +co.cz + +// Ici la Lune : http://www.icilalune.com/ +// Submitted by Simon Morvan +*.moonscale.io +moonscale.net + +// iDOT Services Limited : http://www.domain.gr.com +// Submitted by Gavin Brown +gr.com + +// iki.fi +// Submitted by Hannu Aronsson +iki.fi + +// iliad italia : https://www.iliad.it +// Submitted by Marios Makassikis +ibxos.it +iliadboxos.it + +// Incsub, LLC : https://incsub.com/ +// Submitted by Aaron Edwards +smushcdn.com +wphostedmail.com +wpmucdn.com +tempurl.host +wpmudev.host + +// Individual Network Berlin e.V. : https://www.in-berlin.de/ +// Submitted by Christian Seitz +dyn-berlin.de +in-berlin.de +in-brb.de +in-butter.de +in-dsl.de +in-vpn.de +in-dsl.net +in-vpn.net +in-dsl.org +in-vpn.org + +// Inferno Communications : https://inferno.co.uk +// Submitted by Connor McFarlane +oninferno.net + +// info.at : http://www.info.at/ +biz.at +info.at + +// info.cx : http://info.cx +// Submitted by June Slater +info.cx + +// Interlegis : http://www.interlegis.leg.br +// Submitted by Gabriel Ferreira +ac.leg.br +al.leg.br +am.leg.br +ap.leg.br +ba.leg.br +ce.leg.br +df.leg.br +es.leg.br +go.leg.br +ma.leg.br +mg.leg.br +ms.leg.br +mt.leg.br +pa.leg.br +pb.leg.br +pe.leg.br +pi.leg.br +pr.leg.br +rj.leg.br +rn.leg.br +ro.leg.br +rr.leg.br +rs.leg.br +sc.leg.br +se.leg.br +sp.leg.br +to.leg.br + +// intermetrics GmbH : https://pixolino.com/ +// Submitted by Wolfgang Schwarz +pixolino.com + +// Internet-Pro, LLP : https://netangels.ru/ +// Submitted by Vasiliy Sheredeko +na4u.ru + +// Inventor Services : https://inventor.gg/ +// Submitted by Inventor Team +botdash.app +botdash.dev +botdash.gg +botdash.net +botda.sh +botdash.xyz + +// IONOS SE : https://www.ionos.com/ +// IONOS Group SE : https://www.ionos-group.com/ +// Submitted by Henrik Willert +apps-1and1.com +live-website.com +apps-1and1.net +websitebuilder.online +app-ionos.space + +// iopsys software solutions AB : https://iopsys.eu/ +// Submitted by Roman Azarenko +iopsys.se + +// IPFS Project : https://ipfs.tech/ +// Submitted by Interplanetary Shipyard +*.inbrowser.dev +*.dweb.link +*.inbrowser.link + +// IPiFony Systems, Inc. : https://www.ipifony.com/ +// Submitted by Matthew Hardeman +ipifony.net + +// ir.md : https://nic.ir.md +// Submitted by Ali Soizi +ir.md + +// is-a-good.dev : https://is-a-good.dev +// Submitted by William Harrison +is-a-good.dev + +// is-a.dev : https://is-a.dev +// Submitted by William Harrison +is-a.dev + +// IServ GmbH : https://iserv.de +// Submitted by Mario Hoberg +iservschule.de +mein-iserv.de +schulplattform.de +schulserver.de +test-iserv.de +iserv.dev + +// Jelastic, Inc. : https://jelastic.com/ +// Submitted by Ihor Kolodyuk +mel.cloudlets.com.au +cloud.interhostsolutions.be +alp1.ae.flow.ch +appengine.flow.ch +es-1.axarnet.cloud +diadem.cloud +vip.jelastic.cloud +jele.cloud +it1.eur.aruba.jenv-aruba.cloud +it1.jenv-aruba.cloud +keliweb.cloud +cs.keliweb.cloud +oxa.cloud +tn.oxa.cloud +uk.oxa.cloud +primetel.cloud +uk.primetel.cloud +ca.reclaim.cloud +uk.reclaim.cloud +us.reclaim.cloud +ch.trendhosting.cloud +de.trendhosting.cloud +jele.club +dopaas.com +paas.hosted-by-previder.com +rag-cloud.hosteur.com +rag-cloud-ch.hosteur.com +jcloud.ik-server.com +jcloud-ver-jpc.ik-server.com +demo.jelastic.com +paas.massivegrid.com +jed.wafaicloud.com +ryd.wafaicloud.com +j.scaleforce.com.cy +jelastic.dogado.eu +fi.cloudplatform.fi +demo.datacenter.fi +paas.datacenter.fi +jele.host +mircloud.host +paas.beebyte.io +sekd1.beebyteapp.io +jele.io +jc.neen.it +jcloud.kz +cloudjiffy.net +fra1-de.cloudjiffy.net +west1-us.cloudjiffy.net +jls-sto1.elastx.net +jls-sto2.elastx.net +jls-sto3.elastx.net +fr-1.paas.massivegrid.net +lon-1.paas.massivegrid.net +lon-2.paas.massivegrid.net +ny-1.paas.massivegrid.net +ny-2.paas.massivegrid.net +sg-1.paas.massivegrid.net +jelastic.saveincloud.net +nordeste-idc.saveincloud.net +j.scaleforce.net +sdscloud.pl +unicloud.pl +mircloud.ru +enscaled.sg +jele.site +jelastic.team +orangecloud.tn +j.layershift.co.uk +phx.enscaled.us +mircloud.us + +// Jino : https://www.jino.ru +// Submitted by Sergey Ulyashin +myjino.ru +*.hosting.myjino.ru +*.landing.myjino.ru +*.spectrum.myjino.ru +*.vps.myjino.ru + +// Jotelulu S.L. : https://jotelulu.com +// Submitted by Daniel Fariña +jotelulu.cloud + +// JouwWeb B.V. : https://www.jouwweb.nl +// Submitted by Camilo Sperberg +webadorsite.com +jouwweb.site + +// Joyent : https://www.joyent.com/ +// Submitted by Brian Bennett +*.cns.joyent.com +*.triton.zone + +// JS.ORG : http://dns.js.org +// Submitted by Stefan Keim +js.org + +// KaasHosting : http://www.kaashosting.nl/ +// Submitted by Wouter Bakker +kaas.gg +khplay.nl + +// Kapsi : https://kapsi.fi +// Submitted by Tomi Juntunen +kapsi.fi + +// Katholieke Universiteit Leuven : https://www.kuleuven.be +// Submitted by Abuse KU Leuven +ezproxy.kuleuven.be +kuleuven.cloud + +// Keyweb AG : https://www.keyweb.de +// Submitted by Martin Dannehl +keymachine.de + +// KingHost : https://king.host +// Submitted by Felipe Keller Braz +kinghost.net +uni5.net + +// KnightPoint Systems, LLC : http://www.knightpoint.com/ +// Submitted by Roy Keene +knightpoint.systems + +// KoobinEvent, SL : https://www.koobin.com +// Submitted by Iván Oliva +koobin.events + +// Krellian Ltd. : https://krellian.com +// Submitted by Ben Francis +webthings.io +krellian.net + +// KUROKU LTD : https://kuroku.ltd/ +// Submitted by DisposaBoy +oya.to + +// Laravel Holdings, Inc. : https://laravel.com +// Submitted by André Valentin +laravel.cloud + +// LCube - Professional hosting e.K. : https://www.lcube-webhosting.de +// Submitted by Lars Laehn +git-repos.de +lcube-server.de +svn-repos.de + +// Leadpages : https://www.leadpages.net +// Submitted by Greg Dallavalle +leadpages.co +lpages.co +lpusercontent.com + +// Liara : https://liara.ir +// Submitted by Amirhossein Badinloo +liara.run +iran.liara.run + +// libp2p project : https://libp2p.io +// Submitted by Interplanetary Shipyard +libp2p.direct + +// Libre IT Ltd : https://libre.nz +// Submitted by Tomas Maggio +runcontainers.dev + +// Lifetime Hosting : https://Lifetime.Hosting/ +// Submitted by Mike Fillator +co.business +co.education +co.events +co.financial +co.network +co.place +co.technology + +// linkyard ldt : https://www.linkyard.ch/ +// Submitted by Mario Siegenthaler +linkyard-cloud.ch +linkyard.cloud + +// Linode : https://linode.com +// Submitted by +members.linode.com +*.nodebalancer.linode.com +*.linodeobjects.com +ip.linodeusercontent.com + +// LiquidNet Ltd : http://www.liquidnetlimited.com/ +// Submitted by Victor Velchev +we.bs + +// Listen53 : https://www.l53.net +// Submitted by Gerry Keh +filegear-sg.me +ggff.net + +// Localcert : https://localcert.dev +// Submitted by Lann Martin +*.user.localcert.dev + +// LocalCert : https://localcert.net +// Submitted by William Harrison +localcert.net +localhostcert.net + +// Localtonet : https://localtonet.com/ +// Submitted by Burak Isleyici +localtonet.com +*.localto.net + +// Lodz University of Technology LODMAN regional domains : https://www.man.lodz.pl/dns +// Submitted by Piotr Wilk +lodz.pl +pabianice.pl +plock.pl +sieradz.pl +skierniewice.pl +zgierz.pl + +// Log'in Line : https://www.loginline.com/ +// Submitted by Rémi Mach +loginline.app +loginline.dev +loginline.io +loginline.services +loginline.site + +// Lõhmus Family, The : https://lohmus.me/ +// Submitted by Heiki Lõhmus +lohmus.me + +// Lokalized : https://lokalized.nl +// Submitted by Noah Taheij +servers.run + +// Lovable : https://lovable.dev +// Submitted by Fabian Hedin +lovable.app +lovableproject.com + +// LubMAN UMCS Sp. z o.o : https://lubman.pl/ +// Submitted by Ireneusz Maliszewski +krasnik.pl +leczna.pl +lubartow.pl +lublin.pl +poniatowa.pl +swidnik.pl + +// Lug.org.uk : https://lug.org.uk +// Submitted by Jon Spriggs +glug.org.uk +lug.org.uk +lugs.org.uk + +// Lukanet Ltd : https://lukanet.com +// Submitted by Anton Avramov +barsy.bg +barsy.club +barsycenter.com +barsyonline.com +barsy.de +barsy.dev +barsy.eu +barsy.gr +barsy.in +barsy.info +barsy.io +barsy.me +barsy.menu +barsyonline.menu +barsy.mobi +barsy.net +barsy.online +barsy.org +barsy.pro +barsy.pub +barsy.ro +barsy.rs +barsy.shop +barsyonline.shop +barsy.site +barsy.store +barsy.support +barsy.uk +barsy.co.uk +barsyonline.co.uk + +// Luyani Inc. : https://luyani.com/ +// Submitted by Umut Gumeli +luyani.app +luyani.net + +// Magento Commerce +// Submitted by Damien Tournoud +*.magentosite.cloud + +// Mail.Ru Group : https://hb.cldmail.ru +// Submitted by Ilya Zaretskiy +hb.cldmail.ru + +// MathWorks : https://www.mathworks.com/ +// Submitted by Emily Reed +matlab.cloud +modelscape.com +mwcloudnonprod.com +polyspace.com + +// May First - People Link : https://mayfirst.org/ +// Submitted by Jamie McClelland +mayfirst.info +mayfirst.org + +// Maze Play : https://www.mazeplay.com +// Submitted by Adam Humpherys +mazeplay.com + +// McHost : https://mchost.ru +// Submitted by Evgeniy Subbotin +mcdir.me +mcdir.ru +vps.mcdir.ru +mcpre.ru + +// Mediatech : https://mediatech.by +// Submitted by Evgeniy Kozhuhovskiy +mediatech.by +mediatech.dev + +// Medicom Health : https://medicomhealth.com +// Submitted by Michael Olson +hra.health + +// MedusaJS, Inc : https://medusajs.com/ +// Submitted by Stevche Radevski +medusajs.app + +// Memset hosting : https://www.memset.com +// Submitted by Tom Whitwell +miniserver.com +memset.net + +// Messerli Informatik AG : https://www.messerli.ch/ +// Submitted by Ruben Schmidmeister +messerli.app + +// Meta Platforms, Inc. : https://meta.com/ +// Submitted by Jacob Cordero +atmeta.com +apps.fbsbx.com + +// MetaCentrum, CESNET z.s.p.o. : https://www.metacentrum.cz/en/ +// Submitted by Zdeněk Šustr and Radim Janča +*.cloud.metacentrum.cz +custom.metacentrum.cz +flt.cloud.muni.cz +usr.cloud.muni.cz + +// Meteor Development Group : https://www.meteor.com/hosting +// Submitted by Pierre Carrier +meteorapp.com +eu.meteorapp.com + +// Michau Enterprises Limited : http://www.co.pl/ +co.pl + +// Microsoft Corporation : http://microsoft.com +// Submitted by Public Suffix List Admin +// Managed by Corporate Domains +// Microsoft Azure : https://home.azure +*.azurecontainer.io +azure-api.net +azure-mobile.net +azureedge.net +azurefd.net +azurestaticapps.net +1.azurestaticapps.net +2.azurestaticapps.net +3.azurestaticapps.net +4.azurestaticapps.net +5.azurestaticapps.net +6.azurestaticapps.net +7.azurestaticapps.net +centralus.azurestaticapps.net +eastasia.azurestaticapps.net +eastus2.azurestaticapps.net +westeurope.azurestaticapps.net +westus2.azurestaticapps.net +azurewebsites.net +cloudapp.net +trafficmanager.net +blob.core.windows.net +servicebus.windows.net + +// MikroTik : https://mikrotik.com +// Submitted by MikroTik SysAdmin Team +routingthecloud.com +sn.mynetname.net +routingthecloud.net +routingthecloud.org + +// minion.systems : http://minion.systems +// Submitted by Robert Böttinger +csx.cc + +// Mittwald CM Service GmbH & Co. KG : https://mittwald.de +// Submitted by Marco Rieger +mydbserver.com +webspaceconfig.de +mittwald.info +mittwaldserver.info +typo3server.info +project.space + +// MODX Systems LLC : https://modx.com +// Submitted by Elizabeth Southwell +modx.dev + +// Mozilla Foundation : https://mozilla.org/ +// Submitted by glob +bmoattachments.org + +// MSK-IX : https://www.msk-ix.ru/ +// Submitted by Khannanov Roman +net.ru +org.ru +pp.ru + +// Mythic Beasts : https://www.mythic-beasts.com +// Submitted by Paul Cammish +hostedpi.com +caracal.mythic-beasts.com +customer.mythic-beasts.com +fentiger.mythic-beasts.com +lynx.mythic-beasts.com +ocelot.mythic-beasts.com +oncilla.mythic-beasts.com +onza.mythic-beasts.com +sphinx.mythic-beasts.com +vs.mythic-beasts.com +x.mythic-beasts.com +yali.mythic-beasts.com +cust.retrosnub.co.uk + +// Nabu Casa : https://www.nabucasa.com +// Submitted by Paulus Schoutsen +ui.nabu.casa + +// Net at Work Gmbh : https://www.netatwork.de +// Submitted by Jan Jaeschke +cloud.nospamproxy.com +o365.cloud.nospamproxy.com + +// Net libre : https://www.netlib.re +// Submitted by Philippe PITTOLI +netlib.re + +// Netfy Domains : https://netfy.domains +// Submitted by Suranga Ranasinghe +netfy.app + +// Netlify : https://www.netlify.com +// Submitted by Jessica Parsons +netlify.app + +// Neustar Inc. +// Submitted by Trung Tran +4u.com + +// NFSN, Inc. : https://www.NearlyFreeSpeech.NET/ +// Submitted by Jeff Wheelhouse +nfshost.com + +// NFT.Storage : https://nft.storage/ +// Submitted by Vasco Santos or +ipfs.nftstorage.link + +// NGO.US Registry : https://nic.ngo.us +// Submitted by Alstra Solutions Ltd. Networking Team +ngo.us + +// ngrok : https://ngrok.com/ +// Submitted by Alan Shreve +ngrok.app +ngrok-free.app +ngrok.dev +ngrok-free.dev +ngrok.io +ap.ngrok.io +au.ngrok.io +eu.ngrok.io +in.ngrok.io +jp.ngrok.io +sa.ngrok.io +us.ngrok.io +ngrok.pizza +ngrok.pro + +// Nicolaus Copernicus University in Torun - MSK TORMAN : https://www.man.torun.pl +torun.pl + +// Nimbus Hosting Ltd. : https://www.nimbushosting.co.uk/ +// Submitted by Nicholas Ford +nh-serv.co.uk +nimsite.uk + +// No-IP.com : https://noip.com/ +// Submitted by Deven Reza +mmafan.biz +myftp.biz +no-ip.biz +no-ip.ca +fantasyleague.cc +gotdns.ch +3utilities.com +blogsyte.com +ciscofreak.com +damnserver.com +ddnsking.com +ditchyourip.com +dnsiskinky.com +dynns.com +geekgalaxy.com +health-carereform.com +homesecuritymac.com +homesecuritypc.com +myactivedirectory.com +mysecuritycamera.com +myvnc.com +net-freaks.com +onthewifi.com +point2this.com +quicksytes.com +securitytactics.com +servebeer.com +servecounterstrike.com +serveexchange.com +serveftp.com +servegame.com +servehalflife.com +servehttp.com +servehumour.com +serveirc.com +servemp3.com +servep2p.com +servepics.com +servequake.com +servesarcasm.com +stufftoread.com +unusualperson.com +workisboring.com +dvrcam.info +ilovecollege.info +no-ip.info +brasilia.me +ddns.me +dnsfor.me +hopto.me +loginto.me +noip.me +webhop.me +bounceme.net +ddns.net +eating-organic.net +mydissent.net +myeffect.net +mymediapc.net +mypsx.net +mysecuritycamera.net +nhlfan.net +no-ip.net +pgafan.net +privatizehealthinsurance.net +redirectme.net +serveblog.net +serveminecraft.net +sytes.net +cable-modem.org +collegefan.org +couchpotatofries.org +hopto.org +mlbfan.org +myftp.org +mysecuritycamera.org +nflfan.org +no-ip.org +read-books.org +ufcfan.org +zapto.org +no-ip.co.uk +golffan.us +noip.us +pointto.us + +// NodeArt : https://nodeart.io +// Submitted by Konstantin Nosov +stage.nodeart.io + +// Noop : https://noop.app +// Submitted by Nathaniel Schweinberg +*.developer.app +noop.app + +// Northflank Ltd. : https://northflank.com/ +// Submitted by Marco Suter +*.northflank.app +*.build.run +*.code.run +*.database.run +*.migration.run + +// Noticeable : https://noticeable.io +// Submitted by Laurent Pellegrino +noticeable.news + +// Notion Labs, Inc : https://www.notion.so/ +// Submitted by Jess Yao +notion.site + +// Now-DNS : https://now-dns.com +// Submitted by Steve Russell +dnsking.ch +mypi.co +myiphost.com +forumz.info +soundcast.me +tcp4.me +dnsup.net +hicam.net +now-dns.net +ownip.net +vpndns.net +dynserv.org +now-dns.org +x443.pw +ntdll.top +freeddns.us + +// nsupdate.info : https://www.nsupdate.info/ +// Submitted by Thomas Waldmann +nsupdate.info +nerdpol.ovh + +// NYC.mn : https://dot.nyc.mn/ +// Submitted by NYC.mn Subdomain Service +nyc.mn + +// O3O.Foundation : https://o3o.foundation/ +// Submitted by the prvcy.page Registry Team +prvcy.page + +// Obl.ong : https://obl.ong +// Submitted by Reese Armstrong +obl.ong + +// Observable, Inc. : https://observablehq.com +// Submitted by Mike Bostock +observablehq.cloud +static.observableusercontent.com + +// OMG.LOL : https://omg.lol +// Submitted by Adam Newbold +omg.lol + +// Omnibond Systems, LLC. : https://www.omnibond.com +// Submitted by Cole Estep +cloudycluster.net + +// OmniWe Limited : https://omniwe.com +// Submitted by Vicary Archangel +omniwe.site + +// One.com : https://www.one.com/ +// Submitted by Jacob Bunk Nielsen +123webseite.at +123website.be +simplesite.com.br +123website.ch +simplesite.com +123webseite.de +123hjemmeside.dk +123miweb.es +123kotisivu.fi +123siteweb.fr +simplesite.gr +123homepage.it +123website.lu +123website.nl +123hjemmeside.no +service.one +simplesite.pl +123paginaweb.pt +123minsida.se + +// ONID : https://get.onid.ca +// Submitted by ONID Engineering Team +onid.ca + +// Open Domains : https://open-domains.net +// Submitted by William Harrison +is-a-fullstack.dev +is-cool.dev +is-not-a.dev +localplayer.dev +is-local.org + +// Open Social : https://www.getopensocial.com/ +// Submitted by Alexander Varwijk +opensocial.site + +// OpenCraft GmbH : http://opencraft.com/ +// Submitted by Sven Marnach +opencraft.hosting + +// OpenHost : https://registry.openhost.uk +// Submitted by OpenHost Registry Team +16-b.it +32-b.it +64-b.it + +// OpenResearch GmbH : https://openresearch.com/ +// Submitted by Philipp Schmid +orsites.com + +// Opera Software, A.S.A. +// Submitted by Yngve Pettersen +operaunite.com + +// Oracle Dyn : https://cloud.oracle.com/home https://dyn.com/dns/ +// Submitted by Gregory Drake +// Note: This is intended to also include customer-oci.com due to wildcards implicitly including the current label +*.customer-oci.com +*.oci.customer-oci.com +*.ocp.customer-oci.com +*.ocs.customer-oci.com +*.oraclecloudapps.com +*.oraclegovcloudapps.com +*.oraclegovcloudapps.uk + +// Orange : https://www.orange.com +// Submitted by Alexandre Linte +tech.orange + +// OsSav Technology Ltd. : https://ossav.com/ +// Submitted by OsSav Technology Ltd. +// https://nic.can.re +can.re + +// Oursky Limited : https://authgear.com/ +// Submitted by Authgear Team & Skygear Developer +authgear-staging.com +authgearapps.com +skygearapp.com + +// OutSystems +// Submitted by Duarte Santos +outsystemscloud.com + +// OVHcloud : https://ovhcloud.com +// Submitted by Vincent Cassé +*.hosting.ovh.net +*.webpaas.ovh.net + +// OwnProvider GmbH : http://www.ownprovider.com +// Submitted by Jan Moennich +ownprovider.com +own.pm + +// OwO : https://whats-th.is/ +// Submitted by Dean Sheather +*.owo.codes + +// OX : http://www.ox.rs +// Submitted by Adam Grand +ox.rs + +// oy.lc +// Submitted by Charly Coste +oy.lc + +// Pagefog : https://pagefog.com/ +// Submitted by Derek Myers +pgfog.com + +// PageXL : https://pagexl.com +// Submitted by Yann Guichard +pagexl.com + +// Pantheon Systems, Inc. : https://pantheon.io/ +// Submitted by Gary Dylina +gotpantheon.com +pantheonsite.io + +// Paywhirl, Inc : https://paywhirl.com/ +// Submitted by Daniel Netzer +*.paywhirl.com + +// pcarrier.ca Software Inc : https://pcarrier.ca/ +// Submitted by Pierre Carrier +*.xmit.co +xmit.dev +madethis.site +srv.us +gh.srv.us +gl.srv.us + +// PE Ulyanov Kirill Sergeevich : https://airy.host +// Submitted by Kirill Ulyanov +lk3.ru + +// Peplink | Pepwave : http://peplink.com/ +// Submitted by Steve Leung +mypep.link + +// Perspecta : https://perspecta.com/ +// Submitted by Kenneth Van Alstyne +perspecta.cloud + +// Planet-Work : https://www.planet-work.com/ +// Submitted by Frédéric VANNIÈRE +on-web.fr + +// Platform.sh : https://platform.sh +// Submitted by Nikola Kotur +*.upsun.app +upsunapp.com +ent.platform.sh +eu.platform.sh +us.platform.sh +*.platformsh.site +*.tst.site + +// Platter : https://platter.dev +// Submitted by Patrick Flor +platter-app.dev +platterp.us + +// Pley AB : https://www.pley.com/ +// Submitted by Henning Pohl +pley.games + +// Porter : https://porter.run/ +// Submitted by Rudraksh MK +onporter.run + +// Positive Codes Technology Company : http://co.bn/faq.html +// Submitted by Zulfais +co.bn + +// Postman, Inc : https://postman.com +// Submitted by Rahul Dhawan +postman-echo.com +pstmn.io +mock.pstmn.io +httpbin.org + +// prequalifyme.today : https://prequalifyme.today +// Submitted by DeepakTiwari deepak@ivylead.io +prequalifyme.today + +// prgmr.com : https://prgmr.com/ +// Submitted by Sarah Newman +xen.prgmr.com + +// priv.at : http://www.nic.priv.at/ +// Submitted by registry +priv.at + +// PROJECT ELIV : https://eliv.kr/ +// Submitted by PROJECT ELIV Domain Team +c01.kr +eliv-dns.kr +mmv.kr +vki.kr + +// project-study : https://project-study.com +// Submitted by yumenewa +dev.project-study.com + +// Protonet GmbH : http://protonet.io +// Submitted by Martin Meier +protonet.io + +// PSL Sandbox : https://psl.hrsn.dev +// Submitted by William Harrison +sub.psl.hrsn.dev +*.wc.psl.hrsn.dev +!ignored.wc.psl.hrsn.dev +*.sub.wc.psl.hrsn.dev +!ignored.sub.wc.psl.hrsn.dev + +// Publication Presse Communication SARL : https://ppcom.fr +// Submitted by Yaacov Akiba Slama +chirurgiens-dentistes-en-france.fr +byen.site + +// pubtls.org : https://www.pubtls.org +// Submitted by Kor Nielsen +pubtls.org + +// PythonAnywhere LLP : https://www.pythonanywhere.com +// Submitted by Giles Thomas +pythonanywhere.com +eu.pythonanywhere.com + +// QA2 +// Submitted by Daniel Dent : https://www.danieldent.com/ +qa2.com + +// QCX +// Submitted by Cassandra Beelen +qcx.io +*.sys.qcx.io + +// QNAP System Inc : https://www.qnap.com +// Submitted by Nick Chang +myqnapcloud.cn +alpha-myqnapcloud.com +dev-myqnapcloud.com +mycloudnas.com +mynascloud.com +myqnapcloud.com + +// QOTO, Org. +// Submitted by Jeffrey Phillips Freeman +qoto.io + +// Qualifio : https://qualifio.com/ +// Submitted by Xavier De Cock +qualifioapp.com + +// Quality Unit : https://qualityunit.com +// Submitted by Vasyl Tsalko +ladesk.com + +// QuickBackend : https://www.quickbackend.com +// Submitted by Dani Biro +qbuser.com + +// Quip : https://quip.com +// Submitted by Patrick Linehan +*.quipelements.com + +// Qutheory LLC : http://qutheory.io +// Submitted by Jonas Schwartz +vapor.cloud +vaporcloud.io + +// Rackmaze LLC : https://www.rackmaze.com +// Submitted by Kirill Pertsev +rackmaze.com +rackmaze.net + +// Rad Web Hosting : https://radwebhosting.com +// Submitted by Scott Claeys +cloudsite.builders +myradweb.net +servername.us + +// Radix FZC : http://domains.in.net +// Submitted by Gavin Brown +web.in +in.net + +// Raidboxes GmbH : https://raidboxes.de +// Submitted by Auke Tembrink +myrdbx.io +site.rb-hosting.io + +// Rancher Labs, Inc : https://rancher.com +// Submitted by Vincent Fiduccia +*.on-rancher.cloud +*.on-k3s.io +*.on-rio.io + +// RavPage : https://www.ravpage.co.il +// Submitted by Roni Horowitz +ravpage.co.il + +// Read The Docs, Inc : https://www.readthedocs.org +// Submitted by David Fischer +readthedocs-hosted.com +readthedocs.io + +// Red Hat, Inc. OpenShift : https://openshift.redhat.com/ +// Submitted by Tim Kramer +rhcloud.com + +// Redgate Software : https://red-gate.com +// Submitted by Andrew Farries +instances.spawn.cc + +// Render : https://render.com +// Submitted by Anurag Goel +onrender.com +app.render.com + +// Repl.it : https://repl.it +// Submitted by Lincoln Bergeson +replit.app +id.replit.app +firewalledreplit.co +id.firewalledreplit.co +repl.co +id.repl.co +replit.dev +archer.replit.dev +bones.replit.dev +canary.replit.dev +global.replit.dev +hacker.replit.dev +id.replit.dev +janeway.replit.dev +kim.replit.dev +kira.replit.dev +kirk.replit.dev +odo.replit.dev +paris.replit.dev +picard.replit.dev +pike.replit.dev +prerelease.replit.dev +reed.replit.dev +riker.replit.dev +sisko.replit.dev +spock.replit.dev +staging.replit.dev +sulu.replit.dev +tarpit.replit.dev +teams.replit.dev +tucker.replit.dev +wesley.replit.dev +worf.replit.dev +repl.run + +// Resin.io : https://resin.io +// Submitted by Tim Perry +resindevice.io +devices.resinstaging.io + +// RethinkDB : https://www.rethinkdb.com/ +// Submitted by Chris Kastorff +hzc.io + +// Rico Developments Limited : https://adimo.co +// Submitted by Colin Brown +adimo.co.uk + +// Riseup Networks : https://riseup.net +// Submitted by Micah Anderson +itcouldbewor.se + +// Roar Domains LLC : https://roar.basketball/ +// Submitted by Gavin Brown +aus.basketball +nz.basketball + +// ROBOT PAYMENT INC. : https://www.robotpayment.co.jp/ +// Submitted by Kentaro Takamori +subsc-pay.com +subsc-pay.net + +// Rochester Institute of Technology : http://www.rit.edu/ +// Submitted by Jennifer Herting +git-pages.rit.edu + +// Rocky Enterprise Software Foundation : https://resf.org +// Submitted by Neil Hanlon +rocky.page + +// Ruhr University Bochum : https://www.ruhr-uni-bochum.de/ +// Submitted by Andreas Jobs +rub.de +ruhr-uni-bochum.de +io.noc.ruhr-uni-bochum.de + +// Rusnames Limited : http://rusnames.ru/ +// Submitted by Sergey Zotov +биз.рус +ком.рус +крым.рус +мир.рус +мск.рус +орг.рус +самара.рус +сочи.рус +спб.рус +я.рус + +// Russian Academy of Sciences +// Submitted by Tech Support +ras.ru + +// Sakura Frp : https://www.natfrp.com +// Submitted by Bobo Liu +nyat.app + +// SAKURA Internet Inc. : https://www.sakura.ad.jp/ +// Submitted by Internet Service Department +180r.com +dojin.com +sakuratan.com +sakuraweb.com +x0.com +2-d.jp +bona.jp +crap.jp +daynight.jp +eek.jp +flop.jp +halfmoon.jp +jeez.jp +matrix.jp +mimoza.jp +ivory.ne.jp +mail-box.ne.jp +mints.ne.jp +mokuren.ne.jp +opal.ne.jp +sakura.ne.jp +sumomo.ne.jp +topaz.ne.jp +netgamers.jp +nyanta.jp +o0o0.jp +rdy.jp +rgr.jp +rulez.jp +s3.isk01.sakurastorage.jp +s3.isk02.sakurastorage.jp +saloon.jp +sblo.jp +skr.jp +tank.jp +uh-oh.jp +undo.jp +rs.webaccel.jp +user.webaccel.jp +websozai.jp +xii.jp +squares.net +jpn.org +kirara.st +x0.to +from.tv +sakura.tv + +// Salesforce.com, Inc. : https://salesforce.com/ +// Submitted by Salesforce Public Suffix List Team +*.builder.code.com +*.dev-builder.code.com +*.stg-builder.code.com +*.001.test.code-builder-stg.platform.salesforce.com +*.d.crm.dev +*.w.crm.dev +*.wa.crm.dev +*.wb.crm.dev +*.wc.crm.dev +*.wd.crm.dev +*.we.crm.dev +*.wf.crm.dev + +// Sandstorm Development Group, Inc. : https://sandcats.io/ +// Submitted by Asheesh Laroia +sandcats.io + +// SBE network solutions GmbH : https://www.sbe.de/ +// Submitted by Norman Meilick +logoip.com +logoip.de + +// Scaleway : https://www.scaleway.com/ +// Submitted by Rémy Léone +fr-par-1.baremetal.scw.cloud +fr-par-2.baremetal.scw.cloud +nl-ams-1.baremetal.scw.cloud +cockpit.fr-par.scw.cloud +fnc.fr-par.scw.cloud +functions.fnc.fr-par.scw.cloud +k8s.fr-par.scw.cloud +nodes.k8s.fr-par.scw.cloud +s3.fr-par.scw.cloud +s3-website.fr-par.scw.cloud +whm.fr-par.scw.cloud +priv.instances.scw.cloud +pub.instances.scw.cloud +k8s.scw.cloud +cockpit.nl-ams.scw.cloud +k8s.nl-ams.scw.cloud +nodes.k8s.nl-ams.scw.cloud +s3.nl-ams.scw.cloud +s3-website.nl-ams.scw.cloud +whm.nl-ams.scw.cloud +cockpit.pl-waw.scw.cloud +k8s.pl-waw.scw.cloud +nodes.k8s.pl-waw.scw.cloud +s3.pl-waw.scw.cloud +s3-website.pl-waw.scw.cloud +scalebook.scw.cloud +smartlabeling.scw.cloud +dedibox.fr + +// schokokeks.org GbR : https://schokokeks.org/ +// Submitted by Hanno Böck +schokokeks.net + +// Scottish Government : https://www.gov.scot +// Submitted by Martin Ellis +gov.scot +service.gov.scot + +// Scry Security : http://www.scrysec.com +// Submitted by Shante Adam +scrysec.com + +// Scrypted : https://scrypted.app +// Submitted by Koushik Dutta +client.scrypted.io + +// Securepoint GmbH : https://www.securepoint.de +// Submitted by Erik Anders +firewall-gateway.com +firewall-gateway.de +my-gateway.de +my-router.de +spdns.de +spdns.eu +firewall-gateway.net +my-firewall.org +myfirewall.org +spdns.org + +// Seidat : https://www.seidat.com +// Submitted by Artem Kondratev +seidat.net + +// Sellfy : https://sellfy.com +// Submitted by Yuriy Romadin +sellfy.store + +// Sendmsg : https://www.sendmsg.co.il +// Submitted by Assaf Stern +minisite.ms + +// Senseering GmbH : https://www.senseering.de +// Submitted by Felix Mönckemeyer +senseering.net + +// Servebolt AS : https://servebolt.com +// Submitted by Daniel Kjeserud +servebolt.cloud + +// Service Online LLC : http://drs.ua/ +// Submitted by Serhii Bulakh +biz.ua +co.ua +pp.ua + +// Shanghai Accounting Society : https://www.sasf.org.cn +// Submitted by Information Administration +as.sh.cn + +// Sheezy.Art : https://sheezy.art +// Submitted by Nyoom +sheezy.games + +// Shopblocks : http://www.shopblocks.com/ +// Submitted by Alex Bowers +myshopblocks.com + +// Shopify : https://www.shopify.com +// Submitted by Alex Richter +myshopify.com + +// Shopit : https://www.shopitcommerce.com/ +// Submitted by Craig McMahon +shopitsite.com + +// shopware AG : https://shopware.com +// Submitted by Jens Küper +shopware.shop +shopware.store + +// Siemens Mobility GmbH +// Submitted by Oliver Graebner +mo-siemens.io + +// SinaAppEngine : http://sae.sina.com.cn/ +// Submitted by SinaAppEngine +1kapp.com +appchizi.com +applinzi.com +sinaapp.com +vipsinaapp.com + +// Siteleaf : https://www.siteleaf.com/ +// Submitted by Skylar Challand +siteleaf.net + +// Small Technology Foundation : https://small-tech.org +// Submitted by Aral Balkan +small-web.org + +// Smallregistry by Promopixel SARL : https://www.smallregistry.net +// Former AFNIC's SLDs +// Submitted by Jérôme Lipowicz +aeroport.fr +avocat.fr +chambagri.fr +chirurgiens-dentistes.fr +experts-comptables.fr +medecin.fr +notaires.fr +pharmacien.fr +port.fr +veterinaire.fr + +// Smoove.io : https://www.smoove.io/ +// Submitted by Dan Kozak +vp4.me + +// Snowflake Inc : https://www.snowflake.com/ +// Submitted by Sam Haar +*.snowflake.app +*.privatelink.snowflake.app +streamlit.app +streamlitapp.com + +// Snowplow Analytics : https://snowplowanalytics.com/ +// Submitted by Ian Streeter +try-snowplow.com + +// Software Consulting Michal Zalewski : https://www.mafelo.com +// Submitted by Michal Zalewski +mafelo.net + +// Sony Interactive Entertainment LLC : https://sie.com/ +// Submitted by David Coles +playstation-cloud.com + +// SourceHut : https://sourcehut.org +// Submitted by Drew DeVault +srht.site + +// SourceLair PC : https://www.sourcelair.com +// Submitted by Antonis Kalipetis +apps.lair.io +*.stolos.io + +// SparrowHost : https://sparrowhost.in/ +// Submitted by Anant Pandey +ind.mom + +// SpeedPartner GmbH : https://www.speedpartner.de/ +// Submitted by Stefan Neufeind +customer.speedpartner.de + +// Spreadshop (sprd.net AG) : https://www.spreadshop.com/ +// Submitted by Martin Breest +myspreadshop.at +myspreadshop.com.au +myspreadshop.be +myspreadshop.ca +myspreadshop.ch +myspreadshop.com +myspreadshop.de +myspreadshop.dk +myspreadshop.es +myspreadshop.fi +myspreadshop.fr +myspreadshop.ie +myspreadshop.it +myspreadshop.net +myspreadshop.nl +myspreadshop.no +myspreadshop.pl +myspreadshop.se +myspreadshop.co.uk + +// StackBlitz : https://stackblitz.com +// Submitted by Dominic Elm +w-corp-staticblitz.com +w-credentialless-staticblitz.com +w-staticblitz.com + +// Stackhero : https://www.stackhero.io +// Submitted by Adrien Gillon +stackhero-network.com + +// STACKIT GmbH & Co. KG : https://www.stackit.de/en/ +// Submitted by STACKIT-DNS Team (Simon Stier) +runs.onstackit.cloud +stackit.gg +stackit.rocks +stackit.run +stackit.zone + +// Staclar : https://staclar.com +// Submitted by Q Misell +// Submitted by Matthias Merkel +musician.io +novecore.site + +// Standard Library : https://stdlib.com +// Submitted by Jacob Lee +api.stdlib.com + +// stereosense GmbH : https://www.involve.me +// Submitted by Florian Burmann +feedback.ac +forms.ac +assessments.cx +calculators.cx +funnels.cx +paynow.cx +quizzes.cx +researched.cx +tests.cx +surveys.so + +// Storacha Network : https://storacha.network +// Submitted by Alan Shaw +ipfs.storacha.link +ipfs.w3s.link + +// Storebase : https://www.storebase.io +// Submitted by Tony Schirmer +storebase.store + +// Storipress : https://storipress.com +// Submitted by Benno Liu +storipress.app + +// Storj Labs Inc. : https://storj.io/ +// Submitted by Philip Hutchins +storj.farm + +// Strapi : https://strapi.io/ +// Submitted by Florent Baldino +strapiapp.com +media.strapiapp.com + +// Strategic System Consulting (eApps Hosting) : https://www.eapps.com/ +// Submitted by Alex Oancea +vps-host.net +atl.jelastic.vps-host.net +njs.jelastic.vps-host.net +ric.jelastic.vps-host.net + +// Streak : https://streak.com +// Submitted by Blake Kadatz +streak-link.com +streaklinks.com +streakusercontent.com + +// Student-Run Computing Facility : https://www.srcf.net/ +// Submitted by Edwin Balani +soc.srcf.net +user.srcf.net + +// Studenten Net Twente : http://www.snt.utwente.nl/ +// Submitted by Silke Hofstra +utwente.io + +// Sub 6 Limited : http://www.sub6.com +// Submitted by Dan Miller +temp-dns.com + +// Supabase : https://supabase.io +// Submitted by Inian Parameshwaran +supabase.co +supabase.in +supabase.net + +// Syncloud : https://syncloud.org +// Submitted by Boris Rybalkin +syncloud.it + +// Synology, Inc. : https://www.synology.com/ +// Submitted by Rony Weng +dscloud.biz +direct.quickconnect.cn +dsmynas.com +familyds.com +diskstation.me +dscloud.me +i234.me +myds.me +synology.me +dscloud.mobi +dsmynas.net +familyds.net +dsmynas.org +familyds.org +direct.quickconnect.to +vpnplus.to + +// Tabit Technologies Ltd. : https://tabit.cloud/ +// Submitted by Oren Agiv +mytabit.com +mytabit.co.il +tabitorder.co.il + +// TAIFUN Software AG : http://taifun-software.de +// Submitted by Bjoern Henke +taifun-dns.de + +// Tailscale Inc. : https://www.tailscale.com +// Submitted by David Anderson +ts.net +*.c.ts.net + +// TASK geographical domains : https://task.gda.pl/en/services/for-entrepreneurs/ +gda.pl +gdansk.pl +gdynia.pl +med.pl +sopot.pl + +// Tave Creative Corp : https://tave.com/ +// Submitted by Adrian Ziemkowski +taveusercontent.com + +// tawk.to, Inc : https://www.tawk.to +// Submitted by tawk.to developer team +p.tawk.email +p.tawkto.email + +// team.blue : https://team.blue +// Submitted by Cedric Dubois +site.tb-hosting.com + +// Teckids e.V. : https://www.teckids.org +// Submitted by Dominik George +edugit.io +s3.teckids.org + +// Telebit : https://telebit.cloud +// Submitted by AJ ONeal +telebit.app +telebit.io +*.telebit.xyz + +// Thingdust AG : https://thingdust.com/ +// Submitted by Adrian Imboden +*.firenet.ch +*.svc.firenet.ch +reservd.com +thingdustdata.com +cust.dev.thingdust.io +reservd.dev.thingdust.io +cust.disrec.thingdust.io +reservd.disrec.thingdust.io +cust.prod.thingdust.io +cust.testing.thingdust.io +reservd.testing.thingdust.io + +// ticket i/O GmbH : https://ticket.io +// Submitted by Christian Franke +tickets.io + +// Tlon.io : https://tlon.io +// Submitted by Mark Staarink +arvo.network +azimuth.network +tlon.network + +// Tor Project, Inc. : https://torproject.org +// Submitted by Antoine Beaupré +torproject.net +pages.torproject.net + +// TownNews.com : http://www.townnews.com +// Submitted by Dustin Ward +townnews-staging.com + +// TrafficPlex GmbH : https://www.trafficplex.de/ +// Submitted by Phillipp Röll +12hp.at +2ix.at +4lima.at +lima-city.at +12hp.ch +2ix.ch +4lima.ch +lima-city.ch +trafficplex.cloud +de.cool +12hp.de +2ix.de +4lima.de +lima-city.de +1337.pictures +clan.rip +lima-city.rocks +webspace.rocks +lima.zone + +// TransIP : https://www.transip.nl +// Submitted by Rory Breuk and Cedric Dubois +*.transurl.be +*.transurl.eu +site.transip.me +*.transurl.nl + +// TuxFamily : http://tuxfamily.org +// Submitted by TuxFamily administrators +tuxfamily.org + +// TwoDNS : https://www.twodns.de/ +// Submitted by TwoDNS-Support +dd-dns.de +dray-dns.de +draydns.de +dyn-vpn.de +dynvpn.de +mein-vigor.de +my-vigor.de +my-wan.de +syno-ds.de +synology-diskstation.de +synology-ds.de +diskstation.eu +diskstation.org + +// Typedream : https://typedream.com +// Submitted by Putri Karunia +typedream.app + +// Typeform : https://www.typeform.com +// Submitted by Typeform +pro.typeform.com + +// Uberspace : https://uberspace.de +// Submitted by Moritz Werner +*.uberspace.de +uber.space + +// UDR Limited : http://www.udr.hk.com +// Submitted by registry +hk.com +inc.hk +ltd.hk +hk.org + +// UK Intis Telecom LTD : https://it.com +// Submitted by ITComdomains +it.com + +// Unison Computing, PBC : https://unison.cloud +// Submitted by Simon Højberg +unison-services.cloud + +// United Gameserver GmbH : https://united-gameserver.de +// Submitted by Stefan Schwarz +virtual-user.de +virtualuser.de + +// United States Writing Corporation : https://uswriting.co +// Submitted by Andrew Sampson +obj.ag + +// UNIVERSAL DOMAIN REGISTRY : https://www.udr.org.yt/ +// see also: whois -h whois.udr.org.yt help +// Submitted by Atanunu Igbunuroghene +name.pm +sch.tf +biz.wf +sch.wf +org.yt + +// University of Banja Luka : https://unibl.org +// Domains for Republic of Srpska administrative entity. +// Submitted by Marko Ivanovic +rs.ba + +// University of Bielsko-Biala regional domain : http://dns.bielsko.pl/ +// Submitted by Marcin +bielsko.pl + +// urown.net : https://urown.net +// Submitted by Hostmaster +urown.cloud +dnsupdate.info + +// US REGISTRY LLC : http://us.org +// Submitted by Gavin Brown +us.org + +// V.UA Domain Administrator : https://domain.v.ua/ +// Submitted by Serhii Rostilo +v.ua + +// Val Town, Inc : https://val.town/ +// Submitted by Tom MacWright +val.run +web.val.run + +// Vercel, Inc : https://vercel.com/ +// Submitted by Max Leiter +vercel.app +v0.build +vercel.dev +vusercontent.net +now.sh + +// VeryPositive SIA : http://very.lv +// Submitted by Danko Aleksejevs +2038.io + +// Virtual-Info : https://www.virtual-info.info/ +// Submitted by Adnan RIHAN +v-info.info + +// Viva Republica, Inc. : https://toss.im/ +// Submitted by Deus Team +deus-canvas.com + +// Voorloper.com : https://voorloper.com +// Submitted by Nathan van Bakel +voorloper.cloud + +// Vultr Objects : https://www.vultr.com/products/object-storage/ +// Submitted by Niels Maumenee +*.vultrobjects.com + +// Waffle Computer Inc., Ltd. : https://docs.waffleinfo.com +// Submitted by Masayuki Note +wafflecell.com + +// Webflow, Inc. : https://www.webflow.com +// Submitted by Webflow Security Team +webflow.io +webflowtest.io + +// WebHare bv : https://www.webhare.com/ +// Submitted by Arnold Hendriks +*.webhare.dev + +// WebHotelier Technologies Ltd : https://www.webhotelier.net/ +// Submitted by Apostolos Tsakpinis +bookonline.app +hotelwithflight.com +reserve-online.com +reserve-online.net + +// WebPros International, LLC : https://webpros.com/ +// Submitted by Nicolas Rochelemagne +cprapid.com +pleskns.com +wp2.host +pdns.page +plesk.page +cpanel.site +wpsquared.site + +// WebWaddle Ltd : https://webwaddle.com/ +// Submitted by Merlin Glander +*.wadl.top + +// Western Digital Technologies, Inc : https://www.wdc.com +// Submitted by Jung Jin +remotewd.com + +// Whatbox Inc. : https://whatbox.ca/ +// Submitted by Anthony Ryan +box.ca + +// WIARD Enterprises : https://wiardweb.com +// Submitted by Kidd Hustle +pages.wiardweb.com + +// Wikimedia Labs : https://wikitech.wikimedia.org +// Submitted by Arturo Borrero Gonzalez +toolforge.org +wmcloud.org +wmflabs.org + +// William Harrison : https://wharrison.com.au +// Submitted by William Harrison +wdh.app + +// Windsurf : https://windsurf.com +// Submitted by Douglas Chen +windsurf.app +windsurf.build + +// WISP : https://wisp.gg +// Submitted by Stepan Fedotov +panel.gg +daemon.panel.gg + +// Wix.com, Inc. : https://www.wix.com +// Submitted by Shahar Talmi / Alon Kochba +wixsite.com +wixstudio.com +editorx.io +wixstudio.io +wix.run + +// Wizard Zines : https://wizardzines.com +// Submitted by Julia Evans +messwithdns.com + +// WoltLab GmbH : https://www.woltlab.com +// Submitted by Tim Düsterhus +woltlab-demo.com +myforum.community +community-pro.de +diskussionsbereich.de +community-pro.net +meinforum.net + +// Woods Valldata : https://www.woodsvalldata.co.uk/ +// Submitted by Chris Whittle +affinitylottery.org.uk +raffleentry.org.uk +weeklylottery.org.uk + +// WP Engine : https://wpengine.com/ +// Submitted by Michael Smith +// Submitted by Brandon DuRette +wpenginepowered.com +js.wpenginepowered.com + +// XenonCloud GbR : https://xenoncloud.net +// Submitted by Julian Uphoff +half.host + +// XnBay Technology : http://www.xnbay.com/ +// Submitted by XnBay Developer +xnbay.com +u2.xnbay.com +u2-local.xnbay.com + +// XS4ALL Internet bv : https://www.xs4all.nl/ +// Submitted by Daniel Mostertman +cistron.nl +demon.nl +xs4all.space + +// Yandex.Cloud LLC : https://cloud.yandex.com +// Submitted by Alexander Lodin +yandexcloud.net +storage.yandexcloud.net +website.yandexcloud.net + +// YesCourse Pty Ltd : https://yescourse.com +// Submitted by Atul Bhouraskar +official.academy + +// Yola : https://www.yola.com/ +// Submitted by Stefano Rivera +yolasite.com + +// Yunohost : https://yunohost.org +// Submitted by Valentin Grimaud +ynh.fr +nohost.me +noho.st + +// ZaNiC : http://www.za.net/ +// Submitted by registry +za.net +za.org + +// ZAP-Hosting GmbH & Co. KG : https://zap-hosting.com +// Submitted by Julian Alker +zap.cloud + +// Zeabur : https://zeabur.com/ +// Submitted by Zeabur Team +zeabur.app + +// Zerops : https://zerops.io/ +// Submitted by Zerops Team +*.zerops.app + +// Zine EOOD : https://zine.bg/ +// Submitted by Martin Angelov +bss.design + +// Zitcom A/S : https://www.zitcom.dk +// Submitted by Emil Stahl +basicserver.io +virtualserver.io +enterprisecloud.nu + +// Zone.ID: https://zone.id +// Submitted by Gx1.org +zone.id + +// ===END PRIVATE DOMAINS=== diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/lib/public_suffix.rb b/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/lib/public_suffix.rb new file mode 100644 index 00000000..75397d73 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/lib/public_suffix.rb @@ -0,0 +1,177 @@ +# frozen_string_literal: true + +# = Public Suffix +# +# Domain name parser based on the Public Suffix List. +# +# Copyright (c) 2009-2025 Simone Carletti + +require_relative "public_suffix/domain" +require_relative "public_suffix/version" +require_relative "public_suffix/errors" +require_relative "public_suffix/rule" +require_relative "public_suffix/list" + +# PublicSuffix is a Ruby domain name parser based on the Public Suffix List. +# +# The [Public Suffix List](https://publicsuffix.org) is a cross-vendor initiative +# to provide an accurate list of domain name suffixes. +# +# The Public Suffix List is an initiative of the Mozilla Project, +# but is maintained as a community resource. It is available for use in any software, +# but was originally created to meet the needs of browser manufacturers. +module PublicSuffix + + DOT = "." + BANG = "!" + STAR = "*" + + # Parses +name+ and returns the {PublicSuffix::Domain} instance. + # + # @example Parse a valid domain + # PublicSuffix.parse("google.com") + # # => # + # + # @example Parse a valid subdomain + # PublicSuffix.parse("www.google.com") + # # => # + # + # @example Parse a fully qualified domain + # PublicSuffix.parse("google.com.") + # # => # + # + # @example Parse a fully qualified domain (subdomain) + # PublicSuffix.parse("www.google.com.") + # # => # + # + # @example Parse an invalid (unlisted) domain + # PublicSuffix.parse("x.yz") + # # => # + # + # @example Parse an invalid (unlisted) domain with strict checking (without applying the default * rule) + # PublicSuffix.parse("x.yz", default_rule: nil) + # # => PublicSuffix::DomainInvalid: `x.yz` is not a valid domain + # + # @example Parse an URL (not supported, only domains) + # PublicSuffix.parse("http://www.google.com") + # # => PublicSuffix::DomainInvalid: http://www.google.com is not expected to contain a scheme + # + # + # @param name [#to_s] The domain name or fully qualified domain name to parse. + # @param list [PublicSuffix::List] The rule list to search, defaults to the default {PublicSuffix::List} + # @param ignore_private [Boolean] + # @return [PublicSuffix::Domain] + # + # @raise [PublicSuffix::DomainInvalid] If domain is not a valid domain. + # @raise [PublicSuffix::DomainNotAllowed] If a rule for +domain+ is found, but the rule doesn't allow +domain+. + def self.parse(name, list: List.default, default_rule: list.default_rule, ignore_private: false) + what = normalize(name) + raise what if what.is_a?(DomainInvalid) + + rule = list.find(what, default: default_rule, ignore_private: ignore_private) + + # rubocop:disable Style/IfUnlessModifier + if rule.nil? + raise DomainInvalid, "`#{what}` is not a valid domain" + end + if rule.decompose(what).last.nil? + raise DomainNotAllowed, "`#{what}` is not allowed according to Registry policy" + end + + # rubocop:enable Style/IfUnlessModifier + + decompose(what, rule) + end + + # Checks whether +domain+ is assigned and allowed, without actually parsing it. + # + # This method doesn't care whether domain is a domain or subdomain. + # The validation is performed using the default {PublicSuffix::List}. + # + # @example Validate a valid domain + # PublicSuffix.valid?("example.com") + # # => true + # + # @example Validate a valid subdomain + # PublicSuffix.valid?("www.example.com") + # # => true + # + # @example Validate a not-listed domain + # PublicSuffix.valid?("example.tldnotlisted") + # # => true + # + # @example Validate a not-listed domain with strict checking (without applying the default * rule) + # PublicSuffix.valid?("example.tldnotlisted") + # # => true + # PublicSuffix.valid?("example.tldnotlisted", default_rule: nil) + # # => false + # + # @example Validate a fully qualified domain + # PublicSuffix.valid?("google.com.") + # # => true + # PublicSuffix.valid?("www.google.com.") + # # => true + # + # @example Check an URL (which is not a valid domain) + # PublicSuffix.valid?("http://www.example.com") + # # => false + # + # + # @param name [#to_s] The domain name or fully qualified domain name to validate. + # @param ignore_private [Boolean] + # @return [Boolean] + def self.valid?(name, list: List.default, default_rule: list.default_rule, ignore_private: false) + what = normalize(name) + return false if what.is_a?(DomainInvalid) + + rule = list.find(what, default: default_rule, ignore_private: ignore_private) + + !rule.nil? && !rule.decompose(what).last.nil? + end + + # Attempt to parse the name and returns the domain, if valid. + # + # This method doesn't raise. Instead, it returns nil if the domain is not valid for whatever reason. + # + # @param name [#to_s] The domain name or fully qualified domain name to parse. + # @param list [PublicSuffix::List] The rule list to search, defaults to the default {PublicSuffix::List} + # @param ignore_private [Boolean] + # @return [String] + def self.domain(name, **options) + parse(name, **options).domain + rescue PublicSuffix::Error + nil + end + + + # private + + def self.decompose(name, rule) + left, right = rule.decompose(name) + + parts = left.split(DOT) + # If we have 0 parts left, there is just a tld and no domain or subdomain + # If we have 1 part left, there is just a tld, domain and not subdomain + # If we have 2 parts left, the last part is the domain, the other parts (combined) are the subdomain + tld = right + sld = parts.empty? ? nil : parts.pop + trd = parts.empty? ? nil : parts.join(DOT) + + Domain.new(tld, sld, trd) + end + + # Pretend we know how to deal with user input. + def self.normalize(name) + name = name.to_s.dup + name.strip! + name.chomp!(DOT) + name.downcase! + + return DomainInvalid.new("Name is blank") if name.empty? + return DomainInvalid.new("Name starts with a dot") if name.start_with?(DOT) + return DomainInvalid.new(format("%s is not expected to contain a scheme", name)) if name.include?("://") + + name + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/lib/public_suffix/domain.rb b/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/lib/public_suffix/domain.rb new file mode 100644 index 00000000..2b18ed8e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/lib/public_suffix/domain.rb @@ -0,0 +1,235 @@ +# frozen_string_literal: true + +# = Public Suffix +# +# Domain name parser based on the Public Suffix List. +# +# Copyright (c) 2009-2025 Simone Carletti + +module PublicSuffix + + # Domain represents a domain name, composed by a TLD, SLD and TRD. + class Domain + + # Splits a string into the labels, that is the dot-separated parts. + # + # The input is not validated, but it is assumed to be a valid domain name. + # + # @example + # + # name_to_labels('example.com') + # # => ['example', 'com'] + # + # name_to_labels('example.co.uk') + # # => ['example', 'co', 'uk'] + # + # @param name [String, #to_s] The domain name to split. + # @return [Array] + def self.name_to_labels(name) + name.to_s.split(DOT) + end + + + attr_reader :tld, :sld, :trd + + # Creates and returns a new {PublicSuffix::Domain} instance. + # + # @overload initialize(tld) + # Initializes with a +tld+. + # @param [String] tld The TLD (extension) + # @overload initialize(tld, sld) + # Initializes with a +tld+ and +sld+. + # @param [String] tld The TLD (extension) + # @param [String] sld The TRD (domain) + # @overload initialize(tld, sld, trd) + # Initializes with a +tld+, +sld+ and +trd+. + # @param [String] tld The TLD (extension) + # @param [String] sld The SLD (domain) + # @param [String] trd The TRD (subdomain) + # + # @yield [self] Yields on self. + # @yieldparam [PublicSuffix::Domain] self The newly creates instance + # + # @example Initialize with a TLD + # PublicSuffix::Domain.new("com") + # # => # + # + # @example Initialize with a TLD and SLD + # PublicSuffix::Domain.new("com", "example") + # # => # + # + # @example Initialize with a TLD, SLD and TRD + # PublicSuffix::Domain.new("com", "example", "wwww") + # # => # + # + def initialize(*args) + @tld, @sld, @trd = args + yield(self) if block_given? + end + + # Returns a string representation of this object. + # + # @return [String] + def to_s + name + end + + # Returns an array containing the domain parts. + # + # @return [Array] + # + # @example + # + # PublicSuffix::Domain.new("google.com").to_a + # # => [nil, "google", "com"] + # + # PublicSuffix::Domain.new("www.google.com").to_a + # # => [nil, "google", "com"] + # + def to_a + [@trd, @sld, @tld] + end + + # Returns the full domain name. + # + # @return [String] + # + # @example Gets the domain name of a domain + # PublicSuffix::Domain.new("com", "google").name + # # => "google.com" + # + # @example Gets the domain name of a subdomain + # PublicSuffix::Domain.new("com", "google", "www").name + # # => "www.google.com" + # + def name + [@trd, @sld, @tld].compact.join(DOT) + end + + # Returns a domain-like representation of this object + # if the object is a {#domain?}, nil otherwise. + # + # PublicSuffix::Domain.new("com").domain + # # => nil + # + # PublicSuffix::Domain.new("com", "google").domain + # # => "google.com" + # + # PublicSuffix::Domain.new("com", "google", "www").domain + # # => "www.google.com" + # + # This method doesn't validate the input. It handles the domain + # as a valid domain name and simply applies the necessary transformations. + # + # This method returns a FQD, not just the domain part. + # To get the domain part, use #sld (aka second level domain). + # + # PublicSuffix::Domain.new("com", "google", "www").domain + # # => "google.com" + # + # PublicSuffix::Domain.new("com", "google", "www").sld + # # => "google" + # + # @see #domain? + # @see #subdomain + # + # @return [String] + def domain + [@sld, @tld].join(DOT) if domain? + end + + # Returns a subdomain-like representation of this object + # if the object is a {#subdomain?}, nil otherwise. + # + # PublicSuffix::Domain.new("com").subdomain + # # => nil + # + # PublicSuffix::Domain.new("com", "google").subdomain + # # => nil + # + # PublicSuffix::Domain.new("com", "google", "www").subdomain + # # => "www.google.com" + # + # This method doesn't validate the input. It handles the domain + # as a valid domain name and simply applies the necessary transformations. + # + # This method returns a FQD, not just the subdomain part. + # To get the subdomain part, use #trd (aka third level domain). + # + # PublicSuffix::Domain.new("com", "google", "www").subdomain + # # => "www.google.com" + # + # PublicSuffix::Domain.new("com", "google", "www").trd + # # => "www" + # + # @see #subdomain? + # @see #domain + # + # @return [String] + def subdomain + [@trd, @sld, @tld].join(DOT) if subdomain? + end + + # Checks whether self looks like a domain. + # + # This method doesn't actually validate the domain. + # It only checks whether the instance contains + # a value for the {#tld} and {#sld} attributes. + # + # @example + # + # PublicSuffix::Domain.new("com").domain? + # # => false + # + # PublicSuffix::Domain.new("com", "google").domain? + # # => true + # + # PublicSuffix::Domain.new("com", "google", "www").domain? + # # => true + # + # # This is an invalid domain, but returns true + # # because this method doesn't validate the content. + # PublicSuffix::Domain.new("com", nil).domain? + # # => true + # + # @see #subdomain? + # + # @return [Boolean] + def domain? + !(@tld.nil? || @sld.nil?) + end + + # Checks whether self looks like a subdomain. + # + # This method doesn't actually validate the subdomain. + # It only checks whether the instance contains + # a value for the {#tld}, {#sld} and {#trd} attributes. + # If you also want to validate the domain, + # use {#valid_subdomain?} instead. + # + # @example + # + # PublicSuffix::Domain.new("com").subdomain? + # # => false + # + # PublicSuffix::Domain.new("com", "google").subdomain? + # # => false + # + # PublicSuffix::Domain.new("com", "google", "www").subdomain? + # # => true + # + # # This is an invalid domain, but returns true + # # because this method doesn't validate the content. + # PublicSuffix::Domain.new("com", "example", nil).subdomain? + # # => true + # + # @see #domain? + # + # @return [Boolean] + def subdomain? + !(@tld.nil? || @sld.nil? || @trd.nil?) + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/lib/public_suffix/errors.rb b/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/lib/public_suffix/errors.rb new file mode 100644 index 00000000..8b4d0a62 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/lib/public_suffix/errors.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +# = Public Suffix +# +# Domain name parser based on the Public Suffix List. +# +# Copyright (c) 2009-2025 Simone Carletti + +module PublicSuffix + + class Error < StandardError + end + + # Raised when trying to parse an invalid name. + # A name is considered invalid when no rule is found in the definition list. + # + # @example + # + # PublicSuffix.parse("nic.test") + # # => PublicSuffix::DomainInvalid + # + # PublicSuffix.parse("http://www.nic.it") + # # => PublicSuffix::DomainInvalid + # + class DomainInvalid < Error + end + + # Raised when trying to parse a name that matches a suffix. + # + # @example + # + # PublicSuffix.parse("nic.do") + # # => PublicSuffix::DomainNotAllowed + # + # PublicSuffix.parse("www.nic.do") + # # => PublicSuffix::Domain + # + class DomainNotAllowed < DomainInvalid + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/lib/public_suffix/list.rb b/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/lib/public_suffix/list.rb new file mode 100644 index 00000000..06949575 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/lib/public_suffix/list.rb @@ -0,0 +1,247 @@ +# frozen_string_literal: true + +# = Public Suffix +# +# Domain name parser based on the Public Suffix List. +# +# Copyright (c) 2009-2025 Simone Carletti + +module PublicSuffix + + # A {PublicSuffix::List} is a collection of one + # or more {PublicSuffix::Rule}. + # + # Given a {PublicSuffix::List}, + # you can add or remove {PublicSuffix::Rule}, + # iterate all items in the list or search for the first rule + # which matches a specific domain name. + # + # # Create a new list + # list = PublicSuffix::List.new + # + # # Push two rules to the list + # list << PublicSuffix::Rule.factory("it") + # list << PublicSuffix::Rule.factory("com") + # + # # Get the size of the list + # list.size + # # => 2 + # + # # Search for the rule matching given domain + # list.find("example.com") + # # => # + # list.find("example.org") + # # => nil + # + # You can create as many {PublicSuffix::List} you want. + # The {PublicSuffix::List.default} rule list is used + # to tokenize and validate a domain. + # + class List + + DEFAULT_LIST_PATH = File.expand_path("../../data/list.txt", __dir__) + + # Gets the default rule list. + # + # Initializes a new {PublicSuffix::List} parsing the content + # of {PublicSuffix::List.default_list_content}, if required. + # + # @return [PublicSuffix::List] + def self.default(**options) + @default ||= parse(File.read(DEFAULT_LIST_PATH), **options) + end + + # Sets the default rule list to +value+. + # + # @param value [PublicSuffix::List] the new list + # @return [PublicSuffix::List] + def self.default=(value) + @default = value + end + + # Parse given +input+ treating the content as Public Suffix List. + # + # See http://publicsuffix.org/format/ for more details about input format. + # + # @param input [#each_line] the list to parse + # @param private_domains [Boolean] whether to ignore the private domains section + # @return [PublicSuffix::List] + def self.parse(input, private_domains: true) + comment_token = "//" + private_token = "===BEGIN PRIVATE DOMAINS===" + section = nil # 1 == ICANN, 2 == PRIVATE + + new do |list| + input.each_line do |line| + line.strip! + case # rubocop:disable Style/EmptyCaseCondition + + # skip blank lines + when line.empty? + next + + # include private domains or stop scanner + when line.include?(private_token) + break if !private_domains + + section = 2 + + # skip comments + when line.start_with?(comment_token) # rubocop:disable Lint/DuplicateBranch + next + + else + list.add(Rule.factory(line, private: section == 2)) + + end + end + end + end + + + # Initializes an empty {PublicSuffix::List}. + # + # @yield [self] Yields on self. + # @yieldparam [PublicSuffix::List] self The newly created instance. + def initialize + @rules = {} + yield(self) if block_given? + end + + + # Checks whether two lists are equal. + # + # List one is equal to two, if two is an instance of + # {PublicSuffix::List} and each +PublicSuffix::Rule::*+ + # in list one is available in list two, in the same order. + # + # @param other [PublicSuffix::List] the List to compare + # @return [Boolean] + def ==(other) + return false unless other.is_a?(List) + + equal?(other) || @rules == other.rules + end + alias eql? == + + # Iterates each rule in the list. + def each(&block) + Enumerator.new do |y| + @rules.each do |key, node| + y << entry_to_rule(node, key) + end + end.each(&block) + end + + + # Adds the given object to the list and optionally refreshes the rule index. + # + # @param rule [PublicSuffix::Rule::*] the rule to add to the list + # @return [self] + def add(rule) + @rules[rule.value] = rule_to_entry(rule) + self + end + alias << add + + # Gets the number of rules in the list. + # + # @return [Integer] + def size + @rules.size + end + + # Checks whether the list is empty. + # + # @return [Boolean] + def empty? + @rules.empty? + end + + # Removes all rules. + # + # @return [self] + def clear + @rules.clear + self + end + + # Finds and returns the rule corresponding to the longest public suffix for the hostname. + # + # @param name [#to_s] the hostname + # @param default [PublicSuffix::Rule::*] the default rule to return in case no rule matches + # @return [PublicSuffix::Rule::*] + def find(name, default: default_rule, **options) + rule = select(name, **options).inject do |l, r| + return r if r.instance_of?(Rule::Exception) + + l.length > r.length ? l : r + end + rule || default + end + + # Selects all the rules matching given hostame. + # + # If `ignore_private` is set to true, the algorithm will skip the rules that are flagged as + # private domain. Note that the rules will still be part of the loop. + # If you frequently need to access lists ignoring the private domains, + # you should create a list that doesn't include these domains setting the + # `private_domains: false` option when calling {.parse}. + # + # Note that this method is currently private, as you should not rely on it. Instead, + # the public interface is {#find}. The current internal algorithm allows to return all + # matching rules, but different data structures may not be able to do it, and instead would + # return only the match. For this reason, you should rely on {#find}. + # + # @param name [#to_s] the hostname + # @param ignore_private [Boolean] + # @return [Array] + def select(name, ignore_private: false) + name = name.to_s + + parts = name.split(DOT).reverse! + index = 0 + query = parts[index] + rules = [] + + loop do + match = @rules[query] + rules << entry_to_rule(match, query) if !match.nil? && (ignore_private == false || match.private == false) + + index += 1 + break if index >= parts.size + + query = parts[index] + DOT + query + end + + rules + end + private :select + + # Gets the default rule. + # + # @see PublicSuffix::Rule.default_rule + # + # @return [PublicSuffix::Rule::*] + def default_rule + PublicSuffix::Rule.default + end + + + protected + + attr_reader :rules + + + private + + def entry_to_rule(entry, value) + entry.type.new(value: value, length: entry.length, private: entry.private) + end + + def rule_to_entry(rule) + Rule::Entry.new(rule.class, rule.length, rule.private) + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/lib/public_suffix/rule.rb b/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/lib/public_suffix/rule.rb new file mode 100644 index 00000000..594b5c06 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/lib/public_suffix/rule.rb @@ -0,0 +1,350 @@ +# frozen_string_literal: true + +# = Public Suffix +# +# Domain name parser based on the Public Suffix List. +# +# Copyright (c) 2009-2025 Simone Carletti + +module PublicSuffix + + # A Rule is a special object which holds a single definition + # of the Public Suffix List. + # + # There are 3 types of rules, each one represented by a specific + # subclass within the +PublicSuffix::Rule+ namespace. + # + # To create a new Rule, use the {PublicSuffix::Rule#factory} method. + # + # PublicSuffix::Rule.factory("ar") + # # => # + # + module Rule + + # @api internal + Entry = Struct.new(:type, :length, :private) # rubocop:disable Lint/StructNewOverride + + # = Abstract rule class + # + # This represent the base class for a Rule definition + # in the {Public Suffix List}[https://publicsuffix.org]. + # + # This is intended to be an Abstract class + # and you shouldn't create a direct instance. The only purpose + # of this class is to expose a common interface + # for all the available subclasses. + # + # * {PublicSuffix::Rule::Normal} + # * {PublicSuffix::Rule::Exception} + # * {PublicSuffix::Rule::Wildcard} + # + # ## Properties + # + # A rule is composed by 4 properties: + # + # value - A normalized version of the rule name. + # The normalization process depends on rule tpe. + # + # Here's an example + # + # PublicSuffix::Rule.factory("*.google.com") + # # + # + # ## Rule Creation + # + # The best way to create a new rule is passing the rule name + # to the PublicSuffix::Rule.factory method. + # + # PublicSuffix::Rule.factory("com") + # # => PublicSuffix::Rule::Normal + # + # PublicSuffix::Rule.factory("*.com") + # # => PublicSuffix::Rule::Wildcard + # + # This method will detect the rule type and create an instance + # from the proper rule class. + # + # ## Rule Usage + # + # A rule describes the composition of a domain name and explains how to tokenize + # the name into tld, sld and trd. + # + # To use a rule, you first need to be sure the name you want to tokenize + # can be handled by the current rule. + # You can use the #match? method. + # + # rule = PublicSuffix::Rule.factory("com") + # + # rule.match?("google.com") + # # => true + # + # rule.match?("google.com") + # # => false + # + # Rule order is significant. A name can match more than one rule. + # See the {Public Suffix Documentation}[http://publicsuffix.org/format/] + # to learn more about rule priority. + # + # When you have the right rule, you can use it to tokenize the domain name. + # + # rule = PublicSuffix::Rule.factory("com") + # + # rule.decompose("google.com") + # # => ["google", "com"] + # + # rule.decompose("www.google.com") + # # => ["www.google", "com"] + # + # @abstract + # + class Base + + # @return [String] the rule definition + attr_reader :value + + # @return [String] the length of the rule + attr_reader :length + + # @return [Boolean] true if the rule is a private domain + attr_reader :private + + + # Initializes a new rule from the content. + # + # @param content [String] the content of the rule + # @param private [Boolean] + def self.build(content, private: false) + new(value: content, private: private) + end + + # Initializes a new rule. + # + # @param value [String] + # @param private [Boolean] + def initialize(value:, length: nil, private: false) + @value = value.to_s + @length = length || (@value.count(DOT) + 1) + @private = private + end + + # Checks whether this rule is equal to other. + # + # @param other [PublicSuffix::Rule::*] The rule to compare + # @return [Boolean] true if this rule and other are instances of the same class + # and has the same value, false otherwise. + def ==(other) + equal?(other) || (self.class == other.class && value == other.value) + end + alias eql? == + + # Checks if this rule matches +name+. + # + # A domain name is said to match a rule if and only if + # all of the following conditions are met: + # + # - When the domain and rule are split into corresponding labels, + # that the domain contains as many or more labels than the rule. + # - Beginning with the right-most labels of both the domain and the rule, + # and continuing for all labels in the rule, one finds that for every pair, + # either they are identical, or that the label from the rule is "*". + # + # @see https://publicsuffix.org/list/ + # + # @example + # PublicSuffix::Rule.factory("com").match?("example.com") + # # => true + # PublicSuffix::Rule.factory("com").match?("example.net") + # # => false + # + # @param name [String] the domain name to check + # @return [Boolean] + def match?(name) + # NOTE: it works because of the assumption there are no + # rules like foo.*.com. If the assumption is incorrect, + # we need to properly walk the input and skip parts according + # to wildcard component. + diff = name.chomp(value) + diff.empty? || diff.end_with?(DOT) + end + + # @abstract + def parts + raise NotImplementedError + end + + # @abstract + # @param domain [#to_s] The domain name to decompose + # @return [Array] + def decompose(*) + raise NotImplementedError + end + + end + + # Normal represents a standard rule (e.g. com). + class Normal < Base + + # Gets the original rule definition. + # + # @return [String] The rule definition. + def rule + value + end + + # Decomposes the domain name according to rule properties. + # + # @param domain [#to_s] The domain name to decompose + # @return [Array] The array with [trd + sld, tld]. + def decompose(domain) + suffix = parts.join('\.') + matches = domain.to_s.match(/^(.*)\.(#{suffix})$/) + matches ? matches[1..2] : [nil, nil] + end + + # dot-split rule value and returns all rule parts + # in the order they appear in the value. + # + # @return [Array] + def parts + @value.split(DOT) + end + + end + + # Wildcard represents a wildcard rule (e.g. *.co.uk). + class Wildcard < Base + + # Initializes a new rule from the content. + # + # @param content [String] the content of the rule + # @param private [Boolean] + def self.build(content, private: false) + new(value: content.to_s[2..], private: private) + end + + # Initializes a new rule. + # + # @param value [String] + # @param length [Integer] + # @param private [Boolean] + def initialize(value:, length: nil, private: false) + super + length or @length += 1 # * counts as 1 + end + + # Gets the original rule definition. + # + # @return [String] The rule definition. + def rule + value == "" ? STAR : STAR + DOT + value + end + + # Decomposes the domain name according to rule properties. + # + # @param domain [#to_s] The domain name to decompose + # @return [Array] The array with [trd + sld, tld]. + def decompose(domain) + suffix = ([".*?"] + parts).join('\.') + matches = domain.to_s.match(/^(.*)\.(#{suffix})$/) + matches ? matches[1..2] : [nil, nil] + end + + # dot-split rule value and returns all rule parts + # in the order they appear in the value. + # + # @return [Array] + def parts + @value.split(DOT) + end + + end + + # Exception represents an exception rule (e.g. !parliament.uk). + class Exception < Base + + # Initializes a new rule from the content. + # + # @param content [#to_s] the content of the rule + # @param private [Boolean] + def self.build(content, private: false) + new(value: content.to_s[1..], private: private) + end + + # Gets the original rule definition. + # + # @return [String] The rule definition. + def rule + BANG + value + end + + # Decomposes the domain name according to rule properties. + # + # @param domain [#to_s] The domain name to decompose + # @return [Array] The array with [trd + sld, tld]. + def decompose(domain) + suffix = parts.join('\.') + matches = domain.to_s.match(/^(.*)\.(#{suffix})$/) + matches ? matches[1..2] : [nil, nil] + end + + # dot-split rule value and returns all rule parts + # in the order they appear in the value. + # The leftmost label is not considered a label. + # + # See http://publicsuffix.org/format/: + # If the prevailing rule is a exception rule, + # modify it by removing the leftmost label. + # + # @return [Array] + def parts + @value.split(DOT)[1..] + end + + end + + + # Takes the +name+ of the rule, detects the specific rule class + # and creates a new instance of that class. + # The +name+ becomes the rule +value+. + # + # @example Creates a Normal rule + # PublicSuffix::Rule.factory("ar") + # # => # + # + # @example Creates a Wildcard rule + # PublicSuffix::Rule.factory("*.ar") + # # => # + # + # @example Creates an Exception rule + # PublicSuffix::Rule.factory("!congresodelalengua3.ar") + # # => # + # + # @param content [#to_s] the content of the rule + # @return [PublicSuffix::Rule::*] A rule instance. + def self.factory(content, private: false) + case content.to_s[0, 1] + when STAR + Wildcard + when BANG + Exception + else + Normal + end.build(content, private: private) + end + + # The default rule to use if no rule match. + # + # The default rule is "*". From https://publicsuffix.org/list/: + # + # > If no rules match, the prevailing rule is "*". + # + # @return [PublicSuffix::Rule::Wildcard] The default rule. + def self.default + factory(STAR) + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/lib/public_suffix/version.rb b/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/lib/public_suffix/version.rb new file mode 100644 index 00000000..ef09e582 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/public_suffix-6.0.2/lib/public_suffix/version.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# = Public Suffix +# +# Domain name parser based on the Public Suffix List. +# +# Copyright (c) 2009-2025 Simone Carletti + +module PublicSuffix + + # @return [String] the current library version + VERSION = "6.0.2" + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/History.md b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/History.md new file mode 100644 index 00000000..c42a6942 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/History.md @@ -0,0 +1,3030 @@ +## 6.6.0 / 2025-01-29 + +* Features + * Option to turn off SIGUSR2 trapping ([#3570], [#3567]) + * Shorten `ThreadPool` trimmer and reaper thread names ([#3383]) + * Add after_refork hook ([#3386]) + * Add busy threads stat ([#3517]) + * Add a debug log before running each type of hook ([#3375]) + * Allow alternative schemes in Binder ([#3348], [#3302]) + * Avoid spawning `Threadpool#trim` thread if pool size is fixed ([#3384]) + +* Bugfixes + * Change `HttpParserError` to be subclass of `StandardError` ([#3590], [#3552]) + * added test cases + * fix update phased restart symlink folder + +* Performance + * Only ping worker 0 during phased restart if using fork worker ([#3568]) + +* Refactor + * Fix multi-delimiter split to get status app token ([#3505]) + * Change ping to use const ([#3595]) + * Fixup use of Puma::Const::PipeRequest constants ([#3565]) + * Update DSL hook processing logic to be consistent ([#3376]) + +## 6.5.0 / 2024-11-23 + +* Features + * Print RUBY_DESCRIPTION when Puma starts ([#3407]) + * Set the worker process count automatically when using WEB_CONCURRENCY=auto ([#3439], [#3437]) + * Mark as ractor-safe ([#3486], [#3422]) + * Add option `enable_keep_alive`. `true` mimics existing behavior, but now can use `false` to disable keepalive to reduce queue tail latency ([#3496]) + * Add parameters to Puma methods to allow CI to change ENV in isolation ([#3485]) + * Add `ssl_ciphersuites` option for TLSv1.3 ciphers ([#3359], [#3343]) + * You can now use `--threads 5` or `threads 5` to config max/min threads with a single number (used to need to say `5:5`) ([#3309]) + * Option to turn off systemd plugin ([#3425], [#3424]) + * Add `on_stopped` hook ([#3411], [#3380]) + +* Bugfixes + * Handle blank environment variables when loading config ([#3539]) + * lib/rack/handler/puma.rb - fix for rackup v1.0.1, adjust Gemfile ([#3532], [#3531]) + * null_io.rb - add `external_encoding`, `set_encoding`, `binmode`, `binmode?` ([#3214]) + * Implement NullIO#seek and #pos to mimic IO ([#3468]) + * add support in rack handler & fix regression in binder for linux abstract namespace sockets ([#3508]) + * Use actual thread local for `Puma::Server.current`. ([#3360]) + * client.rb - fix request chunked body handling ([#3338], [#3337]) + * Properly handle two requests seen in the initial buffer ([#3332]) + * Fix response repeated status line when request is invalid or errors are raised ([#3308], [#3307]) + * Fix child processes not being reaped when `Process.detach` used ([#3314], [#3313]) + +* JRuby + * Make HTTP length constants configurable ([#3518]) + * Fixup jruby_restart.rb & launcher.rb to work with ARM64 macOS JRuby ([#3467]) + +* Performance + * Avoid checking if all workers reached timeout unless idle timeout is configured ([#3341]) + * Request body - increase read size to 64 kB ([#3548]) + * single mode skip wait_for_less_busy_worker ([#3325]) + +* Refactor + * A ton of CI/test improvements by @MSP-Greg, as usual. + * Add ThreadPool#stats and adjust Server#stats to use it ([#3527]) + * normalize whitespace in worker stats string ([#3513]) + * rack/handler/puma.rb - ssl - use `start_with?`, add test ([#3510]) + * extconf.rb - add logging for OpenSSL versions ([#3370]) + * Lazily require `Puma::Rack::Builder` ([#3340]) + * Refactor: Constantize worker pipe request types ([#3318]) + +* Docs + * stats.md improvements ([#3514]) + * control_cli.rb: Harmonize help message with bin/puma ([#3434]) + * dsl.rb: Clarify a callback's argument ([#3435]) + * lib/rack/handler/puma.rb - relocate and fixup module comment ([#3495]) + +## 6.4.3 / 2024-09-19 + +* Security + * Discards any headers using underscores if the non-underscore version also exists. Without this, an attacker could overwrite values set by intermediate proxies (e.g. X-Forwarded-For). ([CVE-2024-45614](https://github.com/puma/puma/security/advisories/GHSA-9hf4-67fc-4vf4)/GHSA-9hf4-67fc-4vf4) + +## 6.4.2 / 2024-01-08 + +* Security + * Limit the size of chunk extensions. Without this limit, an attacker could cause unbounded resource (CPU, network bandwidth) consumption. ([GHSA-c2f4-cvqm-65w2](https://github.com/puma/puma/security/advisories/GHSA-c2f4-cvqm-65w2)) + +## 6.4.1 / 2024-01-03 + +* Bugfixes + * DSL#warn_if_in_single_mode - fixup when workers set via CLI ([#3256]) + * Fix `idle-timeout` not working in cluster mode ([#3235], [#3228], [#3282], [#3283]) + * Fix worker 0 timing out during phased restart ([#3225], [#2786]) + * context_builder.rb - require openssl if verify_mode != 'none' ([#3179]) + * Make puma cluster process suitable as PID 1 ([#3255]) + * Improve Puma::NullIO consistency with real IO ([#3276]) + * extconf.rb - fixup to detect openssl info in Ruby build ([#3271], [#3266]) + * MiniSSL.java - set serialVersionUID, fix RaiseException deprecation ([#3270]) + * dsl.rb - fix warn_if_in_single_mode when WEB_CONCURRENCY is set ([#3265], [#3264]) + +* Maintenance + * LOTS of test refactoring to make tests more stable and easier to write - thanks to @MSP-Greg! + * Fix bug in tests re: TestPuma::HOST4 ([#3254]) + * Dockerfile for minimal repros: use Ruby 3.2, expect bundler installed ([#3245]) + * fix define_method calls, use Symbol parameter instead of String ([#3293]) + +* Docs + * README.md - add the puma-acme plugin ([#3301]) + * Remove `--keep-file-descriptors` flag from systemd docs ([#3248]) + * Note symlink mechanism in restart documentation for hot restart ([#3298]) + +## 6.4.0 / 2023-09-21 + +* Features + * on_thread_exit hook ([#2920]) + * on_thread_start_hook ([#3195]) + * Shutdown on idle ([#3209], [#2580]) + * New error message when control server port taken ([#3204]) + +* Refactor + * Remove `Forwardable` dependency ([#3191], #3190) + * Update URLMap Regexp usage for Ruby v3.3 ([#3165]) + +* Bugfixes + * Bring the cert_pem: parameter into parity with the cert: parameter to ssl_bind. ([#3174]) + * Fix using control server with IPv6 host ([#3181]) + * control_cli.rb - add require_relative 'log_writer' ([#3187]) + * Fix cases where fallback Rack response wasn't sent to the client ([#3094]) + +## 6.3.1 / 2023-08-18 + +* Security + * Address HTTP request smuggling vulnerabilities with zero-length Content Length header and trailer fields ([GHSA-68xg-gqqm-vgj8](https://github.com/puma/puma/security/advisories/GHSA-68xg-gqqm-vgj8)) + +## 6.3.0 / 2023-05-31 + +* Features + * Add dsl method `supported_http_methods` ([#3106], [#3014]) + * Puma error responses no longer have any fingerprints to indicate Puma ([#3161], [#3037]) + * Support decryption of SSL key ([#3133], [#3132]) + +* Bugfixes + * Don't send 103 early hints response when only invalid headers are used ([#3163]) + * Handle malformed request path ([#3155], [#3148]) + * Misc lib file fixes - trapping additional errors, CI helper ([#3129]) + * Fixup req form data file upload with "r\n" line endings ([#3137]) + * Restore rack 1.6 compatibility ([#3156]) + +* Refactor + * const.rb - Update Puma::HTTP_STATUS_CODES ([#3162]) + * Clarify Reactor#initialize ([#3151]) + +## 6.2.2 / 2023-04-17 + +* Bugfixes + * Fix Rack-related NameError by adding :: operator ([#3118], [#3117]) + +## 6.2.1 / 2023-03-31 + +* Bugfixes + * Fix java 8 compatibility ([#3109], [#3108]) + * Always write io_buffer when in "enum bodies" branch. ([#3113], [#3112]) + * Fix warn_if_in_single_mode incorrect message ([#3111]) + +## 6.2.0 / 2023-03-29 + +* Features + * Ability to supply a custom logger ([#2770], [#2511]) + * Warn when clustered-only hooks are defined in single mode ([#3089]) + * Adds the on_booted event ([#2709]) + +* Bugfixes + * Loggers - internal_write - catch Errno::EINVAL ([#3091]) + * commonlogger.rb - fix HIJACK time format, use constants, not strings ([#3074]) + * Fixed some edge cases regarding request hijacking ([#3072]) + +## 6.1.1 / 2023-02-28 + +* Bugfixes + * We no longer try to use the systemd plugin for JRuby ([#3079]) + * Allow ::Rack::Handler::Puma.run to work regardless of whether Rack/Rackup are loaded ([#3080]) + +## 6.1.0 / 2023-02-12 + +* Features + * WebSocket support via partial hijack ([#3058], [#3007]) + * Add built-in systemd notify support ([#3011]) + * Periodically send status to systemd ([#3006], [#2604]) + * Introduce the ability to return 413: payload too large for requests ([#3040]) + * Log loaded extensions when `PUMA_DEBUG` is set ([#3036], [#3020]) + +* Bugfixes + * Fix issue with rack 3 compatibility re: rackup ([#3061], [#3057]) + * Allow setting TCP low_latency with SSL listener ([#3065]) + +* Performance + * Reduce memory usage for large file uploads ([#3062]) + +## 6.0.2 / 2023-01-01 + +* Refactor + * Remove use of etc and time gems in Puma ([#3035], [#3033]) + * Refactor const.rb - freeze ([#3016]) + +## 6.0.1 / 2022-12-20 + +* Bugfixes + * Handle waking up a closed selector in Reactor#add ([#3005]) + * Fixup response processing, enumerable bodies ([#3004], [#3000]) + * Correctly close app body for all code paths ([#3002], [#2999]) +* Refactor + * Add IOBuffer to Client, remove from ThreadPool thread instances ([#3013]) + +## 6.0.0 / 2022-10-14 + +* Breaking Changes + * Dropping Ruby 2.2 and 2.3 support (now 2.4+) ([#2919]) + * Remote_addr functionality has changed ([#2652], [#2653]) + * No longer supporting Java 1.7 or below (JRuby 9.1 was the last release to support this) ([#2849]) + * Remove nakayoshi GC ([#2933], [#2925]) + * wait_for_less_busy_worker is now default on ([#2940]) + * Prefix all environment variables with `PUMA_` ([#2924], [#2853]) + * Removed some constants ([#2957], [#2958], [#2959], [#2960]) + * The following classes are now part of Puma's private API: `Client`, `Cluster::Worker`, `Cluster::Worker`, `HandleRequest`. ([#2988]) + * Configuration constants like `DefaultRackup` removed ([#2928]) + * Extracted `LogWriter` from `Events` ([#2798]) + * Only accept the standard 8 HTTP methods, others rejected with 501. ([#2932]) + +* Features + * Increase throughput on large (100kb+) response bodies by 3-10x ([#2896], [#2892]) + * Increase throughput on file responses ([#2923]) + * Add support for streaming bodies in Rack. ([#2740]) + * Allow OpenSSL session reuse via a 'reuse' ssl_bind method or bind string query parameter ([#2845]) + * Allow `run_hooks` to pass a hash to blocks for use later ([#2917], [#2915]) + * Allow using `preload_app!` with `fork_worker` ([#2907]) + * Support request_body_wait metric with higher precision ([#2953]) + * Allow header values to be arrays (Rack 3) ([#2936], [#2931]) + * Export Puma/Ruby versions in /stats ([#2875]) + * Allow configuring request uri max length & request path max length ([#2840]) + * Add a couple of public accessors ([#2774]) + * Log entire backtrace when worker start fails ([#2891]) + * [jruby] Enable TLSv1.3 support ([#2886]) + * [jruby] support setting TLS protocols + rename ssl_cipher_list ([#2899]) + * [jruby] Support a truststore option ([#2849], [#2904], [#2884]) + +* Bugfixes + * Load the configuration before passing it to the binder ([#2897]) + * Do not raise error raised on HTTP methods we don't recognize or support, like CONNECT ([#2932], [#1441]) + * Fixed a memory leak when creating a new SSL listener ([#2956]) + +* Refactor + * log_writer.rb - add internal_write method ([#2888]) + * Extract prune_bundler code into it's own class. ([#2797]) + * Refactor Launcher#run to increase readability (no logic change) ([#2795]) + * Ruby 3.2 will have native IO#wait_* methods, don't require io/wait ([#2903]) + * Various internal API refactorings ([#2942], [#2921], [#2922], [#2955]) + +## 5.6.9 / 2024-09-19 + +* Security + * Discards any headers using underscores if the non-underscore version also exists. Without this, an attacker could overwrite values set by intermediate proxies (e.g. X-Forwarded-For). ([CVE-2024-45614](https://github.com/puma/puma/security/advisories/GHSA-9hf4-67fc-4vf4)/GHSA-9hf4-67fc-4vf4) +* JRuby + * Must use at least Java >= 9 to compile. You can no longer build from source on Java 8. + + +## 5.6.8 / 2024-01-08 + +* Security + * Limit the size of chunk extensions. Without this limit, an attacker could cause unbounded resource (CPU, network bandwidth) consumption. ([GHSA-c2f4-cvqm-65w2](https://github.com/puma/puma/security/advisories/GHSA-c2f4-cvqm-65w2)) + +## 5.6.7 / 2023-08-18 + +* Security + * Address HTTP request smuggling vulnerabilities with zero-length Content Length header and trailer fields ([GHSA-68xg-gqqm-vgj8](https://github.com/puma/puma/security/advisories/GHSA-68xg-gqqm-vgj8)) + +## 5.6.6 / 2023-06-21 + +* Bugfix + * Prevent loading with rack 3 ([#3166]) + +## 5.6.5 / 2022-08-23 + +* Feature + * Puma::ControlCLI - allow refork command to be sent as a request ([#2868], [#2866]) + +* Bugfixes + * NullIO#closed should return false ([#2883]) + * [jruby] Fix TLS verification hang ([#2890], [#2729]) + * extconf.rb - don't use pkg_config('openssl') if '--with-openssl-dir' is used ([#2885], [#2839]) + * MiniSSL - detect SSL_CTX_set_dh_auto ([#2864], [#2863]) + * Fix rack.after_reply exceptions breaking connections ([#2861], [#2856]) + * Escape SSL cert and filenames ([#2855]) + * Fail hard if SSL certs or keys are invalid ([#2848]) + * Fail hard if SSL certs or keys cannot be read by user ([#2847]) + * Fix build with Opaque DH in LibreSSL 3.5. ([#2838]) + * Pre-existing socket file removed when TERM is issued after USR2 (if puma is running in cluster mode) ([#2817]) + * Fix Puma::StateFile#load incompatibility ([#2810]) + +## 5.6.4 / 2022-03-30 + +* Security + * Close several HTTP Request Smuggling exploits (CVE-2022-24790) + +## 5.6.2 / 2022-02-11 + +* Bugfix/Security + * Response body will always be `close`d. (GHSA-rmj8-8hhh-gv5h, related to [#2809]) + +## 5.6.1 / 2022-01-26 + +* Bugfixes + * Reverted a commit which appeared to be causing occasional blank header values ([#2809]) + +## 5.6.0 / 2022-01-25 + +* Features + * Support `localhost` integration in `ssl_bind` ([#2764], [#2708]) + * Allow backlog parameter to be set with ssl_bind DSL ([#2780]) + * Remove yaml (psych) requirement in StateFile ([#2784]) + * Allow culling of oldest workers, previously was only youngest ([#2773], [#2794]) + * Add worker_check_interval configuration option ([#2759]) + * Always send lowlevel_error response to client ([#2731], [#2341]) + * Support for cert_pem and key_pem with ssl_bind DSL ([#2728]) + +* Bugfixes + * Keep thread names under 15 characters, prevents breakage on some OSes ([#2733]) + * Fix two 'old-style-definition' compile warning ([#2807], [#2806]) + * Log environment correctly using option value ([#2799]) + * Fix warning from Ruby master (will be 3.2.0) ([#2785]) + * extconf.rb - fix openssl with old Windows builds ([#2757]) + * server.rb - rescue handling (`Errno::EBADF`) for `@notify.close` ([#2745]) + +* Refactor + * server.rb - refactor code using @options[:remote_address] ([#2742]) + * [jruby] a couple refactorings - avoid copy-ing bytes ([#2730]) + +## 5.5.2 / 2021-10-12 + +* Bugfixes + * Allow UTF-8 in HTTP header values + +## 5.5.1 / 2021-10-12 + +* Feature (added as mistake - we don't normally do this on bugfix releases, sorry!) + * Allow setting APP_ENV in preference to RACK_ENV or RAILS_ENV ([#2702]) + +* Security + * Do not allow LF as a line ending in a header (CVE-2021-41136) + +## 5.5.0 / 2021-09-19 + +* Features + * Automatic SSL certificate provisioning for localhost, via localhost gem ([#2610], [#2257]) + * add support for the PROXY protocol (v1 only) ([#2654], [#2651]) + * Add a semantic CLI option for no config file ([#2689]) + +* Bugfixes + * More elaborate exception handling - lets some dead pumas die. ([#2700], [#2699]) + * allow multiple after_worker_fork hooks ([#2690]) + * Preserve BUNDLE_APP_CONFIG on worker fork ([#2688], [#2687]) + +* Performance + * Fix performance of server-side SSL connection close. ([#2675]) + +## 5.4.0 / 2021-07-28 + +* Features + * Better/expanded names for threadpool threads ([#2657]) + * Allow pkg_config for OpenSSL ([#2648], [#1412]) + * Add `rack_url_scheme` to Puma::DSL, allows setting of `rack.url_scheme` header ([#2586], [#2569]) + +* Bugfixes + * `Binder#parse` - allow for symlinked unix path, add create_activated_fds debug ENV ([#2643], [#2638]) + * Fix deprecation warning: minissl.c - Use Random.bytes if available ([#2642]) + * Client certificates: set session id context while creating SSLContext ([#2633]) + * Fix deadlock issue in thread pool ([#2656]) + +* Refactor + * Replace `IO.select` with `IO#wait_*` when checking a single IO ([#2666]) + +## 5.3.2 / 2021-05-21 + +* Bugfixes + * Gracefully handle Rack not accepting CLI options ([#2630], [#2626]) + * Fix sigterm misbehavior ([#2629]) + * Improvements to keepalive-connection shedding ([#2628]) + +## 5.3.1 / 2021-05-11 + +* Security + * Close keepalive connections after the maximum number of fast inlined requests (CVE-2021-29509) ([#2625]) + +## 5.3.0 / 2021-05-07 + +* Features + * Add support for Linux's abstract sockets ([#2564], [#2526]) + * Add debug to worker timeout and startup ([#2559], [#2528]) + * Print warning when running one-worker cluster ([#2565], [#2534]) + * Don't close systemd activated socket on pumactl restart ([#2563], [#2504]) + +* Bugfixes + * systemd - fix event firing ([#2591], [#2572]) + * Immediately unlink temporary files ([#2613]) + * Improve parsing of HTTP_HOST header ([#2605], [#2584]) + * Handle fatal error that has no backtrace ([#2607], [#2552]) + * Fix timing out requests too early ([#2606], [#2574]) + * Handle segfault in Ruby 2.6.6 on thread-locals ([#2567], [#2566]) + * Server#closed_socket? - parameter may be a MiniSSL::Socket ([#2596]) + * Define UNPACK_TCP_STATE_FROM_TCP_INFO in the right place ([#2588], [#2556]) + * request.rb - fix chunked assembly for ascii incompatible encodings, add test ([#2585], [#2583]) + +* Performance + * Reset peerip only if remote_addr_header is set ([#2609]) + * Reduce puma_parser struct size ([#2590]) + +* Refactor + * Refactor drain on shutdown ([#2600]) + * Micro optimisations in `wait_for_less_busy_worker` feature ([#2579]) + * Lots of test fixes + +## 5.2.2 / 2021-02-22 + +* Bugfixes + * Add `#flush` and `#sync` methods to `Puma::NullIO` ([#2553]) + * Restore `sync=true` on `STDOUT` and `STDERR` streams ([#2557]) + +## 5.2.1 / 2021-02-05 + +* Bugfixes + * Fix TCP cork/uncork operations to work with ssl clients ([#2550]) + * Require rack/common_logger explicitly if :verbose is true ([#2547]) + * MiniSSL::Socket#write - use data.byteslice(wrote..-1) ([#2543]) + * Set `@env[CONTENT_LENGTH]` value as string. ([#2549]) + +## 5.2.0 / 2021-01-27 + +* Features + * 10x latency improvement for MRI on ssl connections by reducing overhead ([#2519]) + * Add option to specify the desired IO selector backend for libev ([#2522]) + * Add ability to set OpenSSL verification flags (MRI only) ([#2490]) + * Uses `flush` after writing messages to avoid mutating $stdout and $stderr using `sync=true` ([#2486]) + +* Bugfixes + * MiniSSL - Update dhparam to 2048 bit for use with SSL_CTX_set_tmp_dh ([#2535]) + * Change 'Goodbye!' message to be output after listeners are closed ([#2529]) + * Fix ssl bind logging with 0.0.0.0 and localhost ([#2533]) + * Fix compiler warnings, but skipped warnings related to ragel state machine generated code ([#1953]) + * Fix phased restart errors related to nio4r gem when using the Puma control server ([#2516]) + * Add `#string` method to `Puma::NullIO` ([#2520]) + * Fix binding via Rack handler to IPv6 addresses ([#2521]) + +* Refactor + * Refactor MiniSSL::Context on MRI, fix MiniSSL::Socket#write ([#2519]) + * Remove `Server#read_body` ([#2531]) + * Fail build if compiling extensions raises warnings on GH Actions, configurable via `MAKE_WARNINGS_INTO_ERRORS` ([#1953]) + +## 5.1.1 / 2020-12-10 + +* Bugfixes + * Fix over eager matching against banned header names ([#2510]) + +## 5.1.0 / 2020-11-30 + +* Features + * Phased restart availability is now always logged, even if it is not available. + * Prints the loaded configuration if the environment variable `PUMA_LOG_CONFIG` is present ([#2472]) + * Integrate with systemd's watchdog and notification features ([#2438]) + * Adds max_fast_inline as a configuration option for the Server object ([#2406]) + * You can now fork workers from worker 0 using SIGURG w/o fork_worker enabled [#2449] + * Add option to bind to systemd activated sockets ([#2362]) + * Add compile option to change the `QUERY_STRING` max length ([#2485]) + +* Bugfixes + * Fix JRuby handling in Puma::DSL#ssl_bind ([#2489]) + * control_cli.rb - all normal output should be to @stdout ([#2487]) + * Catch 'Error in reactor loop escaped: mode not supported for this object: r' ([#2477]) + * Ignore Rails' reaper thread (and any thread marked forksafe) for warning ([#2475]) + * Ignore illegal (by Rack spec) response header ([#2439]) + * Close idle connections immediately on shutdown ([#2460]) + * Fix some instances of phased restart errors related to the `json` gem ([#2473]) + * Remove use of `json` gem to fix phased restart errors ([#2479]) + * Fix grouping regexp of ILLEGAL_HEADER_KEY_REGEX ([#2495]) + +## 5.0.4 / 2020-10-27 + +* Bugfixes + * Pass preloaded application into new workers if available when using `preload_app` ([#2461], [#2454]) + +## 5.0.3 / 2020-10-26 + +* Bugfixes + * Add Client#io_ok?, check before Reactor#register ([#2432]) + * Fix hang on shutdown in refork ([#2442]) + * Fix `Bundler::GemNotFound` errors for `nio4r` gem during phased restarts ([#2427], [#2018]) + * Server run thread safety fix ([#2435]) + * Fire `on_booted` after server starts ([#2431], [#2212]) + * Cleanup daemonization in rc.d script ([#2409]) + +* Refactor + * Remove accept_nonblock.rb, add test_integration_ssl.rb ([#2448]) + * Refactor status.rb - dry it up a bit ([#2450]) + * Extract req/resp methods to new request.rb from server.rb ([#2419]) + * Refactor Reactor and Client request buffering ([#2279]) + * client.rb - remove JRuby specific 'finish' code ([#2412]) + * Consolidate fast_write calls in Server, extract early_hints assembly ([#2405]) + * Remove upstart from docs ([#2408]) + * Extract worker process into separate class ([#2374]) + * Consolidate option handling in Server, Server small refactors, doc changes ([#2389]) + +## 5.0.2 / 2020-09-28 + +* Bugfixes + * Reverted API changes to Server. + +## 5.0.1 / 2020-09-28 + +* Bugfixes + * Fix LoadError in CentOS 8 ([#2381]) + * Better error handling during force shutdown ([#2271]) + * Prevent connections from entering Reactor after shutdown begins ([#2377]) + * Fix error backtrace debug logging && Do not log request dump if it is not parsed ([#2376]) + * Split TCP_CORK and TCP_INFO ([#2372]) + * Do not log EOFError when a client connection is closed without write ([#2384]) + +* Refactor + * Change Events#ssl_error signature from (error, peeraddr, peercert) to (error, ssl_socket) ([#2375]) + * Consolidate option handling in Server, Server small refactors, doc chang ([#2373]) + +## 5.0.0 / 2020-09-17 + +* Features + * Allow compiling without OpenSSL and dynamically load files needed for SSL, add 'no ssl' CI ([#2305]) + * EXPERIMENTAL: Add `fork_worker` option and `refork` command for reduced memory usage by forking from a worker process instead of the master process. ([#2099]) + * EXPERIMENTAL: Added `wait_for_less_busy_worker` config. This may reduce latency on MRI through inserting a small delay before re-listening on the socket if worker is busy ([#2079]). + * EXPERIMENTAL: Added `nakayoshi_fork` option. Reduce memory usage in preloaded cluster-mode apps by GCing before fork and compacting, where available. ([#2093], [#2256]) + * Added pumactl `thread-backtraces` command to print thread backtraces ([#2054]) + * Added incrementing `requests_count` to `Puma.stats`. ([#2106]) + * Increased maximum URI path length from 2048 to 8192 bytes ([#2167], [#2344]) + * `lowlevel_error_handler` is now called during a forced threadpool shutdown, and if a callable with 3 arguments is set, we now also pass the status code ([#2203]) + * Faster phased restart and worker timeout ([#2220]) + * Added `state_permission` to config DSL to set state file permissions ([#2238]) + * Added `Puma.stats_hash`, which returns a stats in Hash instead of a JSON string ([#2086], [#2253]) + * `rack.multithread` and `rack.multiprocess` now dynamically resolved by `max_thread` and `workers` respectively ([#2288]) + +* Deprecations, Removals and Breaking API Changes + * `--control` has been removed. Use `--control-url` ([#1487]) + * `worker_directory` has been removed. Use `directory`. + * min_threads now set by environment variables PUMA_MIN_THREADS and MIN_THREADS. ([#2143]) + * max_threads now set by environment variables PUMA_MAX_THREADS and MAX_THREADS. ([#2143]) + * max_threads default to 5 in MRI or 16 for all other interpreters. ([#2143]) + * `preload_app!` is on by default if number of workers > 1 and set via `WEB_CONCURRENCY` ([#2143]) + * Puma::Plugin.workers_supported? has been removed. Use Puma.forkable? instead. ([#2143]) + * `tcp_mode` has been removed without replacement. ([#2169]) + * Daemonization has been removed without replacement. ([#2170]) + * Changed #connected_port to #connected_ports ([#2076]) + * Configuration: `environment` is read from `RAILS_ENV`, if `RACK_ENV` can't be found ([#2022]) + * Log binding on http:// for TCP bindings to make it clickable ([#2300]) + +* Bugfixes + * Fix JSON loading issues on phased-restarts ([#2269]) + * Improve shutdown reliability ([#2312], [#2338]) + * Close client http connections made to an ssl server with TLSv1.3 ([#2116]) + * Do not set user_config to quiet by default to allow for file config ([#2074]) + * Always close SSL connection in Puma::ControlCLI ([#2211]) + * Windows update extconf.rb for use with ssp and varied Ruby/MSYS2 combinations ([#2069]) + * Ensure control server Unix socket is closed on shutdown ([#2112]) + * Preserve `BUNDLE_GEMFILE` env var when using `prune_bundler` ([#1893]) + * Send 408 request timeout even when queue requests is disabled ([#2119]) + * Rescue IO::WaitReadable instead of EAGAIN for blocking read ([#2121]) + * Ensure `BUNDLE_GEMFILE` is unspecified in workers if unspecified in master when using `prune_bundler` ([#2154]) + * Rescue and log exceptions in hooks defined by users (on_worker_boot, after_worker_fork etc) ([#1551]) + * Read directly from the socket in #read_and_drop to avoid raising further SSL errors ([#2198]) + * Set `Connection: closed` header when queue requests is disabled ([#2216]) + * Pass queued requests to thread pool on server shutdown ([#2122]) + * Fixed a few minor concurrency bugs in ThreadPool that may have affected non-GVL Rubies ([#2220]) + * Fix `out_of_band` hook never executed if the number of worker threads is > 1 ([#2177]) + * Fix ThreadPool#shutdown timeout accuracy ([#2221]) + * Fix `UserFileDefaultOptions#fetch` to properly use `default` ([#2233]) + * Improvements to `out_of_band` hook ([#2234]) + * Prefer the rackup file specified by the CLI ([#2225]) + * Fix for spawning subprocesses with fork_worker option ([#2267]) + * Set `CONTENT_LENGTH` for chunked requests ([#2287]) + * JRuby - Add Puma::MiniSSL::Engine#init? and #teardown methods, run all SSL tests ([#2317]) + * Improve shutdown reliability ([#2312]) + * Resolve issue with threadpool waiting counter decrement when thread is killed + * Constrain rake-compiler version to 0.9.4 to fix `ClassNotFound` exception when using MiniSSL with Java8. + * Fix recursive `prune_bundler` ([#2319]). + * Ensure that TCP_CORK is usable + * Fix corner case when request body is chunked ([#2326]) + * Fix filehandle leak in MiniSSL ([#2299]) + +* Refactor + * Remove unused loader argument from Plugin initializer ([#2095]) + * Simplify `Configuration.random_token` and remove insecure fallback ([#2102]) + * Simplify `Runner#start_control` URL parsing ([#2111]) + * Removed the IOBuffer extension and replaced with Ruby ([#1980]) + * Update `Rack::Handler::Puma.run` to use `**options` ([#2189]) + * ThreadPool concurrency refactoring ([#2220]) + * JSON parse cluster worker stats instead of regex ([#2124]) + * Support parallel tests in verbose progress reporting ([#2223]) + * Refactor error handling in server accept loop ([#2239]) + +## 4.3.12 / 2022-03-30 + +* Security + * Close several HTTP Request Smuggling exploits (CVE-2022-24790) + +## 4.3.11 / 2022-02-11 + +* Security + * Always close the response body (GHSA-rmj8-8hhh-gv5h) + +## 4.3.10 / 2021-10-12 + +* Bugfixes + * Allow UTF-8 in HTTP header values + +## 4.3.9 / 2021-10-12 + +* Security + * Do not allow LF as a line ending in a header (CVE-2021-41136) + +## 4.3.8 / 2021-05-11 + +* Security + * Close keepalive connections after the maximum number of fast inlined requests (CVE-2021-29509) ([#2625]) + +## 4.3.7 / 2020-11-30 + +* Bugfixes + * Backport set CONTENT_LENGTH for chunked requests (Originally: [#2287], backport: [#2496]) + +## 4.3.6 / 2020-09-05 + +* Bugfixes + * Explicitly include ctype.h to fix compilation warning and build error on macOS with Xcode 12 ([#2304]) + * Don't require json at boot ([#2269]) + +## 4.3.4/4.3.5 and 3.12.5/3.12.6 / 2020-05-22 + +Each patchlevel release contains a separate security fix. We recommend simply upgrading to 4.3.5/3.12.6. + +* Security + * Fix: Fixed two separate HTTP smuggling vulnerabilities that used the Transfer-Encoding header. CVE-2020-11076 and CVE-2020-11077. + +## 4.3.3 and 3.12.4 / 2020-02-28 + +* Bugfixes + * Fix: Fixes a problem where we weren't splitting headers correctly on newlines ([#2132]) +* Security + * Fix: Prevent HTTP Response splitting via CR in early hints. CVE-2020-5249. + +## 4.3.2 and 3.12.3 / 2020-02-27 (YANKED) + +* Security + * Fix: Prevent HTTP Response splitting via CR/LF in header values. CVE-2020-5247. + +## 4.3.1 and 3.12.2 / 2019-12-05 + +* Security + * Fix: a poorly-behaved client could use keepalive requests to monopolize Puma's reactor and create a denial of service attack. CVE-2019-16770. + +## 4.3.0 / 2019-11-07 + +* Features + * Strip whitespace at end of HTTP headers ([#2010]) + * Optimize HTTP parser for JRuby ([#2012]) + * Add SSL support for the control app and cli ([#2046], [#2052]) + +* Bugfixes + * Fix Errno::EINVAL when SSL is enabled and browser rejects cert ([#1564]) + * Fix pumactl defaulting puma to development if an environment was not specified ([#2035]) + * Fix closing file stream when reading pid from pidfile ([#2048]) + * Fix a typo in configuration option `--extra_runtime_dependencies` ([#2050]) + +## 4.2.1 / 2019-10-07 + +* 3 bugfixes + * Fix socket activation of systemd (pre-existing) unix binder files ([#1842], [#1988]) + * Deal with multiple calls to bind correctly ([#1986], [#1994], [#2006]) + * Accepts symbols for `verify_mode` ([#1222]) + +## 4.2.0 / 2019-09-23 + +* 6 features + * Pumactl has a new -e environment option and reads `config/puma/.rb` config files ([#1885]) + * Semicolons are now allowed in URL paths (MRI only), useful for Angular or Redmine ([#1934]) + * Allow extra dependencies to be defined when using prune_bundler ([#1105]) + * Puma now reports the correct port when binding to port 0, also reports other listeners when binding to localhost ([#1786]) + * Sending SIGINFO to any Puma worker now prints currently active threads and their backtraces ([#1320]) + * Puma threads all now have their name set on Ruby 2.3+ ([#1968]) +* 4 bugfixes + * Fix some misbehavior with phased restart and externally SIGTERMed workers ([#1908], [#1952]) + * Fix socket closing on error ([#1941]) + * Removed unnecessary SIGINT trap for JRuby that caused some race conditions ([#1961]) + * Fix socket files being left around after process stopped ([#1970]) +* Absolutely thousands of lines of test improvements and fixes thanks to @MSP-Greg + +## 4.1.1 / 2019-09-05 + +* 3 bugfixes + * Revert our attempt to not dup STDOUT/STDERR ([#1946]) + * Fix socket close on error ([#1941]) + * Fix workers not shutting down correctly ([#1908]) + +## 4.1.0 / 2019-08-08 + +* 4 features + * Add REQUEST_PATH on parse error message ([#1831]) + * You can now easily add custom log formatters with the `log_formatter` config option ([#1816]) + * Puma.stats now provides process start times ([#1844]) + * Add support for disabling TLSv1.1 ([#1836]) + +* 7 bugfixes + * Fix issue where Puma was creating zombie process entries ([#1887]) + * Fix bugs with line-endings and chunked encoding ([#1812]) + * RACK_URL_SCHEME is now set correctly in all conditions ([#1491]) + * We no longer mutate global STDOUT/STDERR, particularly the sync setting ([#1837]) + * SSL read_nonblock no longer blocks ([#1857]) + * Swallow connection errors when sending early hints ([#1822]) + * Backtrace no longer dumped when invalid pumactl commands are run ([#1863]) + +* 5 other + * Avoid casting worker_timeout twice ([#1838]) + * Removed a call to private that wasn't doing anything ([#1882]) + * README, Rakefile, docs and test cleanups ([#1848], [#1847], [#1846], [#1853], #1859, [#1850], [#1866], [#1870], [#1872], [#1833], [#1888]) + * Puma.io has proper documentation now (https://puma.io/puma/) + * Added the Contributor Covenant CoC + +* 1 known issue + * Some users are still experiencing issues surrounding socket activation and Unix sockets ([#1842]) + +## 4.0.1 / 2019-07-11 + +* 2 bugfixes + * Fix socket removed after reload - should fix problems with systemd socket activation. ([#1829]) + * Add extconf tests for DTLS_method & TLS_server_method, use in minissl.rb. Should fix "undefined symbol: DTLS_method" when compiling against old OpenSSL versions. ([#1832]) +* 1 other + * Removed unnecessary RUBY_VERSION checks. ([#1827]) + +## 4.0.0 / 2019-06-25 + +* 9 features + * Add support for disabling TLSv1.0 ([#1562]) + * Request body read time metric ([#1569]) + * Add out_of_band hook ([#1648]) + * Re-implement (native) IOBuffer for JRuby ([#1691]) + * Min worker timeout ([#1716]) + * Add option to suppress SignalException on SIGTERM ([#1690]) + * Allow mutual TLS CA to be set using `ssl_bind` DSL ([#1689]) + * Reactor now uses nio4r instead of `select` ([#1728]) + * Add status to pumactl with pidfile ([#1824]) + +* 10 bugfixes + * Do not accept new requests on shutdown ([#1685], [#1808]) + * Fix 3 corner cases when request body is chunked ([#1508]) + * Change pid existence check's condition branches ([#1650]) + * Don't call .stop on a server that doesn't exist ([#1655]) + * Implemented NID_X9_62_prime256v1 (P-256) curve over P-521 ([#1671]) + * Fix @notify.close can't modify frozen IOError (RuntimeError) ([#1583]) + * Fix Java 8 support ([#1773]) + * Fix error `uninitialized constant Puma::Cluster` ([#1731]) + * Fix `not_token` being able to be set to true ([#1803]) + * Fix "Hang on SIGTERM with ruby 2.6 in clustered mode" (PR [#1741], [#1674], [#1720], [#1730], [#1755]) + +## 3.12.1 / 2019-03-19 + +* 1 features + * Internal strings are frozen ([#1649]) +* 3 bugfixes + * Fix chunked ending check ([#1607]) + * Rack handler should use provided default host ([#1700]) + * Better support for detecting runtimes that support `fork` ([#1630]) + +## 3.12.0 / 2018-07-13 + +* 5 features: + * You can now specify which SSL ciphers the server should support, default is unchanged ([#1478]) + * The setting for Puma's `max_threads` is now in `Puma.stats` ([#1604]) + * Pool capacity is now in `Puma.stats` ([#1579]) + * Installs restricted to Ruby 2.2+ ([#1506]) + * `--control` is now deprecated in favor of `--control-url` ([#1487]) + +* 2 bugfixes: + * Workers will no longer accept more web requests than they have capacity to process. This prevents an issue where one worker would accept lots of requests while starving other workers ([#1563]) + * In a test env puma now emits the stack on an exception ([#1557]) + +## 3.11.4 / 2018-04-12 + +* 2 features: + * Manage puma as a service using rc.d ([#1529]) + * Server stats are now available from a top level method ([#1532]) +* 5 bugfixes: + * Fix parsing CLI options ([#1482]) + * Order of stderr and stdout is made before redirecting to a log file ([#1511]) + * Init.d fix of `ps -p` to check if pid exists ([#1545]) + * Early hints bugfix ([#1550]) + * Purge interrupt queue when closing socket fails ([#1553]) + +## 3.11.3 / 2018-03-05 + +* 3 bugfixes: + * Add closed? to MiniSSL::Socket for use in reactor ([#1510]) + * Handle EOFError at the toplevel of the server threads ([#1524]) ([#1507]) + * Deal with zero sized bodies when using SSL ([#1483]) + +## 3.11.2 / 2018-01-19 + +* 1 bugfix: + * Deal with read\_nonblock returning nil early + +## 3.11.1 / 2018-01-18 + +* 1 bugfix: + * Handle read\_nonblock returning nil when the socket close ([#1502]) + +## 3.11.0 / 2017-11-20 + +* 2 features: + * HTTP 103 Early Hints ([#1403]) + * 421/451 status codes now have correct status messages attached ([#1435]) + +* 9 bugfixes: + * Environment config files (/config/puma/.rb) load correctly ([#1340]) + * Specify windows dependencies correctly ([#1434], [#1436]) + * puma/events required in test helper ([#1418]) + * Correct control CLI's option help text ([#1416]) + * Remove a warning for unused variable in mini_ssl ([#1409]) + * Correct pumactl docs argument ordering ([#1427]) + * Fix an uninitialized variable warning in server.rb ([#1430]) + * Fix docs typo/error in Launcher init ([#1429]) + * Deal with leading spaces in RUBYOPT ([#1455]) + +* 2 other: + * Add docs about internals ([#1425], [#1452]) + * Tons of test fixes from @MSP-Greg ([#1439], [#1442], [#1464]) + +## 3.10.0 / 2017-08-17 + +* 3 features: + * The status server has a new /gc and /gc-status command. ([#1384]) + * The persistent and first data timeouts are now configurable ([#1111]) + * Implemented RFC 2324 ([#1392]) + +* 12 bugfixes: + * Not really a Puma bug, but @NickolasVashchenko created a gem to workaround a Ruby bug that some users of Puma may be experiencing. See README for more. ([#1347]) + * Fix hangups with SSL and persistent connections. ([#1334]) + * Fix Rails double-binding to a port ([#1383]) + * Fix incorrect thread names ([#1368]) + * Fix issues with /etc/hosts and JRuby where localhost addresses were not correct. ([#1318]) + * Fix compatibility with RUBYOPT="--enable-frozen-string-literal" ([#1376]) + * Fixed some compiler warnings ([#1388]) + * We actually run the integration tests in CI now ([#1390]) + * No longer shipping unnecessary directories in the gemfile ([#1391]) + * If RUBYOPT is nil, we no longer blow up on restart. ([#1385]) + * Correct response to SIGINT ([#1377]) + * Proper exit code returned when we receive a TERM signal ([#1337]) + +* 3 refactors: + * Various test improvements from @grosser + * Rubocop ([#1325]) + * Hoe has been removed ([#1395]) + +* 1 known issue: + * Socket activation doesn't work in JRuby. Their fault, not ours. ([#1367]) + +## 3.9.1 / 2017-06-03 + +* 2 bugfixes: + * Fixed compatibility with older Bundler versions ([#1314]) + * Some internal test/development cleanup ([#1311], [#1313]) + +## 3.9.0 / 2017-06-01 + +* 2 features: + * The ENV is now reset to its original values when Puma restarts via USR1/USR2 ([#1260]) (MRI only, no JRuby support) + * Puma will no longer accept more clients than the maximum number of threads. ([#1278]) + +* 9 bugfixes: + * Reduce information leakage by preventing HTTP parse errors from writing environment hashes to STDERR ([#1306]) + * Fix SSL/WebSocket compatibility ([#1274]) + * HTTP headers with empty values are no longer omitted from responses. ([#1261]) + * Fix a Rack env key which was set to nil. ([#1259]) + * peercert has been implemented for JRuby ([#1248]) + * Fix port settings when using rails s ([#1277], [#1290]) + * Fix compat w/LibreSSL ([#1285]) + * Fix restarting Puma w/symlinks and a new Gemfile ([#1282]) + * Replace Dir.exists? with Dir.exist? ([#1294]) + +* 1 known issue: + * A bug in MRI 2.2+ can result in IOError: stream closed. See [#1206]. This issue has existed since at least Puma 3.6, and probably further back. + +* 1 refactor: + * Lots of test fixups from @grosser. + +## 3.8.2 / 2017-03-14 + +* 1 bugfix: + * Deal with getsockopt with TCP\_INFO failing for sockets that say they're TCP but aren't really. ([#1241]) + +## 3.8.1 / 2017-03-10 + +* 1 bugfix: + * Remove method call to method that no longer exists ([#1239]) + +## 3.8.0 / 2017-03-09 + +* 2 bugfixes: + * Port from rack handler does not take precedence over config file in Rails 5.1.0.beta2+ and 5.0.1.rc3+ ([#1234]) + * The `tmp/restart.txt` plugin no longer restricts the user from running more than one server from the same folder at a time ([#1226]) + +* 1 feature: + * Closed clients are aborted to save capacity ([#1227]) + +* 1 refactor: + * Bundler is no longer a dependency from tests ([#1213]) + +## 3.7.1 / 2017-02-20 + +* 2 bugfixes: + * Fix typo which blew up MiniSSL ([#1182]) + * Stop overriding command-line options with the config file ([#1203]) + +## 3.7.0 / 2017-01-04 + +* 6 minor features: + * Allow rack handler to accept ssl host. ([#1129]) + * Refactor TTOU processing. TTOU now handles multiple signals at once. ([#1165]) + * Pickup any remaining chunk data as the next request. + * Prevent short term thread churn - increased auto trim default to 30 seconds. + * Raise error when `stdout` or `stderr` is not writable. ([#1175]) + * Add Rack 2.0 support to gemspec. ([#1068]) + +* 5 refactors: + * Compare host and server name only once per call. ([#1091]) + * Minor refactor on Thread pool ([#1088]) + * Removed a ton of unused constants, variables and files. + * Use MRI macros when allocating heap memory + * Use hooks for on\_booted event. ([#1160]) + +* 14 bugfixes: + * Add eof? method to NullIO? ([#1169]) + * Fix Puma startup in provided init.d script ([#1061]) + * Fix default SSL mode back to none. ([#1036]) + * Fixed the issue of @listeners getting nil io ([#1120]) + * Make `get_dh1024` compatible with OpenSSL v1.1.0 ([#1178]) + * More gracefully deal with SSL sessions. Fixes [#1002] + * Move puma.rb to just autoloads. Fixes [#1063] + * MiniSSL: Provide write as <<. Fixes [#1089] + * Prune bundler should inherit fds ([#1114]) + * Replace use of Process.getpgid which does not behave as intended on all platforms ([#1110]) + * Transfer encoding header should be downcased before comparison ([#1135]) + * Use same write log logic for hijacked requests. ([#1081]) + * Fix `uninitialized constant Puma::StateFile` ([#1138]) + * Fix access priorities of each level in LeveledOptions ([#1118]) + +* 3 others: + + * Lots of tests added/fixed/improved. Switched to Minitest from Test::Unit. Big thanks to @frodsan. + * Lots of documentation added/improved. + * Add license indicators to the HTTP extension. ([#1075]) + +## 3.6.2 / 2016-11-22 + +* 1 bug fix: + + * Revert [#1118]/Fix access priorities of each level in LeveledOptions. This + had an unintentional side effect of changing the importance of command line + options, such as -p. + +## 3.6.1 / 2016-11-21 + +* 8 bug fixes: + + * Fix Puma start in init.d script. + * Fix default SSL mode back to none. Fixes [#1036] + * Fixed the issue of @listeners getting nil io, fix rails restart ([#1120]) + * More gracefully deal with SSL sessions. Fixes [#1002] + * Prevent short term thread churn. + * Provide write as <<. Fixes [#1089] + * Fix access priorities of each level in LeveledOptions - fixes TTIN. + * Stub description files updated for init.d. + +* 2 new project committers: + + * Nate Berkopec (@nateberkopec) + * Richard Schneeman (@schneems) + +## 3.6.0 / 2016-07-24 + +* 12 bug fixes: + * Add ability to detect a shutting down server. Fixes [#932] + * Add support for Expect: 100-continue. Fixes [#519] + * Check SSLContext better. Fixes [#828] + * Clarify behavior of '-t num'. Fixes [#984] + * Don't default to VERIFY_PEER. Fixes [#1028] + * Don't use ENV['PWD'] on windows. Fixes [#1023] + * Enlarge the scope of catching app exceptions. Fixes [#1027] + * Execute background hooks after daemonizing. Fixes [#925] + * Handle HUP as a stop unless there is IO redirection. Fixes [#911] + * Implement chunked request handling. Fixes [#620] + * Just rescue exception to return a 500. Fixes [#1027] + * Redirect IO in the jruby daemon mode. Fixes [#778] + +## 3.5.2 / 2016-07-20 + +* 1 bug fix: + * Don't let persistent_timeout be nil + +* 1 PR merged: + * Merge pull request [#1021] from benzrf/patch-1 + +## 3.5.1 / 2016-07-20 + +* 1 bug fix: + * Be sure to only listen on host:port combos once. Fixes [#1022] + +## 3.5.0 / 2016-07-18 + +* 1 minor features: + * Allow persistent_timeout to be configured via the dsl. + +* 9 bug fixes: + * Allow a bare % in a query string. Fixes [#958] + * Explicitly listen on all localhost addresses. Fixes [#782] + * Fix `TCPLogger` log error in tcp cluster mode. + * Fix puma/puma[#968] Cannot bind SSL port due to missing verify_mode option + * Fix puma/puma[#968] Default verify_mode to peer + * Log any exceptions in ThreadPool. Fixes [#1010] + * Silence connection errors in the reactor. Fixes [#959] + * Tiny fixes in hook documentation for [#840] + * It should not log requests if we want it to be quiet + +* 5 doc fixes: + * Add How to stop Puma on Heroku using plugins to the example directory + * Provide both hot and phased restart in jungle script + * Update reference to the instances management script + * Update default number of threads + * Fix typo in example config + +* 14 PRs merged: + * Merge pull request [#1007] from willnet/patch-1 + * Merge pull request [#1014] from jeznet/patch-1 + * Merge pull request [#1015] from bf4/patch-1 + * Merge pull request [#1017] from jorihardman/configurable_persistent_timeout + * Merge pull request [#954] from jf/master + * Merge pull request [#955] from jf/add-request-info-to-standard-error-rescue + * Merge pull request [#956] from maxkwallace/master + * Merge pull request [#960] from kmayer/kmayer-plugins-heroku-restart + * Merge pull request [#969] from frankwong15/master + * Merge pull request [#970] from willnet/delete-blank-document + * Merge pull request [#974] from rocketjob/feature/name_threads + * Merge pull request [#977] from snow/master + * Merge pull request [#981] from zach-chai/patch-1 + * Merge pull request [#993] from scorix/master + +## 3.4.0 / 2016-04-07 + +* 2 minor features: + * Add ability to force threads to stop on shutdown. Fixes [#938] + * Detect and commit seppuku when fork(2) fails. Fixes [#529] + +* 3 unknowns: + * Ignore errors trying to update the backport tables. Fixes [#788] + * Invoke the lowlevel_error in more places to allow for exception tracking. Fixes [#894] + * Update the query string when an absolute URI is used. Fixes [#937] + +* 5 doc fixes: + * Add Process Monitors section to top-level README + * Better document the hooks. Fixes [#840] + * docs/system.md sample config refinements and elaborations + * Fix typos at couple of places. + * Cleanup warnings + +* 3 PRs merged: + * Merge pull request [#945] from dekellum/systemd-docs-refined + * Merge pull request [#946] from vipulnsward/rm-pid + * Merge pull request [#947] from vipulnsward/housekeeping-typos + +## 3.3.0 / 2016-04-05 + +* 2 minor features: + * Allow overriding options of Configuration object + * Rename to inherit_ssl_listener like inherit_tcp|unix + +* 2 doc fixes: + * Add docs/systemd.md (with socket activation sub-section) + * Document UNIX signals with cluster on README.md + +* 3 PRs merged: + * Merge pull request [#936] from prathamesh-sonpatki/allow-overriding-config-options + * Merge pull request [#940] from kyledrake/signalsdoc + * Merge pull request [#942] from dekellum/socket-activate-improve + +## 3.2.0 / 2016-03-20 + +* 1 deprecation removal: + * Delete capistrano.rb + +* 3 bug fixes: + * Detect gems.rb as well as Gemfile + * Simplify and fix logic for directory to use when restarting for all phases + * Speed up phased-restart start + +* 2 PRs merged: + * Merge pull request [#927] from jlecour/gemfile_variants + * Merge pull request [#931] from joneslee85/patch-10 + +## 3.1.1 / 2016-03-17 + +* 4 bug fixes: + * Disable USR1 usage on JRuby + * Fixes [#922] - Correctly define file encoding as UTF-8 + * Set a more explicit SERVER_SOFTWARE Rack variable + * Show RUBY_ENGINE_VERSION if available. Fixes [#923] + +* 3 PRs merged: + * Merge pull request [#912] from tricknotes/fix-allow-failures-in-travis-yml + * Merge pull request [#921] from swrobel/patch-1 + * Merge pull request [#924] from tbrisker/patch-1 + +## 3.1.0 / 2016-03-05 + +* 1 minor feature: + * Add 'import' directive to config file. Fixes [#916] + +* 5 bug fixes: + * Add 'fetch' to options. Fixes [#913] + * Fix jruby daemonization. Fixes [#918] + * Recreate the proper args manually. Fixes [#910] + * Require 'time' to get iso8601. Fixes [#914] + +## 3.0.2 / 2016-02-26 + +* 5 bug fixes: + + * Fix 'undefined local variable or method `pid` for #' when execute pumactl with `--pid` option. + * Fix 'undefined method `windows?` for Puma:Module' when execute pumactl. + * Harden tmp_restart against errors related to the restart file + * Make `plugin :tmp_restart` behavior correct in Windows. + * fix uninitialized constant Puma::ControlCLI::StateFile + +* 3 PRs merged: + + * Merge pull request [#901] from mitto/fix-pumactl-uninitialized-constant-statefile + * Merge pull request [#902] from corrupt952/fix_undefined_method_and_variable_when_execute_pumactl + * Merge pull request [#905] from Eric-Guo/master + +## 3.0.1 / 2016-02-25 + +* 1 bug fix: + + * Removed the experimental support for async.callback as it broke + websockets entirely. Seems no server has both hijack and async.callback + and thus faye is totally confused what to do and doesn't work. + +## 3.0.0 / 2016-02-25 + +* 2 major changes: + + * Ruby pre-2.0 is no longer supported. We'll do our best to not add + features that break those rubies but will no longer be testing + with them. + * Don't log requests by default. Fixes [#852] + +* 2 major features: + + * Plugin support! Plugins can interact with configuration as well + as provide augment server functionality! + * Experimental env['async.callback'] support + +* 4 minor features: + + * Listen to unix socket with provided backlog if any + * Improves the clustered stats to report worker stats + * Pass the env to the lowlevel_error handler. Fixes [#854] + * Treat path-like hosts as unix sockets. Fixes [#824] + +* 5 bug fixes: + + * Clean thread locals when using keepalive. Fixes [#823] + * Cleanup compiler warnings. Fixes [#815] + * Expose closed? for use by the reactor. Fixes [#835] + * Move signal handlers to separate method to prevent space leak. Fixes [#798] + * Signal not full on worker exit [#876] + +* 5 doc fixes: + + * Update README.md with various grammar fixes + * Use newest version of Minitest + * Add directory configuration docs, fix typo [ci skip] + * Remove old COPYING notice. Fixes [#849] + +* 10 merged PRs: + + * Merge pull request [#871] from deepj/travis + * Merge pull request [#874] from wallclockbuilder/master + * Merge pull request [#883] from dadah89/igor/trim_only_worker + * Merge pull request [#884] from uistudio/async-callback + * Merge pull request [#888] from mlarraz/tick_minitest + * Merge pull request [#890] from todd/directory_docs + * Merge pull request [#891] from ctaintor/improve_clustered_status + * Merge pull request [#893] from spastorino/add_missing_require + * Merge pull request [#897] from zendesk/master + * Merge pull request [#899] from kch/kch-readme-fixes + +## 2.16.0 / 2016-01-27 + +* 7 minor features: + + * Add 'set_remote_address' config option + * Allow to run puma in silent mode + * Expose cli options in DSL + * Support passing JRuby keystore info in ssl_bind DSL + * Allow umask for unix:/// style control urls + * Expose `old_worker_count` in stats url + * Support TLS client auth (verify_mode) in jruby + +* 7 bug fixes: + + * Don't persist before_fork hook in state file + * Reload bundler before pulling in rack. Fixes [#859] + * Remove NEWRELIC_DISPATCHER env variable + * Cleanup C code + * Use Timeout.timeout instead of Object.timeout + * Make phased restarts faster + * Ignore the case of certain headers, because HTTP + +* 1 doc changes: + + * Test against the latest Ruby 2.1, 2.2, 2.3, head and JRuby 9.0.4.0 on Travis + +* 12 merged PRs + * Merge pull request [#822] from kwugirl/remove_NEWRELIC_DISPATCHER + * Merge pull request [#833] from joemiller/jruby-client-tls-auth + * Merge pull request [#837] from YuriSolovyov/ssl-keystore-jruby + * Merge pull request [#839] from mezuka/master + * Merge pull request [#845] from deepj/timeout-deprecation + * Merge pull request [#846] from sriedel/strip_before_fork + * Merge pull request [#850] from deepj/travis + * Merge pull request [#853] from Jeffrey6052/patch-1 + * Merge pull request [#857] from zendesk/faster_phased_restarts + * Merge pull request [#858] from mlarraz/fix_some_warnings + * Merge pull request [#860] from zendesk/expose_old_worker_count + * Merge pull request [#861] from zendesk/allow_control_url_umask + +## 2.15.3 / 2015-11-07 + +* 1 bug fix: + + * Fix JRuby parser + +## 2.15.2 / 2015-11-06 + +* 2 bug fixes: + * ext/puma_http11: handle duplicate headers as per RFC + * Only set ctx.ca iff there is a params['ca'] to set with. + +* 2 PRs merged: + * Merge pull request [#818] from unleashed/support-duplicate-headers + * Merge pull request [#819] from VictorLowther/fix-ca-and-verify_null-exception + +## 2.15.1 / 2015-11-06 + +* 1 bug fix: + + * Allow older openssl versions + +## 2.15.0 / 2015-11-06 + +* 6 minor features: + * Allow setting ca without setting a verify mode + * Make jungle for init.d support rbenv + * Use SSL_CTX_use_certificate_chain_file for full chain + * cluster: add worker_boot_timeout option + * configuration: allow empty tags to mean no tag desired + * puma/cli: support specifying STD{OUT,ERR} redirections and append mode + +* 5 bug fixes: + * Disable SSL Compression + * Fix bug setting worker_directory when using a symlink directory + * Fix error message in DSL that was slightly inaccurate + * Pumactl: set correct process name. Fixes [#563] + * thread_pool: fix race condition when shutting down workers + +* 10 doc fixes: + * Add before_fork explanation in Readme.md + * Correct spelling in DEPLOYMENT.md + * Correct spelling in docs/nginx.md + * Fix spelling errors. + * Fix typo in deployment description + * Fix typos (it's -> its) in events.rb and server.rb + * fixing for typo mentioned in [#803] + * Spelling correction for README + * thread_pool: fix typos in comment + * More explicit docs for worker_timeout + +* 18 PRs merged: + * Merge pull request [#768] from nathansamson/patch-1 + * Merge pull request [#773] from rossta/spelling_corrections + * Merge pull request [#774] from snow/master + * Merge pull request [#781] from sunsations/fix-typo + * Merge pull request [#791] from unleashed/allow_empty_tags + * Merge pull request [#793] from robdimarco/fix-working-directory-symlink-bug + * Merge pull request [#794] from peterkeen/patch-1 + * Merge pull request [#795] from unleashed/redirects-from-cmdline + * Merge pull request [#796] from cschneid/fix_dsl_message + * Merge pull request [#799] from annafw/master + * Merge pull request [#800] from liamseanbrady/fix_typo + * Merge pull request [#801] from scottjg/ssl-chain-file + * Merge pull request [#802] from scottjg/ssl-crimes + * Merge pull request [#804] from burningTyger/patch-2 + * Merge pull request [#809] from unleashed/threadpool-fix-race-in-shutdown + * Merge pull request [#810] from vlmonk/fix-pumactl-restart-bug + * Merge pull request [#814] from schneems/schneems/worker_timeout-docs + * Merge pull request [#817] from unleashed/worker-boot-timeout + +## 2.14.0 / 2015-09-18 + +* 1 minor feature: + * Make building with SSL support optional + +* 1 bug fix: + * Use Rack::Builder if available. Fixes [#735] + +## 2.13.4 / 2015-08-16 + +* 1 bug fix: + * Use the environment possible set by the config early and from + the config file later (if set). + +## 2.13.3 / 2015-08-15 + +Seriously, I need to revamp config with tests. + +* 1 bug fix: + * Fix preserving options before cleaning for state. Fixes [#769] + +## 2.13.2 / 2015-08-15 + +The "clearly I don't have enough tests for the config" release. + +* 1 bug fix: + * Fix another place binds wasn't initialized. Fixes [#767] + +## 2.13.1 / 2015-08-15 + +* 2 bug fixes: + * Fix binds being masked in config files. Fixes [#765] + * Use options from the config file properly in pumactl. Fixes [#764] + +## 2.13.0 / 2015-08-14 + +* 1 minor feature: + * Add before_fork hooks option. + +* 3 bug fixes: + * Check for OPENSSL_NO_ECDH before using ECDH + * Eliminate logging overhead from JRuby SSL + * Prefer cli options over config file ones. Fixes [#669] + +* 1 deprecation: + * Add deprecation warning to capistrano.rb. Fixes [#673] + +* 4 PRs merged: + * Merge pull request [#668] from kcollignon/patch-1 + * Merge pull request [#754] from nathansamson/before_boot + * Merge pull request [#759] from BenV/fix-centos6-build + * Merge pull request [#761] from looker/no-log + +## 2.12.3 / 2015-08-03 + +* 8 minor bugs fixed: + * Fix Capistrano 'uninitialized constant Puma' error. + * Fix some ancient and incorrect error handling code + * Fix uninitialized constant error + * Remove toplevel rack interspection, require rack on load instead + * Skip empty parts when chunking + * Switch from inject to each in config_ru_binds iteration + * Wrap SSLv3 spec in version guard. + * ruby 1.8.7 compatibility patches + +* 4 PRs merged: + * Merge pull request [#742] from deivid-rodriguez/fix_missing_require + * Merge pull request [#743] from matthewd/skip-empty-chunks + * Merge pull request [#749] from huacnlee/fix-cap-uninitialized-puma-error + * Merge pull request [#751] from costi/compat_1_8_7 + +* 1 test fix: + * Add 1.8.7, rbx-1 (allow failures) to Travis. + +## 2.12.2 / 2015-07-17 + +* 2 bug fix: + * Pull over and use Rack::URLMap. Fixes [#741] + * Stub out peercert on JRuby for now. Fixes [#739] + +## 2.12.1 / 2015-07-16 + +* 2 bug fixes: + * Use a constant format. Fixes [#737] + * Use strerror for Windows sake. Fixes [#733] + +* 1 doc change: + * typo fix: occured -> occurred + +* 1 PR merged: + * Merge pull request [#736] from paulanunda/paulanunda/typo-fix + +## 2.12.0 / 2015-07-14 + +* 13 bug fixes: + * Add thread reaping to thread pool + * Do not automatically use chunked responses when hijacked + * Do not suppress Content-Length on partial hijack + * Don't allow any exceptions to terminate a thread + * Handle ENOTCONN client disconnects when setting REMOTE_ADDR + * Handle very early exit of cluster mode. Fixes [#722] + * Install rack when running tests on travis to use rack/lint + * Make puma -v and -h return success exit code + * Make pumactl load config/puma.rb by default + * Pass options from pumactl properly when pruning. Fixes [#694] + * Remove rack dependency. Fixes [#705] + * Remove the default Content-Type: text/plain + * Add Client Side Certificate Auth + +* 8 doc/test changes: + * Added example sourcing of environment vars + * Added tests for bind configuration on rackup file + * Fix example config text + * Update DEPLOYMENT.md + * Update Readme with example of custom error handler + * ci: Improve Travis settings + * ci: Start running tests against JRuby 9k on Travis + * ci: Convert to container infrastructure for travisci + +* 2 ops changes: + * Check for system-wide rbenv + * capistrano: Add additional env when start rails + +* 16 PRs merged: + * Merge pull request [#686] from jjb/patch-2 + * Merge pull request [#693] from rob-murray/update-example-config + * Merge pull request [#697] from spk/tests-bind-on-rackup-file + * Merge pull request [#699] from deees/fix/require_rack_builder + * Merge pull request [#701] from deepj/master + * Merge pull request [#702] from Jimdo/thread-reaping + * Merge pull request [#703] from deepj/travis + * Merge pull request [#704] from grega/master + * Merge pull request [#709] from lian/master + * Merge pull request [#711] from julik/master + * Merge pull request [#712] from yakara-ltd/pumactl-default-config + * Merge pull request [#715] from RobotJiang/master + * Merge pull request [#725] from rwz/master + * Merge pull request [#726] from strenuus/handle-client-disconnect + * Merge pull request [#729] from allaire/patch-1 + * Merge pull request [#730] from iamjarvo/container-infrastructure + +## 2.11.3 / 2015-05-18 + +* 5 bug fixes: + * Be sure to unlink tempfiles after a request. Fixes [#690] + * Coerce the key to a string before checking. (thar be symbols). Fixes [#684] + * Fix hang on bad SSL handshake + * Remove `enable_SSLv3` support from JRuby + +* 1 PR merged: + * Merge pull request [#698] from looker/hang-handshake + +## 2.11.2 / 2015-04-11 + +* 2 minor features: + * Add `on_worker_fork` hook, which allows to mimic Unicorn's behavior + * Add shutdown_debug config option + +* 4 bug fixes: + * Fix the Config constants not being available in the DSL. Fixes [#683] + * Ignore multiple port declarations + * Proper 'Connection' header handling compatible with HTTP 1.[01] protocols + * Use "Puma" instead of "puma" to reporting to New Relic + +* 1 doc fixes: + * Add Gitter badge. + +* 6 PRs merged: + * Merge pull request [#657] from schneems/schneems/puma-once-port + * Merge pull request [#658] from Tomohiro/newrelic-dispatcher-default-update + * Merge pull request [#662] from basecrm/connection-compatibility + * Merge pull request [#664] from fxposter/on-worker-fork + * Merge pull request [#667] from JuanitoFatas/doc/gemspec + * Merge pull request [#672] from chulkilee/refactor + +## 2.11.1 / 2015-02-11 + +* 2 bug fixes: + * Avoid crash in strange restart conditions + * Inject the GEM_HOME that bundler into puma-wild's env. Fixes [#653] + +* 2 PRs merged: + * Merge pull request [#644] from bpaquet/master + * Merge pull request [#646] from mkonecny/master + +## 2.11.0 / 2015-01-20 + +* 9 bug fixes: + * Add mode as an additional bind option to unix sockets. Fixes [#630] + * Advertise HTTPS properly after a hot restart + * Don't write lowlevel_error_handler to state + * Fix phased restart with stuck requests + * Handle spaces in the path properly. Fixes [#622] + * Set a default REMOTE_ADDR to avoid using peeraddr on unix sockets. Fixes [#583] + * Skip device number checking on jruby. Fixes [#586] + * Update extconf.rb to compile correctly on OS X + * redirect io right after daemonizing so startup errors are shown. Fixes [#359] + +* 6 minor features: + * Add a configuration option that prevents puma from queueing requests. + * Add reload_worker_directory + * Add the ability to pass environment variables to the init script (for Jungle). + * Add the proctitle tag to the worker. Fixes [#633] + * Infer a proctitle tag based on the directory + * Update lowlevel error message to be more meaningful. + +* 10 PRs merged: + * Merge pull request [#478] from rubencaro/master + * Merge pull request [#610] from kwilczynski/master + * Merge pull request [#611] from jasonl/better-lowlevel-message + * Merge pull request [#616] from jc00ke/master + * Merge pull request [#623] from raldred/patch-1 + * Merge pull request [#628] from rdpoor/master + * Merge pull request [#634] from deepj/master + * Merge pull request [#637] from raskhadafi/patch-1 + * Merge pull request [#639] from ebeigarts/fix-phased-restarts + * Merge pull request [#640] from codehotter/issue-612-dependent-requests-deadlock + +## 2.10.2 / 2014-11-26 + +* 1 bug fix: + * Conditionalize thread local cleaning, fixes perf degradation fix + The code to clean out all Thread locals adds pretty significant + overhead to a each request, so it has to be turned on explicitly + if a user needs it. + +## 2.10.1 / 2014-11-24 + +* 1 bug fix: + * Load the app after daemonizing because the app might start threads. + + This change means errors loading the app are now reported only in the redirected + stdout/stderr. + + If you're app has problems starting up, start it without daemon mode initially + to test. + +## 2.10.0 / 2014-11-23 + +* 3 minor features: + * Added on_worker_shutdown hook mechanism + * Allow binding to ipv6 addresses for ssl URIs + * Warn about any threads started during app preload + +* 5 bug fixes: + * Clean out a threads local data before doing work + * Disable SSLv3. Fixes [#591] + * First change the directory to use the correct Gemfile. + * Only use config.ru binds if specified. Fixes [#606] + * Strongish cipher suite with FS support for some browsers + +* 2 doc changes: + * Change umask examples to more permissive values + * fix typo in README.md + +* 9 Merged PRs: + * Merge pull request [#560] from raskhadafi/prune_bundler-bug + * Merge pull request [#566] from sheltond/master + * Merge pull request [#593] from andruby/patch-1 + * Merge pull request [#594] from hassox/thread-cleanliness + * Merge pull request [#596] from burningTyger/patch-1 + * Merge pull request [#601] from sorentwo/friendly-umask + * Merge pull request [#602] from 1334/patch-1 + * Merge pull request [#608] from Gu1/master + * Merge pull request [#538] from memiux/? + +## 2.9.2 / 2014-10-25 + +* 8 bug fixes: + * Fix puma-wild handling a restart properly. Fixes [#550] + * JRuby SSL POODLE update + * Keep deprecated features warnings + * Log the current time when Puma shuts down. + * Fix cross-platform extension library detection + * Use the correct Windows names for OpenSSL. + * Better error logging during startup + * Fixing sexist error messages + +* 6 PRs merged: + * Merge pull request [#549] from bsnape/log-shutdown-time + * Merge pull request [#553] from lowjoel/master + * Merge pull request [#568] from mariuz/patch-1 + * Merge pull request [#578] from danielbuechele/patch-1 + * Merge pull request [#581] from alexch/slightly-better-logging + * Merge pull request [#590] from looker/jruby_disable_sslv3 + +## 2.9.1 / 2014-09-05 + +* 4 bug fixes: + * Cleanup the SSL related structures properly, fixes memory leak + * Fix thread spawning edge case. + * Force a worker check after a worker boots, don't wait 5sec. Fixes [#574] + * Implement SIGHUP for logs reopening + +* 2 PRs merged: + * Merge pull request [#561] from theoldreader/sighup + * Merge pull request [#570] from havenwood/spawn-thread-edge-case + +## 2.9.0 / 2014-07-12 + +* 1 minor feature: + * Add SSL support for JRuby + +* 3 bug fixes: + * Typo BUNDLER_GEMFILE -> BUNDLE_GEMFILE + * Use fast_write because we can't trust syswrite + * pumactl - do not modify original ARGV + +* 4 doc fixes: + * BSD-3-Clause over BSD to avoid confusion + * Deploy doc: clarification of the GIL + * Fix typo in DEPLOYMENT.md + * Update README.md + +* 6 PRs merged: + * Merge pull request [#520] from misfo/patch-2 + * Merge pull request [#530] from looker/jruby-ssl + * Merge pull request [#537] from vlmonk/patch-1 + * Merge pull request [#540] from allaire/patch-1 + * Merge pull request [#544] from chulkilee/bsd-3-clause + * Merge pull request [#551] from jcxplorer/patch-1 + +## 2.8.2 / 2014-04-12 + +* 4 bug fixes: + * During upgrade, change directory in main process instead of workers. + * Close the client properly on error + * Capistrano: fallback from phased restart to start when not started + * Allow tag option in conf file + +* 4 doc fixes: + * Fix Puma daemon service README typo + * `preload_app!` instead of `preload_app` + * add preload_app and prune_bundler to example config + * allow changing of worker_timeout in config file + +* 11 PRs merged: + * Merge pull request [#487] from ckuttruff/master + * Merge pull request [#492] from ckuttruff/master + * Merge pull request [#493] from alepore/config_tag + * Merge pull request [#503] from mariuz/patch-1 + * Merge pull request [#505] from sammcj/patch-1 + * Merge pull request [#506] from FlavourSys/config_worker_timeout + * Merge pull request [#510] from momer/rescue-block-handle-servers-fix + * Merge pull request [#511] from macool/patch-1 + * Merge pull request [#514] from edogawaconan/refactor_env + * Merge pull request [#517] from misfo/patch-1 + * Merge pull request [#518] from LongMan/master + +## 2.8.1 / 2014-03-06 + +* 1 bug fixes: + * Run puma-wild with proper deps for prune_bundler + +* 2 doc changes: + * Described the configuration file finding behavior added in 2.8.0 and how to disable it. + * Start the deployment doc + +* 6 PRs merged: + * Merge pull request [#471] from arthurnn/fix_test + * Merge pull request [#485] from joneslee85/patch-9 + * Merge pull request [#486] from joshwlewis/patch-1 + * Merge pull request [#490] from tobinibot/patch-1 + * Merge pull request [#491] from brianknight10/clarify-no-config + +## 2.8.0 / 2014-02-28 + +* 8 minor features: + * Add ability to autoload a config file. Fixes [#438] + * Add ability to detect and terminate hung workers. Fixes [#333] + * Add booted_workers to stats response + * Add config to customize the default error message + * Add prune_bundler option + * Add worker indexes, expose them via on_worker_boot. Fixes [#440] + * Add pretty process name + * Show the ruby version in use + +* 7 bug fixes: + * Added 408 status on timeout. + * Be more hostile with sockets that write block. Fixes [#449] + * Expect at_exit to exclusively remove the pidfile. Fixes [#444] + * Expose latency and listen backlog via bind query. Fixes [#370] + * JRuby raises IOError if the socket is there. Fixes [#377] + * Process requests fairly. Fixes [#406] + * Rescue SystemCallError as well. Fixes [#425] + +* 4 doc changes: + * Add 2.1.0 to the matrix + * Add Code Climate badge to README + * Create signals.md + * Set the license to BSD. Fixes [#432] + +* 14 PRs merged: + * Merge pull request [#428] from alexeyfrank/capistrano_default_hooks + * Merge pull request [#429] from namusyaka/revert-const_defined + * Merge pull request [#431] from mrb/master + * Merge pull request [#433] from alepore/process-name + * Merge pull request [#437] from ibrahima/master + * Merge pull request [#446] from sudara/master + * Merge pull request [#451] from pwiebe/status_408 + * Merge pull request [#453] from joevandyk/patch-1 + * Merge pull request [#470] from arthurnn/fix_458 + * Merge pull request [#472] from rubencaro/master + * Merge pull request [#480] from jjb/docs-on-running-test-suite + * Merge pull request [#481] from schneems/master + * Merge pull request [#482] from prathamesh-sonpatki/signals-doc-cleanup + * Merge pull request [#483] from YotpoLtd/master + +## 2.7.1 / 2013-12-05 + +* 1 bug fix: + * Keep STDOUT/STDERR the right mode. Fixes [#422] + +## 2.7.0 / 2013-12-03 + +* 1 minor feature: + * Adding TTIN and TTOU to increment/decrement workers + +* N bug fixes: + * Always use our Process.daemon because it's not busted + * Add capistrano restart failback to start. + * Change position of `cd` so that rvm gemset is loaded + * Clarify some platform specifics + * Do not close the pipe sockets when retrying + * Fix String#byteslice for Ruby 1.9.1, 1.9.2 + * Fix compatibility with 1.8.7. + * Handle IOError closed stream in IO.select + * Increase the max URI path length to 2048 chars from 1024 chars + * Upstart jungle use config/puma.rb instead + +## 2.6.0 / 2013-09-13 + +* 2 minor features: + * Add support for event hooks + ** Add a hook for state transitions + * Add phased restart to capistrano recipe. + +* 4 bug fixes: + * Convince workers to stop by SIGKILL after timeout + * Define RSTRING_NOT_MODIFIED for Rubinius performance + * Handle BrokenPipe, StandardError and IOError in fat_wrote and break out + * Return success status to the invoking environment + +## 2.5.1 / 2013-08-13 + +* 2 bug fixes: + * Keep jruby daemon mode from retrying on a hot restart + * Extract version from const.rb in gemspec + +## 2.5.0 / 2013-08-08 + +* 2 minor features: + * Allow configuring pumactl with config.rb + * make `pumactl restart` start puma if not running + +* 6 bug fixes: + * Autodetect ruby managers and home directory in upstart script + * Convert header values to string before sending. + * Correctly report phased-restart availability + * Fix pidfile creation/deletion race on jruby daemonization + * Use integers when comparing thread counts + * Fix typo in using lopez express (raw tcp) mode + +* 6 misc changes: + * Fix typo in phased-restart response + * Uncomment setuid/setgid by default in upstart + * Use Puma::Const::PUMA_VERSION in gemspec + * Update upstart comments to reflect new commandline + * Remove obsolete pumactl instructions; refer to pumactl for details + * Make Bundler used puma.gemspec version agnostic + +## 2.4.1 / 2013-08-07 + +* 1 experimental feature: + * Support raw tcp servers (aka Lopez Express mode) + +## 2.4.0 / 2013-07-22 + +* 5 minor features: + * Add PUMA_JRUBY_DAEMON_OPTS to get around agent starting twice + * Add ability to drain accept socket on shutdown + * Add port to DSL + * Adds support for using puma config file in capistrano deploys. + * Make phased_restart fallback to restart if not available + +* 10 bug fixes: + + * Be sure to only delete the pid in the master. Fixes [#334] + * Call out -C/--config flags + * Change parser symbol names to avoid clash. Fixes [#179] + * Convert thread pool sizes to integers + * Detect when the jruby daemon child doesn't start properly + * Fix typo in CLI help + * Improve the logging output when hijack is used. Fixes [#332] + * Remove unnecessary thread pool size conversions + * Setup :worker_boot as an Array. Fixes [#317] + * Use 127.0.0.1 as REMOTE_ADDR of unix client. Fixes [#309] + + +## 2.3.2 / 2013-07-08 + +* 1 bug fix: + * Move starting control server to after daemonization. + +## 2.3.1 / 2013-07-06 + +* 2 bug fixes: + * Include the right files in the Manifest. + * Disable inheriting connections on restart on windows. Fixes [#166] + +* 1 doc change: + * Better document some platform constraints + +## 2.3.0 / 2013-07-05 + +* 1 major bug fix: + * Stabilize control server, add support in cluster mode + +* 5 minor bug fixes: + * Add ability to cleanup stale unix sockets + * Check status data better. Fixes [#292] + * Convert raw IO errors to ConnectionError. Fixes [#274] + * Fix sending Content-Type and Content-Length for no body status. Fixes [#304] + * Pass state path through to `pumactl start`. Fixes [#287] + +* 2 internal changes: + * Refactored modes into seperate classes that CLI uses + * Changed CLI to take an Events object instead of stdout/stderr (API change) + +## 2.2.2 / 2013-07-02 + +* 1 bug fix: + * Fix restart_command in the config + +## 2.2.1 / 2013-07-02 + +* 1 minor feature: + * Introduce preload flag + +* 1 bug fix: + * Pass custom restart command in JRuby + +## 2.2.0 / 2013-07-01 + +* 1 major feature: + * Add ability to preload rack app + +* 2 minor bugfixes: + * Don't leak info when not in development. Fixes [#256] + * Load the app, then bind the ports + +## 2.1.1 / 2013-06-20 + +* 2 minor bug fixes: + + * Fix daemonization on jruby + * Load the application before daemonizing. Fixes [#285] + +## 2.1.0 / 2013-06-18 + +* 3 minor features: + * Allow listening socket to be configured via Capistrano variable + * Output results from 'stat's command when using pumactl + * Support systemd socket activation + +* 15 bug fixes: + * Deal with pipes closing while stopping. Fixes [#270] + * Error out early if there is no app configured + * Handle ConnectionError rather than the lowlevel exceptions + * tune with `-C` config file and `on_worker_boot` + * use `-w` + * Fixed some typos in upstart scripts + * Make sure to use bytesize instead of size (MiniSSL write) + * Fix an error in puma-manager.conf + * fix: stop leaking sockets on restart (affects ruby 1.9.3 or before) + * Ignore errors on the cross-thread pipe. Fixes [#246] + * Ignore errors while uncorking the socket (it might already be closed) + * Ignore the body on a HEAD request. Fixes [#278] + * Handle all engine data when possible. Fixes [#251]. + * Handle all read exceptions properly. Fixes [#252] + * Handle errors from the server better + +* 3 doc changes: + * Add note about on_worker_boot hook + * Add some documentation for Clustered mode + * Added quotes to /etc/puma.conf + +## 2.0.1 / 2013-04-30 + +* 1 bug fix: + * Fix not starting on JRuby properly + +## 2.0.0 / 2013-04-29 + +RailsConf 2013 edition! + +* 2 doc changes: + * Start with rackup -s Puma, NOT rackup -s puma. + * Minor doc fixes in the README.md, Capistrano section + +* 2 bug fixes: + * Fix reading RACK_ENV properly. Fixes [#234] + * Make cap recipe handle tmp/sockets; fixes [#228] + +* 3 minor changes: + * Fix capistrano recipe + * Fix stdout/stderr logs to sync outputs + * allow binding to IPv6 addresses + +## 2.0.0.b7 / 2013-03-18 + +* 5 minor enhancements: + * Add -q option for :start + * Add -V, --version + * Add default Rack handler helper + * Upstart support + * Set worker directory from configuration file + +* 12 bug fixes: + * Close the binder in the right place. Fixes [#192] + * Handle early term in workers. Fixes [#206] + * Make sure that the default port is 80 when the request doesn't include HTTP_X_FORWARDED_PROTO. + * Prevent Errno::EBADF errors on restart when running ruby 2.0 + * Record the proper @master_pid + * Respect the header HTTP_X_FORWARDED_PROTO when the host doesn't include a port number. + * Retry EAGAIN/EWOULDBLOCK during syswrite + * Run exec properly to restart. Fixes [#154] + * Set Rack run_once to false + * Syncronize all access to @timeouts. Fixes [#208] + * Write out the state post-daemonize. Fixes [#189] + * Prevent crash when all workers are gone + +## 2.0.0.b6 / 2013-02-06 + +* 2 minor enhancements: + * Add hook for running when a worker boots + * Advertise the Configuration object for apps to use. + +* 1 bug fix: + * Change directory in working during upgrade. Fixes [#185] + +## 2.0.0.b5 / 2013-02-05 + +* 2 major features: + * Add phased worker upgrade + * Add support for the rack hijack protocol + +* 2 minor features: + * Add -R to specify the restart command + * Add config file option to specify the restart command + +* 5 bug fixes: + * Cleanup pipes properly. Fixes [#182] + * Daemonize earlier so that we don't lose app threads. Fixes [#183] + * Drain the notification pipe. Fixes [#176], thanks @cryo28 + * Move write_pid to after we daemonize. Fixes [#180] + * Redirect IO properly and emit message for checkpointing + +## 2.0.0.b4 / 2012-12-12 + +* 4 bug fixes: + * Properly check #syswrite's value for variable sized buffers. Fixes [#170] + * Shutdown status server properly + * Handle char vs byte and mixing syswrite with write properly + * made MiniSSL validate key/cert file existence + +## 2.0.0.b3 / 2012-11-22 + +* 1 bug fix: + * Package right files in gem + +## 2.0.0.b2 / 2012-11-18 +* 5 minor feature: + * Now Puma is bundled with an capistrano recipe. Just require + 'puma/capistrano' in you deploy.rb + * Only inject CommonLogger in development mode + * Add -p option to pumactl + * Add ability to use pumactl to start a server + * Add options to daemonize puma + +* 7 bug fixes: + * Reset the IOBuffer properly. Fixes [#148] + * Shutdown gracefully on JRuby with Ctrl-C + * Various methods to get newrelic to start. Fixes [#128] + * fixing syntax error at capistrano recipe + * Force ECONNRESET when read returns nil + * Be sure to empty the drain the todo before shutting down. Fixes [#155] + * allow for alternate locations for status app + +## 2.0.0.b1 / 2012-09-11 + +* 1 major feature: + * Optional worker process mode (-w) to allow for process scaling in + addition to thread scaling + +* 1 bug fix: + * Introduce Puma::MiniSSL to be able to properly control doing + nonblocking SSL + +NOTE: SSL support in JRuby is not supported at present. Support will +be added back in a future date when a java Puma::MiniSSL is added. + +## 1.6.3 / 2012-09-04 + +* 1 bug fix: + * Close sockets waiting in the reactor when a hot restart is performed + so that browsers reconnect on the next request + +## 1.6.2 / 2012-08-27 + +* 1 bug fix: + * Rescue StandardError instead of IOError to handle SystemCallErrors + as well as other application exceptions inside the reactor. + +## 1.6.1 / 2012-07-23 + +* 1 packaging bug fixed: + * Include missing files + +## 1.6.0 / 2012-07-23 + +* 1 major bug fix: + * Prevent slow clients from starving the server by introducing a + dedicated IO reactor thread. Credit for reporting goes to @meh. + +## 1.5.0 / 2012-07-19 + +* 7 contributors to this release: + * Christian Mayer + * Darío Javier Cravero + * Dirkjan Bussink + * Gianluca Padovani + * Santiago Pastorino + * Thibault Jouan + * tomykaira + +* 6 bug fixes: + * Define RSTRING_NOT_MODIFIED for Rubinius + * Convert status to integer. Fixes [#123] + * Delete pidfile when stopping the server + * Allow compilation with -Werror=format-security option + * Fix wrong HTTP version for a HTTP/1.0 request + * Use String#bytesize instead of String#length + +* 3 minor features: + * Added support for setting RACK_ENV via the CLI, config file, and rack app + * Allow Server#run to run sync. Fixes [#111] + * Puma can now run on windows + +## 1.4.0 / 2012-06-04 + +* 1 bug fix: + * SCRIPT_NAME should be passed from env to allow mounting apps + +* 1 experimental feature: + * Add puma.socket key for direct socket access + +## 1.3.1 / 2012-05-15 + +* 2 bug fixes: + * use #bytesize instead of #length for Content-Length header + * Use StringIO properly. Fixes [#98] + +## 1.3.0 / 2012-05-08 + +* 2 minor features: + * Return valid Rack responses (passes Lint) from status server + * Add -I option to specify $LOAD_PATH directories + +* 4 bug fixes: + * Don't join the server thread inside the signal handle. Fixes [#94] + * Make NullIO#read mimic IO#read + * Only stop the status server if it's started. Fixes [#84] + * Set RACK_ENV early in cli also. Fixes [#78] + +* 1 new contributor: + * Jesse Cooke + +## 1.2.2 / 2012-04-28 + +* 4 bug fixes: + * Report a lowlevel error to stderr + * Set a fallback SERVER_NAME and SERVER_PORT + * Keep the encoding of the body correct. Fixes [#79] + * show error.to_s along with backtrace for low-level error + +## 1.2.1 / 2012-04-11 + +* 1 bug fix: + * Fix rack.url_scheme for SSL servers. Fixes [#65] + +## 1.2.0 / 2012-04-11 + +* 1 major feature: + * When possible, the internal restart does a "hot restart" meaning + the server sockets remains open, so no connections are lost. + +* 1 minor feature: + * More helpful fallback error message + +* 6 bug fixes: + * Pass the proper args to unknown_error. Fixes [#54], [#58] + * Stop the control server before restarting. Fixes [#61] + * Fix reporting https only on a true SSL connection + * Set the default content type to 'text/plain'. Fixes [#63] + * Use REUSEADDR. Fixes [#60] + * Shutdown gracefully on SIGTERM. Fixes [#53] + +* 2 new contributors: + * Seamus Abshere + * Steve Richert + +## 1.1.1 / 2012-03-30 + +* 1 bugfix: + * Include puma/compat.rb in the gem (oops!) + +## 1.1.0 / 2012-03-30 + +* 1 bugfix: + * Make sure that the unix socket has the perms 0777 by default + +* 1 minor feature: + * Add umask param to the unix:// bind to set the umask + +## 1.0.0 / 2012-03-29 + +* Released! + +## Ignore - this is for maintainers to copy-paste during release +## Master + +* Features + * Your feature goes here (#Github Number) + +* Bugfixes + * Your bugfix goes here (#Github Number) + +[#3570]:https://github.com/puma/puma/pull/3570 "PR by @mohamedhafez, merged 2024-12-30" +[#3567]:https://github.com/puma/puma/issues/3567 "Issue by @mohamedhafez, closed 2024-12-30" +[#3383]:https://github.com/puma/puma/pull/3383 "PR by @joshuay03, merged 2024-11-29" +[#3386]:https://github.com/puma/puma/pull/3386 "PR by @Drakula2k, merged 2024-11-27" +[#3517]:https://github.com/puma/puma/pull/3517 "PR by @jjb, merged 2024-11-26" +[#3375]:https://github.com/puma/puma/pull/3375 "PR by @joshuay03, merged 2024-11-23" +[#3348]:https://github.com/puma/puma/pull/3348 "PR by @tomurb, merged 2024-11-23" +[#3302]:https://github.com/puma/puma/issues/3302 "Issue by @benburkert, closed 2024-11-23" +[#3384]:https://github.com/puma/puma/pull/3384 "PR by @joshuay03, merged 2024-11-23" +[#3590]:https://github.com/puma/puma/pull/3590 "PR by @MSP-Greg, merged 2025-01-01" +[#3552]:https://github.com/puma/puma/issues/3552 "Issue by @utay, closed 2025-01-01" +[#3568]:https://github.com/puma/puma/pull/3568 "PR by @joshuay03, merged 2024-12-11" +[#3505]:https://github.com/puma/puma/pull/3505 "PR by @AnthonyClark, merged 2025-01-27" +[#3595]:https://github.com/puma/puma/pull/3595 "PR by @nateberkopec, merged 2025-01-07" +[#3565]:https://github.com/puma/puma/pull/3565 "PR by @MSP-Greg, merged 2024-11-28" +[#3376]:https://github.com/puma/puma/pull/3376 "PR by @joshuay03, merged 2024-11-23" +[#3407]:https://github.com/puma/puma/pull/3407 "PR by @JacobEvelyn, merged 2024-11-05" +[#3439]:https://github.com/puma/puma/pull/3439 "PR by @codergeek121, merged 2024-11-04" +[#3437]:https://github.com/puma/puma/issues/3437 "Issue by @rafaelfranca, closed 2024-11-04" +[#3486]:https://github.com/puma/puma/pull/3486 "PR by @mohamedhafez, merged 2024-09-26" +[#3422]:https://github.com/puma/puma/issues/3422 "Issue by @mohamedhafez, closed 2024-09-26" +[#3496]:https://github.com/puma/puma/pull/3496 "PR by @slizco, merged 2024-09-26" +[#3485]:https://github.com/puma/puma/pull/3485 "PR by @MSP-Greg, merged 2024-09-21" +[#3359]:https://github.com/puma/puma/pull/3359 "PR by @willayton, merged 2024-04-11" +[#3343]:https://github.com/puma/puma/issues/3343 "Issue by @willayton, closed 2024-04-11" +[#3309]:https://github.com/puma/puma/pull/3309 "PR by @byroot, merged 2024-01-09" +[#3425]:https://github.com/puma/puma/pull/3425 "PR by @mohamedhafez, merged 2024-07-14" +[#3424]:https://github.com/puma/puma/issues/3424 "Issue by @mohamedhafez, closed 2024-07-14" +[#3411]:https://github.com/puma/puma/pull/3411 "PR by @OuYangJinTing, merged 2024-06-15" +[#3380]:https://github.com/puma/puma/pull/3380 "PR by @emilyst, closed 2024-06-15" +[#3539]:https://github.com/puma/puma/pull/3539 "PR by @caius, merged 2024-11-20" +[#3532]:https://github.com/puma/puma/pull/3532 "PR by @MSP-Greg, merged 2024-10-24" +[#3531]:https://github.com/puma/puma/issues/3531 "Issue by @tagliala, closed 2024-10-24" +[#3214]:https://github.com/puma/puma/pull/3214 "PR by @MSP-Greg, merged 2024-10-15" +[#3468]:https://github.com/puma/puma/pull/3468 "PR by @foca, merged 2024-10-04" +[#3508]:https://github.com/puma/puma/pull/3508 "PR by @MayCXC, merged 2024-10-02" +[#3360]:https://github.com/puma/puma/pull/3360 "PR by @ioquatix, merged 2024-04-24" +[#3338]:https://github.com/puma/puma/pull/3338 "PR by @MSP-Greg, merged 2024-04-11" +[#3337]:https://github.com/puma/puma/issues/3337 "Issue by @skliew, closed 2024-04-11" +[#3332]:https://github.com/puma/puma/pull/3332 "PR by @evanphx, merged 2024-02-18" +[#3308]:https://github.com/puma/puma/pull/3308 "PR by @MSP-Greg, merged 2024-01-31" +[#3307]:https://github.com/puma/puma/issues/3307 "Issue by @nateberkopec, closed 2024-01-31" +[#3314]:https://github.com/puma/puma/pull/3314 "PR by @stanhu, merged 2024-01-26" +[#3313]:https://github.com/puma/puma/issues/3313 "Issue by @stanhu, closed 2024-01-26" +[#3518]:https://github.com/puma/puma/pull/3518 "PR by @roque86, merged 2024-11-15" +[#3467]:https://github.com/puma/puma/pull/3467 "PR by @MSP-Greg, merged 2024-09-21" +[#3341]:https://github.com/puma/puma/pull/3341 "PR by @joshuay03, merged 2024-03-11" +[#3548]:https://github.com/puma/puma/pull/3548 "PR by @MSP-Greg, merged 2024-11-21" +[#3325]:https://github.com/puma/puma/pull/3325 "PR by @OuYangJinTing, merged 2024-10-22" +[#3527]:https://github.com/puma/puma/pull/3527 "PR by @MSP-Greg, merged 2024-10-26" +[#3513]:https://github.com/puma/puma/pull/3513 "PR by @jjb, merged 2024-10-11" +[#3510]:https://github.com/puma/puma/pull/3510 "PR by @MSP-Greg, merged 2024-10-03" +[#3370]:https://github.com/puma/puma/pull/3370 "PR by @MSP-Greg, merged 2024-04-15" +[#3340]:https://github.com/puma/puma/pull/3340 "PR by @joshuay03, merged 2024-03-10" +[#3318]:https://github.com/puma/puma/pull/3318 "PR by @joshuay03, merged 2024-01-15" +[#3514]:https://github.com/puma/puma/pull/3514 "PR by @jjb, merged 2024-10-11" +[#3434]:https://github.com/puma/puma/pull/3434 "PR by @olleolleolle, merged 2024-09-19" +[#3435]:https://github.com/puma/puma/pull/3435 "PR by @olleolleolle, merged 2024-09-19" +[#3495]:https://github.com/puma/puma/pull/3495 "PR by @MSP-Greg, merged 2024-09-19" +[#3256]:https://github.com/puma/puma/pull/3256 "PR by @MSP-Greg, merged 2023-10-16" +[#3235]:https://github.com/puma/puma/pull/3235 "PR by @joshuay03, merged 2023-10-03" +[#3228]:https://github.com/puma/puma/issues/3228 "Issue by @davidalejandroaguilar, closed 2023-10-03" +[#3282]:https://github.com/puma/puma/issues/3282 "Issue by @bensheldon, closed 2024-01-02" +[#3283]:https://github.com/puma/puma/pull/3283 "PR by @joshuay03, merged 2024-01-02" +[#3225]:https://github.com/puma/puma/pull/3225 "PR by @joshuay03, merged 2023-09-27" +[#2786]:https://github.com/puma/puma/issues/2786 "Issue by @vitiokss, closed 2023-09-27" +[#3179]:https://github.com/puma/puma/pull/3179 "PR by @MSP-Greg, merged 2023-09-26" +[#3255]:https://github.com/puma/puma/pull/3255 "PR by @casperisfine, merged 2023-10-19" +[#3276]:https://github.com/puma/puma/pull/3276 "PR by @casperisfine, merged 2023-11-16" +[#3271]:https://github.com/puma/puma/pull/3271 "PR by @MSP-Greg, merged 2023-10-30" +[#3266]:https://github.com/puma/puma/issues/3266 "Issue by @Dragonicity, closed 2023-10-30" +[#3270]:https://github.com/puma/puma/pull/3270 "PR by @MSP-Greg, merged 2023-10-30" +[#3265]:https://github.com/puma/puma/pull/3265 "PR by @MSP-Greg, merged 2023-10-25" +[#3264]:https://github.com/puma/puma/issues/3264 "Issue by @dentarg, closed 2023-10-25" +[#3254]:https://github.com/puma/puma/pull/3254 "PR by @casperisfine, merged 2023-10-11" +[#3245]:https://github.com/puma/puma/pull/3245 "PR by @olleolleolle, merged 2023-10-02" +[#3293]:https://github.com/puma/puma/pull/3293 "PR by @MSP-Greg, merged 2023-12-21" +[#3301]:https://github.com/puma/puma/pull/3301 "PR by @benburkert, merged 2023-12-29" +[#3248]:https://github.com/puma/puma/pull/3248 "PR by @dentarg, merged 2023-10-04" +[#3298]:https://github.com/puma/puma/pull/3298 "PR by @til, merged 2023-12-26" +[#2920]:https://github.com/puma/puma/pull/2920 "PR by @biinari, merged 2023-07-11" +[#3195]:https://github.com/puma/puma/pull/3195 "PR by @binarygit, merged 2023-08-15" +[#3209]:https://github.com/puma/puma/pull/3209 "PR by @joshuay03, merged 2023-09-04" +[#2580]:https://github.com/puma/puma/issues/2580 "Issue by @schuetzm, closed 2023-09-04" +[#3204]:https://github.com/puma/puma/pull/3204 "PR by @dhavalsingh, merged 2023-08-25" +[#3191]:https://github.com/puma/puma/pull/3191 "PR by @MSP-Greg, merged 2023-08-31" +[#3165]:https://github.com/puma/puma/pull/3165 "PR by @fallwith, merged 2023-06-06" +[#3174]:https://github.com/puma/puma/pull/3174 "PR by @copiousfreetime, merged 2023-06-11" +[#3181]:https://github.com/puma/puma/pull/3181 "PR by @MSP-Greg, merged 2023-06-23" +[#3187]:https://github.com/puma/puma/pull/3187 "PR by @MSP-Greg, merged 2023-06-30" +[#3094]:https://github.com/puma/puma/pull/3094 "PR by @Vuta, merged 2023-07-23" +[#3106]:https://github.com/puma/puma/pull/3106 "PR by @MSP-Greg, merged 2023-05-29" +[#3014]:https://github.com/puma/puma/issues/3014 "Issue by @kyledrake, closed 2023-05-29" +[#3161]:https://github.com/puma/puma/pull/3161 "PR by @MSP-Greg, merged 2023-05-27" +[#3037]:https://github.com/puma/puma/issues/3037 "Issue by @daisy1754, closed 2023-05-27" +[#3133]:https://github.com/puma/puma/pull/3133 "PR by @stanhu, merged 2023-04-30" +[#3132]:https://github.com/puma/puma/issues/3132 "Issue by @stanhu, closed 2023-04-30" +[#3163]:https://github.com/puma/puma/pull/3163 "PR by @MSP-Greg, merged 2023-05-27" +[#3155]:https://github.com/puma/puma/pull/3155 "PR by @dentarg, merged 2023-05-14" +[#3148]:https://github.com/puma/puma/issues/3148 "Issue by @dentarg, closed 2023-05-14" +[#3129]:https://github.com/puma/puma/pull/3129 "PR by @MSP-Greg, merged 2023-05-02" +[#3137]:https://github.com/puma/puma/pull/3137 "PR by @MSP-Greg, merged 2023-04-30" +[#3156]:https://github.com/puma/puma/pull/3156 "PR by @severin, merged 2023-05-16" +[#3162]:https://github.com/puma/puma/pull/3162 "PR by @MSP-Greg, merged 2023-05-23" +[#3151]:https://github.com/puma/puma/pull/3151 "PR by @nateberkopec, merged 2023-05-12" +[#3118]:https://github.com/puma/puma/pull/3118 "PR by @ninoseki, merged 2023-04-01" +[#3117]:https://github.com/puma/puma/issues/3117 "Issue by @ninoseki, closed 2023-04-01" +[#3109]:https://github.com/puma/puma/pull/3109 "PR by @ahorek, merged 2023-03-31" +[#3108]:https://github.com/puma/puma/issues/3108 "Issue by @treviateo, closed 2023-03-31" +[#3113]:https://github.com/puma/puma/pull/3113 "PR by @collinsauve, merged 2023-03-31" +[#3112]:https://github.com/puma/puma/issues/3112 "Issue by @dmke, closed 2023-03-31" +[#3111]:https://github.com/puma/puma/pull/3111 "PR by @adzap, merged 2023-03-30" +[#2770]:https://github.com/puma/puma/pull/2770 "PR by @vzajkov, merged 2023-03-29" +[#2511]:https://github.com/puma/puma/issues/2511 "Issue by @jchristie55332, closed 2021-12-12" +[#3089]:https://github.com/puma/puma/pull/3089 "PR by @Vuta, merged 2023-03-06" +[#2709]:https://github.com/puma/puma/pull/2709 "PR by @rodzyn, merged 2023-02-20" +[#3091]:https://github.com/puma/puma/pull/3091 "PR by @MSP-Greg, merged 2023-03-28" +[#3074]:https://github.com/puma/puma/pull/3074 "PR by @MSP-Greg, merged 2023-03-14" +[#3072]:https://github.com/puma/puma/pull/3072 "PR by @MSP-Greg, merged 2023-02-17" +[#3079]:https://github.com/puma/puma/pull/3079 "PR by @mohamedhafez, merged 2023-02-24" +[#3080]:https://github.com/puma/puma/pull/3080 "PR by @MSP-Greg, merged 2023-02-16" +[#3058]:https://github.com/puma/puma/pull/3058 "PR by @dentarg, merged 2023-01-29" +[#3007]:https://github.com/puma/puma/issues/3007 "Issue by @MSP-Greg, closed 2023-01-29" +[#3011]:https://github.com/puma/puma/pull/3011 "PR by @joaomarcos96, merged 2023-01-03" +[#3006]:https://github.com/puma/puma/pull/3006 "PR by @QWYNG, merged 2023-02-09" +[#2604]:https://github.com/puma/puma/issues/2604 "Issue by @dgoetz, closed 2023-02-09" +[#3040]:https://github.com/puma/puma/pull/3040 "PR by @shayonj, merged 2023-01-02" +[#3036]:https://github.com/puma/puma/pull/3036 "PR by @MSP-Greg, merged 2023-01-13" +[#3020]:https://github.com/puma/puma/issues/3020 "Issue by @dentarg, closed 2023-01-13" +[#3061]:https://github.com/puma/puma/pull/3061 "PR by @MSP-Greg, merged 2023-02-12" +[#3057]:https://github.com/puma/puma/issues/3057 "Issue by @mmarvb8h, closed 2023-02-12" +[#3065]:https://github.com/puma/puma/pull/3065 "PR by @MSP-Greg, merged 2023-02-11" +[#3062]:https://github.com/puma/puma/pull/3062 "PR by @willkoehler, merged 2023-01-29" +[#3035]:https://github.com/puma/puma/pull/3035 "PR by @MSP-Greg, merged 2022-12-24" +[#3033]:https://github.com/puma/puma/issues/3033 "Issue by @jules-w2, closed 2022-12-24" +[#3016]:https://github.com/puma/puma/pull/3016 "PR by @MSP-Greg, merged 2022-12-24" +[#3005]:https://github.com/puma/puma/pull/3005 "PR by @JuanitoFatas, merged 2022-11-04" +[#3004]:https://github.com/puma/puma/pull/3004 "PR by @MSP-Greg, merged 2022-11-24" +[#3000]:https://github.com/puma/puma/issues/3000 "Issue by @dentarg, closed 2022-11-24" +[#3002]:https://github.com/puma/puma/pull/3002 "PR by @MSP-Greg, merged 2022-11-03" +[#2999]:https://github.com/puma/puma/issues/2999 "Issue by @aymeric-ledorze, closed 2022-11-03" +[#3013]:https://github.com/puma/puma/pull/3013 "PR by @MSP-Greg, merged 2022-11-13" +[#2919]:https://github.com/puma/puma/pull/2919 "PR by @MSP-Greg, merged 2022-08-30" +[#2652]:https://github.com/puma/puma/issues/2652 "Issue by @Roguelazer, closed 2022-09-04" +[#2653]:https://github.com/puma/puma/pull/2653 "PR by @Roguelazer, closed 2022-03-07" +[#2849]:https://github.com/puma/puma/pull/2849 "PR by @kares, merged 2022-04-09" +[#2933]:https://github.com/puma/puma/pull/2933 "PR by @cafedomancer, merged 2022-09-09" +[#2925]:https://github.com/puma/puma/issues/2925 "Issue by @nateberkopec, closed 2022-09-09" +[#2940]:https://github.com/puma/puma/pull/2940 "PR by @cafedomancer, merged 2022-09-10" +[#2924]:https://github.com/puma/puma/pull/2924 "PR by @cafedomancer, merged 2022-09-07" +[#2853]:https://github.com/puma/puma/issues/2853 "Issue by @nateberkopec, closed 2022-09-07" +[#2957]:https://github.com/puma/puma/pull/2957 "PR by @JuanitoFatas, merged 2022-09-16" +[#2958]:https://github.com/puma/puma/pull/2958 "PR by @JuanitoFatas, merged 2022-09-16" +[#2959]:https://github.com/puma/puma/pull/2959 "PR by @JuanitoFatas, merged 2022-09-16" +[#2960]:https://github.com/puma/puma/pull/2960 "PR by @JuanitoFatas, merged 2022-09-16" +[#2988]:https://github.com/puma/puma/pull/2988 "PR by @MSP-Greg, merged 2022-10-12" +[#2928]:https://github.com/puma/puma/pull/2928 "PR by @nateberkopec, merged 2022-09-10" +[#2798]:https://github.com/puma/puma/pull/2798 "PR by @johnnyshields, merged 2022-02-05" +[#2932]:https://github.com/puma/puma/pull/2932 "PR by @mrzasa, merged 2022-09-12" +[#2896]:https://github.com/puma/puma/pull/2896 "PR by @MSP-Greg, merged 2022-09-13" +[#2892]:https://github.com/puma/puma/pull/2892 "PR by @guilleiguaran, closed 2022-09-13" +[#2923]:https://github.com/puma/puma/pull/2923 "PR by @nateberkopec, merged 2022-09-09" +[#2740]:https://github.com/puma/puma/pull/2740 "PR by @ioquatix, merged 2022-01-29" +[#2845]:https://github.com/puma/puma/issues/2845 "Issue by @donv, closed 2022-03-22" +[#2917]:https://github.com/puma/puma/pull/2917 "PR by @MSP-Greg, merged 2022-09-19" +[#2915]:https://github.com/puma/puma/issues/2915 "Issue by @mperham, closed 2022-09-19" +[#2907]:https://github.com/puma/puma/pull/2907 "PR by @casperisfine, merged 2022-09-15" +[#2953]:https://github.com/puma/puma/pull/2953 "PR by @JuanitoFatas, merged 2022-09-14" +[#2936]:https://github.com/puma/puma/pull/2936 "PR by @MSP-Greg, merged 2022-09-09" +[#2931]:https://github.com/puma/puma/issues/2931 "Issue by @dentarg, closed 2022-09-09" +[#2875]:https://github.com/puma/puma/pull/2875 "PR by @ylecuyer, merged 2022-05-19" +[#2840]:https://github.com/puma/puma/pull/2840 "PR by @LukaszMaslej, merged 2022-04-13" +[#2774]:https://github.com/puma/puma/pull/2774 "PR by @ob-stripe, merged 2022-01-31" +[#2891]:https://github.com/puma/puma/pull/2891 "PR by @gingerlime, merged 2022-06-02" +[#2886]:https://github.com/puma/puma/pull/2886 "PR by @kares, merged 2022-05-30" +[#2899]:https://github.com/puma/puma/pull/2899 "PR by @kares, merged 2022-07-04" +[#2904]:https://github.com/puma/puma/pull/2904 "PR by @kares, merged 2022-08-27" +[#2884]:https://github.com/puma/puma/pull/2884 "PR by @kares, merged 2022-05-30" +[#2897]:https://github.com/puma/puma/pull/2897 "PR by @Edouard-chin, merged 2022-08-27" +[#1441]:https://github.com/puma/puma/issues/1441 "Issue by @nirvdrum, closed 2022-09-12" +[#2956]:https://github.com/puma/puma/pull/2956 "PR by @MSP-Greg, merged 2022-09-15" +[#2888]:https://github.com/puma/puma/pull/2888 "PR by @MSP-Greg, merged 2022-06-01" +[#2797]:https://github.com/puma/puma/pull/2797 "PR by @johnnyshields, merged 2022-02-01" +[#2795]:https://github.com/puma/puma/pull/2795 "PR by @johnnyshields, merged 2022-01-31" +[#2903]:https://github.com/puma/puma/pull/2903 "PR by @MSP-Greg, merged 2022-08-27" +[#2942]:https://github.com/puma/puma/pull/2942 "PR by @nateberkopec, merged 2022-09-15" +[#2921]:https://github.com/puma/puma/issues/2921 "Issue by @MSP-Greg, closed 2022-09-15" +[#2922]:https://github.com/puma/puma/issues/2922 "Issue by @MSP-Greg, closed 2022-09-10" +[#2955]:https://github.com/puma/puma/pull/2955 "PR by @cafedomancer, merged 2022-09-15" +[#3166]:https://github.com/puma/puma/pull/3166 "PR by @JoeDupuis, merged 2023-06-08" +[#2868]:https://github.com/puma/puma/pull/2868 "PR by @MSP-Greg, merged 2022-06-02" +[#2866]:https://github.com/puma/puma/issues/2866 "Issue by @slondr, closed 2022-06-02" +[#2883]:https://github.com/puma/puma/pull/2883 "PR by @MSP-Greg, merged 2022-06-02" +[#2890]:https://github.com/puma/puma/pull/2890 "PR by @kares, merged 2022-06-01" +[#2729]:https://github.com/puma/puma/issues/2729 "Issue by @kares, closed 2022-06-01" +[#2885]:https://github.com/puma/puma/pull/2885 "PR by @MSP-Greg, merged 2022-05-30" +[#2839]:https://github.com/puma/puma/issues/2839 "Issue by @wlipa, closed 2022-05-30" +[#2864]:https://github.com/puma/puma/pull/2864 "PR by @MSP-Greg, merged 2022-04-26" +[#2863]:https://github.com/puma/puma/issues/2863 "Issue by @eradman, closed 2022-04-26" +[#2861]:https://github.com/puma/puma/pull/2861 "PR by @BlakeWilliams, merged 2022-04-17" +[#2856]:https://github.com/puma/puma/issues/2856 "Issue by @nateberkopec, closed 2022-04-17" +[#2855]:https://github.com/puma/puma/pull/2855 "PR by @stanhu, merged 2022-04-09" +[#2848]:https://github.com/puma/puma/pull/2848 "PR by @stanhu, merged 2022-04-02" +[#2847]:https://github.com/puma/puma/pull/2847 "PR by @stanhu, merged 2022-04-02" +[#2838]:https://github.com/puma/puma/pull/2838 "PR by @epsilon-0, merged 2022-03-03" +[#2817]:https://github.com/puma/puma/pull/2817 "PR by @khustochka, merged 2022-02-20" +[#2810]:https://github.com/puma/puma/pull/2810 "PR by @kzkn, merged 2022-01-27" +[#2809]:https://github.com/puma/puma/pull/2809 "PR by @dentarg, merged 2022-01-26" +[#2764]:https://github.com/puma/puma/pull/2764 "PR by @dentarg, merged 2022-01-18" +[#2708]:https://github.com/puma/puma/issues/2708 "Issue by @erikaxel, closed 2022-01-18" +[#2780]:https://github.com/puma/puma/pull/2780 "PR by @dalibor, merged 2022-01-01" +[#2784]:https://github.com/puma/puma/pull/2784 "PR by @MSP-Greg, merged 2022-01-01" +[#2773]:https://github.com/puma/puma/pull/2773 "PR by @ob-stripe, merged 2022-01-01" +[#2794]:https://github.com/puma/puma/pull/2794 "PR by @johnnyshields, merged 2022-01-10" +[#2759]:https://github.com/puma/puma/pull/2759 "PR by @ob-stripe, merged 2021-12-11" +[#2731]:https://github.com/puma/puma/pull/2731 "PR by @baelter, merged 2021-11-02" +[#2341]:https://github.com/puma/puma/issues/2341 "Issue by @cjlarose, closed 2023-07-23" +[#2728]:https://github.com/puma/puma/pull/2728 "PR by @dalibor, merged 2021-10-31" +[#2733]:https://github.com/puma/puma/pull/2733 "PR by @ob-stripe, merged 2021-12-12" +[#2807]:https://github.com/puma/puma/pull/2807 "PR by @MSP-Greg, merged 2022-01-25" +[#2806]:https://github.com/puma/puma/issues/2806 "Issue by @olleolleolle, closed 2022-01-25" +[#2799]:https://github.com/puma/puma/pull/2799 "PR by @ags, merged 2022-01-22" +[#2785]:https://github.com/puma/puma/pull/2785 "PR by @MSP-Greg, merged 2022-01-02" +[#2757]:https://github.com/puma/puma/pull/2757 "PR by @MSP-Greg, merged 2021-11-24" +[#2745]:https://github.com/puma/puma/pull/2745 "PR by @MSP-Greg, merged 2021-11-03" +[#2742]:https://github.com/puma/puma/pull/2742 "PR by @MSP-Greg, merged 2021-12-12" +[#2730]:https://github.com/puma/puma/pull/2730 "PR by @kares, merged 2021-11-01" +[#2702]:https://github.com/puma/puma/pull/2702 "PR by @jacobherrington, merged 2021-09-21" +[#2610]:https://github.com/puma/puma/pull/2610 "PR by @ye-lin-aung, merged 2021-08-18" +[#2257]:https://github.com/puma/puma/issues/2257 "Issue by @nateberkopec, closed 2021-08-18" +[#2654]:https://github.com/puma/puma/pull/2654 "PR by @Roguelazer, merged 2021-09-07" +[#2651]:https://github.com/puma/puma/issues/2651 "Issue by @Roguelazer, closed 2021-09-07" +[#2689]:https://github.com/puma/puma/pull/2689 "PR by @jacobherrington, merged 2021-09-05" +[#2700]:https://github.com/puma/puma/pull/2700 "PR by @ioquatix, merged 2021-09-16" +[#2699]:https://github.com/puma/puma/issues/2699 "Issue by @ioquatix, closed 2021-09-16" +[#2690]:https://github.com/puma/puma/pull/2690 "PR by @doits, merged 2021-09-06" +[#2688]:https://github.com/puma/puma/pull/2688 "PR by @jdelStrother, merged 2021-09-03" +[#2687]:https://github.com/puma/puma/issues/2687 "Issue by @jdelStrother, closed 2021-09-03" +[#2675]:https://github.com/puma/puma/pull/2675 "PR by @devwout, merged 2021-09-08" +[#2657]:https://github.com/puma/puma/pull/2657 "PR by @olivierbellone, merged 2021-07-13" +[#2648]:https://github.com/puma/puma/pull/2648 "PR by @MSP-Greg, merged 2021-06-27" +[#1412]:https://github.com/puma/puma/issues/1412 "Issue by @x-yuri, closed 2021-06-27" +[#2586]:https://github.com/puma/puma/pull/2586 "PR by @MSP-Greg, merged 2021-05-26" +[#2569]:https://github.com/puma/puma/issues/2569 "Issue by @tarragon, closed 2021-05-26" +[#2643]:https://github.com/puma/puma/pull/2643 "PR by @MSP-Greg, merged 2021-06-27" +[#2638]:https://github.com/puma/puma/issues/2638 "Issue by @gingerlime, closed 2021-06-27" +[#2642]:https://github.com/puma/puma/pull/2642 "PR by @MSP-Greg, merged 2021-06-16" +[#2633]:https://github.com/puma/puma/pull/2633 "PR by @onlined, merged 2021-06-04" +[#2656]:https://github.com/puma/puma/pull/2656 "PR by @olivierbellone, merged 2021-07-07" +[#2666]:https://github.com/puma/puma/pull/2666 "PR by @MSP-Greg, merged 2021-07-25" +[#2630]:https://github.com/puma/puma/pull/2630 "PR by @seangoedecke, merged 2021-05-20" +[#2626]:https://github.com/puma/puma/issues/2626 "Issue by @rorymckinley, closed 2021-05-20" +[#2629]:https://github.com/puma/puma/pull/2629 "PR by @ye-lin-aung, merged 2021-05-20" +[#2628]:https://github.com/puma/puma/pull/2628 "PR by @wjordan, merged 2021-05-20" +[#2625]:https://github.com/puma/puma/issues/2625 "Issue by @jarthod, closed 2021-05-11" +[#2564]:https://github.com/puma/puma/pull/2564 "PR by @MSP-Greg, merged 2021-04-24" +[#2526]:https://github.com/puma/puma/issues/2526 "Issue by @nerdrew, closed 2021-04-24" +[#2559]:https://github.com/puma/puma/pull/2559 "PR by @ylecuyer, merged 2021-03-11" +[#2528]:https://github.com/puma/puma/issues/2528 "Issue by @cjlarose, closed 2021-03-11" +[#2565]:https://github.com/puma/puma/pull/2565 "PR by @CGA1123, merged 2021-03-09" +[#2534]:https://github.com/puma/puma/issues/2534 "Issue by @nateberkopec, closed 2021-03-09" +[#2563]:https://github.com/puma/puma/pull/2563 "PR by @MSP-Greg, merged 2021-03-06" +[#2504]:https://github.com/puma/puma/issues/2504 "Issue by @fsateler, closed 2021-03-06" +[#2591]:https://github.com/puma/puma/pull/2591 "PR by @MSP-Greg, merged 2021-05-05" +[#2572]:https://github.com/puma/puma/issues/2572 "Issue by @josef-krabath, closed 2021-05-05" +[#2613]:https://github.com/puma/puma/pull/2613 "PR by @smcgivern, merged 2021-04-27" +[#2605]:https://github.com/puma/puma/pull/2605 "PR by @pascalbetz, merged 2021-04-26" +[#2584]:https://github.com/puma/puma/issues/2584 "Issue by @kaorihinata, closed 2021-04-26" +[#2607]:https://github.com/puma/puma/pull/2607 "PR by @calvinxiao, merged 2021-04-23" +[#2552]:https://github.com/puma/puma/issues/2552 "Issue by @feliperaul, closed 2021-05-24" +[#2606]:https://github.com/puma/puma/pull/2606 "PR by @wjordan, merged 2021-04-20" +[#2574]:https://github.com/puma/puma/issues/2574 "Issue by @darkhelmet, closed 2021-04-20" +[#2567]:https://github.com/puma/puma/pull/2567 "PR by @kddnewton, merged 2021-04-19" +[#2566]:https://github.com/puma/puma/issues/2566 "Issue by @kddnewton, closed 2021-04-19" +[#2596]:https://github.com/puma/puma/pull/2596 "PR by @MSP-Greg, merged 2021-04-18" +[#2588]:https://github.com/puma/puma/pull/2588 "PR by @dentarg, merged 2021-04-02" +[#2556]:https://github.com/puma/puma/issues/2556 "Issue by @gamecreature, closed 2021-04-02" +[#2585]:https://github.com/puma/puma/pull/2585 "PR by @MSP-Greg, merged 2021-03-26" +[#2583]:https://github.com/puma/puma/issues/2583 "Issue by @jboler, closed 2021-03-26" +[#2609]:https://github.com/puma/puma/pull/2609 "PR by @calvinxiao, merged 2021-04-26" +[#2590]:https://github.com/puma/puma/pull/2590 "PR by @calvinxiao, merged 2021-04-05" +[#2600]:https://github.com/puma/puma/pull/2600 "PR by @wjordan, merged 2021-04-30" +[#2579]:https://github.com/puma/puma/pull/2579 "PR by @ghiculescu, merged 2021-03-17" +[#2553]:https://github.com/puma/puma/pull/2553 "PR by @olivierbellone, merged 2021-02-10" +[#2557]:https://github.com/puma/puma/pull/2557 "PR by @cjlarose, merged 2021-02-22" +[#2550]:https://github.com/puma/puma/pull/2550 "PR by @MSP-Greg, merged 2021-02-05" +[#2547]:https://github.com/puma/puma/pull/2547 "PR by @wildmaples, merged 2021-02-03" +[#2543]:https://github.com/puma/puma/pull/2543 "PR by @MSP-Greg, merged 2021-02-01" +[#2549]:https://github.com/puma/puma/pull/2549 "PR by @nmb, merged 2021-02-04" +[#2519]:https://github.com/puma/puma/pull/2519 "PR by @MSP-Greg, merged 2021-01-26" +[#2522]:https://github.com/puma/puma/pull/2522 "PR by @jcmfernandes, merged 2021-01-12" +[#2490]:https://github.com/puma/puma/pull/2490 "PR by @Bonias, merged 2020-12-07" +[#2486]:https://github.com/puma/puma/pull/2486 "PR by @karloscodes, merged 2020-12-02" +[#2535]:https://github.com/puma/puma/pull/2535 "PR by @MSP-Greg, merged 2021-01-27" +[#2529]:https://github.com/puma/puma/pull/2529 "PR by @MSP-Greg, merged 2021-01-24" +[#2533]:https://github.com/puma/puma/pull/2533 "PR by @MSP-Greg, merged 2021-01-24" +[#1953]:https://github.com/puma/puma/issues/1953 "Issue by @nateberkopec, closed 2020-12-01" +[#2516]:https://github.com/puma/puma/pull/2516 "PR by @cjlarose, merged 2020-12-17" +[#2520]:https://github.com/puma/puma/pull/2520 "PR by @dentarg, merged 2021-01-04" +[#2521]:https://github.com/puma/puma/pull/2521 "PR by @ojab, merged 2021-01-04" +[#2531]:https://github.com/puma/puma/pull/2531 "PR by @wjordan, merged 2021-01-19" +[#2510]:https://github.com/puma/puma/pull/2510 "PR by @micke, merged 2020-12-10" +[#2472]:https://github.com/puma/puma/pull/2472 "PR by @karloscodes, merged 2020-11-02" +[#2438]:https://github.com/puma/puma/pull/2438 "PR by @ekohl, merged 2020-10-26" +[#2406]:https://github.com/puma/puma/pull/2406 "PR by @fdel15, merged 2020-10-19" +[#2449]:https://github.com/puma/puma/pull/2449 "PR by @MSP-Greg, merged 2020-10-28" +[#2362]:https://github.com/puma/puma/pull/2362 "PR by @ekohl, merged 2020-11-10" +[#2485]:https://github.com/puma/puma/pull/2485 "PR by @elct9620, merged 2020-11-18" +[#2489]:https://github.com/puma/puma/pull/2489 "PR by @MSP-Greg, merged 2020-11-27" +[#2487]:https://github.com/puma/puma/pull/2487 "PR by @MSP-Greg, merged 2020-11-17" +[#2477]:https://github.com/puma/puma/pull/2477 "PR by @MSP-Greg, merged 2020-11-16" +[#2475]:https://github.com/puma/puma/pull/2475 "PR by @nateberkopec, merged 2020-11-02" +[#2439]:https://github.com/puma/puma/pull/2439 "PR by @kuei0221, merged 2020-10-26" +[#2460]:https://github.com/puma/puma/pull/2460 "PR by @cjlarose, merged 2020-10-27" +[#2473]:https://github.com/puma/puma/pull/2473 "PR by @cjlarose, merged 2020-11-01" +[#2479]:https://github.com/puma/puma/pull/2479 "PR by @cjlarose, merged 2020-11-10" +[#2495]:https://github.com/puma/puma/pull/2495 "PR by @JuanitoFatas, merged 2020-11-27" +[#2461]:https://github.com/puma/puma/pull/2461 "PR by @cjlarose, merged 2020-10-27" +[#2454]:https://github.com/puma/puma/issues/2454 "Issue by @majksner, closed 2020-10-27" +[#2432]:https://github.com/puma/puma/pull/2432 "PR by @MSP-Greg, merged 2020-10-25" +[#2442]:https://github.com/puma/puma/pull/2442 "PR by @wjordan, merged 2020-10-22" +[#2427]:https://github.com/puma/puma/pull/2427 "PR by @cjlarose, merged 2020-10-20" +[#2018]:https://github.com/puma/puma/issues/2018 "Issue by @gingerlime, closed 2020-10-20" +[#2435]:https://github.com/puma/puma/pull/2435 "PR by @wjordan, merged 2020-10-20" +[#2431]:https://github.com/puma/puma/pull/2431 "PR by @wjordan, merged 2020-10-16" +[#2212]:https://github.com/puma/puma/issues/2212 "Issue by @junaruga, closed 2020-10-16" +[#2409]:https://github.com/puma/puma/pull/2409 "PR by @fliiiix, merged 2020-10-03" +[#2448]:https://github.com/puma/puma/pull/2448 "PR by @MSP-Greg, merged 2020-10-25" +[#2450]:https://github.com/puma/puma/pull/2450 "PR by @MSP-Greg, merged 2020-10-25" +[#2419]:https://github.com/puma/puma/pull/2419 "PR by @MSP-Greg, merged 2020-10-09" +[#2279]:https://github.com/puma/puma/pull/2279 "PR by @wjordan, merged 2020-10-06" +[#2412]:https://github.com/puma/puma/pull/2412 "PR by @MSP-Greg, merged 2020-10-06" +[#2405]:https://github.com/puma/puma/pull/2405 "PR by @MSP-Greg, merged 2020-10-05" +[#2408]:https://github.com/puma/puma/pull/2408 "PR by @fliiiix, merged 2020-10-03" +[#2374]:https://github.com/puma/puma/pull/2374 "PR by @cjlarose, merged 2020-09-29" +[#2389]:https://github.com/puma/puma/pull/2389 "PR by @MSP-Greg, merged 2020-09-29" +[#2381]:https://github.com/puma/puma/pull/2381 "PR by @joergschray, merged 2020-09-24" +[#2271]:https://github.com/puma/puma/pull/2271 "PR by @wjordan, merged 2020-09-24" +[#2377]:https://github.com/puma/puma/pull/2377 "PR by @cjlarose, merged 2020-09-23" +[#2376]:https://github.com/puma/puma/pull/2376 "PR by @alexeevit, merged 2020-09-22" +[#2372]:https://github.com/puma/puma/pull/2372 "PR by @ahorek, merged 2020-09-22" +[#2384]:https://github.com/puma/puma/pull/2384 "PR by @schneems, merged 2020-09-27" +[#2375]:https://github.com/puma/puma/pull/2375 "PR by @MSP-Greg, merged 2020-09-23" +[#2373]:https://github.com/puma/puma/pull/2373 "PR by @MSP-Greg, merged 2020-09-23" +[#2305]:https://github.com/puma/puma/pull/2305 "PR by @MSP-Greg, merged 2020-09-14" +[#2099]:https://github.com/puma/puma/pull/2099 "PR by @wjordan, merged 2020-05-11" +[#2079]:https://github.com/puma/puma/pull/2079 "PR by @ayufan, merged 2020-05-11" +[#2093]:https://github.com/puma/puma/pull/2093 "PR by @schneems, merged 2019-12-18" +[#2256]:https://github.com/puma/puma/pull/2256 "PR by @nateberkopec, merged 2020-05-11" +[#2054]:https://github.com/puma/puma/pull/2054 "PR by @composerinteralia, merged 2019-11-11" +[#2106]:https://github.com/puma/puma/pull/2106 "PR by @ylecuyer, merged 2020-02-11" +[#2167]:https://github.com/puma/puma/pull/2167 "PR by @ChrisBr, closed 2020-07-06" +[#2344]:https://github.com/puma/puma/pull/2344 "PR by @dentarg, merged 2020-08-26" +[#2203]:https://github.com/puma/puma/pull/2203 "PR by @zanker-stripe, merged 2020-03-31" +[#2220]:https://github.com/puma/puma/pull/2220 "PR by @wjordan, merged 2020-04-14" +[#2238]:https://github.com/puma/puma/pull/2238 "PR by @sthirugn, merged 2020-05-07" +[#2086]:https://github.com/puma/puma/pull/2086 "PR by @bdewater, merged 2019-12-17" +[#2253]:https://github.com/puma/puma/pull/2253 "PR by @schneems, merged 2020-05-11" +[#2288]:https://github.com/puma/puma/pull/2288 "PR by @FTLam11, merged 2020-06-02" +[#1487]:https://github.com/puma/puma/pull/1487 "PR by @jxa, merged 2018-05-09" +[#2143]:https://github.com/puma/puma/pull/2143 "PR by @jalevin, merged 2020-04-21" +[#2169]:https://github.com/puma/puma/pull/2169 "PR by @nateberkopec, merged 2020-03-10" +[#2170]:https://github.com/puma/puma/pull/2170 "PR by @nateberkopec, merged 2020-03-10" +[#2076]:https://github.com/puma/puma/pull/2076 "PR by @drews256, merged 2020-02-27" +[#2022]:https://github.com/puma/puma/pull/2022 "PR by @olleolleolle, merged 2019-11-11" +[#2300]:https://github.com/puma/puma/pull/2300 "PR by @alexeevit, merged 2020-07-06" +[#2269]:https://github.com/puma/puma/pull/2269 "PR by @MSP-Greg, merged 2020-08-31" +[#2312]:https://github.com/puma/puma/pull/2312 "PR by @MSP-Greg, merged 2020-07-20" +[#2338]:https://github.com/puma/puma/issues/2338 "Issue by @micahhainlinestitchfix, closed 2020-08-18" +[#2116]:https://github.com/puma/puma/pull/2116 "PR by @MSP-Greg, merged 2020-05-15" +[#2074]:https://github.com/puma/puma/issues/2074 "Issue by @jchristie55332, closed 2020-02-19" +[#2211]:https://github.com/puma/puma/pull/2211 "PR by @MSP-Greg, merged 2020-03-30" +[#2069]:https://github.com/puma/puma/pull/2069 "PR by @MSP-Greg, merged 2019-11-09" +[#2112]:https://github.com/puma/puma/pull/2112 "PR by @wjordan, merged 2020-03-03" +[#1893]:https://github.com/puma/puma/pull/1893 "PR by @seven1m, merged 2020-02-18" +[#2119]:https://github.com/puma/puma/pull/2119 "PR by @wjordan, merged 2020-02-20" +[#2121]:https://github.com/puma/puma/pull/2121 "PR by @wjordan, merged 2020-02-21" +[#2154]:https://github.com/puma/puma/pull/2154 "PR by @cjlarose, merged 2020-03-10" +[#1551]:https://github.com/puma/puma/issues/1551 "Issue by @austinthecoder, closed 2020-03-10" +[#2198]:https://github.com/puma/puma/pull/2198 "PR by @eregon, merged 2020-03-24" +[#2216]:https://github.com/puma/puma/pull/2216 "PR by @praboud-stripe, merged 2020-04-06" +[#2122]:https://github.com/puma/puma/pull/2122 "PR by @wjordan, merged 2020-04-10" +[#2177]:https://github.com/puma/puma/issues/2177 "Issue by @GuiTeK, closed 2020-04-08" +[#2221]:https://github.com/puma/puma/pull/2221 "PR by @wjordan, merged 2020-04-17" +[#2233]:https://github.com/puma/puma/pull/2233 "PR by @ayufan, merged 2020-04-25" +[#2234]:https://github.com/puma/puma/pull/2234 "PR by @wjordan, merged 2020-04-30" +[#2225]:https://github.com/puma/puma/issues/2225 "Issue by @nateberkopec, closed 2020-04-27" +[#2267]:https://github.com/puma/puma/pull/2267 "PR by @wjordan, merged 2020-05-20" +[#2287]:https://github.com/puma/puma/pull/2287 "PR by @eugeneius, merged 2020-05-31" +[#2317]:https://github.com/puma/puma/pull/2317 "PR by @MSP-Greg, merged 2020-09-01" +[#2319]:https://github.com/puma/puma/issues/2319 "Issue by @AlexWayfer, closed 2020-09-03" +[#2326]:https://github.com/puma/puma/pull/2326 "PR by @rkistner, closed 2020-09-04" +[#2299]:https://github.com/puma/puma/issues/2299 "Issue by @JohnPhillips31416, closed 2020-09-17" +[#2095]:https://github.com/puma/puma/pull/2095 "PR by @bdewater, merged 2019-12-25" +[#2102]:https://github.com/puma/puma/pull/2102 "PR by @bdewater, merged 2020-02-07" +[#2111]:https://github.com/puma/puma/pull/2111 "PR by @wjordan, merged 2020-02-20" +[#1980]:https://github.com/puma/puma/pull/1980 "PR by @nateberkopec, merged 2020-02-27" +[#2189]:https://github.com/puma/puma/pull/2189 "PR by @jkowens, merged 2020-03-19" +[#2124]:https://github.com/puma/puma/pull/2124 "PR by @wjordan, merged 2020-04-14" +[#2223]:https://github.com/puma/puma/pull/2223 "PR by @wjordan, merged 2020-04-20" +[#2239]:https://github.com/puma/puma/pull/2239 "PR by @wjordan, merged 2020-05-15" +[#2496]:https://github.com/puma/puma/pull/2496 "PR by @TheRusskiy, merged 2020-11-30" +[#2304]:https://github.com/puma/puma/issues/2304 "Issue by @mpeltomaa, closed 2020-09-05" +[#2132]:https://github.com/puma/puma/issues/2132 "Issue by @bmclean, closed 2020-02-28" +[#2010]:https://github.com/puma/puma/pull/2010 "PR by @nateberkopec, merged 2019-10-07" +[#2012]:https://github.com/puma/puma/pull/2012 "PR by @headius, merged 2019-10-07" +[#2046]:https://github.com/puma/puma/pull/2046 "PR by @composerinteralia, merged 2019-10-21" +[#2052]:https://github.com/puma/puma/pull/2052 "PR by @composerinteralia, merged 2019-11-02" +[#1564]:https://github.com/puma/puma/issues/1564 "Issue by @perlun, closed 2019-10-07" +[#2035]:https://github.com/puma/puma/pull/2035 "PR by @AndrewSpeed, merged 2019-10-18" +[#2048]:https://github.com/puma/puma/pull/2048 "PR by @hahmed, merged 2019-10-21" +[#2050]:https://github.com/puma/puma/pull/2050 "PR by @olleolleolle, merged 2019-10-25" +[#1842]:https://github.com/puma/puma/issues/1842 "Issue by @nateberkopec, closed 2019-09-18" +[#1988]:https://github.com/puma/puma/issues/1988 "Issue by @mcg, closed 2019-10-01" +[#1986]:https://github.com/puma/puma/issues/1986 "Issue by @flaminestone, closed 2019-10-01" +[#1994]:https://github.com/puma/puma/issues/1994 "Issue by @LimeBlast, closed 2019-10-01" +[#2006]:https://github.com/puma/puma/pull/2006 "PR by @nateberkopec, merged 2019-10-01" +[#1222]:https://github.com/puma/puma/issues/1222 "Issue by @seanmckinley, closed 2019-10-04" +[#1885]:https://github.com/puma/puma/pull/1885 "PR by @spk, merged 2019-08-10" +[#1934]:https://github.com/puma/puma/pull/1934 "PR by @zarelit, merged 2019-08-28" +[#1105]:https://github.com/puma/puma/pull/1105 "PR by @daveallie, merged 2019-09-02" +[#1786]:https://github.com/puma/puma/pull/1786 "PR by @evanphx, merged 2019-09-11" +[#1320]:https://github.com/puma/puma/pull/1320 "PR by @nateberkopec, merged 2019-09-12" +[#1968]:https://github.com/puma/puma/pull/1968 "PR by @nateberkopec, merged 2019-09-15" +[#1908]:https://github.com/puma/puma/pull/1908 "PR by @MSP-Greg, merged 2019-08-23" +[#1952]:https://github.com/puma/puma/pull/1952 "PR by @MSP-Greg, merged 2019-09-19" +[#1941]:https://github.com/puma/puma/pull/1941 "PR by @MSP-Greg, merged 2019-09-02" +[#1961]:https://github.com/puma/puma/pull/1961 "PR by @nateberkopec, merged 2019-09-11" +[#1970]:https://github.com/puma/puma/pull/1970 "PR by @MSP-Greg, merged 2019-09-18" +[#1946]:https://github.com/puma/puma/pull/1946 "PR by @nateberkopec, merged 2019-09-02" +[#1831]:https://github.com/puma/puma/pull/1831 "PR by @spk, merged 2019-07-27" +[#1816]:https://github.com/puma/puma/pull/1816 "PR by @ylecuyer, merged 2019-08-01" +[#1844]:https://github.com/puma/puma/pull/1844 "PR by @ylecuyer, merged 2019-08-01" +[#1836]:https://github.com/puma/puma/pull/1836 "PR by @MSP-Greg, merged 2019-08-06" +[#1887]:https://github.com/puma/puma/pull/1887 "PR by @MSP-Greg, merged 2019-08-06" +[#1812]:https://github.com/puma/puma/pull/1812 "PR by @kou, merged 2019-08-03" +[#1491]:https://github.com/puma/puma/pull/1491 "PR by @olleolleolle, merged 2019-07-17" +[#1837]:https://github.com/puma/puma/pull/1837 "PR by @montanalow, merged 2019-07-25" +[#1857]:https://github.com/puma/puma/pull/1857 "PR by @Jesus, merged 2019-08-03" +[#1822]:https://github.com/puma/puma/pull/1822 "PR by @Jesus, merged 2019-08-01" +[#1863]:https://github.com/puma/puma/pull/1863 "PR by @dzunk, merged 2019-08-04" +[#1838]:https://github.com/puma/puma/pull/1838 "PR by @bogn83, merged 2019-07-14" +[#1882]:https://github.com/puma/puma/pull/1882 "PR by @okuramasafumi, merged 2019-08-06" +[#1848]:https://github.com/puma/puma/pull/1848 "PR by @nateberkopec, merged 2019-07-16" +[#1847]:https://github.com/puma/puma/pull/1847 "PR by @nateberkopec, merged 2019-07-16" +[#1846]:https://github.com/puma/puma/pull/1846 "PR by @nateberkopec, merged 2019-07-16" +[#1853]:https://github.com/puma/puma/pull/1853 "PR by @Jesus, merged 2019-07-18" +[#1850]:https://github.com/puma/puma/pull/1850 "PR by @nateberkopec, merged 2019-07-27" +[#1866]:https://github.com/puma/puma/pull/1866 "PR by @josacar, merged 2019-07-28" +[#1870]:https://github.com/puma/puma/pull/1870 "PR by @MSP-Greg, merged 2019-07-30" +[#1872]:https://github.com/puma/puma/pull/1872 "PR by @MSP-Greg, merged 2019-07-30" +[#1833]:https://github.com/puma/puma/issues/1833 "Issue by @julik, closed 2019-07-09" +[#1888]:https://github.com/puma/puma/pull/1888 "PR by @ClikeX, merged 2019-08-06" +[#1829]:https://github.com/puma/puma/pull/1829 "PR by @Fudoshiki, merged 2019-07-09" +[#1832]:https://github.com/puma/puma/pull/1832 "PR by @MSP-Greg, merged 2019-07-08" +[#1827]:https://github.com/puma/puma/pull/1827 "PR by @amrrbakry, merged 2019-06-27" +[#1562]:https://github.com/puma/puma/pull/1562 "PR by @skrobul, merged 2019-02-20" +[#1569]:https://github.com/puma/puma/pull/1569 "PR by @rianmcguire, merged 2019-02-20" +[#1648]:https://github.com/puma/puma/pull/1648 "PR by @wjordan, merged 2019-02-20" +[#1691]:https://github.com/puma/puma/pull/1691 "PR by @kares, merged 2019-02-20" +[#1716]:https://github.com/puma/puma/pull/1716 "PR by @mdkent, merged 2019-02-20" +[#1690]:https://github.com/puma/puma/pull/1690 "PR by @mic-kul, merged 2019-03-11" +[#1689]:https://github.com/puma/puma/pull/1689 "PR by @michaelherold, merged 2019-03-11" +[#1728]:https://github.com/puma/puma/pull/1728 "PR by @evanphx, merged 2019-03-20" +[#1824]:https://github.com/puma/puma/pull/1824 "PR by @spk, merged 2019-06-24" +[#1685]:https://github.com/puma/puma/pull/1685 "PR by @mainameiz, merged 2019-02-20" +[#1808]:https://github.com/puma/puma/pull/1808 "PR by @schneems, merged 2019-06-10" +[#1508]:https://github.com/puma/puma/pull/1508 "PR by @florin555, merged 2019-02-20" +[#1650]:https://github.com/puma/puma/pull/1650 "PR by @adam101, merged 2019-02-20" +[#1655]:https://github.com/puma/puma/pull/1655 "PR by @mipearson, merged 2019-02-20" +[#1671]:https://github.com/puma/puma/pull/1671 "PR by @eric-norcross, merged 2019-02-20" +[#1583]:https://github.com/puma/puma/pull/1583 "PR by @chwevans, merged 2019-02-20" +[#1773]:https://github.com/puma/puma/pull/1773 "PR by @enebo, merged 2019-04-14" +[#1731]:https://github.com/puma/puma/issues/1731 "Issue by @Fudoshiki, closed 2019-03-20" +[#1803]:https://github.com/puma/puma/pull/1803 "PR by @Jesus, merged 2019-05-28" +[#1741]:https://github.com/puma/puma/pull/1741 "PR by @MSP-Greg, merged 2019-03-19" +[#1674]:https://github.com/puma/puma/issues/1674 "Issue by @atitan, closed 2019-06-12" +[#1720]:https://github.com/puma/puma/issues/1720 "Issue by @voxik, closed 2019-03-20" +[#1730]:https://github.com/puma/puma/issues/1730 "Issue by @nearapogee, closed 2019-07-16" +[#1755]:https://github.com/puma/puma/issues/1755 "Issue by @vbalazs, closed 2019-07-26" +[#1649]:https://github.com/puma/puma/pull/1649 "PR by @schneems, merged 2018-10-17" +[#1607]:https://github.com/puma/puma/pull/1607 "PR by @harmdewit, merged 2018-08-15" +[#1700]:https://github.com/puma/puma/pull/1700 "PR by @schneems, merged 2019-01-05" +[#1630]:https://github.com/puma/puma/pull/1630 "PR by @eregon, merged 2018-09-11" +[#1478]:https://github.com/puma/puma/pull/1478 "PR by @eallison91, merged 2018-05-09" +[#1604]:https://github.com/puma/puma/pull/1604 "PR by @schneems, merged 2018-07-02" +[#1579]:https://github.com/puma/puma/pull/1579 "PR by @schneems, merged 2018-06-14" +[#1506]:https://github.com/puma/puma/pull/1506 "PR by @dekellum, merged 2018-05-09" +[#1563]:https://github.com/puma/puma/pull/1563 "PR by @dannyfallon, merged 2018-05-01" +[#1557]:https://github.com/puma/puma/pull/1557 "PR by @swrobel, merged 2018-05-09" +[#1529]:https://github.com/puma/puma/pull/1529 "PR by @desnudopenguino, merged 2018-03-20" +[#1532]:https://github.com/puma/puma/pull/1532 "PR by @schneems, merged 2018-03-21" +[#1482]:https://github.com/puma/puma/pull/1482 "PR by @shayonj, merged 2018-03-19" +[#1511]:https://github.com/puma/puma/pull/1511 "PR by @jemiam, merged 2018-03-19" +[#1545]:https://github.com/puma/puma/pull/1545 "PR by @hoshinotsuyoshi, merged 2018-03-28" +[#1550]:https://github.com/puma/puma/pull/1550 "PR by @eileencodes, merged 2018-03-29" +[#1553]:https://github.com/puma/puma/pull/1553 "PR by @eugeneius, merged 2018-04-02" +[#1510]:https://github.com/puma/puma/issues/1510 "Issue by @vincentwoo, closed 2018-03-06" +[#1524]:https://github.com/puma/puma/pull/1524 "PR by @tuwukee, closed 2018-03-06" +[#1507]:https://github.com/puma/puma/issues/1507 "Issue by @vincentwoo, closed 2018-03-19" +[#1483]:https://github.com/puma/puma/issues/1483 "Issue by @igravious, closed 2018-03-06" +[#1502]:https://github.com/puma/puma/issues/1502 "Issue by @vincentwoo, closed 2020-03-09" +[#1403]:https://github.com/puma/puma/pull/1403 "PR by @eileencodes, merged 2017-10-04" +[#1435]:https://github.com/puma/puma/pull/1435 "PR by @juliancheal, merged 2017-10-11" +[#1340]:https://github.com/puma/puma/pull/1340 "PR by @ViliusLuneckas, merged 2017-10-16" +[#1434]:https://github.com/puma/puma/pull/1434 "PR by @jumbosushi, merged 2017-10-10" +[#1436]:https://github.com/puma/puma/pull/1436 "PR by @luislavena, merged 2017-10-11" +[#1418]:https://github.com/puma/puma/pull/1418 "PR by @eileencodes, merged 2017-09-22" +[#1416]:https://github.com/puma/puma/pull/1416 "PR by @hiimtaylorjones, merged 2017-09-22" +[#1409]:https://github.com/puma/puma/pull/1409 "PR by @olleolleolle, merged 2017-09-13" +[#1427]:https://github.com/puma/puma/issues/1427 "Issue by @garybernhardt, closed 2017-10-04" +[#1430]:https://github.com/puma/puma/pull/1430 "PR by @MSP-Greg, merged 2017-10-09" +[#1429]:https://github.com/puma/puma/pull/1429 "PR by @perlun, merged 2017-10-09" +[#1455]:https://github.com/puma/puma/pull/1455 "PR by @perlun, merged 2017-11-16" +[#1425]:https://github.com/puma/puma/pull/1425 "PR by @vizcay, merged 2017-10-01" +[#1452]:https://github.com/puma/puma/pull/1452 "PR by @eprothro, merged 2017-11-16" +[#1439]:https://github.com/puma/puma/pull/1439 "PR by @MSP-Greg, merged 2017-10-16" +[#1442]:https://github.com/puma/puma/pull/1442 "PR by @MSP-Greg, merged 2017-10-19" +[#1464]:https://github.com/puma/puma/pull/1464 "PR by @MSP-Greg, merged 2017-11-20" +[#1384]:https://github.com/puma/puma/pull/1384 "PR by @noahgibbs, merged 2017-08-03" +[#1111]:https://github.com/puma/puma/pull/1111 "PR by @alexlance, merged 2017-06-04" +[#1392]:https://github.com/puma/puma/pull/1392 "PR by @hoffm, merged 2017-08-11" +[#1347]:https://github.com/puma/puma/pull/1347 "PR by @NikolayRys, merged 2017-06-28" +[#1334]:https://github.com/puma/puma/pull/1334 "PR by @respire, merged 2017-06-13" +[#1383]:https://github.com/puma/puma/pull/1383 "PR by @schneems, merged 2017-08-02" +[#1368]:https://github.com/puma/puma/pull/1368 "PR by @bongole, merged 2017-08-03" +[#1318]:https://github.com/puma/puma/pull/1318 "PR by @nateberkopec, merged 2017-08-03" +[#1376]:https://github.com/puma/puma/pull/1376 "PR by @pat, merged 2017-08-03" +[#1388]:https://github.com/puma/puma/pull/1388 "PR by @nateberkopec, merged 2017-08-08" +[#1390]:https://github.com/puma/puma/pull/1390 "PR by @junaruga, merged 2017-08-16" +[#1391]:https://github.com/puma/puma/pull/1391 "PR by @junaruga, merged 2017-08-16" +[#1385]:https://github.com/puma/puma/pull/1385 "PR by @grosser, merged 2017-08-16" +[#1377]:https://github.com/puma/puma/pull/1377 "PR by @shayonj, merged 2017-08-16" +[#1337]:https://github.com/puma/puma/pull/1337 "PR by @shayonj, merged 2017-08-16" +[#1325]:https://github.com/puma/puma/pull/1325 "PR by @palkan, merged 2017-06-04" +[#1395]:https://github.com/puma/puma/pull/1395 "PR by @junaruga, merged 2017-08-16" +[#1367]:https://github.com/puma/puma/issues/1367 "Issue by @dekellum, closed 2017-08-17" +[#1314]:https://github.com/puma/puma/pull/1314 "PR by @grosser, merged 2017-06-02" +[#1311]:https://github.com/puma/puma/pull/1311 "PR by @grosser, merged 2017-06-02" +[#1313]:https://github.com/puma/puma/pull/1313 "PR by @grosser, merged 2017-06-03" +[#1260]:https://github.com/puma/puma/pull/1260 "PR by @grosser, merged 2017-04-11" +[#1278]:https://github.com/puma/puma/pull/1278 "PR by @evanphx, merged 2017-04-28" +[#1306]:https://github.com/puma/puma/pull/1306 "PR by @jules2689, merged 2017-05-31" +[#1274]:https://github.com/puma/puma/pull/1274 "PR by @evanphx, merged 2017-05-01" +[#1261]:https://github.com/puma/puma/pull/1261 "PR by @jacksonrayhamilton, merged 2017-04-07" +[#1259]:https://github.com/puma/puma/pull/1259 "PR by @jacksonrayhamilton, merged 2017-04-07" +[#1248]:https://github.com/puma/puma/pull/1248 "PR by @davidarnold, merged 2017-04-18" +[#1277]:https://github.com/puma/puma/pull/1277 "PR by @schneems, merged 2017-05-01" +[#1290]:https://github.com/puma/puma/pull/1290 "PR by @schneems, merged 2017-05-12" +[#1285]:https://github.com/puma/puma/pull/1285 "PR by @fmauNeko, merged 2017-05-12" +[#1282]:https://github.com/puma/puma/pull/1282 "PR by @grosser, merged 2017-05-09" +[#1294]:https://github.com/puma/puma/pull/1294 "PR by @masry707, merged 2017-05-15" +[#1206]:https://github.com/puma/puma/pull/1206 "PR by @NikolayRys, closed 2017-06-27" +[#1241]:https://github.com/puma/puma/issues/1241 "Issue by @renchap, closed 2017-03-14" +[#1239]:https://github.com/puma/puma/pull/1239 "PR by @schneems, merged 2017-03-10" +[#1234]:https://github.com/puma/puma/pull/1234 "PR by @schneems, merged 2017-03-09" +[#1226]:https://github.com/puma/puma/pull/1226 "PR by @eileencodes, merged 2017-03-09" +[#1227]:https://github.com/puma/puma/pull/1227 "PR by @sirupsen, merged 2017-02-27" +[#1213]:https://github.com/puma/puma/pull/1213 "PR by @junaruga, merged 2017-02-28" +[#1182]:https://github.com/puma/puma/issues/1182 "Issue by @brunowego, closed 2017-02-09" +[#1203]:https://github.com/puma/puma/pull/1203 "PR by @twalpole, merged 2017-02-09" +[#1129]:https://github.com/puma/puma/pull/1129 "PR by @chtitux, merged 2016-12-12" +[#1165]:https://github.com/puma/puma/pull/1165 "PR by @sriedel, merged 2016-12-21" +[#1175]:https://github.com/puma/puma/pull/1175 "PR by @jemiam, merged 2016-12-21" +[#1068]:https://github.com/puma/puma/pull/1068 "PR by @junaruga, merged 2016-09-05" +[#1091]:https://github.com/puma/puma/pull/1091 "PR by @frodsan, merged 2016-09-17" +[#1088]:https://github.com/puma/puma/pull/1088 "PR by @frodsan, merged 2016-11-20" +[#1160]:https://github.com/puma/puma/pull/1160 "PR by @frodsan, merged 2016-11-24" +[#1169]:https://github.com/puma/puma/pull/1169 "PR by @scbrubaker02, merged 2016-12-12" +[#1061]:https://github.com/puma/puma/pull/1061 "PR by @michaelsauter, merged 2016-09-05" +[#1036]:https://github.com/puma/puma/issues/1036 "Issue by @matobinder, closed 2016-08-03" +[#1120]:https://github.com/puma/puma/pull/1120 "PR by @prathamesh-sonpatki, merged 2016-11-21" +[#1178]:https://github.com/puma/puma/pull/1178 "PR by @Koronen, merged 2016-12-21" +[#1002]:https://github.com/puma/puma/issues/1002 "Issue by @mattyb, closed 2016-07-26" +[#1063]:https://github.com/puma/puma/issues/1063 "Issue by @mperham, closed 2016-09-05" +[#1089]:https://github.com/puma/puma/issues/1089 "Issue by @AdamBialas, closed 2016-09-17" +[#1114]:https://github.com/puma/puma/pull/1114 "PR by @sj26, merged 2016-12-13" +[#1110]:https://github.com/puma/puma/pull/1110 "PR by @montdidier, merged 2016-12-12" +[#1135]:https://github.com/puma/puma/pull/1135 "PR by @jkraemer, merged 2016-11-19" +[#1081]:https://github.com/puma/puma/pull/1081 "PR by @frodsan, merged 2016-09-08" +[#1138]:https://github.com/puma/puma/pull/1138 "PR by @skull-squadron, merged 2016-12-13" +[#1118]:https://github.com/puma/puma/pull/1118 "PR by @hiroara, merged 2016-11-20" +[#1075]:https://github.com/puma/puma/issues/1075 "Issue by @pvalena, closed 2016-09-06" +[#932]:https://github.com/puma/puma/issues/932 "Issue by @everplays, closed 2016-07-24" +[#519]:https://github.com/puma/puma/issues/519 "Issue by @tmornini, closed 2016-07-25" +[#828]:https://github.com/puma/puma/issues/828 "Issue by @Zapotek, closed 2016-07-24" +[#984]:https://github.com/puma/puma/issues/984 "Issue by @erichmenge, closed 2016-07-24" +[#1028]:https://github.com/puma/puma/issues/1028 "Issue by @matobinder, closed 2016-07-24" +[#1023]:https://github.com/puma/puma/issues/1023 "Issue by @fera2k, closed 2016-07-24" +[#1027]:https://github.com/puma/puma/issues/1027 "Issue by @rosenfeld, closed 2016-07-24" +[#925]:https://github.com/puma/puma/issues/925 "Issue by @lokenmakwana, closed 2016-07-24" +[#911]:https://github.com/puma/puma/issues/911 "Issue by @veganstraightedge, closed 2016-07-24" +[#620]:https://github.com/puma/puma/issues/620 "Issue by @javanthropus, closed 2016-07-25" +[#778]:https://github.com/puma/puma/issues/778 "Issue by @niedhui, closed 2016-07-24" +[#1021]:https://github.com/puma/puma/pull/1021 "PR by @sarahzrf, merged 2016-07-20" +[#1022]:https://github.com/puma/puma/issues/1022 "Issue by @AKovtunov, closed 2017-08-16" +[#958]:https://github.com/puma/puma/issues/958 "Issue by @lalitlogical, closed 2016-04-23" +[#782]:https://github.com/puma/puma/issues/782 "Issue by @Tonkpils, closed 2016-07-19" +[#1010]:https://github.com/puma/puma/issues/1010 "Issue by @mneumark, closed 2016-07-19" +[#959]:https://github.com/puma/puma/issues/959 "Issue by @mwpastore, closed 2016-04-22" +[#840]:https://github.com/puma/puma/issues/840 "Issue by @marisawallace, closed 2016-04-07" +[#1007]:https://github.com/puma/puma/pull/1007 "PR by @willnet, merged 2016-06-24" +[#1014]:https://github.com/puma/puma/pull/1014 "PR by @szymon-jez, merged 2016-07-11" +[#1015]:https://github.com/puma/puma/pull/1015 "PR by @bf4, merged 2016-07-19" +[#1017]:https://github.com/puma/puma/pull/1017 "PR by @jorihardman, merged 2016-07-19" +[#954]:https://github.com/puma/puma/pull/954 "PR by @jf, merged 2016-04-12" +[#955]:https://github.com/puma/puma/pull/955 "PR by @jf, merged 2016-04-22" +[#956]:https://github.com/puma/puma/pull/956 "PR by @marisawallace, merged 2016-04-12" +[#960]:https://github.com/puma/puma/pull/960 "PR by @kmayer, merged 2016-04-15" +[#969]:https://github.com/puma/puma/pull/969 "PR by @frankwong15, merged 2016-05-10" +[#970]:https://github.com/puma/puma/pull/970 "PR by @willnet, merged 2016-04-26" +[#974]:https://github.com/puma/puma/pull/974 "PR by @reidmorrison, merged 2016-05-10" +[#977]:https://github.com/puma/puma/pull/977 "PR by @snow, merged 2016-05-10" +[#981]:https://github.com/puma/puma/pull/981 "PR by @zach-chai, merged 2016-07-19" +[#993]:https://github.com/puma/puma/pull/993 "PR by @scorix, merged 2016-07-19" +[#938]:https://github.com/puma/puma/issues/938 "Issue by @vandrijevik, closed 2016-04-07" +[#529]:https://github.com/puma/puma/issues/529 "Issue by @mperham, closed 2016-04-07" +[#788]:https://github.com/puma/puma/issues/788 "Issue by @herregroen, closed 2016-04-07" +[#894]:https://github.com/puma/puma/issues/894 "Issue by @rafbm, closed 2016-04-07" +[#937]:https://github.com/puma/puma/issues/937 "Issue by @huangxiangdan, closed 2016-04-07" +[#945]:https://github.com/puma/puma/pull/945 "PR by @dekellum, merged 2016-04-07" +[#946]:https://github.com/puma/puma/pull/946 "PR by @vipulnsward, merged 2016-04-07" +[#947]:https://github.com/puma/puma/pull/947 "PR by @vipulnsward, merged 2016-04-07" +[#936]:https://github.com/puma/puma/pull/936 "PR by @prathamesh-sonpatki, merged 2016-04-01" +[#940]:https://github.com/puma/puma/pull/940 "PR by @kyledrake, merged 2016-04-01" +[#942]:https://github.com/puma/puma/pull/942 "PR by @dekellum, merged 2016-04-01" +[#927]:https://github.com/puma/puma/pull/927 "PR by @jlecour, merged 2016-03-18" +[#931]:https://github.com/puma/puma/pull/931 "PR by @runlevel5, merged 2016-03-18" +[#922]:https://github.com/puma/puma/issues/922 "Issue by @LavirtheWhiolet, closed 2016-03-07" +[#923]:https://github.com/puma/puma/issues/923 "Issue by @donv, closed 2016-03-06" +[#912]:https://github.com/puma/puma/pull/912 "PR by @tricknotes, merged 2016-03-06" +[#921]:https://github.com/puma/puma/pull/921 "PR by @swrobel, merged 2016-03-06" +[#924]:https://github.com/puma/puma/pull/924 "PR by @tbrisker, merged 2016-03-07" +[#916]:https://github.com/puma/puma/issues/916 "Issue by @ma11hew28, closed 2016-03-06" +[#913]:https://github.com/puma/puma/issues/913 "Issue by @Casara, closed 2016-03-06" +[#918]:https://github.com/puma/puma/issues/918 "Issue by @rodrigdav, closed 2016-03-06" +[#910]:https://github.com/puma/puma/issues/910 "Issue by @ball-hayden, closed 2016-03-05" +[#914]:https://github.com/puma/puma/issues/914 "Issue by @osheroff, closed 2016-03-06" +[#901]:https://github.com/puma/puma/pull/901 "PR by @mitto, merged 2016-02-26" +[#902]:https://github.com/puma/puma/pull/902 "PR by @corrupt952, merged 2016-02-26" +[#905]:https://github.com/puma/puma/pull/905 "PR by @Eric-Guo, merged 2016-02-26" +[#852]:https://github.com/puma/puma/issues/852 "Issue by @asia653, closed 2016-02-25" +[#854]:https://github.com/puma/puma/issues/854 "Issue by @ollym, closed 2016-02-25" +[#824]:https://github.com/puma/puma/issues/824 "Issue by @MattWalston, closed 2016-02-25" +[#823]:https://github.com/puma/puma/issues/823 "Issue by @pneuman, closed 2016-02-25" +[#815]:https://github.com/puma/puma/issues/815 "Issue by @nate-dipiazza, closed 2016-02-25" +[#835]:https://github.com/puma/puma/issues/835 "Issue by @mwpastore, closed 2016-02-25" +[#798]:https://github.com/puma/puma/issues/798 "Issue by @schneems, closed 2016-02-25" +[#876]:https://github.com/puma/puma/issues/876 "Issue by @osheroff, closed 2016-02-25" +[#849]:https://github.com/puma/puma/issues/849 "Issue by @apotheon, closed 2016-02-25" +[#871]:https://github.com/puma/puma/pull/871 "PR by @deepj, merged 2016-02-25" +[#874]:https://github.com/puma/puma/pull/874 "PR by @wallclockbuilder, merged 2016-02-25" +[#883]:https://github.com/puma/puma/pull/883 "PR by @dadah89, merged 2016-02-25" +[#884]:https://github.com/puma/puma/pull/884 "PR by @furkanmustafa, merged 2016-02-25" +[#888]:https://github.com/puma/puma/pull/888 "PR by @mlarraz, merged 2016-02-25" +[#890]:https://github.com/puma/puma/pull/890 "PR by @todd, merged 2016-02-25" +[#891]:https://github.com/puma/puma/pull/891 "PR by @ctaintor, merged 2016-02-25" +[#893]:https://github.com/puma/puma/pull/893 "PR by @spastorino, merged 2016-02-25" +[#897]:https://github.com/puma/puma/pull/897 "PR by @vanchi-zendesk, merged 2016-02-25" +[#899]:https://github.com/puma/puma/pull/899 "PR by @kch, merged 2016-02-25" +[#859]:https://github.com/puma/puma/issues/859 "Issue by @boxofrad, closed 2016-01-28" +[#822]:https://github.com/puma/puma/pull/822 "PR by @kwugirl, merged 2016-01-28" +[#833]:https://github.com/puma/puma/pull/833 "PR by @joemiller, merged 2016-01-28" +[#837]:https://github.com/puma/puma/pull/837 "PR by @YurySolovyov, merged 2016-01-28" +[#839]:https://github.com/puma/puma/pull/839 "PR by @ka8725, merged 2016-01-15" +[#845]:https://github.com/puma/puma/pull/845 "PR by @deepj, merged 2016-01-28" +[#846]:https://github.com/puma/puma/pull/846 "PR by @sriedel, merged 2016-01-15" +[#850]:https://github.com/puma/puma/pull/850 "PR by @deepj, merged 2016-01-15" +[#853]:https://github.com/puma/puma/pull/853 "PR by @xuqiyong666, merged 2016-01-28" +[#857]:https://github.com/puma/puma/pull/857 "PR by @osheroff, merged 2016-01-15" +[#858]:https://github.com/puma/puma/pull/858 "PR by @mlarraz, merged 2016-01-28" +[#860]:https://github.com/puma/puma/pull/860 "PR by @osheroff, merged 2016-01-15" +[#861]:https://github.com/puma/puma/pull/861 "PR by @osheroff, merged 2016-01-15" +[#818]:https://github.com/puma/puma/pull/818 "PR by @unleashed, merged 2015-11-06" +[#819]:https://github.com/puma/puma/pull/819 "PR by @VictorLowther, merged 2015-11-06" +[#563]:https://github.com/puma/puma/issues/563 "Issue by @deathbob, closed 2015-11-06" +[#803]:https://github.com/puma/puma/issues/803 "Issue by @burningTyger, closed 2016-04-07" +[#768]:https://github.com/puma/puma/pull/768 "PR by @nathansamson, merged 2015-11-06" +[#773]:https://github.com/puma/puma/pull/773 "PR by @rossta, merged 2015-11-06" +[#774]:https://github.com/puma/puma/pull/774 "PR by @snow, merged 2015-11-06" +[#781]:https://github.com/puma/puma/pull/781 "PR by @sunsations, merged 2015-11-06" +[#791]:https://github.com/puma/puma/pull/791 "PR by @unleashed, merged 2015-10-01" +[#793]:https://github.com/puma/puma/pull/793 "PR by @robdimarco, merged 2015-11-06" +[#794]:https://github.com/puma/puma/pull/794 "PR by @peterkeen, merged 2015-11-06" +[#795]:https://github.com/puma/puma/pull/795 "PR by @unleashed, merged 2015-11-06" +[#796]:https://github.com/puma/puma/pull/796 "PR by @cschneid, merged 2015-10-13" +[#799]:https://github.com/puma/puma/pull/799 "PR by @annawinkler, merged 2015-11-06" +[#800]:https://github.com/puma/puma/pull/800 "PR by @liamseanbrady, merged 2015-11-06" +[#801]:https://github.com/puma/puma/pull/801 "PR by @scottjg, merged 2015-11-06" +[#802]:https://github.com/puma/puma/pull/802 "PR by @scottjg, merged 2015-11-06" +[#804]:https://github.com/puma/puma/pull/804 "PR by @burningTyger, merged 2015-11-06" +[#809]:https://github.com/puma/puma/pull/809 "PR by @unleashed, merged 2015-11-06" +[#810]:https://github.com/puma/puma/pull/810 "PR by @vlmonk, merged 2015-11-06" +[#814]:https://github.com/puma/puma/pull/814 "PR by @schneems, merged 2015-11-04" +[#817]:https://github.com/puma/puma/pull/817 "PR by @unleashed, merged 2015-11-06" +[#735]:https://github.com/puma/puma/issues/735 "Issue by @trekr5, closed 2015-08-04" +[#769]:https://github.com/puma/puma/issues/769 "Issue by @dovestyle, closed 2015-08-16" +[#767]:https://github.com/puma/puma/issues/767 "Issue by @kapso, closed 2015-08-15" +[#765]:https://github.com/puma/puma/issues/765 "Issue by @monfresh, closed 2015-08-15" +[#764]:https://github.com/puma/puma/issues/764 "Issue by @keithpitt, closed 2015-08-15" +[#669]:https://github.com/puma/puma/pull/669 "PR by @chulkilee, closed 2015-08-14" +[#673]:https://github.com/puma/puma/pull/673 "PR by @chulkilee, closed 2015-08-14" +[#668]:https://github.com/puma/puma/pull/668 "PR by @kcollignon, merged 2015-08-14" +[#754]:https://github.com/puma/puma/pull/754 "PR by @nathansamson, merged 2015-08-14" +[#759]:https://github.com/puma/puma/pull/759 "PR by @BenV, merged 2015-08-14" +[#761]:https://github.com/puma/puma/pull/761 "PR by @dmarcotte, merged 2015-08-14" +[#742]:https://github.com/puma/puma/pull/742 "PR by @deivid-rodriguez, merged 2015-07-17" +[#743]:https://github.com/puma/puma/pull/743 "PR by @matthewd, merged 2015-07-18" +[#749]:https://github.com/puma/puma/pull/749 "PR by @huacnlee, merged 2015-08-04" +[#751]:https://github.com/puma/puma/pull/751 "PR by @costi, merged 2015-07-31" +[#741]:https://github.com/puma/puma/issues/741 "Issue by @GUI, closed 2015-07-17" +[#739]:https://github.com/puma/puma/issues/739 "Issue by @hab278, closed 2015-07-17" +[#737]:https://github.com/puma/puma/issues/737 "Issue by @dmill, closed 2015-07-16" +[#733]:https://github.com/puma/puma/issues/733 "Issue by @Eric-Guo, closed 2015-07-15" +[#736]:https://github.com/puma/puma/pull/736 "PR by @paulanunda, merged 2015-07-15" +[#722]:https://github.com/puma/puma/issues/722 "Issue by @mikeki, closed 2015-07-14" +[#694]:https://github.com/puma/puma/issues/694 "Issue by @yld, closed 2015-06-10" +[#705]:https://github.com/puma/puma/issues/705 "Issue by @TheTeaNerd, closed 2015-07-14" +[#686]:https://github.com/puma/puma/pull/686 "PR by @jjb, merged 2015-06-10" +[#693]:https://github.com/puma/puma/pull/693 "PR by @rob-murray, merged 2015-06-10" +[#697]:https://github.com/puma/puma/pull/697 "PR by @spk, merged 2015-06-10" +[#699]:https://github.com/puma/puma/pull/699 "PR by @deees, merged 2015-05-19" +[#701]:https://github.com/puma/puma/pull/701 "PR by @deepj, merged 2015-05-19" +[#702]:https://github.com/puma/puma/pull/702 "PR by @OleMchls, merged 2015-06-10" +[#703]:https://github.com/puma/puma/pull/703 "PR by @deepj, merged 2015-06-10" +[#704]:https://github.com/puma/puma/pull/704 "PR by @grega, merged 2015-06-10" +[#709]:https://github.com/puma/puma/pull/709 "PR by @lian, merged 2015-06-10" +[#711]:https://github.com/puma/puma/pull/711 "PR by @julik, merged 2015-06-10" +[#712]:https://github.com/puma/puma/pull/712 "PR by @chewi, merged 2015-07-14" +[#715]:https://github.com/puma/puma/pull/715 "PR by @raymondmars, merged 2015-07-14" +[#725]:https://github.com/puma/puma/pull/725 "PR by @rwz, merged 2015-07-14" +[#726]:https://github.com/puma/puma/pull/726 "PR by @jshafton, merged 2015-07-14" +[#729]:https://github.com/puma/puma/pull/729 "PR by @allaire, merged 2015-07-14" +[#730]:https://github.com/puma/puma/pull/730 "PR by @iamjarvo, merged 2015-07-14" +[#690]:https://github.com/puma/puma/issues/690 "Issue by @bachue, closed 2015-04-21" +[#684]:https://github.com/puma/puma/issues/684 "Issue by @tomquas, closed 2015-04-13" +[#698]:https://github.com/puma/puma/pull/698 "PR by @dmarcotte, merged 2015-05-04" +[#683]:https://github.com/puma/puma/issues/683 "Issue by @indirect, closed 2015-04-11" +[#657]:https://github.com/puma/puma/pull/657 "PR by @schneems, merged 2015-02-19" +[#658]:https://github.com/puma/puma/pull/658 "PR by @tomohiro, merged 2015-02-23" +[#662]:https://github.com/puma/puma/pull/662 "PR by @iaintshine, merged 2015-03-06" +[#664]:https://github.com/puma/puma/pull/664 "PR by @fxposter, merged 2015-03-09" +[#667]:https://github.com/puma/puma/pull/667 "PR by @JuanitoFatas, merged 2015-03-12" +[#672]:https://github.com/puma/puma/pull/672 "PR by @chulkilee, merged 2015-03-15" +[#653]:https://github.com/puma/puma/issues/653 "Issue by @dvrensk, closed 2015-02-11" +[#644]:https://github.com/puma/puma/pull/644 "PR by @bpaquet, merged 2015-01-29" +[#646]:https://github.com/puma/puma/pull/646 "PR by @mkonecny, merged 2015-02-05" +[#630]:https://github.com/puma/puma/issues/630 "Issue by @jelmd, closed 2015-01-20" +[#622]:https://github.com/puma/puma/issues/622 "Issue by @sabamotto, closed 2015-01-20" +[#583]:https://github.com/puma/puma/issues/583 "Issue by @rwojsznis, closed 2015-01-20" +[#586]:https://github.com/puma/puma/issues/586 "Issue by @ponchik, closed 2015-01-20" +[#359]:https://github.com/puma/puma/issues/359 "Issue by @natew, closed 2014-12-13" +[#633]:https://github.com/puma/puma/issues/633 "Issue by @joevandyk, closed 2015-01-20" +[#478]:https://github.com/puma/puma/pull/478 "PR by @rubencaro, merged 2015-01-20" +[#610]:https://github.com/puma/puma/pull/610 "PR by @kwilczynski, merged 2014-11-27" +[#611]:https://github.com/puma/puma/pull/611 "PR by @jasonl, merged 2015-01-20" +[#616]:https://github.com/puma/puma/pull/616 "PR by @jc00ke, merged 2014-12-10" +[#623]:https://github.com/puma/puma/pull/623 "PR by @raldred, merged 2015-01-20" +[#628]:https://github.com/puma/puma/pull/628 "PR by @rdpoor, merged 2015-01-20" +[#634]:https://github.com/puma/puma/pull/634 "PR by @deepj, merged 2015-01-20" +[#637]:https://github.com/puma/puma/pull/637 "PR by @raskhadafi, merged 2015-01-20" +[#639]:https://github.com/puma/puma/pull/639 "PR by @ebeigarts, merged 2015-01-20" +[#640]:https://github.com/puma/puma/pull/640 "PR by @bailsman, merged 2015-01-20" +[#591]:https://github.com/puma/puma/issues/591 "Issue by @renier, closed 2014-11-24" +[#606]:https://github.com/puma/puma/issues/606 "Issue by @, closed 2014-11-24" +[#560]:https://github.com/puma/puma/pull/560 "PR by @raskhadafi, merged 2014-11-24" +[#566]:https://github.com/puma/puma/pull/566 "PR by @sheltond, merged 2014-11-24" +[#593]:https://github.com/puma/puma/pull/593 "PR by @andruby, merged 2014-10-30" +[#594]:https://github.com/puma/puma/pull/594 "PR by @hassox, merged 2014-10-31" +[#596]:https://github.com/puma/puma/pull/596 "PR by @burningTyger, merged 2014-11-01" +[#601]:https://github.com/puma/puma/pull/601 "PR by @sorentwo, merged 2014-11-24" +[#602]:https://github.com/puma/puma/pull/602 "PR by @1334, merged 2014-11-24" +[#608]:https://github.com/puma/puma/pull/608 "PR by @Gu1, merged 2014-11-24" +[#538]:https://github.com/puma/puma/pull/538 "PR by @memiux, merged 2014-11-24" +[#550]:https://github.com/puma/puma/issues/550 "Issue by @, closed 2014-10-30" +[#549]:https://github.com/puma/puma/pull/549 "PR by @bsnape, merged 2014-10-16" +[#553]:https://github.com/puma/puma/pull/553 "PR by @lowjoel, merged 2014-10-16" +[#568]:https://github.com/puma/puma/pull/568 "PR by @mariuz, merged 2014-10-16" +[#578]:https://github.com/puma/puma/pull/578 "PR by @danielbuechele, merged 2014-10-16" +[#581]:https://github.com/puma/puma/pull/581 "PR by @alexch, merged 2014-10-16" +[#590]:https://github.com/puma/puma/pull/590 "PR by @dmarcotte, merged 2014-10-16" +[#574]:https://github.com/puma/puma/issues/574 "Issue by @minasmart, closed 2014-09-05" +[#561]:https://github.com/puma/puma/pull/561 "PR by @krasnoukhov, merged 2014-08-04" +[#570]:https://github.com/puma/puma/pull/570 "PR by @havenwood, merged 2014-08-20" +[#520]:https://github.com/puma/puma/pull/520 "PR by @misfo, merged 2014-06-16" +[#530]:https://github.com/puma/puma/pull/530 "PR by @dmarcotte, merged 2014-06-16" +[#537]:https://github.com/puma/puma/pull/537 "PR by @vlmonk, merged 2014-06-16" +[#540]:https://github.com/puma/puma/pull/540 "PR by @allaire, merged 2014-05-27" +[#544]:https://github.com/puma/puma/pull/544 "PR by @chulkilee, merged 2014-06-03" +[#551]:https://github.com/puma/puma/pull/551 "PR by @jcxplorer, merged 2014-07-02" +[#487]:https://github.com/puma/puma/pull/487 "PR by @, merged 2014-03-06" +[#492]:https://github.com/puma/puma/pull/492 "PR by @, merged 2014-03-06" +[#493]:https://github.com/puma/puma/pull/493 "PR by @alepore, merged 2014-03-07" +[#503]:https://github.com/puma/puma/pull/503 "PR by @mariuz, merged 2014-04-12" +[#505]:https://github.com/puma/puma/pull/505 "PR by @sammcj, merged 2014-04-12" +[#506]:https://github.com/puma/puma/pull/506 "PR by @dsander, merged 2014-04-12" +[#510]:https://github.com/puma/puma/pull/510 "PR by @momer, merged 2014-04-12" +[#511]:https://github.com/puma/puma/pull/511 "PR by @macool, merged 2014-04-12" +[#514]:https://github.com/puma/puma/pull/514 "PR by @nanaya, merged 2014-04-12" +[#517]:https://github.com/puma/puma/pull/517 "PR by @misfo, merged 2014-04-12" +[#518]:https://github.com/puma/puma/pull/518 "PR by @alxgsv, merged 2014-04-12" +[#471]:https://github.com/puma/puma/pull/471 "PR by @arthurnn, merged 2014-02-28" +[#485]:https://github.com/puma/puma/pull/485 "PR by @runlevel5, merged 2014-03-01" +[#486]:https://github.com/puma/puma/pull/486 "PR by @joshwlewis, merged 2014-03-02" +[#490]:https://github.com/puma/puma/pull/490 "PR by @tobinibot, merged 2014-03-06" +[#491]:https://github.com/puma/puma/pull/491 "PR by @brianknight10, merged 2014-03-06" +[#438]:https://github.com/puma/puma/issues/438 "Issue by @mperham, closed 2014-01-25" +[#333]:https://github.com/puma/puma/issues/333 "Issue by @SamSaffron, closed 2014-01-26" +[#440]:https://github.com/puma/puma/issues/440 "Issue by @sudara, closed 2014-01-25" +[#449]:https://github.com/puma/puma/issues/449 "Issue by @cezarsa, closed 2014-02-04" +[#444]:https://github.com/puma/puma/issues/444 "Issue by @le0pard, closed 2014-01-25" +[#370]:https://github.com/puma/puma/issues/370 "Issue by @pelcasandra, closed 2014-01-26" +[#377]:https://github.com/puma/puma/issues/377 "Issue by @mrbrdo, closed 2014-01-26" +[#406]:https://github.com/puma/puma/issues/406 "Issue by @simonrussell, closed 2014-01-25" +[#425]:https://github.com/puma/puma/issues/425 "Issue by @jhass, closed 2014-01-26" +[#432]:https://github.com/puma/puma/pull/432 "PR by @anatol, closed 2014-01-25" +[#428]:https://github.com/puma/puma/pull/428 "PR by @alexeyfrank, merged 2014-01-25" +[#429]:https://github.com/puma/puma/pull/429 "PR by @namusyaka, merged 2013-12-16" +[#431]:https://github.com/puma/puma/pull/431 "PR by @mrb, merged 2014-01-25" +[#433]:https://github.com/puma/puma/pull/433 "PR by @alepore, merged 2014-02-28" +[#437]:https://github.com/puma/puma/pull/437 "PR by @ibrahima, merged 2014-01-25" +[#446]:https://github.com/puma/puma/pull/446 "PR by @sudara, merged 2014-01-27" +[#451]:https://github.com/puma/puma/pull/451 "PR by @pwiebe, merged 2014-02-04" +[#453]:https://github.com/puma/puma/pull/453 "PR by @joevandyk, merged 2014-02-28" +[#470]:https://github.com/puma/puma/pull/470 "PR by @arthurnn, merged 2014-02-28" +[#472]:https://github.com/puma/puma/pull/472 "PR by @rubencaro, merged 2014-02-21" +[#480]:https://github.com/puma/puma/pull/480 "PR by @jjb, merged 2014-02-26" +[#481]:https://github.com/puma/puma/pull/481 "PR by @schneems, merged 2014-02-25" +[#482]:https://github.com/puma/puma/pull/482 "PR by @prathamesh-sonpatki, merged 2014-02-26" +[#483]:https://github.com/puma/puma/pull/483 "PR by @maxilev, merged 2014-02-26" +[#422]:https://github.com/puma/puma/issues/422 "Issue by @alexandru-calinoiu, closed 2013-12-05" +[#334]:https://github.com/puma/puma/issues/334 "Issue by @srgpqt, closed 2013-07-18" +[#179]:https://github.com/puma/puma/issues/179 "Issue by @betelgeuse, closed 2013-07-18" +[#332]:https://github.com/puma/puma/issues/332 "Issue by @SamSaffron, closed 2013-07-18" +[#317]:https://github.com/puma/puma/issues/317 "Issue by @masterkain, closed 2013-07-11" +[#309]:https://github.com/puma/puma/issues/309 "Issue by @masterkain, closed 2013-07-09" +[#166]:https://github.com/puma/puma/issues/166 "Issue by @emassip, closed 2013-07-06" +[#292]:https://github.com/puma/puma/issues/292 "Issue by @pulse00, closed 2013-07-06" +[#274]:https://github.com/puma/puma/issues/274 "Issue by @mrbrdo, closed 2013-07-06" +[#304]:https://github.com/puma/puma/issues/304 "Issue by @nandosola, closed 2013-07-06" +[#287]:https://github.com/puma/puma/issues/287 "Issue by @runlevel5, closed 2013-07-06" +[#256]:https://github.com/puma/puma/issues/256 "Issue by @rkh, closed 2013-07-01" +[#285]:https://github.com/puma/puma/issues/285 "Issue by @mkwiatkowski, closed 2013-06-20" +[#270]:https://github.com/puma/puma/issues/270 "Issue by @iamroody, closed 2013-06-01" +[#246]:https://github.com/puma/puma/issues/246 "Issue by @amencarini, closed 2013-06-01" +[#278]:https://github.com/puma/puma/issues/278 "Issue by @titanous, closed 2013-06-18" +[#251]:https://github.com/puma/puma/issues/251 "Issue by @cure, closed 2013-06-18" +[#252]:https://github.com/puma/puma/issues/252 "Issue by @vixns, closed 2013-06-01" +[#234]:https://github.com/puma/puma/issues/234 "Issue by @jgarber, closed 2013-04-08" +[#228]:https://github.com/puma/puma/issues/228 "Issue by @joelmats, closed 2013-04-29" +[#192]:https://github.com/puma/puma/issues/192 "Issue by @steverandy, closed 2013-02-09" +[#206]:https://github.com/puma/puma/issues/206 "Issue by @moll, closed 2013-03-19" +[#154]:https://github.com/puma/puma/issues/154 "Issue by @trevor, closed 2013-03-19" +[#208]:https://github.com/puma/puma/issues/208 "Issue by @ochronus, closed 2013-03-18" +[#189]:https://github.com/puma/puma/issues/189 "Issue by @tolot27, closed 2013-02-09" +[#185]:https://github.com/puma/puma/issues/185 "Issue by @nicolai86, closed 2013-02-06" +[#182]:https://github.com/puma/puma/issues/182 "Issue by @sriedel, closed 2013-02-05" +[#183]:https://github.com/puma/puma/issues/183 "Issue by @concept47, closed 2013-02-05" +[#176]:https://github.com/puma/puma/issues/176 "Issue by @cryo28, closed 2013-02-05" +[#180]:https://github.com/puma/puma/issues/180 "Issue by @tscolari, closed 2013-02-05" +[#170]:https://github.com/puma/puma/issues/170 "Issue by @nixme, closed 2012-11-29" +[#148]:https://github.com/puma/puma/issues/148 "Issue by @rafaelss, closed 2012-11-18" +[#128]:https://github.com/puma/puma/issues/128 "Issue by @fbjork, closed 2012-10-20" +[#155]:https://github.com/puma/puma/issues/155 "Issue by @ehlertij, closed 2012-10-13" +[#123]:https://github.com/puma/puma/pull/123 "PR by @jcoene, closed 2012-07-19" +[#111]:https://github.com/puma/puma/pull/111 "PR by @kenkeiter, closed 2012-07-19" +[#98]:https://github.com/puma/puma/pull/98 "PR by @Flink, closed 2012-05-15" +[#94]:https://github.com/puma/puma/issues/94 "Issue by @ender672, closed 2012-05-08" +[#84]:https://github.com/puma/puma/issues/84 "Issue by @sigursoft, closed 2012-04-29" +[#78]:https://github.com/puma/puma/issues/78 "Issue by @dstrelau, closed 2012-04-28" +[#79]:https://github.com/puma/puma/issues/79 "Issue by @jammi, closed 2012-04-28" +[#65]:https://github.com/puma/puma/issues/65 "Issue by @bporterfield, closed 2012-04-11" +[#54]:https://github.com/puma/puma/issues/54 "Issue by @masterkain, closed 2012-04-10" +[#58]:https://github.com/puma/puma/pull/58 "PR by @paneq, closed 2012-04-10" +[#61]:https://github.com/puma/puma/issues/61 "Issue by @dustalov, closed 2012-04-10" +[#63]:https://github.com/puma/puma/issues/63 "Issue by @seamusabshere, closed 2012-04-11" +[#60]:https://github.com/puma/puma/issues/60 "Issue by @paneq, closed 2012-04-11" +[#53]:https://github.com/puma/puma/pull/53 "PR by @sxua, closed 2012-04-11" diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/LICENSE b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/LICENSE new file mode 100644 index 00000000..14bfc858 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2019, Evan Phoenix. Some code by Zed Shaw, (c) 2005. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/README.md b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/README.md new file mode 100644 index 00000000..a373f25f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/README.md @@ -0,0 +1,485 @@ +

+ +

+ +# Puma: A Ruby Web Server Built For Parallelism + +[![Actions](https://github.com/puma/puma/workflows/Tests/badge.svg?branch=master)](https://github.com/puma/puma/actions?query=workflow%3ATests) +[![Code Climate](https://codeclimate.com/github/puma/puma.svg)](https://codeclimate.com/github/puma/puma) +[![StackOverflow](https://img.shields.io/badge/stackoverflow-Puma-blue.svg)]( https://stackoverflow.com/questions/tagged/puma ) + +Puma is a **simple, fast, multi-threaded, and highly parallel HTTP 1.1 server for Ruby/Rack applications**. + +## Built For Speed & Parallelism + +Puma is a server for [Rack](https://github.com/rack/rack)-powered HTTP applications written in Ruby. It is: +* **Multi-threaded**. Each request is served in a separate thread. This helps you serve more requests per second with less memory use. +* **Multi-process**. "Pre-forks" in cluster mode, using less memory per-process thanks to copy-on-write memory. +* **Standalone**. With SSL support, zero-downtime rolling restarts and a built-in request bufferer, you can deploy Puma without any reverse proxy. +* **Battle-tested**. Our HTTP parser is inherited from Mongrel and has over 15 years of production use. Puma is currently the most popular Ruby webserver, and is the default server for Ruby on Rails. + +Originally designed as a server for [Rubinius](https://github.com/rubinius/rubinius), Puma also works well with Ruby (MRI) and JRuby. + +On MRI, there is a Global VM Lock (GVL) that ensures only one thread can run Ruby code at a time. But if you're doing a lot of blocking IO (such as HTTP calls to external APIs like Twitter), Puma still improves MRI's throughput by allowing IO waiting to be done in parallel. Truly parallel Ruby implementations (TruffleRuby, JRuby) don't have this limitation. + +## Quick Start + +``` +$ gem install puma +$ puma +``` + +Without arguments, puma will look for a rackup (.ru) file in +working directory called `config.ru`. + +## SSL Connection Support + +Puma will install/compile with support for ssl sockets, assuming OpenSSL +development files are installed on the system. + +If the system does not have OpenSSL development files installed, Puma will +install/compile, but it will not allow ssl connections. + +## Frameworks + +### Rails + +Puma is the default server for Rails, included in the generated Gemfile. + +Start your server with the `rails` command: + +``` +$ rails server +``` + +Many configuration options and Puma features are not available when using `rails server`. It is recommended that you use Puma's executable instead: + +``` +$ bundle exec puma +``` + +### Sinatra + +You can run your Sinatra application with Puma from the command line like this: + +``` +$ ruby app.rb -s Puma +``` + +In order to actually configure Puma using a config file, like `puma.rb`, however, you need to use the `puma` executable. To do this, you must add a rackup file to your Sinatra app: + +```ruby +# config.ru +require './app' +run Sinatra::Application +``` + +You can then start your application using: + +``` +$ bundle exec puma +``` + +## Configuration + +Puma provides numerous options. Consult `puma -h` (or `puma --help`) for a full list of CLI options, or see `Puma::DSL` or [dsl.rb](https://github.com/puma/puma/blob/master/lib/puma/dsl.rb). + +You can also find several configuration examples as part of the +[test](https://github.com/puma/puma/tree/master/test/config) suite. + +For debugging purposes, you can set the environment variable `PUMA_LOG_CONFIG` with a value +and the loaded configuration will be printed as part of the boot process. + +### Thread Pool + +Puma uses a thread pool. You can set the minimum and maximum number of threads that are available in the pool with the `-t` (or `--threads`) flag: + +``` +$ puma -t 8:32 +``` + +Puma will automatically scale the number of threads, from the minimum until it caps out at the maximum, based on how much traffic is present. The current default is `0:16` and on MRI is `0:5`. Feel free to experiment, but be careful not to set the number of maximum threads to a large number, as you may exhaust resources on the system (or cause contention for the Global VM Lock, when using MRI). + +Be aware that additionally Puma creates threads on its own for internal purposes (e.g. handling slow clients). So, even if you specify -t 1:1, expect around 7 threads created in your application. + +### Clustered mode + +Puma also offers "clustered mode". Clustered mode `fork`s workers from a master process. Each child process still has its own thread pool. You can tune the number of workers with the `-w` (or `--workers`) flag: + +``` +$ puma -t 8:32 -w 3 +``` + +Or with the `WEB_CONCURRENCY` environment variable: + +``` +$ WEB_CONCURRENCY=3 puma -t 8:32 +``` + +Note that threads are still used in clustered mode, and the `-t` thread flag setting is per worker, so `-w 2 -t 16:16` will spawn 32 threads in total, with 16 in each worker process. + +If the `WEB_CONCURRENCY` environment variable is set to `"auto"` and the `concurrent-ruby` gem is available in your application, Puma will set the worker process count to the result of [available processors](https://ruby-concurrency.github.io/concurrent-ruby/master/Concurrent.html#available_processor_count-class_method). + +For an in-depth discussion of the tradeoffs of thread and process count settings, [see our docs](https://github.com/puma/puma/blob/9282a8efa5a0c48e39c60d22ca70051a25df9f55/docs/kubernetes.md#workers-per-pod-and-other-config-issues). + +In clustered mode, Puma can "preload" your application. This loads all the application code *prior* to forking. Preloading reduces total memory usage of your application via an operating system feature called [copy-on-write](https://en.wikipedia.org/wiki/Copy-on-write). + +If the `WEB_CONCURRENCY` environment variable is set to a value > 1 (and `--prune-bundler` has not been specified), preloading will be enabled by default. Otherwise, you can use the `--preload` flag from the command line: + +``` +$ puma -w 3 --preload +``` + +Or, if you're using a configuration file, you can use the `preload_app!` method: + +```ruby +# config/puma.rb +workers 3 +preload_app! +``` + +Preloading can’t be used with phased restart, since phased restart kills and restarts workers one-by-one, and preloading copies the code of master into the workers. + +#### Clustered mode hooks + +When using clustered mode, Puma's configuration DSL provides `before_fork` and `on_worker_boot` +hooks to run code when the master process forks and child workers are booted respectively. + +It is recommended to use these hooks with `preload_app!`, otherwise constants loaded by your +application (such as `Rails`) will not be available inside the hooks. + +```ruby +# config/puma.rb +before_fork do + # Add code to run inside the Puma master process before it forks a worker child. +end + +on_worker_boot do + # Add code to run inside the Puma worker process after forking. +end +``` + +In addition, there is an `on_refork` and `after_refork` hooks which are used only in [`fork_worker` mode](docs/fork_worker.md), +when the worker 0 child process forks a grandchild worker: + +```ruby +on_refork do + # Used only when fork_worker mode is enabled. Add code to run inside the Puma worker 0 + # child process before it forks a grandchild worker. +end +``` + +```ruby +after_refork do + # Used only when fork_worker mode is enabled. Add code to run inside the Puma worker 0 + # child process after it forks a grandchild worker. +end +``` + +Importantly, note the following considerations when Ruby forks a child process: + +1. File descriptors such as network sockets **are** copied from the parent to the forked + child process. Dual-use of the same sockets by parent and child will result in I/O conflicts + such as `SocketError`, `Errno::EPIPE`, and `EOFError`. +2. Background Ruby threads, including threads used by various third-party gems for connection + monitoring, etc., are **not** copied to the child process. Often this does not cause + immediate problems until a third-party connection goes down, at which point there will + be no supervisor to reconnect it. + +Therefore, we recommend the following: + +1. If possible, do not establish any socket connections (HTTP, database connections, etc.) + inside Puma's master process when booting. +2. If (1) is not possible, use `before_fork` and `on_refork` to disconnect the parent's socket + connections when forking, so that they are not accidentally copied to the child process. +3. Use `on_worker_boot` to restart any background threads on the forked child. +4. Use `after_refork` to restart any background threads on the parent. + +#### Master process lifecycle hooks + +Puma's configuration DSL provides master process lifecycle hooks `on_booted`, `on_restart`, and `on_stopped` +which may be used to specify code blocks to run on each event: + +```ruby +# config/puma.rb +on_booted do + # Add code to run in the Puma master process after it boots, + # and also after a phased restart completes. +end + +on_restart do + # Add code to run in the Puma master process when it receives + # a restart command but before it restarts. +end + +on_stopped do + # Add code to run in the Puma master process when it receives + # a stop command but before it shuts down. +end +``` + +### Error handling + +If Puma encounters an error outside of the context of your application, it will respond with a 400/500 and a simple +textual error message (see `Puma::Server#lowlevel_error` or [server.rb](https://github.com/puma/puma/blob/master/lib/puma/server.rb)). +You can specify custom behavior for this scenario. For example, you can report the error to your third-party +error-tracking service (in this example, [rollbar](https://rollbar.com)): + +```ruby +lowlevel_error_handler do |e, env, status| + if status == 400 + message = "The server could not process the request due to an error, such as an incorrectly typed URL, malformed syntax, or a URL that contains illegal characters.\n" + else + message = "An error has occurred, and engineers have been informed. Please reload the page. If you continue to have problems, contact support@example.com\n" + Rollbar.critical(e) + end + + [status, {}, [message]] +end +``` + +### Binding TCP / Sockets + +Bind Puma to a socket with the `-b` (or `--bind`) flag: + +``` +$ puma -b tcp://127.0.0.1:9292 +``` + +To use a UNIX Socket instead of TCP: + +``` +$ puma -b unix:///var/run/puma.sock +``` + +If you need to change the permissions of the UNIX socket, just add a umask parameter: + +``` +$ puma -b 'unix:///var/run/puma.sock?umask=0111' +``` + +Need a bit of security? Use SSL sockets: + +``` +$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert' +``` +#### Self-signed SSL certificates (via the [`localhost`] gem, for development use): + +Puma supports the [`localhost`] gem for self-signed certificates. This is particularly useful if you want to use Puma with SSL locally, and self-signed certificates will work for your use-case. Currently, the integration can only be used in MRI. + +Puma automatically configures SSL when the [`localhost`] gem is loaded in a `development` environment: + +Add the gem to your Gemfile: +```ruby +group(:development) do + gem 'localhost' +end +``` + +And require it implicitly using bundler: +```ruby +require "bundler" +Bundler.require(:default, ENV["RACK_ENV"].to_sym) +``` + +Alternatively, you can require the gem in your configuration file, either `config/puma/development.rb`, `config/puma.rb`, or set via the `-C` cli option: +```ruby +require 'localhost' +# configuration methods (from Puma::DSL) as needed +``` + +Additionally, Puma must be listening to an SSL socket: + +```shell +$ puma -b 'ssl://localhost:9292' -C config/use_local_host.rb + +# The following options allow you to reach Puma over HTTP as well: +$ puma -b ssl://localhost:9292 -b tcp://localhost:9393 -C config/use_local_host.rb +``` + +[`localhost`]: https://github.com/socketry/localhost + +#### Controlling SSL Cipher Suites + +To use or avoid specific SSL ciphers for TLSv1.2 and below, use `ssl_cipher_filter` or `ssl_cipher_list` options. + +##### Ruby: + +``` +$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&ssl_cipher_filter=!aNULL:AES+SHA' +``` + +##### JRuby: + +``` +$ puma -b 'ssl://127.0.0.1:9292?keystore=path_to_keystore&keystore-pass=keystore_password&ssl_cipher_list=TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA' +``` + +To configure the available TLSv1.3 ciphersuites, use `ssl_ciphersuites` option (not available for JRuby). + +##### Ruby: + +``` +$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&ssl_ciphersuites=TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256' +``` + +See https://www.openssl.org/docs/man1.1.1/man1/ciphers.html for cipher filter format and full list of cipher suites. + +Disable TLS v1 with the `no_tlsv1` option: + +``` +$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&no_tlsv1=true' +``` + +#### Controlling OpenSSL Verification Flags + +To enable verification flags offered by OpenSSL, use `verification_flags` (not available for JRuby): + +``` +$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&verification_flags=PARTIAL_CHAIN' +``` + +You can also set multiple verification flags (by separating them with a comma): + +``` +$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&verification_flags=PARTIAL_CHAIN,CRL_CHECK' +``` + +List of available flags: `USE_CHECK_TIME`, `CRL_CHECK`, `CRL_CHECK_ALL`, `IGNORE_CRITICAL`, `X509_STRICT`, `ALLOW_PROXY_CERTS`, `POLICY_CHECK`, `EXPLICIT_POLICY`, `INHIBIT_ANY`, `INHIBIT_MAP`, `NOTIFY_POLICY`, `EXTENDED_CRL_SUPPORT`, `USE_DELTAS`, `CHECK_SS_SIGNATURE`, `TRUSTED_FIRST`, `SUITEB_128_LOS_ONLY`, `SUITEB_192_LOS`, `SUITEB_128_LOS`, `PARTIAL_CHAIN`, `NO_ALT_CHAINS`, `NO_CHECK_TIME` +(see https://www.openssl.org/docs/manmaster/man3/X509_VERIFY_PARAM_set_hostflags.html#VERIFICATION-FLAGS). + +#### Controlling OpenSSL Password Decryption + +To enable runtime decryption of an encrypted SSL key (not available for JRuby), use `key_password_command`: + +``` +$ puma -b 'ssl://127.0.0.1:9292?key=path_to_key&cert=path_to_cert&key_password_command=/path/to/command.sh' +``` + +`key_password_command` must: + +1. Be executable by Puma. +2. Print the decryption password to stdout. + + For example: + +```shell +#!/bin/sh + +echo "this is my password" +``` + +`key_password_command` can be used with `key` or `key_pem`. If the key +is not encrypted, the executable will not be called. + +### Control/Status Server + +Puma has a built-in status and control app that can be used to query and control Puma. + +``` +$ puma --control-url tcp://127.0.0.1:9293 --control-token foo +``` + +Puma will start the control server on localhost port 9293. All requests to the control server will need to include control token (in this case, `token=foo`) as a query parameter. This allows for simple authentication. Check out `Puma::App::Status` or [status.rb](https://github.com/puma/puma/blob/master/lib/puma/app/status.rb) to see what the status app has available. + +You can also interact with the control server via `pumactl`. This command will restart Puma: + +``` +$ pumactl --control-url 'tcp://127.0.0.1:9293' --control-token foo restart +``` + +To see a list of `pumactl` options, use `pumactl --help`. + +### Configuration File + +You can also provide a configuration file with the `-C` (or `--config`) flag: + +``` +$ puma -C /path/to/config +``` + +If no configuration file is specified, Puma will look for a configuration file at `config/puma.rb`. If an environment is specified (via the `--environment` flag or through the `APP_ENV`, `RACK_ENV`, or `RAILS_ENV` environment variables) Puma looks for a configuration file at `config/puma/.rb` and then falls back to `config/puma.rb`. + +If you want to prevent Puma from looking for a configuration file in those locations, include the `--no-config` flag: + +``` +$ puma --no-config + +# or + +$ puma -C "-" +``` + +The other side-effects of setting the environment are whether to show stack traces (in `development` or `test`), and setting RACK_ENV may potentially affect middleware looking for this value to change their behavior. The default puma RACK_ENV value is `development`. You can see all config default values in `Puma::Configuration#puma_default_options` or [configuration.rb](https://github.com/puma/puma/blob/61c6213fbab/lib/puma/configuration.rb#L182-L204). + +Check out `Puma::DSL` or [dsl.rb](https://github.com/puma/puma/blob/master/lib/puma/dsl.rb) to see all available options. + +## Restart + +Puma includes the ability to restart itself. When available (MRI, Rubinius, JRuby), Puma performs a "hot restart". This is the same functionality available in *Unicorn* and *NGINX* which keep the server sockets open between restarts. This makes sure that no pending requests are dropped while the restart is taking place. + +For more, see the [Restart documentation](docs/restart.md). + +## Signals + +Puma responds to several signals. A detailed guide to using UNIX signals with Puma can be found in the [Signals documentation](docs/signals.md). + +## Platform Constraints + +Some platforms do not support all Puma features. + + * **JRuby**, **Windows**: server sockets are not seamless on restart, they must be closed and reopened. These platforms have no way to pass descriptors into a new process that is exposed to Ruby. Also, cluster mode is not supported due to a lack of fork(2). + * **Windows**: Cluster mode is not supported due to a lack of fork(2). + * **Kubernetes**: The way Kubernetes handles pod shutdowns interacts poorly with server processes implementing graceful shutdown, like Puma. See the [kubernetes section of the documentation](docs/kubernetes.md) for more details. + +## Known Bugs + +For MRI versions 2.2.7, 2.2.8, 2.2.9, 2.2.10, 2.3.4 and 2.4.1, you may see ```stream closed in another thread (IOError)```. It may be caused by a [Ruby bug](https://bugs.ruby-lang.org/issues/13632). It can be fixed with the gem https://rubygems.org/gems/stopgap_13632: + +```ruby +if %w(2.2.7 2.2.8 2.2.9 2.2.10 2.3.4 2.4.1).include? RUBY_VERSION + begin + require 'stopgap_13632' + rescue LoadError + end +end +``` + +## Deployment + + * Puma has support for Capistrano with an [external gem](https://github.com/seuros/capistrano-puma). + + * Additionally, Puma has support for built-in daemonization via the [puma-daemon](https://github.com/kigster/puma-daemon) ruby gem. The gem restores the `daemonize` option that was removed from Puma starting version 5, but only for MRI Ruby. + + +It is common to use process monitors with Puma. Modern process monitors like systemd or rc.d +provide continuous monitoring and restarts for increased reliability in production environments: + +* [rc.d](docs/jungle/rc.d/README.md) +* [systemd](docs/systemd.md) + +Community guides: + +* [Deploying Puma on OpenBSD using relayd and httpd](https://gist.github.com/anon987654321/4532cf8d6c59c1f43ec8973faa031103) + +## Community Extensions + +### Plugins + +* [puma-metrics](https://github.com/harmjanblok/puma-metrics) — export Puma metrics to Prometheus +* [puma-plugin-statsd](https://github.com/yob/puma-plugin-statsd) — send Puma metrics to statsd +* [puma-plugin-systemd](https://github.com/sj26/puma-plugin-systemd) — deeper integration with systemd for notify, status and watchdog. Puma 5.1.0 integrated notify and watchdog, which probably conflicts with this plugin. Puma 6.1.0 added status support which obsoletes the plugin entirely. +* [puma-plugin-telemetry](https://github.com/babbel/puma-plugin-telemetry) - telemetry plugin for Puma offering various targets to publish +* [puma-acme](https://github.com/anchordotdev/puma-acme) - automatic SSL/HTTPS certificate provisioning and setup + +### Monitoring + +* [puma-status](https://github.com/ylecuyer/puma-status) — Monitor CPU/Mem/Load of running puma instances from the CLI + +## Contributing + +Find details for contributing in the [contribution guide](CONTRIBUTING.md). + +## License + +Puma is copyright Evan Phoenix and contributors, licensed under the BSD 3-Clause license. See the included LICENSE file for details. diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/bin/puma b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/bin/puma new file mode 100755 index 00000000..9c67c0fc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/bin/puma @@ -0,0 +1,10 @@ +#!/usr/bin/env ruby +# +# Copyright (c) 2011 Evan Phoenix +# + +require 'puma/cli' + +cli = Puma::CLI.new ARGV + +cli.run diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/bin/puma-wild b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/bin/puma-wild new file mode 100644 index 00000000..3701b210 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/bin/puma-wild @@ -0,0 +1,25 @@ +#!/usr/bin/env ruby +# +# Copyright (c) 2014 Evan Phoenix +# + +require 'rubygems' + +cli_arg = ARGV.shift + +inc = "" + +if cli_arg == "-I" + inc = ARGV.shift + $LOAD_PATH.concat inc.split(":") +end + +module Puma; end + +Puma.const_set(:WILD_ARGS, ["-I", inc]) + +require 'puma/cli' + +cli = Puma::CLI.new ARGV + +cli.run diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/bin/pumactl b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/bin/pumactl new file mode 100755 index 00000000..51ab353d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/bin/pumactl @@ -0,0 +1,12 @@ +#!/usr/bin/env ruby + +require 'puma/control_cli' + +cli = Puma::ControlCLI.new ARGV.dup + +begin + cli.run +rescue => e + STDERR.puts e.message + exit 1 +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/architecture.md b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/architecture.md new file mode 100644 index 00000000..83f438b7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/architecture.md @@ -0,0 +1,74 @@ +# Architecture + +## Overview + +![https://bit.ly/2iJuFky](images/puma-general-arch.png) + +Puma is a threaded Ruby HTTP application server processing requests across a TCP +and/or UNIX socket. + + +Puma processes (there can be one or many) accept connections from the socket via +a thread (in the [`Reactor`](../lib/puma/reactor.rb) class). The connection, +once fully buffered and read, moves into the `todo` list, where an available +thread will pick it up (in the [`ThreadPool`](../lib/puma/thread_pool.rb) +class). + +Puma works in two main modes: cluster and single. In single mode, only one Puma +process boots. In cluster mode, a `master` process is booted, which prepares +(and may boot) the application and then uses the `fork()` system call to create +one or more `child` processes. These `child` processes all listen to the same +socket. The `master` process does not listen to the socket or process requests - +its purpose is primarily to manage and listen for UNIX signals and possibly kill +or boot `child` processes. + +We sometimes call `child` processes (or Puma processes in `single` mode) +_workers_, and we sometimes call the threads created by Puma's +[`ThreadPool`](../lib/puma/thread_pool.rb) _worker threads_. + +## How Requests Work + +![https://bit.ly/2zwzhEK](images/puma-connection-flow.png) + +* Upon startup, Puma listens on a TCP or UNIX socket. + * The backlog of this socket is configured with a default of 1024, but the + actual backlog value is capped by the `net.core.somaxconn` sysctl value. + The backlog determines the size of the queue for unaccepted connections. If + the backlog is full, the operating system is not accepting new connections. + * This socket backlog is distinct from the `backlog` of work as reported by + `Puma.stats` or the control server. The backlog that `Puma.stats` refers to + represents the number of connections in the process' `todo` set waiting for + a thread from the [`ThreadPool`](../lib/puma/thread_pool.rb). +* By default, a single, separate thread (created by the + [`Reactor`](../lib/puma/reactor.rb) class) reads and buffers requests from the + socket. + * When at least one worker thread is available for work, the reactor thread + listens to the socket and accepts a request (if one is waiting). + * The reactor thread waits for the entire HTTP request to be received. + * Puma exposes the time spent waiting for the HTTP request body to be + received to the Rack app as `env['puma.request_body_wait']` + (milliseconds). + * Once fully buffered and received, the connection is pushed into the "todo" + set. +* Worker threads pop work off the "todo" set for processing. + * The worker thread processes the request via `call`ing the configured Rack + application. The Rack application generates the HTTP response. + * The worker thread writes the response to the connection. While Puma buffers + requests via a separate thread, it does not use a separate thread for + responses. + * Once done, the thread becomes available to process another connection in the + "todo" set. + +### `queue_requests` + +![https://bit.ly/2zxCJ1Z](images/puma-connection-flow-no-reactor.png) + +The `queue_requests` option is `true` by default, enabling the separate reactor +thread used to buffer requests as described above. + +If set to `false`, this buffer will not be used for connections while waiting +for the request to arrive. + +In this mode, when a connection is accepted, it is added to the "todo" queue +immediately, and a worker will synchronously do any waiting necessary to read +the HTTP request from the socket. diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/compile_options.md b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/compile_options.md new file mode 100644 index 00000000..4b4f9f9e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/compile_options.md @@ -0,0 +1,55 @@ +# Compile Options + +There are some `cflags` provided to change Puma's default configuration for its +C extension. + +## Query String, `PUMA_QUERY_STRING_MAX_LENGTH` + +By default, the max length of `QUERY_STRING` is `1024 * 10`. But you may want to +adjust it to accept longer queries in GET requests. + +For manual install, pass the `PUMA_QUERY_STRING_MAX_LENGTH` option like this: + +``` +gem install puma -- --with-cflags="-D PUMA_QUERY_STRING_MAX_LENGTH=64000" +``` + +For Bundler, use its configuration system: + +``` +bundle config build.puma "--with-cflags='-D PUMA_QUERY_STRING_MAX_LENGTH=64000'" +``` + +## Request Path, `PUMA_REQUEST_PATH_MAX_LENGTH` + +By default, the max length of `REQUEST_PATH` is `8192`. But you may want to +adjust it to accept longer paths in requests. + +For manual install, pass the `PUMA_REQUEST_PATH_MAX_LENGTH` option like this: + +``` +gem install puma -- --with-cflags="-D PUMA_REQUEST_PATH_MAX_LENGTH=64000" +``` + +For Bundler, use its configuration system: + +``` +bundle config build.puma "--with-cflags='-D PUMA_REQUEST_PATH_MAX_LENGTH=64000'" +``` + +## Request URI, `PUMA_REQUEST_URI_MAX_LENGTH` + +By default, the max length of `REQUEST_URI` is `1024 * 12`. But you may want to +adjust it to accept longer URIs in requests. + +For manual install, pass the `PUMA_REQUEST_URI_MAX_LENGTH` option like this: + +``` +gem install puma -- --with-cflags="-D PUMA_REQUEST_URI_MAX_LENGTH=64000" +``` + +For Bundler, use its configuration system: + +``` +bundle config build.puma "--with-cflags='-D PUMA_REQUEST_URI_MAX_LENGTH=64000'" +``` diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/deployment.md b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/deployment.md new file mode 100644 index 00000000..2364aa66 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/deployment.md @@ -0,0 +1,102 @@ +# Deployment engineering for Puma + +Puma expects to be run in a deployed environment eventually. You can use it as +your development server, but most people use it in their production deployments. + +To that end, this document serves as a foundation of wisdom regarding deploying +Puma to production while increasing happiness and decreasing downtime. + +## Specifying Puma + +Most people will specify Puma by including `gem "puma"` in a Gemfile, so we'll +assume this is how you're using Puma. + +## Single vs. Cluster mode + +Initially, Puma was conceived as a thread-only web server, but support for +processes was added in version 2. + +To run `puma` in single mode (i.e., as a development environment), set the +number of workers to 0; anything higher will run in cluster mode. + +Here are some tips for cluster mode: + +### MRI + +* Use cluster mode and set the number of workers to 1.5x the number of CPU cores + in the machine, starting from a minimum of 2. +* Set the number of threads to desired concurrent requests/number of workers. + Puma defaults to 5, and that's a decent number. + +#### Migrating from Unicorn + +* If you're migrating from unicorn though, here are some settings to start with: + * Set workers to half the number of unicorn workers you're using + * Set threads to 2 + * Enjoy 50% memory savings +* As you grow more confident in the thread-safety of your app, you can tune the + workers down and the threads up. + +#### Ubuntu / Systemd (Systemctl) Installation + +See [systemd.md](systemd.md) + +#### Worker utilization + +**How do you know if you've got enough (or too many workers)?** + +A good question. Due to MRI's GIL, only one thread can be executing Ruby code at +a time. But since so many apps are waiting on IO from DBs, etc., they can +utilize threads to use the process more efficiently. + +Generally, you never want processes that are pegged all the time. That can mean +there is more work to do than the process can get through. On the other hand, if +you have processes that sit around doing nothing, then they're just eating up +resources. + +Watch your CPU utilization over time and aim for about 70% on average. 70% +utilization means you've got capacity still but aren't starving threads. + +**Measuring utilization** + +Using a timestamp header from an upstream proxy server (e.g., `nginx` or +`haproxy`) makes it possible to indicate how long requests have been waiting for +a Puma thread to become available. + +* Have your upstream proxy set a header with the time it received the request: + * nginx: `proxy_set_header X-Request-Start "${msec}";` + * haproxy >= 1.9: `http-request set-header X-Request-Start + t=%[date()]%[date_us()]` + * haproxy < 1.9: `http-request set-header X-Request-Start t=%[date()]` +* In your Rack middleware, determine the amount of time elapsed since + `X-Request-Start`. +* To improve accuracy, you will want to subtract time spent waiting for slow + clients: + * `env['puma.request_body_wait']` contains the number of milliseconds Puma + spent waiting for the client to send the request body. + * haproxy: `%Th` (TLS handshake time) and `%Ti` (idle time before request) + can can also be added as headers. + +## Should I daemonize? + +The Puma 5.0 release removed daemonization. For older versions and alternatives, +continue reading. + +I prefer not to daemonize my servers and use something like `runit` or `systemd` +to monitor them as child processes. This gives them fast response to crashes and +makes it easy to figure out what is going on. Additionally, unlike `unicorn`, +Puma does not require daemonization to do zero-downtime restarts. + +I see people using daemonization because they start puma directly via Capistrano +task and thus want it to live on past the `cap deploy`. To these people, I say: +You need to be using a process monitor. Nothing is making sure Puma stays up in +this scenario! You're just waiting for something weird to happen, Puma to die, +and to get paged at 3 AM. Do yourself a favor, at least the process monitoring +your OS comes with, be it `sysvinit` or `systemd`. Or branch out and use `runit` +or hell, even `monit`. + +## Restarting + +You probably will want to deploy some new code at some point, and you'd like +Puma to start running that new code. There are a few options for restarting +Puma, described separately in our [restart documentation](restart.md). diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/fork_worker.md b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/fork_worker.md new file mode 100644 index 00000000..6e12ab39 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/fork_worker.md @@ -0,0 +1,41 @@ +# Fork-Worker Cluster Mode [Experimental] + +Puma 5 introduces an experimental new cluster-mode configuration option, `fork_worker` (`--fork-worker` from the CLI). This mode causes Puma to fork additional workers from worker 0, instead of directly from the master process: + +``` +10000 \_ puma 4.3.3 (tcp://0.0.0.0:9292) [puma] +10001 \_ puma: cluster worker 0: 10000 [puma] +10002 \_ puma: cluster worker 1: 10000 [puma] +10003 \_ puma: cluster worker 2: 10000 [puma] +10004 \_ puma: cluster worker 3: 10000 [puma] +``` + +The `fork_worker` option allows your application to be initialized only once for copy-on-write memory savings, and it has two additional advantages: + +1. **Compatible with phased restart.** Because the master process itself doesn't preload the application, this mode works with phased restart (`SIGUSR1` or `pumactl phased-restart`). When worker 0 reloads as part of a phased restart, it initializes a new copy of your application first, then the other workers reload by forking from this new worker already containing the new preloaded application. + + This allows a phased restart to complete as quickly as a hot restart (`SIGUSR2` or `pumactl restart`), while still minimizing downtime by staggering the restart across cluster workers. + +2. **'Refork' for additional copy-on-write improvements in running applications.** Fork-worker mode introduces a new `refork` command that re-loads all nonzero workers by re-forking them from worker 0. + + This command can potentially improve memory utilization in large or complex applications that don't fully pre-initialize on startup, because the re-forked workers can share copy-on-write memory with a worker that has been running for a while and serving requests. + + You can trigger a refork by sending the cluster the `SIGURG` signal or running the `pumactl refork` command at any time. A refork will also automatically trigger once, after a certain number of requests have been processed by worker 0 (default 1000). To configure the number of requests before the auto-refork, pass a positive integer argument to `fork_worker` (e.g., `fork_worker 1000`), or `0` to disable. + +### Usage Considerations + +- `fork_worker` introduces new `on_refork` and `after_refork` configuration hooks. Note the following: + - When initially forking the parent process to the worker 0 child, `before_fork` will trigger on the parent process and `on_worker_boot` will trigger on the worker 0 child as normal. + - When forking the worker 0 child to grandchild workers, `on_refork` and `after_refork` will trigger on the worker 0 child, and `on_worker_boot` will trigger on each grandchild worker. + - For clarity, `before_fork` does not trigger on worker 0, and `after_refork` does not trigger on the grandchild. +- As a general migration guide: + - Copy any logic within your existing `before_fork` hook to the `on_refork` hook. + - Consider to copy logic from your `on_worker_boot` hook to the `after_refork` hook, if it is needed to reset the state of worker 0 after it forks. + +### Limitations + +- This mode is still very experimental so there may be bugs or edge-cases, particularly around expected behavior of existing hooks. Please open a [bug report](https://github.com/puma/puma/issues/new?template=bug_report.md) if you encounter any issues. + +- In order to fork new workers cleanly, worker 0 shuts down its server and stops serving requests so there are no open file descriptors or other kinds of shared global state between processes, and to maximize copy-on-write efficiency across the newly-forked workers. This may temporarily reduce total capacity of the cluster during a phased restart / refork. + +- In a cluster with `n` workers, a normal phased restart stops and restarts workers one by one while the application is loaded in each process, so `n-1` workers are available serving requests during the restart. In a phased restart in fork-worker mode, the application is first loaded in worker 0 while `n-1` workers are available, then worker 0 remains stopped while the rest of the workers are reloaded one by one, leaving only `n-2` workers to be available for a brief period of time. Reloading the rest of the workers should be quick because the application is preloaded at that point, but there may be situations where it can take longer (slow clients, long-running application code, slow worker-fork hooks, etc). diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/images/puma-connection-flow-no-reactor.png b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/images/puma-connection-flow-no-reactor.png new file mode 100644 index 00000000..05ef8d01 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/images/puma-connection-flow-no-reactor.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/images/puma-connection-flow.png b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/images/puma-connection-flow.png new file mode 100644 index 00000000..afae5dfd Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/images/puma-connection-flow.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/images/puma-general-arch.png b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/images/puma-general-arch.png new file mode 100644 index 00000000..89e26bd8 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/images/puma-general-arch.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/java_options.md b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/java_options.md new file mode 100644 index 00000000..ba1cd8d9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/java_options.md @@ -0,0 +1,54 @@ +# Java Options + +`System Properties` or `Environment Variables` can be used to change Puma's +default configuration for its Java extension. The provided values are evaluated +during initialization, and changes while running the app have no effect. +Moreover, default values may be used in case of invalid inputs. + +## Supported Options + +| ENV Name | Default Value | Validation | +|------------------------------|:-------------:|:------------------------:| +| PUMA_QUERY_STRING_MAX_LENGTH | 1024 * 10 | Positive natural number | +| PUMA_REQUEST_PATH_MAX_LENGTH | 8192 | Positive natural number | +| PUMA_REQUEST_URI_MAX_LENGTH | 1024 * 12 | Positive natural number | +| PUMA_SKIP_SIGUSR2 | nil | n/a | + +## Examples + +### Invalid inputs + +An empty string will be handled as missing, and the default value will be used instead. +Puma will print an error message for other invalid values. + +``` +foo@bar:~/puma$ PUMA_QUERY_STRING_MAX_LENGTH=abc PUMA_REQUEST_PATH_MAX_LENGTH='' PUMA_REQUEST_URI_MAX_LENGTH=0 bundle exec bin/puma test/rackup/hello.ru + +The value 0 for PUMA_REQUEST_URI_MAX_LENGTH is invalid. Using default value 12288 instead. +The value abc for PUMA_QUERY_STRING_MAX_LENGTH is invalid. Using default value 10240 instead. +Puma starting in single mode... +``` + +### Valid inputs + +``` +foo@bar:~/puma$ PUMA_REQUEST_PATH_MAX_LENGTH=9 bundle exec bin/puma test/rackup/hello.ru + +Puma starting in single mode... +``` +``` +foo@bar:~ export path=/123456789 # 10 chars +foo@bar:~ curl "http://localhost:9292${path}" + +Puma caught this error: HTTP element REQUEST_PATH is longer than the 9 allowed length. (Puma::HttpParserError) + +foo@bar:~ export path=/12345678 # 9 chars +foo@bar:~ curl "http://localhost:9292${path}" +Hello World +``` + +### Java Flight Recorder Compatibility + +Unfortunately Java Flight Recorder uses `SIGUSR2` internally. If you wish to +use JFR, turn off Puma's trapping of `SIGUSR2` by setting the environment variable +`PUMA_SKIP_SIGUSR2` to any value. diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/jungle/README.md b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/jungle/README.md new file mode 100644 index 00000000..46713f93 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/jungle/README.md @@ -0,0 +1,9 @@ +# Puma as a service + +## Systemd + +See [/docs/systemd](https://github.com/puma/puma/blob/master/docs/systemd.md). + +## rc.d + +See `/docs/jungle/rc.d` for FreeBSD's rc.d scripts diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/jungle/rc.d/README.md b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/jungle/rc.d/README.md new file mode 100644 index 00000000..2c5ddf51 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/jungle/rc.d/README.md @@ -0,0 +1,74 @@ +# Puma as a service using rc.d + +Manage multiple Puma servers as services on one box using FreeBSD's rc.d service. + +## Dependencies + +* `jq` - a command-line json parser is needed to parse the json in the config file + +## Installation + + # Copy the puma script to the rc.d directory (make sure everyone has read/execute perms) + sudo cp puma /usr/local/etc/rc.d/ + + # Create an empty configuration file + sudo touch /usr/local/etc/puma.conf + + # Enable the puma service + sudo echo 'puma_enable="YES"' >> /etc/rc.conf + +## Managing the jungle + +Puma apps are referenced in /usr/local/etc/puma.conf by default. + +Start the jungle running: + +`service puma start` + +This script will run at boot time. + + +You can also stop the jungle (stops ALL puma instances) by running: + +`service puma stop` + + +To restart the jungle: + +`service puma restart` + +## Conventions + +* The script expects: + * a config file to exist under `config/puma.rb` in your app. E.g.: `/home/apps/my-app/config/puma.rb`. + +You can always change those defaults by editing the scripts. + +## Here's what a minimal app's config file should have + +``` +{ + "servers" : [ + { + "dir": "/path/to/rails/project", + "user": "deploy-user", + "ruby_version": "ruby.version", + "ruby_env": "rbenv" + } + ] +} +``` + +## Before starting... + +You need to customise `puma.conf` to: + +* Set the right user your app should be running on unless you want root to execute it! +* Set the directory of the app +* Set the ruby version to execute +* Set the ruby environment (currently set to rbenv, since that is the only ruby environment currently supported) +* Add additional server instances following the scheme in the example + +## Notes: + +Only rbenv is currently supported. diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/jungle/rc.d/puma b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/jungle/rc.d/puma new file mode 100755 index 00000000..e8002238 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/jungle/rc.d/puma @@ -0,0 +1,61 @@ +#!/bin/sh +# + +# PROVIDE: puma + +. /etc/rc.subr + +name="puma" +start_cmd="puma_start" +stop_cmd="puma_stop" +restart_cmd="puma_restart" +rcvar=puma_enable +required_files=/usr/local/etc/puma.conf + +puma_start() +{ + server_count=$(/usr/local/bin/jq ".servers[] .ruby_env" /usr/local/etc/puma.conf | wc -l) + i=0 + while [ "$i" -lt "$server_count" ]; do + rb_env=$(/usr/local/bin/jq -r ".servers[$i].ruby_env" /usr/local/etc/puma.conf) + dir=$(/usr/local/bin/jq -r ".servers[$i].dir" /usr/local/etc/puma.conf) + user=$(/usr/local/bin/jq -r ".servers[$i].user" /usr/local/etc/puma.conf) + rb_ver=$(/usr/local/bin/jq -r ".servers[$i].ruby_version" /usr/local/etc/puma.conf) + case $rb_env in + "rbenv") + cd $dir && rbenv shell $rb_ver && /usr/sbin/daemon -u $user bundle exec puma -C $dir/config/puma.rb + ;; + *) + ;; + esac + i=$(( i + 1 )) + done +} + +puma_stop() +{ + pkill ruby +} + +puma_restart() +{ + server_count=$(/usr/local/bin/jq ".servers[] .ruby_env" /usr/local/etc/puma.conf | wc -l) + i=0 + while [ "$i" -lt "$server_count" ]; do + rb_env=$(/usr/local/bin/jq -r ".servers[$i].ruby_env" /usr/local/etc/puma.conf) + dir=$(/usr/local/bin/jq -r ".servers[$i].dir" /usr/local/etc/puma.conf) + user=$(/usr/local/bin/jq -r ".servers[$i].user" /usr/local/etc/puma.conf) + rb_ver=$(/usr/local/bin/jq -r ".servers[$i].ruby_version" /usr/local/etc/puma.conf) + case $rb_env in + "rbenv") + cd $dir && rbenv shell $rb_ver && /usr/sbin/daemon -u $user bundle exec puma -C $dir/config/puma.rb + ;; + *) + ;; + esac + i=$(( i + 1 )) + done +} + +load_rc_config $name +run_rc_command "$1" diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/jungle/rc.d/puma.conf b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/jungle/rc.d/puma.conf new file mode 100644 index 00000000..600537ac --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/jungle/rc.d/puma.conf @@ -0,0 +1,10 @@ +{ + "servers" : [ + { + "dir": "/path/to/rails/project", + "user": "deploy-user", + "ruby_version": "ruby.version", + "ruby_env": "rbenv" + } + ] +} diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/kubernetes.md b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/kubernetes.md new file mode 100644 index 00000000..5c59a4db --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/kubernetes.md @@ -0,0 +1,78 @@ +# Kubernetes + +## Running Puma in Kubernetes + +In general running Puma in Kubernetes works as-is, no special configuration is needed beyond what you would write anyway to get a new Kubernetes Deployment going. There is one known interaction between the way Kubernetes handles pod termination and how Puma handles `SIGINT`, where some request might be sent to Puma after it has already entered graceful shutdown mode and is no longer accepting requests. This can lead to dropped requests during rolling deploys. A workaround for this is listed at the end of this article. + +## Basic setup + +Assuming you already have a running cluster and docker image repository, you can run a simple Puma app with the following example Dockerfile and Deployment specification. These are meant as examples only and are deliberately very minimal to the point of skipping many options that are recommended for running in production, like healthchecks and envvar configuration with ConfigMaps. In general you should check the [Kubernetes documentation](https://kubernetes.io/docs/home/) and [Docker documentation](https://docs.docker.com/) for a more comprehensive overview of the available options. + +A basic Dockerfile example: +``` +FROM ruby:2.5.1-alpine # can be updated to newer ruby versions +RUN apk update && apk add build-base # and any other packages you need + +# Only rebuild gem bundle if Gemfile changes +COPY Gemfile Gemfile.lock ./ +RUN bundle install + +# Copy over the rest of the files +COPY . . + +# Open up port and start the service +EXPOSE 9292 +CMD bundle exec rackup -o 0.0.0.0 +``` + +A sample `deployment.yaml`: +``` +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: my-awesome-puma-app +spec: + selector: + matchLabels: + app: my-awesome-puma-app + template: + metadata: + labels: + app: my-awesome-puma-app + service: my-awesome-puma-app + spec: + containers: + - name: my-awesome-puma-app + image: + ports: + - containerPort: 9292 +``` + +## Graceful shutdown and pod termination + +For some high-throughput systems, it is possible that some HTTP requests will return responses with response codes in the 5XX range during a rolling deploy to a new version. This is caused by [the way that Kubernetes terminates a pod during rolling deploys](https://cloud.google.com/blog/products/gcp/kubernetes-best-practices-terminating-with-grace): + +1. The replication controller determines a pod should be shut down. +2. The Pod is set to the “Terminating” State and removed from the endpoints list of all Services, so that it receives no more requests. +3. The pods pre-stop hook get called. The default for this is to send `SIGTERM` to the process inside the pod. +4. The pod has up to `terminationGracePeriodSeconds` (default: 30 seconds) to gracefully shut down. Puma will do this (after it receives SIGTERM) by closing down the socket that accepts new requests and finishing any requests already running before exiting the Puma process. +5. If the pod is still running after `terminationGracePeriodSeconds` has elapsed, the pod receives `SIGKILL` to make sure the process inside it stops. After that, the container exits and all other Kubernetes objects associated with it are cleaned up. + +There is a subtle race condition between step 2 and 3: The replication controller does not synchronously remove the pod from the Services AND THEN call the pre-stop hook of the pod, but rather it asynchronously sends "remove this pod from your endpoints" requests to the Services and then immediately proceeds to invoke the pods' pre-stop hook. If the Service controller (typically something like nginx or haproxy) receives this request handles this request "too" late (due to internal lag or network latency between the replication and Service controllers) then it is possible that the Service controller will send one or more requests to a Puma process which has already shut down its listening socket. These requests will then fail with 5XX error codes. + +The way Kubernetes works this way, rather than handling step 2 synchronously, is due to the CAP theorem: in a distributed system there is no way to guarantee that any message will arrive promptly. In particular, waiting for all Service controllers to report back might get stuck for an indefinite time if one of them has already been terminated or if there has been a net split. A way to work around this is to add a sleep to the pre-stop hook of the same time as the `terminationGracePeriodSeconds` time. This will allow the Puma process to keep serving new requests during the entire grace period, although it will no longer receive new requests after all Service controllers have propagated the removal of the pod from their endpoint lists. Then, after `terminationGracePeriodSeconds`, the pod receives `SIGKILL` and closes down. If your process can't handle SIGKILL properly, for example because it needs to release locks in different services, you can also sleep for a shorter period (and/or increase `terminationGracePeriodSeconds`) as long as the time slept is longer than the time that your Service controllers take to propagate the pod removal. The downside of this workaround is that all pods will take at minimum the amount of time slept to shut down and this will increase the time required for your rolling deploy. + +More discussions and links to relevant articles can be found in https://github.com/puma/puma/issues/2343. + +## Workers Per Pod, and Other Config Issues + +With containerization, you will have to make a decision about how "big" to make each pod. Should you run 2 pods with 50 workers each? 25 pods, each with 4 workers? 100 pods, with each Puma running in single mode? Each scenario represents the same total amount of capacity (100 Puma processes that can respond to requests), but there are tradeoffs to make. + +* Worker counts should be somewhere between 4 and 32 in most cases. You want more than 4 in order to minimize time spent in request queueing for a free Puma worker, but probably less than ~32 because otherwise autoscaling is working in too large of an increment or they probably won't fit very well into your nodes. In any queueing system, queue time is proportional to 1/n, where n is the number of things pulling from the queue. Each pod will have its own request queue (i.e., the socket backlog). If you have 4 pods with 1 worker each (4 request queues), wait times are, proportionally, about 4 times higher than if you had 1 pod with 4 workers (1 request queue). +* Unless you have a very I/O-heavy application (50%+ time spent waiting on IO), use the default thread count (5 for MRI). Using higher numbers of threads with low I/O wait (<50%) will lead to additional request queueing time (latency!) and additional memory usage. +* More processes per pod reduces memory usage per process, because of copy-on-write memory and because the cost of the single master process is "amortized" over more child processes. +* Don't run less than 4 processes per pod if you can. Low numbers of processes per pod will lead to high request queueing, which means you will have to run more pods. +* If multithreaded, allocate 1 CPU per worker. If single threaded, allocate 0.75 cpus per worker. Most web applications spend about 25% of their time in I/O - but when you're running multi-threaded, your Puma process will have higher CPU usage and should be able to fully saturate a CPU core. +* Most Puma processes will use about ~512MB-1GB per worker, and about 1GB for the master process. However, you probably shouldn't bother with setting memory limits lower than around 2GB per process, because most places you are deploying will have 2GB of RAM per CPU. A sensible memory limit for a Puma configuration of 4 child workers might be something like 8 GB (1 GB for the master, 7GB for the 4 children). + diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/nginx.md b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/nginx.md new file mode 100644 index 00000000..64b27826 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/nginx.md @@ -0,0 +1,80 @@ +# Nginx configuration example file + +This is a very common setup using an upstream. It was adapted from some Capistrano recipe I found on the Internet a while ago. + +```nginx +upstream myapp { + server unix:///myapp/tmp/puma.sock; +} + +server { + listen 80; + server_name myapp.com; + + # ~2 seconds is often enough for most folks to parse HTML/CSS and + # retrieve needed images/icons/frames, connections are cheap in + # nginx so increasing this is generally safe... + keepalive_timeout 5; + + # path for static files + root /myapp/public; + access_log /myapp/log/nginx.access.log; + error_log /myapp/log/nginx.error.log info; + + # this rewrites all the requests to the maintenance.html + # page if it exists in the doc root. This is for capistrano's + # disable web task + if (-f $document_root/maintenance.html) { + rewrite ^(.*)$ /maintenance.html last; + break; + } + + location / { + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $host; + + # If the file exists as a static file serve it directly without + # running all the other rewrite tests on it + if (-f $request_filename) { + break; + } + + # check for index.html for directory index + # if it's there on the filesystem then rewrite + # the url to add /index.html to the end of it + # and then break to send it to the next config rules. + if (-f $request_filename/index.html) { + rewrite (.*) $1/index.html break; + } + + # this is the meat of the rack page caching config + # it adds .html to the end of the url and then checks + # the filesystem for that file. If it exists, then we + # rewrite the url to have explicit .html on the end + # and then send it on its way to the next config rule. + # if there is no file on the fs then it sets all the + # necessary headers and proxies to our upstream pumas + if (-f $request_filename.html) { + rewrite (.*) $1.html break; + } + + if (!-f $request_filename) { + proxy_pass http://myapp; + break; + } + } + + # Now this supposedly should work as it gets the filenames with querystrings that Rails provides. + # BUT there's a chance it could break the ajax calls. + location ~* \.(ico|css|gif|jpe?g|png|js)(\?[0-9]+)?$ { + expires max; + break; + } + + # Error pages + # error_page 500 502 503 504 /500.html; + location = /500.html { + root /myapp/current/public; + } +} +``` diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/plugins.md b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/plugins.md new file mode 100644 index 00000000..23316829 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/plugins.md @@ -0,0 +1,42 @@ +## Plugins + +Puma 3.0 added support for plugins that can augment configuration and service +operations. + +There are two canonical plugins to aid in the development of new plugins: + +* [tmp\_restart](https://github.com/puma/puma/blob/master/lib/puma/plugin/tmp_restart.rb): + Restarts the server if the file `tmp/restart.txt` is touched +* [heroku](https://github.com/puma/puma-heroku/blob/master/lib/puma/plugin/heroku.rb): + Packages up the default configuration used by Puma on Heroku (being sunset + with the release of Puma 5.0) + +Plugins are activated in a Puma configuration file (such as `config/puma.rb'`) +by adding `plugin "name"`, such as `plugin "heroku"`. + +Plugins are activated based on path requirements so, activating the `heroku` +plugin is much like `require "puma/plugin/heroku"`. This allows gems to provide +multiple plugins (as well as unrelated gems to provide Puma plugins). + +The `tmp_restart` plugin comes with Puma, so it is always available. + +To use the `heroku` plugin, add `puma-heroku` to your Gemfile or install it. + +### API + +## Server-wide hooks + +Plugins can use a couple of hooks at the server level: `start` and `config`. + +`start` runs when the server has started and allows the plugin to initiate other +functionality to augment Puma. + +`config` runs when the server is being configured and receives a `Puma::DSL` +object that is useful for additional configuration. + +Public methods in [`Puma::Plugin`](../lib/puma/plugin.rb) are treated as a +public API for plugins. + +## Binder hooks + +There's `Puma::Binder#before_parse` method that allows to add proc to run before the body of `Puma::Binder#parse`. Example of usage can be found in [that repository](https://github.com/anchordotdev/puma-acme/blob/v0.1.3/lib/puma/acme/plugin.rb#L97-L118) (`before_parse_hook` could be renamed `before_parse`, making monkey patching of [binder.rb](https://github.com/anchordotdev/puma-acme/blob/v0.1.3/lib/puma/acme/binder.rb) is unnecessary). \ No newline at end of file diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/rails_dev_mode.md b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/rails_dev_mode.md new file mode 100644 index 00000000..add3cee8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/rails_dev_mode.md @@ -0,0 +1,28 @@ +# Running Puma in Rails Development Mode + +## "Loopback requests" + +Be cautious of "loopback requests," where a Rails application executes a request to a server that, in turn, results in another request back to the same Rails application before the first request completes. Having a loopback request will trigger [Rails' load interlock](https://guides.rubyonrails.org/threading_and_code_execution.html#load-interlock) mechanism. The load interlock mechanism prevents a thread from using Rails autoloading mechanism to load constants while the application code is still running inside another thread. + +This issue only occurs in the development environment as Rails' load interlock is not used in production environments. Although we're not sure, we believe this issue may not occur with the new `zeitwerk` code loader. + +### Solutions + +#### 1. Bypass Rails' load interlock with `.permit_concurrent_loads` + +Wrap the first request inside a block that will allow concurrent loads: [`ActiveSupport::Dependencies.interlock.permit_concurrent_loads`](https://guides.rubyonrails.org/threading_and_code_execution.html#permit-concurrent-loads). Anything wrapped inside the `.permit_concurrent_loads` block will bypass the load interlock mechanism, allowing new threads to access the Rails environment and boot properly. + +###### Example + +```ruby +response = ActiveSupport::Dependencies.interlock.permit_concurrent_loads do + # Your HTTP request code here. For example: + Faraday.post url, data: 'foo' +end + +do_something_with response +``` + +#### 2. Use multiple processes on Puma + +Alternatively, you may also enable multiple (single-threaded) workers on Puma. By doing so, you are sidestepping the problem by creating multiple processes rather than new threads. However, this workaround is not ideal because debugging tools such as [byebug](https://github.com/deivid-rodriguez/byebug/issues/487) and [pry](https://github.com/pry/pry/issues/2153), work poorly with any multi-process web server. diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/restart.md b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/restart.md new file mode 100644 index 00000000..7ea5b02c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/restart.md @@ -0,0 +1,65 @@ +Puma provides three distinct kinds of restart operations, each for different use cases. This document describes "hot restarts" and "phased restarts." The third kind of restart operation is called "refork" and is described in the documentation for [`fork_worker`](fork_worker.md). + +## Hot restart + +To perform a "hot" restart, Puma performs an `exec` operation to start the process up again, so no memory is shared between the old process and the new process. As a result, it is safe to issue a restart at any place where you would manually stop Puma and start it again. In particular, it is safe to upgrade Puma itself using a hot restart. + +If the new process is unable to load, it will simply exit. You should therefore run Puma under a process monitor when using it in production. + +### How-to + +Any of the following will cause a Puma server to perform a hot restart: + +* Send the `puma` process the `SIGUSR2` signal +* Issue a `GET` request to the Puma status/control server with the path `/restart` +* Issue `pumactl restart` (this uses the control server method if available, otherwise sends the `SIGUSR2` signal to the process) + +### Supported configurations + +* Works in cluster mode and single mode +* Supported on all platforms + +### Client experience + +* All platforms: clients with an in-flight request are served responses before the connection is closed gracefully. Puma gracefully disconnects any idle HTTP persistent connections before restarting. +* On MRI or TruffleRuby on Linux and BSD: Clients who connect just before the server restarts may experience increased latency while the server stops and starts again, but their connections will not be closed prematurely. +* On Windows and JRuby: Clients who connect just before a restart may experience "connection reset" errors. + +### Additional notes + +* The newly started Puma process changes its current working directory to the directory specified by the `directory` option. If `directory` is set to symlink, this is automatically re-evaluated, so this mechanism can be used to upgrade the application. +* Only one version of the application is running at a time. +* `on_restart` is invoked just before the server shuts down. This can be used to clean up resources (like long-lived database connections) gracefully. Since Ruby 2.0, it is not typically necessary to explicitly close file descriptors on restart. This is because any file descriptor opened by Ruby will have the `FD_CLOEXEC` flag set, meaning that file descriptors are closed on `exec`. `on_restart` is useful, though, if your application needs to perform any more graceful protocol-specific shutdown procedures before closing connections. + +## Phased restart + +Phased restarts replace all running workers in a Puma cluster. This is a useful way to upgrade the application that Puma is serving gracefully. A phased restart works by first killing an old worker, then starting a new worker, waiting until the new worker has successfully started before proceeding to the next worker. This process continues until all workers are replaced. The master process is not restarted. + +### How-to + +Any of the following will cause a Puma server to perform a phased restart: + +* Send the `puma` process the `SIGUSR1` signal +* Issue a `GET` request to the Puma status/control server with the path `/phased-restart` +* Issue `pumactl phased-restart` (this uses the control server method if available, otherwise sends the `SIGUSR1` signal to the process) + +### Supported configurations + +* Works in cluster mode only +* To support upgrading the application that Puma is serving, ensure `prune_bundler` is enabled and that `preload_app!` is disabled +* Supported on all platforms where cluster mode is supported + +### Client experience + +* In-flight requests are always served responses before the connection is closed gracefully +* Idle persistent connections are gracefully disconnected +* New connections are not lost, and clients will not experience any increase in latency (as long as the number of configured workers is greater than one) + +### Additional notes + +* When a phased restart begins, the Puma master process changes its current working directory to the directory specified by the `directory` option. If `directory` is set to symlink, this is automatically re-evaluated, so this mechanism can be used to upgrade the application. +* On a single server, it's possible that two versions of the application are running concurrently during a phased restart. +* `on_restart` is not invoked +* Phased restarts can be slow for Puma clusters with many workers. Hot restarts often complete more quickly, but at the cost of increased latency during the restart. +* Phased restarts cannot be used to upgrade any gems loaded by the Puma master process, including `puma` itself, anything in `extra_runtime_dependencies`, or dependencies thereof. Upgrading other gems is safe. +* If you remove the gems from old releases as part of your deployment strategy, there are additional considerations. Do not put any gems into `extra_runtime_dependencies` that have native extensions or have dependencies that have native extensions (one common example is `puma_worker_killer` and its dependency on `ffi`). Workers will fail on boot during a phased restart. The underlying issue is recorded in [an issue on the rubygems project](https://github.com/rubygems/rubygems/issues/4004). Hot restarts are your only option here if you need these dependencies. diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/signals.md b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/signals.md new file mode 100644 index 00000000..915560cf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/signals.md @@ -0,0 +1,98 @@ +The [unix signal](https://en.wikipedia.org/wiki/Unix_signal) is a method of sending messages between [processes](https://en.wikipedia.org/wiki/Process_(computing)). When a signal is sent, the operating system interrupts the target process's normal flow of execution. There are standard signals that are used to stop a process, but there are also custom signals that can be used for other purposes. This document is an attempt to list all supported signals that Puma will respond to. In general, signals need only be sent to the master process of a cluster. + +## Sending Signals + +If you are new to signals, it can be helpful to see how they are used. When a process starts in a *nix-like operating system, it will have a [PID - or process identifier](https://en.wikipedia.org/wiki/Process_identifier) that can be used to send signals to the process. For demonstration, we will create an infinitely running process by tailing a file: + +```sh +$ echo "foo" >> my.log +$ irb +> pid = Process.spawn 'tail -f my.log' +``` + +From here, we can see that the tail process is running by using the `ps` command: + +```sh +$ ps aux | grep tail +schneems 87152 0.0 0.0 2432772 492 s032 S+ 12:46PM 0:00.00 tail -f my.log +``` + +You can send a signal in Ruby using the [Process module](https://ruby-doc.org/3.2.2/Process.html#method-c-kill): + +``` +$ irb +> puts pid +=> 87152 +Process.detach(pid) # https://ruby-doc.org/3.2.2/Process.html#method-c-detach +Process.kill("TERM", pid) +``` + +Now you will see via `ps` that there is no more `tail` process. Sometimes when referring to signals, the `SIG` prefix will be used. For example, `SIGTERM` is equivalent to sending `TERM` via `Process.kill`. + +## Puma Signals + +Puma cluster responds to these signals: + +- `TTIN` increment the worker count by 1 +- `TTOU` decrement the worker count by 1 +- `TERM` send `TERM` to worker. The worker will attempt to finish then exit. +- `USR2` restart workers. This also reloads the Puma configuration file, if there is one. +- `USR1` restart workers in phases, a rolling restart. This will not reload the configuration file. +- `HUP ` reopen log files defined in stdout_redirect configuration parameter. If there is no stdout_redirect option provided, it will behave like `INT` +- `INT ` equivalent of sending Ctrl-C to cluster. Puma will attempt to finish then exit. +- `CHLD` +- `URG ` refork workers in phases from worker 0 if `fork_workers` option is enabled. +- `INFO` print backtraces of all puma threads + +## Callbacks order in case of different signals + +### Start application + +``` +puma configuration file reloaded, if there is one +* Pruning Bundler environment +puma configuration file reloaded, if there is one + +before_fork +on_worker_fork +after_worker_fork + +Gemfile in context + +on_worker_boot + +Code of the app is loaded and running +``` + +### Send USR2 + +``` +on_worker_shutdown +on_restart + +puma configuration file reloaded, if there is one + +before_fork +on_worker_fork +after_worker_fork + +Gemfile in context + +on_worker_boot + +Code of the app is loaded and running +``` + +### Send USR1 + +``` +on_worker_shutdown +on_worker_fork +after_worker_fork + +Gemfile in context + +on_worker_boot + +Code of the app is loaded and running +``` diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/stats.md b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/stats.md new file mode 100644 index 00000000..2b55980f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/stats.md @@ -0,0 +1,147 @@ +## Accessing stats + +Stats can be accessed in two ways: + +### control server + +`$ pumactl stats` or `GET /stats` + +[Read more about `pumactl` and the control server in the README.](https://github.com/puma/puma#controlstatus-server). + +### Puma.stats + +`Puma.stats` produces a JSON string. `Puma.stats_hash` produces a ruby hash. + +#### in single mode + +Invoke `Puma.stats` anywhere in runtime, e.g. in a rails initializer: + +```ruby +# config/initializers/puma_stats.rb + +Thread.new do + loop do + sleep 30 + puts Puma.stats + end +end +``` + +#### in cluster mode + +Invoke `Puma.stats` from the master process + +```ruby +# config/puma.rb + +before_fork do + Thread.new do + loop do + puts Puma.stats + sleep 30 + end + end +end +``` + + +## Explanation of stats + +`Puma.stats` returns different information and a different structure depending on if Puma is in single vs. cluster mode. There is one top-level attribute that is common to both modes: + +* started_at: when Puma was started + +### single mode and individual workers in cluster mode + +When Puma runs in single mode, these stats are available at the top level. When Puma runs in cluster mode, these stats are available within the `worker_status` array in a hash labeled `last_status`, in an array of hashes where one hash represents each worker. + +* backlog: requests that are waiting for an available thread to be available. if this is frequently above 0, you need more capacity. +* running: how many threads are spawned. A spawned thread may be busy processing a request or waiting for a new request. If `min_threads` and `max_threads` are set to the same number, + this will be a never-changing number (other than rare cases when a thread dies, etc). +* busy_threads: `running` - `how many threads are waiting to receive work` + `how many requests are waiting for a thread to pick them up`. + this is a "wholistic" stat reflecting the overall current state of work to be done and the capacity to do it. +* pool_capacity: `how many threads are waiting to receive work` + `max_threads` - `running`. In a typical configuration where `min_threads` + and `max_threads` are configured to the same number, this is simply `how many threads are waiting to receive work`. This number exists only as a stat + and is not used for any internal decisions, unlike `busy_theads`, which is usually a more useful stat. +* max_threads: the maximum number of threads Puma is configured to spool per worker +* requests_count: the number of requests this worker has served since starting + + +### cluster mode + +* phase: which phase of restart the process is in, during [phased restart](https://github.com/puma/puma/blob/master/docs/restart.md) +* workers: ?? +* booted_workers: how many workers currently running? +* old_workers: ?? +* worker_status: array of hashes of info for each worker (see below) + +### worker status + +* started_at: when the worker started +* pid: the process id of the worker process +* index: each worker gets a number. if Puma is configured to have 3 workers, then this will be 0, 1, or 2 +* booted: if it's done booting [?] +* last_checkin: Last time the worker responded to the master process' heartbeat check. +* last_status: a hash of info about the worker's state handling requests. See the explanation for this in "single mode and individual workers in cluster mode" section above. + + +## Examples + +Here are two example stats hashes produced by `Puma.stats`: + +### single + +```json +{ + "started_at": "2021-01-14T07:12:35Z", + "backlog": 0, + "running": 5, + "pool_capacity": 5, + "max_threads": 5, + "requests_count": 3 +} +``` + +### cluster + +```json +{ + "started_at": "2021-01-14T07:09:17Z", + "workers": 2, + "phase": 0, + "booted_workers": 2, + "old_workers": 0, + "worker_status": [ + { + "started_at": "2021-01-14T07:09:24Z", + "pid": 64136, + "index": 0, + "phase": 0, + "booted": true, + "last_checkin": "2021-01-14T07:11:09Z", + "last_status": { + "backlog": 0, + "running": 5, + "pool_capacity": 5, + "max_threads": 5, + "requests_count": 2 + } + }, + { + "started_at": "2021-01-14T07:09:24Z", + "pid": 64137, + "index": 1, + "phase": 0, + "booted": true, + "last_checkin": "2021-01-14T07:11:09Z", + "last_status": { + "backlog": 0, + "running": 5, + "pool_capacity": 5, + "max_threads": 5, + "requests_count": 1 + } + } + ] +} +``` diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/systemd.md b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/systemd.md new file mode 100644 index 00000000..1c7f577a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/systemd.md @@ -0,0 +1,253 @@ +# systemd + +[systemd](https://www.freedesktop.org/wiki/Software/systemd/) is a commonly +available init system (PID 1) on many Linux distributions. It offers process +monitoring (including automatic restarts) and other useful features for running +Puma in production. + +## Service Configuration + +Below is a sample puma.service configuration file for systemd, which can be +copied or symlinked to `/etc/systemd/system/puma.service`, or if desired, using +an application or instance-specific name. + +Note that this uses the systemd preferred "simple" type where the start command +remains running in the foreground (does not fork and exit). + +~~~~ ini +[Unit] +Description=Puma HTTP Server +After=network.target + +# Uncomment for socket activation (see below) +# Requires=puma.socket + +[Service] +# Puma supports systemd's `Type=notify` and watchdog service +# monitoring, as of Puma 5.1 or later. +# On earlier versions of Puma or JRuby, change this to `Type=simple` and remove +# the `WatchdogSec` line. +Type=notify + +# If your Puma process locks up, systemd's watchdog will restart it within seconds. +WatchdogSec=10 + +# Preferably configure a non-privileged user +# User= + +# The path to your application code root directory. +# Also replace the "" placeholders below with this path. +# Example /home/username/myapp +WorkingDirectory= + +# Helpful for debugging socket activation, etc. +# Environment=PUMA_DEBUG=1 + +# SystemD will not run puma even if it is in your path. You must specify +# an absolute URL to puma. For example /usr/local/bin/puma +# Alternatively, create a binstub with `bundle binstubs puma --path ./sbin` in the WorkingDirectory +ExecStart=//bin/puma -C /puma.rb + +# Variant: Rails start. +# ExecStart=//bin/puma -C /config/puma.rb ../config.ru + +# Variant: Use `bundle exec puma` instead of binstub +# Variant: Specify directives inline. +# ExecStart=//puma -b tcp://0.0.0.0:9292 -b ssl://0.0.0.0:9293?key=key.pem&cert=cert.pem + + +Restart=always + +[Install] +WantedBy=multi-user.target +~~~~ + +See +[systemd.exec](https://www.freedesktop.org/software/systemd/man/systemd.exec.html) +for additional details. + +## Socket Activation + +systemd and Puma also support socket activation, where systemd opens the +listening socket(s) in advance and provides them to the Puma master process on +startup. Among other advantages, this keeps listening sockets open across puma +restarts and achieves graceful restarts, including when upgraded Puma, and is +compatible with both clustered mode and application preload. + +**Note:** Any wrapper scripts which `exec`, or other indirections in `ExecStart` +may result in activated socket file descriptors being closed before reaching the +puma master process. + +**Note:** Socket activation doesn't currently work on JRuby. This is tracked in +[#1367]. + +Configure one or more `ListenStream` sockets in a companion `*.socket` unit file +to use socket activation. Also, uncomment the associated `Requires` directive +for the socket unit in the service file (see above.) Here is a sample +puma.socket, matching the ports used in the above puma.service: + +~~~~ ini +[Unit] +Description=Puma HTTP Server Accept Sockets + +[Socket] +ListenStream=0.0.0.0:9292 +ListenStream=0.0.0.0:9293 + +# AF_UNIX domain socket +# SocketUser, SocketGroup, etc. may be needed for Unix domain sockets +# ListenStream=/run/puma.sock + +# Socket options matching Puma defaults +ReusePort=true +Backlog=1024 +# Enable this if you're using Puma with the "low_latency" option, read more in Puma DSL docs and systemd docs: +# https://www.freedesktop.org/software/systemd/man/latest/systemd.socket.html#NoDelay= +# NoDelay=true + +[Install] +WantedBy=sockets.target +~~~~ + +See +[systemd.socket](https://www.freedesktop.org/software/systemd/man/systemd.socket.html) +for additional configuration details. + +Note that the above configurations will work with Puma in either single process +or cluster mode. + +### Sockets and symlinks + +When using releases folders, you should set the socket path using the shared +folder path (ex. `/srv/projet/shared/tmp/puma.sock`), not the release folder +path (`/srv/projet/releases/1234/tmp/puma.sock`). + +Puma will detect the release path socket as different than the one provided by +systemd and attempt to bind it again, resulting in the exception `There is +already a server bound to:`. + +### Binding + +By default, you need to configure Puma to have binds matching with all +ListenStream statements. Any mismatched systemd ListenStreams will be closed by +Puma. + +To automatically bind to all activated sockets, the option +`--bind-to-activated-sockets` can be used. This matches the config DSL +`bind_to_activated_sockets` statement. This will cause Puma to create a bind +automatically for any activated socket. When systemd socket activation is not +enabled, this option does nothing. + +This also accepts an optional argument `only` (DSL: `'only'`) to discard any +binds that's not socket activated. + +## Usage + +Without socket activation, use `systemctl` as root (i.e., via `sudo`) as with +other system services: + +~~~~ sh +# After installing or making changes to puma.service +systemctl daemon-reload + +# Enable so it starts on boot +systemctl enable puma.service + +# Initial startup. +systemctl start puma.service + +# Check status +systemctl status puma.service + +# A normal restart. Warning: listener's sockets will be closed +# while a new puma process initializes. +systemctl restart puma.service +~~~~ + +With socket activation, several but not all of these commands should be run for +both socket and service: + +~~~~ sh +# After installing or making changes to either puma.socket or +# puma.service. +systemctl daemon-reload + +# Enable both socket and service, so they start on boot. Alternatively +# you could leave puma.service disabled, and systemd will start it on +# the first use (with startup lag on the first request) +systemctl enable puma.socket puma.service + +# Initial startup. The Requires directive (see above) ensures the +# socket is started before the service. +systemctl start puma.socket puma.service + +# Check the status of both socket and service. +systemctl status puma.socket puma.service + +# A "hot" restart, with systemd keeping puma.socket listening and +# providing to the new puma (master) instance. +systemctl restart puma.service + +# A normal restart, needed to handle changes to +# puma.socket, such as changing the ListenStream ports. Note +# daemon-reload (above) should be run first. +systemctl restart puma.socket puma.service +~~~~ + +Here is sample output from `systemctl status` with both service and socket +running: + +~~~~ +● puma.socket - Puma HTTP Server Accept Sockets + Loaded: loaded (/etc/systemd/system/puma.socket; enabled; vendor preset: enabled) + Active: active (running) since Thu 2016-04-07 08:40:19 PDT; 1h 2min ago + Listen: 0.0.0.0:9233 (Stream) + 0.0.0.0:9234 (Stream) + +Apr 07 08:40:19 hx systemd[874]: Listening on Puma HTTP Server Accept Sockets. + +● puma.service - Puma HTTP Server + Loaded: loaded (/etc/systemd/system/puma.service; enabled; vendor preset: enabled) + Active: active (running) since Thu 2016-04-07 08:40:19 PDT; 1h 2min ago + Main PID: 28320 (ruby) + CGroup: /system.slice/puma.service + ├─28320 puma 3.3.0 (tcp://0.0.0.0:9233,ssl://0.0.0.0:9234?key=key.pem&cert=cert.pem) [app] + ├─28323 puma: cluster worker 0: 28320 [app] + └─28327 puma: cluster worker 1: 28320 [app] + +Apr 07 08:40:19 hx puma[28320]: Puma starting in cluster mode... +Apr 07 08:40:19 hx puma[28320]: * Version 3.3.0 (ruby 2.2.4-p230), codename: Jovial Platypus +Apr 07 08:40:19 hx puma[28320]: * Min threads: 0, max threads: 16 +Apr 07 08:40:19 hx puma[28320]: * Environment: production +Apr 07 08:40:19 hx puma[28320]: * Process workers: 2 +Apr 07 08:40:19 hx puma[28320]: * Phased restart available +Apr 07 08:40:19 hx puma[28320]: * Activated tcp://0.0.0.0:9233 +Apr 07 08:40:19 hx puma[28320]: * Activated ssl://0.0.0.0:9234?key=key.pem&cert=cert.pem +Apr 07 08:40:19 hx puma[28320]: Use Ctrl-C to stop +~~~~ + +### capistrano3-puma + +By default, [capistrano3-puma](https://github.com/seuros/capistrano-puma) uses +`pumactl` for deployment restarts outside of systemd. To learn the exact +commands that this tool would use for `ExecStart` and `ExecStop`, use the +following `cap` commands in dry-run mode, and update from the above forking +service configuration accordingly. Note also that the configured `User` should +likely be the same as the capistrano3-puma `:puma_user` option. + +~~~~ sh +stage=production # or different stage, as needed +cap $stage puma:start --dry-run +cap $stage puma:stop --dry-run +~~~~ + +### Disabling Puma Systemd Integration + +If you would like to disable Puma's systemd integration, for example if you handle it elsewhere +in your code yourself, simply set the the environment variable `PUMA_SKIP_SYSTEMD` to any value. + + + +[Restart]: https://www.freedesktop.org/software/systemd/man/systemd.service.html#Restart= +[#1367]: https://github.com/puma/puma/issues/1367 +[#1499]: https://github.com/puma/puma/issues/1499 diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/testing_benchmarks_local_files.md b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/testing_benchmarks_local_files.md new file mode 100644 index 00000000..aea776ba --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/testing_benchmarks_local_files.md @@ -0,0 +1,150 @@ +# Testing - benchmark/local files + +These files generate data that shows request-per-second (RPS), etc. Typically, files are in +pairs, a shell script and a Ruby script. The shell script starts the server, then runs the +Ruby file, which starts client request stream(s), then collects and logs metrics. + +## response_time_wrk.sh + +This uses [wrk] for generating data. One or more wrk runs are performed. Summarizes RPS and +wrk latency times. The default for the `-b` argument runs 28 different client request streams, +and takes a bit over 5 minutes. See 'Request Stream Configuration' below for `-b` argument +description. + +
+ Summary output for
benchmarks/local/response_time_wrk.sh -w2 -t5:5 -s tcp6:
+ +``` +Type req/sec 50% 75% 90% 99% 100% Resp Size +───────────────────────────────────────────────────────────────── 1kB +array 13710 0.74 2.52 5.23 7.76 37.45 1024 +chunk 13502 0.76 2.55 5.28 7.84 11.23 1042 +string 13794 0.74 2.51 5.20 7.75 14.07 1024 +io 9615 1.16 3.45 7.13 10.57 15.75 1024 +───────────────────────────────────────────────────────────────── 10kB +array 13458 0.76 2.57 5.31 7.93 13.94 10239 +chunk 13066 0.78 2.64 5.46 8.18 38.48 10320 +string 13500 0.76 2.55 5.29 7.88 11.42 10240 +io 9293 1.18 3.59 7.39 10.94 16.99 10240 +───────────────────────────────────────────────────────────────── 100kB +array 11315 0.96 3.06 6.33 9.49 17.69 102424 +chunk 9916 1.10 3.48 7.20 10.73 15.14 103075 +string 10948 1.00 3.17 6.57 9.83 17.88 102378 +io 8901 1.21 3.72 7.48 11.27 59.98 102407 +───────────────────────────────────────────────────────────────── 256kB +array 9217 1.15 3.82 7.88 11.74 17.12 262212 +chunk 7339 1.45 4.76 9.81 14.63 22.70 264007 +string 8574 1.19 3.81 7.73 11.21 15.80 262147 +io 8911 1.19 3.80 7.55 15.25 60.01 262183 +───────────────────────────────────────────────────────────────── 512kB +array 6951 1.49 5.03 10.28 15.90 25.08 524378 +chunk 5234 2.03 6.56 13.57 20.46 32.15 527862 +string 6438 1.55 5.04 10.12 16.28 72.87 524275 +io 8533 1.15 4.62 8.79 48.15 70.51 524327 +───────────────────────────────────────────────────────────────── 1024kB +array 4122 1.80 15.59 41.87 67.79 121.00 1048565 +chunk 3158 2.82 15.22 31.00 71.39 99.90 1055654 +string 4710 2.24 6.66 13.65 20.38 70.44 1048575 +io 8355 1.23 3.95 7.94 14.08 68.54 1048498 +───────────────────────────────────────────────────────────────── 2048kB +array 2454 4.12 14.02 27.70 43.48 88.89 2097415 +chunk 1743 6.26 17.65 36.98 55.78 92.10 2111358 +string 2479 4.38 12.52 25.65 38.44 95.62 2097502 +io 8264 1.25 3.83 7.76 11.73 65.69 2097090 + +Body ────────── req/sec ────────── ─────── req 50% times ─────── + KB array chunk string io array chunk string io +1 13710 13502 13794 9615 0.745 0.757 0.741 1.160 +10 13458 13066 13500 9293 0.760 0.784 0.759 1.180 +100 11315 9916 10948 8901 0.960 1.100 1.000 1.210 +256 9217 7339 8574 8911 1.150 1.450 1.190 1.190 +512 6951 5234 6438 8533 1.490 2.030 1.550 1.150 +1024 4122 3158 4710 8355 1.800 2.820 2.240 1.230 +2048 2454 1743 2479 8264 4.120 6.260 4.380 1.250 +───────────────────────────────────────────────────────────────────── +wrk -t8 -c16 -d10s +benchmarks/local/response_time_wrk.sh -w2 -t5:5 -s tcp6 -Y +Server cluster mode -w2 -t5:5, bind: tcp6 +Puma repo branch 00-response-refactor +ruby 3.2.0dev (2022-06-14T01:21:55Z master 048f14221c) +YJIT [x86_64-linux] + +[2136] - Gracefully shutting down workers... +[2136] === puma shutdown: 2022-06-13 21:16:13 -0500 === +[2136] - Goodbye! + + 5:15 Total Time +``` +

+ +## bench_base.sh, bench_base.rb + +These two files setup parameters for the Puma server, which is normally started in a shell +script. It then starts a Ruby file (a subclass of BenchBase), passing arguments to it. The +Ruby file is normally used to generate a client request stream(s). + +### Puma Configuration + +The following arguments are used for the Puma server: + +* **`-C`** - configuration file +* **`-d`** - app delay +* **`-r`** - rackup file, often defaults to test/rackup/ci_select.ru +* **`-s`** - bind socket type, default is tcp/tcp4, also tcp6, ssl/ssl4, ssl6, unix, or aunix + (unix & abstract unix are not available with wrk). +* **`-t`** - threads, expressed as '5:5', same as Puma --thread +* **`-w`** - workers, same as Puma --worker +* **`-Y`** - enable Ruby YJIT + +### Request Stream Configuration + +The following arguments are used for request streams: + +* **`-b`** - response body configuration. Body type options are a array, c chunked, s string, + and i for File/IO. None or any combination can be specified, they should start the option. + Then, any combination of comma separated integers can be used for the response body size + in kB. The string 'ac50,100' would create four runs, 50kb array, 50kB chunked, 100kB array, + and 100kB chunked. See 'Testing - test/rackup/ci-*.ru files' for more info. +* **`-c`** - connections per client request stream thread, defaults to 2 for wrk. +* **`-D`** - duration of client request stream in seconds. +* **`-T`** - number of threads in the client request stream. For wrk, this defaults to + 80% of Puma workers * max_threads. + +### Notes - Configuration + +The above lists script arguments. + +`bench_base.sh` contains most server defaults. Many can be set via ENV variables. + +`bench_base.rb` contains the client request stream defaults. The default value for +`-b` is `acsi1,10,100,256,512,1024,2048`, which is a 4 x 7 matrix, and hence, runs +28 jobs. Also, the i body type (File/IO) generates files, they are placed in the +`"#{Dir.tmpdir}/.puma_response_body_io"` directory, which is created. + +### Notes - wrk + +The shell scripts use `-T` for wrk's thread count, since `-t` is used for Puma +server threads. Regarding the `-c` argument, wrk has an interesting behavior. +The total number of connections is set by `(connections/threads).to_i`. The scripts +here use `-c` as connections per thread. Hence, using `-T4 -c2` will yield a total +of eight wrk connections, two per thread. The equivalent wrk arguments would be `-t4 -c8`. + +Puma can only process so many requests, and requests will queue in the backlog +until Puma can respond to them. With wrk, if the number of total connections is +too high, one will see the upper latency times increase, pushing into the lower +latency times as the connections are increased. The default values for wrk's +threads and connections were chosen to minimize requests' time in the backlog. + +An example with four wrk runs using `-b s10`. Notice that `req/sec` varies by +less than 1%, but the `75%` times increase by an order of magnitude: +``` +req/sec 50% 75% 90% 99% 100% Resp Size wrk cmd line +───────────────────────────────────────────────────────────────────────────── + 13597 0.755 2.550 5.260 7.800 13.310 12040 wrk -t8 -c16 -d10 + 13549 0.793 4.430 8.140 11.220 16.600 12002 wrk -t10 -c20 -d10 + 13570 1.040 25.790 40.010 49.070 58.300 11982 wrk -t8 -c64 -d10 + 13684 1.050 25.820 40.080 49.160 66.190 12033 wrk -t16 -c64 -d10 +``` +Finally, wrk's output may cause rounding errors, so the response body size calculation is +imprecise. + +[wrk]: diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/testing_test_rackup_ci_files.md b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/testing_test_rackup_ci_files.md new file mode 100644 index 00000000..029d8256 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/docs/testing_test_rackup_ci_files.md @@ -0,0 +1,36 @@ +# Testing - test/rackup/ci-*.ru files + +## Overview + +Puma should efficiently handle a variety of response bodies, varying both by size +and by the type of object used for the body. + +Five rackup files are located in 'test/rackup' that can be used. All have their +request body size (in kB) set via `Body-Conf` header or with `ENV['CI_BODY_CONF']`. +Additionally, the ci_select.ru file can have it's body type set via a starting +character. + +* **ci_array.ru** - body is an `Array` of 1kB strings. `Content-Length` is not set. +* **ci_chunked.ru** - body is an `Enumerator` of 1kB strings. `Content-Length` is not set. +* **ci_io.ru** - body is a File/IO object. `Content-Length` is set. +* **ci_string.ru** - body is a single string. `Content-Length` is set. +* **ci_select.ru** - can be any of the above. + +All responses have 25 headers, total length approx 1kB. ci_array.ru and ci_chunked.ru +contain 1kB items. + +All can be delayed by a float value (seconds) specified by the `Dly` header + +Note that rhe `Body-Conf` header takes precedence, and `ENV['CI_BODY_CONF']` is +only read on load. + +## ci_select.ru + +The ci_select.ru file allows a starting character to specify the body type in the +`Body-Conf` header or with `ENV['CI_BODY_CONF']`. +* **a** - array of strings +* **c** - chunked (enum) +* **s** - single string +* **i** - File/IO + +A value of `a100` would return a body as an array of 100 1kB strings. diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/Makefile b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/Makefile new file mode 100644 index 00000000..06dc4ae5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/Makefile @@ -0,0 +1,273 @@ + +SHELL = /bin/sh + +# V=0 quiet, V=1 verbose. other values don't work. +V = 0 +V0 = $(V:0=) +Q1 = $(V:1=) +Q = $(Q1:0=@) +ECHO1 = $(V:1=@ :) +ECHO = $(ECHO1:0=@ echo) +NULLCMD = : + +#### Start of system configuration section. #### + +srcdir = . +topdir = /opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 +hdrdir = $(topdir) +arch_hdrdir = /opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux +PATH_SEPARATOR = : +VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby +prefix = $(DESTDIR)/opt/hostedtoolcache/Ruby/3.4.4/x64 +rubysitearchprefix = $(rubylibprefix)/$(sitearch) +rubyarchprefix = $(rubylibprefix)/$(arch) +rubylibprefix = $(libdir)/$(RUBY_BASE_NAME) +exec_prefix = $(prefix) +vendorarchhdrdir = $(vendorhdrdir)/$(sitearch) +sitearchhdrdir = $(sitehdrdir)/$(sitearch) +rubyarchhdrdir = $(rubyhdrdir)/$(arch) +vendorhdrdir = $(rubyhdrdir)/vendor_ruby +sitehdrdir = $(rubyhdrdir)/site_ruby +rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME) +vendorarchdir = $(vendorlibdir)/$(sitearch) +vendorlibdir = $(vendordir)/$(ruby_version) +vendordir = $(rubylibprefix)/vendor_ruby +sitearchdir = $(sitelibdir)/$(sitearch) +sitelibdir = $(sitedir)/$(ruby_version) +sitedir = $(rubylibprefix)/site_ruby +rubyarchdir = $(rubylibdir)/$(arch) +rubylibdir = $(rubylibprefix)/$(ruby_version) +sitearchincludedir = $(includedir)/$(sitearch) +archincludedir = $(includedir)/$(arch) +sitearchlibdir = $(libdir)/$(sitearch) +archlibdir = $(libdir)/$(arch) +ridir = $(datarootdir)/$(RI_BASE_NAME) +modular_gc_dir = $(DESTDIR) +mandir = $(datarootdir)/man +localedir = $(datarootdir)/locale +libdir = $(exec_prefix)/lib +psdir = $(docdir) +pdfdir = $(docdir) +dvidir = $(docdir) +htmldir = $(docdir) +infodir = $(datarootdir)/info +docdir = $(datarootdir)/doc/$(PACKAGE) +oldincludedir = $(DESTDIR)/usr/include +includedir = $(prefix)/include +runstatedir = $(localstatedir)/run +localstatedir = $(prefix)/var +sharedstatedir = $(prefix)/com +sysconfdir = $(prefix)/etc +datadir = $(datarootdir) +datarootdir = $(prefix)/share +libexecdir = $(exec_prefix)/libexec +sbindir = $(exec_prefix)/sbin +bindir = $(exec_prefix)/bin +archdir = $(rubyarchdir) + + +CC_WRAPPER = +CC = gcc +CXX = g++ +LIBRUBY = $(LIBRUBY_SO) +LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a +LIBRUBYARG_SHARED = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME) +LIBRUBYARG_STATIC = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)-static $(MAINLIBS) +empty = +OUTFLAG = -o $(empty) +COUTFLAG = -o $(empty) +CSRCFLAG = $(empty) + +RUBY_EXTCONF_H = +cflags = $(hardenflags) $(optflags) $(debugflags) $(warnflags) +cxxflags = +optflags = -O3 -fno-fast-math +debugflags = -ggdb3 +warnflags = -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef +cppflags = +CCDLFLAGS = -fPIC +CFLAGS = $(CCDLFLAGS) $(cflags) -fPIC $(ARCH_FLAG) +INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) +DEFS = +CPPFLAGS = -DHAVE_OPENSSL_BIO_H -DHAVE_DTLS_METHOD -DHAVE_SSL_CTX_SET_SESSION_CACHE_MODE -DHAVE_TLS_SERVER_METHOD -DHAVE_SSL_CTX_SET_MIN_PROTO_VERSION -DHAVE_SSL_CTX_SET_DH_AUTO -DHAVE_SSL_CTX_SET_CIPHERSUITES -DHAVE_SSL_GET1_PEER_CERTIFICATE -DHAVE_RANDOM_BYTES -DENABLE_PATH_CHECK=0 $(DEFS) $(cppflags) +CXXFLAGS = $(CCDLFLAGS) $(ARCH_FLAG) +ldflags = -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed +dldflags = -Wl,--compress-debug-sections=zlib +ARCH_FLAG = +DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG) +LDSHARED = $(CC) -shared +LDSHAREDXX = $(CXX) -shared +POSTLINK = : +AR = gcc-ar +LD = ld +EXEEXT = + +RUBY_INSTALL_NAME = $(RUBY_BASE_NAME) +RUBY_SO_NAME = ruby +RUBYW_INSTALL_NAME = +RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version) +RUBYW_BASE_NAME = rubyw +RUBY_BASE_NAME = ruby + +arch = x86_64-linux +sitearch = $(arch) +ruby_version = 3.4.0 +ruby = $(bindir)/$(RUBY_BASE_NAME) +RUBY = $(ruby) +BUILTRUBY = $(bindir)/$(RUBY_BASE_NAME) +ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/backward.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h + +RM = rm -f +RM_RF = rm -fr +RMDIRS = rmdir --ignore-fail-on-non-empty -p +MAKEDIRS = /usr/bin/mkdir -p +INSTALL = /usr/bin/install -c +INSTALL_PROG = $(INSTALL) -m 0755 +INSTALL_DATA = $(INSTALL) -m 644 +COPY = cp +TOUCH = exit > + +#### End of system configuration section. #### + +preload = +libpath = . $(libdir) +LIBPATH = -L. -L$(libdir) -Wl,-rpath,$(libdir) +DEFFILE = + +CLEANFILES = mkmf.log +DISTCLEANFILES = +DISTCLEANDIRS = + +extout = +extout_prefix = +target_prefix = /puma +LOCAL_LIBS = +LIBS = $(LIBRUBYARG_SHARED) -lssl -lcrypto -lm -lpthread -lc +ORIG_SRCS = http11_parser.c mini_ssl.c puma_http11.c +SRCS = $(ORIG_SRCS) +OBJS = http11_parser.o mini_ssl.o puma_http11.o +HDRS = $(srcdir)/ext_help.h $(srcdir)/http11_parser.h +LOCAL_HDRS = +TARGET = puma_http11 +TARGET_NAME = puma_http11 +TARGET_ENTRY = Init_$(TARGET_NAME) +DLLIB = $(TARGET).so +EXTSTATIC = +STATIC_LIB = + +TIMESTAMP_DIR = . +BINDIR = $(bindir) +RUBYCOMMONDIR = $(sitedir)$(target_prefix) +RUBYLIBDIR = $(sitelibdir)$(target_prefix) +RUBYARCHDIR = $(sitearchdir)$(target_prefix) +HDRDIR = $(sitehdrdir)$(target_prefix) +ARCHHDRDIR = $(sitearchhdrdir)$(target_prefix) +TARGET_SO_DIR = +TARGET_SO = $(TARGET_SO_DIR)$(DLLIB) +CLEANLIBS = $(TARGET_SO) false +CLEANOBJS = $(OBJS) *.bak +TARGET_SO_DIR_TIMESTAMP = $(TIMESTAMP_DIR)/.sitearchdir.-.puma.time + +all: $(DLLIB) +static: $(STATIC_LIB) +.PHONY: all install static install-so install-rb +.PHONY: clean clean-so clean-static clean-rb + +clean-static:: +clean-rb-default:: +clean-rb:: +clean-so:: +clean: clean-so clean-static clean-rb-default clean-rb + -$(Q)$(RM_RF) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time + +distclean-rb-default:: +distclean-rb:: +distclean-so:: +distclean-static:: +distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb + -$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + -$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + -$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true + +realclean: distclean +install: install-so install-rb + +install-so: $(DLLIB) $(TARGET_SO_DIR_TIMESTAMP) + $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) +clean-static:: + -$(Q)$(RM) $(STATIC_LIB) +install-rb: pre-install-rb do-install-rb install-rb-default +install-rb-default: pre-install-rb-default do-install-rb-default +pre-install-rb: Makefile +pre-install-rb-default: Makefile +do-install-rb: +do-install-rb-default: +pre-install-rb-default: + @$(NULLCMD) +$(TARGET_SO_DIR_TIMESTAMP): + $(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR) + $(Q) $(TOUCH) $@ + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + +.SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S + +.cc.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cc.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.mm.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.mm.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cxx.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cxx.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cpp.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cpp.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.c.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.c.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.m.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.m.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +$(TARGET_SO): $(OBJS) Makefile + $(ECHO) linking shared-object puma/$(DLLIB) + -$(Q)$(RM) $(@) + $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) + $(Q) $(POSTLINK) + + + +$(OBJS): $(HDRS) $(ruby_headers) diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/PumaHttp11Service.java b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/PumaHttp11Service.java new file mode 100644 index 00000000..00f63aa2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/PumaHttp11Service.java @@ -0,0 +1,17 @@ +package puma; + +import java.io.IOException; + +import org.jruby.Ruby; +import org.jruby.runtime.load.BasicLibraryService; + +import org.jruby.puma.Http11; +import org.jruby.puma.MiniSSL; + +public class PumaHttp11Service implements BasicLibraryService { + public boolean basicLoad(final Ruby runtime) throws IOException { + Http11.createHttp11(runtime); + MiniSSL.createMiniSSL(runtime); + return true; + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/ext_help.h b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/ext_help.h new file mode 100644 index 00000000..ba09e6dc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/ext_help.h @@ -0,0 +1,15 @@ +#ifndef ext_help_h +#define ext_help_h + +#define RAISE_NOT_NULL(T) if(T == NULL) rb_raise(rb_eArgError, "%s", "NULL found for " # T " when shouldn't be."); +#define DATA_GET(from,type,data_type,name) TypedData_Get_Struct(from,type,data_type,name); RAISE_NOT_NULL(name); +#define REQUIRE_TYPE(V, T) if(TYPE(V) != T) rb_raise(rb_eTypeError, "%s", "Wrong argument type for " # V " required " # T); +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +#ifdef DEBUG +#define TRACE() fprintf(stderr, "> %s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__) +#else +#define TRACE() +#endif + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/extconf.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/extconf.rb new file mode 100644 index 00000000..5748647f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/extconf.rb @@ -0,0 +1,80 @@ +require 'mkmf' + +dir_config("puma_http11") + +if $mingw + append_cflags '-fstack-protector-strong -D_FORTIFY_SOURCE=2' + append_ldflags '-fstack-protector-strong -l:libssp.a' + have_library 'ssp' +end + +unless ENV["PUMA_DISABLE_SSL"] + # don't use pkg_config('openssl') if '--with-openssl-dir' is used + has_openssl_dir = dir_config('openssl').any? || + RbConfig::CONFIG['configure_args']&.include?('openssl') + + found_pkg_config = !has_openssl_dir && pkg_config('openssl') + + found_ssl = if !$mingw && found_pkg_config + puts '──── Using OpenSSL pkgconfig (openssl.pc) ────' + true + elsif have_library('libcrypto', 'BIO_read') && have_library('libssl', 'SSL_CTX_new') + true + elsif %w'crypto libeay32'.find {|crypto| have_library(crypto, 'BIO_read')} && + %w'ssl ssleay32'.find {|ssl| have_library(ssl, 'SSL_CTX_new')} + true + else + puts '** Puma will be compiled without SSL support' + false + end + + if found_ssl + have_header "openssl/bio.h" + + ssl_h = "openssl/ssl.h".freeze + + puts "\n──── Below are yes for 1.0.2 & later ────" + have_func "DTLS_method" , ssl_h + have_func "SSL_CTX_set_session_cache_mode(NULL, 0)", ssl_h + + puts "\n──── Below are yes for 1.1.0 & later ────" + have_func "TLS_server_method" , ssl_h + have_func "SSL_CTX_set_min_proto_version(NULL, 0)" , ssl_h + + puts "\n──── Below is yes for 1.1.0 and later, but isn't documented until 3.0.0 ────" + # https://github.com/openssl/openssl/blob/OpenSSL_1_1_0/include/openssl/ssl.h#L1159 + have_func "SSL_CTX_set_dh_auto(NULL, 0)" , ssl_h + + puts "\n──── Below is yes for 1.1.1 & later ────" + have_func "SSL_CTX_set_ciphersuites(NULL, \"\")" , ssl_h + + puts "\n──── Below is yes for 3.0.0 & later ────" + have_func "SSL_get1_peer_certificate" , ssl_h + + puts '' + + # Random.bytes available in Ruby 2.5 and later, Random::DEFAULT deprecated in 3.0 + if Random.respond_to?(:bytes) + $defs.push "-DHAVE_RANDOM_BYTES" + puts "checking for Random.bytes... yes" + else + puts "checking for Random.bytes... no" + end + end +end + +if ENV["PUMA_MAKE_WARNINGS_INTO_ERRORS"] + # Make all warnings into errors + # Except `implicit-fallthrough` since most failures comes from ragel state machine generated code + if respond_to?(:append_cflags, true) # Ruby 2.5 and later + append_cflags(config_string('WERRORFLAG') || '-Werror') + append_cflags '-Wno-implicit-fallthrough' + else + # flag may not exist on some platforms, -Werror may not be defined on some platforms, but + # works with all in current CI + $CFLAGS << " #{config_string('WERRORFLAG') || '-Werror'}" + $CFLAGS << ' -Wno-implicit-fallthrough' + end +end + +create_makefile("puma/puma_http11") diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/http11_parser.c b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/http11_parser.c new file mode 100644 index 00000000..388a098f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/http11_parser.c @@ -0,0 +1,1057 @@ + +#line 1 "ext/puma_http11/http11_parser.rl" +/** + * Copyright (c) 2005 Zed A. Shaw + * You can redistribute it and/or modify it under the same terms as Ruby. + * License 3-clause BSD + */ +#include "http11_parser.h" +#include +#include +#include +#include +#include + +/* + * capitalizes all lower-case ASCII characters, + * converts dashes to underscores, and underscores to commas. + */ +static void snake_upcase_char(char *c) +{ + if (*c >= 'a' && *c <= 'z') + *c &= ~0x20; + else if (*c == '_') + *c = ','; + else if (*c == '-') + *c = '_'; +} + +#define LEN(AT, FPC) (FPC - buffer - parser->AT) +#define MARK(M,FPC) (parser->M = (FPC) - buffer) +#define PTR_TO(F) (buffer + parser->F) + +/** Machine **/ + + +#line 81 "ext/puma_http11/http11_parser.rl" + + +/** Data **/ + +#line 42 "ext/puma_http11/http11_parser.c" +static const int puma_parser_start = 1; +static const int puma_parser_first_final = 46; +static const int puma_parser_error = 0; + + +#line 85 "ext/puma_http11/http11_parser.rl" + +int puma_parser_init(puma_parser *parser) { + int cs = 0; + +#line 53 "ext/puma_http11/http11_parser.c" + { + cs = puma_parser_start; + } + +#line 89 "ext/puma_http11/http11_parser.rl" + parser->cs = cs; + parser->body_start = 0; + parser->content_len = 0; + parser->mark = 0; + parser->nread = 0; + parser->field_len = 0; + parser->field_start = 0; + parser->request = Qnil; + parser->body = Qnil; + + return 1; +} + + +/** exec **/ +size_t puma_parser_execute(puma_parser *parser, const char *buffer, size_t len, size_t off) { + const char *p, *pe; + int cs = parser->cs; + + assert(off <= len && "offset past end of buffer"); + + p = buffer+off; + pe = buffer+len; + + /* assert(*pe == '\0' && "pointer does not end on NUL"); */ + assert((size_t) (pe - p) == len - off && "pointers aren't same distance"); + + +#line 87 "ext/puma_http11/http11_parser.c" + { + if ( p == pe ) + goto _test_eof; + switch ( cs ) + { +case 1: + switch( (*p) ) { + case 36: goto tr0; + case 95: goto tr0; + } + if ( (*p) < 48 ) { + if ( 45 <= (*p) && (*p) <= 46 ) + goto tr0; + } else if ( (*p) > 57 ) { + if ( 65 <= (*p) && (*p) <= 90 ) + goto tr0; + } else + goto tr0; + goto st0; +st0: +cs = 0; + goto _out; +tr0: +#line 37 "ext/puma_http11/http11_parser.rl" + { MARK(mark, p); } + goto st2; +st2: + if ( ++p == pe ) + goto _test_eof2; +case 2: +#line 118 "ext/puma_http11/http11_parser.c" + switch( (*p) ) { + case 32: goto tr2; + case 36: goto st27; + case 95: goto st27; + } + if ( (*p) < 48 ) { + if ( 45 <= (*p) && (*p) <= 46 ) + goto st27; + } else if ( (*p) > 57 ) { + if ( 65 <= (*p) && (*p) <= 90 ) + goto st27; + } else + goto st27; + goto st0; +tr2: +#line 50 "ext/puma_http11/http11_parser.rl" + { + parser->request_method(parser, PTR_TO(mark), LEN(mark, p)); + } + goto st3; +st3: + if ( ++p == pe ) + goto _test_eof3; +case 3: +#line 143 "ext/puma_http11/http11_parser.c" + switch( (*p) ) { + case 42: goto tr4; + case 43: goto tr5; + case 47: goto tr6; + case 58: goto tr7; + } + if ( (*p) < 65 ) { + if ( 45 <= (*p) && (*p) <= 57 ) + goto tr5; + } else if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto tr5; + } else + goto tr5; + goto st0; +tr4: +#line 37 "ext/puma_http11/http11_parser.rl" + { MARK(mark, p); } + goto st4; +st4: + if ( ++p == pe ) + goto _test_eof4; +case 4: +#line 167 "ext/puma_http11/http11_parser.c" + switch( (*p) ) { + case 32: goto tr8; + case 35: goto tr9; + } + goto st0; +tr8: +#line 53 "ext/puma_http11/http11_parser.rl" + { + parser->request_uri(parser, PTR_TO(mark), LEN(mark, p)); + } + goto st5; +tr31: +#line 37 "ext/puma_http11/http11_parser.rl" + { MARK(mark, p); } +#line 56 "ext/puma_http11/http11_parser.rl" + { + parser->fragment(parser, PTR_TO(mark), LEN(mark, p)); + } + goto st5; +tr33: +#line 56 "ext/puma_http11/http11_parser.rl" + { + parser->fragment(parser, PTR_TO(mark), LEN(mark, p)); + } + goto st5; +tr37: +#line 69 "ext/puma_http11/http11_parser.rl" + { + parser->request_path(parser, PTR_TO(mark), LEN(mark,p)); + } +#line 53 "ext/puma_http11/http11_parser.rl" + { + parser->request_uri(parser, PTR_TO(mark), LEN(mark, p)); + } + goto st5; +tr41: +#line 60 "ext/puma_http11/http11_parser.rl" + { MARK(query_start, p); } +#line 61 "ext/puma_http11/http11_parser.rl" + { + parser->query_string(parser, PTR_TO(query_start), LEN(query_start, p)); + } +#line 53 "ext/puma_http11/http11_parser.rl" + { + parser->request_uri(parser, PTR_TO(mark), LEN(mark, p)); + } + goto st5; +tr44: +#line 61 "ext/puma_http11/http11_parser.rl" + { + parser->query_string(parser, PTR_TO(query_start), LEN(query_start, p)); + } +#line 53 "ext/puma_http11/http11_parser.rl" + { + parser->request_uri(parser, PTR_TO(mark), LEN(mark, p)); + } + goto st5; +st5: + if ( ++p == pe ) + goto _test_eof5; +case 5: +#line 229 "ext/puma_http11/http11_parser.c" + if ( (*p) == 72 ) + goto tr10; + goto st0; +tr10: +#line 37 "ext/puma_http11/http11_parser.rl" + { MARK(mark, p); } + goto st6; +st6: + if ( ++p == pe ) + goto _test_eof6; +case 6: +#line 241 "ext/puma_http11/http11_parser.c" + if ( (*p) == 84 ) + goto st7; + goto st0; +st7: + if ( ++p == pe ) + goto _test_eof7; +case 7: + if ( (*p) == 84 ) + goto st8; + goto st0; +st8: + if ( ++p == pe ) + goto _test_eof8; +case 8: + if ( (*p) == 80 ) + goto st9; + goto st0; +st9: + if ( ++p == pe ) + goto _test_eof9; +case 9: + if ( (*p) == 47 ) + goto st10; + goto st0; +st10: + if ( ++p == pe ) + goto _test_eof10; +case 10: + if ( 48 <= (*p) && (*p) <= 57 ) + goto st11; + goto st0; +st11: + if ( ++p == pe ) + goto _test_eof11; +case 11: + if ( (*p) == 46 ) + goto st12; + if ( 48 <= (*p) && (*p) <= 57 ) + goto st11; + goto st0; +st12: + if ( ++p == pe ) + goto _test_eof12; +case 12: + if ( 48 <= (*p) && (*p) <= 57 ) + goto st13; + goto st0; +st13: + if ( ++p == pe ) + goto _test_eof13; +case 13: + if ( (*p) == 13 ) + goto tr18; + if ( 48 <= (*p) && (*p) <= 57 ) + goto st13; + goto st0; +tr18: +#line 65 "ext/puma_http11/http11_parser.rl" + { + parser->server_protocol(parser, PTR_TO(mark), LEN(mark, p)); + } + goto st14; +tr26: +#line 46 "ext/puma_http11/http11_parser.rl" + { MARK(mark, p); } +#line 47 "ext/puma_http11/http11_parser.rl" + { + parser->http_field(parser, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, p)); + } + goto st14; +tr29: +#line 47 "ext/puma_http11/http11_parser.rl" + { + parser->http_field(parser, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, p)); + } + goto st14; +st14: + if ( ++p == pe ) + goto _test_eof14; +case 14: +#line 322 "ext/puma_http11/http11_parser.c" + if ( (*p) == 10 ) + goto st15; + goto st0; +st15: + if ( ++p == pe ) + goto _test_eof15; +case 15: + switch( (*p) ) { + case 13: goto st16; + case 33: goto tr21; + case 124: goto tr21; + case 126: goto tr21; + } + if ( (*p) < 45 ) { + if ( (*p) > 39 ) { + if ( 42 <= (*p) && (*p) <= 43 ) + goto tr21; + } else if ( (*p) >= 35 ) + goto tr21; + } else if ( (*p) > 46 ) { + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr21; + } else if ( (*p) > 90 ) { + if ( 94 <= (*p) && (*p) <= 122 ) + goto tr21; + } else + goto tr21; + } else + goto tr21; + goto st0; +st16: + if ( ++p == pe ) + goto _test_eof16; +case 16: + if ( (*p) == 10 ) + goto tr22; + goto st0; +tr22: +#line 73 "ext/puma_http11/http11_parser.rl" + { + parser->body_start = p - buffer + 1; + parser->header_done(parser, p + 1, pe - p - 1); + {p++; cs = 46; goto _out;} + } + goto st46; +st46: + if ( ++p == pe ) + goto _test_eof46; +case 46: +#line 373 "ext/puma_http11/http11_parser.c" + goto st0; +tr21: +#line 40 "ext/puma_http11/http11_parser.rl" + { MARK(field_start, p); } +#line 41 "ext/puma_http11/http11_parser.rl" + { snake_upcase_char((char *)p); } + goto st17; +tr23: +#line 41 "ext/puma_http11/http11_parser.rl" + { snake_upcase_char((char *)p); } + goto st17; +st17: + if ( ++p == pe ) + goto _test_eof17; +case 17: +#line 389 "ext/puma_http11/http11_parser.c" + switch( (*p) ) { + case 33: goto tr23; + case 58: goto tr24; + case 124: goto tr23; + case 126: goto tr23; + } + if ( (*p) < 45 ) { + if ( (*p) > 39 ) { + if ( 42 <= (*p) && (*p) <= 43 ) + goto tr23; + } else if ( (*p) >= 35 ) + goto tr23; + } else if ( (*p) > 46 ) { + if ( (*p) < 65 ) { + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr23; + } else if ( (*p) > 90 ) { + if ( 94 <= (*p) && (*p) <= 122 ) + goto tr23; + } else + goto tr23; + } else + goto tr23; + goto st0; +tr24: +#line 42 "ext/puma_http11/http11_parser.rl" + { + parser->field_len = LEN(field_start, p); + } + goto st18; +tr27: +#line 46 "ext/puma_http11/http11_parser.rl" + { MARK(mark, p); } + goto st18; +st18: + if ( ++p == pe ) + goto _test_eof18; +case 18: +#line 428 "ext/puma_http11/http11_parser.c" + switch( (*p) ) { + case 13: goto tr26; + case 32: goto tr27; + case 127: goto st0; + } + if ( (*p) > 8 ) { + if ( 10 <= (*p) && (*p) <= 31 ) + goto st0; + } else if ( (*p) >= 0 ) + goto st0; + goto tr25; +tr25: +#line 46 "ext/puma_http11/http11_parser.rl" + { MARK(mark, p); } + goto st19; +st19: + if ( ++p == pe ) + goto _test_eof19; +case 19: +#line 448 "ext/puma_http11/http11_parser.c" + switch( (*p) ) { + case 13: goto tr29; + case 127: goto st0; + } + if ( (*p) > 8 ) { + if ( 10 <= (*p) && (*p) <= 31 ) + goto st0; + } else if ( (*p) >= 0 ) + goto st0; + goto st19; +tr9: +#line 53 "ext/puma_http11/http11_parser.rl" + { + parser->request_uri(parser, PTR_TO(mark), LEN(mark, p)); + } + goto st20; +tr38: +#line 69 "ext/puma_http11/http11_parser.rl" + { + parser->request_path(parser, PTR_TO(mark), LEN(mark,p)); + } +#line 53 "ext/puma_http11/http11_parser.rl" + { + parser->request_uri(parser, PTR_TO(mark), LEN(mark, p)); + } + goto st20; +tr42: +#line 60 "ext/puma_http11/http11_parser.rl" + { MARK(query_start, p); } +#line 61 "ext/puma_http11/http11_parser.rl" + { + parser->query_string(parser, PTR_TO(query_start), LEN(query_start, p)); + } +#line 53 "ext/puma_http11/http11_parser.rl" + { + parser->request_uri(parser, PTR_TO(mark), LEN(mark, p)); + } + goto st20; +tr45: +#line 61 "ext/puma_http11/http11_parser.rl" + { + parser->query_string(parser, PTR_TO(query_start), LEN(query_start, p)); + } +#line 53 "ext/puma_http11/http11_parser.rl" + { + parser->request_uri(parser, PTR_TO(mark), LEN(mark, p)); + } + goto st20; +st20: + if ( ++p == pe ) + goto _test_eof20; +case 20: +#line 501 "ext/puma_http11/http11_parser.c" + switch( (*p) ) { + case 32: goto tr31; + case 60: goto st0; + case 62: goto st0; + case 127: goto st0; + } + if ( (*p) > 31 ) { + if ( 34 <= (*p) && (*p) <= 35 ) + goto st0; + } else if ( (*p) >= 0 ) + goto st0; + goto tr30; +tr30: +#line 37 "ext/puma_http11/http11_parser.rl" + { MARK(mark, p); } + goto st21; +st21: + if ( ++p == pe ) + goto _test_eof21; +case 21: +#line 522 "ext/puma_http11/http11_parser.c" + switch( (*p) ) { + case 32: goto tr33; + case 60: goto st0; + case 62: goto st0; + case 127: goto st0; + } + if ( (*p) > 31 ) { + if ( 34 <= (*p) && (*p) <= 35 ) + goto st0; + } else if ( (*p) >= 0 ) + goto st0; + goto st21; +tr5: +#line 37 "ext/puma_http11/http11_parser.rl" + { MARK(mark, p); } + goto st22; +st22: + if ( ++p == pe ) + goto _test_eof22; +case 22: +#line 543 "ext/puma_http11/http11_parser.c" + switch( (*p) ) { + case 43: goto st22; + case 58: goto st23; + } + if ( (*p) < 48 ) { + if ( 45 <= (*p) && (*p) <= 46 ) + goto st22; + } else if ( (*p) > 57 ) { + if ( (*p) > 90 ) { + if ( 97 <= (*p) && (*p) <= 122 ) + goto st22; + } else if ( (*p) >= 65 ) + goto st22; + } else + goto st22; + goto st0; +tr7: +#line 37 "ext/puma_http11/http11_parser.rl" + { MARK(mark, p); } + goto st23; +st23: + if ( ++p == pe ) + goto _test_eof23; +case 23: +#line 568 "ext/puma_http11/http11_parser.c" + switch( (*p) ) { + case 32: goto tr8; + case 34: goto st0; + case 35: goto tr9; + case 60: goto st0; + case 62: goto st0; + case 127: goto st0; + } + if ( 0 <= (*p) && (*p) <= 31 ) + goto st0; + goto st23; +tr6: +#line 37 "ext/puma_http11/http11_parser.rl" + { MARK(mark, p); } + goto st24; +st24: + if ( ++p == pe ) + goto _test_eof24; +case 24: +#line 588 "ext/puma_http11/http11_parser.c" + switch( (*p) ) { + case 32: goto tr37; + case 34: goto st0; + case 35: goto tr38; + case 60: goto st0; + case 62: goto st0; + case 63: goto tr39; + case 127: goto st0; + } + if ( 0 <= (*p) && (*p) <= 31 ) + goto st0; + goto st24; +tr39: +#line 69 "ext/puma_http11/http11_parser.rl" + { + parser->request_path(parser, PTR_TO(mark), LEN(mark,p)); + } + goto st25; +st25: + if ( ++p == pe ) + goto _test_eof25; +case 25: +#line 611 "ext/puma_http11/http11_parser.c" + switch( (*p) ) { + case 32: goto tr41; + case 34: goto st0; + case 35: goto tr42; + case 60: goto st0; + case 62: goto st0; + case 127: goto st0; + } + if ( 0 <= (*p) && (*p) <= 31 ) + goto st0; + goto tr40; +tr40: +#line 60 "ext/puma_http11/http11_parser.rl" + { MARK(query_start, p); } + goto st26; +st26: + if ( ++p == pe ) + goto _test_eof26; +case 26: +#line 631 "ext/puma_http11/http11_parser.c" + switch( (*p) ) { + case 32: goto tr44; + case 34: goto st0; + case 35: goto tr45; + case 60: goto st0; + case 62: goto st0; + case 127: goto st0; + } + if ( 0 <= (*p) && (*p) <= 31 ) + goto st0; + goto st26; +st27: + if ( ++p == pe ) + goto _test_eof27; +case 27: + switch( (*p) ) { + case 32: goto tr2; + case 36: goto st28; + case 95: goto st28; + } + if ( (*p) < 48 ) { + if ( 45 <= (*p) && (*p) <= 46 ) + goto st28; + } else if ( (*p) > 57 ) { + if ( 65 <= (*p) && (*p) <= 90 ) + goto st28; + } else + goto st28; + goto st0; +st28: + if ( ++p == pe ) + goto _test_eof28; +case 28: + switch( (*p) ) { + case 32: goto tr2; + case 36: goto st29; + case 95: goto st29; + } + if ( (*p) < 48 ) { + if ( 45 <= (*p) && (*p) <= 46 ) + goto st29; + } else if ( (*p) > 57 ) { + if ( 65 <= (*p) && (*p) <= 90 ) + goto st29; + } else + goto st29; + goto st0; +st29: + if ( ++p == pe ) + goto _test_eof29; +case 29: + switch( (*p) ) { + case 32: goto tr2; + case 36: goto st30; + case 95: goto st30; + } + if ( (*p) < 48 ) { + if ( 45 <= (*p) && (*p) <= 46 ) + goto st30; + } else if ( (*p) > 57 ) { + if ( 65 <= (*p) && (*p) <= 90 ) + goto st30; + } else + goto st30; + goto st0; +st30: + if ( ++p == pe ) + goto _test_eof30; +case 30: + switch( (*p) ) { + case 32: goto tr2; + case 36: goto st31; + case 95: goto st31; + } + if ( (*p) < 48 ) { + if ( 45 <= (*p) && (*p) <= 46 ) + goto st31; + } else if ( (*p) > 57 ) { + if ( 65 <= (*p) && (*p) <= 90 ) + goto st31; + } else + goto st31; + goto st0; +st31: + if ( ++p == pe ) + goto _test_eof31; +case 31: + switch( (*p) ) { + case 32: goto tr2; + case 36: goto st32; + case 95: goto st32; + } + if ( (*p) < 48 ) { + if ( 45 <= (*p) && (*p) <= 46 ) + goto st32; + } else if ( (*p) > 57 ) { + if ( 65 <= (*p) && (*p) <= 90 ) + goto st32; + } else + goto st32; + goto st0; +st32: + if ( ++p == pe ) + goto _test_eof32; +case 32: + switch( (*p) ) { + case 32: goto tr2; + case 36: goto st33; + case 95: goto st33; + } + if ( (*p) < 48 ) { + if ( 45 <= (*p) && (*p) <= 46 ) + goto st33; + } else if ( (*p) > 57 ) { + if ( 65 <= (*p) && (*p) <= 90 ) + goto st33; + } else + goto st33; + goto st0; +st33: + if ( ++p == pe ) + goto _test_eof33; +case 33: + switch( (*p) ) { + case 32: goto tr2; + case 36: goto st34; + case 95: goto st34; + } + if ( (*p) < 48 ) { + if ( 45 <= (*p) && (*p) <= 46 ) + goto st34; + } else if ( (*p) > 57 ) { + if ( 65 <= (*p) && (*p) <= 90 ) + goto st34; + } else + goto st34; + goto st0; +st34: + if ( ++p == pe ) + goto _test_eof34; +case 34: + switch( (*p) ) { + case 32: goto tr2; + case 36: goto st35; + case 95: goto st35; + } + if ( (*p) < 48 ) { + if ( 45 <= (*p) && (*p) <= 46 ) + goto st35; + } else if ( (*p) > 57 ) { + if ( 65 <= (*p) && (*p) <= 90 ) + goto st35; + } else + goto st35; + goto st0; +st35: + if ( ++p == pe ) + goto _test_eof35; +case 35: + switch( (*p) ) { + case 32: goto tr2; + case 36: goto st36; + case 95: goto st36; + } + if ( (*p) < 48 ) { + if ( 45 <= (*p) && (*p) <= 46 ) + goto st36; + } else if ( (*p) > 57 ) { + if ( 65 <= (*p) && (*p) <= 90 ) + goto st36; + } else + goto st36; + goto st0; +st36: + if ( ++p == pe ) + goto _test_eof36; +case 36: + switch( (*p) ) { + case 32: goto tr2; + case 36: goto st37; + case 95: goto st37; + } + if ( (*p) < 48 ) { + if ( 45 <= (*p) && (*p) <= 46 ) + goto st37; + } else if ( (*p) > 57 ) { + if ( 65 <= (*p) && (*p) <= 90 ) + goto st37; + } else + goto st37; + goto st0; +st37: + if ( ++p == pe ) + goto _test_eof37; +case 37: + switch( (*p) ) { + case 32: goto tr2; + case 36: goto st38; + case 95: goto st38; + } + if ( (*p) < 48 ) { + if ( 45 <= (*p) && (*p) <= 46 ) + goto st38; + } else if ( (*p) > 57 ) { + if ( 65 <= (*p) && (*p) <= 90 ) + goto st38; + } else + goto st38; + goto st0; +st38: + if ( ++p == pe ) + goto _test_eof38; +case 38: + switch( (*p) ) { + case 32: goto tr2; + case 36: goto st39; + case 95: goto st39; + } + if ( (*p) < 48 ) { + if ( 45 <= (*p) && (*p) <= 46 ) + goto st39; + } else if ( (*p) > 57 ) { + if ( 65 <= (*p) && (*p) <= 90 ) + goto st39; + } else + goto st39; + goto st0; +st39: + if ( ++p == pe ) + goto _test_eof39; +case 39: + switch( (*p) ) { + case 32: goto tr2; + case 36: goto st40; + case 95: goto st40; + } + if ( (*p) < 48 ) { + if ( 45 <= (*p) && (*p) <= 46 ) + goto st40; + } else if ( (*p) > 57 ) { + if ( 65 <= (*p) && (*p) <= 90 ) + goto st40; + } else + goto st40; + goto st0; +st40: + if ( ++p == pe ) + goto _test_eof40; +case 40: + switch( (*p) ) { + case 32: goto tr2; + case 36: goto st41; + case 95: goto st41; + } + if ( (*p) < 48 ) { + if ( 45 <= (*p) && (*p) <= 46 ) + goto st41; + } else if ( (*p) > 57 ) { + if ( 65 <= (*p) && (*p) <= 90 ) + goto st41; + } else + goto st41; + goto st0; +st41: + if ( ++p == pe ) + goto _test_eof41; +case 41: + switch( (*p) ) { + case 32: goto tr2; + case 36: goto st42; + case 95: goto st42; + } + if ( (*p) < 48 ) { + if ( 45 <= (*p) && (*p) <= 46 ) + goto st42; + } else if ( (*p) > 57 ) { + if ( 65 <= (*p) && (*p) <= 90 ) + goto st42; + } else + goto st42; + goto st0; +st42: + if ( ++p == pe ) + goto _test_eof42; +case 42: + switch( (*p) ) { + case 32: goto tr2; + case 36: goto st43; + case 95: goto st43; + } + if ( (*p) < 48 ) { + if ( 45 <= (*p) && (*p) <= 46 ) + goto st43; + } else if ( (*p) > 57 ) { + if ( 65 <= (*p) && (*p) <= 90 ) + goto st43; + } else + goto st43; + goto st0; +st43: + if ( ++p == pe ) + goto _test_eof43; +case 43: + switch( (*p) ) { + case 32: goto tr2; + case 36: goto st44; + case 95: goto st44; + } + if ( (*p) < 48 ) { + if ( 45 <= (*p) && (*p) <= 46 ) + goto st44; + } else if ( (*p) > 57 ) { + if ( 65 <= (*p) && (*p) <= 90 ) + goto st44; + } else + goto st44; + goto st0; +st44: + if ( ++p == pe ) + goto _test_eof44; +case 44: + switch( (*p) ) { + case 32: goto tr2; + case 36: goto st45; + case 95: goto st45; + } + if ( (*p) < 48 ) { + if ( 45 <= (*p) && (*p) <= 46 ) + goto st45; + } else if ( (*p) > 57 ) { + if ( 65 <= (*p) && (*p) <= 90 ) + goto st45; + } else + goto st45; + goto st0; +st45: + if ( ++p == pe ) + goto _test_eof45; +case 45: + if ( (*p) == 32 ) + goto tr2; + goto st0; + } + _test_eof2: cs = 2; goto _test_eof; + _test_eof3: cs = 3; goto _test_eof; + _test_eof4: cs = 4; goto _test_eof; + _test_eof5: cs = 5; goto _test_eof; + _test_eof6: cs = 6; goto _test_eof; + _test_eof7: cs = 7; goto _test_eof; + _test_eof8: cs = 8; goto _test_eof; + _test_eof9: cs = 9; goto _test_eof; + _test_eof10: cs = 10; goto _test_eof; + _test_eof11: cs = 11; goto _test_eof; + _test_eof12: cs = 12; goto _test_eof; + _test_eof13: cs = 13; goto _test_eof; + _test_eof14: cs = 14; goto _test_eof; + _test_eof15: cs = 15; goto _test_eof; + _test_eof16: cs = 16; goto _test_eof; + _test_eof46: cs = 46; goto _test_eof; + _test_eof17: cs = 17; goto _test_eof; + _test_eof18: cs = 18; goto _test_eof; + _test_eof19: cs = 19; goto _test_eof; + _test_eof20: cs = 20; goto _test_eof; + _test_eof21: cs = 21; goto _test_eof; + _test_eof22: cs = 22; goto _test_eof; + _test_eof23: cs = 23; goto _test_eof; + _test_eof24: cs = 24; goto _test_eof; + _test_eof25: cs = 25; goto _test_eof; + _test_eof26: cs = 26; goto _test_eof; + _test_eof27: cs = 27; goto _test_eof; + _test_eof28: cs = 28; goto _test_eof; + _test_eof29: cs = 29; goto _test_eof; + _test_eof30: cs = 30; goto _test_eof; + _test_eof31: cs = 31; goto _test_eof; + _test_eof32: cs = 32; goto _test_eof; + _test_eof33: cs = 33; goto _test_eof; + _test_eof34: cs = 34; goto _test_eof; + _test_eof35: cs = 35; goto _test_eof; + _test_eof36: cs = 36; goto _test_eof; + _test_eof37: cs = 37; goto _test_eof; + _test_eof38: cs = 38; goto _test_eof; + _test_eof39: cs = 39; goto _test_eof; + _test_eof40: cs = 40; goto _test_eof; + _test_eof41: cs = 41; goto _test_eof; + _test_eof42: cs = 42; goto _test_eof; + _test_eof43: cs = 43; goto _test_eof; + _test_eof44: cs = 44; goto _test_eof; + _test_eof45: cs = 45; goto _test_eof; + + _test_eof: {} + _out: {} + } + +#line 117 "ext/puma_http11/http11_parser.rl" + + if (!puma_parser_has_error(parser)) + parser->cs = cs; + parser->nread += p - (buffer + off); + + assert(p <= pe && "buffer overflow after parsing execute"); + assert(parser->nread <= len && "nread longer than length"); + assert(parser->body_start <= len && "body starts after buffer end"); + assert(parser->mark < len && "mark is after buffer end"); + assert(parser->field_len <= len && "field has length longer than whole buffer"); + assert(parser->field_start < len && "field starts after buffer end"); + + return(parser->nread); +} + +int puma_parser_finish(puma_parser *parser) +{ + if (puma_parser_has_error(parser) ) { + return -1; + } else if (puma_parser_is_finished(parser) ) { + return 1; + } else { + return 0; + } +} + +int puma_parser_has_error(puma_parser *parser) { + return parser->cs == puma_parser_error; +} + +int puma_parser_is_finished(puma_parser *parser) { + return parser->cs >= puma_parser_first_final; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/http11_parser.h b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/http11_parser.h new file mode 100644 index 00000000..e0545a9b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/http11_parser.h @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2005 Zed A. Shaw + * You can redistribute it and/or modify it under the same terms as Ruby. + * License 3-clause BSD + */ + +#ifndef http11_parser_h +#define http11_parser_h + +#define RSTRING_NOT_MODIFIED 1 +#include "ruby.h" + +#include + +#if defined(_WIN32) +#include +#endif + +#define BUFFER_LEN 1024 + +struct puma_parser; + +typedef void (*element_cb)(struct puma_parser* hp, + const char *at, size_t length); + +typedef void (*field_cb)(struct puma_parser* hp, + const char *field, size_t flen, + const char *value, size_t vlen); + +typedef struct puma_parser { + int cs; + int content_len; + size_t body_start; + size_t nread; + size_t mark; + size_t field_start; + size_t field_len; + size_t query_start; + + VALUE request; + VALUE body; + + field_cb http_field; + element_cb request_method; + element_cb request_uri; + element_cb fragment; + element_cb request_path; + element_cb query_string; + element_cb server_protocol; + element_cb header_done; + + char buf[BUFFER_LEN]; + +} puma_parser; + +int puma_parser_init(puma_parser *parser); +int puma_parser_finish(puma_parser *parser); +size_t puma_parser_execute(puma_parser *parser, const char *data, + size_t len, size_t off); +int puma_parser_has_error(puma_parser *parser); +int puma_parser_is_finished(puma_parser *parser); + +#define puma_parser_nread(parser) (parser)->nread + +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/http11_parser.java.rl b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/http11_parser.java.rl new file mode 100644 index 00000000..c5cb6583 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/http11_parser.java.rl @@ -0,0 +1,145 @@ +package org.jruby.puma; + +import org.jruby.Ruby; +import org.jruby.RubyHash; +import org.jruby.util.ByteList; + +public class Http11Parser { + +/** Machine **/ + +%%{ + + machine puma_parser; + + action mark {parser.mark = fpc; } + + action start_field { parser.field_start = fpc; } + action snake_upcase_field { /* FIXME stub */ } + action write_field { + parser.field_len = fpc-parser.field_start; + } + + action start_value { parser.mark = fpc; } + action write_value { + Http11.http_field(runtime, parser.data, parser.buffer, parser.field_start, parser.field_len, parser.mark, fpc-parser.mark); + } + action request_method { + Http11.request_method(runtime, parser.data, parser.buffer, parser.mark, fpc-parser.mark); + } + action request_uri { + Http11.request_uri(runtime, parser.data, parser.buffer, parser.mark, fpc-parser.mark); + } + action fragment { + Http11.fragment(runtime, parser.data, parser.buffer, parser.mark, fpc-parser.mark); + } + + action start_query {parser.query_start = fpc; } + action query_string { + Http11.query_string(runtime, parser.data, parser.buffer, parser.query_start, fpc-parser.query_start); + } + + action server_protocol { + Http11.server_protocol(runtime, parser.data, parser.buffer, parser.mark, fpc-parser.mark); + } + + action request_path { + Http11.request_path(runtime, parser.data, parser.buffer, parser.mark, fpc-parser.mark); + } + + action done { + parser.body_start = fpc + 1; + http.header_done(runtime, parser.data, parser.buffer, fpc + 1, pe - fpc - 1); + fbreak; + } + + include puma_parser_common "http11_parser_common.rl"; + +}%% + +/** Data **/ +%% write data noentry; + + public static interface ElementCB { + public void call(Ruby runtime, RubyHash data, ByteList buffer, int at, int length); + } + + public static interface FieldCB { + public void call(Ruby runtime, RubyHash data, ByteList buffer, int field, int flen, int value, int vlen); + } + + public static class HttpParser { + int cs; + int body_start; + int content_len; + int nread; + int mark; + int field_start; + int field_len; + int query_start; + + RubyHash data; + ByteList buffer; + + public void init() { + cs = 0; + + %% write init; + + body_start = 0; + content_len = 0; + mark = 0; + nread = 0; + field_len = 0; + field_start = 0; + } + } + + public final HttpParser parser = new HttpParser(); + + public int execute(Ruby runtime, Http11 http, ByteList buffer, int off) { + int p, pe; + int cs = parser.cs; + int len = buffer.length(); + assert off<=len : "offset past end of buffer"; + + p = off; + pe = len; + // get a copy of the bytes, since it may not start at 0 + // FIXME: figure out how to just use the bytes in-place + byte[] data = buffer.bytes(); + parser.buffer = buffer; + + %% write exec; + + parser.cs = cs; + parser.nread += (p - off); + + assert p <= pe : "buffer overflow after parsing execute"; + assert parser.nread <= len : "nread longer than length"; + assert parser.body_start <= len : "body starts after buffer end"; + assert parser.mark < len : "mark is after buffer end"; + assert parser.field_len <= len : "field has length longer than whole buffer"; + assert parser.field_start < len : "field starts after buffer end"; + + return parser.nread; + } + + public int finish() { + if(has_error()) { + return -1; + } else if(is_finished()) { + return 1; + } else { + return 0; + } + } + + public boolean has_error() { + return parser.cs == puma_parser_error; + } + + public boolean is_finished() { + return parser.cs == puma_parser_first_final; + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/http11_parser.rl b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/http11_parser.rl new file mode 100644 index 00000000..f1ef5a11 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/http11_parser.rl @@ -0,0 +1,149 @@ +/** + * Copyright (c) 2005 Zed A. Shaw + * You can redistribute it and/or modify it under the same terms as Ruby. + * License 3-clause BSD + */ +#include "http11_parser.h" +#include +#include +#include +#include +#include + +/* + * capitalizes all lower-case ASCII characters, + * converts dashes to underscores, and underscores to commas. + */ +static void snake_upcase_char(char *c) +{ + if (*c >= 'a' && *c <= 'z') + *c &= ~0x20; + else if (*c == '_') + *c = ','; + else if (*c == '-') + *c = '_'; +} + +#define LEN(AT, FPC) (FPC - buffer - parser->AT) +#define MARK(M,FPC) (parser->M = (FPC) - buffer) +#define PTR_TO(F) (buffer + parser->F) + +/** Machine **/ + +%%{ + + machine puma_parser; + + action mark { MARK(mark, fpc); } + + + action start_field { MARK(field_start, fpc); } + action snake_upcase_field { snake_upcase_char((char *)fpc); } + action write_field { + parser->field_len = LEN(field_start, fpc); + } + + action start_value { MARK(mark, fpc); } + action write_value { + parser->http_field(parser, PTR_TO(field_start), parser->field_len, PTR_TO(mark), LEN(mark, fpc)); + } + action request_method { + parser->request_method(parser, PTR_TO(mark), LEN(mark, fpc)); + } + action request_uri { + parser->request_uri(parser, PTR_TO(mark), LEN(mark, fpc)); + } + action fragment { + parser->fragment(parser, PTR_TO(mark), LEN(mark, fpc)); + } + + action start_query { MARK(query_start, fpc); } + action query_string { + parser->query_string(parser, PTR_TO(query_start), LEN(query_start, fpc)); + } + + action server_protocol { + parser->server_protocol(parser, PTR_TO(mark), LEN(mark, fpc)); + } + + action request_path { + parser->request_path(parser, PTR_TO(mark), LEN(mark,fpc)); + } + + action done { + parser->body_start = fpc - buffer + 1; + parser->header_done(parser, fpc + 1, pe - fpc - 1); + fbreak; + } + + include puma_parser_common "http11_parser_common.rl"; + +}%% + +/** Data **/ +%% write data noentry; + +int puma_parser_init(puma_parser *parser) { + int cs = 0; + %% write init; + parser->cs = cs; + parser->body_start = 0; + parser->content_len = 0; + parser->mark = 0; + parser->nread = 0; + parser->field_len = 0; + parser->field_start = 0; + parser->request = Qnil; + parser->body = Qnil; + + return 1; +} + + +/** exec **/ +size_t puma_parser_execute(puma_parser *parser, const char *buffer, size_t len, size_t off) { + const char *p, *pe; + int cs = parser->cs; + + assert(off <= len && "offset past end of buffer"); + + p = buffer+off; + pe = buffer+len; + + /* assert(*pe == '\0' && "pointer does not end on NUL"); */ + assert((size_t) (pe - p) == len - off && "pointers aren't same distance"); + + %% write exec; + + if (!puma_parser_has_error(parser)) + parser->cs = cs; + parser->nread += p - (buffer + off); + + assert(p <= pe && "buffer overflow after parsing execute"); + assert(parser->nread <= len && "nread longer than length"); + assert(parser->body_start <= len && "body starts after buffer end"); + assert(parser->mark < len && "mark is after buffer end"); + assert(parser->field_len <= len && "field has length longer than whole buffer"); + assert(parser->field_start < len && "field starts after buffer end"); + + return(parser->nread); +} + +int puma_parser_finish(puma_parser *parser) +{ + if (puma_parser_has_error(parser) ) { + return -1; + } else if (puma_parser_is_finished(parser) ) { + return 1; + } else { + return 0; + } +} + +int puma_parser_has_error(puma_parser *parser) { + return parser->cs == puma_parser_error; +} + +int puma_parser_is_finished(puma_parser *parser) { + return parser->cs >= puma_parser_first_final; +} diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/http11_parser_common.rl b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/http11_parser_common.rl new file mode 100644 index 00000000..d61aafa4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/http11_parser_common.rl @@ -0,0 +1,54 @@ +%%{ + + machine puma_parser_common; + +#### HTTP PROTOCOL GRAMMAR +# line endings + CRLF = "\r\n"; + +# character types + CTL = (cntrl | 127); + safe = ("$" | "-" | "_" | "."); + extra = ("!" | "*" | "'" | "(" | ")" | ","); + reserved = (";" | "/" | "?" | ":" | "@" | "&" | "=" | "+"); + unsafe = (CTL | " " | "\"" | "#" | "%" | "<" | ">"); + national = any -- (alpha | digit | reserved | extra | safe | unsafe); + unreserved = (alpha | digit | safe | extra | national); + escape = ("%" xdigit xdigit); + uchar = (unreserved | escape | "%"); + pchar = (uchar | ":" | "@" | "&" | "=" | "+" | ";"); + tspecials = ("(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\\" | "\"" | "/" | "[" | "]" | "?" | "=" | "{" | "}" | " " | "\t"); + +# elements + token = (ascii -- (CTL | tspecials)); + +# URI schemes and absolute paths + scheme = ( alpha | digit | "+" | "-" | "." )* ; + absolute_uri = (scheme ":" (uchar | reserved )*); + + path = ( pchar+ ( "/" pchar* )* ) ; + query = ( uchar | reserved )* %query_string ; + param = ( pchar | "/" )* ; + params = ( param ( ";" param )* ) ; + rel_path = ( path? %request_path ) ("?" %start_query query)?; + absolute_path = ( "/"+ rel_path ); + + Request_URI = ( "*" | absolute_uri | absolute_path ) >mark %request_uri; + Fragment = ( uchar | reserved )* >mark %fragment; + Method = ( upper | digit | safe ){1,20} >mark %request_method; + + http_number = ( digit+ "." digit+ ) ; + Server_Protocol = ( "HTTP/" http_number ) >mark %server_protocol ; + Request_Line = ( Method " " Request_URI ("#" Fragment){0,1} " " Server_Protocol CRLF ) ; + + field_name = ( token -- ":" )+ >start_field $snake_upcase_field %write_field; + + field_value = ( (any -- CTL) | "\t" )* >start_value %write_value; + + message_header = field_name ":" " "* field_value :> CRLF; + + Request = Request_Line ( message_header )* ( CRLF @done ); + +main := Request; + +}%% diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/mini_ssl.c b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/mini_ssl.c new file mode 100644 index 00000000..dc5a77fe --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/mini_ssl.c @@ -0,0 +1,842 @@ +#define RSTRING_NOT_MODIFIED 1 + +#include +#include +#include + +#ifdef HAVE_OPENSSL_BIO_H + +#include +#include +#include +#include +#include + +#ifndef SSL_OP_NO_COMPRESSION +#define SSL_OP_NO_COMPRESSION 0 +#endif + +typedef struct { + BIO* read; + BIO* write; + SSL* ssl; + SSL_CTX* ctx; +} ms_conn; + +typedef struct { + unsigned char* buf; + int bytes; +} ms_cert_buf; + +VALUE eError; + +NORETURN(void raise_file_error(const char* caller, const char *filename)); + +void raise_file_error(const char* caller, const char *filename) { + rb_raise(eError, "%s: error in file '%s': %s", caller, filename, ERR_error_string(ERR_get_error(), NULL)); +} + +NORETURN(void raise_param_error(const char* caller, const char *param)); + +void raise_param_error(const char* caller, const char *param) { + rb_raise(eError, "%s: error with parameter '%s': %s", caller, param, ERR_error_string(ERR_get_error(), NULL)); +} + +void engine_free(void *ptr) { + ms_conn *conn = ptr; + ms_cert_buf* cert_buf = (ms_cert_buf*)SSL_get_app_data(conn->ssl); + if(cert_buf) { + OPENSSL_free(cert_buf->buf); + free(cert_buf); + } + SSL_free(conn->ssl); + SSL_CTX_free(conn->ctx); + + free(conn); +} + +const rb_data_type_t engine_data_type = { + "MiniSSL/ENGINE", + { 0, engine_free, 0 }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + +#ifndef HAVE_SSL_CTX_SET_DH_AUTO +DH *get_dh2048(void) { + /* `openssl dhparam -C 2048` + * -----BEGIN DH PARAMETERS----- + * MIIBCAKCAQEAjmh1uQHdTfxOyxEbKAV30fUfzqMDF/ChPzjfyzl2jcrqQMhrk76o + * 2NPNXqxHwsddMZ1RzvU8/jl+uhRuPWjXCFZbhET4N1vrviZM3VJhV8PPHuiVOACO + * y32jFd+Szx4bo2cXSK83hJ6jRd+0asP1awWjz9/06dFkrILCXMIfQLo0D8rqmppn + * EfDDAwuudCpM9kcDmBRAm9JsKbQ6gzZWjkc5+QWSaQofojIHbjvj3xzguaCJn+oQ + * vHWM+hsAnaOgEwCyeZ3xqs+/5lwSbkE/tqJW98cEZGygBUVo9jxZRZx6KOfjpdrb + * yenO9LJr/qtyrZB31WJbqxI0m0AKTAO8UwIBAg== + * -----END DH PARAMETERS----- + */ + static unsigned char dh2048_p[] = { + 0x8E, 0x68, 0x75, 0xB9, 0x01, 0xDD, 0x4D, 0xFC, 0x4E, 0xCB, + 0x11, 0x1B, 0x28, 0x05, 0x77, 0xD1, 0xF5, 0x1F, 0xCE, 0xA3, + 0x03, 0x17, 0xF0, 0xA1, 0x3F, 0x38, 0xDF, 0xCB, 0x39, 0x76, + 0x8D, 0xCA, 0xEA, 0x40, 0xC8, 0x6B, 0x93, 0xBE, 0xA8, 0xD8, + 0xD3, 0xCD, 0x5E, 0xAC, 0x47, 0xC2, 0xC7, 0x5D, 0x31, 0x9D, + 0x51, 0xCE, 0xF5, 0x3C, 0xFE, 0x39, 0x7E, 0xBA, 0x14, 0x6E, + 0x3D, 0x68, 0xD7, 0x08, 0x56, 0x5B, 0x84, 0x44, 0xF8, 0x37, + 0x5B, 0xEB, 0xBE, 0x26, 0x4C, 0xDD, 0x52, 0x61, 0x57, 0xC3, + 0xCF, 0x1E, 0xE8, 0x95, 0x38, 0x00, 0x8E, 0xCB, 0x7D, 0xA3, + 0x15, 0xDF, 0x92, 0xCF, 0x1E, 0x1B, 0xA3, 0x67, 0x17, 0x48, + 0xAF, 0x37, 0x84, 0x9E, 0xA3, 0x45, 0xDF, 0xB4, 0x6A, 0xC3, + 0xF5, 0x6B, 0x05, 0xA3, 0xCF, 0xDF, 0xF4, 0xE9, 0xD1, 0x64, + 0xAC, 0x82, 0xC2, 0x5C, 0xC2, 0x1F, 0x40, 0xBA, 0x34, 0x0F, + 0xCA, 0xEA, 0x9A, 0x9A, 0x67, 0x11, 0xF0, 0xC3, 0x03, 0x0B, + 0xAE, 0x74, 0x2A, 0x4C, 0xF6, 0x47, 0x03, 0x98, 0x14, 0x40, + 0x9B, 0xD2, 0x6C, 0x29, 0xB4, 0x3A, 0x83, 0x36, 0x56, 0x8E, + 0x47, 0x39, 0xF9, 0x05, 0x92, 0x69, 0x0A, 0x1F, 0xA2, 0x32, + 0x07, 0x6E, 0x3B, 0xE3, 0xDF, 0x1C, 0xE0, 0xB9, 0xA0, 0x89, + 0x9F, 0xEA, 0x10, 0xBC, 0x75, 0x8C, 0xFA, 0x1B, 0x00, 0x9D, + 0xA3, 0xA0, 0x13, 0x00, 0xB2, 0x79, 0x9D, 0xF1, 0xAA, 0xCF, + 0xBF, 0xE6, 0x5C, 0x12, 0x6E, 0x41, 0x3F, 0xB6, 0xA2, 0x56, + 0xF7, 0xC7, 0x04, 0x64, 0x6C, 0xA0, 0x05, 0x45, 0x68, 0xF6, + 0x3C, 0x59, 0x45, 0x9C, 0x7A, 0x28, 0xE7, 0xE3, 0xA5, 0xDA, + 0xDB, 0xC9, 0xE9, 0xCE, 0xF4, 0xB2, 0x6B, 0xFE, 0xAB, 0x72, + 0xAD, 0x90, 0x77, 0xD5, 0x62, 0x5B, 0xAB, 0x12, 0x34, 0x9B, + 0x40, 0x0A, 0x4C, 0x03, 0xBC, 0x53 + }; + static unsigned char dh2048_g[] = { 0x02 }; + + DH *dh; +#if !(OPENSSL_VERSION_NUMBER < 0x10100005L) + BIGNUM *p, *g; +#endif + + dh = DH_new(); + +#if OPENSSL_VERSION_NUMBER < 0x10100005L + dh->p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL); + dh->g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL); + + if ((dh->p == NULL) || (dh->g == NULL)) { + DH_free(dh); + return NULL; + } +#else + p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL); + g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL); + + if (p == NULL || g == NULL || !DH_set0_pqg(dh, p, NULL, g)) { + DH_free(dh); + BN_free(p); + BN_free(g); + return NULL; + } +#endif + + return dh; +} +#endif + +static void +sslctx_free(void *ptr) { + SSL_CTX *ctx = ptr; + SSL_CTX_free(ctx); +} + +static const rb_data_type_t sslctx_type = { + "MiniSSL/SSLContext", + { + 0, sslctx_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + +ms_conn* engine_alloc(VALUE klass, VALUE* obj) { + ms_conn* conn; + + *obj = TypedData_Make_Struct(klass, ms_conn, &engine_data_type, conn); + + conn->read = BIO_new(BIO_s_mem()); + BIO_set_nbio(conn->read, 1); + + conn->write = BIO_new(BIO_s_mem()); + BIO_set_nbio(conn->write, 1); + + conn->ssl = 0; + conn->ctx = 0; + + return conn; +} + +static int engine_verify_callback(int preverify_ok, X509_STORE_CTX* ctx) { + X509* err_cert; + SSL* ssl; + int bytes; + unsigned char* buf = NULL; + + if(!preverify_ok) { + err_cert = X509_STORE_CTX_get_current_cert(ctx); + if(err_cert) { + /* + * Save the failed certificate for inspection/logging. + */ + bytes = i2d_X509(err_cert, &buf); + if(bytes > 0) { + ms_cert_buf* cert_buf = (ms_cert_buf*)malloc(sizeof(ms_cert_buf)); + cert_buf->buf = buf; + cert_buf->bytes = bytes; + ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); + SSL_set_app_data(ssl, cert_buf); + } + } + } + + return preverify_ok; +} + +static int password_callback(char *buf, int size, int rwflag, void *userdata) { + const char *password = (const char *) userdata; + size_t len = strlen(password); + + if (len > (size_t) size) { + return 0; + } + + memcpy(buf, password, len); + return (int) len; +} + +static VALUE +sslctx_alloc(VALUE klass) { + SSL_CTX *ctx; + long mode = 0 | + SSL_MODE_ENABLE_PARTIAL_WRITE | + SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | + SSL_MODE_RELEASE_BUFFERS; + +#ifdef HAVE_TLS_SERVER_METHOD + ctx = SSL_CTX_new(TLS_method()); + // printf("\nctx using TLS_method security_level %d\n", SSL_CTX_get_security_level(ctx)); +#else + ctx = SSL_CTX_new(SSLv23_method()); +#endif + if (!ctx) { + rb_raise(eError, "SSL_CTX_new"); + } + SSL_CTX_set_mode(ctx, mode); + + return TypedData_Wrap_Struct(klass, &sslctx_type, ctx); +} + +VALUE +sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) { + SSL_CTX* ctx; + int ssl_options; + VALUE key, cert, ca, verify_mode, ssl_cipher_filter, ssl_ciphersuites, no_tlsv1, no_tlsv1_1, + verification_flags, session_id_bytes, cert_pem, key_pem, key_password_command, key_password; + BIO *bio; + X509 *x509 = NULL; + EVP_PKEY *pkey; + pem_password_cb *password_cb = NULL; + const char *password = NULL; +#ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION + int min; +#endif +#ifndef HAVE_SSL_CTX_SET_DH_AUTO + DH *dh; +#endif +#if OPENSSL_VERSION_NUMBER < 0x10002000L + EC_KEY *ecdh; +#endif +#ifdef HAVE_SSL_CTX_SET_SESSION_CACHE_MODE + VALUE reuse, reuse_cache_size, reuse_timeout; + + reuse = rb_funcall(mini_ssl_ctx, rb_intern_const("reuse"), 0); + reuse_cache_size = rb_funcall(mini_ssl_ctx, rb_intern_const("reuse_cache_size"), 0); + reuse_timeout = rb_funcall(mini_ssl_ctx, rb_intern_const("reuse_timeout"), 0); +#endif + + key = rb_funcall(mini_ssl_ctx, rb_intern_const("key"), 0); + + key_password_command = rb_funcall(mini_ssl_ctx, rb_intern_const("key_password_command"), 0); + + cert = rb_funcall(mini_ssl_ctx, rb_intern_const("cert"), 0); + + ca = rb_funcall(mini_ssl_ctx, rb_intern_const("ca"), 0); + + cert_pem = rb_funcall(mini_ssl_ctx, rb_intern_const("cert_pem"), 0); + + key_pem = rb_funcall(mini_ssl_ctx, rb_intern_const("key_pem"), 0); + + verify_mode = rb_funcall(mini_ssl_ctx, rb_intern_const("verify_mode"), 0); + + ssl_cipher_filter = rb_funcall(mini_ssl_ctx, rb_intern_const("ssl_cipher_filter"), 0); + + ssl_ciphersuites = rb_funcall(mini_ssl_ctx, rb_intern_const("ssl_ciphersuites"), 0); + + no_tlsv1 = rb_funcall(mini_ssl_ctx, rb_intern_const("no_tlsv1"), 0); + + no_tlsv1_1 = rb_funcall(mini_ssl_ctx, rb_intern_const("no_tlsv1_1"), 0); + + TypedData_Get_Struct(self, SSL_CTX, &sslctx_type, ctx); + + if (!NIL_P(cert)) { + StringValue(cert); + + if (SSL_CTX_use_certificate_chain_file(ctx, RSTRING_PTR(cert)) != 1) { + raise_file_error("SSL_CTX_use_certificate_chain_file", RSTRING_PTR(cert)); + } + } + + if (!NIL_P(key_password_command)) { + key_password = rb_funcall(mini_ssl_ctx, rb_intern_const("key_password"), 0); + + if (!NIL_P(key_password)) { + StringValue(key_password); + password_cb = password_callback; + password = RSTRING_PTR(key_password); + SSL_CTX_set_default_passwd_cb(ctx, password_cb); + SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *) password); + } + } + + if (!NIL_P(key)) { + StringValue(key); + + if (SSL_CTX_use_PrivateKey_file(ctx, RSTRING_PTR(key), SSL_FILETYPE_PEM) != 1) { + raise_file_error("SSL_CTX_use_PrivateKey_file", RSTRING_PTR(key)); + } + } + + if (!NIL_P(cert_pem)) { + X509 *ca = NULL; + unsigned long err; + + bio = BIO_new(BIO_s_mem()); + BIO_puts(bio, RSTRING_PTR(cert_pem)); + + /** + * Much of this pulled as a simplified version of the `use_certificate_chain_file` method + * from openssl's `ssl_rsa.c` file. + */ + + /* first read the cert as the first item in the pem file */ + x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL); + if (NULL == x509) { + BIO_free_all(bio); + raise_param_error("PEM_read_bio_X509", "cert_pem"); + } + + /* Add the cert to the context */ + /* 1 is success - otherwise check the error codes */ + if (1 != SSL_CTX_use_certificate(ctx, x509)) { + BIO_free_all(bio); + raise_param_error("SSL_CTX_use_certificate", "cert_pem"); + } + + X509_free(x509); /* no longer need our reference */ + + /* Now lets load up the rest of the certificate chain */ + /* 1 is success 0 is error */ + if (0 == SSL_CTX_clear_chain_certs(ctx)) { + BIO_free_all(bio); + raise_param_error("SSL_CTX_clear_chain_certs","cert_pem"); + } + + while (1) { + ca = PEM_read_bio_X509(bio, NULL, NULL, NULL); + + if (NULL == ca) { + break; + } + + if (0 == SSL_CTX_add0_chain_cert(ctx, ca)) { + BIO_free_all(bio); + raise_param_error("SSL_CTX_add0_chain_cert","cert_pem"); + } + /* don't free ca - its now owned by the context */ + } + + /* ca is NULL - so its either the end of the file or an error */ + err = ERR_peek_last_error(); + + /* If its the end of the file - then we are done, in any case free the bio */ + BIO_free_all(bio); + + if ((ERR_GET_LIB(err) == ERR_LIB_PEM) && (ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) { + ERR_clear_error(); + } else { + raise_param_error("PEM_read_bio_X509","cert_pem"); + } + } + + if (!NIL_P(key_pem)) { + bio = BIO_new(BIO_s_mem()); + BIO_puts(bio, RSTRING_PTR(key_pem)); + pkey = PEM_read_bio_PrivateKey(bio, NULL, password_cb, (void *) password); + + if (SSL_CTX_use_PrivateKey(ctx, pkey) != 1) { + BIO_free(bio); + raise_file_error("SSL_CTX_use_PrivateKey", RSTRING_PTR(key_pem)); + } + EVP_PKEY_free(pkey); + BIO_free(bio); + } + + verification_flags = rb_funcall(mini_ssl_ctx, rb_intern_const("verification_flags"), 0); + + if (!NIL_P(verification_flags)) { + X509_VERIFY_PARAM *param = SSL_CTX_get0_param(ctx); + X509_VERIFY_PARAM_set_flags(param, NUM2INT(verification_flags)); + SSL_CTX_set1_param(ctx, param); + } + + if (!NIL_P(ca)) { + StringValue(ca); + if (SSL_CTX_load_verify_locations(ctx, RSTRING_PTR(ca), NULL) != 1) { + raise_file_error("SSL_CTX_load_verify_locations", RSTRING_PTR(ca)); + } + } + + ssl_options = SSL_OP_CIPHER_SERVER_PREFERENCE | SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_COMPRESSION; + +#ifdef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION + if (RTEST(no_tlsv1_1)) { + min = TLS1_2_VERSION; + } + else if (RTEST(no_tlsv1)) { + min = TLS1_1_VERSION; + } + else { + min = TLS1_VERSION; + } + + SSL_CTX_set_min_proto_version(ctx, min); + +#else + /* As of 1.0.2f, SSL_OP_SINGLE_DH_USE key use is always on */ + ssl_options |= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_SINGLE_DH_USE; + + if (RTEST(no_tlsv1)) { + ssl_options |= SSL_OP_NO_TLSv1; + } + if(RTEST(no_tlsv1_1)) { + ssl_options |= SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1; + } +#endif + +#ifdef HAVE_SSL_CTX_SET_SESSION_CACHE_MODE + if (!NIL_P(reuse)) { + SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER); + if (!NIL_P(reuse_cache_size)) { + SSL_CTX_sess_set_cache_size(ctx, NUM2INT(reuse_cache_size)); + } + if (!NIL_P(reuse_timeout)) { + SSL_CTX_set_timeout(ctx, NUM2INT(reuse_timeout)); + } + } else { + SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); + } +#endif + + SSL_CTX_set_options(ctx, ssl_options); + + if (!NIL_P(ssl_cipher_filter)) { + StringValue(ssl_cipher_filter); + SSL_CTX_set_cipher_list(ctx, RSTRING_PTR(ssl_cipher_filter)); + } + else { + SSL_CTX_set_cipher_list(ctx, "HIGH:!aNULL@STRENGTH"); + } + +#if HAVE_SSL_CTX_SET_CIPHERSUITES + // Only override OpenSSL default ciphersuites if config option is supplied. + if (!NIL_P(ssl_ciphersuites)) { + StringValue(ssl_ciphersuites); + SSL_CTX_set_ciphersuites(ctx, RSTRING_PTR(ssl_ciphersuites)); + } +#endif + +#if OPENSSL_VERSION_NUMBER < 0x10002000L + // Remove this case if OpenSSL 1.0.1 (now EOL) support is no longer needed. + ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + if (ecdh) { + SSL_CTX_set_tmp_ecdh(ctx, ecdh); + EC_KEY_free(ecdh); + } +#elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) + SSL_CTX_set_ecdh_auto(ctx, 1); +#endif + + if (NIL_P(verify_mode)) { + /* SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); */ + } else { + SSL_CTX_set_verify(ctx, NUM2INT(verify_mode), engine_verify_callback); + } + + // Random.bytes available in Ruby 2.5 and later, Random::DEFAULT deprecated in 3.0 + session_id_bytes = rb_funcall( +#ifdef HAVE_RANDOM_BYTES + rb_cRandom, +#else + rb_const_get(rb_cRandom, rb_intern_const("DEFAULT")), +#endif + rb_intern_const("bytes"), + 1, ULL2NUM(SSL_MAX_SSL_SESSION_ID_LENGTH)); + + SSL_CTX_set_session_id_context(ctx, + (unsigned char *) RSTRING_PTR(session_id_bytes), + SSL_MAX_SSL_SESSION_ID_LENGTH); + + // printf("\ninitialize end security_level %d\n", SSL_CTX_get_security_level(ctx)); + +#ifdef HAVE_SSL_CTX_SET_DH_AUTO + // https://www.openssl.org/docs/man3.0/man3/SSL_CTX_set_dh_auto.html + SSL_CTX_set_dh_auto(ctx, 1); +#else + dh = get_dh2048(); + SSL_CTX_set_tmp_dh(ctx, dh); +#endif + + rb_obj_freeze(self); + return self; +} + +VALUE engine_init_server(VALUE self, VALUE sslctx) { + ms_conn* conn; + VALUE obj; + SSL_CTX* ctx; + SSL* ssl; + + conn = engine_alloc(self, &obj); + + TypedData_Get_Struct(sslctx, SSL_CTX, &sslctx_type, ctx); + + ssl = SSL_new(ctx); + conn->ssl = ssl; + SSL_set_app_data(ssl, NULL); + SSL_set_bio(ssl, conn->read, conn->write); + SSL_set_accept_state(ssl); + return obj; +} + +VALUE engine_init_client(VALUE klass) { + VALUE obj; + ms_conn* conn = engine_alloc(klass, &obj); +#ifdef HAVE_DTLS_METHOD + conn->ctx = SSL_CTX_new(DTLS_method()); +#else + conn->ctx = SSL_CTX_new(DTLSv1_method()); +#endif + conn->ssl = SSL_new(conn->ctx); + SSL_set_app_data(conn->ssl, NULL); + SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL); + + SSL_set_bio(conn->ssl, conn->read, conn->write); + + SSL_set_connect_state(conn->ssl); + return obj; +} + +VALUE engine_inject(VALUE self, VALUE str) { + ms_conn* conn; + long used; + + TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn); + + StringValue(str); + + used = BIO_write(conn->read, RSTRING_PTR(str), (int)RSTRING_LEN(str)); + + if(used == 0 || used == -1) { + return Qfalse; + } + + return INT2FIX(used); +} + +NORETURN(void raise_error(SSL* ssl, int result)); + +void raise_error(SSL* ssl, int result) { + char buf[512]; + char msg[768]; + const char* err_str; + int err = errno; + int mask = 4095; + int ssl_err = SSL_get_error(ssl, result); + int verify_err = (int) SSL_get_verify_result(ssl); + + if(SSL_ERROR_SYSCALL == ssl_err) { + snprintf(msg, sizeof(msg), "System error: %s - %d", strerror(err), err); + + } else if(SSL_ERROR_SSL == ssl_err) { + if(X509_V_OK != verify_err) { + err_str = X509_verify_cert_error_string(verify_err); + snprintf(msg, sizeof(msg), + "OpenSSL certificate verification error: %s - %d", + err_str, verify_err); + + } else { + err = (int) ERR_get_error(); + ERR_error_string_n(err, buf, sizeof(buf)); + snprintf(msg, sizeof(msg), "OpenSSL error: %s - %d", buf, err & mask); + } + } else { + snprintf(msg, sizeof(msg), "Unknown OpenSSL error: %d", ssl_err); + } + + ERR_clear_error(); + rb_raise(eError, "%s", msg); +} + +VALUE engine_read(VALUE self) { + ms_conn* conn; + char buf[512]; + int bytes, error; + + TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn); + + ERR_clear_error(); + + bytes = SSL_read(conn->ssl, (void*)buf, sizeof(buf)); + + if(bytes > 0) { + return rb_str_new(buf, bytes); + } + + if(SSL_want_read(conn->ssl)) return Qnil; + + error = SSL_get_error(conn->ssl, bytes); + + if(error == SSL_ERROR_ZERO_RETURN) { + rb_eof_error(); + } else { + raise_error(conn->ssl, bytes); + } + + return Qnil; +} + +VALUE engine_write(VALUE self, VALUE str) { + ms_conn* conn; + int bytes; + + TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn); + + StringValue(str); + + ERR_clear_error(); + + bytes = SSL_write(conn->ssl, (void*)RSTRING_PTR(str), (int)RSTRING_LEN(str)); + if(bytes > 0) { + return INT2FIX(bytes); + } + + if(SSL_want_write(conn->ssl)) return Qnil; + + raise_error(conn->ssl, bytes); + + return Qnil; +} + +VALUE engine_extract(VALUE self) { + ms_conn* conn; + int bytes; + size_t pending; + // https://www.openssl.org/docs/manmaster/man3/BIO_f_buffer.html + // crypto/bio/bf_buff.c DEFAULT_BUFFER_SIZE + char buf[4096]; + + TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn); + + pending = BIO_pending(conn->write); + if(pending > 0) { + bytes = BIO_read(conn->write, buf, sizeof(buf)); + if(bytes > 0) { + return rb_str_new(buf, bytes); + } else if(!BIO_should_retry(conn->write)) { + raise_error(conn->ssl, bytes); + } + } + + return Qnil; +} + +VALUE engine_shutdown(VALUE self) { + ms_conn* conn; + int ok; + + TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn); + + ERR_clear_error(); + + ok = SSL_shutdown(conn->ssl); + if (ok == 0) { + return Qfalse; + } + + return Qtrue; +} + +VALUE engine_init(VALUE self) { + ms_conn* conn; + + TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn); + + return SSL_in_init(conn->ssl) ? Qtrue : Qfalse; +} + +VALUE engine_peercert(VALUE self) { + ms_conn* conn; + X509* cert; + int bytes; + unsigned char* buf = NULL; + ms_cert_buf* cert_buf = NULL; + VALUE rb_cert_buf; + + TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn); + +#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE + cert = SSL_get1_peer_certificate(conn->ssl); +#else + cert = SSL_get_peer_certificate(conn->ssl); +#endif + if(!cert) { + /* + * See if there was a failed certificate associated with this client. + */ + cert_buf = (ms_cert_buf*)SSL_get_app_data(conn->ssl); + if(!cert_buf) { + return Qnil; + } + buf = cert_buf->buf; + bytes = cert_buf->bytes; + + } else { + bytes = i2d_X509(cert, &buf); + X509_free(cert); + + if(bytes < 0) { + return Qnil; + } + } + + rb_cert_buf = rb_str_new((const char*)(buf), bytes); + if(!cert_buf) { + OPENSSL_free(buf); + } + + return rb_cert_buf; +} + +/* @see Puma::MiniSSL::Socket#ssl_version_state + * @version 5.0.0 + */ +static VALUE +engine_ssl_vers_st(VALUE self) { + ms_conn* conn; + TypedData_Get_Struct(self, ms_conn, &engine_data_type, conn); + return rb_ary_new3(2, rb_str_new2(SSL_get_version(conn->ssl)), rb_str_new2(SSL_state_string(conn->ssl))); +} + +VALUE noop(VALUE self) { + return Qnil; +} + +void Init_mini_ssl(VALUE puma) { + VALUE mod, eng, sslctx; + +/* Fake operation for documentation (RDoc, YARD) */ +#if 0 == 1 + puma = rb_define_module("Puma"); +#endif + + SSL_library_init(); + OpenSSL_add_ssl_algorithms(); + SSL_load_error_strings(); + ERR_load_crypto_strings(); + + mod = rb_define_module_under(puma, "MiniSSL"); + + eng = rb_define_class_under(mod, "Engine", rb_cObject); + rb_undef_alloc_func(eng); + + sslctx = rb_define_class_under(mod, "SSLContext", rb_cObject); + rb_define_alloc_func(sslctx, sslctx_alloc); + rb_define_method(sslctx, "initialize", sslctx_initialize, 1); + rb_undef_method(sslctx, "initialize_copy"); + + + // OpenSSL Build / Runtime/Load versions + + /* Version of OpenSSL that Puma was compiled with */ + rb_define_const(mod, "OPENSSL_VERSION", rb_str_new2(OPENSSL_VERSION_TEXT)); + +#if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000 + /* Version of OpenSSL that Puma loaded with */ + rb_define_const(mod, "OPENSSL_LIBRARY_VERSION", rb_str_new2(OpenSSL_version(OPENSSL_VERSION))); +#else + rb_define_const(mod, "OPENSSL_LIBRARY_VERSION", rb_str_new2(SSLeay_version(SSLEAY_VERSION))); +#endif + +#if defined(OPENSSL_NO_SSL3) || defined(OPENSSL_NO_SSL3_METHOD) + /* True if SSL3 is not available */ + rb_define_const(mod, "OPENSSL_NO_SSL3", Qtrue); +#else + rb_define_const(mod, "OPENSSL_NO_SSL3", Qfalse); +#endif + +#if defined(OPENSSL_NO_TLS1) || defined(OPENSSL_NO_TLS1_METHOD) + /* True if TLS1 is not available */ + rb_define_const(mod, "OPENSSL_NO_TLS1", Qtrue); +#else + rb_define_const(mod, "OPENSSL_NO_TLS1", Qfalse); +#endif + +#if defined(OPENSSL_NO_TLS1_1) || defined(OPENSSL_NO_TLS1_1_METHOD) + /* True if TLS1_1 is not available */ + rb_define_const(mod, "OPENSSL_NO_TLS1_1", Qtrue); +#else + rb_define_const(mod, "OPENSSL_NO_TLS1_1", Qfalse); +#endif + + rb_define_singleton_method(mod, "check", noop, 0); + + eError = rb_define_class_under(mod, "SSLError", rb_eStandardError); + + rb_define_singleton_method(eng, "server", engine_init_server, 1); + rb_define_singleton_method(eng, "client", engine_init_client, 0); + + rb_define_method(eng, "inject", engine_inject, 1); + rb_define_method(eng, "read", engine_read, 0); + + rb_define_method(eng, "write", engine_write, 1); + rb_define_method(eng, "extract", engine_extract, 0); + + rb_define_method(eng, "shutdown", engine_shutdown, 0); + + rb_define_method(eng, "init?", engine_init, 0); + + /* @!attribute [r] peercert + * Returns `nil` when `MiniSSL::Context#verify_mode` is set to `VERIFY_NONE`. + * @return [String, nil] DER encoded cert + */ + rb_define_method(eng, "peercert", engine_peercert, 0); + + rb_define_method(eng, "ssl_vers_st", engine_ssl_vers_st, 0); +} + +#else + +NORETURN(VALUE raise_error(VALUE self)); + +VALUE raise_error(VALUE self) { + rb_raise(rb_eStandardError, "SSL not available in this build"); +} + +void Init_mini_ssl(VALUE puma) { + VALUE mod; + + mod = rb_define_module_under(puma, "MiniSSL"); + rb_define_class_under(mod, "SSLError", rb_eStandardError); + + rb_define_singleton_method(mod, "check", raise_error, 0); +} +#endif diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/no_ssl/PumaHttp11Service.java b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/no_ssl/PumaHttp11Service.java new file mode 100644 index 00000000..5701e83f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/no_ssl/PumaHttp11Service.java @@ -0,0 +1,15 @@ +package puma; + +import java.io.IOException; + +import org.jruby.Ruby; +import org.jruby.runtime.load.BasicLibraryService; + +import org.jruby.puma.Http11; + +public class PumaHttp11Service implements BasicLibraryService { + public boolean basicLoad(final Ruby runtime) throws IOException { + Http11.createHttp11(runtime); + return true; + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/org/jruby/puma/Http11.java b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/org/jruby/puma/Http11.java new file mode 100644 index 00000000..2b909ad4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/org/jruby/puma/Http11.java @@ -0,0 +1,249 @@ +package org.jruby.puma; + +import org.jruby.Ruby; +import org.jruby.RubyClass; +import org.jruby.RubyHash; +import org.jruby.RubyModule; +import org.jruby.RubyNumeric; +import org.jruby.RubyObject; +import org.jruby.RubyString; + +import org.jruby.anno.JRubyMethod; + +import org.jruby.runtime.ObjectAllocator; +import org.jruby.runtime.builtin.IRubyObject; + +import org.jruby.exceptions.RaiseException; + +import org.jruby.util.ByteList; + +/** + * @author Ola Bini + * @author Charles Oliver Nutter + */ +public class Http11 extends RubyObject { + public final static int MAX_FIELD_NAME_LENGTH = 256; + public final static String MAX_FIELD_NAME_LENGTH_ERR = "HTTP element FIELD_NAME is longer than the 256 allowed length."; + public final static int MAX_FIELD_VALUE_LENGTH = 80 * 1024; + public final static String MAX_FIELD_VALUE_LENGTH_ERR = "HTTP element FIELD_VALUE is longer than the 81920 allowed length."; + public final static int MAX_REQUEST_URI_LENGTH = getConstLength("PUMA_REQUEST_URI_MAX_LENGTH", 1024 * 12); + public final static String MAX_REQUEST_URI_LENGTH_ERR = "HTTP element REQUEST_URI is longer than the " + MAX_REQUEST_URI_LENGTH + " allowed length."; + public final static int MAX_FRAGMENT_LENGTH = 1024; + public final static String MAX_FRAGMENT_LENGTH_ERR = "HTTP element REQUEST_PATH is longer than the 1024 allowed length."; + public final static int MAX_REQUEST_PATH_LENGTH = getConstLength("PUMA_REQUEST_PATH_MAX_LENGTH", 8192); + public final static String MAX_REQUEST_PATH_LENGTH_ERR = "HTTP element REQUEST_PATH is longer than the " + MAX_REQUEST_PATH_LENGTH + " allowed length."; + public final static int MAX_QUERY_STRING_LENGTH = getConstLength("PUMA_QUERY_STRING_MAX_LENGTH", 10 * 1024); + public final static String MAX_QUERY_STRING_LENGTH_ERR = "HTTP element QUERY_STRING is longer than the " + MAX_QUERY_STRING_LENGTH +" allowed length."; + public final static int MAX_HEADER_LENGTH = 1024 * (80 + 32); + public final static String MAX_HEADER_LENGTH_ERR = "HTTP element HEADER is longer than the 114688 allowed length."; + + public static final ByteList CONTENT_TYPE_BYTELIST = new ByteList(ByteList.plain("CONTENT_TYPE")); + public static final ByteList CONTENT_LENGTH_BYTELIST = new ByteList(ByteList.plain("CONTENT_LENGTH")); + public static final ByteList HTTP_PREFIX_BYTELIST = new ByteList(ByteList.plain("HTTP_")); + public static final ByteList COMMA_SPACE_BYTELIST = new ByteList(ByteList.plain(", ")); + public static final ByteList REQUEST_METHOD_BYTELIST = new ByteList(ByteList.plain("REQUEST_METHOD")); + public static final ByteList REQUEST_URI_BYTELIST = new ByteList(ByteList.plain("REQUEST_URI")); + public static final ByteList FRAGMENT_BYTELIST = new ByteList(ByteList.plain("FRAGMENT")); + public static final ByteList REQUEST_PATH_BYTELIST = new ByteList(ByteList.plain("REQUEST_PATH")); + public static final ByteList QUERY_STRING_BYTELIST = new ByteList(ByteList.plain("QUERY_STRING")); + public static final ByteList SERVER_PROTOCOL_BYTELIST = new ByteList(ByteList.plain("SERVER_PROTOCOL")); + + public static String getEnvOrProperty(String name) { + String envValue = System.getenv(name); + return (envValue != null) ? envValue : System.getProperty(name); + } + + public static int getConstLength(String name, Integer defaultValue) { + String stringValue = getEnvOrProperty(name); + if (stringValue == null || stringValue.isEmpty()) return defaultValue; + + try { + int value = Integer.parseUnsignedInt(stringValue); + if (value <= 0) { + throw new NumberFormatException("The number is not positive."); + } + return value; + } catch (NumberFormatException e) { + System.err.println(String.format("The value %s for %s is invalid. Using default value %d instead.", stringValue, name, defaultValue)); + return defaultValue; + } + } + + private static ObjectAllocator ALLOCATOR = new ObjectAllocator() { + public IRubyObject allocate(Ruby runtime, RubyClass klass) { + return new Http11(runtime, klass); + } + }; + + public static void createHttp11(Ruby runtime) { + RubyModule mPuma = runtime.defineModule("Puma"); + mPuma.defineClassUnder("HttpParserError",runtime.getClass("StandardError"),runtime.getClass("StandardError").getAllocator()); + + RubyClass cHttpParser = mPuma.defineClassUnder("HttpParser",runtime.getObject(),ALLOCATOR); + cHttpParser.defineAnnotatedMethods(Http11.class); + } + + private Ruby runtime; + private Http11Parser hp; + private RubyString body; + + public Http11(Ruby runtime, RubyClass clazz) { + super(runtime,clazz); + this.runtime = runtime; + this.hp = new Http11Parser(); + this.hp.parser.init(); + } + + public static void validateMaxLength(Ruby runtime, int len, int max, String msg) { + if(len>max) { + throw newHTTPParserError(runtime, msg); + } + } + + private static RaiseException newHTTPParserError(Ruby runtime, String msg) { + return runtime.newRaiseException(getHTTPParserError(runtime), msg); + } + + private static RubyClass getHTTPParserError(Ruby runtime) { + // Cheaper to look this up lazily than cache eagerly and consume a field, since it's rarely encountered + return (RubyClass)runtime.getModule("Puma").getConstant("HttpParserError"); + } + + public static void http_field(Ruby runtime, RubyHash req, ByteList buffer, int field, int flen, int value, int vlen) { + RubyString f; + IRubyObject v; + validateMaxLength(runtime, flen, MAX_FIELD_NAME_LENGTH, MAX_FIELD_NAME_LENGTH_ERR); + validateMaxLength(runtime, vlen, MAX_FIELD_VALUE_LENGTH, MAX_FIELD_VALUE_LENGTH_ERR); + + ByteList b = new ByteList(buffer,field,flen); + for(int i = 0,j = b.length();i 0 && Character.isWhitespace(buffer.get(value + vlen - 1))) vlen--; + + if (b.equals(CONTENT_LENGTH_BYTELIST) || b.equals(CONTENT_TYPE_BYTELIST)) { + f = RubyString.newString(runtime, b); + } else { + f = RubyString.newStringShared(runtime, HTTP_PREFIX_BYTELIST); + f.cat(b); + } + + b = new ByteList(buffer, value, vlen); + v = req.fastARef(f); + if (v == null || v.isNil()) { + req.fastASet(f, RubyString.newString(runtime, b)); + } else { + RubyString vs = v.convertToString(); + vs.cat(COMMA_SPACE_BYTELIST); + vs.cat(b); + } + } + + public static void request_method(Ruby runtime, RubyHash req, ByteList buffer, int at, int length) { + RubyString val = RubyString.newString(runtime,new ByteList(buffer,at,length)); + req.fastASet(RubyString.newStringShared(runtime, REQUEST_METHOD_BYTELIST),val); + } + + public static void request_uri(Ruby runtime, RubyHash req, ByteList buffer, int at, int length) { + validateMaxLength(runtime, length, MAX_REQUEST_URI_LENGTH, MAX_REQUEST_URI_LENGTH_ERR); + RubyString val = RubyString.newString(runtime,new ByteList(buffer,at,length)); + req.fastASet(RubyString.newStringShared(runtime, REQUEST_URI_BYTELIST),val); + } + + public static void fragment(Ruby runtime, RubyHash req, ByteList buffer, int at, int length) { + validateMaxLength(runtime, length, MAX_FRAGMENT_LENGTH, MAX_FRAGMENT_LENGTH_ERR); + RubyString val = RubyString.newString(runtime,new ByteList(buffer,at,length)); + req.fastASet(RubyString.newStringShared(runtime, FRAGMENT_BYTELIST),val); + } + + public static void request_path(Ruby runtime, RubyHash req, ByteList buffer, int at, int length) { + validateMaxLength(runtime, length, MAX_REQUEST_PATH_LENGTH, MAX_REQUEST_PATH_LENGTH_ERR); + RubyString val = RubyString.newString(runtime,new ByteList(buffer,at,length)); + req.fastASet(RubyString.newStringShared(runtime, REQUEST_PATH_BYTELIST),val); + } + + public static void query_string(Ruby runtime, RubyHash req, ByteList buffer, int at, int length) { + validateMaxLength(runtime, length, MAX_QUERY_STRING_LENGTH, MAX_QUERY_STRING_LENGTH_ERR); + RubyString val = RubyString.newString(runtime,new ByteList(buffer,at,length)); + req.fastASet(RubyString.newStringShared(runtime, QUERY_STRING_BYTELIST),val); + } + + public static void server_protocol(Ruby runtime, RubyHash req, ByteList buffer, int at, int length) { + RubyString val = RubyString.newString(runtime,new ByteList(buffer,at,length)); + req.fastASet(RubyString.newStringShared(runtime, SERVER_PROTOCOL_BYTELIST),val); + } + + public void header_done(Ruby runtime, RubyHash req, ByteList buffer, int at, int length) { + body = RubyString.newStringShared(runtime, new ByteList(buffer, at, length)); + } + + @JRubyMethod + public IRubyObject initialize() { + this.hp.parser.init(); + return this; + } + + @JRubyMethod + public IRubyObject reset() { + this.hp.parser.init(); + return runtime.getNil(); + } + + @JRubyMethod + public IRubyObject finish() { + this.hp.finish(); + return this.hp.is_finished() ? runtime.getTrue() : runtime.getFalse(); + } + + @JRubyMethod + public IRubyObject execute(IRubyObject req_hash, IRubyObject data, IRubyObject start) { + int from = RubyNumeric.fix2int(start); + ByteList d = ((RubyString)data).getByteList(); + if(from >= d.length()) { + throw newHTTPParserError(runtime, "Requested start is after data buffer end."); + } else { + Http11Parser hp = this.hp; + Http11Parser.HttpParser parser = hp.parser; + + parser.data = (RubyHash) req_hash; + + hp.execute(runtime, this, d,from); + + validateMaxLength(runtime, parser.nread,MAX_HEADER_LENGTH, MAX_HEADER_LENGTH_ERR); + + if(hp.has_error()) { + throw newHTTPParserError(runtime, "Invalid HTTP format, parsing fails. Are you trying to open an SSL connection to a non-SSL Puma?"); + } else { + return runtime.newFixnum(parser.nread); + } + } + } + + @JRubyMethod(name = "error?") + public IRubyObject has_error() { + return this.hp.has_error() ? runtime.getTrue() : runtime.getFalse(); + } + + @JRubyMethod(name = "finished?") + public IRubyObject is_finished() { + return this.hp.is_finished() ? runtime.getTrue() : runtime.getFalse(); + } + + @JRubyMethod + public IRubyObject nread() { + return runtime.newFixnum(this.hp.parser.nread); + } + + @JRubyMethod + public IRubyObject body() { + return body; + } +}// Http11 diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/org/jruby/puma/Http11Parser.java b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/org/jruby/puma/Http11Parser.java new file mode 100644 index 00000000..d5a68158 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/org/jruby/puma/Http11Parser.java @@ -0,0 +1,455 @@ + +// line 1 "ext/puma_http11/http11_parser.java.rl" +package org.jruby.puma; + +import org.jruby.Ruby; +import org.jruby.RubyHash; +import org.jruby.util.ByteList; + +public class Http11Parser { + +/** Machine **/ + + +// line 58 "ext/puma_http11/http11_parser.java.rl" + + +/** Data **/ + +// line 20 "ext/puma_http11/org/jruby/puma/Http11Parser.java" +private static byte[] init__puma_parser_actions_0() +{ + return new byte [] { + 0, 1, 0, 1, 2, 1, 3, 1, 4, 1, 5, 1, + 6, 1, 7, 1, 8, 1, 9, 1, 11, 1, 12, 1, + 13, 2, 0, 8, 2, 1, 2, 2, 4, 5, 2, 10, + 7, 2, 12, 7, 3, 9, 10, 7 + }; +} + +private static final byte _puma_parser_actions[] = init__puma_parser_actions_0(); + + +private static short[] init__puma_parser_key_offsets_0() +{ + return new short [] { + 0, 0, 8, 17, 27, 29, 30, 31, 32, 33, 34, 36, + 39, 41, 44, 45, 61, 62, 78, 85, 91, 99, 107, 117, + 125, 134, 142, 150, 159, 168, 177, 186, 195, 204, 213, 222, + 231, 240, 249, 258, 267, 276, 285, 294, 303, 312, 313 + }; +} + +private static final short _puma_parser_key_offsets[] = init__puma_parser_key_offsets_0(); + + +private static char[] init__puma_parser_trans_keys_0() +{ + return new char [] { + 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95, 45, + 46, 48, 57, 65, 90, 42, 43, 47, 58, 45, 57, 65, + 90, 97, 122, 32, 35, 72, 84, 84, 80, 47, 48, 57, + 46, 48, 57, 48, 57, 13, 48, 57, 10, 13, 33, 124, + 126, 35, 39, 42, 43, 45, 46, 48, 57, 65, 90, 94, + 122, 10, 33, 58, 124, 126, 35, 39, 42, 43, 45, 46, + 48, 57, 65, 90, 94, 122, 13, 32, 127, 0, 8, 10, + 31, 13, 127, 0, 8, 10, 31, 32, 60, 62, 127, 0, + 31, 34, 35, 32, 60, 62, 127, 0, 31, 34, 35, 43, + 58, 45, 46, 48, 57, 65, 90, 97, 122, 32, 34, 35, + 60, 62, 127, 0, 31, 32, 34, 35, 60, 62, 63, 127, + 0, 31, 32, 34, 35, 60, 62, 127, 0, 31, 32, 34, + 35, 60, 62, 127, 0, 31, 32, 36, 95, 45, 46, 48, + 57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90, + 32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95, + 45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48, + 57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90, + 32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95, + 45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48, + 57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90, + 32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95, + 45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48, + 57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90, + 32, 36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95, + 45, 46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48, + 57, 65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90, + 32, 0 + }; +} + +private static final char _puma_parser_trans_keys[] = init__puma_parser_trans_keys_0(); + + +private static byte[] init__puma_parser_single_lengths_0() +{ + return new byte [] { + 0, 2, 3, 4, 2, 1, 1, 1, 1, 1, 0, 1, + 0, 1, 1, 4, 1, 4, 3, 2, 4, 4, 2, 6, + 7, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0 + }; +} + +private static final byte _puma_parser_single_lengths[] = init__puma_parser_single_lengths_0(); + + +private static byte[] init__puma_parser_range_lengths_0() +{ + return new byte [] { + 0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 0, 6, 0, 6, 2, 2, 2, 2, 4, 1, + 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0 + }; +} + +private static final byte _puma_parser_range_lengths[] = init__puma_parser_range_lengths_0(); + + +private static short[] init__puma_parser_index_offsets_0() +{ + return new short [] { + 0, 0, 6, 13, 21, 24, 26, 28, 30, 32, 34, 36, + 39, 41, 44, 46, 57, 59, 70, 76, 81, 88, 95, 102, + 110, 119, 127, 135, 142, 149, 156, 163, 170, 177, 184, 191, + 198, 205, 212, 219, 226, 233, 240, 247, 254, 261, 263 + }; +} + +private static final short _puma_parser_index_offsets[] = init__puma_parser_index_offsets_0(); + + +private static byte[] init__puma_parser_indicies_0() +{ + return new byte [] { + 0, 0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 3, + 1, 4, 5, 6, 7, 5, 5, 5, 1, 8, 9, 1, + 10, 1, 11, 1, 12, 1, 13, 1, 14, 1, 15, 1, + 16, 15, 1, 17, 1, 18, 17, 1, 19, 1, 20, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 1, 22, 1, 23, + 24, 23, 23, 23, 23, 23, 23, 23, 23, 1, 26, 27, + 1, 1, 1, 25, 29, 1, 1, 1, 28, 30, 1, 1, + 1, 1, 1, 31, 32, 1, 1, 1, 1, 1, 33, 34, + 35, 34, 34, 34, 34, 1, 8, 1, 9, 1, 1, 1, + 1, 35, 36, 1, 38, 1, 1, 39, 1, 1, 37, 40, + 1, 42, 1, 1, 1, 1, 41, 43, 1, 45, 1, 1, + 1, 1, 44, 2, 46, 46, 46, 46, 46, 1, 2, 47, + 47, 47, 47, 47, 1, 2, 48, 48, 48, 48, 48, 1, + 2, 49, 49, 49, 49, 49, 1, 2, 50, 50, 50, 50, + 50, 1, 2, 51, 51, 51, 51, 51, 1, 2, 52, 52, + 52, 52, 52, 1, 2, 53, 53, 53, 53, 53, 1, 2, + 54, 54, 54, 54, 54, 1, 2, 55, 55, 55, 55, 55, + 1, 2, 56, 56, 56, 56, 56, 1, 2, 57, 57, 57, + 57, 57, 1, 2, 58, 58, 58, 58, 58, 1, 2, 59, + 59, 59, 59, 59, 1, 2, 60, 60, 60, 60, 60, 1, + 2, 61, 61, 61, 61, 61, 1, 2, 62, 62, 62, 62, + 62, 1, 2, 63, 63, 63, 63, 63, 1, 2, 1, 1, + 0 + }; +} + +private static final byte _puma_parser_indicies[] = init__puma_parser_indicies_0(); + + +private static byte[] init__puma_parser_trans_targs_0() +{ + return new byte [] { + 2, 0, 3, 27, 4, 22, 24, 23, 5, 20, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 46, 17, + 18, 19, 14, 18, 19, 14, 5, 21, 5, 21, 22, 23, + 5, 24, 20, 25, 5, 26, 20, 5, 26, 20, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45 + }; +} + +private static final byte _puma_parser_trans_targs[] = init__puma_parser_trans_targs_0(); + + +private static byte[] init__puma_parser_trans_actions_0() +{ + return new byte [] { + 1, 0, 11, 0, 1, 1, 1, 1, 13, 13, 1, 0, + 0, 0, 0, 0, 0, 0, 19, 0, 0, 28, 23, 3, + 5, 7, 31, 7, 0, 9, 25, 1, 15, 0, 0, 0, + 37, 0, 37, 21, 40, 17, 40, 34, 0, 34, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0 + }; +} + +private static final byte _puma_parser_trans_actions[] = init__puma_parser_trans_actions_0(); + + +static final int puma_parser_start = 1; +static final int puma_parser_first_final = 46; +static final int puma_parser_error = 0; + + +// line 62 "ext/puma_http11/http11_parser.java.rl" + + public static interface ElementCB { + public void call(Ruby runtime, RubyHash data, ByteList buffer, int at, int length); + } + + public static interface FieldCB { + public void call(Ruby runtime, RubyHash data, ByteList buffer, int field, int flen, int value, int vlen); + } + + public static class HttpParser { + int cs; + int body_start; + int content_len; + int nread; + int mark; + int field_start; + int field_len; + int query_start; + + RubyHash data; + ByteList buffer; + + public void init() { + cs = 0; + + +// line 216 "ext/puma_http11/org/jruby/puma/Http11Parser.java" + { + cs = puma_parser_start; + } + +// line 88 "ext/puma_http11/http11_parser.java.rl" + + body_start = 0; + content_len = 0; + mark = 0; + nread = 0; + field_len = 0; + field_start = 0; + } + } + + public final HttpParser parser = new HttpParser(); + + public int execute(Ruby runtime, Http11 http, ByteList buffer, int off) { + int p, pe; + int cs = parser.cs; + int len = buffer.length(); + assert off<=len : "offset past end of buffer"; + + p = off; + pe = len; + // get a copy of the bytes, since it may not start at 0 + // FIXME: figure out how to just use the bytes in-place + byte[] data = buffer.bytes(); + parser.buffer = buffer; + + +// line 248 "ext/puma_http11/org/jruby/puma/Http11Parser.java" + { + int _klen; + int _trans = 0; + int _acts; + int _nacts; + int _keys; + int _goto_targ = 0; + + _goto: while (true) { + switch ( _goto_targ ) { + case 0: + if ( p == pe ) { + _goto_targ = 4; + continue _goto; + } + if ( cs == 0 ) { + _goto_targ = 5; + continue _goto; + } +case 1: + _match: do { + _keys = _puma_parser_key_offsets[cs]; + _trans = _puma_parser_index_offsets[cs]; + _klen = _puma_parser_single_lengths[cs]; + if ( _klen > 0 ) { + int _lower = _keys; + int _mid; + int _upper = _keys + _klen - 1; + while (true) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( data[p] < _puma_parser_trans_keys[_mid] ) + _upper = _mid - 1; + else if ( data[p] > _puma_parser_trans_keys[_mid] ) + _lower = _mid + 1; + else { + _trans += (_mid - _keys); + break _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _puma_parser_range_lengths[cs]; + if ( _klen > 0 ) { + int _lower = _keys; + int _mid; + int _upper = _keys + (_klen<<1) - 2; + while (true) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( data[p] < _puma_parser_trans_keys[_mid] ) + _upper = _mid - 2; + else if ( data[p] > _puma_parser_trans_keys[_mid+1] ) + _lower = _mid + 2; + else { + _trans += ((_mid - _keys)>>1); + break _match; + } + } + _trans += _klen; + } + } while (false); + + _trans = _puma_parser_indicies[_trans]; + cs = _puma_parser_trans_targs[_trans]; + + if ( _puma_parser_trans_actions[_trans] != 0 ) { + _acts = _puma_parser_trans_actions[_trans]; + _nacts = (int) _puma_parser_actions[_acts++]; + while ( _nacts-- > 0 ) + { + switch ( _puma_parser_actions[_acts++] ) + { + case 0: +// line 15 "ext/puma_http11/http11_parser.java.rl" + {parser.mark = p; } + break; + case 1: +// line 17 "ext/puma_http11/http11_parser.java.rl" + { parser.field_start = p; } + break; + case 2: +// line 18 "ext/puma_http11/http11_parser.java.rl" + { /* FIXME stub */ } + break; + case 3: +// line 19 "ext/puma_http11/http11_parser.java.rl" + { + parser.field_len = p-parser.field_start; + } + break; + case 4: +// line 23 "ext/puma_http11/http11_parser.java.rl" + { parser.mark = p; } + break; + case 5: +// line 24 "ext/puma_http11/http11_parser.java.rl" + { + Http11.http_field(runtime, parser.data, parser.buffer, parser.field_start, parser.field_len, parser.mark, p-parser.mark); + } + break; + case 6: +// line 27 "ext/puma_http11/http11_parser.java.rl" + { + Http11.request_method(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark); + } + break; + case 7: +// line 30 "ext/puma_http11/http11_parser.java.rl" + { + Http11.request_uri(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark); + } + break; + case 8: +// line 33 "ext/puma_http11/http11_parser.java.rl" + { + Http11.fragment(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark); + } + break; + case 9: +// line 37 "ext/puma_http11/http11_parser.java.rl" + {parser.query_start = p; } + break; + case 10: +// line 38 "ext/puma_http11/http11_parser.java.rl" + { + Http11.query_string(runtime, parser.data, parser.buffer, parser.query_start, p-parser.query_start); + } + break; + case 11: +// line 42 "ext/puma_http11/http11_parser.java.rl" + { + Http11.server_protocol(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark); + } + break; + case 12: +// line 46 "ext/puma_http11/http11_parser.java.rl" + { + Http11.request_path(runtime, parser.data, parser.buffer, parser.mark, p-parser.mark); + } + break; + case 13: +// line 50 "ext/puma_http11/http11_parser.java.rl" + { + parser.body_start = p + 1; + http.header_done(runtime, parser.data, parser.buffer, p + 1, pe - p - 1); + { p += 1; _goto_targ = 5; if (true) continue _goto;} + } + break; +// line 404 "ext/puma_http11/org/jruby/puma/Http11Parser.java" + } + } + } + +case 2: + if ( cs == 0 ) { + _goto_targ = 5; + continue _goto; + } + if ( ++p != pe ) { + _goto_targ = 1; + continue _goto; + } +case 4: +case 5: + } + break; } + } + +// line 114 "ext/puma_http11/http11_parser.java.rl" + + parser.cs = cs; + parser.nread += (p - off); + + assert p <= pe : "buffer overflow after parsing execute"; + assert parser.nread <= len : "nread longer than length"; + assert parser.body_start <= len : "body starts after buffer end"; + assert parser.mark < len : "mark is after buffer end"; + assert parser.field_len <= len : "field has length longer than whole buffer"; + assert parser.field_start < len : "field starts after buffer end"; + + return parser.nread; + } + + public int finish() { + if(has_error()) { + return -1; + } else if(is_finished()) { + return 1; + } else { + return 0; + } + } + + public boolean has_error() { + return parser.cs == puma_parser_error; + } + + public boolean is_finished() { + return parser.cs == puma_parser_first_final; + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/org/jruby/puma/MiniSSL.java b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/org/jruby/puma/MiniSSL.java new file mode 100644 index 00000000..36ad801e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/org/jruby/puma/MiniSSL.java @@ -0,0 +1,509 @@ +package org.jruby.puma; + +import org.jruby.Ruby; +import org.jruby.RubyArray; +import org.jruby.RubyClass; +import org.jruby.RubyModule; +import org.jruby.RubyObject; +import org.jruby.RubyString; +import org.jruby.anno.JRubyMethod; +import org.jruby.exceptions.RaiseException; +import org.jruby.javasupport.JavaEmbedUtils; +import org.jruby.runtime.Block; +import org.jruby.runtime.ObjectAllocator; +import org.jruby.runtime.ThreadContext; +import org.jruby.runtime.builtin.IRubyObject; +import org.jruby.util.ByteList; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLEngineResult; +import javax.net.ssl.SSLException; +import javax.net.ssl.SSLPeerUnverifiedException; +import javax.net.ssl.SSLSession; +import javax.net.ssl.X509TrustManager; +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.IOException; +import java.nio.Buffer; +import java.nio.ByteBuffer; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.Certificate; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.concurrent.ConcurrentHashMap; +import java.util.Map; +import java.util.function.Supplier; + +import static javax.net.ssl.SSLEngineResult.Status; +import static javax.net.ssl.SSLEngineResult.HandshakeStatus; + +public class MiniSSL extends RubyObject { // MiniSSL::Engine + private static final long serialVersionUID = -6903439483039141234L; + private static ObjectAllocator ALLOCATOR = new ObjectAllocator() { + public IRubyObject allocate(Ruby runtime, RubyClass klass) { + return new MiniSSL(runtime, klass); + } + }; + + public static void createMiniSSL(Ruby runtime) { + RubyModule mPuma = runtime.defineModule("Puma"); + RubyModule ssl = mPuma.defineModuleUnder("MiniSSL"); + + // Puma::MiniSSL::SSLError + ssl.defineClassUnder("SSLError", runtime.getStandardError(), runtime.getStandardError().getAllocator()); + + RubyClass eng = ssl.defineClassUnder("Engine", runtime.getObject(), ALLOCATOR); + eng.defineAnnotatedMethods(MiniSSL.class); + } + + /** + * Fairly transparent wrapper around {@link java.nio.ByteBuffer} which adds the enhancements we need + */ + private static class MiniSSLBuffer { + ByteBuffer buffer; + + private MiniSSLBuffer(int capacity) { buffer = ByteBuffer.allocate(capacity); } + private MiniSSLBuffer(byte[] initialContents) { buffer = ByteBuffer.wrap(initialContents); } + + public void clear() { buffer.clear(); } + public void compact() { buffer.compact(); } + public void flip() { ((Buffer) buffer).flip(); } + public boolean hasRemaining() { return buffer.hasRemaining(); } + public int position() { return buffer.position(); } + + public ByteBuffer getRawBuffer() { + return buffer; + } + + /** + * Writes bytes to the buffer after ensuring there's room + */ + private void put(byte[] bytes, final int offset, final int length) { + if (buffer.remaining() < length) { + resize(buffer.limit() + length); + } + buffer.put(bytes, offset, length); + } + + /** + * Ensures that newCapacity bytes can be written to this buffer, only re-allocating if necessary + */ + public void resize(int newCapacity) { + if (newCapacity > buffer.capacity()) { + ByteBuffer dstTmp = ByteBuffer.allocate(newCapacity); + flip(); + dstTmp.put(buffer); + buffer = dstTmp; + } else { + buffer.limit(newCapacity); + } + } + + /** + * Drains the buffer to a ByteList, or returns null for an empty buffer + */ + public ByteList asByteList() { + flip(); + if (!buffer.hasRemaining()) { + buffer.clear(); + return null; + } + + byte[] bss = new byte[buffer.limit()]; + + buffer.get(bss); + buffer.clear(); + return new ByteList(bss, false); + } + + @Override + public String toString() { return buffer.toString(); } + } + + private SSLEngine engine; + private boolean closed; + private boolean handshake; + private MiniSSLBuffer inboundNetData; + private MiniSSLBuffer outboundAppData; + private MiniSSLBuffer outboundNetData; + + public MiniSSL(Ruby runtime, RubyClass klass) { + super(runtime, klass); + } + + private static Map keyManagerFactoryMap = new ConcurrentHashMap(); + private static Map trustManagerFactoryMap = new ConcurrentHashMap(); + + @JRubyMethod(meta = true) // Engine.server + public static synchronized IRubyObject server(ThreadContext context, IRubyObject recv, IRubyObject miniSSLContext) + throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException { + // Create the KeyManagerFactory and TrustManagerFactory for this server + String keystoreFile = asStringValue(miniSSLContext.callMethod(context, "keystore"), null); + char[] keystorePass = asStringValue(miniSSLContext.callMethod(context, "keystore_pass"), null).toCharArray(); + String keystoreType = asStringValue(miniSSLContext.callMethod(context, "keystore_type"), KeyStore::getDefaultType); + + String truststoreFile; + char[] truststorePass; + String truststoreType; + IRubyObject truststore = miniSSLContext.callMethod(context, "truststore"); + if (truststore.isNil()) { + truststoreFile = keystoreFile; + truststorePass = keystorePass; + truststoreType = keystoreType; + } else if (!isDefaultSymbol(context, truststore)) { + truststoreFile = truststore.convertToString().asJavaString(); + IRubyObject pass = miniSSLContext.callMethod(context, "truststore_pass"); + if (pass.isNil()) { + truststorePass = null; + } else { + truststorePass = asStringValue(pass, null).toCharArray(); + } + truststoreType = asStringValue(miniSSLContext.callMethod(context, "truststore_type"), KeyStore::getDefaultType); + } else { // self.truststore = :default + truststoreFile = null; + truststorePass = null; + truststoreType = null; + } + + KeyStore ks = KeyStore.getInstance(keystoreType); + InputStream is = new FileInputStream(keystoreFile); + try { + ks.load(is, keystorePass); + } finally { + is.close(); + } + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + kmf.init(ks, keystorePass); + keyManagerFactoryMap.put(keystoreFile, kmf); + + if (truststoreFile != null) { + KeyStore ts = KeyStore.getInstance(truststoreType); + is = new FileInputStream(truststoreFile); + try { + ts.load(is, truststorePass); + } finally { + is.close(); + } + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); + tmf.init(ts); + trustManagerFactoryMap.put(truststoreFile, tmf); + } + + RubyClass klass = (RubyClass) recv; + return klass.newInstance(context, miniSSLContext, Block.NULL_BLOCK); + } + + private static String asStringValue(IRubyObject value, Supplier defaultValue) { + if (defaultValue != null && value.isNil()) return defaultValue.get(); + return value.convertToString().asJavaString(); + } + + private static boolean isDefaultSymbol(ThreadContext context, IRubyObject truststore) { + return context.runtime.newSymbol("default").equals(truststore); + } + + @JRubyMethod + public IRubyObject initialize(ThreadContext context, IRubyObject miniSSLContext) + throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException { + + String keystoreFile = miniSSLContext.callMethod(context, "keystore").convertToString().asJavaString(); + KeyManagerFactory kmf = keyManagerFactoryMap.get(keystoreFile); + IRubyObject truststore = miniSSLContext.callMethod(context, "truststore"); + String truststoreFile = isDefaultSymbol(context, truststore) ? "" : asStringValue(truststore, () -> keystoreFile); + TrustManagerFactory tmf = trustManagerFactoryMap.get(truststoreFile); // null if self.truststore = :default + if (kmf == null) { + throw new KeyStoreException("Could not find KeyManagerFactory for keystore: " + keystoreFile + " truststore: " + truststoreFile); + } + + SSLContext sslCtx = SSLContext.getInstance("TLS"); + + sslCtx.init(kmf.getKeyManagers(), getTrustManagers(tmf), null); + closed = false; + handshake = false; + engine = sslCtx.createSSLEngine(); + + String[] enabledProtocols; + IRubyObject protocols = miniSSLContext.callMethod(context, "protocols"); + if (protocols.isNil()) { + if (miniSSLContext.callMethod(context, "no_tlsv1").isTrue()) { + enabledProtocols = new String[] { "TLSv1.1", "TLSv1.2", "TLSv1.3" }; + } else { + enabledProtocols = new String[] { "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3" }; + } + + if (miniSSLContext.callMethod(context, "no_tlsv1_1").isTrue()) { + enabledProtocols = new String[] { "TLSv1.2", "TLSv1.3" }; + } + } else if (protocols instanceof RubyArray) { + enabledProtocols = (String[]) ((RubyArray) protocols).toArray(new String[0]); + } else { + throw context.runtime.newTypeError(protocols, context.runtime.getArray()); + } + engine.setEnabledProtocols(enabledProtocols); + + engine.setUseClientMode(false); + + long verify_mode = miniSSLContext.callMethod(context, "verify_mode").convertToInteger("to_i").getLongValue(); + if ((verify_mode & 0x1) != 0) { // 'peer' + engine.setWantClientAuth(true); + } + if ((verify_mode & 0x2) != 0) { // 'force_peer' + engine.setNeedClientAuth(true); + } + + IRubyObject cipher_suites = miniSSLContext.callMethod(context, "cipher_suites"); + if (cipher_suites instanceof RubyArray) { + engine.setEnabledCipherSuites((String[]) ((RubyArray) cipher_suites).toArray(new String[0])); + } else if (!cipher_suites.isNil()) { + throw context.runtime.newTypeError(cipher_suites, context.runtime.getArray()); + } + + SSLSession session = engine.getSession(); + inboundNetData = new MiniSSLBuffer(session.getPacketBufferSize()); + outboundAppData = new MiniSSLBuffer(session.getApplicationBufferSize()); + outboundAppData.flip(); + outboundNetData = new MiniSSLBuffer(session.getPacketBufferSize()); + + return this; + } + + private TrustManager[] getTrustManagers(TrustManagerFactory factory) { + if (factory == null) return null; // use JDK trust defaults + final TrustManager[] tms = factory.getTrustManagers(); + if (tms != null) { + for (int i=0; i 0 ? chain[0] : null; + delegate.checkClientTrusted(chain, authType); + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + delegate.checkServerTrusted(chain, authType); + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return delegate.getAcceptedIssuers(); + } + + } + + @JRubyMethod + public IRubyObject inject(IRubyObject arg) { + ByteList bytes = arg.convertToString().getByteList(); + inboundNetData.put(bytes.unsafeBytes(), bytes.getBegin(), bytes.getRealSize()); + return this; + } + + private enum SSLOperation { + WRAP, + UNWRAP + } + + private SSLEngineResult doOp(SSLOperation sslOp, MiniSSLBuffer src, MiniSSLBuffer dst) throws SSLException { + SSLEngineResult res = null; + boolean retryOp = true; + while (retryOp) { + switch (sslOp) { + case WRAP: + res = engine.wrap(src.getRawBuffer(), dst.getRawBuffer()); + break; + case UNWRAP: + res = engine.unwrap(src.getRawBuffer(), dst.getRawBuffer()); + break; + default: + throw new AssertionError("Unknown SSLOperation: " + sslOp); + } + + switch (res.getStatus()) { + case BUFFER_OVERFLOW: + // increase the buffer size to accommodate the overflowing data + int newSize = Math.max(engine.getSession().getPacketBufferSize(), engine.getSession().getApplicationBufferSize()); + dst.resize(newSize + dst.position()); + // retry the operation + retryOp = true; + break; + case BUFFER_UNDERFLOW: + // need to wait for more data to come in before we retry + retryOp = false; + break; + case CLOSED: + closed = true; + retryOp = false; + break; + default: + // other case is OK. We're done here. + retryOp = false; + } + if (res.getHandshakeStatus() == HandshakeStatus.FINISHED) { + handshake = true; + } + } + + return res; + } + + @JRubyMethod + public IRubyObject read() { + try { + inboundNetData.flip(); + + if(!inboundNetData.hasRemaining()) { + return getRuntime().getNil(); + } + + MiniSSLBuffer inboundAppData = new MiniSSLBuffer(engine.getSession().getApplicationBufferSize()); + doOp(SSLOperation.UNWRAP, inboundNetData, inboundAppData); + + HandshakeStatus handshakeStatus = engine.getHandshakeStatus(); + boolean done = false; + while (!done) { + SSLEngineResult res; + switch (handshakeStatus) { + case NEED_WRAP: + res = doOp(SSLOperation.WRAP, inboundAppData, outboundNetData); + handshakeStatus = res.getHandshakeStatus(); + break; + case NEED_UNWRAP: + res = doOp(SSLOperation.UNWRAP, inboundNetData, inboundAppData); + if (res.getStatus() == Status.BUFFER_UNDERFLOW) { + // need more data before we can shake more hands + done = true; + } + handshakeStatus = res.getHandshakeStatus(); + break; + case NEED_TASK: + Runnable runnable; + while ((runnable = engine.getDelegatedTask()) != null) { + runnable.run(); + } + handshakeStatus = engine.getHandshakeStatus(); + break; + default: + done = true; + } + } + + if (inboundNetData.hasRemaining()) { + inboundNetData.compact(); + } else { + inboundNetData.clear(); + } + + ByteList appDataByteList = inboundAppData.asByteList(); + if (appDataByteList == null) { + return getRuntime().getNil(); + } + + return RubyString.newString(getRuntime(), appDataByteList); + } catch (SSLException e) { + throw newSSLError(getRuntime(), e); + } + } + + @JRubyMethod + public IRubyObject write(IRubyObject arg) { + byte[] bls = arg.convertToString().getBytes(); + outboundAppData = new MiniSSLBuffer(bls); + + return getRuntime().newFixnum(bls.length); + } + + @JRubyMethod + public IRubyObject extract(ThreadContext context) { + try { + ByteList dataByteList = outboundNetData.asByteList(); + if (dataByteList != null) { + return RubyString.newString(context.runtime, dataByteList); + } + + if (!outboundAppData.hasRemaining()) { + return context.nil; + } + + outboundNetData.clear(); + doOp(SSLOperation.WRAP, outboundAppData, outboundNetData); + dataByteList = outboundNetData.asByteList(); + if (dataByteList == null) { + return context.nil; + } + + return RubyString.newString(context.runtime, dataByteList); + } catch (SSLException e) { + throw newSSLError(getRuntime(), e); + } + } + + @JRubyMethod + public IRubyObject peercert(ThreadContext context) throws CertificateEncodingException { + Certificate peerCert; + try { + peerCert = engine.getSession().getPeerCertificates()[0]; + } catch (SSLPeerUnverifiedException e) { + peerCert = lastCheckedCert0; // null if trust check did not happen + } + return peerCert == null ? context.nil : JavaEmbedUtils.javaToRuby(context.runtime, peerCert.getEncoded()); + } + + @JRubyMethod(name = "init?") + public IRubyObject isInit(ThreadContext context) { + return handshake ? getRuntime().getFalse() : getRuntime().getTrue(); + } + + @JRubyMethod + public IRubyObject shutdown() { + if (closed || engine.isInboundDone() && engine.isOutboundDone()) { + if (engine.isOutboundDone()) { + engine.closeOutbound(); + } + return getRuntime().getTrue(); + } else { + return getRuntime().getFalse(); + } + } + + private static RubyClass getSSLError(Ruby runtime) { + return (RubyClass) ((RubyModule) runtime.getModule("Puma").getConstantAt("MiniSSL")).getConstantAt("SSLError"); + } + + private static RaiseException newSSLError(Ruby runtime, SSLException cause) { + return newError(runtime, getSSLError(runtime), cause.toString(), cause); + } + + private static RaiseException newError(Ruby runtime, RubyClass errorClass, String message, Throwable cause) { + RaiseException ex = RaiseException.from(runtime, errorClass, message); + ex.initCause(cause); + return ex; + } + +} diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/puma_http11.c b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/puma_http11.c new file mode 100644 index 00000000..b6bd18d0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/ext/puma_http11/puma_http11.c @@ -0,0 +1,495 @@ +/** + * Copyright (c) 2005 Zed A. Shaw + * You can redistribute it and/or modify it under the same terms as Ruby. + * License 3-clause BSD + */ + +#define RSTRING_NOT_MODIFIED 1 + +#include "ruby.h" +#include "ext_help.h" +#include +#include +#include +#include "http11_parser.h" + +#ifndef MANAGED_STRINGS + +#ifndef RSTRING_PTR +#define RSTRING_PTR(s) (RSTRING(s)->ptr) +#endif +#ifndef RSTRING_LEN +#define RSTRING_LEN(s) (RSTRING(s)->len) +#endif + +#define rb_extract_chars(e, sz) (*sz = RSTRING_LEN(e), RSTRING_PTR(e)) +#define rb_free_chars(e) /* nothing */ + +#endif + +static VALUE eHttpParserError; + +#define HTTP_PREFIX "HTTP_" +#define HTTP_PREFIX_LEN (sizeof(HTTP_PREFIX) - 1) + +static VALUE global_request_method; +static VALUE global_request_uri; +static VALUE global_fragment; +static VALUE global_query_string; +static VALUE global_server_protocol; +static VALUE global_request_path; + +/** Defines common length and error messages for input length validation. */ +#define QUOTE(s) #s +#define EXPAND_MAX_LENGTH_VALUE(s) QUOTE(s) +#define DEF_MAX_LENGTH(N,length) const size_t MAX_##N##_LENGTH = length; const char *MAX_##N##_LENGTH_ERR = "HTTP element " # N " is longer than the " EXPAND_MAX_LENGTH_VALUE(length) " allowed length (was %d)" + +/** Validates the max length of given input and throws an HttpParserError exception if over. */ +#define VALIDATE_MAX_LENGTH(len, N) if(len > MAX_##N##_LENGTH) { rb_raise(eHttpParserError, MAX_##N##_LENGTH_ERR, len); } + +/** Defines global strings in the init method. */ +#define DEF_GLOBAL(N, val) global_##N = rb_str_new2(val); rb_global_variable(&global_##N) + + +/* Defines the maximum allowed lengths for various input elements.*/ +#ifndef PUMA_REQUEST_URI_MAX_LENGTH +#define PUMA_REQUEST_URI_MAX_LENGTH (1024 * 12) +#endif + +#ifndef PUMA_REQUEST_PATH_MAX_LENGTH +#define PUMA_REQUEST_PATH_MAX_LENGTH (8192) +#endif + +#ifndef PUMA_QUERY_STRING_MAX_LENGTH +#define PUMA_QUERY_STRING_MAX_LENGTH (1024 * 10) +#endif + +DEF_MAX_LENGTH(FIELD_NAME, 256); +DEF_MAX_LENGTH(FIELD_VALUE, 80 * 1024); +DEF_MAX_LENGTH(REQUEST_URI, PUMA_REQUEST_URI_MAX_LENGTH); +DEF_MAX_LENGTH(FRAGMENT, 1024); /* Don't know if this length is specified somewhere or not */ +DEF_MAX_LENGTH(REQUEST_PATH, PUMA_REQUEST_PATH_MAX_LENGTH); +DEF_MAX_LENGTH(QUERY_STRING, PUMA_QUERY_STRING_MAX_LENGTH); +DEF_MAX_LENGTH(HEADER, (1024 * (80 + 32))); + +struct common_field { + const size_t len; + const char *name; + int raw; + VALUE value; +}; + +/* + * A list of common HTTP headers we expect to receive. + * This allows us to avoid repeatedly creating identical string + * objects to be used with rb_hash_aset(). + */ +static struct common_field common_http_fields[] = { +# define f(N) { (sizeof(N) - 1), N, 0, Qnil } +# define fr(N) { (sizeof(N) - 1), N, 1, Qnil } + f("ACCEPT"), + f("ACCEPT_CHARSET"), + f("ACCEPT_ENCODING"), + f("ACCEPT_LANGUAGE"), + f("ALLOW"), + f("AUTHORIZATION"), + f("CACHE_CONTROL"), + f("CONNECTION"), + f("CONTENT_ENCODING"), + fr("CONTENT_LENGTH"), + fr("CONTENT_TYPE"), + f("COOKIE"), + f("DATE"), + f("EXPECT"), + f("FROM"), + f("HOST"), + f("IF_MATCH"), + f("IF_MODIFIED_SINCE"), + f("IF_NONE_MATCH"), + f("IF_RANGE"), + f("IF_UNMODIFIED_SINCE"), + f("KEEP_ALIVE"), /* Firefox sends this */ + f("MAX_FORWARDS"), + f("PRAGMA"), + f("PROXY_AUTHORIZATION"), + f("RANGE"), + f("REFERER"), + f("TE"), + f("TRAILER"), + f("TRANSFER_ENCODING"), + f("UPGRADE"), + f("USER_AGENT"), + f("VIA"), + f("X_FORWARDED_FOR"), /* common for proxies */ + f("X_REAL_IP"), /* common for proxies */ + f("WARNING") +# undef f +}; + +static void init_common_fields(void) +{ + unsigned i; + struct common_field *cf = common_http_fields; + char tmp[256]; /* MAX_FIELD_NAME_LENGTH */ + memcpy(tmp, HTTP_PREFIX, HTTP_PREFIX_LEN); + + for(i = 0; i < ARRAY_SIZE(common_http_fields); cf++, i++) { + if(cf->raw) { + cf->value = rb_str_new(cf->name, cf->len); + } else { + memcpy(tmp + HTTP_PREFIX_LEN, cf->name, cf->len + 1); + cf->value = rb_str_new(tmp, HTTP_PREFIX_LEN + cf->len); + } + rb_global_variable(&cf->value); + } +} + +static VALUE find_common_field_value(const char *field, size_t flen) +{ + unsigned i; + struct common_field *cf = common_http_fields; + for(i = 0; i < ARRAY_SIZE(common_http_fields); i++, cf++) { + if (cf->len == flen && !memcmp(cf->name, field, flen)) + return cf->value; + } + return Qnil; +} + +void http_field(puma_parser* hp, const char *field, size_t flen, + const char *value, size_t vlen) +{ + VALUE f = Qnil; + VALUE v; + + VALIDATE_MAX_LENGTH(flen, FIELD_NAME); + VALIDATE_MAX_LENGTH(vlen, FIELD_VALUE); + + f = find_common_field_value(field, flen); + + if (f == Qnil) { + /* + * We got a strange header that we don't have a memoized value for. + * Fallback to creating a new string to use as a hash key. + */ + + size_t new_size = HTTP_PREFIX_LEN + flen; + assert(new_size < BUFFER_LEN); + + memcpy(hp->buf, HTTP_PREFIX, HTTP_PREFIX_LEN); + memcpy(hp->buf + HTTP_PREFIX_LEN, field, flen); + + f = rb_str_new(hp->buf, new_size); + } + + while (vlen > 0 && isspace(value[vlen - 1])) vlen--; + + /* check for duplicate header */ + v = rb_hash_aref(hp->request, f); + + if (v == Qnil) { + v = rb_str_new(value, vlen); + rb_hash_aset(hp->request, f, v); + } else { + /* if duplicate header, normalize to comma-separated values */ + rb_str_cat2(v, ", "); + rb_str_cat(v, value, vlen); + } +} + +void request_method(puma_parser* hp, const char *at, size_t length) +{ + VALUE val = Qnil; + + val = rb_str_new(at, length); + rb_hash_aset(hp->request, global_request_method, val); +} + +void request_uri(puma_parser* hp, const char *at, size_t length) +{ + VALUE val = Qnil; + + VALIDATE_MAX_LENGTH(length, REQUEST_URI); + + val = rb_str_new(at, length); + rb_hash_aset(hp->request, global_request_uri, val); +} + +void fragment(puma_parser* hp, const char *at, size_t length) +{ + VALUE val = Qnil; + + VALIDATE_MAX_LENGTH(length, FRAGMENT); + + val = rb_str_new(at, length); + rb_hash_aset(hp->request, global_fragment, val); +} + +void request_path(puma_parser* hp, const char *at, size_t length) +{ + VALUE val = Qnil; + + VALIDATE_MAX_LENGTH(length, REQUEST_PATH); + + val = rb_str_new(at, length); + rb_hash_aset(hp->request, global_request_path, val); +} + +void query_string(puma_parser* hp, const char *at, size_t length) +{ + VALUE val = Qnil; + + VALIDATE_MAX_LENGTH(length, QUERY_STRING); + + val = rb_str_new(at, length); + rb_hash_aset(hp->request, global_query_string, val); +} + +void server_protocol(puma_parser* hp, const char *at, size_t length) +{ + VALUE val = rb_str_new(at, length); + rb_hash_aset(hp->request, global_server_protocol, val); +} + +/** Finalizes the request header to have a bunch of stuff that's + needed. */ + +void header_done(puma_parser* hp, const char *at, size_t length) +{ + hp->body = rb_str_new(at, length); +} + + +void HttpParser_free(void *data) { + TRACE(); + + if(data) { + xfree(data); + } +} + +void HttpParser_mark(void *ptr) { + puma_parser *hp = ptr; + if(hp->request) rb_gc_mark(hp->request); + if(hp->body) rb_gc_mark(hp->body); +} + +const rb_data_type_t HttpParser_data_type = { + "HttpParser", + { HttpParser_mark, HttpParser_free, 0 }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, +}; + +VALUE HttpParser_alloc(VALUE klass) +{ + puma_parser *hp = ALLOC_N(puma_parser, 1); + TRACE(); + hp->http_field = http_field; + hp->request_method = request_method; + hp->request_uri = request_uri; + hp->fragment = fragment; + hp->request_path = request_path; + hp->query_string = query_string; + hp->server_protocol = server_protocol; + hp->header_done = header_done; + hp->request = Qnil; + + puma_parser_init(hp); + + return TypedData_Wrap_Struct(klass, &HttpParser_data_type, hp); +} + +/** + * call-seq: + * parser.new -> parser + * + * Creates a new parser. + */ +VALUE HttpParser_init(VALUE self) +{ + puma_parser *http = NULL; + DATA_GET(self, puma_parser, &HttpParser_data_type, http); + puma_parser_init(http); + + return self; +} + + +/** + * call-seq: + * parser.reset -> nil + * + * Resets the parser to it's initial state so that you can reuse it + * rather than making new ones. + */ +VALUE HttpParser_reset(VALUE self) +{ + puma_parser *http = NULL; + DATA_GET(self, puma_parser, &HttpParser_data_type, http); + puma_parser_init(http); + + return Qnil; +} + + +/** + * call-seq: + * parser.finish -> true/false + * + * Finishes a parser early which could put in a "good" or bad state. + * You should call reset after finish it or bad things will happen. + */ +VALUE HttpParser_finish(VALUE self) +{ + puma_parser *http = NULL; + DATA_GET(self, puma_parser, &HttpParser_data_type, http); + puma_parser_finish(http); + + return puma_parser_is_finished(http) ? Qtrue : Qfalse; +} + + +/** + * call-seq: + * parser.execute(req_hash, data, start) -> Integer + * + * Takes a Hash and a String of data, parses the String of data filling in the Hash + * returning an Integer to indicate how much of the data has been read. No matter + * what the return value, you should call HttpParser#finished? and HttpParser#error? + * to figure out if it's done parsing or there was an error. + * + * This function now throws an exception when there is a parsing error. This makes + * the logic for working with the parser much easier. You can still test for an + * error, but now you need to wrap the parser with an exception handling block. + * + * The third argument allows for parsing a partial request and then continuing + * the parsing from that position. It needs all of the original data as well + * so you have to append to the data buffer as you read. + */ +VALUE HttpParser_execute(VALUE self, VALUE req_hash, VALUE data, VALUE start) +{ + puma_parser *http = NULL; + int from = 0; + char *dptr = NULL; + long dlen = 0; + + DATA_GET(self, puma_parser, &HttpParser_data_type, http); + + from = FIX2INT(start); + dptr = rb_extract_chars(data, &dlen); + + if(from >= dlen) { + rb_free_chars(dptr); + rb_raise(eHttpParserError, "%s", "Requested start is after data buffer end."); + } else { + http->request = req_hash; + puma_parser_execute(http, dptr, dlen, from); + + rb_free_chars(dptr); + VALIDATE_MAX_LENGTH(puma_parser_nread(http), HEADER); + + if(puma_parser_has_error(http)) { + rb_raise(eHttpParserError, "%s", "Invalid HTTP format, parsing fails. Are you trying to open an SSL connection to a non-SSL Puma?"); + } else { + return INT2FIX(puma_parser_nread(http)); + } + } +} + + + +/** + * call-seq: + * parser.error? -> true/false + * + * Tells you whether the parser is in an error state. + */ +VALUE HttpParser_has_error(VALUE self) +{ + puma_parser *http = NULL; + DATA_GET(self, puma_parser, &HttpParser_data_type, http); + + return puma_parser_has_error(http) ? Qtrue : Qfalse; +} + + +/** + * call-seq: + * parser.finished? -> true/false + * + * Tells you whether the parser is finished or not and in a good state. + */ +VALUE HttpParser_is_finished(VALUE self) +{ + puma_parser *http = NULL; + DATA_GET(self, puma_parser, &HttpParser_data_type, http); + + return puma_parser_is_finished(http) ? Qtrue : Qfalse; +} + + +/** + * call-seq: + * parser.nread -> Integer + * + * Returns the amount of data processed so far during this processing cycle. It is + * set to 0 on initialize or reset calls and is incremented each time execute is called. + */ +VALUE HttpParser_nread(VALUE self) +{ + puma_parser *http = NULL; + DATA_GET(self, puma_parser, &HttpParser_data_type, http); + + return INT2FIX(http->nread); +} + +/** + * call-seq: + * parser.body -> nil or String + * + * If the request included a body, returns it. + */ +VALUE HttpParser_body(VALUE self) { + puma_parser *http = NULL; + DATA_GET(self, puma_parser, &HttpParser_data_type, http); + + return http->body; +} + +#ifdef HAVE_OPENSSL_BIO_H +void Init_mini_ssl(VALUE mod); +#endif + +void Init_puma_http11(void) +{ +#ifdef HAVE_RB_EXT_RACTOR_SAFE + rb_ext_ractor_safe(true); +#endif + + VALUE mPuma = rb_define_module("Puma"); + VALUE cHttpParser = rb_define_class_under(mPuma, "HttpParser", rb_cObject); + + DEF_GLOBAL(request_method, "REQUEST_METHOD"); + DEF_GLOBAL(request_uri, "REQUEST_URI"); + DEF_GLOBAL(fragment, "FRAGMENT"); + DEF_GLOBAL(query_string, "QUERY_STRING"); + DEF_GLOBAL(server_protocol, "SERVER_PROTOCOL"); + DEF_GLOBAL(request_path, "REQUEST_PATH"); + + eHttpParserError = rb_define_class_under(mPuma, "HttpParserError", rb_eStandardError); + rb_global_variable(&eHttpParserError); + + rb_define_alloc_func(cHttpParser, HttpParser_alloc); + rb_define_method(cHttpParser, "initialize", HttpParser_init, 0); + rb_define_method(cHttpParser, "reset", HttpParser_reset, 0); + rb_define_method(cHttpParser, "finish", HttpParser_finish, 0); + rb_define_method(cHttpParser, "execute", HttpParser_execute, 3); + rb_define_method(cHttpParser, "error?", HttpParser_has_error, 0); + rb_define_method(cHttpParser, "finished?", HttpParser_is_finished, 0); + rb_define_method(cHttpParser, "nread", HttpParser_nread, 0); + rb_define_method(cHttpParser, "body", HttpParser_body, 0); + init_common_fields(); + +#ifdef HAVE_OPENSSL_BIO_H + Init_mini_ssl(mPuma); +#endif +} diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma.rb new file mode 100644 index 00000000..ab2b2205 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true + +# Standard libraries +require 'socket' +require 'tempfile' +require 'uri' +require 'stringio' + +require 'thread' + +# use require, see https://github.com/puma/puma/pull/2381 +require 'puma/puma_http11' + +require_relative 'puma/detect' +require_relative 'puma/json_serialization' + +module Puma + # when Puma is loaded via `Puma::CLI`, all files are loaded via + # `require_relative`. The below are for non-standard loading + autoload :Const, "#{__dir__}/puma/const" + autoload :Server, "#{__dir__}/puma/server" + autoload :Launcher, "#{__dir__}/puma/launcher" + autoload :LogWriter, "#{__dir__}/puma/log_writer" + + # at present, MiniSSL::Engine is only defined in extension code (puma_http11), + # not in minissl.rb + HAS_SSL = const_defined?(:MiniSSL, false) && MiniSSL.const_defined?(:Engine, false) + + HAS_UNIX_SOCKET = Object.const_defined?(:UNIXSocket) && !IS_WINDOWS + + if HAS_SSL + require_relative 'puma/minissl' + else + module MiniSSL + # this class is defined so that it exists when Puma is compiled + # without ssl support, as Server and Reactor use it in rescue statements. + class SSLError < StandardError ; end + end + end + + def self.ssl? + HAS_SSL + end + + def self.abstract_unix_socket? + @abstract_unix ||= + if HAS_UNIX_SOCKET + begin + ::UNIXServer.new("\0puma.temp.unix").close + true + rescue ArgumentError # darwin + false + end + else + false + end + end + + # @!attribute [rw] stats_object= + def self.stats_object=(val) + @get_stats = val + end + + # @!attribute [rw] stats_object + def self.stats + Puma::JSONSerialization.generate @get_stats.stats + end + + # @!attribute [r] stats_hash + # @version 5.0.0 + def self.stats_hash + @get_stats.stats + end + + def self.set_thread_name(name) + Thread.current.name = "puma #{name}" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/app/status.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/app/status.rb new file mode 100644 index 00000000..53c012e2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/app/status.rb @@ -0,0 +1,96 @@ +# frozen_string_literal: true +require_relative '../json_serialization' + +module Puma + module App + # Check out {#call}'s source code to see what actions this web application + # can respond to. + class Status + OK_STATUS = '{ "status": "ok" }'.freeze + + # @param launcher [::Puma::Launcher] + # @param token [String, nil] the token used for authentication + # + def initialize(launcher, token = nil) + @launcher = launcher + @auth_token = token + end + + # most commands call methods in `::Puma::Launcher` based on command in + # `env['PATH_INFO']` + def call(env) + unless authenticate(env) + return rack_response(403, 'Invalid auth token', 'text/plain') + end + + # resp_type is processed by following case statement, return + # is a number (status) or a string used as the body of a 200 response + resp_type = + case env['PATH_INFO'][/\/([^\/]+)$/, 1] + when 'stop' + @launcher.stop ; 200 + + when 'halt' + @launcher.halt ; 200 + + when 'restart' + @launcher.restart ; 200 + + when 'phased-restart' + @launcher.phased_restart ? 200 : 404 + + when 'refork' + @launcher.refork ? 200 : 404 + + when 'reload-worker-directory' + @launcher.send(:reload_worker_directory) ? 200 : 404 + + when 'gc' + GC.start ; 200 + + when 'gc-stats' + Puma::JSONSerialization.generate GC.stat + + when 'stats' + Puma::JSONSerialization.generate @launcher.stats + + when 'thread-backtraces' + backtraces = [] + @launcher.thread_status do |name, backtrace| + backtraces << { name: name, backtrace: backtrace } + end + Puma::JSONSerialization.generate backtraces + + else + return rack_response(404, "Unsupported action", 'text/plain') + end + + case resp_type + when String + rack_response 200, resp_type + when 200 + rack_response 200, OK_STATUS + when 404 + str = env['PATH_INFO'][/\/(\S+)/, 1].tr '-', '_' + rack_response 404, "{ \"error\": \"#{str} not available\" }" + end + end + + private + + def authenticate(env) + return true unless @auth_token + env['QUERY_STRING'].to_s.split(/[&;]/).include? "token=#{@auth_token}" + end + + def rack_response(status, body, content_type='application/json') + headers = { + 'content-type' => content_type, + 'content-length' => body.bytesize.to_s + } + + [status, headers, [body]] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/binder.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/binder.rb new file mode 100644 index 00000000..bbcca5ba --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/binder.rb @@ -0,0 +1,509 @@ +# frozen_string_literal: true + +require 'uri' +require 'socket' + +require_relative 'const' +require_relative 'util' +require_relative 'configuration' + +module Puma + + if HAS_SSL + require_relative 'minissl' + require_relative 'minissl/context_builder' + end + + class Binder + include Puma::Const + + RACK_VERSION = [1,6].freeze + + def initialize(log_writer, conf = Configuration.new, env: ENV) + @log_writer = log_writer + @conf = conf + @listeners = [] + @inherited_fds = {} + @activated_sockets = {} + @unix_paths = [] + @env = env + + @proto_env = { + "rack.version".freeze => RACK_VERSION, + "rack.errors".freeze => log_writer.stderr, + "rack.multithread".freeze => conf.options[:max_threads] > 1, + "rack.multiprocess".freeze => conf.options[:workers] >= 1, + "rack.run_once".freeze => false, + RACK_URL_SCHEME => conf.options[:rack_url_scheme], + "SCRIPT_NAME".freeze => env['SCRIPT_NAME'] || "", + + # I'd like to set a default CONTENT_TYPE here but some things + # depend on their not being a default set and inferring + # it from the content. And so if i set it here, it won't + # infer properly. + + "QUERY_STRING".freeze => "", + SERVER_SOFTWARE => PUMA_SERVER_STRING, + GATEWAY_INTERFACE => CGI_VER + } + + @envs = {} + @ios = [] + end + + attr_reader :ios + + # @version 5.0.0 + attr_reader :activated_sockets, :envs, :inherited_fds, :listeners, :proto_env, :unix_paths + + # @version 5.0.0 + attr_writer :ios, :listeners + + def env(sock) + @envs.fetch(sock, @proto_env) + end + + def close + @ios.each { |i| i.close } + end + + # @!attribute [r] connected_ports + # @version 5.0.0 + def connected_ports + t = ios.map { |io| io.addr[1] }; t.uniq!; t + end + + # @version 5.0.0 + def create_inherited_fds(env_hash) + env_hash.select {|k,v| k =~ /PUMA_INHERIT_\d+/}.each do |_k, v| + fd, url = v.split(":", 2) + @inherited_fds[url] = fd.to_i + end.keys # pass keys back for removal + end + + # systemd socket activation. + # LISTEN_FDS = number of listening sockets. e.g. 2 means accept on 2 sockets w/descriptors 3 and 4. + # LISTEN_PID = PID of the service process, aka us + # @see https://www.freedesktop.org/software/systemd/man/systemd-socket-activate.html + # @version 5.0.0 + # + def create_activated_fds(env_hash) + @log_writer.debug "ENV['LISTEN_FDS'] #{@env['LISTEN_FDS'].inspect} env_hash['LISTEN_PID'] #{env_hash['LISTEN_PID'].inspect}" + return [] unless env_hash['LISTEN_FDS'] && env_hash['LISTEN_PID'].to_i == $$ + env_hash['LISTEN_FDS'].to_i.times do |index| + sock = TCPServer.for_fd(socket_activation_fd(index)) + key = begin # Try to parse as a path + [:unix, Socket.unpack_sockaddr_un(sock.getsockname)] + rescue ArgumentError # Try to parse as a port/ip + port, addr = Socket.unpack_sockaddr_in(sock.getsockname) + addr = "[#{addr}]" if addr&.include? ':' + [:tcp, addr, port] + end + @activated_sockets[key] = sock + @log_writer.debug "Registered #{key.join ':'} for activation from LISTEN_FDS" + end + ["LISTEN_FDS", "LISTEN_PID"] # Signal to remove these keys from ENV + end + + # Synthesize binds from systemd socket activation + # + # When systemd socket activation is enabled, it can be tedious to keep the + # binds in sync. This method can synthesize any binds based on the received + # activated sockets. Any existing matching binds will be respected. + # + # When only_matching is true in, all binds that do not match an activated + # socket is removed in place. + # + # It's a noop if no activated sockets were received. + def synthesize_binds_from_activated_fs(binds, only_matching) + return binds unless activated_sockets.any? + + activated_binds = [] + + activated_sockets.keys.each do |proto, addr, port| + if port + tcp_url = "#{proto}://#{addr}:#{port}" + ssl_url = "ssl://#{addr}:#{port}" + ssl_url_prefix = "#{ssl_url}?" + + existing = binds.find { |bind| bind == tcp_url || bind == ssl_url || bind.start_with?(ssl_url_prefix) } + + activated_binds << (existing || tcp_url) + else + # TODO: can there be a SSL bind without a port? + activated_binds << "#{proto}://#{addr}" + end + end + + if only_matching + activated_binds + else + binds | activated_binds + end + end + + def before_parse(&block) + @before_parse ||= [] + @before_parse << block if block + @before_parse + end + + def parse(binds, log_writer = nil, log_msg = 'Listening') + before_parse.each(&:call) + log_writer ||= @log_writer + binds.each do |str| + uri = URI.parse str + case uri.scheme + when "tcp" + if fd = @inherited_fds.delete(str) + io = inherit_tcp_listener uri.host, uri.port, fd + log_writer.log "* Inherited #{str}" + elsif sock = @activated_sockets.delete([ :tcp, uri.host, uri.port ]) + io = inherit_tcp_listener uri.host, uri.port, sock + log_writer.log "* Activated #{str}" + else + ios_len = @ios.length + params = Util.parse_query uri.query + + low_latency = params.key?('low_latency') && params['low_latency'] != 'false' + backlog = params.fetch('backlog', 1024).to_i + + io = add_tcp_listener uri.host, uri.port, low_latency, backlog + + @ios[ios_len..-1].each do |i| + addr = loc_addr_str i + log_writer.log "* #{log_msg} on http://#{addr}" + end + end + + @listeners << [str, io] if io + when "unix" + path = "#{uri.host}#{uri.path}".gsub("%20", " ") + abstract = false + if str.start_with? 'unix://@' + raise "OS does not support abstract UNIXSockets" unless Puma.abstract_unix_socket? + abstract = true + path = "@#{path}" + end + + if fd = @inherited_fds.delete(str) + @unix_paths << path unless abstract || File.exist?(path) + io = inherit_unix_listener path, fd + log_writer.log "* Inherited #{str}" + elsif sock = @activated_sockets.delete([ :unix, path ]) || + !abstract && @activated_sockets.delete([ :unix, File.realdirpath(path) ]) + @unix_paths << path unless abstract || File.exist?(path) + io = inherit_unix_listener path, sock + log_writer.log "* Activated #{str}" + else + umask = nil + mode = nil + backlog = 1024 + + if uri.query + params = Util.parse_query uri.query + if u = params['umask'] + # Use Integer() to respect the 0 prefix as octal + umask = Integer(u) + end + + if u = params['mode'] + mode = Integer('0'+u) + end + + if u = params['backlog'] + backlog = Integer(u) + end + end + + @unix_paths << path unless abstract || File.exist?(path) + io = add_unix_listener path, umask, mode, backlog + log_writer.log "* #{log_msg} on #{str}" + end + + @listeners << [str, io] + when "ssl" + cert_key = %w[cert key] + + raise "Puma compiled without SSL support" unless HAS_SSL + + params = Util.parse_query uri.query + + # If key and certs are not defined and localhost gem is required. + # localhost gem will be used for self signed + # Load localhost authority if not loaded. + # Ruby 3 `values_at` accepts an array, earlier do not + if params.values_at(*cert_key).all? { |v| v.to_s.empty? } + ctx = localhost_authority && localhost_authority_context + end + + ctx ||= + begin + # Extract cert_pem and key_pem from options[:store] if present + cert_key.each do |v| + if params[v]&.start_with?('store:') + index = Integer(params.delete(v).split('store:').last) + params["#{v}_pem"] = @conf.options[:store][index] + end + end + MiniSSL::ContextBuilder.new(params, @log_writer).context + end + + if fd = @inherited_fds.delete(str) + log_writer.log "* Inherited #{str}" + io = inherit_ssl_listener fd, ctx + elsif sock = @activated_sockets.delete([ :tcp, uri.host, uri.port ]) + io = inherit_ssl_listener sock, ctx + log_writer.log "* Activated #{str}" + else + ios_len = @ios.length + backlog = params.fetch('backlog', 1024).to_i + low_latency = params['low_latency'] != 'false' + io = add_ssl_listener uri.host, uri.port, ctx, low_latency, backlog + + @ios[ios_len..-1].each do |i| + addr = loc_addr_str i + log_writer.log "* #{log_msg} on ssl://#{addr}?#{uri.query}" + end + end + + @listeners << [str, io] if io + else + log_writer.error "Invalid URI: #{str}" + end + end + + # If we inherited fds but didn't use them (because of a + # configuration change), then be sure to close them. + @inherited_fds.each do |str, fd| + log_writer.log "* Closing unused inherited connection: #{str}" + + begin + IO.for_fd(fd).close + rescue SystemCallError + end + + # We have to unlink a unix socket path that's not being used + uri = URI.parse str + if uri.scheme == "unix" + path = "#{uri.host}#{uri.path}" + File.unlink path + end + end + + # Also close any unused activated sockets + unless @activated_sockets.empty? + fds = @ios.map(&:to_i) + @activated_sockets.each do |key, sock| + next if fds.include? sock.to_i + log_writer.log "* Closing unused activated socket: #{key.first}://#{key[1..-1].join ':'}" + begin + sock.close + rescue SystemCallError + end + # We have to unlink a unix socket path that's not being used + File.unlink key[1] if key.first == :unix + end + end + end + + def localhost_authority + @localhost_authority ||= Localhost::Authority.fetch if defined?(Localhost::Authority) && !Puma::IS_JRUBY + end + + def localhost_authority_context + return unless localhost_authority + + key_path, crt_path = if [:key_path, :certificate_path].all? { |m| localhost_authority.respond_to?(m) } + [localhost_authority.key_path, localhost_authority.certificate_path] + else + local_certificates_path = File.expand_path("~/.localhost") + [File.join(local_certificates_path, "localhost.key"), File.join(local_certificates_path, "localhost.crt")] + end + MiniSSL::ContextBuilder.new({ "key" => key_path, "cert" => crt_path }, @log_writer).context + end + + # Tell the server to listen on host +host+, port +port+. + # If +optimize_for_latency+ is true (the default) then clients connecting + # will be optimized for latency over throughput. + # + # +backlog+ indicates how many unaccepted connections the kernel should + # allow to accumulate before returning connection refused. + # + def add_tcp_listener(host, port, optimize_for_latency=true, backlog=1024) + if host == "localhost" + loopback_addresses.each do |addr| + add_tcp_listener addr, port, optimize_for_latency, backlog + end + return + end + + host = host[1..-2] if host&.start_with? '[' + tcp_server = TCPServer.new(host, port) + + if optimize_for_latency + tcp_server.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) + end + tcp_server.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true) + tcp_server.listen backlog + + @ios << tcp_server + tcp_server + end + + def inherit_tcp_listener(host, port, fd) + s = fd.kind_of?(::TCPServer) ? fd : ::TCPServer.for_fd(fd) + + @ios << s + s + end + + def add_ssl_listener(host, port, ctx, + optimize_for_latency=true, backlog=1024) + + raise "Puma compiled without SSL support" unless HAS_SSL + # Puma will try to use local authority context if context is supplied nil + ctx ||= localhost_authority_context + + if host == "localhost" + loopback_addresses.each do |addr| + add_ssl_listener addr, port, ctx, optimize_for_latency, backlog + end + return + end + + host = host[1..-2] if host&.start_with? '[' + s = TCPServer.new(host, port) + if optimize_for_latency + s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) + end + s.setsockopt(Socket::SOL_SOCKET,Socket::SO_REUSEADDR, true) + s.listen backlog + + ssl = MiniSSL::Server.new s, ctx + env = @proto_env.dup + env[HTTPS_KEY] = HTTPS + @envs[ssl] = env + + @ios << ssl + s + end + + def inherit_ssl_listener(fd, ctx) + raise "Puma compiled without SSL support" unless HAS_SSL + # Puma will try to use local authority context if context is supplied nil + ctx ||= localhost_authority_context + + s = fd.kind_of?(::TCPServer) ? fd : ::TCPServer.for_fd(fd) + + ssl = MiniSSL::Server.new(s, ctx) + + env = @proto_env.dup + env[HTTPS_KEY] = HTTPS + @envs[ssl] = env + + @ios << ssl + + s + end + + # Tell the server to listen on +path+ as a UNIX domain socket. + # + def add_unix_listener(path, umask=nil, mode=nil, backlog=1024) + # Let anyone connect by default + umask ||= 0 + + begin + old_mask = File.umask(umask) + + if File.exist? path + begin + old = UNIXSocket.new path + rescue SystemCallError, IOError + File.unlink path + else + old.close + raise "There is already a server bound to: #{path}" + end + end + s = UNIXServer.new path.sub(/\A@/, "\0") # check for abstract UNIXSocket + s.listen backlog + @ios << s + ensure + File.umask old_mask + end + + if mode + File.chmod mode, path + end + + env = @proto_env.dup + env[REMOTE_ADDR] = "127.0.0.1" + @envs[s] = env + + s + end + + def inherit_unix_listener(path, fd) + s = fd.kind_of?(::TCPServer) ? fd : ::UNIXServer.for_fd(fd) + + @ios << s + + env = @proto_env.dup + env[REMOTE_ADDR] = "127.0.0.1" + @envs[s] = env + + s + end + + def close_listeners + @listeners.each do |l, io| + begin + io.close unless io.closed? + uri = URI.parse l + next unless uri.scheme == 'unix' + unix_path = "#{uri.host}#{uri.path}" + File.unlink unix_path if @unix_paths.include?(unix_path) && File.exist?(unix_path) + rescue Errno::EBADF + end + end + end + + def redirects_for_restart + redirects = @listeners.map { |a| [a[1].to_i, a[1].to_i] }.to_h + redirects[:close_others] = true + redirects + end + + # @version 5.0.0 + def redirects_for_restart_env + @listeners.each_with_object({}).with_index do |(listen, memo), i| + memo["PUMA_INHERIT_#{i}"] = "#{listen[1].to_i}:#{listen[0]}" + end + end + + private + + # @!attribute [r] loopback_addresses + def loopback_addresses + t = Socket.ip_address_list.select do |addrinfo| + addrinfo.ipv6_loopback? || addrinfo.ipv4_loopback? + end + t.map! { |addrinfo| addrinfo.ip_address }; t.uniq!; t + end + + def loc_addr_str(io) + loc_addr = io.to_io.local_address + if loc_addr.ipv6? + "[#{loc_addr.ip_unpack[0]}]:#{loc_addr.ip_unpack[1]}" + else + loc_addr.ip_unpack.join(':') + end + end + + # @version 5.0.0 + def socket_activation_fd(int) + int + 3 # 3 is the magic number you add to follow the SA protocol + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/cli.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/cli.rb new file mode 100644 index 00000000..8f0c7a8f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/cli.rb @@ -0,0 +1,247 @@ +# frozen_string_literal: true + +require 'optparse' +require 'uri' + +require_relative '../puma' +require_relative 'configuration' +require_relative 'launcher' +require_relative 'const' +require_relative 'log_writer' + +module Puma + class << self + # The CLI exports a Puma::Configuration instance here to allow + # apps to pick it up. An app must load this object conditionally + # because it is not set if the app is launched via any mechanism + # other than the CLI class. + attr_accessor :cli_config + end + + # Handles invoke a Puma::Server in a command line style. + # + class CLI + # Create a new CLI object using +argv+ as the command line + # arguments. + # + def initialize(argv, log_writer = LogWriter.stdio, events = Events.new, env: ENV) + @debug = false + @argv = argv.dup + @log_writer = log_writer + @events = events + + @conf = nil + + @stdout = nil + @stderr = nil + @append = false + + @control_url = nil + @control_options = {} + + setup_options env + + begin + @parser.parse! @argv + + if file = @argv.shift + @conf.configure do |user_config, file_config| + file_config.rackup file + end + end + rescue UnsupportedOption + exit 1 + end + + @conf.configure do |user_config, file_config| + if @stdout || @stderr + user_config.stdout_redirect @stdout, @stderr, @append + end + + if @control_url + user_config.activate_control_app @control_url, @control_options + end + end + + @launcher = Puma::Launcher.new(@conf, env: ENV, log_writer: @log_writer, events: @events, argv: argv) + end + + attr_reader :launcher + + # Parse the options, load the rackup, start the server and wait + # for it to finish. + # + def run + @launcher.run + end + + private + def unsupported(str) + @log_writer.error(str) + raise UnsupportedOption + end + + def configure_control_url(command_line_arg) + if command_line_arg + @control_url = command_line_arg + elsif Puma.jruby? + unsupported "No default url available on JRuby" + end + end + + # Build the OptionParser object to handle the available options. + # + + def setup_options(env = ENV) + @conf = Configuration.new({}, {events: @events}, env) do |user_config, file_config| + @parser = OptionParser.new do |o| + o.on "-b", "--bind URI", "URI to bind to (tcp://, unix://, ssl://)" do |arg| + user_config.bind arg + end + + o.on "--bind-to-activated-sockets [only]", "Bind to all activated sockets" do |arg| + user_config.bind_to_activated_sockets(arg || true) + end + + o.on "-C", "--config PATH", "Load PATH as a config file" do |arg| + file_config.load arg + end + + # Identical to supplying --config "-", but more semantic + o.on "--no-config", "Prevent Puma from searching for a config file" do |arg| + file_config.load "-" + end + + o.on "--control-url URL", "The bind url to use for the control server. Use 'auto' to use temp unix server" do |arg| + configure_control_url(arg) + end + + o.on "--control-token TOKEN", + "The token to use as authentication for the control server" do |arg| + @control_options[:auth_token] = arg + end + + o.on "--debug", "Log lowlevel debugging information" do + user_config.debug + end + + o.on "--dir DIR", "Change to DIR before starting" do |d| + user_config.directory d + end + + o.on "-e", "--environment ENVIRONMENT", + "The environment to run the Rack app on (default development)" do |arg| + user_config.environment arg + end + + o.on "-f", "--fork-worker=[REQUESTS]", OptionParser::DecimalInteger, + "Fork new workers from existing worker. Cluster mode only", + "Auto-refork after REQUESTS (default 1000)" do |*args| + user_config.fork_worker(*args.compact) + end + + o.on "-I", "--include PATH", "Specify $LOAD_PATH directories" do |arg| + $LOAD_PATH.unshift(*arg.split(':')) + end + + o.on "--idle-timeout SECONDS", "Number of seconds until the next request before automatic shutdown" do |arg| + user_config.idle_timeout arg + end + + o.on "-p", "--port PORT", "Define the TCP port to bind to", + "Use -b for more advanced options" do |arg| + user_config.bind "tcp://#{Configuration::DEFAULTS[:tcp_host]}:#{arg}" + end + + o.on "--pidfile PATH", "Use PATH as a pidfile" do |arg| + user_config.pidfile arg + end + + o.on "--plugin PLUGIN", "Load the given PLUGIN. Can be used multiple times to load multiple plugins." do |arg| + user_config.plugin arg + end + + o.on "--preload", "Preload the app. Cluster mode only" do + user_config.preload_app! + end + + o.on "--prune-bundler", "Prune out the bundler env if possible" do + user_config.prune_bundler + end + + o.on "--extra-runtime-dependencies GEM1,GEM2", "Defines any extra needed gems when using --prune-bundler" do |arg| + user_config.extra_runtime_dependencies arg.split(',') + end + + o.on "-q", "--quiet", "Do not log requests internally (default true)" do + user_config.quiet + end + + o.on "-v", "--log-requests", "Log requests as they occur" do + user_config.log_requests + end + + o.on "-R", "--restart-cmd CMD", + "The puma command to run during a hot restart", + "Default: inferred" do |cmd| + user_config.restart_command cmd + end + + o.on "-s", "--silent", "Do not log prompt messages other than errors" do + @log_writer = LogWriter.new(NullIO.new, $stderr) + end + + o.on "-S", "--state PATH", "Where to store the state details" do |arg| + user_config.state_path arg + end + + o.on '-t', '--threads INT', "min:max threads to use (default 0:16)" do |arg| + min, max = arg.split(":") + if max + user_config.threads min, max + else + user_config.threads min, min + end + end + + o.on "--early-hints", "Enable early hints support" do + user_config.early_hints + end + + o.on "-V", "--version", "Print the version information" do + puts "puma version #{Puma::Const::VERSION}" + exit 0 + end + + o.on "-w", "--workers COUNT", + "Activate cluster mode: How many worker processes to create" do |arg| + user_config.workers arg + end + + o.on "--tag NAME", "Additional text to display in process listing" do |arg| + user_config.tag arg + end + + o.on "--redirect-stdout FILE", "Redirect STDOUT to a specific file" do |arg| + @stdout = arg.to_s + end + + o.on "--redirect-stderr FILE", "Redirect STDERR to a specific file" do |arg| + @stderr = arg.to_s + end + + o.on "--[no-]redirect-append", "Append to redirected files" do |val| + @append = val + end + + o.banner = "puma " + + o.on_tail "-h", "--help", "Show help" do + $stdout.puts o + exit 0 + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/client.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/client.rb new file mode 100644 index 00000000..069d753b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/client.rb @@ -0,0 +1,682 @@ +# frozen_string_literal: true + +class IO + # We need to use this for a jruby work around on both 1.8 and 1.9. + # So this either creates the constant (on 1.8), or harmlessly + # reopens it (on 1.9). + module WaitReadable + end +end + +require_relative 'detect' +require_relative 'io_buffer' +require 'tempfile' + +if Puma::IS_JRUBY + # We have to work around some OpenSSL buffer/io-readiness bugs + # so we pull it in regardless of if the user is binding + # to an SSL socket + require 'openssl' +end + +module Puma + + class ConnectionError < RuntimeError; end + + class HttpParserError501 < IOError; end + + #———————————————————————— DO NOT USE — this class is for internal use only ——— + + + # An instance of this class represents a unique request from a client. + # For example, this could be a web request from a browser or from CURL. + # + # An instance of `Puma::Client` can be used as if it were an IO object + # by the reactor. The reactor is expected to call `#to_io` + # on any non-IO objects it polls. For example, nio4r internally calls + # `IO::try_convert` (which may call `#to_io`) when a new socket is + # registered. + # + # Instances of this class are responsible for knowing if + # the header and body are fully buffered via the `try_to_finish` method. + # They can be used to "time out" a response via the `timeout_at` reader. + # + class Client # :nodoc: + + # this tests all values but the last, which must be chunked + ALLOWED_TRANSFER_ENCODING = %w[compress deflate gzip].freeze + + # chunked body validation + CHUNK_SIZE_INVALID = /[^\h]/.freeze + CHUNK_VALID_ENDING = Const::LINE_END + CHUNK_VALID_ENDING_SIZE = CHUNK_VALID_ENDING.bytesize + + # The maximum number of bytes we'll buffer looking for a valid + # chunk header. + MAX_CHUNK_HEADER_SIZE = 4096 + + # The maximum amount of excess data the client sends + # using chunk size extensions before we abort the connection. + MAX_CHUNK_EXCESS = 16 * 1024 + + # Content-Length header value validation + CONTENT_LENGTH_VALUE_INVALID = /[^\d]/.freeze + + TE_ERR_MSG = 'Invalid Transfer-Encoding' + + # The object used for a request with no body. All requests with + # no body share this one object since it has no state. + EmptyBody = NullIO.new + + include Puma::Const + + def initialize(io, env=nil) + @io = io + @to_io = io.to_io + @io_buffer = IOBuffer.new + @proto_env = env + @env = env&.dup + + @parser = HttpParser.new + @parsed_bytes = 0 + @read_header = true + @read_proxy = false + @ready = false + + @body = nil + @body_read_start = nil + @buffer = nil + @tempfile = nil + + @timeout_at = nil + + @requests_served = 0 + @hijacked = false + + @http_content_length_limit = nil + @http_content_length_limit_exceeded = false + + @peerip = nil + @peer_family = nil + @listener = nil + @remote_addr_header = nil + @expect_proxy_proto = false + + @body_remain = 0 + + @in_last_chunk = false + + # need unfrozen ASCII-8BIT, +'' is UTF-8 + @read_buffer = String.new # rubocop: disable Performance/UnfreezeString + end + + attr_reader :env, :to_io, :body, :io, :timeout_at, :ready, :hijacked, + :tempfile, :io_buffer, :http_content_length_limit_exceeded + + attr_writer :peerip, :http_content_length_limit + + attr_accessor :remote_addr_header, :listener + + # Remove in Puma 7? + def closed? + @to_io.closed? + end + + # Test to see if io meets a bare minimum of functioning, @to_io needs to be + # used for MiniSSL::Socket + def io_ok? + @to_io.is_a?(::BasicSocket) && !closed? + end + + # @!attribute [r] inspect + def inspect + "#" + end + + # For the hijack protocol (allows us to just put the Client object + # into the env) + def call + @hijacked = true + env[HIJACK_IO] ||= @io + end + + # @!attribute [r] in_data_phase + def in_data_phase + !(@read_header || @read_proxy) + end + + def set_timeout(val) + @timeout_at = Process.clock_gettime(Process::CLOCK_MONOTONIC) + val + end + + # Number of seconds until the timeout elapses. + def timeout + [@timeout_at - Process.clock_gettime(Process::CLOCK_MONOTONIC), 0].max + end + + def reset(fast_check=true) + @parser.reset + @io_buffer.reset + @read_header = true + @read_proxy = !!@expect_proxy_proto + @env = @proto_env.dup + @parsed_bytes = 0 + @ready = false + @body_remain = 0 + @peerip = nil if @remote_addr_header + @in_last_chunk = false + @http_content_length_limit_exceeded = false + + if @buffer + return false unless try_to_parse_proxy_protocol + + @parsed_bytes = @parser.execute(@env, @buffer, @parsed_bytes) + + if @parser.finished? + return setup_body + elsif @parsed_bytes >= MAX_HEADER + raise HttpParserError, + "HEADER is longer than allowed, aborting client early." + end + + return false + else + begin + if fast_check && @to_io.wait_readable(FAST_TRACK_KA_TIMEOUT) + return try_to_finish + end + rescue IOError + # swallow it + end + end + end + + def close + tempfile_close + begin + @io.close + rescue IOError, Errno::EBADF + Puma::Util.purge_interrupt_queue + end + end + + def tempfile_close + tf_path = @tempfile&.path + @tempfile&.close + File.unlink(tf_path) if tf_path + @tempfile = nil + @body = nil + rescue Errno::ENOENT, IOError + end + + # If necessary, read the PROXY protocol from the buffer. Returns + # false if more data is needed. + def try_to_parse_proxy_protocol + if @read_proxy + if @expect_proxy_proto == :v1 + if @buffer.include? "\r\n" + if md = PROXY_PROTOCOL_V1_REGEX.match(@buffer) + if md[1] + @peerip = md[1].split(" ")[0] + end + @buffer = md.post_match + end + # if the buffer has a \r\n but doesn't have a PROXY protocol + # request, this is just HTTP from a non-PROXY client; move on + @read_proxy = false + return @buffer.size > 0 + else + return false + end + end + end + true + end + + def try_to_finish + if env[CONTENT_LENGTH] && above_http_content_limit(env[CONTENT_LENGTH].to_i) + @http_content_length_limit_exceeded = true + end + + if @http_content_length_limit_exceeded + @buffer = nil + @body = EmptyBody + set_ready + return true + end + + return read_body if in_data_phase + + data = nil + begin + data = @io.read_nonblock(CHUNK_SIZE) + rescue IO::WaitReadable + return false + rescue EOFError + # Swallow error, don't log + rescue SystemCallError, IOError + raise ConnectionError, "Connection error detected during read" + end + + # No data means a closed socket + unless data + @buffer = nil + set_ready + raise EOFError + end + + if @buffer + @buffer << data + else + @buffer = data + end + + return false unless try_to_parse_proxy_protocol + + @parsed_bytes = @parser.execute(@env, @buffer, @parsed_bytes) + + if @parser.finished? && above_http_content_limit(@parser.body.bytesize) + @http_content_length_limit_exceeded = true + end + + if @parser.finished? + return setup_body + elsif @parsed_bytes >= MAX_HEADER + raise HttpParserError, + "HEADER is longer than allowed, aborting client early." + end + + false + end + + def eagerly_finish + return true if @ready + return false unless @to_io.wait_readable(0) + try_to_finish + end + + def finish(timeout) + return if @ready + @to_io.wait_readable(timeout) || timeout! until try_to_finish + end + + def timeout! + write_error(408) if in_data_phase + raise ConnectionError + end + + def write_error(status_code) + begin + @io << ERROR_RESPONSE[status_code] + rescue StandardError + end + end + + def peerip + return @peerip if @peerip + + if @remote_addr_header + hdr = (@env[@remote_addr_header] || @io.peeraddr.last).split(/[\s,]/).first + @peerip = hdr + return hdr + end + + @peerip ||= @io.peeraddr.last + end + + def peer_family + return @peer_family if @peer_family + + @peer_family ||= begin + @io.local_address.afamily + rescue + Socket::AF_INET + end + end + + # Returns true if the persistent connection can be closed immediately + # without waiting for the configured idle/shutdown timeout. + # @version 5.0.0 + # + def can_close? + # Allow connection to close if we're not in the middle of parsing a request. + @parsed_bytes == 0 + end + + def expect_proxy_proto=(val) + if val + if @read_header + @read_proxy = true + end + else + @read_proxy = false + end + @expect_proxy_proto = val + end + + private + + def setup_body + @body_read_start = Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond) + + if @env[HTTP_EXPECT] == CONTINUE + # TODO allow a hook here to check the headers before + # going forward + @io << HTTP_11_100 + @io.flush + end + + @read_header = false + + body = @parser.body + + te = @env[TRANSFER_ENCODING2] + if te + te_lwr = te.downcase + if te.include? ',' + te_ary = te_lwr.split ',' + te_count = te_ary.count CHUNKED + te_valid = te_ary[0..-2].all? { |e| ALLOWED_TRANSFER_ENCODING.include? e } + if te_ary.last == CHUNKED && te_count == 1 && te_valid + @env.delete TRANSFER_ENCODING2 + return setup_chunked_body body + elsif te_count >= 1 + raise HttpParserError , "#{TE_ERR_MSG}, multiple chunked: '#{te}'" + elsif !te_valid + raise HttpParserError501, "#{TE_ERR_MSG}, unknown value: '#{te}'" + end + elsif te_lwr == CHUNKED + @env.delete TRANSFER_ENCODING2 + return setup_chunked_body body + elsif ALLOWED_TRANSFER_ENCODING.include? te_lwr + raise HttpParserError , "#{TE_ERR_MSG}, single value must be chunked: '#{te}'" + else + raise HttpParserError501 , "#{TE_ERR_MSG}, unknown value: '#{te}'" + end + end + + @chunked_body = false + + cl = @env[CONTENT_LENGTH] + + if cl + # cannot contain characters that are not \d, or be empty + if CONTENT_LENGTH_VALUE_INVALID.match?(cl) || cl.empty? + raise HttpParserError, "Invalid Content-Length: #{cl.inspect}" + end + else + @buffer = body.empty? ? nil : body + @body = EmptyBody + set_ready + return true + end + + content_length = cl.to_i + + remain = content_length - body.bytesize + + if remain <= 0 + # Part of the body is a pipelined request OR garbage. We'll deal with that later. + if content_length == 0 + @body = EmptyBody + if body.empty? + @buffer = nil + else + @buffer = body + end + elsif remain == 0 + @body = StringIO.new body + @buffer = nil + else + @body = StringIO.new(body[0,content_length]) + @buffer = body[content_length..-1] + end + set_ready + return true + end + + if remain > MAX_BODY + @body = Tempfile.create(Const::PUMA_TMP_BASE) + File.unlink @body.path unless IS_WINDOWS + @body.binmode + @tempfile = @body + else + # The body[0,0] trick is to get an empty string in the same + # encoding as body. + @body = StringIO.new body[0,0] + end + + @body.write body + + @body_remain = remain + + false + end + + def read_body + if @chunked_body + return read_chunked_body + end + + # Read an odd sized chunk so we can read even sized ones + # after this + remain = @body_remain + + if remain > CHUNK_SIZE + want = CHUNK_SIZE + else + want = remain + end + + begin + chunk = @io.read_nonblock(want, @read_buffer) + rescue IO::WaitReadable + return false + rescue SystemCallError, IOError + raise ConnectionError, "Connection error detected during read" + end + + # No chunk means a closed socket + unless chunk + @body.close + @buffer = nil + set_ready + raise EOFError + end + + remain -= @body.write(chunk) + + if remain <= 0 + @body.rewind + @buffer = nil + set_ready + return true + end + + @body_remain = remain + + false + end + + def read_chunked_body + while true + begin + chunk = @io.read_nonblock(CHUNK_SIZE, @read_buffer) + rescue IO::WaitReadable + return false + rescue SystemCallError, IOError + raise ConnectionError, "Connection error detected during read" + end + + # No chunk means a closed socket + unless chunk + @body.close + @buffer = nil + set_ready + raise EOFError + end + + if decode_chunk(chunk) + @env[CONTENT_LENGTH] = @chunked_content_length.to_s + return true + end + end + end + + def setup_chunked_body(body) + @chunked_body = true + @partial_part_left = 0 + @prev_chunk = "" + @excess_cr = 0 + + @body = Tempfile.create(Const::PUMA_TMP_BASE) + File.unlink @body.path unless IS_WINDOWS + @body.binmode + @tempfile = @body + @chunked_content_length = 0 + + if decode_chunk(body) + @env[CONTENT_LENGTH] = @chunked_content_length.to_s + return true + end + end + + # @version 5.0.0 + def write_chunk(str) + @chunked_content_length += @body.write(str) + end + + def decode_chunk(chunk) + if @partial_part_left > 0 + if @partial_part_left <= chunk.size + if @partial_part_left > 2 + write_chunk(chunk[0..(@partial_part_left-3)]) # skip the \r\n + end + chunk = chunk[@partial_part_left..-1] + @partial_part_left = 0 + else + if @partial_part_left > 2 + if @partial_part_left == chunk.size + 1 + # Don't include the last \r + write_chunk(chunk[0..(@partial_part_left-3)]) + else + # don't include the last \r\n + write_chunk(chunk) + end + end + @partial_part_left -= chunk.size + return false + end + end + + if @prev_chunk.empty? + io = StringIO.new(chunk) + else + io = StringIO.new(@prev_chunk+chunk) + @prev_chunk = "" + end + + while !io.eof? + line = io.gets + if line.end_with?(CHUNK_VALID_ENDING) + # Puma doesn't process chunk extensions, but should parse if they're + # present, which is the reason for the semicolon regex + chunk_hex = line.strip[/\A[^;]+/] + if CHUNK_SIZE_INVALID.match? chunk_hex + raise HttpParserError, "Invalid chunk size: '#{chunk_hex}'" + end + len = chunk_hex.to_i(16) + if len == 0 + @in_last_chunk = true + @body.rewind + rest = io.read + if rest.bytesize < CHUNK_VALID_ENDING_SIZE + @buffer = nil + @partial_part_left = CHUNK_VALID_ENDING_SIZE - rest.bytesize + return false + else + # if the next character is a CRLF, set buffer to everything after that CRLF + start_of_rest = if rest.start_with?(CHUNK_VALID_ENDING) + CHUNK_VALID_ENDING_SIZE + else # we have started a trailer section, which we do not support. skip it! + rest.index(CHUNK_VALID_ENDING*2) + CHUNK_VALID_ENDING_SIZE*2 + end + + @buffer = rest[start_of_rest..-1] + @buffer = nil if @buffer.empty? + set_ready + return true + end + end + + # Track the excess as a function of the size of the + # header vs the size of the actual data. Excess can + # go negative (and is expected to) when the body is + # significant. + # The additional of chunk_hex.size and 2 compensates + # for a client sending 1 byte in a chunked body over + # a long period of time, making sure that that client + # isn't accidentally eventually punished. + @excess_cr += (line.size - len - chunk_hex.size - 2) + + if @excess_cr >= MAX_CHUNK_EXCESS + raise HttpParserError, "Maximum chunk excess detected" + end + + len += 2 + + part = io.read(len) + + unless part + @partial_part_left = len + next + end + + got = part.size + + case + when got == len + # proper chunked segment must end with "\r\n" + if part.end_with? CHUNK_VALID_ENDING + write_chunk(part[0..-3]) # to skip the ending \r\n + else + raise HttpParserError, "Chunk size mismatch" + end + when got <= len - 2 + write_chunk(part) + @partial_part_left = len - part.size + when got == len - 1 # edge where we get just \r but not \n + write_chunk(part[0..-2]) + @partial_part_left = len - part.size + end + else + if @prev_chunk.size + line.size >= MAX_CHUNK_HEADER_SIZE + raise HttpParserError, "maximum size of chunk header exceeded" + end + + @prev_chunk = line + return false + end + end + + if @in_last_chunk + set_ready + true + else + false + end + end + + def set_ready + if @body_read_start + @env['puma.request_body_wait'] = Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_millisecond) - @body_read_start + end + @requests_served += 1 + @ready = true + end + + def above_http_content_limit(value) + @http_content_length_limit&.< value + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/cluster.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/cluster.rb new file mode 100644 index 00000000..e36ad0a9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/cluster.rb @@ -0,0 +1,620 @@ +# frozen_string_literal: true + +require_relative 'runner' +require_relative 'util' +require_relative 'plugin' +require_relative 'cluster/worker_handle' +require_relative 'cluster/worker' + +module Puma + # This class is instantiated by the `Puma::Launcher` and used + # to boot and serve a Ruby application when puma "workers" are needed + # i.e. when using multi-processes. For example `$ puma -w 5` + # + # An instance of this class will spawn the number of processes passed in + # via the `spawn_workers` method call. Each worker will have it's own + # instance of a `Puma::Server`. + class Cluster < Runner + def initialize(launcher) + super(launcher) + + @phase = 0 + @workers = [] + @next_check = Time.now + + @phased_restart = false + end + + # Returns the list of cluster worker handles. + # @return [Array] + attr_reader :workers + + def stop_workers + log "- Gracefully shutting down workers..." + @workers.each { |x| x.term } + + begin + loop do + wait_workers + break if @workers.reject {|w| w.pid.nil?}.empty? + sleep 0.2 + end + rescue Interrupt + log "! Cancelled waiting for workers" + end + end + + def start_phased_restart + @events.fire_on_restart! + @phase += 1 + log "- Starting phased worker restart, phase: #{@phase}" + + # Be sure to change the directory again before loading + # the app. This way we can pick up new code. + dir = @launcher.restart_dir + log "+ Changing to #{dir}" + Dir.chdir dir + end + + def redirect_io + super + + @workers.each { |x| x.hup } + end + + def spawn_workers + diff = @options[:workers] - @workers.size + return if diff < 1 + + master = Process.pid + if @options[:fork_worker] + @fork_writer << "-1\n" + end + + diff.times do + idx = next_worker_index + + if @options[:fork_worker] && idx != 0 + @fork_writer << "#{idx}\n" + pid = nil + else + pid = spawn_worker(idx, master) + end + + debug "Spawned worker: #{pid}" + @workers << WorkerHandle.new(idx, pid, @phase, @options) + end + + if @options[:fork_worker] && all_workers_in_phase? + @fork_writer << "0\n" + + if worker_at(0).phase > 0 + @fork_writer << "-2\n" + end + end + end + + # @version 5.0.0 + def spawn_worker(idx, master) + @config.run_hooks(:before_worker_fork, idx, @log_writer) + + pid = fork { worker(idx, master) } + if !pid + log "! Complete inability to spawn new workers detected" + log "! Seppuku is the only choice." + exit! 1 + end + + @config.run_hooks(:after_worker_fork, idx, @log_writer) + pid + end + + def cull_workers + diff = @workers.size - @options[:workers] + return if diff < 1 + debug "Culling #{diff} workers" + + workers = workers_to_cull(diff) + debug "Workers to cull: #{workers.inspect}" + + workers.each do |worker| + log "- Worker #{worker.index} (PID: #{worker.pid}) terminating" + worker.term + end + end + + def workers_to_cull(diff) + workers = @workers.sort_by(&:started_at) + + # In fork_worker mode, worker 0 acts as our master process. + # We should avoid culling it to preserve copy-on-write memory gains. + workers.reject! { |w| w.index == 0 } if @options[:fork_worker] + + workers[cull_start_index(diff), diff] + end + + def cull_start_index(diff) + case @options[:worker_culling_strategy] + when :oldest + 0 + else # :youngest + -diff + end + end + + # @!attribute [r] next_worker_index + def next_worker_index + occupied_positions = @workers.map(&:index) + idx = 0 + idx += 1 until !occupied_positions.include?(idx) + idx + end + + def worker_at(idx) + @workers.find { |w| w.index == idx } + end + + def all_workers_booted? + @workers.count { |w| !w.booted? } == 0 + end + + def all_workers_in_phase? + @workers.all? { |w| w.phase == @phase } + end + + def all_workers_idle_timed_out? + (@workers.map(&:pid) - idle_timed_out_worker_pids).empty? + end + + def check_workers + return if @next_check >= Time.now + + @next_check = Time.now + @options[:worker_check_interval] + + timeout_workers + wait_workers + cull_workers + spawn_workers + + if all_workers_booted? + # If we're running at proper capacity, check to see if + # we need to phase any workers out (which will restart + # in the right phase). + # + w = @workers.find { |x| x.phase != @phase } + + if w + log "- Stopping #{w.pid} for phased upgrade..." + unless w.term? + w.term + log "- #{w.signal} sent to #{w.pid}..." + end + end + end + + t = @workers.reject(&:term?) + t.map!(&:ping_timeout) + + @next_check = [t.min, @next_check].compact.min + end + + def worker(index, master) + @workers = [] + + @master_read.close + @suicide_pipe.close + @fork_writer.close + + pipes = { check_pipe: @check_pipe, worker_write: @worker_write } + if @options[:fork_worker] + pipes[:fork_pipe] = @fork_pipe + pipes[:wakeup] = @wakeup + end + + server = start_server if preload? + new_worker = Worker.new index: index, + master: master, + launcher: @launcher, + pipes: pipes, + server: server + new_worker.run + end + + def restart + @restart = true + stop + end + + def phased_restart(refork = false) + return false if @options[:preload_app] && !refork + + @phased_restart = true + wakeup! + + true + end + + def stop + @status = :stop + wakeup! + end + + def stop_blocked + @status = :stop if @status == :run + wakeup! + @control&.stop true + Process.waitall + end + + def halt + @status = :halt + wakeup! + end + + def reload_worker_directory + dir = @launcher.restart_dir + log "+ Changing to #{dir}" + Dir.chdir dir + end + + # Inside of a child process, this will return all zeroes, as @workers is only populated in + # the master process. + # @!attribute [r] stats + def stats + old_worker_count = @workers.count { |w| w.phase != @phase } + worker_status = @workers.map do |w| + { + started_at: utc_iso8601(w.started_at), + pid: w.pid, + index: w.index, + phase: w.phase, + booted: w.booted?, + last_checkin: utc_iso8601(w.last_checkin), + last_status: w.last_status, + } + end + + { + started_at: utc_iso8601(@started_at), + workers: @workers.size, + phase: @phase, + booted_workers: worker_status.count { |w| w[:booted] }, + old_workers: old_worker_count, + worker_status: worker_status, + }.merge(super) + end + + def preload? + @options[:preload_app] + end + + # @version 5.0.0 + def fork_worker! + if (worker = worker_at 0) + worker.phase += 1 + end + phased_restart(true) + end + + # We do this in a separate method to keep the lambda scope + # of the signals handlers as small as possible. + def setup_signals + if @options[:fork_worker] + Signal.trap "SIGURG" do + fork_worker! + end + + # Auto-fork after the specified number of requests. + if (fork_requests = @options[:fork_worker].to_i) > 0 + @events.register(:ping!) do |w| + fork_worker! if w.index == 0 && + w.phase == 0 && + w.last_status[:requests_count] >= fork_requests + end + end + end + + Signal.trap "SIGCHLD" do + wakeup! + end + + Signal.trap "TTIN" do + @options[:workers] += 1 + wakeup! + end + + Signal.trap "TTOU" do + @options[:workers] -= 1 if @options[:workers] >= 2 + wakeup! + end + + master_pid = Process.pid + + Signal.trap "SIGTERM" do + # The worker installs their own SIGTERM when booted. + # Until then, this is run by the worker and the worker + # should just exit if they get it. + if Process.pid != master_pid + log "Early termination of worker" + exit! 0 + else + @launcher.close_binder_listeners + + stop_workers + stop + @events.fire_on_stopped! + raise(SignalException, "SIGTERM") if @options[:raise_exception_on_sigterm] + exit 0 # Clean exit, workers were stopped + end + end + end + + def run + @status = :run + + output_header "cluster" + + # This is aligned with the output from Runner, see Runner#output_header + log "* Workers: #{@options[:workers]}" + + if preload? + # Threads explicitly marked as fork safe will be ignored. Used in Rails, + # but may be used by anyone. Note that we need to explicit + # Process::Waiter check here because there's a bug in Ruby 2.6 and below + # where calling thread_variable_get on a Process::Waiter will segfault. + # We can drop that clause once those versions of Ruby are no longer + # supported. + fork_safe = ->(t) { !t.is_a?(Process::Waiter) && t.thread_variable_get(:fork_safe) } + + before = Thread.list.reject(&fork_safe) + + log "* Restarts: (\u2714) hot (\u2716) phased" + log "* Preloading application" + load_and_bind + + after = Thread.list.reject(&fork_safe) + + if after.size > before.size + threads = (after - before) + if threads.first.respond_to? :backtrace + log "! WARNING: Detected #{after.size-before.size} Thread(s) started in app boot:" + threads.each do |t| + log "! #{t.inspect} - #{t.backtrace ? t.backtrace.first : ''}" + end + else + log "! WARNING: Detected #{after.size-before.size} Thread(s) started in app boot" + end + end + else + log "* Restarts: (\u2714) hot (\u2714) phased" + + unless @config.app_configured? + error "No application configured, nothing to run" + exit 1 + end + + @launcher.binder.parse @options[:binds] + end + + read, @wakeup = Puma::Util.pipe + + setup_signals + + # Used by the workers to detect if the master process dies. + # If select says that @check_pipe is ready, it's because the + # master has exited and @suicide_pipe has been automatically + # closed. + # + @check_pipe, @suicide_pipe = Puma::Util.pipe + + # Separate pipe used by worker 0 to receive commands to + # fork new worker processes. + @fork_pipe, @fork_writer = Puma::Util.pipe + + log "Use Ctrl-C to stop" + + single_worker_warning + + redirect_io + + Plugins.fire_background + + @launcher.write_state + + start_control + + @master_read, @worker_write = read, @wakeup + + @options[:worker_write] = @worker_write + + @config.run_hooks(:before_fork, nil, @log_writer) + + spawn_workers + + Signal.trap "SIGINT" do + stop + end + + begin + booted = false + in_phased_restart = false + workers_not_booted = @options[:workers] + + while @status == :run + begin + if @options[:idle_timeout] && all_workers_idle_timed_out? + log "- All workers reached idle timeout" + break + end + + if @phased_restart + start_phased_restart + @phased_restart = false + in_phased_restart = true + workers_not_booted = @options[:workers] + end + + check_workers + + if read.wait_readable([0, @next_check - Time.now].max) + req = read.read_nonblock(1) + next unless req + + if req == PIPE_WAKEUP + @next_check = Time.now + next + end + + result = read.gets + pid = result.to_i + + if req == PIPE_BOOT || req == PIPE_FORK + pid, idx = result.split(':').map(&:to_i) + w = worker_at idx + w.pid = pid if w.pid.nil? + end + + if w = @workers.find { |x| x.pid == pid } + case req + when PIPE_BOOT + w.boot! + log "- Worker #{w.index} (PID: #{pid}) booted in #{w.uptime.round(2)}s, phase: #{w.phase}" + @next_check = Time.now + workers_not_booted -= 1 + when PIPE_EXTERNAL_TERM + # external term, see worker method, Signal.trap "SIGTERM" + w.term! + when PIPE_TERM + w.term unless w.term? + when PIPE_PING + status = result.sub(/^\d+/,'').chomp + w.ping!(status) + @events.fire(:ping!, w) + + if in_phased_restart && @options[:fork_worker] && workers_not_booted.positive? && w0 = worker_at(0) + w0.ping!(status) + @events.fire(:ping!, w0) + end + + if !booted && @workers.none? {|worker| worker.last_status.empty?} + @events.fire_on_booted! + debug_loaded_extensions("Loaded Extensions - master:") if @log_writer.debug? + booted = true + end + when PIPE_IDLE + if idle_workers[pid] + idle_workers.delete pid + else + idle_workers[pid] = true + end + end + else + log "! Out-of-sync worker list, no #{pid} worker" + end + end + + if in_phased_restart && workers_not_booted.zero? + @events.fire_on_booted! + debug_loaded_extensions("Loaded Extensions - master:") if @log_writer.debug? + in_phased_restart = false + end + rescue Interrupt + @status = :stop + end + end + + stop_workers unless @status == :halt + ensure + @check_pipe.close + @suicide_pipe.close + read.close + @wakeup.close + end + end + + private + + def single_worker_warning + return if @options[:workers] != 1 || @options[:silence_single_worker_warning] + + log "! WARNING: Detected running cluster mode with 1 worker." + log "! Running Puma in cluster mode with a single worker is often a misconfiguration." + log "! Consider running Puma in single-mode (workers = 0) in order to reduce memory overhead." + log "! Set the `silence_single_worker_warning` option to silence this warning message." + end + + # loops thru @workers, removing workers that exited, and calling + # `#term` if needed + def wait_workers + # Reap all children, known workers or otherwise. + # If puma has PID 1, as it's common in containerized environments, + # then it's responsible for reaping orphaned processes, so we must reap + # all our dead children, regardless of whether they are workers we spawned + # or some reattached processes. + reaped_children = {} + loop do + begin + pid, status = Process.wait2(-1, Process::WNOHANG) + break unless pid + reaped_children[pid] = status + rescue Errno::ECHILD + break + end + end + + @workers.reject! do |w| + next false if w.pid.nil? + begin + # We may need to check the PID individually because: + # 1. From Ruby versions 2.6 to 3.2, `Process.detach` can prevent or delay + # `Process.wait2(-1)` from detecting a terminated process: https://bugs.ruby-lang.org/issues/19837. + # 2. When `fork_worker` is enabled, some worker may not be direct children, + # but grand children. Because of this they won't be reaped by `Process.wait2(-1)`. + if reaped_children.delete(w.pid) || Process.wait(w.pid, Process::WNOHANG) + true + else + w.term if w.term? + nil + end + rescue Errno::ECHILD + begin + Process.kill(0, w.pid) + # child still alive but has another parent (e.g., using fork_worker) + w.term if w.term? + false + rescue Errno::ESRCH, Errno::EPERM + true # child is already terminated + end + end + end + + # Log unknown children + reaped_children.each do |pid, status| + log "! reaped unknown child process pid=#{pid} status=#{status}" + end + end + + # @version 5.0.0 + def timeout_workers + @workers.each do |w| + if !w.term? && w.ping_timeout <= Time.now + details = if w.booted? + "(Worker #{w.index} failed to check in within #{@options[:worker_timeout]} seconds)" + else + "(Worker #{w.index} failed to boot within #{@options[:worker_boot_timeout]} seconds)" + end + log "! Terminating timed out worker #{details}: #{w.pid}" + w.kill + end + end + end + + def idle_timed_out_worker_pids + idle_workers.keys + end + + def idle_workers + @idle_workers ||= {} + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/cluster/worker.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/cluster/worker.rb new file mode 100644 index 00000000..458f13ce --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/cluster/worker.rb @@ -0,0 +1,183 @@ +# frozen_string_literal: true + +module Puma + class Cluster < Puma::Runner + #—————————————————————— DO NOT USE — this class is for internal use only ——— + + + # This class is instantiated by the `Puma::Cluster` and represents a single + # worker process. + # + # At the core of this class is running an instance of `Puma::Server` which + # gets created via the `start_server` method from the `Puma::Runner` class + # that this inherits from. + class Worker < Puma::Runner # :nodoc: + attr_reader :index, :master + + def initialize(index:, master:, launcher:, pipes:, server: nil) + super(launcher) + + @index = index + @master = master + @check_pipe = pipes[:check_pipe] + @worker_write = pipes[:worker_write] + @fork_pipe = pipes[:fork_pipe] + @wakeup = pipes[:wakeup] + @server = server + @hook_data = {} + end + + def run + title = "puma: cluster worker #{index}: #{master}" + title += " [#{@options[:tag]}]" if @options[:tag] && !@options[:tag].empty? + $0 = title + + Signal.trap "SIGINT", "IGNORE" + Signal.trap "SIGCHLD", "DEFAULT" + + Thread.new do + Puma.set_thread_name "wrkr check" + @check_pipe.wait_readable + log "! Detected parent died, dying" + exit! 1 + end + + # If we're not running under a Bundler context, then + # report the info about the context we will be using + if !ENV['BUNDLE_GEMFILE'] + if File.exist?("Gemfile") + log "+ Gemfile in context: #{File.expand_path("Gemfile")}" + elsif File.exist?("gems.rb") + log "+ Gemfile in context: #{File.expand_path("gems.rb")}" + end + end + + # Invoke any worker boot hooks so they can get + # things in shape before booting the app. + @config.run_hooks(:before_worker_boot, index, @log_writer, @hook_data) + + begin + server = @server ||= start_server + rescue Exception => e + log "! Unable to start worker" + log e + log e.backtrace.join("\n ") + exit 1 + end + + restart_server = Queue.new << true << false + + fork_worker = @options[:fork_worker] && index == 0 + + if fork_worker + restart_server.clear + worker_pids = [] + Signal.trap "SIGCHLD" do + wakeup! if worker_pids.reject! do |p| + Process.wait(p, Process::WNOHANG) rescue true + end + end + + Thread.new do + Puma.set_thread_name "wrkr fork" + while (idx = @fork_pipe.gets) + idx = idx.to_i + if idx == -1 # stop server + if restart_server.length > 0 + restart_server.clear + server.begin_restart(true) + @config.run_hooks(:before_refork, nil, @log_writer, @hook_data) + end + elsif idx == -2 # refork cycle is done + @config.run_hooks(:after_refork, nil, @log_writer, @hook_data) + elsif idx == 0 # restart server + restart_server << true << false + else # fork worker + worker_pids << pid = spawn_worker(idx) + @worker_write << "#{PIPE_FORK}#{pid}:#{idx}\n" rescue nil + end + end + end + end + + Signal.trap "SIGTERM" do + @worker_write << "#{PIPE_EXTERNAL_TERM}#{Process.pid}\n" rescue nil + restart_server.clear + server.stop + restart_server << false + end + + begin + @worker_write << "#{PIPE_BOOT}#{Process.pid}:#{index}\n" + rescue SystemCallError, IOError + Puma::Util.purge_interrupt_queue + STDERR.puts "Master seems to have exited, exiting." + return + end + + while restart_server.pop + server_thread = server.run + + if @log_writer.debug? && index == 0 + debug_loaded_extensions "Loaded Extensions - worker 0:" + end + + stat_thread ||= Thread.new(@worker_write) do |io| + Puma.set_thread_name "stat pld" + base_payload = "#{PIPE_PING}#{Process.pid}" + + while true + begin + b = server.backlog || 0 + r = server.running || 0 + t = server.pool_capacity || 0 + m = server.max_threads || 0 + rc = server.requests_count || 0 + bt = server.busy_threads || 0 + payload = %Q!#{base_payload}{ "backlog":#{b}, "running":#{r}, "pool_capacity":#{t}, "max_threads":#{m}, "requests_count":#{rc}, "busy_threads":#{bt} }\n! + io << payload + rescue IOError + Puma::Util.purge_interrupt_queue + break + end + sleep @options[:worker_check_interval] + end + end + server_thread.join + end + + # Invoke any worker shutdown hooks so they can prevent the worker + # exiting until any background operations are completed + @config.run_hooks(:before_worker_shutdown, index, @log_writer, @hook_data) + ensure + @worker_write << "#{PIPE_TERM}#{Process.pid}\n" rescue nil + @worker_write.close + end + + private + + def spawn_worker(idx) + @config.run_hooks(:before_worker_fork, idx, @log_writer, @hook_data) + + pid = fork do + new_worker = Worker.new index: idx, + master: master, + launcher: @launcher, + pipes: { check_pipe: @check_pipe, + worker_write: @worker_write }, + server: @server + new_worker.run + end + + if !pid + log "! Complete inability to spawn new workers detected" + log "! Seppuku is the only choice." + exit! 1 + end + + @config.run_hooks(:after_worker_fork, idx, @log_writer, @hook_data) + pid + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/cluster/worker_handle.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/cluster/worker_handle.rb new file mode 100644 index 00000000..64fff1a8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/cluster/worker_handle.rb @@ -0,0 +1,96 @@ +# frozen_string_literal: true + +module Puma + class Cluster < Runner + #—————————————————————— DO NOT USE — this class is for internal use only ——— + + + # This class represents a worker process from the perspective of the puma + # master process. It contains information about the process and its health + # and it exposes methods to control the process via IPC. It does not + # include the actual logic executed by the worker process itself. For that, + # see Puma::Cluster::Worker. + class WorkerHandle # :nodoc: + def initialize(idx, pid, phase, options) + @index = idx + @pid = pid + @phase = phase + @stage = :started + @signal = "TERM" + @options = options + @first_term_sent = nil + @started_at = Time.now + @last_checkin = Time.now + @last_status = {} + @term = false + end + + attr_reader :index, :pid, :phase, :signal, :last_checkin, :last_status, :started_at + + # @version 5.0.0 + attr_writer :pid, :phase + + def booted? + @stage == :booted + end + + def uptime + Time.now - started_at + end + + def boot! + @last_checkin = Time.now + @stage = :booted + end + + def term! + @term = true + end + + def term? + @term + end + + STATUS_PATTERN = /{ "backlog":(?\d*), "running":(?\d*), "pool_capacity":(?\d*), "max_threads":(?\d*), "requests_count":(?\d*), "busy_threads":(?\d*) }/ + private_constant :STATUS_PATTERN + + def ping!(status) + @last_checkin = Time.now + @last_status = status.match(STATUS_PATTERN).named_captures.map { |c_name, c| [c_name.to_sym, c.to_i] }.to_h + end + + # @see Puma::Cluster#check_workers + # @version 5.0.0 + def ping_timeout + @last_checkin + + (booted? ? + @options[:worker_timeout] : + @options[:worker_boot_timeout] + ) + end + + def term + begin + if @first_term_sent && (Time.now - @first_term_sent) > @options[:worker_shutdown_timeout] + @signal = "KILL" + else + @term ||= true + @first_term_sent ||= Time.now + end + Process.kill @signal, @pid if @pid + rescue Errno::ESRCH + end + end + + def kill + @signal = 'KILL' + term + end + + def hup + Process.kill "HUP", @pid + rescue Errno::ESRCH + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/commonlogger.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/commonlogger.rb new file mode 100644 index 00000000..144e9a9f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/commonlogger.rb @@ -0,0 +1,115 @@ +# frozen_string_literal: true + +module Puma + # Rack::CommonLogger forwards every request to the given +app+, and + # logs a line in the + # {Apache common log format}[https://httpd.apache.org/docs/2.4/logs.html#common] + # to the +logger+. + # + # If +logger+ is nil, CommonLogger will fall back +rack.errors+, which is + # an instance of Rack::NullLogger. + # + # +logger+ can be any class, including the standard library Logger, and is + # expected to have either +write+ or +<<+ method, which accepts the CommonLogger::FORMAT. + # According to the SPEC, the error stream must also respond to +puts+ + # (which takes a single argument that responds to +to_s+), and +flush+ + # (which is called without arguments in order to make the error appear for + # sure) + class CommonLogger + # Common Log Format: https://httpd.apache.org/docs/2.4/logs.html#common + # + # lilith.local - - [07/Aug/2006 23:58:02 -0400] "GET / HTTP/1.1" 500 - + # + # %{%s - %s [%s] "%s %s%s %s" %d %s\n} % + FORMAT = %{%s - %s [%s] "%s %s%s %s" %d %s %0.4f\n} + + HIJACK_FORMAT = %{%s - %s [%s] "%s %s%s %s" HIJACKED -1 %0.4f\n} + + LOG_TIME_FORMAT = '%d/%b/%Y:%H:%M:%S %z' + + CONTENT_LENGTH = 'Content-Length' # should be lower case from app, + # Util::HeaderHash allows mixed + HTTP_VERSION = Const::HTTP_VERSION + HTTP_X_FORWARDED_FOR = Const::HTTP_X_FORWARDED_FOR + PATH_INFO = Const::PATH_INFO + QUERY_STRING = Const::QUERY_STRING + REMOTE_ADDR = Const::REMOTE_ADDR + REMOTE_USER = 'REMOTE_USER' + REQUEST_METHOD = Const::REQUEST_METHOD + + def initialize(app, logger=nil) + @app = app + @logger = logger + end + + def call(env) + began_at = Time.now + status, header, body = @app.call(env) + header = Util::HeaderHash.new(header) + + # If we've been hijacked, then output a special line + if env['rack.hijack_io'] + log_hijacking(env, 'HIJACK', header, began_at) + else + ary = env['rack.after_reply'] + ary << lambda { log(env, status, header, began_at) } + end + + [status, header, body] + end + + private + + def log_hijacking(env, status, header, began_at) + now = Time.now + + msg = HIJACK_FORMAT % [ + env[HTTP_X_FORWARDED_FOR] || env[REMOTE_ADDR] || "-", + env[REMOTE_USER] || "-", + now.strftime(LOG_TIME_FORMAT), + env[REQUEST_METHOD], + env[PATH_INFO], + env[QUERY_STRING].empty? ? "" : "?#{env[QUERY_STRING]}", + env[HTTP_VERSION], + now - began_at ] + + write(msg) + end + + def log(env, status, header, began_at) + now = Time.now + length = extract_content_length(header) + + msg = FORMAT % [ + env[HTTP_X_FORWARDED_FOR] || env[REMOTE_ADDR] || "-", + env[REMOTE_USER] || "-", + now.strftime(LOG_TIME_FORMAT), + env[REQUEST_METHOD], + env[PATH_INFO], + env[QUERY_STRING].empty? ? "" : "?#{env[QUERY_STRING]}", + env[HTTP_VERSION], + status.to_s[0..3], + length, + now - began_at ] + + write(msg) + end + + def write(msg) + logger = @logger || env['rack.errors'] + + # Standard library logger doesn't support write but it supports << which actually + # calls to write on the log device without formatting + if logger.respond_to?(:write) + logger.write(msg) + else + logger << msg + end + end + + def extract_content_length(headers) + value = headers[CONTENT_LENGTH] or return '-' + value.to_s == '0' ? '-' : value + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/configuration.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/configuration.rb new file mode 100644 index 00000000..31321ecc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/configuration.rb @@ -0,0 +1,407 @@ +# frozen_string_literal: true + +require_relative 'plugin' +require_relative 'const' +require_relative 'dsl' + +module Puma + # A class used for storing "leveled" configuration options. + # + # In this class any "user" specified options take precedence over any + # "file" specified options, take precedence over any "default" options. + # + # User input is preferred over "defaults": + # user_options = { foo: "bar" } + # default_options = { foo: "zoo" } + # options = UserFileDefaultOptions.new(user_options, default_options) + # puts options[:foo] + # # => "bar" + # + # All values can be accessed via `all_of` + # + # puts options.all_of(:foo) + # # => ["bar", "zoo"] + # + # A "file" option can be set. This config will be preferred over "default" options + # but will defer to any available "user" specified options. + # + # user_options = { foo: "bar" } + # default_options = { rackup: "zoo.rb" } + # options = UserFileDefaultOptions.new(user_options, default_options) + # options.file_options[:rackup] = "sup.rb" + # puts options[:rackup] + # # => "sup.rb" + # + # The "default" options can be set via procs. These are resolved during runtime + # via calls to `finalize_values` + class UserFileDefaultOptions + def initialize(user_options, default_options) + @user_options = user_options + @file_options = {} + @default_options = default_options + end + + attr_reader :user_options, :file_options, :default_options + + def [](key) + fetch(key) + end + + def []=(key, value) + user_options[key] = value + end + + def fetch(key, default_value = nil) + return user_options[key] if user_options.key?(key) + return file_options[key] if file_options.key?(key) + return default_options[key] if default_options.key?(key) + + default_value + end + + def all_of(key) + user = user_options[key] + file = file_options[key] + default = default_options[key] + + user = [user] unless user.is_a?(Array) + file = [file] unless file.is_a?(Array) + default = [default] unless default.is_a?(Array) + + user.compact! + file.compact! + default.compact! + + user + file + default + end + + def finalize_values + @default_options.each do |k,v| + if v.respond_to? :call + @default_options[k] = v.call + end + end + end + + def final_options + default_options + .merge(file_options) + .merge(user_options) + end + end + + # The main configuration class of Puma. + # + # It can be initialized with a set of "user" options and "default" options. + # Defaults will be merged with `Configuration.puma_default_options`. + # + # This class works together with 2 main other classes the `UserFileDefaultOptions` + # which stores configuration options in order so the precedence is that user + # set configuration wins over "file" based configuration wins over "default" + # configuration. These configurations are set via the `DSL` class. This + # class powers the Puma config file syntax and does double duty as a configuration + # DSL used by the `Puma::CLI` and Puma rack handler. + # + # It also handles loading plugins. + # + # [Note:] + # `:port` and `:host` are not valid keys. By the time they make it to the + # configuration options they are expected to be incorporated into a `:binds` key. + # Under the hood the DSL maps `port` and `host` calls to `:binds` + # + # config = Configuration.new({}) do |user_config, file_config, default_config| + # user_config.port 3003 + # end + # config.load + # puts config.options[:port] + # # => 3003 + # + # It is expected that `load` is called on the configuration instance after setting + # config. This method expands any values in `config_file` and puts them into the + # correct configuration option hash. + # + # Once all configuration is complete it is expected that `clamp` will be called + # on the instance. This will expand any procs stored under "default" values. This + # is done because an environment variable may have been modified while loading + # configuration files. + class Configuration + DEFAULTS = { + auto_trim_time: 30, + binds: ['tcp://0.0.0.0:9292'.freeze], + clean_thread_locals: false, + debug: false, + enable_keep_alives: true, + early_hints: nil, + environment: 'development'.freeze, + # Number of seconds to wait until we get the first data for the request. + first_data_timeout: 30, + # Number of seconds to wait until the next request before shutting down. + idle_timeout: nil, + io_selector_backend: :auto, + log_requests: false, + logger: STDOUT, + # How many requests to attempt inline before sending a client back to + # the reactor to be subject to normal ordering. The idea here is that + # we amortize the cost of going back to the reactor for a well behaved + # but very "greedy" client across 10 requests. This prevents a not + # well behaved client from monopolizing the thread forever. + max_fast_inline: 10, + max_threads: Puma.mri? ? 5 : 16, + min_threads: 0, + mode: :http, + mutate_stdout_and_stderr_to_sync_on_write: true, + out_of_band: [], + # Number of seconds for another request within a persistent session. + persistent_timeout: 20, + queue_requests: true, + rackup: 'config.ru'.freeze, + raise_exception_on_sigterm: true, + reaping_time: 1, + remote_address: :socket, + silence_single_worker_warning: false, + silence_fork_callback_warning: false, + tag: File.basename(Dir.getwd), + tcp_host: '0.0.0.0'.freeze, + tcp_port: 9292, + wait_for_less_busy_worker: 0.005, + worker_boot_timeout: 60, + worker_check_interval: 5, + worker_culling_strategy: :youngest, + worker_shutdown_timeout: 30, + worker_timeout: 60, + workers: 0, + http_content_length_limit: nil + } + + def initialize(user_options={}, default_options = {}, env = ENV, &block) + default_options = self.puma_default_options(env).merge(default_options) + + @options = UserFileDefaultOptions.new(user_options, default_options) + @plugins = PluginLoader.new + @user_dsl = DSL.new(@options.user_options, self) + @file_dsl = DSL.new(@options.file_options, self) + @default_dsl = DSL.new(@options.default_options, self) + + if !@options[:prune_bundler] + default_options[:preload_app] = (@options[:workers] > 1) && Puma.forkable? + end + + @puma_bundler_pruned = env.key? 'PUMA_BUNDLER_PRUNED' + + if block + configure(&block) + end + end + + attr_reader :options, :plugins + + def configure + yield @user_dsl, @file_dsl, @default_dsl + ensure + @user_dsl._offer_plugins + @file_dsl._offer_plugins + @default_dsl._offer_plugins + end + + def initialize_copy(other) + @conf = nil + @cli_options = nil + @options = @options.dup + end + + def flatten + dup.flatten! + end + + def flatten! + @options = @options.flatten + self + end + + def puma_default_options(env = ENV) + defaults = DEFAULTS.dup + puma_options_from_env(env).each { |k,v| defaults[k] = v if v } + defaults + end + + def puma_options_from_env(env = ENV) + min = env['PUMA_MIN_THREADS'] || env['MIN_THREADS'] + max = env['PUMA_MAX_THREADS'] || env['MAX_THREADS'] + workers = if env['WEB_CONCURRENCY'] == 'auto' + require_processor_counter + ::Concurrent.available_processor_count + else + env['WEB_CONCURRENCY'] + end + + { + min_threads: min && min != "" && Integer(min), + max_threads: max && max != "" && Integer(max), + workers: workers && workers != "" && Integer(workers), + environment: env['APP_ENV'] || env['RACK_ENV'] || env['RAILS_ENV'], + } + end + + def load + config_files.each { |config_file| @file_dsl._load_from(config_file) } + + @options + end + + def config_files + files = @options.all_of(:config_files) + + return [] if files == ['-'] + return files if files.any? + + first_default_file = %W(config/puma/#{@options[:environment]}.rb config/puma.rb).find do |f| + File.exist?(f) + end + + [first_default_file] + end + + # Call once all configuration (included from rackup files) + # is loaded to flesh out any defaults + def clamp + @options.finalize_values + end + + # Injects the Configuration object into the env + class ConfigMiddleware + def initialize(config, app) + @config = config + @app = app + end + + def call(env) + env[Const::PUMA_CONFIG] = @config + @app.call(env) + end + end + + # Indicate if there is a properly configured app + # + def app_configured? + @options[:app] || File.exist?(rackup) + end + + def rackup + @options[:rackup] + end + + # Load the specified rackup file, pull options from + # the rackup file, and set @app. + # + def app + found = options[:app] || load_rackup + + if @options[:log_requests] + require_relative 'commonlogger' + logger = @options[:logger] + found = CommonLogger.new(found, logger) + end + + ConfigMiddleware.new(self, found) + end + + # Return which environment we're running in + def environment + @options[:environment] + end + + def load_plugin(name) + @plugins.create name + end + + # @param key [:Symbol] hook to run + # @param arg [Launcher, Int] `:on_restart` passes Launcher + # + def run_hooks(key, arg, log_writer, hook_data = nil) + log_writer.debug "Running #{key} hooks" + + @options.all_of(key).each do |b| + begin + if Array === b + hook_data[b[1]] ||= Hash.new + b[0].call arg, hook_data[b[1]] + else + b.call arg + end + rescue => e + log_writer.log "WARNING hook #{key} failed with exception (#{e.class}) #{e.message}" + log_writer.debug e.backtrace.join("\n") + end + end + end + + def final_options + @options.final_options + end + + def self.temp_path + require 'tmpdir' + + t = (Time.now.to_f * 1000).to_i + "#{Dir.tmpdir}/puma-status-#{t}-#{$$}" + end + + private + + def require_processor_counter + require 'concurrent/utility/processor_counter' + rescue LoadError + warn <<~MESSAGE + WEB_CONCURRENCY=auto requires the "concurrent-ruby" gem to be installed. + Please add "concurrent-ruby" to your Gemfile. + MESSAGE + raise + end + + # Load and use the normal Rack builder if we can, otherwise + # fallback to our minimal version. + def rack_builder + # Load bundler now if we can so that we can pickup rack from + # a Gemfile + if @puma_bundler_pruned + begin + require 'bundler/setup' + rescue LoadError + end + end + + begin + require 'rack' + require 'rack/builder' + ::Rack::Builder + rescue LoadError + require_relative 'rack/builder' + Puma::Rack::Builder + end + end + + def load_rackup + raise "Missing rackup file '#{rackup}'" unless File.exist?(rackup) + + rack_app, rack_options = rack_builder.parse_file(rackup) + rack_options = rack_options || {} + + @options.file_options.merge!(rack_options) + + config_ru_binds = [] + rack_options.each do |k, v| + config_ru_binds << v if k.to_s.start_with?("bind") + end + + @options.file_options[:binds] = config_ru_binds unless config_ru_binds.empty? + + rack_app + end + + def self.random_token + require 'securerandom' unless defined?(SecureRandom) + + SecureRandom.hex(16) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/const.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/const.rb new file mode 100644 index 00000000..6a64a89b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/const.rb @@ -0,0 +1,308 @@ +#encoding: utf-8 +# frozen_string_literal: true + +module Puma + class UnsupportedOption < RuntimeError + end + + # Every standard HTTP code mapped to the appropriate message. These are + # used so frequently that they are placed directly in Puma for easy + # access rather than Puma::Const itself. + + # Every standard HTTP code mapped to the appropriate message. + # Generated with: + # curl -s https://www.iana.org/assignments/http-status-codes/http-status-codes-1.csv | \ + # ruby -ne 'm = /^(\d{3}),(?!Unassigned|\(Unused\))([^,]+)/.match($_) and \ + # puts "#{m[1]} => \x27#{m[2].strip}\x27,"' + HTTP_STATUS_CODES = { + 100 => 'Continue', + 101 => 'Switching Protocols', + 102 => 'Processing', + 103 => 'Early Hints', + 200 => 'OK', + 201 => 'Created', + 202 => 'Accepted', + 203 => 'Non-Authoritative Information', + 204 => 'No Content', + 205 => 'Reset Content', + 206 => 'Partial Content', + 207 => 'Multi-Status', + 208 => 'Already Reported', + 226 => 'IM Used', + 300 => 'Multiple Choices', + 301 => 'Moved Permanently', + 302 => 'Found', + 303 => 'See Other', + 304 => 'Not Modified', + 305 => 'Use Proxy', + 307 => 'Temporary Redirect', + 308 => 'Permanent Redirect', + 400 => 'Bad Request', + 401 => 'Unauthorized', + 402 => 'Payment Required', + 403 => 'Forbidden', + 404 => 'Not Found', + 405 => 'Method Not Allowed', + 406 => 'Not Acceptable', + 407 => 'Proxy Authentication Required', + 408 => 'Request Timeout', + 409 => 'Conflict', + 410 => 'Gone', + 411 => 'Length Required', + 412 => 'Precondition Failed', + 413 => 'Content Too Large', + 414 => 'URI Too Long', + 415 => 'Unsupported Media Type', + 416 => 'Range Not Satisfiable', + 417 => 'Expectation Failed', + 421 => 'Misdirected Request', + 422 => 'Unprocessable Content', + 423 => 'Locked', + 424 => 'Failed Dependency', + 425 => 'Too Early', + 426 => 'Upgrade Required', + 428 => 'Precondition Required', + 429 => 'Too Many Requests', + 431 => 'Request Header Fields Too Large', + 451 => 'Unavailable For Legal Reasons', + 500 => 'Internal Server Error', + 501 => 'Not Implemented', + 502 => 'Bad Gateway', + 503 => 'Service Unavailable', + 504 => 'Gateway Timeout', + 505 => 'HTTP Version Not Supported', + 506 => 'Variant Also Negotiates', + 507 => 'Insufficient Storage', + 508 => 'Loop Detected', + 510 => 'Not Extended (OBSOLETED)', + 511 => 'Network Authentication Required' + }.freeze + + # For some HTTP status codes the client only expects headers. + # + + STATUS_WITH_NO_ENTITY_BODY = { + 204 => true, + 205 => true, + 304 => true + }.freeze + + # Frequently used constants when constructing requests or responses. Many times + # the constant just refers to a string with the same contents. Using these constants + # gave about a 3% to 10% performance improvement over using the strings directly. + # + # The constants are frozen because Hash#[]= when called with a String key dups + # the String UNLESS the String is frozen. This saves us therefore 2 object + # allocations when creating the env hash later. + # + # While Puma does try to emulate the CGI/1.2 protocol, it does not use the REMOTE_IDENT, + # REMOTE_USER, or REMOTE_HOST parameters since those are either a security problem or + # too taxing on performance. + module Const + + PUMA_VERSION = VERSION = "6.6.0" + CODE_NAME = "Return to Forever" + + PUMA_SERVER_STRING = ["puma", PUMA_VERSION, CODE_NAME].join(" ").freeze + + FAST_TRACK_KA_TIMEOUT = 0.2 + + # How long to wait when getting some write blocking on the socket when + # sending data back + WRITE_TIMEOUT = 10 + + # The original URI requested by the client. + REQUEST_URI= "REQUEST_URI" + REQUEST_PATH = "REQUEST_PATH" + QUERY_STRING = "QUERY_STRING" + CONTENT_LENGTH = "CONTENT_LENGTH" + + PATH_INFO = "PATH_INFO" + + PUMA_TMP_BASE = "puma" + + ERROR_RESPONSE = { + # Indicate that we couldn't parse the request + 400 => "HTTP/1.1 400 Bad Request\r\n\r\n", + # The standard empty 404 response for bad requests. Use Error4040Handler for custom stuff. + 404 => "HTTP/1.1 404 Not Found\r\nConnection: close\r\n\r\n", + # The standard empty 408 response for requests that timed out. + 408 => "HTTP/1.1 408 Request Timeout\r\nConnection: close\r\n\r\n", + # Indicate that there was an internal error, obviously. + 500 => "HTTP/1.1 500 Internal Server Error\r\n\r\n", + # Incorrect or invalid header value + 501 => "HTTP/1.1 501 Not Implemented\r\n\r\n", + # A common header for indicating the server is too busy. Not used yet. + 503 => "HTTP/1.1 503 Service Unavailable\r\n\r\n" + }.freeze + + # The basic max request size we'll try to read. + CHUNK_SIZE = 64 * 1024 + + # This is the maximum header that is allowed before a client is booted. The parser detects + # this, but we'd also like to do this as well. + MAX_HEADER = 1024 * (80 + 32) + + # Maximum request body size before it is moved out of memory and into a tempfile for reading. + MAX_BODY = MAX_HEADER + + REQUEST_METHOD = "REQUEST_METHOD" + HEAD = "HEAD" + + # based on https://www.rfc-editor.org/rfc/rfc9110.html#name-overview, + # with CONNECT removed, and PATCH added + SUPPORTED_HTTP_METHODS = %w[HEAD GET POST PUT DELETE OPTIONS TRACE PATCH].freeze + + # list from https://www.iana.org/assignments/http-methods/http-methods.xhtml + # as of 04-May-23 + IANA_HTTP_METHODS = %w[ + ACL + BASELINE-CONTROL + BIND + CHECKIN + CHECKOUT + CONNECT + COPY + DELETE + GET + HEAD + LABEL + LINK + LOCK + MERGE + MKACTIVITY + MKCALENDAR + MKCOL + MKREDIRECTREF + MKWORKSPACE + MOVE + OPTIONS + ORDERPATCH + PATCH + POST + PRI + PROPFIND + PROPPATCH + PUT + REBIND + REPORT + SEARCH + TRACE + UNBIND + UNCHECKOUT + UNLINK + UNLOCK + UPDATE + UPDATEREDIRECTREF + VERSION-CONTROL + ].freeze + + # ETag is based on the apache standard of hex mtime-size-inode (inode is 0 on win32) + LINE_END = "\r\n" + REMOTE_ADDR = "REMOTE_ADDR" + HTTP_X_FORWARDED_FOR = "HTTP_X_FORWARDED_FOR" + HTTP_X_FORWARDED_SSL = "HTTP_X_FORWARDED_SSL" + HTTP_X_FORWARDED_SCHEME = "HTTP_X_FORWARDED_SCHEME" + HTTP_X_FORWARDED_PROTO = "HTTP_X_FORWARDED_PROTO" + + SERVER_NAME = "SERVER_NAME" + SERVER_PORT = "SERVER_PORT" + HTTP_HOST = "HTTP_HOST" + PORT_80 = "80" + PORT_443 = "443" + LOCALHOST = "localhost" + LOCALHOST_IPV4 = "127.0.0.1" + LOCALHOST_IPV6 = "::1" + UNSPECIFIED_IPV4 = "0.0.0.0" + UNSPECIFIED_IPV6 = "::" + + SERVER_PROTOCOL = "SERVER_PROTOCOL" + HTTP_11 = "HTTP/1.1" + + SERVER_SOFTWARE = "SERVER_SOFTWARE" + GATEWAY_INTERFACE = "GATEWAY_INTERFACE" + CGI_VER = "CGI/1.2" + + STOP_COMMAND = "?" + HALT_COMMAND = "!" + RESTART_COMMAND = "R" + + RACK_INPUT = "rack.input" + RACK_URL_SCHEME = "rack.url_scheme" + RACK_AFTER_REPLY = "rack.after_reply" + PUMA_SOCKET = "puma.socket" + PUMA_CONFIG = "puma.config" + PUMA_PEERCERT = "puma.peercert" + + HTTP = "http" + HTTPS = "https" + + HTTPS_KEY = "HTTPS" + + HTTP_VERSION = "HTTP_VERSION" + HTTP_CONNECTION = "HTTP_CONNECTION" + HTTP_EXPECT = "HTTP_EXPECT" + CONTINUE = "100-continue" + + HTTP_11_100 = "HTTP/1.1 100 Continue\r\n\r\n" + HTTP_11_200 = "HTTP/1.1 200 OK\r\n" + HTTP_10_200 = "HTTP/1.0 200 OK\r\n" + + CLOSE = "close" + KEEP_ALIVE = "keep-alive" + + CONTENT_LENGTH2 = "content-length" + CONTENT_LENGTH_S = "Content-Length: " + TRANSFER_ENCODING = "transfer-encoding" + TRANSFER_ENCODING2 = "HTTP_TRANSFER_ENCODING" + + CONNECTION_CLOSE = "Connection: close\r\n" + CONNECTION_KEEP_ALIVE = "Connection: Keep-Alive\r\n" + + TRANSFER_ENCODING_CHUNKED = "Transfer-Encoding: chunked\r\n" + CLOSE_CHUNKED = "0\r\n\r\n" + + CHUNKED = "chunked" + + COLON = ": " + + NEWLINE = "\n" + + HIJACK_P = "rack.hijack?" + HIJACK = "rack.hijack" + HIJACK_IO = "rack.hijack_io" + + EARLY_HINTS = "rack.early_hints" + + # Illegal character in the key or value of response header + DQUOTE = "\"" + HTTP_HEADER_DELIMITER = Regexp.escape("(),/:;<=>?@[]{}\\").freeze + ILLEGAL_HEADER_KEY_REGEX = /[\x00-\x20#{DQUOTE}#{HTTP_HEADER_DELIMITER}]/.freeze + # header values can contain HTAB? + ILLEGAL_HEADER_VALUE_REGEX = /[\x00-\x08\x0A-\x1F]/.freeze + + # The keys of headers that should not be convert to underscore + # normalized versions. These headers are ignored at the request reading layer, + # but if we normalize them after reading, it's just confusing for the application. + UNMASKABLE_HEADERS = { + "HTTP_TRANSFER,ENCODING" => true, + "HTTP_CONTENT,LENGTH" => true, + } + + # Banned keys of response header + BANNED_HEADER_KEY = /\A(rack\.|status\z)/.freeze + + PROXY_PROTOCOL_V1_REGEX = /^PROXY (?:TCP4|TCP6|UNKNOWN) ([^\r]+)\r\n/.freeze + + # All constants are prefixed with `PIPE_` to avoid name collisions. + module PipeRequest + PIPE_WAKEUP = "!" + PIPE_BOOT = "b" + PIPE_FORK = "f" + PIPE_EXTERNAL_TERM = "e" + PIPE_TERM = "t" + PIPE_PING = "p" + PIPE_IDLE = "i" + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/control_cli.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/control_cli.rb new file mode 100644 index 00000000..5aaef94c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/control_cli.rb @@ -0,0 +1,316 @@ +# frozen_string_literal: true + +require 'optparse' +require_relative 'const' +require_relative 'detect' +require 'uri' +require 'socket' + +module Puma + class ControlCLI + + # values must be string or nil + # value of `nil` means command cannot be processed via signal + # @version 5.0.3 + CMD_PATH_SIG_MAP = { + 'gc' => nil, + 'gc-stats' => nil, + 'halt' => 'SIGQUIT', + 'info' => 'SIGINFO', + 'phased-restart' => 'SIGUSR1', + 'refork' => 'SIGURG', + 'reload-worker-directory' => nil, + 'reopen-log' => 'SIGHUP', + 'restart' => 'SIGUSR2', + 'start' => nil, + 'stats' => nil, + 'status' => '', + 'stop' => 'SIGTERM', + 'thread-backtraces' => nil, + 'worker-count-down' => 'SIGTTOU', + 'worker-count-up' => 'SIGTTIN' + }.freeze + + # commands that cannot be used in a request + NO_REQ_COMMANDS = %w[info reopen-log worker-count-down worker-count-up].freeze + + # @version 5.0.0 + PRINTABLE_COMMANDS = %w[gc-stats stats thread-backtraces].freeze + + def initialize(argv, stdout=STDOUT, stderr=STDERR, env: ENV) + @state = nil + @quiet = false + @pidfile = nil + @pid = nil + @control_url = nil + @control_auth_token = nil + @config_file = nil + @command = nil + @environment = env['APP_ENV'] || env['RACK_ENV'] || env['RAILS_ENV'] + + @argv = argv.dup + @stdout = stdout + @stderr = stderr + @cli_options = {} + + opts = OptionParser.new do |o| + o.banner = "Usage: pumactl (-p PID | -P pidfile | -S status_file | -C url -T token | -F config.rb) (#{CMD_PATH_SIG_MAP.keys.join("|")})" + + o.on "-S", "--state PATH", "Where the state file to use is" do |arg| + @state = arg + end + + o.on "-Q", "--quiet", "Do not display messages" do |arg| + @quiet = true + end + + o.on "-P", "--pidfile PATH", "Pid file" do |arg| + @pidfile = arg + end + + o.on "-p", "--pid PID", "Pid" do |arg| + @pid = arg.to_i + end + + o.on "-C", "--control-url URL", "The bind url to use for the control server" do |arg| + @control_url = arg + end + + o.on "-T", "--control-token TOKEN", "The token to use as authentication for the control server" do |arg| + @control_auth_token = arg + end + + o.on "-F", "--config-file PATH", "Puma config script" do |arg| + @config_file = arg + end + + o.on "-e", "--environment ENVIRONMENT", + "The environment to run the Rack app on (default development)" do |arg| + @environment = arg + end + + o.on_tail("-H", "--help", "Show this message") do + @stdout.puts o + exit + end + + o.on_tail("-V", "--version", "Show version") do + @stdout.puts Const::PUMA_VERSION + exit + end + end + + opts.order!(argv) { |a| opts.terminate a } + opts.parse! + + @command = argv.shift + + # check presence of command + unless @command + raise "Available commands: #{CMD_PATH_SIG_MAP.keys.join(", ")}" + end + + unless CMD_PATH_SIG_MAP.key? @command + raise "Invalid command: #{@command}" + end + + unless @config_file == '-' + environment = @environment || 'development' + + if @config_file.nil? + @config_file = %W(config/puma/#{environment}.rb config/puma.rb).find do |f| + File.exist?(f) + end + end + + if @config_file + require_relative 'configuration' + require_relative 'log_writer' + + config = Puma::Configuration.new({ config_files: [@config_file] }, {} , env) + config.load + @state ||= config.options[:state] + @control_url ||= config.options[:control_url] + @control_auth_token ||= config.options[:control_auth_token] + @pidfile ||= config.options[:pidfile] + end + end + rescue => e + @stdout.puts e.message + exit 1 + end + + def message(msg) + @stdout.puts msg unless @quiet + end + + def prepare_configuration + if @state + unless File.exist? @state + raise "State file not found: #{@state}" + end + + require_relative 'state_file' + + sf = Puma::StateFile.new + sf.load @state + + @control_url = sf.control_url + @control_auth_token = sf.control_auth_token + @pid = sf.pid + elsif @pidfile + # get pid from pid_file + @pid = File.read(@pidfile, mode: 'rb:UTF-8').to_i + end + end + + def send_request + uri = URI.parse @control_url + + host = uri.host + + # create server object by scheme + server = + case uri.scheme + when 'ssl' + require 'openssl' + host = host[1..-2] if host&.start_with? '[' + OpenSSL::SSL::SSLSocket.new( + TCPSocket.new(host, uri.port), + OpenSSL::SSL::SSLContext.new) + .tap { |ssl| ssl.sync_close = true } # default is false + .tap(&:connect) + when 'tcp' + host = host[1..-2] if host&.start_with? '[' + TCPSocket.new host, uri.port + when 'unix' + # check for abstract UNIXSocket + UNIXSocket.new(@control_url.start_with?('unix://@') ? + "\0#{host}#{uri.path}" : "#{host}#{uri.path}") + else + raise "Invalid scheme: #{uri.scheme}" + end + + if @command == 'status' + message 'Puma is started' + else + url = "/#{@command}" + + if @control_auth_token + url = url + "?token=#{@control_auth_token}" + end + + server.syswrite "GET #{url} HTTP/1.0\r\n\r\n" + + unless data = server.read + raise 'Server closed connection before responding' + end + + response = data.split("\r\n") + + if response.empty? + raise "Server sent empty response" + end + + @http, @code, @message = response.first.split(' ',3) + + if @code == '403' + raise 'Unauthorized access to server (wrong auth token)' + elsif @code == '404' + raise "Command error: #{response.last}" + elsif @code != '200' + raise "Bad response from server: #{@code}" + end + + message "Command #{@command} sent success" + message response.last if PRINTABLE_COMMANDS.include?(@command) + end + ensure + if server + if uri.scheme == 'ssl' + server.sysclose + else + server.close unless server.closed? + end + end + end + + def send_signal + unless @pid + raise 'Neither pid nor control url available' + end + + begin + sig = CMD_PATH_SIG_MAP[@command] + + if sig.nil? + @stdout.puts "'#{@command}' not available via pid only" + @stdout.flush unless @stdout.sync + return + elsif sig.start_with? 'SIG' + if Signal.list.key? sig.sub(/\ASIG/, '') + Process.kill sig, @pid + else + raise "Signal '#{sig}' not available'" + end + elsif @command == 'status' + begin + Process.kill 0, @pid + @stdout.puts 'Puma is started' + @stdout.flush unless @stdout.sync + rescue Errno::ESRCH + raise 'Puma is not running' + end + return + end + rescue SystemCallError + if @command == 'restart' + start + else + raise "No pid '#{@pid}' found" + end + end + + message "Command #{@command} sent success" + end + + def run + return start if @command == 'start' + prepare_configuration + + if Puma.windows? || @control_url && !NO_REQ_COMMANDS.include?(@command) + send_request + else + send_signal + end + + rescue => e + message e.message + exit 1 + end + + private + def start + require_relative 'cli' + + run_args = [] + + run_args += ["-S", @state] if @state + run_args += ["-q"] if @quiet + run_args += ["--pidfile", @pidfile] if @pidfile + run_args += ["--control-url", @control_url] if @control_url + run_args += ["--control-token", @control_auth_token] if @control_auth_token + run_args += ["-C", @config_file] if @config_file + run_args += ["-e", @environment] if @environment + + log_writer = Puma::LogWriter.new(@stdout, @stderr) + + # replace $0 because puma use it to generate restart command + puma_cmd = $0.gsub(/pumactl$/, 'puma') + $0 = puma_cmd if File.exist?(puma_cmd) + + cli = Puma::CLI.new run_args, log_writer + cli.run + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/detect.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/detect.rb new file mode 100644 index 00000000..a233eb40 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/detect.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +# This file can be loaded independently of puma.rb, so it cannot have any code +# that assumes puma.rb is loaded. + + +module Puma + # @version 5.2.1 + HAS_FORK = ::Process.respond_to? :fork + + HAS_NATIVE_IO_WAIT = ::IO.public_instance_methods(false).include? :wait_readable + + IS_JRUBY = Object.const_defined? :JRUBY_VERSION + + IS_OSX = RUBY_DESCRIPTION.include? 'darwin' + + IS_WINDOWS = RUBY_DESCRIPTION.match?(/mswin|ming|cygwin/) + + IS_LINUX = !(IS_OSX || IS_WINDOWS) + + # @version 5.2.0 + IS_MRI = RUBY_ENGINE == 'ruby' + + def self.jruby? + IS_JRUBY + end + + def self.osx? + IS_OSX + end + + def self.windows? + IS_WINDOWS + end + + # @version 5.0.0 + def self.mri? + IS_MRI + end + + # @version 5.0.0 + def self.forkable? + HAS_FORK + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/dsl.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/dsl.rb new file mode 100644 index 00000000..8601e021 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/dsl.rb @@ -0,0 +1,1445 @@ +# frozen_string_literal: true + +require_relative 'const' +require_relative 'util' + +module Puma + # The methods that are available for use inside the configuration file. + # These same methods are used in Puma cli and the rack handler + # internally. + # + # Used manually (via CLI class): + # + # config = Configuration.new({}) do |user_config| + # user_config.port 3001 + # end + # config.load + # + # puts config.options[:binds] # => "tcp://127.0.0.1:3001" + # + # Used to load file: + # + # $ cat puma_config.rb + # port 3002 + # + # Resulting configuration: + # + # config = Configuration.new(config_file: "puma_config.rb") + # config.load + # + # puts config.options[:binds] # => "tcp://127.0.0.1:3002" + # + # You can also find many examples being used by the test suite in + # +test/config+. + # + # Puma v6 adds the option to specify a key name (String or Symbol) to the + # hooks that run inside the forked workers. All the hooks run inside the + # {Puma::Cluster::Worker#run} method. + # + # Previously, the worker index and the LogWriter instance were passed to the + # hook blocks/procs. If a key name is specified, a hash is passed as the last + # parameter. This allows storage of data, typically objects that are created + # before the worker that need to be passed to the hook when the worker is shutdown. + # + # The following hooks have been updated: + # + # | DSL Method | Options Key | Fork Block Location | + # | on_worker_boot | :before_worker_boot | inside, before | + # | on_worker_shutdown | :before_worker_shutdown | inside, after | + # | on_refork | :before_refork | inside | + # | after_refork | :after_refork | inside | + # + class DSL + ON_WORKER_KEY = [String, Symbol].freeze + + # Convenience method so logic can be used in CI. + # + # @see ssl_bind + # + def self.ssl_bind_str(host, port, opts) + verify = opts.fetch(:verify_mode, 'none').to_s + + tls_str = + if opts[:no_tlsv1_1] then '&no_tlsv1_1=true' + elsif opts[:no_tlsv1] then '&no_tlsv1=true' + else '' + end + + ca_additions = "&ca=#{Puma::Util.escape(opts[:ca])}" if ['peer', 'force_peer'].include?(verify) + + low_latency_str = opts.key?(:low_latency) ? "&low_latency=#{opts[:low_latency]}" : '' + backlog_str = opts[:backlog] ? "&backlog=#{Integer(opts[:backlog])}" : '' + + if defined?(JRUBY_VERSION) + cipher_suites = opts[:ssl_cipher_list] ? "&ssl_cipher_list=#{opts[:ssl_cipher_list]}" : nil # old name + cipher_suites = "#{cipher_suites}&cipher_suites=#{opts[:cipher_suites]}" if opts[:cipher_suites] + protocols = opts[:protocols] ? "&protocols=#{opts[:protocols]}" : nil + + keystore_additions = "keystore=#{opts[:keystore]}&keystore-pass=#{opts[:keystore_pass]}" + keystore_additions = "#{keystore_additions}&keystore-type=#{opts[:keystore_type]}" if opts[:keystore_type] + if opts[:truststore] + truststore_additions = "&truststore=#{opts[:truststore]}" + truststore_additions = "#{truststore_additions}&truststore-pass=#{opts[:truststore_pass]}" if opts[:truststore_pass] + truststore_additions = "#{truststore_additions}&truststore-type=#{opts[:truststore_type]}" if opts[:truststore_type] + end + + "ssl://#{host}:#{port}?#{keystore_additions}#{truststore_additions}#{cipher_suites}#{protocols}" \ + "&verify_mode=#{verify}#{tls_str}#{ca_additions}#{backlog_str}" + else + ssl_cipher_filter = opts[:ssl_cipher_filter] ? "&ssl_cipher_filter=#{opts[:ssl_cipher_filter]}" : nil + ssl_ciphersuites = opts[:ssl_ciphersuites] ? "&ssl_ciphersuites=#{opts[:ssl_ciphersuites]}" : nil + v_flags = (ary = opts[:verification_flags]) ? "&verification_flags=#{Array(ary).join ','}" : nil + + cert_flags = (cert = opts[:cert]) ? "cert=#{Puma::Util.escape(cert)}" : nil + key_flags = (key = opts[:key]) ? "&key=#{Puma::Util.escape(key)}" : nil + password_flags = (password_command = opts[:key_password_command]) ? "&key_password_command=#{Puma::Util.escape(password_command)}" : nil + + reuse_flag = + if (reuse = opts[:reuse]) + if reuse == true + '&reuse=dflt' + elsif reuse.is_a?(Hash) && (reuse.key?(:size) || reuse.key?(:timeout)) + val = +'' + if (size = reuse[:size]) && Integer === size + val << size.to_s + end + if (timeout = reuse[:timeout]) && Integer === timeout + val << ",#{timeout}" + end + if val.empty? + nil + else + "&reuse=#{val}" + end + else + nil + end + else + nil + end + + "ssl://#{host}:#{port}?#{cert_flags}#{key_flags}#{password_flags}#{ssl_cipher_filter}#{ssl_ciphersuites}" \ + "#{reuse_flag}&verify_mode=#{verify}#{tls_str}#{ca_additions}#{v_flags}#{backlog_str}#{low_latency_str}" + end + end + + def initialize(options, config) + @config = config + @options = options + + @plugins = [] + end + + def _load_from(path) + if path + @path = path + instance_eval(File.read(path), path, 1) + end + ensure + _offer_plugins + end + + def _offer_plugins + @plugins.each do |o| + if o.respond_to? :config + @options.shift + o.config self + end + end + + @plugins.clear + end + + def set_default_host(host) + @options[:default_host] = host + end + + def default_host + @options[:default_host] || Configuration::DEFAULTS[:tcp_host] + end + + def inject(&blk) + instance_eval(&blk) + end + + def get(key,default=nil) + @options[key.to_sym] || default + end + + # Load the named plugin for use by this configuration. + # + # @example + # plugin :tmp_restart + # + def plugin(name) + @plugins << @config.load_plugin(name) + end + + # Use an object or block as the rack application. This allows the + # configuration file to be the application itself. + # + # @example + # app do |env| + # body = 'Hello, World!' + # + # [ + # 200, + # { + # 'Content-Type' => 'text/plain', + # 'Content-Length' => body.length.to_s + # }, + # [body] + # ] + # end + # + # @see Puma::Configuration#app + # + def app(obj=nil, &block) + obj ||= block + + raise "Provide either a #call'able or a block" unless obj + + @options[:app] = obj + end + + # Start the Puma control rack application on +url+. This application can + # be communicated with to control the main server. Additionally, you can + # provide an authentication token, so all requests to the control server + # will need to include that token as a query parameter. This allows for + # simple authentication. + # + # Check out {Puma::App::Status} to see what the app has available. + # + # @example + # activate_control_app 'unix:///var/run/pumactl.sock' + # @example + # activate_control_app 'unix:///var/run/pumactl.sock', { auth_token: '12345' } + # @example + # activate_control_app 'unix:///var/run/pumactl.sock', { no_token: true } + # + def activate_control_app(url="auto", opts={}) + if url == "auto" + path = Configuration.temp_path + @options[:control_url] = "unix://#{path}" + @options[:control_url_temp] = path + else + @options[:control_url] = url + end + + if opts[:no_token] + # We need to use 'none' rather than :none because this value will be + # passed on to an instance of OptionParser, which doesn't support + # symbols as option values. + # + # See: https://github.com/puma/puma/issues/1193#issuecomment-305995488 + auth_token = 'none' + else + auth_token = opts[:auth_token] + auth_token ||= Configuration.random_token + end + + @options[:control_auth_token] = auth_token + @options[:control_url_umask] = opts[:umask] if opts[:umask] + end + + # Load additional configuration from a file. + # Files get loaded later via Configuration#load. + # + # @example + # load 'config/puma/production.rb' + # + def load(file) + @options[:config_files] ||= [] + @options[:config_files] << file + end + + # Bind the server to +url+. "tcp://", "unix://" and "ssl://" are the only + # accepted protocols. Multiple urls can be bound to, calling +bind+ does + # not overwrite previous bindings. + # + # The default is "tcp://0.0.0.0:9292". + # + # You can use query parameters within the url to specify options: + # + # * Set the socket backlog depth with +backlog+, default is 1024. + # * Set up an SSL certificate with +key+ & +cert+. + # * Set up an SSL certificate for mTLS with +key+, +cert+, +ca+ and +verify_mode+. + # * Set whether to optimize for low latency instead of throughput with + # +low_latency+, default is to not optimize for low latency. This is done + # via +Socket::TCP_NODELAY+. + # * Set socket permissions with +umask+. + # + # @example Backlog depth + # bind 'unix:///var/run/puma.sock?backlog=512' + # @example SSL cert + # bind 'ssl://127.0.0.1:9292?key=key.key&cert=cert.pem' + # @example SSL cert for mutual TLS (mTLS) + # bind 'ssl://127.0.0.1:9292?key=key.key&cert=cert.pem&ca=ca.pem&verify_mode=force_peer' + # @example Disable optimization for low latency + # bind 'tcp://0.0.0.0:9292?low_latency=false' + # @example Socket permissions + # bind 'unix:///var/run/puma.sock?umask=0111' + # + # @see Puma::Runner#load_and_bind + # @see Puma::Cluster#run + # + def bind(url) + @options[:binds] ||= [] + @options[:binds] << url + end + + def clear_binds! + @options[:binds] = [] + end + + # Bind to (systemd) activated sockets, regardless of configured binds. + # + # Systemd can present sockets as file descriptors that are already opened. + # By default Puma will use these but only if it was explicitly told to bind + # to the socket. If not, it will close the activated sockets. This means + # all configuration is duplicated. + # + # Binds can contain additional configuration, but only SSL config is really + # relevant since the unix and TCP socket options are ignored. + # + # This means there is a lot of duplicated configuration for no additional + # value in most setups. This method tells the launcher to bind to all + # activated sockets, regardless of existing bind. + # + # To clear configured binds, the value only can be passed. This will clear + # out any binds that may have been configured. + # + # @example Use any systemd activated sockets as well as configured binds + # bind_to_activated_sockets + # + # @example Only bind to systemd activated sockets, ignoring other binds + # bind_to_activated_sockets 'only' + # + def bind_to_activated_sockets(bind=true) + @options[:bind_to_activated_sockets] = bind + end + + # Define the TCP port to bind to. Use `bind` for more advanced options. + # + # The default is +9292+. + # + # @example + # port 3000 + # + def port(port, host=nil) + host ||= default_host + bind URI::Generic.build(scheme: 'tcp', host: host, port: Integer(port)).to_s + end + + # Define how long the tcp socket stays open, if no data has been received. + # + # The default is 30 seconds. + # + # @example + # first_data_timeout 40 + # + # @see Puma::Server.new + # + def first_data_timeout(seconds) + @options[:first_data_timeout] = Integer(seconds) + end + + # Define how long persistent connections can be idle before Puma closes them. + # + # The default is 20 seconds. + # + # @example + # persistent_timeout 30 + # + # @see Puma::Server.new + # + def persistent_timeout(seconds) + @options[:persistent_timeout] = Integer(seconds) + end + + # If a new request is not received within this number of seconds, begin shutting down. + # + # The default is +nil+. + # + # @example + # idle_timeout 60 + # + # @see Puma::Server.new + # + def idle_timeout(seconds) + @options[:idle_timeout] = Integer(seconds) + end + + # Work around leaky apps that leave garbage in Thread locals + # across requests. + # + # The default is +false+. + # + # @example + # clean_thread_locals + # + def clean_thread_locals(which=true) + @options[:clean_thread_locals] = which + end + + # When shutting down, drain the accept socket of pending connections and + # process them. This loops over the accept socket until there are no more + # read events and then stops looking and waits for the requests to finish. + # + # @see Puma::Server#graceful_shutdown + # + def drain_on_shutdown(which=true) + @options[:drain_on_shutdown] = which + end + + # Set the environment in which the rack's app will run. The value must be + # a string. + # + # The default is "development". + # + # @example + # environment 'production' + # + def environment(environment) + @options[:environment] = environment + end + + # How long to wait for threads to stop when shutting them down. + # Specifying :immediately will cause Puma to kill the threads immediately. + # Otherwise the value is the number of seconds to wait. + # + # Puma always waits a few seconds after killing a thread for it to try + # to finish up it's work, even in :immediately mode. + # + # The default is +:forever+. + # + # @see Puma::Server#graceful_shutdown + # + def force_shutdown_after(val=:forever) + i = case val + when :forever + -1 + when :immediately + 0 + else + Float(val) + end + + @options[:force_shutdown_after] = i + end + + # Code to run before doing a restart. This code should + # close log files, database connections, etc. + # + # This can be called multiple times to add code each time. + # + # @example + # on_restart do + # puts 'On restart...' + # end + # + def on_restart(&block) + process_hook :on_restart, nil, block, 'on_restart' + end + + # Command to use to restart Puma. This should be just how to + # load Puma itself (ie. 'ruby -Ilib bin/puma'), not the arguments + # to Puma, as those are the same as the original process. + # + # @example + # restart_command '/u/app/lolcat/bin/restart_puma' + # + def restart_command(cmd) + @options[:restart_cmd] = cmd.to_s + end + + # Store the pid of the server in the file at "path". + # + # @example + # pidfile '/u/apps/lolcat/tmp/pids/puma.pid' + # + def pidfile(path) + @options[:pidfile] = path.to_s + end + + # Disable request logging, the inverse of `log_requests`. + # + # The default is +true+. + # + # @example + # quiet + # + def quiet(which=true) + @options[:log_requests] = !which + end + + # Enable request logging, the inverse of `quiet`. + # + # The default is +false+. + # + # @example + # log_requests + # + def log_requests(which=true) + @options[:log_requests] = which + end + + # Pass in a custom logging class instance + # + # @example + # custom_logger Logger.new('t.log') + # + def custom_logger(custom_logger) + @options[:custom_logger] = custom_logger + end + + # Show debugging info + # + # The default is +false+. + # + # @example + # debug + # + def debug + @options[:debug] = true + end + + # Load +path+ as a rackup file. + # + # The default is "config.ru". + # + # @example + # rackup '/u/apps/lolcat/config.ru' + # + def rackup(path) + @options[:rackup] ||= path.to_s + end + + # Allows setting `env['rack.url_scheme']`. + # Only necessary if X-Forwarded-Proto is not being set by your proxy + # Normal values are 'http' or 'https'. + # + def rack_url_scheme(scheme=nil) + @options[:rack_url_scheme] = scheme + end + + # Enable HTTP 103 Early Hints responses. + # + # The default is +nil+. + # + # @example + # early_hints + # + def early_hints(answer=true) + @options[:early_hints] = answer + end + + # Redirect +STDOUT+ and +STDERR+ to files specified. The +append+ parameter + # specifies whether the output is appended. + # + # The default is +false+. + # + # @example + # stdout_redirect '/app/lolcat/log/stdout', '/app/lolcat/log/stderr' + # @example + # stdout_redirect '/app/lolcat/log/stdout', '/app/lolcat/log/stderr', true + # + def stdout_redirect(stdout=nil, stderr=nil, append=false) + @options[:redirect_stdout] = stdout + @options[:redirect_stderr] = stderr + @options[:redirect_append] = append + end + + def log_formatter(&block) + @options[:log_formatter] = block + end + + # Configure the number of threads to use to answer requests. + # + # It can be a single fixed number, or a +min+ and a +max+. + # + # The default is the environment variables +PUMA_MIN_THREADS+ / +PUMA_MAX_THREADS+ + # (or +MIN_THREADS+ / +MAX_THREADS+ if the +PUMA_+ variables aren't set). + # + # If these environment variables aren't set, the default is "0, 5" in MRI or "0, 16" for other interpreters. + # + # @example + # threads 5 + # @example + # threads 0, 16 + # @example + # threads 5, 5 + # + def threads(min, max = min) + min = Integer(min) + max = Integer(max) + if min > max + raise "The minimum (#{min}) number of threads must be less than or equal to the max (#{max})" + end + + if max < 1 + raise "The maximum number of threads (#{max}) must be greater than 0" + end + + @options[:min_threads] = min + @options[:max_threads] = max + end + + # Instead of using +bind+ and manually constructing a URI like: + # + # bind 'ssl://127.0.0.1:9292?key=key_path&cert=cert_path' + # + # you can use the this method. + # + # When binding on localhost you don't need to specify +cert+ and +key+, + # Puma will assume you are using the +localhost+ gem and try to load the + # appropriate files. + # + # When using the options hash parameter, the `reuse:` value is either + # `true`, which sets reuse 'on' with default values, or a hash, with `:size` + # and/or `:timeout` keys, each with integer values. + # + # The `cert:` options hash parameter can be the path to a certificate + # file including all intermediate certificates in PEM format. + # + # The `cert_pem:` options hash parameter can be String containing the + # cerificate and all intermediate certificates in PEM format. + # + # @example + # ssl_bind '127.0.0.1', '9292', { + # cert: path_to_cert, + # key: path_to_key, + # ssl_cipher_filter: cipher_filter, # optional + # ssl_ciphersuites: ciphersuites, # optional + # verify_mode: verify_mode, # default 'none' + # verification_flags: flags, # optional, not supported by JRuby + # reuse: true # optional + # } + # + # @example Using self-signed certificate with the +localhost+ gem: + # ssl_bind '127.0.0.1', '9292' + # + # @example Alternatively, you can provide +cert_pem+ and +key_pem+: + # ssl_bind '127.0.0.1', '9292', { + # cert_pem: File.read(path_to_cert), + # key_pem: File.read(path_to_key), + # reuse: {size: 2_000, timeout: 20} # optional + # } + # + # @example For JRuby, two keys are required: +keystore+ & +keystore_pass+ + # ssl_bind '127.0.0.1', '9292', { + # keystore: path_to_keystore, + # keystore_pass: password, + # ssl_cipher_list: cipher_list, # optional + # verify_mode: verify_mode # default 'none' + # } + # + def ssl_bind(host, port, opts = {}) + add_pem_values_to_options_store(opts) + bind self.class.ssl_bind_str(host, port, opts) + end + + # Use +path+ as the file to store the server info state. This is + # used by +pumactl+ to query and control the server. + # + # @example + # state_path '/u/apps/lolcat/tmp/pids/puma.state' + # + def state_path(path) + @options[:state] = path.to_s + end + + # Use +permission+ to restrict permissions for the state file. + # + # @example + # state_permission 0600 + # + # @version 5.0.0 + # + def state_permission(permission) + @options[:state_permission] = permission + end + + # How many worker processes to run. Typically this is set to + # the number of available cores. + # + # The default is the value of the environment variable +WEB_CONCURRENCY+ if + # set, otherwise 0. + # + # @note Cluster mode only. + # + # @example + # workers 2 + # + # @see Puma::Cluster + # + def workers(count) + @options[:workers] = count.to_i + end + + # Disable warning message when running in cluster mode with a single worker. + # + # Cluster mode has some overhead of running an additional 'control' process + # in order to manage the cluster. If only running a single worker it is + # likely not worth paying that overhead vs running in single mode with + # additional threads instead. + # + # There are some scenarios where running cluster mode with a single worker + # may still be warranted and valid under certain deployment scenarios, see + # https://github.com/puma/puma/issues/2534 + # + # Moving from workers = 1 to workers = 0 will save 10-30% of memory use. + # + # The default is +false+. + # + # @note Cluster mode only. + # + # @example + # silence_single_worker_warning + # + def silence_single_worker_warning + @options[:silence_single_worker_warning] = true + end + + # Disable warning message when running single mode with callback hook defined. + # + # The default is +false+. + # + # @example + # silence_fork_callback_warning + # + def silence_fork_callback_warning + @options[:silence_fork_callback_warning] = true + end + + # Code to run immediately before master process + # forks workers (once on boot). These hooks can block if necessary + # to wait for background operations unknown to Puma to finish before + # the process terminates. + # This can be used to close any connections to remote servers (database, + # Redis, ...) that were opened when preloading the code. + # + # This can be called multiple times to add several hooks. + # + # @note Cluster mode only. + # + # @example + # before_fork do + # puts "Starting workers..." + # end + # + def before_fork(&block) + warn_if_in_single_mode('before_fork') + + process_hook :before_fork, nil, block, 'before_fork' + end + + # Code to run in a worker when it boots to setup + # the process before booting the app. + # + # This can be called multiple times to add several hooks. + # + # @note Cluster mode only. + # + # @example + # on_worker_boot do + # puts 'Before worker boot...' + # end + # + def on_worker_boot(key = nil, &block) + warn_if_in_single_mode('on_worker_boot') + + process_hook :before_worker_boot, key, block, 'on_worker_boot' + end + + # Code to run immediately before a worker shuts + # down (after it has finished processing HTTP requests). The worker's + # index is passed as an argument. These hooks + # can block if necessary to wait for background operations unknown + # to Puma to finish before the process terminates. + # + # This can be called multiple times to add several hooks. + # + # @note Cluster mode only. + # + # @example + # on_worker_shutdown do + # puts 'On worker shutdown...' + # end + # + def on_worker_shutdown(key = nil, &block) + warn_if_in_single_mode('on_worker_shutdown') + + process_hook :before_worker_shutdown, key, block, 'on_worker_shutdown' + end + + # Code to run in the master right before a worker is started. The worker's + # index is passed as an argument. + # + # This can be called multiple times to add several hooks. + # + # @note Cluster mode only. + # + # @example + # on_worker_fork do + # puts 'Before worker fork...' + # end + # + def on_worker_fork(&block) + warn_if_in_single_mode('on_worker_fork') + + process_hook :before_worker_fork, nil, block, 'on_worker_fork' + end + + # Code to run in the master after a worker has been started. The worker's + # index is passed as an argument. + # + # This is called everytime a worker is to be started. + # + # @note Cluster mode only. + # + # @example + # after_worker_fork do + # puts 'After worker fork...' + # end + # + def after_worker_fork(&block) + warn_if_in_single_mode('after_worker_fork') + + process_hook :after_worker_fork, nil, block, 'after_worker_fork' + end + + alias_method :after_worker_boot, :after_worker_fork + + # Code to run after puma is booted (works for both: single and clustered) + # + # @example + # on_booted do + # puts 'After booting...' + # end + # + def on_booted(&block) + @config.options[:events].on_booted(&block) + end + + # Code to run after puma is stopped (works for both: single and clustered) + # + # @example + # on_stopped do + # puts 'After stopping...' + # end + # + def on_stopped(&block) + @config.options[:events].on_stopped(&block) + end + + # When `fork_worker` is enabled, code to run in Worker 0 + # before all other workers are re-forked from this process, + # after the server has temporarily stopped serving requests + # (once per complete refork cycle). + # + # This can be used to trigger extra garbage-collection to maximize + # copy-on-write efficiency, or close any connections to remote servers + # (database, Redis, ...) that were opened while the server was running. + # + # This can be called multiple times to add several hooks. + # + # @note Cluster mode with `fork_worker` enabled only. + # + # @example + # on_refork do + # 3.times {GC.start} + # end + # + # @version 5.0.0 + # + def on_refork(key = nil, &block) + warn_if_in_single_mode('on_refork') + + process_hook :before_refork, key, block, 'on_refork' + end + + # When `fork_worker` is enabled, code to run in Worker 0 + # after all other workers are re-forked from this process, + # after the server has temporarily stopped serving requests + # (once per complete refork cycle). + # + # This can be used to re-open any connections to remote servers + # (database, Redis, ...) that were closed via on_refork. + # + # This can be called multiple times to add several hooks. + # + # @note Cluster mode with `fork_worker` enabled only. + # + # @example + # after_refork do + # puts 'After refork...' + # end + # + def after_refork(key = nil, &block) + process_hook :after_refork, key, block, 'after_refork' + end + + # Provide a block to be executed just before a thread is added to the thread + # pool. Be careful: while the block executes, thread creation is delayed, and + # probably a request will have to wait too! The new thread will not be added to + # the threadpool until the provided block returns. + # + # Return values are ignored. + # Raising an exception will log a warning. + # + # This hook is useful for doing something when the thread pool grows. + # + # This can be called multiple times to add several hooks. + # + # @example + # on_thread_start do + # puts 'On thread start...' + # end + # + def on_thread_start(&block) + process_hook :before_thread_start, nil, block, 'on_thread_start' + end + + # Provide a block to be executed after a thread is trimmed from the thread + # pool. Be careful: while this block executes, Puma's main loop is + # blocked, so no new requests will be picked up. + # + # This hook only runs when a thread in the threadpool is trimmed by Puma. + # It does not run when a thread dies due to exceptions or any other cause. + # + # Return values are ignored. + # Raising an exception will log a warning. + # + # This hook is useful for cleaning up thread local resources when a thread + # is trimmed. + # + # This can be called multiple times to add several hooks. + # + # @example + # on_thread_exit do + # puts 'On thread exit...' + # end + # + def on_thread_exit(&block) + process_hook :before_thread_exit, nil, block, 'on_thread_exit' + end + + # Code to run out-of-band when the worker is idle. + # These hooks run immediately after a request has finished + # processing and there are no busy threads on the worker. + # The worker doesn't accept new requests until this code finishes. + # + # This hook is useful for running out-of-band garbage collection + # or scheduling asynchronous tasks to execute after a response. + # + # This can be called multiple times to add several hooks. + # + def out_of_band(&block) + process_hook :out_of_band, nil, block, 'out_of_band' + end + + # The directory to operate out of. + # + # The default is the current directory. + # + # @example + # directory '/u/apps/lolcat' + # + def directory(dir) + @options[:directory] = dir.to_s + end + + # Preload the application before starting the workers; this conflicts with + # phased restart feature. + # + # The default is +true+ if your app uses more than 1 worker. + # + # @note Cluster mode only. + # + # @example + # preload_app! + # + def preload_app!(answer=true) + @options[:preload_app] = answer + end + + # Use +obj+ or +block+ as the low level error handler. This allows the + # configuration file to change the default error on the server. + # + # @example + # lowlevel_error_handler do |err| + # [200, {}, ["error page"]] + # end + # + def lowlevel_error_handler(obj=nil, &block) + obj ||= block + raise "Provide either a #call'able or a block" unless obj + @options[:lowlevel_error_handler] = obj + end + + # This option is used to allow your app and its gems to be + # properly reloaded when not using preload. + # + # When set, if Puma detects that it's been invoked in the + # context of Bundler, it will cleanup the environment and + # re-run itself outside the Bundler environment, but directly + # using the files that Bundler has setup. + # + # This means that Puma is now decoupled from your Bundler + # context and when each worker loads, it will be loading a + # new Bundler context and thus can float around as the release + # dictates. + # + # @note This is incompatible with +preload_app!+. + # @note This is only supported for RubyGems 2.2+ + # + # @see extra_runtime_dependencies + # + def prune_bundler(answer=true) + @options[:prune_bundler] = answer + end + + # Raises a SignalException when SIGTERM is received. In environments where + # SIGTERM is something expected, you can suppress these with this option. + # + # This can be useful for example in Kubernetes, where rolling restart is + # guaranteed usually on the infrastructure level. + # + # The default is +true+. + # + # @example + # raise_exception_on_sigterm false + # + # @see Puma::Launcher#setup_signals + # @see Puma::Cluster#setup_signals + # + def raise_exception_on_sigterm(answer=true) + @options[:raise_exception_on_sigterm] = answer + end + + # When using prune_bundler, if extra runtime dependencies need to be loaded to + # initialize your app, then this setting can be used. This includes any Puma plugins. + # + # Before bundler is pruned, the gem names supplied will be looked up in the bundler + # context and then loaded again after bundler is pruned. + # Only applies if prune_bundler is used. + # + # @example + # extra_runtime_dependencies ['gem_name_1', 'gem_name_2'] + # @example + # extra_runtime_dependencies ['puma_worker_killer', 'puma-heroku'] + # + # @see Puma::Launcher#extra_runtime_deps_directories + # + def extra_runtime_dependencies(answer = []) + @options[:extra_runtime_dependencies] = Array(answer) + end + + # Additional text to display in process listing. + # + # If you do not specify a tag, Puma will infer it. If you do not want Puma + # to add a tag, use an empty string. + # + # The default is the current file or directory base name. + # + # @example + # tag 'app name' + # @example + # tag '' + # + def tag(string) + @options[:tag] = string.to_s + end + + # Change the default interval for checking workers. + # + # The default is 5 seconds. + # + # @note Cluster mode only. + # + # @example + # worker_check_interval 10 + # + # @see Puma::Cluster#check_workers + # + def worker_check_interval(interval) + @options[:worker_check_interval] = Integer(interval) + end + + # Verifies that all workers have checked in to the master process within + # the given timeout. If not the worker process will be restarted. This is + # not a request timeout, it is to protect against a hung or dead process. + # Setting this value will not protect against slow requests. + # + # This value must be greater than worker_check_interval. + # + # The default is 60 seconds. + # + # @note Cluster mode only. + # + # @example + # worker_timeout 60 + # + # @see Puma::Cluster::Worker#ping_timeout + # + def worker_timeout(timeout) + timeout = Integer(timeout) + min = @options.fetch(:worker_check_interval, Configuration::DEFAULTS[:worker_check_interval]) + + if timeout <= min + raise "The minimum worker_timeout must be greater than the worker reporting interval (#{min})" + end + + @options[:worker_timeout] = timeout + end + + # Change the default worker timeout for booting. + # + # The default is the value of `worker_timeout`. + # + # @note Cluster mode only. + # + # @example + # worker_boot_timeout 60 + # + # @see Puma::Cluster::Worker#ping_timeout + # + def worker_boot_timeout(timeout) + @options[:worker_boot_timeout] = Integer(timeout) + end + + # Set the timeout for worker shutdown. + # + # The default is 60 seconds. + # + # @note Cluster mode only. + # + # @example + # worker_shutdown_timeout 90 + # + # @see Puma::Cluster::Worker#term + # + def worker_shutdown_timeout(timeout) + @options[:worker_shutdown_timeout] = Integer(timeout) + end + + # Set the strategy for worker culling. + # + # There are two possible values: + # + # 1. **:youngest** - the youngest workers (i.e. the workers that were + # the most recently started) will be culled. + # 2. **:oldest** - the oldest workers (i.e. the workers that were started + # the longest time ago) will be culled. + # + # The default is +:youngest+. + # + # @note Cluster mode only. + # + # @example + # worker_culling_strategy :oldest + # + # @see Puma::Cluster#cull_workers + # + def worker_culling_strategy(strategy) + stategy = strategy.to_sym + + if ![:youngest, :oldest].include?(strategy) + raise "Invalid value for worker_culling_strategy - #{stategy}" + end + + @options[:worker_culling_strategy] = strategy + end + + # When set to true, workers accept all requests + # and queue them before passing them to the handlers. + # When set to false, each worker process accepts exactly as + # many requests as it is configured to simultaneously handle. + # + # Queueing requests generally improves performance. In some + # cases, such as a single threaded application, it may be + # better to ensure requests get balanced across workers. + # + # Note that setting this to false disables HTTP keepalive and + # slow clients will occupy a handler thread while the request + # is being sent. A reverse proxy, such as nginx, can handle + # slow clients and queue requests before they reach Puma. + # + # The default is +true+. + # + # @see Puma::Server + # + def queue_requests(answer=true) + @options[:queue_requests] = answer + end + + # When a shutdown is requested, the backtraces of all the + # threads will be written to $stdout. This can help figure + # out why shutdown is hanging. + # + def shutdown_debug(val=true) + @options[:shutdown_debug] = val + end + + + # Attempts to route traffic to less-busy workers by causing them to delay + # listening on the socket, allowing workers which are not processing any + # requests to pick up new requests first. + # + # The default is 0.005 seconds. + # + # Only works on MRI. For all other interpreters, this setting does nothing. + # + # @see Puma::Server#handle_servers + # @see Puma::ThreadPool#wait_for_less_busy_worker + # + # @version 5.0.0 + # + def wait_for_less_busy_worker(val=0.005) + @options[:wait_for_less_busy_worker] = val.to_f + end + + # Control how the remote address of the connection is set. This + # is configurable because to calculate the true socket peer address + # a kernel syscall is required which for very fast rack handlers + # slows down the handling significantly. + # + # There are 5 possible values: + # + # 1. **:socket** - read the peername from the socket using the + # syscall. This is the normal behavior. If this fails for any reason (e.g., + # if the peer disconnects between the connection being accepted and the getpeername + # system call), Puma will return "0.0.0.0" + # 2. **:localhost** - set the remote address to "127.0.0.1" + # 3. **header: **- set the remote address to the value of the + # provided http header. For instance: + # `set_remote_address header: "X-Real-IP"`. + # Only the first word (as separated by spaces or comma) is used, allowing + # headers such as X-Forwarded-For to be used as well. If this header is absent, + # Puma will fall back to the behavior of :socket + # 4. **proxy_protocol: :v1**- set the remote address to the value read from the + # HAproxy PROXY protocol, version 1. If the request does not have the PROXY + # protocol attached to it, will fall back to :socket + # 5. **\** - this allows you to hardcode remote address to any value + # you wish. Because Puma never uses this field anyway, it's format is + # entirely in your hands. + # + # The default is +:socket+. + # + # @example + # set_remote_address :localhost + # + def set_remote_address(val=:socket) + case val + when :socket + @options[:remote_address] = val + when :localhost + @options[:remote_address] = :value + @options[:remote_address_value] = "127.0.0.1".freeze + when String + @options[:remote_address] = :value + @options[:remote_address_value] = val + when Hash + if hdr = val[:header] + @options[:remote_address] = :header + @options[:remote_address_header] = "HTTP_" + hdr.upcase.tr("-", "_") + elsif protocol_version = val[:proxy_protocol] + @options[:remote_address] = :proxy_protocol + protocol_version = protocol_version.downcase.to_sym + unless [:v1].include?(protocol_version) + raise "Invalid value for proxy_protocol - #{protocol_version.inspect}" + end + @options[:remote_address_proxy_protocol] = protocol_version + else + raise "Invalid value for set_remote_address - #{val.inspect}" + end + else + raise "Invalid value for set_remote_address - #{val}" + end + end + + # When enabled, workers will be forked from worker 0 instead of from the master process. + # This option is similar to `preload_app` because the app is preloaded before forking, + # but it is compatible with phased restart. + # + # This option also enables the `refork` command (SIGURG), which optimizes copy-on-write performance + # in a running app. + # + # A refork will automatically trigger once after the specified number of requests + # (default 1000), or pass 0 to disable auto refork. + # + # @note Cluster mode only. + # + # @version 5.0.0 + # + def fork_worker(after_requests=1000) + @options[:fork_worker] = Integer(after_requests) + end + + # The number of requests to attempt inline before sending a client back to + # the reactor to be subject to normal ordering. + # + # The default is 10. + # + # @example + # max_fast_inline 20 + # + def max_fast_inline(num_of_requests) + @options[:max_fast_inline] = Float(num_of_requests) + end + + # When `true`, keep-alive connections are maintained on inbound requests. + # Enabling this setting reduces the number of TCP operations, reducing response + # times for connections that can send multiple requests in a single connection. + # + # When Puma receives more incoming connections than available Puma threads, + # enabling the keep-alive behavior may result in processing requests out-of-order, + # increasing overall response time variance. Increased response time variance + # means that the overall average of response times might not change, but more + # outliers will exist. Those long-tail outliers may significantly affect response + # times for some processed requests. + # + # When `false`, Puma closes the connection after each request, requiring the + # client to open a new request. Disabling this setting guarantees that requests + # will be processed in the order they are fully received, decreasing response + # variance and eliminating long-tail outliers caused by keep-alive behavior. + # The trade-off is that the number of TCP operations required will increase. + # + # The default is +true+. + # + # @example + # enable_keep_alives false + # + def enable_keep_alives(enabled=true) + @options[:enable_keep_alives] = enabled + end + + # Specify the backend for the IO selector. + # + # Provided values will be passed directly to +NIO::Selector.new+, with the + # exception of +:auto+ which will let nio4r choose the backend. + # + # Check the documentation of +NIO::Selector.backends+ for the list of valid + # options. Note that the available options on your system will depend on the + # operating system. If you want to use the pure Ruby backend (not + # recommended due to its comparatively low performance), set environment + # variable +NIO4R_PURE+ to +true+. + # + # The default is +:auto+. + # + # @see https://github.com/socketry/nio4r/blob/master/lib/nio/selector.rb + # + def io_selector_backend(backend) + @options[:io_selector_backend] = backend.to_sym + end + + # Ensures +STDOUT+ and +STDERR+ is immediately flushed to the underlying + # operating system and is not buffered internally + # + # The default is +true+. + # + # @example + # mutate_stdout_and_stderr_to_sync_on_write false + # + def mutate_stdout_and_stderr_to_sync_on_write(enabled=true) + @options[:mutate_stdout_and_stderr_to_sync_on_write] = enabled + end + + # Specify how big the request payload should be, in bytes. + # This limit is compared against Content-Length HTTP header. + # If the payload size (CONTENT_LENGTH) is larger than http_content_length_limit, + # HTTP 413 status code is returned. + # + # When no Content-Length http header is present, it is compared against the + # size of the body of the request. + # + # The default is +nil+. + # + # @example + # http_content_length_limit 2_000_000_000 + # + def http_content_length_limit(limit) + @options[:http_content_length_limit] = limit + end + + # Supported http methods, which will replace `Puma::Const::SUPPORTED_HTTP_METHODS`. + # The value of `:any` will allows all methods, otherwise, the value must be + # an array of strings. Note that methods are all uppercase. + # + # `Puma::Const::SUPPORTED_HTTP_METHODS` is conservative, if you want a + # complete set of methods, the methods defined by the + # [IANA Method Registry](https://www.iana.org/assignments/http-methods/http-methods.xhtml) + # are pre-defined as the constant `Puma::Const::IANA_HTTP_METHODS`. + # + # @note If the `methods` value is `:any`, no method check with be performed, + # similar to Puma v5 and earlier. + # + # @example Adds 'PROPFIND' to existing supported methods + # supported_http_methods(Puma::Const::SUPPORTED_HTTP_METHODS + ['PROPFIND']) + # @example Restricts methods to the array elements + # supported_http_methods %w[HEAD GET POST PUT DELETE OPTIONS PROPFIND] + # @example Restricts methods to the methods in the IANA Registry + # supported_http_methods Puma::Const::IANA_HTTP_METHODS + # @example Allows any method + # supported_http_methods :any + # + def supported_http_methods(methods) + if methods == :any + @options[:supported_http_methods] = :any + elsif Array === methods && methods == (ary = methods.grep(String).uniq) && + !ary.empty? + @options[:supported_http_methods] = ary + else + raise "supported_http_methods must be ':any' or a unique array of strings" + end + end + + private + + # To avoid adding cert_pem and key_pem as URI params, we store them on the + # options[:store] from where Puma binder knows how to find and extract them. + # + def add_pem_values_to_options_store(opts) + return if defined?(JRUBY_VERSION) + + @options[:store] ||= [] + + # Store cert_pem and key_pem to options[:store] if present + [:cert, :key].each do |v| + opt_key = :"#{v}_pem" + if opts[opt_key] + index = @options[:store].length + @options[:store] << opts[opt_key] + opts[v] = "store:#{index}" + end + end + end + + def process_hook(options_key, key, block, meth) + @options[options_key] ||= [] + if ON_WORKER_KEY.include? key.class + @options[options_key] << [block, key.to_sym] + elsif key.nil? + @options[options_key] << block + else + raise "'#{meth}' key must be String or Symbol" + end + end + + def warn_if_in_single_mode(hook_name) + return if @options[:silence_fork_callback_warning] + # user_options (CLI) have precedence over config file + workers_val = @config.options.user_options[:workers] || @options[:workers] || + @config.puma_default_options[:workers] || 0 + if workers_val == 0 + log_string = + "Warning: You specified code to run in a `#{hook_name}` block, " \ + "but Puma is not configured to run in cluster mode (worker count > 0), " \ + "so your `#{hook_name}` block will not run." + + LogWriter.stdio.log(log_string) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/error_logger.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/error_logger.rb new file mode 100644 index 00000000..792e14a6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/error_logger.rb @@ -0,0 +1,113 @@ +# frozen_string_literal: true + +require_relative 'const' + +module Puma + # The implementation of a detailed error logging. + # @version 5.0.0 + # + class ErrorLogger + include Const + + attr_reader :ioerr + + REQUEST_FORMAT = %{"%s %s%s" - (%s)} + + LOG_QUEUE = Queue.new + + def initialize(ioerr, env: ENV) + @ioerr = ioerr + + @debug = env.key?('PUMA_DEBUG') + end + + def self.stdio(env: ENV) + new($stderr, env: env) + end + + # Print occurred error details. + # +options+ hash with additional options: + # - +error+ is an exception object + # - +req+ the http request + # - +text+ (default nil) custom string to print in title + # and before all remaining info. + # + def info(options={}) + internal_write title(options) + end + + # Print occurred error details only if + # environment variable PUMA_DEBUG is defined. + # +options+ hash with additional options: + # - +error+ is an exception object + # - +req+ the http request + # - +text+ (default nil) custom string to print in title + # and before all remaining info. + # + def debug(options={}) + return unless @debug + + error = options[:error] + req = options[:req] + + string_block = [] + string_block << title(options) + string_block << request_dump(req) if request_parsed?(req) + string_block << error.backtrace if error + + internal_write string_block.join("\n") + end + + def title(options={}) + text = options[:text] + req = options[:req] + error = options[:error] + + string_block = ["#{Time.now}"] + string_block << " #{text}" if text + string_block << " (#{request_title(req)})" if request_parsed?(req) + string_block << ": #{error.inspect}" if error + string_block.join('') + end + + def request_dump(req) + "Headers: #{request_headers(req)}\n" \ + "Body: #{req.body}" + end + + def request_title(req) + env = req.env + + REQUEST_FORMAT % [ + env[REQUEST_METHOD], + env[REQUEST_PATH] || env[PATH_INFO], + env[QUERY_STRING] || "", + env[HTTP_X_FORWARDED_FOR] || env[REMOTE_ADDR] || "-" + ] + end + + def request_headers(req) + headers = req.env.select { |key, _| key.start_with?('HTTP_') } + headers.map { |key, value| [key[5..-1], value] }.to_h.inspect + end + + def request_parsed?(req) + req && req.env[REQUEST_METHOD] + end + + def internal_write(str) + LOG_QUEUE << str + while (w_str = LOG_QUEUE.pop(true)) do + begin + @ioerr.is_a?(IO) and @ioerr.wait_writable(1) + @ioerr.write "#{w_str}\n" + @ioerr.flush unless @ioerr.sync + rescue Errno::EPIPE, Errno::EBADF, IOError, Errno::EINVAL + # 'Invalid argument' (Errno::EINVAL) may be raised by flush + end + end + rescue ThreadError + end + private :internal_write + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/events.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/events.rb new file mode 100644 index 00000000..3ada3e13 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/events.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +module Puma + + # This is an event sink used by `Puma::Server` to handle + # lifecycle events such as :on_booted, :on_restart, and :on_stopped. + # Using `Puma::DSL` it is possible to register callback hooks + # for each event type. + class Events + + def initialize + @hooks = Hash.new { |h,k| h[k] = [] } + end + + # Fire callbacks for the named hook + def fire(hook, *args) + @hooks[hook].each { |t| t.call(*args) } + end + + # Register a callback for a given hook + def register(hook, obj=nil, &blk) + if obj and blk + raise "Specify either an object or a block, not both" + end + + h = obj || blk + + @hooks[hook] << h + + h + end + + def on_booted(&block) + register(:on_booted, &block) + end + + def on_restart(&block) + register(:on_restart, &block) + end + + def on_stopped(&block) + register(:on_stopped, &block) + end + + def fire_on_booted! + fire(:on_booted) + end + + def fire_on_restart! + fire(:on_restart) + end + + def fire_on_stopped! + fire(:on_stopped) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/io_buffer.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/io_buffer.rb new file mode 100644 index 00000000..d2265e97 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/io_buffer.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require 'stringio' + +module Puma + class IOBuffer < StringIO + def initialize + super.binmode + end + + def empty? + length.zero? + end + + def reset + truncate 0 + rewind + end + + def to_s + rewind + read + end + + # Read & Reset - returns contents and resets + # @return [String] StringIO contents + def read_and_reset + rewind + str = read + truncate 0 + rewind + str + end + + alias_method :clear, :reset + + # before Ruby 2.5, `write` would only take one argument + if RUBY_VERSION >= '2.5' && RUBY_ENGINE != 'truffleruby' + alias_method :append, :write + else + def append(*strs) + strs.each { |str| write str } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/jruby_restart.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/jruby_restart.rb new file mode 100644 index 00000000..48c410e3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/jruby_restart.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require 'ffi' + +module Puma + module JRubyRestart + extend FFI::Library + ffi_lib 'c' + attach_function :chdir, [:string], :int + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/json_serialization.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/json_serialization.rb new file mode 100644 index 00000000..94cad5c1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/json_serialization.rb @@ -0,0 +1,96 @@ +# frozen_string_literal: true +require 'stringio' + +module Puma + + # Puma deliberately avoids the use of the json gem and instead performs JSON + # serialization without any external dependencies. In a puma cluster, loading + # any gem into the puma master process means that operators cannot use a + # phased restart to upgrade their application if the new version of that + # application uses a different version of that gem. The json gem in + # particular is additionally problematic because it leverages native + # extensions. If the puma master process relies on a gem with native + # extensions and operators remove gems from disk related to old releases, + # subsequent phased restarts can fail. + # + # The implementation of JSON serialization in this module is not designed to + # be particularly full-featured or fast. It just has to handle the few places + # where Puma relies on JSON serialization internally. + + module JSONSerialization + QUOTE = /"/ + BACKSLASH = /\\/ + CONTROL_CHAR_TO_ESCAPE = /[\x00-\x1F]/ # As required by ECMA-404 + CHAR_TO_ESCAPE = Regexp.union QUOTE, BACKSLASH, CONTROL_CHAR_TO_ESCAPE + + class SerializationError < StandardError; end + + class << self + def generate(value) + StringIO.open do |io| + serialize_value io, value + io.string + end + end + + private + + def serialize_value(output, value) + case value + when Hash + output << '{' + value.each_with_index do |(k, v), index| + output << ',' if index != 0 + serialize_object_key output, k + output << ':' + serialize_value output, v + end + output << '}' + when Array + output << '[' + value.each_with_index do |member, index| + output << ',' if index != 0 + serialize_value output, member + end + output << ']' + when Integer, Float + output << value.to_s + when String + serialize_string output, value + when true + output << 'true' + when false + output << 'false' + when nil + output << 'null' + else + raise SerializationError, "Unexpected value of type #{value.class}" + end + end + + def serialize_string(output, value) + output << '"' + output << value.gsub(CHAR_TO_ESCAPE) do |character| + case character + when BACKSLASH + '\\\\' + when QUOTE + '\\"' + when CONTROL_CHAR_TO_ESCAPE + '\u%.4X' % character.ord + end + end + output << '"' + end + + def serialize_object_key(output, value) + case value + when Symbol, String + serialize_string output, value.to_s + else + raise SerializationError, "Could not serialize object of type #{value.class} as object key" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/launcher.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/launcher.rb new file mode 100644 index 00000000..1ecce525 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/launcher.rb @@ -0,0 +1,497 @@ +# frozen_string_literal: true + +require_relative 'log_writer' +require_relative 'events' +require_relative 'detect' +require_relative 'cluster' +require_relative 'single' +require_relative 'const' +require_relative 'binder' + +module Puma + # Puma::Launcher is the single entry point for starting a Puma server based on user + # configuration. It is responsible for taking user supplied arguments and resolving them + # with configuration in `config/puma.rb` or `config/puma/.rb`. + # + # It is responsible for either launching a cluster of Puma workers or a single + # puma server. + class Launcher + autoload :BundlePruner, 'puma/launcher/bundle_pruner' + + # Returns an instance of Launcher + # + # +conf+ A Puma::Configuration object indicating how to run the server. + # + # +launcher_args+ A Hash that currently has one required key `:events`, + # this is expected to hold an object similar to an `Puma::LogWriter.stdio`, + # this object will be responsible for broadcasting Puma's internal state + # to a logging destination. An optional key `:argv` can be supplied, + # this should be an array of strings, these arguments are re-used when + # restarting the puma server. + # + # Examples: + # + # conf = Puma::Configuration.new do |user_config| + # user_config.threads 1, 10 + # user_config.app do |env| + # [200, {}, ["hello world"]] + # end + # end + # Puma::Launcher.new(conf, log_writer: Puma::LogWriter.stdio).run + def initialize(conf, launcher_args={}) + @runner = nil + @log_writer = launcher_args[:log_writer] || LogWriter::DEFAULT + @events = launcher_args[:events] || Events.new + @argv = launcher_args[:argv] || [] + @original_argv = @argv.dup + @config = conf + + env = launcher_args.delete(:env) || ENV + + @config.options[:log_writer] = @log_writer + + # Advertise the Configuration + Puma.cli_config = @config if defined?(Puma.cli_config) + + @config.load + + @binder = Binder.new(@log_writer, conf) + @binder.create_inherited_fds(ENV).each { |k| ENV.delete k } + @binder.create_activated_fds(ENV).each { |k| ENV.delete k } + + @environment = conf.environment + + # Load the systemd integration if we detect systemd's NOTIFY_SOCKET. + # Skip this on JRuby though, because it is incompatible with the systemd + # integration due to https://github.com/jruby/jruby/issues/6504 + if ENV["NOTIFY_SOCKET"] && !Puma.jruby? && !ENV["PUMA_SKIP_SYSTEMD"] + @config.plugins.create('systemd') + end + + if @config.options[:bind_to_activated_sockets] + @config.options[:binds] = @binder.synthesize_binds_from_activated_fs( + @config.options[:binds], + @config.options[:bind_to_activated_sockets] == 'only' + ) + end + + @options = @config.options + @config.clamp + + @log_writer.formatter = LogWriter::PidFormatter.new if clustered? + @log_writer.formatter = options[:log_formatter] if @options[:log_formatter] + + @log_writer.custom_logger = options[:custom_logger] if @options[:custom_logger] + + generate_restart_data + + if clustered? && !Puma.forkable? + unsupported "worker mode not supported on #{RUBY_ENGINE} on this platform" + end + + Dir.chdir(@restart_dir) + + prune_bundler! + + @environment = @options[:environment] if @options[:environment] + set_rack_environment + + if clustered? + @options[:logger] = @log_writer + + @runner = Cluster.new(self) + else + @runner = Single.new(self) + end + Puma.stats_object = @runner + + @status = :run + + log_config if env['PUMA_LOG_CONFIG'] + end + + attr_reader :binder, :log_writer, :events, :config, :options, :restart_dir + + # Return stats about the server + def stats + @runner.stats + end + + # Write a state file that can be used by pumactl to control + # the server + def write_state + write_pid + + path = @options[:state] + permission = @options[:state_permission] + return unless path + + require_relative 'state_file' + + sf = StateFile.new + sf.pid = Process.pid + sf.control_url = @options[:control_url] + sf.control_auth_token = @options[:control_auth_token] + sf.running_from = File.expand_path('.') + + sf.save path, permission + end + + # Delete the configured pidfile + def delete_pidfile + path = @options[:pidfile] + File.unlink(path) if path && File.exist?(path) + end + + # Begin async shutdown of the server + def halt + @status = :halt + @runner.halt + end + + # Begin async shutdown of the server gracefully + def stop + @status = :stop + @runner.stop + end + + # Begin async restart of the server + def restart + @status = :restart + @runner.restart + end + + # Begin a phased restart if supported + def phased_restart + unless @runner.respond_to?(:phased_restart) and @runner.phased_restart + log "* phased-restart called but not available, restarting normally." + return restart + end + + if @options.file_options[:tag].nil? + dir = File.realdirpath(@restart_dir) + @options[:tag] = File.basename(dir) + set_process_title + end + + true + end + + # Begin a refork if supported + def refork + if clustered? && @runner.respond_to?(:fork_worker!) && @options[:fork_worker] + @runner.fork_worker! + true + else + log "* refork called but not available." + false + end + end + + # Run the server. This blocks until the server is stopped + def run + previous_env = get_env + + @config.clamp + + @config.plugins.fire_starts self + + setup_signals + set_process_title + + # This blocks until the server is stopped + @runner.run + + do_run_finished(previous_env) + end + + # Return all tcp ports the launcher may be using, TCP or SSL + # @!attribute [r] connected_ports + # @version 5.0.0 + def connected_ports + @binder.connected_ports + end + + # @!attribute [r] restart_args + def restart_args + cmd = @options[:restart_cmd] + if cmd + cmd.split(' ') + @original_argv + else + @restart_argv + end + end + + def close_binder_listeners + @runner.close_control_listeners + @binder.close_listeners + unless @status == :restart + log "=== puma shutdown: #{Time.now} ===" + log "- Goodbye!" + end + end + + # @!attribute [r] thread_status + # @version 5.0.0 + def thread_status + Thread.list.each do |thread| + name = "Thread: TID-#{thread.object_id.to_s(36)}" + name += " #{thread['label']}" if thread['label'] + name += " #{thread.name}" if thread.respond_to?(:name) && thread.name + backtrace = thread.backtrace || [""] + + yield name, backtrace + end + end + + private + + def get_env + if defined?(Bundler) + env = Bundler::ORIGINAL_ENV.dup + # add -rbundler/setup so we load from Gemfile when restarting + bundle = "-rbundler/setup" + env["RUBYOPT"] = [env["RUBYOPT"], bundle].join(" ").lstrip unless env["RUBYOPT"].to_s.include?(bundle) + env + else + ENV.to_h + end + end + + def do_run_finished(previous_env) + case @status + when :halt + do_forceful_stop + when :run, :stop + do_graceful_stop + when :restart + do_restart(previous_env) + end + + close_binder_listeners unless @status == :restart + end + + def do_forceful_stop + log "* Stopping immediately!" + @runner.stop_control + end + + def do_graceful_stop + @events.fire_on_stopped! + @runner.stop_blocked + end + + def do_restart(previous_env) + log "* Restarting..." + ENV.replace(previous_env) + @runner.stop_control + restart! + end + + def restart! + @events.fire_on_restart! + @config.run_hooks :on_restart, self, @log_writer + + if Puma.jruby? + close_binder_listeners + + require_relative 'jruby_restart' + argv = restart_args + JRubyRestart.chdir(@restart_dir) + Kernel.exec(*argv) + elsif Puma.windows? + close_binder_listeners + + argv = restart_args + Dir.chdir(@restart_dir) + Kernel.exec(*argv) + else + argv = restart_args + Dir.chdir(@restart_dir) + ENV.update(@binder.redirects_for_restart_env) + argv += [@binder.redirects_for_restart] + Kernel.exec(*argv) + end + end + + # If configured, write the pid of the current process out + # to a file. + def write_pid + path = @options[:pidfile] + return unless path + cur_pid = Process.pid + File.write path, cur_pid, mode: 'wb:UTF-8' + at_exit do + delete_pidfile if cur_pid == Process.pid + end + end + + def reload_worker_directory + @runner.reload_worker_directory if @runner.respond_to?(:reload_worker_directory) + end + + def log(str) + @log_writer.log(str) + end + + def clustered? + (@options[:workers] || 0) > 0 + end + + def unsupported(str) + @log_writer.error(str) + raise UnsupportedOption + end + + def set_process_title + Process.respond_to?(:setproctitle) ? Process.setproctitle(title) : $0 = title + end + + # @!attribute [r] title + def title + buffer = "puma #{Puma::Const::VERSION} (#{@options[:binds].join(',')})" + buffer += " [#{@options[:tag]}]" if @options[:tag] && !@options[:tag].empty? + buffer + end + + def set_rack_environment + @options[:environment] = environment + ENV['RACK_ENV'] = environment + end + + # @!attribute [r] environment + def environment + @environment + end + + def prune_bundler? + @options[:prune_bundler] && clustered? && !@options[:preload_app] + end + + def prune_bundler! + return unless prune_bundler? + BundlePruner.new(@original_argv, @options[:extra_runtime_dependencies], @log_writer).prune + end + + def generate_restart_data + if dir = @options[:directory] + @restart_dir = dir + + elsif Puma.windows? + # I guess the value of PWD is garbage on windows so don't bother + # using it. + @restart_dir = Dir.pwd + + # Use the same trick as unicorn, namely favor PWD because + # it will contain an unresolved symlink, useful for when + # the pwd is /data/releases/current. + elsif dir = ENV['PWD'] + s_env = File.stat(dir) + s_pwd = File.stat(Dir.pwd) + + if s_env.ino == s_pwd.ino and (Puma.jruby? or s_env.dev == s_pwd.dev) + @restart_dir = dir + end + end + + @restart_dir ||= Dir.pwd + + # if $0 is a file in the current directory, then restart + # it the same, otherwise add -S on there because it was + # picked up in PATH. + # + if File.exist?($0) + arg0 = [Gem.ruby, $0] + else + arg0 = [Gem.ruby, "-S", $0] + end + + # Detect and reinject -Ilib from the command line, used for testing without bundler + # cruby has an expanded path, jruby has just "lib" + lib = File.expand_path "lib" + arg0[1,0] = ["-I", lib] if [lib, "lib"].include?($LOAD_PATH[0]) + + if defined? Puma::WILD_ARGS + @restart_argv = arg0 + Puma::WILD_ARGS + @original_argv + else + @restart_argv = arg0 + @original_argv + end + end + + def setup_signals + unless ENV["PUMA_SKIP_SIGUSR2"] + begin + Signal.trap "SIGUSR2" do + restart + end + rescue Exception + log "*** SIGUSR2 not implemented, signal based restart unavailable!" + end + end + + unless Puma.jruby? + begin + Signal.trap "SIGUSR1" do + phased_restart + end + rescue Exception + log "*** SIGUSR1 not implemented, signal based restart unavailable!" + end + end + + begin + Signal.trap "SIGTERM" do + # Shortcut the control flow in case raise_exception_on_sigterm is true + do_graceful_stop + + raise(SignalException, "SIGTERM") if @options[:raise_exception_on_sigterm] + end + rescue Exception + log "*** SIGTERM not implemented, signal based gracefully stopping unavailable!" + end + + begin + Signal.trap "SIGINT" do + stop + end + rescue Exception + log "*** SIGINT not implemented, signal based gracefully stopping unavailable!" + end + + begin + Signal.trap "SIGHUP" do + if @runner.redirected_io? + @runner.redirect_io + else + stop + end + end + rescue Exception + log "*** SIGHUP not implemented, signal based logs reopening unavailable!" + end + + begin + unless Puma.jruby? # INFO in use by JVM already + Signal.trap "SIGINFO" do + thread_status do |name, backtrace| + @log_writer.log(name) + @log_writer.log(backtrace.map { |bt| " #{bt}" }) + end + end + end + rescue Exception + # Not going to log this one, as SIGINFO is *BSD only and would be pretty annoying + # to see this constantly on Linux. + end + end + + def log_config + log "Configuration:" + + @config.final_options + .each { |config_key, value| log "- #{config_key}: #{value}" } + + log "\n" + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/launcher/bundle_pruner.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/launcher/bundle_pruner.rb new file mode 100644 index 00000000..1b5c9116 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/launcher/bundle_pruner.rb @@ -0,0 +1,104 @@ +# frozen_string_literal: true + +module Puma + class Launcher + + # This class is used to pickup Gemfile changes during + # application restarts. + class BundlePruner + + def initialize(original_argv, extra_runtime_dependencies, log_writer) + @original_argv = Array(original_argv) + @extra_runtime_dependencies = Array(extra_runtime_dependencies) + @log_writer = log_writer + end + + def prune + return if ENV['PUMA_BUNDLER_PRUNED'] + return unless defined?(Bundler) + + require_rubygems_min_version! + + unless puma_wild_path + log "! Unable to prune Bundler environment, continuing" + return + end + + dirs = paths_to_require_after_prune + + log '* Pruning Bundler environment' + home = ENV['GEM_HOME'] + bundle_gemfile = Bundler.original_env['BUNDLE_GEMFILE'] + bundle_app_config = Bundler.original_env['BUNDLE_APP_CONFIG'] + + with_unbundled_env do + ENV['GEM_HOME'] = home + ENV['BUNDLE_GEMFILE'] = bundle_gemfile + ENV['PUMA_BUNDLER_PRUNED'] = '1' + ENV["BUNDLE_APP_CONFIG"] = bundle_app_config + args = [Gem.ruby, puma_wild_path, '-I', dirs.join(':')] + @original_argv + # Ruby 2.0+ defaults to true which breaks socket activation + args += [{:close_others => false}] + Kernel.exec(*args) + end + end + + private + + def require_rubygems_min_version! + min_version = Gem::Version.new('2.2') + + return if min_version <= Gem::Version.new(Gem::VERSION) + + raise "prune_bundler is not supported on your version of RubyGems. " \ + "You must have RubyGems #{min_version}+ to use this feature." + end + + def puma_wild_path + puma_lib_dir = puma_require_paths.detect { |x| File.exist? File.join(x, '../bin/puma-wild') } + File.expand_path(File.join(puma_lib_dir, '../bin/puma-wild')) + end + + def with_unbundled_env + bundler_ver = Gem::Version.new(Bundler::VERSION) + if bundler_ver < Gem::Version.new('2.1.0') + Bundler.with_clean_env { yield } + else + Bundler.with_unbundled_env { yield } + end + end + + def paths_to_require_after_prune + puma_require_paths + extra_runtime_deps_paths + end + + def extra_runtime_deps_paths + t = @extra_runtime_dependencies.map do |dep_name| + if (spec = spec_for_gem(dep_name)) + require_paths_for_gem(spec) + else + log "* Could not load extra dependency: #{dep_name}" + nil + end + end + t.flatten!; t.compact!; t + end + + def puma_require_paths + require_paths_for_gem(spec_for_gem('puma')) + end + + def spec_for_gem(gem_name) + Bundler.rubygems.loaded_specs(gem_name) + end + + def require_paths_for_gem(gem_spec) + gem_spec.full_require_paths + end + + def log(str) + @log_writer.log(str) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/log_writer.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/log_writer.rb new file mode 100644 index 00000000..9a1eb9dc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/log_writer.rb @@ -0,0 +1,147 @@ +# frozen_string_literal: true + +require_relative 'null_io' +require_relative 'error_logger' +require 'stringio' +require 'io/wait' unless Puma::HAS_NATIVE_IO_WAIT + +module Puma + + # Handles logging concerns for both standard messages + # (+stdout+) and errors (+stderr+). + class LogWriter + + class DefaultFormatter + def call(str) + str + end + end + + class PidFormatter + def call(str) + "[#{$$}] #{str}" + end + end + + LOG_QUEUE = Queue.new + + attr_reader :stdout, + :stderr + + attr_accessor :formatter, :custom_logger + + # Create a LogWriter that prints to +stdout+ and +stderr+. + def initialize(stdout, stderr, env: ENV) + @formatter = DefaultFormatter.new + @custom_logger = nil + @stdout = stdout + @stderr = stderr + + @debug = env.key?('PUMA_DEBUG') + @error_logger = ErrorLogger.new(@stderr, env: env) + end + + DEFAULT = new(STDOUT, STDERR) + + # Returns an LogWriter object which writes its status to + # two StringIO objects. + def self.strings(env: ENV) + LogWriter.new(StringIO.new, StringIO.new, env: env) + end + + def self.stdio(env: ENV) + LogWriter.new($stdout, $stderr, env: env) + end + + def self.null(env: ENV) + n = NullIO.new + LogWriter.new(n, n, env: env) + end + + # Write +str+ to +@stdout+ + def log(str) + if @custom_logger&.respond_to?(:write) + @custom_logger.write(format(str)) + else + internal_write "#{@formatter.call str}\n" + end + end + + def write(str) + internal_write @formatter.call(str) + end + + def internal_write(str) + LOG_QUEUE << str + while (w_str = LOG_QUEUE.pop(true)) do + begin + @stdout.is_a?(IO) and @stdout.wait_writable(1) + @stdout.write w_str + @stdout.flush unless @stdout.sync + rescue Errno::EPIPE, Errno::EBADF, IOError, Errno::EINVAL + # 'Invalid argument' (Errno::EINVAL) may be raised by flush + end + end + rescue ThreadError + end + private :internal_write + + def debug? + @debug + end + + def debug(str) + log("% #{str}") if @debug + end + + # Write +str+ to +@stderr+ + def error(str) + @error_logger.info(text: @formatter.call("ERROR: #{str}")) + exit 1 + end + + def format(str) + formatter.call(str) + end + + # An HTTP connection error has occurred. + # +error+ a connection exception, +req+ the request, + # and +text+ additional info + # @version 5.0.0 + def connection_error(error, req, text="HTTP connection error") + @error_logger.info(error: error, req: req, text: text) + end + + # An HTTP parse error has occurred. + # +error+ a parsing exception, + # and +req+ the request. + def parse_error(error, req) + @error_logger.info(error: error, req: req, text: 'HTTP parse error, malformed request') + end + + # An SSL error has occurred. + # @param error + # @param ssl_socket + def ssl_error(error, ssl_socket) + peeraddr = ssl_socket.peeraddr.last rescue "" + peercert = ssl_socket.peercert + subject = peercert&.subject + @error_logger.info(error: error, text: "SSL error, peer: #{peeraddr}, peer cert: #{subject}") + end + + # An unknown error has occurred. + # +error+ an exception object, +req+ the request, + # and +text+ additional info + def unknown_error(error, req=nil, text="Unknown error") + @error_logger.info(error: error, req: req, text: text) + end + + # Log occurred error debug dump. + # +error+ an exception object, +req+ the request, + # and +text+ additional info + # @version 5.0.0 + def debug_error(error, req=nil, text="") + @error_logger.debug(error: error, req: req, text: text) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/minissl.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/minissl.rb new file mode 100644 index 00000000..0ff2ce85 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/minissl.rb @@ -0,0 +1,459 @@ +# frozen_string_literal: true + +begin + require 'io/wait' unless Puma::HAS_NATIVE_IO_WAIT +rescue LoadError +end + +require 'open3' +# need for Puma::MiniSSL::OPENSSL constants used in `HAS_TLS1_3` +# use require, see https://github.com/puma/puma/pull/2381 +require 'puma/puma_http11' + +module Puma + module MiniSSL + # Define constant at runtime, as it's easy to determine at built time, + # but Puma could (it shouldn't) be loaded with an older OpenSSL version + # @version 5.0.0 + HAS_TLS1_3 = IS_JRUBY || + ((OPENSSL_VERSION[/ \d+\.\d+\.\d+/].split('.').map(&:to_i) <=> [1,1,1]) != -1 && + (OPENSSL_LIBRARY_VERSION[/ \d+\.\d+\.\d+/].split('.').map(&:to_i) <=> [1,1,1]) !=-1) + + class Socket + def initialize(socket, engine) + @socket = socket + @engine = engine + @peercert = nil + @reuse = nil + end + + # @!attribute [r] to_io + def to_io + @socket + end + + def closed? + @socket.closed? + end + + # Returns a two element array, + # first is protocol version (SSL_get_version), + # second is 'handshake' state (SSL_state_string) + # + # Used for dropping tcp connections to ssl. + # See OpenSSL ssl/ssl_stat.c SSL_state_string for info + # @!attribute [r] ssl_version_state + # @version 5.0.0 + # + def ssl_version_state + IS_JRUBY ? [nil, nil] : @engine.ssl_vers_st + end + + # Used to check the handshake status, in particular when a TCP connection + # is made with TLSv1.3 as an available protocol + # @version 5.0.0 + def bad_tlsv1_3? + HAS_TLS1_3 && ssl_version_state == ['TLSv1.3', 'SSLERR'] + end + private :bad_tlsv1_3? + + def readpartial(size) + while true + output = @engine.read + return output if output + + data = @socket.readpartial(size) + @engine.inject(data) + output = @engine.read + + return output if output + + while neg_data = @engine.extract + @socket.write neg_data + end + end + end + + def engine_read_all + output = @engine.read + while output and additional_output = @engine.read + output << additional_output + end + output + end + + def read_nonblock(size, *_) + # *_ is to deal with keyword args that were added + # at some point (and being used in the wild) + while true + output = engine_read_all + return output if output + + data = @socket.read_nonblock(size, exception: false) + if data == :wait_readable || data == :wait_writable + # It would make more sense to let @socket.read_nonblock raise + # EAGAIN if necessary but it seems like it'll misbehave on Windows. + # I don't have a Windows machine to debug this so I can't explain + # exactly whats happening in that OS. Please let me know if you + # find out! + # + # In the meantime, we can emulate the correct behavior by + # capturing :wait_readable & :wait_writable and raising EAGAIN + # ourselves. + raise IO::EAGAINWaitReadable + elsif data.nil? + raise SSLError.exception "HTTP connection?" if bad_tlsv1_3? + return nil + end + + @engine.inject(data) + output = engine_read_all + + return output if output + + while neg_data = @engine.extract + @socket.write neg_data + end + end + end + + def write(data) + return 0 if data.empty? + + data_size = data.bytesize + need = data_size + + while true + wrote = @engine.write data + + enc_wr = +'' + while (enc = @engine.extract) + enc_wr << enc + end + @socket.write enc_wr unless enc_wr.empty? + + need -= wrote + + return data_size if need == 0 + + data = data.byteslice(wrote..-1) + end + end + + alias_method :syswrite, :write + alias_method :<<, :write + + # This is a temporary fix to deal with websockets code using + # write_nonblock. + + # The problem with implementing it properly + # is that it means we'd have to have the ability to rewind + # an engine because after we write+extract, the socket + # write_nonblock call might raise an exception and later + # code would pass the same data in, but the engine would think + # it had already written the data in. + # + # So for the time being (and since write blocking is quite rare), + # go ahead and actually block in write_nonblock. + # + def write_nonblock(data, *_) + write data + end + + def flush + @socket.flush + end + + def close + begin + unless @engine.shutdown + while alert_data = @engine.extract + @socket.write alert_data + end + end + rescue IOError, SystemCallError + Puma::Util.purge_interrupt_queue + # nothing + ensure + @socket.close + end + end + + # @!attribute [r] peeraddr + def peeraddr + @socket.peeraddr + end + + # OpenSSL is loaded in `MiniSSL::ContextBuilder` when + # `MiniSSL::Context#verify_mode` is not `VERIFY_NONE`. + # When `VERIFY_NONE`, `MiniSSL::Engine#peercert` is nil, regardless of + # whether the client sends a cert. + # @return [OpenSSL::X509::Certificate, nil] + # @!attribute [r] peercert + def peercert + return @peercert if @peercert + + raw = @engine.peercert + return nil unless raw + + @peercert = OpenSSL::X509::Certificate.new raw + end + end + + if IS_JRUBY + OPENSSL_NO_SSL3 = false + OPENSSL_NO_TLS1 = false + end + + class Context + attr_accessor :verify_mode + attr_reader :no_tlsv1, :no_tlsv1_1 + + def initialize + @no_tlsv1 = false + @no_tlsv1_1 = false + @key = nil + @cert = nil + @key_pem = nil + @cert_pem = nil + @reuse = nil + @reuse_cache_size = nil + @reuse_timeout = nil + end + + def check_file(file, desc) + raise ArgumentError, "#{desc} file '#{file}' does not exist" unless File.exist? file + raise ArgumentError, "#{desc} file '#{file}' is not readable" unless File.readable? file + end + + if IS_JRUBY + # jruby-specific Context properties: java uses a keystore and password pair rather than a cert/key pair + attr_reader :keystore + attr_reader :keystore_type + attr_accessor :keystore_pass + attr_reader :truststore + attr_reader :truststore_type + attr_accessor :truststore_pass + attr_reader :cipher_suites + attr_reader :protocols + + def keystore=(keystore) + check_file keystore, 'Keystore' + @keystore = keystore + end + + def truststore=(truststore) + # NOTE: historically truststore was assumed the same as keystore, this is kept for backwards + # compatibility, to rely on JVM's trust defaults we allow setting `truststore = :default` + unless truststore.eql?(:default) + raise ArgumentError, "No such truststore file '#{truststore}'" unless File.exist?(truststore) + end + @truststore = truststore + end + + def keystore_type=(type) + raise ArgumentError, "Invalid keystore type: #{type.inspect}" unless ['pkcs12', 'jks', nil].include?(type) + @keystore_type = type + end + + def truststore_type=(type) + raise ArgumentError, "Invalid truststore type: #{type.inspect}" unless ['pkcs12', 'jks', nil].include?(type) + @truststore_type = type + end + + def cipher_suites=(list) + list = list.split(',').map(&:strip) if list.is_a?(String) + @cipher_suites = list + end + + # aliases for backwards compatibility + alias_method :ssl_cipher_list, :cipher_suites + alias_method :ssl_cipher_list=, :cipher_suites= + + def protocols=(list) + list = list.split(',').map(&:strip) if list.is_a?(String) + @protocols = list + end + + def check + raise "Keystore not configured" unless @keystore + # @truststore defaults to @keystore due backwards compatibility + end + + else + # non-jruby Context properties + attr_reader :key + attr_reader :key_password_command + attr_reader :cert + attr_reader :ca + attr_reader :cert_pem + attr_reader :key_pem + attr_accessor :ssl_cipher_filter + attr_accessor :ssl_ciphersuites + attr_accessor :verification_flags + + attr_reader :reuse, :reuse_cache_size, :reuse_timeout + + def key=(key) + check_file key, 'Key' + @key = key + end + + def key_password_command=(key_password_command) + @key_password_command = key_password_command + end + + def cert=(cert) + check_file cert, 'Cert' + @cert = cert + end + + def ca=(ca) + check_file ca, 'ca' + @ca = ca + end + + def cert_pem=(cert_pem) + raise ArgumentError, "'cert_pem' is not a String" unless cert_pem.is_a? String + @cert_pem = cert_pem + end + + def key_pem=(key_pem) + raise ArgumentError, "'key_pem' is not a String" unless key_pem.is_a? String + @key_pem = key_pem + end + + def check + raise "Key not configured" if @key.nil? && @key_pem.nil? + raise "Cert not configured" if @cert.nil? && @cert_pem.nil? + end + + # Executes the command to return the password needed to decrypt the key. + def key_password + raise "Key password command not configured" if @key_password_command.nil? + + stdout_str, stderr_str, status = Open3.capture3(@key_password_command) + + return stdout_str.chomp if status.success? + + raise "Key password failed with code #{status.exitstatus}: #{stderr_str}" + end + + # Controls session reuse. Allowed values are as follows: + # * 'off' - matches the behavior of Puma 5.6 and earlier. This is included + # in case reuse 'on' is made the default in future Puma versions. + # * 'dflt' - sets session reuse on, with OpenSSL default cache size of + # 20k and default timeout of 300 seconds. + # * 's,t' - where s and t are integer strings, for size and timeout. + # * 's' - where s is an integer strings for size. + # * ',t' - where t is an integer strings for timeout. + # + def reuse=(reuse_str) + case reuse_str + when 'off' + @reuse = nil + when 'dflt' + @reuse = true + when /\A\d+\z/ + @reuse = true + @reuse_cache_size = reuse_str.to_i + when /\A\d+,\d+\z/ + @reuse = true + size, time = reuse_str.split ',' + @reuse_cache_size = size.to_i + @reuse_timeout = time.to_i + when /\A,\d+\z/ + @reuse = true + @reuse_timeout = reuse_str.delete(',').to_i + end + end + end + + # disables TLSv1 + # @!attribute [w] no_tlsv1= + def no_tlsv1=(tlsv1) + raise ArgumentError, "Invalid value of no_tlsv1=" unless ['true', 'false', true, false].include?(tlsv1) + @no_tlsv1 = tlsv1 + end + + # disables TLSv1 and TLSv1.1. Overrides `#no_tlsv1=` + # @!attribute [w] no_tlsv1_1= + def no_tlsv1_1=(tlsv1_1) + raise ArgumentError, "Invalid value of no_tlsv1_1=" unless ['true', 'false', true, false].include?(tlsv1_1) + @no_tlsv1_1 = tlsv1_1 + end + + end + + VERIFY_NONE = 0 + VERIFY_PEER = 1 + VERIFY_FAIL_IF_NO_PEER_CERT = 2 + + # https://github.com/openssl/openssl/blob/master/include/openssl/x509_vfy.h.in + # /* Certificate verify flags */ + VERIFICATION_FLAGS = { + "USE_CHECK_TIME" => 0x2, + "CRL_CHECK" => 0x4, + "CRL_CHECK_ALL" => 0x8, + "IGNORE_CRITICAL" => 0x10, + "X509_STRICT" => 0x20, + "ALLOW_PROXY_CERTS" => 0x40, + "POLICY_CHECK" => 0x80, + "EXPLICIT_POLICY" => 0x100, + "INHIBIT_ANY" => 0x200, + "INHIBIT_MAP" => 0x400, + "NOTIFY_POLICY" => 0x800, + "EXTENDED_CRL_SUPPORT" => 0x1000, + "USE_DELTAS" => 0x2000, + "CHECK_SS_SIGNATURE" => 0x4000, + "TRUSTED_FIRST" => 0x8000, + "SUITEB_128_LOS_ONLY" => 0x10000, + "SUITEB_192_LOS" => 0x20000, + "SUITEB_128_LOS" => 0x30000, + "PARTIAL_CHAIN" => 0x80000, + "NO_ALT_CHAINS" => 0x100000, + "NO_CHECK_TIME" => 0x200000 + }.freeze + + class Server + def initialize(socket, ctx) + @socket = socket + @ctx = ctx + @eng_ctx = IS_JRUBY ? @ctx : SSLContext.new(ctx) + end + + def accept + @ctx.check + io = @socket.accept + engine = Engine.server @eng_ctx + Socket.new io, engine + end + + def accept_nonblock + @ctx.check + io = @socket.accept_nonblock + engine = Engine.server @eng_ctx + Socket.new io, engine + end + + # @!attribute [r] to_io + def to_io + @socket + end + + # @!attribute [r] addr + # @version 5.0.0 + def addr + @socket.addr + end + + def close + @socket.close unless @socket.closed? # closed? call is for Windows + end + + def closed? + @socket.closed? + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/minissl/context_builder.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/minissl/context_builder.rb new file mode 100644 index 00000000..6abce102 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/minissl/context_builder.rb @@ -0,0 +1,96 @@ +module Puma + module MiniSSL + class ContextBuilder + def initialize(params, log_writer) + @params = params + @log_writer = log_writer + end + + def context + ctx = MiniSSL::Context.new + + if defined?(JRUBY_VERSION) + unless params['keystore'] + log_writer.error "Please specify the Java keystore via 'keystore='" + end + + ctx.keystore = params['keystore'] + + unless params['keystore-pass'] + log_writer.error "Please specify the Java keystore password via 'keystore-pass='" + end + + ctx.keystore_pass = params['keystore-pass'] + ctx.keystore_type = params['keystore-type'] + + if truststore = params['truststore'] + ctx.truststore = truststore.eql?('default') ? :default : truststore + ctx.truststore_pass = params['truststore-pass'] + ctx.truststore_type = params['truststore-type'] + end + + ctx.cipher_suites = params['cipher_suites'] || params['ssl_cipher_list'] + ctx.protocols = params['protocols'] if params['protocols'] + else + if params['key'].nil? && params['key_pem'].nil? + log_writer.error "Please specify the SSL key via 'key=' or 'key_pem='" + end + + ctx.key = params['key'] if params['key'] + ctx.key_pem = params['key_pem'] if params['key_pem'] + ctx.key_password_command = params['key_password_command'] if params['key_password_command'] + + if params['cert'].nil? && params['cert_pem'].nil? + log_writer.error "Please specify the SSL cert via 'cert=' or 'cert_pem='" + end + + ctx.cert = params['cert'] if params['cert'] + ctx.cert_pem = params['cert_pem'] if params['cert_pem'] + + if ['peer', 'force_peer'].include?(params['verify_mode']) + unless params['ca'] + log_writer.error "Please specify the SSL ca via 'ca='" + end + # needed for Puma::MiniSSL::Socket#peercert, env['puma.peercert'] + require 'openssl' + end + + ctx.ca = params['ca'] if params['ca'] + ctx.ssl_cipher_filter = params['ssl_cipher_filter'] if params['ssl_cipher_filter'] + ctx.ssl_ciphersuites = params['ssl_ciphersuites'] if params['ssl_ciphersuites'] && HAS_TLS1_3 + + ctx.reuse = params['reuse'] if params['reuse'] + end + + ctx.no_tlsv1 = params['no_tlsv1'] == 'true' + ctx.no_tlsv1_1 = params['no_tlsv1_1'] == 'true' + + if params['verify_mode'] + ctx.verify_mode = case params['verify_mode'] + when "peer" + MiniSSL::VERIFY_PEER + when "force_peer" + MiniSSL::VERIFY_PEER | MiniSSL::VERIFY_FAIL_IF_NO_PEER_CERT + when "none" + MiniSSL::VERIFY_NONE + else + log_writer.error "Please specify a valid verify_mode=" + MiniSSL::VERIFY_NONE + end + end + + if params['verification_flags'] + ctx.verification_flags = params['verification_flags'].split(','). + map { |flag| MiniSSL::VERIFICATION_FLAGS.fetch(flag) }. + inject { |sum, flag| sum ? sum | flag : flag } + end + + ctx + end + + private + + attr_reader :params, :log_writer + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/null_io.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/null_io.rb new file mode 100644 index 00000000..13534cd4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/null_io.rb @@ -0,0 +1,101 @@ +# frozen_string_literal: true + +module Puma + # Provides an IO-like object that always appears to contain no data. + # Used as the value for rack.input when the request has no body. + # + class NullIO + def gets + nil + end + + def string + "" + end + + def each + end + + def pos + 0 + end + + # Mimics IO#read with no data. + # + def read(length = nil, buffer = nil) + if length.to_i < 0 + raise ArgumentError, "(negative length #{length} given)" + end + + buffer = if buffer.nil? + "".b + else + String.try_convert(buffer) or raise TypeError, "no implicit conversion of #{buffer.class} into String" + end + buffer.clear + if length.to_i > 0 + nil + else + buffer + end + end + + def rewind + end + + def seek(pos, whence = 0) + raise ArgumentError, "negative length #{pos} given" if pos.negative? + 0 + end + + def close + end + + def size + 0 + end + + def eof? + true + end + + def sync + true + end + + def sync=(v) + end + + def puts(*ary) + end + + def write(*ary) + end + + def flush + self + end + + # This is used as singleton class, so can't have state. + def closed? + false + end + + def set_encoding(enc) + self + end + + # per rack spec + def external_encoding + Encoding::ASCII_8BIT + end + + def binmode + self + end + + def binmode? + true + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/plugin.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/plugin.rb new file mode 100644 index 00000000..8a943b59 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/plugin.rb @@ -0,0 +1,111 @@ +# frozen_string_literal: true + +module Puma + class UnknownPlugin < RuntimeError; end + + class PluginLoader + def initialize + @instances = [] + end + + def create(name) + if cls = Plugins.find(name) + plugin = cls.new + @instances << plugin + return plugin + end + + raise UnknownPlugin, "File failed to register properly named plugin" + end + + def fire_starts(launcher) + @instances.each do |i| + if i.respond_to? :start + i.start(launcher) + end + end + end + end + + class PluginRegistry + def initialize + @plugins = {} + @background = [] + end + + def register(name, cls) + @plugins[name] = cls + end + + def find(name) + name = name.to_s + + if cls = @plugins[name] + return cls + end + + begin + require "puma/plugin/#{name}" + rescue LoadError + raise UnknownPlugin, "Unable to find plugin: #{name}" + end + + if cls = @plugins[name] + return cls + end + + raise UnknownPlugin, "file failed to register a plugin" + end + + def add_background(blk) + @background << blk + end + + def fire_background + @background.each_with_index do |b, i| + Thread.new do + Puma.set_thread_name "plgn bg #{i}" + b.call + end + end + end + end + + Plugins = PluginRegistry.new + + class Plugin + # Matches + # "C:/Ruby22/lib/ruby/gems/2.2.0/gems/puma-3.0.1/lib/puma/plugin/tmp_restart.rb:3:in `'" + # AS + # C:/Ruby22/lib/ruby/gems/2.2.0/gems/puma-3.0.1/lib/puma/plugin/tmp_restart.rb + CALLER_FILE = / + \A # start of string + .+ # file path (one or more characters) + (?= # stop previous match when + :\d+ # a colon is followed by one or more digits + :in # followed by a colon followed by in + ) + /x + + def self.extract_name(ary) + path = ary.first[CALLER_FILE] + + m = %r!puma/plugin/([^/]*)\.rb$!.match(path) + m[1] + end + + def self.create(&blk) + name = extract_name(caller) + + cls = Class.new(self) + + cls.class_eval(&blk) + + Plugins.register name, cls + end + + def in_background(&blk) + Plugins.add_background blk + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/plugin/systemd.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/plugin/systemd.rb new file mode 100644 index 00000000..d6c4715a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/plugin/systemd.rb @@ -0,0 +1,90 @@ +# frozen_string_literal: true + +require_relative '../plugin' + +# Puma's systemd integration allows Puma to inform systemd: +# 1. when it has successfully started +# 2. when it is starting shutdown +# 3. periodically for a liveness check with a watchdog thread +# 4. periodically set the status +Puma::Plugin.create do + def start(launcher) + require_relative '../sd_notify' + + launcher.log_writer.log "* Enabling systemd notification integration" + + # hook_events + launcher.events.on_booted { Puma::SdNotify.ready } + launcher.events.on_stopped { Puma::SdNotify.stopping } + launcher.events.on_restart { Puma::SdNotify.reloading } + + # start watchdog + if Puma::SdNotify.watchdog? + ping_f = watchdog_sleep_time + + in_background do + launcher.log_writer.log "Pinging systemd watchdog every #{ping_f.round(1)} sec" + loop do + sleep ping_f + Puma::SdNotify.watchdog + end + end + end + + # start status loop + instance = self + sleep_time = 1.0 + in_background do + launcher.log_writer.log "Sending status to systemd every #{sleep_time.round(1)} sec" + + loop do + sleep sleep_time + # TODO: error handling? + Puma::SdNotify.status(instance.status) + end + end + end + + def status + if clustered? + messages = stats[:worker_status].map do |worker| + common_message(worker[:last_status]) + end.join(',') + + "Puma #{Puma::Const::VERSION}: cluster: #{booted_workers}/#{workers}, worker_status: [#{messages}]" + else + "Puma #{Puma::Const::VERSION}: worker: #{common_message(stats)}" + end + end + + private + + def watchdog_sleep_time + usec = Integer(ENV["WATCHDOG_USEC"]) + + sec_f = usec / 1_000_000.0 + # "It is recommended that a daemon sends a keep-alive notification message + # to the service manager every half of the time returned here." + sec_f / 2 + end + + def stats + Puma.stats_hash + end + + def clustered? + stats.has_key?(:workers) + end + + def workers + stats.fetch(:workers, 1) + end + + def booted_workers + stats.fetch(:booted_workers, 1) + end + + def common_message(stats) + "{ #{stats[:running]}/#{stats[:max_threads]} threads, #{stats[:pool_capacity]} available, #{stats[:backlog]} backlog }" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/plugin/tmp_restart.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/plugin/tmp_restart.rb new file mode 100644 index 00000000..5136023c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/plugin/tmp_restart.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +require_relative '../plugin' + +Puma::Plugin.create do + def start(launcher) + path = File.join("tmp", "restart.txt") + + orig = nil + + # If we can't write to the path, then just don't bother with this plugin + begin + File.write(path, "") unless File.exist?(path) + orig = File.stat(path).mtime + rescue SystemCallError + return + end + + in_background do + while true + sleep 2 + + begin + mtime = File.stat(path).mtime + rescue SystemCallError + # If the file has disappeared, assume that means don't restart + else + if mtime > orig + launcher.restart + break + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/puma_http11.so b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/puma_http11.so new file mode 100755 index 00000000..e7b4de5b Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/puma_http11.so differ diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/rack/builder.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/rack/builder.rb new file mode 100644 index 00000000..2d73c607 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/rack/builder.rb @@ -0,0 +1,297 @@ +# frozen_string_literal: true + +module Puma +end + +module Puma::Rack + class Options + def parse!(args) + options = {} + opt_parser = OptionParser.new("", 24, ' ') do |opts| + opts.banner = "Usage: rackup [ruby options] [rack options] [rackup config]" + + opts.separator "" + opts.separator "Ruby options:" + + lineno = 1 + opts.on("-e", "--eval LINE", "evaluate a LINE of code") { |line| + eval line, TOPLEVEL_BINDING, "-e", lineno + lineno += 1 + } + + opts.on("-b", "--builder BUILDER_LINE", "evaluate a BUILDER_LINE of code as a builder script") { |line| + options[:builder] = line + } + + opts.on("-d", "--debug", "set debugging flags (set $DEBUG to true)") { + options[:debug] = true + } + opts.on("-w", "--warn", "turn warnings on for your script") { + options[:warn] = true + } + opts.on("-q", "--quiet", "turn off logging") { + options[:quiet] = true + } + + opts.on("-I", "--include PATH", + "specify $LOAD_PATH (may be used more than once)") { |path| + (options[:include] ||= []).concat(path.split(":")) + } + + opts.on("-r", "--require LIBRARY", + "require the library, before executing your script") { |library| + options[:require] = library + } + + opts.separator "" + opts.separator "Rack options:" + opts.on("-s", "--server SERVER", "serve using SERVER (thin/puma/webrick/mongrel)") { |s| + options[:server] = s + } + + opts.on("-o", "--host HOST", "listen on HOST (default: localhost)") { |host| + options[:Host] = host + } + + opts.on("-p", "--port PORT", "use PORT (default: 9292)") { |port| + options[:Port] = port + } + + opts.on("-O", "--option NAME[=VALUE]", "pass VALUE to the server as option NAME. If no VALUE, sets it to true. Run '#{$0} -s SERVER -h' to get a list of options for SERVER") { |name| + name, value = name.split('=', 2) + value = true if value.nil? + options[name.to_sym] = value + } + + opts.on("-E", "--env ENVIRONMENT", "use ENVIRONMENT for defaults (default: development)") { |e| + options[:environment] = e + } + + opts.on("-P", "--pid FILE", "file to store PID") { |f| + options[:pid] = ::File.expand_path(f) + } + + opts.separator "" + opts.separator "Common options:" + + opts.on_tail("-h", "-?", "--help", "Show this message") do + puts opts + puts handler_opts(options) + + exit + end + + opts.on_tail("--version", "Show version") do + puts "Rack #{Rack.version} (Release: #{Rack.release})" + exit + end + end + + begin + opt_parser.parse! args + rescue OptionParser::InvalidOption => e + warn e.message + abort opt_parser.to_s + end + + options[:config] = args.last if args.last + options + end + + def handler_opts(options) + begin + info = [] + server = Rack::Handler.get(options[:server]) || Rack::Handler.default(options) + if server&.respond_to?(:valid_options) + info << "" + info << "Server-specific options for #{server.name}:" + + has_options = false + server.valid_options.each do |name, description| + next if /^(Host|Port)[^a-zA-Z]/.match? name.to_s # ignore handler's host and port options, we do our own. + + info << " -O %-21s %s" % [name, description] + has_options = true + end + return "" if !has_options + end + info.join("\n") + rescue NameError + return "Warning: Could not find handler specified (#{options[:server] || 'default'}) to determine handler-specific options" + end + end + end + + # Rack::Builder implements a small DSL to iteratively construct Rack + # applications. + # + # Example: + # + # require 'rack/lobster' + # app = Rack::Builder.new do + # use Rack::CommonLogger + # use Rack::ShowExceptions + # map "/lobster" do + # use Rack::Lint + # run Rack::Lobster.new + # end + # end + # + # run app + # + # Or + # + # app = Rack::Builder.app do + # use Rack::CommonLogger + # run lambda { |env| [200, {'Content-Type' => 'text/plain'}, ['OK']] } + # end + # + # run app + # + # +use+ adds middleware to the stack, +run+ dispatches to an application. + # You can use +map+ to construct a Rack::URLMap in a convenient way. + + class Builder + def self.parse_file(config, opts = Options.new) + options = {} + if config =~ /\.ru$/ + cfgfile = ::File.read(config) + if cfgfile[/^#\\(.*)/] && opts + options = opts.parse! $1.split(/\s+/) + end + cfgfile.sub!(/^__END__\n.*\Z/m, '') + app = new_from_string cfgfile, config + else + require config + app = Object.const_get(::File.basename(config, '.rb').capitalize) + end + [app, options] + end + + def self.new_from_string(builder_script, file="(rackup)") + eval "Puma::Rack::Builder.new {\n" + builder_script + "\n}.to_app", + TOPLEVEL_BINDING, file, 0 + end + + def initialize(default_app = nil, &block) + @use, @map, @run, @warmup = [], nil, default_app, nil + + # Conditionally load rack now, so that any rack middlewares, + # etc are available. + begin + require 'rack' + rescue LoadError + end + + instance_eval(&block) if block + end + + def self.app(default_app = nil, &block) + self.new(default_app, &block).to_app + end + + # Specifies middleware to use in a stack. + # + # class Middleware + # def initialize(app) + # @app = app + # end + # + # def call(env) + # env["rack.some_header"] = "setting an example" + # @app.call(env) + # end + # end + # + # use Middleware + # run lambda { |env| [200, { "Content-Type" => "text/plain" }, ["OK"]] } + # + # All requests through to this application will first be processed by the middleware class. + # The +call+ method in this example sets an additional environment key which then can be + # referenced in the application if required. + def use(middleware, *args, &block) + if @map + mapping, @map = @map, nil + @use << proc { |app| generate_map app, mapping } + end + @use << proc { |app| middleware.new(app, *args, &block) } + end + + # Takes an argument that is an object that responds to #call and returns a Rack response. + # The simplest form of this is a lambda object: + # + # run lambda { |env| [200, { "Content-Type" => "text/plain" }, ["OK"]] } + # + # However this could also be a class: + # + # class Heartbeat + # def self.call(env) + # [200, { "Content-Type" => "text/plain" }, ["OK"]] + # end + # end + # + # run Heartbeat + def run(app) + @run = app + end + + # Takes a lambda or block that is used to warm-up the application. + # + # warmup do |app| + # client = Rack::MockRequest.new(app) + # client.get('/') + # end + # + # use SomeMiddleware + # run MyApp + def warmup(prc=nil, &block) + @warmup = prc || block + end + + # Creates a route within the application. + # + # Rack::Builder.app do + # map '/' do + # run Heartbeat + # end + # end + # + # The +use+ method can also be used here to specify middleware to run under a specific path: + # + # Rack::Builder.app do + # map '/' do + # use Middleware + # run Heartbeat + # end + # end + # + # This example includes a piece of middleware which will run before requests hit +Heartbeat+. + # + def map(path, &block) + @map ||= {} + @map[path] = block + end + + def to_app + app = @map ? generate_map(@run, @map) : @run + fail "missing run or map statement" unless app + app = @use.reverse.inject(app) { |a,e| e[a] } + @warmup&.call app + app + end + + def call(env) + to_app.call(env) + end + + private + + def generate_map(default_app, mapping) + require_relative 'urlmap' + + mapped = default_app ? {'/' => default_app} : {} + mapping.each { |r,b| mapped[r] = self.class.new(default_app, &b).to_app } + URLMap.new(mapped) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/rack/urlmap.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/rack/urlmap.rb new file mode 100644 index 00000000..baab2999 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/rack/urlmap.rb @@ -0,0 +1,93 @@ +# frozen_string_literal: true + +module Puma::Rack + # Rack::URLMap takes a hash mapping urls or paths to apps, and + # dispatches accordingly. Support for HTTP/1.1 host names exists if + # the URLs start with http:// or https://. + # + # URLMap modifies the SCRIPT_NAME and PATH_INFO such that the part + # relevant for dispatch is in the SCRIPT_NAME, and the rest in the + # PATH_INFO. This should be taken care of when you need to + # reconstruct the URL in order to create links. + # + # URLMap dispatches in such a way that the longest paths are tried + # first, since they are most specific. + + class URLMap + NEGATIVE_INFINITY = -1.0 / 0.0 + INFINITY = 1.0 / 0.0 + + def initialize(map = {}) + remap(map) + end + + def remap(map) + @mapping = map.map { |location, app| + if location =~ %r{\Ahttps?://(.*?)(/.*)} + host, location = $1, $2 + else + host = nil + end + + unless location[0] == ?/ + raise ArgumentError, "paths need to start with /" + end + + location = location.chomp('/') + match = Regexp.new("^#{Regexp.quote(location).gsub('/', '/+')}(.*)", Regexp::NOENCODING) + + [host, location, match, app] + }.sort_by do |(host, location, _, _)| + [host ? -host.size : INFINITY, -location.size] + end + end + + def call(env) + path = env['PATH_INFO'] + script_name = env['SCRIPT_NAME'] + http_host = env['HTTP_HOST'] + server_name = env['SERVER_NAME'] + server_port = env['SERVER_PORT'] + + is_same_server = casecmp?(http_host, server_name) || + casecmp?(http_host, "#{server_name}:#{server_port}") + + @mapping.each do |host, location, match, app| + unless casecmp?(http_host, host) \ + || casecmp?(server_name, host) \ + || (!host && is_same_server) + next + end + + next unless m = match.match(path.to_s) + + rest = m[1] + next unless !rest || rest.empty? || rest[0] == ?/ + + env['SCRIPT_NAME'] = (script_name + location) + env['PATH_INFO'] = rest + + return app.call(env) + end + + [404, {'Content-Type' => "text/plain", "X-Cascade" => "pass"}, ["Not Found: #{path}"]] + + ensure + env['PATH_INFO'] = path + env['SCRIPT_NAME'] = script_name + end + + private + def casecmp?(v1, v2) + # if both nil, or they're the same string + return true if v1 == v2 + + # if either are nil... (but they're not the same) + return false if v1.nil? + return false if v2.nil? + + # otherwise check they're not case-insensitive the same + v1.casecmp(v2).zero? + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/rack_default.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/rack_default.rb new file mode 100644 index 00000000..fa7ea2ed --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/rack_default.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require_relative '../rack/handler/puma' + +# rackup was removed in Rack 3, it is now a separate gem +if Object.const_defined? :Rackup + module Rackup + module Handler + def self.default(options = {}) + ::Rackup::Handler::Puma + end + end + end +elsif Object.const_defined?(:Rack) && Rack.release < '3' + module Rack + module Handler + def self.default(options = {}) + ::Rack::Handler::Puma + end + end + end +else + raise "Rack 3 must be used with the Rackup gem" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/reactor.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/reactor.rb new file mode 100644 index 00000000..1d74b421 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/reactor.rb @@ -0,0 +1,125 @@ +# frozen_string_literal: true + +module Puma + class UnsupportedBackend < StandardError; end + + # Monitors a collection of IO objects, calling a block whenever + # any monitored object either receives data or times out, or when the Reactor shuts down. + # + # The waiting/wake up is performed with nio4r, which will use the appropriate backend (libev, + # Java NIO or just plain IO#select). The call to `NIO::Selector#select` will + # 'wakeup' any IO object that receives data. + # + # This class additionally tracks a timeout for every added object, + # and wakes up any object when its timeout elapses. + # + # The implementation uses a Queue to synchronize adding new objects from the internal select loop. + class Reactor + # Create a new Reactor to monitor IO objects added by #add. + # The provided block will be invoked when an IO has data available to read, + # its timeout elapses, or when the Reactor shuts down. + def initialize(backend, &block) + require 'nio' + valid_backends = [:auto, *::NIO::Selector.backends] + unless valid_backends.include?(backend) + raise ArgumentError.new("unsupported IO selector backend: #{backend} (available backends: #{valid_backends.join(', ')})") + end + + @selector = ::NIO::Selector.new(NIO::Selector.backends.delete(backend)) + @input = Queue.new + @timeouts = [] + @block = block + end + + # Run the internal select loop, using a background thread by default. + def run(background=true) + if background + @thread = Thread.new do + Puma.set_thread_name "reactor" + select_loop + end + else + select_loop + end + end + + # Add a new client to monitor. + # The object must respond to #timeout and #timeout_at. + # Returns false if the reactor is already shut down. + def add(client) + @input << client + @selector.wakeup + true + rescue ClosedQueueError, IOError # Ignore if selector is already closed + false + end + + # Shutdown the reactor, blocking until the background thread is finished. + def shutdown + @input.close + begin + @selector.wakeup + rescue IOError # Ignore if selector is already closed + end + @thread&.join + end + + private + + def select_loop + close_selector = true + begin + until @input.closed? && @input.empty? + # Wakeup any registered object that receives incoming data. + # Block until the earliest timeout or Selector#wakeup is called. + timeout = (earliest = @timeouts.first) && earliest.timeout + @selector.select(timeout) {|mon| wakeup!(mon.value)} + + # Wakeup all objects that timed out. + timed_out = @timeouts.take_while {|t| t.timeout == 0} + timed_out.each { |c| wakeup! c } + + unless @input.empty? + until @input.empty? + client = @input.pop + register(client) if client.io_ok? + end + @timeouts.sort_by!(&:timeout_at) + end + end + rescue StandardError => e + STDERR.puts "Error in reactor loop escaped: #{e.message} (#{e.class})" + STDERR.puts e.backtrace + + # NoMethodError may be rarely raised when calling @selector.select, which + # is odd. Regardless, it may continue for thousands of calls if retried. + # Also, when it raises, @selector.close also raises an error. + if NoMethodError === e + close_selector = false + else + retry + end + end + # Wakeup all remaining objects on shutdown. + @timeouts.each(&@block) + @selector.close if close_selector + end + + # Start monitoring the object. + def register(client) + @selector.register(client.to_io, :r).value = client + @timeouts << client + rescue ArgumentError + # unreadable clients raise error when processed by NIO + end + + # 'Wake up' a monitored object by calling the provided block. + # Stop monitoring the object if the block returns `true`. + def wakeup!(client) + if @block.call client + @selector.deregister client.to_io + @timeouts.delete client + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/request.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/request.rb new file mode 100644 index 00000000..5f621599 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/request.rb @@ -0,0 +1,688 @@ +# frozen_string_literal: true + +module Puma + #———————————————————————— DO NOT USE — this class is for internal use only ——— + + + # The methods here are included in Server, but are separated into this file. + # All the methods here pertain to passing the request to the app, then + # writing the response back to the client. + # + # None of the methods here are called externally, with the exception of + # #handle_request, which is called in Server#process_client. + # @version 5.0.3 + # + module Request # :nodoc: + + # Single element array body: smaller bodies are written to io_buffer first, + # then a single write from io_buffer. Larger sizes are written separately. + # Also fixes max size of chunked file body read. + BODY_LEN_MAX = 1_024 * 256 + + # File body: smaller bodies are combined with io_buffer, then written to + # socket. Larger bodies are written separately using `copy_stream` + IO_BODY_MAX = 1_024 * 64 + + # Array body: elements are collected in io_buffer. When io_buffer's size + # exceeds value, they are written to the socket. + IO_BUFFER_LEN_MAX = 1_024 * 512 + + SOCKET_WRITE_ERR_MSG = "Socket timeout writing data" + + CUSTOM_STAT = 'CUSTOM' + + include Puma::Const + + # Takes the request contained in +client+, invokes the Rack application to construct + # the response and writes it back to +client.io+. + # + # It'll return +false+ when the connection is closed, this doesn't mean + # that the response wasn't successful. + # + # It'll return +:async+ if the connection remains open but will be handled + # elsewhere, i.e. the connection has been hijacked by the Rack application. + # + # Finally, it'll return +true+ on keep-alive connections. + # @param client [Puma::Client] + # @param requests [Integer] + # @return [Boolean,:async] + # + def handle_request(client, requests) + env = client.env + io_buffer = client.io_buffer + socket = client.io # io may be a MiniSSL::Socket + app_body = nil + + return false if closed_socket?(socket) + + if client.http_content_length_limit_exceeded + return prepare_response(413, {}, ["Payload Too Large"], requests, client) + end + + normalize_env env, client + + env[PUMA_SOCKET] = socket + + if env[HTTPS_KEY] && socket.peercert + env[PUMA_PEERCERT] = socket.peercert + end + + env[HIJACK_P] = true + env[HIJACK] = client + + env[RACK_INPUT] = client.body + env[RACK_URL_SCHEME] ||= default_server_port(env) == PORT_443 ? HTTPS : HTTP + + if @early_hints + env[EARLY_HINTS] = lambda { |headers| + begin + unless (str = str_early_hints headers).empty? + fast_write_str socket, "HTTP/1.1 103 Early Hints\r\n#{str}\r\n" + end + rescue ConnectionError => e + @log_writer.debug_error e + # noop, if we lost the socket we just won't send the early hints + end + } + end + + req_env_post_parse env + + # A rack extension. If the app writes #call'ables to this + # array, we will invoke them when the request is done. + # + env[RACK_AFTER_REPLY] ||= [] + + begin + if @supported_http_methods == :any || @supported_http_methods.key?(env[REQUEST_METHOD]) + status, headers, app_body = @thread_pool.with_force_shutdown do + @app.call(env) + end + else + @log_writer.log "Unsupported HTTP method used: #{env[REQUEST_METHOD]}" + status, headers, app_body = [501, {}, ["#{env[REQUEST_METHOD]} method is not supported"]] + end + + # app_body needs to always be closed, hold value in case lowlevel_error + # is called + res_body = app_body + + # full hijack, app called env['rack.hijack'] + return :async if client.hijacked + + status = status.to_i + + if status == -1 + unless headers.empty? and res_body == [] + raise "async response must have empty headers and body" + end + + return :async + end + rescue ThreadPool::ForceShutdown => e + @log_writer.unknown_error e, client, "Rack app" + @log_writer.log "Detected force shutdown of a thread" + + status, headers, res_body = lowlevel_error(e, env, 503) + rescue Exception => e + @log_writer.unknown_error e, client, "Rack app" + + status, headers, res_body = lowlevel_error(e, env, 500) + end + prepare_response(status, headers, res_body, requests, client) + ensure + io_buffer.reset + uncork_socket client.io + app_body.close if app_body.respond_to? :close + client&.tempfile_close + after_reply = env[RACK_AFTER_REPLY] || [] + begin + after_reply.each { |o| o.call } + rescue StandardError => e + @log_writer.debug_error e + end unless after_reply.empty? + end + + # Assembles the headers and prepares the body for actually sending the + # response via `#fast_write_response`. + # + # @param status [Integer] the status returned by the Rack application + # @param headers [Hash] the headers returned by the Rack application + # @param res_body [Array] the body returned by the Rack application or + # a call to `Server#lowlevel_error` + # @param requests [Integer] number of inline requests handled + # @param client [Puma::Client] + # @return [Boolean,:async] keep-alive status or `:async` + def prepare_response(status, headers, res_body, requests, client) + env = client.env + socket = client.io + io_buffer = client.io_buffer + + return false if closed_socket?(socket) + + # Close the connection after a reasonable number of inline requests + # if the server is at capacity and the listener has a new connection ready. + # This allows Puma to service connections fairly when the number + # of concurrent connections exceeds the size of the threadpool. + force_keep_alive = if @enable_keep_alives + requests < @max_fast_inline || + @thread_pool.busy_threads < @max_threads || + !client.listener.to_io.wait_readable(0) + else + # Always set force_keep_alive to false if the server has keep-alives not enabled. + false + end + + resp_info = str_headers(env, status, headers, res_body, io_buffer, force_keep_alive) + + close_body = false + response_hijack = nil + content_length = resp_info[:content_length] + keep_alive = resp_info[:keep_alive] + + if res_body.respond_to?(:each) && !resp_info[:response_hijack] + # below converts app_body into body, dependent on app_body's characteristics, and + # content_length will be set if it can be determined + if !content_length && !resp_info[:transfer_encoding] && status != 204 + if res_body.respond_to?(:to_ary) && (array_body = res_body.to_ary) && + array_body.is_a?(Array) + body = array_body.compact + content_length = body.sum(&:bytesize) + elsif res_body.is_a?(File) && res_body.respond_to?(:size) + body = res_body + content_length = body.size + elsif res_body.respond_to?(:to_path) && File.readable?(fn = res_body.to_path) + body = File.open fn, 'rb' + content_length = body.size + close_body = true + else + body = res_body + end + elsif !res_body.is_a?(::File) && res_body.respond_to?(:to_path) && + File.readable?(fn = res_body.to_path) + body = File.open fn, 'rb' + content_length = body.size + close_body = true + elsif !res_body.is_a?(::File) && res_body.respond_to?(:filename) && + res_body.respond_to?(:bytesize) && File.readable?(fn = res_body.filename) + # Sprockets::Asset + content_length = res_body.bytesize unless content_length + if (body_str = res_body.to_hash[:source]) + body = [body_str] + else # avoid each and use a File object + body = File.open fn, 'rb' + close_body = true + end + else + body = res_body + end + else + # partial hijack, from Rack spec: + # Servers must ignore the body part of the response tuple when the + # rack.hijack response header is present. + response_hijack = resp_info[:response_hijack] || res_body + end + + line_ending = LINE_END + + cork_socket socket + + if resp_info[:no_body] + # 101 (Switching Protocols) doesn't return here or have content_length, + # it should be using `response_hijack` + unless status == 101 + if content_length && status != 204 + io_buffer.append CONTENT_LENGTH_S, content_length.to_s, line_ending + end + + io_buffer << LINE_END + fast_write_str socket, io_buffer.read_and_reset + socket.flush + return keep_alive + end + else + if content_length + io_buffer.append CONTENT_LENGTH_S, content_length.to_s, line_ending + chunked = false + elsif !response_hijack && resp_info[:allow_chunked] + io_buffer << TRANSFER_ENCODING_CHUNKED + chunked = true + end + end + + io_buffer << line_ending + + # partial hijack, we write headers, then hand the socket to the app via + # response_hijack.call + if response_hijack + fast_write_str socket, io_buffer.read_and_reset + uncork_socket socket + response_hijack.call socket + return :async + end + + fast_write_response socket, body, io_buffer, chunked, content_length.to_i + body.close if close_body + keep_alive + end + + # @param env [Hash] see Puma::Client#env, from request + # @return [Puma::Const::PORT_443,Puma::Const::PORT_80] + # + def default_server_port(env) + if ['on', HTTPS].include?(env[HTTPS_KEY]) || env[HTTP_X_FORWARDED_PROTO].to_s[0...5] == HTTPS || env[HTTP_X_FORWARDED_SCHEME] == HTTPS || env[HTTP_X_FORWARDED_SSL] == "on" + PORT_443 + else + PORT_80 + end + end + + # Used to write 'early hints', 'no body' responses, 'hijacked' responses, + # and body segments (called by `fast_write_response`). + # Writes a string to a socket (normally `Client#io`) using `write_nonblock`. + # Large strings may not be written in one pass, especially if `io` is a + # `MiniSSL::Socket`. + # @param socket [#write_nonblock] the request/response socket + # @param str [String] the string written to the io + # @raise [ConnectionError] + # + def fast_write_str(socket, str) + n = 0 + byte_size = str.bytesize + while n < byte_size + begin + n += socket.write_nonblock(n.zero? ? str : str.byteslice(n..-1)) + rescue Errno::EAGAIN, Errno::EWOULDBLOCK + unless socket.wait_writable WRITE_TIMEOUT + raise ConnectionError, SOCKET_WRITE_ERR_MSG + end + retry + rescue Errno::EPIPE, SystemCallError, IOError + raise ConnectionError, SOCKET_WRITE_ERR_MSG + end + end + end + + # Used to write headers and body. + # Writes to a socket (normally `Client#io`) using `#fast_write_str`. + # Accumulates `body` items into `io_buffer`, then writes to socket. + # @param socket [#write] the response socket + # @param body [Enumerable, File] the body object + # @param io_buffer [Puma::IOBuffer] contains headers + # @param chunked [Boolean] + # @paramn content_length [Integer + # @raise [ConnectionError] + # + def fast_write_response(socket, body, io_buffer, chunked, content_length) + if body.is_a?(::File) && body.respond_to?(:read) + if chunked # would this ever happen? + while chunk = body.read(BODY_LEN_MAX) + io_buffer.append chunk.bytesize.to_s(16), LINE_END, chunk, LINE_END + end + fast_write_str socket, CLOSE_CHUNKED + else + if content_length <= IO_BODY_MAX + io_buffer.write body.read(content_length) + fast_write_str socket, io_buffer.read_and_reset + else + fast_write_str socket, io_buffer.read_and_reset + IO.copy_stream body, socket + end + end + elsif body.is_a?(::Array) && body.length == 1 + body_first = nil + # using body_first = body.first causes issues? + body.each { |str| body_first ||= str } + + if body_first.is_a?(::String) && body_first.bytesize < BODY_LEN_MAX + # smaller body, write to io_buffer first + io_buffer.write body_first + fast_write_str socket, io_buffer.read_and_reset + else + # large body, write both header & body to socket + fast_write_str socket, io_buffer.read_and_reset + fast_write_str socket, body_first + end + elsif body.is_a?(::Array) + # for array bodies, flush io_buffer to socket when size is greater than + # IO_BUFFER_LEN_MAX + if chunked + body.each do |part| + next if (byte_size = part.bytesize).zero? + io_buffer.append byte_size.to_s(16), LINE_END, part, LINE_END + if io_buffer.length > IO_BUFFER_LEN_MAX + fast_write_str socket, io_buffer.read_and_reset + end + end + io_buffer.write CLOSE_CHUNKED + else + body.each do |part| + next if part.bytesize.zero? + io_buffer.write part + if io_buffer.length > IO_BUFFER_LEN_MAX + fast_write_str socket, io_buffer.read_and_reset + end + end + end + # may write last body part for non-chunked, also headers if array is empty + fast_write_str(socket, io_buffer.read_and_reset) unless io_buffer.length.zero? + else + # for enum bodies + if chunked + empty_body = true + body.each do |part| + next if part.nil? || (byte_size = part.bytesize).zero? + empty_body = false + io_buffer.append byte_size.to_s(16), LINE_END, part, LINE_END + fast_write_str socket, io_buffer.read_and_reset + end + if empty_body + io_buffer << CLOSE_CHUNKED + fast_write_str socket, io_buffer.read_and_reset + else + fast_write_str socket, CLOSE_CHUNKED + end + else + fast_write_str socket, io_buffer.read_and_reset + body.each do |part| + next if part.bytesize.zero? + fast_write_str socket, part + end + end + end + socket.flush + rescue Errno::EAGAIN, Errno::EWOULDBLOCK + raise ConnectionError, SOCKET_WRITE_ERR_MSG + rescue Errno::EPIPE, SystemCallError, IOError + raise ConnectionError, SOCKET_WRITE_ERR_MSG + end + + private :fast_write_str, :fast_write_response + + # Given a Hash +env+ for the request read from +client+, add + # and fixup keys to comply with Rack's env guidelines. + # @param env [Hash] see Puma::Client#env, from request + # @param client [Puma::Client] only needed for Client#peerip + # + def normalize_env(env, client) + if host = env[HTTP_HOST] + # host can be a hostname, ipv4 or bracketed ipv6. Followed by an optional port. + if colon = host.rindex("]:") # IPV6 with port + env[SERVER_NAME] = host[0, colon+1] + env[SERVER_PORT] = host[colon+2, host.bytesize] + elsif !host.start_with?("[") && colon = host.index(":") # not hostname or IPV4 with port + env[SERVER_NAME] = host[0, colon] + env[SERVER_PORT] = host[colon+1, host.bytesize] + else + env[SERVER_NAME] = host + env[SERVER_PORT] = default_server_port(env) + end + else + env[SERVER_NAME] = LOCALHOST + env[SERVER_PORT] = default_server_port(env) + end + + unless env[REQUEST_PATH] + # it might be a dumbass full host request header + uri = begin + URI.parse(env[REQUEST_URI]) + rescue URI::InvalidURIError + raise Puma::HttpParserError + end + env[REQUEST_PATH] = uri.path + + # A nil env value will cause a LintError (and fatal errors elsewhere), + # so only set the env value if there actually is a value. + env[QUERY_STRING] = uri.query if uri.query + end + + env[PATH_INFO] = env[REQUEST_PATH].to_s # #to_s in case it's nil + + # From https://www.ietf.org/rfc/rfc3875 : + # "Script authors should be aware that the REMOTE_ADDR and + # REMOTE_HOST meta-variables (see sections 4.1.8 and 4.1.9) + # may not identify the ultimate source of the request. + # They identify the client for the immediate request to the + # server; that client may be a proxy, gateway, or other + # intermediary acting on behalf of the actual source client." + # + + unless env.key?(REMOTE_ADDR) + begin + addr = client.peerip + rescue Errno::ENOTCONN + # Client disconnects can result in an inability to get the + # peeraddr from the socket; default to unspec. + if client.peer_family == Socket::AF_INET6 + addr = UNSPECIFIED_IPV6 + else + addr = UNSPECIFIED_IPV4 + end + end + + # Set unix socket addrs to localhost + if addr.empty? + if client.peer_family == Socket::AF_INET6 + addr = LOCALHOST_IPV6 + else + addr = LOCALHOST_IPV4 + end + end + + env[REMOTE_ADDR] = addr + end + + # The legacy HTTP_VERSION header can be sent as a client header. + # Rack v4 may remove using HTTP_VERSION. If so, remove this line. + env[HTTP_VERSION] = env[SERVER_PROTOCOL] + end + private :normalize_env + + # @param header_key [#to_s] + # @return [Boolean] + # + def illegal_header_key?(header_key) + !!(ILLEGAL_HEADER_KEY_REGEX =~ header_key.to_s) + end + + # @param header_value [#to_s] + # @return [Boolean] + # + def illegal_header_value?(header_value) + !!(ILLEGAL_HEADER_VALUE_REGEX =~ header_value.to_s) + end + private :illegal_header_key?, :illegal_header_value? + + # Fixup any headers with `,` in the name to have `_` now. We emit + # headers with `,` in them during the parse phase to avoid ambiguity + # with the `-` to `_` conversion for critical headers. But here for + # compatibility, we'll convert them back. This code is written to + # avoid allocation in the common case (ie there are no headers + # with `,` in their names), that's why it has the extra conditionals. + # + # @note If a normalized version of a `,` header already exists, we ignore + # the `,` version. This prevents clobbering headers managed by proxies + # but not by clients (Like X-Forwarded-For). + # + # @param env [Hash] see Puma::Client#env, from request, modifies in place + # @version 5.0.3 + # + def req_env_post_parse(env) + to_delete = nil + to_add = nil + + env.each do |k,v| + if k.start_with?("HTTP_") && k.include?(",") && !UNMASKABLE_HEADERS.key?(k) + if to_delete + to_delete << k + else + to_delete = [k] + end + + new_k = k.tr(",", "_") + if env.key?(new_k) + next + end + + unless to_add + to_add = {} + end + + to_add[new_k] = v + end + end + + if to_delete # rubocop:disable Style/SafeNavigation + to_delete.each { |k| env.delete(k) } + end + + if to_add + env.merge! to_add + end + end + private :req_env_post_parse + + # Used in the lambda for env[ `Puma::Const::EARLY_HINTS` ] + # @param headers [Hash] the headers returned by the Rack application + # @return [String] + # @version 5.0.3 + # + def str_early_hints(headers) + eh_str = +"" + headers.each_pair do |k, vs| + next if illegal_header_key?(k) + + if vs.respond_to?(:to_s) && !vs.to_s.empty? + vs.to_s.split(NEWLINE).each do |v| + next if illegal_header_value?(v) + eh_str << "#{k}: #{v}\r\n" + end + elsif !(vs.to_s.empty? || !illegal_header_value?(vs)) + eh_str << "#{k}: #{vs}\r\n" + end + end + eh_str.freeze + end + private :str_early_hints + + # @param status [Integer] status from the app + # @return [String] the text description from Puma::HTTP_STATUS_CODES + # + def fetch_status_code(status) + HTTP_STATUS_CODES.fetch(status) { CUSTOM_STAT } + end + private :fetch_status_code + + # Processes and write headers to the IOBuffer. + # @param env [Hash] see Puma::Client#env, from request + # @param status [Integer] the status returned by the Rack application + # @param headers [Hash] the headers returned by the Rack application + # @param content_length [Integer,nil] content length if it can be determined from the + # response body + # @param io_buffer [Puma::IOBuffer] modified inn place + # @param force_keep_alive [Boolean] 'anded' with keep_alive, based on system + # status and `@max_fast_inline` + # @return [Hash] resp_info + # @version 5.0.3 + # + def str_headers(env, status, headers, res_body, io_buffer, force_keep_alive) + + line_ending = LINE_END + colon = COLON + + resp_info = {} + resp_info[:no_body] = env[REQUEST_METHOD] == HEAD + + http_11 = env[SERVER_PROTOCOL] == HTTP_11 + if http_11 + resp_info[:allow_chunked] = true + resp_info[:keep_alive] = env.fetch(HTTP_CONNECTION, "").downcase != CLOSE + + # An optimization. The most common response is 200, so we can + # reply with the proper 200 status without having to compute + # the response header. + # + if status == 200 + io_buffer << HTTP_11_200 + else + io_buffer.append "#{HTTP_11} #{status} ", fetch_status_code(status), line_ending + + resp_info[:no_body] ||= status < 200 || STATUS_WITH_NO_ENTITY_BODY[status] + end + else + resp_info[:allow_chunked] = false + resp_info[:keep_alive] = env.fetch(HTTP_CONNECTION, "").downcase == KEEP_ALIVE + + # Same optimization as above for HTTP/1.1 + # + if status == 200 + io_buffer << HTTP_10_200 + else + io_buffer.append "HTTP/1.0 #{status} ", + fetch_status_code(status), line_ending + + resp_info[:no_body] ||= status < 200 || STATUS_WITH_NO_ENTITY_BODY[status] + end + end + + # regardless of what the client wants, we always close the connection + # if running without request queueing + resp_info[:keep_alive] &&= @queue_requests + + # see prepare_response + resp_info[:keep_alive] &&= force_keep_alive + + resp_info[:response_hijack] = nil + + headers.each do |k, vs| + next if illegal_header_key?(k) + + case k.downcase + when CONTENT_LENGTH2 + next if illegal_header_value?(vs) + # nil.to_i is 0, nil&.to_i is nil + resp_info[:content_length] = vs&.to_i + next + when TRANSFER_ENCODING + resp_info[:allow_chunked] = false + resp_info[:content_length] = nil + resp_info[:transfer_encoding] = vs + when HIJACK + resp_info[:response_hijack] = vs + next + when BANNED_HEADER_KEY + next + end + + ary = if vs.is_a?(::Array) && !vs.empty? + vs + elsif vs.respond_to?(:to_s) && !vs.to_s.empty? + vs.to_s.split NEWLINE + else + nil + end + if ary + ary.each do |v| + next if illegal_header_value?(v) + io_buffer.append k, colon, v, line_ending + end + else + io_buffer.append k, colon, line_ending + end + end + + # HTTP/1.1 & 1.0 assume different defaults: + # - HTTP 1.0 assumes the connection will be closed if not specified + # - HTTP 1.1 assumes the connection will be kept alive if not specified. + # Only set the header if we're doing something which is not the default + # for this protocol version + if http_11 + io_buffer << CONNECTION_CLOSE if !resp_info[:keep_alive] + else + io_buffer << CONNECTION_KEEP_ALIVE if resp_info[:keep_alive] + end + resp_info + end + private :str_headers + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/runner.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/runner.rb new file mode 100644 index 00000000..2b8a9690 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/runner.rb @@ -0,0 +1,220 @@ +# frozen_string_literal: true + +require_relative 'server' +require_relative 'const' + +module Puma + # Generic class that is used by `Puma::Cluster` and `Puma::Single` to + # serve requests. This class spawns a new instance of `Puma::Server` via + # a call to `start_server`. + class Runner + + include ::Puma::Const::PipeRequest + + def initialize(launcher) + @launcher = launcher + @log_writer = launcher.log_writer + @events = launcher.events + @config = launcher.config + @options = launcher.options + @app = nil + @control = nil + @started_at = Time.now + @wakeup = nil + end + + # Returns the hash of configuration options. + # @return [Puma::UserFileDefaultOptions] + attr_reader :options + + def wakeup! + return unless @wakeup + + @wakeup.write PIPE_WAKEUP unless @wakeup.closed? + + rescue SystemCallError, IOError + Puma::Util.purge_interrupt_queue + end + + def development? + @options[:environment] == "development" + end + + def test? + @options[:environment] == "test" + end + + def log(str) + @log_writer.log str + end + + # @version 5.0.0 + def stop_control + @control&.stop true + end + + def error(str) + @log_writer.error str + end + + def debug(str) + @log_writer.log "- #{str}" if @options[:debug] + end + + def start_control + str = @options[:control_url] + return unless str + + require_relative 'app/status' + + if token = @options[:control_auth_token] + token = nil if token.empty? || token == 'none' + end + + app = Puma::App::Status.new @launcher, token + + # A Reactor is not created and nio4r is not loaded when 'queue_requests: false' + # Use `nil` for events, no hooks in control server + control = Puma::Server.new app, nil, + { min_threads: 0, max_threads: 1, queue_requests: false, log_writer: @log_writer } + + begin + control.binder.parse [str], nil, 'Starting control server' + rescue Errno::EADDRINUSE, Errno::EACCES => e + raise e, "Error: Control server address '#{str}' is already in use. Original error: #{e.message}" + end + + control.run thread_name: 'ctl' + @control = control + end + + # @version 5.0.0 + def close_control_listeners + @control.binder.close_listeners if @control + end + + # @!attribute [r] ruby_engine + # @deprecated Use `RUBY_DESCRIPTION` instead + def ruby_engine + warn "Puma::Runner#ruby_engine is deprecated; use RUBY_DESCRIPTION instead. It will be removed in puma v7." + + if !defined?(RUBY_ENGINE) || RUBY_ENGINE == "ruby" + "ruby #{RUBY_VERSION}-p#{RUBY_PATCHLEVEL}" + else + if defined?(RUBY_ENGINE_VERSION) + "#{RUBY_ENGINE} #{RUBY_ENGINE_VERSION} - ruby #{RUBY_VERSION}" + else + "#{RUBY_ENGINE} #{RUBY_VERSION}" + end + end + end + + def output_header(mode) + min_t = @options[:min_threads] + max_t = @options[:max_threads] + environment = @options[:environment] + + log "Puma starting in #{mode} mode..." + log "* Puma version: #{Puma::Const::PUMA_VERSION} (\"#{Puma::Const::CODE_NAME}\")" + log "* Ruby version: #{RUBY_DESCRIPTION}" + log "* Min threads: #{min_t}" + log "* Max threads: #{max_t}" + log "* Environment: #{environment}" + + if mode == "cluster" + log "* Master PID: #{Process.pid}" + else + log "* PID: #{Process.pid}" + end + end + + def redirected_io? + @options[:redirect_stdout] || @options[:redirect_stderr] + end + + def redirect_io + stdout = @options[:redirect_stdout] + stderr = @options[:redirect_stderr] + append = @options[:redirect_append] + + if stdout + ensure_output_directory_exists(stdout, 'STDOUT') + + STDOUT.reopen stdout, (append ? "a" : "w") + STDOUT.puts "=== puma startup: #{Time.now} ===" + STDOUT.flush unless STDOUT.sync + end + + if stderr + ensure_output_directory_exists(stderr, 'STDERR') + + STDERR.reopen stderr, (append ? "a" : "w") + STDERR.puts "=== puma startup: #{Time.now} ===" + STDERR.flush unless STDERR.sync + end + + if @options[:mutate_stdout_and_stderr_to_sync_on_write] + STDOUT.sync = true + STDERR.sync = true + end + end + + def load_and_bind + unless @config.app_configured? + error "No application configured, nothing to run" + exit 1 + end + + begin + @app = @config.app + rescue Exception => e + log "! Unable to load application: #{e.class}: #{e.message}" + raise e + end + + @launcher.binder.parse @options[:binds] + end + + # @!attribute [r] app + def app + @app ||= @config.app + end + + def start_server + server = Puma::Server.new(app, @events, @options) + server.inherit_binder(@launcher.binder) + server + end + + private + def ensure_output_directory_exists(path, io_name) + unless Dir.exist?(File.dirname(path)) + raise "Cannot redirect #{io_name} to #{path}" + end + end + + def utc_iso8601(val) + "#{val.utc.strftime '%FT%T'}Z" + end + + def stats + { + versions: { + puma: Puma::Const::PUMA_VERSION, + ruby: { + engine: RUBY_ENGINE, + version: RUBY_VERSION, + patchlevel: RUBY_PATCHLEVEL + } + } + } + end + + # this method call should always be guarded by `@log_writer.debug?` + def debug_loaded_extensions(str) + @log_writer.debug "────────────────────────────────── #{str}" + re_ext = /\.#{RbConfig::CONFIG['DLEXT']}\z/i + $LOADED_FEATURES.grep(re_ext).each { |f| @log_writer.debug(" #{f}") } + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/sd_notify.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/sd_notify.rb new file mode 100644 index 00000000..7001fd02 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/sd_notify.rb @@ -0,0 +1,146 @@ +# frozen_string_literal: true + +require "socket" + +module Puma + # The MIT License + # + # Copyright (c) 2017-2022 Agis Anastasopoulos + # + # 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 AUTHORS OR + # COPYRIGHT HOLDERS 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. + # + # This is a copy of https://github.com/agis/ruby-sdnotify as of commit cca575c + # The only changes made was "rehoming" it within the Puma module to avoid + # namespace collisions and applying standard's code formatting style. + # + # SdNotify is a pure-Ruby implementation of sd_notify(3). It can be used to + # notify systemd about state changes. Methods of this package are no-op on + # non-systemd systems (eg. Darwin). + # + # The API maps closely to the original implementation of sd_notify(3), + # therefore be sure to check the official man pages prior to using SdNotify. + # + # @see https://www.freedesktop.org/software/systemd/man/sd_notify.html + module SdNotify + # Exception raised when there's an error writing to the notification socket + class NotifyError < RuntimeError; end + + READY = "READY=1" + RELOADING = "RELOADING=1" + STOPPING = "STOPPING=1" + STATUS = "STATUS=" + ERRNO = "ERRNO=" + MAINPID = "MAINPID=" + WATCHDOG = "WATCHDOG=1" + FDSTORE = "FDSTORE=1" + + def self.ready(unset_env=false) + notify(READY, unset_env) + end + + def self.reloading(unset_env=false) + notify(RELOADING, unset_env) + end + + def self.stopping(unset_env=false) + notify(STOPPING, unset_env) + end + + # @param status [String] a custom status string that describes the current + # state of the service + def self.status(status, unset_env=false) + notify("#{STATUS}#{status}", unset_env) + end + + # @param errno [Integer] + def self.errno(errno, unset_env=false) + notify("#{ERRNO}#{errno}", unset_env) + end + + # @param pid [Integer] + def self.mainpid(pid, unset_env=false) + notify("#{MAINPID}#{pid}", unset_env) + end + + def self.watchdog(unset_env=false) + notify(WATCHDOG, unset_env) + end + + def self.fdstore(unset_env=false) + notify(FDSTORE, unset_env) + end + + # @param [Boolean] true if the service manager expects watchdog keep-alive + # notification messages to be sent from this process. + # + # If the $WATCHDOG_USEC environment variable is set, + # and the $WATCHDOG_PID variable is unset or set to the PID of the current + # process + # + # @note Unlike sd_watchdog_enabled(3), this method does not mutate the + # environment. + def self.watchdog? + wd_usec = ENV["WATCHDOG_USEC"] + wd_pid = ENV["WATCHDOG_PID"] + + return false if !wd_usec + + begin + wd_usec = Integer(wd_usec) + rescue + return false + end + + return false if wd_usec <= 0 + return true if !wd_pid || wd_pid == $$.to_s + + false + end + + # Notify systemd with the provided state, via the notification socket, if + # any. + # + # Generally this method will be used indirectly through the other methods + # of the library. + # + # @param state [String] + # @param unset_env [Boolean] + # + # @return [Fixnum, nil] the number of bytes written to the notification + # socket or nil if there was no socket to report to (eg. the program wasn't + # started by systemd) + # + # @raise [NotifyError] if there was an error communicating with the systemd + # socket + # + # @see https://www.freedesktop.org/software/systemd/man/sd_notify.html + def self.notify(state, unset_env=false) + sock = ENV["NOTIFY_SOCKET"] + + return nil if !sock + + ENV.delete("NOTIFY_SOCKET") if unset_env + + begin + Addrinfo.unix(sock, :DGRAM).connect { |s| s.write state } + rescue StandardError => e + raise NotifyError, "#{e.class}: #{e.message}", e.backtrace + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/server.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/server.rb new file mode 100644 index 00000000..02e2748a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/server.rb @@ -0,0 +1,688 @@ +# frozen_string_literal: true + +require 'stringio' + +require_relative 'thread_pool' +require_relative 'const' +require_relative 'log_writer' +require_relative 'events' +require_relative 'null_io' +require_relative 'reactor' +require_relative 'client' +require_relative 'binder' +require_relative 'util' +require_relative 'request' + +require 'socket' +require 'io/wait' unless Puma::HAS_NATIVE_IO_WAIT + +module Puma + + # This method was private on Ruby 2.4 but became public on Ruby 2.5+: + Thread.send(:attr_accessor, :puma_server) + + # The HTTP Server itself. Serves out a single Rack app. + # + # This class is used by the `Puma::Single` and `Puma::Cluster` classes + # to generate one or more `Puma::Server` instances capable of handling requests. + # Each Puma process will contain one `Puma::Server` instance. + # + # The `Puma::Server` instance pulls requests from the socket, adds them to a + # `Puma::Reactor` where they get eventually passed to a `Puma::ThreadPool`. + # + # Each `Puma::Server` will have one reactor and one thread pool. + class Server + include Puma::Const + include Request + + attr_reader :options + attr_reader :thread + attr_reader :log_writer + attr_reader :events + attr_reader :min_threads, :max_threads # for #stats + attr_reader :requests_count # @version 5.0.0 + + # @todo the following may be deprecated in the future + attr_reader :auto_trim_time, :early_hints, :first_data_timeout, + :leak_stack_on_error, + :persistent_timeout, :reaping_time + + attr_accessor :app + attr_accessor :binder + + + # Create a server for the rack app +app+. + # + # +log_writer+ is a Puma::LogWriter object used to log info and error messages. + # + # +events+ is a Puma::Events object used to notify application status events. + # + # Server#run returns a thread that you can join on to wait for the server + # to do its work. + # + # @note Several instance variables exist so they are available for testing, + # and have default values set via +fetch+. Normally the values are set via + # `::Puma::Configuration.puma_default_options`. + # + # @note The `events` parameter is set to nil, and set to `Events.new` in code. + # Often `options` needs to be passed, but `events` does not. Using nil allows + # calling code to not require events.rb. + # + def initialize(app, events = nil, options = {}) + @app = app + @events = events || Events.new + + @check, @notify = nil + @status = :stop + + @thread = nil + @thread_pool = nil + + @options = if options.is_a?(UserFileDefaultOptions) + options + else + UserFileDefaultOptions.new(options, Configuration::DEFAULTS) + end + + @clustered = (@options.fetch :workers, 0) > 0 + @worker_write = @options[:worker_write] + @log_writer = @options.fetch :log_writer, LogWriter.stdio + @early_hints = @options[:early_hints] + @first_data_timeout = @options[:first_data_timeout] + @persistent_timeout = @options[:persistent_timeout] + @idle_timeout = @options[:idle_timeout] + @min_threads = @options[:min_threads] + @max_threads = @options[:max_threads] + @queue_requests = @options[:queue_requests] + @max_fast_inline = @options[:max_fast_inline] + @enable_keep_alives = @options[:enable_keep_alives] + @io_selector_backend = @options[:io_selector_backend] + @http_content_length_limit = @options[:http_content_length_limit] + + # make this a hash, since we prefer `key?` over `include?` + @supported_http_methods = + if @options[:supported_http_methods] == :any + :any + else + if (ary = @options[:supported_http_methods]) + ary + else + SUPPORTED_HTTP_METHODS + end.sort.product([nil]).to_h.freeze + end + + temp = !!(@options[:environment] =~ /\A(development|test)\z/) + @leak_stack_on_error = @options[:environment] ? temp : true + + @binder = Binder.new(log_writer) + + ENV['RACK_ENV'] ||= "development" + + @mode = :http + + @precheck_closing = true + + @requests_count = 0 + + @idle_timeout_reached = false + end + + def inherit_binder(bind) + @binder = bind + end + + class << self + # @!attribute [r] current + def current + Thread.current.puma_server + end + + # :nodoc: + # @version 5.0.0 + def tcp_cork_supported? + Socket.const_defined?(:TCP_CORK) && Socket.const_defined?(:IPPROTO_TCP) + end + + # :nodoc: + # @version 5.0.0 + def closed_socket_supported? + Socket.const_defined?(:TCP_INFO) && Socket.const_defined?(:IPPROTO_TCP) + end + private :tcp_cork_supported? + private :closed_socket_supported? + end + + # On Linux, use TCP_CORK to better control how the TCP stack + # packetizes our stream. This improves both latency and throughput. + # socket parameter may be an MiniSSL::Socket, so use to_io + # + if tcp_cork_supported? + # 6 == Socket::IPPROTO_TCP + # 3 == TCP_CORK + # 1/0 == turn on/off + def cork_socket(socket) + skt = socket.to_io + begin + skt.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_CORK, 1) if skt.kind_of? TCPSocket + rescue IOError, SystemCallError + Puma::Util.purge_interrupt_queue + end + end + + def uncork_socket(socket) + skt = socket.to_io + begin + skt.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_CORK, 0) if skt.kind_of? TCPSocket + rescue IOError, SystemCallError + Puma::Util.purge_interrupt_queue + end + end + else + def cork_socket(socket) + end + + def uncork_socket(socket) + end + end + + if closed_socket_supported? + UNPACK_TCP_STATE_FROM_TCP_INFO = "C".freeze + + def closed_socket?(socket) + skt = socket.to_io + return false unless skt.kind_of?(TCPSocket) && @precheck_closing + + begin + tcp_info = skt.getsockopt(Socket::IPPROTO_TCP, Socket::TCP_INFO) + rescue IOError, SystemCallError + Puma::Util.purge_interrupt_queue + @precheck_closing = false + false + else + state = tcp_info.unpack(UNPACK_TCP_STATE_FROM_TCP_INFO)[0] + # TIME_WAIT: 6, CLOSE: 7, CLOSE_WAIT: 8, LAST_ACK: 9, CLOSING: 11 + (state >= 6 && state <= 9) || state == 11 + end + end + else + def closed_socket?(socket) + false + end + end + + # @!attribute [r] backlog + def backlog + @thread_pool&.backlog + end + + # @!attribute [r] running + def running + @thread_pool&.spawned + end + + + # This number represents the number of requests that + # the server is capable of taking right now. + # + # For example if the number is 5 then it means + # there are 5 threads sitting idle ready to take + # a request. If one request comes in, then the + # value would be 4 until it finishes processing. + # @!attribute [r] pool_capacity + def pool_capacity + @thread_pool&.pool_capacity + end + + # @!attribute [r] busy_threads + def busy_threads + @thread_pool&.busy_threads + end + + # Runs the server. + # + # If +background+ is true (the default) then a thread is spun + # up in the background to handle requests. Otherwise requests + # are handled synchronously. + # + def run(background=true, thread_name: 'srv') + BasicSocket.do_not_reverse_lookup = true + + @events.fire :state, :booting + + @status = :run + + @thread_pool = ThreadPool.new(thread_name, options) { |client| process_client client } + + if @queue_requests + @reactor = Reactor.new(@io_selector_backend) { |c| reactor_wakeup c } + @reactor.run + end + + @thread_pool.auto_reap! if options[:reaping_time] + @thread_pool.auto_trim! if @min_threads != @max_threads && options[:auto_trim_time] + + @check, @notify = Puma::Util.pipe unless @notify + + @events.fire :state, :running + + if background + @thread = Thread.new do + Puma.set_thread_name thread_name + handle_servers + end + return @thread + else + handle_servers + end + end + + # This method is called from the Reactor thread when a queued Client receives data, + # times out, or when the Reactor is shutting down. + # + # It is responsible for ensuring that a request has been completely received + # before it starts to be processed by the ThreadPool. This may be known as read buffering. + # If read buffering is not done, and no other read buffering is performed (such as by an application server + # such as nginx) then the application would be subject to a slow client attack. + # + # For a graphical representation of how the request buffer works see [architecture.md](https://github.com/puma/puma/blob/master/docs/architecture.md#connection-pipeline). + # + # The method checks to see if it has the full header and body with + # the `Puma::Client#try_to_finish` method. If the full request has been sent, + # then the request is passed to the ThreadPool (`@thread_pool << client`) + # so that a "worker thread" can pick up the request and begin to execute application logic. + # The Client is then removed from the reactor (return `true`). + # + # If a client object times out, a 408 response is written, its connection is closed, + # and the object is removed from the reactor (return `true`). + # + # If the Reactor is shutting down, all Clients are either timed out or passed to the + # ThreadPool, depending on their current state (#can_close?). + # + # Otherwise, if the full request is not ready then the client will remain in the reactor + # (return `false`). When the client sends more data to the socket the `Puma::Client` object + # will wake up and again be checked to see if it's ready to be passed to the thread pool. + def reactor_wakeup(client) + shutdown = !@queue_requests + if client.try_to_finish || (shutdown && !client.can_close?) + @thread_pool << client + elsif shutdown || client.timeout == 0 + client.timeout! + else + client.set_timeout(@first_data_timeout) + false + end + rescue StandardError => e + client_error(e, client) + client.close + true + end + + def handle_servers + begin + check = @check + sockets = [check] + @binder.ios + pool = @thread_pool + queue_requests = @queue_requests + drain = options[:drain_on_shutdown] ? 0 : nil + + addr_send_name, addr_value = case options[:remote_address] + when :value + [:peerip=, options[:remote_address_value]] + when :header + [:remote_addr_header=, options[:remote_address_header]] + when :proxy_protocol + [:expect_proxy_proto=, options[:remote_address_proxy_protocol]] + else + [nil, nil] + end + + while @status == :run || (drain && shutting_down?) + begin + ios = IO.select sockets, nil, nil, (shutting_down? ? 0 : @idle_timeout) + unless ios + unless shutting_down? + @idle_timeout_reached = true + + if @clustered + @worker_write << "#{PipeRequest::PIPE_IDLE}#{Process.pid}\n" rescue nil + next + else + @log_writer.log "- Idle timeout reached" + @status = :stop + end + end + + break + end + + if @idle_timeout_reached && @clustered + @idle_timeout_reached = false + @worker_write << "#{PipeRequest::PIPE_IDLE}#{Process.pid}\n" rescue nil + end + + ios.first.each do |sock| + if sock == check + break if handle_check + else + pool.wait_until_not_full + pool.wait_for_less_busy_worker(options[:wait_for_less_busy_worker]) if @clustered + + io = begin + sock.accept_nonblock + rescue IO::WaitReadable + next + end + drain += 1 if shutting_down? + pool << Client.new(io, @binder.env(sock)).tap { |c| + c.listener = sock + c.http_content_length_limit = @http_content_length_limit + c.send(addr_send_name, addr_value) if addr_value + } + end + end + rescue IOError, Errno::EBADF + # In the case that any of the sockets are unexpectedly close. + raise + rescue StandardError => e + @log_writer.unknown_error e, nil, "Listen loop" + end + end + + @log_writer.debug "Drained #{drain} additional connections." if drain + @events.fire :state, @status + + if queue_requests + @queue_requests = false + @reactor.shutdown + end + + graceful_shutdown if @status == :stop || @status == :restart + rescue Exception => e + @log_writer.unknown_error e, nil, "Exception handling servers" + ensure + # Errno::EBADF is infrequently raised + [@check, @notify].each do |io| + begin + io.close unless io.closed? + rescue Errno::EBADF + end + end + @notify = nil + @check = nil + end + + @events.fire :state, :done + end + + # :nodoc: + def handle_check + cmd = @check.read(1) + + case cmd + when STOP_COMMAND + @status = :stop + return true + when HALT_COMMAND + @status = :halt + return true + when RESTART_COMMAND + @status = :restart + return true + end + + false + end + + # Given a connection on +client+, handle the incoming requests, + # or queue the connection in the Reactor if no request is available. + # + # This method is called from a ThreadPool worker thread. + # + # This method supports HTTP Keep-Alive so it may, depending on if the client + # indicates that it supports keep alive, wait for another request before + # returning. + # + # Return true if one or more requests were processed. + def process_client(client) + # Advertise this server into the thread + Thread.current.puma_server = self + + clean_thread_locals = options[:clean_thread_locals] + close_socket = true + + requests = 0 + + begin + if @queue_requests && + !client.eagerly_finish + + client.set_timeout(@first_data_timeout) + if @reactor.add client + close_socket = false + return false + end + end + + with_force_shutdown(client) do + client.finish(@first_data_timeout) + end + + while true + @requests_count += 1 + case handle_request(client, requests + 1) + when false + break + when :async + close_socket = false + break + when true + ThreadPool.clean_thread_locals if clean_thread_locals + + requests += 1 + + # As an optimization, try to read the next request from the + # socket for a short time before returning to the reactor. + fast_check = @status == :run + + # Always pass the client back to the reactor after a reasonable + # number of inline requests if there are other requests pending. + fast_check = false if requests >= @max_fast_inline && + @thread_pool.backlog > 0 + + next_request_ready = with_force_shutdown(client) do + client.reset(fast_check) + end + + unless next_request_ready + break unless @queue_requests + client.set_timeout @persistent_timeout + if @reactor.add client + close_socket = false + break + end + end + end + end + true + rescue StandardError => e + client_error(e, client, requests) + # The ensure tries to close +client+ down + requests > 0 + ensure + client.io_buffer.reset + + begin + client.close if close_socket + rescue IOError, SystemCallError + Puma::Util.purge_interrupt_queue + # Already closed + rescue StandardError => e + @log_writer.unknown_error e, nil, "Client" + end + end + end + + # Triggers a client timeout if the thread-pool shuts down + # during execution of the provided block. + def with_force_shutdown(client, &block) + @thread_pool.with_force_shutdown(&block) + rescue ThreadPool::ForceShutdown + client.timeout! + end + + # :nocov: + + # Handle various error types thrown by Client I/O operations. + def client_error(e, client, requests = 1) + # Swallow, do not log + return if [ConnectionError, EOFError].include?(e.class) + + case e + when MiniSSL::SSLError + lowlevel_error(e, client.env) + @log_writer.ssl_error e, client.io + when HttpParserError + response_to_error(client, requests, e, 400) + @log_writer.parse_error e, client + when HttpParserError501 + response_to_error(client, requests, e, 501) + @log_writer.parse_error e, client + else + response_to_error(client, requests, e, 500) + @log_writer.unknown_error e, nil, "Read" + end + end + + # A fallback rack response if +@app+ raises as exception. + # + def lowlevel_error(e, env, status=500) + if handler = options[:lowlevel_error_handler] + if handler.arity == 1 + return handler.call(e) + elsif handler.arity == 2 + return handler.call(e, env) + else + return handler.call(e, env, status) + end + end + + if @leak_stack_on_error + backtrace = e.backtrace.nil? ? '' : e.backtrace.join("\n") + [status, {}, ["Puma caught this error: #{e.message} (#{e.class})\n#{backtrace}"]] + else + [status, {}, [""]] + end + end + + def response_to_error(client, requests, err, status_code) + status, headers, res_body = lowlevel_error(err, client.env, status_code) + prepare_response(status, headers, res_body, requests, client) + end + private :response_to_error + + # Wait for all outstanding requests to finish. + # + def graceful_shutdown + if options[:shutdown_debug] + threads = Thread.list + total = threads.size + + pid = Process.pid + + $stdout.syswrite "#{pid}: === Begin thread backtrace dump ===\n" + + threads.each_with_index do |t,i| + $stdout.syswrite "#{pid}: Thread #{i+1}/#{total}: #{t.inspect}\n" + $stdout.syswrite "#{pid}: #{t.backtrace.join("\n#{pid}: ")}\n\n" + end + $stdout.syswrite "#{pid}: === End thread backtrace dump ===\n" + end + + if @status != :restart + @binder.close + end + + if @thread_pool + if timeout = options[:force_shutdown_after] + @thread_pool.shutdown timeout.to_f + else + @thread_pool.shutdown + end + end + end + + def notify_safely(message) + @notify << message + rescue IOError, NoMethodError, Errno::EPIPE, Errno::EBADF + # The server, in another thread, is shutting down + Puma::Util.purge_interrupt_queue + rescue RuntimeError => e + # Temporary workaround for https://bugs.ruby-lang.org/issues/13239 + if e.message.include?('IOError') + Puma::Util.purge_interrupt_queue + else + raise e + end + end + private :notify_safely + + # Stops the acceptor thread and then causes the worker threads to finish + # off the request queue before finally exiting. + + def stop(sync=false) + notify_safely(STOP_COMMAND) + @thread.join if @thread && sync + end + + def halt(sync=false) + notify_safely(HALT_COMMAND) + @thread.join if @thread && sync + end + + def begin_restart(sync=false) + notify_safely(RESTART_COMMAND) + @thread.join if @thread && sync + end + + def shutting_down? + @status == :stop || @status == :restart + end + + # List of methods invoked by #stats. + # @version 5.0.0 + STAT_METHODS = [:backlog, :running, :pool_capacity, :max_threads, :requests_count, :busy_threads].freeze + + # Returns a hash of stats about the running server for reporting purposes. + # @version 5.0.0 + # @!attribute [r] stats + # @return [Hash] hash containing stat info from `Server` and `ThreadPool` + def stats + stats = @thread_pool&.stats || {} + stats[:max_threads] = @max_threads + stats[:requests_count] = @requests_count + stats + end + + # below are 'delegations' to binder + # remove in Puma 7? + + + def add_tcp_listener(host, port, optimize_for_latency = true, backlog = 1024) + @binder.add_tcp_listener host, port, optimize_for_latency, backlog + end + + def add_ssl_listener(host, port, ctx, optimize_for_latency = true, + backlog = 1024) + @binder.add_ssl_listener host, port, ctx, optimize_for_latency, backlog + end + + def add_unix_listener(path, umask = nil, mode = nil, backlog = 1024) + @binder.add_unix_listener path, umask, mode, backlog + end + + # @!attribute [r] connected_ports + def connected_ports + @binder.connected_ports + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/single.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/single.rb new file mode 100644 index 00000000..1697f6b2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/single.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +require_relative 'runner' +require_relative 'detect' +require_relative 'plugin' + +module Puma + # This class is instantiated by the `Puma::Launcher` and used + # to boot and serve a Ruby application when no puma "workers" are needed + # i.e. only using "threaded" mode. For example `$ puma -t 1:5` + # + # At the core of this class is running an instance of `Puma::Server` which + # gets created via the `start_server` method from the `Puma::Runner` class + # that this inherits from. + class Single < Runner + # @!attribute [r] stats + def stats + { + started_at: utc_iso8601(@started_at) + }.merge(@server.stats).merge(super) + end + + def restart + @server&.begin_restart + end + + def stop + @server&.stop false + end + + def halt + @server&.halt + end + + def stop_blocked + log "- Gracefully stopping, waiting for requests to finish" + @control&.stop true + @server&.stop true + end + + def run + output_header "single" + + load_and_bind + + Plugins.fire_background + + @launcher.write_state + + start_control + + @server = server = start_server + server_thread = server.run + + log "Use Ctrl-C to stop" + redirect_io + + @events.fire_on_booted! + + debug_loaded_extensions("Loaded Extensions:") if @log_writer.debug? + + begin + server_thread.join + rescue Interrupt + # Swallow it + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/state_file.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/state_file.rb new file mode 100644 index 00000000..7f6ddbc1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/state_file.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +module Puma + + # Puma::Launcher uses StateFile to write a yaml file for use with Puma::ControlCLI. + # + # In previous versions of Puma, YAML was used to read/write the state file. + # Since Puma is similar to Bundler/RubyGems in that it may load before one's app + # does, minimizing the dependencies that may be shared with the app is desired. + # + # At present, it only works with numeric and string values. It is still a valid + # yaml file, and the CI tests parse it with Psych. + # + class StateFile + + ALLOWED_FIELDS = %w!control_url control_auth_token pid running_from! + + def initialize + @options = {} + end + + def save(path, permission = nil) + contents = +"---\n" + @options.each do |k,v| + next unless ALLOWED_FIELDS.include? k + case v + when Numeric + contents << "#{k}: #{v}\n" + when String + next if v.strip.empty? + contents << (k == 'running_from' || v.to_s.include?(' ') ? + "#{k}: \"#{v}\"\n" : "#{k}: #{v}\n") + end + end + if permission + File.write path, contents, mode: 'wb:UTF-8' + else + File.write path, contents, mode: 'wb:UTF-8', perm: permission + end + end + + def load(path) + File.read(path).lines.each do |line| + next if line.start_with? '#' + k,v = line.split ':', 2 + next unless v && ALLOWED_FIELDS.include?(k) + v = v.strip + @options[k] = + case v + when '' then nil + when /\A\d+\z/ then v.to_i + when /\A\d+\.\d+\z/ then v.to_f + else v.gsub(/\A"|"\z/, '') + end + end + end + + ALLOWED_FIELDS.each do |f| + define_method f.to_sym do + @options[f] + end + + define_method :"#{f}=" do |v| + @options[f] = v + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/thread_pool.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/thread_pool.rb new file mode 100644 index 00000000..f919bf7b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/thread_pool.rb @@ -0,0 +1,446 @@ +# frozen_string_literal: true + +require 'thread' + +require_relative 'io_buffer' + +module Puma + # Internal Docs for A simple thread pool management object. + # + # Each Puma "worker" has a thread pool to process requests. + # + # First a connection to a client is made in `Puma::Server`. It is wrapped in a + # `Puma::Client` instance and then passed to the `Puma::Reactor` to ensure + # the whole request is buffered into memory. Once the request is ready, it is passed into + # a thread pool via the `Puma::ThreadPool#<<` operator where it is stored in a `@todo` array. + # + # Each thread in the pool has an internal loop where it pulls a request from the `@todo` array + # and processes it. + class ThreadPool + class ForceShutdown < RuntimeError + end + + # How long, after raising the ForceShutdown of a thread during + # forced shutdown mode, to wait for the thread to try and finish + # up its work before leaving the thread to die on the vine. + SHUTDOWN_GRACE_TIME = 5 # seconds + + # Maintain a minimum of +min+ and maximum of +max+ threads + # in the pool. + # + # The block passed is the work that will be performed in each + # thread. + # + def initialize(name, options = {}, &block) + @not_empty = ConditionVariable.new + @not_full = ConditionVariable.new + @mutex = Mutex.new + + @todo = [] + + @spawned = 0 + @waiting = 0 + + @name = name + @min = Integer(options[:min_threads]) + @max = Integer(options[:max_threads]) + # Not an 'exposed' option, options[:pool_shutdown_grace_time] is used in CI + # to shorten @shutdown_grace_time from SHUTDOWN_GRACE_TIME. Parallel CI + # makes stubbing constants difficult. + @shutdown_grace_time = Float(options[:pool_shutdown_grace_time] || SHUTDOWN_GRACE_TIME) + @block = block + @out_of_band = options[:out_of_band] + @clean_thread_locals = options[:clean_thread_locals] + @before_thread_start = options[:before_thread_start] + @before_thread_exit = options[:before_thread_exit] + @reaping_time = options[:reaping_time] + @auto_trim_time = options[:auto_trim_time] + + @shutdown = false + + @trim_requested = 0 + @out_of_band_pending = false + + @workers = [] + + @auto_trim = nil + @reaper = nil + + @mutex.synchronize do + @min.times do + spawn_thread + @not_full.wait(@mutex) + end + end + + @force_shutdown = false + @shutdown_mutex = Mutex.new + end + + attr_reader :spawned, :trim_requested, :waiting + + def self.clean_thread_locals + Thread.current.keys.each do |key| # rubocop: disable Style/HashEachMethods + Thread.current[key] = nil unless key == :__recursive_key__ + end + end + + # generate stats hash so as not to perform multiple locks + # @return [Hash] hash containing stat info from ThreadPool + def stats + with_mutex do + { backlog: @todo.size, + running: @spawned, + pool_capacity: @waiting + (@max - @spawned), + busy_threads: @spawned - @waiting + @todo.size + } + end + end + + # How many objects have yet to be processed by the pool? + # + def backlog + with_mutex { @todo.size } + end + + # @!attribute [r] pool_capacity + def pool_capacity + waiting + (@max - spawned) + end + + # @!attribute [r] busy_threads + # @version 5.0.0 + def busy_threads + with_mutex { @spawned - @waiting + @todo.size } + end + + # :nodoc: + # + # Must be called with @mutex held! + # + def spawn_thread + @spawned += 1 + + trigger_before_thread_start_hooks + th = Thread.new(@spawned) do |spawned| + Puma.set_thread_name '%s tp %03i' % [@name, spawned] + todo = @todo + block = @block + mutex = @mutex + not_empty = @not_empty + not_full = @not_full + + while true + work = nil + + mutex.synchronize do + while todo.empty? + if @trim_requested > 0 + @trim_requested -= 1 + @spawned -= 1 + @workers.delete th + not_full.signal + trigger_before_thread_exit_hooks + Thread.exit + end + + @waiting += 1 + if @out_of_band_pending && trigger_out_of_band_hook + @out_of_band_pending = false + end + not_full.signal + begin + not_empty.wait mutex + ensure + @waiting -= 1 + end + end + + work = todo.shift + end + + if @clean_thread_locals + ThreadPool.clean_thread_locals + end + + begin + @out_of_band_pending = true if block.call(work) + rescue Exception => e + STDERR.puts "Error reached top of thread-pool: #{e.message} (#{e.class})" + end + end + end + + @workers << th + + th + end + + private :spawn_thread + + def trigger_before_thread_start_hooks + return unless @before_thread_start&.any? + + @before_thread_start.each do |b| + begin + b.call + rescue Exception => e + STDERR.puts "WARNING before_thread_start hook failed with exception (#{e.class}) #{e.message}" + end + end + nil + end + + private :trigger_before_thread_start_hooks + + def trigger_before_thread_exit_hooks + return unless @before_thread_exit&.any? + + @before_thread_exit.each do |b| + begin + b.call + rescue Exception => e + STDERR.puts "WARNING before_thread_exit hook failed with exception (#{e.class}) #{e.message}" + end + end + nil + end + + private :trigger_before_thread_exit_hooks + + # @version 5.0.0 + def trigger_out_of_band_hook + return false unless @out_of_band&.any? + + # we execute on idle hook when all threads are free + return false unless @spawned == @waiting + + @out_of_band.each(&:call) + true + rescue Exception => e + STDERR.puts "Exception calling out_of_band_hook: #{e.message} (#{e.class})" + true + end + + private :trigger_out_of_band_hook + + # @version 5.0.0 + def with_mutex(&block) + @mutex.owned? ? + yield : + @mutex.synchronize(&block) + end + + # Add +work+ to the todo list for a Thread to pickup and process. + def <<(work) + with_mutex do + if @shutdown + raise "Unable to add work while shutting down" + end + + @todo << work + + if @waiting < @todo.size and @spawned < @max + spawn_thread + end + + @not_empty.signal + end + end + + # This method is used by `Puma::Server` to let the server know when + # the thread pool can pull more requests from the socket and + # pass to the reactor. + # + # The general idea is that the thread pool can only work on a fixed + # number of requests at the same time. If it is already processing that + # number of requests then it is at capacity. If another Puma process has + # spare capacity, then the request can be left on the socket so the other + # worker can pick it up and process it. + # + # For example: if there are 5 threads, but only 4 working on + # requests, this method will not wait and the `Puma::Server` + # can pull a request right away. + # + # If there are 5 threads and all 5 of them are busy, then it will + # pause here, and wait until the `not_full` condition variable is + # signaled, usually this indicates that a request has been processed. + # + # It's important to note that even though the server might accept another + # request, it might not be added to the `@todo` array right away. + # For example if a slow client has only sent a header, but not a body + # then the `@todo` array would stay the same size as the reactor works + # to try to buffer the request. In that scenario the next call to this + # method would not block and another request would be added into the reactor + # by the server. This would continue until a fully buffered request + # makes it through the reactor and can then be processed by the thread pool. + def wait_until_not_full + with_mutex do + while true + return if @shutdown + + # If we can still spin up new threads and there + # is work queued that cannot be handled by waiting + # threads, then accept more work until we would + # spin up the max number of threads. + return if busy_threads < @max + + @not_full.wait @mutex + end + end + end + + # @version 5.0.0 + def wait_for_less_busy_worker(delay_s) + return unless delay_s && delay_s > 0 + + # Ruby MRI does GVL, this can result + # in processing contention when multiple threads + # (requests) are running concurrently + return unless Puma.mri? + + with_mutex do + return if @shutdown + + # do not delay, if we are not busy + return unless busy_threads > 0 + + # this will be signaled once a request finishes, + # which can happen earlier than delay + @not_full.wait @mutex, delay_s + end + end + + # If there are any free threads in the pool, tell one to go ahead + # and exit. If +force+ is true, then a trim request is requested + # even if all threads are being utilized. + # + def trim(force=false) + with_mutex do + free = @waiting - @todo.size + if (force or free > 0) and @spawned - @trim_requested > @min + @trim_requested += 1 + @not_empty.signal + end + end + end + + # If there are dead threads in the pool make them go away while decreasing + # spawned counter so that new healthy threads could be created again. + def reap + with_mutex do + dead_workers = @workers.reject(&:alive?) + + dead_workers.each do |worker| + worker.kill + @spawned -= 1 + end + + @workers.delete_if do |w| + dead_workers.include?(w) + end + end + end + + class Automaton + def initialize(pool, timeout, thread_name, message) + @pool = pool + @timeout = timeout + @thread_name = thread_name + @message = message + @running = false + end + + def start! + @running = true + + @thread = Thread.new do + Puma.set_thread_name @thread_name + while @running + @pool.public_send(@message) + sleep @timeout + end + end + end + + def stop + @running = false + @thread.wakeup + end + end + + def auto_trim!(timeout=@auto_trim_time) + @auto_trim = Automaton.new(self, timeout, "#{@name} tp trim", :trim) + @auto_trim.start! + end + + def auto_reap!(timeout=@reaping_time) + @reaper = Automaton.new(self, timeout, "#{@name} tp reap", :reap) + @reaper.start! + end + + # Allows ThreadPool::ForceShutdown to be raised within the + # provided block if the thread is forced to shutdown during execution. + def with_force_shutdown + t = Thread.current + @shutdown_mutex.synchronize do + raise ForceShutdown if @force_shutdown + t[:with_force_shutdown] = true + end + yield + ensure + t[:with_force_shutdown] = false + end + + # Tell all threads in the pool to exit and wait for them to finish. + # Wait +timeout+ seconds then raise +ForceShutdown+ in remaining threads. + # Next, wait an extra +@shutdown_grace_time+ seconds then force-kill remaining + # threads. Finally, wait 1 second for remaining threads to exit. + # + def shutdown(timeout=-1) + threads = with_mutex do + @shutdown = true + @trim_requested = @spawned + @not_empty.broadcast + @not_full.broadcast + + @auto_trim&.stop + @reaper&.stop + # dup workers so that we join them all safely + @workers.dup + end + + if timeout == -1 + # Wait for threads to finish without force shutdown. + threads.each(&:join) + else + join = ->(inner_timeout) do + start = Process.clock_gettime(Process::CLOCK_MONOTONIC) + threads.reject! do |t| + elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start + t.join inner_timeout - elapsed + end + end + + # Wait +timeout+ seconds for threads to finish. + join.call(timeout) + + # If threads are still running, raise ForceShutdown and wait to finish. + @shutdown_mutex.synchronize do + @force_shutdown = true + threads.each do |t| + t.raise ForceShutdown if t[:with_force_shutdown] + end + end + join.call(@shutdown_grace_time) + + # If threads are _still_ running, forcefully kill them and wait to finish. + threads.each(&:kill) + join.call(1) + end + + @spawned = 0 + @workers = [] + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/util.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/util.rb new file mode 100644 index 00000000..a87dc731 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/puma/util.rb @@ -0,0 +1,141 @@ +# frozen_string_literal: true + +require 'uri/common' + +module Puma + module Util + module_function + + def pipe + IO.pipe + end + + # An instance method on Thread has been provided to address https://bugs.ruby-lang.org/issues/13632, + # which currently affects some older versions of Ruby: 2.2.7 2.2.8 2.2.9 2.2.10 2.3.4 2.4.1 + # Additional context: https://github.com/puma/puma/pull/1345 + def purge_interrupt_queue + Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue + end + + # Escapes and unescapes a URI escaped string with + # +encoding+. +encoding+ will be the target encoding of the string + # returned, and it defaults to UTF-8 + if defined?(::Encoding) + def escape(s, encoding = Encoding::UTF_8) + URI.encode_www_form_component(s, encoding) + end + + def unescape(s, encoding = Encoding::UTF_8) + URI.decode_www_form_component(s, encoding) + end + else + def escape(s, encoding = nil) + URI.encode_www_form_component(s, encoding) + end + + def unescape(s, encoding = nil) + URI.decode_www_form_component(s, encoding) + end + end + module_function :unescape, :escape + + DEFAULT_SEP = /[&;] */n + + # Stolen from Mongrel, with some small modifications: + # Parses a query string by breaking it up at the '&' + # and ';' characters. You can also use this to parse + # cookies by changing the characters used in the second + # parameter (which defaults to '&;'). + def parse_query(qs, d = nil, &unescaper) + unescaper ||= method(:unescape) + + params = {} + + (qs || '').split(d ? /[#{d}] */n : DEFAULT_SEP).each do |p| + next if p.empty? + k, v = p.split('=', 2).map(&unescaper) + + if cur = params[k] + if cur.class == Array + params[k] << v + else + params[k] = [cur, v] + end + else + params[k] = v + end + end + + params + end + + # A case-insensitive Hash that preserves the original case of a + # header when set. + class HeaderHash < Hash + def self.new(hash={}) + HeaderHash === hash ? hash : super(hash) + end + + def initialize(hash={}) + super() + @names = {} + hash.each { |k, v| self[k] = v } + end + + def each + super do |k, v| + yield(k, v.respond_to?(:to_ary) ? v.to_ary.join("\n") : v) + end + end + + # @!attribute [r] to_hash + def to_hash + hash = {} + each { |k,v| hash[k] = v } + hash + end + + def [](k) + super(k) || super(@names[k.downcase]) + end + + def []=(k, v) + canonical = k.downcase + delete k if @names[canonical] && @names[canonical] != k # .delete is expensive, don't invoke it unless necessary + @names[k] = @names[canonical] = k + super k, v + end + + def delete(k) + canonical = k.downcase + result = super @names.delete(canonical) + @names.delete_if { |name,| name.downcase == canonical } + result + end + + def include?(k) + @names.include?(k) || @names.include?(k.downcase) + end + + alias_method :has_key?, :include? + alias_method :member?, :include? + alias_method :key?, :include? + + def merge!(other) + other.each { |k, v| self[k] = v } + self + end + + def merge(other) + hash = dup + hash.merge! other + end + + def replace(other) + clear + other.each { |k, v| self[k] = v } + self + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/rack/handler/puma.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/rack/handler/puma.rb new file mode 100644 index 00000000..7b3ce3db --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/lib/rack/handler/puma.rb @@ -0,0 +1,144 @@ +# frozen_string_literal: true + +module Puma + + # This module is used as an 'include' file in code at bottom of file. It loads + # into either `Rackup::Handler::Puma` or `Rack::Handler::Puma`. + + module RackHandler + DEFAULT_OPTIONS = { + :Verbose => false, + :Silent => false + } + + def config(app, options = {}) + require_relative '../../puma' + require_relative '../../puma/configuration' + require_relative '../../puma/log_writer' + require_relative '../../puma/launcher' + + default_options = DEFAULT_OPTIONS.dup + + # Libraries pass in values such as :Port and there is no way to determine + # if it is a default provided by the library or a special value provided + # by the user. A special key `user_supplied_options` can be passed. This + # contains an array of all explicitly defined user options. We then + # know that all other values are defaults + if user_supplied_options = options.delete(:user_supplied_options) + (options.keys - user_supplied_options).each do |k| + default_options[k] = options.delete(k) + end + end + + @events = options[:events] || ::Puma::Events.new + + conf = ::Puma::Configuration.new(options, default_options.merge({events: @events})) do |user_config, file_config, default_config| + if options.delete(:Verbose) + begin + require 'rack/commonlogger' # Rack 1.x + rescue LoadError + require 'rack/common_logger' # Rack 2 and later + end + app = ::Rack::CommonLogger.new(app, STDOUT) + end + + if options[:environment] + user_config.environment options[:environment] + end + + if options[:Threads] + min, max = options.delete(:Threads).split(':', 2) + user_config.threads min, max + end + + if options[:Host] || options[:Port] + host = options[:Host] || default_options[:Host] + port = options[:Port] || default_options[:Port] + self.set_host_port_to_config(host, port, user_config) + end + + if default_options[:Host] + file_config.set_default_host(default_options[:Host]) + end + self.set_host_port_to_config(default_options[:Host], default_options[:Port], default_config) + + user_config.app app + end + conf + end + + def run(app, **options) + conf = self.config(app, options) + + log_writer = options.delete(:Silent) ? ::Puma::LogWriter.strings : ::Puma::LogWriter.stdio + + launcher = ::Puma::Launcher.new(conf, :log_writer => log_writer, events: @events) + + yield launcher if block_given? + begin + launcher.run + rescue Interrupt + puts "* Gracefully stopping, waiting for requests to finish" + launcher.stop + puts "* Goodbye!" + end + end + + def valid_options + { + "Host=HOST" => "Hostname to listen on (default: localhost)", + "Port=PORT" => "Port to listen on (default: 8080)", + "Threads=MIN:MAX" => "min:max threads to use (default 0:16)", + "Verbose" => "Don't report each request (default: false)" + } + end + + def set_host_port_to_config(host, port, config) + config.clear_binds! if host || port + + if host&.start_with? '.', '/', '@' + config.bind "unix://#{host}" + elsif host&.start_with? 'ssl://' + uri = URI.parse(host) + uri.port ||= port || ::Puma::Configuration::DEFAULTS[:tcp_port] + config.bind uri.to_s + else + + if host + port ||= ::Puma::Configuration::DEFAULTS[:tcp_port] + end + + if port + host ||= ::Puma::Configuration::DEFAULTS[:tcp_host] + config.port port, host + end + end + end + end +end + +# rackup was removed in Rack 3, it is now a separate gem +if Object.const_defined?(:Rackup) && ::Rackup.const_defined?(:Handler) + module Rackup + module Handler + module Puma + class << self + include ::Puma::RackHandler + end + end + register :puma, Puma + end + end +else + do_register = Object.const_defined?(:Rack) && ::Rack.release < '3' + module Rack + module Handler + module Puma + class << self + include ::Puma::RackHandler + end + end + end + end + ::Rack::Handler.register(:puma, ::Rack::Handler::Puma) if do_register +end diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/tools/Dockerfile b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/tools/Dockerfile new file mode 100644 index 00000000..88cd8dfb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/tools/Dockerfile @@ -0,0 +1,16 @@ +# Use this Dockerfile to create minimal reproductions of issues + +FROM ruby:3.2 + +# throw errors if Gemfile has been modified since Gemfile.lock +RUN bundle config --global frozen 1 + +WORKDIR /usr/src/app + +COPY . . + +RUN bundle install +RUN bundle exec rake compile + +EXPOSE 9292 +CMD bundle exec bin/puma test/rackup/hello.ru diff --git a/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/tools/trickletest.rb b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/tools/trickletest.rb new file mode 100644 index 00000000..fa543806 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/puma-6.6.0/tools/trickletest.rb @@ -0,0 +1,44 @@ +require 'socket' +require 'stringio' + +def do_test(st, chunk) + s = TCPSocket.new('127.0.0.1',ARGV[0].to_i); + req = StringIO.new(st) + nout = 0 + randstop = rand(st.length / 10) + STDERR.puts "stopping after: #{randstop}" + + begin + while data = req.read(chunk) + nout += s.write(data) + s.flush + sleep 0.1 + if nout > randstop + STDERR.puts "BANG! after #{nout} bytes." + break + end + end + rescue Object => e + STDERR.puts "ERROR: #{e}" + ensure + s.close + end +end + +content = "-" * (1024 * 240) +st = "GET / HTTP/1.1\r\nHost: www.zedshaw.com\r\nContent-Type: text/plain\r\nContent-Length: #{content.length}\r\n\r\n#{content}" + +puts "length: #{content.length}" + +threads = [] +ARGV[1].to_i.times do + t = Thread.new do + size = 100 + puts ">>>> #{size} sized chunks" + do_test(st, size) + end + + threads << t +end + +threads.each {|t| t.join} diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/BSDL b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/BSDL new file mode 100644 index 00000000..66d93598 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/BSDL @@ -0,0 +1,22 @@ +Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/COPYING b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/COPYING new file mode 100644 index 00000000..48e5a96d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/COPYING @@ -0,0 +1,56 @@ +Ruby is copyrighted free software by Yukihiro Matsumoto . +You can redistribute it and/or modify it under either the terms of the +2-clause BSDL (see the file BSDL), or the conditions below: + +1. You may make and give away verbatim copies of the source form of the + software without restriction, provided that you duplicate all of the + original copyright notices and associated disclaimers. + +2. You may modify your copy of the software in any way, provided that + you do at least ONE of the following: + + a. place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said + modifications to Usenet or an equivalent medium, or by allowing + the author to include your modifications in the software. + + b. use the modified software only within your corporation or + organization. + + c. give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d. make other distribution arrangements with the author. + +3. You may distribute the software in object code or binary form, + provided that you do at least ONE of the following: + + a. distribute the binaries and library files of the software, + together with instructions (in the manual page or equivalent) + on where to get the original distribution. + + b. accompany the distribution with the machine-readable source of + the software. + + c. give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d. make other distribution arrangements with the author. + +4. You may modify and include the part of the software into any other + software (possibly commercial). But some files in the distribution + are not written by the author, so that they are not under these terms. + + For the list of those files and their copying conditions, see the + file LEGAL. + +5. The scripts and library files supplied as input to or produced as + output from the software do not automatically fall under the + copyright of the software, but belong to whomever generated them, + and may be sold commercially, and may be aggregated with this + software. + +6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/ChangeLog b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/ChangeLog new file mode 100644 index 00000000..760765b8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/ChangeLog @@ -0,0 +1,846 @@ +Tue Feb 20 18:45:45 2007 Minero Aoki + + * lib/racc/grammar.rb (separated_by): last commit was wrong. use + optional default return value of #option. + +Tue Feb 20 18:27:48 2007 Minero Aoki + + * lib/racc/grammar.rb (separated_by): return [] for empty list. + +Tue Nov 7 07:13:47 2006 Minero Aoki + + * lib/racc/grammar.rb (Rule#prec): rule.prec{...} should set + action. + +Tue Nov 7 06:38:57 2006 Minero Aoki + + * lib/racc/grammar.rb: system call error on writing log file + should be ignored. + + * lib/racc/grammar.rb: never define lvar which have same name with + block local variable. + + * lib/racc/iset.rb: ditto. + + * lib/racc/logfilegenerator.rb: ditto. + + * lib/racc/parser.rb: ditto. + + * lib/racc/state.rb: ditto. + + * lib/racc/statetransitiontable.rb: ditto. + + * test/test.rb: racc -c is obsolete, use --line-convert-all. + +Sun Oct 29 13:27:30 2006 Minero Aoki + + * lib/racc/grammarfileparser.rb: use String#lines instead of + #to_a. + + * lib/racc/parserfilegenerator.rb: ditto. + + * lib/racc/compat.rb: provide Object#__send. + + * lib/racc/compat.rb: provide Object#__send!. + + * lib/racc/compat.rb: provide String#lines. + +Thu Aug 24 23:14:16 2006 Minero Aoki + + * lib/racc/grammar.rb: report conflicts/useless if $DEBUG. + + * lib/racc/statetransitiontable.rb: remove code for Ruby 1.4 + compatibility. + +Fri Aug 4 01:02:36 2006 Minero Aoki + + * lib/racc/grammar.rb: #should_terminal should be called in + #check_terminals. + +Fri Aug 4 00:44:56 2006 Minero Aoki + + * bin/racc: getopts -> optparse. + + * lib/racc/grammar.rb: value of error symbol is :error. + + * lib/racc/grammar.rb (check_terminals): string symbols are + terminal. + + * lib/racc/grammarfileparser.rb (add_rule_block): specified-prec + did not work. + +Fri Aug 4 00:29:53 2006 Minero Aoki + + * lib/racc/parserfilegenerator.rb + (serialize_integer_list_compressed): fix typo. + +Thu Aug 3 22:20:34 2006 Minero Aoki + + * bin/y2racc: fix filename. + +Thu Aug 3 21:10:48 2006 Minero Aoki + + * bin/y2racc: getopts -> optparse. + +Thu Aug 3 19:35:34 2006 Minero Aoki + + * setup.rb: updated. + +Thu Aug 3 19:34:55 2006 Minero Aoki + + * bin/racc2y: getopts -> optparse. + + * bin/racc2y: rewrite code for new generator. + + * lib/racc/grammar.rb (_regist): did not check @delayed rules (it + causes registering same dummy rules many times). + + * lib/racc/grammarfileparser.rb: refactoring: simplify syntax. + + * lib/racc/grammarfileparser.rb: new method + GrammarFileParser.parse. + + * lib/racc/grammarfileparser.rb: new method + GrammarFileParser.parse_file. + +Sat Jul 29 04:51:42 2006 Minero Aoki + + * lib/racc/pre-setup: We need not make grammarfileparser.rb. + +Sat Jul 29 04:30:33 2006 Minero Aoki + + * lib/racc/grammar.rb: allow '|' operation with meta rules + (many, option...). + +Sat Jul 29 03:17:20 2006 Minero Aoki + + * lib/racc/grammar.rb (Grammar#parser_class): write log file when + $DEBUG=true. + + * lib/racc/grammar.rb (Grammar.define): run block on a + Racc::Grammar::DefinitionEnv object, instead of a Racc::Grammar + object. + + * lib/racc/grammar.rb (DefinitionEnv): new method #null. + + * lib/racc/grammar.rb (DefinitionEnv): new method #many. + + * lib/racc/grammar.rb (DefinitionEnv): new method #many1. + + * lib/racc/grammar.rb (DefinitionEnv): new method #option. + + * lib/racc/grammar.rb (DefinitionEnv): new method #seperated_by. + + * lib/racc/grammar.rb (DefinitionEnv): new method #seperated_by1. + + * lib/racc/grammar.rb (DefinitionEnv): new method #action. + +Sat Jul 29 03:13:22 2006 Minero Aoki + + * lib/racc/compat.rb: reduce warning. + +Sun Jul 16 05:07:12 2006 Minero Aoki + + * lib/racc/compat.rb: implement Enumerable#each_slice for Ruby + 1.8. + + * lib/racc/parserfilegenerator.rb: better output. + + * ext/racc/cparse/cparse.c: always use VALUE instead of struct + cparse_params. + + * ext/racc/cparse/cparse.c: mark params->value_v. + +Thu Jul 6 20:44:48 2006 Minero Aoki + + * lib/racc/grammar.rb: on-the-fly generator implemented. + + * lib/racc/generator.rb -> statetransitiontable.rb, + parserfilegenerator.rb, logfilegenerator.rb. + + * lib/racc/statetransitiontable.rb: new file. + + * lib/racc/parserfilegenerator.rb: new file. + + * lib/racc/logfilegenerator.rb: new file. + + * lib/racc/grammarfileparser.rb.in: removed. + + * lib/racc/grammarfileparser.rb: new file. uses on-the-fly + generator. + + * misc/boot.rb: removed. + + * lib/racc/static.rb: new file, to import static generator + (lib/racc.rb provides dynamic generator). + + * lib/racc/grammar.rb: grand refactoring. + + * lib/racc/sourcetext.rb: new method #to_s, #location. + + * lib/racc/state.rb: compute NFA/DFA on demand. + + * bin/racc: follow these changes. + +Thu Jul 6 20:39:42 2006 Minero Aoki + + * ext/racc/cparse/cparse.so: should mark VALUEs in cparse_params. + +Tue Jul 4 02:24:27 2006 Minero Aoki + + * bin/racc: simplify report code. + + * lib/racc/grammar.rb: introduce new methods for racc command. + + * lib/racc/states.rb: ditto. + + * lib/racc/generator.rb: class CodeGenerator -> + ParserFileGenerator. + + * lib/racc/generator.rb: new class ParserFileGenerator::Params. + + * bin/racc: ditto. + + * misc/boot.rb: ditto. + + * lib/racc/grammarfileparser.rb.in: ditto. + + * lib/racc/grammarfileparser.rb.in: merge grammarfilescanner.rb. + + * lib/racc/grammarfilescanner.rb: removed. + + * lib/racc/grammarfileparser.rb.in: parses user code blocks. + + * lib/racc/usercodeparser.rb: removed. + + * lib/racc/generator.rb: remove user code parsing code. + + * lib/racc/grammarfileparser.rb.in: passes user code block by a + SourceText object. + + * lib/racc/generator.rb: ditto. + + * lib/racc/sourcetext.rb: new file. + + * lib/racc/generator.rb: introduce DSL to describe file contents. + +Tue Jul 4 02:15:36 2006 Minero Aoki + + * lib/racc/debugflags.rb: remove unused class GenerationOptions. + +Tue Jul 4 02:14:48 2006 Minero Aoki + + * lib/racc/compat.rb: update coding style. + +Mon Jul 3 04:34:32 2006 Minero Aoki + + * lib/racc/compiler.rb: do not export Grammar/SymbolTable/States. + + * lib/racc/compiler.rb: make a new class for debug flags + (Racc::DebugFlags). + + * lib/racc/compiler.rb: removed. + + * bin/racc: eliminate Racc::Compiler class. + + * bin/racc: refactor profiling code. + + * bin/racc: move file generation code to racc/generator.rb. + + * misc/boot.rb: does not emulate Racc::Compiler interface. + + * lib/racc.rb: new file to require whole generator. + + * lib/racc/grammar.rb: class RuleTable -> Grammar. + + * lib/racc/grammar.rb: Grammar.new does not accept a Compiler. + + * lib/racc/grammar.rb: refactoring. + + * lib/racc/grammarfileparser.rb.in: GrammarFileParser.new does not + accept a Compiler. + + * lib/racc/grammarfileparser.rb.in: #parser takes more 2 args, a + filename and a base line number. + + * lib/racc/grammarfileparser.rb.in: refactoring. + + * lib/racc/output.rb -> generate.rb + + * lib/racc/generate.rb: class Formatter -> CodeGenerator. + + * lib/racc/generate.rb: CodeGenerator.new does not accept a + Compiler. + + * lib/racc/generate.rb: a CodeGenerator got many parameters via + setter method. + + * lib/racc/generate.rb: class VerboseOutputter -> + LogFileGenerator. + + * lib/racc/generate.rb: LogFileGenerator.new does not accept a + Compiler. + + * lib/racc/generate.rb: refactoring. + + * lib/racc/state.rb: class StateTable -> States. + + * lib/racc/state.rb: States.new does not accept a Compiler. + + * lib/racc/state.rb: refactoring. + + * test/test.rb: -Da is obsolete (I forgot what this flag is). + + * test/test.rb: allow replacing racc via environment variable + $RACC. + +Mon Jul 3 04:18:49 2006 Minero Aoki + + * Makefile: new task bootstrap-force. + +Sun Jul 2 19:46:58 2006 Minero Aoki + + * test/ichk.y: update coding style. + +Sun Jul 2 19:01:55 2006 Minero Aoki + + * ext/racc/cparse/cparse.c: must require version.h to get + RUBY_VERSION_CODE. + +Sun Jul 2 18:33:32 2006 Minero Aoki + + * ext/racc/cparse/cparse.c: do not use rb_iterate to give a block + to the method, use rb_block_call instead. [ruby-dev:28445] + +Mon Jun 19 02:38:18 2006 Minero Aoki + + * bin/racc: -g option is now -t. -g option is obsolete and is an + alias of -t. + +Mon Jun 19 02:35:59 2006 Minero Aoki + + * ext/racc/cparse/cparse.c: K&R -> ANSI C. + +Mon Nov 21 02:37:10 2005 Minero Aoki + + * version 1.4.5 released. + +Mon Nov 21 02:31:18 2005 Minero Aoki + + * bin/racc: shebang line should include file extension. + + * lib/racc/compat.rb: method removed: bug!. + + * lib/racc/*.rb: racc compiler should not depend on + Racc::ParseError. + + * lib/racc/*.rb: update copyright year. + + * lib/racc/*.rb: update coding style. + + * lib/racc/exception.rb: new file. + +Mon Nov 21 00:49:18 2005 Minero Aoki + + * Makefile: remove useless target `import'. + + * Makefile: generate parser-text.rb. + + * misc/dist.sh: setup.rb and COPYING is now in repository. + + * misc/dist.sh: generate parser-text.rb. + +Mon Nov 21 00:14:21 2005 Minero Aoki + + * bin/racc: read racc/parser.rb from parser-text.rb. + + * lib/racc/rubyloader.rb: no longer needed. + + * lib/racc/pre-setup: new file. + + * lib/racc/pre-setup: generate parser-text.rb. + + * lib/racc/pre-setup: generate grammarfileparser.rb. + + * misc/boot.rb: new method BootstrapCompiler.main. + + * misc/boot.rb: new method BootstrapCompiler.generate, which is + used from pre-setup. + +Mon Nov 21 00:09:04 2005 Minero Aoki + + * bin/racc2y: refactoring. + + * bin/y2racc: refactoring. + +Sun Nov 20 23:46:42 2005 Minero Aoki + + * lib/racc/pre-setup: new file. + +Sun Nov 20 22:46:21 2005 Minero Aoki + + * COPYING: new file. + +Sun Nov 20 22:25:15 2005 Minero Aoki + + * setup.rb: import setup.rb 3.4.1. + +Thu Sep 29 02:51:56 2005 Minero Aoki + + * Makefile (clean): invoke `make clean' in ext. + +Thu Sep 29 02:50:56 2005 Minero Aoki + + * lib/racc/.cvsignore: removed. + +Thu Sep 29 02:46:30 2005 Minero Aoki + + * Makefile: use .makeparams system. + + * Makefile: unify lib/racc/Makefile. + + * Makefile: new target lib/racc/grammarfileparser.rb. + + * lib/racc/Makefile: unified by ./Makefile. + + * lib/racc/boot: removed (moved under misc). + + * misc/boot.rb: new file. + +Thu Sep 29 02:43:30 2005 Minero Aoki + + * setup.rb: new file. + +Tue Jul 26 23:37:46 2005 Minero Aoki + + * bin/racc: --no-omit-actions did not work (This patch is + contributed by OHKUBO Takuya). + +Sun Jan 2 11:48:19 2005 Minero Aoki + + * lib/racc/grammar.rb (once_writer): bug! needs argument. + +Mon Feb 16 16:14:16 2004 Minero Aoki + + * test/echk.y: fix typo. + + * test/ichk.y: does not use amstd. + + * test/opt.y: untabify. + +Mon Feb 16 16:10:46 2004 Minero Aoki + + * lib/racc/boot: update coding style. + + * lib/racc/compat.rb: ditto. + + * lib/racc/compiler.rb: ditto. + + * lib/racc/grammar.rb: ditto. + + * lib/racc/grammarfileparser.rb.in: ditto. + + * lib/racc/grammarfilescanner.rb: ditto. + + * lib/racc/info.rb: ditto. + + * lib/racc/iset.rb: ditto. + + * lib/racc/output.rb: ditto. + + * lib/racc/parser.rb: ditto. + + * lib/racc/state.rb: ditto. + + * lib/racc/usercodeparser.rb: ditto. + +Mon Feb 16 16:01:34 2004 Minero Aoki + + * lib/racc/rubyloader.rb: imported rev1.6. + +Fri Dec 12 01:57:47 2003 Minero Aoki + + * sample/hash.y: use no_result_var option. + + * sample/array.y: use latest (my) coding style. + + * sample/array2.y: ditto. + + * sample/hash.y: ditto. + + * sample/lists.y: ditto. + +Wed Nov 5 19:50:35 2003 Minero Aoki + + * test/bench.y: remove dependency on amstd. + + * test/chk.y: ditto. + + * test/echk.y: ditto. + + * test/ichk.y: ditto. + + * test/intp.y: ditto. + + * test/opt.y: ditto. + + * test/percent.y: ditto. + +Wed Nov 5 19:11:15 2003 Minero Aoki + + * bin/racc (get_options): remove --no-extensions option; + racc/parser is preloaded, Racc_No_Extension does not work. + +Mon Nov 3 22:41:42 2003 Minero Aoki + + * bin/racc: apply latest coding style. + + * lib/racc/parser.rb: ditto. + + * lib/racc/compat.rb: add File.read. + +Mon Nov 3 21:20:25 2003 Minero Aoki + + * ext/racc/cparse/cparse.c (parse_main): abort if length of state + stack <=1, not ==0. + + * lib/racc/parser.rb: use <=1, not <2. + + * ext/racc/cparse/cparse.c: check_*() -> assert_*() + + * ext/racc/cparse/cparse.c (racc_cparse): define lvar `v' for + debugging. + + * ext/racc/cparse/cparse.c (racc_yyparse): ditto. + +Mon Nov 3 17:21:55 2003 Minero Aoki + + * Makefile (all): make cparse.so. + +Mon Nov 3 17:19:26 2003 Minero Aoki + + * lib/racc/parser.rb: update version. + + * ext/racc/cparse/cparse.c: update version. + +Mon Nov 3 17:19:01 2003 Minero Aoki + + * Makefile: update version in parser.rb, cparse.c. + +Sun Oct 12 23:49:58 2003 Minero Aoki + + * version 1.4.4. + +Sun Oct 12 23:49:40 2003 Minero Aoki + + * bin/y2racc: did not work. + + * bin/y2racc: -u options did not work. + +Sun Oct 12 23:41:46 2003 Minero Aoki + + * misc/dist.sh: cd before make. + +Sun Oct 12 23:38:04 2003 Minero Aoki + + * Makefile (site): create $siteroot/{ja,en}/man/racc/*.html. + +Sun Oct 12 23:37:18 2003 Minero Aoki + + * doc/parser.rrd.m: missing 'j'. + +Sun Oct 12 23:29:11 2003 Minero Aoki + + * Makefile: new target `doc'. + + * Makefile: new target `clean'. + + * lib/racc/Makefile: new target `clean'. + + * misc/dist.sh: create documents before pack. + +Sun Oct 12 23:27:58 2003 Minero Aoki + + * doc/debug.rd.m: junk char was inserted. + + * doc/index.html.m: en/ja text were mixed. + + * doc/parser.rrd.m: add return values. + + * doc/usage.html.m: fix hyper link. + +Sun Oct 12 22:57:28 2003 Minero Aoki + + * doc.en/changes.html, doc.ja/changes.html -> doc/NEWS.rd.m + + * doc.en/command.html, doc.ja/command.html -> doc/command.html.m + + * doc.en/debug.html, doc.ja/debug.html -> doc/debug.rd.m + + * doc.en/grammar.html, doc.ja/grammar.html -> doc/grammar.rd.m + + * doc.en/index.html, doc.ja/index.html -> doc/index.html.m + + * doc.en/parser.html, doc.ja/parser.html -> doc/parser.rrd.m + + * doc.en/usage.html, doc.ja/usage.html -> doc/usage.html.m + +Sun Oct 12 18:46:21 2003 Minero Aoki + + * web/racc.ja.html: update descriptions. + + * web/racc.en.html: ditto. + +Sun Oct 12 18:43:45 2003 Minero Aoki + + * misc/dist.sh: remove web/ directory before distribute. + +Sun Oct 12 18:37:29 2003 Minero Aoki + + * Makefile: new target `site'. + + * web/racc.ja.html: new file. + + * web/racc.en.html: new file. + +Sun Oct 12 18:30:55 2003 Minero Aoki + + * misc/dist.sh: forgot to remove tmp comment out. + +Sun Oct 12 18:12:09 2003 Minero Aoki + + * lib/racc/info.rb: version 1.4.4. + +Sun Oct 12 18:11:42 2003 Minero Aoki + + * Makefile (dist): split out misc/dist.sh. + + * misc/dist.sh: new file. + +Sun Oct 12 17:18:47 2003 Minero Aoki + + * README.en: update documents. + + * README.ja: ditto. + + * doc.en/changes.html: ditto. + + * doc.en/command.html: ditto. + + * doc.en/debug.html: ditto. + + * doc.en/grammar.html: ditto. + + * doc.en/index.html: ditto. + + * doc.en/parser.html: ditto. + + * doc.en/usage.html: ditto. + + * doc.ja/changes.html: ditto. + + * doc.ja/command.html: ditto. + + * doc.ja/debug.html: ditto. + + * doc.ja/index.html: ditto. + + * doc.ja/parser.html: ditto. + + * doc.ja/usage.html: ditto. + +Sun Oct 12 16:24:46 2003 Minero Aoki + + * sameple/calc-ja.y: simplify. + +Sun Oct 12 16:24:16 2003 Minero Aoki + + * misc/y2racc -> bin/y2racc + + * misc/racc2y -> bin/racc2y + +Sun Oct 12 15:56:30 2003 Minero Aoki + + * bin/racc: follow method name change. + +Sun Oct 12 15:34:14 2003 Minero Aoki + + * Makefile: new target `test'. + + * Makefile: missing $datadir. + +Sun Oct 12 15:33:02 2003 Minero Aoki + + * README.ja: update description. + + * README.en: ditto. + +Sun Oct 12 15:25:23 2003 Minero Aoki + + * lib/racc/compiler.rb: adjust file names. + + * lib/racc/grammarfileparser.rb.in: ditto. + + * lib/racc/grammarfilescanner.rb: ditto. + +Sun Oct 12 15:24:53 2003 Minero Aoki + + * Makefile: new file. + +Sun Oct 12 15:19:57 2003 Minero Aoki + + * BUGS.en: removed. + + * BUGS.ja: removed. + +Sun Oct 12 15:10:38 2003 Minero Aoki + + * racc -> bin/racc + + * .cvsignore -> lib/racc/.cvsignore + + * lib/racc/Makefile: new file. + + * boot.rb -> lib/racc/boot + + * compat.rb -> lib/racc/compat.rb + + * compiler.rb -> lib/racc/compiler.rb + + * grammar.rb -> lib/racc/grammar.rb + + * in.raccp.rb -> lib/racc/grammarfileparser.rb.in + + * raccs.rb -> lib/racc/grammarfilescanner.rb + + * info.rb -> lib/racc/info.rb + + * iset.rb -> lib/racc/iset.rb + + * outpur.rb -> lib/racc/output.rb + + * parser.rb -> lib/racc/parser.rb + + * rubyloader.rb -> lib/racc/rubyloader.rb + + * state.rb -> lib/racc/state.rb + + * ucodep.rb -> lib/racc/usercodeparser.rb + + * cparse/MANIFEST -> ext/racc/cparse/MANIFEST + + * cparse/cparse.c -> ext/racc/cparse/cparse.c + + * cparse/depend -> ext/racc/cparse/depend + + * cparse/extconf.rb -> ext/racc/cparse/extconf.rb + + * cparse/.cvsignore -> ext/racc/cparse/.cvsignore + +Sun Oct 12 15:10:13 2003 Minero Aoki + + * test/test.rb: use /bin/rm if exists. + +Sun Oct 12 14:33:29 2003 Minero Aoki + + * rubyloader.rb: imported from amstd, rev 1.5. + +Sun Oct 12 14:24:47 2003 Minero Aoki + + * boot.rb: reformat only. + + * compiler.rb: ditto. + + * grammar.rb: ditto. + + * in.raccp.rb: ditto. + + * iset.rb: ditto. + + * output.rb: ditto. + + * raccs.rb: ditto. + + * state.rb: ditto. + +Sun Oct 12 14:17:22 2003 Minero Aoki + + * test/test.rb: refactoring. + +Tue Jun 24 03:14:01 2003 Minero Aoki + + * ucodep.rb: typo: Grammer -> Grammar + +Mon May 26 23:06:58 2003 Minero Aoki + + * compiler.rb: update copyright year. + + * grammar.rb: ditto. + + * in.raccp.rb: ditto. + + * info.rb: ditto. + + * iset.rb: ditto. + + * output.rb: ditto. + + * parser.rb: ditto. + + * raccs.rb: ditto. + + * state.rb: ditto. + + * ucodep.rb: ditto. + +Sun May 25 13:21:27 2003 Minero Aoki + + * raccs.rb: update coding style. + +Fri Nov 15 17:53:12 2002 Minero Aoki + + * racc: changes style. + + * parser.rb: ditto. + +Fri Nov 15 17:11:52 2002 Minero Aoki + + version 1.4.3. + +Fri Nov 15 17:08:01 2002 Minero Aoki + + * boot.rb, compiler.rb, grammar.rb, in.raccp.rb, iset.rb, + output.rb, parser.rb, racc, raccs.rb, state.rb, ucodep.rb, + misc/racc2y, misc/y2racc: follows (my) latest coding styles. + +Thu Nov 14 14:39:53 2002 Minero Aoki + + * raccs.rb: explicit method call for VCALL. + +Wed Oct 16 15:45:11 2002 Minero Aoki + + * parser.rb: reformat. + +Fri Aug 9 18:21:01 2002 Minero Aoki + + * cparse/cparse.c: use better variable/macro names. + +Wed Aug 7 08:39:19 2002 Minero Aoki + + * cparse/cparse.c: goto label requires stmt. + +Mon Aug 5 21:53:07 2002 Minero Aoki + + * cparse/cparse.c: grand refine. + + * cparse/depend: re-added from ruby/ext/racc/cparse. + +Tue Jun 4 00:15:28 2002 Minero Aoki + + * boot.rb: allow to omit last 'end'. + +Mon Jun 3 23:29:45 2002 Minero Aoki + + * racc (write_table_file): shebang must placed on first line. + (reported by Hiroyuki Sato) + diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/README.ja.rdoc b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/README.ja.rdoc new file mode 100644 index 00000000..7c0bd8b7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/README.ja.rdoc @@ -0,0 +1,58 @@ += Racc + +* https://github.com/ruby/racc + +== DESCRIPTION: + + Racc は LALR(1) パーサジェネレータです。 + yacc の Ruby 版に相当します。 + +== 必要環境 + + * Ruby 2.5 以降 + +== インストール + + gem インストール: + + $ gem install racc + +== テスト + + sample/ 以下にいくつか Racc の文法ファイルのサンプルが用意 + してあります。動くのも動かないのもありますが、少なくとも + calc-ja.y は動くのでこれを処理してみましょう。Racc をインス + トールしたあと + + $ racc -ocalc.rb calc-ja.y + + として下さい。処理は一瞬から数秒で終わるので、 + + $ ruby calc.rb + + を実行してください。ちゃんと動いてますか? + + Racc の文法など詳しいことは doc.ja/ ディレクトリ以下の HTML を + 見てください。 + + +== ライセンス + + このパッケージに付属するファイルの著作権は青木峰郎が保持します。 + ライセンスは Ruby ライセンスです。ただしユーザが書いた規則 + ファイルや、Racc がそこから生成した Ruby スクリプトはその対象 + 外です。好きなライセンスで配布してください。 + + +== バグなど + + Racc を使っていてバグらしき現象に遭遇したら、下記のアドレスまで + メールをください。作者にはバグを修正する義務はありませんがその + 意思はあります。また、そのときはできるだけバグを再現できる文法 + ファイルを付けてください。 + + + 青木峰郎(あおきみねろう) + aamine@loveruby.net + http://i.loveruby.net + diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/README.rdoc b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/README.rdoc new file mode 100644 index 00000000..fc2a5733 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/README.rdoc @@ -0,0 +1,60 @@ += Racc + +* https://github.com/ruby/racc + +== DESCRIPTION: + + Racc is an LALR(1) parser generator. + It is written in Ruby itself, and generates Ruby program. + +== Requirement + + * Ruby 2.5 or later. + +== Installation + + gem install: + + $ gem install racc + +== Testing Racc + + Racc comes with simple calculator. To compile this, on shell: + + $ racc -o calc calc.y + + This process costs few seconds (or less). Then type: + + $ ruby calc + + ... Does it work? + For details of Racc, see HTML documents placed under 'doc/en/' + and sample grammar files under 'sample/'. + +== Release flow + +* Update VERSION number of these files + * RACC_VERSION in "ext/racc/com/headius/racc/Cparse.java" + * VERSION in "lib/racc/info.rb" +* Release as a gem by rake release with CRuby and JRuby because Racc gem provides 2 packages +* Create new release on {GitHub}[https://github.com/ruby/racc/releases] + +== License + + Racc is distributed under the same terms of ruby. + (see the file COPYING). Note that you do NOT need to follow + ruby license for your own parser (racc outputs). + You can distribute those files under any licenses you want. + + +== Bug Reports + + Any kind of bug report is welcome. + If you find a bug of Racc, please report an issue at + https://github.com/ruby/racc/issues. Your grammar file, + debug output generated by "racc -g", are helpful. + + + Minero Aoki + aamine@loveruby.net + http://i.loveruby.net diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/TODO b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/TODO new file mode 100644 index 00000000..22ffd7fc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/TODO @@ -0,0 +1,5 @@ +* check 'error' token handling. +* interactive transition table monitor. +* support backtracking. +* output Ruby extension library? +* LL(k)? (But it should not be called Racc) diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/bin/racc b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/bin/racc new file mode 100755 index 00000000..17be1663 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/bin/racc @@ -0,0 +1,320 @@ +#!/usr/bin/env ruby +# +# +# +# Copyright (c) 1999-2006 Minero Aoki +# +# This program is free software. +# You can distribute/modify this program under the same terms of ruby. +# see the file "COPYING". + +require 'racc/static' +require 'optparse' + +def main + output = nil + debug_parser = false + make_logfile = false + logfilename = nil + make_executable = false + rubypath = nil + embed_runtime = false + frozen_strings = false + debug_flags = Racc::DebugFlags.new + line_convert = true + line_convert_all = false + omit_action_call = true + superclass = nil + check_only = false + verbose = false + profiler = RaccProfiler.new(false) + + parser = OptionParser.new + parser.banner = "Usage: #{File.basename($0)} [options] [input]" + parser.on('-o', '--output-file=PATH', + 'output file name [.tab.rb]') {|name| + output = name + } + parser.on('-t', '--debug', 'Outputs debugging parser.') {|fl| + debug_parser = fl + } + parser.on('-g', 'Equivalent to -t (obsolete).') {|fl| + $stderr.puts "racc -g is obsolete. Use racc -t instead." if $VERBOSE + debug_parser = fl + } + parser.on('-v', '--verbose', + 'Creates .output log file.') {|fl| + make_logfile = fl + } + parser.on('-O', '--log-file=PATH', + 'Log file name [.output]') {|path| + make_logfile = true + logfilename = path + } + parser.on('-e', '--executable [RUBYPATH]', 'Makes executable parser.') {|path| + make_executable = true + rubypath = (path == 'ruby' ? nil : path) + } + parser.on('-E', '--embedded', "Embeds Racc runtime in output.") { + embed_runtime = true + } + parser.on('-F', '--frozen', "Add frozen_string_literals: true.") { + frozen_strings = true + } + parser.on('--line-convert-all', 'Converts line numbers of user codes.') { + line_convert_all = true + } + parser.on('-l', '--no-line-convert', 'Never convert line numbers.') { + line_convert = false + line_convert_all = false + } + parser.on('-a', '--no-omit-actions', 'Never omit actions.') { + omit_action_call = false + } + parser.on('--superclass=CLASSNAME', + 'Uses CLASSNAME instead of Racc::Parser.') {|name| + superclass = name + } + parser.on('-C', '--check-only', 'Checks syntax and quit immediately.') {|fl| + check_only = fl + } + parser.on('-S', '--output-status', 'Outputs internal status time to time.') { + verbose = true + } + parser.on('-P', 'Enables generator profile') { + profiler = RaccProfiler.new(true) + } + parser.on('-D flags', "Flags for Racc debugging (do not use).") {|flags| + debug_flags = Racc::DebugFlags.parse_option_string(flags) + } + #parser.on('--no-extensions', 'Run Racc without any Ruby extension.') { + # Racc.const_set :Racc_No_Extensions, true + #} + parser.on('--version', 'Prints version and quit.') { + puts "racc version #{Racc::Version}" + exit + } + parser.on('--runtime-version', 'Prints runtime version and quit.') { + printf "racc runtime version %s; %s core version %s\n", + Racc::Parser::Racc_Runtime_Version, + Racc::Parser.racc_runtime_type, + if Racc::Parser.racc_runtime_type == 'ruby' + Racc::Parser::Racc_Runtime_Core_Version_R + else + Racc::Parser::Racc_Runtime_Core_Version_C + end + exit + } + parser.on('--copyright', 'Prints copyright and quit.') { + puts Racc::Copyright + exit + } + parser.on('--help', 'Prints this message and quit.') { + puts parser.help + exit + } + begin + parser.parse! + rescue OptionParser::ParseError => err + abort [err.message, parser.help].join("\n") + end + if ARGV.size > 1 + abort 'too many input' + end + + input = ARGV[0] || "stdin" + + if input == "stdin" && !output then + abort 'You must specify a path to read or use -o for output.' + end + + begin + $stderr.puts 'Parsing grammar file...' if verbose + result = profiler.section('parse') { + parser = Racc::GrammarFileParser.new(debug_flags) + content = input == "stdin" ? ARGF.read : File.read(input) + parser.parse(content, File.basename(input)) + } + if check_only + $stderr.puts 'syntax ok' + exit + end + + $stderr.puts 'Generating LALR states...' if verbose + states = profiler.section('nfa') { + Racc::States.new(result.grammar).nfa + } + + $stderr.puts "Resolving #{states.size} states..." if verbose + profiler.section('dfa') { + states.dfa + } + + $stderr.puts 'Creating parser file...' if verbose + params = result.params.dup + params.filename = File.basename(input) + # Overwrites parameters given by a grammar file with command line options. + params.superclass = superclass if superclass + params.omit_action_call = true if omit_action_call + # From command line option + if make_executable + params.make_executable = true + params.interpreter = rubypath + end + params.debug_parser = debug_parser + params.convert_line = line_convert + params.convert_line_all = line_convert_all + params.embed_runtime = embed_runtime + params.frozen_strings = frozen_strings + profiler.section('generation') { + generator = Racc::ParserFileGenerator.new(states, params) + generator.generate_parser_file(output || make_filename(input, '.tab.rb')) + } + + if make_logfile + profiler.section('logging') { + $stderr.puts 'Creating log file...' if verbose + logfilename ||= make_filename(output || File.basename(input), '.output') + File.open(logfilename, 'w') {|f| + Racc::LogFileGenerator.new(states, debug_flags).output f + } + } + end + if debug_flags.status_logging + log_useless states.grammar + log_conflict states + else + has_useless = report_useless states.grammar + has_conflicts = report_conflict states + if has_useless || has_conflicts + preamble = make_logfile ? 'C' : 'Turn on logging with "-v" and c' + $stderr.puts %Q{#{preamble}heck ".output" file for details} + end + end + + profiler.report + if states.should_error_on_expect_mismatch? + raise Racc::CompileError, "#{states.grammar.n_expected_srconflicts} shift/reduce conflicts are expected but #{states.n_srconflicts} shift/reduce conflicts exist" + end + rescue Racc::Error, Errno::ENOENT, Errno::EPERM => err + raise if $DEBUG or debug_flags.any? + lineno = err.message.slice(/\A\d+:/).to_s + abort "#{File.basename $0}: #{input}:#{lineno} #{err.message.strip}" + end +end + +def make_filename(path, suffix) + path.sub(/(?:\..*?)?\z/, suffix) +end + +LIST_LIMIT = 10 +def report_list(enum, label) + c = enum.count + if c > 0 + $stderr.puts "#{c} #{label}:" + enum.first(LIST_LIMIT).each do |item| + $stderr.puts " #{yield item}" + end + $stderr.puts " ..." if c > LIST_LIMIT + end +end + +# @return [Boolean] if anything was reported +def report_conflict(states) + if states.should_report_srconflict? + reported = true + $stderr.puts "#{states.n_srconflicts} shift/reduce conflicts" + end + if states.rrconflict_exist? + reported = true + $stderr.puts "#{states.n_rrconflicts} reduce/reduce conflicts" + end + reported +end + +def log_conflict(states) + logging('w') {|f| + f.puts "ex#{states.grammar.n_expected_srconflicts}" + if states.should_report_srconflict? + f.puts "sr#{states.n_srconflicts}" + end + if states.rrconflict_exist? + f.puts "rr#{states.n_rrconflicts}" + end + } +end + +# @return [Boolean] if anything was reported +def report_useless(grammar) + reported = report_list(grammar.each_useless_nonterminal, 'useless nonterminals', &:to_s) + + reported ||= report_list(grammar.each_useless_rule, 'useless rules') { |r| "##{r.ident} (#{r.target})" } + + if grammar.start.useless? + $stderr.puts 'fatal: start symbol does not derive any sentence' + reported = true + end + reported +end + +def log_useless(grammar) + logging('a') {|f| + if grammar.useless_nonterminal_exist? + f.puts "un#{grammar.n_useless_nonterminals}" + end + if grammar.useless_rule_exist? + f.puts "ur#{grammar.n_useless_rules}" + end + } +end + +def logging(mode, &block) + File.open("log/#{File.basename(ARGV[0])}", mode, &block) +end + +class RaccProfiler + def initialize(really) + @really = really + @log = [] + end + + def section(name) + if @really + t1 = ::Process.times.utime + result = yield + t2 = ::Process.times.utime + @log.push [name, t2 - t1] + result + else + yield + end + end + + def report + return unless @really + f = $stderr + total = cumulative_time() + f.puts '--task-----------+--sec------+---%-' + @log.each do |name, time| + f.printf "%-19s %s %3d%%\n", name, pjust(time,4,4), (time/total*100).to_i + end + f.puts '-----------------+-----------+-----' + f.printf "%-20s%s\n", 'total', pjust(total,4,4) + end + + private + + def cumulative_time + t = @log.inject(0) {|sum, (name, time)| sum + time } + t == 0 ? 0.01 : t + end + + def pjust(num, i, j) + m = /(\d+)(\.\d+)?/.match(num.to_s) + str = m[1].rjust(i) + str.concat m[2].ljust(j+1)[0,j+1] if m[2] + str + end +end + +main diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/doc/en/grammar.en.rdoc b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/doc/en/grammar.en.rdoc new file mode 100644 index 00000000..704a5ea6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/doc/en/grammar.en.rdoc @@ -0,0 +1,218 @@ += Racc Grammar File Reference + +== Global Structure + +== Class Block and User Code Block + +There are two top-level blocks: the 'class' block, and the 'user code' +block. The 'user code' block MUST be after the 'class' block. + +== Comment + +Comments can be added about everywhere. Two comment styles are +supported: Ruby style (`# ...`) and C style (`/* ... */`). + +== Class Block + +The class block is formed like this: + + class CLASS_NAME + [precedence table] + [token declarations] + [expected number of S/R conflict] + [options] + [semantic value conversion] + [start rule] + rule + GRAMMARS + +CLASS_NAME is a name of parser class. +This is the name of generating parser class. + +If CLASS_NAME includes '::', Racc outputs module clause. +For example, writing "class M::C" causes creating the code below: + + module M + class C + : + : + end + end + +== Grammar Block + +The grammar block describes the grammar +to be understood by parser. Syntax is: + + (token): (token) (token) (token).... (action) + + (token): (token) (token) (token).... (action) + | (token) (token) (token).... (action) + | (token) (token) (token).... (action) + +(action) is an action which is executed when its (token)s are found. +(action) is a ruby code block, which is surrounded by braces: + + { print val[0] + puts val[1] } + +Note that you cannot use '%' string, here document, '%r' regexp in action. + +Actions can be omitted. +When it is omitted, '' (empty string) is used. + +A return value of action is a value of left side value ($$). +It is value of result, or returned value by "return" statement. + +Here is an example of whole grammar block. + + rule + goal: definition rules source { result = val } + + definition: /* none */ { result = [] } + | definition startdesig { result[0] = val[1] } + | definition + precrule # this line continue from upper line + { + result[1] = val[1] + } + + startdesig: START TOKEN + +You can use following special local variables in action. + + * result ($$) + +The value of left-hand side (lhs). A default value is val[0]. + + * val ($1,$2,$3...) + +An array of value of right-hand side (rhs). + + * _values (...$-2,$-1,$0) + +A stack of values. +DO NOT MODIFY this stack unless you know what you are doing. + +== Operator Precedence + +This function is equal to '%prec' in yacc. +To designate this block: + + prechigh + nonassoc '++' + left '*' '/' + left '+' '-' + right '=' + preclow + +`right' is yacc's %right, `left' is yacc's %left. + +`=' + (symbol) means yacc's %prec: + + prechigh + nonassoc UMINUS + left '*' '/' + left '+' '-' + preclow + + rule + exp: exp '*' exp + | exp '-' exp + | '-' exp =UMINUS # equals to "%prec UMINUS" + : + : + +== expect + +Racc supports Bison's "expect" directive to declare the expected +number of shift/reduce conflicts. + + class MyParser + expect 3 + rule + : + : + +Then warnings are issued only when the effective number of conflicts differs. + +== Declaring Tokens + +Declaring tokens avoids many bugs. + +Racc outputs warnings for declared tokens that do not exist, or existing tokens not declared. +The syntax is: + + token TOKEN_NAME AND_IS_THIS + ALSO_THIS_IS AGAIN_AND_AGAIN THIS_IS_LAST + +== Options + +You can write options for racc command in your racc file. + + options OPTION OPTION ... + +Options are: + + * omit_action_call + +omit empty action call or not. + + * result_var + +use/does not use local variable "result" + +You can use 'no_' prefix to invert its meanings. + +== Converting Token Symbol + +Token symbols are, as default, + + * naked token strings in racc file (TOK, XFILE, this_is_token, ...) + --> symbol (:TOK, :XFILE, :this_is_token, ...) + * quoted strings (':', '.', '(', ...) + --> same string (':', '.', '(', ...) + +You can change this default using a "convert" block. +Here is an example: + + convert + PLUS 'PlusClass' # We use PlusClass for symbol of `PLUS' + MIN 'MinusClass' # We use MinusClass for symbol of `MIN' + end + +We can use almost all ruby value can be used by token symbol, +except 'false' and 'nil'. These are causes unexpected parse error. + +If you want to use String as token symbol, special care is required. +For example: + + convert + class '"cls"' # in code, "cls" + PLUS '"plus\n"' # in code, "plus\n" + MIN "\"minus#{val}\"" # in code, \"minus#{val}\" + end + +== Start Rule + +'%start' in yacc. This changes the start symbol. + + start real_target + +== User Code Block + +A "User Code Block" is a piece of Ruby source code copied in the output. +There are three user code blocks, "header" "inner" and "footer". + +User code blocks are introduced by four '-' at the beginning of a line, +followed by a single-word name: + + ---- header + ruby statement + ruby statement + ruby statement + + ---- inner + ruby statement + : + : diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/doc/en/grammar2.en.rdoc b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/doc/en/grammar2.en.rdoc new file mode 100644 index 00000000..8e9b9ddf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/doc/en/grammar2.en.rdoc @@ -0,0 +1,219 @@ += Racc Grammar File Reference + +== Global Structure + +== Class Block and User Code Block + +There are two blocks on the toplevel. One is the 'class' block, the other is the 'user code' +block. The 'user code' block MUST be placed after the 'class' block. + +== Comments + +You can insert comments about all places. Two styles of comments can be used, Ruby style '#.....' and C style '/\*......*\/'. + +== Class Block + +The class block is formed like this: + + class CLASS_NAME + [precedence table] + [token declarations] + [expected number of S/R conflicts] + [options] + [semantic value conversion] + [start rule] + rule + GRAMMARS + +CLASS_NAME is a name of the parser class. This is the name of the generating parser +class. + +If CLASS_NAME includes '::', Racc outputs the module clause. For example, writing +"class M::C" causes the code below to be created: + + module M + class C + : + : + end + end + +== Grammar Block + +The grammar block describes grammar which is able to be understood by the parser. +Syntax is: + + (token): (token) (token) (token).... (action) + + (token): (token) (token) (token).... (action) + | (token) (token) (token).... (action) + | (token) (token) (token).... (action) + +(action) is an action which is executed when its (token)s are found. +(action) is a ruby code block, which is surrounded by braces: + + { print val[0] + puts val[1] } + +Note that you cannot use '%' string, here document, '%r' regexp in action. + +Actions can be omitted. When it is omitted, '' (empty string) is used. + +A return value of action is a value of the left side value ($$). It is the value of the +result, or the returned value by `return` statement. + +Here is an example of the whole grammar block. + + rule + goal: definition rules source { result = val } + + definition: /* none */ { result = [] } + | definition startdesig { result[0] = val[1] } + | definition + precrule # this line continues from upper line + { + result[1] = val[1] + } + + startdesig: START TOKEN + +You can use the following special local variables in action: + +* result ($$) + +The value of the left-hand side (lhs). A default value is val[0]. + +* val ($1,$2,$3...) + +An array of value of the right-hand side (rhs). + +* _values (...$-2,$-1,$0) + +A stack of values. DO NOT MODIFY this stack unless you know what you are doing. + +== Operator Precedence + +This function is equal to '%prec' in yacc. +To designate this block: + + prechigh + nonassoc '++' + left '*' '/' + left '+' '-' + right '=' + preclow + +`right` is yacc's %right, `left` is yacc's %left. + +`=` + (symbol) means yacc's %prec: + + prechigh + nonassoc UMINUS + left '*' '/' + left '+' '-' + preclow + + rule + exp: exp '*' exp + | exp '-' exp + | '-' exp =UMINUS # equals to "%prec UMINUS" + : + : + +== expect + +Racc has bison's "expect" directive. + + # Example + + class MyParser + expect 3 + rule + : + : + +This directive declares "expected" number of shift/reduce conflicts. If +"expected" number is equal to real number of conflicts, Racc does not print +conflict warning message. + +== Declaring Tokens + +By declaring tokens, you can avoid many meaningless bugs. If declared token +does not exist or existing token does not decleared, Racc output warnings. +Declaration syntax is: + + token TOKEN_NAME AND_IS_THIS + ALSO_THIS_IS AGAIN_AND_AGAIN THIS_IS_LAST + +== Options + +You can write options for Racc command in your Racc file. + + options OPTION OPTION ... + +Options are: + +* omit_action_call + +omits empty action call or not. + +* result_var + +uses local variable "result" or not. + +You can use 'no_' prefix to invert their meanings. + +== Converting Token Symbol + +Token symbols are, as default, + + * naked token string in Racc file (TOK, XFILE, this_is_token, ...) + --> symbol (:TOK, :XFILE, :this_is_token, ...) + * quoted string (':', '.', '(', ...) + --> same string (':', '.', '(', ...) + +You can change this default by "convert" block. +Here is an example: + + convert + PLUS 'PlusClass' # We use PlusClass for symbol of `PLUS' + MIN 'MinusClass' # We use MinusClass for symbol of `MIN' + end + +We can use almost all ruby value can be used by token symbol, +except 'false' and 'nil'. These cause unexpected parse error. + +If you want to use String as token symbol, special care is required. +For example: + + convert + class '"cls"' # in code, "cls" + PLUS '"plus\n"' # in code, "plus\n" + MIN "\"minus#{val}\"" # in code, \"minus#{val}\" + end + +== Start Rule + +'%start' in yacc. This changes start rule. + + start real_target + +== User Code Block + +"User Code Block" is a Ruby source code which is copied to output. There are +three user code blocks, "header" "inner" and "footer". + +Format of user code is like this: + + ---- header + ruby statement + ruby statement + ruby statement + + ---- inner + ruby statement + : + : + +If four '-' exist on the line head, Racc treats it as the beginning of the +user code block. The name of the user code block must be one word. diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/doc/ja/command.ja.html b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/doc/ja/command.ja.html new file mode 100644 index 00000000..52eccfd4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/doc/ja/command.ja.html @@ -0,0 +1,99 @@ +

Raccコマンドリファレンス

+

+racc [-ofilename] [--output-file=filename] + [-erubypath] [--executable=rubypath] + [-v] [--verbose] + [-Ofilename] [--log-file=filename] + [-g] [--debug] + [-E] [--embedded] + [-F] [--frozen] + [-l] [--no-line-convert] + [-c] [--line-convert-all] + [-a] [--no-omit-actions] + [-C] [--check-only] + [-S] [--output-status] + [--version] [--copyright] [--help] grammarfile +

+ +
+
filename +
+Raccの文法ファイルを指定します。拡張子には特に制限はありません。 +
+
-ooutfile, --output-file=outfile +
+作成するクラスをかきこむファイル名を指定します。デフォルトは.tab.rbです。 +
+
-Ofilename, --log-file=filename +
+-v オプションをつけた時に生成するログファイルの名前を +filename に変更します。 +デフォルトは filename.output です。 +
+
-erubypath, --executable=rubypath +
+実行可能ファイルを生成します。rubypathは Ruby 本体のパスです。 +rubypathを単に 'ruby' にした時には Racc が動作している +Ruby のパスを使用します。 +
+
-v, --verbose +
+ファイル "filename".output に詳細な解析情報を出力します。 +
+
-g, --debug +
+出力するコードにデバッグ用コードを加えます。-g をつけて生成したパーサで +@yydebug を true にセットすると、デバッグ用のコードが出力されます。
+-g をつけるだけでは何もおこりませんので注意してください。 +
+
-E, --embedded +
+ランタイムルーチンをすべて含んだコードを生成します。 +つまり、このオプションをつけて生成したコードは Ruby さえあれば動きます。 +
+
-F, --frozen +
+Add frozen_string_literals: true. +
+
-C, --check-only +
+(文法ファイルの) 文法のチェックだけをして終了します。 +
+
-S, --output-status +
+進行状況を逐一報告します。 +
+
-l, --no-line-convert +
+

+Ruby では例外が発生した時のファイル名や行番号を表示してくれますが、 +Racc の生成したパーサは、デフォルトではこの場合のファイル名・行番号を +文法ファイルでのものに置きかえます。このフラグはその機能をオフにします。 +

+

+ruby 1.4.3 以前のバージョンではバグのために定数の参照に失敗する +場合があるので、定数参照に関してなにかおかしいことがおこったらこのフラグを +試してみてください。 +

+
+
-c, --line-convert-all +
+アクションと inner に加え header footer の行番号も変換します。 +header と footer がつながっているような場合には使わないでください。 +
-a, --no-omit-actions +
+全てのアクションに対応するメソッド定義と呼び出しを行います。 +例えアクションが省略されていても空のメソッドを生成します。 +
+
--version +
+Racc のバージョンを出力して終了します。 +
+
--copyright +
+著作権表示を出力して終了します。 +
--help +
+オプションの簡単な説明を出力して終了します。 +
+
diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/doc/ja/debug.ja.rdoc b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/doc/ja/debug.ja.rdoc new file mode 100644 index 00000000..90f70f68 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/doc/ja/debug.ja.rdoc @@ -0,0 +1,36 @@ += パーサのデバッグ + +ここでは、Racc を使っていくうえで遭遇しそうな問題について書きます。 + +== 文法ファイルがパースエラーになる + +エラーメッセージに出ている行番号のあたりを見て間違いを +探してください。ブロックを閉じる行でエラーになる場合は、 +どこかで開き括弧などを増やしてしまっている可能性が高いです。 + +== なんたら conflict って言われた + +一番ありがちで一番面倒な問題は衝突 (conflict) でしょう。 +文法中に衝突があると、racc はコンパイル後に +「5 shift/reduce conflict」のようなメッセージを表示します。 +-v をつけると出力される .output ファイルからはさらに詳しい情報が得られます。 +それをどう使うか、とかそういうことに関しては、それなりの本を読んでください。 +とてもここに書けるような単純な話ではありません。 +当然ながら『Ruby を 256 倍使うための本 無道編』(青木峰郎著)がお勧めです。 + +== パーサは問題なく生成できたけど予想どおりに動かない + +racc に -g オプションをつけてパーサを出力すると、デバッグ用のコードが +付加されます。ここで、パーサクラスのインスタンス変数 @yydebug を true に +しておいてから do_parse/yyparse を呼ぶと、デバッグ用メッセージが出力 +されます。パーサが動作する様子が直接見えますので、完全に現在の状態を +把握できます。これを見てどこがおかしいのかわかったらあとは直すだけ。 + +== next_token に関して + +いまだ自分でも忘れることが多いのが +「送るトークンが尽きたら [false,なにか] を送る」ということです。 +ちなみに Racc 0.10.2 以降では一度 [false,なにか] を受け取ったら +それ以上 next_token は呼ばないことが保証されています。 + +追記: 最近は [false,なにか] ではなく nil でもよいことになった。 diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/doc/ja/grammar.ja.rdoc b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/doc/ja/grammar.ja.rdoc new file mode 100644 index 00000000..fd414a05 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/doc/ja/grammar.ja.rdoc @@ -0,0 +1,348 @@ += 規則ファイル文法リファレンス + +== 文法に関する前バージョンとの非互換 + + * (1.2.5) ユーザーコードを連結する時、外部ファイルよりも + 埋めこんであるコードを先に連結します。 + * (1.1.6) 新しいディレクティブ options が追加されました。 + * (1.1.5) 予約語 token の意味が変更になりました。 + * (0.14) ルールの最後のセミコロンが省略可能になりました。 + また、token prechigh などが予約語でなくなりました。 + * (10.2) prepare が header に driver が footer になりました。 + 今はそのままでも使えますが、2.0 からは対応しません。 + * (0.10) class に対応する end がなくなりました。 + * (0.9) ダサダサのピリオド方式をやめて { と } で囲むようにしました。 + +== 全体の構造 + +トップレベルは、規則部とユーザーコード部に分けられます。 +ユーザーコード部はクラス定義の後に来なければいけません。 + +=== コメント + +文法ファイルには、一部例外を除いて、ほとんどどこにでもコメントを +書くことができます。コメントは、Rubyの #.....(行末) スタイルと、 +Cの /*......*/ スタイルを使うことができます。 + +=== 規則部 + +規則部は以下のような形をしています。 +-- +class クラス名 [< スーパークラス] + [演算子順位] + [トークン宣言] + [オプション] + [expect] + [トークンシンボル値おきかえ] + [スタート規則] +rule + 文法記述 +-- +"クラス名"はここで定義するパーサクラスの名前です。 +これはそのままRubyのクラス名になります。 + +また M::C のように「::」を使った名前を使うと、クラス定義を +モジュール M の中にネストさせます。つまり class M::C ならば +-- +module M + class C < Racc::Parser + いろいろ + end +end +-- +のように出力します。 + +さらに、Ruby と同じ構文でスーパークラスを指定できます。 +ただしこの指定をするとパーサの動作に重大な影響を与えるので、 +特に必要がない限り指定してはいけません。これは将来の拡張の +ために用意したもので、現在指定する必然性はあまりありません。 + +=== 文法の記述 + +racc で生成するパーサが理解できる文法を記述します。 +文法は、予約語 rule と end の間に、以下のような書式で書きます。 +-- +トークン: トークンの並び アクション + +トークン: トークンの並び アクション + | トークンの並び アクション + | トークンの並び アクション + (必要なだけ同じようにつづける) +-- +アクションは { } で囲みます。アクションでは Ruby の文はほとんど +使えますが、一部だけは非対応です。対応していないものは以下のとおり。 + + * ヒアドキュメント + * =begin ... =end 型コメント + * スペースで始まる正規表現 + * ごくまれに % の演算。普通に演算子のまわりにスペースを入れていれば問題なし + +このあたりに関しては完全な対応はまず無理です。あきらめてください。 + +左辺の値($$)は、オプションによって返し方がかわります。まずデフォルトでは +ローカル変数 result (そのデフォルト値は val[0])が 左辺値を表し、アクション +ブロックを抜けた時の result の値が左辺値になります。または明示的に return +で返した場合もこの値になります。一方、options で no_result_var を指定した +場合、左辺値はアクションブロックの最後の文の値になります (Ruby のメソッドと +同じ)。 + +どちらの場合でもアクションは省略でき、省略した場合の左辺値は常に val[0] です。 + +以下に文法記述の全体の例をしめします。 +-- +rule + goal: def ruls source + { + result = val + } + + def : /* none */ + { + result = [] + } + | def startdesig + { + result[0] = val[1] + } + | def + precrule # これは上の行の続き + { + result[1] = val[1] + } +(略) +-- +アクション内では特別な意味をもった変数がいくつか使えます。 +そのような変数を以下に示します。括弧の中は yacc での表記です。 + + * result ($$) + +左辺の値。初期値は val[0] です。 + + * val ($1,$2,$3…) + +右辺の記号の値の配列。Ruby の配列なので当然インデックスはゼロから始まります。 +この配列は毎回作られるので自由に変更したり捨てたりして構いません。 + + * _values (...,$-2,$-1,$0) + +値スタック。Racc コアが使っているオブジェクトがそのまま渡されます。 +この変数の意味がわかる人以外は絶対に変更してはいけません。 + +またアクションの特別な形式に、埋めこみアクションというものがあります。 +これはトークン列の途中の好きなところに記述することができます。 +以下に埋めこみアクションの例を示します。 +-- +target: A B { puts 'test test' } C D { normal action } +-- +このように記述すると A B を検出した時点で puts が実行されます。 +また、埋めこみアクションはそれ自体が値を持ちます。つまり、以下の例において +-- +target: A { result = 1 } B { p val[1] } +-- +最後にある p val[1] は埋めこみアクションの値 1 を表示します。 +B の値ではありません。 + +意味的には、埋めこみアクションは空の規則を持つ非終端記号を追加することと +全く同じ働きをします。つまり、上の例は次のコードと完全に同じ意味です。 +-- +target : A nonterm B { p val[1] } +nonterm : /* 空の規則 */ { result = 1 } +-- + +=== 演算子優先順位 + +あるトークン上でシフト・還元衝突がおこったとき、そのトークンに +演算子優先順位が設定してあると衝突を解消できる場合があります。 +そのようなものとして特に有名なのは数式の演算子と if...else 構文です。 + +優先順位で解決できる文法は、うまく文法をくみかえてやれば +優先順位なしでも同じ効果を得ることができます。しかしたいていの +場合は優先順位を設定して解決するほうが文法を簡単にできます。 + +シフト・還元衝突がおこったとき、Racc はまずその規則に順位が設定 +されているか調べます。規則の順位は、その規則で一番うしろにある +終端トークンの優先順位です。たとえば +-- +target: TERM_A nonterm_a TERM_B nonterm_b +-- +のような規則の順位はTERM_Bの優先順位になります。もしTERM_Bに +優先順位が設定されていなかったら、優先順位で衝突を解決することは +できないと判断し、「Shift/Reduce conflict」を報告します。 + +演算子の優先順位はつぎのように書いて定義します。 +-- +prechigh + nonassoc PLUSPLUS + left MULTI DIVIDE + left PLUS MINUS + right '=' +preclow +-- +prechigh に近い行にあるほど優先順位の高いトークンです。上下をまるごと +さかさまにして preclow...prechigh の順番に書くこともできます。left +などは必ず行の最初になければいけません。 + +left right nonassoc はそれぞれ「結合性」を表します。結合性によって、 +同じ順位の演算子の規則が衝突した場合にシフト還元のどちらをとるかが +決まります。たとえば +-- +a - b - c +-- +が +-- +(a - b) - c +-- +になるのが左結合 (left) です。四則演算は普通これです。 +一方 +-- +a - (b - c) +-- +になるのが右結合 (right) です。代入のクオートは普通 right です。 +またこのように演算子が重なるのはエラーである場合、非結合 (nonassoc) です。 +C 言語の ++ や単項のマイナスなどがこれにあたります。 + +ところで、説明したとおり通常は還元する規則の最後のトークンが順位を +決めるのですが、ある規則に限ってそのトークンとは違う順位にしたいことも +あります。例えば符号反転のマイナスは引き算のマイナスより順位を高く +しないといけません。このような場合 yacc では %prec を使います。 +racc ではイコール記号を使って同じことをできます。 +-- +prechigh + nonassoc UMINUS + left '*' '/' + left '+' '-' +preclow +(略) +exp: exp '*' exp + | exp '-' exp + | '-' exp = UMINUS # ここだけ順位を上げる +-- +このように記述すると、'-' exp の規則の順位が UMINUS の順位になります。 +こうすることで符号反転の '-' は '*' よりも順位が高くなるので、 +意図どおりになります。 + +=== トークン宣言 + +トークン(終端記号)のつづりを間違えるというのはよくあることですが、 +発見するのはなかなか難しいものです。1.1.5 からはトークンを明示的に +宣言することで、宣言にないトークン / 宣言にだけあるトークンに対して +警告が出るようになりました。yacc の %token と似ていますが最大の違いは +racc では必須ではなく、しかもエラーにならず警告だけ、という点です。 + +トークン宣言は以下のように書きます。 +-- +token A B C D + E F G H +-- +トークンのリストを複数行にわたって書けることに注目してください。 +racc では一般に「予約語」は行の先頭に来た時だけ予約語とみなされるので +prechigh などもシンボルとして使えます。ただし深淵な理由から end だけは +どうやっても予約語になってしまいます。 + +=== オプション + +racc のコマンドラインオプションの一部をファイル中にデフォルト値 +として記述することができます。 +-- +options オプション オプション … +-- +現在ここで使えるのは + + * omit_action_call + +空のアクション呼び出しを省略する + + * result_var + +変数 result を使う + +です。 +それぞれ no_ を頭につけることで意味を反転できます。 + +=== expect + +実用になるパーサはたいてい無害な shift/reduce conflict を含みます。 +しかし文法ファイルを書いた本人はそれを知っているからいいですが、 +ユーザが文法ファイルを処理した時に「conflict」と表示されたら +不安に思うでしょう。そのような場合、以下のように書いておくと +shift/reduce conflict のメッセージを抑制できます。 +-- +expect 3 +-- +この場合 shift/reduce conflict はぴったり三つでなければいけません。 +三つでない場合はやはり表示が出ます (ゼロでも出ます)。 +また reduce/reduce conflict の表示は抑制できません。 + +=== トークンシンボル値の変更 + +トークンシンボルを表す値は、デフォルトでは + + * 文法中、引用符でかこまれていないもの (RULEとかXENDとか) + →その名前の文字列を intern して得られるシンボル (1.4 では Fixnum) + * 引用符でかこまれているもの(':'とか'.'とか) + →その文字列そのまま + +となっていますが、たとえば他の形式のスキャナがすでに存在する場合などは、 +これにあわせなければならず、このままでは不便です。このような場合には、 +convert 節を加えることで、トークンシンボルを表す値を変えることができます。 +以下がその例です。 +-- +convert + PLUS 'PlusClass' #→ PlusClass + MIN 'MinusClass' #→ MinusClass +end +-- +デフォルトではトークンシンボル PLUS に対してはトークンシンボル値は +:PLUS ですが、上のような記述がある場合は PlusClass になります。 +変換後の値は false・nil 以外ならなんでも使えます。 + +変換後の値として文字列を使うときは、次のように引用符を重ねる必要があります。 +-- +convert + PLUS '"plus"' #→ "plus" +end +-- +また、「'」を使っても生成された Ruby のコード上では「"」になるので +注意してください。バックスラッシュによるクオートは有効ですが、バック +スラッシュは消えずにそのまま残ります。 +-- +PLUS '"plus\n"' #→ "plus\n" +MIN "\"minus#{val}\"" #→ \"minus#{val}\" +-- + +=== スタート規則 + +パーサをつくるためには、どの規則が「最初の」規則か、ということを Racc におしえて +やらなければいけません。それを明示的に書くのがスタート規則です。スタート規則は +次のように書きます。 +-- +start real_target +-- +start は行の最初にこなければいけません。このように書くと、ファイルで +一番最初に出てくる real_target の規則をスタート規則として使います。 +省略した場合は、ファイルの最初の規則がスタート規則になります。普通は +最初の規則を一番上にかくほうが書きやすく、わかりやすくなりますから、 +この記法はあまりつかう必要はないでしょう。 + +=== ユーザーコード部 + +ユーザーコードは、パーサクラスが書きこまれるファイルに、 +アクションの他にもコードを含めたい時に使います。このようなものは +書きこまれる場所に応じて三つ存在し、パーサクラスの定義の前が +header、クラスの定義中(の冒頭)が inner、定義の後が footer です。 +ユーザコードとして書いたものは全く手を加えずにそのまま連結されます。 + +ユーザーコード部の書式は以下の通りです。 +-- +---- 識別子 + ruby の文 + ruby の文 + ruby の文 + +---- 識別子 + ruby の文 + : +-- +行の先頭から四つ以上連続した「-」(マイナス)があるとユーザーコードと +みなされます。識別子は一つの単語で、そのあとには「=」以外なら何を +書いてもかまいません。 diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/doc/ja/index.ja.html b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/doc/ja/index.ja.html new file mode 100644 index 00000000..29fd70f3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/doc/ja/index.ja.html @@ -0,0 +1,10 @@ +

Racc ユーザマニュアル

+

バージョン 1.4 対応

+ diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/doc/ja/parser.ja.rdoc b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/doc/ja/parser.ja.rdoc new file mode 100644 index 00000000..395047bf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/doc/ja/parser.ja.rdoc @@ -0,0 +1,125 @@ += class Racc::Parser +Racc の生成するパーサはすべて Racc::Parser クラスを継承します。 +Racc::Parser クラスにはパース中に使用するメソッドがいくつかあり、 +そのようなメソッドをオーバーロードすると、パーサを初期化したり +することができます。 + +== Super Class + +Object + +== Constants + +プリフィクス "Racc_" がついた定数はパーサの予約定数です。 +そのような定数は使わないでください。動作不可能になります。 +== Instance Methods +ここに載っているもののほか、プリフィクス "racc_" および "_racc_" が +ついたメソッドはパーサの予約名です。そのようなメソッドは使わないで +ください。 + +: do_parse -> Object + パースを開始します。 + また、トークンが必要になった時は #next_token を呼び出します。 + + -- + # Example + ---- inner + def parse + @q = [[1,1], + [2,2], + [3,3], + [false, '$']] + do_parse + end + + def next_token + @q.shift + end + -- + +: next_token -> [Symbol, Object] + [abstract method] + + パーサが次のトークンを読みこむ時に使います。 + [記号, その値] の形式の配列を返してください。 + 記号はデフォルトでは + + * 文法中、引用符でかこまれていないもの + → その名前の文字列のシンボル (例えば :ATOM ) + * 引用符でかこまれているもの
+ → その文字列そのまま (例えば '=' ) + + で表します。これを変更する方法については、 + 文法リファレンスを参照してください。 + + また、もう送るシンボルがなくなったときには + [false, なにか] または nil を返してください。 + + このメソッドは抽象メソッドなので、#do_parse を使う場合は + 必ずパーサクラス中で再定義する必要があります。 + 定義しないままパースを始めると例外 NotImplementedError が + 発生します。 + +: yyparse( receiver, method_id ) + パースを開始します。このメソッドでは始めてトークンが + 必要になった時点で receiver に対して method_id メソッドを + 呼び出してトークンを得ます。 + + receiver の method_id メソッドはトークンを yield しなければ + なりません。形式は #next_token と同じで [記号, 値] です。 + つまり、receiver の method_id メソッドの概形は以下のように + なるはずです。 + -- + def method_id + until end_of_file + : + yield 記号, 値 + : + end + end + -- + 少し注意が必要なのは、method_id が呼び出されるのは始めて + トークンが必要になった時点であるということです。method_id + メソッドが呼び出されたときは既にパースが進行中なので、 + アクション中で使う変数を method_id の冒頭で初期化すると + まず失敗します。 + + トークンの終端を示す [false, なにか] を渡したらそれ以上は + yield しないでください。その場合には例外が発生します。 + + 最後に、method_id メソッドからは必ず yield してください。 + しない場合は何が起きるかわかりません。 + +: on_error( error_token_id, error_value, value_stack ) + パーサコアが文法エラーを検出すると呼び出します (yacc の yyerror)。 + エラーメッセージを出すなり、例外を発生するなりしてください。 + このメソッドから正常に戻った場合、パーサはエラー回復モード + に移行します。 + + error_token_id はパースエラーを起こした記号の内部表現 (整数) です。 + #token_to_str で文法ファイル上の文字列表現に直せます。 + + error_value はその値です。 + + value_stack はエラーの時点での値スタックです。 + value_stack を変更してはいけません。 + + on_error のデフォルトの実装は例外 ParseError を発生します。 + +: token_to_str( t ) -> String + Racc トークンの内部表現 (整数) + を文法ファイル上の記号表現の文字列に変換します。 + + t が整数でない場合は TypeError を発生します。 + t が範囲外の整数だった場合は nil を返します。 + +: yyerror + エラー回復モードに入ります。このとき #on_error は呼ばれません。 + アクション以外からは呼び出さないでください。 + +: yyerrok + エラー回復モードから復帰します。 + アクション以外からは呼び出さないでください。 + +: yyaccept + すぐに値スタックの先頭の値を返して #do_parse、#yyparse を抜けます。 diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/doc/ja/usage.ja.html b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/doc/ja/usage.ja.html new file mode 100644 index 00000000..8884b8f6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/doc/ja/usage.ja.html @@ -0,0 +1,414 @@ +

Racc の使い方

+

+Racc は文法規則から Ruby で書かれたパーサを生成するパーサジェネレータです。 +パーサ生成アルゴリズムには yacc などと同じ LALR(1) を使用しています。 +

+

+yacc を知っている人は記述法の違いだけわかれば使えると思います。 +yacc を知らない人は +拙著『Ruby を 256 倍使うための本 無道編』(青木峰郎著、ASCII) +などを一読していただくのがよいかと思います。 +他の UNIX コマンドなどとは異なり、 +いきなり使うだけで Racc を理解するのはかなり困難です。 +

+ +

Racc とはなにか

+

+Racc は文法を処理するツールです。 +文字列はただの文字の列で、コンピュータにとっては意味を持ちません。 +しかし人間はその文字の列の中になにか意味を見出すことができます。 +コンピュータにもそのようなことを、部分的にでも、させられたら便利でしょう。 +Racc はその手伝いをしてくれます。完全な自動化ではありませんが、 +人間が全部やるよりも遥かに簡単になります。 +

+

+Racc が自動化してくれる部分とは、文字列の含む「構造」の処理です。 +たとえば Ruby の if 文を考えてみると、次のように定式化できます。 +

+
+if 条件式 [then]
+  文
+  :
+[elsif 条件式 [then]
+  文
+  :]
+[else
+  文
+  :]
+end
+
+

+if 文では if という単語が最初になくてはならず、 +elsif 節は else 節より前になくてはいけません。 +このような配置の関係 (構造) が、Racc が処理する対象です。 +

+

+一方、Racc で処理できないのはどういうことでしょうか。それは、たとえば +if の条件式にあたる部分が「なんであるか」ということです。つまり、条件 +式が if の条件だということです。これは、こっちで条件として扱うコードを +書いてやらないといけません。 +

+

+と言っても、わかりにくいでしょう。こういう抽象的なものは実際にいじって +みるのが一番です。 +

+ +

実際の話

+

+実際に Racc をどのように使うかという話をします。Racc には独自のソース +コードみたいなものがあって、この中に処理したい「構造」を記述しておきま +す。このソースファイルを「文法ファイル」と呼ぶことにしましょう。この文 +法ファイルの名前が parse.y と仮定すると、コマンドラインから以下のよう +に打ちこめば、その構造を処理するためのクラスを含んだファイルが得られま +す。 +

+
+$ racc parse.y
+
+

+生成されるファイルはデフォルトでは "ファイル名.tab.rb" です。他の名前 +にしたいなら、-o オプションで変更できます。 +

+
+$ racc parse.y -o myparser.rb
+
+

+このようにして作ったクラス、またはそのような処理を担当するパート、 +のことはパーサ (parser) と呼ぶことになっています。解析するヤツ、 +というくらいに適当にとらえてください。 +

+ +

文法ファイルを書く

+

+Racc は文法ファイルから Ruby のクラスを生成するツールだと言いました。 +そのクラスは全て Racc::Parser の下位クラスで、名前は文法ファイル中で +指定します。以下、ここに書くべきことが「なんなのか」を説明します。 +ここでは内容に重点を置くので、文法ファイル自体の文法の詳細は +文法リファレンスを見てください。 +

+ +

文法

+

+まずは、全体の概形です。 +

+
+class MyParser
+rule
+
+  if_stmt: IF expr then stmt_list elsif else END
+
+  then   : THEN
+         |
+
+  elsif  :
+         | ELSIF stmt_list
+
+  else   :
+         | ELSE stmt_list
+
+  expr   : NUMBER
+         | IDENT
+         | STRING
+
+  stmt_list : ふにゃふにゃ
+
+end
+
+

+Ruby スクリプトのように class でパーサクラス名を指定し、rule ... end +の間にパーサに解析させたい文法を記述します。 +

+

+文法は、記号の並びでもって表します。rule ... end の間にあるコロンとバー +以外のもの、if_stmt IF expr then などが全て「記号」です。そしてコロン +が日本語で言う「〜は××だ」の「は」みたいなもんで、その左の記号が右の +記号の列と同じものを指す、というふうに定義します。また、バーは「または」 +を意味します。それと、単純にコロンの左の記号のことを左辺、右を右辺とも +言います。以下はこちらのほうを使って説明しましょう。 +

+

+少し注意が必要な点を述べます。まず、then の、バーのあとの定義 (規則) を +見てください。ここには何も書いていないので、これはその通り「無」であっ +てもいい、ということを表しています。つまり、then は記号 THEN 一個か、 +またはなにもなし(省略する)でよい、ということです。記号 then は実際の +Ruby のソースコードにある then とは切り離して考えましょう +(それは実は大文字の記号 THEN が表しています)。 +

+

+さて、そろそろ「記号」というものがなんなのか書きましょう。 +ただし順番に話をしないといけないので、まずは聞いていてください。 +この文章の最初に、パーサとは文字の列から構造を見出す部分だと言いました。 +しかし文字の列からいきなり構造を探すのは面倒なので、実際にはまず +文字の列を単語の列に分割します。その時点でスペースやコメントは捨てて +しまい、以降は純粋にプログラムの一部をなす部分だけを相手にします。 +たとえば文字列の入力が次のようだったとすると、 +

+
+if flag then   # item found.
+  puts 'ok'
+end
+
+

+単語の列は次のようになります。 +

+
+if flag then puts 'ok' end
+
+

+ここで、工夫が必要です。どうやら flag はローカル変数名だと思われますが、 +変数名というのは他にもいろいろあります。しかし名前が i だろうが a だろ +うが vvvvvvvvvvvv だろうが、「構造」は同じです。つまり同じ扱いをされる +べきです。変数 a を書ける場所なら b も書けなくてはいけません。だったら +一時的に同じ名前で読んでもいいじゃん。ということで、この単語の列を以下 +のように読みかえましょう。 +

+
+IF IDENT THEN IDENT STRING END
+
+

+これが「記号」の列です。パーサではこの記号列のほうを扱い、構造を見付け +ていきます。 +

+

+さらに記号について見ていきましょう。 +記号は二種類に分けられます。「左辺にある記号」と「ない記号」です。 +左辺にある記号は「非終端」記号と言います。ないほうは「終端」記号と +言います。最初の例では終端記号はすべて大文字、非終端記号は小文字で +書いてあるので、もう一度戻って例の文法を見てください。 +

+

+なぜこの区分が重要かと言うと、入力の記号列はすべて終端記号だからです。 +一方、非終端記号はパーサの中でだけ、終端記号の列から「作りだす」ことに +よって始めて存在します。例えば次の規則をもう一度見てください。 +

+
+  expr   : NUMBER
+         | IDENT
+         | STRING
+
+

+expr は NUMBER か IDENT か STRING だと言っています。逆に言うと、 +IDENT は expr に「なることができます」。文法上 expr が存在できる +場所に IDENT が来ると、それは expr になります。例えば if の条件式の +部分は expr ですから、ここに IDENT があると expr になります。その +ように文法的に「大きい」記号を作っていって、最終的に一個になると、 +その入力は文法を満たしていることになります。実際にさっきの入力で +試してみましょう。入力はこうでした。 +

+
+IF IDENT THEN IDENT STRING END
+
+

+まず、IDENT が expr になります。 +

+
+IF expr THEN IDENT STRING END
+
+

+次に THEN が then になります。 +

+
+IF expr then IDENT STRING END
+
+

+IDENT STRING がメソッドコールになります。この定義はさきほどの例には +ないですが、実は省略されているんだと考えてください。そしていろいろな +過程を経て、最終的には stmt_list (文のリスト)になります。 +

+
+IF expr then stmt_list END
+
+

+elsif と else は省略できる、つまり無から生成できます。 +

+
+IF expr then stmt_list elsif else END
+
+

+最後に if_stmt を作ります。 +

+
+if_stmt
+
+

+ということでひとつになりました。 +つまりこの入力は文法的に正しいということがわかりました。 +

+ +

アクション

+

+ここまでで入力の文法が正しいかどうかを確認する方法はわかりましたが、 +これだけではなんにもなりません。最初に説明したように、ここまででは +構造が見えただけで、プログラムは「意味」を理解できません。そしてその +部分は Racc では自動処理できないので、人間が書く、とも言いました。 +それを書くのが以下に説明する「アクション」という部分です。 +

+

+前項で、記号の列がだんだんと大きな単位にまとめられていく過程を見ました。 +そのまとめる時に、同時になにかをやらせることができます。それが +アクションです。アクションは、文法ファイルで以下のように書きます。 +

+
+class MyParser
+rule
+
+  if_stmt: IF expr then stmt_list elsif else END
+             { puts 'if_stmt found' }
+
+  then   : THEN
+             { puts 'then found' }
+         |
+             { puts 'then is omitted' }
+
+  elsif  :
+             { puts 'elsif is omitted' }
+         | ELSIF stmt_list
+             { puts 'elsif found' }
+
+  else   :
+             { puts 'else omitted' }
+         | ELSE stmt_list
+             { puts 'else found' }
+
+  expr   : NUMBER
+             { puts 'expr found (NUMBER)' }
+         | IDENT
+             { puts 'expr found (IDENT)' }
+         | STRING
+             { puts 'expr found (STRING)' }
+
+  stmt_list : ふにゃふにゃ
+
+end
+
+

+見てのとおり、規則のあとに { と } で囲んで書きます。 +アクションにはだいたい好きなように Ruby スクリプトが書けます。 +

+

+(この節、未完) +

+
+ +

+yacc での $$ は Racc ではローカル変数 result +で、$1,$2... は配列 valです。 +resultval[0] ($1) の値に初期化され、 +アクションを抜けたときの result の値が左辺値になります。 +Racc ではアクション中の return はアクションから抜けるだけで、 +パース自体は終わりません。アクション中からパースを終了するには、 +メソッド yyaccept を使ってください。 +

+

+演算子の優先順位、スタートルールなどの yacc の一般的な機能も用意されて +います。ただしこちらも少し文法が違います。 +

+

+yacc では生成されたコードに直接転写されるコードがありました。 +Racc でも同じように、ユーザ指定のコードが書けます。 +Racc ではクラスを生成するので、クラス定義の前/中/後の三個所があります。 +Racc ではそれを上から順番に header inner footer と呼んでいます。 +

+ +

ユーザが用意すべきコード

+

+パースのエントリポイントとなるメソッドは二つあります。ひとつは +do_parseで、こちらはトークンを +Parser#next_token から得ます。もうひとつは +yyparse で、こちらはスキャナから yield され +ることによってトークンを得ます。ユーザ側ではこのどちらか(両方でもいい +けど)を起動する簡単なメソッドを inner に書いてください。これらメソッド +の引数など、詳しいことはリファレンスを見てください。 +

+ +

+どちらのメソッドにも共通なのはトークンの形式です。必ずトークンシンボル +とその値の二要素を持つ配列を返すようにします。またスキャンが終了して、 +もう送るものがない場合は [false,なにか] を返し +てください。これは一回返せば十分です (逆に、yyparse を使 +う場合は二回以上 yield してはいけない)。 +

+

+パーサは別に文字列処理にだけ使われるものではありませんが、実際問題とし +て、パーサを作る場面ではたいてい文字列のスキャナとセットで使うことが多 +いでしょう。Ruby ならスキャナくらい楽勝で作れますが、高速なスキャナと +なると実は難しかったりします。そこで高速なスキャナを作成するためのライ +ブラリも作っています。詳しくは +「スキャナを作る」の項を見てください。 +

+

+Racc には error トークンを使ったエラー回復機能もあります。yacc の +yyerror() は Racc では +Racc::Parser#on_error +で、エラーが起きたトークンとその値、値スタック、の三つの引数をとります。 +on_error のデフォルトの実装は例外 +Racc::ParseError を発生します。 +

+

+ユーザがアクション中でパースエラーを発見した場合は、メソッド +yyerror +を呼べばパーサがエラー回復モードに入ります。 +ただしこのとき on_errorは呼ばれません。 +

+ +

パーサを生成する

+

+これだけあればだいたい書けると思います。あとは、最初に示した方法で文法 +ファイルを処理し、Ruby スクリプトを得ます。 +

+

+うまくいけばいいのですが、大きいものだと最初からはうまくいかないでしょ +う。racc に -g オプションをつけてコンパイルし、@yydebug を true にする +とデバッグ用の出力が得られます。デバッグ出力はパーサの @racc_debug_out +に出力されます(デフォルトは stderr)。また、racc に -v オプションをつけ +ると、状態遷移表を読みやすい形で出力したファイル(*.output)が得られます。 +どちらもデバッグの参考になるでしょう。 +

+ + +

作ったパーサを配布する

+

+Racc の生成したパーサは動作時にランタイムルーチンが必要です。 +具体的には parser.rb と cparse.so です。 +ただし cparse.so は単にパースを高速化するためのライブラリなので +必須ではありません。なくても動きます。 +

+

+まず Ruby 1.8.0 以降にはこのランタイムが標準添付されているので、 +Ruby 1.8 がある環境ならばランタイムについて考慮する必要はありません。 +Racc 1.4.x のランタイムと Ruby 1.8 に添付されているランタイムは +完全互換です。 +

+

+問題は Ruby 1.8 を仮定できない場合です。 +Racc をユーザみんなにインストールしてもらうのも一つの手ですが、 +これでは不親切です。そこでRacc では回避策を用意しました。 +

+

+racc に -E オプションをつけてコンパイルすると、 +パーサと racc/parser.rb を合体したファイルを出力できます。 +これならばファイルは一つだけなので簡単に扱えます。 +racc/parser.rb は擬似的に require したような扱いになるので、 +この形式のパーサが複数あったとしてもクラスやメソッドが衝突することもありません。 +ただし -E を使った場合は cparse.so が使えませんので、 +必然的にパーサの速度は落ちます。 +

+ + +

おまけ: スキャナを書く

+

+パーサを使うときは、たいてい文字列をトークンに切りわけてくれるスキャナ +が必要になります。しかし実は Ruby は文字列の最初からトークンに切りわけ +ていくという作業があまり得意ではありません。 +正確に言うと、簡単にできるのですが、それなりのオーバーヘッドがかかります。 +

+

+そのオーバーヘッドを回避しつつ、 +手軽にスキャナを作れるように strscan というパッケージを作りました。 +Ruby 1.8 以降には標準添付されていますし、 +筆者のホームページには +単体パッケージがあります。 +

diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/ext/racc/cparse/Makefile b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/ext/racc/cparse/Makefile new file mode 100644 index 00000000..83d86b95 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/ext/racc/cparse/Makefile @@ -0,0 +1,273 @@ + +SHELL = /bin/sh + +# V=0 quiet, V=1 verbose. other values don't work. +V = 0 +V0 = $(V:0=) +Q1 = $(V:1=) +Q = $(Q1:0=@) +ECHO1 = $(V:1=@ :) +ECHO = $(ECHO1:0=@ echo) +NULLCMD = : + +#### Start of system configuration section. #### + +srcdir = . +topdir = /opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0 +hdrdir = $(topdir) +arch_hdrdir = /opt/hostedtoolcache/Ruby/3.4.4/x64/include/ruby-3.4.0/x86_64-linux +PATH_SEPARATOR = : +VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby +prefix = $(DESTDIR)/opt/hostedtoolcache/Ruby/3.4.4/x64 +rubysitearchprefix = $(rubylibprefix)/$(sitearch) +rubyarchprefix = $(rubylibprefix)/$(arch) +rubylibprefix = $(libdir)/$(RUBY_BASE_NAME) +exec_prefix = $(prefix) +vendorarchhdrdir = $(vendorhdrdir)/$(sitearch) +sitearchhdrdir = $(sitehdrdir)/$(sitearch) +rubyarchhdrdir = $(rubyhdrdir)/$(arch) +vendorhdrdir = $(rubyhdrdir)/vendor_ruby +sitehdrdir = $(rubyhdrdir)/site_ruby +rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME) +vendorarchdir = $(vendorlibdir)/$(sitearch) +vendorlibdir = $(vendordir)/$(ruby_version) +vendordir = $(rubylibprefix)/vendor_ruby +sitearchdir = $(sitelibdir)/$(sitearch) +sitelibdir = $(sitedir)/$(ruby_version) +sitedir = $(rubylibprefix)/site_ruby +rubyarchdir = $(rubylibdir)/$(arch) +rubylibdir = $(rubylibprefix)/$(ruby_version) +sitearchincludedir = $(includedir)/$(sitearch) +archincludedir = $(includedir)/$(arch) +sitearchlibdir = $(libdir)/$(sitearch) +archlibdir = $(libdir)/$(arch) +ridir = $(datarootdir)/$(RI_BASE_NAME) +modular_gc_dir = $(DESTDIR) +mandir = $(datarootdir)/man +localedir = $(datarootdir)/locale +libdir = $(exec_prefix)/lib +psdir = $(docdir) +pdfdir = $(docdir) +dvidir = $(docdir) +htmldir = $(docdir) +infodir = $(datarootdir)/info +docdir = $(datarootdir)/doc/$(PACKAGE) +oldincludedir = $(DESTDIR)/usr/include +includedir = $(prefix)/include +runstatedir = $(localstatedir)/run +localstatedir = $(prefix)/var +sharedstatedir = $(prefix)/com +sysconfdir = $(prefix)/etc +datadir = $(datarootdir) +datarootdir = $(prefix)/share +libexecdir = $(exec_prefix)/libexec +sbindir = $(exec_prefix)/sbin +bindir = $(exec_prefix)/bin +archdir = $(rubyarchdir) + + +CC_WRAPPER = +CC = gcc +CXX = g++ +LIBRUBY = $(LIBRUBY_SO) +LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a +LIBRUBYARG_SHARED = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME) +LIBRUBYARG_STATIC = -Wl,-rpath,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)-static $(MAINLIBS) +empty = +OUTFLAG = -o $(empty) +COUTFLAG = -o $(empty) +CSRCFLAG = $(empty) + +RUBY_EXTCONF_H = +cflags = $(hardenflags) $(optflags) $(debugflags) $(warnflags) +cxxflags = +optflags = -O3 -fno-fast-math +debugflags = -ggdb3 +warnflags = -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef +cppflags = +CCDLFLAGS = -fPIC +CFLAGS = $(CCDLFLAGS) $(cflags) -fPIC $(ARCH_FLAG) +INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) +DEFS = +CPPFLAGS = -DRACC_INFO_VERSION=1.8.1 -DENABLE_PATH_CHECK=0 $(DEFS) $(cppflags) +CXXFLAGS = $(CCDLFLAGS) $(ARCH_FLAG) +ldflags = -L. -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed +dldflags = -Wl,--compress-debug-sections=zlib +ARCH_FLAG = +DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG) +LDSHARED = $(CC) -shared +LDSHAREDXX = $(CXX) -shared +POSTLINK = : +AR = gcc-ar +LD = ld +EXEEXT = + +RUBY_INSTALL_NAME = $(RUBY_BASE_NAME) +RUBY_SO_NAME = ruby +RUBYW_INSTALL_NAME = +RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version) +RUBYW_BASE_NAME = rubyw +RUBY_BASE_NAME = ruby + +arch = x86_64-linux +sitearch = $(arch) +ruby_version = 3.4.0 +ruby = $(bindir)/$(RUBY_BASE_NAME) +RUBY = $(ruby) +BUILTRUBY = $(bindir)/$(RUBY_BASE_NAME) +ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/backward.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h + +RM = rm -f +RM_RF = rm -fr +RMDIRS = rmdir --ignore-fail-on-non-empty -p +MAKEDIRS = /usr/bin/mkdir -p +INSTALL = /usr/bin/install -c +INSTALL_PROG = $(INSTALL) -m 0755 +INSTALL_DATA = $(INSTALL) -m 644 +COPY = cp +TOUCH = exit > + +#### End of system configuration section. #### + +preload = +libpath = . $(libdir) +LIBPATH = -L. -L$(libdir) -Wl,-rpath,$(libdir) +DEFFILE = + +CLEANFILES = mkmf.log +DISTCLEANFILES = +DISTCLEANDIRS = + +extout = +extout_prefix = +target_prefix = /racc +LOCAL_LIBS = +LIBS = $(LIBRUBYARG_SHARED) -lm -lpthread -lc +ORIG_SRCS = cparse.c +SRCS = $(ORIG_SRCS) +OBJS = cparse.o +HDRS = +LOCAL_HDRS = +TARGET = cparse +TARGET_NAME = cparse +TARGET_ENTRY = Init_$(TARGET_NAME) +DLLIB = $(TARGET).so +EXTSTATIC = +STATIC_LIB = + +TIMESTAMP_DIR = . +BINDIR = $(bindir) +RUBYCOMMONDIR = $(sitedir)$(target_prefix) +RUBYLIBDIR = $(sitelibdir)$(target_prefix) +RUBYARCHDIR = $(sitearchdir)$(target_prefix) +HDRDIR = $(sitehdrdir)$(target_prefix) +ARCHHDRDIR = $(sitearchhdrdir)$(target_prefix) +TARGET_SO_DIR = +TARGET_SO = $(TARGET_SO_DIR)$(DLLIB) +CLEANLIBS = $(TARGET_SO) false +CLEANOBJS = $(OBJS) *.bak +TARGET_SO_DIR_TIMESTAMP = $(TIMESTAMP_DIR)/.sitearchdir.-.racc.time + +all: $(DLLIB) +static: $(STATIC_LIB) +.PHONY: all install static install-so install-rb +.PHONY: clean clean-so clean-static clean-rb + +clean-static:: +clean-rb-default:: +clean-rb:: +clean-so:: +clean: clean-so clean-static clean-rb-default clean-rb + -$(Q)$(RM_RF) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time + +distclean-rb-default:: +distclean-rb:: +distclean-so:: +distclean-static:: +distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb + -$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + -$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + -$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true + +realclean: distclean +install: install-so install-rb + +install-so: $(DLLIB) $(TARGET_SO_DIR_TIMESTAMP) + $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) +clean-static:: + -$(Q)$(RM) $(STATIC_LIB) +install-rb: pre-install-rb do-install-rb install-rb-default +install-rb-default: pre-install-rb-default do-install-rb-default +pre-install-rb: Makefile +pre-install-rb-default: Makefile +do-install-rb: +do-install-rb-default: +pre-install-rb-default: + @$(NULLCMD) +$(TARGET_SO_DIR_TIMESTAMP): + $(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR) + $(Q) $(TOUCH) $@ + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + +.SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S + +.cc.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cc.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.mm.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.mm.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cxx.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cxx.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.cpp.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.cpp.S: + $(ECHO) translating $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.c.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.c.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +.m.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$< + +.m.S: + $(ECHO) translating $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$< + +$(TARGET_SO): $(OBJS) Makefile + $(ECHO) linking shared-object racc/$(DLLIB) + -$(Q)$(RM) $(@) + $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) + $(Q) $(POSTLINK) + + + +$(OBJS): $(HDRS) $(ruby_headers) diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/ext/racc/cparse/cparse.c b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/ext/racc/cparse/cparse.c new file mode 100644 index 00000000..7d9319be --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/ext/racc/cparse/cparse.c @@ -0,0 +1,840 @@ +/* + + cparse.c -- Racc Runtime Core + + Copyright (c) 1999-2006 Minero Aoki + + This library is free software. + You can distribute/modify this program under the same terms of ruby. + +*/ + +#include + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +/* ----------------------------------------------------------------------- + Important Constants +----------------------------------------------------------------------- */ + +#define RACC_VERSION STRINGIZE(RACC_INFO_VERSION) + +#define DEFAULT_TOKEN -1 +#define ERROR_TOKEN 1 +#define FINAL_TOKEN 0 + +#define vDEFAULT_TOKEN INT2FIX(DEFAULT_TOKEN) +#define vERROR_TOKEN INT2FIX(ERROR_TOKEN) +#define vFINAL_TOKEN INT2FIX(FINAL_TOKEN) + +/* ----------------------------------------------------------------------- + File Local Variables +----------------------------------------------------------------------- */ + +static VALUE RaccBug; +static VALUE CparseParams; + +static ID id_yydebug; +static ID id_nexttoken; +static ID id_onerror; +static ID id_noreduce; +static ID id_errstatus; + +static ID id_d_shift; +static ID id_d_reduce; +static ID id_d_accept; +static ID id_d_read_token; +static ID id_d_next_state; +static ID id_d_e_pop; + +/* ----------------------------------------------------------------------- + Utils +----------------------------------------------------------------------- */ + +/* For backward compatibility */ +#ifndef ID2SYM +# define ID2SYM(i) ULONG2NUM(i) +#endif +#ifndef SYM2ID +# define SYM2ID(v) ((ID)NUM2ULONG(v)) +#endif +#ifndef SYMBOL_P +# define SYMBOL_P(v) FIXNUM_P(v) +#endif +#ifndef LONG2NUM +# define LONG2NUM(i) INT2NUM(i) +#endif + +static ID value_to_id(VALUE v); +static inline long num_to_long(VALUE n); + +static ID +value_to_id(VALUE v) +{ + if (! SYMBOL_P(v)) { + rb_raise(rb_eTypeError, "not symbol"); + } + return SYM2ID(v); +} + +static inline long +num_to_long(VALUE n) +{ + return NUM2LONG(n); +} + +#define AREF(s, idx) \ + ((0 <= idx && idx < RARRAY_LEN(s)) ? rb_ary_entry(s, idx) : Qnil) + +/* ----------------------------------------------------------------------- + Parser Stack Interfaces +----------------------------------------------------------------------- */ + +static VALUE get_stack_tail(VALUE stack, long len); +static void cut_stack_tail(VALUE stack, long len); + +static VALUE +get_stack_tail(VALUE stack, long len) +{ + if (len < 0) return Qnil; /* system error */ + if (len > RARRAY_LEN(stack)) len = RARRAY_LEN(stack); + return rb_ary_subseq(stack, RARRAY_LEN(stack) - len, len); +} + +static void +cut_stack_tail(VALUE stack, long len) +{ + while (len > 0) { + rb_ary_pop(stack); + len--; + } +} + +#define STACK_INIT_LEN 64 +#define NEW_STACK() rb_ary_new2(STACK_INIT_LEN) +#define PUSH(s, i) rb_ary_store(s, RARRAY_LEN(s), i) +#define POP(s) rb_ary_pop(s) +#define LAST_I(s) \ + ((RARRAY_LEN(s) > 0) ? rb_ary_entry(s, RARRAY_LEN(s) - 1) : Qnil) +#define GET_TAIL(s, len) get_stack_tail(s, len) +#define CUT_TAIL(s, len) cut_stack_tail(s, len) + +/* ----------------------------------------------------------------------- + struct cparse_params +----------------------------------------------------------------------- */ + +struct cparse_params { + VALUE value_v; /* VALUE version of this struct */ + + VALUE parser; /* parser object */ + + int lex_is_iterator; + VALUE lexer; /* scanner object */ + ID lexmid; /* name of scanner method (must be an iterator) */ + + /* State transition tables (immutable) + Data structure is from Dragon Book 4.9 */ + /* action table */ + VALUE action_table; + VALUE action_check; + VALUE action_default; + VALUE action_pointer; + /* goto table */ + VALUE goto_table; + VALUE goto_check; + VALUE goto_default; + VALUE goto_pointer; + + long nt_base; /* NonTerminal BASE index */ + VALUE reduce_table; /* reduce data table */ + VALUE token_table; /* token conversion table */ + + /* parser stacks and parameters */ + VALUE state; + long curstate; + VALUE vstack; + VALUE tstack; + VALUE t; + long shift_n; + long reduce_n; + long ruleno; + + long errstatus; /* nonzero in error recovering mode */ + long nerr; /* number of error */ + + int use_result_var; + + VALUE retval; /* return value of parser routine */ + long fin; /* parse result status */ +#define CP_FIN_ACCEPT 1 +#define CP_FIN_EOT 2 +#define CP_FIN_CANTPOP 3 + + int debug; /* user level debug */ + int sys_debug; /* system level debug */ + + long i; /* table index */ +}; + +/* ----------------------------------------------------------------------- + Parser Main Routines +----------------------------------------------------------------------- */ + +static VALUE racc_cparse(VALUE parser, VALUE arg, VALUE sysdebug); +static VALUE racc_yyparse(VALUE parser, VALUE lexer, VALUE lexmid, + VALUE arg, VALUE sysdebug); + +static void call_lexer(struct cparse_params *v); +static VALUE lexer_i(RB_BLOCK_CALL_FUNC_ARGLIST(block_args, data)); + +static VALUE assert_array(VALUE a); +static long assert_integer(VALUE n); +static VALUE assert_hash(VALUE h); +static VALUE initialize_params(VALUE vparams, VALUE parser, VALUE arg, + VALUE lexer, VALUE lexmid); +static void cparse_params_mark(void *ptr); +static size_t cparse_params_memsize(const void *ptr); + +static void parse_main(struct cparse_params *v, + VALUE tok, VALUE val, int resume); +static void extract_user_token(struct cparse_params *v, + VALUE block_args, VALUE *tok, VALUE *val); +static void shift(struct cparse_params* v, long act, VALUE tok, VALUE val); +static int reduce(struct cparse_params* v, long act); +static rb_block_call_func reduce0; + +#ifdef DEBUG +# define D_puts(msg) if (v->sys_debug) puts(msg) +# define D_printf(fmt,arg) if (v->sys_debug) printf(fmt,arg) +#else +# define D_puts(msg) +# define D_printf(fmt,arg) +#endif + +#undef RUBY_UNTYPED_DATA_WARNING +#define RUBY_UNTYPED_DATA_WARNING 1 + +static const rb_data_type_t cparse_params_type = { + "racc/cparse", + { + cparse_params_mark, + RUBY_TYPED_DEFAULT_FREE, + cparse_params_memsize, + }, +#ifdef RUBY_TYPED_FREE_IMMEDIATELY + 0, 0, + RUBY_TYPED_FREE_IMMEDIATELY, +#endif +}; + +static VALUE +racc_cparse(VALUE parser, VALUE arg, VALUE sysdebug) +{ + VALUE vparams; + struct cparse_params *v; + + vparams = TypedData_Make_Struct(CparseParams, struct cparse_params, + &cparse_params_type, v); + D_puts("starting cparse"); + v->sys_debug = RTEST(sysdebug); + vparams = initialize_params(vparams, parser, arg, Qnil, Qnil); + v->lex_is_iterator = FALSE; + parse_main(v, Qnil, Qnil, 0); + + RB_GC_GUARD(vparams); + return v->retval; +} + +static VALUE +racc_yyparse(VALUE parser, VALUE lexer, VALUE lexmid, VALUE arg, VALUE sysdebug) +{ + VALUE vparams; + struct cparse_params *v; + + vparams = TypedData_Make_Struct(CparseParams, struct cparse_params, + &cparse_params_type, v); + v->sys_debug = RTEST(sysdebug); + D_puts("start C yyparse"); + vparams = initialize_params(vparams, parser, arg, lexer, lexmid); + v->lex_is_iterator = TRUE; + D_puts("params initialized"); + parse_main(v, Qnil, Qnil, 0); + call_lexer(v); + if (!v->fin) { + rb_raise(rb_eArgError, "%s() is finished before EndOfToken", + rb_id2name(v->lexmid)); + } + + RB_GC_GUARD(vparams); + return v->retval; +} + +static void +call_lexer(struct cparse_params *v) +{ + rb_block_call(v->lexer, v->lexmid, 0, NULL, lexer_i, v->value_v); +} + +static VALUE +lexer_i(RB_BLOCK_CALL_FUNC_ARGLIST(block_args, data)) +{ + struct cparse_params *v = rb_check_typeddata(data, &cparse_params_type); + VALUE tok, val; + + if (v->fin) + rb_raise(rb_eArgError, "extra token after EndOfToken"); + extract_user_token(v, block_args, &tok, &val); + parse_main(v, tok, val, 1); + if (v->fin && v->fin != CP_FIN_ACCEPT) + rb_iter_break(); + return Qnil; +} + +static VALUE +assert_array(VALUE a) +{ + Check_Type(a, T_ARRAY); + return a; +} + +static VALUE +assert_hash(VALUE h) +{ + Check_Type(h, T_HASH); + return h; +} + +static long +assert_integer(VALUE n) +{ + return NUM2LONG(n); +} + +static VALUE +initialize_params(VALUE vparams, VALUE parser, VALUE arg, VALUE lexer, VALUE lexmid) +{ + struct cparse_params *v = rb_check_typeddata(vparams, &cparse_params_type); + + v->value_v = vparams; + v->parser = parser; + v->lexer = lexer; + if (! NIL_P(lexmid)) + v->lexmid = value_to_id(lexmid); + + v->debug = RTEST(rb_ivar_get(parser, id_yydebug)); + + Check_Type(arg, T_ARRAY); + if (!(13 <= RARRAY_LEN(arg) && RARRAY_LEN(arg) <= 14)) + rb_raise(RaccBug, "[Racc Bug] wrong arg.size %ld", RARRAY_LEN(arg)); + v->action_table = assert_array (rb_ary_entry(arg, 0)); + v->action_check = assert_array (rb_ary_entry(arg, 1)); + v->action_default = assert_array (rb_ary_entry(arg, 2)); + v->action_pointer = assert_array (rb_ary_entry(arg, 3)); + v->goto_table = assert_array (rb_ary_entry(arg, 4)); + v->goto_check = assert_array (rb_ary_entry(arg, 5)); + v->goto_default = assert_array (rb_ary_entry(arg, 6)); + v->goto_pointer = assert_array (rb_ary_entry(arg, 7)); + v->nt_base = assert_integer(rb_ary_entry(arg, 8)); + v->reduce_table = assert_array (rb_ary_entry(arg, 9)); + v->token_table = assert_hash (rb_ary_entry(arg, 10)); + v->shift_n = assert_integer(rb_ary_entry(arg, 11)); + v->reduce_n = assert_integer(rb_ary_entry(arg, 12)); + if (RARRAY_LEN(arg) > 13) { + v->use_result_var = RTEST(rb_ary_entry(arg, 13)); + } + else { + v->use_result_var = TRUE; + } + + v->tstack = v->debug ? NEW_STACK() : Qnil; + v->vstack = NEW_STACK(); + v->state = NEW_STACK(); + v->curstate = 0; + PUSH(v->state, INT2FIX(0)); + v->t = INT2FIX(FINAL_TOKEN + 1); /* must not init to FINAL_TOKEN */ + v->nerr = 0; + v->errstatus = 0; + rb_ivar_set(parser, id_errstatus, LONG2NUM(v->errstatus)); + + v->retval = Qnil; + v->fin = 0; + + v->lex_is_iterator = FALSE; + + rb_iv_set(parser, "@vstack", v->vstack); + if (v->debug) { + rb_iv_set(parser, "@tstack", v->tstack); + } + else { + rb_iv_set(parser, "@tstack", Qnil); + } + + return vparams; +} + +static void +cparse_params_mark(void *ptr) +{ + struct cparse_params *v = (struct cparse_params*)ptr; + + rb_gc_mark(v->value_v); + rb_gc_mark(v->parser); + rb_gc_mark(v->lexer); + rb_gc_mark(v->action_table); + rb_gc_mark(v->action_check); + rb_gc_mark(v->action_default); + rb_gc_mark(v->action_pointer); + rb_gc_mark(v->goto_table); + rb_gc_mark(v->goto_check); + rb_gc_mark(v->goto_default); + rb_gc_mark(v->goto_pointer); + rb_gc_mark(v->reduce_table); + rb_gc_mark(v->token_table); + rb_gc_mark(v->state); + rb_gc_mark(v->vstack); + rb_gc_mark(v->tstack); + rb_gc_mark(v->t); + rb_gc_mark(v->retval); +} + +static size_t +cparse_params_memsize(const void *ptr) +{ + return sizeof(struct cparse_params); +} + +static void +extract_user_token(struct cparse_params *v, VALUE block_args, + VALUE *tok, VALUE *val) +{ + if (NIL_P(block_args)) { + /* EOF */ + *tok = Qfalse; + *val = rb_str_new("$", 1); + return; + } + + if (!RB_TYPE_P(block_args, T_ARRAY)) { + rb_raise(rb_eTypeError, + "%s() %s %"PRIsVALUE" (must be Array[2])", + v->lex_is_iterator ? rb_id2name(v->lexmid) : "next_token", + v->lex_is_iterator ? "yielded" : "returned", + rb_obj_class(block_args)); + } + if (RARRAY_LEN(block_args) != 2) { + rb_raise(rb_eArgError, + "%s() %s wrong size of array (%ld for 2)", + v->lex_is_iterator ? rb_id2name(v->lexmid) : "next_token", + v->lex_is_iterator ? "yielded" : "returned", + RARRAY_LEN(block_args)); + } + *tok = AREF(block_args, 0); + *val = AREF(block_args, 1); +} + +#define SHIFT(v,act,tok,val) shift(v,act,tok,val) +#define REDUCE(v,act) do {\ + switch (reduce(v,act)) { \ + case 0: /* normal */ \ + break; \ + case 1: /* yyerror */ \ + goto user_yyerror; \ + case 2: /* yyaccept */ \ + D_puts("u accept"); \ + goto accept; \ + default: \ + break; \ + } \ +} while (0) + +static void +parse_main(struct cparse_params *v, VALUE tok, VALUE val, int resume) +{ + long i; /* table index */ + long act; /* action type */ + VALUE act_value; /* action type, VALUE version */ + int read_next = 1; /* true if we need to read next token */ + VALUE tmp; + + if (resume) + goto resume; + + while (1) { + D_puts(""); + D_puts("---- enter new loop ----"); + D_puts(""); + + D_printf("(act) k1=%ld\n", v->curstate); + tmp = AREF(v->action_pointer, v->curstate); + if (NIL_P(tmp)) goto notfound; + D_puts("(act) pointer[k1] ok"); + i = NUM2LONG(tmp); + + D_printf("read_next=%d\n", read_next); + if (read_next && (v->t != vFINAL_TOKEN)) { + if (v->lex_is_iterator) { + D_puts("resuming..."); + if (v->fin) rb_raise(rb_eArgError, "token given after EOF"); + v->i = i; /* save i */ + return; + resume: + D_puts("resumed"); + i = v->i; /* load i */ + } + else { + D_puts("next_token"); + tmp = rb_funcall(v->parser, id_nexttoken, 0); + extract_user_token(v, tmp, &tok, &val); + } + /* convert token */ + v->t = rb_hash_aref(v->token_table, tok); + if (NIL_P(v->t)) { + v->t = vERROR_TOKEN; + } + D_printf("(act) t(k2)=%ld\n", NUM2LONG(v->t)); + if (v->debug) { + rb_funcall(v->parser, id_d_read_token, + 3, v->t, tok, val); + } + } + read_next = 0; + + i += NUM2LONG(v->t); + D_printf("(act) i=%ld\n", i); + if (i < 0) goto notfound; + + act_value = AREF(v->action_table, i); + if (NIL_P(act_value)) goto notfound; + act = NUM2LONG(act_value); + D_printf("(act) table[i]=%ld\n", act); + + tmp = AREF(v->action_check, i); + if (NIL_P(tmp)) goto notfound; + if (NUM2LONG(tmp) != v->curstate) goto notfound; + D_printf("(act) check[i]=%ld\n", NUM2LONG(tmp)); + + D_puts("(act) found"); + act_fixed: + D_printf("act=%ld\n", act); + goto handle_act; + + notfound: + D_puts("(act) not found: use default"); + act_value = AREF(v->action_default, v->curstate); + act = NUM2LONG(act_value); + goto act_fixed; + + + handle_act: + if (act > 0 && act < v->shift_n) { + D_puts("shift"); + if (v->errstatus > 0) { + v->errstatus--; + rb_ivar_set(v->parser, id_errstatus, LONG2NUM(v->errstatus)); + } + SHIFT(v, act, v->t, val); + read_next = 1; + } + else if (act < 0 && act > -(v->reduce_n)) { + D_puts("reduce"); + REDUCE(v, act); + } + else if (act == -(v->reduce_n)) { + goto error; + error_recovered: + ; /* goto label requires stmt */ + } + else if (act == v->shift_n) { + D_puts("accept"); + goto accept; + } + else { + rb_raise(RaccBug, "[Racc Bug] unknown act value %ld", act); + } + + if (v->debug) { + rb_funcall(v->parser, id_d_next_state, + 2, LONG2NUM(v->curstate), v->state); + } + } + /* not reach */ + + + accept: + if (v->debug) rb_funcall(v->parser, id_d_accept, 0); + v->retval = rb_ary_entry(v->vstack, 0); + v->fin = CP_FIN_ACCEPT; + return; + + + error: + D_printf("error detected, status=%ld\n", v->errstatus); + if (v->errstatus == 0) { + v->nerr++; + rb_funcall(v->parser, id_onerror, + 3, v->t, val, v->vstack); + } + user_yyerror: + if (v->errstatus == 3) { + if (v->t == vFINAL_TOKEN) { + v->retval = Qnil; + v->fin = CP_FIN_EOT; + return; + } + read_next = 1; + } + v->errstatus = 3; + rb_ivar_set(v->parser, id_errstatus, LONG2NUM(v->errstatus)); + + /* check if we can shift/reduce error token */ + D_printf("(err) k1=%ld\n", v->curstate); + D_printf("(err) k2=%d (error)\n", ERROR_TOKEN); + while (1) { + tmp = AREF(v->action_pointer, v->curstate); + if (NIL_P(tmp)) goto error_pop; + D_puts("(err) pointer[k1] ok"); + + i = NUM2LONG(tmp) + ERROR_TOKEN; + D_printf("(err) i=%ld\n", i); + if (i < 0) goto error_pop; + + act_value = AREF(v->action_table, i); + if (NIL_P(act_value)) { + D_puts("(err) table[i] == nil"); + goto error_pop; + } + act = NUM2LONG(act_value); + D_printf("(err) table[i]=%ld\n", act); + + tmp = AREF(v->action_check, i); + if (NIL_P(tmp)) { + D_puts("(err) check[i] == nil"); + goto error_pop; + } + if (NUM2LONG(tmp) != v->curstate) { + D_puts("(err) check[i] != k1"); + goto error_pop; + } + + D_puts("(err) found: can handle error token"); + break; + + error_pop: + D_puts("(err) act not found: can't handle error token; pop"); + + if (RARRAY_LEN(v->state) <= 1) { + v->retval = Qnil; + v->fin = CP_FIN_CANTPOP; + return; + } + POP(v->state); + POP(v->vstack); + v->curstate = num_to_long(LAST_I(v->state)); + if (v->debug) { + POP(v->tstack); + rb_funcall(v->parser, id_d_e_pop, + 3, v->state, v->tstack, v->vstack); + } + } + + /* shift/reduce error token */ + if (act > 0 && act < v->shift_n) { + D_puts("e shift"); + SHIFT(v, act, ERROR_TOKEN, val); + } + else if (act < 0 && act > -(v->reduce_n)) { + D_puts("e reduce"); + REDUCE(v, act); + } + else if (act == v->shift_n) { + D_puts("e accept"); + goto accept; + } + else { + rb_raise(RaccBug, "[Racc Bug] unknown act value %ld", act); + } + goto error_recovered; +} + +static void +shift(struct cparse_params *v, long act, VALUE tok, VALUE val) +{ + PUSH(v->vstack, val); + if (v->debug) { + PUSH(v->tstack, tok); + rb_funcall(v->parser, id_d_shift, + 3, tok, v->tstack, v->vstack); + } + v->curstate = act; + PUSH(v->state, LONG2NUM(v->curstate)); +} + +static int +reduce(struct cparse_params *v, long act) +{ + VALUE code; + v->ruleno = -act * 3; + code = rb_catch("racc_jump", reduce0, v->value_v); + v->errstatus = num_to_long(rb_ivar_get(v->parser, id_errstatus)); + return NUM2INT(code); +} + +static VALUE +reduce0(RB_BLOCK_CALL_FUNC_ARGLIST(_, data)) +{ + struct cparse_params *v = rb_check_typeddata(data, &cparse_params_type); + VALUE reduce_to, reduce_len, method_id; + long len; + ID mid; + VALUE tmp, tmp_t = Qundef, tmp_v = Qundef; + long i, k1, k2; + VALUE goto_state; + + reduce_len = rb_ary_entry(v->reduce_table, v->ruleno); + reduce_to = rb_ary_entry(v->reduce_table, v->ruleno+1); + method_id = rb_ary_entry(v->reduce_table, v->ruleno+2); + len = NUM2LONG(reduce_len); + mid = value_to_id(method_id); + + /* call action */ + if (len == 0) { + tmp = Qnil; + if (mid != id_noreduce) + tmp_v = rb_ary_new(); + if (v->debug) + tmp_t = rb_ary_new(); + } + else { + if (mid != id_noreduce) { + tmp_v = GET_TAIL(v->vstack, len); + tmp = rb_ary_entry(tmp_v, 0); + } + else { + tmp = rb_ary_entry(v->vstack, RARRAY_LEN(v->vstack) - len); + } + CUT_TAIL(v->vstack, len); + if (v->debug) { + tmp_t = GET_TAIL(v->tstack, len); + CUT_TAIL(v->tstack, len); + } + CUT_TAIL(v->state, len); + } + if (mid != id_noreduce) { + if (v->use_result_var) { + tmp = rb_funcall(v->parser, mid, + 3, tmp_v, v->vstack, tmp); + } + else { + tmp = rb_funcall(v->parser, mid, + 2, tmp_v, v->vstack); + } + } + + /* then push result */ + PUSH(v->vstack, tmp); + if (v->debug) { + PUSH(v->tstack, reduce_to); + rb_funcall(v->parser, id_d_reduce, + 4, tmp_t, reduce_to, v->tstack, v->vstack); + } + + /* calculate transition state */ + if (RARRAY_LEN(v->state) == 0) + rb_raise(RaccBug, "state stack unexpectedly empty"); + k2 = num_to_long(LAST_I(v->state)); + k1 = num_to_long(reduce_to) - v->nt_base; + D_printf("(goto) k1=%ld\n", k1); + D_printf("(goto) k2=%ld\n", k2); + + tmp = AREF(v->goto_pointer, k1); + if (NIL_P(tmp)) goto notfound; + + i = NUM2LONG(tmp) + k2; + D_printf("(goto) i=%ld\n", i); + if (i < 0) goto notfound; + + goto_state = AREF(v->goto_table, i); + if (NIL_P(goto_state)) { + D_puts("(goto) table[i] == nil"); + goto notfound; + } + D_printf("(goto) table[i]=%ld (goto_state)\n", NUM2LONG(goto_state)); + + tmp = AREF(v->goto_check, i); + if (NIL_P(tmp)) { + D_puts("(goto) check[i] == nil"); + goto notfound; + } + if (tmp != LONG2NUM(k1)) { + D_puts("(goto) check[i] != table[i]"); + goto notfound; + } + D_printf("(goto) check[i]=%ld\n", NUM2LONG(tmp)); + + D_puts("(goto) found"); + transit: + PUSH(v->state, goto_state); + v->curstate = NUM2LONG(goto_state); + return INT2FIX(0); + + notfound: + D_puts("(goto) not found: use default"); + /* overwrite `goto-state' by default value */ + goto_state = AREF(v->goto_default, k1); + goto transit; +} + +/* ----------------------------------------------------------------------- + Ruby Interface +----------------------------------------------------------------------- */ + +void +Init_cparse(void) +{ +#ifdef HAVE_RB_EXT_RACTOR_SAFE + rb_ext_ractor_safe(true); +#endif + + VALUE Racc, Parser; + ID id_racc = rb_intern_const("Racc"); + + if (rb_const_defined(rb_cObject, id_racc)) { + Racc = rb_const_get(rb_cObject, id_racc); + Parser = rb_const_get_at(Racc, rb_intern_const("Parser")); + } + else { + Racc = rb_define_module("Racc"); + Parser = rb_define_class_under(Racc, "Parser", rb_cObject); + } + rb_define_private_method(Parser, "_racc_do_parse_c", racc_cparse, 2); + rb_define_private_method(Parser, "_racc_yyparse_c", racc_yyparse, 4); + rb_define_const(Parser, "Racc_Runtime_Core_Version_C", + rb_str_new2(RACC_VERSION)); + rb_define_const(Parser, "Racc_Runtime_Core_Id_C", + rb_str_new2("$originalId: cparse.c,v 1.8 2006/07/06 11:39:46 aamine Exp $")); + + CparseParams = rb_define_class_under(Racc, "CparseParams", rb_cObject); + rb_undef_alloc_func(CparseParams); + rb_undef_method(CparseParams, "initialize"); + rb_undef_method(CparseParams, "initialize_copy"); + + RaccBug = rb_eRuntimeError; + + id_yydebug = rb_intern_const("@yydebug"); + id_nexttoken = rb_intern_const("next_token"); + id_onerror = rb_intern_const("on_error"); + id_noreduce = rb_intern_const("_reduce_none"); + id_errstatus = rb_intern_const("@racc_error_status"); + + id_d_shift = rb_intern_const("racc_shift"); + id_d_reduce = rb_intern_const("racc_reduce"); + id_d_accept = rb_intern_const("racc_accept"); + id_d_read_token = rb_intern_const("racc_read_token"); + id_d_next_state = rb_intern_const("racc_next_state"); + id_d_e_pop = rb_intern_const("racc_e_pop"); +} diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/ext/racc/cparse/extconf.rb b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/ext/racc/cparse/extconf.rb new file mode 100644 index 00000000..ffec1f9d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/ext/racc/cparse/extconf.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true +# + +require 'mkmf' +require_relative '../../../lib/racc/info' + +$defs << "-D""RACC_INFO_VERSION=#{Racc::VERSION}" +create_makefile 'racc/cparse' diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc.rb b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc.rb new file mode 100644 index 00000000..02aa65ac --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc.rb @@ -0,0 +1,6 @@ +require_relative 'racc/compat' +require_relative 'racc/debugflags' +require_relative 'racc/grammar' +require_relative 'racc/state' +require_relative 'racc/exception' +require_relative 'racc/info' diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/compat.rb b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/compat.rb new file mode 100644 index 00000000..62f4f630 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/compat.rb @@ -0,0 +1,33 @@ +#-- +# +# +# +# Copyright (c) 1999-2006 Minero Aoki +# +# This program is free software. +# You can distribute/modify this program under the same terms of ruby. +# see the file "COPYING". +# +#++ + +unless Object.method_defined?(:__send) + class Object + alias __send __send__ + end +end + +unless Object.method_defined?(:__send!) + class Object + alias __send! __send__ + end +end + +unless Array.method_defined?(:map!) + class Array + if Array.method_defined?(:collect!) + alias map! collect! + else + alias map! filter + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/cparse.so b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/cparse.so new file mode 100755 index 00000000..e8af7b39 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/cparse.so differ diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/debugflags.rb b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/debugflags.rb new file mode 100644 index 00000000..ee34cf23 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/debugflags.rb @@ -0,0 +1,60 @@ +#-- +# +# +# +# Copyright (c) 1999-2006 Minero Aoki +# +# This program is free software. +# You can distribute/modify this program under the same terms of ruby. +# see the file "COPYING". +# +#++ + +module Racc + + class DebugFlags + def DebugFlags.parse_option_string(s) + parse = rule = token = state = la = prec = conf = false + s.split(//).each do |ch| + case ch + when 'p' then parse = true + when 'r' then rule = true + when 't' then token = true + when 's' then state = true + when 'l' then la = true + when 'c' then prec = true + when 'o' then conf = true + else + raise "unknown debug flag char: #{ch.inspect}" + end + end + new(parse, rule, token, state, la, prec, conf) + end + + def initialize(parse = false, rule = false, token = false, state = false, + la = false, prec = false, conf = false) + @parse = parse + @rule = rule + @token = token + @state = state + @la = la + @prec = prec + @any = (parse || rule || token || state || la || prec) + @status_logging = conf + end + + attr_reader :parse + attr_reader :rule + attr_reader :token + attr_reader :state + attr_reader :la + attr_reader :prec + + def any? + @any + end + + attr_reader :status_logging + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/exception.rb b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/exception.rb new file mode 100644 index 00000000..c11dc2e4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/exception.rb @@ -0,0 +1,16 @@ +#-- +# +# +# +# Copyright (c) 1999-2006 Minero Aoki +# +# This program is free software. +# You can distribute/modify this program under the same terms of ruby. +# see the file "COPYING". +# +#++ + +module Racc + class Error < StandardError; end + class CompileError < Error; end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/grammar.rb b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/grammar.rb new file mode 100644 index 00000000..2023a9d3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/grammar.rb @@ -0,0 +1,1191 @@ +#-- +# +# +# +# Copyright (c) 1999-2006 Minero Aoki +# +# This program is free software. +# You can distribute/modify this program under the same terms of ruby. +# see the file "COPYING". +# +#++ + +require_relative 'compat' +require_relative 'iset' +require_relative 'sourcetext' +require_relative 'logfilegenerator' +require_relative 'exception' +require 'forwardable' + +module Racc + + class Grammar + + def initialize(debug_flags = DebugFlags.new) + @symboltable = SymbolTable.new + @debug_symbol = debug_flags.token + @rules = [] # :: [Rule] + @start = nil + @n_expected_srconflicts = nil + @error_on_expect_mismatch = nil + @prec_table = [] + @prec_table_closed = false + @closed = false + @states = nil + end + + attr_reader :start + attr_reader :symboltable + attr_accessor :n_expected_srconflicts + attr_accessor :error_on_expect_mismatch + + def [](x) + @rules[x] + end + + def each_rule(&block) + @rules.each(&block) + end + + alias each each_rule + + def each_index(&block) + @rules.each_index(&block) + end + + def each_with_index(&block) + @rules.each_with_index(&block) + end + + def size + @rules.size + end + + def to_s + "" + end + + extend Forwardable + + def_delegator "@symboltable", :each, :each_symbol + def_delegator "@symboltable", :each_terminal + def_delegator "@symboltable", :each_nonterminal + + def intern(value, dummy = false) + @symboltable.intern(value, dummy) + end + + def symbols + @symboltable.symbols + end + + def nonterminal_base + @symboltable.nt_base + end + + def useless_nonterminal_exist? + n_useless_nonterminals() != 0 + end + + def n_useless_nonterminals + @n_useless_nonterminals ||= each_useless_nonterminal.count + end + + def each_useless_nonterminal + return to_enum __method__ unless block_given? + + @symboltable.each_nonterminal do |sym| + yield sym if sym.useless? + end + end + + def useless_rule_exist? + n_useless_rules() != 0 + end + + def n_useless_rules + @n_useless_rules ||= each_useless_rule.count + end + + def each_useless_rule + return to_enum __method__ unless block_given? + + each do |r| + yield r if r.useless? + end + end + + def nfa + (@states ||= States.new(self)).nfa + end + + def dfa + (@states ||= States.new(self)).dfa + end + + alias states dfa + + def state_transition_table + states().state_transition_table + end + + def parser_class + states = states() # cache + if $DEBUG + srcfilename = caller(1).first.slice(/\A(.*?):/, 1) + begin + write_log srcfilename + ".output" + rescue SystemCallError + end + report = lambda {|s| $stderr.puts "racc: #{srcfilename}: #{s}" } + if states.should_report_srconflict? + report["#{states.n_srconflicts} shift/reduce conflicts"] + end + if states.rrconflict_exist? + report["#{states.n_rrconflicts} reduce/reduce conflicts"] + end + g = states.grammar + if g.useless_nonterminal_exist? + report["#{g.n_useless_nonterminals} useless nonterminals"] + end + if g.useless_rule_exist? + report["#{g.n_useless_rules} useless rules"] + end + end + states.state_transition_table.parser_class + end + + def write_log(path) + File.open(path, 'w') {|f| + LogFileGenerator.new(states()).output f + } + end + + # + # Grammar Definition Interface + # + + def add(rule) + raise ArgumentError, "rule added after the Grammar closed" if @closed + @rules.push rule + end + + def added?(sym) + @rules.detect {|r| r.target == sym } + end + + def start_symbol=(s) + raise CompileError, "start symbol set twice'" if @start + @start = s + end + + def declare_precedence(assoc, syms) + raise CompileError, "precedence table defined twice" if @prec_table_closed + @prec_table.push [assoc, syms] + end + + def end_precedence_declaration(reverse) + @prec_table_closed = true + return if @prec_table.empty? + table = reverse ? @prec_table.reverse : @prec_table + table.each_with_index do |(assoc, syms), idx| + syms.each do |sym| + sym.assoc = assoc + sym.precedence = idx + end + end + end + + # + # Dynamic Generation Interface + # + + def Grammar.define(&block) + env = DefinitionEnv.new + env.instance_eval(&block) + env.grammar + end + + class DefinitionEnv + def initialize + @grammar = Grammar.new + @seqs = Hash.new(0) + @delayed = [] + end + + def grammar + flush_delayed + @grammar.each do |rule| + if rule.specified_prec + rule.specified_prec = @grammar.intern(rule.specified_prec) + end + end + @grammar.init + @grammar + end + + def precedence_table(&block) + env = PrecedenceDefinitionEnv.new(@grammar) + env.instance_eval(&block) + @grammar.end_precedence_declaration env.reverse + end + + def method_missing(mid, *args, &block) + unless mid.to_s[-1,1] == '=' + super # raises NoMethodError + end + target = @grammar.intern(mid.to_s.chop.intern) + unless args.size == 1 + raise ArgumentError, "too many arguments for #{mid} (#{args.size} for 1)" + end + _add target, args.first + end + + def _add(target, x) + case x + when Sym + @delayed.each do |rule| + rule.replace x, target if rule.target == x + end + @grammar.symboltable.delete x + else + x.each_rule do |r| + r.target = target + @grammar.add r + end + end + flush_delayed + end + + def _delayed_add(rule) + @delayed.push rule + end + + def _added?(sym) + @grammar.added?(sym) or @delayed.detect {|r| r.target == sym } + end + + def flush_delayed + return if @delayed.empty? + @delayed.each do |rule| + @grammar.add rule + end + @delayed.clear + end + + def seq(*list, &block) + Rule.new(nil, list.map {|x| _intern(x) }, UserAction.proc(block)) + end + + def null(&block) + seq(&block) + end + + def action(&block) + id = "@#{@seqs["action"] += 1}".intern + _delayed_add Rule.new(@grammar.intern(id), [], UserAction.proc(block)) + id + end + + alias _ action + + def option(sym, default = nil, &block) + _defmetasyntax("option", _intern(sym), block) {|target| + seq() { default } | seq(sym) + } + end + + def many(sym, &block) + _defmetasyntax("many", _intern(sym), block) {|target| + seq() { [] }\ + | seq(target, sym) {|list, x| list.push x; list } + } + end + + def many1(sym, &block) + _defmetasyntax("many1", _intern(sym), block) {|target| + seq(sym) {|x| [x] }\ + | seq(target, sym) {|list, x| list.push x; list } + } + end + + def separated_by(sep, sym, &block) + option(separated_by1(sep, sym), [], &block) + end + + def separated_by1(sep, sym, &block) + _defmetasyntax("separated_by1", _intern(sym), block) {|target| + seq(sym) {|x| [x] }\ + | seq(target, sep, sym) {|list, _, x| list.push x; list } + } + end + + def _intern(x) + case x + when Symbol, String + @grammar.intern(x) + when Racc::Sym + x + else + raise TypeError, "wrong type #{x.class} (expected Symbol/String/Racc::Sym)" + end + end + + private + + def _defmetasyntax(type, id, action, &block) + if action + idbase = "#{type}@#{id}-#{@seqs[type] += 1}" + target = _wrap(idbase, "#{idbase}-core", action) + _register("#{idbase}-core", &block) + else + target = _register("#{type}@#{id}", &block) + end + @grammar.intern(target) + end + + def _register(target_name) + target = target_name.intern + unless _added?(@grammar.intern(target)) + yield(target).each_rule do |rule| + rule.target = @grammar.intern(target) + _delayed_add rule + end + end + target + end + + def _wrap(target_name, sym, block) + target = target_name.intern + _delayed_add Rule.new(@grammar.intern(target), + [@grammar.intern(sym.intern)], + UserAction.proc(block)) + target + end + end + + class PrecedenceDefinitionEnv + def initialize(g) + @grammar = g + @prechigh_seen = false + @preclow_seen = false + @reverse = false + end + + attr_reader :reverse + + def higher + if @prechigh_seen + raise CompileError, "prechigh used twice" + end + @prechigh_seen = true + end + + def lower + if @preclow_seen + raise CompileError, "preclow used twice" + end + if @prechigh_seen + @reverse = true + end + @preclow_seen = true + end + + def left(*syms) + @grammar.declare_precedence :Left, syms.map {|s| @grammar.intern(s) } + end + + def right(*syms) + @grammar.declare_precedence :Right, syms.map {|s| @grammar.intern(s) } + end + + def nonassoc(*syms) + @grammar.declare_precedence :Nonassoc, syms.map {|s| @grammar.intern(s)} + end + end + + # + # Computation + # + + def init + return if @closed + @closed = true + @start ||= @rules.map {|r| r.target }.detect {|sym| not sym.dummy? } + raise CompileError, 'no rule in input' if @rules.empty? + add_start_rule + @rules.freeze + fix_ident + compute_hash + compute_heads + determine_terminals + compute_nullable_0 + @symboltable.fix + compute_locate + @symboltable.each_nonterminal {|t| compute_expand t } + compute_nullable + compute_useless + end + + private + + def add_start_rule + r = Rule.new(@symboltable.dummy, + [@start, @symboltable.anchor, @symboltable.anchor], + UserAction.empty) + r.ident = 0 + r.hash = 0 + r.precedence = nil + @rules.unshift r + end + + # Rule#ident + # LocationPointer#ident + def fix_ident + @rules.each_with_index do |rule, idx| + rule.ident = idx + end + end + + # Rule#hash + def compute_hash + hash = 4 # size of dummy rule + @rules.each do |rule| + rule.hash = hash + hash += (rule.size + 1) + end + end + + # Sym#heads + def compute_heads + @rules.each do |rule| + rule.target.heads.push rule.ptrs[0] + end + end + + # Sym#terminal? + def determine_terminals + @symboltable.each do |s| + s.term = s.heads.empty? + end + end + + # Sym#self_null? + def compute_nullable_0 + @symboltable.each do |s| + if s.terminal? + s.snull = false + else + s.snull = s.heads.any? {|loc| loc.reduce? } + end + end + end + + # Sym#locate + def compute_locate + @rules.each do |rule| + t = nil + rule.ptrs.each do |ptr| + unless ptr.reduce? + tok = ptr.dereference + tok.locate.push ptr + t = tok if tok.terminal? + end + end + rule.precedence = t + end + end + + # Sym#expand + def compute_expand(t) + puts "expand> #{t.to_s}" if @debug_symbol + t.expand = _compute_expand(t, ISet.new, []) + puts "expand< #{t.to_s}: #{t.expand.to_s}" if @debug_symbol + end + + def _compute_expand(t, set, lock) + if tmp = t.expand + set.update tmp + return set + end + tok = nil + set.update_a t.heads + t.heads.each do |ptr| + tok = ptr.dereference + if tok and tok.nonterminal? + unless lock[tok.ident] + lock[tok.ident] = true + _compute_expand tok, set, lock + end + end + end + set + end + + # Sym#nullable?, Rule#nullable? + def compute_nullable + @rules.each {|r| r.null = false } + @symboltable.each {|t| t.null = false } + r = @rules.dup + s = @symboltable.nonterminals + begin + rs = r.size + ss = s.size + check_rules_nullable r + check_symbols_nullable s + end until rs == r.size and ss == s.size + end + + def check_rules_nullable(rules) + rules.delete_if do |rule| + rule.null = true + rule.symbols.each do |t| + unless t.nullable? + rule.null = false + break + end + end + rule.nullable? + end + end + + def check_symbols_nullable(symbols) + symbols.delete_if do |sym| + sym.heads.each do |ptr| + if ptr.rule.nullable? + sym.null = true + break + end + end + sym.nullable? + end + end + + # Sym#useless?, Rule#useless? + # FIXME: what means "useless"? + def compute_useless + @symboltable.each_terminal {|sym| sym.useless = false } + @symboltable.each_nonterminal {|sym| sym.useless = true } + @rules.each {|rule| rule.useless = true } + r = @rules.dup + s = @symboltable.nonterminals + begin + rs = r.size + ss = s.size + check_rules_useless r + check_symbols_useless s + end until r.size == rs and s.size == ss + end + + def check_rules_useless(rules) + rules.delete_if do |rule| + rule.useless = false + rule.symbols.each do |sym| + if sym.useless? + rule.useless = true + break + end + end + not rule.useless? + end + end + + def check_symbols_useless(s) + s.delete_if do |t| + t.heads.each do |ptr| + unless ptr.rule.useless? + t.useless = false + break + end + end + not t.useless? + end + end + + end # class Grammar + + + class Rule + + def initialize(target, syms, act) + @target = target + @symbols = syms + @action = act + @alternatives = [] + + @ident = nil + @hash = nil + @ptrs = nil + @precedence = nil + @specified_prec = nil + @null = nil + @useless = nil + end + + attr_accessor :target + attr_reader :symbols + attr_reader :action + + def |(x) + @alternatives.push x.rule + self + end + + def rule + self + end + + def each_rule(&block) + yield self + @alternatives.each(&block) + end + + attr_accessor :ident + + attr_reader :hash + attr_reader :ptrs + + def hash=(n) + @hash = n + ptrs = [] + @symbols.each_with_index do |sym, idx| + ptrs.push LocationPointer.new(self, idx, sym) + end + ptrs.push LocationPointer.new(self, @symbols.size, nil) + @ptrs = ptrs + end + + def precedence + @specified_prec || @precedence + end + + def precedence=(sym) + @precedence ||= sym + end + + def prec(sym, &block) + @specified_prec = sym + if block + unless @action.empty? + raise CompileError, 'both of rule action block and prec block given' + end + @action = UserAction.proc(block) + end + self + end + + attr_accessor :specified_prec + + def nullable?() @null end + def null=(n) @null = n end + + def useless?() @useless end + def useless=(u) @useless = u end + + def inspect + "#" + end + + def ==(other) + other.kind_of?(Rule) and @ident == other.ident + end + + def [](idx) + @symbols[idx] + end + + def size + @symbols.size + end + + def empty? + @symbols.empty? + end + + def to_s + "#" + end + + def accept? + if tok = @symbols[-1] + tok.anchor? + else + false + end + end + + def each(&block) + @symbols.each(&block) + end + + def replace(src, dest) + @target = dest + @symbols = @symbols.map {|s| s == src ? dest : s } + end + + end # class Rule + + + class UserAction + + def UserAction.source_text(src) + new(src, nil) + end + + def UserAction.proc(pr = nil, &block) + if pr and block + raise ArgumentError, "both of argument and block given" + end + new(nil, pr || block) + end + + def UserAction.empty + new(nil, nil) + end + + private_class_method :new + + def initialize(src, proc) + @source = src + @proc = proc + end + + attr_reader :source + attr_reader :proc + + def source? + not @proc + end + + def proc? + not @source + end + + def empty? + not @proc and not @source + end + + def name + "{action type=#{@source || @proc || 'nil'}}" + end + + alias inspect name + + end + + + class OrMark + def initialize(lineno) + @lineno = lineno + end + + def name + '|' + end + + alias inspect name + + attr_reader :lineno + end + + + class OptionMark + def initialize(lineno) + @lineno = lineno + end + + def name + '?' + end + + alias inspect name + + attr_reader :lineno + end + + + class ManyMark + def initialize(lineno) + @lineno = lineno + end + + def name + '*' + end + + alias inspect name + + attr_reader :lineno + end + + + class Many1Mark + def initialize(lineno) + @lineno = lineno + end + + def name + '+' + end + + alias inspect name + + attr_reader :lineno + end + + + class GroupStartMark + def initialize(lineno) + @lineno = lineno + end + + def name + '(' + end + + alias inspect name + + attr_reader :lineno + end + + + class GroupEndMark + def initialize(lineno) + @lineno = lineno + end + + def name + ')' + end + + alias inspect name + + attr_reader :lineno + end + + + class Prec + def initialize(symbol, lineno) + @symbol = symbol + @lineno = lineno + end + + def name + "=#{@symbol}" + end + + alias inspect name + + attr_reader :symbol + attr_reader :lineno + end + + + # + # A set of rule and position in it's RHS. + # Note that the number of pointers is more than rule's RHS array, + # because pointer points right edge of the final symbol when reducing. + # + class LocationPointer + + def initialize(rule, i, sym) + @rule = rule + @index = i + @symbol = sym + @ident = @rule.hash + i + @reduce = sym.nil? + end + + attr_reader :rule + attr_reader :index + attr_reader :symbol + + alias dereference symbol + + attr_reader :ident + alias hash ident + attr_reader :reduce + alias reduce? reduce + + def to_s + sprintf('(%d,%d %s)', + @rule.ident, @index, (reduce?() ? '#' : @symbol.to_s)) + end + + alias inspect to_s + + def eql?(ot) + @hash == ot.hash + end + + alias == eql? + + def head? + @index == 0 + end + + def next + @rule.ptrs[@index + 1] or ptr_bug! + end + + alias increment next + + def before(len) + @rule.ptrs[@index - len] or ptr_bug! + end + + private + + def ptr_bug! + raise "racc: fatal: pointer not exist: self: #{to_s}" + end + + end # class LocationPointer + + + class SymbolTable + + include Enumerable + + def initialize + @symbols = [] # :: [Racc::Sym] + @cache = {} # :: {(String|Symbol) => Racc::Sym} + @dummy = intern(:$start, true) + @anchor = intern(false, true) # Symbol ID = 0 + @error = intern(:error, false) # Symbol ID = 1 + end + + attr_reader :dummy + attr_reader :anchor + attr_reader :error + + def [](id) + @symbols[id] + end + + def intern(val, dummy = false) + @cache[val] ||= + begin + sym = Sym.new(val, dummy) + @symbols.push sym + sym + end + end + + attr_reader :symbols + alias to_a symbols + + def delete(sym) + @symbols.delete sym + @cache.delete sym.value + end + + attr_reader :nt_base + + def nt_max + @symbols.size + end + + def each(&block) + @symbols.each(&block) + end + + def terminals(&block) + @symbols[0, @nt_base] + end + + def each_terminal(&block) + @terms.each(&block) + end + + def nonterminals + @symbols[@nt_base, @symbols.size - @nt_base] + end + + def each_nonterminal(&block) + @nterms.each(&block) + end + + def fix + terms, nterms = @symbols.partition {|s| s.terminal? } + @symbols = terms + nterms + @terms = terms + @nterms = nterms + @nt_base = terms.size + fix_ident + check_terminals + end + + private + + def fix_ident + @symbols.each_with_index do |t, i| + t.ident = i + end + end + + def check_terminals + return unless @symbols.any? {|s| s.should_terminal? } + @anchor.should_terminal + @error.should_terminal + each_terminal do |t| + t.should_terminal if t.string_symbol? + end + each do |s| + s.should_terminal if s.assoc + end + terminals().reject {|t| t.should_terminal? }.each do |t| + raise CompileError, "terminal #{t} not declared as terminal" + end + nonterminals().select {|n| n.should_terminal? }.each do |n| + raise CompileError, "symbol #{n} declared as terminal but is not terminal" + end + end + + end # class SymbolTable + + + # Stands terminal and nonterminal symbols. + class Sym + + def initialize(value, dummyp) + @ident = nil + @value = value + @dummyp = dummyp + + @term = nil + @nterm = nil + @should_terminal = false + @precedence = nil + case value + when Symbol + @to_s = value.to_s + @serialized = value.inspect + @string = false + when String + @to_s = value.inspect + @serialized = value.dump + @string = true + when false + @to_s = '$end' + @serialized = 'false' + @string = false + else + raise ArgumentError, "unknown symbol value: #{value.class}" + end + + @heads = [] + @locate = [] + @snull = nil + @null = nil + @expand = nil + @useless = nil + end + + class << self + def once_writer(nm) + nm = nm.id2name + module_eval(<<-EOS) + def #{nm}=(v) + raise 'racc: fatal: @#{nm} != nil' unless @#{nm}.nil? + @#{nm} = v + end + EOS + end + end + + once_writer :ident + attr_reader :ident + + alias hash ident + + attr_reader :value + + def dummy? + @dummyp + end + + def terminal? + @term + end + + def nonterminal? + @nterm + end + + def term=(t) + raise 'racc: fatal: term= called twice' unless @term.nil? + @term = t + @nterm = !t + end + + def should_terminal + @should_terminal = true + end + + def should_terminal? + @should_terminal + end + + def string_symbol? + @string + end + + def serialize + @serialized + end + + attr_writer :serialized + + attr_accessor :precedence + attr_accessor :assoc + + def to_s + @to_s.dup + end + + alias inspect to_s + + def |(x) + rule() | x.rule + end + + def rule + Rule.new(nil, [self], UserAction.empty) + end + + # + # cache + # + + attr_reader :heads + attr_reader :locate + + def self_null? + @snull + end + + once_writer :snull + + def nullable? + @null + end + + def null=(n) + @null = n + end + + attr_reader :expand + once_writer :expand + + def useless? + @useless + end + + def useless=(f) + @useless = f + end + + end # class Sym + +end # module Racc diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/grammarfileparser.rb b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/grammarfileparser.rb new file mode 100644 index 00000000..69870257 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/grammarfileparser.rb @@ -0,0 +1,667 @@ +#-- +# +# +# +# Copyright (c) 1999-2006 Minero Aoki +# +# This program is free software. +# You can distribute/modify this program under the same terms of ruby. +# see the file "COPYING". +# +#++ + +require_relative '../racc' +require_relative 'compat' +require_relative 'grammar' +require_relative 'parserfilegenerator' +require_relative 'sourcetext' +require 'stringio' + +module Racc + + grammar = Grammar.define { + g = self + + g.class = seq(:CLASS, :cname, many(:param), :RULE, :rules, option(:END)) + + g.cname = seq(:rubyconst) {|name| + @result.params.classname = name + }\ + | seq(:rubyconst, "<", :rubyconst) {|c, _, s| + @result.params.classname = c + @result.params.superclass = s + } + + g.rubyconst = separated_by1(:colon2, :SYMBOL) {|syms| + syms.map {|s| s.to_s }.join('::') + } + + g.colon2 = seq(':', ':') + + g.param = seq(:CONV, many1(:convdef), :END) {|*| + #@grammar.end_convert_block # FIXME + }\ + | seq(:PRECHIGH, many1(:precdef), :PRECLOW) {|*| + @grammar.end_precedence_declaration true + }\ + | seq(:PRECLOW, many1(:precdef), :PRECHIGH) {|*| + @grammar.end_precedence_declaration false + }\ + | seq(:START, :symbol) {|_, sym| + @grammar.start_symbol = sym + }\ + | seq(:TOKEN, :symbols) {|_, syms| + syms.each do |s| + s.should_terminal + end + }\ + | seq(:OPTION, :options) {|_, syms| + syms.each do |opt| + case opt + when 'result_var' + @result.params.result_var = true + when 'no_result_var' + @result.params.result_var = false + when 'omit_action_call' + @result.params.omit_action_call = true + when 'no_omit_action_call' + @result.params.omit_action_call = false + else + raise CompileError, "unknown option: #{opt}" + end + end + }\ + | seq(:EXPECT, :DIGIT) {|_, num| + if @grammar.n_expected_srconflicts + raise CompileError, "`expect' seen twice" + end + @grammar.n_expected_srconflicts = num + }\ + | seq(:ERROR_ON_EXPECT_MISMATCH) {|*| + @grammar.error_on_expect_mismatch = true + } + + g.convdef = seq(:symbol, :STRING) {|sym, code| + sym.serialized = code + } + + g.precdef = seq(:LEFT, :symbols) {|_, syms| + @grammar.declare_precedence :Left, syms + }\ + | seq(:RIGHT, :symbols) {|_, syms| + @grammar.declare_precedence :Right, syms + }\ + | seq(:NONASSOC, :symbols) {|_, syms| + @grammar.declare_precedence :Nonassoc, syms + } + + g.symbols = seq(:symbol) {|sym| + [sym] + }\ + | seq(:symbols, :symbol) {|list, sym| + list.push sym + list + }\ + | seq(:symbols, "|") + + g.symbol = seq(:SYMBOL) {|sym| @grammar.intern(sym) }\ + | seq(:STRING) {|str| @grammar.intern(str) } + + g.options = many(:SYMBOL) {|syms| syms.map {|s| s.to_s } } + + g.rules = option(:rules_core) {|list| + add_rule_block list unless list.empty? + nil + } + + g.rules_core = seq(:symbol) {|sym| + [sym] + }\ + | seq(:rules_core, :rule_item) {|list, i| + list.push i + list + }\ + | seq(:rules_core, ';') {|list, *| + add_rule_block list unless list.empty? + list.clear + list + }\ + | seq(:rules_core, ':') {|list, *| + next_target = list.pop + add_rule_block list unless list.empty? + [next_target] + } + + g.rule_item = seq(:symbol)\ + | seq("|") {|*| + OrMark.new(@scanner.lineno) + }\ + | seq("?") {|*| + OptionMark.new(@scanner.lineno) + }\ + | seq("*") {|*| + ManyMark.new(@scanner.lineno) + }\ + | seq("+") {|*| + Many1Mark.new(@scanner.lineno) + }\ + | seq("(") {|*| + GroupStartMark.new(@scanner.lineno) + }\ + | seq(")") {|*| + GroupEndMark.new(@scanner.lineno) + }\ + | seq("=", :symbol) {|_, sym| + Prec.new(sym, @scanner.lineno) + }\ + | seq(:ACTION) {|src| + UserAction.source_text(src) + } + } + + GrammarFileParser = grammar.parser_class + + if grammar.states.srconflict_exist? + raise 'Racc boot script fatal: S/R conflict in build' + end + if grammar.states.rrconflict_exist? + raise 'Racc boot script fatal: R/R conflict in build' + end + + class GrammarFileParser # reopen + + class Result + def initialize(grammar) + @grammar = grammar + @params = ParserFileGenerator::Params.new + end + + attr_reader :grammar + attr_reader :params + end + + def GrammarFileParser.parse_file(filename) + parse(File.read(filename), filename, 1) + end + + def GrammarFileParser.parse(src, filename = '-', lineno = 1) + new().parse(src, filename, lineno) + end + + def initialize(debug_flags = DebugFlags.new) + @yydebug = debug_flags.parse + end + + def parse(src, filename = '-', lineno = 1) + @filename = filename + @lineno = lineno + @scanner = GrammarFileScanner.new(src, @filename) + @scanner.debug = @yydebug + @grammar = Grammar.new + @result = Result.new(@grammar) + @embedded_action_seq = 0 + yyparse @scanner, :yylex + parse_user_code + @result.grammar.init + @result + end + + private + + def next_token + @scanner.scan + end + + def on_error(tok, val, _values) + if val.respond_to?(:id2name) + v = val.id2name + elsif val.kind_of?(String) + v = val + else + v = val.inspect + end + raise CompileError, "#{location()}: unexpected token '#{v}'" + end + + def location + "#{@filename}:#{@lineno - 1 + @scanner.lineno}" + end + + def add_rule_block(list) + target = list.shift + case target + when OrMark, OptionMark, ManyMark, Many1Mark, GroupStartMark, GroupEndMark, UserAction, Prec + raise CompileError, "#{target.lineno}: unexpected symbol #{target.name}" + end + enum = list.each.with_index + _, sym, idx = _add_rule_block(target, enum) + if idx + # sym is Racc::GroupEndMark + raise "#{sym.lineno}: unexpected symbol ')' at pos=#{idx}" + end + end + + def _add_rule_block(target, enum) + rules = [] # [ [seqs, sprec], .. ] + curr = [] + sprec = nil + while (sym, idx = enum.next rescue nil) + case sym + when OrMark + rules << [curr, sprec] + curr = [] + sprec = nil + when OptionMark + curr << _add_option_rule(curr.pop) + when ManyMark + curr << _add_many_rule(curr.pop) + when Many1Mark + curr << _add_many1_rule(curr.pop) + when GroupStartMark + curr << _add_group_rule(enum) + when GroupEndMark + rules << [curr, sprec] + return rules, sym, idx + when Prec + raise CompileError, "'=' used twice in one rule" if sprec + sprec = sym.symbol + else + curr.push sym + end + end + rules << [curr, sprec] + rules.each do |syms, sprec| + add_rule target, syms, sprec + end + nil + end + + + def _add_option_rule(prev) + @option_rule_registry ||= {} + target = @option_rule_registry[prev.to_s] + return target if target + target = _gen_target_name("option", prev) + @option_rule_registry[prev.to_s] = target + act = UserAction.empty + @grammar.add Rule.new(target, [], act) + @grammar.add Rule.new(target, [prev], act) + target + end + + def _add_many_rule(prev) + @many_rule_registry ||= {} + target = @many_rule_registry[prev.to_s] + return target if target + target = _gen_target_name("many", prev) + @many_rule_registry[prev.to_s] = target + src = SourceText.new("result = val[1] ? val[1].unshift(val[0]) : val", @filename, @scanner.lineno + 1) + act = UserAction.source_text(src) + @grammar.add Rule.new(target, [], act) + @grammar.add Rule.new(target, [prev, target], act) + target + end + + def _add_many1_rule(prev) + @many1_rule_registry ||= {} + target = @many1_rule_registry[prev.to_s] + return target if target + target = _gen_target_name("many1", prev) + @many1_rule_registry[prev.to_s] = target + src = SourceText.new("result = val[1] ? val[1].unshift(val[0]) : val", @filename, @scanner.lineno + 1) + act = UserAction.source_text(src) + @grammar.add Rule.new(target, [prev], act) + @grammar.add Rule.new(target, [prev, target], act) + target + end + + def _add_group_rule(enum) + target = @grammar.intern("-temp-group", true) + rules, _ = _add_rule_block(target, enum) + target_name = rules.map{|syms, sprec| syms.join("-")}.join("|") + @group_rule_registry ||= {} + unless target = @group_rule_registry[target_name] + target = @grammar.intern("-group@#{target_name}", true) + @group_rule_registry[target_name] = target + src = SourceText.new("result = val", @filename, @scanner.lineno + 1) + act = UserAction.source_text(src) + rules.each do |syms, sprec| + rule = Rule.new(target, syms, act) + rule.specified_prec = sprec + @grammar.add rule + end + end + target + end + + def _gen_target_name(type, sym) + @grammar.intern("-#{type}@#{sym.value}", true) + end + + def add_rule(target, list, sprec) + if list.last.kind_of?(UserAction) + act = list.pop + else + act = UserAction.empty + end + list.map! {|s| s.kind_of?(UserAction) ? embedded_action(s) : s } + rule = Rule.new(target, list, act) + rule.specified_prec = sprec + @grammar.add rule + end + + def embedded_action(act) + sym = @grammar.intern("@#{@embedded_action_seq += 1}".intern, true) + @grammar.add Rule.new(sym, [], act) + sym + end + + # + # User Code Block + # + + def parse_user_code + line = @scanner.lineno + _, *blocks = *@scanner.epilogue.split(/^----/) + blocks.each do |block| + header, *body = block.lines.to_a + label0, paths = *header.sub(/\A-+/, '').split('=', 2) + label = canonical_label(label0) + (paths ? paths.strip.split(' ') : []).each do |path| + add_user_code label, SourceText.new(File.read(path), path, 1) + end + add_user_code label, SourceText.new(body.join(''), @filename, line + 1) + line += (1 + body.size) + end + end + + USER_CODE_LABELS = { + 'header' => :header, + 'prepare' => :header, # obsolete + 'inner' => :inner, + 'footer' => :footer, + 'driver' => :footer # obsolete + } + + def canonical_label(src) + label = src.to_s.strip.downcase.slice(/\w+/) + unless USER_CODE_LABELS.key?(label) + raise CompileError, "unknown user code type: #{label.inspect}" + end + label + end + + def add_user_code(label, src) + @result.params.public_send(USER_CODE_LABELS[label]).push src + end + + end + + + class GrammarFileScanner + + def initialize(str, filename = '-') + @lines = str.b.split(/\n|\r\n|\r/) + @filename = filename + @lineno = -1 + @line_head = true + @in_rule_blk = false + @in_conv_blk = false + @in_block = nil + @epilogue = '' + @debug = false + next_line + end + + attr_reader :epilogue + + def lineno + @lineno + 1 + end + + attr_accessor :debug + + def yylex(&block) + unless @debug + yylex0(&block) + else + yylex0 do |sym, tok| + $stderr.printf "%7d %-10s %s\n", lineno(), sym.inspect, tok.inspect + yield [sym, tok] + end + end + end + + private + + def yylex0 + begin + until @line.empty? + @line.sub!(/\A\s+/, '') + if /\A\#/ =~ @line + break + elsif /\A\/\*/ =~ @line + skip_comment + elsif s = reads(/\A[a-zA-Z_]\w*/) + yield [atom_symbol(s), s.intern] + elsif s = reads(/\A\d+/) + yield [:DIGIT, s.to_i] + elsif ch = reads(/\A./) + case ch + when '"', "'" + yield [:STRING, eval(scan_quoted(ch))] + when '{' + lineno = lineno() + yield [:ACTION, SourceText.new(scan_action(), @filename, lineno)] + else + if ch == '|' + @line_head = false + end + yield [ch, ch] + end + else + end + end + end while next_line() + yield nil + end + + def next_line + @lineno += 1 + @line = @lines[@lineno] + if not @line or /\A----/ =~ @line + @epilogue = @lines.join("\n") + @lines.clear + @line = nil + if @in_block + @lineno -= 1 + scan_error! sprintf('unterminated %s', @in_block) + end + false + else + @line.sub!(/(?:\n|\r\n|\r)\z/, '') + @line_head = true + true + end + end + + ReservedWord = { + 'right' => :RIGHT, + 'left' => :LEFT, + 'nonassoc' => :NONASSOC, + 'preclow' => :PRECLOW, + 'prechigh' => :PRECHIGH, + 'token' => :TOKEN, + 'convert' => :CONV, + 'options' => :OPTION, + 'start' => :START, + 'expect' => :EXPECT, + 'error_on_expect_mismatch' => :ERROR_ON_EXPECT_MISMATCH, + 'class' => :CLASS, + 'rule' => :RULE, + 'end' => :END + } + + def atom_symbol(token) + if token == 'end' + symbol = :END + @in_conv_blk = false + @in_rule_blk = false + else + if @line_head and not @in_conv_blk and not @in_rule_blk + symbol = ReservedWord[token] || :SYMBOL + else + symbol = :SYMBOL + end + case symbol + when :RULE then @in_rule_blk = true + when :CONV then @in_conv_blk = true + end + end + @line_head = false + symbol + end + + def skip_comment + @in_block = 'comment' + until m = /\*\//.match(@line) + next_line + end + @line = m.post_match + @in_block = nil + end + + $raccs_print_type = false + + def scan_action + buf = String.new + nest = 1 + pre = nil + @in_block = 'action' + begin + pre = nil + if s = reads(/\A\s+/) + # does not set 'pre' + buf << s + end + until @line.empty? + if s = reads(/\A[^'"`{}%#\/\$]+/) + buf << (pre = s) + next + end + case ch = read(1) + when '{' + nest += 1 + buf << (pre = ch) + when '}' + nest -= 1 + if nest == 0 + @in_block = nil + buf.sub!(/[ \t\f]+\z/, '') + return buf + end + buf << (pre = ch) + when '#' # comment + buf << ch << @line + break + when "'", '"', '`' + buf << (pre = scan_quoted(ch)) + when '%' + if literal_head? pre, @line + # % string, regexp, array + buf << ch + case ch = read(1) + when /[qQx]/n + buf << ch << (pre = scan_quoted(read(1), '%string')) + when /wW/n + buf << ch << (pre = scan_quoted(read(1), '%array')) + when /s/n + buf << ch << (pre = scan_quoted(read(1), '%symbol')) + when /r/n + buf << ch << (pre = scan_quoted(read(1), '%regexp')) + when /[a-zA-Z0-9= ]/n # does not include "_" + scan_error! "unknown type of % literal '%#{ch}'" + else + buf << (pre = scan_quoted(ch, '%string')) + end + else + # operator + buf << '||op->' if $raccs_print_type + buf << (pre = ch) + end + when '/' + if literal_head? pre, @line + # regexp + buf << (pre = scan_quoted(ch, 'regexp')) + else + # operator + buf << '||op->' if $raccs_print_type + buf << (pre = ch) + end + when '$' # gvar + buf << ch << (pre = read(1)) + else + raise 'racc: fatal: must not happen' + end + end + buf << "\n" + end while next_line() + raise 'racc: fatal: scan finished before parser finished' + end + + def literal_head?(pre, post) + (!pre || /[a-zA-Z_0-9]/n !~ pre[-1,1]) && + !post.empty? && /\A[\s\=]/n !~ post + end + + def read(len) + s = @line[0, len] + @line = @line[len .. -1] + s + end + + def reads(re) + m = re.match(@line) or return nil + @line = m.post_match + m[0] + end + + def scan_quoted(left, tag = 'string') + buf = left.dup + buf = "||#{tag}->" + buf if $raccs_print_type + re = get_quoted_re(left) + sv, @in_block = @in_block, tag + begin + if s = reads(re) + buf << s + break + else + buf << @line + end + end while next_line() + @in_block = sv + buf << "<-#{tag}||" if $raccs_print_type + buf + end + + LEFT_TO_RIGHT = { + '(' => ')', + '{' => '}', + '[' => ']', + '<' => '>' + } + + CACHE = {} + + def get_quoted_re(left) + term = Regexp.quote(LEFT_TO_RIGHT[left] || left) + CACHE[left] ||= /\A[^#{term}\\]*(?:\\.[^\\#{term}]*)*#{term}/ + end + + def scan_error!(msg) + raise CompileError, "#{lineno()}: #{msg}" + end + + end + +end # module Racc diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/info.rb b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/info.rb new file mode 100644 index 00000000..79e5817c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/info.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true +#-- +# +# +# +# Copyright (c) 1999-2006 Minero Aoki +# +# This program is free software. +# You can distribute/modify this program under the same terms of ruby. +# see the file "COPYING". +# +#++ + +module Racc + VERSION = '1.8.1' + Version = VERSION + Copyright = 'Copyright (c) 1999-2006 Minero Aoki' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/iset.rb b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/iset.rb new file mode 100644 index 00000000..339221d2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/iset.rb @@ -0,0 +1,92 @@ +#-- +# +# +# +# Copyright (c) 1999-2006 Minero Aoki +# +# This program is free software. +# You can distribute/modify this program under the same terms of ruby. +# see the file "COPYING". +# +#++ + +module Racc + + # An "indexed" set. All items must respond to :ident. + class ISet + + def initialize(a = []) + @set = a + end + + attr_reader :set + + def add(i) + @set[i.ident] = i + end + + def [](key) + @set[key.ident] + end + + def []=(key, val) + @set[key.ident] = val + end + + alias include? [] + alias key? [] + + def update(other) + s = @set + o = other.set + o.each_index do |idx| + if t = o[idx] + s[idx] = t + end + end + end + + def update_a(a) + s = @set + a.each {|i| s[i.ident] = i } + end + + def delete(key) + i = @set[key.ident] + @set[key.ident] = nil + i + end + + def each(&block) + @set.compact.each(&block) + end + + def to_a + @set.compact + end + + def to_s + "[#{@set.compact.join(' ')}]" + end + + alias inspect to_s + + def size + @set.nitems + end + + def empty? + @set.nitems == 0 + end + + def clear + @set.clear + end + + def dup + ISet.new(@set.dup) + end + + end # class ISet + +end # module Racc diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/logfilegenerator.rb b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/logfilegenerator.rb new file mode 100644 index 00000000..2f5aa0c8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/logfilegenerator.rb @@ -0,0 +1,212 @@ +#-- +# +# +# +# Copyright (c) 1999-2006 Minero Aoki +# +# This program is free software. +# You can distribute/modify this program under the same terms of ruby. +# see the file "COPYING". +# +#++ + +module Racc + + class LogFileGenerator + + def initialize(states, debug_flags = DebugFlags.new) + @states = states + @grammar = states.grammar + @debug_flags = debug_flags + end + + def output(out) + output_conflict out; out.puts + output_useless out; out.puts + output_rule out; out.puts + output_token out; out.puts + output_state out + end + + # + # Warnings + # + + def output_conflict(out) + @states.each do |state| + if state.srconf + out.printf "state %d contains %d shift/reduce conflicts\n", + state.stateid, state.srconf.size + end + if state.rrconf + out.printf "state %d contains %d reduce/reduce conflicts\n", + state.stateid, state.rrconf.size + end + end + end + + def output_useless(out) + @grammar.each do |rl| + if rl.useless? + out.printf "rule %d (%s) never reduced\n", + rl.ident, rl.target.to_s + end + end + @grammar.each_nonterminal do |t| + if t.useless? + out.printf "useless nonterminal %s\n", t.to_s + end + end + end + + # + # States + # + + def output_state(out) + out << "--------- State ---------\n" + + showall = @debug_flags.la || @debug_flags.state + @states.each do |state| + out << "\nstate #{state.ident}\n\n" + + (showall ? state.closure : state.core).each do |ptr| + pointer_out(out, ptr) if ptr.rule.ident != 0 or showall + end + out << "\n" + + action_out out, state + end + end + + def pointer_out(out, ptr) + buf = sprintf("%4d) %s :", ptr.rule.ident, ptr.rule.target.to_s) + ptr.rule.symbols.each_with_index do |tok, idx| + buf << ' _' if idx == ptr.index + buf << ' ' << tok.to_s + end + buf << ' _' if ptr.reduce? + out.puts buf + end + + def action_out(f, state) + sr = state.srconf && state.srconf.dup + rr = state.rrconf && state.rrconf.dup + acts = state.action + keys = acts.keys + keys.sort! {|a,b| a.ident <=> b.ident } + + [ Shift, Reduce, Error, Accept ].each do |klass| + keys.delete_if do |tok| + act = acts[tok] + if act.kind_of?(klass) + outact f, tok, act + if sr and c = sr.delete(tok) + outsrconf f, c + end + if rr and c = rr.delete(tok) + outrrconf f, c + end + + true + else + false + end + end + end + sr.each {|tok, c| outsrconf f, c } if sr + rr.each {|tok, c| outrrconf f, c } if rr + + act = state.defact + if not act.kind_of?(Error) or @debug_flags.any? + outact f, '$default', act + end + + f.puts + state.goto_table.each do |t, st| + if t.nonterminal? + f.printf " %-12s go to state %d\n", t.to_s, st.ident + end + end + end + + def outact(f, t, act) + case act + when Shift + f.printf " %-12s shift, and go to state %d\n", + t.to_s, act.goto_id + when Reduce + f.printf " %-12s reduce using rule %d (%s)\n", + t.to_s, act.ruleid, act.rule.target.to_s + when Accept + f.printf " %-12s accept\n", t.to_s + when Error + f.printf " %-12s error\n", t.to_s + else + raise "racc: fatal: wrong act for outact: act=#{act}(#{act.class})" + end + end + + def outsrconf(f, confs) + confs.each do |c| + r = c.reduce + f.printf " %-12s [reduce using rule %d (%s)]\n", + c.shift.to_s, r.ident, r.target.to_s + end + end + + def outrrconf(f, confs) + confs.each do |c| + r = c.low_prec + f.printf " %-12s [reduce using rule %d (%s)]\n", + c.token.to_s, r.ident, r.target.to_s + end + end + + # + # Rules + # + + def output_rule(out) + out.print "-------- Grammar --------\n\n" + @grammar.each do |rl| + if @debug_flags.any? or rl.ident != 0 + out.printf "rule %d %s: %s\n", + rl.ident, rl.target.to_s, rl.symbols.join(' ') + end + end + end + + # + # Tokens + # + + def output_token(out) + out.print "------- Symbols -------\n\n" + + out.print "**Nonterminals, with rules where they appear\n\n" + @grammar.each_nonterminal do |t| + tmp = <filename] [--output-file=filename] +# [-erubypath] [--executable=rubypath] +# [-v] [--verbose] +# [-Ofilename] [--log-file=filename] +# [-g] [--debug] +# [-E] [--embedded] +# [-l] [--no-line-convert] +# [-c] [--line-convert-all] +# [-a] [--no-omit-actions] +# [-C] [--check-only] +# [-S] [--output-status] +# [--version] [--copyright] [--help] grammarfile +# +# [+grammarfile+] +# Racc grammar file. Any extension is permitted. +# [-o+outfile+, --output-file=+outfile+] +# A filename for output. default is <+filename+>.tab.rb +# [-O+filename+, --log-file=+filename+] +# Place logging output in file +filename+. +# Default log file name is <+filename+>.output. +# [-e+rubypath+, --executable=+rubypath+] +# output executable file(mode 755). where +path+ is the Ruby interpreter. +# [-v, --verbose] +# verbose mode. create +filename+.output file, like yacc's y.output file. +# [-g, --debug] +# add debug code to parser class. To display debugging information, +# use this '-g' option and set @yydebug true in parser class. +# [-E, --embedded] +# Output parser which doesn't need runtime files (racc/parser.rb). +# [-F, --frozen] +# Output parser which declares frozen_string_literals: true +# [-C, --check-only] +# Check syntax of racc grammar file and quit. +# [-S, --output-status] +# Print messages time to time while compiling. +# [-l, --no-line-convert] +# turns off line number converting. +# [-c, --line-convert-all] +# Convert line number of actions, inner, header and footer. +# [-a, --no-omit-actions] +# Call all actions, even if an action is empty. +# [--version] +# print Racc version and quit. +# [--copyright] +# Print copyright and quit. +# [--help] +# Print usage and quit. +# +# == Generating Parser Using Racc +# +# To compile Racc grammar file, simply type: +# +# $ racc parse.y +# +# This creates Ruby script file "parse.tab.y". The -o option can change the output filename. +# +# == Writing A Racc Grammar File +# +# If you want your own parser, you have to write a grammar file. +# A grammar file contains the name of your parser class, grammar for the parser, +# user code, and anything else. +# When writing a grammar file, yacc's knowledge is helpful. +# If you have not used yacc before, Racc is not too difficult. +# +# Here's an example Racc grammar file. +# +# class Calcparser +# rule +# target: exp { print val[0] } +# +# exp: exp '+' exp +# | exp '*' exp +# | '(' exp ')' +# | NUMBER +# end +# +# Racc grammar files resemble yacc files. +# But (of course), this is Ruby code. +# yacc's $$ is the 'result', $0, $1... is +# an array called 'val', and $-1, $-2... is an array called '_values'. +# +# See the {Grammar File Reference}[rdoc-ref:lib/racc/rdoc/grammar.en.rdoc] for +# more information on grammar files. +# +# == Parser +# +# Then you must prepare the parse entry method. There are two types of +# parse methods in Racc, Racc::Parser#do_parse and Racc::Parser#yyparse +# +# Racc::Parser#do_parse is simple. +# +# It's yyparse() of yacc, and Racc::Parser#next_token is yylex(). +# This method must returns an array like [TOKENSYMBOL, ITS_VALUE]. +# EOF is [false, false]. +# (TOKENSYMBOL is a Ruby symbol (taken from String#intern) by default. +# If you want to change this, see the grammar reference. +# +# Racc::Parser#yyparse is little complicated, but useful. +# It does not use Racc::Parser#next_token, instead it gets tokens from any iterator. +# +# For example, yyparse(obj, :scan) causes +# calling +obj#scan+, and you can return tokens by yielding them from +obj#scan+. +# +# == Debugging +# +# When debugging, "-v" or/and the "-g" option is helpful. +# +# "-v" creates verbose log file (.output). +# "-g" creates a "Verbose Parser". +# Verbose Parser prints the internal status when parsing. +# But it's _not_ automatic. +# You must use -g option and set +@yydebug+ to +true+ in order to get output. +# -g option only creates the verbose parser. +# +# === Racc reported syntax error. +# +# Isn't there too many "end"? +# grammar of racc file is changed in v0.10. +# +# Racc does not use '%' mark, while yacc uses huge number of '%' marks.. +# +# === Racc reported "XXXX conflicts". +# +# Try "racc -v xxxx.y". +# It causes producing racc's internal log file, xxxx.output. +# +# === Generated parsers does not work correctly +# +# Try "racc -g xxxx.y". +# This command let racc generate "debugging parser". +# Then set @yydebug=true in your parser. +# It produces a working log of your parser. +# +# == Re-distributing Racc runtime +# +# A parser, which is created by Racc, requires the Racc runtime module; +# racc/parser.rb. +# +# Ruby 1.8.x comes with Racc runtime module, +# you need NOT distribute Racc runtime files. +# +# If you want to include the Racc runtime module with your parser. +# This can be done by using '-E' option: +# +# $ racc -E -omyparser.rb myparser.y +# +# This command creates myparser.rb which `includes' Racc runtime. +# Only you must do is to distribute your parser file (myparser.rb). +# +# Note: parser.rb is ruby license, but your parser is not. +# Your own parser is completely yours. +module Racc + + unless defined?(Racc_No_Extensions) + Racc_No_Extensions = false # :nodoc: + end + + class Parser + + Racc_Runtime_Version = ::Racc::VERSION + Racc_Runtime_Core_Version_R = ::Racc::VERSION + + begin + if Object.const_defined?(:RUBY_ENGINE) and RUBY_ENGINE == 'jruby' + require 'jruby' + require 'racc/cparse-jruby.jar' + com.headius.racc.Cparse.new.load(JRuby.runtime, false) + else + require 'racc/cparse' + end + + unless new.respond_to?(:_racc_do_parse_c, true) + raise LoadError, 'old cparse.so' + end + if Racc_No_Extensions + raise LoadError, 'selecting ruby version of racc runtime core' + end + + Racc_Main_Parsing_Routine = :_racc_do_parse_c # :nodoc: + Racc_YY_Parse_Method = :_racc_yyparse_c # :nodoc: + Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_C # :nodoc: + Racc_Runtime_Type = 'c' # :nodoc: + rescue LoadError + Racc_Main_Parsing_Routine = :_racc_do_parse_rb + Racc_YY_Parse_Method = :_racc_yyparse_rb + Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_R + Racc_Runtime_Type = 'ruby' + end + + def Parser.racc_runtime_type # :nodoc: + Racc_Runtime_Type + end + + def _racc_setup + @yydebug = false unless self.class::Racc_debug_parser + @yydebug = false unless defined?(@yydebug) + if @yydebug + @racc_debug_out = $stderr unless defined?(@racc_debug_out) + @racc_debug_out ||= $stderr + end + arg = self.class::Racc_arg + arg[13] = true if arg.size < 14 + arg + end + + def _racc_init_sysvars + @racc_state = [0] + @racc_tstack = [] + @racc_vstack = [] + + @racc_t = nil + @racc_val = nil + + @racc_read_next = true + + @racc_user_yyerror = false + @racc_error_status = 0 + end + + # The entry point of the parser. This method is used with #next_token. + # If Racc wants to get token (and its value), calls next_token. + # + # Example: + # def parse + # @q = [[1,1], + # [2,2], + # [3,3], + # [false, '$']] + # do_parse + # end + # + # def next_token + # @q.shift + # end + class_eval <<~RUBY, __FILE__, __LINE__ + 1 + def do_parse + #{Racc_Main_Parsing_Routine}(_racc_setup(), false) + end + RUBY + + # The method to fetch next token. + # If you use #do_parse method, you must implement #next_token. + # + # The format of return value is [TOKEN_SYMBOL, VALUE]. + # +token-symbol+ is represented by Ruby's symbol by default, e.g. :IDENT + # for 'IDENT'. ";" (String) for ';'. + # + # The final symbol (End of file) must be false. + def next_token + raise NotImplementedError, "#{self.class}\#next_token is not defined" + end + + def _racc_do_parse_rb(arg, in_debug) + action_table, action_check, action_default, action_pointer, + _, _, _, _, + _, _, token_table, * = arg + + _racc_init_sysvars + tok = act = i = nil + + catch(:racc_end_parse) { + while true + if i = action_pointer[@racc_state[-1]] + if @racc_read_next + if @racc_t != 0 # not EOF + tok, @racc_val = next_token() + unless tok # EOF + @racc_t = 0 + else + @racc_t = (token_table[tok] or 1) # error token + end + racc_read_token(@racc_t, tok, @racc_val) if @yydebug + @racc_read_next = false + end + end + i += @racc_t + unless i >= 0 and + act = action_table[i] and + action_check[i] == @racc_state[-1] + act = action_default[@racc_state[-1]] + end + else + act = action_default[@racc_state[-1]] + end + while act = _racc_evalact(act, arg) + ; + end + end + } + end + + # Another entry point for the parser. + # If you use this method, you must implement RECEIVER#METHOD_ID method. + # + # RECEIVER#METHOD_ID is a method to get next token. + # It must 'yield' the token, which format is [TOKEN-SYMBOL, VALUE]. + class_eval <<~RUBY, __FILE__, __LINE__ + 1 + def yyparse(recv, mid) + #{Racc_YY_Parse_Method}(recv, mid, _racc_setup(), false) + end + RUBY + + def _racc_yyparse_rb(recv, mid, arg, c_debug) + action_table, action_check, action_default, action_pointer, + _, _, _, _, + _, _, token_table, * = arg + + _racc_init_sysvars + + catch(:racc_end_parse) { + until i = action_pointer[@racc_state[-1]] + while act = _racc_evalact(action_default[@racc_state[-1]], arg) + ; + end + end + recv.__send__(mid) do |tok, val| + unless tok + @racc_t = 0 + else + @racc_t = (token_table[tok] or 1) # error token + end + @racc_val = val + @racc_read_next = false + + i += @racc_t + unless i >= 0 and + act = action_table[i] and + action_check[i] == @racc_state[-1] + act = action_default[@racc_state[-1]] + end + while act = _racc_evalact(act, arg) + ; + end + + while !(i = action_pointer[@racc_state[-1]]) || + ! @racc_read_next || + @racc_t == 0 # $ + unless i and i += @racc_t and + i >= 0 and + act = action_table[i] and + action_check[i] == @racc_state[-1] + act = action_default[@racc_state[-1]] + end + while act = _racc_evalact(act, arg) + ; + end + end + end + } + end + + ### + ### common + ### + + def _racc_evalact(act, arg) + action_table, action_check, _, action_pointer, + _, _, _, _, + _, _, _, shift_n, + reduce_n, * = arg + nerr = 0 # tmp + + if act > 0 and act < shift_n + # + # shift + # + if @racc_error_status > 0 + @racc_error_status -= 1 unless @racc_t <= 1 # error token or EOF + end + @racc_vstack.push @racc_val + @racc_state.push act + @racc_read_next = true + if @yydebug + @racc_tstack.push @racc_t + racc_shift @racc_t, @racc_tstack, @racc_vstack + end + + elsif act < 0 and act > -reduce_n + # + # reduce + # + code = catch(:racc_jump) { + @racc_state.push _racc_do_reduce(arg, act) + false + } + if code + case code + when 1 # yyerror + @racc_user_yyerror = true # user_yyerror + return -reduce_n + when 2 # yyaccept + return shift_n + else + raise '[Racc Bug] unknown jump code' + end + end + + elsif act == shift_n + # + # accept + # + racc_accept if @yydebug + throw :racc_end_parse, @racc_vstack[0] + + elsif act == -reduce_n + # + # error + # + case @racc_error_status + when 0 + unless arg[21] # user_yyerror + nerr += 1 + on_error @racc_t, @racc_val, @racc_vstack + end + when 3 + if @racc_t == 0 # is $ + # We're at EOF, and another error occurred immediately after + # attempting auto-recovery + throw :racc_end_parse, nil + end + @racc_read_next = true + end + @racc_user_yyerror = false + @racc_error_status = 3 + while true + if i = action_pointer[@racc_state[-1]] + i += 1 # error token + if i >= 0 and + (act = action_table[i]) and + action_check[i] == @racc_state[-1] + break + end + end + throw :racc_end_parse, nil if @racc_state.size <= 1 + @racc_state.pop + @racc_vstack.pop + if @yydebug + @racc_tstack.pop + racc_e_pop @racc_state, @racc_tstack, @racc_vstack + end + end + return act + + else + raise "[Racc Bug] unknown action #{act.inspect}" + end + + racc_next_state(@racc_state[-1], @racc_state) if @yydebug + + nil + end + + def _racc_do_reduce(arg, act) + _, _, _, _, + goto_table, goto_check, goto_default, goto_pointer, + nt_base, reduce_table, _, _, + _, use_result, * = arg + + state = @racc_state + vstack = @racc_vstack + tstack = @racc_tstack + + i = act * -3 + len = reduce_table[i] + reduce_to = reduce_table[i+1] + method_id = reduce_table[i+2] + void_array = [] + + tmp_t = tstack[-len, len] if @yydebug + tmp_v = vstack[-len, len] + tstack[-len, len] = void_array if @yydebug + vstack[-len, len] = void_array + state[-len, len] = void_array + + # tstack must be updated AFTER method call + if use_result + vstack.push __send__(method_id, tmp_v, vstack, tmp_v[0]) + else + vstack.push __send__(method_id, tmp_v, vstack) + end + tstack.push reduce_to + + racc_reduce(tmp_t, reduce_to, tstack, vstack) if @yydebug + + k1 = reduce_to - nt_base + if i = goto_pointer[k1] + i += state[-1] + if i >= 0 and (curstate = goto_table[i]) and goto_check[i] == k1 + return curstate + end + end + goto_default[k1] + end + + # This method is called when a parse error is found. + # + # ERROR_TOKEN_ID is an internal ID of token which caused error. + # You can get string representation of this ID by calling + # #token_to_str. + # + # ERROR_VALUE is a value of error token. + # + # value_stack is a stack of symbol values. + # DO NOT MODIFY this object. + # + # This method raises ParseError by default. + # + # If this method returns, parsers enter "error recovering mode". + def on_error(t, val, vstack) + raise ParseError, sprintf("parse error on value %s (%s)", + val.inspect, token_to_str(t) || '?') + end + + # Enter error recovering mode. + # This method does not call #on_error. + def yyerror + throw :racc_jump, 1 + end + + # Exit parser. + # Return value is +Symbol_Value_Stack[0]+. + def yyaccept + throw :racc_jump, 2 + end + + # Leave error recovering mode. + def yyerrok + @racc_error_status = 0 + end + + # For debugging output + def racc_read_token(t, tok, val) + @racc_debug_out.print 'read ' + @racc_debug_out.print tok.inspect, '(', racc_token2str(t), ') ' + @racc_debug_out.puts val.inspect + @racc_debug_out.puts + end + + def racc_shift(tok, tstack, vstack) + @racc_debug_out.puts "shift #{racc_token2str tok}" + racc_print_stacks tstack, vstack + @racc_debug_out.puts + end + + def racc_reduce(toks, sim, tstack, vstack) + out = @racc_debug_out + out.print 'reduce ' + if toks.empty? + out.print ' ' + else + toks.each {|t| out.print ' ', racc_token2str(t) } + end + out.puts " --> #{racc_token2str(sim)}" + racc_print_stacks tstack, vstack + @racc_debug_out.puts + end + + def racc_accept + @racc_debug_out.puts 'accept' + @racc_debug_out.puts + end + + def racc_e_pop(state, tstack, vstack) + @racc_debug_out.puts 'error recovering mode: pop token' + racc_print_states state + racc_print_stacks tstack, vstack + @racc_debug_out.puts + end + + def racc_next_state(curstate, state) + @racc_debug_out.puts "goto #{curstate}" + racc_print_states state + @racc_debug_out.puts + end + + def racc_print_stacks(t, v) + out = @racc_debug_out + out.print ' [' + t.each_index do |i| + out.print ' (', racc_token2str(t[i]), ' ', v[i].inspect, ')' + end + out.puts ' ]' + end + + def racc_print_states(s) + out = @racc_debug_out + out.print ' [' + s.each {|st| out.print ' ', st } + out.puts ' ]' + end + + def racc_token2str(tok) + self.class::Racc_token_to_s_table[tok] or + raise "[Racc Bug] can't convert token #{tok} to string" + end + + # Convert internal ID of token symbol to the string. + def token_to_str(t) + self.class::Racc_token_to_s_table[t] + end + + end + +end + +__end_of_file__ +end diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/parser.rb b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/parser.rb new file mode 100644 index 00000000..d80dec0f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/parser.rb @@ -0,0 +1,630 @@ +# frozen_string_literal: true +#-- +# Copyright (c) 1999-2006 Minero Aoki +# +# This program is free software. +# You can distribute/modify this program under the same terms of ruby. +# +# As a special exception, when this code is copied by Racc +# into a Racc output file, you may use that output file +# without restriction. +#++ + +require 'racc/info' + +module Racc + class ParseError < StandardError; end +end +unless defined?(::ParseError) + ParseError = Racc::ParseError # :nodoc: +end + +# Racc is an LALR(1) parser generator. +# It is written in Ruby itself, and generates Ruby programs. +# +# == Command-line Reference +# +# racc [-ofilename] [--output-file=filename] +# [-erubypath] [--executable=rubypath] +# [-v] [--verbose] +# [-Ofilename] [--log-file=filename] +# [-g] [--debug] +# [-E] [--embedded] +# [-l] [--no-line-convert] +# [-c] [--line-convert-all] +# [-a] [--no-omit-actions] +# [-C] [--check-only] +# [-S] [--output-status] +# [--version] [--copyright] [--help] grammarfile +# +# [+grammarfile+] +# Racc grammar file. Any extension is permitted. +# [-o+outfile+, --output-file=+outfile+] +# A filename for output. default is <+filename+>.tab.rb +# [-O+filename+, --log-file=+filename+] +# Place logging output in file +filename+. +# Default log file name is <+filename+>.output. +# [-e+rubypath+, --executable=+rubypath+] +# output executable file(mode 755). where +path+ is the Ruby interpreter. +# [-v, --verbose] +# verbose mode. create +filename+.output file, like yacc's y.output file. +# [-g, --debug] +# add debug code to parser class. To display debugging information, +# use this '-g' option and set @yydebug true in parser class. +# [-E, --embedded] +# Output parser which doesn't need runtime files (racc/parser.rb). +# [-F, --frozen] +# Output parser which declares frozen_string_literals: true +# [-C, --check-only] +# Check syntax of racc grammar file and quit. +# [-S, --output-status] +# Print messages time to time while compiling. +# [-l, --no-line-convert] +# turns off line number converting. +# [-c, --line-convert-all] +# Convert line number of actions, inner, header and footer. +# [-a, --no-omit-actions] +# Call all actions, even if an action is empty. +# [--version] +# print Racc version and quit. +# [--copyright] +# Print copyright and quit. +# [--help] +# Print usage and quit. +# +# == Generating Parser Using Racc +# +# To compile Racc grammar file, simply type: +# +# $ racc parse.y +# +# This creates Ruby script file "parse.tab.y". The -o option can change the output filename. +# +# == Writing A Racc Grammar File +# +# If you want your own parser, you have to write a grammar file. +# A grammar file contains the name of your parser class, grammar for the parser, +# user code, and anything else. +# When writing a grammar file, yacc's knowledge is helpful. +# If you have not used yacc before, Racc is not too difficult. +# +# Here's an example Racc grammar file. +# +# class Calcparser +# rule +# target: exp { print val[0] } +# +# exp: exp '+' exp +# | exp '*' exp +# | '(' exp ')' +# | NUMBER +# end +# +# Racc grammar files resemble yacc files. +# But (of course), this is Ruby code. +# yacc's $$ is the 'result', $0, $1... is +# an array called 'val', and $-1, $-2... is an array called '_values'. +# +# See the {Grammar File Reference}[rdoc-ref:lib/racc/rdoc/grammar.en.rdoc] for +# more information on grammar files. +# +# == Parser +# +# Then you must prepare the parse entry method. There are two types of +# parse methods in Racc, Racc::Parser#do_parse and Racc::Parser#yyparse +# +# Racc::Parser#do_parse is simple. +# +# It's yyparse() of yacc, and Racc::Parser#next_token is yylex(). +# This method must returns an array like [TOKENSYMBOL, ITS_VALUE]. +# EOF is [false, false]. +# (TOKENSYMBOL is a Ruby symbol (taken from String#intern) by default. +# If you want to change this, see the grammar reference. +# +# Racc::Parser#yyparse is little complicated, but useful. +# It does not use Racc::Parser#next_token, instead it gets tokens from any iterator. +# +# For example, yyparse(obj, :scan) causes +# calling +obj#scan+, and you can return tokens by yielding them from +obj#scan+. +# +# == Debugging +# +# When debugging, "-v" or/and the "-g" option is helpful. +# +# "-v" creates verbose log file (.output). +# "-g" creates a "Verbose Parser". +# Verbose Parser prints the internal status when parsing. +# But it's _not_ automatic. +# You must use -g option and set +@yydebug+ to +true+ in order to get output. +# -g option only creates the verbose parser. +# +# === Racc reported syntax error. +# +# Isn't there too many "end"? +# grammar of racc file is changed in v0.10. +# +# Racc does not use '%' mark, while yacc uses huge number of '%' marks.. +# +# === Racc reported "XXXX conflicts". +# +# Try "racc -v xxxx.y". +# It causes producing racc's internal log file, xxxx.output. +# +# === Generated parsers does not work correctly +# +# Try "racc -g xxxx.y". +# This command let racc generate "debugging parser". +# Then set @yydebug=true in your parser. +# It produces a working log of your parser. +# +# == Re-distributing Racc runtime +# +# A parser, which is created by Racc, requires the Racc runtime module; +# racc/parser.rb. +# +# Ruby 1.8.x comes with Racc runtime module, +# you need NOT distribute Racc runtime files. +# +# If you want to include the Racc runtime module with your parser. +# This can be done by using '-E' option: +# +# $ racc -E -omyparser.rb myparser.y +# +# This command creates myparser.rb which `includes' Racc runtime. +# Only you must do is to distribute your parser file (myparser.rb). +# +# Note: parser.rb is ruby license, but your parser is not. +# Your own parser is completely yours. +module Racc + + unless defined?(Racc_No_Extensions) + Racc_No_Extensions = false # :nodoc: + end + + class Parser + + Racc_Runtime_Version = ::Racc::VERSION + Racc_Runtime_Core_Version_R = ::Racc::VERSION + + begin + if Object.const_defined?(:RUBY_ENGINE) and RUBY_ENGINE == 'jruby' + require 'jruby' + require 'racc/cparse-jruby.jar' + com.headius.racc.Cparse.new.load(JRuby.runtime, false) + else + require 'racc/cparse' + end + + unless new.respond_to?(:_racc_do_parse_c, true) + raise LoadError, 'old cparse.so' + end + if Racc_No_Extensions + raise LoadError, 'selecting ruby version of racc runtime core' + end + + Racc_Main_Parsing_Routine = :_racc_do_parse_c # :nodoc: + Racc_YY_Parse_Method = :_racc_yyparse_c # :nodoc: + Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_C # :nodoc: + Racc_Runtime_Type = 'c' # :nodoc: + rescue LoadError + Racc_Main_Parsing_Routine = :_racc_do_parse_rb + Racc_YY_Parse_Method = :_racc_yyparse_rb + Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_R + Racc_Runtime_Type = 'ruby' + end + + def Parser.racc_runtime_type # :nodoc: + Racc_Runtime_Type + end + + def _racc_setup + @yydebug = false unless self.class::Racc_debug_parser + @yydebug = false unless defined?(@yydebug) + if @yydebug + @racc_debug_out = $stderr unless defined?(@racc_debug_out) + @racc_debug_out ||= $stderr + end + arg = self.class::Racc_arg + arg[13] = true if arg.size < 14 + arg + end + + def _racc_init_sysvars + @racc_state = [0] + @racc_tstack = [] + @racc_vstack = [] + + @racc_t = nil + @racc_val = nil + + @racc_read_next = true + + @racc_user_yyerror = false + @racc_error_status = 0 + end + + # The entry point of the parser. This method is used with #next_token. + # If Racc wants to get token (and its value), calls next_token. + # + # Example: + # def parse + # @q = [[1,1], + # [2,2], + # [3,3], + # [false, '$']] + # do_parse + # end + # + # def next_token + # @q.shift + # end + class_eval <<~RUBY, __FILE__, __LINE__ + 1 + def do_parse + #{Racc_Main_Parsing_Routine}(_racc_setup(), false) + end + RUBY + + # The method to fetch next token. + # If you use #do_parse method, you must implement #next_token. + # + # The format of return value is [TOKEN_SYMBOL, VALUE]. + # +token-symbol+ is represented by Ruby's symbol by default, e.g. :IDENT + # for 'IDENT'. ";" (String) for ';'. + # + # The final symbol (End of file) must be false. + def next_token + raise NotImplementedError, "#{self.class}\#next_token is not defined" + end + + def _racc_do_parse_rb(arg, in_debug) + action_table, action_check, action_default, action_pointer, + _, _, _, _, + _, _, token_table, * = arg + + _racc_init_sysvars + tok = act = i = nil + + catch(:racc_end_parse) { + while true + if i = action_pointer[@racc_state[-1]] + if @racc_read_next + if @racc_t != 0 # not EOF + tok, @racc_val = next_token() + unless tok # EOF + @racc_t = 0 + else + @racc_t = (token_table[tok] or 1) # error token + end + racc_read_token(@racc_t, tok, @racc_val) if @yydebug + @racc_read_next = false + end + end + i += @racc_t + unless i >= 0 and + act = action_table[i] and + action_check[i] == @racc_state[-1] + act = action_default[@racc_state[-1]] + end + else + act = action_default[@racc_state[-1]] + end + while act = _racc_evalact(act, arg) + ; + end + end + } + end + + # Another entry point for the parser. + # If you use this method, you must implement RECEIVER#METHOD_ID method. + # + # RECEIVER#METHOD_ID is a method to get next token. + # It must 'yield' the token, which format is [TOKEN-SYMBOL, VALUE]. + class_eval <<~RUBY, __FILE__, __LINE__ + 1 + def yyparse(recv, mid) + #{Racc_YY_Parse_Method}(recv, mid, _racc_setup(), false) + end + RUBY + + def _racc_yyparse_rb(recv, mid, arg, c_debug) + action_table, action_check, action_default, action_pointer, + _, _, _, _, + _, _, token_table, * = arg + + _racc_init_sysvars + + catch(:racc_end_parse) { + until i = action_pointer[@racc_state[-1]] + while act = _racc_evalact(action_default[@racc_state[-1]], arg) + ; + end + end + recv.__send__(mid) do |tok, val| + unless tok + @racc_t = 0 + else + @racc_t = (token_table[tok] or 1) # error token + end + @racc_val = val + @racc_read_next = false + + i += @racc_t + unless i >= 0 and + act = action_table[i] and + action_check[i] == @racc_state[-1] + act = action_default[@racc_state[-1]] + end + while act = _racc_evalact(act, arg) + ; + end + + while !(i = action_pointer[@racc_state[-1]]) || + ! @racc_read_next || + @racc_t == 0 # $ + unless i and i += @racc_t and + i >= 0 and + act = action_table[i] and + action_check[i] == @racc_state[-1] + act = action_default[@racc_state[-1]] + end + while act = _racc_evalact(act, arg) + ; + end + end + end + } + end + + ### + ### common + ### + + def _racc_evalact(act, arg) + action_table, action_check, _, action_pointer, + _, _, _, _, + _, _, _, shift_n, + reduce_n, * = arg + nerr = 0 # tmp + + if act > 0 and act < shift_n + # + # shift + # + if @racc_error_status > 0 + @racc_error_status -= 1 unless @racc_t <= 1 # error token or EOF + end + @racc_vstack.push @racc_val + @racc_state.push act + @racc_read_next = true + if @yydebug + @racc_tstack.push @racc_t + racc_shift @racc_t, @racc_tstack, @racc_vstack + end + + elsif act < 0 and act > -reduce_n + # + # reduce + # + code = catch(:racc_jump) { + @racc_state.push _racc_do_reduce(arg, act) + false + } + if code + case code + when 1 # yyerror + @racc_user_yyerror = true # user_yyerror + return -reduce_n + when 2 # yyaccept + return shift_n + else + raise '[Racc Bug] unknown jump code' + end + end + + elsif act == shift_n + # + # accept + # + racc_accept if @yydebug + throw :racc_end_parse, @racc_vstack[0] + + elsif act == -reduce_n + # + # error + # + case @racc_error_status + when 0 + unless arg[21] # user_yyerror + nerr += 1 + on_error @racc_t, @racc_val, @racc_vstack + end + when 3 + if @racc_t == 0 # is $ + # We're at EOF, and another error occurred immediately after + # attempting auto-recovery + throw :racc_end_parse, nil + end + @racc_read_next = true + end + @racc_user_yyerror = false + @racc_error_status = 3 + while true + if i = action_pointer[@racc_state[-1]] + i += 1 # error token + if i >= 0 and + (act = action_table[i]) and + action_check[i] == @racc_state[-1] + break + end + end + throw :racc_end_parse, nil if @racc_state.size <= 1 + @racc_state.pop + @racc_vstack.pop + if @yydebug + @racc_tstack.pop + racc_e_pop @racc_state, @racc_tstack, @racc_vstack + end + end + return act + + else + raise "[Racc Bug] unknown action #{act.inspect}" + end + + racc_next_state(@racc_state[-1], @racc_state) if @yydebug + + nil + end + + def _racc_do_reduce(arg, act) + _, _, _, _, + goto_table, goto_check, goto_default, goto_pointer, + nt_base, reduce_table, _, _, + _, use_result, * = arg + + state = @racc_state + vstack = @racc_vstack + tstack = @racc_tstack + + i = act * -3 + len = reduce_table[i] + reduce_to = reduce_table[i+1] + method_id = reduce_table[i+2] + void_array = [] + + tmp_t = tstack[-len, len] if @yydebug + tmp_v = vstack[-len, len] + tstack[-len, len] = void_array if @yydebug + vstack[-len, len] = void_array + state[-len, len] = void_array + + # tstack must be updated AFTER method call + if use_result + vstack.push __send__(method_id, tmp_v, vstack, tmp_v[0]) + else + vstack.push __send__(method_id, tmp_v, vstack) + end + tstack.push reduce_to + + racc_reduce(tmp_t, reduce_to, tstack, vstack) if @yydebug + + k1 = reduce_to - nt_base + if i = goto_pointer[k1] + i += state[-1] + if i >= 0 and (curstate = goto_table[i]) and goto_check[i] == k1 + return curstate + end + end + goto_default[k1] + end + + # This method is called when a parse error is found. + # + # ERROR_TOKEN_ID is an internal ID of token which caused error. + # You can get string representation of this ID by calling + # #token_to_str. + # + # ERROR_VALUE is a value of error token. + # + # value_stack is a stack of symbol values. + # DO NOT MODIFY this object. + # + # This method raises ParseError by default. + # + # If this method returns, parsers enter "error recovering mode". + def on_error(t, val, vstack) + raise ParseError, sprintf("parse error on value %s (%s)", + val.inspect, token_to_str(t) || '?') + end + + # Enter error recovering mode. + # This method does not call #on_error. + def yyerror + throw :racc_jump, 1 + end + + # Exit parser. + # Return value is +Symbol_Value_Stack[0]+. + def yyaccept + throw :racc_jump, 2 + end + + # Leave error recovering mode. + def yyerrok + @racc_error_status = 0 + end + + # For debugging output + def racc_read_token(t, tok, val) + @racc_debug_out.print 'read ' + @racc_debug_out.print tok.inspect, '(', racc_token2str(t), ') ' + @racc_debug_out.puts val.inspect + @racc_debug_out.puts + end + + def racc_shift(tok, tstack, vstack) + @racc_debug_out.puts "shift #{racc_token2str tok}" + racc_print_stacks tstack, vstack + @racc_debug_out.puts + end + + def racc_reduce(toks, sim, tstack, vstack) + out = @racc_debug_out + out.print 'reduce ' + if toks.empty? + out.print ' ' + else + toks.each {|t| out.print ' ', racc_token2str(t) } + end + out.puts " --> #{racc_token2str(sim)}" + racc_print_stacks tstack, vstack + @racc_debug_out.puts + end + + def racc_accept + @racc_debug_out.puts 'accept' + @racc_debug_out.puts + end + + def racc_e_pop(state, tstack, vstack) + @racc_debug_out.puts 'error recovering mode: pop token' + racc_print_states state + racc_print_stacks tstack, vstack + @racc_debug_out.puts + end + + def racc_next_state(curstate, state) + @racc_debug_out.puts "goto #{curstate}" + racc_print_states state + @racc_debug_out.puts + end + + def racc_print_stacks(t, v) + out = @racc_debug_out + out.print ' [' + t.each_index do |i| + out.print ' (', racc_token2str(t[i]), ' ', v[i].inspect, ')' + end + out.puts ' ]' + end + + def racc_print_states(s) + out = @racc_debug_out + out.print ' [' + s.each {|st| out.print ' ', st } + out.puts ' ]' + end + + def racc_token2str(tok) + self.class::Racc_token_to_s_table[tok] or + raise "[Racc Bug] can't convert token #{tok} to string" + end + + # Convert internal ID of token symbol to the string. + def token_to_str(t) + self.class::Racc_token_to_s_table[t] + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/parserfilegenerator.rb b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/parserfilegenerator.rb new file mode 100644 index 00000000..00fc1b35 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/parserfilegenerator.rb @@ -0,0 +1,473 @@ +#-- +# +# +# +# Copyright (c) 1999-2006 Minero Aoki +# +# This program is free software. +# You can distribute/modify this program under the same terms of ruby. +# see the file "COPYING". +# +#++ + +require_relative 'compat' +require_relative 'sourcetext' +require_relative 'parser-text' +require 'rbconfig' + +module Racc + + class ParserFileGenerator + + class Params + def self.bool_attr(name) + module_eval(<<-End) + def #{name}? + @#{name} + end + + def #{name}=(b) + @#{name} = b + end + End + end + + attr_accessor :filename + attr_accessor :classname + attr_accessor :superclass + bool_attr :omit_action_call + bool_attr :result_var + attr_accessor :header + attr_accessor :inner + attr_accessor :footer + + bool_attr :debug_parser + bool_attr :convert_line + bool_attr :convert_line_all + bool_attr :embed_runtime + bool_attr :frozen_strings + bool_attr :make_executable + attr_accessor :interpreter + + def initialize + # Parameters derived from parser + self.filename = nil + self.classname = nil + self.superclass = 'Racc::Parser' + self.omit_action_call = true + self.result_var = true + self.header = [] + self.inner = [] + self.footer = [] + + # Parameters derived from command line options + self.debug_parser = false + self.convert_line = true + self.convert_line_all = false + self.embed_runtime = false + self.frozen_strings = false + self.make_executable = false + self.interpreter = nil + end + end + + def initialize(states, params) + @states = states + @grammar = states.grammar + @params = params + end + + def generate_parser + string_io = StringIO.new + + init_line_conversion_system + @f = string_io + parser_file + + string_io.rewind + string_io.read + end + + def generate_parser_file(destpath) + init_line_conversion_system + File.open(destpath, 'w') {|f| + @f = f + parser_file + } + File.chmod 0755, destpath if @params.make_executable? + end + + private + + def parser_file + shebang @params.interpreter if @params.make_executable? + notice + line + if @params.embed_runtime? + embed_library runtime_source() + else + require 'racc/parser.rb' + end + header + parser_class(@params.classname, @params.superclass) { + inner + state_transition_table + } + footer + end + + c = ::RbConfig::CONFIG + RUBY_PATH = "#{c['bindir']}/#{c['ruby_install_name']}#{c['EXEEXT']}" + + def shebang(path) + line '#!' + (path == 'ruby' ? RUBY_PATH : path) + end + + def notice + line %q[# frozen_string_literal: true] if @params.frozen_strings? + line %q[#] + line %q[# DO NOT MODIFY!!!!] + line %Q[# This file is automatically generated by Racc #{Racc::Version}] + line %Q[# from Racc grammar file "#{@params.filename}".] + line %q[#] + end + + def runtime_source + SourceText.new(::Racc::PARSER_TEXT, 'racc/parser.rb', 1) + end + + def embed_library(src) + line %[###### #{src.filename} begin] + line %[unless $".find {|p| p.end_with?('/#{src.filename}')}] + line %[$".push "\#{__dir__}/#{src.filename}"] + put src, @params.convert_line? + line %[end] + line %[###### #{src.filename} end] + end + + def require(feature) + line "require '#{feature}'" + end + + def parser_class(classname, superclass) + mods = classname.split('::') + classid = mods.pop + mods.each do |mod| + indent; line "module #{mod}" + cref_push mod + end + indent; line "class #{classid} < #{superclass}" + cref_push classid + yield + cref_pop + indent; line "end \# class #{classid}" + mods.reverse_each do |mod| + cref_pop + indent; line "end \# module #{mod}" + end + end + + def header + @params.header.each do |src| + line + put src, @params.convert_line_all? + end + end + + def inner + @params.inner.each do |src| + line + put src, @params.convert_line? + end + end + + def footer + @params.footer.each do |src| + line + put src, @params.convert_line_all? + end + end + + # Low Level Routines + + def put(src, convert_line = false) + if convert_line + replace_location(src) { + @f.puts src.text + } + else + @f.puts src.text + end + end + + def line(str = '') + @f.puts str + end + + def init_line_conversion_system + @cref = [] + @used_separator = {} + end + + def cref_push(name) + @cref.push name + end + + def cref_pop + @cref.pop + end + + def indent + @f.print ' ' * @cref.size + end + + def toplevel? + @cref.empty? + end + + def replace_location(src) + sep = make_separator(src) + @f.print 'self.class.' if toplevel? + @f.puts "module_eval(<<'#{sep}', '#{src.filename}', #{src.lineno})" + yield + @f.puts sep + end + + def make_separator(src) + sep = unique_separator(src.filename) + sep *= 2 while src.text.index(sep) + sep + end + + def unique_separator(id) + sep = String.new "...end #{id}/module_eval..." + while @used_separator.key?(sep) + sep.concat sprintf('%02x', rand(255)) + end + @used_separator[sep] = true + sep + end + + # + # State Transition Table Serialization + # + + public + + def put_state_transition_table(f) + @f = f + state_transition_table + end + + private + + def state_transition_table + table = @states.state_transition_table + table.use_result_var = @params.result_var? + table.debug_parser = @params.debug_parser? + + line "##### State transition tables begin ###" + line + integer_list 'racc_action_table', table.action_table + line + integer_list 'racc_action_check', table.action_check + line + integer_list 'racc_action_pointer', table.action_pointer + line + integer_list 'racc_action_default', table.action_default + line + integer_list 'racc_goto_table', table.goto_table + line + integer_list 'racc_goto_check', table.goto_check + line + integer_list 'racc_goto_pointer', table.goto_pointer + line + integer_list 'racc_goto_default', table.goto_default + line + i_i_sym_list 'racc_reduce_table', table.reduce_table + line + line "racc_reduce_n = #{table.reduce_n}" + line + line "racc_shift_n = #{table.shift_n}" + line + sym_int_hash 'racc_token_table', table.token_table + line + line "racc_nt_base = #{table.nt_base}" + line + line "racc_use_result_var = #{table.use_result_var}" + line + @f.print(unindent_auto(<<-End)) + Racc_arg = [ + racc_action_table, + racc_action_check, + racc_action_default, + racc_action_pointer, + racc_goto_table, + racc_goto_check, + racc_goto_default, + racc_goto_pointer, + racc_nt_base, + racc_reduce_table, + racc_token_table, + racc_shift_n, + racc_reduce_n, + racc_use_result_var ] + End + line "Ractor.make_shareable(Racc_arg) if defined?(Ractor)" + line + string_list 'Racc_token_to_s_table', table.token_to_s_table + line "Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor)" + line + line "Racc_debug_parser = #{table.debug_parser}" + line + line '##### State transition tables end #####' + actions + end + + def integer_list(name, table) + sep = '' + line "#{name} = [" + table.each_slice(10) do |ns| + @f.print sep; sep = ",\n" + @f.print ns.map {|n| sprintf('%6s', n ? n.to_s : 'nil') }.join(',') + end + line ' ]' + end + + def i_i_sym_list(name, table) + sep = '' + line "#{name} = [" + table.each_slice(3) do |len, target, mid| + @f.print sep; sep = ",\n" + @f.printf ' %d, %d, %s', len, target, mid.inspect + end + line " ]" + end + + def sym_int_hash(name, h) + sep = "\n" + @f.print "#{name} = {" + h.to_a.sort_by {|sym, i| i }.each do |sym, i| + @f.print sep; sep = ",\n" + @f.printf " %s => %d", sym.serialize, i + end + line " }" + end + + def string_list(name, list) + sep = " " + line "#{name} = [" + list.each do |s| + @f.print sep; sep = ",\n " + @f.print s.dump + end + line ' ]' + end + + def actions + @grammar.each do |rule| + unless rule.action.source? + raise "racc: fatal: cannot generate parser file when any action is a Proc" + end + end + + if @params.result_var? + decl = ', result' + retval = "\n result" + default_body = '' + else + decl = '' + retval = '' + default_body = 'val[0]' + end + @grammar.each do |rule| + line + if rule.action.empty? and @params.omit_action_call? + line "# reduce #{rule.ident} omitted" + else + src0 = rule.action.source || SourceText.new(default_body, __FILE__, 0) + if @params.convert_line? + src = remove_blank_lines(src0) + delim = make_delimiter(src.text) + @f.printf unindent_auto(<<-End), + module_eval(<<'%s', '%s', %d) + def _reduce_%d(val, _values%s) + %s%s + end + %s + End + delim, src.filename, src.lineno - 1, + rule.ident, decl, + src.text, retval, + delim + else + src = remove_blank_lines(src0) + @f.printf unindent_auto(<<-End), + def _reduce_%d(val, _values%s) + %s%s + end + End + rule.ident, decl, + src.text, retval + end + end + end + line + @f.printf unindent_auto(<<-'End'), decl + def _reduce_none(val, _values%s) + val[0] + end + End + line + end + + def remove_blank_lines(src) + body = src.text.dup + line = src.lineno + while body.slice!(/\A[ \t\f]*(?:\n|\r\n|\r)/) + line += 1 + end + SourceText.new(body, src.filename, line) + end + + def make_delimiter(body) + delim = '.,.,' + while body.index(delim) + delim *= 2 + end + delim + end + + def unindent_auto(str) + lines = str.lines.to_a + n = minimum_indent(lines) + lines.map {|line| detab(line).sub(indent_re(n), '').rstrip + "\n" }.join('') + end + + def minimum_indent(lines) + lines.map {|line| n_indent(line) }.min + end + + def n_indent(line) + line.slice(/\A\s+/).size + end + + RE_CACHE = {} + + def indent_re(n) + RE_CACHE[n] ||= /\A {#{n}}/ + end + + def detab(str, ts = 8) + add = 0 + len = nil + str.gsub(/\t/) { + len = ts - ($`.size + add) % ts + add += len - 1 + ' ' * len + } + end + + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/sourcetext.rb b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/sourcetext.rb new file mode 100644 index 00000000..de52dcae --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/sourcetext.rb @@ -0,0 +1,35 @@ +#-- +# +# +# +# Copyright (c) 1999-2006 Minero Aoki +# +# This program is free software. +# You can distribute/modify this program under the same terms of ruby. +# see the file "COPYING". +# +#++ + +module Racc + + class SourceText + def initialize(text, filename, lineno) + @text = text + @filename = filename + @lineno = lineno + end + + attr_reader :text + attr_reader :filename + attr_reader :lineno + + def to_s + "#" + end + + def location + "#{@filename}:#{@lineno}" + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/state.rb b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/state.rb new file mode 100644 index 00000000..d57e658e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/state.rb @@ -0,0 +1,976 @@ +#-- +# +# +# +# Copyright (c) 1999-2006 Minero Aoki +# +# This program is free software. +# You can distribute/modify this program under the same terms of ruby. +# see the file "COPYING". +# +#++ + +require_relative 'iset' +require_relative 'statetransitiontable' +require_relative 'exception' +require 'forwardable' + +module Racc + + # A table of LALR states. + class States + + include Enumerable + + def initialize(grammar, debug_flags = DebugFlags.new) + @grammar = grammar + @symboltable = grammar.symboltable + @d_state = debug_flags.state + @d_la = debug_flags.la + @d_prec = debug_flags.prec + @states = [] + @statecache = {} + @actions = ActionTable.new(@grammar, self) + @nfa_computed = false + @dfa_computed = false + end + + attr_reader :grammar + attr_reader :actions + + def size + @states.size + end + + def inspect + '#' + end + + alias to_s inspect + + def [](i) + @states[i] + end + + def each_state(&block) + @states.each(&block) + end + + alias each each_state + + def each_index(&block) + @states.each_index(&block) + end + + extend Forwardable + + def_delegator "@actions", :shift_n + def_delegator "@actions", :reduce_n + def_delegator "@actions", :nt_base + + def should_report_srconflict? + srconflict_exist? and + (n_srconflicts() != @grammar.n_expected_srconflicts) + end + + def should_error_on_expect_mismatch? + should_report_srconflict? && @grammar.error_on_expect_mismatch + end + + def srconflict_exist? + n_srconflicts() != 0 + end + + def n_srconflicts + @n_srconflicts ||= inject(0) {|sum, st| sum + st.n_srconflicts } + end + + def rrconflict_exist? + n_rrconflicts() != 0 + end + + def n_rrconflicts + @n_rrconflicts ||= inject(0) {|sum, st| sum + st.n_rrconflicts } + end + + def state_transition_table + @state_transition_table ||= StateTransitionTable.generate(self.dfa) + end + + # + # NFA (Non-deterministic Finite Automaton) Computation + # + + public + + def nfa + return self if @nfa_computed + compute_nfa + @nfa_computed = true + self + end + + private + + def compute_nfa + @grammar.init + # add state 0 + core_to_state [ @grammar[0].ptrs[0] ] + # generate LALR states + cur = 0 + @gotos = [] + while cur < @states.size + generate_states @states[cur] # state is added here + cur += 1 + end + @actions.init + end + + def generate_states(state) + puts "dstate: #{state}" if @d_state + + table = {} + state.closure.each do |ptr| + if sym = ptr.dereference + addsym table, sym, ptr.next + end + end + table.each do |sym, core| + puts "dstate: sym=#{sym} ncore=#{core}" if @d_state + + dest = core_to_state(core.to_a) + state.goto_table[sym] = dest + id = sym.nonterminal?() ? @gotos.size : nil + g = Goto.new(id, sym, state, dest) + @gotos.push g if sym.nonterminal? + state.gotos[sym] = g + puts "dstate: #{state.ident} --#{sym}--> #{dest.ident}" if @d_state + + # check infinite recursion + if state.ident == dest.ident and state.closure.size == 1 + raise CompileError, + sprintf("Infinite recursion: state %d, with rule %d", + state.ident, state.ptrs[0].rule.ident) + end + end + end + + def addsym(table, sym, ptr) + unless s = table[sym] + table[sym] = s = ISet.new + end + s.add ptr + end + + def core_to_state(core) + # + # convert CORE to a State object. + # If matching state does not exist, create it and add to the table. + # + + k = fingerprint(core) + unless dest = @statecache[k] + # not registered yet + dest = State.new(@states.size, core) + @states.push dest + + @statecache[k] = dest + + puts "core_to_state: create state ID #{dest.ident}" if @d_state + else + if @d_state + puts "core_to_state: dest is cached ID #{dest.ident}" + puts "core_to_state: dest core #{dest.core.join(' ')}" + end + end + + dest + end + + def fingerprint(arr) + arr.map {|i| i.ident }.pack('L*') + end + + # + # DFA (Deterministic Finite Automaton) Generation + # + + public + + def dfa + return self if @dfa_computed + nfa + compute_dfa + @dfa_computed = true + self + end + + private + + def compute_dfa + la = lookahead() + @states.each do |state| + state.la = la + resolve state + end + set_accept + @states.each do |state| + pack state + end + check_useless + end + + def lookahead + # + # lookahead algorithm ver.3 -- from bison 1.26 + # + + gotos = @gotos + if @d_la + puts "\n--- goto ---" + gotos.each_with_index {|g, i| print i, ' '; p g } + end + + ### initialize_LA() + ### set_goto_map() + la_rules = [] + @states.each do |state| + state.check_la la_rules + end + + ### initialize_F() + f = create_tmap(gotos.size) + reads = [] + edge = [] + gotos.each do |goto| + goto.to_state.goto_table.each do |t, st| + if t.terminal? + f[goto.ident] |= (1 << t.ident) + elsif t.nullable? + edge.push goto.to_state.gotos[t].ident + end + end + if edge.empty? + reads.push nil + else + reads.push edge + edge = [] + end + end + digraph f, reads + if @d_la + puts "\n--- F1 (reads) ---" + print_tab gotos, reads, f + end + + ### build_relations() + ### compute_FOLLOWS + path = nil + edge = [] + lookback = Array.new(la_rules.size, nil) + includes = [] + gotos.each do |goto| + goto.symbol.heads.each do |ptr| + path = record_path(goto.from_state, ptr.rule) + lastgoto = path.last + st = lastgoto ? lastgoto.to_state : goto.from_state + if st.conflict? + addrel lookback, st.rruleid(ptr.rule), goto + end + path.reverse_each do |g| + break if g.symbol.terminal? + edge.push g.ident + break unless g.symbol.nullable? + end + end + if edge.empty? + includes.push nil + else + includes.push edge + edge = [] + end + end + includes = transpose(includes) + digraph f, includes + if @d_la + puts "\n--- F2 (includes) ---" + print_tab gotos, includes, f + end + + ### compute_lookaheads + la = create_tmap(la_rules.size) + lookback.each_with_index do |arr, i| + if arr + arr.each do |g| + la[i] |= f[g.ident] + end + end + end + if @d_la + puts "\n--- LA (lookback) ---" + print_tab la_rules, lookback, la + end + + la + end + + def create_tmap(size) + Array.new(size, 0) # use Integer as bitmap + end + + def addrel(tbl, i, item) + if a = tbl[i] + a.push item + else + tbl[i] = [item] + end + end + + def record_path(begst, rule) + st = begst + path = [] + rule.symbols.each do |t| + goto = st.gotos[t] + path.push goto + st = goto.to_state + end + path + end + + def transpose(rel) + new = Array.new(rel.size, nil) + rel.each_with_index do |arr, idx| + if arr + arr.each do |i| + addrel new, i, idx + end + end + end + new + end + + def digraph(map, relation) + n = relation.size + index = Array.new(n, nil) + vertices = [] + @infinity = n + 2 + + index.each_index do |i| + if not index[i] and relation[i] + traverse i, index, vertices, map, relation + end + end + end + + def traverse(i, index, vertices, map, relation) + vertices.push i + index[i] = height = vertices.size + + if rp = relation[i] + rp.each do |proci| + unless index[proci] + traverse proci, index, vertices, map, relation + end + if index[i] > index[proci] + # circulative recursion !!! + index[i] = index[proci] + end + map[i] |= map[proci] + end + end + + if index[i] == height + while true + proci = vertices.pop + index[proci] = @infinity + break if i == proci + + map[proci] |= map[i] + end + end + end + + # for debug + def print_atab(idx, tab) + tab.each_with_index do |i,ii| + printf '%-20s', idx[ii].inspect + p i + end + end + + def print_tab(idx, rel, tab) + tab.each_with_index do |bin,i| + print i, ' ', idx[i].inspect, ' << '; p rel[i] + print ' ' + each_t(@symboltable, bin) {|t| print ' ', t } + puts + end + end + + # for debug + def print_tab_i(idx, rel, tab, i) + bin = tab[i] + print i, ' ', idx[i].inspect, ' << '; p rel[i] + print ' ' + each_t(@symboltable, bin) {|t| print ' ', t } + end + + # for debug + def printb(i) + each_t(@symboltable, i) do |t| + print t, ' ' + end + puts + end + + def each_t(tbl, set) + 0.upto( set.size ) do |i| + (0..7).each do |ii| + if set[idx = i * 8 + ii] == 1 + yield tbl[idx] + end + end + end + end + + # + # resolve + # + + def resolve(state) + if state.conflict? + resolve_rr state, state.ritems + resolve_sr state, state.stokens + else + if state.rrules.empty? + # shift + state.stokens.each do |t| + state.action[t] = @actions.shift(state.goto_table[t]) + end + else + # reduce + state.defact = @actions.reduce(state.rrules[0]) + end + end + end + + def resolve_rr(state, r) + r.each do |item| + item.each_la(@symboltable) do |t| + act = state.action[t] + if act + unless act.kind_of?(Reduce) + raise "racc: fatal: #{act.class} in action table" + end + # Cannot resolve R/R conflict (on t). + # Reduce with upper rule as default. + state.rr_conflict act.rule, item.rule, t + else + # No conflict. + state.action[t] = @actions.reduce(item.rule) + end + end + end + end + + def resolve_sr(state, s) + s.each do |stok| + goto = state.goto_table[stok] + act = state.action[stok] + + unless act + # no conflict + state.action[stok] = @actions.shift(goto) + else + unless act.kind_of?(Reduce) + puts 'DEBUG -------------------------------' + p stok + p act + state.action.each do |k,v| + print k.inspect, ' ', v.inspect, "\n" + end + raise "racc: fatal: #{act.class} in action table" + end + + # conflict on stok + + rtok = act.rule.precedence + case do_resolve_sr(stok, rtok) + when :Reduce + # action is already set + + when :Shift + # overwrite + act.decref + state.action[stok] = @actions.shift(goto) + + when :Error + act.decref + state.action[stok] = @actions.error + + when :CantResolve + # shift as default + act.decref + state.action[stok] = @actions.shift(goto) + state.sr_conflict stok, act.rule + end + end + end + end + + ASSOC = { + :Left => :Reduce, + :Right => :Shift, + :Nonassoc => :Error + } + + def do_resolve_sr(stok, rtok) + puts "resolve_sr: s/r conflict: rtok=#{rtok}, stok=#{stok}" if @d_prec + + unless rtok and rtok.precedence + puts "resolve_sr: no prec for #{rtok}(R)" if @d_prec + return :CantResolve + end + rprec = rtok.precedence + + unless stok and stok.precedence + puts "resolve_sr: no prec for #{stok}(S)" if @d_prec + return :CantResolve + end + sprec = stok.precedence + + ret = if rprec == sprec + ASSOC[rtok.assoc] or + raise "racc: fatal: #{rtok}.assoc is not Left/Right/Nonassoc" + else + (rprec > sprec) ? (:Reduce) : (:Shift) + end + + puts "resolve_sr: resolved as #{ret.id2name}" if @d_prec + ret + end + + # + # complete + # + + def set_accept + anch = @symboltable.anchor + init_state = @states[0].goto_table[@grammar.start] + targ_state = init_state.action[anch].goto_state + acc_state = targ_state.action[anch].goto_state + + acc_state.action.clear + acc_state.goto_table.clear + acc_state.defact = @actions.accept + end + + def pack(state) + ### find most frequently used reduce rule + act = state.action + arr = Array.new(@grammar.size, 0) + act.each do |t, a| + arr[a.ruleid] += 1 if a.kind_of?(Reduce) + end + i = arr.max + s = (i > 0) ? arr.index(i) : nil + + ### set & delete default action + if s + r = @actions.reduce(s) + if not state.defact or state.defact == r + act.delete_if {|t, a| a == r } + state.defact = r + end + else + state.defact ||= @actions.error + end + end + + def check_useless + used = [] + @actions.each_reduce do |act| + if not act or act.refn == 0 + act.rule.useless = true + else + t = act.rule.target + used[t.ident] = t + end + end + @symboltable.nt_base.upto(@symboltable.nt_max - 1) do |n| + unless used[n] + @symboltable[n].useless = true + end + end + end + + end # class StateTable + + + # A LALR state. + class State + + def initialize(ident, core) + @ident = ident + @core = core + @goto_table = {} + @gotos = {} + @stokens = nil + @ritems = nil + @action = {} + @defact = nil + @rrconf = nil + @srconf = nil + + @closure = make_closure(@core) + end + + attr_reader :ident + alias stateid ident + alias hash ident + + attr_reader :core + attr_reader :closure + + attr_reader :goto_table + attr_reader :gotos + + attr_reader :stokens + attr_reader :ritems + attr_reader :rrules + + attr_reader :action + attr_accessor :defact # default action + + attr_reader :rrconf + attr_reader :srconf + + def inspect + "" + end + + alias to_s inspect + + def ==(oth) + @ident == oth.ident + end + + alias eql? == + + def make_closure(core) + set = ISet.new + core.each do |ptr| + set.add ptr + if t = ptr.dereference and t.nonterminal? + set.update_a t.expand + end + end + set.to_a + end + + def check_la(la_rules) + @conflict = false + s = [] + r = [] + @closure.each do |ptr| + if t = ptr.dereference + if t.terminal? + s[t.ident] = t + if t.ident == 1 # $error + @conflict = true + end + end + else + r.push ptr.rule + end + end + unless r.empty? + if not s.empty? or r.size > 1 + @conflict = true + end + end + s.compact! + @stokens = s + @rrules = r + + if @conflict + @la_rules_i = la_rules.size + @la_rules = r.map {|i| i.ident } + la_rules.concat r + else + @la_rules_i = @la_rules = nil + end + end + + def conflict? + @conflict + end + + def rruleid(rule) + if i = @la_rules.index(rule.ident) + @la_rules_i + i + else + puts '/// rruleid' + p self + p rule + p @rrules + p @la_rules_i + raise 'racc: fatal: cannot get reduce rule id' + end + end + + def la=(la) + return unless @conflict + i = @la_rules_i + @ritems = r = [] + @rrules.each do |rule| + r.push Item.new(rule, la[i]) + i += 1 + end + end + + def rr_conflict(high, low, ctok) + c = RRconflict.new(@ident, high, low, ctok) + + @rrconf ||= {} + if a = @rrconf[ctok] + a.push c + else + @rrconf[ctok] = [c] + end + end + + def sr_conflict(shift, reduce) + c = SRconflict.new(@ident, shift, reduce) + + @srconf ||= {} + if a = @srconf[shift] + a.push c + else + @srconf[shift] = [c] + end + end + + def n_srconflicts + @srconf ? @srconf.size : 0 + end + + def n_rrconflicts + @rrconf ? @rrconf.size : 0 + end + + end # class State + + + # + # Represents a transition on the grammar. + # "Real goto" means a transition by nonterminal, + # but this class treats also terminal's. + # If one is a terminal transition, .ident returns nil. + # + class Goto + def initialize(ident, sym, from, to) + @ident = ident + @symbol = sym + @from_state = from + @to_state = to + end + + attr_reader :ident + attr_reader :symbol + attr_reader :from_state + attr_reader :to_state + + def inspect + "(#{@from_state.ident}-#{@symbol}->#{@to_state.ident})" + end + end + + + # LALR item. A set of rule and its lookahead tokens. + class Item + def initialize(rule, la) + @rule = rule + @la = la + end + + attr_reader :rule + attr_reader :la + + def each_la(tbl) + la = @la + 0.upto(la.size - 1) do |i| + (0..7).each do |ii| + if la[idx = i * 8 + ii] == 1 + yield tbl[idx] + end + end + end + end + end + + + # The table of LALR actions. Actions are either of + # Shift, Reduce, Accept and Error. + class ActionTable + + def initialize(rt, st) + @grammar = rt + @statetable = st + + @reduce = [] + @shift = [] + @accept = nil + @error = nil + end + + def init + @grammar.each do |rule| + @reduce.push Reduce.new(rule) + end + @statetable.each do |state| + @shift.push Shift.new(state) + end + @accept = Accept.new + @error = Error.new + end + + def reduce_n + @reduce.size + end + + def reduce(i) + case i + when Rule then i = i.ident + when Integer then ; + else + raise "racc: fatal: wrong class #{i.class} for reduce" + end + + r = @reduce[i] or raise "racc: fatal: reduce action #{i.inspect} not exist" + r.incref + r + end + + def each_reduce(&block) + @reduce.each(&block) + end + + def shift_n + @shift.size + end + + def shift(i) + case i + when State then i = i.ident + when Integer then ; + else + raise "racc: fatal: wrong class #{i.class} for shift" + end + + @shift[i] or raise "racc: fatal: shift action #{i} does not exist" + end + + def each_shift(&block) + @shift.each(&block) + end + + attr_reader :accept + attr_reader :error + + end + + + class Shift + def initialize(goto) + @goto_state = goto + end + + attr_reader :goto_state + + def goto_id + @goto_state.ident + end + + def inspect + "" + end + end + + + class Reduce + def initialize(rule) + @rule = rule + @refn = 0 + end + + attr_reader :rule + attr_reader :refn + + def ruleid + @rule.ident + end + + def inspect + "" + end + + def incref + @refn += 1 + end + + def decref + @refn -= 1 + raise 'racc: fatal: act.refn < 0' if @refn < 0 + end + end + + class Accept + def inspect + "" + end + end + + class Error + def inspect + "" + end + end + + class SRconflict + def initialize(sid, shift, reduce) + @stateid = sid + @shift = shift + @reduce = reduce + end + + attr_reader :stateid + attr_reader :shift + attr_reader :reduce + + def to_s + sprintf('state %d: S/R conflict rule %d reduce and shift %s', + @stateid, @reduce.ruleid, @shift.to_s) + end + end + + class RRconflict + def initialize(sid, high, low, tok) + @stateid = sid + @high_prec = high + @low_prec = low + @token = tok + end + + attr_reader :stateid + attr_reader :high_prec + attr_reader :low_prec + attr_reader :token + + def to_s + sprintf('state %d: R/R conflict with rule %d and %d on %s', + @stateid, @high_prec.ident, @low_prec.ident, @token.to_s) + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/statetransitiontable.rb b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/statetransitiontable.rb new file mode 100644 index 00000000..fa5abdd4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/statetransitiontable.rb @@ -0,0 +1,311 @@ +#-- +# +# +# +# Copyright (c) 1999-2006 Minero Aoki +# +# This program is free software. +# You can distribute/modify this program under the same terms of ruby. +# see the file "COPYING". +# +#++ + +require_relative 'parser' + +module Racc + + StateTransitionTable = Struct.new(:action_table, + :action_check, + :action_default, + :action_pointer, + :goto_table, + :goto_check, + :goto_default, + :goto_pointer, + :token_table, + :reduce_table, + :reduce_n, + :shift_n, + :nt_base, + :token_to_s_table, + :use_result_var, + :debug_parser) + class StateTransitionTable # reopen + def StateTransitionTable.generate(states) + StateTransitionTableGenerator.new(states).generate + end + + def initialize(states) + super() + @states = states + @grammar = states.grammar + self.use_result_var = true + self.debug_parser = true + end + + attr_reader :states + attr_reader :grammar + + def parser_class + ParserClassGenerator.new(@states).generate + end + + def token_value_table + h = {} + token_table().each do |sym, i| + h[sym.value] = i + end + h + end + end + + + class StateTransitionTableGenerator + + def initialize(states) + @states = states + @grammar = states.grammar + end + + def generate + t = StateTransitionTable.new(@states) + gen_action_tables t, @states + gen_goto_tables t, @grammar + t.token_table = token_table(@grammar) + t.reduce_table = reduce_table(@grammar) + t.reduce_n = @states.reduce_n + t.shift_n = @states.shift_n + t.nt_base = @grammar.nonterminal_base + t.token_to_s_table = @grammar.symbols.map {|sym| sym.to_s } + t + end + + def reduce_table(grammar) + t = [0, 0, :racc_error] + grammar.each_with_index do |rule, idx| + next if idx == 0 + t.push rule.size + t.push rule.target.ident + t.push(if rule.action.empty? # and @params.omit_action_call? + then :_reduce_none + else "_reduce_#{idx}".intern + end) + end + t + end + + def token_table(grammar) + h = {} + grammar.symboltable.terminals.each do |t| + h[t] = t.ident + end + h + end + + def gen_action_tables(t, states) + t.action_table = yytable = [] + t.action_check = yycheck = [] + t.action_default = yydefact = [] + t.action_pointer = yypact = [] + e1 = [] + e2 = [] + states.each do |state| + yydefact.push act2actid(state.defact) + if state.action.empty? + yypact.push nil + next + end + vector = [] + state.action.each do |tok, act| + vector[tok.ident] = act2actid(act) + end + addent e1, vector, state.ident, yypact + end + set_table e1, e2, yytable, yycheck, yypact + end + + def gen_goto_tables(t, grammar) + t.goto_table = yytable2 = [] + t.goto_check = yycheck2 = [] + t.goto_pointer = yypgoto = [] + t.goto_default = yydefgoto = [] + e1 = [] + e2 = [] + grammar.each_nonterminal do |tok| + tmp = [] + + # decide default + freq = Array.new(@states.size, 0) + @states.each do |state| + st = state.goto_table[tok] + if st + st = st.ident + freq[st] += 1 + end + tmp[state.ident] = st + end + max = freq.max + if max > 1 + default = freq.index(max) + tmp.map! {|i| default == i ? nil : i } + else + default = nil + end + yydefgoto.push default + + # delete default value + tmp.pop until tmp.last or tmp.empty? + if tmp.compact.empty? + # only default + yypgoto.push nil + next + end + + addent e1, tmp, (tok.ident - grammar.nonterminal_base), yypgoto + end + set_table e1, e2, yytable2, yycheck2, yypgoto + end + + def addent(all, arr, chkval, ptr) + max = arr.size + min = nil + arr.each_with_index do |item, idx| + if item + min ||= idx + end + end + ptr.push(-7777) # mark + arr = arr[min...max] + all.push [arr, chkval, mkmapexp(arr), min, ptr.size - 1] + end + + n = 2 ** 16 + begin + Regexp.compile("a{#{n}}") + RE_DUP_MAX = n + rescue RegexpError + n /= 2 + retry + end + + def mkmapexp(arr) + i = ii = 0 + as = arr.size + map = String.new + maxdup = RE_DUP_MAX + curr = nil + while i < as + ii = i + 1 + if arr[i] + ii += 1 while ii < as and arr[ii] + curr = '-' + else + ii += 1 while ii < as and not arr[ii] + curr = '.' + end + + offset = ii - i + if offset == 1 + map << curr + else + while offset > maxdup + map << "#{curr}{#{maxdup}}" + offset -= maxdup + end + map << "#{curr}{#{offset}}" if offset > 1 + end + i = ii + end + Regexp.compile(map, Regexp::NOENCODING) + end + + def set_table(entries, dummy, tbl, chk, ptr) + upper = 0 + map = '-' * 10240 + + # sort long to short + entries.sort_by!.with_index {|a,i| [-a[0].size, i] } + + entries.each do |arr, chkval, expr, min, ptri| + if upper + arr.size > map.size + map << '-' * (arr.size + 1024) + end + idx = map.index(expr) + ptr[ptri] = idx - min + arr.each_with_index do |item, i| + if item + i += idx + tbl[i] = item + chk[i] = chkval + map[i] = ?o + end + end + upper = idx + arr.size + end + end + + def act2actid(act) + case act + when Shift then act.goto_id + when Reduce then -act.ruleid + when Accept then @states.shift_n + when Error then @states.reduce_n * -1 + else + raise "racc: fatal: wrong act type #{act.class} in action table" + end + end + + end + + + class ParserClassGenerator + + def initialize(states) + @states = states + @grammar = states.grammar + end + + def generate + table = @states.state_transition_table + c = Class.new(::Racc::Parser) + c.const_set :Racc_arg, [table.action_table, + table.action_check, + table.action_default, + table.action_pointer, + table.goto_table, + table.goto_check, + table.goto_default, + table.goto_pointer, + table.nt_base, + table.reduce_table, + table.token_value_table, + table.shift_n, + table.reduce_n, + false] + c.const_set :Racc_token_to_s_table, table.token_to_s_table + c.const_set :Racc_debug_parser, true + define_actions c + c + end + + private + + def define_actions(c) + c.module_eval "def _reduce_none(vals, vstack) vals[0] end" + @grammar.each do |rule| + if rule.action.empty? + c.alias_method("_reduce_#{rule.ident}", :_reduce_none) + else + c.define_method("_racc_action_#{rule.ident}", &rule.action.proc) + c.module_eval(<<-End, __FILE__, __LINE__ + 1) + def _reduce_#{rule.ident}(vals, vstack) + _racc_action_#{rule.ident}(*vals) + end + End + end + end + end + + end + +end # module Racc diff --git a/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/static.rb b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/static.rb new file mode 100644 index 00000000..04965dae --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/racc-1.8.1/lib/racc/static.rb @@ -0,0 +1,5 @@ +require_relative '../racc' +require_relative 'parser' +require_relative 'grammarfileparser' +require_relative 'parserfilegenerator' +require_relative 'logfilegenerator' diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/CHANGELOG.md b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/CHANGELOG.md new file mode 100644 index 00000000..a39839de --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/CHANGELOG.md @@ -0,0 +1,1157 @@ +# Changelog + +All notable changes to this project will be documented in this file. For info on how to format all future additions to this file please reference [Keep A Changelog](https://keepachangelog.com/en/1.0.0/). + +## [3.1.15] - 2025-05-18 + +- Optional support for `CGI::Cookie` if not available. ([#2327](https://github.com/rack/rack/pull/2327), [#2333](https://github.com/rack/rack/pull/2333), [@earlopain]) + +## [3.1.14] - 2025-05-06 + +### Security + +- [CVE-2025-46727](https://github.com/rack/rack/security/advisories/GHSA-gjh7-p2fx-99vx) Unbounded parameter parsing in `Rack::QueryParser` can lead to memory exhaustion. + +## [3.1.13] - 2025-04-13 + +- Ensure `Rack::ETag` correctly updates response body. ([#2324](https://github.com/rack/rack/pull/2324), [@ioquatix]) + +## [3.1.12] - 2025-03-11 + +### Security + +- [CVE-2025-27610](https://github.com/rack/rack/security/advisories/GHSA-7wqh-767x-r66v) Local file inclusion in `Rack::Static`. + +## [3.1.11] - 2025-03-04 + +### Security + +- [CVE-2025-27111](https://github.com/rack/rack/security/advisories/GHSA-8cgq-6mh2-7j6v) Possible Log Injection in `Rack::Sendfile`. + +## [3.1.10] - 2025-02-12 + +### Security + +- [CVE-2025-25184](https://github.com/rack/rack/security/advisories/GHSA-7g2v-jj9q-g3rg) Possible Log Injection in `Rack::CommonLogger`. + +## [3.1.9] - 2025-01-31 + +### Fixed + +- `Rack::MediaType#params` now handles parameters without values. ([#2263](https://github.com/rack/rack/pull/2263), [@AllyMarthaJ](https://github.com/AllyMarthaJ)) + +## [3.1.8] - 2024-10-14 + +### Fixed + +- Resolve deprecation warnings about uri `DEFAULT_PARSER`. ([#2249](https://github.com/rack/rack/pull/2249), [@earlopain]) + +## [3.1.7] - 2024-07-11 + +### Fixed + +- Do not remove escaped opening/closing quotes for content-disposition filenames. ([#2229](https://github.com/rack/rack/pull/2229), [@jeremyevans]) +- Fix encoding setting for non-binary IO-like objects in MockRequest#env_for. ([#2227](https://github.com/rack/rack/pull/2227), [@jeremyevans]) +- `Rack::Response` should not generate invalid `content-length` header. ([#2219](https://github.com/rack/rack/pull/2219), [@ioquatix]) +- Allow empty PATH_INFO. ([#2214](https://github.com/rack/rack/pull/2214), [@ioquatix]) + +## [3.1.6] - 2024-07-03 + +### Fixed + +- Fix several edge cases in `Rack::Request#parse_http_accept_header`'s implementation. ([#2226](https://github.com/rack/rack/pull/2226), [@ioquatix]) + +## [3.1.5] - 2024-07-02 + +### Security + +- Fix potential ReDoS attack in `Rack::Request#parse_http_accept_header`. ([GHSA-cj83-2ww7-mvq7](https://github.com/rack/rack/security/advisories/GHSA-cj83-2ww7-mvq7), [@dwisiswant0](https://github.com/dwisiswant0)) + +## [3.1.4] - 2024-06-22 + +### Fixed + +- Fix `Rack::Lint` matching some paths incorrectly as authority form. ([#2220](https://github.com/rack/rack/pull/2220), [@ioquatix]) + +## [3.1.3] - 2024-06-12 + +### Fixed + +- Fix passing non-strings to `Rack::Utils.escape_html`. ([#2202](https://github.com/rack/rack/pull/2202), [@earlopain]) +- `Rack::MockResponse` gracefully handles empty cookies ([#2203](https://github.com/rack/rack/pull/2203) [@wynksaiddestroy]) + +## [3.1.2] - 2024-06-11 + +- `Rack::Response` will take in to consideration chunked encoding responses ([#2204](https://github.com/rack/rack/pull/2204), [@tenderlove]) + +## [3.1.1] - 2024-06-11 + +- Oops! I shouldn't have shipped that + +## [3.1.0] - 2024-06-11 + +:warning: **This release includes several breaking changes.** Refer to the **Removed** section below for the list of deprecated methods that have been removed in this release. + +Rack v3.1 is primarily a maintenance release that removes features deprecated in Rack v3.0. Alongside these removals, there are several improvements to the Rack SPEC, mainly focused on enhancing input and output handling. These changes aim to make Rack more efficient and align better with the requirements of server implementations and relevant HTTP specifications. + +### SPEC Changes + +- `rack.input` is now optional. ([#1997](https://github.com/rack/rack/pull/1997), [#2018](https://github.com/rack/rack/pull/2018), [@ioquatix]) +- `PATH_INFO` is now validated according to the HTTP/1.1 specification. ([#2117](https://github.com/rack/rack/pull/2117), [#2181](https://github.com/rack/rack/pull/2181), [@ioquatix]) + - `OPTIONS *` is now accepted. ([#2114](https://github.com/rack/rack/pull/2114), [@doriantaylor](https://github.com/doriantaylor)) +- Introduce optional `rack.protocol` request and response header for handling connection upgrades. ([#1954](https://github.com/rack/rack/pull/1954), [@ioquatix]) + +### Added + +- Introduce `Rack::Multipart::MissingInputError` for improved handling of missing input in `#parse_multipart`. ([#2018](https://github.com/rack/rack/pull/2018), [@ioquatix]) +- Introduce `module Rack::BadRequest` which is included in multipart and query parser errors. ([#2019](https://github.com/rack/rack/pull/2019), [@ioquatix]) +- Add `.mjs` MIME type ([#2057](https://github.com/rack/rack/pull/2057), [@axilleas](https://github.com/axilleas)) +- `set_cookie_header` utility now supports the `partitioned` cookie attribute. This is required by Chrome in some embedded contexts. ([#2131](https://github.com/rack/rack/pull/2131), [@flavio-b](https://github.com/flavio-b)) +- Introduce `rack.early_hints` for sending `103 Early Hints` informational responses. ([#1831](https://github.com/rack/rack/pull/1831), [@casperisfine](https://github.com/casperisfine), [@jeremyevans]) + +### Changed + +- MIME type for JavaScript files (`.js`) changed from `application/javascript` to `text/javascript` ([`1bd0f15`](https://github.com/rack/rack/commit/1bd0f1597d8f4a90d47115f3e156a8ce7870c9c8), [@ioquatix]) +- Update MIME types associated to `.ttf`, `.woff`, `.woff2` and `.otf` extensions to use mondern `font/*` types. ([#2065](https://github.com/rack/rack/pull/2065), [@davidstosik]) +- `Rack::Utils.escape_html` is now delegated to `CGI.escapeHTML`. `'` is escaped to `#39;` instead of `#x27;`. (decimal vs hexadecimal) ([#2099](https://github.com/rack/rack/pull/2099), [@JunichiIto](https://github.com/JunichiIto)) +- Clarify use of `@buffered` and only update `content-length` when `Rack::Response#finish` is invoked. ([#2149](https://github.com/rack/rack/pull/2149), [@ioquatix]) + +### Deprecated + +- Deprecate automatic cache invalidation in `Request#{GET,POST}` ([#2073](https://github.com/rack/rack/pull/2073), [@jeremyevans]) +- Only cookie keys that are not valid according to the HTTP specifications are escaped. We are planning to deprecate this behaviour, so now a deprecation message will be emitted in this case. In the future, invalid cookie keys may not be accepted. ([#2191](https://github.com/rack/rack/pull/2191), [@ioquatix]) +- `Rack::Logger` is deprecated. ([#2197](https://github.com/rack/rack/pull/2197), [@ioquatix]) +- Add fallback lookup and deprecation warning for obsolete status symbols. ([#2137](https://github.com/rack/rack/pull/2137), [@wtn](https://github.com/wtn)) +- Deprecate `Rack::Request#values_at`, use `request.params.values_at` instead ([#2183](https://github.com/rack/rack/pull/2183), [@ioquatix]) + +### Removed + +- Remove deprecated `Rack::Auth::Digest` with no replacement. ([#1966](https://github.com/rack/rack/pull/1966), [@ioquatix]) +- Remove deprecated `Rack::Cascade::NotFound` with no replacement. ([#1966](https://github.com/rack/rack/pull/1966), [@ioquatix]) +- Remove deprecated `Rack::Chunked` with no replacement. ([#1966](https://github.com/rack/rack/pull/1966), [@ioquatix]) +- Remove deprecated `Rack::File`, use `Rack::Files` instead. ([#1966](https://github.com/rack/rack/pull/1966), [@ioquatix]) +- Remove deprecated `Rack::QueryParser` `key_space_limit` parameter with no replacement. ([#1966](https://github.com/rack/rack/pull/1966), [@ioquatix]) +- Remove deprecated `Rack::Response#header`, use `Rack::Response#headers` instead. ([#1966](https://github.com/rack/rack/pull/1966), [@ioquatix]) +- Remove deprecated cookie methods from `Rack::Utils`: `add_cookie_to_header`, `make_delete_cookie_header`, `add_remove_cookie_to_header`. ([#1966](https://github.com/rack/rack/pull/1966), [@ioquatix]) +- Remove deprecated `Rack::Utils::HeaderHash`. ([#1966](https://github.com/rack/rack/pull/1966), [@ioquatix]) +- Remove deprecated `Rack::VERSION`, `Rack::VERSION_STRING`, `Rack.version`, use `Rack.release` instead. ([#1966](https://github.com/rack/rack/pull/1966), [@ioquatix]) +- Remove non-standard status codes 306, 509, & 510 and update descriptions for 413, 422, & 451. ([#2137](https://github.com/rack/rack/pull/2137), [@wtn](https://github.com/wtn)) +- Remove any dependency on `transfer-encoding: chunked`. ([#2195](https://github.com/rack/rack/pull/2195), [@ioquatix]) +- Remove deprecated `Rack::Request#[]`, use `request.params[key]` instead ([#2183](https://github.com/rack/rack/pull/2183), [@ioquatix]) + +### Fixed + +- In `Rack::Files`, ignore the `Range` header if served file is 0 bytes. ([#2159](https://github.com/rack/rack/pull/2159), [@zarqman]) + +## [3.0.18] - 2025-05-22 + +- Fix incorrect backport of optional `CGI::Cookie` support. ([#2335](https://github.com/rack/rack/pull/2335), [@jeremyevans]) + +## [3.0.17] - 2025-05-18 + +- Optional support for `CGI::Cookie` if not available. ([#2327](https://github.com/rack/rack/pull/2327), [#2333](https://github.com/rack/rack/pull/2333), [@earlopain]) + +## [3.0.16] - 2025-05-06 + +### Security + +- [CVE-2025-46727](https://github.com/rack/rack/security/advisories/GHSA-gjh7-p2fx-99vx) Unbounded parameter parsing in `Rack::QueryParser` can lead to memory exhaustion. + +## [3.0.15] - 2025-04-13 + +- Ensure `Rack::ETag` correctly updates response body. ([#2324](https://github.com/rack/rack/pull/2324), [@ioquatix]) + +## [3.0.14] - 2025-03-11 + +### Security + +- [CVE-2025-27610](https://github.com/rack/rack/security/advisories/GHSA-7wqh-767x-r66v) Local file inclusion in `Rack::Static`. + +## [3.0.13] - 2025-03-04 + +### Security + +- [CVE-2025-27111](https://github.com/rack/rack/security/advisories/GHSA-8cgq-6mh2-7j6v) Possible Log Injection in `Rack::Sendfile`. + +### Fixed + +- Remove autoloads for constants no longer shipped with Rack. ([#2269](https://github.com/rack/rack/pull/2269), [@ccutrer](https://github.com/ccutrer)) + +## [3.0.12] - 2025-02-12 + +### Security + +- [CVE-2025-25184](https://github.com/rack/rack/security/advisories/GHSA-7g2v-jj9q-g3rg) Possible Log Injection in `Rack::CommonLogger`. + +## [3.0.11] - 2024-05-10 + +- Backport #2062 to 3-0-stable: Do not allow `BodyProxy` to respond to `to_str`, make `to_ary` call close . ([#2062](https://github.com/rack/rack/pull/2062), [@jeremyevans](https://github.com/jeremyevans)) + +## [3.0.10] - 2024-03-21 + +- Backport #2104 to 3-0-stable: Return empty when parsing a multi-part POST with only one end delimiter. ([#2164](https://github.com/rack/rack/pull/2164), [@JoeDupuis](https://github.com/JoeDupuis)) + +## [3.0.9.1] - 2024-02-21 + +### Security + +* [CVE-2024-26146] Fixed ReDoS in Accept header parsing +* [CVE-2024-25126] Fixed ReDoS in Content Type header parsing +* [CVE-2024-26141] Reject Range headers which are too large + +[CVE-2024-26146]: https://github.com/advisories/GHSA-54rr-7fvw-6x8f +[CVE-2024-25126]: https://github.com/advisories/GHSA-22f2-v57c-j9cx +[CVE-2024-26141]: https://github.com/advisories/GHSA-xj5v-6v4g-jfw6 + +## [3.0.9] - 2024-01-31 + +- Fix incorrect content-length header that was emitted when `Rack::Response#write` was used in some situations. ([#2150](https://github.com/rack/rack/pull/2150), [@mattbrictson](https://github.com/mattbrictson)) + +## [3.0.8] - 2023-06-14 + +- Fix some unused variable verbose warnings. ([#2084](https://github.com/rack/rack/pull/2084), [@jeremyevans], [@skipkayhil](https://github.com/skipkayhil)) + +## [3.0.7] - 2023-03-16 + +- Make query parameters without `=` have `nil` values. ([#2059](https://github.com/rack/rack/pull/2059), [@jeremyevans]) + +## [3.0.6.1] - 2023-03-13 + +### Security + +- [CVE-2023-27539] Avoid ReDoS in header parsing + +## [3.0.6] - 2023-03-13 + +- Add `QueryParser#missing_value` for handling missing values + tests. ([#2052](https://github.com/rack/rack/pull/2052), [@ioquatix]) + +## [3.0.5] - 2023-03-13 + +- Split form/query parsing into two steps. ([#2038](https://github.com/rack/rack/pull/2038), [@matthewd](https://github.com/matthewd)) + +## [3.0.4.2] - 2023-03-02 + +### Security + +- [CVE-2023-27530] Introduce multipart_total_part_limit to limit total parts + +## [3.0.4.1] - 2023-01-17 + +### Security + +- [CVE-2022-44571] Fix ReDoS vulnerability in multipart parser +- [CVE-2022-44570] Fix ReDoS in Rack::Utils.get_byte_ranges +- [CVE-2022-44572] Forbid control characters in attributes (also ReDoS) + +## [3.0.4] - 2023-01-17 + +- `Rack::Request#POST` should consistently raise errors. Cache errors that occur when invoking `Rack::Request#POST` so they can be raised again later. ([#2010](https://github.com/rack/rack/pull/2010), [@ioquatix]) +- Fix `Rack::Lint` error message for `HTTP_CONTENT_TYPE` and `HTTP_CONTENT_LENGTH`. ([#2007](https://github.com/rack/rack/pull/2007), [@byroot](https://github.com/byroot)) +- Extend `Rack::MethodOverride` to handle `QueryParser::ParamsTooDeepError` error. ([#2006](https://github.com/rack/rack/pull/2006), [@byroot](https://github.com/byroot)) + +## [3.0.3] - 2022-12-27 + +### Fixed + +- `Rack::URLMap` uses non-deprecated form of `Regexp.new`. ([#1998](https://github.com/rack/rack/pull/1998), [@weizheheng](https://github.com/weizheheng)) + +## [3.0.2] - 2022-12-05 + +### Fixed + +- `Utils.build_nested_query` URL-encodes nested field names including the square brackets. +- Allow `Rack::Response` to pass through streaming bodies. ([#1993](https://github.com/rack/rack/pull/1993), [@ioquatix]) + +## [3.0.1] - 2022-11-18 + +### Fixed + +- `MethodOverride` does not look for an override if a request does not include form/parseable data. +- `Rack::Lint::Wrapper` correctly handles `respond_to?` with `to_ary`, `each`, `call` and `to_path`, forwarding to the body. ([#1981](https://github.com/rack/rack/pull/1981), [@ioquatix]) + +## [3.0.0] - 2022-09-06 + +- No changes + +## [3.0.0.rc1] - 2022-09-04 + +### SPEC Changes + +- Stream argument must implement `<<` https://github.com/rack/rack/pull/1959 +- `close` may be called on `rack.input` https://github.com/rack/rack/pull/1956 +- `rack.response_finished` may be used for executing code after the response has been finished https://github.com/rack/rack/pull/1952 + +## [3.0.0.beta1] - 2022-08-08 + +### Security + +- Do not use semicolon as GET parameter separator. ([#1733](https://github.com/rack/rack/pull/1733), [@jeremyevans]) + +### SPEC Changes + +- Response array must now be non-frozen. +- Response `status` must now be an integer greater than or equal to 100. +- Response `headers` must now be an unfrozen hash. +- Response header keys can no longer include uppercase characters. +- Response header values can be an `Array` to handle multiple values (and no longer supports `\n` encoded headers). +- Response body can now respond to `#call` (streaming body) instead of `#each` (enumerable body), for the equivalent of response hijacking in previous versions. +- Middleware must no longer call `#each` on the body, but they can call `#to_ary` on the body if it responds to `#to_ary`. +- `rack.input` is no longer required to be rewindable. +- `rack.multithread`/`rack.multiprocess`/`rack.run_once`/`rack.version` are no longer required environment keys. +- `SERVER_PROTOCOL` is now a required environment key, matching the HTTP protocol used in the request. +- `rack.hijack?` (partial hijack) and `rack.hijack` (full hijack) are now independently optional. +- `rack.hijack_io` has been removed completely. +- `rack.response_finished` is an optional environment key which contains an array of callable objects that must accept `#call(env, status, headers, error)` and are invoked after the response is finished (either successfully or unsuccessfully). +- It is okay to call `#close` on `rack.input` to indicate that you no longer need or care about the input. +- The stream argument supplied to the streaming body and hijack must support `#<<` for writing output. + +### Removed + +- Remove `rack.multithread`/`rack.multiprocess`/`rack.run_once`. These variables generally come too late to be useful. ([#1720](https://github.com/rack/rack/pull/1720), [@ioquatix], [@jeremyevans])) +- Remove deprecated Rack::Request::SCHEME_WHITELIST. ([@jeremyevans]) +- Remove internal cookie deletion using pattern matching, there are very few practical cases where it would be useful and browsers handle it correctly without us doing anything special. ([#1844](https://github.com/rack/rack/pull/1844), [@ioquatix]) +- Remove `rack.version` as it comes too late to be useful. ([#1938](https://github.com/rack/rack/pull/1938), [@ioquatix]) +- Extract `rackup` command, `Rack::Server`, `Rack::Handler` and related code into a separate gem. ([#1937](https://github.com/rack/rack/pull/1937), [@ioquatix]) + +### Added + +- `Rack::Headers` added to support lower-case header keys. ([@jeremyevans]) +- `Rack::Utils#set_cookie_header` now supports `escape_key: false` to avoid key escaping. ([@jeremyevans]) +- `Rack::RewindableInput` supports size. ([@ahorek](https://github.com/ahorek)) +- `Rack::RewindableInput::Middleware` added for making `rack.input` rewindable. ([@jeremyevans]) +- The RFC 7239 Forwarded header is now supported and considered by default when looking for information on forwarding, falling back to the X-Forwarded-* headers. `Rack::Request.forwarded_priority` accessor has been added for configuring the priority of which header to check. ([#1423](https://github.com/rack/rack/issues/1423), [@jeremyevans]) +- Allow response headers to contain array of values. ([#1598](https://github.com/rack/rack/issues/1598), [@ioquatix]) +- Support callable body for explicit streaming support and clarify streaming response body behaviour. ([#1745](https://github.com/rack/rack/pull/1745), [@ioquatix], [#1748](https://github.com/rack/rack/pull/1748), [@wjordan]) +- Allow `Rack::Builder#run` to take a block instead of an argument. ([#1942](https://github.com/rack/rack/pull/1942), [@ioquatix]) +- Add `rack.response_finished` to `Rack::Lint`. ([#1802](https://github.com/rack/rack/pull/1802), [@BlakeWilliams], [#1952](https://github.com/rack/rack/pull/1952), [@ioquatix]) +- The stream argument must implement `#<<`. ([#1959](https://github.com/rack/rack/pull/1959), [@ioquatix]) + +### Changed + +- BREAKING CHANGE: Require `status` to be an Integer. ([#1662](https://github.com/rack/rack/pull/1662), [@olleolleolle](https://github.com/olleolleolle)) +- BREAKING CHANGE: Query parsing now treats parameters without `=` as having the empty string value instead of nil value, to conform to the URL spec. ([#1696](https://github.com/rack/rack/issues/1696), [@jeremyevans]) +- Relax validations around `Rack::Request#host` and `Rack::Request#hostname`. ([#1606](https://github.com/rack/rack/issues/1606), [@pvande](https://github.com/pvande)) +- Removed antiquated handlers: FCGI, LSWS, SCGI, Thin. ([#1658](https://github.com/rack/rack/pull/1658), [@ioquatix]) +- Removed options from `Rack::Builder.parse_file` and `Rack::Builder.load_file`. ([#1663](https://github.com/rack/rack/pull/1663), [@ioquatix]) +- `Rack::HTTP_VERSION` has been removed and the `HTTP_VERSION` env setting is no longer set in the CGI and Webrick handlers. ([#970](https://github.com/rack/rack/issues/970), [@jeremyevans]) +- `Rack::Request#[]` and `#[]=` now warn even in non-verbose mode. ([#1277](https://github.com/rack/rack/issues/1277), [@jeremyevans]) +- Decrease default allowed parameter recursion level from 100 to 32. ([#1640](https://github.com/rack/rack/issues/1640), [@jeremyevans]) +- Attempting to parse a multipart response with an empty body now raises Rack::Multipart::EmptyContentError. ([#1603](https://github.com/rack/rack/issues/1603), [@jeremyevans]) +- `Rack::Utils.secure_compare` uses OpenSSL's faster implementation if available. ([#1711](https://github.com/rack/rack/pull/1711), [@bdewater](https://github.com/bdewater)) +- `Rack::Request#POST` now caches an empty hash if input content type is not parseable. ([#749](https://github.com/rack/rack/pull/749), [@jeremyevans]) +- BREAKING CHANGE: Updated `trusted_proxy?` to match full 127.0.0.0/8 network. ([#1781](https://github.com/rack/rack/pull/1781), [@snbloch](https://github.com/snbloch)) +- Explicitly deprecate `Rack::File` which was an alias for `Rack::Files`. ([#1811](https://github.com/rack/rack/pull/1720), [@ioquatix]). +- Moved `Rack::Session` into [separate gem](https://github.com/rack/rack-session). ([#1805](https://github.com/rack/rack/pull/1805), [@ioquatix]) +- `rackup -D` option to daemonizes no longer changes the working directory to the root. ([#1813](https://github.com/rack/rack/pull/1813), [@jeremyevans]) +- The `x-forwarded-proto` header is now considered before the `x-forwarded-scheme` header for determining the forwarded protocol. `Rack::Request.x_forwarded_proto_priority` accessor has been added for configuring the priority of which header to check. ([#1809](https://github.com/rack/rack/issues/1809), [@jeremyevans]) +- `Rack::Request.forwarded_authority` (and methods that call it, such as `host`) now returns the last authority in the forwarded header, instead of the first, as earlier forwarded authorities can be forged by clients. This restores the Rack 2.1 behavior. ([#1829](https://github.com/rack/rack/issues/1809), [@jeremyevans]) +- Use lower case cookie attributes when creating cookies, and fold cookie attributes to lower case when reading cookies (specifically impacting `secure` and `httponly` attributes). ([#1849](https://github.com/rack/rack/pull/1849), [@ioquatix]) +- The response array must now be mutable (non-frozen) so middleware can modify it without allocating a new Array,therefore reducing object allocations. ([#1887](https://github.com/rack/rack/pull/1887), [#1927](https://github.com/rack/rack/pull/1927), [@amatsuda], [@ioquatix]) +- `rack.hijack?` (partial hijack) and `rack.hijack` (full hijack) are now independently optional. `rack.hijack_io` is no longer required/specified. ([#1939](https://github.com/rack/rack/pull/1939), [@ioquatix]) +- Allow calling close on `rack.input`. ([#1956](https://github.com/rack/rack/pull/1956), [@ioquatix]) + +### Fixed + +- Make Rack::MockResponse handle non-hash headers. ([#1629](https://github.com/rack/rack/issues/1629), [@jeremyevans]) +- TempfileReaper now deletes temp files if application raises an exception. ([#1679](https://github.com/rack/rack/issues/1679), [@jeremyevans]) +- Handle cookies with values that end in '=' ([#1645](https://github.com/rack/rack/pull/1645), [@lukaso](https://github.com/lukaso)) +- Make `Rack::NullLogger` respond to `#fatal!` [@jeremyevans]) +- Fix multipart filename generation for filenames that contain spaces. Encode spaces as "%20" instead of "+" which will be decoded properly by the multipart parser. ([#1736](https://github.com/rack/rack/pull/1645), [@muirdm](https://github.com/muirdm)) +- `Rack::Request#scheme` returns `ws` or `wss` when one of the `X-Forwarded-Scheme` / `X-Forwarded-Proto` headers is set to `ws` or `wss`, respectively. ([#1730](https://github.com/rack/rack/issues/1730), [@erwanst](https://github.com/erwanst)) + +## [2.2.16] - 2025-05-22 + +- Fix incorrect backport of optional `CGI::Cookie` support. ([#2335](https://github.com/rack/rack/pull/2335), [@jeremyevans]) + +## [2.2.15] - 2025-05-18 + +- Optional support for `CGI::Cookie` if not available. ([#2327](https://github.com/rack/rack/pull/2327), [#2333](https://github.com/rack/rack/pull/2333), [@earlopain]) + +## [2.2.14] - 2025-05-06 + +### Security + +- [CVE-2025-46727](https://github.com/rack/rack/security/advisories/GHSA-gjh7-p2fx-99vx) Unbounded parameter parsing in `Rack::QueryParser` can lead to memory exhaustion. + +## [2.2.13] - 2025-03-11 + +### Security + +- [CVE-2025-27610](https://github.com/rack/rack/security/advisories/GHSA-7wqh-767x-r66v) Local file inclusion in `Rack::Static`. + +## [2.2.12] - 2025-03-04 + +### Security + +- [CVE-2025-27111](https://github.com/rack/rack/security/advisories/GHSA-8cgq-6mh2-7j6v) Possible Log Injection in `Rack::Sendfile`. + +## [2.2.11] - 2025-02-12 + +### Security + +- [CVE-2025-25184](https://github.com/rack/rack/security/advisories/GHSA-7g2v-jj9q-g3rg) Possible Log Injection in `Rack::CommonLogger`. + +## [2.2.10] - 2024-10-14 + +- Fix compatibility issues with Ruby v3.4.0. ([#2248](https://github.com/rack/rack/pull/2248), [@byroot](https://github.com/byroot)) + +## [2.2.9] - 2023-03-21 + +- Return empty when parsing a multi-part POST with only one end delimiter. ([#2104](https://github.com/rack/rack/pull/2104), [@alpaca-tc]) + +## [2.2.8] - 2023-07-31 + +- Regenerate SPEC ([#2102](https://github.com/rack/rack/pull/2102), [@skipkayhil](https://github.com/skipkayhil)) +- Limit file extension length of multipart tempfiles ([#2015](https://github.com/rack/rack/pull/2015), [@dentarg](https://github.com/dentarg)) +- Fix "undefined method DelegateClass for Rack::Session::Cookie:Class" ([#2092](https://github.com/rack/rack/pull/2092), [@onigra](https://github.com/onigra) [@dchandekstark](https://github.com/dchandekstark)) + +## [2.2.7] - 2023-03-13 + +- Correct the year number in the changelog ([#2015](https://github.com/rack/rack/pull/2015), [@kimulab](https://github.com/kimulab)) +- Support underscore in host names for Rack 2.2 (Fixes [#2070](https://github.com/rack/rack/issues/2070)) ([#2015](https://github.com/rack/rack/pull/2071), [@jeremyevans](https://github.com/jeremyevans)) + +## [2.2.6.4] - 2023-03-13 + +- [CVE-2023-27539] Avoid ReDoS in header parsing + +## [2.2.6.3] - 2023-03-02 + +- [CVE-2023-27530] Introduce multipart_total_part_limit to limit total parts + +## [2.2.6.2] - 2023-01-17 + +- [CVE-2022-44570] Fix ReDoS in Rack::Utils.get_byte_ranges + +## [2.2.6.1] - 2023-01-17 + +- [CVE-2022-44571] Fix ReDoS vulnerability in multipart parser +- [CVE-2022-44572] Forbid control characters in attributes (also ReDoS) + +## [2.2.6] - 2023-01-17 + +- Extend `Rack::MethodOverride` to handle `QueryParser::ParamsTooDeepError` error. ([#2011](https://github.com/rack/rack/pull/2011), [@byroot](https://github.com/byroot)) + +## [2.2.5] - 2022-12-27 + +### Fixed + +- `Rack::URLMap` uses non-deprecated form of `Regexp.new`. ([#1998](https://github.com/rack/rack/pull/1998), [@weizheheng](https://github.com/weizheheng)) + +## [2.2.4] - 2022-06-30 + +- Better support for lower case headers in `Rack::ETag` middleware. ([#1919](https://github.com/rack/rack/pull/1919), [@ioquatix](https://github.com/ioquatix)) +- Use custom exception on params too deep error. ([#1838](https://github.com/rack/rack/pull/1838), [@simi](https://github.com/simi)) + +## [2.2.3.1] - 2022-05-27 + +### Security + +- [CVE-2022-30123] Fix shell escaping issue in Common Logger +- [CVE-2022-30122] Restrict parsing of broken MIME attachments + +## [2.2.3] - 2020-06-15 + +### Security + +- [[CVE-2020-8184](https://nvd.nist.gov/vuln/detail/CVE-2020-8184)] Do not allow percent-encoded cookie name to override existing cookie names. BREAKING CHANGE: Accessing cookie names that require URL encoding with decoded name no longer works. ([@fletchto99](https://github.com/fletchto99)) + +## [2.2.2] - 2020-02-11 + +### Fixed + +- Fix incorrect `Rack::Request#host` value. ([#1591](https://github.com/rack/rack/pull/1591), [@ioquatix]) +- Revert `Rack::Handler::Thin` implementation. ([#1583](https://github.com/rack/rack/pull/1583), [@jeremyevans]) +- Double assignment is still needed to prevent an "unused variable" warning. ([#1589](https://github.com/rack/rack/pull/1589), [@kamipo](https://github.com/kamipo)) +- Fix to handle same_site option for session pool. ([#1587](https://github.com/rack/rack/pull/1587), [@kamipo](https://github.com/kamipo)) + +## [2.2.1] - 2020-02-09 + +### Fixed + +- Rework `Rack::Request#ip` to handle empty `forwarded_for`. ([#1577](https://github.com/rack/rack/pull/1577), [@ioquatix]) + +## [2.2.0] - 2020-02-08 + +### SPEC Changes + +- `rack.session` request environment entry must respond to `to_hash` and return unfrozen Hash. ([@jeremyevans]) +- Request environment cannot be frozen. ([@jeremyevans]) +- CGI values in the request environment with non-ASCII characters must use ASCII-8BIT encoding. ([@jeremyevans]) +- Improve SPEC/lint relating to SERVER_NAME, SERVER_PORT and HTTP_HOST. ([#1561](https://github.com/rack/rack/pull/1561), [@ioquatix]) + +### Added + +- `rackup` supports multiple `-r` options and will require all arguments. ([@jeremyevans]) +- `Server` supports an array of paths to require for the `:require` option. ([@khotta](https://github.com/khotta)) +- `Files` supports multipart range requests. ([@fatkodima](https://github.com/fatkodima)) +- `Multipart::UploadedFile` supports an IO-like object instead of using the filesystem, using `:filename` and `:io` options. ([@jeremyevans]) +- `Multipart::UploadedFile` supports keyword arguments `:path`, `:content_type`, and `:binary` in addition to positional arguments. ([@jeremyevans]) +- `Static` supports a `:cascade` option for calling the app if there is no matching file. ([@jeremyevans]) +- `Session::Abstract::SessionHash#dig`. ([@jeremyevans]) +- `Response.[]` and `MockResponse.[]` for creating instances using status, headers, and body. ([@ioquatix]) +- Convenient cache and content type methods for `Rack::Response`. ([#1555](https://github.com/rack/rack/pull/1555), [@ioquatix]) + +### Changed + +- `Request#params` no longer rescues EOFError. ([@jeremyevans]) +- `Directory` uses a streaming approach, significantly improving time to first byte for large directories. ([@jeremyevans]) +- `Directory` no longer includes a Parent directory link in the root directory index. ([@jeremyevans]) +- `QueryParser#parse_nested_query` uses original backtrace when reraising exception with new class. ([@jeremyevans]) +- `ConditionalGet` follows RFC 7232 precedence if both If-None-Match and If-Modified-Since headers are provided. ([@jeremyevans]) +- `.ru` files supports the `frozen-string-literal` magic comment. ([@eregon](https://github.com/eregon)) +- Rely on autoload to load constants instead of requiring internal files, make sure to require 'rack' and not just 'rack/...'. ([@jeremyevans]) +- BREAKING CHANGE: `Etag` will continue sending ETag even if the response should not be cached. Streaming no longer works without a workaround, see [#1619](https://github.com/rack/rack/issues/1619#issuecomment-848460528). ([@henm](https://github.com/henm)) +- `Request#host_with_port` no longer includes a colon for a missing or empty port. ([@AlexWayfer](https://github.com/AlexWayfer)) +- All handlers uses keywords arguments instead of an options hash argument. ([@ioquatix]) +- `Files` handling of range requests no longer return a body that supports `to_path`, to ensure range requests are handled correctly. ([@jeremyevans]) +- `Multipart::Generator` only includes `Content-Length` for files with paths, and `Content-Disposition` `filename` if the `UploadedFile` instance has one. ([@jeremyevans]) +- `Request#ssl?` is true for the `wss` scheme (secure websockets). ([@jeremyevans]) +- `Rack::HeaderHash` is memoized by default. ([#1549](https://github.com/rack/rack/pull/1549), [@ioquatix]) +- `Rack::Directory` allow directory traversal inside root directory. ([#1417](https://github.com/rack/rack/pull/1417), [@ThomasSevestre](https://github.com/ThomasSevestre)) +- Sort encodings by server preference. ([#1184](https://github.com/rack/rack/pull/1184), [@ioquatix], [@wjordan](https://github.com/wjordan)) +- Rework host/hostname/authority implementation in `Rack::Request`. `#host` and `#host_with_port` have been changed to correctly return IPv6 addresses formatted with square brackets, as defined by [RFC3986](https://tools.ietf.org/html/rfc3986#section-3.2.2). ([#1561](https://github.com/rack/rack/pull/1561), [@ioquatix]) +- `Rack::Builder` parsing options on first `#\` line is deprecated. ([#1574](https://github.com/rack/rack/pull/1574), [@ioquatix]) + +### Removed + +- `Directory#path` as it was not used and always returned nil. ([@jeremyevans]) +- `BodyProxy#each` as it was only needed to work around a bug in Ruby <1.9.3. ([@jeremyevans]) +- `URLMap::INFINITY` and `URLMap::NEGATIVE_INFINITY`, in favor of `Float::INFINITY`. ([@ch1c0t](https://github.com/ch1c0t)) +- Deprecation of `Rack::File`. It will be deprecated again in rack 2.2 or 3.0. ([@rafaelfranca](https://github.com/rafaelfranca)) +- Support for Ruby 2.2 as it is well past EOL. ([@ioquatix]) +- Remove `Rack::Files#response_body` as the implementation was broken. ([#1153](https://github.com/rack/rack/pull/1153), [@ioquatix]) +- Remove `SERVER_ADDR` which was never part of the original SPEC. ([#1573](https://github.com/rack/rack/pull/1573), [@ioquatix]) + +### Fixed + +- `Directory` correctly handles root paths containing glob metacharacters. ([@jeremyevans]) +- `Cascade` uses a new response object for each call if initialized with no apps. ([@jeremyevans]) +- `BodyProxy` correctly delegates keyword arguments to the body object on Ruby 2.7+. ([@jeremyevans]) +- `BodyProxy#method` correctly handles methods delegated to the body object. ([@jeremyevans]) +- `Request#host` and `Request#host_with_port` handle IPv6 addresses correctly. ([@AlexWayfer](https://github.com/AlexWayfer)) +- `Lint` checks when response hijacking that `rack.hijack` is called with a valid object. ([@jeremyevans]) +- `Response#write` correctly updates `Content-Length` if initialized with a body. ([@jeremyevans]) +- `CommonLogger` includes `SCRIPT_NAME` when logging. ([@Erol](https://github.com/Erol)) +- `Utils.parse_nested_query` correctly handles empty queries, using an empty instance of the params class instead of a hash. ([@jeremyevans]) +- `Directory` correctly escapes paths in links. ([@yous](https://github.com/yous)) +- `Request#delete_cookie` and related `Utils` methods handle `:domain` and `:path` options in same call. ([@jeremyevans]) +- `Request#delete_cookie` and related `Utils` methods do an exact match on `:domain` and `:path` options. ([@jeremyevans]) +- `Static` no longer adds headers when a gzipped file request has a 304 response. ([@chooh](https://github.com/chooh)) +- `ContentLength` sets `Content-Length` response header even for bodies not responding to `to_ary`. ([@jeremyevans]) +- Thin handler supports options passed directly to `Thin::Controllers::Controller`. ([@jeremyevans]) +- WEBrick handler no longer ignores `:BindAddress` option. ([@jeremyevans]) +- `ShowExceptions` handles invalid POST data. ([@jeremyevans]) +- Basic authentication requires a password, even if the password is empty. ([@jeremyevans]) +- `Lint` checks response is array with 3 elements, per SPEC. ([@jeremyevans]) +- Support for using `:SSLEnable` option when using WEBrick handler. (Gregor Melhorn) +- Close response body after buffering it when buffering. ([@ioquatix]) +- Only accept `;` as delimiter when parsing cookies. ([@mrageh](https://github.com/mrageh)) +- `Utils::HeaderHash#clear` clears the name mapping as well. ([@raxoft](https://github.com/raxoft)) +- Support for passing `nil` `Rack::Files.new`, which notably fixes Rails' current `ActiveStorage::FileServer` implementation. ([@ioquatix]) + +### Documentation + +- CHANGELOG updates. ([@aupajo](https://github.com/aupajo)) +- Added [CONTRIBUTING](CONTRIBUTING.md). ([@dblock](https://github.com/dblock)) + +## [2.0.9] - 2020-02-08 + +- Handle case where session id key is requested but missing ([@jeremyevans]) +- Restore support for code relying on `SessionId#to_s`. ([@jeremyevans]) +- Add support for `SameSite=None` cookie value. ([@hennikul](https://github.com/hennikul)) + +## [2.1.2] - 2020-01-27 + +- Fix multipart parser for some files to prevent denial of service ([@aiomaster](https://github.com/aiomaster)) +- Fix `Rack::Builder#use` with keyword arguments ([@kamipo](https://github.com/kamipo)) +- Skip deflating in Rack::Deflater if Content-Length is 0 ([@jeremyevans]) +- Remove `SessionHash#transform_keys`, no longer needed ([@pavel](https://github.com/pavel)) +- Add to_hash to wrap Hash and Session classes ([@oleh-demyanyuk](https://github.com/oleh-demyanyuk)) +- Handle case where session id key is requested but missing ([@jeremyevans]) + +## [2.1.1] - 2020-01-12 + +- Remove `Rack::Chunked` from `Rack::Server` default middleware. ([#1475](https://github.com/rack/rack/pull/1475), [@ioquatix]) +- Restore support for code relying on `SessionId#to_s`. ([@jeremyevans]) + +## [2.1.0] - 2020-01-10 + +### Added + +- Add support for `SameSite=None` cookie value. ([@hennikul](https://github.com/hennikul)) +- Add trailer headers. ([@eileencodes](https://github.com/eileencodes)) +- Add MIME Types for video streaming. ([@styd](https://github.com/styd)) +- Add MIME Type for WASM. ([@buildrtech](https://github.com/buildrtech)) +- Add `Early Hints(103)` to status codes. ([@egtra](https://github.com/egtra)) +- Add `Too Early(425)` to status codes. ([@y-yagi]((https://github.com/y-yagi))) +- Add `Bandwidth Limit Exceeded(509)` to status codes. ([@CJKinni](https://github.com/CJKinni)) +- Add method for custom `ip_filter`. ([@svcastaneda](https://github.com/svcastaneda)) +- Add boot-time profiling capabilities to `rackup`. ([@tenderlove](https://github.com/tenderlove)) +- Add multi mapping support for `X-Accel-Mappings` header. ([@yoshuki](https://github.com/yoshuki)) +- Add `sync: false` option to `Rack::Deflater`. (Eric Wong) +- Add `Builder#freeze_app` to freeze application and all middleware instances. ([@jeremyevans]) +- Add API to extract cookies from `Rack::MockResponse`. ([@petercline](https://github.com/petercline)) + +### Changed + +- Don't propagate nil values from middleware. ([@ioquatix]) +- Lazily initialize the response body and only buffer it if required. ([@ioquatix]) +- Fix deflater zlib buffer errors on empty body part. ([@felixbuenemann](https://github.com/felixbuenemann)) +- Set `X-Accel-Redirect` to percent-encoded path. ([@diskkid](https://github.com/diskkid)) +- Remove unnecessary buffer growing when parsing multipart. ([@tainoe](https://github.com/tainoe)) +- Expand the root path in `Rack::Static` upon initialization. ([@rosenfeld](https://github.com/rosenfeld)) +- Make `ShowExceptions` work with binary data. ([@axyjo](https://github.com/axyjo)) +- Use buffer string when parsing multipart requests. ([@janko-m](https://github.com/janko-m)) +- Support optional UTF-8 Byte Order Mark (BOM) in config.ru. ([@mikegee](https://github.com/mikegee)) +- Handle `X-Forwarded-For` with optional port. ([@dpritchett](https://github.com/dpritchett)) +- Use `Time#httpdate` format for Expires, as proposed by RFC 7231. ([@nanaya](https://github.com/nanaya)) +- Make `Utils.status_code` raise an error when the status symbol is invalid instead of `500`. ([@adambutler](https://github.com/adambutler)) +- Rename `Request::SCHEME_WHITELIST` to `Request::ALLOWED_SCHEMES`. +- Make `Multipart::Parser.get_filename` accept files with `+` in their name. ([@lucaskanashiro](https://github.com/lucaskanashiro)) +- Add Falcon to the default handler fallbacks. ([@ioquatix]) +- Update codebase to avoid string mutations in preparation for `frozen_string_literals`. ([@pat](https://github.com/pat)) +- Change `MockRequest#env_for` to rely on the input optionally responding to `#size` instead of `#length`. ([@janko](https://github.com/janko)) +- Rename `Rack::File` -> `Rack::Files` and add deprecation notice. ([@postmodern](https://github.com/postmodern)) +- Prefer Base64 “strict encoding” for Base64 cookies. ([@ioquatix]) + +### Removed + +- BREAKING CHANGE: Remove `to_ary` from Response ([@tenderlove](https://github.com/tenderlove)) +- Deprecate `Rack::Session::Memcache` in favor of `Rack::Session::Dalli` from dalli gem ([@fatkodima](https://github.com/fatkodima)) + +### Fixed + +- Eliminate warnings for Ruby 2.7. ([@osamtimizer](https://github.com/osamtimizer])) + +### Documentation + +- Update broken example in `Session::Abstract::ID` documentation. ([tonytonyjan](https://github.com/tonytonyjan)) +- Add Padrino to the list of frameworks implementing Rack. ([@wikimatze](https://github.com/wikimatze)) +- Remove Mongrel from the suggested server options in the help output. ([@tricknotes](https://github.com/tricknotes)) +- Replace `HISTORY.md` and `NEWS.md` with `CHANGELOG.md`. ([@twitnithegirl](https://github.com/twitnithegirl)) +- CHANGELOG updates. ([@drenmi](https://github.com/Drenmi), [@p8](https://github.com/p8)) + +## [2.0.8] - 2019-12-08 + +### Security + +- [[CVE-2019-16782](https://nvd.nist.gov/vuln/detail/CVE-2019-16782)] Prevent timing attacks targeted at session ID lookup. BREAKING CHANGE: Session ID is now a SessionId instance instead of a String. ([@tenderlove](https://github.com/tenderlove), [@rafaelfranca](https://github.com/rafaelfranca)) + +## [1.6.12] - 2019-12-08 + +### Security + +- [[CVE-2019-16782](https://nvd.nist.gov/vuln/detail/CVE-2019-16782)] Prevent timing attacks targeted at session ID lookup. BREAKING CHANGE: Session ID is now a SessionId instance instead of a String. ([@tenderlove](https://github.com/tenderlove), [@rafaelfranca](https://github.com/rafaelfranca)) + +## [2.0.7] - 2019-04-02 + +### Fixed + +- Remove calls to `#eof?` on Rack input in `Multipart::Parser`, as this breaks the specification. ([@matthewd](https://github.com/matthewd)) +- Preserve forwarded IP addresses for trusted proxy chains. ([@SamSaffron](https://github.com/SamSaffron)) + +## [2.0.6] - 2018-11-05 + +### Fixed + +- [[CVE-2018-16470](https://nvd.nist.gov/vuln/detail/CVE-2018-16470)] Reduce buffer size of `Multipart::Parser` to avoid pathological parsing. ([@tenderlove](https://github.com/tenderlove)) +- Fix a call to a non-existing method `#accepts_html` in the `ShowExceptions` middleware. ([@tomelm](https://github.com/tomelm)) +- [[CVE-2018-16471](https://nvd.nist.gov/vuln/detail/CVE-2018-16471)] Whitelist HTTP and HTTPS schemes in `Request#scheme` to prevent a possible XSS attack. ([@PatrickTulskie](https://github.com/PatrickTulskie)) + +## [2.0.5] - 2018-04-23 + +### Fixed + +- Record errors originating from invalid UTF8 in `MethodOverride` middleware instead of breaking. ([@mclark](https://github.com/mclark)) + +## [2.0.4] - 2018-01-31 + +### Changed + +- Ensure the `Lock` middleware passes the original `env` object. ([@lugray](https://github.com/lugray)) +- Improve performance of `Multipart::Parser` when uploading large files. ([@tompng](https://github.com/tompng)) +- Increase buffer size in `Multipart::Parser` for better performance. ([@jkowens](https://github.com/jkowens)) +- Reduce memory usage of `Multipart::Parser` when uploading large files. ([@tompng](https://github.com/tompng)) +- Replace ConcurrentRuby dependency with native `Queue`. ([@devmchakan](https://github.com/devmchakan)) + +### Fixed + +- Require the correct digest algorithm in the `ETag` middleware. ([@matthewd](https://github.com/matthewd)) + +### Documentation + +- Update homepage links to use SSL. ([@hugoabonizio](https://github.com/hugoabonizio)) + +## [2.0.3] - 2017-05-15 + +### Changed + +- Ensure `env` values are ASCII 8-bit encoded. ([@eileencodes](https://github.com/eileencodes)) + +### Fixed + +- Prevent exceptions when a class with mixins inherits from `Session::Abstract::ID`. ([@jnraine](https://github.com/jnraine)) + +## [2.0.2] - 2017-05-08 + +### Added + +- Allow `Session::Abstract::SessionHash#fetch` to accept a block with a default value. ([@yannvanhalewyn](https://github.com/yannvanhalewyn)) +- Add `Builder#freeze_app` to freeze application and all middleware. ([@jeremyevans]) + +### Changed + +- Freeze default session options to avoid accidental mutation. ([@kirs](https://github.com/kirs)) +- Detect partial hijack without hash headers. ([@devmchakan](https://github.com/devmchakan)) +- Update tests to use MiniTest 6 matchers. ([@tonytonyjan](https://github.com/tonytonyjan)) +- Allow 205 Reset Content responses to set a Content-Length, as RFC 7231 proposes setting this to 0. ([@devmchakan](https://github.com/devmchakan)) + +### Fixed + +- Handle `NULL` bytes in multipart filenames. ([@casperisfine](https://github.com/casperisfine)) +- Remove warnings due to miscapitalized global. ([@ioquatix]) +- Prevent exceptions caused by a race condition on multi-threaded servers. ([@sophiedeziel](https://github.com/sophiedeziel)) +- Add RDoc as an explicit dependency for `doc` group. ([@tonytonyjan](https://github.com/tonytonyjan)) +- Record errors originating from `Multipart::Parser` in the `MethodOverride` middleware instead of letting them bubble up. ([@carlzulauf](https://github.com/carlzulauf)) +- Remove remaining use of removed `Utils#bytesize` method from the `File` middleware. ([@brauliomartinezlm](https://github.com/brauliomartinezlm)) + +### Removed + +- Remove `deflate` encoding support to reduce caching overhead. ([@devmchakan](https://github.com/devmchakan)) + +### Documentation + +- Update broken example in `Deflater` documentation. ([@mwpastore](https://github.com/mwpastore)) + +## [2.0.1] - 2016-06-30 + +### Changed + +- Remove JSON as an explicit dependency. ([@mperham](https://github.com/mperham)) + + +# History/News Archive +Items below this line are from the previously maintained HISTORY.md and NEWS.md files. + +## [2.0.0.rc1] 2016-05-06 +- Rack::Session::Abstract::ID is deprecated. Please change to use Rack::Session::Abstract::Persisted + +## [2.0.0.alpha] 2015-12-04 +- First-party "SameSite" cookies. Browsers omit SameSite cookies from third-party requests, closing the door on many CSRF attacks. +- Pass `same_site: true` (or `:strict`) to enable: response.set_cookie 'foo', value: 'bar', same_site: true or `same_site: :lax` to use Lax enforcement: response.set_cookie 'foo', value: 'bar', same_site: :lax +- Based on version 7 of the Same-site Cookies internet draft: + https://tools.ietf.org/html/draft-west-first-party-cookies-07 +- Thanks to Ben Toews (@mastahyeti) and Bob Long (@bobjflong) for updating to drafts 5 and 7. +- Add `Rack::Events` middleware for adding event based middleware: middleware that does not care about the response body, but only cares about doing work at particular points in the request / response lifecycle. +- Add `Rack::Request#authority` to calculate the authority under which the response is being made (this will be handy for h2 pushes). +- Add `Rack::Response::Helpers#cache_control` and `cache_control=`. Use this for setting cache control headers on your response objects. +- Add `Rack::Response::Helpers#etag` and `etag=`. Use this for setting etag values on the response. +- Introduce `Rack::Response::Helpers#add_header` to add a value to a multi-valued response header. Implemented in terms of other `Response#*_header` methods, so it's available to any response-like class that includes the `Helpers` module. +- Add `Rack::Request#add_header` to match. +- `Rack::Session::Abstract::ID` IS DEPRECATED. Please switch to `Rack::Session::Abstract::Persisted`. `Rack::Session::Abstract::Persisted` uses a request object rather than the `env` hash. +- Pull `ENV` access inside the request object in to a module. This will help with legacy Request objects that are ENV based but don't want to inherit from Rack::Request +- Move most methods on the `Rack::Request` to a module `Rack::Request::Helpers` and use public API to get values from the request object. This enables users to mix `Rack::Request::Helpers` in to their own objects so they can implement `(get|set|fetch|each)_header` as they see fit (for example a proxy object). +- Files and directories with + in the name are served correctly. Rather than unescaping paths like a form, we unescape with a URI parser using `Rack::Utils.unescape_path`. Fixes #265 +- Tempfiles are automatically closed in the case that there were too + many posted. +- Added methods for manipulating response headers that don't assume + they're stored as a Hash. Response-like classes may include the + Rack::Response::Helpers module if they define these methods: + - Rack::Response#has_header? + - Rack::Response#get_header + - Rack::Response#set_header + - Rack::Response#delete_header +- Introduce Util.get_byte_ranges that will parse the value of the HTTP_RANGE string passed to it without depending on the `env` hash. `byte_ranges` is deprecated in favor of this method. +- Change Session internals to use Request objects for looking up session information. This allows us to only allocate one request object when dealing with session objects (rather than doing it every time we need to manipulate cookies, etc). +- Add `Rack::Request#initialize_copy` so that the env is duped when the request gets duped. +- Added methods for manipulating request specific data. This includes + data set as CGI parameters, and just any arbitrary data the user wants + to associate with a particular request. New methods: + - Rack::Request#has_header? + - Rack::Request#get_header + - Rack::Request#fetch_header + - Rack::Request#each_header + - Rack::Request#set_header + - Rack::Request#delete_header +- lib/rack/utils.rb: add a method for constructing "delete" cookie + headers. This allows us to construct cookie headers without depending + on the side effects of mutating a hash. +- Prevent extremely deep parameters from being parsed. CVE-2015-3225 + +## [1.6.1] 2015-05-06 + - Fix CVE-2014-9490, denial of service attack in OkJson + - Use a monotonic time for Rack::Runtime, if available + - RACK_MULTIPART_LIMIT changed to RACK_MULTIPART_PART_LIMIT (RACK_MULTIPART_LIMIT is deprecated and will be removed in 1.7.0) + +## [1.5.3] 2015-05-06 + - Fix CVE-2014-9490, denial of service attack in OkJson + - Backport bug fixes to 1.5 series + +## [1.6.0] 2014-01-18 + - Response#unauthorized? helper + - Deflater now accepts an options hash to control compression on a per-request level + - Builder#warmup method for app preloading + - Request#accept_language method to extract HTTP_ACCEPT_LANGUAGE + - Add quiet mode of rack server, rackup --quiet + - Update HTTP Status Codes to RFC 7231 + - Less strict header name validation according to RFC 2616 + - SPEC updated to specify headers conform to RFC7230 specification + - Etag correctly marks etags as weak + - Request#port supports multiple x-http-forwarded-proto values + - Utils#multipart_part_limit configures the maximum number of parts a request can contain + - Default host to localhost when in development mode + - Various bugfixes and performance improvements + +## [1.5.2] 2013-02-07 + - Fix CVE-2013-0263, timing attack against Rack::Session::Cookie + - Fix CVE-2013-0262, symlink path traversal in Rack::File + - Add various methods to Session for enhanced Rails compatibility + - Request#trusted_proxy? now only matches whole strings + - Add JSON cookie coder, to be default in Rack 1.6+ due to security concerns + - URLMap host matching in environments that don't set the Host header fixed + - Fix a race condition that could result in overwritten pidfiles + - Various documentation additions + +## [1.4.5] 2013-02-07 + - Fix CVE-2013-0263, timing attack against Rack::Session::Cookie + - Fix CVE-2013-0262, symlink path traversal in Rack::File + +## [1.1.6, 1.2.8, 1.3.10] 2013-02-07 + - Fix CVE-2013-0263, timing attack against Rack::Session::Cookie + +## [1.5.1] 2013-01-28 + - Rack::Lint check_hijack now conforms to other parts of SPEC + - Added hash-like methods to Abstract::ID::SessionHash for compatibility + - Various documentation corrections + +## [1.5.0] 2013-01-21 + - Introduced hijack SPEC, for before-response and after-response hijacking + - SessionHash is no longer a Hash subclass + - Rack::File cache_control parameter is removed, in place of headers options + - Rack::Auth::AbstractRequest#scheme now yields strings, not symbols + - Rack::Utils cookie functions now format expires in RFC 2822 format + - Rack::File now has a default mime type + - rackup -b 'run Rack::Files.new(".")', option provides command line configs + - Rack::Deflater will no longer double encode bodies + - Rack::Mime#match? provides convenience for Accept header matching + - Rack::Utils#q_values provides splitting for Accept headers + - Rack::Utils#best_q_match provides a helper for Accept headers + - Rack::Handler.pick provides convenience for finding available servers + - Puma added to the list of default servers (preferred over Webrick) + - Various middleware now correctly close body when replacing it + - Rack::Request#params is no longer persistent with only GET params + - Rack::Request#update_param and #delete_param provide persistent operations + - Rack::Request#trusted_proxy? now returns true for local unix sockets + - Rack::Response no longer forces Content-Types + - Rack::Sendfile provides local mapping configuration options + - Rack::Utils#rfc2109 provides old netscape style time output + - Updated HTTP status codes + - Ruby 1.8.6 likely no longer passes tests, and is no longer fully supported + +## [1.4.4, 1.3.9, 1.2.7, 1.1.5] 2013-01-13 + - [SEC] Rack::Auth::AbstractRequest no longer symbolizes arbitrary strings + - Fixed erroneous test case in the 1.3.x series + +## [1.4.3] 2013-01-07 + - Security: Prevent unbounded reads in large multipart boundaries + +## [1.3.8] 2013-01-07 + - Security: Prevent unbounded reads in large multipart boundaries + +## [1.4.2] 2013-01-06 + - Add warnings when users do not provide a session secret + - Fix parsing performance for unquoted filenames + - Updated URI backports + - Fix URI backport version matching, and silence constant warnings + - Correct parameter parsing with empty values + - Correct rackup '-I' flag, to allow multiple uses + - Correct rackup pidfile handling + - Report rackup line numbers correctly + - Fix request loops caused by non-stale nonces with time limits + - Fix reloader on Windows + - Prevent infinite recursions from Response#to_ary + - Various middleware better conforms to the body close specification + - Updated language for the body close specification + - Additional notes regarding ECMA escape compatibility issues + - Fix the parsing of multiple ranges in range headers + - Prevent errors from empty parameter keys + - Added PATCH verb to Rack::Request + - Various documentation updates + - Fix session merge semantics (fixes rack-test) + - Rack::Static :index can now handle multiple directories + - All tests now utilize Rack::Lint (special thanks to Lars Gierth) + - Rack::File cache_control parameter is now deprecated, and removed by 1.5 + - Correct Rack::Directory script name escaping + - Rack::Static supports header rules for sophisticated configurations + - Multipart parsing now works without a Content-Length header + - New logos courtesy of Zachary Scott! + - Rack::BodyProxy now explicitly defines #each, useful for C extensions + - Cookies that are not URI escaped no longer cause exceptions + +## [1.3.7] 2013-01-06 + - Add warnings when users do not provide a session secret + - Fix parsing performance for unquoted filenames + - Updated URI backports + - Fix URI backport version matching, and silence constant warnings + - Correct parameter parsing with empty values + - Correct rackup '-I' flag, to allow multiple uses + - Correct rackup pidfile handling + - Report rackup line numbers correctly + - Fix request loops caused by non-stale nonces with time limits + - Fix reloader on Windows + - Prevent infinite recursions from Response#to_ary + - Various middleware better conforms to the body close specification + - Updated language for the body close specification + - Additional notes regarding ECMA escape compatibility issues + - Fix the parsing of multiple ranges in range headers + +## [1.2.6] 2013-01-06 + - Add warnings when users do not provide a session secret + - Fix parsing performance for unquoted filenames + +## [1.1.4] 2013-01-06 + - Add warnings when users do not provide a session secret + +## [1.4.1] 2012-01-22 + - Alter the keyspace limit calculations to reduce issues with nested params + - Add a workaround for multipart parsing where files contain unescaped "%" + - Added Rack::Response::Helpers#method_not_allowed? (code 405) + - Rack::File now returns 404 for illegal directory traversals + - Rack::File now returns 405 for illegal methods (non HEAD/GET) + - Rack::Cascade now catches 405 by default, as well as 404 + - Cookies missing '--' no longer cause an exception to be raised + - Various style changes and documentation spelling errors + - Rack::BodyProxy always ensures to execute its block + - Additional test coverage around cookies and secrets + - Rack::Session::Cookie can now be supplied either secret or old_secret + - Tests are no longer dependent on set order + - Rack::Static no longer defaults to serving index files + - Rack.release was fixed + +## [1.4.0] 2011-12-28 + - Ruby 1.8.6 support has officially been dropped. Not all tests pass. + - Raise sane error messages for broken config.ru + - Allow combining run and map in a config.ru + - Rack::ContentType will not set Content-Type for responses without a body + - Status code 205 does not send a response body + - Rack::Response::Helpers will not rely on instance variables + - Rack::Utils.build_query no longer outputs '=' for nil query values + - Various mime types added + - Rack::MockRequest now supports HEAD + - Rack::Directory now supports files that contain RFC3986 reserved chars + - Rack::File now only supports GET and HEAD requests + - Rack::Server#start now passes the block to Rack::Handler::#run + - Rack::Static now supports an index option + - Added the Teapot status code + - rackup now defaults to Thin instead of Mongrel (if installed) + - Support added for HTTP_X_FORWARDED_SCHEME + - Numerous bug fixes, including many fixes for new and alternate rubies + +## [1.1.3] 2011-12-28 + - Security fix. http://www.ocert.org/advisories/ocert-2011-003.html + Further information here: http://jruby.org/2011/12/27/jruby-1-6-5-1 + +## [1.3.5] 2011-10-17 + - Fix annoying warnings caused by the backport in 1.3.4 + +## [1.3.4] 2011-10-01 + - Backport security fix from 1.9.3, also fixes some roundtrip issues in URI + - Small documentation update + - Fix an issue where BodyProxy could cause an infinite recursion + - Add some supporting files for travis-ci + +## [1.2.4] 2011-09-16 + - Fix a bug with MRI regex engine to prevent XSS by malformed unicode + +## [1.3.3] 2011-09-16 + - Fix bug with broken query parameters in Rack::ShowExceptions + - Rack::Request#cookies no longer swallows exceptions on broken input + - Prevents XSS attacks enabled by bug in Ruby 1.8's regexp engine + - Rack::ConditionalGet handles broken If-Modified-Since helpers + +## [1.3.2] 2011-07-16 + - Fix for Rails and rack-test, Rack::Utils#escape calls to_s + +## [1.3.1] 2011-07-13 + - Fix 1.9.1 support + - Fix JRuby support + - Properly handle $KCODE in Rack::Utils.escape + - Make method_missing/respond_to behavior consistent for Rack::Lock, + Rack::Auth::Digest::Request and Rack::Multipart::UploadedFile + - Reenable passing rack.session to session middleware + - Rack::CommonLogger handles streaming responses correctly + - Rack::MockResponse calls close on the body object + - Fix a DOS vector from MRI stdlib backport + +## [1.2.3] 2011-05-22 + - Pulled in relevant bug fixes from 1.3 + - Fixed 1.8.6 support + +## [1.3.0] 2011-05-22 + - Various performance optimizations + - Various multipart fixes + - Various multipart refactors + - Infinite loop fix for multipart + - Test coverage for Rack::Server returns + - Allow files with '..', but not path components that are '..' + - rackup accepts handler-specific options on the command line + - Request#params no longer merges POST into GET (but returns the same) + - Use URI.encode_www_form_component instead. Use core methods for escaping. + - Allow multi-line comments in the config file + - Bug L#94 reported by Nikolai Lugovoi, query parameter unescaping. + - Rack::Response now deletes Content-Length when appropriate + - Rack::Deflater now supports streaming + - Improved Rack::Handler loading and searching + - Support for the PATCH verb + - env['rack.session.options'] now contains session options + - Cookies respect renew + - Session middleware uses SecureRandom.hex + +## [1.2.2, 1.1.2] 2011-03-13 + - Security fix in Rack::Auth::Digest::MD5: when authenticator + returned nil, permission was granted on empty password. + +## [1.2.1] 2010-06-15 + - Make CGI handler rewindable + - Rename spec/ to test/ to not conflict with SPEC on lesser + operating systems + +## [1.2.0] 2010-06-13 + - Removed Camping adapter: Camping 2.0 supports Rack as-is + - Removed parsing of quoted values + - Add Request.trace? and Request.options? + - Add mime-type for .webm and .htc + - Fix HTTP_X_FORWARDED_FOR + - Various multipart fixes + - Switch test suite to bacon + +## [1.1.0] 2010-01-03 + - Moved Auth::OpenID to rack-contrib. + - SPEC change that relaxes Lint slightly to allow subclasses of the + required types + - SPEC change to document rack.input binary mode in greater detail + - SPEC define optional rack.logger specification + - File servers support X-Cascade header + - Imported Config middleware + - Imported ETag middleware + - Imported Runtime middleware + - Imported Sendfile middleware + - New Logger and NullLogger middlewares + - Added mime type for .ogv and .manifest. + - Don't squeeze PATH_INFO slashes + - Use Content-Type to determine POST params parsing + - Update Rack::Utils::HTTP_STATUS_CODES hash + - Add status code lookup utility + - Response should call #to_i on the status + - Add Request#user_agent + - Request#host knows about forwarded host + - Return an empty string for Request#host if HTTP_HOST and + SERVER_NAME are both missing + - Allow MockRequest to accept hash params + - Optimizations to HeaderHash + - Refactored rackup into Rack::Server + - Added Utils.build_nested_query to complement Utils.parse_nested_query + - Added Utils::Multipart.build_multipart to complement + Utils::Multipart.parse_multipart + - Extracted set and delete cookie helpers into Utils so they can be + used outside Response + - Extract parse_query and parse_multipart in Request so subclasses + can change their behavior + - Enforce binary encoding in RewindableInput + - Set correct external_encoding for handlers that don't use RewindableInput + +## [1.0.1] 2009-10-18 + - Bump remainder of rack.versions. + - Support the pure Ruby FCGI implementation. + - Fix for form names containing "=": split first then unescape components + - Fixes the handling of the filename parameter with semicolons in names. + - Add anchor to nested params parsing regexp to prevent stack overflows + - Use more compatible gzip write api instead of "<<". + - Make sure that Reloader doesn't break when executed via ruby -e + - Make sure WEBrick respects the :Host option + - Many Ruby 1.9 fixes. + +## [1.0.0] 2009-04-25 + - SPEC change: Rack::VERSION has been pushed to [1,0]. + - SPEC change: header values must be Strings now, split on "\n". + - SPEC change: Content-Length can be missing, in this case chunked transfer + encoding is used. + - SPEC change: rack.input must be rewindable and support reading into + a buffer, wrap with Rack::RewindableInput if it isn't. + - SPEC change: rack.session is now specified. + - SPEC change: Bodies can now additionally respond to #to_path with + a filename to be served. + - NOTE: String bodies break in 1.9, use an Array consisting of a + single String instead. + - New middleware Rack::Lock. + - New middleware Rack::ContentType. + - Rack::Reloader has been rewritten. + - Major update to Rack::Auth::OpenID. + - Support for nested parameter parsing in Rack::Response. + - Support for redirects in Rack::Response. + - HttpOnly cookie support in Rack::Response. + - The Rakefile has been rewritten. + - Many bugfixes and small improvements. + +## [0.9.1] 2009-01-09 + - Fix directory traversal exploits in Rack::File and Rack::Directory. + +## [0.9] 2009-01-06 + - Rack is now managed by the Rack Core Team. + - Rack::Lint is stricter and follows the HTTP RFCs more closely. + - Added ConditionalGet middleware. + - Added ContentLength middleware. + - Added Deflater middleware. + - Added Head middleware. + - Added MethodOverride middleware. + - Rack::Mime now provides popular MIME-types and their extension. + - Mongrel Header now streams. + - Added Thin handler. + - Official support for swiftiplied Mongrel. + - Secure cookies. + - Made HeaderHash case-preserving. + - Many bugfixes and small improvements. + +## [0.4] 2008-08-21 + - New middleware, Rack::Deflater, by Christoffer Sawicki. + - OpenID authentication now needs ruby-openid 2. + - New Memcache sessions, by blink. + - Explicit EventedMongrel handler, by Joshua Peek + - Rack::Reloader is not loaded in rackup development mode. + - rackup can daemonize with -D. + - Many bugfixes, especially for pool sessions, URLMap, thread safety + and tempfile handling. + - Improved tests. + - Rack moved to Git. + +## [0.3] 2008-02-26 + - LiteSpeed handler, by Adrian Madrid. + - SCGI handler, by Jeremy Evans. + - Pool sessions, by blink. + - OpenID authentication, by blink. + - :Port and :File options for opening FastCGI sockets, by blink. + - Last-Modified HTTP header for Rack::File, by blink. + - Rack::Builder#use now accepts blocks, by Corey Jewett. + (See example/protectedlobster.ru) + - HTTP status 201 can contain a Content-Type and a body now. + - Many bugfixes, especially related to Cookie handling. + +## [0.2] 2007-05-16 + - HTTP Basic authentication. + - Cookie Sessions. + - Static file handler. + - Improved Rack::Request. + - Improved Rack::Response. + - Added Rack::ShowStatus, for better default error messages. + - Bug fixes in the Camping adapter. + - Removed Rails adapter, was too alpha. + +## [0.1] 2007-03-03 + +[@ioquatix]: https://github.com/ioquatix "Samuel Williams" +[@jeremyevans]: https://github.com/jeremyevans "Jeremy Evans" +[@amatsuda]: https://github.com/amatsuda "Akira Matsuda" +[@wjordan]: https://github.com/wjordan "Will Jordan" +[@BlakeWilliams]: https://github.com/BlakeWilliams "Blake Williams" +[@davidstosik]: https://github.com/davidstosik "David Stosik" +[@earlopain]: https://github.com/earlopain "Earlopain" diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/CONTRIBUTING.md b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/CONTRIBUTING.md new file mode 100644 index 00000000..a95263d8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/CONTRIBUTING.md @@ -0,0 +1,144 @@ +# Contributing to Rack + +Rack is work of [hundreds of +contributors](https://github.com/rack/rack/graphs/contributors). You're +encouraged to submit [pull requests](https://github.com/rack/rack/pulls) and +[propose features and discuss issues](https://github.com/rack/rack/issues). + +## Backports + +Only security patches are ideal for backporting to non-main release versions. If +you're not sure if your bug fix is backportable, you should open a discussion to +discuss it first. + +The [Security Policy] documents which release versions will receive security +backports. + +## Fork the Project + +Fork the [project on GitHub](https://github.com/rack/rack) and check out your +copy. + +``` +git clone https://github.com/(your-github-username)/rack.git +cd rack +git remote add upstream https://github.com/rack/rack.git +``` + +## Create a Topic Branch + +Make sure your fork is up-to-date and create a topic branch for your feature or +bug fix. + +``` +git checkout main +git pull upstream main +git checkout -b my-feature-branch +``` + +## Running All Tests + +Install all dependencies. + +``` +bundle install +``` + +Run all tests. + +``` +rake test +``` + +## Write Tests + +Try to write a test that reproduces the problem you're trying to fix or +describes a feature that you want to build. + +We definitely appreciate pull requests that highlight or reproduce a problem, +even without a fix. + +## Write Code + +Implement your feature or bug fix. + +Make sure that all tests pass: + +``` +bundle exec rake test +``` + +## Write Documentation + +Document any external behavior in the [README](README.md). + +## Update Changelog + +Add a line to [CHANGELOG](CHANGELOG.md). + +## Commit Changes + +Make sure git knows your name and email address: + +``` +git config --global user.name "Your Name" +git config --global user.email "contributor@example.com" +``` + +Writing good commit logs is important. A commit log should describe what changed +and why. + +``` +git add ... +git commit +``` + +## Push + +``` +git push origin my-feature-branch +``` + +## Make a Pull Request + +Go to your fork of rack on GitHub and select your feature branch. Click the +'Pull Request' button and fill out the form. Pull requests are usually +reviewed within a few days. + +## Rebase + +If you've been working on a change for a while, rebase with upstream/main. + +``` +git fetch upstream +git rebase upstream/main +git push origin my-feature-branch -f +``` + +## Make Required Changes + +Amend your previous commit and force push the changes. + +``` +git commit --amend +git push origin my-feature-branch -f +``` + +## Check on Your Pull Request + +Go back to your pull request after a few minutes and see whether it passed +tests with GitHub Actions. Everything should look green, otherwise fix issues and +amend your commit as described above. + +## Be Patient + +It's likely that your change will not be merged and that the nitpicky +maintainers will ask you to do more, or fix seemingly benign problems. Hang in +there! + +## Thank You + +Please do know that we really appreciate and value your time and work. We love +you, really. + +[Security Policy]: SECURITY.md diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/MIT-LICENSE b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/MIT-LICENSE new file mode 100644 index 00000000..fb33b7fe --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/MIT-LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (C) 2007-2021 Leah Neukirchen + +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 AUTHORS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/README.md b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/README.md new file mode 100644 index 00000000..d52de005 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/README.md @@ -0,0 +1,355 @@ +# ![Rack](contrib/logo.webp) + +Rack provides a minimal, modular, and adaptable interface for developing web +applications in Ruby. By wrapping HTTP requests and responses in the simplest +way possible, it unifies and distills the bridge between web servers, web +frameworks, and web application into a single method call. + +The exact details of this are described in the [Rack Specification], which all +Rack applications should conform to. + +## Version support + +| Version | Support | +|----------|------------------------------------| +| 3.0.x | Bug fixes and security patches. | +| 2.2.x | Security patches only. | +| <= 2.1.x | End of support. | + +Please see the [Security Policy] for more information. + +## Rack 3.0 + +This is the latest version of Rack. It contains API improvements but also some +breaking changes. Please check the [Upgrade Guide](UPGRADE-GUIDE.md) for more +details about migrating servers, middlewares and applications designed for Rack 2 +to Rack 3. For detailed information on specific changes, check the [Change Log](CHANGELOG.md). + +## Rack 2.2 + +This version of Rack is receiving security patches only, and effort should be +made to move to Rack 3. + +Starting in Ruby 3.4 the `base64` dependency will no longer be a default gem, +and may cause a warning or error about `base64` being missing. To correct this, +add `base64` as a dependency to your project. + +## Installation + +Add the rack gem to your application bundle, or follow the instructions provided +by a [supported web framework](#supported-web-frameworks): + +```bash +# Install it generally: +$ gem install rack + +# or, add it to your current application gemfile: +$ bundle add rack +``` + +If you need features from `Rack::Session` or `bin/rackup` please add those gems separately. + +```bash +$ gem install rack-session rackup +``` + +## Usage + +Create a file called `config.ru` with the following contents: + +```ruby +run do |env| + [200, {}, ["Hello World"]] +end +``` + +Run this using the rackup gem or another [supported web +server](#supported-web-servers). + +```bash +$ gem install rackup +$ rackup +$ curl http://localhost:9292 +Hello World +``` + +## Supported web servers + +Rack is supported by a wide range of servers, including: + +* [Agoo](https://github.com/ohler55/agoo) +* [Falcon](https://github.com/socketry/falcon) +* [Iodine](https://github.com/boazsegev/iodine) +* [NGINX Unit](https://unit.nginx.org/) +* [Phusion Passenger](https://www.phusionpassenger.com/) (which is mod_rack for + Apache and for nginx) +* [Puma](https://puma.io/) +* [Thin](https://github.com/macournoyer/thin) +* [Unicorn](https://yhbt.net/unicorn/) +* [uWSGI](https://uwsgi-docs.readthedocs.io/en/latest/) +* [Lamby](https://lamby.custominktech.com) (for AWS Lambda) + +You will need to consult the server documentation to find out what features and +limitations they may have. In general, any valid Rack app will run the same on +all these servers, without changing anything. + +### Rackup + +Rack provides a separate gem, [rackup](https://github.com/rack/rackup) which is +a generic interface for running a Rack application on supported servers, which +include `WEBRick`, `Puma`, `Falcon` and others. + +## Supported web frameworks + +These frameworks and many others support the [Rack Specification]: + +* [Camping](https://github.com/camping/camping) +* [Hanami](https://hanamirb.org/) +* [Ramaze](https://github.com/ramaze/ramaze) +* [Padrino](https://padrinorb.com/) +* [Roda](https://github.com/jeremyevans/roda) +* [Ruby on Rails](https://rubyonrails.org/) +* [Rum](https://github.com/leahneukirchen/rum) +* [Sinatra](https://sinatrarb.com/) +* [Utopia](https://github.com/socketry/utopia) +* [WABuR](https://github.com/ohler55/wabur) + +## Available middleware shipped with Rack + +Between the server and the framework, Rack can be customized to your +applications needs using middleware. Rack itself ships with the following +middleware: + +* `Rack::CommonLogger` for creating Apache-style logfiles. +* `Rack::ConditionalGet` for returning [Not + Modified](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/304) + responses when the response has not changed. +* `Rack::Config` for modifying the environment before processing the request. +* `Rack::ContentLength` for setting a `content-length` header based on body + size. +* `Rack::ContentType` for setting a default `content-type` header for responses. +* `Rack::Deflater` for compressing responses with gzip. +* `Rack::ETag` for setting `etag` header on bodies that can be buffered. +* `Rack::Events` for providing easy hooks when a request is received and when + the response is sent. +* `Rack::Files` for serving static files. +* `Rack::Head` for returning an empty body for HEAD requests. +* `Rack::Lint` for checking conformance to the [Rack Specification]. +* `Rack::Lock` for serializing requests using a mutex. +* `Rack::Logger` for setting a logger to handle logging errors. +* `Rack::MethodOverride` for modifying the request method based on a submitted + parameter. +* `Rack::Recursive` for including data from other paths in the application, and + for performing internal redirects. +* `Rack::Reloader` for reloading files if they have been modified. +* `Rack::Runtime` for including a response header with the time taken to process + the request. +* `Rack::Sendfile` for working with web servers that can use optimized file + serving for file system paths. +* `Rack::ShowException` for catching unhandled exceptions and presenting them in + a nice and helpful way with clickable backtrace. +* `Rack::ShowStatus` for using nice error pages for empty client error + responses. +* `Rack::Static` for more configurable serving of static files. +* `Rack::TempfileReaper` for removing temporary files creating during a request. + +All these components use the same interface, which is described in detail in the +[Rack Specification]. These optional components can be used in any way you wish. + +### Convenience interfaces + +If you want to develop outside of existing frameworks, implement your own ones, +or develop middleware, Rack provides many helpers to create Rack applications +quickly and without doing the same web stuff all over: + +* `Rack::Request` which also provides query string parsing and multipart + handling. +* `Rack::Response` for convenient generation of HTTP replies and cookie + handling. +* `Rack::MockRequest` and `Rack::MockResponse` for efficient and quick testing + of Rack application without real HTTP round-trips. +* `Rack::Cascade` for trying additional Rack applications if an application + returns a not found or method not supported response. +* `Rack::Directory` for serving files under a given directory, with directory + indexes. +* `Rack::MediaType` for parsing content-type headers. +* `Rack::Mime` for determining content-type based on file extension. +* `Rack::RewindableInput` for making any IO object rewindable, using a temporary + file buffer. +* `Rack::URLMap` to route to multiple applications inside the same process. + +## Configuration + +Rack exposes several configuration parameters to control various features of the +implementation. + +### `RACK_QUERY_PARSER_BYTESIZE_LIMIT` + +This environment variable sets the default for the maximum query string bytesize +that `Rack::QueryParser` will attempt to parse. Attempts to use a query string +that exceeds this number of bytes will result in a +`Rack::QueryParser::QueryLimitError` exception. If this enviroment variable is +provided, it must be an integer, or `Rack::QueryParser` will raise an exception. + +The default limit can be overridden on a per-`Rack::QueryParser` basis using +the `bytesize_limit` keyword argument when creating the `Rack::QueryParser`. + +### `RACK_QUERY_PARSER_PARAMS_LIMIT` + +This environment variable sets the default for the maximum number of query +parameters that `Rack::QueryParser` will attempt to parse. Attempts to use a +query string with more than this many query parameters will result in a +`Rack::QueryParser::QueryLimitError` exception. If this enviroment variable is +provided, it must be an integer, or `Rack::QueryParser` will raise an exception. + +The default limit can be overridden on a per-`Rack::QueryParser` basis using +the `params_limit` keyword argument when creating the `Rack::QueryParser`. + +This is implemented by counting the number of parameter separators in the +query string, before attempting parsing, so if the same parameter key is +used multiple times in the query, each counts as a separate parameter for +this check. + +### `param_depth_limit` + +```ruby +Rack::Utils.param_depth_limit = 32 # default +``` + +The maximum amount of nesting allowed in parameters. For example, if set to 3, +this query string would be allowed: + +``` +?a[b][c]=d +``` + +but this query string would not be allowed: + +``` +?a[b][c][d]=e +``` + +Limiting the depth prevents a possible stack overflow when parsing parameters. + +### `multipart_file_limit` + +```ruby +Rack::Utils.multipart_file_limit = 128 # default +``` + +The maximum number of parts with a filename a request can contain. Accepting +too many parts can lead to the server running out of file handles. + +The default is 128, which means that a single request can't upload more than 128 +files at once. Set to 0 for no limit. + +Can also be set via the `RACK_MULTIPART_FILE_LIMIT` environment variable. + +(This is also aliased as `multipart_part_limit` and `RACK_MULTIPART_PART_LIMIT` for compatibility) + + +### `multipart_total_part_limit` + +The maximum total number of parts a request can contain of any type, including +both file and non-file form fields. + +The default is 4096, which means that a single request can't contain more than +4096 parts. + +Set to 0 for no limit. + +Can also be set via the `RACK_MULTIPART_TOTAL_PART_LIMIT` environment variable. + + +## Changelog + +See [CHANGELOG.md](CHANGELOG.md). + +## Contributing + +See [CONTRIBUTING.md](CONTRIBUTING.md) for specific details about how to make a +contribution to Rack. + +Please post bugs, suggestions and patches to [GitHub +Issues](https://github.com/rack/rack/issues). + +Please check our [Security Policy](https://github.com/rack/rack/security/policy) +for responsible disclosure and security bug reporting process. Due to wide usage +of the library, it is strongly preferred that we manage timing in order to +provide viable patches at the time of disclosure. Your assistance in this matter +is greatly appreciated. + +## See Also + +### `rack-contrib` + +The plethora of useful middleware created the need for a project that collects +fresh Rack middleware. `rack-contrib` includes a variety of add-on components +for Rack and it is easy to contribute new modules. + +* https://github.com/rack/rack-contrib + +### `rack-session` + +Provides convenient session management for Rack. + +* https://github.com/rack/rack-session + +## Thanks + +The Rack Core Team, consisting of + +* Aaron Patterson [tenderlove](https://github.com/tenderlove) +* Samuel Williams [ioquatix](https://github.com/ioquatix) +* Jeremy Evans [jeremyevans](https://github.com/jeremyevans) +* Eileen Uchitelle [eileencodes](https://github.com/eileencodes) +* Matthew Draper [matthewd](https://github.com/matthewd) +* Rafael França [rafaelfranca](https://github.com/rafaelfranca) + +and the Rack Alumni + +* Ryan Tomayko [rtomayko](https://github.com/rtomayko) +* Scytrin dai Kinthra [scytrin](https://github.com/scytrin) +* Leah Neukirchen [leahneukirchen](https://github.com/leahneukirchen) +* James Tucker [raggi](https://github.com/raggi) +* Josh Peek [josh](https://github.com/josh) +* José Valim [josevalim](https://github.com/josevalim) +* Michael Fellinger [manveru](https://github.com/manveru) +* Santiago Pastorino [spastorino](https://github.com/spastorino) +* Konstantin Haase [rkh](https://github.com/rkh) + +would like to thank: + +* Adrian Madrid, for the LiteSpeed handler. +* Christoffer Sawicki, for the first Rails adapter and `Rack::Deflater`. +* Tim Fletcher, for the HTTP authentication code. +* Luc Heinrich for the Cookie sessions, the static file handler and bugfixes. +* Armin Ronacher, for the logo and racktools. +* Alex Beregszaszi, Alexander Kahn, Anil Wadghule, Aredridel, Ben Alpert, Dan + Kubb, Daniel Roethlisberger, Matt Todd, Tom Robinson, Phil Hagelberg, S. Brent + Faulkner, Bosko Milekic, Daniel Rodríguez Troitiño, Genki Takiuchi, Geoffrey + Grosenbach, Julien Sanchez, Kamal Fariz Mahyuddin, Masayoshi Takahashi, + Patrick Aljordm, Mig, Kazuhiro Nishiyama, Jon Bardin, Konstantin Haase, Larry + Siden, Matias Korhonen, Sam Ruby, Simon Chiang, Tim Connor, Timur Batyrshin, + and Zach Brock for bug fixing and other improvements. +* Eric Wong, Hongli Lai, Jeremy Kemper for their continuous support and API + improvements. +* Yehuda Katz and Carl Lerche for refactoring rackup. +* Brian Candler, for `Rack::ContentType`. +* Graham Batty, for improved handler loading. +* Stephen Bannasch, for bug reports and documentation. +* Gary Wright, for proposing a better `Rack::Response` interface. +* Jonathan Buch, for improvements regarding `Rack::Response`. +* Armin Röhrl, for tracking down bugs in the Cookie generator. +* Alexander Kellett for testing the Gem and reviewing the announcement. +* Marcus Rückert, for help with configuring and debugging lighttpd. +* The WSGI team for the well-done and documented work they've done and Rack + builds up on. +* All bug reporters and patch contributors not mentioned above. + +## License + +Rack is released under the [MIT License](MIT-LICENSE). + +[Rack Specification]: SPEC.rdoc +[Security Policy]: SECURITY.md diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/SPEC.rdoc b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/SPEC.rdoc new file mode 100644 index 00000000..ed5d9824 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/SPEC.rdoc @@ -0,0 +1,365 @@ +This specification aims to formalize the Rack protocol. You +can (and should) use Rack::Lint to enforce it. + +When you develop middleware, be sure to add a Lint before and +after to catch all mistakes. + += Rack applications + +A Rack application is a Ruby object (not a class) that +responds to +call+. +It takes exactly one argument, the *environment* +and returns a non-frozen Array of exactly three values: +The *status*, +the *headers*, +and the *body*. + +== The Environment + +The environment must be an unfrozen instance of Hash that includes +CGI-like headers. The Rack application is free to modify the +environment. + +The environment is required to include these variables +(adopted from {PEP 333}[https://peps.python.org/pep-0333/]), except when they'd be empty, but see +below. +REQUEST_METHOD:: The HTTP request method, such as + "GET" or "POST". This cannot ever + be an empty string, and so is + always required. +SCRIPT_NAME:: The initial portion of the request + URL's "path" that corresponds to the + application object, so that the + application knows its virtual + "location". This may be an empty + string, if the application corresponds + to the "root" of the server. +PATH_INFO:: The remainder of the request URL's + "path", designating the virtual + "location" of the request's target + within the application. This may be an + empty string, if the request URL targets + the application root and does not have a + trailing slash. This value may be + percent-encoded when originating from + a URL. +QUERY_STRING:: The portion of the request URL that + follows the ?, if any. May be + empty, but is always required! +SERVER_NAME:: When combined with SCRIPT_NAME and + PATH_INFO, these variables can be + used to complete the URL. Note, however, + that HTTP_HOST, if present, + should be used in preference to + SERVER_NAME for reconstructing + the request URL. + SERVER_NAME can never be an empty + string, and so is always required. +SERVER_PORT:: An optional +Integer+ which is the port the + server is running on. Should be specified if + the server is running on a non-standard port. +SERVER_PROTOCOL:: A string representing the HTTP version used + for the request. +HTTP_ Variables:: Variables corresponding to the + client-supplied HTTP request + headers (i.e., variables whose + names begin with HTTP_). The + presence or absence of these + variables should correspond with + the presence or absence of the + appropriate HTTP header in the + request. See + {RFC3875 section 4.1.18}[https://tools.ietf.org/html/rfc3875#section-4.1.18] + for specific behavior. +In addition to this, the Rack environment must include these +Rack-specific variables: +rack.url_scheme:: +http+ or +https+, depending on the + request URL. +rack.input:: See below, the input stream. +rack.errors:: See below, the error stream. +rack.hijack?:: See below, if present and true, indicates + that the server supports partial hijacking. +rack.hijack:: See below, if present, an object responding + to +call+ that is used to perform a full + hijack. +rack.protocol:: An optional +Array+ of +String+, containing + the protocols advertised by the client in + the +upgrade+ header (HTTP/1) or the + +:protocol+ pseudo-header (HTTP/2). +Additional environment specifications have approved to +standardized middleware APIs. None of these are required to +be implemented by the server. +rack.session:: A hash-like interface for storing + request session data. + The store must implement: + store(key, value) (aliased as []=); + fetch(key, default = nil) (aliased as []); + delete(key); + clear; + to_hash (returning unfrozen Hash instance); +rack.logger:: A common object interface for logging messages. + The object must implement: + info(message, &block) + debug(message, &block) + warn(message, &block) + error(message, &block) + fatal(message, &block) +rack.multipart.buffer_size:: An Integer hint to the multipart parser as to what chunk size to use for reads and writes. +rack.multipart.tempfile_factory:: An object responding to #call with two arguments, the filename and content_type given for the multipart form field, and returning an IO-like object that responds to #<< and optionally #rewind. This factory will be used to instantiate the tempfile for each multipart form file upload field, rather than the default class of Tempfile. +The server or the application can store their own data in the +environment, too. The keys must contain at least one dot, +and should be prefixed uniquely. The prefix rack. +is reserved for use with the Rack core distribution and other +accepted specifications and must not be used otherwise. + +The SERVER_PORT must be an Integer if set. +The SERVER_NAME must be a valid authority as defined by RFC7540. +The HTTP_HOST must be a valid authority as defined by RFC7540. +The SERVER_PROTOCOL must match the regexp HTTP/\d(\.\d)?. +The environment must not contain the keys +HTTP_CONTENT_TYPE or HTTP_CONTENT_LENGTH +(use the versions without HTTP_). +The CGI keys (named without a period) must have String values. +If the string values for CGI keys contain non-ASCII characters, +they should use ASCII-8BIT encoding. +There are the following restrictions: +* rack.url_scheme must either be +http+ or +https+. +* There may be a valid input stream in rack.input. +* There must be a valid error stream in rack.errors. +* There may be a valid hijack callback in rack.hijack +* There may be a valid early hints callback in rack.early_hints +* The REQUEST_METHOD must be a valid token. +* The SCRIPT_NAME, if non-empty, must start with / +* The PATH_INFO, if provided, must be a valid request target or an empty string. + * Only OPTIONS requests may have PATH_INFO set to * (asterisk-form). + * Only CONNECT requests may have PATH_INFO set to an authority (authority-form). Note that in HTTP/2+, the authority-form is not a valid request target. + * CONNECT and OPTIONS requests must not have PATH_INFO set to a URI (absolute-form). + * Otherwise, PATH_INFO must start with a / and must not include a fragment part starting with '#' (origin-form). +* The CONTENT_LENGTH, if given, must consist of digits only. +* One of SCRIPT_NAME or PATH_INFO must be + set. PATH_INFO should be / if + SCRIPT_NAME is empty. + SCRIPT_NAME never should be /, but instead be empty. +rack.response_finished:: An array of callables run by the server after the response has been +processed. This would typically be invoked after sending the response to the client, but it could also be +invoked if an error occurs while generating the response or sending the response; in that case, the error +argument will be a subclass of +Exception+. +The callables are invoked with +env, status, headers, error+ arguments and should not raise any +exceptions. They should be invoked in reverse order of registration. + +=== The Input Stream + +The input stream is an IO-like object which contains the raw HTTP +POST data. +When applicable, its external encoding must be "ASCII-8BIT" and it +must be opened in binary mode. +The input stream must respond to +gets+, +each+, and +read+. +* +gets+ must be called without arguments and return a string, + or +nil+ on EOF. +* +read+ behaves like IO#read. + Its signature is read([length, [buffer]]). + + If given, +length+ must be a non-negative Integer (>= 0) or +nil+, + and +buffer+ must be a String and may not be nil. + + If +length+ is given and not nil, then this method reads at most + +length+ bytes from the input stream. + + If +length+ is not given or nil, then this method reads + all data until EOF. + + When EOF is reached, this method returns nil if +length+ is given + and not nil, or "" if +length+ is not given or is nil. + + If +buffer+ is given, then the read data will be placed + into +buffer+ instead of a newly created String object. +* +each+ must be called without arguments and only yield Strings. +* +close+ can be called on the input stream to indicate that + any remaining input is not needed. + +=== The Error Stream + +The error stream must respond to +puts+, +write+ and +flush+. +* +puts+ must be called with a single argument that responds to +to_s+. +* +write+ must be called with a single argument that is a String. +* +flush+ must be called without arguments and must be called + in order to make the error appear for sure. +* +close+ must never be called on the error stream. + +=== Hijacking + +The hijacking interfaces provides a means for an application to take +control of the HTTP connection. There are two distinct hijack +interfaces: full hijacking where the application takes over the raw +connection, and partial hijacking where the application takes over +just the response body stream. In both cases, the application is +responsible for closing the hijacked stream. + +Full hijacking only works with HTTP/1. Partial hijacking is functionally +equivalent to streaming bodies, and is still optionally supported for +backwards compatibility with older Rack versions. + +==== Full Hijack + +Full hijack is used to completely take over an HTTP/1 connection. It +occurs before any headers are written and causes the request to +ignores any response generated by the application. + +It is intended to be used when applications need access to raw HTTP/1 +connection. + +If +rack.hijack+ is present in +env+, it must respond to +call+ +and return an +IO+ instance which can be used to read and write +to the underlying connection using HTTP/1 semantics and +formatting. + +==== Partial Hijack + +Partial hijack is used for bi-directional streaming of the request and +response body. It occurs after the status and headers are written by +the server and causes the server to ignore the Body of the response. + +It is intended to be used when applications need bi-directional +streaming. + +If +rack.hijack?+ is present in +env+ and truthy, +an application may set the special response header +rack.hijack+ +to an object that responds to +call+, +accepting a +stream+ argument. + +After the response status and headers have been sent, this hijack +callback will be invoked with a +stream+ argument which follows the +same interface as outlined in "Streaming Body". Servers must +ignore the +body+ part of the response tuple when the ++rack.hijack+ response header is present. Using an empty +Array+ +instance is recommended. + +The special response header +rack.hijack+ must only be set +if the request +env+ has a truthy +rack.hijack?+. + +=== Early Hints + +The application or any middleware may call the rack.early_hints +with an object which would be valid as the headers of a Rack response. + +If rack.early_hints is present, it must respond to #call. +If rack.early_hints is called, it must be called with +valid Rack response headers. + +== The Response + +=== The Status + +This is an HTTP status. It must be an Integer greater than or equal to +100. + +=== The Headers + +The headers must be a unfrozen Hash. +The header keys must be Strings. +Special headers starting "rack." are for communicating with the +server, and must not be sent back to the client. +The header must not contain a +Status+ key. +Header keys must conform to RFC7230 token specification, i.e. cannot +contain non-printable ASCII, DQUOTE or "(),/:;<=>?@[\]{}". +Header keys must not contain uppercase ASCII characters (A-Z). +Header values must be either a String instance, +or an Array of String instances, +such that each String instance must not contain characters below 037. + +==== The +content-type+ Header + +There must not be a content-type header key when the +Status+ is 1xx, +204, or 304. + +==== The +content-length+ Header + +There must not be a content-length header key when the ++Status+ is 1xx, 204, or 304. + +==== The +rack.protocol+ Header + +If the +rack.protocol+ header is present, it must be a +String+, and +must be one of the values from the +rack.protocol+ array from the +environment. + +Setting this value informs the server that it should perform a +connection upgrade. In HTTP/1, this is done using the +upgrade+ +header. In HTTP/2, this is done by accepting the request. + +=== The Body + +The Body is typically an +Array+ of +String+ instances, an enumerable +that yields +String+ instances, a +Proc+ instance, or a File-like +object. + +The Body must respond to +each+ or +call+. It may optionally respond +to +to_path+ or +to_ary+. A Body that responds to +each+ is considered +to be an Enumerable Body. A Body that responds to +call+ is considered +to be a Streaming Body. + +A Body that responds to both +each+ and +call+ must be treated as an +Enumerable Body, not a Streaming Body. If it responds to +each+, you +must call +each+ and not +call+. If the Body doesn't respond to ++each+, then you can assume it responds to +call+. + +The Body must either be consumed or returned. The Body is consumed by +optionally calling either +each+ or +call+. +Then, if the Body responds to +close+, it must be called to release +any resources associated with the generation of the body. +In other words, +close+ must always be called at least once; typically +after the web server has sent the response to the client, but also in +cases where the Rack application makes internal/virtual requests and +discards the response. + + +After calling +close+, the Body is considered closed and should not +be consumed again. +If the original Body is replaced by a new Body, the new Body must +also consume the original Body by calling +close+ if possible. + +If the Body responds to +to_path+, it must return a +String+ +path for the local file system whose contents are identical +to that produced by calling +each+; this may be used by the +server as an alternative, possibly more efficient way to +transport the response. The +to_path+ method does not consume +the body. + +==== Enumerable Body + +The Enumerable Body must respond to +each+. +It must only be called once. +It must not be called after being closed, +and must only yield String values. + +Middleware must not call +each+ directly on the Body. +Instead, middleware can return a new Body that calls +each+ on the +original Body, yielding at least once per iteration. + +If the Body responds to +to_ary+, it must return an +Array+ whose +contents are identical to that produced by calling +each+. +Middleware may call +to_ary+ directly on the Body and return a new +Body in its place. In other words, middleware can only process the +Body directly if it responds to +to_ary+. If the Body responds to both ++to_ary+ and +close+, its implementation of +to_ary+ must call ++close+. + +==== Streaming Body + +The Streaming Body must respond to +call+. +It must only be called once. +It must not be called after being closed. +It takes a +stream+ argument. + +The +stream+ argument must implement: +read, write, <<, flush, close, close_read, close_write, closed? + +The semantics of these IO methods must be a best effort match to +those of a normal Ruby IO or Socket object, using standard arguments +and raising standard exceptions. Servers are encouraged to simply +pass on real IO objects, although it is recognized that this approach +is not directly compatible with HTTP/2. + +== Thanks +Some parts of this specification are adopted from {PEP 333 – Python Web Server Gateway Interface v1.0}[https://peps.python.org/pep-0333/] +I'd like to thank everyone involved in that effort. diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack.rb new file mode 100644 index 00000000..e4bb1f54 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +# Copyright (C) 2007-2019 Leah Neukirchen +# +# Rack is freely distributable under the terms of an MIT-style license. +# See MIT-LICENSE or https://opensource.org/licenses/MIT. + +# The Rack main module, serving as a namespace for all core Rack +# modules and classes. +# +# All modules meant for use in your application are autoloaded here, +# so it should be enough just to require 'rack' in your code. + +require_relative 'rack/version' +require_relative 'rack/constants' + +module Rack + autoload :BadRequest, "rack/bad_request" + autoload :BodyProxy, "rack/body_proxy" + autoload :Builder, "rack/builder" + autoload :Cascade, "rack/cascade" + autoload :CommonLogger, "rack/common_logger" + autoload :ConditionalGet, "rack/conditional_get" + autoload :Config, "rack/config" + autoload :ContentLength, "rack/content_length" + autoload :ContentType, "rack/content_type" + autoload :Deflater, "rack/deflater" + autoload :Directory, "rack/directory" + autoload :ETag, "rack/etag" + autoload :Events, "rack/events" + autoload :Files, "rack/files" + autoload :ForwardRequest, "rack/recursive" + autoload :Head, "rack/head" + autoload :Headers, "rack/headers" + autoload :Lint, "rack/lint" + autoload :Lock, "rack/lock" + autoload :Logger, "rack/logger" + autoload :MediaType, "rack/media_type" + autoload :MethodOverride, "rack/method_override" + autoload :Mime, "rack/mime" + autoload :MockRequest, "rack/mock_request" + autoload :MockResponse, "rack/mock_response" + autoload :Multipart, "rack/multipart" + autoload :NullLogger, "rack/null_logger" + autoload :QueryParser, "rack/query_parser" + autoload :Recursive, "rack/recursive" + autoload :Reloader, "rack/reloader" + autoload :Request, "rack/request" + autoload :Response, "rack/response" + autoload :RewindableInput, "rack/rewindable_input" + autoload :Runtime, "rack/runtime" + autoload :Sendfile, "rack/sendfile" + autoload :ShowExceptions, "rack/show_exceptions" + autoload :ShowStatus, "rack/show_status" + autoload :Static, "rack/static" + autoload :TempfileReaper, "rack/tempfile_reaper" + autoload :URLMap, "rack/urlmap" + autoload :Utils, "rack/utils" + + module Auth + autoload :Basic, "rack/auth/basic" + autoload :AbstractHandler, "rack/auth/abstract/handler" + autoload :AbstractRequest, "rack/auth/abstract/request" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/auth/abstract/handler.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/auth/abstract/handler.rb new file mode 100644 index 00000000..4731ee8c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/auth/abstract/handler.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require_relative '../../constants' + +module Rack + module Auth + # Rack::Auth::AbstractHandler implements common authentication functionality. + # + # +realm+ should be set for all handlers. + + class AbstractHandler + + attr_accessor :realm + + def initialize(app, realm = nil, &authenticator) + @app, @realm, @authenticator = app, realm, authenticator + end + + + private + + def unauthorized(www_authenticate = challenge) + return [ 401, + { CONTENT_TYPE => 'text/plain', + CONTENT_LENGTH => '0', + 'www-authenticate' => www_authenticate.to_s }, + [] + ] + end + + def bad_request + return [ 400, + { CONTENT_TYPE => 'text/plain', + CONTENT_LENGTH => '0' }, + [] + ] + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/auth/abstract/request.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/auth/abstract/request.rb new file mode 100644 index 00000000..f8723315 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/auth/abstract/request.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +require_relative '../../request' + +module Rack + module Auth + class AbstractRequest + + def initialize(env) + @env = env + end + + def request + @request ||= Request.new(@env) + end + + def provided? + !authorization_key.nil? && valid? + end + + def valid? + !@env[authorization_key].nil? + end + + def parts + @parts ||= @env[authorization_key].split(' ', 2) + end + + def scheme + @scheme ||= parts.first&.downcase + end + + def params + @params ||= parts.last + end + + + private + + AUTHORIZATION_KEYS = ['HTTP_AUTHORIZATION', 'X-HTTP_AUTHORIZATION', 'X_HTTP_AUTHORIZATION'] + + def authorization_key + @authorization_key ||= AUTHORIZATION_KEYS.detect { |key| @env.has_key?(key) } + end + + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/auth/basic.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/auth/basic.rb new file mode 100644 index 00000000..67ffc49c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/auth/basic.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require_relative 'abstract/handler' +require_relative 'abstract/request' + +module Rack + module Auth + # Rack::Auth::Basic implements HTTP Basic Authentication, as per RFC 2617. + # + # Initialize with the Rack application that you want protecting, + # and a block that checks if a username and password pair are valid. + + class Basic < AbstractHandler + + def call(env) + auth = Basic::Request.new(env) + + return unauthorized unless auth.provided? + + return bad_request unless auth.basic? + + if valid?(auth) + env['REMOTE_USER'] = auth.username + + return @app.call(env) + end + + unauthorized + end + + + private + + def challenge + 'Basic realm="%s"' % realm + end + + def valid?(auth) + @authenticator.call(*auth.credentials) + end + + class Request < Auth::AbstractRequest + def basic? + "basic" == scheme && credentials.length == 2 + end + + def credentials + @credentials ||= params.unpack1('m').split(':', 2) + end + + def username + credentials.first + end + end + + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/bad_request.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/bad_request.rb new file mode 100644 index 00000000..8eaa94e6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/bad_request.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +module Rack + # Represents a 400 Bad Request error when input data fails to meet the + # requirements. + module BadRequest + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/body_proxy.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/body_proxy.rb new file mode 100644 index 00000000..72915798 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/body_proxy.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +module Rack + # Proxy for response bodies allowing calling a block when + # the response body is closed (after the response has been fully + # sent to the client). + class BodyProxy + # Set the response body to wrap, and the block to call when the + # response has been fully sent. + def initialize(body, &block) + @body = body + @block = block + @closed = false + end + + # Return whether the wrapped body responds to the method. + def respond_to_missing?(method_name, include_all = false) + case method_name + when :to_str + false + else + super or @body.respond_to?(method_name, include_all) + end + end + + # If not already closed, close the wrapped body and + # then call the block the proxy was initialized with. + def close + return if @closed + @closed = true + begin + @body.close if @body.respond_to?(:close) + ensure + @block.call + end + end + + # Whether the proxy is closed. The proxy starts as not closed, + # and becomes closed on the first call to close. + def closed? + @closed + end + + # Delegate missing methods to the wrapped body. + def method_missing(method_name, *args, &block) + case method_name + when :to_str + super + when :to_ary + begin + @body.__send__(method_name, *args, &block) + ensure + close + end + else + @body.__send__(method_name, *args, &block) + end + end + # :nocov: + ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true) + # :nocov: + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/builder.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/builder.rb new file mode 100644 index 00000000..9faeffb7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/builder.rb @@ -0,0 +1,290 @@ +# frozen_string_literal: true + +require_relative 'urlmap' + +module Rack; end +Rack::BUILDER_TOPLEVEL_BINDING = ->(builder){builder.instance_eval{binding}} + +module Rack + # Rack::Builder provides a domain-specific language (DSL) to construct Rack + # applications. It is primarily used to parse +config.ru+ files which + # instantiate several middleware and a final application which are hosted + # by a Rack-compatible web server. + # + # Example: + # + # app = Rack::Builder.new do + # use Rack::CommonLogger + # map "/ok" do + # run lambda { |env| [200, {'content-type' => 'text/plain'}, ['OK']] } + # end + # end + # + # run app + # + # Or + # + # app = Rack::Builder.app do + # use Rack::CommonLogger + # run lambda { |env| [200, {'content-type' => 'text/plain'}, ['OK']] } + # end + # + # run app + # + # +use+ adds middleware to the stack, +run+ dispatches to an application. + # You can use +map+ to construct a Rack::URLMap in a convenient way. + class Builder + + # https://stackoverflow.com/questions/2223882/whats-the-difference-between-utf-8-and-utf-8-without-bom + UTF_8_BOM = '\xef\xbb\xbf' + + # Parse the given config file to get a Rack application. + # + # If the config file ends in +.ru+, it is treated as a + # rackup file and the contents will be treated as if + # specified inside a Rack::Builder block. + # + # If the config file does not end in +.ru+, it is + # required and Rack will use the basename of the file + # to guess which constant will be the Rack application to run. + # + # Examples: + # + # Rack::Builder.parse_file('config.ru') + # # Rack application built using Rack::Builder.new + # + # Rack::Builder.parse_file('app.rb') + # # requires app.rb, which can be anywhere in Ruby's + # # load path. After requiring, assumes App constant + # # is a Rack application + # + # Rack::Builder.parse_file('./my_app.rb') + # # requires ./my_app.rb, which should be in the + # # process's current directory. After requiring, + # # assumes MyApp constant is a Rack application + def self.parse_file(path, **options) + if path.end_with?('.ru') + return self.load_file(path, **options) + else + require path + return Object.const_get(::File.basename(path, '.rb').split('_').map(&:capitalize).join('')) + end + end + + # Load the given file as a rackup file, treating the + # contents as if specified inside a Rack::Builder block. + # + # Ignores content in the file after +__END__+, so that + # use of +__END__+ will not result in a syntax error. + # + # Example config.ru file: + # + # $ cat config.ru + # + # use Rack::ContentLength + # require './app.rb' + # run App + def self.load_file(path, **options) + config = ::File.read(path) + config.slice!(/\A#{UTF_8_BOM}/) if config.encoding == Encoding::UTF_8 + + if config[/^#\\(.*)/] + fail "Parsing options from the first comment line is no longer supported: #{path}" + end + + config.sub!(/^__END__\n.*\Z/m, '') + + return new_from_string(config, path, **options) + end + + # Evaluate the given +builder_script+ string in the context of + # a Rack::Builder block, returning a Rack application. + def self.new_from_string(builder_script, path = "(rackup)", **options) + builder = self.new(**options) + + # We want to build a variant of TOPLEVEL_BINDING with self as a Rack::Builder instance. + # We cannot use instance_eval(String) as that would resolve constants differently. + binding = BUILDER_TOPLEVEL_BINDING.call(builder) + eval(builder_script, binding, path) + + return builder.to_app + end + + # Initialize a new Rack::Builder instance. +default_app+ specifies the + # default application if +run+ is not called later. If a block + # is given, it is evaluated in the context of the instance. + def initialize(default_app = nil, **options, &block) + @use = [] + @map = nil + @run = default_app + @warmup = nil + @freeze_app = false + @options = options + + instance_eval(&block) if block_given? + end + + # Any options provided to the Rack::Builder instance at initialization. + # These options can be server-specific. Some general options are: + # + # * +:isolation+: One of +process+, +thread+ or +fiber+. The execution + # isolation model to use. + attr :options + + # Create a new Rack::Builder instance and return the Rack application + # generated from it. + def self.app(default_app = nil, &block) + self.new(default_app, &block).to_app + end + + # Specifies middleware to use in a stack. + # + # class Middleware + # def initialize(app) + # @app = app + # end + # + # def call(env) + # env["rack.some_header"] = "setting an example" + # @app.call(env) + # end + # end + # + # use Middleware + # run lambda { |env| [200, { "content-type" => "text/plain" }, ["OK"]] } + # + # All requests through to this application will first be processed by the middleware class. + # The +call+ method in this example sets an additional environment key which then can be + # referenced in the application if required. + def use(middleware, *args, &block) + if @map + mapping, @map = @map, nil + @use << proc { |app| generate_map(app, mapping) } + end + @use << proc { |app| middleware.new(app, *args, &block) } + end + # :nocov: + ruby2_keywords(:use) if respond_to?(:ruby2_keywords, true) + # :nocov: + + # Takes a block or argument that is an object that responds to #call and + # returns a Rack response. + # + # You can use a block: + # + # run do |env| + # [200, { "content-type" => "text/plain" }, ["Hello World!"]] + # end + # + # You can also provide a lambda: + # + # run lambda { |env| [200, { "content-type" => "text/plain" }, ["OK"]] } + # + # You can also provide a class instance: + # + # class Heartbeat + # def call(env) + # [200, { "content-type" => "text/plain" }, ["OK"]] + # end + # end + # + # run Heartbeat.new + # + def run(app = nil, &block) + raise ArgumentError, "Both app and block given!" if app && block_given? + + @run = app || block + end + + # Takes a lambda or block that is used to warm-up the application. This block is called + # before the Rack application is returned by to_app. + # + # warmup do |app| + # client = Rack::MockRequest.new(app) + # client.get('/') + # end + # + # use SomeMiddleware + # run MyApp + def warmup(prc = nil, &block) + @warmup = prc || block + end + + # Creates a route within the application. Routes under the mapped path will be sent to + # the Rack application specified by run inside the block. Other requests will be sent to the + # default application specified by run outside the block. + # + # class App + # def call(env) + # [200, {'content-type' => 'text/plain'}, ["Hello World"]] + # end + # end + # + # class Heartbeat + # def call(env) + # [200, { "content-type" => "text/plain" }, ["OK"]] + # end + # end + # + # app = Rack::Builder.app do + # map '/heartbeat' do + # run Heartbeat.new + # end + # run App.new + # end + # + # run app + # + # The +use+ method can also be used inside the block to specify middleware to run under a specific path: + # + # app = Rack::Builder.app do + # map '/heartbeat' do + # use Middleware + # run Heartbeat.new + # end + # run App.new + # end + # + # This example includes a piece of middleware which will run before +/heartbeat+ requests hit +Heartbeat+. + # + # Note that providing a +path+ of +/+ will ignore any default application given in a +run+ statement + # outside the block. + def map(path, &block) + @map ||= {} + @map[path] = block + end + + # Freeze the app (set using run) and all middleware instances when building the application + # in to_app. + def freeze_app + @freeze_app = true + end + + # Return the Rack application generated by this instance. + def to_app + app = @map ? generate_map(@run, @map) : @run + fail "missing run or map statement" unless app + app.freeze if @freeze_app + app = @use.reverse.inject(app) { |a, e| e[a].tap { |x| x.freeze if @freeze_app } } + @warmup.call(app) if @warmup + app + end + + # Call the Rack application generated by this builder instance. Note that + # this rebuilds the Rack application and runs the warmup code (if any) + # every time it is called, so it should not be used if performance is important. + def call(env) + to_app.call(env) + end + + private + + # Generate a URLMap instance by generating new Rack applications for each + # map block in this instance. + def generate_map(default_app, mapping) + mapped = default_app ? { '/' => default_app } : {} + mapping.each { |r, b| mapped[r] = self.class.new(default_app, &b).to_app } + URLMap.new(mapped) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/cascade.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/cascade.rb new file mode 100644 index 00000000..9c952fd7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/cascade.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +require_relative 'constants' + +module Rack + # Rack::Cascade tries a request on several apps, and returns the + # first response that is not 404 or 405 (or in a list of configured + # status codes). If all applications tried return one of the configured + # status codes, return the last response. + + class Cascade + # An array of applications to try in order. + attr_reader :apps + + # Set the apps to send requests to, and what statuses result in + # cascading. Arguments: + # + # apps: An enumerable of rack applications. + # cascade_for: The statuses to use cascading for. If a response is received + # from an app, the next app is tried. + def initialize(apps, cascade_for = [404, 405]) + @apps = [] + apps.each { |app| add app } + + @cascade_for = {} + [*cascade_for].each { |status| @cascade_for[status] = true } + end + + # Call each app in order. If the responses uses a status that requires + # cascading, try the next app. If all responses require cascading, + # return the response from the last app. + def call(env) + return [404, { CONTENT_TYPE => "text/plain" }, []] if @apps.empty? + result = nil + last_body = nil + + @apps.each do |app| + # The SPEC says that the body must be closed after it has been iterated + # by the server, or if it is replaced by a middleware action. Cascade + # replaces the body each time a cascade happens. It is assumed that nil + # does not respond to close, otherwise the previous application body + # will be closed. The final application body will not be closed, as it + # will be passed to the server as a result. + last_body.close if last_body.respond_to? :close + + result = app.call(env) + return result unless @cascade_for.include?(result[0].to_i) + last_body = result[2] + end + + result + end + + # Append an app to the list of apps to cascade. This app will + # be tried last. + def add(app) + @apps << app + end + + # Whether the given app is one of the apps to cascade to. + def include?(app) + @apps.include?(app) + end + + alias_method :<<, :add + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/common_logger.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/common_logger.rb new file mode 100644 index 00000000..940b8bea --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/common_logger.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: true + +require_relative 'constants' +require_relative 'utils' +require_relative 'body_proxy' +require_relative 'request' + +module Rack + # Rack::CommonLogger forwards every request to the given +app+, and + # logs a line in the + # {Apache common log format}[http://httpd.apache.org/docs/1.3/logs.html#common] + # to the configured logger. + class CommonLogger + # Common Log Format: http://httpd.apache.org/docs/1.3/logs.html#common + # + # lilith.local - - [07/Aug/2006 23:58:02 -0400] "GET / HTTP/1.1" 500 - + # + # %{%s - %s [%s] "%s %s%s %s" %d %s\n} % + # + # The actual format is slightly different than the above due to the + # separation of SCRIPT_NAME and PATH_INFO, and because the elapsed + # time in seconds is included at the end. + FORMAT = %{%s - %s [%s] "%s %s%s%s %s" %d %s %0.4f } + + # +logger+ can be any object that supports the +write+ or +<<+ methods, + # which includes the standard library Logger. These methods are called + # with a single string argument, the log message. + # If +logger+ is nil, CommonLogger will fall back env['rack.errors']. + def initialize(app, logger = nil) + @app = app + @logger = logger + end + + # Log all requests in common_log format after a response has been + # returned. Note that if the app raises an exception, the request + # will not be logged, so if exception handling middleware are used, + # they should be loaded after this middleware. Additionally, because + # the logging happens after the request body has been fully sent, any + # exceptions raised during the sending of the response body will + # cause the request not to be logged. + def call(env) + began_at = Utils.clock_time + status, headers, body = response = @app.call(env) + + response[2] = BodyProxy.new(body) { log(env, status, headers, began_at) } + response + end + + private + + # Log the request to the configured logger. + def log(env, status, response_headers, began_at) + request = Rack::Request.new(env) + length = extract_content_length(response_headers) + + msg = sprintf(FORMAT, + request.ip || "-", + request.get_header("REMOTE_USER") || "-", + Time.now.strftime("%d/%b/%Y:%H:%M:%S %z"), + request.request_method, + request.script_name, + request.path_info, + request.query_string.empty? ? "" : "?#{request.query_string}", + request.get_header(SERVER_PROTOCOL), + status.to_s[0..3], + length, + Utils.clock_time - began_at) + + msg.gsub!(/[^[:print:]]/) { |c| sprintf("\\x%x", c.ord) } + msg[-1] = "\n" + + logger = @logger || request.get_header(RACK_ERRORS) + # Standard library logger doesn't support write but it supports << which actually + # calls to write on the log device without formatting + if logger.respond_to?(:write) + logger.write(msg) + else + logger << msg + end + end + + # Attempt to determine the content length for the response to + # include it in the logged data. + def extract_content_length(headers) + value = headers[CONTENT_LENGTH] + !value || value.to_s == '0' ? '-' : value + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/conditional_get.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/conditional_get.rb new file mode 100644 index 00000000..c3b334a2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/conditional_get.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true + +require_relative 'constants' +require_relative 'utils' +require_relative 'body_proxy' + +module Rack + + # Middleware that enables conditional GET using if-none-match and + # if-modified-since. The application should set either or both of the + # last-modified or etag response headers according to RFC 2616. When + # either of the conditions is met, the response body is set to be zero + # length and the response status is set to 304 Not Modified. + # + # Applications that defer response body generation until the body's each + # message is received will avoid response body generation completely when + # a conditional GET matches. + # + # Adapted from Michael Klishin's Merb implementation: + # https://github.com/wycats/merb/blob/master/merb-core/lib/merb-core/rack/middleware/conditional_get.rb + class ConditionalGet + def initialize(app) + @app = app + end + + # Return empty 304 response if the response has not been + # modified since the last request. + def call(env) + case env[REQUEST_METHOD] + when "GET", "HEAD" + status, headers, body = response = @app.call(env) + + if status == 200 && fresh?(env, headers) + response[0] = 304 + headers.delete(CONTENT_TYPE) + headers.delete(CONTENT_LENGTH) + response[2] = Rack::BodyProxy.new([]) do + body.close if body.respond_to?(:close) + end + end + response + else + @app.call(env) + end + end + + private + + # Return whether the response has not been modified since the + # last request. + def fresh?(env, headers) + # if-none-match has priority over if-modified-since per RFC 7232 + if none_match = env['HTTP_IF_NONE_MATCH'] + etag_matches?(none_match, headers) + elsif (modified_since = env['HTTP_IF_MODIFIED_SINCE']) && (modified_since = to_rfc2822(modified_since)) + modified_since?(modified_since, headers) + end + end + + # Whether the etag response header matches the if-none-match request header. + # If so, the request has not been modified. + def etag_matches?(none_match, headers) + headers[ETAG] == none_match + end + + # Whether the last-modified response header matches the if-modified-since + # request header. If so, the request has not been modified. + def modified_since?(modified_since, headers) + last_modified = to_rfc2822(headers['last-modified']) and + modified_since >= last_modified + end + + # Return a Time object for the given string (which should be in RFC2822 + # format), or nil if the string cannot be parsed. + def to_rfc2822(since) + # shortest possible valid date is the obsolete: 1 Nov 97 09:55 A + # anything shorter is invalid, this avoids exceptions for common cases + # most common being the empty string + if since && since.length >= 16 + # NOTE: there is no trivial way to write this in a non exception way + # _rfc2822 returns a hash but is not that usable + Time.rfc2822(since) rescue nil + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/config.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/config.rb new file mode 100644 index 00000000..41f6f7dd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/config.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Rack + # Rack::Config modifies the environment using the block given during + # initialization. + # + # Example: + # use Rack::Config do |env| + # env['my-key'] = 'some-value' + # end + class Config + def initialize(app, &block) + @app = app + @block = block + end + + def call(env) + @block.call(env) + @app.call(env) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/constants.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/constants.rb new file mode 100644 index 00000000..e9b6e10e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/constants.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +module Rack + # Request env keys + HTTP_HOST = 'HTTP_HOST' + HTTP_PORT = 'HTTP_PORT' + HTTPS = 'HTTPS' + PATH_INFO = 'PATH_INFO' + REQUEST_METHOD = 'REQUEST_METHOD' + REQUEST_PATH = 'REQUEST_PATH' + SCRIPT_NAME = 'SCRIPT_NAME' + QUERY_STRING = 'QUERY_STRING' + SERVER_PROTOCOL = 'SERVER_PROTOCOL' + SERVER_NAME = 'SERVER_NAME' + SERVER_PORT = 'SERVER_PORT' + HTTP_COOKIE = 'HTTP_COOKIE' + + # Response Header Keys + CACHE_CONTROL = 'cache-control' + CONTENT_LENGTH = 'content-length' + CONTENT_TYPE = 'content-type' + ETAG = 'etag' + EXPIRES = 'expires' + SET_COOKIE = 'set-cookie' + TRANSFER_ENCODING = 'transfer-encoding' + + # HTTP method verbs + GET = 'GET' + POST = 'POST' + PUT = 'PUT' + PATCH = 'PATCH' + DELETE = 'DELETE' + HEAD = 'HEAD' + OPTIONS = 'OPTIONS' + CONNECT = 'CONNECT' + LINK = 'LINK' + UNLINK = 'UNLINK' + TRACE = 'TRACE' + + # Rack environment variables + RACK_VERSION = 'rack.version' + RACK_TEMPFILES = 'rack.tempfiles' + RACK_EARLY_HINTS = 'rack.early_hints' + RACK_ERRORS = 'rack.errors' + RACK_LOGGER = 'rack.logger' + RACK_INPUT = 'rack.input' + RACK_SESSION = 'rack.session' + RACK_SESSION_OPTIONS = 'rack.session.options' + RACK_SHOWSTATUS_DETAIL = 'rack.showstatus.detail' + RACK_URL_SCHEME = 'rack.url_scheme' + RACK_HIJACK = 'rack.hijack' + RACK_IS_HIJACK = 'rack.hijack?' + RACK_RECURSIVE_INCLUDE = 'rack.recursive.include' + RACK_MULTIPART_BUFFER_SIZE = 'rack.multipart.buffer_size' + RACK_MULTIPART_TEMPFILE_FACTORY = 'rack.multipart.tempfile_factory' + RACK_RESPONSE_FINISHED = 'rack.response_finished' + RACK_REQUEST_FORM_INPUT = 'rack.request.form_input' + RACK_REQUEST_FORM_HASH = 'rack.request.form_hash' + RACK_REQUEST_FORM_PAIRS = 'rack.request.form_pairs' + RACK_REQUEST_FORM_VARS = 'rack.request.form_vars' + RACK_REQUEST_FORM_ERROR = 'rack.request.form_error' + RACK_REQUEST_COOKIE_HASH = 'rack.request.cookie_hash' + RACK_REQUEST_COOKIE_STRING = 'rack.request.cookie_string' + RACK_REQUEST_QUERY_HASH = 'rack.request.query_hash' + RACK_REQUEST_QUERY_STRING = 'rack.request.query_string' + RACK_METHODOVERRIDE_ORIGINAL_METHOD = 'rack.methodoverride.original_method' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/content_length.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/content_length.rb new file mode 100644 index 00000000..cbac93ab --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/content_length.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require_relative 'constants' +require_relative 'utils' + +module Rack + + # Sets the content-length header on responses that do not specify + # a content-length or transfer-encoding header. Note that this + # does not fix responses that have an invalid content-length + # header specified. + class ContentLength + include Rack::Utils + + def initialize(app) + @app = app + end + + def call(env) + status, headers, body = response = @app.call(env) + + if !STATUS_WITH_NO_ENTITY_BODY.key?(status.to_i) && + !headers[CONTENT_LENGTH] && + !headers[TRANSFER_ENCODING] && + body.respond_to?(:to_ary) + + response[2] = body = body.to_ary + headers[CONTENT_LENGTH] = body.sum(&:bytesize).to_s + end + + response + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/content_type.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/content_type.rb new file mode 100644 index 00000000..19f07824 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/content_type.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require_relative 'constants' +require_relative 'utils' + +module Rack + + # Sets the content-type header on responses which don't have one. + # + # Builder Usage: + # use Rack::ContentType, "text/plain" + # + # When no content type argument is provided, "text/html" is the + # default. + class ContentType + include Rack::Utils + + def initialize(app, content_type = "text/html") + @app = app + @content_type = content_type + end + + def call(env) + status, headers, _ = response = @app.call(env) + + unless STATUS_WITH_NO_ENTITY_BODY.key?(status.to_i) + headers[CONTENT_TYPE] ||= @content_type + end + + response + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/deflater.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/deflater.rb new file mode 100644 index 00000000..cc01c32a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/deflater.rb @@ -0,0 +1,158 @@ +# frozen_string_literal: true + +require "zlib" +require "time" # for Time.httpdate + +require_relative 'constants' +require_relative 'utils' +require_relative 'request' +require_relative 'body_proxy' + +module Rack + # This middleware enables content encoding of http responses, + # usually for purposes of compression. + # + # Currently supported encodings: + # + # * gzip + # * identity (no transformation) + # + # This middleware automatically detects when encoding is supported + # and allowed. For example no encoding is made when a cache + # directive of 'no-transform' is present, when the response status + # code is one that doesn't allow an entity body, or when the body + # is empty. + # + # Note that despite the name, Deflater does not support the +deflate+ + # encoding. + class Deflater + # Creates Rack::Deflater middleware. Options: + # + # :if :: a lambda enabling / disabling deflation based on returned boolean value + # (e.g use Rack::Deflater, :if => lambda { |*, body| sum=0; body.each { |i| sum += i.length }; sum > 512 }). + # However, be aware that calling `body.each` inside the block will break cases where `body.each` is not idempotent, + # such as when it is an +IO+ instance. + # :include :: a list of content types that should be compressed. By default, all content types are compressed. + # :sync :: determines if the stream is going to be flushed after every chunk. Flushing after every chunk reduces + # latency for time-sensitive streaming applications, but hurts compression and throughput. + # Defaults to +true+. + def initialize(app, options = {}) + @app = app + @condition = options[:if] + @compressible_types = options[:include] + @sync = options.fetch(:sync, true) + end + + def call(env) + status, headers, body = response = @app.call(env) + + unless should_deflate?(env, status, headers, body) + return response + end + + request = Request.new(env) + + encoding = Utils.select_best_encoding(%w(gzip identity), + request.accept_encoding) + + # Set the Vary HTTP header. + vary = headers["vary"].to_s.split(",").map(&:strip) + unless vary.include?("*") || vary.any?{|v| v.downcase == 'accept-encoding'} + headers["vary"] = vary.push("Accept-Encoding").join(",") + end + + case encoding + when "gzip" + headers['content-encoding'] = "gzip" + headers.delete(CONTENT_LENGTH) + mtime = headers["last-modified"] + mtime = Time.httpdate(mtime).to_i if mtime + response[2] = GzipStream.new(body, mtime, @sync) + response + when "identity" + response + else # when nil + # Only possible encoding values here are 'gzip', 'identity', and nil + message = "An acceptable encoding for the requested resource #{request.fullpath} could not be found." + bp = Rack::BodyProxy.new([message]) { body.close if body.respond_to?(:close) } + [406, { CONTENT_TYPE => "text/plain", CONTENT_LENGTH => message.length.to_s }, bp] + end + end + + # Body class used for gzip encoded responses. + class GzipStream + + BUFFER_LENGTH = 128 * 1_024 + + # Initialize the gzip stream. Arguments: + # body :: Response body to compress with gzip + # mtime :: The modification time of the body, used to set the + # modification time in the gzip header. + # sync :: Whether to flush each gzip chunk as soon as it is ready. + def initialize(body, mtime, sync) + @body = body + @mtime = mtime + @sync = sync + end + + # Yield gzip compressed strings to the given block. + def each(&block) + @writer = block + gzip = ::Zlib::GzipWriter.new(self) + gzip.mtime = @mtime if @mtime + # @body.each is equivalent to @body.gets (slow) + if @body.is_a? ::File # XXX: Should probably be ::IO + while part = @body.read(BUFFER_LENGTH) + gzip.write(part) + gzip.flush if @sync + end + else + @body.each { |part| + # Skip empty strings, as they would result in no output, + # and flushing empty parts would raise Zlib::BufError. + next if part.empty? + gzip.write(part) + gzip.flush if @sync + } + end + ensure + gzip.finish + end + + # Call the block passed to #each with the gzipped data. + def write(data) + @writer.call(data) + end + + # Close the original body if possible. + def close + @body.close if @body.respond_to?(:close) + end + end + + private + + # Whether the body should be compressed. + def should_deflate?(env, status, headers, body) + # Skip compressing empty entity body responses and responses with + # no-transform set. + if Utils::STATUS_WITH_NO_ENTITY_BODY.key?(status.to_i) || + /\bno-transform\b/.match?(headers[CACHE_CONTROL].to_s) || + headers['content-encoding']&.!~(/\bidentity\b/) + return false + end + + # Skip if @compressible_types are given and does not include request's content type + return false if @compressible_types && !(headers.has_key?(CONTENT_TYPE) && @compressible_types.include?(headers[CONTENT_TYPE][/[^;]*/])) + + # Skip if @condition lambda is given and evaluates to false + return false if @condition && !@condition.call(env, status, headers, body) + + # No point in compressing empty body, also handles usage with + # Rack::Sendfile. + return false if headers[CONTENT_LENGTH] == '0' + + true + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/directory.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/directory.rb new file mode 100644 index 00000000..089623f9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/directory.rb @@ -0,0 +1,205 @@ +# frozen_string_literal: true + +require 'time' + +require_relative 'constants' +require_relative 'utils' +require_relative 'head' +require_relative 'mime' +require_relative 'files' + +module Rack + # Rack::Directory serves entries below the +root+ given, according to the + # path info of the Rack request. If a directory is found, the file's contents + # will be presented in an html based index. If a file is found, the env will + # be passed to the specified +app+. + # + # If +app+ is not specified, a Rack::Files of the same +root+ will be used. + + class Directory + DIR_FILE = "%s%s%s%s\n" + DIR_PAGE_HEADER = <<-PAGE + + %s + + + +

%s

+
+ + + + + + + + PAGE + DIR_PAGE_FOOTER = <<-PAGE +
NameSizeTypeLast Modified
+
+ + PAGE + + # Body class for directory entries, showing an index page with links + # to each file. + class DirectoryBody < Struct.new(:root, :path, :files) + # Yield strings for each part of the directory entry + def each + show_path = Utils.escape_html(path.sub(/^#{root}/, '')) + yield(DIR_PAGE_HEADER % [ show_path, show_path ]) + + unless path.chomp('/') == root + yield(DIR_FILE % DIR_FILE_escape(files.call('..'))) + end + + Dir.foreach(path) do |basename| + next if basename.start_with?('.') + next unless f = files.call(basename) + yield(DIR_FILE % DIR_FILE_escape(f)) + end + + yield(DIR_PAGE_FOOTER) + end + + private + + # Escape each element in the array of html strings. + def DIR_FILE_escape(htmls) + htmls.map { |e| Utils.escape_html(e) } + end + end + + # The root of the directory hierarchy. Only requests for files and + # directories inside of the root directory are supported. + attr_reader :root + + # Set the root directory and application for serving files. + def initialize(root, app = nil) + @root = ::File.expand_path(root) + @app = app || Files.new(@root) + @head = Head.new(method(:get)) + end + + def call(env) + # strip body if this is a HEAD call + @head.call env + end + + # Internals of request handling. Similar to call but does + # not remove body for HEAD requests. + def get(env) + script_name = env[SCRIPT_NAME] + path_info = Utils.unescape_path(env[PATH_INFO]) + + if client_error_response = check_bad_request(path_info) || check_forbidden(path_info) + client_error_response + else + path = ::File.join(@root, path_info) + list_path(env, path, path_info, script_name) + end + end + + # Rack response to use for requests with invalid paths, or nil if path is valid. + def check_bad_request(path_info) + return if Utils.valid_path?(path_info) + + body = "Bad Request\n" + [400, { CONTENT_TYPE => "text/plain", + CONTENT_LENGTH => body.bytesize.to_s, + "x-cascade" => "pass" }, [body]] + end + + # Rack response to use for requests with paths outside the root, or nil if path is inside the root. + def check_forbidden(path_info) + return unless path_info.include? ".." + return if ::File.expand_path(::File.join(@root, path_info)).start_with?(@root) + + body = "Forbidden\n" + [403, { CONTENT_TYPE => "text/plain", + CONTENT_LENGTH => body.bytesize.to_s, + "x-cascade" => "pass" }, [body]] + end + + # Rack response to use for directories under the root. + def list_directory(path_info, path, script_name) + url_head = (script_name.split('/') + path_info.split('/')).map do |part| + Utils.escape_path part + end + + # Globbing not safe as path could contain glob metacharacters + body = DirectoryBody.new(@root, path, ->(basename) do + stat = stat(::File.join(path, basename)) + next unless stat + + url = ::File.join(*url_head + [Utils.escape_path(basename)]) + mtime = stat.mtime.httpdate + if stat.directory? + type = 'directory' + size = '-' + url << '/' + if basename == '..' + basename = 'Parent Directory' + else + basename << '/' + end + else + type = Mime.mime_type(::File.extname(basename)) + size = filesize_format(stat.size) + end + + [ url, basename, size, type, mtime ] + end) + + [ 200, { CONTENT_TYPE => 'text/html; charset=utf-8' }, body ] + end + + # File::Stat for the given path, but return nil for missing/bad entries. + def stat(path) + ::File.stat(path) + rescue Errno::ENOENT, Errno::ELOOP + return nil + end + + # Rack response to use for files and directories under the root. + # Unreadable and non-file, non-directory entries will get a 404 response. + def list_path(env, path, path_info, script_name) + if (stat = stat(path)) && stat.readable? + return @app.call(env) if stat.file? + return list_directory(path_info, path, script_name) if stat.directory? + end + + entity_not_found(path_info) + end + + # Rack response to use for unreadable and non-file, non-directory entries. + def entity_not_found(path_info) + body = "Entity not found: #{path_info}\n" + [404, { CONTENT_TYPE => "text/plain", + CONTENT_LENGTH => body.bytesize.to_s, + "x-cascade" => "pass" }, [body]] + end + + # Stolen from Ramaze + FILESIZE_FORMAT = [ + ['%.1fT', 1 << 40], + ['%.1fG', 1 << 30], + ['%.1fM', 1 << 20], + ['%.1fK', 1 << 10], + ] + + # Provide human readable file sizes + def filesize_format(int) + FILESIZE_FORMAT.each do |format, size| + return format % (int.to_f / size) if int >= size + end + + "#{int}B" + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/etag.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/etag.rb new file mode 100644 index 00000000..1841beb3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/etag.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +require 'digest/sha2' + +require_relative 'constants' +require_relative 'utils' + +module Rack + # Automatically sets the etag header on all String bodies. + # + # The etag header is skipped if etag or last-modified headers are sent or if + # a sendfile body (body.responds_to :to_path) is given (since such cases + # should be handled by apache/nginx). + # + # On initialization, you can pass two parameters: a cache-control directive + # used when etag is absent and a directive when it is present. The first + # defaults to nil, while the second defaults to "max-age=0, private, must-revalidate" + class ETag + ETAG_STRING = Rack::ETAG + DEFAULT_CACHE_CONTROL = "max-age=0, private, must-revalidate" + + def initialize(app, no_cache_control = nil, cache_control = DEFAULT_CACHE_CONTROL) + @app = app + @cache_control = cache_control + @no_cache_control = no_cache_control + end + + def call(env) + status, headers, body = response = @app.call(env) + + if etag_status?(status) && body.respond_to?(:to_ary) && !skip_caching?(headers) + body = body.to_ary + digest = digest_body(body) + headers[ETAG_STRING] = %(W/"#{digest}") if digest + + # Body was modified, so we need to re-assign it: + response[2] = body + end + + unless headers[CACHE_CONTROL] + if digest + headers[CACHE_CONTROL] = @cache_control if @cache_control + else + headers[CACHE_CONTROL] = @no_cache_control if @no_cache_control + end + end + + response + end + + private + + def etag_status?(status) + status == 200 || status == 201 + end + + def skip_caching?(headers) + headers.key?(ETAG_STRING) || headers.key?('last-modified') + end + + def digest_body(body) + digest = nil + + body.each do |part| + (digest ||= Digest::SHA256.new) << part unless part.empty? + end + + digest && digest.hexdigest.byteslice(0,32) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/events.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/events.rb new file mode 100644 index 00000000..c7bb201f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/events.rb @@ -0,0 +1,157 @@ +# frozen_string_literal: true + +require_relative 'body_proxy' +require_relative 'request' +require_relative 'response' + +module Rack + ### This middleware provides hooks to certain places in the request / + # response lifecycle. This is so that middleware that don't need to filter + # the response data can safely leave it alone and not have to send messages + # down the traditional "rack stack". + # + # The events are: + # + # * on_start(request, response) + # + # This event is sent at the start of the request, before the next + # middleware in the chain is called. This method is called with a request + # object, and a response object. Right now, the response object is always + # nil, but in the future it may actually be a real response object. + # + # * on_commit(request, response) + # + # The response has been committed. The application has returned, but the + # response has not been sent to the webserver yet. This method is always + # called with a request object and the response object. The response + # object is constructed from the rack triple that the application returned. + # Changes may still be made to the response object at this point. + # + # * on_send(request, response) + # + # The webserver has started iterating over the response body and presumably + # has started sending data over the wire. This method is always called with + # a request object and the response object. The response object is + # constructed from the rack triple that the application returned. Changes + # SHOULD NOT be made to the response object as the webserver has already + # started sending data. Any mutations will likely result in an exception. + # + # * on_finish(request, response) + # + # The webserver has closed the response, and all data has been written to + # the response socket. The request and response object should both be + # read-only at this point. The body MAY NOT be available on the response + # object as it may have been flushed to the socket. + # + # * on_error(request, response, error) + # + # An exception has occurred in the application or an `on_commit` event. + # This method will get the request, the response (if available) and the + # exception that was raised. + # + # ## Order + # + # `on_start` is called on the handlers in the order that they were passed to + # the constructor. `on_commit`, on_send`, `on_finish`, and `on_error` are + # called in the reverse order. `on_finish` handlers are called inside an + # `ensure` block, so they are guaranteed to be called even if something + # raises an exception. If something raises an exception in a `on_finish` + # method, then nothing is guaranteed. + + class Events + module Abstract + def on_start(req, res) + end + + def on_commit(req, res) + end + + def on_send(req, res) + end + + def on_finish(req, res) + end + + def on_error(req, res, e) + end + end + + class EventedBodyProxy < Rack::BodyProxy # :nodoc: + attr_reader :request, :response + + def initialize(body, request, response, handlers, &block) + super(body, &block) + @request = request + @response = response + @handlers = handlers + end + + def each + @handlers.reverse_each { |handler| handler.on_send request, response } + super + end + end + + class BufferedResponse < Rack::Response::Raw # :nodoc: + attr_reader :body + + def initialize(status, headers, body) + super(status, headers) + @body = body + end + + def to_a; [status, headers, body]; end + end + + def initialize(app, handlers) + @app = app + @handlers = handlers + end + + def call(env) + request = make_request env + on_start request, nil + + begin + status, headers, body = @app.call request.env + response = make_response status, headers, body + on_commit request, response + rescue StandardError => e + on_error request, response, e + on_finish request, response + raise + end + + body = EventedBodyProxy.new(body, request, response, @handlers) do + on_finish request, response + end + [response.status, response.headers, body] + end + + private + + def on_error(request, response, e) + @handlers.reverse_each { |handler| handler.on_error request, response, e } + end + + def on_commit(request, response) + @handlers.reverse_each { |handler| handler.on_commit request, response } + end + + def on_start(request, response) + @handlers.each { |handler| handler.on_start request, nil } + end + + def on_finish(request, response) + @handlers.reverse_each { |handler| handler.on_finish request, response } + end + + def make_request(env) + Rack::Request.new env + end + + def make_response(status, headers, body) + BufferedResponse.new status, headers, body + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/files.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/files.rb new file mode 100644 index 00000000..5b8353f5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/files.rb @@ -0,0 +1,216 @@ +# frozen_string_literal: true + +require 'time' + +require_relative 'constants' +require_relative 'head' +require_relative 'utils' +require_relative 'request' +require_relative 'mime' + +module Rack + # Rack::Files serves files below the +root+ directory given, according to the + # path info of the Rack request. + # e.g. when Rack::Files.new("/etc") is used, you can access 'passwd' file + # as http://localhost:9292/passwd + # + # Handlers can detect if bodies are a Rack::Files, and use mechanisms + # like sendfile on the +path+. + + class Files + ALLOWED_VERBS = %w[GET HEAD OPTIONS] + ALLOW_HEADER = ALLOWED_VERBS.join(', ') + MULTIPART_BOUNDARY = 'AaB03x' + + attr_reader :root + + def initialize(root, headers = {}, default_mime = 'text/plain') + @root = (::File.expand_path(root) if root) + @headers = headers + @default_mime = default_mime + @head = Rack::Head.new(lambda { |env| get env }) + end + + def call(env) + # HEAD requests drop the response body, including 4xx error messages. + @head.call env + end + + def get(env) + request = Rack::Request.new env + unless ALLOWED_VERBS.include? request.request_method + return fail(405, "Method Not Allowed", { 'allow' => ALLOW_HEADER }) + end + + path_info = Utils.unescape_path request.path_info + return fail(400, "Bad Request") unless Utils.valid_path?(path_info) + + clean_path_info = Utils.clean_path_info(path_info) + path = ::File.join(@root, clean_path_info) + + available = begin + ::File.file?(path) && ::File.readable?(path) + rescue SystemCallError + # Not sure in what conditions this exception can occur, but this + # is a safe way to handle such an error. + # :nocov: + false + # :nocov: + end + + if available + serving(request, path) + else + fail(404, "File not found: #{path_info}") + end + end + + def serving(request, path) + if request.options? + return [200, { 'allow' => ALLOW_HEADER, CONTENT_LENGTH => '0' }, []] + end + last_modified = ::File.mtime(path).httpdate + return [304, {}, []] if request.get_header('HTTP_IF_MODIFIED_SINCE') == last_modified + + headers = { "last-modified" => last_modified } + mime_type = mime_type path, @default_mime + headers[CONTENT_TYPE] = mime_type if mime_type + + # Set custom headers + headers.merge!(@headers) if @headers + + status = 200 + size = filesize path + + ranges = Rack::Utils.get_byte_ranges(request.get_header('HTTP_RANGE'), size) + if ranges.nil? + # No ranges: + ranges = [0..size - 1] + elsif ranges.empty? + # Unsatisfiable. Return error, and file size: + response = fail(416, "Byte range unsatisfiable") + response[1]["content-range"] = "bytes */#{size}" + return response + else + # Partial content + partial_content = true + + if ranges.size == 1 + range = ranges[0] + headers["content-range"] = "bytes #{range.begin}-#{range.end}/#{size}" + else + headers[CONTENT_TYPE] = "multipart/byteranges; boundary=#{MULTIPART_BOUNDARY}" + end + + status = 206 + body = BaseIterator.new(path, ranges, mime_type: mime_type, size: size) + size = body.bytesize + end + + headers[CONTENT_LENGTH] = size.to_s + + if request.head? + body = [] + elsif !partial_content + body = Iterator.new(path, ranges, mime_type: mime_type, size: size) + end + + [status, headers, body] + end + + class BaseIterator + attr_reader :path, :ranges, :options + + def initialize(path, ranges, options) + @path = path + @ranges = ranges + @options = options + end + + def each + ::File.open(path, "rb") do |file| + ranges.each do |range| + yield multipart_heading(range) if multipart? + + each_range_part(file, range) do |part| + yield part + end + end + + yield "\r\n--#{MULTIPART_BOUNDARY}--\r\n" if multipart? + end + end + + def bytesize + size = ranges.inject(0) do |sum, range| + sum += multipart_heading(range).bytesize if multipart? + sum += range.size + end + size += "\r\n--#{MULTIPART_BOUNDARY}--\r\n".bytesize if multipart? + size + end + + def close; end + + private + + def multipart? + ranges.size > 1 + end + + def multipart_heading(range) +<<-EOF +\r +--#{MULTIPART_BOUNDARY}\r +content-type: #{options[:mime_type]}\r +content-range: bytes #{range.begin}-#{range.end}/#{options[:size]}\r +\r +EOF + end + + def each_range_part(file, range) + file.seek(range.begin) + remaining_len = range.end - range.begin + 1 + while remaining_len > 0 + part = file.read([8192, remaining_len].min) + break unless part + remaining_len -= part.length + + yield part + end + end + end + + class Iterator < BaseIterator + alias :to_path :path + end + + private + + def fail(status, body, headers = {}) + body += "\n" + + [ + status, + { + CONTENT_TYPE => "text/plain", + CONTENT_LENGTH => body.size.to_s, + "x-cascade" => "pass" + }.merge!(headers), + [body] + ] + end + + # The MIME type for the contents of the file located at @path + def mime_type(path, default_mime) + Mime.mime_type(::File.extname(path), default_mime) + end + + def filesize(path) + # We check via File::size? whether this file provides size info + # via stat (e.g. /proc files often don't), otherwise we have to + # figure it out by reading the whole file into memory. + ::File.size?(path) || ::File.read(path).bytesize + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/head.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/head.rb new file mode 100644 index 00000000..c1c430f6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/head.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +require_relative 'constants' +require_relative 'body_proxy' + +module Rack + # Rack::Head returns an empty body for all HEAD requests. It leaves + # all other requests unchanged. + class Head + def initialize(app) + @app = app + end + + def call(env) + _, _, body = response = @app.call(env) + + if env[REQUEST_METHOD] == HEAD + response[2] = Rack::BodyProxy.new([]) do + body.close if body.respond_to? :close + end + end + + response + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/headers.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/headers.rb new file mode 100644 index 00000000..cedf3a8f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/headers.rb @@ -0,0 +1,238 @@ +# frozen_string_literal: true + +module Rack + # Rack::Headers is a Hash subclass that downcases all keys. It's designed + # to be used by rack applications that don't implement the Rack 3 SPEC + # (by using non-lowercase response header keys), automatically handling + # the downcasing of keys. + class Headers < Hash + KNOWN_HEADERS = {} + %w( + Accept-CH + Accept-Patch + Accept-Ranges + Access-Control-Allow-Credentials + Access-Control-Allow-Headers + Access-Control-Allow-Methods + Access-Control-Allow-Origin + Access-Control-Expose-Headers + Access-Control-Max-Age + Age + Allow + Alt-Svc + Cache-Control + Connection + Content-Disposition + Content-Encoding + Content-Language + Content-Length + Content-Location + Content-MD5 + Content-Range + Content-Security-Policy + Content-Security-Policy-Report-Only + Content-Type + Date + Delta-Base + ETag + Expect-CT + Expires + Feature-Policy + IM + Last-Modified + Link + Location + NEL + P3P + Permissions-Policy + Pragma + Preference-Applied + Proxy-Authenticate + Public-Key-Pins + Referrer-Policy + Refresh + Report-To + Retry-After + Server + Set-Cookie + Status + Strict-Transport-Security + Timing-Allow-Origin + Tk + Trailer + Transfer-Encoding + Upgrade + Vary + Via + WWW-Authenticate + Warning + X-Cascade + X-Content-Duration + X-Content-Security-Policy + X-Content-Type-Options + X-Correlation-ID + X-Correlation-Id + X-Download-Options + X-Frame-Options + X-Permitted-Cross-Domain-Policies + X-Powered-By + X-Redirect-By + X-Request-ID + X-Request-Id + X-Runtime + X-UA-Compatible + X-WebKit-CS + X-XSS-Protection + ).each do |str| + downcased = str.downcase.freeze + KNOWN_HEADERS[str] = KNOWN_HEADERS[downcased] = downcased + end + + def self.[](*items) + if items.length % 2 != 0 + if items.length == 1 && items.first.is_a?(Hash) + new.merge!(items.first) + else + raise ArgumentError, "odd number of arguments for Rack::Headers" + end + else + hash = new + loop do + break if items.length == 0 + key = items.shift + value = items.shift + hash[key] = value + end + hash + end + end + + def [](key) + super(downcase_key(key)) + end + + def []=(key, value) + super(KNOWN_HEADERS[key] || key.downcase.freeze, value) + end + alias store []= + + def assoc(key) + super(downcase_key(key)) + end + + def compare_by_identity + raise TypeError, "Rack::Headers cannot compare by identity, use regular Hash" + end + + def delete(key) + super(downcase_key(key)) + end + + def dig(key, *a) + super(downcase_key(key), *a) + end + + def fetch(key, *default, &block) + key = downcase_key(key) + super + end + + def fetch_values(*a) + super(*a.map!{|key| downcase_key(key)}) + end + + def has_key?(key) + super(downcase_key(key)) + end + alias include? has_key? + alias key? has_key? + alias member? has_key? + + def invert + hash = self.class.new + each{|key, value| hash[value] = key} + hash + end + + def merge(hash, &block) + dup.merge!(hash, &block) + end + + def reject(&block) + hash = dup + hash.reject!(&block) + hash + end + + def replace(hash) + clear + update(hash) + end + + def select(&block) + hash = dup + hash.select!(&block) + hash + end + + def to_proc + lambda{|x| self[x]} + end + + def transform_values(&block) + dup.transform_values!(&block) + end + + def update(hash, &block) + hash.each do |key, value| + self[key] = if block_given? && include?(key) + block.call(key, self[key], value) + else + value + end + end + self + end + alias merge! update + + def values_at(*keys) + keys.map{|key| self[key]} + end + + # :nocov: + if RUBY_VERSION >= '2.5' + # :nocov: + def slice(*a) + h = self.class.new + a.each{|k| h[k] = self[k] if has_key?(k)} + h + end + + def transform_keys(&block) + dup.transform_keys!(&block) + end + + def transform_keys! + hash = self.class.new + each do |k, v| + hash[yield k] = v + end + replace(hash) + end + end + + # :nocov: + if RUBY_VERSION >= '3.0' + # :nocov: + def except(*a) + super(*a.map!{|key| downcase_key(key)}) + end + end + + private + + def downcase_key(key) + key.is_a?(String) ? KNOWN_HEADERS[key] || key.downcase : key + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/lint.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/lint.rb new file mode 100644 index 00000000..4f36c2eb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/lint.rb @@ -0,0 +1,991 @@ +# frozen_string_literal: true + +require 'forwardable' +require 'uri' + +require_relative 'constants' +require_relative 'utils' + +module Rack + # Rack::Lint validates your application and the requests and + # responses according to the Rack spec. + + class Lint + REQUEST_PATH_ORIGIN_FORM = /\A\/[^#]*\z/ + REQUEST_PATH_ABSOLUTE_FORM = /\A#{Utils::URI_PARSER.make_regexp}\z/ + REQUEST_PATH_AUTHORITY_FORM = /\A[^\/:]+:\d+\z/ + REQUEST_PATH_ASTERISK_FORM = '*' + + def initialize(app) + @app = app + end + + # :stopdoc: + + class LintError < RuntimeError; end + # AUTHORS: n.b. The trailing whitespace between paragraphs is important and + # should not be removed. The whitespace creates paragraphs in the RDoc + # output. + # + ## This specification aims to formalize the Rack protocol. You + ## can (and should) use Rack::Lint to enforce it. + ## + ## When you develop middleware, be sure to add a Lint before and + ## after to catch all mistakes. + ## + ## = Rack applications + ## + ## A Rack application is a Ruby object (not a class) that + ## responds to +call+. + def call(env = nil) + Wrapper.new(@app, env).response + end + + class Wrapper + def initialize(app, env) + @app = app + @env = env + @response = nil + @head_request = false + + @status = nil + @headers = nil + @body = nil + @invoked = nil + @content_length = nil + @closed = false + @size = 0 + end + + def response + ## It takes exactly one argument, the *environment* + raise LintError, "No env given" unless @env + check_environment(@env) + + ## and returns a non-frozen Array of exactly three values: + @response = @app.call(@env) + raise LintError, "response is not an Array, but #{@response.class}" unless @response.kind_of? Array + raise LintError, "response is frozen" if @response.frozen? + raise LintError, "response array has #{@response.size} elements instead of 3" unless @response.size == 3 + + @status, @headers, @body = @response + ## The *status*, + check_status(@status) + + ## the *headers*, + check_headers(@headers) + + hijack_proc = check_hijack_response(@headers, @env) + if hijack_proc + @headers[RACK_HIJACK] = hijack_proc + end + + ## and the *body*. + check_content_type_header(@status, @headers) + check_content_length_header(@status, @headers) + check_rack_protocol_header(@status, @headers) + @head_request = @env[REQUEST_METHOD] == HEAD + + @lint = (@env['rack.lint'] ||= []) << self + + if (@env['rack.lint.body_iteration'] ||= 0) > 0 + raise LintError, "Middleware must not call #each directly" + end + + return [@status, @headers, self] + end + + ## + ## == The Environment + ## + def check_environment(env) + ## The environment must be an unfrozen instance of Hash that includes + ## CGI-like headers. The Rack application is free to modify the + ## environment. + raise LintError, "env #{env.inspect} is not a Hash, but #{env.class}" unless env.kind_of? Hash + raise LintError, "env should not be frozen, but is" if env.frozen? + + ## + ## The environment is required to include these variables + ## (adopted from {PEP 333}[https://peps.python.org/pep-0333/]), except when they'd be empty, but see + ## below. + + ## REQUEST_METHOD:: The HTTP request method, such as + ## "GET" or "POST". This cannot ever + ## be an empty string, and so is + ## always required. + + ## SCRIPT_NAME:: The initial portion of the request + ## URL's "path" that corresponds to the + ## application object, so that the + ## application knows its virtual + ## "location". This may be an empty + ## string, if the application corresponds + ## to the "root" of the server. + + ## PATH_INFO:: The remainder of the request URL's + ## "path", designating the virtual + ## "location" of the request's target + ## within the application. This may be an + ## empty string, if the request URL targets + ## the application root and does not have a + ## trailing slash. This value may be + ## percent-encoded when originating from + ## a URL. + + ## QUERY_STRING:: The portion of the request URL that + ## follows the ?, if any. May be + ## empty, but is always required! + + ## SERVER_NAME:: When combined with SCRIPT_NAME and + ## PATH_INFO, these variables can be + ## used to complete the URL. Note, however, + ## that HTTP_HOST, if present, + ## should be used in preference to + ## SERVER_NAME for reconstructing + ## the request URL. + ## SERVER_NAME can never be an empty + ## string, and so is always required. + + ## SERVER_PORT:: An optional +Integer+ which is the port the + ## server is running on. Should be specified if + ## the server is running on a non-standard port. + + ## SERVER_PROTOCOL:: A string representing the HTTP version used + ## for the request. + + ## HTTP_ Variables:: Variables corresponding to the + ## client-supplied HTTP request + ## headers (i.e., variables whose + ## names begin with HTTP_). The + ## presence or absence of these + ## variables should correspond with + ## the presence or absence of the + ## appropriate HTTP header in the + ## request. See + ## {RFC3875 section 4.1.18}[https://tools.ietf.org/html/rfc3875#section-4.1.18] + ## for specific behavior. + + ## In addition to this, the Rack environment must include these + ## Rack-specific variables: + + ## rack.url_scheme:: +http+ or +https+, depending on the + ## request URL. + + ## rack.input:: See below, the input stream. + + ## rack.errors:: See below, the error stream. + + ## rack.hijack?:: See below, if present and true, indicates + ## that the server supports partial hijacking. + + ## rack.hijack:: See below, if present, an object responding + ## to +call+ that is used to perform a full + ## hijack. + + ## rack.protocol:: An optional +Array+ of +String+, containing + ## the protocols advertised by the client in + ## the +upgrade+ header (HTTP/1) or the + ## +:protocol+ pseudo-header (HTTP/2). + if protocols = @env['rack.protocol'] + unless protocols.is_a?(Array) && protocols.all?{|protocol| protocol.is_a?(String)} + raise LintError, "rack.protocol must be an Array of Strings" + end + end + + ## Additional environment specifications have approved to + ## standardized middleware APIs. None of these are required to + ## be implemented by the server. + + ## rack.session:: A hash-like interface for storing + ## request session data. + ## The store must implement: + if session = env[RACK_SESSION] + ## store(key, value) (aliased as []=); + unless session.respond_to?(:store) && session.respond_to?(:[]=) + raise LintError, "session #{session.inspect} must respond to store and []=" + end + + ## fetch(key, default = nil) (aliased as []); + unless session.respond_to?(:fetch) && session.respond_to?(:[]) + raise LintError, "session #{session.inspect} must respond to fetch and []" + end + + ## delete(key); + unless session.respond_to?(:delete) + raise LintError, "session #{session.inspect} must respond to delete" + end + + ## clear; + unless session.respond_to?(:clear) + raise LintError, "session #{session.inspect} must respond to clear" + end + + ## to_hash (returning unfrozen Hash instance); + unless session.respond_to?(:to_hash) && session.to_hash.kind_of?(Hash) && !session.to_hash.frozen? + raise LintError, "session #{session.inspect} must respond to to_hash and return unfrozen Hash instance" + end + end + + ## rack.logger:: A common object interface for logging messages. + ## The object must implement: + if logger = env[RACK_LOGGER] + ## info(message, &block) + unless logger.respond_to?(:info) + raise LintError, "logger #{logger.inspect} must respond to info" + end + + ## debug(message, &block) + unless logger.respond_to?(:debug) + raise LintError, "logger #{logger.inspect} must respond to debug" + end + + ## warn(message, &block) + unless logger.respond_to?(:warn) + raise LintError, "logger #{logger.inspect} must respond to warn" + end + + ## error(message, &block) + unless logger.respond_to?(:error) + raise LintError, "logger #{logger.inspect} must respond to error" + end + + ## fatal(message, &block) + unless logger.respond_to?(:fatal) + raise LintError, "logger #{logger.inspect} must respond to fatal" + end + end + + ## rack.multipart.buffer_size:: An Integer hint to the multipart parser as to what chunk size to use for reads and writes. + if bufsize = env[RACK_MULTIPART_BUFFER_SIZE] + unless bufsize.is_a?(Integer) && bufsize > 0 + raise LintError, "rack.multipart.buffer_size must be an Integer > 0 if specified" + end + end + + ## rack.multipart.tempfile_factory:: An object responding to #call with two arguments, the filename and content_type given for the multipart form field, and returning an IO-like object that responds to #<< and optionally #rewind. This factory will be used to instantiate the tempfile for each multipart form file upload field, rather than the default class of Tempfile. + if tempfile_factory = env[RACK_MULTIPART_TEMPFILE_FACTORY] + raise LintError, "rack.multipart.tempfile_factory must respond to #call" unless tempfile_factory.respond_to?(:call) + env[RACK_MULTIPART_TEMPFILE_FACTORY] = lambda do |filename, content_type| + io = tempfile_factory.call(filename, content_type) + raise LintError, "rack.multipart.tempfile_factory return value must respond to #<<" unless io.respond_to?(:<<) + io + end + end + + ## The server or the application can store their own data in the + ## environment, too. The keys must contain at least one dot, + ## and should be prefixed uniquely. The prefix rack. + ## is reserved for use with the Rack core distribution and other + ## accepted specifications and must not be used otherwise. + ## + %w[REQUEST_METHOD SERVER_NAME QUERY_STRING SERVER_PROTOCOL rack.errors].each do |header| + raise LintError, "env missing required key #{header}" unless env.include? header + end + + ## The SERVER_PORT must be an Integer if set. + server_port = env["SERVER_PORT"] + unless server_port.nil? || (Integer(server_port) rescue false) + raise LintError, "env[SERVER_PORT] is not an Integer" + end + + ## The SERVER_NAME must be a valid authority as defined by RFC7540. + unless (URI.parse("http://#{env[SERVER_NAME]}/") rescue false) + raise LintError, "#{env[SERVER_NAME]} must be a valid authority" + end + + ## The HTTP_HOST must be a valid authority as defined by RFC7540. + unless (URI.parse("http://#{env[HTTP_HOST]}/") rescue false) + raise LintError, "#{env[HTTP_HOST]} must be a valid authority" + end + + ## The SERVER_PROTOCOL must match the regexp HTTP/\d(\.\d)?. + server_protocol = env['SERVER_PROTOCOL'] + unless %r{HTTP/\d(\.\d)?}.match?(server_protocol) + raise LintError, "env[SERVER_PROTOCOL] does not match HTTP/\\d(\\.\\d)?" + end + + ## The environment must not contain the keys + ## HTTP_CONTENT_TYPE or HTTP_CONTENT_LENGTH + ## (use the versions without HTTP_). + %w[HTTP_CONTENT_TYPE HTTP_CONTENT_LENGTH].each { |header| + if env.include? header + raise LintError, "env contains #{header}, must use #{header[5..-1]}" + end + } + + ## The CGI keys (named without a period) must have String values. + ## If the string values for CGI keys contain non-ASCII characters, + ## they should use ASCII-8BIT encoding. + env.each { |key, value| + next if key.include? "." # Skip extensions + unless value.kind_of? String + raise LintError, "env variable #{key} has non-string value #{value.inspect}" + end + next if value.encoding == Encoding::ASCII_8BIT + unless value.b !~ /[\x80-\xff]/n + raise LintError, "env variable #{key} has value containing non-ASCII characters and has non-ASCII-8BIT encoding #{value.inspect} encoding: #{value.encoding}" + end + } + + ## There are the following restrictions: + + ## * rack.url_scheme must either be +http+ or +https+. + unless %w[http https].include?(env[RACK_URL_SCHEME]) + raise LintError, "rack.url_scheme unknown: #{env[RACK_URL_SCHEME].inspect}" + end + + ## * There may be a valid input stream in rack.input. + if rack_input = env[RACK_INPUT] + check_input_stream(rack_input) + @env[RACK_INPUT] = InputWrapper.new(rack_input) + end + + ## * There must be a valid error stream in rack.errors. + rack_errors = env[RACK_ERRORS] + check_error_stream(rack_errors) + @env[RACK_ERRORS] = ErrorWrapper.new(rack_errors) + + ## * There may be a valid hijack callback in rack.hijack + check_hijack env + ## * There may be a valid early hints callback in rack.early_hints + check_early_hints env + + ## * The REQUEST_METHOD must be a valid token. + unless env[REQUEST_METHOD] =~ /\A[0-9A-Za-z!\#$%&'*+.^_`|~-]+\z/ + raise LintError, "REQUEST_METHOD unknown: #{env[REQUEST_METHOD].dump}" + end + + ## * The SCRIPT_NAME, if non-empty, must start with / + if env.include?(SCRIPT_NAME) && env[SCRIPT_NAME] != "" && env[SCRIPT_NAME] !~ /\A\// + raise LintError, "SCRIPT_NAME must start with /" + end + + ## * The PATH_INFO, if provided, must be a valid request target or an empty string. + if env.include?(PATH_INFO) + case env[PATH_INFO] + when REQUEST_PATH_ASTERISK_FORM + ## * Only OPTIONS requests may have PATH_INFO set to * (asterisk-form). + unless env[REQUEST_METHOD] == OPTIONS + raise LintError, "Only OPTIONS requests may have PATH_INFO set to '*' (asterisk-form)" + end + when REQUEST_PATH_AUTHORITY_FORM + ## * Only CONNECT requests may have PATH_INFO set to an authority (authority-form). Note that in HTTP/2+, the authority-form is not a valid request target. + unless env[REQUEST_METHOD] == CONNECT + raise LintError, "Only CONNECT requests may have PATH_INFO set to an authority (authority-form)" + end + when REQUEST_PATH_ABSOLUTE_FORM + ## * CONNECT and OPTIONS requests must not have PATH_INFO set to a URI (absolute-form). + if env[REQUEST_METHOD] == CONNECT || env[REQUEST_METHOD] == OPTIONS + raise LintError, "CONNECT and OPTIONS requests must not have PATH_INFO set to a URI (absolute-form)" + end + when REQUEST_PATH_ORIGIN_FORM + ## * Otherwise, PATH_INFO must start with a / and must not include a fragment part starting with '#' (origin-form). + when "" + # Empty string is okay. + else + raise LintError, "PATH_INFO must start with a '/' and must not include a fragment part starting with '#' (origin-form)" + end + end + + ## * The CONTENT_LENGTH, if given, must consist of digits only. + if env.include?("CONTENT_LENGTH") && env["CONTENT_LENGTH"] !~ /\A\d+\z/ + raise LintError, "Invalid CONTENT_LENGTH: #{env["CONTENT_LENGTH"]}" + end + + ## * One of SCRIPT_NAME or PATH_INFO must be + ## set. PATH_INFO should be / if + ## SCRIPT_NAME is empty. + unless env[SCRIPT_NAME] || env[PATH_INFO] + raise LintError, "One of SCRIPT_NAME or PATH_INFO must be set (make PATH_INFO '/' if SCRIPT_NAME is empty)" + end + ## SCRIPT_NAME never should be /, but instead be empty. + unless env[SCRIPT_NAME] != "/" + raise LintError, "SCRIPT_NAME cannot be '/', make it '' and PATH_INFO '/'" + end + + ## rack.response_finished:: An array of callables run by the server after the response has been + ## processed. This would typically be invoked after sending the response to the client, but it could also be + ## invoked if an error occurs while generating the response or sending the response; in that case, the error + ## argument will be a subclass of +Exception+. + ## The callables are invoked with +env, status, headers, error+ arguments and should not raise any + ## exceptions. They should be invoked in reverse order of registration. + if callables = env[RACK_RESPONSE_FINISHED] + raise LintError, "rack.response_finished must be an array of callable objects" unless callables.is_a?(Array) + + callables.each do |callable| + raise LintError, "rack.response_finished values must respond to call(env, status, headers, error)" unless callable.respond_to?(:call) + end + end + end + + ## + ## === The Input Stream + ## + ## The input stream is an IO-like object which contains the raw HTTP + ## POST data. + def check_input_stream(input) + ## When applicable, its external encoding must be "ASCII-8BIT" and it + ## must be opened in binary mode. + if input.respond_to?(:external_encoding) && input.external_encoding != Encoding::ASCII_8BIT + raise LintError, "rack.input #{input} does not have ASCII-8BIT as its external encoding" + end + if input.respond_to?(:binmode?) && !input.binmode? + raise LintError, "rack.input #{input} is not opened in binary mode" + end + + ## The input stream must respond to +gets+, +each+, and +read+. + [:gets, :each, :read].each { |method| + unless input.respond_to? method + raise LintError, "rack.input #{input} does not respond to ##{method}" + end + } + end + + class InputWrapper + def initialize(input) + @input = input + end + + ## * +gets+ must be called without arguments and return a string, + ## or +nil+ on EOF. + def gets(*args) + raise LintError, "rack.input#gets called with arguments" unless args.size == 0 + v = @input.gets + unless v.nil? or v.kind_of? String + raise LintError, "rack.input#gets didn't return a String" + end + v + end + + ## * +read+ behaves like IO#read. + ## Its signature is read([length, [buffer]]). + ## + ## If given, +length+ must be a non-negative Integer (>= 0) or +nil+, + ## and +buffer+ must be a String and may not be nil. + ## + ## If +length+ is given and not nil, then this method reads at most + ## +length+ bytes from the input stream. + ## + ## If +length+ is not given or nil, then this method reads + ## all data until EOF. + ## + ## When EOF is reached, this method returns nil if +length+ is given + ## and not nil, or "" if +length+ is not given or is nil. + ## + ## If +buffer+ is given, then the read data will be placed + ## into +buffer+ instead of a newly created String object. + def read(*args) + unless args.size <= 2 + raise LintError, "rack.input#read called with too many arguments" + end + if args.size >= 1 + unless args.first.kind_of?(Integer) || args.first.nil? + raise LintError, "rack.input#read called with non-integer and non-nil length" + end + unless args.first.nil? || args.first >= 0 + raise LintError, "rack.input#read called with a negative length" + end + end + if args.size >= 2 + unless args[1].kind_of?(String) + raise LintError, "rack.input#read called with non-String buffer" + end + end + + v = @input.read(*args) + + unless v.nil? or v.kind_of? String + raise LintError, "rack.input#read didn't return nil or a String" + end + if args[0].nil? + unless !v.nil? + raise LintError, "rack.input#read(nil) returned nil on EOF" + end + end + + v + end + + ## * +each+ must be called without arguments and only yield Strings. + def each(*args) + raise LintError, "rack.input#each called with arguments" unless args.size == 0 + @input.each { |line| + unless line.kind_of? String + raise LintError, "rack.input#each didn't yield a String" + end + yield line + } + end + + ## * +close+ can be called on the input stream to indicate that + ## any remaining input is not needed. + def close(*args) + @input.close(*args) + end + end + + ## + ## === The Error Stream + ## + def check_error_stream(error) + ## The error stream must respond to +puts+, +write+ and +flush+. + [:puts, :write, :flush].each { |method| + unless error.respond_to? method + raise LintError, "rack.error #{error} does not respond to ##{method}" + end + } + end + + class ErrorWrapper + def initialize(error) + @error = error + end + + ## * +puts+ must be called with a single argument that responds to +to_s+. + def puts(str) + @error.puts str + end + + ## * +write+ must be called with a single argument that is a String. + def write(str) + raise LintError, "rack.errors#write not called with a String" unless str.kind_of? String + @error.write str + end + + ## * +flush+ must be called without arguments and must be called + ## in order to make the error appear for sure. + def flush + @error.flush + end + + ## * +close+ must never be called on the error stream. + def close(*args) + raise LintError, "rack.errors#close must not be called" + end + end + + ## + ## === Hijacking + ## + ## The hijacking interfaces provides a means for an application to take + ## control of the HTTP connection. There are two distinct hijack + ## interfaces: full hijacking where the application takes over the raw + ## connection, and partial hijacking where the application takes over + ## just the response body stream. In both cases, the application is + ## responsible for closing the hijacked stream. + ## + ## Full hijacking only works with HTTP/1. Partial hijacking is functionally + ## equivalent to streaming bodies, and is still optionally supported for + ## backwards compatibility with older Rack versions. + ## + ## ==== Full Hijack + ## + ## Full hijack is used to completely take over an HTTP/1 connection. It + ## occurs before any headers are written and causes the request to + ## ignores any response generated by the application. + ## + ## It is intended to be used when applications need access to raw HTTP/1 + ## connection. + ## + def check_hijack(env) + ## If +rack.hijack+ is present in +env+, it must respond to +call+ + if original_hijack = env[RACK_HIJACK] + raise LintError, "rack.hijack must respond to call" unless original_hijack.respond_to?(:call) + + env[RACK_HIJACK] = proc do + io = original_hijack.call + + ## and return an +IO+ instance which can be used to read and write + ## to the underlying connection using HTTP/1 semantics and + ## formatting. + raise LintError, "rack.hijack must return an IO instance" unless io.is_a?(IO) + + io + end + end + end + + ## + ## ==== Partial Hijack + ## + ## Partial hijack is used for bi-directional streaming of the request and + ## response body. It occurs after the status and headers are written by + ## the server and causes the server to ignore the Body of the response. + ## + ## It is intended to be used when applications need bi-directional + ## streaming. + ## + def check_hijack_response(headers, env) + ## If +rack.hijack?+ is present in +env+ and truthy, + if env[RACK_IS_HIJACK] + ## an application may set the special response header +rack.hijack+ + if original_hijack = headers[RACK_HIJACK] + ## to an object that responds to +call+, + unless original_hijack.respond_to?(:call) + raise LintError, 'rack.hijack header must respond to #call' + end + ## accepting a +stream+ argument. + return proc do |io| + original_hijack.call StreamWrapper.new(io) + end + end + ## + ## After the response status and headers have been sent, this hijack + ## callback will be invoked with a +stream+ argument which follows the + ## same interface as outlined in "Streaming Body". Servers must + ## ignore the +body+ part of the response tuple when the + ## +rack.hijack+ response header is present. Using an empty +Array+ + ## instance is recommended. + else + ## + ## The special response header +rack.hijack+ must only be set + ## if the request +env+ has a truthy +rack.hijack?+. + if headers.key?(RACK_HIJACK) + raise LintError, 'rack.hijack header must not be present if server does not support hijacking' + end + end + + nil + end + + ## + ## === Early Hints + ## + ## The application or any middleware may call the rack.early_hints + ## with an object which would be valid as the headers of a Rack response. + def check_early_hints(env) + if env[RACK_EARLY_HINTS] + ## + ## If rack.early_hints is present, it must respond to #call. + unless env[RACK_EARLY_HINTS].respond_to?(:call) + raise LintError, "rack.early_hints must respond to call" + end + + original_callback = env[RACK_EARLY_HINTS] + env[RACK_EARLY_HINTS] = lambda do |headers| + ## If rack.early_hints is called, it must be called with + ## valid Rack response headers. + check_headers(headers) + original_callback.call(headers) + end + end + end + + ## + ## == The Response + ## + ## === The Status + ## + def check_status(status) + ## This is an HTTP status. It must be an Integer greater than or equal to + ## 100. + unless status.is_a?(Integer) && status >= 100 + raise LintError, "Status must be an Integer >=100" + end + end + + ## + ## === The Headers + ## + def check_headers(headers) + ## The headers must be a unfrozen Hash. + unless headers.kind_of?(Hash) + raise LintError, "headers object should be a hash, but isn't (got #{headers.class} as headers)" + end + + if headers.frozen? + raise LintError, "headers object should not be frozen, but is" + end + + headers.each do |key, value| + ## The header keys must be Strings. + unless key.kind_of? String + raise LintError, "header key must be a string, was #{key.class}" + end + + ## Special headers starting "rack." are for communicating with the + ## server, and must not be sent back to the client. + next if key.start_with?("rack.") + + ## The header must not contain a +Status+ key. + raise LintError, "header must not contain status" if key == "status" + ## Header keys must conform to RFC7230 token specification, i.e. cannot + ## contain non-printable ASCII, DQUOTE or "(),/:;<=>?@[\]{}". + raise LintError, "invalid header name: #{key}" if key =~ /[\(\),\/:;<=>\?@\[\\\]{}[:cntrl:]]/ + ## Header keys must not contain uppercase ASCII characters (A-Z). + raise LintError, "uppercase character in header name: #{key}" if key =~ /[A-Z]/ + + ## Header values must be either a String instance, + if value.kind_of?(String) + check_header_value(key, value) + elsif value.kind_of?(Array) + ## or an Array of String instances, + value.each{|value| check_header_value(key, value)} + else + raise LintError, "a header value must be a String or Array of Strings, but the value of '#{key}' is a #{value.class}" + end + end + end + + def check_header_value(key, value) + ## such that each String instance must not contain characters below 037. + if value =~ /[\000-\037]/ + raise LintError, "invalid header value #{key}: #{value.inspect}" + end + end + + ## + ## ==== The +content-type+ Header + ## + def check_content_type_header(status, headers) + headers.each { |key, value| + ## There must not be a content-type header key when the +Status+ is 1xx, + ## 204, or 304. + if key == "content-type" + if Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.key? status.to_i + raise LintError, "content-type header found in #{status} response, not allowed" + end + return + end + } + end + + ## + ## ==== The +content-length+ Header + ## + def check_content_length_header(status, headers) + headers.each { |key, value| + if key == 'content-length' + ## There must not be a content-length header key when the + ## +Status+ is 1xx, 204, or 304. + if Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.key? status.to_i + raise LintError, "content-length header found in #{status} response, not allowed" + end + @content_length = value + end + } + end + + def verify_content_length(size) + if @head_request + unless size == 0 + raise LintError, "Response body was given for HEAD request, but should be empty" + end + elsif @content_length + unless @content_length == size.to_s + raise LintError, "content-length header was #{@content_length}, but should be #{size}" + end + end + end + + ## + ## ==== The +rack.protocol+ Header + ## + def check_rack_protocol_header(status, headers) + ## If the +rack.protocol+ header is present, it must be a +String+, and + ## must be one of the values from the +rack.protocol+ array from the + ## environment. + protocol = headers['rack.protocol'] + + if protocol + request_protocols = @env['rack.protocol'] + + if request_protocols.nil? + raise LintError, "rack.protocol header is #{protocol.inspect}, but rack.protocol was not set in request!" + elsif !request_protocols.include?(protocol) + raise LintError, "rack.protocol header is #{protocol.inspect}, but should be one of #{request_protocols.inspect} from the request!" + end + end + end + ## + ## Setting this value informs the server that it should perform a + ## connection upgrade. In HTTP/1, this is done using the +upgrade+ + ## header. In HTTP/2, this is done by accepting the request. + ## + ## === The Body + ## + ## The Body is typically an +Array+ of +String+ instances, an enumerable + ## that yields +String+ instances, a +Proc+ instance, or a File-like + ## object. + ## + ## The Body must respond to +each+ or +call+. It may optionally respond + ## to +to_path+ or +to_ary+. A Body that responds to +each+ is considered + ## to be an Enumerable Body. A Body that responds to +call+ is considered + ## to be a Streaming Body. + ## + ## A Body that responds to both +each+ and +call+ must be treated as an + ## Enumerable Body, not a Streaming Body. If it responds to +each+, you + ## must call +each+ and not +call+. If the Body doesn't respond to + ## +each+, then you can assume it responds to +call+. + ## + ## The Body must either be consumed or returned. The Body is consumed by + ## optionally calling either +each+ or +call+. + ## Then, if the Body responds to +close+, it must be called to release + ## any resources associated with the generation of the body. + ## In other words, +close+ must always be called at least once; typically + ## after the web server has sent the response to the client, but also in + ## cases where the Rack application makes internal/virtual requests and + ## discards the response. + ## + def close + ## + ## After calling +close+, the Body is considered closed and should not + ## be consumed again. + @closed = true + + ## If the original Body is replaced by a new Body, the new Body must + ## also consume the original Body by calling +close+ if possible. + @body.close if @body.respond_to?(:close) + + index = @lint.index(self) + unless @env['rack.lint'][0..index].all? {|lint| lint.instance_variable_get(:@closed)} + raise LintError, "Body has not been closed" + end + end + + def verify_to_path + ## + ## If the Body responds to +to_path+, it must return a +String+ + ## path for the local file system whose contents are identical + ## to that produced by calling +each+; this may be used by the + ## server as an alternative, possibly more efficient way to + ## transport the response. The +to_path+ method does not consume + ## the body. + if @body.respond_to?(:to_path) + unless ::File.exist? @body.to_path + raise LintError, "The file identified by body.to_path does not exist" + end + end + end + + ## + ## ==== Enumerable Body + ## + def each + ## The Enumerable Body must respond to +each+. + raise LintError, "Enumerable Body must respond to each" unless @body.respond_to?(:each) + + ## It must only be called once. + raise LintError, "Response body must only be invoked once (#{@invoked})" unless @invoked.nil? + + ## It must not be called after being closed, + raise LintError, "Response body is already closed" if @closed + + @invoked = :each + + @body.each do |chunk| + ## and must only yield String values. + unless chunk.kind_of? String + raise LintError, "Body yielded non-string value #{chunk.inspect}" + end + + ## + ## Middleware must not call +each+ directly on the Body. + ## Instead, middleware can return a new Body that calls +each+ on the + ## original Body, yielding at least once per iteration. + if @lint[0] == self + @env['rack.lint.body_iteration'] += 1 + else + if (@env['rack.lint.body_iteration'] -= 1) > 0 + raise LintError, "New body must yield at least once per iteration of old body" + end + end + + @size += chunk.bytesize + yield chunk + end + + verify_content_length(@size) + + verify_to_path + end + + BODY_METHODS = {to_ary: true, each: true, call: true, to_path: true} + + def to_path + @body.to_path + end + + def respond_to?(name, *) + if BODY_METHODS.key?(name) + @body.respond_to?(name) + else + super + end + end + + ## + ## If the Body responds to +to_ary+, it must return an +Array+ whose + ## contents are identical to that produced by calling +each+. + ## Middleware may call +to_ary+ directly on the Body and return a new + ## Body in its place. In other words, middleware can only process the + ## Body directly if it responds to +to_ary+. If the Body responds to both + ## +to_ary+ and +close+, its implementation of +to_ary+ must call + ## +close+. + def to_ary + @body.to_ary.tap do |content| + unless content == @body.enum_for.to_a + raise LintError, "#to_ary not identical to contents produced by calling #each" + end + end + ensure + close + end + + ## + ## ==== Streaming Body + ## + def call(stream) + ## The Streaming Body must respond to +call+. + raise LintError, "Streaming Body must respond to call" unless @body.respond_to?(:call) + + ## It must only be called once. + raise LintError, "Response body must only be invoked once (#{@invoked})" unless @invoked.nil? + + ## It must not be called after being closed. + raise LintError, "Response body is already closed" if @closed + + @invoked = :call + + ## It takes a +stream+ argument. + ## + ## The +stream+ argument must implement: + ## read, write, <<, flush, close, close_read, close_write, closed? + ## + @body.call(StreamWrapper.new(stream)) + end + + class StreamWrapper + extend Forwardable + + ## The semantics of these IO methods must be a best effort match to + ## those of a normal Ruby IO or Socket object, using standard arguments + ## and raising standard exceptions. Servers are encouraged to simply + ## pass on real IO objects, although it is recognized that this approach + ## is not directly compatible with HTTP/2. + REQUIRED_METHODS = [ + :read, :write, :<<, :flush, :close, + :close_read, :close_write, :closed? + ] + + def_delegators :@stream, *REQUIRED_METHODS + + def initialize(stream) + @stream = stream + + REQUIRED_METHODS.each do |method_name| + raise LintError, "Stream must respond to #{method_name}" unless stream.respond_to?(method_name) + end + end + end + + # :startdoc: + end + end +end + +## +## == Thanks +## Some parts of this specification are adopted from {PEP 333 – Python Web Server Gateway Interface v1.0}[https://peps.python.org/pep-0333/] +## I'd like to thank everyone involved in that effort. diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/lock.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/lock.rb new file mode 100644 index 00000000..342123a0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/lock.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require_relative 'body_proxy' + +module Rack + # Rack::Lock locks every request inside a mutex, so that every request + # will effectively be executed synchronously. + class Lock + def initialize(app, mutex = Mutex.new) + @app, @mutex = app, mutex + end + + def call(env) + @mutex.lock + begin + response = @app.call(env) + returned = response << BodyProxy.new(response.pop) { unlock } + ensure + unlock unless returned + end + end + + private + + def unlock + @mutex.unlock + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/logger.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/logger.rb new file mode 100644 index 00000000..081212d6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/logger.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'logger' +require_relative 'constants' + +warn "Rack::Logger is deprecated and will be removed in Rack 3.2.", uplevel: 1 + +module Rack + # Sets up rack.logger to write to rack.errors stream + class Logger + def initialize(app, level = ::Logger::INFO) + @app, @level = app, level + end + + def call(env) + logger = ::Logger.new(env[RACK_ERRORS]) + logger.level = @level + + env[RACK_LOGGER] = logger + @app.call(env) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/media_type.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/media_type.rb new file mode 100644 index 00000000..f4902b20 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/media_type.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +module Rack + # Rack::MediaType parse media type and parameters out of content_type string + + class MediaType + SPLIT_PATTERN = /[;,]/ + + class << self + # The media type (type/subtype) portion of the CONTENT_TYPE header + # without any media type parameters. e.g., when CONTENT_TYPE is + # "text/plain;charset=utf-8", the media-type is "text/plain". + # + # For more information on the use of media types in HTTP, see: + # http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7 + def type(content_type) + return nil unless content_type + if type = content_type.split(SPLIT_PATTERN, 2).first + type.rstrip! + type.downcase! + type + end + end + + # The media type parameters provided in CONTENT_TYPE as a Hash, or + # an empty Hash if no CONTENT_TYPE or media-type parameters were + # provided. e.g., when the CONTENT_TYPE is "text/plain;charset=utf-8", + # this method responds with the following Hash: + # { 'charset' => 'utf-8' } + # + # This will pass back parameters with empty strings in the hash if they + # lack a value (e.g., "text/plain;charset=" will return { 'charset' => '' }, + # and "text/plain;charset" will return { 'charset' => '' }, similarly to + # the query params parser (barring the latter case, which returns nil instead)). + def params(content_type) + return {} if content_type.nil? + + content_type.split(SPLIT_PATTERN)[1..-1].each_with_object({}) do |s, hsh| + s.strip! + k, v = s.split('=', 2) + k.downcase! + hsh[k] = strip_doublequotes(v) + end + end + + private + + def strip_doublequotes(str) + (str && str.start_with?('"') && str.end_with?('"')) ? str[1..-2] : str || '' + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/method_override.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/method_override.rb new file mode 100644 index 00000000..6125b191 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/method_override.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require_relative 'constants' +require_relative 'request' +require_relative 'utils' + +module Rack + class MethodOverride + HTTP_METHODS = %w[GET HEAD PUT POST DELETE OPTIONS PATCH LINK UNLINK] + + METHOD_OVERRIDE_PARAM_KEY = "_method" + HTTP_METHOD_OVERRIDE_HEADER = "HTTP_X_HTTP_METHOD_OVERRIDE" + ALLOWED_METHODS = %w[POST] + + def initialize(app) + @app = app + end + + def call(env) + if allowed_methods.include?(env[REQUEST_METHOD]) + method = method_override(env) + if HTTP_METHODS.include?(method) + env[RACK_METHODOVERRIDE_ORIGINAL_METHOD] = env[REQUEST_METHOD] + env[REQUEST_METHOD] = method + end + end + + @app.call(env) + end + + def method_override(env) + req = Request.new(env) + method = method_override_param(req) || + env[HTTP_METHOD_OVERRIDE_HEADER] + begin + method.to_s.upcase + rescue ArgumentError + env[RACK_ERRORS].puts "Invalid string for method" + end + end + + private + + def allowed_methods + ALLOWED_METHODS + end + + def method_override_param(req) + req.POST[METHOD_OVERRIDE_PARAM_KEY] if req.form_data? || req.parseable_data? + rescue Utils::InvalidParameterError, Utils::ParameterTypeError, QueryParser::ParamsTooDeepError + req.get_header(RACK_ERRORS).puts "Invalid or incomplete POST params" + rescue EOFError + req.get_header(RACK_ERRORS).puts "Bad request content body" + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/mime.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/mime.rb new file mode 100644 index 00000000..0272968f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/mime.rb @@ -0,0 +1,694 @@ +# frozen_string_literal: true + +module Rack + module Mime + # Returns String with mime type if found, otherwise use +fallback+. + # +ext+ should be filename extension in the '.ext' format that + # File.extname(file) returns. + # +fallback+ may be any object + # + # Also see the documentation for MIME_TYPES + # + # Usage: + # Rack::Mime.mime_type('.foo') + # + # This is a shortcut for: + # Rack::Mime::MIME_TYPES.fetch('.foo', 'application/octet-stream') + + def mime_type(ext, fallback = 'application/octet-stream') + MIME_TYPES.fetch(ext.to_s.downcase, fallback) + end + module_function :mime_type + + # Returns true if the given value is a mime match for the given mime match + # specification, false otherwise. + # + # Rack::Mime.match?('text/html', 'text/*') => true + # Rack::Mime.match?('text/plain', '*') => true + # Rack::Mime.match?('text/html', 'application/json') => false + + def match?(value, matcher) + v1, v2 = value.split('/', 2) + m1, m2 = matcher.split('/', 2) + + (m1 == '*' || v1 == m1) && (m2.nil? || m2 == '*' || m2 == v2) + end + module_function :match? + + # List of most common mime-types, selected various sources + # according to their usefulness in a webserving scope for Ruby + # users. + # + # To amend this list with your local mime.types list you can use: + # + # require 'webrick/httputils' + # list = WEBrick::HTTPUtils.load_mime_types('/etc/mime.types') + # Rack::Mime::MIME_TYPES.merge!(list) + # + # N.B. On Ubuntu the mime.types file does not include the leading period, so + # users may need to modify the data before merging into the hash. + + MIME_TYPES = { + ".123" => "application/vnd.lotus-1-2-3", + ".3dml" => "text/vnd.in3d.3dml", + ".3g2" => "video/3gpp2", + ".3gp" => "video/3gpp", + ".a" => "application/octet-stream", + ".acc" => "application/vnd.americandynamics.acc", + ".ace" => "application/x-ace-compressed", + ".acu" => "application/vnd.acucobol", + ".aep" => "application/vnd.audiograph", + ".afp" => "application/vnd.ibm.modcap", + ".ai" => "application/postscript", + ".aif" => "audio/x-aiff", + ".aiff" => "audio/x-aiff", + ".ami" => "application/vnd.amiga.ami", + ".apng" => "image/apng", + ".appcache" => "text/cache-manifest", + ".apr" => "application/vnd.lotus-approach", + ".asc" => "application/pgp-signature", + ".asf" => "video/x-ms-asf", + ".asm" => "text/x-asm", + ".aso" => "application/vnd.accpac.simply.aso", + ".asx" => "video/x-ms-asf", + ".atc" => "application/vnd.acucorp", + ".atom" => "application/atom+xml", + ".atomcat" => "application/atomcat+xml", + ".atomsvc" => "application/atomsvc+xml", + ".atx" => "application/vnd.antix.game-component", + ".au" => "audio/basic", + ".avi" => "video/x-msvideo", + ".avif" => "image/avif", + ".bat" => "application/x-msdownload", + ".bcpio" => "application/x-bcpio", + ".bdm" => "application/vnd.syncml.dm+wbxml", + ".bh2" => "application/vnd.fujitsu.oasysprs", + ".bin" => "application/octet-stream", + ".bmi" => "application/vnd.bmi", + ".bmp" => "image/bmp", + ".box" => "application/vnd.previewsystems.box", + ".btif" => "image/prs.btif", + ".bz" => "application/x-bzip", + ".bz2" => "application/x-bzip2", + ".c" => "text/x-c", + ".c4g" => "application/vnd.clonk.c4group", + ".cab" => "application/vnd.ms-cab-compressed", + ".cc" => "text/x-c", + ".ccxml" => "application/ccxml+xml", + ".cdbcmsg" => "application/vnd.contact.cmsg", + ".cdkey" => "application/vnd.mediastation.cdkey", + ".cdx" => "chemical/x-cdx", + ".cdxml" => "application/vnd.chemdraw+xml", + ".cdy" => "application/vnd.cinderella", + ".cer" => "application/pkix-cert", + ".cgm" => "image/cgm", + ".chat" => "application/x-chat", + ".chm" => "application/vnd.ms-htmlhelp", + ".chrt" => "application/vnd.kde.kchart", + ".cif" => "chemical/x-cif", + ".cii" => "application/vnd.anser-web-certificate-issue-initiation", + ".cil" => "application/vnd.ms-artgalry", + ".cla" => "application/vnd.claymore", + ".class" => "application/octet-stream", + ".clkk" => "application/vnd.crick.clicker.keyboard", + ".clkp" => "application/vnd.crick.clicker.palette", + ".clkt" => "application/vnd.crick.clicker.template", + ".clkw" => "application/vnd.crick.clicker.wordbank", + ".clkx" => "application/vnd.crick.clicker", + ".clp" => "application/x-msclip", + ".cmc" => "application/vnd.cosmocaller", + ".cmdf" => "chemical/x-cmdf", + ".cml" => "chemical/x-cml", + ".cmp" => "application/vnd.yellowriver-custom-menu", + ".cmx" => "image/x-cmx", + ".com" => "application/x-msdownload", + ".conf" => "text/plain", + ".cpio" => "application/x-cpio", + ".cpp" => "text/x-c", + ".cpt" => "application/mac-compactpro", + ".crd" => "application/x-mscardfile", + ".crl" => "application/pkix-crl", + ".crt" => "application/x-x509-ca-cert", + ".csh" => "application/x-csh", + ".csml" => "chemical/x-csml", + ".csp" => "application/vnd.commonspace", + ".css" => "text/css", + ".csv" => "text/csv", + ".curl" => "application/vnd.curl", + ".cww" => "application/prs.cww", + ".cxx" => "text/x-c", + ".daf" => "application/vnd.mobius.daf", + ".davmount" => "application/davmount+xml", + ".dcr" => "application/x-director", + ".dd2" => "application/vnd.oma.dd2+xml", + ".ddd" => "application/vnd.fujixerox.ddd", + ".deb" => "application/x-debian-package", + ".der" => "application/x-x509-ca-cert", + ".dfac" => "application/vnd.dreamfactory", + ".diff" => "text/x-diff", + ".dis" => "application/vnd.mobius.dis", + ".djv" => "image/vnd.djvu", + ".djvu" => "image/vnd.djvu", + ".dll" => "application/x-msdownload", + ".dmg" => "application/octet-stream", + ".dna" => "application/vnd.dna", + ".doc" => "application/msword", + ".docm" => "application/vnd.ms-word.document.macroEnabled.12", + ".docx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + ".dot" => "application/msword", + ".dotm" => "application/vnd.ms-word.template.macroEnabled.12", + ".dotx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.template", + ".dp" => "application/vnd.osgi.dp", + ".dpg" => "application/vnd.dpgraph", + ".dsc" => "text/prs.lines.tag", + ".dtd" => "application/xml-dtd", + ".dts" => "audio/vnd.dts", + ".dtshd" => "audio/vnd.dts.hd", + ".dv" => "video/x-dv", + ".dvi" => "application/x-dvi", + ".dwf" => "model/vnd.dwf", + ".dwg" => "image/vnd.dwg", + ".dxf" => "image/vnd.dxf", + ".dxp" => "application/vnd.spotfire.dxp", + ".ear" => "application/java-archive", + ".ecelp4800" => "audio/vnd.nuera.ecelp4800", + ".ecelp7470" => "audio/vnd.nuera.ecelp7470", + ".ecelp9600" => "audio/vnd.nuera.ecelp9600", + ".ecma" => "application/ecmascript", + ".edm" => "application/vnd.novadigm.edm", + ".edx" => "application/vnd.novadigm.edx", + ".efif" => "application/vnd.picsel", + ".ei6" => "application/vnd.pg.osasli", + ".eml" => "message/rfc822", + ".eol" => "audio/vnd.digital-winds", + ".eot" => "application/vnd.ms-fontobject", + ".eps" => "application/postscript", + ".es3" => "application/vnd.eszigno3+xml", + ".esf" => "application/vnd.epson.esf", + ".etx" => "text/x-setext", + ".exe" => "application/x-msdownload", + ".ext" => "application/vnd.novadigm.ext", + ".ez" => "application/andrew-inset", + ".ez2" => "application/vnd.ezpix-album", + ".ez3" => "application/vnd.ezpix-package", + ".f" => "text/x-fortran", + ".f77" => "text/x-fortran", + ".f90" => "text/x-fortran", + ".fbs" => "image/vnd.fastbidsheet", + ".fdf" => "application/vnd.fdf", + ".fe_launch" => "application/vnd.denovo.fcselayout-link", + ".fg5" => "application/vnd.fujitsu.oasysgp", + ".fli" => "video/x-fli", + ".flif" => "image/flif", + ".flo" => "application/vnd.micrografx.flo", + ".flv" => "video/x-flv", + ".flw" => "application/vnd.kde.kivio", + ".flx" => "text/vnd.fmi.flexstor", + ".fly" => "text/vnd.fly", + ".fm" => "application/vnd.framemaker", + ".fnc" => "application/vnd.frogans.fnc", + ".for" => "text/x-fortran", + ".fpx" => "image/vnd.fpx", + ".fsc" => "application/vnd.fsc.weblaunch", + ".fst" => "image/vnd.fst", + ".ftc" => "application/vnd.fluxtime.clip", + ".fti" => "application/vnd.anser-web-funds-transfer-initiation", + ".fvt" => "video/vnd.fvt", + ".fzs" => "application/vnd.fuzzysheet", + ".g3" => "image/g3fax", + ".gac" => "application/vnd.groove-account", + ".gdl" => "model/vnd.gdl", + ".gem" => "application/octet-stream", + ".gemspec" => "text/x-script.ruby", + ".ghf" => "application/vnd.groove-help", + ".gif" => "image/gif", + ".gim" => "application/vnd.groove-identity-message", + ".gmx" => "application/vnd.gmx", + ".gph" => "application/vnd.flographit", + ".gqf" => "application/vnd.grafeq", + ".gram" => "application/srgs", + ".grv" => "application/vnd.groove-injector", + ".grxml" => "application/srgs+xml", + ".gtar" => "application/x-gtar", + ".gtm" => "application/vnd.groove-tool-message", + ".gtw" => "model/vnd.gtw", + ".gv" => "text/vnd.graphviz", + ".gz" => "application/x-gzip", + ".h" => "text/x-c", + ".h261" => "video/h261", + ".h263" => "video/h263", + ".h264" => "video/h264", + ".hbci" => "application/vnd.hbci", + ".hdf" => "application/x-hdf", + ".heic" => "image/heic", + ".heics" => "image/heic-sequence", + ".heif" => "image/heif", + ".heifs" => "image/heif-sequence", + ".hh" => "text/x-c", + ".hlp" => "application/winhlp", + ".hpgl" => "application/vnd.hp-hpgl", + ".hpid" => "application/vnd.hp-hpid", + ".hps" => "application/vnd.hp-hps", + ".hqx" => "application/mac-binhex40", + ".htc" => "text/x-component", + ".htke" => "application/vnd.kenameaapp", + ".htm" => "text/html", + ".html" => "text/html", + ".hvd" => "application/vnd.yamaha.hv-dic", + ".hvp" => "application/vnd.yamaha.hv-voice", + ".hvs" => "application/vnd.yamaha.hv-script", + ".icc" => "application/vnd.iccprofile", + ".ice" => "x-conference/x-cooltalk", + ".ico" => "image/vnd.microsoft.icon", + ".ics" => "text/calendar", + ".ief" => "image/ief", + ".ifb" => "text/calendar", + ".ifm" => "application/vnd.shana.informed.formdata", + ".igl" => "application/vnd.igloader", + ".igs" => "model/iges", + ".igx" => "application/vnd.micrografx.igx", + ".iif" => "application/vnd.shana.informed.interchange", + ".imp" => "application/vnd.accpac.simply.imp", + ".ims" => "application/vnd.ms-ims", + ".ipk" => "application/vnd.shana.informed.package", + ".irm" => "application/vnd.ibm.rights-management", + ".irp" => "application/vnd.irepository.package+xml", + ".iso" => "application/octet-stream", + ".itp" => "application/vnd.shana.informed.formtemplate", + ".ivp" => "application/vnd.immervision-ivp", + ".ivu" => "application/vnd.immervision-ivu", + ".jad" => "text/vnd.sun.j2me.app-descriptor", + ".jam" => "application/vnd.jam", + ".jar" => "application/java-archive", + ".java" => "text/x-java-source", + ".jisp" => "application/vnd.jisp", + ".jlt" => "application/vnd.hp-jlyt", + ".jnlp" => "application/x-java-jnlp-file", + ".joda" => "application/vnd.joost.joda-archive", + ".jp2" => "image/jp2", + ".jpeg" => "image/jpeg", + ".jpg" => "image/jpeg", + ".jpgv" => "video/jpeg", + ".jpm" => "video/jpm", + ".js" => "text/javascript", + ".json" => "application/json", + ".karbon" => "application/vnd.kde.karbon", + ".kfo" => "application/vnd.kde.kformula", + ".kia" => "application/vnd.kidspiration", + ".kml" => "application/vnd.google-earth.kml+xml", + ".kmz" => "application/vnd.google-earth.kmz", + ".kne" => "application/vnd.kinar", + ".kon" => "application/vnd.kde.kontour", + ".kpr" => "application/vnd.kde.kpresenter", + ".ksp" => "application/vnd.kde.kspread", + ".ktz" => "application/vnd.kahootz", + ".kwd" => "application/vnd.kde.kword", + ".latex" => "application/x-latex", + ".lbd" => "application/vnd.llamagraphics.life-balance.desktop", + ".lbe" => "application/vnd.llamagraphics.life-balance.exchange+xml", + ".les" => "application/vnd.hhe.lesson-player", + ".link66" => "application/vnd.route66.link66+xml", + ".log" => "text/plain", + ".lostxml" => "application/lost+xml", + ".lrm" => "application/vnd.ms-lrm", + ".ltf" => "application/vnd.frogans.ltf", + ".lvp" => "audio/vnd.lucent.voice", + ".lwp" => "application/vnd.lotus-wordpro", + ".m3u" => "audio/x-mpegurl", + ".m3u8" => "application/x-mpegurl", + ".m4a" => "audio/mp4a-latm", + ".m4v" => "video/mp4", + ".ma" => "application/mathematica", + ".mag" => "application/vnd.ecowin.chart", + ".man" => "text/troff", + ".manifest" => "text/cache-manifest", + ".mathml" => "application/mathml+xml", + ".mbk" => "application/vnd.mobius.mbk", + ".mbox" => "application/mbox", + ".mc1" => "application/vnd.medcalcdata", + ".mcd" => "application/vnd.mcd", + ".mdb" => "application/x-msaccess", + ".mdi" => "image/vnd.ms-modi", + ".mdoc" => "text/troff", + ".me" => "text/troff", + ".mfm" => "application/vnd.mfmp", + ".mgz" => "application/vnd.proteus.magazine", + ".mid" => "audio/midi", + ".midi" => "audio/midi", + ".mif" => "application/vnd.mif", + ".mime" => "message/rfc822", + ".mj2" => "video/mj2", + ".mjs" => "text/javascript", + ".mlp" => "application/vnd.dolby.mlp", + ".mmd" => "application/vnd.chipnuts.karaoke-mmd", + ".mmf" => "application/vnd.smaf", + ".mml" => "application/mathml+xml", + ".mmr" => "image/vnd.fujixerox.edmics-mmr", + ".mng" => "video/x-mng", + ".mny" => "application/x-msmoney", + ".mov" => "video/quicktime", + ".movie" => "video/x-sgi-movie", + ".mp3" => "audio/mpeg", + ".mp4" => "video/mp4", + ".mp4a" => "audio/mp4", + ".mp4s" => "application/mp4", + ".mp4v" => "video/mp4", + ".mpc" => "application/vnd.mophun.certificate", + ".mpd" => "application/dash+xml", + ".mpeg" => "video/mpeg", + ".mpg" => "video/mpeg", + ".mpga" => "audio/mpeg", + ".mpkg" => "application/vnd.apple.installer+xml", + ".mpm" => "application/vnd.blueice.multipass", + ".mpn" => "application/vnd.mophun.application", + ".mpp" => "application/vnd.ms-project", + ".mpy" => "application/vnd.ibm.minipay", + ".mqy" => "application/vnd.mobius.mqy", + ".mrc" => "application/marc", + ".ms" => "text/troff", + ".mscml" => "application/mediaservercontrol+xml", + ".mseq" => "application/vnd.mseq", + ".msf" => "application/vnd.epson.msf", + ".msh" => "model/mesh", + ".msi" => "application/x-msdownload", + ".msl" => "application/vnd.mobius.msl", + ".msty" => "application/vnd.muvee.style", + ".mts" => "model/vnd.mts", + ".mus" => "application/vnd.musician", + ".mvb" => "application/x-msmediaview", + ".mwf" => "application/vnd.mfer", + ".mxf" => "application/mxf", + ".mxl" => "application/vnd.recordare.musicxml", + ".mxml" => "application/xv+xml", + ".mxs" => "application/vnd.triscape.mxs", + ".mxu" => "video/vnd.mpegurl", + ".n" => "application/vnd.nokia.n-gage.symbian.install", + ".nc" => "application/x-netcdf", + ".ngdat" => "application/vnd.nokia.n-gage.data", + ".nlu" => "application/vnd.neurolanguage.nlu", + ".nml" => "application/vnd.enliven", + ".nnd" => "application/vnd.noblenet-directory", + ".nns" => "application/vnd.noblenet-sealer", + ".nnw" => "application/vnd.noblenet-web", + ".npx" => "image/vnd.net-fpx", + ".nsf" => "application/vnd.lotus-notes", + ".oa2" => "application/vnd.fujitsu.oasys2", + ".oa3" => "application/vnd.fujitsu.oasys3", + ".oas" => "application/vnd.fujitsu.oasys", + ".obd" => "application/x-msbinder", + ".oda" => "application/oda", + ".odc" => "application/vnd.oasis.opendocument.chart", + ".odf" => "application/vnd.oasis.opendocument.formula", + ".odg" => "application/vnd.oasis.opendocument.graphics", + ".odi" => "application/vnd.oasis.opendocument.image", + ".odp" => "application/vnd.oasis.opendocument.presentation", + ".ods" => "application/vnd.oasis.opendocument.spreadsheet", + ".odt" => "application/vnd.oasis.opendocument.text", + ".oga" => "audio/ogg", + ".ogg" => "application/ogg", + ".ogv" => "video/ogg", + ".ogx" => "application/ogg", + ".org" => "application/vnd.lotus-organizer", + ".otc" => "application/vnd.oasis.opendocument.chart-template", + ".otf" => "font/otf", + ".otg" => "application/vnd.oasis.opendocument.graphics-template", + ".oth" => "application/vnd.oasis.opendocument.text-web", + ".oti" => "application/vnd.oasis.opendocument.image-template", + ".otm" => "application/vnd.oasis.opendocument.text-master", + ".ots" => "application/vnd.oasis.opendocument.spreadsheet-template", + ".ott" => "application/vnd.oasis.opendocument.text-template", + ".oxt" => "application/vnd.openofficeorg.extension", + ".p" => "text/x-pascal", + ".p10" => "application/pkcs10", + ".p12" => "application/x-pkcs12", + ".p7b" => "application/x-pkcs7-certificates", + ".p7m" => "application/pkcs7-mime", + ".p7r" => "application/x-pkcs7-certreqresp", + ".p7s" => "application/pkcs7-signature", + ".pas" => "text/x-pascal", + ".pbd" => "application/vnd.powerbuilder6", + ".pbm" => "image/x-portable-bitmap", + ".pcl" => "application/vnd.hp-pcl", + ".pclxl" => "application/vnd.hp-pclxl", + ".pcx" => "image/x-pcx", + ".pdb" => "chemical/x-pdb", + ".pdf" => "application/pdf", + ".pem" => "application/x-x509-ca-cert", + ".pfr" => "application/font-tdpfr", + ".pgm" => "image/x-portable-graymap", + ".pgn" => "application/x-chess-pgn", + ".pgp" => "application/pgp-encrypted", + ".pic" => "image/x-pict", + ".pict" => "image/pict", + ".pkg" => "application/octet-stream", + ".pki" => "application/pkixcmp", + ".pkipath" => "application/pkix-pkipath", + ".pl" => "text/x-script.perl", + ".plb" => "application/vnd.3gpp.pic-bw-large", + ".plc" => "application/vnd.mobius.plc", + ".plf" => "application/vnd.pocketlearn", + ".pls" => "application/pls+xml", + ".pm" => "text/x-script.perl-module", + ".pml" => "application/vnd.ctc-posml", + ".png" => "image/png", + ".pnm" => "image/x-portable-anymap", + ".pntg" => "image/x-macpaint", + ".portpkg" => "application/vnd.macports.portpkg", + ".pot" => "application/vnd.ms-powerpoint", + ".potm" => "application/vnd.ms-powerpoint.template.macroEnabled.12", + ".potx" => "application/vnd.openxmlformats-officedocument.presentationml.template", + ".ppa" => "application/vnd.ms-powerpoint", + ".ppam" => "application/vnd.ms-powerpoint.addin.macroEnabled.12", + ".ppd" => "application/vnd.cups-ppd", + ".ppm" => "image/x-portable-pixmap", + ".pps" => "application/vnd.ms-powerpoint", + ".ppsm" => "application/vnd.ms-powerpoint.slideshow.macroEnabled.12", + ".ppsx" => "application/vnd.openxmlformats-officedocument.presentationml.slideshow", + ".ppt" => "application/vnd.ms-powerpoint", + ".pptm" => "application/vnd.ms-powerpoint.presentation.macroEnabled.12", + ".pptx" => "application/vnd.openxmlformats-officedocument.presentationml.presentation", + ".prc" => "application/vnd.palm", + ".pre" => "application/vnd.lotus-freelance", + ".prf" => "application/pics-rules", + ".ps" => "application/postscript", + ".psb" => "application/vnd.3gpp.pic-bw-small", + ".psd" => "image/vnd.adobe.photoshop", + ".ptid" => "application/vnd.pvi.ptid1", + ".pub" => "application/x-mspublisher", + ".pvb" => "application/vnd.3gpp.pic-bw-var", + ".pwn" => "application/vnd.3m.post-it-notes", + ".py" => "text/x-script.python", + ".pya" => "audio/vnd.ms-playready.media.pya", + ".pyv" => "video/vnd.ms-playready.media.pyv", + ".qam" => "application/vnd.epson.quickanime", + ".qbo" => "application/vnd.intu.qbo", + ".qfx" => "application/vnd.intu.qfx", + ".qps" => "application/vnd.publishare-delta-tree", + ".qt" => "video/quicktime", + ".qtif" => "image/x-quicktime", + ".qxd" => "application/vnd.quark.quarkxpress", + ".ra" => "audio/x-pn-realaudio", + ".rake" => "text/x-script.ruby", + ".ram" => "audio/x-pn-realaudio", + ".rar" => "application/x-rar-compressed", + ".ras" => "image/x-cmu-raster", + ".rb" => "text/x-script.ruby", + ".rcprofile" => "application/vnd.ipunplugged.rcprofile", + ".rdf" => "application/rdf+xml", + ".rdz" => "application/vnd.data-vision.rdz", + ".rep" => "application/vnd.businessobjects", + ".rgb" => "image/x-rgb", + ".rif" => "application/reginfo+xml", + ".rl" => "application/resource-lists+xml", + ".rlc" => "image/vnd.fujixerox.edmics-rlc", + ".rld" => "application/resource-lists-diff+xml", + ".rm" => "application/vnd.rn-realmedia", + ".rmp" => "audio/x-pn-realaudio-plugin", + ".rms" => "application/vnd.jcp.javame.midlet-rms", + ".rnc" => "application/relax-ng-compact-syntax", + ".roff" => "text/troff", + ".rpm" => "application/x-redhat-package-manager", + ".rpss" => "application/vnd.nokia.radio-presets", + ".rpst" => "application/vnd.nokia.radio-preset", + ".rq" => "application/sparql-query", + ".rs" => "application/rls-services+xml", + ".rsd" => "application/rsd+xml", + ".rss" => "application/rss+xml", + ".rtf" => "application/rtf", + ".rtx" => "text/richtext", + ".ru" => "text/x-script.ruby", + ".s" => "text/x-asm", + ".saf" => "application/vnd.yamaha.smaf-audio", + ".sbml" => "application/sbml+xml", + ".sc" => "application/vnd.ibm.secure-container", + ".scd" => "application/x-msschedule", + ".scm" => "application/vnd.lotus-screencam", + ".scq" => "application/scvp-cv-request", + ".scs" => "application/scvp-cv-response", + ".sdkm" => "application/vnd.solent.sdkm+xml", + ".sdp" => "application/sdp", + ".see" => "application/vnd.seemail", + ".sema" => "application/vnd.sema", + ".semd" => "application/vnd.semd", + ".semf" => "application/vnd.semf", + ".setpay" => "application/set-payment-initiation", + ".setreg" => "application/set-registration-initiation", + ".sfd" => "application/vnd.hydrostatix.sof-data", + ".sfs" => "application/vnd.spotfire.sfs", + ".sgm" => "text/sgml", + ".sgml" => "text/sgml", + ".sh" => "application/x-sh", + ".shar" => "application/x-shar", + ".shf" => "application/shf+xml", + ".sig" => "application/pgp-signature", + ".sit" => "application/x-stuffit", + ".sitx" => "application/x-stuffitx", + ".skp" => "application/vnd.koan", + ".slt" => "application/vnd.epson.salt", + ".smi" => "application/smil+xml", + ".snd" => "audio/basic", + ".so" => "application/octet-stream", + ".spf" => "application/vnd.yamaha.smaf-phrase", + ".spl" => "application/x-futuresplash", + ".spot" => "text/vnd.in3d.spot", + ".spp" => "application/scvp-vp-response", + ".spq" => "application/scvp-vp-request", + ".src" => "application/x-wais-source", + ".srt" => "text/srt", + ".srx" => "application/sparql-results+xml", + ".sse" => "application/vnd.kodak-descriptor", + ".ssf" => "application/vnd.epson.ssf", + ".ssml" => "application/ssml+xml", + ".stf" => "application/vnd.wt.stf", + ".stk" => "application/hyperstudio", + ".str" => "application/vnd.pg.format", + ".sus" => "application/vnd.sus-calendar", + ".sv4cpio" => "application/x-sv4cpio", + ".sv4crc" => "application/x-sv4crc", + ".svd" => "application/vnd.svd", + ".svg" => "image/svg+xml", + ".svgz" => "image/svg+xml", + ".swf" => "application/x-shockwave-flash", + ".swi" => "application/vnd.arastra.swi", + ".t" => "text/troff", + ".tao" => "application/vnd.tao.intent-module-archive", + ".tar" => "application/x-tar", + ".tbz" => "application/x-bzip-compressed-tar", + ".tcap" => "application/vnd.3gpp2.tcap", + ".tcl" => "application/x-tcl", + ".tex" => "application/x-tex", + ".texi" => "application/x-texinfo", + ".texinfo" => "application/x-texinfo", + ".text" => "text/plain", + ".tif" => "image/tiff", + ".tiff" => "image/tiff", + ".tmo" => "application/vnd.tmobile-livetv", + ".torrent" => "application/x-bittorrent", + ".tpl" => "application/vnd.groove-tool-template", + ".tpt" => "application/vnd.trid.tpt", + ".tr" => "text/troff", + ".tra" => "application/vnd.trueapp", + ".trm" => "application/x-msterminal", + ".ts" => "video/mp2t", + ".tsv" => "text/tab-separated-values", + ".ttf" => "font/ttf", + ".twd" => "application/vnd.simtech-mindmapper", + ".txd" => "application/vnd.genomatix.tuxedo", + ".txf" => "application/vnd.mobius.txf", + ".txt" => "text/plain", + ".ufd" => "application/vnd.ufdl", + ".umj" => "application/vnd.umajin", + ".unityweb" => "application/vnd.unity", + ".uoml" => "application/vnd.uoml+xml", + ".uri" => "text/uri-list", + ".ustar" => "application/x-ustar", + ".utz" => "application/vnd.uiq.theme", + ".uu" => "text/x-uuencode", + ".vcd" => "application/x-cdlink", + ".vcf" => "text/x-vcard", + ".vcg" => "application/vnd.groove-vcard", + ".vcs" => "text/x-vcalendar", + ".vcx" => "application/vnd.vcx", + ".vis" => "application/vnd.visionary", + ".viv" => "video/vnd.vivo", + ".vrml" => "model/vrml", + ".vsd" => "application/vnd.visio", + ".vsf" => "application/vnd.vsf", + ".vtt" => "text/vtt", + ".vtu" => "model/vnd.vtu", + ".vxml" => "application/voicexml+xml", + ".war" => "application/java-archive", + ".wasm" => "application/wasm", + ".wav" => "audio/x-wav", + ".wax" => "audio/x-ms-wax", + ".wbmp" => "image/vnd.wap.wbmp", + ".wbs" => "application/vnd.criticaltools.wbs+xml", + ".wbxml" => "application/vnd.wap.wbxml", + ".webm" => "video/webm", + ".webp" => "image/webp", + ".wm" => "video/x-ms-wm", + ".wma" => "audio/x-ms-wma", + ".wmd" => "application/x-ms-wmd", + ".wmf" => "application/x-msmetafile", + ".wml" => "text/vnd.wap.wml", + ".wmlc" => "application/vnd.wap.wmlc", + ".wmls" => "text/vnd.wap.wmlscript", + ".wmlsc" => "application/vnd.wap.wmlscriptc", + ".wmv" => "video/x-ms-wmv", + ".wmx" => "video/x-ms-wmx", + ".wmz" => "application/x-ms-wmz", + ".woff" => "font/woff", + ".woff2" => "font/woff2", + ".wpd" => "application/vnd.wordperfect", + ".wpl" => "application/vnd.ms-wpl", + ".wps" => "application/vnd.ms-works", + ".wqd" => "application/vnd.wqd", + ".wri" => "application/x-mswrite", + ".wrl" => "model/vrml", + ".wsdl" => "application/wsdl+xml", + ".wspolicy" => "application/wspolicy+xml", + ".wtb" => "application/vnd.webturbo", + ".wvx" => "video/x-ms-wvx", + ".x3d" => "application/vnd.hzn-3d-crossword", + ".xar" => "application/vnd.xara", + ".xbd" => "application/vnd.fujixerox.docuworks.binder", + ".xbm" => "image/x-xbitmap", + ".xdm" => "application/vnd.syncml.dm+xml", + ".xdp" => "application/vnd.adobe.xdp+xml", + ".xdw" => "application/vnd.fujixerox.docuworks", + ".xenc" => "application/xenc+xml", + ".xer" => "application/patch-ops-error+xml", + ".xfdf" => "application/vnd.adobe.xfdf", + ".xfdl" => "application/vnd.xfdl", + ".xhtml" => "application/xhtml+xml", + ".xif" => "image/vnd.xiff", + ".xla" => "application/vnd.ms-excel", + ".xlam" => "application/vnd.ms-excel.addin.macroEnabled.12", + ".xls" => "application/vnd.ms-excel", + ".xlsb" => "application/vnd.ms-excel.sheet.binary.macroEnabled.12", + ".xlsx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + ".xlsm" => "application/vnd.ms-excel.sheet.macroEnabled.12", + ".xlt" => "application/vnd.ms-excel", + ".xltx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.template", + ".xml" => "application/xml", + ".xo" => "application/vnd.olpc-sugar", + ".xop" => "application/xop+xml", + ".xpm" => "image/x-xpixmap", + ".xpr" => "application/vnd.is-xpr", + ".xps" => "application/vnd.ms-xpsdocument", + ".xpw" => "application/vnd.intercon.formnet", + ".xsl" => "application/xml", + ".xslt" => "application/xslt+xml", + ".xsm" => "application/vnd.syncml+xml", + ".xspf" => "application/xspf+xml", + ".xul" => "application/vnd.mozilla.xul+xml", + ".xwd" => "image/x-xwindowdump", + ".xyz" => "chemical/x-xyz", + ".yaml" => "text/yaml", + ".yml" => "text/yaml", + ".zaz" => "application/vnd.zzazz.deck+xml", + ".zip" => "application/zip", + ".zmm" => "application/vnd.handheld-entertainment+xml", + } + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/mock.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/mock.rb new file mode 100644 index 00000000..5e5c457c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/mock.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +require_relative 'mock_request' diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/mock_request.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/mock_request.rb new file mode 100644 index 00000000..7c87bea5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/mock_request.rb @@ -0,0 +1,161 @@ +# frozen_string_literal: true + +require 'uri' +require 'stringio' + +require_relative 'constants' +require_relative 'mock_response' + +module Rack + # Rack::MockRequest helps testing your Rack application without + # actually using HTTP. + # + # After performing a request on a URL with get/post/put/patch/delete, it + # returns a MockResponse with useful helper methods for effective + # testing. + # + # You can pass a hash with additional configuration to the + # get/post/put/patch/delete. + # :input:: A String or IO-like to be used as rack.input. + # :fatal:: Raise a FatalWarning if the app writes to rack.errors. + # :lint:: If true, wrap the application in a Rack::Lint. + + class MockRequest + class FatalWarning < RuntimeError + end + + class FatalWarner + def puts(warning) + raise FatalWarning, warning + end + + def write(warning) + raise FatalWarning, warning + end + + def flush + end + + def string + "" + end + end + + def initialize(app) + @app = app + end + + # Make a GET request and return a MockResponse. See #request. + def get(uri, opts = {}) request(GET, uri, opts) end + # Make a POST request and return a MockResponse. See #request. + def post(uri, opts = {}) request(POST, uri, opts) end + # Make a PUT request and return a MockResponse. See #request. + def put(uri, opts = {}) request(PUT, uri, opts) end + # Make a PATCH request and return a MockResponse. See #request. + def patch(uri, opts = {}) request(PATCH, uri, opts) end + # Make a DELETE request and return a MockResponse. See #request. + def delete(uri, opts = {}) request(DELETE, uri, opts) end + # Make a HEAD request and return a MockResponse. See #request. + def head(uri, opts = {}) request(HEAD, uri, opts) end + # Make an OPTIONS request and return a MockResponse. See #request. + def options(uri, opts = {}) request(OPTIONS, uri, opts) end + + # Make a request using the given request method for the given + # uri to the rack application and return a MockResponse. + # Options given are passed to MockRequest.env_for. + def request(method = GET, uri = "", opts = {}) + env = self.class.env_for(uri, opts.merge(method: method)) + + if opts[:lint] + app = Rack::Lint.new(@app) + else + app = @app + end + + errors = env[RACK_ERRORS] + status, headers, body = app.call(env) + MockResponse.new(status, headers, body, errors) + ensure + body.close if body.respond_to?(:close) + end + + # For historical reasons, we're pinning to RFC 2396. + # URI::Parser = URI::RFC2396_Parser + def self.parse_uri_rfc2396(uri) + @parser ||= URI::Parser.new + @parser.parse(uri) + end + + # Return the Rack environment used for a request to +uri+. + # All options that are strings are added to the returned environment. + # Options: + # :fatal :: Whether to raise an exception if request outputs to rack.errors + # :input :: The rack.input to set + # :http_version :: The SERVER_PROTOCOL to set + # :method :: The HTTP request method to use + # :params :: The params to use + # :script_name :: The SCRIPT_NAME to set + def self.env_for(uri = "", opts = {}) + uri = parse_uri_rfc2396(uri) + uri.path = "/#{uri.path}" unless uri.path[0] == ?/ + + env = {} + + env[REQUEST_METHOD] = (opts[:method] ? opts[:method].to_s.upcase : GET).b + env[SERVER_NAME] = (uri.host || "example.org").b + env[SERVER_PORT] = (uri.port ? uri.port.to_s : "80").b + env[SERVER_PROTOCOL] = opts[:http_version] || 'HTTP/1.1' + env[QUERY_STRING] = (uri.query.to_s).b + env[PATH_INFO] = (uri.path).b + env[RACK_URL_SCHEME] = (uri.scheme || "http").b + env[HTTPS] = (env[RACK_URL_SCHEME] == "https" ? "on" : "off").b + + env[SCRIPT_NAME] = opts[:script_name] || "" + + if opts[:fatal] + env[RACK_ERRORS] = FatalWarner.new + else + env[RACK_ERRORS] = StringIO.new + end + + if params = opts[:params] + if env[REQUEST_METHOD] == GET + params = Utils.parse_nested_query(params) if params.is_a?(String) + params.update(Utils.parse_nested_query(env[QUERY_STRING])) + env[QUERY_STRING] = Utils.build_nested_query(params) + elsif !opts.has_key?(:input) + opts["CONTENT_TYPE"] = "application/x-www-form-urlencoded" + if params.is_a?(Hash) + if data = Rack::Multipart.build_multipart(params) + opts[:input] = data + opts["CONTENT_LENGTH"] ||= data.length.to_s + opts["CONTENT_TYPE"] = "multipart/form-data; boundary=#{Rack::Multipart::MULTIPART_BOUNDARY}" + else + opts[:input] = Utils.build_nested_query(params) + end + else + opts[:input] = params + end + end + end + + rack_input = opts[:input] + if String === rack_input + rack_input = StringIO.new(rack_input) + end + + if rack_input + rack_input.set_encoding(Encoding::BINARY) if rack_input.respond_to?(:set_encoding) + env[RACK_INPUT] = rack_input + + env["CONTENT_LENGTH"] ||= env[RACK_INPUT].size.to_s if env[RACK_INPUT].respond_to?(:size) + end + + opts.each { |field, value| + env[field] = value if String === field + } + + env + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/mock_response.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/mock_response.rb new file mode 100644 index 00000000..a3ed3db5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/mock_response.rb @@ -0,0 +1,153 @@ +# frozen_string_literal: true + +require 'time' + +require_relative 'response' + +module Rack + # Rack::MockResponse provides useful helpers for testing your apps. + # Usually, you don't create the MockResponse on your own, but use + # MockRequest. + + class MockResponse < Rack::Response + begin + # Recent versions of the CGI gem may not provide `CGI::Cookie`. + require 'cgi/cookie' + Cookie = CGI::Cookie + rescue LoadError + class Cookie + attr_reader :name, :value, :path, :domain, :expires, :secure + + def initialize(args) + @name = args["name"] + @value = args["value"] + @path = args["path"] + @domain = args["domain"] + @expires = args["expires"] + @secure = args["secure"] + end + + def method_missing(method_name, *args, &block) + @value.send(method_name, *args, &block) + end + # :nocov: + ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true) + # :nocov: + + def respond_to_missing?(method_name, include_all = false) + @value.respond_to?(method_name, include_all) || super + end + end + end + + class << self + alias [] new + end + + # Headers + attr_reader :original_headers, :cookies + + # Errors + attr_accessor :errors + + def initialize(status, headers, body, errors = nil) + @original_headers = headers + + if errors + @errors = errors.string if errors.respond_to?(:string) + else + @errors = "" + end + + super(body, status, headers) + + @cookies = parse_cookies_from_header + buffered_body! + end + + def =~(other) + body =~ other + end + + def match(other) + body.match other + end + + def body + return @buffered_body if defined?(@buffered_body) + + # FIXME: apparently users of MockResponse expect the return value of + # MockResponse#body to be a string. However, the real response object + # returns the body as a list. + # + # See spec_showstatus.rb: + # + # should "not replace existing messages" do + # ... + # res.body.should == "foo!" + # end + buffer = @buffered_body = String.new + + @body.each do |chunk| + buffer << chunk + end + + return buffer + end + + def empty? + [201, 204, 304].include? status + end + + def cookie(name) + cookies.fetch(name, nil) + end + + private + + def parse_cookies_from_header + cookies = Hash.new + set_cookie_header = headers['set-cookie'] + if set_cookie_header && !set_cookie_header.empty? + Array(set_cookie_header).each do |cookie| + cookie_name, cookie_filling = cookie.split('=', 2) + cookie_attributes = identify_cookie_attributes cookie_filling + parsed_cookie = Cookie.new( + 'name' => cookie_name.strip, + 'value' => cookie_attributes.fetch('value'), + 'path' => cookie_attributes.fetch('path', nil), + 'domain' => cookie_attributes.fetch('domain', nil), + 'expires' => cookie_attributes.fetch('expires', nil), + 'secure' => cookie_attributes.fetch('secure', false) + ) + cookies.store(cookie_name, parsed_cookie) + end + end + cookies + end + + def identify_cookie_attributes(cookie_filling) + cookie_bits = cookie_filling.split(';') + cookie_attributes = Hash.new + cookie_attributes.store('value', Array(cookie_bits[0].strip)) + cookie_bits.drop(1).each do |bit| + if bit.include? '=' + cookie_attribute, attribute_value = bit.split('=', 2) + cookie_attributes.store(cookie_attribute.strip.downcase, attribute_value.strip) + end + if bit.include? 'secure' + cookie_attributes.store('secure', true) + end + end + + if cookie_attributes.key? 'max-age' + cookie_attributes.store('expires', Time.now + cookie_attributes['max-age'].to_i) + elsif cookie_attributes.key? 'expires' + cookie_attributes.store('expires', Time.httpdate(cookie_attributes['expires'])) + end + + cookie_attributes + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/multipart.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/multipart.rb new file mode 100644 index 00000000..4b02fb3e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/multipart.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +require_relative 'constants' +require_relative 'utils' + +require_relative 'multipart/parser' +require_relative 'multipart/generator' + +require_relative 'bad_request' + +module Rack + # A multipart form data parser, adapted from IOWA. + # + # Usually, Rack::Request#POST takes care of calling this. + module Multipart + MULTIPART_BOUNDARY = "AaB03x" + + class MissingInputError < StandardError + include BadRequest + end + + # Accumulator for multipart form data, conforming to the QueryParser API. + # In future, the Parser could return the pair list directly, but that would + # change its API. + class ParamList # :nodoc: + def self.make_params + new + end + + def self.normalize_params(params, key, value) + params << [key, value] + end + + def initialize + @pairs = [] + end + + def <<(pair) + @pairs << pair + end + + def to_params_hash + @pairs + end + end + + class << self + def parse_multipart(env, params = Rack::Utils.default_query_parser) + unless io = env[RACK_INPUT] + raise MissingInputError, "Missing input stream!" + end + + if content_length = env['CONTENT_LENGTH'] + content_length = content_length.to_i + end + + content_type = env['CONTENT_TYPE'] + + tempfile = env[RACK_MULTIPART_TEMPFILE_FACTORY] || Parser::TEMPFILE_FACTORY + bufsize = env[RACK_MULTIPART_BUFFER_SIZE] || Parser::BUFSIZE + + info = Parser.parse(io, content_length, content_type, tempfile, bufsize, params) + env[RACK_TEMPFILES] = info.tmp_files + + return info.params + end + + def extract_multipart(request, params = Rack::Utils.default_query_parser) + parse_multipart(request.env) + end + + def build_multipart(params, first = true) + Generator.new(params, first).dump + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/multipart/generator.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/multipart/generator.rb new file mode 100644 index 00000000..30d7f51d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/multipart/generator.rb @@ -0,0 +1,99 @@ +# frozen_string_literal: true + +require_relative 'uploaded_file' + +module Rack + module Multipart + class Generator + def initialize(params, first = true) + @params, @first = params, first + + if @first && !@params.is_a?(Hash) + raise ArgumentError, "value must be a Hash" + end + end + + def dump + return nil if @first && !multipart? + return flattened_params unless @first + + flattened_params.map do |name, file| + if file.respond_to?(:original_filename) + if file.path + ::File.open(file.path, 'rb') do |f| + f.set_encoding(Encoding::BINARY) + content_for_tempfile(f, file, name) + end + else + content_for_tempfile(file, file, name) + end + else + content_for_other(file, name) + end + end.join << "--#{MULTIPART_BOUNDARY}--\r" + end + + private + def multipart? + query = lambda { |value| + case value + when Array + value.any?(&query) + when Hash + value.values.any?(&query) + when Rack::Multipart::UploadedFile + true + end + } + + @params.values.any?(&query) + end + + def flattened_params + @flattened_params ||= begin + h = Hash.new + @params.each do |key, value| + k = @first ? key.to_s : "[#{key}]" + + case value + when Array + value.map { |v| + Multipart.build_multipart(v, false).each { |subkey, subvalue| + h["#{k}[]#{subkey}"] = subvalue + } + } + when Hash + Multipart.build_multipart(value, false).each { |subkey, subvalue| + h[k + subkey] = subvalue + } + else + h[k] = value + end + end + h + end + end + + def content_for_tempfile(io, file, name) + length = ::File.stat(file.path).size if file.path + filename = "; filename=\"#{Utils.escape_path(file.original_filename)}\"" +<<-EOF +--#{MULTIPART_BOUNDARY}\r +content-disposition: form-data; name="#{name}"#{filename}\r +content-type: #{file.content_type}\r +#{"content-length: #{length}\r\n" if length}\r +#{io.read}\r +EOF + end + + def content_for_other(file, name) +<<-EOF +--#{MULTIPART_BOUNDARY}\r +content-disposition: form-data; name="#{name}"\r +\r +#{file}\r +EOF + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/multipart/parser.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/multipart/parser.rb new file mode 100644 index 00000000..c78f0e39 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/multipart/parser.rb @@ -0,0 +1,504 @@ +# frozen_string_literal: true + +require 'strscan' + +require_relative '../utils' +require_relative '../bad_request' + +module Rack + module Multipart + class MultipartPartLimitError < Errno::EMFILE + include BadRequest + end + + class MultipartTotalPartLimitError < StandardError + include BadRequest + end + + # Use specific error class when parsing multipart request + # that ends early. + class EmptyContentError < ::EOFError + include BadRequest + end + + # Base class for multipart exceptions that do not subclass from + # other exception classes for backwards compatibility. + class BoundaryTooLongError < StandardError + include BadRequest + end + + # Prefer to use the BoundaryTooLongError class or Rack::BadRequest. + Error = BoundaryTooLongError + + EOL = "\r\n" + FWS = /[ \t]+(?:\r\n[ \t]+)?/ # whitespace with optional folding + HEADER_VALUE = "(?:[^\r\n]|\r\n[ \t])*" # anything but a non-folding CRLF + MULTIPART = %r|\Amultipart/.*boundary=\"?([^\";,]+)\"?|ni + MULTIPART_CONTENT_TYPE = /^Content-Type:#{FWS}?(#{HEADER_VALUE})/ni + MULTIPART_CONTENT_DISPOSITION = /^Content-Disposition:#{FWS}?(#{HEADER_VALUE})/ni + MULTIPART_CONTENT_ID = /^Content-ID:#{FWS}?(#{HEADER_VALUE})/ni + + class Parser + BUFSIZE = 1_048_576 + TEXT_PLAIN = "text/plain" + TEMPFILE_FACTORY = lambda { |filename, content_type| + extension = ::File.extname(filename.gsub("\0", '%00'))[0, 129] + + Tempfile.new(["RackMultipart", extension]) + } + + class BoundedIO # :nodoc: + def initialize(io, content_length) + @io = io + @content_length = content_length + @cursor = 0 + end + + def read(size, outbuf = nil) + return if @cursor >= @content_length + + left = @content_length - @cursor + + str = if left < size + @io.read left, outbuf + else + @io.read size, outbuf + end + + if str + @cursor += str.bytesize + else + # Raise an error for mismatching content-length and actual contents + raise EOFError, "bad content body" + end + + str + end + end + + MultipartInfo = Struct.new :params, :tmp_files + EMPTY = MultipartInfo.new(nil, []) + + def self.parse_boundary(content_type) + return unless content_type + data = content_type.match(MULTIPART) + return unless data + data[1] + end + + def self.parse(io, content_length, content_type, tmpfile, bufsize, qp) + return EMPTY if 0 == content_length + + boundary = parse_boundary content_type + return EMPTY unless boundary + + if boundary.length > 70 + # RFC 1521 Section 7.2.1 imposes a 70 character maximum for the boundary. + # Most clients use no more than 55 characters. + raise BoundaryTooLongError, "multipart boundary size too large (#{boundary.length} characters)" + end + + io = BoundedIO.new(io, content_length) if content_length + + parser = new(boundary, tmpfile, bufsize, qp) + parser.parse(io) + + parser.result + end + + class Collector + class MimePart < Struct.new(:body, :head, :filename, :content_type, :name) + def get_data + data = body + if filename == "" + # filename is blank which means no file has been selected + return + elsif filename + body.rewind if body.respond_to?(:rewind) + + # Take the basename of the upload's original filename. + # This handles the full Windows paths given by Internet Explorer + # (and perhaps other broken user agents) without affecting + # those which give the lone filename. + fn = filename.split(/[\/\\]/).last + + data = { filename: fn, type: content_type, + name: name, tempfile: body, head: head } + end + + yield data + end + end + + class BufferPart < MimePart + def file?; false; end + def close; end + end + + class TempfilePart < MimePart + def file?; true; end + def close; body.close; end + end + + include Enumerable + + def initialize(tempfile) + @tempfile = tempfile + @mime_parts = [] + @open_files = 0 + end + + def each + @mime_parts.each { |part| yield part } + end + + def on_mime_head(mime_index, head, filename, content_type, name) + if filename + body = @tempfile.call(filename, content_type) + body.binmode if body.respond_to?(:binmode) + klass = TempfilePart + @open_files += 1 + else + body = String.new + klass = BufferPart + end + + @mime_parts[mime_index] = klass.new(body, head, filename, content_type, name) + + check_part_limits + end + + def on_mime_body(mime_index, content) + @mime_parts[mime_index].body << content + end + + def on_mime_finish(mime_index) + end + + private + + def check_part_limits + file_limit = Utils.multipart_file_limit + part_limit = Utils.multipart_total_part_limit + + if file_limit && file_limit > 0 + if @open_files >= file_limit + @mime_parts.each(&:close) + raise MultipartPartLimitError, 'Maximum file multiparts in content reached' + end + end + + if part_limit && part_limit > 0 + if @mime_parts.size >= part_limit + @mime_parts.each(&:close) + raise MultipartTotalPartLimitError, 'Maximum total multiparts in content reached' + end + end + end + end + + attr_reader :state + + def initialize(boundary, tempfile, bufsize, query_parser) + @query_parser = query_parser + @params = query_parser.make_params + @bufsize = bufsize + + @state = :FAST_FORWARD + @mime_index = 0 + @collector = Collector.new tempfile + + @sbuf = StringScanner.new("".dup) + @body_regex = /(?:#{EOL}|\A)--#{Regexp.quote(boundary)}(?:#{EOL}|--)/m + @body_regex_at_end = /#{@body_regex}\z/m + @end_boundary_size = boundary.bytesize + 4 # (-- at start, -- at finish) + @rx_max_size = boundary.bytesize + 6 # (\r\n-- at start, either \r\n or -- at finish) + @head_regex = /(.*?#{EOL})#{EOL}/m + end + + def parse(io) + outbuf = String.new + read_data(io, outbuf) + + loop do + status = + case @state + when :FAST_FORWARD + handle_fast_forward + when :CONSUME_TOKEN + handle_consume_token + when :MIME_HEAD + handle_mime_head + when :MIME_BODY + handle_mime_body + else # when :DONE + return + end + + read_data(io, outbuf) if status == :want_read + end + end + + def result + @collector.each do |part| + part.get_data do |data| + tag_multipart_encoding(part.filename, part.content_type, part.name, data) + @query_parser.normalize_params(@params, part.name, data) + end + end + MultipartInfo.new @params.to_params_hash, @collector.find_all(&:file?).map(&:body) + end + + private + + def dequote(str) # From WEBrick::HTTPUtils + ret = (/\A"(.*)"\Z/ =~ str) ? $1 : str.dup + ret.gsub!(/\\(.)/, "\\1") + ret + end + + def read_data(io, outbuf) + content = io.read(@bufsize, outbuf) + handle_empty_content!(content) + @sbuf.concat(content) + end + + # This handles the initial parser state. We read until we find the starting + # boundary, then we can transition to the next state. If we find the ending + # boundary, this is an invalid multipart upload, but keep scanning for opening + # boundary in that case. If no boundary found, we need to keep reading data + # and retry. It's highly unlikely the initial read will not consume the + # boundary. The client would have to deliberately craft a response + # with the opening boundary beyond the buffer size for that to happen. + def handle_fast_forward + while true + case consume_boundary + when :BOUNDARY + # found opening boundary, transition to next state + @state = :MIME_HEAD + return + when :END_BOUNDARY + # invalid multipart upload + if @sbuf.pos == @end_boundary_size && @sbuf.rest == EOL + # stop parsing a buffer if a buffer is only an end boundary. + @state = :DONE + return + end + + # retry for opening boundary + else + # no boundary found, keep reading data + return :want_read + end + end + end + + def handle_consume_token + tok = consume_boundary + # break if we're at the end of a buffer, but not if it is the end of a field + @state = if tok == :END_BOUNDARY || (@sbuf.eos? && tok != :BOUNDARY) + :DONE + else + :MIME_HEAD + end + end + + CONTENT_DISPOSITION_MAX_PARAMS = 16 + CONTENT_DISPOSITION_MAX_BYTES = 1536 + def handle_mime_head + if @sbuf.scan_until(@head_regex) + head = @sbuf[1] + content_type = head[MULTIPART_CONTENT_TYPE, 1] + if (disposition = head[MULTIPART_CONTENT_DISPOSITION, 1]) && + disposition.bytesize <= CONTENT_DISPOSITION_MAX_BYTES + + # ignore actual content-disposition value (should always be form-data) + i = disposition.index(';') + disposition.slice!(0, i+1) + param = nil + num_params = 0 + + # Parse parameter list + while i = disposition.index('=') + # Only parse up to max parameters, to avoid potential denial of service + num_params += 1 + break if num_params > CONTENT_DISPOSITION_MAX_PARAMS + + # Found end of parameter name, ensure forward progress in loop + param = disposition.slice!(0, i+1) + + # Remove ending equals and preceding whitespace from parameter name + param.chomp!('=') + param.lstrip! + + if disposition[0] == '"' + # Parameter value is quoted, parse it, handling backslash escapes + disposition.slice!(0, 1) + value = String.new + + while i = disposition.index(/(["\\])/) + c = $1 + + # Append all content until ending quote or escape + value << disposition.slice!(0, i) + + # Remove either backslash or ending quote, + # ensures forward progress in loop + disposition.slice!(0, 1) + + # stop parsing parameter value if found ending quote + break if c == '"' + + escaped_char = disposition.slice!(0, 1) + if param == 'filename' && escaped_char != '"' + # Possible IE uploaded filename, append both escape backslash and value + value << c << escaped_char + else + # Other only append escaped value + value << escaped_char + end + end + else + if i = disposition.index(';') + # Parameter value unquoted (which may be invalid), value ends at semicolon + value = disposition.slice!(0, i) + else + # If no ending semicolon, assume remainder of line is value and stop + # parsing + disposition.strip! + value = disposition + disposition = '' + end + end + + case param + when 'name' + name = value + when 'filename' + filename = value + when 'filename*' + filename_star = value + # else + # ignore other parameters + end + + # skip trailing semicolon, to proceed to next parameter + if i = disposition.index(';') + disposition.slice!(0, i+1) + end + end + else + name = head[MULTIPART_CONTENT_ID, 1] + end + + if filename_star + encoding, _, filename = filename_star.split("'", 3) + filename = normalize_filename(filename || '') + filename.force_encoding(find_encoding(encoding)) + elsif filename + filename = normalize_filename(filename) + end + + if name.nil? || name.empty? + name = filename || "#{content_type || TEXT_PLAIN}[]".dup + end + + @collector.on_mime_head @mime_index, head, filename, content_type, name + @state = :MIME_BODY + else + :want_read + end + end + + def handle_mime_body + if (body_with_boundary = @sbuf.check_until(@body_regex)) # check but do not advance the pointer yet + body = body_with_boundary.sub(@body_regex_at_end, '') # remove the boundary from the string + @collector.on_mime_body @mime_index, body + @sbuf.pos += body.length + 2 # skip \r\n after the content + @state = :CONSUME_TOKEN + @mime_index += 1 + else + # Save what we have so far + if @rx_max_size < @sbuf.rest_size + delta = @sbuf.rest_size - @rx_max_size + @collector.on_mime_body @mime_index, @sbuf.peek(delta) + @sbuf.pos += delta + @sbuf.string = @sbuf.rest + end + :want_read + end + end + + # Scan until the we find the start or end of the boundary. + # If we find it, return the appropriate symbol for the start or + # end of the boundary. If we don't find the start or end of the + # boundary, clear the buffer and return nil. + def consume_boundary + if read_buffer = @sbuf.scan_until(@body_regex) + read_buffer.end_with?(EOL) ? :BOUNDARY : :END_BOUNDARY + else + @sbuf.terminate + nil + end + end + + def normalize_filename(filename) + if filename.scan(/%.?.?/).all? { |s| /%[0-9a-fA-F]{2}/.match?(s) } + filename = Utils.unescape_path(filename) + end + + filename.scrub! + + filename.split(/[\/\\]/).last || String.new + end + + CHARSET = "charset" + deprecate_constant :CHARSET + + def tag_multipart_encoding(filename, content_type, name, body) + name = name.to_s + encoding = Encoding::UTF_8 + + name.force_encoding(encoding) + + return if filename + + if content_type + list = content_type.split(';') + type_subtype = list.first + type_subtype.strip! + if TEXT_PLAIN == type_subtype + rest = list.drop 1 + rest.each do |param| + k, v = param.split('=', 2) + k.strip! + v.strip! + v = v[1..-2] if v.start_with?('"') && v.end_with?('"') + if k == "charset" + encoding = find_encoding(v) + end + end + end + end + + name.force_encoding(encoding) + body.force_encoding(encoding) + end + + # Return the related Encoding object. However, because + # enc is submitted by the user, it may be invalid, so + # use a binary encoding in that case. + def find_encoding(enc) + Encoding.find enc + rescue ArgumentError + Encoding::BINARY + end + + def handle_empty_content!(content) + if content.nil? || content.empty? + raise EmptyContentError + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/multipart/uploaded_file.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/multipart/uploaded_file.rb new file mode 100644 index 00000000..2782e44c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/multipart/uploaded_file.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'tempfile' +require 'fileutils' + +module Rack + module Multipart + class UploadedFile + + # The filename, *not* including the path, of the "uploaded" file + attr_reader :original_filename + + # The content type of the "uploaded" file + attr_accessor :content_type + + def initialize(filepath = nil, ct = "text/plain", bin = false, + path: filepath, content_type: ct, binary: bin, filename: nil, io: nil) + if io + @tempfile = io + @original_filename = filename + else + raise "#{path} file does not exist" unless ::File.exist?(path) + @original_filename = filename || ::File.basename(path) + @tempfile = Tempfile.new([@original_filename, ::File.extname(path)], encoding: Encoding::BINARY) + @tempfile.binmode if binary + FileUtils.copy_file(path, @tempfile.path) + end + @content_type = content_type + end + + def path + @tempfile.path if @tempfile.respond_to?(:path) + end + alias_method :local_path, :path + + def respond_to?(*args) + super or @tempfile.respond_to?(*args) + end + + def method_missing(method_name, *args, &block) #:nodoc: + @tempfile.__send__(method_name, *args, &block) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/null_logger.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/null_logger.rb new file mode 100644 index 00000000..52fc125c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/null_logger.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +require_relative 'constants' + +module Rack + class NullLogger + def initialize(app) + @app = app + end + + def call(env) + env[RACK_LOGGER] = self + @app.call(env) + end + + def info(progname = nil, &block); end + def debug(progname = nil, &block); end + def warn(progname = nil, &block); end + def error(progname = nil, &block); end + def fatal(progname = nil, &block); end + def unknown(progname = nil, &block); end + def info? ; end + def debug? ; end + def warn? ; end + def error? ; end + def fatal? ; end + def debug! ; end + def error! ; end + def fatal! ; end + def info! ; end + def warn! ; end + def level ; end + def progname ; end + def datetime_format ; end + def formatter ; end + def sev_threshold ; end + def level=(level); end + def progname=(progname); end + def datetime_format=(datetime_format); end + def formatter=(formatter); end + def sev_threshold=(sev_threshold); end + def close ; end + def add(severity, message = nil, progname = nil, &block); end + def log(severity, message = nil, progname = nil, &block); end + def <<(msg); end + def reopen(logdev = nil); end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/query_parser.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/query_parser.rb new file mode 100644 index 00000000..3107e218 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/query_parser.rb @@ -0,0 +1,242 @@ +# frozen_string_literal: true + +require_relative 'bad_request' +require 'uri' + +module Rack + class QueryParser + DEFAULT_SEP = /& */n + COMMON_SEP = { ";" => /; */n, ";," => /[;,] */n, "&" => /& */n } + + # ParameterTypeError is the error that is raised when incoming structural + # parameters (parsed by parse_nested_query) contain conflicting types. + class ParameterTypeError < TypeError + include BadRequest + end + + # InvalidParameterError is the error that is raised when incoming structural + # parameters (parsed by parse_nested_query) contain invalid format or byte + # sequence. + class InvalidParameterError < ArgumentError + include BadRequest + end + + # QueryLimitError is for errors raised when the query provided exceeds one + # of the query parser limits. + class QueryLimitError < RangeError + include BadRequest + end + + # ParamsTooDeepError is the old name for the error that is raised when params + # are recursively nested over the specified limit. Make it the same as + # as QueryLimitError, so that code that rescues ParamsTooDeepError error + # to handle bad query strings also now handles other limits. + ParamsTooDeepError = QueryLimitError + + def self.make_default(param_depth_limit, **options) + new(Params, param_depth_limit, **options) + end + + attr_reader :param_depth_limit + + env_int = lambda do |key, val| + if str_val = ENV[key] + begin + val = Integer(str_val, 10) + rescue ArgumentError + raise ArgumentError, "non-integer value provided for environment variable #{key}" + end + end + + val + end + + BYTESIZE_LIMIT = env_int.call("RACK_QUERY_PARSER_BYTESIZE_LIMIT", 4194304) + private_constant :BYTESIZE_LIMIT + + PARAMS_LIMIT = env_int.call("RACK_QUERY_PARSER_PARAMS_LIMIT", 4096) + private_constant :PARAMS_LIMIT + + def initialize(params_class, param_depth_limit, bytesize_limit: BYTESIZE_LIMIT, params_limit: PARAMS_LIMIT) + @params_class = params_class + @param_depth_limit = param_depth_limit + @bytesize_limit = bytesize_limit + @params_limit = params_limit + end + + # Stolen from Mongrel, with some small modifications: + # Parses a query string by breaking it up at the '&'. You can also use this + # to parse cookies by changing the characters used in the second parameter + # (which defaults to '&'). + def parse_query(qs, separator = nil, &unescaper) + unescaper ||= method(:unescape) + + params = make_params + + check_query_string(qs, separator).split(separator ? (COMMON_SEP[separator] || /[#{separator}] */n) : DEFAULT_SEP).each do |p| + next if p.empty? + k, v = p.split('=', 2).map!(&unescaper) + + if cur = params[k] + if cur.class == Array + params[k] << v + else + params[k] = [cur, v] + end + else + params[k] = v + end + end + + return params.to_h + end + + # parse_nested_query expands a query string into structural types. Supported + # types are Arrays, Hashes and basic value types. It is possible to supply + # query strings with parameters of conflicting types, in this case a + # ParameterTypeError is raised. Users are encouraged to return a 400 in this + # case. + def parse_nested_query(qs, separator = nil) + params = make_params + + unless qs.nil? || qs.empty? + check_query_string(qs, separator).split(separator ? (COMMON_SEP[separator] || /[#{separator}] */n) : DEFAULT_SEP).each do |p| + k, v = p.split('=', 2).map! { |s| unescape(s) } + + _normalize_params(params, k, v, 0) + end + end + + return params.to_h + rescue ArgumentError => e + raise InvalidParameterError, e.message, e.backtrace + end + + # normalize_params recursively expands parameters into structural types. If + # the structural types represented by two different parameter names are in + # conflict, a ParameterTypeError is raised. The depth argument is deprecated + # and should no longer be used, it is kept for backwards compatibility with + # earlier versions of rack. + def normalize_params(params, name, v, _depth=nil) + _normalize_params(params, name, v, 0) + end + + private def _normalize_params(params, name, v, depth) + raise ParamsTooDeepError if depth >= param_depth_limit + + if !name + # nil name, treat same as empty string (required by tests) + k = after = '' + elsif depth == 0 + # Start of parsing, don't treat [] or [ at start of string specially + if start = name.index('[', 1) + # Start of parameter nesting, use part before brackets as key + k = name[0, start] + after = name[start, name.length] + else + # Plain parameter with no nesting + k = name + after = '' + end + elsif name.start_with?('[]') + # Array nesting + k = '[]' + after = name[2, name.length] + elsif name.start_with?('[') && (start = name.index(']', 1)) + # Hash nesting, use the part inside brackets as the key + k = name[1, start-1] + after = name[start+1, name.length] + else + # Probably malformed input, nested but not starting with [ + # treat full name as key for backwards compatibility. + k = name + after = '' + end + + return if k.empty? + + if after == '' + if k == '[]' && depth != 0 + return [v] + else + params[k] = v + end + elsif after == "[" + params[name] = v + elsif after == "[]" + params[k] ||= [] + raise ParameterTypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array) + params[k] << v + elsif after.start_with?('[]') + # Recognize x[][y] (hash inside array) parameters + unless after[2] == '[' && after.end_with?(']') && (child_key = after[3, after.length-4]) && !child_key.empty? && !child_key.index('[') && !child_key.index(']') + # Handle other nested array parameters + child_key = after[2, after.length] + end + params[k] ||= [] + raise ParameterTypeError, "expected Array (got #{params[k].class.name}) for param `#{k}'" unless params[k].is_a?(Array) + if params_hash_type?(params[k].last) && !params_hash_has_key?(params[k].last, child_key) + _normalize_params(params[k].last, child_key, v, depth + 1) + else + params[k] << _normalize_params(make_params, child_key, v, depth + 1) + end + else + params[k] ||= make_params + raise ParameterTypeError, "expected Hash (got #{params[k].class.name}) for param `#{k}'" unless params_hash_type?(params[k]) + params[k] = _normalize_params(params[k], after, v, depth + 1) + end + + params + end + + def make_params + @params_class.new + end + + def new_depth_limit(param_depth_limit) + self.class.new @params_class, param_depth_limit + end + + private + + def params_hash_type?(obj) + obj.kind_of?(@params_class) + end + + def params_hash_has_key?(hash, key) + return false if /\[\]/.match?(key) + + key.split(/[\[\]]+/).inject(hash) do |h, part| + next h if part == '' + return false unless params_hash_type?(h) && h.key?(part) + h[part] + end + + true + end + + def check_query_string(qs, sep) + if qs + if qs.bytesize > @bytesize_limit + raise QueryLimitError, "total query size (#{qs.bytesize}) exceeds limit (#{@bytesize_limit})" + end + + if (param_count = qs.count(sep.is_a?(String) ? sep : '&')) >= @params_limit + raise QueryLimitError, "total number of query parameters (#{param_count+1}) exceeds limit (#{@params_limit})" + end + + qs + else + '' + end + end + + def unescape(string, encoding = Encoding::UTF_8) + URI.decode_www_form_component(string, encoding) + end + + class Params < Hash + alias_method :to_params_hash, :to_h + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/recursive.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/recursive.rb new file mode 100644 index 00000000..0945d322 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/recursive.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +require 'uri' + +require_relative 'constants' + +module Rack + # Rack::ForwardRequest gets caught by Rack::Recursive and redirects + # the current request to the app at +url+. + # + # raise ForwardRequest.new("/not-found") + # + + class ForwardRequest < Exception + attr_reader :url, :env + + def initialize(url, env = {}) + @url = URI(url) + @env = env + + @env[PATH_INFO] = @url.path + @env[QUERY_STRING] = @url.query if @url.query + @env[HTTP_HOST] = @url.host if @url.host + @env[HTTP_PORT] = @url.port if @url.port + @env[RACK_URL_SCHEME] = @url.scheme if @url.scheme + + super "forwarding to #{url}" + end + end + + # Rack::Recursive allows applications called down the chain to + # include data from other applications (by using + # rack['rack.recursive.include'][...] or raise a + # ForwardRequest to redirect internally. + + class Recursive + def initialize(app) + @app = app + end + + def call(env) + dup._call(env) + end + + def _call(env) + @script_name = env[SCRIPT_NAME] + @app.call(env.merge(RACK_RECURSIVE_INCLUDE => method(:include))) + rescue ForwardRequest => req + call(env.merge(req.env)) + end + + def include(env, path) + unless path.index(@script_name) == 0 && (path[@script_name.size] == ?/ || + path[@script_name.size].nil?) + raise ArgumentError, "can only include below #{@script_name}, not #{path}" + end + + env = env.merge(PATH_INFO => path, + SCRIPT_NAME => @script_name, + REQUEST_METHOD => GET, + "CONTENT_LENGTH" => "0", "CONTENT_TYPE" => "", + RACK_INPUT => StringIO.new("")) + @app.call(env) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/reloader.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/reloader.rb new file mode 100644 index 00000000..a15064ac --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/reloader.rb @@ -0,0 +1,112 @@ +# frozen_string_literal: true + +# Copyright (C) 2009-2018 Michael Fellinger +# Rack::Reloader is subject to the terms of an MIT-style license. +# See MIT-LICENSE or https://opensource.org/licenses/MIT. + +require 'pathname' + +module Rack + + # High performant source reloader + # + # This class acts as Rack middleware. + # + # What makes it especially suited for use in a production environment is that + # any file will only be checked once and there will only be made one system + # call stat(2). + # + # Please note that this will not reload files in the background, it does so + # only when actively called. + # + # It is performing a check/reload cycle at the start of every request, but + # also respects a cool down time, during which nothing will be done. + class Reloader + def initialize(app, cooldown = 10, backend = Stat) + @app = app + @cooldown = cooldown + @last = (Time.now - cooldown) + @cache = {} + @mtimes = {} + @reload_mutex = Mutex.new + + extend backend + end + + def call(env) + if @cooldown and Time.now > @last + @cooldown + if Thread.list.size > 1 + @reload_mutex.synchronize{ reload! } + else + reload! + end + + @last = Time.now + end + + @app.call(env) + end + + def reload!(stderr = $stderr) + rotation do |file, mtime| + previous_mtime = @mtimes[file] ||= mtime + safe_load(file, mtime, stderr) if mtime > previous_mtime + end + end + + # A safe Kernel::load, issuing the hooks depending on the results + def safe_load(file, mtime, stderr = $stderr) + load(file) + stderr.puts "#{self.class}: reloaded `#{file}'" + file + rescue LoadError, SyntaxError => ex + stderr.puts ex + ensure + @mtimes[file] = mtime + end + + module Stat + def rotation + files = [$0, *$LOADED_FEATURES].uniq + paths = ['./', *$LOAD_PATH].uniq + + files.map{|file| + next if /\.(so|bundle)$/.match?(file) # cannot reload compiled files + + found, stat = figure_path(file, paths) + next unless found && stat && mtime = stat.mtime + + @cache[file] = found + + yield(found, mtime) + }.compact + end + + # Takes a relative or absolute +file+ name, a couple possible +paths+ that + # the +file+ might reside in. Returns the full path and File::Stat for the + # path. + def figure_path(file, paths) + found = @cache[file] + found = file if !found and Pathname.new(file).absolute? + found, stat = safe_stat(found) + return found, stat if found + + paths.find do |possible_path| + path = ::File.join(possible_path, file) + found, stat = safe_stat(path) + return ::File.expand_path(found), stat if found + end + + return false, false + end + + def safe_stat(file) + return unless file + stat = ::File.stat(file) + return file, stat if stat.file? + rescue Errno::ENOENT, Errno::ENOTDIR, Errno::ESRCH + @cache.delete(file) and false + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/request.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/request.rb new file mode 100644 index 00000000..93526a09 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/request.rb @@ -0,0 +1,796 @@ +# frozen_string_literal: true + +require_relative 'constants' +require_relative 'utils' +require_relative 'media_type' + +module Rack + # Rack::Request provides a convenient interface to a Rack + # environment. It is stateless, the environment +env+ passed to the + # constructor will be directly modified. + # + # req = Rack::Request.new(env) + # req.post? + # req.params["data"] + + class Request + class << self + attr_accessor :ip_filter + + # The priority when checking forwarded headers. The default + # is [:forwarded, :x_forwarded], which means, check the + # +Forwarded+ header first, followed by the appropriate + # X-Forwarded-* header. You can revert the priority by + # reversing the priority, or remove checking of either + # or both headers by removing elements from the array. + # + # This should be set as appropriate in your environment + # based on what reverse proxies are in use. If you are not + # using reverse proxies, you should probably use an empty + # array. + attr_accessor :forwarded_priority + + # The priority when checking either the X-Forwarded-Proto + # or X-Forwarded-Scheme header for the forwarded protocol. + # The default is [:proto, :scheme], to try the + # X-Forwarded-Proto header before the + # X-Forwarded-Scheme header. Rack 2 had behavior + # similar to [:scheme, :proto]. You can remove either or + # both of the entries in array to ignore that respective header. + attr_accessor :x_forwarded_proto_priority + end + + @forwarded_priority = [:forwarded, :x_forwarded] + @x_forwarded_proto_priority = [:proto, :scheme] + + valid_ipv4_octet = /\.(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])/ + + trusted_proxies = Regexp.union( + /\A127#{valid_ipv4_octet}{3}\z/, # localhost IPv4 range 127.x.x.x, per RFC-3330 + /\A::1\z/, # localhost IPv6 ::1 + /\Af[cd][0-9a-f]{2}(?::[0-9a-f]{0,4}){0,7}\z/i, # private IPv6 range fc00 .. fdff + /\A10#{valid_ipv4_octet}{3}\z/, # private IPv4 range 10.x.x.x + /\A172\.(1[6-9]|2[0-9]|3[01])#{valid_ipv4_octet}{2}\z/, # private IPv4 range 172.16.0.0 .. 172.31.255.255 + /\A192\.168#{valid_ipv4_octet}{2}\z/, # private IPv4 range 192.168.x.x + /\Alocalhost\z|\Aunix(\z|:)/i, # localhost hostname, and unix domain sockets + ) + + self.ip_filter = lambda { |ip| trusted_proxies.match?(ip) } + + ALLOWED_SCHEMES = %w(https http wss ws).freeze + + def initialize(env) + @env = env + @params = nil + end + + def params + @params ||= super + end + + def update_param(k, v) + super + @params = nil + end + + def delete_param(k) + v = super + @params = nil + v + end + + module Env + # The environment of the request. + attr_reader :env + + def initialize(env) + @env = env + # This module is included at least in `ActionDispatch::Request` + # The call to `super()` allows additional mixed-in initializers are called + super() + end + + # Predicate method to test to see if `name` has been set as request + # specific data + def has_header?(name) + @env.key? name + end + + # Get a request specific value for `name`. + def get_header(name) + @env[name] + end + + # If a block is given, it yields to the block if the value hasn't been set + # on the request. + def fetch_header(name, &block) + @env.fetch(name, &block) + end + + # Loops through each key / value pair in the request specific data. + def each_header(&block) + @env.each(&block) + end + + # Set a request specific value for `name` to `v` + def set_header(name, v) + @env[name] = v + end + + # Add a header that may have multiple values. + # + # Example: + # request.add_header 'Accept', 'image/png' + # request.add_header 'Accept', '*/*' + # + # assert_equal 'image/png,*/*', request.get_header('Accept') + # + # http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 + def add_header(key, v) + if v.nil? + get_header key + elsif has_header? key + set_header key, "#{get_header key},#{v}" + else + set_header key, v + end + end + + # Delete a request specific value for `name`. + def delete_header(name) + @env.delete name + end + + def initialize_copy(other) + @env = other.env.dup + end + end + + module Helpers + # The set of form-data media-types. Requests that do not indicate + # one of the media types present in this list will not be eligible + # for form-data / param parsing. + FORM_DATA_MEDIA_TYPES = [ + 'application/x-www-form-urlencoded', + 'multipart/form-data' + ] + + # The set of media-types. Requests that do not indicate + # one of the media types present in this list will not be eligible + # for param parsing like soap attachments or generic multiparts + PARSEABLE_DATA_MEDIA_TYPES = [ + 'multipart/related', + 'multipart/mixed' + ] + + # Default ports depending on scheme. Used to decide whether or not + # to include the port in a generated URI. + DEFAULT_PORTS = { 'http' => 80, 'https' => 443, 'coffee' => 80 } + + # The address of the client which connected to the proxy. + HTTP_X_FORWARDED_FOR = 'HTTP_X_FORWARDED_FOR' + + # The contents of the host/:authority header sent to the proxy. + HTTP_X_FORWARDED_HOST = 'HTTP_X_FORWARDED_HOST' + + HTTP_FORWARDED = 'HTTP_FORWARDED' + + # The value of the scheme sent to the proxy. + HTTP_X_FORWARDED_SCHEME = 'HTTP_X_FORWARDED_SCHEME' + + # The protocol used to connect to the proxy. + HTTP_X_FORWARDED_PROTO = 'HTTP_X_FORWARDED_PROTO' + + # The port used to connect to the proxy. + HTTP_X_FORWARDED_PORT = 'HTTP_X_FORWARDED_PORT' + + # Another way for specifying https scheme was used. + HTTP_X_FORWARDED_SSL = 'HTTP_X_FORWARDED_SSL' + + def body; get_header(RACK_INPUT) end + def script_name; get_header(SCRIPT_NAME).to_s end + def script_name=(s); set_header(SCRIPT_NAME, s.to_s) end + + def path_info; get_header(PATH_INFO).to_s end + def path_info=(s); set_header(PATH_INFO, s.to_s) end + + def request_method; get_header(REQUEST_METHOD) end + def query_string; get_header(QUERY_STRING).to_s end + def content_length; get_header('CONTENT_LENGTH') end + def logger; get_header(RACK_LOGGER) end + def user_agent; get_header('HTTP_USER_AGENT') end + + # the referer of the client + def referer; get_header('HTTP_REFERER') end + alias referrer referer + + def session + fetch_header(RACK_SESSION) do |k| + set_header RACK_SESSION, default_session + end + end + + def session_options + fetch_header(RACK_SESSION_OPTIONS) do |k| + set_header RACK_SESSION_OPTIONS, {} + end + end + + # Checks the HTTP request method (or verb) to see if it was of type DELETE + def delete?; request_method == DELETE end + + # Checks the HTTP request method (or verb) to see if it was of type GET + def get?; request_method == GET end + + # Checks the HTTP request method (or verb) to see if it was of type HEAD + def head?; request_method == HEAD end + + # Checks the HTTP request method (or verb) to see if it was of type OPTIONS + def options?; request_method == OPTIONS end + + # Checks the HTTP request method (or verb) to see if it was of type LINK + def link?; request_method == LINK end + + # Checks the HTTP request method (or verb) to see if it was of type PATCH + def patch?; request_method == PATCH end + + # Checks the HTTP request method (or verb) to see if it was of type POST + def post?; request_method == POST end + + # Checks the HTTP request method (or verb) to see if it was of type PUT + def put?; request_method == PUT end + + # Checks the HTTP request method (or verb) to see if it was of type TRACE + def trace?; request_method == TRACE end + + # Checks the HTTP request method (or verb) to see if it was of type UNLINK + def unlink?; request_method == UNLINK end + + def scheme + if get_header(HTTPS) == 'on' + 'https' + elsif get_header(HTTP_X_FORWARDED_SSL) == 'on' + 'https' + elsif forwarded_scheme + forwarded_scheme + else + get_header(RACK_URL_SCHEME) + end + end + + # The authority of the incoming request as defined by RFC3976. + # https://tools.ietf.org/html/rfc3986#section-3.2 + # + # In HTTP/1, this is the `host` header. + # In HTTP/2, this is the `:authority` pseudo-header. + def authority + forwarded_authority || host_authority || server_authority + end + + # The authority as defined by the `SERVER_NAME` and `SERVER_PORT` + # variables. + def server_authority + host = self.server_name + port = self.server_port + + if host + if port + "#{host}:#{port}" + else + host + end + end + end + + def server_name + get_header(SERVER_NAME) + end + + def server_port + get_header(SERVER_PORT) + end + + def cookies + hash = fetch_header(RACK_REQUEST_COOKIE_HASH) do |key| + set_header(key, {}) + end + + string = get_header(HTTP_COOKIE) + + unless string == get_header(RACK_REQUEST_COOKIE_STRING) + hash.replace Utils.parse_cookies_header(string) + set_header(RACK_REQUEST_COOKIE_STRING, string) + end + + hash + end + + def content_type + content_type = get_header('CONTENT_TYPE') + content_type.nil? || content_type.empty? ? nil : content_type + end + + def xhr? + get_header("HTTP_X_REQUESTED_WITH") == "XMLHttpRequest" + end + + # The `HTTP_HOST` header. + def host_authority + get_header(HTTP_HOST) + end + + def host_with_port(authority = self.authority) + host, _, port = split_authority(authority) + + if port == DEFAULT_PORTS[self.scheme] + host + else + authority + end + end + + # Returns a formatted host, suitable for being used in a URI. + def host + split_authority(self.authority)[0] + end + + # Returns an address suitable for being to resolve to an address. + # In the case of a domain name or IPv4 address, the result is the same + # as +host+. In the case of IPv6 or future address formats, the square + # brackets are removed. + def hostname + split_authority(self.authority)[1] + end + + def port + if authority = self.authority + _, _, port = split_authority(authority) + end + + port || forwarded_port&.last || DEFAULT_PORTS[scheme] || server_port + end + + def forwarded_for + forwarded_priority.each do |type| + case type + when :forwarded + if forwarded_for = get_http_forwarded(:for) + return(forwarded_for.map! do |authority| + split_authority(authority)[1] + end) + end + when :x_forwarded + if value = get_header(HTTP_X_FORWARDED_FOR) + return(split_header(value).map do |authority| + split_authority(wrap_ipv6(authority))[1] + end) + end + end + end + + nil + end + + def forwarded_port + forwarded_priority.each do |type| + case type + when :forwarded + if forwarded = get_http_forwarded(:for) + return(forwarded.map do |authority| + split_authority(authority)[2] + end.compact) + end + when :x_forwarded + if value = get_header(HTTP_X_FORWARDED_PORT) + return split_header(value).map(&:to_i) + end + end + end + + nil + end + + def forwarded_authority + forwarded_priority.each do |type| + case type + when :forwarded + if forwarded = get_http_forwarded(:host) + return forwarded.last + end + when :x_forwarded + if value = get_header(HTTP_X_FORWARDED_HOST) + return wrap_ipv6(split_header(value).last) + end + end + end + + nil + end + + def ssl? + scheme == 'https' || scheme == 'wss' + end + + def ip + remote_addresses = split_header(get_header('REMOTE_ADDR')) + external_addresses = reject_trusted_ip_addresses(remote_addresses) + + unless external_addresses.empty? + return external_addresses.last + end + + if (forwarded_for = self.forwarded_for) && !forwarded_for.empty? + # The forwarded for addresses are ordered: client, proxy1, proxy2. + # So we reject all the trusted addresses (proxy*) and return the + # last client. Or if we trust everyone, we just return the first + # address. + return reject_trusted_ip_addresses(forwarded_for).last || forwarded_for.first + end + + # If all the addresses are trusted, and we aren't forwarded, just return + # the first remote address, which represents the source of the request. + remote_addresses.first + end + + # The media type (type/subtype) portion of the CONTENT_TYPE header + # without any media type parameters. e.g., when CONTENT_TYPE is + # "text/plain;charset=utf-8", the media-type is "text/plain". + # + # For more information on the use of media types in HTTP, see: + # http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7 + def media_type + MediaType.type(content_type) + end + + # The media type parameters provided in CONTENT_TYPE as a Hash, or + # an empty Hash if no CONTENT_TYPE or media-type parameters were + # provided. e.g., when the CONTENT_TYPE is "text/plain;charset=utf-8", + # this method responds with the following Hash: + # { 'charset' => 'utf-8' } + def media_type_params + MediaType.params(content_type) + end + + # The character set of the request body if a "charset" media type + # parameter was given, or nil if no "charset" was specified. Note + # that, per RFC2616, text/* media types that specify no explicit + # charset are to be considered ISO-8859-1. + def content_charset + media_type_params['charset'] + end + + # Determine whether the request body contains form-data by checking + # the request content-type for one of the media-types: + # "application/x-www-form-urlencoded" or "multipart/form-data". The + # list of form-data media types can be modified through the + # +FORM_DATA_MEDIA_TYPES+ array. + # + # A request body is also assumed to contain form-data when no + # content-type header is provided and the request_method is POST. + def form_data? + type = media_type + meth = get_header(RACK_METHODOVERRIDE_ORIGINAL_METHOD) || get_header(REQUEST_METHOD) + + (meth == POST && type.nil?) || FORM_DATA_MEDIA_TYPES.include?(type) + end + + # Determine whether the request body contains data by checking + # the request media_type against registered parse-data media-types + def parseable_data? + PARSEABLE_DATA_MEDIA_TYPES.include?(media_type) + end + + # Returns the data received in the query string. + def GET + rr_query_string = get_header(RACK_REQUEST_QUERY_STRING) + query_string = self.query_string + if rr_query_string == query_string + get_header(RACK_REQUEST_QUERY_HASH) + else + if rr_query_string + warn "query string used for GET parsing different from current query string. Starting in Rack 3.2, Rack will used the cached GET value instead of parsing the current query string.", uplevel: 1 + end + query_hash = parse_query(query_string, '&') + set_header(RACK_REQUEST_QUERY_STRING, query_string) + set_header(RACK_REQUEST_QUERY_HASH, query_hash) + end + end + + # Returns the data received in the request body. + # + # This method support both application/x-www-form-urlencoded and + # multipart/form-data. + def POST + if error = get_header(RACK_REQUEST_FORM_ERROR) + raise error.class, error.message, cause: error.cause + end + + begin + rack_input = get_header(RACK_INPUT) + + # If the form hash was already memoized: + if form_hash = get_header(RACK_REQUEST_FORM_HASH) + form_input = get_header(RACK_REQUEST_FORM_INPUT) + # And it was memoized from the same input: + if form_input.equal?(rack_input) + return form_hash + elsif form_input + warn "input stream used for POST parsing different from current input stream. Starting in Rack 3.2, Rack will used the cached POST value instead of parsing the current input stream.", uplevel: 1 + end + end + + # Otherwise, figure out how to parse the input: + if rack_input.nil? + set_header RACK_REQUEST_FORM_INPUT, nil + set_header(RACK_REQUEST_FORM_HASH, {}) + elsif form_data? || parseable_data? + if pairs = Rack::Multipart.parse_multipart(env, Rack::Multipart::ParamList) + set_header RACK_REQUEST_FORM_PAIRS, pairs + set_header RACK_REQUEST_FORM_HASH, expand_param_pairs(pairs) + else + form_vars = get_header(RACK_INPUT).read + + # Fix for Safari Ajax postings that always append \0 + # form_vars.sub!(/\0\z/, '') # performance replacement: + form_vars.slice!(-1) if form_vars.end_with?("\0") + + set_header RACK_REQUEST_FORM_VARS, form_vars + set_header RACK_REQUEST_FORM_HASH, parse_query(form_vars, '&') + end + + set_header RACK_REQUEST_FORM_INPUT, get_header(RACK_INPUT) + get_header RACK_REQUEST_FORM_HASH + else + set_header RACK_REQUEST_FORM_INPUT, get_header(RACK_INPUT) + set_header(RACK_REQUEST_FORM_HASH, {}) + end + rescue => error + set_header(RACK_REQUEST_FORM_ERROR, error) + raise + end + end + + # The union of GET and POST data. + # + # Note that modifications will not be persisted in the env. Use update_param or delete_param if you want to destructively modify params. + def params + self.GET.merge(self.POST) + end + + # Destructively update a parameter, whether it's in GET and/or POST. Returns nil. + # + # The parameter is updated wherever it was previous defined, so GET, POST, or both. If it wasn't previously defined, it's inserted into GET. + # + # env['rack.input'] is not touched. + def update_param(k, v) + found = false + if self.GET.has_key?(k) + found = true + self.GET[k] = v + end + if self.POST.has_key?(k) + found = true + self.POST[k] = v + end + unless found + self.GET[k] = v + end + end + + # Destructively delete a parameter, whether it's in GET or POST. Returns the value of the deleted parameter. + # + # If the parameter is in both GET and POST, the POST value takes precedence since that's how #params works. + # + # env['rack.input'] is not touched. + def delete_param(k) + post_value, get_value = self.POST.delete(k), self.GET.delete(k) + post_value || get_value + end + + def base_url + "#{scheme}://#{host_with_port}" + end + + # Tries to return a remake of the original request URL as a string. + def url + base_url + fullpath + end + + def path + script_name + path_info + end + + def fullpath + query_string.empty? ? path : "#{path}?#{query_string}" + end + + def accept_encoding + parse_http_accept_header(get_header("HTTP_ACCEPT_ENCODING")) + end + + def accept_language + parse_http_accept_header(get_header("HTTP_ACCEPT_LANGUAGE")) + end + + def trusted_proxy?(ip) + Rack::Request.ip_filter.call(ip) + end + + # like Hash#values_at + def values_at(*keys) + warn("Request#values_at is deprecated and will be removed in a future version of Rack. Please use request.params.values_at instead", uplevel: 1) + + keys.map { |key| params[key] } + end + + private + + def default_session; {}; end + + # Assist with compatibility when processing `X-Forwarded-For`. + def wrap_ipv6(host) + # Even thought IPv6 addresses should be wrapped in square brackets, + # sometimes this is not done in various legacy/underspecified headers. + # So we try to fix this situation for compatibility reasons. + + # Try to detect IPv6 addresses which aren't escaped yet: + if !host.start_with?('[') && host.count(':') > 1 + "[#{host}]" + else + host + end + end + + def parse_http_accept_header(header) + # It would be nice to use filter_map here, but it's Ruby 2.7+ + parts = header.to_s.split(',') + + parts.map! do |part| + part.strip! + next if part.empty? + + attribute, parameters = part.split(';', 2) + attribute.strip! + parameters&.strip! + quality = 1.0 + if parameters and /\Aq=([\d.]+)/ =~ parameters + quality = $1.to_f + end + [attribute, quality] + end + + parts.compact! + + parts + end + + # Get an array of values set in the RFC 7239 `Forwarded` request header. + def get_http_forwarded(token) + Utils.forwarded_values(get_header(HTTP_FORWARDED))&.[](token) + end + + def query_parser + Utils.default_query_parser + end + + def parse_query(qs, d = '&') + query_parser.parse_nested_query(qs, d) + end + + def parse_multipart + Rack::Multipart.extract_multipart(self, query_parser) + end + + def expand_param_pairs(pairs, query_parser = query_parser()) + params = query_parser.make_params + + pairs.each do |k, v| + query_parser.normalize_params(params, k, v) + end + + params.to_params_hash + end + + def split_header(value) + value ? value.strip.split(/[,\s]+/) : [] + end + + # ipv6 extracted from resolv stdlib, simplified + # to remove numbered match group creation. + ipv6 = Regexp.union( + /(?:[0-9A-Fa-f]{1,4}:){7} + [0-9A-Fa-f]{1,4}/x, + /(?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)? :: + (?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)?/x, + /(?:[0-9A-Fa-f]{1,4}:){6,6} + \d+\.\d+\.\d+\.\d+/x, + /(?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)? :: + (?:[0-9A-Fa-f]{1,4}:)* + \d+\.\d+\.\d+\.\d+/x, + /[Ff][Ee]80 + (?::[0-9A-Fa-f]{1,4}){7} + %[-0-9A-Za-z._~]+/x, + /[Ff][Ee]80: + (?: + (?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)? :: + (?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)? + | + :(?:[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4})*)? + )? + :[0-9A-Fa-f]{1,4}%[-0-9A-Za-z._~]+/x) + + AUTHORITY = / + \A + (? + # Match IPv6 as a string of hex digits and colons in square brackets + \[(?
#{ipv6})\] + | + # Match any other printable string (except square brackets) as a hostname + (?
[[[:graph:]&&[^\[\]]]]*?) + ) + (:(?\d+))? + \z + /x + + private_constant :AUTHORITY + + def split_authority(authority) + return [] if authority.nil? + return [] unless match = AUTHORITY.match(authority) + return match[:host], match[:address], match[:port]&.to_i + end + + def reject_trusted_ip_addresses(ip_addresses) + ip_addresses.reject { |ip| trusted_proxy?(ip) } + end + + FORWARDED_SCHEME_HEADERS = { + proto: HTTP_X_FORWARDED_PROTO, + scheme: HTTP_X_FORWARDED_SCHEME + }.freeze + private_constant :FORWARDED_SCHEME_HEADERS + def forwarded_scheme + forwarded_priority.each do |type| + case type + when :forwarded + if (forwarded_proto = get_http_forwarded(:proto)) && + (scheme = allowed_scheme(forwarded_proto.last)) + return scheme + end + when :x_forwarded + x_forwarded_proto_priority.each do |x_type| + if header = FORWARDED_SCHEME_HEADERS[x_type] + split_header(get_header(header)).reverse_each do |scheme| + if allowed_scheme(scheme) + return scheme + end + end + end + end + end + end + + nil + end + + def allowed_scheme(header) + header if ALLOWED_SCHEMES.include?(header) + end + + def forwarded_priority + Request.forwarded_priority + end + + def x_forwarded_proto_priority + Request.x_forwarded_proto_priority + end + end + + include Env + include Helpers + end +end + +# :nocov: +require_relative 'multipart' unless defined?(Rack::Multipart) +# :nocov: diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/response.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/response.rb new file mode 100644 index 00000000..ece451db --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/response.rb @@ -0,0 +1,403 @@ +# frozen_string_literal: true + +require 'time' + +require_relative 'constants' +require_relative 'utils' +require_relative 'media_type' +require_relative 'headers' + +module Rack + # Rack::Response provides a convenient interface to create a Rack + # response. + # + # It allows setting of headers and cookies, and provides useful + # defaults (an OK response with empty headers and body). + # + # You can use Response#write to iteratively generate your response, + # but note that this is buffered by Rack::Response until you call + # +finish+. +finish+ however can take a block inside which calls to + # +write+ are synchronous with the Rack response. + # + # Your application's +call+ should end returning Response#finish. + class Response + def self.[](status, headers, body) + self.new(body, status, headers) + end + + CHUNKED = 'chunked' + STATUS_WITH_NO_ENTITY_BODY = Utils::STATUS_WITH_NO_ENTITY_BODY + + attr_accessor :length, :status, :body + attr_reader :headers + + # Initialize the response object with the specified +body+, +status+ + # and +headers+. + # + # If the +body+ is +nil+, construct an empty response object with internal + # buffering. + # + # If the +body+ responds to +to_str+, assume it's a string-like object and + # construct a buffered response object containing using that string as the + # initial contents of the buffer. + # + # Otherwise it is expected +body+ conforms to the normal requirements of a + # Rack response body, typically implementing one of +each+ (enumerable + # body) or +call+ (streaming body). + # + # The +status+ defaults to +200+ which is the "OK" HTTP status code. You + # can provide any other valid status code. + # + # The +headers+ must be a +Hash+ of key-value header pairs which conform to + # the Rack specification for response headers. The key must be a +String+ + # instance and the value can be either a +String+ or +Array+ instance. + def initialize(body = nil, status = 200, headers = {}) + @status = status.to_i + + unless headers.is_a?(Hash) + raise ArgumentError, "Headers must be a Hash!" + end + + @headers = Headers.new + # Convert headers input to a plain hash with lowercase keys. + headers.each do |k, v| + @headers[k] = v + end + + @writer = self.method(:append) + + @block = nil + + # Keep track of whether we have expanded the user supplied body. + if body.nil? + @body = [] + @buffered = true + # Body is unspecified - it may be a buffered response, or it may be a HEAD response. + @length = nil + elsif body.respond_to?(:to_str) + @body = [body] + @buffered = true + @length = body.to_str.bytesize + else + @body = body + @buffered = nil # undetermined as of yet. + @length = nil + end + + yield self if block_given? + end + + def redirect(target, status = 302) + self.status = status + self.location = target + end + + def chunked? + CHUNKED == get_header(TRANSFER_ENCODING) + end + + def no_entity_body? + # The response body is an enumerable body and it is not allowed to have an entity body. + @body.respond_to?(:each) && STATUS_WITH_NO_ENTITY_BODY[@status] + end + + # Generate a response array consistent with the requirements of the SPEC. + # @return [Array] a 3-tuple suitable of `[status, headers, body]` + # which is suitable to be returned from the middleware `#call(env)` method. + def finish(&block) + if no_entity_body? + delete_header CONTENT_TYPE + delete_header CONTENT_LENGTH + close + return [@status, @headers, []] + else + if block_given? + # We don't add the content-length here as the user has provided a block that can #write additional chunks to the body. + @block = block + return [@status, @headers, self] + else + # If we know the length of the body, set the content-length header... except if we are chunked? which is a legacy special case where the body might already be encoded and thus the actual encoded body length and the content-length are likely to be different. + if @length && !chunked? + @headers[CONTENT_LENGTH] = @length.to_s + end + return [@status, @headers, @body] + end + end + end + + alias to_a finish # For *response + + def each(&callback) + @body.each(&callback) + @buffered = true + + if @block + @writer = callback + @block.call(self) + end + end + + # Append a chunk to the response body. + # + # Converts the response into a buffered response if it wasn't already. + # + # NOTE: Do not mix #write and direct #body access! + # + def write(chunk) + buffered_body! + + @writer.call(chunk.to_s) + end + + def close + @body.close if @body.respond_to?(:close) + end + + def empty? + @block == nil && @body.empty? + end + + def has_header?(key) + raise ArgumentError unless key.is_a?(String) + @headers.key?(key) + end + def get_header(key) + raise ArgumentError unless key.is_a?(String) + @headers[key] + end + def set_header(key, value) + raise ArgumentError unless key.is_a?(String) + @headers[key] = value + end + def delete_header(key) + raise ArgumentError unless key.is_a?(String) + @headers.delete key + end + + alias :[] :get_header + alias :[]= :set_header + + module Helpers + def invalid?; status < 100 || status >= 600; end + + def informational?; status >= 100 && status < 200; end + def successful?; status >= 200 && status < 300; end + def redirection?; status >= 300 && status < 400; end + def client_error?; status >= 400 && status < 500; end + def server_error?; status >= 500 && status < 600; end + + def ok?; status == 200; end + def created?; status == 201; end + def accepted?; status == 202; end + def no_content?; status == 204; end + def moved_permanently?; status == 301; end + def bad_request?; status == 400; end + def unauthorized?; status == 401; end + def forbidden?; status == 403; end + def not_found?; status == 404; end + def method_not_allowed?; status == 405; end + def not_acceptable?; status == 406; end + def request_timeout?; status == 408; end + def precondition_failed?; status == 412; end + def unprocessable?; status == 422; end + + def redirect?; [301, 302, 303, 307, 308].include? status; end + + def include?(header) + has_header?(header) + end + + # Add a header that may have multiple values. + # + # Example: + # response.add_header 'vary', 'accept-encoding' + # response.add_header 'vary', 'cookie' + # + # assert_equal 'accept-encoding,cookie', response.get_header('vary') + # + # http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 + def add_header(key, value) + raise ArgumentError unless key.is_a?(String) + + if value.nil? + return get_header(key) + end + + value = value.to_s + + if header = get_header(key) + if header.is_a?(Array) + header << value + else + set_header(key, [header, value]) + end + else + set_header(key, value) + end + end + + # Get the content type of the response. + def content_type + get_header CONTENT_TYPE + end + + # Set the content type of the response. + def content_type=(content_type) + set_header CONTENT_TYPE, content_type + end + + def media_type + MediaType.type(content_type) + end + + def media_type_params + MediaType.params(content_type) + end + + def content_length + cl = get_header CONTENT_LENGTH + cl ? cl.to_i : cl + end + + def location + get_header "location" + end + + def location=(location) + set_header "location", location + end + + def set_cookie(key, value) + add_header SET_COOKIE, Utils.set_cookie_header(key, value) + end + + def delete_cookie(key, value = {}) + set_header(SET_COOKIE, + Utils.delete_set_cookie_header!( + get_header(SET_COOKIE), key, value + ) + ) + end + + def set_cookie_header + get_header SET_COOKIE + end + + def set_cookie_header=(value) + set_header SET_COOKIE, value + end + + def cache_control + get_header CACHE_CONTROL + end + + def cache_control=(value) + set_header CACHE_CONTROL, value + end + + # Specifies that the content shouldn't be cached. Overrides `cache!` if already called. + def do_not_cache! + set_header CACHE_CONTROL, "no-cache, must-revalidate" + set_header EXPIRES, Time.now.httpdate + end + + # Specify that the content should be cached. + # @param duration [Integer] The number of seconds until the cache expires. + # @option directive [String] The cache control directive, one of "public", "private", "no-cache" or "no-store". + def cache!(duration = 3600, directive: "public") + unless headers[CACHE_CONTROL] =~ /no-cache/ + set_header CACHE_CONTROL, "#{directive}, max-age=#{duration}" + set_header EXPIRES, (Time.now + duration).httpdate + end + end + + def etag + get_header ETAG + end + + def etag=(value) + set_header ETAG, value + end + + protected + + # Convert the body of this response into an internally buffered Array if possible. + # + # `@buffered` is a ternary value which indicates whether the body is buffered. It can be: + # * `nil` - The body has not been buffered yet. + # * `true` - The body is buffered as an Array instance. + # * `false` - The body is not buffered and cannot be buffered. + # + # @return [Boolean] whether the body is buffered as an Array instance. + def buffered_body! + if @buffered.nil? + if @body.is_a?(Array) + # The user supplied body was an array: + @body = @body.compact + @length = @body.sum{|part| part.bytesize} + @buffered = true + elsif @body.respond_to?(:each) + # Turn the user supplied body into a buffered array: + body = @body + @body = Array.new + @buffered = true + + body.each do |part| + @writer.call(part.to_s) + end + + body.close if body.respond_to?(:close) + else + # We don't know how to buffer the user-supplied body: + @buffered = false + end + end + + return @buffered + end + + def append(chunk) + chunk = chunk.dup unless chunk.frozen? + @body << chunk + + if @length + @length += chunk.bytesize + elsif @buffered + @length = chunk.bytesize + end + + return chunk + end + end + + include Helpers + + class Raw + include Helpers + + attr_reader :headers + attr_accessor :status + + def initialize(status, headers) + @status = status + @headers = headers + end + + def has_header?(key) + headers.key?(key) + end + + def get_header(key) + headers[key] + end + + def set_header(key, value) + headers[key] = value + end + + def delete_header(key) + headers.delete(key) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/rewindable_input.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/rewindable_input.rb new file mode 100644 index 00000000..730c6a28 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/rewindable_input.rb @@ -0,0 +1,113 @@ +# -*- encoding: binary -*- +# frozen_string_literal: true + +require 'tempfile' + +require_relative 'constants' + +module Rack + # Class which can make any IO object rewindable, including non-rewindable ones. It does + # this by buffering the data into a tempfile, which is rewindable. + # + # Don't forget to call #close when you're done. This frees up temporary resources that + # RewindableInput uses, though it does *not* close the original IO object. + class RewindableInput + # Makes rack.input rewindable, for compatibility with applications and middleware + # designed for earlier versions of Rack (where rack.input was required to be + # rewindable). + class Middleware + def initialize(app) + @app = app + end + + def call(env) + env[RACK_INPUT] = RewindableInput.new(env[RACK_INPUT]) + @app.call(env) + end + end + + def initialize(io) + @io = io + @rewindable_io = nil + @unlinked = false + end + + def gets + make_rewindable unless @rewindable_io + @rewindable_io.gets + end + + def read(*args) + make_rewindable unless @rewindable_io + @rewindable_io.read(*args) + end + + def each(&block) + make_rewindable unless @rewindable_io + @rewindable_io.each(&block) + end + + def rewind + make_rewindable unless @rewindable_io + @rewindable_io.rewind + end + + def size + make_rewindable unless @rewindable_io + @rewindable_io.size + end + + # Closes this RewindableInput object without closing the originally + # wrapped IO object. Cleans up any temporary resources that this RewindableInput + # has created. + # + # This method may be called multiple times. It does nothing on subsequent calls. + def close + if @rewindable_io + if @unlinked + @rewindable_io.close + else + @rewindable_io.close! + end + @rewindable_io = nil + end + end + + private + + def make_rewindable + # Buffer all data into a tempfile. Since this tempfile is private to this + # RewindableInput object, we chmod it so that nobody else can read or write + # it. On POSIX filesystems we also unlink the file so that it doesn't + # even have a file entry on the filesystem anymore, though we can still + # access it because we have the file handle open. + @rewindable_io = Tempfile.new('RackRewindableInput') + @rewindable_io.chmod(0000) + @rewindable_io.set_encoding(Encoding::BINARY) + @rewindable_io.binmode + # :nocov: + if filesystem_has_posix_semantics? + raise 'Unlink failed. IO closed.' if @rewindable_io.closed? + @unlinked = true + end + # :nocov: + + buffer = "".dup + while @io.read(1024 * 4, buffer) + entire_buffer_written_out = false + while !entire_buffer_written_out + written = @rewindable_io.write(buffer) + entire_buffer_written_out = written == buffer.bytesize + if !entire_buffer_written_out + buffer.slice!(0 .. written - 1) + end + end + end + @rewindable_io.rewind + end + + def filesystem_has_posix_semantics? + RUBY_PLATFORM !~ /(mswin|mingw|cygwin|java)/ + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/runtime.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/runtime.rb new file mode 100644 index 00000000..a1bfa696 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/runtime.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require_relative 'utils' + +module Rack + # Sets an "x-runtime" response header, indicating the response + # time of the request, in seconds + # + # You can put it right before the application to see the processing + # time, or before all the other middlewares to include time for them, + # too. + class Runtime + FORMAT_STRING = "%0.6f" # :nodoc: + HEADER_NAME = "x-runtime" # :nodoc: + + def initialize(app, name = nil) + @app = app + @header_name = HEADER_NAME + @header_name += "-#{name.to_s.downcase}" if name + end + + def call(env) + start_time = Utils.clock_time + _, headers, _ = response = @app.call(env) + + request_time = Utils.clock_time - start_time + + unless headers.key?(@header_name) + headers[@header_name] = FORMAT_STRING % request_time + end + + response + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/sendfile.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/sendfile.rb new file mode 100644 index 00000000..47238936 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/sendfile.rb @@ -0,0 +1,167 @@ +# frozen_string_literal: true + +require_relative 'constants' +require_relative 'utils' +require_relative 'body_proxy' + +module Rack + + # = Sendfile + # + # The Sendfile middleware intercepts responses whose body is being + # served from a file and replaces it with a server specific x-sendfile + # header. The web server is then responsible for writing the file contents + # to the client. This can dramatically reduce the amount of work required + # by the Ruby backend and takes advantage of the web server's optimized file + # delivery code. + # + # In order to take advantage of this middleware, the response body must + # respond to +to_path+ and the request must include an x-sendfile-type + # header. Rack::Files and other components implement +to_path+ so there's + # rarely anything you need to do in your application. The x-sendfile-type + # header is typically set in your web servers configuration. The following + # sections attempt to document + # + # === Nginx + # + # Nginx supports the x-accel-redirect header. This is similar to x-sendfile + # but requires parts of the filesystem to be mapped into a private URL + # hierarchy. + # + # The following example shows the Nginx configuration required to create + # a private "/files/" area, enable x-accel-redirect, and pass the special + # x-sendfile-type and x-accel-mapping headers to the backend: + # + # location ~ /files/(.*) { + # internal; + # alias /var/www/$1; + # } + # + # location / { + # proxy_redirect off; + # + # proxy_set_header Host $host; + # proxy_set_header X-Real-IP $remote_addr; + # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + # + # proxy_set_header x-sendfile-type x-accel-redirect; + # proxy_set_header x-accel-mapping /var/www/=/files/; + # + # proxy_pass http://127.0.0.1:8080/; + # } + # + # Note that the x-sendfile-type header must be set exactly as shown above. + # The x-accel-mapping header should specify the location on the file system, + # followed by an equals sign (=), followed name of the private URL pattern + # that it maps to. The middleware performs a simple substitution on the + # resulting path. + # + # See Also: https://www.nginx.com/resources/wiki/start/topics/examples/xsendfile + # + # === lighttpd + # + # Lighttpd has supported some variation of the x-sendfile header for some + # time, although only recent version support x-sendfile in a reverse proxy + # configuration. + # + # $HTTP["host"] == "example.com" { + # proxy-core.protocol = "http" + # proxy-core.balancer = "round-robin" + # proxy-core.backends = ( + # "127.0.0.1:8000", + # "127.0.0.1:8001", + # ... + # ) + # + # proxy-core.allow-x-sendfile = "enable" + # proxy-core.rewrite-request = ( + # "x-sendfile-type" => (".*" => "x-sendfile") + # ) + # } + # + # See Also: http://redmine.lighttpd.net/wiki/lighttpd/Docs:ModProxyCore + # + # === Apache + # + # x-sendfile is supported under Apache 2.x using a separate module: + # + # https://tn123.org/mod_xsendfile/ + # + # Once the module is compiled and installed, you can enable it using + # XSendFile config directive: + # + # RequestHeader Set x-sendfile-type x-sendfile + # ProxyPassReverse / http://localhost:8001/ + # XSendFile on + # + # === Mapping parameter + # + # The third parameter allows for an overriding extension of the + # x-accel-mapping header. Mappings should be provided in tuples of internal to + # external. The internal values may contain regular expression syntax, they + # will be matched with case indifference. + + class Sendfile + def initialize(app, variation = nil, mappings = []) + @app = app + @variation = variation + @mappings = mappings.map do |internal, external| + [/^#{internal}/i, external] + end + end + + def call(env) + _, headers, body = response = @app.call(env) + + if body.respond_to?(:to_path) + case type = variation(env) + when /x-accel-redirect/i + path = ::File.expand_path(body.to_path) + if url = map_accel_path(env, path) + headers[CONTENT_LENGTH] = '0' + # '?' must be percent-encoded because it is not query string but a part of path + headers[type.downcase] = ::Rack::Utils.escape_path(url).gsub('?', '%3F') + obody = body + response[2] = Rack::BodyProxy.new([]) do + obody.close if obody.respond_to?(:close) + end + else + env[RACK_ERRORS].puts "x-accel-mapping header missing" + end + when /x-sendfile|x-lighttpd-send-file/i + path = ::File.expand_path(body.to_path) + headers[CONTENT_LENGTH] = '0' + headers[type.downcase] = path + obody = body + response[2] = Rack::BodyProxy.new([]) do + obody.close if obody.respond_to?(:close) + end + when '', nil + else + env[RACK_ERRORS].puts "Unknown x-sendfile variation: #{type.inspect}" + end + end + response + end + + private + def variation(env) + @variation || + env['sendfile.type'] || + env['HTTP_X_SENDFILE_TYPE'] + end + + def map_accel_path(env, path) + if mapping = @mappings.find { |internal, _| internal =~ path } + path.sub(*mapping) + elsif mapping = env['HTTP_X_ACCEL_MAPPING'] + mapping.split(',').map(&:strip).each do |m| + internal, external = m.split('=', 2).map(&:strip) + new_path = path.sub(/^#{internal}/i, external) + return new_path unless path == new_path + end + path + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/show_exceptions.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/show_exceptions.rb new file mode 100644 index 00000000..9172a4db --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/show_exceptions.rb @@ -0,0 +1,407 @@ +# frozen_string_literal: true + +require 'erb' + +require_relative 'constants' +require_relative 'utils' +require_relative 'request' + +module Rack + # Rack::ShowExceptions catches all exceptions raised from the app it + # wraps. It shows a useful backtrace with the sourcefile and + # clickable context, the whole Rack environment and the request + # data. + # + # Be careful when you use this on public-facing sites as it could + # reveal information helpful to attackers. + + class ShowExceptions + CONTEXT = 7 + + Frame = Struct.new(:filename, :lineno, :function, + :pre_context_lineno, :pre_context, + :context_line, :post_context_lineno, + :post_context) + + def initialize(app) + @app = app + end + + def call(env) + @app.call(env) + rescue StandardError, LoadError, SyntaxError => e + exception_string = dump_exception(e) + + env[RACK_ERRORS].puts(exception_string) + env[RACK_ERRORS].flush + + if accepts_html?(env) + content_type = "text/html" + body = pretty(env, e) + else + content_type = "text/plain" + body = exception_string + end + + [ + 500, + { + CONTENT_TYPE => content_type, + CONTENT_LENGTH => body.bytesize.to_s, + }, + [body], + ] + end + + def prefers_plaintext?(env) + !accepts_html?(env) + end + + def accepts_html?(env) + Rack::Utils.best_q_match(env["HTTP_ACCEPT"], %w[text/html]) + end + private :accepts_html? + + def dump_exception(exception) + if exception.respond_to?(:detailed_message) + message = exception.detailed_message(highlight: false) + else + message = exception.message + end + string = "#{exception.class}: #{message}\n".dup + string << exception.backtrace.map { |l| "\t#{l}" }.join("\n") + string + end + + def pretty(env, exception) + req = Rack::Request.new(env) + + # This double assignment is to prevent an "unused variable" warning. + # Yes, it is dumb, but I don't like Ruby yelling at me. + path = path = (req.script_name + req.path_info).squeeze("/") + + # This double assignment is to prevent an "unused variable" warning. + # Yes, it is dumb, but I don't like Ruby yelling at me. + frames = frames = exception.backtrace.map { |line| + frame = Frame.new + if line =~ /(.*?):(\d+)(:in `(.*)')?/ + frame.filename = $1 + frame.lineno = $2.to_i + frame.function = $4 + + begin + lineno = frame.lineno - 1 + lines = ::File.readlines(frame.filename) + frame.pre_context_lineno = [lineno - CONTEXT, 0].max + frame.pre_context = lines[frame.pre_context_lineno...lineno] + frame.context_line = lines[lineno].chomp + frame.post_context_lineno = [lineno + CONTEXT, lines.size].min + frame.post_context = lines[lineno + 1..frame.post_context_lineno] + rescue + end + + frame + else + nil + end + }.compact + + template.result(binding) + end + + def template + TEMPLATE + end + + def h(obj) # :nodoc: + case obj + when String + Utils.escape_html(obj) + else + Utils.escape_html(obj.inspect) + end + end + + # :stopdoc: + + # adapted from Django + # Copyright (c) Django Software Foundation and individual contributors. + # Used under the modified BSD license: + # http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5 + TEMPLATE = ERB.new(<<-'HTML'.gsub(/^ /, '')) + + + + + + <%=h exception.class %> at <%=h path %> + + + + + +
+

<%=h exception.class %> at <%=h path %>

+ <% if exception.respond_to?(:detailed_message) %> +

<%=h exception.detailed_message(highlight: false) %>

+ <% else %> +

<%=h exception.message %>

+ <% end %> + + + + + + +
Ruby + <% if first = frames.first %> + <%=h first.filename %>: in <%=h first.function %>, line <%=h frames.first.lineno %> + <% else %> + unknown location + <% end %> +
Web<%=h req.request_method %> <%=h(req.host + path)%>
+ +

Jump to:

+ +
+ +
+

Traceback (innermost first)

+
    + <% frames.each { |frame| %> +
  • + <%=h frame.filename %>: in <%=h frame.function %> + + <% if frame.context_line %> +
    + <% if frame.pre_context %> +
      + <% frame.pre_context.each { |line| %> +
    1. <%=h line %>
    2. + <% } %> +
    + <% end %> + +
      +
    1. <%=h frame.context_line %>...
    + + <% if frame.post_context %> +
      + <% frame.post_context.each { |line| %> +
    1. <%=h line %>
    2. + <% } %> +
    + <% end %> +
    + <% end %> +
  • + <% } %> +
+
+ +
+

Request information

+ +

GET

+ <% if req.GET and not req.GET.empty? %> + + + + + + + + + <% req.GET.sort_by { |k, v| k.to_s }.each { |key, val| %> + + + + + <% } %> + +
VariableValue
<%=h key %>
<%=h val.inspect %>
+ <% else %> +

No GET data.

+ <% end %> + +

POST

+ <% if ((req.POST and not req.POST.empty?) rescue (no_post_data = "Invalid POST data"; nil)) %> + + + + + + + + + <% req.POST.sort_by { |k, v| k.to_s }.each { |key, val| %> + + + + + <% } %> + +
VariableValue
<%=h key %>
<%=h val.inspect %>
+ <% else %> +

<%= no_post_data || "No POST data" %>.

+ <% end %> + + + + <% unless req.cookies.empty? %> + + + + + + + + + <% req.cookies.each { |key, val| %> + + + + + <% } %> + +
VariableValue
<%=h key %>
<%=h val.inspect %>
+ <% else %> +

No cookie data.

+ <% end %> + +

Rack ENV

+ + + + + + + + + <% env.sort_by { |k, v| k.to_s }.each { |key, val| %> + + + + + <% } %> + +
VariableValue
<%=h key %>
<%=h val.inspect %>
+ +
+ +
+

+ You're seeing this error because you use Rack::ShowExceptions. +

+
+ + + + HTML + + # :startdoc: + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/show_status.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/show_status.rb new file mode 100644 index 00000000..b6f75a01 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/show_status.rb @@ -0,0 +1,123 @@ +# frozen_string_literal: true + +require 'erb' + +require_relative 'constants' +require_relative 'utils' +require_relative 'request' +require_relative 'body_proxy' + +module Rack + # Rack::ShowStatus catches all empty responses and replaces them + # with a site explaining the error. + # + # Additional details can be put into rack.showstatus.detail + # and will be shown as HTML. If such details exist, the error page + # is always rendered, even if the reply was not empty. + + class ShowStatus + def initialize(app) + @app = app + @template = ERB.new(TEMPLATE) + end + + def call(env) + status, headers, body = response = @app.call(env) + empty = headers[CONTENT_LENGTH].to_i <= 0 + + # client or server error, or explicit message + if (status.to_i >= 400 && empty) || env[RACK_SHOWSTATUS_DETAIL] + # This double assignment is to prevent an "unused variable" warning. + # Yes, it is dumb, but I don't like Ruby yelling at me. + req = req = Rack::Request.new(env) + + message = Rack::Utils::HTTP_STATUS_CODES[status.to_i] || status.to_s + + # This double assignment is to prevent an "unused variable" warning. + # Yes, it is dumb, but I don't like Ruby yelling at me. + detail = detail = env[RACK_SHOWSTATUS_DETAIL] || message + + html = @template.result(binding) + size = html.bytesize + + response[2] = Rack::BodyProxy.new([html]) do + body.close if body.respond_to?(:close) + end + + headers[CONTENT_TYPE] = "text/html" + headers[CONTENT_LENGTH] = size.to_s + end + + response + end + + def h(obj) # :nodoc: + case obj + when String + Utils.escape_html(obj) + else + Utils.escape_html(obj.inspect) + end + end + + # :stopdoc: + +# adapted from Django +# Copyright (c) Django Software Foundation and individual contributors. +# Used under the modified BSD license: +# http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5 +TEMPLATE = <<'HTML' + + + + + <%=h message %> at <%=h req.script_name + req.path_info %> + + + + +
+

<%=h message %> (<%= status.to_i %>)

+ + + + + + + + + +
Request Method:<%=h req.request_method %>
Request URL:<%=h req.url %>
+
+
+

<%=h detail %>

+
+ +
+

+ You're seeing this error because you use Rack::ShowStatus. +

+
+ + +HTML + + # :startdoc: + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/static.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/static.rb new file mode 100644 index 00000000..c26993ea --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/static.rb @@ -0,0 +1,188 @@ +# frozen_string_literal: true + +require_relative 'constants' +require_relative 'files' +require_relative 'mime' + +module Rack + + # The Rack::Static middleware intercepts requests for static files + # (javascript files, images, stylesheets, etc) based on the url prefixes or + # route mappings passed in the options, and serves them using a Rack::Files + # object. This allows a Rack stack to serve both static and dynamic content. + # + # Examples: + # + # Serve all requests beginning with /media from the "media" folder located + # in the current directory (ie media/*): + # + # use Rack::Static, :urls => ["/media"] + # + # Same as previous, but instead of returning 404 for missing files under + # /media, call the next middleware: + # + # use Rack::Static, :urls => ["/media"], :cascade => true + # + # Serve all requests beginning with /css or /images from the folder "public" + # in the current directory (ie public/css/* and public/images/*): + # + # use Rack::Static, :urls => ["/css", "/images"], :root => "public" + # + # Serve all requests to / with "index.html" from the folder "public" in the + # current directory (ie public/index.html): + # + # use Rack::Static, :urls => {"/" => 'index.html'}, :root => 'public' + # + # Serve all requests normally from the folder "public" in the current + # directory but uses index.html as default route for "/" + # + # use Rack::Static, :urls => [""], :root => 'public', :index => + # 'index.html' + # + # Set custom HTTP Headers for based on rules: + # + # use Rack::Static, :root => 'public', + # :header_rules => [ + # [rule, {header_field => content, header_field => content}], + # [rule, {header_field => content}] + # ] + # + # Rules for selecting files: + # + # 1) All files + # Provide the :all symbol + # :all => Matches every file + # + # 2) Folders + # Provide the folder path as a string + # '/folder' or '/folder/subfolder' => Matches files in a certain folder + # + # 3) File Extensions + # Provide the file extensions as an array + # ['css', 'js'] or %w(css js) => Matches files ending in .css or .js + # + # 4) Regular Expressions / Regexp + # Provide a regular expression + # %r{\.(?:css|js)\z} => Matches files ending in .css or .js + # /\.(?:eot|ttf|otf|woff2|woff|svg)\z/ => Matches files ending in + # the most common web font formats (.eot, .ttf, .otf, .woff2, .woff, .svg) + # Note: This Regexp is available as a shortcut, using the :fonts rule + # + # 5) Font Shortcut + # Provide the :fonts symbol + # :fonts => Uses the Regexp rule stated right above to match all common web font endings + # + # Rule Ordering: + # Rules are applied in the order that they are provided. + # List rather general rules above special ones. + # + # Complete example use case including HTTP header rules: + # + # use Rack::Static, :root => 'public', + # :header_rules => [ + # # Cache all static files in public caches (e.g. Rack::Cache) + # # as well as in the browser + # [:all, {'cache-control' => 'public, max-age=31536000'}], + # + # # Provide web fonts with cross-origin access-control-headers + # # Firefox requires this when serving assets using a Content Delivery Network + # [:fonts, {'access-control-allow-origin' => '*'}] + # ] + # + class Static + def initialize(app, options = {}) + @app = app + @urls = options[:urls] || ["/favicon.ico"] + @index = options[:index] + @gzip = options[:gzip] + @cascade = options[:cascade] + root = options[:root] || Dir.pwd + + # HTTP Headers + @header_rules = options[:header_rules] || [] + # Allow for legacy :cache_control option while prioritizing global header_rules setting + @header_rules.unshift([:all, { CACHE_CONTROL => options[:cache_control] }]) if options[:cache_control] + + @file_server = Rack::Files.new(root) + end + + def add_index_root?(path) + @index && route_file(path) && path.end_with?('/') + end + + def overwrite_file_path(path) + @urls.kind_of?(Hash) && @urls.key?(path) || add_index_root?(path) + end + + def route_file(path) + @urls.kind_of?(Array) && @urls.any? { |url| path.index(url) == 0 } + end + + def can_serve(path) + route_file(path) || overwrite_file_path(path) + end + + def call(env) + path = env[PATH_INFO] + actual_path = Utils.clean_path_info(Utils.unescape_path(path)) + + if can_serve(actual_path) + if overwrite_file_path(path) + env[PATH_INFO] = (add_index_root?(path) ? path + @index : @urls[path]) + elsif @gzip && env['HTTP_ACCEPT_ENCODING'] && /\bgzip\b/.match?(env['HTTP_ACCEPT_ENCODING']) + path = env[PATH_INFO] + env[PATH_INFO] += '.gz' + response = @file_server.call(env) + env[PATH_INFO] = path + + if response[0] == 404 + response = nil + elsif response[0] == 304 + # Do nothing, leave headers as is + else + response[1][CONTENT_TYPE] = Mime.mime_type(::File.extname(path), 'text/plain') + response[1]['content-encoding'] = 'gzip' + end + end + + path = env[PATH_INFO] + response ||= @file_server.call(env) + + if @cascade && response[0] == 404 + return @app.call(env) + end + + headers = response[1] + applicable_rules(path).each do |rule, new_headers| + new_headers.each { |field, content| headers[field] = content } + end + + response + else + @app.call(env) + end + end + + # Convert HTTP header rules to HTTP headers + def applicable_rules(path) + @header_rules.find_all do |rule, new_headers| + case rule + when :all + true + when :fonts + /\.(?:ttf|otf|eot|woff2|woff|svg)\z/.match?(path) + when String + path = ::Rack::Utils.unescape(path) + path.start_with?(rule) || path.start_with?('/' + rule) + when Array + /\.(#{rule.join('|')})\z/.match?(path) + when Regexp + rule.match?(path) + else + false + end + end + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/tempfile_reaper.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/tempfile_reaper.rb new file mode 100644 index 00000000..0b94cc73 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/tempfile_reaper.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require_relative 'constants' +require_relative 'body_proxy' + +module Rack + + # Middleware tracks and cleans Tempfiles created throughout a request (i.e. Rack::Multipart) + # Ideas/strategy based on posts by Eric Wong and Charles Oliver Nutter + # https://groups.google.com/forum/#!searchin/rack-devel/temp/rack-devel/brK8eh-MByw/sw61oJJCGRMJ + class TempfileReaper + def initialize(app) + @app = app + end + + def call(env) + env[RACK_TEMPFILES] ||= [] + + begin + _, _, body = response = @app.call(env) + rescue Exception + env[RACK_TEMPFILES]&.each(&:close!) + raise + end + + response[2] = BodyProxy.new(body) do + env[RACK_TEMPFILES]&.each(&:close!) + end + + response + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/urlmap.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/urlmap.rb new file mode 100644 index 00000000..99c4d823 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/urlmap.rb @@ -0,0 +1,99 @@ +# frozen_string_literal: true + +require 'set' + +require_relative 'constants' + +module Rack + # Rack::URLMap takes a hash mapping urls or paths to apps, and + # dispatches accordingly. Support for HTTP/1.1 host names exists if + # the URLs start with http:// or https://. + # + # URLMap modifies the SCRIPT_NAME and PATH_INFO such that the part + # relevant for dispatch is in the SCRIPT_NAME, and the rest in the + # PATH_INFO. This should be taken care of when you need to + # reconstruct the URL in order to create links. + # + # URLMap dispatches in such a way that the longest paths are tried + # first, since they are most specific. + + class URLMap + def initialize(map = {}) + remap(map) + end + + def remap(map) + @known_hosts = Set[] + @mapping = map.map { |location, app| + if location =~ %r{\Ahttps?://(.*?)(/.*)} + host, location = $1, $2 + @known_hosts << host + else + host = nil + end + + unless location[0] == ?/ + raise ArgumentError, "paths need to start with /" + end + + location = location.chomp('/') + match = Regexp.new("^#{Regexp.quote(location).gsub('/', '/+')}(.*)", Regexp::NOENCODING) + + [host, location, match, app] + }.sort_by do |(host, location, _, _)| + [host ? -host.size : Float::INFINITY, -location.size] + end + end + + def call(env) + path = env[PATH_INFO] + script_name = env[SCRIPT_NAME] + http_host = env[HTTP_HOST] + server_name = env[SERVER_NAME] + server_port = env[SERVER_PORT] + + is_same_server = casecmp?(http_host, server_name) || + casecmp?(http_host, "#{server_name}:#{server_port}") + + is_host_known = @known_hosts.include? http_host + + @mapping.each do |host, location, match, app| + unless casecmp?(http_host, host) \ + || casecmp?(server_name, host) \ + || (!host && is_same_server) \ + || (!host && !is_host_known) # If we don't have a matching host, default to the first without a specified host + next + end + + next unless m = match.match(path.to_s) + + rest = m[1] + next unless !rest || rest.empty? || rest[0] == ?/ + + env[SCRIPT_NAME] = (script_name + location) + env[PATH_INFO] = rest + + return app.call(env) + end + + [404, { CONTENT_TYPE => "text/plain", "x-cascade" => "pass" }, ["Not Found: #{path}"]] + + ensure + env[PATH_INFO] = path + env[SCRIPT_NAME] = script_name + end + + private + def casecmp?(v1, v2) + # if both nil, or they're the same string + return true if v1 == v2 + + # if either are nil... (but they're not the same) + return false if v1.nil? + return false if v2.nil? + + # otherwise check they're not case-insensitive the same + v1.casecmp(v2).zero? + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/utils.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/utils.rb new file mode 100644 index 00000000..bbf4969f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/utils.rb @@ -0,0 +1,631 @@ +# -*- encoding: binary -*- +# frozen_string_literal: true + +require 'uri' +require 'fileutils' +require 'set' +require 'tempfile' +require 'time' +require 'erb' + +require_relative 'query_parser' +require_relative 'mime' +require_relative 'headers' +require_relative 'constants' + +module Rack + # Rack::Utils contains a grab-bag of useful methods for writing web + # applications adopted from all kinds of Ruby libraries. + + module Utils + ParameterTypeError = QueryParser::ParameterTypeError + InvalidParameterError = QueryParser::InvalidParameterError + ParamsTooDeepError = QueryParser::ParamsTooDeepError + DEFAULT_SEP = QueryParser::DEFAULT_SEP + COMMON_SEP = QueryParser::COMMON_SEP + KeySpaceConstrainedParams = QueryParser::Params + URI_PARSER = defined?(::URI::RFC2396_PARSER) ? ::URI::RFC2396_PARSER : ::URI::DEFAULT_PARSER + + class << self + attr_accessor :default_query_parser + end + # The default amount of nesting to allowed by hash parameters. + # This helps prevent a rogue client from triggering a possible stack overflow + # when parsing parameters. + self.default_query_parser = QueryParser.make_default(32) + + module_function + + # URI escapes. (CGI style space to +) + def escape(s) + URI.encode_www_form_component(s) + end + + # Like URI escaping, but with %20 instead of +. Strictly speaking this is + # true URI escaping. + def escape_path(s) + URI_PARSER.escape s + end + + # Unescapes the **path** component of a URI. See Rack::Utils.unescape for + # unescaping query parameters or form components. + def unescape_path(s) + URI_PARSER.unescape s + end + + # Unescapes a URI escaped string with +encoding+. +encoding+ will be the + # target encoding of the string returned, and it defaults to UTF-8 + def unescape(s, encoding = Encoding::UTF_8) + URI.decode_www_form_component(s, encoding) + end + + class << self + attr_accessor :multipart_total_part_limit + + attr_accessor :multipart_file_limit + + # multipart_part_limit is the original name of multipart_file_limit, but + # the limit only counts parts with filenames. + alias multipart_part_limit multipart_file_limit + alias multipart_part_limit= multipart_file_limit= + end + + # The maximum number of file parts a request can contain. Accepting too + # many parts can lead to the server running out of file handles. + # Set to `0` for no limit. + self.multipart_file_limit = (ENV['RACK_MULTIPART_PART_LIMIT'] || ENV['RACK_MULTIPART_FILE_LIMIT'] || 128).to_i + + # The maximum total number of parts a request can contain. Accepting too + # many can lead to excessive memory use and parsing time. + self.multipart_total_part_limit = (ENV['RACK_MULTIPART_TOTAL_PART_LIMIT'] || 4096).to_i + + def self.param_depth_limit + default_query_parser.param_depth_limit + end + + def self.param_depth_limit=(v) + self.default_query_parser = self.default_query_parser.new_depth_limit(v) + end + + if defined?(Process::CLOCK_MONOTONIC) + def clock_time + Process.clock_gettime(Process::CLOCK_MONOTONIC) + end + else + # :nocov: + def clock_time + Time.now.to_f + end + # :nocov: + end + + def parse_query(qs, d = nil, &unescaper) + Rack::Utils.default_query_parser.parse_query(qs, d, &unescaper) + end + + def parse_nested_query(qs, d = nil) + Rack::Utils.default_query_parser.parse_nested_query(qs, d) + end + + def build_query(params) + params.map { |k, v| + if v.class == Array + build_query(v.map { |x| [k, x] }) + else + v.nil? ? escape(k) : "#{escape(k)}=#{escape(v)}" + end + }.join("&") + end + + def build_nested_query(value, prefix = nil) + case value + when Array + value.map { |v| + build_nested_query(v, "#{prefix}[]") + }.join("&") + when Hash + value.map { |k, v| + build_nested_query(v, prefix ? "#{prefix}[#{k}]" : k) + }.delete_if(&:empty?).join('&') + when nil + escape(prefix) + else + raise ArgumentError, "value must be a Hash" if prefix.nil? + "#{escape(prefix)}=#{escape(value)}" + end + end + + def q_values(q_value_header) + q_value_header.to_s.split(',').map do |part| + value, parameters = part.split(';', 2).map(&:strip) + quality = 1.0 + if parameters && (md = /\Aq=([\d.]+)/.match(parameters)) + quality = md[1].to_f + end + [value, quality] + end + end + + def forwarded_values(forwarded_header) + return nil unless forwarded_header + forwarded_header = forwarded_header.to_s.gsub("\n", ";") + + forwarded_header.split(';').each_with_object({}) do |field, values| + field.split(',').each do |pair| + pair = pair.split('=').map(&:strip).join('=') + return nil unless pair =~ /\A(by|for|host|proto)="?([^"]+)"?\Z/i + (values[$1.downcase.to_sym] ||= []) << $2 + end + end + end + module_function :forwarded_values + + # Return best accept value to use, based on the algorithm + # in RFC 2616 Section 14. If there are multiple best + # matches (same specificity and quality), the value returned + # is arbitrary. + def best_q_match(q_value_header, available_mimes) + values = q_values(q_value_header) + + matches = values.map do |req_mime, quality| + match = available_mimes.find { |am| Rack::Mime.match?(am, req_mime) } + next unless match + [match, quality] + end.compact.sort_by do |match, quality| + (match.split('/', 2).count('*') * -10) + quality + end.last + matches&.first + end + + # Introduced in ERB 4.0. ERB::Escape is an alias for ERB::Utils which + # doesn't get monkey-patched by rails + if defined?(ERB::Escape) && ERB::Escape.instance_method(:html_escape) + define_method(:escape_html, ERB::Escape.instance_method(:html_escape)) + else + require 'cgi/escape' + # Escape ampersands, brackets and quotes to their HTML/XML entities. + def escape_html(string) + CGI.escapeHTML(string.to_s) + end + end + + def select_best_encoding(available_encodings, accept_encoding) + # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html + + expanded_accept_encoding = [] + + accept_encoding.each do |m, q| + preference = available_encodings.index(m) || available_encodings.size + + if m == "*" + (available_encodings - accept_encoding.map(&:first)).each do |m2| + expanded_accept_encoding << [m2, q, preference] + end + else + expanded_accept_encoding << [m, q, preference] + end + end + + encoding_candidates = expanded_accept_encoding + .sort_by { |_, q, p| [-q, p] } + .map!(&:first) + + unless encoding_candidates.include?("identity") + encoding_candidates.push("identity") + end + + expanded_accept_encoding.each do |m, q| + encoding_candidates.delete(m) if q == 0.0 + end + + (encoding_candidates & available_encodings)[0] + end + + # :call-seq: + # parse_cookies_header(value) -> hash + # + # Parse cookies from the provided header +value+ according to RFC6265. The + # syntax for cookie headers only supports semicolons. Returns a map of + # cookie +key+ to cookie +value+. + # + # parse_cookies_header('myname=myvalue; max-age=0') + # # => {"myname"=>"myvalue", "max-age"=>"0"} + # + def parse_cookies_header(value) + return {} unless value + + value.split(/; */n).each_with_object({}) do |cookie, cookies| + next if cookie.empty? + key, value = cookie.split('=', 2) + cookies[key] = (unescape(value) rescue value) unless cookies.key?(key) + end + end + + # :call-seq: + # parse_cookies(env) -> hash + # + # Parse cookies from the provided request environment using + # parse_cookies_header. Returns a map of cookie +key+ to cookie +value+. + # + # parse_cookies({'HTTP_COOKIE' => 'myname=myvalue'}) + # # => {'myname' => 'myvalue'} + # + def parse_cookies(env) + parse_cookies_header env[HTTP_COOKIE] + end + + # A valid cookie key according to RFC2616. + # A can be any US-ASCII characters, except control characters, spaces, or tabs. It also must not contain a separator character like the following: ( ) < > @ , ; : \ " / [ ] ? = { }. + VALID_COOKIE_KEY = /\A[!#$%&'*+\-\.\^_`|~0-9a-zA-Z]+\z/.freeze + private_constant :VALID_COOKIE_KEY + + private def escape_cookie_key(key) + if key =~ VALID_COOKIE_KEY + key + else + warn "Cookie key #{key.inspect} is not valid according to RFC2616; it will be escaped. This behaviour is deprecated and will be removed in a future version of Rack.", uplevel: 2 + escape(key) + end + end + + # :call-seq: + # set_cookie_header(key, value) -> encoded string + # + # Generate an encoded string using the provided +key+ and +value+ suitable + # for the +set-cookie+ header according to RFC6265. The +value+ may be an + # instance of either +String+ or +Hash+. + # + # If the cookie +value+ is an instance of +Hash+, it considers the following + # cookie attribute keys: +domain+, +max_age+, +expires+ (must be instance + # of +Time+), +secure+, +http_only+, +same_site+ and +value+. For more + # details about the interpretation of these fields, consult + # [RFC6265 Section 5.2](https://datatracker.ietf.org/doc/html/rfc6265#section-5.2). + # + # An extra cookie attribute +escape_key+ can be provided to control whether + # or not the cookie key is URL encoded. If explicitly set to +false+, the + # cookie key name will not be url encoded (escaped). The default is +true+. + # + # set_cookie_header("myname", "myvalue") + # # => "myname=myvalue" + # + # set_cookie_header("myname", {value: "myvalue", max_age: 10}) + # # => "myname=myvalue; max-age=10" + # + def set_cookie_header(key, value) + case value + when Hash + key = escape_cookie_key(key) unless value[:escape_key] == false + domain = "; domain=#{value[:domain]}" if value[:domain] + path = "; path=#{value[:path]}" if value[:path] + max_age = "; max-age=#{value[:max_age]}" if value[:max_age] + expires = "; expires=#{value[:expires].httpdate}" if value[:expires] + secure = "; secure" if value[:secure] + httponly = "; httponly" if (value.key?(:httponly) ? value[:httponly] : value[:http_only]) + same_site = + case value[:same_site] + when false, nil + nil + when :none, 'None', :None + '; samesite=none' + when :lax, 'Lax', :Lax + '; samesite=lax' + when true, :strict, 'Strict', :Strict + '; samesite=strict' + else + raise ArgumentError, "Invalid :same_site value: #{value[:same_site].inspect}" + end + partitioned = "; partitioned" if value[:partitioned] + value = value[:value] + else + key = escape_cookie_key(key) + end + + value = [value] unless Array === value + + return "#{key}=#{value.map { |v| escape v }.join('&')}#{domain}" \ + "#{path}#{max_age}#{expires}#{secure}#{httponly}#{same_site}#{partitioned}" + end + + # :call-seq: + # set_cookie_header!(headers, key, value) -> header value + # + # Append a cookie in the specified headers with the given cookie +key+ and + # +value+ using set_cookie_header. + # + # If the headers already contains a +set-cookie+ key, it will be converted + # to an +Array+ if not already, and appended to. + def set_cookie_header!(headers, key, value) + if header = headers[SET_COOKIE] + if header.is_a?(Array) + header << set_cookie_header(key, value) + else + headers[SET_COOKIE] = [header, set_cookie_header(key, value)] + end + else + headers[SET_COOKIE] = set_cookie_header(key, value) + end + end + + # :call-seq: + # delete_set_cookie_header(key, value = {}) -> encoded string + # + # Generate an encoded string based on the given +key+ and +value+ using + # set_cookie_header for the purpose of causing the specified cookie to be + # deleted. The +value+ may be an instance of +Hash+ and can include + # attributes as outlined by set_cookie_header. The encoded cookie will have + # a +max_age+ of 0 seconds, an +expires+ date in the past and an empty + # +value+. When used with the +set-cookie+ header, it will cause the client + # to *remove* any matching cookie. + # + # delete_set_cookie_header("myname") + # # => "myname=; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 GMT" + # + def delete_set_cookie_header(key, value = {}) + set_cookie_header(key, value.merge(max_age: '0', expires: Time.at(0), value: '')) + end + + def delete_cookie_header!(headers, key, value = {}) + headers[SET_COOKIE] = delete_set_cookie_header!(headers[SET_COOKIE], key, value) + + return nil + end + + # :call-seq: + # delete_set_cookie_header!(header, key, value = {}) -> header value + # + # Set an expired cookie in the specified headers with the given cookie + # +key+ and +value+ using delete_set_cookie_header. This causes + # the client to immediately delete the specified cookie. + # + # delete_set_cookie_header!(nil, "mycookie") + # # => "mycookie=; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 GMT" + # + # If the header is non-nil, it will be modified in place. + # + # header = [] + # delete_set_cookie_header!(header, "mycookie") + # # => ["mycookie=; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 GMT"] + # header + # # => ["mycookie=; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 GMT"] + # + def delete_set_cookie_header!(header, key, value = {}) + if header + header = Array(header) + header << delete_set_cookie_header(key, value) + else + header = delete_set_cookie_header(key, value) + end + + return header + end + + def rfc2822(time) + time.rfc2822 + end + + # Parses the "Range:" header, if present, into an array of Range objects. + # Returns nil if the header is missing or syntactically invalid. + # Returns an empty array if none of the ranges are satisfiable. + def byte_ranges(env, size) + get_byte_ranges env['HTTP_RANGE'], size + end + + def get_byte_ranges(http_range, size) + # See + # Ignore Range when file size is 0 to avoid a 416 error. + return nil if size.zero? + return nil unless http_range && http_range =~ /bytes=([^;]+)/ + ranges = [] + $1.split(/,\s*/).each do |range_spec| + return nil unless range_spec.include?('-') + range = range_spec.split('-') + r0, r1 = range[0], range[1] + if r0.nil? || r0.empty? + return nil if r1.nil? + # suffix-byte-range-spec, represents trailing suffix of file + r0 = size - r1.to_i + r0 = 0 if r0 < 0 + r1 = size - 1 + else + r0 = r0.to_i + if r1.nil? + r1 = size - 1 + else + r1 = r1.to_i + return nil if r1 < r0 # backwards range is syntactically invalid + r1 = size - 1 if r1 >= size + end + end + ranges << (r0..r1) if r0 <= r1 + end + + return [] if ranges.map(&:size).sum > size + + ranges + end + + # :nocov: + if defined?(OpenSSL.fixed_length_secure_compare) + # Constant time string comparison. + # + # NOTE: the values compared should be of fixed length, such as strings + # that have already been processed by HMAC. This should not be used + # on variable length plaintext strings because it could leak length info + # via timing attacks. + def secure_compare(a, b) + return false unless a.bytesize == b.bytesize + + OpenSSL.fixed_length_secure_compare(a, b) + end + # :nocov: + else + def secure_compare(a, b) + return false unless a.bytesize == b.bytesize + + l = a.unpack("C*") + + r, i = 0, -1 + b.each_byte { |v| r |= v ^ l[i += 1] } + r == 0 + end + end + + # Context allows the use of a compatible middleware at different points + # in a request handling stack. A compatible middleware must define + # #context which should take the arguments env and app. The first of which + # would be the request environment. The second of which would be the rack + # application that the request would be forwarded to. + class Context + attr_reader :for, :app + + def initialize(app_f, app_r) + raise 'running context does not respond to #context' unless app_f.respond_to? :context + @for, @app = app_f, app_r + end + + def call(env) + @for.context(env, @app) + end + + def recontext(app) + self.class.new(@for, app) + end + + def context(env, app = @app) + recontext(app).call(env) + end + end + + # Every standard HTTP code mapped to the appropriate message. + # Generated with: + # curl -s https://www.iana.org/assignments/http-status-codes/http-status-codes-1.csv \ + # | ruby -rcsv -e "puts CSV.parse(STDIN, headers: true) \ + # .reject {|v| v['Description'] == 'Unassigned' or v['Description'].include? '(' } \ + # .map {|v| %Q/#{v['Value']} => '#{v['Description']}'/ }.join(','+?\n)" + HTTP_STATUS_CODES = { + 100 => 'Continue', + 101 => 'Switching Protocols', + 102 => 'Processing', + 103 => 'Early Hints', + 200 => 'OK', + 201 => 'Created', + 202 => 'Accepted', + 203 => 'Non-Authoritative Information', + 204 => 'No Content', + 205 => 'Reset Content', + 206 => 'Partial Content', + 207 => 'Multi-Status', + 208 => 'Already Reported', + 226 => 'IM Used', + 300 => 'Multiple Choices', + 301 => 'Moved Permanently', + 302 => 'Found', + 303 => 'See Other', + 304 => 'Not Modified', + 305 => 'Use Proxy', + 307 => 'Temporary Redirect', + 308 => 'Permanent Redirect', + 400 => 'Bad Request', + 401 => 'Unauthorized', + 402 => 'Payment Required', + 403 => 'Forbidden', + 404 => 'Not Found', + 405 => 'Method Not Allowed', + 406 => 'Not Acceptable', + 407 => 'Proxy Authentication Required', + 408 => 'Request Timeout', + 409 => 'Conflict', + 410 => 'Gone', + 411 => 'Length Required', + 412 => 'Precondition Failed', + 413 => 'Content Too Large', + 414 => 'URI Too Long', + 415 => 'Unsupported Media Type', + 416 => 'Range Not Satisfiable', + 417 => 'Expectation Failed', + 421 => 'Misdirected Request', + 422 => 'Unprocessable Content', + 423 => 'Locked', + 424 => 'Failed Dependency', + 425 => 'Too Early', + 426 => 'Upgrade Required', + 428 => 'Precondition Required', + 429 => 'Too Many Requests', + 431 => 'Request Header Fields Too Large', + 451 => 'Unavailable For Legal Reasons', + 500 => 'Internal Server Error', + 501 => 'Not Implemented', + 502 => 'Bad Gateway', + 503 => 'Service Unavailable', + 504 => 'Gateway Timeout', + 505 => 'HTTP Version Not Supported', + 506 => 'Variant Also Negotiates', + 507 => 'Insufficient Storage', + 508 => 'Loop Detected', + 511 => 'Network Authentication Required' + } + + # Responses with HTTP status codes that should not have an entity body + STATUS_WITH_NO_ENTITY_BODY = Hash[((100..199).to_a << 204 << 304).product([true])] + + SYMBOL_TO_STATUS_CODE = Hash[*HTTP_STATUS_CODES.map { |code, message| + [message.downcase.gsub(/\s|-/, '_').to_sym, code] + }.flatten] + + OBSOLETE_SYMBOLS_TO_STATUS_CODES = { + payload_too_large: 413, + unprocessable_entity: 422, + bandwidth_limit_exceeded: 509, + not_extended: 510 + }.freeze + private_constant :OBSOLETE_SYMBOLS_TO_STATUS_CODES + + OBSOLETE_SYMBOL_MAPPINGS = { + payload_too_large: :content_too_large, + unprocessable_entity: :unprocessable_content + }.freeze + private_constant :OBSOLETE_SYMBOL_MAPPINGS + + def status_code(status) + if status.is_a?(Symbol) + SYMBOL_TO_STATUS_CODE.fetch(status) do + fallback_code = OBSOLETE_SYMBOLS_TO_STATUS_CODES.fetch(status) { raise ArgumentError, "Unrecognized status code #{status.inspect}" } + message = "Status code #{status.inspect} is deprecated and will be removed in a future version of Rack." + if canonical_symbol = OBSOLETE_SYMBOL_MAPPINGS[status] + # message = "#{message} Please use #{canonical_symbol.inspect} instead." + # For now, let's not emit any warning when there is a mapping. + else + warn message, uplevel: 3 + end + fallback_code + end + else + status.to_i + end + end + + PATH_SEPS = Regexp.union(*[::File::SEPARATOR, ::File::ALT_SEPARATOR].compact) + + def clean_path_info(path_info) + parts = path_info.split PATH_SEPS + + clean = [] + + parts.each do |part| + next if part.empty? || part == '.' + part == '..' ? clean.pop : clean << part + end + + clean_path = clean.join(::File::SEPARATOR) + clean_path.prepend("/") if parts.empty? || parts.first.empty? + clean_path + end + + NULL_BYTE = "\0" + + def valid_path?(path) + path.valid_encoding? && !path.include?(NULL_BYTE) + end + + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/version.rb b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/version.rb new file mode 100644 index 00000000..cd2e109d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-3.1.16/lib/rack/version.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +# Copyright (C) 2007-2019 Leah Neukirchen +# +# Rack is freely distributable under the terms of an MIT-style license. +# See MIT-LICENSE or https://opensource.org/licenses/MIT. + +# The Rack main module, serving as a namespace for all core Rack +# modules and classes. +# +# All modules meant for use in your application are autoloaded here, +# so it should be enough just to require 'rack' in your code. + +module Rack + RELEASE = "3.1.16" + + # Return the Rack release as a dotted string. + def self.release + RELEASE + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/History.md b/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/History.md new file mode 100644 index 00000000..0deacecd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/History.md @@ -0,0 +1,389 @@ +## 2.2.0 / 2024-12-23 + +* Bug fixes: + * `Rack::Test::Cookie` now parses cookie parameters using a + case-insensitive approach (Guillaume Malette #349) + +* Minor enhancements: + * Arrays of cookies containing a blank cookie are now handled + correctly when processing responses. (Martin Emde #343) + * `Rack::Test::UploadedFile` no longer uses a finalizer for named + paths to close and unlink the created Tempfile. Tempfile itself + uses a finalizer to close and unlink itself, so there is no + reason for `Rack::Test::UploadedFile` to do so (Jeremy Evans #338) + +## 2.1.0 / 2023-03-14 + +* Breaking changes: + * Digest authentication support, deprecated in 2.0.0, has been + removed (Jeremy Evans #307) + * requiring rack/mock_session, deprecated in 2.0.0, has been removed + (Jeremy Evans #307) + +* Minor enhancements: + * The `original_filename` for `Rack::Test::UploadedFile` can now be + set even if the content of the file comes from a file path + (Stuart Chinery #314) + * Add `Rack::Test::Session#restore_state`, for executing a block + and restoring current state (last request, last response, and + cookies) after the block (Jeremy Evans #316) + * Make `Rack::Test::Methods` support `default_host` method similar to + `app`, which will set the default host used for requests to the app + (Jeremy Evans #317 #318) + * Allow responses to set cookie paths not matching the current + request URI. Such cookies will only be sent for paths matching + the cookie path (Chris Waters #322) + * Ignore leading dot for cookie domains, per RFC 6265 (Stephen Crosby + #329) + * Avoid creating empty multipart body if params is empty in + `Rack::Test::Session#env_for` (Ryunosuke Sato #331) + +## 2.0.2 / 2022-06-28 + +* Bug fixes: + * Fix additional incompatible character encodings error when building + uploaded bodies (Jeremy Evans #311) + +## 2.0.1 / 2022-06-27 + +* Bug fixes: + * Fix incompatible character encodings error when building uploaded + file bodies (Jeremy Evans #308 #309) + +## 2.0.0 / 2022-06-24 + +* Breaking changes: + * Digest authentication support is now deprecated, as it relies on + digest authentication support in rack, which has been deprecated + (Jeremy Evans #294) + * `Rack::Test::Utils.build_primitive_part` no longer handles array + values (Jeremy Evans #292) + * `Rack::Test::Utils` module methods other than `build_nested_query` + and `build_multipart` are now private methods (Jeremy Evans #297) + * `Rack::MockSession` has been combined into `Rack::Test::Session`, + and remains as an alias to `Rack::Test::Session`, but to keep some + backwards compatibility, `Rack::Test::Session.new` will accept a + `Rack::Test::Session` instance and return it (Jeremy Evans #297) + * Previously protected methods in `Rack::Test::Cookie{,Jar}` are now + private methods (Jeremy Evans #297) + * `Rack::Test::Methods` no longer defines `build_rack_mock_session`, + but for backwards compatibility, `build_rack_test_session` will call + `build_rack_mock_session` if it is defined (Jeremy Evans #297) + * `Rack::Test::Methods::METHODS` is no longer defined + (Jeremy Evans #297) + * `Rack::Test::Methods#_current_session_names` has been removed + (Jeremy Evans #297) + * Headers used/accessed by rack-test are now lower case, for rack 3 + compliance (Jeremy Evans #295) + * Frozen literal strings are now used internally, which may break + code that mutates static strings returned by rack-test, if any + (Jeremy Evans #304) + +* Minor enhancements: + * rack-test now works with the rack main branch (what will be rack 3) + (Jeremy Evans #280 #292) + * rack-test only loads the parts of rack it uses when running on the + rack main branch (what will be rack 3) (Jeremy Evans #292) + * Development dependencies have been significantly reduced, and are + now a subset of the development dependencies of rack itself + (Jeremy Evans #292) + * Avoid creating multiple large copies of uploaded file data in + memory (Jeremy Evans #286) + * Specify HTTP/1.0 when submitting requests, to avoid responses with + Transfer-Encoding: chunked (Jeremy Evans #288) + * Support `:query_params` in rack environment for parameters that + are appended to the query string instead of used in the request + body (Jeremy Evans #150 #287) + * Reduce required ruby version to 2.0, since tests run fine on + Ruby 2.0 (Jeremy Evans #292) + * Support :multipart env key for request methods to force multipart + input (Jeremy Evans #303) + * Force multipart input for request methods if content type starts + with multipart (Jeremy Evans #303) + * Improve performance of Utils.build_multipart by using an + append-only design (Jeremy Evans #304) + * Improve performance of Utils.build_nested_query for array values + (Jeremy Evans #304) + +* Bug fixes: + * The `CONTENT_TYPE` of multipart requests is now respected, if it + starts with `multipart/` (Tom Knig #238) + * Work correctly with responses that respond to `to_a` but not + `to_ary` (Sergio Faria #276) + * Raise an ArgumentError instead of a TypeError when providing a + StringIO without an original filename when creating an + UploadedFile (Nuno Correia #279) + * Allow combining both an UploadedFile and a plain string when + building a multipart upload (Mitsuhiro Shibuya #278) + * Fix the generation of filenames with spaces to use path + escaping instead of regular escaping, since path unescaping is + used to decode it (Muir Manders, Jeremy Evans #275 #284) + * Rewind tempfile used for multipart uploads before it is + submitted to the application + (Jeremy Evans, Alexander Dervish #261 #268 #286) + * Fix Rack::Test.encoding_aware_strings to be true only on rack + 1.6+ (Jeremy Evans #292) + * Make Rack::Test::CookieJar#valid? return true/false + (Jeremy Evans #292) + * Cookies without a domain attribute no longer are submitted to + requests for subdomains of that domain, for RFC 6265 + compliance (Jeremy Evans #292) + * Increase required rack version to 1.3, since tests fail on + rack 1.2 and below (Jeremy Evans #293) + +## 1.1.0 / 2018-07-21 + +* Breaking changes: + * None + +* Minor enhancements / new functionality: + * [GitHub] Added configuration for Stale (Per Lundberg #232) + * follow_direct: Include rack.session.options (Mark Edmondson #233) + * [CI] Add simplecov (fatkodima #227) + +* Bug fixes: + * Follow relative locations correctly. (Samuel Williams #230) + +## 1.0.0 / 2018-03-27 + +* Breaking changes: + * Always set CONTENT_TYPE for non-GET requests + (Per Lundberg #223) + +* Minor enhancements / bug fixes: + * Create tempfile using the basename without extension + (Edouard Chin #201) + * Save `session` during `follow_redirect!` + (Alexander Popov #218) + * Document how to use URL params with DELETE method + (Timur Platonov #220) + +## 0.8.3 / 2018-02-27 + +* Bug fixes: + * Do not set Content-Type if params are explicitly set to nil + (Bartek Bułat #212). Fixes #200. + * Fix `UploadedFile#new` regression + (Per Lundberg #215) + +* Minor enhancements + * [CI] Test against Ruby 2.5 (Nicolas Leger #217) + +## 0.8.2 / 2017-11-21 + +* Bug fixes: + * Bugfix for `UploadedFile.new` unintended API breakage. + (Per Lundberg #210) + +## 0.8.0 / 2017-11-20 + +* Known Issue + * In `UploadedFile.new`, when passing e.g. a `Pathname` object, + errors can be raised (eg. `ArgumentError: Missing original_filename + for IO`, or `NoMethodError: undefined method 'size'`) See #207, #209. +* Minor enhancements + * Add a required_ruby_version of >= 2.2.2, similar to rack 2.0.1. + (Samuel Giddins #194) + * Remove new line from basic auth. (Felix Kleinschmidt #185) + * Rubocop fixes (Per Lundberg #196) + * Add how to install rack-test from github to README. (Jun Aruga #189) + * Update CodeClimate badges (Toshimaru #195) + * Add the ability to create Test::UploadedFile instances without + the file system (Adam Milligan #149) + * Add custom_request, remove duplication (Johannes Barre #184) + * README.md: Added note about how to post JSON (Per Lundberg #198) + * README.md: Added version badge (Per Lundberg #199) +* Bug fixes + * Bugfix for Cookies with multiple paths (Kyle Welsby #197) + +## 0.7.0 / 2017-07-10 + +* Major enhancements + * The project URL changed to https://github.com/rack-test/rack-test + (Per Lundberg, Dennis Sivia, Jun Aruga) + * Rack 2 compatible. (Trevor Wennblom #81, Vít Ondruch, Jun Aruga #151) +* Minor enhancements + * Port to RSpec 3. (Murahashi [Matt] Kenichi #70, Antonio Terceiro #134) + * Add Travis CI (Johannes Barre #108, Jun Aruga #161) + * Don't append an ampersand when params are empty (sbilharz, #157) + * Allow symbol access to cookies (Anorlondo448 #156) + * README: Added Travis badge (Olivier Lacan, Per Lundberg #146) + * `Rack::Test::Utils#build_multipart`: Allow passing a third parameter + to force multipart (Koen Punt #142) + * Allow better testing of cookies (Stephen Best #133) + * make `build_multipart` work without mixing in `Rack::Test::Utils` + (Aaron Patterson #131) + * Add license to gemspec (Jordi Massaguer Pla #72, Anatol Pomozov #89, + Anatol Pomozov #90, Johannes Barre #109, Mandaryn #115, + Chris Marshall #120, Robert Reiz #126, Nic Benders #127, Nic Benders #130) + * Feature/bulk pr for readme updates (Patrick Mulder #65, + Troels Knak-Nielsen #74, Jeff Casimir #76) + * Switch README format to Markdown (Dennis Sivia #176) + * Convert History.txt to Markdown (Dennis Sivia #179) + * Stop generating gemspec file. (Jun Aruga #181) + * Fix errors at rake docs and whitespace. (Jun Aruga #183) + * Ensure Rack::Test::UploadedFile closes its tempfile file descriptor + on GC (Michael de Silva #180) + * Change codeclimate URL correctly. (Jun Aruga #186) +* Bug fixes + * Initialize digest_username before using it. (Guo Xiang Tan #116, + John Drago #124, Mike Perham #154) + * Do not set Content-Type for DELETE requests (David Celis #132) + * Adds support for empty arrays in params. (Cedric Röck, Tim Masliuchenko + #125) + * Update README code example quotes to be consistent. (Dmitry Gritsay #112) + * Update README not to recommend installing gem with sudo. (T.J. Schuck #87) + * Set scheme when using ENV to enable SSL (Neil Ang #155) + * Reuse request method and parameters on HTTP 307 redirect. (Martin Mauch + #138) + +## 0.6.3 / 2015-01-09 + +* Minor enhancements + * Expose an env helper for persistently configuring the env as needed + (Darío Javier Cravero #80) + * Expose the tempfile of UploadedFile (Sytse Sijbrandij #67) +* Bug fixes + * Improve support for arrays of hashes in multipart forms (Murray Steele #69) + * Improve test for query strings (Paul Grayson #66) + +## 0.6.2 / 2012-09-27 + +* Minor enhancements + * Support HTTP PATCH method (Marjan Krekoten' #33) + * Preserve the exact query string when possible (Paul Grayson #63) + * Add a #delete method to CookieJar (Paul Grayson #63) +* Bug fixes + * Fix HTTP Digest authentication when the URI has query params + * Don't append default ports to HTTP_HOST (David Lee #57) + +## 0.6.1 / 2011-07-27 + +* Bug fixes + * Fix support for params with arrays in multipart forms (Joel Chippindale) + * Add `respond_to?` to `Rack::Test::UploadedFile` to match `method_missing` (Josh Nichols) + * Set the Referer header on requests issued by follow_redirect! (Ryan Bigg) + +## 0.6.0 / 2011-05-03 + +* Bug fixes + * Add support for HTTP OPTIONS verb (Paolo "Nusco" Perrotta) + * Call #finish on MockResponses if it's available (Aaron Patterson) + * Allow HTTP_HOST to be set via #header (Geoff Buesing) + +## 0.5.7 / 2011-01-01 +* Bug fixes + * If no URI is present, include all cookies (Pratik Naik) + +## 0.5.6 / 2010-09-25 + +* Bug fixes + * Use parse_nested_query for parsing URI like Rack does (Eugene Bolshakov) + * Don't depend on ActiveSupport extension to String (Bryan Helmkamp) + * Do not overwrite HTTP_HOST if it is set (Krekoten' Marjan) + +## 0.5.5 / 2010-09-22 + +* Bug fixes + * Fix encoding of file uploads on Ruby 1.9 (Alan Kennedy) + * Set env["HTTP_HOST"] when making requests (Istvan Hoka) + +## 0.5.4 / 2010-05-26 + +* Bug fixes + * Don't stomp on Content-Type's supplied via #header (Bryan Helmkamp) + * Fixed build_multipart to allow for arrays of files (Louis Rose) + * Don't raise an error if raw cookies contain a blank line (John Reilly) + * Handle parameter names with brackets properly (Tanner Donovan) + +## 0.5.3 / 2009-11-27 + +* Bug fixes + * Fix cookie matching for subdomains (Marcin Kulik) + +## 0.5.2 / 2009-11-13 + +* Bug fixes + * Call close on response body after iteration, not before (Simon Rozet) + * Add missing require for time in cookie_jar.rb (Jerry West) + +## 0.5.1 / 2009-10-27 + +* Bug fixes + * Escape cookie values (John Pignata) + * Close the response body after each request, as per the Rack spec (Elomar França) + +## 0.5.0 / 2009-09-19 + +* Bug fixes + * Set HTTP_X_REQUESTED_WITH in the Rack env when a request is made with :xhr => true (Ben Sales) + * Set headers in the Rack env in HTTP_USER_AGENT form + * Rack::Test now generates no Ruby warnings + +## 0.4.2 / 2009-09-01 + +* Minor enhancements + * Merge in rack/master's build_multipart method which covers additional cases + * Accept raw :params string input and merge it with the query string + * Stringify and upcase request method (e.g. :post => "POST") (Josh Peek) +* Bug fixes + * Properly convert hashes with nil values (e.g. :foo => nil becomes simply "foo", not "foo=") + * Prepend a slash to the URI path if it doesn't start with one (Josh Peek) + * Requiring Rack-Test never modifies the Ruby load path anymore (Josh Peek) + * Fixed using multiple cookies in a string on Ruby 1.8 (Tuomas Kareinen and Hermanni Hyytiälä) + +## 0.4.1 / 2009-08-06 + +* Minor enhancements + * Support initializing a `Rack::Test::Session` with an app in addition to + a `Rack::MockSession` + * Allow CONTENT_TYPE to be specified in the env and not overwritten when + sending a POST or PUT + +## 0.4.0 / 2009-06-25 + +* Minor enhancements + * Expose hook for building `Rack::MockSessions` for frameworks that need + to configure them before use + * Support passing in arrays of raw cookies in addition to a newline + separated string + * Support after_request callbacks in MockSession for things like running + background jobs + * Allow multiple named sessions using with_session + * Initialize `Rack::Test::Sessions` with `Rack::MockSessions` instead of apps. + This change should help integration with other Ruby web frameworks + (like Merb). + * Support sending bodies for PUT requests (Larry Diehl) + +## 0.3.0 / 2009-05-17 + +* Major enhancements + * Ruby 1.9 compatible (Simon Rozet, Michael Fellinger) +* Minor enhancements + * Add `CookieJar#[]` and `CookieJar#[]=` methods + * Make the default host configurable + * Use `Rack::Lint` and fix errors (Simon Rozet) + * Extract `Rack::MockSession` from `Rack::Test::Session` to handle tracking + the last request and response and the cookie jar + * Add #set_cookie and #clear_cookies methods + * Rename #authorize to #basic_authorize (#authorize remains as an alias) + (Simon Rozet) + +## 0.2.0 / 2009-04-26 + +Because `#last_response` is now a `MockResponse` instead of a `Rack::Response`, `#last_response.body` +now returns a string instead of an array. + +* Major enhancements + * Support multipart requests via the UploadedFile class (thanks, Rails) +* Minor enhancements + * Updated for Rack 1.0 + * Don't require rubygems (See http://gist.github.com/54177) + * Support HTTP Digest authentication with the `#digest_authorize` method + * `#last_response` returns a `MockResponse` instead of a Response + (Michael Fellinger) + +## 0.1.0 / 2009-03-02 + +* 1 major enhancement + * Birthday! diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/MIT-LICENSE.txt b/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/MIT-LICENSE.txt new file mode 100644 index 00000000..78b1b579 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/MIT-LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2008-2009 Bryan Helmkamp, Engine Yard Inc. +Copyright (c) 2022 Jeremy Evans + +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 +AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/README.md b/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/README.md new file mode 100644 index 00000000..cfa24e6e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/README.md @@ -0,0 +1,139 @@ +# Rack::Test +[![Gem Version](https://badge.fury.io/rb/rack-test.svg)](https://badge.fury.io/rb/rack-test) + +Code: https://github.com/rack/rack-test + +## Description + +Rack::Test is a small, simple testing API for Rack apps. It can be used on its +own or as a reusable starting point for Web frameworks and testing libraries +to build on. + +## Features + +* Allows for submitting requests and testing responses +* Maintains a cookie jar across requests +* Supports request headers used for subsequent requests +* Follow redirects when requested + +## Examples + +These examples use `test/unit` but it's equally possible to use `rack-test` with +other testing frameworks such as `minitest` or `rspec`. + +```ruby +require "test/unit" +require "rack/test" +require "json" + +class HomepageTest < Test::Unit::TestCase + include Rack::Test::Methods + + def app + lambda { |env| [200, {'content-type' => 'text/plain'}, ['All responses are OK']] } + end + + def test_response_is_ok + # Optionally set headers used for all requests in this spec: + #header 'accept-charset', 'utf-8' + + # First argument is treated as the path + get '/' + + assert last_response.ok? + assert_equal 'All responses are OK', last_response.body + end + + def delete_with_url_params_and_body + # First argument can have a query string + # + # Second argument is used as the parameters for the request, which will be + # included in the request body for non-GET requests. + delete '/?foo=bar', JSON.generate('baz' => 'zot') + end + + def post_with_json + # Third argument is the rack environment to use for the request. The following + # entries in the submitted rack environment are treated specially (in addition + # to options supported by `Rack::MockRequest#env_for`: + # + # :cookie : Set a cookie for the current session before submitting the request. + # + # :query_params : Set parameters for the query string (as opposed to the body). + # Value should be a hash of parameters. + # + # :xhr : Set HTTP_X_REQUESTED_WITH env key to XMLHttpRequest. + post(uri, JSON.generate('baz' => 'zot'), 'CONTENT_TYPE' => 'application/json') + end +end +``` + +`rack-test` will test the app returned by the `app` method. If you are loading middleware +in a `config.ru` file, and want to test that, you should load the Rack app created from +the `config.ru` file: + +```ruby +OUTER_APP = Rack::Builder.parse_file("config.ru").first + +class TestApp < Test::Unit::TestCase + include Rack::Test::Methods + + def app + OUTER_APP + end + + def test_root + get "/" + assert last_response.ok? + end +end +``` + +## Install + +To install the latest release as a gem: + +``` +gem install rack-test +``` + +Or add to your `Gemfile`: + +``` +gem 'rack-test' +``` + +## Contribution + +Contributions are welcome. Please make sure to: + +* Use a regular forking workflow +* Write tests for the new or changed behaviour +* Provide an explanation/motivation in your commit message / PR message +* Ensure `History.md` is updated + +## Authors + +- Contributions from Bryan Helmkamp, Jeremy Evans, Simon Rozet, and others +- Much of the original code was extracted from Merb 1.0's request helper + +## License + +`rack-test` is released under the [MIT License](MIT-LICENSE.txt). + +## Supported platforms + +* Ruby 2.0+ +* JRuby 9.1+ + +## Releasing + +* Bump VERSION in lib/rack/test/version.rb +* Ensure `History.md` is up-to-date, including correct version and date +* `git commit . -m 'Release $VERSION'` +* `git push` +* `git tag -a -m 'Tag the $VERSION release' $VERSION` +* `git push --tags` +* `gem build rack-test.gemspec` +* `gem push rack-test-$VERSION.gem` +* Add a discussion post for the release diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/lib/rack/test.rb b/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/lib/rack/test.rb new file mode 100644 index 00000000..0b519e9c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/lib/rack/test.rb @@ -0,0 +1,382 @@ +# frozen_string_literal: true + +require 'uri' + +# :nocov: +begin + require "rack/version" +rescue LoadError + require "rack" +else + if Rack.release >= '2.3' + require "rack/request" + require "rack/mock" + require "rack/utils" + else + require "rack" + end +end +# :nocov: + +require 'forwardable' + +require_relative 'test/cookie_jar' +require_relative 'test/utils' +require_relative 'test/methods' +require_relative 'test/uploaded_file' +require_relative 'test/version' + +module Rack + module Test + # The default host to use for requests, when a full URI is not + # provided. + DEFAULT_HOST = 'example.org'.freeze + + # The default multipart boundary to use for multipart request bodies + MULTIPART_BOUNDARY = '----------XnJLe9ZIbbGUYtzPQJ16u1'.freeze + + # The starting boundary in multipart requests + START_BOUNDARY = "--#{MULTIPART_BOUNDARY}\r\n".freeze + + # The ending boundary in multipart requests + END_BOUNDARY = "--#{MULTIPART_BOUNDARY}--\r\n".freeze + + # The common base class for exceptions raised by Rack::Test + class Error < StandardError; end + + # Rack::Test::Session handles a series of requests issued to a Rack app. + # It keeps track of the cookies for the session, and allows for setting headers + # and a default rack environment that is used for future requests. + # + # Rack::Test::Session's methods are most often called through Rack::Test::Methods, + # which will automatically build a session when it's first used. + class Session + extend Forwardable + include Rack::Test::Utils + + def self.new(app, default_host = DEFAULT_HOST) # :nodoc: + if app.is_a?(self) + # Backwards compatibility for initializing with Rack::MockSession + app + else + super + end + end + + # The Rack::Test::CookieJar for the cookies for the current session. + attr_accessor :cookie_jar + + # The default host used for the session for when using paths for URIs. + attr_reader :default_host + + # Creates a Rack::Test::Session for a given Rack app or Rack::Test::BasicSession. + # + # Note: Generally, you won't need to initialize a Rack::Test::Session directly. + # Instead, you should include Rack::Test::Methods into your testing context. + # (See README.rdoc for an example) + # + # The following methods are defined via metaprogramming: get, post, put, patch, + # delete, options, and head. Each method submits a request with the given request + # method, with the given URI and optional parameters and rack environment. + # Examples: + # + # # URI only: + # get("/") # GET / + # get("/?foo=bar") # GET /?foo=bar + # + # # URI and parameters + # get("/foo", 'bar'=>'baz') # GET /foo?bar=baz + # post("/foo", 'bar'=>'baz') # POST /foo (bar=baz in request body) + # + # # URI, parameters, and rack environment + # get("/bar", {}, 'CONTENT_TYPE'=>'foo') + # get("/bar", {'foo'=>'baz'}, 'HTTP_ACCEPT'=>'*') + # + # The above methods as well as #request and #custom_request store the Rack::Request + # submitted in #last_request. The methods store a Rack::MockResponse based on the + # response in #last_response. #last_response is also returned by the methods. + # If a block is given, #last_response is also yielded to the block. + def initialize(app, default_host = DEFAULT_HOST) + @env = {} + @app = app + @after_request = [] + @default_host = default_host + @last_request = nil + @last_response = nil + clear_cookies + end + + %w[get post put patch delete options head].each do |method_name| + class_eval(<<-END, __FILE__, __LINE__+1) + def #{method_name}(uri, params = {}, env = {}, &block) + custom_request('#{method_name.upcase}', uri, params, env, &block) + end + END + end + + # Run a block after the each request completes. + def after_request(&block) + @after_request << block + end + + # Replace the current cookie jar with an empty cookie jar. + def clear_cookies + @cookie_jar = CookieJar.new([], @default_host) + end + + # Set a cookie in the current cookie jar. + def set_cookie(cookie, uri = nil) + cookie_jar.merge(cookie, uri) + end + + # Return the last request issued in the session. Raises an error if no + # requests have been sent yet. + def last_request + raise Error, 'No request yet. Request a page first.' unless @last_request + @last_request + end + + # Return the last response received in the session. Raises an error if + # no requests have been sent yet. + def last_response + raise Error, 'No response yet. Request a page first.' unless @last_response + @last_response + end + + # Issue a request to the Rack app for the given URI and optional Rack + # environment. Example: + # + # request "/" + def request(uri, env = {}, &block) + uri = parse_uri(uri, env) + env = env_for(uri, env) + process_request(uri, env, &block) + end + + # Issue a request using the given HTTP verb for the given URI, with optional + # params and rack environment. Example: + # + # custom_request "LINK", "/" + def custom_request(verb, uri, params = {}, env = {}, &block) + uri = parse_uri(uri, env) + env = env_for(uri, env.merge(method: verb.to_s.upcase, params: params)) + process_request(uri, env, &block) + end + + # Set a header to be included on all subsequent requests through the + # session. Use a value of nil to remove a previously configured header. + # + # In accordance with the Rack spec, headers will be included in the Rack + # environment hash in HTTP_USER_AGENT form. Example: + # + # header "user-agent", "Firefox" + def header(name, value) + name = name.upcase + name.tr!('-', '_') + name = "HTTP_#{name}" unless name == 'CONTENT_TYPE' || name == 'CONTENT_LENGTH' + env(name, value) + end + + # Set an entry in the rack environment to be included on all subsequent + # requests through the session. Use a value of nil to remove a previously + # value. Example: + # + # env "rack.session", {:csrf => 'token'} + def env(name, value) + if value.nil? + @env.delete(name) + else + @env[name] = value + end + end + + # Set the username and password for HTTP Basic authorization, to be + # included in subsequent requests in the HTTP_AUTHORIZATION header. + # + # Example: + # basic_authorize "bryan", "secret" + def basic_authorize(username, password) + encoded_login = ["#{username}:#{password}"].pack('m0') + header('Authorization', "Basic #{encoded_login}") + end + + alias authorize basic_authorize + + # Rack::Test will not follow any redirects automatically. This method + # will follow the redirect returned (including setting the Referer header + # on the new request) in the last response. If the last response was not + # a redirect, an error will be raised. + def follow_redirect! + unless last_response.redirect? + raise Error, 'Last response was not a redirect. Cannot follow_redirect!' + end + + if last_response.status == 307 + request_method = last_request.request_method + params = last_request.params + else + request_method = 'GET' + params = {} + end + + # Compute the next location by appending the location header with the + # last request, as per https://tools.ietf.org/html/rfc7231#section-7.1.2 + # Adding two absolute locations returns the right-hand location + next_location = URI.parse(last_request.url) + URI.parse(last_response['Location']) + + custom_request( + request_method, + next_location.to_s, + params, + 'HTTP_REFERER' => last_request.url, + 'rack.session' => last_request.session, + 'rack.session.options' => last_request.session_options + ) + end + + # Yield to the block, and restore the last request, last response, and + # cookie jar to the state they were prior to block execution upon + # exiting the block. + def restore_state + request = @last_request + response = @last_response + cookie_jar = @cookie_jar.dup + after_request = @after_request.dup + + begin + yield + ensure + @last_request = request + @last_response = response + @cookie_jar = cookie_jar + @after_request = after_request + end + end + + private + + # :nocov: + if !defined?(Rack::RELEASE) || Gem::Version.new(Rack::RELEASE) < Gem::Version.new('2.2.2') + def close_body(body) + body.close if body.respond_to?(:close) + end + # :nocov: + else + # close() gets called automatically in newer Rack versions. + def close_body(body) + end + end + + # Normalize URI based on given URI/path and environment. + def parse_uri(path, env) + uri = URI.parse(path) + uri.path = "/#{uri.path}" unless uri.path.start_with?('/') + uri.host ||= @default_host + uri.scheme ||= 'https' if env['HTTPS'] == 'on' + uri + end + + DEFAULT_ENV = { + 'rack.test' => true, + 'REMOTE_ADDR' => '127.0.0.1', + 'SERVER_PROTOCOL' => 'HTTP/1.0', + } + # :nocov: + unless Rack.release >= '2.3' + DEFAULT_ENV['HTTP_VERSION'] = DEFAULT_ENV['SERVER_PROTOCOL'] + end + # :nocov: + DEFAULT_ENV.freeze + private_constant :DEFAULT_ENV + + # Update environment to use based on given URI. + def env_for(uri, env) + env = DEFAULT_ENV.merge(@env).merge!(env) + + env['HTTP_HOST'] ||= [uri.host, (uri.port if uri.port != uri.default_port)].compact.join(':') + env['HTTPS'] = 'on' if URI::HTTPS === uri + env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest' if env[:xhr] + env['REQUEST_METHOD'] ||= env[:method] ? env[:method].to_s.upcase : 'GET' + + params = env.delete(:params) + query_array = [uri.query] + + if env['REQUEST_METHOD'] == 'GET' + # Treat params as query params + if params + append_query_params(query_array, params) + end + elsif !env.key?(:input) + env['CONTENT_TYPE'] ||= 'application/x-www-form-urlencoded' + params ||= {} + multipart = env.has_key?(:multipart) ? env.delete(:multipart) : env['CONTENT_TYPE'].start_with?('multipart/') + + if params.is_a?(Hash) + if !params.empty? && data = build_multipart(params, false, multipart) + env[:input] = data + env['CONTENT_LENGTH'] ||= data.length.to_s + env['CONTENT_TYPE'] = "#{multipart_content_type(env)}; boundary=#{MULTIPART_BOUNDARY}" + else + env[:input] = build_nested_query(params) + end + else + env[:input] = params + end + end + + if query_params = env.delete(:query_params) + append_query_params(query_array, query_params) + end + query_array.compact! + query_array.reject!(&:empty?) + uri.query = query_array.join('&') + + set_cookie(env.delete(:cookie), uri) if env.key?(:cookie) + + Rack::MockRequest.env_for(uri.to_s, env) + end + + # Append a string version of the query params to the array of query params. + def append_query_params(query_array, query_params) + query_params = parse_nested_query(query_params) if query_params.is_a?(String) + query_array << build_nested_query(query_params) + end + + # Return the multipart content type to use based on the environment. + def multipart_content_type(env) + requested_content_type = env['CONTENT_TYPE'] + if requested_content_type.start_with?('multipart/') + requested_content_type + else + 'multipart/form-data' + end + end + + # Submit the request with the given URI and rack environment to + # the mock session. Returns and potentially yields the last response. + def process_request(uri, env) + env['HTTP_COOKIE'] ||= cookie_jar.for(uri) + @last_request = Rack::Request.new(env) + status, headers, body = @app.call(env).to_a + + @last_response = MockResponse.new(status, headers, body, env['rack.errors'].flush) + close_body(body) + cookie_jar.merge(last_response.headers['set-cookie'], uri) + @after_request.each(&:call) + @last_response.finish + + yield @last_response if block_given? + + @last_response + end + end + + # Whether the version of rack in use handles encodings. + def self.encoding_aware_strings? + Rack.release >= '1.6' + end + end + + # For backwards compatibility with 1.1.0 and below + MockSession = Test::Session +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/lib/rack/test/cookie_jar.rb b/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/lib/rack/test/cookie_jar.rb new file mode 100644 index 00000000..d09a5bb5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/lib/rack/test/cookie_jar.rb @@ -0,0 +1,251 @@ +# frozen_string_literal: true + +require 'uri' +require 'time' + +module Rack + module Test + # Represents individual cookies in the cookie jar. This is considered private + # API and behavior of this class can change at any time. + class Cookie # :nodoc: + include Rack::Utils + + # The name of the cookie, will be a string + attr_reader :name + + # The value of the cookie, will be a string or nil if there is no value. + attr_reader :value + + # The raw string for the cookie, without options. Will generally be in + # name=value format is name and value are provided. + attr_reader :raw + + def initialize(raw, uri = nil, default_host = DEFAULT_HOST) + @default_host = default_host + uri ||= default_uri + + # separate the name / value pair from the cookie options + @raw, options = raw.split(/[;,] */n, 2) + + @name, @value = parse_query(@raw, ';').to_a.first + @options = Hash[parse_query(options, ';').map { |k, v| [k.downcase, v] }] + + if domain = @options['domain'] + @exact_domain_match = false + domain[0] = '' if domain[0] == '.' + else + # If the domain attribute is not present in the cookie, + # the domain must match exactly. + @exact_domain_match = true + @options['domain'] = (uri.host || default_host) + end + + # Set the path for the cookie to the directory containing + # the request if it isn't set. + @options['path'] ||= uri.path.sub(/\/[^\/]*\Z/, '') + end + + # Wether the given cookie can replace the current cookie in the cookie jar. + def replaces?(other) + [name.downcase, domain, path] == [other.name.downcase, other.domain, other.path] + end + + # Whether the cookie has a value. + def empty? + @value.nil? || @value.empty? + end + + # The explicit or implicit domain for the cookie. + def domain + @options['domain'] + end + + # Whether the cookie has the secure flag, indicating it can only be sent over + # an encrypted connection. + def secure? + @options.key?('secure') + end + + # Whether the cookie has the httponly flag, indicating it is not available via + # a javascript API. + def http_only? + @options.key?('httponly') + end + + # The explicit or implicit path for the cookie. + def path + ([*@options['path']].first.split(',').first || '/').strip + end + + # A Time value for when the cookie expires, if the expires option is set. + def expires + Time.parse(@options['expires']) if @options['expires'] + end + + # Whether the cookie is currently expired. + def expired? + expires && expires < Time.now + end + + # Whether the cookie is valid for the given URI. + def valid?(uri) + uri ||= default_uri + + uri.host = @default_host if uri.host.nil? + + !!((!secure? || (secure? && uri.scheme == 'https')) && + uri.host =~ Regexp.new("#{'^' if @exact_domain_match}#{Regexp.escape(domain)}$", Regexp::IGNORECASE)) + end + + # Cookies that do not match the URI will not be sent in requests to the URI. + def matches?(uri) + !expired? && valid?(uri) && uri.path.start_with?(path) + end + + # Order cookies by name, path, and domain. + def <=>(other) + [name, path, domain.reverse] <=> [other.name, other.path, other.domain.reverse] + end + + # A hash of cookie options, including the cookie value, but excluding the cookie name. + def to_h + hash = @options.merge( + 'value' => @value, + 'HttpOnly' => http_only?, + 'secure' => secure? + ) + hash.delete('httponly') + hash + end + alias to_hash to_h + + private + + # The default URI to use for the cookie, including just the host. + def default_uri + URI.parse('//' + @default_host + '/') + end + end + + # Represents all cookies for a session, handling adding and + # removing cookies, and finding which cookies apply to a given + # request. This is considered private API and behavior of this + # class can change at any time. + class CookieJar # :nodoc: + DELIMITER = '; '.freeze + + def initialize(cookies = [], default_host = DEFAULT_HOST) + @default_host = default_host + @cookies = cookies.sort! + end + + # Ensure the copy uses a distinct cookies array. + def initialize_copy(other) + super + @cookies = @cookies.dup + end + + # Return the value for first cookie with the given name, or nil + # if no such cookie exists. + def [](name) + name = name.to_s + @cookies.each do |cookie| + return cookie.value if cookie.name == name + end + nil + end + + # Set a cookie with the given name and value in the + # cookie jar. + def []=(name, value) + merge("#{name}=#{Rack::Utils.escape(value)}") + end + + # Return the first cookie with the given name, or nil if + # no such cookie exists. + def get_cookie(name) + @cookies.each do |cookie| + return cookie if cookie.name == name + end + nil + end + + # Delete all cookies with the given name from the cookie jar. + def delete(name) + @cookies.reject! do |cookie| + cookie.name == name + end + nil + end + + # Add a string of raw cookie information to the cookie jar, + # if the cookie is valid for the given URI. + # Cookies should be separated with a newline. + def merge(raw_cookies, uri = nil) + return unless raw_cookies + + raw_cookies = raw_cookies.split("\n") if raw_cookies.is_a? String + + raw_cookies.each do |raw_cookie| + next if raw_cookie.empty? + cookie = Cookie.new(raw_cookie, uri, @default_host) + self << cookie if cookie.valid?(uri) + end + end + + # Add a Cookie to the cookie jar. + def <<(new_cookie) + @cookies.reject! do |existing_cookie| + new_cookie.replaces?(existing_cookie) + end + + @cookies << new_cookie + @cookies.sort! + end + + # Return a raw cookie string for the cookie header to + # use for the given URI. + def for(uri) + buf = String.new + delimiter = nil + + each_cookie_for(uri) do |cookie| + if delimiter + buf << delimiter + else + delimiter = DELIMITER + end + buf << cookie.raw + end + + buf + end + + # Return a hash cookie names and cookie values for cookies in the jar. + def to_hash + cookies = {} + + @cookies.each do |cookie| + cookies[cookie.name] = cookie.value + end + + cookies + end + + private + + # Yield each cookie that matches for the URI. + # + # The cookies are sorted by most specific first. So, we loop through + # all the cookies in order and add it to a hash by cookie name if + # the cookie can be sent to the current URI. It's added to the hash + # so that when we are done, the cookies will be unique by name and + # we'll have grabbed the most specific to the URI. + def each_cookie_for(uri) + @cookies.each do |cookie| + yield cookie if !uri || cookie.matches?(uri) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/lib/rack/test/methods.rb b/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/lib/rack/test/methods.rb new file mode 100644 index 00000000..a30d02d4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/lib/rack/test/methods.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +require 'forwardable' + +module Rack + module Test + # This module serves as the primary integration point for using Rack::Test + # in a testing environment. It depends on an app method being defined in the + # same context, and provides the Rack::Test API methods (see Rack::Test::Session + # for their documentation). It defines the following methods that are delegated + # to the current session: :request, :get, :post, :put, :patch, :delete, :options, + # :head, :custom_request, :follow_redirect!, :header, :env, :set_cookie, + # :clear_cookies, :authorize, :basic_authorize, :last_response, and :last_request. + # + # Example: + # + # class HomepageTest < Test::Unit::TestCase + # include Rack::Test::Methods + # + # def app + # MyApp + # end + # end + module Methods + extend Forwardable + + # Return the existing session with the given name, or a new + # rack session. Always use a new session if name is nil. + def rack_test_session(name = :default) # :nodoc: + return build_rack_test_session(name) unless name + + @_rack_test_sessions ||= {} + @_rack_test_sessions[name] ||= build_rack_test_session(name) + end + + # For backwards compatibility with older rack-test versions. + alias rack_mock_session rack_test_session # :nodoc: + + # Create a new Rack::Test::Session for #app. + def build_rack_test_session(_name) # :nodoc: + if respond_to?(:build_rack_mock_session, true) + # Backwards compatibility for capybara + build_rack_mock_session + else + if respond_to?(:default_host) + Session.new(app, default_host) + else + Session.new(app) + end + end + end + + # Return the currently actively session. This is the session to + # which the delegated methods are sent. + def current_session + @_rack_test_current_session ||= rack_test_session + end + + # Create a new session (or reuse an existing session with the given name), + # and make it the current session for the given block. + def with_session(name) + session = _rack_test_current_session + yield(@_rack_test_current_session = rack_test_session(name)) + ensure + @_rack_test_current_session = session + end + + def_delegators(:current_session, + :request, + :get, + :post, + :put, + :patch, + :delete, + :options, + :head, + :custom_request, + :follow_redirect!, + :header, + :env, + :set_cookie, + :clear_cookies, + :authorize, + :basic_authorize, + :last_response, + :last_request, + ) + + # Private accessor to avoid uninitialized instance variable warning in Ruby 2.* + attr_accessor :_rack_test_current_session + private :_rack_test_current_session + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/lib/rack/test/uploaded_file.rb b/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/lib/rack/test/uploaded_file.rb new file mode 100644 index 00000000..5be6dc7e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/lib/rack/test/uploaded_file.rb @@ -0,0 +1,99 @@ +# frozen_string_literal: true + +require 'fileutils' +require 'tempfile' +require 'stringio' + +module Rack + module Test + # Wraps a Tempfile with a content type. Including one or more UploadedFile's + # in the params causes Rack::Test to build and issue a multipart request. + # + # Example: + # post "/photos", "file" => Rack::Test::UploadedFile.new("me.jpg", "image/jpeg") + class UploadedFile + # The filename, *not* including the path, of the "uploaded" file + attr_reader :original_filename + + # The tempfile + attr_reader :tempfile + + # The content type of the "uploaded" file + attr_accessor :content_type + + # Creates a new UploadedFile instance. + # + # Arguments: + # content :: is a path to a file, or an {IO} or {StringIO} object representing the content. + # content_type :: MIME type of the file + # binary :: Whether the file should be set to binmode (content treated as binary). + # original_filename :: The filename to use for the file. Required if content is StringIO, optional override if not + def initialize(content, content_type = 'text/plain', binary = false, original_filename: nil) + @content_type = content_type + @original_filename = original_filename + + case content + when StringIO + initialize_from_stringio(content) + else + initialize_from_file_path(content) + end + + @tempfile.binmode if binary + end + + # The path to the tempfile. Will not work if the receiver's content is from a StringIO. + def path + tempfile.path + end + alias local_path path + + # Delegate all methods not handled to the tempfile. + def method_missing(method_name, *args, &block) + tempfile.public_send(method_name, *args, &block) + end + + # Append to given buffer in 64K chunks to avoid multiple large + # copies of file data in memory. Rewind tempfile before and + # after to make sure all data in tempfile is appended to the + # buffer. + def append_to(buffer) + tempfile.rewind + + buf = String.new + buffer << tempfile.readpartial(65_536, buf) until tempfile.eof? + + tempfile.rewind + + nil + end + + def respond_to_missing?(method_name, include_private = false) #:nodoc: + tempfile.respond_to?(method_name, include_private) || super + end + + private + + # Use the StringIO as the tempfile. + def initialize_from_stringio(stringio) + raise(ArgumentError, 'Missing `original_filename` for StringIO object') unless @original_filename + + @tempfile = stringio + end + + # Create a tempfile and copy the content from the given path into the tempfile, optionally renaming if + # original_filename has been set. + def initialize_from_file_path(path) + raise "#{path} file does not exist" unless ::File.exist?(path) + + @original_filename ||= ::File.basename(path) + extension = ::File.extname(@original_filename) + + @tempfile = Tempfile.new([::File.basename(@original_filename, extension), extension]) + @tempfile.set_encoding(Encoding::BINARY) + + FileUtils.copy_file(path, @tempfile.path) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/lib/rack/test/utils.rb b/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/lib/rack/test/utils.rb new file mode 100644 index 00000000..a79a8e7a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/lib/rack/test/utils.rb @@ -0,0 +1,156 @@ +# frozen_string_literal: true + +module Rack + module Test + module Utils # :nodoc: + include Rack::Utils + extend self + + # Build a query string for the given value and prefix. The value + # can be an array or hash of parameters. + def build_nested_query(value, prefix = nil) + case value + when Array + if value.empty? + "#{prefix}[]=" + else + prefix += "[]" unless unescape(prefix).end_with?('[]') + value.map do |v| + build_nested_query(v, prefix.to_s) + end.join('&') + end + when Hash + value.map do |k, v| + build_nested_query(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k)) + end.join('&') + when NilClass + prefix.to_s + else + "#{prefix}=#{escape(value)}" + end + end + + # Build a multipart body for the given params. + def build_multipart(params, _first = true, multipart = false) + raise ArgumentError, 'value must be a Hash' unless params.is_a?(Hash) + + unless multipart + query = lambda { |value| + case value + when Array + value.each(&query) + when Hash + value.values.each(&query) + when UploadedFile + multipart = true + end + } + params.values.each(&query) + return nil unless multipart + end + + params = normalize_multipart_params(params, true) + + buffer = String.new + build_parts(buffer, params) + buffer + end + + private + + # Return a flattened hash of parameter values based on the given params. + def normalize_multipart_params(params, first=false) + flattened_params = {} + + params.each do |key, value| + k = first ? key.to_s : "[#{key}]" + + case value + when Array + value.map do |v| + if v.is_a?(Hash) + nested_params = {} + normalize_multipart_params(v).each do |subkey, subvalue| + nested_params[subkey] = subvalue + end + (flattened_params["#{k}[]"] ||= []) << nested_params + else + flattened_params["#{k}[]"] = value + end + end + when Hash + normalize_multipart_params(value).each do |subkey, subvalue| + flattened_params[k + subkey] = subvalue + end + else + flattened_params[k] = value + end + end + + flattened_params + end + + # Build the multipart content for uploading. + def build_parts(buffer, parameters) + _build_parts(buffer, parameters) + buffer << END_BOUNDARY + end + + # Append each multipart parameter value to the buffer. + def _build_parts(buffer, parameters) + parameters.map do |name, value| + if name =~ /\[\]\Z/ && value.is_a?(Array) && value.all? { |v| v.is_a?(Hash) } + value.each do |hash| + new_value = {} + hash.each { |k, v| new_value[name + k] = v } + _build_parts(buffer, new_value) + end + else + [value].flatten.map do |v| + if v.respond_to?(:original_filename) + build_file_part(buffer, name, v) + else + build_primitive_part(buffer, name, v) + end + end + end + end + end + + # Append the multipart fragment for a parameter that isn't a file upload to the buffer. + def build_primitive_part(buffer, parameter_name, value) + buffer << + START_BOUNDARY << + "content-disposition: form-data; name=\"" << + parameter_name.to_s.b << + "\"\r\n\r\n" << + value.to_s.b << + "\r\n" + buffer + end + + # Append the multipart fragment for a parameter that is a file upload to the buffer. + def build_file_part(buffer, parameter_name, uploaded_file) + buffer << + START_BOUNDARY << + "content-disposition: form-data; name=\"" << + parameter_name.to_s.b << + "\"; filename=\"" << + escape_path(uploaded_file.original_filename).b << + "\"\r\ncontent-type: " << + uploaded_file.content_type.to_s.b << + "\r\ncontent-length: " << + uploaded_file.size.to_s.b << + "\r\n\r\n" + + # Handle old versions of Capybara::RackTest::Form::NilUploadedFile + if uploaded_file.respond_to?(:set_encoding) + uploaded_file.set_encoding(Encoding::BINARY) + uploaded_file.append_to(buffer) + end + + buffer << "\r\n" + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/lib/rack/test/version.rb b/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/lib/rack/test/version.rb new file mode 100644 index 00000000..f7e7462e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rack-test-2.2.0/lib/rack/test/version.rb @@ -0,0 +1,5 @@ +module Rack + module Test + VERSION = '2.2.0'.freeze + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/Changelog.md b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/Changelog.md new file mode 100644 index 00000000..8a678e1a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/Changelog.md @@ -0,0 +1,101 @@ +# Rainbow changelog + +## 3.1.0 (2020-08-26) + +- added `cross_out` aka `strike` +- hexadecimal color names supported better, see #83 +- gemspec: list files using a Ruby expression, avoiding git + +## 3.0.0 (2017-11-29) + +* added String refinement +* added new `Rainbow.uncolor` method +* dropped MRI 1.9.3 compatibility +* dropped MRI 2.0 compatibility +* removed Rake dependency + +## 2.2.2 (2017-04-21) + +* added explicit rake dependency to fix installation issue + +## 2.2.1 (2016-12-28) + +* fixed gem installation (2.2.0 was a broken release) + +## 2.2.0 (2016-12-27) + +* improved Windows support +* added Ruby 2.4 support +* added `bold` alias method for `bright` + +## 2.1.0 (2016-01-24) + +* added X11 color support +* fixed `require` issue when rainbow is used as a dependency in another gem +* improved Windows support + +## 2.0.0 (2014-01-24) + +* disable string mixin by default + +## 1.99.2 (2014-01-24) + +* bring back ruby 1.8 support + +## 1.99.1 (2013-12-28) + +* drop support for ruby 1.8 +* `require "rainbow/string"` -> `require "rainbow/ext/string"` +* custom rainbow wrapper instances (with separate enabled/disabled state) +* shortcut methods for changing text color (`Rainbow("foo").red`) + +## 1.99.0 (2013-12-26) + +* preparation for dropping String monkey patching +* `require "rainbow/string"` if you want to use monkey patched String +* introduction of Rainbow() wrapper +* support for MRI 1.8.7, 1.9.2, 1.9.3, 2.0 and 2.1, JRuby and Rubinius +* deprecation of Sickill::Rainbow namespace (use Rainbow.enabled = true instead) + +## 1.1.4 (2012-4-28) + +* option for forcing coloring even when STDOUT is not a TTY (CLICOLOR_FORCE env var) +* fix for frozen strings + +## 1.1.3 (2011-12-6) + +* improved compatibility with MRI 1.8.7 +* fix for regression with regards to original string mutation + +## 1.1.2 (2011-11-13) + +* improved compatibility with MRI 1.9.3 + +## 1.1.1 (2011-2-7) + +* improved Windows support + +## 1.1 (2010-6-7) + +* option for enabling/disabling of escape code wrapping +* auto-disabling when STDOUT is not a TTY + +## 1.0.4 (2009-11-27) + +* support for 256 colors + +## 1.0.3 (2009-7-26) + +* rainbow methods don't mutate the original string object anymore + +## 1.0.2 (2009-5-15) + +* improved support for ruby 1.8.6 and 1.9.1 + +## 1.0.1 (2009-3-19) + +* Windows support + +## 1.0.0 (2008-7-21) + +* initial version diff --git a/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/LICENSE b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/LICENSE new file mode 100644 index 00000000..1330bc62 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) Marcin Kulik + +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 AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/README.markdown b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/README.markdown new file mode 100644 index 00000000..cbc0bf37 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/README.markdown @@ -0,0 +1,227 @@ +# Rainbow + +[![Gem Version](https://badge.fury.io/rb/rainbow.svg)](https://rubygems.org/gems/rainbow) +[![Build Status](https://travis-ci.org/sickill/rainbow.svg?branch=master)](https://travis-ci.org/sickill/rainbow) +[![Build status](https://ci.appveyor.com/api/projects/status/vq4acb2c38642s5q?svg=true)](https://ci.appveyor.com/project/sickill/rainbow) +[![Code Climate](https://codeclimate.com/github/sickill/rainbow.svg)](https://codeclimate.com/github/sickill/rainbow) +[![Coverage Status](https://coveralls.io/repos/sickill/rainbow/badge.svg)](https://coveralls.io/r/sickill/rainbow) + +Rainbow is a ruby gem for colorizing printed text on ANSI terminals. + +It provides a string presenter object, which adds several methods to your +strings for wrapping them in [ANSI escape +codes](http://en.wikipedia.org/wiki/ANSI_escape_code). These codes when printed +in a terminal change text attributes like text color, background color, +intensity etc. + +## Usage + +To make your string colored wrap it with `Rainbow()` presenter and call +`.color()` on it. + +### Example + +```ruby +require 'rainbow' + +puts Rainbow("this is red").red + " and " + Rainbow("this on yellow bg").bg(:yellow) + " and " + Rainbow("even bright underlined!").underline.bright + +# => "\e[31mthis is red\e[0m and \e[43mthis on yellow bg\e[0m and \e[4m\e[1meven bright underlined!\e[0m" +``` + +![Screenshot of the previous code in a terminal](https://user-images.githubusercontent.com/132/132943811-93747cc5-bdaf-43a2-a1a4-a1f18e805eba.png) + +Or, [watch this video example](https://asciinema.org/a/J928KpHoUQ0sl54ulOSOLE71E?rows=20&speed=2.5) + +### Rainbow presenter API + +Rainbow presenter adds the following methods to presented string: + +* `color(c)` (with `foreground`, and `fg` aliases) +* `background(c)` (with `bg` alias) +* `bright` +* `underline` +* `blink` +* `inverse` +* `hide` +* `faint` (not well supported by terminal emulators) +* `italic` (not well supported by terminal emulators) +* `cross_out`, `strike` + +Text color can also be changed by calling a method named by a color: + +* `black` +* `red` +* `green` +* `yellow` +* `blue` +* `magenta` +* `cyan` +* `white` +* `aqua` +* `silver` +* `aliceblue` +* `indianred` + +All of the methods return `self` (the presenter object) so you can chain method +calls: + +```ruby +Rainbow("hola!").blue.bright.underline +``` + +### Refinement + +If you want to use the Refinements version, you can: + +```ruby +require 'rainbow/refinement' +using Rainbow +puts "Hi!".green +``` + +Here's an IRB session example: + +``` +>> 'Hello, World!'.blue.bright.underline +NoMethodError: undefined method `blue' for "Hello, World!":String + (ripl):1:in `
' +>> using Rainbow +=> main +>> 'Hello, World!'.blue.bright.underline +=> "\e[34m\e[1m\e[4mHello, World!\e[0m" +``` + +### Color specification + +Both `color` and `background` accept color specified in any +of the following ways: + +* ANSI color number (where 0 is black, 1 is red, 2 is green and so on): + `Rainbow("hello").color(1)` + +* [ANSI color](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors) name or [X11 color](https://en.wikipedia.org/wiki/X11_color_names) name as a symbol: + `Rainbow("hello").color(:yellow)`. + This can be simplified to `Rainbow("hello").yellow` + + See [Color list](#user-content-color-list) for all available color names. + Note that ANSI colors can be changed in accordance with terminal setting. + But X11 color is just a syntax sugar for RGB triplet. So you always see what you specified. + +* RGB triplet as separate values in the range 0-255: + `Rainbow("hello").color(115, 23, 98)` + +* RGB triplet as a hex string: + `Rainbow("hello").color("FFC482")` or `Rainbow("hello").color("#FFC482")` + +When you specify a color with a RGB triplet rainbow finds the nearest match +from 256 colors palette. Note that it requires a 256-colors capable terminal to +display correctly. + +#### Example: Choose a random color + +You can pick a random color with Rainbow, it's a one-liner: + +```ruby +colors = Range.new(0,7).to_a +"whoop dee doop".chars.map { |char| Rainbow(char).color(colors.sample) }.join +# => "\e[36mw\e[0m\e[37mh\e[0m\e[34mo\e[0m\e[34mo\e[0m\e[37mp\e[0m\e[34m \e[0m\e[36md\e[0m\e[33me\e[0m\e[34me\e[0m\e[37m \e[0m\e[32md\e[0m\e[35mo\e[0m\e[33mo\e[0m\e[36mp\e[0m" + +colors = [:aliceblue, :antiquewhite, :aqua, :aquamarine, :azure, :beige, :bisque, :blanchedalmond, :blueviolet] +"whoop dee doop".chars.map { |char| Rainbow(char).color(colors.sample) }.join +# => "\e[38;5;135mw\e[0m\e[38;5;230mh\e[0m\e[38;5;231mo\e[0m\e[38;5;135mo\e[0m\e[38;5;231mp\e[0m\e[38;5;231m \e[0m\e[38;5;122md\e[0m\e[38;5;231me\e[0m\e[38;5;231me\e[0m\e[38;5;230m \e[0m\e[38;5;122md\e[0m\e[38;5;51mo\e[0m\e[38;5;51mo\e[0m\e[38;5;51mp\e[0m" +``` + +### Configuration + +Rainbow can be enabled/disabled globally by setting: + +```ruby +Rainbow.enabled = true/false +``` + +When disabled all the methods return an unmodified string +(`Rainbow("hello").red == "hello"`). + +It's enabled by default, unless STDOUT/STDERR is not a TTY or a terminal is +dumb. + +### Advanced usage + +`Rainbow()` and `Rainbow.enabled` operate on the global Rainbow wrapper +instance. If you would like to selectively enable/disable coloring in separate +parts of your application you can get a new Rainbow wrapper instance for each +of them and control the state of coloring during the runtime. + +```ruby +rainbow_one = Rainbow.new +rainbow_two = Rainbow.new + +rainbow_one.enabled = false + +Rainbow("hello").red # => "\e[31mhello\e[0m" ("hello" if not on TTY) +rainbow_one.wrap("hello").red # => "hello" +rainbow_two.wrap("hello").red # => "\e[31mhello\e[0m" ("hello" if not on TTY) +``` + +By default each new instance inherits enabled/disabled state from the global +`Rainbow.enabled`. + +This feature comes handy for example when you have multiple output formatters +in your application and some of them print to a terminal but others write to a +file. Normally rainbow would detect that STDIN/STDERR is a TTY and would +colorize all the strings, even the ones that go through file writing +formatters. You can easily solve that by disabling coloring for the Rainbow +instances that are used by formatters with file output. + +## Installation + +Add it to your Gemfile: + +```ruby +gem 'rainbow' +``` + +Or just install it via rubygems: + +```ruby +gem install rainbow +``` + +## Color list + +### ANSI colors + +`black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white` + +### X11 colors + +`aliceblue`, `antiquewhite`, `aqua`, `aquamarine`, `azure`, `beige`, `bisque`, +`blanchedalmond`, `blueviolet`, `brown`, `burlywood`, `cadetblue`, `chartreuse`, +`chocolate`, `coral`, `cornflower`, `cornsilk`, `crimson`, `darkblue`, +`darkcyan`, `darkgoldenrod`, `darkgray`, `darkgreen`, `darkkhaki`, +`darkmagenta`, `darkolivegreen`, `darkorange`, `darkorchid`, `darkred`, +`darksalmon`, `darkseagreen`, `darkslateblue`, `darkslategray`, `darkturquoise`, +`darkviolet`, `deeppink`, `deepskyblue`, `dimgray`, `dodgerblue`, `firebrick`, +`floralwhite`, `forestgreen`, `fuchsia`, `gainsboro`, `ghostwhite`, `gold`, +`goldenrod`, `gray`, `greenyellow`, `honeydew`, `hotpink`, `indianred`, +`indigo`, `ivory`, `khaki`, `lavender`, `lavenderblush`, `lawngreen`, +`lemonchiffon`, `lightblue`, `lightcoral`, `lightcyan`, `lightgoldenrod`, +`lightgray`, `lightgreen`, `lightpink`, `lightsalmon`, `lightseagreen`, +`lightskyblue`, `lightslategray`, `lightsteelblue`, `lightyellow`, `lime`, +`limegreen`, `linen`, `maroon`, `mediumaquamarine`, `mediumblue`, +`mediumorchid`, `mediumpurple`, `mediumseagreen`, `mediumslateblue`, +`mediumspringgreen`, `mediumturquoise`, `mediumvioletred`, `midnightblue`, +`mintcream`, `mistyrose`, `moccasin`, `navajowhite`, `navyblue`, `oldlace`, +`olive`, `olivedrab`, `orange`, `orangered`, `orchid`, `palegoldenrod`, +`palegreen`, `paleturquoise`, `palevioletred`, `papayawhip`, `peachpuff`, +`peru`, `pink`, `plum`, `powderblue`, `purple`, `rebeccapurple`, `rosybrown`, +`royalblue`, `saddlebrown`, `salmon`, `sandybrown`, `seagreen`, `seashell`, +`sienna`, `silver`, `skyblue`, `slateblue`, `slategray`, `snow`, `springgreen`, +`steelblue`, `tan`, `teal`, `thistle`, `tomato`, `turquoise`, `violet`, +`webgray`, `webgreen`, `webmaroon`, `webpurple`, `wheat`, `whitesmoke`, +`yellowgreen` + +## Authors + +[Marcin Kulik](http://ku1ik.com/) and [great open-source contributors](https://github.com/sickill/rainbow/graphs/contributors). diff --git a/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow.rb b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow.rb new file mode 100644 index 00000000..7fa371ff --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require_relative 'rainbow/global' + +module Rainbow + def self.new + Wrapper.new(global.enabled) + end + + self.enabled = false unless STDOUT.tty? && STDERR.tty? + self.enabled = false if ENV['TERM'] == 'dumb' + self.enabled = true if ENV['CLICOLOR_FORCE'] == '1' +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/color.rb b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/color.rb new file mode 100644 index 00000000..74ec3e38 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/color.rb @@ -0,0 +1,150 @@ +# frozen_string_literal: true + +module Rainbow + class Color + attr_reader :ground + + def self.build(ground, values) + unless [1, 3].include?(values.size) + raise ArgumentError, + "Wrong number of arguments for color definition, should be 1 or 3" + end + + color = values.size == 1 ? values.first : values + + case color + # NOTE: Properly handle versions before/after Ruby 2.4.0. + # Ruby 2.4+ unifies Fixnum & Bignum into Integer. + # However previous versions would still use Fixnum. + # To avoid missing `Fixnum` input, call `0.class` which would + # return either `Integer` or `Fixnum`. + when 0.class + Indexed.new(ground, color) + when Symbol + if Named.color_names.include?(color) + Named.new(ground, color) + elsif X11Named.color_names.include?(color) + X11Named.new(ground, color) + else + raise ArgumentError, + "Unknown color name, valid names: " + + (Named.color_names + X11Named.color_names).join(', ') + end + when Array + RGB.new(ground, *color) + when String + RGB.new(ground, *parse_hex_color(color)) + end + end + + def self.parse_hex_color(hex) + unless hex =~ /^#?[a-f0-9]{6}/i + raise ArgumentError, + "Invalid hexadecimal RGB triplet. Valid format: /^#?[a-f0-9]{6}/i" + end + + hex = hex.sub(/^#/, '') + r = hex[0..1].to_i(16) + g = hex[2..3].to_i(16) + b = hex[4..5].to_i(16) + + [r, g, b] + end + + class Indexed < Color + attr_reader :num + + def initialize(ground, num) + @ground = ground + @num = num + end + + def codes + code = num + (ground == :foreground ? 30 : 40) + + [code] + end + end + + class Named < Indexed + NAMES = { + black: 0, + red: 1, + green: 2, + yellow: 3, + blue: 4, + magenta: 5, + cyan: 6, + white: 7, + default: 9 + }.freeze + + def self.color_names + NAMES.keys + end + + def self.valid_names + color_names.join(', ') + end + + def initialize(ground, name) + unless Named.color_names.include?(name) + raise ArgumentError, + "Unknown color name, valid names: #{self.class.valid_names}" + end + + super(ground, NAMES[name]) + end + end + + class RGB < Indexed + attr_reader :r, :g, :b + + def self.to_ansi_domain(value) + (6 * (value / 256.0)).to_i + end + + def initialize(ground, *values) + if values.min.negative? || values.max > 255 + raise ArgumentError, "RGB value outside 0-255 range" + end + + super(ground, 8) + @r, @g, @b = values + end + + def codes + super + [5, code_from_rgb] + end + + private + + def code_from_rgb + 16 + self.class.to_ansi_domain(r) * 36 + + self.class.to_ansi_domain(g) * 6 + + self.class.to_ansi_domain(b) + end + end + + class X11Named < RGB + include X11ColorNames + + def self.color_names + NAMES.keys + end + + def self.valid_names + color_names.join(', ') + end + + def initialize(ground, name) + unless X11Named.color_names.include?(name) + raise ArgumentError, + "Unknown color name, valid names: #{self.class.valid_names}" + end + + super(ground, *NAMES[name]) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/ext/string.rb b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/ext/string.rb new file mode 100644 index 00000000..aee2fd6c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/ext/string.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +require 'rainbow' + +module Rainbow + module Ext + module String + module InstanceMethods + def foreground(*color) + Rainbow(self).foreground(*color) + end + + alias color foreground + alias colour foreground + + def background(*color) + Rainbow(self).background(*color) + end + + def reset + Rainbow(self).reset + end + + def bright + Rainbow(self).bright + end + + def faint + Rainbow(self).faint + end + + def italic + Rainbow(self).italic + end + + def underline + Rainbow(self).underline + end + + def blink + Rainbow(self).blink + end + + def inverse + Rainbow(self).inverse + end + + def hide + Rainbow(self).hide + end + + def cross_out + Rainbow(self).cross_out + end + + alias strike cross_out + end + end + end +end + +class String + include Rainbow::Ext::String::InstanceMethods +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/global.rb b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/global.rb new file mode 100644 index 00000000..08599bfa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/global.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require_relative 'wrapper' + +module Rainbow + def self.global + @global ||= Wrapper.new + end + + def self.enabled + global.enabled + end + + def self.enabled=(value) + global.enabled = value + end + + def self.uncolor(string) + StringUtils.uncolor(string) + end +end + +def Rainbow(string) + Rainbow.global.wrap(string.to_s) +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/null_presenter.rb b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/null_presenter.rb new file mode 100644 index 00000000..104738f2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/null_presenter.rb @@ -0,0 +1,100 @@ +# frozen_string_literal: true + +module Rainbow + class NullPresenter < ::String + def color(*_values) + self + end + + def background(*_values) + self + end + + def reset + self + end + + def bright + self + end + + def faint + self + end + + def italic + self + end + + def underline + self + end + + def blink + self + end + + def inverse + self + end + + def hide + self + end + + def cross_out + self + end + + def black + self + end + + def red + self + end + + def green + self + end + + def yellow + self + end + + def blue + self + end + + def magenta + self + end + + def cyan + self + end + + def white + self + end + + def method_missing(method_name, *args) + if Color::X11Named.color_names.include?(method_name) && args.empty? + self + else + super + end + end + + def respond_to_missing?(method_name, *args) + Color::X11Named.color_names.include?(method_name) && args.empty? || super + end + + alias foreground color + alias fg color + alias bg background + alias bold bright + alias dark faint + alias strike cross_out + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/presenter.rb b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/presenter.rb new file mode 100644 index 00000000..753f2736 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/presenter.rb @@ -0,0 +1,144 @@ +# frozen_string_literal: true + +require_relative 'string_utils' +require_relative 'x11_color_names' +require_relative 'color' + +module Rainbow + class Presenter < ::String + TERM_EFFECTS = { + reset: 0, + bright: 1, + faint: 2, + italic: 3, + underline: 4, + blink: 5, + inverse: 7, + hide: 8, + cross_out: 9 + }.freeze + + # Sets color of this text. + def color(*values) + wrap_with_sgr(Color.build(:foreground, values).codes) + end + + alias foreground color + alias fg color + + # Sets background color of this text. + def background(*values) + wrap_with_sgr(Color.build(:background, values).codes) + end + + alias bg background + + # Resets terminal to default colors/backgrounds. + # + # It shouldn't be needed to use this method because all methods + # append terminal reset code to end of string. + def reset + wrap_with_sgr(TERM_EFFECTS[:reset]) + end + + # Turns on bright/bold for this text. + def bright + wrap_with_sgr(TERM_EFFECTS[:bright]) + end + + alias bold bright + + # Turns on faint/dark for this text (not well supported by terminal + # emulators). + def faint + wrap_with_sgr(TERM_EFFECTS[:faint]) + end + + alias dark faint + + # Turns on italic style for this text (not well supported by terminal + # emulators). + def italic + wrap_with_sgr(TERM_EFFECTS[:italic]) + end + + # Turns on underline decoration for this text. + def underline + wrap_with_sgr(TERM_EFFECTS[:underline]) + end + + # Turns on blinking attribute for this text (not well supported by terminal + # emulators). + def blink + wrap_with_sgr(TERM_EFFECTS[:blink]) + end + + # Inverses current foreground/background colors. + def inverse + wrap_with_sgr(TERM_EFFECTS[:inverse]) + end + + # Hides this text (set its color to the same as background). + def hide + wrap_with_sgr(TERM_EFFECTS[:hide]) + end + + def cross_out + wrap_with_sgr(TERM_EFFECTS[:cross_out]) + end + + alias strike cross_out + + def black + color(:black) + end + + def red + color(:red) + end + + def green + color(:green) + end + + def yellow + color(:yellow) + end + + def blue + color(:blue) + end + + def magenta + color(:magenta) + end + + def cyan + color(:cyan) + end + + def white + color(:white) + end + + # We take care of X11 color method call here. + # Such as #aqua, #ghostwhite. + def method_missing(method_name, *args) + if Color::X11Named.color_names.include?(method_name) && args.empty? + color(method_name) + else + super + end + end + + def respond_to_missing?(method_name, *args) + Color::X11Named.color_names.include?(method_name) && args.empty? || super + end + + private + + def wrap_with_sgr(codes) #:nodoc: + self.class.new(StringUtils.wrap_with_sgr(self, [*codes])) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/refinement.rb b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/refinement.rb new file mode 100644 index 00000000..cba942ba --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/refinement.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +require_relative 'presenter' +require_relative 'global' + +module Rainbow + refine String do + Presenter.instance_methods(false).each do |method_name| + define_method(method_name) do |*args| + ::Rainbow.global.wrap(self).send(method_name, *args) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/string_utils.rb b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/string_utils.rb new file mode 100644 index 00000000..f9a4152e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/string_utils.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Rainbow + class StringUtils + def self.wrap_with_sgr(string, codes) + return string if codes.empty? + + seq = "\e[" + codes.join(";") + "m" + + string = string.sub(/^(\e\[([\d;]+)m)*/) { |m| m + seq } + + return string if string.end_with? "\e[0m" + + string + "\e[0m" + end + + def self.uncolor(string) + # See http://www.commandlinefu.com/commands/view/3584/remove-color-codes-special-characters-with-sed + string.gsub(/\e\[[0-9;]*m/, '') + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/version.rb b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/version.rb new file mode 100644 index 00000000..024d6e5a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/version.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +module Rainbow + VERSION = "3.1.1" +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/wrapper.rb b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/wrapper.rb new file mode 100644 index 00000000..053d28ec --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/wrapper.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require_relative 'presenter' +require_relative 'null_presenter' + +module Rainbow + class Wrapper + attr_accessor :enabled + + def initialize(enabled = true) + @enabled = enabled + end + + def wrap(string) + if enabled + Presenter.new(string.to_s) + else + NullPresenter.new(string.to_s) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/x11_color_names.rb b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/x11_color_names.rb new file mode 100644 index 00000000..1a5f78c6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rainbow-3.1.1/lib/rainbow/x11_color_names.rb @@ -0,0 +1,153 @@ +# frozen_string_literal: true + +module Rainbow + module X11ColorNames + NAMES = { + aqua: [0, 255, 255], + aquamarine: [127, 255, 212], + mediumaquamarine: [102, 205, 170], + azure: [240, 255, 255], + beige: [245, 245, 220], + bisque: [255, 228, 196], + black: [0, 0, 0], + blanchedalmond: [255, 235, 205], + blue: [0, 0, 255], + darkblue: [0, 0, 139], + lightblue: [173, 216, 230], + mediumblue: [0, 0, 205], + aliceblue: [240, 248, 255], + cadetblue: [95, 158, 160], + dodgerblue: [30, 144, 255], + midnightblue: [25, 25, 112], + navyblue: [0, 0, 128], + powderblue: [176, 224, 230], + royalblue: [65, 105, 225], + skyblue: [135, 206, 235], + deepskyblue: [0, 191, 255], + lightskyblue: [135, 206, 250], + slateblue: [106, 90, 205], + darkslateblue: [72, 61, 139], + mediumslateblue: [123, 104, 238], + steelblue: [70, 130, 180], + lightsteelblue: [176, 196, 222], + brown: [165, 42, 42], + rosybrown: [188, 143, 143], + saddlebrown: [139, 69, 19], + sandybrown: [244, 164, 96], + burlywood: [222, 184, 135], + chartreuse: [127, 255, 0], + chocolate: [210, 105, 30], + coral: [255, 127, 80], + lightcoral: [240, 128, 128], + cornflower: [100, 149, 237], + cornsilk: [255, 248, 220], + crimson: [220, 20, 60], + cyan: [0, 255, 255], + darkcyan: [0, 139, 139], + lightcyan: [224, 255, 255], + firebrick: [178, 34, 34], + fuchsia: [255, 0, 255], + gainsboro: [220, 220, 220], + gold: [255, 215, 0], + goldenrod: [218, 165, 32], + darkgoldenrod: [184, 134, 11], + lightgoldenrod: [250, 250, 210], + palegoldenrod: [238, 232, 170], + gray: [190, 190, 190], + darkgray: [169, 169, 169], + dimgray: [105, 105, 105], + lightgray: [211, 211, 211], + slategray: [112, 128, 144], + lightslategray: [119, 136, 153], + webgray: [128, 128, 128], + green: [0, 255, 0], + darkgreen: [0, 100, 0], + lightgreen: [144, 238, 144], + palegreen: [152, 251, 152], + darkolivegreen: [85, 107, 47], + yellowgreen: [154, 205, 50], + forestgreen: [34, 139, 34], + lawngreen: [124, 252, 0], + limegreen: [50, 205, 50], + seagreen: [46, 139, 87], + darkseagreen: [143, 188, 143], + lightseagreen: [32, 178, 170], + mediumseagreen: [60, 179, 113], + springgreen: [0, 255, 127], + mediumspringgreen: [0, 250, 154], + webgreen: [0, 128, 0], + honeydew: [240, 255, 240], + indianred: [205, 92, 92], + indigo: [75, 0, 130], + ivory: [255, 255, 240], + khaki: [240, 230, 140], + darkkhaki: [189, 183, 107], + lavender: [230, 230, 250], + lavenderblush: [255, 240, 245], + lemonchiffon: [255, 250, 205], + lime: [0, 255, 0], + linen: [250, 240, 230], + magenta: [255, 0, 255], + darkmagenta: [139, 0, 139], + maroon: [176, 48, 96], + webmaroon: [127, 0, 0], + mintcream: [245, 255, 250], + mistyrose: [255, 228, 225], + moccasin: [255, 228, 181], + oldlace: [253, 245, 230], + olive: [128, 128, 0], + olivedrab: [107, 142, 35], + orange: [255, 165, 0], + darkorange: [255, 140, 0], + orchid: [218, 112, 214], + darkorchid: [153, 50, 204], + mediumorchid: [186, 85, 211], + papayawhip: [255, 239, 213], + peachpuff: [255, 218, 185], + peru: [205, 133, 63], + pink: [255, 192, 203], + deeppink: [255, 20, 147], + lightpink: [255, 182, 193], + hotpink: [255, 105, 180], + plum: [221, 160, 221], + purple: [160, 32, 240], + mediumpurple: [147, 112, 219], + rebeccapurple: [102, 51, 153], + webpurple: [127, 0, 127], + red: [255, 0, 0], + darkred: [139, 0, 0], + orangered: [255, 69, 0], + mediumvioletred: [199, 21, 133], + palevioletred: [219, 112, 147], + salmon: [250, 128, 114], + darksalmon: [233, 150, 122], + lightsalmon: [255, 160, 122], + seashell: [255, 245, 238], + sienna: [160, 82, 45], + silver: [192, 192, 192], + darkslategray: [47, 79, 79], + snow: [255, 250, 250], + tan: [210, 180, 140], + teal: [0, 128, 128], + thistle: [216, 191, 216], + tomato: [255, 99, 71], + turquoise: [64, 224, 208], + darkturquoise: [0, 206, 209], + mediumturquoise: [72, 209, 204], + paleturquoise: [175, 238, 238], + violet: [238, 130, 238], + darkviolet: [148, 0, 211], + blueviolet: [138, 43, 226], + wheat: [245, 222, 179], + white: [255, 255, 255], + antiquewhite: [250, 235, 215], + floralwhite: [255, 250, 240], + ghostwhite: [248, 248, 255], + navajowhite: [255, 222, 173], + whitesmoke: [245, 245, 245], + yellow: [255, 255, 0], + lightyellow: [255, 255, 224], + greenyellow: [173, 255, 47] + }.freeze + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/CONTRIBUTING.rdoc b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/CONTRIBUTING.rdoc new file mode 100644 index 00000000..d76eb6b0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/CONTRIBUTING.rdoc @@ -0,0 +1,219 @@ += Developer Introduction + +So you want to write a generator, fix a bug, or otherwise work with RDoc. This +document provides an overview of how RDoc works from parsing options to +generating output. Most of the documentation can be found in the specific +classes for each feature. + +== Bugs + +If you think you found a bug, file a ticket on the {issues +tracker}[https://github.com/ruby/rdoc/issues] on github. + +If your bug involves an error RDoc produced please include a sample file that +illustrates the problem or link to the repository or gem that is associated +with the bug. + +Please include steps to reproduce the issue. Here are some examples of good +issues: + +* https://github.com/ruby/rdoc/issues/55 +* https://github.com/ruby/rdoc/issues/61 + +== Developer Quick Start + +RDoc uses bundler for development. To get ready to work on RDoc run: + + $ gem install bundler + [...] + $ bundle install + [...] + $ rake + [...] + +This will install all the necessary dependencies for development with rake, +generate documentation and run the tests for the first time. + +If the tests don't pass on the first run check the {GitHub Actions page}[https://github.com/ruby/rdoc/actions] to see if there are any known failures +(there shouldn't be). + +You can now use `rake` and `autotest` to run the tests. + +Note: the `rake` command must be used first before running any tests, because +it's used to generate various parsers implemented in RDoc. Also `rake clean` is +helpful to delete these generated files. + +== Glossary + +Here are definitions for some common terms in the RDoc documentation. The +list also briefly describes how the components of RDoc interact. + +parser:: + Parses files and creates a documentation tree from the contents. + +documentation tree:: + The documentation tree represents files, classes, modules, methods, + constants, includes, comments and other ruby syntax features as a tree. + RDoc walks this tree with a generator to create documentation. + +generator:: + Walks the documentation tree and generates output. + + RDoc ships with two generators, the Darkfish generator creates HTML and the + RI generator creates an RI data store. + +markup parser:: + Parses comments from a file into a generic markup tree. + + The markup parsers allow RDoc to handle RDoc, TomDoc, rd and Markdown format + documentation with common formatters. + +markup tree:: + Each parsed comment has a markup tree that represents common markup items + such as headings, paragraphs, lists or verbatim text sections for example + code or output. + + A generator uses a formatters to walks the tree to create output. Some + generators use multiple formatters on a markup tree to produce the output. + +formatter:: + Converts a parsed markup tree into some form other form of markup. + + Formatters can either produce a one-to-one conversion, such as ToHtml, or + extract part of the parsed result, such as ToHtmlSnippet which outputs the + first 100 characters as HTML. + +== Plugins + +When 'rdoc/rdoc' is loaded RDoc looks for 'rdoc/discover' files in your +installed gems. This can be used to load parsers, alternate generators, or +additional preprocessor directives. An rdoc plugin layout should look +something like this: + + lib/rdoc/discover.rb + lib/my/rdoc/plugin.rb + # etc. + +In your rdoc/discover.rb file you will want to wrap the loading of your plugin +in an RDoc version check like this: + + begin + gem 'rdoc', '~> 3' + require 'my/rdoc/plugin' + rescue Gem::LoadError + end + +=== Plugin Types + +In RDoc you can change the following behaviors: + +* Add a parser for a new file format +* Add a new output generator +* Add a new markup directive +* Add a new type of documentation markup +* Add a new type of formatter + +All of these are described below + +== Option Parsing + +Option parsing is handled by RDoc::Options. When you're writing a generator +you can provide the user with extra options by providing a class method ++setup_options+. The option parser will call this after your generator is +loaded. See RDoc::Generator for details. + +== File Parsing + +After options are parsed, RDoc parses files from the files and directories in +ARGV. RDoc compares the filename against what each parser claims it can parse +via RDoc::Parser#parse_files_matching. For example, RDoc::Parser::C can parse +C files, C headers, C++ files, C++ headers and yacc grammars. + +Once a matching parser class is found it is instantiated and +scan+ is called. +The parser needs to extract documentation from the file and add it to the RDoc +document tree. Usually this involves starting at the root and adding a class +or a module (RDoc::TopLevel#add_class and RDoc::TopLevel#add_module) and +proceeding to add classes, modules and methods to each nested item. + +When the parsers are finished the document tree is cleaned up to remove +dangling references to aliases and includes that were not found (and may exist +in a separate library) through RDoc::ClassModule#complete. + +To write your own parser for a new file format see RDoc::Parser. + +=== Documentation Tree + +The parsers build a documentation tree that is composed of RDoc::CodeObject and +its subclasses. There are various methods to walk the tree to extract +information, see RDoc::Context and its subclasses. + +Within a class or module, attributes, methods and constants are divided into +sections. The section represents a functional grouping of parts of the class. +TomDoc uses the sections "Public", "Internal" and "Deprecated". The sections +can be enumerated using RDoc::Context#each_section. + +== Output Generation + +An RDoc generator turns the documentation tree into some other kind of output. +RDoc comes with an HTML generator (RDoc::Generator::Darkfish) and an RI +database generator (RDoc::Generator::RI). The output a generator creates does +not have to be human-readable. + +To create your own generator see RDoc::Generator. + +=== Comments + +In RDoc 3.10 and newer the comment on an RDoc::CodeObject is now an +RDoc::Comment object instead of a String. This is to support various +documentation markup formats like rdoc, TomDoc and rd. The comments are +normalized to remove comment markers and remove indentation then parsed lazily +via RDoc::Comment#document to create a generic markup tree that can be +processed by a formatter. + +To add your own markup format see RDoc::Markup@Other+directives + +==== Formatters + +To transform a comment into some form of output an RDoc::Markup::Formatter +subclass is used like RDoc::Markup::ToHtml. A formatter is a visitor that +walks a parsed comment tree (an RDoc::Markup::Document) of any format. To help +write a formatter RDoc::Markup::FormatterTestCase exists for generic parsers, +and RDoc::Markup::TextFormatterTestCase which contains extra test cases for +text-type output (like +ri+ output). + +RDoc ships with formatters that will turn a comment into HTML, rdoc-markup-like +text, ANSI or terminal backspace highlighted text, HTML, cross-referenced HTML, +an HTML snippet free of most markup, an HTML label for use in id attributes, a +table-of-contents page, and text with only code blocks. + +The output of the formatter does not need to be text or text-like. +RDoc::Markup::ToLabel creates an HTML-safe label for use in an HTML id +attribute. A formatter could count the number of words and the average word +length for a comment, for example. + +==== Directives + +For comments in markup you can add new directives (:nodoc: is a directive). +Directives may replace text or store it off for later use. + +See RDoc::Markup::PreProcess::register for details. + +=== JSONIndex + +RDoc contains a special generator, RDoc::Generator::JSONIndex, which creates a +JSON-based search index and includes a search engine for use with HTML output. +This generator can be used to add searching to any HTML output and is designed +to be called from inside an HTML generator. + +== Markup + +Additional documentation markup formats can be added to RDoc. A markup +parsing class must respond to \::parse and accept a String argument containing +the markup format. An RDoc::Document containing documentation items +(RDoc::Markup::Heading, RDoc::Markup::Paragraph, RDoc::Markup::Verbatim, etc.) +must be returned. + +To register the parser with rdoc, add the markup type's name and class to the +RDoc::Text::MARKUP_FORMAT hash like: + + RDoc::Text::MARKUP_FORMAT['rdoc'] = RDoc::Markup diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/CVE-2013-0256.rdoc b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/CVE-2013-0256.rdoc new file mode 100644 index 00000000..b285b6ac --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/CVE-2013-0256.rdoc @@ -0,0 +1,49 @@ += RDoc 2.3.0 through 3.12 XSS Exploit + +RDoc documentation generated by rdoc 2.3.0 through rdoc 3.12 and prereleases up +to rdoc 4.0.0.preview2.1 are vulnerable to an XSS exploit. This exploit may +lead to cookie disclosure to third parties. + +The exploit exists in darkfish.js which is copied from the RDoc install +location to the generated documentation. + +RDoc is a static documentation generation tool. Patching the library itself +is insufficient to correct this exploit. Those hosting rdoc documentation will +need to apply the following patch. If applied while ignoring whitespace, this +patch will correct all affected versions: + + diff --git darkfish.js darkfish.js + index 4be722f..f26fd45 100644 + --- darkfish.js + +++ darkfish.js + @@ -109,13 +109,15 @@ function hookSearch() { + function highlightTarget( anchor ) { + console.debug( "Highlighting target '%s'.", anchor ); + + - $("a[name=" + anchor + "]").each( function() { + - if ( !$(this).parent().parent().hasClass('target-section') ) { + - console.debug( "Wrapping the target-section" ); + - $('div.method-detail').unwrap( 'div.target-section' ); + - $(this).parent().wrap( '
' ); + - } else { + - console.debug( "Already wrapped." ); + + $("a[name]").each( function() { + + if ( $(this).attr("name") == anchor ) { + + if ( !$(this).parent().parent().hasClass('target-section') ) { + + console.debug( "Wrapping the target-section" ); + + $('div.method-detail').unwrap( 'div.target-section' ); + + $(this).parent().wrap( '
' ); + + } else { + + console.debug( "Already wrapped." ); + + } + } + }); + }; + +RDoc 3.9.5, 3.12.1 and RDoc 4.0.0.rc.2 and newer are not vulnerable to this +exploit. + +This exploit was discovered by Evgeny Ermakov . + +This vulnerability has been assigned the CVE identifier CVE-2013-0256. + diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/ExampleMarkdown.md b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/ExampleMarkdown.md new file mode 100644 index 00000000..fd4359f3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/ExampleMarkdown.md @@ -0,0 +1,39 @@ +# Example Markdown + +This document contains example output to show RDoc styling. This file was +created from a Markdown file. + +For the following styles, see ExampleRDoc.rdoc for style examples: + +* Headings +* Paragraphs +* Code blocks (verbatim sections) +* Definition lists +* Ordered lists +* Unordered lists + +These items all use the same styles as RDoc format files. + +## Footnotes + +Footnotes are rendered at the bottom of the documentation section[^1]. For +pages this will be at the bottom of the page. For method documentation this +will be at the end of the current method. + +[^1]: Here is the footnote content. As you can see it is at the bottom of the +page. + +## Blockquotes + +Here is how a blockquote looks. + +> We finished our first sensor sweep of the neutral zone. Now, how the hell do +> we defeat an enemy that knows us better than we know ourselves? and attack +> the Romulans. +> +> > Sorry, Data. I guess it's better to be lucky than good. The unexpected is +> > our normal routine. Could someone survive inside a transporter buffer for +> > 75 years? + +This text is from [Riker Ipsum](http://rikeripsum.com) + diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/ExampleRDoc.rdoc b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/ExampleRDoc.rdoc new file mode 100644 index 00000000..b5dd68c1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/ExampleRDoc.rdoc @@ -0,0 +1,210 @@ += Example \RDoc + +This document contains example output to show RDoc styling. This file was +created from a RDoc Markup file. + +== Headings + +You should not use headings beyond level 3, it is a sign of poor organization +of your code or documentation. It also becomes difficult for the user to +figure out what you are attempting to explain to them as they have to track +the multiple layers of nesting. + += Heading level 1 + +Above is a level one heading. + +These paragraphs are filler that exist so you can see how the heading +interacts with paragraphs before and after the heading. As you can see each +different heading has a different amount of margin above and below. + +This should be sufficient to give you a proper picture of how it will appear in +your documentation. + +== Heading level 2 + +Above is a level two heading. + +These paragraphs are filler that exist so you can see how the heading +interacts with paragraphs before and after the heading. As you can see each +different heading has a different amount of margin above and below. + +This should be sufficient to give you a proper picture of how it will appear in +your documentation. + +=== Heading level 3 + +Above is a level three heading. + +These paragraphs are filler that exist so you can see how the heading +interacts with paragraphs before and after the heading. As you can see each +different heading has a different amount of margin above and below. + +This should be sufficient to give you a proper picture of how it will appear in +your documentation. + +==== Heading level 4 + +Above is a level four heading. + +These paragraphs are filler that exist so you can see how the heading +interacts with paragraphs before and after the heading. As you can see each +different heading has a different amount of margin above and below. + +This should be sufficient to give you a proper picture of how it will appear in +your documentation. + +===== Heading level 5 + +Above is a level five heading. + +These paragraphs are filler that exist so you can see how the heading +interacts with paragraphs before and after the heading. As you can see each +different heading has a different amount of margin above and below. + +This should be sufficient to give you a proper picture of how it will appear in +your documentation. + +====== Heading level 6 + +Above is a level six heading. + +These paragraphs are filler that exist so you can see how the heading +interacts with paragraphs before and after the heading. As you can see each +different heading has a different amount of margin above and below. + +This should be sufficient to give you a proper picture of how it will appear in +your documentation. + +== Paragraphs + +This is how a paragraph looks. Since it is difficult to generate good content +for paragraphs I have chosen to use {Riker Ipsum}[http://rikeripsum.com] for +nonsense filler content. In the previous sentence you can see how a link is +formatted. + +Here is an example of *bold* and _emphasis_ styling. Try not to combine the +two or use them too often. Here is an example of inline verbatim +text. That should be enough of a taste of inline markup in paragraphs. +The Riker Ipsum filler follows: + +Shields up! Rrrrred alert! Well, I'll say this for him - he's sure of himself. +and attack the Romulans. Worf, It's better than music. It's jazz. This should +be interesting. When has justice ever been as simple as a rule book? Flair is +what marks the difference between artistry and mere competence. + +Sorry, Data. I think you've let your personal feelings cloud your judgement. We +finished our first sensor sweep of the neutral zone. Yes, absolutely, I do +indeed concur, wholeheartedly! Mr. Worf, you do remember how to fire phasers? A +lot of things can change in twelve years, Admiral. Your shields were failing, +sir. + +== Verbatim sections + +A verbatim section typically contains source code or example output. This is +how verbatim blocks of code looks: + + def local responder + responder.ping do |value| + return value + end + end + + def ping uri + @uri = uri + @remote = DRb::DRbObject.new_with_uri @uri + + @remote.ping do |value| + return value + end + end + +This is a paragraph following the verbatim block so you can see how leading and trailing paragraphs interact with it. + +== Unordered lists + +Here is an unordered list. As you can see it uses non-numeral markers for each list item: + +* This is the top-most item in the list. +* This is a second item in the list. + + Unlike the first item, this item has more than one paragraph so you can see + how they interact. +* This is a third item in the list. Like the item before it, this item has a + second paragraph. + + Here is the second paragraph in the list item. +* A final list item. + +== Ordered lists + +Here is an ordered list. As you can see it uses numeral markers for each list +item: + +1. This is the first item in the list. +1. This is the second item in the list. + + Unlike the first item, this item has more than one paragraph so you can see + how they interact. +1. This is the third item in the list. Like the item before it, this item has + a second paragraph. + + Here is the second paragraph in the third list item. +1. The fourth and final list item. + +== Definition lists + +=== "Note" list + +The "note" syntax can be used to create a definition list: + + note:: + description + +Here is such a definition list: + +cat:: + A cat is a small mammal that is commonly kept as a pet. + +dog:: + A dog is a mammal that is also kept as a pet. A dog may range in size from + smaller than a cat to larger than a human. + + Typically dogs are easier to train to respond to commands than cats. + +rabbit:: + Rabbits are also mammals, but are infrequently kept as pets. Most rabbits + are wild. + +=== "Label" list + +The "label" syntax can be used to create a definition list: + + [label] + description + +Here is such a definition list: + +[cat] + A cat is a small mammal that is commonly kept as a pet. + +[dog] + A dog is a mammal that is also kept as a pet. A dog may range in size from + smaller than a cat to larger than a human. + + Typically dogs are easier to train to respond to commands than cats. + +[rabbit] + Rabbits are also mammals, but are infrequently kept as pets. Most rabbits + are wild. + +== Rule + +A rule is a horizontal divider between two paragraphs. Following this +paragraph is a rule. + +--- + +In historic versions of RDoc you could control the height of the rule in HTML +output. This is no longer true as HTML 5 does not support this. + diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/History.rdoc b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/History.rdoc new file mode 100644 index 00000000..deb8c777 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/History.rdoc @@ -0,0 +1,1668 @@ += History + +== 5.1.0 / 2017-02-24 + +* Bug fixes + * Fix an issue that rdoc fails when running on Windows with RUBYOPT=-U. + PR #430 by Toshihiko Ichida + +* Minor enhancements + * Parse ruby 2.1 def. PR #436 by Akira Matsuda. + * Suppress warnings in eval. PR #440 by Nobuyoshi Nakada. + +== 5.0.0 / 2016-11-05 + +* Major enhancements + * Cleanup deprecated code targeted Ruby 1.8 + +* Bug fixes + * Ensure badge data is included in result of JsonIndex template. + * Ensure items in the nil section are displayed in HTML output. Issue #399 + by Daniel Svensson. + * Parse rb_intern_const correctly in C. PR #381 by Sho Hashimoto. + * Fix broken assets caused by #335 when serving ri. PR #360 by Alex Wood. + * Don't try to parse svg files. Issue #350 by Sigurd Svela. + +* Minor enhancements + * Improve class name expansion/resolution in ri. PR #400 by NARUSE, Yui + * Improve performance of document generation. PR #397 by Yusuke Endoh. + +== 4.3.0 / 2016-11-04 + +* Minor enhancements + * Removed json dependency for Ruby 2.4.0 + * End to support Ruby 1.8.x + +== 4.2.2 / 2016-02-09 + +* Bug fixes + * Include lib/rdoc/generator/pot/* in built gem + + +== 4.2.1 / 2015-12-22 + +* Bug fixes + * Fixed infinite loop with CR #339 by @nobu + * Allow rdoc run with --disable-gems #340 by @luizluca + * Don't store full path in GZipped js files #341 by @voxik + * Fix relative path names for drive letters #367 by @nobu + * Fix for valid syntax `class C end` parsing #368 by @nobu + + +== 4.2.0 / 2014-12-06 + +* Major enhancements + * RDoc can now produce translation files for use with gettext. See + RDoc::Generator::POT for a workflow for creating translations of your + documentation. Pull request #254 by Kouhei Sutou. + +* Minor enhancements + * RDoc now allows any single-word macro before a C method implementation. + Issue #722 by Hanmac. + * Now :all is a synonym for :private for RDoc::Options#visibility= to match + the --all command line option. Pull request #276 by Zachary Scott. + * Running rake for the first time now installs racc. Pull request #285 by + Kouhei Sutou. + * Added -h flag to also display help. Issue #300 by Ryan Davis + * search_index.js is now loaded asynchronously for improved performance. + * Allow +X::Y+ as typewriter text. Issue #319, pull request #322 by Jeremy + Evans. + * Added RDoc::RI::Task for building ri data easily through rake. Pull + request #332 by Zachary Scott. + * A gzipped search index is generated for servers configured to use + precompressed files. Pull request #334 by Zachary Scott. + * CSS files now live under /css relative to the document root. Pull request + #335 by Zachary Scott. + * Improved detection of valid ruby in verbatim sections. Pull request #333 + by Jeremy Evans. + +* Bug fixes + * Fixed HTML labels for cross-browser compatibility. This breaks existing + links but enables cross-browser compatibility. Pull request #330 by Jens + Will. + * RDoc handles ASCII-incompatible encodings now. An encoding hint may need + to be added to the file for RDoc to produce correct output, though. + Issue #288 by Manuel Meurer. + * Fixed height recalculation issues when headings are hovered. Issue #289 + by Dietmar H. Büto. + * RDoc now ignores its own output directories. Pull Request #306 by + Hsing-Hui Hsu, bug #305 by Ryan Davis. + * Fixed RDoc::Task no longer uselessly builds documentation when generating + non-HTML output. Bug #307 by Christina Thompson, pull request #308 by + Hsing-Hui Hsu + * Added pointer to font copyright and license information to LEGAL.rdoc. + Issue #290 by Christian Hofstaedtler. + * Fixed RDoc::Context#<=> for ruby trunk. Issue #284 by Hanmac, pull + request #287 by Aaron Patterson + * Tests no longer create directories inside test/. Pull request #286 by + Kouhei Sutou. + * Fixed documentation example in RDoc::Markup. Pull request #292 by Gregory + Brown. + * Applied typo fix to RDoc::Markup. Pull request #297 by @montanalow + * Fixed pretty_print for RDoc::MethodAttr with an alias. Pull request #324 + by Hsing-Hui Hsu. + * Fixed lexing of %w"". Issue #315 by Thierry Lambert, pull request #323 by + Jeremy Evans. + * RDoc::TokenStream now removes nil tokens. Pull request #318 by Calle + Erlandsson. + * Fixed footer links to rubyforge and darkfish. Pull request #328 by + @blackwinter + * Fixed page-top link. Pull request #329 by @blackwinter + * Minitest gem activation failures are now ignored during test startup. + Issue #313 by Vít Ondruch. + * Fixed error when generating documentation from singleton classes. Issue + #311 by Vít Ondruch. + * Splat and keyword params can now be detected for documentation + completeness. Issue #321 Tom Kadwill. + * Standalone anchors in markdown documents are no longer escaped. Issue + #312 by Scott Thompson. + * Fixed RegExp matching stack overflow on Ruby 1.8.7. Issue #327 by sshao. + +== 4.1.2 / 2014-09-05 + +* Bug fixes + * Updated vendored jQuery to 1.6.4. Bug ruby/ruby#711 by @neuralme + +== 4.1.1 / 2014-01-09 + +* Bug fixes + * Fixed reporting of undocumented method parameters when including when + yield and &block are present. Pull request #281 by Victor Bilyk. + * Fixed merging of rd-style and hash-style comments at the top of a file. + Bug #266 by Zachary Scott. + * Fixed Document-attr in the C parser. Bug #271 by Hanmac. + * Removed duplicated condition in superclass fixup. Pull request #282 by + Benoit Daloze. + +== 4.1.0 / 2013-12-26 + +* Notable changes + * Improved accessibility of HTML output. Accessibility review was provided + by: + + Techvision – http://www.techvision.net.in + + The accessibility consultants in Pune, India + + * The look of RDoc has been updated. + +* Minor enhancements + * RDoc can now link to [], []=, << and >> methods. Pull request #202 by + Jeremy Evans, Bug # 191 by by Zachary Scott. + * Added RDoc::Options#output_decoration which controls header labels for + HTML output. Pull Request #199 by Zachary Scott. + * Added --template-stylesheets options to RDoc to allow specification of + alternate stylesheets. Pull request #205 by Zachary Scott. + * Improved performance of the Markdown and RD parsers. Pull request #217 by + Ryan Davis. + * rdoc -v now prints the version instead of enabling verbose + mode. Pull request #201 by Lee Jarvis. + * Running rake newb now automatically installs development + dependencies if the parser files haven't been built. Pull request #235 by + Kouhei Sutou. + * Moved old DEVELOPERS file to CONTRIBUTING to match github conventions. + * TomDoc output now has a "Returns" heading. Issue #234 by Brian Henderson + * Metaprogrammed methods can now use the :args: directive in addition to the + :call-seq: directive. Issue #236 by Mike Moore. + * Sections can be linked to using "@" like labels. If a section and a label + have the same name the section will be preferred. Issue #233 by Brian + Henderson. + * Files that come with a template are hard-linked to save space. Issue #186 + by Vít Ondruch. + +* Bug fixes + * Applied typo fixes by @dvsuresh from ruby/ruby@2c5dcdf + * Restored behavior of --no-pager alias -T. Pull request #223 by ruafozy. + * Fixed extra whitespace output in the rdoc coverage report. Bug #210 by + Ryan Davis. + * RDoc no longer documents its timestamp file when run on an empty + directory. Bug #212 by Rainer Keller + * HTML escape method names in the table of contents. Bug #219 by Akinori + MUSHA. + * Character literals ?h now create a new token type to prevent + loss of the "?" in output. Bug #220 by Vipul A M. + * When looking up a method that does not exist, ri escapes the regular + expression for fallback searches. Bug #227 by Aaron Patterson. + * The ri generator now writes the class method data after +module_function+. + Bug #222 by Zachary Scott, Ruby bug #8225 by David Unric. + * ri now handles missing ri data files. Bug #222 by Zachary Scott, Ruby bug + #8225 by David Unric. + * Added TomDoc to the supported markup formats section of rdoc --help. + Bug #214 by Ryan Davis. + * Fixed documented? check for classes which indicated incorrect 100% + coverage. Bug #211 by Ryan Davis. + * An :enddoc: at the top level stops all further parsing. Bug #213 by Ryan + Davis. + * Improved handling of multiline call-seq. Bug #207 by Erik Hollensbe. + * Fixed text that is missing whitespace for TomDoc. Bug #248 by Noel Cower. + * The RDoc methods now store the method they are aliased to. Bug #206 by + Jeremy Stephens. + * Fixed parsing of multiple methods on the same line. Bug #221 by derula. + * Fixed missing support for images in markdown. Bug #241, pull request #242 + by Zachary Scott. + * The markdown image fix also added support for images via an rdoc-image: + scheme. See RDoc::Markup@Links for details. Issue #93 by Tim Pease. + * Ignore empty call-seq for methods. Improved deduplication of C methods + sharing the same C function. This allows the method heading to show + up correctly for String#== and #===. Bug #244 by Neurogami. + * RDoc no longer adds "http://" to urls without a scheme. Bug #208 by + Zachary Scott. + * Improved the error message in the RDoc server when ri data is missing. + Bug #243, Pull Request #249 by Tadas Tamošauskas. + * Support ruby 2.0 hash syntax for keywords. Bug #256 by diogocsc. + * Prevent \\ from escaping the tag in RDoc markup. (\ still + escapes the tag.) Bug #251 by Pablo Bianciotto. + * Fixed lexing of escaped characters in strings which could cause + duplication of the final characters in source code view. Bug #252 by Mike + Stok. + * Disallow invalid tab widths for -w option. Bug reported by Charles + Hixson. + * rb_file_const() now adds constants to File::Constants when used outside + file.c. Fixes missing File::Constants::FNM_* constants in ruby. + * Fixed handling of :markup: when the file parser is unknown. Issue #262 by + Brian Henderson, pull request #269 by Rein Henrichs. + * Regexp options are no longer stripped in HTML output. Bug #259 by Zachary + Scott, Pull request #265 by Rein Henrichs + +== 4.0.1 / 2013-03-27 + +* Bug fixes + * RDoc::Options parser should rescue from OptionParser::ParseError. + * Updated example of RDoc::Options to include reopening RDoc::Options. + Pointed out by Michael Granger + * Moved RubyGems documentation installed message into RDoc hook. For + RubyGems bug #469 by Jeff Sandberg + * An Error is now raised when a heredoc is not terminated. Fixes exceptions + when processing comment blocks. Reported by darix + * rdoc --quiet --no-ignore-invalid now exits for invalid options. Pull + request #192 by Jeremy Evans + * RDoc::Parser::C no longer ignores a (METHOD) cast in rb_define_method. + Pull request #184 by Carlos Agarie + * RDoc::Servlet no longer ignores extra directories from -d. Pull request + #173 by Thomas Leitner + * Fixed `rdoc --ri-site`. Bug #193 by Michal Papis. + * RDoc no longer attempts to parse binary files. Bug #189 by postmodern, + Bug #190 by Christoffer Lervåg, Bug #195 by Aaron Patterson + * `rdoc --pipe` output now contains for markdown compliance. + * RDoc no longer leaves emacs-style modelines in .txt, .md or .rd files. + Bug #178 by Zachary Scott + * RDoc no longer puts raw markup in HTML output for markdown input. Bug + #204 by Erik Hollensbe + * Code objects with nodoc are no longer included in the ri store. Bug #177 + by Thomas Leitner. + * Text#snippet now creates a RDoc::Markup::ToHtmlSnippet correctly. + * The C parser now de-duplicates call-seq if the same C function is used for + multiple method names. Bug #203 by Pete Higgins + +== 4.0.0 / 2013-02-24 + +RDoc 4.0 includes several new features and several breaking changes. The +changes should not affect users of `rdoc` or `ri`. + +Notable feature additions are markdown support and an WEBrick servlet that can +serve HTML from an ri store. (This means that RubyGems 2.0+ no longer needs +to build HTML documentation when installing gems.) + +Changes since RDoc 3.12.1: + +* Breaking changes + * The default output encoding for RDoc is now UTF-8. Previously RDoc used + the default external encoding which was determined from your locale. + Issue #106 by Justin Baker. + * RDoc::RI::Store is now RDoc::Store so ri data generated by RDoc 4 cannot + be read by earlier versions of RDoc. RDoc::RI::Store exists as an alias + of RDoc::Store so ri data from older versions can still be read. + RDoc::RI::Store will be removed in RDoc 5. + + Tests that create RDoc::CodeObjects on the fly without wiring them into + the documentation tree (did not use add_class, add_method, etc.) must be + updated to use these methods. The documentation tree automatically + attaches them to the store instance which allows lookups to work + correctly. Additionally, a new method RDoc::Store#add_file must be used + instead of RDoc::TopLevel.new. The latter will not be attached to the + documentation tree. + * RDoc generators must accept an RDoc::Store and an RDoc::Options in + initialize. RDoc no longer passes an Array of RDoc::TopLevel objects to + #generate. Use RDoc::Store#all_files instead. + * Some markup formatters (RDoc::Markup::To*) now accept an RDoc::Options + instance as the first argument. Notably, the base class Formatter and + ToHtml*. (This is not universal due to the difficult at accessing the + user's options instance deep inside RDoc. A future major release may + remedy this.) + * Added new markup nodes and specials that RDoc::Markup::Formatter + subclasses must handle. If you're using RDoc::Markup::FormatterTestCase + the new methods you need to add should be readily apparent. + * Removed RDoc::RI::Paths::SYSDIR and ::SITEDIR. These were hidden + constants so no breakage is expected. Use RDoc::RI::Paths::system_dir + and ::site_dir instead. + * RDoc::RI::Store#modules has been renamed to RDoc::Store#module_names + to avoid confusion with RDoc::Store#all_modules imported from + RDoc::TopLevel. + * RDoc::RDocError has been removed. It was deprecated throughout RDoc 3. + * ri -f html is no longer supported. + * Comment definitions in C comments are now only discovered from the first + line. A colon on a subsequent line won't trigger definition extraction. + Issue #103, see also + http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/42942 + * Fixed :stopdoc: for class A::B where A has not been seen. Issue #95 by + Ryan Davis + * RDoc::ClassModule#each_ancestor no longer yields itself if there is + circular ancestry + +* Major enhancements + * ri can now show pages (README, etc.) + + ri rdoc:README + + Will show the README for the latest version of RDoc. You can specify + exact gem versions such as "rdoc-4.0:README" or view pages from the + standard library documentation with "ruby:README". + + RDoc 3 did not save pages in ri data so you will need to regenerate + documentation from your gems to use this feature. + * Added Markdown as a supported format. The markdown format can be set on a + per-file or per-comment basis with the +:markdown:+ directive like the rd + and tomdoc formats and on a per-project basis with + rdoc --markup markdown --write-options + * Removed global state from RDoc. RDoc::Store holds the documentation tree + and connects the driver to the parsers and generator. This also allows + documentation parsing and generation for multiple instances, but the rdoc + command-line tool does not support this. + + Due to this change RDoc::RDoc.current and RDoc::RDoc.reset no longer + exist. + +* Minor enhancements + * Added --page-dir option to give pretty names for a FAQ, guides, or other + documentation you write that is not stored in the project root. For + example, with the following layout: + + README.txt + guides/syntax.txt + guides/conversion.txt + + Running `rdoc --page-dir guides` will make the files in "guides" appear to + be at the top level of the project. This means they will appear to exist + at the top level in HTML output and you can access them with + `ri your_gem:syntax` and `ri your_gem:conversion`. + * Added --root for building documentation from outside the source dir. + * Added current heading and page-top links to HTML headings. + * Added a ChangeLog parser. It automatically parses files that begin + with 'ChangeLog' + * Added a table of contents to the sidebar. + * RDoc markup format merges adjacent labels in a label or note list into a + single definition list item for output. + * RDoc now tracks use of extend. Pull request #118 by Michael Granger. + * RDoc now tracks methods that use super. Pull request #116 by Erik + Hollensbe. + * Added methods ::system_dir, ::site_dir, ::home_dir and ::gem_dir to fetch + the components of RDoc::RI::Paths.path individually. + * Added support for rb_file_const. + * RDoc now processes files in sorted order. Issue #71 by Vít Ondruch + * RDoc now warns with --verbose when methods are duplicated. Issue #71 by + Vít Ondruch + * ri will display documentation for all methods in a class if -a is given. + Issue #57 by casper + * The RDoc coverage report will report line information for attributes, + constants and methods missing documentation. Issue #121 by Zachary Scott + * RDoc now reports a warning for files that are unreadable due to + permissions problems. + * RDoc controls documentation generation for RubyGems 2.0+ + +* Bug fixes + * Fixed parsing of multibyte files with incomplete characters at byte 1024. + Ruby bug #6393 by nobu, patch by Nobuyoshi Nakada and Yui NARUSE. + * Fixed rdoc -E. Ruby Bug #6392 and (modified) patch by Nobuyoshi Nakada + * Added link handling to Markdown output. Bug #160 by burningTyger. + * Fixed HEREDOC output for the limited case of a heredoc followed by a line + end. When a HEREDOC is not followed by a line end RDoc is not currently + smart enough to restore the source correctly. Bug #162 by Zachary Scott. + * Fixed parsing of executables with shebang and encoding comments. Bug #161 + by Marcus Stollsteimer + * RDoc now ignores methods defined on constants instead of creating a fake + module. Bug #163 by Zachary Scott. + * Fixed ChangeLog parsing for FFI gem. Bug #165 by Zachary Scott. + * RDoc now links \#== methods. Bug #164 by Zachary Scott. + * Allow [] following argument names for TomDoc. Bug #167 by Ellis Berner. + * Fixed the RDoc servlet for home and site directories. Bug #170 by Thomas + Leitner. + * Fixed references to methods in the RDoc servlet. Bug #171 by Thomas + Leitner. + * Fixed debug message when generating the darkfish root page. Pull Request + #174 by Thomas Leitner. + * Fixed deletion of attribute ri data when a class was loaded then saved. + Issue #171 by Thomas Leitner. + * Fully qualified names for constants declared from the top level are now + attached to their class or module properly. + * Fixed table of contents display in HTML output for classes and modules. + * Incremental ri builds of C files now work. C variable names from previous + runs are now saved between runs. + * A word that is directly followed by a multi-word tidy link label no longer + disappears. (Like text{link}[http://example]) + * Fixed legacy template support. Pull Request #107 by Justin Baker. + * An HTML class in a verbatim section no longer triggers ruby parsing. + Issue #92 by Vijay Dev + * Improved documentation for setting the default documentation format for + your ruby project. Issue #94 by Henrik Hodne + * Fixed handling of LANG in the RDoc::Options tests. Issue #99 by Vít + Ondruch + * RDoc no longer quits when given an entry that is not a file or directory. + Issue #101 by Charles Nutter + * Fixed bug in syntax-highlighting that would corrupt regular expressions. + Ruby Bug #6488 by Benny Lyne Amorsen. + * "class Object" no longer appears in the coverage report if all its methods + are documented. This suppresses a false positive for libraries that add + toplevel methods. Pull Request #128 by Zachary Scott. + * Fixed test_gen_url test name in TestRDocMarkupToHtml. Pull Request #130 + by Zachary Scott. + * Comment-defined methods ahead of define_method are now discovered. Issue + #133 by eclectic923 + * Fixed detection of define_method documentation. Issue #138 by Marvin + Gülker. + * Fixed lexing of character syntax (?z). Reported by Xavier + Noria. + * Add license to gem spec. Issue #144 by pivotalcommon + * Fixed comment selection for classes. Pull request #146 by pioz + * Fixed parsing of def self.&() end. Issue #148 by Michael + Lucy + * Generated RD parser files are now included in the gem. Issue #145 by + Marvin Gülker + * Class and module aliases now create new classes to avoid duplicate names + in the class list. Issue #143 by Richard Schneeman, Rails Issue #2839 + * RDoc::Markup::Parser now correctly matches indentation of lists when + multibyte characters are used in the list labels. Issue #140 by + burningTyger + * Fixed mangling of email addresses that look like labels. Issue #129 by + Tobias Koch + * Classes and modules in a C file may now be created in any order. Issue + #124 by Su Zhang + * A metaprogrammed method supports the :args: directive. Issue #100 + * A metaprogrammed method supports the :yields: directive. + * RDoc will now look for directives up to the end of the line. For example, + class B < A; end # :nodoc: + will now hide documentation of B. Issue #125 by Zachary Scott + * Fixed tokenization of % when it is not followed by a $-string type + * Fixed display of __END__ in documentation examples in HTML output + * Fixed tokenization of reserved words used as new-style hash keys + * RDoc now handles class << $gvar by ignoring the body + * Fixed parsing of class A:: B. + * Worked around bug in RDoc::RubyLex where tokens won't be reinterpreted + after unget_tk. + * Fixed class << ::Foo writing documentation to /Foo.html + * Fixed class ::A referencing itself from inside its own namespace. + +Changes since RDoc 4.0.0.rc.2: + +* Bug fix + * Templates now use the correct encoding when generating pages. Issue #183 + by Vít Ondruch + +== 4.0.0.rc.2 / 2013-02-05 + +* Minor enhancements + * Added current heading and page-top links to HTML headings. + +* Bug fixes + * Fixed an XSS exploit in darkfish.js. This could lead to cookie disclosure + to third parties. See CVE-2013-0256[rdoc-ref:CVE-2013-0256.rdoc] for full + details including a patch you can apply to generated RDoc documentation. + * Fixed parsing of multibyte files with incomplete characters at byte 1024. + Ruby bug #6393 by nobu, patch by Nobuyoshi Nakada and Yui NARUSE. + * Fixed rdoc -E. Ruby Bug #6392 and (modified) patch by Nobuyoshi Nakada + * Added link handling to Markdown output. Bug #160 by burningTyger. + * Fixed HEREDOC output for the limited case of a heredoc followed by a line + end. When a HEREDOC is not followed by a line end RDoc is not currently + smart enough to restore the source correctly. Bug #162 by Zachary Scott. + * Fixed parsing of executables with shebang and encoding comments. Bug #161 + by Marcus Stollsteimer + * RDoc now ignores methods defined on constants instead of creating a fake + module. Bug #163 by Zachary Scott. + * Fixed ChangeLog parsing for FFI gem. Bug #165 by Zachary Scott. + * RDoc now links \#== methods. Bug #164 by Zachary Scott. + * Allow [] following argument names for TomDoc. Bug #167 by Ellis Berner. + * Fixed the RDoc servlet for home and site directories. Bug #170 by Thomas + Leitner. + * Fixed references to methods in the RDoc servlet. Bug #171 by Thomas + Leitner. + * Fixed debug message when generating the darkfish root page. Pull Request + #174 by Thomas Leitner. + * Fixed deletion of attribute ri data when a class was loaded then saved. + Issue #171 by Thomas Leitner. + +== 4.0.0.preview2.1 / 2012-12-14 + +* Minor enhancements + * Added --page-dir option to give pretty names for a FAQ, guides, or other + documentation you write that is not stored in the project root. For + example, with the following layout: + + README.txt + guides/syntax.txt + guides/conversion.txt + + Running `rdoc --page-dir guides` will make the files in "guides" appear to + be at the top level of the project. This means they will appear to exist + at the top level in HTML output and you can access them with + `ri your_gem:syntax` and `ri your_gem:conversion`. + +* Bug fixes + * Fully qualified names for constants declared from the top level are now + attached to their class or module properly. + * Fixed table of contents display in HTML output for classes and modules. + * Incremental ri builds of C files now work. C variable names from previous + runs are now saved between runs. + +== 4.0.0.preview2 / 2012-12-01 + +* Breaking changes + * The default output encoding for RDoc is now UTF-8. Previously RDoc used + the default external encoding which was determined from your locale. + Issue #106 by Justin Baker. + * RDoc::RI::Store is now RDoc::Store so ri data generated by RDoc 4 cannot + be read by earlier versions of RDoc. RDoc::RI::Store exists as an alias + of RDoc::Store so ri data from older versions can still be read. + RDoc::RI::Store will be removed in RDoc 5. + + Tests that create RDoc::CodeObjects on the fly without wiring them into + the documentation tree (did not use add_class, add_method, etc.) must be + updated to use these methods. The documentation tree automatically + attaches them to the store instance which allows lookups to work + correctly. Additionally, a new method RDoc::Store#add_file must be used + instead of RDoc::TopLevel.new. The latter will not be attached to the + documentation tree. + * RDoc generators must accept an RDoc::Store and an RDoc::Options in + initialize. RDoc no longer passes an Array of RDoc::TopLevel objects to + #generate. Use RDoc::Store#all_files instead. + * Some markup formatters (RDoc::Markup::To*) now accept an RDoc::Options + instance as the first argument. Notably, the base class Formatter and + ToHtml*. (This is not universal due to the difficult at accessing the + user's options instance deep inside RDoc. A future major release may + remedy this.) + * Added new markup nodes and specials that RDoc::Markup::Formatter + subclasses must handle. If you're using RDoc::Markup::FormatterTestCase + the new methods you need to add should be readily apparent. + * Removed RDoc::RI::Paths::SYSDIR and ::SITEDIR. These were hidden + constants so no breakage is expected. Use RDoc::RI::Paths::system_dir + and ::site_dir instead. + * RDoc::RI::Store#modules has been renamed to RDoc::Store#module_names + to avoid confusion with RDoc::Store#all_modules imported from + RDoc::TopLevel. + * RDoc::RDocError has been removed. It was deprecated throughout RDoc 3. + * ri -f html is no longer supported. + * Comment definitions in C comments are now only discovered from the first + line. A colon on a subsequent line won't trigger definition extraction. + Issue #103, see also + http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/42942 + * Fixed :stopdoc: for class A::B where A has not been seen. Issue #95 by + Ryan Davis + * RDoc::ClassModule#each_ancestor no longer yields itself if there is + circular ancestry + +* Major enhancements + * ri can now show pages (README, etc.) + + ri rdoc:README + + Will show the README for the latest version of RDoc. You can specify + exact gem versions such as "rdoc-4.0:README" or view pages from the + standard library documentation with "ruby:README". + + RDoc 3 did not save pages in ri data so you will need to regenerate + documentation from your gems to use this feature. + * Added Markdown as a supported format. The markdown format can be set on a + per-file or per-comment basis with the +:markdown:+ directive like the rd + and tomdoc formats and on a per-project basis with + rdoc --markup markdown --write-options + * Removed global state from RDoc. RDoc::Store holds the documentation tree + and connects the driver to the parsers and generator. This also allows + documentation parsing and generation for multiple instances, but the rdoc + command-line tool does not support this. + + Due to this change RDoc::RDoc.current and RDoc::RDoc.reset no longer + exist. + +* Minor enhancements + * Added --root for building documentation from outside the source dir. + * Added a ChangeLog parser. It automatically parses files that begin + with 'ChangeLog' + * Added a table of contents to the sidebar. + * RDoc markup format merges adjacent labels in a label or note list into a + single definition list item for output. + * RDoc now tracks use of extend. Pull request #118 by Michael Granger. + * RDoc now tracks methods that use super. Pull request #116 by Erik + Hollensbe. + * Added methods ::system_dir, ::site_dir, ::home_dir and ::gem_dir to fetch + the components of RDoc::RI::Paths.path individually. + * Added support for rb_file_const. + * RDoc now processes files in sorted order. Issue #71 by Vít Ondruch + * RDoc now warns with --verbose when methods are duplicated. Issue #71 by + Vít Ondruch + * ri will display documentation for all methods in a class if -a is given. + Issue #57 by casper + * The RDoc coverage report will report line information for attributes, + constants and methods missing documentation. Issue #121 by Zachary Scott + * RDoc now reports a warning for files that are unreadable due to + permissions problems. + * RDoc controls documentation generation for RubyGems 2.0+ + +* Bug fixes + * A word that is directly followed by a multi-word tidy link label no longer + disappears. (Like text{link}[http://example]) + * Fixed legacy template support. Pull Request #107 by Justin Baker. + * An HTML class in a verbatim section no longer triggers ruby parsing. + Issue #92 by Vijay Dev + * Improved documentation for setting the default documentation format for + your ruby project. Issue #94 by Henrik Hodne + * Fixed handling of LANG in the RDoc::Options tests. Issue #99 by Vít + Ondruch + * RDoc no longer quits when given an entry that is not a file or directory. + Issue #101 by Charles Nutter + * Fixed bug in syntax-highlighting that would corrupt regular expressions. + Ruby Bug #6488 by Benny Lyne Amorsen. + * "class Object" no longer appears in the coverage report if all its methods + are documented. This suppresses a false positive for libraries that add + toplevel methods. Pull Request #128 by Zachary Scott. + * Fixed test_gen_url test name in TestRDocMarkupToHtml. Pull Request #130 + by Zachary Scott. + * Comment-defined methods ahead of define_method are now discovered. Issue + #133 by eclectic923 + * Fixed detection of define_method documentation. Issue #138 by Marvin + Gülker. + * Fixed lexing of character syntax (?z). Reported by Xavier + Noria. + * Add license to gem spec. Issue #144 by pivotalcommon + * Fixed comment selection for classes. Pull request #146 by pioz + * Fixed parsing of def self.&() end. Issue #148 by Michael + Lucy + * Generated RD parser files are now included in the gem. Issue #145 by + Marvin Gülker + * Class and module aliases now create new classes to avoid duplicate names + in the class list. Issue #143 by Richard Schneeman, Rails Issue #2839 + * RDoc::Markup::Parser now correctly matches indentation of lists when + multibyte characters are used in the list labels. Issue #140 by + burningTyger + * Fixed mangling of email addresses that look like labels. Issue #129 by + Tobias Koch + * Classes and modules in a C file may now be created in any order. Issue + #124 by Su Zhang + * A metaprogrammed method supports the :args: directive. Issue #100 + * A metaprogrammed method supports the :yields: directive. + * RDoc will now look for directives up to the end of the line. For example, + class B < A; end # :nodoc: + will now hide documentation of B. Issue #125 by Zachary Scott + * Fixed tokenization of % when it is not followed by a $-string type + * Fixed display of __END__ in documentation examples in HTML output + * Fixed tokenization of reserved words used as new-style hash keys + * RDoc now handles class << $gvar by ignoring the body + * Fixed parsing of class A:: B. + * Worked around bug in RDoc::RubyLex where tokens won't be reinterpreted + after unget_tk. + * Fixed class << ::Foo writing documentation to /Foo.html + * Fixed class ::A referencing itself from inside its own namespace. + +== 3.12.2 / 2013-02-24 + +* Bug fixes + * Fixed bug in syntax-highlighting that would corrupt regular expressions. + Ruby Bug #6488 by Benny Lyne Amorsen. + * Fixed lexing of character syntax (?x). Reported by Xavier + Noria. + * Fixed tokenization of % when it is not followed by a $-string type + * Fixed display of __END__ in documentation examples in HTML output + * Fixed tokenization of reserved words used as new-style hash keys + * Fixed HEREDOC output for the limited case of a heredoc followed by a line + end. When a HEREDOC is not followed by a line end RDoc is not currently + smart enough to restore the source correctly. Bug #162 by Zachary Scott. + +== 3.12.1 / 2013-02-05 + +* Bug fixes + * Fixed an XSS exploit in darkfish.js. This could lead to cookie disclosure + to third parties. See CVE-2013-0256[rdoc-ref:CVE-2013-0256.rdoc] for full + details including a patch you can apply to generated RDoc documentation. + * Ensured that rd parser files are generated before checking the manifest. + +== 3.12 / 2011-12-15 + +* Minor enhancements + * Added DEVELOPERS document which contains an overview of how RDoc works and + how to add new features to RDoc. + * Improved title for HTML output to include --title in the + title element. + * rdoc --pipe now understands --markup. + * RDoc now supports IRC-scheme hyperlinks. Issue #83 by trans. + +* Bug fixes + * Fixed title on HTML output for pages. + * Fixed parsing of non-indented HEREDOC. + * Fixed parsing of %w[] and other % literals. Issue #84 by + Erik Hollensbe + * Fixed arrow replacement in HTML output munging the spaceship operator. + Issue #85 by eclectic923. + * Verbatim sections with ERB that match the ruby code whitelist are no + longer syntax-highlighted. Issue #86 by eclectic923 + * Line endings on windows are normalized immediately after reading with + binmode. Issue #87 by Usa Nakamura + * RDoc better understands directives for comments. Comment directives can + now be found anywhere in multi-line comments. Issue #90 by Ryan Davis + * Tidy links to methods show the label again. Issue #88 by Simon Chiang + * RDoc::Parser::C can now find comments directly above + +rb_define_class_under+. Issue #89 by Enrico + * In rdoc, backspace and ansi formatters, labels and notes without bodies + are now shown. + * In rdoc, backspace and ansi formatters, whitespace between label or note + and the colon is now stripped. + +== 3.11 / 2011-10-17 + +* Bug fixes + * Avoid parsing TAGS files included in gems. Issue #81 by Santiago + Pastorino. + +== 3.10 / 2011-10-08 + +* Major enhancements + * RDoc HTML output has been improved: + * The search from Володя Колесников's (Vladimir Kolesnikov) SDoc has been + integrated. + + The search index generation is a reusable component through + RDoc::Generator::JsonIndex + * The table of contents is now a separate page and now shows links to + headings and sections inside a page or class. + * Class pages no longer show the namespace and no longer have file info + pages. + * HTML output is HTML 5. + * Static files can be copied into RDoc using --copy-files + * RDoc supports additional documentation formats: + * TomDoc 1.0.0-rc1 + * RD format + + The default markup can be set via the --markup option. + + The format of documentation in a particular file can be specified by the + +:markup:+ directive. If the +:markup:+ directive is in the first comment + it is used as the default for the entire file. For other comments it + overrides the default markup format. + + The markup format can be set for rake tasks using RDoc::Task#markup + * RDoc can save and load an options file. + + To create an options file that defaults to using TomDoc markup run: + + rdoc --markup tomdoc --write-options + + This will create a .rdoc_options file. Check it in to your VCS and + package it with your gem. RDoc will automatically load this file and + combine it with the user's options. + + Some options are not saved. See RDoc::Options@Saved+Options for full + details. + +* Minor enhancements + * RDoc autoloads everything. You only need to require 'rdoc' now. + * HTML headings now have ids matching their titles. + + = Hello! + + Is rendered as + +

Hello!

+ + * Labels for classes or methods can be linked-to by adding an @ + following the class or method reference. For example, + RDoc::Markup@Links + + See RDoc::Markup@Links for further details. + * For HTML output RDoc uses +SomeClass.method_name+ and + +SomeClass#method_name+ for remote methods and attributes and + +::method_name+ and +#method_name+ for local methods. + * RDoc makes an effort to syntax-highlight ruby code in verbatim sections. + See RDoc::Markup@Paragraphs+and+Verbatim + * Added RDoc::TopLevel#text? and RDoc::Parser::Text to indicate a + parsed file contains no ruby constructs. + * Added rdoc-label link scheme which allows bidirectional links. + See RDoc::Markup for details. + * Image paths at HTTPS URLs will now be turned into ++ tags. Pull + Request #60 by James Mead + * Added RDoc::Comment which encapsulates comment-handling functionality. + * Added RDoc::Markup::PreProcess::post_process to allow arbitrary comment + munging. + * RDoc::RDoc::current is set for the entire RDoc run. + * Split rdoc/markup/inline into individual files for its component classes. + * Moved token stream HTML markup out of RDoc::AnyMethod#markup_code into + RDoc::TokenStream::to_html + * "Top" link in section headers is no longer inside the heading element. + * RDoc avoids printing some warnings unless run with `rdoc --verbose`. For + Rails issue #1646. + * Finishing a paragraph with two or more spaces will result in a line break. + This feature is experimental and may be modified or removed. + +* Bug fixes + * Markup defined by RDoc::Markup#add_special inside a is no + longer converted. + * Performance of RDoc::RubyLex has been improved. Ruby Bug #5202 by Ryan + Melton. + * Add US-ASCII magic comments to work with ruby -Ku. Issue #63 by + Travis D. Warlick, Jr. + * Clicking a link in the method description now works. Issue #61 by Alan + Hogan. + * Fixed RDoc::Markup::Parser for CRLF line endings. Issue #67 by Marvin + Gülker. + * Fixed lexing of percent strings like %r{#}. Issue #68 by eclectic923. + * The C parser now understands classes defined with + +rb_struct_define_without_accessor+ (like Range). Pull Request #73 by Dan + Bernier + * Fixed lexing of a b <<-HEREDOC. Issue #75 by John Mair. + * Added LEGAL.rdoc with references to licenses in other files. Issue #78 by + Dmitry Jemerov. + * Block parameters are displayed in Darkfish output again. Issue #76 by + Andrea Singh. + * The method parameter coverage report no longer includes parameter default + values. Issue #77 by Jake Goulding. + * The module for an include is not looked up until parsed all the files are + parsed. Unless your project includes nonexistent modules this avoids + worst-case behavior (O(n!)) of RDoc::Include#module. + +== 3.9.5 / 2013-02-05 + +* Bug fixes + * Fixed an XSS exploit in darkfish.js. This could lead to cookie disclosure + to third parties. See CVE-2013-0256.rdoc for full details including a + patch you can apply to generated RDoc documentation. + +== 3.9.4 / 2011-08-26 + +* Bug fixes + * Applied typo and grammar fixes from Luke Gruber. Ruby bug #5203 + +== 3.9.3 / 2011-08-23 + +* Bug fixes + * Add US-ASCII magic comments to work with ruby -Ku. Issue #63 by + Travis D. Warlick, Jr. + * Image paths at HTTPS URLs are now turned into ++ tags. Pull + Request #60 by James Mead + * Markup defined by RDoc::Markup#add_special inside a is no + longer converted. + +== 3.9.2 / 2011-08-11 + +* Bug fix + * Loosened TIDYLINK regexp to allow any content in the link section like: + {foo}[rdoc-ref:SomeClass] + * In HTML output headings are capped at
again + +== 3.9.1 / 2011-07-31 + +* Bug fixes + * Fix RDoc::Markup parser for a header followed by a non-text token. Issue + #56 by Adam Tait + * Fix RDoc::Markup::ToHtmlCrossref#gen_url for non-rdoc-ref links. + * Fix bug report URL when rdoc crashes. + +== 3.9 / 2011-07-30 + +* Minor enhancements + * RDoc::Parser::C now supports :doc: and :nodoc: for class comments + * Added the rdoc-ref: link scheme which links to a named reference. + rdoc-ref: can resolve references to classes, modules, methods, + files, etc. This can be used to create cross-generator named links unlike + the link: scheme which is dependent upon the exact file name. + Issue #53 by Simon Chiang + * Pulled RDoc::CrossReference out of RDoc::Markup::ToHtmlCrossref. + Cross-references can now be created easily for non-HTML formatters. +* Bug fixes + * `ri []` and other special methods now work properly. Issue #52 by + ddebernardy. + * `ri` now has space between class comments from multiple files. + * :stopdoc: no longer creates Object references. Issue #55 by Simon Chiang + * :nodoc: works on class aliases now. Issue #51 by Steven G. Harms + * Remove tokenizer restriction on header lengths for verbatim sections. + Issue #49 by trans + +== 3.8 / 2011-06-29 + +* Minor enhancements + * RDoc::Parser::C can now discover methods on ENV and ARGF. + * RDoc::Parser::C now knows about rb_cSocket and rb_mDL. +* Bug fixes + * Updating Object in an ri data store with new data now removes methods, + includes, constants and aliases. + +== 3.7 / 2011-06-27 + +* Minor enhancements + * New directive :category: which allows methods to be grouped into sections + more cleanly. See RDoc::Markup for details. + * Document-class for RDoc::Parser::C now supports Foo::CONST as well as + CONST. + * ri method output is now a comma-separated list when displayed + interactively. Pull Request #39 by Benoit Daloze. + * RDoc::ClassModule#merge now prefers the argument's information over the + receiver's (it now behaves like Hash#merge! instead of a backwards + Hash#merge!). + * RDoc::Markup#convert now accepts an RDoc::Markup::Document instance + * RDoc now owns the code for generating RDoc and ri data when gems install + * Added RDoc::RDoc::reset + * Added RDoc::CodeObject#file_name +* Bug fixes + * ri no longer crashes when attempting to complete a plain [. + * ri data now tracks which file information came from so it can process + removals and changes to: + * Classes and Modules + * Methods + * Attributes + * Includes + * Constants + You will need to rebuild your ri data for it to update properly. Issue + #21 by Sven Riedel + * Signal and SignalException no longer clobber each other + * RDoc::Parser::C no longer creates classes when processing aliases. + * RDoc::Text#strip_stars handles Document-method for methods with =, ! and ? + now. + * RDoc::Parser::C now allows .cpp files to be used with the "in" comment on + rb_define_method. Bug #35 by Hanmac. + * RDoc::Parser::Ruby no longer eats content when =begin/=end documentation + blocks are followed by a documentable item. Issue #41 by mfn. + * RDoc::Markup::Formatter and subclasses now allow an optional +markup+ + parameter for adding custom markup. The example in + RDoc::Markup::Formatter will now work. Issue #38 by tsilen. + * RDoc::Parser::C can now distinguish between class methods and instance + methods in Document-method. Issue #36 by Vincent Batts. + * RDoc now encodes file names in the output encoding. Issue #33 by Perry + Smith. + * ri data generation for method aliases no longer duplicates the class in + #full_name + +== 3.6.1 / 2011-05-15 + +* Bug fixes + * Fix infinite loop created when re-encountering BasicObject. + * RDoc::Context#each_ancestor is now provided for duck-typing. + * rb_path2class() can now be used to discover the parent class in + rb_define_class_under. + +== 3.6 / 2011-05-13 + +* Major Enhancements + * Interactive ri is now the default when no names are given. +* Minor Enhancements + * RDoc::RDoc#generate was added to allow multiple generators to be used with + a set of parsed file info. + * RDoc::Options#finish can be called multiple times now. + * `ri -i` only shows one level of namespace when completing class names. + * Added `ri --list` for explicit listing. `ri -l F G` will list all classes + or modules starting with F or G +* Bug fixes + * Remove windows-specific test for test_check_files, it is too hard to do. + Ruby commit r30811 by Usaku Nakamura. + * Remove unnecessary (and wrong) platform-dependent hacks. Ruby commit + r30829 by Usaku Nakamura. + * Completing via Array#[ in `ri -i` no longer crashes. Ruby Bug #3167 + * Completing IO::o in `ri -i` now returns results. Ruby Bug #3167 + * RDoc::Parser::C ignores prototypes better. Pull Request #34 by Pete + Higgins. + * private_class_method and public_class_method are now parsed correctly for + inherited methods. Issue #16 by gitsucks. + * The doc directive now forces documentation even when the method is marked + private or protected. + +== 3.5.3 / 2010-02-06 + +* Bug fixes + * When including a file perform a lossy force-transcoding to the output + encoding instead of crashing to preserve as much content as possible. + Ruby Bug #4376 by Yui NARUSE. + * Work around inconsistent encoding result from String#sub!, String#gsub!. + Related to Ruby Bug #4376. + * Work around inconsistent encoding result from String#[]=. Related to Ruby + Bug #4376. + * When Darkfish fails the file being generated is now reported. + +== 3.5.2 / 2010-02-04 + +* Deprecations + * RDoc::Context::Section#sequence is now deprecated. Use + RDoc::Context::Section#aref instead. + +* Bug fixes + * Fixed syntax highlighting CSS class generation. Reported by Daniel + Bretoi. + * Fixed ri for methods with aliases. Pull Request #15 by Sven Riedel. + * Added windows-specific test for test_check_files. + * Darkfish now supports sections. Template and generator author see + RDoc::Context#each_section to add section support. RubyForge Bug #26883 + by Jeff Hodges. + * Fixed post-install message for Ruby 1.9.2 users. + * Set required ruby version to >= 1.8.7. + +== 3.5.1 / 2010-01-30 + +* Bug fixes + * Fixed some typos. Pull request #13 by R.T. Lechow. + * Ensure an RDoc::Stats is created in #parse_files. Fixes documentation for + railties which has no files. Reported by Aaron Patterson + +== 3.5 / 2010-01-29 + +* Minor enhancements + * RDoc::Parser::C looks for rb_scan_args and fills in RDoc::AnyMethod#params + appropriately. This may provide useful information if the author did not + provide a call-seq. + * RDoc::Parser::C now records the function name for methods implemented in + C. + * RDoc now records file and byte offset information for methods. +* Bug fixes + * Locations of module aliases are now recorded. + * RDoc::Parser::C finds method bodies better now. + * Fixed further locations where output encoding was not preserved. Bug #11 + by Vít Ondruch, RubyForge bug #28791 by Dzmitry Prakapenka. + * Fixed display of numeric lists on the index page and file pages. Bug #12 + by tobijk. + * Skip TestRDocOptions#test_check_files on windows until a windows-specific + test can be created. RubyForge bug #28821 by Usaku Nakamura. + * Fixed line-height of headings in method and alias descriptions. RubyForge + Bug #2770 by Adam Avilla + * Relaxed RDoc::Parser::Ruby#remove_private_comments to consume more dashes + as older versions once did. Bug #7 by Claus Folke Brobak. + +== 3.4 / 2010-01-06 + +* Minor enhancements + * RDoc::RDoc#document may now be called with an RDoc::Options instance. +* Bug fixes + * Added skips to Encoding tests running on 1.8. + * Fixed warnings + +== 3.3 / 2010-01-03 + +* Minor enhancements + * The coverage report can now report undocumented method parameters + including methods defined in C. + + rdoc -C gives a standard report, rdoc -C1 includes + method parameters. Method parameters are considered documented if they're + marked-up with +, or . + * The C parser now uses *args instead of ... if no + call-seq was provided to give names to the arguments. +* Bug fixes + * The C parser now records the file location of aliases, attributes, + constants and methods allowing -C to work on C files. + * Darkfish now handles dots in call-seq allowing ary.insert(index, + obj...) to display correctly. Patch #6 by KUBO Takehiro. + * Improved processing of meta-programmed methods when followed by unparseable + syntax. RubyForge patch #28653 by Aidan Cully. + * rdoc now touches the flag file when it create the output directory. + Prevents the "isn't an RDoc directory" error if rdoc crashes. + * RDoc now properly converts to the expected output encoding. RubyForge bug + #28791 by Dzmitry Prakapenka. + * Restored parsing of block comments. RubyForge bug #28668 by Stefano Crocco. + * Metaprogrammed methods defined with blocks no longer confuse the ruby + parser. RubyForge bug #28370 by Erik Hollensbe. + * ri no longer displays all methods in the inheritance chain. + +== 3.2 / 2010-12-29 + +* Minor enhancements + * RDoc generator authors may now suppress updating the output dir (creating + a created.rid file) by setting RDoc::Options#update_output_dir to false. + * RDoc::Task has been refactored to ease creating subclasses. +* Bug fixes + * RDoc's gitignore now ignores .DS_Store files. Pull Request #3 by Shane + Becker. + +== 3.1 / 2010-12-28 + +RDoc has moved to github. Releases after 3.1 reference github unless +otherwise noted. + +* Minor enhancements + * RDoc::Task now features a #generator option to choose an alternate + generator. Pull Request #2 by Erik Hollensbe. + * Enhanced test for RDoc::Parser::binary? RubyForge patch #28538 by Eito + Katagiri. + * Generator list in --help is no longer static. Generator description comes + from the generator's DESCRIPTION constant. + * Documentation summary is now displayed with dynamic width. +* Bug fixes + * Strip encoding comment from input to avoid overriding file comment. + RubyForge Bug #22113 by James Gray. + * Restore call-seq parsing behavior when the call-seq is the only comment. + RubyForge Bug #26290 by Sylvain Joyeux. + * Coverage report no longer crashes for constant aliases. Pull Request #1 + by Andy Lindeman. + * RDoc no longer loses ghost methods when followed by certain tokens. + RubyForge bug #27793 by Aaron Patterson. + * RDoc no longer crashes in ri if HOME is not set. Ruby Bug #4202 by + Shyouhei Urabe. + * ri no longer crashes with HTML format output. RubyForge bug #28675 by + 7rans. + * RDoc::Markup::ToHtml#gen_url now initializes #from_path to ''. + Additionally, #from_path is now settable. RubyForge bug #27838 by Claus + Folke Brobak. + * Comments in the C parser are now normalized before being combined. + RubyForge patch #28646 by Sven Herzberg. + * RDoc::Parser::C no longer requires a comment and finds more method bodies. + RubyForge patch #28643 by Sven Herzberg. + * Darkfish now has a "Class/Module Index" instead of a "Class Index". + RubyForge patch #28364 by James Tucker. + * RDoc::Parser::Ruby now parses negative numbers correctly. RubyForge patch + #28544 by Eito Katagiri. + +== 3.0.1 / 2010-12-19 + +* Bug fix + * RDoc no longer has a Perl parser. + +== 3.0 / 2010-12-19 + +Special thanks to Thierry Lambert for massive improvements to RDoc. + +* Major enhancements + * Ruby 1.8.6 is no longer supported by RDoc. + * RDoc now converts input files to a single encoding specified by + --encoding. See RDoc::RDoc and RDoc::Options#encoding. + --encoding is now preferred over --charset + * RDoc now supports a --coverage-report flag (also -C and + --dcov) that outputs a report on items lacking documentation. + * Templates (rdoc -T) are now checked for existence in + RDoc::Options. Generator authors can now use RDoc::Options#template_dir + which is the full path to the template directory. + * Added support for class aliases. Patch by Thierry Lambert. + * Improved merging of classes and modules across multiple files including + more accurate documentation statistics. Patch by Thierry Lambert. + * Improved handling of method aliases. Patch by Thierry Lambert. + * Improved handling of visibility of RDoc code objects. Patch by Thierry + Lambert. + * RDoc::Attr#type is now RDoc::Attr#definition. Patch by Thierry Lambert. + * Removed TimeConstantMethods + * RDoc now calls ::new instead of ::for on generators. +* Minor enhancements + * Added rdoc arguments --dry-run, --all, + --visibility, --force-output, --hyperlink-all. + Patch by Thierry Lambert. + * RDoc::Markup::FormatterTestCase has been expanded. Patch by Thierry + Lambert. + * RDoc::Markup::TextFormatterTestCase has been extracted from RDoc tests. + Patch by Thierry Lambert. + * Various RDoc::Parser::Ruby enhancements. Patch by Thierry Lambert. + * Various RDoc::Markup::Parser enhancements. Patch by Thierry Lambert. + * RDoc::Parser::binary? is more robust now that it uses Encoding. + * Deprecated rdoc arguments are now explicitly mentioned in rdoc command + output. Patch by Thierry Lambert. + * Constant values are formatted more accurately. Patch by Thierry Lambert. + * Enhanced call-seq parsing in RDoc::Parser::C. Patch by Thierry Lambert. + * RDoc no longer uses kw, cmt, re or str classes for embedded source code + snippets. Patch by Thierry Lambert. + * RDoc directives may now be escaped with a leading '\\'. Patch by Thierry + Lambert. + * RDoc note lists (label::) now generate a table with class + "rdoc-list". Patch by Thierry Lambert. + * RDoc markup documentation has been moved to RDoc::Markup including notes + on how to document source code. + * An RDoc::Require is now always listed at the file level. Patch by Thierry + Lambert. + * RDoc::CodeObjects now know which file they were defined in. + * RDoc::Options calls ::setup_options on the generator class specified by + --format. See RDoc::Options::setup_generator. + * rdoc gives an error when multiple formats are given. + * Files with erb inside will no longer trip RDoc::Parser::binary? + * Last --title wins. Patch by Thierry Lambert. + * Better block params handling. Patch by Thierry Lambert. + * Moved rdoc/tokenstream.rb to rdoc/token_stream.rb. + * Moved rdoc/markup/preprocess.rb to rdoc/markup/pre_process.rb. + * Removed "':' not followed by operator or identifier" warning for new Hash + syntax. + * rb_attr() is now supported for attributes. + * RDoc::Parser::C now supports yields, doc, and args directives like + RDoc::Parser::Ruby. + * Moved RDoc::Parser::PerlPOD to the rdoc-perl_pod gem. +* Bug fixes + * RDoc::Generator tests no longer require any installed RDoc on Ruby 1.9 + * Load existing cache before generating ri. Ruby r27749 by NAKAMURA Usaku. + * RDoc now handles BOM. Ruby r28062 by Nobuyoshi Nakada. + * Use proper XML encoding for darkfish classpage. Ruby r28083 by NARUSE, + Yui. + * Fix ri output when special characters are inside html tags. Patch by Tomo + Kazahaya, Ruby Bug #3512. + * Don't bother checking if the pager exists, it's already done. Ruby r28842 + by NAKAMURA Usaku. + * RDoc::Parser::Ruby now ignores non-constant-named singleton classes. Ruby + r29140 by Nobuyoshi Nakada. Ruby Bug #3759. + * RDoc::Parser::Ruby call args no longer include assignment. Ruby r29141 by + Nobuyoshi Nakada. Ruby Bug #3759 + * Handle $HOME being unset in ri. Ruby r29272 by Nobuyoshi Nakada. + * uniq ancestors and modules too. Ruby r29312 by Nobuyoshi Nakada. + * RDoc now knows about Encoding by default. Ruby r29356 by Nobuyoshi + Nakada. + * ri now defaults to the backspace formatter when piped. Use RI environment + variable or options to override. Ruby r28455 by Yusuke Endoh. + * __send__ and friends no longer get their underscores removed. Patch by + Thierry Lambert. + * The C parser now makes new public when promoting initialize. + * Fix crash in #markup_code for TkUnknownChar. + * Fix crash in RDoc::Parser::C when aliasing methods with Regexp special + characters. + * Fix crash when various operators are used as a name as in + alias * compose. + * Fix warning with some dynamic use of attr_* + * Methods added to true, false and nil are now documented. + * Remove warning for methods defined on globals. + +== 2.5.11 / 2010-08-20 + +* Minor Enhancements + * Alias comments are now discovered by the C parser. Reported by Jeremy + Evans. + * Removed --all option which is unused in RDoc. Use the nodoc or + stopdoc/startdoc directives to suppress documentation instead. + +== 2.5.10 / 2010-08-17 + +* Minor Enhancements + * Support rb_singleton_class(). Reported by Jeremy Evans. + * Support rb_define_private_method() on rb_singleton_class(). Reported by + Jeremy Evans. + +* Bug Fixes + * Treat non-ASCII RDoc files as text. Bug #28391 by Kouhei Sutou. + * Fix potential test failures due to ivar collision. Bug #28390 by Kouhei + Sutou. + * Added duck-typed #aref for RDoc::Attr to RDoc::AnyMethod. Bug #28375 by + Erik Hollensbe + * Fixed method references in HTML output when show_hash is false. + * Fixed comments with '.' in call-seq in C sources. Reported by Jeremy + Evans. + * RDoc now understands singleton aliases. Reported by Jeremy Evans. + +== 2.5.9 / 2010-07-06 + +* Bug Fixes + * Look up pager correctly. + * Fixed handling of bullets in verbatim sections. Partial patch by + Juha-Jarmo Heinonen. + +== 2.5.8 / 2010-04-27 + +*NOTE*: + +RDoc 2.5 did not save method parameters, so you should upgrade your rdoc-data +gem to a version >= 2.5.3. + +To have ri data for core and stdlib you'll need to: + + gem install rdoc-data + +then run: + + rdoc-data --install + +To have ri data for you gems you'll also need to run: + + gem rdoc --all --overwrite + +If you don't want to rebuild the rdoc for `gem server`, add --no-rdoc. + +* Bug Fixes + * ri no longer complains about nonexistent pagers. + * Fixed failing test + +== 2.5.7 / 2010-04-22 + +* Minor Enhancements + * Unrecognized RDoc directives can now be registered by a plugin for + handling. See RDoc::Markup::PreProcess. + * Added RDoc::Markup::Raw to allow other markup engines to dump raw content + into RDoc. +* Bug Fixes + * rdoc -p no longer means --pipe if files are also given. + * RDoc now knows about BasicObject by default. Ruby Bug #1318 by Ambrus Zsbán + +== 2.5.6 / 2010-04-22 + +* Minor Enhancements + * Unrecognized RDoc directives are added as metadata to the object they get + attached to. + + ## + # :my_new_directive: my cool value + + Results in a 'my_new_directive' metadata key with value 'my cool value' on + the RDoc::CodeObject it is for +* Bug Fixes + * RDoc no longer prints out "invalid options:" when there were no invalid + options. + * Fixed link size on Darkfish file pages + +== 2.5.5 / 2010-04-19 + +* 1 Minor Enhancement + * Use #binread in RDoc::Markup::PreProcess. Patch from ruby trunk. +* 3 Bug Fixes + * Fixed indentation of method-description lists in Darkfish. Bug #28081 by + Theresa Dwinnell. + * Fixed loading RDoc::AnyMethod aliases to no longer infinitely loop. Bug + #28107 by Sven Riedel + * Fixed handling of ignored invalid options to continue after the invalid + option. + +== 2.5.4 / 2010-04-18 + +* 2 Minor Enhancements + * Methods will now be cross-referenced when preceded with ::. Ruby Bug + #3169 by Marc-Andre Lafortune. + * Methods now have human readable fragment identifiers for HTML output. + (#method-i-gsub vs #M000005). Ruby Bug #3023 by Marc-Andre Lafortune. +* 1 Bug Fixes + * RDoc::Parser::Ruby now handles while begin a; b end # .... + Ruby Bug #3160 by Yusuke Endoh. + +== 2.5.3 / 2010-04-10 + +* 1 Minor Enhancement + * RDoc::Parser::Simple and the include directive remove coding: comment from + first line +* 2 Bug Fixes + * Fixed loading of created.rid when regenerating documentation. Ruby bug + #3121 by Yusuke Endoh. + * Compare times as Integers as created.rid doesn't store fractional times. + +== 2.5.2 / 2010-04-09 + +* 1 Minor Enhancement + * Imported various changes by Nobu from ruby trunk. +* 2 Bug Fixes + * RDoc parses files without extensions as text files again. + * RDoc::Parser::Ruby parses %{ strings correctly again. + +== 2.5.1 / 2010-04-06 + +* 1 Minor Enhancement + * RDoc::Parser::C now supports the include directive for classes and + modules. +* 6 Bug Fixes + * RDoc::AnyMethod params now get saved in ri data. + * ri now displays method arguments correctly. + * RDoc::Markup::Parser allows no space between = and header text like rdoc + 2.4 and earlier. + * RDoc::Parser::C's "in" directive now looks in the current directory. + * RDoc::Task's rerdoc task no longer deletes the doc directory twice. + * rdoc --force-update now works correctly. Patch by Nobu Nokada + +== 2.5 / 2010-03-31 + +* 9 Major Enhancements + * Darkfish now has a "Home" button + * ri no longer displays the value of a constant. There's no easy way to + make them presentable. Use irb or ruby -e instead. Ruby Bug #549. + * New ri data format now uses Marshal and pre-builds caches + * No support for old ri data format, too hard to maintain + * To upgrade your core ri documentation, install the rdoc-data gem and run + rdoc-data + * RDoc now displays how well you've documented your library + * New recursive-descent parser for RDoc::Markup. See RDoc::Markup::Parser + * Updated ruby_lex and ruby_token + * Removed threading support, RDoc is not thread-safe + * Removed many unsupported options to rdoc + * Future versions of RDoc will not support Ruby 1.8.6. Bugs filed for + 1.8.6-only issues will be (largely) rejected. + +* 17 Minor Enhancements + * Source Parsing + * RDoc now supports module aliasing via constant assignment. + * RDoc now tracks superclasses correctly. Fixes File < IO for core docs. + * RDoc now ignores methods inside methods. + * RDoc now ignores Marshal and other binray files. + * Removed "Skipping require of dynamic string" warning. + * C parser now handles Document-method better. Bug #27329. + * API enhancements for writing parsers like the Ruby parser, see + RDoc::Parser::RubyTools + * ri + * Uses pager over less and more for Debian. Ruby Bug #1171. + * ri will use the RI_PAGER environment variable to find a pager. + * ri data generator now supports SIGINFO (^T) + * When rdoc is in debug mode, ^C now prints a backtrace + * RDoc::Markup::AttributeManager no longer uses global state. + * RDoc::RDoc no longer passes around options. Patch #27167. + * Darkfish won't generate a file if its template is missing. Patch #25857. + * Improved some wording for the RDoc main page. Patch #27264, #27268. + * Removed diagram generation support (to return in the future). + * Removed external support for RDoc::Task. + +* 12 Bug Fixes + * The :attr: directives now use the name given to create an attribute. See + RDoc::Parser::Ruby#parse_meta_attr. + * Fix crossrefs on paths with '-'. Ruby Bug #883. + * Fix ruby parser for alias with = in the name. Bug #27522. + * Images are no longer executable. Bug #27156. + * --op is no longer overridden by --ri. Bug #27054. + * :method: now works when at the end of a class. Bug #26910. + * Preserve ellipsis from call-seq in Darkfish. Patch #26974. + * Emacs-style coding: is handled properly. Patch #27388. + * RDoc::RubyLex now parses UTF-8 identifiers. Bug #26946, #26947. + * Fixed namespace lookup rules. Bug #26161. + * Worked around bug in Selenium where they hide a .jar in a .txt file. + Filed Selenium bug #27789. + * Alias comments are no longer hidden. Reported by Adam Avilla. + +== 2.4.3 / 2009-04-01 + +* 2 Bug Fixes + * Corrected patch for file links + * Corrected display of file popup + +== 2.4.2 / 2009-03-25 + +* 2 Minor Enhancements + * Added --pipe for turning RDoc on stdin into HTML + * Added rdoc/task.rb containing a replacement for rake/rdoctask.rb. Use + RDoc::Task now instead of Rake::RDocTask. + +* 10 Bug Fixes + * Writing the ri cache file to the proper directory. Bug #24459 by Lars + Christensen. + * Possible fix for Dir::[] and Pathname interaction on 1.9. Bug #24650 by + tiburon. + * Fixed scanning constants for if/end, etc. pairs. Bug #24609 by Ryan + Davis. + * Fixed private methods in the C parser. Bug #24599 by Aaron Patterson. + * Fixed display of markup on RDoc main page. Bug #24168 by rhubarb. + * Fixed display of \\ character in documentation proceeding words. + Bug #22112 by James Gray. See RDoc for details. + * Fixed parsing and display of arg params for some corner cases. Bug #21113 + by Csiszár Attila. + * Fixed links in Files box. Patch #24403 by Eric Wong. + * Toplevel methods now appear in Object. Bug #22677 by Ryan Davis. + * Added back --promiscuous which didn't do anything you cared about. Why + did you enable it? Nobody looked at that page! Oh, it warns, too. + +== 2.4.1 / 2009-02-26 + +* 1 Minor Enhancements + * Added :attr:, :attr_reader:, :attr_writer:, :attr_accessor: directives. + Replaces --accessor. See RDoc::Parser::Ruby for details. + +* 3 Bug Fixes + * Don't complain when exiting normally. Bug by Matt Neuburg. + * Restore --inline-source that warns + * Fixed links to files in Darkfish output + +== 2.4.0 / 2009-02-24 + +* 9 Minor Enhancements + * `ri -f html` is now XHTML-happy + * Clarified RDoc::Markup link syntax. Bug #23517 by Eric Armstrong. + * Number of threads to parse with is now configurable + * Darkfish can now use alternate templates from $LOAD_PATH via -T + * Removed F95 parser in favor of the rdoc-f95 gem + * Moved HTML and XML generators to unmaintained + * No gem will be provided as it's too difficult to make them work + * Removed options --one-file, --style=, --inline-source, --promiscuous, + --op-name + * Removed support for --accessor, use regular documentation or + the method directive instead. See RDoc::Parser::Ruby + * Removed --ri-system as it is unused by Ruby's makefiles + * Added method list to index.html + +* 6 Bug Fixes + * A class marked nodoc no longer appears in the index. Bug #23751 by + Clifford Heath. + * Fix 1.9 compatibility issues. Bug #23815 by paddor. + * Darkfish now respects --charset + * RDoc no longer attempts to be lazy when building HTML. This is a + workaround. Bug #23893 by Stefano Crocco. + * RDoc doesn't crash with def (blah).foo() end + * RDoc doesn't crash with #define functions + +== 2.3.0 / 2009-01-28 + +* 3 Major Enhancements + * Michael Granger's Darkfish generator is now the default for HTML output + * Various rdoc generation speedups by Hongli Lai. Patches #22555, #22556, + #22557, #22562, #22565. + * rdoc/discover.rb files are loaded automatically from installed gems + +* 8 Minor Enhancements + * Added a space after the commas in ri class method lists. RubyForge + enhancement #22182. + * Improved ri --interactive + * Generators can now override generated file locations + * Moved unmaintained CHM generator to it's own package + * Moved unmaintained extra HTML templates to their own package + * Removed experimental texinfo generator + * Converted to minitest + * Known classes and modules list outputs once per line now for grep + +* 11 Bug Fixes + * Fix missing superclass in ri output + * Fix an RDoc crash when told to parse an empty file + * Ignore nonexistent files instead of crashing + * .txt and .rdoc files are always considered text. Patch #22897 by Aaron + Patterson. + * When merging ri data with a nonexistent directory, RDoc no longer crashes + * Fix visibility of methods in XML output. Issue by Yehuda Katz. + * Fixed relative link generation + * Fix crash, RDoc now ignores comments above local variable assignments in + modules + * RDoc now only accepts adjacent comments for rb_define_module and + rb_define_class + * C file RDoc is no longer included in token stream + * Scan all gem paths to match gem name for ri output + +== 2.2.1 / 2008-09-24 +This version provides some minor fixes and enhancements to 2.2.0 intended +to polish RDoc for Ruby 1.9.1. + +* 3 Minor Enhancements + * Support for parsing RDoc from SWIG. Ruby patch #10742 by Gonzalo + Garramuno, #13993 by Steven Jenkins. + * Simple support for Perl POD documentation. Patch by Hugh Sasse. + * Changed the default character set of RDoc's output from iso-8859-1 to + utf-8. + +* 9 Bug Fixes + * Explicitly set the html template's text color, so that the generated + documentation will display correctly on browsers with custom text and + background color settings (patch by Luther Thompson). + * Ensure that RDoc correctly will associate an alias and a method, even + if it encounters the alias first because the alias lives in a different + file. + * Fix the parsing of multiline constants (patch by Chris Alfeld and + Joel VanderWerf) + * Make --exclude usuable. Ruby patch #11671 by Trans. + * Detect inline C functions. Ruby Bug #11993 by Florian Frank. + * Fix an issue in which RDoc might not document a class' + superclass correctly if the class was defined in multiple files and + depending on the order in which RDoc processed the files. This should + ensure that the child class -> parent class relationship is correct in + ri documentation, allowing ri to lookup inherited methods (i.e., File.read). + * Stop ri from crashing when it looks for a completely bogus method (i.e., + File#reada). Now, ri exits with a helpful error message. + * Fixed missing display of constant values in ri. + * Fixed display of constants in ri's html output. + +== 2.2.0 / 2008-09-19 +This version includes some significant enhancements to ri. See RI.txt for +documentation about ri. + +* 5 Major Enhancements + * More extensive unit tests (special thanks to Chris Lowis for contributing + a test). + * Made ri twice as fast for the most common use case of displaying + information for a class or a fully-qualified method + (i.e., ri Array#flatten, after ri has created a cache the first time that + it runs). + * Made ri many times faster when searching for an unqualified method (i.e., + ri read, again after the first such search has populated ri's cache) + * Changed ri to do regular expression searches for unqualified methods; + now, a regular expression for a method can be passed to ri on the + command-line. + * Added an interactive mode to ri (patch by Daniel Choi). Now, when ri + is given a -i argument, it will allow the user to disambiguate + unqualified methods if more than one is present and also will allow a + user to get information for a class' method. + +* 8 Minor Enhancements + * RDoc now adds the package title to the web pages that it generates + for files and classes/modules, which helps them appear better in + search engine results. + * RDoc now automatically generates cross-reference links for classes and + methods specified relative to the global namespace (i.e., ::A::B::C#method). + * All built-in templates now output valid, strict XHTML. + * The documentation is slightly better organized (the markup details were + merged into the RDoc module's documentation). + * Improved rdoc's HTML generation speed by about 20% (on Windows, the + boost seems larger). + * Provided an ri command-line option to control its caching behavior. + * Improved RDoc's documentation. Added RI.txt to document ri. + * Allow HTML templates distributed as gems to be loaded with the -T option, + just like the standard templates in rdoc/generator/html (so an HTML + template lib/new_template.rb in a gem can be used with rdoc -T new_template) + +* 25 Bug fixes: + * Fixed prototype detection in C parser. Can process ruby 1.8 C files + again. + * Fixed the main page for frameless template. Patch by Marcin Raczkowski. + * Fixed the main page for frame templates. Now, if no main page is + specified, RDoc will default to the README. + * Fixed missing stylesheet in generated chm. Patch by Gordon Thiesfeld. + * Fixed the parsing of module names starting with '::'. Patch by + Giuseppe Bilotta. + * Fixed a case where RDoc first would encounter Foo::Bar and then would + encounter class Foo. Previously, RDoc erroneously would have considered + that both a Foo class and a Foo module existed. + * Fix a class where RDoc would not generate correct cross-reference links + to a class contained within a module of the same name (i.e. RDoc::RDoc) + * Prevented RDoc from trying to parse binary files, which would produce + garbage output. + * RDoc now correctly converts ' characters to apostrophes, opening single + quotes, and closing single quotes in most cases (smart single quotes). + * RDoc now correctly converts " characters to opening double quotes and + and closing double quotes in most cases (smart double quotes). + * (c) correctly is converted into the copyright symbol. + * '&' characters in text now correctly are translated to HTML character codes. + * Fixed missing stylesheet in generated chm. Patch by Gordon Thiesfeld. + * Fixed broken method links in the built-in templates. + * RDoc properly links to files and classes in the one page HTML template. + * The kilmer and hefss templates properly syntax highlight when inlining + source code. + * The kilmer and hefss template class pages properly display methods again. + * Fixed broken class, file, and method links in the frameless template. + * Fixed the clipping of source code in the html and frameless templates when + the source code cannot fit into the window; a scrollbar now will allow + all of the source code to be viewed. + * Fixed the missing constant descriptions in the html and frameless + templates. + * Fixed the ri command-line options that customize the directories to be + searched for documentation. + * Fixed the XML generator. Patch by Anthony Durity. + * Stopped the XML template from generating invalid XML due to malformed + embedded ruby. + * Adding missing information about a class' constants to the XML template. + * Fixed the horizontal rule markup (---) so that it correctly adds a + horizontal rule rather than suppressing all text that follows. + +== 2.1.0 / 2008-07-20 + +* 3 Major Enhancements: + * RDoc now knows about meta-programmed methods, see RDoc::Parser::Ruby + * Reorganized parsers under RDoc::Parser base class + * ri now walks the ancestors of a class looking for a method e.g. ri + File#read displays documentation for IO#read (may require regeneration of + ri data) +* 5 Minor Enhancements: + * Allow links to files + * Default options now taken from RDOCOPT environment variable + * Class method documentation can be found at toplevel now (def X.foo) + * Allow HTML templates distributed as gems to be loaded with the -T option, + just like the standard templates in rdoc/generator/html (so an HTML + template lib/new_template.rb in a gem can be used with rdoc -T new_template) + * `rdoc -v` prints out files, classes, modules and methods as it goes +* 11 Bug Fixes: + * `ri Foo.bar` now looks for class methods also + * Sections work in the default template again + * Doesn't warn about :foo:: list item being an unrecognized directive + * RDoc no longer converts characters inside tt tags + * Fixed "uninitialized constant RDoc::Markup::ToHtml::HTML" + * Fixed generation of relative links + * Fixed various diagram generation issues + * Fixed templates broken by switch to erb + * Fixed issue with style comments + * Lowercase words are no longer rdoc'd as methods without leading #, as + described in the documentation + * RDoc now correctly sets superclasses if they were originally unknown + +== 2.0.0 / 2008-04-10 + +* 3 Major Enhancements: + * Renamespaced everything RDoc under the RDoc module. + * New `ri` implementation. + * Reads from a cache in ~/.ri/ for enhanced speed. + * RubyGems aware, only searches latest gem versions. + * Now up to over 100 tests and 200 assertions. +* 4 Minor Enhancements: + * Switched to an ERb-based TemplatePage, see RDoc::TemplatePage. + * Class/module ri now displays attribute and constant comments. + * Cross-references can be disabled with a leading \. + * Relaxed parsing for some RDoc inline markup. diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/LEGAL.rdoc b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/LEGAL.rdoc new file mode 100644 index 00000000..dae10591 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/LEGAL.rdoc @@ -0,0 +1,50 @@ +# coding: UTF-8 + += Legal Notice Information + +The files in this distribution are covered by the Ruby license (see LICENSE) except the features mentioned below: + +Darkfish:: + Darkfish was written by Michael Granger and is included under the BSD 3-Clause + license. Darkfish contains images from the Silk Icons set by Mark James. + + See lib/rdoc/generator/darkfish.rb for license information. + + * lib/rdoc/generator/darkfish.rb + * lib/rdoc/generator/template/darkfish/* + * lib/rdoc/generator/template/darkfish/images + +SDoc:: + Portions of SDoc by (Володя Колесников) Vladimir Kolesnikov are included + under the MIT license as RDoc::Generator::JsonIndex. See + lib/rdoc/generator/json_index.rb for license information. + + * lib/rdoc/generator/json_index.rb + * lib/rdoc/generator/template/json_index/* + * The +#search_index+ methods on RDoc::CodeObject subclasses were derived + from sdoc. + * RDoc::ClassModule#document_self_or_methods comes from SDoc. + +peg-markdown:: + RDoc's Markdown support is derived from peg-markdown by John MacFarlane. It + is used under the MIT license. See RDoc::Markdown for license details. + +MarkdownTest:: + test/test_rdoc_markdown_test.rb uses MarkdownTest 1.0.3's source files which + are included as test/MarkdownTest_1.0.3/*.text which are Copyright (c) + 2004-2005 John Gruber http://daringfireball.net and is included under the + same terms as Perl itself. + + See http://dev.perl.org/licenses/ for the terms of the Perl license. + +Fonts:: + Source Code Pro is (c) 2010, 2012 Adobe Systems Incorporated. + + Lato is (c) 2010 Łukasz Dziedzic. + + Both fonts are used under the SIL Open Font License, Version 1.1. The + license is available at http://scripts.sil.org/OFL + + See lib/rdoc/generator/template/darkfish/fonts.css for complete copyright + and license information, including a copy of the OFL. + diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/LICENSE.rdoc b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/LICENSE.rdoc new file mode 100644 index 00000000..c61bb933 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/LICENSE.rdoc @@ -0,0 +1,59 @@ += License + +RDoc is copyrighted free software. + +You can redistribute it and/or modify it under either the terms of the GPL +version 2 (see the file GPL), or the conditions below: + +1. You may make and give away verbatim copies of the source form of the + software without restriction, provided that you duplicate all of the + original copyright notices and associated disclaimers. + +2. You may modify your copy of the software in any way, provided that + you do at least ONE of the following: + + a. place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said + modifications to Usenet or an equivalent medium, or by allowing + the author to include your modifications in the software. + + b. use the modified software only within your corporation or + organization. + + c. give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d. make other distribution arrangements with the author. + +3. You may distribute the software in object code or binary form, + provided that you do at least ONE of the following: + + a. distribute the binaries and library files of the software, + together with instructions (in the manual page or equivalent) + on where to get the original distribution. + + b. accompany the distribution with the machine-readable source of + the software. + + c. give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d. make other distribution arrangements with the author. + +4. You may modify and include the part of the software into any other + software (possibly commercial). But some files in the distribution + are not written by the author, so that they are not under these terms. + + For the list of those files and their copying conditions, see the + file LEGAL. + +5. The scripts and library files supplied as input to or produced as + output from the software do not automatically fall under the + copyright of the software, but belong to whomever generated them, + and may be sold commercially, and may be aggregated with this + software. + +6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/README.rdoc b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/README.rdoc new file mode 100644 index 00000000..c4b60b29 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/README.rdoc @@ -0,0 +1,144 @@ += \RDoc - Ruby Documentation System + +home :: https://github.com/ruby/rdoc +rdoc :: https://ruby.github.io/rdoc +bugs :: https://github.com/ruby/rdoc/issues +code quality :: https://codeclimate.com/github/ruby/rdoc + +== Description + +RDoc produces HTML and command-line documentation for Ruby projects. RDoc +includes the +rdoc+ and +ri+ tools for generating and displaying documentation +from the command-line. + +== Generating Documentation + +Once installed, you can create documentation using the +rdoc+ command + + $ rdoc [options] [names...] + +For an up-to-date option summary, type + + $ rdoc --help + +A typical use might be to generate documentation for a package of Ruby +source (such as RDoc itself). + + $ rdoc + +This command generates documentation for all the Ruby and C source +files in and below the current directory. These will be stored in a +documentation tree starting in the subdirectory +doc+. + +You can make this slightly more useful for your readers by having the +index page contain the documentation for the primary file. In our +case, we could type + + % rdoc --main README.rdoc + +You'll find information on the various formatting tricks you can use +in comment blocks in the documentation this generates. + +RDoc uses file extensions to determine how to process each file. File names +ending +.rb+ and +.rbw+ are assumed to be Ruby source. Files +ending +.c+ are parsed as C files. All other files are assumed to +contain just Markup-style markup (with or without leading '#' comment +markers). If directory names are passed to RDoc, they are scanned +recursively for C and Ruby source files only. + +To generate documentation using +rake+ see RDoc::Task[https://ruby.github.io/rdoc/RDoc/Task.html]. + +To generate documentation programmatically: + + gem 'rdoc' + require 'rdoc/rdoc' + + options = RDoc::Options.new + options.files = ['a.rb', 'b.rb'] + options.setup_generator 'darkfish' + # see RDoc::Options + + rdoc = RDoc::RDoc.new + rdoc.document options + # see RDoc::RDoc + +You can specify the target files for document generation with +.document+ file in the project root directory. ++.document+ file contains a list of file and directory names including comment lines starting with '#'. +See https://github.com/ruby/rdoc/blob/master/.document as an example. + +== Writing Documentation + +To write documentation for RDoc place a comment above the class, module, +method, constant, or attribute you want documented: + + ## + # This class represents an arbitrary shape by a series of points. + + class Shape + + ## + # Creates a new shape described by a +polyline+. + # + # If the +polyline+ does not end at the same point it started at the + # first pointed is copied and placed at the end of the line. + # + # An ArgumentError is raised if the line crosses itself, but shapes may + # be concave. + + def initialize polyline + # ... + end + + end + +The default comment markup format is the RDoc::Markup format. +TomDoc[rdoc-ref:RDoc::TomDoc], Markdown[rdoc-ref:RDoc::Markdown] and +RD[rdoc-ref:RDoc::RD] format comments are also supported. You can set the +default comment format for your entire project by creating a +.rdoc_options file. See RDoc::Options@Saved+Options for instructions +on creating one. You can also set the comment format for a single file +through the +:markup:+ directive, but this is only recommended if you wish to +switch markup formats. See RDoc::Markup@Other+directives. + +Comments can contain directives that tell RDoc information that it cannot +otherwise discover through parsing. See RDoc::Markup@Directives to control +what is or is not documented, to define method arguments or to break up +methods in a class by topic. See RDoc::Parser::Ruby for directives used to +teach RDoc about metaprogrammed methods. + +See RDoc::Parser::C for documenting C extensions with RDoc. + +To determine how well your project is documented run rdoc -C lib to +get a documentation coverage report. rdoc -C1 lib includes parameter +names in the documentation coverage report. + +== Theme Options + +There are a few community-maintained themes for \RDoc: + +- rorvswild-theme-rdoc[https://github.com/BaseSecrete/rorvswild-theme-rdoc] +- hanna[https://github.com/jeremyevans/hanna] (a fork maintained by {Jeremy Evans}[https://github.com/jeremyevans]) + +Please follow the theme's README for usage instructions. + +== Bugs + +See CONTRIBUTING.rdoc for information on filing a bug report. It's OK to file +a bug report for anything you're having a problem with. If you can't figure +out how to make RDoc produce the output you like that is probably a +documentation bug. + +== License + +RDoc is Copyright (c) 2001-2003 Dave Thomas, The Pragmatic Programmers. +Portions (c) 2007-2011 Eric Hodel. Portions copyright others, see individual +files and LEGAL.rdoc for details. + +RDoc is free software, and may be redistributed under the terms specified in +LICENSE.rdoc. + +== Warranty + +This software is provided "as is" and without any express or implied +warranties, including, without limitation, the implied warranties of +merchantability and fitness for a particular purpose. diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/RI.md b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/RI.md new file mode 100644 index 00000000..45addacd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/RI.md @@ -0,0 +1,842 @@ +# `ri`: Ruby Information + +`ri` (ruby information) is the Ruby command-line utility +that gives fast and easy on-line access to Ruby documentation. + +`ri` can show documentation for Ruby itself and for its installed gems: + +- A **class** or **module**: + text associated with the class or module definition + in a source file (`.rb` or `.c`). +- One or more **methods**: + text associated with method definitions + in source files (`.rb` and `.c`). +- A **page**: + text from a stand-alone documentation file + (`.rdoc` or `.md`, or sometimes other). + +Examples (output omitted): + +```sh +$ ri Hash # Document for class Hash. +$ ri Array#sort # Document for instance method sort in class Array. +$ ri read # Documents for methods ::read and #read in all classes and modules. +$ ri ruby:dig_methods # Document for page dig_methods. +``` + +`ri` can also show lists of: + +- **classes** and **modules**: + full or partial list. +- **pages**: + for Ruby or for an installed gem. + +Examples (output omitted): + +```sh +$ ri --list # List of classes and modules. +$ ri ruby: # List of Ruby pages. +``` + +## Why `ri`? + +Using `ri` may have advantages over using +the [Ruby online documentation](https://docs.ruby-lang.org/en/master): + +- The `ri` documentation is always available, even when you do not have internet access + (think: airplane mode). +- If you are working in a terminal window, typing `ri _whatever_` (or just `ri`) + may be faster than navigating to a browser window and searching for documentation. +- If you are working in an + [irb \(interactive Ruby\)](https://docs.ruby-lang.org/en/master/IRB.html) + session, you _already_ have immediate access to `ri`: + just type `'show_doc'`. + +## Modes + +There are two `ri` modes: + +- Static mode: + In general, `ri` responds in its static mode + if a _name_ is given; + it shows results and exits (as in the examples above). + See [Static Mode][1]. +- Interactive mode: + In general, `ri` enters its interactive mode + if no _name_ is given; + in interactive mode, `ri` shows results and waits for another command: + + ```sh + $ ri + Enter the method name you want to look up. + You can use tab to autocomplete. + Enter a blank line to exit. + >> + ``` + + See [Interactive Mode][2]. + +## Names + +In both modes, static and interactive, +`ri` responds to an input _name_ that specifies what is to be displayed: +a document, multiple documents, or other information: + +- Static mode (in the shell): type `'ri _name_'`; + examples (output omitted): + + ```sh + $ ri File + $ ri IO#readlines + $ ri ruby: + ``` + +- Interactive mode (already in `ri`): just type the _name_; + examples (output omitted): + + ```sh + $ ri + Enter the method name you want to look up. + You can use tab to autocomplete. + Enter a blank line to exit. + >> File + >> IO#readlines + >> ruby: + ``` + +### Names for Class and Module Documents + +These example `ri` commands cite names for class and module documents +(see [details and examples][3]): + +| Command | Shows | +|------------------------------|------------------------------------------------------------| +| ri File | Document for Ruby class File. | +| ri File::Stat | Document for Ruby nested class File::Stat. | +| ri Enumerable | Document for Ruby module Enumerable. | +| ri Arr | Document for Ruby class Array (unique initial characters). | +| ri Nokogiri::HTML4::Document | Document for gem class Nokogiri::HTML4::Document. | +| ri Nokogiri | Document for gem module Nokogiri. | +
+ +If [option \\--all][4] +is in effect, documents for the methods in the named class or module +are included in the display. + +### Names for Method Documents + +These example `ri` commands cite names for method documents +(see [details and examples][5]): + +| Command | Shows | +|--------------------------------------|----------------------------------------------------------------------------------| +| ri IO::readlines | Document for Ruby class method IO::readlines. | +| ri IO#readlines | Document for Ruby instance method IO::readlines. | +| ri IO.readlines | Documents for Ruby instance method IO::readlines and class method IO::readlines. | +| ri ::readlines | Documents for all class methods ::readlines. | +| ri #readlines | Documents for all instance methods #readlines. | +| ri .readlines, ri readlines | Documents for class methods ::readlines and instance methods #readlines. | +| ri Nokogiri::HTML4::Document::parse | Document for gem class method Nokogiri::HTML4::Document::parse. | +| ri Nokogiri::HTML4::Document#fragment | Document for gem instance method Nokogiri::HTML4::Document#fragment. | +
+ +### Names for Page Documents + +These example `ri` commands cite names for page documents +(see [details and examples][6]): + +| Command | Shows | +|--------------------------------|--------------------------------------------------| +| ri ruby:syntax/assignment.rdoc | Document for Ruby page assignment. | +| ri ruby:syntax/assignment | Same document, if no other syntax/assignment.*. | +| ri ruby:assignment | Same document, if no other */assignment.*. | +| ri nokogiri:README.md | Document for page README.md. | +
+ +### Names for Lists + +These example `ri` commands cite names for lists +(see [details and examples][7]): + +| Command | Shows | +|---------------|-------------------------| +| ri ruby: | List of Ruby pages. | +| ri nokogiri: | List of Nokogiri pages. | +
+ +There are more lists available; +see [option \\--list][8]. + +## Pro Tips + +### `ri` at the Ready + +If you are a frequent `ri` user, +you can save time by keeping open a dedicated command window +with either of: + +- A running [interactive ri][2] session. +- A running [irb session][9]; + type `'show_doc'` to enter `ri`, newline to exit. + +When you switch to that window, `ri` is ready to respond quickly, +without the performance overhead of re-reading `ri` sources. + +### Output Filters + +The `pager` value actually need not be simply the path to an executable; +it's actually a full-fledged command line, +and so may include not only the executable path, +but also whatever options and arguments that executable accepts. + +You can, for example, set the pager value to `'grep . | less'`, +which will exclude blank lines (thus saving screen space) +before piping the result to `less`; +example (output omitted): + +```sh +$ RI_PAGER="grep . | less" ri Array +``` + +See the documentation for your chosen pager programs +(e.g, type `'grep --help'`, `'less --help'`). + +### Links in `ri` Output + +#### Implicit Link + +When you see: + +- `'IO::readlines'`, `'IO#readlines'`, `'IO.readlines'`: + use that same text as the _name_ in an `ri` command. + + Examples (output omitted): + + ```sh + $ ri IO::readlines + $ ri IO#readlines + $ ri IO.readlines + ``` + +- `'#read'`, `'::read'`, `'.read'`: + you're likely already in the `ri` document for a class or module, + or for a method in a class or module; + use that same text with the name of the class or module (such as `'File'`) + as the _name_ in an `ri` command. + + Examples (output omitted): + + ```sh + $ ri File::read + $ ri File#read + $ ri File.read + ``` + +#### Explicit Link + +When you see: + +- `'{Dig Methods}[rdoc-ref:doc/dig_methods.rdoc]'`: + use the trailing part of the `'[rdoc-ref:doc/'` in an `ri` command + for a Ruby document. + + Example (output omitted): + + ```sh + $ ri ruby:dig_methods.rdoc + ``` + +- `'{Table (information)}[https://en.wikipedia.org/wiki/Table_(information)]'`: + go to the given URL in your browser. + +## About the Examples + +- `ri` output can be large; + to save space, an example may pipe it to one of these: + + - [head](https://www.man7.org/linux/man-pages/man1/head.1.html): leading lines only. + - [tail](https://www.man7.org/linux/man-pages/man1/tail.1.html): trailing lines only. + - [wc -l](https://www.man7.org/linux/man-pages/man1/wc.1.html): line count only. + - [grep](https://www.man7.org/linux/man-pages/man1/grep.1.html): selected lines only. + +- An example that involves a gem assumes that gems `nokogiri` and `minitest` are installed. + +## `ri` Documents + +This section outlines what you can expect to find +in the `ri` document for a class, module, method, or page. + +See also: + +- [Pager][10]. +- [Links in ri Output][11]. + +### Class and Module Documents + +The document for a class or module shows: + +- The class or module name, along with its parent class if any. +- Where it's defined (Ruby core or gem). +- When each exists: + + - The names of its included modules. + - The text of its embedded documentation. + - Its constants. + - Its class methods. + - Its instance methods. + +Examples: + +- Ruby class `Array`: + + ```sh + $ ri Array | head + = Array < Object + + ------------------------------------------------------------------------ + = Includes: + Enumerable (from ruby core) + + (from ruby core) + ------------------------------------------------------------------------ + An Array is an ordered, integer-indexed collection of objects, called + elements. Any object may be an Array element. + ``` + +- Gem module `Nokogiri`: + + ```sh + $ ri Nokogiri | head + = Nokogiri + + (from gem nokogiri-1.16.2-x86_64-linux) + ------------------------------------------------------------------------ + + Nokogiri parses and searches XML/HTML very quickly, and also has + correctly implemented CSS3 selector support as well as XPath 1.0 + support. + + Parsing a document returns either a Nokogiri::XML::Document, or a + ``` + +The document typically includes certain headings, +which may be useful for searching: + +```sh +$ ri IO | grep "^= " += IO < Object += Includes: += Constants: += Class methods: += Instance methods: +``` + +### Method Documents + +The document for a method includes: + +- The source of the method: `'(from ruby core)'` or `'(from gem _gem_)'`. +- The calling sequence(s) for the method. +- The text of its embedded documentation (if it exists). + +Examples: + +```sh +$ ri IO#read | head += IO#read + +(from ruby core) +------------------------------------------------------------------------ +ios.read([length [, outbuf]]) -> string, outbuf, or nil + +------------------------------------------------------------------------ + +Reads length bytes from the I/O stream. +``` + +```sh +$ ri Nokogiri::parse | head += Nokogiri::parse + +(from gem nokogiri-1.16.2-x86_64-linux) +------------------------------------------------------------------------ + parse(string, url = nil, encoding = nil, options = nil) { |doc| ... } + +------------------------------------------------------------------------ + +Parse an HTML or XML document. string contains the document. +``` + +The output for a _name_ that cites methods includes the document +for each found implementation; +the number of such implementations depends on the _name_: + +- Within a class: + + Each of these commands shows documents + for methods in Ruby class `IO` (output omitted): + + ```sh + $ ri IO::readlines # Class method ::readlines. + $ ri IO#readlines # Instance method #readlines. + $ ri IO.readlines # Both of above. + ``` + +- In all classes: + + Each of these commands shows documents + for methods in all classes (output omitted): + + ```sh + $ ri ::readlines # Class method ::readlines. + $ ri \#readlines # Instance method #readlines. + $ ri .readlines # Both of above. + ``` + + For these all-classes commands, + the output is organized into sections, + one for each found method (output filtered to show sections): + + ```sh + $ ri ::readlines | grep "= Implementation" + === Implementation from CSV + === Implementation from IO + ``` + + ```sh + $ ri \#readlines | grep "= Implementation" + === Implementation from ARGF + === Implementation from CSV + === Implementation from IO + === Implementation from Kernel + === Implementation from Buffering + === Implementation from Pathname + === Implementation from StringIO + === Implementation from GzipReader + ``` + + ```sh + $ ri .readlines | grep "= Implementation" + === Implementation from ARGF + === Implementation from CSV + === Implementation from CSV + === Implementation from IO + === Implementation from IO + === Implementation from Kernel + === Implementation from Buffering + === Implementation from Pathname + === Implementation from StringIO + === Implementation from GzipReader + ``` + +### Page Documents + +The document for a Ruby page is the text from the `.rdoc` or `.md` source +for that page: + +```sh +$ ri ruby:dig_methods | head += Dig Methods + +Ruby's dig methods are useful for accessing nested data structures. + +Consider this data: + item = { + id: "0001", + type: "donut", + name: "Cake", + ppu: 0.55, +``` + +The document for a gem page is whatever the gem has generated +for the page: + +```sh +$ ri minitest:README | head += minitest/{test,spec,mock,benchmark} + +home: + https://github.com/minitest/minitest + +bugs: + https://github.com/minitest/minitest/issues + +rdoc: + https://docs.seattlerb.org/minitest +``` + +## `ri` Lists + +The list of Ruby pages is available via _name_ `'ruby:'`: + +```sh +$ ri ruby: | head += Pages in ruby core + +CONTRIBUTING.md +COPYING +COPYING.ja +LEGAL +NEWS-1.8.7 +NEWS-1.9.1 +NEWS-1.9.2 +NEWS-1.9.3 +``` + +```sh +$ ri ruby: | tail +syntax/control_expressions.rdoc +syntax/exceptions.rdoc +syntax/literals.rdoc +syntax/methods.rdoc +syntax/miscellaneous.rdoc +syntax/modules_and_classes.rdoc +syntax/pattern_matching.rdoc +syntax/precedence.rdoc +syntax/refinements.rdoc +win32/README.win32 +``` + +The list of gem pages is available via _name_ `'_gem_name_'`: + +```sh +$ ri nokogiri: | head += Pages in gem nokogiri-1.16.2-x86_64-linux + +README.md +lib/nokogiri/css/tokenizer.rex +``` + +See also: + +- [Option \\--list][8]: + lists classes and modules. +- [Option \\--list-doc-dirs][12]: + lists `ri` source directories. + +## `ri` Information + +With certain options, +an `ri` command may display information other than documents or lists: + +- [Option \\--help or -h][13]: + Shows `ri` help text. +- [option \\--version or -v][14]: + Shows `ri` version. +- [Option \\--dump=FILEPATH][15]: + Shows dump of `ri` cache file at the given filepath. + +## Static Mode + +In static mode, `ri` shows a response and exits. + +In general, `ri` responds in static mode +if the command gives a _name_: + +```sh +$ ri Array | head += Array < Object + +------------------------------------------------------------------------ += Includes: +Enumerable (from ruby core) + +(from ruby core) +------------------------------------------------------------------------ +An Array is an ordered, integer-indexed collection of objects, called +elements. Any object may be an Array element. +``` + +`ri` also responds in static mode when certain options are given, +even when no _name_ is given; +see [ri Information][16]. + +## Interactive Mode + +In general, `ri` responds to a command in interactive mode +if the command has no arguments: + +```sh +$ ri +Enter the method name you want to look up. +You can use tab to autocomplete. +Enter a blank line to exit. +>> + +``` + +A command in interactive mode are similar to one in static mode, +except that it: + +- Omits command word `ri`; you just type the _name_. +- Omits options; in interactive mode the only options in effect + are those taken from environment variable `RI`. + See [Options][17]. +- Supports tab auto-completion for the name of a class, module, or method; + when, for example, you type `"Arr\t"` (here `"\t` represents the tab character), + `ri` "completes" the text as `'Array '`. + +See also [ri at the Ready][18]. + +## Pager + +Because `ri` output is often large, +`ri` by default pipes it to a _pager_, +which is the program whose name is the first-found among: + +- The value of `ENV['RI_PAGER']`. +- The value of `ENV['PAGER']`. +- `'pager'`. +- `'less'`. +- `'more'`. + +If none is found, the output goes directly to `$stdout`, with no pager. + +If you set environment variable `RI_PAGER` or `PAGER`, +its value should be the name of an executable program +that will accept the `ri` output (such as `'pager'`, `'less'`, or `'more'`). + +See also [Output Filters][19]. + +## Options + +Options may be given on the `ri` command line; +those should be whitespace-separated, and must precede the given _name_, if any. + +Options may also be specified in environment variable `RI`; +those should also be whitespace-separated. + +An option specified in environment variable `RI` +may be overridden by an option on the `ri` command line: + +```sh +$ RI="--all" ri Array | wc -l +4224 +$ RI="--all" ri --no-all Array | wc -l +390 +``` + +### Source Directories Options + +#### Options `--doc-dir=DIRPATH`, `-d DIRPATH` + +Option `--doc-dir=DIRPATH` (aliased as `-d`) adds the given directory path +to the beginning of the array of `ri` source directory paths: + +```sh +$ ri --doc-dir=/tmp --list-doc-dirs | head -1 +/tmp +``` + +#### Options `--gems`, `--no-gems` + +Option `--gems` (the default) specifies that documents from installed gems +may be included; +option `--no-gems` may be used to exclude them: + +```sh +$ ri --list | wc -l +1417 +$ ri --list --no-gems| wc -l +1262 +``` + +#### Options `--home`, `--no-home` + +Option `--home` (the default) specifies that `ri` is to include source directory +in `~/.rdoc` if it exists; +option `--no-home` may be used to exclude them. + +#### Options `--list-doc-dirs`, `--no-list-doc-dirs` + +Option `--list-doc-dirs` specifies that a list of the `ri` source directories +is to be displayed; +default is `--no-list-doc-dirs`. + +#### Option `--no-standard` + +Option `--no-standard` specifies that documents from the standard libraries +are not to be included; +default is to include documents from the standard libraries. + +#### Options `--site`, `--no-site` + +Option `--site` (the default) specifies that documents from the site libraries +may be included; +option `--no-site` may be used to exclude them. + +#### Options `--system`, `--no-system` + +Option `--system` (the default) specifies that documents from the system libraries +may be included; +option `--no-system` may be used to exclude them. + +### Mode Options + +#### Options `--interactive`, `-i`, `--no-interactive` + +Option `--interactive` (aliased as `-i`) +specifies that `ri` is to enter interactive mode (ignoring the _name_ if given); +the option is the default when no _name_ is given; +option `--no-interactive` (the default) +specifies that `ri` is not to enter interactive mode, +regardless of whether _name_ is given. + +### Information Options + +#### Options `--help`, `-h` + +Option `--help` (aliased as `-h`) specifies that `ri` is to show +its help text and exit. + +#### Options `--version`, `-v` + +Option `--version` (aliased as `-v`) specifies that `ri` is to show its version and exit. + +### Debugging Options + +#### Options `--dump=FILEPATH`, `--no-dump` + +Option `--dump=FILEPATH` specifies that `ri` is to dump the content +of the `.ri` file at the given file path; +option`--no-dump` (the default) specifies that `ri` is not to dump content. + +The file path may point to any `.ri` file, +but typically would point to one named `cache.ri`: + +```sh +$ ri --dump=/usr/share/ri/3.0.0/system/cache.ri | wc -l +14487 +$ ri --dump=/usr/share/ri/3.0.0/system/cache.ri | head +{:ancestors=> + {"Array"=>["Enumerable", "Object"], + "RubyVM"=>["Object"], + "RubyVM::AbstractSyntaxTree::Node"=>["Object"], + "Object"=>["BasicObject", "Kernel"], + "Integer"=>["Numeric"], + "Module"=>["Object"], + "Class"=>["Module"], + "Complex"=>["Numeric"], + "NilClass"=>["Object"], +``` + +#### Options `--profile`, `--no-profile` + +Option `--profile` specifies that the program is to be run with the Ruby profiler; +option `no-profile` (the default) specifies that the program is not to be run +with the Ruby profiler. + +### Output Options + +#### Options `--format=FORMAT`, `-f FORMAT` + +Option `--format=FORMAT` (aliased as `-f`) specifies the formatter for the output, +which must be `ansi`, `bs`, `markdown`, or `rdoc`; +the default is `bs` for paged output, `ansi` otherwise. + +#### Options `--pager`, `--no-pager` + +Option `--pager` (the default) specifies that the output is to be piped +to a pager; +option `--no-pager` specifies that the output is not to be piped. + +#### Options `--width=NUMBER`, `-w NUMBER` + +Option `--width` (aliased as `-w`) specifies that the lengths of the displayed lines +should be restricted to the given _NUMBER_ of characters; +this is to be accomplished by line-wrapping, not truncation. +The default width is `80`: + +```sh +$ ri --width=40 Array | head += Array < Object + +---------------------------------------- += Includes: +Enumerable (from ruby core) + +(from ruby core) +---------------------------------------- +An Array is an ordered, integer-indexed +collection of objects, called +``` + + +### List Options + +#### Options `--list`, `-l`, `--no-list` + +Option `--list` (aliased as `-l`) specifies that all class and module names +whose initial characters match the given _name_ are to be displayed: +whose initial characters match the given _name_ are to be displayed: + +```sh +$ ri --list Ar | head +ArgumentError +Array +``` + +If no _name_ is given, all class and module names are displayed. + +Option `--no-list` (the default) specifies that a list of class and module names +is not to be displayed. + +### Methods Options (for Class or Module) + +#### Options `--all`, `-a`, `--no-all` + +Option `--all` (aliased as `-a`) specifies that when _name_ identifies a class or module, +the documents for all its methods are included; +option `--no-all` (the default) specifies that the method documents are not to be included: + +```shell +$ ri Array | wc -l +390 +$ ri --all Array | wc -l +4224 +``` + +### Server Option + +#### Option `--server=NUMBER` + +Option `--server` specifies that the \RDoc server is to be run on the port +given as _NUMBER_; +the default port is `8214`. + +## Generating `ri` Source Files + +`ri` by default reads data from directories installed by Ruby and gems. + +You can create your own `ri` source files. +This command creates `ri` source files in local directory `my_ri`, +from Ruby source files in local directory `my_sources`: + +```sh +$ rdoc --op my_ri --format=ri my_sources +``` + +Those files may then be considered for any `ri` command +by specifying option `--doc-dir=my_ri`; +see [option \\--doc-dir][20]. + +[1]: rdoc-ref:RI.md@Static+Mode +[2]: rdoc-ref:RI.md@Interactive+Mode +[3]: rdoc-ref:RI.md@Class+and+Module+Documents +[4]: rdoc-ref:RI.md@Options+--all-2C+-a-2C+--no-all +[5]: rdoc-ref:RI.md@Method+Documents +[6]: rdoc-ref:RI.md@Page+Documents +[7]: rdoc-ref:RI.md@ri+Lists +[8]: rdoc-ref:RI.md@Options+--list-2C+-l-2C+--no-list +[9]: https://docs.ruby-lang.org/en/master/IRB.html +[10]: rdoc-ref:RI.md@Pager +[11]: rdoc-ref:RI.md@Links+in+ri+Output +[12]: rdoc-ref:RI.md@Options+--list-doc-dirs-2C+--no-list-doc-dirs +[13]: rdoc-ref:RI.md@Options+--help-2C+-h +[14]: rdoc-ref:RI.md@Options+--version-2C+-v +[15]: rdoc-ref:RI.md@Options+--dump-3DFILEPATH-2C+--no-dump +[16]: rdoc-ref:RI.md@ri+Information +[17]: rdoc-ref:RI.md@Options +[18]: rdoc-ref:RI.md@ri+at+the+Ready +[19]: rdoc-ref:RI.md@Output+Filters +[20]: rdoc-ref:RI.md@Options+--doc-dir-3DDIRPATH-2C+-d+DIRPATH diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/TODO.rdoc b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/TODO.rdoc new file mode 100644 index 00000000..da919118 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/TODO.rdoc @@ -0,0 +1,60 @@ += TODO +This file contains some things that might happen in RDoc, or might not. +Forward Looking Statements applies. + +== RDoc::VERSION.succ + +=== Blockers: + +* Update LICENSE to match ruby's switch +* The alias keyword should not be bidirectional +* Fix RDoc::Parser#use_markup to handle the filename (see TODO) +* Restore backwards compatibility due to paragraph text joining from existing + ri files +* Fix consumption of , after link like: RDoc[rdoc-ref:RDoc], <- comma here +* Remove support for links like Matrix[*rows] + +=== Nice to have: + +* Parse only changed files (like in ruby) +* Page of Glory (or Shame) in HTML output showing documentation coverage + statistics. +* Link to the parent-class implementation of methods that use super +* Add direct accessor to RDoc::Options to RDoc::Task +* Remove "Public" in HTML output if there are only public methods +* Method markup support for rd documentation (per rd syntax) +* Improve SIGINFO handling +* Global variable support +* Provide the code_object to directive handlers + +== More Future + +=== API changes to RDoc + +* RDoc::TopLevel#add_method should automatically create the appropriate method + class rather than requiring one be passed in. +* Remove #comment= from Context subclasses in favor of #add_comment +* Add versions to RDoc::Markup syntax tree marshal format +* Comments can no longer be Strings + +== Crazy Ideas + +* Auto-normalize heading levels to look OK. It's weird to see an

in + the middle of a method section. +* RDoc::CodeObject + * Move into own namespace + * Rename TopLevel to File + * Rename Context to Container + * Rename NormalClass to Class + +== Accessibility + +Page title in right hand side + +Table of contents in left hand side as sub-list under main heading + +For class list, never method list, method summary at top + +table-of-contents-navigation div => nav + role="navigation" + +type "mod", focus is still on "mod" diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/exe/rdoc b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/exe/rdoc new file mode 100755 index 00000000..95b6eea2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/exe/rdoc @@ -0,0 +1,43 @@ +#!/usr/bin/env ruby +# +# RDoc: Documentation tool for source code +# (see lib/rdoc/rdoc.rb for more information) +# +# Copyright (c) 2003 Dave Thomas +# Released under the same terms as Ruby + +begin + gem 'rdoc' +rescue NameError => e # --disable-gems + raise unless e.name == :gem +rescue Gem::LoadError +end + +require 'rdoc/rdoc' + +begin + r = RDoc::RDoc.new + r.document ARGV +rescue Errno::ENOSPC + $stderr.puts 'Ran out of space creating documentation' + $stderr.puts + $stderr.puts 'Please free up some space and try again' +rescue SystemExit + raise +rescue Exception => e + if $DEBUG_RDOC then + $stderr.puts e.message + $stderr.puts "#{e.backtrace.join "\n\t"}" + $stderr.puts + elsif Interrupt === e then + $stderr.puts + $stderr.puts 'Interrupted' + else + $stderr.puts "uh-oh! RDoc had a problem:" + $stderr.puts e.message + $stderr.puts + $stderr.puts "run with --debug for full backtrace" + end + + exit 1 +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/exe/ri b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/exe/ri new file mode 100755 index 00000000..7fbed0c0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/exe/ri @@ -0,0 +1,12 @@ +#!/usr/bin/env ruby + +begin + gem 'rdoc' +rescue NameError => e # --disable-gems + raise unless e.name == :gem +rescue Gem::LoadError +end + +require 'rdoc/ri/driver' + +RDoc::RI::Driver.run ARGV diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc.rb new file mode 100644 index 00000000..b42059c7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc.rb @@ -0,0 +1,211 @@ +# frozen_string_literal: true +$DEBUG_RDOC = nil + +## +# RDoc produces documentation for Ruby source files by parsing the source and +# extracting the definition for classes, modules, methods, includes and +# requires. It associates these with optional documentation contained in an +# immediately preceding comment block then renders the result using an output +# formatter. +# +# For a simple introduction to writing or generating documentation using RDoc +# see the README. +# +# == Roadmap +# +# If you think you found a bug in RDoc see CONTRIBUTING@Bugs +# +# If you want to use RDoc to create documentation for your Ruby source files, +# see RDoc::Markup and refer to rdoc --help for command line usage. +# +# If you want to set the default markup format see +# RDoc::Markup@Markup+Formats +# +# If you want to store rdoc configuration in your gem (such as the default +# markup format) see RDoc::Options@Saved+Options +# +# If you want to write documentation for Ruby files see RDoc::Parser::Ruby +# +# If you want to write documentation for extensions written in C see +# RDoc::Parser::C +# +# If you want to generate documentation using rake see RDoc::Task. +# +# If you want to drive RDoc programmatically, see RDoc::RDoc. +# +# If you want to use the library to format text blocks into HTML or other +# formats, look at RDoc::Markup. +# +# If you want to make an RDoc plugin such as a generator or directive handler +# see RDoc::RDoc. +# +# If you want to write your own output generator see RDoc::Generator. +# +# If you want an overview of how RDoc works see CONTRIBUTING +# +# == Credits +# +# RDoc is currently being maintained by Eric Hodel . +# +# Dave Thomas is the original author of RDoc. +# +# * The Ruby parser in rdoc/parse.rb is based heavily on the outstanding +# work of Keiju ISHITSUKA of Nippon Rational Inc, who produced the Ruby +# parser for irb and the rtags package. + +module RDoc + + ## + # Exception thrown by any rdoc error. + + class Error < RuntimeError; end + + require_relative 'rdoc/version' + + ## + # Method visibilities + + VISIBILITIES = [:public, :protected, :private] + + ## + # Name of the dotfile that contains the description of files to be processed + # in the current directory + + DOT_DOC_FILENAME = ".document" + + ## + # General RDoc modifiers + + GENERAL_MODIFIERS = %w[nodoc].freeze + + ## + # RDoc modifiers for classes + + CLASS_MODIFIERS = GENERAL_MODIFIERS + + ## + # RDoc modifiers for attributes + + ATTR_MODIFIERS = GENERAL_MODIFIERS + + ## + # RDoc modifiers for constants + + CONSTANT_MODIFIERS = GENERAL_MODIFIERS + + ## + # RDoc modifiers for methods + + METHOD_MODIFIERS = GENERAL_MODIFIERS + + %w[arg args yield yields notnew not-new not_new doc] + + ## + # Loads the best available YAML library. + + def self.load_yaml + begin + gem 'psych' + rescue NameError => e # --disable-gems + raise unless e.name == :gem + rescue Gem::LoadError + end + + begin + require 'psych' + rescue ::LoadError + ensure + require 'yaml' + end + end + + ## + # Searches and returns the directory for settings. + # + # 1. $HOME/.rdoc directory, if it exists. + # 2. The +rdoc+ directory under the path specified by the + # +XDG_DATA_HOME+ environment variable, if it is set. + # 3. $HOME/.local/share/rdoc directory. + # + # Other than the home directory, the containing directory will be + # created automatically. + + def self.home + rdoc_dir = begin + File.expand_path('~/.rdoc') + rescue ArgumentError + end + + if File.directory?(rdoc_dir) + rdoc_dir + else + require 'fileutils' + begin + # XDG + xdg_data_home = ENV["XDG_DATA_HOME"] || File.join(File.expand_path("~"), '.local', 'share') + unless File.exist?(xdg_data_home) + FileUtils.mkdir_p xdg_data_home + end + File.join xdg_data_home, "rdoc" + rescue Errno::EACCES + end + end + end + + autoload :RDoc, "#{__dir__}/rdoc/rdoc" + + autoload :CrossReference, "#{__dir__}/rdoc/cross_reference" + autoload :ERBIO, "#{__dir__}/rdoc/erbio" + autoload :ERBPartial, "#{__dir__}/rdoc/erb_partial" + autoload :Encoding, "#{__dir__}/rdoc/encoding" + autoload :Generator, "#{__dir__}/rdoc/generator" + autoload :Options, "#{__dir__}/rdoc/options" + autoload :Parser, "#{__dir__}/rdoc/parser" + autoload :Servlet, "#{__dir__}/rdoc/servlet" + autoload :RI, "#{__dir__}/rdoc/ri" + autoload :Stats, "#{__dir__}/rdoc/stats" + autoload :Store, "#{__dir__}/rdoc/store" + autoload :Task, "#{__dir__}/rdoc/task" + autoload :Text, "#{__dir__}/rdoc/text" + + autoload :Markdown, "#{__dir__}/rdoc/markdown" + autoload :Markup, "#{__dir__}/rdoc/markup" + autoload :RD, "#{__dir__}/rdoc/rd" + autoload :TomDoc, "#{__dir__}/rdoc/tom_doc" + + autoload :KNOWN_CLASSES, "#{__dir__}/rdoc/known_classes" + + autoload :TokenStream, "#{__dir__}/rdoc/token_stream" + + autoload :Comment, "#{__dir__}/rdoc/comment" + + require_relative 'rdoc/i18n' + + # code objects + # + # We represent the various high-level code constructs that appear in Ruby + # programs: classes, modules, methods, and so on. + autoload :CodeObject, "#{__dir__}/rdoc/code_object" + + autoload :Context, "#{__dir__}/rdoc/code_object/context" + autoload :TopLevel, "#{__dir__}/rdoc/code_object/top_level" + + autoload :AnonClass, "#{__dir__}/rdoc/code_object/anon_class" + autoload :ClassModule, "#{__dir__}/rdoc/code_object/class_module" + autoload :NormalClass, "#{__dir__}/rdoc/code_object/normal_class" + autoload :NormalModule, "#{__dir__}/rdoc/code_object/normal_module" + autoload :SingleClass, "#{__dir__}/rdoc/code_object/single_class" + + autoload :Alias, "#{__dir__}/rdoc/code_object/alias" + autoload :AnyMethod, "#{__dir__}/rdoc/code_object/any_method" + autoload :MethodAttr, "#{__dir__}/rdoc/code_object/method_attr" + autoload :GhostMethod, "#{__dir__}/rdoc/code_object/ghost_method" + autoload :MetaMethod, "#{__dir__}/rdoc/code_object/meta_method" + autoload :Attr, "#{__dir__}/rdoc/code_object/attr" + + autoload :Constant, "#{__dir__}/rdoc/code_object/constant" + autoload :Mixin, "#{__dir__}/rdoc/code_object/mixin" + autoload :Include, "#{__dir__}/rdoc/code_object/include" + autoload :Extend, "#{__dir__}/rdoc/code_object/extend" + autoload :Require, "#{__dir__}/rdoc/code_object/require" + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object.rb new file mode 100644 index 00000000..388863b0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object.rb @@ -0,0 +1,395 @@ +# frozen_string_literal: true +## +# Base class for the RDoc code tree. +# +# We contain the common stuff for contexts (which are containers) and other +# elements (methods, attributes and so on) +# +# Here's the tree of the CodeObject subclasses: +# +# * RDoc::Context +# * RDoc::TopLevel +# * RDoc::ClassModule +# * RDoc::AnonClass (never used so far) +# * RDoc::NormalClass +# * RDoc::NormalModule +# * RDoc::SingleClass +# * RDoc::MethodAttr +# * RDoc::Attr +# * RDoc::AnyMethod +# * RDoc::GhostMethod +# * RDoc::MetaMethod +# * RDoc::Alias +# * RDoc::Constant +# * RDoc::Require +# * RDoc::Mixin +# * RDoc::Include +# * RDoc::Extend + +class RDoc::CodeObject + + include RDoc::Text + + ## + # Our comment + + attr_reader :comment + + ## + # Do we document our children? + + attr_reader :document_children + + ## + # Do we document ourselves? + + attr_reader :document_self + + ## + # Are we done documenting (ie, did we come across a :enddoc:)? + + attr_reader :done_documenting + + ## + # Which file this code object was defined in + + attr_reader :file + + ## + # Force documentation of this CodeObject + + attr_reader :force_documentation + + ## + # Line in #file where this CodeObject was defined + + attr_accessor :line + + ## + # Hash of arbitrary metadata for this CodeObject + + attr_reader :metadata + + ## + # Sets the parent CodeObject + + attr_writer :parent + + ## + # Did we ever receive a +:nodoc:+ directive? + + attr_reader :received_nodoc + + ## + # Set the section this CodeObject is in + + attr_writer :section + + ## + # The RDoc::Store for this object. + + attr_reader :store + + ## + # When mixed-in to a class, this points to the Context in which it was originally defined. + + attr_accessor :mixin_from + + ## + # Creates a new CodeObject that will document itself and its children + + def initialize + @metadata = {} + @comment = '' + @parent = nil + @parent_name = nil # for loading + @parent_class = nil # for loading + @section = nil + @section_title = nil # for loading + @file = nil + @full_name = nil + @store = nil + @track_visibility = true + @mixin_from = nil + + initialize_visibility + end + + ## + # Initializes state for visibility of this CodeObject and its children. + + def initialize_visibility # :nodoc: + @document_children = true + @document_self = true + @done_documenting = false + @force_documentation = false + @received_nodoc = false + @ignored = false + @suppressed = false + @track_visibility = true + end + + ## + # Replaces our comment with +comment+, unless it is empty. + + def comment=(comment) + @comment = case comment + when NilClass then '' + when RDoc::Comment then comment.normalize + else + if comment and not comment.empty? then + normalize_comment comment + else + # HACK correct fix is to have #initialize create @comment + # with the correct encoding + if String === @comment and @comment.empty? then + @comment = RDoc::Encoding.change_encoding @comment, comment.encoding + end + @comment + end + end + end + + ## + # Should this CodeObject be displayed in output? + # + # A code object should be displayed if: + # + # * The item didn't have a nodoc or wasn't in a container that had nodoc + # * The item wasn't ignored + # * The item has documentation and was not suppressed + + def display? + @document_self and not @ignored and + (documented? or not @suppressed) + end + + ## + # Enables or disables documentation of this CodeObject's children unless it + # has been turned off by :enddoc: + + def document_children=(document_children) + return unless @track_visibility + + @document_children = document_children unless @done_documenting + end + + ## + # Enables or disables documentation of this CodeObject unless it has been + # turned off by :enddoc:. If the argument is +nil+ it means the + # documentation is turned off by +:nodoc:+. + + def document_self=(document_self) + return unless @track_visibility + return if @done_documenting + + @document_self = document_self + @received_nodoc = true if document_self.nil? + end + + ## + # Does this object have a comment with content or is #received_nodoc true? + + def documented? + @received_nodoc or !@comment.empty? + end + + ## + # Turns documentation on/off, and turns on/off #document_self + # and #document_children. + # + # Once documentation has been turned off (by +:enddoc:+), + # the object will refuse to turn #document_self or + # #document_children on, so +:doc:+ and +:start_doc:+ directives + # will have no effect in the current file. + + def done_documenting=(value) + return unless @track_visibility + @done_documenting = value + @document_self = !value + @document_children = @document_self + end + + ## + # File name where this CodeObject was found. + # + # See also RDoc::Context#in_files + + def file_name + return unless @file + + @file.absolute_name + end + + ## + # Force the documentation of this object unless documentation + # has been turned off by :enddoc: + #-- + # HACK untested, was assigning to an ivar + + def force_documentation=(value) + @force_documentation = value unless @done_documenting + end + + ## + # Sets the full_name overriding any computed full name. + # + # Set to +nil+ to clear RDoc's cached value + + def full_name=(full_name) + @full_name = full_name + end + + ## + # Use this to ignore a CodeObject and all its children until found again + # (#record_location is called). An ignored item will not be displayed in + # documentation. + # + # See github issue #55 + # + # The ignored status is temporary in order to allow implementation details + # to be hidden. At the end of processing a file RDoc allows all classes + # and modules to add new documentation to previously created classes. + # + # If a class was ignored (via stopdoc) then reopened later with additional + # documentation it should be displayed. If a class was ignored and never + # reopened it should not be displayed. The ignore flag allows this to + # occur. + + def ignore + return unless @track_visibility + + @ignored = true + + stop_doc + end + + ## + # Has this class been ignored? + # + # See also #ignore + + def ignored? + @ignored + end + + ## + # The options instance from the store this CodeObject is attached to, or a + # default options instance if the CodeObject is not attached. + # + # This is used by Text#snippet + + def options + @store&.options || RDoc::Options.new + end + + ## + # Our parent CodeObject. The parent may be missing for classes loaded from + # legacy RI data stores. + + def parent + return @parent if @parent + return nil unless @parent_name + + if @parent_class == RDoc::TopLevel then + @parent = @store.add_file @parent_name + else + @parent = @store.find_class_or_module @parent_name + + return @parent if @parent + + begin + @parent = @store.load_class @parent_name + rescue RDoc::Store::MissingFileError + nil + end + end + end + + ## + # Name of our parent + + def parent_name + @parent ? @parent.full_name : '(unknown)' + end + + ## + # Records the RDoc::TopLevel (file) where this code object was defined + + def record_location(top_level) + @ignored = false + @suppressed = false + @file = top_level + end + + ## + # The section this CodeObject is in. Sections allow grouping of constants, + # attributes and methods inside a class or module. + + def section + return @section if @section + + @section = parent.add_section @section_title if parent + end + + ## + # Enable capture of documentation unless documentation has been + # turned off by :enddoc: + + def start_doc + return if @done_documenting + + @document_self = true + @document_children = true + @ignored = false + @suppressed = false + end + + ## + # Disable capture of documentation + + def stop_doc + return unless @track_visibility + + @document_self = false + @document_children = false + end + + ## + # Sets the +store+ that contains this CodeObject + + def store=(store) + @store = store + + return unless @track_visibility + + if :nodoc == options.visibility then + initialize_visibility + @track_visibility = false + end + end + + ## + # Use this to suppress a CodeObject and all its children until the next file + # it is seen in or documentation is discovered. A suppressed item with + # documentation will be displayed while an ignored item with documentation + # may not be displayed. + + def suppress + return unless @track_visibility + + @suppressed = true + + stop_doc + end + + ## + # Has this class been suppressed? + # + # See also #suppress + + def suppressed? + @suppressed + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/alias.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/alias.rb new file mode 100644 index 00000000..bd5b3ec6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/alias.rb @@ -0,0 +1,104 @@ +# frozen_string_literal: true +## +# Represent an alias, which is an old_name/new_name pair associated with a +# particular context +#-- +# TODO implement Alias as a proxy to a method/attribute, inheriting from +# MethodAttr + +class RDoc::Alias < RDoc::CodeObject + + ## + # Aliased method's name + + attr_reader :new_name + + alias name new_name + + ## + # Aliasee method's name + + attr_reader :old_name + + ## + # Is this an alias declared in a singleton context? + + attr_reader :singleton + + ## + # Source file token stream + + attr_reader :text + + ## + # Creates a new Alias with a token stream of +text+ that aliases +old_name+ + # to +new_name+, has +comment+ and is a +singleton+ context. + + def initialize(text, old_name, new_name, comment, singleton: false) + super() + + @text = text + @singleton = singleton + @old_name = old_name + @new_name = new_name + self.comment = comment + end + + ## + # Order by #singleton then #new_name + + def <=>(other) + [@singleton ? 0 : 1, new_name] <=> [other.singleton ? 0 : 1, other.new_name] + end + + ## + # HTML fragment reference for this alias + + def aref + type = singleton ? 'c' : 'i' + "#alias-#{type}-#{html_name}" + end + + ## + # HTML id-friendly version of +#new_name+. + + def html_name + CGI.escape(@new_name.gsub('-', '-2D')).gsub('%', '-').sub(/^-/, '') + end + + def inspect # :nodoc: + parent_name = parent ? parent.name : '(unknown)' + "#<%s:0x%x %s.alias_method %s, %s>" % [ + self.class, object_id, + parent_name, @old_name, @new_name, + ] + end + + ## + # '::' for the alias of a singleton method/attribute, '#' for instance-level. + + def name_prefix + singleton ? '::' : '#' + end + + ## + # Old name with prefix '::' or '#'. + + def pretty_old_name + "#{singleton ? '::' : '#'}#{@old_name}" + end + + ## + # New name with prefix '::' or '#'. + + def pretty_new_name + "#{singleton ? '::' : '#'}#{@new_name}" + end + + alias pretty_name pretty_new_name + + def to_s # :nodoc: + "alias: #{self.new_name} -> #{self.pretty_old_name} in: #{parent}" + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/anon_class.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/anon_class.rb new file mode 100644 index 00000000..3c2f0e18 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/anon_class.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true +## +# An anonymous class like: +# +# c = Class.new do end +# +# AnonClass is currently not used. + +class RDoc::AnonClass < RDoc::ClassModule +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/any_method.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/any_method.rb new file mode 100644 index 00000000..b319f0d0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/any_method.rb @@ -0,0 +1,374 @@ +# frozen_string_literal: true +## +# AnyMethod is the base class for objects representing methods + +class RDoc::AnyMethod < RDoc::MethodAttr + + ## + # 2:: + # RDoc 4 + # Added calls_super + # Added parent name and class + # Added section title + # 3:: + # RDoc 4.1 + # Added is_alias_for + + MARSHAL_VERSION = 3 # :nodoc: + + ## + # Don't rename \#initialize to \::new + + attr_accessor :dont_rename_initialize + + ## + # The C function that implements this method (if it was defined in a C file) + + attr_accessor :c_function + + # The section title of the method (if defined in a C file via +:category:+) + attr_accessor :section_title + + ## + # If true this method uses +super+ to call a superclass version + + attr_accessor :calls_super + + include RDoc::TokenStream + + ## + # Creates a new AnyMethod with a token stream +text+ and +name+ + + def initialize(text, name, singleton: false) + super(text, name, singleton: singleton) + + @c_function = nil + @dont_rename_initialize = false + @token_stream = nil + @calls_super = false + @superclass_method = nil + end + + ## + # Adds +an_alias+ as an alias for this method in +context+. + + def add_alias(an_alias, context = nil) + method = self.class.new an_alias.text, an_alias.new_name, singleton: singleton + + method.record_location an_alias.file + method.params = self.params + method.visibility = self.visibility + method.comment = an_alias.comment + method.is_alias_for = self + @aliases << method + context.add_method method if context + method + end + + ## + # Prefix for +aref+ is 'method'. + + def aref_prefix + 'method' + end + + ## + # The call_seq or the param_seq with method name, if there is no call_seq. + # + # Use this for displaying a method's argument lists. + + def arglists + if @call_seq then + @call_seq + elsif @params then + "#{name}#{param_seq}" + end + end + + ## + # Different ways to call this method + + def call_seq + unless call_seq = _call_seq + call_seq = is_alias_for._call_seq if is_alias_for + end + + return unless call_seq + + deduplicate_call_seq(call_seq) + end + + ## + # Sets the different ways you can call this method. If an empty +call_seq+ + # is given nil is assumed. + # + # See also #param_seq + + def call_seq=(call_seq) + return if call_seq.nil? || call_seq.empty? + + @call_seq = call_seq + end + + ## + # Whether the method has a call-seq. + + def has_call_seq? + !!(@call_seq || is_alias_for&._call_seq) + end + + ## + # Loads is_alias_for from the internal name. Returns nil if the alias + # cannot be found. + + def is_alias_for # :nodoc: + case @is_alias_for + when RDoc::MethodAttr then + @is_alias_for + when Array then + return nil unless @store + + klass_name, singleton, method_name = @is_alias_for + + return nil unless klass = @store.find_class_or_module(klass_name) + + @is_alias_for = klass.find_method method_name, singleton + end + end + + ## + # Dumps this AnyMethod for use by ri. See also #marshal_load + + def marshal_dump + aliases = @aliases.map do |a| + [a.name, parse(a.comment)] + end + + is_alias_for = [ + @is_alias_for.parent.full_name, + @is_alias_for.singleton, + @is_alias_for.name + ] if @is_alias_for + + [ MARSHAL_VERSION, + @name, + full_name, + @singleton, + @visibility, + parse(@comment), + @call_seq, + @block_params, + aliases, + @params, + @file.relative_name, + @calls_super, + @parent.name, + @parent.class, + @section.title, + is_alias_for, + ] + end + + ## + # Loads this AnyMethod from +array+. For a loaded AnyMethod the following + # methods will return cached values: + # + # * #full_name + # * #parent_name + + def marshal_load(array) + initialize_visibility + + @dont_rename_initialize = nil + @token_stream = nil + @aliases = [] + @parent = nil + @parent_name = nil + @parent_class = nil + @section = nil + @file = nil + + version = array[0] + @name = array[1] + @full_name = array[2] + @singleton = array[3] + @visibility = array[4] + @comment = RDoc::Comment.from_document array[5] + @call_seq = array[6] + @block_params = array[7] + # 8 handled below + @params = array[9] + # 10 handled below + @calls_super = array[11] + @parent_name = array[12] + @parent_title = array[13] + @section_title = array[14] + @is_alias_for = array[15] + + array[8].each do |new_name, document| + add_alias RDoc::Alias.new(nil, @name, new_name, RDoc::Comment.from_document(document), singleton: @singleton) + end + + @parent_name ||= if @full_name =~ /#/ then + $` + else + name = @full_name.split('::') + name.pop + name.join '::' + end + + @file = RDoc::TopLevel.new array[10] if version > 0 + end + + ## + # Method name + # + # If the method has no assigned name, it extracts it from #call_seq. + + def name + return @name if @name + + @name = + @call_seq[/^.*?\.(\w+)/, 1] || + @call_seq[/^.*?(\w+)/, 1] || + @call_seq if @call_seq + end + + ## + # A list of this method's method and yield parameters. +call-seq+ params + # are preferred over parsed method and block params. + + def param_list + if @call_seq then + params = @call_seq.split("\n").last + params = params.sub(/.*?\((.*)\)/, '\1') + params = params.sub(/(\{|do)\s*\|([^|]*)\|.*/, ',\2') + elsif @params then + params = @params.sub(/\((.*)\)/, '\1') + + params << ",#{@block_params}" if @block_params + elsif @block_params then + params = @block_params + else + return [] + end + + if @block_params then + # If this method has explicit block parameters, remove any explicit + # &block + params = params.sub(/,?\s*&\w+/, '') + else + params = params.sub(/\&(\w+)/, '\1') + end + + params = params.gsub(/\s+/, '').split(',').reject(&:empty?) + + params.map { |param| param.sub(/=.*/, '') } + end + + ## + # Pretty parameter list for this method. If the method's parameters were + # given by +call-seq+ it is preferred over the parsed values. + + def param_seq + if @call_seq then + params = @call_seq.split("\n").last + params = params.sub(/[^( ]+/, '') + params = params.sub(/(\|[^|]+\|)\s*\.\.\.\s*(end|\})/, '\1 \2') + elsif @params then + params = @params.gsub(/\s*\#.*/, '') + params = params.tr_s("\n ", " ") + params = "(#{params})" unless params[0] == ?( + else + params = '' + end + + if @block_params then + # If this method has explicit block parameters, remove any explicit + # &block + params = params.sub(/,?\s*&\w+/, '') + + block = @block_params.tr_s("\n ", " ") + if block[0] == ?( + block = block.sub(/^\(/, '').sub(/\)/, '') + end + params << " { |#{block}| ... }" + end + + params + end + + ## + # Whether to skip the method description, true for methods that have + # aliases with a call-seq that doesn't include the method name. + + def skip_description? + has_call_seq? && call_seq.nil? && !!(is_alias_for || !aliases.empty?) + end + + ## + # Sets the store for this method and its referenced code objects. + + def store=(store) + super + + @file = @store.add_file @file.full_name if @file + end + + ## + # For methods that +super+, find the superclass method that would be called. + + def superclass_method + return unless @calls_super + return @superclass_method if @superclass_method + + parent.each_ancestor do |ancestor| + if method = ancestor.method_list.find { |m| m.name == @name } then + @superclass_method = method + break + end + end + + @superclass_method + end + + protected + + ## + # call_seq without deduplication and alias lookup. + + def _call_seq + @call_seq if defined?(@call_seq) && @call_seq + end + + private + + ## + # call_seq with alias examples information removed, if this + # method is an alias method. + + def deduplicate_call_seq(call_seq) + return call_seq unless is_alias_for || !aliases.empty? + + method_name = self.name + method_name = method_name[0, 1] if method_name =~ /\A\[/ + + entries = call_seq.split "\n" + + ignore = aliases.map(&:name) + if is_alias_for + ignore << is_alias_for.name + ignore.concat is_alias_for.aliases.map(&:name) + end + ignore.map! { |n| n =~ /\A\[/ ? /\[.*\]/ : n} + ignore.delete(method_name) + ignore = Regexp.union(ignore) + + matching = entries.reject do |entry| + entry =~ /^\w*\.?#{ignore}[$\(\s]/ or + entry =~ /\s#{ignore}\s/ + end + + matching.empty? ? nil : matching.join("\n") + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/attr.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/attr.rb new file mode 100644 index 00000000..969b1834 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/attr.rb @@ -0,0 +1,172 @@ +# frozen_string_literal: true +## +# An attribute created by \#attr, \#attr_reader, \#attr_writer or +# \#attr_accessor + +class RDoc::Attr < RDoc::MethodAttr + + ## + # 3:: + # RDoc 4 + # Added parent name and class + # Added section title + + MARSHAL_VERSION = 3 # :nodoc: + + ## + # Is the attribute readable ('R'), writable ('W') or both ('RW')? + + attr_accessor :rw + + ## + # Creates a new Attr with body +text+, +name+, read/write status +rw+ and + # +comment+. +singleton+ marks this as a class attribute. + + def initialize(text, name, rw, comment, singleton: false) + super(text, name, singleton: singleton) + + @rw = rw + self.comment = comment + end + + ## + # Attributes are equal when their names, singleton and rw are identical + + def ==(other) + self.class == other.class and + self.name == other.name and + self.rw == other.rw and + self.singleton == other.singleton + end + + ## + # Add +an_alias+ as an attribute in +context+. + + def add_alias(an_alias, context) + new_attr = self.class.new(text, an_alias.new_name, rw, comment, singleton: singleton) + new_attr.record_location an_alias.file + new_attr.visibility = self.visibility + new_attr.is_alias_for = self + @aliases << new_attr + context.add_attribute new_attr + new_attr + end + + ## + # The #aref prefix for attributes + + def aref_prefix + 'attribute' + end + + ## + # Attributes never call super. See RDoc::AnyMethod#calls_super + # + # An RDoc::Attr can show up in the method list in some situations (see + # Gem::ConfigFile) + + def calls_super # :nodoc: + false + end + + ## + # Returns attr_reader, attr_writer or attr_accessor as appropriate. + + def definition + case @rw + when 'RW' then 'attr_accessor' + when 'R' then 'attr_reader' + when 'W' then 'attr_writer' + end + end + + def inspect # :nodoc: + alias_for = @is_alias_for ? " (alias for #{@is_alias_for.name})" : nil + visibility = self.visibility + visibility = "forced #{visibility}" if force_documentation + "#<%s:0x%x %s %s (%s)%s>" % [ + self.class, object_id, + full_name, + rw, + visibility, + alias_for, + ] + end + + ## + # Dumps this Attr for use by ri. See also #marshal_load + + def marshal_dump + [ MARSHAL_VERSION, + @name, + full_name, + @rw, + @visibility, + parse(@comment), + singleton, + @file.relative_name, + @parent.full_name, + @parent.class, + @section.title + ] + end + + ## + # Loads this Attr from +array+. For a loaded Attr the following + # methods will return cached values: + # + # * #full_name + # * #parent_name + + def marshal_load(array) + initialize_visibility + + @aliases = [] + @parent = nil + @parent_name = nil + @parent_class = nil + @section = nil + @file = nil + + version = array[0] + @name = array[1] + @full_name = array[2] + @rw = array[3] + @visibility = array[4] + @comment = RDoc::Comment.from_document array[5] + @singleton = array[6] || false # MARSHAL_VERSION == 0 + # 7 handled below + @parent_name = array[8] + @parent_class = array[9] + @section_title = array[10] + + @file = RDoc::TopLevel.new array[7] if version > 1 + + @parent_name ||= @full_name.split('#', 2).first + end + + def pretty_print(q) # :nodoc: + q.group 2, "[#{self.class.name} #{full_name} #{rw} #{visibility}", "]" do + unless comment.empty? then + q.breakable + q.text "comment:" + q.breakable + q.pp @comment + end + end + end + + def to_s # :nodoc: + "#{definition} #{name} in: #{parent}" + end + + ## + # Attributes do not have token streams. + # + # An RDoc::Attr can show up in the method list in some situations (see + # Gem::ConfigFile) + + def token_stream # :nodoc: + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/class_module.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/class_module.rb new file mode 100644 index 00000000..f6b0abb2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/class_module.rb @@ -0,0 +1,888 @@ +# frozen_string_literal: true +## +# ClassModule is the base class for objects representing either a class or a +# module. + +class RDoc::ClassModule < RDoc::Context + + ## + # 1:: + # RDoc 3.7 + # * Added visibility, singleton and file to attributes + # * Added file to constants + # * Added file to includes + # * Added file to methods + # 2:: + # RDoc 3.13 + # * Added extends + # 3:: + # RDoc 4.0 + # * Added sections + # * Added in_files + # * Added parent name + # * Complete Constant dump + + MARSHAL_VERSION = 3 # :nodoc: + + ## + # Constants that are aliases for this class or module + + attr_accessor :constant_aliases + + ## + # Comment and the location it came from. Use #add_comment to add comments + + attr_accessor :comment_location + + ## + # Class or module this constant is an alias for + + attr_accessor :is_alias_for + + ## + # Return a RDoc::ClassModule of class +class_type+ that is a copy + # of module +module+. Used to promote modules to classes. + #-- + # TODO move to RDoc::NormalClass (I think) + + def self.from_module(class_type, mod) + klass = class_type.new mod.name + + mod.comment_location.each do |comment, location| + klass.add_comment comment, location + end + + klass.parent = mod.parent + klass.section = mod.section + + klass.attributes.concat mod.attributes + klass.method_list.concat mod.method_list + klass.aliases.concat mod.aliases + klass.external_aliases.concat mod.external_aliases + klass.constants.concat mod.constants + klass.includes.concat mod.includes + klass.extends.concat mod.extends + + klass.methods_hash.update mod.methods_hash + klass.constants_hash.update mod.constants_hash + + klass.current_section = mod.current_section + klass.in_files.concat mod.in_files + klass.sections.concat mod.sections + klass.unmatched_alias_lists = mod.unmatched_alias_lists + klass.current_section = mod.current_section + klass.visibility = mod.visibility + + klass.classes_hash.update mod.classes_hash + klass.modules_hash.update mod.modules_hash + klass.metadata.update mod.metadata + + klass.document_self = mod.received_nodoc ? nil : mod.document_self + klass.document_children = mod.document_children + klass.force_documentation = mod.force_documentation + klass.done_documenting = mod.done_documenting + + # update the parent of all children + + (klass.attributes + + klass.method_list + + klass.aliases + + klass.external_aliases + + klass.constants + + klass.includes + + klass.extends + + klass.classes + + klass.modules).each do |obj| + obj.parent = klass + obj.full_name = nil + end + + klass + end + + ## + # Creates a new ClassModule with +name+ with optional +superclass+ + # + # This is a constructor for subclasses, and must never be called directly. + + def initialize(name, superclass = nil) + @constant_aliases = [] + @is_alias_for = nil + @name = name + @superclass = superclass + @comment_location = [] # [[comment, location]] + + super() + end + + ## + # Adds +comment+ to this ClassModule's list of comments at +location+. This + # method is preferred over #comment= since it allows ri data to be updated + # across multiple runs. + + def add_comment(comment, location) + return unless document_self + + original = comment + + comment = case comment + when RDoc::Comment then + comment.normalize + else + normalize_comment comment + end + + if location.parser == RDoc::Parser::C + @comment_location.delete_if { |(_, l)| l == location } + end + + @comment_location << [comment, location] + + self.comment = original + end + + def add_things(my_things, other_things) # :nodoc: + other_things.each do |group, things| + my_things[group].each { |thing| yield false, thing } if + my_things.include? group + + things.each do |thing| + yield true, thing + end + end + end + + ## + # Ancestors list for this ClassModule: the list of included modules + # (classes will add their superclass if any). + # + # Returns the included classes or modules, not the includes + # themselves. The returned values are either String or + # RDoc::NormalModule instances (see RDoc::Include#module). + # + # The values are returned in reverse order of their inclusion, + # which is the order suitable for searching methods/attributes + # in the ancestors. The superclass, if any, comes last. + + def ancestors + includes.map { |i| i.module }.reverse + end + + def aref_prefix # :nodoc: + raise NotImplementedError, "missing aref_prefix for #{self.class}" + end + + ## + # HTML fragment reference for this module or class. See + # RDoc::NormalClass#aref and RDoc::NormalModule#aref + + def aref + "#{aref_prefix}-#{full_name}" + end + + ## + # Ancestors of this class or module only + + alias direct_ancestors ancestors + + ## + # Clears the comment. Used by the Ruby parser. + + def clear_comment + @comment = '' + end + + ## + # This method is deprecated, use #add_comment instead. + # + # Appends +comment+ to the current comment, but separated by a rule. Works + # more like +=. + + def comment=(comment) # :nodoc: + comment = case comment + when RDoc::Comment then + comment.normalize + else + normalize_comment comment + end + + comment = "#{@comment.to_s}\n---\n#{comment.to_s}" unless @comment.empty? + + super comment + end + + ## + # Prepares this ClassModule for use by a generator. + # + # See RDoc::Store#complete + + def complete(min_visibility) + update_aliases + remove_nodoc_children + embed_mixins + update_includes + update_extends + remove_invisible min_visibility + end + + ## + # Does this ClassModule or any of its methods have document_self set? + + def document_self_or_methods + document_self || method_list.any?{ |m| m.document_self } + end + + ## + # Does this class or module have a comment with content or is + # #received_nodoc true? + + def documented? + return true if @received_nodoc + return false if @comment_location.empty? + @comment_location.any? { |comment, _| not comment.empty? } + end + + ## + # Iterates the ancestors of this class or module for which an + # RDoc::ClassModule exists. + + def each_ancestor # :yields: module + return enum_for __method__ unless block_given? + + ancestors.each do |mod| + next if String === mod + next if self == mod + yield mod + end + end + + ## + # Looks for a symbol in the #ancestors. See Context#find_local_symbol. + + def find_ancestor_local_symbol(symbol) + each_ancestor do |m| + res = m.find_local_symbol(symbol) + return res if res + end + + nil + end + + ## + # Finds a class or module with +name+ in this namespace or its descendants + + def find_class_named(name) + return self if full_name == name + return self if @name == name + + @classes.values.find do |klass| + next if klass == self + klass.find_class_named name + end + end + + ## + # Return the fully qualified name of this class or module + + def full_name + @full_name ||= if RDoc::ClassModule === parent then + "#{parent.full_name}::#{@name}" + else + @name + end + end + + ## + # Return array of full_name splitted by +::+. + + def nesting_namespaces + @namespaces ||= full_name.split("::").reject(&:empty?) + end + + ## + # Return array of fully qualified nesting namespaces. + # + # For example, if full_name is +A::B::C+, this method returns ["A", "A::B", "A::B::C"] + + def fully_qualified_nesting_namespaces + return nesting_namespaces if nesting_namespaces.length < 2 + @fqns ||= nesting_namespaces.inject([]) do |list, n| + list << (list.empty? ? n : "#{list.last}::#{n}") + end + end + + ## + # TODO: filter included items by #display? + + def marshal_dump # :nodoc: + attrs = attributes.sort.map do |attr| + next unless attr.display? + [ attr.name, attr.rw, + attr.visibility, attr.singleton, attr.file_name, + ] + end.compact + + method_types = methods_by_type.map do |type, visibilities| + visibilities = visibilities.map do |visibility, methods| + method_names = methods.map do |method| + next unless method.display? + [method.name, method.file_name] + end.compact + + [visibility, method_names.uniq] + end + + [type, visibilities] + end + + [ MARSHAL_VERSION, + @name, + full_name, + @superclass, + parse(@comment_location), + attrs, + constants.select { |constant| constant.display? }, + includes.map do |incl| + next unless incl.display? + [incl.name, parse(incl.comment), incl.file_name] + end.compact, + method_types, + extends.map do |ext| + next unless ext.display? + [ext.name, parse(ext.comment), ext.file_name] + end.compact, + @sections.values, + @in_files.map do |tl| + tl.relative_name + end, + parent.full_name, + parent.class, + ] + end + + def marshal_load(array) # :nodoc: + initialize_visibility + initialize_methods_etc + @current_section = nil + @document_self = true + @done_documenting = false + @parent = nil + @temporary_section = nil + @visibility = nil + @classes = {} + @modules = {} + + @name = array[1] + @full_name = array[2] + @superclass = array[3] + document = array[4] + + @comment = RDoc::Comment.from_document document + + @comment_location = if RDoc::Markup::Document === document.parts.first then + document + else + RDoc::Markup::Document.new document + end + + array[5].each do |name, rw, visibility, singleton, file| + singleton ||= false + visibility ||= :public + + attr = RDoc::Attr.new nil, name, rw, nil, singleton: singleton + + add_attribute attr + attr.visibility = visibility + attr.record_location RDoc::TopLevel.new file + end + + array[6].each do |constant, document, file| + case constant + when RDoc::Constant then + add_constant constant + else + constant = add_constant RDoc::Constant.new(constant, nil, RDoc::Comment.from_document(document)) + constant.record_location RDoc::TopLevel.new file + end + end + + array[7].each do |name, document, file| + incl = add_include RDoc::Include.new(name, RDoc::Comment.from_document(document)) + incl.record_location RDoc::TopLevel.new file + end + + array[8].each do |type, visibilities| + visibilities.each do |visibility, methods| + @visibility = visibility + + methods.each do |name, file| + method = RDoc::AnyMethod.new nil, name, singleton: type == 'class' + method.record_location RDoc::TopLevel.new file + add_method method + end + end + end + + array[9].each do |name, document, file| + ext = add_extend RDoc::Extend.new(name, RDoc::Comment.from_document(document)) + ext.record_location RDoc::TopLevel.new file + end if array[9] # Support Marshal version 1 + + sections = (array[10] || []).map do |section| + [section.title, section] + end + + @sections = Hash[*sections.flatten] + @current_section = add_section nil + + @in_files = [] + + (array[11] || []).each do |filename| + record_location RDoc::TopLevel.new filename + end + + @parent_name = array[12] + @parent_class = array[13] + end + + ## + # Merges +class_module+ into this ClassModule. + # + # The data in +class_module+ is preferred over the receiver. + + def merge(class_module) + @parent = class_module.parent + @parent_name = class_module.parent_name + + other_document = parse class_module.comment_location + + if other_document then + document = parse @comment_location + + document = document.merge other_document + + @comment = RDoc::Comment.from_document(document) + @comment_location = document + end + + cm = class_module + other_files = cm.in_files + + merge_collections attributes, cm.attributes, other_files do |add, attr| + if add then + add_attribute attr + else + @attributes.delete attr + @methods_hash.delete attr.pretty_name + end + end + + merge_collections constants, cm.constants, other_files do |add, const| + if add then + add_constant const + else + @constants.delete const + @constants_hash.delete const.name + end + end + + merge_collections includes, cm.includes, other_files do |add, incl| + if add then + add_include incl + else + @includes.delete incl + end + end + + @includes.uniq! # clean up + + merge_collections extends, cm.extends, other_files do |add, ext| + if add then + add_extend ext + else + @extends.delete ext + end + end + + @extends.uniq! # clean up + + merge_collections method_list, cm.method_list, other_files do |add, meth| + if add then + add_method meth + else + @method_list.delete meth + @methods_hash.delete meth.pretty_name + end + end + + merge_sections cm + + self + end + + ## + # Merges collection +mine+ with +other+ preferring other. +other_files+ is + # used to help determine which items should be deleted. + # + # Yields whether the item should be added or removed (true or false) and the + # item to be added or removed. + # + # merge_collections things, other.things, other.in_files do |add, thing| + # if add then + # # add the thing + # else + # # remove the thing + # end + # end + + def merge_collections(mine, other, other_files, &block) # :nodoc: + my_things = mine. group_by { |thing| thing.file } + other_things = other.group_by { |thing| thing.file } + + remove_things my_things, other_files, &block + add_things my_things, other_things, &block + end + + ## + # Merges the comments in this ClassModule with the comments in the other + # ClassModule +cm+. + + def merge_sections(cm) # :nodoc: + my_sections = sections.group_by { |section| section.title } + other_sections = cm.sections.group_by { |section| section.title } + + other_files = cm.in_files + + remove_things my_sections, other_files do |_, section| + @sections.delete section.title + end + + other_sections.each do |group, sections| + if my_sections.include? group + my_sections[group].each do |my_section| + other_section = cm.sections_hash[group] + + my_comments = my_section.comments + other_comments = other_section.comments + + other_files = other_section.in_files + + merge_collections my_comments, other_comments, other_files do |add, comment| + if add then + my_section.add_comment comment + else + my_section.remove_comment comment + end + end + end + else + sections.each do |section| + add_section group, section.comments + end + end + end + end + + ## + # Does this object represent a module? + + def module? + false + end + + ## + # Allows overriding the initial name. + # + # Used for modules and classes that are constant aliases. + + def name=(new_name) + @name = new_name + end + + ## + # Parses +comment_location+ into an RDoc::Markup::Document composed of + # multiple RDoc::Markup::Documents with their file set. + + def parse(comment_location) + case comment_location + when String then + super + when Array then + docs = comment_location.map do |comment, location| + doc = super comment + doc.file = location + doc + end + + RDoc::Markup::Document.new(*docs) + when RDoc::Comment then + doc = super comment_location.text, comment_location.format + doc.file = comment_location.location + doc + when RDoc::Markup::Document then + return comment_location + else + raise ArgumentError, "unknown comment class #{comment_location.class}" + end + end + + ## + # Path to this class or module for use with HTML generator output. + + def path + prefix = options.class_module_path_prefix + return http_url unless prefix + File.join(prefix, http_url) + end + + ## + # Name to use to generate the url: + # modules and classes that are aliases for another + # module or class return the name of the latter. + + def name_for_path + is_alias_for ? is_alias_for.full_name : full_name + end + + ## + # Returns the classes and modules that are not constants + # aliasing another class or module. For use by formatters + # only (caches its result). + + def non_aliases + @non_aliases ||= classes_and_modules.reject { |cm| cm.is_alias_for } + end + + ## + # Updates the child modules or classes of class/module +parent+ by + # deleting the ones that have been removed from the documentation. + # + # +parent_hash+ is either parent.modules_hash or + # parent.classes_hash and +all_hash+ is ::all_modules_hash or + # ::all_classes_hash. + + def remove_nodoc_children + prefix = self.full_name + '::' + + modules_hash.each_key do |name| + full_name = prefix + name + modules_hash.delete name unless @store.modules_hash[full_name] + end + + classes_hash.each_key do |name| + full_name = prefix + name + classes_hash.delete name unless @store.classes_hash[full_name] + end + end + + def remove_things(my_things, other_files) # :nodoc: + my_things.delete_if do |file, things| + next false unless other_files.include? file + + things.each do |thing| + yield false, thing + end + + true + end + end + + ## + # Search record used by RDoc::Generator::JsonIndex + + def search_record + [ + name, + full_name, + full_name, + '', + path, + '', + snippet(@comment_location), + ] + end + + ## + # Sets the store for this class or module and its contained code objects. + + def store=(store) + super + + @attributes .each do |attr| attr.store = store end + @constants .each do |const| const.store = store end + @includes .each do |incl| incl.store = store end + @extends .each do |ext| ext.store = store end + @method_list.each do |meth| meth.store = store end + end + + ## + # Get the superclass of this class. Attempts to retrieve the superclass + # object, returns the name if it is not known. + + def superclass + @store.find_class_named(@superclass) || @superclass + end + + ## + # Set the superclass of this class to +superclass+ + # + # where +superclass+ is one of: + # + # - +nil+ + # - a String containing the full name of the superclass + # - the RDoc::ClassModule representing the superclass + + def superclass=(superclass) + raise NoMethodError, "#{full_name} is a module" if module? + case superclass + when RDoc::ClassModule + @superclass = superclass.full_name + when nil, String + @superclass = superclass + else + raise TypeError, "superclass must be a String or RDoc::ClassModule, not #{superclass.class}" + end + end + + ## + # Get all super classes of this class in an array. The last element might be + # a string if the name is unknown. + + def super_classes + result = [] + parent = self + while parent = parent.superclass + result << parent + return result if parent.is_a?(String) + end + result + end + + def to_s # :nodoc: + if is_alias_for then + "#{self.class.name} #{self.full_name} -> #{is_alias_for}" + else + super + end + end + + ## + # 'module' or 'class' + + def type + module? ? 'module' : 'class' + end + + ## + # Updates the child modules & classes by replacing the ones that are + # aliases through a constant. + # + # The aliased module/class is replaced in the children and in + # RDoc::Store#modules_hash or RDoc::Store#classes_hash + # by a copy that has RDoc::ClassModule#is_alias_for set to + # the aliased module/class, and this copy is added to #aliases + # of the aliased module/class. + # + # Formatters can use the #non_aliases method to retrieve children that + # are not aliases, for instance to list the namespace content, since + # the aliased modules are included in the constants of the class/module, + # that are listed separately. + + def update_aliases + constants.each do |const| + next unless cm = const.is_alias_for + cm_alias = cm.dup + cm_alias.name = const.name + + # Don't move top-level aliases under Object, they look ugly there + unless RDoc::TopLevel === cm_alias.parent then + cm_alias.parent = self + cm_alias.full_name = nil # force update for new parent + end + + cm_alias.aliases.clear + cm_alias.is_alias_for = cm + + if cm.module? then + @store.modules_hash[cm_alias.full_name] = cm_alias + modules_hash[const.name] = cm_alias + else + @store.classes_hash[cm_alias.full_name] = cm_alias + classes_hash[const.name] = cm_alias + end + + cm.aliases << cm_alias + end + end + + ## + # Deletes from #includes those whose module has been removed from the + # documentation. + #-- + # FIXME: includes are not reliably removed, see _possible_bug test case + + def update_includes + includes.reject! do |include| + mod = include.module + !(String === mod) && @store.modules_hash[mod.full_name].nil? + end + + includes.uniq! + end + + ## + # Deletes from #extends those whose module has been removed from the + # documentation. + #-- + # FIXME: like update_includes, extends are not reliably removed + + def update_extends + extends.reject! do |ext| + mod = ext.module + + !(String === mod) && @store.modules_hash[mod.full_name].nil? + end + + extends.uniq! + end + + def embed_mixins + return unless options.embed_mixins + + includes.each do |include| + next if String === include.module + include.module.method_list.each do |code_object| + add_method(prepare_to_embed(code_object)) + end + include.module.constants.each do |code_object| + add_constant(prepare_to_embed(code_object)) + end + include.module.attributes.each do |code_object| + add_attribute(prepare_to_embed(code_object)) + end + end + + extends.each do |ext| + next if String === ext.module + ext.module.method_list.each do |code_object| + add_method(prepare_to_embed(code_object, true)) + end + ext.module.attributes.each do |code_object| + add_attribute(prepare_to_embed(code_object, true)) + end + end + end + + private + + def prepare_to_embed(code_object, singleton=false) + code_object = code_object.dup + code_object.mixin_from = code_object.parent + code_object.singleton = true if singleton + set_current_section(code_object.section.title, code_object.section.comment) + # add_method and add_attribute will reassign self's visibility back to the method/attribute + # so we need to sync self's visibility with the object's to properly retain that information + self.visibility = code_object.visibility + code_object + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/constant.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/constant.rb new file mode 100644 index 00000000..d5f54edb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/constant.rb @@ -0,0 +1,186 @@ +# frozen_string_literal: true +## +# A constant + +class RDoc::Constant < RDoc::CodeObject + + MARSHAL_VERSION = 0 # :nodoc: + + ## + # Sets the module or class this is constant is an alias for. + + attr_writer :is_alias_for + + ## + # The constant's name + + attr_accessor :name + + ## + # The constant's value + + attr_accessor :value + + ## + # The constant's visibility + + attr_accessor :visibility + + ## + # Creates a new constant with +name+, +value+ and +comment+ + + def initialize(name, value, comment) + super() + + @name = name + @value = value + + @is_alias_for = nil + @visibility = :public + + self.comment = comment + end + + ## + # Constants are ordered by name + + def <=>(other) + return unless self.class === other + + [parent_name, name] <=> [other.parent_name, other.name] + end + + ## + # Constants are equal when their #parent and #name is the same + + def ==(other) + self.class == other.class and + @parent == other.parent and + @name == other.name + end + + ## + # A constant is documented if it has a comment, or is an alias + # for a documented class or module. + + def documented? + return true if super + return false unless @is_alias_for + case @is_alias_for + when String then + found = @store.find_class_or_module @is_alias_for + return false unless found + @is_alias_for = found + end + @is_alias_for.documented? + end + + ## + # Full constant name including namespace + + def full_name + @full_name ||= "#{parent_name}::#{@name}" + end + + ## + # The module or class this constant is an alias for + + def is_alias_for + case @is_alias_for + when String then + found = @store.find_class_or_module @is_alias_for + @is_alias_for = found if found + @is_alias_for + else + @is_alias_for + end + end + + def inspect # :nodoc: + "#<%s:0x%x %s::%s>" % [ + self.class, object_id, + parent_name, @name, + ] + end + + ## + # Dumps this Constant for use by ri. See also #marshal_load + + def marshal_dump + alias_name = case found = is_alias_for + when RDoc::CodeObject then found.full_name + else found + end + + [ MARSHAL_VERSION, + @name, + full_name, + @visibility, + alias_name, + parse(@comment), + @file.relative_name, + parent.name, + parent.class, + section.title, + ] + end + + ## + # Loads this Constant from +array+. For a loaded Constant the following + # methods will return cached values: + # + # * #full_name + # * #parent_name + + def marshal_load(array) + initialize array[1], nil, RDoc::Comment.from_document(array[5]) + + @full_name = array[2] + @visibility = array[3] || :public + @is_alias_for = array[4] + # 5 handled above + # 6 handled below + @parent_name = array[7] + @parent_class = array[8] + @section_title = array[9] + + @file = RDoc::TopLevel.new array[6] + end + + ## + # Path to this constant for use with HTML generator output. + + def path + "#{@parent.path}##{@name}" + end + + def pretty_print(q) # :nodoc: + q.group 2, "[#{self.class.name} #{full_name}", "]" do + unless comment.empty? then + q.breakable + q.text "comment:" + q.breakable + q.pp @comment + end + end + end + + ## + # Sets the store for this class or module and its contained code objects. + + def store=(store) + super + + @file = @store.add_file @file.full_name if @file + end + + def to_s # :nodoc: + parent_name = parent ? parent.full_name : '(unknown)' + if is_alias_for + "constant #{parent_name}::#@name -> #{is_alias_for}" + else + "constant #{parent_name}::#@name" + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/context.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/context.rb new file mode 100644 index 00000000..3a4dd0ec --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/context.rb @@ -0,0 +1,1222 @@ +# frozen_string_literal: true +## +# A Context is something that can hold modules, classes, methods, attributes, +# aliases, requires, and includes. Classes, modules, and files are all +# Contexts. + +class RDoc::Context < RDoc::CodeObject + + include Comparable + + ## + # Types of methods + + TYPES = %w[class instance] + + ## + # If a context has these titles it will be sorted in this order. + + TOMDOC_TITLES = [nil, 'Public', 'Internal', 'Deprecated'] # :nodoc: + TOMDOC_TITLES_SORT = TOMDOC_TITLES.sort_by { |title| title.to_s } # :nodoc: + + ## + # Class/module aliases + + attr_reader :aliases + + ## + # All attr* methods + + attr_reader :attributes + + ## + # Block params to be used in the next MethodAttr parsed under this context + + attr_accessor :block_params + + ## + # Constants defined + + attr_reader :constants + + ## + # Sets the current documentation section of documentation + + attr_writer :current_section + + ## + # Files this context is found in + + attr_reader :in_files + + ## + # Modules this context includes + + attr_reader :includes + + ## + # Modules this context is extended with + + attr_reader :extends + + ## + # Methods defined in this context + + attr_reader :method_list + + ## + # Name of this class excluding namespace. See also full_name + + attr_reader :name + + ## + # Files this context requires + + attr_reader :requires + + ## + # Use this section for the next method, attribute or constant added. + + attr_accessor :temporary_section + + ## + # Hash old_name => [aliases], for aliases + # that haven't (yet) been resolved to a method/attribute. + # (Not to be confused with the aliases of the context.) + + attr_accessor :unmatched_alias_lists + + ## + # Aliases that could not be resolved. + + attr_reader :external_aliases + + ## + # Current visibility of this context + + attr_accessor :visibility + + ## + # Current visibility of this line + + attr_writer :current_line_visibility + + ## + # Hash of registered methods. Attributes are also registered here, + # twice if they are RW. + + attr_reader :methods_hash + + ## + # Params to be used in the next MethodAttr parsed under this context + + attr_accessor :params + + ## + # Hash of registered constants. + + attr_reader :constants_hash + + ## + # Creates an unnamed empty context with public current visibility + + def initialize + super + + @in_files = [] + + @name ||= "unknown" + @parent = nil + @visibility = :public + + @current_section = Section.new self, nil, nil + @sections = { nil => @current_section } + @temporary_section = nil + + @classes = {} + @modules = {} + + initialize_methods_etc + end + + ## + # Sets the defaults for methods and so-forth + + def initialize_methods_etc + @method_list = [] + @attributes = [] + @aliases = [] + @requires = [] + @includes = [] + @extends = [] + @constants = [] + @external_aliases = [] + @current_line_visibility = nil + + # This Hash maps a method name to a list of unmatched aliases (aliases of + # a method not yet encountered). + @unmatched_alias_lists = {} + + @methods_hash = {} + @constants_hash = {} + + @params = nil + + @store ||= nil + end + + ## + # Contexts are sorted by full_name + + def <=>(other) + return nil unless RDoc::CodeObject === other + + full_name <=> other.full_name + end + + ## + # Adds an item of type +klass+ with the given +name+ and +comment+ to the + # context. + # + # Currently only RDoc::Extend and RDoc::Include are supported. + + def add(klass, name, comment) + if RDoc::Extend == klass then + ext = RDoc::Extend.new name, comment + add_extend ext + elsif RDoc::Include == klass then + incl = RDoc::Include.new name, comment + add_include incl + else + raise NotImplementedError, "adding a #{klass} is not implemented" + end + end + + ## + # Adds +an_alias+ that is automatically resolved + + def add_alias(an_alias) + return an_alias unless @document_self + + method_attr = find_method(an_alias.old_name, an_alias.singleton) || + find_attribute(an_alias.old_name, an_alias.singleton) + + if method_attr then + method_attr.add_alias an_alias, self + else + add_to @external_aliases, an_alias + unmatched_alias_list = + @unmatched_alias_lists[an_alias.pretty_old_name] ||= [] + unmatched_alias_list.push an_alias + end + + an_alias + end + + ## + # Adds +attribute+ if not already there. If it is (as method(s) or attribute), + # updates the comment if it was empty. + # + # The attribute is registered only if it defines a new method. + # For instance, attr_reader :foo will not be registered + # if method +foo+ exists, but attr_accessor :foo will be registered + # if method +foo+ exists, but foo= does not. + + def add_attribute(attribute) + return attribute unless @document_self + + # mainly to check for redefinition of an attribute as a method + # TODO find a policy for 'attr_reader :foo' + 'def foo=()' + register = false + + key = nil + + if attribute.rw.index 'R' then + key = attribute.pretty_name + known = @methods_hash[key] + + if known then + known.comment = attribute.comment if known.comment.empty? + elsif registered = @methods_hash[attribute.pretty_name + '='] and + RDoc::Attr === registered then + registered.rw = 'RW' + else + @methods_hash[key] = attribute + register = true + end + end + + if attribute.rw.index 'W' then + key = attribute.pretty_name + '=' + known = @methods_hash[key] + + if known then + known.comment = attribute.comment if known.comment.empty? + elsif registered = @methods_hash[attribute.pretty_name] and + RDoc::Attr === registered then + registered.rw = 'RW' + else + @methods_hash[key] = attribute + register = true + end + end + + if register then + attribute.visibility = @visibility + add_to @attributes, attribute + resolve_aliases attribute + end + + attribute + end + + ## + # Adds a class named +given_name+ with +superclass+. + # + # Both +given_name+ and +superclass+ may contain '::', and are + # interpreted relative to the +self+ context. This allows handling correctly + # examples like these: + # class RDoc::Gauntlet < Gauntlet + # module Mod + # class Object # implies < ::Object + # class SubObject < Object # this is _not_ ::Object + # + # Given class Container::Item RDoc assumes +Container+ is a module + # unless it later sees class Container. +add_class+ automatically + # upgrades +given_name+ to a class in this case. + + def add_class(class_type, given_name, superclass = '::Object') + # superclass +nil+ is passed by the C parser in the following cases: + # - registering Object in 1.8 (correct) + # - registering BasicObject in 1.9 (correct) + # - registering RubyVM in 1.9 in iseq.c (incorrect: < Object in vm.c) + # + # If we later find a superclass for a registered class with a nil + # superclass, we must honor it. + + # find the name & enclosing context + if given_name =~ /^:+(\w+)$/ then + full_name = $1 + enclosing = top_level + name = full_name.split(/:+/).last + else + full_name = child_name given_name + + if full_name =~ /^(.+)::(\w+)$/ then + name = $2 + ename = $1 + enclosing = @store.classes_hash[ename] || @store.modules_hash[ename] + # HACK: crashes in actionpack/lib/action_view/helpers/form_helper.rb (metaprogramming) + unless enclosing then + # try the given name at top level (will work for the above example) + enclosing = @store.classes_hash[given_name] || + @store.modules_hash[given_name] + return enclosing if enclosing + # not found: create the parent(s) + names = ename.split('::') + enclosing = self + names.each do |n| + enclosing = enclosing.classes_hash[n] || + enclosing.modules_hash[n] || + enclosing.add_module(RDoc::NormalModule, n) + end + end + else + name = full_name + enclosing = self + end + end + + # fix up superclass + if full_name == 'BasicObject' then + superclass = nil + elsif full_name == 'Object' then + superclass = '::BasicObject' + end + + # find the superclass full name + if superclass then + if superclass =~ /^:+/ then + superclass = $' #' + else + if superclass =~ /^(\w+):+(.+)$/ then + suffix = $2 + mod = find_module_named($1) + superclass = mod.full_name + '::' + suffix if mod + else + mod = find_module_named(superclass) + superclass = mod.full_name if mod + end + end + + # did we believe it was a module? + mod = @store.modules_hash.delete superclass + + upgrade_to_class mod, RDoc::NormalClass, mod.parent if mod + + # e.g., Object < Object + superclass = nil if superclass == full_name + end + + klass = @store.classes_hash[full_name] + + if klass then + # if TopLevel, it may not be registered in the classes: + enclosing.classes_hash[name] = klass + + # update the superclass if needed + if superclass then + existing = klass.superclass + existing = existing.full_name unless existing.is_a?(String) if existing + if existing.nil? || + (existing == 'Object' && superclass != 'Object') then + klass.superclass = superclass + end + end + else + # this is a new class + mod = @store.modules_hash.delete full_name + + if mod then + klass = upgrade_to_class mod, RDoc::NormalClass, enclosing + + klass.superclass = superclass unless superclass.nil? + else + klass = class_type.new name, superclass + + enclosing.add_class_or_module(klass, enclosing.classes_hash, + @store.classes_hash) + end + end + + klass.parent = self + + klass + end + + ## + # Adds the class or module +mod+ to the modules or + # classes Hash +self_hash+, and to +all_hash+ (either + # TopLevel::modules_hash or TopLevel::classes_hash), + # unless #done_documenting is +true+. Sets the #parent of +mod+ + # to +self+, and its #section to #current_section. Returns +mod+. + + def add_class_or_module(mod, self_hash, all_hash) + mod.section = current_section # TODO declaring context? something is + # wrong here... + mod.parent = self + mod.full_name = nil + mod.store = @store + + unless @done_documenting then + self_hash[mod.name] = mod + # this must be done AFTER adding mod to its parent, so that the full + # name is correct: + all_hash[mod.full_name] = mod + if @store.unmatched_constant_alias[mod.full_name] then + to, file = @store.unmatched_constant_alias[mod.full_name] + add_module_alias mod, mod.name, to, file + end + end + + mod + end + + ## + # Adds +constant+ if not already there. If it is, updates the comment, + # value and/or is_alias_for of the known constant if they were empty/nil. + + def add_constant(constant) + return constant unless @document_self + + # HACK: avoid duplicate 'PI' & 'E' in math.c (1.8.7 source code) + # (this is a #ifdef: should be handled by the C parser) + known = @constants_hash[constant.name] + + if known then + known.comment = constant.comment if known.comment.empty? + + known.value = constant.value if + known.value.nil? or known.value.strip.empty? + + known.is_alias_for ||= constant.is_alias_for + else + @constants_hash[constant.name] = constant + add_to @constants, constant + end + + constant + end + + ## + # Adds included module +include+ which should be an RDoc::Include + + def add_include(include) + add_to @includes, include + + include + end + + ## + # Adds extension module +ext+ which should be an RDoc::Extend + + def add_extend(ext) + add_to @extends, ext + + ext + end + + ## + # Adds +method+ if not already there. If it is (as method or attribute), + # updates the comment if it was empty. + + def add_method(method) + return method unless @document_self + + # HACK: avoid duplicate 'new' in io.c & struct.c (1.8.7 source code) + key = method.pretty_name + known = @methods_hash[key] + + if known then + if @store then # otherwise we are loading + known.comment = method.comment if known.comment.empty? + previously = ", previously in #{known.file}" unless + method.file == known.file + @store.options.warn \ + "Duplicate method #{known.full_name} in #{method.file}#{previously}" + end + else + @methods_hash[key] = method + if @current_line_visibility + method.visibility, @current_line_visibility = @current_line_visibility, nil + else + method.visibility = @visibility + end + add_to @method_list, method + resolve_aliases method + end + + method + end + + ## + # Adds a module named +name+. If RDoc already knows +name+ is a class then + # that class is returned instead. See also #add_class. + + def add_module(class_type, name) + mod = @classes[name] || @modules[name] + return mod if mod + + full_name = child_name name + mod = @store.modules_hash[full_name] || class_type.new(name) + + add_class_or_module mod, @modules, @store.modules_hash + end + + ## + # Adds a module by +RDoc::NormalModule+ instance. See also #add_module. + + def add_module_by_normal_module(mod) + add_class_or_module mod, @modules, @store.modules_hash + end + + ## + # Adds an alias from +from+ (a class or module) to +name+ which was defined + # in +file+. + + def add_module_alias(from, from_name, to, file) + return from if @done_documenting + + to_full_name = child_name to.name + + # if we already know this name, don't register an alias: + # see the metaprogramming in lib/active_support/basic_object.rb, + # where we already know BasicObject is a class when we find + # BasicObject = BlankSlate + return from if @store.find_class_or_module to_full_name + + unless from + @store.unmatched_constant_alias[child_name(from_name)] = [to, file] + return to + end + + new_to = from.dup + new_to.name = to.name + new_to.full_name = nil + + if new_to.module? then + @store.modules_hash[to_full_name] = new_to + @modules[to.name] = new_to + else + @store.classes_hash[to_full_name] = new_to + @classes[to.name] = new_to + end + + # Registers a constant for this alias. The constant value and comment + # will be updated later, when the Ruby parser adds the constant + const = RDoc::Constant.new to.name, nil, new_to.comment + const.record_location file + const.is_alias_for = from + add_constant const + + new_to + end + + ## + # Adds +require+ to this context's top level + + def add_require(require) + return require unless @document_self + + if RDoc::TopLevel === self then + add_to @requires, require + else + parent.add_require require + end + end + + ## + # Returns a section with +title+, creating it if it doesn't already exist. + # +comment+ will be appended to the section's comment. + # + # A section with a +title+ of +nil+ will return the default section. + # + # See also RDoc::Context::Section + + def add_section(title, comment = nil) + if section = @sections[title] then + section.add_comment comment if comment + else + section = Section.new self, title, comment + @sections[title] = section + end + + section + end + + ## + # Adds +thing+ to the collection +array+ + + def add_to(array, thing) + array << thing if @document_self + + thing.parent = self + thing.store = @store if @store + thing.section = current_section + end + + ## + # Is there any content? + # + # This means any of: comment, aliases, methods, attributes, external + # aliases, require, constant. + # + # Includes and extends are also checked unless includes == false. + + def any_content(includes = true) + @any_content ||= !( + @comment.empty? && + @method_list.empty? && + @attributes.empty? && + @aliases.empty? && + @external_aliases.empty? && + @requires.empty? && + @constants.empty? + ) + @any_content || (includes && !(@includes + @extends).empty? ) + end + + ## + # Creates the full name for a child with +name+ + + def child_name(name) + if name =~ /^:+/ + $' #' + elsif RDoc::TopLevel === self then + name + else + "#{self.full_name}::#{name}" + end + end + + ## + # Class attributes + + def class_attributes + @class_attributes ||= attributes.select { |a| a.singleton } + end + + ## + # Class methods + + def class_method_list + @class_method_list ||= method_list.select { |a| a.singleton } + end + + ## + # Array of classes in this context + + def classes + @classes.values + end + + ## + # All classes and modules in this namespace + + def classes_and_modules + classes + modules + end + + ## + # Hash of classes keyed by class name + + def classes_hash + @classes + end + + ## + # The current documentation section that new items will be added to. If + # temporary_section is available it will be used. + + def current_section + if section = @temporary_section then + @temporary_section = nil + else + section = @current_section + end + + section + end + + def display(method_attr) # :nodoc: + if method_attr.is_a? RDoc::Attr + "#{method_attr.definition} #{method_attr.pretty_name}" + else + "method #{method_attr.pretty_name}" + end + end + + ## + # Iterator for ancestors for duck-typing. Does nothing. See + # RDoc::ClassModule#each_ancestor. + # + # This method exists to make it easy to work with Context subclasses that + # aren't part of RDoc. + + def each_ancestor(&_) # :nodoc: + end + + ## + # Iterator for classes and modules + + def each_classmodule(&block) # :yields: module + classes_and_modules.sort.each(&block) + end + + ## + # Iterator for methods + + def each_method # :yields: method + return enum_for __method__ unless block_given? + + @method_list.sort.each { |m| yield m } + end + + ## + # Iterator for each section's contents sorted by title. The +section+, the + # section's +constants+ and the sections +attributes+ are yielded. The + # +constants+ and +attributes+ collections are sorted. + # + # To retrieve methods in a section use #methods_by_type with the optional + # +section+ parameter. + # + # NOTE: Do not edit collections yielded by this method + + def each_section # :yields: section, constants, attributes + return enum_for __method__ unless block_given? + + constants = @constants.group_by do |constant| constant.section end + attributes = @attributes.group_by do |attribute| attribute.section end + + constants.default = [] + attributes.default = [] + + sort_sections.each do |section| + yield section, constants[section].select(&:display?).sort, attributes[section].select(&:display?).sort + end + end + + ## + # Finds an attribute +name+ with singleton value +singleton+. + + def find_attribute(name, singleton) + name = $1 if name =~ /^(.*)=$/ + @attributes.find { |a| a.name == name && a.singleton == singleton } + end + + ## + # Finds an attribute with +name+ in this context + + def find_attribute_named(name) + case name + when /\A#/ then + find_attribute name[1..-1], false + when /\A::/ then + find_attribute name[2..-1], true + else + @attributes.find { |a| a.name == name } + end + end + + ## + # Finds a class method with +name+ in this context + + def find_class_method_named(name) + @method_list.find { |meth| meth.singleton && meth.name == name } + end + + ## + # Finds a constant with +name+ in this context + + def find_constant_named(name) + @constants.find do |m| + m.name == name || m.full_name == name + end + end + + ## + # Find a module at a higher scope + + def find_enclosing_module_named(name) + parent && parent.find_module_named(name) + end + + ## + # Finds an external alias +name+ with singleton value +singleton+. + + def find_external_alias(name, singleton) + @external_aliases.find { |m| m.name == name && m.singleton == singleton } + end + + ## + # Finds an external alias with +name+ in this context + + def find_external_alias_named(name) + case name + when /\A#/ then + find_external_alias name[1..-1], false + when /\A::/ then + find_external_alias name[2..-1], true + else + @external_aliases.find { |a| a.name == name } + end + end + + ## + # Finds an instance method with +name+ in this context + + def find_instance_method_named(name) + @method_list.find { |meth| !meth.singleton && meth.name == name } + end + + ## + # Finds a method, constant, attribute, external alias, module or file + # named +symbol+ in this context. + + def find_local_symbol(symbol) + find_method_named(symbol) or + find_constant_named(symbol) or + find_attribute_named(symbol) or + find_external_alias_named(symbol) or + find_module_named(symbol) or + @store.find_file_named(symbol) + end + + ## + # Finds a method named +name+ with singleton value +singleton+. + + def find_method(name, singleton) + @method_list.find { |m| + if m.singleton + m.name == name && m.singleton == singleton + else + m.name == name && !m.singleton && !singleton + end + } + end + + ## + # Finds a instance or module method with +name+ in this context + + def find_method_named(name) + case name + when /\A#/ then + find_method name[1..-1], false + when /\A::/ then + find_method name[2..-1], true + else + @method_list.find { |meth| meth.name == name } + end + end + + ## + # Find a module with +name+ using ruby's scoping rules + + def find_module_named(name) + res = @modules[name] || @classes[name] + return res if res + return self if self.name == name + find_enclosing_module_named name + end + + ## + # Look up +symbol+, first as a module, then as a local symbol. + + def find_symbol(symbol) + find_symbol_module(symbol) || find_local_symbol(symbol) + end + + ## + # Look up a module named +symbol+. + + def find_symbol_module(symbol) + result = nil + + # look for a class or module 'symbol' + case symbol + when /^::/ then + result = @store.find_class_or_module symbol + when /^(\w+):+(.+)$/ + suffix = $2 + top = $1 + searched = self + while searched do + mod = searched.find_module_named(top) + break unless mod + result = @store.find_class_or_module "#{mod.full_name}::#{suffix}" + break if result || searched.is_a?(RDoc::TopLevel) + searched = searched.parent + end + else + searched = self + while searched do + result = searched.find_module_named(symbol) + break if result || searched.is_a?(RDoc::TopLevel) + searched = searched.parent + end + end + + result + end + + ## + # The full name for this context. This method is overridden by subclasses. + + def full_name + '(unknown)' + end + + ## + # Does this context and its methods and constants all have documentation? + # + # (Yes, fully documented doesn't mean everything.) + + def fully_documented? + documented? and + attributes.all? { |a| a.documented? } and + method_list.all? { |m| m.documented? } and + constants.all? { |c| c.documented? } + end + + ## + # URL for this with a +prefix+ + + def http_url + path = name_for_path + path = path.gsub(/<<\s*(\w*)/, 'from-\1') if path =~ /<'class' or + # 'instance') and visibility (+:public+, +:protected+, +:private+). + # + # If +section+ is provided only methods in that RDoc::Context::Section will + # be returned. + + def methods_by_type(section = nil) + methods = {} + + TYPES.each do |type| + visibilities = {} + RDoc::VISIBILITIES.each do |vis| + visibilities[vis] = [] + end + + methods[type] = visibilities + end + + each_method do |method| + next if section and not method.section == section + methods[method.type][method.visibility] << method + end + + methods + end + + ## + # Yields AnyMethod and Attr entries matching the list of names in +methods+. + + def methods_matching(methods, singleton = false, &block) + (@method_list + @attributes).each do |m| + yield m if methods.include?(m.name) and m.singleton == singleton + end + + each_ancestor do |parent| + parent.methods_matching(methods, singleton, &block) + end + end + + ## + # Array of modules in this context + + def modules + @modules.values + end + + ## + # Hash of modules keyed by module name + + def modules_hash + @modules + end + + ## + # Name to use to generate the url. + # #full_name by default. + + def name_for_path + full_name + end + + ## + # Changes the visibility for new methods to +visibility+ + + def ongoing_visibility=(visibility) + @visibility = visibility + end + + ## + # Record +top_level+ as a file +self+ is in. + + def record_location(top_level) + @in_files << top_level unless @in_files.include?(top_level) + end + + ## + # Should we remove this context from the documentation? + # + # The answer is yes if: + # * #received_nodoc is +true+ + # * #any_content is +false+ (not counting includes) + # * All #includes are modules (not a string), and their module has + # #remove_from_documentation? == true + # * All classes and modules have #remove_from_documentation? == true + + def remove_from_documentation? + @remove_from_documentation ||= + @received_nodoc && + !any_content(false) && + @includes.all? { |i| !i.module.is_a?(String) && i.module.remove_from_documentation? } && + classes_and_modules.all? { |cm| cm.remove_from_documentation? } + end + + ## + # Removes methods and attributes with a visibility less than +min_visibility+. + #-- + # TODO mark the visibility of attributes in the template (if not public?) + + def remove_invisible(min_visibility) + return if [:private, :nodoc].include? min_visibility + remove_invisible_in @method_list, min_visibility + remove_invisible_in @attributes, min_visibility + remove_invisible_in @constants, min_visibility + end + + ## + # Only called when min_visibility == :public or :private + + def remove_invisible_in(array, min_visibility) # :nodoc: + if min_visibility == :public then + array.reject! { |e| + e.visibility != :public and not e.force_documentation + } + else + array.reject! { |e| + e.visibility == :private and not e.force_documentation + } + end + end + + ## + # Tries to resolve unmatched aliases when a method or attribute has just + # been added. + + def resolve_aliases(added) + # resolve any pending unmatched aliases + key = added.pretty_name + unmatched_alias_list = @unmatched_alias_lists[key] + return unless unmatched_alias_list + unmatched_alias_list.each do |unmatched_alias| + added.add_alias unmatched_alias, self + @external_aliases.delete unmatched_alias + end + @unmatched_alias_lists.delete key + end + + ## + # Returns RDoc::Context::Section objects referenced in this context for use + # in a table of contents. + + def section_contents + used_sections = {} + + each_method do |method| + next unless method.display? + + used_sections[method.section] = true + end + + # order found sections + sections = sort_sections.select do |section| + used_sections[section] + end + + # only the default section is used + return [] if + sections.length == 1 and not sections.first.title + + sections + end + + ## + # Sections in this context + + def sections + @sections.values + end + + def sections_hash # :nodoc: + @sections + end + + ## + # Sets the current section to a section with +title+. See also #add_section + + def set_current_section(title, comment) + @current_section = add_section title, comment + end + + ## + # Given an array +methods+ of method names, set the visibility of each to + # +visibility+ + + def set_visibility_for(methods, visibility, singleton = false) + methods_matching methods, singleton do |m| + m.visibility = visibility + end + end + + ## + # Given an array +names+ of constants, set the visibility of each constant to + # +visibility+ + + def set_constant_visibility_for(names, visibility) + names.each do |name| + constant = @constants_hash[name] or next + constant.visibility = visibility + end + end + + ## + # Sorts sections alphabetically (default) or in TomDoc fashion (none, + # Public, Internal, Deprecated) + + def sort_sections + titles = @sections.map { |title, _| title } + + if titles.length > 1 and + TOMDOC_TITLES_SORT == + (titles | TOMDOC_TITLES).sort_by { |title| title.to_s } then + @sections.values_at(*TOMDOC_TITLES).compact + else + @sections.sort_by { |title, _| + title.to_s + }.map { |_, section| + section + } + end + end + + def to_s # :nodoc: + "#{self.class.name} #{self.full_name}" + end + + ## + # Return the TopLevel that owns us + #-- + # FIXME we can be 'owned' by several TopLevel (see #record_location & + # #in_files) + + def top_level + return @top_level if defined? @top_level + @top_level = self + @top_level = @top_level.parent until RDoc::TopLevel === @top_level + @top_level + end + + ## + # Upgrades NormalModule +mod+ in +enclosing+ to a +class_type+ + + def upgrade_to_class(mod, class_type, enclosing) + enclosing.modules_hash.delete mod.name + + klass = RDoc::ClassModule.from_module class_type, mod + klass.store = @store + + # if it was there, then we keep it even if done_documenting + @store.classes_hash[mod.full_name] = klass + enclosing.classes_hash[mod.name] = klass + + klass + end + + autoload :Section, "#{__dir__}/context/section" + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/context/section.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/context/section.rb new file mode 100644 index 00000000..ff4d5a60 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/context/section.rb @@ -0,0 +1,175 @@ +# frozen_string_literal: true +require 'cgi/escape' + +## +# A section of documentation like: +# +# # :section: The title +# # The body +# +# Sections can be referenced multiple times and will be collapsed into a +# single section. + +class RDoc::Context::Section + + include RDoc::Text + + MARSHAL_VERSION = 0 # :nodoc: + + ## + # Section comment + + attr_reader :comment + + ## + # Section comments + + attr_reader :comments + + ## + # Context this Section lives in + + attr_reader :parent + + ## + # Section title + + attr_reader :title + + ## + # Creates a new section with +title+ and +comment+ + + def initialize(parent, title, comment) + @parent = parent + @title = title ? title.strip : title + + @comments = [] + + add_comment comment + end + + ## + # Sections are equal when they have the same #title + + def ==(other) + self.class === other and @title == other.title + end + + alias eql? == + + ## + # Adds +comment+ to this section + + def add_comment(comment) + comments = Array(comment) + comments.each do |c| + extracted_comment = extract_comment(c) + @comments << extracted_comment unless extracted_comment.empty? + end + end + + ## + # Anchor reference for linking to this section + + def aref + title = @title || '[untitled]' + + CGI.escape(title).gsub('%', '-').sub(/^-/, '') + end + + ## + # Extracts the comment for this section from the original comment block. + # If the first line contains :section:, strip it and use the rest. + # Otherwise remove lines up to the line containing :section:, and look + # for those lines again at the end and remove them. This lets us write + # + # # :section: The title + # # The body + + def extract_comment(comment) + case comment + when nil + RDoc::Comment.new '' + when RDoc::Comment then + if comment.text =~ /^#[ \t]*:section:.*\n/ then + start = $` + rest = $' + + comment.text = if start.empty? then + rest + else + rest.sub(/#{start.chomp}\Z/, '') + end + end + + comment + else + raise TypeError, "unknown comment #{comment.inspect}" + end + end + + def inspect # :nodoc: + "#<%s:0x%x %p>" % [self.class, object_id, title] + end + + def hash # :nodoc: + @title.hash + end + + ## + # The files comments in this section come from + + def in_files + @comments.map(&:file) + end + + ## + # Serializes this Section. The title and parsed comment are saved, but not + # the section parent which must be restored manually. + + def marshal_dump + [ + MARSHAL_VERSION, + @title, + parse, + ] + end + + ## + # De-serializes this Section. The section parent must be restored manually. + + def marshal_load(array) + @parent = nil + + @title = array[1] + @comments = array[2].parts.map { |doc| RDoc::Comment.from_document(doc) } + end + + ## + # Parses +comment_location+ into an RDoc::Markup::Document composed of + # multiple RDoc::Markup::Documents with their file set. + + def parse + RDoc::Markup::Document.new(*@comments.map(&:parse)) + end + + ## + # The section's title, or 'Top Section' if the title is nil. + # + # This is used by the table of contents template so the name is silly. + + def plain_html + @title || 'Top Section' + end + + ## + # Removes a comment from this section if it is from the same file as + # +comment+ + + def remove_comment(target_comment) + @comments.delete_if do |stored_comment| + stored_comment.file == target_comment.file + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/extend.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/extend.rb new file mode 100644 index 00000000..7d57433d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/extend.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true +## +# A Module extension to a class with \#extend +# +# RDoc::Extend.new 'Enumerable', 'comment ...' + +class RDoc::Extend < RDoc::Mixin + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/ghost_method.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/ghost_method.rb new file mode 100644 index 00000000..25f951e3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/ghost_method.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true +## +# GhostMethod represents a method referenced only by a comment + +class RDoc::GhostMethod < RDoc::AnyMethod +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/include.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/include.rb new file mode 100644 index 00000000..c3e0d45e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/include.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true +## +# A Module included in a class with \#include +# +# RDoc::Include.new 'Enumerable', 'comment ...' + +class RDoc::Include < RDoc::Mixin + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/meta_method.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/meta_method.rb new file mode 100644 index 00000000..8c95a0f7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/meta_method.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true +## +# MetaMethod represents a meta-programmed method + +class RDoc::MetaMethod < RDoc::AnyMethod +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/method_attr.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/method_attr.rb new file mode 100644 index 00000000..3dd60719 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/method_attr.rb @@ -0,0 +1,410 @@ +# frozen_string_literal: true +## +# Abstract class representing either a method or an attribute. + +class RDoc::MethodAttr < RDoc::CodeObject + + include Comparable + + ## + # Name of this method/attribute. + + attr_accessor :name + + ## + # public, protected, private + + attr_accessor :visibility + + ## + # Is this a singleton method/attribute? + + attr_accessor :singleton + + ## + # Source file token stream + + attr_reader :text + + ## + # Array of other names for this method/attribute + + attr_reader :aliases + + ## + # The method/attribute we're aliasing + + attr_accessor :is_alias_for + + #-- + # The attributes below are for AnyMethod only. + # They are left here for the time being to + # allow ri to operate. + # TODO modify ri to avoid calling these on attributes. + #++ + + ## + # Parameters yielded by the called block + + attr_reader :block_params + + ## + # Parameters for this method + + attr_accessor :params + + ## + # Different ways to call this method + + attr_accessor :call_seq + + ## + # The call_seq or the param_seq with method name, if there is no call_seq. + + attr_reader :arglists + + ## + # Creates a new MethodAttr from token stream +text+ and method or attribute + # name +name+. + # + # Usually this is called by super from a subclass. + + def initialize(text, name, singleton: false) + super() + + @text = text + @name = name + + @aliases = [] + @is_alias_for = nil + @parent_name = nil + @singleton = singleton + @visibility = :public + @see = false + + @arglists = nil + @block_params = nil + @call_seq = nil + @params = nil + end + + ## + # Resets cached data for the object so it can be rebuilt by accessor methods + + def initialize_copy(other) # :nodoc: + @full_name = nil + end + + def initialize_visibility # :nodoc: + super + @see = nil + end + + ## + # Order by #singleton then #name + + def <=>(other) + return unless other.respond_to?(:singleton) && + other.respond_to?(:name) + + [@singleton ? 0 : 1, name_ord_range, name] <=> + [other.singleton ? 0 : 1, other.name_ord_range, other.name] + end + + def ==(other) # :nodoc: + equal?(other) or self.class == other.class and full_name == other.full_name + end + + ## + # A method/attribute is documented if any of the following is true: + # - it was marked with :nodoc:; + # - it has a comment; + # - it is an alias for a documented method; + # - it has a +#see+ method that is documented. + + def documented? + super or + (is_alias_for and is_alias_for.documented?) or + (see and see.documented?) + end + + ## + # A method/attribute to look at, + # in particular if this method/attribute has no documentation. + # + # It can be a method/attribute of the superclass or of an included module, + # including the Kernel module, which is always appended to the included + # modules. + # + # Returns +nil+ if there is no such method/attribute. + # The +#is_alias_for+ method/attribute, if any, is not included. + # + # Templates may generate a "see also ..." if this method/attribute + # has documentation, and "see ..." if it does not. + + def see + @see = find_see if @see == false + @see + end + + ## + # Sets the store for this class or module and its contained code objects. + + def store=(store) + super + + @file = @store.add_file @file.full_name if @file + end + + def find_see # :nodoc: + return nil if singleton || is_alias_for + + # look for the method + other = find_method_or_attribute name + return other if other + + # if it is a setter, look for a getter + return nil unless name =~ /[a-z_]=$/i # avoid == or === + return find_method_or_attribute name[0..-2] + end + + def find_method_or_attribute(name) # :nodoc: + return nil unless parent.respond_to? :ancestors + + searched = parent.ancestors + kernel = @store.modules_hash['Kernel'] + + searched << kernel if kernel && + parent != kernel && !searched.include?(kernel) + + searched.each do |ancestor| + next if String === ancestor + next if parent == ancestor + + other = ancestor.find_method_named('#' + name) || + ancestor.find_attribute_named(name) + + return other if other + end + + nil + end + + ## + # Abstract method. Contexts in their building phase call this + # to register a new alias for this known method/attribute. + # + # - creates a new AnyMethod/Attribute named an_alias.new_name; + # - adds +self+ as an alias for the new method or attribute + # - adds the method or attribute to #aliases + # - adds the method or attribute to +context+. + + def add_alias(an_alias, context) + raise NotImplementedError + end + + ## + # HTML fragment reference for this method + + def aref + type = singleton ? 'c' : 'i' + # % characters are not allowed in html names => dash instead + "#{aref_prefix}-#{type}-#{html_name}" + end + + ## + # Prefix for +aref+, defined by subclasses. + + def aref_prefix + raise NotImplementedError + end + + ## + # Attempts to sanitize the content passed by the Ruby parser: + # remove outer parentheses, etc. + + def block_params=(value) + # 'yield.to_s' or 'assert yield, msg' + return @block_params = '' if value =~ /^[\.,]/ + + # remove trailing 'if/unless ...' + return @block_params = '' if value =~ /^(if|unless)\s/ + + value = $1.strip if value =~ /^(.+)\s(if|unless)\s/ + + # outer parentheses + value = $1 if value =~ /^\s*\((.*)\)\s*$/ + value = value.strip + + # proc/lambda + return @block_params = $1 if value =~ /^(proc|lambda)(\s*\{|\sdo)/ + + # surrounding +...+ or [...] + value = $1.strip if value =~ /^\+(.*)\+$/ + value = $1.strip if value =~ /^\[(.*)\]$/ + + return @block_params = '' if value.empty? + + # global variable + return @block_params = 'str' if value =~ /^\$[&0-9]$/ + + # wipe out array/hash indices + value.gsub!(/(\w)\[[^\[]+\]/, '\1') + + # remove @ from class/instance variables + value.gsub!(/@@?([a-z0-9_]+)/, '\1') + + # method calls => method name + value.gsub!(/([A-Z:a-z0-9_]+)\.([a-z0-9_]+)(\s*\(\s*[a-z0-9_.,\s]*\s*\)\s*)?/) do + case $2 + when 'to_s' then $1 + when 'const_get' then 'const' + when 'new' then + $1.split('::').last. # ClassName => class_name + gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2'). + gsub(/([a-z\d])([A-Z])/, '\1_\2'). + downcase + else + $2 + end + end + + # class prefixes + value.gsub!(/[A-Za-z0-9_:]+::/, '') + + # simple expressions + value = $1 if value =~ /^([a-z0-9_]+)\s*[-*+\/]/ + + @block_params = value.strip + end + + ## + # HTML id-friendly method/attribute name + + def html_name + require 'cgi/escape' + + CGI.escape(@name.gsub('-', '-2D')).gsub('%', '-').sub(/^-/, '') + end + + ## + # Full method/attribute name including namespace + + def full_name + @full_name ||= "#{parent_name}#{pretty_name}" + end + + def inspect # :nodoc: + alias_for = @is_alias_for ? " (alias for #{@is_alias_for.name})" : nil + visibility = self.visibility + visibility = "forced #{visibility}" if force_documentation + "#<%s:0x%x %s (%s)%s>" % [ + self.class, object_id, + full_name, + visibility, + alias_for, + ] + end + + ## + # '::' for a class method/attribute, '#' for an instance method. + + def name_prefix + @singleton ? '::' : '#' + end + + ## + # Method/attribute name with class/instance indicator + + def pretty_name + "#{name_prefix}#{@name}" + end + + ## + # Type of method/attribute (class or instance) + + def type + singleton ? 'class' : 'instance' + end + + ## + # Path to this method for use with HTML generator output. + + def path + "#{@parent.path}##{aref}" + end + + ## + # Name of our parent with special handling for un-marshaled methods + + def parent_name + @parent_name || super + end + + def pretty_print(q) # :nodoc: + alias_for = + if @is_alias_for.respond_to? :name then + "alias for #{@is_alias_for.name}" + elsif Array === @is_alias_for then + "alias for #{@is_alias_for.last}" + end + + q.group 2, "[#{self.class.name} #{full_name} #{visibility}", "]" do + if alias_for then + q.breakable + q.text alias_for + end + + if text then + q.breakable + q.text "text:" + q.breakable + q.pp @text + end + + unless comment.empty? then + q.breakable + q.text "comment:" + q.breakable + q.pp @comment + end + end + end + + ## + # Used by RDoc::Generator::JsonIndex to create a record for the search + # engine. + + def search_record + [ + @name, + full_name, + @name, + @parent.full_name, + path, + params, + snippet(@comment), + ] + end + + def to_s # :nodoc: + if @is_alias_for + "#{self.class.name}: #{full_name} -> #{is_alias_for}" + else + "#{self.class.name}: #{full_name}" + end + end + + def name_ord_range # :nodoc: + case name.ord + when 0..64 # anything below "A" + 1 + when 91..96 # the symbols between "Z" and "a" + 2 + when 123..126 # 7-bit symbols above "z": "{", "|", "}", "~" + 3 + else # everythig else can be sorted as normal + 4 + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/mixin.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/mixin.rb new file mode 100644 index 00000000..9b425efd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/mixin.rb @@ -0,0 +1,120 @@ +# frozen_string_literal: true +## +# A Mixin adds features from a module into another context. RDoc::Include and +# RDoc::Extend are both mixins. + +class RDoc::Mixin < RDoc::CodeObject + + ## + # Name of included module + + attr_accessor :name + + ## + # Creates a new Mixin for +name+ with +comment+ + + def initialize(name, comment) + super() + @name = name + self.comment = comment + @module = nil # cache for module if found + end + + ## + # Mixins are sorted by name + + def <=>(other) + return unless self.class === other + + name <=> other.name + end + + def ==(other) # :nodoc: + self.class === other and @name == other.name + end + + alias eql? == # :nodoc: + + ## + # Full name based on #module + + def full_name + m = self.module + RDoc::ClassModule === m ? m.full_name : @name + end + + def hash # :nodoc: + [@name, self.module].hash + end + + def inspect # :nodoc: + "#<%s:0x%x %s.%s %s>" % [ + self.class, + object_id, + parent_name, self.class.name.downcase, @name, + ] + end + + ## + # Attempts to locate the included module object. Returns the name if not + # known. + # + # The scoping rules of Ruby to resolve the name of an included module are: + # - first look into the children of the current context; + # - if not found, look into the children of included modules, + # in reverse inclusion order; + # - if still not found, go up the hierarchy of names. + # + # This method has O(n!) behavior when the module calling + # include is referencing nonexistent modules. Avoid calling #module until + # after all the files are parsed. This behavior is due to ruby's constant + # lookup behavior. + # + # As of the beginning of October, 2011, no gem includes nonexistent modules. + + def module + return @module if @module + + # search the current context + return @name unless parent + full_name = parent.child_name(@name) + @module = @store.modules_hash[full_name] + return @module if @module + return @name if @name =~ /^::/ + + # search the includes before this one, in reverse order + searched = parent.includes.take_while { |i| i != self }.reverse + searched.each do |i| + inc = i.module + next if String === inc + full_name = inc.child_name(@name) + @module = @store.modules_hash[full_name] + return @module if @module + end + + # go up the hierarchy of names + up = parent.parent + while up + full_name = up.child_name(@name) + @module = @store.modules_hash[full_name] + return @module if @module + up = up.parent + end + + @name + end + + ## + # Sets the store for this class or module and its contained code objects. + + def store=(store) + super + + @file = @store.add_file @file.full_name if @file + end + + def to_s # :nodoc: + "#{self.class.name.downcase} #@name in: #{parent}" + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/normal_class.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/normal_class.rb new file mode 100644 index 00000000..6b68d6db --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/normal_class.rb @@ -0,0 +1,92 @@ +# frozen_string_literal: true +## +# A normal class, neither singleton nor anonymous + +class RDoc::NormalClass < RDoc::ClassModule + + ## + # The ancestors of this class including modules. Unlike Module#ancestors, + # this class is not included in the result. The result will contain both + # RDoc::ClassModules and Strings. + + def ancestors + if String === superclass then + super << superclass + elsif superclass then + ancestors = super + ancestors << superclass + ancestors.concat superclass.ancestors + else + super + end + end + + def aref_prefix # :nodoc: + 'class' + end + + ## + # The definition of this class, class MyClassName + + def definition + "class #{full_name}" + end + + def direct_ancestors + superclass ? super + [superclass] : super + end + + def inspect # :nodoc: + superclass = @superclass ? " < #{@superclass}" : nil + "<%s:0x%x class %s%s includes: %p extends: %p attributes: %p methods: %p aliases: %p>" % [ + self.class, object_id, + full_name, superclass, @includes, @extends, @attributes, @method_list, @aliases + ] + end + + def to_s # :nodoc: + display = "#{self.class.name} #{self.full_name}" + if superclass + display += ' < ' + (superclass.is_a?(String) ? superclass : superclass.full_name) + end + display += ' -> ' + is_alias_for.to_s if is_alias_for + display + end + + def pretty_print(q) # :nodoc: + superclass = @superclass ? " < #{@superclass}" : nil + + q.group 2, "[class #{full_name}#{superclass}", "]" do + q.breakable + q.text "includes:" + q.breakable + q.seplist @includes do |inc| q.pp inc end + + q.breakable + q.text "constants:" + q.breakable + q.seplist @constants do |const| q.pp const end + + q.breakable + q.text "attributes:" + q.breakable + q.seplist @attributes do |attr| q.pp attr end + + q.breakable + q.text "methods:" + q.breakable + q.seplist @method_list do |meth| q.pp meth end + + q.breakable + q.text "aliases:" + q.breakable + q.seplist @aliases do |aliaz| q.pp aliaz end + + q.breakable + q.text "comment:" + q.breakable + q.pp comment + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/normal_module.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/normal_module.rb new file mode 100644 index 00000000..677a9dc3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/normal_module.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true +## +# A normal module, like NormalClass + +class RDoc::NormalModule < RDoc::ClassModule + + def aref_prefix # :nodoc: + 'module' + end + + def inspect # :nodoc: + "#<%s:0x%x module %s includes: %p extends: %p attributes: %p methods: %p aliases: %p>" % [ + self.class, object_id, + full_name, @includes, @extends, @attributes, @method_list, @aliases + ] + end + + ## + # The definition of this module, module MyModuleName + + def definition + "module #{full_name}" + end + + ## + # This is a module, returns true + + def module? + true + end + + def pretty_print(q) # :nodoc: + q.group 2, "[module #{full_name}:", "]" do + q.breakable + q.text "includes:" + q.breakable + q.seplist @includes do |inc| q.pp inc end + q.breakable + + q.breakable + q.text "constants:" + q.breakable + q.seplist @constants do |const| q.pp const end + + q.text "attributes:" + q.breakable + q.seplist @attributes do |attr| q.pp attr end + q.breakable + + q.text "methods:" + q.breakable + q.seplist @method_list do |meth| q.pp meth end + q.breakable + + q.text "aliases:" + q.breakable + q.seplist @aliases do |aliaz| q.pp aliaz end + q.breakable + + q.text "comment:" + q.breakable + q.pp comment + end + end + + ## + # Modules don't have one, raises NoMethodError + + def superclass + raise NoMethodError, "#{full_name} is a module" + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/require.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/require.rb new file mode 100644 index 00000000..f47e3b15 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/require.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true +## +# A file loaded by \#require + +class RDoc::Require < RDoc::CodeObject + + ## + # Name of the required file + + attr_accessor :name + + ## + # Creates a new Require that loads +name+ with +comment+ + + def initialize(name, comment) + super() + @name = name.gsub(/'|"/, "") #' + @top_level = nil + self.comment = comment + end + + def inspect # :nodoc: + "#<%s:0x%x require '%s' in %s>" % [ + self.class, + object_id, + @name, + @parent ? @parent.base_name : '(unknown)' + ] + end + + def to_s # :nodoc: + "require #{name} in: #{parent}" + end + + ## + # The RDoc::TopLevel corresponding to this require, or +nil+ if not found. + + def top_level + @top_level ||= begin + tl = RDoc::TopLevel.all_files_hash[name + '.rb'] + + if tl.nil? and RDoc::TopLevel.all_files.first.full_name =~ %r(^lib/) then + # second chance + tl = RDoc::TopLevel.all_files_hash['lib/' + name + '.rb'] + end + + tl + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/single_class.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/single_class.rb new file mode 100644 index 00000000..88a93a0c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/single_class.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true +## +# A singleton class + +class RDoc::SingleClass < RDoc::ClassModule + + ## + # Adds the superclass to the included modules. + + def ancestors + superclass ? super + [superclass] : super + end + + def aref_prefix # :nodoc: + 'sclass' + end + + ## + # The definition of this singleton class, class << MyClassName + + def definition + "class << #{full_name}" + end + + def pretty_print(q) # :nodoc: + q.group 2, "[class << #{full_name}", "]" do + next + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/top_level.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/top_level.rb new file mode 100644 index 00000000..eeeff026 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_object/top_level.rb @@ -0,0 +1,273 @@ +# frozen_string_literal: true +## +# A TopLevel context is a representation of the contents of a single file + +class RDoc::TopLevel < RDoc::Context + + MARSHAL_VERSION = 0 # :nodoc: + + ## + # Relative name of this file + + attr_accessor :relative_name + + ## + # Absolute name of this file + + attr_accessor :absolute_name + + ## + # All the classes or modules that were declared in + # this file. These are assigned to either +#classes_hash+ + # or +#modules_hash+ once we know what they really are. + + attr_reader :classes_or_modules + + ## + # The parser class that processed this file + + attr_reader :parser + + ## + # Creates a new TopLevel for the file at +absolute_name+. If documentation + # is being generated outside the source dir +relative_name+ is relative to + # the source directory. + + def initialize(absolute_name, relative_name = absolute_name) + super() + @name = nil + @absolute_name = absolute_name + @relative_name = relative_name + @parser = nil + + @classes_or_modules = [] + end + + ## + # Sets the parser for this toplevel context, also the store. + + def parser=(val) + @parser = val + @store.update_parser_of_file(absolute_name, val) if @store + @parser + end + + ## + # An RDoc::TopLevel is equal to another with the same relative_name + + def ==(other) + self.class === other and @relative_name == other.relative_name + end + + alias eql? == + + ## + # Adds +an_alias+ to +Object+ instead of +self+. + + def add_alias(an_alias) + object_class.record_location self + return an_alias unless @document_self + object_class.add_alias an_alias + end + + ## + # Adds +constant+ to +Object+ instead of +self+. + + def add_constant(constant) + object_class.record_location self + return constant unless @document_self + object_class.add_constant constant + end + + ## + # Adds +include+ to +Object+ instead of +self+. + + def add_include(include) + object_class.record_location self + return include unless @document_self + object_class.add_include include + end + + ## + # Adds +method+ to +Object+ instead of +self+. + + def add_method(method) + object_class.record_location self + return method unless @document_self + object_class.add_method method + end + + ## + # Adds class or module +mod+. Used in the building phase + # by the Ruby parser. + + def add_to_classes_or_modules(mod) + @classes_or_modules << mod + end + + ## + # Base name of this file + + def base_name + File.basename @relative_name + end + + alias name base_name + + ## + # Only a TopLevel that contains text file) will be displayed. See also + # RDoc::CodeObject#display? + + def display? + text? and super + end + + ## + # See RDoc::TopLevel::find_class_or_module + #-- + # TODO Why do we search through all classes/modules found, not just the + # ones of this instance? + + def find_class_or_module(name) + @store.find_class_or_module name + end + + ## + # Finds a class or module named +symbol+ + + def find_local_symbol(symbol) + find_class_or_module(symbol) || super + end + + ## + # Finds a module or class with +name+ + + def find_module_named(name) + find_class_or_module(name) + end + + ## + # Returns the relative name of this file + + def full_name + @relative_name + end + + ## + # An RDoc::TopLevel has the same hash as another with the same + # relative_name + + def hash + @relative_name.hash + end + + ## + # URL for this with a +prefix+ + + def http_url + @relative_name.tr('.', '_') + '.html' + end + + def inspect # :nodoc: + "#<%s:0x%x %p modules: %p classes: %p>" % [ + self.class, object_id, + base_name, + @modules.map { |n, m| m }, + @classes.map { |n, c| c } + ] + end + + ## + # Dumps this TopLevel for use by ri. See also #marshal_load + + def marshal_dump + [ + MARSHAL_VERSION, + @relative_name, + @parser, + parse(@comment), + ] + end + + ## + # Loads this TopLevel from +array+. + + def marshal_load(array) # :nodoc: + initialize array[1] + + @parser = array[2] + @comment = RDoc::Comment.from_document array[3] + end + + ## + # Returns the NormalClass "Object", creating it if not found. + # + # Records +self+ as a location in "Object". + + def object_class + @object_class ||= begin + oc = @store.find_class_named('Object') || add_class(RDoc::NormalClass, 'Object') + oc.record_location self + oc + end + end + + ## + # Base name of this file without the extension + + def page_name + basename = File.basename @relative_name + basename =~ /\.(rb|rdoc|txt|md)$/i + + $` || basename + end + + ## + # Path to this file for use with HTML generator output. + + def path + prefix = options.file_path_prefix + return http_url unless prefix + File.join(prefix, http_url) + end + + def pretty_print(q) # :nodoc: + q.group 2, "[#{self.class}: ", "]" do + q.text "base name: #{base_name.inspect}" + q.breakable + + items = @modules.map { |n, m| m } + items.concat @modules.map { |n, c| c } + q.seplist items do |mod| q.pp mod end + end + end + + ## + # Search record used by RDoc::Generator::JsonIndex + + def search_record + return unless @parser < RDoc::Parser::Text + + [ + page_name, + '', + page_name, + '', + path, + '', + snippet(@comment), + ] + end + + ## + # Is this TopLevel from a text file instead of a source code file? + + def text? + @parser and @parser.include? RDoc::Parser::Text + end + + def to_s # :nodoc: + "file #{full_name}" + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_objects.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_objects.rb new file mode 100644 index 00000000..d5f2f920 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/code_objects.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true +# This file was used to load all the RDoc::CodeObject subclasses at once. Now +# autoload handles this. + +require_relative '../rdoc' diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/comment.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/comment.rb new file mode 100644 index 00000000..b269ec48 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/comment.rb @@ -0,0 +1,236 @@ +# frozen_string_literal: true +## +# A comment holds the text comment for a RDoc::CodeObject and provides a +# unified way of cleaning it up and parsing it into an RDoc::Markup::Document. +# +# Each comment may have a different markup format set by #format=. By default +# 'rdoc' is used. The :markup: directive tells RDoc which format to use. +# +# See RDoc::MarkupReference@Directive+for+Specifying+RDoc+Source+Format. + + +class RDoc::Comment + + include RDoc::Text + + ## + # The format of this comment. Defaults to RDoc::Markup + + attr_reader :format + + ## + # The RDoc::TopLevel this comment was found in + + attr_accessor :location + + ## + # Line where this Comment was written + + attr_accessor :line + + ## + # For duck-typing when merging classes at load time + + alias file location # :nodoc: + + ## + # The text for this comment + + attr_reader :text + + ## + # Alias for text + + alias to_s text + + ## + # Overrides the content returned by #parse. Use when there is no #text + # source for this comment + + attr_writer :document + + ## + # Creates a new comment with +text+ that is found in the RDoc::TopLevel + # +location+. + + def initialize(text = nil, location = nil, language = nil) + @location = location + @text = text.nil? ? nil : text.dup + @language = language + + @document = nil + @format = 'rdoc' + @normalized = false + end + + ## + #-- + # TODO deep copy @document + + def initialize_copy(copy) # :nodoc: + @text = copy.text.dup + end + + def ==(other) # :nodoc: + self.class === other and + other.text == @text and other.location == @location + end + + ## + # Look for a 'call-seq' in the comment to override the normal parameter + # handling. The :call-seq: is indented from the baseline. All lines of the + # same indentation level and prefix are consumed. + # + # For example, all of the following will be used as the :call-seq: + # + # # :call-seq: + # # ARGF.readlines(sep=$/) -> array + # # ARGF.readlines(limit) -> array + # # ARGF.readlines(sep, limit) -> array + # # + # # ARGF.to_a(sep=$/) -> array + # # ARGF.to_a(limit) -> array + # # ARGF.to_a(sep, limit) -> array + + def extract_call_seq + # we must handle situations like the above followed by an unindented first + # comment. The difficulty is to make sure not to match lines starting + # with ARGF at the same indent, but that are after the first description + # paragraph. + if /^(? ((?!\n)\s)*+ (?# whitespaces except newline)) + :?call-seq: + (? \g(?\n|\z) (?# trailing spaces))? + (? + (\g(?!\w)\S.*\g)* + (?> + (? \g\w+ (?# ' # ARGF' in the example above)) + .*\g)? + (\g\S.*\g (?# other non-blank line))*+ + (\g+(\k.*\g (?# ARGF.to_a lines))++)*+ + ) + (?m:^\s*$|\z) + /x =~ @text + seq = $~[:seq] + + all_start, all_stop = $~.offset(0) + @text.slice! all_start...all_stop + + seq.gsub!(/^\s*/, '') + end + end + + ## + # A comment is empty if its text String is empty. + + def empty? + @text.empty? && (@document.nil? || @document.empty?) + end + + ## + # HACK dubious + + def encode!(encoding) + @text = String.new @text, encoding: encoding + self + end + + ## + # Sets the format of this comment and resets any parsed document + + def format=(format) + @format = format + @document = nil + end + + def inspect # :nodoc: + location = @location ? @location.relative_name : '(unknown)' + + "#<%s:%x %s %p>" % [self.class, object_id, location, @text] + end + + ## + # Normalizes the text. See RDoc::Text#normalize_comment for details + + def normalize + return self unless @text + return self if @normalized # TODO eliminate duplicate normalization + + @text = normalize_comment @text + + @normalized = true + + self + end + + ## + # Was this text normalized? + + def normalized? # :nodoc: + @normalized + end + + ## + # Parses the comment into an RDoc::Markup::Document. The parsed document is + # cached until the text is changed. + + def parse + return @document if @document + + @document = super @text, @format + @document.file = @location + @document + end + + ## + # Removes private sections from this comment. Private sections are flush to + # the comment marker and start with -- and end with ++. + # For C-style comments, a private marker may not start at the opening of the + # comment. + # + # /* + # *-- + # * private + # *++ + # * public + # */ + + def remove_private + # Workaround for gsub encoding for Ruby 1.9.2 and earlier + empty = '' + empty = RDoc::Encoding.change_encoding empty, @text.encoding + + @text = @text.gsub(%r%^\s*([#*]?)--.*?^\s*(\1)\+\+\n?%m, empty) + @text = @text.sub(%r%^\s*[#*]?--.*%m, '') + end + + ## + # Replaces this comment's text with +text+ and resets the parsed document. + # + # An error is raised if the comment contains a document but no text. + + def text=(text) + raise RDoc::Error, 'replacing document-only comment is not allowed' if + @text.nil? and @document + + @document = nil + @text = text.nil? ? nil : text.dup + end + + ## + # Returns true if this comment is in TomDoc format. + + def tomdoc? + @format == 'tomdoc' + end + + ## + # Create a new parsed comment from a document + + def self.from_document(document) # :nodoc: + comment = RDoc::Comment.new('') + comment.document = document + comment.location = RDoc::TopLevel.new(document.file) if document.file + comment + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/cross_reference.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/cross_reference.rb new file mode 100644 index 00000000..a942d33c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/cross_reference.rb @@ -0,0 +1,228 @@ +# frozen_string_literal: true + +require_relative 'markup/attribute_manager' # for PROTECT_ATTR + +## +# RDoc::CrossReference is a reusable way to create cross references for names. + +class RDoc::CrossReference + + ## + # Regular expression to match class references + # + # 1. There can be a '\\' in front of text to suppress the cross-reference + # 2. There can be a '::' in front of class names to reference from the + # top-level namespace. + # 3. The method can be followed by parenthesis (not recommended) + + CLASS_REGEXP_STR = '\\\\?((?:\:{2})?[A-Z]\w*(?:\:\:\w+)*)' + + ## + # Regular expression to match a single method argument. + + METHOD_ARG_REGEXP_STR = '[\w.+*/=<>-]+' + + ## + # Regular expression to match method arguments. + + METHOD_ARGS_REGEXP_STR = /(?:\((?:#{METHOD_ARG_REGEXP_STR}(?:,\s*#{METHOD_ARG_REGEXP_STR})*)?\))?/.source + + ## + # Regular expression to match method references. + # + # See CLASS_REGEXP_STR + + METHOD_REGEXP_STR = /( + (?!\d)[\w#{RDoc::Markup::AttributeManager::PROTECT_ATTR}]+[!?=]?| + %|=(?:==?|~)|![=~]|\[\]=?|<(?:<|=>?)?|>[>=]?|[-+!]@?|\*\*?|[\/%\`|&^~] + )#{METHOD_ARGS_REGEXP_STR}/.source.delete("\n ").freeze + + ## + # Regular expressions matching text that should potentially have + # cross-reference links generated are passed to add_regexp_handling. Note + # that these expressions are meant to pick up text for which cross-references + # have been suppressed, since the suppression characters are removed by the + # code that is triggered. + + CROSSREF_REGEXP = /(?:^|[\s()]) + ( + (?: + # A::B::C.meth + #{CLASS_REGEXP_STR}(?:[.#]|::)#{METHOD_REGEXP_STR} + + # A::B::C + # The stuff after CLASS_REGEXP_STR is a + # nasty hack. CLASS_REGEXP_STR unfortunately matches + # words like dog and cat (these are legal "class" + # names in Fortran 95). When a word is flagged as a + # potential cross-reference, limitations in the markup + # engine suppress other processing, such as typesetting. + # This is particularly noticeable for contractions. + # In order that words like "can't" not + # be flagged as potential cross-references, only + # flag potential class cross-references if the character + # after the cross-reference is a space, sentence + # punctuation, tag start character, or attribute + # marker. + | #{CLASS_REGEXP_STR}(?=[@\s).?!,;<\000]|\z) + + # Stand-alone method (preceded by a #) + | \\?\##{METHOD_REGEXP_STR} + + # Stand-alone method (preceded by ::) + | ::#{METHOD_REGEXP_STR} + + # Things that look like filenames + # The key thing is that there must be at least + # one special character (period, slash, or + # underscore). + | (?:\.\.\/)*[-\/\w]+[_\/.][-\w\/.]+ + + # Things that have markup suppressed + # Don't process things like '\<' in \, though. + # TODO: including < is a hack, not very satisfying. + | \\[^\s<] + ) + + # labels for headings + (?:@[\w+%-]+(?:\.[\w|%-]+)?)? + )/x + + ## + # Version of CROSSREF_REGEXP used when --hyperlink-all is specified. + + ALL_CROSSREF_REGEXP = / + (?:^|[\s()]) + ( + (?: + # A::B::C.meth + #{CLASS_REGEXP_STR}(?:[.#]|::)#{METHOD_REGEXP_STR} + + # A::B::C + | #{CLASS_REGEXP_STR}(?=[@\s).?!,;<\000]|\z) + + # Stand-alone method + | \\?#{METHOD_REGEXP_STR} + + # Things that look like filenames + | (?:\.\.\/)*[-\/\w]+[_\/.][-\w\/.]+ + + # Things that have markup suppressed + | \\[^\s<] + ) + + # labels for headings + (?:@[\w+%-]+)? + )/x + + ## + # Hash of references that have been looked-up to their replacements + + attr_accessor :seen + + ## + # Allows cross-references to be created based on the given +context+ + # (RDoc::Context). + + def initialize(context) + @context = context + @store = context.store + + @seen = {} + end + + ## + # Returns a method reference to +name+. + + def resolve_method(name) + ref = nil + + if /#{CLASS_REGEXP_STR}([.#]|::)#{METHOD_REGEXP_STR}/o =~ name then + type = $2 + if '.' == type # will find either #method or ::method + method = $3 + else + method = "#{type}#{$3}" + end + container = @context.find_symbol_module($1) + elsif /^([.#]|::)#{METHOD_REGEXP_STR}/o =~ name then + type = $1 + if '.' == type + method = $2 + else + method = "#{type}#{$2}" + end + container = @context + else + type = nil + container = nil + end + + if container then + unless RDoc::TopLevel === container then + if '.' == type then + if 'new' == method then # AnyClassName.new will be class method + ref = container.find_local_symbol method + ref = container.find_ancestor_local_symbol method unless ref + else + ref = container.find_local_symbol "::#{method}" + ref = container.find_ancestor_local_symbol "::#{method}" unless ref + ref = container.find_local_symbol "##{method}" unless ref + ref = container.find_ancestor_local_symbol "##{method}" unless ref + end + else + ref = container.find_local_symbol method + ref = container.find_ancestor_local_symbol method unless ref + end + end + end + + ref + end + + ## + # Returns a reference to +name+. + # + # If the reference is found and +name+ is not documented +text+ will be + # returned. If +name+ is escaped +name+ is returned. If +name+ is not + # found +text+ is returned. + + def resolve(name, text) + return @seen[name] if @seen.include? name + + ref = case name + when /^\\(#{CLASS_REGEXP_STR})$/o then + @context.find_symbol $1 + else + @context.find_symbol name + end + + ref = resolve_method name unless ref + + # Try a page name + ref = @store.page name if not ref and name =~ /^[\w.]+$/ + + ref = nil if RDoc::Alias === ref # external alias, can't link to it + + out = if name == '\\' then + name + elsif name =~ /^\\/ then + # we remove the \ only in front of what we know: + # other backslashes are treated later, only outside of + ref ? $' : name + elsif ref then + if ref.display? then + ref + else + text + end + else + text + end + + @seen[name] = out + + out + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/encoding.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/encoding.rb new file mode 100644 index 00000000..78dbe87d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/encoding.rb @@ -0,0 +1,120 @@ +# coding: US-ASCII +# frozen_string_literal: true + +## +# This class is a wrapper around File IO and Encoding that helps RDoc load +# files and convert them to the correct encoding. + +module RDoc::Encoding + + HEADER_REGEXP = /^ + (?: + \A\#!.*\n + | + ^\#\s+frozen[-_]string[-_]literal[=:].+\n + | + ^\#[^\n]+\b(?:en)?coding[=:]\s*(?[^\s;]+).*\n + | + <\?xml[^?]*encoding=(?["'])(?.*?)\k.*\n + )+ + /xi # :nodoc: + + ## + # Reads the contents of +filename+ and handles any encoding directives in + # the file. + # + # The content will be converted to the +encoding+. If the file cannot be + # converted a warning will be printed and nil will be returned. + # + # If +force_transcode+ is true the document will be transcoded and any + # unknown character in the target encoding will be replaced with '?' + + def self.read_file(filename, encoding, force_transcode = false) + content = File.open filename, "rb" do |f| f.read end + content.gsub!("\r\n", "\n") if RUBY_PLATFORM =~ /mswin|mingw/ + + utf8 = content.sub!(/\A\xef\xbb\xbf/, '') + + enc = RDoc::Encoding.detect_encoding content + content = RDoc::Encoding.change_encoding content, enc if enc + + begin + encoding ||= Encoding.default_external + orig_encoding = content.encoding + + if not orig_encoding.ascii_compatible? then + content = content.encode encoding + elsif utf8 then + content = RDoc::Encoding.change_encoding content, Encoding::UTF_8 + content = content.encode encoding + else + # assume the content is in our output encoding + content = RDoc::Encoding.change_encoding content, encoding + end + + unless content.valid_encoding? then + # revert and try to transcode + content = RDoc::Encoding.change_encoding content, orig_encoding + content = content.encode encoding + end + + unless content.valid_encoding? then + warn "unable to convert #{filename} to #{encoding}, skipping" + content = nil + end + rescue Encoding::InvalidByteSequenceError, + Encoding::UndefinedConversionError => e + if force_transcode then + content = RDoc::Encoding.change_encoding content, orig_encoding + content = content.encode(encoding, + :invalid => :replace, + :undef => :replace, + :replace => '?') + return content + else + warn "unable to convert #{e.message} for #{filename}, skipping" + return nil + end + end + + content + rescue ArgumentError => e + raise unless e.message =~ /unknown encoding name - (.*)/ + warn "unknown encoding name \"#{$1}\" for #{filename}, skipping" + nil + rescue Errno::EISDIR, Errno::ENOENT + nil + end + + ## + # Detects the encoding of +string+ based on the magic comment + + def self.detect_encoding(string) + result = HEADER_REGEXP.match string + name = result && result[:name] + + name ? Encoding.find(name) : nil + end + + ## + # Removes magic comments and shebang + + def self.remove_magic_comment(string) + string.sub HEADER_REGEXP do |s| + s.gsub(/[^\n]/, '') + end + end + + ## + # Changes encoding based on +encoding+ without converting and returns new + # string + + def self.change_encoding(text, encoding) + if text.kind_of? RDoc::Comment + text.encode! encoding + else + String.new text, encoding: encoding + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/erb_partial.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/erb_partial.rb new file mode 100644 index 00000000..bad02ea7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/erb_partial.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true +## +# Allows an ERB template to be rendered in the context (binding) of an +# existing ERB template evaluation. + +class RDoc::ERBPartial < ERB + + ## + # Overrides +compiler+ startup to set the +eoutvar+ to an empty string only + # if it isn't already set. + + def set_eoutvar(compiler, eoutvar = '_erbout') + super + + compiler.pre_cmd = ["#{eoutvar} ||= +''"] + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/erbio.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/erbio.rb new file mode 100644 index 00000000..e955eed8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/erbio.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true +require 'erb' + +## +# A subclass of ERB that writes directly to an IO. Credit to Aaron Patterson +# and Masatoshi SEKI. +# +# To use: +# +# erbio = RDoc::ERBIO.new '<%= "hello world" %>', nil, nil +# +# File.open 'hello.txt', 'w' do |io| +# erbio.result binding +# end +# +# Note that binding must enclose the io you wish to output on. + +class RDoc::ERBIO < ERB + + ## + # Defaults +eoutvar+ to 'io', otherwise is identical to ERB's initialize + + def initialize(str, trim_mode: nil, eoutvar: 'io') + super(str, trim_mode: trim_mode, eoutvar: eoutvar) + end + + ## + # Instructs +compiler+ how to write to +io_variable+ + + def set_eoutvar(compiler, io_variable) + compiler.put_cmd = "#{io_variable}.write" + compiler.insert_cmd = "#{io_variable}.write" + compiler.pre_cmd = [] + compiler.post_cmd = [] + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator.rb new file mode 100644 index 00000000..a769cf8a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true +## +# RDoc uses generators to turn parsed source code in the form of an +# RDoc::CodeObject tree into some form of output. RDoc comes with the HTML +# generator RDoc::Generator::Darkfish and an ri data generator +# RDoc::Generator::RI. +# +# == Registering a Generator +# +# Generators are registered by calling RDoc::RDoc.add_generator with the class +# of the generator: +# +# class My::Awesome::Generator +# RDoc::RDoc.add_generator self +# end +# +# == Adding Options to +rdoc+ +# +# Before option processing in +rdoc+, RDoc::Options will call ::setup_options +# on the generator class with an RDoc::Options instance. The generator can +# use RDoc::Options#option_parser to add command-line options to the +rdoc+ +# tool. See RDoc::Options@Custom+Options for an example and see OptionParser +# for details on how to add options. +# +# You can extend the RDoc::Options instance with additional accessors for your +# generator. +# +# == Generator Instantiation +# +# After parsing, RDoc::RDoc will instantiate a generator by calling +# #initialize with an RDoc::Store instance and an RDoc::Options instance. +# +# The RDoc::Store instance holds documentation for parsed source code. In +# RDoc 3 and earlier the RDoc::TopLevel class held this data. When upgrading +# a generator from RDoc 3 and earlier you should only need to replace +# RDoc::TopLevel with the store instance. +# +# RDoc will then call #generate on the generator instance. You can use the +# various methods on RDoc::Store and in the RDoc::CodeObject tree to create +# your desired output format. + +module RDoc::Generator + + autoload :Markup, "#{__dir__}/generator/markup" + + autoload :Darkfish, "#{__dir__}/generator/darkfish" + autoload :JsonIndex, "#{__dir__}/generator/json_index" + autoload :RI, "#{__dir__}/generator/ri" + autoload :POT, "#{__dir__}/generator/pot" + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/darkfish.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/darkfish.rb new file mode 100644 index 00000000..7fec3650 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/darkfish.rb @@ -0,0 +1,812 @@ +# frozen_string_literal: true +# -*- mode: ruby; ruby-indent-level: 2; tab-width: 2 -*- + +require 'erb' +require 'fileutils' +require 'pathname' +require_relative 'markup' + +## +# Darkfish RDoc HTML Generator +# +# $Id: darkfish.rb 52 2009-01-07 02:08:11Z deveiant $ +# +# == Author/s +# * Michael Granger (ged@FaerieMUD.org) +# +# == Contributors +# * Mahlon E. Smith (mahlon@martini.nu) +# * Eric Hodel (drbrain@segment7.net) +# +# == License +# +# Copyright (c) 2007, 2008, Michael Granger. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# * Neither the name of the author/s, nor the names of the project's +# contributors may be used to endorse or promote products derived from this +# software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# == Attributions +# +# Darkfish uses the {Silk Icons}[http://www.famfamfam.com/lab/icons/silk/] set +# by Mark James. + +class RDoc::Generator::Darkfish + + RDoc::RDoc.add_generator self + + include ERB::Util + + ## + # Stylesheets, fonts, etc. that are included in RDoc. + + BUILTIN_STYLE_ITEMS = # :nodoc: + %w[ + css/fonts.css + fonts/Lato-Light.ttf + fonts/Lato-LightItalic.ttf + fonts/Lato-Regular.ttf + fonts/Lato-RegularItalic.ttf + fonts/SourceCodePro-Bold.ttf + fonts/SourceCodePro-Regular.ttf + css/rdoc.css + ] + + ## + # Release Version + + VERSION = '3' + + ## + # Description of this generator + + DESCRIPTION = 'HTML generator, written by Michael Granger' + + ## + # The relative path to style sheets and javascript. By default this is set + # the same as the rel_prefix. + + attr_accessor :asset_rel_path + + ## + # The path to generate files into, combined with --op from the + # options for a full path. + + attr_reader :base_dir + + ## + # Classes and modules to be used by this generator, not necessarily + # displayed. See also #modsort + + attr_reader :classes + + ## + # No files will be written when dry_run is true. + + attr_accessor :dry_run + + ## + # When false the generate methods return a String instead of writing to a + # file. The default is true. + + attr_accessor :file_output + + ## + # Files to be displayed by this generator + + attr_reader :files + + ## + # The JSON index generator for this Darkfish generator + + attr_reader :json_index + + ## + # Methods to be displayed by this generator + + attr_reader :methods + + ## + # Sorted list of classes and modules to be displayed by this generator + + attr_reader :modsort + + ## + # The RDoc::Store that is the source of the generated content + + attr_reader :store + + ## + # The directory where the template files live + + attr_reader :template_dir # :nodoc: + + ## + # The output directory + + attr_reader :outputdir + + ## + # Initialize a few instance variables before we start + + def initialize(store, options) + @store = store + @options = options + + @asset_rel_path = '' + @base_dir = Pathname.pwd.expand_path + @dry_run = @options.dry_run + @file_output = true + @template_dir = Pathname.new options.template_dir + @template_cache = {} + + @classes = nil + @context = nil + @files = nil + @methods = nil + @modsort = nil + + @json_index = RDoc::Generator::JsonIndex.new self, options + end + + ## + # Output progress information if debugging is enabled + + def debug_msg *msg + return unless $DEBUG_RDOC + $stderr.puts(*msg) + end + + ## + # Create the directories the generated docs will live in if they don't + # already exist. + + def gen_sub_directories + @outputdir.mkpath + end + + ## + # Copy over the stylesheet into the appropriate place in the output + # directory. + + def write_style_sheet + debug_msg "Copying static files" + options = { :verbose => $DEBUG_RDOC, :noop => @dry_run } + + BUILTIN_STYLE_ITEMS.each do |item| + install_rdoc_static_file @template_dir + item, "./#{item}", options + end + + unless @options.template_stylesheets.empty? + FileUtils.cp @options.template_stylesheets, '.', **options + end + + Dir[(@template_dir + "{js,images}/**/*").to_s].each do |path| + next if File.directory? path + next if File.basename(path) =~ /^\./ + + dst = Pathname.new(path).relative_path_from @template_dir + + install_rdoc_static_file @template_dir + path, dst, options + end + end + + ## + # Build the initial indices and output objects based on an array of TopLevel + # objects containing the extracted information. + + def generate + setup + + write_style_sheet + generate_index + generate_class_files + generate_file_files + generate_table_of_contents + @json_index.generate + @json_index.generate_gzipped + + copy_static + + rescue => e + debug_msg "%s: %s\n %s" % [ + e.class.name, e.message, e.backtrace.join("\n ") + ] + + raise + end + + ## + # Copies static files from the static_path into the output directory + + def copy_static + return if @options.static_path.empty? + + fu_options = { :verbose => $DEBUG_RDOC, :noop => @dry_run } + + @options.static_path.each do |path| + unless File.directory? path then + FileUtils.install path, @outputdir, **fu_options.merge(:mode => 0644) + next + end + + Dir.chdir path do + Dir[File.join('**', '*')].each do |entry| + dest_file = @outputdir + entry + + if File.directory? entry then + FileUtils.mkdir_p entry, **fu_options + else + FileUtils.install entry, dest_file, **fu_options.merge(:mode => 0644) + end + end + end + end + end + + ## + # Return a list of the documented modules sorted by salience first, then + # by name. + + def get_sorted_module_list(classes) + classes.select do |klass| + klass.display? + end.sort + end + + ## + # Generate an index page which lists all the classes which are documented. + + def generate_index + template_file = @template_dir + 'index.rhtml' + return unless template_file.exist? + + debug_msg "Rendering the index page..." + + out_file = @base_dir + @options.op_dir + 'index.html' + rel_prefix = @outputdir.relative_path_from out_file.dirname + search_index_rel_prefix = rel_prefix + search_index_rel_prefix += @asset_rel_path if @file_output + + asset_rel_prefix = rel_prefix + @asset_rel_path + + @title = @options.title + @main_page = @files.find { |f| f.full_name == @options.main_page } + + render_template template_file, out_file do |io| + here = binding + # suppress 1.9.3 warning + here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) + # some partials rely on the presence of current variable to render + here.local_variable_set(:current, @main_page) if @main_page + here + end + rescue => e + error = RDoc::Error.new \ + "error generating index.html: #{e.message} (#{e.class})" + error.set_backtrace e.backtrace + + raise error + end + + ## + # Generates a class file for +klass+ + + def generate_class(klass, template_file = nil) + current = klass + + template_file ||= @template_dir + 'class.rhtml' + + debug_msg " working on %s (%s)" % [klass.full_name, klass.path] + out_file = @outputdir + klass.path + rel_prefix = @outputdir.relative_path_from out_file.dirname + search_index_rel_prefix = rel_prefix + search_index_rel_prefix += @asset_rel_path if @file_output + + asset_rel_prefix = rel_prefix + @asset_rel_path + + breadcrumb = # used in templates + breadcrumb = generate_nesting_namespaces_breadcrumb(current, rel_prefix) + + @title = "#{klass.type} #{klass.full_name} - #{@options.title}" + + debug_msg " rendering #{out_file}" + render_template template_file, out_file do |io| + here = binding + # suppress 1.9.3 warning + here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) + here + end + end + + ## + # Generate a documentation file for each class and module + + def generate_class_files + template_file = @template_dir + 'class.rhtml' + template_file = @template_dir + 'classpage.rhtml' unless + template_file.exist? + return unless template_file.exist? + debug_msg "Generating class documentation in #{@outputdir}" + + current = nil + + @classes.each do |klass| + current = klass + + generate_class klass, template_file + end + rescue => e + error = RDoc::Error.new \ + "error generating #{current.path}: #{e.message} (#{e.class})" + error.set_backtrace e.backtrace + + raise error + end + + ## + # Generate a documentation file for each file + + def generate_file_files + page_file = @template_dir + 'page.rhtml' + fileinfo_file = @template_dir + 'fileinfo.rhtml' + + # for legacy templates + filepage_file = @template_dir + 'filepage.rhtml' unless + page_file.exist? or fileinfo_file.exist? + + return unless + page_file.exist? or fileinfo_file.exist? or filepage_file.exist? + + debug_msg "Generating file documentation in #{@outputdir}" + + out_file = nil + current = nil + + @files.each do |file| + current = file + + if file.text? and page_file.exist? then + generate_page file + next + end + + template_file = nil + out_file = @outputdir + file.path + debug_msg " working on %s (%s)" % [file.full_name, out_file] + rel_prefix = @outputdir.relative_path_from out_file.dirname + search_index_rel_prefix = rel_prefix + search_index_rel_prefix += @asset_rel_path if @file_output + + asset_rel_prefix = rel_prefix + @asset_rel_path + + unless filepage_file then + if file.text? then + next unless page_file.exist? + template_file = page_file + @title = file.page_name + else + next unless fileinfo_file.exist? + template_file = fileinfo_file + @title = "File: #{file.base_name}" + end + end + + @title += " - #{@options.title}" + template_file ||= filepage_file + + render_template template_file, out_file do |io| + here = binding + # suppress 1.9.3 warning + here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) + here.local_variable_set(:current, current) + here + end + end + rescue => e + error = + RDoc::Error.new "error generating #{out_file}: #{e.message} (#{e.class})" + error.set_backtrace e.backtrace + + raise error + end + + ## + # Generate a page file for +file+ + + def generate_page(file) + template_file = @template_dir + 'page.rhtml' + + out_file = @outputdir + file.path + debug_msg " working on %s (%s)" % [file.full_name, out_file] + rel_prefix = @outputdir.relative_path_from out_file.dirname + search_index_rel_prefix = rel_prefix + search_index_rel_prefix += @asset_rel_path if @file_output + + current = file + asset_rel_prefix = rel_prefix + @asset_rel_path + + @title = "#{file.page_name} - #{@options.title}" + + debug_msg " rendering #{out_file}" + render_template template_file, out_file do |io| + here = binding + # suppress 1.9.3 warning + here.local_variable_set(:current, current) + here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) + here + end + end + + ## + # Generates the 404 page for the RDoc servlet + + def generate_servlet_not_found(message) + template_file = @template_dir + 'servlet_not_found.rhtml' + return unless template_file.exist? + + debug_msg "Rendering the servlet 404 Not Found page..." + + rel_prefix = rel_prefix = '' + search_index_rel_prefix = rel_prefix + search_index_rel_prefix += @asset_rel_path if @file_output + + asset_rel_prefix = '' + + @title = 'Not Found' + + render_template template_file do |io| + here = binding + # suppress 1.9.3 warning + here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) + here + end + rescue => e + error = RDoc::Error.new \ + "error generating servlet_not_found: #{e.message} (#{e.class})" + error.set_backtrace e.backtrace + + raise error + end + + ## + # Generates the servlet root page for the RDoc servlet + + def generate_servlet_root(installed) + template_file = @template_dir + 'servlet_root.rhtml' + return unless template_file.exist? + + debug_msg 'Rendering the servlet root page...' + + rel_prefix = '.' + asset_rel_prefix = rel_prefix + search_index_rel_prefix = asset_rel_prefix + search_index_rel_prefix += @asset_rel_path if @file_output + + @title = 'Local RDoc Documentation' + + render_template template_file do |io| binding end + rescue => e + error = RDoc::Error.new \ + "error generating servlet_root: #{e.message} (#{e.class})" + error.set_backtrace e.backtrace + + raise error + end + + ## + # Generate an index page which lists all the classes which are documented. + + def generate_table_of_contents + template_file = @template_dir + 'table_of_contents.rhtml' + return unless template_file.exist? + + debug_msg "Rendering the Table of Contents..." + + out_file = @outputdir + 'table_of_contents.html' + rel_prefix = @outputdir.relative_path_from out_file.dirname + search_index_rel_prefix = rel_prefix + search_index_rel_prefix += @asset_rel_path if @file_output + + asset_rel_prefix = rel_prefix + @asset_rel_path + + @title = "Table of Contents - #{@options.title}" + + render_template template_file, out_file do |io| + here = binding + # suppress 1.9.3 warning + here.local_variable_set(:asset_rel_prefix, asset_rel_prefix) + here + end + rescue => e + error = RDoc::Error.new \ + "error generating table_of_contents.html: #{e.message} (#{e.class})" + error.set_backtrace e.backtrace + + raise error + end + + def install_rdoc_static_file(source, destination, options) # :nodoc: + return unless source.exist? + + begin + FileUtils.mkdir_p File.dirname(destination), **options + + begin + FileUtils.ln source, destination, **options + rescue Errno::EEXIST + FileUtils.rm destination + retry + end + rescue + FileUtils.cp source, destination, **options + end + end + + ## + # Prepares for generation of output from the current directory + + def setup + return if instance_variable_defined? :@outputdir + + @outputdir = Pathname.new(@options.op_dir).expand_path @base_dir + + return unless @store + + @classes = @store.all_classes_and_modules.sort + @files = @store.all_files.sort + @methods = @classes.flat_map { |m| m.method_list }.sort + @modsort = get_sorted_module_list @classes + end + + ## + # Creates a template from its components and the +body_file+. + # + # For backwards compatibility, if +body_file+ contains " + + + +#{head_file.read} + +#{body} + TEMPLATE + end + + ## + # Renders the ERb contained in +file_name+ relative to the template + # directory and returns the result based on the current context. + + def render(file_name) + template_file = @template_dir + file_name + + template = template_for template_file, false, RDoc::ERBPartial + + template.filename = template_file.to_s + + template.result @context + end + + ## + # Load and render the erb template in the given +template_file+ and write + # it out to +out_file+. + # + # Both +template_file+ and +out_file+ should be Pathname-like objects. + # + # An io will be yielded which must be captured by binding in the caller. + + def render_template(template_file, out_file = nil) # :yield: io + io_output = out_file && !@dry_run && @file_output + erb_klass = io_output ? RDoc::ERBIO : ERB + + template = template_for template_file, true, erb_klass + + if io_output then + debug_msg "Outputting to %s" % [out_file.expand_path] + + out_file.dirname.mkpath + out_file.open 'w', 0644 do |io| + io.set_encoding @options.encoding + + @context = yield io + + template_result template, @context, template_file + end + else + @context = yield nil + + output = template_result template, @context, template_file + + debug_msg " would have written %d characters to %s" % [ + output.length, out_file.expand_path + ] if @dry_run + + output + end + end + + ## + # Creates the result for +template+ with +context+. If an error is raised a + # Pathname +template_file+ will indicate the file where the error occurred. + + def template_result(template, context, template_file) + template.filename = template_file.to_s + template.result context + rescue NoMethodError => e + raise RDoc::Error, "Error while evaluating %s: %s" % [ + template_file.expand_path, + e.message, + ], e.backtrace + end + + ## + # Retrieves a cache template for +file+, if present, or fills the cache. + + def template_for(file, page = true, klass = ERB) + template = @template_cache[file] + + return template if template + + if page then + template = assemble_template file + erbout = 'io' + else + template = file.read + template = template.encode @options.encoding + + file_var = File.basename(file).sub(/\..*/, '') + + erbout = "_erbout_#{file_var}" + end + + template = klass.new template, trim_mode: '-', eoutvar: erbout + @template_cache[file] = template + template + end + + # :stopdoc: + ParagraphExcerptRegexpOther = %r[\b\w[^./:]++\.] + # use \p/\P{letter} instead of \w/\W in Unicode + ParagraphExcerptRegexpUnicode = %r[\b\p{letter}[^./:]++\.] + # :startdoc: + + # Returns an excerpt of the comment for usage in meta description tags + def excerpt(comment) + text = case comment + when RDoc::Comment + comment.text + else + comment + end + + # Match from a capital letter to the first period, discarding any links, so + # that we don't end up matching badges in the README + pattern = ParagraphExcerptRegexpUnicode + begin + first_paragraph_match = text.match(pattern) + rescue Encoding::CompatibilityError + # The doc is non-ASCII text and encoded in other than Unicode base encodings. + raise if pattern == ParagraphExcerptRegexpOther + pattern = ParagraphExcerptRegexpOther + retry + end + return text[0...150].tr_s("\n", " ").squeeze(" ") unless first_paragraph_match + + extracted_text = first_paragraph_match[0] + second_paragraph = text.match(pattern, first_paragraph_match.end(0)) + extracted_text << " " << second_paragraph[0] if second_paragraph + + extracted_text[0...150].tr_s("\n", " ").squeeze(" ") + end + + def generate_ancestor_list(ancestors, klass) + return '' if ancestors.empty? + + ancestor = ancestors.shift + content = +'
  • ' + + if ancestor.is_a?(RDoc::NormalClass) + content << "#{ancestor.full_name}" + else + content << ancestor.to_s + end + + # Recursively call the method for the remaining ancestors + content << generate_ancestor_list(ancestors, klass) + + content << '
' + end + + def generate_class_link(klass, rel_prefix) + if klass.display? + %(#{klass.name}) + else + %(#{klass.name}) + end + end + + def generate_class_index_content(classes, rel_prefix) + grouped_classes = group_classes_by_namespace_for_sidebar(classes) + return '' unless top = grouped_classes[nil] + + solo = top.one? { |klass| klass.display? } + traverse_classes(top, grouped_classes, rel_prefix, solo) + end + + def traverse_classes(klasses, grouped_classes, rel_prefix, solo = false) + content = +'" + end + + def group_classes_by_namespace_for_sidebar(classes) + grouped_classes = classes.group_by do |klass| + klass.full_name[/\A[^:]++(?:::[^:]++(?=::))*+(?=::[^:]*+\z)/] + end.select do |_, klasses| + klasses.any?(&:display?) + end + + grouped_classes.values.each(&:uniq!) + grouped_classes + end + + private + + def nesting_namespaces_to_class_modules(klass) + tree = {} + + klass.nesting_namespaces.zip(klass.fully_qualified_nesting_namespaces) do |ns, fqns| + tree[ns] = @store.classes_hash[fqns] || @store.modules_hash[fqns] + end + + tree + end + + def generate_nesting_namespaces_breadcrumb(klass, rel_prefix) + nesting_namespaces_to_class_modules(klass).map do |namespace, class_module| + path = class_module ? (rel_prefix + class_module.path).to_s : "" + { name: namespace, path: path, self: klass.full_name == class_module&.full_name } + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/json_index.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/json_index.rb new file mode 100644 index 00000000..065caa47 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/json_index.rb @@ -0,0 +1,284 @@ +# frozen_string_literal: true +require 'json' +begin + require 'zlib' +rescue LoadError +end + +## +# The JsonIndex generator is designed to complement an HTML generator and +# produces a JSON search index. This generator is derived from sdoc by +# Vladimir Kolesnikov and contains verbatim code written by him. +# +# This generator is designed to be used with a regular HTML generator: +# +# class RDoc::Generator::Darkfish +# def initialize options +# # ... +# @base_dir = Pathname.pwd.expand_path +# +# @json_index = RDoc::Generator::JsonIndex.new self, options +# end +# +# def generate +# # ... +# @json_index.generate +# end +# end +# +# == Index Format +# +# The index is output as a JSON file assigned to the global variable +# +search_data+. The structure is: +# +# var search_data = { +# "index": { +# "searchIndex": +# ["a", "b", ...], +# "longSearchIndex": +# ["a", "a::b", ...], +# "info": [ +# ["A", "A", "A.html", "", ""], +# ["B", "A::B", "A::B.html", "", ""], +# ... +# ] +# } +# } +# +# The same item is described across the +searchIndex+, +longSearchIndex+ and +# +info+ fields. The +searchIndex+ field contains the item's short name, the +# +longSearchIndex+ field contains the full_name (when appropriate) and the +# +info+ field contains the item's name, full_name, path, parameters and a +# snippet of the item's comment. +# +# == LICENSE +# +# Copyright (c) 2009 Vladimir Kolesnikov +# +# 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 AUTHORS OR COPYRIGHT HOLDERS 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. + +class RDoc::Generator::JsonIndex + + include RDoc::Text + + ## + # Where the search index lives in the generated output + + SEARCH_INDEX_FILE = File.join 'js', 'search_index.js' + + attr_reader :index # :nodoc: + + ## + # Creates a new generator. + # +options+ are the same options passed to the parent generator. + + def initialize(parent_generator, options) + @parent_generator = parent_generator + @store = parent_generator.store + @options = options + + @template_dir = File.expand_path '../template/json_index', __FILE__ + @base_dir = @parent_generator.base_dir + + @classes = nil + @files = nil + @index = nil + end + + ## + # Builds the JSON index as a Hash. + + def build_index + reset @store.all_files.sort, @store.all_classes_and_modules.sort + + index_classes + index_methods + index_pages + + { :index => @index } + end + + ## + # Output progress information if debugging is enabled + + def debug_msg *msg + return unless $DEBUG_RDOC + $stderr.puts(*msg) + end + + ## + # Writes the JSON index to disk + + def generate + debug_msg "Generating JSON index" + + debug_msg " writing search index to %s" % SEARCH_INDEX_FILE + data = build_index + + return if @options.dry_run + + out_dir = @base_dir + @options.op_dir + index_file = out_dir + SEARCH_INDEX_FILE + + FileUtils.mkdir_p index_file.dirname, :verbose => $DEBUG_RDOC + + index_file.open 'w', 0644 do |io| + io.set_encoding Encoding::UTF_8 + io.write 'var search_data = ' + + JSON.dump data, io, 0 + end + unless ENV['SOURCE_DATE_EPOCH'].nil? + index_file.utime index_file.atime, Time.at(ENV['SOURCE_DATE_EPOCH'].to_i).gmtime + end + + Dir.chdir @template_dir do + Dir['**/*.js'].each do |source| + dest = File.join out_dir, source + + FileUtils.install source, dest, :mode => 0644, :preserve => true, :verbose => $DEBUG_RDOC + end + end + end + + ## + # Compress the search_index.js file using gzip + + def generate_gzipped + return if @options.dry_run or not defined?(Zlib) + + debug_msg "Compressing generated JSON index" + out_dir = @base_dir + @options.op_dir + + search_index_file = out_dir + SEARCH_INDEX_FILE + outfile = out_dir + "#{search_index_file}.gz" + + debug_msg "Reading the JSON index file from %s" % search_index_file + search_index = search_index_file.read(mode: 'r:utf-8') + + debug_msg "Writing gzipped search index to %s" % outfile + + Zlib::GzipWriter.open(outfile) do |gz| + gz.mtime = File.mtime(search_index_file) + gz.orig_name = search_index_file.basename.to_s + gz.write search_index + gz.close + end + + # GZip the rest of the js files + Dir.chdir @template_dir do + Dir['**/*.js'].each do |source| + dest = out_dir + source + outfile = out_dir + "#{dest}.gz" + + debug_msg "Reading the original js file from %s" % dest + data = dest.read + + debug_msg "Writing gzipped file to %s" % outfile + + Zlib::GzipWriter.open(outfile) do |gz| + gz.mtime = File.mtime(dest) + gz.orig_name = dest.basename.to_s + gz.write data + gz.close + end + end + end + end + + ## + # Adds classes and modules to the index + + def index_classes + debug_msg " generating class search index" + + documented = @classes.uniq.select do |klass| + klass.document_self_or_methods + end + + documented.each do |klass| + debug_msg " #{klass.full_name}" + record = klass.search_record + @index[:searchIndex] << search_string(record.shift) + @index[:longSearchIndex] << search_string(record.shift) + @index[:info] << record + end + end + + ## + # Adds methods to the index + + def index_methods + debug_msg " generating method search index" + + list = @classes.uniq.flat_map do |klass| + klass.method_list + end.sort_by do |method| + [method.name, method.parent.full_name] + end + + list.each do |method| + debug_msg " #{method.full_name}" + record = method.search_record + @index[:searchIndex] << "#{search_string record.shift}()" + @index[:longSearchIndex] << "#{search_string record.shift}()" + @index[:info] << record + end + end + + ## + # Adds pages to the index + + def index_pages + debug_msg " generating pages search index" + + pages = @files.select do |file| + file.text? + end + + pages.each do |page| + debug_msg " #{page.page_name}" + record = page.search_record + @index[:searchIndex] << search_string(record.shift) + @index[:longSearchIndex] << '' + record.shift + @index[:info] << record + end + end + + def reset(files, classes) # :nodoc: + @files = files + @classes = classes + + @index = { + :searchIndex => [], + :longSearchIndex => [], + :info => [] + } + end + + ## + # Removes whitespace and downcases +string+ + + def search_string(string) + string.downcase.gsub(/\s/, '') + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/markup.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/markup.rb new file mode 100644 index 00000000..1c396870 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/markup.rb @@ -0,0 +1,171 @@ +# frozen_string_literal: true +## +# Handle common RDoc::Markup tasks for various CodeObjects +# +# This module is loaded by generators. It allows RDoc's CodeObject tree to +# avoid loading generator code to improve startup time for +ri+. + +module RDoc::Generator::Markup + + ## + # Generates a relative URL from this object's path to +target_path+ + + def aref_to(target_path) + RDoc::Markup::ToHtml.gen_relative_url path, target_path + end + + ## + # Generates a relative URL from +from_path+ to this object's path + + def as_href(from_path) + RDoc::Markup::ToHtml.gen_relative_url from_path, path + end + + ## + # Handy wrapper for marking up this object's comment + + def description + markup @comment + end + + ## + # Creates an RDoc::Markup::ToHtmlCrossref formatter + + def formatter + return @formatter if defined? @formatter + + options = @store.options + this = RDoc::Context === self ? self : @parent + + @formatter = RDoc::Markup::ToHtmlCrossref.new options, this.path, this + @formatter.code_object = self + @formatter + end + + ## + # Build a webcvs URL starting for the given +url+ with +full_path+ appended + # as the destination path. If +url+ contains '%s' +full_path+ will be + # will replace the %s using sprintf on the +url+. + + def cvs_url(url, full_path) + if /%s/ =~ url then + sprintf url, full_path + else + url + full_path + end + end + + ## + # The preferred URL for this object. + + def canonical_url + options = @store.options + if path + File.join(options.canonical_root, path.to_s) + else + options.canonical_root + end + end + +end + +class RDoc::CodeObject + + include RDoc::Generator::Markup + +end + +class RDoc::MethodAttr + + ## + # Prepend +src+ with line numbers. Relies on the first line of a source + # code listing having: + # + # # File xxxxx, line dddd + # + # If it has this comment then line numbers are added to +src+ and the , + # line dddd portion of the comment is removed. + + def add_line_numbers(src) + return unless src.sub!(/\A(.*)(, line (\d+))/, '\1') + first = $3.to_i - 1 + last = first + src.count("\n") + size = last.to_s.length + + line = first + src.gsub!(/^/) do + res = if line == first then + " " * (size + 1) + else + "%2$*1$d " % [size, line] + end + + line += 1 + res + end + end + + ## + # Turns the method's token stream into HTML. + # + # Prepends line numbers if +options.line_numbers+ is true. + + def markup_code + return '' unless @token_stream + + src = RDoc::TokenStream.to_html @token_stream + + # dedent the source + indent = src.length + lines = src.lines.to_a + lines.shift if src =~ /\A.*#\ *File/i # remove '# File' comment + lines.each do |line| + if line =~ /^ *(?=\S)/ + n = $~.end(0) + indent = n if n < indent + break if n == 0 + end + end + src.gsub!(/^#{' ' * indent}/, '') if indent > 0 + + add_line_numbers(src) if options.line_numbers + + src + end + +end + +class RDoc::ClassModule + + ## + # Handy wrapper for marking up this class or module's comment + + def description + markup @comment_location + end + +end + +class RDoc::Context::Section + + include RDoc::Generator::Markup + +end + +class RDoc::TopLevel + + ## + # Returns a URL for this source file on some web repository. Use the -W + # command line option to set. + + def cvs_url + url = @store.options.webcvs + + if /%s/ =~ url then + url % @relative_name + else + url + @relative_name + end + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/pot.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/pot.rb new file mode 100644 index 00000000..a20fde07 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/pot.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true +## +# Generates a POT file. +# +# Here is a translator work flow with the generator. +# +# == Create .pot +# +# You create .pot file by pot formatter: +# +# % rdoc --format pot +# +# It generates doc/rdoc.pot. +# +# == Create .po +# +# You create .po file from doc/rdoc.pot. This operation is needed only +# the first time. This work flow assumes that you are a translator +# for Japanese. +# +# You create locale/ja/rdoc.po from doc/rdoc.pot. You can use msginit +# provided by GNU gettext or rmsginit provided by gettext gem. This +# work flow uses gettext gem because it is more portable than GNU +# gettext for Rubyists. Gettext gem is implemented by pure Ruby. +# +# % gem install gettext +# % mkdir -p locale/ja +# % rmsginit --input doc/rdoc.pot --output locale/ja/rdoc.po --locale ja +# +# Translate messages in .po +# +# You translate messages in .po by a PO file editor. po-mode.el exists +# for Emacs users. There are some GUI tools such as GTranslator. +# There are some Web services such as POEditor and Tansifex. You can +# edit by your favorite text editor because .po is a text file. +# Generate localized documentation +# +# You can generate localized documentation with locale/ja/rdoc.po: +# +# % rdoc --locale ja +# +# You can find documentation in Japanese in doc/. Yay! +# +# == Update translation +# +# You need to update translation when your application is added or +# modified messages. +# +# You can update .po by the following command lines: +# +# % rdoc --format pot +# % rmsgmerge --update locale/ja/rdoc.po doc/rdoc.pot +# +# You edit locale/ja/rdoc.po to translate new messages. + +class RDoc::Generator::POT + + RDoc::RDoc.add_generator self + + ## + # Description of this generator + + DESCRIPTION = 'creates .pot file' + + ## + # Set up a new .pot generator + + def initialize(store, options) #:not-new: + @options = options + @store = store + end + + ## + # Writes .pot to disk. + + def generate + po = extract_messages + pot_path = 'rdoc.pot' + File.open(pot_path, "w") do |pot| + pot.print(po.to_s) + end + end + + private + def extract_messages + extractor = MessageExtractor.new(@store) + extractor.extract + end + + require_relative 'pot/message_extractor' + require_relative 'pot/po' + require_relative 'pot/po_entry' + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/pot/message_extractor.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/pot/message_extractor.rb new file mode 100644 index 00000000..ee6d847b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/pot/message_extractor.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true +## +# Extracts message from RDoc::Store + +class RDoc::Generator::POT::MessageExtractor + + ## + # Creates a message extractor for +store+. + + def initialize(store) + @store = store + @po = RDoc::Generator::POT::PO.new + end + + ## + # Extracts messages from +store+, stores them into + # RDoc::Generator::POT::PO and returns it. + + def extract + @store.all_classes_and_modules.each do |klass| + extract_from_klass(klass) + end + @po + end + + private + + def extract_from_klass(klass) + extract_text(klass.comment_location, klass.full_name) + + klass.each_section do |section, constants, attributes| + extract_text(section.title, "#{klass.full_name}: section title") + section.comments.each do |comment| + extract_text(comment, "#{klass.full_name}: #{section.title}") + end + end + + klass.constants.each do |constant| + extract_text(constant.comment, constant.full_name) + end + + klass.attributes.each do |attribute| + extract_text(attribute.comment, attribute.full_name) + end + + klass.each_method do |method| + extract_text(method.comment, method.full_name) + end + end + + def extract_text(text, comment, location = nil) + return if text.nil? + + options = { + :extracted_comment => comment, + :references => [location].compact, + } + i18n_text = RDoc::I18n::Text.new(text) + i18n_text.extract_messages do |part| + @po.add(entry(part[:paragraph], options)) + end + end + + def entry(msgid, options) + RDoc::Generator::POT::POEntry.new(msgid, options) + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/pot/po.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/pot/po.rb new file mode 100644 index 00000000..447cb60e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/pot/po.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: true +## +# Generates a PO format text + +class RDoc::Generator::POT::PO + + ## + # Creates an object that represents PO format. + + def initialize + @entries = {} + add_header + end + + ## + # Adds a PO entry to the PO. + + def add(entry) + existing_entry = @entries[entry.msgid] + if existing_entry + entry = existing_entry.merge(entry) + end + @entries[entry.msgid] = entry + end + + ## + # Returns PO format text for the PO. + + def to_s + po = '' + sort_entries.each do |entry| + po += "\n" unless po.empty? + po += entry.to_s + end + po + end + + private + + def add_header + add(header_entry) + end + + def header_entry + comment = <<-COMMENT +SOME DESCRIPTIVE TITLE. +Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +This file is distributed under the same license as the PACKAGE package. +FIRST AUTHOR , YEAR. + COMMENT + + content = <<-CONTENT +Project-Id-Version: PACKAGE VERSEION +Report-Msgid-Bugs-To: +PO-Revision-Date: YEAR-MO_DA HO:MI+ZONE +Last-Translator: FULL NAME +Language-Team: LANGUAGE +Language: +MIME-Version: 1.0 +Content-Type: text/plain; charset=CHARSET +Content-Transfer-Encoding: 8bit +Plural-Forms: nplurals=INTEGER; plural=EXPRESSION; + CONTENT + + options = { + :msgstr => content, + :translator_comment => comment, + :flags => ['fuzzy'], + } + RDoc::Generator::POT::POEntry.new('', options) + end + + def sort_entries + headers, messages = @entries.values.partition do |entry| + entry.msgid.empty? + end + # TODO: sort by location + sorted_messages = messages.sort_by do |entry| + entry.msgid + end + headers + sorted_messages + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/pot/po_entry.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/pot/po_entry.rb new file mode 100644 index 00000000..8de260ee --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/pot/po_entry.rb @@ -0,0 +1,141 @@ +# frozen_string_literal: true +## +# A PO entry in PO + +class RDoc::Generator::POT::POEntry + + # The msgid content + attr_reader :msgid + + # The msgstr content + attr_reader :msgstr + + # The comment content created by translator (PO editor) + attr_reader :translator_comment + + # The comment content extracted from source file + attr_reader :extracted_comment + + # The locations where the PO entry is extracted + attr_reader :references + + # The flags of the PO entry + attr_reader :flags + + ## + # Creates a PO entry for +msgid+. Other values can be specified by + # +options+. + + def initialize(msgid, options = {}) + @msgid = msgid + @msgstr = options[:msgstr] || "" + @translator_comment = options[:translator_comment] + @extracted_comment = options[:extracted_comment] + @references = options[:references] || [] + @flags = options[:flags] || [] + end + + ## + # Returns the PO entry in PO format. + + def to_s + entry = '' + entry += format_translator_comment + entry += format_extracted_comment + entry += format_references + entry += format_flags + entry += <<-ENTRY +msgid #{format_message(@msgid)} +msgstr #{format_message(@msgstr)} + ENTRY + end + + ## + # Merges the PO entry with +other_entry+. + + def merge(other_entry) + options = { + :extracted_comment => merge_string(@extracted_comment, + other_entry.extracted_comment), + :translator_comment => merge_string(@translator_comment, + other_entry.translator_comment), + :references => merge_array(@references, + other_entry.references), + :flags => merge_array(@flags, + other_entry.flags), + } + self.class.new(@msgid, options) + end + + private + + def format_comment(mark, comment) + return '' unless comment + return '' if comment.empty? + + formatted_comment = '' + comment.each_line do |line| + formatted_comment += "#{mark} #{line}" + end + formatted_comment += "\n" unless formatted_comment.end_with?("\n") + formatted_comment + end + + def format_translator_comment + format_comment('#', @translator_comment) + end + + def format_extracted_comment + format_comment('#.', @extracted_comment) + end + + def format_references + return '' if @references.empty? + + formatted_references = '' + @references.sort.each do |file, line| + formatted_references += "\#: #{file}:#{line}\n" + end + formatted_references + end + + def format_flags + return '' if @flags.empty? + + formatted_flags = flags.join(",") + "\#, #{formatted_flags}\n" + end + + def format_message(message) + return "\"#{escape(message)}\"" unless message.include?("\n") + + formatted_message = '""' + message.each_line do |line| + formatted_message += "\n" + formatted_message += "\"#{escape(line)}\"" + end + formatted_message + end + + def escape(string) + string.gsub(/["\\\t\n]/) do |special_character| + case special_character + when "\t" + "\\t" + when "\n" + "\\n" + else + "\\#{special_character}" + end + end + end + + def merge_string(string1, string2) + [string1, string2].compact.join("\n") + end + + def merge_array(array1, array2) + (array1 + array2).uniq + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/ri.rb b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/ri.rb new file mode 100644 index 00000000..32f518ac --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/ri.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true +## +# Generates ri data files + +class RDoc::Generator::RI + + RDoc::RDoc.add_generator self + + ## + # Description of this generator + + DESCRIPTION = 'creates ri data files' + + ## + # Set up a new ri generator + + def initialize(store, options) #:not-new: + @options = options + @store = store + @store.path = '.' + end + + ## + # Writes the parsed data store to disk for use by ri. + + def generate + @store.save + end + +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_footer.rhtml b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_footer.rhtml new file mode 100644 index 00000000..9791b429 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_footer.rhtml @@ -0,0 +1,5 @@ + diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_head.rhtml b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_head.rhtml new file mode 100644 index 00000000..7376fc39 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_head.rhtml @@ -0,0 +1,48 @@ + + + +<%= h @title %> + +<%- if defined?(klass) -%> + "> + + <%- if klass.comment.empty? -%> + "> + <%- else -%> + "> + <%- end -%> +<%- elsif defined?(file) -%> + + "> +<%- elsif @title -%> + + + <%- if @options.main_page and + main_page = @files.find { |f| f.full_name == @options.main_page } then %> + "> + <%- else -%> + + <%- end -%> +<%- end -%> + +<%- if canonical_url = @options.canonical_root -%> +<% canonical_url = current.canonical_url if defined?(current) %> + +<%- end -%> + + + + + + + + + + + +<%- @options.template_stylesheets.each do |stylesheet| -%> + +<%- end -%> diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml new file mode 100644 index 00000000..d33ecd43 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_classes.rhtml @@ -0,0 +1,5 @@ + diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml new file mode 100644 index 00000000..067bd62e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml @@ -0,0 +1,15 @@ +<%- unless klass.extends.empty? then %> + +<%- end -%> diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml new file mode 100644 index 00000000..04846f84 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml @@ -0,0 +1,15 @@ +<%- unless klass.includes.empty? then %> + +<%- end -%> diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml new file mode 100644 index 00000000..faed7e0a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml @@ -0,0 +1,15 @@ + diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml new file mode 100644 index 00000000..d09216a0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_methods.rhtml @@ -0,0 +1,21 @@ +<% if (class_methods = klass.class_method_list.sort).any? %> + +<% end %> + +<% if (instance_methods = klass.instance_methods.sort).any? %> + +<% end %> diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_navigation.rhtml b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_navigation.rhtml new file mode 100644 index 00000000..d7f33084 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_navigation.rhtml @@ -0,0 +1,11 @@ + diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml new file mode 100644 index 00000000..3f68f0c0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml @@ -0,0 +1,32 @@ +<%- simple_files = @files.select { |f| f.text? } %> +<%- if defined?(current) -%> + <%- dir = current.full_name[%r{\A[^/]+(?=/)}] || current.page_name -%> +<%- end -%> +<%- unless simple_files.empty? then -%> + +<%- end -%> diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml new file mode 100644 index 00000000..6808b2bf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_parent.rhtml @@ -0,0 +1,6 @@ +<%- if klass.type == 'class' && (ancestors = klass.super_classes).any? -%> + +<%- end -%> diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml new file mode 100644 index 00000000..afc7f7b8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_search.rhtml @@ -0,0 +1,14 @@ + diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml new file mode 100644 index 00000000..6dcd2ae8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml @@ -0,0 +1,11 @@ +<%- unless klass.sections.length == 1 then %> + +<%- end -%> diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml new file mode 100644 index 00000000..b1e047b5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml @@ -0,0 +1,39 @@ +<%- comment = if current.respond_to? :comment_location then + current.comment_location + else + current.comment + end + table = current.parse(comment).table_of_contents.dup + + if table.length > 1 then %> + +<%- end -%> diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_toggle.rhtml b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_toggle.rhtml new file mode 100644 index 00000000..ed2cbe31 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/_sidebar_toggle.rhtml @@ -0,0 +1,3 @@ + diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/class.rhtml b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/class.rhtml new file mode 100644 index 00000000..628945d8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/class.rhtml @@ -0,0 +1,221 @@ + +<%= render '_sidebar_toggle.rhtml' %> + + + +
+ <%# If nesting level is 1, breadcrumb list is not needed %> + <% if breadcrumb.size > 1 %> + + <% end %> + +

+ <%= klass.type %> <%= klass.full_name %> +

+ +
+ <%= klass.description %> +
+ + <%- klass.each_section do |section, constants, attributes| -%> + +<%- end -%> +
diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/css/fonts.css b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/css/fonts.css new file mode 100644 index 00000000..57302b51 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/css/fonts.css @@ -0,0 +1,167 @@ +/* + * Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), + * with Reserved Font Name "Source". All Rights Reserved. Source is a + * trademark of Adobe Systems Incorporated in the United States and/or other + * countries. + * + * This Font Software is licensed under the SIL Open Font License, Version + * 1.1. + * + * This license is copied below, and is also available with a FAQ at: + * http://scripts.sil.org/OFL + */ + +@font-face { + font-family: "Source Code Pro"; + font-style: normal; + font-weight: 400; + src: local("Source Code Pro"), + local("SourceCodePro-Regular"), + url("../fonts/SourceCodePro-Regular.ttf") format("truetype"); +} + +@font-face { + font-family: "Source Code Pro"; + font-style: normal; + font-weight: 700; + src: local("Source Code Pro Bold"), + local("SourceCodePro-Bold"), + url("../fonts/SourceCodePro-Bold.ttf") format("truetype"); +} + +/* + * Copyright (c) 2010, Łukasz Dziedzic (dziedzic@typoland.com), + * with Reserved Font Name Lato. + * + * This Font Software is licensed under the SIL Open Font License, Version + * 1.1. + * + * This license is copied below, and is also available with a FAQ at: + * http://scripts.sil.org/OFL + */ + +@font-face { + font-family: "Lato"; + font-style: normal; + font-weight: 300; + src: local("Lato Light"), + local("Lato-Light"), + url("../fonts/Lato-Light.ttf") format("truetype"); +} + +@font-face { + font-family: "Lato"; + font-style: italic; + font-weight: 300; + src: local("Lato Light Italic"), + local("Lato-LightItalic"), + url("../fonts/Lato-LightItalic.ttf") format("truetype"); +} + +@font-face { + font-family: "Lato"; + font-style: normal; + font-weight: 700; + src: local("Lato Regular"), + local("Lato-Regular"), + url("../fonts/Lato-Regular.ttf") format("truetype"); +} + +@font-face { + font-family: "Lato"; + font-style: italic; + font-weight: 700; + src: local("Lato Italic"), + local("Lato-Italic"), + url("../fonts/Lato-RegularItalic.ttf") format("truetype"); +} + +/* + * ----------------------------------------------------------- + * SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 + * ----------------------------------------------------------- + * + * PREAMBLE + * The goals of the Open Font License (OFL) are to stimulate worldwide + * development of collaborative font projects, to support the font creation + * efforts of academic and linguistic communities, and to provide a free and + * open framework in which fonts may be shared and improved in partnership + * with others. + * + * The OFL allows the licensed fonts to be used, studied, modified and + * redistributed freely as long as they are not sold by themselves. The + * fonts, including any derivative works, can be bundled, embedded, + * redistributed and/or sold with any software provided that any reserved + * names are not used by derivative works. The fonts and derivatives, + * however, cannot be released under any other type of license. The + * requirement for fonts to remain under this license does not apply + * to any document created using the fonts or their derivatives. + * + * DEFINITIONS + * "Font Software" refers to the set of files released by the Copyright + * Holder(s) under this license and clearly marked as such. This may + * include source files, build scripts and documentation. + * + * "Reserved Font Name" refers to any names specified as such after the + * copyright statement(s). + * + * "Original Version" refers to the collection of Font Software components as + * distributed by the Copyright Holder(s). + * + * "Modified Version" refers to any derivative made by adding to, deleting, + * or substituting -- in part or in whole -- any of the components of the + * Original Version, by changing formats or by porting the Font Software to a + * new environment. + * + * "Author" refers to any designer, engineer, programmer, technical + * writer or other person who contributed to the Font Software. + * + * PERMISSION & CONDITIONS + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of the Font Software, to use, study, copy, merge, embed, modify, + * redistribute, and sell modified and unmodified copies of the Font + * Software, subject to the following conditions: + * + * 1) Neither the Font Software nor any of its individual components, + * in Original or Modified Versions, may be sold by itself. + * + * 2) Original or Modified Versions of the Font Software may be bundled, + * redistributed and/or sold with any software, provided that each copy + * contains the above copyright notice and this license. These can be + * included either as stand-alone text files, human-readable headers or + * in the appropriate machine-readable metadata fields within text or + * binary files as long as those fields can be easily viewed by the user. + * + * 3) No Modified Version of the Font Software may use the Reserved Font + * Name(s) unless explicit written permission is granted by the corresponding + * Copyright Holder. This restriction only applies to the primary font name as + * presented to the users. + * + * 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font + * Software shall not be used to promote, endorse or advertise any + * Modified Version, except to acknowledge the contribution(s) of the + * Copyright Holder(s) and the Author(s) or with their explicit written + * permission. + * + * 5) The Font Software, modified or unmodified, in part or in whole, + * must be distributed entirely under this license, and must not be + * distributed under any other license. The requirement for fonts to + * remain under this license does not apply to any document created + * using the Font Software. + * + * TERMINATION + * This license becomes null and void if any of the above conditions are + * not met. + * + * DISCLAIMER + * THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT + * OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL + * DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM + * OTHER DEALINGS IN THE FONT SOFTWARE. + */ + diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/css/rdoc.css b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/css/rdoc.css new file mode 100644 index 00000000..c84a604c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/css/rdoc.css @@ -0,0 +1,683 @@ +/* + * "Darkfish" RDoc CSS + * $Id: rdoc.css 54 2009-01-27 01:09:48Z deveiant $ + * + * Author: Michael Granger + * + */ + +/* vim: ft=css et sw=2 ts=2 sts=2 */ + +/* 1. Variables and Root Styles */ +:root { + --sidebar-width: 300px; + --highlight-color: #cc342d; /* Reddish color for accents and headings */ + --secondary-highlight-color: #c83045; /* Darker reddish color for secondary highlights */ + --text-color: #505050; /* Dark bluish-grey for text */ + --background-color: #fefefe; /* Near white background */ + --code-block-background-color: #f6f6f3; /* Slightly darker grey for code blocks */ + --link-color: #42405F; /* Dark bluish-grey for links */ + --link-hover-color: var(--highlight-color); /* Reddish color on hover */ + --border-color: #e0e0e0;; /* General border color */ + --source-code-toggle-color: var(--secondary-highlight-color); + --scrollbar-thumb-hover-background: #505050; /* Hover color for scrollbar thumb */ + --table-header-background-color: #eceaed; + --table-td-background-color: #f5f4f6; + + /* Font family variables */ + --font-primary: 'Segoe UI', 'Verdana', 'Arial', sans-serif; + --font-heading: 'Helvetica', 'Arial', sans-serif; + --font-code: monospace; +} + +/* 2. Global Styles */ +body { + background: var(--background-color); + font-family: var(--font-primary); + font-weight: 400; + color: var(--text-color); + line-height: 1.6; + + /* Layout */ + display: flex; + flex-direction: column; + min-height: 100vh; + margin: 0; +} + +/* 3. Typography */ +h1 span, +h2 span, +h3 span, +h4 span, +h5 span, +h6 span { + position: relative; + + display: none; + padding-left: 1em; + line-height: 0; + vertical-align: baseline; + font-size: 10px; +} + +h1 span { top: -1.3em; } +h2 span { top: -1.2em; } +h3 span { top: -1.0em; } +h4 span { top: -0.8em; } +h5 span { top: -0.5em; } +h6 span { top: -0.5em; } + +h1:hover span, +h2:hover span, +h3:hover span, +h4:hover span, +h5:hover span, +h6:hover span { + display: inline; +} + +h1:target, +h2:target, +h3:target, +h4:target, +h5:target, +h6:target { + margin-left: -10px; + border-left: 10px solid var(--border-color); + scroll-margin-top: 1rem; +} + +main .anchor-link:target { + scroll-margin-top: 1rem; +} + +/* 4. Links */ +a { + color: var(--link-color); + transition: color 0.3s ease; + text-decoration: underline; + text-underline-offset: 0.2em; /* Make sure it doesn't overlap with underscores in a method name. */ +} + +a:hover { + color: var(--link-hover-color); +} + +a code:hover { + color: var(--link-hover-color); +} + +/* 5. Code and Pre */ +code, +pre { + font-family: var(--font-code); + background-color: var(--code-block-background-color); + border: 1px solid var(--border-color); + border-radius: 6px; + padding: 16px; + overflow-x: auto; + font-size: 15px; + line-height: 1.5; + margin: 1em 0; +} + +code { + background-color: var(--code-block-background-color); + padding: 0.1em 0.3em; + border-radius: 3px; + font-size: 85%; +} + +/* Tables */ +table { + margin: 0; + border-spacing: 0; + border-collapse: collapse; +} + +table tr th, table tr td { + padding: 0.2em 0.4em; + border: 1px solid var(--border-color); +} + +table tr th { + background-color: var(--table-header-background-color); +} + +table tr:nth-child(even) td { + background-color: var(--table-td-background-color); +} + +/* 7. Navigation and Sidebar */ +nav { + font-family: var(--font-heading); + font-size: 16px; + border-right: 1px solid var(--border-color); + position: fixed; + top: 0; + bottom: 0; + left: 0; + width: var(--sidebar-width); + background: var(--background-color); /* It needs an explicit background for toggling narrow screens */ + overflow-y: auto; + z-index: 10; + display: flex; + flex-direction: column; + color: var(--text-color); +} + +nav[hidden] { + display: none; +} + +nav footer { + padding: 1em; + border-top: 1px solid var(--border-color); +} + +nav footer a { + color: var(--secondary-highlight-color); +} + +nav .nav-section { + margin-top: 1em; + padding: 0 1em; +} + +nav h2, nav h3 { + margin: 0 0 0.5em; + padding: 0.5em 0; + color: var(--highlight-color); + border-bottom: 1px solid var(--border-color); +} + +nav h2 { + font-size: 1.2em; +} + +nav h3, +#table-of-contents-navigation { + font-size: 1em; +} + +ol.breadcrumb { + display: flex; + + padding: 0; + margin: 0 0 1em; +} + +ol.breadcrumb li { + display: block; + list-style: none; + font-size: 125%; +} + +nav ul, +nav dl, +nav p { + padding: 0; + list-style: none; + margin: 0.5em 0; +} + +nav ul li { + margin-bottom: 0.3em; +} + +nav ul ul { + padding-left: 1em; +} + +nav ul ul ul { + padding-left: 1em; +} + +nav ul ul ul ul { + padding-left: 1em; +} + +nav a { + color: var(--link-color); + text-decoration: none; +} + +nav a:hover { + color: var(--link-hover-color); + text-decoration: underline; +} + +#navigation-toggle { + z-index: 1000; + font-size: 2em; + display: block; + position: fixed; + top: 10px; + left: 20px; + cursor: pointer; +} + +#navigation-toggle[aria-expanded="true"] { + top: 10px; + left: 250px; +} + +nav ul li details { + position: relative; + padding-right: 1.5em; /* Add space for the marker on the right */ +} + +nav ul li details > summary { + list-style: none; /* Remove the default marker */ + position: relative; /* So that the open/close triangle can position itself absolutely inside */ +} + +nav ul li details > summary::-webkit-details-marker { + display: none; /* Removes the default marker, in Safari 18. */ +} + +nav ul li details > summary::after { + content: '▶'; /* Unicode right-pointing triangle */ + position: absolute; + font-size: 0.8em; + bottom: 0.1em; + margin-left: 0.3em; + transition: transform 0.2s ease; +} + +nav ul li details[open] > summary::after { + transform: rotate(90deg); /* Rotate the triangle when open */ +} + +/* 8. Main Content */ +main { + flex: 1; + display: block; + margin: 3em auto; + padding: 0 2em; + max-width: 800px; + font-size: 16px; + line-height: 1.6; + color: var(--text-color); + box-sizing: border-box; +} + +@media (min-width: 1024px) { + main { + margin-left: var(--sidebar-width); + } + + .table-of-contents main { + margin-left: 20em; + } + + #navigation-toggle { + display: none; + } +} + +main h1[class] { + margin-top: 0; + margin-bottom: 1em; + font-size: 2.5em; + color: var(--highlight-color); +} + +main h1, +main h2, +main h3, +main h4, +main h5, +main h6 { + font-family: var(--font-heading); + color: var(--highlight-color); +} + +/* Search */ +#search-section { + padding: 1em; + background-color: var(--background-color); + border-bottom: 1px solid var(--border-color); +} + +#search-field-wrapper { + position: relative; + display: flex; + align-items: center; +} + +#search-field { + width: 100%; + padding: 0.5em 1em 0.5em 2.5em; + border: 1px solid var(--border-color); + border-radius: 20px; + font-size: 14px; + outline: none; + transition: border-color 0.3s ease; + color: var(--text-color); +} + +#search-field:focus { + border-color: var(--highlight-color); +} + +#search-field::placeholder { + color: var(--text-color); +} + +#search-field-wrapper::before { + content: "\1F50D"; + position: absolute; + left: 0.75em; + top: 50%; + transform: translateY(-50%); + font-size: 14px; + color: var(--text-color); + opacity: 0.6; +} + +/* Search Results */ +#search-results { + font-family: var(--font-primary); + font-weight: 300; +} + +#search-results .search-match { + font-family: var(--font-heading); + font-weight: normal; +} + +#search-results .search-selected { + background: var(--code-block-background-color); + border-bottom: 1px solid transparent; +} + +#search-results li { + list-style: none; + border-bottom: 1px solid var(--border-color); + margin-bottom: 0.5em; +} + +#search-results li:last-child { + border-bottom: none; + margin-bottom: 0; +} + +#search-results li p { + padding: 0; + margin: 0.5em; +} + +#search-results .search-namespace { + font-weight: bold; +} + +#search-results li em { + background-color: rgba(224, 108, 117, 0.1); + font-style: normal; +} + +#search-results pre { + margin: 0.5em; + font-family: var(--font-code); +} + +/* Syntax Highlighting - Gruvbox Light Scheme */ + +.ruby-constant { color: #AF3A03; } /* Dark Orange */ +.ruby-keyword { color: #9D0006; } /* Dark Red */ +.ruby-ivar { color: #B57614; } /* Brown */ +.ruby-operator { color: #427B58; } /* Dark Teal */ +.ruby-identifier { color: #076678; } /* Deep Teal */ +.ruby-node { color: #8F3F71; } /* Plum */ +.ruby-comment { color: #928374; font-style: italic; } /* Gray */ +.ruby-regexp { color: #8F3F71; } /* Plum */ +.ruby-value { color: #AF3A03; } /* Dark Orange */ +.ruby-string { color: #79740E; } /* Olive */ + +/* Emphasis */ +em { + text-decoration-color: rgba(52, 48, 64, 0.25); + text-decoration-line: underline; + text-decoration-style: dotted; +} + +strong, +em { + color: var(--highlight-color); + background-color: rgba(255, 111, 97, 0.1); /* Light red background for emphasis */ +} + +/* Paragraphs */ +main p { + line-height: 1.5em; + font-weight: 400; +} + +/* Preformatted Text */ +main pre { + margin: 1.2em 0.5em; + padding: 1em; + font-size: 0.8em; +} + +/* Horizontal Rules */ +main hr { + margin: 1.5em 1em; + border: 2px solid var(--border-color); +} + +/* Blockquotes */ +main blockquote { + margin: 0 2em 1.2em 1.2em; + padding-left: 0.5em; + border-left: 2px solid var(--border-color); +} + +/* Lists */ +main li > p { + margin: 0.5em; +} + +/* Definition Lists */ +main dl { + margin: 1em 0.5em; +} + +main dt { + line-height: 1.5; /* matches `main p` */ + font-weight: bold; +} + +main dl.note-list dt { + margin-right: 1em; + float: left; +} + +main dl.note-list dt:has(+ dt) { + margin-right: 0.25em; +} + +main dl.note-list dt:has(+ dt)::after { + content: ', '; + font-weight: normal; +} + +main dd { + margin: 0 0 1em 1em; +} + +main dd p:first-child { + margin-top: 0; +} + +/* Headers within Main */ +main header h2 { + margin-top: 2em; + border-width: 0; + border-top: 4px solid var(--border-color); + font-size: 130%; +} + +main header h3 { + margin: 2em 0 1.5em; + border-width: 0; + border-top: 3px solid var(--border-color); + font-size: 120%; +} + +/* Utility Classes */ +.hide { display: none !important; } +.initially-hidden { display: none; } + +/* Table of Contents */ +.table-of-contents ul { + margin: 1em; + list-style: none; +} + +.table-of-contents ul ul { + margin-top: 0.25em; +} + +.table-of-contents ul :link, +.table-of-contents ul :visited { + font-size: 16px; +} + +.table-of-contents li { + margin-bottom: 0.25em; +} + +/* Method Details */ +main .method-source-code { + visibility: hidden; + max-height: 0; + overflow: auto; + transition-duration: 200ms; + transition-delay: 0ms; + transition-property: all; + transition-timing-function: ease-in-out; +} + +main .method-source-code pre { + border-color: var(--source-code-toggle-color); +} + +main .method-source-code.active-menu { + visibility: visible; + max-height: 100vh; +} + +main .method-description .method-calls-super { + color: var(--text-color); + font-weight: bold; +} + +main .method-detail { + margin-bottom: 2.5em; +} + +main .method-detail:target { + margin-left: -10px; + border-left: 10px solid var(--border-color); +} + +main .method-header { + display: inline-block; +} + +main .method-heading { + position: relative; + font-family: var(--font-code); + font-size: 110%; + font-weight: bold; +} + +main .method-heading::after { + content: '¶'; + position: absolute; + visibility: hidden; + color: var(--highlight-color); + font-size: 0.5em; +} + +main .method-heading:hover::after { + visibility: visible; +} + +main .method-controls { + line-height: 20px; + float: right; + color: var(--source-code-toggle-color); + cursor: pointer; +} + +main .method-description, +main .aliases { + margin-top: 0.75em; + color: var(--text-color); +} + +main .aliases { + padding-top: 4px; + font-style: italic; + cursor: default; +} + +main .aliases a { + color: var(--secondary-highlight-color); +} + +main .mixin-from { + font-size: 80%; + font-style: italic; + margin-bottom: 0.75em; +} + +main .method-description ul { + margin-left: 1.5em; +} + +main #attribute-method-details .method-detail:hover { + background-color: transparent; + cursor: default; +} + +main .attribute-access-type { + text-transform: uppercase; +} + +/* Responsive Adjustments */ +@media (max-width: 480px) { + nav { + width: 100%; + } + + main { + margin: 1em auto; + padding: 0 1em; + max-width: 100%; + } + + #navigation-toggle { + right: 10px; + left: auto; + } + + #navigation-toggle[aria-expanded="true"] { + left: auto; + } + + table { + display: block; + overflow-x: auto; + white-space: nowrap; + } + + main .method-controls { + margin-top: 10px; + float: none; + } +} diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/fonts/Lato-Light.ttf b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/fonts/Lato-Light.ttf new file mode 100644 index 00000000..b49dd437 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/fonts/Lato-Light.ttf differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/fonts/Lato-LightItalic.ttf b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/fonts/Lato-LightItalic.ttf new file mode 100644 index 00000000..7959fef0 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/fonts/Lato-LightItalic.ttf differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/fonts/Lato-Regular.ttf b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/fonts/Lato-Regular.ttf new file mode 100644 index 00000000..839cd589 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/fonts/Lato-Regular.ttf differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/fonts/Lato-RegularItalic.ttf b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/fonts/Lato-RegularItalic.ttf new file mode 100644 index 00000000..bababa09 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/fonts/Lato-RegularItalic.ttf differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Bold.ttf b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Bold.ttf new file mode 100644 index 00000000..dd00982d Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Bold.ttf differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Regular.ttf b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Regular.ttf new file mode 100644 index 00000000..1decfb95 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/fonts/SourceCodePro-Regular.ttf differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/add.png b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/add.png new file mode 100644 index 00000000..6332fefe Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/add.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/arrow_up.png b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/arrow_up.png new file mode 100644 index 00000000..1ebb1932 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/arrow_up.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/brick.png b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/brick.png new file mode 100644 index 00000000..7851cf34 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/brick.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/brick_link.png b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/brick_link.png new file mode 100644 index 00000000..9ebf013a Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/brick_link.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/bug.png b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/bug.png new file mode 100644 index 00000000..2d5fb90e Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/bug.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/bullet_black.png b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/bullet_black.png new file mode 100644 index 00000000..57619706 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/bullet_black.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/bullet_toggle_minus.png b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/bullet_toggle_minus.png new file mode 100644 index 00000000..b47ce55f Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/bullet_toggle_minus.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/bullet_toggle_plus.png b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/bullet_toggle_plus.png new file mode 100644 index 00000000..9ab4a896 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/bullet_toggle_plus.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/date.png b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/date.png new file mode 100644 index 00000000..783c8335 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/date.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/delete.png b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/delete.png new file mode 100644 index 00000000..08f24936 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/delete.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/find.png b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/find.png new file mode 100644 index 00000000..15474796 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/find.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/loadingAnimation.gif b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/loadingAnimation.gif new file mode 100644 index 00000000..82290f48 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/loadingAnimation.gif differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/macFFBgHack.png b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/macFFBgHack.png new file mode 100644 index 00000000..c6473b32 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/macFFBgHack.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/package.png b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/package.png new file mode 100644 index 00000000..da3c2a2d Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/package.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/page_green.png b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/page_green.png new file mode 100644 index 00000000..de8e003f Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/page_green.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/page_white_text.png b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/page_white_text.png new file mode 100644 index 00000000..813f712f Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/page_white_text.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/page_white_width.png b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/page_white_width.png new file mode 100644 index 00000000..1eb88094 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/page_white_width.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/plugin.png b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/plugin.png new file mode 100644 index 00000000..6187b15a Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/plugin.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/ruby.png b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/ruby.png new file mode 100644 index 00000000..f763a168 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/ruby.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/tag_blue.png b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/tag_blue.png new file mode 100644 index 00000000..3f02b5f8 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/tag_blue.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/tag_green.png b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/tag_green.png new file mode 100644 index 00000000..83ec984b Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/tag_green.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/transparent.png b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/transparent.png new file mode 100644 index 00000000..d665e179 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/transparent.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/wrench.png b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/wrench.png new file mode 100644 index 00000000..5c8213fe Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/wrench.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/wrench_orange.png b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/wrench_orange.png new file mode 100644 index 00000000..565a9330 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/wrench_orange.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/zoom.png b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/zoom.png new file mode 100644 index 00000000..908612e3 Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/images/zoom.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/index.rhtml b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/index.rhtml new file mode 100644 index 00000000..beaab957 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/index.rhtml @@ -0,0 +1,23 @@ + +<%= render '_sidebar_toggle.rhtml' %> + + + +
+<%- if @main_page %> + <%= @main_page.description %> +<%- else -%> +

This is the API documentation for <%= h @title %>. +<%- end -%> +

diff --git a/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/js/darkfish.js b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/js/darkfish.js new file mode 100644 index 00000000..4c15efde --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rdoc-6.14.0/lib/rdoc/generator/template/darkfish/js/darkfish.js @@ -0,0 +1,120 @@ +/** + * + * Darkfish Page Functions + * $Id: darkfish.js 53 2009-01-07 02:52:03Z deveiant $ + * + * Author: Michael Granger + * + */ + +/* Provide console simulation for firebug-less environments */ +/* +if (!("console" in window) || !("firebug" in console)) { + var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", + "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"]; + + window.console = {}; + for (var i = 0; i < names.length; ++i) + window.console[names[i]] = function() {}; +}; +*/ + + +function showSource( e ) { + var target = e.target; + while (!target.classList.contains('method-detail')) { + target = target.parentNode; + } + if (typeof target !== "undefined" && target !== null) { + target = target.querySelector('.method-source-code'); + } + if (typeof target !== "undefined" && target !== null) { + target.classList.toggle('active-menu') + } +}; + +function hookSourceViews() { + document.querySelectorAll('.method-source-toggle').forEach(function (codeObject) { + codeObject.addEventListener('click', showSource); + }); +}; + +function hookSearch() { + var input = document.querySelector('#search-field'); + var result = document.querySelector('#search-results'); + result.classList.remove("initially-hidden"); + + var search_section = document.querySelector('#search-section'); + search_section.classList.remove("initially-hidden"); + + var search = new Search(search_data, input, result); + + search.renderItem = function(result) { + var li = document.createElement('li'); + var html = ''; + + // TODO add relative path to " + @output.puts "" + @output.puts "" + @output.puts "" + @output.puts "" + @output.puts "" + end + + def flush + @output.flush + end + + def move_progress(percent_done) + @output.puts " " + @output.flush + end + + def make_header_red + @output.puts " " + end + + def make_header_yellow + @output.puts " " + end + + def make_example_group_header_red(group_id) + @output.puts " " + @output.puts " " + end + + def make_example_group_header_yellow(group_id) + @output.puts " " + @output.puts " " + end + + private + + def indentation_style(number_of_parents) + "style=\"margin-left: #{(number_of_parents - 1) * 15}px;\"" + end + + REPORT_HEADER = <<-EOF +
+ +
+
+

RSpec Code Examples

+
+ +
+ + + +
+ +
+

 

+

 

+
+
+ + +
+EOF + + GLOBAL_SCRIPTS = <<-EOF + +function addClass(element_id, classname) { + document.getElementById(element_id).className += (" " + classname); +} + +function removeClass(element_id, classname) { + var elem = document.getElementById(element_id); + var classlist = elem.className.replace(classname,''); + elem.className = classlist; +} + +function moveProgressBar(percentDone) { + document.getElementById("rspec-header").style.width = percentDone +"%"; +} + +function makeRed(element_id) { + removeClass(element_id, 'passed'); + removeClass(element_id, 'not_implemented'); + addClass(element_id,'failed'); +} + +function makeYellow(element_id) { + var elem = document.getElementById(element_id); + if (elem.className.indexOf("failed") == -1) { // class doesn't includes failed + if (elem.className.indexOf("not_implemented") == -1) { // class doesn't include not_implemented + removeClass(element_id, 'passed'); + addClass(element_id,'not_implemented'); + } + } +} + +function apply_filters() { + var passed_filter = document.getElementById('passed_checkbox').checked; + var failed_filter = document.getElementById('failed_checkbox').checked; + var pending_filter = document.getElementById('pending_checkbox').checked; + + assign_display_style("example passed", passed_filter); + assign_display_style("example failed", failed_filter); + assign_display_style("example not_implemented", pending_filter); + + assign_display_style_for_group("example_group passed", passed_filter); + assign_display_style_for_group("example_group not_implemented", pending_filter, pending_filter || passed_filter); + assign_display_style_for_group("example_group failed", failed_filter, failed_filter || pending_filter || passed_filter); +} + +function get_display_style(display_flag) { + var style_mode = 'none'; + if (display_flag == true) { + style_mode = 'block'; + } + return style_mode; +} + +function assign_display_style(classname, display_flag) { + var style_mode = get_display_style(display_flag); + var elems = document.getElementsByClassName(classname) + for (var i=0; i + + + RSpec results + + + + + + + + +EOF + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/formatters/html_snippet_extractor.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/formatters/html_snippet_extractor.rb new file mode 100644 index 00000000..992704b6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/formatters/html_snippet_extractor.rb @@ -0,0 +1,122 @@ +module RSpec + module Core + module Formatters + # @api private + # + # Extracts code snippets by looking at the backtrace of the passed error + # and applies synax highlighting and line numbers using html. + class HtmlSnippetExtractor + # @private + module NullConverter + def self.convert(code) + %Q(#{code}\n# Install the coderay gem to get syntax highlighting) + end + end + + # @private + module CoderayConverter + def self.convert(code) + CodeRay.scan(code, :ruby).html(:line_numbers => false) + end + end + + # rubocop:disable Style/ClassVars + # @private + @@converter = NullConverter + + begin + require 'coderay' + RSpec::Support.require_rspec_core 'formatters/syntax_highlighter' + RSpec::Core::Formatters::SyntaxHighlighter.attempt_to_add_rspec_terms_to_coderay_keywords + @@converter = CoderayConverter + # rubocop:disable Lint/HandleExceptions + rescue LoadError + # it'll fall back to the NullConverter assigned above + # rubocop:enable Lint/HandleExceptions + end + + # rubocop:enable Style/ClassVars + + # @api private + # + # Extract lines of code corresponding to a backtrace. + # + # @param backtrace [String] the backtrace from a test failure + # @return [String] highlighted code snippet indicating where the test + # failure occurred + # + # @see #post_process + def snippet(backtrace) + raw_code, line = snippet_for(backtrace[0]) + highlighted = @@converter.convert(raw_code) + post_process(highlighted, line) + end + # rubocop:enable Style/ClassVars + + # @api private + # + # Create a snippet from a line of code. + # + # @param error_line [String] file name with line number (i.e. + # 'foo_spec.rb:12') + # @return [String] lines around the target line within the file + # + # @see #lines_around + def snippet_for(error_line) + if error_line =~ /(.*):(\d+)/ + file = Regexp.last_match[1] + line = Regexp.last_match[2].to_i + [lines_around(file, line), line] + else + ["# Couldn't get snippet for #{error_line}", 1] + end + end + + # @api private + # + # Extract lines of code centered around a particular line within a + # source file. + # + # @param file [String] filename + # @param line [Fixnum] line number + # @return [String] lines around the target line within the file (2 above + # and 1 below). + def lines_around(file, line) + if File.file?(file) + lines = File.read(file).split("\n") + min = [0, line - 3].max + max = [line + 1, lines.length - 1].min + selected_lines = [] + selected_lines.join("\n") + lines[min..max].join("\n") + else + "# Couldn't get snippet for #{file}" + end + rescue SecurityError + # :nocov: - SecurityError is no longer produced starting in ruby 2.7 + "# Couldn't get snippet for #{file}" + # :nocov: + end + + # @api private + # + # Adds line numbers to all lines and highlights the line where the + # failure occurred using html `span` tags. + # + # @param highlighted [String] syntax-highlighted snippet surrounding the + # offending line of code + # @param offending_line [Fixnum] line where failure occurred + # @return [String] completed snippet + def post_process(highlighted, offending_line) + new_lines = [] + highlighted.split("\n").each_with_index do |line, i| + new_line = "#{offending_line + i - 2}#{line}" + new_line = "#{new_line}" if i == 2 + new_lines << new_line + end + new_lines.join("\n") + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/formatters/json_formatter.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/formatters/json_formatter.rb new file mode 100644 index 00000000..7c6fde82 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/formatters/json_formatter.rb @@ -0,0 +1,103 @@ +RSpec::Support.require_rspec_core "formatters/base_formatter" +require 'json' + +module RSpec + module Core + module Formatters + # @private + class JsonFormatter < BaseFormatter + Formatters.register self, :message, :dump_summary, :dump_profile, :stop, :seed, :close + + attr_reader :output_hash + + def initialize(output) + super + @output_hash = { + :version => RSpec::Core::Version::STRING + } + end + + def message(notification) + (@output_hash[:messages] ||= []) << notification.message + end + + def dump_summary(summary) + @output_hash[:summary] = { + :duration => summary.duration, + :example_count => summary.example_count, + :failure_count => summary.failure_count, + :pending_count => summary.pending_count, + :errors_outside_of_examples_count => summary.errors_outside_of_examples_count + } + @output_hash[:summary_line] = summary.totals_line + end + + def stop(group_notification) + @output_hash[:examples] = group_notification.notifications.map do |notification| + format_example(notification.example).tap do |hash| + e = notification.example.exception + + if e + hash[:exception] = { + :class => e.class.name, + :message => e.message, + :backtrace => notification.formatted_backtrace, + } + end + end + end + end + + def seed(notification) + return unless notification.seed_used? + @output_hash[:seed] = notification.seed + end + + def close(_notification) + output.write @output_hash.to_json + end + + def dump_profile(profile) + @output_hash[:profile] = {} + dump_profile_slowest_examples(profile) + dump_profile_slowest_example_groups(profile) + end + + # @api private + def dump_profile_slowest_examples(profile) + @output_hash[:profile] = {} + @output_hash[:profile][:examples] = profile.slowest_examples.map do |example| + format_example(example).tap do |hash| + hash[:run_time] = example.execution_result.run_time + end + end + @output_hash[:profile][:slowest] = profile.slow_duration + @output_hash[:profile][:total] = profile.duration + end + + # @api private + def dump_profile_slowest_example_groups(profile) + @output_hash[:profile] ||= {} + @output_hash[:profile][:groups] = profile.slowest_groups.map do |loc, hash| + hash.update(:location => loc) + end + end + + private + + def format_example(example) + { + :id => example.id, + :description => example.description, + :full_description => example.full_description, + :status => example.execution_result.status.to_s, + :file_path => example.metadata[:file_path], + :line_number => example.metadata[:line_number], + :run_time => example.execution_result.run_time, + :pending_message => example.execution_result.pending_message, + } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/formatters/profile_formatter.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/formatters/profile_formatter.rb new file mode 100644 index 00000000..4b95d938 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/formatters/profile_formatter.rb @@ -0,0 +1,68 @@ +RSpec::Support.require_rspec_core "formatters/console_codes" + +module RSpec + module Core + module Formatters + # @api private + # Formatter for providing profile output. + class ProfileFormatter + Formatters.register self, :dump_profile + + def initialize(output) + @output = output + end + + # @private + attr_reader :output + + # @api public + # + # This method is invoked after the dumping the summary if profiling is + # enabled. + # + # @param profile [ProfileNotification] containing duration, + # slowest_examples and slowest_example_groups + def dump_profile(profile) + dump_profile_slowest_examples(profile) + dump_profile_slowest_example_groups(profile) + end + + private + + def dump_profile_slowest_examples(profile) + @output.puts "\nTop #{profile.slowest_examples.size} slowest " \ + "examples (#{Helpers.format_seconds(profile.slow_duration)} " \ + "seconds, #{profile.percentage}% of total time):\n" + + profile.slowest_examples.each do |example| + @output.puts " #{example.full_description}" + @output.puts " #{bold(Helpers.format_seconds(example.execution_result.run_time))} " \ + "#{bold("seconds")} #{format_caller(example.location)}" + end + end + + def dump_profile_slowest_example_groups(profile) + return if profile.slowest_groups.empty? + + @output.puts "\nTop #{profile.slowest_groups.size} slowest example groups:" + profile.slowest_groups.each do |loc, hash| + average = "#{bold(Helpers.format_seconds(hash[:average]))} #{bold("seconds")} average" + total = "#{Helpers.format_seconds(hash[:total_time])} seconds" + count = Helpers.pluralize(hash[:count], "example") + @output.puts " #{hash[:description]}" + @output.puts " #{average} (#{total} / #{count}) #{loc}" + end + end + + def format_caller(caller_info) + RSpec.configuration.backtrace_formatter.backtrace_line( + caller_info.to_s.split(':in `block').first) + end + + def bold(text) + ConsoleCodes.wrap(text, :bold) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/formatters/progress_formatter.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/formatters/progress_formatter.rb new file mode 100644 index 00000000..81e0beb4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/formatters/progress_formatter.rb @@ -0,0 +1,29 @@ +RSpec::Support.require_rspec_core "formatters/base_text_formatter" +RSpec::Support.require_rspec_core "formatters/console_codes" + +module RSpec + module Core + module Formatters + # @private + class ProgressFormatter < BaseTextFormatter + Formatters.register self, :example_passed, :example_pending, :example_failed, :start_dump + + def example_passed(_notification) + output.print ConsoleCodes.wrap('.', :success) + end + + def example_pending(_notification) + output.print ConsoleCodes.wrap('*', :pending) + end + + def example_failed(_notification) + output.print ConsoleCodes.wrap('F', :failure) + end + + def start_dump(_notification) + output.puts + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/formatters/protocol.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/formatters/protocol.rb new file mode 100644 index 00000000..12fc71f8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/formatters/protocol.rb @@ -0,0 +1,182 @@ +module RSpec + module Core + module Formatters + # This class isn't loaded at runtime but serves to document all of the + # notifications implemented as part of the standard interface. The + # reporter will issue these during a normal test suite run, but a + # formatter will only receive those notifications it has registered + # itself to receive. To register a formatter call: + # + # `::RSpec::Core::Formatters.register class, :list, :of, :notifications` + # + # e.g. + # + # `::RSpec::Core::Formatters.register self, :start, :example_started` + # + # @see RSpec::Core::Formatters::BaseFormatter + # @see RSpec::Core::Formatters::BaseTextFormatter + # @see RSpec::Core::Reporter + class Protocol + # @method initialize(output) + # @api public + # + # @param output [IO] the formatter output + + # @method start(notification) + # @api public + # @group Suite Notifications + # + # This method is invoked before any examples are run, right after + # they have all been collected. This can be useful for special + # formatters that need to provide progress on feedback (graphical ones). + # + # This will only be invoked once, and the next one to be invoked + # is {#example_group_started}. + # + # @param notification [Notifications::StartNotification] + + # @method example_group_started(notification) + # @api public + # @group Group Notifications + # + # This method is invoked at the beginning of the execution of each + # example group. + # + # The next method to be invoked after this is {#example_passed}, + # {#example_pending}, or {#example_group_finished}. + # + # @param notification [Notifications::GroupNotification] containing example_group + # subclass of {ExampleGroup} + + # @method example_group_finished(notification) + # @api public + # @group Group Notifications + # + # Invoked at the end of the execution of each example group. + # + # @param notification [Notifications::GroupNotification] containing example_group + # subclass of {ExampleGroup} + + # @method example_started(notification) + # @api public + # @group Example Notifications + # + # Invoked at the beginning of the execution of each example. + # + # @param notification [Notifications::ExampleNotification] containing example subclass + # of {Example} + + # @method example_finished(notification) + # @api public + # @group Example Notifications + # + # Invoked at the end of the execution of each example. + # + # @param notification [Notifications::ExampleNotification] containing example subclass + # of {Example} + + # @method example_passed(notification) + # @api public + # @group Example Notifications + # + # Invoked when an example passes. + # + # @param notification [Notifications::ExampleNotification] containing example subclass + # of {Example} + + # @method example_pending(notification) + # @api public + # @group Example Notifications + # + # Invoked when an example is pending. + # + # @param notification [Notifications::ExampleNotification] containing example subclass + # of {Example} + + # @method example_failed(notification) + # @api public + # @group Example Notifications + # + # Invoked when an example fails. + # + # @param notification [Notifications::ExampleNotification] containing example subclass + # of {Example} + + # @method message(notification) + # @api public + # @group Suite Notifications + # + # Used by the reporter to send messages to the output stream. + # + # @param notification [Notifications::MessageNotification] containing message + + # @method stop(notification) + # @api public + # @group Suite Notifications + # + # Invoked after all examples have executed, before dumping post-run + # reports. + # + # @param notification [Notifications::NullNotification] + + # @method start_dump(notification) + # @api public + # @group Suite Notifications + # + # This method is invoked after all of the examples have executed. The + # next method to be invoked after this one is {#dump_failures} + # (BaseTextFormatter then calls {#dump_failures} once for each failed + # example). + # + # @param notification [Notifications::NullNotification] + + # @method dump_failures(notification) + # @api public + # @group Suite Notifications + # + # Dumps detailed information about each example failure. + # + # @param notification [Notifications::NullNotification] + + # @method dump_summary(summary) + # @api public + # @group Suite Notifications + # + # This method is invoked after the dumping of examples and failures. + # Each parameter is assigned to a corresponding attribute. + # + # @param summary [Notifications::SummaryNotification] containing duration, + # example_count, failure_count and pending_count + + # @method dump_profile(profile) + # @api public + # @group Suite Notifications + # + # This method is invoked after the dumping the summary if profiling is + # enabled. + # + # @param profile [Notifications::ProfileNotification] containing duration, + # slowest_examples and slowest_example_groups + + # @method dump_pending(notification) + # @api public + # @group Suite Notifications + # + # Outputs a report of pending examples. This gets invoked + # after the summary if option is set to do so. + # + # @param notification [Notifications::NullNotification] + + # @method close(notification) + # @api public + # @group Suite Notifications + # + # Invoked at the end of a suite run. Allows the formatter to do any + # tidying up, but be aware that formatter output streams may be used + # elsewhere so don't actually close them. + # + # @param notification [Notifications::NullNotification] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/formatters/snippet_extractor.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/formatters/snippet_extractor.rb new file mode 100644 index 00000000..c585db41 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/formatters/snippet_extractor.rb @@ -0,0 +1,134 @@ +module RSpec + module Core + module Formatters + # @private + class SnippetExtractor + NoSuchFileError = Class.new(StandardError) + NoSuchLineError = Class.new(StandardError) + + def self.extract_line_at(file_path, line_number) + source = source_from_file(file_path) + line = source.lines[line_number - 1] + raise NoSuchLineError unless line + line + end + + def self.source_from_file(path) + raise NoSuchFileError unless File.exist?(path) + RSpec.world.source_from_file(path) + end + + if RSpec::Support::RubyFeatures.ripper_supported? + NoExpressionAtLineError = Class.new(StandardError) + + attr_reader :source, :beginning_line_number, :max_line_count + + def self.extract_expression_lines_at(file_path, beginning_line_number, max_line_count=nil) + if max_line_count == 1 + [extract_line_at(file_path, beginning_line_number)] + else + source = source_from_file(file_path) + new(source, beginning_line_number, max_line_count).expression_lines + end + end + + def initialize(source, beginning_line_number, max_line_count=nil) + @source = source + @beginning_line_number = beginning_line_number + @max_line_count = max_line_count + end + + def expression_lines + line_range = line_range_of_expression + + if max_line_count && line_range.count > max_line_count + line_range = (line_range.begin)..(line_range.begin + max_line_count - 1) + end + + source.lines[(line_range.begin - 1)..(line_range.end - 1)] + rescue SyntaxError, NoExpressionAtLineError + [self.class.extract_line_at(source.path, beginning_line_number)] + end + + private + + def line_range_of_expression + @line_range_of_expression ||= begin + line_range = line_range_of_location_nodes_in_expression + initial_unclosed_tokens = unclosed_tokens_in_line_range(line_range) + unclosed_tokens = initial_unclosed_tokens + + until (initial_unclosed_tokens & unclosed_tokens).empty? + line_range = (line_range.begin)..(line_range.end + 1) + unclosed_tokens = unclosed_tokens_in_line_range(line_range) + end + + line_range + end + end + + def unclosed_tokens_in_line_range(line_range) + tokens = FlatMap.flat_map(line_range) do |line_number| + source.tokens_by_line_number[line_number] + end + + tokens.each_with_object([]) do |token, unclosed_tokens| + if token.opening? + unclosed_tokens << token + else + index = unclosed_tokens.rindex do |unclosed_token| + unclosed_token.closed_by?(token) + end + unclosed_tokens.delete_at(index) if index + end + end + end + + def line_range_of_location_nodes_in_expression + line_numbers = expression_node.each_with_object(Set.new) do |node, set| + set << node.location.line if node.location + end + + line_numbers.min..line_numbers.max + end + + def expression_node + raise NoExpressionAtLineError if location_nodes_at_beginning_line.empty? + + @expression_node ||= begin + common_ancestor_nodes = location_nodes_at_beginning_line.map do |node| + node.each_ancestor.to_a + end.reduce(:&) + + common_ancestor_nodes.find { |node| expression_outmost_node?(node) } + end + end + + def expression_outmost_node?(node) + return true unless node.parent + return false if node.type.to_s.start_with?('@') + ![node, node.parent].all? do |n| + # See `Ripper::PARSER_EVENTS` for the complete list of sexp types. + type = n.type.to_s + type.end_with?('call') || type.start_with?('method_add_') + end + end + + def location_nodes_at_beginning_line + source.nodes_by_line_number[beginning_line_number] + end + else + # :nocov: + def self.extract_expression_lines_at(file_path, beginning_line_number, *) + [extract_line_at(file_path, beginning_line_number)] + end + # :nocov: + end + + def self.least_indentation_from(lines) + lines.map { |line| line[/^[ \t]*/] }.min + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/formatters/syntax_highlighter.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/formatters/syntax_highlighter.rb new file mode 100644 index 00000000..e7766f6a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/formatters/syntax_highlighter.rb @@ -0,0 +1,91 @@ +module RSpec + module Core + module Formatters + # @private + # Provides terminal syntax highlighting of code snippets + # when coderay is available. + class SyntaxHighlighter + def initialize(configuration) + @configuration = configuration + end + + def highlight(lines) + implementation.highlight_syntax(lines) + end + + # rubocop:disable Lint/RescueException + # rubocop:disable Lint/HandleExceptions + def self.attempt_to_add_rspec_terms_to_coderay_keywords + CodeRay::Scanners::Ruby::Patterns::IDENT_KIND.add(%w[ + describe context + it specify + before after around + let subject + expect allow + ], :keyword) + rescue Exception + # Mutating CodeRay's contants like this is not a public API + # and might not always work. If we cannot add our keywords + # to CodeRay it is not a big deal and not worth raising an + # error over, so we ignore it. + end + # rubocop:enable Lint/HandleExceptions + # rubocop:enable Lint/RescueException + + private + + if RSpec::Support::OS.windows? + # :nocov: + def implementation + WindowsImplementation + end + # :nocov: + else + def implementation + return color_enabled_implementation if @configuration.color_enabled? + NoSyntaxHighlightingImplementation + end + end + + def color_enabled_implementation + @color_enabled_implementation ||= begin + require 'coderay' + self.class.attempt_to_add_rspec_terms_to_coderay_keywords + CodeRayImplementation + rescue LoadError + NoSyntaxHighlightingImplementation + end + end + + # @private + module CodeRayImplementation + RESET_CODE = "\e[0m" + + def self.highlight_syntax(lines) + highlighted = begin + CodeRay.encode(lines.join("\n"), :ruby, :terminal) + rescue Support::AllExceptionsExceptOnesWeMustNotRescue + return lines + end + + highlighted.split("\n").map do |line| + line.sub(/\S/) { |char| char.insert(0, RESET_CODE) } + end + end + end + + # @private + module NoSyntaxHighlightingImplementation + def self.highlight_syntax(lines) + lines + end + end + + # @private + # Not sure why, but our code above (and/or coderay itself) does not work + # on Windows, so we disable the feature on Windows. + WindowsImplementation = NoSyntaxHighlightingImplementation + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/hooks.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/hooks.rb new file mode 100644 index 00000000..2935a737 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/hooks.rb @@ -0,0 +1,646 @@ +module RSpec + module Core + # Provides `before`, `after` and `around` hooks as a means of + # supporting common setup and teardown. This module is extended + # onto {ExampleGroup}, making the methods available from any `describe` + # or `context` block and included in {Configuration}, making them + # available off of the configuration object to define global setup + # or teardown logic. + module Hooks + # @api public + # + # @overload before(&block) + # @overload before(scope, &block) + # @param scope [Symbol] `:example`, `:context`, or `:suite` + # (defaults to `:example`) + # @overload before(scope, *conditions, &block) + # @param scope [Symbol] `:example`, `:context`, or `:suite` + # (defaults to `:example`) + # @param conditions [Array, Hash] constrains this hook to + # examples matching these conditions e.g. + # `before(:example, :ui => true) { ... }` will only run with examples + # or groups declared with `:ui => true`. Symbols will be transformed + # into hash entries with `true` values. + # @overload before(conditions, &block) + # @param conditions [Hash] + # constrains this hook to examples matching these conditions e.g. + # `before(:example, :ui => true) { ... }` will only run with examples + # or groups declared with `:ui => true`. + # + # @see #after + # @see #around + # @see ExampleGroup + # @see SharedContext + # @see SharedExampleGroup + # @see Configuration + # + # Declare a block of code to be run before each example (using `:example`) + # or once before any example (using `:context`). These are usually + # declared directly in the {ExampleGroup} to which they apply, but they + # can also be shared across multiple groups. + # + # You can also use `before(:suite)` to run a block of code before any + # example groups are run. This should be declared in {RSpec.configure}. + # + # Instance variables declared in `before(:example)` or `before(:context)` + # are accessible within each example. + # + # ### Order + # + # `before` hooks are stored in three scopes, which are run in order: + # `:suite`, `:context`, and `:example`. They can also be declared in + # several different places: `RSpec.configure`, a parent group, the current + # group. They are run in the following order: + # + # before(:suite) # Declared in RSpec.configure. + # before(:context) # Declared in RSpec.configure. + # before(:context) # Declared in a parent group. + # before(:context) # Declared in the current group. + # before(:example) # Declared in RSpec.configure. + # before(:example) # Declared in a parent group. + # before(:example) # Declared in the current group. + # + # If more than one `before` is declared within any one example group, they + # are run in the order in which they are declared. Any `around` hooks will + # execute after `before` context hooks but before any `before` example + # hook regardless of where they are declared. + # + # ### Conditions + # + # When you add a conditions hash to `before(:example)` or + # `before(:context)`, RSpec will only apply that hook to groups or + # examples that match the conditions. e.g. + # + # RSpec.configure do |config| + # config.before(:example, :authorized => true) do + # log_in_as :authorized_user + # end + # end + # + # RSpec.describe Something, :authorized => true do + # # The before hook will run in before each example in this group. + # end + # + # RSpec.describe SomethingElse do + # it "does something", :authorized => true do + # # The before hook will run before this example. + # end + # + # it "does something else" do + # # The hook will not run before this example. + # end + # end + # + # Note that filtered config `:context` hooks can still be applied + # to individual examples that have matching metadata. Just like + # Ruby's object model is that every object has a singleton class + # which has only a single instance, RSpec's model is that every + # example has a singleton example group containing just the one + # example. + # + # ### Warning: `before(:suite, :with => :conditions)` + # + # The conditions hash is used to match against specific examples. Since + # `before(:suite)` is not run in relation to any specific example or + # group, conditions passed along with `:suite` are effectively ignored. + # + # ### Exceptions + # + # When an exception is raised in a `before` block, RSpec skips any + # subsequent `before` blocks and the example, but runs all of the + # `after(:example)` and `after(:context)` hooks. + # + # ### Warning: implicit before blocks + # + # `before` hooks can also be declared in shared contexts which get + # included implicitly either by you or by extension libraries. Since + # RSpec runs these in the order in which they are declared within each + # scope, load order matters, and can lead to confusing results when one + # before block depends on state that is prepared in another before block + # that gets run later. + # + # ### Warning: `before(:context)` + # + # It is very tempting to use `before(:context)` to speed things up, but we + # recommend that you avoid this as there are a number of gotchas, as well + # as things that simply don't work. + # + # #### Context + # + # `before(:context)` is run in an example that is generated to provide + # group context for the block. + # + # #### Instance variables + # + # Instance variables declared in `before(:context)` are shared across all + # the examples in the group. This means that each example can change the + # state of a shared object, resulting in an ordering dependency that can + # make it difficult to reason about failures. + # + # #### Unsupported RSpec constructs + # + # RSpec has several constructs that reset state between each example + # automatically. These are not intended for use from within + # `before(:context)`: + # + # * `let` declarations + # * `subject` declarations + # * Any mocking, stubbing or test double declaration + # + # ### other frameworks + # + # Mock object frameworks and database transaction managers (like + # ActiveRecord) are typically designed around the idea of setting up + # before an example, running that one example, and then tearing down. This + # means that mocks and stubs can (sometimes) be declared in + # `before(:context)`, but get torn down before the first real example is + # ever run. + # + # You _can_ create database-backed model objects in a `before(:context)` + # in rspec-rails, but it will not be wrapped in a transaction for you, so + # you are on your own to clean up in an `after(:context)` block. + # + # @example before(:example) declared in an {ExampleGroup} + # + # RSpec.describe Thing do + # before(:example) do + # @thing = Thing.new + # end + # + # it "does something" do + # # Here you can access @thing. + # end + # end + # + # @example before(:context) declared in an {ExampleGroup} + # + # RSpec.describe Parser do + # before(:context) do + # File.open(file_to_parse, 'w') do |f| + # f.write <<-CONTENT + # stuff in the file + # CONTENT + # end + # end + # + # it "parses the file" do + # Parser.parse(file_to_parse) + # end + # + # after(:context) do + # File.delete(file_to_parse) + # end + # end + # + # @note The `:example` and `:context` scopes are also available as + # `:each` and `:all`, respectively. Use whichever you prefer. + # @note The `:suite` scope is only supported for hooks registered on + # `RSpec.configuration` since they exist independently of any + # example or example group. + def before(*args, &block) + hooks.register :append, :before, *args, &block + end + + alias_method :append_before, :before + + # Adds `block` to the front of the list of `before` blocks in the same + # scope (`:example`, `:context`, or `:suite`). + # + # See {#before} for scoping semantics. + def prepend_before(*args, &block) + hooks.register :prepend, :before, *args, &block + end + + # @api public + # @overload after(&block) + # @overload after(scope, &block) + # @param scope [Symbol] `:example`, `:context`, or `:suite` (defaults to + # `:example`) + # @overload after(scope, *conditions, &block) + # @param scope [Symbol] `:example`, `:context`, or `:suite` (defaults to + # `:example`) + # @param conditions [Array, Hash] constrains this hook to + # examples matching these conditions e.g. + # `after(:example, :ui => true) { ... }` will only run with examples + # or groups declared with `:ui => true`. Symbols will be transformed + # into hash entries with `true` values. + # @overload after(conditions, &block) + # @param conditions [Hash] + # constrains this hook to examples matching these conditions e.g. + # `after(:example, :ui => true) { ... }` will only run with examples + # or groups declared with `:ui => true`. + # + # @see #before + # @see #around + # @see ExampleGroup + # @see SharedContext + # @see SharedExampleGroup + # @see Configuration + # + # Declare a block of code to be run after each example (using `:example`) + # or once after all examples n the context (using `:context`). See + # {#before} for more information about ordering. + # + # ### Exceptions + # + # `after` hooks are guaranteed to run even when there are exceptions in + # `before` hooks or examples. When an exception is raised in an after + # block, the exception is captured for later reporting, and subsequent + # `after` blocks are run. + # + # ### Order + # + # `after` hooks are stored in three scopes, which are run in order: + # `:example`, `:context`, and `:suite`. They can also be declared in + # several different places: `RSpec.configure`, a parent group, the current + # group. They are run in the following order: + # + # after(:example) # Declared in the current group. + # after(:example) # Declared in a parent group. + # after(:example) # Declared in RSpec.configure. + # after(:context) # Declared in the current group. + # after(:context) # Declared in a parent group. + # after(:context) # Declared in RSpec.configure. + # after(:suite) # Declared in RSpec.configure. + # + # This is the reverse of the order in which `before` hooks are run. + # Similarly, if more than one `after` is declared within any example + # group, they are run in reverse order of that in which they are declared. + # Also `around` hooks will run after any `after` example hooks are + # invoked but before any `after` context hooks. + # + # @note The `:example` and `:context` scopes are also available as + # `:each` and `:all`, respectively. Use whichever you prefer. + # @note The `:suite` scope is only supported for hooks registered on + # `RSpec.configuration` since they exist independently of any + # example or example group. + def after(*args, &block) + hooks.register :prepend, :after, *args, &block + end + + alias_method :prepend_after, :after + + # Adds `block` to the back of the list of `after` blocks in the same + # scope (`:example`, `:context`, or `:suite`). + # + # See {#after} for scoping semantics. + def append_after(*args, &block) + hooks.register :append, :after, *args, &block + end + + # @api public + # @overload around(&block) + # @overload around(scope, &block) + # @param scope [Symbol] `:example` (defaults to `:example`) + # present for syntax parity with `before` and `after`, but + # `:example`/`:each` is the only supported value. + # @overload around(scope, *conditions, &block) + # @param scope [Symbol] `:example` (defaults to `:example`) + # present for syntax parity with `before` and `after`, but + # `:example`/`:each` is the only supported value. + # @param conditions [Array, Hash] constrains this hook to + # examples matching these conditions e.g. + # `around(:example, :ui => true) { ... }` will only run with examples + # or groups declared with `:ui => true`. Symbols will be transformed + # into hash entries with `true` values. + # @overload around(conditions, &block) + # @param conditions [Hash] constrains this hook to examples matching + # these conditions e.g. `around(:example, :ui => true) { ... }` will + # only run with examples or groups declared with `:ui => true`. + # + # @yield [Example] the example to run + # + # @note the syntax of `around` is similar to that of `before` and `after` + # but the semantics are quite different. `before` and `after` hooks are + # run in the context of the examples with which they are associated, + # whereas `around` hooks are actually responsible for running the + # examples. Consequently, `around` hooks do not have direct access to + # resources that are made available within the examples and their + # associated `before` and `after` hooks. + # + # @note `:example`/`:each` is the only supported scope. + # + # Declare a block of code, parts of which will be run before and parts + # after the example. It is your responsibility to run the example: + # + # around(:example) do |ex| + # # Do some stuff before. + # ex.run + # # Do some stuff after. + # end + # + # The yielded example aliases `run` with `call`, which lets you treat it + # like a `Proc`. This is especially handy when working with libraries + # that manage their own setup and teardown using a block or proc syntax, + # e.g. + # + # around(:example) {|ex| Database.transaction(&ex)} + # around(:example) {|ex| FakeFS(&ex)} + # + # ### Order + # + # The `around` hooks execute surrounding an example and its hooks. + # + # This means after any `before` context hooks, but before any `before` + # example hooks, and similarly after any `after` example hooks but before + # any `after` context hooks. + # + # They are not a synonym for `before`/`after`. + def around(*args, &block) + hooks.register :prepend, :around, *args, &block + end + + # @private + # Holds the various registered hooks. + def hooks + @hooks ||= HookCollections.new(self, FilterableItemRepository::UpdateOptimized) + end + + # @private + Hook = Struct.new(:block, :options) + + # @private + class BeforeHook < Hook + def run(example) + example.instance_exec(example, &block) + end + end + + # @private + class AfterHook < Hook + def run(example) + example.instance_exec(example, &block) + rescue Support::AllExceptionsExceptOnesWeMustNotRescue => ex + example.set_exception(ex) + end + end + + # @private + class AfterContextHook < Hook + def run(example) + example.instance_exec(example, &block) + rescue Support::AllExceptionsExceptOnesWeMustNotRescue => e + RSpec.configuration.reporter.notify_non_example_exception(e, "An error occurred in an `after(:context)` hook.") + end + end + + # @private + class AroundHook < Hook + def execute_with(example, procsy) + example.instance_exec(procsy, &block) + return if procsy.executed? + Pending.mark_skipped!(example, + "#{hook_description} did not execute the example") + end + + if Proc.method_defined?(:source_location) + def hook_description + "around hook at #{Metadata.relative_path(block.source_location.join(':'))}" + end + else # for 1.8.7 + # :nocov: + def hook_description + "around hook" + end + # :nocov: + end + end + + # @private + # + # This provides the primary API used by other parts of rspec-core. By hiding all + # implementation details behind this facade, it's allowed us to heavily optimize + # this, so that, for example, hook collection objects are only instantiated when + # a hook is added. This allows us to avoid many object allocations for the common + # case of a group having no hooks. + # + # This is only possible because this interface provides a "tell, don't ask"-style + # API, so that callers _tell_ this class what to do with the hooks, rather than + # asking this class for a list of hooks, and then doing something with them. + class HookCollections + def initialize(owner, filterable_item_repo_class) + @owner = owner + @filterable_item_repo_class = filterable_item_repo_class + @before_example_hooks = nil + @after_example_hooks = nil + @before_context_hooks = nil + @after_context_hooks = nil + @around_example_hooks = nil + end + + def register_globals(host, globals) + parent_groups = host.parent_groups + + process(host, parent_groups, globals, :before, :example, &:options) + process(host, parent_groups, globals, :after, :example, &:options) + process(host, parent_groups, globals, :around, :example, &:options) + + process(host, parent_groups, globals, :before, :context, &:options) + process(host, parent_groups, globals, :after, :context, &:options) + end + + def register_global_singleton_context_hooks(example, globals) + parent_groups = example.example_group.parent_groups + + process(example, parent_groups, globals, :before, :context) { {} } + process(example, parent_groups, globals, :after, :context) { {} } + end + + def register(prepend_or_append, position, *args, &block) + scope, options = scope_and_options_from(*args) + + if scope == :suite + # TODO: consider making this an error in RSpec 4. For SemVer reasons, + # we are only warning in RSpec 3. + RSpec.warn_with "WARNING: `#{position}(:suite)` hooks are only supported on " \ + "the RSpec configuration object. This " \ + "`#{position}(:suite)` hook, registered on an example " \ + "group, will be ignored." + return + elsif scope == :context && position == :around + # TODO: consider making this an error in RSpec 4. For SemVer reasons, + # we are only warning in RSpec 3. + RSpec.warn_with "WARNING: `around(:context)` hooks are not supported and " \ + "behave like `around(:example)`." + end + + hook = HOOK_TYPES[position][scope].new(block, options) + ensure_hooks_initialized_for(position, scope).__send__(prepend_or_append, hook, options) + end + + # @private + # + # Runs all of the blocks stored with the hook in the context of the + # example. If no example is provided, just calls the hook directly. + def run(position, scope, example_or_group) + return if RSpec.configuration.dry_run? + + if scope == :context + unless example_or_group.class.metadata[:skip] + run_owned_hooks_for(position, :context, example_or_group) + end + else + case position + when :before then run_example_hooks_for(example_or_group, :before, :reverse_each) + when :after then run_example_hooks_for(example_or_group, :after, :each) + when :around then run_around_example_hooks_for(example_or_group) { yield } + end + end + end + + SCOPES = [:example, :context] + + SCOPE_ALIASES = { :each => :example, :all => :context } + + HOOK_TYPES = { + :before => Hash.new { BeforeHook }, + :after => Hash.new { AfterHook }, + :around => Hash.new { AroundHook } + } + + HOOK_TYPES[:after][:context] = AfterContextHook + + protected + + EMPTY_HOOK_ARRAY = [].freeze + + def matching_hooks_for(position, scope, example_or_group) + repository = hooks_for(position, scope) { return EMPTY_HOOK_ARRAY } + + # It would be nice to not have to switch on type here, but + # we don't want to define `ExampleGroup#metadata` because then + # `metadata` from within an individual example would return the + # group's metadata but the user would probably expect it to be + # the example's metadata. + metadata = case example_or_group + when ExampleGroup then example_or_group.class.metadata + else example_or_group.metadata + end + + repository.items_for(metadata) + end + + def all_hooks_for(position, scope) + hooks_for(position, scope) { return EMPTY_HOOK_ARRAY }.items_and_filters.map(&:first) + end + + def run_owned_hooks_for(position, scope, example_or_group) + matching_hooks_for(position, scope, example_or_group).each do |hook| + hook.run(example_or_group) + end + end + + def processable_hooks_for(position, scope, host) + if scope == :example + all_hooks_for(position, scope) + else + matching_hooks_for(position, scope, host) + end + end + + private + + def hooks_for(position, scope) + if position == :before + scope == :example ? @before_example_hooks : @before_context_hooks + elsif position == :after + scope == :example ? @after_example_hooks : @after_context_hooks + else # around + @around_example_hooks + end || yield + end + + def ensure_hooks_initialized_for(position, scope) + if position == :before + if scope == :example + @before_example_hooks ||= @filterable_item_repo_class.new(:all?) + else + @before_context_hooks ||= @filterable_item_repo_class.new(:all?) + end + elsif position == :after + if scope == :example + @after_example_hooks ||= @filterable_item_repo_class.new(:all?) + else + @after_context_hooks ||= @filterable_item_repo_class.new(:all?) + end + else # around + @around_example_hooks ||= @filterable_item_repo_class.new(:all?) + end + end + + def process(host, parent_groups, globals, position, scope) + hooks_to_process = globals.processable_hooks_for(position, scope, host) + return if hooks_to_process.empty? + + hooks_to_process -= FlatMap.flat_map(parent_groups) do |group| + group.hooks.all_hooks_for(position, scope) + end + return if hooks_to_process.empty? + + repository = ensure_hooks_initialized_for(position, scope) + hooks_to_process.each { |hook| repository.append hook, (yield hook) } + end + + def scope_and_options_from(*args) + return :suite if args.first == :suite + scope = extract_scope_from(args) + meta = Metadata.build_hash_from(args, :warn_about_example_group_filtering) + return scope, meta + end + + def extract_scope_from(args) + if known_scope?(args.first) + normalized_scope_for(args.shift) + elsif args.any? { |a| a.is_a?(Symbol) } + error_message = "You must explicitly give a scope " \ + "(#{SCOPES.join(", ")}) or scope alias " \ + "(#{SCOPE_ALIASES.keys.join(", ")}) when using symbols as " \ + "metadata for a hook." + raise ArgumentError.new error_message + else + :example + end + end + + def known_scope?(scope) + SCOPES.include?(scope) || SCOPE_ALIASES.keys.include?(scope) + end + + def normalized_scope_for(scope) + SCOPE_ALIASES[scope] || scope + end + + def run_example_hooks_for(example, position, each_method) + owner_parent_groups.__send__(each_method) do |group| + group.hooks.run_owned_hooks_for(position, :example, example) + end + end + + def run_around_example_hooks_for(example) + hooks = FlatMap.flat_map(owner_parent_groups) do |group| + group.hooks.matching_hooks_for(:around, :example, example) + end + + return yield if hooks.empty? # exit early to avoid the extra allocation cost of `Example::Procsy` + + initial_procsy = Example::Procsy.new(example) { yield } + hooks.inject(initial_procsy) do |procsy, around_hook| + procsy.wrap { around_hook.execute_with(example, procsy) } + end.call + end + + if respond_to?(:singleton_class) && singleton_class.ancestors.include?(singleton_class) + def owner_parent_groups + @owner.parent_groups + end + else # Ruby < 2.1 (see https://bugs.ruby-lang.org/issues/8035) + # :nocov: + def owner_parent_groups + @owner_parent_groups ||= [@owner] + @owner.parent_groups + end + # :nocov: + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/invocations.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/invocations.rb new file mode 100644 index 00000000..4719085b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/invocations.rb @@ -0,0 +1,87 @@ +module RSpec + module Core + # @private + module Invocations + # @private + class InitializeProject + def call(*_args) + RSpec::Support.require_rspec_core "project_initializer" + ProjectInitializer.new.run + 0 + end + end + + # @private + class DRbWithFallback + def call(options, err, out) + require 'rspec/core/drb' + begin + return DRbRunner.new(options).run(err, out) + rescue DRb::DRbConnError + err.puts "No DRb server is running. Running in local process instead ..." + end + RSpec::Core::Runner.new(options).run(err, out) + end + end + + # @private + class Bisect + def call(options, err, out) + RSpec::Support.require_rspec_core "bisect/coordinator" + runner = Runner.new(options).tap { |r| r.configure(err, out) } + formatter = bisect_formatter_klass_for(options.options[:bisect]).new( + out, runner.configuration.bisect_runner + ) + + success = RSpec::Core::Bisect::Coordinator.bisect_with( + runner, options.args, formatter + ) + + runner.exit_code(success) + end + + private + + def bisect_formatter_klass_for(argument) + return Formatters::BisectDebugFormatter if argument == "verbose" + Formatters::BisectProgressFormatter + end + end + + # @private + class PrintVersion + def call(_options, _err, out) + overall_version = RSpec::Core::Version::STRING + unless overall_version =~ /[a-zA-Z]+/ + overall_version = overall_version.split('.').first(2).join('.') + end + + out.puts "RSpec #{overall_version}" + + [:Core, :Expectations, :Mocks, :Rails, :Support].each do |const_name| + lib_name = const_name.to_s.downcase + begin + require "rspec/#{lib_name}/version" + rescue LoadError + # Not worth mentioning libs that are not installed + nil + else + out.puts " - rspec-#{lib_name} #{RSpec.const_get(const_name)::Version::STRING}" + end + end + + 0 + end + end + + # @private + PrintHelp = Struct.new(:parser, :hidden_options) do + def call(_options, _err, out) + # Removing the hidden options from the output. + out.puts parser.to_s.gsub(/^\s+(#{hidden_options.join('|')})\b.*$\n/, '') + 0 + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/memoized_helpers.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/memoized_helpers.rb new file mode 100644 index 00000000..adcfce7a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/memoized_helpers.rb @@ -0,0 +1,580 @@ +RSpec::Support.require_rspec_support 'reentrant_mutex' + +module RSpec + module Core + # This module is included in {ExampleGroup}, making the methods + # available to be called from within example blocks. + # + # @see ClassMethods + module MemoizedHelpers + # @note `subject` was contributed by Joe Ferris to support the one-liner + # syntax embraced by shoulda matchers: + # + # RSpec.describe Widget do + # it { is_expected.to validate_presence_of(:name) } + # # or + # it { should validate_presence_of(:name) } + # end + # + # While the examples below demonstrate how to use `subject` + # explicitly in examples, we recommend that you define a method with + # an intention revealing name instead. + # + # @example + # + # # Explicit declaration of subject. + # RSpec.describe Person do + # subject { Person.new(:birthdate => 19.years.ago) } + # it "should be eligible to vote" do + # subject.should be_eligible_to_vote + # # ^ ^ explicit reference to subject not recommended + # end + # end + # + # # Implicit subject => { Person.new }. + # RSpec.describe Person do + # it "should be eligible to vote" do + # subject.should be_eligible_to_vote + # # ^ ^ explicit reference to subject not recommended + # end + # end + # + # # One-liner syntax - expectation is set on the subject. + # RSpec.describe Person do + # it { is_expected.to be_eligible_to_vote } + # # or + # it { should be_eligible_to_vote } + # end + # + # @note Because `subject` is designed to create state that is reset + # between each example, and `before(:context)` is designed to setup + # state that is shared across _all_ examples in an example group, + # `subject` is _not_ intended to be used in a `before(:context)` hook. + # + # @see #should + # @see #should_not + # @see #is_expected + def subject + __memoized.fetch_or_store(:subject) do + described = described_class || self.class.metadata.fetch(:description_args).first + Class === described ? described.new : described + end + end + + # When `should` is called with no explicit receiver, the call is + # delegated to the object returned by `subject`. Combined with an + # implicit subject this supports very concise expressions. + # + # @example + # + # RSpec.describe Person do + # it { should be_eligible_to_vote } + # end + # + # @see #subject + # @see #is_expected + # + # @note This only works if you are using rspec-expectations. + # @note If you are using RSpec's newer expect-based syntax you may + # want to use `is_expected.to` instead of `should`. + def should(matcher=nil, message=nil) + enforce_value_expectation(matcher, 'should') + RSpec::Expectations::PositiveExpectationHandler.handle_matcher(subject, matcher, message) + end + + # Just like `should`, `should_not` delegates to the subject (implicit or + # explicit) of the example group. + # + # @example + # + # RSpec.describe Person do + # it { should_not be_eligible_to_vote } + # end + # + # @see #subject + # @see #is_expected + # + # @note This only works if you are using rspec-expectations. + # @note If you are using RSpec's newer expect-based syntax you may + # want to use `is_expected.to_not` instead of `should_not`. + def should_not(matcher=nil, message=nil) + enforce_value_expectation(matcher, 'should_not') + RSpec::Expectations::NegativeExpectationHandler.handle_matcher(subject, matcher, message) + end + + # Wraps the `subject` in `expect` to make it the target of an expectation. + # Designed to read nicely for one-liners. + # + # @example + # + # describe [1, 2, 3] do + # it { is_expected.to be_an Array } + # it { is_expected.not_to include 4 } + # end + # + # @see #subject + # @see #should + # @see #should_not + # + # @note This only works if you are using rspec-expectations. + def is_expected + expect(subject) + end + + # @private + # should just be placed in private section, + # but Ruby issues warnings on private attributes. + # and expanding it to the equivalent method upsets Rubocop, + # b/c it should obviously be a reader + attr_reader :__memoized + private :__memoized + + private + + # @private + def initialize(*) + __init_memoized + super + end + + # @private + def __init_memoized + @__memoized = if RSpec.configuration.threadsafe? + ThreadsafeMemoized.new + else + NonThreadSafeMemoized.new + end + end + + # @private + def enforce_value_expectation(matcher, method_name) + return if matcher_supports_value_expectations?(matcher) + + RSpec.deprecate( + "#{method_name} #{RSpec::Support::ObjectFormatter.format(matcher)}", + :message => + "The implicit block expectation syntax is deprecated, you should pass " \ + "a block to `expect` to use the provided block expectation matcher " \ + "(#{RSpec::Support::ObjectFormatter.format(matcher)}), " \ + "or the matcher must implement `supports_value_expectations?`." + ) + end + + def matcher_supports_value_expectations?(matcher) + matcher.supports_value_expectations? + rescue + true + end + + # @private + class ThreadsafeMemoized + def initialize + @memoized = {} + @mutex = Support::ReentrantMutex.new + end + + def fetch_or_store(key) + @memoized.fetch(key) do # only first access pays for synchronization + @mutex.synchronize do + @memoized.fetch(key) { @memoized[key] = yield } + end + end + end + end + + # @private + class NonThreadSafeMemoized + def initialize + @memoized = {} + end + + def fetch_or_store(key) + @memoized.fetch(key) { @memoized[key] = yield } + end + end + + # Used internally to customize the behavior of the + # memoized hash when used in a `before(:context)` hook. + # + # @private + class ContextHookMemoized + def self.isolate_for_context_hook(example_group_instance) + exploding_memoized = self + + example_group_instance.instance_exec do + @__memoized = exploding_memoized + + begin + yield + ensure + # This is doing a reset instead of just isolating for context hook. + # Really, this should set the old @__memoized back into place. + # + # Caller is the before and after context hooks + # which are both called from self.run + # I didn't look at why it made tests fail, maybe an object was getting reused in RSpec tests, + # if so, then that probably already works, and its the tests that are wrong. + __init_memoized + end + end + end + + def self.fetch_or_store(key, &_block) + description = if key == :subject + "subject" + else + "let declaration `#{key}`" + end + + raise <<-EOS +#{description} accessed in #{article} #{hook_expression} hook at: + #{CallerFilter.first_non_rspec_line} + +`let` and `subject` declarations are not intended to be called +in #{article} #{hook_expression} hook, as they exist to define state that +is reset between each example, while #{hook_expression} exists to +#{hook_intention}. +EOS + end + + # @private + class Before < self + def self.hook_expression + "`before(:context)`" + end + + def self.article + "a" + end + + def self.hook_intention + "define state that is shared across examples in an example group" + end + end + + # @private + class After < self + def self.hook_expression + "`after(:context)`" + end + + def self.article + "an" + end + + def self.hook_intention + "cleanup state that is shared across examples in an example group" + end + end + end + + # This module is extended onto {ExampleGroup}, making the methods + # available to be called from within example group blocks. + # You can think of them as being analagous to class macros. + module ClassMethods + # Generates a method whose return value is memoized after the first + # call. Useful for reducing duplication between examples that assign + # values to the same local variable. + # + # @note `let` _can_ enhance readability when used sparingly (1,2, or + # maybe 3 declarations) in any given example group, but that can + # quickly degrade with overuse. YMMV. + # + # @note `let` can be configured to be threadsafe or not. + # If it is threadsafe, it will take longer to access the value. + # If it is not threadsafe, it may behave in surprising ways in examples + # that spawn separate threads. Specify this on `RSpec.configure` + # + # @note Because `let` is designed to create state that is reset between + # each example, and `before(:context)` is designed to setup state that + # is shared across _all_ examples in an example group, `let` is _not_ + # intended to be used in a `before(:context)` hook. + # + # @example + # + # RSpec.describe Thing do + # let(:thing) { Thing.new } + # + # it "does something" do + # # First invocation, executes block, memoizes and returns result. + # thing.do_something + # + # # Second invocation, returns the memoized value. + # thing.should be_something + # end + # end + def let(name, &block) + # We have to pass the block directly to `define_method` to + # allow it to use method constructs like `super` and `return`. + raise "#let or #subject called without a block" if block.nil? + + # A list of reserved words that can't be used as a name for a memoized helper + # Matches for both symbols and passed strings + if [:initialize, :to_s].include?(name.to_sym) + raise ArgumentError, "#let or #subject called with reserved name `#{name}`" + end + + our_module = MemoizedHelpers.module_for(self) + + # If we have a module clash in our helper module + # then we need to remove it to prevent a warning. + # + # Note we do not check ancestor modules (see: `instance_methods(false)`) + # as we can override them. + if our_module.instance_methods(false).include?(name) + our_module.__send__(:remove_method, name) + end + our_module.__send__(:define_method, name, &block) + + # If we have a module clash in the example module + # then we need to remove it to prevent a warning. + # + # Note we do not check ancestor modules (see: `instance_methods(false)`) + # as we can override them. + if instance_methods(false).include?(name) + remove_method(name) + end + + # Apply the memoization. The method has been defined in an ancestor + # module so we can use `super` here to get the value. + if block.arity == 1 + define_method(name) { __memoized.fetch_or_store(name) { super(RSpec.current_example, &nil) } } + else + define_method(name) { __memoized.fetch_or_store(name) { super(&nil) } } + end + end + + # Just like `let`, except the block is invoked by an implicit `before` + # hook. This serves a dual purpose of setting up state and providing a + # memoized reference to that state. + # + # @example + # + # class Thing + # def self.count + # @count ||= 0 + # end + # + # def self.count=(val) + # @count += val + # end + # + # def self.reset_count + # @count = 0 + # end + # + # def initialize + # self.class.count += 1 + # end + # end + # + # RSpec.describe Thing do + # after(:example) { Thing.reset_count } + # + # context "using let" do + # let(:thing) { Thing.new } + # + # it "is not invoked implicitly" do + # Thing.count.should eq(0) + # end + # + # it "can be invoked explicitly" do + # thing + # Thing.count.should eq(1) + # end + # end + # + # context "using let!" do + # let!(:thing) { Thing.new } + # + # it "is invoked implicitly" do + # Thing.count.should eq(1) + # end + # + # it "returns memoized version on first invocation" do + # thing + # Thing.count.should eq(1) + # end + # end + # end + def let!(name, &block) + let(name, &block) + before { __send__(name) } + end + + # Declares a `subject` for an example group which can then be wrapped + # with `expect` using `is_expected` to make it the target of an + # expectation in a concise, one-line example. + # + # Given a `name`, defines a method with that name which returns the + # `subject`. This lets you declare the subject once and access it + # implicitly in one-liners and explicitly using an intention revealing + # name. + # + # When given a `name`, calling `super` in the block is not supported. + # + # @note `subject` can be configured to be threadsafe or not. + # If it is threadsafe, it will take longer to access the value. + # If it is not threadsafe, it may behave in surprising ways in examples + # that spawn separate threads. Specify this on `RSpec.configure` + # + # @param name [String,Symbol] used to define an accessor with an + # intention revealing name + # @param block defines the value to be returned by `subject` in examples + # + # @example + # + # RSpec.describe CheckingAccount, "with $50" do + # subject { CheckingAccount.new(Money.new(50, :USD)) } + # it { is_expected.to have_a_balance_of(Money.new(50, :USD)) } + # it { is_expected.not_to be_overdrawn } + # end + # + # RSpec.describe CheckingAccount, "with a non-zero starting balance" do + # subject(:account) { CheckingAccount.new(Money.new(50, :USD)) } + # it { is_expected.not_to be_overdrawn } + # it "has a balance equal to the starting balance" do + # account.balance.should eq(Money.new(50, :USD)) + # end + # end + # + # @see MemoizedHelpers#should + # @see MemoizedHelpers#should_not + # @see MemoizedHelpers#is_expected + def subject(name=nil, &block) + if name + let(name, &block) + alias_method :subject, name + + self::NamedSubjectPreventSuper.__send__(:define_method, name) do + raise NotImplementedError, "`super` in named subjects is not supported" + end + else + let(:subject, &block) + end + end + + # Just like `subject`, except the block is invoked by an implicit + # `before` hook. This serves a dual purpose of setting up state and + # providing a memoized reference to that state. + # + # @example + # + # class Thing + # def self.count + # @count ||= 0 + # end + # + # def self.count=(val) + # @count += val + # end + # + # def self.reset_count + # @count = 0 + # end + # + # def initialize + # self.class.count += 1 + # end + # end + # + # RSpec.describe Thing do + # after(:example) { Thing.reset_count } + # + # context "using subject" do + # subject { Thing.new } + # + # it "is not invoked implicitly" do + # Thing.count.should eq(0) + # end + # + # it "can be invoked explicitly" do + # subject + # Thing.count.should eq(1) + # end + # end + # + # context "using subject!" do + # subject!(:thing) { Thing.new } + # + # it "is invoked implicitly" do + # Thing.count.should eq(1) + # end + # + # it "returns memoized version on first invocation" do + # subject + # Thing.count.should eq(1) + # end + # end + # end + def subject!(name=nil, &block) + subject(name, &block) + before { subject } + end + end + + # @private + # + # Gets the LetDefinitions module. The module is mixed into + # the example group and is used to hold all let definitions. + # This is done so that the block passed to `let` can be + # forwarded directly on to `define_method`, so that all method + # constructs (including `super` and `return`) can be used in + # a `let` block. + # + # The memoization is provided by a method definition on the + # example group that supers to the LetDefinitions definition + # in order to get the value to memoize. + def self.module_for(example_group) + get_constant_or_yield(example_group, :LetDefinitions) do + mod = Module.new do + include(Module.new { + example_group.const_set(:NamedSubjectPreventSuper, self) + }) + end + + example_group.const_set(:LetDefinitions, mod) + mod + end + end + + # @private + def self.define_helpers_on(example_group) + example_group.__send__(:include, module_for(example_group)) + end + + if Module.method(:const_defined?).arity == 1 # for 1.8 + # @private + # + # Gets the named constant or yields. + # On 1.8, const_defined? / const_get do not take into + # account the inheritance hierarchy. + # :nocov: + def self.get_constant_or_yield(example_group, name) + if example_group.const_defined?(name) + example_group.const_get(name) + else + yield + end + end + # :nocov: + else + # @private + # + # Gets the named constant or yields. + # On 1.9, const_defined? / const_get take into account the + # the inheritance by default, and accept an argument to + # disable this behavior. It's important that we don't + # consider inheritance here; each example group level that + # uses a `let` should get its own `LetDefinitions` module. + def self.get_constant_or_yield(example_group, name) + if example_group.const_defined?(name, (check_ancestors = false)) + example_group.const_get(name, check_ancestors) + else + yield + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/metadata.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/metadata.rb new file mode 100644 index 00000000..9034214c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/metadata.rb @@ -0,0 +1,498 @@ +module RSpec + module Core + # Each ExampleGroup class and Example instance owns an instance of + # Metadata, which is Hash extended to support lazy evaluation of values + # associated with keys that may or may not be used by any example or group. + # + # In addition to metadata that is used internally, this also stores + # user-supplied metadata, e.g. + # + # RSpec.describe Something, :type => :ui do + # it "does something", :slow => true do + # # ... + # end + # end + # + # `:type => :ui` is stored in the Metadata owned by the example group, and + # `:slow => true` is stored in the Metadata owned by the example. These can + # then be used to select which examples are run using the `--tag` option on + # the command line, or several methods on `Configuration` used to filter a + # run (e.g. `filter_run_including`, `filter_run_excluding`, etc). + # + # @see Example#metadata + # @see ExampleGroup.metadata + # @see FilterManager + # @see Configuration#filter_run_including + # @see Configuration#filter_run_excluding + module Metadata + # Matches strings either at the beginning of the input or prefixed with a + # whitespace, containing the current path, either postfixed with the + # separator, or at the end of the string. Match groups are the character + # before and the character after the string if any. + # + # http://rubular.com/r/fT0gmX6VJX + # http://rubular.com/r/duOrD4i3wb + # http://rubular.com/r/sbAMHFrOx1 + def self.relative_path_regex + @relative_path_regex ||= /(\A|\s)#{File.expand_path('.')}(#{File::SEPARATOR}|\s|\Z)/ + end + + # @api private + # + # @param line [String] current code line + # @return [String] relative path to line + def self.relative_path(line) + line = line.sub(relative_path_regex, "\\1.\\2".freeze) + line = line.sub(/\A([^:]+:\d+)$/, '\\1'.freeze) + return nil if line == '-e:1'.freeze + line + rescue SecurityError + # :nocov: - SecurityError is no longer produced starting in ruby 2.7 + nil + # :nocov: + end + + # @private + # Iteratively walks up from the given metadata through all + # example group ancestors, yielding each metadata hash along the way. + def self.ascending(metadata) + yield metadata + return unless (group_metadata = metadata.fetch(:example_group) { metadata[:parent_example_group] }) + + loop do + yield group_metadata + break unless (group_metadata = group_metadata[:parent_example_group]) + end + end + + # @private + # Returns an enumerator that iteratively walks up the given metadata through all + # example group ancestors, yielding each metadata hash along the way. + def self.ascend(metadata) + enum_for(:ascending, metadata) + end + + # @private + # Used internally to build a hash from an args array. + # Symbols are converted into hash keys with a value of `true`. + # This is done to support simple tagging using a symbol, rather + # than needing to do `:symbol => true`. + def self.build_hash_from(args, warn_about_example_group_filtering=false) + hash = args.last.is_a?(Hash) ? args.pop : {} + + hash[args.pop] = true while args.last.is_a?(Symbol) + + if warn_about_example_group_filtering && hash.key?(:example_group) + RSpec.deprecate("Filtering by an `:example_group` subhash", + :replacement => "the subhash to filter directly") + end + + hash + end + + # @private + def self.deep_hash_dup(object) + return object.dup if Array === object + return object unless Hash === object + + object.inject(object.dup) do |duplicate, (key, value)| + duplicate[key] = deep_hash_dup(value) + duplicate + end + end + + # @private + def self.id_from(metadata) + "#{metadata[:rerun_file_path]}[#{metadata[:scoped_id]}]" + end + + # @private + def self.location_tuple_from(metadata) + [metadata[:absolute_file_path], metadata[:line_number]] + end + + # @private + # Used internally to populate metadata hashes with computed keys + # managed by RSpec. + class HashPopulator + attr_reader :metadata, :user_metadata, :description_args, :block + + def initialize(metadata, user_metadata, index_provider, description_args, block) + @metadata = metadata + @user_metadata = user_metadata + @index_provider = index_provider + @description_args = description_args + @block = block + end + + def populate + ensure_valid_user_keys + + metadata[:block] = block + metadata[:description_args] = description_args + metadata[:description] = build_description_from(*metadata[:description_args]) + metadata[:full_description] = full_description + metadata[:described_class] = described_class + + populate_location_attributes + metadata.update(user_metadata) + end + + private + + def populate_location_attributes + backtrace = user_metadata.delete(:caller) + + file_path, line_number = if backtrace + file_path_and_line_number_from(backtrace) + elsif block.respond_to?(:source_location) + block.source_location + else + file_path_and_line_number_from(caller) + end + + relative_file_path = Metadata.relative_path(file_path) + absolute_file_path = File.expand_path(relative_file_path) + metadata[:file_path] = relative_file_path + metadata[:line_number] = line_number.to_i + metadata[:location] = "#{relative_file_path}:#{line_number}" + metadata[:absolute_file_path] = absolute_file_path + metadata[:rerun_file_path] ||= relative_file_path + metadata[:scoped_id] = build_scoped_id_for(absolute_file_path) + end + + def file_path_and_line_number_from(backtrace) + first_caller_from_outside_rspec = backtrace.find { |l| l !~ CallerFilter::LIB_REGEX } + first_caller_from_outside_rspec ||= backtrace.first + /(.+?):(\d+)(?:|:\d+)/.match(first_caller_from_outside_rspec).captures + end + + def description_separator(parent_part, child_part) + if parent_part.is_a?(Module) && /^(?:#|::|\.)/.match(child_part.to_s) + ''.freeze + else + ' '.freeze + end + end + + def build_description_from(parent_description=nil, my_description=nil) + return parent_description.to_s unless my_description + return my_description.to_s if parent_description.to_s == '' + separator = description_separator(parent_description, my_description) + (parent_description.to_s + separator) << my_description.to_s + end + + def build_scoped_id_for(file_path) + index = @index_provider.call(file_path).to_s + parent_scoped_id = metadata.fetch(:scoped_id) { return index } + "#{parent_scoped_id}:#{index}" + end + + def ensure_valid_user_keys + RESERVED_KEYS.each do |key| + next unless user_metadata.key?(key) + raise <<-EOM.gsub(/^\s+\|/, '') + |#{"*" * 50} + |:#{key} is not allowed + | + |RSpec reserves some hash keys for its own internal use, + |including :#{key}, which is used on: + | + | #{CallerFilter.first_non_rspec_line}. + | + |Here are all of RSpec's reserved hash keys: + | + | #{RESERVED_KEYS.join("\n ")} + |#{"*" * 50} + EOM + end + end + end + + # @private + class ExampleHash < HashPopulator + def self.create(group_metadata, user_metadata, index_provider, description, block) + example_metadata = group_metadata.dup + group_metadata = Hash.new(&ExampleGroupHash.backwards_compatibility_default_proc do |hash| + hash[:parent_example_group] + end) + group_metadata.update(example_metadata) + + example_metadata[:execution_result] = Example::ExecutionResult.new + example_metadata[:example_group] = group_metadata + example_metadata[:shared_group_inclusion_backtrace] = SharedExampleGroupInclusionStackFrame.current_backtrace + example_metadata.delete(:parent_example_group) + + description_args = description.nil? ? [] : [description] + hash = new(example_metadata, user_metadata, index_provider, description_args, block) + hash.populate + hash.metadata + end + + private + + def described_class + metadata[:example_group][:described_class] + end + + def full_description + build_description_from( + metadata[:example_group][:full_description], + metadata[:description] + ) + end + end + + # @private + class ExampleGroupHash < HashPopulator + def self.create(parent_group_metadata, user_metadata, example_group_index, *args, &block) + group_metadata = hash_with_backwards_compatibility_default_proc + + if parent_group_metadata + group_metadata.update(parent_group_metadata) + group_metadata[:parent_example_group] = parent_group_metadata + end + + hash = new(group_metadata, user_metadata, example_group_index, args, block) + hash.populate + hash.metadata + end + + def self.hash_with_backwards_compatibility_default_proc + Hash.new(&backwards_compatibility_default_proc { |hash| hash }) + end + + def self.backwards_compatibility_default_proc(&example_group_selector) + Proc.new do |hash, key| + case key + when :example_group + # We commonly get here when rspec-core is applying a previously + # configured filter rule, such as when a gem configures: + # + # RSpec.configure do |c| + # c.include MyGemHelpers, :example_group => { :file_path => /spec\/my_gem_specs/ } + # end + # + # It's confusing for a user to get a deprecation at this point in + # the code, so instead we issue a deprecation from the config APIs + # that take a metadata hash, and MetadataFilter sets this thread + # local to silence the warning here since it would be so + # confusing. + unless RSpec::Support.thread_local_data[:silence_metadata_example_group_deprecations] + RSpec.deprecate("The `:example_group` key in an example group's metadata hash", + :replacement => "the example group's hash directly for the " \ + "computed keys and `:parent_example_group` to access the parent " \ + "example group metadata") + end + + group_hash = example_group_selector.call(hash) + LegacyExampleGroupHash.new(group_hash) if group_hash + when :example_group_block + RSpec.deprecate("`metadata[:example_group_block]`", + :replacement => "`metadata[:block]`") + hash[:block] + when :describes + RSpec.deprecate("`metadata[:describes]`", + :replacement => "`metadata[:described_class]`") + hash[:described_class] + end + end + end + + private + + def described_class + candidate = metadata[:description_args].first + return candidate unless NilClass === candidate || String === candidate + parent_group = metadata[:parent_example_group] + parent_group && parent_group[:described_class] + end + + def full_description + description = metadata[:description] + parent_example_group = metadata[:parent_example_group] + return description unless parent_example_group + + parent_description = parent_example_group[:full_description] + separator = description_separator(parent_example_group[:description_args].last, + metadata[:description_args].first) + + parent_description + separator + description + end + end + + # @private + RESERVED_KEYS = [ + :description, + :description_args, + :described_class, + :example_group, + :parent_example_group, + :execution_result, + :last_run_status, + :file_path, + :absolute_file_path, + :rerun_file_path, + :full_description, + :line_number, + :location, + :scoped_id, + :block, + :shared_group_inclusion_backtrace + ] + end + + # Mixin that makes the including class imitate a hash for backwards + # compatibility. The including class should use `attr_accessor` to + # declare attributes. + # @private + module HashImitatable + def self.included(klass) + klass.extend ClassMethods + end + + def to_h + hash = extra_hash_attributes.dup + + self.class.hash_attribute_names.each do |name| + hash[name] = __send__(name) + end + + hash + end + + (Hash.public_instance_methods - Object.public_instance_methods).each do |method_name| + next if [:[], :[]=, :to_h].include?(method_name.to_sym) + + define_method(method_name) do |*args, &block| + issue_deprecation(method_name, *args) + + hash = hash_for_delegation + self.class.hash_attribute_names.each do |name| + hash.delete(name) unless instance_variable_defined?(:"@#{name}") + end + + hash.__send__(method_name, *args, &block).tap do + # apply mutations back to the object + hash.each do |name, value| + if directly_supports_attribute?(name) + set_value(name, value) + else + extra_hash_attributes[name] = value + end + end + end + end + end + + def [](key) + issue_deprecation(:[], key) + + if directly_supports_attribute?(key) + get_value(key) + else + extra_hash_attributes[key] + end + end + + def []=(key, value) + issue_deprecation(:[]=, key, value) + + if directly_supports_attribute?(key) + set_value(key, value) + else + extra_hash_attributes[key] = value + end + end + + private + + def extra_hash_attributes + @extra_hash_attributes ||= {} + end + + def directly_supports_attribute?(name) + self.class.hash_attribute_names.include?(name) + end + + def get_value(name) + __send__(name) + end + + def set_value(name, value) + __send__(:"#{name}=", value) + end + + def hash_for_delegation + to_h + end + + def issue_deprecation(_method_name, *_args) + # no-op by default: subclasses can override + end + + # @private + module ClassMethods + def hash_attribute_names + @hash_attribute_names ||= [] + end + + def attr_accessor(*names) + hash_attribute_names.concat(names) + super + end + end + end + + # @private + # Together with the example group metadata hash default block, + # provides backwards compatibility for the old `:example_group` + # key. In RSpec 2.x, the computed keys of a group's metadata + # were exposed from a nested subhash keyed by `[:example_group]`, and + # then the parent group's metadata was exposed by sub-subhash + # keyed by `[:example_group][:example_group]`. + # + # In RSpec 3, we reorganized this to that the computed keys are + # exposed directly of the group metadata hash (no nesting), and + # `:parent_example_group` returns the parent group's metadata. + # + # Maintaining backwards compatibility was difficult: we wanted + # `:example_group` to return an object that: + # + # * Exposes the top-level metadata keys that used to be nested + # under `:example_group`. + # * Supports mutation (rspec-rails, for example, assigns + # `metadata[:example_group][:described_class]` when you use + # anonymous controller specs) such that changes are written + # back to the top-level metadata hash. + # * Exposes the parent group metadata as + # `[:example_group][:example_group]`. + class LegacyExampleGroupHash + include HashImitatable + + def initialize(metadata) + @metadata = metadata + parent_group_metadata = metadata.fetch(:parent_example_group) { {} }[:example_group] + self[:example_group] = parent_group_metadata if parent_group_metadata + end + + def to_h + super.merge(@metadata) + end + + private + + def directly_supports_attribute?(name) + name != :example_group + end + + def get_value(name) + @metadata[name] + end + + def set_value(name, value) + @metadata[name] = value + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/metadata_filter.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/metadata_filter.rb new file mode 100644 index 00000000..2e63baf9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/metadata_filter.rb @@ -0,0 +1,255 @@ +module RSpec + module Core + # Contains metadata filtering logic. This has been extracted from + # the metadata classes because it operates ON a metadata hash but + # does not manage any of the state in the hash. We're moving towards + # having metadata be a raw hash (not a custom subclass), so externalizing + # this filtering logic helps us move in that direction. + module MetadataFilter + class << self + # @private + def apply?(predicate, filters, metadata) + filters.__send__(predicate) { |k, v| filter_applies?(k, v, metadata) } + end + + # @private + def filter_applies?(key, filter_value, metadata) + silence_metadata_example_group_deprecations do + return location_filter_applies?(filter_value, metadata) if key == :locations + return id_filter_applies?(filter_value, metadata) if key == :ids + return filters_apply?(key, filter_value, metadata) if Hash === filter_value + + meta_value = metadata.fetch(key) { return false } + + return true if TrueClass === filter_value && meta_value + return proc_filter_applies?(key, filter_value, metadata) if Proc === filter_value + return filter_applies_to_any_value?(key, filter_value, metadata) if Array === meta_value + + filter_value === meta_value || filter_value.to_s == meta_value.to_s + end + end + + # @private + def silence_metadata_example_group_deprecations + RSpec::Support.thread_local_data[:silence_metadata_example_group_deprecations] = true + yield + ensure + RSpec::Support.thread_local_data.delete(:silence_metadata_example_group_deprecations) + end + + private + + def filter_applies_to_any_value?(key, value, metadata) + metadata[key].any? { |v| filter_applies?(key, v, key => value) } + end + + def id_filter_applies?(rerun_paths_to_scoped_ids, metadata) + scoped_ids = rerun_paths_to_scoped_ids.fetch(metadata[:rerun_file_path]) { return false } + + Metadata.ascend(metadata).any? do |meta| + scoped_ids.include?(meta[:scoped_id]) + end + end + + def location_filter_applies?(locations, metadata) + Metadata.ascend(metadata).any? do |meta| + file_path = meta[:absolute_file_path] + line_num = meta[:line_number] + + locations[file_path].any? do |filter_line_num| + line_num == RSpec.world.preceding_declaration_line(file_path, filter_line_num) + end + end + end + + def proc_filter_applies?(key, proc, metadata) + case proc.arity + when 0 then proc.call + when 2 then proc.call(metadata[key], metadata) + else proc.call(metadata[key]) + end + end + + def filters_apply?(key, value, metadata) + subhash = metadata[key] + return false unless Hash === subhash || HashImitatable === subhash + value.all? { |k, v| filter_applies?(k, v, subhash) } + end + end + end + + # Tracks a collection of filterable items (e.g. modules, hooks, etc) + # and provides an optimized API to get the applicable items for the + # metadata of an example or example group. + # + # There are two implementations, optimized for different uses. + # @private + module FilterableItemRepository + # This implementation is simple, and is optimized for frequent + # updates but rare queries. `append` and `prepend` do no extra + # processing, and no internal memoization is done, since this + # is not optimized for queries. + # + # This is ideal for use by a example or example group, which may + # be updated multiple times with globally configured hooks, etc, + # but will not be queried frequently by other examples or example + # groups. + # @private + class UpdateOptimized + attr_reader :items_and_filters + + def initialize(applies_predicate) + @applies_predicate = applies_predicate + @items_and_filters = [] + end + + def append(item, metadata) + @items_and_filters << [item, metadata] + end + + def prepend(item, metadata) + @items_and_filters.unshift [item, metadata] + end + + def delete(item, metadata) + @items_and_filters.delete [item, metadata] + end + + def items_for(request_meta) + @items_and_filters.each_with_object([]) do |(item, item_meta), to_return| + to_return << item if item_meta.empty? || + MetadataFilter.apply?(@applies_predicate, item_meta, request_meta) + end + end + + unless [].respond_to?(:each_with_object) # For 1.8.7 + # :nocov: + undef items_for + def items_for(request_meta) + @items_and_filters.inject([]) do |to_return, (item, item_meta)| + to_return << item if item_meta.empty? || + MetadataFilter.apply?(@applies_predicate, item_meta, request_meta) + to_return + end + end + # :nocov: + end + end + + # This implementation is much more complex, and is optimized for + # rare (or hopefully no) updates once the queries start. Updates + # incur a cost as it has to clear the memoization and keep track + # of applicable keys. Queries will be O(N) the first time an item + # is provided with a given set of applicable metadata; subsequent + # queries with items with the same set of applicable metadata will + # be O(1) due to internal memoization. + # + # This is ideal for use by config, where filterable items (e.g. hooks) + # are typically added at the start of the process (e.g. in `spec_helper`) + # and then repeatedly queried as example groups and examples are defined. + # @private + class QueryOptimized < UpdateOptimized + alias find_items_for items_for + private :find_items_for + + def initialize(applies_predicate) + super + @applicable_keys = Set.new + @proc_keys = Set.new + @memoized_lookups = Hash.new do |hash, applicable_metadata| + hash[applicable_metadata] = find_items_for(applicable_metadata) + end + end + + def append(item, metadata) + super + handle_mutation(metadata) + end + + def prepend(item, metadata) + super + handle_mutation(metadata) + end + + def delete(item, metadata) + super + reconstruct_caches + end + + def items_for(metadata) + # The filtering of `metadata` to `applicable_metadata` is the key thing + # that makes the memoization actually useful in practice, since each + # example and example group have different metadata (e.g. location and + # description). By filtering to the metadata keys our items care about, + # we can ignore extra metadata keys that differ for each example/group. + # For example, given `config.include DBHelpers, :db`, example groups + # can be split into these two sets: those that are tagged with `:db` and those + # that are not. For each set, this method for the first group in the set is + # still an `O(N)` calculation, but all subsequent groups in the set will be + # constant time lookups when they call this method. + applicable_metadata = applicable_metadata_from(metadata) + + if applicable_metadata.any? { |k, _| @proc_keys.include?(k) } + # It's unsafe to memoize lookups involving procs (since they can + # be non-deterministic), so we skip the memoization in this case. + find_items_for(applicable_metadata) + else + @memoized_lookups[applicable_metadata] + end + end + + private + + def reconstruct_caches + @applicable_keys.clear + @proc_keys.clear + @items_and_filters.each do |_item, metadata| + handle_mutation(metadata) + end + end + + def handle_mutation(metadata) + @applicable_keys.merge(metadata.keys) + @proc_keys.merge(proc_keys_from metadata) + @memoized_lookups.clear + end + + def applicable_metadata_from(metadata) + MetadataFilter.silence_metadata_example_group_deprecations do + @applicable_keys.inject({}) do |hash, key| + # :example_group is treated special here because... + # - In RSpec 2, example groups had an `:example_group` key + # - In RSpec 3, that key is deprecated (it was confusing!). + # - The key is not technically present in an example group metadata hash + # (and thus would fail the `metadata.key?(key)` check) but a value + # is provided when accessed via the hash's `default_proc` + # - Thus, for backwards compatibility, we have to explicitly check + # for `:example_group` here if it is one of the keys being used to + # filter. + hash[key] = metadata[key] if metadata.key?(key) || key == :example_group + hash + end + end + end + + def proc_keys_from(metadata) + metadata.each_with_object([]) do |(key, value), to_return| + to_return << key if Proc === value + end + end + + unless [].respond_to?(:each_with_object) # For 1.8.7 + # :nocov: + undef proc_keys_from + def proc_keys_from(metadata) + metadata.inject([]) do |to_return, (key, value)| + to_return << key if Proc === value + to_return + end + end + # :nocov: + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/minitest_assertions_adapter.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/minitest_assertions_adapter.rb new file mode 100644 index 00000000..25db7514 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/minitest_assertions_adapter.rb @@ -0,0 +1,31 @@ +begin + # Only the minitest 5.x gem includes the minitest.rb and assertions.rb files. + require 'minitest' + require 'minitest/assertions' +rescue LoadError + # We must be using Ruby Core's MiniTest or the Minitest gem 4.x. + require 'minitest/unit' + Minitest = MiniTest +end + +module RSpec + module Core + # @private + module MinitestAssertionsAdapter + include ::Minitest::Assertions + # Need to forcefully include Pending after Minitest::Assertions + # to make sure our own #skip method beats Minitest's. + include ::RSpec::Core::Pending + + # Minitest 5.x requires this accessor to be available. See + # https://github.com/seattlerb/minitest/blob/38f0a5fcbd9c37c3f80a3eaad4ba84d3fc9947a0/lib/minitest/assertions.rb#L8 + # + # It is not required for other extension libraries, and RSpec does not + # report or make this information available to formatters. + attr_writer :assertions + def assertions + @assertions ||= 0 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/mocking_adapters/flexmock.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/mocking_adapters/flexmock.rb new file mode 100644 index 00000000..91475ae7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/mocking_adapters/flexmock.rb @@ -0,0 +1,31 @@ +# Created by Jim Weirich on 2007-04-10. +# Copyright (c) 2007. All rights reserved. + +require 'flexmock/rspec' + +module RSpec + module Core + module MockingAdapters + # @private + module Flexmock + include ::FlexMock::MockContainer + + def self.framework_name + :flexmock + end + + def setup_mocks_for_rspec + # No setup required. + end + + def verify_mocks_for_rspec + flexmock_verify + end + + def teardown_mocks_for_rspec + flexmock_close + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/mocking_adapters/mocha.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/mocking_adapters/mocha.rb new file mode 100644 index 00000000..8caf7b64 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/mocking_adapters/mocha.rb @@ -0,0 +1,57 @@ +# In order to support all versions of mocha, we have to jump through some +# hoops here. +# +# mocha >= '0.13.0': +# require 'mocha/api' is required. +# require 'mocha/object' raises a LoadError b/c the file no longer exists. +# mocha < '0.13.0', >= '0.9.7' +# require 'mocha/api' is required. +# require 'mocha/object' is required. +# mocha < '0.9.7': +# require 'mocha/api' raises a LoadError b/c the file does not yet exist. +# require 'mocha/standalone' is required. +# require 'mocha/object' is required. +begin + require 'mocha/api' + + begin + require 'mocha/object' + rescue LoadError + # Mocha >= 0.13.0 no longer contains this file nor needs it to be loaded. + end +rescue LoadError + require 'mocha/standalone' + require 'mocha/object' +end + +module RSpec + module Core + module MockingAdapters + # @private + module Mocha + def self.framework_name + :mocha + end + + # Mocha::Standalone was deprecated as of Mocha 0.9.7. + begin + include ::Mocha::API + rescue NameError + include ::Mocha::Standalone + end + + def setup_mocks_for_rspec + mocha_setup + end + + def verify_mocks_for_rspec + mocha_verify + end + + def teardown_mocks_for_rspec + mocha_teardown + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/mocking_adapters/null.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/mocking_adapters/null.rb new file mode 100644 index 00000000..442de9a7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/mocking_adapters/null.rb @@ -0,0 +1,14 @@ +module RSpec + module Core + module MockingAdapters + # @private + module Null + def setup_mocks_for_rspec; end + + def verify_mocks_for_rspec; end + + def teardown_mocks_for_rspec; end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/mocking_adapters/rr.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/mocking_adapters/rr.rb new file mode 100644 index 00000000..d72651a6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/mocking_adapters/rr.rb @@ -0,0 +1,31 @@ +require 'rr' + +RSpec.configuration.backtrace_exclusion_patterns.push(RR::Errors::BACKTRACE_IDENTIFIER) + +module RSpec + module Core + # @private + module MockingAdapters + # @private + module RR + def self.framework_name + :rr + end + + include ::RR::Extensions::InstanceMethods + + def setup_mocks_for_rspec + ::RR::Space.instance.reset + end + + def verify_mocks_for_rspec + ::RR::Space.instance.verify_doubles + end + + def teardown_mocks_for_rspec + ::RR::Space.instance.reset + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/mocking_adapters/rspec.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/mocking_adapters/rspec.rb new file mode 100644 index 00000000..bb3f0ae6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/mocking_adapters/rspec.rb @@ -0,0 +1,32 @@ +require 'rspec/mocks' + +module RSpec + module Core + module MockingAdapters + # @private + module RSpec + include ::RSpec::Mocks::ExampleMethods + + def self.framework_name + :rspec + end + + def self.configuration + ::RSpec::Mocks.configuration + end + + def setup_mocks_for_rspec + ::RSpec::Mocks.setup + end + + def verify_mocks_for_rspec + ::RSpec::Mocks.verify + end + + def teardown_mocks_for_rspec + ::RSpec::Mocks.teardown + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/notifications.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/notifications.rb new file mode 100644 index 00000000..72768ef4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/notifications.rb @@ -0,0 +1,523 @@ +RSpec::Support.require_rspec_core "formatters/console_codes" +RSpec::Support.require_rspec_core "formatters/exception_presenter" +RSpec::Support.require_rspec_core "formatters/helpers" +RSpec::Support.require_rspec_core "shell_escape" + +module RSpec::Core + # Notifications are value objects passed to formatters to provide them + # with information about a particular event of interest. + module Notifications + # @private + module NullColorizer + module_function + + def wrap(line, _code_or_symbol) + line + end + end + + # The `StartNotification` represents a notification sent by the reporter + # when the suite is started. It contains the expected amount of examples + # to be executed, and the load time of RSpec. + # + # @attr count [Fixnum] the number counted + # @attr load_time [Float] the number of seconds taken to boot RSpec + # and load the spec files + StartNotification = Struct.new(:count, :load_time) + + # The `ExampleNotification` represents notifications sent by the reporter + # which contain information about the current (or soon to be) example. + # It is used by formatters to access information about that example. + # + # @example + # def example_started(notification) + # puts "Hey I started #{notification.example.description}" + # end + # + # @attr example [RSpec::Core::Example] the current example + ExampleNotification = Struct.new(:example) + class ExampleNotification + # @private + def self.for(example) + execution_result = example.execution_result + + return SkippedExampleNotification.new(example) if execution_result.example_skipped? + return new(example) unless execution_result.status == :pending || execution_result.status == :failed + + klass = if execution_result.pending_fixed? + PendingExampleFixedNotification + elsif execution_result.status == :pending + PendingExampleFailedAsExpectedNotification + else + FailedExampleNotification + end + + klass.new(example) + end + + private_class_method :new + end + + # The `ExamplesNotification` represents notifications sent by the reporter + # which contain information about the suites examples. + # + # @example + # def stop(notification) + # puts "Hey I ran #{notification.examples.size}" + # end + # + class ExamplesNotification + def initialize(reporter) + @reporter = reporter + end + + # @return [Array] list of examples + def examples + @reporter.examples + end + + # @return [Array] list of failed examples + def failed_examples + @reporter.failed_examples + end + + # @return [Array] list of pending examples + def pending_examples + @reporter.pending_examples + end + + # @return [Array] + # returns examples as notifications + def notifications + @notifications ||= format_examples(examples) + end + + # @return [Array] + # returns failed examples as notifications + def failure_notifications + @failed_notifications ||= format_examples(failed_examples) + end + + # @return [Array] + # returns pending examples as notifications + def pending_notifications + @pending_notifications ||= format_examples(pending_examples) + end + + # @return [String] The list of failed examples, fully formatted in the way + # that RSpec's built-in formatters emit. + def fully_formatted_failed_examples(colorizer=::RSpec::Core::Formatters::ConsoleCodes) + formatted = "\nFailures:\n" + + failure_notifications.each_with_index do |failure, index| + formatted += failure.fully_formatted(index.next, colorizer) + end + + formatted + end + + # @return [String] The list of pending examples, fully formatted in the + # way that RSpec's built-in formatters emit. + def fully_formatted_pending_examples(colorizer=::RSpec::Core::Formatters::ConsoleCodes) + return if RSpec.configuration.pending_failure_output == :skip + + formatted = "\nPending: (Failures listed here are expected and do not affect your suite's status)\n".dup + + pending_notifications.each_with_index do |notification, index| + formatted << notification.fully_formatted(index.next, colorizer) + end + + formatted + end + + private + + def format_examples(examples) + examples.map do |example| + ExampleNotification.for(example) + end + end + end + + # The `FailedExampleNotification` extends `ExampleNotification` with + # things useful for examples that have failure info -- typically a + # failed or pending spec. + # + # @example + # def example_failed(notification) + # puts "Hey I failed :(" + # puts "Here's my stack trace" + # puts notification.exception.backtrace.join("\n") + # end + # + # @attr [RSpec::Core::Example] example the current example + # @see ExampleNotification + class FailedExampleNotification < ExampleNotification + public_class_method :new + + # @return [Exception] The example failure + def exception + @exception_presenter.exception + end + + # @return [String] The example description + def description + @exception_presenter.description + end + + # Returns the message generated for this failure line by line. + # + # @return [Array] The example failure message + def message_lines + @exception_presenter.message_lines + end + + # Returns the message generated for this failure colorized line by line. + # + # @param colorizer [#wrap] An object to colorize the message_lines by + # @return [Array] The example failure message colorized + def colorized_message_lines(colorizer=::RSpec::Core::Formatters::ConsoleCodes) + @exception_presenter.colorized_message_lines(colorizer) + end + + # Returns the failures formatted backtrace. + # + # @return [Array] the examples backtrace lines + def formatted_backtrace + @exception_presenter.formatted_backtrace + end + + # Returns the failures colorized formatted backtrace. + # + # @param colorizer [#wrap] An object to colorize the message_lines by + # @return [Array] the examples colorized backtrace lines + def colorized_formatted_backtrace(colorizer=::RSpec::Core::Formatters::ConsoleCodes) + @exception_presenter.colorized_formatted_backtrace(colorizer) + end + + # @return [String] The failure information fully formatted in the way that + # RSpec's built-in formatters emit. + def fully_formatted(failure_number, colorizer=::RSpec::Core::Formatters::ConsoleCodes) + @exception_presenter.fully_formatted(failure_number, colorizer) + end + + # @return [Array] The failure information fully formatted in the way that + # RSpec's built-in formatters emit, split by line. + def fully_formatted_lines(failure_number, colorizer=::RSpec::Core::Formatters::ConsoleCodes) + @exception_presenter.fully_formatted_lines(failure_number, colorizer) + end + + private + + def initialize(example, exception_presenter=Formatters::ExceptionPresenter::Factory.new(example).build) + @exception_presenter = exception_presenter + super(example) + end + end + + # @deprecated Use {FailedExampleNotification} instead. + class PendingExampleFixedNotification < FailedExampleNotification; end + + # @deprecated Use {FailedExampleNotification} instead. + class PendingExampleFailedAsExpectedNotification < FailedExampleNotification; end + + # The `SkippedExampleNotification` extends `ExampleNotification` with + # things useful for specs that are skipped. + # + # @attr [RSpec::Core::Example] example the current example + # @see ExampleNotification + class SkippedExampleNotification < ExampleNotification + public_class_method :new + + # @return [String] The pending detail fully formatted in the way that + # RSpec's built-in formatters emit. + def fully_formatted(pending_number, colorizer=::RSpec::Core::Formatters::ConsoleCodes) + formatted_caller = RSpec.configuration.backtrace_formatter.backtrace_line(example.location) + + [ + colorizer.wrap("\n #{pending_number}) #{example.full_description}", :pending), + "\n ", + Formatters::ExceptionPresenter::PENDING_DETAIL_FORMATTER.call(example, colorizer), + "\n", + colorizer.wrap(" # #{formatted_caller}\n", :detail) + ].join("") + end + end + + # The `GroupNotification` represents notifications sent by the reporter + # which contain information about the currently running (or soon to be) + # example group. It is used by formatters to access information about that + # group. + # + # @example + # def example_group_started(notification) + # puts "Hey I started #{notification.group.description}" + # end + # @attr group [RSpec::Core::ExampleGroup] the current group + GroupNotification = Struct.new(:group) + + # The `MessageNotification` encapsulates generic messages that the reporter + # sends to formatters. + # + # @attr message [String] the message + MessageNotification = Struct.new(:message) + + # The `SeedNotification` holds the seed used to randomize examples and + # whether that seed has been used or not. + # + # @attr seed [Fixnum] the seed used to randomize ordering + # @attr used [Boolean] whether the seed has been used or not + SeedNotification = Struct.new(:seed, :used) + class SeedNotification + # @api + # @return [Boolean] has the seed been used? + def seed_used? + !!used + end + private :used + + # @return [String] The seed information fully formatted in the way that + # RSpec's built-in formatters emit. + def fully_formatted + "\nRandomized with seed #{seed}\n" + end + end + + # The `SummaryNotification` holds information about the results of running + # a test suite. It is used by formatters to provide information at the end + # of the test run. + # + # @attr duration [Float] the time taken (in seconds) to run the suite + # @attr examples [Array] the examples run + # @attr failed_examples [Array] the failed examples + # @attr pending_examples [Array] the pending examples + # @attr load_time [Float] the number of seconds taken to boot RSpec + # and load the spec files + # @attr errors_outside_of_examples_count [Integer] the number of errors that + # have occurred processing + # the spec suite + SummaryNotification = Struct.new(:duration, :examples, :failed_examples, + :pending_examples, :load_time, + :errors_outside_of_examples_count) + class SummaryNotification + # @api + # @return [Fixnum] the number of examples run + def example_count + @example_count ||= examples.size + end + + # @api + # @return [Fixnum] the number of failed examples + def failure_count + @failure_count ||= failed_examples.size + end + + # @api + # @return [Fixnum] the number of pending examples + def pending_count + @pending_count ||= pending_examples.size + end + + # @api + # @return [String] A line summarising the result totals of the spec run. + def totals_line + summary = Formatters::Helpers.pluralize(example_count, "example") + + ", " + Formatters::Helpers.pluralize(failure_count, "failure") + summary += ", #{pending_count} pending" if pending_count > 0 + if errors_outside_of_examples_count > 0 + summary += ( + ", " + + Formatters::Helpers.pluralize(errors_outside_of_examples_count, "error") + + " occurred outside of examples" + ) + end + summary + end + + # @api public + # + # Wraps the results line with colors based on the configured + # colors for failure, pending, and success. Defaults to red, + # yellow, green accordingly. + # + # @param colorizer [#wrap] An object which supports wrapping text with + # specific colors. + # @return [String] A colorized results line. + def colorized_totals_line(colorizer=::RSpec::Core::Formatters::ConsoleCodes) + if failure_count > 0 || errors_outside_of_examples_count > 0 + colorizer.wrap(totals_line, RSpec.configuration.failure_color) + elsif pending_count > 0 + colorizer.wrap(totals_line, RSpec.configuration.pending_color) + else + colorizer.wrap(totals_line, RSpec.configuration.success_color) + end + end + + # @api public + # + # Formats failures into a rerunable command format. + # + # @param colorizer [#wrap] An object which supports wrapping text with + # specific colors. + # @return [String] A colorized summary line. + def colorized_rerun_commands(colorizer=::RSpec::Core::Formatters::ConsoleCodes) + "\nFailed examples:\n\n" + + failed_examples.map do |example| + colorizer.wrap("rspec #{rerun_argument_for(example)}", RSpec.configuration.failure_color) + " " + + colorizer.wrap("# #{example.full_description}", RSpec.configuration.detail_color) + end.join("\n") + end + + # @return [String] a formatted version of the time it took to run the + # suite + def formatted_duration + Formatters::Helpers.format_duration(duration) + end + + # @return [String] a formatted version of the time it took to boot RSpec + # and load the spec files + def formatted_load_time + Formatters::Helpers.format_duration(load_time) + end + + # @return [String] The summary information fully formatted in the way that + # RSpec's built-in formatters emit. + def fully_formatted(colorizer=::RSpec::Core::Formatters::ConsoleCodes) + formatted = "\nFinished in #{formatted_duration} " \ + "(files took #{formatted_load_time} to load)\n" \ + "#{colorized_totals_line(colorizer)}\n" + + unless failed_examples.empty? + formatted += (colorized_rerun_commands(colorizer) + "\n") + end + + formatted + end + + private + + include RSpec::Core::ShellEscape + + def rerun_argument_for(example) + location = example.location_rerun_argument + return location unless duplicate_rerun_locations.include?(location) + conditionally_quote(example.id) + end + + def duplicate_rerun_locations + @duplicate_rerun_locations ||= begin + locations = RSpec.world.all_examples.map(&:location_rerun_argument) + + Set.new.tap do |s| + locations.group_by { |l| l }.each do |l, ls| + s << l if ls.count > 1 + end + end + end + end + end + + # The `ProfileNotification` holds information about the results of running a + # test suite when profiling is enabled. It is used by formatters to provide + # information at the end of the test run for profiling information. + # + # @attr duration [Float] the time taken (in seconds) to run the suite + # @attr examples [Array] the examples run + # @attr number_of_examples [Fixnum] the number of examples to profile + # @attr example_groups [Array] example groups run + class ProfileNotification + def initialize(duration, examples, number_of_examples, example_groups) + @duration = duration + @examples = examples + @number_of_examples = number_of_examples + @example_groups = example_groups + end + attr_reader :duration, :examples, :number_of_examples + + # @return [Array] the slowest examples + def slowest_examples + @slowest_examples ||= + examples.sort_by do |example| + -example.execution_result.run_time + end.first(number_of_examples) + end + + # @return [Float] the time taken (in seconds) to run the slowest examples + def slow_duration + @slow_duration ||= + slowest_examples.inject(0.0) do |i, e| + i + e.execution_result.run_time + end + end + + # @return [String] the percentage of total time taken + def percentage + @percentage ||= + begin + time_taken = slow_duration / duration + '%.1f' % ((time_taken.nan? ? 0.0 : time_taken) * 100) + end + end + + # @return [Array] the slowest example groups + def slowest_groups + @slowest_groups ||= calculate_slowest_groups + end + + private + + def calculate_slowest_groups + # stop if we've only one example group + return {} if @example_groups.keys.length <= 1 + + @example_groups.each_value do |hash| + hash[:average] = hash[:total_time].to_f / hash[:count] + end + + groups = @example_groups.sort_by { |_, hash| -hash[:average] }.first(number_of_examples) + groups.map { |group, data| [group.location, data] } + end + end + + # The `DeprecationNotification` is issued by the reporter when a deprecated + # part of RSpec is encountered. It represents information about the + # deprecated call site. + # + # @attr message [String] A custom message about the deprecation + # @attr deprecated [String] A custom message about the deprecation (alias of + # message) + # @attr replacement [String] An optional replacement for the deprecation + # @attr call_site [String] An optional call site from which the deprecation + # was issued + DeprecationNotification = Struct.new(:deprecated, :message, :replacement, :call_site) + class DeprecationNotification + private_class_method :new + + # @api + # Convenience way to initialize the notification + def self.from_hash(data) + new data[:deprecated], data[:message], data[:replacement], data[:call_site] + end + end + + # `NullNotification` represents a placeholder value for notifications that + # currently require no information, but we may wish to extend in future. + class NullNotification + end + + # `CustomNotification` is used when sending custom events to formatters / + # other registered listeners, it creates attributes based on supplied hash + # of options. + class CustomNotification < Struct + # @param options [Hash] A hash of method / value pairs to create on this notification + # @return [CustomNotification] + # + # Build a custom notification based on the supplied option key / values. + def self.for(options={}) + return NullNotification if options.keys.empty? + new(*options.keys).new(*options.values) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/option_parser.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/option_parser.rb new file mode 100644 index 00000000..e239e87a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/option_parser.rb @@ -0,0 +1,325 @@ +# http://www.ruby-doc.org/stdlib/libdoc/optparse/rdoc/classes/OptionParser.html +require 'optparse' + +module RSpec::Core + # @private + class Parser + def self.parse(args, source=nil) + new(args).parse(source) + end + + attr_reader :original_args + + def initialize(original_args) + @original_args = original_args + end + + def parse(source=nil) + return { :files_or_directories_to_run => [] } if original_args.empty? + args = original_args.dup + + options = args.delete('--tty') ? { :tty => true } : {} + begin + parser(options).parse!(args) + rescue OptionParser::InvalidOption => e + abort "#{e.message}#{" (defined in #{source})" if source}\n\n" \ + "Please use --help for a listing of valid options" + end + + options[:files_or_directories_to_run] = args + options + end + + private + + # rubocop:disable Metrics/AbcSize + # rubocop:disable Metrics/MethodLength + # rubocop:disable Metrics/CyclomaticComplexity + # rubocop:disable Metrics/PerceivedComplexity + def parser(options) + OptionParser.new do |parser| + parser.summary_width = 34 + + parser.banner = "Usage: rspec [options] [files or directories]\n\n" + + parser.on('-I PATH', 'Specify PATH to add to $LOAD_PATH (may be used more than once).') do |dirs| + options[:libs] ||= [] + options[:libs].concat(dirs.split(File::PATH_SEPARATOR)) + end + + parser.on('-r', '--require PATH', 'Require a file.') do |path| + options[:requires] ||= [] + options[:requires] << path + end + + parser.on('-O', '--options PATH', 'Specify the path to a custom options file.') do |path| + options[:custom_options_file] = path + end + + parser.on('--order TYPE[:SEED]', 'Run examples by the specified order type.', + ' [defined] examples and groups are run in the order they are defined', + ' [rand] randomize the order of groups and examples', + ' [random] alias for rand', + ' [random:SEED] e.g. --order random:123', + ' [recently-modified] run the most recently modified files first') do |o| + options[:order] = o + end + + parser.on('--seed SEED', Integer, 'Equivalent of --order rand:SEED.') do |seed| + options[:order] = "rand:#{seed}" + end + + parser.on('--bisect[=verbose]', 'Repeatedly runs the suite in order to isolate the failures to the ', + ' smallest reproducible case.') do |argument| + options[:bisect] = argument || true + options[:runner] = RSpec::Core::Invocations::Bisect.new + end + + parser.on('--[no-]fail-fast[=COUNT]', 'Abort the run after a certain number of failures (1 by default).') do |argument| + if argument == true + value = 1 + elsif argument == false || argument == 0 + value = false + else + begin + value = Integer(argument) + rescue ArgumentError + RSpec.warning "Expected an integer value for `--fail-fast`, got: #{argument.inspect}", :call_site => nil + end + end + set_fail_fast(options, value) + end + + parser.on('--failure-exit-code CODE', Integer, + 'Override the exit code used when there are failing specs.') do |code| + options[:failure_exit_code] = code + end + + parser.on('--error-exit-code CODE', Integer, + 'Override the exit code used when there are errors loading or running specs outside of examples.') do |code| + options[:error_exit_code] = code + end + + parser.on('-X', '--[no-]drb', 'Run examples via DRb.') do |use_drb| + options[:drb] = use_drb + options[:runner] = RSpec::Core::Invocations::DRbWithFallback.new if use_drb + end + + parser.on('--drb-port PORT', 'Port to connect to the DRb server.') do |o| + options[:drb_port] = o.to_i + end + + parser.separator("\n **** Output ****\n\n") + + parser.on('-f', '--format FORMATTER', 'Choose a formatter.', + ' [p]rogress (default - dots)', + ' [d]ocumentation (group and example names)', + ' [h]tml', + ' [j]son', + ' [f]ailures ("file:line:reason", suitable for editors integration)', + ' custom formatter class name') do |o| + options[:formatters] ||= [] + options[:formatters] << [o] + end + + parser.on('-o', '--out FILE', + 'Write output to a file instead of $stdout. This option applies', + ' to the previously specified --format, or the default format', + ' if no format is specified.' + ) do |o| + options[:formatters] ||= [['progress']] + options[:formatters].last << o + end + + parser.on('--deprecation-out FILE', 'Write deprecation warnings to a file instead of $stderr.') do |file| + options[:deprecation_stream] = file + end + + parser.on('-b', '--backtrace', 'Enable full backtrace.') do |_o| + options[:full_backtrace] = true + end + + parser.on('-c', '--color', '--colour', '') do |_o| + # flag will be excluded from `--help` output because it is deprecated + options[:color] = true + options[:color_mode] = :automatic + end + + parser.on('--force-color', '--force-colour', 'Force the output to be in color, even if the output is not a TTY') do |_o| + if options[:color_mode] == :off + abort "Please only use one of `--force-color` and `--no-color`" + end + options[:color_mode] = :on + end + + parser.on('--no-color', '--no-colour', 'Force the output to not be in color, even if the output is a TTY') do |_o| + if options[:color_mode] == :on + abort "Please only use one of --force-color and --no-color" + end + options[:color_mode] = :off + end + + parser.on('-p', '--[no-]profile [COUNT]', + 'Enable profiling of examples and list the slowest examples (default: 10).') do |argument| + options[:profile_examples] = if argument.nil? + true + elsif argument == false + false + else + begin + Integer(argument) + rescue ArgumentError + RSpec.warning "Non integer specified as profile count, separate " \ + "your path from options with -- e.g. " \ + "`rspec --profile -- #{argument}`", + :call_site => nil + true + end + end + end + + parser.on('--dry-run', 'Print the formatter output of your suite without', + ' running any examples or hooks') do |_o| + options[:dry_run] = true + end + + parser.on('-w', '--warnings', 'Enable ruby warnings') do + if Object.const_defined?(:Warning) && Warning.respond_to?(:[]=) + # :nocov: on older Ruby without Warning + Warning[:deprecated] = true + # :nocov: + end + $VERBOSE = true + end + + parser.separator <<-FILTERING + + **** Filtering/tags **** + + In addition to the following options for selecting specific files, groups, or + examples, you can select individual examples by appending the line number(s) to + the filename: + + rspec path/to/a_spec.rb:37:87 + + You can also pass example ids enclosed in square brackets: + + rspec path/to/a_spec.rb[1:5,1:6] # run the 5th and 6th examples/groups defined in the 1st group + +FILTERING + + parser.on('--only-failures', "Filter to just the examples that failed the last time they ran.") do + configure_only_failures(options) + end + + parser.on("-n", "--next-failure", "Apply `--only-failures` and abort after one failure.", + " (Equivalent to `--only-failures --fail-fast --order defined`)") do + configure_only_failures(options) + set_fail_fast(options, 1) + options[:order] ||= 'defined' + end + + parser.on('-P', '--pattern PATTERN', 'Load files matching pattern (default: "spec/**/*_spec.rb").') do |o| + if options[:pattern] + options[:pattern] += ',' + o + else + options[:pattern] = o + end + end + + parser.on('--exclude-pattern PATTERN', + 'Load files except those matching pattern. Opposite effect of --pattern.') do |o| + options[:exclude_pattern] = o + end + + parser.on('-e', '--example STRING', "Run examples whose full nested names include STRING (may be", + " used more than once)") do |o| + (options[:full_description] ||= []) << Regexp.compile(Regexp.escape(o)) + end + + parser.on('-E', '--example-matches REGEX', "Run examples whose full nested names match REGEX (may be", + " used more than once)") do |o| + (options[:full_description] ||= []) << Regexp.compile(o) + end + + parser.on('-t', '--tag TAG[:VALUE]', + 'Run examples with the specified tag, or exclude examples', + 'by adding ~ before the tag.', + ' - e.g. ~slow', + ' - TAG is always converted to a symbol') do |tag| + filter_type = tag =~ /^~/ ? :exclusion_filter : :inclusion_filter + + name, value = tag.gsub(/^(~@|~|@)/, '').split(':', 2) + name = name.to_sym + + parsed_value = case value + when nil then true # The default value for tags is true + when 'true' then true + when 'false' then false + when 'nil' then nil + when /^:/ then value[1..-1].to_sym + when /^\d+$/ then Integer(value) + when /^\d+.\d+$/ then Float(value) + else + value + end + + add_tag_filter(options, filter_type, name, parsed_value) + end + + parser.on('--default-path PATH', 'Set the default path where RSpec looks for examples (can', + ' be a path to a file or a directory).') do |path| + options[:default_path] = path + end + + parser.separator("\n **** Utility ****\n\n") + + parser.on('--init', 'Initialize your project with RSpec.') do |_cmd| + options[:runner] = RSpec::Core::Invocations::InitializeProject.new + end + + parser.on('-v', '--version', 'Display the version.') do + options[:runner] = RSpec::Core::Invocations::PrintVersion.new + end + + # These options would otherwise be confusing to users, so we forcibly + # prevent them from executing. + # + # * --I is too similar to -I. + # * -d was a shorthand for --debugger, which is removed, but now would + # trigger --default-path. + invalid_options = %w[-d --I] + + hidden_options = invalid_options + %w[-c] + + parser.on_tail('-h', '--help', "You're looking at it.") do + options[:runner] = RSpec::Core::Invocations::PrintHelp.new(parser, hidden_options) + end + + # This prevents usage of the invalid_options. + invalid_options.each do |option| + parser.on(option) do + raise OptionParser::InvalidOption.new + end + end + end + end + # rubocop:enable Metrics/AbcSize + # rubocop:enable Metrics/MethodLength + # rubocop:enable Metrics/CyclomaticComplexity + # rubocop:enable Metrics/PerceivedComplexity + + def add_tag_filter(options, filter_type, tag_name, value=true) + (options[filter_type] ||= {})[tag_name] = value + end + + def set_fail_fast(options, value) + options[:fail_fast] = value + end + + def configure_only_failures(options) + options[:only_failures] = true + add_tag_filter(options, :inclusion_filter, :last_run_status, 'failed') + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/ordering.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/ordering.rb new file mode 100644 index 00000000..6058a2f2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/ordering.rb @@ -0,0 +1,208 @@ +module RSpec + module Core + # @private + module Ordering + # @private + # The default global ordering (defined order). + class Identity + def order(items) + items + end + end + + # @private + # Orders items randomly. + class Random + def initialize(configuration) + @configuration = configuration + @used = false + end + + def used? + @used + end + + def order(items) + @used = true + + seed = @configuration.seed.to_s + items.sort_by { |item| jenkins_hash_digest(seed + item.id) } + end + + private + + # http://en.wikipedia.org/wiki/Jenkins_hash_function + # Jenkins provides a good distribution and is simpler than MD5. + # It's a bit slower than MD5 (primarily because `Digest::MD5` is + # implemented in C) but has the advantage of not requiring us + # to load another part of stdlib, which we try to minimize. + def jenkins_hash_digest(string) + hash = 0 + + string.each_byte do |byte| + hash += byte + hash &= MAX_32_BIT + hash += ((hash << 10) & MAX_32_BIT) + hash &= MAX_32_BIT + hash ^= hash >> 6 + end + + hash += ((hash << 3) & MAX_32_BIT) + hash &= MAX_32_BIT + hash ^= hash >> 11 + hash += ((hash << 15) & MAX_32_BIT) + hash &= MAX_32_BIT + hash + end + + MAX_32_BIT = 4_294_967_295 + end + + # @private + # Orders items by modification time (most recent modified first). + class RecentlyModified + def order(list) + list.sort_by { |item| -File.mtime(item.metadata[:absolute_file_path]).to_i } + end + end + + # @private + # Orders items based on a custom block. + class Custom + def initialize(callable) + @callable = callable + end + + def order(list) + @callable.call(list) + end + end + + # @private + # A strategy which delays looking up the ordering until needed + class Delayed + def initialize(registry, name) + @registry = registry + @name = name + end + + def order(list) + strategy.order(list) + end + + private + + def strategy + @strategy ||= lookup_strategy + end + + def lookup_strategy + raise "Undefined ordering strategy #{@name.inspect}" unless @registry.has_strategy?(@name) + @registry.fetch(@name) + end + end + + # @private + # Stores the different ordering strategies. + class Registry + def initialize(configuration) + @configuration = configuration + @strategies = {} + + register(:random, Random.new(configuration)) + register(:recently_modified, RecentlyModified.new) + + identity = Identity.new + register(:defined, identity) + + # The default global ordering is --defined. + register(:global, identity) + end + + def fetch(name, &fallback) + @strategies.fetch(name, &fallback) + end + + def has_strategy?(name) + @strategies.key?(name) + end + + def register(sym, strategy) + @strategies[sym] = strategy + end + + def used_random_seed? + @strategies[:random].used? + end + end + + # @private + # Manages ordering configuration. + # + # @note This is not intended to be used externally. Use + # the APIs provided by `RSpec::Core::Configuration` instead. + class ConfigurationManager + attr_reader :seed, :ordering_registry + + def initialize + @ordering_registry = Registry.new(self) + @seed = rand(0xFFFF) + @seed_forced = false + @order_forced = false + end + + def seed_used? + ordering_registry.used_random_seed? + end + + def seed=(seed) + return if @seed_forced + register_ordering(:global, ordering_registry.fetch(:random)) + @seed = seed.to_i + end + + def order=(type) + order, seed = type.to_s.split(':') + @seed = seed.to_i if seed + + ordering_name = if order.include?('rand') + :random + elsif order == 'defined' + :defined + elsif order == 'recently-modified' + :recently_modified + else + order.to_sym + end + + if ordering_name + strategy = + if ordering_registry.has_strategy?(ordering_name) + ordering_registry.fetch(ordering_name) + else + Delayed.new(ordering_registry, ordering_name) + end + + register_ordering(:global, strategy) + end + end + + def force(hash) + if hash.key?(:seed) + self.seed = hash[:seed] + @seed_forced = true + @order_forced = true + elsif hash.key?(:order) + self.order = hash[:order] + @order_forced = true + end + end + + def register_ordering(name, strategy=Custom.new(Proc.new { |l| yield l })) + return if @order_forced && name == :global + ordering_registry.register(name, strategy) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/output_wrapper.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/output_wrapper.rb new file mode 100644 index 00000000..8e07aa87 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/output_wrapper.rb @@ -0,0 +1,29 @@ +module RSpec + module Core + # @private + class OutputWrapper + # @private + attr_accessor :output + + # @private + def initialize(output) + @output = output + end + + def respond_to?(name, priv=false) + output.respond_to?(name, priv) + end + + def method_missing(name, *args, &block) + output.__send__(name, *args, &block) + end + + # Redirect calls for IO interface methods + IO.instance_methods(false).each do |method| + define_method(method) do |*args, &block| + output.__send__(method, *args, &block) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/pending.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/pending.rb new file mode 100644 index 00000000..c6c59c18 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/pending.rb @@ -0,0 +1,157 @@ +module RSpec + module Core + # Provides methods to mark examples as pending. These methods are available + # to be called from within any example or hook. + module Pending + # Raised in the middle of an example to indicate that it should be marked + # as skipped. + class SkipDeclaredInExample < StandardError + attr_reader :argument + + def initialize(argument) + @argument = argument + end + end + + # If Test::Unit is loaded, we'll use its error as baseclass, so that + # Test::Unit will report unmet RSpec expectations as failures rather than + # errors. + begin + class PendingExampleFixedError < Test::Unit::AssertionFailedError; end + rescue + class PendingExampleFixedError < StandardError; end + end + + # @private + NO_REASON_GIVEN = 'No reason given' + + # @private + NOT_YET_IMPLEMENTED = 'Not yet implemented' + + # @overload pending() + # @overload pending(message) + # + # Marks an example as pending. The rest of the example will still be + # executed, and if it passes the example will fail to indicate that the + # pending can be removed. + # + # @param message [String] optional message to add to the summary report. + # + # @example + # describe "some behaviour" do + # # reported as "Pending: no reason given" + # it "is pending with no message" do + # pending + # raise "broken" + # end + # + # # reported as "Pending: something else getting finished" + # it "is pending with a custom message" do + # pending("something else getting finished") + # raise "broken" + # end + # end + # + # @note When using `pending` inside an example body using this method + # hooks, such as `before(:example)`, have already be run. This means that + # a failure from the code in the `before` hook will prevent the example + # from being considered pending, as the example body would not be + # executed. If you need to consider hooks as pending as well you can use + # the pending metadata as an alternative, e.g. + # `it "does something", pending: "message"`. + def pending(message=nil, &_block) + current_example = RSpec.current_example + + if block_given? + raise ArgumentError, <<-EOS.gsub(/^\s+\|/, '') + |The semantics of `RSpec::Core::Pending#pending` have changed in + |RSpec 3. In RSpec 2.x, it caused the example to be skipped. In + |RSpec 3, the rest of the example is still run but is expected to + |fail, and will be marked as a failure (rather than as pending) if + |the example passes. + | + |Passing a block within an example is now deprecated. Marking the + |example as pending provides the same behavior in RSpec 3 which was + |provided only by the block in RSpec 2.x. + | + |Move the code in the block provided to `pending` into the rest of + |the example body. + | + |Called from #{CallerFilter.first_non_rspec_line}. + | + EOS + elsif current_example + Pending.mark_pending! current_example, message + else + raise "`pending` may not be used outside of examples, such as in " \ + "before(:context). Maybe you want `skip`?" + end + end + + # @overload skip() + # @overload skip(message) + # + # Marks an example as pending and skips execution. + # + # @param message [String] optional message to add to the summary report. + # + # @example + # describe "an example" do + # # reported as "Pending: no reason given" + # it "is skipped with no message" do + # skip + # end + # + # # reported as "Pending: something else getting finished" + # it "is skipped with a custom message" do + # skip "something else getting finished" + # end + # end + def skip(message=nil) + current_example = RSpec.current_example + + Pending.mark_skipped!(current_example, message) if current_example + + raise SkipDeclaredInExample.new(message) + end + + # @private + # + # Mark example as skipped. + # + # @param example [RSpec::Core::Example] the example to mark as skipped + # @param message_or_bool [Boolean, String] the message to use, or true + def self.mark_skipped!(example, message_or_bool) + Pending.mark_pending! example, message_or_bool + example.metadata[:skip] = true + end + + # @private + # + # Mark example as pending. + # + # @param example [RSpec::Core::Example] the example to mark as pending + # @param message_or_bool [Boolean, String] the message to use, or true + def self.mark_pending!(example, message_or_bool) + message = if !message_or_bool || !(String === message_or_bool) + NO_REASON_GIVEN + else + message_or_bool + end + + example.metadata[:pending] = true + example.execution_result.pending_message = message + example.execution_result.pending_fixed = false + end + + # @private + # + # Mark example as fixed. + # + # @param example [RSpec::Core::Example] the example to mark as fixed + def self.mark_fixed!(example) + example.execution_result.pending_fixed = true + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/profiler.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/profiler.rb new file mode 100644 index 00000000..5e652797 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/profiler.rb @@ -0,0 +1,34 @@ +module RSpec + module Core + # @private + class Profiler + NOTIFICATIONS = [:example_group_started, :example_group_finished, :example_started] + + def initialize + @example_groups = Hash.new { |h, k| h[k] = { :count => 0 } } + end + + attr_reader :example_groups + + def example_group_started(notification) + return unless notification.group.top_level? + + @example_groups[notification.group][:start] = Time.now + @example_groups[notification.group][:description] = notification.group.top_level_description + end + + def example_group_finished(notification) + return unless notification.group.top_level? + + group = @example_groups[notification.group] + return unless group.key?(:start) + group[:total_time] = Time.now - group[:start] + end + + def example_started(notification) + group = notification.example.example_group.parent_groups.last + @example_groups[group][:count] += 1 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/project_initializer.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/project_initializer.rb new file mode 100644 index 00000000..ca707e03 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/project_initializer.rb @@ -0,0 +1,48 @@ +RSpec::Support.require_rspec_support "directory_maker" + +module RSpec + module Core + # @private + # Generates conventional files for an RSpec project. + class ProjectInitializer + attr_reader :destination, :stream, :template_path + + DOT_RSPEC_FILE = '.rspec' + SPEC_HELPER_FILE = 'spec/spec_helper.rb' + + def initialize(opts={}) + @destination = opts.fetch(:destination, Dir.getwd) + @stream = opts.fetch(:report_stream, $stdout) + @template_path = opts.fetch(:template_path) do + File.expand_path("../project_initializer", __FILE__) + end + end + + def run + copy_template DOT_RSPEC_FILE + copy_template SPEC_HELPER_FILE + end + + private + + def copy_template(file) + destination_file = File.join(destination, file) + return report_exists(file) if File.exist?(destination_file) + + report_creating(file) + RSpec::Support::DirectoryMaker.mkdir_p(File.dirname(destination_file)) + File.open(destination_file, 'w') do |f| + f.write File.read(File.join(template_path, file)) + end + end + + def report_exists(file) + stream.puts " exist #{file}" + end + + def report_creating(file) + stream.puts " create #{file}" + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/project_initializer/.rspec b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/project_initializer/.rspec new file mode 100644 index 00000000..c99d2e73 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/project_initializer/.rspec @@ -0,0 +1 @@ +--require spec_helper diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/project_initializer/spec/spec_helper.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/project_initializer/spec/spec_helper.rb new file mode 100644 index 00000000..c80d44b9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/project_initializer/spec/spec_helper.rb @@ -0,0 +1,98 @@ +# This file was generated by the `rspec --init` command. Conventionally, all +# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. +# The generated `.rspec` file contains `--require spec_helper` which will cause +# this file to always be loaded, without a need to explicitly require it in any +# files. +# +# Given that it is always loaded, you are encouraged to keep this file as +# light-weight as possible. Requiring heavyweight dependencies from this file +# will add to the boot time of your test suite on EVERY test run, even for an +# individual file that may not need all of that loaded. Instead, consider making +# a separate helper file that requires the additional dependencies and performs +# the additional setup, and require it from the spec files that actually need +# it. +# +# See https://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +RSpec.configure do |config| + # rspec-expectations config goes here. You can use an alternate + # assertion/expectation library such as wrong or the stdlib/minitest + # assertions if you prefer. + config.expect_with :rspec do |expectations| + # This option will default to `true` in RSpec 4. It makes the `description` + # and `failure_message` of custom matchers include text for helper methods + # defined using `chain`, e.g.: + # be_bigger_than(2).and_smaller_than(4).description + # # => "be bigger than 2 and smaller than 4" + # ...rather than: + # # => "be bigger than 2" + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + # rspec-mocks config goes here. You can use an alternate test double + # library (such as bogus or mocha) by changing the `mock_with` option here. + config.mock_with :rspec do |mocks| + # Prevents you from mocking or stubbing a method that does not exist on + # a real object. This is generally recommended, and will default to + # `true` in RSpec 4. + mocks.verify_partial_doubles = true + end + + # This option will default to `:apply_to_host_groups` in RSpec 4 (and will + # have no way to turn it off -- the option exists only for backwards + # compatibility in RSpec 3). It causes shared context metadata to be + # inherited by the metadata hash of host groups and examples, rather than + # triggering implicit auto-inclusion in groups with matching metadata. + config.shared_context_metadata_behavior = :apply_to_host_groups + +# The settings below are suggested to provide a good initial experience +# with RSpec, but feel free to customize to your heart's content. +=begin + # This allows you to limit a spec run to individual examples or groups + # you care about by tagging them with `:focus` metadata. When nothing + # is tagged with `:focus`, all examples get run. RSpec also provides + # aliases for `it`, `describe`, and `context` that include `:focus` + # metadata: `fit`, `fdescribe` and `fcontext`, respectively. + config.filter_run_when_matching :focus + + # Allows RSpec to persist some state between runs in order to support + # the `--only-failures` and `--next-failure` CLI options. We recommend + # you configure your source control system to ignore this file. + config.example_status_persistence_file_path = "spec/examples.txt" + + # Limits the available syntax to the non-monkey patched syntax that is + # recommended. For more details, see: + # https://rspec.info/features/3-12/rspec-core/configuration/zero-monkey-patching-mode/ + config.disable_monkey_patching! + + # This setting enables warnings. It's recommended, but in some cases may + # be too noisy due to issues in dependencies. + config.warnings = true + + # Many RSpec users commonly either run the entire suite or an individual + # file, and it's useful to allow more verbose output when running an + # individual spec file. + if config.files_to_run.one? + # Use the documentation formatter for detailed output, + # unless a formatter has already been configured + # (e.g. via a command-line flag). + config.default_formatter = "doc" + end + + # Print the 10 slowest examples and example groups at the + # end of the spec run, to help surface which specs are running + # particularly slow. + config.profile_examples = 10 + + # Run specs in random order to surface order dependencies. If you find an + # order dependency and want to debug it, you can fix the order by providing + # the seed, which is printed after each run. + # --seed 1234 + config.order = :random + + # Seed global randomization in this process using the `--seed` CLI option. + # Setting this allows you to use `--seed` to deterministically reproduce + # test failures related to randomization by passing the same `--seed` value + # as the one that triggered the failure. + Kernel.srand config.seed +=end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/rake_task.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/rake_task.rb new file mode 100644 index 00000000..1b60db03 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/rake_task.rb @@ -0,0 +1,190 @@ +require 'rake' +require 'rake/tasklib' +require 'rspec/support' + +RSpec::Support.require_rspec_support "ruby_features" + +# :nocov: +unless RSpec::Support.respond_to?(:require_rspec_core) + RSpec::Support.define_optimized_require_for_rspec(:core) { |f| require_relative "../#{f}" } +end +# :nocov: + +RSpec::Support.require_rspec_core "shell_escape" + +module RSpec + module Core + # RSpec rake task + # + # @see Rakefile + class RakeTask < ::Rake::TaskLib + include ::Rake::DSL if defined?(::Rake::DSL) + include RSpec::Core::ShellEscape + + # Default path to the RSpec executable. + DEFAULT_RSPEC_PATH = File.expand_path('../../../../exe/rspec', __FILE__) + + # Default pattern for spec files. + DEFAULT_PATTERN = 'spec/**{,/*/**}/*_spec.rb' + + # Name of task. Defaults to `:spec`. + attr_accessor :name + + # Files matching this pattern will be loaded. + # Defaults to `'spec/**{,/*/**}/*_spec.rb'`. + attr_accessor :pattern + + # Files matching this pattern will be excluded. + # Defaults to `nil`. + attr_accessor :exclude_pattern + + # Whether or not to fail Rake when an error occurs (typically when + # examples fail). Defaults to `true`. + attr_accessor :fail_on_error + + # A message to print to stderr when there are failures. + attr_accessor :failure_message + + if RUBY_VERSION < "1.9.0" || Support::Ruby.jruby? + # Run RSpec with a clean (empty) environment is not supported + # :nocov: + def with_clean_environment=(_value) + raise ArgumentError, "Running in a clean environment is not supported on Ruby versions before 1.9.0" + end + + # Run RSpec with a clean (empty) environment is not supported + def with_clean_environment + false + end + # :nocov: + else + # Run RSpec with a clean (empty) environment. + attr_accessor :with_clean_environment + end + + # Use verbose output. If this is set to true, the task will print the + # executed spec command to stdout. Defaults to `true`. + attr_accessor :verbose + + # Command line options to pass to ruby. Defaults to `nil`. + attr_accessor :ruby_opts + + # Path to RSpec. Defaults to the absolute path to the + # rspec binary from the loaded rspec-core gem. + attr_accessor :rspec_path + + # Command line options to pass to RSpec. Defaults to `nil`. + attr_accessor :rspec_opts + + def initialize(*args, &task_block) + @name = args.shift || :spec + @ruby_opts = nil + @rspec_opts = nil + @verbose = true + @fail_on_error = true + @rspec_path = DEFAULT_RSPEC_PATH + @pattern = DEFAULT_PATTERN + + define(args, &task_block) + end + + # @private + def run_task(verbose) + command = spec_command + puts command if verbose + + if with_clean_environment + return if system({}, command, :unsetenv_others => true) + else + return if system(command) + end + + puts failure_message if failure_message + + return unless fail_on_error + $stderr.puts "#{command} failed" if verbose + exit $?.exitstatus || 1 + end + + private + + # @private + def define(args, &task_block) + desc "Run RSpec code examples" unless ::Rake.application.last_description + + task name, *args do |_, task_args| + RakeFileUtils.__send__(:verbose, verbose) do + task_block.call(*[self, task_args].slice(0, task_block.arity)) if task_block + run_task verbose + end + end + end + + def file_inclusion_specification + if ENV['SPEC'] + FileList[ENV['SPEC']].sort + elsif String === pattern && !File.exist?(pattern) + return if [*rspec_opts].any? { |opt| opt =~ /--pattern/ } + "--pattern #{escape pattern}" + else + # Before RSpec 3.1, we used `FileList` to get the list of matched + # files, and then pass that along to the `rspec` command. Starting + # with 3.1, we prefer to pass along the pattern as-is to the `rspec` + # command, for 3 reasons: + # + # * It's *much* less verbose to pass one `--pattern` option than a + # long list of files. + # * It ensures `task.pattern` and `--pattern` have the same + # behavior. + # * It fixes a bug, where + # `task.pattern = pattern_that_matches_no_files` would run *all* + # files because it would cause no pattern or file args to get + # passed to `rspec`, which causes all files to get run. + # + # However, `FileList` is *far* more flexible than the `--pattern` + # option. Specifically, it supports individual files and directories, + # as well as arrays of files, directories and globs, as well as other + # `FileList` objects. + # + # For backwards compatibility, we have to fall back to using FileList + # if the user has passed a `pattern` option that will not work with + # `--pattern`. + # + # TODO: consider deprecating support for this and removing it in + # RSpec 4. + FileList[pattern].sort.map { |file| escape file } + end + end + + def file_exclusion_specification + " --exclude-pattern #{escape exclude_pattern}" if exclude_pattern + end + + def spec_command + cmd_parts = [] + cmd_parts << RUBY + cmd_parts << ruby_opts + cmd_parts << rspec_load_path + cmd_parts << escape(rspec_path) + cmd_parts << file_inclusion_specification + cmd_parts << file_exclusion_specification + cmd_parts << rspec_opts + cmd_parts.flatten.reject(&blank).join(" ") + end + + def blank + lambda { |s| s.nil? || s == "" } + end + + def rspec_load_path + @rspec_load_path ||= begin + core_and_support = $LOAD_PATH.grep( + /#{File::SEPARATOR}rspec-(core|support)[^#{File::SEPARATOR}]*#{File::SEPARATOR}lib/ + ).uniq + + "-I#{core_and_support.map { |file| escape file }.join(File::PATH_SEPARATOR)}" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/reporter.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/reporter.rb new file mode 100644 index 00000000..d513f3f9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/reporter.rb @@ -0,0 +1,266 @@ +module RSpec::Core + # A reporter will send notifications to listeners, usually formatters for the + # spec suite run. + class Reporter + # @private + RSPEC_NOTIFICATIONS = Set.new( + [ + :close, :deprecation, :deprecation_summary, :dump_failures, :dump_pending, + :dump_profile, :dump_summary, :example_failed, :example_group_finished, + :example_group_started, :example_passed, :example_pending, :example_started, + :message, :seed, :start, :start_dump, :stop, :example_finished + ]) + + def initialize(configuration) + @configuration = configuration + @listeners = Hash.new { |h, k| h[k] = Set.new } + @examples = [] + @failed_examples = [] + @pending_examples = [] + @duration = @start = @load_time = nil + @non_example_exception_count = 0 + @setup_default = lambda {} + @setup = false + @profiler = nil + end + + # @private + attr_reader :examples, :failed_examples, :pending_examples + + # Registers a listener to a list of notifications. The reporter will send + # notification of events to all registered listeners. + # + # @param listener [Object] An object that wishes to be notified of reporter + # events + # @param notifications [Array] Array of symbols represents the events a + # listener wishes to subscribe too + def register_listener(listener, *notifications) + notifications.each do |notification| + @listeners[notification.to_sym] << listener + end + true + end + + # @private + def prepare_default(loader, output_stream, deprecation_stream) + @setup_default = lambda do + loader.setup_default output_stream, deprecation_stream + end + end + + # @private + def registered_listeners(notification) + @listeners[notification].to_a + end + + # @overload report(count, &block) + # @overload report(count, &block) + # @param expected_example_count [Integer] the number of examples being run + # @yield [Block] block yields itself for further reporting. + # + # Initializes the report run and yields itself for further reporting. The + # block is required, so that the reporter can manage cleaning up after the + # run. + # + # @example + # + # reporter.report(group.examples.size) do |r| + # example_groups.map {|g| g.run(r) } + # end + # + def report(expected_example_count) + start(expected_example_count) + begin + yield self + ensure + finish + end + end + + # @param exit_code [Integer] the exit_code to be return by the reporter + # + # Reports a run that exited early without having run any examples. + # + def exit_early(exit_code) + report(0) { exit_code } + end + + # @private + def start(expected_example_count, time=RSpec::Core::Time.now) + @start = time + @load_time = (@start - @configuration.start_time).to_f + notify :seed, Notifications::SeedNotification.new(@configuration.seed, seed_used?) + notify :start, Notifications::StartNotification.new(expected_example_count, @load_time) + end + + # @param message [#to_s] A message object to send to formatters + # + # Send a custom message to supporting formatters. + def message(message) + notify :message, Notifications::MessageNotification.new(message) + end + + # @param event [Symbol] Name of the custom event to trigger on formatters + # @param options [Hash] Hash of arguments to provide via `CustomNotification` + # + # Publish a custom event to supporting registered formatters. + # @see RSpec::Core::Notifications::CustomNotification + def publish(event, options={}) + if RSPEC_NOTIFICATIONS.include? event + raise "RSpec::Core::Reporter#publish is intended for sending custom " \ + "events not internal RSpec ones, please rename your custom event." + end + notify event, Notifications::CustomNotification.for(options) + end + + # @private + def example_group_started(group) + notify :example_group_started, Notifications::GroupNotification.new(group) unless group.descendant_filtered_examples.empty? + end + + # @private + def example_group_finished(group) + notify :example_group_finished, Notifications::GroupNotification.new(group) unless group.descendant_filtered_examples.empty? + end + + # @private + def example_started(example) + @examples << example + notify :example_started, Notifications::ExampleNotification.for(example) + end + + # @private + def example_finished(example) + notify :example_finished, Notifications::ExampleNotification.for(example) + end + + # @private + def example_passed(example) + notify :example_passed, Notifications::ExampleNotification.for(example) + end + + # @private + def example_failed(example) + @failed_examples << example + notify :example_failed, Notifications::ExampleNotification.for(example) + end + + # @private + def example_pending(example) + @pending_examples << example + notify :example_pending, Notifications::ExampleNotification.for(example) + end + + # @private + def deprecation(hash) + notify :deprecation, Notifications::DeprecationNotification.from_hash(hash) + end + + # @private + # Provides a way to notify of an exception that is not tied to any + # particular example (such as an exception encountered in a :suite hook). + # Exceptions will be formatted the same way they normally are. + def notify_non_example_exception(exception, context_description) + @configuration.world.non_example_failure = true + @non_example_exception_count += 1 + + example = Example.new(AnonymousExampleGroup, context_description, {}) + presenter = Formatters::ExceptionPresenter.new(exception, example, :indentation => 0) + message presenter.fully_formatted(nil) + end + + # @private + def finish + close_after do + examples_notification = Notifications::ExamplesNotification.new(self) + stop(examples_notification) + notify :start_dump, Notifications::NullNotification + notify :dump_pending, examples_notification + notify :dump_failures, examples_notification + notify :deprecation_summary, Notifications::NullNotification + unless mute_profile_output? + notify :dump_profile, Notifications::ProfileNotification.new(@duration, @examples, + @configuration.profile_examples, + @profiler.example_groups) + end + notify :dump_summary, Notifications::SummaryNotification.new(@duration, @examples, @failed_examples, + @pending_examples, @load_time, + @non_example_exception_count) + notify :seed, Notifications::SeedNotification.new(@configuration.seed, seed_used?) + end + end + + # @private + def close_after + yield + ensure + close + end + + # @private + def stop(notification) + @duration = (RSpec::Core::Time.now - @start).to_f if @start + notify :stop, notification + end + + # @private + def notify(event, notification) + ensure_listeners_ready + registered_listeners(event).each do |formatter| + formatter.__send__(event, notification) + end + end + + # @private + def abort_with(msg, exit_status) + message(msg) + close + exit!(exit_status) + end + + # @private + def fail_fast_limit_met? + return false unless (fail_fast = @configuration.fail_fast) + + if fail_fast == true + @failed_examples.any? + else + fail_fast <= @failed_examples.size + end + end + + private + + def ensure_listeners_ready + return if @setup + + @setup_default.call + @profiler = Profiler.new + register_listener @profiler, *Profiler::NOTIFICATIONS + @setup = true + end + + def close + notify :close, Notifications::NullNotification + end + + def mute_profile_output? + # Don't print out profiled info if there are failures and `--fail-fast` is + # used, it just clutters the output. + !@configuration.profile_examples? || fail_fast_limit_met? + end + + def seed_used? + @configuration.seed && @configuration.seed_used? + end + end + + # @private + # # Used in place of a {Reporter} for situations where we don't want reporting output. + class NullReporter + def self.method_missing(*) + # ignore + end + private_class_method :method_missing + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/ruby_project.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/ruby_project.rb new file mode 100644 index 00000000..156f89be --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/ruby_project.rb @@ -0,0 +1,53 @@ +# This is borrowed (slightly modified) from Scott Taylor's +# project_path project: +# http://github.com/smtlaissezfaire/project_path +module RSpec + module Core + # @private + module RubyProject + def add_to_load_path(*dirs) + dirs.each { |dir| add_dir_to_load_path(File.join(root, dir)) } + end + + def add_dir_to_load_path(dir) + $LOAD_PATH.unshift(dir) unless $LOAD_PATH.include?(dir) + end + + def root + @project_root ||= determine_root + end + + def determine_root + find_first_parent_containing('spec') || '.' + end + + def find_first_parent_containing(dir) + ascend_until { |path| File.exist?(File.join(path, dir)) } + end + + def ascend_until + fs = File::SEPARATOR + escaped_slash = "\\#{fs}" + special = "_RSPEC_ESCAPED_SLASH_" + project_path = File.expand_path(".") + parts = project_path.gsub(escaped_slash, special).squeeze(fs).split(fs).map do |x| + x.gsub(special, escaped_slash) + end + + until parts.empty? + path = parts.join(fs) + path = fs if path == "" + return path if yield(path) + parts.pop + end + end + + module_function :add_to_load_path + module_function :add_dir_to_load_path + module_function :root + module_function :determine_root + module_function :find_first_parent_containing + module_function :ascend_until + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/runner.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/runner.rb new file mode 100644 index 00000000..16d07efe --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/runner.rb @@ -0,0 +1,216 @@ +module RSpec + module Core + # Provides the main entry point to run a suite of RSpec examples. + class Runner + # @attr_reader + # @private + attr_reader :options, :configuration, :world + + # Register an `at_exit` hook that runs the suite when the process exits. + # + # @note This is not generally needed. The `rspec` command takes care + # of running examples for you without involving an `at_exit` + # hook. This is only needed if you are running specs using + # the `ruby` command, and even then, the normal way to invoke + # this is by requiring `rspec/autorun`. + def self.autorun + if autorun_disabled? + RSpec.deprecate("Requiring `rspec/autorun` when running RSpec via the `rspec` command") + return + elsif installed_at_exit? || running_in_drb? + return + end + + at_exit { perform_at_exit } + @installed_at_exit = true + end + + # @private + def self.perform_at_exit + # Don't bother running any specs and just let the program terminate + # if we got here due to an unrescued exception (anything other than + # SystemExit, which is raised when somebody calls Kernel#exit). + return unless $!.nil? || $!.is_a?(SystemExit) + + # We got here because either the end of the program was reached or + # somebody called Kernel#exit. Run the specs and then override any + # existing exit status with RSpec's exit status if any specs failed. + invoke + end + + # Runs the suite of specs and exits the process with an appropriate exit + # code. + def self.invoke + disable_autorun! + status = run(ARGV, $stderr, $stdout).to_i + exit(status) if status != 0 + end + + # Run a suite of RSpec examples. Does not exit. + # + # This is used internally by RSpec to run a suite, but is available + # for use by any other automation tool. + # + # If you want to run this multiple times in the same process, and you + # want files like `spec_helper.rb` to be reloaded, be sure to load `load` + # instead of `require`. + # + # @param args [Array] command-line-supported arguments + # @param err [IO] error stream + # @param out [IO] output stream + # @return [Fixnum] exit status code. 0 if all specs passed, + # or the configured failure exit code (1 by default) if specs + # failed. + def self.run(args, err=$stderr, out=$stdout) + trap_interrupt + options = ConfigurationOptions.new(args) + + if options.options[:runner] + options.options[:runner].call(options, err, out) + else + new(options).run(err, out) + end + end + + def initialize(options, configuration=RSpec.configuration, world=RSpec.world) + @options = options + @configuration = configuration + @world = world + end + + # Configures and runs a spec suite. + # + # @param err [IO] error stream + # @param out [IO] output stream + def run(err, out) + setup(err, out) + return @configuration.reporter.exit_early(exit_code) if RSpec.world.wants_to_quit + + run_specs(@world.ordered_example_groups).tap do + persist_example_statuses + end + end + + # Wires together the various configuration objects and state holders. + # + # @param err [IO] error stream + # @param out [IO] output stream + def setup(err, out) + configure(err, out) + return if RSpec.world.wants_to_quit + + @configuration.load_spec_files + ensure + @world.announce_filters + end + + # Runs the provided example groups. + # + # @param example_groups [Array] groups to run + # @return [Fixnum] exit status code. 0 if all specs passed, + # or the configured failure exit code (1 by default) if specs + # failed. + def run_specs(example_groups) + examples_count = @world.example_count(example_groups) + examples_passed = @configuration.reporter.report(examples_count) do |reporter| + @configuration.with_suite_hooks do + if examples_count == 0 && @configuration.fail_if_no_examples + return @configuration.failure_exit_code + end + + example_groups.map { |g| g.run(reporter) }.all? + end + end + + exit_code(examples_passed) + end + + # @private + def configure(err, out) + @configuration.error_stream = err + @configuration.output_stream = out if @configuration.output_stream == $stdout + @options.configure(@configuration) + end + + # @private + def self.disable_autorun! + @autorun_disabled = true + end + + # @private + def self.autorun_disabled? + @autorun_disabled ||= false + end + + # @private + def self.installed_at_exit? + @installed_at_exit ||= false + end + + # @private + def self.running_in_drb? + return false unless defined?(DRb) + + server = begin + DRb.current_server + rescue DRb::DRbServerNotFound + return false + end + + return false unless server && server.alive? + + require 'socket' + require 'uri' + + local_ipv4 = begin + IPSocket.getaddress(Socket.gethostname) + rescue SocketError + return false + end + + ["127.0.0.1", "localhost", local_ipv4].any? { |addr| addr == URI(DRb.current_server.uri).host } + end + + # @private + def self.trap_interrupt + trap('INT') { handle_interrupt } + end + + # @private + def self.handle_interrupt + if RSpec.world.wants_to_quit + exit!(1) + else + RSpec.world.wants_to_quit = true + + $stderr.puts( + "\nRSpec is shutting down and will print the summary report... Interrupt again to force quit " \ + "(warning: at_exit hooks will be skipped if you force quit)." + ) + end + end + + # @private + def exit_code(examples_passed=false) + return @configuration.error_exit_code || @configuration.failure_exit_code if @world.non_example_failure + return @configuration.failure_exit_code unless examples_passed + + 0 + end + + private + + def persist_example_statuses + return if @configuration.dry_run + return unless (path = @configuration.example_status_persistence_file_path) + + ExampleStatusPersister.persist(@world.all_examples, path) + rescue SystemCallError => e + RSpec.warning "Could not write example statuses to #{path} (configured as " \ + "`config.example_status_persistence_file_path`) due to a " \ + "system error: #{e.inspect}. Please check that the config " \ + "option is set to an accessible, valid file path", :call_site => nil + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/sandbox.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/sandbox.rb new file mode 100644 index 00000000..e7d518c2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/sandbox.rb @@ -0,0 +1,37 @@ +module RSpec + module Core + # A sandbox isolates the enclosed code into an environment that looks 'new' + # meaning globally accessed objects are reset for the duration of the + # sandbox. + # + # @note This module is not normally available. You must require + # `rspec/core/sandbox` to load it. + module Sandbox + # Execute a provided block with RSpec global objects (configuration, + # world) reset. This is used to test RSpec with RSpec. + # + # When calling this the configuration is passed into the provided block. + # Use this to set custom configs for your sandboxed examples. + # + # ``` + # Sandbox.sandboxed do |config| + # config.before(:context) { RSpec.current_example = nil } + # end + # ``` + def self.sandboxed + orig_config = RSpec.configuration + orig_world = RSpec.world + orig_example = RSpec.current_example + + RSpec.configuration = RSpec::Core::Configuration.new + RSpec.world = RSpec::Core::World.new(RSpec.configuration) + + yield RSpec.configuration + ensure + RSpec.configuration = orig_config + RSpec.world = orig_world + RSpec.current_example = orig_example + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/set.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/set.rb new file mode 100644 index 00000000..ae978106 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/set.rb @@ -0,0 +1,54 @@ +module RSpec + module Core + # @private + # + # We use this to replace `::Set` so we can have the advantage of + # constant time key lookups for unique arrays but without the + # potential to pollute a developers environment with an extra + # piece of the stdlib. This helps to prevent false positive + # builds. + # + class Set + include Enumerable + + def initialize(array=[]) + @values = {} + merge(array) + end + + def empty? + @values.empty? + end + + def <<(key) + @values[key] = true + self + end + + def delete(key) + @values.delete(key) + end + + def each(&block) + @values.keys.each(&block) + self + end + + def include?(key) + @values.key?(key) + end + + def merge(values) + values.each do |key| + @values[key] = true + end + self + end + + def clear + @values.clear + self + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/shared_context.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/shared_context.rb new file mode 100644 index 00000000..6de7f649 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/shared_context.rb @@ -0,0 +1,55 @@ +module RSpec + module Core + # Exposes {ExampleGroup}-level methods to a module, so you can include that + # module in an {ExampleGroup}. + # + # @example + # + # module LoggedInAsAdmin + # extend RSpec::Core::SharedContext + # before(:example) do + # log_in_as :admin + # end + # end + # + # describe "admin section" do + # include LoggedInAsAdmin + # # ... + # end + module SharedContext + # @private + def included(group) + __shared_context_recordings.each do |recording| + recording.playback_onto(group) + end + end + + # @private + def __shared_context_recordings + @__shared_context_recordings ||= [] + end + + # @private + Recording = Struct.new(:method_name, :args, :block) do + def playback_onto(group) + group.__send__(method_name, *args, &block) + end + end + + # @private + def self.record(methods) + methods.each do |meth| + define_method(meth) do |*args, &block| + __shared_context_recordings << Recording.new(meth, args, block) + end + end + end + + # @private + record [:describe, :context] + Hooks.instance_methods(false) + + MemoizedHelpers::ClassMethods.instance_methods(false) + end + end + # @private + SharedContext = Core::SharedContext +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/shared_example_group.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/shared_example_group.rb new file mode 100644 index 00000000..3d9efce2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/shared_example_group.rb @@ -0,0 +1,271 @@ +RSpec::Support.require_rspec_support "with_keywords_when_needed" + +module RSpec + module Core + # Represents some functionality that is shared with multiple example groups. + # The functionality is defined by the provided block, which is lazily + # eval'd when the `SharedExampleGroupModule` instance is included in an example + # group. + class SharedExampleGroupModule < Module + # @private + attr_reader :definition + + def initialize(description, definition, metadata) + @description = description + @definition = definition + @metadata = metadata + end + + # Provides a human-readable representation of this module. + def inspect + "#<#{self.class.name} #{@description.inspect}>" + end + alias to_s inspect + + # Ruby callback for when a module is included in another module is class. + # Our definition evaluates the shared group block in the context of the + # including example group. + def included(klass) + inclusion_line = klass.metadata[:location] + include_in klass, inclusion_line, [], nil + end + + # @private + def include_in(klass, inclusion_line, args, customization_block) + klass.update_inherited_metadata(@metadata) unless @metadata.empty? + + SharedExampleGroupInclusionStackFrame.with_frame(@description, inclusion_line) do + RSpec::Support::WithKeywordsWhenNeeded.class_exec(klass, *args, &@definition) + klass.class_exec(&customization_block) if customization_block + end + end + end + + # Shared example groups let you define common context and/or common + # examples that you wish to use in multiple example groups. + # + # When defined, the shared group block is stored for later evaluation. + # It can later be included in an example group either explicitly + # (using `include_examples`, `include_context` or `it_behaves_like`) + # or implicitly (via matching metadata). + # + # Named shared example groups are scoped based on where they are + # defined. Shared groups defined in an example group are available + # for inclusion in that example group or any child example groups, + # but not in any parent or sibling example groups. Shared example + # groups defined at the top level can be included from any example group. + module SharedExampleGroup + # @overload shared_examples(name, &block) + # @param name [String, Symbol, Module] identifer to use when looking up + # this shared group + # @param block The block to be eval'd + # @overload shared_examples(name, metadata, &block) + # @param name [String, Symbol, Module] identifer to use when looking up + # this shared group + # @param metadata [Array, Hash] metadata to attach to this + # group; any example group or example with matching metadata will + # automatically include this shared example group. + # @param block The block to be eval'd + # + # Stores the block for later use. The block will be evaluated + # in the context of an example group via `include_examples`, + # `include_context`, or `it_behaves_like`. + # + # @example + # shared_examples "auditable" do + # it "stores an audit record on save!" do + # expect { auditable.save! }.to change(Audit, :count).by(1) + # end + # end + # + # RSpec.describe Account do + # it_behaves_like "auditable" do + # let(:auditable) { Account.new } + # end + # end + # + # @see ExampleGroup.it_behaves_like + # @see ExampleGroup.include_examples + # @see ExampleGroup.include_context + def shared_examples(name, *args, &block) + top_level = self == ExampleGroup + if top_level && RSpec::Support.thread_local_data[:in_example_group] + raise "Creating isolated shared examples from within a context is " \ + "not allowed. Remove `RSpec.` prefix or move this to a " \ + "top-level scope." + end + + RSpec.world.shared_example_group_registry.add(self, name, *args, &block) + end + alias shared_context shared_examples + alias shared_examples_for shared_examples + + # @api private + # + # Shared examples top level DSL. + module TopLevelDSL + # @private + def self.definitions + proc do + def shared_examples(name, *args, &block) + RSpec.world.shared_example_group_registry.add(:main, name, *args, &block) + end + alias shared_context shared_examples + alias shared_examples_for shared_examples + end + end + + # @private + def self.exposed_globally? + @exposed_globally ||= false + end + + # @api private + # + # Adds the top level DSL methods to Module and the top level binding. + def self.expose_globally! + return if exposed_globally? + Core::DSL.change_global_dsl(&definitions) + @exposed_globally = true + end + + # @api private + # + # Removes the top level DSL methods to Module and the top level binding. + def self.remove_globally! + return unless exposed_globally? + + Core::DSL.change_global_dsl do + undef shared_examples + undef shared_context + undef shared_examples_for + end + + @exposed_globally = false + end + end + + # @private + class Registry + def add(context, name, *metadata_args, &block) + unless block + RSpec.warning "Shared example group #{name} was defined without a "\ + "block and will have no effect. Please define a "\ + "block or remove the definition." + end + + if RSpec.configuration.shared_context_metadata_behavior == :trigger_inclusion + return legacy_add(context, name, *metadata_args, &block) + end + + unless valid_name?(name) + raise ArgumentError, "Shared example group names can only be a string, " \ + "symbol or module but got: #{name.inspect}" + end + + ensure_block_has_source_location(block) { CallerFilter.first_non_rspec_line } + warn_if_key_taken context, name, block + + metadata = Metadata.build_hash_from(metadata_args) + shared_module = SharedExampleGroupModule.new(name, block, metadata) + shared_example_groups[context][name] = shared_module + end + + def find(lookup_contexts, name) + lookup_contexts.each do |context| + found = shared_example_groups[context][name] + return found if found + end + + shared_example_groups[:main][name] + end + + private + + # TODO: remove this in RSpec 4. This exists only to support + # `config.shared_context_metadata_behavior == :trigger_inclusion`, + # the legacy behavior of shared context metadata, which we do + # not want to support in RSpec 4. + def legacy_add(context, name, *metadata_args, &block) + ensure_block_has_source_location(block) { CallerFilter.first_non_rspec_line } + shared_module = SharedExampleGroupModule.new(name, block, {}) + + if valid_name?(name) + warn_if_key_taken context, name, block + shared_example_groups[context][name] = shared_module + else + metadata_args.unshift name + end + + return if metadata_args.empty? + RSpec.configuration.include shared_module, *metadata_args + end + + def shared_example_groups + @shared_example_groups ||= Hash.new { |hash, context| hash[context] = {} } + end + + def valid_name?(candidate) + case candidate + when String, Symbol, Module then true + else false + end + end + + def warn_if_key_taken(context, key, new_block) + existing_module = shared_example_groups[context][key] + return unless existing_module + + old_definition_location = formatted_location existing_module.definition + new_definition_location = formatted_location new_block + loaded_spec_files = RSpec.configuration.loaded_spec_files + + if loaded_spec_files.include?(new_definition_location) && old_definition_location == new_definition_location + RSpec.warn_with <<-WARNING.gsub(/^ +\|/, ''), :call_site => nil + |WARNING: Your shared example group, '#{key}', defined at: + | #{old_definition_location} + |was automatically loaded by RSpec because the file name + |matches the configured autoloading pattern (#{RSpec.configuration.pattern}), + |and is also being required from somewhere else. To fix this + |warning, either rename the file to not match the pattern, or + |do not explicitly require the file. + WARNING + else + RSpec.warn_with <<-WARNING.gsub(/^ +\|/, ''), :call_site => nil + |WARNING: Shared example group '#{key}' has been previously defined at: + | #{old_definition_location} + |...and you are now defining it at: + | #{new_definition_location} + |The new definition will overwrite the original one. + WARNING + end + end + + if RUBY_VERSION.to_f >= 1.9 + def formatted_location(block) + block.source_location.join(":") + end + else # 1.8.7 + # :nocov: + def formatted_location(block) + block.source_location.join(":").gsub(/:in.*$/, '') + end + # :nocov: + end + + if Proc.method_defined?(:source_location) + def ensure_block_has_source_location(_block); end + else # for 1.8.7 + # :nocov: + def ensure_block_has_source_location(block) + source_location = yield.split(':') + block.extend(Module.new { define_method(:source_location) { source_location } }) + end + # :nocov: + end + end + end + end + + instance_exec(&Core::SharedExampleGroup::TopLevelDSL.definitions) +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/shell_escape.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/shell_escape.rb new file mode 100644 index 00000000..a92feae8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/shell_escape.rb @@ -0,0 +1,49 @@ +module RSpec + module Core + # @private + # Deals with the fact that `shellwords` only works on POSIX systems. + module ShellEscape + module_function + + def quote(argument) + "'#{argument.to_s.gsub("'", "\\\\'")}'" + end + + if RSpec::Support::OS.windows? + # :nocov: + alias escape quote + # :nocov: + else + require 'shellwords' + + def escape(shell_command) + Shellwords.escape(shell_command.to_s) + end + end + + # Known shells that require quoting: zsh, csh, tcsh. + # + # Feel free to add other shells to this list that are known to + # allow `rspec ./some_spec.rb[1:1]` syntax without quoting the id. + # + # @private + SHELLS_ALLOWING_UNQUOTED_IDS = %w[ bash ksh fish ] + + def conditionally_quote(id) + return id if shell_allows_unquoted_ids? + quote(id) + end + + def shell_allows_unquoted_ids? + # Note: ENV['SHELL'] isn't necessarily the shell the user is currently running. + # According to http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html: + # "This variable shall represent a pathname of the user's preferred command language interpreter." + # + # It's the best we can easily do, though. We err on the side of safety (quoting + # the id when not actually needed) so it's not a big deal if the user is actually + # using a different shell. + SHELLS_ALLOWING_UNQUOTED_IDS.include?(ENV['SHELL'].to_s.split('/').last) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/test_unit_assertions_adapter.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/test_unit_assertions_adapter.rb new file mode 100644 index 00000000..d84ecb14 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/test_unit_assertions_adapter.rb @@ -0,0 +1,30 @@ +require 'test/unit/assertions' + +module RSpec + module Core + # @private + module TestUnitAssertionsAdapter + include ::Test::Unit::Assertions + + # If using test/unit from Ruby core with Ruby 1.9+, it includes + # MiniTest::Assertions by default. Note the upcasing of 'Test'. + # + # If the test/unit gem is being loaded, it will not include any minitest + # assertions. + # + # Only if Minitest 5.x is included / loaded do we need to worry about + # adding a shim for the new updates. Thus instead of checking on the + # RUBY_VERSION we need to check ancestors. + begin + # MiniTest is 4.x. + # Minitest is 5.x. + if ancestors.include?(::Minitest::Assertions) + require 'rspec/core/minitest_assertions_adapter' + include ::RSpec::Core::MinitestAssertionsAdapter + end + rescue NameError + # No-op. Minitest 5.x was not loaded. + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/version.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/version.rb new file mode 100644 index 00000000..582b24eb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/version.rb @@ -0,0 +1,9 @@ +module RSpec + module Core + # Version information for RSpec Core. + module Version + # Current version of RSpec Core, in semantic versioning format. + STRING = '3.13.4' + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/warnings.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/warnings.rb new file mode 100644 index 00000000..b8800591 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/warnings.rb @@ -0,0 +1,40 @@ +require "rspec/support/warnings" + +module RSpec + module Core + # @private + module Warnings + # @private + # + # Used internally to print deprecation warnings. + def deprecate(deprecated, data={}) + RSpec.configuration.reporter.deprecation( + { + :deprecated => deprecated, + :call_site => CallerFilter.first_non_rspec_line + }.merge(data) + ) + end + + # @private + # + # Used internally to print deprecation warnings. + def warn_deprecation(message, opts={}) + RSpec.configuration.reporter.deprecation opts.merge(:message => message) + end + + # @private + def warn_with(message, options={}) + if options[:use_spec_location_as_call_site] + message += "." unless message.end_with?(".") + + if RSpec.current_example + message += " Warning generated from spec at `#{RSpec.current_example.location}`." + end + end + + super(message, options) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/world.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/world.rb new file mode 100644 index 00000000..6fb43965 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-core-3.13.4/lib/rspec/core/world.rb @@ -0,0 +1,287 @@ +module RSpec + module Core + # @api private + # + # Internal container for global non-configuration data. + class World + # @private + attr_reader :example_groups, :filtered_examples, :example_group_counts_by_spec_file + + # Used internally to determine what to do when a SIGINT is received. + attr_accessor :wants_to_quit + + # Used internally to signify that a SystemExit occurred in + # `Configuration#load_file_handling_errors`, and thus examples cannot + # be counted accurately. Specifically, we cannot accurately report + # "No examples found". + # @private + attr_accessor :rspec_is_quitting + + # Used internally to signal that a failure outside of an example + # has occurred, and that therefore the exit status should indicate + # the run failed. + # @private + attr_accessor :non_example_failure + + def initialize(configuration=RSpec.configuration) + @wants_to_quit = false + @rspec_is_quitting = false + @configuration = configuration + configuration.world = self + @example_groups = [] + @example_group_counts_by_spec_file = Hash.new(0) + prepare_example_filtering + end + + # @api public + # + # Prepares filters so that they apply to example groups when they run. + # + # This is a separate method so that filters can be modified/replaced and + # examples refiltered during a process's lifetime, which can be useful for + # a custom runner. + def prepare_example_filtering + @filtered_examples = Hash.new do |hash, group| + hash[group] = filter_manager.prune(group.examples) + end + end + + # @api private + # + # Apply ordering strategy from configuration to example groups. + def ordered_example_groups + ordering_strategy = @configuration.ordering_registry.fetch(:global) + ordering_strategy.order(@example_groups) + end + + # @api private + # + # Reset world to 'scratch' before running suite. + def reset + RSpec::ExampleGroups.remove_all_constants + example_groups.clear + @sources_by_path.clear if defined?(@sources_by_path) + @syntax_highlighter = nil + @example_group_counts_by_spec_file = Hash.new(0) + end + + # @private + def filter_manager + @configuration.filter_manager + end + + # @private + def registered_example_group_files + @example_group_counts_by_spec_file.keys + end + + # @api private + # + # Records an example group. + def record(example_group) + @configuration.on_example_group_definition_callbacks.each { |block| block.call(example_group) } + @example_group_counts_by_spec_file[example_group.metadata[:absolute_file_path]] += 1 + end + + # @private + def num_example_groups_defined_in(file) + @example_group_counts_by_spec_file[file] + end + + # @private + def shared_example_group_registry + @shared_example_group_registry ||= SharedExampleGroup::Registry.new + end + + # @private + def inclusion_filter + @configuration.inclusion_filter + end + + # @private + def exclusion_filter + @configuration.exclusion_filter + end + + # @api private + # + # Get count of examples to be run. + def example_count(groups=example_groups) + FlatMap.flat_map(groups) { |g| g.descendants }. + inject(0) { |a, e| a + e.filtered_examples.size } + end + + # @private + def all_example_groups + FlatMap.flat_map(example_groups) { |g| g.descendants } + end + + # @private + def all_examples + FlatMap.flat_map(all_example_groups) { |g| g.examples } + end + + # @private + # Traverses the tree of each top level group. + # For each it yields the group, then the children, recursively. + # Halts the traversal of a branch of the tree as soon as the passed block returns true. + # Note that siblings groups and their sub-trees will continue to be explored. + # This is intended to make it easy to find the top-most group that satisfies some + # condition. + def traverse_example_group_trees_until(&block) + example_groups.each do |group| + group.traverse_tree_until(&block) + end + end + + # @api private + # + # Find line number of previous declaration. + def preceding_declaration_line(absolute_file_name, filter_line) + line_numbers = descending_declaration_line_numbers_by_file.fetch(absolute_file_name) do + return nil + end + + line_numbers.find { |num| num <= filter_line } + end + + # @private + def reporter + @configuration.reporter + end + + # @private + def source_from_file(path) + unless defined?(@sources_by_path) + RSpec::Support.require_rspec_support 'source' + @sources_by_path = {} + end + + @sources_by_path[path] ||= Support::Source.from_file(path) + end + + # @private + def syntax_highlighter + @syntax_highlighter ||= Formatters::SyntaxHighlighter.new(@configuration) + end + + # @api private + # + # Notify reporter of filters. + def announce_filters + fail_if_config_and_cli_options_invalid + filter_announcements = [] + + announce_inclusion_filter filter_announcements + announce_exclusion_filter filter_announcements + + unless filter_manager.empty? + if filter_announcements.length == 1 + report_filter_message("Run options: #{filter_announcements[0]}") + else + report_filter_message("Run options:\n #{filter_announcements.join("\n ")}") + end + end + + if @configuration.run_all_when_everything_filtered? && example_count.zero? && !@configuration.only_failures? + report_filter_message("#{everything_filtered_message}; ignoring #{inclusion_filter.description}") + filtered_examples.clear + inclusion_filter.clear + end + + return unless example_count.zero? + + example_groups.clear + unless rspec_is_quitting + if filter_manager.empty? + report_filter_message("No examples found.") + elsif exclusion_filter.empty? || inclusion_filter.empty? + report_filter_message(everything_filtered_message) + end + end + end + + # @private + def report_filter_message(message) + reporter.message(message) unless @configuration.silence_filter_announcements? + end + + # @private + def everything_filtered_message + "\nAll examples were filtered out" + end + + # @api private + # + # Add inclusion filters to announcement message. + def announce_inclusion_filter(announcements) + return if inclusion_filter.empty? + + announcements << "include #{inclusion_filter.description}" + end + + # @api private + # + # Add exclusion filters to announcement message. + def announce_exclusion_filter(announcements) + return if exclusion_filter.empty? + + announcements << "exclude #{exclusion_filter.description}" + end + + private + + def descending_declaration_line_numbers_by_file + @descending_declaration_line_numbers_by_file ||= begin + declaration_locations = FlatMap.flat_map(example_groups, &:declaration_locations) + hash_of_arrays = Hash.new { |h, k| h[k] = [] } + + # TODO: change `inject` to `each_with_object` when we drop 1.8.7 support. + line_nums_by_file = declaration_locations.inject(hash_of_arrays) do |hash, (file_name, line_number)| + hash[file_name] << line_number + hash + end + + line_nums_by_file.each_value do |list| + list.sort! + list.reverse! + end + end + end + + def fail_if_config_and_cli_options_invalid + return unless @configuration.only_failures_but_not_configured? + + reporter.abort_with( + "\nTo use `--only-failures`, you must first set " \ + "`config.example_status_persistence_file_path`.", + 1 # exit code + ) + end + + # @private + # Provides a null implementation for initial use by configuration. + module Null + def self.non_example_failure; end + def self.non_example_failure=(_); end + + def self.registered_example_group_files + [] + end + + def self.traverse_example_group_trees_until + end + + # :nocov: + def self.example_groups + [] + end + + def self.all_example_groups + [] + end + # :nocov: + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/.document b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/.document new file mode 100644 index 00000000..52a564f6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/.document @@ -0,0 +1,5 @@ +lib/**/*.rb +- +README.md +LICENSE.md +Changelog.md diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/.yardopts b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/.yardopts new file mode 100644 index 00000000..9555b8e5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/.yardopts @@ -0,0 +1,6 @@ +--exclude features +--no-private +--markup markdown +- +Changelog.md +LICENSE.md diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/Changelog.md b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/Changelog.md new file mode 100644 index 00000000..fc7d5f02 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/Changelog.md @@ -0,0 +1,1366 @@ +### Development +[Full Changelog](https://github.com/rspec/rspec/compare/rspec-expectations-v3.13.4...3-13-maintenance) + +### 3.13.5 / 2025-05-27 +[Full Changelog](https://github.com/rspec/rspec/compare/rspec-expectations-v3.13.4...rspec-expectations-v3.13.5) + +Bug Fixes: + +* Fix links in gemspec to point to the monorepo / homepage. + +### 3.13.4 / 2025-05-01 +[Full Changelog](https://github.com/rspec/rspec/compare/rspec-expectations-v3.13.3...rspec-expectations-v3.13.4) + +Bug Fixes: + +* Prevent `match` from trying to compare strings and arrays using `Array#match`. (Joseph Haig, rspec/rspec#183) + +### 3.13.3 / 2024-09-07 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.13.2...v3.13.3) + +Bug Fixes: + +* Fix passing a regular expression to the `include` matcher without a count constraint. + (Jon Rowe, rspec/rspec-expectations#1485) + +### 3.13.2 / 2024-08-20 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.13.1...v3.13.2) + +Bug Fixes: + +* When using null object doubles, prevent typos triggering dynamic matchers. + (Eric Mueller, rspec/rspec-expectations#1455) +* Use `RSpec.warning` for an expectation warning rather than `Kernel.warn`. (Jon Rowe, rspec/rspec-expectations#1472) +* Prevent mismatched use of block and value matchers in compound expectations. (Phil Pirozhkov, rspec/rspec-expectations#1476) +* Raise an error when passing no arguments to the `include` matcher. (Eric Mueller, rspec/rspec-expectations#1479) + +### 3.13.1 / 2024-06-13 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.13.0...v3.13.1) + +Bug Fixes: + +* Fix the "false positive" warning message when using a negated `raise_error` matcher + with a `RegExp` instance. (Eric Mueller, rspec/rspec-expectations#1456) + +### 3.13.0 / 2024-02-04 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.4...v3.13.0) + +Enhancements: + +* Update `eq` and `eql` matchers to better highlight difference in string encoding. + (Alan Foster, rspec/rspec-expectations#1425) + +### 3.12.4 / 2024-02-04 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.3...v3.12.4) + +Bug Fixes: + +* Fix the diff for redefined `actual` and reassigned `@actual` in compound + expectations failure messages. (Phil Pirozhkov, rspec/rspec-expectations#1440) + +### 3.12.3 / 2023-04-20 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.2...v3.12.3) + +Bug Fixes: + +* Fix `include` matcher when fuzzy matching on keys with a hash-like actual which + has a non standard `key?` method which may raise. + (Jon Rowe, rspec/rspec-expectations#1416) + +### 3.12.2 / 2023-01-07 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.1...v3.12.2) + +Bug Fixes: + +* Prevent deprecation warning when using the `exist` matcher with `Dir`. + (Steve Dierker, rspec/rspec-expectations#1398) + +### 3.12.1 / 2022-12-16 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.12.0...v3.12.1) + +Bug Fixes: + +* Pass keyword arguments through to aliased (and thus negated) matchers. (Jon Rowe, rspec/rspec-expectations#1394) +* When handling failures in an aggregated_failures block (or example) prevent + the failure list leaking out. (Maciek Rząsa, rspec/rspec-expectations#1392) + +### 3.12.0 / 2022-10-26 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.11.1...v3.12.0) + +Enhancements: + +* Add `an_array_matching` alias for `match_array` to improve readability as an argument + matcher. (Mark Schneider, rspec/rspec-expectations#1361) + +### 3.11.1 / 2022-09-12 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.11.0...v3.11.1) + +Bug Fixes: + +* Allow the `contain_exactly` matcher to be reused by resetting its + internals on `matches?` (@bclayman-sq, rspec/rspec-expectations#1326) +* Using the exist matcher on `FileTest` no longer produces a deprecation warning. + (Ryo Nakamura, rspec/rspec-expectations#1383) + +### 3.11.0 / 2022-02-09 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.10.2...v3.11.0) + +Enhancements: + +* Return `true` from `aggregate_failures` when no exception occurs. (Jon Rowe, rspec/rspec-expectations#1225) + +Deprecations: + +* Print a deprecation message when using the implicit block expectation syntax. + (Phil Pirozhkov, rspec/rspec-expectations#1139) + +### 3.10.2 / 2022-01-14 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.10.1...v3.10.2) + +Bug Fixes: + +* Fix support for dynamic matchers for expectation target checks (Phil Pirozhkov, rspec/rspec-expectations#1294) +* Fix `expect(array).to include(hash).times`, previously this would fail due to + matching the entire array as a single hash, rather than a member of the hash. + (Slava Kardakov, rspec/rspec-expectations#1322) +* Ensure `raise_error` matches works with the `error_highlight` option from Ruby 3.1. + (Peter Goldstein, rspec/rspec-expectations#1339) + +### 3.10.1 / 2020-12-27 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.10.0...v3.10.1) + +Bug Fixes: + +* Allow JRuby 9.2.x.x to generate backtraces normally rather than via our + backfill workaround. (rspec/rspec-expectations#1230, Jon Rowe) + +### 3.10.0 / 2020-10-30 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.3...v3.10.0) + +Enhancements: + +* Allow `include` matcher to be chained with `once`, `at_least`, etc. for simple cases. + (Marc-André Lafortune, rspec/rspec-expectations#1168) +* Add an explicit warning when `nil` is passed to `raise_error`. (Phil Pirozhkov, rspec/rspec-expectations#1143) +* Improve `include` matcher's composability. (Phil Pirozhkov, rspec/rspec-expectations#1155) +* Mocks expectations can now set a custom failure message. + (Benoit Tigeot and Nicolas Zermati, rspec/rspec-expectations#1156) +* `aggregate_failures` now shows the backtrace line for each failure. (Fabricio Bedin, rspec/rspec-expectations#1163) +* Support multiple combinations of `yield_control` modifiers like `at_least`, `at_most`. + (Jon Rowe, rspec/rspec-expectations#1169) +* Dynamic `have_` matchers now have output consistent with other dynamic matchers. + (Marc-André Lafortune, rspec/rspec-expectations#1195) +* New config option `strict_predicate_matchers` allows predicate matcher to be strict + (i.e. match for `true` or `false`) instead of the default (match truthy vs `false` or `nil`). + (Marc-André Lafortune, rspec/rspec-expectations#1196) + +### 3.9.4 / 2020-10-29 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.3...v3.9.4) + +Bug Fixes: + +* Fix regression with `be_` and `have_` matchers and arguments implementing `to_hash` + were they would act like keywords and be cast to a hash. (Jon Rowe, rspec/rspec-expectations#1222) + +### 3.9.3 / 2020-10-23 + +Bug Fixes: + +* Swap the comparison of the delta vs the expected for the `be_within` matcher allowing + more complicated oobjects to be compared providing they provide `abs` and other + comparison methods. (Kelly Stannard, rspec/rspec-expectations#1182) +* Properly format expected in the description of the `be_within` matcher. (Jon Rowe, rspec/rspec-expectations#1185) +* Remove warning when using keyword arguments with `be_` and `have_` matchers on 2.7.x + (Jon Rowe, rspec/rspec-expectations#1187) +* Prevent formatting a single hash as a list of key value pairs in default failure messages + for custom matches (fixes formatting in `EnglishPhrasing#list`). (Robert Eshleman, rspec/rspec-expectations#1193) +* Prevent errors from causing false positives when using `be ` comparison, e.g. + `expect(1).not_to be < 'a'` will now correctly fail rather than pass. (Jon Rowe, rspec/rspec-expectations#1208) + + +### 3.9.2 / 2020-05-08 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.1...v3.9.2) + +Bug Fixes: + +* Issue a proper `ArgumentError` when invalid arguments are given to `yield_control` + modifiers such as `at_least` et al. (Marc-André Lafortune, rspec/rspec-expectations#1167) +* Prevent Ruby 2.7 keyword arguments warning from being issued by custom + matcher definitions. (Jon Rowe, rspec/rspec-expectations#1176) + +### 3.9.1 / 2020-03-13 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.9.0...v3.9.1) + +Bug Fixes: + +* Issue an improved warning when using `respond_to(...).with(n).arguments` and ignore + the warning when using with `have_attributes(...)`. (Jon Rowe, rspec/rspec-expectations#1164) + +### 3.9.0 / 2019-10-08 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.6...v3.9.0) + +Enhancements: + +* The `respond_to` matcher now uses the signature from `initialize` to validate checks + for `new` (unless `new` is non standard). (Jon Rowe, rspec/rspec-expectations#1072) +* Generated descriptions for matchers now use `is expected to` rather than `should` in + line with our preferred DSL. (Pete Johns, rspec/rspec-expectations#1080, rspec/rspec-corerspec/rspec-expectations#2572) +* Add the ability to re-raise expectation errors when matching + with `match_when_negated` blocks. (Jon Rowe, rspec/rspec-expectations#1130) +* Add a warning when an empty diff is produce due to identical inspect output. + (Benoit Tigeot, rspec/rspec-expectations#1126) + +### 3.8.6 / 2019-10-07 + +Bug Fixes: + +* Revert rspec/rspec-expectations#1125 due to the change being incompatible with our semantic versioning + policy. + +### 3.8.5 / 2019-10-02 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.4...v3.8.5) + +Bug Fixes: + +* Prevent unsupported implicit block expectation syntax from being used. + (Phil Pirozhkov, rspec/rspec-expectations#1125) + +### 3.8.4 / 2019-06-10 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.3...v3.8.4) + +Bug Fixes: + +* Prevent false negatives when checking objects for the methods required to run the + the `be_an_instance_of` and `be_kind_of` matchers. (Nazar Matus, rspec/rspec-expectations#1112) + +### 3.8.3 / 2019-04-20 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.2...v3.8.3) + +Bug Fixes: + +* Prevent composed `all` matchers from leaking into their siblings leading to duplicate + failures. (Jamie English, rspec/rspec-expectations#1086) +* Prevent objects which change their hash on comparison from failing change checks. + (Phil Pirozhkov, rspec/rspec-expectations#1100) +* Issue an `ArgumentError` rather than a `NoMethodError` when `be_an_instance_of` and + `be_kind_of` matchers encounter objects not supporting those methods. + (Taichi Ishitani, rspec/rspec-expectations#1107) + +### 3.8.2 / 2018-10-09 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.1...v3.8.2) + +Bug Fixes: + +* Change `include` matcher to rely on a `respond_to?(:include?)` check rather than a direct + Hash comparison before calling `to_hash` to convert to a hash. (Jordan Owens, rspec/rspec-expectations#1073) +* Prevent unexpected call stack jumps from causing an obscure error (`IndexError`), and + replace that error with a proper informative message. (Jon Rowe, rspec/rspec-expectations#1076) + +### 3.8.1 / 2018-08-06 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.8.0...v3.8.1) + +Bug Fixes: + +* Fix regression in `include` matcher so stopped + `expect(hash.with_indifferent_access).to include(:symbol_key)` + from working. (Eito Katagiri, rspec/rspec-expectations#1069) + +### 3.8.0 / 2018-08-04 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.7.0...v3.8.0) + +Enhancements: + +* Improve failure message of `change(receiver, :message)` by including the + receiver as `SomeClass#some_message`. (Tomohiro Hashidate, rspec/rspec-expectations#1005) +* Improve `change` matcher so that it can correctly detect changes in + deeply nested mutable objects (such as arrays-of-hashes-of-arrays). + The improved logic uses the before/after `hash` value to see if the + object has been mutated, rather than shallow duping the object. + (Myron Marston, rspec/rspec-expectations#1034) +* Improve `include` matcher so that pseudo-hash objects (e.g. objects + that decorate a hash using a `SimpleDelegator` or similar) are treated + as a hash, as long as they implement `to_hash`. (Pablo Brasero, rspec/rspec-expectations#1012) +* Add `max_formatted_output_length=` to configuration, allowing changing + the length at which we truncate large output strings. + (Sam Phippen rspec/rspec-expectations#951, Benoit Tigeot rspec/rspec-expectations#1056) +* Improve error message when passing a matcher that doesn't support block + expectations to a block based `expect`. (@nicktime, rspec/rspec-expectations#1066) + +### 3.7.0 / 2017-10-17 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.6.0...v3.7.0) + +Enhancements: + +* Improve compatibility with `--enable-frozen-string-literal` option + on Ruby 2.3+. (Pat Allan, rspec/rspec-expectations#997) + +### 3.6.0 / 2017-05-04 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.6.0.beta2...v3.6.0) + +Enhancements: + +* Treat NoMethodError as a failure for comparison matchers. (Jon Rowe, rspec/rspec-expectations#972) +* Allow for scoped aliased and negated matchers--just call + `alias_matcher` or `define_negated_matcher` from within an example + group. (Markus Reiter, rspec/rspec-expectations#974) +* Improve failure message of `change` matcher with block and `satisfy` matcher + by including the block snippet instead of just describing it as `result` or + `block` when Ripper is available. (Yuji Nakayama, rspec/rspec-expectations#987) + +Bug Fixes: + +* Fix `yield_with_args` and `yield_successive_args` matchers so that + they compare expected to actual args at the time the args are yielded + instead of at the end, in case the method that is yielding mutates the + arguments after yielding. (Alyssa Ross, rspec/rspec-expectations#965) + +### 3.6.0.beta2 / 2016-12-12 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.6.0.beta1...v3.6.0.beta2) + +Bug Fixes: + +* Using the exist matcher on `File` no longer produces a deprecation warning. + (Jon Rowe, rspec/rspec-expectations#954) + +### 3.6.0.beta1 / 2016-10-09 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.5.0...v3.6.0.beta1) + +Bug Fixes: + +* Fix `contain_exactly` to work correctly with ranges. (Myron Marston, rspec/rspec-expectations#940) +* Fix `change` to work correctly with sets. (Marcin Gajewski, rspec/rspec-expectations#939) + +### 3.5.0 / 2016-07-01 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.5.0.beta4...v3.5.0) + +Enhancements: + +* Add support for keyword arguments to the `respond_to` matcher. (Rob Smith, rspec/rspec-expectations#915). + +### 3.5.0.beta4 / 2016-06-05 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.5.0.beta3...v3.5.0.beta4) + +Bug Fixes: + +* Fix `include` matcher so that it provides a valid diff for hashes. (Yuji Nakayama, rspec/rspec-expectations#916) + +### 3.5.0.beta3 / 2016-04-02 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.5.0.beta2...v3.5.0.beta3) + +Enhancements: + +* Make `rspec/expectations/minitest_integration` work on Minitest::Spec + 5.6+. (Myron Marston, rspec/rspec-expectations#904) +* Add an alias `having_attributes` for `have_attributes` matcher. + (Yuji Nakayama, rspec/rspec-expectations#905) +* Improve `change` matcher error message when block is mis-used. + (Alex Altair, rspec/rspec-expectations#908) + +### 3.5.0.beta2 / 2016-03-10 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.5.0.beta1...v3.5.0.beta2) + +Enhancements: + +* Add the ability to raise an error on encountering false positives via + `RSpec::Configuration#on_potential_false_positives = :raise`. (Jon Rowe, rspec/rspec-expectations#900) +* When using the custom matcher DSL, support new + `notify_expectation_failures: true` option for the `match` method to + allow expectation failures to be raised as normal instead of being + converted into a `false` return value for `matches?`. (Jon Rowe, rspec/rspec-expectations#892) + +Bug Fixes: + +* Allow `should` deprecation check to work on `BasicObject`s. (James Coleman, rspec/rspec-expectations#898) + +### 3.5.0.beta1 / 2016-02-06 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.4.0...v3.5.0.beta1) + +Enhancements: + +* Make `match_when_negated` in custom matcher DSL support use of + expectations within the match logic. (Chris Arcand, rspec/rspec-expectations#789) + +Bug Fixes: + +* Return `true` as expected from passing negated expectations + (such as `expect("foo").not_to eq "bar"`), so they work + properly when used within a `match` or `match_when_negated` + block. (Chris Arcand, rspec/rspec-expectations#789) + +### 3.4.0 / 2015-11-11 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.3.1...v3.4.0) + +Enhancements: + +* Warn when `RSpec::Matchers` is included in a superclass after it has + already been included in a subclass on MRI 1.9, since that situation + can cause uses of `super` to trigger infinite recursion. (Myron Marston, rspec/rspec-expectations#816) +* Stop rescuing `NoMemoryError`, `SignalExcepetion`, `Interrupt` and + `SystemExit`. It is dangerous to interfere with these. (Myron Marston, rspec/rspec-expectations#845) +* Add `#with_captures` to the match matcher which allows a user to specify expected + captures when matching a regex against a string. (Sam Phippen, rspec/rspec-expectations#848) +* Always print compound failure messages in the multi-line form. Trying + to print it all on a single line didn't read very well. (Myron Marston, rspec/rspec-expectations#859) + +Bug Fixes: + +* Fix failure message from dynamic predicate matchers when the object + does not respond to the predicate so that it is inspected rather + than relying upon its `to_s` -- that way for `nil`, `"nil"` is + printed rather than an empty string. (Myron Marston, rspec/rspec-expectations#841) +* Fix SystemStackError raised when diffing an Enumerable object + whose `#each` includes the object itself. (Yuji Nakayama, rspec/rspec-expectations#857) + +### 3.3.1 / 2015-07-15 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.3.0...v3.3.1) + +Bug Fixes: + +* Fix `be >`, `be <`, etc so that it fails rather than allowing an + argument error to be raised when compared against an object of the + wrong type. This allows it to be used in composed matcher expressions + against heterogeneous objects. (Dennis Günnewig, rspec/rspec-expectations#809) +* Fix `respond_to` to work properly on target objects + that redefine the `method` method. (unmanbearpig, rspec/rspec-expectations#821) + +### 3.3.0 / 2015-06-12 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.2.1...v3.3.0) + +Enhancements: + +* Expose `RSpec::Matchers::EnglishPhrasing` to make it easier to write + nice failure messages in custom matchers. (Jared Beck, rspec/rspec-expectations#736) +* Add `RSpec::Matchers::FailMatchers`, a mixin which provides + `fail`, `fail_with` and `fail_including` matchers for use in + specifying that an expectation fails for use by + extension/plugin authors. (Charlie Rudolph, rspec/rspec-expectations#729) +* Avoid loading `tempfile` (and its dependencies) unless + it is absolutely needed. (Myron Marston, rspec/rspec-expectations#735) +* Improve failure output when attempting to use `be_true` or `be_false`. + (Tim Wade, rspec/rspec-expectations#744) +* Define `RSpec::Matchers#respond_to_missing?` so that + `RSpec::Matchers#respond_to?` and `RSpec::Matchers#method` handle + dynamic predicate matchers. (Andrei Botalov, rspec/rspec-expectations#751) +* Use custom Time/DateTime/BigDecimal formatting for all matchers + so they are consistently represented in failure messages. + (Gavin Miller, rspec/rspec-expectations#740) +* Add configuration to turn off warnings about matcher combinations that + may cause false positives. (Jon Rowe, rspec/rspec-expectations#768) +* Warn when using a bare `raise_error` matcher that you may be subject to + false positives. (Jon Rowe, rspec/rspec-expectations#768) +* Warn rather than raise when using the`raise_error` matcher in negative + expectations that may be subject to false positives. (Jon Rowe, rspec/rspec-expectations#775) +* Improve failure message for `include(a, b, c)` so that if `a` and `b` + are included the failure message only mentions `c`. (Chris Arcand, rspec/rspec-expectations#780) +* Allow `satisfy` matcher to take an optional description argument + that will be used in the `description`, `failure_message` and + `failure_message_when_negated` in place of the undescriptive + "sastify block". (Chris Arcand, rspec/rspec-expectations#783) +* Add new `aggregate_failures` API that allows multiple independent + expectations to all fail and be listed in the failure output, rather + than the example aborting on the first failure. (Myron Marston, rspec/rspec-expectations#776) +* Improve `raise_error` matcher so that it can accept a matcher as a single argument + that matches the message. (Time Wade, rspec/rspec-expectations#782) + +Bug Fixes: + +* Make `contain_exactly` / `match_array` work with strict test doubles + that have not defined `<=>`. (Myron Marston, rspec/rspec-expectations#758) +* Fix `include` matcher so that it omits the diff when it would + confusingly highlight items that are actually included but are not + an exact match in a line-by-line diff. (Tim Wade, rspec/rspec-expectations#763) +* Fix `match` matcher so that it does not blow up when matching a string + or regex against another matcher (rather than a string or regex). + (Myron Marston, rspec/rspec-expectations#772) +* Silence whitespace-only diffs. (Myron Marston, rspec/rspec-expectations#801) + +### 3.2.1 / 2015-04-06 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.2.0...v3.2.1) + +Bug Fixes: + +* Prevent `Range`s from being enumerated when generating matcher + descriptions. (Jon Rowe, rspec/rspec-expectations#755) +* Ensure exception messages are compared as strings in the `raise_error` + matcher. (Jon Rowe, rspec/rspec-expectations#755) + +### 3.2.0 / 2015-02-03 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.1.2...v3.2.0) + +Enhancements: + +* Add `block_arg` method to custom matcher API, which allows you to + access the block passed to a custom matcher, if there is one. + (Mike Dalton, rspec/rspec-expectations#645) +* Provide more detail in failure message of `yield_control` matcher. + (Jon Rowe, rspec/rspec-expectations#650) +* Add a shorthand syntax for `chain` in the matcher DSL which assigns values + for use elsewhere, for example `chain :and_smaller_than, :small_value` + creates an `attr_reader` for `small_value` (Tom Stuart, rspec/rspec-expectations#644) +* Provide a more helpful deprecation message when using the `should` syntax. + (Elia Schito, rspec/rspec-expectations#663) +* Provide more detail in the `have_attributes` matcher failure message. + (Jon Rowe, rspec/rspec-expectations#668) +* Make the `have_attributes` matcher diffable. + (Jon Rowe, Alexey Fedorov, rspec/rspec-expectations#668) +* Add `output(...).to_std(out|err)_from_any_process` as alternatives + to `output(...).to_std(out|err)`. The latter doesn't work when a sub + process writes to the named stream but is much faster. + (Alex Genco, rspec/rspec-expectations#700) +* Improve compound matchers (created by `and` and `or`) so that diffs + are included in failures when one or more of their matchers + are diffable. (Alexey Fedorov, rspec/rspec-expectations#713) + +Bug Fixes: + +* Avoid calling `private_methods` from the `be` predicate matcher on + the target object if the object publicly responds to the predicate + method. This avoids a possible error that can occur if the object + raises errors from `private_methods` (which can happen with celluloid + objects). (@chapmajs, rspec/rspec-expectations#670) +* Make `yield_control` (with no modifier) default to + `at_least(:once)` rather than raising a confusing error + when multiple yields are encountered. + (Myron Marston, rspec/rspec-expectations#675) +* Fix "instance variable @color not initialized" warning when using + rspec-expectations outside of an rspec-core context. (Myron Marston, rspec/rspec-expectations#689) +* Fix `start_with` and `end_with` to work properly when checking a + string against an array of strings. (Myron Marston, rspec/rspec-expectations#690) +* Don't use internally delegated matchers when generating descriptions + for examples without doc strings. (Myron Marston, rspec/rspec-expectations#692) + +### 3.1.2 / 2014-09-26 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.1.1...v3.1.2) + +Bug Fixes: + +* Fix `define_negated_matcher` so that matchers that support fluent + interfaces continue to be negated after you use the chained method. + (Myron Marston, rspec/rspec-expectations#656) +* Fix `define_negated_matcher` so that the matchers fail with an + appropriate failure message. (Myron Marston, rspec/rspec-expectations#659) + +### 3.1.1 / 2014-09-15 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.1.0...v3.1.1) + +Bug Fixes: + +* Fix regression in `all` matcher in 3.1.0 that prevented it from + working on objects that are not `Enumerable` but do implement + `each_with_index` (such as an ActiveRecord proxy). (Jori Hardman, rspec/rspec-expectations#647) + +### 3.1.0 / 2014-09-04 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.4...v3.1.0) + +Enhancements: + +* Add `have_attributes` matcher, that passes if actual's attribute + values match the expected attributes hash: + `Person = Struct.new(:name, :age)` + `person = Person.new("Bob", 32)` + `expect(person).to have_attributes(:name => "Bob", :age => 32)`. + (Adam Farhi, rspec/rspec-expectations#571) +* Extended compound matcher support to block matchers, for cases like: + `expect { ... }.to change { x }.to(3).and change { y }.to(4)`. (Myron + Marston, rspec/rspec-expectations#567) +* Include chained methods in custom matcher description and failure message + when new `include_chain_clauses_in_custom_matcher_descriptions` config + option is enabled. (Dan Oved, rspec/rspec-expectations#600) +* Add `thrice` modifier to `yield_control` matcher as a synonym for + `exactly(3).times`. (Dennis Taylor, rspec/rspec-expectations#615) +* Add `RSpec::Matchers.define_negated_matcher`, which defines a negated + version of the named matcher. (Adam Farhi, Myron Marston, rspec/rspec-expectations#618) +* Document and support negation of `contain_exactly`/`match_array`. + (Jon Rowe, rspec/rspec-expectations#626). + +Bug Fixes: + +* Rename private `LegacyMacherAdapter` constant to `LegacyMatcherAdapter` + to fix typo. (Abdelkader Boudih, rspec/rspec-expectations#563) +* Fix `all` matcher so that it fails properly (rather than raising a + `NoMethodError`) when matched against a non-enumerable. (Hao Su, rspec/rspec-expectations#622) + +### 3.0.4 / 2014-08-14 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.3...v3.0.4) + +Bug Fixes: + +* Fix `start_with` and `end_with` so that they work properly with + structs. (Myron Marston, rspec/rspec-expectations#620) +* Fix failure message generation so that structs are printed properly + in failures. Previously failure messages would represent them as + an array. (Myron Marston, rspec/rspec-expectations#620) +* Fix composable matcher support so that it does not wrongly treat + structs as arrays. (Myron Marston, rspec/rspec-expectations#620) + +### 3.0.3 / 2014-07-21 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.2...v3.0.3) + +Bug Fixes: + +* Fix issue with detection of generic operator matchers so they work + correctly when undefined. (Myron Marston, rspec/rspec-expectations#597) +* Don't inadvertently define `BasicObject` in 1.8.7. (Chris Griego, rspec/rspec-expectations#603) +* Fix `include` matcher so that it fails gracefully when matched against + an object that does not respond to `include?`. (Myron Marston, rspec/rspec-expectations#607) + +### 3.0.2 / 2014-06-19 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.1...v3.0.2) + +Bug Fixes: + +* Fix regression in `contain_exactly` (AKA `match_array`) that caused it + to wrongly pass when the expected array was empty. (Myron Marston, rspec/rspec-expectations#581) +* Provide a better error message when you use the `change(obj, :msg)` + form of the change matcher but forget the message argument. (Alex + Sunderland, rspec/rspec-expectations#585) +* Make the `contain_exactly` matcher work with arrays that contain hashes in + arbitrary ordering. (Sam Phippen, rspec/rspec-expectations#578) + +### 3.0.1 / 2014-06-12 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.0...v3.0.1) + +Bug Fixes: + +* Add a missing `require` that would cause the `respond_to` matcher to + fail when used in a project where the rest of RSpec (e.g. core and + expecatations) weren't being used. (Myron Marston, rspec/rspec-expectations#566) +* Structs are no longer treated as arrays when diffed. (Jon Rowe, rspec/rspec-expectations#576) + +### 3.0.0 / 2014-06-01 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.0.rc1...v3.0.0) + +No code changes. Just taking it out of pre-release. + +### 3.0.0.rc1 / 2014-05-18 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.0.beta2...v3.0.0.rc1) + +Breaking Changes for 3.0.0: + +* Remove `matcher_execution_context` attribute from DSL-defined + custom matchers. (Myron Marston) +* Remove `RSpec::Matchers::Pretty#_pretty_print`. (Myron Marston) +* Remove `RSpec::Matchers::Pretty#expected_to_sentence`. (Myron Marston) +* Rename `RSpec::Matchers::Configuration` constant to + `RSpec::Expectations::Configuration`. (Myron Marston) +* Prevent `have_xyz` predicate matchers using private methods. + (Adrian Gonzalez) +* Block matchers must now implement `supports_block_expectations?`. + (Myron Marston) +* Stop supporting `require 'rspec-expectations'`. + Use `require 'rspec/expectations'` instead. (Myron Marston) + +Bug Fixes: + +* Fix `NoMethodError` triggered by beta2 when `YARD` was loaded in + the test environment. (Myron Marston) +* Fix `be_xyz` matcher to accept a `do...end` block. (Myron Marston) +* Fix composable matcher failure message generation logic + so that it does not blow up when given `$stdout` or `$stderr`. + (Myron Marston) +* Fix `change` matcher to work properly with `IO` objects. + (Myron Marston) +* Fix `exist` matcher so that it can be used in composed matcher + expressions involving objects that do not implement `exist?` or + `exists?`. (Daniel Fone) +* Fix composable matcher match logic so that it clones matchers + before using them in order to work properly with matchers + that use internal memoization based on a given `actual` value. + (Myron Marston) +* Fix `be_xyz` and `has_xyz` predicate matchers so that they can + be used in composed matcher expressions involving objects that + do not implement the predicate method. (Daniel Fone) + +Enhancements: + +* Document the remaining public APIs. rspec-expectations now has 100% of + the public API documented and will remain that way (as new undocumented + methods will fail the build). (Myron Marston) +* Improve the formatting of BigDecimal objects in `eq` matcher failure + messages. (Daniel Fone) +* Improve the failure message for `be_xyz` predicate matchers so + that it includes the `inspect` output of the receiver. + (Erik Michaels-Ober, Sam Phippen) +* Add `all` matcher, to allow you to specify that a given matcher + matches all elements in a collection: + `expect([1, 3, 5]).to all( be_odd )`. (Adam Farhi) +* Add boolean aliases (`&`/`|`) for compound operators (`and`/`or`). (Adam Farhi) +* Give users a clear error when they wrongly use a value matcher + in a block expectation expression (e.g. `expect { 3 }.to eq(3)`) + or vice versa. (Myron Marston) + +### 3.0.0.beta2 / 2014-02-17 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v3.0.0.beta1...v3.0.0.beta2) + +Breaking Changes for 3.0.0: + +* Remove deprecated support for accessing the `RSpec` constant using + `Rspec` or `Spec`. (Myron Marston) +* Remove deprecated `RSpec::Expectations.differ=`. (Myron Marston) +* Remove support for deprecated `expect(...).should`. (Myron Marston) +* Explicitly disallow `expect { }.not_to change { }` with `by`, + `by_at_least`, `by_at_most` or `to`. These have never been supported + but did not raise explicit errors. (Myron Marston) +* Provide `===` rather than `==` as an alias of `matches?` for + all matchers. The semantics of `===` are closer to an RSpec + matcher than `==`. (Myron Marston) +* Remove deprecated `RSpec::Matchers::OperatorMatcher` constant. + (Myron Marston) +* Make `RSpec::Expectations::ExpectationNotMetError` subclass + `Exception` rather than `StandardError` so they can bypass + a bare `rescue` in end-user code (e.g. when an expectation is + set from within a rspec-mocks stub implementation). (Myron Marston) +* Remove Test::Unit and Minitest 4.x integration. (Myron Marston) + +Enhancements: + +* Simplify the failure message of the `be` matcher when matching against: + `true`, `false` and `nil`. (Sam Phippen) +* Update matcher protocol and custom matcher DSL to better align + with the newer `expect` syntax. If you want your matchers to + maintain compatibility with multiple versions of RSpec, you can + alias the new names to the old. (Myron Marston) + * `failure_message_for_should` => `failure_message` + * `failure_message_for_should_not` => `failure_message_when_negated` + * `match_for_should` => `match` + * `match_for_should_not` => `match_when_negated` +* Improve generated descriptions from `change` matcher. (Myron Marston) +* Add support for compound matcher expressions using `and` and `or`. + Simply chain them off of any existing matcher to create an expression + like `expect(alphabet).to start_with("a").and end_with("z")`. + (Eloy Espinaco) +* Add `contain_exactly` as a less ambiguous version of `match_array`. + Note that it expects the expected array to be splatted as + individual args: `expect(array).to contain_exactly(1, 2)` is + the same as `expect(array).to match_array([1, 2])`. (Myron Marston) +* Update `contain_exactly`/`match_array` so that it can match against + other non-array collections (such as a `Set`). (Myron Marston) +* Update built-in matchers so that they can accept matchers as arguments + to allow you to compose matchers in arbitrary ways. (Myron Marston) +* Add `RSpec::Matchers::Composable` mixin that can be used to make + a custom matcher composable as well. Note that custom matchers + defined via `RSpec::Matchers.define` already have this. (Myron + Marston) +* Define noun-phrase aliases for built-in matchers, which can be + used when creating composed matcher expressions that read better + and provide better failure messages. (Myron Marston) +* Add `RSpec::Matchers.alias_matcher` so users can define their own + matcher aliases. The `description` of the matcher will reflect the + alternate matcher name. (Myron Marston) +* Add explicit `be_between` matcher. `be_between` has worked for a + long time as a dynamic predicate matcher, but the failure message + was suboptimal. The new matcher provides a much better failure + message. (Erik Michaels-Ober) +* Enhance the `be_between` matcher to allow for `inclusive` or `exclusive` + comparison (e.g. inclusive of min/max or exclusive of min/max). + (Pedro Gimenez) +* Make failure message for `not_to be #{operator}` less confusing by + only saying it's confusing when comparison operators are used. + (Prathamesh Sonpatki) +* Improve failure message of `eq` matcher when `Time` or `DateTime` + objects are used so that the full sub-second precision is included. + (Thomas Holmes, Jeff Wallace) +* Add `output` matcher for expecting that a block outputs `to_stdout` + or `to_stderr`. (Luca Pette, Matthias Günther) +* Forward a provided block on to the `has_xyz?` method call when + the `have_xyz` matcher is used. (Damian Galarza) +* Provide integration with Minitest 5.x. Require + `rspec/expectations/minitest_integration` after loading minitest + to use rspec-expectations with minitest. (Myron Marston) + +Bug Fixes: + +* Fix wrong matcher descriptions with falsey expected value (yujinakayama) +* Fix `expect { }.not_to change { }.from(x)` so that the matcher only + passes if the starting value is `x`. (Tyler Rick, Myron Marston) +* Fix hash diffing, so that it colorizes properly and doesn't consider trailing + commas when performing the diff. (Jared Norman) +* Fix built-in matchers to fail normally rather than raising + `ArgumentError` when given an object of the wrong type to match + against, so that they work well in composite matcher expressions like + `expect([1.51, "foo"]).to include(a_string_matching(/foo/), a_value_within(0.1).of(1.5))`. + (Myron Marston) + +Deprecations: + +* Retain support for RSpec 2 matcher protocol (e.g. for matchers + in 3rd party extension gems like `shoulda`), but it will print + a deprecation warning. (Myron Marston) + +### 3.0.0.beta1 / 2013-11-07 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.99.2...v3.0.0.beta1) + +Breaking Changes for 3.0.0: + +* Remove explicit support for 1.8.6. (Jon Rowe) +* Remove the deprecated `be_close` matcher, preferring `be_within` instead. + (Sam Phippen) +* Remove the deprecated `have`, `have_at_least` and `have_at_most` matchers. + You can continue using those matchers through https://github.com/rspec/rspec-collection_matchers, + or you can rewrite your expectations with something like + `expect(your_object.size).to eq(num)`. (Hugo Baraúna) +* Rename `be_true` and `be_false` to `be_truthy` and `be_falsey`. (Sam Phippen) +* Make `expect { }.to_not raise_error(SomeSpecificClass, message)`, + `expect { }.to_not raise_error(SomeSpecificClass)` and + `expect { }.to_not raise_error(message)` invalid, since they are prone + to hiding failures. Instead, use `expect { }.to_not raise_error` (with no + args). (Sam Phippen) +* Within `RSpec::Matchers.define` blocks, helper methods made available + either via `def self.helper` or `extend HelperModule` are no longer + available to the `match` block (or any of the others). Instead + `include` your helper module and define the helper method as an + instance method. (Myron Marston) +* Force upgrading Diff::LCS for encoding compatability with diffs. (Jon Rowe) + +Enhancements: + +* Support `do..end` style block with `raise_error` matcher. (Yuji Nakayama) +* Rewrote custom matcher DSL to simplify its implementation and solve a + few issues. (Myron Marston) +* Allow early `return` from within custom matcher DSL blocks. (Myron + Marston) +* The custom matcher DSL's `chain` can now accept a block. (Myron + Marston) +* Support setting an expectation on a `raise_error` matcher via a chained + `with_message` method call. (Sam Phippen) + +Bug Fixes: + +* Allow `include` and `match` matchers to be used from within a + DSL-defined custom matcher's `match` block. (Myron Marston) +* Correct encoding error message on diff failure (Jon Rowe) + +Deprecations: + + * Using the old `:should` syntax without explicitly configuring it is deprecated. + It will continue to work but will emit a deprecation warning in RSpec 3 if + you do not explicitly enable it. (Sam Phippen) + +### 2.99.2 / 2014-07-21 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.99.1...v2.99.2) + +Bug Fixes: + +* Fix regression in `Expectations#method_handle_for` where proxy objects + with method delegated would wrongly not return a method handle. + (Jon Rowe, rspec/rspec-expectations#594) +* Fix issue with detection of generic operator matchers so they work + correctly when undefined. (Myron Marston, rspec/rspec-expectations#597) + +### 2.99.1 / 2014-06-19 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.99.0...v2.99.1) + +Bug Fixes: + +* Fix typo in custom matcher `expected` deprecation warning -- it's + `expected_as_array`, not `expected_array`. (Frederick Cheung, rspec/rspec-expectations#562) + +### 2.99.0 / 2014-06-01 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.99.0.rc1...v2.99.0) + +Enhancements: + +* Special case deprecation message for `errors_on` with `rspec-rails` to be more useful. + (Aaron Kromer) + +### 2.99.0.rc1 / 2014-05-18 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.99.0.beta2...2.99.0.rc1) + +Deprecations: + +* Deprecate `matcher_execution_context` attribute on DSL-defined + custom matchers. (Myron Marston) +* Deprecate `RSpec::Matchers::Pretty#_pretty_print`. (Myron Marston) +* Deprecate `RSpec::Matchers::Pretty#expected_to_sentence`. (Myron Marston) +* Deprecate `RSpec::Matchers::Configuration` in favor of + `RSpec::Expectations::Configuration`. (Myron Marston) +* Deprecate `be_xyz` predicate matcher on an object that doesn't respond to + `xyz?` or `xyzs?`. (Daniel Fone) +* Deprecate `have_xyz` matcher on an object that doesn't respond to `has_xyz?`. + (Daniel Fone) +* Deprecate `have_xyz` matcher on an object that has a private method `has_xyz?`. + (Jon Rowe) +* Issue a deprecation warning when a block expectation expression is + used with a matcher that doesn't explicitly support block expectations + via `supports_block_expectations?`. (Myron Marston) +* Deprecate `require 'rspec-expectations'`. Use + `require 'rspec/expectations'` instead. (Myron Marston) + +### 2.99.0.beta2 / 2014-02-17 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.99.0.beta1...v2.99.0.beta2) + +Deprecations: + +* Deprecate chaining `by`, `by_at_least`, `by_at_most` or `to` off of + `expect { }.not_to change { }`. The docs have always said these are + not supported for the negative form but now they explicitly raise + errors in RSpec 3. (Myron Marston) +* Change the semantics of `expect { }.not_to change { x }.from(y)`. + In RSpec 2.x, this expectation would only fail if `x` started with + the value of `y` and changed. If it started with a different value + and changed, it would pass. In RSpec 3, it will pass only if the + value starts at `y` and it does not change. (Myron Marston) +* Deprecate `matcher == value` as an alias for `matcher.matches?(value)`, + in favor of `matcher === value`. (Myron Marston) +* Deprecate `RSpec::Matchers::OperatorMatcher` in favor of + `RSpec::Matchers::BuiltIn::OperatorMatcher`. (Myron Marston) +* Deprecate auto-integration with Test::Unit and minitest. + Instead, include `RSpec::Matchers` in the appropriate test case + base class yourself. (Myron Marston) +* Deprecate treating `#expected` on a DSL-generated custom matcher + as an array when only 1 argument is passed to the matcher method. + In RSpec 3 it will be the single value in order to make diffs + work properly. (Jon Rowe) + +### 2.99.0.beta1 / 2013-11-07 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.4...v2.99.0.beta1) + +Deprecations + +* Deprecate `have`, `have_at_least` and `have_at_most`. You can continue using those + matchers through https://github.com/rspec/rspec-collection_matchers, or + you can rewrite your expectations with something like + `expect(your_object.size).to eq(num)`. (Hugo Baraúna) +* Deprecate `be_xyz` predicate matcher when `xyz?` is a private method. + (Jon Rowe) +* Deprecate `be_true`/`be_false` in favour of `be_truthy`/`be_falsey` + (for Ruby's conditional semantics) or `be true`/`be false` + (for exact equality). (Sam Phippen) +* Deprecate calling helper methods from a custom matcher with the wrong + scope. (Myron Marston) + * `def self.foo` / `extend Helper` can be used to add macro methods + (e.g. methods that call the custom matcher DSL methods), but should + not be used to define helper methods called from within the DSL + blocks. + * `def foo` / `include Helper` is the opposite: it's for helper methods + callable from within a DSL block, but not for defining macros. + * RSpec 2.x allowed helper methods defined either way to be used for + either purpose, but RSpec 3.0 will not. + +### 2.14.5 / 2014-02-01 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.4...v2.14.5) + +Bug fixes + +* Fix wrong matcher descriptions with falsey expected value + (yujinakayama) + +### 2.14.4 / 2013-11-06 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.3...v2.14.4) + +Bug fixes + +* Make the `match` matcher produce a diff output. (Jon Rowe, Ben Moss) +* Choose encoding for diff's more intelligently, and when all else fails fall + back to default internal encoding with replacing characters. (Jon Rowe) + +### 2.14.3 / 2013-09-22 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.2...v2.14.3) + +Bug fixes + +* Fix operator matchers (`should` syntax) when `method` is redefined on target. + (Brandon Turner) +* Fix diffing of hashes with object based keys. (Jon Rowe) +* Fix operator matchers (`should` syntax) when operator is defined via + `method_missing` (Jon Rowe) + +### 2.14.2 / 2013-08-14 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.1...v2.14.2) + +Bug fixes + +* Fix `be_` matcher to not support operator chaining like the + `be` matcher does (e.g. `be == 5`). This led to some odd behaviors + since `be_ == anything` returned a `BeComparedTo` matcher + and was thus always truthy. This was a consequence of the implementation + (e.g. subclassing the basic `Be` matcher) and was not intended behavior. + (Myron Marston). +* Fix `change` matcher to compare using `==` in addition to `===`. This + is important for an expression like: + `expect {}.to change { a.class }.from(ClassA).to(ClassB)` because + `SomeClass === SomeClass` returns false. (Myron Marston) + +### 2.14.1 / 2013-08-08 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.0...2.14.1) + +Bug fixes + +* Ensure diff output uses the same encoding as the encoding of + the string being diff'd to prevent `Encoding::UndefinedConversionError` + errors (Jon Rowe). + +### 2.14.0 / 2013-07-06 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.14.0.rc1...v2.14.0) + +Bug fixes + +* Values that are not matchers use `#inspect`, rather than `#description` for + documentation output (Andy Lindeman, Sam Phippen). +* Make `expect(a).to be_within(x).percent_of(y)` work with negative y + (Katsuhiko Nishimra). +* Make the `be_predicate` matcher work as expected used with `expect{...}.to + change...` (Sam Phippen). + +### 2.14.0.rc1 / 2013-05-27 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.13.0...v2.14.0.rc1) + +Enhancements + +* Enhance `yield_control` so that you can specify an exact or relative + number of times: `expect { }.to yield_control.exactly(3).times`, + `expect { }.to yield_control.at_least(2).times`, etc (Bartek + Borkowski). +* Make the differ that is used when an expectation fails better handle arrays + by splitting each element of the array onto its own line. (Sam Phippen) +* Accept duck-typed strings that respond to `:to_str` as expectation messages. + (Toby Ovod-Everett) + +Bug fixes + +* Fix differ to not raise errors when dealing with differently-encoded + strings (Jon Rowe). +* Fix `expect(something).to be_within(x).percent_of(y)` where x and y are both + integers (Sam Phippen). +* Fix `have` matcher to handle the fact that on ruby 2.0, + `Enumerator#size` may return nil (Kenta Murata). +* Fix `expect { raise s }.to raise_error(s)` where s is an error instance + on ruby 2.0 (Sam Phippen). +* Fix `expect(object).to raise_error` passing. This now warns the user and + fails the spec (tomykaira). + +Deprecations + +* Deprecate `expect { }.not_to raise_error(SpecificErrorClass)` or + `expect { }.not_to raise_error("some specific message")`. Using + these was prone to hiding failures as they would allow _any other + error_ to pass. (Sam Phippen and David Chelimsky) + +### 2.13.0 / 2013-02-23 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.12.1...v2.13.0) + +Enhancements + +* Add support for percent deltas to `be_within` matcher: + `expect(value).to be_within(10).percent_of(expected)` + (Myron Marston). +* Add support to `include` matcher to allow it to be given a list + of matchers as the expecteds to match against (Luke Redpath). + +Bug fixes + +* Fix `change` matcher so that it dups strings in order to handle + mutated strings (Myron Marston). +* Fix `should be =~ /some regex/` / `expect(...).to be =~ /some regex/`. + Previously, these either failed with a confusing `undefined method + matches?' for false:FalseClass` error or were no-ops that didn't + actually verify anything (Myron Marston). +* Add compatibility for diff-lcs 1.2 and relax the version + constraint (Peter Goldstein). +* Fix DSL-generated matchers to allow multiple instances of the + same matcher in the same example to have different description + and failure messages based on the expected value (Myron Marston). +* Prevent `undefined method #split for Array` error when dumping + the diff of an array of multiline strings (Myron Marston). +* Don't blow up when comparing strings that are in an encoding + that is not ASCII compatible (Myron Marston). +* Remove confusing "Check the implementation of #==" message + printed for empty diffs (Myron Marston). + +### 2.12.1 / 2012-12-15 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.12.0...v2.12.1) + +Bug fixes + +* Improve the failure message for an expression like + `{}.should =~ {}`. (Myron Marston and Andy Lindeman) +* Provide a `match_regex` alias so that custom matchers + built using the matcher DSL can use it (since `match` + is a different method in that context). + (Steven Harman) + +### 2.12.0 / 2012-11-12 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.11.3...v2.12.0) + +Enhancements + +* Colorize diffs if the `--color` option is configured. (Alex Coplan) +* Include backtraces in unexpected errors handled by `raise_error` + matcher (Myron Marston) +* Print a warning when users accidentally pass a non-string argument + as an expectation message (Sam Phippen) +* `=~` and `match_array` matchers output a more useful error message when + the actual value is not an array (or an object that responds to `#to_ary`) + (Sam Phippen) + +Bug fixes + +* Fix `include` matcher so that `expect({}).to include(:a => nil)` + fails as it should (Sam Phippen). +* Fix `be_an_instance_of` matcher so that `Class#to_s` is used in the + description rather than `Class#inspect`, since some classes (like + `ActiveRecord::Base`) define a long, verbose `#inspect`. + (Tom Stuart) + +### 2.11.3 / 2012-09-04 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.11.2...v2.11.3) + +Bug fixes + +* Fix (and deprecate) `expect { }.should` syntax so that it works even + though it was never a documented or intended syntax. It worked as a + consequence of the implementation of `expect` in RSpec 2.10 and + earlier. (Myron Marston) +* Ensure #== is defined on built in matchers so that they can be composed. + For example: + + expect { + user.emailed! + }.to change { user.last_emailed_at }.to be_within(1.second).of(Time.zone.now) + +### 2.11.2 / 2012-07-25 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.11.1...v2.11.2) + +Bug fixes + +* Define `should` and `should_not` on `Object` rather than `BasicObject` + on MacRuby. On MacRuby, `BasicObject` is defined but is not the root + of the object hierarchy. (Gabriel Gilder) + +### 2.11.1 / 2012-07-08 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.11.0...v2.11.1) + +Bug fixes + +* Constrain `actual` in `be_within` matcher to values that respond to `-` instead + of requiring a specific type. + * `Time`, for example, is a legit alternative. + +### 2.11.0 / 2012-07-07 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.10.0...v2.11.0) + +Enhancements + +* Expand `expect` syntax so that it supports expections on bare values + in addition to blocks (Myron Marston). +* Add configuration options to control available expectation syntaxes + (Myron Marston): + * `RSpec.configuration.expect_with(:rspec) { |c| c.syntax = :expect }` + * `RSpec.configuration.expect_with(:rspec) { |c| c.syntax = :should }` + * `RSpec.configuration.expect_with(:rspec) { |c| c.syntax = [:should, :expect] }` + * `RSpec.configuration.add_should_and_should_not_to Delegator` + +Bug fixes + +* Allow only `Numeric` values to be the "actual" in the `be_within` matcher. + This prevents confusing error messages. (Su Zhang @zhangsu) +* Define `should` and `should_not` on `BasicObject` rather than `Kernel` + on 1.9. This makes `should` and `should_not` work properly with + `BasicObject`-subclassed proxy objects like `Delegator`. (Myron + Marston) + +### 2.10.0 / 2012-05-03 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.9.1...v2.10.0) + +Enhancements + +* Add new `start_with` and `end_with` matchers (Jeremy Wadsack) +* Add new matchers for specifying yields (Myron Marston): + * `expect {...}.to yield_control` + * `expect {...}.to yield_with_args(1, 2, 3)` + * `expect {...}.to yield_with_no_args` + * `expect {...}.to yield_successive_args(1, 2, 3)` +* `match_unless_raises` takes multiple exception args + +Bug fixes + +* Fix `be_within` matcher to be inclusive of delta. +* Fix message-specific specs to pass on Rubinius (John Firebaugh) + +### 2.9.1 / 2012-04-03 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.9.0...v2.9.1) + +Bug fixes + +* Provide a helpful message if the diff between two objects is empty. +* Fix bug diffing single strings with multiline strings. +* Fix for error with using custom matchers inside other custom matchers + (mirasrael) +* Fix using execution context methods in nested DSL matchers (mirasrael) + +### 2.9.0 / 2012-03-17 +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.8.0...v2.9.0) + +Enhancements + +* Move built-in matcher classes to RSpec::Matchers::BuiltIn to reduce pollution + of RSpec::Matchers (which is included in every example). +* Autoload files with matcher classes to improve load time. + +Bug fixes + +* Align `respond_to?` and `method_missing` in DSL-defined matchers. +* Clear out user-defined instance variables between invocations of DSL-defined + matchers. +* Dup the instance of a DSL generated matcher so its state is not changed by + subsequent invocations. +* Treat expected args consistently across positive and negative expectations + (thanks to Ralf Kistner for the heads up) + +### 2.8.0 / 2012-01-04 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.8.0.rc2...v2.8.0) + +Enhancements + +* Better diff output for Hash (Philippe Creux) +* Eliminate Ruby warnings (Olek Janiszewski) + +### 2.8.0.rc2 / 2011-12-19 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.8.0.rc1...v2.8.0.rc2) + +No changes for this release. Just releasing with the other rspec gems. + +### 2.8.0.rc1 / 2011-11-06 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.7.0...v2.8.0.rc1) + +Enhancements + +* Use classes for the built-in matchers (they're faster). +* Eliminate Ruby warnings (Matijs van Zuijlen) + +### 2.7.0 / 2011-10-16 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.6.0...v2.7.0) + +Enhancements + +* `HaveMatcher` converts argument using `to_i` (Alex Bepple & Pat Maddox) +* Improved failure message for the `have_xxx` matcher (Myron Marston) +* `HaveMatcher` supports `count` (Matthew Bellantoni) +* Change matcher dups `Enumerable` before the action, supporting custom + `Enumerable` types like `CollectionProxy` in Rails (David Chelimsky) + +Bug fixes + +* Fix typo in `have(n).xyz` documentation (Jean Boussier) +* fix `safe_sort` for ruby 1.9.2 (`Kernel` now defines `<=>` for Object) (Peter + van Hardenberg) + +### 2.6.0 / 2011-05-12 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.5.0...v2.6.0) + +Enhancements + +* `change` matcher accepts regexps (Robert Davis) +* better descriptions for `have_xxx` matchers (Magnus Bergmark) +* `range.should cover(*values)` (Anders Furseth) + +Bug fixes + +* Removed non-ascii characters that were choking rcov (Geoffrey Byers) +* change matcher dups arrays and hashes so their before/after states can be + compared correctly. +* Fix the order of inclusion of RSpec::Matchers in Test::Unit::TestCase and + MiniTest::Unit::TestCase to prevent a SystemStackError (Myron Marston) + +### 2.5.0 / 2011-02-05 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.4.0...v2.5.0) + +Enhancements + +* `should exist` works with `exist?` or `exists?` (Myron Marston) +* `expect { ... }.not_to do_something` (in addition to `to_not`) + +Documentation + +* improved docs for raise_error matcher (James Almond) + +### 2.4.0 / 2011-01-02 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.3.0...v2.4.0) + +No functional changes in this release, which was made to align with the +rspec-core-2.4.0 release. + +Enhancements + +* improved RDoc for change matcher (Jo Liss) + +### 2.3.0 / 2010-12-12 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.2.1...v2.3.0) + +Enhancements + +* diff strings when include matcher fails (Mike Sassak) + +### 2.2.0 / 2010-11-28 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.1.0...v2.2.0) + +### 2.1.0 / 2010-11-07 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.0.1...v2.1.0) + +Enhancements + +* `be_within(delta).of(expected)` matcher (Myron Marston) +* Lots of new Cucumber features (Myron Marston) +* Raise error if you try `should != expected` on Ruby-1.9 (Myron Marston) +* Improved failure messages from `throw_symbol` (Myron Marston) + +Bug fixes + +* Eliminate hard dependency on `RSpec::Core` (Myron Marston) +* `have_matcher` - use pluralize only when ActiveSupport inflections are indeed + defined (Josep M Bach) +* throw_symbol matcher no longer swallows exceptions (Myron Marston) +* fix matcher chaining to avoid name collisions (Myron Marston) + +### 2.0.0 / 2010-10-10 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.0.0.rc...v2.0.0) + +Enhancements + +* Add match_for_should_not method to matcher DSL (Myron Marston) + +Bug fixes + +* `respond_to` matcher works correctly with `should_not` with multiple methods + (Myron Marston) +* `include` matcher works correctly with `should_not` with multiple values + (Myron Marston) + +### 2.0.0.rc / 2010-10-05 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.0.0.beta.22...v2.0.0.rc) + +Enhancements + +* `require 'rspec/expectations'` in a T::U or MiniUnit suite (Josep M. Bach) + +Bug fixes + +* change by 0 passes/fails correctly (Len Smith) +* Add description to satisfy matcher + +### 2.0.0.beta.22 / 2010-09-12 + +[Full Changelog](http://github.com/rspec/rspec-expectations/compare/v2.0.0.beta.20...v2.0.0.beta.22) + +Enhancements + +* diffing improvements + * diff multiline strings + * don't diff single line strings + * don't diff numbers (silly) + * diff regexp + multiline string + +Bug fixes + * `should[_not]` change now handles boolean values correctly diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/LICENSE.md b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/LICENSE.md new file mode 100644 index 00000000..dae02d8a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/LICENSE.md @@ -0,0 +1,25 @@ +The MIT License (MIT) +===================== + +* Copyright © 2012 David Chelimsky, Myron Marston +* Copyright © 2006 David Chelimsky, The RSpec Development Team +* Copyright © 2005 Steven Baker + +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 AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/README.md b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/README.md new file mode 100644 index 00000000..a649542b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/README.md @@ -0,0 +1,326 @@ +# RSpec Expectations [![Build Status](https://github.com/rspec/rspec-expectations/workflows/RSpec%20CI/badge.svg)](https://github.com/rspec/rspec-expectations/actions) [![Code Climate](https://codeclimate.com/github/rspec/rspec-expectations.svg)](https://codeclimate.com/github/rspec/rspec-expectations) + +RSpec::Expectations lets you express expected outcomes on an object in an +example. + +```ruby +expect(account.balance).to eq(Money.new(37.42, :USD)) +``` + +## Install + +If you want to use rspec-expectations with rspec, just install the rspec gem +and RubyGems will also install rspec-expectations for you (along with +rspec-core and rspec-mocks): + +```shell +gem install rspec +``` + +Want to run against the `main` branch? You'll need to include the dependent +RSpec repos as well. Add the following to your `Gemfile`: + +```ruby +%w[rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib| + gem lib, :git => "https://github.com/rspec/#{lib}.git", :branch => 'main' +end +``` + +If you want to use rspec-expectations with another tool, like Test::Unit, +Minitest, or Cucumber, you can install it directly: + +```shell +gem install rspec-expectations +``` + +## Contributing + +Once you've set up the environment, you'll need to cd into the working +directory of whichever repo you want to work in. From there you can run the +specs and cucumber features, and make patches. + +NOTE: You do not need to use rspec-dev to work on a specific RSpec repo. You +can treat each RSpec repo as an independent project. + +- [Build details](BUILD_DETAIL.md) +- [Code of Conduct](CODE_OF_CONDUCT.md) +- [Detailed contributing guide](CONTRIBUTING.md) +- [Development setup guide](DEVELOPMENT.md) + +## Basic usage + +Here's an example using rspec-core: + +```ruby +RSpec.describe Order do + it "sums the prices of the items in its line items" do + order = Order.new + order.add_entry(LineItem.new(:item => Item.new( + :price => Money.new(1.11, :USD) + ))) + order.add_entry(LineItem.new(:item => Item.new( + :price => Money.new(2.22, :USD), + :quantity => 2 + ))) + expect(order.total).to eq(Money.new(5.55, :USD)) + end +end +``` + +The `describe` and `it` methods come from rspec-core. The `Order`, `LineItem`, `Item` and `Money` classes would be from _your_ code. The last line of the example +expresses an expected outcome. If `order.total == Money.new(5.55, :USD)`, then +the example passes. If not, it fails with a message like: + +``` + expected: # + got: # +``` + +## Built-in matchers + +### Equivalence + +```ruby +expect(actual).to eq(expected) # passes if actual == expected +expect(actual).to eql(expected) # passes if actual.eql?(expected) +expect(actual).not_to eql(not_expected) # passes if not(actual.eql?(expected)) +``` + +Note: The new `expect` syntax no longer supports the `==` matcher. + +### Identity + +```ruby +expect(actual).to be(expected) # passes if actual.equal?(expected) +expect(actual).to equal(expected) # passes if actual.equal?(expected) +``` + +### Comparisons + +```ruby +expect(actual).to be > expected +expect(actual).to be >= expected +expect(actual).to be <= expected +expect(actual).to be < expected +expect(actual).to be_within(delta).of(expected) +``` + +### Regular expressions + +```ruby +expect(actual).to match(/expression/) +``` + +Note: The new `expect` syntax no longer supports the `=~` matcher. + +### Types/classes + +```ruby +expect(actual).to be_an_instance_of(expected) # passes if actual.class == expected +expect(actual).to be_a(expected) # passes if actual.kind_of?(expected) +expect(actual).to be_an(expected) # an alias for be_a +expect(actual).to be_a_kind_of(expected) # another alias +``` + +### Truthiness + +```ruby +expect(actual).to be_truthy # passes if actual is truthy (not nil or false) +expect(actual).to be true # passes if actual == true +expect(actual).to be_falsy # passes if actual is falsy (nil or false) +expect(actual).to be false # passes if actual == false +expect(actual).to be_nil # passes if actual is nil +expect(actual).to_not be_nil # passes if actual is not nil +``` + +### Expecting errors + +```ruby +expect { ... }.to raise_error +expect { ... }.to raise_error(ErrorClass) +expect { ... }.to raise_error("message") +expect { ... }.to raise_error(ErrorClass, "message") +``` + +### Expecting throws + +```ruby +expect { ... }.to throw_symbol +expect { ... }.to throw_symbol(:symbol) +expect { ... }.to throw_symbol(:symbol, 'value') +``` + +### Yielding + +```ruby +expect { |b| 5.tap(&b) }.to yield_control # passes regardless of yielded args + +expect { |b| yield_if_true(true, &b) }.to yield_with_no_args # passes only if no args are yielded + +expect { |b| 5.tap(&b) }.to yield_with_args(5) +expect { |b| 5.tap(&b) }.to yield_with_args(Integer) +expect { |b| "a string".tap(&b) }.to yield_with_args(/str/) + +expect { |b| [1, 2, 3].each(&b) }.to yield_successive_args(1, 2, 3) +expect { |b| { :a => 1, :b => 2 }.each(&b) }.to yield_successive_args([:a, 1], [:b, 2]) +``` + +### Predicate matchers + +```ruby +expect(actual).to be_xxx # passes if actual.xxx? +expect(actual).to have_xxx(:arg) # passes if actual.has_xxx?(:arg) +``` + +### Ranges (Ruby >= 1.9 only) + +```ruby +expect(1..10).to cover(3) +``` + +### Collection membership + +```ruby +# exact order, entire collection +expect(actual).to eq(expected) + +# exact order, partial collection (based on an exact position) +expect(actual).to start_with(expected) +expect(actual).to end_with(expected) + +# any order, entire collection +expect(actual).to match_array(expected) + +# You can also express this by passing the expected elements +# as individual arguments +expect(actual).to contain_exactly(expected_element1, expected_element2) + + # any order, partial collection +expect(actual).to include(expected) +``` + +#### Examples + +```ruby +expect([1, 2, 3]).to eq([1, 2, 3]) # Order dependent equality check +expect([1, 2, 3]).to include(1) # Exact ordering, partial collection matches +expect([1, 2, 3]).to include(2, 3) # +expect([1, 2, 3]).to start_with(1) # As above, but from the start of the collection +expect([1, 2, 3]).to start_with(1, 2) # +expect([1, 2, 3]).to end_with(3) # As above but from the end of the collection +expect([1, 2, 3]).to end_with(2, 3) # +expect({:a => 'b'}).to include(:a => 'b') # Matching within hashes +expect("this string").to include("is str") # Matching within strings +expect("this string").to start_with("this") # +expect("this string").to end_with("ring") # +expect([1, 2, 3]).to contain_exactly(2, 3, 1) # Order independent matches +expect([1, 2, 3]).to match_array([3, 2, 1]) # + +# Order dependent compound matchers +expect( + [{:a => 'hash'},{:a => 'another'}] +).to match([a_hash_including(:a => 'hash'), a_hash_including(:a => 'another')]) +``` + +## `should` syntax + +In addition to the `expect` syntax, rspec-expectations continues to support the +`should` syntax: + +```ruby +actual.should eq expected +actual.should be > 3 +[1, 2, 3].should_not include 4 +``` + +See [detailed information on the `should` syntax and its usage.](https://github.com/rspec/rspec-expectations/blob/main/Should.md) + +## Compound Matcher Expressions + +You can also create compound matcher expressions using `and` or `or`: + +``` ruby +expect(alphabet).to start_with("a").and end_with("z") +expect(stoplight.color).to eq("red").or eq("green").or eq("yellow") +``` + +## Composing Matchers + +Many of the built-in matchers are designed to take matchers as +arguments, to allow you to flexibly specify only the essential +aspects of an object or data structure. In addition, all of the +built-in matchers have one or more aliases that provide better +phrasing for when they are used as arguments to another matcher. + +### Examples + +```ruby +expect { k += 1.05 }.to change { k }.by( a_value_within(0.1).of(1.0) ) + +expect { s = "barn" }.to change { s } + .from( a_string_matching(/foo/) ) + .to( a_string_matching(/bar/) ) + +expect(["barn", 2.45]).to contain_exactly( + a_value_within(0.1).of(2.5), + a_string_starting_with("bar") +) + +expect(["barn", "food", 2.45]).to end_with( + a_string_matching("foo"), + a_value > 2 +) + +expect(["barn", 2.45]).to include( a_string_starting_with("bar") ) + +expect(:a => "food", :b => "good").to include(:a => a_string_matching(/foo/)) + +hash = { + :a => { + :b => ["foo", 5], + :c => { :d => 2.05 } + } +} + +expect(hash).to match( + :a => { + :b => a_collection_containing_exactly( + a_string_starting_with("f"), + an_instance_of(Integer) + ), + :c => { :d => (a_value < 3) } + } +) + +expect { |probe| + [1, 2, 3].each(&probe) +}.to yield_successive_args( a_value < 2, 2, a_value > 2 ) +``` + +## Usage outside rspec-core + +You always need to load `rspec/expectations` even if you only want to use one part of the library: + +```ruby +require 'rspec/expectations' +``` + +Then simply include `RSpec::Matchers` in any class: + +```ruby +class MyClass + include RSpec::Matchers + + def do_something(arg) + expect(arg).to be > 0 + # do other stuff + end +end +``` + +## Also see + +* [https://github.com/rspec/rspec](https://github.com/rspec/rspec) +* [https://github.com/rspec/rspec-core](https://github.com/rspec/rspec-core) +* [https://github.com/rspec/rspec-mocks](https://github.com/rspec/rspec-mocks) +* [https://github.com/rspec/rspec-rails](https://github.com/rspec/rspec-rails) diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations.rb new file mode 100644 index 00000000..9e11ea00 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations.rb @@ -0,0 +1,82 @@ +require 'rspec/support' +RSpec::Support.require_rspec_support "caller_filter" +RSpec::Support.require_rspec_support "warnings" +RSpec::Support.require_rspec_support "object_formatter" + +require 'rspec/matchers' + +RSpec::Support.define_optimized_require_for_rspec(:expectations) { |f| require_relative(f) } + +%w[ + expectation_target + configuration + fail_with + handler + version +].each { |file| RSpec::Support.require_rspec_expectations(file) } + +module RSpec + # RSpec::Expectations provides a simple, readable API to express + # the expected outcomes in a code example. To express an expected + # outcome, wrap an object or block in `expect`, call `to` or `to_not` + # (aliased as `not_to`) and pass it a matcher object: + # + # expect(order.total).to eq(Money.new(5.55, :USD)) + # expect(list).to include(user) + # expect(message).not_to match(/foo/) + # expect { do_something }.to raise_error + # + # The last form (the block form) is needed to match against ruby constructs + # that are not objects, but can only be observed when executing a block + # of code. This includes raising errors, throwing symbols, yielding, + # and changing values. + # + # When `expect(...).to` is invoked with a matcher, it turns around + # and calls `matcher.matches?()`. For example, + # in the expression: + # + # expect(order.total).to eq(Money.new(5.55, :USD)) + # + # ...`eq(Money.new(5.55, :USD))` returns a matcher object, and it results + # in the equivalent of `eq.matches?(order.total)`. If `matches?` returns + # `true`, the expectation is met and execution continues. If `false`, then + # the spec fails with the message returned by `eq.failure_message`. + # + # Given the expression: + # + # expect(order.entries).not_to include(entry) + # + # ...the `not_to` method (also available as `to_not`) invokes the equivalent of + # `include.matches?(order.entries)`, but it interprets `false` as success, and + # `true` as a failure, using the message generated by + # `include.failure_message_when_negated`. + # + # rspec-expectations ships with a standard set of useful matchers, and writing + # your own matchers is quite simple. + # + # See [RSpec::Matchers](../RSpec/Matchers) for more information about the + # built-in matchers that ship with rspec-expectations, and how to write your + # own custom matchers. + module Expectations + # Exception raised when an expectation fails. + # + # @note We subclass Exception so that in a stub implementation if + # the user sets an expectation, it can't be caught in their + # code by a bare `rescue`. + # @api public + class ExpectationNotMetError < Exception + end + + # Exception raised from `aggregate_failures` when multiple expectations fail. + # + # @note The constant is defined here but the extensive logic of this class + # is lazily defined when `FailureAggregator` is autoloaded, since we do + # not need to waste time defining that functionality unless + # `aggregate_failures` is used. + class MultipleExpectationsNotMetError < ExpectationNotMetError + end + + autoload :BlockSnippetExtractor, "rspec/expectations/block_snippet_extractor" + autoload :FailureAggregator, "rspec/expectations/failure_aggregator" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/block_snippet_extractor.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/block_snippet_extractor.rb new file mode 100644 index 00000000..25cc3266 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/block_snippet_extractor.rb @@ -0,0 +1,255 @@ +module RSpec + module Expectations + # @private + class BlockSnippetExtractor # rubocop:disable Metrics/ClassLength + # rubocop should properly handle `Struct.new {}` as an inner class definition. + + attr_reader :proc, :method_name + + def self.try_extracting_single_line_body_of(proc, method_name) + lines = new(proc, method_name).body_content_lines + return nil unless lines.count == 1 + lines.first + rescue Error + nil + end + + def initialize(proc, method_name) + @proc = proc + @method_name = method_name.to_s.freeze + end + + # Ideally we should properly handle indentations of multiline snippet, + # but it's not implemented yet since because we use result of this method only when it's a + # single line and implementing the logic introduces additional complexity. + def body_content_lines + raw_body_lines.map(&:strip).reject(&:empty?) + end + + private + + def raw_body_lines + raw_body_snippet.split("\n") + end + + def raw_body_snippet + block_token_extractor.body_tokens.map(&:string).join + end + + def block_token_extractor + @block_token_extractor ||= BlockTokenExtractor.new(method_name, source, beginning_line_number) + end + + if RSpec.respond_to?(:world) + def source + raise TargetNotFoundError unless File.exist?(file_path) + RSpec.world.source_from_file(file_path) + end + else + # :nocov: + RSpec::Support.require_rspec_support 'source' + def source + raise TargetNotFoundError unless File.exist?(file_path) + @source ||= RSpec::Support::Source.from_file(file_path) + end + # :nocov: + end + + def file_path + source_location.first + end + + def beginning_line_number + source_location.last + end + + def source_location + proc.source_location || raise(TargetNotFoundError) + end + + Error = Class.new(StandardError) + TargetNotFoundError = Class.new(Error) + AmbiguousTargetError = Class.new(Error) + + # @private + # Performs extraction of block body snippet using tokens, + # which cannot be done with node information. + BlockTokenExtractor = Struct.new(:method_name, :source, :beginning_line_number) do + attr_reader :state, :body_tokens + + def initialize(*) + super + parse! + end + + private + + def parse! + @state = :initial + + catch(:finish) do + source.tokens.each do |token| + invoke_state_handler(token) + end + end + end + + def finish! + throw :finish + end + + def invoke_state_handler(token) + __send__("#{state}_state", token) + end + + def initial_state(token) + @state = :after_method_call if token.location == block_locator.method_call_location + end + + def after_method_call_state(token) + @state = :after_opener if handle_opener_token(token) + end + + def after_opener_state(token) + if handle_closer_token(token) + finish_or_find_next_block_if_incorrect! + elsif pipe_token?(token) + finalize_pending_tokens! + @state = :after_beginning_of_args + else + pending_tokens << token + handle_opener_token(token) + @state = :after_beginning_of_body unless token.type == :on_sp + end + end + + def after_beginning_of_args_state(token) + @state = :after_beginning_of_body if pipe_token?(token) + end + + def after_beginning_of_body_state(token) + if handle_closer_token(token) + finish_or_find_next_block_if_incorrect! + else + pending_tokens << token + handle_opener_token(token) + end + end + + def pending_tokens + @pending_tokens ||= [] + end + + def finalize_pending_tokens! + pending_tokens.freeze.tap do + @pending_tokens = nil + end + end + + def finish_or_find_next_block_if_incorrect! + body_tokens = finalize_pending_tokens! + + if correct_block?(body_tokens) + @body_tokens = body_tokens + finish! + else + @state = :after_method_call + end + end + + def handle_opener_token(token) + opener_token?(token).tap do |boolean| + opener_token_stack.push(token) if boolean + end + end + + def opener_token?(token) + token.type == :on_lbrace || (token.type == :on_kw && token.string == 'do') + end + + def handle_closer_token(token) + if opener_token_stack.last.closed_by?(token) + opener_token_stack.pop + opener_token_stack.empty? + else + false + end + end + + def opener_token_stack + @opener_token_stack ||= [] + end + + def pipe_token?(token) + token.type == :on_op && token.string == '|' + end + + def correct_block?(body_tokens) + return true if block_locator.body_content_locations.empty? + content_location = block_locator.body_content_locations.first + content_location.between?(body_tokens.first.location, body_tokens.last.location) + end + + def block_locator + @block_locator ||= BlockLocator.new(method_name, source, beginning_line_number) + end + end + + # @private + # Locates target block with node information (semantics), which tokens don't have. + BlockLocator = Struct.new(:method_name, :source, :beginning_line_number) do + def method_call_location + @method_call_location ||= method_ident_node.location + end + + def body_content_locations + @body_content_locations ||= block_body_node.map(&:location).compact + end + + private + + def method_ident_node + method_call_node = block_wrapper_node.children.first + method_call_node.find do |node| + method_ident_node?(node) + end + end + + def block_body_node + block_node = block_wrapper_node.children[1] + block_node.children.last + end + + def block_wrapper_node + case candidate_block_wrapper_nodes.size + when 1 + candidate_block_wrapper_nodes.first + when 0 + raise TargetNotFoundError + else + raise AmbiguousTargetError + end + end + + def candidate_block_wrapper_nodes + @candidate_block_wrapper_nodes ||= candidate_method_ident_nodes.map do |method_ident_node| + block_wrapper_node = method_ident_node.each_ancestor.find { |node| node.type == :method_add_block } + next nil unless block_wrapper_node + method_call_node = block_wrapper_node.children.first + method_call_node.include?(method_ident_node) ? block_wrapper_node : nil + end.compact + end + + def candidate_method_ident_nodes + source.nodes_by_line_number[beginning_line_number].select do |node| + method_ident_node?(node) + end + end + + def method_ident_node?(node) + node.type == :@ident && node.args.first == method_name + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/configuration.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/configuration.rb new file mode 100644 index 00000000..21620fb5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/configuration.rb @@ -0,0 +1,244 @@ +RSpec::Support.require_rspec_expectations "syntax" + +module RSpec + module Expectations + # Provides configuration options for rspec-expectations. + # If you are using rspec-core, you can access this via a + # block passed to `RSpec::Core::Configuration#expect_with`. + # Otherwise, you can access it via RSpec::Expectations.configuration. + # + # @example + # RSpec.configure do |rspec| + # rspec.expect_with :rspec do |c| + # # c is the config object + # end + # end + # + # # or + # + # RSpec::Expectations.configuration + class Configuration + # @private + FALSE_POSITIVE_BEHAVIOURS = + { + :warn => lambda { |message| RSpec.warning message }, + :raise => lambda { |message| raise ArgumentError, message }, + :nothing => lambda { |_| true }, + } + + def initialize + @on_potential_false_positives = :warn + @strict_predicate_matchers = false + end + + # Configures the supported syntax. + # @param [Array, Symbol] values the syntaxes to enable + # @example + # RSpec.configure do |rspec| + # rspec.expect_with :rspec do |c| + # c.syntax = :should + # # or + # c.syntax = :expect + # # or + # c.syntax = [:should, :expect] + # end + # end + def syntax=(values) + if Array(values).include?(:expect) + Expectations::Syntax.enable_expect + else + Expectations::Syntax.disable_expect + end + + if Array(values).include?(:should) + Expectations::Syntax.enable_should + else + Expectations::Syntax.disable_should + end + end + + # Configures the maximum character length that RSpec will print while + # formatting an object. You can set length to nil to prevent RSpec from + # doing truncation. + # @param [Fixnum] length the number of characters to limit the formatted output to. + # @example + # RSpec.configure do |rspec| + # rspec.expect_with :rspec do |c| + # c.max_formatted_output_length = 200 + # end + # end + def max_formatted_output_length=(length) + RSpec::Support::ObjectFormatter.default_instance.max_formatted_output_length = length + end + + # The list of configured syntaxes. + # @return [Array] the list of configured syntaxes. + # @example + # unless RSpec::Matchers.configuration.syntax.include?(:expect) + # raise "this RSpec extension gem requires the rspec-expectations `:expect` syntax" + # end + def syntax + syntaxes = [] + syntaxes << :should if Expectations::Syntax.should_enabled? + syntaxes << :expect if Expectations::Syntax.expect_enabled? + syntaxes + end + + if ::RSpec.respond_to?(:configuration) + def color? + ::RSpec.configuration.color_enabled? + end + else + # :nocov: + # Indicates whether or not diffs should be colored. + # Delegates to rspec-core's color option if rspec-core + # is loaded; otherwise you can set it here. + attr_writer :color + + # Indicates whether or not diffs should be colored. + # Delegates to rspec-core's color option if rspec-core + # is loaded; otherwise you can set it here. + def color? + defined?(@color) && @color + end + # :nocov: + end + + # :nocov: Because this is only really _useful_ on 1.8, and hard to test elsewhere. + # + # Adds `should` and `should_not` to the given classes + # or modules. This can be used to ensure `should` works + # properly on things like proxy objects (particular + # `Delegator`-subclassed objects on 1.8). + # + # @param [Array] modules the list of classes or modules + # to add `should` and `should_not` to. + def add_should_and_should_not_to(*modules) + modules.each do |mod| + Expectations::Syntax.enable_should(mod) + end + end + # :nocov: + + # Sets or gets the backtrace formatter. The backtrace formatter should + # implement `#format_backtrace(Array)`. This is used + # to format backtraces of errors handled by the `raise_error` + # matcher. + # + # If you are using rspec-core, rspec-core's backtrace formatting + # will be used (including respecting the presence or absence of + # the `--backtrace` option). + # + # @!attribute [rw] backtrace_formatter + attr_writer :backtrace_formatter + def backtrace_formatter + @backtrace_formatter ||= if defined?(::RSpec.configuration.backtrace_formatter) + ::RSpec.configuration.backtrace_formatter + else + NullBacktraceFormatter + end + end + + # Sets if custom matcher descriptions and failure messages + # should include clauses from methods defined using `chain`. + # @param value [Boolean] + attr_writer :include_chain_clauses_in_custom_matcher_descriptions + + # Indicates whether or not custom matcher descriptions and failure messages + # should include clauses from methods defined using `chain`. It is + # false by default for backwards compatibility. + def include_chain_clauses_in_custom_matcher_descriptions? + @include_chain_clauses_in_custom_matcher_descriptions ||= false + end + + # @private + def reset_syntaxes_to_default + self.syntax = [:should, :expect] + RSpec::Expectations::Syntax.warn_about_should! + end + + # @api private + # Null implementation of a backtrace formatter used by default + # when rspec-core is not loaded. Does no filtering. + NullBacktraceFormatter = Module.new do + def self.format_backtrace(backtrace) + backtrace + end + end + + # Configures whether RSpec will warn about matcher use which will + # potentially cause false positives in tests. + # + # @param [Boolean] boolean + def warn_about_potential_false_positives=(boolean) + if boolean + self.on_potential_false_positives = :warn + elsif warn_about_potential_false_positives? + self.on_potential_false_positives = :nothing + else + # no-op, handler is something else + end + end + + # Configures what RSpec will do about matcher use which would potentially cause + # false positives in tests. Defaults to `:warn` since this is generally the desired behavior, + # but can also be set to `:raise` or `:nothing`. + # + # @overload on_potential_false_positives + # @return [Symbol] the behavior setting + # @overload on_potential_false_positives=(value) + # @param [Symbol] behavior can be set to `:warn`, `:raise` or `:nothing` + # @return [Symbol] the behavior setting + attr_reader :on_potential_false_positives + + def on_potential_false_positives=(behavior) + unless FALSE_POSITIVE_BEHAVIOURS.key?(behavior) + raise ArgumentError, "Supported values are: #{FALSE_POSITIVE_BEHAVIOURS.keys}" + end + @on_potential_false_positives = behavior + end + + # Configures RSpec to check predicate matchers to `be(true)` / `be(false)` (strict), + # or `be_truthy` / `be_falsey` (not strict). + # Historically, the default was `false`, but `true` is recommended. + # + # @overload strict_predicate_matchers + # @return [Boolean] + # @overload strict_predicate_matchers? + # @return [Boolean] + # @overload strict_predicate_matchers=(value) + # @param [Boolean] value + attr_reader :strict_predicate_matchers + + def strict_predicate_matchers=(value) + raise ArgumentError, "Pass `true` or `false`" unless value == true || value == false + @strict_predicate_matchers = value + end + + def strict_predicate_matchers? + @strict_predicate_matchers + end + + # Indicates whether RSpec will warn about matcher use which will + # potentially cause false positives in tests, generally you want to + # avoid such scenarios so this defaults to `true`. + def warn_about_potential_false_positives? + on_potential_false_positives == :warn + end + + # @private + def false_positives_handler + FALSE_POSITIVE_BEHAVIOURS.fetch(@on_potential_false_positives) + end + end + + # The configuration object. + # @return [RSpec::Expectations::Configuration] the configuration object + def self.configuration + @configuration ||= Configuration.new + end + + # set default syntax + configuration.reset_syntaxes_to_default + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/expectation_target.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/expectation_target.rb new file mode 100644 index 00000000..7d1e8d40 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/expectation_target.rb @@ -0,0 +1,163 @@ +module RSpec + module Expectations + # Wraps the target of an expectation. + # + # @example + # expect(something) # => ExpectationTarget wrapping something + # expect { do_something } # => ExpectationTarget wrapping the block + # + # # used with `to` + # expect(actual).to eq(3) + # + # # with `not_to` + # expect(actual).not_to eq(3) + # + # @note `ExpectationTarget` is not intended to be instantiated + # directly by users. Use `expect` instead. + class ExpectationTarget + # @private + # Used as a sentinel value to be able to tell when the user + # did not pass an argument. We can't use `nil` for that because + # `nil` is a valid value to pass. + UndefinedValue = Module.new + + # @note this name aligns with `Minitest::Expectation` so that our + # {InstanceMethods} module can be included in that class when + # used in a Minitest context. + # @return [Object] the target of the expectation + attr_reader :target + + # @api private + def initialize(value) + @target = value + end + + # @private + def self.for(value, block) + if UndefinedValue.equal?(value) + unless block + raise ArgumentError, "You must pass either an argument or a block to `expect`." + end + BlockExpectationTarget.new(block) + elsif block + raise ArgumentError, "You cannot pass both an argument and a block to `expect`." + else + ValueExpectationTarget.new(value) + end + end + + # Defines instance {ExpectationTarget} instance methods. These are defined + # in a module so we can include it in `Minitest::Expectation` when + # `rspec/expectations/minitest_integration` is loaded in order to + # support usage with Minitest. + module InstanceMethods + # Runs the given expectation, passing if `matcher` returns true. + # @example + # expect(value).to eq(5) + # expect { perform }.to raise_error + # @param [Matcher] + # matcher + # @param [String, Proc] message optional message to display when the expectation fails + # @return [Boolean] true if the expectation succeeds (else raises) + # @see RSpec::Matchers + def to(matcher=nil, message=nil, &block) + prevent_operator_matchers(:to) unless matcher + RSpec::Expectations::PositiveExpectationHandler.handle_matcher(target, matcher, message, &block) + end + + # Runs the given expectation, passing if `matcher` returns false. + # @example + # expect(value).not_to eq(5) + # @param [Matcher] + # matcher + # @param [String, Proc] message optional message to display when the expectation fails + # @return [Boolean] false if the negative expectation succeeds (else raises) + # @see RSpec::Matchers + def not_to(matcher=nil, message=nil, &block) + prevent_operator_matchers(:not_to) unless matcher + RSpec::Expectations::NegativeExpectationHandler.handle_matcher(target, matcher, message, &block) + end + alias to_not not_to + + private + + def prevent_operator_matchers(verb) + raise ArgumentError, "The expect syntax does not support operator matchers, " \ + "so you must pass a matcher to `##{verb}`." + end + end + + include InstanceMethods + end + + # @private + # Validates the provided matcher to ensure it supports block + # expectations, in order to avoid user confusion when they + # use a block thinking the expectation will be on the return + # value of the block rather than the block itself. + class ValueExpectationTarget < ExpectationTarget + def to(matcher=nil, message=nil, &block) + enforce_value_expectation(matcher) + super + end + + def not_to(matcher=nil, message=nil, &block) + enforce_value_expectation(matcher) + super + end + + private + + def enforce_value_expectation(matcher) + return if supports_value_expectations?(matcher) + + RSpec.deprecate( + "expect(value).to #{RSpec::Support::ObjectFormatter.format(matcher)}", + :message => + "The implicit block expectation syntax is deprecated, you should pass " \ + "a block rather than an argument to `expect` to use the provided " \ + "block expectation matcher or the matcher must implement " \ + "`supports_value_expectations?`. e.g `expect { value }.to " \ + "#{RSpec::Support::ObjectFormatter.format(matcher)}` not " \ + "`expect(value).to #{RSpec::Support::ObjectFormatter.format(matcher)}`" + ) + end + + def supports_value_expectations?(matcher) + !matcher.respond_to?(:supports_value_expectations?) || matcher.supports_value_expectations? + end + end + + # @private + # Validates the provided matcher to ensure it supports block + # expectations, in order to avoid user confusion when they + # use a block thinking the expectation will be on the return + # value of the block rather than the block itself. + class BlockExpectationTarget < ExpectationTarget + def to(matcher, message=nil, &block) + enforce_block_expectation(matcher) + super + end + + def not_to(matcher, message=nil, &block) + enforce_block_expectation(matcher) + super + end + alias to_not not_to + + private + + def enforce_block_expectation(matcher) + return if supports_block_expectations?(matcher) + + raise ExpectationNotMetError, "You must pass an argument rather than a block to `expect` to use the provided " \ + "matcher (#{RSpec::Support::ObjectFormatter.format(matcher)}), or the matcher must implement " \ + "`supports_block_expectations?`." + end + + def supports_block_expectations?(matcher) + matcher.respond_to?(:supports_block_expectations?) && matcher.supports_block_expectations? + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/fail_with.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/fail_with.rb new file mode 100644 index 00000000..17b66b3d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/fail_with.rb @@ -0,0 +1,39 @@ +module RSpec + module Expectations + class << self + # @private + class Differ + # @private + OBJECT_PREPARER = lambda do |object| + RSpec::Matchers::Composable.surface_descriptions_in(object) + end + end + + # @private + def differ + RSpec::Support::Differ.new( + :object_preparer => Differ::OBJECT_PREPARER, + :color => RSpec::Matchers.configuration.color? + ) + end + + # Raises an RSpec::Expectations::ExpectationNotMetError with message. + # @param [String] message + # @param [Object] expected + # @param [Object] actual + # + # Adds a diff to the failure message when `expected` and `actual` are + # both present. + def fail_with(message, expected=nil, actual=nil) + unless message + raise ArgumentError, "Failure message is nil. Does your matcher define the " \ + "appropriate failure_message[_when_negated] method to return a string?" + end + + message = ::RSpec::Matchers::MultiMatcherDiff.from(expected, actual).message_with_diff(message, differ) + + RSpec::Support.notify_failure(RSpec::Expectations::ExpectationNotMetError.new message) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/failure_aggregator.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/failure_aggregator.rb new file mode 100644 index 00000000..b573bba2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/failure_aggregator.rb @@ -0,0 +1,236 @@ +module RSpec + module Expectations + # @private + class FailureAggregator + attr_reader :block_label, :metadata + + # @private + class AggregatedFailure + # :nocov: + # `inspect` was apparently used by some versions early in ruby 3 while constructing + # NoMethodError, but seems to be no longer. + # + # @private + MESSAGE = + 'AggregatedFailure: This method caused a failure which has been ' \ + 'suppressed to be aggregated into our failure report by returning ' \ + 'this value, further errors can be ignored.' + + def inspect + MESSAGE + end + # :nocov: + end + + AGGREGATED_FAILURE = AggregatedFailure.new + + def aggregate + RSpec::Support.with_failure_notifier(self) do + begin + yield + rescue ExpectationNotMetError => e + # Normally, expectation failures will be notified via the `call` method, below, + # but since the failure notifier uses a thread local variable, failing expectations + # in another thread will still raise. We handle that here and categorize it as part + # of `failures` rather than letting it fall through and be categorized as part of + # `other_errors`. + failures << e + rescue Support::AllExceptionsExceptOnesWeMustNotRescue => e + # While it is normally a bad practice to rescue `Exception`, it's important we do + # so here. It's low risk (`notify_aggregated_failures` below will re-raise the exception, + # or raise a `MultipleExpectationsNotMetError` that includes the exception), and it's + # essential that the user is notified of expectation failures that may have already + # occurred in the `aggregate_failures` block. Those expectation failures may provide + # important diagnostics for understanding why this exception occurred, and if we simply + # allowed this exception to be raised as-is, it would (wrongly) suggest to the user + # that the expectation passed when it did not, which would be quite confusing. + other_errors << e + end + end + + notify_aggregated_failures + end + + def failures + @failures ||= [] + end + + def other_errors + @other_errors ||= [] + end + + # This method is defined to satisfy the callable interface + # expected by `RSpec::Support.with_failure_notifier`. + def call(failure, options) + source_id = options[:source_id] + return if source_id && @seen_source_ids.key?(source_id) + + @seen_source_ids[source_id] = true + assign_backtrace(failure) unless failure.backtrace + failures << failure + + AGGREGATED_FAILURE + end + + private + + if RSpec::Support::Ruby.jruby? && RSpec::Support::Ruby.jruby_version < '9.2.0.0' + # On JRuby 9.1.x.x and before, `caller` and `raise` produce different backtraces with + # regards to `.java` stack frames. It's important that we use `raise` for JRuby to produce + # a backtrace that has a continuous common section with the raised `MultipleExpectationsNotMetError`, + # so that rspec-core's truncation logic can work properly on it to list the backtrace + # relative to the `aggregate_failures` block. + # :nocov: + def assign_backtrace(failure) + raise failure + rescue failure.class => e + failure.set_backtrace(e.backtrace) + end + # :nocov: + else + # Using `caller` performs better (and is simpler) than `raise` on most Rubies. + def assign_backtrace(failure) + failure.set_backtrace(caller) + end + end + + def initialize(block_label, metadata) + @block_label = block_label + @metadata = metadata + @seen_source_ids = {} # don't want to load stdlib set + end + + def notify_aggregated_failures + all_errors = failures + other_errors + + case all_errors.size + when 0 then return true + when 1 then RSpec::Support.notify_failure all_errors.first + else RSpec::Support.notify_failure MultipleExpectationsNotMetError.new(self) + end + end + end + + # Exception raised from `aggregate_failures` when multiple expectations fail. + class MultipleExpectationsNotMetError + # @return [String] The fully formatted exception message. + def message + @message ||= (["#{summary}:"] + enumerated_failures + enumerated_errors).join("\n\n") + end + + # @return [Array] The list of expectation failures. + def failures + @failure_aggregator.failures + end + + # @return [Array] The list of other exceptions. + def other_errors + @failure_aggregator.other_errors + end + + # @return [Array] The list of expectation failures and other exceptions, combined. + attr_reader :all_exceptions + + # @return [String] The user-assigned label for the aggregation block. + def aggregation_block_label + @failure_aggregator.block_label + end + + # @return [Hash] The metadata hash passed to `aggregate_failures`. + def aggregation_metadata + @failure_aggregator.metadata + end + + # @return [String] A summary of the failure, including the block label and a count of failures. + def summary + "Got #{exception_count_description} from failure aggregation " \ + "block#{block_description}" + end + + # return [String] A description of the failure/error counts. + def exception_count_description + failure_count = pluralize("failure", failures.size) + return failure_count if other_errors.empty? + error_count = pluralize("other error", other_errors.size) + "#{failure_count} and #{error_count}" + end + + private + + def initialize(failure_aggregator) + @failure_aggregator = failure_aggregator + @all_exceptions = failures + other_errors + end + + def block_description + return "" unless aggregation_block_label + " #{aggregation_block_label.inspect}" + end + + def pluralize(noun, count) + "#{count} #{noun}#{'s' unless count == 1}" + end + + def enumerated(exceptions, index_offset) + exceptions.each_with_index.map do |exception, index| + index += index_offset + formatted_message = "#{yield exception}\n#{format_backtrace(exception.backtrace).first}" + "#{index_label index}#{indented formatted_message, index}" + end + end + + def exclusion_patterns + patterns = %w[/lib\d*/ruby/ bin/ exe/rspec /lib/bundler/ /exe/bundle:] + patterns << "org/jruby/" if RSpec::Support::Ruby.jruby? + patterns.map! { |s| Regexp.new(s.gsub('/', File::SEPARATOR)) } + end + + def format_backtrace(backtrace) + backtrace.map { |l| backtrace_line(l) }.compact.tap { |filtered| filtered.concat backtrace if filtered.empty? } + end + + def backtrace_line(line) + return if [Regexp.union(RSpec::CallerFilter::IGNORE_REGEX, *exclusion_patterns)].any? { |p| line =~ p } + + # It changes the current path that is relative to + # system root to be relative to the project root. + line.sub(/(\A|\s)#{File.expand_path('.')}(#{File::SEPARATOR}|\s|\Z)/, '\\1.\\2'.freeze).sub(/\A([^:]+:\d+)$/, '\\1'.freeze) + end + + def enumerated_failures + enumerated(failures, 0, &:message) + end + + def enumerated_errors + enumerated(other_errors, failures.size) do |error| + "#{error.class}: #{error.message}" + end + end + + def indented(failure_message, index) + line_1, *rest = failure_message.strip.lines.to_a + first_line_indentation = ' ' * (longest_index_label_width - width_of_label(index)) + + first_line_indentation + line_1 + rest.map do |line| + line =~ /\S/ ? indentation + line : line + end.join + end + + def indentation + @indentation ||= ' ' * longest_index_label_width + end + + def longest_index_label_width + @longest_index_label_width ||= width_of_label(failures.size) + end + + def width_of_label(index) + index_label(index).chars.count + end + + def index_label(index) + " #{index + 1}) " + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/handler.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/handler.rb new file mode 100644 index 00000000..d86061a1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/handler.rb @@ -0,0 +1,181 @@ +module RSpec + module Expectations + # @private + module ExpectationHelper + def self.check_message(msg) + unless msg.nil? || msg.respond_to?(:to_str) || msg.respond_to?(:call) + RSpec.warning( + "ignoring the provided expectation message argument" \ + "(#{ msg.inspect }) since it is not a string or a proc" + ) + end + end + + # Returns an RSpec-3+ compatible matcher, wrapping a legacy one + # in an adapter if necessary. + # + # @private + def self.modern_matcher_from(matcher) + LegacyMatcherAdapter::RSpec2.wrap(matcher) || + LegacyMatcherAdapter::RSpec1.wrap(matcher) || matcher + end + + def self.with_matcher(handler, matcher, message) + check_message(message) + matcher = modern_matcher_from(matcher) + yield matcher + ensure + ::RSpec::Matchers.last_expectation_handler = handler + ::RSpec::Matchers.last_matcher = matcher + end + + def self.handle_failure(matcher, message, failure_message_method) + message = message.call if message.respond_to?(:call) + message ||= matcher.__send__(failure_message_method) + + if matcher.respond_to?(:diffable?) && matcher.diffable? + ::RSpec::Expectations.fail_with message, matcher.expected, matcher.actual + else + ::RSpec::Expectations.fail_with message + end + end + end + + # @private + class PositiveExpectationHandler + def self.handle_matcher(actual, initial_matcher, custom_message=nil, &block) + ExpectationHelper.with_matcher(self, initial_matcher, custom_message) do |matcher| + return ::RSpec::Matchers::BuiltIn::PositiveOperatorMatcher.new(actual) unless initial_matcher + + match_result = matcher.matches?(actual, &block) + if custom_message && match_result.respond_to?(:error_generator) + match_result.error_generator.opts[:message] = custom_message + end + + match_result || ExpectationHelper.handle_failure(matcher, custom_message, :failure_message) + end + end + + def self.verb + 'is expected to' + end + + def self.should_method + :should + end + + def self.opposite_should_method + :should_not + end + end + + # @private + class NegativeExpectationHandler + def self.handle_matcher(actual, initial_matcher, custom_message=nil, &block) + ExpectationHelper.with_matcher(self, initial_matcher, custom_message) do |matcher| + return ::RSpec::Matchers::BuiltIn::NegativeOperatorMatcher.new(actual) unless initial_matcher + + negated_match_result = does_not_match?(matcher, actual, &block) + if custom_message && negated_match_result.respond_to?(:error_generator) + negated_match_result.error_generator.opts[:message] = custom_message + end + + negated_match_result || ExpectationHelper.handle_failure(matcher, custom_message, :failure_message_when_negated) + end + end + + def self.does_not_match?(matcher, actual, &block) + if matcher.respond_to?(:does_not_match?) + matcher.does_not_match?(actual, &block) + else + !matcher.matches?(actual, &block) + end + end + + def self.verb + 'is expected not to' + end + + def self.should_method + :should_not + end + + def self.opposite_should_method + :should + end + end + + # Wraps a matcher written against one of the legacy protocols in + # order to present the current protocol. + # + # @private + class LegacyMatcherAdapter < Matchers::MatcherDelegator + def initialize(matcher) + super + ::RSpec.warn_deprecation(<<-EOS.gsub(/^\s+\|/, ''), :type => "legacy_matcher") + |#{matcher.class.name || matcher.inspect} implements a legacy RSpec matcher + |protocol. For the current protocol you should expose the failure messages + |via the `failure_message` and `failure_message_when_negated` methods. + |(Used from #{CallerFilter.first_non_rspec_line}) + EOS + end + + def self.wrap(matcher) + new(matcher) if interface_matches?(matcher) + end + + # Starting in RSpec 1.2 (and continuing through all 2.x releases), + # the failure message protocol was: + # * `failure_message_for_should` + # * `failure_message_for_should_not` + # @private + class RSpec2 < self + def failure_message + base_matcher.failure_message_for_should + end + + def failure_message_when_negated + base_matcher.failure_message_for_should_not + end + + def self.interface_matches?(matcher) + ( + !matcher.respond_to?(:failure_message) && + matcher.respond_to?(:failure_message_for_should) + ) || ( + !matcher.respond_to?(:failure_message_when_negated) && + matcher.respond_to?(:failure_message_for_should_not) + ) + end + end + + # Before RSpec 1.2, the failure message protocol was: + # * `failure_message` + # * `negative_failure_message` + # @private + class RSpec1 < self + def failure_message + base_matcher.failure_message + end + + def failure_message_when_negated + base_matcher.negative_failure_message + end + + # Note: `failure_message` is part of the RSpec 3 protocol + # (paired with `failure_message_when_negated`), so we don't check + # for `failure_message` here. + def self.interface_matches?(matcher) + !matcher.respond_to?(:failure_message_when_negated) && + matcher.respond_to?(:negative_failure_message) + end + end + end + + # RSpec 3.0 was released with the class name misspelled. For SemVer compatibility, + # we will provide this misspelled alias until 4.0. + # @deprecated Use LegacyMatcherAdapter instead. + # @private + LegacyMacherAdapter = LegacyMatcherAdapter + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/minitest_integration.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/minitest_integration.rb new file mode 100644 index 00000000..94cdb5f3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/minitest_integration.rb @@ -0,0 +1,58 @@ +require 'rspec/expectations' + +Minitest::Test.class_eval do + include ::RSpec::Matchers + + # This `expect` will only be called if the user is using Minitest < 5.6 + # or if they are _not_ using Minitest::Spec on 5.6+. Minitest::Spec on 5.6+ + # defines its own `expect` and will have the assertions incremented via our + # definitions of `to`/`not_to`/`to_not` below. + def expect(*a, &b) + self.assertions += 1 + super + end + + # Convert a `MultipleExpectationsNotMetError` to a `Minitest::Assertion` error so + # it gets counted in minitest's summary stats as a failure rather than an error. + # It would be nice to make `MultipleExpectationsNotMetError` subclass + # `Minitest::Assertion`, but Minitest's implementation does not treat subclasses + # the same, so this is the best we can do. + def aggregate_failures(*args, &block) + super + rescue RSpec::Expectations::MultipleExpectationsNotMetError => e + assertion_failed = Minitest::Assertion.new(e.message) + assertion_failed.set_backtrace e.backtrace + raise assertion_failed + end +end + +# Older versions of Minitest (e.g. before 5.6) do not define +# `Minitest::Expectation`. +if defined?(::Minitest::Expectation) + Minitest::Expectation.class_eval do + include RSpec::Expectations::ExpectationTarget::InstanceMethods + + def to(*args) + ctx.assertions += 1 + super + end + + def not_to(*args) + ctx.assertions += 1 + super + end + + def to_not(*args) + ctx.assertions += 1 + super + end + end +end + +module RSpec + module Expectations + remove_const :ExpectationNotMetError + # Exception raised when an expectation fails. + const_set :ExpectationNotMetError, ::Minitest::Assertion + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/syntax.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/syntax.rb new file mode 100644 index 00000000..b8430346 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/syntax.rb @@ -0,0 +1,132 @@ +module RSpec + module Expectations + # @api private + # Provides methods for enabling and disabling the available + # syntaxes provided by rspec-expectations. + module Syntax + module_function + + # @api private + # Determines where we add `should` and `should_not`. + def default_should_host + @default_should_host ||= ::Object.ancestors.last + end + + # @api private + # Instructs rspec-expectations to warn on first usage of `should` or `should_not`. + # Enabled by default. This is largely here to facilitate testing. + def warn_about_should! + @warn_about_should = true + end + + # @api private + # Generates a deprecation warning for the given method if no warning + # has already been issued. + def warn_about_should_unless_configured(method_name) + return unless @warn_about_should + + RSpec.deprecate( + "Using `#{method_name}` from rspec-expectations' old `:should` syntax without explicitly enabling the syntax", + :replacement => "the new `:expect` syntax or explicitly enable `:should` with `config.expect_with(:rspec) { |c| c.syntax = :should }`" + ) + + @warn_about_should = false + end + + # @api private + # Enables the `should` syntax. + def enable_should(syntax_host=default_should_host) + @warn_about_should = false if syntax_host == default_should_host + return if should_enabled?(syntax_host) + + syntax_host.module_exec do + def should(matcher=nil, message=nil, &block) + ::RSpec::Expectations::Syntax.warn_about_should_unless_configured(::Kernel.__method__) + ::RSpec::Expectations::PositiveExpectationHandler.handle_matcher(self, matcher, message, &block) + end + + def should_not(matcher=nil, message=nil, &block) + ::RSpec::Expectations::Syntax.warn_about_should_unless_configured(::Kernel.__method__) + ::RSpec::Expectations::NegativeExpectationHandler.handle_matcher(self, matcher, message, &block) + end + end + end + + # @api private + # Disables the `should` syntax. + def disable_should(syntax_host=default_should_host) + return unless should_enabled?(syntax_host) + + syntax_host.module_exec do + undef should + undef should_not + end + end + + # @api private + # Enables the `expect` syntax. + def enable_expect(syntax_host=::RSpec::Matchers) + return if expect_enabled?(syntax_host) + + syntax_host.module_exec do + def expect(value=::RSpec::Expectations::ExpectationTarget::UndefinedValue, &block) + ::RSpec::Expectations::ExpectationTarget.for(value, block) + end + end + end + + # @api private + # Disables the `expect` syntax. + def disable_expect(syntax_host=::RSpec::Matchers) + return unless expect_enabled?(syntax_host) + + syntax_host.module_exec do + undef expect + end + end + + # @api private + # Indicates whether or not the `should` syntax is enabled. + def should_enabled?(syntax_host=default_should_host) + syntax_host.method_defined?(:should) + end + + # @api private + # Indicates whether or not the `expect` syntax is enabled. + def expect_enabled?(syntax_host=::RSpec::Matchers) + syntax_host.method_defined?(:expect) + end + end + end +end + +if defined?(BasicObject) + # The legacy `:should` syntax adds the following methods directly to + # `BasicObject` so that they are available off of any object. Note, however, + # that this syntax does not always play nice with delegate/proxy objects. + # We recommend you use the non-monkeypatching `:expect` syntax instead. + class BasicObject + # @method should(matcher, message) + # Passes if `matcher` returns true. Available on every `Object`. + # @example + # actual.should eq expected + # actual.should match /expression/ + # @param [Matcher] + # matcher + # @param [String] message optional message to display when the expectation fails + # @return [Boolean] true if the expectation succeeds (else raises) + # @note This is only available when you have enabled the `:should` syntax. + # @see RSpec::Matchers + + # @method should_not(matcher, message) + # Passes if `matcher` returns false. Available on every `Object`. + # @example + # actual.should_not eq expected + # @param [Matcher] + # matcher + # @param [String] message optional message to display when the expectation fails + # @return [Boolean] false if the negative expectation succeeds (else raises) + # @note This is only available when you have enabled the `:should` syntax. + # @see RSpec::Matchers + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/version.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/version.rb new file mode 100644 index 00000000..0fc9ef9a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/expectations/version.rb @@ -0,0 +1,8 @@ +module RSpec + module Expectations + # @private + module Version + STRING = '3.13.5' + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers.rb new file mode 100644 index 00000000..d5347d12 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers.rb @@ -0,0 +1,1046 @@ +require 'rspec/support' +RSpec::Support.require_rspec_support 'matcher_definition' +RSpec::Support.define_optimized_require_for_rspec(:matchers) { |f| require_relative(f) } + +%w[ + english_phrasing + composable + built_in + generated_descriptions + dsl + matcher_delegator + aliased_matcher + multi_matcher_diff +].each { |file| RSpec::Support.require_rspec_matchers(file) } + +# RSpec's top level namespace. All of rspec-expectations is contained +# in the `RSpec::Expectations` and `RSpec::Matchers` namespaces. +module RSpec + # RSpec::Matchers provides a number of useful matchers we use to define + # expectations. Any object that implements the [matcher protocol](Matchers/MatcherProtocol) + # can be used as a matcher. + # + # ## Predicates + # + # In addition to matchers that are defined explicitly, RSpec will create + # custom matchers on the fly for any arbitrary predicate, giving your specs a + # much more natural language feel. + # + # A Ruby predicate is a method that ends with a "?" and returns true or false. + # Common examples are `empty?`, `nil?`, and `instance_of?`. + # + # All you need to do is write `expect(..).to be_` followed by the predicate + # without the question mark, and RSpec will figure it out from there. + # For example: + # + # expect([]).to be_empty # => [].empty?() | passes + # expect([]).not_to be_empty # => [].empty?() | fails + # + # In addition to prefixing the predicate matchers with "be_", you can also use "be_a_" + # and "be_an_", making your specs read much more naturally: + # + # expect("a string").to be_an_instance_of(String) # =>"a string".instance_of?(String) # passes + # + # expect(3).to be_a_kind_of(Integer) # => 3.kind_of?(Numeric) | passes + # expect(3).to be_a_kind_of(Numeric) # => 3.kind_of?(Numeric) | passes + # expect(3).to be_an_instance_of(Integer) # => 3.instance_of?(Integer) | passes + # expect(3).not_to be_an_instance_of(Numeric) # => 3.instance_of?(Numeric) | fails + # + # RSpec will also create custom matchers for predicates like `has_key?`. To + # use this feature, just state that the object should have_key(:key) and RSpec will + # call has_key?(:key) on the target. For example: + # + # expect(:a => "A").to have_key(:a) + # expect(:a => "A").to have_key(:b) # fails + # + # You can use this feature to invoke any predicate that begins with "has_", whether it is + # part of the Ruby libraries (like `Hash#has_key?`) or a method you wrote on your own class. + # + # Note that RSpec does not provide composable aliases for these dynamic predicate + # matchers. You can easily define your own aliases, though: + # + # RSpec::Matchers.alias_matcher :a_user_who_is_an_admin, :be_an_admin + # expect(user_list).to include(a_user_who_is_an_admin) + # + # ## Alias Matchers + # + # With {RSpec::Matchers.alias_matcher}, you can easily create an + # alternate name for a given matcher. + # + # The description will also change according to the new name: + # + # RSpec::Matchers.alias_matcher :a_list_that_sums_to, :sum_to + # sum_to(3).description # => "sum to 3" + # a_list_that_sums_to(3).description # => "a list that sums to 3" + # + # or you can specify a custom description like this: + # + # RSpec::Matchers.alias_matcher :a_list_sorted_by, :be_sorted_by do |description| + # description.sub("be sorted by", "a list sorted by") + # end + # + # be_sorted_by(:age).description # => "be sorted by age" + # a_list_sorted_by(:age).description # => "a list sorted by age" + # + # ## Custom Matchers + # + # When you find that none of the stock matchers provide a natural feeling + # expectation, you can very easily write your own using RSpec's matcher DSL + # or writing one from scratch. + # + # ### Matcher DSL + # + # Imagine that you are writing a game in which players can be in various + # zones on a virtual board. To specify that bob should be in zone 4, you + # could say: + # + # expect(bob.current_zone).to eql(Zone.new("4")) + # + # But you might find it more expressive to say: + # + # expect(bob).to be_in_zone("4") + # + # and/or + # + # expect(bob).not_to be_in_zone("3") + # + # You can create such a matcher like so: + # + # RSpec::Matchers.define :be_in_zone do |zone| + # match do |player| + # player.in_zone?(zone) + # end + # end + # + # This will generate a be_in_zone method that returns a matcher + # with logical default messages for failures. You can override the failure + # messages and the generated description as follows: + # + # RSpec::Matchers.define :be_in_zone do |zone| + # match do |player| + # player.in_zone?(zone) + # end + # + # failure_message do |player| + # # generate and return the appropriate string. + # end + # + # failure_message_when_negated do |player| + # # generate and return the appropriate string. + # end + # + # description do + # # generate and return the appropriate string. + # end + # end + # + # Each of the message-generation methods has access to the block arguments + # passed to the create method (in this case, zone). The + # failure message methods (failure_message and + # failure_message_when_negated) are passed the actual value (the + # receiver of expect(..) or expect(..).not_to). + # + # ### Custom Matcher from scratch + # + # You could also write a custom matcher from scratch, as follows: + # + # class BeInZone + # def initialize(expected) + # @expected = expected + # end + # + # def matches?(target) + # @target = target + # @target.current_zone.eql?(Zone.new(@expected)) + # end + # + # def failure_message + # "expected #{@target.inspect} to be in Zone #{@expected}" + # end + # + # def failure_message_when_negated + # "expected #{@target.inspect} not to be in Zone #{@expected}" + # end + # end + # + # ... and a method like this: + # + # def be_in_zone(expected) + # BeInZone.new(expected) + # end + # + # And then expose the method to your specs. This is normally done + # by including the method and the class in a module, which is then + # included in your spec: + # + # module CustomGameMatchers + # class BeInZone + # # ... + # end + # + # def be_in_zone(expected) + # # ... + # end + # end + # + # describe "Player behaviour" do + # include CustomGameMatchers + # # ... + # end + # + # or you can include in globally in a spec_helper.rb file required + # from your spec file(s): + # + # RSpec::configure do |config| + # config.include(CustomGameMatchers) + # end + # + # ### Making custom matchers composable + # + # RSpec's built-in matchers are designed to be composed, in expressions like: + # + # expect(["barn", 2.45]).to contain_exactly( + # a_value_within(0.1).of(2.5), + # a_string_starting_with("bar") + # ) + # + # Custom matchers can easily participate in composed matcher expressions like these. + # Include {RSpec::Matchers::Composable} in your custom matcher to make it support + # being composed (matchers defined using the DSL have this included automatically). + # Within your matcher's `matches?` method (or the `match` block, if using the DSL), + # use `values_match?(expected, actual)` rather than `expected == actual`. + # Under the covers, `values_match?` is able to match arbitrary + # nested data structures containing a mix of both matchers and non-matcher objects. + # It uses `===` and `==` to perform the matching, considering the values to + # match if either returns `true`. The `Composable` mixin also provides some helper + # methods for surfacing the matcher descriptions within your matcher's description + # or failure messages. + # + # RSpec's built-in matchers each have a number of aliases that rephrase the matcher + # from a verb phrase (such as `be_within`) to a noun phrase (such as `a_value_within`), + # which reads better when the matcher is passed as an argument in a composed matcher + # expressions, and also uses the noun-phrase wording in the matcher's `description`, + # for readable failure messages. You can alias your custom matchers in similar fashion + # using {RSpec::Matchers.alias_matcher}. + # + # ## Negated Matchers + # + # Sometimes if you want to test for the opposite using a more descriptive name + # instead of using `not_to`, you can use {RSpec::Matchers.define_negated_matcher}: + # + # RSpec::Matchers.define_negated_matcher :exclude, :include + # include(1, 2).description # => "include 1 and 2" + # exclude(1, 2).description # => "exclude 1 and 2" + # + # While the most obvious negated form may be to add a `not_` prefix, + # the failure messages you get with that form can be confusing (e.g. + # "expected [actual] to not [verb], but did not"). We've found it works + # best to find a more positive name for the negated form, such as + # `avoid_changing` rather than `not_change`. + # + module Matchers # rubocop:disable Metrics/ModuleLength + extend ::RSpec::Matchers::DSL + + # @!macro [attach] alias_matcher + # @!parse + # alias $1 $2 + # @!visibility private + # We define this override here so we can attach a YARD macro to it. + # It ensures that our docs list all the matcher aliases. + def self.alias_matcher(*args, &block) + super(*args, &block) + end + + # @!method self.alias_matcher(new_name, old_name, options={}, &description_override) + # Extended from {RSpec::Matchers::DSL#alias_matcher}. + + # @!method self.define(name, &declarations) + # Extended from {RSpec::Matchers::DSL#define}. + + # @!method self.define_negated_matcher(negated_name, base_name, &description_override) + # Extended from {RSpec::Matchers::DSL#define_negated_matcher}. + + # @method expect + # Supports `expect(actual).to matcher` syntax by wrapping `actual` in an + # `ExpectationTarget`. + # @example + # expect(actual).to eq(expected) + # expect(actual).not_to eq(expected) + # @return [Expectations::ExpectationTarget] + # @see Expectations::ExpectationTarget#to + # @see Expectations::ExpectationTarget#not_to + + # Allows multiple expectations in the provided block to fail, and then + # aggregates them into a single exception, rather than aborting on the + # first expectation failure like normal. This allows you to see all + # failures from an entire set of expectations without splitting each + # off into its own example (which may slow things down if the example + # setup is expensive). + # + # @param label [String] label for this aggregation block, which will be + # included in the aggregated exception message. + # @param metadata [Hash] additional metadata about this failure aggregation + # block. If multiple expectations fail, it will be exposed from the + # {Expectations::MultipleExpectationsNotMetError} exception. Mostly + # intended for internal RSpec use but you can use it as well. + # @yield Block containing as many expectation as you want. The block is + # simply yielded to, so you can trust that anything that works outside + # the block should work within it. + # @raise [Expectations::MultipleExpectationsNotMetError] raised when + # multiple expectations fail. + # @raise [Expectations::ExpectationNotMetError] raised when a single + # expectation fails. + # @raise [Exception] other sorts of exceptions will be raised as normal. + # + # @example + # aggregate_failures("verifying response") do + # expect(response.status).to eq(200) + # expect(response.headers).to include("Content-Type" => "text/plain") + # expect(response.body).to include("Success") + # end + # + # @note The implementation of this feature uses a thread-local variable, + # which means that if you have an expectation failure in another thread, + # it'll abort like normal. + def aggregate_failures(label=nil, metadata={}, &block) + Expectations::FailureAggregator.new(label, metadata).aggregate(&block) + end + + # Passes if actual is truthy (anything but false or nil) + def be_truthy + BuiltIn::BeTruthy.new + end + alias_matcher :a_truthy_value, :be_truthy + + # Passes if actual is falsey (false or nil) + def be_falsey + BuiltIn::BeFalsey.new + end + alias_matcher :be_falsy, :be_falsey + alias_matcher :a_falsey_value, :be_falsey + alias_matcher :a_falsy_value, :be_falsey + + # Passes if actual is nil + def be_nil + BuiltIn::BeNil.new + end + alias_matcher :a_nil_value, :be_nil + + # @example + # expect(actual).to be_truthy + # expect(actual).to be_falsey + # expect(actual).to be_nil + # expect(actual).to be_[arbitrary_predicate](*args) + # expect(actual).not_to be_nil + # expect(actual).not_to be_[arbitrary_predicate](*args) + # + # Given true, false, or nil, will pass if actual value is true, false or + # nil (respectively). Given no args means the caller should satisfy an if + # condition (to be or not to be). + # + # Predicates are any Ruby method that ends in a "?" and returns true or + # false. Given be_ followed by arbitrary_predicate (without the "?"), + # RSpec will match convert that into a query against the target object. + # + # The arbitrary_predicate feature will handle any predicate prefixed with + # "be_an_" (e.g. be_an_instance_of), "be_a_" (e.g. be_a_kind_of) or "be_" + # (e.g. be_empty), letting you choose the prefix that best suits the + # predicate. + def be(*args) + args.empty? ? Matchers::BuiltIn::Be.new : equal(*args) + end + alias_matcher :a_value, :be, :klass => AliasedMatcherWithOperatorSupport + + # passes if target.kind_of?(klass) + def be_a(klass) + be_a_kind_of(klass) + end + alias_method :be_an, :be_a + + # Passes if actual.instance_of?(expected) + # + # @example + # expect(5).to be_an_instance_of(Integer) + # expect(5).not_to be_an_instance_of(Numeric) + # expect(5).not_to be_an_instance_of(Float) + def be_an_instance_of(expected) + BuiltIn::BeAnInstanceOf.new(expected) + end + alias_method :be_instance_of, :be_an_instance_of + alias_matcher :an_instance_of, :be_an_instance_of + + # Passes if actual.kind_of?(expected) + # + # @example + # expect(5).to be_a_kind_of(Integer) + # expect(5).to be_a_kind_of(Numeric) + # expect(5).not_to be_a_kind_of(Float) + def be_a_kind_of(expected) + BuiltIn::BeAKindOf.new(expected) + end + alias_method :be_kind_of, :be_a_kind_of + alias_matcher :a_kind_of, :be_a_kind_of + + # Passes if actual.between?(min, max). Works with any Comparable object, + # including String, Symbol, Time, or Numeric (Fixnum, Bignum, Integer, + # Float, Complex, and Rational). + # + # By default, `be_between` is inclusive (i.e. passes when given either the max or min value), + # but you can make it `exclusive` by chaining that off the matcher. + # + # @example + # expect(5).to be_between(1, 10) + # expect(11).not_to be_between(1, 10) + # expect(10).not_to be_between(1, 10).exclusive + def be_between(min, max) + BuiltIn::BeBetween.new(min, max) + end + alias_matcher :a_value_between, :be_between + + # Passes if actual == expected +/- delta + # + # @example + # expect(result).to be_within(0.5).of(3.0) + # expect(result).not_to be_within(0.5).of(3.0) + def be_within(delta) + BuiltIn::BeWithin.new(delta) + end + alias_matcher :a_value_within, :be_within + alias_matcher :within, :be_within + + # Applied to a proc, specifies that its execution will cause some value to + # change. + # + # @param [Object] receiver + # @param [Symbol] message the message to send the receiver + # + # You can either pass receiver and message, or a block, + # but not both. + # + # When passing a block, it must use the `{ ... }` format, not + # do/end, as `{ ... }` binds to the `change` method, whereas do/end + # would errantly bind to the `expect(..).to` or `expect(...).not_to` method. + # + # You can chain any of the following off of the end to specify details + # about the change: + # + # * `from` + # * `to` + # + # or any one of: + # + # * `by` + # * `by_at_least` + # * `by_at_most` + # + # @example + # expect { + # team.add_player(player) + # }.to change(roster, :count) + # + # expect { + # team.add_player(player) + # }.to change(roster, :count).by(1) + # + # expect { + # team.add_player(player) + # }.to change(roster, :count).by_at_least(1) + # + # expect { + # team.add_player(player) + # }.to change(roster, :count).by_at_most(1) + # + # string = "string" + # expect { + # string.reverse! + # }.to change { string }.from("string").to("gnirts") + # + # string = "string" + # expect { + # string + # }.not_to change { string }.from("string") + # + # expect { + # person.happy_birthday + # }.to change(person, :birthday).from(32).to(33) + # + # expect { + # employee.develop_great_new_social_networking_app + # }.to change(employee, :title).from("Mail Clerk").to("CEO") + # + # expect { + # doctor.leave_office + # }.to change(doctor, :sign).from(/is in/).to(/is out/) + # + # user = User.new(:type => "admin") + # expect { + # user.symbolize_type + # }.to change(user, :type).from(String).to(Symbol) + # + # == Notes + # + # Evaluates `receiver.message` or `block` before and after it + # evaluates the block passed to `expect`. If the value is the same + # object, its before/after `hash` value is used to see if it has changed. + # Therefore, your object needs to properly implement `hash` to work correctly + # with this matcher. + # + # `expect( ... ).not_to change` supports the form that specifies `from` + # (which specifies what you expect the starting, unchanged value to be) + # but does not support forms with subsequent calls to `by`, `by_at_least`, + # `by_at_most` or `to`. + def change(receiver=nil, message=nil, &block) + BuiltIn::Change.new(receiver, message, &block) + end + alias_matcher :a_block_changing, :change + alias_matcher :changing, :change + + # Passes if actual contains all of the expected regardless of order. + # This works for collections. Pass in multiple args and it will only + # pass if all args are found in collection. + # + # @note This is also available using the `=~` operator with `should`, + # but `=~` is not supported with `expect`. + # + # @example + # expect([1, 2, 3]).to contain_exactly(1, 2, 3) + # expect([1, 2, 3]).to contain_exactly(1, 3, 2) + # + # @see #match_array + def contain_exactly(*items) + BuiltIn::ContainExactly.new(items) + end + alias_matcher :a_collection_containing_exactly, :contain_exactly + alias_matcher :containing_exactly, :contain_exactly + + # Passes if actual covers expected. This works for + # Ranges. You can also pass in multiple args + # and it will only pass if all args are found in Range. + # + # @example + # expect(1..10).to cover(5) + # expect(1..10).to cover(4, 6) + # expect(1..10).to cover(4, 6, 11) # fails + # expect(1..10).not_to cover(11) + # expect(1..10).not_to cover(5) # fails + # + # ### Warning:: Ruby >= 1.9 only + def cover(*values) + BuiltIn::Cover.new(*values) + end + alias_matcher :a_range_covering, :cover + alias_matcher :covering, :cover + + # Matches if the actual value ends with the expected value(s). In the case + # of a string, matches against the last `expected.length` characters of the + # actual string. In the case of an array, matches against the last + # `expected.length` elements of the actual array. + # + # @example + # expect("this string").to end_with "string" + # expect([0, 1, 2, 3, 4]).to end_with 4 + # expect([0, 2, 3, 4, 4]).to end_with 3, 4 + def end_with(*expected) + BuiltIn::EndWith.new(*expected) + end + alias_matcher :a_collection_ending_with, :end_with + alias_matcher :a_string_ending_with, :end_with + alias_matcher :ending_with, :end_with + + # Passes if actual == expected. + # + # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more + # information about equality in Ruby. + # + # @example + # expect(5).to eq(5) + # expect(5).not_to eq(3) + def eq(expected) + BuiltIn::Eq.new(expected) + end + alias_matcher :an_object_eq_to, :eq + alias_matcher :eq_to, :eq + + # Passes if `actual.eql?(expected)` + # + # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more + # information about equality in Ruby. + # + # @example + # expect(5).to eql(5) + # expect(5).not_to eql(3) + def eql(expected) + BuiltIn::Eql.new(expected) + end + alias_matcher :an_object_eql_to, :eql + alias_matcher :eql_to, :eql + + # Passes if actual.equal?(expected) (object identity). + # + # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more + # information about equality in Ruby. + # + # @example + # expect(5).to equal(5) # Integers are equal + # expect("5").not_to equal("5") # Strings that look the same are not the same object + def equal(expected) + BuiltIn::Equal.new(expected) + end + alias_matcher :an_object_equal_to, :equal + alias_matcher :equal_to, :equal + + # Passes if `actual.exist?` or `actual.exists?` + # + # @example + # expect(File).to exist("path/to/file") + def exist(*args) + BuiltIn::Exist.new(*args) + end + alias_matcher :an_object_existing, :exist + alias_matcher :existing, :exist + + # Passes if actual's attribute values match the expected attributes hash. + # This works no matter how you define your attribute readers. + # + # @example + # Person = Struct.new(:name, :age) + # person = Person.new("Bob", 32) + # + # expect(person).to have_attributes(:name => "Bob", :age => 32) + # expect(person).to have_attributes(:name => a_string_starting_with("B"), :age => (a_value > 30) ) + # + # @note It will fail if actual doesn't respond to any of the expected attributes. + # + # @example + # expect(person).to have_attributes(:color => "red") + def have_attributes(expected) + BuiltIn::HaveAttributes.new(expected) + end + alias_matcher :an_object_having_attributes, :have_attributes + alias_matcher :having_attributes, :have_attributes + + # Passes if actual includes expected. This works for + # collections and Strings. You can also pass in multiple args + # and it will only pass if all args are found in collection. + # + # @example + # expect([1,2,3]).to include(3) + # expect([1,2,3]).to include(2,3) + # expect([1,2,3]).to include(2,3,4) # fails + # expect([1,2,3]).not_to include(4) + # expect("spread").to include("read") + # expect("spread").not_to include("red") + # expect(:a => 1, :b => 2).to include(:a) + # expect(:a => 1, :b => 2).to include(:a, :b) + # expect(:a => 1, :b => 2).to include(:a => 1) + # expect(:a => 1, :b => 2).to include(:b => 2, :a => 1) + # expect(:a => 1, :b => 2).to include(:c) # fails + # expect(:a => 1, :b => 2).not_to include(:a => 2) + def include(*expected) + BuiltIn::Include.new(*expected) + end + alias_matcher :a_collection_including, :include + alias_matcher :a_string_including, :include + alias_matcher :a_hash_including, :include + alias_matcher :including, :include + + # Passes if the provided matcher passes when checked against all + # elements of the collection. + # + # @example + # expect([1, 3, 5]).to all be_odd + # expect([1, 3, 6]).to all be_odd # fails + # + # @note The negative form `not_to all` is not supported. Instead + # use `not_to include` or pass a negative form of a matcher + # as the argument (e.g. `all exclude(:foo)`). + # + # @note You can also use this with compound matchers as well. + # + # @example + # expect([1, 3, 5]).to all( be_odd.and be_an(Integer) ) + def all(expected) + BuiltIn::All.new(expected) + end + + # Given a `Regexp` or `String`, passes if `actual.match(pattern)` + # Given an arbitrary nested data structure (e.g. arrays and hashes), + # matches if `expected === actual` || `actual == expected` for each + # pair of elements. + # + # @example + # expect(email).to match(/^([^\s]+)((?:[-a-z0-9]+\.)+[a-z]{2,})$/i) + # expect(email).to match("@example.com") + # + # @example + # hash = { + # :a => { + # :b => ["foo", 5], + # :c => { :d => 2.05 } + # } + # } + # + # expect(hash).to match( + # :a => { + # :b => a_collection_containing_exactly( + # a_string_starting_with("f"), + # an_instance_of(Integer) + # ), + # :c => { :d => (a_value < 3) } + # } + # ) + # + # @note The `match_regex` alias is deprecated and is not recommended for use. + # It was added in 2.12.1 to facilitate its use from within custom + # matchers (due to how the custom matcher DSL was evaluated in 2.x, + # `match` could not be used there), but is no longer needed in 3.x. + def match(expected) + BuiltIn::Match.new(expected) + end + alias_matcher :match_regex, :match + alias_matcher :an_object_matching, :match + alias_matcher :a_string_matching, :match + alias_matcher :matching, :match + + # An alternate form of `contain_exactly` that accepts + # the expected contents as a single array arg rather + # than splatted out as individual items. + # + # @example + # expect(results).to contain_exactly(1, 2) + # # is identical to: + # expect(results).to match_array([1, 2]) + # + # @see #contain_exactly + def match_array(items) + contain_exactly(*items) + end + alias_matcher :an_array_matching, :match_array do |desc| + desc.sub("contain exactly", "an array containing exactly") + end + + # With no arg, passes if the block outputs `to_stdout` or `to_stderr`. + # With a string, passes if the block outputs that specific string `to_stdout` or `to_stderr`. + # With a regexp or matcher, passes if the block outputs a string `to_stdout` or `to_stderr` that matches. + # + # To capture output from any spawned subprocess as well, use `to_stdout_from_any_process` or + # `to_stderr_from_any_process`. Output from any process that inherits the main process's corresponding + # standard stream will be captured. + # + # @example + # expect { print 'foo' }.to output.to_stdout + # expect { print 'foo' }.to output('foo').to_stdout + # expect { print 'foo' }.to output(/foo/).to_stdout + # + # expect { do_something }.to_not output.to_stdout + # + # expect { warn('foo') }.to output.to_stderr + # expect { warn('foo') }.to output('foo').to_stderr + # expect { warn('foo') }.to output(/foo/).to_stderr + # + # expect { do_something }.to_not output.to_stderr + # + # expect { system('echo foo') }.to output("foo\n").to_stdout_from_any_process + # expect { system('echo foo', out: :err) }.to output("foo\n").to_stderr_from_any_process + # + # @note `to_stdout` and `to_stderr` work by temporarily replacing `$stdout` or `$stderr`, + # so they're not able to intercept stream output that explicitly uses `STDOUT`/`STDERR` + # or that uses a reference to `$stdout`/`$stderr` that was stored before the + # matcher was used. + # @note `to_stdout_from_any_process` and `to_stderr_from_any_process` use Tempfiles, and + # are thus significantly (~30x) slower than `to_stdout` and `to_stderr`. + def output(expected=nil) + BuiltIn::Output.new(expected) + end + alias_matcher :a_block_outputting, :output + + # With no args, matches if any error is raised. + # With a named error, matches only if that specific error is raised. + # With a named error and message specified as a String, matches only if both match. + # With a named error and message specified as a Regexp, matches only if both match. + # Pass an optional block to perform extra verifications on the exception matched + # + # @example + # expect { do_something_risky }.to raise_error + # expect { do_something_risky }.to raise_error(PoorRiskDecisionError) + # expect { do_something_risky }.to raise_error(PoorRiskDecisionError) { |error| expect(error.data).to eq 42 } + # expect { do_something_risky }.to raise_error { |error| expect(error.data).to eq 42 } + # expect { do_something_risky }.to raise_error(PoorRiskDecisionError, "that was too risky") + # expect { do_something_risky }.to raise_error(PoorRiskDecisionError, /oo ri/) + # expect { do_something_risky }.to raise_error("that was too risky") + # + # expect { do_something_risky }.not_to raise_error + def raise_error(error=BuiltIn::RaiseError::UndefinedValue, message=nil, &block) + BuiltIn::RaiseError.new(error, message, &block) + end + alias_method :raise_exception, :raise_error + + alias_matcher :a_block_raising, :raise_error do |desc| + desc.sub("raise", "a block raising") + end + + alias_matcher :raising, :raise_error do |desc| + desc.sub("raise", "raising") + end + + # Matches if the target object responds to all of the names + # provided. Names can be Strings or Symbols. + # + # @example + # expect("string").to respond_to(:length) + # + def respond_to(*names) + BuiltIn::RespondTo.new(*names) + end + alias_matcher :an_object_responding_to, :respond_to + alias_matcher :responding_to, :respond_to + + # Passes if the submitted block returns true. Yields target to the + # block. + # + # Generally speaking, this should be thought of as a last resort when + # you can't find any other way to specify the behaviour you wish to + # specify. + # + # If you do find yourself in such a situation, you could always write + # a custom matcher, which would likely make your specs more expressive. + # + # @param description [String] optional description to be used for this matcher. + # + # @example + # expect(5).to satisfy { |n| n > 3 } + # expect(5).to satisfy("be greater than 3") { |n| n > 3 } + def satisfy(description=nil, &block) + BuiltIn::Satisfy.new(description, &block) + end + alias_matcher :an_object_satisfying, :satisfy + alias_matcher :satisfying, :satisfy + + # Matches if the actual value starts with the expected value(s). In the + # case of a string, matches against the first `expected.length` characters + # of the actual string. In the case of an array, matches against the first + # `expected.length` elements of the actual array. + # + # @example + # expect("this string").to start_with "this s" + # expect([0, 1, 2, 3, 4]).to start_with 0 + # expect([0, 2, 3, 4, 4]).to start_with 0, 1 + def start_with(*expected) + BuiltIn::StartWith.new(*expected) + end + alias_matcher :a_collection_starting_with, :start_with + alias_matcher :a_string_starting_with, :start_with + alias_matcher :starting_with, :start_with + + # Given no argument, matches if a proc throws any Symbol. + # + # Given a Symbol, matches if the given proc throws the specified Symbol. + # + # Given a Symbol and an arg, matches if the given proc throws the + # specified Symbol with the specified arg. + # + # @example + # expect { do_something_risky }.to throw_symbol + # expect { do_something_risky }.to throw_symbol(:that_was_risky) + # expect { do_something_risky }.to throw_symbol(:that_was_risky, 'culprit') + # + # expect { do_something_risky }.not_to throw_symbol + # expect { do_something_risky }.not_to throw_symbol(:that_was_risky) + # expect { do_something_risky }.not_to throw_symbol(:that_was_risky, 'culprit') + def throw_symbol(expected_symbol=nil, expected_arg=nil) + BuiltIn::ThrowSymbol.new(expected_symbol, expected_arg) + end + + alias_matcher :a_block_throwing, :throw_symbol do |desc| + desc.sub("throw", "a block throwing") + end + + alias_matcher :throwing, :throw_symbol do |desc| + desc.sub("throw", "throwing") + end + + # Passes if the method called in the expect block yields, regardless + # of whether or not arguments are yielded. + # + # @example + # expect { |b| 5.tap(&b) }.to yield_control + # expect { |b| "a".to_sym(&b) }.not_to yield_control + # + # @note Your expect block must accept a parameter and pass it on to + # the method-under-test as a block. + def yield_control + BuiltIn::YieldControl.new + end + alias_matcher :a_block_yielding_control, :yield_control + alias_matcher :yielding_control, :yield_control + + # Passes if the method called in the expect block yields with + # no arguments. Fails if it does not yield, or yields with arguments. + # + # @example + # expect { |b| User.transaction(&b) }.to yield_with_no_args + # expect { |b| 5.tap(&b) }.not_to yield_with_no_args # because it yields with `5` + # expect { |b| "a".to_sym(&b) }.not_to yield_with_no_args # because it does not yield + # + # @note Your expect block must accept a parameter and pass it on to + # the method-under-test as a block. + # @note This matcher is not designed for use with methods that yield + # multiple times. + def yield_with_no_args + BuiltIn::YieldWithNoArgs.new + end + alias_matcher :a_block_yielding_with_no_args, :yield_with_no_args + alias_matcher :yielding_with_no_args, :yield_with_no_args + + # Given no arguments, matches if the method called in the expect + # block yields with arguments (regardless of what they are or how + # many there are). + # + # Given arguments, matches if the method called in the expect block + # yields with arguments that match the given arguments. + # + # Argument matching is done using `===` (the case match operator) + # and `==`. If the expected and actual arguments match with either + # operator, the matcher will pass. + # + # @example + # expect { |b| 5.tap(&b) }.to yield_with_args # because #tap yields an arg + # expect { |b| 5.tap(&b) }.to yield_with_args(5) # because 5 == 5 + # expect { |b| 5.tap(&b) }.to yield_with_args(Integer) # because Integer === 5 + # expect { |b| File.open("f.txt", &b) }.to yield_with_args(/txt/) # because /txt/ === "f.txt" + # + # expect { |b| User.transaction(&b) }.not_to yield_with_args # because it yields no args + # expect { |b| 5.tap(&b) }.not_to yield_with_args(1, 2, 3) + # + # @note Your expect block must accept a parameter and pass it on to + # the method-under-test as a block. + # @note This matcher is not designed for use with methods that yield + # multiple times. + def yield_with_args(*args) + BuiltIn::YieldWithArgs.new(*args) + end + alias_matcher :a_block_yielding_with_args, :yield_with_args + alias_matcher :yielding_with_args, :yield_with_args + + # Designed for use with methods that repeatedly yield (such as + # iterators). Passes if the method called in the expect block yields + # multiple times with arguments matching those given. + # + # Argument matching is done using `===` (the case match operator) + # and `==`. If the expected and actual arguments match with either + # operator, the matcher will pass. + # + # @example + # expect { |b| [1, 2, 3].each(&b) }.to yield_successive_args(1, 2, 3) + # expect { |b| { :a => 1, :b => 2 }.each(&b) }.to yield_successive_args([:a, 1], [:b, 2]) + # expect { |b| [1, 2, 3].each(&b) }.not_to yield_successive_args(1, 2) + # + # @note Your expect block must accept a parameter and pass it on to + # the method-under-test as a block. + def yield_successive_args(*args) + BuiltIn::YieldSuccessiveArgs.new(*args) + end + alias_matcher :a_block_yielding_successive_args, :yield_successive_args + alias_matcher :yielding_successive_args, :yield_successive_args + + # Delegates to {RSpec::Expectations.configuration}. + # This is here because rspec-core's `expect_with` option + # looks for a `configuration` method on the mixin + # (`RSpec::Matchers`) to yield to a block. + # @return [RSpec::Expectations::Configuration] the configuration object + def self.configuration + Expectations.configuration + end + + private + + BE_PREDICATE_REGEX = /^(?:be_(?:an?_)?)(.*)/ + HAS_REGEX = /^(?:have_)(.*)/ + DYNAMIC_MATCHER_REGEX = Regexp.union(BE_PREDICATE_REGEX, HAS_REGEX) + + def method_missing(method, *args, &block) + case method.to_s + when BE_PREDICATE_REGEX + BuiltIn::BePredicate.new(method, *args, &block) + when HAS_REGEX + BuiltIn::Has.new(method, *args, &block) + else + super + end + end + ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true) + + if RUBY_VERSION.to_f >= 1.9 + def respond_to_missing?(method, *) + method =~ DYNAMIC_MATCHER_REGEX || super + end + else # for 1.8.7 + # :nocov: + def respond_to?(method, *) + method = method.to_s + method =~ DYNAMIC_MATCHER_REGEX || super + end + public :respond_to? + # :nocov: + end + + # @api private + def self.is_a_matcher?(obj) + return true if ::RSpec::Matchers::BuiltIn::BaseMatcher === obj + begin + return false if obj.respond_to?(:i_respond_to_everything_so_im_not_really_a_matcher) + rescue NoMethodError + # Some objects, like BasicObject, don't implemented standard + # reflection methods. + return false + end + return false unless obj.respond_to?(:matches?) + + obj.respond_to?(:failure_message) || + obj.respond_to?(:failure_message_for_should) # support legacy matchers + end + + ::RSpec::Support.register_matcher_definition do |obj| + is_a_matcher?(obj) + end + + # @api private + def self.is_a_describable_matcher?(obj) + is_a_matcher?(obj) && obj.respond_to?(:description) + end + + class << self + private + + if RSpec::Support::Ruby.mri? && RUBY_VERSION[0, 3] == '1.9' + # Note that `included` doesn't work for this because it is triggered + # _after_ `RSpec::Matchers` is an ancestor of the inclusion host, rather + # than _before_, like `append_features`. It's important we check this before + # in order to find the cases where it was already previously included. + # @api private + # :nocov: + def append_features(mod) + return super if mod < self # `mod < self` indicates a re-inclusion. + + subclasses = ObjectSpace.each_object(Class).select { |c| c < mod && c < self } + return super unless subclasses.any? + + subclasses.reject! { |s| subclasses.any? { |s2| s < s2 } } # Filter to the root ancestor. + subclasses = subclasses.map { |s| "`#{s}`" }.join(", ") + + RSpec.warning "`#{self}` has been included in a superclass (`#{mod}`) " \ + "after previously being included in subclasses (#{subclasses}), " \ + "which can trigger infinite recursion from `super` due to an MRI 1.9 bug " \ + "(https://redmine.ruby-lang.org/issues/3351). To work around this, " \ + "either upgrade to MRI 2.0+, include a dup of the module (e.g. " \ + "`include #{self}.dup`), or find a way to include `#{self}` in `#{mod}` " \ + "before it is included in subclasses (#{subclasses}). See " \ + "https://github.com/rspec/rspec-expectations/issues/814 for more info" + + super + end + # :nocov: + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/aliased_matcher.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/aliased_matcher.rb new file mode 100644 index 00000000..c52c4c4c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/aliased_matcher.rb @@ -0,0 +1,116 @@ +module RSpec + module Matchers + # Decorator that wraps a matcher and overrides `description` + # using the provided block in order to support an alias + # of a matcher. This is intended for use when composing + # matchers, so that you can use an expression like + # `include( a_value_within(0.1).of(3) )` rather than + # `include( be_within(0.1).of(3) )`, and have the corresponding + # description read naturally. + # + # @api private + class AliasedMatcher < MatcherDelegator + def initialize(base_matcher, description_block) + @description_block = description_block + super(base_matcher) + end + + # Forward messages on to the wrapped matcher. + # Since many matchers provide a fluent interface + # (e.g. `a_value_within(0.1).of(3)`), we need to wrap + # the returned value if it responds to `description`, + # so that our override can be applied when it is eventually + # used. + def method_missing(*) + return_val = super + return return_val unless RSpec::Matchers.is_a_matcher?(return_val) + self.class.new(return_val, @description_block) + end + + # Provides the description of the aliased matcher. Aliased matchers + # are designed to behave identically to the original matcher except + # for the description and failure messages. The description is different + # to reflect the aliased name. + # + # @api private + def description + @description_block.call(super) + end + + # Provides the failure_message of the aliased matcher. Aliased matchers + # are designed to behave identically to the original matcher except + # for the description and failure messages. The failure_message is different + # to reflect the aliased name. + # + # @api private + def failure_message + @description_block.call(super) + end + + # Provides the failure_message_when_negated of the aliased matcher. Aliased matchers + # are designed to behave identically to the original matcher except + # for the description and failure messages. The failure_message_when_negated is different + # to reflect the aliased name. + # + # @api private + def failure_message_when_negated + @description_block.call(super) + end + end + + # Decorator used for matchers that have special implementations of + # operators like `==` and `===`. + # @private + class AliasedMatcherWithOperatorSupport < AliasedMatcher + # We undef these so that they get delegated via `method_missing`. + undef == + undef === + end + + # @private + class AliasedNegatedMatcher < AliasedMatcher + def matches?(*args, &block) + if @base_matcher.respond_to?(:does_not_match?) + @base_matcher.does_not_match?(*args, &block) + else + !super + end + end + + def does_not_match?(*args, &block) + @base_matcher.matches?(*args, &block) + end + + def failure_message + optimal_failure_message(__method__, :failure_message_when_negated) + end + + def failure_message_when_negated + optimal_failure_message(__method__, :failure_message) + end + + private + + DefaultFailureMessages = BuiltIn::BaseMatcher::DefaultFailureMessages + + # For a matcher that uses the default failure messages, we prefer to + # use the override provided by the `description_block`, because it + # includes the phrasing that the user has expressed a preference for + # by going through the effort of defining a negated matcher. + # + # However, if the override didn't actually change anything, then we + # should return the opposite failure message instead -- the overridden + # message is going to be confusing if we return it as-is, as it represents + # the non-negated failure message for a negated match (or vice versa). + def optimal_failure_message(same, inverted) + if DefaultFailureMessages.has_default_failure_messages?(@base_matcher) + base_message = @base_matcher.__send__(same) + overridden = @description_block.call(base_message) + return overridden if overridden != base_message + end + + @base_matcher.__send__(inverted) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in.rb new file mode 100644 index 00000000..e6237ff0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in.rb @@ -0,0 +1,53 @@ +RSpec::Support.require_rspec_matchers "built_in/base_matcher" + +module RSpec + module Matchers + # Container module for all built-in matchers. The matcher classes are here + # (rather than directly under `RSpec::Matchers`) in order to prevent name + # collisions, since `RSpec::Matchers` gets included into the user's namespace. + # + # Autoloading is used to delay when the matcher classes get loaded, allowing + # rspec-matchers to boot faster, and avoiding loading matchers the user is + # not using. + module BuiltIn + autoload :BeAKindOf, 'rspec/matchers/built_in/be_kind_of' + autoload :BeAnInstanceOf, 'rspec/matchers/built_in/be_instance_of' + autoload :BeBetween, 'rspec/matchers/built_in/be_between' + autoload :Be, 'rspec/matchers/built_in/be' + autoload :BeComparedTo, 'rspec/matchers/built_in/be' + autoload :BeFalsey, 'rspec/matchers/built_in/be' + autoload :BeHelpers, 'rspec/matchers/built_in/be' + autoload :BeNil, 'rspec/matchers/built_in/be' + autoload :BePredicate, 'rspec/matchers/built_in/has' + autoload :BeTruthy, 'rspec/matchers/built_in/be' + autoload :BeWithin, 'rspec/matchers/built_in/be_within' + autoload :Change, 'rspec/matchers/built_in/change' + autoload :Compound, 'rspec/matchers/built_in/compound' + autoload :ContainExactly, 'rspec/matchers/built_in/contain_exactly' + autoload :Cover, 'rspec/matchers/built_in/cover' + autoload :EndWith, 'rspec/matchers/built_in/start_or_end_with' + autoload :Eq, 'rspec/matchers/built_in/eq' + autoload :Eql, 'rspec/matchers/built_in/eql' + autoload :Equal, 'rspec/matchers/built_in/equal' + autoload :Exist, 'rspec/matchers/built_in/exist' + autoload :Has, 'rspec/matchers/built_in/has' + autoload :HaveAttributes, 'rspec/matchers/built_in/have_attributes' + autoload :Include, 'rspec/matchers/built_in/include' + autoload :All, 'rspec/matchers/built_in/all' + autoload :Match, 'rspec/matchers/built_in/match' + autoload :NegativeOperatorMatcher, 'rspec/matchers/built_in/operators' + autoload :OperatorMatcher, 'rspec/matchers/built_in/operators' + autoload :Output, 'rspec/matchers/built_in/output' + autoload :PositiveOperatorMatcher, 'rspec/matchers/built_in/operators' + autoload :RaiseError, 'rspec/matchers/built_in/raise_error' + autoload :RespondTo, 'rspec/matchers/built_in/respond_to' + autoload :Satisfy, 'rspec/matchers/built_in/satisfy' + autoload :StartWith, 'rspec/matchers/built_in/start_or_end_with' + autoload :ThrowSymbol, 'rspec/matchers/built_in/throw_symbol' + autoload :YieldControl, 'rspec/matchers/built_in/yield' + autoload :YieldSuccessiveArgs, 'rspec/matchers/built_in/yield' + autoload :YieldWithArgs, 'rspec/matchers/built_in/yield' + autoload :YieldWithNoArgs, 'rspec/matchers/built_in/yield' + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/all.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/all.rb new file mode 100644 index 00000000..27cce20d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/all.rb @@ -0,0 +1,86 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `all`. + # Not intended to be instantiated directly. + class All < BaseMatcher + # @private + attr_reader :matcher, :failed_objects + + def initialize(matcher) + @matcher = matcher + @failed_objects = {} + end + + # @private + def does_not_match?(_actual) + raise NotImplementedError, '`expect().not_to all( matcher )` is not supported.' + end + + # @api private + # @return [String] + def failure_message + unless iterable? + return "#{improve_hash_formatting(super)}, but was not iterable" + end + + all_messages = [improve_hash_formatting(super)] + failed_objects.each do |index, matcher_failure_message| + all_messages << failure_message_for_item(index, matcher_failure_message) + end + all_messages.join("\n\n") + end + + # @api private + # @return [String] + def description + improve_hash_formatting "all #{description_of matcher}" + end + + private + + def match(_expected, _actual) + return false unless iterable? + + index_failed_objects + failed_objects.empty? + end + + def index_failed_objects + actual.each_with_index do |actual_item, index| + cloned_matcher = matcher.clone + matches = cloned_matcher.matches?(actual_item) + failed_objects[index] = cloned_matcher.failure_message unless matches + end + end + + def failure_message_for_item(index, failure_message) + failure_message = indent_multiline_message(add_new_line_if_needed(failure_message)) + indent_multiline_message("object at index #{index} failed to match:#{failure_message}") + end + + def add_new_line_if_needed(message) + message.start_with?("\n") ? message : "\n#{message}" + end + + def indent_multiline_message(message) + message = message.sub(/\n+\z/, '') + message.lines.map do |line| + line =~ /\S/ ? ' ' + line : line + end.join + end + + def initialize_copy(other) + @matcher = @matcher.clone + @failed_objects = @failed_objects.clone + super + end + + def iterable? + @actual.respond_to?(:each_with_index) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/base_matcher.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/base_matcher.rb new file mode 100644 index 00000000..8dd5133d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/base_matcher.rb @@ -0,0 +1,225 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # + # Used _internally_ as a base class for matchers that ship with + # rspec-expectations and rspec-rails. + # + # ### Warning: + # + # This class is for internal use, and subject to change without notice. + # We strongly recommend that you do not base your custom matchers on this + # class. If/when this changes, we will announce it and remove this warning. + class BaseMatcher + include RSpec::Matchers::Composable + + # @api private + # Used to detect when no arg is passed to `initialize`. + # `nil` cannot be used because it's a valid value to pass. + UNDEFINED = Object.new.freeze + + # @private + attr_reader :actual, :expected, :rescued_exception + + # @private + attr_writer :matcher_name + + def initialize(expected=UNDEFINED) + @expected = expected unless UNDEFINED.equal?(expected) + end + + # @api private + # Indicates if the match is successful. Delegates to `match`, which + # should be defined on a subclass. Takes care of consistently + # initializing the `actual` attribute. + def matches?(actual) + @actual = actual + match(expected, actual) + end + + # @api private + # Used to wrap a block of code that will indicate failure by + # raising one of the named exceptions. + # + # This is used by rspec-rails for some of its matchers that + # wrap rails' assertions. + def match_unless_raises(*exceptions) + exceptions.unshift Exception if exceptions.empty? + begin + yield + true + rescue *exceptions => @rescued_exception + false + end + end + + # @api private + # Generates a description using {EnglishPhrasing}. + # @return [String] + def description + desc = EnglishPhrasing.split_words(self.class.matcher_name) + desc << EnglishPhrasing.list(@expected) if defined?(@expected) + desc + end + + # @api private + # Matchers are not diffable by default. Override this to make your + # subclass diffable. + def diffable? + false + end + + # @api private + # Most matchers are value matchers (i.e. meant to work with `expect(value)`) + # rather than block matchers (i.e. meant to work with `expect { }`), so + # this defaults to false. Block matchers must override this to return true. + def supports_block_expectations? + false + end + + # @private + def supports_value_expectations? + true + end + + # @api private + def expects_call_stack_jump? + false + end + + # @private + def expected_formatted + RSpec::Support::ObjectFormatter.format(@expected) + end + + # @private + def actual_formatted + RSpec::Support::ObjectFormatter.format(@actual) + end + + # @private + def self.matcher_name + @matcher_name ||= underscore(name.split('::').last) + end + + # @private + def matcher_name + if defined?(@matcher_name) + @matcher_name + else + self.class.matcher_name + end + end + + # @private + # Borrowed from ActiveSupport. + def self.underscore(camel_cased_word) + word = camel_cased_word.to_s.dup + 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 + private_class_method :underscore + + # @private + module HashFormatting + # `{ :a => 5, :b => 2 }.inspect` produces: + # + # {:a=>5, :b=>2} + # + # ...but it looks much better as: + # + # {:a => 5, :b => 2} + # + # This is idempotent and safe to run on a string multiple times. + def improve_hash_formatting(inspect_string) + inspect_string.gsub(/(\S)=>(\S)/, '\1 => \2') + end + module_function :improve_hash_formatting + end + + include HashFormatting + + # @private + module StringEncodingFormatting + # @api private + # @return [Boolean] True if the actual and expected string encoding are different. + # i.e. the failure may be related to encoding differences and the encoding + # should be shown to the user. false otherwise. + if String.method_defined?(:encoding) + def string_encoding_differs? + actual.is_a?(String) && expected.is_a?(String) && actual.encoding != expected.encoding + end + else + # @api private + # @return [Boolean] False always as the curent Ruby version does not support String encoding + # :nocov: + def string_encoding_differs? + false + end + # :nocov: + end + module_function :string_encoding_differs? + + if String.method_defined?(:encoding) + # @api private + # Formats a String's encoding as a human readable string + # @param value [String] + # @return [String] + def format_encoding(value) + "#" + end + else + # @api private + # Formats a String's encoding as a human readable string + # @param _value [String] + # @return [nil] nil as the curent Ruby version does not support String encoding + # :nocov: + def format_encoding(_value) + nil + end + # :nocov: + end + module_function :format_encoding + end + + include StringEncodingFormatting + + # @api private + # Provides default implementations of failure messages, based on the `description`. + module DefaultFailureMessages + # @api private + # Provides a good generic failure message. Based on `description`. + # When subclassing, if you are not satisfied with this failure message + # you often only need to override `description`. + # @return [String] + def failure_message + "expected #{description_of @actual} to #{description}".dup + end + + # @api private + # Provides a good generic negative failure message. Based on `description`. + # When subclassing, if you are not satisfied with this failure message + # you often only need to override `description`. + # @return [String] + def failure_message_when_negated + "expected #{description_of @actual} not to #{description}".dup + end + + # @private + def self.has_default_failure_messages?(matcher) + matcher.method(:failure_message).owner == self && + matcher.method(:failure_message_when_negated).owner == self + rescue NameError + false + end + end + + include DefaultFailureMessages + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be.rb new file mode 100644 index 00000000..40d40171 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be.rb @@ -0,0 +1,191 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `be_truthy`. + # Not intended to be instantiated directly. + class BeTruthy < BaseMatcher + # @api private + # @return [String] + def failure_message + "expected: truthy value\n got: #{actual_formatted}" + end + + # @api private + # @return [String] + def failure_message_when_negated + "expected: falsey value\n got: #{actual_formatted}" + end + + private + + def match(_, actual) + !!actual + end + end + + # @api private + # Provides the implementation for `be_falsey`. + # Not intended to be instantiated directly. + class BeFalsey < BaseMatcher + # @api private + # @return [String] + def failure_message + "expected: falsey value\n got: #{actual_formatted}" + end + + # @api private + # @return [String] + def failure_message_when_negated + "expected: truthy value\n got: #{actual_formatted}" + end + + private + + def match(_, actual) + !actual + end + end + + # @api private + # Provides the implementation for `be_nil`. + # Not intended to be instantiated directly. + class BeNil < BaseMatcher + # @api private + # @return [String] + def failure_message + "expected: nil\n got: #{actual_formatted}" + end + + # @api private + # @return [String] + def failure_message_when_negated + "expected: not nil\n got: nil" + end + + private + + def match(_, actual) + actual.nil? + end + end + + # @private + module BeHelpers + private + + def args_to_s + @args.empty? ? "" : parenthesize(inspected_args.join(', ')) + end + + def parenthesize(string) + "(#{string})" + end + + def inspected_args + @args.map { |a| RSpec::Support::ObjectFormatter.format(a) } + end + + def expected_to_sentence + EnglishPhrasing.split_words(@expected) + end + + def args_to_sentence + EnglishPhrasing.list(@args) + end + end + + # @api private + # Provides the implementation for `be`. + # Not intended to be instantiated directly. + class Be < BaseMatcher + include BeHelpers + + def initialize(*args) + @args = args + end + + # @api private + # @return [String] + def failure_message + "expected #{actual_formatted} to evaluate to true" + end + + # @api private + # @return [String] + def failure_message_when_negated + "expected #{actual_formatted} to evaluate to false" + end + + [:==, :<, :<=, :>=, :>, :===, :=~].each do |operator| + define_method operator do |operand| + BeComparedTo.new(operand, operator) + end + end + + private + + def match(_, actual) + !!actual + end + end + + # @api private + # Provides the implementation of `be value`. + # Not intended to be instantiated directly. + class BeComparedTo < BaseMatcher + include BeHelpers + + def initialize(operand, operator) + @expected = operand + @operator = operator + @args = [] + end + + def matches?(actual) + perform_match(actual) + rescue ArgumentError, NoMethodError + false + end + + def does_not_match?(actual) + !perform_match(actual) + rescue ArgumentError, NoMethodError + false + end + + # @api private + # @return [String] + def failure_message + "expected: #{@operator} #{expected_formatted}\n" \ + " got: #{@operator.to_s.gsub(/./, ' ')} #{actual_formatted}" + end + + # @api private + # @return [String] + def failure_message_when_negated + message = "`expect(#{actual_formatted}).not_to " \ + "be #{@operator} #{expected_formatted}`" + if [:<, :>, :<=, :>=].include?(@operator) + message + " not only FAILED, it is a bit confusing." + else + message + end + end + + # @api private + # @return [String] + def description + "be #{@operator} #{expected_to_sentence}#{args_to_sentence}" + end + + private + + def perform_match(actual) + @actual = actual + @actual.__send__ @operator, @expected + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_between.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_between.rb new file mode 100644 index 00000000..55f084e4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_between.rb @@ -0,0 +1,77 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `be_between`. + # Not intended to be instantiated directly. + class BeBetween < BaseMatcher + def initialize(min, max) + @min, @max = min, max + inclusive + end + + # @api public + # Makes the between comparison inclusive. + # + # @example + # expect(3).to be_between(2, 3).inclusive + # + # @note The matcher is inclusive by default; this simply provides + # a way to be more explicit about it. + def inclusive + @less_than_operator = :<= + @greater_than_operator = :>= + @mode = :inclusive + self + end + + # @api public + # Makes the between comparison exclusive. + # + # @example + # expect(3).to be_between(2, 4).exclusive + def exclusive + @less_than_operator = :< + @greater_than_operator = :> + @mode = :exclusive + self + end + + # @api private + # @return [Boolean] + def matches?(actual) + @actual = actual + comparable? && compare + rescue ArgumentError + false + end + + # @api private + # @return [String] + def failure_message + "#{super}#{not_comparable_clause}" + end + + # @api private + # @return [String] + def description + "be between #{description_of @min} and #{description_of @max} (#{@mode})" + end + + private + + def comparable? + @actual.respond_to?(@less_than_operator) && @actual.respond_to?(@greater_than_operator) + end + + def not_comparable_clause + ", but it does not respond to `#{@less_than_operator}` and `#{@greater_than_operator}`" unless comparable? + end + + def compare + @actual.__send__(@greater_than_operator, @min) && @actual.__send__(@less_than_operator, @max) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_instance_of.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_instance_of.rb new file mode 100644 index 00000000..e71d380a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_instance_of.rb @@ -0,0 +1,26 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `be_an_instance_of`. + # Not intended to be instantiated directly. + class BeAnInstanceOf < BaseMatcher + # @api private + # @return [String] + def description + "be an instance of #{expected}" + end + + private + + def match(expected, actual) + actual.instance_of?(expected) + rescue NoMethodError + raise ::ArgumentError, "The #{matcher_name} matcher requires that " \ + "the actual object responds to #instance_of? method " \ + "but a `NoMethodError` was encountered instead." + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_kind_of.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_kind_of.rb new file mode 100644 index 00000000..4fe23bd9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_kind_of.rb @@ -0,0 +1,20 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `be_a_kind_of`. + # Not intended to be instantiated directly. + class BeAKindOf < BaseMatcher + private + + def match(expected, actual) + actual.kind_of?(expected) + rescue NoMethodError + raise ::ArgumentError, "The #{matcher_name} matcher requires that " \ + "the actual object responds to #kind_of? method " \ + "but a `NoMethodError` was encountered instead." + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_within.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_within.rb new file mode 100644 index 00000000..7a2b5b5b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/be_within.rb @@ -0,0 +1,72 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `be_within`. + # Not intended to be instantiated directly. + class BeWithin < BaseMatcher + def initialize(delta) + @delta = delta + end + + # @api public + # Sets the expected value. + def of(expected) + @expected = expected + @tolerance = @delta + @unit = '' + self + end + + # @api public + # Sets the expected value, and makes the matcher do + # a percent comparison. + def percent_of(expected) + @expected = expected + @tolerance = @expected.abs * @delta / 100.0 + @unit = '%' + self + end + + # @private + def matches?(actual) + @actual = actual + raise needs_expected unless defined? @expected + numeric? && (@actual - @expected).abs <= @tolerance + end + + # @api private + # @return [String] + def failure_message + "expected #{actual_formatted} to #{description}#{not_numeric_clause}" + end + + # @api private + # @return [String] + def failure_message_when_negated + "expected #{actual_formatted} not to #{description}" + end + + # @api private + # @return [String] + def description + "be within #{@delta}#{@unit} of #{expected_formatted}" + end + + private + + def numeric? + @actual.respond_to?(:-) + end + + def needs_expected + ArgumentError.new "You must set an expected value using #of: be_within(#{@delta}).of(expected_value)" + end + + def not_numeric_clause + ", but it could not be treated as a numeric value" unless numeric? + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/change.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/change.rb new file mode 100644 index 00000000..00e65dcf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/change.rb @@ -0,0 +1,452 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `change`. + # Not intended to be instantiated directly. + class Change < BaseMatcher + # @api public + # Specifies the delta of the expected change. + def by(expected_delta) + ChangeRelatively.new(change_details, expected_delta, :by) do |actual_delta| + values_match?(expected_delta, actual_delta) + end + end + + # @api public + # Specifies a minimum delta of the expected change. + def by_at_least(minimum) + ChangeRelatively.new(change_details, minimum, :by_at_least) do |actual_delta| + actual_delta >= minimum + end + end + + # @api public + # Specifies a maximum delta of the expected change. + def by_at_most(maximum) + ChangeRelatively.new(change_details, maximum, :by_at_most) do |actual_delta| + actual_delta <= maximum + end + end + + # @api public + # Specifies the new value you expect. + def to(value) + ChangeToValue.new(change_details, value) + end + + # @api public + # Specifies the original value. + def from(value) + ChangeFromValue.new(change_details, value) + end + + # @private + def matches?(event_proc) + raise_block_syntax_error if block_given? + perform_change(event_proc) && change_details.changed? + end + + def does_not_match?(event_proc) + raise_block_syntax_error if block_given? + perform_change(event_proc) && !change_details.changed? + end + + # @api private + # @return [String] + def failure_message + "expected #{change_details.value_representation} to have changed, " \ + "but #{positive_failure_reason}" + end + + # @api private + # @return [String] + def failure_message_when_negated + "expected #{change_details.value_representation} not to have changed, " \ + "but #{negative_failure_reason}" + end + + # @api private + # @return [String] + def description + "change #{change_details.value_representation}" + end + + # @private + def supports_block_expectations? + true + end + + # @private + def supports_value_expectations? + false + end + + private + + def initialize(receiver=nil, message=nil, &block) + @receiver = receiver + @message = message + @block = block + end + + def change_details + @change_details ||= ChangeDetails.new(matcher_name, @receiver, @message, &@block) + end + + def perform_change(event_proc) + @event_proc = event_proc + change_details.perform_change(event_proc) do |actual_before| + # pre-compute values derived from the `before` value before the + # mutation is applied, in case the specified mutation is mutation + # of a single object (rather than a changing what object a method + # returns). We need to cache these values before the `before` value + # they are based on potentially gets mutated. + @actual_before_description = description_of(actual_before) + end + end + + def raise_block_syntax_error + raise SyntaxError, "Block not received by the `change` matcher. " \ + "Perhaps you want to use `{ ... }` instead of do/end?" + end + + def positive_failure_reason + return "was not given a block" unless Proc === @event_proc + "is still #{@actual_before_description}" + end + + def negative_failure_reason + return "was not given a block" unless Proc === @event_proc + "did change from #{@actual_before_description} " \ + "to #{description_of change_details.actual_after}" + end + end + + # Used to specify a relative change. + # @api private + class ChangeRelatively < BaseMatcher + def initialize(change_details, expected_delta, relativity, &comparer) + @change_details = change_details + @expected_delta = expected_delta + @relativity = relativity + @comparer = comparer + end + + # @private + def failure_message + "expected #{@change_details.value_representation} to have changed " \ + "#{@relativity.to_s.tr('_', ' ')} " \ + "#{description_of @expected_delta}, but #{failure_reason}" + end + + # @private + def matches?(event_proc) + @event_proc = event_proc + @change_details.perform_change(event_proc) && @comparer.call(@change_details.actual_delta) + end + + # @private + def does_not_match?(_event_proc) + raise NotImplementedError, "`expect { }.not_to change " \ + "{ }.#{@relativity}()` is not supported" + end + + # @private + def description + "change #{@change_details.value_representation} " \ + "#{@relativity.to_s.tr('_', ' ')} #{description_of @expected_delta}" + end + + # @private + def supports_block_expectations? + true + end + + # @private + def supports_value_expectations? + false + end + + private + + def failure_reason + return "was not given a block" unless Proc === @event_proc + "was changed by #{description_of @change_details.actual_delta}" + end + end + + # @api private + # Base class for specifying a change from and/or to specific values. + class SpecificValuesChange < BaseMatcher + # @private + MATCH_ANYTHING = ::Object.ancestors.last + + def initialize(change_details, from, to) + @change_details = change_details + @expected_before = from + @expected_after = to + end + + # @private + def matches?(event_proc) + perform_change(event_proc) && @change_details.changed? && @matches_before && matches_after? + end + + # @private + def description + "change #{@change_details.value_representation} #{change_description}" + end + + # @private + def failure_message + return not_given_a_block_failure unless Proc === @event_proc + return before_value_failure unless @matches_before + return did_not_change_failure unless @change_details.changed? + after_value_failure + end + + # @private + def supports_block_expectations? + true + end + + # @private + def supports_value_expectations? + false + end + + private + + def perform_change(event_proc) + @event_proc = event_proc + @change_details.perform_change(event_proc) do |actual_before| + # pre-compute values derived from the `before` value before the + # mutation is applied, in case the specified mutation is mutation + # of a single object (rather than a changing what object a method + # returns). We need to cache these values before the `before` value + # they are based on potentially gets mutated. + @matches_before = values_match?(@expected_before, actual_before) + @actual_before_description = description_of(actual_before) + end + end + + def matches_after? + values_match?(@expected_after, @change_details.actual_after) + end + + def before_value_failure + "expected #{@change_details.value_representation} " \ + "to have initially been #{description_of @expected_before}, " \ + "but was #{@actual_before_description}" + end + + def after_value_failure + "expected #{@change_details.value_representation} " \ + "to have changed to #{description_of @expected_after}, " \ + "but is now #{description_of @change_details.actual_after}" + end + + def did_not_change_failure + "expected #{@change_details.value_representation} " \ + "to have changed #{change_description}, but did not change" + end + + def did_change_failure + "expected #{@change_details.value_representation} not to have changed, but " \ + "did change from #{@actual_before_description} " \ + "to #{description_of @change_details.actual_after}" + end + + def not_given_a_block_failure + "expected #{@change_details.value_representation} to have changed " \ + "#{change_description}, but was not given a block" + end + end + + # @api private + # Used to specify a change from a specific value + # (and, optionally, to a specific value). + class ChangeFromValue < SpecificValuesChange + def initialize(change_details, expected_before) + @description_suffix = nil + super(change_details, expected_before, MATCH_ANYTHING) + end + + # @api public + # Specifies the new value you expect. + def to(value) + @expected_after = value + @description_suffix = " to #{description_of value}" + self + end + + # @private + def does_not_match?(event_proc) + if @description_suffix + raise NotImplementedError, "`expect { }.not_to change { }.to()` " \ + "is not supported" + end + + perform_change(event_proc) && !@change_details.changed? && @matches_before + end + + # @private + def failure_message_when_negated + return not_given_a_block_failure unless Proc === @event_proc + return before_value_failure unless @matches_before + did_change_failure + end + + private + + def change_description + "from #{description_of @expected_before}#{@description_suffix}" + end + end + + # @api private + # Used to specify a change to a specific value + # (and, optionally, from a specific value). + class ChangeToValue < SpecificValuesChange + def initialize(change_details, expected_after) + @description_suffix = nil + super(change_details, MATCH_ANYTHING, expected_after) + end + + # @api public + # Specifies the original value. + def from(value) + @expected_before = value + @description_suffix = " from #{description_of value}" + self + end + + # @private + def does_not_match?(_event_proc) + raise NotImplementedError, "`expect { }.not_to change { }.to()` " \ + "is not supported" + end + + private + + def change_description + "to #{description_of @expected_after}#{@description_suffix}" + end + end + + # @private + # Encapsulates the details of the before/after values. + # + # Note that this class exposes the `actual_after` value, to allow the + # matchers above to derive failure messages, etc from the value on demand + # as needed, but it intentionally does _not_ expose the `actual_before` + # value. Some usages of the `change` matcher mutate a specific object + # returned by the value proc, which means that failure message snippets, + # etc, which are derived from the `before` value may not be accurate if + # they are lazily computed as needed. We must pre-compute them before + # applying the change in the `expect` block. To ensure that all `change` + # matchers do that properly, we do not expose the `actual_before` value. + # Instead, matchers must pass a block to `perform_change`, which yields + # the `actual_before` value before applying the change. + class ChangeDetails + attr_reader :actual_after + + UNDEFINED = Module.new.freeze + + def initialize(matcher_name, receiver=nil, message=nil, &block) + if receiver && !message + raise( + ArgumentError, + "`change` requires either an object and message " \ + "(`change(obj, :msg)`) or a block (`change { }`). " \ + "You passed an object but no message." + ) + end + + @matcher_name = matcher_name + @receiver = receiver + @message = message + @value_proc = block + # TODO: temporary measure to mute warning of access to an initialized + # instance variable when a deprecated implicit block expectation + # syntax is used. This may be removed once `fail` is used, and the + # matcher never issues this warning. + @actual_after = UNDEFINED + end + + def value_representation + @value_representation ||= + if @message + "`#{message_notation(@receiver, @message)}`" + elsif (value_block_snippet = extract_value_block_snippet) + "`#{value_block_snippet}`" + else + 'result' + end + end + + def perform_change(event_proc) + @actual_before = evaluate_value_proc + @before_hash = @actual_before.hash + yield @actual_before if block_given? + + return false unless Proc === event_proc + event_proc.call + + @actual_after = evaluate_value_proc + @actual_hash = @actual_after.hash + true + end + + def changed? + # Consider it changed if either: + # + # - The before/after values are unequal + # - The before/after values have different hash values + # + # The latter case specifically handles the case when the value proc + # returns the exact same object, but it has been mutated. + # + # Note that it is not sufficient to only check the hashes; it is + # possible for two values to be unequal (and of different classes) + # but to return the same hash value. Also, some objects may change + # their hash after being compared with `==`/`!=`. + @actual_before != @actual_after || @before_hash != @actual_hash + end + + def actual_delta + @actual_after - @actual_before + end + + private + + def evaluate_value_proc + @value_proc ? @value_proc.call : @receiver.__send__(@message) + end + + def message_notation(receiver, message) + case receiver + when Module + "#{receiver}.#{message}" + else + "#{Support.class_of(receiver)}##{message}" + end + end + + if RSpec::Support::RubyFeatures.ripper_supported? + def extract_value_block_snippet + return nil unless @value_proc + Expectations::BlockSnippetExtractor.try_extracting_single_line_body_of(@value_proc, @matcher_name) + end + else + # :nocov: + def extract_value_block_snippet + nil + end + # :nocov: + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/compound.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/compound.rb new file mode 100644 index 00000000..3a7fb1e6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/compound.rb @@ -0,0 +1,293 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Base class for `and` and `or` compound matchers. + class Compound < BaseMatcher + # @private + attr_reader :matcher_1, :matcher_2, :evaluator + + def initialize(matcher_1, matcher_2) + @matcher_1 = matcher_1 + @matcher_2 = matcher_2 + end + + # @private + def does_not_match?(_actual) + raise NotImplementedError, "`expect(...).not_to matcher.#{conjunction} matcher` " \ + "is not supported, since it creates a bit of an ambiguity. Instead, define negated versions " \ + "of whatever matchers you wish to negate with `RSpec::Matchers.define_negated_matcher` and " \ + "use `expect(...).to matcher.#{conjunction} matcher`." + end + + # @api private + # @return [String] + def description + "#{matcher_1.description} #{conjunction} #{matcher_2.description}" + end + + # @api private + def supports_block_expectations? + matcher_supports_block_expectations?(matcher_1) && + matcher_supports_block_expectations?(matcher_2) + end + + # @api private + def supports_value_expectations? + matcher_supports_value_expectations?(matcher_1) && + matcher_supports_value_expectations?(matcher_2) + end + + # @api private + def expects_call_stack_jump? + NestedEvaluator.matcher_expects_call_stack_jump?(matcher_1) || + NestedEvaluator.matcher_expects_call_stack_jump?(matcher_2) + end + + # @api private + # @return [Boolean] + def diffable? + matcher_is_diffable?(matcher_1) || matcher_is_diffable?(matcher_2) + end + + # @api private + # @return [RSpec::Matchers::MultiMatcherDiff] + def expected + return nil unless evaluator + ::RSpec::Matchers::MultiMatcherDiff.for_many_matchers(diffable_matcher_list) + end + + protected + + def diffable_matcher_list + list = [] + list.concat(diffable_matcher_list_for(matcher_1)) unless matcher_1_matches? + list.concat(diffable_matcher_list_for(matcher_2)) unless matcher_2_matches? + list + end + + private + + def initialize_copy(other) + @matcher_1 = @matcher_1.clone + @matcher_2 = @matcher_2.clone + super + end + + def match(_expected, actual) + evaluator_klass = if supports_block_expectations? && Proc === actual + NestedEvaluator + elsif supports_value_expectations? + SequentialEvaluator + else + # Can't raise an ArgumentError in this context, as it's rescued + raise "Block and value matchers can't be combined in a compound expectation (#{matcher_1.description}, #{matcher_2.description})" + end + + @evaluator = evaluator_klass.new(actual, matcher_1, matcher_2) + end + + def indent_multiline_message(message) + message.lines.map do |line| + line =~ /\S/ ? ' ' + line : line + end.join + end + + def compound_failure_message + "#{indent_multiline_message(matcher_1.failure_message.sub(/\n+\z/, ''))}" \ + "\n\n...#{conjunction}:" \ + "\n\n#{indent_multiline_message(matcher_2.failure_message.sub(/\A\n+/, ''))}" + end + + def matcher_1_matches? + evaluator.matcher_matches?(matcher_1) + end + + def matcher_2_matches? + evaluator.matcher_matches?(matcher_2) + end + + def matcher_supports_block_expectations?(matcher) + matcher.supports_block_expectations? + rescue NoMethodError + false + end + + def matcher_supports_value_expectations?(matcher) + matcher.supports_value_expectations? + rescue NoMethodError + true + end + + def matcher_is_diffable?(matcher) + matcher.diffable? + rescue NoMethodError + false + end + + def diffable_matcher_list_for(matcher) + return [] unless matcher_is_diffable?(matcher) + return matcher.diffable_matcher_list if Compound === matcher + [matcher] + end + + # For value expectations, we can evaluate the matchers sequentially. + class SequentialEvaluator + def initialize(actual, *) + @actual = actual + end + + def matcher_matches?(matcher) + matcher.matches?(@actual) + end + end + + # Normally, we evaluate the matching sequentially. For an expression like + # `expect(x).to foo.and bar`, this becomes: + # + # expect(x).to foo + # expect(x).to bar + # + # For block expectations, we need to nest them instead, so that + # `expect { x }.to foo.and bar` becomes: + # + # expect { + # expect { x }.to foo + # }.to bar + # + # This is necessary so that the `expect` block is only executed once. + class NestedEvaluator + def initialize(actual, matcher_1, matcher_2) + @actual = actual + @matcher_1 = matcher_1 + @matcher_2 = matcher_2 + @match_results = {} + + inner, outer = order_block_matchers + + @match_results[outer] = outer.matches?(Proc.new do |*args| + @match_results[inner] = inner.matches?(inner_matcher_block(args)) + end) + end + + def matcher_matches?(matcher) + @match_results.fetch(matcher) do + raise ArgumentError, "Your #{matcher.description} has no match " \ + "results, this can occur when an unexpected call stack or " \ + "local jump occurs. Perhaps one of your matchers needs to " \ + "declare `expects_call_stack_jump?` as `true`?" + end + end + + private + + # Some block matchers (such as `yield_xyz`) pass args to the `expect` block. + # When such a matcher is used as the outer matcher, we need to forward the + # the args on to the `expect` block. + def inner_matcher_block(outer_args) + return @actual if outer_args.empty? + + Proc.new do |*inner_args| + unless inner_args.empty? + raise ArgumentError, "(#{@matcher_1.description}) and " \ + "(#{@matcher_2.description}) cannot be combined in a compound expectation " \ + "since both matchers pass arguments to the block." + end + + @actual.call(*outer_args) + end + end + + # For a matcher like `raise_error` or `throw_symbol`, where the block will jump + # up the call stack, we need to order things so that it is the inner matcher. + # For example, we need it to be this: + # + # expect { + # expect { + # x += 1 + # raise "boom" + # }.to raise_error("boom") + # }.to change { x }.by(1) + # + # ...rather than: + # + # expect { + # expect { + # x += 1 + # raise "boom" + # }.to change { x }.by(1) + # }.to raise_error("boom") + # + # In the latter case, the after-block logic in the `change` matcher would never + # get executed because the `raise "boom"` line would jump to the `rescue` in the + # `raise_error` logic, so only the former case will work properly. + # + # This method figures out which matcher should be the inner matcher and which + # should be the outer matcher. + def order_block_matchers + return @matcher_1, @matcher_2 unless self.class.matcher_expects_call_stack_jump?(@matcher_2) + return @matcher_2, @matcher_1 unless self.class.matcher_expects_call_stack_jump?(@matcher_1) + + raise ArgumentError, "(#{@matcher_1.description}) and " \ + "(#{@matcher_2.description}) cannot be combined in a compound expectation " \ + "because they both expect a call stack jump." + end + + def self.matcher_expects_call_stack_jump?(matcher) + matcher.expects_call_stack_jump? + rescue NoMethodError + false + end + end + + # @api public + # Matcher used to represent a compound `and` expectation. + class And < self + # @api private + # @return [String] + def failure_message + if matcher_1_matches? + matcher_2.failure_message + elsif matcher_2_matches? + matcher_1.failure_message + else + compound_failure_message + end + end + + private + + def match(*) + super + matcher_1_matches? && matcher_2_matches? + end + + def conjunction + "and" + end + end + + # @api public + # Matcher used to represent a compound `or` expectation. + class Or < self + # @api private + # @return [String] + def failure_message + compound_failure_message + end + + private + + def match(*) + super + matcher_1_matches? || matcher_2_matches? + end + + def conjunction + "or" + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/contain_exactly.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/contain_exactly.rb new file mode 100644 index 00000000..f80572c5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/contain_exactly.rb @@ -0,0 +1,312 @@ +module RSpec + module Matchers + module BuiltIn + # rubocop:disable Metrics/ClassLength + # @api private + # Provides the implementation for `contain_exactly` and `match_array`. + # Not intended to be instantiated directly. + class ContainExactly < BaseMatcher + # @api private + # @return [String] + def failure_message + if Array === actual + generate_failure_message + else + "expected a collection that can be converted to an array with " \ + "`#to_ary` or `#to_a`, but got #{actual_formatted}" + end + end + + # @api private + # @return [String] + def failure_message_when_negated + list = EnglishPhrasing.list(surface_descriptions_in(expected)) + "expected #{actual_formatted} not to contain exactly#{list}" + end + + # @api private + # @return [String] + def description + list = EnglishPhrasing.list(surface_descriptions_in(expected)) + "contain exactly#{list}" + end + + def matches?(actual) + @pairings_maximizer = nil + @best_solution = nil + @extra_items = nil + @missing_items = nil + super(actual) + end + + private + + def generate_failure_message + message = expected_collection_line + message += actual_collection_line + message += missing_elements_line unless missing_items.empty? + message += extra_elements_line unless extra_items.empty? + message + end + + def expected_collection_line + message_line('expected collection contained', expected, true) + end + + def actual_collection_line + message_line('actual collection contained', actual) + end + + def missing_elements_line + message_line('the missing elements were', missing_items, true) + end + + def extra_elements_line + message_line('the extra elements were', extra_items) + end + + def describe_collection(collection, surface_descriptions=false) + if surface_descriptions + "#{description_of(safe_sort(surface_descriptions_in collection))}\n" + else + "#{description_of(safe_sort(collection))}\n" + end + end + + def message_line(prefix, collection, surface_descriptions=false) + "%-32s%s" % [prefix + ':', + describe_collection(collection, surface_descriptions)] + end + + def match(_expected, _actual) + return false unless convert_actual_to_an_array + match_when_sorted? || (extra_items.empty? && missing_items.empty?) + end + + # This cannot always work (e.g. when dealing with unsortable items, + # or matchers as expected items), but it's practically free compared to + # the slowness of the full matching algorithm, and in common cases this + # works, so it's worth a try. + def match_when_sorted? + values_match?(safe_sort(expected), safe_sort(actual)) + end + + def convert_actual_to_an_array + if actual.respond_to?(:to_ary) + @actual = actual.to_ary + elsif actual.respond_to?(:to_a) && !to_a_disallowed?(actual) + @actual = actual.to_a + else + false + end + end + + def safe_sort(array) + array.sort + rescue Support::AllExceptionsExceptOnesWeMustNotRescue + array + end + + if RUBY_VERSION == "1.8.7" + # :nocov: + def to_a_disallowed?(object) + case object + when NilClass, String then true + else Kernel == RSpec::Support.method_handle_for(object, :to_a).owner + end + end + # :nocov: + else + def to_a_disallowed?(object) + NilClass === object + end + end + + def missing_items + @missing_items ||= best_solution.unmatched_expected_indexes.map do |index| + expected[index] + end + end + + def extra_items + @extra_items ||= best_solution.unmatched_actual_indexes.map do |index| + actual[index] + end + end + + def best_solution + @best_solution ||= pairings_maximizer.find_best_solution + end + + def pairings_maximizer + @pairings_maximizer ||= begin + expected_matches = Hash[Array.new(expected.size) { |i| [i, []] }] + actual_matches = Hash[Array.new(actual.size) { |i| [i, []] }] + + expected.each_with_index do |e, ei| + actual.each_with_index do |a, ai| + next unless values_match?(e, a) + + expected_matches[ei] << ai + actual_matches[ai] << ei + end + end + + PairingsMaximizer.new(expected_matches, actual_matches) + end + end + + # Once we started supporting composing matchers, the algorithm for this matcher got + # much more complicated. Consider this expression: + # + # expect(["fool", "food"]).to contain_exactly(/foo/, /fool/) + # + # This should pass (because we can pair /fool/ with "fool" and /foo/ with "food"), but + # the original algorithm used by this matcher would pair the first elements it could + # (/foo/ with "fool"), which would leave /fool/ and "food" unmatched. When we have + # an expected element which is a matcher that matches a superset of actual items + # compared to another expected element matcher, we need to consider every possible pairing. + # + # This class is designed to maximize the number of actual/expected pairings -- or, + # conversely, to minimize the number of unpaired items. It's essentially a brute + # force solution, but with a few heuristics applied to reduce the size of the + # problem space: + # + # * Any items which match none of the items in the other list are immediately + # placed into the `unmatched_expected_indexes` or `unmatched_actual_indexes` array. + # The extra items and missing items in the matcher failure message are derived + # from these arrays. + # * Any items which reciprocally match only each other are paired up and not + # considered further. + # + # What's left is only the items which match multiple items from the other list + # (or vice versa). From here, it performs a brute-force depth-first search, + # looking for a solution which pairs all elements in both lists, or, barring that, + # that produces the fewest unmatched items. + # + # @private + class PairingsMaximizer + # @private + Solution = Struct.new(:unmatched_expected_indexes, :unmatched_actual_indexes, + :indeterminate_expected_indexes, :indeterminate_actual_indexes) do + def worse_than?(other) + unmatched_item_count > other.unmatched_item_count + end + + def candidate? + indeterminate_expected_indexes.empty? && + indeterminate_actual_indexes.empty? + end + + def ideal? + candidate? && ( + unmatched_expected_indexes.empty? || + unmatched_actual_indexes.empty? + ) + end + + def unmatched_item_count + unmatched_expected_indexes.count + unmatched_actual_indexes.count + end + + def +(derived_candidate_solution) + self.class.new( + unmatched_expected_indexes + derived_candidate_solution.unmatched_expected_indexes, + unmatched_actual_indexes + derived_candidate_solution.unmatched_actual_indexes, + # Ignore the indeterminate indexes: by the time we get here, + # we've dealt with all indeterminates. + [], [] + ) + end + end + + attr_reader :expected_to_actual_matched_indexes, :actual_to_expected_matched_indexes, :solution + + def initialize(expected_to_actual_matched_indexes, actual_to_expected_matched_indexes) + @expected_to_actual_matched_indexes = expected_to_actual_matched_indexes + @actual_to_expected_matched_indexes = actual_to_expected_matched_indexes + + unmatched_expected_indexes, indeterminate_expected_indexes = + categorize_indexes(expected_to_actual_matched_indexes, actual_to_expected_matched_indexes) + + unmatched_actual_indexes, indeterminate_actual_indexes = + categorize_indexes(actual_to_expected_matched_indexes, expected_to_actual_matched_indexes) + + @solution = Solution.new(unmatched_expected_indexes, unmatched_actual_indexes, + indeterminate_expected_indexes, indeterminate_actual_indexes) + end + + def find_best_solution + return solution if solution.candidate? + best_solution_so_far = NullSolution + + expected_index = solution.indeterminate_expected_indexes.first + actuals = expected_to_actual_matched_indexes[expected_index] + + actuals.each do |actual_index| + solution = best_solution_for_pairing(expected_index, actual_index) + return solution if solution.ideal? + best_solution_so_far = solution if best_solution_so_far.worse_than?(solution) + end + + best_solution_so_far + end + + private + + # @private + # Starting solution that is worse than any other real solution. + NullSolution = Class.new do + def self.worse_than?(_other) + true + end + end + + def categorize_indexes(indexes_to_categorize, other_indexes) + unmatched = [] + indeterminate = [] + + indexes_to_categorize.each_pair do |index, matches| + if matches.empty? + unmatched << index + elsif !reciprocal_single_match?(matches, index, other_indexes) + indeterminate << index + end + end + + return unmatched, indeterminate + end + + def reciprocal_single_match?(matches, index, other_list) + return false unless matches.one? + other_list[matches.first] == [index] + end + + def best_solution_for_pairing(expected_index, actual_index) + modified_expecteds = apply_pairing_to( + solution.indeterminate_expected_indexes, + expected_to_actual_matched_indexes, actual_index) + + modified_expecteds.delete(expected_index) + + modified_actuals = apply_pairing_to( + solution.indeterminate_actual_indexes, + actual_to_expected_matched_indexes, expected_index) + + modified_actuals.delete(actual_index) + + solution + self.class.new(modified_expecteds, modified_actuals).find_best_solution + end + + def apply_pairing_to(indeterminates, original_matches, other_list_index) + indeterminates.inject({}) do |accum, index| + accum[index] = original_matches[index] - [other_list_index] + accum + end + end + end + end + # rubocop:enable Metrics/ClassLength + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/count_expectation.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/count_expectation.rb new file mode 100644 index 00000000..aa91310c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/count_expectation.rb @@ -0,0 +1,171 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Abstract class to implement `once`, `at_least` and other + # count constraints. + module CountExpectation + # @api public + # Specifies that the method is expected to match once. + def once + exactly(1) + end + + # @api public + # Specifies that the method is expected to match twice. + def twice + exactly(2) + end + + # @api public + # Specifies that the method is expected to match thrice. + def thrice + exactly(3) + end + + # @api public + # Specifies that the method is expected to match the given number of times. + def exactly(number) + set_expected_count(:==, number) + self + end + + # @api public + # Specifies the maximum number of times the method is expected to match + def at_most(number) + set_expected_count(:<=, number) + self + end + + # @api public + # Specifies the minimum number of times the method is expected to match + def at_least(number) + set_expected_count(:>=, number) + self + end + + # @api public + # No-op. Provides syntactic sugar. + def times + self + end + + protected + # @api private + attr_reader :count_expectation_type, :expected_count + + private + + if RUBY_VERSION.to_f > 1.8 + def cover?(count, number) + count.cover?(number) + end + else + # :nocov: + def cover?(count, number) + number >= count.first && number <= count.last + end + # :nocov: + end + + def expected_count_matches?(actual_count) + @actual_count = actual_count + return @actual_count > 0 unless count_expectation_type + return cover?(expected_count, actual_count) if count_expectation_type == :<=> + + @actual_count.__send__(count_expectation_type, expected_count) + end + + def has_expected_count? + !!count_expectation_type + end + + def set_expected_count(relativity, n) + raise_unsupported_count_expectation if unsupported_count_expectation?(relativity) + + count = count_constraint_to_number(n) + + if count_expectation_type == :<= && relativity == :>= + raise_impossible_count_expectation(count) if count > expected_count + @count_expectation_type = :<=> + @expected_count = count..expected_count + elsif count_expectation_type == :>= && relativity == :<= + raise_impossible_count_expectation(count) if count < expected_count + @count_expectation_type = :<=> + @expected_count = expected_count..count + else + @count_expectation_type = relativity + @expected_count = count + end + end + + def raise_impossible_count_expectation(count) + text = + case count_expectation_type + when :<= then "at_least(#{count}).at_most(#{expected_count})" + when :>= then "at_least(#{expected_count}).at_most(#{count})" + end + raise ArgumentError, "The constraint #{text} is not possible" + end + + def raise_unsupported_count_expectation + text = + case count_expectation_type + when :<= then "at_least" + when :>= then "at_most" + when :<=> then "at_least/at_most combination" + else "count" + end + raise ArgumentError, "Multiple #{text} constraints are not supported" + end + + def count_constraint_to_number(n) + case n + when Numeric then n + when :once then 1 + when :twice then 2 + when :thrice then 3 + else + raise ArgumentError, "Expected a number, :once, :twice or :thrice," \ + " but got #{n}" + end + end + + def unsupported_count_expectation?(relativity) + return true if count_expectation_type == :== + return true if count_expectation_type == :<=> + (count_expectation_type == :<= && relativity == :<=) || + (count_expectation_type == :>= && relativity == :>=) + end + + def count_expectation_description + "#{human_readable_expectation_type}#{human_readable_count(expected_count)}" + end + + def count_failure_reason(action) + "#{count_expectation_description}" \ + " but #{action}#{human_readable_count(@actual_count)}" + end + + def human_readable_expectation_type + case count_expectation_type + when :<= then ' at most' + when :>= then ' at least' + when :<=> then ' between' + else '' + end + end + + def human_readable_count(count) + case count + when Range then " #{count.first} and #{count.last} times" + when nil then '' + when 1 then ' once' + when 2 then ' twice' + else " #{count} times" + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/cover.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/cover.rb new file mode 100644 index 00000000..47474a2c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/cover.rb @@ -0,0 +1,24 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `cover`. + # Not intended to be instantiated directly. + class Cover < BaseMatcher + def initialize(*expected) + @expected = expected + end + + def matches?(range) + @actual = range + @expected.all? { |e| range.cover?(e) } + end + + def does_not_match?(range) + @actual = range + expected.none? { |e| range.cover?(e) } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/eq.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/eq.rb new file mode 100644 index 00000000..08ed6563 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/eq.rb @@ -0,0 +1,44 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `eq`. + # Not intended to be instantiated directly. + class Eq < BaseMatcher + # @api private + # @return [String] + def failure_message + if string_encoding_differs? + "\nexpected: #{format_encoding(expected)} #{expected_formatted}\n got: #{format_encoding(actual)} #{actual_formatted}\n\n(compared using ==)\n" + else + "\nexpected: #{expected_formatted}\n got: #{actual_formatted}\n\n(compared using ==)\n" + end + end + + # @api private + # @return [String] + def failure_message_when_negated + "\nexpected: value != #{expected_formatted}\n got: #{actual_formatted}\n\n(compared using ==)\n" + end + + # @api private + # @return [String] + def description + "eq #{expected_formatted}" + end + + # @api private + # @return [Boolean] + def diffable? + true + end + + private + + def match(expected, actual) + actual == expected + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/eql.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/eql.rb new file mode 100644 index 00000000..32560dfe --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/eql.rb @@ -0,0 +1,38 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `eql`. + # Not intended to be instantiated directly. + class Eql < BaseMatcher + # @api private + # @return [String] + def failure_message + if string_encoding_differs? + "\nexpected: #{format_encoding(expected)} #{expected_formatted}\n got: #{format_encoding(actual)} #{actual_formatted}\n\n(compared using eql?)\n" + else + "\nexpected: #{expected_formatted}\n got: #{actual_formatted}\n\n(compared using eql?)\n" + end + end + + # @api private + # @return [String] + def failure_message_when_negated + "\nexpected: value != #{expected_formatted}\n got: #{actual_formatted}\n\n(compared using eql?)\n" + end + + # @api private + # @return [Boolean] + def diffable? + true + end + + private + + def match(expected, actual) + actual.eql? expected + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/equal.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/equal.rb new file mode 100644 index 00000000..bbab3ed1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/equal.rb @@ -0,0 +1,81 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `equal`. + # Not intended to be instantiated directly. + class Equal < BaseMatcher + # @api private + # @return [String] + def failure_message + if expected_is_a_literal_singleton? + simple_failure_message + else + detailed_failure_message + end + end + + # @api private + # @return [String] + def failure_message_when_negated + <<-MESSAGE + +expected not #{inspect_object(actual)} + got #{inspect_object(expected)} + +Compared using equal?, which compares object identity. + +MESSAGE + end + + # @api private + # @return [Boolean] + def diffable? + !expected_is_a_literal_singleton? + end + + private + + def match(expected, actual) + actual.equal? expected + end + + LITERAL_SINGLETONS = [true, false, nil] + + def expected_is_a_literal_singleton? + LITERAL_SINGLETONS.include?(expected) + end + + def actual_inspected + if LITERAL_SINGLETONS.include?(actual) + actual_formatted + else + inspect_object(actual) + end + end + + def simple_failure_message + "\nexpected #{expected_formatted}\n got #{actual_inspected}\n" + end + + def detailed_failure_message + <<-MESSAGE + +expected #{inspect_object(expected)} + got #{inspect_object(actual)} + +Compared using equal?, which compares object identity, +but expected and actual are not the same object. Use +`expect(actual).to eq(expected)` if you don't care about +object identity in this example. + +MESSAGE + end + + def inspect_object(o) + "#<#{o.class}:#{o.object_id}> => #{RSpec::Support::ObjectFormatter.format(o)}" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/exist.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/exist.rb new file mode 100644 index 00000000..438625d7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/exist.rb @@ -0,0 +1,90 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `exist`. + # Not intended to be instantiated directly. + class Exist < BaseMatcher + def initialize(*expected) + @expected = expected + end + + # @api private + # @return [Boolean] + def matches?(actual) + @actual = actual + @test = ExistenceTest.new @actual, @expected + @test.valid_test? && @test.actual_exists? + end + + # @api private + # @return [Boolean] + def does_not_match?(actual) + @actual = actual + @test = ExistenceTest.new @actual, @expected + @test.valid_test? && !@test.actual_exists? + end + + # @api private + # @return [String] + def failure_message + "expected #{actual_formatted} to exist#{@test.validity_message}" + end + + # @api private + # @return [String] + def failure_message_when_negated + "expected #{actual_formatted} not to exist#{@test.validity_message}" + end + + # @api private + # Simple class for memoizing actual/expected for this matcher + # and examining the match + class ExistenceTest < Struct.new(:actual, :expected) + # @api private + # @return [Boolean] + def valid_test? + uniq_truthy_values.size == 1 + end + + # @api private + # @return [Boolean] + def actual_exists? + existence_values.first + end + + # @api private + # @return [String] + def validity_message + case uniq_truthy_values.size + when 0 + " but it does not respond to either `exist?` or `exists?`" + when 2 + " but `exist?` and `exists?` returned different values:\n\n"\ + " exist?: #{existence_values.first}\n"\ + "exists?: #{existence_values.last}" + end + end + + private + + def uniq_truthy_values + @uniq_truthy_values ||= existence_values.map { |v| !!v }.uniq + end + + def existence_values + @existence_values ||= predicates.map { |p| actual.__send__(p, *expected) } + end + + def predicates + @predicates ||= [:exist?, :exists?].select { |p| actual.respond_to?(p) && !deprecated(p, actual) } + end + + def deprecated(predicate, actual) + predicate == :exists? && (File == actual || FileTest == actual || Dir == actual) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/has.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/has.rb new file mode 100644 index 00000000..0f4e7e4c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/has.rb @@ -0,0 +1,194 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for dynamic predicate matchers. + # Not intended to be inherited directly. + class DynamicPredicate < BaseMatcher + include BeHelpers + + def initialize(method_name, *args, &block) + @method_name, @args, @block = method_name, args, block + end + ruby2_keywords :initialize if respond_to?(:ruby2_keywords, true) + + # @private + def matches?(actual, &block) + @actual = actual + @block ||= block + predicate_accessible? && predicate_matches? + end + + # @private + def does_not_match?(actual, &block) + @actual = actual + @block ||= block + predicate_accessible? && predicate_matches?(false) + end + + # @api private + # @return [String] + def failure_message + failure_message_expecting(true) + end + + # @api private + # @return [String] + def failure_message_when_negated + failure_message_expecting(false) + end + + # @api private + # @return [String] + def description + "#{method_description}#{args_to_sentence}" + end + + private + + # Catch a semi-frequent typo - if you have strict_predicate_matchers disabled and + # expect(spy).to have_receieveddd(:foo) it would be evergreen - the dynamic matcher + # queries `has_receiveddd?`, the spy _fakes_ the method, returning its (truthy) self. + if defined?(RSpec::Mocks::Double) + def really_responds_to?(method) + if RSpec::Mocks::Double === @actual + @actual.respond_to?(method) && methods_include?(method) + else + @actual.respond_to?(method) + end + end + else + # :nocov: + def really_responds_to?(method) + @actual.respond_to?(method) + end + # :nocov: + end + + def predicate_accessible? + really_responds_to?(predicate) + end + + # support 1.8.7, evaluate once at load time for performance + if String === methods.first + # :nocov: + def private_predicate? + @actual.private_methods.include? predicate.to_s + end + + def methods_include?(method) + @actual.methods.include?(method.to_s) + end + # :nocov: + else + def private_predicate? + @actual.private_methods.include? predicate + end + + def methods_include?(method) + @actual.methods.include?(method) + end + end + + def predicate_result + @predicate_result = actual.__send__(predicate_method_name, *@args, &@block) + end + + def predicate_method_name + predicate + end + + def predicate_matches?(value=true) + if RSpec::Expectations.configuration.strict_predicate_matchers? + value == predicate_result + else + value == !!predicate_result + end + end + + def root + # On 1.9, there appears to be a bug where String#match can return `false` + # rather than the match data object. Changing to Regex#match appears to + # work around this bug. For an example of this bug, see: + # https://travis-ci.org/rspec/rspec-expectations/jobs/27549635 + self.class::REGEX.match(@method_name.to_s).captures.first + end + + def method_description + EnglishPhrasing.split_words(@method_name) + end + + def failure_message_expecting(value) + validity_message || + "expected `#{actual_formatted}.#{predicate}#{args_to_s}` to #{expectation_of value}, got #{description_of @predicate_result}" + end + + def expectation_of(value) + if RSpec::Expectations.configuration.strict_predicate_matchers? + "return #{value}" + elsif value + "be truthy" + else + "be falsey" + end + end + + def validity_message + return nil if predicate_accessible? + + "expected #{actual_formatted} to respond to `#{predicate}`#{failure_to_respond_explanation}" + end + + def failure_to_respond_explanation + if private_predicate? + " but `#{predicate}` is a private method" + end + end + end + + # @api private + # Provides the implementation for `has_`. + # Not intended to be instantiated directly. + class Has < DynamicPredicate + # :nodoc: + REGEX = Matchers::HAS_REGEX + private + def predicate + @predicate ||= :"has_#{root}?" + end + end + + # @api private + # Provides the implementation of `be_`. + # Not intended to be instantiated directly. + class BePredicate < DynamicPredicate + # :nodoc: + REGEX = Matchers::BE_PREDICATE_REGEX + private + def predicate + @predicate ||= :"#{root}?" + end + + def predicate_method_name + actual.respond_to?(predicate) ? predicate : present_tense_predicate + end + + def failure_to_respond_explanation + super || if predicate == :true? + " or perhaps you meant `be true` or `be_truthy`" + elsif predicate == :false? + " or perhaps you meant `be false` or `be_falsey`" + end + end + + def predicate_accessible? + super || really_responds_to?(present_tense_predicate) + end + + def present_tense_predicate + :"#{root}s?" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/have_attributes.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/have_attributes.rb new file mode 100644 index 00000000..89be3f2e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/have_attributes.rb @@ -0,0 +1,114 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `have_attributes`. + # Not intended to be instantiated directly. + class HaveAttributes < BaseMatcher + # @private + attr_reader :respond_to_failed + + def initialize(expected) + @expected = expected + @values = {} + @respond_to_failed = false + @negated = false + end + + # @private + def actual + @values + end + + # @api private + # @return [Boolean] + def matches?(actual) + @actual = actual + @negated = false + return false unless respond_to_attributes? + perform_match(:all?) + end + + # @api private + # @return [Boolean] + def does_not_match?(actual) + @actual = actual + @negated = true + return false unless respond_to_attributes? + perform_match(:none?) + end + + # @api private + # @return [String] + def description + described_items = surface_descriptions_in(expected) + improve_hash_formatting "have attributes #{RSpec::Support::ObjectFormatter.format(described_items)}" + end + + # @api private + # @return [Boolean] + def diffable? + !@respond_to_failed && !@negated + end + + # @api private + # @return [String] + def failure_message + respond_to_failure_message_or do + "expected #{actual_formatted} to #{description} but had attributes #{ formatted_values }" + end + end + + # @api private + # @return [String] + def failure_message_when_negated + respond_to_failure_message_or { "expected #{actual_formatted} not to #{description}" } + end + + private + + def cache_all_values + @values = {} + expected.each do |attribute_key, _attribute_value| + actual_value = @actual.__send__(attribute_key) + @values[attribute_key] = actual_value + end + end + + def perform_match(predicate) + cache_all_values + expected.__send__(predicate) do |attribute_key, attribute_value| + actual_has_attribute?(attribute_key, attribute_value) + end + end + + def actual_has_attribute?(attribute_key, attribute_value) + values_match?(attribute_value, @values.fetch(attribute_key)) + end + + def respond_to_attributes? + matches = respond_to_matcher.matches?(@actual) + @respond_to_failed = !matches + matches + end + + def respond_to_matcher + @respond_to_matcher ||= RespondTo.new(*expected.keys).with(0).arguments.tap { |m| m.ignoring_method_signature_failure! } + end + + def respond_to_failure_message_or + if respond_to_failed + respond_to_matcher.failure_message + else + improve_hash_formatting(yield) + end + end + + def formatted_values + values = RSpec::Support::ObjectFormatter.format(@values) + improve_hash_formatting(values) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/include.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/include.rb new file mode 100644 index 00000000..3fedee3a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/include.rb @@ -0,0 +1,218 @@ +require 'rspec/matchers/built_in/count_expectation' + +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `include`. + # Not intended to be instantiated directly. + class Include < BaseMatcher # rubocop:disable Metrics/ClassLength + include CountExpectation + # @private + attr_reader :expecteds + + # @api private + def initialize(*expecteds) + raise(ArgumentError, 'include() is not supported, please supply an argument') if expecteds.empty? + @expecteds = expecteds + end + + # @api private + # @return [Boolean] + def matches?(actual) + check_actual?(actual) && + if check_expected_count? + expected_count_matches?(count_inclusions) + else + perform_match { |v| v } + end + end + + # @api private + # @return [Boolean] + def does_not_match?(actual) + check_actual?(actual) && + if check_expected_count? + !expected_count_matches?(count_inclusions) + else + perform_match { |v| !v } + end + end + + # @api private + # @return [String] + def description + improve_hash_formatting("include#{readable_list_of(expecteds)}#{count_expectation_description}") + end + + # @api private + # @return [String] + def failure_message + format_failure_message("to") { super } + end + + # @api private + # @return [String] + def failure_message_when_negated + format_failure_message("not to") { super } + end + + # @api private + # @return [Boolean] + def diffable? + !diff_would_wrongly_highlight_matched_item? + end + + # @api private + # @return [Array, Hash] + def expected + if expecteds.one? && Hash === expecteds.first + expecteds.first + else + expecteds + end + end + + private + + def check_actual?(actual) + actual = actual.to_hash if convert_to_hash?(actual) + @actual = actual + @actual.respond_to?(:include?) + end + + def check_expected_count? + case + when !has_expected_count? + return false + when expecteds.size != 1 + raise NotImplementedError, 'Count constraint supported only when testing for a single value being included' + when actual.is_a?(Hash) + raise NotImplementedError, 'Count constraint on hash keys not implemented' + end + true + end + + def format_failure_message(preposition) + msg = if actual.respond_to?(:include?) + "expected #{description_of @actual} #{preposition}" \ + " include#{readable_list_of @divergent_items}" \ + "#{count_failure_reason('it is included') if has_expected_count?}" + else + "#{yield}, but it does not respond to `include?`" + end + improve_hash_formatting(msg) + end + + def readable_list_of(items) + described_items = surface_descriptions_in(items) + if described_items.all? { |item| item.is_a?(Hash) } + " #{described_items.inject(:merge).inspect}" + else + EnglishPhrasing.list(described_items) + end + end + + def perform_match(&block) + @divergent_items = excluded_from_actual(&block) + @divergent_items.empty? + end + + def excluded_from_actual + return [] unless @actual.respond_to?(:include?) + + expecteds.inject([]) do |memo, expected_item| + if comparing_hash_to_a_subset?(expected_item) + expected_item.each do |(key, value)| + memo << { key => value } unless yield actual_hash_includes?(key, value) + end + elsif comparing_hash_keys?(expected_item) + memo << expected_item unless yield actual_hash_has_key?(expected_item) + else + memo << expected_item unless yield actual_collection_includes?(expected_item) + end + memo + end + end + + def comparing_hash_to_a_subset?(expected_item) + actual.is_a?(Hash) && expected_item.is_a?(Hash) + end + + def actual_hash_includes?(expected_key, expected_value) + actual_value = + actual.fetch(expected_key) do + actual.find(Proc.new { return false }) { |actual_key, _| values_match?(expected_key, actual_key) }[1] + end + values_match?(expected_value, actual_value) + end + + def comparing_hash_keys?(expected_item) + actual.is_a?(Hash) && !expected_item.is_a?(Hash) + end + + def actual_hash_has_key?(expected_key) + # We check `key?` first for perf: + # `key?` is O(1), but `any?` is O(N). + + has_exact_key = + begin + actual.key?(expected_key) + rescue + false + end + + has_exact_key || actual.keys.any? { |key| values_match?(expected_key, key) } + end + + def actual_collection_includes?(expected_item) + return actual.scan(expected_item).size > 0 if Regexp === expected_item && String === actual + return true if actual.include?(expected_item) + + # String lacks an `any?` method... + return false unless actual.respond_to?(:any?) + + actual.any? { |value| values_match?(expected_item, value) } + end + + if RUBY_VERSION < '1.9' + # :nocov: + def count_enumerable(expected_item) + actual.select { |value| values_match?(expected_item, value) }.size + end + # :nocov: + else + def count_enumerable(expected_item) + actual.count { |value| values_match?(expected_item, value) } + end + end + + def count_inclusions + @divergent_items = expected + case actual + when String + actual.scan(expected.first).length + when Enumerable + count_enumerable(Hash === expected ? expected : expected.first) + else + raise NotImplementedError, 'Count constraints are implemented for Enumerable and String values only' + end + end + + def diff_would_wrongly_highlight_matched_item? + return false unless actual.is_a?(String) && expected.is_a?(Array) + return false if Regexp === expecteds.first + + lines = actual.split("\n") + expected.any? do |str| + actual.include?(str) && lines.none? { |line| line == str } + end + end + + def convert_to_hash?(obj) + !obj.respond_to?(:include?) && obj.respond_to?(:to_hash) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/match.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/match.rb new file mode 100644 index 00000000..a822f76b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/match.rb @@ -0,0 +1,120 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `match`. + # Not intended to be instantiated directly. + class Match < BaseMatcher + def initialize(expected) + super(expected) + + @expected_captures = nil + end + # @api private + # @return [String] + def description + if @expected_captures && @expected.match(actual) + "match #{surface_descriptions_in(expected).inspect} with captures #{surface_descriptions_in(@expected_captures).inspect}" + else + "match #{surface_descriptions_in(expected).inspect}" + end + end + + # @api private + # @return [Boolean] + def diffable? + true + end + + # Used to specify the captures we match against + # @return [self] + def with_captures(*captures) + @expected_captures = captures + self + end + + # @api private + # @return [String] + def failure_message + if Array === expected && !(actual.respond_to?(:to_a) || actual.respond_to?(:to_ary)) + return "expected a collection that can be converted to an array with " \ + "`#to_ary` or `#to_a`, but got #{actual_formatted}" + end + + super + end + + private + + def match(expected, actual) + return match_captures(expected, actual) if @expected_captures + return true if values_match?(expected, actual) + return false if Array === expected + return false unless can_safely_call_match?(expected, actual) + actual.match(expected) + end + + def can_safely_call_match?(expected, actual) + return false unless actual.respond_to?(:match) + + !(RSpec::Matchers.is_a_matcher?(expected) && + (String === actual || Regexp === actual)) + end + + def match_captures(expected, actual) + match = actual.match(expected) + if match + match = ReliableMatchData.new(match) + if match.names.empty? + values_match?(@expected_captures, match.captures) + else + expected_matcher = @expected_captures.last + values_match?(expected_matcher, Hash[match.names.zip(match.captures)]) || + values_match?(expected_matcher, Hash[match.names.map(&:to_sym).zip(match.captures)]) || + values_match?(@expected_captures, match.captures) + end + else + false + end + end + end + + # @api private + # Used to wrap match data and make it reliable for 1.8.7 + class ReliableMatchData + def initialize(match_data) + @match_data = match_data + end + + if RUBY_VERSION == "1.8.7" + # @api private + # Returns match data names for named captures + # @return Array + # :nocov: + def names + [] + end + # :nocov: + else + # @api private + # Returns match data names for named captures + # @return Array + def names + match_data.names + end + end + + # @api private + # returns an array of captures from the match data + # @return Array + def captures + match_data.captures + end + + protected + + attr_reader :match_data + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/operators.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/operators.rb new file mode 100644 index 00000000..64f8f3b2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/operators.rb @@ -0,0 +1,128 @@ +require 'rspec/support' + +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for operator matchers. + # Not intended to be instantiated directly. + # Only available for use with `should`. + class OperatorMatcher + class << self + # @private + def registry + @registry ||= {} + end + + # @private + def register(klass, operator, matcher) + registry[klass] ||= {} + registry[klass][operator] = matcher + end + + # @private + def unregister(klass, operator) + registry[klass] && registry[klass].delete(operator) + end + + # @private + def get(klass, operator) + klass.ancestors.each do |ancestor| + matcher = registry[ancestor] && registry[ancestor][operator] + return matcher if matcher + end + + nil + end + end + + register Enumerable, '=~', BuiltIn::ContainExactly + + def initialize(actual) + @actual = actual + end + + # @private + def self.use_custom_matcher_or_delegate(operator) + define_method(operator) do |expected| + if !has_non_generic_implementation_of?(operator) && (matcher = OperatorMatcher.get(@actual.class, operator)) + @actual.__send__(::RSpec::Matchers.last_expectation_handler.should_method, matcher.new(expected)) + else + eval_match(@actual, operator, expected) + end + end + + negative_operator = operator.sub(/^=/, '!') + if negative_operator != operator && respond_to?(negative_operator) + define_method(negative_operator) do |_expected| + opposite_should = ::RSpec::Matchers.last_expectation_handler.opposite_should_method + raise "RSpec does not support `#{::RSpec::Matchers.last_expectation_handler.should_method} #{negative_operator} expected`. " \ + "Use `#{opposite_should} #{operator} expected` instead." + end + end + end + + ['==', '===', '=~', '>', '>=', '<', '<='].each do |operator| + use_custom_matcher_or_delegate operator + end + + # @private + def fail_with_message(message) + RSpec::Expectations.fail_with(message, @expected, @actual) + end + + # @api private + # @return [String] + def description + "#{@operator} #{RSpec::Support::ObjectFormatter.format(@expected)}" + end + + private + + def has_non_generic_implementation_of?(op) + Support.method_handle_for(@actual, op).owner != ::Kernel + rescue NameError + false + end + + def eval_match(actual, operator, expected) + ::RSpec::Matchers.last_matcher = self + @operator, @expected = operator, expected + __delegate_operator(actual, operator, expected) + end + end + + # @private + # Handles operator matcher for `should`. + class PositiveOperatorMatcher < OperatorMatcher + def __delegate_operator(actual, operator, expected) + if actual.__send__(operator, expected) + true + else + expected_formatted = RSpec::Support::ObjectFormatter.format(expected) + actual_formatted = RSpec::Support::ObjectFormatter.format(actual) + + if ['==', '===', '=~'].include?(operator) + fail_with_message("expected: #{expected_formatted}\n got: #{actual_formatted} (using #{operator})") + else + fail_with_message("expected: #{operator} #{expected_formatted}\n got: #{operator.gsub(/./, ' ')} #{actual_formatted}") + end + end + end + end + + # @private + # Handles operator matcher for `should_not`. + class NegativeOperatorMatcher < OperatorMatcher + def __delegate_operator(actual, operator, expected) + return false unless actual.__send__(operator, expected) + + expected_formatted = RSpec::Support::ObjectFormatter.format(expected) + actual_formatted = RSpec::Support::ObjectFormatter.format(actual) + + fail_with_message("expected not: #{operator} #{expected_formatted}\n got: #{operator.gsub(/./, ' ')} #{actual_formatted}") + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/output.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/output.rb new file mode 100644 index 00000000..8c3cceda --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/output.rb @@ -0,0 +1,207 @@ +require 'stringio' + +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `output`. + # Not intended to be instantiated directly. + class Output < BaseMatcher + def initialize(expected) + @expected = expected + @actual = "" + @block = nil + @stream_capturer = NullCapture + end + + def matches?(block) + @block = block + return false unless Proc === block + @actual = @stream_capturer.capture(block) + @expected ? values_match?(@expected, @actual) : captured? + end + + def does_not_match?(block) + !matches?(block) && Proc === block + end + + # @api public + # Tells the matcher to match against stdout. + # Works only when the main Ruby process prints to stdout + def to_stdout + @stream_capturer = CaptureStdout + self + end + + # @api public + # Tells the matcher to match against stderr. + # Works only when the main Ruby process prints to stderr + def to_stderr + @stream_capturer = CaptureStderr + self + end + + # @api public + # Tells the matcher to match against stdout. + # Works when subprocesses print to stdout as well. + # This is significantly (~30x) slower than `to_stdout` + def to_stdout_from_any_process + @stream_capturer = CaptureStreamToTempfile.new("stdout", $stdout) + self + end + + # @api public + # Tells the matcher to match against stderr. + # Works when subprocesses print to stderr as well. + # This is significantly (~30x) slower than `to_stderr` + def to_stderr_from_any_process + @stream_capturer = CaptureStreamToTempfile.new("stderr", $stderr) + self + end + + # @api private + # @return [String] + def failure_message + "expected block to #{description}, but #{positive_failure_reason}" + end + + # @api private + # @return [String] + def failure_message_when_negated + "expected block to not #{description}, but #{negative_failure_reason}" + end + + # @api private + # @return [String] + def description + if @expected + "output #{description_of @expected} to #{@stream_capturer.name}" + else + "output to #{@stream_capturer.name}" + end + end + + # @api private + # @return [Boolean] + def diffable? + true + end + + # @api private + # Indicates this matcher matches against a block. + # @return [True] + def supports_block_expectations? + true + end + + # @api private + # Indicates this matcher matches against a block only. + # @return [False] + def supports_value_expectations? + false + end + + private + + def captured? + @actual.length > 0 + end + + def positive_failure_reason + return "was not a block" unless Proc === @block + return "output #{actual_output_description}" if @expected + "did not" + end + + def negative_failure_reason + return "was not a block" unless Proc === @block + "output #{actual_output_description}" + end + + def actual_output_description + return "nothing" unless captured? + actual_formatted + end + end + + # @private + module NullCapture + def self.name + "some stream" + end + + def self.capture(_block) + raise "You must chain `to_stdout` or `to_stderr` off of the `output(...)` matcher." + end + end + + # @private + module CaptureStdout + def self.name + 'stdout' + end + + def self.capture(block) + captured_stream = StringIO.new + + original_stream = $stdout + $stdout = captured_stream + + block.call + + captured_stream.string + ensure + $stdout = original_stream + end + end + + # @private + module CaptureStderr + def self.name + 'stderr' + end + + def self.capture(block) + captured_stream = StringIO.new + + original_stream = $stderr + $stderr = captured_stream + + block.call + + captured_stream.string + ensure + $stderr = original_stream + end + end + + # @private + class CaptureStreamToTempfile < Struct.new(:name, :stream) + def capture(block) + # We delay loading tempfile until it is actually needed because + # we want to minimize stdlibs loaded so that users who use a + # portion of the stdlib can't have passing specs while forgetting + # to load it themselves. `CaptureStreamToTempfile` is rarely used + # and `tempfile` pulls in a bunch of things (delegate, tmpdir, + # thread, fileutils, etc), so it's worth delaying it until this point. + require 'tempfile' + + original_stream = stream.clone + captured_stream = Tempfile.new(name) + + begin + captured_stream.sync = true + stream.reopen(captured_stream) + block.call + captured_stream.rewind + captured_stream.read + ensure + stream.reopen(original_stream) + captured_stream.close + captured_stream.unlink + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/raise_error.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/raise_error.rb new file mode 100644 index 00000000..bbaaf623 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/raise_error.rb @@ -0,0 +1,275 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `raise_error`. + # Not intended to be instantiated directly. + # rubocop:disable Metrics/ClassLength + # rubocop:disable Lint/RescueException + class RaiseError + include Composable + + # Used as a sentinel value to be able to tell when the user did not pass an + # argument. We can't use `nil` for that because we need to warn when `nil` is + # passed in a different way. It's an Object, not a Module, since Module's `===` + # does not evaluate to true when compared to itself. + # + # Note; this _is_ the default value supplied for expected_error_or_message, but + # because there are two method-calls involved, that default is actually supplied + # in the definition of the _matcher_ method, `RSpec::Matchers#raise_error` + UndefinedValue = Object.new.freeze + + def initialize(expected_error_or_message, expected_message, &block) + @block = block + @actual_error = nil + @warn_about_bare_error = UndefinedValue === expected_error_or_message + @warn_about_nil_error = expected_error_or_message.nil? + + case expected_error_or_message + when nil, UndefinedValue + @expected_error = Exception + @expected_message = expected_message + when String, Regexp + @expected_error = Exception + @expected_message = expected_error_or_message + else + @expected_error = expected_error_or_message + @expected_message = expected_message + end + end + + # @api public + # Specifies the expected error message. + def with_message(expected_message) + raise_message_already_set if @expected_message + @warn_about_bare_error = false + @expected_message = expected_message + self + end + + # rubocop:disable Metrics/MethodLength + # @private + def matches?(given_proc, negative_expectation=false, &block) + @given_proc = given_proc + @block ||= block + @raised_expected_error = false + @with_expected_message = false + @eval_block = false + @eval_block_passed = false + + return false unless Proc === given_proc + + begin + given_proc.call + rescue Exception => @actual_error + if values_match?(@expected_error, @actual_error) || + values_match?(@expected_error, actual_error_message) + @raised_expected_error = true + @with_expected_message = verify_message + end + end + + unless negative_expectation + warn_about_bare_error! if warn_about_bare_error? + warn_about_nil_error! if warn_about_nil_error? + eval_block if ready_to_eval_block? + end + + expectation_matched? + end + # rubocop:enable Metrics/MethodLength + + # @private + def does_not_match?(given_proc) + warn_for_negative_false_positives! + !matches?(given_proc, :negative_expectation) && Proc === given_proc + end + + # @private + def supports_block_expectations? + true + end + + # @private + def supports_value_expectations? + false + end + + # @private + def expects_call_stack_jump? + true + end + + # @api private + # @return [String] + def failure_message + @eval_block ? actual_error_message : "expected #{expected_error}#{given_error}" + end + + # @api private + # @return [String] + def failure_message_when_negated + "expected no #{expected_error}#{given_error}" + end + + # @api private + # @return [String] + def description + "raise #{expected_error}" + end + + private + + def actual_error_message + return nil unless @actual_error + + @actual_error.respond_to?(:original_message) ? @actual_error.original_message : @actual_error.message + end + + def expectation_matched? + error_and_message_match? && block_matches? + end + + def error_and_message_match? + @raised_expected_error && @with_expected_message + end + + def block_matches? + @eval_block ? @eval_block_passed : true + end + + def ready_to_eval_block? + @raised_expected_error && @with_expected_message && @block + end + + def eval_block + @eval_block = true + begin + @block[@actual_error] + @eval_block_passed = true + rescue Exception => err + @actual_error = err + end + end + + def verify_message + return true if @expected_message.nil? + values_match?(@expected_message, actual_error_message.to_s) + end + + def warn_for_negative_false_positives! + expression = if expecting_specific_exception? && @expected_message + "`expect { }.not_to raise_error(SpecificErrorClass, message)`" + elsif expecting_specific_exception? + "`expect { }.not_to raise_error(SpecificErrorClass)`" + elsif @expected_message + "`expect { }.not_to raise_error(message)`" + elsif @warn_about_nil_error + "`expect { }.not_to raise_error(nil)`" + end + + return unless expression + + warn_about_negative_false_positive! expression + end + + def handle_warning(message) + RSpec::Expectations.configuration.false_positives_handler.call(message) + end + + def warn_about_bare_error? + @warn_about_bare_error && @block.nil? + end + + def warn_about_nil_error? + @warn_about_nil_error + end + + def warn_about_bare_error! + handle_warning("Using the `raise_error` matcher without providing a specific " \ + "error or message risks false positives, since `raise_error` " \ + "will match when Ruby raises a `NoMethodError`, `NameError` or " \ + "`ArgumentError`, potentially allowing the expectation to pass " \ + "without even executing the method you are intending to call. " \ + "#{warning}"\ + "Instead consider providing a specific error class or message. " \ + "This message can be suppressed by setting: " \ + "`RSpec::Expectations.configuration.on_potential_false" \ + "_positives = :nothing`") + end + + def warn_about_nil_error! + handle_warning("Using the `raise_error` matcher with a `nil` error is probably " \ + "unintentional, it risks false positives, since `raise_error` " \ + "will match when Ruby raises a `NoMethodError`, `NameError` or " \ + "`ArgumentError`, potentially allowing the expectation to pass " \ + "without even executing the method you are intending to call. " \ + "#{warning}"\ + "Instead consider providing a specific error class or message. " \ + "This message can be suppressed by setting: " \ + "`RSpec::Expectations.configuration.on_potential_false" \ + "_positives = :nothing`") + end + + def warn_about_negative_false_positive!(expression) + handle_warning("Using #{expression} risks false positives, since literally " \ + "any other error would cause the expectation to pass, " \ + "including those raised by Ruby (e.g. `NoMethodError`, `NameError` " \ + "and `ArgumentError`), meaning the code you are intending to test " \ + "may not even get reached. Instead consider using " \ + "`expect { }.not_to raise_error` or `expect { }.to raise_error" \ + "(DifferentSpecificErrorClass)`. This message can be suppressed by " \ + "setting: `RSpec::Expectations.configuration.on_potential_false" \ + "_positives = :nothing`") + end + + def expected_error + case @expected_message + when nil + if RSpec::Support.is_a_matcher?(@expected_error) + "Exception with #{description_of(@expected_error)}" + else + description_of(@expected_error) + end + when Regexp + "#{@expected_error} with message matching #{description_of(@expected_message)}" + else + "#{@expected_error} with #{description_of(@expected_message)}" + end + end + + def format_backtrace(backtrace) + formatter = Matchers.configuration.backtrace_formatter + formatter.format_backtrace(backtrace) + end + + def given_error + return " but was not given a block" unless Proc === @given_proc + return " but nothing was raised" unless @actual_error + + backtrace = format_backtrace(@actual_error.backtrace) + [ + ", got #{description_of(@actual_error)} with backtrace:", + *backtrace + ].join("\n # ") + end + + def expecting_specific_exception? + @expected_error != Exception + end + + def raise_message_already_set + raise "`expect { }.to raise_error(message).with_message(message)` is not valid. " \ + 'The matcher only allows the expected message to be specified once' + end + + def warning + warning = "Actual error raised was #{description_of(@actual_error)}. " + warning if @actual_error + end + end + # rubocop:enable Lint/RescueException + # rubocop:enable Metrics/ClassLength + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/respond_to.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/respond_to.rb new file mode 100644 index 00000000..9adbe04e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/respond_to.rb @@ -0,0 +1,200 @@ +RSpec::Support.require_rspec_support "method_signature_verifier" + +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `respond_to`. + # Not intended to be instantiated directly. + class RespondTo < BaseMatcher + def initialize(*names) + @names = names + @expected_arity = nil + @expected_keywords = [] + @ignoring_method_signature_failure = false + @unlimited_arguments = nil + @arbitrary_keywords = nil + end + + # @api public + # Specifies the number of expected arguments. + # + # @example + # expect(obj).to respond_to(:message).with(3).arguments + def with(n) + @expected_arity = n + self + end + + # @api public + # Specifies keyword arguments, if any. + # + # @example + # expect(obj).to respond_to(:message).with_keywords(:color, :shape) + # @example with an expected number of arguments + # expect(obj).to respond_to(:message).with(3).arguments.and_keywords(:color, :shape) + def with_keywords(*keywords) + @expected_keywords = keywords + self + end + alias :and_keywords :with_keywords + + # @api public + # Specifies that the method accepts any keyword, i.e. the method has + # a splatted keyword parameter of the form **kw_args. + # + # @example + # expect(obj).to respond_to(:message).with_any_keywords + def with_any_keywords + @arbitrary_keywords = true + self + end + alias :and_any_keywords :with_any_keywords + + # @api public + # Specifies that the number of arguments has no upper limit, i.e. the + # method has a splatted parameter of the form *args. + # + # @example + # expect(obj).to respond_to(:message).with_unlimited_arguments + def with_unlimited_arguments + @unlimited_arguments = true + self + end + alias :and_unlimited_arguments :with_unlimited_arguments + + # @api public + # No-op. Intended to be used as syntactic sugar when using `with`. + # + # @example + # expect(obj).to respond_to(:message).with(3).arguments + def argument + self + end + alias :arguments :argument + + # @private + def matches?(actual) + find_failing_method_names(actual, :reject).empty? + end + + # @private + def does_not_match?(actual) + find_failing_method_names(actual, :select).empty? + end + + # @api private + # @return [String] + def failure_message + "expected #{actual_formatted} to respond to #{@failing_method_names.map { |name| description_of(name) }.join(', ')}#{with_arity}" + end + + # @api private + # @return [String] + def failure_message_when_negated + failure_message.sub(/to respond to/, 'not to respond to') + end + + # @api private + # @return [String] + def description + "respond to #{pp_names}#{with_arity}" + end + + # @api private + # Used by other matchers to suppress a check + def ignoring_method_signature_failure! + @ignoring_method_signature_failure = true + end + + private + + def find_failing_method_names(actual, filter_method) + @actual = actual + @failing_method_names = @names.__send__(filter_method) do |name| + @actual.respond_to?(name) && matches_arity?(actual, name) + end + end + + def matches_arity?(actual, name) + ArityCheck.new(@expected_arity, @expected_keywords, @arbitrary_keywords, @unlimited_arguments).matches?(actual, name) + rescue NameError + return true if @ignoring_method_signature_failure + raise ArgumentError, "The #{matcher_name} matcher requires that " \ + "the actual object define the method(s) in " \ + "order to check arity, but the method " \ + "`#{name}` is not defined. Remove the arity " \ + "check or define the method to continue." + end + + def with_arity + str = ''.dup + str << " with #{with_arity_string}" if @expected_arity + str << " #{str.length == 0 ? 'with' : 'and'} #{with_keywords_string}" if @expected_keywords && @expected_keywords.count > 0 + str << " #{str.length == 0 ? 'with' : 'and'} unlimited arguments" if @unlimited_arguments + str << " #{str.length == 0 ? 'with' : 'and'} any keywords" if @arbitrary_keywords + str + end + + def with_arity_string + "#{@expected_arity} argument#{@expected_arity == 1 ? '' : 's'}" + end + + def with_keywords_string + kw_str = case @expected_keywords.count + when 1 + @expected_keywords.first.inspect + when 2 + @expected_keywords.map(&:inspect).join(' and ') + else + "#{@expected_keywords[0...-1].map(&:inspect).join(', ')}, and #{@expected_keywords.last.inspect}" + end + + "keyword#{@expected_keywords.count == 1 ? '' : 's'} #{kw_str}" + end + + def pp_names + @names.length == 1 ? "##{@names.first}" : description_of(@names) + end + + # @private + class ArityCheck + def initialize(expected_arity, expected_keywords, arbitrary_keywords, unlimited_arguments) + expectation = Support::MethodSignatureExpectation.new + + if expected_arity.is_a?(Range) + expectation.min_count = expected_arity.min + expectation.max_count = expected_arity.max + else + expectation.min_count = expected_arity + end + + expectation.keywords = expected_keywords + expectation.expect_unlimited_arguments = unlimited_arguments + expectation.expect_arbitrary_keywords = arbitrary_keywords + @expectation = expectation + end + + def matches?(actual, name) + return true if @expectation.empty? + verifier_for(actual, name).with_expectation(@expectation).valid? + end + + def verifier_for(actual, name) + Support::StrictSignatureVerifier.new(method_signature_for(actual, name)) + end + + def method_signature_for(actual, name) + method_handle = Support.method_handle_for(actual, name) + + if name == :new && method_handle.owner === ::Class && ::Class === actual + Support::MethodSignature.new(actual.instance_method(:initialize)) + else + Support::MethodSignature.new(method_handle) + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/satisfy.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/satisfy.rb new file mode 100644 index 00000000..a50967bf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/satisfy.rb @@ -0,0 +1,62 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `satisfy`. + # Not intended to be instantiated directly. + class Satisfy < BaseMatcher + def initialize(description=nil, &block) + @description = description + @block = block + end + + # @private + def matches?(actual, &block) + @block = block if block + @actual = actual + @block.call(actual) + end + + # @private + def description + @description ||= "satisfy #{block_representation}" + end + + # @api private + # @return [String] + def failure_message + "expected #{actual_formatted} to #{description}" + end + + # @api private + # @return [String] + def failure_message_when_negated + "expected #{actual_formatted} not to #{description}" + end + + private + + if RSpec::Support::RubyFeatures.ripper_supported? + def block_representation + if (block_snippet = extract_block_snippet) + "expression `#{block_snippet}`" + else + 'block' + end + end + + def extract_block_snippet + return nil unless @block + Expectations::BlockSnippetExtractor.try_extracting_single_line_body_of(@block, matcher_name) + end + else + # :nocov: + def block_representation + 'block' + end + # :nocov: + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/start_or_end_with.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/start_or_end_with.rb new file mode 100644 index 00000000..81f06c28 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/start_or_end_with.rb @@ -0,0 +1,94 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Base class for the `end_with` and `start_with` matchers. + # Not intended to be instantiated directly. + class StartOrEndWith < BaseMatcher + def initialize(*expected) + @actual_does_not_have_ordered_elements = false + @expected = expected.length == 1 ? expected.first : expected + end + + # @api private + # @return [String] + def failure_message + super.tap do |msg| + if @actual_does_not_have_ordered_elements + msg << ", but it does not have ordered elements" + elsif !actual.respond_to?(:[]) + msg << ", but it cannot be indexed using #[]" + end + end + end + + # @api private + # @return [String] + def description + return super unless Hash === expected + english_name = EnglishPhrasing.split_words(self.class.matcher_name) + description_of_expected = surface_descriptions_in(expected).inspect + "#{english_name} #{description_of_expected}" + end + + private + + def match(_expected, actual) + return false unless actual.respond_to?(:[]) + + begin + return true if subsets_comparable? && subset_matches? + element_matches? + rescue ArgumentError + @actual_does_not_have_ordered_elements = true + return false + end + end + + def subsets_comparable? + # Structs support the Enumerable interface but don't really have + # the semantics of a subset of a larger set... + return false if Struct === expected + + expected.respond_to?(:length) + end + end + + # For RSpec 3.1, the base class was named `StartAndEndWith`. For SemVer reasons, + # we still provide this constant until 4.0. + # @deprecated Use StartOrEndWith instead. + # @private + StartAndEndWith = StartOrEndWith + + # @api private + # Provides the implementation for `start_with`. + # Not intended to be instantiated directly. + class StartWith < StartOrEndWith + private + + def subset_matches? + values_match?(expected, actual[0, expected.length]) + end + + def element_matches? + values_match?(expected, actual[0]) + end + end + + # @api private + # Provides the implementation for `end_with`. + # Not intended to be instantiated directly. + class EndWith < StartOrEndWith + private + + def subset_matches? + values_match?(expected, actual[-expected.length, expected.length]) + end + + def element_matches? + values_match?(expected, actual[-1]) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/throw_symbol.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/throw_symbol.rb new file mode 100644 index 00000000..e1bb4c55 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/throw_symbol.rb @@ -0,0 +1,138 @@ +module RSpec + module Matchers + module BuiltIn + # @api private + # Provides the implementation for `throw_symbol`. + # Not intended to be instantiated directly. + class ThrowSymbol + include Composable + + def initialize(expected_symbol=nil, expected_arg=nil) + @expected_symbol = expected_symbol + @expected_arg = expected_arg + @caught_symbol = @caught_arg = nil + end + + # rubocop:disable Metrics/MethodLength + # @private + def matches?(given_proc) + @block = given_proc + return false unless Proc === given_proc + + begin + if @expected_symbol.nil? + given_proc.call + else + @caught_arg = catch :proc_did_not_throw_anything do + catch @expected_symbol do + given_proc.call + throw :proc_did_not_throw_anything, :nothing_thrown + end + end + + if @caught_arg == :nothing_thrown + @caught_arg = nil + else + @caught_symbol = @expected_symbol + end + end + + # Ruby 1.8 uses NameError with `symbol' + # Ruby 1.9 uses ArgumentError with :symbol + rescue NameError, ArgumentError => e + unless (match_data = e.message.match(/uncaught throw (`|\:)([a-zA-Z0-9_]*)(')?/)) + other_exception = e + raise + end + @caught_symbol = match_data.captures[1].to_sym + rescue => other_exception + raise + ensure + # rubocop:disable Lint/EnsureReturn + unless other_exception + if @expected_symbol.nil? + return !!@caught_symbol + else + if @expected_arg.nil? + return @caught_symbol == @expected_symbol + else + return (@caught_symbol == @expected_symbol) && values_match?(@expected_arg, @caught_arg) + end + end + end + # rubocop:enable Lint/EnsureReturn + end + end + # rubocop:enable Metrics/MethodLength + + def does_not_match?(given_proc) + !matches?(given_proc) && Proc === given_proc + end + + # @api private + # @return [String] + def failure_message + "expected #{expected} to be thrown, #{actual_result}" + end + + # @api private + # @return [String] + def failure_message_when_negated + "expected #{expected('no Symbol')}#{' not' if @expected_symbol} to be thrown, #{actual_result}" + end + + # @api private + # @return [String] + def description + "throw #{expected}" + end + + # @api private + # Indicates this matcher matches against a block. + # @return [True] + def supports_block_expectations? + true + end + + # @api private + def supports_value_expectations? + false + end + + # @api private + def expects_call_stack_jump? + true + end + + private + + def actual_result + return "but was not a block" unless Proc === @block + "got #{caught}" + end + + def expected(symbol_desc='a Symbol') + throw_description(@expected_symbol || symbol_desc, @expected_arg) + end + + def caught + throw_description(@caught_symbol || 'nothing', @caught_arg) + end + + def throw_description(symbol, arg) + symbol_description = symbol.is_a?(String) ? symbol : description_of(symbol) + + arg_description = if arg + " with #{description_of arg}" + elsif @expected_arg && @caught_symbol == @expected_symbol + " with no argument" + else + "" + end + + symbol_description + arg_description + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/yield.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/yield.rb new file mode 100644 index 00000000..c443dc03 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/built_in/yield.rb @@ -0,0 +1,375 @@ +require 'rspec/matchers/built_in/count_expectation' + +RSpec::Support.require_rspec_support 'method_signature_verifier' + +module RSpec + module Matchers + module BuiltIn + # @private + # Object that is yielded to `expect` when one of the + # yield matchers is used. Provides information about + # the yield behavior of the object-under-test. + class YieldProbe + def self.probe(block, &callback) + probe = new(block, &callback) + return probe unless probe.has_block? + probe.probe + end + + attr_accessor :num_yields, :yielded_args + + def initialize(block, &callback) + @block = block + @callback = callback || Proc.new {} + @used = false + self.num_yields = 0 + self.yielded_args = [] + end + + def has_block? + Proc === @block + end + + def probe + assert_valid_expect_block! + @block.call(self) + assert_used! + self + end + + def to_proc + @used = true + + probe = self + callback = @callback + Proc.new do |*args| + probe.num_yields += 1 + probe.yielded_args << args + callback.call(*args) + nil # to indicate the block does not return a meaningful value + end + end + + def single_yield_args + yielded_args.first + end + + def yielded_once?(matcher_name) + case num_yields + when 1 then true + when 0 then false + else + raise "The #{matcher_name} matcher is not designed to be used with a " \ + 'method that yields multiple times. Use the yield_successive_args ' \ + 'matcher for that case.' + end + end + + def assert_used! + return if @used + raise 'You must pass the argument yielded to your expect block on ' \ + 'to the method-under-test as a block. It acts as a probe that ' \ + 'allows the matcher to detect whether or not the method-under-test ' \ + 'yields, and, if so, how many times, and what the yielded arguments ' \ + 'are.' + end + + if RUBY_VERSION.to_f > 1.8 + def assert_valid_expect_block! + block_signature = RSpec::Support::BlockSignature.new(@block) + return if RSpec::Support::StrictSignatureVerifier.new(block_signature, [self]).valid? + raise 'Your expect block must accept an argument to be used with this ' \ + 'matcher. Pass the argument as a block on to the method you are testing.' + end + else + # :nocov: + # On 1.8.7, `lambda { }.arity` and `lambda { |*a| }.arity` both return -1, + # so we can't distinguish between accepting no args and an arg splat. + # It's OK to skip, this, though; it just provides a nice error message + # when the user forgets to accept an arg in their block. They'll still get + # the `assert_used!` error message from above, which is sufficient. + def assert_valid_expect_block! + # nothing to do + end + # :nocov: + end + end + + # @api private + # Provides the implementation for `yield_control`. + # Not intended to be instantiated directly. + class YieldControl < BaseMatcher + include CountExpectation + # @private + def matches?(block) + @probe = YieldProbe.probe(block) + return false unless @probe.has_block? + expected_count_matches?(@probe.num_yields) + end + + # @private + def does_not_match?(block) + !matches?(block) && @probe.has_block? + end + + # @api private + # @return [String] + def failure_message + 'expected given block to yield control' + failure_reason + end + + # @api private + # @return [String] + def failure_message_when_negated + 'expected given block not to yield control' + failure_reason + end + + # @private + def supports_block_expectations? + true + end + + # @private + def supports_value_expectations? + false + end + + private + + def failure_reason + return ' but was not a block' unless @probe.has_block? + return "#{count_expectation_description} but did not yield" if @probe.num_yields == 0 + count_failure_reason('yielded') + end + end + + # @api private + # Provides the implementation for `yield_with_no_args`. + # Not intended to be instantiated directly. + class YieldWithNoArgs < BaseMatcher + # @private + def matches?(block) + @probe = YieldProbe.probe(block) + return false unless @probe.has_block? + @probe.yielded_once?(:yield_with_no_args) && @probe.single_yield_args.empty? + end + + # @private + def does_not_match?(block) + !matches?(block) && @probe.has_block? + end + + # @private + def failure_message + "expected given block to yield with no arguments, but #{positive_failure_reason}" + end + + # @private + def failure_message_when_negated + "expected given block not to yield with no arguments, but #{negative_failure_reason}" + end + + # @private + def supports_block_expectations? + true + end + + # @private + def supports_value_expectations? + false + end + + private + + def positive_failure_reason + return 'was not a block' unless @probe.has_block? + return 'did not yield' if @probe.num_yields.zero? + "yielded with arguments: #{description_of @probe.single_yield_args}" + end + + def negative_failure_reason + return 'was not a block' unless @probe.has_block? + 'did' + end + end + + # @api private + # Provides the implementation for `yield_with_args`. + # Not intended to be instantiated directly. + class YieldWithArgs < BaseMatcher + def initialize(*args) + @expected = args + end + + # @private + def matches?(block) + @args_matched_when_yielded = true + @probe = YieldProbe.new(block) do + @actual = @probe.single_yield_args + @actual_formatted = actual_formatted + @args_matched_when_yielded &&= args_currently_match? + end + return false unless @probe.has_block? + @probe.probe + @probe.yielded_once?(:yield_with_args) && @args_matched_when_yielded + end + + # @private + def does_not_match?(block) + !matches?(block) && @probe.has_block? + end + + # @private + def failure_message + "expected given block to yield with arguments, but #{positive_failure_reason}" + end + + # @private + def failure_message_when_negated + "expected given block not to yield with arguments, but #{negative_failure_reason}" + end + + # @private + def description + desc = 'yield with args' + desc = "#{desc}(#{expected_arg_description})" unless @expected.empty? + desc + end + + # @private + def supports_block_expectations? + true + end + + # @private + def supports_value_expectations? + false + end + + private + + def positive_failure_reason + return 'was not a block' unless @probe.has_block? + return 'did not yield' if @probe.num_yields.zero? + @positive_args_failure + end + + def expected_arg_description + @expected.map { |e| description_of e }.join(', ') + end + + def negative_failure_reason + if !@probe.has_block? + 'was not a block' + elsif @args_matched_when_yielded && !@expected.empty? + 'yielded with expected arguments' \ + "\nexpected not: #{surface_descriptions_in(@expected).inspect}" \ + "\n got: #{@actual_formatted}" + else + 'did' + end + end + + def args_currently_match? + if @expected.empty? # expect {...}.to yield_with_args + @positive_args_failure = 'yielded with no arguments' if @actual.empty? + return !@actual.empty? + end + + unless (match = all_args_match?) + @positive_args_failure = 'yielded with unexpected arguments' \ + "\nexpected: #{surface_descriptions_in(@expected).inspect}" \ + "\n got: #{@actual_formatted}" + end + + match + end + + def all_args_match? + values_match?(@expected, @actual) + end + end + + # @api private + # Provides the implementation for `yield_successive_args`. + # Not intended to be instantiated directly. + class YieldSuccessiveArgs < BaseMatcher + def initialize(*args) + @expected = args + end + + # @private + def matches?(block) + @actual_formatted = [] + @actual = [] + args_matched_when_yielded = true + yield_count = 0 + + @probe = YieldProbe.probe(block) do |*arg_array| + arg_or_args = arg_array.size == 1 ? arg_array.first : arg_array + @actual_formatted << RSpec::Support::ObjectFormatter.format(arg_or_args) + @actual << arg_or_args + args_matched_when_yielded &&= values_match?(@expected[yield_count], arg_or_args) + yield_count += 1 + end + + return false unless @probe.has_block? + args_matched_when_yielded && yield_count == @expected.length + end + + def does_not_match?(block) + !matches?(block) && @probe.has_block? + end + + # @private + def failure_message + 'expected given block to yield successively with arguments, ' \ + "but #{positive_failure_reason}" + end + + # @private + def failure_message_when_negated + 'expected given block not to yield successively with arguments, ' \ + "but #{negative_failure_reason}" + end + + # @private + def description + "yield successive args(#{expected_arg_description})" + end + + # @private + def supports_block_expectations? + true + end + + # @private + def supports_value_expectations? + false + end + + private + + def expected_arg_description + @expected.map { |e| description_of e }.join(', ') + end + + def positive_failure_reason + return 'was not a block' unless @probe.has_block? + + 'yielded with unexpected arguments' \ + "\nexpected: #{surface_descriptions_in(@expected).inspect}" \ + "\n got: [#{@actual_formatted.join(", ")}]" + end + + def negative_failure_reason + return 'was not a block' unless @probe.has_block? + + 'yielded with expected arguments' \ + "\nexpected not: #{surface_descriptions_in(@expected).inspect}" \ + "\n got: [#{@actual_formatted.join(", ")}]" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/composable.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/composable.rb new file mode 100644 index 00000000..e4816e99 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/composable.rb @@ -0,0 +1,171 @@ +RSpec::Support.require_rspec_support "fuzzy_matcher" + +module RSpec + module Matchers + # Mixin designed to support the composable matcher features + # of RSpec 3+. Mix it into your custom matcher classes to + # allow them to be used in a composable fashion. + # + # @api public + module Composable + # Creates a compound `and` expectation. The matcher will + # only pass if both sub-matchers pass. + # This can be chained together to form an arbitrarily long + # chain of matchers. + # + # @example + # expect(alphabet).to start_with("a").and end_with("z") + # expect(alphabet).to start_with("a") & end_with("z") + # + # @note The negative form (`expect(...).not_to matcher.and other`) + # is not supported at this time. + def and(matcher) + BuiltIn::Compound::And.new self, matcher + end + alias & and + + # Creates a compound `or` expectation. The matcher will + # pass if either sub-matcher passes. + # This can be chained together to form an arbitrarily long + # chain of matchers. + # + # @example + # expect(stoplight.color).to eq("red").or eq("green").or eq("yellow") + # expect(stoplight.color).to eq("red") | eq("green") | eq("yellow") + # + # @note The negative form (`expect(...).not_to matcher.or other`) + # is not supported at this time. + def or(matcher) + BuiltIn::Compound::Or.new self, matcher + end + alias | or + + # Delegates to `#matches?`. Allows matchers to be used in composable + # fashion and also supports using matchers in case statements. + def ===(value) + matches?(value) + end + + private + + # This provides a generic way to fuzzy-match an expected value against + # an actual value. It understands nested data structures (e.g. hashes + # and arrays) and is able to match against a matcher being used as + # the expected value or within the expected value at any level of + # nesting. + # + # Within a custom matcher you are encouraged to use this whenever your + # matcher needs to match two values, unless it needs more precise semantics. + # For example, the `eq` matcher _does not_ use this as it is meant to + # use `==` (and only `==`) for matching. + # + # @param expected [Object] what is expected + # @param actual [Object] the actual value + # + # @!visibility public + def values_match?(expected, actual) + expected = with_matchers_cloned(expected) + Support::FuzzyMatcher.values_match?(expected, actual) + end + + # Returns the description of the given object in a way that is + # aware of composed matchers. If the object is a matcher with + # a `description` method, returns the description; otherwise + # returns `object.inspect`. + # + # You are encouraged to use this in your custom matcher's + # `description`, `failure_message` or + # `failure_message_when_negated` implementation if you are + # supporting matcher arguments. + # + # @!visibility public + def description_of(object) + RSpec::Support::ObjectFormatter.format(object) + end + + # Transforms the given data structure (typically a hash or array) + # into a new data structure that, when `#inspect` is called on it, + # will provide descriptions of any contained matchers rather than + # the normal `#inspect` output. + # + # You are encouraged to use this in your custom matcher's + # `description`, `failure_message` or + # `failure_message_when_negated` implementation if you are + # supporting any arguments which may be a data structure + # containing matchers. + # + # @!visibility public + def surface_descriptions_in(item) + if Matchers.is_a_describable_matcher?(item) + DescribableItem.new(item) + elsif Hash === item + Hash[surface_descriptions_in(item.to_a)] + elsif Struct === item || unreadable_io?(item) + RSpec::Support::ObjectFormatter.format(item) + elsif should_enumerate?(item) + item.map { |subitem| surface_descriptions_in(subitem) } + else + item + end + end + + # @private + # Historically, a single matcher instance was only checked + # against a single value. Given that the matcher was only + # used once, it's been common to memoize some intermediate + # calculation that is derived from the `actual` value in + # order to reuse that intermediate result in the failure + # message. + # + # This can cause a problem when using such a matcher as an + # argument to another matcher in a composed matcher expression, + # since the matcher instance may be checked against multiple + # values and produce invalid results due to the memoization. + # + # To deal with this, we clone any matchers in `expected` via + # this method when using `values_match?`, so that any memoization + # does not "leak" between checks. + def with_matchers_cloned(object) + if Matchers.is_a_matcher?(object) + object.clone + elsif Hash === object + Hash[with_matchers_cloned(object.to_a)] + elsif should_enumerate?(object) + object.map { |subobject| with_matchers_cloned(subobject) } + else + object + end + end + + # @api private + # We should enumerate arrays as long as they are not recursive. + def should_enumerate?(item) + Array === item && item.none? { |subitem| subitem.equal?(item) } + end + + # @api private + def unreadable_io?(object) + return false unless IO === object + object.each {} # STDOUT is enumerable but raises an error + false + rescue IOError + true + end + module_function :surface_descriptions_in, :should_enumerate?, :unreadable_io? + + # Wraps an item in order to surface its `description` via `inspect`. + # @api private + DescribableItem = Struct.new(:item) do + # Inspectable version of the item description + def inspect + "(#{item.description})" + end + + # A pretty printed version of the item description. + def pretty_print(pp) + pp.text "(#{item.description})" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/dsl.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/dsl.rb new file mode 100644 index 00000000..4905dd8e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/dsl.rb @@ -0,0 +1,546 @@ +RSpec::Support.require_rspec_support "with_keywords_when_needed" + +module RSpec + module Matchers + # Defines the custom matcher DSL. + module DSL + # Defines a matcher alias. The returned matcher's `description` will be overridden + # to reflect the phrasing of the new name, which will be used in failure messages + # when passed as an argument to another matcher in a composed matcher expression. + # + # @example + # RSpec::Matchers.alias_matcher :a_list_that_sums_to, :sum_to + # sum_to(3).description # => "sum to 3" + # a_list_that_sums_to(3).description # => "a list that sums to 3" + # + # @example + # RSpec::Matchers.alias_matcher :a_list_sorted_by, :be_sorted_by do |description| + # description.sub("be sorted by", "a list sorted by") + # end + # + # be_sorted_by(:age).description # => "be sorted by age" + # a_list_sorted_by(:age).description # => "a list sorted by age" + # + # @param new_name [Symbol] the new name for the matcher + # @param old_name [Symbol] the original name for the matcher + # @param options [Hash] options for the aliased matcher + # @option options [Class] :klass the ruby class to use as the decorator. (Not normally used). + # @yield [String] optional block that, when given, is used to define the overridden + # logic. The yielded arg is the original description or failure message. If no + # block is provided, a default override is used based on the old and new names. + # @see RSpec::Matchers + def alias_matcher(new_name, old_name, options={}, &description_override) + description_override ||= lambda do |old_desc| + old_desc.gsub(EnglishPhrasing.split_words(old_name), EnglishPhrasing.split_words(new_name)) + end + klass = options.fetch(:klass) { AliasedMatcher } + + define_method(new_name) do |*args, &block| + matcher = __send__(old_name, *args, &block) + matcher.matcher_name = new_name if matcher.respond_to?(:matcher_name=) + klass.new(matcher, description_override) + end + ruby2_keywords new_name if respond_to?(:ruby2_keywords, true) + end + + # Defines a negated matcher. The returned matcher's `description` and `failure_message` + # will be overridden to reflect the phrasing of the new name, and the match logic will + # be based on the original matcher but negated. + # + # @example + # RSpec::Matchers.define_negated_matcher :exclude, :include + # include(1, 2).description # => "include 1 and 2" + # exclude(1, 2).description # => "exclude 1 and 2" + # + # @param negated_name [Symbol] the name for the negated matcher + # @param base_name [Symbol] the name of the original matcher that will be negated + # @yield [String] optional block that, when given, is used to define the overridden + # logic. The yielded arg is the original description or failure message. If no + # block is provided, a default override is used based on the old and new names. + # @see RSpec::Matchers + def define_negated_matcher(negated_name, base_name, &description_override) + alias_matcher(negated_name, base_name, :klass => AliasedNegatedMatcher, &description_override) + end + + # Defines a custom matcher. + # + # @param name [Symbol] the name for the matcher + # @yield [Object] block that is used to define the matcher. + # The block is evaluated in the context of your custom matcher class. + # When args are passed to your matcher, they will be yielded here, + # usually representing the expected value(s). + # @see RSpec::Matchers + def define(name, &declarations) + warn_about_block_args(name, declarations) + define_method name do |*expected, &block_arg| + RSpec::Matchers::DSL::Matcher.new(name, declarations, self, *expected, &block_arg) + end + end + alias_method :matcher, :define + + private + + if Proc.method_defined?(:parameters) + def warn_about_block_args(name, declarations) + declarations.parameters.each do |type, arg_name| + next unless type == :block + RSpec.warning("Your `#{name}` custom matcher receives a block argument (`#{arg_name}`), " \ + "but due to limitations in ruby, RSpec cannot provide the block. Instead, " \ + "use the `block_arg` method to access the block") + end + end + else + # :nocov: + def warn_about_block_args(*) + # There's no way to detect block params on 1.8 since the method reflection APIs don't expose it + end + # :nocov: + end + + RSpec.configure { |c| c.extend self } if RSpec.respond_to?(:configure) + + # Contains the methods that are available from within the + # `RSpec::Matchers.define` DSL for creating custom matchers. + module Macros + # Stores the block that is used to determine whether this matcher passes + # or fails. The block should return a boolean value. When the matcher is + # passed to `expect(...).to` and the block returns `true`, then the expectation + # passes. Similarly, when the matcher is passed to `expect(...).not_to` and the + # block returns `false`, then the expectation passes. + # + # @example + # + # RSpec::Matchers.define :be_even do + # match do |actual| + # actual.even? + # end + # end + # + # expect(4).to be_even # passes + # expect(3).not_to be_even # passes + # expect(3).to be_even # fails + # expect(4).not_to be_even # fails + # + # By default the match block will swallow expectation errors (e.g. + # caused by using an expectation such as `expect(1).to eq 2`), if you + # wish to allow these to bubble up, pass in the option + # `:notify_expectation_failures => true`. + # + # @param [Hash] options for defining the behavior of the match block. + # @yield [Object] actual the actual value (i.e. the value wrapped by `expect`) + def match(options={}, &match_block) + define_user_override(:matches?, match_block) do |actual| + @actual = actual + RSpec::Support.with_failure_notifier(RAISE_NOTIFIER) do + begin + super(*actual_arg_for(match_block)) + rescue RSpec::Expectations::ExpectationNotMetError + raise if options[:notify_expectation_failures] + false + end + end + end + end + + # @private + RAISE_NOTIFIER = Proc.new { |err, _opts| raise err } + + # Use this to define the block for a negative expectation (`expect(...).not_to`) + # when the positive and negative forms require different handling. This + # is rarely necessary, but can be helpful, for example, when specifying + # asynchronous processes that require different timeouts. + # + # By default the match block will swallow expectation errors (e.g. + # caused by using an expectation such as `expect(1).to eq 2`), if you + # wish to allow these to bubble up, pass in the option + # `:notify_expectation_failures => true`. + # + # @param [Hash] options for defining the behavior of the match block. + # @yield [Object] actual the actual value (i.e. the value wrapped by `expect`) + def match_when_negated(options={}, &match_block) + define_user_override(:does_not_match?, match_block) do |actual| + begin + @actual = actual + RSpec::Support.with_failure_notifier(RAISE_NOTIFIER) do + super(*actual_arg_for(match_block)) + end + rescue RSpec::Expectations::ExpectationNotMetError + raise if options[:notify_expectation_failures] + false + end + end + end + + # Use this instead of `match` when the block will raise an exception + # rather than returning false to indicate a failure. + # + # @example + # + # RSpec::Matchers.define :accept_as_valid do |candidate_address| + # match_unless_raises ValidationException do |validator| + # validator.validate(candidate_address) + # end + # end + # + # expect(email_validator).to accept_as_valid("person@company.com") + # + # @yield [Object] actual the actual object (i.e. the value wrapped by `expect`) + def match_unless_raises(expected_exception=Exception, &match_block) + define_user_override(:matches?, match_block) do |actual| + @actual = actual + begin + super(*actual_arg_for(match_block)) + rescue expected_exception => @rescued_exception + false + else + true + end + end + end + + # Customizes the failure message to use when this matcher is + # asked to positively match. Only use this when the message + # generated by default doesn't suit your needs. + # + # @example + # + # RSpec::Matchers.define :have_strength do |expected| + # match { your_match_logic } + # + # failure_message do |actual| + # "Expected strength of #{expected}, but had #{actual.strength}" + # end + # end + # + # @yield [Object] actual the actual object (i.e. the value wrapped by `expect`) + def failure_message(&definition) + define_user_override(__method__, definition) + end + + # Customize the failure message to use when this matcher is asked + # to negatively match. Only use this when the message generated by + # default doesn't suit your needs. + # + # @example + # + # RSpec::Matchers.define :have_strength do |expected| + # match { your_match_logic } + # + # failure_message_when_negated do |actual| + # "Expected not to have strength of #{expected}, but did" + # end + # end + # + # @yield [Object] actual the actual object (i.e. the value wrapped by `expect`) + def failure_message_when_negated(&definition) + define_user_override(__method__, definition) + end + + # Customize the description to use for one-liners. Only use this when + # the description generated by default doesn't suit your needs. + # + # @example + # + # RSpec::Matchers.define :qualify_for do |expected| + # match { your_match_logic } + # + # description do + # "qualify for #{expected}" + # end + # end + # + # @yield [Object] actual the actual object (i.e. the value wrapped by `expect`) + def description(&definition) + define_user_override(__method__, definition) + end + + # Tells the matcher to diff the actual and expected values in the failure + # message. + def diffable + define_method(:diffable?) { true } + end + + # Declares that the matcher can be used in a block expectation. + # Users will not be able to use your matcher in a block + # expectation without declaring this. + # (e.g. `expect { do_something }.to matcher`). + def supports_block_expectations + define_method(:supports_block_expectations?) { true } + end + + # Convenience for defining methods on this matcher to create a fluent + # interface. The trick about fluent interfaces is that each method must + # return self in order to chain methods together. `chain` handles that + # for you. If the method is invoked and the + # `include_chain_clauses_in_custom_matcher_descriptions` config option + # hash been enabled, the chained method name and args will be added to the + # default description and failure message. + # + # In the common case where you just want the chained method to store some + # value(s) for later use (e.g. in `match`), you can provide one or more + # attribute names instead of a block; the chained method will store its + # arguments in instance variables with those names, and the values will + # be exposed via getters. + # + # @example + # + # RSpec::Matchers.define :have_errors_on do |key| + # chain :with do |message| + # @message = message + # end + # + # match do |actual| + # actual.errors[key] == @message + # end + # end + # + # expect(minor).to have_errors_on(:age).with("Not old enough to participate") + def chain(method_name, *attr_names, &definition) + unless block_given? ^ attr_names.any? + raise ArgumentError, "You must pass either a block or some attribute names (but not both) to `chain`." + end + + definition = assign_attributes(attr_names) if attr_names.any? + + define_user_override(method_name, definition) do |*args, &block| + super(*args, &block) + @chained_method_clauses.push([method_name, args]) + self + end + end + + def assign_attributes(attr_names) + attr_reader(*attr_names) + private(*attr_names) + + lambda do |*attr_values| + attr_names.zip(attr_values) do |attr_name, attr_value| + instance_variable_set(:"@#{attr_name}", attr_value) + end + end + end + + # assign_attributes isn't defined in the private section below because + # that makes MRI 1.9.2 emit a warning about private attributes. + private :assign_attributes + + private + + # Does the following: + # + # - Defines the named method using a user-provided block + # in @user_method_defs, which is included as an ancestor + # in the singleton class in which we eval the `define` block. + # - Defines an overridden definition for the same method + # usign the provided `our_def` block. + # - Provides a default `our_def` block for the common case + # of needing to call the user's definition with `@actual` + # as an arg, but only if their block's arity can handle it. + # + # This compiles the user block into an actual method, allowing + # them to use normal method constructs like `return` + # (e.g. for an early guard statement), while allowing us to define + # an override that can provide the wrapped handling + # (e.g. assigning `@actual`, rescueing errors, etc) and + # can `super` to the user's definition. + def define_user_override(method_name, user_def, &our_def) + @user_method_defs.__send__(:define_method, method_name, &user_def) + our_def ||= lambda { super(*actual_arg_for(user_def)) } + define_method(method_name, &our_def) + end + + # Defines deprecated macro methods from RSpec 2 for backwards compatibility. + # @deprecated Use the methods from {Macros} instead. + module Deprecated + # @deprecated Use {Macros#match} instead. + def match_for_should(&definition) + RSpec.deprecate("`match_for_should`", :replacement => "`match`") + match(&definition) + end + + # @deprecated Use {Macros#match_when_negated} instead. + def match_for_should_not(&definition) + RSpec.deprecate("`match_for_should_not`", :replacement => "`match_when_negated`") + match_when_negated(&definition) + end + + # @deprecated Use {Macros#failure_message} instead. + def failure_message_for_should(&definition) + RSpec.deprecate("`failure_message_for_should`", :replacement => "`failure_message`") + failure_message(&definition) + end + + # @deprecated Use {Macros#failure_message_when_negated} instead. + def failure_message_for_should_not(&definition) + RSpec.deprecate("`failure_message_for_should_not`", :replacement => "`failure_message_when_negated`") + failure_message_when_negated(&definition) + end + end + end + + # Defines default implementations of the matcher + # protocol methods for custom matchers. You can + # override any of these using the {RSpec::Matchers::DSL::Macros Macros} methods + # from within an `RSpec::Matchers.define` block. + module DefaultImplementations + include BuiltIn::BaseMatcher::DefaultFailureMessages + + # @api private + # Used internally by objects returns by `should` and `should_not`. + def diffable? + false + end + + # The default description. + def description + english_name = EnglishPhrasing.split_words(name) + expected_list = EnglishPhrasing.list(expected) + "#{english_name}#{expected_list}#{chained_method_clause_sentences}" + end + + # Matchers do not support block expectations by default. You + # must opt-in. + def supports_block_expectations? + false + end + + def supports_value_expectations? + true + end + + # Most matchers do not expect call stack jumps. + def expects_call_stack_jump? + false + end + + private + + def chained_method_clause_sentences + return '' unless Expectations.configuration.include_chain_clauses_in_custom_matcher_descriptions? + + @chained_method_clauses.map do |(method_name, method_args)| + english_name = EnglishPhrasing.split_words(method_name) + arg_list = EnglishPhrasing.list(method_args) + " #{english_name}#{arg_list}" + end.join + end + end + + # The class used for custom matchers. The block passed to + # `RSpec::Matchers.define` will be evaluated in the context + # of the singleton class of an instance, and will have the + # {RSpec::Matchers::DSL::Macros Macros} methods available. + class Matcher + # Provides default implementations for the matcher protocol methods. + include DefaultImplementations + + # Allows expectation expressions to be used in the match block. + include RSpec::Matchers + + # Supports the matcher composability features of RSpec 3+. + include Composable + + # Makes the macro methods available to an `RSpec::Matchers.define` block. + extend Macros + extend Macros::Deprecated + + # Exposes the value being matched against -- generally the object + # object wrapped by `expect`. + attr_reader :actual + + # Exposes the exception raised during the matching by `match_unless_raises`. + # Could be useful to extract details for a failure message. + attr_reader :rescued_exception + + # The block parameter used in the expectation + attr_reader :block_arg + + # The name of the matcher. + attr_reader :name + + # @api private + def initialize(name, declarations, matcher_execution_context, *expected, &block_arg) + @name = name + @actual = nil + @expected_as_array = expected + @matcher_execution_context = matcher_execution_context + @chained_method_clauses = [] + @block_arg = block_arg + + klass = + class << self + # See `Macros#define_user_override` above, for an explanation. + include(@user_method_defs = Module.new) + self + end + RSpec::Support::WithKeywordsWhenNeeded.class_exec(klass, *expected, &declarations) + end + + # Provides the expected value. This will return an array if + # multiple arguments were passed to the matcher; otherwise it + # will return a single value. + # @see #expected_as_array + def expected + if expected_as_array.size == 1 + expected_as_array[0] + else + expected_as_array + end + end + + # Returns the expected value as an an array. This exists primarily + # to aid in upgrading from RSpec 2.x, since in RSpec 2, `expected` + # always returned an array. + # @see #expected + attr_reader :expected_as_array + + # Adds the name (rather than a cryptic hex number) + # so we can identify an instance of + # the matcher in error messages (e.g. for `NoMethodError`) + def inspect + "#<#{self.class.name} #{name}>" + end + + if RUBY_VERSION.to_f >= 1.9 + # Indicates that this matcher responds to messages + # from the `@matcher_execution_context` as well. + # Also, supports getting a method object for such methods. + def respond_to_missing?(method, include_private=false) + super || @matcher_execution_context.respond_to?(method, include_private) + end + else # for 1.8.7 + # :nocov: + # Indicates that this matcher responds to messages + # from the `@matcher_execution_context` as well. + def respond_to?(method, include_private=false) + super || @matcher_execution_context.respond_to?(method, include_private) + end + # :nocov: + end + + private + + def actual_arg_for(block) + block.arity.zero? ? [] : [@actual] + end + + # Takes care of forwarding unhandled messages to the + # `@matcher_execution_context` (typically the current + # running `RSpec::Core::Example`). This is needed by + # rspec-rails so that it can define matchers that wrap + # Rails' test helper methods, but it's also a useful + # feature in its own right. + def method_missing(method, *args, &block) + if @matcher_execution_context.respond_to?(method) + @matcher_execution_context.__send__ method, *args, &block + else + super(method, *args, &block) + end + end + # The method_missing method should be refactored to pass kw args in RSpec 4 + # then this can be removed + ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/english_phrasing.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/english_phrasing.rb new file mode 100644 index 00000000..05b69bd9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/english_phrasing.rb @@ -0,0 +1,60 @@ +module RSpec + module Matchers + # Facilitates converting ruby objects to English phrases. + module EnglishPhrasing + # Converts a symbol into an English expression. + # + # split_words(:banana_creme_pie) #=> "banana creme pie" + # + def self.split_words(sym) + sym.to_s.tr('_', ' ') + end + + # @note The returned string has a leading space except + # when given an empty list. + # + # Converts an object (often a collection of objects) + # into an English list. + # + # list(['banana', 'kiwi', 'mango']) + # #=> " \"banana\", \"kiwi\", and \"mango\"" + # + # Given an empty collection, returns the empty string. + # + # list([]) #=> "" + # + def self.list(obj) + return " #{RSpec::Support::ObjectFormatter.format(obj)}" if !obj || Struct === obj || Hash === obj + items = Array(obj).map { |w| RSpec::Support::ObjectFormatter.format(w) } + case items.length + when 0 + "" + when 1 + " #{items[0]}" + when 2 + " #{items[0]} and #{items[1]}" + else + " #{items[0...-1].join(', ')}, and #{items[-1]}" + end + end + + if RUBY_VERSION == '1.8.7' + # Not sure why, but on travis on 1.8.7 we have gotten these warnings: + # lib/rspec/matchers/english_phrasing.rb:28: warning: default `to_a' will be obsolete + # So it appears that `Array` can trigger that (e.g. by calling `to_a` on the passed object?) + # So here we replace `Kernel#Array` with our own warning-free implementation for 1.8.7. + # @private + # rubocop:disable Naming/MethodName + # :nocov: + def self.Array(obj) + case obj + when Array then obj + else [obj] + end + end + # :nocov: + # rubocop:enable Naming/MethodName + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/fail_matchers.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/fail_matchers.rb new file mode 100644 index 00000000..bdd7cda0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/fail_matchers.rb @@ -0,0 +1,42 @@ +require 'rspec/expectations' + +module RSpec + module Matchers + # Matchers for testing RSpec matchers. Include them with: + # + # require 'rspec/matchers/fail_matchers' + # RSpec.configure do |config| + # config.include RSpec::Matchers::FailMatchers + # end + # + module FailMatchers + # Matches if an expectation fails + # + # @example + # expect { some_expectation }.to fail + def fail(&block) + raise_error(RSpec::Expectations::ExpectationNotMetError, &block) + end + + # Matches if an expectation fails with the provided message + # + # @example + # expect { some_expectation }.to fail_with("some failure message") + # expect { some_expectation }.to fail_with(/some failure message/) + def fail_with(message) + raise_error(RSpec::Expectations::ExpectationNotMetError, message) + end + + # Matches if an expectation fails including the provided message + # + # @example + # expect { some_expectation }.to fail_including("portion of some failure message") + def fail_including(*snippets) + raise_error( + RSpec::Expectations::ExpectationNotMetError, + a_string_including(*snippets) + ) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/generated_descriptions.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/generated_descriptions.rb new file mode 100644 index 00000000..cbf37519 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/generated_descriptions.rb @@ -0,0 +1,41 @@ +module RSpec + module Matchers + class << self + # @private + attr_accessor :last_matcher, :last_expectation_handler + end + + # @api private + # Used by rspec-core to clear the state used to generate + # descriptions after an example. + def self.clear_generated_description + self.last_matcher = nil + self.last_expectation_handler = nil + end + + # @api private + # Generates an an example description based on the last expectation. + # Used by rspec-core's one-liner syntax. + def self.generated_description + return nil if last_expectation_handler.nil? + "#{last_expectation_handler.verb} #{last_description}" + end + + # @private + def self.last_description + last_matcher.respond_to?(:description) ? last_matcher.description : <<-MESSAGE +When you call a matcher in an example without a String, like this: + +specify { expect(object).to matcher } + +or this: + +it { is_expected.to matcher } + +RSpec expects the matcher to have a #description method. You should either +add a String to the example this matcher is being used in, or give it a +description method. Then you won't have to suffer this lengthy warning again. +MESSAGE + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/matcher_delegator.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/matcher_delegator.rb new file mode 100644 index 00000000..b957b4ff --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/matcher_delegator.rb @@ -0,0 +1,61 @@ +module RSpec + module Matchers + # Provides a base class with as little methods as possible, so that + # most methods can be delegated via `method_missing`. + # + # On Ruby 2.0+ BasicObject could be used for this purpose, but it + # introduce some extra complexity with constant resolution, so the + # BlankSlate pattern was prefered. + # @private + class BaseDelegator + kept_methods = [ + # Methods that raise warnings if removed. + :__id__, :__send__, :object_id, + + # Methods that are explicitly undefined in some subclasses. + :==, :===, + + # Methods we keep on purpose. + :class, :respond_to?, :__method__, :method, :dup, + :clone, :initialize_dup, :initialize_copy, :initialize_clone, + ] + instance_methods.each do |method| + unless kept_methods.include?(method.to_sym) + undef_method(method) + end + end + end + + # Provides the necessary plumbing to wrap a matcher with a decorator. + # @private + class MatcherDelegator < BaseDelegator + include Composable + attr_reader :base_matcher + + def initialize(base_matcher) + @base_matcher = base_matcher + end + + def method_missing(*args, &block) + base_matcher.__send__(*args, &block) + end + + if ::RUBY_VERSION.to_f > 1.8 + def respond_to_missing?(name, include_all=false) + super || base_matcher.respond_to?(name, include_all) + end + else + # :nocov: + def respond_to?(name, include_all=false) + super || base_matcher.respond_to?(name, include_all) + end + # :nocov: + end + + def initialize_copy(other) + @base_matcher = @base_matcher.clone + super + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/matcher_protocol.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/matcher_protocol.rb new file mode 100644 index 00000000..4a87f648 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/matcher_protocol.rb @@ -0,0 +1,105 @@ +module RSpec + module Matchers + # rspec-expectations can work with any matcher object that implements this protocol. + # + # @note This class is not loaded at runtime by rspec-expectations. It exists + # purely to provide documentation for the matcher protocol. + class MatcherProtocol + # @!group Required Methods + + # @!method matches?(actual) + # @param actual [Object] The object being matched against. + # @yield For an expression like `expect(x).to matcher do...end`, the `do/end` + # block binds to `to`. It passes that block, if there is one, on to this method. + # @return [Boolean] true if this matcher matches the provided object. + + # @!method failure_message + # This will only be called if {#matches?} returns false. + # @return [String] Explanation for the failure. + + # @!endgroup + + # @!group Optional Methods + + # @!method does_not_match?(actual) + # In a negative expectation such as `expect(x).not_to foo`, RSpec will + # call `foo.does_not_match?(x)` if this method is defined. If it's not + # defined it will fall back to using `!foo.matches?(x)`. This allows you + # to provide custom logic for the negative case. + # + # @param actual [Object] The object being matched against. + # @yield For an expression like `expect(x).not_to matcher do...end`, the `do/end` + # block binds to `not_to`. It passes that block, if there is one, on to this method. + # @return [Boolean] true if this matcher does not match the provided object. + + # @!method failure_message_when_negated + # This will only be called when a negative match fails. + # @return [String] Explanation for the failure. + # @note This method is listed as optional because matchers do not have to + # support negation. But if your matcher does support negation, this is a + # required method -- otherwise, you'll get a `NoMethodError`. + + # @!method description + # The description is used for two things: + # + # * When using RSpec's one-liner syntax + # (e.g. `it { is_expected.to matcher }`), the description + # is used to generate the example's doc string since you + # have not provided one. + # * In a composed matcher expression, the description is used + # as part of the failure message (and description) of the outer + # matcher. + # + # @return [String] Description of the matcher. + + # @!method supports_block_expectations? + # Indicates that this matcher can be used in a block expectation expression, + # such as `expect { foo }.to raise_error`. Generally speaking, this is + # only needed for matchers which operate on a side effect of a block, rather + # than on a particular object. + # @return [Boolean] true if this matcher can be used in block expressions. + # @note If not defined, RSpec assumes a value of `false` for this method. + + # @!method supports_value_expectations? + # Indicates that this matcher can be used in a value expectation expression, + # such as `expect(foo).to eq(bar)`. + # @return [Boolean] true if this matcher can be used in value expressions. + # @note If not defined, RSpec assumes a value of `true` for this method. + + # @!method expects_call_stack_jump? + # Indicates that when this matcher is used in a block expectation + # expression, it expects the block to use a ruby construct that causes + # a call stack jump (such as raising an error or throwing a symbol). + # + # This is used internally for compound block expressions, as matchers + # which expect call stack jumps must be treated with care to work properly. + # + # @return [Boolean] true if the matcher expects a call stack jump + # + # @note This method is very rarely used or needed. + # @note If not defined, RSpec assumes a value of `false` for this method. + + # @!method diffable? + # @return [Boolean] true if `actual` and `expected` can be diffed. + # Indicates that this matcher provides `actual` and `expected` attributes, + # and that the values returned by these can be usefully diffed, which can + # be included in the output. + + # @!method actual + # @return [String, Object] If an object (rather than a string) is provided, + # RSpec will use the `pp` library to convert it to multi-line output in + # order to diff. + # The actual value for the purposes of a diff. + # @note This method is required if `diffable?` returns true. + + # @!method expected + # @return [String, Object] If an object (rather than a string) is provided, + # RSpec will use the `pp` library to convert it to multi-line output in + # order to diff. + # The expected value for the purposes of a diff. + # @note This method is required if `diffable?` returns true. + + # @!endgroup + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/multi_matcher_diff.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/multi_matcher_diff.rb new file mode 100644 index 00000000..cd2264e2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-expectations-3.13.5/lib/rspec/matchers/multi_matcher_diff.rb @@ -0,0 +1,82 @@ +module RSpec + module Matchers + # @api private + # Handles list of expected and actual value pairs when there is a need + # to render multiple diffs. Also can handle one pair. + class MultiMatcherDiff + # @private + # Default diff label when there is only one matcher in diff + # output + DEFAULT_DIFF_LABEL = "Diff:".freeze + + # @private + # Maximum readable matcher description length + DESCRIPTION_MAX_LENGTH = 65 + + def initialize(expected_list) + @expected_list = expected_list + end + + # @api private + # Wraps provided expected value in instance of + # MultiMatcherDiff. If provided value is already an + # MultiMatcherDiff then it just returns it. + # @param [Any] expected value to be wrapped + # @param [Any] actual value + # @return [RSpec::Matchers::MultiMatcherDiff] + def self.from(expected, actual) + return expected if self === expected + new([[expected, DEFAULT_DIFF_LABEL, actual]]) + end + + # @api private + # Wraps provided matcher list in instance of + # MultiMatcherDiff. + # @param [Array] matchers list of matchers to wrap + # @return [RSpec::Matchers::MultiMatcherDiff] + def self.for_many_matchers(matchers) + new(matchers.map { |m| [m.expected, diff_label_for(m), m.actual] }) + end + + # @api private + # Returns message with diff(s) appended for provided differ + # factory and actual value if there are any + # @param [String] message original failure message + # @param [Proc] differ + # @return [String] + def message_with_diff(message, differ) + diff = diffs(differ) + message = "#{message}\n#{diff}" unless diff.empty? + message + end + + private + + class << self + private + + def diff_label_for(matcher) + "Diff for (#{truncated(RSpec::Support::ObjectFormatter.format(matcher))}):" + end + + def truncated(description) + return description if description.length <= DESCRIPTION_MAX_LENGTH + description[0...DESCRIPTION_MAX_LENGTH - 3] << "..." + end + end + + def diffs(differ) + @expected_list.map do |(expected, diff_label, actual)| + diff = differ.diff(actual, expected) + next if diff.strip.empty? + if diff == "\e[0m\n\e[0m" + "#{diff_label}\n" \ + " " + else + "#{diff_label}#{diff}" + end + end.compact.join("\n") + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/.document b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/.document new file mode 100644 index 00000000..52a564f6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/.document @@ -0,0 +1,5 @@ +lib/**/*.rb +- +README.md +LICENSE.md +Changelog.md diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/.yardopts b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/.yardopts new file mode 100644 index 00000000..9555b8e5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/.yardopts @@ -0,0 +1,6 @@ +--exclude features +--no-private +--markup markdown +- +Changelog.md +LICENSE.md diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/Changelog.md b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/Changelog.md new file mode 100644 index 00000000..f326ed9d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/Changelog.md @@ -0,0 +1,1329 @@ +### Development +[Full Changelog](https://github.com/rspec/rspec/compare/rspec-mocks-v3.13.5...3-13-maintenance) + +### 3.13.5 / 2025-05-27 +[Full Changelog](https://github.com/rspec/rspec/compare/rspec-mocks-v3.13.4...rspec-mocks-v3.13.5) + +Bug Fixes: + +* Fix regression where a previous fix (rspec/rspec#214) would leave behind thread data + between tests. (Jon Rowe, rspec/rspec#219) +* Fix links in gemspec to point to monorepo / homepage. (Jon Rowe) + +### 3.13.4 / 2025-05-05 +[Full Changelog](https://github.com/rspec/rspec/compare/rspec-mocks-v3.13.3...rspec-mocks-v3.13.4) + +Bug Fixes: + +* Fix regression where nested stubbed method calls would inadvertently not be counted. + (Jon Rowe, rspec/rspec#214) +* Fix regression where keyword arguments would not be passed through to nested stubbed + method calls. (Jon Rowe, rspec/rspec#214) + +### 3.13.3 / 2025-05-01 +[Full Changelog](https://github.com/rspec/rspec/compare/rspec-mocks-v3.13.2...rspec-mocks-v3.13.3) + +Bug Fixes: + +* When stubbing methods using the `expect_any_instance_of` or `allow_any_instance_of` + ensure the stubbed method has the same visibility as the real method. + (Jon Rowe, rspec/rspec-mocks#1596) +* Prevent recursive calls to stubbed methods during stub invocation. + (James Dabbs, rspec/rspec#116, rspec/rspec#156) + +### 3.13.2 / 2024-10-02 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.13.1...v3.13.2) + +Bug Fixes: + +* Support keyword arguments in callables passed to `and_invoke`. (Jon Rowe, rspec/rspec-mocks#1595) + +### 3.13.1 / 2024-05-08 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.13.0...v3.13.1) + +Bug Fixes: + +* Use `RSpec::Support::Mutex` in `RSpec::Mocks::Proxy` to avoid issues from + stubbing `::Mutex#new`. (Eric Mueller, rspec/rspec-mocks#1575) + +### 3.13.0 / 2024-02-04 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.12.7...v3.13.0) + +Enhancements: + +* Add an `array_excluding` matcher for arguments. (Zane Wolfgang Pickett, rspec/rspec-mocks#1528) + +### 3.12.7 / 2024-02-04 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.12.6...v3.12.7) + +Bug Fixes: + +* Reduce allocations from "any_instance" style mocks. (Carlos Palhares, rspec/rspec-mocks#1479) + +### 3.12.6 / 2023-07-11 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.12.5...v3.12.6) + +Bug Fixes: + +* Fix an issue with `and_call_original` when using the `method_missing` fallback + with keyword arguments. (Igor Drozdov, rspec/rspec-mocks#1552) + +### 3.12.5 / 2023-03-30 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.12.4...v3.12.5) + +Bug Fixes: + +* Fix compatibility issue with Rails where active_support monkey patches `with` + when using any instance. (Lachlan Sylvester, rspec/rspec-mocks#1540) + +### 3.12.4 / 2023-03-12 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.12.3...v3.12.4) + +Bug Fixes: + +* Fix an issue with asserting that Array#reverse is never called. (Brad Trick, rspec/rspec-mocks#1533) +* Fix compatibility issue with Rails where active_support monkey patches `with`. + (Jean Boussier, rspec/rspec-mocks#1531, rspec/rspec-mocks#1534) + +### 3.12.3 / 2023-01-17 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.12.2...v3.12.3) + +Bug Fixes: + +* Fix keyword delegation in `send` for verifying doubles on Ruby 3. + (Charlie Honig, rspec/rspec-mocks#1485) + +### 3.12.2 / 2023-01-07 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.12.1...v3.12.2) + +Bug Fixes: + +* Fix implementation blocks for mocks using keyword arguments on Ruby 3.2.0. + (Adam Steel, rspec/rspec-mocks#1508) +* Fix keyword argument assertions when mocking using `with` on Ruby 3.2.0. + (Slava Kardakov, Benoit Tigeot, Phil Pirozhkov, Benoit Daloze, rspec/rspec-mocks#1514) + +### 3.12.1 / 2022-12-10 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.12.0...v3.12.1) + +Bug Fixes: + +* Remove empty diff marker when a diff only contains console codes. (Jon Rowe, rspec/rspec-mocks#1506) +* Show keyword vs hash diff marker when arguments are not `==` (Jon Rowe, rspec/rspec-mocks#1506) +* Change check to detect frozen objects to rescue errors rather than + pre-empting by checking `frozen?` due to some objects mis-behaving. + (Keegan Roth, rspec/rspec-mocks#1401) +* Prevent unfulfilled expectations using `expect_any_instance_of` across a class + inheritance boundary from raising rather than failing. (Jon Rowe, rspec/rspec-mocks#1496) +* Prevent a misleading error message when using `allow(...).not_to` with + unsupported matchers. (Phil Pirozhkov, rspec/rspec-mocks#1503) + +### 3.12.0 / 2022-10-26 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.11.2...v3.12.0) + +Enhancements: + +* Improve diff output when diffing keyword arguments against hashes. + (Jean Boussier, rspec/rspec-mocks#1461) + +### 3.11.2 / 2022-10-25 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.11.1...v3.11.2) + +Bug Fixes: + +* Use the original implementation of `Class.new` to detect overridden definitions + of `new` rather than the owner, fixing detection of "double aliased" methods + in Ruby 3 and above. (Benoit Daloze, rspec/rspec-mocks#1470, rspec/rspec-mocks#1476) +* Support keyword argument semantics when constraining argument expectations using + `with` on Ruby 3.0+ with `instance_double` (Andrii Malyshko, rspec/rspec-mocks#1473) + +### 3.11.1 / 2022-03-31 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.11.0...v3.11.1) + +Bug Fixes: + +* Add extra `ruby2_keywords` calls to properly designate methods using + `*args` to pass keyword around, fixes an issue with TruffleRuby. + (Benoit Daloze, rspec/rspec-mocks#1464) + +### 3.11.0 / 2022-02-09 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.10.3...v3.11.0) + +Enhancements: + +* Add `and_invoke` implementation for configuring responses to `receive` + (and `receive_messages`) with multiple callable objects. (Kyle Smith, rspec/rspec-mocks#1411) + +### 3.10.3 / 2022-01-28 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.10.2...v3.10.3) + +Bug Fixes: + +* Suppress warning by setting `$VERBOSE` to nil. (Nobuyoshi Nakada, rspec/rspec-mocks#1414) +* Support keyword argument semantics when constraining argument expectations using + `with` on Ruby 3.0+ (Yusuke Endoh, rspec/rspec-mocks#1394) + +### 3.10.2 / 2021-01-27 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.10.1...v3.10.2) + +Bug Fixes: + +* Support keyword arguments with `and_call_original` on Ruby 3.0. + (Bryan Powell, rspec/rspec-mocks#1385) +* `RSpec::Mocks::Constant#previously_defined?` is now always a boolean. + (Phil Pirozhkov, rspec/rspec-mocks#1397) +* Support keyword arguments on Ruby 3.0 when used with `expect_any_instance_of` + or `allow_any_instance_of` with `and_call_original`. + (Jess Hottenstein, rspec/rspec-mocks#1407) + +### 3.10.1 / 2020-12-27 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.10.0...v3.10.1) + +Bug Fixes: + +* Issue `ArgumentError` rather than `TypeError` when unsupported methods on + unsupported objects are attempted to be stubbed. (@zhisme, rspec/rspec-mocks#1357) + +### 3.10.0 / 2020-10-30 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.9.1...v3.10.0) + +Enhancements: +* Add the ability to set a custom error generator in `MessageExpectation`. + This will allow rspec-expectations to inject a custom failure message. + (Benoit Tigeot and Nicolas Zermati, rspec/rspec-mocks#1312) +* Return the result of the block passed to `RSpec::Mocks.with_temporary_scope` + when block run. (@expeehaa, rspec/rspec-mocks#1329) + +### 3.9.1 / 2019-12-31 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.9.0...v3.9.1) + +Bug Fixes: + +* Trigger `RSpec::Mocks.configuration.verifying_double_callbacks` when using + `allow_any_instance_of` or `expect_any_instance_of` (Daniel Orner, rspec/rspec-mocks#1309) + +### 3.9.0 / 2019-10-07 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.8.2...v3.9.0) + +Enhancements: + +* Improve thread safety of message expectations by using Mutex to prevent + deadlocking errors. (Ry Biesemeyer, rspec/rspec-mocks#1236) +* Add the ability to use `time` as an alias for `times`. For example: + `expect(Class).to receive(:method).exactly(1).time`. + (Pistos, Benoit Tigeot, rspec/rspec-mocks#1271) + +### 3.8.2 / 2019-10-02 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.8.1...v3.8.2) + +* Allow `array_including` argument matchers to be nested. + (Emmanuel Delmas, rspec/rspec-mocks#1291) + +### 3.8.1 / 2019-06-13 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.8.0...v3.8.1) + +Bug Fixes: + +* Ensure stubbing methods does not change their visibility. + (Kevin Boschert, rspec/rspec-mocks#1277) + +### 3.8.0 / 2018-08-04 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.7.0...v3.8.0) + +Bug Fixes: + +* Issue error when encountering invalid "counted" negative message expectations. + (Sergiy Yarinovskiy, rspec/rspec-mocks#1212) +* Ensure `allow_any_instance_of` and `expect_any_instance_of` can be temporarily + supressed. (Jon Rowe, rspec/rspec-mocks#1228) +* Ensure `expect_any_instance_of(double).to_not have_received(:some_method)` + fails gracefully (as its not supported) rather than issuing a `NoMethodError`. + (Maxim Krizhanovsky, rspec/rspec-mocks#1231) + +### 3.7.0 / 2017-10-17 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.6.0...v3.7.0) + +Enhancements: + +* Improve compatibility with `--enable-frozen-string-literal` option + on Ruby 2.3+. (Pat Allan, rspec/rspec-mocks#1165) + +Bug Fixes: + +* Fix `hash_including` and `hash_excluding` so that they work against + subclasses of `Hash`. (Aaron Rosenberg, rspec/rspec-mocks#1167) + +### 3.6.0 / 2017-05-04 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.6.0.beta2...v3.6.0) + +Bug Fixes: + +* Fix "instance variable @color not initialized" warning when using + rspec-mocks without rspec-core. (Myron Marston, rspec/rspec-mocks#1142) +* Restore aliased module methods properly when stubbing on 1.8.7. + (Samuel Giddins, rspec/rspec-mocks#1144) +* Allow a message chain expectation to be constrained by argument(s). + (Jon Rowe, rspec/rspec-mocks#1156) + +### 3.6.0.beta2 / 2016-12-12 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.6.0.beta1...v3.6.0.beta2) + +Enhancements: + +* Add new `without_partial_double_verification { }` API that lets you + temporarily turn off partial double verification for an example. + (Jon Rowe, rspec/rspec-mocks#1104) + +### 3.6.0.beta1 / 2016-10-09 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.5.0...v3.6.0.beta1) + +Bug Fixes: + +* Return the test double instance form `#freeze` (Alessandro Berardi, rspec/rspec-mocks#1109) +* Allow the special logic for stubbing `new` to work when `.method` has + been redefined. (Proby, rspec/rspec-mocks#1119) + +### 3.5.0 / 2016-07-01 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.5.0.beta4...v3.5.0) + +Enhancements: + +* Provides a nice string representation of + `RSpec::Mocks::MessageExpectation` (Myron Marston, rspec/rspec-mocks#1095) + +### 3.5.0.beta4 / 2016-06-05 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.5.0.beta3...v3.5.0.beta4) + +Enhancements: + +* Add `and_throw` to any instance handling. (Tobias Bühlmann, rspec/rspec-mocks#1068) + +### 3.5.0.beta3 / 2016-04-02 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.5.0.beta2...v3.5.0.beta3) + +Enhancements: + +* Issue warning when attempting to use unsupported + `allow(...).to receive(...).ordered`. (Jon Rowe, rspec/rspec-mocks#1000) +* Add `rspec/mocks/minitest_integration`, to properly integrate rspec-mocks + with minitest. (Myron Marston, rspec/rspec-mocks#1065) + +### 3.5.0.beta2 / 2016-03-10 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.5.0.beta1...v3.5.0.beta2) + +Enhancements: + +* Improve error message displayed when using `and_wrap_original` on pure test + doubles. (betesh, rspec/rspec-mocks#1063) + +Bug Fixes: + +* Fix issue that prevented `receive_message_chain(...).with(...)` working + correctly on "any instance" mocks. (Jon Rowe, rspec/rspec-mocks#1061) + +### 3.5.0.beta1 / 2016-02-06 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.4.1...v3.5.0.beta1) + +Bug Fixes: + +* Allow `any_instance_of(...).to receive(...)` to use `and_yield` multiple + times. (Kilian Cirera Sant, rspec/rspec-mocks#1054) +* Allow matchers which inherit from `rspec-mocks` matchers to be used for + `allow`. (Andrew Kozin, rspec/rspec-mocks#1056) +* Prevent stubbing `respond_to?` on partial doubles from causing infinite + recursion. (Jon Rowe, rspec/rspec-mocks#1013) +* Prevent aliased methods from disapearing after being mocked with + `any_instance` (regression from rspec/rspec-mocks#1043). (Joe Rafaniello, rspec/rspec-mocks#1060) + +### 3.4.1 / 2016-01-10 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.4.0...v3.4.1) + +Bug Fixes: + +* Fix `any_instance` to work properly on Ruby 2.3. (Joe Rafaniello, rspec/rspec-mocks#1043) + +### 3.4.0 / 2015-11-11 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.3.2...v3.4.0) + +Enhancements: + +* Make `expect(...).to have_received` work without relying upon + rspec-expectations. (Myron Marston, rspec/rspec-mocks#978) +* Add option for failing tests when expectations are set on `nil`. + (Liz Rush, rspec/rspec-mocks#983) + +Bug Fixes: + +* Fix `have_received { ... }` so that any block passed when the message + was received is forwarded to the `have_received` block. (Myron Marston, rspec/rspec-mocks#1006) +* Fix infinite loop in error generator when stubbing `respond_to?`. + (Alex Dowad, rspec/rspec-mocks#1022) +* Fix issue with using `receive` on subclasses (at a class level) with 1.8.7. + (Alex Dowad, rspec/rspec-mocks#1026) + +### 3.3.2 / 2015-07-15 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.3.1...v3.3.2) + +Bug Fixes: + +* Prevent thread deadlock errors during proxy creation (e.g. when using + `before_verifying_doubles` callbacks). (Jon Rowe, rspec/rspec-mocks#980, rspec/rspec-mocks#979) + +### 3.3.1 / 2015-06-19 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.3.0...v3.3.1) + +Bug Fixes: + +* Fix bug in `before_verifying_double` callback logic that caused it to be called + once for each class in the ancestor list when mocking or stubbing a class. Now + it is only called for the mocked or stubbed class, as you would expect. (Sam + Phippen, rspec/rspec-mocks#974) + +### 3.3.0 / 2015-06-12 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.2.1...v3.3.0) + +Enhancements: + +* When stubbing `new` on `MyClass` or `class_double(MyClass)`, use the + method signature from `MyClass#initialize` to verify arguments. + (Myron Marston, rspec/rspec-mocks#886) +* Use matcher descriptions when generating description of received arguments + for mock expectation failures. (Tim Wade, rspec/rspec-mocks#891) +* Avoid loading `stringio` unnecessarily. (Myron Marston, rspec/rspec-mocks#894) +* Verifying doubles failure messages now distinguish between class and instance + level methods. (Tim Wade, rspec/rspec-mocks#896, rspec/rspec-mocks#908) +* Improve mock expectation failure messages so that it combines both + number of times and the received arguments in the output. (John Ceh, rspec/rspec-mocks#918) +* Improve how test doubles are represented in failure messages. + (Siva Gollapalli, Myron Marston, rspec/rspec-mocks#932) +* Rename `RSpec::Mocks::Configuration#when_declaring_verifying_double` to + `RSpec::Mocks::Configuration#before_verifying_doubles` and utilise when + verifying partial doubles. (Jon Rowe, rspec/rspec-mocks#940) +* Use rspec-support's `ObjectFormatter` for improved formatting of + arguments in failure messages so that, for example, full time + precisions is displayed for time objects. (Gavin Miller, Myron Marston, rspec/rspec-mocks#955) + +Bug Fixes: + +* Ensure expectations that raise eagerly also raise during RSpec verification. + This means that if exceptions are caught inside test execution the test will + still fail. (Sam Phippen, rspec/rspec-mocks#884) +* Fix `have_received(msg).with(args).exactly(n).times` and + `receive(msg).with(args).exactly(n).times` failure messages + for when the message was received the wrong number of times with + the specified args, and also received additional times with other + arguments. Previously it confusingly listed the arguments as being + mis-matched (even when the double was allowed to receive with any + args) rather than listing the count. (John Ceh, rspec/rspec-mocks#918) +* Fix `any_args`/`anything` support so that we avoid calling `obj == anything` + on user objects that may have improperly implemented `==` in a way that + raises errors. (Myron Marston, rspec/rspec-mocks#924) +* Fix edge case involving stubbing the same method on a class and a subclass + which previously hit a `NoMethodError` internally in RSpec. (Myron Marston rspec/rspec-mocks#954) +* Fix edge case where the message received count would be incremented multiple + times for one failure. (Myron Marston, rspec/rspec-mocks#957) +* Fix failure messages for when spies received the expected message with + different arguments and also received another message. (Maurício Linhares, rspec/rspec-mocks#960) +* Silence whitespace-only diffs. (Myron Marston, rspec/rspec-mocks#969) + +### 3.2.1 / 2015-02-23 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.2.0...v3.2.1) + +Bug Fixes: + +* Add missing `rspec/support/differ` require so that rspec-mocks can be + used w/o rspec-expectations (which also loads the differ and hided the + fact we forgot to require it). (Myron Marston, rspec/rspec-mocks#893) +* Revert tracking of received arg mutation (added in 3.2.0 to provide an + error in a situation we can't support) as our implementation has side + effects on non-standard objects and there's no solution we could come + up with that always works. (Myron Marston, rspec/rspec-mocks#900) + +### 3.2.0 / 2015-02-03 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.1.3...v3.2.0) + +Enhancements: + +* Treat `any_args` as an arg splat, allowing it to match an arbitrary + number of args at any point in an arg list. (Myron Marston, rspec/rspec-mocks#786) +* Print diffs when arguments in mock expectations are mismatched. + (Sam Phippen, rspec/rspec-mocks#751) +* Support names for verified doubles (`instance_double`, `instance_spy`, + `class_double`, `class_spy`, `object_double`, `object_spy`). (Cezary + Baginski, rspec/rspec-mocks#826) +* Make `array_including` and `hash_including` argument matchers composable. + (Sam Phippen, rspec/rspec-mocks#819) +* Make `allow_any_instance_of(...).to receive(...).and_wrap_original` + work. (Ryan Fitzgerald, rspec/rspec-mocks#869) + +Bug Fixes: + +* Provide a clear error when users wrongly combine `no_args` with + additional arguments (e.g. `expect().to receive().with(no_args, 1)`). + (Myron Marston, rspec/rspec-mocks#786) +* Provide a clear error when users wrongly use `any_args` multiple times in the + same argument list (e.g. `expect().to receive().with(any_args, 1, any_args)`. + (Myron Marston, rspec/rspec-mocks#786) +* Prevent the error generator from using user object #description methods. + See [rspec/rspec-mocks#685](https://github.com/rspec/rspec-mocks/issues/685). + (Sam Phippen, rspec/rspec-mocks#751) +* Make verified doubles declared as `(instance|class)_double(SomeConst)` + work properly when `SomeConst` has previously been stubbed. + `(instance|class)_double("SomeClass")` already worked properly. + (Myron Marston, rspec/rspec-mocks#824) +* Add a matcher description for `receive`, `receive_messages` and + `receive_message_chain`. (Myron Marston, rspec/rspec-mocks#828) +* Validate invocation args for null object verified doubles. + (Myron Marston, rspec/rspec-mocks#829) +* Fix `RSpec::Mocks::Constant.original` when called with an invalid + constant to return an object indicating the constant name is invalid, + rather than blowing up. (Myron Marston, rspec/rspec-mocks#833) +* Make `extend RSpec::Mocks::ExampleMethods` on any object work properly + to add the rspec-mocks API to that object. Previously, `expect` would + be undefined. (Myron Marston, rspec/rspec-mocks#846) +* Fix `require 'rspec/mocks/standalone'` so that it only affects `main` + and not every object. It's really only intended to be used in a REPL + like IRB, but some gems have loaded it, thinking it needs to be loaded + when using rspec-mocks outside the context of rspec-core. + (Myron Marston, rspec/rspec-mocks#846) +* Prevent message expectations from being modified by customization methods + (e.g. `with`) after they have been invoked. (Sam Phippen and Melanie Gilman, rspec/rspec-mocks#837) +* Handle cases where a method stub cannot be removed due to something + external to RSpec monkeying with the method definition. This can + happen, for example, when you `file.reopen(io)` after previously + stubbing a method on the `file` object. (Myron Marston, rspec/rspec-mocks#853) +* Provide a clear error when received message args are mutated before + a `have_received(...).with(...)` expectation. (Myron Marston, rspec/rspec-mocks#868) + +### 3.1.3 / 2014-10-08 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.1.2...v3.1.3) + +Bug Fixes: + +* Correct received messages count when used with `have_received` matcher. + (Jon Rowe, rspec/rspec-mocks#793) +* Provide a clear error message when you use `allow_any_instance_of(...)` or + `expect_any_instance_of(...)` with the `have_received` matcher (they are + not intended to be used together and previously caused an odd internal + failure in rspec-mocks). (Jon Rowe, rspec/rspec-mocks#799). +* Fix verified double `with` verification so that it applies to method + stubs. (Myron Marston, rspec/rspec-mocks#790) + +### 3.1.2 / 2014-09-26 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.1.1...v3.1.2) + +Bug Fixes: + +* Provide a clear error message when you use `allow(...)` with the + `have_received` matcher (they are not intended to be used together + and previously caused an odd internal failure in rspec-mocks). (Jon Rowe, rspec/rspec-mocks#788). + +### 3.1.1 / 2014-09-18 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.1.0...v3.1.1) + +Bug Fixes: + +* Prevent included modules being detected as prepended modules on Ruby 2.0 + when using `any_instance_of(...)`. (Tony Novak, rspec/rspec-mocks#781) + +### 3.1.0 / 2014-09-04 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.4...v3.1.0) + +Enhancements: + +* Add spying methods (`spy`, `ìnstance_spy`, `class_spy` and `object_spy`) + which create doubles as null objects for use with spying in testing. (Sam + Phippen, rspec/rspec-mocks#671) +* `have_received` matcher will raise "does not implement" errors correctly when + used with verifying doubles and partial doubles. (Xavier Shay, rspec/rspec-mocks#722) +* Allow matchers to be used in place of keyword arguments in `with` + expectations. (Xavier Shay, rspec/rspec-mocks#726) +* Add `thrice` modifier to message expectation interface as a synonym + for `exactly(3).times`. (Dennis Taylor, rspec/rspec-mocks#753) +* Add more `thrice` synonyms e.g. `.at_least(:thrice)`, `.at_most(:thrice)`, + `receive(...).thrice` and `have_received(...).thrice`. (Jon Rowe, rspec/rspec-mocks#754) +* Add `and_wrap_original` modifier for partial doubles to mutate the + response from a method. (Jon Rowe, rspec/rspec-mocks#762) + +Bug Fixes: + +* Remove `any_number_of_times` from `any_instance` recorders that were + erroneously causing mention of the method in documentation. (Jon Rowe, rspec/rspec-mocks#760) +* Prevent included modules being detected as prepended modules on Ruby 2.0. + (Eugene Kenny, rspec/rspec-mocks#771) + +### 3.0.4 / 2014-08-14 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.3...v3.0.4) + +Bug Fixes: + +* Restore `kind_of(x)` to match using `arg.kind_of?(x)` (like RSpec 2) + rather than `x === arg`. (Jon Rowe, rspec/rspec-mocks#750) + +### 3.0.3 / 2014-07-21 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.2...v3.0.3) + +Bug Fixes: + +* `have_received` matcher will raise "does not implement" errors correctly when + used with verifying doubles and partial doubles. (Xavier Shay, rspec/rspec-mocks#722) +* Make `double.as_null_object.dup` and `double.as_null_object.clone` + make the copies be null objects. (Myron Marston, rspec/rspec-mocks#732) +* Don't inadvertently define `BasicObject` in 1.8.7. (Chris Griego, rspec/rspec-mocks#739) + +### 3.0.2 / 2014-06-19 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.1...v3.0.2) + +Bug Fixes: + +* Fix edge case that triggered "can't add a new key into hash during + iteration" during mock verification. (Sam Phippen, Myron Marston, rspec/rspec-mocks#711) +* Fix verifying doubles so that when they accidentally leak into another + example, they provide the same clear error message that normal doubles + do. (Myron Marston, rspec/rspec-mocks#718) +* Make `ordered` work with exact receive counts. (Sam Phippen, rspec/rspec-mocks#713) + +### 3.0.1 / 2014-06-07 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.0...v3.0.1) + +Bug Fixes: + +* Fix `receive_message_chain(...)` so that it supports `with` just like + `stub_chain` did. (Jon Rowe, rspec/rspec-mocks#697) +* Fix regression in `expect_any_instance_of` so that it expects the + message on _any_ instance rather than on _every_ instance. + (Myron Marston, rspec/rspec-mocks#699) + +### 3.0.0 / 2014-06-01 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.0.rc1...v3.0.0) + +Bug Fixes: + +* Fix module prepend detection to work properly on ruby 2.0 for a case + where a module is extended onto itself. (Myron Marston) +* Fix `transfer_nested_constants` option so that transferred constants + get properly reset at the end of the example. (Myron Marston) +* Fix `config.transfer_nested_constants = true` so that you don't + erroneously get errors when stubbing a constant that is not a module + or a class. (Myron Marston) +* Fix regression that caused `double(:class => SomeClass)` to later + trigger infinite recursion. (Myron Marston) +* Fix bug in `have_received(...).with(...).ordered` where it was not + taking the args into account when checking the order. (Myron Marston) +* Fix bug in `have_received(...).ordered` where it was wrongly + considering stubs when checking the order. (Myron Marston) +* Message expectation matchers now show descriptions from argument + matchers when their expectations aren't met. (Jon Rowe) +* Display warning when encountering `TypeError` during instance method + staging on 2.0.0-p195, suffers from https://bugs.ruby-lang.org/issues/8686 + too. (Cezar Halmagean). + +### 3.0.0.rc1 / 2014-05-18 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.0.beta2...v3.0.0.rc1) + +Breaking Changes for 3.0.0: + +* Remove `RSpec::Mocks::TestDouble.extend_onto`. (Myron Marston) +* Remove `RSpec::Mocks::ConstantStubber`. (Jon Rowe) +* Make monkey-patch of Marshal to support dumping of stubbed objects opt-in. + (Xavier Shay) + +Enhancements: + +* Instead of crashing when cleaning up stub methods on a frozen object, it now + issues a warning explaining that it's impossible to clean up the stubs. + (Justin Coyne and Sam Phippen) +* Add meaningful descriptions to `anything`, `duck_type` and `instance_of` argument + matchers. (Jon Rowe) + +Bug Fixes: + +* Fix regression introduced in 3.0.0.beta2 that caused + `double.as_null_object.to_str` to return the double rather + than a string. (Myron Marston) +* Fix bug in `expect(dbl).to receive_message_chain(:foo, :bar)` where it was + not setting an expectation for the last message in the chain. + (Jonathan del Strother) +* Allow verifying partial doubles to have private methods stubbed. (Xavier Shay) +* Fix bug with allowing/expecting messages on Class objects which have had + their singleton class prepended to. (Jon Rowe) +* Fix an issue with 1.8.7 not running implementation blocks on partial doubles. + (Maurício Linhares) +* Prevent `StackLevelTooDeep` errors when stubbing an `any_instance` method that's + accessed in `inspect` by providing our own inspect output. (Jon Rowe) +* Fix bug in `any_instance` logic that did not allow you to mock or stub + private methods if `verify_partial_doubles` was configured. (Oren Dobzinski) +* Include useful error message when trying to observe an unimplemented method + on an any instance. (Xavier Shay) +* Fix `and_call_original` to work properly when multiple classes in an + inheritance hierarchy have been stubbed with the same method. (Myron Marston) +* Fix `any_instance` so that it updates existing instances that have + already been stubbed. (Myron Marston) +* Fix verified doubles so that their class name is included in failure + messages. (Myron Marston) +* Fix `expect_any_instance_of` so that when the message is received + on an individual instance that has been directly stubbed, it still + satisfies the expectation. (Sam Phippen, Myron Marston) +* Explicitly disallow using `any_instance` to mock or stub a method + that is defined on a module prepended onto the class. This triggered + `SystemStackError` before and is very hard to support so we are not + supporting it at this time. (Myron Marston) + +### 3.0.0.beta2 / 2014-02-17 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v3.0.0.beta1...v3.0.0.beta2) + +Breaking Changes for 3.0.0: + +* Rename `RSpec::Mocks::Mock` to `RSpec::Mocks::Double`. (Myron Marston) +* Change how to integrate rspec-mocks in other test frameworks. You now + need to include `RSpec::Mocks::ExampleMethods` in your test context. + (Myron Marston) +* Prevent RSpec mocks' doubles and partial doubles from being used outside of + the per-test lifecycle (e.g. from a `before(:all)` hook). (Sam Phippen) +* Remove the `host` argument of `RSpec::Mocks.setup`. Instead + `RSpec::Mocks::ExampleMethods` should be included directly in the scope where + RSpec's mocking capabilities are used. (Sam Phippen) +* Make test doubles raise errors if you attempt to use them after they + get reset, to help surface issues when you accidentally retain + references to test doubles and attempt to reuse them in another + example. (Myron Marston) +* Remove support for `and_return { value }` and `and_return` without arguments. (Yuji Nakayama) + +Enhancements: + +* Add `receive_message_chain` which provides the functionality of the old + `stub_chain` for the new allow/expect syntax. Use it like so: `allow(...).to + receive_message_chain(:foo, :bar, :bazz)`. (Sam Phippen). +* Change argument matchers to use `===` as their primary matching + protocol, since their semantics mirror that of a case or rescue statement + (which uses `===` for matching). (Myron Marston) +* Add `RSpec::Mocks.with_temporary_scope`, which allows you to create + temporary rspec-mocks scopes in arbitrary places (such as a + `before(:all)` hook). (Myron Marston) +* Support keyword arguments when checking arity with verifying doubles. + (Xavier Shay) + +Bug Fixes: + +* Fix regression in 3.0.0.beta1 that caused `double("string_name" => :value)` + to stop working. (Xavier Shay) +* Fix the way rspec-mocks and rspec-core interact so that if users + define a `let` with the same name as one of the methods + from `RSpec::Mocks::ArgumentMatchers`, the user's `let` takes + precedence. (Michi Huber, Myron Marston) +* Fix verified doubles so that their methods match the visibility + (public, protected or private) of the interface they verify + against. (Myron Marston) +* Fix verified null object doubles so that they do not wrongly + report that they respond to anything. They only respond to methods + available on the interface they verify against. (Myron Marston) +* Fix deprecation warning for use of old `:should` syntax w/o explicit + config so that it no longer is silenced by an extension gem such + as rspec-rails when it calls `config.add_stub_and_should_receive_to`. + (Sam Phippen) +* Fix `expect` syntax so that it does not wrongly emit a "You're + overriding a previous implementation for this stub" warning when + you are not actually doing that. (Myron Marston) +* Fix `any_instance.unstub` when used on sub classes for whom the super + class has had `any_instance.stub` invoked on. (Jon Rowe) +* Fix regression in `stub_chain`/`receive_message_chain` that caused + it to raise an `ArgumentError` when passing args to the stubbed + methods. (Sam Phippen) +* Correct stub of undefined parent modules all the way down when stubbing a + nested constant. (Xavier Shay) +* Raise `VerifyingDoubleNotDefinedError` when a constant is not defined for + a verifying class double. (Maurício Linhares) +* Remove `Double#to_str`, which caused confusing `raise some_double` + behavior. (Maurício Linhares) + +### 3.0.0.beta1 / 2013-11-07 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.4...v3.0.0.beta1) + +Breaking Changes for 3.0.0: + +* Raise an explicit error if `should_not_receive(...).and_return` is used. (Sam + Phippen) +* Remove 1.8.6 workarounds. (Jon Rowe) +* Remove `stub!` and `unstub!`. (Sam Phippen) +* Remove `mock(name, methods)` and `stub(name, methods)`, leaving + `double(name, methods)` for creating test doubles. (Sam Phippen, Michi Huber) +* Remove `any_number_of_times` since `should_receive(:msg).any_number_of_times` + is really a stub in a mock's clothing. (Sam Phippen) +* Remove support for re-using the same null-object test double in multiple + examples. Test doubles are designed to only live for one example. + (Myron Marston) +* Make `at_least(0)` raise an error. (Sam Phippen) +* Remove support for `require 'spec/mocks'` which had been kept + in place for backwards compatibility with RSpec 1. (Myron Marston) +* Blocks provided to `with` are always used as implementation. (Xavier Shay) +* The config option (added in 2.99) to yield the receiver to + `any_instance` implementation blocks now defaults to "on". (Sam Phippen) + +Enhancements: + +* Allow the `have_received` matcher to use a block to set further expectations + on arguments. (Tim Cowlishaw) +* Provide `instance_double` and `class_double` to create verifying doubles, + ported from `rspec-fire`. (Xavier Shay) +* `as_null_object` on a verifying double only responds to defined methods. + (Xavier Shay) +* Provide `object_double` to create verified doubles of specific object + instances. (Xavier Shay) +* Provide `verify_partial_doubles` configuration that provides `object_double` + like verification behaviour on partial doubles. (Xavier Shay) +* Improved performance of double creation, particularly those with many + attributes. (Xavier Shay) +* Default value of `transfer_nested_constants` option for constant stubbing can + be configured. (Xavier Shay) +* Messages can be allowed or expected on in bulk via + `receive_messages(:message => :value)`. (Jon Rowe) +* `allow(Klass.any_instance)` and `expect(Klass.any_instance)` now print a + warning. This is usually a mistake, and users usually want + `allow_any_instance_of` or `expect_any_instance_of` instead. (Sam Phippen) +* `instance_double` and `class_double` raise `ArgumentError` if the underlying + module is loaded and the arity of the method being invoked does not match the + arity of the method as it is actually implemented. (Andy Lindeman) +* Spies can now check their invocation ordering is correct. (Jon Rowe) + +Deprecations: + +* Using the old `:should` syntax without explicitly configuring it + is deprecated. It will continue to work but will emit a deprecation + warning in RSpec 3 if you do not explicitly enable it. (Sam Phippen) + +Bug Fixes: + +* Fix `and_call_original` to handle a complex edge case involving + singleton class ancestors. (Marc-André Lafortune, Myron Marston) +* When generating an error message for unexpected arguments, + use `#inspect` rather than `#description` if `#description` + returns `nil` or `''` so that you still get a useful message. + (Nick DeLuca) + +### 2.99.4 / 2015-06-19 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.3...v2.99.4) + +Bug Fixes: + +* Add missing deprecation for using `with` with no arguments e.g. `with()`. (Yousuke, rspec/rspec-mocks#970) + +### 2.99.3 / 2015-01-09 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.2...v2.99.3) + +Bug Fixes: + +* Fix regression that caused an error when a test double was deserialized from YAML. (Yuji Nakayama, rspec/rspec-mocks#777) + +### 2.99.2 / 2014-07-21 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.1...v2.99.2) + +Enhancements: + +* Warn about upcoming change to `#===` matching and `DateTime#===` behaviour. + (Jon Rowe, rspec/rspec-mocks#735) + +### 2.99.1 / 2014-06-12 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.0...v2.99.1) + +Bug Fixes: + +* Fix bug that caused errors at the end of each example + when a `double.as_null_object` had been frozen. (Yuji Nakayama, rspec/rspec-mocks#698) + +Deprecations: + +* Deprecate freezing a test double. (Yuji Nakayama, rspec/rspec-mocks#698) + +### 2.99.0 / 2014-06-01 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.0.rc1...v2.99.0) + +No changes. Just taking it out of pre-release. + +### 2.99.0.rc1 / 2014-05-18 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.0.beta2...v2.99.0.rc1) + +Deprecations: + +* Deprecate `RSpec::Mocks::TestDouble.extend_onto`. (Myron Marston) +* Deprecate `RSpec::Mocks::ConstantStubber`. (Jon Rowe) +* Deprecate `Marshal.dump` monkey-patch without opt-in. (Xavier Shay) + +### 2.99.0.beta2 / 2014-02-17 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.99.0.beta1...v2.99.0.beta2) + +Deprecations: + +* Deprecate `RSpec::Mocks::Mock` in favor of `RSpec::Mocks::Double`. + (Myron Marston) +* Deprecate the `host` argument of `RSpec::Mocks.setup`. Instead + `RSpec::Mocks::ExampleMethods` should be included directly in the scope where + RSpec's mocking capabilities are used. (Sam Phippen) +* Deprecate using any of rspec-mocks' features outside the per-test + lifecycle (e.g. from a `before(:all)` hook). (Myron Marston) +* Deprecate re-using a test double in another example. (Myron Marston) +* Deprecate `and_return { value }` and `and_return` without arguments. (Yuji Nakayama) + +### 2.99.0.beta1 / 2013-11-07 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.4...v2.99.0.beta1) + +Deprecations + +* Expecting to use lambdas or other strong arity implementations for stub + methods with mis-matched arity is deprecated and support for them will be + removed in 3.0. Either provide the right amount of arguments or use a weak + arity implementation (methods with splats or procs). (Jon Rowe) +* Using the same test double instance in multiple examples is deprecated. Test + doubles are only meant to live for one example. The mocks and stubs have + always been reset between examples; however, in 2.x the `as_null_object` + state was not reset and some users relied on this to have a null object + double that is used for many examples. This behavior will be removed in 3.0. + (Myron Marston) +* Print a detailed warning when an `any_instance` implementation block is used + when the new `yield_receiver_to_any_instance_implementation_blocks` config + option is not explicitly set, as RSpec 3.0 will default to enabling this new + feature. (Sam Phippen) + +Enhancements: + +* Add a config option to yield the receiver to `any_instance` implementation + blocks. (Sam Phippen) + +### 2.14.6 / 2014-02-20 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.5...v2.14.6) + +Bug Fixes: + +* Ensure `any_instance` method stubs and expectations are torn down regardless of + expectation failures. (Sam Phippen) + +### 2.14.5 / 2014-02-01 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.4...v2.14.5) + +Bug Fixes: + +* Fix regression that caused block implementations to not receive all + args on 1.8.7 if the block also receives a block, due to Proc#arity + reporting `1` no matter how many args the block receives if it + receives a block, too. (Myron Marston) + +### 2.14.4 / 2013-10-15 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.3...v2.14.4) + +Bug Fixes: + +* Fix issue where unstubing methods on "any instances" would not + remove stubs on existing instances (Jon Rowe) +* Fix issue with receive(:message) do ... end precedence preventing + the usage of modifications (`and_return` etc) (Jon Rowe) + +### 2.14.3 / 2013-08-08 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.2...v2.14.3) + +Bug Fixes: + +* Fix stubbing some instance methods for classes whose hierarchy includes + a prepended Module (Bradley Schaefer) + +### 2.14.2 / 2013-07-30 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.1...v2.14.2) + +Bug Fixes: + +* Fix `as_null_object` doubles so that they return `nil` from `to_ary` + (Jon Rowe). +* Fix regression in 2.14 that made `stub!` (with an implicit receiver) + return a test double rather than stub a method (Myron Marston). + +### 2.14.1 / 2013-07-07 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.0...v2.14.1) + +Bug Fixes: + +* Restore `double.as_null_object` behavior from 2.13 and earlier: a + double's nullness persisted between examples in earlier examples. + While this is not an intended use case (test doubles are meant to live + for only one example), we don't want to break behavior users rely + on in a minor relase. This will be deprecated in 2.99 and removed + in 3.0. (Myron Marston) + +### 2.14.0 / 2013-07-06 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.14.0.rc1...v2.14.0) + +Enhancements: + +* Document test spies in the readme. (Adarsh Pandit) +* Add an `array_including` matcher. (Sam Phippen) +* Add a syntax-agnostic API for mocking or stubbing a method. This is + intended for use by libraries such as rspec-rails that need to mock + or stub a method, and work regardless of the syntax the user has + configured (Paul Annesley, Myron Marston and Sam Phippen). + +Bug Fixes: + +* Fix `double` so that it sets up passed stubs correctly regardless of + the configured syntax (Paul Annesley). +* Allow a block implementation to be used in combination with + `and_yield`, `and_raise`, `and_return` or `and_throw`. This got fixed + in 2.13.1 but failed to get merged into master for the 2.14.0.rc1 + release (Myron Marston). +* `Marshal.dump` does not unnecessarily duplicate objects when rspec-mocks has + not been fully initialized. This could cause errors when using `spork` or + similar preloading gems (Andy Lindeman). + +### 2.14.0.rc1 / 2013-05-27 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.13.0...v2.14.0.rc1) + +Enhancements: + +* Refactor internals so that the mock proxy methods and state are held + outside of the mocked object rather than inside it. This paves the way + for future syntax enhancements and removes the need for some hacky + work arounds for `any_instance` dup'ing and `YAML` serialization, + among other things. Note that the code now relies upon `__id__` + returning a unique, consistent value for any object you want to + mock or stub (Myron Marston). +* Add support for test spies. This allows you to verify a message + was received afterwards using the `have_received` matcher. + Note that you must first stub the method or use a null double. + (Joe Ferris and Joël Quenneville) +* Make `at_least` and `at_most` style receive expectations print that they were + expecting at least or at most some number of calls, rather than just the + number of calls given in the expectation (Sam Phippen) +* Make `with` style receive expectations print the args they were expecting, and + the args that they got (Sam Phippen) +* Fix some warnings seen under ruby 2.0.0p0 (Sam Phippen). +* Add a new `:expect` syntax for message expectations + (Myron Marston and Sam Phippen). + +Bug fixes + +* Fix `any_instance` so that a frozen object can be `dup`'d when methods + have been stubbed on that type using `any_instance` (Jon Rowe). +* Fix `and_call_original` so that it properly raises an `ArgumentError` + when the wrong number of args are passed (Jon Rowe). +* Fix `double` on 1.9.2 so you can wrap them in an Array + using `Array(my_double)` (Jon Rowe). +* Fix `stub_const` and `hide_const` to handle constants that redefine `send` + (Sam Phippen). +* Fix `Marshal.dump` extension so that it correctly handles nil. + (Luke Imhoff, Jon Rowe) +* Fix isolation of `allow_message_expectations_on_nil` (Jon Rowe) +* Use inspect to format actual arguments on expectations in failure messages (rspec/rspec-mocks#280, Ben Langfeld) +* Protect against improperly initialised test doubles (rspec/rspec-mocks#293) (Joseph Shraibman and Jon Rowe) + +Deprecations + +* Deprecate `stub` and `mock` as aliases for `double`. `double` is the + best term for creating a test double, and it reduces confusion to + have only one term (Michi Huber). +* Deprecate `stub!` and `unstub!` in favor of `stub` and `unstub` + (Jon Rowe). +* Deprecate `at_least(0).times` and `any_number_of_times` (Michi Huber). + +### 2.13.1 / 2013-04-06 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.13.0...v2.13.1) + +Bug fixes + +* Allow a block implementation to be used in combination with + `and_yield`, `and_raise`, `and_return` or `and_throw` (Myron Marston). + +### 2.13.0 / 2013-02-23 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.12.2...v2.13.0) + +Bug fixes + +* Fix bug that caused weird behavior when a method that had + previously been stubbed with multiple return values (e.g. + `obj.stub(:foo).and_return(1, 2)`) was later mocked with a + single return value (e.g. `obj.should_receive(:foo).once.and_return(1)`). + (Myron Marston) +* Fix bug related to a mock expectation for a method that already had + multiple stubs with different `with` constraints. Previously, the + first stub was used, even though it may not have matched the passed + args. The fix defers this decision until the message is received so + that the proper stub response can be chosen based on the passed + arguments (Myron Marston). +* Do not call `nil?` extra times on a mocked object, in case `nil?` + itself is expected a set number of times (Myron Marston). +* Fix `missing_default_stub_error` message so array args are handled + properly (Myron Marston). +* Explicitly disallow `any_instance.unstub!` (Ryan Jones). +* Fix `any_instance` stubbing so that it works with `Delegator` + subclasses (Myron Marston). +* Fix `and_call_original` so that it works with `Delegator` subclasses + (Myron Marston). +* Fix `any_instance.should_not_receive` when `any_instance.should_receive` + is used on the same class in the same example. Previously it would + wrongly report a failure even when the message was not received + (Myron Marston). + +### 2.12.2 / 2013-01-27 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.12.1...v.2.12.2) + +Bug fixes + +* Fix `and_call_original` to work properly for methods defined + on a module extended onto an object instance (Myron Marston). +* Fix `stub_const` with an undefined constnat name to work properly + with constant strings that are prefixed with `::` -- and edge case + I missed in the bug fix in the 2.12.1 release (Myron Marston). +* Ensure method visibility on a partial mock is restored after reseting + method stubs, even on a singleton module (created via `extend self`) + when the method visibility differs between the instance and singleton + versions (Andy Lindeman). + +### 2.12.1 / 2012-12-21 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.12.0...v2.12.1) + +Bug fixes + +* Fix `any_instance` to support `and_call_original`. + (Myron Marston) +* Properly restore stubbed aliased methods on rubies + that report the incorrect owner (Myron Marston and Andy Lindeman). +* Fix `hide_const` and `stub_const` with a defined constnat name to + work properly with constant strings that are prefixed with `::` (Myron Marston). + +### 2.12.0 / 2012-11-12 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.11.3...v2.12.0) + +Enhancements + +* `and_raise` can accept an exception class and message, more closely + matching `Kernel#raise` (e.g., `foo.stub(:bar).and_raise(RuntimeError, "message")`) + (Bas Vodde) +* Add `and_call_original`, which will delegate the message to the + original method (Myron Marston). + +Deprecations: + +* Add deprecation warning when using `and_return` with `should_not_receive` + (Neha Kumari) + +### 2.11.3 / 2012-09-19 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.11.2...v2.11.3) + +Bug fixes + +* Fix `:transfer_nested_constants` option of `stub_const` so that it + doesn't blow up when there are inherited constants. (Myron Marston) +* `any_instance` stubs can be used on classes that override `Object#method`. + (Andy Lindeman) +* Methods stubbed with `any_instance` are unstubbed after the test finishes. + (Andy Lindeman) +* Fix confusing error message when calling a mocked class method an + extra time with the wrong arguments (Myron Marston). + +### 2.11.2 / 2012-08-11 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.11.1...v2.11.2) + +Bug fixes + +* Don't modify `dup` on classes that don't support `dup` (David Chelimsky) +* Fix `any_instance` so that it works properly with methods defined on + a superclass. (Daniel Eguzkiza) +* Fix `stub_const` so that it works properly for nested constants that + share a name with a top-level constant (e.g. "MyGem::Hash"). (Myron + Marston) + +### 2.11.1 / 2012-07-09 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.11.0...v2.11.1) + +Bug fixes + +* Fix `should_receive` so that when it is called on an `as_null_object` + double with no implementation, and there is a previous explicit stub + for the same method, the explicit stub remains (rather than being + overridden with the null object implementation--`return self`). (Myron + Marston) + +### 2.11.0 / 2012-07-07 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.10.1...v2.11.0) + +Enhancements + +* Expose ArgumentListMatcher as a formal API + * supports use by 3rd party mock frameworks like Surrogate +* Add `stub_const` API to stub constants for the duration of an + example (Myron Marston). + +Bug fixes + +* Fix regression of edge case behavior. `double.should_receive(:foo) { a }` + was causing a NoMethodError when `double.stub(:foo).and_return(a, b)` + had been setup before (Myron Marston). +* Infinite loop generated by using `any_instance` and `dup`. (Sidu Ponnappa @kaiwren) +* `double.should_receive(:foo).at_least(:once).and_return(a)` always returns a + even if `:foo` is already stubbed. +* Prevent infinite loop when interpolating a null double into a string + as an integer (`"%i" % double.as_null_object`). (Myron Marston) +* Fix `should_receive` so that null object behavior (e.g. returning + self) is preserved if no implementation is given (Myron Marston). +* Fix `and_raise` so that it raises `RuntimeError` rather than + `Exception` by default, just like ruby does. (Andrew Marshall) + +### 2.10.1 / 2012-05-05 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.10.0...v2.10.1) + +Bug fixes + +* fix regression of edge case behavior + (https://github.com/rspec/rspec-mocks/issues/132) + * fixed failure of `object.should_receive(:message).at_least(0).times.and_return value` + * fixed failure of `object.should_not_receive(:message).and_return value` + +### 2.10.0 / 2012-05-03 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.9.0...v2.10.0) + +Bug fixes + +* fail fast when an `exactly` or `at_most` expectation is exceeded + +### 2.9.0 / 2012-03-17 +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.8.0...v2.9.0) + +Enhancements + +* Support order constraints across objects (preethiramdev) + +Bug fixes + +* Allow a `as_null_object` to be passed to `with` +* Pass proc to block passed to stub (Aubrey Rhodes) +* Initialize child message expectation args to match any args (rspec/rspec-mocks#109 - + preethiramdev) + +### 2.8.0 / 2012-01-04 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.8.0.rc2...v2.8.0) + +No changes for this release. Just releasing with the other rspec gems. + +### 2.8.0.rc2 / 2011-12-19 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.8.0.rc1...v2.8.0.rc2) + +No changes for this release. Just releasing with the other rspec gems. + +### 2.8.0.rc1 / 2011-11-06 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.7.0...v2.8.0.rc1) + +Enhancements + +* Eliminate Ruby warnings (Matijs van Zuijlen) + +### 2.7.0 / 2011-10-16 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.6.0...v2.7.0) + +Enhancements + +* Use `__send__` rather than `send` (alextk) +* Add support for `any_instance.stub_chain` (Sidu Ponnappa) +* Add support for `any_instance` argument matching based on `with` (Sidu + Ponnappa and Andy Lindeman) + +Changes + +* Check for `failure_message_for_should` or `failure_message` instead of + `description` to detect a matcher (Tibor Claassen) + +Bug fixes + +* pass a hash to `any_instance.stub`. (Justin Ko) +* allow `to_ary` to be called without raising `NoMethodError` (Mikhail + Dieterle) +* `any_instance` properly restores private methods (Sidu Ponnappa) + +### 2.6.0 / 2011-05-12 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.5.0...v2.6.0) + +Enhancements + +* Add support for `any_instance.stub` and `any_instance.should_receive` (Sidu + Ponnappa and Andy Lindeman) + +Bug fixes + +* fix bug in which multiple chains with shared messages ending in hashes failed + to return the correct value + +### 2.5.0 / 2011-02-05 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.4.0...v2.5.0) + +Bug fixes + +* message expectation counts now work in combination with a stub (Damian + Nurzynski) +* fix failure message when message received with incorrect args (Josep M. + Bach) + +### 2.4.0 / 2011-01-02 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.3.0...v2.4.0) + +No functional changes in this release, which was made to align with the +rspec-core-2.4.0 release. + +### 2.3.0 / 2010-12-12 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.2.0...v2.3.0) + +Bug fixes + +* Fix our Marshal extension so that it does not interfere with objects that + have their own `@mock_proxy` instance variable. (Myron Marston) + +### 2.2.0 / 2010-11-28 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.1.0...v2.2.0) + +Enhancements + +* Added "rspec/mocks/standalone" for exploring the rspec-mocks in irb. + +Bug fix + +* Eliminate warning on splat args without parens (Gioele Barabucci) +* Fix bug where `obj.should_receive(:foo).with(stub.as_null_object)` would pass + with a false positive. + +### 2.1.0 / 2010-11-07 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.0.1...v2.1.0) + +Bug fixes + +* Fix serialization of stubbed object (Josep M Bach) + +### 2.0.0 / 2010-10-10 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.0.0.beta.22...v2.0.0) + +### 2.0.0.rc / 2010-10-05 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.0.0.beta.22...v2.0.0.rc) + +Enhancements + +* support passing a block to an expectation block (Nicolas Braem) + * `obj.should_receive(:msg) {|&block| ... }` + +Bug fixes + +* Fix YAML serialization of stub (Myron Marston) +* Fix rdoc rake task (Hans de Graaff) + +### 2.0.0.beta.22 / 2010-09-12 + +[Full Changelog](http://github.com/rspec/rspec-mocks/compare/v2.0.0.beta.20...v2.0.0.beta.22) + +Bug fixes + +* fixed regression that broke `obj.stub_chain(:a, :b => :c)` +* fixed regression that broke `obj.stub_chain(:a, :b) { :c }` +* `respond_to?` always returns true when using `as_null_object` diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/LICENSE.md b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/LICENSE.md new file mode 100644 index 00000000..dae02d8a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/LICENSE.md @@ -0,0 +1,25 @@ +The MIT License (MIT) +===================== + +* Copyright © 2012 David Chelimsky, Myron Marston +* Copyright © 2006 David Chelimsky, The RSpec Development Team +* Copyright © 2005 Steven Baker + +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 AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/README.md b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/README.md new file mode 100644 index 00000000..e569feee --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/README.md @@ -0,0 +1,465 @@ +# RSpec Mocks [![Build Status](https://github.com/rspec/rspec-mocks/workflows/RSpec%20CI/badge.svg)](https://github.com/rspec/rspec-mocks/actions) [![Code Climate](https://codeclimate.com/github/rspec/rspec-mocks.svg)](https://codeclimate.com/github/rspec/rspec-mocks) +rspec-mocks is a test-double framework for rspec with support for method stubs, +fakes, and message expectations on generated test-doubles and real objects +alike. + +## Install + + gem install rspec # for rspec-core, rspec-expectations, rspec-mocks + gem install rspec-mocks # for rspec-mocks only + +Want to run against the `main` branch? You'll need to include the dependent +RSpec repos as well. Add the following to your `Gemfile`: + +```ruby +%w[rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib| + gem lib, :git => "https://github.com/rspec/#{lib}.git", :branch => 'main' +end +``` +## Contributing + +Once you've set up the environment, you'll need to cd into the working +directory of whichever repo you want to work in. From there you can run the +specs and cucumber features, and make patches. + +NOTE: You do not need to use rspec-dev to work on a specific RSpec repo. You +can treat each RSpec repo as an independent project. + +For information about contributing to RSpec, please refer to the following markdown files: +* [Build details](BUILD_DETAIL.md) +* [Code of Conduct](CODE_OF_CONDUCT.md) +* [Detailed contributing guide](CONTRIBUTING.md) +* [Development setup guide](DEVELOPMENT.md) + +## Test Doubles + +A test double is an object that stands in for another object in your system +during a code example. Use the `double` method, passing in an optional identifier, to create one: + +```ruby +book = double("book") +``` + +Most of the time you will want some confidence that your doubles resemble an +existing object in your system. Verifying doubles are provided for this +purpose. If the existing object is available, they will prevent you from adding +stubs and expectations for methods that do not exist or that have an invalid +number of parameters. + +```ruby +book = instance_double("Book", :pages => 250) +``` + +Verifying doubles have some clever tricks to enable you to both test in +isolation without your dependencies loaded while still being able to validate +them against real objects. More detail is available in [their +documentation](https://github.com/rspec/rspec-mocks/blob/main/features/verifying_doubles). + +Verifying doubles can also accept custom identifiers, just like double(), e.g.: + +```ruby +books = [] +books << instance_double("Book", :rspec_book, :pages => 250) +books << instance_double("Book", "(Untitled)", :pages => 5000) + +puts books.inspect # with names, it's clearer which were actually added +``` + +## Method Stubs + +A method stub is an implementation that returns a pre-determined value. Method +stubs can be declared on test doubles or real objects using the same syntax. +rspec-mocks supports 3 forms for declaring method stubs: + +```ruby +allow(book).to receive(:title) { "The RSpec Book" } +allow(book).to receive(:title).and_return("The RSpec Book") +allow(book).to receive_messages( + :title => "The RSpec Book", + :subtitle => "Behaviour-Driven Development with RSpec, Cucumber, and Friends") +``` + +You can also use this shortcut, which creates a test double and declares a +method stub in one statement: + +```ruby +book = double("book", :title => "The RSpec Book") +``` + +The first argument is a name, which is used for documentation and appears in +failure messages. If you don't care about the name, you can leave it out, +making the combined instantiation/stub declaration very terse: + +```ruby +double(:foo => 'bar') +``` + +This is particularly nice when providing a list of test doubles to a method +that iterates through them: + +```ruby +order.calculate_total_price(double(:price => 1.99), double(:price => 2.99)) +``` + +### Stubbing a chain of methods + +You can use `receive_message_chain` in place of `receive` to stub a chain of messages: + +```ruby +allow(double).to receive_message_chain("foo.bar") { :baz } +allow(double).to receive_message_chain(:foo, :bar => :baz) +allow(double).to receive_message_chain(:foo, :bar) { :baz } + +# Given any of the above forms: +double.foo.bar # => :baz +``` + +Chains can be arbitrarily long, which makes it quite painless to violate the Law of Demeter in violent ways, so you should consider any use of `receive_message_chain` a code smell. Even though not all code smells indicate real problems (think fluent interfaces), `receive_message_chain` still results in brittle examples. For example, if you write `allow(foo).to receive_message_chain(:bar, :baz => 37)` in a spec and then the implementation calls `foo.baz.bar`, the stub will not work. + +## Consecutive return values + +When a stub might be invoked more than once, you can provide additional +arguments to `and_return`. The invocations cycle through the list. The last +value is returned for any subsequent invocations: + +```ruby +allow(die).to receive(:roll).and_return(1, 2, 3) +die.roll # => 1 +die.roll # => 2 +die.roll # => 3 +die.roll # => 3 +die.roll # => 3 +``` + +To return an array in a single invocation, declare an array: + +```ruby +allow(team).to receive(:players).and_return([double(:name => "David")]) +``` + +## Message Expectations + +A message expectation is an expectation that the test double will receive a +message some time before the example ends. If the message is received, the +expectation is satisfied. If not, the example fails. + +```ruby +validator = double("validator") +expect(validator).to receive(:validate) { "02134" } +zipcode = Zipcode.new("02134", validator) +zipcode.valid? +``` + +## Test Spies + +Verifies the given object received the expected message during the course of +the test. For a message to be verified, the given object must be setup to spy +on it, either by having it explicitly stubbed or by being a null object double +(e.g. `double(...).as_null_object`). Convenience methods are provided to easily +create null object doubles for this purpose: + +```ruby +spy("invitation") # => same as `double("invitation").as_null_object` +instance_spy("Invitation") # => same as `instance_double("Invitation").as_null_object` +class_spy("Invitation") # => same as `class_double("Invitation").as_null_object` +object_spy("Invitation") # => same as `object_double("Invitation").as_null_object` +``` + +Verifying messages received in this way implements the Test Spy pattern. + +```ruby +invitation = spy('invitation') + +user.accept_invitation(invitation) + +expect(invitation).to have_received(:accept) + +# You can also use other common message expectations. For example: +expect(invitation).to have_received(:accept).with(mailer) +expect(invitation).to have_received(:accept).twice +expect(invitation).to_not have_received(:accept).with(mailer) + +# One can specify a return value on the spy the same way one would a double. +invitation = spy('invitation', :accept => true) +expect(invitation).to have_received(:accept).with(mailer) +expect(invitation.accept).to eq(true) +``` + +Note that `have_received(...).with(...)` is unable to work properly when +passed arguments are mutated after the spy records the received message. +For example, this does not work properly: + +```ruby +greeter = spy("greeter") + +message = "Hello" +greeter.greet_with(message) +message << ", World" + +expect(greeter).to have_received(:greet_with).with("Hello") +``` + +## Nomenclature + +### Mock Objects and Test Stubs + +The names Mock Object and Test Stub suggest specialized Test Doubles. i.e. +a Test Stub is a Test Double that only supports method stubs, and a Mock +Object is a Test Double that supports message expectations and method +stubs. + +There is a lot of overlapping nomenclature here, and there are many +variations of these patterns (fakes, spies, etc). Keep in mind that most of +the time we're talking about method-level concepts that are variations of +method stubs and message expectations, and we're applying to them to _one_ +generic kind of object: a Test Double. + +### Test-Specific Extension + +a.k.a. Partial Double, a Test-Specific Extension is an extension of a +real object in a system that is instrumented with test-double like +behaviour in the context of a test. This technique is very common in Ruby +because we often see class objects acting as global namespaces for methods. +For example, in Rails: + +```ruby +person = double("person") +allow(Person).to receive(:find) { person } +``` + +In this case we're instrumenting Person to return the person object we've +defined whenever it receives the `find` message. We can also set a message +expectation so that the example fails if `find` is not called: + +```ruby +person = double("person") +expect(Person).to receive(:find) { person } +``` + +RSpec replaces the method we're stubbing or mocking with its own +test-double-like method. At the end of the example, RSpec verifies any message +expectations, and then restores the original methods. + +## Expecting Arguments + +```ruby +expect(double).to receive(:msg).with(*args) +expect(double).to_not receive(:msg).with(*args) +``` + +You can set multiple expectations for the same message if you need to: + +```ruby +expect(double).to receive(:msg).with("A", 1, 3) +expect(double).to receive(:msg).with("B", 2, 4) +``` + +## Argument Matchers + +Arguments that are passed to `with` are compared with actual arguments +received using ===. In cases in which you want to specify things about the +arguments rather than the arguments themselves, you can use any of the +matchers that ship with rspec-expectations. They don't all make syntactic +sense (they were primarily designed for use with RSpec::Expectations), but +you are free to create your own custom RSpec::Matchers. + +rspec-mocks also adds some keyword Symbols that you can use to +specify certain kinds of arguments: + +```ruby +expect(double).to receive(:msg).with(no_args) +expect(double).to receive(:msg).with(any_args) +expect(double).to receive(:msg).with(1, any_args) # any args acts like an arg splat and can go anywhere +expect(double).to receive(:msg).with(1, kind_of(Numeric), "b") #2nd argument can be any kind of Numeric +expect(double).to receive(:msg).with(1, boolean(), "b") #2nd argument can be true or false +expect(double).to receive(:msg).with(1, /abc/, "b") #2nd argument can be any String matching the submitted Regexp +expect(double).to receive(:msg).with(1, anything(), "b") #2nd argument can be anything at all +expect(double).to receive(:msg).with(1, duck_type(:abs, :div), "b") #2nd argument can be object that responds to #abs and #div +expect(double).to receive(:msg).with(hash_including(:a => 5)) # first arg is a hash with a: 5 as one of the key-values +expect(double).to receive(:msg).with(array_including(5)) # first arg is an array with 5 as one of the key-values +expect(double).to receive(:msg).with(hash_excluding(:a => 5)) # first arg is a hash without a: 5 as one of the key-values +expect(double).to receive(:msg).with(start_with('a')) # any matcher, custom or from rspec-expectations +expect(double).to receive(:msg).with(satisfy { |data| data.dig(:a, :b, :c) == 5 }) # assert anything you want +``` + +## Receive Counts + +```ruby +expect(double).to receive(:msg).once +expect(double).to receive(:msg).twice +expect(double).to receive(:msg).exactly(n).time +expect(double).to receive(:msg).exactly(n).times +expect(double).to receive(:msg).at_least(:once) +expect(double).to receive(:msg).at_least(:twice) +expect(double).to receive(:msg).at_least(n).time +expect(double).to receive(:msg).at_least(n).times +expect(double).to receive(:msg).at_most(:once) +expect(double).to receive(:msg).at_most(:twice) +expect(double).to receive(:msg).at_most(n).time +expect(double).to receive(:msg).at_most(n).times +``` + +## Ordering + +```ruby +expect(double).to receive(:msg).ordered +expect(double).to receive(:other_msg).ordered + # This will fail if the messages are received out of order +``` + +This can include the same message with different arguments: + +```ruby +expect(double).to receive(:msg).with("A", 1, 3).ordered +expect(double).to receive(:msg).with("B", 2, 4).ordered +``` + +## Setting Responses + +Whether you are setting a message expectation or a method stub, you can +tell the object precisely how to respond. The most generic way is to pass +a block to `receive`: + +```ruby +expect(double).to receive(:msg) { value } +``` + +When the double receives the `msg` message, it evaluates the block and returns +the result. + +```ruby +expect(double).to receive(:msg).and_return(value) +expect(double).to receive(:msg).exactly(3).times.and_return(value1, value2, value3) + # returns value1 the first time, value2 the second, etc +expect(double).to receive(:msg).and_raise(error) + # `error` can be an instantiated object (e.g. `StandardError.new(some_arg)`) or a class (e.g. `StandardError`) + # if it is a class, it must be instantiable with no args +expect(double).to receive(:msg).and_throw(:msg) +expect(double).to receive(:msg).and_yield(values, to, yield) +expect(double).to receive(:msg).and_yield(values, to, yield).and_yield(some, other, values, this, time) + # for methods that yield to a block multiple times +``` + +Any of these responses can be applied to a stub as well + +```ruby +allow(double).to receive(:msg).and_return(value) +allow(double).to receive(:msg).and_return(value1, value2, value3) +allow(double).to receive(:msg).and_raise(error) +allow(double).to receive(:msg).and_throw(:msg) +allow(double).to receive(:msg).and_yield(values, to, yield) +allow(double).to receive(:msg).and_yield(values, to, yield).and_yield(some, other, values, this, time) +``` + +## Arbitrary Handling + +Once in a while you'll find that the available expectations don't solve the +particular problem you are trying to solve. Imagine that you expect the message +to come with an Array argument that has a specific length, but you don't care +what is in it. You could do this: + +```ruby +expect(double).to receive(:msg) do |arg| + expect(arg.size).to eq 7 +end +``` + +If the method being stubbed itself takes a block, and you need to yield to it +in some special way, you can use this: + +```ruby +expect(double).to receive(:msg) do |&arg| + begin + arg.call + ensure + # cleanup + end +end +``` + +## Delegating to the Original Implementation + +When working with a partial mock object, you may occasionally +want to set a message expectation without interfering with how +the object responds to the message. You can use `and_call_original` +to achieve this: + +```ruby +expect(Person).to receive(:find).and_call_original +Person.find # => executes the original find method and returns the result +``` + +## Combining Expectation Details + +Combining the message name with specific arguments, receive counts and responses +you can get quite a bit of detail in your expectations: + +```ruby +expect(double).to receive(:<<).with("illegal value").once.and_raise(ArgumentError) +``` + +While this is a good thing when you really need it, you probably don't really +need it! Take care to specify only the things that matter to the behavior of +your code. + +## Stubbing and Hiding Constants + +See the [mutating constants +README](https://github.com/rspec/rspec-mocks/blob/main/features/mutating_constants/README.md) +for info on this feature. + +## Use `before(:example)`, not `before(:context)` + +Stubs in `before(:context)` are not supported. The reason is that all stubs and mocks get cleared out after each example, so any stub that is set in `before(:context)` would work in the first example that happens to run in that group, but not for any others. + +Instead of `before(:context)`, use `before(:example)`. + +## Settings mocks or stubs on any instance of a class + +rspec-mocks provides two methods, `allow_any_instance_of` and +`expect_any_instance_of`, that will allow you to stub or mock any instance +of a class. They are used in place of `allow` or `expect`: + +```ruby +allow_any_instance_of(Widget).to receive(:name).and_return("Wibble") +expect_any_instance_of(Widget).to receive(:name).and_return("Wobble") +``` + +These methods add the appropriate stub or expectation to all instances of +`Widget`. + +This feature is sometimes useful when working with legacy code, though in +general we discourage its use for a number of reasons: + +* The `rspec-mocks` API is designed for individual object instances, but this + feature operates on entire classes of objects. As a result there are some + semantically confusing edge cases. For example in + `expect_any_instance_of(Widget).to receive(:name).twice` it isn't clear + whether each specific instance is expected to receive `name` twice, or if two + receives total are expected. (It's the former.) +* Using this feature is often a design smell. It may be + that your test is trying to do too much or that the object under test is too + complex. +* It is the most complicated feature of `rspec-mocks`, and has historically + received the most bug reports. (None of the core team actively use it, + which doesn't help.) + + +## Further Reading + +There are many different viewpoints about the meaning of mocks and stubs. If +you are interested in learning more, here is some recommended reading: + +* Mock Objects: http://www.mockobjects.com/ +* Endo-Testing: http://www.ccs.neu.edu/research/demeter/related-work/extreme-programming/MockObjectsFinal.PDF +* Mock Roles, Not Objects: http://www.jmock.org/oopsla2004.pdf +* Test Double: http://www.martinfowler.com/bliki/TestDouble.html +* Test Double Patterns: http://xunitpatterns.com/Test%20Double%20Patterns.html +* Mocks aren't stubs: http://www.martinfowler.com/articles/mocksArentStubs.html + +## Also see + +* [https://github.com/rspec/rspec](https://github.com/rspec/rspec) +* [https://github.com/rspec/rspec-core](https://github.com/rspec/rspec-core) +* [https://github.com/rspec/rspec-expectations](https://github.com/rspec/rspec-expectations) +* [https://github.com/rspec/rspec-rails](https://github.com/rspec/rspec-rails) diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks.rb new file mode 100644 index 00000000..297779e5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks.rb @@ -0,0 +1,133 @@ +require 'rspec/support' +RSpec::Support.require_rspec_support 'caller_filter' +RSpec::Support.require_rspec_support 'warnings' +RSpec::Support.require_rspec_support 'ruby_features' + +RSpec::Support.define_optimized_require_for_rspec(:mocks) { |f| require_relative f } + +%w[ + instance_method_stasher + method_double + argument_matchers + example_methods + proxy + test_double + argument_list_matcher + message_expectation + order_group + error_generator + space + mutate_const + targets + syntax + configuration + verifying_double + version +].each { |name| RSpec::Support.require_rspec_mocks name } + +# Share the top-level RSpec namespace, because we are a core supported +# extension. +module RSpec + # Contains top-level utility methods. While this contains a few + # public methods, these are not generally meant to be called from + # a test or example. They exist primarily for integration with + # test frameworks (such as rspec-core). + module Mocks + # Performs per-test/example setup. This should be called before + # an test or example begins. + def self.setup + @space_stack << (@space = space.new_scope) + end + + # Verifies any message expectations that were set during the + # test or example. This should be called at the end of an example. + def self.verify + space.verify_all + end + + # Cleans up all test double state (including any methods that were + # redefined on partial doubles). This _must_ be called after + # each example, even if an error was raised during the example. + def self.teardown + space.reset_all + @space_stack.pop + @space = @space_stack.last || @root_space + end + + # Adds an allowance (stub) on `subject` + # + # @param subject the subject to which the message will be added + # @param message a symbol, representing the message that will be + # added. + # @param opts a hash of options, :expected_from is used to set the + # original call site + # @yield an optional implementation for the allowance + # + # @example Defines the implementation of `foo` on `bar`, using the passed block + # x = 0 + # RSpec::Mocks.allow_message(bar, :foo) { x += 1 } + def self.allow_message(subject, message, opts={}, &block) + space.proxy_for(subject).add_stub(message, opts, &block) + end + + # Sets a message expectation on `subject`. + # @param subject the subject on which the message will be expected + # @param message a symbol, representing the message that will be + # expected. + # @param opts a hash of options, :expected_from is used to set the + # original call site + # @yield an optional implementation for the expectation + # + # @example Expect the message `foo` to receive `bar`, then call it + # RSpec::Mocks.expect_message(bar, :foo) + # bar.foo + def self.expect_message(subject, message, opts={}, &block) + space.proxy_for(subject).add_message_expectation(message, opts, &block) + end + + # Call the passed block and verify mocks after it has executed. This allows + # mock usage in arbitrary places, such as a `before(:all)` hook. + # + # @return [Object] the return value from the block + def self.with_temporary_scope + setup + + begin + result = yield + verify + result + ensure + teardown + end + end + + class << self + # @private + attr_reader :space + end + @space_stack = [] + @root_space = @space = RSpec::Mocks::RootSpace.new + + # @private + IGNORED_BACKTRACE_LINE = 'this backtrace line is ignored' + + # To speed up boot time a bit, delay loading optional or rarely + # used features until their first use. + autoload :AnyInstance, "rspec/mocks/any_instance" + autoload :ExpectChain, "rspec/mocks/message_chain" + autoload :StubChain, "rspec/mocks/message_chain" + autoload :MarshalExtension, "rspec/mocks/marshal_extension" + + # Namespace for mock-related matchers. + module Matchers + # @private + # just a "tag" for rspec-mock matchers detection + module Matcher; end + + autoload :HaveReceived, "rspec/mocks/matchers/have_received" + autoload :Receive, "rspec/mocks/matchers/receive" + autoload :ReceiveMessageChain, "rspec/mocks/matchers/receive_message_chain" + autoload :ReceiveMessages, "rspec/mocks/matchers/receive_messages" + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance.rb new file mode 100644 index 00000000..41eae814 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance.rb @@ -0,0 +1,11 @@ +%w[ + any_instance/chain + any_instance/error_generator + any_instance/stub_chain + any_instance/stub_chain_chain + any_instance/expect_chain_chain + any_instance/expectation_chain + any_instance/message_chains + any_instance/recorder + any_instance/proxy +].each { |f| RSpec::Support.require_rspec_mocks(f) } diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/chain.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/chain.rb new file mode 100644 index 00000000..74d864b3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/chain.rb @@ -0,0 +1,111 @@ +module RSpec + module Mocks + # @private + module AnyInstance + # @private + class Chain + def initialize(recorder, *args, &block) + @recorder = recorder + @expectation_args = args + @expectation_block = block + @argument_list_matcher = ArgumentListMatcher::MATCH_ALL + end + + # @private + # + # Provides convenience methods for recording customizations on message + # expectations. + module Customizations + # @macro [attach] record + # @method $1(*args, &block) + # Records the `$1` message for playback against an instance that + # invokes a method stubbed or mocked using `any_instance`. + # + # @see RSpec::Mocks::MessageExpectation#$1 + # + def self.record(method_name) + define_method(method_name) do |*args, &block| + record(method_name, *args, &block) + end + end + + record :and_return + record :and_raise + record :and_throw + record :and_yield + record :and_call_original + record :and_wrap_original + record :with + record :once + record :twice + record :thrice + record :exactly + record :times + record :time + record :never + record :at_least + record :at_most + end + + include Customizations + + # @private + def playback!(instance) + message_expectation = create_message_expectation_on(instance) + messages.inject(message_expectation) do |object, message| + object.__send__(*message.first, &message.last) + end + end + + # @private + def constrained_to_any_of?(*constraints) + constraints.any? do |constraint| + messages.any? do |message| + message.first.first == constraint + end + end + end + + # @private + def matches_args?(*args) + @argument_list_matcher.args_match?(*args) + end + + # @private + def expectation_fulfilled! + @expectation_fulfilled = true + end + + def never + AnyInstance.error_generator.raise_double_negation_error("expect_any_instance_of(MyClass)") if negated? + super + end + + def with(*args, &block) + @argument_list_matcher = ArgumentListMatcher.new(*args) + super + end + + private + + def negated? + messages.any? { |(message, *_), _| message == :never } + end + + def messages + @messages ||= [] + end + + def last_message + messages.last.first.first unless messages.empty? + end + + def record(rspec_method_name, *args, &block) + verify_invocation_order(rspec_method_name, *args, &block) + messages << [args.unshift(rspec_method_name), block] + self + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/error_generator.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/error_generator.rb new file mode 100644 index 00000000..d1046cb0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/error_generator.rb @@ -0,0 +1,31 @@ +module RSpec + module Mocks + module AnyInstance + # @private + class ErrorGenerator < ::RSpec::Mocks::ErrorGenerator + def raise_second_instance_received_message_error(unfulfilled_expectations) + __raise "Exactly one instance should have received the following " \ + "message(s) but didn't: #{unfulfilled_expectations.sort.join(', ')}" + end + + def raise_does_not_implement_error(klass, method_name) + __raise "#{klass} does not implement ##{method_name}" + end + + def raise_message_already_received_by_other_instance_error(method_name, object_inspect, invoked_instance) + __raise "The message '#{method_name}' was received by #{object_inspect} " \ + "but has already been received by #{invoked_instance}" + end + + def raise_not_supported_with_prepend_error(method_name, problem_mod) + __raise "Using `any_instance` to stub a method (#{method_name}) that has been " \ + "defined on a prepended module (#{problem_mod}) is not supported." + end + end + + def self.error_generator + @error_generator ||= ErrorGenerator.new + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/expect_chain_chain.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/expect_chain_chain.rb new file mode 100644 index 00000000..c467ba93 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/expect_chain_chain.rb @@ -0,0 +1,31 @@ +module RSpec + module Mocks + module AnyInstance + # @private + class ExpectChainChain < StubChain + def initialize(*args) + super + @expectation_fulfilled = false + end + + def expectation_fulfilled? + @expectation_fulfilled + end + + def playback!(instance) + super.tap { @expectation_fulfilled = true } + end + + private + + def create_message_expectation_on(instance) + ::RSpec::Mocks::ExpectChain.expect_chain_on(instance, *@expectation_args, &@expectation_block) + end + + def invocation_order + EmptyInvocationOrder + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/expectation_chain.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/expectation_chain.rb new file mode 100644 index 00000000..edf85482 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/expectation_chain.rb @@ -0,0 +1,50 @@ +module RSpec + module Mocks + module AnyInstance + # @private + class ExpectationChain < Chain + def expectation_fulfilled? + @expectation_fulfilled || constrained_to_any_of?(:never) + end + + def initialize(*args, &block) + @expectation_fulfilled = false + super + end + + private + + def verify_invocation_order(_rspec_method_name, *_args, &_block) + end + end + + # @private + class PositiveExpectationChain < ExpectationChain + private + + def create_message_expectation_on(instance) + proxy = ::RSpec::Mocks.space.proxy_for(instance) + method_name, opts = @expectation_args + opts = (opts || {}).merge(:expected_form => IGNORED_BACKTRACE_LINE) + + me = proxy.add_message_expectation(method_name, opts, &@expectation_block) + if RSpec::Mocks.configuration.yield_receiver_to_any_instance_implementation_blocks? + me.and_yield_receiver_to_implementation + end + + me + end + + ExpectationInvocationOrder = + { + :and_return => [:with, nil], + :and_raise => [:with, nil], + }.freeze + + def invocation_order + ExpectationInvocationOrder + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/message_chains.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/message_chains.rb new file mode 100644 index 00000000..7f4d770a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/message_chains.rb @@ -0,0 +1,83 @@ +module RSpec + module Mocks + module AnyInstance + # @private + class MessageChains + def initialize + @chains_by_method_name = Hash.new { |h, k| h[k] = [] } + end + + # @private + def [](method_name) + @chains_by_method_name[method_name] + end + + # @private + def add(method_name, chain) + @chains_by_method_name[method_name] << chain + chain + end + + # @private + def remove_stub_chains_for!(method_name) + @chains_by_method_name[method_name].reject! do |chain| + StubChain === chain + end + end + + # @private + def has_expectation?(method_name) + @chains_by_method_name[method_name].find do |chain| + ExpectationChain === chain + end + end + + # @private + def each_unfulfilled_expectation_matching(method_name, *args) + @chains_by_method_name[method_name].each do |chain| + yield chain if !chain.expectation_fulfilled? && chain.matches_args?(*args) + end + end + + # @private + def all_expectations_fulfilled? + @chains_by_method_name.all? do |_method_name, chains| + chains.all? { |chain| chain.expectation_fulfilled? } + end + end + + # @private + def unfulfilled_expectations + @chains_by_method_name.map do |method_name, chains| + method_name.to_s if ExpectationChain === chains.last && !chains.last.expectation_fulfilled? + end.compact + end + + # @private + def received_expected_message!(method_name) + @chains_by_method_name[method_name].each do |chain| + chain.expectation_fulfilled! + end + end + + # @private + def playback!(instance, method_name) + raise_if_second_instance_to_receive_message(instance) + @chains_by_method_name[method_name].each do |chain| + chain.playback!(instance) + end + end + + private + + def raise_if_second_instance_to_receive_message(instance) + @instance_with_expectation ||= instance if ExpectationChain === instance + return unless ExpectationChain === instance + return if @instance_with_expectation.equal?(instance) + + AnyInstance.error_generator.raise_second_instance_received_message_error(unfulfilled_expectations) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/proxy.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/proxy.rb new file mode 100644 index 00000000..54ded058 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/proxy.rb @@ -0,0 +1,125 @@ +module RSpec + module Mocks + module AnyInstance + # @private + # The `AnyInstance::Recorder` is responsible for redefining the klass's + # instance method in order to add any stubs/expectations the first time + # the method is called. It's not capable of updating a stub on an instance + # that's already been previously stubbed (either directly, or via + # `any_instance`). + # + # This proxy sits in front of the recorder and delegates both to it + # and to the `RSpec::Mocks::Proxy` for each already mocked or stubbed + # instance of the class, in order to propagates changes to the instances. + # + # Note that unlike `RSpec::Mocks::Proxy`, this proxy class is stateless + # and is not persisted in `RSpec::Mocks.space`. + # + # Proxying for the message expectation fluent interface (typically chained + # off of the return value of one of these methods) is provided by the + # `FluentInterfaceProxy` class below. + class Proxy + def initialize(recorder, target_proxies) + @recorder = recorder + @target_proxies = target_proxies + end + + def klass + @recorder.klass + end + + def stub(method_name_or_method_map, &block) + if Hash === method_name_or_method_map + method_name_or_method_map.each do |method_name, return_value| + stub(method_name).and_return(return_value) + end + else + perform_proxying(__method__, [method_name_or_method_map], block) do |proxy| + proxy.add_stub(method_name_or_method_map, &block) + end + end + end + + def unstub(method_name) + perform_proxying(__method__, [method_name], nil) do |proxy| + proxy.remove_stub_if_present(method_name) + end + end + + def stub_chain(*chain, &block) + perform_proxying(__method__, chain, block) do |proxy| + Mocks::StubChain.stub_chain_on(proxy.object, *chain, &block) + end + end + + def expect_chain(*chain, &block) + perform_proxying(__method__, chain, block) do |proxy| + Mocks::ExpectChain.expect_chain_on(proxy.object, *chain, &block) + end + end + + def should_receive(method_name, &block) + perform_proxying(__method__, [method_name], block) do |proxy| + # Yeah, this is a bit odd...but if we used `add_message_expectation` + # then it would act like `expect_every_instance_of(klass).to receive`. + # The any_instance recorder takes care of validating that an instance + # received the message. + proxy.add_stub(method_name, &block) + end + end + + def should_not_receive(method_name, &block) + perform_proxying(__method__, [method_name], block) do |proxy| + proxy.add_message_expectation(method_name, &block).never + end + end + + private + + def perform_proxying(method_name, args, block, &target_proxy_block) + recorder_value = @recorder.__send__(method_name, *args, &block) + proxy_values = @target_proxies.map(&target_proxy_block) + FluentInterfaceProxy.new([recorder_value] + proxy_values) + end + end + + unless defined?(BasicObject) + class BasicObject + # Remove all methods except those expected to be defined on BasicObject + (instance_methods.map(&:to_sym) - [:__send__, :"!", :instance_eval, :==, :instance_exec, :"!=", :equal?, :__id__, :__binding__, :object_id]).each do |method| + undef_method method + end + end + end + + # @private + # Delegates messages to each of the given targets in order to + # provide the fluent interface that is available off of message + # expectations when dealing with `any_instance`. + # + # `targets` will typically contain 1 of the `AnyInstance::Recorder` + # return values and N `MessageExpectation` instances (one per instance + # of the `any_instance` klass). + class FluentInterfaceProxy < BasicObject + def initialize(targets) + @targets = targets + end + + if ::RUBY_VERSION.to_f > 1.8 + def respond_to_missing?(method_name, include_private=false) + super || @targets.first.respond_to?(method_name, include_private) + end + else + def respond_to?(method_name, include_private=false) + super || @targets.first.respond_to?(method_name, include_private) + end + end + + def method_missing(*args, &block) + return_values = @targets.map { |t| t.__send__(*args, &block) } + FluentInterfaceProxy.new(return_values) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/recorder.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/recorder.rb new file mode 100644 index 00000000..0eb8245b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/recorder.rb @@ -0,0 +1,299 @@ +module RSpec + module Mocks + module AnyInstance + # Given a class `TheClass`, `TheClass.any_instance` returns a `Recorder`, + # which records stubs and message expectations for later playback on + # instances of `TheClass`. + # + # Further constraints are stored in instances of [Chain](Chain). + # + # @see AnyInstance + # @see Chain + class Recorder + # @private + attr_reader :message_chains, :stubs, :klass + + def initialize(klass) + @message_chains = MessageChains.new + @stubs = Hash.new { |hash, key| hash[key] = [] } + @observed_methods = [] + @played_methods = {} + @backed_up_method_owner = {} + @klass = klass + @expectation_set = false + + return unless RSpec::Mocks.configuration.verify_partial_doubles? + RSpec::Mocks.configuration.verifying_double_callbacks.each do |block| + block.call(ObjectReference.for(klass)) + end + end + + # Initializes the recording a stub to be played back against any + # instance of this object that invokes the submitted method. + # + # @see Methods#stub + def stub(method_name, &block) + observe!(method_name) + message_chains.add(method_name, StubChain.new(self, method_name, &block)) + end + + # Initializes the recording a stub chain to be played back against any + # instance of this object that invokes the method matching the first + # argument. + # + # @see Methods#stub_chain + def stub_chain(*method_names_and_optional_return_values, &block) + normalize_chain(*method_names_and_optional_return_values) do |method_name, args| + observe!(method_name) + message_chains.add(method_name, StubChainChain.new(self, *args, &block)) + end + end + + # @private + def expect_chain(*method_names_and_optional_return_values, &block) + @expectation_set = true + normalize_chain(*method_names_and_optional_return_values) do |method_name, args| + observe!(method_name) + message_chains.add(method_name, ExpectChainChain.new(self, *args, &block)) + end + end + + # Initializes the recording a message expectation to be played back + # against any instance of this object that invokes the submitted + # method. + # + # @see Methods#should_receive + def should_receive(method_name, &block) + @expectation_set = true + observe!(method_name) + message_chains.add(method_name, PositiveExpectationChain.new(self, method_name, &block)) + end + + # The opposite of `should_receive` + # + # @see Methods#should_not_receive + def should_not_receive(method_name, &block) + should_receive(method_name, &block).never + end + + # Removes any previously recorded stubs, stub_chains or message + # expectations that use `method_name`. + # + # @see Methods#unstub + def unstub(method_name) + unless @observed_methods.include?(method_name.to_sym) + AnyInstance.error_generator.raise_method_not_stubbed_error(method_name) + end + message_chains.remove_stub_chains_for!(method_name) + stubs[method_name].clear + stop_observing!(method_name) unless message_chains.has_expectation?(method_name) + end + + # @api private + # + # Used internally to verify that message expectations have been + # fulfilled. + def verify + return unless @expectation_set + return if message_chains.all_expectations_fulfilled? + + AnyInstance.error_generator.raise_second_instance_received_message_error(message_chains.unfulfilled_expectations) + end + + # @private + def stop_all_observation! + @observed_methods.each { |method_name| restore_method!(method_name) } + end + + # @private + def playback!(instance, method_name) + RSpec::Mocks.space.ensure_registered(instance) + message_chains.playback!(instance, method_name) + @played_methods[method_name] = instance + received_expected_message!(method_name) if message_chains.has_expectation?(method_name) + end + + # @private + def instance_that_received(method_name) + @played_methods[method_name] + end + + # @private + def build_alias_method_name(method_name) + "__#{method_name}_without_any_instance__" + end + + # @private + def already_observing?(method_name) + @observed_methods.include?(method_name) || super_class_observing?(method_name) + end + + # @private + def notify_received_message(_object, message, args, _blk) + has_expectation = false + + message_chains.each_unfulfilled_expectation_matching(message, *args) do |expectation| + has_expectation = true + expectation.expectation_fulfilled! + end + + return unless has_expectation + + restore_method!(message) + mark_invoked!(message) + end + + protected + + def stop_observing!(method_name) + restore_method!(method_name) + @observed_methods.delete(method_name) + super_class_observers_for(method_name).each do |ancestor| + ::RSpec::Mocks.space. + any_instance_recorder_for(ancestor).stop_observing!(method_name) + end + end + + private + + def ancestor_is_an_observer?(ancestor, method_name) + return if ancestor == @klass + + ::RSpec::Mocks.space. + any_instance_recorder_for(ancestor).already_observing?(method_name) + end + + def super_class_observers_for(method_name) + @klass.ancestors.select do |ancestor| + ancestor_is_an_observer?(ancestor, method_name) + end + end + + def super_class_observing?(method_name) + @klass.ancestors.any? do |ancestor| + ancestor_is_an_observer?(ancestor, method_name) + end + end + + def normalize_chain(*args) + args.shift.to_s.split('.').map { |s| s.to_sym }.reverse.each { |a| args.unshift a } + yield args.first, args + end + + def received_expected_message!(method_name) + message_chains.received_expected_message!(method_name) + restore_method!(method_name) + mark_invoked!(method_name) + end + + def restore_method!(method_name) + if public_protected_or_private_method_defined?(build_alias_method_name(method_name)) + restore_original_method!(method_name) + else + remove_dummy_method!(method_name) + end + end + + def restore_original_method!(method_name) + return unless @klass.instance_method(method_name).owner == @klass + + alias_method_name = build_alias_method_name(method_name) + @klass.class_exec(@backed_up_method_owner) do |backed_up_method_owner| + remove_method method_name + + # A @klass can have methods implemented (see Method#owner) in @klass + # or inherited from a superclass. In ruby 2.2 and earlier, we can copy + # a method regardless of the 'owner' and restore it to @klass after + # because a call to 'super' from @klass's copied method would end up + # calling the original class's superclass's method. + # + # With the commit below, available starting in 2.3.0, ruby changed + # this behavior and a call to 'super' from the method copied to @klass + # will call @klass's superclass method, which is the original + # implementer of this method! This leads to very strange errors + # if @klass's copied method calls 'super', since it would end up + # calling itself, the original method implemented in @klass's + # superclass. + # + # For ruby 2.3 and above, we need to only restore methods that + # @klass originally owned. + # + # https://github.com/ruby/ruby/commit/c8854d2ca4be9ee6946e6d17b0e17d9ef130ee81 + if RUBY_VERSION < "2.3" || backed_up_method_owner[method_name.to_sym] == self + alias_method method_name, alias_method_name + end + remove_method alias_method_name + end + end + + def remove_dummy_method!(method_name) + @klass.class_exec do + remove_method method_name + end + end + + def backup_method!(method_name) + return unless public_protected_or_private_method_defined?(method_name) + + alias_method_name = build_alias_method_name(method_name) + @backed_up_method_owner[method_name.to_sym] ||= @klass.instance_method(method_name).owner + @klass.class_exec do + alias_method alias_method_name, method_name + end + end + + def public_protected_or_private_method_defined?(method_name) + MethodReference.method_defined_at_any_visibility?(@klass, method_name) + end + + def observe!(method_name) + allow_no_prepended_module_definition_of(method_name) + + if RSpec::Mocks.configuration.verify_partial_doubles? && !Mocks.configuration.temporarily_suppress_partial_double_verification + unless public_protected_or_private_method_defined?(method_name) + AnyInstance.error_generator.raise_does_not_implement_error(@klass, method_name) + end + end + + stop_observing!(method_name) if already_observing?(method_name) + @observed_methods << method_name + backup_method!(method_name) + recorder = self + method_was_private = @klass.private_method_defined?(method_name) + @klass.__send__(:define_method, method_name) do |*args, &blk| + recorder.playback!(self, method_name) + __send__(method_name, *args, &blk) + end + @klass.__send__(:private, method_name) if method_was_private + @klass.__send__(:ruby2_keywords, method_name) if @klass.respond_to?(:ruby2_keywords, true) + end + + def mark_invoked!(method_name) + backup_method!(method_name) + recorder = self + @klass.__send__(:define_method, method_name) do |*_args, &_blk| + invoked_instance = recorder.instance_that_received(method_name) + inspect = "#<#{self.class}:#{object_id} #{instance_variables.map { |name| "#{name}=#{instance_variable_get name}" }.join(', ')}>" + AnyInstance.error_generator.raise_message_already_received_by_other_instance_error( + method_name, inspect, invoked_instance + ) + end + end + + if Support::RubyFeatures.module_prepends_supported? + def allow_no_prepended_module_definition_of(method_name) + prepended_modules = RSpec::Mocks::Proxy.prepended_modules_of(@klass) + problem_mod = prepended_modules.find { |mod| mod.method_defined?(method_name) } + return unless problem_mod + + AnyInstance.error_generator.raise_not_supported_with_prepend_error(method_name, problem_mod) + end + else + def allow_no_prepended_module_definition_of(_method_name) + # nothing to do; prepends aren't supported on this version of ruby + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/stub_chain.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/stub_chain.rb new file mode 100644 index 00000000..c4c0ab74 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/stub_chain.rb @@ -0,0 +1,51 @@ +module RSpec + module Mocks + module AnyInstance + # @private + class StubChain < Chain + # @private + def expectation_fulfilled? + true + end + + private + + def create_message_expectation_on(instance) + proxy = ::RSpec::Mocks.space.proxy_for(instance) + method_name, opts = @expectation_args + opts = (opts || {}).merge(:expected_form => IGNORED_BACKTRACE_LINE) + + stub = proxy.add_stub(method_name, opts, &@expectation_block) + @recorder.stubs[stub.message] << stub + + if RSpec::Mocks.configuration.yield_receiver_to_any_instance_implementation_blocks? + stub.and_yield_receiver_to_implementation + end + + stub + end + + InvocationOrder = + { + :and_return => [:with, nil], + :and_raise => [:with, nil], + :and_yield => [:with, :and_yield, nil], + :and_throw => [:with, nil], + :and_call_original => [:with, nil], + :and_wrap_original => [:with, nil] + }.freeze + + EmptyInvocationOrder = {}.freeze + + def invocation_order + InvocationOrder + end + + def verify_invocation_order(rspec_method_name, *_args, &_block) + return if invocation_order.fetch(rspec_method_name, [nil]).include?(last_message) + raise NoMethodError, "Undefined method #{rspec_method_name}" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/stub_chain_chain.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/stub_chain_chain.rb new file mode 100644 index 00000000..495511c0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/any_instance/stub_chain_chain.rb @@ -0,0 +1,23 @@ +module RSpec + module Mocks + module AnyInstance + # @private + class StubChainChain < StubChain + def initialize(*args) + super + @expectation_fulfilled = false + end + + private + + def create_message_expectation_on(instance) + ::RSpec::Mocks::StubChain.stub_chain_on(instance, *@expectation_args, &@expectation_block) + end + + def invocation_order + EmptyInvocationOrder + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/argument_list_matcher.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/argument_list_matcher.rb new file mode 100644 index 00000000..f8adcd93 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/argument_list_matcher.rb @@ -0,0 +1,117 @@ +# We intentionally do not use the `RSpec::Support.require...` methods +# here so that this file can be loaded individually, as documented +# below. +require 'rspec/mocks/argument_matchers' +require 'rspec/support/fuzzy_matcher' + +module RSpec + module Mocks + # Wrapper for matching arguments against a list of expected values. Used by + # the `with` method on a `MessageExpectation`: + # + # expect(object).to receive(:message).with(:a, 'b', 3) + # object.message(:a, 'b', 3) + # + # Values passed to `with` can be literal values or argument matchers that + # match against the real objects .e.g. + # + # expect(object).to receive(:message).with(hash_including(:a => 'b')) + # + # Can also be used directly to match the contents of any `Array`. This + # enables 3rd party mocking libs to take advantage of rspec's argument + # matching without using the rest of rspec-mocks. + # + # require 'rspec/mocks/argument_list_matcher' + # include RSpec::Mocks::ArgumentMatchers + # + # arg_list_matcher = RSpec::Mocks::ArgumentListMatcher.new(123, hash_including(:a => 'b')) + # arg_list_matcher.args_match?(123, :a => 'b') + # + # This class is immutable. + # + # @see ArgumentMatchers + class ArgumentListMatcher + # @private + attr_reader :expected_args + + # @api public + # @param [Array] expected_args a list of expected literals and/or argument matchers + # + # Initializes an `ArgumentListMatcher` with a collection of literal + # values and/or argument matchers. + # + # @see ArgumentMatchers + # @see #args_match? + def initialize(*expected_args) + @expected_args = expected_args + ensure_expected_args_valid! + end + ruby2_keywords :initialize if respond_to?(:ruby2_keywords, true) + + # @api public + # @param [Array] actual_args + # + # Matches each element in the `expected_args` against the element in the same + # position of the arguments passed to `new`. + # + # @see #initialize + def args_match?(*actual_args) + expected_args = resolve_expected_args_based_on(actual_args) + + return false if expected_args.size != actual_args.size + + if RUBY_VERSION >= "3" + # If the expectation was set with keywords, while the actual method was called with a positional hash argument, they don't match. + # If the expectation was set without keywords, e.g., with({a: 1}), then it fine to call it with either foo(a: 1) or foo({a: 1}). + # This corresponds to Ruby semantics, as if the method was def foo(options). + if Hash === expected_args.last && Hash === actual_args.last + if !Hash.ruby2_keywords_hash?(actual_args.last) && Hash.ruby2_keywords_hash?(expected_args.last) + return false + end + end + end + + Support::FuzzyMatcher.values_match?(expected_args, actual_args) + end + ruby2_keywords :args_match? if respond_to?(:ruby2_keywords, true) + + # @private + # Resolves abstract arg placeholders like `no_args` and `any_args` into + # a more concrete arg list based on the provided `actual_args`. + def resolve_expected_args_based_on(actual_args) + return [] if [ArgumentMatchers::NoArgsMatcher::INSTANCE] == expected_args + + any_args_index = expected_args.index { |a| ArgumentMatchers::AnyArgsMatcher::INSTANCE == a } + return expected_args unless any_args_index + + replace_any_args_with_splat_of_anything(any_args_index, actual_args.count) + end + + private + + def replace_any_args_with_splat_of_anything(before_count, actual_args_count) + any_args_count = actual_args_count - expected_args.count + 1 + after_count = expected_args.count - before_count - 1 + + any_args = 1.upto(any_args_count).map { ArgumentMatchers::AnyArgMatcher::INSTANCE } + expected_args.first(before_count) + any_args + expected_args.last(after_count) + end + + def ensure_expected_args_valid! + if expected_args.count { |a| ArgumentMatchers::AnyArgsMatcher::INSTANCE == a } > 1 + raise ArgumentError, "`any_args` can only be passed to " \ + "`with` once but you have passed it multiple times." + elsif expected_args.count > 1 && expected_args.any? { |a| ArgumentMatchers::NoArgsMatcher::INSTANCE == a } + raise ArgumentError, "`no_args` can only be passed as a " \ + "singleton argument to `with` (i.e. `with(no_args)`), " \ + "but you have passed additional arguments." + end + end + + # Value that will match all argument lists. + # + # @private + MATCH_ALL = new(ArgumentMatchers::AnyArgsMatcher::INSTANCE) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/argument_matchers.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/argument_matchers.rb new file mode 100644 index 00000000..5452508c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/argument_matchers.rb @@ -0,0 +1,366 @@ +# This cannot take advantage of our relative requires, since this file is a +# dependency of `rspec/mocks/argument_list_matcher.rb`. See comment there for +# details. +require 'rspec/support/matcher_definition' + +module RSpec + module Mocks + # ArgumentMatchers are placeholders that you can include in message + # expectations to match arguments against a broader check than simple + # equality. + # + # With the exception of `any_args` and `no_args`, they all match against + # the arg in same position in the argument list. + # + # @see ArgumentListMatcher + module ArgumentMatchers + # Acts like an arg splat, matching any number of args at any point in an arg list. + # + # @example + # expect(object).to receive(:message).with(1, 2, any_args) + # + # # matches any of these: + # object.message(1, 2) + # object.message(1, 2, 3) + # object.message(1, 2, 3, 4) + def any_args + AnyArgsMatcher::INSTANCE + end + + # Matches any argument at all. + # + # @example + # expect(object).to receive(:message).with(anything) + def anything + AnyArgMatcher::INSTANCE + end + + # Matches no arguments. + # + # @example + # expect(object).to receive(:message).with(no_args) + def no_args + NoArgsMatcher::INSTANCE + end + + # Matches if the actual argument responds to the specified messages. + # + # @example + # expect(object).to receive(:message).with(duck_type(:hello)) + # expect(object).to receive(:message).with(duck_type(:hello, :goodbye)) + def duck_type(*args) + DuckTypeMatcher.new(*args) + end + + # Matches a boolean value. + # + # @example + # expect(object).to receive(:message).with(boolean()) + def boolean + BooleanMatcher::INSTANCE + end + + # Matches a hash that includes the specified key(s) or key/value pairs. + # Ignores any additional keys. + # + # @example + # expect(object).to receive(:message).with(hash_including(:key => val)) + # expect(object).to receive(:message).with(hash_including(:key)) + # expect(object).to receive(:message).with(hash_including(:key, :key2 => val2)) + def hash_including(*args) + HashIncludingMatcher.new(ArgumentMatchers.anythingize_lonely_keys(*args)) + end + + # Matches a hash that doesn't include the specified key(s) or key/value. + # + # @example + # expect(object).to receive(:message).with(hash_excluding(:key => val)) + # expect(object).to receive(:message).with(hash_excluding(:key)) + # expect(object).to receive(:message).with(hash_excluding(:key, :key2 => :val2)) + def hash_excluding(*args) + HashExcludingMatcher.new(ArgumentMatchers.anythingize_lonely_keys(*args)) + end + + # Matches an array that includes the specified items at least once. + # Ignores duplicates and additional values + # + # @example + # expect(object).to receive(:message).with(array_including(1,2,3)) + # expect(object).to receive(:message).with(array_including([1,2,3])) + def array_including(*args) + actually_an_array = Array === args.first && args.count == 1 ? args.first : args + ArrayIncludingMatcher.new(actually_an_array) + end + + # Matches an array that excludes the specified items. + # + # @example + # expect(object).to receive(:message).with(array_excluding(1,2,3)) + # expect(object).to receive(:message).with(array_excluding([1,2,3])) + def array_excluding(*args) + actually_an_array = Array === args.first && args.count == 1 ? args.first : args + ArrayExcludingMatcher.new(actually_an_array) + end + + alias_method :hash_not_including, :hash_excluding + + # Matches if `arg.instance_of?(klass)` + # + # @example + # expect(object).to receive(:message).with(instance_of(Thing)) + def instance_of(klass) + InstanceOf.new(klass) + end + + alias_method :an_instance_of, :instance_of + + # Matches if `arg.kind_of?(klass)` + # + # @example + # expect(object).to receive(:message).with(kind_of(Thing)) + def kind_of(klass) + KindOf.new(klass) + end + + alias_method :a_kind_of, :kind_of + + # @private + def self.anythingize_lonely_keys(*args) + hash = Hash === args.last ? args.delete_at(-1) : {} + args.each { | arg | hash[arg] = AnyArgMatcher::INSTANCE } + hash + end + + # Intended to be subclassed by stateless, immutable argument matchers. + # Provides a `::INSTANCE` constant for accessing a global + # singleton instance of the matcher. There is no need to construct + # multiple instance since there is no state. It also facilities the + # special case logic we need for some of these matchers, by making it + # easy to do comparisons like: `[klass::INSTANCE] == args` rather than + # `args.count == 1 && klass === args.first`. + # + # @private + class SingletonMatcher + private_class_method :new + + def self.inherited(subklass) + subklass.const_set(:INSTANCE, subklass.send(:new)) + end + end + + # @private + class AnyArgsMatcher < SingletonMatcher + def description + "*(any args)" + end + end + + # @private + class AnyArgMatcher < SingletonMatcher + def ===(_other) + true + end + + def description + "anything" + end + end + + # @private + class NoArgsMatcher < SingletonMatcher + def description + "no args" + end + end + + # @private + class BooleanMatcher < SingletonMatcher + def ===(value) + true == value || false == value + end + + def description + "boolean" + end + end + + # @private + class BaseHashMatcher + def initialize(expected) + @expected = expected + end + + def ===(predicate, actual) + @expected.__send__(predicate) do |k, v| + actual.key?(k) && Support::FuzzyMatcher.values_match?(v, actual[k]) + end + rescue NoMethodError + false + end + + def description(name) + "#{name}(#{formatted_expected_hash.inspect.sub(/^\{/, "").sub(/\}$/, "")})" + end + + private + + def formatted_expected_hash + Hash[ + @expected.map do |k, v| + k = RSpec::Support.rspec_description_for_object(k) + v = RSpec::Support.rspec_description_for_object(v) + + [k, v] + end + ] + end + end + + # @private + class HashIncludingMatcher < BaseHashMatcher + def ===(actual) + super(:all?, actual) + end + + def description + super("hash_including") + end + end + + # @private + class HashExcludingMatcher < BaseHashMatcher + def ===(actual) + super(:none?, actual) + end + + def description + super("hash_not_including") + end + end + + # @private + class ArrayIncludingMatcher + def initialize(expected) + @expected = expected + end + + def ===(actual) + actual = actual.uniq + return true if (actual & @expected).count >= @expected.count + + @expected.uniq.all? do |expected_element| + actual.any? do |actual_element| + RSpec::Support::FuzzyMatcher.values_match?(expected_element, actual_element) + end + end + rescue NoMethodError + false + end + + def description + "array_including(#{formatted_expected_values})" + end + + private + + def formatted_expected_values + @expected.map do |x| + RSpec::Support.rspec_description_for_object(x) + end.join(", ") + end + end + + # @private + class ArrayExcludingMatcher + def initialize(unexpected) + @unexpected = unexpected.uniq + end + + def ===(actual) + actual = actual.uniq + return false unless (actual & @unexpected).empty? + + actual.none? do |actual_element| + @unexpected.any? do |unexpected_element| + RSpec::Support::FuzzyMatcher.values_match?(unexpected_element, actual_element) + end + end + rescue NoMethodError + false + end + + def description + "array_excluding(#{formatted_unexpected_values})" + end + + private + + def formatted_unexpected_values + @unexpected.map do |x| + RSpec::Support.rspec_description_for_object(x) + end.join(", ") + end + end + + # @private + class DuckTypeMatcher + def initialize(*methods_to_respond_to) + @methods_to_respond_to = methods_to_respond_to + end + + def ===(value) + @methods_to_respond_to.all? { |message| value.respond_to?(message) } + end + + def description + "duck_type(#{@methods_to_respond_to.map(&:inspect).join(', ')})" + end + end + + # @private + class InstanceOf + def initialize(klass) + @klass = klass + end + + def ===(actual) + actual.instance_of?(@klass) + end + + def description + "an_instance_of(#{@klass.name})" + end + end + + # @private + class KindOf + def initialize(klass) + @klass = klass + end + + def ===(actual) + actual.kind_of?(@klass) + end + + def description + "kind of #{@klass.name}" + end + end + + matcher_namespace = name + '::' + ::RSpec::Support.register_matcher_definition do |object| + # This is the best we have for now. We should tag all of our matchers + # with a module or something so we can test for it directly. + # + # (Note Module#parent in ActiveSupport is defined in a similar way.) + begin + object.class.name.include?(matcher_namespace) + rescue NoMethodError + # Some objects, like BasicObject, don't implement standard + # reflection methods. + false + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/configuration.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/configuration.rb new file mode 100644 index 00000000..8496bdcc --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/configuration.rb @@ -0,0 +1,212 @@ +module RSpec + module Mocks + # Provides configuration options for rspec-mocks. + class Configuration + def initialize + @allow_message_expectations_on_nil = nil + @yield_receiver_to_any_instance_implementation_blocks = true + @verify_doubled_constant_names = false + @transfer_nested_constants = false + @verify_partial_doubles = false + @temporarily_suppress_partial_double_verification = false + @color = false + end + + # Sets whether RSpec will warn, ignore, or fail a test when + # expectations are set on nil. + # By default, when this flag is not set, warning messages are issued when + # expectations are set on nil. This is to prevent false-positives and to + # catch potential bugs early on. + # When set to `true`, warning messages are suppressed. + # When set to `false`, it will raise an error. + # + # @example + # RSpec.configure do |config| + # config.mock_with :rspec do |mocks| + # mocks.allow_message_expectations_on_nil = false + # end + # end + attr_accessor :allow_message_expectations_on_nil + + def yield_receiver_to_any_instance_implementation_blocks? + @yield_receiver_to_any_instance_implementation_blocks + end + + # Sets whether or not RSpec will yield the receiving instance of a + # message to blocks that are used for any_instance stub implementations. + # When set, the first yielded argument will be the receiving instance. + # Defaults to `true`. + # + # @example + # RSpec.configure do |rspec| + # rspec.mock_with :rspec do |mocks| + # mocks.yield_receiver_to_any_instance_implementation_blocks = false + # end + # end + attr_writer :yield_receiver_to_any_instance_implementation_blocks + + # Adds `stub` and `should_receive` to the given + # modules or classes. This is usually only necessary + # if you application uses some proxy classes that + # "strip themselves down" to a bare minimum set of + # methods and remove `stub` and `should_receive` in + # the process. + # + # @example + # RSpec.configure do |rspec| + # rspec.mock_with :rspec do |mocks| + # mocks.add_stub_and_should_receive_to Delegator + # end + # end + # + def add_stub_and_should_receive_to(*modules) + modules.each do |mod| + Syntax.enable_should(mod) + end + end + + # Provides the ability to set either `expect`, + # `should` or both syntaxes. RSpec uses `expect` + # syntax by default. This is needed if you want to + # explicitly enable `should` syntax and/or explicitly + # disable `expect` syntax. + # + # @example + # RSpec.configure do |rspec| + # rspec.mock_with :rspec do |mocks| + # mocks.syntax = [:expect, :should] + # end + # end + # + def syntax=(*values) + syntaxes = values.flatten + if syntaxes.include?(:expect) + Syntax.enable_expect + else + Syntax.disable_expect + end + + if syntaxes.include?(:should) + Syntax.enable_should + else + Syntax.disable_should + end + end + + # Returns an array with a list of syntaxes + # that are enabled. + # + # @example + # unless RSpec::Mocks.configuration.syntax.include?(:expect) + # raise "this RSpec extension gem requires the rspec-mocks `:expect` syntax" + # end + # + def syntax + syntaxes = [] + syntaxes << :should if Syntax.should_enabled? + syntaxes << :expect if Syntax.expect_enabled? + syntaxes + end + + def verify_doubled_constant_names? + !!@verify_doubled_constant_names + end + + # When this is set to true, an error will be raised when + # `instance_double` or `class_double` is given the name of an undefined + # constant. You probably only want to set this when running your entire + # test suite, with all production code loaded. Setting this for an + # isolated unit test will prevent you from being able to isolate it! + attr_writer :verify_doubled_constant_names + + # Provides a way to perform customisations when verifying doubles. + # + # @example + # RSpec::Mocks.configuration.before_verifying_doubles do |ref| + # ref.some_method! + # end + def before_verifying_doubles(&block) + verifying_double_callbacks << block + end + alias :when_declaring_verifying_double :before_verifying_doubles + + # @api private + # Returns an array of blocks to call when verifying doubles + def verifying_double_callbacks + @verifying_double_callbacks ||= [] + end + + def transfer_nested_constants? + !!@transfer_nested_constants + end + + # Sets the default for the `transfer_nested_constants` option when + # stubbing constants. + attr_writer :transfer_nested_constants + + # When set to true, partial mocks will be verified the same as object + # doubles. Any stubs will have their arguments checked against the original + # method, and methods that do not exist cannot be stubbed. + def verify_partial_doubles=(val) + @verify_partial_doubles = !!val + end + + def verify_partial_doubles? + @verify_partial_doubles + end + + # @private + # Used to track whether we are temporarily suppressing verifying partial + # doubles with `without_partial_double_verification { ... }` + attr_accessor :temporarily_suppress_partial_double_verification + + if ::RSpec.respond_to?(:configuration) + def color? + ::RSpec.configuration.color_enabled? + end + else + # Indicates whether or not diffs should be colored. + # Delegates to rspec-core's color option if rspec-core + # is loaded; otherwise you can set it here. + attr_writer :color + + # Indicates whether or not diffs should be colored. + # Delegates to rspec-core's color option if rspec-core + # is loaded; otherwise you can set it here. + def color? + @color + end + end + + # Monkey-patch `Marshal.dump` to enable dumping of mocked or stubbed + # objects. By default this will not work since RSpec mocks works by + # adding singleton methods that cannot be serialized. This patch removes + # these singleton methods before serialization. Setting to falsey removes + # the patch. + # + # This method is idempotent. + def patch_marshal_to_support_partial_doubles=(val) + if val + RSpec::Mocks::MarshalExtension.patch! + else + RSpec::Mocks::MarshalExtension.unpatch! + end + end + + # @api private + # Resets the configured syntax to the default. + def reset_syntaxes_to_default + self.syntax = [:should, :expect] + RSpec::Mocks::Syntax.warn_about_should! + end + end + + # Mocks specific configuration, as distinct from `RSpec.configuration` + # which is core RSpec configuration. + def self.configuration + @configuration ||= Configuration.new + end + + configuration.reset_syntaxes_to_default + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/error_generator.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/error_generator.rb new file mode 100644 index 00000000..8e7e2c1f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/error_generator.rb @@ -0,0 +1,390 @@ +RSpec::Support.require_rspec_support "object_formatter" + +module RSpec + module Mocks + # Raised when a message expectation is not satisfied. + MockExpectationError = Class.new(Exception) + + # Raised when a test double is used after it has been torn + # down (typically at the end of an rspec-core example). + ExpiredTestDoubleError = Class.new(MockExpectationError) + + # Raised when doubles or partial doubles are used outside of the per-test lifecycle. + OutsideOfExampleError = Class.new(StandardError) + + # Raised when an expectation customization method (e.g. `with`, + # `and_return`) is called on a message expectation which has already been + # invoked. + MockExpectationAlreadyInvokedError = Class.new(Exception) + + # Raised for situations that RSpec cannot support due to mutations made + # externally on arguments that RSpec is holding onto to use for later + # comparisons. + # + # @deprecated We no longer raise this error but the constant remains until + # RSpec 4 for SemVer reasons. + CannotSupportArgMutationsError = Class.new(StandardError) + + # @private + UnsupportedMatcherError = Class.new(StandardError) + # @private + NegationUnsupportedError = Class.new(StandardError) + # @private + VerifyingDoubleNotDefinedError = Class.new(StandardError) + + # @private + class ErrorGenerator + attr_writer :opts + + def initialize(target=nil) + @target = target + end + + # @private + def opts + @opts ||= {} + end + + # @private + def raise_unexpected_message_error(message, args) + __raise "#{intro} received unexpected message :#{message} with #{format_args(args)}" + end + + # @private + def raise_unexpected_message_args_error(expectation, args_for_multiple_calls, source_id=nil) + __raise error_message(expectation, args_for_multiple_calls), nil, source_id + end + + # @private + def raise_missing_default_stub_error(expectation, args_for_multiple_calls) + __raise( + error_message(expectation, args_for_multiple_calls) + + "\n Please stub a default value first if message might be received with other args as well. \n" + ) + end + + # @private + def raise_similar_message_args_error(expectation, args_for_multiple_calls, backtrace_line=nil) + __raise error_message(expectation, args_for_multiple_calls), backtrace_line + end + + def default_error_message(expectation, expected_args, actual_args) + "#{intro} received #{expectation.message.inspect} #{unexpected_arguments_message(expected_args, actual_args)}".dup + end + + # rubocop:disable Metrics/ParameterLists + # @private + def raise_expectation_error(message, expected_received_count, argument_list_matcher, + actual_received_count, expectation_count_type, args, + backtrace_line=nil, source_id=nil) + expected_part = expected_part_of_expectation_error(expected_received_count, expectation_count_type, argument_list_matcher) + received_part = received_part_of_expectation_error(actual_received_count, args) + __raise "(#{intro(:unwrapped)}).#{message}#{format_args(args)}\n #{expected_part}\n #{received_part}", backtrace_line, source_id + end + # rubocop:enable Metrics/ParameterLists + + # @private + def raise_unimplemented_error(doubled_module, method_name, object) + message = case object + when InstanceVerifyingDouble + "the %s class does not implement the instance method: %s".dup << + if ObjectMethodReference.for(doubled_module, method_name).implemented? + ". Perhaps you meant to use `class_double` instead?" + else + "" + end + when ClassVerifyingDouble + "the %s class does not implement the class method: %s".dup << + if InstanceMethodReference.for(doubled_module, method_name).implemented? + ". Perhaps you meant to use `instance_double` instead?" + else + "" + end + else + "%s does not implement: %s" + end + + __raise message % [doubled_module.description, method_name] + end + + # @private + def raise_non_public_error(method_name, visibility) + raise NoMethodError, "%s method `%s' called on %s" % [ + visibility, method_name, intro + ] + end + + # @private + def raise_invalid_arguments_error(verifier) + __raise verifier.error_message + end + + # @private + def raise_expired_test_double_error + raise ExpiredTestDoubleError, + "#{intro} was originally created in one example but has leaked into " \ + "another example and can no longer be used. rspec-mocks' doubles are " \ + "designed to only last for one example, and you need to create a new " \ + "one in each example you wish to use it for." + end + + # @private + def describe_expectation(verb, message, expected_received_count, _actual_received_count, args) + "#{verb} #{message}#{format_args(args)} #{count_message(expected_received_count)}" + end + + # @private + def raise_out_of_order_error(message) + __raise "#{intro} received :#{message} out of order" + end + + # @private + def raise_missing_block_error(args_to_yield) + __raise "#{intro} asked to yield |#{arg_list(args_to_yield)}| but no block was passed" + end + + # @private + def raise_wrong_arity_error(args_to_yield, signature) + __raise "#{intro} yielded |#{arg_list(args_to_yield)}| to block with #{signature.description}" + end + + # @private + def raise_only_valid_on_a_partial_double(method) + __raise "#{intro} is a pure test double. `#{method}` is only " \ + "available on a partial double." + end + + # @private + def raise_expectation_on_unstubbed_method(method) + __raise "#{intro} expected to have received #{method}, but that " \ + "object is not a spy or method has not been stubbed." + end + + # @private + def raise_expectation_on_mocked_method(method) + __raise "#{intro} expected to have received #{method}, but that " \ + "method has been mocked instead of stubbed or spied." + end + + # @private + def raise_double_negation_error(wrapped_expression) + __raise "Isn't life confusing enough? You've already set a " \ + "negative message expectation and now you are trying to " \ + "negate it again with `never`. What does an expression like " \ + "`#{wrapped_expression}.not_to receive(:msg).never` even mean?" + end + + # @private + def raise_verifying_double_not_defined_error(ref) + notify(VerifyingDoubleNotDefinedError.new( + "#{ref.description.inspect} is not a defined constant. " \ + "Perhaps you misspelt it? " \ + "Disable check with `verify_doubled_constant_names` configuration option." + )) + end + + # @private + def raise_have_received_disallowed(type, reason) + __raise "Using #{type}(...) with the `have_received` " \ + "matcher is not supported#{reason}." + end + + # @private + def raise_cant_constrain_count_for_negated_have_received_error(count_constraint) + __raise "can't use #{count_constraint} when negative" + end + + # @private + def raise_method_not_stubbed_error(method_name) + __raise "The method `#{method_name}` was not stubbed or was already unstubbed" + end + + # @private + def raise_already_invoked_error(message, calling_customization) + error_message = "The message expectation for #{intro}.#{message} has already been invoked " \ + "and cannot be modified further (e.g. using `#{calling_customization}`). All message expectation " \ + "customizations must be applied before it is used for the first time." + + notify MockExpectationAlreadyInvokedError.new(error_message) + end + + def raise_expectation_on_nil_error(method_name) + __raise expectation_on_nil_message(method_name) + end + + def expectation_on_nil_message(method_name) + "An expectation of `:#{method_name}` was set on `nil`. " \ + "To allow expectations on `nil` and suppress this message, set `RSpec::Mocks.configuration.allow_message_expectations_on_nil` to `true`. " \ + "To disallow expectations on `nil`, set `RSpec::Mocks.configuration.allow_message_expectations_on_nil` to `false`" + end + + # @private + def intro(unwrapped=false) + case @target + when TestDouble then TestDoubleFormatter.format(@target, unwrapped) + when Class then + formatted = "#{@target.inspect} (class)" + return formatted if unwrapped + "#<#{formatted}>" + when NilClass then "nil" + else @target.inspect + end + end + + # @private + def method_call_args_description(args, generic_prefix=" with arguments: ", matcher_prefix=" with ") + case args.first + when ArgumentMatchers::AnyArgsMatcher then "#{matcher_prefix}any arguments" + when ArgumentMatchers::NoArgsMatcher then "#{matcher_prefix}no arguments" + else + if yield + "#{generic_prefix}#{format_args(args)}" + else + "" + end + end + end + + private + + def received_part_of_expectation_error(actual_received_count, args) + "received: #{count_message(actual_received_count)}" + + method_call_args_description(args) do + actual_received_count > 0 && args.length > 0 + end + end + + def expected_part_of_expectation_error(expected_received_count, expectation_count_type, argument_list_matcher) + "expected: #{count_message(expected_received_count, expectation_count_type)}" + + method_call_args_description(argument_list_matcher.expected_args) do + argument_list_matcher.expected_args.length > 0 + end + end + + def unexpected_arguments_message(expected_args_string, actual_args_string) + "with unexpected arguments\n expected: #{expected_args_string}\n got: #{actual_args_string}" + end + + def error_message(expectation, args_for_multiple_calls) + expected_args = format_args(expectation.expected_args) + actual_args = format_received_args(args_for_multiple_calls) + + if RSpec::Support::RubyFeatures.distincts_kw_args_from_positional_hash? + expected_hash = expectation.expected_args.last + actual_hash = args_for_multiple_calls.last.last + if Hash === expected_hash && Hash === actual_hash && + (Hash.ruby2_keywords_hash?(expected_hash) != Hash.ruby2_keywords_hash?(actual_hash)) + + actual_description = Hash.ruby2_keywords_hash?(actual_hash) ? " (keyword arguments)" : " (options hash)" + expected_description = Hash.ruby2_keywords_hash?(expected_hash) ? " (keyword arguments)" : " (options hash)" + + if actual_description != expected_description + actual_args += actual_description + expected_args += expected_description + end + end + end + + message = default_error_message(expectation, expected_args, actual_args) + + if args_for_multiple_calls.one? + diff = diff_message(expectation.expected_args, args_for_multiple_calls.first) + if RSpec::Mocks.configuration.color? + message << "\nDiff:#{diff}" unless diff.gsub(/\e\[\d+m/, '').strip.empty? + else + message << "\nDiff:#{diff}" unless diff.strip.empty? + end + end + + message + end + + def diff_message(expected_args, actual_args) + formatted_expected_args = expected_args.map do |x| + RSpec::Support.rspec_description_for_object(x) + end + + formatted_expected_args, actual_args = unpack_string_args(formatted_expected_args, actual_args) + + differ.diff(actual_args, formatted_expected_args) + end + + def unpack_string_args(formatted_expected_args, actual_args) + if [formatted_expected_args, actual_args].all? { |x| list_of_exactly_one_string?(x) } + [formatted_expected_args.first, actual_args.first] + else + [formatted_expected_args, actual_args] + end + end + + def list_of_exactly_one_string?(args) + Array === args && args.count == 1 && String === args.first + end + + def differ + RSpec::Support::Differ.new(:color => RSpec::Mocks.configuration.color?) + end + + def __raise(message, backtrace_line=nil, source_id=nil) + message = opts[:message] unless opts[:message].nil? + exception = RSpec::Mocks::MockExpectationError.new(message) + prepend_to_backtrace(exception, backtrace_line) if backtrace_line + notify exception, :source_id => source_id + end + + if RSpec::Support::Ruby.jruby? + def prepend_to_backtrace(exception, line) + raise exception + rescue RSpec::Mocks::MockExpectationError => with_backtrace + with_backtrace.backtrace.unshift(line) + end + else + def prepend_to_backtrace(exception, line) + exception.set_backtrace(caller.unshift line) + end + end + + def notify(*args) + RSpec::Support.notify_failure(*args) + end + + def format_args(args) + return "(no args)" if args.empty? + "(#{arg_list(args)})" + end + + def arg_list(args) + args.map { |arg| RSpec::Support::ObjectFormatter.format(arg) }.join(", ") + end + + def format_received_args(args_for_multiple_calls) + grouped_args(args_for_multiple_calls).map do |args_for_one_call, index| + "#{format_args(args_for_one_call)}#{group_count(index, args_for_multiple_calls)}" + end.join("\n ") + end + + def count_message(count, expectation_count_type=nil) + return "at least #{times(count.abs)}" if count < 0 || expectation_count_type == :at_least + return "at most #{times(count)}" if expectation_count_type == :at_most + times(count) + end + + def times(count) + "#{count} time#{count == 1 ? '' : 's'}" + end + + def grouped_args(args) + Hash[args.group_by { |x| x }.map { |k, v| [k, v.count] }] + end + + def group_count(index, args) + " (#{times(index)})" if args.size > 1 || index > 1 + end + end + + # @private + def self.error_generator + @error_generator ||= ErrorGenerator.new + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/example_methods.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/example_methods.rb new file mode 100644 index 00000000..5531b28b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/example_methods.rb @@ -0,0 +1,434 @@ +RSpec::Support.require_rspec_mocks 'object_reference' + +module RSpec + module Mocks + # Contains methods intended to be used from within code examples. + # Mix this in to your test context (such as a test framework base class) + # to use rspec-mocks with your test framework. If you're using rspec-core, + # it'll take care of doing this for you. + module ExampleMethods + include RSpec::Mocks::ArgumentMatchers + + # @overload double() + # @overload double(name) + # @param name [String/Symbol] name or description to be used in failure messages + # @overload double(stubs) + # @param stubs (Hash) hash of message/return-value pairs + # @overload double(name, stubs) + # @param name [String/Symbol] name or description to be used in failure messages + # @param stubs (Hash) hash of message/return-value pairs + # @return (Double) + # + # Constructs an instance of [RSpec::Mocks::Double](RSpec::Mocks::Double) configured + # with an optional name, used for reporting in failure messages, and an optional + # hash of message/return-value pairs. + # + # @example + # book = double("book", :title => "The RSpec Book") + # book.title #=> "The RSpec Book" + # + # card = double("card", :suit => "Spades", :rank => "A") + # card.suit #=> "Spades" + # card.rank #=> "A" + # + def double(*args) + ExampleMethods.declare_double(Double, *args) + end + + # @overload instance_double(doubled_class) + # @param doubled_class [String, Class] + # @overload instance_double(doubled_class, name) + # @param doubled_class [String, Class] + # @param name [String/Symbol] name or description to be used in failure messages + # @overload instance_double(doubled_class, stubs) + # @param doubled_class [String, Class] + # @param stubs [Hash] hash of message/return-value pairs + # @overload instance_double(doubled_class, name, stubs) + # @param doubled_class [String, Class] + # @param name [String/Symbol] name or description to be used in failure messages + # @param stubs [Hash] hash of message/return-value pairs + # @return InstanceVerifyingDouble + # + # Constructs a test double against a specific class. If the given class + # name has been loaded, only instance methods defined on the class are + # allowed to be stubbed. In all other ways it behaves like a + # [double](double). + def instance_double(doubled_class, *args) + ref = ObjectReference.for(doubled_class) + ExampleMethods.declare_verifying_double(InstanceVerifyingDouble, ref, *args) + end + + # @overload class_double(doubled_class) + # @param doubled_class [String, Module] + # @overload class_double(doubled_class, name) + # @param doubled_class [String, Module] + # @param name [String/Symbol] name or description to be used in failure messages + # @overload class_double(doubled_class, stubs) + # @param doubled_class [String, Module] + # @param stubs [Hash] hash of message/return-value pairs + # @overload class_double(doubled_class, name, stubs) + # @param doubled_class [String, Module] + # @param name [String/Symbol] name or description to be used in failure messages + # @param stubs [Hash] hash of message/return-value pairs + # @return ClassVerifyingDouble + # + # Constructs a test double against a specific class. If the given class + # name has been loaded, only class methods defined on the class are + # allowed to be stubbed. In all other ways it behaves like a + # [double](double). + def class_double(doubled_class, *args) + ref = ObjectReference.for(doubled_class) + ExampleMethods.declare_verifying_double(ClassVerifyingDouble, ref, *args) + end + + # @overload object_double(object_or_name) + # @param object_or_name [String, Object] + # @overload object_double(object_or_name, name) + # @param object_or_name [String, Object] + # @param name [String/Symbol] name or description to be used in failure messages + # @overload object_double(object_or_name, stubs) + # @param object_or_name [String, Object] + # @param stubs [Hash] hash of message/return-value pairs + # @overload object_double(object_or_name, name, stubs) + # @param object_or_name [String, Object] + # @param name [String/Symbol] name or description to be used in failure messages + # @param stubs [Hash] hash of message/return-value pairs + # @return ObjectVerifyingDouble + # + # Constructs a test double against a specific object. Only the methods + # the object responds to are allowed to be stubbed. If a String argument + # is provided, it is assumed to reference a constant object which is used + # for verification. In all other ways it behaves like a [double](double). + def object_double(object_or_name, *args) + ref = ObjectReference.for(object_or_name, :allow_direct_object_refs) + ExampleMethods.declare_verifying_double(ObjectVerifyingDouble, ref, *args) + end + + # @overload spy() + # @overload spy(name) + # @param name [String/Symbol] name or description to be used in failure messages + # @overload spy(stubs) + # @param stubs (Hash) hash of message/return-value pairs + # @overload spy(name, stubs) + # @param name [String/Symbol] name or description to be used in failure messages + # @param stubs (Hash) hash of message/return-value pairs + # @return (Double) + # + # Constructs a test double that is optimized for use with + # `have_received`. With a normal double one has to stub methods in order + # to be able to spy them. A spy automatically spies on all methods. + def spy(*args) + double(*args).as_null_object + end + + # @overload instance_spy(doubled_class) + # @param doubled_class [String, Class] + # @overload instance_spy(doubled_class, name) + # @param doubled_class [String, Class] + # @param name [String/Symbol] name or description to be used in failure messages + # @overload instance_spy(doubled_class, stubs) + # @param doubled_class [String, Class] + # @param stubs [Hash] hash of message/return-value pairs + # @overload instance_spy(doubled_class, name, stubs) + # @param doubled_class [String, Class] + # @param name [String/Symbol] name or description to be used in failure messages + # @param stubs [Hash] hash of message/return-value pairs + # @return InstanceVerifyingDouble + # + # Constructs a test double that is optimized for use with `have_received` + # against a specific class. If the given class name has been loaded, only + # instance methods defined on the class are allowed to be stubbed. With + # a normal double one has to stub methods in order to be able to spy + # them. An instance_spy automatically spies on all instance methods to + # which the class responds. + def instance_spy(*args) + instance_double(*args).as_null_object + end + + # @overload object_spy(object_or_name) + # @param object_or_name [String, Object] + # @overload object_spy(object_or_name, name) + # @param object_or_name [String, Class] + # @param name [String/Symbol] name or description to be used in failure messages + # @overload object_spy(object_or_name, stubs) + # @param object_or_name [String, Object] + # @param stubs [Hash] hash of message/return-value pairs + # @overload object_spy(object_or_name, name, stubs) + # @param object_or_name [String, Class] + # @param name [String/Symbol] name or description to be used in failure messages + # @param stubs [Hash] hash of message/return-value pairs + # @return ObjectVerifyingDouble + # + # Constructs a test double that is optimized for use with `have_received` + # against a specific object. Only instance methods defined on the object + # are allowed to be stubbed. With a normal double one has to stub + # methods in order to be able to spy them. An object_spy automatically + # spies on all methods to which the object responds. + def object_spy(*args) + object_double(*args).as_null_object + end + + # @overload class_spy(doubled_class) + # @param doubled_class [String, Module] + # @overload class_spy(doubled_class, name) + # @param doubled_class [String, Class] + # @param name [String/Symbol] name or description to be used in failure messages + # @overload class_spy(doubled_class, stubs) + # @param doubled_class [String, Module] + # @param stubs [Hash] hash of message/return-value pairs + # @overload class_spy(doubled_class, name, stubs) + # @param doubled_class [String, Class] + # @param name [String/Symbol] name or description to be used in failure messages + # @param stubs [Hash] hash of message/return-value pairs + # @return ClassVerifyingDouble + # + # Constructs a test double that is optimized for use with `have_received` + # against a specific class. If the given class name has been loaded, + # only class methods defined on the class are allowed to be stubbed. + # With a normal double one has to stub methods in order to be able to spy + # them. An class_spy automatically spies on all class methods to which the + # class responds. + def class_spy(*args) + class_double(*args).as_null_object + end + + # Disables warning messages about expectations being set on nil. + # + # By default warning messages are issued when expectations are set on + # nil. This is to prevent false-positives and to catch potential bugs + # early on. + # @deprecated Use {RSpec::Mocks::Configuration#allow_message_expectations_on_nil} instead. + def allow_message_expectations_on_nil + RSpec::Mocks.space.proxy_for(nil).warn_about_expectations = false + end + + # Stubs the named constant with the given value. + # Like method stubs, the constant will be restored + # to its original value (or lack of one, if it was + # undefined) when the example completes. + # + # @param constant_name [String] The fully qualified name of the constant. The current + # constant scoping at the point of call is not considered. + # @param value [Object] The value to make the constant refer to. When the + # example completes, the constant will be restored to its prior state. + # @param options [Hash] Stubbing options. + # @option options :transfer_nested_constants [Boolean, Array] Determines + # what nested constants, if any, will be transferred from the original value + # of the constant to the new value of the constant. This only works if both + # the original and new values are modules (or classes). + # @return [Object] the stubbed value of the constant + # + # @example + # stub_const("MyClass", Class.new) # => Replaces (or defines) MyClass with a new class object. + # stub_const("SomeModel::PER_PAGE", 5) # => Sets SomeModel::PER_PAGE to 5. + # + # class CardDeck + # SUITS = [:Spades, :Diamonds, :Clubs, :Hearts] + # NUM_CARDS = 52 + # end + # + # stub_const("CardDeck", Class.new) + # CardDeck::SUITS # => uninitialized constant error + # CardDeck::NUM_CARDS # => uninitialized constant error + # + # stub_const("CardDeck", Class.new, :transfer_nested_constants => true) + # CardDeck::SUITS # => our suits array + # CardDeck::NUM_CARDS # => 52 + # + # stub_const("CardDeck", Class.new, :transfer_nested_constants => [:SUITS]) + # CardDeck::SUITS # => our suits array + # CardDeck::NUM_CARDS # => uninitialized constant error + def stub_const(constant_name, value, options={}) + ConstantMutator.stub(constant_name, value, options) + end + + # Hides the named constant with the given value. The constant will be + # undefined for the duration of the test. + # + # Like method stubs, the constant will be restored to its original value + # when the example completes. + # + # @param constant_name [String] The fully qualified name of the constant. + # The current constant scoping at the point of call is not considered. + # + # @example + # hide_const("MyClass") # => MyClass is now an undefined constant + def hide_const(constant_name) + ConstantMutator.hide(constant_name) + end + + # Verifies that the given object received the expected message during the + # course of the test. On a spy objects or as null object doubles this + # works for any method, on other objects the method must have + # been stubbed beforehand in order for messages to be verified. + # + # Stubbing and verifying messages received in this way implements the + # Test Spy pattern. + # + # @param method_name [Symbol] name of the method expected to have been + # called. + # + # @example + # invitation = double('invitation', accept: true) + # user.accept_invitation(invitation) + # expect(invitation).to have_received(:accept) + # + # # You can also use most message expectations: + # expect(invitation).to have_received(:accept).with(mailer).once + # + # @note `have_received(...).with(...)` is unable to work properly when + # passed arguments are mutated after the spy records the received message. + def have_received(method_name, &block) + Matchers::HaveReceived.new(method_name, &block) + end + + # Turns off the verifying of partial doubles for the duration of the + # block, this is useful in situations where methods are defined at run + # time and you wish to define stubs for them but not turn off partial + # doubles for the entire run suite. (e.g. view specs in rspec-rails). + def without_partial_double_verification + original_state = Mocks.configuration.temporarily_suppress_partial_double_verification + Mocks.configuration.temporarily_suppress_partial_double_verification = true + yield + ensure + Mocks.configuration.temporarily_suppress_partial_double_verification = original_state + end + + # @method expect + # Used to wrap an object in preparation for setting a mock expectation + # on it. + # + # @example + # expect(obj).to receive(:foo).with(5).and_return(:return_value) + # + # @note This method is usually provided by rspec-expectations. However, + # if you use rspec-mocks without rspec-expectations, there's a definition + # of it that is made available here. If you disable the `:expect` syntax + # this method will be undefined. + + # @method allow + # Used to wrap an object in preparation for stubbing a method + # on it. + # + # @example + # allow(dbl).to receive(:foo).with(5).and_return(:return_value) + # + # @note If you disable the `:expect` syntax this method will be undefined. + + # @method expect_any_instance_of + # Used to wrap a class in preparation for setting a mock expectation + # on instances of it. + # + # @example + # expect_any_instance_of(MyClass).to receive(:foo) + # + # @note If you disable the `:expect` syntax this method will be undefined. + + # @method allow_any_instance_of + # Used to wrap a class in preparation for stubbing a method + # on instances of it. + # + # @example + # allow_any_instance_of(MyClass).to receive(:foo) + # + # @note This is only available when you have enabled the `expect` syntax. + + # @method receive + # Used to specify a message that you expect or allow an object + # to receive. The object returned by `receive` supports the same + # fluent interface that `should_receive` and `stub` have always + # supported, allowing you to constrain the arguments or number of + # times, and configure how the object should respond to the message. + # + # @example + # expect(obj).to receive(:hello).with("world").exactly(3).times + # + # @note If you disable the `:expect` syntax this method will be undefined. + + # @method receive_messages + # Shorthand syntax used to setup message(s), and their return value(s), + # that you expect or allow an object to receive. The method takes a hash + # of messages and their respective return values. Unlike with `receive`, + # you cannot apply further customizations using a block or the fluent + # interface. + # + # @example + # allow(obj).to receive_messages(:speak => "Hello World") + # allow(obj).to receive_messages(:speak => "Hello", :meow => "Meow") + # + # @note If you disable the `:expect` syntax this method will be undefined. + + # @method receive_message_chain + # @overload receive_message_chain(method1, method2) + # @overload receive_message_chain("method1.method2") + # @overload receive_message_chain(method1, method_to_value_hash) + # + # stubs/mocks a chain of messages on an object or test double. + # + # ## Warning: + # + # Chains can be arbitrarily long, which makes it quite painless to + # violate the Law of Demeter in violent ways, so you should consider any + # use of `receive_message_chain` a code smell. Even though not all code smells + # indicate real problems (think fluent interfaces), `receive_message_chain` still + # results in brittle examples. For example, if you write + # `allow(foo).to receive_message_chain(:bar, :baz => 37)` in a spec and then the + # implementation calls `foo.baz.bar`, the stub will not work. + # + # @example + # allow(double).to receive_message_chain("foo.bar") { :baz } + # allow(double).to receive_message_chain(:foo, :bar => :baz) + # allow(double).to receive_message_chain(:foo, :bar) { :baz } + # + # # Given any of ^^ these three forms ^^: + # double.foo.bar # => :baz + # + # # Common use in Rails/ActiveRecord: + # allow(Article).to receive_message_chain("recent.published") { [Article.new] } + # + # @note If you disable the `:expect` syntax this method will be undefined. + + # @private + def self.included(klass) + klass.class_exec do + # This gets mixed in so that if `RSpec::Matchers` is included in + # `klass` later, its definition of `expect` will take precedence. + include ExpectHost unless method_defined?(:expect) + end + end + + # @private + def self.extended(object) + # This gets extended in so that if `RSpec::Matchers` is included in + # `klass` later, its definition of `expect` will take precedence. + object.extend ExpectHost unless object.respond_to?(:expect) + end + + # @private + def self.declare_verifying_double(type, ref, *args) + if RSpec::Mocks.configuration.verify_doubled_constant_names? && + !ref.defined? + + RSpec::Mocks.error_generator.raise_verifying_double_not_defined_error(ref) + end + + RSpec::Mocks.configuration.verifying_double_callbacks.each do |block| + block.call(ref) + end + + declare_double(type, ref, *args) + end + + # @private + def self.declare_double(type, *args) + args << {} unless Hash === args.last + type.new(*args) + end + + # This module exists to host the `expect` method for cases where + # rspec-mocks is used w/o rspec-expectations. + module ExpectHost + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/instance_method_stasher.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/instance_method_stasher.rb new file mode 100644 index 00000000..12edec2f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/instance_method_stasher.rb @@ -0,0 +1,146 @@ +module RSpec + module Mocks + # @private + class InstanceMethodStasher + def initialize(object, method) + @object = object + @method = method + @klass = (class << object; self; end) + + @original_method = nil + @method_is_stashed = false + end + + attr_reader :original_method + + if RUBY_VERSION.to_f < 1.9 + # @private + def method_is_stashed? + @method_is_stashed + end + + # @private + def stash + return if !method_defined_directly_on_klass? || @method_is_stashed + + @klass.__send__(:alias_method, stashed_method_name, @method) + @method_is_stashed = true + end + + # @private + def stashed_method_name + "obfuscated_by_rspec_mocks__#{@method}" + end + + # @private + def restore + return unless @method_is_stashed + + if @klass.__send__(:method_defined?, @method) + @klass.__send__(:undef_method, @method) + end + @klass.__send__(:alias_method, @method, stashed_method_name) + @klass.__send__(:remove_method, stashed_method_name) + @method_is_stashed = false + end + else + + # @private + def method_is_stashed? + !!@original_method + end + + # @private + def stash + return unless method_defined_directly_on_klass? + @original_method ||= ::RSpec::Support.method_handle_for(@object, @method) + @klass.__send__(:undef_method, @method) + end + + # @private + def restore + return unless @original_method + + if @klass.__send__(:method_defined?, @method) + @klass.__send__(:undef_method, @method) + end + + handle_restoration_failures do + @klass.__send__(:define_method, @method, @original_method) + end + + @original_method = nil + end + end + + if RUBY_DESCRIPTION.include?('2.0.0p247') || RUBY_DESCRIPTION.include?('2.0.0p195') + # ruby 2.0.0-p247 and 2.0.0-p195 both have a bug that we can't work around :(. + # https://bugs.ruby-lang.org/issues/8686 + def handle_restoration_failures + yield + rescue TypeError + RSpec.warn_with( + "RSpec failed to properly restore a partial double (#{@object.inspect}) " \ + "to its original state due to a known bug in MRI 2.0.0-p195 & p247 " \ + "(https://bugs.ruby-lang.org/issues/8686). This object may remain " \ + "screwed up for the rest of this process. Please upgrade to 2.0.0-p353 or above.", + :call_site => nil, :use_spec_location_as_call_site => true + ) + end + else + def handle_restoration_failures + # No known reasons for restoration to fail on other rubies. + yield + end + end + + private + + # @private + def method_defined_directly_on_klass? + method_defined_on_klass? && method_owned_by_klass? + end + + # @private + def method_defined_on_klass?(klass=@klass) + MethodReference.method_defined_at_any_visibility?(klass, @method) + end + + def method_owned_by_klass? + owner = @klass.instance_method(@method).owner + + # On Ruby 2.0.0+ the owner of a method on a class which has been + # `prepend`ed may actually be an instance, e.g. + # `#`, rather than the expected `MyClass`. + owner = owner.class unless Module === owner + + # On some 1.9s (e.g. rubinius) aliased methods + # can report the wrong owner. Example: + # class MyClass + # class << self + # alias alternate_new new + # end + # end + # + # MyClass.owner(:alternate_new) returns `Class` when incorrect, + # but we need to consider the owner to be `MyClass` because + # it is not actually available on `Class` but is on `MyClass`. + # Hence, we verify that the owner actually has the method defined. + # If the given owner does not have the method defined, we assume + # that the method is actually owned by @klass. + # + # On 1.8, aliased methods can also report the wrong owner. Example: + # module M + # def a; end + # module_function :a + # alias b a + # module_function :b + # end + # The owner of M.b is the raw Module object, instead of the expected + # singleton class of the module + return true if RUBY_VERSION < '1.9' && owner == @object + owner == @klass || !(method_defined_on_klass?(owner)) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/marshal_extension.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/marshal_extension.rb new file mode 100644 index 00000000..cfa9c1a7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/marshal_extension.rb @@ -0,0 +1,41 @@ +module RSpec + module Mocks + # Support for `patch_marshal_to_support_partial_doubles` configuration. + # + # @private + class MarshalExtension + def self.patch! + return if Marshal.respond_to?(:dump_with_rspec_mocks) + + Marshal.instance_eval do + class << self + def dump_with_rspec_mocks(object, *rest) + if !::RSpec::Mocks.space.registered?(object) || NilClass === object + dump_without_rspec_mocks(object, *rest) + else + dump_without_rspec_mocks(object.dup, *rest) + end + end + + alias_method :dump_without_rspec_mocks, :dump + undef_method :dump + alias_method :dump, :dump_with_rspec_mocks + end + end + end + + def self.unpatch! + return unless Marshal.respond_to?(:dump_with_rspec_mocks) + + Marshal.instance_eval do + class << self + undef_method :dump_with_rspec_mocks + undef_method :dump + alias_method :dump, :dump_without_rspec_mocks + undef_method :dump_without_rspec_mocks + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/matchers/expectation_customization.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/matchers/expectation_customization.rb new file mode 100644 index 00000000..81e64279 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/matchers/expectation_customization.rb @@ -0,0 +1,20 @@ +module RSpec + module Mocks + module Matchers + # @private + class ExpectationCustomization + attr_accessor :block + + def initialize(method_name, args, block) + @method_name = method_name + @args = args + @block = block + end + + def playback_onto(expectation) + expectation.__send__(@method_name, *@args, &@block) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/matchers/have_received.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/matchers/have_received.rb new file mode 100644 index 00000000..cf4852b4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/matchers/have_received.rb @@ -0,0 +1,134 @@ +module RSpec + module Mocks + module Matchers + # @private + class HaveReceived + include Matcher + + COUNT_CONSTRAINTS = %w[exactly at_least at_most times time once twice thrice] + ARGS_CONSTRAINTS = %w[with] + CONSTRAINTS = COUNT_CONSTRAINTS + ARGS_CONSTRAINTS + %w[ordered] + + def initialize(method_name, &block) + @method_name = method_name + @block = block + @constraints = [] + @subject = nil + end + + def matcher_name + "have_received" + end + + def matches?(subject, &block) + @block ||= block + @subject = subject + @expectation = expect + mock_proxy.ensure_implemented(@method_name) + + expected_messages_received_in_order? + end + + def does_not_match?(subject) + @subject = subject + ensure_count_unconstrained + @expectation = expect.never + mock_proxy.ensure_implemented(@method_name) + expected_messages_received_in_order? + end + + def failure_message + capture_failure_message + end + + def failure_message_when_negated + capture_failure_message + end + + def description + (@expectation ||= expect).description_for("have received") + end + + CONSTRAINTS.each do |expectation| + define_method expectation do |*args| + @constraints << [expectation, *args] + self + end + end + + def setup_expectation(subject, &block) + notify_failure_message unless matches?(subject, &block) + end + + def setup_negative_expectation(subject, &block) + notify_failure_message unless does_not_match?(subject, &block) + end + + def setup_allowance(_subject, &_block) + disallow("allow", " as it would have no effect") + end + + def setup_any_instance_allowance(_subject, &_block) + disallow("allow_any_instance_of") + end + + def setup_any_instance_expectation(_subject, &_block) + disallow("expect_any_instance_of") + end + + def setup_any_instance_negative_expectation(_subject, &_block) + disallow("expect_any_instance_of") + end + + private + + def disallow(type, reason="") + RSpec::Mocks.error_generator.raise_have_received_disallowed(type, reason) + end + + def expect + expectation = mock_proxy.build_expectation(@method_name) + apply_constraints_to expectation + expectation + end + + def apply_constraints_to(expectation) + @constraints.each do |constraint| + expectation.send(*constraint) + end + end + + def ensure_count_unconstrained + return unless count_constraint + RSpec::Mocks.error_generator.raise_cant_constrain_count_for_negated_have_received_error(count_constraint) + end + + def count_constraint + @constraints.map(&:first).find do |constraint| + COUNT_CONSTRAINTS.include?(constraint) + end + end + + def capture_failure_message + RSpec::Support.with_failure_notifier(Proc.new { |err, _opt| return err.message }) do + notify_failure_message + end + end + + def notify_failure_message + mock_proxy.check_for_unexpected_arguments(@expectation) + @expectation.generate_error + end + + def expected_messages_received_in_order? + mock_proxy.replay_received_message_on @expectation, &@block + @expectation.expected_messages_received? && @expectation.ensure_expected_ordering_received! + end + + def mock_proxy + RSpec::Mocks.space.proxy_for(@subject) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/matchers/receive.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/matchers/receive.rb new file mode 100644 index 00000000..ee958308 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/matchers/receive.rb @@ -0,0 +1,134 @@ +RSpec::Support.require_rspec_mocks 'matchers/expectation_customization' + +module RSpec + module Mocks + module Matchers + # @private + class Receive + include Matcher + + def initialize(message, block) + @message = message + @block = block + @recorded_customizations = [] + end + + def matcher_name + "receive" + end + + def description + describable.description_for("receive") + end + + def setup_expectation(subject, &block) + warn_if_any_instance("expect", subject) + @describable = setup_mock_proxy_method_substitute(subject, :add_message_expectation, block) + end + alias matches? setup_expectation + + def setup_negative_expectation(subject, &block) + # ensure `never` goes first for cases like `never.and_return(5)`, + # where `and_return` is meant to raise an error + @recorded_customizations.unshift ExpectationCustomization.new(:never, [], nil) + + warn_if_any_instance("expect", subject) + + setup_expectation(subject, &block) + end + alias does_not_match? setup_negative_expectation + + def setup_allowance(subject, &block) + warn_if_any_instance("allow", subject) + setup_mock_proxy_method_substitute(subject, :add_stub, block) + end + + def setup_any_instance_expectation(subject, &block) + setup_any_instance_method_substitute(subject, :should_receive, block) + end + + def setup_any_instance_negative_expectation(subject, &block) + setup_any_instance_method_substitute(subject, :should_not_receive, block) + end + + def setup_any_instance_allowance(subject, &block) + setup_any_instance_method_substitute(subject, :stub, block) + end + + own_methods = (instance_methods - superclass.instance_methods) + MessageExpectation.public_instance_methods(false).each do |method| + next if own_methods.include?(method) + + define_method(method) do |*args, &block| + @recorded_customizations << ExpectationCustomization.new(method, args, block) + self + end + ruby2_keywords(method) if respond_to?(:ruby2_keywords, true) + end + + private + + def describable + @describable ||= DefaultDescribable.new(@message) + end + + def warn_if_any_instance(expression, subject) + return unless AnyInstance::Proxy === subject + + RSpec.warning( + "`#{expression}(#{subject.klass}.any_instance).to` " \ + "is probably not what you meant, it does not operate on " \ + "any instance of `#{subject.klass}`. " \ + "Use `#{expression}_any_instance_of(#{subject.klass}).to` instead." + ) + end + + def setup_mock_proxy_method_substitute(subject, method, block) + proxy = ::RSpec::Mocks.space.proxy_for(subject) + setup_method_substitute(proxy, method, block) + end + + def setup_any_instance_method_substitute(subject, method, block) + proxy = ::RSpec::Mocks.space.any_instance_proxy_for(subject) + setup_method_substitute(proxy, method, block) + end + + def setup_method_substitute(host, method, block, *args) + args << @message.to_sym + block = move_block_to_last_customization(block) + + expectation = host.__send__(method, *args, &(@block || block)) + + @recorded_customizations.each do |customization| + customization.playback_onto(expectation) + end + expectation + end + + def move_block_to_last_customization(block) + last = @recorded_customizations.last + return block unless last + + last.block ||= block + nil + end + + # MessageExpectation objects are able to describe themselves in detail. + # We use this as a fall back when a MessageExpectation is not available. + # @private + class DefaultDescribable + def initialize(message) + @message = message + end + + # This is much simpler for the `any_instance` case than what the + # user may want, but I'm not up for putting a bunch of effort + # into full descriptions for `any_instance` expectations at this point :(. + def description_for(verb) + "#{verb} #{@message}" + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/matchers/receive_message_chain.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/matchers/receive_message_chain.rb new file mode 100644 index 00000000..fdc89f9f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/matchers/receive_message_chain.rb @@ -0,0 +1,82 @@ +RSpec::Support.require_rspec_mocks 'matchers/expectation_customization' + +module RSpec + module Mocks + module Matchers + # @private + class ReceiveMessageChain + include Matcher + + def initialize(chain, &block) + @chain = chain + @block = block + @recorded_customizations = [] + end + + [:with, :and_return, :and_invoke, :and_throw, :and_raise, :and_yield, :and_call_original].each do |msg| + define_method(msg) do |*args, &block| + @recorded_customizations << ExpectationCustomization.new(msg, args, block) + self + end + end + + def matcher_name + "receive_message_chain" + end + + def description + "receive message chain #{formatted_chain}" + end + + def setup_allowance(subject, &block) + chain = StubChain.stub_chain_on(subject, *@chain, &(@block || block)) + replay_customizations(chain) + end + + def setup_any_instance_allowance(subject, &block) + proxy = ::RSpec::Mocks.space.any_instance_proxy_for(subject) + chain = proxy.stub_chain(*@chain, &(@block || block)) + replay_customizations(chain) + end + + def setup_any_instance_expectation(subject, &block) + proxy = ::RSpec::Mocks.space.any_instance_proxy_for(subject) + chain = proxy.expect_chain(*@chain, &(@block || block)) + replay_customizations(chain) + end + + def setup_expectation(subject, &block) + chain = ExpectChain.expect_chain_on(subject, *@chain, &(@block || block)) + replay_customizations(chain) + end + + def setup_negative_expectation(*_args) + raise NegationUnsupportedError, + "`expect(...).not_to receive_message_chain` is not supported " \ + "since it doesn't really make sense. What would it even mean?" + end + + alias matches? setup_expectation + alias does_not_match? setup_negative_expectation + + private + + def replay_customizations(chain) + @recorded_customizations.each do |customization| + customization.playback_onto(chain) + end + end + + def formatted_chain + @formatted_chain ||= @chain.map do |part| + if Hash === part + part.keys.first.to_s + else + part.to_s + end + end.join(".") + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/matchers/receive_messages.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/matchers/receive_messages.rb new file mode 100644 index 00000000..6bf90478 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/matchers/receive_messages.rb @@ -0,0 +1,77 @@ +module RSpec + module Mocks + module Matchers + # @private + class ReceiveMessages + include Matcher + + def initialize(message_return_value_hash) + @message_return_value_hash = message_return_value_hash + @backtrace_line = CallerFilter.first_non_rspec_line + end + + def matcher_name + "receive_messages" + end + + def description + "receive messages: #{@message_return_value_hash.inspect}" + end + + def setup_expectation(subject) + warn_about_block if block_given? + each_message_on(proxy_on(subject)) do |host, message, return_value| + host.add_simple_expectation(message, return_value, @backtrace_line) + end + end + alias matches? setup_expectation + + def setup_negative_expectation(_subject) + raise NegationUnsupportedError, + "`expect(...).to_not receive_messages` is not supported since it " \ + "doesn't really make sense. What would it even mean?" + end + alias does_not_match? setup_negative_expectation + + def setup_allowance(subject) + warn_about_block if block_given? + each_message_on(proxy_on(subject)) do |host, message, return_value| + host.add_simple_stub(message, return_value) + end + end + + def setup_any_instance_expectation(subject) + warn_about_block if block_given? + each_message_on(any_instance_of(subject)) do |host, message, return_value| + host.should_receive(message).and_return(return_value) + end + end + + def setup_any_instance_allowance(subject) + warn_about_block if block_given? + any_instance_of(subject).stub(@message_return_value_hash) + end + + def warn_about_block + raise "Implementation blocks aren't supported with `receive_messages`" + end + + private + + def proxy_on(subject) + ::RSpec::Mocks.space.proxy_for(subject) + end + + def any_instance_of(subject) + ::RSpec::Mocks.space.any_instance_proxy_for(subject) + end + + def each_message_on(host) + @message_return_value_hash.each do |message, value| + yield host, message, value + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/message_chain.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/message_chain.rb new file mode 100644 index 00000000..907d14b0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/message_chain.rb @@ -0,0 +1,87 @@ +module RSpec + module Mocks + # @private + class MessageChain + attr_reader :object, :chain, :block + + def initialize(object, *chain, &blk) + @object = object + @chain, @block = format_chain(*chain, &blk) + end + + # @api private + def setup_chain + if chain.length > 1 + if (matching_stub = find_matching_stub) + chain.shift + chain_on(matching_stub.invoke(nil), *chain, &@block) + elsif (matching_expectation = find_matching_expectation) + chain.shift + chain_on(matching_expectation.invoke_without_incrementing_received_count(nil), *chain, &@block) + else + next_in_chain = Double.new + expectation(object, chain.shift) { next_in_chain } + chain_on(next_in_chain, *chain, &@block) + end + else + expectation(object, chain.shift, &@block) + end + end + + private + + def chain_on(object, *chain, &block) + initialize(object, *chain, &block) + setup_chain + end + + def format_chain(*chain, &blk) + if Hash === chain.last + hash = chain.pop + hash.each do |k, v| + chain << k + blk = Proc.new { v } + end + end + return chain.join('.').split('.'), blk + end + + def find_matching_stub + ::RSpec::Mocks.space.proxy_for(object). + __send__(:find_matching_method_stub, chain.first.to_sym) + end + + def find_matching_expectation + ::RSpec::Mocks.space.proxy_for(object). + __send__(:find_matching_expectation, chain.first.to_sym) + end + end + + # @private + class ExpectChain < MessageChain + # @api private + def self.expect_chain_on(object, *chain, &blk) + new(object, *chain, &blk).setup_chain + end + + private + + def expectation(object, message, &return_block) + ::RSpec::Mocks.expect_message(object, message, {}, &return_block) + end + end + + # @private + class StubChain < MessageChain + def self.stub_chain_on(object, *chain, &blk) + new(object, *chain, &blk).setup_chain + end + + private + + def expectation(object, message, &return_block) + ::RSpec::Mocks.allow_message(object, message, {}, &return_block) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/message_expectation.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/message_expectation.rb new file mode 100644 index 00000000..a478db73 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/message_expectation.rb @@ -0,0 +1,856 @@ +RSpec::Support.require_rspec_support 'mutex' + +module RSpec + module Mocks + # A message expectation that only allows concrete return values to be set + # for a message. While this same effect can be achieved using a standard + # MessageExpectation, this version is much faster and so can be used as an + # optimization. + # + # @private + class SimpleMessageExpectation + def initialize(message, response, error_generator, backtrace_line=nil) + @message, @response, @error_generator, @backtrace_line = message.to_sym, response, error_generator, backtrace_line + @received = false + end + + def invoke(*_) + @received = true + @response + end + + def matches?(message, *_) + @message == message.to_sym + end + + def called_max_times? + false + end + + def verify_messages_received + return if @received + @error_generator.raise_expectation_error( + @message, 1, ArgumentListMatcher::MATCH_ALL, 0, nil, [], @backtrace_line + ) + end + + def unadvise(_) + end + end + + # Represents an individual method stub or message expectation. The methods + # defined here can be used to configure how it behaves. The methods return + # `self` so that they can be chained together to form a fluent interface. + class MessageExpectation + # @!group Configuring Responses + + # @overload and_return(value) + # @overload and_return(first_value, second_value) + # + # Tells the object to return a value when it receives the message. Given + # more than one value, the first value is returned the first time the + # message is received, the second value is returned the next time, etc, + # etc. + # + # If the message is received more times than there are values, the last + # value is returned for every subsequent call. + # + # @return [nil] No further chaining is supported after this. + # @example + # allow(counter).to receive(:count).and_return(1) + # counter.count # => 1 + # counter.count # => 1 + # + # allow(counter).to receive(:count).and_return(1,2,3) + # counter.count # => 1 + # counter.count # => 2 + # counter.count # => 3 + # counter.count # => 3 + # counter.count # => 3 + # # etc + def and_return(first_value, *values, &_block) + raise_already_invoked_error_if_necessary(__method__) + if negative? + raise "`and_return` is not supported with negative message expectations" + end + + if block_given? + raise ArgumentError, "Implementation blocks aren't supported with `and_return`" + end + + values.unshift(first_value) + @expected_received_count = [@expected_received_count, values.size].max unless ignoring_args? || (@expected_received_count == 0 && @at_least) + self.terminal_implementation_action = AndReturnImplementation.new(values) + + nil + end + + # Tells the object to invoke a Proc when it receives the message. Given + # more than one value, the result of the first Proc is returned the first + # time the message is received, the result of the second Proc is returned + # the next time, etc, etc. + # + # If the message is received more times than there are Procs, the result of + # the last Proc is returned for every subsequent call. + # + # @return [nil] No further chaining is supported after this. + # @example + # allow(api).to receive(:get_foo).and_invoke(-> { raise ApiTimeout }) + # api.get_foo # => raises ApiTimeout + # api.get_foo # => raises ApiTimeout + # + # allow(api).to receive(:get_foo).and_invoke(-> { raise ApiTimeout }, -> { raise ApiTimeout }, -> { :a_foo }) + # api.get_foo # => raises ApiTimeout + # api.get_foo # => raises ApiTimeout + # api.get_foo # => :a_foo + # api.get_foo # => :a_foo + # api.get_foo # => :a_foo + # # etc + def and_invoke(first_proc, *procs, &_block) + raise_already_invoked_error_if_necessary(__method__) + if negative? + raise "`and_invoke` is not supported with negative message expectations" + end + + if block_given? + raise ArgumentError, "Implementation blocks aren't supported with `and_invoke`" + end + + procs.unshift(first_proc) + if procs.any? { |p| !p.respond_to?(:call) } + raise ArgumentError, "Arguments to `and_invoke` must be callable." + end + + @expected_received_count = [@expected_received_count, procs.size].max unless ignoring_args? || (@expected_received_count == 0 && @at_least) + self.terminal_implementation_action = AndInvokeImplementation.new(procs) + + nil + end + + # Tells the object to delegate to the original unmodified method + # when it receives the message. + # + # @note This is only available on partial doubles. + # + # @return [nil] No further chaining is supported after this. + # @example + # expect(counter).to receive(:increment).and_call_original + # original_count = counter.count + # counter.increment + # expect(counter.count).to eq(original_count + 1) + def and_call_original + block = lambda do |original, *args, &b| + original.call(*args, &b) + end + block = block.ruby2_keywords if block.respond_to?(:ruby2_keywords) + + wrap_original(__method__, &block) + end + + # Decorates the stubbed method with the supplied block. The original + # unmodified method is passed to the block along with any method call + # arguments so you can delegate to it, whilst still being able to + # change what args are passed to it and/or change the return value. + # + # @note This is only available on partial doubles. + # + # @return [nil] No further chaining is supported after this. + # @example + # expect(api).to receive(:large_list).and_wrap_original do |original_method, *args, &block| + # original_method.call(*args, &block).first(10) + # end + def and_wrap_original(&block) + wrap_original(__method__, &block) + end + + # @overload and_raise + # @overload and_raise(ExceptionClass) + # @overload and_raise(ExceptionClass, message) + # @overload and_raise(exception_instance) + # + # Tells the object to raise an exception when the message is received. + # + # @return [nil] No further chaining is supported after this. + # @note + # When you pass an exception class, the MessageExpectation will raise + # an instance of it, creating it with `exception` and passing `message` + # if specified. If the exception class initializer requires more than + # one parameters, you must pass in an instance and not the class, + # otherwise this method will raise an ArgumentError exception. + # + # @example + # allow(car).to receive(:go).and_raise + # allow(car).to receive(:go).and_raise(OutOfGas) + # allow(car).to receive(:go).and_raise(OutOfGas, "At least 2 oz of gas needed to drive") + # allow(car).to receive(:go).and_raise(OutOfGas.new(2, :oz)) + def and_raise(*args) + raise_already_invoked_error_if_necessary(__method__) + self.terminal_implementation_action = Proc.new { raise(*args) } + nil + end + + # @overload and_throw(symbol) + # @overload and_throw(symbol, object) + # + # Tells the object to throw a symbol (with the object if that form is + # used) when the message is received. + # + # @return [nil] No further chaining is supported after this. + # @example + # allow(car).to receive(:go).and_throw(:out_of_gas) + # allow(car).to receive(:go).and_throw(:out_of_gas, :level => 0.1) + def and_throw(*args) + raise_already_invoked_error_if_necessary(__method__) + self.terminal_implementation_action = Proc.new { throw(*args) } + nil + end + + # Tells the object to yield one or more args to a block when the message + # is received. + # + # @return [MessageExpectation] self, to support further chaining. + # @example + # stream.stub(:open).and_yield(StringIO.new) + def and_yield(*args, &block) + raise_already_invoked_error_if_necessary(__method__) + yield @eval_context = Object.new if block + + # Initialize args to yield now that it's being used, see also: comment + # in constructor. + @args_to_yield ||= [] + + @args_to_yield << args + self.initial_implementation_action = AndYieldImplementation.new(@args_to_yield, @eval_context, @error_generator) + self + end + # @!endgroup + + # @!group Constraining Receive Counts + + # Constrain a message expectation to be received a specific number of + # times. + # + # @return [MessageExpectation] self, to support further chaining. + # @example + # expect(dealer).to receive(:deal_card).exactly(10).times + def exactly(n, &block) + raise_already_invoked_error_if_necessary(__method__) + self.inner_implementation_action = block + set_expected_received_count :exactly, n + self + end + + # Constrain a message expectation to be received at least a specific + # number of times. + # + # @return [MessageExpectation] self, to support further chaining. + # @example + # expect(dealer).to receive(:deal_card).at_least(9).times + def at_least(n, &block) + raise_already_invoked_error_if_necessary(__method__) + set_expected_received_count :at_least, n + + if n == 0 + raise "at_least(0) has been removed, use allow(...).to receive(:message) instead" + end + + self.inner_implementation_action = block + + self + end + + # Constrain a message expectation to be received at most a specific + # number of times. + # + # @return [MessageExpectation] self, to support further chaining. + # @example + # expect(dealer).to receive(:deal_card).at_most(10).times + def at_most(n, &block) + raise_already_invoked_error_if_necessary(__method__) + self.inner_implementation_action = block + set_expected_received_count :at_most, n + self + end + + # Syntactic sugar for `exactly`, `at_least` and `at_most` + # + # @return [MessageExpectation] self, to support further chaining. + # @example + # expect(dealer).to receive(:deal_card).exactly(10).times + # expect(dealer).to receive(:deal_card).at_least(10).times + # expect(dealer).to receive(:deal_card).at_most(10).times + def times(&block) + self.inner_implementation_action = block + self + end + alias time times + + # Expect a message not to be received at all. + # + # @return [MessageExpectation] self, to support further chaining. + # @example + # expect(car).to receive(:stop).never + def never + error_generator.raise_double_negation_error("expect(obj)") if negative? + @expected_received_count = 0 + self + end + + # Expect a message to be received exactly one time. + # + # @return [MessageExpectation] self, to support further chaining. + # @example + # expect(car).to receive(:go).once + def once(&block) + self.inner_implementation_action = block + set_expected_received_count :exactly, 1 + self + end + + # Expect a message to be received exactly two times. + # + # @return [MessageExpectation] self, to support further chaining. + # @example + # expect(car).to receive(:go).twice + def twice(&block) + self.inner_implementation_action = block + set_expected_received_count :exactly, 2 + self + end + + # Expect a message to be received exactly three times. + # + # @return [MessageExpectation] self, to support further chaining. + # @example + # expect(car).to receive(:go).thrice + def thrice(&block) + self.inner_implementation_action = block + set_expected_received_count :exactly, 3 + self + end + # @!endgroup + + # @!group Other Constraints + + # Constrains a stub or message expectation to invocations with specific + # arguments. + # + # With a stub, if the message might be received with other args as well, + # you should stub a default value first, and then stub or mock the same + # message using `with` to constrain to specific arguments. + # + # A message expectation will fail if the message is received with different + # arguments. + # + # @return [MessageExpectation] self, to support further chaining. + # @example + # allow(cart).to receive(:add) { :failure } + # allow(cart).to receive(:add).with(Book.new(:isbn => 1934356379)) { :success } + # cart.add(Book.new(:isbn => 1234567890)) + # # => :failure + # cart.add(Book.new(:isbn => 1934356379)) + # # => :success + # + # expect(cart).to receive(:add).with(Book.new(:isbn => 1934356379)) { :success } + # cart.add(Book.new(:isbn => 1234567890)) + # # => failed expectation + # cart.add(Book.new(:isbn => 1934356379)) + # # => passes + def with(*args, &block) + raise_already_invoked_error_if_necessary(__method__) + if args.empty? + raise ArgumentError, + "`with` must have at least one argument. Use `no_args` matcher to set the expectation of receiving no arguments." + end + + self.inner_implementation_action = block + @argument_list_matcher = ArgumentListMatcher.new(*args) + self + end + ruby2_keywords(:with) if respond_to?(:ruby2_keywords, true) + + # Expect messages to be received in a specific order. + # + # @return [MessageExpectation] self, to support further chaining. + # @example + # expect(api).to receive(:prepare).ordered + # expect(api).to receive(:run).ordered + # expect(api).to receive(:finish).ordered + def ordered(&block) + if type == :stub + RSpec.warning( + "`allow(...).to receive(..).ordered` is not supported and will " \ + "have no effect, use `and_return(*ordered_values)` instead." + ) + end + + self.inner_implementation_action = block + additional_expected_calls.times do + @order_group.register(self) + end + @ordered = true + self + end + + # @return [String] a nice representation of the message expectation + def to_s + args_description = error_generator.method_call_args_description(@argument_list_matcher.expected_args, "", "") { true } + args_description = "(#{args_description})" unless args_description.start_with?("(") + "#<#{self.class} #{error_generator.intro}.#{message}#{args_description}>" + end + alias inspect to_s + + # Implementation details is a long module + # rubocop:disable Metrics/ModuleLength + + # @private + # Contains the parts of `MessageExpectation` that aren't part of + # rspec-mocks' public API. The class is very big and could really use + # some collaborators it delegates to for this stuff but for now this was + # the simplest way to split the public from private stuff to make it + # easier to publish the docs for the APIs we want published. + module ImplementationDetails + attr_accessor :error_generator, :implementation + attr_reader :message + attr_reader :orig_object + attr_writer :expected_received_count, :expected_from, :argument_list_matcher + protected :expected_received_count=, :expected_from=, :error_generator=, :implementation= + + # @private + attr_reader :type + + # rubocop:disable Metrics/ParameterLists + def initialize(error_generator, expectation_ordering, expected_from, method_double, + type=:expectation, opts={}, &implementation_block) + @type = type + @error_generator = error_generator + @error_generator.opts = error_generator.opts.merge(opts) + @expected_from = expected_from + @method_double = method_double + @orig_object = @method_double.object + @message = @method_double.method_name + @actual_received_count = 0 + @actual_received_count_write_mutex = Support::Mutex.new + @expected_received_count = type == :expectation ? 1 : :any + @argument_list_matcher = ArgumentListMatcher::MATCH_ALL + @order_group = expectation_ordering + @order_group.register(self) unless type == :stub + @expectation_type = type + @ordered = false + @at_least = @at_most = @exactly = nil + + self.invoking_internals = false + + # Initialized to nil so that we don't allocate an array for every + # mock or stub. See also comment in `and_yield`. + @args_to_yield = nil + @eval_context = nil + @yield_receiver_to_implementation_block = false + + @implementation = Implementation.new + self.inner_implementation_action = implementation_block + end + # rubocop:enable Metrics/ParameterLists + + def expected_args + @argument_list_matcher.expected_args + end + + def and_yield_receiver_to_implementation + @yield_receiver_to_implementation_block = true + self + end + + def yield_receiver_to_implementation_block? + @yield_receiver_to_implementation_block + end + + def matches?(message, *args) + @message == message && @argument_list_matcher.args_match?(*args) + end + ruby2_keywords :matches? if respond_to?(:ruby2_keywords, true) + + def safe_invoke(parent_stub, *args, &block) + invoke_incrementing_actual_calls_by(1, false, parent_stub, *args, &block) + end + ruby2_keywords :safe_invoke if respond_to?(:ruby2_keywords, true) + + def invoke(parent_stub, *args, &block) + if invoking_internals + safe_invoke_without_incrementing_received_count(parent_stub, *args, &block) + else + invoke_incrementing_actual_calls_by(1, true, parent_stub, *args, &block) + end + end + ruby2_keywords :invoke if respond_to?(:ruby2_keywords, true) + + def safe_invoke_without_incrementing_received_count(parent_stub, *args, &block) + invoke_incrementing_actual_calls_by(0, false, parent_stub, *args, &block) + end + ruby2_keywords :safe_invoke_without_incrementing_received_count if respond_to?(:ruby2_keywords, true) + + def invoke_without_incrementing_received_count(parent_stub, *args, &block) + invoke_incrementing_actual_calls_by(0, true, parent_stub, *args, &block) + end + ruby2_keywords :invoke_without_incrementing_received_count if respond_to?(:ruby2_keywords, true) + + def negative? + @expected_received_count == 0 && !@at_least + end + + def called_max_times? + @expected_received_count != :any && + !@at_least && + @expected_received_count > 0 && + @actual_received_count >= @expected_received_count + end + + def matches_name_but_not_args(message, *args) + @message == message && !@argument_list_matcher.args_match?(*args) + end + + def verify_messages_received + return if expected_messages_received? + generate_error + end + + def expected_messages_received? + ignoring_args? || matches_exact_count? || matches_at_least_count? || matches_at_most_count? + end + + def ensure_expected_ordering_received! + @order_group.verify_invocation_order(self) if @ordered + true + end + + def ignoring_args? + @expected_received_count == :any + end + + def matches_at_least_count? + @at_least && @actual_received_count >= @expected_received_count + end + + def matches_at_most_count? + @at_most && @actual_received_count <= @expected_received_count + end + + def matches_exact_count? + @expected_received_count == @actual_received_count + end + + def similar_messages + @similar_messages ||= [] + end + + def advise(*args) + similar_messages << args + end + + def unadvise(args) + similar_messages.delete_if { |message| args.include?(message) } + end + + def generate_error + if similar_messages.empty? + @error_generator.raise_expectation_error( + @message, @expected_received_count, @argument_list_matcher, + @actual_received_count, expectation_count_type, expected_args, + @expected_from, exception_source_id + ) + else + @error_generator.raise_similar_message_args_error( + self, @similar_messages, @expected_from + ) + end + end + + def raise_unexpected_message_args_error(args_for_multiple_calls) + @error_generator.raise_unexpected_message_args_error(self, args_for_multiple_calls, exception_source_id) + end + + def expectation_count_type + return :at_least if @at_least + return :at_most if @at_most + nil + end + + def description_for(verb) + @error_generator.describe_expectation( + verb, @message, @expected_received_count, + @actual_received_count, expected_args + ) + end + + def raise_out_of_order_error + @error_generator.raise_out_of_order_error @message + end + + def additional_expected_calls + return 0 if @expectation_type == :stub || !@exactly + @expected_received_count - 1 + end + + def ordered? + @ordered + end + + def negative_expectation_for?(message) + @message == message && negative? + end + + def actual_received_count_matters? + @at_least || @at_most || @exactly + end + + def increase_actual_received_count! + @actual_received_count_write_mutex.synchronize do + @actual_received_count += 1 + end + end + + private + + def exception_source_id + @exception_source_id ||= "#{self.class.name} #{__id__}" + end + + def invoking_internals + RSpec::Support.thread_local_data[:"__rspec_#{object_id}_invoking_internals"] + end + + def invoking_internals=(value) + # We clear the key for this rather than setting to false because otherwise the amount of + # thread local data will keep growing over the lifetime of the thread (which is a long + # time on a single threaded spec run e.g standard MRI) + if value + RSpec::Support.thread_local_data[:"__rspec_#{object_id}_invoking_internals"] = true + else + RSpec::Support.thread_local_data.delete(:"__rspec_#{object_id}_invoking_internals") + end + end + + def invoke_incrementing_actual_calls_by(increment, allowed_to_fail, parent_stub, *args, &block) + self.invoking_internals = true + + args.unshift(orig_object) if yield_receiver_to_implementation_block? + + if negative? || (allowed_to_fail && (@exactly || @at_most) && (@actual_received_count == @expected_received_count)) + # args are the args we actually received, @argument_list_matcher is the + # list of args we were expecting + @error_generator.raise_expectation_error( + @message, @expected_received_count, + @argument_list_matcher, + @actual_received_count + increment, + expectation_count_type, args, nil, exception_source_id + ) + end + + @order_group.handle_order_constraint self + + self.invoking_internals = false + + if implementation.present? + implementation.call(*args, &block) + elsif parent_stub + parent_stub.invoke(nil, *args, &block) + end + ensure + self.invoking_internals = false + @actual_received_count_write_mutex.synchronize do + @actual_received_count += increment + end + end + ruby2_keywords :invoke_incrementing_actual_calls_by if respond_to?(:ruby2_keywords, true) + + def has_been_invoked? + @actual_received_count > 0 + end + + def raise_already_invoked_error_if_necessary(calling_customization) + return unless has_been_invoked? + + error_generator.raise_already_invoked_error(message, calling_customization) + end + + def set_expected_received_count(relativity, n) + raise "`count` is not supported with negative message expectations" if negative? + @at_least = (relativity == :at_least) + @at_most = (relativity == :at_most) + @exactly = (relativity == :exactly) + @expected_received_count = case n + when Numeric then n + when :once then 1 + when :twice then 2 + when :thrice then 3 + end + end + + def initial_implementation_action=(action) + implementation.initial_action = action + end + + def inner_implementation_action=(action) + return unless action + warn_about_stub_override if implementation.inner_action + implementation.inner_action = action + end + + def terminal_implementation_action=(action) + implementation.terminal_action = action + end + + def warn_about_stub_override + RSpec.warning( + "You're overriding a previous stub implementation of `#{@message}`. " \ + "Called from #{CallerFilter.first_non_rspec_line}." + ) + end + + def wrap_original(method_name, &block) + if RSpec::Mocks::TestDouble === @method_double.object + @error_generator.raise_only_valid_on_a_partial_double(method_name) + else + warn_about_stub_override if implementation.inner_action + @implementation = AndWrapOriginalImplementation.new(@method_double.original_implementation_callable, block) + @yield_receiver_to_implementation_block = false + end + + nil + end + end + + include ImplementationDetails + end + # rubocop:enable Metrics/ModuleLength + + # Handles the implementation of an `and_yield` declaration. + # @private + class AndYieldImplementation + def initialize(args_to_yield, eval_context, error_generator) + @args_to_yield = args_to_yield + @eval_context = eval_context + @error_generator = error_generator + end + + def call(*_args_to_ignore, &block) + return if @args_to_yield.empty? && @eval_context.nil? + + @error_generator.raise_missing_block_error @args_to_yield unless block + value = nil + block_signature = Support::BlockSignature.new(block) + + @args_to_yield.each do |args| + unless Support::StrictSignatureVerifier.new(block_signature, args).valid? + @error_generator.raise_wrong_arity_error(args, block_signature) + end + + value = @eval_context ? @eval_context.instance_exec(*args, &block) : yield(*args) + end + value + end + end + + # Handles the implementation of an `and_return` implementation. + # @private + class AndReturnImplementation + def initialize(values_to_return) + @values_to_return = values_to_return + end + + def call(*_args_to_ignore, &_block) + if @values_to_return.size > 1 + @values_to_return.shift + else + @values_to_return.first + end + end + end + + # Handles the implementation of an `and_invoke` implementation. + # @private + class AndInvokeImplementation + def initialize(procs_to_invoke) + @procs_to_invoke = procs_to_invoke + end + + def call(*args, &block) + proc = if @procs_to_invoke.size > 1 + @procs_to_invoke.shift + else + @procs_to_invoke.first + end + + proc.call(*args, &block) + end + ruby2_keywords(:call) if respond_to?(:ruby2_keywords, true) + end + + # Represents a configured implementation. Takes into account + # any number of sub-implementations. + # @private + class Implementation + attr_accessor :initial_action, :inner_action, :terminal_action + + def call(*args, &block) + actions.map do |action| + action.call(*args, &block) + end.last + end + ruby2_keywords :call if respond_to?(:ruby2_keywords, true) + + def present? + actions.any? + end + + private + + def actions + [initial_action, inner_action, terminal_action].compact + end + end + + # Represents an `and_call_original` implementation. + # @private + class AndWrapOriginalImplementation + def initialize(method, block) + @method = method + @block = block + end + + CannotModifyFurtherError = Class.new(StandardError) + + def initial_action=(_value) + raise cannot_modify_further_error + end + + def inner_action=(_value) + raise cannot_modify_further_error + end + + def terminal_action=(_value) + raise cannot_modify_further_error + end + + def present? + true + end + + def inner_action + true + end + + def call(*args, &block) + @block.call(@method, *args, &block) + end + ruby2_keywords :call if respond_to?(:ruby2_keywords, true) + + private + + def cannot_modify_further_error + CannotModifyFurtherError.new "This method has already been configured " \ + "to call the original implementation, and cannot be modified further." + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/method_double.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/method_double.rb new file mode 100644 index 00000000..7417f65a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/method_double.rb @@ -0,0 +1,316 @@ +module RSpec + module Mocks + # @private + class MethodDouble + # @private TODO: drop in favor of FrozenError in ruby 2.5+ + FROZEN_ERROR_MSG = /can't modify frozen/ + + # @private + attr_reader :method_name, :object, :expectations, :stubs, :method_stasher + + # @private + def initialize(object, method_name, proxy) + @method_name = method_name + @object = object + @proxy = proxy + + @original_visibility = nil + @method_stasher = InstanceMethodStasher.new(object, method_name) + @method_is_proxied = false + @expectations = [] + @stubs = [] + end + + def original_implementation_callable + # If original method is not present, uses the `method_missing` + # handler of the object. This accounts for cases where the user has not + # correctly defined `respond_to?`, and also 1.8 which does not provide + # method handles for missing methods even if `respond_to?` is correct. + @original_implementation_callable ||= original_method || method_missing_block + end + + alias_method :save_original_implementation_callable!, :original_implementation_callable + + def original_method + @original_method ||= + @method_stasher.original_method || + @proxy.original_method_handle_for(method_name) + end + + # @private + def method_missing_block + block = Proc.new do |*args, &b| + @object.__send__(:method_missing, @method_name, *args, &b) + end + block.ruby2_keywords if block.respond_to?(:ruby2_keywords) + + block + end + + # @private + def visibility + @proxy.visibility_for(@method_name) + end + + # @private + def object_singleton_class + class << @object; self; end + end + + # @private + def configure_method + @original_visibility = visibility + @method_stasher.stash unless @method_is_proxied + define_proxy_method + end + + # @private + def define_proxy_method + return if @method_is_proxied + + save_original_implementation_callable! + definition_target.class_exec(self, method_name, @original_visibility || visibility) do |method_double, method_name, visibility| + define_method(method_name) do |*args, &block| + method_double.proxy_method_invoked(self, *args, &block) + end + # This can't be `if respond_to?(:ruby2_keywords, true)`, + # see https://github.com/rspec/rspec-mocks/pull/1385#issuecomment-755340298 + ruby2_keywords(method_name) if Module.private_method_defined?(:ruby2_keywords) + __send__(visibility, method_name) + end + + @method_is_proxied = true + rescue RuntimeError, TypeError => e + # TODO: drop in favor of FrozenError in ruby 2.5+ + # RuntimeError (and FrozenError) for ruby 2.x + # TypeError for ruby 1.x + if (defined?(FrozenError) && e.is_a?(FrozenError)) || FROZEN_ERROR_MSG === e.message + raise ArgumentError, "Cannot proxy frozen objects, rspec-mocks relies on proxies for method stubbing and expectations." + end + raise + end + + # The implementation of the proxied method. Subclasses may override this + # method to perform additional operations. + # + # @private + def proxy_method_invoked(_obj, *args, &block) + @proxy.message_received method_name, *args, &block + end + ruby2_keywords :proxy_method_invoked if respond_to?(:ruby2_keywords, true) + + # @private + def restore_original_method + return unless @method_is_proxied + + remove_method_from_definition_target + @method_stasher.restore if @method_stasher.method_is_stashed? + restore_original_visibility + + @method_is_proxied = false + rescue RuntimeError, TypeError => e + # TODO: drop in favor of FrozenError in ruby 2.5+ + # RuntimeError (and FrozenError) for ruby 2.x + # TypeError for ruby 1.x + if (defined?(FrozenError) && e.is_a?(FrozenError)) || FROZEN_ERROR_MSG === e.message + return show_frozen_warning + end + raise + end + + # @private + def show_frozen_warning + RSpec.warn_with( + "WARNING: rspec-mocks was unable to restore the original `#{@method_name}` " \ + "method on #{@object.inspect} because it has been frozen. If you reuse this " \ + "object, `#{@method_name}` will continue to respond with its stub implementation.", + :call_site => nil, + :use_spec_location_as_call_site => true + ) + end + + # @private + def restore_original_visibility + return unless @original_visibility && + MethodReference.method_defined_at_any_visibility?(object_singleton_class, @method_name) + + object_singleton_class.__send__(@original_visibility, method_name) + end + + # @private + def verify + expectations.each { |e| e.verify_messages_received } + end + + # @private + def reset + restore_original_method + clear + end + + # @private + def clear + expectations.clear + stubs.clear + end + + # The type of message expectation to create has been extracted to its own + # method so that subclasses can override it. + # + # @private + def message_expectation_class + MessageExpectation + end + + # @private + def add_expectation(error_generator, expectation_ordering, expected_from, opts, &implementation) + configure_method + expectation = message_expectation_class.new(error_generator, expectation_ordering, + expected_from, self, :expectation, opts, &implementation) + expectations << expectation + expectation + end + + # @private + def build_expectation(error_generator, expectation_ordering) + expected_from = IGNORED_BACKTRACE_LINE + message_expectation_class.new(error_generator, expectation_ordering, expected_from, self) + end + + # @private + def add_stub(error_generator, expectation_ordering, expected_from, opts={}, &implementation) + configure_method + stub = message_expectation_class.new(error_generator, expectation_ordering, expected_from, + self, :stub, opts, &implementation) + stubs.unshift stub + stub + end + + # A simple stub can only return a concrete value for a message, and + # cannot match on arguments. It is used as an optimization over + # `add_stub` / `add_expectation` where it is known in advance that this + # is all that will be required of a stub, such as when passing attributes + # to the `double` example method. They do not stash or restore existing method + # definitions. + # + # @private + def add_simple_stub(method_name, response) + setup_simple_method_double method_name, response, stubs + end + + # @private + def add_simple_expectation(method_name, response, error_generator, backtrace_line) + setup_simple_method_double method_name, response, expectations, error_generator, backtrace_line + end + + # @private + def setup_simple_method_double(method_name, response, collection, error_generator=nil, backtrace_line=nil) + define_proxy_method + + me = SimpleMessageExpectation.new(method_name, response, error_generator, backtrace_line) + collection.unshift me + me + end + + # @private + def add_default_stub(*args, &implementation) + return if stubs.any? + add_stub(*args, &implementation) + end + + # @private + def remove_stub + raise_method_not_stubbed_error if stubs.empty? + remove_stub_if_present + end + + # @private + def remove_stub_if_present + expectations.empty? ? reset : stubs.clear + end + + # @private + def raise_method_not_stubbed_error + RSpec::Mocks.error_generator.raise_method_not_stubbed_error(method_name) + end + + # In Ruby 2.0.0 and above prepend will alter the method lookup chain. + # We use an object's singleton class to define method doubles upon, + # however if the object has had its singleton class (as opposed to + # its actual class) prepended too then the the method lookup chain + # will look in the prepended module first, **before** the singleton + # class. + # + # This code works around that by providing a mock definition target + # that is either the singleton class, or if necessary, a prepended module + # of our own. + # + if Support::RubyFeatures.module_prepends_supported? + + private + + # We subclass `Module` in order to be able to easily detect our prepended module. + RSpecPrependedModule = Class.new(Module) + + def definition_target + @definition_target ||= usable_rspec_prepended_module || object_singleton_class + end + + def usable_rspec_prepended_module + @proxy.prepended_modules_of_singleton_class.each do |mod| + # If we have one of our modules prepended before one of the user's + # modules that defines the method, use that, since our module's + # definition will take precedence. + return mod if RSpecPrependedModule === mod + + # If we hit a user module with the method defined first, + # we must create a new prepend module, even if one exists later, + # because ours will only take precedence if it comes first. + return new_rspec_prepended_module if mod.method_defined?(method_name) + end + + nil + end + + def new_rspec_prepended_module + RSpecPrependedModule.new.tap do |mod| + object_singleton_class.__send__ :prepend, mod + end + end + + else + + private + + def definition_target + object_singleton_class + end + + end + + private + + def remove_method_from_definition_target + definition_target.__send__(:remove_method, @method_name) + rescue NameError + # This can happen when the method has been monkeyed with by + # something outside RSpec. This happens, for example, when + # `file.write` has been stubbed, and then `file.reopen(other_io)` + # is later called, as `File#reopen` appears to redefine `write`. + # + # Note: we could avoid rescuing this by checking + # `definition_target.instance_method(@method_name).owner == definition_target`, + # saving us from the cost of the expensive exception, but this error is + # extremely rare (it was discovered on 2014-12-30, only happens on + # RUBY_VERSION < 2.0 and our spec suite only hits this condition once), + # so we'd rather avoid the cost of that check for every method double, + # and risk the rare situation where this exception will get raised. + RSpec.warn_with( + "WARNING: RSpec could not fully restore #{@object.inspect}." \ + "#{@method_name}, possibly because the method has been redefined " \ + "by something outside of RSpec." + ) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/method_reference.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/method_reference.rb new file mode 100644 index 00000000..50608b01 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/method_reference.rb @@ -0,0 +1,214 @@ +RSpec::Support.require_rspec_support 'comparable_version' + +module RSpec + module Mocks + # Represents a method on an object that may or may not be defined. + # The method may be an instance method on a module or a method on + # any object. + # + # @private + class MethodReference + def self.for(object_reference, method_name) + new(object_reference, method_name) + end + + def initialize(object_reference, method_name) + @object_reference = object_reference + @method_name = method_name + end + + # A method is implemented if sending the message does not result in + # a `NoMethodError`. It might be dynamically implemented by + # `method_missing`. + def implemented? + @object_reference.when_loaded do |m| + method_implemented?(m) + end + end + + # Returns true if we definitively know that sending the method + # will result in a `NoMethodError`. + # + # This is not simply the inverse of `implemented?`: there are + # cases when we don't know if a method is implemented and + # both `implemented?` and `unimplemented?` will return false. + def unimplemented? + @object_reference.when_loaded do |_m| + return !implemented? + end + + # If it's not loaded, then it may be implemented but we can't check. + false + end + + # A method is defined if we are able to get a `Method` object for it. + # In that case, we can assert against metadata like the arity. + def defined? + @object_reference.when_loaded do |m| + method_defined?(m) + end + end + + def with_signature + return unless (original = original_method) + yield Support::MethodSignature.new(original) + end + + def visibility + @object_reference.when_loaded do |m| + return visibility_from(m) + end + + # When it's not loaded, assume it's public. We don't want to + # wrongly treat the method as private. + :public + end + + def self.instance_method_visibility_for(klass, method_name) + if klass.public_method_defined?(method_name) + :public + elsif klass.private_method_defined?(method_name) + :private + elsif klass.protected_method_defined?(method_name) + :protected + end + end + + class << self + alias method_defined_at_any_visibility? instance_method_visibility_for + end + + def self.method_visibility_for(object, method_name) + vis = instance_method_visibility_for(class << object; self; end, method_name) + + # If the method is not defined on the class, `instance_method_visibility_for` + # returns `nil`. However, it may be handled dynamically by `method_missing`, + # so here we check `respond_to` (passing false to not check private methods). + # + # This only considers the public case, but I don't think it's possible to + # write `method_missing` in such a way that it handles a dynamic message + # with private or protected visibility. Ruby doesn't provide you with + # the caller info. + return vis unless vis.nil? + + proxy = RSpec::Mocks.space.proxy_for(object) + respond_to = proxy.method_double_if_exists_for_message(:respond_to?) + + visible = respond_to && respond_to.original_method.call(method_name) || + object.respond_to?(method_name) + + return :public if visible + end + + private + + def original_method + @object_reference.when_loaded do |m| + self.defined? && find_method(m) + end + end + end + + # @private + class InstanceMethodReference < MethodReference + private + + def method_implemented?(mod) + MethodReference.method_defined_at_any_visibility?(mod, @method_name) + end + + # Ideally, we'd use `respond_to?` for `method_implemented?` but we need a + # reference to an instance to do that and we don't have one. Note that + # we may get false negatives: if the method is implemented via + # `method_missing`, we'll return `false` even though it meets our + # definition of "implemented". However, it's the best we can do. + alias method_defined? method_implemented? + + # works around the fact that repeated calls for method parameters will + # falsely return empty arrays on JRuby in certain circumstances, this + # is necessary here because we can't dup/clone UnboundMethods. + # + # This is necessary due to a bug in JRuby prior to 1.7.5 fixed in: + # https://github.com/jruby/jruby/commit/99a0613fe29935150d76a9a1ee4cf2b4f63f4a27 + if RUBY_PLATFORM == 'java' && RSpec::Support::ComparableVersion.new(JRUBY_VERSION) < '1.7.5' + def find_method(mod) + mod.dup.instance_method(@method_name) + end + else + def find_method(mod) + mod.instance_method(@method_name) + end + end + + def visibility_from(mod) + MethodReference.instance_method_visibility_for(mod, @method_name) + end + end + + # @private + class ObjectMethodReference < MethodReference + def self.for(object_reference, method_name) + if ClassNewMethodReference.applies_to?(method_name) { object_reference.when_loaded { |o| o } } + ClassNewMethodReference.new(object_reference, method_name) + else + super + end + end + + private + + def method_implemented?(object) + object.respond_to?(@method_name, true) + end + + def method_defined?(object) + (class << object; self; end).method_defined?(@method_name) + end + + def find_method(object) + object.method(@method_name) + end + + def visibility_from(object) + MethodReference.method_visibility_for(object, @method_name) + end + end + + # When a class's `.new` method is stubbed, we want to use the method + # signature from `#initialize` because `.new`'s signature is a generic + # `def new(*args)` and it simply delegates to `#initialize` and forwards + # all args...so the method with the actually used signature is `#initialize`. + # + # This method reference implementation handles that specific case. + # @private + class ClassNewMethodReference < ObjectMethodReference + def self.applies_to?(method_name) + return false unless method_name == :new + klass = yield + return false unless ::Class === klass && klass.respond_to?(:new, true) + + # We only want to apply our special logic to normal `new` methods. + # Methods that the user has monkeyed with should be left as-is. + uses_class_new?(klass) + end + + if RUBY_VERSION.to_i >= 3 + CLASS_NEW = ::Class.instance_method(:new) + + def self.uses_class_new?(klass) + ::RSpec::Support.method_handle_for(klass, :new) == CLASS_NEW.bind(klass) + end + else # Ruby 2's Method#== is too strict + def self.uses_class_new?(klass) + ::RSpec::Support.method_handle_for(klass, :new).owner == ::Class + end + end + + def with_signature + @object_reference.when_loaded do |klass| + yield Support::MethodSignature.new(klass.instance_method(:initialize)) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/minitest_integration.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/minitest_integration.rb new file mode 100644 index 00000000..a1298904 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/minitest_integration.rb @@ -0,0 +1,68 @@ +require 'rspec/mocks' + +module RSpec + module Mocks + # @private + module MinitestIntegration + include ::RSpec::Mocks::ExampleMethods + + def before_setup + ::RSpec::Mocks.setup + super + end + + def after_teardown + super + + # Only verify if there's not already an error. Otherwise + # we risk getting the same failure twice, since negative + # expectation violations raise both when the message is + # unexpectedly received, and also during `verify` (in case + # the first failure was caught by user code via a + # `rescue Exception`). + ::RSpec::Mocks.verify unless failures.any? + ensure + ::RSpec::Mocks.teardown + end + end + end +end + +Minitest::Test.send(:include, RSpec::Mocks::MinitestIntegration) + +if defined?(::Minitest::Expectation) + if defined?(::RSpec::Expectations) && ::Minitest::Expectation.method_defined?(:to) + # rspec/expectations/minitest_integration has already been loaded and + # has defined `to`/`not_to`/`to_not` on `Minitest::Expectation` so we do + # not want to here (or else we would interfere with rspec-expectations' definition). + else + # ...otherwise, define those methods now. If `rspec/expectations/minitest_integration` + # is loaded after this file, it'll override the definition here. + Minitest::Expectation.class_eval do + include RSpec::Mocks::ExpectationTargetMethods + + def to(*args) + ctx.assertions += 1 + super + end + + def not_to(*args) + ctx.assertions += 1 + super + end + + def to_not(*args) + ctx.assertions += 1 + super + end + end + end +end + +module RSpec + module Mocks + remove_const :MockExpectationError + # Raised when a message expectation is not satisfied. + MockExpectationError = ::Minitest::Assertion + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/mutate_const.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/mutate_const.rb new file mode 100644 index 00000000..071d7a21 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/mutate_const.rb @@ -0,0 +1,339 @@ +RSpec::Support.require_rspec_support 'recursive_const_methods' + +module RSpec + module Mocks + # Provides information about constants that may (or may not) + # have been mutated by rspec-mocks. + class Constant + extend Support::RecursiveConstMethods + + # @api private + def initialize(name) + @name = name + @previously_defined = false + @stubbed = false + @hidden = false + @valid_name = true + yield self if block_given? + end + + # @return [String] The fully qualified name of the constant. + attr_reader :name + + # @return [Object, nil] The original value (e.g. before it + # was mutated by rspec-mocks) of the constant, or + # nil if the constant was not previously defined. + attr_accessor :original_value + + # @private + attr_writer :previously_defined, :stubbed, :hidden, :valid_name + + # @return [Boolean] Whether or not the constant was defined + # before the current example. + def previously_defined? + @previously_defined + end + + # @return [Boolean] Whether or not rspec-mocks has mutated + # (stubbed or hidden) this constant. + def mutated? + @stubbed || @hidden + end + + # @return [Boolean] Whether or not rspec-mocks has stubbed + # this constant. + def stubbed? + @stubbed + end + + # @return [Boolean] Whether or not rspec-mocks has hidden + # this constant. + def hidden? + @hidden + end + + # @return [Boolean] Whether or not the provided constant name + # is a valid Ruby constant name. + def valid_name? + @valid_name + end + + # The default `to_s` isn't very useful, so a custom version is provided. + def to_s + "#<#{self.class.name} #{name}>" + end + alias inspect to_s + + # @private + def self.unmutated(name) + previously_defined = !!recursive_const_defined?(name) + rescue NameError + new(name) do |c| + c.valid_name = false + end + else + new(name) do |const| + const.previously_defined = previously_defined + const.original_value = recursive_const_get(name) if previously_defined + end + end + + # Queries rspec-mocks to find out information about the named constant. + # + # @param [String] name the name of the constant + # @return [Constant] an object containing information about the named + # constant. + def self.original(name) + mutator = ::RSpec::Mocks.space.constant_mutator_for(name) + mutator ? mutator.to_constant : unmutated(name) + end + end + + # Provides a means to stub constants. + class ConstantMutator + extend Support::RecursiveConstMethods + + # Stubs a constant. + # + # @param (see ExampleMethods#stub_const) + # @option (see ExampleMethods#stub_const) + # @return (see ExampleMethods#stub_const) + # + # @see ExampleMethods#stub_const + # @note It's recommended that you use `stub_const` in your + # examples. This is an alternate public API that is provided + # so you can stub constants in other contexts (e.g. helper + # classes). + def self.stub(constant_name, value, options={}) + unless String === constant_name + raise ArgumentError, "`stub_const` requires a String, but you provided a #{constant_name.class.name}" + end + + mutator = if recursive_const_defined?(constant_name, &raise_on_invalid_const) + DefinedConstantReplacer + else + UndefinedConstantSetter + end + + mutate(mutator.new(constant_name, value, options[:transfer_nested_constants])) + value + end + + # Hides a constant. + # + # @param (see ExampleMethods#hide_const) + # + # @see ExampleMethods#hide_const + # @note It's recommended that you use `hide_const` in your + # examples. This is an alternate public API that is provided + # so you can hide constants in other contexts (e.g. helper + # classes). + def self.hide(constant_name) + mutate(ConstantHider.new(constant_name, nil, {})) + nil + end + + # Contains common functionality used by all of the constant mutators. + # + # @private + class BaseMutator + include Support::RecursiveConstMethods + + attr_reader :original_value, :full_constant_name + + def initialize(full_constant_name, mutated_value, transfer_nested_constants) + @full_constant_name = normalize_const_name(full_constant_name) + @mutated_value = mutated_value + @transfer_nested_constants = transfer_nested_constants + @context_parts = @full_constant_name.split('::') + @const_name = @context_parts.pop + @reset_performed = false + end + + def to_constant + const = Constant.new(full_constant_name) + const.original_value = original_value + + const + end + + def idempotently_reset + reset unless @reset_performed + @reset_performed = true + end + end + + # Hides a defined constant for the duration of an example. + # + # @private + class ConstantHider < BaseMutator + def mutate + return unless (@defined = recursive_const_defined?(full_constant_name)) + @context = recursive_const_get(@context_parts.join('::')) + @original_value = get_const_defined_on(@context, @const_name) + + @context.__send__(:remove_const, @const_name) + end + + def to_constant + return Constant.unmutated(full_constant_name) unless @defined + + const = super + const.hidden = true + const.previously_defined = true + + const + end + + def reset + return unless @defined + @context.const_set(@const_name, @original_value) + end + end + + # Replaces a defined constant for the duration of an example. + # + # @private + class DefinedConstantReplacer < BaseMutator + def initialize(*args) + super + @constants_to_transfer = [] + end + + def mutate + @context = recursive_const_get(@context_parts.join('::')) + @original_value = get_const_defined_on(@context, @const_name) + + @constants_to_transfer = verify_constants_to_transfer! + + @context.__send__(:remove_const, @const_name) + @context.const_set(@const_name, @mutated_value) + + transfer_nested_constants + end + + def to_constant + const = super + const.stubbed = true + const.previously_defined = true + + const + end + + def reset + @constants_to_transfer.each do |const| + @mutated_value.__send__(:remove_const, const) + end + + @context.__send__(:remove_const, @const_name) + @context.const_set(@const_name, @original_value) + end + + def transfer_nested_constants + @constants_to_transfer.each do |const| + @mutated_value.const_set(const, get_const_defined_on(original_value, const)) + end + end + + def verify_constants_to_transfer! + return [] unless should_transfer_nested_constants? + + { @original_value => "the original value", @mutated_value => "the stubbed value" }.each do |value, description| + next if value.respond_to?(:constants) + + raise ArgumentError, + "Cannot transfer nested constants for #{@full_constant_name} " \ + "since #{description} is not a class or module and only classes " \ + "and modules support nested constants." + end + + if Array === @transfer_nested_constants + @transfer_nested_constants = @transfer_nested_constants.map(&:to_s) if RUBY_VERSION == '1.8.7' + undefined_constants = @transfer_nested_constants - constants_defined_on(@original_value) + + if undefined_constants.any? + available_constants = constants_defined_on(@original_value) - @transfer_nested_constants + raise ArgumentError, + "Cannot transfer nested constant(s) #{undefined_constants.join(' and ')} " \ + "for #{@full_constant_name} since they are not defined. Did you mean " \ + "#{available_constants.join(' or ')}?" + end + + @transfer_nested_constants + else + constants_defined_on(@original_value) + end + end + + def should_transfer_nested_constants? + return true if @transfer_nested_constants + return false unless RSpec::Mocks.configuration.transfer_nested_constants? + @original_value.respond_to?(:constants) && @mutated_value.respond_to?(:constants) + end + end + + # Sets an undefined constant for the duration of an example. + # + # @private + class UndefinedConstantSetter < BaseMutator + def mutate + @parent = @context_parts.inject(Object) do |klass, name| + if const_defined_on?(klass, name) + get_const_defined_on(klass, name) + else + ConstantMutator.stub(name_for(klass, name), Module.new) + end + end + + @parent.const_set(@const_name, @mutated_value) + end + + def to_constant + const = super + const.stubbed = true + const.previously_defined = false + + const + end + + def reset + @parent.__send__(:remove_const, @const_name) + end + + private + + def name_for(parent, name) + root = if parent == Object + '' + else + parent.name + end + root + '::' + name + end + end + + # Uses the mutator to mutate (stub or hide) a constant. Ensures that + # the mutator is correctly registered so it can be backed out at the end + # of the test. + # + # @private + def self.mutate(mutator) + ::RSpec::Mocks.space.register_constant_mutator(mutator) + mutator.mutate + end + + # Used internally by the constant stubbing to raise a helpful + # error when a constant like "A::B::C" is stubbed and A::B is + # not a module (and thus, it's impossible to define "A::B::C" + # since only modules can have nested constants). + # + # @api private + def self.raise_on_invalid_const + lambda do |const_name, failed_name| + raise "Cannot stub constant #{failed_name} on #{const_name} " \ + "since #{const_name} is not a module." + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/object_reference.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/object_reference.rb new file mode 100644 index 00000000..cce2c331 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/object_reference.rb @@ -0,0 +1,149 @@ +module RSpec + module Mocks + # @private + class ObjectReference + # Returns an appropriate Object or Module reference based + # on the given argument. + def self.for(object_module_or_name, allow_direct_object_refs=false) + case object_module_or_name + when Module + if anonymous_module?(object_module_or_name) + DirectObjectReference.new(object_module_or_name) + else + # Use a `NamedObjectReference` if it has a name because this + # will use the original value of the constant in case it has + # been stubbed. + NamedObjectReference.new(name_of(object_module_or_name)) + end + when String + NamedObjectReference.new(object_module_or_name) + else + if allow_direct_object_refs + DirectObjectReference.new(object_module_or_name) + else + raise ArgumentError, + "Module or String expected, got #{object_module_or_name.inspect}" + end + end + end + + if Module.new.name.nil? + def self.anonymous_module?(mod) + !name_of(mod) + end + else # 1.8.7 + def self.anonymous_module?(mod) + name_of(mod) == "" + end + end + private_class_method :anonymous_module? + + def self.name_of(mod) + MODULE_NAME_METHOD.bind(mod).call + end + private_class_method :name_of + + # @private + MODULE_NAME_METHOD = Module.instance_method(:name) + end + + # An implementation of rspec-mocks' reference interface. + # Used when an object is passed to {ExampleMethods#object_double}, or + # an anonymous class or module is passed to {ExampleMethods#instance_double} + # or {ExampleMethods#class_double}. + # Represents a reference to that object. + # @see NamedObjectReference + class DirectObjectReference + # @param object [Object] the object to which this refers + def initialize(object) + @object = object + end + + # @return [String] the object's description (via `#inspect`). + def description + @object.inspect + end + + # Defined for interface parity with the other object reference + # implementations. Raises an `ArgumentError` to indicate that `as_stubbed_const` + # is invalid when passing an object argument to `object_double`. + def const_to_replace + raise ArgumentError, + "Can not perform constant replacement with an anonymous object." + end + + # The target of the verifying double (the object itself). + # + # @return [Object] + def target + @object + end + + # Always returns true for an object as the class is defined. + # + # @return [true] + def defined? + true + end + + # Yields if the reference target is loaded, providing a generic mechanism + # to optionally run a bit of code only when a reference's target is + # loaded. + # + # This specific implementation always yields because direct references + # are always loaded. + # + # @yield [Object] the target of this reference. + def when_loaded + yield @object + end + end + + # An implementation of rspec-mocks' reference interface. + # Used when a string is passed to {ExampleMethods#object_double}, + # and when a string, named class or named module is passed to + # {ExampleMethods#instance_double}, or {ExampleMethods#class_double}. + # Represents a reference to the object named (via a constant lookup) + # by the string. + # @see DirectObjectReference + class NamedObjectReference + # @param const_name [String] constant name + def initialize(const_name) + @const_name = const_name + end + + # @return [Boolean] true if the named constant is defined, false otherwise. + def defined? + !!object + end + + # @return [String] the constant name to replace with a double. + def const_to_replace + @const_name + end + alias description const_to_replace + + # @return [Object, nil] the target of the verifying double (the named object), or + # nil if it is not defined. + def target + object + end + + # Yields if the reference target is loaded, providing a generic mechanism + # to optionally run a bit of code only when a reference's target is + # loaded. + # + # @yield [Object] the target object + def when_loaded + yield object if object + end + + private + + def object + return @object if defined?(@object) + @object = Constant.original(@const_name).original_value + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/order_group.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/order_group.rb new file mode 100644 index 00000000..a9947995 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/order_group.rb @@ -0,0 +1,81 @@ +module RSpec + module Mocks + # @private + class OrderGroup + def initialize + @expectations = [] + @invocation_order = [] + @index = 0 + end + + # @private + def register(expectation) + @expectations << expectation + end + + def invoked(message) + @invocation_order << message + end + + # @private + def ready_for?(expectation) + remaining_expectations.find(&:ordered?) == expectation + end + + # @private + def consume + remaining_expectations.each_with_index do |expectation, index| + next unless expectation.ordered? + + @index += index + 1 + return expectation + end + nil + end + + # @private + def handle_order_constraint(expectation) + return unless expectation.ordered? && remaining_expectations.include?(expectation) + return consume if ready_for?(expectation) + expectation.raise_out_of_order_error + end + + def verify_invocation_order(expectation) + expectation.raise_out_of_order_error unless expectations_invoked_in_order? + true + end + + def clear + @index = 0 + @invocation_order.clear + @expectations.clear + end + + def empty? + @expectations.empty? + end + + private + + def remaining_expectations + @expectations[@index..-1] || [] + end + + def expectations_invoked_in_order? + invoked_expectations == expected_invocations + end + + def invoked_expectations + @expectations.select { |e| e.ordered? && @invocation_order.include?(e) } + end + + def expected_invocations + @invocation_order.map { |invocation| expectation_for(invocation) }.compact + end + + def expectation_for(message) + @expectations.find { |e| message == e } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/proxy.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/proxy.rb new file mode 100644 index 00000000..45beb551 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/proxy.rb @@ -0,0 +1,517 @@ +RSpec::Support.require_rspec_support 'mutex' + +module RSpec + module Mocks + # @private + class Proxy + # @private + SpecificMessage = Struct.new(:object, :message, :args) do + def ==(expectation) + expectation.orig_object == object && expectation.matches?(message, *args) + end + end + + # @private + def ensure_implemented(*_args) + # noop for basic proxies, see VerifyingProxy for behaviour. + end + + # @private + def initialize(object, order_group, options={}) + ensure_can_be_proxied!(object) + + @object = object + @order_group = order_group + @error_generator = ErrorGenerator.new(object) + @messages_received = [] + @messages_received_mutex = Support::Mutex.new + @options = options + @null_object = false + @method_doubles = Hash.new { |h, k| h[k] = MethodDouble.new(@object, k, self) } + end + + # @private + def ensure_can_be_proxied!(object) + return unless object.is_a?(Symbol) + + msg = "Cannot proxy frozen objects. Symbols such as #{object} cannot be mocked or stubbed." + raise ArgumentError, msg + end + + # @private + attr_reader :object + + # @private + def null_object? + @null_object + end + + # @private + # Tells the object to ignore any messages that aren't explicitly set as + # stubs or message expectations. + def as_null_object + @null_object = true + @object + end + + # @private + def original_method_handle_for(_message) + nil + end + + DEFAULT_MESSAGE_EXPECTATION_OPTS = {}.freeze + + # @private + def add_message_expectation(method_name, opts=DEFAULT_MESSAGE_EXPECTATION_OPTS, &block) + location = opts.fetch(:expected_from) { CallerFilter.first_non_rspec_line } + meth_double = method_double_for(method_name) + + if null_object? && !block + meth_double.add_default_stub(@error_generator, @order_group, location, opts) do + @object + end + end + + meth_double.add_expectation @error_generator, @order_group, location, opts, &block + end + + # @private + def add_simple_expectation(method_name, response, location) + method_double_for(method_name).add_simple_expectation method_name, response, @error_generator, location + end + + # @private + def build_expectation(method_name) + meth_double = method_double_for(method_name) + + meth_double.build_expectation( + @error_generator, + @order_group + ) + end + + # @private + def replay_received_message_on(expectation, &block) + expected_method_name = expectation.message + meth_double = method_double_for(expected_method_name) + + if meth_double.expectations.any? + @error_generator.raise_expectation_on_mocked_method(expected_method_name) + end + + unless null_object? || meth_double.stubs.any? + @error_generator.raise_expectation_on_unstubbed_method(expected_method_name) + end + + @messages_received_mutex.synchronize do + @messages_received.each do |(actual_method_name, args, received_block)| + next unless expectation.matches?(actual_method_name, *args) + + expectation.safe_invoke(nil) + block.call(*args, &received_block) if block + end + end + end + + # @private + def check_for_unexpected_arguments(expectation) + @messages_received_mutex.synchronize do + return if @messages_received.empty? + + return if @messages_received.any? { |method_name, args, _| expectation.matches?(method_name, *args) } + + name_but_not_args, others = @messages_received.partition do |(method_name, args, _)| + expectation.matches_name_but_not_args(method_name, *args) + end + + return if name_but_not_args.empty? && !others.empty? + + expectation.raise_unexpected_message_args_error(name_but_not_args.map { |args| args[1] }) + end + end + + # @private + def add_stub(method_name, opts={}, &implementation) + location = opts.fetch(:expected_from) { CallerFilter.first_non_rspec_line } + method_double_for(method_name).add_stub @error_generator, @order_group, location, opts, &implementation + end + + # @private + def add_simple_stub(method_name, response) + method_double_for(method_name).add_simple_stub method_name, response + end + + # @private + def remove_stub(method_name) + method_double_for(method_name).remove_stub + end + + # @private + def remove_stub_if_present(method_name) + method_double_for(method_name).remove_stub_if_present + end + + # @private + def verify + @method_doubles.each_value { |d| d.verify } + end + + # @private + def reset + @messages_received_mutex.synchronize do + @messages_received.clear + end + end + + # @private + def received_message?(method_name, *args, &block) + @messages_received_mutex.synchronize do + @messages_received.any? { |array| array == [method_name, args, block] } + end + end + + # @private + def messages_arg_list + @messages_received_mutex.synchronize do + @messages_received.map { |_, args, _| args } + end + end + + # @private + def has_negative_expectation?(message) + method_double_for(message).expectations.find { |expectation| expectation.negative_expectation_for?(message) } + end + + # @private + def record_message_received(message, *args, &block) + @order_group.invoked SpecificMessage.new(object, message, args) + @messages_received_mutex.synchronize do + @messages_received << [message, args, block] + end + end + ruby2_keywords :record_message_received if respond_to?(:ruby2_keywords, true) + + # @private + def message_received(message, *args, &block) + record_message_received message, *args, &block + + expectation = find_matching_expectation(message, *args) + stub = find_matching_method_stub(message, *args) + + if (stub && expectation && expectation.called_max_times?) || (stub && !expectation) + expectation.increase_actual_received_count! if expectation && expectation.actual_received_count_matters? + if (expectation = find_almost_matching_expectation(message, *args)) + expectation.advise(*args) unless expectation.expected_messages_received? + end + stub.invoke(nil, *args, &block) + elsif expectation + expectation.unadvise(messages_arg_list) + expectation.invoke(stub, *args, &block) + elsif (expectation = find_almost_matching_expectation(message, *args)) + expectation.advise(*args) if null_object? unless expectation.expected_messages_received? + + if null_object? || !has_negative_expectation?(message) + expectation.raise_unexpected_message_args_error([args]) + end + elsif (stub = find_almost_matching_stub(message, *args)) + stub.advise(*args) + raise_missing_default_stub_error(stub, [args]) + elsif Class === @object + @object.superclass.__send__(message, *args, &block) + else + @object.__send__(:method_missing, message, *args, &block) + end + end + ruby2_keywords :message_received if respond_to?(:ruby2_keywords, true) + + # @private + def raise_unexpected_message_error(method_name, args) + @error_generator.raise_unexpected_message_error method_name, args + end + + # @private + def raise_missing_default_stub_error(expectation, args_for_multiple_calls) + @error_generator.raise_missing_default_stub_error(expectation, args_for_multiple_calls) + end + + # @private + def visibility_for(_method_name) + # This is the default (for test doubles). Subclasses override this. + :public + end + + if Support::RubyFeatures.module_prepends_supported? + def self.prepended_modules_of(klass) + ancestors = klass.ancestors + + # `|| 0` is necessary for Ruby 2.0, where the singleton class + # is only in the ancestor list when there are prepended modules. + singleton_index = ancestors.index(klass) || 0 + + ancestors[0, singleton_index] + end + + def prepended_modules_of_singleton_class + @prepended_modules_of_singleton_class ||= RSpec::Mocks::Proxy.prepended_modules_of(@object.singleton_class) + end + end + + # @private + def method_double_if_exists_for_message(message) + method_double_for(message) if @method_doubles.key?(message.to_sym) + end + + private + + def method_double_for(message) + @method_doubles[message.to_sym] + end + + def find_matching_expectation(method_name, *args) + find_best_matching_expectation_for(method_name) do |expectation| + expectation.matches?(method_name, *args) + end + end + ruby2_keywords :find_matching_expectation if respond_to?(:ruby2_keywords, true) + + def find_almost_matching_expectation(method_name, *args) + find_best_matching_expectation_for(method_name) do |expectation| + expectation.matches_name_but_not_args(method_name, *args) + end + end + ruby2_keywords :find_almost_matching_expectation if respond_to?(:ruby2_keywords, true) + + def find_best_matching_expectation_for(method_name) + first_match = nil + + method_double_for(method_name).expectations.each do |expectation| + next unless yield expectation + return expectation unless expectation.called_max_times? + first_match ||= expectation + end + + first_match + end + + def find_matching_method_stub(method_name, *args) + method_double_for(method_name).stubs.find { |stub| stub.matches?(method_name, *args) } + end + ruby2_keywords :find_matching_method_stub if respond_to?(:ruby2_keywords, true) + + def find_almost_matching_stub(method_name, *args) + method_double_for(method_name).stubs.find { |stub| stub.matches_name_but_not_args(method_name, *args) } + end + ruby2_keywords :find_almost_matching_stub if respond_to?(:ruby2_keywords, true) + end + + # @private + class TestDoubleProxy < Proxy + def reset + @method_doubles.clear + object.__disallow_further_usage! + super + end + end + + # @private + class PartialDoubleProxy < Proxy + def original_method_handle_for(message) + if any_instance_class_recorder_observing_method?(@object.class, message) + message = ::RSpec::Mocks.space. + any_instance_recorder_for(@object.class). + build_alias_method_name(message) + end + + ::RSpec::Support.method_handle_for(@object, message) + rescue NameError + nil + end + + # @private + def add_simple_expectation(method_name, response, location) + method_double_for(method_name).configure_method + super + end + + # @private + def add_simple_stub(method_name, response) + method_double_for(method_name).configure_method + super + end + + # @private + def visibility_for(method_name) + # We fall back to :public because by default we allow undefined methods + # to be stubbed, and when we do so, we make them public. + MethodReference.method_visibility_for(@object, method_name) || :public + end + + def reset + @method_doubles.each_value { |d| d.reset } + super + end + + def message_received(message, *args, &block) + RSpec::Mocks.space.any_instance_recorders_from_ancestry_of(object).each do |subscriber| + subscriber.notify_received_message(object, message, args, block) + end + super + end + ruby2_keywords :message_received if respond_to?(:ruby2_keywords, true) + + private + + def any_instance_class_recorder_observing_method?(klass, method_name) + only_return_existing = true + recorder = ::RSpec::Mocks.space.any_instance_recorder_for(klass, only_return_existing) + return true if recorder && recorder.already_observing?(method_name) + + superklass = klass.superclass + return false if superklass.nil? + any_instance_class_recorder_observing_method?(superklass, method_name) + end + end + + # @private + # When we mock or stub a method on a class, we have to treat it a bit different, + # because normally singleton method definitions only affect the object on which + # they are defined, but on classes they affect subclasses, too. As a result, + # we need some special handling to get the original method. + module PartialClassDoubleProxyMethods + def initialize(source_space, *args) + @source_space = source_space + super(*args) + end + + # Consider this situation: + # + # class A; end + # class B < A; end + # + # allow(A).to receive(:new) + # expect(B).to receive(:new).and_call_original + # + # When getting the original definition for `B.new`, we cannot rely purely on + # using `B.method(:new)` before our redefinition is defined on `B`, because + # `B.method(:new)` will return a method that will execute the stubbed version + # of the method on `A` since singleton methods on classes are in the lookup + # hierarchy. + # + # To do it properly, we need to find the original definition of `new` from `A` + # from _before_ `A` was stubbed, and we need to rebind it to `B` so that it will + # run with the proper `self`. + # + # That's what this method (together with `original_unbound_method_handle_from_ancestor_for`) + # does. + def original_method_handle_for(message) + unbound_method = superclass_proxy && + superclass_proxy.original_unbound_method_handle_from_ancestor_for(message.to_sym) + + return super unless unbound_method + unbound_method.bind(object) + # :nocov: + rescue TypeError + if RUBY_VERSION == '1.8.7' + # In MRI 1.8.7, a singleton method on a class cannot be rebound to its subclass + if unbound_method && unbound_method.owner.ancestors.first != unbound_method.owner + # This is a singleton method; we can't do anything with it + # But we can work around this using a different implementation + double = method_double_from_ancestor_for(message) + return object.method(double.method_stasher.stashed_method_name) + end + end + raise + # :nocov: + end + + protected + + def original_unbound_method_handle_from_ancestor_for(message) + double = method_double_from_ancestor_for(message) + double && double.original_method.unbind + end + + def method_double_from_ancestor_for(message) + @method_doubles.fetch(message) do + # The fact that there is no method double for this message indicates + # that it has not been redefined by rspec-mocks. We need to continue + # looking up the ancestor chain. + return superclass_proxy && + superclass_proxy.method_double_from_ancestor_for(message) + end + end + + def superclass_proxy + return @superclass_proxy if defined?(@superclass_proxy) + + if (superclass = object.superclass) + @superclass_proxy = @source_space.superclass_proxy_for(superclass) + else + @superclass_proxy = nil + end + end + end + + # @private + class PartialClassDoubleProxy < PartialDoubleProxy + include PartialClassDoubleProxyMethods + end + + # @private + class ProxyForNil < PartialDoubleProxy + def initialize(order_group) + set_expectation_behavior + super(nil, order_group) + end + + attr_accessor :disallow_expectations + attr_accessor :warn_about_expectations + + def add_message_expectation(method_name, opts={}, &block) + warn_or_raise!(method_name) + super + end + + def add_stub(method_name, opts={}, &implementation) + warn_or_raise!(method_name) + super + end + + private + + def set_expectation_behavior + case RSpec::Mocks.configuration.allow_message_expectations_on_nil + when false + @warn_about_expectations = false + @disallow_expectations = true + when true + @warn_about_expectations = false + @disallow_expectations = false + else + @warn_about_expectations = true + @disallow_expectations = false + end + end + + def warn_or_raise!(method_name) + # This method intentionally swallows the message when + # neither disallow_expectations nor warn_about_expectations + # are set to true. + if disallow_expectations + raise_error(method_name) + elsif warn_about_expectations + warn(method_name) + end + end + + def warn(method_name) + warning_msg = @error_generator.expectation_on_nil_message(method_name) + RSpec.warning(warning_msg) + end + + def raise_error(method_name) + @error_generator.raise_expectation_on_nil_error(method_name) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/space.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/space.rb new file mode 100644 index 00000000..f933caa9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/space.rb @@ -0,0 +1,238 @@ +RSpec::Support.require_rspec_support 'reentrant_mutex' + +module RSpec + module Mocks + # @private + # Provides a default space implementation for outside + # the scope of an example. Called "root" because it serves + # as the root of the space stack. + class RootSpace + def proxy_for(*_args) + raise_lifecycle_message + end + + def any_instance_recorder_for(*_args) + raise_lifecycle_message + end + + def any_instance_proxy_for(*_args) + raise_lifecycle_message + end + + def register_constant_mutator(_mutator) + raise_lifecycle_message + end + + def any_instance_recorders_from_ancestry_of(_object) + raise_lifecycle_message + end + + def reset_all + end + + def verify_all + end + + def registered?(_object) + false + end + + def superclass_proxy_for(*_args) + raise_lifecycle_message + end + + def new_scope + Space.new + end + + private + + def raise_lifecycle_message + raise OutsideOfExampleError, + "The use of doubles or partial doubles from rspec-mocks outside of the per-test lifecycle is not supported." + end + end + + # @private + class Space + attr_reader :proxies, :any_instance_recorders, :proxy_mutex, :any_instance_mutex + + def initialize + @proxies = {} + @any_instance_recorders = {} + @constant_mutators = [] + @expectation_ordering = OrderGroup.new + @proxy_mutex = new_mutex + @any_instance_mutex = new_mutex + end + + def new_scope + NestedSpace.new(self) + end + + def verify_all + proxies.values.each { |proxy| proxy.verify } + any_instance_recorders.each_value { |recorder| recorder.verify } + end + + def reset_all + proxies.each_value { |proxy| proxy.reset } + any_instance_recorders.each_value { |recorder| recorder.stop_all_observation! } + any_instance_recorders.clear + @constant_mutators.reverse.each { |mut| mut.idempotently_reset } + end + + def register_constant_mutator(mutator) + @constant_mutators << mutator + end + + def constant_mutator_for(name) + @constant_mutators.find { |m| m.full_constant_name == name } + end + + def any_instance_recorder_for(klass, only_return_existing=false) + any_instance_mutex.synchronize do + id = klass.__id__ + any_instance_recorders.fetch(id) do + return nil if only_return_existing + any_instance_recorder_not_found_for(id, klass) + end + end + end + + def any_instance_proxy_for(klass) + AnyInstance::Proxy.new(any_instance_recorder_for(klass), proxies_of(klass)) + end + + def proxies_of(klass) + proxies.values.select { |proxy| klass === proxy.object } + end + + def proxy_for(object) + proxy_mutex.synchronize do + id = id_for(object) + proxies.fetch(id) { proxy_not_found_for(id, object) } + end + end + + def superclass_proxy_for(klass) + proxy_mutex.synchronize do + id = id_for(klass) + proxies.fetch(id) { superclass_proxy_not_found_for(id, klass) } + end + end + + alias ensure_registered proxy_for + + def registered?(object) + proxies.key?(id_for object) + end + + def any_instance_recorders_from_ancestry_of(object) + # Optimization: `any_instance` is a feature we generally + # recommend not using, so we can often early exit here + # without doing an O(N) linear search over the number of + # ancestors in the object's class hierarchy. + return [] if any_instance_recorders.empty? + + # We access the ancestors through the singleton class, to avoid calling + # `class` in case `class` has been stubbed. + (class << object; ancestors; end).map do |klass| + any_instance_recorders[klass.__id__] + end.compact + end + + private + + def new_mutex + Support::ReentrantMutex.new + end + + def proxy_not_found_for(id, object) + proxies[id] = case object + when NilClass then ProxyForNil.new(@expectation_ordering) + when TestDouble then object.__build_mock_proxy_unless_expired(@expectation_ordering) + when Class + class_proxy_with_callback_verification_strategy(object, CallbackInvocationStrategy.new) + else + if RSpec::Mocks.configuration.verify_partial_doubles? + VerifyingPartialDoubleProxy.new(object, @expectation_ordering) + else + PartialDoubleProxy.new(object, @expectation_ordering) + end + end + end + + def superclass_proxy_not_found_for(id, object) + raise "superclass_proxy_not_found_for called with something that is not a class" unless Class === object + proxies[id] = class_proxy_with_callback_verification_strategy(object, NoCallbackInvocationStrategy.new) + end + + def class_proxy_with_callback_verification_strategy(object, strategy) + if RSpec::Mocks.configuration.verify_partial_doubles? + VerifyingPartialClassDoubleProxy.new( + self, + object, + @expectation_ordering, + strategy + ) + else + PartialClassDoubleProxy.new(self, object, @expectation_ordering) + end + end + + def any_instance_recorder_not_found_for(id, klass) + any_instance_recorders[id] = AnyInstance::Recorder.new(klass) + end + + if defined?(::BasicObject) && !::BasicObject.method_defined?(:__id__) # for 1.9.2 + require 'securerandom' + + def id_for(object) + id = object.__id__ + + return id if object.equal?(::ObjectSpace._id2ref(id)) + # this suggests that object.__id__ is proxying through to some wrapped object + + object.instance_exec do + @__id_for_rspec_mocks_space ||= ::SecureRandom.uuid + end + end + else + def id_for(object) + object.__id__ + end + end + end + + # @private + class NestedSpace < Space + def initialize(parent) + @parent = parent + super() + end + + def proxies_of(klass) + super + @parent.proxies_of(klass) + end + + def constant_mutator_for(name) + super || @parent.constant_mutator_for(name) + end + + def registered?(object) + super || @parent.registered?(object) + end + + private + + def proxy_not_found_for(id, object) + @parent.proxies[id] || super + end + + def any_instance_recorder_not_found_for(id, klass) + @parent.any_instance_recorders[id] || super + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/standalone.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/standalone.rb new file mode 100644 index 00000000..74317b01 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/standalone.rb @@ -0,0 +1,3 @@ +require 'rspec/mocks' +extend RSpec::Mocks::ExampleMethods +RSpec::Mocks.setup diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/syntax.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/syntax.rb new file mode 100644 index 00000000..2caabd1a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/syntax.rb @@ -0,0 +1,325 @@ +module RSpec + module Mocks + # @api private + # Provides methods for enabling and disabling the available syntaxes + # provided by rspec-mocks. + module Syntax + # @private + def self.warn_about_should! + @warn_about_should = true + end + + # @private + def self.warn_unless_should_configured(method_name , replacement="the new `:expect` syntax or explicitly enable `:should`") + if @warn_about_should + RSpec.deprecate( + "Using `#{method_name}` from rspec-mocks' old `:should` syntax without explicitly enabling the syntax", + :replacement => replacement + ) + + @warn_about_should = false + end + end + + # @api private + # Enables the should syntax (`dbl.stub`, `dbl.should_receive`, etc). + def self.enable_should(syntax_host=default_should_syntax_host) + @warn_about_should = false if syntax_host == default_should_syntax_host + return if should_enabled?(syntax_host) + + syntax_host.class_exec do + def should_receive(message, opts={}, &block) + ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) + ::RSpec::Mocks.expect_message(self, message, opts, &block) + end + + def should_not_receive(message, &block) + ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) + ::RSpec::Mocks.expect_message(self, message, {}, &block).never + end + + def stub(message_or_hash, opts={}, &block) + ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) + if ::Hash === message_or_hash + message_or_hash.each { |message, value| stub(message).and_return value } + else + ::RSpec::Mocks.allow_message(self, message_or_hash, opts, &block) + end + end + + def unstub(message) + ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__, "`allow(...).to receive(...).and_call_original` or explicitly enable `:should`") + ::RSpec::Mocks.space.proxy_for(self).remove_stub(message) + end + + def stub_chain(*chain, &blk) + ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) + ::RSpec::Mocks::StubChain.stub_chain_on(self, *chain, &blk) + end + + def as_null_object + ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) + @_null_object = true + ::RSpec::Mocks.space.proxy_for(self).as_null_object + end + + def null_object? + ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) + defined?(@_null_object) + end + + def received_message?(message, *args, &block) + ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) + ::RSpec::Mocks.space.proxy_for(self).received_message?(message, *args, &block) + end + + unless Class.respond_to? :any_instance + Class.class_exec do + def any_instance + ::RSpec::Mocks::Syntax.warn_unless_should_configured(__method__) + ::RSpec::Mocks.space.any_instance_proxy_for(self) + end + end + end + end + end + + # @api private + # Disables the should syntax (`dbl.stub`, `dbl.should_receive`, etc). + def self.disable_should(syntax_host=default_should_syntax_host) + return unless should_enabled?(syntax_host) + + syntax_host.class_exec do + undef should_receive + undef should_not_receive + undef stub + undef unstub + undef stub_chain + undef as_null_object + undef null_object? + undef received_message? + end + + Class.class_exec do + undef any_instance + end + end + + # @api private + # Enables the expect syntax (`expect(dbl).to receive`, `allow(dbl).to receive`, etc). + def self.enable_expect(syntax_host=::RSpec::Mocks::ExampleMethods) + return if expect_enabled?(syntax_host) + + syntax_host.class_exec do + def receive(method_name, &block) + Matchers::Receive.new(method_name, block) + end + + def receive_messages(message_return_value_hash, &_block) + matcher = Matchers::ReceiveMessages.new(message_return_value_hash) + matcher.warn_about_block if block_given? + matcher + end + + def receive_message_chain(*messages, &block) + Matchers::ReceiveMessageChain.new(messages, &block) + end + + def allow(target) + AllowanceTarget.new(target) + end + + def expect_any_instance_of(klass) + AnyInstanceExpectationTarget.new(klass) + end + + def allow_any_instance_of(klass) + AnyInstanceAllowanceTarget.new(klass) + end + end + + RSpec::Mocks::ExampleMethods::ExpectHost.class_exec do + def expect(target) + ExpectationTarget.new(target) + end + end + end + + # @api private + # Disables the expect syntax (`expect(dbl).to receive`, `allow(dbl).to receive`, etc). + def self.disable_expect(syntax_host=::RSpec::Mocks::ExampleMethods) + return unless expect_enabled?(syntax_host) + + syntax_host.class_exec do + undef receive + undef receive_messages + undef receive_message_chain + undef allow + undef expect_any_instance_of + undef allow_any_instance_of + end + + RSpec::Mocks::ExampleMethods::ExpectHost.class_exec do + undef expect + end + end + + # @api private + # Indicates whether or not the should syntax is enabled. + def self.should_enabled?(syntax_host=default_should_syntax_host) + syntax_host.method_defined?(:should_receive) + end + + # @api private + # Indicates whether or not the expect syntax is enabled. + def self.expect_enabled?(syntax_host=::RSpec::Mocks::ExampleMethods) + syntax_host.method_defined?(:allow) + end + + # @api private + # Determines where the methods like `should_receive`, and `stub` are added. + def self.default_should_syntax_host + # JRuby 1.7.4 introduces a regression whereby `defined?(::BasicObject) => nil` + # yet `BasicObject` still exists and patching onto ::Object breaks things + # e.g. SimpleDelegator expectations won't work + # + # See: https://github.com/jruby/jruby/issues/814 + if defined?(JRUBY_VERSION) && JRUBY_VERSION == '1.7.4' && RUBY_VERSION.to_f > 1.8 + return ::BasicObject + end + + # On 1.8.7, Object.ancestors.last == Kernel but + # things blow up if we include `RSpec::Mocks::Methods` + # into Kernel...not sure why. + return Object unless defined?(::BasicObject) + + # MacRuby has BasicObject but it's not the root class. + return Object unless Object.ancestors.last == ::BasicObject + + ::BasicObject + end + end + end +end + +if defined?(BasicObject) + # The legacy `:should` syntax adds the following methods directly to + # `BasicObject` so that they are available off of any object. Note, however, + # that this syntax does not always play nice with delegate/proxy objects. + # We recommend you use the non-monkeypatching `:expect` syntax instead. + # @see Class + class BasicObject + # @method should_receive + # Sets an expectation that this object should receive a message before + # the end of the example. + # + # @example + # logger = double('logger') + # thing_that_logs = ThingThatLogs.new(logger) + # logger.should_receive(:log) + # thing_that_logs.do_something_that_logs_a_message + # + # @note This is only available when you have enabled the `should` syntax. + # @see RSpec::Mocks::ExampleMethods#expect + + # @method should_not_receive + # Sets and expectation that this object should _not_ receive a message + # during this example. + # @see RSpec::Mocks::ExampleMethods#expect + + # @method stub + # Tells the object to respond to the message with the specified value. + # + # @example + # counter.stub(:count).and_return(37) + # counter.stub(:count => 37) + # counter.stub(:count) { 37 } + # + # @note This is only available when you have enabled the `should` syntax. + # @see RSpec::Mocks::ExampleMethods#allow + + # @method unstub + # Removes a stub. On a double, the object will no longer respond to + # `message`. On a real object, the original method (if it exists) is + # restored. + # + # This is rarely used, but can be useful when a stub is set up during a + # shared `before` hook for the common case, but you want to replace it + # for a special case. + # + # @note This is only available when you have enabled the `should` syntax. + + # @method stub_chain + # @overload stub_chain(method1, method2) + # @overload stub_chain("method1.method2") + # @overload stub_chain(method1, method_to_value_hash) + # + # Stubs a chain of methods. + # + # ## Warning: + # + # Chains can be arbitrarily long, which makes it quite painless to + # violate the Law of Demeter in violent ways, so you should consider any + # use of `stub_chain` a code smell. Even though not all code smells + # indicate real problems (think fluent interfaces), `stub_chain` still + # results in brittle examples. For example, if you write + # `foo.stub_chain(:bar, :baz => 37)` in a spec and then the + # implementation calls `foo.baz.bar`, the stub will not work. + # + # @example + # double.stub_chain("foo.bar") { :baz } + # double.stub_chain(:foo, :bar => :baz) + # double.stub_chain(:foo, :bar) { :baz } + # + # # Given any of ^^ these three forms ^^: + # double.foo.bar # => :baz + # + # # Common use in Rails/ActiveRecord: + # Article.stub_chain("recent.published") { [Article.new] } + # + # @note This is only available when you have enabled the `should` syntax. + # @see RSpec::Mocks::ExampleMethods#receive_message_chain + + # @method as_null_object + # Tells the object to respond to all messages. If specific stub values + # are declared, they'll work as expected. If not, the receiver is + # returned. + # + # @note This is only available when you have enabled the `should` syntax. + + # @method null_object? + # Returns true if this object has received `as_null_object` + # + # @note This is only available when you have enabled the `should` syntax. + end +end + +# The legacy `:should` syntax adds the `any_instance` to `Class`. +# We generally recommend you use the newer `:expect` syntax instead, +# which allows you to stub any instance of a class using +# `allow_any_instance_of(klass)` or mock any instance using +# `expect_any_instance_of(klass)`. +# @see BasicObject +class Class + # @method any_instance + # Used to set stubs and message expectations on any instance of a given + # class. Returns a [Recorder](Recorder), which records messages like + # `stub` and `should_receive` for later playback on instances of the + # class. + # + # @example + # Car.any_instance.should_receive(:go) + # race = Race.new + # race.cars << Car.new + # race.go # assuming this delegates to all of its cars + # # this example would pass + # + # Account.any_instance.stub(:balance) { Money.new(:USD, 25) } + # Account.new.balance # => Money.new(:USD, 25)) + # + # @return [Recorder] + # + # @note This is only available when you have enabled the `should` syntax. + # @see RSpec::Mocks::ExampleMethods#expect_any_instance_of + # @see RSpec::Mocks::ExampleMethods#allow_any_instance_of +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/targets.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/targets.rb new file mode 100644 index 00000000..26f72871 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/targets.rb @@ -0,0 +1,124 @@ +module RSpec + module Mocks + # @private + module TargetDelegationClassMethods + def delegate_to(matcher_method) + define_method(:to) do |matcher, &block| + unless matcher_allowed?(matcher) + raise_unsupported_matcher(:to, matcher) + end + define_matcher(matcher, matcher_method, &block) + end + end + + def delegate_not_to(matcher_method, options={}) + method_name = options.fetch(:from) + define_method(method_name) do |matcher, &block| + case matcher + when Matchers::Receive, Matchers::HaveReceived + define_matcher(matcher, matcher_method, &block) + when Matchers::ReceiveMessages, Matchers::ReceiveMessageChain + raise_negation_unsupported(method_name, matcher) + else + raise_unsupported_matcher(method_name, matcher) + end + end + end + + def disallow_negation(method_name) + define_method(method_name) do |matcher, *_args| + raise_negation_unsupported(method_name, matcher) + end + end + end + + # @private + module TargetDelegationInstanceMethods + attr_reader :target + + private + + def matcher_allowed?(matcher) + Matchers::Matcher === matcher + end + + def define_matcher(matcher, name, &block) + matcher.__send__(name, target, &block) + end + + def raise_unsupported_matcher(method_name, matcher) + raise UnsupportedMatcherError, + "only the `receive`, `have_received` and `receive_messages` matchers are supported " \ + "with `#{expression}(...).#{method_name}`, but you have provided: #{matcher}" + end + + def raise_negation_unsupported(method_name, matcher) + raise NegationUnsupportedError, + "`#{expression}(...).#{method_name} #{matcher.matcher_name}` is not supported since it " \ + "doesn't really make sense. What would it even mean?" + end + end + + # @private + class TargetBase + def initialize(target) + @target = target + end + + extend TargetDelegationClassMethods + include TargetDelegationInstanceMethods + end + + # @private + module ExpectationTargetMethods + extend TargetDelegationClassMethods + include TargetDelegationInstanceMethods + + delegate_to :setup_expectation + delegate_not_to :setup_negative_expectation, :from => :not_to + delegate_not_to :setup_negative_expectation, :from => :to_not + + def expression + :expect + end + end + + # @private + class ExpectationTarget < TargetBase + include ExpectationTargetMethods + end + + # @private + class AllowanceTarget < TargetBase + def expression + :allow + end + + delegate_to :setup_allowance + disallow_negation :not_to + disallow_negation :to_not + end + + # @private + class AnyInstanceAllowanceTarget < TargetBase + def expression + :allow_any_instance_of + end + + delegate_to :setup_any_instance_allowance + disallow_negation :not_to + disallow_negation :to_not + end + + # @private + class AnyInstanceExpectationTarget < TargetBase + def expression + :expect_any_instance_of + end + + delegate_to :setup_any_instance_expectation + delegate_not_to :setup_any_instance_negative_expectation, :from => :not_to + delegate_not_to :setup_any_instance_negative_expectation, :from => :to_not + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/test_double.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/test_double.rb new file mode 100644 index 00000000..fed46dd7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/test_double.rb @@ -0,0 +1,173 @@ +module RSpec + module Mocks + # Implements the methods needed for a pure test double. RSpec::Mocks::Double + # includes this module, and it is provided for cases where you want a + # pure test double without subclassing RSpec::Mocks::Double. + module TestDouble + # Creates a new test double with a `name` (that will be used in error + # messages only) + def initialize(name=nil, stubs={}) + @__expired = false + if Hash === name && stubs.empty? + stubs = name + @name = nil + else + @name = name + end + assign_stubs(stubs) + end + + # Tells the object to respond to all messages. If specific stub values + # are declared, they'll work as expected. If not, the receiver is + # returned. + def as_null_object + __mock_proxy.as_null_object + end + + # Returns true if this object has received `as_null_object` + def null_object? + __mock_proxy.null_object? + end + + # This allows for comparing the mock to other objects that proxy such as + # ActiveRecords belongs_to proxy objects. By making the other object run + # the comparison, we're sure the call gets delegated to the proxy + # target. + def ==(other) + other == __mock_proxy + end + + # @private + def inspect + TestDoubleFormatter.format(self) + end + + # @private + def to_s + inspect.tr('<', '[').tr('>', ']') + end + + # @private + def respond_to?(message, incl_private=false) + return true if __mock_proxy.null_object? + + super + end + + # @private + def __build_mock_proxy_unless_expired(order_group) + __raise_expired_error || __build_mock_proxy(order_group) + end + + # @private + def __disallow_further_usage! + @__expired = true + end + + # Override for default freeze implementation to prevent freezing of test + # doubles. + def freeze + RSpec.warn_with("WARNING: you attempted to freeze a test double. This is explicitly a no-op as freezing doubles can lead to undesired behaviour when resetting tests.") + self + end + + private + + def method_missing(message, *args, &block) + proxy = __mock_proxy + proxy.record_message_received(message, *args, &block) + + if proxy.null_object? + case message + when :to_int then return 0 + when :to_a, :to_ary then return nil + when :to_str then return to_s + else return self + end + end + + # Defined private and protected methods will still trigger `method_missing` + # when called publicly. We want ruby's method visibility error to get raised, + # so we simply delegate to `super` in that case. + # ...well, we would delegate to `super`, but there's a JRuby + # bug, so we raise our own visibility error instead: + # https://github.com/jruby/jruby/issues/1398 + visibility = proxy.visibility_for(message) + if visibility == :private || visibility == :protected + ErrorGenerator.new(self).raise_non_public_error( + message, visibility + ) + end + + # Required wrapping doubles in an Array on Ruby 1.9.2 + raise NoMethodError if [:to_a, :to_ary].include? message + proxy.raise_unexpected_message_error(message, args) + end + + def assign_stubs(stubs) + stubs.each_pair do |message, response| + __mock_proxy.add_simple_stub(message, response) + end + end + + def __mock_proxy + ::RSpec::Mocks.space.proxy_for(self) + end + + def __build_mock_proxy(order_group) + TestDoubleProxy.new(self, order_group) + end + + def __raise_expired_error + return false unless @__expired + ErrorGenerator.new(self).raise_expired_test_double_error + end + + def initialize_copy(other) + as_null_object if other.null_object? + super + end + end + + # A generic test double object. `double`, `instance_double` and friends + # return an instance of this. + class Double + include TestDouble + end + + # @private + module TestDoubleFormatter + def self.format(dbl, unwrap=false) + format = "#{type_desc(dbl)}#{verified_module_desc(dbl)} #{name_desc(dbl)}" + return format if unwrap + "#<#{format}>" + end + + class << self + private + + def type_desc(dbl) + case dbl + when InstanceVerifyingDouble then "InstanceDouble" + when ClassVerifyingDouble then "ClassDouble" + when ObjectVerifyingDouble then "ObjectDouble" + else "Double" + end + end + + # @private + IVAR_GET = Object.instance_method(:instance_variable_get) + + def verified_module_desc(dbl) + return nil unless VerifyingDouble === dbl + "(#{IVAR_GET.bind(dbl).call(:@doubled_module).description})" + end + + def name_desc(dbl) + return "(anonymous)" unless (name = IVAR_GET.bind(dbl).call(:@name)) + name.inspect + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/verifying_double.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/verifying_double.rb new file mode 100644 index 00000000..3402967e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/verifying_double.rb @@ -0,0 +1,125 @@ +RSpec::Support.require_rspec_mocks 'verifying_proxy' + +module RSpec + module Mocks + # @private + module VerifyingDouble + def respond_to?(message, include_private=false) + return super unless null_object? + + method_ref = __mock_proxy.method_reference[message] + + case method_ref.visibility + when :public then true + when :private then include_private + when :protected then include_private || RUBY_VERSION.to_f < 2.0 + else !method_ref.unimplemented? + end + end + + def method_missing(message, *args, &block) + # Null object conditional is an optimization. If not a null object, + # validity of method expectations will have been checked at definition + # time. + if null_object? + if @__sending_message == message + __mock_proxy.ensure_implemented(message) + else + __mock_proxy.ensure_publicly_implemented(message, self) + end + + __mock_proxy.validate_arguments!(message, args) + end + + super + end + + # Redefining `__send__` causes ruby to issue a warning. + old, $VERBOSE = $VERBOSE, nil + # rubocop:disable Naming/MethodName + def __send__(name, *args, &block) + @__sending_message = name + super + ensure + @__sending_message = nil + end + # rubocop:enable Naming/MethodName + ruby2_keywords :__send__ if respond_to?(:ruby2_keywords, true) + $VERBOSE = old + + def send(name, *args, &block) + __send__(name, *args, &block) + end + ruby2_keywords :send if respond_to?(:ruby2_keywords, true) + + def initialize(doubled_module, *args) + @doubled_module = doubled_module + + possible_name = args.first + name = if String === possible_name || Symbol === possible_name + args.shift + end + + super(name, *args) + @__sending_message = nil + end + end + + # A mock providing a custom proxy that can verify the validity of any + # method stubs or expectations against the public instance methods of the + # given class. + # + # @private + class InstanceVerifyingDouble + include TestDouble + include VerifyingDouble + + def __build_mock_proxy(order_group) + VerifyingProxy.new(self, order_group, + @doubled_module, + InstanceMethodReference + ) + end + end + + # An awkward module necessary because we cannot otherwise have + # ClassVerifyingDouble inherit from Module and still share these methods. + # + # @private + module ObjectVerifyingDoubleMethods + include TestDouble + include VerifyingDouble + + def as_stubbed_const(options={}) + ConstantMutator.stub(@doubled_module.const_to_replace, self, options) + self + end + + private + + def __build_mock_proxy(order_group) + VerifyingProxy.new(self, order_group, + @doubled_module, + ObjectMethodReference + ) + end + end + + # Similar to an InstanceVerifyingDouble, except that it verifies against + # public methods of the given object. + # + # @private + class ObjectVerifyingDouble + include ObjectVerifyingDoubleMethods + end + + # Effectively the same as an ObjectVerifyingDouble (since a class is a type + # of object), except with Module in the inheritance chain so that + # transferring nested constants to work. + # + # @private + class ClassVerifyingDouble < Module + include ObjectVerifyingDoubleMethods + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/verifying_message_expectation.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/verifying_message_expectation.rb new file mode 100644 index 00000000..d6dcb574 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/verifying_message_expectation.rb @@ -0,0 +1,55 @@ +RSpec::Support.require_rspec_support 'method_signature_verifier' + +module RSpec + module Mocks + # A message expectation that knows about the real implementation of the + # message being expected, so that it can verify that any expectations + # have the valid arguments. + # @api private + class VerifyingMessageExpectation < MessageExpectation + # A level of indirection is used here rather than just passing in the + # method itself, since method look up is expensive and we only want to + # do it if actually needed. + # + # Conceptually the method reference makes more sense as a constructor + # argument since it should be immutable, but it is significantly more + # straight forward to build the object in pieces so for now it stays as + # an accessor. + attr_accessor :method_reference + + def initialize(*args) + super + end + + # @private + def with(*args, &block) + super(*args, &block).tap do + validate_expected_arguments! do |signature| + example_call_site_args = [:an_arg] * signature.min_non_kw_args + example_call_site_args << :kw_args_hash if signature.required_kw_args.any? + @argument_list_matcher.resolve_expected_args_based_on(example_call_site_args) + end + end + end + ruby2_keywords(:with) if respond_to?(:ruby2_keywords, true) + + private + + def validate_expected_arguments! + return if method_reference.nil? + + method_reference.with_signature do |signature| + args = yield signature + verifier = Support::LooseSignatureVerifier.new(signature, args) + + unless verifier.valid? + # Fail fast is required, otherwise the message expectation will fail + # as well ("expected method not called") and clobber this one. + @failed_fast = true + @error_generator.raise_invalid_arguments_error(verifier) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/verifying_proxy.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/verifying_proxy.rb new file mode 100644 index 00000000..6147b819 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/verifying_proxy.rb @@ -0,0 +1,221 @@ +RSpec::Support.require_rspec_mocks 'verifying_message_expectation' +RSpec::Support.require_rspec_mocks 'method_reference' + +module RSpec + module Mocks + # @private + class CallbackInvocationStrategy + def call(doubled_module) + RSpec::Mocks.configuration.verifying_double_callbacks.each do |block| + block.call doubled_module + end + end + end + + # @private + class NoCallbackInvocationStrategy + def call(_doubled_module) + end + end + + # @private + module VerifyingProxyMethods + def add_stub(method_name, opts={}, &implementation) + ensure_implemented(method_name) + super + end + + def add_simple_stub(method_name, *args) + ensure_implemented(method_name) + super + end + + def add_message_expectation(method_name, opts={}, &block) + ensure_implemented(method_name) + super + end + + def ensure_implemented(method_name) + return unless method_reference[method_name].unimplemented? + + @error_generator.raise_unimplemented_error( + @doubled_module, + method_name, + @object + ) + end + + def ensure_publicly_implemented(method_name, _object) + ensure_implemented(method_name) + visibility = method_reference[method_name].visibility + + return if visibility == :public + @error_generator.raise_non_public_error(method_name, visibility) + end + end + + # A verifying proxy mostly acts like a normal proxy, except that it + # contains extra logic to try and determine the validity of any expectation + # set on it. This includes whether or not methods have been defined and the + # validity of arguments on method calls. + # + # In all other ways this behaves like a normal proxy. It only adds the + # verification behaviour to specific methods then delegates to the parent + # implementation. + # + # These checks are only activated if the doubled class has already been + # loaded, otherwise they are disabled. This allows for testing in + # isolation. + # + # @private + class VerifyingProxy < TestDoubleProxy + include VerifyingProxyMethods + + def initialize(object, order_group, doubled_module, method_reference_class) + super(object, order_group) + @object = object + @doubled_module = doubled_module + @method_reference_class = method_reference_class + + # A custom method double is required to pass through a way to lookup + # methods to determine their parameters. This is only relevant if the doubled + # class is loaded. + @method_doubles = Hash.new do |h, k| + h[k] = VerifyingMethodDouble.new(@object, k, self, method_reference[k]) + end + end + + def method_reference + @method_reference ||= Hash.new do |h, k| + h[k] = @method_reference_class.for(@doubled_module, k) + end + end + + def visibility_for(method_name) + method_reference[method_name].visibility + end + + def validate_arguments!(method_name, args) + @method_doubles[method_name].validate_arguments!(args) + end + end + + # @private + DEFAULT_CALLBACK_INVOCATION_STRATEGY = CallbackInvocationStrategy.new + + # @private + class VerifyingPartialDoubleProxy < PartialDoubleProxy + include VerifyingProxyMethods + + def initialize(object, expectation_ordering, optional_callback_invocation_strategy=DEFAULT_CALLBACK_INVOCATION_STRATEGY) + super(object, expectation_ordering) + @doubled_module = DirectObjectReference.new(object) + + # A custom method double is required to pass through a way to lookup + # methods to determine their parameters. + @method_doubles = Hash.new do |h, k| + h[k] = VerifyingExistingMethodDouble.for(object, k, self) + end + + optional_callback_invocation_strategy.call(@doubled_module) + end + + def ensure_implemented(_method_name) + return if Mocks.configuration.temporarily_suppress_partial_double_verification + super + end + + def method_reference + @method_doubles + end + end + + # @private + class VerifyingPartialClassDoubleProxy < VerifyingPartialDoubleProxy + include PartialClassDoubleProxyMethods + end + + # @private + class VerifyingMethodDouble < MethodDouble + def initialize(object, method_name, proxy, method_reference) + super(object, method_name, proxy) + @method_reference = method_reference + end + + def message_expectation_class + VerifyingMessageExpectation + end + + def add_expectation(*args, &block) + # explicit params necessary for 1.8.7 see #626 + super(*args, &block).tap { |x| x.method_reference = @method_reference } + end + + def add_stub(*args, &block) + # explicit params necessary for 1.8.7 see #626 + super(*args, &block).tap { |x| x.method_reference = @method_reference } + end + + def proxy_method_invoked(obj, *args, &block) + validate_arguments!(args) + super + end + ruby2_keywords :proxy_method_invoked if respond_to?(:ruby2_keywords, true) + + def validate_arguments!(actual_args) + @method_reference.with_signature do |signature| + verifier = Support::StrictSignatureVerifier.new(signature, actual_args) + raise ArgumentError, verifier.error_message unless verifier.valid? + end + end + end + + # A VerifyingMethodDouble fetches the method to verify against from the + # original object, using a MethodReference. This works for pure doubles, + # but when the original object is itself the one being modified we need to + # collapse the reference and the method double into a single object so that + # we can access the original pristine method definition. + # + # @private + class VerifyingExistingMethodDouble < VerifyingMethodDouble + def initialize(object, method_name, proxy) + super(object, method_name, proxy, self) + + @valid_method = object.respond_to?(method_name, true) + + # Trigger an eager find of the original method since if we find it any + # later we end up getting a stubbed method with incorrect arity. + save_original_implementation_callable! + end + + def with_signature + yield Support::MethodSignature.new(original_implementation_callable) + end + + def unimplemented? + !@valid_method + end + + def self.for(object, method_name, proxy) + if ClassNewMethodReference.applies_to?(method_name) { object } + VerifyingExistingClassNewMethodDouble + elsif Mocks.configuration.temporarily_suppress_partial_double_verification + MethodDouble + else + self + end.new(object, method_name, proxy) + end + end + + # Used in place of a `VerifyingExistingMethodDouble` for the specific case + # of mocking or stubbing a `new` method on a class. In this case, we substitute + # the method signature from `#initialize` since new's signature is just `*args`. + # + # @private + class VerifyingExistingClassNewMethodDouble < VerifyingExistingMethodDouble + def with_signature + yield Support::MethodSignature.new(object.instance_method(:initialize)) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/version.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/version.rb new file mode 100644 index 00000000..9b42c775 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-mocks-3.13.5/lib/rspec/mocks/version.rb @@ -0,0 +1,9 @@ +module RSpec + module Mocks + # Version information for RSpec mocks. + module Version + # Version of RSpec mocks currently in use in SemVer format. + STRING = '3.13.5' + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/Changelog.md b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/Changelog.md new file mode 100644 index 00000000..2f31e09b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/Changelog.md @@ -0,0 +1,420 @@ +### Development +[Full Changelog](https://github.com/rspec/rspec/compare/rspec-support-v3.13.2...3-13-maintenance) + +### 3.13.4 +[Full Changelog](http://github.com/rspec/rspec/compare/rspec-support-v3.13.3...rspec-support-v3.13.4) + +Bug Fixes: + +* Fix homepage link in gemspec. (Jon Rowe) + +### 3.13.3 / 2025-04-30 +[Full Changelog](http://github.com/rspec/rspec/compare/rspec-support-v3.13.2...rspec-support-v3.13.3) + +Bug Fixes: + +* Support for changes in diff-lcs and Ruby 3.4 in spec helpers. (Jon Rowe, #164 etc) + +### 3.13.2 / 2024-12-02 +[Full Changelog](http://github.com/rspec/rspec/compare/rspec-support-v3.13.1...rspec-support-v3.13.2) + +No changes. Released during the monorepo migration to test release processes, but accidentally +contained no changes. + +### 3.13.1 / 2024-02-23 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.13.0...v3.13.1) + +Bug Fixes: + +* Exclude ruby internal require warnings from `RSpec::Support::CallerFilter#first_non_rspec_line`. + (Jon Rowe, rspec/rspec-support#593) + +### 3.13.0 / 2024-02-04 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.12.2...v3.13.0) + +Enchancements + +* Add `RubyFeatures#supports_syntax_suggest?`. (Jon Rowe, rspec/rspec-support#571) + +Bug Fixes: + +* Allow string keys for keyword arguments during verification of method + signatures, (but only on Ruby 3+). (@malcolmohare, rspec/rspec-support#591) + +### 3.12.2 / 2024-02-04 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.12.1...v3.12.2) + +Bug Fixes: + +* Properly surface errors from `in_sub_process`. (Jon Rowe, rspec/rspec-support#575) +* Add magic comment for freezing string literals. (Josh Nichols, rspec/rspec-support#586) + +### 3.12.1 / 2023-06-26 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.12.0...v3.12.1) + +Bug Fixes: + +* Fix `RSpec::Support.thread_local_data` to be Thread local but not Fiber local. + (Jon Rowe, rspec/rspec-support#581) + +### 3.12.0 / 2022-10-26 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.11.1...v3.12.0) +Enhancements: + +* Add `RSpec::Support::RubyFeatures.distincts_kw_args_from_positional_hash?` + (Jean byroot Boussier, rspec/rspec-support#535) + +### 3.11.1 / 2022-09-12 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.11.0...v3.11.1) + +Bug Fixes: + +* Fix ripper detection on TruffleRuby. (Brandon Fish, rspec/rspec-support#541) + +### 3.11.0 / 2022-02-09 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.10.3...v3.11.0) + +No changes. Released to support other RSpec releases. + +### 3.10.3 / 2021-11-03 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.10.2...v3.10.3) + +Bug Fixes: + +* Use `Mutex#owned?` to allow `RSpec::Support::ReentrantMutex` to work in + nested Fibers on Ruby 3.0 and later. (Benoit Daloze, rspec/rspec-support#503, rspec/rspec-support#504) +* Support `end`-less methods in `RSpec::Support::Source::Token` + so that RSpec won't hang when an `end`-less method raises an error. (Yuji Nakayama, rspec/rspec-support#505) + +### 3.10.2 / 2021-01-28 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.10.1...v3.10.2) + +Bug Fixes: + +* Fix issue with `RSpec::Support.define_optimized_require_for_rspec` on JRuby + 9.1.17.0 (Jon Rowe, rspec/rspec-support#492) + +### 3.10.1 / 2020-12-27 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.10.0...v3.10.1) + +Bug Fixes: + +* Fix deprecation expectations to fail correctly when + asserting on messages. (Phil Pirozhkov, rspec/rspec-support#453) + +### 3.10.0 / 2020-10-30 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.9.4...v3.10.0) + +No changes. Released to support other RSpec releases. + +### 3.9.4 / 2020-10-23 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.9.3...v3.9.4) + +Bug Fixes: + +* Flag ripper as supported on Truffle Ruby. (Brandon Fish, rspec/rspec-support#427) +* Prevent stubbing `File.read` from breaking source extraction. + (Jon Rowe, rspec/rspec-support#431) + +### 3.9.3 / 2020-05-02 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.9.2...v3.9.3) + +Bug Fixes: + +* Mark ripper as unsupported on Truffle Ruby. (Brandon Fish, rspec/rspec-support#395) +* Mark ripper as unsupported on JRuby 9.2.0.0. (Brian Hawley, rspec/rspec-support#400) +* Capture `Mutex.new` for our `RSpec::Support:Mutex` in order to + allow stubbing `Mutex.new`. (Jon Rowe, rspec/rspec-support#411) + +### 3.9.2 / 2019-12-30 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.9.1...v3.9.2) + +Bug Fixes: + +* Remove unneeded eval. (Matijs van Zuijlen, rspec/rspec-support#394) + +### 3.9.1 / 2019-12-28 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.9.0...v3.9.1) + +Bug Fixes: + +* Remove warning caused by keyword arguments on Ruby 2.7.0. + (Jon Rowe, rspec/rspec-support#392) + +### 3.9.0 / 2019-10-07 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.8.3...v3.9.0) + +*NO CHANGES* + +Version 3.9.0 was released to allow other RSpec gems to release 3.9.0. + +### 3.8.3 / 2019-10-02 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.8.2...v3.8.3) + +Bug Fixes: + +* Escape \r when outputting strings inside arrays. + (Tomita Masahiro, Jon Rowe, rspec/rspec-support#378) +* Ensure that optional hash arguments are recognised correctly vs keyword + arguments. (Evgeni Dzhelyov, rspec/rspec-support#366) + +### 3.8.2 / 2019-06-10 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.8.1...v3.8.2) + +Bug Fixes: + +* Ensure that an empty hash is recognised as empty keyword arguments when + applicable. (Thomas Walpole, rspec/rspec-support#375) +* Ensure that diffing truthy values produce diffs consistently. + (Lucas Nestor, rspec/rspec-support#377) + +### 3.8.1 / 2019-03-03 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.8.0...v3.8.1) + +Bug Fixes: + +* Ensure that inspecting a `SimpleDelegator` based object works regardless of + visibility of the `__getobj__` method. (Jon Rowe, rspec/rspec-support#369) + +### 3.8.0 / 2018-08-04 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.7.1...v3.8.0) + +Bug Fixes: + +* Order hash keys before diffing to improve diff accuracy when using mocked calls. + (James Crisp, rspec/rspec-support#334) + +### 3.7.1 / 2018-01-29 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.7.0...v3.7.1) + +Bug Fixes: + +* Fix source extraction logic so that it does not trigger a `SystemStackError` + when processing deeply nested example groups. (Craig Bass, rspec/rspec-support#343) + +### 3.7.0 / 2017-10-17 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.6.0...v3.7.0) + +Enhancements: + +* Improve compatibility with `--enable-frozen-string-literal` option + on Ruby 2.3+. (Pat Allan, rspec/rspec-support#320) +* Add `Support.class_of` for extracting class of any object. + (Yuji Nakayama, rspec/rspec-support#325) + +Bug Fixes: + +* Fix recursive const support to not blow up when given buggy classes + that raise odd errors from `#to_str`. (Myron Marston, rspec/rspec-support#317) + +### 3.6.0 / 2017-05-04 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.6.0.beta2...3.6.0) + +Enhancements: + +* Import `Source` classes from rspec-core. (Yuji Nakayama, rspec/rspec-support#315) + +### 3.6.0.beta2 / 2016-12-12 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.6.0.beta1...v3.6.0.beta2) + +No user-facing changes. + +### 3.6.0.beta1 / 2016-10-09 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.5.0...v3.6.0.beta1) + +Bug Fixes: + +* Prevent truncated formatted object output from mangling console codes. (rspec/rspec-support#294, Anson Kelly) + +### 3.5.0 / 2016-07-01 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.5.0.beta4...v3.5.0) + +**No user facing changes since beta4** + +### 3.5.0.beta4 / 2016-06-05 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.5.0.beta3...v3.5.0.beta4) + +Enhancements: +* Improve `MethodSignature` to better support keyword arguments. (rspec/rspec-support#250, Rob Smith). + +### 3.5.0.beta3 / 2016-04-02 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.5.0.beta2...v3.5.0.beta3) + +Bug Fixes: + +* Fix `EncodedString` to properly handle the behavior of `String#split` + on JRuby when the string contains invalid bytes. (Jon Rowe, rspec/rspec-support#268) +* Fix `ObjectFormatter` so that formatting objects that don't respond to + `#inspect` (such as `BasicObject`) does not cause `NoMethodError`. + (Yuji Nakayama, rspec/rspec-support#269) +* Fix `ObjectFormatter` so that formatting recursive array or hash does not + cause `SystemStackError`. (Yuji Nakayama, rspec/rspec-support#270, rspec/rspec-support#272) + +### 3.5.0.beta2 / 2016-03-10 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.5.0.beta1...v3.5.0.beta2) + +No user-facing changes. + +### 3.5.0.beta1 / 2016-02-06 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.4.1...v3.5.0.beta1) + +Enhancements: + +* Improve formatting of objects by allowing truncation to a pre-configured length. + (Liam M, rspec/rspec-support#256) + +### 3.4.1 / 2015-11-20 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.4.0...v3.4.1) + +Bug Fixes: + +* Fix `RSpec::Support::RubyFeature.ripper_supported?` so it returns + `false` on Rubinius since the Rubinius team has no plans to support + it. This prevents rspec-core from trying to load and use ripper to + extract failure snippets. (Aaron Stone, rspec/rspec-support#251) + +Changes: + +* Remove `VersionChecker` in favor of `ComparableVersion`. (Yuji Nakayama, rspec/rspec-support#266) + +### 3.4.0 / 2015-11-11 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.3.0...v3.4.0) + +Enhancements: + +* Improve formatting of `Delegator` based objects (e.g. `SimpleDelegator`) in + failure messages and diffs. (Andrew Horner, rspec/rspec-support#215) +* Add `ComparableVersion`. (Yuji Nakayama, rspec/rspec-support#245) +* Add `Ripper` support detection. (Yuji Nakayama, rspec/rspec-support#245) + +Bug Fixes: + +* Work around bug in JRuby that reports that `attr_writer` methods + have no parameters, causing RSpec's verifying doubles to wrongly + fail when mocking or stubbing a writer method on JRuby. (Myron Marston, rspec/rspec-support#225) + +### 3.3.0 / 2015-06-12 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.2.2...v3.3.0) + +Enhancements: + +* Improve formatting of arrays and hashes in failure messages so they + use our custom formatting of matchers, time objects, etc. + (Myron Marston, Nicholas Chmielewski, rspec/rspec-support#205) +* Use improved formatting for diffs as well. (Nicholas Chmielewski, rspec/rspec-support#205) + +Bug Fixes: + +* Fix `FuzzyMatcher` so that it checks `expected == actual` rather than + `actual == expected`, which avoids errors in situations where the + `actual` object's `==` is improperly implemented to assume that only + objects of the same type will be given. This allows rspec-mocks' + `anything` to match against objects with buggy `==` definitions. + (Myron Marston, rspec/rspec-support#193) + +### 3.2.2 / 2015-02-23 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.2.1...v3.2.2) + +Bug Fixes: + +* Fix an encoding issue with `EncodedString#split` when encountering an + invalid byte string. (Benjamin Fleischer, rspec/rspec-support#1760) + +### 3.2.1 / 2015-02-04 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.2.0...v3.2.1) + +Bug Fixes: + +* Fix `RSpec::CallerFilter` to work on Rubinius 2.2. + (Myron Marston, rspec/rspec-support#169) + +### 3.2.0 / 2015-02-03 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.1.2...v3.2.0) + +Enhancements: + +* Add extra Ruby type detection. (Jon Rowe, rspec/rspec-support#133) +* Make differ instance re-usable. (Alexey Fedorov, rspec/rspec-support#160) + +Bug Fixes: + +* Do not consider `[]` and `{}` to match when performing fuzzy matching. + (Myron Marston, rspec/rspec-support#157) + +### 3.1.2 / 2014-10-08 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.1.1...v3.1.2) + +Bug Fixes: + +* Fix method signature to not blow up with a `NoMethodError` on 1.8.7 when + verifying against an RSpec matcher. (Myron Marston, rspec/rspec-support#116) + +### 3.1.1 / 2014-09-26 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.1.0...v3.1.1) + +Bug Fixes: + +* Fix `RSpec::Support::DirectoryMaker` (used by `rspec --init` and + `rails generate rspec:install`) so that it detects absolute paths + on Windows properly. (Scott Archer, rspec/rspec-support#107, rspec/rspec-support#108, rspec/rspec-support#109) (Jon Rowe, rspec/rspec-support#110) + +### 3.1.0 / 2014-09-04 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.4...v3.1.0) + +Bug Fixes: + +* Fix `FuzzyMatcher` so that it does not wrongly match a struct against + an array. (Myron Marston, rspec/rspec-support#97) +* Prevent infinitely recursing `#flatten` methods from causing the differ + to hang. (Jon Rowe, rspec/rspec-support#101) + +### 3.0.4 / 2014-08-14 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.3...v3.0.4) + +Bug Fixes: + +* Fix `FuzzyMatcher` so that it does not silence `ArgumentError` raised + from broken implementations of `==`. (Myron Marston, rspec/rspec-support#94) + +### 3.0.3 / 2014-07-21 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.2...v3.0.3) + +Bug Fixes: + +* Fix regression in `Support#method_handle_for` where proxy objects + with method delegated would wrongly not return a method handle. + (Jon Rowe, rspec/rspec-support#90) +* Properly detect Module#prepend support in Ruby 2.1+ (Ben Langfeld, rspec/rspec-support#91) +* Fix `rspec/support/warnings.rb` so it can be loaded and used in + isolation. (Myron Marston, rspec/rspec-support#93) + +### 3.0.2 / 2014-06-20 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.1...v3.0.2) + +* Revert `BlockSignature` change from 3.0.1 because of a ruby bug that + caused it to change the block's behavior (https://bugs.ruby-lang.org/issues/9967). + (Myron Marston, rspec-mocksrspec/rspec-support#721) + +### 3.0.1 / 2014-06-19 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.0...v3.0.1) + +* Fix `BlockSignature` so that it correctly differentiates between + required and optional block args. (Myron Marston, rspec-mocksrspec/rspec-support#714) + +### 3.0.0 / 2014-06-01 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.0.rc1...v3.0.0) + +### 3.0.0.rc1 / 2014-05-18 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.0.beta2...v3.0.0.rc1) + +### 3.0.0.beta2 / 2014-02-17 +[Full Changelog](http://github.com/rspec/rspec-support/compare/v3.0.0.beta1...v3.0.0.beta2) + +Bug Fixes: + +* Issue message when :replacement is passed to `RSpec.warn_with`. (Jon Rowe) + +### 3.0.0.beta1 / 2013-11-07 +[Full Changelog](https://github.com/rspec/rspec-support/compare/0dc12d1bdbbacc757a9989f8c09cd08ef3a4837e...v3.0.0.beta1) + +Initial release. diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/LICENSE.md b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/LICENSE.md new file mode 100644 index 00000000..08aa3abb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/LICENSE.md @@ -0,0 +1,23 @@ +The MIT License (MIT) +==================== + +* Copyright © 2013 David Chelimsky, Myron Marston, Jon Rowe, Sam Phippen, Xavier Shay, Bradley Schaefer + +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 AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/README.md b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/README.md new file mode 100644 index 00000000..bb88209d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/README.md @@ -0,0 +1,40 @@ +# RSpec::Support [![Build Status](https://github.com/rspec/rspec-support/workflows/RSpec%20CI/badge.svg)](https://github.com/rspec/rspec-support/actions) + +`RSpec::Support` provides common functionality to `RSpec::Core`, +`RSpec::Expectations` and `RSpec::Mocks`. It is considered +suitable for internal use only at this time. + +## Installation / Usage + +Install one or more of the `RSpec` gems. + +Want to run against the `main` branch? You'll need to include the dependent +RSpec repos as well. Add the following to your `Gemfile`: + +```ruby +%w[rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib| + gem lib, :git => "https://github.com/rspec/#{lib}.git", :branch => 'main' +end +``` + +## Contributing + +Once you've set up the environment, you'll need to cd into the working +directory of whichever repo you want to work in. From there you can run the +specs and cucumber features, and make patches. + +NOTE: You do not need to use rspec-dev to work on a specific RSpec repo. You +can treat each RSpec repo as an independent project. + +- [Build details](BUILD_DETAIL.md) +- [Code of Conduct](CODE_OF_CONDUCT.md) +- [Detailed contributing guide](CONTRIBUTING.md) +- [Development setup guide](DEVELOPMENT.md) + +## Patches + +Please submit a pull request or a github issue. If you submit an issue, please +include a link to either of: + +* a gist (or equivalent) of the patch +* a branch or commit in your github fork of the repo diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support.rb new file mode 100644 index 00000000..72154e07 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support.rb @@ -0,0 +1,162 @@ +# frozen_string_literal: true + +module RSpec + module Support + # @api private + # + # Defines a helper method that is optimized to require files from the + # named lib. The passed block MUST be `{ |f| require_relative f }` + # because for `require_relative` to work properly from within the named + # lib the line of code must be IN that lib. + # + # `require_relative` is preferred when available because it is always O(1), + # regardless of the number of dirs in $LOAD_PATH. `require`, on the other + # hand, does a linear O(N) search over the dirs in the $LOAD_PATH until + # it can resolve the file relative to one of the dirs. + def self.define_optimized_require_for_rspec(lib, &require_relative) + name = "require_rspec_#{lib}" + + if RUBY_PLATFORM == 'java' && !Kernel.respond_to?(:require) + # JRuby 9.1.17.0 has developed a regression for require + (class << self; self; end).__send__(:define_method, name) do |f| + Kernel.send(:require, "rspec/#{lib}/#{f}") + end + elsif Kernel.respond_to?(:require_relative) + (class << self; self; end).__send__(:define_method, name) do |f| + require_relative.call("#{lib}/#{f}") + end + else + (class << self; self; end).__send__(:define_method, name) do |f| + require "rspec/#{lib}/#{f}" + end + end + end + + define_optimized_require_for_rspec(:support) { |f| require_relative(f) } + require_rspec_support "version" + require_rspec_support "ruby_features" + + # @api private + KERNEL_METHOD_METHOD = ::Kernel.instance_method(:method) + + # @api private + # + # Used internally to get a method handle for a particular object + # and method name. + # + # Includes handling for a few special cases: + # + # - Objects that redefine #method (e.g. an HTTPRequest struct) + # - BasicObject subclasses that mixin a Kernel dup (e.g. SimpleDelegator) + # - Objects that undefine method and delegate everything to another + # object (e.g. Mongoid association objects) + if RubyFeatures.supports_rebinding_module_methods? + def self.method_handle_for(object, method_name) + KERNEL_METHOD_METHOD.bind(object).call(method_name) + rescue NameError => original + begin + handle = object.method(method_name) + raise original unless handle.is_a? Method + handle + rescue Support::AllExceptionsExceptOnesWeMustNotRescue + raise original + end + end + else + def self.method_handle_for(object, method_name) + if ::Kernel === object + KERNEL_METHOD_METHOD.bind(object).call(method_name) + else + object.method(method_name) + end + rescue NameError => original + begin + handle = object.method(method_name) + raise original unless handle.is_a? Method + handle + rescue Support::AllExceptionsExceptOnesWeMustNotRescue + raise original + end + end + end + + # @api private + # + # Used internally to get a class of a given object, even if it does not respond to #class. + def self.class_of(object) + object.class + rescue NoMethodError + singleton_class = class << object; self; end + singleton_class.ancestors.find { |ancestor| !ancestor.equal?(singleton_class) } + end + + # A single thread local variable so we don't excessively pollute that namespace. + if RUBY_VERSION.to_f >= 2 + def self.thread_local_data + Thread.current.thread_variable_get(:__rspec) || Thread.current.thread_variable_set(:__rspec, {}) + end + else + def self.thread_local_data + Thread.current[:__rspec] ||= {} + end + end + + # @api private + def self.failure_notifier=(callable) + thread_local_data[:failure_notifier] = callable + end + + # @private + DEFAULT_FAILURE_NOTIFIER = lambda { |failure, _opts| raise failure } + + # @api private + def self.failure_notifier + thread_local_data[:failure_notifier] || DEFAULT_FAILURE_NOTIFIER + end + + # @api private + def self.notify_failure(failure, options={}) + failure_notifier.call(failure, options) + end + + # @api private + def self.with_failure_notifier(callable) + orig_notifier = failure_notifier + self.failure_notifier = callable + yield + ensure + self.failure_notifier = orig_notifier + end + + class << self + # @api private + attr_writer :warning_notifier + end + + # @private + DEFAULT_WARNING_NOTIFIER = lambda { |warning| ::Kernel.warn warning } + + # @api private + def self.warning_notifier + @warning_notifier ||= DEFAULT_WARNING_NOTIFIER + end + + # @private + module AllExceptionsExceptOnesWeMustNotRescue + # These exceptions are dangerous to rescue as rescuing them + # would interfere with things we should not interfere with. + AVOID_RESCUING = [NoMemoryError, SignalException, Interrupt, SystemExit] + + def self.===(exception) + AVOID_RESCUING.none? { |ar| ar === exception } + end + end + + # The Differ is only needed when a spec fails with a diffable failure. + # In the more common case of all specs passing or the only failures being + # non-diffable, we can avoid the extra cost of loading the differ, diff-lcs, + # pp, etc by avoiding an unnecessary require. Instead, autoload will take + # care of loading the differ on first use. + autoload :Differ, "rspec/support/differ" + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/caller_filter.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/caller_filter.rb new file mode 100644 index 00000000..e54b23aa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/caller_filter.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +RSpec::Support.require_rspec_support "ruby_features" + +module RSpec + # Consistent implementation for "cleaning" the caller method to strip out + # non-rspec lines. This enables errors to be reported at the call site in + # the code using the library, which is far more useful than the particular + # internal method that raised an error. + class CallerFilter + RSPEC_LIBS = %w[ + core + mocks + expectations + support + matchers + rails + ] + + ADDITIONAL_TOP_LEVEL_FILES = %w[ autorun ] + + LIB_REGEX = %r{/lib/rspec/(#{(RSPEC_LIBS + ADDITIONAL_TOP_LEVEL_FILES).join('|')})(\.rb|/)} + + # rubygems/core_ext/kernel_require.rb isn't actually part of rspec (obviously) but we want + # it ignored when we are looking for the first meaningful line of the backtrace outside + # of RSpec. It can show up in the backtrace as the immediate first caller + # when `CallerFilter.first_non_rspec_line` is called from the top level of a required + # file, but it depends on if rubygems is loaded or not. We don't want to have to deal + # with this complexity in our `RSpec.deprecate` calls, so we ignore it here. + IGNORE_REGEX = Regexp.union(LIB_REGEX, "rubygems/core_ext/kernel_require.rb", "(other) + other = self.class.new(other) unless other.is_a?(self.class) + + return 0 if string == other.string + + longer_segment_count = [self, other].map { |version| version.segments.count }.max + + longer_segment_count.times do |index| + self_segment = segments[index] || 0 + other_segment = other.segments[index] || 0 + + if self_segment.class == other_segment.class + result = self_segment <=> other_segment + return result unless result == 0 + else + return self_segment.is_a?(String) ? -1 : 1 + end + end + + 0 + end + + def segments + @segments ||= string.scan(/[a-z]+|\d+/i).map do |segment| + if segment =~ /\A\d+\z/ + segment.to_i + else + segment + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/differ.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/differ.rb new file mode 100644 index 00000000..9488296e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/differ.rb @@ -0,0 +1,217 @@ +# frozen_string_literal: true + +RSpec::Support.require_rspec_support 'encoded_string' +RSpec::Support.require_rspec_support 'hunk_generator' +RSpec::Support.require_rspec_support "object_formatter" + +require 'pp' + +module RSpec + module Support + # rubocop:disable Metrics/ClassLength + class Differ + def diff(actual, expected) + diff = "" + + unless actual.nil? || expected.nil? + if all_strings?(actual, expected) + if any_multiline_strings?(actual, expected) + diff = diff_as_string(coerce_to_string(actual), coerce_to_string(expected)) + end + elsif no_procs?(actual, expected) && no_numbers?(actual, expected) + diff = diff_as_object(actual, expected) + end + end + + diff.to_s + end + + # rubocop:disable Metrics/MethodLength + def diff_as_string(actual, expected) + encoding = EncodedString.pick_encoding(actual, expected) + + actual = EncodedString.new(actual, encoding) + expected = EncodedString.new(expected, encoding) + + output = EncodedString.new("\n", encoding) + hunks = build_hunks(actual, expected) + + hunks.each_cons(2) do |prev_hunk, current_hunk| + begin + if current_hunk.overlaps?(prev_hunk) + add_old_hunk_to_hunk(current_hunk, prev_hunk) + else + add_to_output(output, prev_hunk.diff(format_type).to_s) + end + ensure + add_to_output(output, "\n") + end + end + + finalize_output(output, hunks.last.diff(format_type).to_s) if hunks.last + + color_diff output + rescue Encoding::CompatibilityError + handle_encoding_errors(actual, expected) + end + # rubocop:enable Metrics/MethodLength + + def diff_as_object(actual, expected) + actual_as_string = object_to_string(actual) + expected_as_string = object_to_string(expected) + diff_as_string(actual_as_string, expected_as_string) + end + + def color? + @color + end + + def initialize(opts={}) + @color = opts.fetch(:color, false) + @object_preparer = opts.fetch(:object_preparer, lambda { |string| string }) + end + + private + + def no_procs?(*args) + safely_flatten(args).none? { |a| Proc === a } + end + + def all_strings?(*args) + safely_flatten(args).all? { |a| String === a } + end + + def any_multiline_strings?(*args) + all_strings?(*args) && safely_flatten(args).any? { |a| multiline?(a) } + end + + def no_numbers?(*args) + safely_flatten(args).none? { |a| Numeric === a } + end + + def coerce_to_string(string_or_array) + return string_or_array unless Array === string_or_array + diffably_stringify(string_or_array).join("\n") + end + + def diffably_stringify(array) + array.map do |entry| + if Array === entry + entry.inspect + else + entry.to_s.gsub("\n", "\\n").gsub("\r", "\\r") + end + end + end + + if String.method_defined?(:encoding) + def multiline?(string) + string.include?("\n".encode(string.encoding)) + end + else + def multiline?(string) + string.include?("\n") + end + end + + def build_hunks(actual, expected) + HunkGenerator.new(actual, expected).hunks + end + + def finalize_output(output, final_line) + add_to_output(output, final_line) + add_to_output(output, "\n") + end + + def add_to_output(output, string) + output << string + end + + def add_old_hunk_to_hunk(hunk, oldhunk) + hunk.merge(oldhunk) + end + + def safely_flatten(array) + array = array.flatten(1) until (array == array.flatten(1)) + array + end + + def format_type + :unified + end + + def color(text, color_code) + "\e[#{color_code}m#{text}\e[0m" + end + + def red(text) + color(text, 31) + end + + def green(text) + color(text, 32) + end + + def blue(text) + color(text, 34) + end + + def normal(text) + color(text, 0) + end + + def color_diff(diff) + return diff unless color? + + diff.lines.map do |line| + case line[0].chr + when "+" + green line + when "-" + red line + when "@" + line[1].chr == "@" ? blue(line) : normal(line) + else + normal(line) + end + end.join + end + + def object_to_string(object) + object = @object_preparer.call(object) + case object + when Hash + hash_to_string(object) + when Array + PP.pp(ObjectFormatter.prepare_for_inspection(object), "".dup) + when String + object =~ /\n/ ? object : object.inspect + else + PP.pp(object, "".dup) + end + end + + def hash_to_string(hash) + formatted_hash = ObjectFormatter.prepare_for_inspection(hash) + formatted_hash.keys.sort_by { |k| k.to_s }.map do |key| + pp_key = PP.singleline_pp(key, "".dup) + pp_value = PP.singleline_pp(formatted_hash[key], "".dup) + + "#{pp_key} => #{pp_value}," + end.join("\n") + end + + def handle_encoding_errors(actual, expected) + if actual.source_encoding != expected.source_encoding + "Could not produce a diff because the encoding of the actual string " \ + "(#{actual.source_encoding}) differs from the encoding of the expected " \ + "string (#{expected.source_encoding})" + else + "Could not produce a diff because of the encoding of the string " \ + "(#{expected.source_encoding})" + end + end + end + # rubocop:enable Metrics/ClassLength + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/directory_maker.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/directory_maker.rb new file mode 100644 index 00000000..c59d7513 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/directory_maker.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +RSpec::Support.require_rspec_support 'ruby_features' + +module RSpec + module Support + # @api private + # + # Replacement for fileutils#mkdir_p because we don't want to require parts + # of stdlib in RSpec. + class DirectoryMaker + # @api private + # + # Implements nested directory construction + def self.mkdir_p(path) + stack = generate_stack(path) + path.split(File::SEPARATOR).each do |part| + stack = generate_path(stack, part) + begin + Dir.mkdir(stack) unless directory_exists?(stack) + rescue Errno::EEXIST => e + raise e unless directory_exists?(stack) + rescue Errno::ENOTDIR => e + raise Errno::EEXIST, e.message + end + end + end + + if OS.windows_file_path? + def self.generate_stack(path) + if path.start_with?(File::SEPARATOR) + File::SEPARATOR + elsif path[1] == ':' + '' + else + '.' + end + end + def self.generate_path(stack, part) + if stack == '' + part + elsif stack == File::SEPARATOR + File.join('', part) + else + File.join(stack, part) + end + end + else + def self.generate_stack(path) + path.start_with?(File::SEPARATOR) ? File::SEPARATOR : "." + end + def self.generate_path(stack, part) + File.join(stack, part) + end + end + + def self.directory_exists?(dirname) + File.exist?(dirname) && File.directory?(dirname) + end + private_class_method :directory_exists? + private_class_method :generate_stack + private_class_method :generate_path + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/encoded_string.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/encoded_string.rb new file mode 100644 index 00000000..044c151a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/encoded_string.rb @@ -0,0 +1,163 @@ +# frozen_string_literal: true + +module RSpec + module Support + # @private + class EncodedString + # Reduce allocations by storing constants. + UTF_8 = "UTF-8" + US_ASCII = "US-ASCII" + + # Ruby's default replacement string is: + # U+FFFD ("\xEF\xBF\xBD"), for Unicode encoding forms, else + # ? ("\x3F") + REPLACE = "?" + + def initialize(string, encoding=nil) + @encoding = encoding + @source_encoding = detect_source_encoding(string) + @string = matching_encoding(string) + end + attr_reader :source_encoding + + delegated_methods = String.instance_methods.map(&:to_s) & %w[eql? lines == encoding empty?] + delegated_methods.each do |name| + define_method(name) { |*args, &block| @string.__send__(name, *args, &block) } + end + + def <<(string) + @string << matching_encoding(string) + end + + if Ruby.jruby? + def split(regex_or_string) + @string.split(matching_encoding(regex_or_string)) + rescue ArgumentError + # JRuby raises an ArgumentError when splitting a source string that + # contains invalid bytes. + remove_invalid_bytes(@string).split regex_or_string + end + else + def split(regex_or_string) + @string.split(matching_encoding(regex_or_string)) + end + end + + def to_s + @string + end + alias :to_str :to_s + + if String.method_defined?(:encoding) + + private + + # Encoding Exceptions: + # + # Raised by Encoding and String methods: + # Encoding::UndefinedConversionError: + # when a transcoding operation fails + # if the String contains characters invalid for the target encoding + # e.g. "\x80".encode('UTF-8','ASCII-8BIT') + # vs "\x80".encode('UTF-8','ASCII-8BIT', undef: :replace, replace: '') + # # => '' + # Encoding::CompatibilityError + # when Encoding.compatible?(str1, str2) is nil + # e.g. utf_16le_emoji_string.split("\n") + # e.g. valid_unicode_string.encode(utf8_encoding) << ascii_string + # Encoding::InvalidByteSequenceError: + # when the string being transcoded contains a byte invalid for + # either the source or target encoding + # e.g. "\x80".encode('UTF-8','US-ASCII') + # vs "\x80".encode('UTF-8','US-ASCII', invalid: :replace, replace: '') + # # => '' + # ArgumentError + # when operating on a string with invalid bytes + # e.g."\x80".split("\n") + # TypeError + # when a symbol is passed as an encoding + # Encoding.find(:"UTF-8") + # when calling force_encoding on an object + # that doesn't respond to #to_str + # + # Raised by transcoding methods: + # Encoding::ConverterNotFoundError: + # when a named encoding does not correspond with a known converter + # e.g. 'abc'.force_encoding('UTF-8').encode('foo') + # or a converter path cannot be found + # e.g. "\x80".force_encoding('ASCII-8BIT').encode('Emacs-Mule') + # + # Raised by byte <-> char conversions + # RangeError: out of char range + # e.g. the UTF-16LE emoji: 128169.chr + def matching_encoding(string) + string = remove_invalid_bytes(string) + string.encode(@encoding) + rescue Encoding::UndefinedConversionError, Encoding::InvalidByteSequenceError + # Originally defined as a constant to avoid unneeded allocations, this hash must + # be defined inline (without {}) to avoid warnings on Ruby 2.7 + # + # In MRI 2.1 'invalid: :replace' changed to also replace an invalid byte sequence + # see https://github.com/ruby/ruby/blob/v2_1_0/NEWS#L176 + # https://www.ruby-forum.com/topic/6861247 + # https://twitter.com/nalsh/status/553413844685438976 + # + # For example, given: + # "\x80".force_encoding("Emacs-Mule").encode(:invalid => :replace).bytes.to_a + # + # On MRI 2.1 or above: 63 # '?' + # else : 128 # "\x80" + # + string.encode(@encoding, :invalid => :replace, :undef => :replace, :replace => REPLACE) + rescue Encoding::ConverterNotFoundError + # Originally defined as a constant to avoid unneeded allocations, this hash must + # be defined inline (without {}) to avoid warnings on Ruby 2.7 + string.dup.force_encoding(@encoding).encode(:invalid => :replace, :replace => REPLACE) + end + + # Prevents raising ArgumentError + if String.method_defined?(:scrub) + # https://github.com/ruby/ruby/blob/eeb05e8c11/doc/NEWS-2.1.0#L120-L123 + # https://github.com/ruby/ruby/blob/v2_1_0/string.c#L8242 + # https://github.com/hsbt/string-scrub + # https://github.com/rubinius/rubinius/blob/v2.5.2/kernel/common/string.rb#L1913-L1972 + def remove_invalid_bytes(string) + string.scrub(REPLACE) + end + else + # http://stackoverflow.com/a/8711118/879854 + # Loop over chars in a string replacing chars + # with invalid encoding, which is a pretty good proxy + # for the invalid byte sequence that causes an ArgumentError + def remove_invalid_bytes(string) + string.chars.map do |char| + char.valid_encoding? ? char : REPLACE + end.join + end + end + + def detect_source_encoding(string) + string.encoding + end + + def self.pick_encoding(source_a, source_b) + Encoding.compatible?(source_a, source_b) || Encoding.default_external + end + else + + def self.pick_encoding(_source_a, _source_b) + end + + private + + def matching_encoding(string) + string + end + + def detect_source_encoding(_string) + US_ASCII + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/fuzzy_matcher.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/fuzzy_matcher.rb new file mode 100644 index 00000000..46c0cab2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/fuzzy_matcher.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +module RSpec + module Support + # Provides a means to fuzzy-match between two arbitrary objects. + # Understands array/hash nesting. Uses `===` or `==` to + # perform the matching. + module FuzzyMatcher + # @api private + def self.values_match?(expected, actual) + if Hash === actual + return hashes_match?(expected, actual) if Hash === expected + elsif Array === expected && Enumerable === actual && !(Struct === actual) + return arrays_match?(expected, actual.to_a) + end + + return true if expected == actual + + begin + expected === actual + rescue ArgumentError + # Some objects, like 0-arg lambdas on 1.9+, raise + # ArgumentError for `expected === actual`. + false + end + end + + # @private + def self.arrays_match?(expected_list, actual_list) + return false if expected_list.size != actual_list.size + + expected_list.zip(actual_list).all? do |expected, actual| + values_match?(expected, actual) + end + end + + # @private + def self.hashes_match?(expected_hash, actual_hash) + return false if expected_hash.size != actual_hash.size + + expected_hash.all? do |expected_key, expected_value| + actual_value = actual_hash.fetch(expected_key) { return false } + values_match?(expected_value, actual_value) + end + end + + private_class_method :arrays_match?, :hashes_match? + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/hunk_generator.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/hunk_generator.rb new file mode 100644 index 00000000..086a88e6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/hunk_generator.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +require 'diff/lcs' +require 'diff/lcs/hunk' + +module RSpec + module Support + # @private + class HunkGenerator + def initialize(actual, expected) + @actual = actual + @expected = expected + end + + def hunks + @file_length_difference = 0 + @hunks ||= diffs.map do |piece| + build_hunk(piece) + end + end + + private + + def diffs + Diff::LCS.diff(expected_lines, actual_lines) + end + + def expected_lines + @expected.split("\n").map! { |e| e.chomp } + end + + def actual_lines + @actual.split("\n").map! { |e| e.chomp } + end + + def build_hunk(piece) + Diff::LCS::Hunk.new( + expected_lines, actual_lines, piece, context_lines, @file_length_difference + ).tap do |h| + @file_length_difference = h.file_length_difference + end + end + + def context_lines + 3 + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/matcher_definition.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/matcher_definition.rb new file mode 100644 index 00000000..6b7819c4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/matcher_definition.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +module RSpec + module Support + # @private + def self.matcher_definitions + @matcher_definitions ||= [] + end + + # Used internally to break cyclic dependency between mocks, expectations, + # and support. We don't currently have a consistent implementation of our + # matchers, though we are considering changing that: + # https://github.com/rspec/rspec-mocks/issues/513 + # + # @private + def self.register_matcher_definition(&block) + matcher_definitions << block + end + + # Remove a previously registered matcher. Useful for cleaning up after + # yourself in specs. + # + # @private + def self.deregister_matcher_definition(&block) + matcher_definitions.delete(block) + end + + # @private + def self.is_a_matcher?(object) + matcher_definitions.any? { |md| md.call(object) } + end + + # @api private + # + # gives a string representation of an object for use in RSpec descriptions + def self.rspec_description_for_object(object) + if RSpec::Support.is_a_matcher?(object) && object.respond_to?(:description) + object.description + else + object + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/method_signature_verifier.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/method_signature_verifier.rb new file mode 100644 index 00000000..03c700c6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/method_signature_verifier.rb @@ -0,0 +1,442 @@ +# frozen_string_literal: true + +require 'rspec/support' +RSpec::Support.require_rspec_support "ruby_features" +RSpec::Support.require_rspec_support "matcher_definition" + +module RSpec + module Support + # Extracts info about the number of arguments and allowed/required + # keyword args of a given method. + # + # @private + class MethodSignature # rubocop:disable Metrics/ClassLength + attr_reader :min_non_kw_args, :max_non_kw_args, :optional_kw_args, :required_kw_args + + def initialize(method) + @method = method + @optional_kw_args = [] + @required_kw_args = [] + classify_parameters + end + + def non_kw_args_arity_description + case max_non_kw_args + when min_non_kw_args then min_non_kw_args.to_s + when INFINITY then "#{min_non_kw_args} or more" + else "#{min_non_kw_args} to #{max_non_kw_args}" + end + end + + def valid_non_kw_args?(positional_arg_count, optional_max_arg_count=positional_arg_count) + return true if positional_arg_count.nil? + + min_non_kw_args <= positional_arg_count && + optional_max_arg_count <= max_non_kw_args + end + + def classify_arity(arity=@method.arity) + if arity < 0 + # `~` inverts the one's complement and gives us the + # number of required args + @min_non_kw_args = ~arity + @max_non_kw_args = INFINITY + else + @min_non_kw_args = arity + @max_non_kw_args = arity + end + end + + if RubyFeatures.optional_and_splat_args_supported? + def description + @description ||= begin + parts = [] + + unless non_kw_args_arity_description == "0" + parts << "arity of #{non_kw_args_arity_description}" + end + + if @optional_kw_args.any? + parts << "optional keyword args (#{@optional_kw_args.map(&:inspect).join(", ")})" + end + + if @required_kw_args.any? + parts << "required keyword args (#{@required_kw_args.map(&:inspect).join(", ")})" + end + + parts << "any additional keyword args" if @allows_any_kw_args + + parts.join(" and ") + end + end + + def missing_kw_args_from(given_kw_args) + @required_kw_args - given_kw_args + end + + def invalid_kw_args_from(given_kw_args) + return [] if @allows_any_kw_args + given_kw_args - @allowed_kw_args + end + + # If the last argument is Hash, Ruby will treat only symbol keys as keyword arguments + # the rest will be grouped in another Hash and passed as positional argument. + def has_kw_args_in?(args) + Hash === args.last && + could_contain_kw_args?(args) && + (RubyFeatures.kw_arg_separation? || args.last.empty? || args.last.keys.any? { |x| x.is_a?(Symbol) }) + end + + # Without considering what the last arg is, could it + # contain keyword arguments? + def could_contain_kw_args?(args) + return false if args.count <= min_non_kw_args + + @allows_any_kw_args || @allowed_kw_args.any? + end + + def arbitrary_kw_args? + @allows_any_kw_args + end + + def unlimited_args? + @max_non_kw_args == INFINITY + end + + def classify_parameters + optional_non_kw_args = @min_non_kw_args = 0 + @allows_any_kw_args = false + + @method.parameters.each do |(type, name)| + case type + # def foo(a:) + when :keyreq then @required_kw_args << name + # def foo(a: 1) + when :key then @optional_kw_args << name + # def foo(**kw_args) + when :keyrest then @allows_any_kw_args = true + # def foo(a) + when :req then @min_non_kw_args += 1 + # def foo(a = 1) + when :opt then optional_non_kw_args += 1 + # def foo(*a) + when :rest then optional_non_kw_args = INFINITY + end + end + + @max_non_kw_args = @min_non_kw_args + optional_non_kw_args + @allowed_kw_args = @required_kw_args + @optional_kw_args + end + else + def description + "arity of #{non_kw_args_arity_description}" + end + + def missing_kw_args_from(_given_kw_args) + [] + end + + def invalid_kw_args_from(_given_kw_args) + [] + end + + def has_kw_args_in?(_args) + false + end + + def could_contain_kw_args?(*) + false + end + + def arbitrary_kw_args? + false + end + + def unlimited_args? + false + end + + alias_method :classify_parameters, :classify_arity + end + + INFINITY = 1 / 0.0 + end + + if RSpec::Support::Ruby.jruby? + # JRuby has only partial support for UnboundMethod#parameters, so we fall back on using #arity + # https://github.com/jruby/jruby/issues/2816 and https://github.com/jruby/jruby/issues/2817 + if RubyFeatures.optional_and_splat_args_supported? && + Java::JavaLang::String.instance_method(:char_at).parameters == [] + + class MethodSignature < remove_const(:MethodSignature) + private + + def classify_parameters + super + if (arity = @method.arity) != 0 && @method.parameters.empty? + classify_arity(arity) + end + end + end + end + + # JRuby used to always report -1 arity for Java proxy methods. + # The workaround essentially makes use of Java's introspection to figure + # out matching methods (which could be more than one partly because Java + # supports multiple overloads, and partly because JRuby introduces + # aliases to make method names look more Rubyesque). If there is only a + # single match, we can use that methods arity directly instead of the + # default -1 arity. + # + # This workaround only works for Java proxy methods, and in order to + # support regular methods and blocks, we need to be careful about calling + # owner and java_class as they might not be available + if Java::JavaLang::String.instance_method(:char_at).arity == -1 + class MethodSignature < remove_const(:MethodSignature) + private + + def classify_parameters + super + return unless @method.arity == -1 + return unless @method.respond_to?(:owner) + return unless @method.owner.respond_to?(:java_class) + java_instance_methods = @method.owner.java_class.java_instance_methods + compatible_overloads = java_instance_methods.select do |java_method| + @method == @method.owner.instance_method(java_method.name) + end + if compatible_overloads.size == 1 + classify_arity(compatible_overloads.first.arity) + end + end + end + end + end + + # Encapsulates expectations about the number of arguments and + # allowed/required keyword args of a given method. + # + # @api private + class MethodSignatureExpectation + def initialize + @min_count = nil + @max_count = nil + @keywords = [] + + @expect_unlimited_arguments = false + @expect_arbitrary_keywords = false + end + + attr_reader :min_count, :max_count, :keywords + + attr_accessor :expect_unlimited_arguments, :expect_arbitrary_keywords + + def max_count=(number) + raise ArgumentError, 'must be a non-negative integer or nil' \ + unless number.nil? || (number.is_a?(Integer) && number >= 0) + + @max_count = number + end + + def min_count=(number) + raise ArgumentError, 'must be a non-negative integer or nil' \ + unless number.nil? || (number.is_a?(Integer) && number >= 0) + + @min_count = number + end + + def empty? + @min_count.nil? && + @keywords.to_a.empty? && + !@expect_arbitrary_keywords && + !@expect_unlimited_arguments + end + + def keywords=(values) + @keywords = values.to_a || [] + end + end + + # Deals with the slightly different semantics of block arguments. + # For methods, arguments are required unless a default value is provided. + # For blocks, arguments are optional, even if no default value is provided. + # + # However, we want to treat block args as required since you virtually + # always want to pass a value for each received argument and our + # `and_yield` has treated block args as required for many years. + # + # @api private + class BlockSignature < MethodSignature + if RubyFeatures.optional_and_splat_args_supported? + def classify_parameters + super + @min_non_kw_args = @max_non_kw_args unless @max_non_kw_args == INFINITY + end + end + end + + # Abstract base class for signature verifiers. + # + # @api private + class MethodSignatureVerifier + attr_reader :non_kw_args, :kw_args, :min_non_kw_args, :max_non_kw_args + + def initialize(signature, args=[]) + @signature = signature + @non_kw_args, @kw_args = split_args(*args) + @min_non_kw_args = @max_non_kw_args = @non_kw_args + @arbitrary_kw_args = @unlimited_args = false + end + + def with_expectation(expectation) # rubocop:disable Metrics/MethodLength + return self unless MethodSignatureExpectation === expectation + + if expectation.empty? + @min_non_kw_args = @max_non_kw_args = @non_kw_args = nil + @kw_args = [] + else + @min_non_kw_args = @non_kw_args = expectation.min_count || 0 + @max_non_kw_args = expectation.max_count || @min_non_kw_args + + if RubyFeatures.optional_and_splat_args_supported? + @unlimited_args = expectation.expect_unlimited_arguments + else + @unlimited_args = false + end + + if RubyFeatures.kw_args_supported? + @kw_args = expectation.keywords + @arbitrary_kw_args = expectation.expect_arbitrary_keywords + else + @kw_args = [] + @arbitrary_kw_args = false + end + end + + self + end + + def valid? + missing_kw_args.empty? && + invalid_kw_args.empty? && + valid_non_kw_args? && + arbitrary_kw_args? && + unlimited_args? + end + + def error_message + if missing_kw_args.any? + "Missing required keyword arguments: %s" % [ + missing_kw_args.join(", ") + ] + elsif invalid_kw_args.any? + "Invalid keyword arguments provided: %s" % [ + invalid_kw_args.join(", ") + ] + elsif !valid_non_kw_args? + "Wrong number of arguments. Expected %s, got %s." % [ + @signature.non_kw_args_arity_description, + non_kw_args + ] + end + end + + private + + def valid_non_kw_args? + @signature.valid_non_kw_args?(min_non_kw_args, max_non_kw_args) + end + + def missing_kw_args + @signature.missing_kw_args_from(kw_args) + end + + def invalid_kw_args + @signature.invalid_kw_args_from(kw_args) + end + + def arbitrary_kw_args? + !@arbitrary_kw_args || @signature.arbitrary_kw_args? + end + + def unlimited_args? + !@unlimited_args || @signature.unlimited_args? + end + + def split_args(*args) + kw_args = if @signature.has_kw_args_in?(args) && !RubyFeatures.kw_arg_separation? + last = args.pop + non_kw_args = last.reject { |k, _| k.is_a?(Symbol) } + if non_kw_args.empty? + last.keys + else + args << non_kw_args + last.select { |k, _| k.is_a?(Symbol) }.keys + end + elsif @signature.has_kw_args_in?(args) && RubyFeatures.kw_arg_separation? + args.pop.keys + else + [] + end + + [args.length, kw_args] + end + end + + # Figures out whether a given method can accept various arguments. + # Surprisingly non-trivial. + # + # @private + StrictSignatureVerifier = MethodSignatureVerifier + + # Allows matchers to be used instead of providing keyword arguments. In + # practice, when this happens only the arity of the method is verified. + # + # @private + class LooseSignatureVerifier < MethodSignatureVerifier + private + + def split_args(*args) + if RSpec::Support.is_a_matcher?(args.last) && @signature.could_contain_kw_args?(args) + args.pop + @signature = SignatureWithKeywordArgumentsMatcher.new(@signature) + end + + super(*args) + end + + # If a matcher is used in a signature in place of keyword arguments, all + # keyword argument validation needs to be skipped since the matcher is + # opaque. + # + # Instead, keyword arguments will be validated when the method is called + # and they are actually known. + # + # @private + class SignatureWithKeywordArgumentsMatcher + def initialize(signature) + @signature = signature + end + + def missing_kw_args_from(_kw_args) + [] + end + + def invalid_kw_args_from(_kw_args) + [] + end + + def non_kw_args_arity_description + @signature.non_kw_args_arity_description + end + + def valid_non_kw_args?(*args) + @signature.valid_non_kw_args?(*args) + end + + def has_kw_args_in?(args) + @signature.has_kw_args_in?(args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/mutex.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/mutex.rb new file mode 100644 index 00000000..63eeca47 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/mutex.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +module RSpec + module Support + # On 1.8.7, it's in the stdlib. + # We don't want to load the stdlib, b/c this is a test tool, and can affect + # the test environment, causing tests to pass where they should fail. + # + # So we're transcribing/modifying it from + # https://github.com/ruby/ruby/blob/v1_8_7_374/lib/thread.rb#L56 + # Some methods we don't need are deleted. Anything I don't + # understand (there's quite a bit, actually) is left in. + # + # Some formatting changes are made to appease the robot overlord: + # https://travis-ci.org/rspec/rspec-core/jobs/54410874 + # @private + class Mutex + def initialize + @waiting = [] + @locked = false + @waiting.taint + taint + end + + # @private + def lock + while Thread.critical = true && @locked + @waiting.push Thread.current + Thread.stop + end + @locked = true + Thread.critical = false + self + end + + # @private + def unlock + return unless @locked + Thread.critical = true + @locked = false + wakeup_and_run_waiting_thread + self + end + + # @private + def synchronize + lock + begin + yield + ensure + unlock + end + end + + private + + def wakeup_and_run_waiting_thread + begin + t = @waiting.shift + t.wakeup if t + rescue ThreadError + retry + end + Thread.critical = false + begin + t.run if t + rescue ThreadError + :noop + end + end + + # Avoid warnings for library wide checks spec + end unless defined?(::RSpec::Support::Mutex) || defined?(::Mutex) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/object_formatter.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/object_formatter.rb new file mode 100644 index 00000000..d464f1b3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/object_formatter.rb @@ -0,0 +1,279 @@ +# frozen_string_literal: true + +RSpec::Support.require_rspec_support 'matcher_definition' + +module RSpec + module Support + # Provide additional output details beyond what `inspect` provides when + # printing Time, DateTime, or BigDecimal + # @api private + class ObjectFormatter # rubocop:disable Metrics/ClassLength + ELLIPSIS = "..." + + attr_accessor :max_formatted_output_length + + # Methods are deferred to a default instance of the class to maintain the interface + # For example, calling ObjectFormatter.format is still possible + def self.default_instance + @default_instance ||= new + end + + def self.format(object) + default_instance.format(object) + end + + def self.prepare_for_inspection(object) + default_instance.prepare_for_inspection(object) + end + + def initialize(max_formatted_output_length=200) + @max_formatted_output_length = max_formatted_output_length + @current_structure_stack = [] + end + + def format(object) + if max_formatted_output_length.nil? + prepare_for_inspection(object).inspect + else + formatted_object = prepare_for_inspection(object).inspect + if formatted_object.length < max_formatted_output_length + formatted_object + else + beginning = truncate_string formatted_object, 0, max_formatted_output_length / 2 + ending = truncate_string formatted_object, -max_formatted_output_length / 2, -1 + beginning + ELLIPSIS + ending + end + end + end + + # Prepares the provided object to be formatted by wrapping it as needed + # in something that, when `inspect` is called on it, will produce the + # desired output. + # + # This allows us to apply the desired formatting to hash/array data structures + # at any level of nesting, simply by walking that structure and replacing items + # with custom items that have `inspect` defined to return the desired output + # for that item. Then we can just use `Array#inspect` or `Hash#inspect` to + # format the entire thing. + def prepare_for_inspection(object) + case object + when Array + prepare_array(object) + when Hash + prepare_hash(object) + when Symbol + object + else + inspector_class = INSPECTOR_CLASSES.find { |inspector| inspector.can_inspect?(object) } + inspector_class.new(object, self) + end + end + + def prepare_array(array) + with_entering_structure(array) do + array.map { |element| prepare_element(element) } + end + end + + def prepare_hash(input_hash) + with_entering_structure(input_hash) do + sort_hash_keys(input_hash).inject({}) do |output_hash, key_and_value| + key, value = key_and_value.map { |element| prepare_element(element) } + output_hash[key] = value + output_hash + end + end + end + + def sort_hash_keys(input_hash) + if input_hash.keys.all? { |k| k.is_a?(String) || k.is_a?(Symbol) } + Hash[input_hash.sort_by { |k, _v| k.to_s }] + else + input_hash + end + end + + def prepare_element(element) + if recursive_structure?(element) + case element + when Array then InspectableItem.new('[...]') + when Hash then InspectableItem.new('{...}') + else raise # This won't happen + end + else + prepare_for_inspection(element) + end + end + + def with_entering_structure(structure) + @current_structure_stack.push(structure) + return_value = yield + @current_structure_stack.pop + return_value + end + + def recursive_structure?(object) + @current_structure_stack.any? { |seen_structure| seen_structure.equal?(object) } + end + + InspectableItem = Struct.new(:text) do + def inspect + text + end + + def pretty_print(pp) + pp.text(text) + end + end + + BaseInspector = Struct.new(:object, :formatter) do + def self.can_inspect?(_object) + raise NotImplementedError + end + + def inspect + raise NotImplementedError + end + + def pretty_print(pp) + pp.text(inspect) + end + end + + class TimeInspector < BaseInspector + FORMAT = "%Y-%m-%d %H:%M:%S" + + def self.can_inspect?(object) + Time === object + end + + if Time.method_defined?(:nsec) + def inspect + object.strftime("#{FORMAT}.#{"%09d" % object.nsec} %z") + end + else # for 1.8.7 + def inspect + object.strftime("#{FORMAT}.#{"%06d" % object.usec} %z") + end + end + end + + class DateTimeInspector < BaseInspector + FORMAT = "%a, %d %b %Y %H:%M:%S.%N %z" + + def self.can_inspect?(object) + defined?(DateTime) && DateTime === object + end + + # ActiveSupport sometimes overrides inspect. If `ActiveSupport` is + # defined use a custom format string that includes more time precision. + def inspect + if defined?(ActiveSupport) + object.strftime(FORMAT) + else + object.inspect + end + end + end + + class BigDecimalInspector < BaseInspector + def self.can_inspect?(object) + defined?(BigDecimal) && BigDecimal === object + end + + def inspect + "#{object.to_s('F')} (#{object.inspect})" + end + end + + class DescribableMatcherInspector < BaseInspector + def self.can_inspect?(object) + Support.is_a_matcher?(object) && object.respond_to?(:description) + end + + def inspect + object.description + end + end + + class UninspectableObjectInspector < BaseInspector + OBJECT_ID_FORMAT = '%#016x' + + def self.can_inspect?(object) + object.inspect + false + rescue NoMethodError + true + end + + def inspect + "#<#{klass}:#{native_object_id}>" + end + + def klass + Support.class_of(object) + end + + # http://stackoverflow.com/a/2818916 + def native_object_id + OBJECT_ID_FORMAT % (object.__id__ << 1) + rescue NoMethodError + # In Ruby 1.9.2, BasicObject responds to none of #__id__, #object_id, #id... + '-' + end + end + + class DelegatorInspector < BaseInspector + def self.can_inspect?(object) + defined?(Delegator) && Delegator === object + end + + def inspect + "#<#{object.class}(#{formatter.format(object.send(:__getobj__))})>" + end + end + + class InspectableObjectInspector < BaseInspector + def self.can_inspect?(object) + object.inspect + true + rescue NoMethodError + false + end + + def inspect + object.inspect + end + end + + INSPECTOR_CLASSES = [ + TimeInspector, + DateTimeInspector, + BigDecimalInspector, + UninspectableObjectInspector, + DescribableMatcherInspector, + DelegatorInspector, + InspectableObjectInspector + ].tap do |classes| + # 2.4 has improved BigDecimal formatting so we do not need + # to provide our own. + # https://github.com/ruby/bigdecimal/pull/42 + classes.delete(BigDecimalInspector) if RUBY_VERSION >= '2.4' + end + + private + + # Returns the substring defined by the start_index and end_index + # If the string ends with a partial ANSI code code then that + # will be removed as printing partial ANSI + # codes to the terminal can lead to corruption + def truncate_string(str, start_index, end_index) + cut_str = str[start_index..end_index] + + # ANSI color codes are like: \e[33m so anything with \e[ and a + # number without a 'm' is an incomplete color code + cut_str.sub(/\e\[\d+$/, '') + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/recursive_const_methods.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/recursive_const_methods.rb new file mode 100644 index 00000000..ac2910d5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/recursive_const_methods.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true + +module RSpec + module Support + # Provides recursive constant lookup methods useful for + # constant stubbing. + module RecursiveConstMethods + # We only want to consider constants that are defined directly on a + # particular module, and not include top-level/inherited constants. + # Unfortunately, the constant API changed between 1.8 and 1.9, so + # we need to conditionally define methods to ignore the top-level/inherited + # constants. + # + # Given: + # class A; B = 1; end + # class C < A; end + # + # On 1.8: + # - C.const_get("Hash") # => ::Hash + # - C.const_defined?("Hash") # => false + # - C.constants # => ["B"] + # - None of these methods accept the extra `inherit` argument + # On 1.9: + # - C.const_get("Hash") # => ::Hash + # - C.const_defined?("Hash") # => true + # - C.const_get("Hash", false) # => raises NameError + # - C.const_defined?("Hash", false) # => false + # - C.constants # => [:B] + # - C.constants(false) #=> [] + if Module.method(:const_defined?).arity == 1 + def const_defined_on?(mod, const_name) + mod.const_defined?(const_name) + end + + def get_const_defined_on(mod, const_name) + return mod.const_get(const_name) if const_defined_on?(mod, const_name) + + raise NameError, "uninitialized constant #{mod.name}::#{const_name}" + end + + def constants_defined_on(mod) + mod.constants.select { |c| const_defined_on?(mod, c) } + end + else + def const_defined_on?(mod, const_name) + mod.const_defined?(const_name, false) + end + + def get_const_defined_on(mod, const_name) + mod.const_get(const_name, false) + end + + def constants_defined_on(mod) + mod.constants(false) + end + end + + def recursive_const_get(const_name) + normalize_const_name(const_name).split('::').inject(Object) do |mod, name| + get_const_defined_on(mod, name) + end + end + + def recursive_const_defined?(const_name) + parts = normalize_const_name(const_name).split('::') + parts.inject([Object, '']) do |(mod, full_name), name| + yield(full_name, name) if block_given? && !(Module === mod) + return false unless const_defined_on?(mod, name) + [get_const_defined_on(mod, name), [mod.name, name].join('::')] + end + end + + def normalize_const_name(const_name) + const_name.sub(/\A::/, '') + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/reentrant_mutex.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/reentrant_mutex.rb new file mode 100644 index 00000000..28957a2a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/reentrant_mutex.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: true + +module RSpec + module Support + # Allows a thread to lock out other threads from a critical section of code, + # while allowing the thread with the lock to reenter that section. + # + # Based on Monitor as of 2.2 - + # https://github.com/ruby/ruby/blob/eb7ddaa3a47bf48045d26c72eb0f263a53524ebc/lib/monitor.rb#L9 + # + # Depends on Mutex, but Mutex is only available as part of core since 1.9.1: + # exists - http://ruby-doc.org/core-1.9.1/Mutex.html + # dne - http://ruby-doc.org/core-1.9.0/Mutex.html + # + # @private + class ReentrantMutex + def initialize + @owner = nil + @count = 0 + @mutex = Mutex.new + end + + def synchronize + enter + yield + ensure + exit + end + + private + + # This is fixing a bug #501 that is specific to Ruby 3.0. The new implementation + # depends on `owned?` that was introduced in Ruby 2.0, so both should work for Ruby 2.x. + if RUBY_VERSION.to_f >= 3.0 + def enter + @mutex.lock unless @mutex.owned? + @count += 1 + end + + def exit + unless @mutex.owned? + raise ThreadError, "Attempt to unlock a mutex which is locked by another thread/fiber" + end + @count -= 1 + @mutex.unlock if @count == 0 + end + else + def enter + @mutex.lock if @owner != Thread.current + @owner = Thread.current + @count += 1 + end + + def exit + @count -= 1 + return unless @count == 0 + @owner = nil + @mutex.unlock + end + end + end + + if defined? ::Mutex + # On 1.9 and up, this is in core, so we just use the real one + class Mutex < ::Mutex + # If you mock Mutex.new you break our usage of Mutex, so + # instead we capture the original method to return Mutexes. + NEW_MUTEX_METHOD = Mutex.method(:new) + + def self.new + NEW_MUTEX_METHOD.call + end + end + else # For 1.8.7 + # :nocov: + RSpec::Support.require_rspec_support "mutex" + # :nocov: + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/ruby_features.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/ruby_features.rb new file mode 100644 index 00000000..7ccdb7e2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/ruby_features.rb @@ -0,0 +1,221 @@ +# frozen_string_literal: true + +require 'rbconfig' +RSpec::Support.require_rspec_support "comparable_version" + +module RSpec + module Support + # @api private + # + # Provides query methods for different OS or OS features. + module OS + module_function + + def windows? + !!(RbConfig::CONFIG['host_os'] =~ /cygwin|mswin|mingw|bccwin|wince|emx/) + end + + def windows_file_path? + ::File::ALT_SEPARATOR == '\\' + end + end + + # @api private + # + # Provides query methods for different rubies + module Ruby + module_function + + def jruby? + RUBY_PLATFORM == 'java' + end + + def jruby_version + @jruby_version ||= ComparableVersion.new(JRUBY_VERSION) + end + + def jruby_9000? + jruby? && JRUBY_VERSION >= '9.0.0.0' + end + + def rbx? + defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx' + end + + def non_mri? + !mri? + end + + def mri? + !defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby' + end + + def truffleruby? + defined?(RUBY_ENGINE) && RUBY_ENGINE == 'truffleruby' + end + end + + # @api private + # + # Provides query methods for ruby features that differ among + # implementations. + module RubyFeatures + module_function + + if Ruby.jruby? && RUBY_VERSION.to_f < 1.9 + # On JRuby 1.7 `--1.8` mode, `Process.respond_to?(:fork)` returns true, + # but when you try to fork, it raises an error: + # NotImplementedError: fork is not available on this platform + # + # When we drop support for JRuby 1.7 and/or Ruby 1.8, we can drop + # this special case. + def fork_supported? + false + end + else + def fork_supported? + Process.respond_to?(:fork) + end + end + + def optional_and_splat_args_supported? + Method.method_defined?(:parameters) + end + + def caller_locations_supported? + respond_to?(:caller_locations, true) + end + + if Exception.method_defined?(:cause) + def supports_exception_cause? + true + end + else + def supports_exception_cause? + false + end + end + + if RUBY_VERSION.to_f >= 3.2 + def supports_syntax_suggest? + true + end + else + def supports_syntax_suggest? + false + end + end + + if RUBY_VERSION.to_f >= 3.0 + # https://rubyreferences.github.io/rubychanges/3.0.html#keyword-arguments-are-now-fully-separated-from-positional-arguments + def kw_arg_separation? + true + end + else + def kw_arg_separation? + false + end + end + + if RUBY_VERSION.to_f >= 2.7 + def supports_taint? + false + end + else + def supports_taint? + true + end + end + ripper_requirements = [ComparableVersion.new(RUBY_VERSION) >= '1.9.2'] + + ripper_requirements.push(false) if Ruby.rbx? + + if Ruby.jruby? + ripper_requirements.push(Ruby.jruby_version >= '1.7.5') + # Ripper on JRuby 9.0.0.0.rc1 - 9.1.8.0 reports wrong line number + # or cannot parse source including `:if`. + # Ripper on JRuby 9.x.x.x < 9.1.17.0 can't handle keyword arguments + # Neither can JRuby 9.2, e.g. < 9.2.1.0 + ripper_requirements.push(!Ruby.jruby_version.between?('9.0.0.0.rc1', '9.2.0.0')) + end + + # TruffleRuby disables ripper due to low performance + ripper_requirements.push(false) if Ruby.truffleruby? + + if ripper_requirements.all? + def ripper_supported? + true + end + else + def ripper_supported? + false + end + end + + def distincts_kw_args_from_positional_hash? + RUBY_VERSION >= '3.0.0' + end + + if Ruby.mri? + def kw_args_supported? + RUBY_VERSION >= '2.0.0' + end + + def required_kw_args_supported? + RUBY_VERSION >= '2.1.0' + end + + def supports_rebinding_module_methods? + RUBY_VERSION.to_i >= 2 + end + else + # RBX / JRuby et al support is unknown for keyword arguments + begin + eval("o = Object.new; def o.m(a: 1); end;"\ + " raise SyntaxError unless o.method(:m).parameters.include?([:key, :a])") + + def kw_args_supported? + true + end + rescue SyntaxError + def kw_args_supported? + false + end + end + + begin + eval("o = Object.new; def o.m(a: ); end;"\ + "raise SyntaxError unless o.method(:m).parameters.include?([:keyreq, :a])") + + def required_kw_args_supported? + true + end + rescue SyntaxError + def required_kw_args_supported? + false + end + end + + begin + Module.new { def foo; end }.instance_method(:foo).bind(Object.new) + + def supports_rebinding_module_methods? + true + end + rescue TypeError + def supports_rebinding_module_methods? + false + end + end + end + + def module_refinement_supported? + Module.method_defined?(:refine) || Module.private_method_defined?(:refine) + end + + def module_prepends_supported? + Module.method_defined?(:prepend) || Module.private_method_defined?(:prepend) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/source.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/source.rb new file mode 100644 index 00000000..8aad27b2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/source.rb @@ -0,0 +1,87 @@ +# frozen_string_literal: true + +RSpec::Support.require_rspec_support 'encoded_string' +RSpec::Support.require_rspec_support 'ruby_features' + +module RSpec + module Support + # @private + # Represents a Ruby source file and provides access to AST and tokens. + class Source + attr_reader :source, :path + + # This class protects us against having File read and expand_path + # stubbed out within tests. + class File + class << self + [:read, :expand_path].each do |method_name| + define_method(method_name, &::File.method(method_name)) + end + end + end + + def self.from_file(path) + source = File.read(path) + new(source, path) + end + + if String.method_defined?(:encoding) + def initialize(source_string, path=nil) + @source = RSpec::Support::EncodedString.new(source_string, Encoding.default_external) + @path = path ? File.expand_path(path) : '(string)' + end + else # for 1.8.7 + # :nocov: + def initialize(source_string, path=nil) + @source = RSpec::Support::EncodedString.new(source_string) + @path = path ? File.expand_path(path) : '(string)' + end + # :nocov: + end + + def lines + @lines ||= source.split("\n") + end + + def inspect + "#<#{self.class} #{path}>" + end + + if RSpec::Support::RubyFeatures.ripper_supported? + RSpec::Support.require_rspec_support 'source/node' + RSpec::Support.require_rspec_support 'source/token' + + def ast + @ast ||= begin + require 'ripper' + sexp = Ripper.sexp(source) + raise SyntaxError unless sexp + Node.new(sexp) + end + end + + def tokens + @tokens ||= begin + require 'ripper' + tokens = Ripper.lex(source) + Token.tokens_from_ripper_tokens(tokens) + end + end + + def nodes_by_line_number + @nodes_by_line_number ||= begin + nodes_by_line_number = ast.select(&:location).group_by { |node| node.location.line } + Hash.new { |hash, key| hash[key] = [] }.merge(nodes_by_line_number) + end + end + + def tokens_by_line_number + @tokens_by_line_number ||= begin + nodes_by_line_number = tokens.group_by { |token| token.location.line } + Hash.new { |hash, key| hash[key] = [] }.merge(nodes_by_line_number) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/source/location.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/source/location.rb new file mode 100644 index 00000000..fb5a3770 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/source/location.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module RSpec + module Support + class Source + # @private + # Represents a source location of node or token. + Location = Struct.new(:line, :column) do + include Comparable + + def self.location?(array) + array.is_a?(Array) && array.size == 2 && array.all? { |e| e.is_a?(Integer) } + end + + def <=>(other) + line_comparison = (line <=> other.line) + return line_comparison unless line_comparison == 0 + column <=> other.column + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/source/node.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/source/node.rb new file mode 100644 index 00000000..359bf9f8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/source/node.rb @@ -0,0 +1,112 @@ +# frozen_string_literal: true + +RSpec::Support.require_rspec_support 'source/location' + +module RSpec + module Support + class Source + # @private + # A wrapper for Ripper AST node which is generated with `Ripper.sexp`. + class Node + include Enumerable + + attr_reader :sexp, :parent + + def self.sexp?(array) + array.is_a?(Array) && array.first.is_a?(Symbol) + end + + def initialize(ripper_sexp, parent=nil) + @sexp = ripper_sexp.freeze + @parent = parent + end + + def type + sexp[0] + end + + def args + @args ||= raw_args.map do |raw_arg| + if Node.sexp?(raw_arg) + Node.new(raw_arg, self) + elsif Location.location?(raw_arg) + Location.new(*raw_arg) + elsif raw_arg.is_a?(Array) + ExpressionSequenceNode.new(raw_arg, self) + else + raw_arg + end + end.freeze + end + + def children + @children ||= args.select { |arg| arg.is_a?(Node) }.freeze + end + + def location + @location ||= args.find { |arg| arg.is_a?(Location) } + end + + # We use a loop here (instead of recursion) to prevent SystemStackError + def each + return to_enum(__method__) unless block_given? + + node_queue = [] + node_queue << self + + while (current_node = node_queue.shift) + yield current_node + node_queue.concat(current_node.children) + end + end + + def each_ancestor + return to_enum(__method__) unless block_given? + + current_node = self + + while (current_node = current_node.parent) + yield current_node + end + end + + def inspect + "#<#{self.class} #{type}>" + end + + private + + def raw_args + sexp[1..-1] || [] + end + end + + # @private + # Basically `Ripper.sexp` generates arrays whose first element is a symbol (type of sexp), + # but it exceptionally generates typeless arrays for expression sequence: + # + # Ripper.sexp('foo; bar') + # => [ + # :program, + # [ # Typeless array + # [:vcall, [:@ident, "foo", [1, 0]]], + # [:vcall, [:@ident, "bar", [1, 5]]] + # ] + # ] + # + # We wrap typeless arrays in this pseudo type node + # so that it can be handled in the same way as other type node. + class ExpressionSequenceNode < Node + def type + :_expression_sequence + end + + private + + def raw_args + sexp + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/source/token.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/source/token.rb new file mode 100644 index 00000000..ca887a72 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/source/token.rb @@ -0,0 +1,96 @@ +# frozen_string_literal: true + +RSpec::Support.require_rspec_support 'source/location' + +module RSpec + module Support + class Source + # @private + # A wrapper for Ripper token which is generated with `Ripper.lex`. + class Token + CLOSING_TYPES_BY_OPENING_TYPE = { + :on_lbracket => :on_rbracket, + :on_lparen => :on_rparen, + :on_lbrace => :on_rbrace, + :on_heredoc_beg => :on_heredoc_end + }.freeze + + CLOSING_KEYWORDS_BY_OPENING_KEYWORD = { + 'def' => 'end', + 'do' => 'end', + }.freeze + + attr_reader :token + + def self.tokens_from_ripper_tokens(ripper_tokens) + ripper_tokens.map { |ripper_token| new(ripper_token) }.freeze + end + + def initialize(ripper_token) + @token = ripper_token.freeze + end + + def location + @location ||= Location.new(*token[0]) + end + + def type + token[1] + end + + def string + token[2] + end + + def ==(other) + token == other.token + end + + alias_method :eql?, :== + + def inspect + "#<#{self.class} #{type} #{string.inspect}>" + end + + def keyword? + type == :on_kw + end + + def equals_operator? + type == :on_op && string == '=' + end + + def opening? + opening_delimiter? || opening_keyword? + end + + def closed_by?(other) + delimiter_closed_by?(other) || keyword_closed_by?(other) + end + + private + + def opening_delimiter? + CLOSING_TYPES_BY_OPENING_TYPE.key?(type) + end + + def opening_keyword? + return false unless keyword? + CLOSING_KEYWORDS_BY_OPENING_KEYWORD.key?(string) + end + + def delimiter_closed_by?(other) + other.type == CLOSING_TYPES_BY_OPENING_TYPE[type] + end + + def keyword_closed_by?(other) + return false unless keyword? + return true if other.string == CLOSING_KEYWORDS_BY_OPENING_KEYWORD[string] + + # Ruby 3's `end`-less method definition: `def method_name = body` + string == 'def' && other.equals_operator? && location.line == other.location.line + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec.rb new file mode 100644 index 00000000..5468cf99 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: true + +require 'rspec/support' +require 'rspec/support/spec/in_sub_process' + +RSpec::Support.require_rspec_support "spec/deprecation_helpers" +RSpec::Support.require_rspec_support "spec/diff_helpers" +RSpec::Support.require_rspec_support "spec/with_isolated_stderr" +RSpec::Support.require_rspec_support "spec/stderr_splitter" +RSpec::Support.require_rspec_support "spec/formatting_support" +RSpec::Support.require_rspec_support "spec/with_isolated_directory" +RSpec::Support.require_rspec_support "ruby_features" + +warning_preventer = $stderr = RSpec::Support::StdErrSplitter.new($stderr) + +RSpec.configure do |c| + c.include RSpecHelpers + c.include RSpec::Support::WithIsolatedStdErr + c.include RSpec::Support::FormattingSupport + c.include RSpec::Support::InSubProcess + + unless defined?(Debugger) # debugger causes warnings when used + c.before do + warning_preventer.reset! + end + + c.after do + warning_preventer.verify_no_warnings! + end + end + + if c.files_to_run.one? + c.full_backtrace = true + c.default_formatter = 'doc' + end + + c.filter_run_when_matching :focus + + c.example_status_persistence_file_path = "./spec/examples.txt" + + c.define_derived_metadata :failing_on_windows_ci do |meta| + meta[:pending] ||= "This spec fails on Windows CI and needs someone to fix it." + end if RSpec::Support::OS.windows? && ENV['CI'] +end + +module RSpec + module Support + module Spec + def self.setup_simplecov(&block) + # Simplecov emits some ruby warnings when loaded, so silence them. + old_verbose, $VERBOSE = $VERBOSE, false + + return if ENV['NO_COVERAGE'] || RUBY_VERSION < '1.9.3' + return if RUBY_ENGINE != 'ruby' || RSpec::Support::OS.windows? + + # Don't load it when we're running a single isolated + # test file rather than the whole suite. + return if RSpec.configuration.files_to_run.one? + + require 'simplecov' + start_simplecov(&block) + rescue LoadError + warn "Simplecov could not be loaded" + ensure + $VERBOSE = old_verbose + end + + def self.start_simplecov(&block) + SimpleCov.start do + add_filter "bundle/" + add_filter "tmp/" + add_filter do |source_file| + # Filter out `spec` directory except when it is under `lib` + # (as is the case in rspec-support) + source_file.filename.include?('/spec/') && !source_file.filename.include?('/lib/') + end + + instance_eval(&block) if block + end + end + private_class_method :start_simplecov + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/deprecation_helpers.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/deprecation_helpers.rb new file mode 100644 index 00000000..f7458c35 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/deprecation_helpers.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +module RSpecHelpers + def expect_deprecation_with_call_site(file, line, snippet=//) + expect(RSpec.configuration.reporter).to receive(:deprecation). + with(include(:deprecated => match(snippet), :call_site => include([file, line].join(':')))) + end + + def expect_deprecation_without_call_site(snippet=//) + expect(RSpec.configuration.reporter).to receive(:deprecation). + with(include(:deprecated => match(snippet), :call_site => eq(nil))) + end + + def expect_warn_deprecation_with_call_site(file, line, snippet=//) + expect(RSpec.configuration.reporter).to receive(:deprecation). + with(include(:message => match(snippet), :call_site => include([file, line].join(':')))) + end + + def expect_warn_deprecation(snippet=//) + expect(RSpec.configuration.reporter).to receive(:deprecation). + with(include(:message => match(snippet))) + end + + def allow_deprecation + allow(RSpec.configuration.reporter).to receive(:deprecation) + end + + def expect_no_deprecations + expect(RSpec.configuration.reporter).not_to receive(:deprecation) + end + alias expect_no_deprecation expect_no_deprecations + + def expect_warning_without_call_site(expected=//) + expect(::Kernel).to receive(:warn). + with(match(expected).and(satisfy { |message| !(/Called from/ =~ message) })) + end + + def expect_warning_with_call_site(file, line, expected=//) + expect(::Kernel).to receive(:warn). + with(match(expected).and(match(/Called from #{file}:#{line}/))) + end + + def expect_no_warnings + expect(::Kernel).not_to receive(:warn) + end + + def allow_warning + allow(::Kernel).to receive(:warn) + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/diff_helpers.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/diff_helpers.rb new file mode 100644 index 00000000..58e0712f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/diff_helpers.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require 'diff/lcs' + +module RSpec + module Support + module Spec + module DiffHelpers + # In the updated version of diff-lcs several diff headers change format slightly + # compensate for this and change minimum version in RSpec 4 + if ::Diff::LCS::VERSION.to_f < 1.4 + def one_line_header(line_number=2) + "-1,#{line_number} +1,#{line_number}" + end + elsif ::Diff::LCS::VERSION.to_f < 1.6 + def one_line_header(_=2) + "-1 +1" + end + else + def one_line_header(line_number=2) + if line_number - 1 == 1 + "-1 +1" + else + "-1,#{line_number - 1} +1,#{line_number - 1}" + end + end + end + + if ::Diff::LCS::VERSION.to_f > 1.5 + def removing_two_line_header + "-1,2 +0,0" + end + elsif Diff::LCS::VERSION.to_f < 1.4 || Diff::LCS::VERSION >= "1.4.4" + def removing_two_line_header + "-1,3 +1" + end + else + def removing_two_line_header + "-1,3 +1,5" + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/formatting_support.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/formatting_support.rb new file mode 100644 index 00000000..a773a20f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/formatting_support.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module RSpec + module Support + module FormattingSupport + def dedent(string) + string.gsub(/^\s+\|/, '').chomp + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/in_sub_process.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/in_sub_process.rb new file mode 100644 index 00000000..4130225f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/in_sub_process.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +module RSpec + module Support + module InSubProcess + if Process.respond_to?(:fork) && !(Ruby.jruby? && RUBY_VERSION == '1.8.7') + + UnmarshableObject = Struct.new(:error) + + # Useful as a way to isolate a global change to a subprocess. + + def in_sub_process(prevent_warnings=true) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize + exception_reader, exception_writer = IO.pipe + result_reader, result_writer = IO.pipe + + # Set binary mode to avoid errors surrounding ascii-8bit to utf-8 conversion + # this happens with warnings on rspec-rails for example + [exception_reader, exception_writer, result_reader, result_writer].each { |io| io.binmode } + + pid = Process.fork do + warning_preventer = $stderr = RSpec::Support::StdErrSplitter.new($stderr) + + begin + result = yield + warning_preventer.verify_no_warnings! if prevent_warnings + # rubocop:disable Lint/HandleExceptions + rescue Support::AllExceptionsExceptOnesWeMustNotRescue => exception + # rubocop:enable Lint/HandleExceptions + end + + exception_writer.write marshal_dump_with_unmarshable_object_handling(exception) + exception_reader.close + exception_writer.close + + result_writer.write marshal_dump_with_unmarshable_object_handling(result) + result_reader.close + result_writer.close + + exit! # prevent at_exit hooks from running (e.g. minitest) + end + + exception_writer.close + result_writer.close + Process.waitpid(pid) + + exception = Marshal.load(exception_reader.read) + exception_reader.close + raise exception if exception + + result = Marshal.load(result_reader.read) + result_reader.close + result + end + alias :in_sub_process_if_possible :in_sub_process + + def marshal_dump_with_unmarshable_object_handling(object) + Marshal.dump(object) + rescue TypeError => error + Marshal.dump(UnmarshableObject.new(error)) + end + else + def in_sub_process(*) + skip "This spec requires forking to work properly, " \ + "and your platform does not support forking" + end + + def in_sub_process_if_possible(*) + yield + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/library_wide_checks.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/library_wide_checks.rb new file mode 100644 index 00000000..d4245259 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/library_wide_checks.rb @@ -0,0 +1,152 @@ +# frozen_string_literal: true + +require 'rspec/support/spec/shell_out' + +module RSpec + module Support + module WhitespaceChecks + # This malformed whitespace detection logic has been borrowed from bundler: + # https://github.com/bundler/bundler/blob/v1.8.0/spec/quality_spec.rb + def check_for_tab_characters(filename) + failing_lines = [] + File.readlines(filename).each_with_index do |line, number| + failing_lines << number + 1 if line =~ /\t/ + end + + return if failing_lines.empty? + "#{filename} has tab characters on lines #{failing_lines.join(', ')}" + end + + def check_for_extra_spaces(filename) + failing_lines = [] + File.readlines(filename).each_with_index do |line, number| + next if line =~ /^\s+#.*\s+\n$/ + failing_lines << number + 1 if line =~ /\s+\n$/ + end + + return if failing_lines.empty? + "#{filename} has spaces on the EOL on lines #{failing_lines.join(', ')}" + end + end + end +end + +RSpec.shared_examples_for "library wide checks" do |lib, options| + consider_a_test_env_file = options.fetch(:consider_a_test_env_file, /MATCHES NOTHING/) + allowed_loaded_feature_regexps = options.fetch(:allowed_loaded_feature_regexps, []) + preamble_for_lib = options[:preamble_for_lib] + preamble_for_spec = "require 'rspec/core'; require 'spec_helper'" + skip_spec_files = options.fetch(:skip_spec_files, /MATCHES NOTHING/) + + include RSpec::Support::ShellOut + include RSpec::Support::WhitespaceChecks + + define_method :files_to_require_for do |sub_dir| + slash = File::SEPARATOR + lib_path_re = /#{slash + lib}[^#{slash}]*#{slash}lib/ + load_path = $LOAD_PATH.grep(lib_path_re).first + directory = load_path.sub(/lib$/, sub_dir) + files = Dir["#{directory}/**/*.rb"] + extract_regex = /#{Regexp.escape(directory) + File::SEPARATOR}(.+)\.rb$/ + + # We sort to ensure the files are loaded in a consistent order, regardless + # of OS. Otherwise, it could load in a different order on Travis than + # locally, and potentially trigger a "circular require considered harmful" + # warning or similar. + files.sort.map { |file| file[extract_regex, 1] } + end + + def command_from(code_lines) + code_lines.join("\n") + end + + def load_all_files(files, preamble, postamble=nil) + requires = files.map { |f| "require '#{f}'" } + command = command_from(Array(preamble) + requires + Array(postamble)) + + stdout, stderr, status = with_env 'NO_COVERAGE' => '1' do + options = %w[ -w ] + options << "--disable=gem" if RUBY_VERSION.to_f >= 1.9 && RSpec::Support::Ruby.mri? + run_ruby_with_current_load_path(command, *options) + end + + [stdout, strip_known_warnings(stderr), status.exitstatus] + end + + define_method :load_all_lib_files do + files = all_lib_files - lib_test_env_files + preamble = ['orig_loaded_features = $".dup', preamble_for_lib] + postamble = ['puts(($" - orig_loaded_features).join("\n"))'] + + @loaded_feature_lines, stderr, exitstatus = load_all_files(files, preamble, postamble) + ["", stderr, exitstatus] + end + + define_method :load_all_spec_files do + files = files_to_require_for("spec") + lib_test_env_files + files = files.reject { |f| f =~ skip_spec_files } + load_all_files(files, preamble_for_spec) + end + + attr_reader :all_lib_files, :lib_test_env_files, + :lib_file_results, :spec_file_results + + before(:context) do + @all_lib_files = files_to_require_for("lib") + @lib_test_env_files = all_lib_files.grep(consider_a_test_env_file) + + @lib_file_results, @spec_file_results = [ + # Load them in parallel so it's faster... + Thread.new { load_all_lib_files }, + Thread.new { load_all_spec_files } + ].map(&:join).map(&:value) + end + + def have_successful_no_warnings_output + eq ["", "", 0] + end + + it "issues no warnings when loaded", :slow do + expect(lib_file_results).to have_successful_no_warnings_output + end + + it "issues no warnings when the spec files are loaded", :slow do + expect(spec_file_results).to have_successful_no_warnings_output + end + + it 'only loads a known set of stdlibs so gem authors are forced ' \ + 'to load libs they use to have passing specs', :slow do + loaded_features = @loaded_feature_lines.split("\n") + if RUBY_VERSION == '1.8.7' + # On 1.8.7, $" returns the relative require path if that was used + # to require the file. LIB_REGEX will not match the relative version + # since it has a `/lib` prefix. Here we deal with this by expanding + # relative files relative to the $LOAD_PATH dir (lib). + Dir.chdir("lib") { loaded_features.map! { |f| File.expand_path(f) } } + end + + loaded_features.reject! { |feature| RSpec::CallerFilter::LIB_REGEX =~ feature } + loaded_features.reject! { |feature| allowed_loaded_feature_regexps.any? { |r| r =~ feature } } + + expect(loaded_features).to eq([]) + end + + RSpec::Matchers.define :be_well_formed do + match do |actual| + actual.empty? + end + + failure_message do |actual| + actual.join("\n") + end + end + + it "has no malformed whitespace", :slow do + error_messages = [] + `git ls-files -z`.split("\x0").each do |filename| + error_messages << check_for_tab_characters(filename) + error_messages << check_for_extra_spaces(filename) + end + expect(error_messages.compact).to be_well_formed + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/shell_out.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/shell_out.rb new file mode 100644 index 00000000..3727c8a8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/shell_out.rb @@ -0,0 +1,115 @@ +# frozen_string_literal: true + +require 'open3' +require 'rake/file_utils' +require 'shellwords' + +module RSpec + module Support + module ShellOut + def with_env(vars) + original = ENV.to_hash + vars.each { |k, v| ENV[k] = v } + + begin + yield + ensure + ENV.replace(original) + end + end + + if Open3.respond_to?(:capture3) # 1.9+ + def shell_out(*command) + stdout, stderr, status = Open3.capture3(*command) + return stdout, filter(stderr), status + end + else # 1.8.7 + # popen3 doesn't provide the exit status so we fake it out. + FakeProcessStatus = Struct.new(:exitstatus) + + def shell_out(*command) + stdout = stderr = nil + + Open3.popen3(*command) do |_in, out, err| + stdout = out.read + stderr = err.read + end + + status = FakeProcessStatus.new(0) + return stdout, filter(stderr), status + end + end + + def run_ruby_with_current_load_path(ruby_command, *flags) + command = [ + FileUtils::RUBY, + "-I#{$LOAD_PATH.map(&:shellescape).join(File::PATH_SEPARATOR)}", + "-e", ruby_command, *flags + ] + + # Unset these env vars because `ruby -w` will issue warnings whenever + # they are set to non-default values. + with_env 'RUBY_GC_HEAP_FREE_SLOTS' => nil, 'RUBY_GC_MALLOC_LIMIT' => nil, + 'RUBY_FREE_MIN' => nil do + shell_out(*command) + end + end + + LINES_TO_IGNORE = + [ + # Ignore bundler warning. + %r{bundler/source/rubygems}, + # Ignore bundler + rubygems warning. + %r{site_ruby/\d\.\d\.\d/rubygems}, + %r{site_ruby/\d\.\d\.\d/bundler}, + %r{jruby-\d\.\d\.\d+\.\d/lib/ruby/stdlib/rubygems}, + %r{lib/rubygems/custom_require}, + # This is required for windows for some reason + %r{lib/bundler/rubygems}, + # This is a JRuby file that generates warnings on 9.0.3.0 + %r{lib/ruby/stdlib/jar}, + # This is a JRuby file that generates warnings on 9.1.7.0 + %r{org/jruby/RubyKernel\.java}, + # This is a JRuby gem that generates warnings on 9.1.7.0 + %r{ffi-1\.13\.\d+-java}, + %r{uninitialized constant FFI}, + # These are related to the above, there is a warning about io from FFI + %r{jruby-\d\.\d\.\d+\.\d/lib/ruby/stdlib/io}, + %r{io/console on JRuby shells out to stty for most operations}, + # This is a JRuby 9.1.17.0 error on Github Actions + %r{io/console not supported; tty will not be manipulated}, + # This is a JRuby 9.2.1.x error + %r{jruby/kernel/gem_prelude}, + %r{lib/jruby\.jar!/jruby/preludes}, + # Ignore some JRuby errors for gems + %r{jruby/\d\.\d(\.\d)?/gems/aruba}, + %r{jruby/\d\.\d(\.\d)?/gems/ffi}, + %r{warning: encoding options not supported in 1\.8}, + # Ignore errors from asdf + %r{\.asdf/installs}, + ] + + def strip_known_warnings(input) + input.split("\n").reject do |l| + LINES_TO_IGNORE.any? { |to_ignore| l =~ to_ignore } || + # Remove blank lines + l == "" || l.nil? + end.join("\n") + end + + private + + if Ruby.jruby? + def filter(output) + output.each_line.reject do |line| + line.include?("lib/ruby/shared/rubygems") + end.join($/) + end + else + def filter(output) + output + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/stderr_splitter.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/stderr_splitter.rb new file mode 100644 index 00000000..9caa34cd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/stderr_splitter.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +require 'stringio' + +module RSpec + module Support + class StdErrSplitter + def initialize(original) + @orig_stderr = original + @output_tracker = ::StringIO.new + @last_line = nil + end + + respond_to_name = (::RUBY_VERSION.to_f < 1.9) ? :respond_to? : :respond_to_missing? + define_method respond_to_name do |*args| + @orig_stderr.respond_to?(*args) || super(*args) + end + + def method_missing(name, *args, &block) + @output_tracker.__send__(name, *args, &block) if @output_tracker.respond_to?(name) + @orig_stderr.__send__(name, *args, &block) + end + + def ==(other) + @orig_stderr == other + end + + def reopen(*args) + reset! + @orig_stderr.reopen(*args) + end + + # To work around JRuby error: + # can't convert RSpec::Support::StdErrSplitter into String + def to_io + @orig_stderr.to_io + end + + # To work around JRuby error: + # TypeError: $stderr must have write method, RSpec::StdErrSplitter given + def write(line) + return if line =~ %r{^\S+/gems/\S+:\d+: warning:} # http://rubular.com/r/kqeUIZOfPG + + # Ruby 2.7.0 warnings from keyword arguments span multiple lines, extend check above + # to look for the next line. + return if @last_line =~ %r{^\S+/gems/\S+:\d+: warning:} && + line =~ %r{warning: The called method .* is defined here} + + # Ruby 2.7.0 complains about hashes used in place of keyword arguments + # Aruba 0.14.2 uses this internally triggering that here + return if line =~ %r{lib/ruby/2\.7\.0/fileutils\.rb:622: warning:} + + @orig_stderr.write(line) + @output_tracker.write(line) + ensure + @last_line = line + end + + def has_output? + !output.empty? + end + + def reset! + @output_tracker = ::StringIO.new + end + + def verify_no_warnings! + raise "Warnings were generated: #{output}" if has_output? + reset! + end + + def output + @output_tracker.string + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/string_matcher.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/string_matcher.rb new file mode 100644 index 00000000..b8c0c71d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/string_matcher.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +require 'rspec/matchers' +# Special matcher for comparing encoded strings so that +# we don't run any expectation failures through the Differ, +# which also relies on EncodedString. Instead, confirm the +# strings have the same bytes. +RSpec::Matchers.define :be_identical_string do |expected| + if String.method_defined?(:encoding) + match do + expected_encoding? && + actual.bytes.to_a == expected.bytes.to_a + end + + failure_message do + "expected\n#{actual.inspect} (#{actual.encoding.name}) to be identical to\n"\ + "#{expected.inspect} (#{expected.encoding.name})\n"\ + "The exact bytes are printed below for more detail:\n"\ + "#{actual.bytes.to_a}\n"\ + "#{expected.bytes.to_a}\n"\ + end + + # Depends on chaining :with_same_encoding for it to + # check for string encoding. + def expected_encoding? + if defined?(@expect_same_encoding) && @expect_same_encoding + actual.encoding == expected.encoding + else + true + end + end + else + match do + actual.split(//) == expected.split(//) + end + + failure_message do + "expected\n#{actual.inspect} to be identical to\n#{expected.inspect}\n" + end + end + + chain :with_same_encoding do + @expect_same_encoding ||= true + end +end +RSpec::Matchers.alias_matcher :a_string_identical_to, :be_identical_string +RSpec::Matchers.alias_matcher :be_diffed_as, :be_identical_string diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/with_isolated_directory.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/with_isolated_directory.rb new file mode 100644 index 00000000..f81a7dfb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/with_isolated_directory.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require 'tmpdir' + +RSpec.shared_context "isolated directory" do + around do |ex| + Dir.mktmpdir do |tmp_dir| + Dir.chdir(tmp_dir, &ex) + end + end +end + +RSpec.configure do |c| + c.include_context "isolated directory", :isolated_directory => true +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/with_isolated_stderr.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/with_isolated_stderr.rb new file mode 100644 index 00000000..ef62be48 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/spec/with_isolated_stderr.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module RSpec + module Support + module WithIsolatedStdErr + def with_isolated_stderr + original = $stderr + $stderr = StringIO.new + yield + ensure + $stderr = original + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/version.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/version.rb new file mode 100644 index 00000000..1ca0335c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/version.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module RSpec + module Support + module Version + STRING = '3.13.4' + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/warnings.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/warnings.rb new file mode 100644 index 00000000..31783d90 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/warnings.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require 'rspec/support' +RSpec::Support.require_rspec_support "caller_filter" + +module RSpec + module Support + module Warnings + def deprecate(deprecated, options={}) + warn_with "DEPRECATION: #{deprecated} is deprecated.", options + end + + # @private + # + # Used internally to print deprecation warnings + # when rspec-core isn't loaded + def warn_deprecation(message, options={}) + warn_with "DEPRECATION: \n #{message}", options + end + + # @private + # + # Used internally to print warnings + def warning(text, options={}) + warn_with "WARNING: #{text}.", options + end + + # @private + # + # Used internally to print longer warnings + def warn_with(message, options={}) + call_site = options.fetch(:call_site) { CallerFilter.first_non_rspec_line } + message += " Use #{options[:replacement]} instead." if options[:replacement] + message += " Called from #{call_site}." if call_site + Support.warning_notifier.call message + end + end + end + + extend RSpec::Support::Warnings +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/with_keywords_when_needed.rb b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/with_keywords_when_needed.rb new file mode 100644 index 00000000..bec99f40 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rspec-support-3.13.4/lib/rspec/support/with_keywords_when_needed.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +RSpec::Support.require_rspec_support("method_signature_verifier") + +module RSpec + module Support + module WithKeywordsWhenNeeded + # This module adds keyword sensitive support for core ruby methods + # where we cannot use `ruby2_keywords` directly. + + module_function + + if RSpec::Support::RubyFeatures.kw_args_supported? + # Remove this in RSpec 4 in favour of explicitly passed in kwargs where + # this is used. Works around a warning in Ruby 2.7 + + def class_exec(klass, *args, &block) + if MethodSignature.new(block).has_kw_args_in?(args) + binding.eval(<<-CODE, __FILE__, __LINE__) + kwargs = args.pop + klass.class_exec(*args, **kwargs, &block) + CODE + else + klass.class_exec(*args, &block) + end + end + ruby2_keywords :class_exec if respond_to?(:ruby2_keywords, true) + else + def class_exec(klass, *args, &block) + klass.class_exec(*args, &block) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/LICENSE.txt b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/LICENSE.txt new file mode 100644 index 00000000..314ec16a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2012-25 Bozhidar Batsov + +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 AUTHORS OR COPYRIGHT HOLDERS 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. diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/README.md b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/README.md new file mode 100644 index 00000000..3b7471c6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/README.md @@ -0,0 +1,257 @@ +

+ RuboCop Logo +

+ +---------- +[![Ruby Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](https://github.com/rubocop/rubocop) +[![Gem Version](https://badge.fury.io/rb/rubocop.svg)](https://badge.fury.io/rb/rubocop) +[![CI](https://github.com/rubocop/rubocop/actions/workflows/rubocop.yml/badge.svg)](https://github.com/rubocop/rubocop/actions/workflows/rubocop.yml) +[![Test Coverage](https://api.codeclimate.com/v1/badges/d2d67f728e88ea84ac69/test_coverage)](https://codeclimate.com/github/rubocop/rubocop/test_coverage) +[![Maintainability](https://api.codeclimate.com/v1/badges/d2d67f728e88ea84ac69/maintainability)](https://codeclimate.com/github/rubocop/rubocop/maintainability) +[![Discord](https://img.shields.io/badge/chat-on%20discord-7289da.svg?sanitize=true)](https://discord.gg/wJjWvGRDmm) + +> Role models are important.
+> -- Officer Alex J. Murphy / RoboCop + +**RuboCop** is a Ruby static code analyzer (a.k.a. `linter`) and code formatter. Out of the box it +will enforce many of the guidelines outlined in the community [Ruby Style +Guide](https://rubystyle.guide). Apart from reporting the problems discovered in your code, +RuboCop can also automatically fix many of them for you. + +RuboCop is extremely flexible and most aspects of its behavior can be tweaked via various +[configuration options](https://github.com/rubocop/rubocop/blob/master/config/default.yml). + +---------- +[![Patreon](https://img.shields.io/badge/patreon-donate-orange.svg)](https://www.patreon.com/bbatsov) +[![OpenCollective](https://opencollective.com/rubocop/backers/badge.svg)](#open-collective-for-individuals) +[![OpenCollective](https://opencollective.com/rubocop/sponsors/badge.svg)](#open-collective-for-organizations) +[![Tidelift](https://tidelift.com/badges/package/rubygems/rubocop)](https://tidelift.com/subscription/pkg/rubygems-rubocop?utm_source=rubygems-rubocop&utm_medium=referral&utm_campaign=readme) + +Working on RuboCop is often fun, but it also requires a great deal of time and energy. + +**Please consider [financially supporting its ongoing development](#funding).** + +## Installation + +**RuboCop**'s installation is pretty standard: + +```sh +gem install rubocop +``` + +If you'd rather install RuboCop using `bundler`, add a line for it in your +`Gemfile` (but set the `require` option to `false`, as it is a standalone tool): + +```rb +gem 'rubocop', require: false +``` + +RuboCop is stable between minor versions, both in terms of API and cop configuration. +We aim to ease the maintenance of RuboCop extensions and the upgrades between RuboCop +releases. All big changes are reserved for major releases. +To prevent an unwanted RuboCop update you might want to use a conservative version lock +in your `Gemfile`: + +```rb +gem 'rubocop', '~> 1.76', require: false +``` + +See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details. + +## Quickstart + +Just type `rubocop` in a Ruby project's folder and watch the magic happen. + +```sh +cd my/cool/ruby/project +rubocop +``` + +> [!TIP] +> +> You can also use this magic in your favorite editor with RuboCop's +> [built-in LSP server](https://docs.rubocop.org/rubocop/usage/lsp.html). + +## Documentation + +You can read a lot more about RuboCop in its [official docs](https://docs.rubocop.org). + +## Compatibility + +RuboCop officially supports the following runtime Ruby implementations: + +* MRI 2.7+ +* JRuby 9.4+ + +It targets Ruby 2.0+ for code analysis. + +See the [compatibility documentation](https://docs.rubocop.org/rubocop/compatibility.html) for further details. + +## Readme Badge + +If you use RuboCop in your project, you can include one of these badges in your readme to let people know that your code is written following the community Ruby Style Guide. + +[![Ruby Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](https://github.com/rubocop/rubocop) + +[![Ruby Style Guide](https://img.shields.io/badge/code_style-community-brightgreen.svg)](https://rubystyle.guide) + +Here are the Markdown snippets for the two badges: + +``` markdown +[![Ruby Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](https://github.com/rubocop/rubocop) + +[![Ruby Style Guide](https://img.shields.io/badge/code_style-community-brightgreen.svg)](https://rubystyle.guide) +``` + +## Team + +Here's a list of RuboCop's core developers: + +* [Bozhidar Batsov](https://github.com/bbatsov) (author & head maintainer) +* [Jonas Arvidsson](https://github.com/jonas054) +* [Yuji Nakayama](https://github.com/yujinakayama) (retired) +* [Evgeni Dzhelyov](https://github.com/edzhelyov) (retired) +* [Ted Johansson](https://github.com/drenmi) +* [Masataka Kuwabara](https://github.com/pocke) +* [Koichi Ito](https://github.com/koic) +* [Maxim Krizhanovski](https://github.com/darhazer) +* [Benjamin Quorning](https://github.com/bquorning) +* [Marc-André Lafortune](https://github.com/marcandre) +* [Daniel Vandersluis](https://github.com/dvandersluis) + +See the [team page](https://docs.rubocop.org/rubocop/about/team.html) for more details. + +## Logo + +RuboCop's logo was created by [Dimiter Petrov](https://www.chadomoto.com/). You can find the logo in various +formats [here](https://github.com/rubocop/rubocop/tree/master/logo). + +The logo is licensed under a +[Creative Commons Attribution-NonCommercial 4.0 International License](https://creativecommons.org/licenses/by-nc/4.0/deed.en_GB). + +## Contributors + +Here's a [list](https://github.com/rubocop/rubocop/graphs/contributors) of +all the people who have contributed to the development of RuboCop. + +I'm extremely grateful to each and every one of them! + +If you'd like to contribute to RuboCop, please take the time to go +through our short +[contribution guidelines](CONTRIBUTING.md). + +Converting more of the Ruby Style Guide into RuboCop cops is our top +priority right now. Writing a new cop is a great way to dive into RuboCop! + +Of course, bug reports and suggestions for improvements are always +welcome. GitHub pull requests are even better! :-) + +## Funding + +While RuboCop is free software and will always be, the project would benefit immensely from some funding. +Raising a monthly budget of a couple of thousand dollars would make it possible to pay people to work on +certain complex features, fund other development related stuff (e.g. hardware, conference trips) and so on. +Raising a monthly budget of over $5000 would open the possibility of someone working full-time on the project +which would speed up the pace of development significantly. + +We welcome both individual and corporate sponsors! We also offer a +wide array of funding channels to account for your preferences +(although +currently [Open Collective](https://opencollective.com/rubocop) is our +preferred funding platform). + +**If you're working in a company that's making significant use of RuboCop we'd +appreciate it if you suggest to your company to become a RuboCop sponsor.** + +You can support the development of RuboCop via +[GitHub Sponsors](https://github.com/sponsors/bbatsov), +[Patreon](https://www.patreon.com/bbatsov), +[PayPal](https://paypal.me/bbatsov), +[Open Collective](https://opencollective.com/rubocop) +and [Tidelift](https://tidelift.com/subscription/pkg/rubygems-rubocop?utm_source=rubygems-rubocop&utm_medium=referral&utm_campaign=readme) +. + +> [!NOTE] +> +> If doing a sponsorship in the form of donation is problematic for your company +> from an accounting standpoint, we'd recommend the use of Tidelift, where you +> can get a support-like subscription instead. + +### Open Collective for Individuals + +Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/rubocop#backer)] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +### Open Collective for Organizations + +Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor](https://opencollective.com/rubocop#sponsor)] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +## Release Notes + +RuboCop's release notes are available [here](https://github.com/rubocop/rubocop/releases). + +## Copyright + +Copyright (c) 2012-2025 Bozhidar Batsov. See [LICENSE.txt](LICENSE.txt) for +further details. diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/assets/logo.png b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/assets/logo.png new file mode 100644 index 00000000..c091ad7f Binary files /dev/null and b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/assets/logo.png differ diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/assets/output.css.erb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/assets/output.css.erb new file mode 100644 index 00000000..71e12cc2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/assets/output.css.erb @@ -0,0 +1,159 @@ +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +body, html { + font-size: 62.5%; +} +body { + background-color: #ecedf0; + font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; + margin: 0; +} +code { + font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; + font-size: 85%; +} +#header { + background: #f9f9f9; + color: #333; + border-bottom: 3px solid #ccc; + height: 50px; + padding: 0; +} +#header .logo { + float: left; + margin: 5px 12px 7px 20px; + width: 38px; + height: 38px; +} +#header .title { + display: inline-block; + float: left; + height: 50px; + font-size: 2.4rem; + letter-spacing: normal; + line-height: 50px; + margin: 0; +} + +.information, #offenses { + width: 100%; + padding: 20px; + color: #333; +} +#offenses { + padding: 0 20px; +} + +.information .infobox { + border-left: 3px solid; + border-radius: 4px; + background-color: #fff; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); + padding: 15px; + border-color: #0088cc; + font-size: 1.4rem; +} +.information .infobox .info-title { + font-size: 1.8rem; + line-height: 2.2rem; + margin: 0 0 0.5em; +} +.information .offenses-list li { + line-height: 1.8rem +} +.information .offenses-list { + padding-left: 20px; + margin-bottom: 0; +} + +#offenses .offense-box { + border-radius: 4px; + margin-bottom: 20px; + background-color: #fff; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); +} +.fixed .box-title { + position: fixed; + top: 0; + z-index: 10; + width: 100%; +} +.box-title-placeholder { + display: none; +} +.fixed .box-title-placeholder { + display: block; +} +#offenses .offense-box .box-title h3, #offenses .offense-box .box-title-placeholder h3 { + color: #33353f; + background-color: #f6f6f6; + font-size: 2rem; + line-height: 2rem; + display: block; + padding: 15px; + border-radius: 5px; + margin: 0; +} +#offenses .offense-box .offense-reports { + padding: 0 15px; +} +#offenses .offense-box .offense-reports .report { + border-bottom: 1px dotted #ddd; + padding: 15px 0px; + position: relative; + font-size: 1.3rem; +} +#offenses .offense-box .offense-reports .report:last-child { + border-bottom: none; +} +#offenses .offense-box .offense-reports .report pre code { + display: block; + background: #000; + color: #fff; + padding: 10px 15px; + border-radius: 5px; + line-height: 1.6rem; +} +#offenses .offense-box .offense-reports .report .location { + font-weight: bold; +} +#offenses .offense-box .offense-reports .report .message code { + padding: 0.3em; + background-color: rgba(0,0,0,0.07); + border-radius: 3px; +} +.severity { + text-transform: capitalize; + font-weight: bold; +} +.highlight { + padding: 2px; + border-radius: 2px; + font-weight: bold; +} +<%- SEVERITY_COLORS.each do |severity, color| %> +.severity.<%= severity %> { + color: <%= color %>; +} +.highlight.<%= severity %> { + background-color: <%= color.fade_out(0.4) %>; + border: 1px solid <%= color.fade_out(0.6) %>; +} +<%- end %> +footer { + margin-bottom: 20px; + margin-right: 20px; + font-size: 1.3rem; + color: #777; + text-align: right; +} +.extra-code { + color: #ED9C28 +} + diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/assets/output.html.erb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/assets/output.html.erb new file mode 100644 index 00000000..02d0c783 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/assets/output.html.erb @@ -0,0 +1,102 @@ + + + + + RuboCop Inspection Report + + + + + +
+
+
+ <%= pluralize(files.count, 'file') %> inspected, + <%= pluralize(summary.offense_count, 'offense', no_for_zero: true) %> detected: +
+ +
+
+
+ <% files.each do |file| %> + <% if file.offenses.any? %> +
+

 

+

<%= relative_path(file.path) %> - <%= pluralize(file.offenses.count, 'offense') %>

+
+ <% file.offenses.each do |offense| %> +
+
+ Line #<%= offense.location.line %> – + <%= offense.severity %>: + <%= decorated_message(offense) %> +
+ <% unless offense.location.source_line.strip.empty? %> +
<%= highlighted_source_line(offense) %>
+ <% end %> +
+ <% end %> +
+
+ <% end %> + <% end %> +
+
+ Generated by RuboCop + <%= RuboCop::Version::STRING %> +
+ + diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/config/default.yml b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/config/default.yml new file mode 100644 index 00000000..68a22a83 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/config/default.yml @@ -0,0 +1,6033 @@ +# Common configuration. + +AllCops: + RubyInterpreters: + - ruby + - macruby + - rake + - jruby + - rbx + # Include common Ruby source files. + Include: + - '**/*.rb' + - '**/*.arb' + - '**/*.axlsx' + - '**/*.builder' + - '**/*.fcgi' + - '**/*.gemfile' + - '**/*.gemspec' + - '**/*.god' + - '**/*.jb' + - '**/*.jbuilder' + - '**/*.mspec' + - '**/*.opal' + - '**/*.pluginspec' + - '**/*.podspec' + - '**/*.rabl' + - '**/*.rake' + - '**/*.rbuild' + - '**/*.rbw' + - '**/*.rbx' + - '**/*.ru' + - '**/*.ruby' + - '**/*.schema' + - '**/*.spec' + - '**/*.thor' + - '**/*.watchr' + - '**/.irbrc' + - '**/.pryrc' + - '**/.simplecov' + - '**/buildfile' + - '**/Appraisals' + - '**/Berksfile' + - '**/Brewfile' + - '**/Buildfile' + - '**/Capfile' + - '**/Cheffile' + - '**/Dangerfile' + - '**/Deliverfile' + - '**/Fastfile' + - '**/*Fastfile' + - '**/Gemfile' + - '**/Guardfile' + - '**/Jarfile' + - '**/Mavenfile' + - '**/Podfile' + - '**/Puppetfile' + - '**/Rakefile' + - '**/rakefile' + - '**/Schemafile' + - '**/Snapfile' + - '**/Steepfile' + - '**/Thorfile' + - '**/Vagabondfile' + - '**/Vagrantfile' + Exclude: + - 'node_modules/**/*' + - 'tmp/**/*' + - 'vendor/**/*' + - '.git/**/*' + # Default formatter will be used if no `-f/--format` option is given. + DefaultFormatter: progress + # Cop names are displayed in offense messages by default. Change behavior + # by overriding DisplayCopNames, or by giving the `--no-display-cop-names` + # option. + DisplayCopNames: true + # Style guide URLs are not displayed in offense messages by default. Change + # behavior by overriding `DisplayStyleGuide`, or by giving the + # `-S/--display-style-guide` option. + DisplayStyleGuide: false + # When specifying style guide URLs, any paths and/or fragments will be + # evaluated relative to the base URL. + StyleGuideBaseURL: https://rubystyle.guide + # Documentation URLs will be constructed using the base URL. + DocumentationBaseURL: https://docs.rubocop.org/rubocop + # Documentation URLs will end with this extension. + DocumentationExtension: .html + # Extra details are not displayed in offense messages by default. Change + # behavior by overriding ExtraDetails, or by giving the + # `-E/--extra-details` option. + ExtraDetails: false + # Additional cops that do not reference a style guide rule may be enabled by + # default. Change behavior by overriding `StyleGuideCopsOnly`, or by giving + # the `--only-guide-cops` option. + StyleGuideCopsOnly: false + # All cops except the ones configured `Enabled: false` in this file are enabled by default. + # Change this behavior by overriding either `DisabledByDefault` or `EnabledByDefault`. + # When `DisabledByDefault` is `true`, all cops in the default configuration + # are disabled, and only cops in user configuration are enabled. This makes + # cops opt-in instead of opt-out. Note that when `DisabledByDefault` is `true`, + # cops in user configuration will be enabled even if they don't set the + # Enabled parameter. + # When `EnabledByDefault` is `true`, all cops, even those configured `Enabled: false` + # in this file are enabled by default. Cops can still be disabled in user configuration. + # Note that it is invalid to set both EnabledByDefault and DisabledByDefault + # to true in the same configuration. + EnabledByDefault: false + DisabledByDefault: false + # New cops introduced between major versions are set to a special pending status + # and are not enabled by default with warning message. + # Change this behavior by overriding either `NewCops: enable` or `NewCops: disable`. + # When `NewCops` is `enable`, pending cops are enabled in bulk. Can be overridden by + # the `--enable-pending-cops` command-line option. + # When `NewCops` is `disable`, pending cops are disabled in bulk. Can be overridden by + # the `--disable-pending-cops` command-line option. + NewCops: pending + # Enables the result cache if `true`. Can be overridden by the `--cache` command + # line option. + UseCache: true + # Threshold for how many files can be stored in the result cache before some + # of the files are automatically removed. + MaxFilesInCache: 20000 + # The cache will be stored in "rubocop_cache" under this directory. If + # CacheRootDirectory is ~ (nil), which it is by default, the root will be + # taken from the environment variable `$XDG_CACHE_HOME` if it is set, or if + # `$XDG_CACHE_HOME` is not set, it will be `$HOME/.cache/`. + # The CacheRootDirectory can be overwritten by passing the `--cache-root` command + # line option or by setting `$RUBOCOP_CACHE_ROOT` environment variable. + CacheRootDirectory: ~ + # It is possible for a malicious user to know the location of RuboCop's cache + # directory by looking at CacheRootDirectory, and create a symlink in its + # place that could cause RuboCop to overwrite unintended files, or read + # malicious input. If you are certain that your cache location is secure from + # this kind of attack, and wish to use a symlinked cache location, set this + # value to "true". + AllowSymlinksInCacheRootDirectory: false + # What MRI version of the Ruby interpreter is the inspected code intended to + # run on? (If there is more than one, set this to the lowest version.) + # If a value is specified for TargetRubyVersion then it is used. Acceptable + # values are specified as a float (i.e. 3.0); the teeny version of Ruby + # should not be included. If the project specifies a Ruby version in the + # .tool-versions or .ruby-version files, Gemfile or gems.rb file, RuboCop will + # try to determine the desired version of Ruby by inspecting the + # .tool-versions file first, then .ruby-version, followed by the Gemfile.lock + # or gems.locked file. (Although the Ruby version is specified in the Gemfile + # or gems.rb file, RuboCop reads the final value from the lock file.) If the + # Ruby version is still unresolved, RuboCop will use the oldest officially + # supported Ruby version (currently Ruby 2.7). + TargetRubyVersion: ~ + # RuboCop choses the parser engine automatically but you can also specify it yourself. + # These options are available: + # - `default` + # - `parser_whitequark` ... https://github.com/whitequark/parser + # - `parser_prism` ... https://github.com/ruby/prism (`Prism::Translation::Parser`) + # Not every parser engine can handle every `TargetRubyVersion`. `parser_whitequark` + # only works with versions 3.4 and below, `parser_prism` with versions 3.3 and above. + ParserEngine: default + # Determines if a notification for extension libraries should be shown when + # rubocop is run. Keys are the name of the extension, and values are an array + # of gems in the Gemfile that the extension is suggested for, if not already + # included. + SuggestExtensions: + rubocop-rails: [rails] + rubocop-rspec: [rspec, rspec-rails] + rubocop-minitest: [minitest] + rubocop-sequel: [sequel] + rubocop-rake: [rake] + rubocop-graphql: [graphql] + rubocop-capybara: [capybara] + rubocop-factory_bot: [factory_bot, factory_bot_rails] + rubocop-rspec_rails: [rspec-rails] + # Enable/Disable checking the methods extended by Active Support. + ActiveSupportExtensionsEnabled: false + # Future version of Ruby will freeze string literals by default. + # This allows to opt in early, for example when enabled through RUBYOPT. + # For now this will behave as if set to false but in future ruby versions + # (likely 4.0) it will be true by default. + StringLiteralsFrozenByDefault: ~ + +#################### Bundler ############################### + +Bundler/DuplicatedGem: + Description: 'Checks for duplicate gem entries in Gemfile.' + Enabled: true + Severity: warning + VersionAdded: '0.46' + VersionChanged: '1.40' + Include: + - '**/*.gemfile' + - '**/Gemfile' + - '**/gems.rb' + +Bundler/DuplicatedGroup: + Description: 'Checks for duplicate group entries in Gemfile.' + Enabled: true + Severity: warning + VersionAdded: '1.56' + Include: + - '**/*.gemfile' + - '**/Gemfile' + - '**/gems.rb' + +Bundler/GemComment: + Description: 'Add a comment describing each gem.' + Enabled: false + VersionAdded: '0.59' + VersionChanged: '0.85' + Include: + - '**/*.gemfile' + - '**/Gemfile' + - '**/gems.rb' + IgnoredGems: [] + OnlyFor: [] + +Bundler/GemFilename: + Description: 'Enforces the filename for managing gems.' + Enabled: true + VersionAdded: '1.20' + EnforcedStyle: 'Gemfile' + SupportedStyles: + - 'Gemfile' + - 'gems.rb' + Include: + - '**/Gemfile' + - '**/gems.rb' + - '**/Gemfile.lock' + - '**/gems.locked' + +Bundler/GemVersion: + Description: 'Requires or forbids specifying gem versions.' + Enabled: false + VersionAdded: '1.14' + EnforcedStyle: 'required' + SupportedStyles: + - 'required' + - 'forbidden' + Include: + - '**/*.gemfile' + - '**/Gemfile' + - '**/gems.rb' + AllowedGems: [] + +Bundler/InsecureProtocolSource: + Description: >- + The source `:gemcutter`, `:rubygems` and `:rubyforge` are deprecated + because HTTP requests are insecure. Please change your source to + 'https://rubygems.org' if possible, or 'http://rubygems.org' if not. + Enabled: true + Severity: warning + VersionAdded: '0.50' + VersionChanged: '1.40' + AllowHttpProtocol: true + Include: + - '**/*.gemfile' + - '**/Gemfile' + - '**/gems.rb' + +Bundler/OrderedGems: + Description: >- + Gems within groups in the Gemfile should be alphabetically sorted. + Enabled: true + VersionAdded: '0.46' + VersionChanged: '0.47' + TreatCommentsAsGroupSeparators: true + # By default, "-" and "_" are ignored for order purposes. + # This can be overridden by setting this parameter to true. + ConsiderPunctuation: false + Include: + - '**/*.gemfile' + - '**/Gemfile' + - '**/gems.rb' + +#################### Gemspec ############################### + +Gemspec/AddRuntimeDependency: + Description: 'Prefer `add_dependency` over `add_runtime_dependency`.' + StyleGuide: '#add_dependency_vs_add_runtime_dependency' + References: + - https://github.com/rubygems/rubygems/issues/7799#issuecomment-2192720316 + Enabled: pending + VersionAdded: '1.65' + Include: + - '**/*.gemspec' + +Gemspec/DependencyVersion: + Description: 'Requires or forbids specifying gem dependency versions.' + Enabled: false + VersionAdded: '1.29' + EnforcedStyle: 'required' + SupportedStyles: + - 'required' + - 'forbidden' + Include: + - '**/*.gemspec' + AllowedGems: [] + +Gemspec/DeprecatedAttributeAssignment: + Description: Checks that deprecated attribute assignments are not set in a gemspec file. + Enabled: pending + Severity: warning + VersionAdded: '1.30' + VersionChanged: '1.40' + Include: + - '**/*.gemspec' + +Gemspec/DevelopmentDependencies: + Description: Checks that development dependencies are specified in Gemfile rather than gemspec. + Enabled: pending + VersionAdded: '1.44' + EnforcedStyle: Gemfile + SupportedStyles: + - Gemfile + - gems.rb + - gemspec + AllowedGems: [] + Include: + - '**/*.gemspec' + - '**/Gemfile' + - '**/gems.rb' + +Gemspec/DuplicatedAssignment: + Description: 'An attribute assignment method calls should be listed only once in a gemspec.' + Enabled: true + Severity: warning + VersionAdded: '0.52' + VersionChanged: '1.40' + Include: + - '**/*.gemspec' + +Gemspec/OrderedDependencies: + Description: >- + Dependencies in the gemspec should be alphabetically sorted. + Enabled: true + VersionAdded: '0.51' + TreatCommentsAsGroupSeparators: true + # By default, "-" and "_" are ignored for order purposes. + # This can be overridden by setting this parameter to true. + ConsiderPunctuation: false + Include: + - '**/*.gemspec' + +Gemspec/RequireMFA: + Description: 'Checks that the gemspec has metadata to require Multi-Factor Authentication from RubyGems.' + Enabled: pending + Severity: warning + VersionAdded: '1.23' + VersionChanged: '1.40' + References: + - https://guides.rubygems.org/mfa-requirement-opt-in/ + Include: + - '**/*.gemspec' + +Gemspec/RequiredRubyVersion: + Description: 'Checks that `required_ruby_version` of gemspec is specified and equal to `TargetRubyVersion` of .rubocop.yml.' + Enabled: true + Severity: warning + VersionAdded: '0.52' + VersionChanged: '1.40' + Include: + - '**/*.gemspec' + +Gemspec/RubyVersionGlobalsUsage: + Description: Checks usage of RUBY_VERSION in gemspec. + StyleGuide: '#no-ruby-version-in-the-gemspec' + Enabled: true + Severity: warning + VersionAdded: '0.72' + VersionChanged: '1.40' + Include: + - '**/*.gemspec' + +#################### Layout ########################### + +Layout/AccessModifierIndentation: + Description: Check indentation of private/protected visibility modifiers. + StyleGuide: '#indent-public-private-protected' + Enabled: true + VersionAdded: '0.49' + EnforcedStyle: indent + SupportedStyles: + - outdent + - indent + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + IndentationWidth: ~ + +Layout/ArgumentAlignment: + Description: >- + Align the arguments of a method call if they span more + than one line. + StyleGuide: '#no-double-indent' + Enabled: true + VersionAdded: '0.68' + VersionChanged: '0.77' + # Alignment of arguments in multi-line method calls. + # + # The `with_first_argument` style aligns the following lines along the same + # column as the first parameter. + # + # method_call(a, + # b) + # + # The `with_fixed_indentation` style aligns the following lines with one + # level of indentation relative to the start of the line with the method call. + # + # method_call(a, + # b) + EnforcedStyle: with_first_argument + SupportedStyles: + - with_first_argument + - with_fixed_indentation + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + IndentationWidth: ~ + +Layout/ArrayAlignment: + Description: >- + Align the elements of an array literal if they span more than + one line. + StyleGuide: '#no-double-indent' + Enabled: true + VersionAdded: '0.49' + VersionChanged: '0.77' + # Alignment of elements of a multi-line array. + # + # The `with_first_parameter` style aligns the following lines along the same + # column as the first element. + # + # array = [1, 2, 3, + # 4, 5, 6] + # + # The `with_fixed_indentation` style aligns the following lines with one + # level of indentation relative to the start of the line with start of array. + # + # array = [1, 2, 3, + # 4, 5, 6] + EnforcedStyle: with_first_element + SupportedStyles: + - with_first_element + - with_fixed_indentation + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + IndentationWidth: ~ + +Layout/AssignmentIndentation: + Description: >- + Checks the indentation of the first line of the + right-hand-side of a multi-line assignment. + Enabled: true + VersionAdded: '0.49' + VersionChanged: '1.45' + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + IndentationWidth: ~ + +Layout/BeginEndAlignment: + Description: 'Align ends corresponding to begins correctly.' + Enabled: true + VersionAdded: '0.91' + # The value `start_of_line` means that `end` should be aligned the start of the line + # where the `begin` keyword is. + # The value `begin` means that `end` should be aligned with the `begin` keyword. + EnforcedStyleAlignWith: start_of_line + SupportedStylesAlignWith: + - start_of_line + - begin + Severity: warning + +Layout/BlockAlignment: + Description: 'Align block ends correctly.' + Enabled: true + VersionAdded: '0.53' + # The value `start_of_block` means that the `end` should be aligned with line + # where the `do` keyword appears. + # The value `start_of_line` means it should be aligned with the whole + # expression's starting line. + # The value `either` means both are allowed. + EnforcedStyleAlignWith: either + SupportedStylesAlignWith: + - either + - start_of_block + - start_of_line + +Layout/BlockEndNewline: + Description: 'Put end statement of multiline block on its own line.' + Enabled: true + VersionAdded: '0.49' + +Layout/CaseIndentation: + Description: 'Indentation of when in a case/(when|in)/[else/]end.' + StyleGuide: '#indent-when-to-case' + Enabled: true + VersionAdded: '0.49' + VersionChanged: '1.16' + EnforcedStyle: case + SupportedStyles: + - case + - end + IndentOneStep: false + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + # This only matters if `IndentOneStep` is `true`. + IndentationWidth: ~ + +Layout/ClassStructure: + Description: 'Enforces a configured order of definitions within a class body.' + StyleGuide: '#consistent-classes' + Enabled: false + SafeAutoCorrect: false + VersionAdded: '0.52' + VersionChanged: '1.53' + Categories: + module_inclusion: + - include + - prepend + - extend + ExpectedOrder: + - module_inclusion + - constants + - public_class_methods + - initializer + - public_methods + - protected_methods + - private_methods + +Layout/ClosingHeredocIndentation: + Description: 'Checks the indentation of here document closings.' + Enabled: true + VersionAdded: '0.57' + +Layout/ClosingParenthesisIndentation: + Description: 'Checks the indentation of hanging closing parentheses.' + Enabled: true + VersionAdded: '0.49' + +Layout/CommentIndentation: + Description: 'Indentation of comments.' + Enabled: true + # When true, allows comments to have extra indentation if that aligns them + # with a comment on the preceding line. + AllowForAlignment: false + VersionAdded: '0.49' + VersionChanged: '1.24' + +Layout/ConditionPosition: + Description: >- + Checks for condition placed in a confusing position relative to + the keyword. + StyleGuide: '#same-line-condition' + Enabled: true + VersionAdded: '0.53' + VersionChanged: '0.83' + +Layout/DefEndAlignment: + Description: 'Align ends corresponding to defs correctly.' + Enabled: true + VersionAdded: '0.53' + # The value `def` means that `end` should be aligned with the def keyword. + # The value `start_of_line` means that `end` should be aligned with method + # calls like `private`, `public`, etc, if present in front of the `def` + # keyword on the same line. + EnforcedStyleAlignWith: start_of_line + SupportedStylesAlignWith: + - start_of_line + - def + Severity: warning + +Layout/DotPosition: + Description: 'Checks the position of the dot in multi-line method calls.' + StyleGuide: '#consistent-multi-line-chains' + Enabled: true + VersionAdded: '0.49' + EnforcedStyle: leading + SupportedStyles: + - leading + - trailing + +Layout/ElseAlignment: + Description: 'Align elses and elsifs correctly.' + Enabled: true + VersionAdded: '0.49' + +Layout/EmptyComment: + Description: 'Checks empty comment.' + Enabled: true + AutoCorrect: contextual + VersionAdded: '0.53' + VersionChanged: '1.61' + AllowBorderComment: true + AllowMarginComment: true + +Layout/EmptyLineAfterGuardClause: + Description: 'Add empty line after guard clause.' + Enabled: true + VersionAdded: '0.56' + VersionChanged: '0.59' + +Layout/EmptyLineAfterMagicComment: + Description: 'Add an empty line after magic comments to separate them from code.' + StyleGuide: '#separate-magic-comments-from-code' + Enabled: true + VersionAdded: '0.49' + +Layout/EmptyLineAfterMultilineCondition: + Description: 'Enforces empty line after multiline condition.' + # This is disabled, because this style is not very common in practice. + Enabled: false + VersionAdded: '0.90' + References: + - https://github.com/airbnb/ruby#multiline-if-newline + +Layout/EmptyLineBetweenDefs: + Description: 'Use empty lines between class/module/method defs.' + StyleGuide: '#empty-lines-between-methods' + Enabled: true + VersionAdded: '0.49' + VersionChanged: '1.23' + EmptyLineBetweenMethodDefs: true + EmptyLineBetweenClassDefs: true + EmptyLineBetweenModuleDefs: true + # `DefLikeMacros` takes the name of any macro that you want to treat like a def. + DefLikeMacros: [] + # `AllowAdjacentOneLineDefs` means that single line method definitions don't + # need an empty line between them. `true` by default. + AllowAdjacentOneLineDefs: true + # Can be array to specify minimum and maximum number of empty lines, e.g. [1, 2] + NumberOfEmptyLines: 1 + +Layout/EmptyLines: + Description: "Don't use several empty lines in a row." + StyleGuide: '#two-or-more-empty-lines' + Enabled: true + VersionAdded: '0.49' + +Layout/EmptyLinesAroundAccessModifier: + Description: "Keep blank lines around access modifiers." + StyleGuide: '#empty-lines-around-access-modifier' + Enabled: true + VersionAdded: '0.49' + EnforcedStyle: around + SupportedStyles: + - around + - only_before + References: + # A reference to `EnforcedStyle: only_before`. + - https://edgeguides.rubyonrails.org/contributing_to_ruby_on_rails.html#follow-the-coding-conventions + +Layout/EmptyLinesAroundArguments: + Description: "Keeps track of empty lines around method arguments." + Enabled: true + VersionAdded: '0.52' + +Layout/EmptyLinesAroundAttributeAccessor: + Description: "Keep blank lines around attribute accessors." + StyleGuide: '#empty-lines-around-attribute-accessor' + Enabled: true + VersionAdded: '0.83' + VersionChanged: '0.84' + AllowAliasSyntax: true + AllowedMethods: + - alias_method + - public + - protected + - private + +Layout/EmptyLinesAroundBeginBody: + Description: "Keeps track of empty lines around begin-end bodies." + StyleGuide: '#empty-lines-around-bodies' + Enabled: true + VersionAdded: '0.49' + +Layout/EmptyLinesAroundBlockBody: + Description: "Keeps track of empty lines around block bodies." + StyleGuide: '#empty-lines-around-bodies' + Enabled: true + VersionAdded: '0.49' + EnforcedStyle: no_empty_lines + SupportedStyles: + - empty_lines + - no_empty_lines + +Layout/EmptyLinesAroundClassBody: + Description: "Keeps track of empty lines around class bodies." + StyleGuide: '#empty-lines-around-bodies' + Enabled: true + VersionAdded: '0.49' + VersionChanged: '0.53' + EnforcedStyle: no_empty_lines + SupportedStyles: + - empty_lines + - empty_lines_except_namespace + - empty_lines_special + - no_empty_lines + - beginning_only + - ending_only + +Layout/EmptyLinesAroundExceptionHandlingKeywords: + Description: "Keeps track of empty lines around exception handling keywords." + StyleGuide: '#empty-lines-around-bodies' + Enabled: true + VersionAdded: '0.49' + +Layout/EmptyLinesAroundMethodBody: + Description: "Keeps track of empty lines around method bodies." + StyleGuide: '#empty-lines-around-bodies' + Enabled: true + VersionAdded: '0.49' + +Layout/EmptyLinesAroundModuleBody: + Description: "Keeps track of empty lines around module bodies." + StyleGuide: '#empty-lines-around-bodies' + Enabled: true + VersionAdded: '0.49' + EnforcedStyle: no_empty_lines + SupportedStyles: + - empty_lines + - empty_lines_except_namespace + - empty_lines_special + - no_empty_lines + +Layout/EndAlignment: + Description: 'Align ends correctly.' + Enabled: true + VersionAdded: '0.53' + # The value `keyword` means that `end` should be aligned with the matching + # keyword (`if`, `while`, etc.). + # The value `variable` means that in assignments, `end` should be aligned + # with the start of the variable on the left hand side of `=`. In all other + # situations, `end` should still be aligned with the keyword. + # The value `start_of_line` means that `end` should be aligned with the start + # of the line which the matching keyword appears on. + EnforcedStyleAlignWith: keyword + SupportedStylesAlignWith: + - keyword + - variable + - start_of_line + Severity: warning + +Layout/EndOfLine: + Description: 'Use Unix-style line endings.' + StyleGuide: '#crlf' + Enabled: true + VersionAdded: '0.49' + # The `native` style means that CR+LF (Carriage Return + Line Feed) is + # enforced on Windows, and LF is enforced on other platforms. The other styles + # mean LF and CR+LF, respectively. + EnforcedStyle: native + SupportedStyles: + - native + - lf + - crlf + +Layout/ExtraSpacing: + Description: 'Do not use unnecessary spacing.' + Enabled: true + VersionAdded: '0.49' + # When true, allows most uses of extra spacing if the intent is to align + # things with the previous or next line, not counting empty lines or comment + # lines. + AllowForAlignment: true + # When true, allows things like 'obj.meth(arg) # comment', + # rather than insisting on 'obj.meth(arg) # comment'. + # If done for alignment, either this OR AllowForAlignment will allow it. + AllowBeforeTrailingComments: false + # When true, forces the alignment of `=` in assignments on consecutive lines. + ForceEqualSignAlignment: false + +Layout/FirstArgumentIndentation: + Description: 'Checks the indentation of the first argument in a method call.' + Enabled: true + VersionAdded: '0.68' + VersionChanged: '0.77' + EnforcedStyle: special_for_inner_method_call_in_parentheses + SupportedStyles: + # The first parameter should always be indented one step more than the + # preceding line. + - consistent + # The first parameter should always be indented one level relative to the + # parent that is receiving the parameter + - consistent_relative_to_receiver + # The first parameter should normally be indented one step more than the + # preceding line, but if it's a parameter for a method call that is itself + # a parameter in a method call, then the inner parameter should be indented + # relative to the inner method. + - special_for_inner_method_call + # Same as `special_for_inner_method_call` except that the special rule only + # applies if the outer method call encloses its arguments in parentheses. + - special_for_inner_method_call_in_parentheses + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + IndentationWidth: ~ + +Layout/FirstArrayElementIndentation: + Description: >- + Checks the indentation of the first element in an array + literal. + Enabled: true + VersionAdded: '0.68' + VersionChanged: '0.77' + # The value `special_inside_parentheses` means that array literals with + # brackets that have their opening bracket on the same line as a surrounding + # opening round parenthesis, shall have their first element indented relative + # to the first position inside the parenthesis. + # + # The value `consistent` means that the indentation of the first element shall + # always be relative to the first position of the line where the opening + # bracket is. + # + # The value `align_brackets` means that the indentation of the first element + # shall always be relative to the position of the opening bracket. + EnforcedStyle: special_inside_parentheses + SupportedStyles: + - special_inside_parentheses + - consistent + - align_brackets + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + IndentationWidth: ~ + +Layout/FirstArrayElementLineBreak: + Description: >- + Checks for a line break before the first element in a + multi-line array. + Enabled: false + VersionAdded: '0.49' + AllowMultilineFinalElement: false + +Layout/FirstHashElementIndentation: + Description: 'Checks the indentation of the first key in a hash literal.' + Enabled: true + VersionAdded: '0.68' + VersionChanged: '0.77' + # The value `special_inside_parentheses` means that hash literals with braces + # that have their opening brace on the same line as a surrounding opening + # round parenthesis, shall have their first key indented relative to the + # first position inside the parenthesis. + # + # The value `consistent` means that the indentation of the first key shall + # always be relative to the first position of the line where the opening + # brace is. + # + # The value `align_braces` means that the indentation of the first key shall + # always be relative to the position of the opening brace. + EnforcedStyle: special_inside_parentheses + SupportedStyles: + - special_inside_parentheses + - consistent + - align_braces + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + IndentationWidth: ~ + +Layout/FirstHashElementLineBreak: + Description: >- + Checks for a line break before the first element in a + multi-line hash. + Enabled: false + VersionAdded: '0.49' + AllowMultilineFinalElement: false + +Layout/FirstMethodArgumentLineBreak: + Description: >- + Checks for a line break before the first argument in a + multi-line method call. + Enabled: false + VersionAdded: '0.49' + AllowMultilineFinalElement: false + AllowedMethods: [] + +Layout/FirstMethodParameterLineBreak: + Description: >- + Checks for a line break before the first parameter in a + multi-line method parameter definition. + Enabled: false + VersionAdded: '0.49' + AllowMultilineFinalElement: false + +Layout/FirstParameterIndentation: + Description: >- + Checks the indentation of the first parameter in a + method definition. + Enabled: true + VersionAdded: '0.49' + VersionChanged: '0.77' + EnforcedStyle: consistent + SupportedStyles: + - consistent + - align_parentheses + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + IndentationWidth: ~ + +Layout/HashAlignment: + Description: >- + Align the elements of a hash literal if they span more than + one line. + Enabled: true + AllowMultipleStyles: true + VersionAdded: '0.49' + VersionChanged: '1.16' + # Alignment of entries using hash rocket as separator. Valid values are: + # + # key - left alignment of keys + # 'a' => 2 + # 'bb' => 3 + # separator - alignment of hash rockets, keys are right aligned + # 'a' => 2 + # 'bb' => 3 + # table - left alignment of keys, hash rockets, and values + # 'a' => 2 + # 'bb' => 3 + EnforcedHashRocketStyle: key + SupportedHashRocketStyles: + - key + - separator + - table + # Alignment of entries using colon as separator. Valid values are: + # + # key - left alignment of keys + # a: 0 + # bb: 1 + # separator - alignment of colons, keys are right aligned + # a: 0 + # bb: 1 + # table - left alignment of keys and values + # a: 0 + # bb: 1 + EnforcedColonStyle: key + SupportedColonStyles: + - key + - separator + - table + # Select whether hashes that are the last argument in a method call should be + # inspected? Valid values are: + # + # always_inspect - Inspect both implicit and explicit hashes. + # Registers an offense for: + # function(a: 1, + # b: 2) + # Registers an offense for: + # function({a: 1, + # b: 2}) + # always_ignore - Ignore both implicit and explicit hashes. + # Accepts: + # function(a: 1, + # b: 2) + # Accepts: + # function({a: 1, + # b: 2}) + # ignore_implicit - Ignore only implicit hashes. + # Accepts: + # function(a: 1, + # b: 2) + # Registers an offense for: + # function({a: 1, + # b: 2}) + # ignore_explicit - Ignore only explicit hashes. + # Accepts: + # function({a: 1, + # b: 2}) + # Registers an offense for: + # function(a: 1, + # b: 2) + EnforcedLastArgumentHashStyle: always_inspect + SupportedLastArgumentHashStyles: + - always_inspect + - always_ignore + - ignore_implicit + - ignore_explicit + +Layout/HeredocArgumentClosingParenthesis: + Description: >- + Checks for the placement of the closing parenthesis in a + method call that passes a HEREDOC string as an argument. + Enabled: false + StyleGuide: '#heredoc-argument-closing-parentheses' + VersionAdded: '0.68' + +Layout/HeredocIndentation: + Description: 'Checks the indentation of the here document bodies.' + StyleGuide: '#squiggly-heredocs' + Enabled: true + VersionAdded: '0.49' + VersionChanged: '0.85' + +Layout/IndentationConsistency: + Description: 'Keep indentation straight.' + StyleGuide: '#spaces-indentation' + Enabled: true + VersionAdded: '0.49' + # The difference between `indented` and `normal` is that the `indented_internal_methods` + # style prescribes that in classes and modules the `protected` and `private` + # modifier keywords shall be indented the same as public methods and that + # protected and private members shall be indented one step more than the + # modifiers. Other than that, both styles mean that entities on the same + # logical depth shall have the same indentation. + EnforcedStyle: normal + SupportedStyles: + - normal + - indented_internal_methods + References: + # A reference to `EnforcedStyle: indented_internal_methods`. + - https://edgeguides.rubyonrails.org/contributing_to_ruby_on_rails.html#follow-the-coding-conventions + +Layout/IndentationStyle: + Description: 'Consistent indentation either with tabs only or spaces only.' + StyleGuide: '#spaces-indentation' + Enabled: true + VersionAdded: '0.49' + VersionChanged: '0.82' + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + # It is used during autocorrection to determine how many spaces should + # replace each tab. + IndentationWidth: ~ + EnforcedStyle: spaces + SupportedStyles: + - spaces + - tabs + +Layout/IndentationWidth: + Description: 'Use 2 spaces for indentation.' + StyleGuide: '#spaces-indentation' + Enabled: true + VersionAdded: '0.49' + # Number of spaces for each indentation level. + Width: 2 + AllowedPatterns: [] + +Layout/InitialIndentation: + Description: >- + Checks the indentation of the first non-blank non-comment line in a file. + Enabled: true + VersionAdded: '0.49' + +Layout/LeadingCommentSpace: + Description: 'Comments should start with a space.' + StyleGuide: '#hash-space' + Enabled: true + VersionAdded: '0.49' + VersionChanged: '0.73' + AllowDoxygenCommentStyle: false + AllowGemfileRubyComment: false + AllowRBSInlineAnnotation: false + AllowSteepAnnotation: false + +Layout/LeadingEmptyLines: + Description: Check for unnecessary blank lines at the beginning of a file. + Enabled: true + VersionAdded: '0.57' + VersionChanged: '0.77' + +Layout/LineContinuationLeadingSpace: + Description: >- + Use trailing spaces instead of leading spaces in strings + broken over multiple lines (by a backslash). + Enabled: pending + VersionAdded: '1.31' + VersionChanged: '1.45' + EnforcedStyle: trailing + SupportedStyles: + - leading + - trailing + +Layout/LineContinuationSpacing: + Description: 'Checks the spacing in front of backslash in line continuations.' + Enabled: pending + VersionAdded: '1.31' + EnforcedStyle: space + SupportedStyles: + - space + - no_space + +Layout/LineEndStringConcatenationIndentation: + Description: >- + Checks the indentation of the next line after a line that + ends with a string literal and a backslash. + Enabled: pending + VersionAdded: '1.18' + EnforcedStyle: aligned + SupportedStyles: + - aligned + - indented + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + IndentationWidth: ~ + +Layout/LineLength: + Description: 'Checks that line length does not exceed the configured limit.' + StyleGuide: '#max-line-length' + Enabled: true + VersionAdded: '0.25' + VersionChanged: '1.69' + Max: 120 + AllowHeredoc: true + # To make it possible to copy or click on URIs in the code, we allow lines + # containing a URI to be longer than Max. + AllowURI: true + URISchemes: + - http + - https + # The IgnoreCopDirectives option causes the LineLength rule to ignore cop + # directives like '# rubocop: enable ...' when calculating a line's length. + IgnoreCopDirectives: true + # The AllowedPatterns option is a list of !ruby/regexp and/or string + # elements. Strings will be converted to Regexp objects. A line that matches + # any regular expression listed in this option will be ignored by LineLength. + AllowedPatterns: [] + # If SplitStrings is true, long strings will be split using continuations + SplitStrings: false + +Layout/MultilineArrayBraceLayout: + Description: >- + Checks that the closing brace in an array literal is + either on the same line as the last array element, or + a new line. + Enabled: true + VersionAdded: '0.49' + EnforcedStyle: symmetrical + SupportedStyles: + # symmetrical: closing brace is positioned in same way as opening brace + # new_line: closing brace is always on a new line + # same_line: closing brace is always on the same line as last element + - symmetrical + - new_line + - same_line + +Layout/MultilineArrayLineBreaks: + Description: >- + Checks that each item in a multi-line array literal + starts on a separate line. + Enabled: false + VersionAdded: '0.67' + AllowMultilineFinalElement: false + +Layout/MultilineAssignmentLayout: + Description: 'Check for a newline after the assignment operator in multi-line assignments.' + StyleGuide: '#indent-conditional-assignment' + Enabled: false + VersionAdded: '0.49' + # The types of assignments which are subject to this rule. + SupportedTypes: + - block + - case + - class + - if + - kwbegin + - module + EnforcedStyle: new_line + SupportedStyles: + # Ensures that the assignment operator and the rhs are on the same line for + # the set of supported types. + - same_line + # Ensures that the assignment operator and the rhs are on separate lines + # for the set of supported types. + - new_line + +Layout/MultilineBlockLayout: + Description: 'Ensures newlines after multiline block do statements.' + Enabled: true + VersionAdded: '0.49' + +Layout/MultilineHashBraceLayout: + Description: >- + Checks that the closing brace in a hash literal is + either on the same line as the last hash element, or + a new line. + Enabled: true + VersionAdded: '0.49' + EnforcedStyle: symmetrical + SupportedStyles: + # symmetrical: closing brace is positioned in same way as opening brace + # new_line: closing brace is always on a new line + # same_line: closing brace is always on same line as last element + - symmetrical + - new_line + - same_line + +Layout/MultilineHashKeyLineBreaks: + Description: >- + Checks that each item in a multi-line hash literal + starts on a separate line. + Enabled: false + VersionAdded: '0.67' + AllowMultilineFinalElement: false + +Layout/MultilineMethodArgumentLineBreaks: + Description: >- + Checks that each argument in a multi-line method call + starts on a separate line. + Enabled: false + VersionAdded: '0.67' + AllowMultilineFinalElement: false + +Layout/MultilineMethodCallBraceLayout: + Description: >- + Checks that the closing brace in a method call is + either on the same line as the last method argument, or + a new line. + Enabled: true + VersionAdded: '0.49' + EnforcedStyle: symmetrical + SupportedStyles: + # symmetrical: closing brace is positioned in same way as opening brace + # new_line: closing brace is always on a new line + # same_line: closing brace is always on the same line as last argument + - symmetrical + - new_line + - same_line + +Layout/MultilineMethodCallIndentation: + Description: >- + Checks indentation of method calls with the dot operator + that span more than one line. + Enabled: true + VersionAdded: '0.49' + EnforcedStyle: aligned + SupportedStyles: + - aligned + - indented + - indented_relative_to_receiver + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + IndentationWidth: ~ + +Layout/MultilineMethodDefinitionBraceLayout: + Description: >- + Checks that the closing brace in a method definition is + either on the same line as the last method parameter, or + a new line. + Enabled: true + VersionAdded: '0.49' + EnforcedStyle: symmetrical + SupportedStyles: + # symmetrical: closing brace is positioned in same way as opening brace + # new_line: closing brace is always on a new line + # same_line: closing brace is always on the same line as last parameter + - symmetrical + - new_line + - same_line + +Layout/MultilineMethodParameterLineBreaks: + Description: >- + Checks that each parameter in a multi-line method definition + starts on a separate line. + Enabled: false + VersionAdded: '1.32' + AllowMultilineFinalElement: false + +Layout/MultilineOperationIndentation: + Description: >- + Checks indentation of binary operations that span more than + one line. + Enabled: true + VersionAdded: '0.49' + EnforcedStyle: aligned + SupportedStyles: + - aligned + - indented + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + IndentationWidth: ~ + +Layout/ParameterAlignment: + Description: >- + Align the parameters of a method definition if they span more + than one line. + StyleGuide: '#no-double-indent' + Enabled: true + VersionAdded: '0.49' + VersionChanged: '0.77' + # Alignment of parameters in multi-line method calls. + # + # The `with_first_parameter` style aligns the following lines along the same + # column as the first parameter. + # + # def method_foo(a, + # b) + # + # The `with_fixed_indentation` style aligns the following lines with one + # level of indentation relative to the start of the line with the method call. + # + # def method_foo(a, + # b) + EnforcedStyle: with_first_parameter + SupportedStyles: + - with_first_parameter + - with_fixed_indentation + # By default the indentation width from `Layout/IndentationWidth` is used, + # but it can be overridden by setting this parameter. + IndentationWidth: ~ + +Layout/RedundantLineBreak: + Description: >- + Do not break up an expression into multiple lines when it fits + on a single line. + Enabled: false + InspectBlocks: false + VersionAdded: '1.13' + +Layout/RescueEnsureAlignment: + Description: 'Align rescues and ensures correctly.' + Enabled: true + VersionAdded: '0.49' + +Layout/SingleLineBlockChain: + Description: 'Put method call on a separate line if chained to a single line block.' + Enabled: false + VersionAdded: '1.14' + +Layout/SpaceAfterColon: + Description: 'Use spaces after colons.' + StyleGuide: '#spaces-operators' + Enabled: true + VersionAdded: '0.49' + +Layout/SpaceAfterComma: + Description: 'Use spaces after commas.' + StyleGuide: '#spaces-operators' + Enabled: true + VersionAdded: '0.49' + +Layout/SpaceAfterMethodName: + Description: >- + Do not put a space between a method name and the opening + parenthesis in a method definition. + StyleGuide: '#parens-no-spaces' + Enabled: true + VersionAdded: '0.49' + +Layout/SpaceAfterNot: + Description: Tracks redundant space after the ! operator. + StyleGuide: '#no-space-bang' + Enabled: true + VersionAdded: '0.49' + +Layout/SpaceAfterSemicolon: + Description: 'Use spaces after semicolons.' + StyleGuide: '#spaces-operators' + Enabled: true + VersionAdded: '0.49' + +Layout/SpaceAroundBlockParameters: + Description: 'Checks the spacing inside and after block parameters pipes.' + Enabled: true + VersionAdded: '0.49' + EnforcedStyleInsidePipes: no_space + SupportedStylesInsidePipes: + - space + - no_space + +Layout/SpaceAroundEqualsInParameterDefault: + Description: >- + Checks that the equals signs in parameter default assignments + have or don't have surrounding space depending on + configuration. + StyleGuide: '#spaces-around-equals' + Enabled: true + VersionAdded: '0.49' + EnforcedStyle: space + SupportedStyles: + - space + - no_space + +Layout/SpaceAroundKeyword: + Description: 'Use a space around keywords if appropriate.' + Enabled: true + VersionAdded: '0.49' + +Layout/SpaceAroundMethodCallOperator: + Description: 'Checks method call operators to not have spaces around them.' + Enabled: true + VersionAdded: '0.82' + +Layout/SpaceAroundOperators: + Description: 'Use a single space around operators.' + StyleGuide: '#spaces-operators' + Enabled: true + VersionAdded: '0.49' + # When `true`, allows most uses of extra spacing if the intent is to align + # with an operator on the previous or next line, not counting empty lines + # or comment lines. + AllowForAlignment: true + EnforcedStyleForExponentOperator: no_space + SupportedStylesForExponentOperator: + - space + - no_space + EnforcedStyleForRationalLiterals: no_space + SupportedStylesForRationalLiterals: + - space + - no_space + +Layout/SpaceBeforeBlockBraces: + Description: >- + Checks that the left block brace has or doesn't have space + before it. + Enabled: true + VersionAdded: '0.49' + EnforcedStyle: space + SupportedStyles: + - space + - no_space + EnforcedStyleForEmptyBraces: space + SupportedStylesForEmptyBraces: + - space + - no_space + VersionChanged: '0.52' + +Layout/SpaceBeforeBrackets: + Description: 'Checks for receiver with a space before the opening brackets.' + StyleGuide: '#space-in-brackets-access' + Enabled: pending + VersionAdded: '1.7' + +Layout/SpaceBeforeComma: + Description: 'No spaces before commas.' + Enabled: true + VersionAdded: '0.49' + +Layout/SpaceBeforeComment: + Description: >- + Checks for missing space between code and a comment on the + same line. + Enabled: true + VersionAdded: '0.49' + +Layout/SpaceBeforeFirstArg: + Description: >- + Checks that exactly one space is used between a method name + and the first argument for method calls without parentheses. + Enabled: true + VersionAdded: '0.49' + # When `true`, allows most uses of extra spacing if the intent is to align + # things with the previous or next line, not counting empty lines or comment + # lines. + AllowForAlignment: true + +Layout/SpaceBeforeSemicolon: + Description: 'No spaces before semicolons.' + Enabled: true + VersionAdded: '0.49' + +Layout/SpaceInLambdaLiteral: + Description: 'Checks for spaces in lambda literals.' + Enabled: true + VersionAdded: '0.49' + EnforcedStyle: require_no_space + SupportedStyles: + - require_no_space + - require_space + +Layout/SpaceInsideArrayLiteralBrackets: + Description: 'Checks the spacing inside array literal brackets.' + Enabled: true + VersionAdded: '0.52' + EnforcedStyle: no_space + SupportedStyles: + - space + - no_space + # 'compact' normally requires a space inside the brackets, with the exception + # that successive left brackets or right brackets are collapsed together + - compact + EnforcedStyleForEmptyBrackets: no_space + SupportedStylesForEmptyBrackets: + - space + - no_space + +Layout/SpaceInsideArrayPercentLiteral: + Description: 'No unnecessary additional spaces between elements in %i/%w literals.' + Enabled: true + VersionAdded: '0.49' + +Layout/SpaceInsideBlockBraces: + Description: >- + Checks that block braces have or don't have surrounding space. + For blocks taking parameters, checks that the left brace has + or doesn't have trailing space. + Enabled: true + VersionAdded: '0.49' + EnforcedStyle: space + SupportedStyles: + - space + - no_space + EnforcedStyleForEmptyBraces: no_space + SupportedStylesForEmptyBraces: + - space + - no_space + # Space between `{` and `|`. Overrides `EnforcedStyle` if there is a conflict. + SpaceBeforeBlockParameters: true + +Layout/SpaceInsideHashLiteralBraces: + Description: "Use spaces inside hash literal braces - or don't." + StyleGuide: '#spaces-braces' + Enabled: true + VersionAdded: '0.49' + EnforcedStyle: space + SupportedStyles: + - space + - no_space + # 'compact' normally requires a space inside hash braces, with the exception + # that successive left braces or right braces are collapsed together + - compact + EnforcedStyleForEmptyBraces: no_space + SupportedStylesForEmptyBraces: + - space + - no_space + +Layout/SpaceInsideParens: + Description: 'No spaces after ( or before ).' + StyleGuide: '#spaces-braces' + Enabled: true + VersionAdded: '0.49' + VersionChanged: '1.22' + EnforcedStyle: no_space + SupportedStyles: + - space + - compact + - no_space + +Layout/SpaceInsidePercentLiteralDelimiters: + Description: 'No unnecessary spaces inside delimiters of %i/%w/%x literals.' + Enabled: true + VersionAdded: '0.49' + +Layout/SpaceInsideRangeLiteral: + Description: 'No spaces inside range literals.' + StyleGuide: '#no-space-inside-range-literals' + Enabled: true + VersionAdded: '0.49' + +Layout/SpaceInsideReferenceBrackets: + Description: 'Checks the spacing inside referential brackets.' + Enabled: true + VersionAdded: '0.52' + VersionChanged: '0.53' + EnforcedStyle: no_space + SupportedStyles: + - space + - no_space + EnforcedStyleForEmptyBrackets: no_space + SupportedStylesForEmptyBrackets: + - space + - no_space + +Layout/SpaceInsideStringInterpolation: + Description: 'Checks for padding/surrounding spaces inside string interpolation.' + StyleGuide: '#string-interpolation' + Enabled: true + VersionAdded: '0.49' + EnforcedStyle: no_space + SupportedStyles: + - space + - no_space + +Layout/TrailingEmptyLines: + Description: 'Checks trailing blank lines and final newline.' + StyleGuide: '#newline-eof' + Enabled: true + VersionAdded: '0.49' + VersionChanged: '0.77' + EnforcedStyle: final_newline + SupportedStyles: + - final_newline + - final_blank_line + +Layout/TrailingWhitespace: + Description: 'Avoid trailing whitespace.' + StyleGuide: '#no-trailing-whitespace' + Enabled: true + VersionAdded: '0.49' + VersionChanged: '1.0' + AllowInHeredoc: false + +#################### Lint ################################## +### Warnings + +Lint/AmbiguousAssignment: + Description: 'Checks for mistyped shorthand assignments.' + Enabled: pending + VersionAdded: '1.7' + +Lint/AmbiguousBlockAssociation: + Description: >- + Checks for ambiguous block association with method when param passed without + parentheses. + Enabled: true + VersionAdded: '0.48' + VersionChanged: '1.13' + AllowedMethods: [] + AllowedPatterns: [] + +Lint/AmbiguousOperator: + Description: >- + Checks for ambiguous operators in the first argument of a + method invocation without parentheses. + StyleGuide: '#method-invocation-parens' + Enabled: true + VersionAdded: '0.17' + VersionChanged: '0.83' + +Lint/AmbiguousOperatorPrecedence: + Description: >- + Checks for expressions containing multiple binary operations with + ambiguous precedence. + Enabled: pending + VersionAdded: '1.21' + +Lint/AmbiguousRange: + Description: Checks for ranges with ambiguous boundaries. + Enabled: pending + VersionAdded: '1.19' + SafeAutoCorrect: false + RequireParenthesesForMethodChains: false + +Lint/AmbiguousRegexpLiteral: + Description: >- + Checks for ambiguous regexp literals in the first argument of + a method invocation without parentheses. + Enabled: true + VersionAdded: '0.17' + VersionChanged: '0.83' + +Lint/ArrayLiteralInRegexp: + Description: 'Checks for an array literal interpolated inside a regexp.' + Enabled: pending + VersionAdded: '1.71' + SafeAutoCorrect: false + +Lint/AssignmentInCondition: + Description: "Don't use assignment in conditions." + StyleGuide: '#safe-assignment-in-condition' + Enabled: true + SafeAutoCorrect: false + VersionAdded: '0.9' + VersionChanged: '1.45' + AllowSafeAssignment: true + +Lint/BigDecimalNew: + Description: '`BigDecimal.new()` is deprecated. Use `BigDecimal()` instead.' + Enabled: true + VersionAdded: '0.53' + +Lint/BinaryOperatorWithIdenticalOperands: + Description: 'Checks for places where binary operator has identical operands.' + Enabled: true + Safe: false + VersionAdded: '0.89' + VersionChanged: '1.69' + +Lint/BooleanSymbol: + Description: 'Check for `:true` and `:false` symbols.' + Enabled: true + SafeAutoCorrect: false + VersionAdded: '0.50' + VersionChanged: '1.22' + +Lint/CircularArgumentReference: + Description: "Default values in optional keyword arguments and optional ordinal arguments should not refer back to the name of the argument." + Enabled: true + VersionAdded: '0.33' + +Lint/ConstantDefinitionInBlock: + Description: 'Do not define constants within a block.' + StyleGuide: '#no-constant-definition-in-block' + Enabled: true + VersionAdded: '0.91' + VersionChanged: '1.3' + # `enums` for Typed Enums via T::Enum in Sorbet. + # https://sorbet.org/docs/tenum + AllowedMethods: + - enums + +Lint/ConstantOverwrittenInRescue: + Description: 'Checks for overwriting an exception with an exception result by use `rescue =>`.' + Enabled: pending + VersionAdded: '1.31' + +Lint/ConstantReassignment: + Description: 'Checks for constant reassignments.' + Enabled: pending + VersionAdded: '1.70' + +Lint/ConstantResolution: + Description: 'Check that constants are fully qualified with `::`.' + Enabled: false + VersionAdded: '0.86' + # Restrict this cop to only looking at certain names + Only: [] + # Restrict this cop from only looking at certain names + Ignore: [] + +Lint/CopDirectiveSyntax: + Description: 'Checks that `# rubocop:` directives are strictly formatted.' + Enabled: pending + VersionAdded: '1.72' + +Lint/Debugger: + Description: 'Check for debugger calls.' + Enabled: true + VersionAdded: '0.14' + VersionChanged: '1.63' + DebuggerMethods: + # Groups are available so that a specific group can be disabled in + # a user's configuration, but are otherwise not significant. + Kernel: + - binding.irb + - Kernel.binding.irb + Byebug: + - byebug + - remote_byebug + - Kernel.byebug + - Kernel.remote_byebug + Capybara: + - page.save_and_open_page + - page.save_and_open_screenshot + - page.save_page + - page.save_screenshot + - save_and_open_page + - save_and_open_screenshot + - save_page + - save_screenshot + debug.rb: + - binding.b + - binding.break + - Kernel.binding.b + - Kernel.binding.break + Pry: + - binding.pry + - binding.remote_pry + - binding.pry_remote + - Kernel.binding.pry + - Kernel.binding.remote_pry + - Kernel.binding.pry_remote + - Pry.rescue + - pry + Rails: + - debugger + - Kernel.debugger + RubyJard: + - jard + WebConsole: + - binding.console + DebuggerRequires: + debug.rb: + - debug/open + - debug/start + +Lint/DeprecatedClassMethods: + Description: 'Check for deprecated class method calls.' + Enabled: true + VersionAdded: '0.19' + +Lint/DeprecatedConstants: + Description: 'Checks for deprecated constants.' + Enabled: pending + VersionAdded: '1.8' + VersionChanged: '1.40' + # You can configure deprecated constants. + # If there is an alternative method, you can set alternative value as `Alternative`. + # And you can set the deprecated version as `DeprecatedVersion`. + # These options can be omitted if they are not needed. + # + # DeprecatedConstants: + # 'DEPRECATED_CONSTANT': + # Alternative: 'alternative_value' + # DeprecatedVersion: 'deprecated_version' + # + DeprecatedConstants: + 'NIL': + Alternative: 'nil' + DeprecatedVersion: '2.4' + 'TRUE': + Alternative: 'true' + DeprecatedVersion: '2.4' + 'FALSE': + Alternative: 'false' + DeprecatedVersion: '2.4' + 'Net::HTTPServerException': + Alternative: 'Net::HTTPClientException' + DeprecatedVersion: '2.6' + 'Random::DEFAULT': + Alternative: 'Random.new' + DeprecatedVersion: '3.0' + 'Struct::Group': + Alternative: 'Etc::Group' + DeprecatedVersion: '3.0' + 'Struct::Passwd': + Alternative: 'Etc::Passwd' + DeprecatedVersion: '3.0' + +Lint/DeprecatedOpenSSLConstant: + Description: "Don't use algorithm constants for `OpenSSL::Cipher` and `OpenSSL::Digest`." + Enabled: true + VersionAdded: '0.84' + +Lint/DisjunctiveAssignmentInConstructor: + Description: 'In constructor, plain assignment is preferred over disjunctive.' + Enabled: true + Safe: false + VersionAdded: '0.62' + VersionChanged: '0.88' + +Lint/DuplicateBranch: + Description: Checks that there are no repeated bodies within `if/unless`, `case-when` and `rescue` constructs. + Enabled: pending + VersionAdded: '1.3' + VersionChanged: '1.7' + IgnoreLiteralBranches: false + IgnoreConstantBranches: false + IgnoreDuplicateElseBranch: false + +Lint/DuplicateCaseCondition: + Description: 'Do not repeat values in case conditionals.' + Enabled: true + VersionAdded: '0.45' + +Lint/DuplicateElsifCondition: + Description: 'Do not repeat conditions used in if `elsif`.' + Enabled: true + VersionAdded: '0.88' + +Lint/DuplicateHashKey: + Description: 'Check for duplicate keys in hash literals.' + Enabled: true + VersionAdded: '0.34' + VersionChanged: '0.77' + +Lint/DuplicateMagicComment: + Description: 'Check for duplicated magic comments.' + Enabled: pending + VersionAdded: '1.37' + +Lint/DuplicateMatchPattern: + Description: 'Do not repeat patterns in `in` keywords.' + Enabled: pending + VersionAdded: '1.50' + +Lint/DuplicateMethods: + Description: 'Check for duplicate method definitions.' + Enabled: true + VersionAdded: '0.29' + +Lint/DuplicateRegexpCharacterClassElement: + Description: 'Checks for duplicate elements in Regexp character classes.' + Enabled: pending + VersionAdded: '1.1' + +Lint/DuplicateRequire: + Description: 'Check for duplicate `require`s and `require_relative`s.' + Enabled: true + SafeAutoCorrect: false + VersionAdded: '0.90' + VersionChanged: '1.28' + +Lint/DuplicateRescueException: + Description: 'Checks that there are no repeated exceptions used in `rescue` expressions.' + Enabled: true + VersionAdded: '0.89' + +Lint/DuplicateSetElement: + Description: 'Checks for duplicate elements in Set.' + Enabled: pending + VersionAdded: '1.67' + +Lint/EachWithObjectArgument: + Description: 'Check for immutable argument given to each_with_object.' + Enabled: true + VersionAdded: '0.31' + +Lint/ElseLayout: + Description: 'Check for odd code arrangement in an else block.' + Enabled: true + VersionAdded: '0.17' + VersionChanged: '1.2' + +Lint/EmptyBlock: + Description: 'Checks for blocks without a body.' + Enabled: pending + VersionAdded: '1.1' + VersionChanged: '1.15' + AllowComments: true + AllowEmptyLambdas: true + +Lint/EmptyClass: + Description: 'Checks for classes and metaclasses without a body.' + Enabled: pending + VersionAdded: '1.3' + AllowComments: false + +Lint/EmptyConditionalBody: + Description: 'Checks for the presence of `if`, `elsif` and `unless` branches without a body.' + Enabled: true + AutoCorrect: contextual + AllowComments: true + VersionAdded: '0.89' + VersionChanged: '1.73' + +Lint/EmptyEnsure: + Description: 'Checks for empty ensure block.' + Enabled: true + AutoCorrect: contextual + VersionAdded: '0.10' + VersionChanged: '1.61' + +Lint/EmptyExpression: + Description: 'Checks for empty expressions.' + Enabled: true + VersionAdded: '0.45' + +Lint/EmptyFile: + Description: 'Enforces that Ruby source files are not empty.' + Enabled: true + AllowComments: true + VersionAdded: '0.90' + +Lint/EmptyInPattern: + Description: 'Checks for the presence of `in` pattern branches without a body.' + Enabled: pending + AllowComments: true + VersionAdded: '1.16' + +Lint/EmptyInterpolation: + Description: 'Checks for empty string interpolation.' + Enabled: true + AutoCorrect: contextual + VersionAdded: '0.20' + VersionChanged: '1.76' + +Lint/EmptyWhen: + Description: 'Checks for `when` branches with empty bodies.' + Enabled: true + AllowComments: true + VersionAdded: '0.45' + VersionChanged: '0.83' + +Lint/EnsureReturn: + Description: 'Do not use return in an ensure block.' + StyleGuide: '#no-return-ensure' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.83' + +Lint/ErbNewArguments: + Description: 'Use `:trim_mode` and `:eoutvar` keyword arguments to `ERB.new`.' + Enabled: true + VersionAdded: '0.56' + +Lint/FlipFlop: + Description: 'Checks for flip-flops.' + StyleGuide: '#no-flip-flops' + Enabled: true + VersionAdded: '0.16' + +Lint/FloatComparison: + Description: 'Checks for the presence of precise comparison of floating point numbers.' + StyleGuide: '#float-comparison' + Enabled: true + VersionAdded: '0.89' + +Lint/FloatOutOfRange: + Description: >- + Catches floating-point literals too large or small for Ruby to + represent. + Enabled: true + VersionAdded: '0.36' + +Lint/FormatParameterMismatch: + Description: 'The number of parameters to format/sprint must match the fields.' + Enabled: true + VersionAdded: '0.33' + +Lint/HashCompareByIdentity: + Description: 'Prefer using `Hash#compare_by_identity` than using `object_id` for keys.' + StyleGuide: '#identity-comparison' + Enabled: true + Safe: false + VersionAdded: '0.93' + +Lint/HashNewWithKeywordArgumentsAsDefault: + Description: 'Checks for the deprecated use of keyword arguments for hash default in `Hash.new`.' + Enabled: pending + VersionAdded: '1.69' + +Lint/HeredocMethodCallPosition: + Description: >- + Checks for the ordering of a method call where + the receiver of the call is a HEREDOC. + Enabled: false + StyleGuide: '#heredoc-method-calls' + VersionAdded: '0.68' + +Lint/IdentityComparison: + Description: 'Prefer `equal?` over `==` when comparing `object_id`.' + Enabled: true + StyleGuide: '#identity-comparison' + VersionAdded: '0.91' + +Lint/ImplicitStringConcatenation: + Description: >- + Checks for adjacent string literals on the same line, which + could better be represented as a single string literal. + Enabled: true + VersionAdded: '0.36' + +Lint/IncompatibleIoSelectWithFiberScheduler: + Description: 'Checks for `IO.select` that is incompatible with Fiber Scheduler.' + Enabled: pending + SafeAutoCorrect: false + VersionAdded: '1.21' + VersionChanged: '1.24' + +Lint/IneffectiveAccessModifier: + Description: >- + Checks for attempts to use `private` or `protected` to set + the visibility of a class method, which does not work. + Enabled: true + VersionAdded: '0.36' + +Lint/InheritException: + Description: 'Avoid inheriting from the `Exception` class.' + Enabled: true + SafeAutoCorrect: false + VersionAdded: '0.41' + VersionChanged: '1.26' + # The default base class in favour of `Exception`. + EnforcedStyle: standard_error + SupportedStyles: + - standard_error + - runtime_error + +Lint/InterpolationCheck: + Description: 'Checks for interpolation in a single quoted string.' + Enabled: true + SafeAutoCorrect: false + VersionAdded: '0.50' + VersionChanged: '1.40' + +Lint/ItWithoutArgumentsInBlock: + Description: 'Checks uses of `it` calls without arguments in block.' + References: + - 'https://bugs.ruby-lang.org/issues/18980' + Enabled: pending + VersionAdded: '1.59' + +Lint/LambdaWithoutLiteralBlock: + Description: 'Checks uses of lambda without a literal block.' + Enabled: pending + VersionAdded: '1.8' + +Lint/LiteralAsCondition: + Description: 'Checks of literals used in conditions.' + Enabled: true + AutoCorrect: contextual + VersionAdded: '0.51' + +Lint/LiteralAssignmentInCondition: + Description: 'Checks for literal assignments in the conditions.' + Enabled: pending + VersionAdded: '1.58' + +Lint/LiteralInInterpolation: + Description: 'Checks for literals used in interpolation.' + Enabled: true + VersionAdded: '0.19' + VersionChanged: '0.32' + +Lint/Loop: + Description: >- + Use Kernel#loop with break rather than begin/end/until or + begin/end/while for post-loop tests. + StyleGuide: '#loop-with-break' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '1.3' + Safe: false + +Lint/MissingCopEnableDirective: + Description: 'Checks for a `# rubocop:enable` after `# rubocop:disable`.' + Enabled: true + VersionAdded: '0.52' + # Maximum number of consecutive lines the cop can be disabled for. + # 0 allows only single-line disables + # 1 would mean the maximum allowed is the following: + # # rubocop:disable SomeCop + # a = 1 + # # rubocop:enable SomeCop + # .inf for any size + MaximumRangeSize: .inf + +Lint/MissingSuper: + Description: >- + Checks for the presence of constructors and lifecycle callbacks + without calls to `super`. + Enabled: true + AllowedParentClasses: [] + VersionAdded: '0.89' + VersionChanged: '1.4' + +Lint/MixedCaseRange: + Description: 'Checks for mixed-case character ranges since they include likely unintended characters.' + Enabled: pending + SafeAutoCorrect: false + VersionAdded: '1.53' + +Lint/MixedRegexpCaptureTypes: + Description: 'Do not mix named captures and numbered captures in a Regexp literal.' + Enabled: true + VersionAdded: '0.85' + +Lint/MultipleComparison: + Description: "Use `&&` operator to compare multiple values." + Enabled: true + VersionAdded: '0.47' + VersionChanged: '1.1' + +Lint/NestedMethodDefinition: + Description: 'Do not use nested method definitions.' + StyleGuide: '#no-nested-methods' + Enabled: true + AllowedMethods: [] + AllowedPatterns: [] + VersionAdded: '0.32' + +Lint/NestedPercentLiteral: + Description: 'Checks for nested percent literals.' + Enabled: true + VersionAdded: '0.52' + +Lint/NextWithoutAccumulator: + Description: >- + Do not omit the accumulator when calling `next` + in a `reduce`/`inject` block. + Enabled: true + VersionAdded: '0.36' + +Lint/NoReturnInBeginEndBlocks: + Description: 'Do not `return` inside `begin..end` blocks in assignment contexts.' + Enabled: pending + VersionAdded: '1.2' + +Lint/NonAtomicFileOperation: + Description: Checks for non-atomic file operations. + StyleGuide: '#atomic-file-operations' + Enabled: pending + VersionAdded: '1.31' + SafeAutoCorrect: false + +Lint/NonDeterministicRequireOrder: + Description: 'Always sort arrays returned by Dir.glob when requiring files.' + Enabled: true + VersionAdded: '0.78' + Safe: false + +Lint/NonLocalExitFromIterator: + Description: 'Do not use return in iterator to cause non-local exit.' + Enabled: true + VersionAdded: '0.30' + +Lint/NumberConversion: + Description: 'Checks unsafe usage of number conversion methods.' + Enabled: false + VersionAdded: '0.53' + VersionChanged: '1.1' + SafeAutoCorrect: false + AllowedMethods: [] + AllowedPatterns: [] + IgnoredClasses: + - Time + - DateTime + +Lint/NumberedParameterAssignment: + Description: 'Checks for uses of numbered parameter assignment.' + Enabled: pending + VersionAdded: '1.9' + +Lint/NumericOperationWithConstantResult: + Description: 'Checks for numeric operations with constant results.' + Enabled: pending + VersionAdded: '1.69' + +Lint/OrAssignmentToConstant: + Description: 'Checks unintended or-assignment to constant.' + Enabled: pending + Safe: false + VersionAdded: '1.9' + +Lint/OrderedMagicComments: + Description: 'Checks the proper ordering of magic comments and whether a magic comment is not placed before a shebang.' + Enabled: true + SafeAutoCorrect: false + VersionAdded: '0.53' + VersionChanged: '1.37' + +Lint/OutOfRangeRegexpRef: + Description: 'Checks for out of range reference for Regexp because it always returns nil.' + Enabled: true + Safe: false + VersionAdded: '0.89' + +Lint/ParenthesesAsGroupedExpression: + Description: >- + Checks for method calls with a space before the opening + parenthesis. + StyleGuide: '#parens-no-spaces' + Enabled: true + VersionAdded: '0.12' + VersionChanged: '0.83' + +Lint/PercentStringArray: + Description: >- + Checks for unwanted commas and quotes in %w/%W literals. + Enabled: true + Safe: false + VersionAdded: '0.41' + +Lint/PercentSymbolArray: + Description: >- + Checks for unwanted commas and colons in %i/%I literals. + Enabled: true + VersionAdded: '0.41' + +Lint/RaiseException: + Description: Checks for `raise` or `fail` statements which are raising `Exception` class. + StyleGuide: '#raise-exception' + Enabled: true + Safe: false + VersionAdded: '0.81' + VersionChanged: '0.86' + AllowedImplicitNamespaces: + - 'Gem' + +Lint/RandOne: + Description: >- + Checks for `rand(1)` calls. Such calls always return `0` + and most likely a mistake. + Enabled: true + VersionAdded: '0.36' + +Lint/RedundantCopDisableDirective: + Description: >- + Checks for rubocop:disable comments that can be removed. + Note: this cop is not disabled when disabling all cops. + It must be explicitly disabled. + Enabled: true + VersionAdded: '0.76' + +Lint/RedundantCopEnableDirective: + Description: Checks for rubocop:enable comments that can be removed. + Enabled: true + VersionAdded: '0.76' + +Lint/RedundantDirGlobSort: + Description: 'Checks for redundant `sort` method to `Dir.glob` and `Dir[]`.' + Enabled: pending + VersionAdded: '1.8' + VersionChanged: '1.26' + SafeAutoCorrect: false + +Lint/RedundantRegexpQuantifiers: + Description: 'Checks for redundant quantifiers in Regexps.' + Enabled: pending + VersionAdded: '1.53' + +Lint/RedundantRequireStatement: + Description: 'Checks for unnecessary `require` statement.' + Enabled: true + VersionAdded: '0.76' + VersionChanged: '1.73' + +Lint/RedundantSafeNavigation: + Description: 'Checks for redundant safe navigation calls.' + Enabled: true + VersionAdded: '0.93' + AllowedMethods: + - instance_of? + - kind_of? + - is_a? + - eql? + - respond_to? + - equal? + Safe: false + +Lint/RedundantSplatExpansion: + Description: 'Checks for splat unnecessarily being called on literals.' + Enabled: true + VersionAdded: '0.76' + VersionChanged: '1.7' + AllowPercentLiteralArrayArgument: true + +Lint/RedundantStringCoercion: + Description: 'Checks for Object#to_s usage in string interpolation.' + StyleGuide: '#no-to-s' + Enabled: true + VersionAdded: '0.19' + VersionChanged: '0.77' + +Lint/RedundantTypeConversion: + Description: 'Checks for redundantly converting a literal to the same type.' + Enabled: pending + VersionAdded: '1.72' + +Lint/RedundantWithIndex: + Description: 'Checks for redundant `with_index`.' + Enabled: true + VersionAdded: '0.50' + +Lint/RedundantWithObject: + Description: 'Checks for redundant `with_object`.' + Enabled: true + VersionAdded: '0.51' + +Lint/RefinementImportMethods: + Description: 'Use `Refinement#import_methods` when using `include` or `prepend` in `refine` block.' + Enabled: pending + SafeAutoCorrect: false + VersionAdded: '1.27' + +Lint/RegexpAsCondition: + Description: >- + Do not use regexp literal as a condition. + The regexp literal matches `$_` implicitly. + Enabled: true + VersionAdded: '0.51' + VersionChanged: '0.86' + +Lint/RequireParentheses: + Description: >- + Use parentheses in the method call to avoid confusion + about precedence. + Enabled: true + VersionAdded: '0.18' + +Lint/RequireRangeParentheses: + Description: 'Checks that a range literal is enclosed in parentheses when the end of the range is at a line break.' + Enabled: pending + VersionAdded: '1.32' + +Lint/RequireRelativeSelfPath: + Description: 'Checks for uses a file requiring itself with `require_relative`.' + Enabled: pending + VersionAdded: '1.22' + +Lint/RescueException: + Description: 'Avoid rescuing the Exception class.' + StyleGuide: '#no-blind-rescues' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.27' + +Lint/RescueType: + Description: 'Avoid rescuing from non constants that could result in a `TypeError`.' + Enabled: true + VersionAdded: '0.49' + +Lint/ReturnInVoidContext: + Description: 'Checks for return in void context.' + Enabled: true + VersionAdded: '0.50' + +Lint/SafeNavigationChain: + Description: 'Do not chain ordinary method call after safe navigation operator.' + Enabled: true + VersionAdded: '0.47' + VersionChanged: '0.77' + AllowedMethods: + - present? + - blank? + - presence + - try + - try! + - in? + +Lint/SafeNavigationConsistency: + Description: >- + Check to make sure that if safe navigation is used in an `&&` or `||` condition, + consistent and appropriate safe navigation, without excess or deficiency, + is used for all method calls on the same object. + Enabled: true + VersionAdded: '0.55' + VersionChanged: '0.77' + AllowedMethods: + - present? + - blank? + - presence + - try + - try! + +Lint/SafeNavigationWithEmpty: + Description: 'Avoid `foo&.empty?` in conditionals.' + Enabled: true + VersionAdded: '0.62' + VersionChanged: '0.87' + +Lint/ScriptPermission: + Description: 'Grant script file execute permission.' + Enabled: true + VersionAdded: '0.49' + VersionChanged: '0.50' + +Lint/SelfAssignment: + Description: 'Checks for self-assignments.' + Enabled: true + VersionAdded: '0.89' + +Lint/SendWithMixinArgument: + Description: 'Checks for `send` method when using mixin.' + Enabled: true + VersionAdded: '0.75' + +Lint/ShadowedArgument: + Description: 'Avoid reassigning arguments before they were used.' + Enabled: true + VersionAdded: '0.52' + IgnoreImplicitReferences: false + +Lint/ShadowedException: + Description: >- + Avoid rescuing a higher level exception + before a lower level exception. + Enabled: true + VersionAdded: '0.41' + +Lint/ShadowingOuterLocalVariable: + Description: >- + Do not use the same name as outer local variable + for block arguments or block local variables. + Enabled: false + VersionAdded: '0.9' + VersionChanged: '1.76' + +Lint/SharedMutableDefault: + Description: 'Checks for mutable literals used as default arguments during Hash initialization.' + StyleGuide: '#no-mutable-defaults' + Enabled: pending + VersionAdded: '1.70' + +Lint/StructNewOverride: + Description: 'Disallow overriding the `Struct` built-in methods via `Struct.new`.' + Enabled: true + VersionAdded: '0.81' + +Lint/SuppressedException: + Description: "Don't suppress exceptions." + StyleGuide: '#dont-hide-exceptions' + Enabled: true + AllowComments: true + AllowNil: true + VersionAdded: '0.9' + VersionChanged: '1.12' + +Lint/SuppressedExceptionInNumberConversion: + Description: 'Checks for cases where exceptions unrelated to the numeric constructors may be unintentionally swallowed.' + Enabled: pending + SafeAutoCorrect: false + VersionAdded: '1.72' + +Lint/SymbolConversion: + Description: 'Checks for unnecessary symbol conversions.' + Enabled: pending + VersionAdded: '1.9' + VersionChanged: '1.16' + EnforcedStyle: strict + SupportedStyles: + - strict + - consistent + +Lint/Syntax: + Description: 'Checks for syntax errors.' + Enabled: true + VersionAdded: '0.9' + +Lint/ToEnumArguments: + Description: 'Ensures that `to_enum`/`enum_for`, called for the current method, has correct arguments.' + Enabled: pending + VersionAdded: '1.1' + +Lint/ToJSON: + Description: 'Ensure #to_json includes an optional argument.' + Enabled: true + VersionAdded: '0.66' + +Lint/TopLevelReturnWithArgument: + Description: 'Detects top level return statements with argument.' + Enabled: true + VersionAdded: '0.89' + # These codes are `eval`-ed in method and their return values may be used. + Exclude: + - '**/*.jb' + +Lint/TrailingCommaInAttributeDeclaration: + Description: 'Checks for trailing commas in attribute declarations.' + Enabled: true + AutoCorrect: contextual + VersionAdded: '0.90' + VersionChanged: '1.61' + +Lint/TripleQuotes: + Description: 'Checks for useless triple quote constructs.' + Enabled: pending + VersionAdded: '1.9' + +Lint/UnderscorePrefixedVariableName: + Description: 'Do not use prefix `_` for a variable that is used.' + Enabled: true + VersionAdded: '0.21' + AllowKeywordBlockArguments: false + +Lint/UnescapedBracketInRegexp: + Description: 'Checks for unescaped literal `]` in Regexp.' + Enabled: pending + VersionAdded: '1.68' + +Lint/UnexpectedBlockArity: + Description: 'Looks for blocks that have fewer arguments that the calling method expects.' + Enabled: pending + Safe: false + VersionAdded: '1.5' + Methods: + chunk_while: 2 + each_with_index: 2 + each_with_object: 2 + inject: 2 + max: 2 + min: 2 + minmax: 2 + reduce: 2 + slice_when: 2 + sort: 2 + +Lint/UnifiedInteger: + Description: 'Use Integer instead of Fixnum or Bignum.' + Enabled: true + VersionAdded: '0.43' + +Lint/UnmodifiedReduceAccumulator: + Description: Checks for `reduce` or `inject` blocks that do not update the accumulator each iteration. + Enabled: pending + VersionAdded: '1.1' + VersionChanged: '1.5' + +Lint/UnreachableCode: + Description: 'Unreachable code.' + Enabled: true + VersionAdded: '0.9' + +Lint/UnreachableLoop: + Description: 'Checks for loops that will have at most one iteration.' + Enabled: true + VersionAdded: '0.89' + VersionChanged: '1.7' + AllowedPatterns: + # RSpec uses `times` in its message expectations + # eg. `exactly(2).times` + - !ruby/regexp /(exactly|at_least|at_most)\(\d+\)\.times/ + +Lint/UnusedBlockArgument: + Description: 'Checks for unused block arguments.' + StyleGuide: '#underscore-unused-vars' + Enabled: true + AutoCorrect: contextual + VersionAdded: '0.21' + VersionChanged: '1.61' + IgnoreEmptyBlocks: true + AllowUnusedKeywordArguments: false + +Lint/UnusedMethodArgument: + Description: 'Checks for unused method arguments.' + StyleGuide: '#underscore-unused-vars' + Enabled: true + AutoCorrect: contextual + VersionAdded: '0.21' + VersionChanged: '1.69' + AllowUnusedKeywordArguments: false + IgnoreEmptyMethods: true + IgnoreNotImplementedMethods: true + NotImplementedExceptions: + - NotImplementedError + +Lint/UriEscapeUnescape: + Description: >- + `URI.escape` method is obsolete and should not be used. Instead, use + `CGI.escape`, `URI.encode_www_form` or `URI.encode_www_form_component` + depending on your specific use case. + Also `URI.unescape` method is obsolete and should not be used. Instead, use + `CGI.unescape`, `URI.decode_www_form` or `URI.decode_www_form_component` + depending on your specific use case. + Enabled: true + VersionAdded: '0.50' + +Lint/UriRegexp: + Description: 'Use `URI::DEFAULT_PARSER.make_regexp` instead of `URI.regexp`.' + Enabled: true + VersionAdded: '0.50' + +Lint/UselessAccessModifier: + Description: 'Checks for useless access modifiers.' + Enabled: true + AutoCorrect: contextual + VersionAdded: '0.20' + VersionChanged: '1.61' + ContextCreatingMethods: [] + MethodCreatingMethods: [] + +Lint/UselessAssignment: + Description: 'Checks for useless assignment to a local variable.' + StyleGuide: '#underscore-unused-vars' + Enabled: true + AutoCorrect: contextual + VersionAdded: '0.11' + VersionChanged: '1.66' + +Lint/UselessConstantScoping: + Description: 'Checks for useless constant scoping.' + Enabled: pending + VersionAdded: '1.72' + +Lint/UselessDefaultValueArgument: + Description: 'Checks for usage of `fetch` or `Array.new` with default value argument and block.' + Enabled: pending + VersionAdded: '1.76' + Safe: false + AllowedReceivers: [] + +Lint/UselessDefined: + Description: 'Checks for calls to `defined?` with strings and symbols. The result of such a call will always be truthy.' + Enabled: pending + VersionAdded: '1.69' + +Lint/UselessElseWithoutRescue: + Description: 'Checks for useless `else` in `begin..end` without `rescue`.' + Enabled: true + VersionAdded: '0.17' + VersionChanged: '1.31' + +Lint/UselessMethodDefinition: + Description: 'Checks for useless method definitions.' + Enabled: true + AutoCorrect: contextual + VersionAdded: '0.90' + VersionChanged: '1.61' + Safe: false + +Lint/UselessNumericOperation: + Description: 'Checks for useless numeric operations.' + Enabled: pending + VersionAdded: '1.66' + +Lint/UselessOr: + Description: 'Checks for useless OR expressions.' + Enabled: pending + VersionAdded: '1.76' + +Lint/UselessRescue: + Description: 'Checks for useless `rescue`s.' + Enabled: pending + VersionAdded: '1.43' + +Lint/UselessRuby2Keywords: + Description: 'Finds unnecessary uses of `ruby2_keywords`.' + Enabled: pending + VersionAdded: '1.23' + +Lint/UselessSetterCall: + Description: 'Checks for useless setter call to a local variable.' + Enabled: true + Safe: false + VersionAdded: '0.13' + VersionChanged: '1.2' + +Lint/UselessTimes: + Description: 'Checks for useless `Integer#times` calls.' + Enabled: true + Safe: false + AutoCorrect: contextual + VersionAdded: '0.91' + VersionChanged: '1.61' + +Lint/Void: + Description: 'Possible use of operator/literal/variable in void context.' + Enabled: true + AutoCorrect: contextual + VersionAdded: '0.9' + VersionChanged: '1.61' + CheckForMethodsWithNoSideEffects: false + +#################### Metrics ############################### + +Metrics/AbcSize: + Description: >- + A calculated magnitude based on number of assignments, + branches, and conditions. + References: + - https://wiki.c2.com/?AbcMetric + - https://en.wikipedia.org/wiki/ABC_Software_Metric + Enabled: true + VersionAdded: '0.27' + VersionChanged: '1.5' + # The ABC size is a calculated magnitude, so this number can be an Integer or + # a Float. + AllowedMethods: [] + AllowedPatterns: [] + CountRepeatedAttributes: true + Max: 17 + +Metrics/BlockLength: + Description: 'Avoid long blocks with many lines.' + Enabled: true + VersionAdded: '0.44' + VersionChanged: '1.5' + CountComments: false # count full line comments? + Max: 25 + CountAsOne: [] + AllowedMethods: + # By default, exclude the `#refine` method, as it tends to have larger + # associated blocks. + - refine + AllowedPatterns: [] + Exclude: + - '**/*.gemspec' + +Metrics/BlockNesting: + Description: 'Avoid excessive block nesting.' + StyleGuide: '#three-is-the-number-thou-shalt-count' + Enabled: true + VersionAdded: '0.25' + VersionChanged: '1.65' + CountBlocks: false + CountModifierForms: false + Max: 3 + +Metrics/ClassLength: + Description: 'Avoid classes longer than 100 lines of code.' + Enabled: true + VersionAdded: '0.25' + VersionChanged: '0.87' + CountComments: false # count full line comments? + Max: 100 + CountAsOne: [] + +Metrics/CollectionLiteralLength: + Description: 'Checks for `Array` or `Hash` literals with many entries.' + Enabled: pending + VersionAdded: '1.47' + LengthThreshold: 250 + +# Avoid complex methods. +Metrics/CyclomaticComplexity: + Description: >- + A complexity metric that is strongly correlated to the number + of test cases needed to validate a method. + Enabled: true + VersionAdded: '0.25' + VersionChanged: '0.81' + AllowedMethods: [] + AllowedPatterns: [] + Max: 7 + +Metrics/MethodLength: + Description: 'Avoid methods longer than 10 lines of code.' + StyleGuide: '#short-methods' + Enabled: true + VersionAdded: '0.25' + VersionChanged: '1.5' + CountComments: false # count full line comments? + Max: 10 + CountAsOne: [] + AllowedMethods: [] + AllowedPatterns: [] + +Metrics/ModuleLength: + Description: 'Avoid modules longer than 100 lines of code.' + Enabled: true + VersionAdded: '0.31' + VersionChanged: '0.87' + CountComments: false # count full line comments? + Max: 100 + CountAsOne: [] + +Metrics/ParameterLists: + Description: 'Avoid parameter lists longer than three or four parameters.' + StyleGuide: '#too-many-params' + Enabled: true + VersionAdded: '0.25' + VersionChanged: '1.5' + Max: 5 + CountKeywordArgs: true + MaxOptionalParameters: 3 + +Metrics/PerceivedComplexity: + Description: >- + A complexity metric geared towards measuring complexity for a + human reader. + Enabled: true + VersionAdded: '0.25' + VersionChanged: '0.81' + AllowedMethods: [] + AllowedPatterns: [] + Max: 8 + +################## Migration ############################# + +Migration/DepartmentName: + Description: >- + Check that cop names in rubocop:disable (etc) comments are + given with department name. + Enabled: true + VersionAdded: '0.75' + +#################### Naming ############################## + +Naming/AccessorMethodName: + Description: Check the naming of accessor methods for get_/set_. + StyleGuide: '#accessor_mutator_method_names' + Enabled: true + VersionAdded: '0.50' + +Naming/AsciiIdentifiers: + Description: 'Use only ascii symbols in identifiers and constants.' + StyleGuide: '#english-identifiers' + Enabled: true + VersionAdded: '0.50' + VersionChanged: '0.87' + AsciiConstants: true + +Naming/BinaryOperatorParameterName: + Description: 'When defining binary operators, name the argument other.' + StyleGuide: '#other-arg' + Enabled: true + VersionAdded: '0.50' + VersionChanged: '1.2' + +Naming/BlockForwarding: + Description: 'Use anonymous block forwarding.' + StyleGuide: '#block-forwarding' + Enabled: pending + VersionAdded: '1.24' + EnforcedStyle: anonymous + SupportedStyles: + - anonymous + - explicit + BlockForwardingName: block + +Naming/BlockParameterName: + Description: >- + Checks for block parameter names that contain capital letters, + end in numbers, or do not meet a minimal length. + Enabled: true + VersionAdded: '0.53' + VersionChanged: '0.77' + # Parameter names may be equal to or greater than this value + MinNameLength: 1 + AllowNamesEndingInNumbers: true + # Allowed names that will not register an offense + AllowedNames: [] + # Forbidden names that will register an offense + ForbiddenNames: [] + +Naming/ClassAndModuleCamelCase: + Description: 'Use CamelCase for classes and modules.' + StyleGuide: '#camelcase-classes' + Enabled: true + VersionAdded: '0.50' + VersionChanged: '0.85' + # Allowed class/module names can be specified here. + # These can be full or part of the name. + AllowedNames: + - module_parent + +Naming/ConstantName: + Description: 'Constants should use SCREAMING_SNAKE_CASE.' + StyleGuide: '#screaming-snake-case' + Enabled: true + VersionAdded: '0.50' + +Naming/FileName: + Description: 'Use snake_case for source file names.' + StyleGuide: '#snake-case-files' + Enabled: true + VersionAdded: '0.50' + VersionChanged: '1.23' + # Camel case file names listed in `AllCops:Include` and all file names listed + # in `AllCops:Exclude` are excluded by default. Add extra excludes here. + Exclude: + - Rakefile.rb + # When `true`, requires that each source file should define a class or module + # with a name which matches the file name (converted to ... case). + # It further expects it to be nested inside modules which match the names + # of subdirectories in its path. + ExpectMatchingDefinition: false + # When `false`, changes the behavior of ExpectMatchingDefinition to match only + # whether each source file's class or module name matches the file name -- + # not whether the nested module hierarchy matches the subdirectory path. + CheckDefinitionPathHierarchy: true + # paths that are considered root directories, for example "lib" in most ruby projects + # or "app/models" in rails projects + CheckDefinitionPathHierarchyRoots: + - lib + - spec + - test + - src + # If non-`nil`, expect all source file names to match the following regex. + # Only the file name itself is matched, not the entire file path. + # Use anchors as necessary if you want to match the entire name rather than + # just a part of it. + Regex: ~ + # With `IgnoreExecutableScripts` set to `true`, this cop does not + # report offending filenames for executable scripts (i.e. source + # files with a shebang in the first line). + IgnoreExecutableScripts: true + AllowedAcronyms: + - CLI + - DSL + - ACL + - API + - ASCII + - CPU + - CSS + - DNS + - EOF + - GUID + - HTML + - HTTP + - HTTPS + - ID + - IP + - JSON + - LHS + - QPS + - RAM + - RHS + - RPC + - SLA + - SMTP + - SQL + - SSH + - TCP + - TLS + - TTL + - UDP + - UI + - UID + - UUID + - URI + - URL + - UTF8 + - VM + - XML + - XMPP + - XSRF + - XSS + +Naming/HeredocDelimiterCase: + Description: 'Use configured case for heredoc delimiters.' + StyleGuide: '#heredoc-delimiters' + Enabled: true + VersionAdded: '0.50' + VersionChanged: '1.2' + EnforcedStyle: uppercase + SupportedStyles: + - lowercase + - uppercase + +Naming/HeredocDelimiterNaming: + Description: 'Use descriptive heredoc delimiters.' + StyleGuide: '#heredoc-delimiters' + Enabled: true + VersionAdded: '0.50' + ForbiddenDelimiters: + - !ruby/regexp '/(^|\s)(EO[A-Z]{1}|END)(\s|$)/i' + +Naming/InclusiveLanguage: + Description: 'Recommend the use of inclusive language instead of problematic terms.' + Enabled: false + VersionAdded: '1.18' + VersionChanged: '1.49' + CheckIdentifiers: true + CheckConstants: true + CheckVariables: true + CheckStrings: false + CheckSymbols: true + CheckComments: true + CheckFilepaths: true + FlaggedTerms: + whitelist: + Regex: !ruby/regexp '/white[-_\s]?list/' + Suggestions: + - allowlist + - permit + blacklist: + Regex: !ruby/regexp '/black[-_\s]?list/' + Suggestions: + - denylist + - block + slave: + WholeWord: true + Suggestions: ['replica', 'secondary', 'follower'] + +Naming/MemoizedInstanceVariableName: + Description: >- + Memoized method name should match memo instance variable name. + Enabled: true + VersionAdded: '0.53' + VersionChanged: '1.2' + EnforcedStyleForLeadingUnderscores: disallowed + SupportedStylesForLeadingUnderscores: + - disallowed + - required + - optional + Safe: false + +Naming/MethodName: + Description: 'Use the configured style when naming methods.' + StyleGuide: '#snake-case-symbols-methods-vars' + Enabled: true + VersionAdded: '0.50' + VersionChanged: '1.75' + EnforcedStyle: snake_case + SupportedStyles: + - snake_case + - camelCase + # Method names matching patterns are always allowed. + # + # AllowedPatterns: + # - '\A\s*onSelectionBulkChange\s*' + # - '\A\s*onSelectionCleared\s*' + # + AllowedPatterns: [] + ForbiddenIdentifiers: + - __id__ + - __send__ + ForbiddenPatterns: [] + +Naming/MethodParameterName: + Description: >- + Checks for method parameter names that contain capital letters, + end in numbers, or do not meet a minimal length. + Enabled: true + VersionAdded: '0.53' + VersionChanged: '0.77' + # Parameter names may be equal to or greater than this value + MinNameLength: 3 + AllowNamesEndingInNumbers: true + # Allowed names that will not register an offense + AllowedNames: + - as + - at + - by + - cc + - db + - id + - if + - in + - io + - ip + - of + - 'on' + - os + - pp + - to + # Forbidden names that will register an offense + ForbiddenNames: [] + +Naming/PredicateMethod: + Description: 'Checks that predicate methods end with `?` and non-predicate methods do not.' + Enabled: pending + VersionAdded: '1.76' + # In `aggressive` mode, the cop will register an offense for predicate methods that + # may return a non-boolean value. + # In `conservative` mode, the cop will *not* register an offense for predicate methods + # that may return a non-boolean value. + Mode: conservative + AllowedMethods: + - call + +Naming/PredicatePrefix: + Description: 'Predicate method names should not be prefixed and end with a `?`.' + StyleGuide: '#bool-methods-qmark' + Enabled: true + VersionAdded: '0.50' + VersionChanged: '1.75' + # Predicate name prefixes. + NamePrefix: + - is_ + - has_ + - have_ + - does_ + # Predicate name prefixes that should be removed. + ForbiddenPrefixes: + - is_ + - has_ + - have_ + - does_ + # Predicate names which, despite having a forbidden prefix, or no `?`, + # should still be accepted + AllowedMethods: + - is_a? + # Method definition macros for dynamically generated methods. + MethodDefinitionMacros: + - define_method + - define_singleton_method + # Use Sorbet's T::Boolean return type to detect predicate methods. + UseSorbetSigs: false + # Exclude Rspec specs because there is a strong convention to write spec + # helpers in the form of `have_something` or `be_something`. + Exclude: + - 'spec/**/*' + +Naming/RescuedExceptionsVariableName: + Description: 'Use consistent rescued exceptions variables naming.' + Enabled: true + VersionAdded: '0.67' + VersionChanged: '0.68' + PreferredName: e + +Naming/VariableName: + Description: 'Use the configured style when naming variables.' + StyleGuide: '#snake-case-symbols-methods-vars' + Enabled: true + VersionAdded: '0.50' + VersionChanged: '1.73' + EnforcedStyle: snake_case + SupportedStyles: + - snake_case + - camelCase + AllowedIdentifiers: [] + AllowedPatterns: [] + ForbiddenIdentifiers: [] + ForbiddenPatterns: [] + +Naming/VariableNumber: + Description: 'Use the configured style when numbering symbols, methods and variables.' + StyleGuide: '#snake-case-symbols-methods-vars-with-numbers' + Enabled: true + VersionAdded: '0.50' + VersionChanged: '1.4' + EnforcedStyle: normalcase + SupportedStyles: + - snake_case + - normalcase + - non_integer + CheckMethodNames: true + CheckSymbols: true + AllowedIdentifiers: + - TLS1_1 # OpenSSL::SSL::TLS1_1_VERSION + - TLS1_2 # OpenSSL::SSL::TLS1_2_VERSION + - capture3 # Open3.capture3 + - iso8601 # Time#iso8601 + - rfc1123_date # CGI.rfc1123_date + - rfc822 # Time#rfc822 + - rfc2822 # Time#rfc2822 + - rfc3339 # DateTime.rfc3339 + - x86_64 # Allowed by default as an underscore separated CPU architecture name + AllowedPatterns: [] + +#################### Security ############################## + +Security/CompoundHash: + Description: 'When overwriting Object#hash to combine values, prefer delegating to Array#hash over writing a custom implementation.' + Enabled: pending + Safe: false + VersionAdded: '1.28' + VersionChanged: '1.51' + +Security/Eval: + Description: 'The use of eval represents a serious security risk.' + Enabled: true + VersionAdded: '0.47' + +Security/IoMethods: + Description: >- + Checks for the first argument to `IO.read`, `IO.binread`, `IO.write`, `IO.binwrite`, + `IO.foreach`, and `IO.readlines`. + Enabled: pending + Safe: false + VersionAdded: '1.22' + +Security/JSONLoad: + Description: >- + Prefer usage of `JSON.parse` over `JSON.load` due to potential + security issues. See reference for more information. + References: + - 'https://ruby-doc.org/stdlib-2.7.0/libdoc/json/rdoc/JSON.html#method-i-load' + Enabled: true + VersionAdded: '0.43' + VersionChanged: '1.22' + # Autocorrect here will change to a method that may cause crashes depending + # on the value of the argument. + SafeAutoCorrect: false + +Security/MarshalLoad: + Description: >- + Avoid using of `Marshal.load` or `Marshal.restore` due to potential + security issues. See reference for more information. + References: + - 'https://ruby-doc.org/core-2.7.0/Marshal.html#module-Marshal-label-Security+considerations' + Enabled: true + VersionAdded: '0.47' + +Security/Open: + Description: 'The use of `Kernel#open` and `URI.open` represent a serious security risk.' + Enabled: true + VersionAdded: '0.53' + VersionChanged: '1.0' + Safe: false + +Security/YAMLLoad: + Description: >- + Prefer usage of `YAML.safe_load` over `YAML.load` due to potential + security issues. See reference for more information. + References: + - 'https://ruby-doc.org/stdlib-2.7.0/libdoc/yaml/rdoc/YAML.html#module-YAML-label-Security' + Enabled: true + VersionAdded: '0.47' + SafeAutoCorrect: false + +#################### Style ############################### + +Style/AccessModifierDeclarations: + Description: 'Checks style of how access modifiers are used.' + Enabled: true + VersionAdded: '0.57' + VersionChanged: '1.70' + EnforcedStyle: group + SupportedStyles: + - inline + - group + AllowModifiersOnSymbols: true + AllowModifiersOnAttrs: true + AllowModifiersOnAliasMethod: true + SafeAutoCorrect: false + +Style/AccessorGrouping: + Description: 'Checks for grouping of accessors in `class` and `module` bodies.' + Enabled: true + VersionAdded: '0.87' + EnforcedStyle: grouped + SupportedStyles: + # separated: each accessor goes in a separate statement. + # grouped: accessors are grouped into a single statement. + - separated + - grouped + +Style/Alias: + Description: 'Use alias instead of alias_method.' + StyleGuide: '#alias-method-lexically' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.36' + EnforcedStyle: prefer_alias + SupportedStyles: + - prefer_alias + - prefer_alias_method + +Style/AmbiguousEndlessMethodDefinition: + Description: 'Checks for endless methods inside operators of lower precedence.' + StyleGuide: '#ambiguous-endless-method-defintions' + Enabled: pending + VersionAdded: '1.68' + +Style/AndOr: + Description: 'Use &&/|| instead of and/or.' + StyleGuide: '#no-and-or-or' + Enabled: true + SafeAutoCorrect: false + VersionAdded: '0.9' + VersionChanged: '1.21' + # Whether `and` and `or` are banned only in conditionals (conditionals) + # or completely (always). + EnforcedStyle: conditionals + SupportedStyles: + - always + - conditionals + +Style/ArgumentsForwarding: + Description: 'Use arguments forwarding.' + StyleGuide: '#arguments-forwarding' + Enabled: pending + AllowOnlyRestArgument: true + UseAnonymousForwarding: true + RedundantRestArgumentNames: + - args + - arguments + RedundantKeywordRestArgumentNames: + - kwargs + - options + - opts + RedundantBlockArgumentNames: + - blk + - block + - proc + VersionAdded: '1.1' + VersionChanged: '1.58' + +Style/ArrayCoercion: + Description: >- + Use Array() instead of explicit Array check or [*var], when dealing + with a variable you want to treat as an Array, but you're not certain it's an array. + StyleGuide: '#array-coercion' + Safe: false + Enabled: false + VersionAdded: '0.88' + +Style/ArrayFirstLast: + Description: 'Use `arr.first` and `arr.last` instead of `arr[0]` and `arr[-1]`.' + References: + - '#first-and-last' + Enabled: false + VersionAdded: '1.58' + Safe: false + +Style/ArrayIntersect: + Description: 'Use `array1.intersect?(array2)` instead of `(array1 & array2).any?`.' + Enabled: 'pending' + Safe: false + VersionAdded: '1.40' + +Style/ArrayJoin: + Description: 'Use Array#join instead of Array#*.' + StyleGuide: '#array-join' + Enabled: true + VersionAdded: '0.20' + VersionChanged: '0.31' + +Style/AsciiComments: + Description: 'Use only ascii symbols in comments.' + StyleGuide: '#english-comments' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '1.21' + AllowedChars: + - © + +Style/Attr: + Description: 'Checks for uses of Module#attr.' + StyleGuide: '#attr' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.12' + +Style/AutoResourceCleanup: + Description: 'Suggests the usage of an auto resource cleanup version of a method (if available).' + Enabled: false + VersionAdded: '0.30' + +Style/BarePercentLiterals: + Description: 'Checks if usage of %() or %Q() matches configuration.' + StyleGuide: '#percent-q-shorthand' + Enabled: true + VersionAdded: '0.25' + EnforcedStyle: bare_percent + SupportedStyles: + - percent_q + - bare_percent + +Style/BeginBlock: + Description: 'Avoid the use of BEGIN blocks.' + StyleGuide: '#no-BEGIN-blocks' + Enabled: true + VersionAdded: '0.9' + +Style/BisectedAttrAccessor: + Description: >- + Checks for places where `attr_reader` and `attr_writer` + for the same method can be combined into single `attr_accessor`. + Enabled: true + VersionAdded: '0.87' + +Style/BitwisePredicate: + Description: 'Prefer bitwise predicate methods over direct comparison operations.' + StyleGuide: '#bitwise-predicate-methods' + Enabled: pending + Safe: false + VersionAdded: '1.68' + +Style/BlockComments: + Description: 'Do not use block comments.' + StyleGuide: '#no-block-comments' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.23' + +Style/BlockDelimiters: + Description: >- + Avoid using {...} for multi-line blocks (multiline chaining is + always ugly). + Prefer {...} over do...end for single-line blocks. + StyleGuide: '#single-line-blocks' + Enabled: true + VersionAdded: '0.30' + VersionChanged: '0.35' + EnforcedStyle: line_count_based + SupportedStyles: + # The `line_count_based` style enforces braces around single line blocks and + # do..end around multi-line blocks. + - line_count_based + # The `semantic` style enforces braces around functional blocks, where the + # primary purpose of the block is to return a value and do..end for + # multi-line procedural blocks, where the primary purpose of the block is + # its side-effects. Single-line procedural blocks may only use do-end, + # unless AllowBracesOnProceduralOneLiners has a truthy value (see below). + # + # This looks at the usage of a block's method to determine its type (e.g. is + # the result of a `map` assigned to a variable or passed to another + # method) but exceptions are permitted in the `ProceduralMethods`, + # `FunctionalMethods` and `AllowedMethods` sections below. + - semantic + # The `braces_for_chaining` style enforces braces around single line blocks + # and do..end around multi-line blocks, except for multi-line blocks whose + # return value is being chained with another method (in which case braces + # are enforced). + - braces_for_chaining + # The `always_braces` style always enforces braces. + - always_braces + ProceduralMethods: + # Methods that are known to be procedural in nature but look functional from + # their usage, e.g. + # + # time = Benchmark.realtime do + # foo.bar + # end + # + # Here, the return value of the block is discarded but the return value of + # `Benchmark.realtime` is used. + - benchmark + - bm + - bmbm + - create + - each_with_object + - measure + - new + - realtime + - tap + - with_object + FunctionalMethods: + # Methods that are known to be functional in nature but look procedural from + # their usage, e.g. + # + # let(:foo) { Foo.new } + # + # Here, the return value of `Foo.new` is used to define a `foo` helper but + # doesn't appear to be used from the return value of `let`. + - let + - let! + - subject + - watch + AllowedMethods: + # Methods that can be either procedural or functional and cannot be + # categorised from their usage alone, e.g. + # + # foo = lambda do |x| + # puts "Hello, #{x}" + # end + # + # foo = lambda do |x| + # x * 100 + # end + # + # Here, it is impossible to tell from the return value of `lambda` whether + # the inner block's return value is significant. + - lambda + - proc + - it + AllowedPatterns: [] + # The AllowBracesOnProceduralOneLiners option is ignored unless the + # EnforcedStyle is set to `semantic`. If so: + # + # If AllowBracesOnProceduralOneLiners is unspecified, or set to any + # falsey value, then semantic purity is maintained, so one-line + # procedural blocks must use do-end, not braces. + # + # # bad + # collection.each { |element| puts element } + # + # # good + # collection.each do |element| puts element end + # + # If AllowBracesOnProceduralOneLiners is set to any truthy value, + # then one-line procedural blocks may use either style. + # + # # good + # collection.each { |element| puts element } + # + # # also good + # collection.each do |element| puts element end + AllowBracesOnProceduralOneLiners: false + # The BracesRequiredMethods overrides all other configurations except + # AllowedMethods. It can be used to enforce that all blocks for specific + # methods use braces. For example, you can use this to enforce Sorbet + # signatures use braces even when the rest of your codebase enforces + # the `line_count_based` style. + BracesRequiredMethods: [] + +Style/CaseEquality: + Description: 'Avoid explicit use of the case equality operator(===).' + StyleGuide: '#no-case-equality' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.89' + # If `AllowOnConstant` option is enabled, the cop will ignore violations when the receiver of + # the case equality operator is a constant. + # + # # bad + # /string/ === "string" + # + # # good + # String === "string" + AllowOnConstant: false + # If `AllowOnSelfClass` option is enabled, the cop will ignore violations when the receiver of + # the case equality operator is `self.class`. + # + # # bad + # some_class === object + # + # # good + # self.class === object + AllowOnSelfClass: false + +Style/CaseLikeIf: + Description: 'Identifies places where `if-elsif` constructions can be replaced with `case-when`.' + StyleGuide: '#case-vs-if-else' + Enabled: true + Safe: false + VersionAdded: '0.88' + VersionChanged: '1.48' + # `MinBranchesCount` defines the number of branches `if` needs to have to trigger this cop. + MinBranchesCount: 3 + +Style/CharacterLiteral: + Description: 'Checks for uses of character literals.' + StyleGuide: '#no-character-literals' + Enabled: true + VersionAdded: '0.9' + +Style/ClassAndModuleChildren: + Description: 'Checks style of children classes and modules.' + StyleGuide: '#namespace-definition' + # Moving from compact to nested children requires knowledge of whether the + # outer parent is a module or a class. Moving from nested to compact requires + # verification that the outer parent is defined elsewhere. RuboCop does not + # have the knowledge to perform either operation safely and thus requires + # manual oversight. + SafeAutoCorrect: false + Enabled: true + VersionAdded: '0.19' + VersionChanged: '1.74' + # + # Basically there are two different styles: + # + # `nested` - have each child on a separate line + # class Foo + # class Bar + # end + # end + # + # `compact` - combine definitions as much as possible + # class Foo::Bar + # end + # + # The compact style is only forced, for classes or modules with one child. + EnforcedStyle: nested + SupportedStyles: &supported_styles + - nested + - compact + # Configure classes separately, if desired. If not set, or set to `nil`, + # the `EnforcedStyle` value will be used. + EnforcedStyleForClasses: ~ + SupportedStylesForClasses: + - ~ + - nested + - compact + # Configure modules separately, if desired. If not set, or set to `nil`, + # the `EnforcedStyle` value will be used. + EnforcedStyleForModules: ~ + SupportedStylesForModules: + - ~ + - nested + - compact + +Style/ClassCheck: + Description: 'Enforces consistent use of `Object#is_a?` or `Object#kind_of?`.' + StyleGuide: '#is-a-vs-kind-of' + Enabled: true + VersionAdded: '0.24' + EnforcedStyle: is_a? + SupportedStyles: + - is_a? + - kind_of? + +Style/ClassEqualityComparison: + Description: 'Enforces the use of `Object#instance_of?` instead of class comparison for equality.' + StyleGuide: '#instance-of-vs-class-comparison' + Enabled: true + SafeAutoCorrect: false + VersionAdded: '0.93' + VersionChanged: '1.57' + AllowedMethods: + - == + - equal? + - eql? + AllowedPatterns: [] + +Style/ClassMethods: + Description: 'Use self when defining module/class methods.' + StyleGuide: '#def-self-class-methods' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.20' + +Style/ClassMethodsDefinitions: + Description: 'Enforces using `def self.method_name` or `class << self` to define class methods.' + StyleGuide: '#def-self-class-methods' + Enabled: false + VersionAdded: '0.89' + EnforcedStyle: def_self + SupportedStyles: + - def_self + - self_class + +Style/ClassVars: + Description: 'Avoid the use of class variables.' + StyleGuide: '#no-class-vars' + Enabled: true + VersionAdded: '0.13' + +Style/CollectionCompact: + Description: 'Use `{Array,Hash}#{compact,compact!}` instead of custom logic to reject nils.' + Enabled: pending + Safe: false + VersionAdded: '1.2' + VersionChanged: '1.3' + AllowedReceivers: [] + +# Align with the style guide. +Style/CollectionMethods: + Description: 'Preferred collection methods.' + StyleGuide: '#map-find-select-reduce-include-size' + Enabled: false + VersionAdded: '0.9' + VersionChanged: '1.7' + Safe: false + # Mapping from undesired method to desired method + # e.g. to use `detect` over `find`: + # + # Style/CollectionMethods: + # PreferredMethods: + # find: detect + PreferredMethods: + collect: 'map' + collect!: 'map!' + collect_concat: 'flat_map' + inject: 'reduce' + detect: 'find' + find_all: 'select' + member?: 'include?' + # Methods in this array accept a final symbol as an implicit block + # eg. `inject(:+)` + MethodsAcceptingSymbol: + - inject + - reduce + +Style/ColonMethodCall: + Description: 'Do not use :: for method call.' + StyleGuide: '#double-colons' + Enabled: true + VersionAdded: '0.9' + +Style/ColonMethodDefinition: + Description: 'Do not use :: for defining class methods.' + StyleGuide: '#colon-method-definition' + Enabled: true + VersionAdded: '0.52' + +Style/CombinableDefined: + Description: 'Checks successive `defined?` calls that can be combined into a single call.' + Enabled: pending + VersionAdded: '1.68' + +Style/CombinableLoops: + Description: >- + Checks for places where multiple consecutive loops over the same data + can be combined into a single loop. + Enabled: true + Safe: false + VersionAdded: '0.90' + +Style/CommandLiteral: + Description: 'Use `` or %x around command literals.' + StyleGuide: '#percent-x' + Enabled: true + VersionAdded: '0.30' + EnforcedStyle: backticks + # backticks: Always use backticks. + # percent_x: Always use `%x`. + # mixed: Use backticks on single-line commands, and `%x` on multi-line commands. + SupportedStyles: + - backticks + - percent_x + - mixed + # If `false`, the cop will always recommend using `%x` if one or more backticks + # are found in the command string. + AllowInnerBackticks: false + +# Checks formatting of special comments +Style/CommentAnnotation: + Description: >- + Checks formatting of special comments + (TODO, FIXME, OPTIMIZE, HACK, REVIEW, NOTE). + StyleGuide: '#annotate-keywords' + Enabled: true + VersionAdded: '0.10' + VersionChanged: '1.20' + Keywords: + - TODO + - FIXME + - OPTIMIZE + - HACK + - REVIEW + - NOTE + RequireColon: true + +Style/CommentedKeyword: + Description: 'Do not place comments on the same line as certain keywords.' + Enabled: true + SafeAutoCorrect: false + VersionAdded: '0.51' + VersionChanged: '1.19' + +Style/ComparableBetween: + Description: 'Enforces the use of `Comparable#between?` instead of logical comparison.' + Enabled: pending + Safe: false + VersionAdded: '1.74' + VersionChanged: '1.75' + StyleGuide: '#ranges-or-between' + +Style/ComparableClamp: + Description: 'Enforces the use of `Comparable#clamp` instead of comparison by minimum and maximum.' + Enabled: pending + VersionAdded: '1.44' + +Style/ConcatArrayLiterals: + Description: 'Enforces the use of `Array#push(item)` instead of `Array#concat([item])` to avoid redundant array literals.' + Enabled: pending + Safe: false + VersionAdded: '1.41' + +Style/ConditionalAssignment: + Description: >- + Use the return value of `if` and `case` statements for + assignment to a variable and variable comparison instead + of assigning that variable inside of each branch. + Enabled: true + VersionAdded: '0.36' + VersionChanged: '0.47' + EnforcedStyle: assign_to_condition + SupportedStyles: + - assign_to_condition + - assign_inside_condition + # When configured to `assign_to_condition`, `SingleLineConditionsOnly` + # will only register an offense when all branches of a condition are + # a single line. + # When configured to `assign_inside_condition`, `SingleLineConditionsOnly` + # will only register an offense for assignment to a condition that has + # at least one multiline branch. + SingleLineConditionsOnly: true + IncludeTernaryExpressions: true + +Style/ConstantVisibility: + Description: >- + Check that class- and module constants have + visibility declarations. + Enabled: false + VersionAdded: '0.66' + VersionChanged: '1.10' + IgnoreModules: false + +# Checks that you have put a copyright in a comment before any code. +# +# You can override the default Notice in your .rubocop.yml file. +# +# In order to use autocorrect, you must supply a value for the +# `AutocorrectNotice` key that matches the regexp Notice. A blank +# `AutocorrectNotice` will cause an error during autocorrect. +# +# Autocorrect will add a copyright notice in a comment at the top +# of the file immediately after any shebang or encoding comments. +# +# Example rubocop.yml: +# +# Style/Copyright: +# Enabled: true +# Notice: 'Copyright (\(c\) )?2015 Yahoo! Inc' +# AutocorrectNotice: '# Copyright (c) 2015 Yahoo! Inc.' +# +Style/Copyright: + Description: 'Include a copyright notice in each file before any code.' + Enabled: false + VersionAdded: '0.30' + Notice: '^Copyright (\(c\) )?2[0-9]{3} .+' + AutocorrectNotice: '' + +Style/DataInheritance: + Description: 'Checks for inheritance from Data.define.' + StyleGuide: '#no-extend-data-define' + Enabled: pending + SafeAutoCorrect: false + VersionAdded: '1.49' + VersionChanged: '1.51' + +Style/DateTime: + Description: 'Use Time over DateTime.' + StyleGuide: '#date-time' + Enabled: false + VersionAdded: '0.51' + VersionChanged: '0.92' + SafeAutoCorrect: false + AllowCoercion: false + +Style/DefWithParentheses: + Description: 'Use def with parentheses when there are arguments.' + StyleGuide: '#method-parens' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.12' + +Style/DigChain: + Description: 'Use `dig` with multiple parameters instead of chaining multiple calls.' + Enabled: pending + Safe: false + VersionAdded: '1.69' + +Style/Dir: + Description: >- + Use the `__dir__` method to retrieve the canonicalized + absolute path to the current file. + Enabled: true + VersionAdded: '0.50' + +Style/DirEmpty: + Description: >- + Prefer to use `Dir.empty?('path/to/dir')` when checking if a directory is empty. + Enabled: pending + VersionAdded: '1.48' + +Style/DisableCopsWithinSourceCodeDirective: + Description: >- + Forbids disabling/enabling cops within source code. + Enabled: false + VersionAdded: '0.82' + VersionChanged: '1.9' + AllowedCops: [] + +Style/DocumentDynamicEvalDefinition: + Description: >- + When using `class_eval` (or other `eval`) with string interpolation, + add a comment block showing its appearance if interpolated. + StyleGuide: '#eval-comment-docs' + Enabled: pending + VersionAdded: '1.1' + VersionChanged: '1.3' + +Style/Documentation: + Description: 'Document classes and non-namespace modules.' + Enabled: true + VersionAdded: '0.9' + AllowedConstants: [] + Exclude: + - 'spec/**/*' + - 'test/**/*' + +Style/DocumentationMethod: + Description: 'Checks for missing documentation comment for public methods.' + Enabled: false + VersionAdded: '0.43' + AllowedMethods: [] + Exclude: + - 'spec/**/*' + - 'test/**/*' + RequireForNonPublicMethods: false + +Style/DoubleCopDisableDirective: + Description: 'Checks for double rubocop:disable comments on a single line.' + Enabled: true + VersionAdded: '0.73' + +Style/DoubleNegation: + Description: 'Checks for uses of double negation (!!).' + StyleGuide: '#no-bang-bang' + Enabled: true + VersionAdded: '0.19' + VersionChanged: '1.2' + EnforcedStyle: allowed_in_returns + SafeAutoCorrect: false + SupportedStyles: + - allowed_in_returns + - forbidden + +Style/EachForSimpleLoop: + Description: >- + Use `Integer#times` for a simple loop which iterates a fixed + number of times. + Enabled: true + VersionAdded: '0.41' + +Style/EachWithObject: + Description: 'Prefer `each_with_object` over `inject` or `reduce`.' + Enabled: true + VersionAdded: '0.22' + VersionChanged: '0.42' + +Style/EmptyBlockParameter: + Description: 'Omit pipes for empty block parameters.' + Enabled: true + VersionAdded: '0.52' + +Style/EmptyCaseCondition: + Description: 'Avoid empty condition in case statements.' + Enabled: true + VersionAdded: '0.40' + +Style/EmptyElse: + Description: 'Avoid empty else-clauses.' + Enabled: true + AutoCorrect: contextual + VersionAdded: '0.28' + VersionChanged: '1.61' + EnforcedStyle: both + # empty - warn only on empty `else` + # nil - warn on `else` with nil in it + # both - warn on empty `else` and `else` with `nil` in it + SupportedStyles: + - empty + - nil + - both + AllowComments: false + +Style/EmptyHeredoc: + Description: 'Checks for using empty heredoc to reduce redundancy.' + Enabled: pending + AutoCorrect: contextual + VersionAdded: '1.32' + VersionChanged: '1.61' + +Style/EmptyLambdaParameter: + Description: 'Omit parens for empty lambda parameters.' + Enabled: true + VersionAdded: '0.52' + +Style/EmptyLiteral: + Description: 'Prefer literals to Array.new/Hash.new/String.new.' + StyleGuide: '#literal-array-hash' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.12' + +Style/EmptyMethod: + Description: 'Checks the formatting of empty method definitions.' + StyleGuide: '#no-single-line-methods' + Enabled: true + AutoCorrect: contextual + VersionAdded: '0.46' + VersionChanged: '1.61' + EnforcedStyle: compact + SupportedStyles: + - compact + - expanded + +Style/EmptyStringInsideInterpolation: + Description: 'Checks for empty strings being assigned inside string interpolation.' + StyleGuide: '#empty-strings-in-interpolation' + Enabled: pending + EnforcedStyle: trailing_conditional + SupportedStyles: + - trailing_conditional + - ternary + VersionAdded: '1.76' + +Style/Encoding: + Description: 'Use UTF-8 as the source file encoding.' + StyleGuide: '#utf-8' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.50' + +Style/EndBlock: + Description: 'Avoid the use of END blocks.' + StyleGuide: '#no-END-blocks' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.81' + +Style/EndlessMethod: + Description: 'Avoid the use of multi-lined endless method definitions.' + StyleGuide: '#endless-methods' + Enabled: pending + VersionAdded: '1.8' + EnforcedStyle: allow_single_line + SupportedStyles: + - allow_single_line + - allow_always + - disallow + - require_single_line + - require_always + +Style/EnvHome: + Description: "Checks for consistent usage of `ENV['HOME']`." + Enabled: pending + Safe: false + VersionAdded: '1.29' + +Style/EvalWithLocation: + Description: 'Pass `__FILE__` and `__LINE__` to `eval` method, as they are used by backtraces.' + Enabled: true + VersionAdded: '0.52' + +Style/EvenOdd: + Description: 'Favor the use of `Integer#even?` && `Integer#odd?`.' + StyleGuide: '#predicate-methods' + Enabled: true + VersionAdded: '0.12' + VersionChanged: '0.29' + +Style/ExactRegexpMatch: + Description: 'Checks for exact regexp match inside Regexp literals.' + Enabled: pending + VersionAdded: '1.51' + +Style/ExpandPathArguments: + Description: "Use `expand_path(__dir__)` instead of `expand_path('..', __FILE__)`." + Enabled: true + VersionAdded: '0.53' + +Style/ExplicitBlockArgument: + Description: >- + Consider using explicit block argument to avoid writing block literal + that just passes its arguments to another block. + StyleGuide: '#block-argument' + Enabled: true + VersionAdded: '0.89' + VersionChanged: '1.8' + +Style/ExponentialNotation: + Description: 'When using exponential notation, favor a mantissa between 1 (inclusive) and 10 (exclusive).' + StyleGuide: '#exponential-notation' + Enabled: true + VersionAdded: '0.82' + EnforcedStyle: scientific + SupportedStyles: + - scientific + - engineering + - integral + +Style/FetchEnvVar: + Description: >- + Suggests `ENV.fetch` for the replacement of `ENV[]`. + References: + - https://rubystyle.guide/#hash-fetch-defaults + Enabled: pending + VersionAdded: '1.28' + # Environment variables to be excluded from the inspection. + AllowedVars: [] + +Style/FileEmpty: + Description: >- + Prefer to use `File.empty?('path/to/file')` when checking if a file is empty. + Enabled: pending + Safe: false + VersionAdded: '1.48' + +Style/FileNull: + Description: 'Use `File::NULL` instead of hardcoding "dev/null".' + Enabled: pending + SafeAutoCorrect: false + VersionAdded: '1.69' + +Style/FileRead: + Description: 'Favor `File.(bin)read` convenience methods.' + StyleGuide: '#file-read' + Enabled: pending + VersionAdded: '1.24' + +Style/FileTouch: + Description: 'Favor `FileUtils.touch` for touching files.' + Enabled: pending + VersionAdded: '1.69' + SafeAutoCorrect: false + +Style/FileWrite: + Description: 'Favor `File.(bin)write` convenience methods.' + StyleGuide: '#file-write' + Enabled: pending + VersionAdded: '1.24' + +Style/FloatDivision: + Description: 'For performing float division, coerce one side only.' + StyleGuide: '#float-division' + References: + - 'https://blog.rubystyle.guide/ruby/2019/06/21/float-division.html' + Enabled: true + VersionAdded: '0.72' + VersionChanged: '1.9' + Safe: false + EnforcedStyle: single_coerce + SupportedStyles: + - left_coerce + - right_coerce + - single_coerce + - fdiv + +Style/For: + Description: 'Checks use of for or each in multiline loops.' + StyleGuide: '#no-for-loops' + Enabled: true + SafeAutoCorrect: false + VersionAdded: '0.13' + VersionChanged: '1.26' + EnforcedStyle: each + SupportedStyles: + - each + - for + +Style/FormatString: + Description: 'Enforce the use of Kernel#sprintf, Kernel#format or String#%.' + StyleGuide: '#sprintf' + Enabled: true + VersionAdded: '0.19' + VersionChanged: '0.49' + EnforcedStyle: format + SupportedStyles: + - format + - sprintf + - percent + +Style/FormatStringToken: + Description: 'Use a consistent style for format string tokens.' + Enabled: true + EnforcedStyle: annotated + SupportedStyles: + # Prefer tokens which contain a sprintf like type annotation like + # `%s`, `%d`, `%f` + - annotated + # Prefer simple looking "template" style tokens like `%{name}`, `%{age}` + - template + - unannotated + # `MaxUnannotatedPlaceholdersAllowed` defines the number of `unannotated` + # style token in a format string to be allowed when enforced style is not + # `unannotated`. + MaxUnannotatedPlaceholdersAllowed: 1 + # The mode the cop operates in. Two values are allowed: + # * aggressive (default): all strings are considered + # * conservative: + # only register offenses for strings given to `printf`, `sprintf`, + # format` and `%` methods. Other strings are not considered. + Mode: aggressive + VersionAdded: '0.49' + VersionChanged: '1.74' + AllowedMethods: [] + AllowedPatterns: [] + +Style/FrozenStringLiteralComment: + Description: >- + Add the frozen_string_literal comment to the top of files + to help transition to frozen string literals by default. + Enabled: true + VersionAdded: '0.36' + VersionChanged: '0.79' + EnforcedStyle: always + SupportedStyles: + # `always` will always add the frozen string literal comment to a file + # regardless of the Ruby version or if `freeze` or `<<` are called on a + # string literal. It is possible that this will create errors. + - always + # `always_true` will add the frozen string literal comment to a file, + # similarly to the `always` style, but will also change any disabled + # comments (e.g. `# frozen_string_literal: false`) to be enabled. + - always_true + # `never` will enforce that the frozen string literal comment does not + # exist in a file. + - never + SafeAutoCorrect: false + Exclude: + # Prevent the Ruby warning: `'frozen_string_literal' is ignored after any tokens` when using Active Admin. + - '**/*.arb' + +Style/GlobalStdStream: + Description: 'Enforces the use of `$stdout/$stderr/$stdin` instead of `STDOUT/STDERR/STDIN`.' + StyleGuide: '#global-stdout' + Enabled: true + VersionAdded: '0.89' + SafeAutoCorrect: false + +Style/GlobalVars: + Description: 'Do not introduce global variables.' + StyleGuide: '#instance-vars' + References: + - 'https://www.zenspider.com/ruby/quickref.html' + Enabled: true + VersionAdded: '0.13' + # Built-in global variables are allowed by default. + AllowedVariables: [] + +Style/GuardClause: + Description: 'Check for conditionals that can be replaced with guard clauses.' + StyleGuide: '#no-nested-conditionals' + Enabled: true + VersionAdded: '0.20' + VersionChanged: '1.31' + # `MinBodyLength` defines the number of lines of the a body of an `if` or `unless` + # needs to have to trigger this cop + MinBodyLength: 1 + AllowConsecutiveConditionals: false + +Style/HashAsLastArrayItem: + Description: >- + Checks for presence or absence of braces around hash literal as a last + array item depending on configuration. + StyleGuide: '#hash-literal-as-last-array-item' + Enabled: true + VersionAdded: '0.88' + EnforcedStyle: braces + SupportedStyles: + - braces + - no_braces + +Style/HashConversion: + Description: 'Avoid Hash[] in favor of ary.to_h or literal hashes.' + StyleGuide: '#avoid-hash-constructor' + Enabled: pending + SafeAutoCorrect: false + VersionAdded: '1.10' + VersionChanged: '1.55' + AllowSplatArgument: true + +Style/HashEachMethods: + Description: 'Use Hash#each_key and Hash#each_value.' + StyleGuide: '#hash-each' + Enabled: true + Safe: false + VersionAdded: '0.80' + VersionChanged: '1.16' + AllowedReceivers: + - Thread.current + +Style/HashExcept: + Description: >- + Checks for usages of `Hash#reject`, `Hash#select`, and `Hash#filter` methods + that can be replaced with `Hash#except` method. + Enabled: pending + Safe: false + VersionAdded: '1.7' + VersionChanged: '1.39' + +Style/HashFetchChain: + Description: 'Use `Hash#dig` instead of chained `fetch` calls.' + Enabled: pending + Safe: false + VersionAdded: '1.75' + +Style/HashLikeCase: + Description: >- + Checks for places where `case-when` represents a simple 1:1 + mapping and can be replaced with a hash lookup. + Enabled: true + VersionAdded: '0.88' + # `MinBranchesCount` defines the number of branches `case` needs to have + # to trigger this cop + MinBranchesCount: 3 + +Style/HashSlice: + Description: >- + Checks for usages of `Hash#reject`, `Hash#select`, and `Hash#filter` methods + that can be replaced with `Hash#slice` method. + Enabled: pending + Safe: false + VersionAdded: '1.71' + +Style/HashSyntax: + Description: >- + Prefer Ruby 1.9 hash syntax { a: 1, b: 2 } over 1.8 syntax + { :a => 1, :b => 2 }. + StyleGuide: '#hash-literals' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '1.67' + EnforcedStyle: ruby19 + SupportedStyles: + # checks for 1.9 syntax (e.g. {a: 1}) for all symbol keys + - ruby19 + # checks for hash rocket syntax for all hashes + - hash_rockets + # forbids mixed key syntaxes (e.g. {a: 1, :b => 2}) + - no_mixed_keys + # enforces both ruby19 and no_mixed_keys styles + - ruby19_no_mixed_keys + # Force hashes that have a hash value omission + EnforcedShorthandSyntax: either + SupportedShorthandSyntax: + # forces use of the 3.1 syntax (e.g. {foo:}) when the hash key and value are the same. + - always + # forces use of explicit hash literal value. + - never + # accepts both shorthand and explicit use of hash literal value. + - either + # forces use of the 3.1 syntax only if all values can be omitted in the hash. + - consistent + # allow either (implicit or explicit) syntax but enforce consistency within a single hash + - either_consistent + # Force hashes that have a symbol value to use hash rockets + UseHashRocketsWithSymbolValues: false + # Do not suggest { a?: 1 } over { :a? => 1 } in ruby19 style + PreferHashRocketsForNonAlnumEndingSymbols: false + +Style/HashTransformKeys: + Description: 'Prefer `transform_keys` over `each_with_object`, `map`, or `to_h`.' + Enabled: true + VersionAdded: '0.80' + VersionChanged: '0.90' + Safe: false + +Style/HashTransformValues: + Description: 'Prefer `transform_values` over `each_with_object`, `map`, or `to_h`.' + Enabled: true + VersionAdded: '0.80' + VersionChanged: '0.90' + Safe: false + +Style/IdenticalConditionalBranches: + Description: >- + Checks that conditional statements do not have an identical + line at the end of each branch, which can validly be moved + out of the conditional. + Enabled: true + SafeAutoCorrect: false + VersionAdded: '0.36' + VersionChanged: '1.19' + +Style/IfInsideElse: + Description: 'Finds if nodes inside else, which can be converted to elsif.' + Enabled: true + AllowIfModifier: false + VersionAdded: '0.36' + VersionChanged: '1.3' + +Style/IfUnlessModifier: + Description: >- + Favor modifier if/unless usage when you have a + single-line body. + StyleGuide: '#if-as-a-modifier' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.30' + +Style/IfUnlessModifierOfIfUnless: + Description: >- + Avoid modifier if/unless usage on conditionals. + Enabled: true + VersionAdded: '0.39' + VersionChanged: '0.87' + +Style/IfWithBooleanLiteralBranches: + Description: 'Checks for redundant `if` with boolean literal branches.' + Enabled: pending + VersionAdded: '1.9' + SafeAutoCorrect: false + AllowedMethods: + - nonzero? + +Style/IfWithSemicolon: + Description: 'Do not use if x; .... Use the ternary operator instead.' + StyleGuide: '#no-semicolon-ifs' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.83' + +Style/ImplicitRuntimeError: + Description: >- + Use `raise` or `fail` with an explicit exception class and + message, rather than just a message. + Enabled: false + VersionAdded: '0.41' + +Style/InPatternThen: + Description: 'Checks for `in;` uses in `case` expressions.' + StyleGuide: '#no-in-pattern-semicolons' + Enabled: pending + VersionAdded: '1.16' + +Style/InfiniteLoop: + Description: >- + Use Kernel#loop for infinite loops. + This cop is unsafe if the body may raise a `StopIteration` exception. + Safe: false + StyleGuide: '#infinite-loop' + Enabled: true + VersionAdded: '0.26' + VersionChanged: '0.61' + +Style/InlineComment: + Description: 'Avoid trailing inline comments.' + Enabled: false + VersionAdded: '0.23' + +Style/InverseMethods: + Description: >- + Use the inverse method instead of `!.method` + if an inverse method is defined. + Enabled: true + Safe: false + VersionAdded: '0.48' + # `InverseMethods` are methods that can be inverted by a not (`not` or `!`) + # The relationship of inverse methods only needs to be defined in one direction. + # Keys and values both need to be defined as symbols. + InverseMethods: + :any?: :none? + :even?: :odd? + :==: :!= + :=~: :!~ + :<: :>= + :>: :<= + # `InverseBlocks` are methods that are inverted by inverting the return + # of the block that is passed to the method + InverseBlocks: + :select: :reject + :select!: :reject! + +Style/InvertibleUnlessCondition: + Description: 'Favor `if` with inverted condition over `unless`.' + Enabled: false + Safe: false + VersionAdded: '1.44' + VersionChanged: '1.50' + # `InverseMethods` are methods that can be inverted in a `unless` condition. + # The relationship of inverse methods needs to be defined in both directions. + # Keys and values both need to be defined as symbols. + InverseMethods: + :!=: :== + :>: :<= + :<=: :> + :<: :>= + :>=: :< + :!~: :=~ + :zero?: :nonzero? + :nonzero?: :zero? + :any?: :none? + :none?: :any? + :even?: :odd? + :odd?: :even? + +Style/IpAddresses: + Description: "Don't include literal IP addresses in code." + Enabled: false + VersionAdded: '0.58' + VersionChanged: '0.91' + # Allow addresses to be permitted + AllowedAddresses: + - "::" + # :: is a valid IPv6 address, but could potentially be legitimately in code + Exclude: + - '**/*.gemfile' + - '**/Gemfile' + - '**/gems.rb' + - '**/*.gemspec' + +Style/ItAssignment: + Description: 'Checks for assignment to `it` inside a block.' + Enabled: pending + VersionAdded: '1.70' + +Style/ItBlockParameter: + Description: 'Checks for blocks with one argument where `it` block parameter can be used.' + Enabled: pending + EnforcedStyle: allow_single_line + SupportedStyles: + - allow_single_line + - only_numbered_parameters + - always + - disallow + VersionAdded: '1.75' + VersionChanged: '1.76' + +Style/KeywordArgumentsMerging: + Description: >- + When passing an existing hash as keyword arguments, provide additional arguments + directly rather than using `merge`. + StyleGuide: '#merging-keyword-arguments' + Enabled: pending + VersionAdded: '1.68' + +Style/KeywordParametersOrder: + Description: 'Enforces that optional keyword parameters are placed at the end of the parameters list.' + StyleGuide: '#keyword-parameters-order' + Enabled: true + VersionAdded: '0.90' + VersionChanged: '1.7' + +Style/Lambda: + Description: 'Use the new lambda literal syntax for single-line blocks.' + StyleGuide: '#lambda-multi-line' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.40' + EnforcedStyle: line_count_dependent + SupportedStyles: + - line_count_dependent + - lambda + - literal + +Style/LambdaCall: + Description: 'Use lambda.call(...) instead of lambda.(...).' + StyleGuide: '#proc-call' + Enabled: true + VersionAdded: '0.13' + VersionChanged: '0.14' + EnforcedStyle: call + SupportedStyles: + - call + - braces + +Style/LineEndConcatenation: + Description: >- + Use \ instead of + or << to concatenate two string literals at + line end. + Enabled: true + SafeAutoCorrect: false + VersionAdded: '0.18' + VersionChanged: '0.64' + +Style/MagicCommentFormat: + Description: 'Use a consistent style for magic comments.' + Enabled: pending + VersionAdded: '1.35' + EnforcedStyle: snake_case + SupportedStyles: + # `snake` will enforce the magic comment is written + # in snake case (words separated by underscores). + # Eg: froze_string_literal: true + - snake_case + # `kebab` will enforce the magic comment is written + # in kebab case (words separated by hyphens). + # Eg: froze-string-literal: true + - kebab_case + DirectiveCapitalization: lowercase + ValueCapitalization: ~ + SupportedCapitalizations: + - lowercase + - uppercase + +Style/MapCompactWithConditionalBlock: + Description: 'Prefer `select` or `reject` over `map { ... }.compact`.' + Enabled: pending + VersionAdded: '1.30' + +Style/MapIntoArray: + Description: 'Checks for usages of `each` with `<<`, `push`, or `append` which can be replaced by `map`.' + StyleGuide: '#functional-code' + Enabled: pending + VersionAdded: '1.63' + VersionChanged: '1.67' + Safe: false + +Style/MapToHash: + Description: 'Prefer `to_h` with a block over `map.to_h`.' + Enabled: pending + VersionAdded: '1.24' + Safe: false + +Style/MapToSet: + Description: 'Prefer `to_set` with a block over `map.to_set`.' + Enabled: pending + Safe: false + VersionAdded: '1.42' + +Style/MethodCallWithArgsParentheses: + Description: 'Use parentheses for method calls with arguments.' + StyleGuide: '#method-invocation-parens' + Enabled: false + VersionAdded: '0.47' + VersionChanged: '1.7' + IgnoreMacros: true + AllowedMethods: [] + AllowedPatterns: [] + IncludedMacros: [] + AllowParenthesesInMultilineCall: false + AllowParenthesesInChaining: false + AllowParenthesesInCamelCaseMethod: false + AllowParenthesesInStringInterpolation: false + EnforcedStyle: require_parentheses + SupportedStyles: + - require_parentheses + - omit_parentheses + +Style/MethodCallWithoutArgsParentheses: + Description: 'Do not use parentheses for method calls with no arguments.' + StyleGuide: '#method-invocation-parens' + Enabled: true + AllowedMethods: [] + AllowedPatterns: [] + VersionAdded: '0.47' + VersionChanged: '0.55' + +Style/MethodCalledOnDoEndBlock: + Description: 'Avoid chaining a method call on a do...end block.' + StyleGuide: '#single-line-blocks' + Enabled: false + VersionAdded: '0.14' + +Style/MethodDefParentheses: + Description: >- + Checks if the method definitions have or don't have + parentheses. + StyleGuide: '#method-parens' + Enabled: true + VersionAdded: '0.16' + VersionChanged: '1.7' + EnforcedStyle: require_parentheses + SupportedStyles: + - require_parentheses + - require_no_parentheses + - require_no_parentheses_except_multiline + +Style/MinMax: + Description: >- + Use `Enumerable#minmax` instead of `Enumerable#min` + and `Enumerable#max` in conjunction. + Enabled: true + VersionAdded: '0.50' + +Style/MinMaxComparison: + Description: 'Enforces the use of `max` or `min` instead of comparison for greater or less.' + Enabled: pending + Safe: false + VersionAdded: '1.42' + +Style/MissingElse: + Description: >- + Require if/case expressions to have an else branches. + If enabled, it is recommended that + Style/UnlessElse and Style/EmptyElse be enabled. + This will conflict with Style/EmptyElse if + Style/EmptyElse is configured to style "both". + Enabled: false + VersionAdded: '0.30' + VersionChanged: '0.38' + EnforcedStyle: both + SupportedStyles: + # if - warn when an if expression is missing an else branch + # case - warn when a case expression is missing an else branch + # both - warn when an if or case expression is missing an else branch + - if + - case + - both + +Style/MissingRespondToMissing: + Description: >- + Checks if `method_missing` is implemented + without implementing `respond_to_missing`. + StyleGuide: '#no-method-missing' + Enabled: true + VersionAdded: '0.56' + +Style/MixinGrouping: + Description: 'Checks for grouping of mixins in `class` and `module` bodies.' + StyleGuide: '#mixin-grouping' + Enabled: true + VersionAdded: '0.48' + VersionChanged: '0.49' + EnforcedStyle: separated + SupportedStyles: + # separated: each mixed in module goes in a separate statement. + # grouped: mixed in modules are grouped into a single statement. + - separated + - grouped + +Style/MixinUsage: + Description: 'Checks that `include`, `extend` and `prepend` exists at the top level.' + Enabled: true + VersionAdded: '0.51' + +Style/ModuleFunction: + Description: 'Checks for usage of `extend self` in modules.' + StyleGuide: '#module-function' + Enabled: true + VersionAdded: '0.11' + VersionChanged: '0.65' + EnforcedStyle: module_function + SupportedStyles: + - module_function + - extend_self + - forbidden + Autocorrect: false + SafeAutoCorrect: false + +Style/MultilineBlockChain: + Description: 'Avoid multi-line chains of blocks.' + StyleGuide: '#single-line-blocks' + Enabled: true + VersionAdded: '0.13' + +Style/MultilineIfModifier: + Description: 'Only use if/unless modifiers on single line statements.' + StyleGuide: '#no-multiline-if-modifiers' + Enabled: true + VersionAdded: '0.45' + +Style/MultilineIfThen: + Description: 'Do not use then for multi-line if/unless.' + StyleGuide: '#no-then' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.26' + +Style/MultilineInPatternThen: + Description: 'Do not use `then` for multi-line `in` statement.' + StyleGuide: '#no-then' + Enabled: pending + VersionAdded: '1.16' + +Style/MultilineMemoization: + Description: 'Wrap multiline memoizations in a `begin` and `end` block.' + Enabled: true + VersionAdded: '0.44' + VersionChanged: '0.48' + EnforcedStyle: keyword + SupportedStyles: + - keyword + - braces + +Style/MultilineMethodSignature: + Description: 'Avoid multi-line method signatures.' + Enabled: false + VersionAdded: '0.59' + VersionChanged: '1.7' + +Style/MultilineTernaryOperator: + Description: >- + Avoid multi-line ?: (the ternary operator); + use if/unless instead. + StyleGuide: '#no-multiline-ternary' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.86' + +Style/MultilineWhenThen: + Description: 'Do not use then for multi-line when statement.' + StyleGuide: '#no-then' + Enabled: true + VersionAdded: '0.73' + +Style/MultipleComparison: + Description: >- + Avoid comparing a variable with multiple items in a conditional, + use Array#include? instead. + Enabled: true + VersionAdded: '0.49' + VersionChanged: '1.1' + AllowMethodComparison: true + ComparisonsThreshold: 2 + +Style/MutableConstant: + Description: 'Do not assign mutable objects to constants.' + Enabled: true + VersionAdded: '0.34' + VersionChanged: '1.8' + SafeAutoCorrect: false + EnforcedStyle: literals + SupportedStyles: + # literals: freeze literals assigned to constants + # strict: freeze all constants + # Strict mode is considered an experimental feature. It has not been updated + # with an exhaustive list of all methods that will produce frozen objects so + # there is a decent chance of getting some false positives. Luckily, there is + # no harm in freezing an already frozen object. + - literals + - strict + +Style/NegatedIf: + Description: >- + Favor unless over if for negative conditions + (or control flow or). + StyleGuide: '#unless-for-negatives' + Enabled: true + VersionAdded: '0.20' + VersionChanged: '0.48' + EnforcedStyle: both + SupportedStyles: + # both: prefix and postfix negated `if` should both use `unless` + # prefix: only use `unless` for negated `if` statements positioned before the body of the statement + # postfix: only use `unless` for negated `if` statements positioned after the body of the statement + - both + - prefix + - postfix + +Style/NegatedIfElseCondition: + Description: >- + Checks for uses of `if-else` and ternary operators with a negated condition + which can be simplified by inverting condition and swapping branches. + Enabled: pending + VersionAdded: '1.2' + +Style/NegatedUnless: + Description: 'Favor if over unless for negative conditions.' + StyleGuide: '#if-for-negatives' + Enabled: true + VersionAdded: '0.69' + EnforcedStyle: both + SupportedStyles: + # both: prefix and postfix negated `unless` should both use `if` + # prefix: only use `if` for negated `unless` statements positioned before the body of the statement + # postfix: only use `if` for negated `unless` statements positioned after the body of the statement + - both + - prefix + - postfix + +Style/NegatedWhile: + Description: 'Favor until over while for negative conditions.' + StyleGuide: '#until-for-negatives' + Enabled: true + VersionAdded: '0.20' + +Style/NestedFileDirname: + Description: 'Checks for nested `File.dirname`.' + Enabled: pending + VersionAdded: '1.26' + +Style/NestedModifier: + Description: 'Avoid using nested modifiers.' + StyleGuide: '#no-nested-modifiers' + Enabled: true + VersionAdded: '0.35' + +Style/NestedParenthesizedCalls: + Description: >- + Parenthesize method calls which are nested inside the + argument list of another parenthesized method call. + Enabled: true + VersionAdded: '0.36' + VersionChanged: '0.77' + AllowedMethods: + - be + - be_a + - be_an + - be_between + - be_falsey + - be_kind_of + - be_instance_of + - be_truthy + - be_within + - eq + - eql + - end_with + - include + - match + - raise_error + - respond_to + - start_with + +Style/NestedTernaryOperator: + Description: 'Use one expression per branch in a ternary operator.' + StyleGuide: '#no-nested-ternary' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.86' + +Style/Next: + Description: 'Use `next` to skip iteration instead of a condition at the end.' + StyleGuide: '#no-nested-conditionals' + Enabled: true + VersionAdded: '0.22' + VersionChanged: '1.75' + # With `always` all conditions at the end of an iteration needs to be + # replaced by next - with `skip_modifier_ifs` the modifier if like this one + # are ignored: [1, 2].each { |a| return 'yes' if a == 1 } + EnforcedStyle: skip_modifier_ifs + # `MinBodyLength` defines the number of lines of the a body of an `if` or `unless` + # needs to have to trigger this cop + MinBodyLength: 3 + AllowConsecutiveConditionals: false + SupportedStyles: + - skip_modifier_ifs + - always + +Style/NilComparison: + Description: 'Prefer x.nil? to x == nil.' + StyleGuide: '#predicate-methods' + Enabled: true + VersionAdded: '0.12' + VersionChanged: '0.59' + EnforcedStyle: predicate + SupportedStyles: + - predicate + - comparison + +Style/NilLambda: + Description: 'Prefer `-> {}` to `-> { nil }`.' + Enabled: pending + VersionAdded: '1.3' + VersionChanged: '1.15' + +Style/NonNilCheck: + Description: 'Checks for redundant nil checks.' + StyleGuide: '#no-non-nil-checks' + Enabled: true + VersionAdded: '0.20' + VersionChanged: '0.22' + # With `IncludeSemanticChanges` set to `true`, this cop reports offenses for + # `!x.nil?` and autocorrects that and `x != nil` to solely `x`, which is + # **usually** OK, but might change behavior. + # + # With `IncludeSemanticChanges` set to `false`, this cop does not report + # offenses for `!x.nil?` and does no changes that might change behavior. + IncludeSemanticChanges: false + +Style/Not: + Description: 'Use ! instead of not.' + StyleGuide: '#bang-not-not' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.20' + +Style/NumberedParameters: + Description: 'Restrict the usage of numbered parameters.' + Enabled: pending + VersionAdded: '1.22' + EnforcedStyle: allow_single_line + SupportedStyles: + - allow_single_line + - disallow + +Style/NumberedParametersLimit: + Description: 'Avoid excessive numbered params in a single block.' + Enabled: pending + VersionAdded: '1.22' + Max: 1 + +Style/NumericLiteralPrefix: + Description: 'Use smallcase prefixes for numeric literals.' + StyleGuide: '#numeric-literal-prefixes' + Enabled: true + VersionAdded: '0.41' + EnforcedOctalStyle: zero_with_o + SupportedOctalStyles: + - zero_with_o + - zero_only + +Style/NumericLiterals: + Description: >- + Add underscores to large numeric literals to improve their + readability. + StyleGuide: '#underscores-in-numerics' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.48' + MinDigits: 5 + Strict: false + # You can specify allowed numbers. (e.g. port number 3000, 8080, and etc) + AllowedNumbers: [] + AllowedPatterns: [] + +Style/NumericPredicate: + Description: >- + Checks for the use of predicate- or comparison methods for + numeric comparisons. + StyleGuide: '#predicate-methods' + # This will change to a new method call which isn't guaranteed to be on the + # object. Switching these methods has to be done with knowledge of the types + # of the variables which rubocop doesn't have. + Safe: false + Enabled: true + VersionAdded: '0.42' + VersionChanged: '0.59' + EnforcedStyle: predicate + SupportedStyles: + - predicate + - comparison + AllowedMethods: [] + AllowedPatterns: [] + # Exclude RSpec specs because assertions like `expect(1).to be > 0` cause + # false positives. + Exclude: + - 'spec/**/*' + +Style/ObjectThen: + Description: 'Enforces the use of consistent method names `Object#yield_self` or `Object#then`.' + StyleGuide: '#object-yield-self-vs-object-then' + Enabled: pending + VersionAdded: '1.28' + # Use `Object#yield_self` or `Object#then`? + # Prefer `Object#yield_self` to `Object#then` (yield_self) + # Prefer `Object#then` to `Object#yield_self` (then) + EnforcedStyle: 'then' + SupportedStyles: + - then + - yield_self + +Style/OneLineConditional: + Description: >- + Favor the ternary operator (?:) or multi-line constructs over + single-line if/then/else/end constructs. + StyleGuide: '#ternary-operator' + Enabled: true + AlwaysCorrectToMultiline: false + VersionAdded: '0.9' + VersionChanged: '0.90' + +Style/OpenStructUse: + Description: >- + Avoid using OpenStruct. As of Ruby 3.0, use is officially discouraged due to performance, + version compatibility, and potential security issues. + References: + - https://docs.ruby-lang.org/en/3.0/OpenStruct.html#class-OpenStruct-label-Caveats + + Enabled: pending + Safe: false + VersionAdded: '1.23' + VersionChanged: '1.51' + +Style/OperatorMethodCall: + Description: 'Checks for redundant dot before operator method call.' + StyleGuide: '#operator-method-call' + Enabled: pending + VersionAdded: '1.37' + +Style/OptionHash: + Description: "Don't use option hashes when you can use keyword arguments." + StyleGuide: '#keyword-arguments-vs-option-hashes' + Enabled: false + VersionAdded: '0.33' + VersionChanged: '0.34' + # A list of parameter names that will be flagged by this cop. + SuspiciousParamNames: + - options + - opts + - args + - params + - parameters + Allowlist: [] + +Style/OptionalArguments: + Description: >- + Checks for optional arguments that do not appear at the end + of the argument list. + StyleGuide: '#optional-arguments' + Enabled: true + Safe: false + VersionAdded: '0.33' + VersionChanged: '0.83' + +Style/OptionalBooleanParameter: + Description: 'Use keyword arguments when defining method with boolean argument.' + StyleGuide: '#boolean-keyword-arguments' + Enabled: true + Safe: false + VersionAdded: '0.89' + AllowedMethods: + - respond_to_missing? + +Style/OrAssignment: + Description: 'Recommend usage of double pipe equals (||=) where applicable.' + StyleGuide: '#double-pipe-for-uninit' + Enabled: true + VersionAdded: '0.50' + +Style/ParallelAssignment: + Description: >- + Check for simple usages of parallel assignment. + It will only warn when the number of variables + matches on both sides of the assignment. + StyleGuide: '#parallel-assignment' + Enabled: true + VersionAdded: '0.32' + +Style/ParenthesesAroundCondition: + Description: >- + Don't use parentheses around the condition of an + if/unless/while. + StyleGuide: '#no-parens-around-condition' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.56' + AllowSafeAssignment: true + AllowInMultilineConditions: false + +Style/PercentLiteralDelimiters: + Description: 'Use `%`-literal delimiters consistently.' + StyleGuide: '#percent-literal-braces' + Enabled: true + VersionAdded: '0.19' + # Specify the default preferred delimiter for all types with the 'default' key + # Override individual delimiters (even with default specified) by specifying + # an individual key + PreferredDelimiters: + default: () + '%i': '[]' + '%I': '[]' + '%r': '{}' + '%w': '[]' + '%W': '[]' + VersionChanged: '0.48' + +Style/PercentQLiterals: + Description: 'Checks if uses of %Q/%q match the configured preference.' + Enabled: true + VersionAdded: '0.25' + EnforcedStyle: lower_case_q + SupportedStyles: + - lower_case_q # Use `%q` when possible, `%Q` when necessary + - upper_case_q # Always use `%Q` + +Style/PerlBackrefs: + Description: 'Avoid Perl-style regex back references.' + StyleGuide: '#no-perl-regexp-last-matchers' + Enabled: true + VersionAdded: '0.13' + +Style/PreferredHashMethods: + Description: 'Checks use of `has_key?` and `has_value?` Hash methods.' + StyleGuide: '#hash-key' + Enabled: true + Safe: false + VersionAdded: '0.41' + VersionChanged: '0.70' + EnforcedStyle: short + SupportedStyles: + - short + - verbose + +Style/Proc: + Description: 'Use proc instead of Proc.new.' + StyleGuide: '#proc' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.18' + +Style/QuotedSymbols: + Description: 'Use a consistent style for quoted symbols.' + Enabled: pending + VersionAdded: '1.16' + EnforcedStyle: same_as_string_literals + SupportedStyles: + - same_as_string_literals + - single_quotes + - double_quotes + +Style/RaiseArgs: + Description: 'Checks the arguments passed to raise/fail.' + StyleGuide: '#exception-class-messages' + Enabled: true + Safe: false + VersionAdded: '0.14' + VersionChanged: '1.61' + EnforcedStyle: exploded + SupportedStyles: + - compact # raise Exception.new(msg) + - exploded # raise Exception, msg + AllowedCompactTypes: [] + +Style/RandomWithOffset: + Description: >- + Prefer to use ranges when generating random numbers instead of + integers with offsets. + StyleGuide: '#random-numbers' + Enabled: true + VersionAdded: '0.52' + +Style/RedundantArgument: + Description: 'Check for a redundant argument passed to certain methods.' + Enabled: pending + Safe: false + VersionAdded: '1.4' + VersionChanged: '1.55' + Methods: + # Array#join + join: '' + # Array#sum + sum: 0 + # Kernel.#exit + exit: true + # Kernel.#exit! + exit!: false + # String#split + split: ' ' + # String#chomp + chomp: "\n" + # String#chomp! + chomp!: "\n" + +Style/RedundantArrayConstructor: + Description: 'Checks for the instantiation of array using redundant `Array` constructor.' + Enabled: pending + VersionAdded: '1.52' + +Style/RedundantArrayFlatten: + Description: 'Checks for redundant calls of `Array#flatten`.' + Enabled: pending + Safe: false + VersionAdded: '1.76' + +Style/RedundantAssignment: + Description: 'Checks for redundant assignment before returning.' + Enabled: true + VersionAdded: '0.87' + +Style/RedundantBegin: + Description: "Don't use begin blocks when they are not needed." + StyleGuide: '#begin-implicit' + Enabled: true + VersionAdded: '0.10' + VersionChanged: '0.21' + +Style/RedundantCapitalW: + Description: 'Checks for %W when interpolation is not needed.' + Enabled: true + VersionAdded: '0.76' + +Style/RedundantCondition: + Description: 'Checks for unnecessary conditional expressions.' + Enabled: true + VersionAdded: '0.76' + VersionChanged: '1.73' + AllowedMethods: + - nonzero? + +Style/RedundantConditional: + Description: "Don't return true/false from a conditional." + Enabled: true + VersionAdded: '0.50' + +Style/RedundantConstantBase: + Description: Avoid redundant `::` prefix on constant. + Enabled: pending + VersionAdded: '1.40' + +Style/RedundantCurrentDirectoryInPath: + Description: 'Checks for a redundant current directory in a path given to `require_relative`.' + Enabled: pending + VersionAdded: '1.53' + +Style/RedundantDoubleSplatHashBraces: + Description: 'Checks for redundant uses of double splat hash braces.' + Enabled: pending + VersionAdded: '1.41' + +Style/RedundantEach: + Description: 'Checks for redundant `each`.' + Enabled: pending + Safe: false + VersionAdded: '1.38' + +Style/RedundantException: + Description: "Checks for an obsolete RuntimeException argument in raise/fail." + StyleGuide: '#no-explicit-runtimeerror' + Enabled: true + VersionAdded: '0.14' + VersionChanged: '0.29' + +Style/RedundantFetchBlock: + Description: >- + Use `fetch(key, value)` instead of `fetch(key) { value }` + when value has Numeric, Rational, Complex, Symbol or String type, `false`, `true`, `nil` or is a constant. + References: + - 'https://github.com/fastruby/fast-ruby#hashfetch-with-argument-vs-hashfetch--block-code' + Enabled: true + Safe: false + # If enabled, this cop will autocorrect usages of + # `fetch` being called with block returning a constant. + # This can be dangerous since constants will not be defined at that moment. + SafeForConstants: false + VersionAdded: '0.86' + +Style/RedundantFileExtensionInRequire: + Description: >- + Checks for the presence of superfluous `.rb` extension in + the filename provided to `require` and `require_relative`. + StyleGuide: '#no-explicit-rb-to-require' + Enabled: true + VersionAdded: '0.88' + +Style/RedundantFilterChain: + Description: >- + Identifies usages of `any?`, `empty?`, `none?` or `one?` predicate methods chained to + `select`/`filter`/`find_all` and change them to use predicate method instead. + Enabled: pending + SafeAutoCorrect: false + VersionAdded: '1.52' + VersionChanged: '1.57' + +Style/RedundantFormat: + Description: 'Checks for usages of `Kernel#format` or `Kernel#sprintf` with only a single argument.' + Enabled: pending + SafeAutoCorrect: false + VersionAdded: '1.72' + VersionChanged: '1.72' + +Style/RedundantFreeze: + Description: "Checks usages of Object#freeze on immutable objects." + Enabled: true + VersionAdded: '0.34' + VersionChanged: '0.66' + +Style/RedundantHeredocDelimiterQuotes: + Description: 'Checks for redundant heredoc delimiter quotes.' + Enabled: pending + VersionAdded: '1.45' + +Style/RedundantInitialize: + Description: 'Checks for redundant `initialize` methods.' + Enabled: pending + AutoCorrect: contextual + Safe: false + AllowComments: true + VersionAdded: '1.27' + VersionChanged: '1.61' + +Style/RedundantInterpolation: + Description: 'Checks for strings that are just an interpolated expression.' + Enabled: true + SafeAutoCorrect: false + VersionAdded: '0.76' + VersionChanged: '1.30' + +Style/RedundantInterpolationUnfreeze: + Description: 'Checks for redundant unfreezing of interpolated strings.' + Enabled: pending + VersionAdded: '1.66' + +Style/RedundantLineContinuation: + Description: 'Check for redundant line continuation.' + Enabled: pending + VersionAdded: '1.49' + +Style/RedundantParentheses: + Description: "Checks for parentheses that seem not to serve any purpose." + Enabled: true + VersionAdded: '0.36' + +Style/RedundantPercentQ: + Description: 'Checks for %q/%Q when single quotes or double quotes would do.' + StyleGuide: '#percent-q' + Enabled: true + VersionAdded: '0.76' + +Style/RedundantRegexpArgument: + Description: 'Identifies places where argument can be replaced from a deterministic regexp to a string.' + Enabled: pending + VersionAdded: '1.53' + +Style/RedundantRegexpCharacterClass: + Description: 'Checks for unnecessary single-element Regexp character classes.' + Enabled: true + VersionAdded: '0.85' + +Style/RedundantRegexpConstructor: + Description: 'Checks for the instantiation of regexp using redundant `Regexp.new` or `Regexp.compile`.' + Enabled: pending + VersionAdded: '1.52' + +Style/RedundantRegexpEscape: + Description: 'Checks for redundant escapes in Regexps.' + Enabled: true + VersionAdded: '0.85' + +Style/RedundantReturn: + Description: "Don't use return where it's not required." + StyleGuide: '#no-explicit-return' + Enabled: true + VersionAdded: '0.10' + VersionChanged: '0.14' + # When `true` allows code like `return x, y`. + AllowMultipleReturnValues: false + +Style/RedundantSelf: + Description: "Don't use self where it's not needed." + StyleGuide: '#no-self-unless-required' + Enabled: true + VersionAdded: '0.10' + VersionChanged: '0.13' + +Style/RedundantSelfAssignment: + Description: 'Checks for places where redundant assignments are made for in place modification methods.' + Enabled: true + Safe: false + VersionAdded: '0.90' + +Style/RedundantSelfAssignmentBranch: + Description: 'Checks for places where conditional branch makes redundant self-assignment.' + Enabled: pending + VersionAdded: '1.19' + +Style/RedundantSort: + Description: >- + Use `min` instead of `sort.first`, + `max_by` instead of `sort_by...last`, etc. + Enabled: true + VersionAdded: '0.76' + VersionChanged: '1.22' + Safe: false + +Style/RedundantSortBy: + Description: 'Use `sort` instead of `sort_by { |x| x }`.' + Enabled: true + VersionAdded: '0.36' + +Style/RedundantStringEscape: + Description: 'Checks for redundant escapes in string literals.' + Enabled: pending + VersionAdded: '1.37' + +Style/RegexpLiteral: + Description: 'Use / or %r around regular expressions.' + StyleGuide: '#percent-r' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.30' + EnforcedStyle: slashes + # slashes: Always use slashes. + # percent_r: Always use `%r`. + # mixed: Use slashes on single-line regexes, and `%r` on multi-line regexes. + SupportedStyles: + - slashes + - percent_r + - mixed + # If `false`, the cop will always recommend using `%r` if one or more slashes + # are found in the regexp string. + AllowInnerSlashes: false + +Style/RequireOrder: + Description: Sort `require` and `require_relative` in alphabetical order. + Enabled: false + SafeAutoCorrect: false + VersionAdded: '1.40' + +Style/RescueModifier: + Description: 'Avoid using rescue in its modifier form.' + StyleGuide: '#no-rescue-modifiers' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.34' + +Style/RescueStandardError: + Description: 'Avoid rescuing without specifying an error class.' + Enabled: true + VersionAdded: '0.52' + EnforcedStyle: explicit + # implicit: Do not include the error class, `rescue` + # explicit: Require an error class `rescue StandardError` + SupportedStyles: + - implicit + - explicit + +Style/ReturnNil: + Description: 'Use return instead of return nil.' + Enabled: false + EnforcedStyle: return + SupportedStyles: + - return + - return_nil + VersionAdded: '0.50' + +Style/ReturnNilInPredicateMethodDefinition: + Description: 'Checks if uses of `return` or `return nil` in predicate method definition.' + StyleGuide: '#bool-methods-qmark' + Enabled: pending + SafeAutoCorrect: false + AllowedMethods: [] + AllowedPatterns: [] + VersionAdded: '1.53' + VersionChanged: '1.67' + +Style/SafeNavigation: + Description: >- + Transforms usages of a method call safeguarded by + a check for the existence of the object to + safe navigation (`&.`). + Autocorrection is unsafe as it assumes the object will + be `nil` or truthy, but never `false`. + Enabled: true + VersionAdded: '0.43' + VersionChanged: '1.67' + # Safe navigation may cause a statement to start returning `nil` in addition + # to whatever it used to return. + ConvertCodeThatCanStartToReturnNil: false + AllowedMethods: + - present? + - blank? + - presence + - try + - try! + SafeAutoCorrect: false + # Maximum length of method chains for register an offense. + MaxChainLength: 2 + +Style/SafeNavigationChainLength: + Description: 'Enforces safe navigation chains length to not exceed the configured maximum.' + StyleGuide: '#safe-navigation' + Enabled: pending + VersionAdded: '1.68' + Max: 2 + +Style/Sample: + Description: >- + Use `sample` instead of `shuffle.first`, + `shuffle.last`, and `shuffle[Integer]`. + References: + - 'https://github.com/fastruby/fast-ruby#arrayshufflefirst-vs-arraysample-code' + Enabled: true + VersionAdded: '0.30' + +Style/SelectByRegexp: + Description: 'Prefer grep/grep_v to select/reject with a regexp match.' + Enabled: pending + SafeAutoCorrect: false + VersionAdded: '1.22' + +Style/SelfAssignment: + Description: >- + Checks for places where self-assignment shorthand should have + been used. + StyleGuide: '#self-assignment' + Enabled: true + VersionAdded: '0.19' + VersionChanged: '0.29' + +Style/Semicolon: + Description: "Don't use semicolons to terminate expressions." + StyleGuide: '#no-semicolon' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.19' + # Allow `;` to separate several expressions on the same line. + AllowAsExpressionSeparator: false + +Style/Send: + Description: 'Prefer `Object#__send__` or `Object#public_send` to `send`, as `send` may overlap with existing methods.' + StyleGuide: '#prefer-public-send' + Enabled: false + VersionAdded: '0.33' + +Style/SendWithLiteralMethodName: + Description: 'Detects the use of the `public_send` method with a static method name argument.' + Enabled: pending + Safe: false + AllowSend: true + VersionAdded: '1.64' + +Style/SignalException: + Description: 'Checks for proper usage of fail and raise.' + StyleGuide: '#prefer-raise-over-fail' + Enabled: true + VersionAdded: '0.11' + VersionChanged: '0.37' + EnforcedStyle: only_raise + SupportedStyles: + - only_raise + - only_fail + - semantic + +Style/SingleArgumentDig: + Description: 'Avoid using single argument dig method.' + Enabled: true + VersionAdded: '0.89' + Safe: false + +Style/SingleLineBlockParams: + Description: 'Enforces the names of some block params.' + Enabled: false + VersionAdded: '0.16' + VersionChanged: '1.6' + Methods: + - reduce: + - acc + - elem + - inject: + - acc + - elem + +Style/SingleLineDoEndBlock: + Description: 'Checks for single-line `do`...`end` blocks.' + StyleGuide: '#single-line-do-end-block' + Enabled: pending + VersionAdded: '1.57' + +Style/SingleLineMethods: + Description: 'Avoid single-line methods.' + StyleGuide: '#no-single-line-methods' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '1.8' + AllowIfMethodIsEmpty: true + +Style/SlicingWithRange: + Description: 'Checks array slicing is done with redundant, endless, and beginless ranges when suitable.' + StyleGuide: '#slicing-with-ranges' + Enabled: true + VersionAdded: '0.83' + Safe: false + +Style/SoleNestedConditional: + Description: >- + Finds sole nested conditional nodes + which can be merged into outer conditional node. + Enabled: true + VersionAdded: '0.89' + VersionChanged: '1.5' + AllowModifier: false + +Style/SpecialGlobalVars: + Description: 'Avoid Perl-style global variables.' + StyleGuide: '#no-cryptic-perlisms' + Enabled: true + VersionAdded: '0.13' + VersionChanged: '0.36' + SafeAutoCorrect: false + RequireEnglish: true + EnforcedStyle: use_english_names + SupportedStyles: + - use_perl_names + - use_english_names + - use_builtin_english_names + +Style/StabbyLambdaParentheses: + Description: 'Check for the usage of parentheses around stabby lambda arguments.' + StyleGuide: '#stabby-lambda-with-args' + Enabled: true + VersionAdded: '0.35' + EnforcedStyle: require_parentheses + SupportedStyles: + - require_parentheses + - require_no_parentheses + +Style/StaticClass: + Description: 'Prefer modules to classes with only class methods.' + StyleGuide: '#modules-vs-classes' + Enabled: false + Safe: false + VersionAdded: '1.3' + +Style/StderrPuts: + Description: 'Use `warn` instead of `$stderr.puts`.' + StyleGuide: '#warn' + Enabled: true + VersionAdded: '0.51' + +Style/StringChars: + Description: 'Checks for uses of `String#split` with empty string or regexp literal argument.' + StyleGuide: '#string-chars' + Enabled: pending + Safe: false + VersionAdded: '1.12' + +Style/StringConcatenation: + Description: 'Checks for places where string concatenation can be replaced with string interpolation.' + StyleGuide: '#string-interpolation' + Enabled: true + Safe: false + VersionAdded: '0.89' + VersionChanged: '1.18' + Mode: aggressive + +Style/StringHashKeys: + Description: 'Prefer symbols instead of strings as hash keys.' + StyleGuide: '#symbols-as-keys' + Enabled: false + VersionAdded: '0.52' + VersionChanged: '0.75' + Safe: false + +Style/StringLiterals: + Description: 'Checks if uses of quotes match the configured preference.' + StyleGuide: '#consistent-string-literals' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.36' + EnforcedStyle: single_quotes + SupportedStyles: + - single_quotes + - double_quotes + # If `true`, strings which span multiple lines using `\` for continuation must + # use the same type of quotes on each line. + ConsistentQuotesInMultiline: false + +Style/StringLiteralsInInterpolation: + Description: >- + Checks if uses of quotes inside expressions in interpolated + strings match the configured preference. + Enabled: true + VersionAdded: '0.27' + EnforcedStyle: single_quotes + SupportedStyles: + - single_quotes + - double_quotes + +Style/StringMethods: + Description: 'Checks if configured preferred methods are used over non-preferred.' + Enabled: false + VersionAdded: '0.34' + VersionChanged: '0.34' + # Mapping from undesired method to desired_method + # e.g. to use `to_sym` over `intern`: + # + # StringMethods: + # PreferredMethods: + # intern: to_sym + PreferredMethods: + intern: to_sym + +Style/Strip: + Description: 'Use `strip` instead of `lstrip.rstrip`.' + Enabled: true + VersionAdded: '0.36' + +Style/StructInheritance: + Description: 'Checks for inheritance from Struct.new.' + StyleGuide: '#no-extend-struct-new' + Enabled: true + SafeAutoCorrect: false + VersionAdded: '0.29' + VersionChanged: '1.20' + +Style/SuperArguments: + Description: 'Call `super` without arguments and parentheses when the signature is identical.' + Enabled: pending + VersionAdded: '1.64' + +Style/SuperWithArgsParentheses: + Description: 'Use parentheses for `super` with arguments.' + StyleGuide: '#super-with-args' + Enabled: pending + VersionAdded: '1.58' + +Style/SwapValues: + Description: 'Enforces the use of shorthand-style swapping of 2 variables.' + StyleGuide: '#values-swapping' + Enabled: pending + VersionAdded: '1.1' + SafeAutoCorrect: false + +Style/SymbolArray: + Description: 'Use %i or %I for arrays of symbols.' + StyleGuide: '#percent-i' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.49' + EnforcedStyle: percent + MinSize: 2 + SupportedStyles: + - percent + - brackets + +Style/SymbolLiteral: + Description: 'Use plain symbols instead of string symbols when possible.' + Enabled: true + VersionAdded: '0.30' + +Style/SymbolProc: + Description: 'Use symbols as procs instead of blocks when possible.' + Enabled: true + Safe: false + VersionAdded: '0.26' + VersionChanged: '1.64' + AllowMethodsWithArguments: false + # A list of method names to be always allowed by the check. + # The names should be fairly unique, otherwise you'll end up ignoring lots of code. + AllowedMethods: + - define_method + AllowedPatterns: [] + AllowComments: false + +Style/TernaryParentheses: + Description: 'Checks for use of parentheses around ternary conditions.' + Enabled: true + VersionAdded: '0.42' + VersionChanged: '0.46' + EnforcedStyle: require_no_parentheses + SupportedStyles: + - require_parentheses + - require_no_parentheses + - require_parentheses_when_complex + AllowSafeAssignment: true + +Style/TopLevelMethodDefinition: + Description: 'Looks for top-level method definitions.' + StyleGuide: '#top-level-methods' + Enabled: false + VersionAdded: '1.15' + +Style/TrailingBodyOnClass: + Description: 'Class body goes below class statement.' + Enabled: true + VersionAdded: '0.53' + +Style/TrailingBodyOnMethodDefinition: + Description: 'Method body goes below definition.' + Enabled: true + VersionAdded: '0.52' + +Style/TrailingBodyOnModule: + Description: 'Module body goes below module statement.' + Enabled: true + VersionAdded: '0.53' + +Style/TrailingCommaInArguments: + Description: 'Checks for trailing comma in argument lists.' + StyleGuide: '#no-trailing-params-comma' + Enabled: true + VersionAdded: '0.36' + # If `comma`, the cop requires a comma after the last argument, but only for + # parenthesized method calls where each argument is on its own line. + # If `consistent_comma`, the cop requires a comma after the last argument, + # for all parenthesized method calls with arguments. + EnforcedStyleForMultiline: no_comma + SupportedStylesForMultiline: + - comma + - consistent_comma + - no_comma + +Style/TrailingCommaInArrayLiteral: + Description: 'Checks for trailing comma in array literals.' + StyleGuide: '#no-trailing-array-commas' + Enabled: true + VersionAdded: '0.53' + # If `comma`, the cop requires a comma after the last item in an array, but only when each item is + # on its own line. + # If `consistent_comma`, the cop requires a comma after the last item of all non-empty, multiline + # array literals. + # If `diff_comma`, the cop requires a comma after the last item of all non-empty, multiline array + # literals, but only when that last item immediately precedes a newline. + EnforcedStyleForMultiline: no_comma + SupportedStylesForMultiline: + - comma + - consistent_comma + - diff_comma + - no_comma + +Style/TrailingCommaInBlockArgs: + Description: 'Checks for useless trailing commas in block arguments.' + Enabled: false + Safe: false + VersionAdded: '0.81' + +Style/TrailingCommaInHashLiteral: + Description: 'Checks for trailing comma in hash literals.' + Enabled: true + # If `comma`, the cop requires a comma after the last item in a hash, but only when each item is + # on its own line. + # If `consistent_comma`, the cop requires a comma after the last item of all non-empty, multiline + # hash literals. + # If `diff_comma`, the cop requires a comma after the last item of all non-empty, multiline hash + # literals, but only when that last item immediately precedes a newline. + EnforcedStyleForMultiline: no_comma + SupportedStylesForMultiline: + - comma + - consistent_comma + - diff_comma + - no_comma + VersionAdded: '0.53' + +Style/TrailingMethodEndStatement: + Description: 'Checks for trailing end statement on line of method body.' + Enabled: true + VersionAdded: '0.52' + +Style/TrailingUnderscoreVariable: + Description: >- + Checks for the usage of unneeded trailing underscores at the + end of parallel variable assignment. + AllowNamedUnderscoreVariables: true + Enabled: true + VersionAdded: '0.31' + VersionChanged: '0.35' + +# `TrivialAccessors` requires exact name matches and doesn't allow +# predicated methods by default. +Style/TrivialAccessors: + Description: 'Prefer attr_* methods to trivial readers/writers.' + StyleGuide: '#attr_family' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '1.15' + # When set to `false` the cop will suggest the use of accessor methods + # in situations like: + # + # def name + # @other_name + # end + # + # This way you can uncover "hidden" attributes in your code. + ExactNameMatch: true + AllowPredicates: true + # Allows trivial writers that don't end in an equal sign. e.g. + # + # def on_exception(action) + # @on_exception=action + # end + # on_exception :restart + # + # Commonly used in DSLs + AllowDSLWriters: true + IgnoreClassMethods: false + AllowedMethods: + - to_ary + - to_a + - to_c + - to_enum + - to_h + - to_hash + - to_i + - to_int + - to_io + - to_open + - to_path + - to_proc + - to_r + - to_regexp + - to_str + - to_s + - to_sym + +Style/UnlessElse: + Description: >- + Do not use unless with else. Rewrite these with the positive + case first. + StyleGuide: '#no-else-with-unless' + Enabled: true + VersionAdded: '0.9' + +Style/UnlessLogicalOperators: + Description: >- + Checks for use of logical operators in an unless condition. + Enabled: false + VersionAdded: '1.11' + EnforcedStyle: forbid_mixed_logical_operators + SupportedStyles: + - forbid_mixed_logical_operators + - forbid_logical_operators + +Style/UnpackFirst: + Description: >- + Checks for accessing the first element of `String#unpack` + instead of using `unpack1`. + Enabled: true + VersionAdded: '0.54' + +Style/VariableInterpolation: + Description: >- + Don't interpolate global, instance and class variables + directly in strings. + StyleGuide: '#curlies-interpolate' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.20' + +Style/WhenThen: + Description: 'Use when x then ... for one-line cases.' + StyleGuide: '#no-when-semicolons' + Enabled: true + VersionAdded: '0.9' + +Style/WhileUntilDo: + Description: 'Checks for redundant do after while or until.' + StyleGuide: '#no-multiline-while-do' + Enabled: true + VersionAdded: '0.9' + +Style/WhileUntilModifier: + Description: >- + Favor modifier while/until usage when you have a + single-line body. + StyleGuide: '#while-as-a-modifier' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '0.30' + +Style/WordArray: + Description: 'Use %w or %W for arrays of words.' + StyleGuide: '#percent-w' + Enabled: true + VersionAdded: '0.9' + VersionChanged: '1.19' + EnforcedStyle: percent + SupportedStyles: + # percent style: %w(word1 word2) + - percent + # bracket style: ['word1', 'word2'] + - brackets + # The `MinSize` option causes the `WordArray` rule to be ignored for arrays + # smaller than a certain size. The rule is only applied to arrays + # whose element count is greater than or equal to `MinSize`. + MinSize: 2 + # The regular expression `WordRegex` decides what is considered a word. + WordRegex: !ruby/regexp '/\A(?:\p{Word}|\p{Word}-\p{Word}|\n|\t)+\z/' + +Style/YAMLFileRead: + Description: 'Checks for the use of `YAML.load`, `YAML.safe_load`, and `YAML.parse` with `File.read` argument.' + Enabled: pending + VersionAdded: '1.53' + +Style/YodaCondition: + Description: 'Forbid or enforce yoda conditions.' + References: + - 'https://en.wikipedia.org/wiki/Yoda_conditions' + Enabled: true + EnforcedStyle: forbid_for_all_comparison_operators + SupportedStyles: + # check all comparison operators + - forbid_for_all_comparison_operators + # check only equality operators: `!=` and `==` + - forbid_for_equality_operators_only + # enforce yoda for all comparison operators + - require_for_all_comparison_operators + # enforce yoda only for equality operators: `!=` and `==` + - require_for_equality_operators_only + Safe: false + VersionAdded: '0.49' + VersionChanged: '0.75' + +Style/YodaExpression: + Description: 'Forbid the use of yoda expressions.' + Enabled: false + Safe: false + VersionAdded: '1.42' + VersionChanged: '1.43' + SupportedOperators: + - '*' + - '+' + - '&' + - '|' + - '^' + +Style/ZeroLengthPredicate: + Description: 'Use #empty? when testing for objects of length 0.' + Enabled: true + Safe: false + VersionAdded: '0.37' + VersionChanged: '0.39' diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/config/internal_affairs.yml b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/config/internal_affairs.yml new file mode 100644 index 00000000..cfff30cf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/config/internal_affairs.yml @@ -0,0 +1,31 @@ +# Configuration for InternalAffairs cops. This file will be +# automatically loaded when `rubocop/cop/internal_affairs` is required. +# Only do this when developing custom cops or a RuboCop extension. + +InternalAffairs/CopDescription: + Include: + - 'lib/rubocop/cop/**/*.rb' + +InternalAffairs/ExampleHeredocDelimiter: + Include: + - 'spec/rubocop/cop/**/*.rb' + +InternalAffairs/ExampleDescription: + Include: + - 'spec/rubocop/cop/**/*.rb' + +InternalAffairs/NodeTypeGroup: + Include: + - 'lib/rubocop/cop/**/*.rb' + +InternalAffairs/OnSendWithoutOnCSend: + Include: + - 'lib/rubocop/cop/**/*.rb' + +InternalAffairs/UndefinedConfig: + Include: + - 'lib/rubocop/cop/**/*.rb' + +InternalAffairs/UselessMessageAssertion: + Include: + - '**/*_spec.rb' diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/config/obsoletion.yml b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/config/obsoletion.yml new file mode 100644 index 00000000..a86e213d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/config/obsoletion.yml @@ -0,0 +1,243 @@ +# Configuration of obsolete/deprecated cops used by `ConfigObsoletion` + +# Cops that were renamed +renamed: + Layout/AlignArguments: Layout/ArgumentAlignment + Layout/AlignArray: Layout/ArrayAlignment + Layout/AlignHash: Layout/HashAlignment + Layout/AlignParameters: Layout/ParameterAlignment + Layout/IndentArray: Layout/FirstArrayElementIndentation + Layout/IndentAssignment: Layout/AssignmentIndentation + Layout/IndentFirstArgument: Layout/FirstArgumentIndentation + Layout/IndentFirstArrayElement: Layout/FirstArrayElementIndentation + Layout/IndentFirstHashElement: Layout/FirstHashElementIndentation + Layout/IndentFirstParameter: Layout/FirstParameterIndentation + Layout/IndentHash: Layout/FirstHashElementIndentation + Layout/IndentHeredoc: Layout/HeredocIndentation + Layout/LeadingBlankLines: Layout/LeadingEmptyLines + Layout/Tab: Layout/IndentationStyle + Layout/TrailingBlankLines: Layout/TrailingEmptyLines + Lint/BlockAlignment: Layout/BlockAlignment + Lint/DefEndAlignment: Layout/DefEndAlignment + Lint/DuplicatedKey: Lint/DuplicateHashKey + Lint/EndAlignment: Layout/EndAlignment + Lint/EndInMethod: Style/EndBlock + Lint/Eval: Security/Eval + Lint/HandleExceptions: Lint/SuppressedException + Lint/MultipleCompare: Lint/MultipleComparison + Lint/StringConversionInInterpolation: Lint/RedundantStringCoercion + Lint/UnneededCopDisableDirective: Lint/RedundantCopDisableDirective + Lint/UnneededCopEnableDirective: Lint/RedundantCopEnableDirective + Lint/UnneededRequireStatement: Lint/RedundantRequireStatement + Lint/UnneededSplatExpansion: Lint/RedundantSplatExpansion + Metrics/LineLength: Layout/LineLength + Naming/PredicateName: + new_name: Naming/PredicatePrefix + severity: warning + Naming/UncommunicativeBlockParamName: Naming/BlockParameterName + Naming/UncommunicativeMethodParamName: Naming/MethodParameterName + Style/AccessorMethodName: Naming/AccessorMethodName + Style/AsciiIdentifiers: Naming/AsciiIdentifiers + Style/ClassAndModuleCamelCase: Naming/ClassAndModuleCamelCase + Style/ConstantName: Naming/ConstantName + Style/DeprecatedHashMethods: Style/PreferredHashMethods + Style/FileName: Naming/FileName + Style/FlipFlop: Lint/FlipFlop + Style/MethodCallParentheses: Style/MethodCallWithoutArgsParentheses + Style/MethodName: Naming/MethodName + Style/OpMethod: Naming/BinaryOperatorParameterName + Style/PredicateName: + new_name: Naming/PredicatePrefix + severity: warning + Style/SingleSpaceBeforeFirstArg: Layout/SpaceBeforeFirstArg + Style/UnneededCapitalW: Style/RedundantCapitalW + Style/UnneededCondition: Style/RedundantCondition + Style/UnneededInterpolation: Style/RedundantInterpolation + Style/UnneededPercentQ: Style/RedundantPercentQ + Style/UnneededSort: Style/RedundantSort + Style/VariableName: Naming/VariableName + Style/VariableNumber: Naming/VariableNumber + +# Cops that were removed +removed: + Gemspec/DateAssignment: + alternatives: Gemspec/DeprecatedAttributeAssignment + Layout/SpaceAfterControlKeyword: + alternatives: Layout/SpaceAroundKeyword + Layout/SpaceBeforeModifierKeyword: + alternatives: Layout/SpaceAroundKeyword + Lint/InvalidCharacterLiteral: + reason: it was never being actually triggered + Lint/RescueWithoutErrorClass: + alternatives: Style/RescueStandardError + Lint/SpaceBeforeFirstArg: + reason: > + it was a duplicate of `Layout/SpaceBeforeFirstArg`. Please use + `Layout/SpaceBeforeFirstArg` instead + Lint/UselessComparison: + reason: > + it has been superseded by + `Lint/BinaryOperatorWithIdenticalOperands`. Please use + `Lint/BinaryOperatorWithIdenticalOperands` instead + Style/BracesAroundHashParameters: true + Style/MethodMissingSuper: + reason: > + it has been superseded by `Lint/MissingSuper`. Please use + `Lint/MissingSuper` instead + Style/SpaceAfterControlKeyword: + alternatives: Layout/SpaceAroundKeyword + Style/SpaceBeforeModifierKeyword: + alternatives: Layout/SpaceAroundKeyword + Style/TrailingComma: + alternatives: + - Style/TrailingCommaInArguments + - Style/TrailingCommaInArrayLiteral + - Style/TrailingCommaInHashLiteral + Style/TrailingCommaInLiteral: + alternatives: + - Style/TrailingCommaInArrayLiteral + - Style/TrailingCommaInHashLiteral + +# Cops split into multiple other cops +split: + Style/MethodMissing: + alternatives: + - Style/MethodMissingSuper + - Style/MissingRespondToMissing + +# Cops that were extracted into a different gem +extracted: + Performance/*: rubocop-performance + Rails/*: rubocop-rails + +# Cop parameters that have been changed +# Can be treated as a warning instead of a failure with `severity: warning` +changed_parameters: + - cops: + - Layout/SpaceAroundOperators + - Style/SpaceAroundOperators + parameters: MultiSpaceAllowedForOperators + reason: > + If your intention was to allow extra spaces for alignment, please + use `AllowForAlignment: true` instead. + - cops: Style/Encoding + parameters: + - EnforcedStyle + - SupportedStyles + - AutoCorrectEncodingComment + reason: '`Style/Encoding` no longer supports styles. The "never" behavior is always assumed.' + - cops: Style/IfUnlessModifier + parameters: MaxLineLength + reason: > + `Style/IfUnlessModifier: MaxLineLength` has been removed. + Use `Layout/LineLength: Max` instead + - cops: Style/WhileUntilModifier + parameters: MaxLineLength + reason: > + `Style/WhileUntilModifier: MaxLineLength` has been removed. + Use `Layout/LineLength: Max` instead + - cops: AllCops + parameters: RunRailsCops + reason: |- + Use the following configuration instead: + Rails: + Enabled: true + - cops: Layout/CaseIndentation + parameters: IndentWhenRelativeTo + alternative: EnforcedStyle + - cops: + - Lint/BlockAlignment + - Layout/BlockAlignment + - Lint/EndAlignment + - Layout/EndAlignment + - Lint/DefEndAlignment + - Layout/DefEndAlignment + parameters: AlignWith + alternative: EnforcedStyleAlignWith + - cops: Rails/UniqBeforePluck + parameters: EnforcedMode + alternative: EnforcedStyle + - cops: Style/MethodCallWithArgsParentheses + parameters: IgnoredMethodPatterns + alternative: AllowedPatterns + - cops: + - Performance/Count + - Performance/Detect + parameters: SafeMode + reason: "`SafeMode` has been removed. Use `SafeAutoCorrect` instead." + - cops: Bundler/GemComment + parameters: Whitelist + alternative: IgnoredGems + - cops: + - Lint/SafeNavigationChain + - Lint/SafeNavigationConsistency + - Style/NestedParenthesizedCalls + - Style/SafeNavigation + - Style/TrivialAccessors + parameters: Whitelist + alternative: AllowedMethods + - cops: Style/IpAddresses + parameters: Whitelist + alternative: AllowedAddresses + - cops: Naming/HeredocDelimiterNaming + parameters: Blacklist + alternative: ForbiddenDelimiters + - cops: Naming/PredicatePrefix + parameters: NamePrefixBlacklist + alternative: ForbiddenPrefixes + - cops: Naming/PredicatePrefix + parameters: NameWhitelist + alternative: AllowedMethods + - cops: + - Metrics/BlockLength + - Metrics/MethodLength + parameters: ExcludedMethods + alternatives: + - AllowedMethods + - AllowedPatterns + severity: warning + - cops: Lint/Debugger + parameters: DebuggerReceivers + reason: "`DebuggerReceivers` is no longer necessary, method receivers should be specified in `DebuggerMethods` instead." + severity: warning + - cops: + - Layout/IndentationWidth + - Layout/LineLength + - Lint/UnreachableLoop + - Naming/MethodName + - Style/MethodCallWithArgsParentheses + parameters: IgnoredPatterns + alternative: AllowedPatterns + severity: warning + - cops: + - Lint/AmbiguousBlockAssociation + - Lint/NumberConversion + - Metrics/AbcSize + - Metrics/BlockLength + - Metrics/CyclomaticComplexity + - Metrics/MethodLength + - Metrics/PerceivedComplexity + - Style/BlockDelimiters + - Style/ClassEqualityComparison + - Style/FormatStringToken + - Style/MethodCallWithArgsParentheses + - Style/MethodCallWithoutArgsParentheses + - Style/NumericPredicate + - Style/SymbolLiteral + parameters: IgnoredMethods + alternatives: + - AllowedMethods + - AllowedPatterns + severity: warning + - cops: Style/ArgumentsForwarding + parameters: AllowOnlyRestArgument + reason: "`AllowOnlyRestArgument` has no effect with TargetRubyVersion >= 3.2." + severity: warning + minimum_ruby_version: 3.2 + +# Enforced styles that have been removed or replaced +changed_enforced_styles: + - cops: Layout/IndentationConsistency + parameters: EnforcedStyle + value: rails + alternative: indented_internal_methods diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/exe/rubocop b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/exe/rubocop new file mode 100755 index 00000000..f9bf9042 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/exe/rubocop @@ -0,0 +1,24 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +$LOAD_PATH.unshift("#{__dir__}/../lib") + +require 'rubocop/server' +server_cli = RuboCop::Server::CLI.new +exit_status = server_cli.run +exit exit_status if server_cli.exit? + +if RuboCop::Server.running? + exit_status = RuboCop::Server::ClientCommand::Exec.new.run +else + require 'rubocop' + + cli = RuboCop::CLI.new + + time_start = Process.clock_gettime(Process::CLOCK_MONOTONIC) + exit_status = cli.run + elapsed_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) - time_start + + puts "Finished in #{elapsed_time} seconds" if cli.options[:debug] || cli.options[:display_time] +end +exit exit_status diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop.rb new file mode 100644 index 00000000..2bdad348 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop.rb @@ -0,0 +1,819 @@ +# frozen_string_literal: true + +require 'English' + +# fileutils is autoloaded by pathname, +# but must be explicitly loaded here for inclusion in `$LOADED_FEATURES`. +require 'fileutils' + +before_us = $LOADED_FEATURES.dup +require 'rainbow' + +require 'regexp_parser' +require 'set' +require 'stringio' +require 'unicode/display_width' + +# we have to require RuboCop's version, before rubocop-ast's +require_relative 'rubocop/version' +require 'rubocop-ast' + +require_relative 'rubocop/ast_aliases' +require_relative 'rubocop/ext/comment' +require_relative 'rubocop/ext/range' +require_relative 'rubocop/ext/regexp_node' +require_relative 'rubocop/ext/regexp_parser' + +require_relative 'rubocop/core_ext/string' +require_relative 'rubocop/ext/processed_source' + +require_relative 'rubocop/error' +require_relative 'rubocop/file_finder' +require_relative 'rubocop/file_patterns' +require_relative 'rubocop/name_similarity' +require_relative 'rubocop/path_util' +require_relative 'rubocop/platform' +require_relative 'rubocop/string_interpreter' +require_relative 'rubocop/util' +require_relative 'rubocop/warning' + +# rubocop:disable Style/RequireOrder + +require_relative 'rubocop/cop/util' +require_relative 'rubocop/cop/offense' +require_relative 'rubocop/cop/message_annotator' +require_relative 'rubocop/cop/ignored_node' +require_relative 'rubocop/cop/autocorrect_logic' +require_relative 'rubocop/cop/exclude_limit' +require_relative 'rubocop/cop/badge' +require_relative 'rubocop/cop/registry' +require_relative 'rubocop/cop/base' +require_relative 'rubocop/cop/cop' +require_relative 'rubocop/cop/commissioner' +require_relative 'rubocop/cop/documentation' +require_relative 'rubocop/cop/corrector' +require_relative 'rubocop/cop/force' +require_relative 'rubocop/cop/severity' +require_relative 'rubocop/cop/generator' +require_relative 'rubocop/cop/generator/configuration_injector' +require_relative 'rubocop/cop/generator/require_file_injector' +require_relative 'rubocop/magic_comment' + +require_relative 'rubocop/cop/variable_force' +require_relative 'rubocop/cop/variable_force/branch' +require_relative 'rubocop/cop/variable_force/branchable' +require_relative 'rubocop/cop/variable_force/variable' +require_relative 'rubocop/cop/variable_force/assignment' +require_relative 'rubocop/cop/variable_force/reference' +require_relative 'rubocop/cop/variable_force/scope' +require_relative 'rubocop/cop/variable_force/variable_table' + +require_relative 'rubocop/cop/mixin/array_min_size' +require_relative 'rubocop/cop/mixin/array_syntax' +require_relative 'rubocop/cop/mixin/alignment' +require_relative 'rubocop/cop/mixin/allowed_identifiers' +require_relative 'rubocop/cop/mixin/allowed_methods' +require_relative 'rubocop/cop/mixin/allowed_pattern' +require_relative 'rubocop/cop/mixin/allowed_receivers' +require_relative 'rubocop/cop/mixin/forbidden_identifiers' +require_relative 'rubocop/cop/mixin/forbidden_pattern' +require_relative 'rubocop/cop/mixin/auto_corrector' # rubocop:todo Naming/InclusiveLanguage +require_relative 'rubocop/cop/mixin/check_assignment' +require_relative 'rubocop/cop/mixin/check_line_breakable' +require_relative 'rubocop/cop/mixin/check_single_line_suitability' +require_relative 'rubocop/cop/mixin/configurable_max' +require_relative 'rubocop/cop/mixin/code_length' # relies on configurable_max +require_relative 'rubocop/cop/mixin/configurable_enforced_style' +require_relative 'rubocop/cop/mixin/configurable_formatting' +require_relative 'rubocop/cop/mixin/configurable_naming' +require_relative 'rubocop/cop/mixin/configurable_numbering' +require_relative 'rubocop/cop/mixin/dig_help' +require_relative 'rubocop/cop/mixin/documentation_comment' +require_relative 'rubocop/cop/mixin/duplication' +require_relative 'rubocop/cop/mixin/range_help' +require_relative 'rubocop/cop/mixin/annotation_comment' # relies on range +require_relative 'rubocop/cop/mixin/empty_lines_around_body' # relies on range +require_relative 'rubocop/cop/mixin/empty_parameter' +require_relative 'rubocop/cop/mixin/end_keyword_alignment' +require_relative 'rubocop/cop/mixin/endless_method_rewriter' +require_relative 'rubocop/cop/mixin/enforce_superclass' +require_relative 'rubocop/cop/mixin/first_element_line_break' +require_relative 'rubocop/cop/mixin/frozen_string_literal' +require_relative 'rubocop/cop/mixin/gem_declaration' +require_relative 'rubocop/cop/mixin/gemspec_help' +require_relative 'rubocop/cop/mixin/hash_alignment_styles' +require_relative 'rubocop/cop/mixin/hash_subset' +require_relative 'rubocop/cop/mixin/hash_transform_method' +require_relative 'rubocop/cop/mixin/integer_node' +require_relative 'rubocop/cop/mixin/interpolation' +require_relative 'rubocop/cop/mixin/line_length_help' +require_relative 'rubocop/cop/mixin/match_range' +require_relative 'rubocop/cop/metrics/utils/repeated_csend_discount' +require_relative 'rubocop/cop/metrics/utils/repeated_attribute_discount' +require_relative 'rubocop/cop/mixin/hash_shorthand_syntax' +require_relative 'rubocop/cop/mixin/method_complexity' +require_relative 'rubocop/cop/mixin/method_preference' +require_relative 'rubocop/cop/mixin/min_body_length' +require_relative 'rubocop/cop/mixin/min_branches_count' +require_relative 'rubocop/cop/mixin/multiline_element_indentation' +require_relative 'rubocop/cop/mixin/multiline_element_line_breaks' +require_relative 'rubocop/cop/mixin/multiline_expression_indentation' +require_relative 'rubocop/cop/mixin/multiline_literal_brace_layout' +require_relative 'rubocop/cop/mixin/negative_conditional' +require_relative 'rubocop/cop/mixin/heredoc' +require_relative 'rubocop/cop/mixin/nil_methods' +require_relative 'rubocop/cop/mixin/on_normal_if_unless' +require_relative 'rubocop/cop/mixin/ordered_gem_node' +require_relative 'rubocop/cop/mixin/parentheses' +require_relative 'rubocop/cop/mixin/percent_array' +require_relative 'rubocop/cop/mixin/percent_literal' +require_relative 'rubocop/cop/mixin/preceding_following_alignment' +require_relative 'rubocop/cop/mixin/preferred_delimiters' +require_relative 'rubocop/cop/mixin/rational_literal' +require_relative 'rubocop/cop/mixin/require_library' +require_relative 'rubocop/cop/mixin/rescue_node' +require_relative 'rubocop/cop/mixin/safe_assignment' +require_relative 'rubocop/cop/mixin/space_after_punctuation' +require_relative 'rubocop/cop/mixin/space_before_punctuation' +require_relative 'rubocop/cop/mixin/surrounding_space' +require_relative 'rubocop/cop/mixin/statement_modifier' +require_relative 'rubocop/cop/mixin/string_help' +require_relative 'rubocop/cop/mixin/string_literals_help' +require_relative 'rubocop/cop/mixin/symbol_help' +require_relative 'rubocop/cop/mixin/target_ruby_version' +require_relative 'rubocop/cop/mixin/trailing_body' +require_relative 'rubocop/cop/mixin/trailing_comma' +require_relative 'rubocop/cop/mixin/uncommunicative_name' +require_relative 'rubocop/cop/mixin/unused_argument' +require_relative 'rubocop/cop/mixin/visibility_help' +require_relative 'rubocop/cop/mixin/comments_help' # relies on visibility_help +require_relative 'rubocop/cop/mixin/def_node' # relies on visibility_help + +require_relative 'rubocop/cop/utils/format_string' + +require_relative 'rubocop/cop/migration/department_name' + +require_relative 'rubocop/cop/correctors/alignment_corrector' +require_relative 'rubocop/cop/correctors/condition_corrector' +require_relative 'rubocop/cop/correctors/each_to_for_corrector' +require_relative 'rubocop/cop/correctors/empty_line_corrector' +require_relative 'rubocop/cop/correctors/for_to_each_corrector' +require_relative 'rubocop/cop/correctors/if_then_corrector' +require_relative 'rubocop/cop/correctors/lambda_literal_to_method_corrector' +require_relative 'rubocop/cop/correctors/line_break_corrector' +require_relative 'rubocop/cop/correctors/multiline_literal_brace_corrector' +require_relative 'rubocop/cop/correctors/ordered_gem_corrector' +require_relative 'rubocop/cop/correctors/parentheses_corrector' +require_relative 'rubocop/cop/correctors/percent_literal_corrector' +require_relative 'rubocop/cop/correctors/punctuation_corrector' +require_relative 'rubocop/cop/correctors/require_library_corrector' +require_relative 'rubocop/cop/correctors/space_corrector' +require_relative 'rubocop/cop/correctors/string_literal_corrector' +require_relative 'rubocop/cop/correctors/unused_arg_corrector' + +require_relative 'rubocop/cop/bundler/duplicated_gem' +require_relative 'rubocop/cop/bundler/duplicated_group' +require_relative 'rubocop/cop/bundler/gem_comment' +require_relative 'rubocop/cop/bundler/gem_filename' +require_relative 'rubocop/cop/bundler/gem_version' +require_relative 'rubocop/cop/bundler/insecure_protocol_source' +require_relative 'rubocop/cop/bundler/ordered_gems' + +require_relative 'rubocop/cop/gemspec/add_runtime_dependency' +require_relative 'rubocop/cop/gemspec/dependency_version' +require_relative 'rubocop/cop/gemspec/deprecated_attribute_assignment' +require_relative 'rubocop/cop/gemspec/development_dependencies' +require_relative 'rubocop/cop/gemspec/duplicated_assignment' +require_relative 'rubocop/cop/gemspec/ordered_dependencies' +require_relative 'rubocop/cop/gemspec/require_mfa' +require_relative 'rubocop/cop/gemspec/required_ruby_version' +require_relative 'rubocop/cop/gemspec/ruby_version_globals_usage' + +require_relative 'rubocop/cop/layout/access_modifier_indentation' +require_relative 'rubocop/cop/layout/argument_alignment' +require_relative 'rubocop/cop/layout/array_alignment' +require_relative 'rubocop/cop/layout/assignment_indentation' +require_relative 'rubocop/cop/layout/begin_end_alignment' +require_relative 'rubocop/cop/layout/block_alignment' +require_relative 'rubocop/cop/layout/block_end_newline' +require_relative 'rubocop/cop/layout/case_indentation' +require_relative 'rubocop/cop/layout/class_structure' +require_relative 'rubocop/cop/layout/closing_heredoc_indentation' +require_relative 'rubocop/cop/layout/closing_parenthesis_indentation' +require_relative 'rubocop/cop/layout/comment_indentation' +require_relative 'rubocop/cop/layout/condition_position' +require_relative 'rubocop/cop/layout/def_end_alignment' +require_relative 'rubocop/cop/layout/dot_position' +require_relative 'rubocop/cop/layout/else_alignment' +require_relative 'rubocop/cop/layout/empty_comment' +require_relative 'rubocop/cop/layout/empty_line_after_guard_clause' +require_relative 'rubocop/cop/layout/empty_line_after_magic_comment' +require_relative 'rubocop/cop/layout/empty_line_after_multiline_condition' +require_relative 'rubocop/cop/layout/empty_line_between_defs' +require_relative 'rubocop/cop/layout/empty_lines_around_access_modifier' +require_relative 'rubocop/cop/layout/empty_lines_around_arguments' +require_relative 'rubocop/cop/layout/empty_lines_around_attribute_accessor' +require_relative 'rubocop/cop/layout/empty_lines_around_begin_body' +require_relative 'rubocop/cop/layout/empty_lines_around_block_body' +require_relative 'rubocop/cop/layout/empty_lines_around_class_body' +require_relative 'rubocop/cop/layout/empty_lines_around_exception_handling_keywords' +require_relative 'rubocop/cop/layout/empty_lines_around_method_body' +require_relative 'rubocop/cop/layout/empty_lines_around_module_body' +require_relative 'rubocop/cop/layout/empty_lines' +require_relative 'rubocop/cop/layout/end_alignment' +require_relative 'rubocop/cop/layout/end_of_line' +require_relative 'rubocop/cop/layout/extra_spacing' +require_relative 'rubocop/cop/layout/first_argument_indentation' +require_relative 'rubocop/cop/layout/first_array_element_indentation' +require_relative 'rubocop/cop/layout/first_array_element_line_break' +require_relative 'rubocop/cop/layout/first_hash_element_indentation' +require_relative 'rubocop/cop/layout/first_hash_element_line_break' +require_relative 'rubocop/cop/layout/first_method_argument_line_break' +require_relative 'rubocop/cop/layout/first_method_parameter_line_break' +require_relative 'rubocop/cop/layout/first_parameter_indentation' +require_relative 'rubocop/cop/layout/hash_alignment' +require_relative 'rubocop/cop/layout/heredoc_argument_closing_parenthesis' +require_relative 'rubocop/cop/layout/heredoc_indentation' +require_relative 'rubocop/cop/layout/indentation_consistency' +require_relative 'rubocop/cop/layout/indentation_style' +require_relative 'rubocop/cop/layout/indentation_width' +require_relative 'rubocop/cop/layout/initial_indentation' +require_relative 'rubocop/cop/layout/leading_comment_space' +require_relative 'rubocop/cop/layout/leading_empty_lines' +require_relative 'rubocop/cop/layout/line_continuation_leading_space' +require_relative 'rubocop/cop/layout/line_continuation_spacing' +require_relative 'rubocop/cop/layout/line_end_string_concatenation_indentation' +require_relative 'rubocop/cop/layout/line_length' +require_relative 'rubocop/cop/layout/multiline_array_brace_layout' +require_relative 'rubocop/cop/layout/multiline_array_line_breaks' +require_relative 'rubocop/cop/layout/multiline_assignment_layout' +require_relative 'rubocop/cop/layout/multiline_block_layout' +require_relative 'rubocop/cop/layout/multiline_hash_brace_layout' +require_relative 'rubocop/cop/layout/multiline_hash_key_line_breaks' +require_relative 'rubocop/cop/layout/multiline_method_argument_line_breaks' +require_relative 'rubocop/cop/layout/multiline_method_call_brace_layout' +require_relative 'rubocop/cop/layout/multiline_method_call_indentation' +require_relative 'rubocop/cop/layout/multiline_method_definition_brace_layout' +require_relative 'rubocop/cop/layout/multiline_method_parameter_line_breaks' +require_relative 'rubocop/cop/layout/multiline_operation_indentation' +require_relative 'rubocop/cop/layout/parameter_alignment' +require_relative 'rubocop/cop/layout/redundant_line_break' +require_relative 'rubocop/cop/layout/rescue_ensure_alignment' +require_relative 'rubocop/cop/layout/single_line_block_chain' +require_relative 'rubocop/cop/layout/space_after_colon' +require_relative 'rubocop/cop/layout/space_after_comma' +require_relative 'rubocop/cop/layout/space_after_method_name' +require_relative 'rubocop/cop/layout/space_after_not' +require_relative 'rubocop/cop/layout/space_after_semicolon' +require_relative 'rubocop/cop/layout/space_around_block_parameters' +require_relative 'rubocop/cop/layout/space_around_equals_in_parameter_default' +require_relative 'rubocop/cop/layout/space_around_keyword' +require_relative 'rubocop/cop/layout/space_around_method_call_operator' +require_relative 'rubocop/cop/layout/space_around_operators' +require_relative 'rubocop/cop/layout/space_before_block_braces' +require_relative 'rubocop/cop/layout/space_before_brackets' +require_relative 'rubocop/cop/layout/space_before_comma' +require_relative 'rubocop/cop/layout/space_before_comment' +require_relative 'rubocop/cop/layout/space_before_first_arg' +require_relative 'rubocop/cop/layout/space_before_semicolon' +require_relative 'rubocop/cop/layout/space_in_lambda_literal' +require_relative 'rubocop/cop/layout/space_inside_array_percent_literal' +require_relative 'rubocop/cop/layout/space_inside_array_literal_brackets' +require_relative 'rubocop/cop/layout/space_inside_block_braces' +require_relative 'rubocop/cop/layout/space_inside_hash_literal_braces' +require_relative 'rubocop/cop/layout/space_inside_parens' +require_relative 'rubocop/cop/layout/space_inside_percent_literal_delimiters' +require_relative 'rubocop/cop/layout/space_inside_range_literal' +require_relative 'rubocop/cop/layout/space_inside_reference_brackets' +require_relative 'rubocop/cop/layout/space_inside_string_interpolation' +require_relative 'rubocop/cop/layout/trailing_empty_lines' +require_relative 'rubocop/cop/layout/trailing_whitespace' + +require_relative 'rubocop/cop/lint/ambiguous_assignment' +require_relative 'rubocop/cop/lint/ambiguous_block_association' +require_relative 'rubocop/cop/lint/ambiguous_operator' +require_relative 'rubocop/cop/lint/ambiguous_operator_precedence' +require_relative 'rubocop/cop/lint/ambiguous_range' +require_relative 'rubocop/cop/lint/ambiguous_regexp_literal' +require_relative 'rubocop/cop/lint/array_literal_in_regexp' +require_relative 'rubocop/cop/lint/assignment_in_condition' +require_relative 'rubocop/cop/lint/big_decimal_new' +require_relative 'rubocop/cop/lint/binary_operator_with_identical_operands' +require_relative 'rubocop/cop/lint/boolean_symbol' +require_relative 'rubocop/cop/lint/circular_argument_reference' +require_relative 'rubocop/cop/lint/constant_definition_in_block' +require_relative 'rubocop/cop/lint/constant_overwritten_in_rescue' +require_relative 'rubocop/cop/lint/constant_reassignment' +require_relative 'rubocop/cop/lint/constant_resolution' +require_relative 'rubocop/cop/lint/cop_directive_syntax' +require_relative 'rubocop/cop/lint/debugger' +require_relative 'rubocop/cop/lint/deprecated_class_methods' +require_relative 'rubocop/cop/lint/deprecated_constants' +require_relative 'rubocop/cop/lint/deprecated_open_ssl_constant' +require_relative 'rubocop/cop/lint/disjunctive_assignment_in_constructor' +require_relative 'rubocop/cop/lint/duplicate_branch' +require_relative 'rubocop/cop/lint/duplicate_case_condition' +require_relative 'rubocop/cop/lint/duplicate_elsif_condition' +require_relative 'rubocop/cop/lint/duplicate_hash_key' +require_relative 'rubocop/cop/lint/duplicate_magic_comment' +require_relative 'rubocop/cop/lint/duplicate_match_pattern' +require_relative 'rubocop/cop/lint/duplicate_methods' +require_relative 'rubocop/cop/lint/duplicate_regexp_character_class_element' +require_relative 'rubocop/cop/lint/duplicate_require' +require_relative 'rubocop/cop/lint/duplicate_rescue_exception' +require_relative 'rubocop/cop/lint/duplicate_set_element' +require_relative 'rubocop/cop/lint/each_with_object_argument' +require_relative 'rubocop/cop/lint/else_layout' +require_relative 'rubocop/cop/lint/empty_block' +require_relative 'rubocop/cop/lint/empty_class' +require_relative 'rubocop/cop/lint/empty_conditional_body' +require_relative 'rubocop/cop/lint/empty_ensure' +require_relative 'rubocop/cop/lint/empty_expression' +require_relative 'rubocop/cop/lint/empty_file' +require_relative 'rubocop/cop/lint/empty_in_pattern' +require_relative 'rubocop/cop/lint/empty_interpolation' +require_relative 'rubocop/cop/lint/empty_when' +require_relative 'rubocop/cop/lint/ensure_return' +require_relative 'rubocop/cop/lint/shared_mutable_default' +require_relative 'rubocop/cop/lint/erb_new_arguments' +require_relative 'rubocop/cop/lint/flip_flop' +require_relative 'rubocop/cop/lint/float_comparison' +require_relative 'rubocop/cop/lint/float_out_of_range' +require_relative 'rubocop/cop/lint/format_parameter_mismatch' +require_relative 'rubocop/cop/lint/hash_compare_by_identity' +require_relative 'rubocop/cop/lint/hash_new_with_keyword_arguments_as_default' +require_relative 'rubocop/cop/lint/heredoc_method_call_position' +require_relative 'rubocop/cop/lint/identity_comparison' +require_relative 'rubocop/cop/lint/implicit_string_concatenation' +require_relative 'rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler' +require_relative 'rubocop/cop/lint/ineffective_access_modifier' +require_relative 'rubocop/cop/lint/inherit_exception' +require_relative 'rubocop/cop/lint/interpolation_check' +require_relative 'rubocop/cop/lint/it_without_arguments_in_block' +require_relative 'rubocop/cop/lint/lambda_without_literal_block' +require_relative 'rubocop/cop/lint/literal_as_condition' +require_relative 'rubocop/cop/lint/literal_assignment_in_condition' +require_relative 'rubocop/cop/lint/literal_in_interpolation' +require_relative 'rubocop/cop/lint/loop' +require_relative 'rubocop/cop/lint/missing_cop_enable_directive' +require_relative 'rubocop/cop/lint/missing_super' +require_relative 'rubocop/cop/lint/mixed_case_range' +require_relative 'rubocop/cop/lint/mixed_regexp_capture_types' +require_relative 'rubocop/cop/lint/multiple_comparison' +require_relative 'rubocop/cop/lint/nested_method_definition' +require_relative 'rubocop/cop/lint/nested_percent_literal' +require_relative 'rubocop/cop/lint/next_without_accumulator' +require_relative 'rubocop/cop/lint/no_return_in_begin_end_blocks' +require_relative 'rubocop/cop/lint/non_atomic_file_operation' +require_relative 'rubocop/cop/lint/non_deterministic_require_order' +require_relative 'rubocop/cop/lint/non_local_exit_from_iterator' +require_relative 'rubocop/cop/lint/number_conversion' +require_relative 'rubocop/cop/lint/numbered_parameter_assignment' +require_relative 'rubocop/cop/lint/numeric_operation_with_constant_result' +require_relative 'rubocop/cop/lint/or_assignment_to_constant' +require_relative 'rubocop/cop/lint/ordered_magic_comments' +require_relative 'rubocop/cop/lint/out_of_range_regexp_ref' +require_relative 'rubocop/cop/lint/parentheses_as_grouped_expression' +require_relative 'rubocop/cop/lint/percent_string_array' +require_relative 'rubocop/cop/lint/percent_symbol_array' +require_relative 'rubocop/cop/lint/raise_exception' +require_relative 'rubocop/cop/lint/rand_one' +require_relative 'rubocop/cop/lint/redundant_cop_disable_directive' +require_relative 'rubocop/cop/lint/redundant_cop_enable_directive' +require_relative 'rubocop/cop/lint/redundant_dir_glob_sort' +require_relative 'rubocop/cop/lint/redundant_regexp_quantifiers' +require_relative 'rubocop/cop/lint/redundant_require_statement' +require_relative 'rubocop/cop/lint/redundant_safe_navigation' +require_relative 'rubocop/cop/lint/redundant_splat_expansion' +require_relative 'rubocop/cop/lint/redundant_string_coercion' +require_relative 'rubocop/cop/lint/redundant_type_conversion' +require_relative 'rubocop/cop/lint/redundant_with_index' +require_relative 'rubocop/cop/lint/redundant_with_object' +require_relative 'rubocop/cop/lint/refinement_import_methods' +require_relative 'rubocop/cop/lint/regexp_as_condition' +require_relative 'rubocop/cop/lint/require_parentheses' +require_relative 'rubocop/cop/lint/require_range_parentheses' +require_relative 'rubocop/cop/lint/require_relative_self_path' +require_relative 'rubocop/cop/lint/rescue_exception' +require_relative 'rubocop/cop/lint/rescue_type' +require_relative 'rubocop/cop/lint/return_in_void_context' +require_relative 'rubocop/cop/lint/safe_navigation_consistency' +require_relative 'rubocop/cop/lint/safe_navigation_chain' +require_relative 'rubocop/cop/lint/safe_navigation_with_empty' +require_relative 'rubocop/cop/lint/script_permission' +require_relative 'rubocop/cop/lint/self_assignment' +require_relative 'rubocop/cop/lint/send_with_mixin_argument' +require_relative 'rubocop/cop/lint/shadowed_argument' +require_relative 'rubocop/cop/lint/shadowed_exception' +require_relative 'rubocop/cop/lint/shadowing_outer_local_variable' +require_relative 'rubocop/cop/lint/struct_new_override' +require_relative 'rubocop/cop/lint/suppressed_exception' +require_relative 'rubocop/cop/lint/suppressed_exception_in_number_conversion' +require_relative 'rubocop/cop/lint/symbol_conversion' +require_relative 'rubocop/cop/lint/syntax' +require_relative 'rubocop/cop/lint/to_enum_arguments' +require_relative 'rubocop/cop/lint/to_json' +require_relative 'rubocop/cop/lint/top_level_return_with_argument' +require_relative 'rubocop/cop/lint/trailing_comma_in_attribute_declaration' +require_relative 'rubocop/cop/lint/triple_quotes' +require_relative 'rubocop/cop/lint/underscore_prefixed_variable_name' +require_relative 'rubocop/cop/lint/unescaped_bracket_in_regexp' +require_relative 'rubocop/cop/lint/unexpected_block_arity' +require_relative 'rubocop/cop/lint/unified_integer' +require_relative 'rubocop/cop/lint/unmodified_reduce_accumulator' +require_relative 'rubocop/cop/lint/unreachable_code' +require_relative 'rubocop/cop/lint/unreachable_loop' +require_relative 'rubocop/cop/lint/unused_block_argument' +require_relative 'rubocop/cop/lint/unused_method_argument' +require_relative 'rubocop/cop/lint/uri_escape_unescape' +require_relative 'rubocop/cop/lint/uri_regexp' +require_relative 'rubocop/cop/lint/useless_access_modifier' +require_relative 'rubocop/cop/lint/useless_assignment' +require_relative 'rubocop/cop/lint/useless_constant_scoping' +require_relative 'rubocop/cop/lint/useless_default_value_argument' +require_relative 'rubocop/cop/lint/useless_defined' +require_relative 'rubocop/cop/lint/useless_else_without_rescue' +require_relative 'rubocop/cop/lint/useless_method_definition' +require_relative 'rubocop/cop/lint/useless_numeric_operation' +require_relative 'rubocop/cop/lint/useless_or' +require_relative 'rubocop/cop/lint/useless_rescue' +require_relative 'rubocop/cop/lint/useless_ruby2_keywords' +require_relative 'rubocop/cop/lint/useless_setter_call' +require_relative 'rubocop/cop/lint/useless_times' +require_relative 'rubocop/cop/lint/void' + +require_relative 'rubocop/cop/metrics/utils/iterating_block' +require_relative 'rubocop/cop/metrics/cyclomatic_complexity' +# relies on cyclomatic_complexity +require_relative 'rubocop/cop/metrics/utils/abc_size_calculator' +require_relative 'rubocop/cop/metrics/utils/code_length_calculator' +require_relative 'rubocop/cop/metrics/abc_size' +require_relative 'rubocop/cop/metrics/block_length' +require_relative 'rubocop/cop/metrics/block_nesting' +require_relative 'rubocop/cop/metrics/class_length' +require_relative 'rubocop/cop/metrics/collection_literal_length' +require_relative 'rubocop/cop/metrics/method_length' +require_relative 'rubocop/cop/metrics/module_length' +require_relative 'rubocop/cop/metrics/parameter_lists' +require_relative 'rubocop/cop/metrics/perceived_complexity' + +require_relative 'rubocop/cop/naming/accessor_method_name' +require_relative 'rubocop/cop/naming/ascii_identifiers' +require_relative 'rubocop/cop/naming/block_forwarding' +require_relative 'rubocop/cop/naming/block_parameter_name' +require_relative 'rubocop/cop/naming/class_and_module_camel_case' +require_relative 'rubocop/cop/naming/constant_name' +require_relative 'rubocop/cop/naming/file_name' +require_relative 'rubocop/cop/naming/heredoc_delimiter_case' +require_relative 'rubocop/cop/naming/heredoc_delimiter_naming' +require_relative 'rubocop/cop/naming/inclusive_language' +require_relative 'rubocop/cop/naming/memoized_instance_variable_name' +require_relative 'rubocop/cop/naming/method_name' +require_relative 'rubocop/cop/naming/method_parameter_name' +require_relative 'rubocop/cop/naming/binary_operator_parameter_name' +require_relative 'rubocop/cop/naming/predicate_method' +require_relative 'rubocop/cop/naming/predicate_prefix' +require_relative 'rubocop/cop/naming/rescued_exceptions_variable_name' +require_relative 'rubocop/cop/naming/variable_name' +require_relative 'rubocop/cop/naming/variable_number' + +require_relative 'rubocop/cop/style/access_modifier_declarations' +require_relative 'rubocop/cop/style/accessor_grouping' +require_relative 'rubocop/cop/style/alias' +require_relative 'rubocop/cop/style/ambiguous_endless_method_definition' +require_relative 'rubocop/cop/style/and_or' +require_relative 'rubocop/cop/style/arguments_forwarding' +require_relative 'rubocop/cop/style/array_coercion' +require_relative 'rubocop/cop/style/array_first_last' +require_relative 'rubocop/cop/style/array_intersect' +require_relative 'rubocop/cop/style/array_join' +require_relative 'rubocop/cop/style/ascii_comments' +require_relative 'rubocop/cop/style/attr' +require_relative 'rubocop/cop/style/auto_resource_cleanup' +require_relative 'rubocop/cop/style/bare_percent_literals' +require_relative 'rubocop/cop/style/begin_block' +require_relative 'rubocop/cop/style/bisected_attr_accessor' +require_relative 'rubocop/cop/style/bitwise_predicate' +require_relative 'rubocop/cop/style/block_comments' +require_relative 'rubocop/cop/style/block_delimiters' +require_relative 'rubocop/cop/style/case_equality' +require_relative 'rubocop/cop/style/case_like_if' +require_relative 'rubocop/cop/style/character_literal' +require_relative 'rubocop/cop/style/class_and_module_children' +require_relative 'rubocop/cop/style/class_check' +require_relative 'rubocop/cop/style/class_equality_comparison' +require_relative 'rubocop/cop/style/class_methods' +require_relative 'rubocop/cop/style/class_methods_definitions' +require_relative 'rubocop/cop/style/class_vars' +require_relative 'rubocop/cop/style/collection_compact' +require_relative 'rubocop/cop/style/collection_methods' +require_relative 'rubocop/cop/style/colon_method_call' +require_relative 'rubocop/cop/style/colon_method_definition' +require_relative 'rubocop/cop/style/combinable_defined' +require_relative 'rubocop/cop/style/combinable_loops' +require_relative 'rubocop/cop/style/command_literal' +require_relative 'rubocop/cop/style/comment_annotation' +require_relative 'rubocop/cop/style/commented_keyword' +require_relative 'rubocop/cop/style/comparable_between' +require_relative 'rubocop/cop/style/comparable_clamp' +require_relative 'rubocop/cop/style/concat_array_literals' +require_relative 'rubocop/cop/style/conditional_assignment' +require_relative 'rubocop/cop/style/constant_visibility' +require_relative 'rubocop/cop/style/copyright' +require_relative 'rubocop/cop/style/data_inheritance' +require_relative 'rubocop/cop/style/date_time' +require_relative 'rubocop/cop/style/def_with_parentheses' +require_relative 'rubocop/cop/style/dig_chain' +require_relative 'rubocop/cop/style/dir' +require_relative 'rubocop/cop/style/dir_empty' +require_relative 'rubocop/cop/style/disable_cops_within_source_code_directive' +require_relative 'rubocop/cop/style/documentation_method' +require_relative 'rubocop/cop/style/documentation' +require_relative 'rubocop/cop/style/document_dynamic_eval_definition' +require_relative 'rubocop/cop/style/double_cop_disable_directive' +require_relative 'rubocop/cop/style/double_negation' +require_relative 'rubocop/cop/style/each_for_simple_loop' +require_relative 'rubocop/cop/style/each_with_object' +require_relative 'rubocop/cop/style/empty_block_parameter' +require_relative 'rubocop/cop/style/empty_case_condition' +require_relative 'rubocop/cop/style/empty_else' +require_relative 'rubocop/cop/style/empty_heredoc' +require_relative 'rubocop/cop/style/empty_lambda_parameter' +require_relative 'rubocop/cop/style/empty_literal' +require_relative 'rubocop/cop/style/empty_method' +require_relative 'rubocop/cop/style/empty_string_inside_interpolation' +require_relative 'rubocop/cop/style/endless_method' +require_relative 'rubocop/cop/style/encoding' +require_relative 'rubocop/cop/style/end_block' +require_relative 'rubocop/cop/style/env_home' +require_relative 'rubocop/cop/style/eval_with_location' +require_relative 'rubocop/cop/style/even_odd' +require_relative 'rubocop/cop/style/exact_regexp_match' +require_relative 'rubocop/cop/style/expand_path_arguments' +require_relative 'rubocop/cop/style/explicit_block_argument' +require_relative 'rubocop/cop/style/exponential_notation' +require_relative 'rubocop/cop/style/fetch_env_var' +require_relative 'rubocop/cop/style/file_empty' +require_relative 'rubocop/cop/style/file_null' +require_relative 'rubocop/cop/style/file_read' +require_relative 'rubocop/cop/style/file_touch' +require_relative 'rubocop/cop/style/file_write' +require_relative 'rubocop/cop/style/float_division' +require_relative 'rubocop/cop/style/for' +require_relative 'rubocop/cop/style/format_string' +require_relative 'rubocop/cop/style/format_string_token' +require_relative 'rubocop/cop/style/frozen_string_literal_comment' +require_relative 'rubocop/cop/style/global_std_stream' +require_relative 'rubocop/cop/style/global_vars' +require_relative 'rubocop/cop/style/guard_clause' +require_relative 'rubocop/cop/style/hash_as_last_array_item' +require_relative 'rubocop/cop/style/hash_conversion' +require_relative 'rubocop/cop/style/hash_each_methods' +require_relative 'rubocop/cop/style/hash_except' +require_relative 'rubocop/cop/style/hash_fetch_chain' +require_relative 'rubocop/cop/style/hash_like_case' +require_relative 'rubocop/cop/style/hash_slice' +require_relative 'rubocop/cop/style/hash_syntax' +require_relative 'rubocop/cop/style/hash_transform_keys' +require_relative 'rubocop/cop/style/hash_transform_values' +require_relative 'rubocop/cop/style/identical_conditional_branches' +require_relative 'rubocop/cop/style/if_inside_else' +require_relative 'rubocop/cop/style/if_unless_modifier' +require_relative 'rubocop/cop/style/if_unless_modifier_of_if_unless' +require_relative 'rubocop/cop/style/if_with_boolean_literal_branches' +require_relative 'rubocop/cop/style/if_with_semicolon' +require_relative 'rubocop/cop/style/implicit_runtime_error' +require_relative 'rubocop/cop/style/in_pattern_then' +require_relative 'rubocop/cop/style/infinite_loop' +require_relative 'rubocop/cop/style/inverse_methods' +require_relative 'rubocop/cop/style/inline_comment' +require_relative 'rubocop/cop/style/invertible_unless_condition' +require_relative 'rubocop/cop/style/ip_addresses' +require_relative 'rubocop/cop/style/it_assignment' +require_relative 'rubocop/cop/style/it_block_parameter' +require_relative 'rubocop/cop/style/keyword_arguments_merging' +require_relative 'rubocop/cop/style/keyword_parameters_order' +require_relative 'rubocop/cop/style/lambda' +require_relative 'rubocop/cop/style/lambda_call' +require_relative 'rubocop/cop/style/line_end_concatenation' +require_relative 'rubocop/cop/style/magic_comment_format' +require_relative 'rubocop/cop/style/map_into_array' +require_relative 'rubocop/cop/style/map_to_hash' +require_relative 'rubocop/cop/style/map_to_set' +require_relative 'rubocop/cop/style/method_call_without_args_parentheses' +require_relative 'rubocop/cop/style/method_call_with_args_parentheses' +require_relative 'rubocop/cop/style/min_max_comparison' +require_relative 'rubocop/cop/style/multiline_in_pattern_then' +require_relative 'rubocop/cop/style/numbered_parameters' +require_relative 'rubocop/cop/style/open_struct_use' +require_relative 'rubocop/cop/style/operator_method_call' +require_relative 'rubocop/cop/style/redundant_array_constructor' +require_relative 'rubocop/cop/style/redundant_array_flatten' +require_relative 'rubocop/cop/style/redundant_assignment' +require_relative 'rubocop/cop/style/redundant_constant_base' +require_relative 'rubocop/cop/style/redundant_current_directory_in_path' +require_relative 'rubocop/cop/style/redundant_double_splat_hash_braces' +require_relative 'rubocop/cop/style/redundant_each' +require_relative 'rubocop/cop/style/redundant_fetch_block' +require_relative 'rubocop/cop/style/redundant_file_extension_in_require' +require_relative 'rubocop/cop/style/redundant_filter_chain' +require_relative 'rubocop/cop/style/redundant_format' +require_relative 'rubocop/cop/style/redundant_heredoc_delimiter_quotes' +require_relative 'rubocop/cop/style/redundant_initialize' +require_relative 'rubocop/cop/style/redundant_interpolation_unfreeze' +require_relative 'rubocop/cop/style/redundant_line_continuation' +require_relative 'rubocop/cop/style/redundant_regexp_argument' +require_relative 'rubocop/cop/style/redundant_regexp_constructor' +require_relative 'rubocop/cop/style/redundant_self_assignment' +require_relative 'rubocop/cop/style/redundant_self_assignment_branch' +require_relative 'rubocop/cop/style/require_order' +require_relative 'rubocop/cop/style/safe_navigation_chain_length' +require_relative 'rubocop/cop/style/single_line_do_end_block' +require_relative 'rubocop/cop/style/sole_nested_conditional' +require_relative 'rubocop/cop/style/static_class' +require_relative 'rubocop/cop/style/map_compact_with_conditional_block' +require_relative 'rubocop/cop/style/method_called_on_do_end_block' +require_relative 'rubocop/cop/style/method_def_parentheses' +require_relative 'rubocop/cop/style/min_max' +require_relative 'rubocop/cop/style/missing_else' +require_relative 'rubocop/cop/style/missing_respond_to_missing' +require_relative 'rubocop/cop/style/mixin_grouping' +require_relative 'rubocop/cop/style/mixin_usage' +require_relative 'rubocop/cop/style/module_function' +require_relative 'rubocop/cop/style/multiline_block_chain' +require_relative 'rubocop/cop/style/multiline_if_then' +require_relative 'rubocop/cop/style/multiline_if_modifier' +require_relative 'rubocop/cop/style/multiline_method_signature' +require_relative 'rubocop/cop/style/multiline_memoization' +require_relative 'rubocop/cop/style/multiline_ternary_operator' +require_relative 'rubocop/cop/style/multiline_when_then' +require_relative 'rubocop/cop/style/multiple_comparison' +require_relative 'rubocop/cop/style/mutable_constant' +require_relative 'rubocop/cop/style/negated_if' +require_relative 'rubocop/cop/style/negated_if_else_condition' +require_relative 'rubocop/cop/style/negated_unless' +require_relative 'rubocop/cop/style/negated_while' +require_relative 'rubocop/cop/style/nested_file_dirname' +require_relative 'rubocop/cop/style/nested_modifier' +require_relative 'rubocop/cop/style/nested_parenthesized_calls' +require_relative 'rubocop/cop/style/nested_ternary_operator' +require_relative 'rubocop/cop/style/next' +require_relative 'rubocop/cop/style/nil_comparison' +require_relative 'rubocop/cop/style/nil_lambda' +require_relative 'rubocop/cop/style/non_nil_check' +require_relative 'rubocop/cop/style/not' +require_relative 'rubocop/cop/style/numbered_parameters_limit' +require_relative 'rubocop/cop/style/numeric_literals' +require_relative 'rubocop/cop/style/numeric_literal_prefix' +require_relative 'rubocop/cop/style/numeric_predicate' +require_relative 'rubocop/cop/style/object_then' +require_relative 'rubocop/cop/style/one_line_conditional' +require_relative 'rubocop/cop/style/or_assignment' +require_relative 'rubocop/cop/style/option_hash' +require_relative 'rubocop/cop/style/optional_arguments' +require_relative 'rubocop/cop/style/optional_boolean_parameter' +require_relative 'rubocop/cop/style/parallel_assignment' +require_relative 'rubocop/cop/style/parentheses_around_condition' +require_relative 'rubocop/cop/style/percent_literal_delimiters' +require_relative 'rubocop/cop/style/percent_q_literals' +require_relative 'rubocop/cop/style/perl_backrefs' +require_relative 'rubocop/cop/style/preferred_hash_methods' +require_relative 'rubocop/cop/style/proc' +require_relative 'rubocop/cop/style/quoted_symbols' +require_relative 'rubocop/cop/style/raise_args' +require_relative 'rubocop/cop/style/random_with_offset' +require_relative 'rubocop/cop/style/redundant_argument' +require_relative 'rubocop/cop/style/redundant_begin' +require_relative 'rubocop/cop/style/redundant_capital_w' +require_relative 'rubocop/cop/style/redundant_condition' +require_relative 'rubocop/cop/style/redundant_conditional' +require_relative 'rubocop/cop/style/redundant_exception' +require_relative 'rubocop/cop/style/redundant_freeze' +require_relative 'rubocop/cop/style/redundant_interpolation' +require_relative 'rubocop/cop/style/redundant_parentheses' +require_relative 'rubocop/cop/style/redundant_percent_q' +require_relative 'rubocop/cop/style/redundant_regexp_character_class' +require_relative 'rubocop/cop/style/redundant_regexp_escape' +require_relative 'rubocop/cop/style/redundant_return' +require_relative 'rubocop/cop/style/redundant_self' +require_relative 'rubocop/cop/style/redundant_sort' +require_relative 'rubocop/cop/style/redundant_sort_by' +require_relative 'rubocop/cop/style/redundant_string_escape' +require_relative 'rubocop/cop/style/regexp_literal' +require_relative 'rubocop/cop/style/rescue_modifier' +require_relative 'rubocop/cop/style/rescue_standard_error' +require_relative 'rubocop/cop/style/return_nil' +require_relative 'rubocop/cop/style/return_nil_in_predicate_method_definition' +require_relative 'rubocop/cop/style/safe_navigation' +require_relative 'rubocop/cop/style/sample' +require_relative 'rubocop/cop/style/select_by_regexp' +require_relative 'rubocop/cop/style/self_assignment' +require_relative 'rubocop/cop/style/semicolon' +require_relative 'rubocop/cop/style/send' +require_relative 'rubocop/cop/style/send_with_literal_method_name' +require_relative 'rubocop/cop/style/signal_exception' +require_relative 'rubocop/cop/style/single_argument_dig' +require_relative 'rubocop/cop/style/single_line_block_params' +require_relative 'rubocop/cop/style/single_line_methods' +require_relative 'rubocop/cop/style/slicing_with_range' +require_relative 'rubocop/cop/style/special_global_vars' +require_relative 'rubocop/cop/style/stabby_lambda_parentheses' +require_relative 'rubocop/cop/style/stderr_puts' +require_relative 'rubocop/cop/style/string_chars' +require_relative 'rubocop/cop/style/string_concatenation' +require_relative 'rubocop/cop/style/string_hash_keys' +require_relative 'rubocop/cop/style/string_literals' +require_relative 'rubocop/cop/style/string_literals_in_interpolation' +require_relative 'rubocop/cop/style/string_methods' +require_relative 'rubocop/cop/style/strip' +require_relative 'rubocop/cop/style/struct_inheritance' +require_relative 'rubocop/cop/style/super_arguments' +require_relative 'rubocop/cop/style/super_with_args_parentheses' +require_relative 'rubocop/cop/style/swap_values' +require_relative 'rubocop/cop/style/symbol_array' +require_relative 'rubocop/cop/style/symbol_literal' +require_relative 'rubocop/cop/style/symbol_proc' +require_relative 'rubocop/cop/style/ternary_parentheses' +require_relative 'rubocop/cop/style/top_level_method_definition' +require_relative 'rubocop/cop/style/trailing_body_on_class' +require_relative 'rubocop/cop/style/trailing_body_on_method_definition' +require_relative 'rubocop/cop/style/trailing_body_on_module' +require_relative 'rubocop/cop/style/trailing_comma_in_arguments' +require_relative 'rubocop/cop/style/trailing_comma_in_array_literal' +require_relative 'rubocop/cop/style/trailing_comma_in_block_args' +require_relative 'rubocop/cop/style/trailing_comma_in_hash_literal' +require_relative 'rubocop/cop/style/trailing_method_end_statement' +require_relative 'rubocop/cop/style/trailing_underscore_variable' +require_relative 'rubocop/cop/style/trivial_accessors' +require_relative 'rubocop/cop/style/unless_else' +require_relative 'rubocop/cop/style/unless_logical_operators' +require_relative 'rubocop/cop/style/unpack_first' +require_relative 'rubocop/cop/style/variable_interpolation' +require_relative 'rubocop/cop/style/when_then' +require_relative 'rubocop/cop/style/while_until_do' +require_relative 'rubocop/cop/style/while_until_modifier' +require_relative 'rubocop/cop/style/word_array' +require_relative 'rubocop/cop/style/yaml_file_read' +require_relative 'rubocop/cop/style/yoda_condition' +require_relative 'rubocop/cop/style/yoda_expression' +require_relative 'rubocop/cop/style/zero_length_predicate' + +require_relative 'rubocop/cop/security/compound_hash' +require_relative 'rubocop/cop/security/eval' +require_relative 'rubocop/cop/security/io_methods' +require_relative 'rubocop/cop/security/json_load' +require_relative 'rubocop/cop/security/marshal_load' +require_relative 'rubocop/cop/security/open' +require_relative 'rubocop/cop/security/yaml_load' + +require_relative 'rubocop/cop/team' +require_relative 'rubocop/formatter' + +require_relative 'rubocop/cached_data' +require_relative 'rubocop/config' +require_relative 'rubocop/config_loader_resolver' +require_relative 'rubocop/config_loader' +require_relative 'rubocop/config_obsoletion/rule' +require_relative 'rubocop/config_obsoletion/cop_rule' +require_relative 'rubocop/config_obsoletion/parameter_rule' +require_relative 'rubocop/config_obsoletion/changed_enforced_styles' +require_relative 'rubocop/config_obsoletion/changed_parameter' +require_relative 'rubocop/config_obsoletion/extracted_cop' +require_relative 'rubocop/config_obsoletion/removed_cop' +require_relative 'rubocop/config_obsoletion/renamed_cop' +require_relative 'rubocop/config_obsoletion/split_cop' +require_relative 'rubocop/config_obsoletion' +require_relative 'rubocop/config_store' +require_relative 'rubocop/config_validator' +require_relative 'rubocop/feature_loader' +require_relative 'rubocop/lockfile' +require_relative 'rubocop/lsp' +require_relative 'rubocop/target_finder' +require_relative 'rubocop/directive_comment' +require_relative 'rubocop/comment_config' +require_relative 'rubocop/result_cache' +require_relative 'rubocop/runner' +require_relative 'rubocop/cli' +require_relative 'rubocop/cli/command' +require_relative 'rubocop/cli/environment' +require_relative 'rubocop/cli/command/base' +require_relative 'rubocop/cli/command/auto_generate_config' +require_relative 'rubocop/cli/command/execute_runner' +require_relative 'rubocop/cli/command/init_dotfile' +require_relative 'rubocop/cli/command/lsp' +require_relative 'rubocop/cli/command/show_cops' +require_relative 'rubocop/cli/command/show_docs_url' +require_relative 'rubocop/cli/command/suggest_extensions' +require_relative 'rubocop/cli/command/version' +require_relative 'rubocop/config_regeneration' +require_relative 'rubocop/options' +require_relative 'rubocop/remote_config' +require_relative 'rubocop/target_ruby' +require_relative 'rubocop/yaml_duplication_checker' + +# rubocop:enable Style/RequireOrder + +unless File.exist?("#{__dir__}/../rubocop.gemspec") # Check if we are a gem + RuboCop::ResultCache.rubocop_required_features = $LOADED_FEATURES - before_us +end +RuboCop::AST.rubocop_loaded if RuboCop::AST.respond_to?(:rubocop_loaded) diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/arguments_env.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/arguments_env.rb new file mode 100644 index 00000000..39b8a412 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/arguments_env.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module RuboCop + # This is a class that reads optional command line arguments to rubocop from environment variable. + # @api private + class ArgumentsEnv + def self.read_as_arguments + if (arguments = ENV.fetch('RUBOCOP_OPTS', '')).empty? + [] + else + require 'shellwords' + + Shellwords.split(arguments) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/arguments_file.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/arguments_file.rb new file mode 100644 index 00000000..bf90a137 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/arguments_file.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module RuboCop + # This is a class that reads optional command line arguments to rubocop from .rubocop file. + # @api private + class ArgumentsFile + def self.read_as_arguments + if File.exist?('.rubocop') && !File.directory?('.rubocop') + require 'shellwords' + + File.read('.rubocop').shellsplit + else + [] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/ast_aliases.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/ast_aliases.rb new file mode 100644 index 00000000..e0f0cd3d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/ast_aliases.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +# These aliases are for compatibility. +module RuboCop + NodePattern = AST::NodePattern + ProcessedSource = AST::ProcessedSource + Token = AST::Token +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cache_config.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cache_config.rb new file mode 100644 index 00000000..504a32e8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cache_config.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module RuboCop + # This class represents the cache config of the caching RuboCop runs. + # @api private + class CacheConfig + def self.root_dir + root = ENV.fetch('RUBOCOP_CACHE_ROOT', nil) + root ||= yield + root ||= if ENV.key?('XDG_CACHE_HOME') + # Include user ID in the path to make sure the user has write + # access. + File.join(ENV.fetch('XDG_CACHE_HOME'), Process.uid.to_s) + else + # On FreeBSD, the /home path is a symbolic link to /usr/home + # and the $HOME environment variable returns the /home path. + # + # As $HOME is a built-in environment variable, FreeBSD users + # always get a warning message. + # + # To avoid raising warn log messages on FreeBSD, we retrieve + # the real path of the home folder. + File.join(File.realpath(Dir.home), '.cache') + end + + File.join(root, 'rubocop_cache') + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cached_data.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cached_data.rb new file mode 100644 index 00000000..0cb0b369 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cached_data.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +require 'json' + +module RuboCop + # Converts RuboCop objects to and from the serialization format JSON. + # @api private + class CachedData + def initialize(filename) + @filename = filename + end + + def from_json(text) + deserialize_offenses(JSON.parse(text)) + end + + def to_json(offenses) + JSON.dump(offenses.map { |o| serialize_offense(o) }) + end + + private + + def serialize_offense(offense) + status = :uncorrected if %i[corrected corrected_with_todo].include?(offense.status) + { + # Calling #to_s here ensures that the serialization works when using + # other json serializers such as Oj. Some of these gems do not call + # #to_s implicitly. + severity: offense.severity.to_s, + location: { + begin_pos: offense.location.begin_pos, + end_pos: offense.location.end_pos + }, + message: message(offense), + cop_name: offense.cop_name, + status: status || offense.status + } + end + + def message(offense) + # JSON.dump will fail if the offense message contains text which is not + # valid UTF-8 + offense.message.dup.force_encoding(::Encoding::UTF_8).scrub + end + + # Restore an offense object loaded from a JSON file. + def deserialize_offenses(offenses) + offenses.map! do |o| + location = location_from_source_buffer(o) + Cop::Offense.new(o['severity'], location, o['message'], o['cop_name'], o['status'].to_sym) + end + end + + def location_from_source_buffer(offense) + begin_pos = offense['location']['begin_pos'] + end_pos = offense['location']['end_pos'] + if begin_pos.zero? && end_pos.zero? + Cop::Offense::NO_LOCATION + else + Parser::Source::Range.new(source_buffer, begin_pos, end_pos) + end + end + + # Delay creation until needed. Some type of offenses will have no buffer associated with them + # and be global only. For these, trying to create the buffer will likely fail, for example + # because of unknown encoding comments. + def source_buffer + @source_buffer ||= begin + source = File.read(@filename, encoding: Encoding::UTF_8) + Parser::Source::Buffer.new(@filename, source: source) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli.rb new file mode 100644 index 00000000..ba497078 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli.rb @@ -0,0 +1,212 @@ +# frozen_string_literal: true + +require 'fileutils' + +module RuboCop + # The CLI is a class responsible of handling all the command line interface + # logic. + class CLI + STATUS_SUCCESS = 0 + STATUS_OFFENSES = 1 + STATUS_ERROR = 2 + STATUS_INTERRUPTED = Signal.list['INT'] + 128 + DEFAULT_PARALLEL_OPTIONS = %i[ + color config debug display_style_guide display_time display_only_fail_level_offenses + display_only_failed editor_mode except extra_details fail_level fix_layout format + ignore_disable_comments lint only only_guide_cops require safe + autocorrect safe_autocorrect autocorrect_all + ].freeze + + class Finished < StandardError; end + + attr_reader :options, :config_store + + def initialize + @options = {} + @config_store = ConfigStore.new + end + + # @api public + # + # Entry point for the application logic. Here we + # do the command line arguments processing and inspect + # the target files. + # + # @param args [Array] command line arguments + # @return [Integer] UNIX exit code + # + # rubocop:disable Metrics/MethodLength, Metrics/AbcSize + def run(args = ARGV) + @options, paths = Options.new.parse(args) + @env = Environment.new(@options, @config_store, paths) + + profile_if_needed do + if @options[:init] + run_command(:init) + else + act_on_options + validate_options_vs_config + parallel_by_default! + apply_default_formatter + execute_runners + end + end + rescue ConfigNotFoundError, IncorrectCopNameError, OptionArgumentError => e + warn Rainbow(e.message).red + STATUS_ERROR + rescue RuboCop::Error => e + warn Rainbow("Error: #{e.message}").red + STATUS_ERROR + rescue Interrupt + warn '' + warn 'Exiting...' + STATUS_INTERRUPTED + rescue Finished + STATUS_SUCCESS + rescue OptionParser::InvalidOption => e + warn e.message + warn 'For usage information, use --help' + STATUS_ERROR + rescue StandardError, SyntaxError, LoadError => e + warn e.message + warn e.backtrace + STATUS_ERROR + end + # rubocop:enable Metrics/MethodLength, Metrics/AbcSize + + private + + # rubocop:disable Metrics/MethodLength, Metrics/AbcSize + def profile_if_needed + return yield unless @options[:profile] + + return STATUS_ERROR unless require_gem('stackprof') + + with_memory = @options[:memory] + if with_memory + return STATUS_ERROR unless require_gem('memory_profiler') + + MemoryProfiler.start + end + + tmp_dir = File.join(ConfigFinder.project_root, 'tmp') + FileUtils.mkdir_p(tmp_dir) + cpu_profile_file = File.join(tmp_dir, 'rubocop-stackprof.dump') + status = nil + + StackProf.run(out: cpu_profile_file) do + status = yield + end + puts "Profile report generated at #{cpu_profile_file}" + + if with_memory + puts 'Building memory report...' + report = MemoryProfiler.stop + memory_profile_file = File.join(tmp_dir, 'rubocop-memory_profiler.txt') + report.pretty_print(to_file: memory_profile_file, scale_bytes: true) + puts "Memory report generated at #{memory_profile_file}" + end + status + end + # rubocop:enable Metrics/MethodLength, Metrics/AbcSize + + def require_gem(name) + require name + true + rescue LoadError + warn("You don't have #{name} installed. Add it to your Gemfile and run `bundle install`") + false + end + + def run_command(name) + @env.run(name) + end + + def execute_runners + if @options[:auto_gen_config] + run_command(:auto_gen_config) + else + run_command(:execute_runner).tap { suggest_extensions } + end + end + + def suggest_extensions + run_command(:suggest_extensions) + end + + def validate_options_vs_config + return unless @options[:parallel] && !@config_store.for_pwd.for_all_cops['UseCache'] + + raise OptionArgumentError, '-P/--parallel uses caching to speed up execution, so combining ' \ + 'with AllCops: UseCache: false is not allowed.' + end + + def parallel_by_default! + # See https://github.com/rubocop/rubocop/pull/4537 for JRuby and Windows constraints. + return if RUBY_ENGINE != 'ruby' || RuboCop::Platform.windows? + + if (@options.keys - DEFAULT_PARALLEL_OPTIONS).empty? && + @config_store.for_pwd.for_all_cops['UseCache'] != false + puts 'Use parallel by default.' if @options[:debug] + + @options[:parallel] = true + end + end + + def act_on_options + set_options_to_config_loader + handle_editor_mode + + @config_store.options_config = @options[:config] if @options[:config] + @config_store.force_default_config! if @options[:force_default_config] + + handle_exiting_options + + if @options[:color] + # color output explicitly forced on + Rainbow.enabled = true + elsif @options[:color] == false + # color output explicitly forced off + Rainbow.enabled = false + end + end + + def set_options_to_config_loader + ConfigLoader.debug = @options[:debug] + ConfigLoader.disable_pending_cops = @options[:disable_pending_cops] + ConfigLoader.enable_pending_cops = @options[:enable_pending_cops] + ConfigLoader.ignore_parent_exclusion = @options[:ignore_parent_exclusion] + ConfigLoader.ignore_unrecognized_cops = @options[:ignore_unrecognized_cops] + end + + def handle_editor_mode + RuboCop::LSP.enable if @options[:editor_mode] + end + + # rubocop:disable Metrics/CyclomaticComplexity + def handle_exiting_options + return unless Options::EXITING_OPTIONS.any? { |o| @options.key? o } + + run_command(:version) if @options[:version] || @options[:verbose_version] + run_command(:show_cops) if @options[:show_cops] + run_command(:show_docs_url) if @options[:show_docs_url] + run_command(:lsp) if @options[:lsp] + raise Finished + end + # rubocop:enable Metrics/CyclomaticComplexity + + def apply_default_formatter + # This must be done after the options have already been processed, + # because they can affect how ConfigStore behaves + @options[:formatters] ||= begin + if @options[:auto_gen_config] + formatter = 'autogenconf' + else + cfg = @config_store.for_pwd.for_all_cops + formatter = cfg['DefaultFormatter'] || 'progress' + end + [[formatter, @options[:output_path]]] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command.rb new file mode 100644 index 00000000..775e929a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module RuboCop + class CLI + # Home of subcommands in the CLI. + # @api private + module Command + class << self + # Find the command with a given name and run it in an environment. + def run(env, name) + class_for(name).new(env).run + end + + private + + def class_for(name) + Base.by_command_name(name) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/auto_generate_config.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/auto_generate_config.rb new file mode 100644 index 00000000..8963136c --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/auto_generate_config.rb @@ -0,0 +1,167 @@ +# frozen_string_literal: true + +module RuboCop + class CLI + module Command + # Generate a configuration file acting as a TODO list. + # @api private + class AutoGenerateConfig < Base + self.command_name = :auto_gen_config + + AUTO_GENERATED_FILE = '.rubocop_todo.yml' + YAML_OPTIONAL_DOC_START = /\A---(\s+#|\s*\z)/.freeze + PLACEHOLDER = '###rubocop:inherit_here' + + PHASE_1 = 'Phase 1 of 2: run Layout/LineLength cop' + PHASE_2 = 'Phase 2 of 2: run all cops' + + PHASE_1_OVERRIDDEN = '(skipped because the default Layout/LineLength:Max is overridden)' + PHASE_1_DISABLED = '(skipped because Layout/LineLength is disabled)' + PHASE_1_SKIPPED_ONLY_COPS = + '(skipped because a list of cops is passed to the `--only` flag)' + PHASE_1_SKIPPED_ONLY_EXCLUDE = + '(skipped because only excludes will be generated due to `--auto-gen-only-exclude` flag)' + + def run + add_formatter + reset_config_and_auto_gen_file + line_length_contents = maybe_run_line_length_cop + run_all_cops(line_length_contents) + end + + private + + def maybe_run_line_length_cop + if only_exclude? + skip_line_length_cop(PHASE_1_SKIPPED_ONLY_EXCLUDE) + elsif !line_length_enabled?(@config_store.for_pwd) + skip_line_length_cop(PHASE_1_DISABLED) + elsif !same_max_line_length?(@config_store.for_pwd, ConfigLoader.default_configuration) + skip_line_length_cop(PHASE_1_OVERRIDDEN) + elsif options_has_only_flag? + skip_line_length_cop(PHASE_1_SKIPPED_ONLY_COPS) + else + run_line_length_cop + end + end + + def skip_line_length_cop(reason) + puts Rainbow("#{PHASE_1} #{reason}").yellow + '' + end + + def line_length_enabled?(config) + line_length_cop(config)['Enabled'] + end + + def same_max_line_length?(config1, config2) + max_line_length(config1) == max_line_length(config2) + end + + def max_line_length(config) + line_length_cop(config)['Max'] + end + + def line_length_cop(config) + config.for_cop('Layout/LineLength') + end + + def options_has_only_flag? + @options[:only] + end + + def only_exclude? + @options[:auto_gen_only_exclude] + end + + # Do an initial run with only Layout/LineLength so that cops that + # depend on Layout/LineLength:Max get the correct value for that + # parameter. + def run_line_length_cop + puts Rainbow(PHASE_1).yellow + @options[:only] = ['Layout/LineLength'] + execute_runner + @options.delete(:only) + @config_store = ConfigStore.new + @config_store.options_config = @options[:config] if @options[:config] + # Save the todo configuration of the LineLength cop. + File.read(AUTO_GENERATED_FILE).lines.drop_while { |line| line.start_with?('#') }.join + end + + def run_all_cops(line_length_contents) + puts Rainbow(PHASE_2).yellow + result = execute_runner + # This run was made with the current maximum length allowed, so append + # the saved setting for LineLength. + File.open(AUTO_GENERATED_FILE, 'a') { |f| f.write(line_length_contents) } + result + end + + def reset_config_and_auto_gen_file + @config_store = ConfigStore.new + @config_store.options_config = @options[:config] if @options[:config] + File.open(AUTO_GENERATED_FILE, 'w') {} # create or truncate if exists + add_inheritance_from_auto_generated_file(@options[:config]) + end + + def add_formatter + @options[:formatters] << [Formatter::DisabledConfigFormatter, AUTO_GENERATED_FILE] + end + + def execute_runner + Environment.new(@options, @config_store, @paths).run(:execute_runner) + end + + def add_inheritance_from_auto_generated_file(config_file) + file_string = " #{relative_path_to_todo_from_options_config}" + + config_file ||= ConfigFinder::DOTFILE + + if File.exist?(config_file) + files = Array(ConfigLoader.load_yaml_configuration(config_file)['inherit_from']) + + return if files.include?(relative_path_to_todo_from_options_config) + + files.unshift(relative_path_to_todo_from_options_config) + file_string = "\n - #{files.join("\n - ")}" if files.size > 1 + rubocop_yml_contents = existing_configuration(config_file) + end + + write_config_file(config_file, file_string, rubocop_yml_contents) + + puts "Added inheritance from `#{relative_path_to_todo_from_options_config}` " \ + "in `#{ConfigFinder::DOTFILE}`." + end + + def existing_configuration(config_file) + File.read(config_file, encoding: Encoding::UTF_8) + .sub(/^inherit_from: *[^\n]+/, PLACEHOLDER) + .sub(/^inherit_from: *(\n *- *[^\n]+)+/, PLACEHOLDER) + end + + def write_config_file(file_name, file_string, rubocop_yml_contents) + lines = /\S/.match?(rubocop_yml_contents) ? rubocop_yml_contents.split("\n", -1) : [] + unless rubocop_yml_contents&.include?(PLACEHOLDER) + doc_start_index = lines.index { |line| YAML_OPTIONAL_DOC_START.match?(line) } || -1 + lines.insert(doc_start_index + 1, PLACEHOLDER) + end + File.write(file_name, lines.join("\n") + .sub(/#{PLACEHOLDER}\n*/o, "inherit_from:#{file_string}\n\n") + .sub(/\n\n+\Z/, "\n")) + end + + def relative_path_to_todo_from_options_config + return AUTO_GENERATED_FILE unless @options[:config] + + base = Pathname.new(Dir.pwd) + config_dir = Pathname.new(@options[:config]).realpath.dirname + + # Don't have the path start with `/` + return AUTO_GENERATED_FILE if config_dir == base + + "#{base.relative_path_from(config_dir)}/#{AUTO_GENERATED_FILE}" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/base.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/base.rb new file mode 100644 index 00000000..f35798a4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/base.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module RuboCop + class CLI + module Command + # A subcommand in the CLI. + # @api private + class Base + attr_reader :env + + @subclasses = [] + + class << self + attr_accessor :command_name + + def inherited(subclass) + super + @subclasses << subclass + end + + def by_command_name(name) + @subclasses.detect { |s| s.command_name == name } + end + end + + def initialize(env) + @env = env + @options = env.options + @config_store = env.config_store + @paths = env.paths + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/execute_runner.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/execute_runner.rb new file mode 100644 index 00000000..5560b0f0 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/execute_runner.rb @@ -0,0 +1,105 @@ +# frozen_string_literal: true + +module RuboCop + class CLI + module Command + # Run all the selected cops and report the result. + # @api private + class ExecuteRunner < Base + include Formatter::TextUtil + + # Combination of short and long formatter names. + INTEGRATION_FORMATTERS = %w[h html j json ju junit].freeze + + self.command_name = :execute_runner + + def run + execute_runner(@paths) + end + + private + + def execute_runner(paths) + runner = Runner.new(@options, @config_store) + + all_pass_or_excluded = with_redirect do + all_passed = runner.run(paths) + display_summary(runner) + all_passed || @options[:auto_gen_config] + end + + maybe_print_corrected_source + + if runner.aborting? + STATUS_INTERRUPTED + elsif all_pass_or_excluded && runner.errors.empty? + STATUS_SUCCESS + else + STATUS_OFFENSES + end + end + + def with_redirect + if @options[:stderr] + orig_stdout = $stdout + begin + $stdout = $stderr + yield + ensure + $stdout = orig_stdout + end + else + yield + end + end + + def display_summary(runner) + display_warning_summary(runner.warnings) + display_error_summary(runner.errors) + end + + def display_warning_summary(warnings) + return if warnings.empty? + + warn Rainbow("\n#{pluralize(warnings.size, 'warning')}:").yellow + + warnings.each { |warning| warn warning } + end + + def display_error_summary(errors) + return if errors.empty? + + warn Rainbow("\n#{pluralize(errors.size, 'error')} occurred:").red + + errors.each { |error| warn Rainbow(error).red } + + warn Rainbow(<<~WARNING.strip).yellow + Errors are usually caused by RuboCop bugs. + Please, update to the latest RuboCop version if not already in use, and report a bug if the issue still occurs on this version. + #{bug_tracker_uri} + Mention the following information in the issue report: + #{RuboCop::Version.verbose} + WARNING + end + + def bug_tracker_uri + return unless Gem.loaded_specs.key?('rubocop') + + "#{Gem.loaded_specs['rubocop'].metadata['bug_tracker_uri']}\n" + end + + def maybe_print_corrected_source + # Integration tools (like RubyMine) expect to have only the JSON result + # when specifying JSON format. Similar HTML and JUnit are targeted as well. + # See: https://github.com/rubocop/rubocop/issues/8673 + return if INTEGRATION_FORMATTERS.include?(@options[:format]) + + return unless @options[:stdin] && @options[:autocorrect] + + (@options[:stderr] ? $stderr : $stdout).puts '=' * 20 + print @options[:stdin] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/init_dotfile.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/init_dotfile.rb new file mode 100644 index 00000000..dab89307 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/init_dotfile.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +module RuboCop + class CLI + module Command + # Generate a .rubocop.yml file in the current directory. + # @api private + class InitDotfile < Base + DOTFILE = ConfigFinder::DOTFILE + + self.command_name = :init + + def run + path = File.expand_path(DOTFILE) + + if File.exist?(DOTFILE) + warn Rainbow("#{DOTFILE} already exists at #{path}").red + + STATUS_ERROR + else + description = <<~DESC + # The behavior of RuboCop can be controlled via the .rubocop.yml + # configuration file. It makes it possible to enable/disable + # certain cops (checks) and to alter their behavior if they accept + # any parameters. The file can be placed either in your home + # directory or in some project directory. + # + # RuboCop will start looking for the configuration file in the directory + # where the inspected file is and continue its way up to the root directory. + # + # See https://docs.rubocop.org/rubocop/configuration + DESC + + File.write(DOTFILE, description) + + puts "Writing new #{DOTFILE} to #{path}" + + STATUS_SUCCESS + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/lsp.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/lsp.rb new file mode 100644 index 00000000..08d09349 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/lsp.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module RuboCop + class CLI + module Command + # Start Language Server Protocol of RuboCop. + # @api private + class LSP < Base + self.command_name = :lsp + + def run + # Load on demand, `languge-server-protocol` is heavy to require. + require_relative '../../lsp/server' + RuboCop::LSP::Server.new(@config_store).start + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/show_cops.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/show_cops.rb new file mode 100644 index 00000000..b4333396 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/show_cops.rb @@ -0,0 +1,96 @@ +# frozen_string_literal: true + +module RuboCop + class CLI + module Command + # Shows the given cops, or all cops by default, and their configurations + # for the current directory. + # @api private + class ShowCops < Base + self.command_name = :show_cops + + ExactMatcher = Struct.new(:pattern) do + def match?(name) + name == pattern + end + end + + WildcardMatcher = Struct.new(:pattern) do + def match?(name) + File.fnmatch(pattern, name, File::FNM_PATHNAME) + end + end + + def initialize(env) + super + + # Load the configs so the require()s are done for custom cops + @config = @config_store.for(Dir.pwd) + + @cop_matchers = @options[:show_cops].map do |pattern| + if pattern.include?('*') + WildcardMatcher.new(pattern) + else + ExactMatcher.new(pattern) + end + end + end + + def run + print_available_cops + end + + private + + def print_available_cops + registry = Cop::Registry.global + show_all = @cop_matchers.empty? + + puts "# Available cops (#{registry.length}) + config for #{Dir.pwd}: " if show_all + + registry.departments.sort!.each do |department| + print_cops_of_department(registry, department, show_all) + end + end + + def print_cops_of_department(registry, department, show_all) + selected_cops = if show_all + cops_of_department(registry, department) + else + selected_cops_of_department(registry, department) + end + + puts "# Department '#{department}' (#{selected_cops.length}):" if show_all + + print_cop_details(selected_cops) + end + + def print_cop_details(cops) + cops.each do |cop| + puts '# Supports --autocorrect' if cop.support_autocorrect? + puts "#{cop.cop_name}:" + puts config_lines(cop) + puts + end + end + + def selected_cops_of_department(cops, department) + cops_of_department(cops, department).select do |cop| + @cop_matchers.any? do |matcher| + matcher.match?(cop.cop_name) + end + end + end + + def cops_of_department(cops, department) + cops.with_department(department).sort! + end + + def config_lines(cop) + cnf = @config.for_cop(cop) + cnf.to_yaml.lines.to_a.drop(1).map { |line| " #{line}" } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/show_docs_url.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/show_docs_url.rb new file mode 100644 index 00000000..9557f10a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/show_docs_url.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +module RuboCop + class CLI + module Command + # Prints out url to documentation of provided cops + # or documentation base url by default. + # @api private + class ShowDocsUrl < Base + self.command_name = :show_docs_url + + def initialize(env) + super + + @config = @config_store.for(Dir.pwd) + end + + def run + print_documentation_url + end + + private + + def print_documentation_url + puts Cop::Documentation.default_base_url if cops_array.empty? + + cops_array.each do |cop_name| + cop = registry_hash[cop_name] + next if cop.empty? + + url = Cop::Documentation.url_for(cop.first, @config) + puts url if url + end + + puts + end + + def cops_array + @cops_array ||= @options[:show_docs_url] + end + + def registry_hash + @registry_hash ||= Cop::Registry.global.to_h + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/suggest_extensions.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/suggest_extensions.rb new file mode 100644 index 00000000..aaa78dcb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/suggest_extensions.rb @@ -0,0 +1,132 @@ +# frozen_string_literal: true + +module RuboCop + class CLI + module Command + # Suggest RuboCop extensions to install based on Gemfile dependencies. + # Only primary dependencies are evaluated, so if a dependency depends on a + # gem with an extension, it is not suggested. However, if an extension is + # a transitive dependency, it will not be suggested. + # @api private + class SuggestExtensions < Base + # Combination of short and long formatter names. + INCLUDED_FORMATTERS = %w[p progress fu fuubar pa pacman].freeze + + self.command_name = :suggest_extensions + + def run + return if skip? || extensions.none? + + print_install_suggestions if not_installed_extensions.any? + print_load_suggestions if installed_and_not_loaded_extensions.any? + + print_opt_out_instruction + + puts if @options[:display_time] + end + + private + + def skip? + # Disable outputting the notification: + # 1. On CI + # 2. When given RuboCop options that it doesn't make sense for + # 3. For all formatters except specified in `INCLUDED_FORMATTERS'` + ENV.fetch('CI', nil) || + @options[:only] || @options[:debug] || @options[:list_target_files] || + @options[:out] || @options[:stdin] || + !INCLUDED_FORMATTERS.include?(current_formatter) + end + + def print_install_suggestions + puts + puts 'Tip: Based on detected gems, the following ' \ + 'RuboCop extension libraries might be helpful:' + + not_installed_extensions.sort.each do |extension| + puts " * #{extension} (https://rubygems.org/gems/#{extension})" + end + end + + def print_load_suggestions + puts + puts 'The following RuboCop extension libraries are installed but not loaded in config:' + + installed_and_not_loaded_extensions.sort.each do |extension| + puts " * #{extension}" + end + end + + def print_opt_out_instruction + puts + puts 'You can opt out of this message by adding the following to your config ' \ + '(see https://docs.rubocop.org/rubocop/extensions.html#extension-suggestions ' \ + 'for more options):' + puts ' AllCops:' + puts ' SuggestExtensions: false' + end + + def current_formatter + @options[:format] || @config_store.for_pwd.for_all_cops['DefaultFormatter'] || 'p' + end + + def all_extensions + return [] unless lockfile.dependencies.any? + + extensions = @config_store.for_pwd.for_all_cops['SuggestExtensions'] + case extensions + when true + extensions = ConfigLoader.default_configuration.for_all_cops['SuggestExtensions'] + when false, nil + extensions = {} + end + + extensions.select { |_, v| (Array(v) & dependent_gems).any? }.keys + end + + def extensions + not_installed_extensions + installed_and_not_loaded_extensions + end + + def installed_extensions + all_extensions & installed_gems + end + + def not_installed_extensions + all_extensions - installed_gems + end + + def loaded_extensions + rubocop_config = @config_store.for_pwd + + plugin_names = rubocop_config.loaded_plugins.map do |plugin| + plugin.about.name + end + + plugin_names + rubocop_config.loaded_features.to_a + end + + def installed_and_not_loaded_extensions + installed_extensions - loaded_extensions + end + + def lockfile + @lockfile ||= Lockfile.new + end + + def dependent_gems + lockfile.dependencies.map(&:name) + end + + def installed_gems + lockfile.gems.map(&:name) + end + + def puts(*args) + output = (@options[:stderr] ? $stderr : $stdout) + output.puts(*args) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/version.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/version.rb new file mode 100644 index 00000000..02fcd376 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/command/version.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module RuboCop + class CLI + module Command + # Display version. + # @api private + class Version < Base + self.command_name = :version + + def run + puts RuboCop::Version::STRING if @options[:version] + puts RuboCop::Version.verbose(env: env) if @options[:verbose_version] + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/environment.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/environment.rb new file mode 100644 index 00000000..70276eb9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cli/environment.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module RuboCop + class CLI + # Execution environment for a CLI command. + # @api private + class Environment + attr_reader :options, :config_store, :paths + + def initialize(options, config_store, paths) + @options = options + @config_store = config_store + @paths = paths + end + + # Run a command in this environment. + def run(name) + Command.run(self, name) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/comment_config.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/comment_config.rb new file mode 100644 index 00000000..1a854062 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/comment_config.rb @@ -0,0 +1,216 @@ +# frozen_string_literal: true + +module RuboCop + # This class parses the special `rubocop:disable` comments in a source + # and provides a way to check if each cop is enabled at arbitrary line. + class CommentConfig + extend SimpleForwardable + + CONFIG_DISABLED_LINE_RANGE_MIN = -Float::INFINITY + + # This class provides an API compatible with RuboCop::DirectiveComment + # to be used for cops that are disabled in the config file + class ConfigDisabledCopDirectiveComment + include RuboCop::Ext::Comment + + attr_reader :text, :loc, :line_number + + Loc = Struct.new(:expression) + Expression = Struct.new(:line) + + def initialize(cop_name) + @text = "# rubocop:disable #{cop_name}" + @line_number = CONFIG_DISABLED_LINE_RANGE_MIN + @loc = Loc.new(Expression.new(CONFIG_DISABLED_LINE_RANGE_MIN)) + end + end + + CopAnalysis = Struct.new(:line_ranges, :start_line_number) + + attr_reader :processed_source + + def_delegators :@processed_source, :config, :registry + + def initialize(processed_source) + @processed_source = processed_source + @no_directives = !processed_source.raw_source.include?('rubocop') + end + + def cop_enabled_at_line?(cop, line_number) + cop = cop.cop_name if cop.respond_to?(:cop_name) + disabled_line_ranges = cop_disabled_line_ranges[cop] + return true unless disabled_line_ranges + + disabled_line_ranges.none? { |range| range.include?(line_number) } + end + + def cop_opted_in?(cop) + opt_in_cops.include?(cop.cop_name) + end + + def cop_disabled_line_ranges + @cop_disabled_line_ranges ||= analyze + end + + def extra_enabled_comments + disable_count = Hash.new(0) + registry.disabled(config).each do |cop| + disable_count[cop.cop_name] += 1 + end + extra_enabled_comments_with_names(extras: Hash.new { |h, k| h[k] = [] }, names: disable_count) + end + + def comment_only_line?(line_number) + non_comment_token_line_numbers.none?(line_number) + end + + private + + def extra_enabled_comments_with_names(extras:, names:) + each_directive do |directive| + next unless comment_only_line?(directive.line_number) + + if directive.enabled_all? + handle_enable_all(directive, names, extras) + else + handle_switch(directive, names, extras) + end + end + + extras + end + + def opt_in_cops + @opt_in_cops ||= begin + cops = Set.new + each_directive do |directive| + next unless directive.enabled? + next if directive.all_cops? + + cops.merge(directive.raw_cop_names) + end + cops + end + end + + def analyze # rubocop:todo Metrics/AbcSize + return {} if @no_directives + + analyses = Hash.new { |hash, key| hash[key] = CopAnalysis.new([], nil) } + inject_disabled_cops_directives(analyses) + + each_directive do |directive| + directive.cop_names.each do |cop_name| + cop_name = qualified_cop_name(cop_name) + analyses[cop_name] = analyze_cop(analyses[cop_name], directive) + end + end + + analyses.each_with_object({}) do |element, hash| + cop_name, analysis = *element + hash[cop_name] = cop_line_ranges(analysis) + end + end + + def inject_disabled_cops_directives(analyses) + registry.disabled(config).each do |cop| + analyses[cop.cop_name] = analyze_cop( + analyses[cop.cop_name], + DirectiveComment.new(ConfigDisabledCopDirectiveComment.new(cop.cop_name)) + ) + end + end + + def analyze_cop(analysis, directive) + # Disabling cops after comments like `#=SomeDslDirective` does not related to single line + if !comment_only_line?(directive.line_number) || directive.single_line? + analyze_single_line(analysis, directive) + elsif directive.disabled? + analyze_disabled(analysis, directive) + else + analyze_rest(analysis, directive) + end + end + + def analyze_single_line(analysis, directive) + return analysis unless directive.disabled? + + line = directive.line_number + start_line = analysis.start_line_number + + CopAnalysis.new(analysis.line_ranges + [(line..line)], start_line) + end + + def analyze_disabled(analysis, directive) + line = directive.line_number + start_line = analysis.start_line_number + + # Cop already disabled on this line, so we end the current disabled + # range before we start a new range. + return CopAnalysis.new(analysis.line_ranges + [start_line..line], line) if start_line + + CopAnalysis.new(analysis.line_ranges, line) + end + + def analyze_rest(analysis, directive) + line = directive.line_number + start_line = analysis.start_line_number + + return CopAnalysis.new(analysis.line_ranges + [start_line..line], nil) if start_line + + CopAnalysis.new(analysis.line_ranges, nil) + end + + def cop_line_ranges(analysis) + return analysis.line_ranges unless analysis.start_line_number + + analysis.line_ranges + [(analysis.start_line_number..Float::INFINITY)] + end + + def each_directive + return if @no_directives + + processed_source.comments.each do |comment| + directive = DirectiveComment.new(comment) + yield directive if directive.cop_names + end + end + + def qualified_cop_name(cop_name) + Cop::Registry.qualified_cop_name(cop_name.strip, processed_source.file_path) + end + + def non_comment_token_line_numbers + @non_comment_token_line_numbers ||= begin + non_comment_tokens = processed_source.tokens.reject(&:comment?) + non_comment_tokens.map(&:line).uniq + end + end + + def handle_enable_all(directive, names, extras) + enabled_cops = 0 + names.each do |name, counter| + next unless counter.positive? + + names[name] -= 1 + enabled_cops += 1 + end + + extras[directive.comment] << 'all' if enabled_cops.zero? + end + + # Collect cops that have been disabled or enabled by name in a directive comment + # so that `Lint/RedundantCopEnableDirective` can register offenses correctly. + def handle_switch(directive, names, extras) + directive.cop_names.each do |name| + if directive.disabled? + names[name] += 1 + elsif names[name].positive? + names[name] -= 1 + else + extras[directive.comment] << name + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config.rb new file mode 100644 index 00000000..0e2ef092 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config.rb @@ -0,0 +1,400 @@ +# frozen_string_literal: true + +# FIXME: Moving Rails department code to RuboCop Rails will remove +# the following rubocop:disable comment. +# rubocop:disable Metrics/ClassLength +module RuboCop + # This class represents the configuration of the RuboCop application + # and all its cops. A Config is associated with a YAML configuration + # file from which it was read. Several different Configs can be used + # during a run of the rubocop program, if files in several + # directories are inspected. + class Config + include PathUtil + include FileFinder + extend SimpleForwardable + + CopConfig = Struct.new(:name, :metadata) + + EMPTY_CONFIG = {}.freeze + DEFAULT_RAILS_VERSION = 5.0 + attr_reader :loaded_path + + def self.create(hash, path, check: true) + config = new(hash, path) + config.check if check + + config + end + + # rubocop:disable Metrics/AbcSize, Metrics/MethodLength + def initialize(hash = RuboCop::ConfigLoader.default_configuration, loaded_path = nil) + @loaded_path = loaded_path + @for_cop = Hash.new do |h, cop| + cop_name = cop.respond_to?(:cop_name) ? cop.cop_name : cop + + if ConfigObsoletion.deprecated_cop_name?(cop) + # Since a deprecated cop will no longer have a qualified name (as the badge is no + # longer valid), and since we do not want to automatically enable the cop, we just + # set the configuration to an empty hash if it is unset. + # This is necessary to allow a renamed cop have its old configuration merged in + # before being used (which is necessary to allow it to be disabled via config). + cop_options = self[cop_name].dup || {} + else + qualified_cop_name = Cop::Registry.qualified_cop_name(cop_name, loaded_path, warn: false) + cop_options = self[qualified_cop_name].dup || {} + cop_options['Enabled'] = enable_cop?(qualified_cop_name, cop_options) + + # If the cop has deprecated names (ie. it has been renamed), it is possible that + # users will still have old configuration for the cop's old name. In this case, + # if `ConfigObsoletion` is configured to warn rather than error (and therefore + # RuboCop runs), we want to respect the old configuration, so merge it in. + # + # NOTE: If there is configuration for both the cop and a deprecated names, the old + # configuration will be merged on top of the new configuration! + ConfigObsoletion.deprecated_names_for(cop).each do |deprecated_cop_name| + deprecated_config = @for_cop[deprecated_cop_name] + next if deprecated_config.empty? + + warn Rainbow(<<~WARNING).yellow + Warning: Using `#{deprecated_cop_name}` configuration in #{loaded_path} for `#{cop}`. + WARNING + + cop_options.merge!(@for_cop[deprecated_cop_name]) + end + end + + h[cop] = h[cop_name] = cop_options + end + @hash = hash + @validator = ConfigValidator.new(self) + + @badge_config_cache = {}.compare_by_identity + @clusivity_config_exists_cache = {} + end + # rubocop:enable Metrics/AbcSize, Metrics/MethodLength + + def loaded_plugins + @loaded_plugins ||= ConfigLoader.loaded_plugins + end + + def loaded_features + @loaded_features ||= ConfigLoader.loaded_features + end + + def check + deprecation_check { |deprecation_message| warn("#{loaded_path} - #{deprecation_message}") } + @validator.validate + make_excludes_absolute + self + end + + def validate_after_resolution + @validator.validate_after_resolution + self + end + + def_delegators :@hash, :[], :[]=, :delete, :dig, :each, :key?, :keys, :each_key, + :fetch, :map, :merge, :replace, :to_h, :to_hash, :transform_values + def_delegators :@validator, :validate, :target_ruby_version + + def to_s + @to_s ||= @hash.to_s + end + + def signature + @signature ||= Digest::SHA1.hexdigest(to_s) + end + + # True if this is a config file that is shipped with RuboCop + def internal? + base_config_path = File.expand_path(File.join(ConfigLoader::RUBOCOP_HOME, 'config')) + File.expand_path(loaded_path).start_with?(base_config_path) + end + + def make_excludes_absolute + each_key do |key| + dig(key, 'Exclude')&.map! do |exclude_elem| + if exclude_elem.is_a?(String) && !absolute?(exclude_elem) + File.expand_path(File.join(base_dir_for_path_parameters, exclude_elem)) + else + exclude_elem + end + end + end + end + + def add_excludes_from_higher_level(highest_config) + return unless highest_config.for_all_cops['Exclude'] + + excludes = for_all_cops['Exclude'] ||= [] + highest_config.for_all_cops['Exclude'].each do |path| + unless path.is_a?(Regexp) || absolute?(path) + path = File.join(File.dirname(highest_config.loaded_path), path) + end + excludes << path unless excludes.include?(path) + end + end + + def deprecation_check + %w[Exclude Include].each do |key| + plural = "#{key}s" + next unless for_all_cops[plural] + + for_all_cops[key] = for_all_cops[plural] # Stay backwards compatible. + for_all_cops.delete(plural) + yield "AllCops/#{plural} was renamed to AllCops/#{key}" + end + end + + # @return [Config] for the given cop / cop name. + # Note: the 'Enabled' attribute is calculated according to the department's + # and 'AllCops' configuration; other attributes are not inherited. + def for_cop(cop) + @for_cop[cop] + end + + # @return [Config, Hash] for the given cop / cop name. + # If the given cop is enabled, returns its configuration hash. + # Otherwise, returns an empty hash. + def for_enabled_cop(cop) + cop_enabled?(cop) ? for_cop(cop) : EMPTY_CONFIG + end + + # @return [Config] for the given cop merged with that of its department (if any) + # Note: the 'Enabled' attribute is same as that returned by `for_cop` + def for_badge(badge) + @badge_config_cache[badge] ||= begin + department_config = self[badge.department_name] + cop_config = for_cop(badge.to_s) + if department_config + department_config.merge(cop_config) + else + cop_config + end + end + end + + # @return [Boolean] whether config for this badge has 'Include' or 'Exclude' keys + # @api private + def clusivity_config_for_badge?(badge) + exists = @clusivity_config_exists_cache[badge.to_s] + return exists unless exists.nil? + + cop_config = for_badge(badge) + @clusivity_config_exists_cache[badge.to_s] = cop_config['Include'] || cop_config['Exclude'] + end + + # @return [Config] for the given department name. + # Note: the 'Enabled' attribute will be present only if specified + # at the department's level + def for_department(department_name) + @for_department ||= Hash.new { |h, dept| h[dept] = self[dept] || {} } + @for_department[department_name.to_s] + end + + def for_all_cops + @for_all_cops ||= self['AllCops'] || {} + end + + def cop_enabled?(name) + !!for_cop(name)['Enabled'] + end + + def disabled_new_cops? + for_all_cops['NewCops'] == 'disable' + end + + def enabled_new_cops? + for_all_cops['NewCops'] == 'enable' + end + + def active_support_extensions_enabled? + for_all_cops['ActiveSupportExtensionsEnabled'] + end + + def string_literals_frozen_by_default? + for_all_cops['StringLiteralsFrozenByDefault'] + end + + def file_to_include?(file) + relative_file_path = path_relative_to_config(file) + + # Optimization to quickly decide if the given file is hidden (on the top + # level) and cannot be matched by any pattern. + is_hidden = relative_file_path.start_with?('.') && !relative_file_path.start_with?('..') + return false if is_hidden && !possibly_include_hidden? + + absolute_file_path = File.expand_path(file) + + patterns_to_include.any? do |pattern| + if block_given? + yield pattern, relative_file_path, absolute_file_path + else + match_path?(pattern, relative_file_path) || match_path?(pattern, absolute_file_path) + end + end + end + + def allowed_camel_case_file?(file) + # Gemspecs are allowed to have dashes because that fits with bundler best + # practices in the case when the gem is nested under a namespace (e.g., + # `bundler-console` conveys `Bundler::Console`). + return true if File.extname(file) == '.gemspec' + + file_to_include?(file) do |pattern, relative_path, absolute_path| + /[A-Z]/.match?(pattern.to_s) && + (match_path?(pattern, relative_path) || match_path?(pattern, absolute_path)) + end + end + + # Returns true if there's a chance that an Include pattern matches hidden + # files, false if that's definitely not possible. + def possibly_include_hidden? + return @possibly_include_hidden if defined?(@possibly_include_hidden) + + @possibly_include_hidden = patterns_to_include.any? do |s| + s.is_a?(Regexp) || s.start_with?('.') || s.include?('/.') + end + end + + def file_to_exclude?(file) + file = File.expand_path(file) + patterns_to_exclude.any? { |pattern| match_path?(pattern, file) } + end + + def patterns_to_include + for_all_cops['Include'] || [] + end + + def patterns_to_exclude + for_all_cops['Exclude'] || [] + end + + def path_relative_to_config(path) + relative_path(path, base_dir_for_path_parameters) + end + + # Paths specified in configuration files starting with .rubocop are + # relative to the directory where that file is. Paths in other config files + # are relative to the current directory. This is so that paths in + # config/default.yml, for example, are not relative to RuboCop's config + # directory since that wouldn't work. + def base_dir_for_path_parameters + @base_dir_for_path_parameters ||= + if loaded_path && File.basename(loaded_path).start_with?('.rubocop') && + loaded_path != File.join(Dir.home, ConfigLoader::DOTFILE) + File.expand_path(File.dirname(loaded_path)) + else + Dir.pwd + end + end + + def parser_engine + @parser_engine ||= for_all_cops.fetch('ParserEngine', :default).to_sym + end + + def target_rails_version + @target_rails_version ||= + if for_all_cops['TargetRailsVersion'] + for_all_cops['TargetRailsVersion'].to_f + elsif target_rails_version_from_bundler_lock_file + target_rails_version_from_bundler_lock_file + else + DEFAULT_RAILS_VERSION + end + end + + def smart_loaded_path + PathUtil.smart_path(@loaded_path) + end + + # @return [String, nil] + def bundler_lock_file_path + return nil unless loaded_path + + base_path = base_dir_for_path_parameters + ['Gemfile.lock', 'gems.locked'].each do |file_name| + path = find_file_upwards(file_name, base_path) + return path if path + end + nil + end + + def pending_cops + keys.each_with_object([]) do |qualified_cop_name, pending_cops| + department = department_of(qualified_cop_name) + next if department && department['Enabled'] == false + + cop_metadata = self[qualified_cop_name] + next unless cop_metadata['Enabled'] == 'pending' + + pending_cops << CopConfig.new(qualified_cop_name, cop_metadata) + end + end + + # Returns target's locked gem versions (i.e. from Gemfile.lock or gems.locked) + # @returns [Hash{String => Gem::Version}] The locked gem versions, keyed by the gems' names. + def gem_versions_in_target + @gem_versions_in_target ||= read_gem_versions_from_target_lockfile + end + + def inspect # :nodoc: + "#<#{self.class.name}:#{object_id} @loaded_path=#{loaded_path}>" + end + + private + + # @return [Float, nil] The Rails version as a `major.minor` Float. + def target_rails_version_from_bundler_lock_file + @target_rails_version_from_bundler_lock_file ||= read_rails_version_from_bundler_lock_file + end + + # @return [Float, nil] The Rails version as a `major.minor` Float. + def read_rails_version_from_bundler_lock_file + return nil unless gem_versions_in_target + + # Look for `railties` instead of `rails`, to support apps that only use a subset of `rails` + # See https://github.com/rubocop/rubocop/pull/11289 + rails_version_in_target = gem_versions_in_target['railties'] + return nil unless rails_version_in_target + + gem_version_to_major_minor_float(rails_version_in_target) + end + + # @param [Gem::Version] gem_version an object like `Gem::Version.new("7.1.2.3")` + # @return [Float] The major and minor version, like `7.1` + def gem_version_to_major_minor_float(gem_version) + segments = gem_version.segments + Float("#{segments[0]}.#{segments[1]}") + end + + # @returns [Hash{String => Gem::Version}] The locked gem versions, keyed by the gems' names. + def read_gem_versions_from_target_lockfile + lockfile_path = bundler_lock_file_path + return nil unless lockfile_path + + Lockfile.new(lockfile_path).gem_versions + end + + def enable_cop?(qualified_cop_name, cop_options) + # If the cop is explicitly enabled or `Lint/Syntax`, the other checks can be skipped. + return true if cop_options['Enabled'] == true || qualified_cop_name == 'Lint/Syntax' + + department = department_of(qualified_cop_name) + cop_enabled = cop_options.fetch('Enabled') { !for_all_cops['DisabledByDefault'] } + return true if cop_enabled == 'override_department' + return false if department && department['Enabled'] == false + + cop_enabled + end + + def department_of(qualified_cop_name) + *cop_department, _ = qualified_cop_name.split('/') + return nil if cop_department.empty? + + self[cop_department.join('/')] + end + end +end +# rubocop:enable Metrics/ClassLength diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_finder.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_finder.rb new file mode 100644 index 00000000..96a9df2d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_finder.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true + +require_relative 'file_finder' + +module RuboCop + # This class has methods related to finding configuration path. + # @api private + class ConfigFinder + DOTFILE = '.rubocop.yml' + XDG_CONFIG = 'config.yml' + RUBOCOP_HOME = File.realpath(File.join(File.dirname(__FILE__), '..', '..')) + DEFAULT_FILE = File.join(RUBOCOP_HOME, 'config', 'default.yml') + + class << self + include FileFinder + + attr_writer :project_root + + def find_config_path(target_dir) + find_project_dotfile(target_dir) || find_project_root_dot_config || + find_user_dotfile || find_user_xdg_config || DEFAULT_FILE + end + + # Returns the path RuboCop inferred as the root of the project. No file + # searches will go past this directory. + def project_root + @project_root ||= find_project_root + end + + private + + def find_project_root + pwd = Dir.pwd + gems_file = find_last_file_upwards('Gemfile', pwd) || find_last_file_upwards('gems.rb', pwd) + return unless gems_file + + File.dirname(gems_file) + end + + def find_project_dotfile(target_dir) + find_file_upwards(DOTFILE, target_dir, project_root) + end + + def find_project_root_dot_config + return unless project_root + + dotfile = File.join(project_root, '.config', DOTFILE) + return dotfile if File.exist?(dotfile) + + xdg_config = File.join(project_root, '.config', 'rubocop', XDG_CONFIG) + xdg_config if File.exist?(xdg_config) + end + + def find_user_dotfile + return unless ENV.key?('HOME') + + file = File.join(Dir.home, DOTFILE) + + file if File.exist?(file) + end + + def find_user_xdg_config + xdg_config_home = expand_path(ENV.fetch('XDG_CONFIG_HOME', '~/.config')) + xdg_config = File.join(xdg_config_home, 'rubocop', XDG_CONFIG) + + xdg_config if File.exist?(xdg_config) + end + + def expand_path(path) + File.expand_path(path) + rescue ArgumentError + # Could happen because HOME or ID could not be determined. Fall back on + # using the path literally in that case. + path + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_loader.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_loader.rb new file mode 100644 index 00000000..6f5347b8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_loader.rb @@ -0,0 +1,307 @@ +# frozen_string_literal: true + +require 'erb' +require 'yaml' +require_relative 'config_finder' + +module RuboCop + # Raised when a RuboCop configuration file is not found. + class ConfigNotFoundError < Error + end + + # This class represents the configuration of the RuboCop application + # and all its cops. A Config is associated with a YAML configuration + # file from which it was read. Several different Configs can be used + # during a run of the rubocop program, if files in several + # directories are inspected. + class ConfigLoader + DOTFILE = ConfigFinder::DOTFILE + RUBOCOP_HOME = File.realpath(File.join(File.dirname(__FILE__), '..', '..')) + DEFAULT_FILE = File.join(RUBOCOP_HOME, 'config', 'default.yml') + + class << self + include FileFinder + + PENDING_BANNER = <<~BANNER + The following cops were added to RuboCop, but are not configured. Please set Enabled to either `true` or `false` in your `.rubocop.yml` file. + + Please also note that you can opt-in to new cops by default by adding this to your config: + AllCops: + NewCops: enable + BANNER + + attr_accessor :debug, :ignore_parent_exclusion, :disable_pending_cops, :enable_pending_cops, + :ignore_unrecognized_cops + attr_writer :default_configuration + attr_reader :loaded_plugins, :loaded_features + + alias debug? debug + alias ignore_parent_exclusion? ignore_parent_exclusion + + def clear_options + @debug = nil + @loaded_plugins = Set.new + @loaded_features = Set.new + @disable_pending_cops = nil + @enable_pending_cops = nil + @ignore_parent_exclusion = nil + @ignore_unrecognized_cops = nil + FileFinder.root_level = nil + end + + # rubocop:disable Metrics/AbcSize + def load_file(file, check: true) + path = file_path(file) + + hash = load_yaml_configuration(path) + + rubocop_config = Config.create(hash, path, check: false) + plugins = hash.delete('plugins') + loaded_plugins = resolver.resolve_plugins(rubocop_config, plugins) + add_loaded_plugins(loaded_plugins) + + loaded_features = resolver.resolve_requires(path, hash) + add_loaded_features(loaded_features) + + resolver.resolve_inheritance_from_gems(hash) + resolver.resolve_inheritance(path, hash, file, debug?) + hash.delete('inherit_from') + + # Adding missing namespaces only after resolving requires & inheritance, + # since both can introduce new cops that need to be considered here. + add_missing_namespaces(path, hash) + + Config.create(hash, path, check: check) + end + # rubocop:enable Metrics/AbcSize + + def load_yaml_configuration(absolute_path) + file_contents = read_file(absolute_path) + yaml_code = Dir.chdir(File.dirname(absolute_path)) { ERB.new(file_contents).result } + yaml_tree = check_duplication(yaml_code, absolute_path) + hash = yaml_tree_to_hash(yaml_tree) || {} + + puts "configuration from #{absolute_path}" if debug? + + raise(TypeError, "Malformed configuration in #{absolute_path}") unless hash.is_a?(Hash) + + hash + end + + def add_missing_namespaces(path, hash) + # Using `hash.each_key` will cause the + # `can't add a new key into hash during iteration` error + obsoletion = ConfigObsoletion.new(hash) + + hash_keys = hash.keys + hash_keys.each do |key| + next if obsoletion.deprecated_cop_name?(key) + + q = Cop::Registry.qualified_cop_name(key, path) + next if q == key + + hash[q] = hash.delete(key) + end + end + + # Return a recursive merge of two hashes. That is, a normal hash merge, + # with the addition that any value that is a hash, and occurs in both + # arguments, will also be merged. And so on. + def merge(base_hash, derived_hash) + resolver.merge(base_hash, derived_hash) + end + + # Returns the path of .rubocop.yml searching upwards in the + # directory structure starting at the given directory where the + # inspected file is. If no .rubocop.yml is found there, the + # user's home directory is checked. If there's no .rubocop.yml + # there either, the path to the default file is returned. + def configuration_file_for(target_dir) + ConfigFinder.find_config_path(target_dir) + end + + def configuration_from_file(config_file, check: true) + return default_configuration if config_file == DEFAULT_FILE + + config = load_file(config_file, check: check) + config.validate_after_resolution if check + + if ignore_parent_exclusion? + print 'Ignoring AllCops/Exclude from parent folders' if debug? + else + add_excludes_from_files(config, config_file) + end + + merge_with_default(config, config_file).tap do |merged_config| + unless possible_new_cops?(merged_config) + pending_cops = pending_cops_only_qualified(merged_config.pending_cops) + warn_on_pending_cops(pending_cops) unless pending_cops.empty? + end + end + end + + def pending_cops_only_qualified(pending_cops) + pending_cops.select { |cop| Cop::Registry.qualified_cop?(cop.name) } + end + + def possible_new_cops?(config) + disable_pending_cops || enable_pending_cops || + config.disabled_new_cops? || config.enabled_new_cops? + end + + def add_excludes_from_files(config, config_file) + exclusion_file = find_last_file_upwards(DOTFILE, config_file, ConfigFinder.project_root) + + return unless exclusion_file + return if PathUtil.relative_path(exclusion_file) == PathUtil.relative_path(config_file) + + print 'AllCops/Exclude ' if debug? + config.add_excludes_from_higher_level(load_file(exclusion_file)) + end + + def default_configuration + @default_configuration ||= begin + print 'Default ' if debug? + load_file(DEFAULT_FILE) + end + end + + # This API is primarily intended for testing and documenting plugins. + # When testing a plugin using `rubocop/rspec/support`, the plugin is loaded automatically, + # so this API is usually not needed. It is intended to be used only when implementing tests + # that do not use `rubocop/rspec/support`. + # rubocop:disable Metrics/MethodLength + def inject_defaults!(config_yml_path) + if Pathname(config_yml_path).directory? + # TODO: Since the warning noise is expected to be high until some time after the release, + # warnings will only be issued when `RUBYOPT=-w` is specified. + # To proceed step by step, the next step is to remove `$VERBOSE` and always issue warning. + # Eventually, `project_root` will no longer be accepted. + if $VERBOSE + warn Rainbow(<<~MESSAGE).yellow, uplevel: 1 + Use config YAML file path instead of project root directory. + e.g., `path/to/config/default.yml` + MESSAGE + end + # NOTE: For compatibility. + project_root = config_yml_path + path = File.join(project_root, 'config', 'default.yml') + config = load_file(path) + else + hash = ConfigLoader.load_yaml_configuration(config_yml_path.to_s) + config = Config.new(hash, config_yml_path).tap(&:make_excludes_absolute) + end + + @default_configuration = ConfigLoader.merge_with_default(config, path) + end + # rubocop:enable Metrics/MethodLength + + # Returns the path RuboCop inferred as the root of the project. No file + # searches will go past this directory. + # @deprecated Use `RuboCop::ConfigFinder.project_root` instead. + def project_root + warn Rainbow(<<~WARNING).yellow, uplevel: 1 + `RuboCop::ConfigLoader.project_root` is deprecated and will be removed in RuboCop 2.0. \ + Use `RuboCop::ConfigFinder.project_root` instead. + WARNING + + ConfigFinder.project_root + end + + def warn_on_pending_cops(pending_cops) + warn Rainbow(PENDING_BANNER).yellow + + pending_cops.each { |cop| warn_pending_cop cop } + + warn Rainbow('For more information: https://docs.rubocop.org/rubocop/versioning.html').yellow + end + + def warn_pending_cop(cop) + version = cop.metadata['VersionAdded'] || 'N/A' + + warn Rainbow("#{cop.name}: # new in #{version}").yellow + warn Rainbow(' Enabled: true').yellow + end + + # Merges the given configuration with the default one. + def merge_with_default(config, config_file, unset_nil: true) + resolver.merge_with_default(config, config_file, unset_nil: unset_nil) + end + + # @api private + # Used to add plugins that were required inside a config or from + # the CLI using `--plugin`. + def add_loaded_plugins(loaded_plugins) + @loaded_plugins.merge(Array(loaded_plugins)) + end + + # @api private + # Used to add features that were required inside a config or from + # the CLI using `--require`. + def add_loaded_features(loaded_features) + @loaded_features.merge(Array(loaded_features)) + end + + private + + def file_path(file) + File.absolute_path(file.is_a?(RemoteConfig) ? file.file : file) + end + + def resolver + @resolver ||= ConfigLoaderResolver.new + end + + def check_duplication(yaml_code, absolute_path) + smart_path = PathUtil.smart_path(absolute_path) + YAMLDuplicationChecker.check(yaml_code, absolute_path) do |key1, key2| + value = key1.value + # .start_line is only available since ruby 2.5 / psych 3.0 + message = if key1.respond_to? :start_line + line1 = key1.start_line + 1 + line2 = key2.start_line + 1 + "#{smart_path}:#{line1}: " \ + "`#{value}` is concealed by line #{line2}" + else + "#{smart_path}: `#{value}` is concealed by duplicate" + end + warn Rainbow(message).yellow + end + end + + # Read the specified file, or exit with a friendly, concise message on + # stderr. Care is taken to use the standard OS exit code for a "file not + # found" error. + def read_file(absolute_path) + File.read(absolute_path, encoding: Encoding::UTF_8) + rescue Errno::ENOENT + raise ConfigNotFoundError, "Configuration file not found: #{absolute_path}" + end + + def yaml_tree_to_hash(yaml_tree) + yaml_tree_to_hash!(yaml_tree) + rescue ::StandardError + if defined?(::SafeYAML) + raise 'SafeYAML is unmaintained, no longer needed and should be removed' + end + + raise + end + + def yaml_tree_to_hash!(yaml_tree) + return nil unless yaml_tree + + # Optimization: Because we checked for duplicate keys, we already have the + # yaml tree and don't need to parse it again. + # Also see https://github.com/ruby/psych/blob/v5.1.2/lib/psych.rb#L322-L336 + class_loader = YAML::ClassLoader::Restricted.new(%w[Regexp Symbol], []) + scanner = YAML::ScalarScanner.new(class_loader) + visitor = YAML::Visitors::ToRuby.new(scanner, class_loader) + visitor.accept(yaml_tree) + end + end + + # Initializing class ivars + clear_options + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_loader_resolver.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_loader_resolver.rb new file mode 100644 index 00000000..5d727f06 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_loader_resolver.rb @@ -0,0 +1,312 @@ +# frozen_string_literal: true + +require 'pathname' +require 'yaml' +require_relative 'plugin' + +module RuboCop + # A help class for ConfigLoader that handles configuration resolution. + # @api private + class ConfigLoaderResolver # rubocop:disable Metrics/ClassLength + def resolve_plugins(rubocop_config, plugins) + plugins = Array(plugins) - ConfigLoader.loaded_plugins.map { |plugin| plugin.about.name } + return if plugins.empty? + + Plugin.integrate_plugins(rubocop_config, plugins) + end + + def resolve_requires(path, hash) + config_dir = File.dirname(path) + hash.delete('require').tap do |loaded_features| + Array(loaded_features).each do |feature| + if Plugin.plugin_capable?(feature) + # NOTE: Compatibility for before plugins style. + warn Rainbow(<<~MESSAGE).yellow + #{feature} extension supports plugin, specify `plugins: #{feature}` instead of `require: #{feature}` in #{path}. + For more information, see https://docs.rubocop.org/rubocop/plugin_migration_guide.html. + MESSAGE + rubocop_config = Config.create(hash, path, check: false) + + resolve_plugins(rubocop_config, feature) + else + FeatureLoader.load(config_directory_path: config_dir, feature: feature) + end + end + end + end + + def resolve_inheritance(path, hash, file, debug) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize + inherited_files = Array(hash['inherit_from']) + base_configs(path, inherited_files, file) + .each_with_index.reverse_each do |base_config, index| + override_department_setting_for_cops(base_config, hash) + override_enabled_for_disabled_departments(base_config, hash) + + base_config.each do |k, v| + next unless v.is_a?(Hash) + + if hash.key?(k) + v = merge(v, hash[k], + cop_name: k, file: file, debug: debug, + inherited_file: inherited_files[index], + inherit_mode: determine_inherit_mode(hash, k)) + end + hash[k] = v + fix_include_paths(base_config.loaded_path, hash, path, k, v) if v.key?('Include') + end + end + end + + # When one .rubocop.yml file inherits from another .rubocop.yml file, the Include paths in the + # base configuration are relative to the directory where the base configuration file is. For the + # derived configuration, we need to make those paths relative to where the derived configuration + # file is. + def fix_include_paths(base_config_path, hash, path, key, value) + return unless File.basename(base_config_path).start_with?('.rubocop') + + base_dir = File.dirname(base_config_path) + derived_dir = File.dirname(path) + hash[key]['Include'] = value['Include'].map do |include_path| + PathUtil.relative_path(File.join(base_dir, include_path), derived_dir) + end + end + + def resolve_inheritance_from_gems(hash) + gems = hash.delete('inherit_gem') + (gems || {}).each_pair do |gem_name, config_path| + if gem_name == 'rubocop' + raise ArgumentError, "can't inherit configuration from the rubocop gem" + end + + hash['inherit_from'] = Array(hash['inherit_from']) + Array(config_path).reverse_each do |path| + # Put gem configuration first so local configuration overrides it. + hash['inherit_from'].unshift gem_config_path(gem_name, path) + end + end + end + + # Merges the given configuration with the default one. If + # AllCops:DisabledByDefault is true, it changes the Enabled params so that + # only cops from user configuration are enabled. If + # AllCops:EnabledByDefault is true, it changes the Enabled params so that + # only cops explicitly disabled in user configuration are disabled. + def merge_with_default(config, config_file, unset_nil:) + default_configuration = ConfigLoader.default_configuration + + disabled_by_default = config.for_all_cops['DisabledByDefault'] + enabled_by_default = config.for_all_cops['EnabledByDefault'] + + if disabled_by_default || enabled_by_default + default_configuration = transform(default_configuration) do |params| + params.merge('Enabled' => !disabled_by_default) + end + end + + config = handle_disabled_by_default(config, default_configuration) if disabled_by_default + override_enabled_for_disabled_departments(default_configuration, config) + + opts = { inherit_mode: config['inherit_mode'] || {}, unset_nil: unset_nil } + Config.new(merge(default_configuration, config, **opts), config_file) + end + + # Return a recursive merge of two hashes. That is, a normal hash merge, + # with the addition that any value that is a hash, and occurs in both + # arguments, will also be merged. And so on. + # + # rubocop:disable Metrics/AbcSize + def merge(base_hash, derived_hash, **opts) + result = base_hash.merge(derived_hash) + keys_appearing_in_both = base_hash.keys & derived_hash.keys + keys_appearing_in_both.each do |key| + if opts[:unset_nil] && derived_hash[key].nil? + result.delete(key) + elsif merge_hashes?(base_hash, derived_hash, key) + result[key] = merge(base_hash[key], derived_hash[key], **opts) + elsif should_union?(derived_hash, base_hash, opts[:inherit_mode], key) + result[key] = Array(base_hash[key]) | Array(derived_hash[key]) + elsif opts[:debug] + warn_on_duplicate_setting(base_hash, derived_hash, key, **opts) + end + end + result + end + # rubocop:enable Metrics/AbcSize + + # An `Enabled: true` setting in user configuration for a cop overrides an + # `Enabled: false` setting for its department. + def override_department_setting_for_cops(base_hash, derived_hash) + derived_hash.each_key do |key| + next unless key =~ %r{(.*)/.*} + + department = Regexp.last_match(1) + next unless disabled?(derived_hash, department) || disabled?(base_hash, department) + + # The `override_department` setting for the `Enabled` parameter is an + # internal setting that's not documented in the manual. It will cause a + # cop to be enabled later, when logic surrounding enabled/disabled it + # run, even though its department is disabled. + derived_hash[key]['Enabled'] = 'override_department' if derived_hash[key]['Enabled'] + end + end + + # If a cop was previously explicitly enabled, but then superseded by the + # department being disabled, disable it. + def override_enabled_for_disabled_departments(base_hash, derived_hash) + cops_to_disable = derived_hash.each_key.with_object([]) do |key, cops| + next unless disabled?(derived_hash, key) + + cops.concat(base_hash.keys.grep(Regexp.new("^#{key}/"))) + end + + cops_to_disable.each do |cop_name| + next unless base_hash.dig(cop_name, 'Enabled') == true + + derived_hash.replace(merge({ cop_name => { 'Enabled' => false } }, derived_hash)) + end + end + + private + + def disabled?(hash, department) + hash[department].is_a?(Hash) && hash[department]['Enabled'] == false + end + + def duplicate_setting?(base_hash, derived_hash, key, inherited_file) + return false if inherited_file.nil? # Not inheritance resolving merge + return false if inherited_file.start_with?('..') # Legitimate override + return false if base_hash[key] == derived_hash[key] # Same value + return false if PathUtil.remote_file?(inherited_file) # Can't change + + Gem.path.none? { |dir| inherited_file.start_with?(dir) } # Can change? + end + + def warn_on_duplicate_setting(base_hash, derived_hash, key, **opts) + # If the file being considered is remote, don't bother checking for duplicates + return if remote_config?(opts[:file]) + + return unless duplicate_setting?(base_hash, derived_hash, key, opts[:inherited_file]) + + inherit_mode = opts[:inherit_mode]['merge'] || opts[:inherit_mode]['override'] + return if base_hash[key].is_a?(Array) && inherit_mode&.include?(key) + + puts duplicate_setting_warning(opts, key) + end + + def duplicate_setting_warning(opts, key) + "#{PathUtil.smart_path(opts[:file])}: " \ + "#{opts[:cop_name]}:#{key} overrides " \ + "the same parameter in #{opts[:inherited_file]}" + end + + def determine_inherit_mode(hash, key) + cop_cfg = hash[key] + local_inherit = cop_cfg['inherit_mode'] if cop_cfg.is_a?(Hash) + local_inherit || hash['inherit_mode'] || {} + end + + def should_union?(derived_hash, base_hash, root_mode, key) + return false unless base_hash[key].is_a?(Array) || derived_hash[key].is_a?(Array) + + derived_mode = derived_hash['inherit_mode'] + return false if should_override?(derived_mode, key) + return true if should_merge?(derived_mode, key) + + base_mode = base_hash['inherit_mode'] + return false if should_override?(base_mode, key) + return true if should_merge?(base_mode, key) + + should_merge?(root_mode, key) + end + + def should_merge?(mode, key) + mode && mode['merge']&.include?(key) + end + + def should_override?(mode, key) + mode && mode['override']&.include?(key) + end + + def merge_hashes?(base_hash, derived_hash, key) + base_hash[key].is_a?(Hash) && derived_hash[key].is_a?(Hash) + end + + def base_configs(path, inherit_from, file) + inherit_froms = Array(inherit_from).compact.flat_map do |f| + PathUtil.glob?(f) ? Dir.glob(f) : f + end + + configs = inherit_froms.map do |f| + ConfigLoader.load_file(inherited_file(path, f, file)) + end + + configs.compact + end + + def inherited_file(path, inherit_from, file) + if PathUtil.remote_file?(inherit_from) + # A remote configuration, e.g. `inherit_from: http://example.com/rubocop.yml`. + RemoteConfig.new(inherit_from, File.dirname(path)) + elsif Pathname.new(inherit_from).absolute? + # An absolute path to a config, e.g. `inherit_from: /Users/me/rubocop.yml`. + # The path may come from `inherit_gem` option, where a gem name is expanded + # to an absolute path to that gem. + print 'Inheriting ' if ConfigLoader.debug? + inherit_from + elsif file.is_a?(RemoteConfig) + # A path relative to a URL, e.g. `inherit_from: configs/default.yml` + # in a config included with `inherit_from: http://example.com/rubocop.yml` + file.inherit_from_remote(inherit_from, path) + else + # A local relative path, e.g. `inherit_from: default.yml` + print 'Inheriting ' if ConfigLoader.debug? + File.expand_path(inherit_from, File.dirname(path)) + end + end + + def remote_config?(file) + file.is_a?(RemoteConfig) + end + + def handle_disabled_by_default(config, new_default_configuration) + department_config = config.to_hash.reject { |cop| cop.include?('/') } + department_config.each do |dept, dept_params| + next unless dept_params['Enabled'] + + new_default_configuration.each do |cop, params| + next unless cop.start_with?("#{dept}/") + + # Retain original default configuration for cops in the department. + params['Enabled'] = ConfigLoader.default_configuration[cop]['Enabled'] + end + end + + transform(config) do |params| + { 'Enabled' => true }.merge(params) # Set true if not set. + end + end + + def transform(config, &block) + config.transform_values(&block) + end + + def gem_config_path(gem_name, relative_config_path) + if defined?(Bundler) + begin + gem = Bundler.load.specs[gem_name].first + gem_path = gem.full_gem_path if gem + rescue Bundler::GemfileNotFound + # No Gemfile found. Bundler may be loaded manually + rescue Bundler::GitError + # The Gemfile exists but contains an uninstalled git source + end + end + + gem_path ||= Gem::Specification.find_by_name(gem_name).gem_dir + + File.join(gem_path, relative_config_path) + rescue Gem::LoadError => e + raise Gem::LoadError, "Unable to find gem #{gem_name}; is the gem installed? #{e}" + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion.rb new file mode 100644 index 00000000..23cea6b6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion.rb @@ -0,0 +1,155 @@ +# frozen_string_literal: true + +module RuboCop + # This class handles obsolete configuration. + # @api private + class ConfigObsoletion + DEFAULT_RULES_FILE = File.join(ConfigLoader::RUBOCOP_HOME, 'config', 'obsoletion.yml') + COP_RULE_CLASSES = { + 'renamed' => RenamedCop, + 'removed' => RemovedCop, + 'split' => SplitCop, + 'extracted' => ExtractedCop + }.freeze + PARAMETER_RULE_CLASSES = { + 'changed_parameters' => ChangedParameter, + 'changed_enforced_styles' => ChangedEnforcedStyles + }.freeze + LOAD_RULES_CACHE = {} # rubocop:disable Style/MutableConstant + private_constant :LOAD_RULES_CACHE + + attr_reader :rules, :warnings + + class << self + attr_accessor :files + + def global + @global ||= new(Config.new) + end + + def reset! + @global = nil + @deprecated_names = {} + LOAD_RULES_CACHE[rules_cache_key] = nil + end + + def rules_cache_key + files.hash + end + + def legacy_cop_names + # Used by DepartmentName#qualified_legacy_cop_name + global.legacy_cop_names + end + + def deprecated_cop_name?(name) + global.deprecated_cop_name?(name) + end + + def deprecated_names_for(cop) + @deprecated_names ||= {} + return @deprecated_names[cop] if @deprecated_names.key?(cop) + + @deprecated_names[cop] = global.rules.filter_map do |rule| + next unless rule.cop_rule? + next unless rule.respond_to?(:new_name) + next unless rule.new_name == cop + + rule.old_name + end + end + end + + # Can be extended by extension libraries to add their own obsoletions + self.files = [DEFAULT_RULES_FILE] + + def initialize(config) + @config = config + @rules = load_rules + @warnings = [] + end + + def reject_obsolete! + messages = obsoletions.flatten.compact + return if messages.empty? + + raise ValidationError, messages.join("\n") + end + + def legacy_cop_names + # Used by DepartmentName#qualified_legacy_cop_name + cop_rules.map(&:old_name) + end + + def deprecated_cop_name?(name) + legacy_cop_names.include?(name) + end + + private + + # Default rules for obsoletions are in config/obsoletion.yml + # Additional rules files can be added with `RuboCop::ConfigObsoletion.files << filename` + def load_rules # rubocop:disable Metrics/AbcSize + rules = LOAD_RULES_CACHE[self.class.rules_cache_key] ||= + self.class.files.each_with_object({}) do |filename, hash| + hash.merge!(YAML.safe_load(File.read(filename)) || {}) do |_key, first, second| + case first + when Hash + first.merge(second) + when Array + first.concat(second) + end + end + end + + cop_rules = rules.slice(*COP_RULE_CLASSES.keys) + parameter_rules = rules.slice(*PARAMETER_RULE_CLASSES.keys) + + load_cop_rules(cop_rules).concat(load_parameter_rules(parameter_rules)) + end + + # Cop rules are keyed by the name of the original cop + def load_cop_rules(rules) + rules.flat_map do |rule_type, data| + data.filter_map do |cop_name, configuration| + next unless configuration # allow configurations to be disabled with `CopName: ~` + + COP_RULE_CLASSES[rule_type].new(@config, cop_name, configuration) + end + end + end + + # Parameter rules may apply to multiple cops and multiple parameters + # and are given as an array. Each combination is turned into a separate + # rule object. + def load_parameter_rules(rules) + rules.flat_map do |rule_type, data| + data.flat_map do |configuration| + cops = Array(configuration['cops']) + parameters = Array(configuration['parameters']) + + cops.product(parameters).map do |cop, parameter| + PARAMETER_RULE_CLASSES[rule_type].new(@config, cop, parameter, configuration) + end + end + end + end + + def obsoletions + rules.map do |rule| + next unless rule.violated? + + if rule.warning? + @warnings.push(rule.message) + next + end + + rule.message + end + end + + def cop_rules + rules.select(&:cop_rule?) + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/changed_enforced_styles.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/changed_enforced_styles.rb new file mode 100644 index 00000000..89e88990 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/changed_enforced_styles.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +module RuboCop + class ConfigObsoletion + # Encapsulation of a ConfigObsoletion rule for changing a parameter + # @api private + class ChangedEnforcedStyles < ParameterRule + BASE_MESSAGE = 'obsolete `%s: %s` (for `%s`) found in %s' + + def violated? + super && config[cop][parameter] == value + end + + def message + base = format(BASE_MESSAGE, + parameter: parameter, value: value, cop: cop, path: smart_loaded_path) + + if alternative + "#{base}\n`#{parameter}: #{value}` has been renamed to " \ + "`#{parameter}: #{alternative.chomp}`." + else + "#{base}\n#{reason.chomp}" + end + end + + private + + def value + metadata['value'] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/changed_parameter.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/changed_parameter.rb new file mode 100644 index 00000000..49905717 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/changed_parameter.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module RuboCop + class ConfigObsoletion + # Encapsulation of a ConfigObsoletion rule for changing a parameter + # @api private + class ChangedParameter < ParameterRule + BASE_MESSAGE = 'obsolete parameter `%s` (for `%s`) found in %s' + + def message + base = format(BASE_MESSAGE, parameter: parameter, cop: cop, path: smart_loaded_path) + + if alternative + "#{base}\n`#{parameter}` has been renamed to `#{alternative.chomp}`." + elsif alternatives + "#{base}\n`#{parameter}` has been renamed to #{to_sentence(alternatives.map do |item| + "`#{item}`" + end, + connector: 'and/or')}." + else + "#{base}\n#{reason.chomp}" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/cop_rule.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/cop_rule.rb new file mode 100644 index 00000000..28c65d66 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/cop_rule.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +module RuboCop + class ConfigObsoletion + # Base class for ConfigObsoletion rules relating to cops + # @api private + class CopRule < Rule + attr_reader :old_name + + def initialize(config, old_name) + super(config) + @old_name = old_name + end + + def cop_rule? + true + end + + def message + rule_message + "\n(obsolete configuration found in #{smart_loaded_path}, please update it)" + end + + # Cop rules currently can only be failures, not warnings + def warning? + false + end + + def violated? + config.key?(old_name) || config.key?(Cop::Badge.parse(old_name).cop_name) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/extracted_cop.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/extracted_cop.rb new file mode 100644 index 00000000..650eaf13 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/extracted_cop.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +module RuboCop + class ConfigObsoletion + # Encapsulation of a ConfigObsoletion rule for splitting a cop's + # functionality into multiple new cops. + # @api private + class ExtractedCop < CopRule + attr_reader :gem, :department + + def initialize(config, old_name, gem) + super(config, old_name) + @department, * = old_name.rpartition('/') + @gem = gem + end + + def violated? + return false if plugin_loaded? + + affected_cops.any? + end + + def rule_message + msg = '%s been extracted to the `%s` gem.' + format(msg, + name: affected_cops.size > 1 ? "`#{department}` cops have" : "`#{old_name}` has", + gem: gem) + end + + private + + def affected_cops + return old_name unless old_name.end_with?('*') + + # Handle whole departments (expressed as `Department/*`) + config.keys.select do |key| + key == department || key.start_with?("#{department}/") + end + end + + def plugin_loaded? + # Plugins loaded via `require` are included in `loaded_features`. + config.loaded_plugins.include?(gem) || config.loaded_features.include?(gem) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/parameter_rule.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/parameter_rule.rb new file mode 100644 index 00000000..8df4655b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/parameter_rule.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +module RuboCop + class ConfigObsoletion + # Base class for ConfigObsoletion rules relating to parameters + # @api private + class ParameterRule < Rule + attr_reader :cop, :parameter, :metadata + + def initialize(config, cop, parameter, metadata) + super(config) + @cop = cop + @parameter = parameter + @metadata = metadata + end + + def parameter_rule? + true + end + + def violated? + applies_to_current_ruby_version? && config[cop]&.key?(parameter) + end + + def warning? + severity == 'warning' + end + + private + + def applies_to_current_ruby_version? + minimum_ruby_version = metadata['minimum_ruby_version'] + + return true unless minimum_ruby_version + + config.target_ruby_version >= minimum_ruby_version + end + + def alternative + metadata['alternative'] + end + + def alternatives + metadata['alternatives'] + end + + def reason + metadata['reason'] + end + + def severity + metadata['severity'] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/removed_cop.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/removed_cop.rb new file mode 100644 index 00000000..03fa8fed --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/removed_cop.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module RuboCop + class ConfigObsoletion + # Encapsulation of a ConfigObsoletion rule for removing + # a previously defined cop. + # @api private + class RemovedCop < CopRule + attr_reader :old_name, :metadata + + BASE_MESSAGE = 'The `%s` cop has been removed' + + def initialize(config, old_name, metadata) + super(config, old_name) + @metadata = metadata.is_a?(Hash) ? metadata : {} + end + + def rule_message + base = format(BASE_MESSAGE, old_name: old_name) + + if reason + "#{base} since #{reason.chomp}." + elsif alternatives + "#{base}. Please use #{to_sentence(alternatives, connector: 'and/or')} instead." + else + "#{base}." + end + end + + private + + def reason + metadata['reason'] + end + + def alternatives + Array(metadata['alternatives']).map { |name| "`#{name}`" } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/renamed_cop.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/renamed_cop.rb new file mode 100644 index 00000000..7b1301f4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/renamed_cop.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +module RuboCop + class ConfigObsoletion + # Encapsulation of a ConfigObsoletion rule for renaming + # a cop or moving it to a new department. + # @api private + class RenamedCop < CopRule + attr_reader :new_name, :metadata + + def initialize(config, old_name, name_or_hash) + super(config, old_name) + + if name_or_hash.is_a?(Hash) + @metadata = name_or_hash + @new_name = name_or_hash['new_name'] + else + @metadata = {} + @new_name = name_or_hash + end + end + + def rule_message + "The `#{old_name}` cop has been #{verb} to `#{new_name}`." + end + + def warning? + severity == 'warning' + end + + private + + def moved? + old_badge = Cop::Badge.parse(old_name) + new_badge = Cop::Badge.parse(new_name) + + old_badge.department != new_badge.department && old_badge.cop_name == new_badge.cop_name + end + + def verb + moved? ? 'moved' : 'renamed' + end + + def severity + metadata['severity'] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/rule.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/rule.rb new file mode 100644 index 00000000..2ee3637f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/rule.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +module RuboCop + class ConfigObsoletion + # Abstract base class for ConfigObsoletion rules + # @api private + class Rule + def initialize(config) + @config = config + end + + # Does this rule relate to cops? + def cop_rule? + false + end + + # Does this rule relate to parameters? + def parameter_rule? + false + end + + def violated? + raise NotImplementedError + end + + private + + attr_reader :config + + def to_sentence(collection, connector: 'and') + return collection.first if collection.size == 1 + + [collection[0..-2].join(', '), collection[-1]].join(" #{connector} ") + end + + def smart_loaded_path + PathUtil.smart_path(config.loaded_path) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/split_cop.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/split_cop.rb new file mode 100644 index 00000000..92aaa0fa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_obsoletion/split_cop.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module RuboCop + class ConfigObsoletion + # Encapsulation of a ConfigObsoletion rule for splitting a cop's + # functionality into multiple new cops. + # @api private + class SplitCop < CopRule + attr_reader :metadata + + def initialize(config, old_name, metadata) + super(config, old_name) + @metadata = metadata + end + + def rule_message + "The `#{old_name}` cop has been split into #{to_sentence(alternatives)}." + end + + private + + def alternatives + Array(metadata['alternatives']).map { |name| "`#{name}`" } + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_regeneration.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_regeneration.rb new file mode 100644 index 00000000..a4889b68 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_regeneration.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +module RuboCop + # This class handles collecting the options for regenerating a TODO file. + # @api private + class ConfigRegeneration + AUTO_GENERATED_FILE = RuboCop::CLI::Command::AutoGenerateConfig::AUTO_GENERATED_FILE + COMMAND_REGEX = /(?<=`rubocop )(.*?)(?=`)/.freeze + DEFAULT_OPTIONS = { auto_gen_config: true }.freeze + + # Get options from the comment in the TODO file, and parse them as options + def options + # If there's no existing TODO file, generate one + return DEFAULT_OPTIONS unless todo_exists? + + match = generation_command.match(COMMAND_REGEX) + return DEFAULT_OPTIONS unless match + + options = match[1].split + Options.new.parse(options).first + end + + private + + def todo_exists? + File.exist?(AUTO_GENERATED_FILE) && !File.empty?(AUTO_GENERATED_FILE) + end + + def generation_command + File.foreach(AUTO_GENERATED_FILE).take(2).last + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_store.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_store.rb new file mode 100644 index 00000000..69314438 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_store.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +module RuboCop + # Handles caching of configurations and association of inspected + # ruby files to configurations. + class ConfigStore + attr_reader :validated + alias validated? validated + + def initialize + # @options_config stores a config that is specified in the command line. + # This takes precedence over configs located in any directories + @options_config = nil + + # @path_cache maps directories to configuration paths. We search + # for .rubocop.yml only if we haven't already found it for the + # given directory. + @path_cache = {} + + # @object_cache maps configuration file paths to + # configuration objects so we only need to load them once. + @object_cache = {} + + # By default the config is validated before it can be used. + @validated = true + end + + def options_config=(options_config) + loaded_config = ConfigLoader.load_file(options_config) + @options_config = ConfigLoader.merge_with_default(loaded_config, options_config) + end + + def force_default_config! + @options_config = ConfigLoader.default_configuration + end + + def unvalidated + @validated = false + self + end + + def for_file(file) + for_dir(File.dirname(file)) + end + + def for_pwd + for_dir(Dir.pwd) + end + + # If type (file/dir) is known beforehand, + # prefer using #for_file or #for_dir for improved performance + def for(file_or_dir) + dir = if File.directory?(file_or_dir) + file_or_dir + else + File.dirname(file_or_dir) + end + for_dir(dir) + end + + def for_dir(dir) + return @options_config if @options_config + + @path_cache[dir] ||= ConfigLoader.configuration_file_for(dir) + path = @path_cache[dir] + @object_cache[path] ||= begin + print "For #{dir}: " if ConfigLoader.debug? + ConfigLoader.configuration_from_file(path, check: validated?) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_validator.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_validator.rb new file mode 100644 index 00000000..cb2cc6ae --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/config_validator.rb @@ -0,0 +1,291 @@ +# frozen_string_literal: true + +module RuboCop + # Handles validation of configuration, for example cop names, parameter + # names, and Ruby versions. + # rubocop:disable Metrics/ClassLength + class ConfigValidator + extend SimpleForwardable + + # @api private + COMMON_PARAMS = %w[Exclude Include Severity inherit_mode AutoCorrect StyleGuide Details + Enabled Reference References].freeze + # @api private + INTERNAL_PARAMS = %w[Description StyleGuide + VersionAdded VersionChanged VersionRemoved + Reference References Safe SafeAutoCorrect].freeze + # @api private + NEW_COPS_VALUES = %w[pending disable enable].freeze + + # @api private + CONFIG_CHECK_KEYS = %w[Enabled Safe SafeAutoCorrect AutoCorrect References].to_set.freeze + CONFIG_CHECK_DEPARTMENTS = %w[pending override_department].freeze + CONFIG_CHECK_AUTOCORRECTS = %w[always contextual disabled].freeze + private_constant :CONFIG_CHECK_KEYS, :CONFIG_CHECK_DEPARTMENTS + + def_delegators :@config, :smart_loaded_path, :for_all_cops + + def initialize(config) + @config = config + @config_obsoletion = ConfigObsoletion.new(config) + @target_ruby = TargetRuby.new(config) + end + + def validate + check_cop_config_value(@config) + reject_conflicting_safe_settings + + # Don't validate RuboCop's own files further. Avoids infinite recursion. + return if @config.internal? + + valid_cop_names, invalid_cop_names = @config.keys.partition do |key| + ConfigLoader.default_configuration.key?(key) + end + + validate_parameter_shape(valid_cop_names) + + check_obsoletions + alert_about_unrecognized_cops(invalid_cop_names) + validate_new_cops_parameter + validate_parameter_names(valid_cop_names) + validate_enforced_styles(valid_cop_names) + validate_syntax_cop + reject_mutually_exclusive_defaults + end + + # Validations that should only be run after all config resolving has + # taken place: + # * The target ruby version is only checked once the entire inheritance + # chain has been loaded so that only the final value is validated, and + # any obsolete but overridden values are ignored. + def validate_after_resolution + check_target_ruby + end + + def target_ruby_version + target_ruby.version + end + + private + + attr_reader :target_ruby + + def check_obsoletions + @config_obsoletion.reject_obsolete! + return unless @config_obsoletion.warnings.any? + + warn Rainbow("Warning: #{@config_obsoletion.warnings.join("\n")}").yellow + end + + def check_target_ruby + return if target_ruby.supported? + + source = target_ruby.source + last_version = target_ruby.rubocop_version_with_support + + msg = if last_version + "RuboCop found unsupported Ruby version #{target_ruby_version} " \ + "in #{source}. #{target_ruby_version}-compatible " \ + "analysis was dropped after version #{last_version}." + else + 'RuboCop found unknown Ruby version ' \ + "#{target_ruby_version.inspect} in #{source}." + end + + msg += "\nSupported versions: #{TargetRuby.supported_versions.join(', ')}" + + raise ValidationError, msg + end + + def alert_about_unrecognized_cops(invalid_cop_names) + unknown_cops = list_unknown_cops(invalid_cop_names) + + return if unknown_cops.empty? + + if ConfigLoader.ignore_unrecognized_cops + warn Rainbow('The following cops or departments are not ' \ + 'recognized and will be ignored:').yellow + warn unknown_cops.join("\n") + + return + end + + raise ValidationError, unknown_cops.join("\n") + end + + def list_unknown_cops(invalid_cop_names) + unknown_cops = [] + invalid_cop_names.each do |name| + # There could be a custom cop with this name. If so, don't warn + next if Cop::Registry.global.contains_cop_matching?([name]) + next if ConfigObsoletion.deprecated_cop_name?(name) + + # Special case for inherit_mode, which is a directive that we keep in + # the configuration (even though it's not a cop), because it's easier + # to do so than to pass the value around to various methods. + next if name == 'inherit_mode' + + message = <<~MESSAGE.rstrip + unrecognized cop or department #{name} found in #{smart_loaded_path} + #{suggestion(name)} + MESSAGE + + unknown_cops << message + end + + unknown_cops + end + + def suggestion(name) + registry = Cop::Registry.global + departments = registry.departments.map(&:to_s) + suggestions = NameSimilarity.find_similar_names(name, departments + registry.map(&:cop_name)) + if suggestions.any? + "Did you mean `#{suggestions.join('`, `')}`?" + else + # Department names can contain slashes, e.g. Chef/Correctness, but there's no support for + # the concept of higher level departments in RuboCop. It's a flat structure. So if the user + # tries to configure a "top level department", we hint that it's the bottom level + # departments that should be configured. + suggestions = departments.select { |department| department.start_with?("#{name}/") } + "#{name} is not a department. Use `#{suggestions.join('`, `')}`." if suggestions.any? + end + end + + def validate_syntax_cop + syntax_config = @config['Lint/Syntax'] + default_config = ConfigLoader.default_configuration['Lint/Syntax'] + + return unless syntax_config && default_config.merge(syntax_config) != default_config + + raise ValidationError, + "configuration for Lint/Syntax cop found in #{smart_loaded_path}\n" \ + 'It\'s not possible to disable this cop.' + end + + def validate_new_cops_parameter + new_cop_parameter = @config.for_all_cops['NewCops'] + return if new_cop_parameter.nil? || NEW_COPS_VALUES.include?(new_cop_parameter) + + message = "invalid #{new_cop_parameter} for `NewCops` found in" \ + "#{smart_loaded_path}\n" \ + "Valid choices are: #{NEW_COPS_VALUES.join(', ')}" + + raise ValidationError, message + end + + def validate_parameter_shape(valid_cop_names) + valid_cop_names.each do |name| + if @config[name].nil? + raise ValidationError, "empty section #{name.inspect} found in #{smart_loaded_path}" + elsif !@config[name].is_a?(Hash) + raise ValidationError, <<~MESSAGE + The configuration for #{name.inspect} in #{smart_loaded_path} is not a Hash. + + Found: #{@config[name].inspect} + MESSAGE + end + end + end + + def validate_parameter_names(valid_cop_names) + valid_cop_names.each do |name| + each_invalid_parameter(name) do |param, supported_params| + warn Rainbow(<<~MESSAGE).yellow + Warning: #{name} does not support #{param} parameter. + + Supported parameters are: + + - #{supported_params.join("\n - ")} + MESSAGE + end + end + end + + def each_invalid_parameter(cop_name) + default_config = ConfigLoader.default_configuration[cop_name] + + @config[cop_name].each_key do |param| + next if COMMON_PARAMS.include?(param) || default_config.key?(param) + + supported_params = default_config.keys - INTERNAL_PARAMS + + yield param, supported_params + end + end + + def validate_enforced_styles(valid_cop_names) # rubocop:todo Metrics/AbcSize + valid_cop_names.each do |name| + styles = @config[name].select { |key, _| key.start_with?('Enforced') } + + styles.each do |style_name, style| + supported_key = RuboCop::Cop::Util.to_supported_styles(style_name) + valid = ConfigLoader.default_configuration[name][supported_key] + + next unless valid + next if valid.include?(style) + next if validate_support_and_has_list(name, style, valid) + + msg = "invalid #{style_name} '#{style}' for #{name} found in " \ + "#{smart_loaded_path}\n" \ + "Valid choices are: #{valid.join(', ')}" + raise ValidationError, msg + end + end + end + + def validate_support_and_has_list(name, formats, valid) + ConfigLoader.default_configuration[name]['AllowMultipleStyles'] && + formats.is_a?(Array) && + formats.all? { |format| valid.include?(format) } + end + + def reject_mutually_exclusive_defaults + disabled_by_default = for_all_cops['DisabledByDefault'] + enabled_by_default = for_all_cops['EnabledByDefault'] + return unless disabled_by_default && enabled_by_default + + msg = 'Cops cannot be both enabled by default and disabled by default' + raise ValidationError, msg + end + + def reject_conflicting_safe_settings + @config.each do |name, cop_config| + next unless cop_config.is_a?(Hash) + next unless cop_config['Safe'] == false && cop_config['SafeAutoCorrect'] == true + + msg = 'Unsafe cops cannot have a safe autocorrection ' \ + "(section #{name} in #{smart_loaded_path})" + raise ValidationError, msg + end + end + + def check_cop_config_value(hash, parent = nil) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity + hash.each do |key, value| + check_cop_config_value(value, key) if value.is_a?(Hash) + + next unless CONFIG_CHECK_KEYS.include?(key) && value.is_a?(String) + + if key == 'Enabled' && !CONFIG_CHECK_DEPARTMENTS.include?(value) + supposed_values = 'a boolean' + elsif key == 'AutoCorrect' && !CONFIG_CHECK_AUTOCORRECTS.include?(value) + supposed_values = '`always`, `contextual`, `disabled`, or a boolean' + elsif key == 'References' + supposed_values = 'an array of strings' + else + next + end + + raise ValidationError, param_error_message(parent, key, value, supposed_values) + end + end + + # FIXME: Handling colors in exception messages like this is ugly. + def param_error_message(parent, key, value, supposed_values) + "#{Rainbow('').reset}" \ + "Property #{Rainbow(key).yellow} of #{Rainbow(parent).yellow} cop " \ + "is supposed to be #{supposed_values} and #{Rainbow(value).yellow} is not." + end + end + # rubocop:enable Metrics/ClassLength +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/autocorrect_logic.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/autocorrect_logic.rb new file mode 100644 index 00000000..e88bf9cf --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/autocorrect_logic.rb @@ -0,0 +1,159 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # This module encapsulates the logic for autocorrect behavior for a cop. + module AutocorrectLogic + def autocorrect? + autocorrect_requested? && correctable? && autocorrect_enabled? + end + + def autocorrect_with_disable_uncorrectable? + autocorrect_requested? && disable_uncorrectable? && autocorrect_enabled? + end + + def autocorrect_requested? + @options.fetch(:autocorrect, false) + end + + def correctable? + self.class.support_autocorrect? || disable_uncorrectable? + end + + def disable_uncorrectable? + @options[:disable_uncorrectable] == true + end + + def safe_autocorrect? + cop_config.fetch('Safe', true) && cop_config.fetch('SafeAutoCorrect', true) + end + + def autocorrect_enabled? + # allow turning off autocorrect on a cop by cop basis + return true unless cop_config + + # `false` is the same as `disabled` for backward compatibility. + return false if ['disabled', false].include?(cop_config['AutoCorrect']) + + # When LSP is enabled, it is considered as editing source code, + # and autocorrection with `AutoCorrect: contextual` will not be performed. + return false if contextual_autocorrect? && LSP.enabled? + + # :safe_autocorrect is a derived option based on several command-line + # arguments - see RuboCop::Options#add_autocorrection_options + return safe_autocorrect? if @options.fetch(:safe_autocorrect, false) + + true + end + + private + + def disable_offense(offense_range) + unbreakable_range = multiline_ranges(offense_range)&.find do |range| + eol_comment_would_be_inside_literal?(offense_range, range) + end + + if unbreakable_range + disable_offense_before_and_after(range_by_lines(unbreakable_range)) + else + disable_offense_with_eol_or_surround_comment(offense_range) + end + end + + def multiline_ranges(offense_range) + return if offense_range.empty? + + processed_source.ast.each_node.filter_map do |node| + if surrounding_heredoc?(node) + heredoc_range(node) + elsif string_continuation?(node) + range_by_lines(node.source_range) + elsif surrounding_percent_array?(node) || multiline_string?(node) + node.source_range + end + end + end + + def disable_offense_with_eol_or_surround_comment(range) + if line_with_eol_comment_too_long?(range) + disable_offense_before_and_after(range_by_lines(range)) + else + disable_offense_at_end_of_line(range_of_first_line(range)) + end + end + + def eol_comment_would_be_inside_literal?(offense_range, literal_range) + return true if line_with_eol_comment_too_long?(offense_range) + + offense_line = offense_range.line + offense_line >= literal_range.first_line && offense_line < literal_range.last_line + end + + def line_with_eol_comment_too_long?(range) + (range.source_line + eol_comment).length > max_line_length + end + + def surrounding_heredoc?(node) + node.type?(:str, :dstr, :xstr) && node.heredoc? + end + + def heredoc_range(node) + node.source_range.join(node.loc.heredoc_end) + end + + def surrounding_percent_array?(node) + node.array_type? && node.percent_literal? + end + + def string_continuation?(node) + node.type?(:str, :dstr, :xstr) && node.source.match?(/\\\s*$/) + end + + def multiline_string?(node) + node.dstr_type? && node.multiline? + end + + def range_of_first_line(range) + begin_of_first_line = range.begin_pos - range.column + end_of_first_line = begin_of_first_line + range.source_line.length + + Parser::Source::Range.new(range.source_buffer, begin_of_first_line, end_of_first_line) + end + + # Expand the given range to include all of any lines it covers. Does not + # include newline at end of the last line. + def range_by_lines(range) + begin_of_first_line = range.begin_pos - range.column + + last_line = range.source_buffer.source_line(range.last_line) + last_line_offset = last_line.length - range.last_column + end_of_last_line = range.end_pos + last_line_offset + + Parser::Source::Range.new(range.source_buffer, begin_of_first_line, end_of_last_line) + end + + def max_line_length + config.for_cop('Layout/LineLength')['Max'] || 120 + end + + def disable_offense_at_end_of_line(range) + Corrector.new(range).insert_after(range, eol_comment) + end + + def eol_comment + " # rubocop:todo #{cop_name}" + end + + def disable_offense_before_and_after(range_by_lines) + range_with_newline = range_by_lines.resize(range_by_lines.size + 1) + leading_whitespace = range_by_lines.source_line[/^\s*/] + + Corrector.new(range_by_lines).wrap( + range_with_newline, + "#{leading_whitespace}# rubocop:todo #{cop_name}\n", + "#{leading_whitespace}# rubocop:enable #{cop_name}\n" + ) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/badge.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/badge.rb new file mode 100644 index 00000000..3eab9272 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/badge.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # Identifier of all cops containing a department and cop name. + # + # All cops are identified by their badge. For example, the badge for + # `RuboCop::Cop::Layout::IndentationStyle` is `Layout/IndentationStyle`. + # Badges can be parsed as either `Department/CopName` or just `CopName` to + # allow for badge references in source files that omit the department for + # RuboCop to infer. + class Badge + attr_reader :department, :department_name, :cop_name + + def self.for(class_name) + parts = class_name.split('::') + name_deep_enough = parts.length >= 4 + new(name_deep_enough ? parts[2..] : parts.last(2)) + end + + @parse_cache = {} + + def self.parse(identifier) + @parse_cache[identifier] ||= new(identifier.split('/').map! { |i| camel_case(i) }) + end + + def self.camel_case(name_part) + return 'RSpec' if name_part == 'rspec' + return name_part unless name_part.match?(/^[a-z]|_[a-z]/) + + name_part.gsub(/^[a-z]|_[a-z]/) { |match| match[-1, 1].upcase } + end + + def initialize(class_name_parts) + department_parts = class_name_parts[0...-1] + @department = (department_parts.join('/').to_sym unless department_parts.empty?) + @department_name = @department&.to_s + @cop_name = class_name_parts.last + end + + def ==(other) + hash == other.hash + end + alias eql? == + + def hash + # Do hashing manually to reduce Array allocations. + department.hash ^ cop_name.hash # rubocop:disable Security/CompoundHash + end + + def match?(other) + cop_name == other.cop_name && (!qualified? || department == other.department) + end + + def to_s + @to_s ||= qualified? ? "#{department}/#{cop_name}" : cop_name + end + + def qualified? + !department.nil? + end + + def with_department(department) + self.class.new([department.to_s.split('/'), cop_name].flatten) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/base.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/base.rb new file mode 100644 index 00000000..78e5c0f9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/base.rb @@ -0,0 +1,547 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # A scaffold for concrete cops. + # + # The Cop::Base class is meant to be extended. + # + # Cops track offenses and can autocorrect them on the fly. + # + # A commissioner object is responsible for traversing the AST and invoking + # the specific callbacks on each cop. + # + # First the callback `on_new_investigation` is called; + # if a cop needs to do its own processing of the AST or depends on + # something else. + # + # Then callbacks like `on_def`, `on_send` (see AST::Traversal) are called + # with their respective nodes. + # + # Finally the callback `on_investigation_end` is called. + # + # Within these callbacks, cops are meant to call `add_offense` or + # `add_global_offense`. Use the `processed_source` method to + # get the currently processed source being investigated. + # + # In case of invalid syntax / unparsable content, + # the callback `on_other_file` is called instead of all the other + # `on_...` callbacks. + # + # Private methods are not meant for custom cops consumption, + # nor are any instance variables. + # + class Base # rubocop:disable Metrics/ClassLength + extend RuboCop::AST::Sexp + extend NodePattern::Macros + extend ExcludeLimit + include RuboCop::AST::Sexp + include Util + include IgnoredNode + include AutocorrectLogic + + attr_reader :config, :processed_source + + # Reports of an investigation. + # Immutable + # Consider creation API private + InvestigationReport = Struct.new(:cop, :processed_source, :offenses, :corrector) + + # List of methods names to restrict calls for `on_send` / `on_csend` + RESTRICT_ON_SEND = Set[].freeze # rubocop:disable InternalAffairs/UselessRestrictOnSend + + # List of cops that should not try to autocorrect at the same + # time as this cop + # + # @return [Array] + # + # @api public + def self.autocorrect_incompatible_with + [] + end + + # Returns a url to view this cops documentation online. + # Requires 'DocumentationBaseURL' to be set for your department. + # Will follow the convention of RuboCops own documentation structure, + # overwrite this method to accommodate your custom layout. + # @return [String, nil] + # + # @api public + def self.documentation_url(config = nil) + Documentation.url_for(self, config) + end + + def self.inherited(subclass) + super + subclass.instance_variable_set(:@gem_requirements, gem_requirements.dup) + Registry.global.enlist(subclass) + end + + # Call for abstract Cop classes + def self.exclude_from_registry + Registry.global.dismiss(self) + end + + # Returns if class supports autocorrect. + # It is recommended to extend AutoCorrector instead of overriding + def self.support_autocorrect? + false + end + + ### Naming + + def self.badge + @badge ||= Badge.for(name) + end + + def self.cop_name + badge.to_s + end + + def self.department + badge.department + end + + def self.lint? + department == :Lint + end + + # Returns true if the cop name or the cop namespace matches any of the + # given names. + def self.match?(given_names) + return false unless given_names + + given_names.include?(cop_name) || given_names.include?(badge.department_name) + end + + # Override and return the Force class(es) you need to join + def self.joining_forces; end + + ### Persistence + + # Override if your cop should be called repeatedly for multiple investigations + # Between calls to `on_new_investigation` and `on_investigation_end`, + # the result of `processed_source` will remain constant. + # You should invalidate any caches that depend on the current `processed_source` + # in the `on_new_investigation` callback. + # If your cop does autocorrections, be aware that your instance may be called + # multiple times with the same `processed_source.path` but different content. + def self.support_multiple_source? + false + end + + ## Gem requirements + + @gem_requirements = {} + + class << self + attr_reader :gem_requirements + + # Register a version requirement for the given gem name. + # This cop will be skipped unless the target satisfies *all* requirements. + # @param [String] gem_name + # @param [Array] version_requirements The version requirements, + # using the same syntax as a Gemfile, e.g. ">= 1.2.3" + # + # If omitted, any version of the gem will be accepted. + # + # https://guides.rubygems.org/patterns/#declaring-dependencies + # + # @api public + def requires_gem(gem_name, *version_requirements) + @gem_requirements[gem_name] = Gem::Requirement.new(version_requirements) + end + end + + def initialize(config = nil, options = nil) + @config = config || Config.new + @options = options || { debug: false } + reset_investigation + end + + # Called before all on_... have been called + # When refining this method, always call `super` + def on_new_investigation + # Typically do nothing here + end + + # Called after all on_... have been called + # When refining this method, always call `super` + def on_investigation_end + # Typically do nothing here + end + + # Called instead of all on_... callbacks for unrecognized files / syntax errors + # When refining this method, always call `super` + def on_other_file + # Typically do nothing here + end + + # Gets called if no message is specified when calling `add_offense` or + # `add_global_offense` + # Cops are discouraged to override this; instead pass your message directly + def message(_range = nil) + self.class::MSG + end + + # Adds an offense that has no particular location. + # No correction can be applied to global offenses + def add_global_offense(message = nil, severity: nil) + severity = find_severity(nil, severity) + message = find_message(nil, message) + range = Offense::NO_LOCATION + status = enabled_line?(range.line) ? :unsupported : :disabled + current_offenses << Offense.new(severity, range, message, name, status) + end + + # Adds an offense on the specified range (or node with an expression) + # Unless that offense is disabled for this range, a corrector will be yielded + # to provide the cop the opportunity to autocorrect the offense. + # If message is not specified, the method `message` will be called. + def add_offense(node_or_range, message: nil, severity: nil, &block) + range = range_from_node_or_range(node_or_range) + return unless current_offense_locations.add?(range) + + range_to_pass = callback_argument(range) + + severity = find_severity(range_to_pass, severity) + message = find_message(range_to_pass, message) + + status, corrector = enabled_line?(range.line) ? correct(range, &block) : :disabled + + # Since this range may be generated from Ruby code embedded in some + # template file, we convert it to location info in the original file. + range = range_for_original(range) + + current_offenses << Offense.new(severity, range, message, name, status, corrector) + end + + # This method should be overridden when a cop's behavior depends + # on state that lives outside of these locations: + # + # (1) the file under inspection + # (2) the cop's source code + # (3) the config (eg a .rubocop.yml file) + # + # For example, some cops may want to look at other parts of + # the codebase being inspected to find violations. A cop may + # use the presence or absence of file `foo.rb` to determine + # whether a certain violation exists in `bar.rb`. + # + # Overriding this method allows the cop to indicate to RuboCop's + # ResultCache system when those external dependencies change, + # ie when the ResultCache should be invalidated. + def external_dependency_checksum + nil + end + + def cop_name + @cop_name ||= self.class.cop_name + end + + alias name cop_name + + ### Configuration Helpers + + def cop_config + # Use department configuration as basis, but let individual cop + # configuration override. + @cop_config ||= @config.for_badge(self.class.badge) + end + + def config_to_allow_offenses + Formatter::DisabledConfigFormatter.config_to_allow_offenses[cop_name] ||= {} + end + + def config_to_allow_offenses=(hash) + Formatter::DisabledConfigFormatter.config_to_allow_offenses[cop_name] = hash + end + + def target_ruby_version + @config.target_ruby_version + end + + # Returns a gems locked versions (i.e. from Gemfile.lock or gems.locked) + # @returns [Gem::Version | nil] The locked gem version, or nil if the gem is not present. + def target_gem_version(gem_name) + @config.gem_versions_in_target && @config.gem_versions_in_target[gem_name] + end + + def parser_engine + @config.parser_engine + end + + def target_rails_version + @config.target_rails_version + end + + def active_support_extensions_enabled? + @config.active_support_extensions_enabled? + end + + def string_literals_frozen_by_default? + @config.string_literals_frozen_by_default? + end + + def relevant_file?(file) + return false unless target_satisfies_all_gem_version_requirements? + return true unless @config.clusivity_config_for_badge?(self.class.badge) + + file == RuboCop::AST::ProcessedSource::STRING_SOURCE_NAME || + (file_name_matches_any?(file, 'Include', true) && + !file_name_matches_any?(file, 'Exclude', false)) + end + + def excluded_file?(file) + !relevant_file?(file) + end + + # There should be very limited reasons for a Cop to do it's own parsing + def parse(source, path = nil) + ProcessedSource.new(source, target_ruby_version, path, parser_engine: parser_engine) + end + + # @api private + # Called between investigations + def ready + return self if self.class.support_multiple_source? + + self.class.new(@config, @options) + end + + ### Reserved for Cop::Cop + + # @deprecated Make potential errors with previous API more obvious + def offenses + raise 'The offenses are not directly available; ' \ + 'they are returned as the result of the investigation' + end + + ### Reserved for Commissioner + + # rubocop:disable Layout/ClassStructure + # @api private + def callbacks_needed + self.class.callbacks_needed + end + + # @api private + def self.callbacks_needed + @callbacks_needed ||= public_instance_methods.select do |m| + # OPTIMIZE: Check method existence first to make fewer `start_with?` calls. + # At the time of writing this comment, this excludes 98 of ~104 methods. + # `start_with?` with two string arguments instead of a regex is faster + # in this specific case as well. + !Base.method_defined?(m) && # exclude standard "callbacks" like 'on_begin_investigation' + m.start_with?('on_', 'after_') + end + end + # rubocop:enable Layout/ClassStructure + + # Called before any investigation + # @api private + def begin_investigation(processed_source, offset: 0, original: processed_source) + @current_offenses = nil + @current_offense_locations = nil + @currently_disabled_lines = nil + @processed_source = processed_source + @current_corrector = nil + + # We need to keep track of the original source and offset, + # because `processed_source` here may be an embedded code in it. + @current_offset = offset + @current_original = original + end + + # @api private + def always_autocorrect? + # `true` is the same as `'always'` for backward compatibility. + ['always', true].include?(cop_config.fetch('AutoCorrect', 'always')) + end + + # @api private + def contextual_autocorrect? + cop_config.fetch('AutoCorrect', 'always') == 'contextual' + end + + def inspect # :nodoc: + "#<#{self.class.name}:#{object_id} @config=#{@config} @options=#{@options}>" + end + + private + + ### Reserved for Cop::Cop + + def callback_argument(range) + range + end + + def apply_correction(corrector) + current_corrector&.merge!(corrector) if corrector + end + + ### Reserved for Commissioner: + + def current_offense_locations + @current_offense_locations ||= Set.new + end + + def currently_disabled_lines + @currently_disabled_lines ||= Set.new + end + + def current_corrector + @current_corrector ||= Corrector.new(@processed_source) if @processed_source.valid_syntax? + end + + def current_offenses + @current_offenses ||= [] + end + + private_class_method def self.restrict_on_send + @restrict_on_send ||= self::RESTRICT_ON_SEND.to_a.freeze + end + + EMPTY_OFFENSES = [].freeze + private_constant :EMPTY_OFFENSES + # Called to complete an investigation + def complete_investigation + InvestigationReport.new( + self, processed_source, @current_offenses || EMPTY_OFFENSES, @current_corrector + ) + ensure + reset_investigation + end + + ### Actually private methods + + def reset_investigation + @currently_disabled_lines = @current_offenses = @processed_source = @current_corrector = nil + end + + # @return [Symbol, Corrector] offense status + def correct(range) + if block_given? + corrector = Corrector.new(self) + yield corrector + if corrector.empty? + corrector = nil + elsif !self.class.support_autocorrect? + raise "The Cop #{name} must `extend AutoCorrector` to be able to autocorrect" + end + end + + [use_corrector(range, corrector), corrector] + end + + # @return [Symbol] offense status + def use_corrector(range, corrector) + if autocorrect? + attempt_correction(range, corrector) + elsif corrector && (always_autocorrect? || (contextual_autocorrect? && !LSP.enabled?)) + :uncorrected + else + :unsupported + end + end + + # @return [Symbol] offense status + def attempt_correction(range, corrector) + if corrector + status = :corrected + elsif disable_uncorrectable? + corrector = disable_uncorrectable(range) + status = :corrected_with_todo + else + return :unsupported + end + + apply_correction(corrector) + status + end + + def disable_uncorrectable(range) + line = range.line + return unless currently_disabled_lines.add?(line) + + disable_offense(range) + end + + def range_from_node_or_range(node_or_range) + if node_or_range.respond_to?(:loc) + node_or_range.source_range + elsif node_or_range.is_a?(::Parser::Source::Range) + node_or_range + else + extra = ' (call `add_global_offense`)' if node_or_range.nil? + raise "Expected a Source::Range, got #{node_or_range.inspect}#{extra}" + end + end + + def find_message(range, message) + annotate(message || message(range)) + end + + def annotate(message) + RuboCop::Cop::MessageAnnotator.new( + config, cop_name, cop_config, @options + ).annotate(message) + end + + def file_name_matches_any?(file, parameter, default_result) + patterns = cop_config[parameter] + return default_result unless patterns + + patterns = FilePatterns.from(patterns) + patterns.match?(config.path_relative_to_config(file)) || patterns.match?(file) + end + + def enabled_line?(line_number) + return true if @options[:ignore_disable_comments] || !@processed_source + + @processed_source.comment_config.cop_enabled_at_line?(self, line_number) + end + + def find_severity(_range, severity) + custom_severity || severity || default_severity + end + + def default_severity + self.class.lint? ? :warning : :convention + end + + def custom_severity + severity = cop_config['Severity'] + return unless severity + + if Severity::NAMES.include?(severity.to_sym) + severity.to_sym + else + message = "Warning: Invalid severity '#{severity}'. " \ + "Valid severities are #{Severity::NAMES.join(', ')}." + warn(Rainbow(message).red) + end + end + + def range_for_original(range) + ::Parser::Source::Range.new( + @current_original.buffer, + range.begin_pos + @current_offset, + range.end_pos + @current_offset + ) + end + + def target_satisfies_all_gem_version_requirements? + self.class.gem_requirements.all? do |gem_name, version_req| + all_gem_versions_in_target = @config.gem_versions_in_target + next false unless all_gem_versions_in_target + + gem_version_in_target = all_gem_versions_in_target[gem_name] + next false unless gem_version_in_target + + version_req.satisfied_by?(gem_version_in_target) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/bundler/duplicated_gem.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/bundler/duplicated_gem.rb new file mode 100644 index 00000000..8234e2fd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/bundler/duplicated_gem.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Bundler + # A Gem's requirements should be listed only once in a Gemfile. + # + # @example + # # bad + # gem 'rubocop' + # gem 'rubocop' + # + # # bad + # group :development do + # gem 'rubocop' + # end + # + # group :test do + # gem 'rubocop' + # end + # + # # good + # group :development, :test do + # gem 'rubocop' + # end + # + # # good + # gem 'rubocop', groups: [:development, :test] + # + # # good - conditional declaration + # if Dir.exist?(local) + # gem 'rubocop', path: local + # elsif ENV['RUBOCOP_VERSION'] == 'master' + # gem 'rubocop', git: 'https://github.com/rubocop/rubocop.git' + # else + # gem 'rubocop', '~> 0.90.0' + # end + # + class DuplicatedGem < Base + include RangeHelp + + MSG = 'Gem `%s` requirements already given on line ' \ + '%d of the Gemfile.' + + def on_new_investigation + return if processed_source.blank? + + duplicated_gem_nodes.each do |nodes| + nodes[1..].each do |node| + register_offense(node, node.first_argument.to_a.first, nodes.first.first_line) + end + end + end + + private + + # @!method gem_declarations(node) + def_node_search :gem_declarations, '(send nil? :gem str ...)' + + def duplicated_gem_nodes + gem_declarations(processed_source.ast) + .group_by(&:first_argument) + .values + .select { |nodes| nodes.size > 1 && !conditional_declaration?(nodes) } + end + + def conditional_declaration?(nodes) + parent = nodes[0].each_ancestor.find { |ancestor| !ancestor.begin_type? } + return false unless parent&.type?(:if, :when) + + root_conditional_node = parent.if_type? ? parent : parent.parent + nodes.all? { |node| within_conditional?(node, root_conditional_node) } + end + + def within_conditional?(node, conditional_node) + conditional_node.branches.compact.any? do |branch| + branch == node || branch.child_nodes.include?(node) + end + end + + def register_offense(node, gem_name, line_of_first_occurrence) + line_range = node.loc.column...node.loc.last_column + offense_location = source_range(processed_source.buffer, node.first_line, line_range) + message = format( + MSG, + gem_name: gem_name, + line_of_first_occurrence: line_of_first_occurrence + ) + add_offense(offense_location, message: message) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/bundler/duplicated_group.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/bundler/duplicated_group.rb new file mode 100644 index 00000000..a2ffe8eb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/bundler/duplicated_group.rb @@ -0,0 +1,127 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Bundler + # A Gem group, or a set of groups, should be listed only once in a Gemfile. + # + # For example, if the values of `source`, `git`, `platforms`, or `path` + # surrounding `group` are different, no offense will be registered: + # + # [source,ruby] + # ----- + # platforms :ruby do + # group :default do + # gem 'openssl' + # end + # end + # + # platforms :jruby do + # group :default do + # gem 'jruby-openssl' + # end + # end + # ----- + # + # @example + # # bad + # group :development do + # gem 'rubocop' + # end + # + # group :development do + # gem 'rubocop-rails' + # end + # + # # bad (same set of groups declared twice) + # group :development, :test do + # gem 'rubocop' + # end + # + # group :test, :development do + # gem 'rspec' + # end + # + # # good + # group :development do + # gem 'rubocop' + # end + # + # group :development, :test do + # gem 'rspec' + # end + # + # # good + # gem 'rubocop', groups: [:development, :test] + # gem 'rspec', groups: [:development, :test] + # + class DuplicatedGroup < Base + include RangeHelp + + MSG = 'Gem group `%s` already defined on line ' \ + '%d of the Gemfile.' + SOURCE_BLOCK_NAMES = %i[source git platforms path].freeze + + # @!method group_declarations(node) + def_node_search :group_declarations, '(send nil? :group ...)' + + def on_new_investigation + return if processed_source.blank? + + duplicated_group_nodes.each do |nodes| + nodes[1..].each do |node| + group_name = node.arguments.map(&:source).join(', ') + + register_offense(node, group_name, nodes.first.first_line) + end + end + end + + private + + def duplicated_group_nodes + group_declarations = group_declarations(processed_source.ast) + group_keys = group_declarations.group_by do |node| + source_key = find_source_key(node) + group_attributes = group_attributes(node).sort.join + + "#{source_key}#{group_attributes}" + end + + group_keys.values.select { |nodes| nodes.size > 1 } + end + + def register_offense(node, group_name, line_of_first_occurrence) + line_range = node.loc.column...node.loc.last_column + offense_location = source_range(processed_source.buffer, node.first_line, line_range) + message = format( + MSG, + group_name: group_name, + line_of_first_occurrence: line_of_first_occurrence + ) + add_offense(offense_location, message: message) + end + + def find_source_key(node) + source_block = node.each_ancestor(:block).find do |block_node| + SOURCE_BLOCK_NAMES.include?(block_node.method_name) + end + + return unless source_block + + "#{source_block.method_name}#{source_block.send_node.first_argument&.source}" + end + + def group_attributes(node) + node.arguments.map do |argument| + if argument.hash_type? + argument.pairs.map(&:source).sort.join(', ') + else + argument.respond_to?(:value) ? argument.value.to_s : argument.source + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/bundler/gem_comment.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/bundler/gem_comment.rb new file mode 100644 index 00000000..374c2e81 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/bundler/gem_comment.rb @@ -0,0 +1,171 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Bundler + # Each gem in the Gemfile should have a comment explaining + # its purpose in the project, or the reason for its version + # or source. + # + # The optional "OnlyFor" configuration array + # can be used to only register offenses when the gems + # use certain options or have version specifiers. + # + # When "version_specifiers" is included, a comment + # will be enforced if the gem has any version specifier. + # + # When "restrictive_version_specifiers" is included, a comment + # will be enforced if the gem has a version specifier that + # holds back the version of the gem. + # + # For any other value in the array, a comment will be enforced for + # a gem if an option by the same name is present. + # A useful use case is to enforce a comment when using + # options that change the source of a gem: + # + # - `bitbucket` + # - `gist` + # - `git` + # - `github` + # - `source` + # + # For a full list of options supported by bundler, + # see https://bundler.io/man/gemfile.5.html + # . + # + # @example OnlyFor: [] (default) + # # bad + # + # gem 'foo' + # + # # good + # + # # Helpers for the foo things. + # gem 'foo' + # + # @example OnlyFor: ['version_specifiers'] + # # bad + # + # gem 'foo', '< 2.1' + # + # # good + # + # # Version 2.1 introduces breaking change baz + # gem 'foo', '< 2.1' + # + # @example OnlyFor: ['restrictive_version_specifiers'] + # # bad + # + # gem 'foo', '< 2.1' + # + # # good + # + # gem 'foo', '>= 1.0' + # + # # Version 2.1 introduces breaking change baz + # gem 'foo', '< 2.1' + # + # @example OnlyFor: ['version_specifiers', 'github'] + # # bad + # + # gem 'foo', github: 'some_account/some_fork_of_foo' + # + # gem 'bar', '< 2.1' + # + # # good + # + # # Using this fork because baz + # gem 'foo', github: 'some_account/some_fork_of_foo' + # + # # Version 2.1 introduces breaking change baz + # gem 'bar', '< 2.1' + # + class GemComment < Base + include DefNode + include GemDeclaration + + MSG = 'Missing gem description comment.' + CHECKED_OPTIONS_CONFIG = 'OnlyFor' + VERSION_SPECIFIERS_OPTION = 'version_specifiers' + RESTRICTIVE_VERSION_SPECIFIERS_OPTION = 'restrictive_version_specifiers' + RESTRICTIVE_VERSION_PATTERN = /\A\s*(?:<|~>|\d|=)/.freeze + RESTRICT_ON_SEND = %i[gem].freeze + + def on_send(node) + return unless gem_declaration?(node) + return if ignored_gem?(node) + return if commented_any_descendant?(node) + return if cop_config[CHECKED_OPTIONS_CONFIG].any? && !checked_options_present?(node) + + add_offense(node) + end + + private + + def commented_any_descendant?(node) + commented?(node) || node.each_descendant.any? { |n| commented?(n) } + end + + def commented?(node) + preceding_lines = preceding_lines(node) + preceding_comment?(node, preceding_lines.last) + end + + # The args node1 & node2 may represent a RuboCop::AST::Node + # or a Parser::Source::Comment. Both respond to #loc. + def precede?(node1, node2) + node2.loc.line - node1.loc.line <= 1 + end + + def preceding_lines(node) + processed_source.ast_with_comments[node].select do |line| + line.loc.line <= node.loc.line + end + end + + def preceding_comment?(node1, node2) + node1 && node2 && precede?(node2, node1) && comment_line?(node2.source) + end + + def ignored_gem?(node) + ignored_gems = Array(cop_config['IgnoredGems']) + ignored_gems.include?(node.first_argument.value) + end + + def checked_options_present?(node) + (cop_config[CHECKED_OPTIONS_CONFIG].include?(VERSION_SPECIFIERS_OPTION) && + version_specified_gem?(node)) || + (cop_config[CHECKED_OPTIONS_CONFIG].include?(RESTRICTIVE_VERSION_SPECIFIERS_OPTION) && + restrictive_version_specified_gem?(node)) || + contains_checked_options?(node) + end + + # Besides the gem name, all other *positional* arguments to `gem` are version specifiers, + # as long as it has one we know there's at least one version specifier. + def version_specified_gem?(node) + # arguments[0] is the gem name + node.arguments[1]&.str_type? + end + + # Version specifications that restrict all updates going forward. This excludes versions + # like ">= 1.0" or "!= 2.0.3". + def restrictive_version_specified_gem?(node) + return false unless version_specified_gem?(node) + + node.arguments[1..] + .any? { |arg| arg&.str_type? && RESTRICTIVE_VERSION_PATTERN.match?(arg.value) } + end + + def contains_checked_options?(node) + (Array(cop_config[CHECKED_OPTIONS_CONFIG]) & gem_options(node).map(&:to_s)).any? + end + + def gem_options(node) + return [] unless node.last_argument&.hash_type? + + node.last_argument.keys.map(&:value) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/bundler/gem_filename.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/bundler/gem_filename.rb new file mode 100644 index 00000000..1f9ec1e1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/bundler/gem_filename.rb @@ -0,0 +1,102 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Bundler + # Verifies that a project contains Gemfile or gems.rb file and correct + # associated lock file based on the configuration. + # + # @example EnforcedStyle: Gemfile (default) + # # bad + # Project contains gems.rb and gems.locked files + # + # # bad + # Project contains Gemfile and gems.locked file + # + # # good + # Project contains Gemfile and Gemfile.lock + # + # @example EnforcedStyle: gems.rb + # # bad + # Project contains Gemfile and Gemfile.lock files + # + # # bad + # Project contains gems.rb and Gemfile.lock file + # + # # good + # Project contains gems.rb and gems.locked files + class GemFilename < Base + include ConfigurableEnforcedStyle + + MSG_GEMFILE_REQUIRED = '`gems.rb` file was found but `Gemfile` is required ' \ + '(file path: %s).' + MSG_GEMS_RB_REQUIRED = '`Gemfile` was found but `gems.rb` file is required ' \ + '(file path: %s).' + MSG_GEMFILE_MISMATCHED = 'Expected a `Gemfile.lock` with `Gemfile` but found ' \ + '`gems.locked` file (file path: %s).' + MSG_GEMS_RB_MISMATCHED = 'Expected a `gems.locked` file with `gems.rb` but found ' \ + '`Gemfile.lock` (file path: %s).' + GEMFILE_FILES = %w[Gemfile Gemfile.lock].freeze + GEMS_RB_FILES = %w[gems.rb gems.locked].freeze + + def on_new_investigation + file_path = processed_source.file_path + basename = File.basename(file_path) + return if expected_gemfile?(basename) + + register_offense(file_path, basename) + end + + private + + def register_offense(file_path, basename) + register_gemfile_offense(file_path, basename) if gemfile_offense?(basename) + register_gems_rb_offense(file_path, basename) if gems_rb_offense?(basename) + end + + def register_gemfile_offense(file_path, basename) + message = case basename + when 'gems.rb' + MSG_GEMFILE_REQUIRED + when 'gems.locked' + MSG_GEMFILE_MISMATCHED + end + + add_global_offense(format(message, file_path: file_path)) + end + + def register_gems_rb_offense(file_path, basename) + message = case basename + when 'Gemfile' + MSG_GEMS_RB_REQUIRED + when 'Gemfile.lock' + MSG_GEMS_RB_MISMATCHED + end + + add_global_offense(format(message, file_path: file_path)) + end + + def gemfile_offense?(basename) + gemfile_required? && GEMS_RB_FILES.include?(basename) + end + + def gems_rb_offense?(basename) + gems_rb_required? && GEMFILE_FILES.include?(basename) + end + + def expected_gemfile?(basename) + (gemfile_required? && GEMFILE_FILES.include?(basename)) || + (gems_rb_required? && GEMS_RB_FILES.include?(basename)) + end + + def gemfile_required? + style == :Gemfile + end + + def gems_rb_required? + style == :'gems.rb' + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/bundler/gem_version.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/bundler/gem_version.rb new file mode 100644 index 00000000..80434ac3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/bundler/gem_version.rb @@ -0,0 +1,132 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Bundler + # Enforce that Gem version specifications or a commit reference (branch, + # ref, or tag) are either required or forbidden. + # + # @example EnforcedStyle: required (default) + # # bad + # gem 'rubocop' + # + # # good + # gem 'rubocop', '~> 1.12' + # + # # good + # gem 'rubocop', '>= 1.10.0' + # + # # good + # gem 'rubocop', '>= 1.5.0', '< 1.10.0' + # + # # good + # gem 'rubocop', branch: 'feature-branch' + # + # # good + # gem 'rubocop', ref: '74b5bfbb2c4b6fd6cdbbc7254bd7084b36e0c85b' + # + # # good + # gem 'rubocop', tag: 'v1.17.0' + # + # @example EnforcedStyle: forbidden + # # good + # gem 'rubocop' + # + # # bad + # gem 'rubocop', '~> 1.12' + # + # # bad + # gem 'rubocop', '>= 1.10.0' + # + # # bad + # gem 'rubocop', '>= 1.5.0', '< 1.10.0' + # + # # bad + # gem 'rubocop', branch: 'feature-branch' + # + # # bad + # gem 'rubocop', ref: '74b5bfbb2c4b6fd6cdbbc7254bd7084b36e0c85b' + # + # # bad + # gem 'rubocop', tag: 'v1.17.0' + # + class GemVersion < Base + include ConfigurableEnforcedStyle + include GemDeclaration + + REQUIRED_MSG = 'Gem version specification is required.' + FORBIDDEN_MSG = 'Gem version specification is forbidden.' + RESTRICT_ON_SEND = %i[gem].freeze + VERSION_SPECIFICATION_REGEX = /^\s*[~<>=]*\s*[0-9.]+/.freeze + + # @!method includes_version_specification?(node) + def_node_matcher :includes_version_specification?, <<~PATTERN + (send nil? :gem <(str #version_specification?) ...>) + PATTERN + + # @!method includes_commit_reference?(node) + def_node_matcher :includes_commit_reference?, <<~PATTERN + (send nil? :gem <(hash <(pair (sym {:branch :ref :tag}) (str _)) ...>) ...>) + PATTERN + + def on_send(node) + return unless gem_declaration?(node) + return if allowed_gem?(node) + + if offense?(node) + add_offense(node) + opposite_style_detected + else + correct_style_detected + end + end + + private + + def allowed_gem?(node) + allowed_gems.include?(node.first_argument.value) + end + + def allowed_gems + Array(cop_config['AllowedGems']) + end + + def message(_range) + if required_style? + REQUIRED_MSG + elsif forbidden_style? + FORBIDDEN_MSG + end + end + + def offense?(node) + required_offense?(node) || forbidden_offense?(node) + end + + def required_offense?(node) + return false unless required_style? + + !includes_version_specification?(node) && !includes_commit_reference?(node) + end + + def forbidden_offense?(node) + return false unless forbidden_style? + + includes_version_specification?(node) || includes_commit_reference?(node) + end + + def forbidden_style? + style == :forbidden + end + + def required_style? + style == :required + end + + def version_specification?(expression) + expression.match?(VERSION_SPECIFICATION_REGEX) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/bundler/insecure_protocol_source.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/bundler/insecure_protocol_source.rb new file mode 100644 index 00000000..532d859e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/bundler/insecure_protocol_source.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Bundler + # Passing symbol arguments to `source` (e.g. `source :rubygems`) is + # deprecated because they default to using HTTP requests. Instead, specify + # `'https://rubygems.org'` if possible, or `'http://rubygems.org'` if not. + # + # When autocorrecting, this cop will replace symbol arguments with + # `'https://rubygems.org'`. + # + # This cop will not replace existing sources that use `http://`. This may + # be necessary where HTTPS is not available. For example, where using an + # internal gem server via an intranet, or where HTTPS is prohibited. + # However, you should strongly prefer `https://` where possible, as it is + # more secure. + # + # If you don't allow `http://`, please set `false` to `AllowHttpProtocol`. + # This option is `true` by default for safe autocorrection. + # + # @example + # # bad + # source :gemcutter + # source :rubygems + # source :rubyforge + # + # # good + # source 'https://rubygems.org' # strongly recommended + # + # @example AllowHttpProtocol: true (default) + # + # # good + # source 'http://rubygems.org' # use only if HTTPS is unavailable + # + # @example AllowHttpProtocol: false + # + # # bad + # source 'http://rubygems.org' + # + class InsecureProtocolSource < Base + extend AutoCorrector + + MSG = 'The source `:%s` is deprecated because HTTP requests ' \ + 'are insecure. ' \ + "Please change your source to 'https://rubygems.org' " \ + "if possible, or 'http://rubygems.org' if not." + MSG_HTTP_PROTOCOL = 'Use `https://rubygems.org` instead of `http://rubygems.org`.' + + RESTRICT_ON_SEND = %i[source].freeze + + # @!method insecure_protocol_source?(node) + def_node_matcher :insecure_protocol_source?, <<~PATTERN + (send nil? :source + ${(sym :gemcutter) (sym :rubygems) (sym :rubyforge) (:str "http://rubygems.org")}) + PATTERN + + def on_send(node) + insecure_protocol_source?(node) do |source_node| + source = source_node.value + use_http_protocol = source == 'http://rubygems.org' + + return if allow_http_protocol? && use_http_protocol + + message = if use_http_protocol + MSG_HTTP_PROTOCOL + else + format(MSG, source: source) + end + + add_offense(source_node, message: message) do |corrector| + corrector.replace(source_node, "'https://rubygems.org'") + end + end + end + + private + + def allow_http_protocol? + cop_config.fetch('AllowHttpProtocol', true) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/bundler/ordered_gems.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/bundler/ordered_gems.rb new file mode 100644 index 00000000..964ebec9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/bundler/ordered_gems.rb @@ -0,0 +1,70 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Bundler + # Gems should be alphabetically sorted within groups. + # + # @example + # # bad + # gem 'rubocop' + # gem 'rspec' + # + # # good + # gem 'rspec' + # gem 'rubocop' + # + # # good + # gem 'rubocop' + # + # gem 'rspec' + # + # @example TreatCommentsAsGroupSeparators: true (default) + # # good + # # For code quality + # gem 'rubocop' + # # For tests + # gem 'rspec' + # + # @example TreatCommentsAsGroupSeparators: false + # # bad + # # For code quality + # gem 'rubocop' + # # For tests + # gem 'rspec' + class OrderedGems < Base + extend AutoCorrector + include OrderedGemNode + + MSG = 'Gems should be sorted in an alphabetical order within their ' \ + 'section of the Gemfile. ' \ + 'Gem `%s` should appear before `%s`.' + + def on_new_investigation + return if processed_source.blank? + + gem_declarations(processed_source.ast) + .each_cons(2) do |previous, current| + next unless consecutive_lines?(previous, current) + next unless case_insensitive_out_of_order?(gem_name(current), gem_name(previous)) + + register_offense(previous, current) + end + end + + private + + def previous_declaration(node) + declarations = gem_declarations(processed_source.ast) + node_index = declarations.map(&:location).find_index(node.location) + declarations.to_a[node_index - 1] + end + + # @!method gem_declarations(node) + def_node_search :gem_declarations, <<~PATTERN + (:send nil? :gem str ...) + PATTERN + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/commissioner.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/commissioner.rb new file mode 100644 index 00000000..cd320842 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/commissioner.rb @@ -0,0 +1,182 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # Commissioner class is responsible for processing the AST and delegating + # work to the specified cops. + class Commissioner + include RuboCop::AST::Traversal + + RESTRICTED_CALLBACKS = %i[on_send on_csend after_send after_csend].freeze + private_constant :RESTRICTED_CALLBACKS + + # How a Commissioner returns the results of the investigation + # as a list of Cop::InvestigationReport and any errors caught + # during the investigation. + # Immutable + # Consider creation API private + InvestigationReport = Struct.new(:processed_source, :cop_reports, :errors) do + def cops + @cops ||= cop_reports.map(&:cop) + end + + def offenses_per_cop + @offenses_per_cop ||= cop_reports.map(&:offenses) + end + + def correctors + @correctors ||= cop_reports.map(&:corrector) + end + + def offenses + @offenses ||= offenses_per_cop.flatten(1) + end + + def merge(investigation) + InvestigationReport.new(processed_source, + cop_reports + investigation.cop_reports, + errors + investigation.errors) + end + end + + attr_reader :errors + + def initialize(cops, forces = [], options = {}) + @cops = cops + @forces = forces + @options = options + initialize_callbacks + + reset + end + + # Create methods like :on_send, :on_super, etc. They will be called + # during AST traversal and try to call corresponding methods on cops. + # A call to `super` is used + # to continue iterating over the children of a node. + # However, if we know that a certain node type (like `int`) never has + # child nodes, there is no reason to pay the cost of calling `super`. + Parser::Meta::NODE_TYPES.each do |node_type| + method_name = :"on_#{node_type}" + next unless method_defined?(method_name) + + # Hacky: Comment-out code as needed + r = '#' unless RESTRICTED_CALLBACKS.include?(method_name) # has Restricted? + c = '#' if NO_CHILD_NODES.include?(node_type) # has Children? + + class_eval(<<~RUBY, __FILE__, __LINE__ + 1) + def on_#{node_type}(node) # def on_send(node) + trigger_responding_cops(:on_#{node_type}, node) # trigger_responding_cops(:on_send, node) + #{r} trigger_restricted_cops(:on_#{node_type}, node) # trigger_restricted_cops(:on_send, node) + #{c} super(node) # super(node) + #{c} trigger_responding_cops(:after_#{node_type}, node) # trigger_responding_cops(:after_send, node) + #{c}#{r} trigger_restricted_cops(:after_#{node_type}, node) # trigger_restricted_cops(:after_send, node) + end # end + RUBY + end + + # @return [InvestigationReport] + def investigate(processed_source, offset: 0, original: processed_source) + reset + + begin_investigation(processed_source, offset: offset, original: original) + if processed_source.valid_syntax? + invoke(:on_new_investigation, @cops) + invoke_with_argument(:investigate, @forces, processed_source) + + walk(processed_source.ast) unless @cops.empty? + invoke(:on_investigation_end, @cops) + else + invoke(:on_other_file, @cops) + end + reports = @cops.map { |cop| cop.send(:complete_investigation) } + InvestigationReport.new(processed_source, reports, @errors) + end + + private + + def begin_investigation(processed_source, offset:, original:) + @cops.each do |cop| + cop.begin_investigation(processed_source, offset: offset, original: original) + end + end + + def trigger_responding_cops(callback, node) + @callbacks[callback]&.each do |cop| + with_cop_error_handling(cop, node) do + cop.public_send(callback, node) + end + end + end + + def reset + @errors = [] + end + + def initialize_callbacks + @callbacks = build_callbacks(@cops) + @restricted_map = restrict_callbacks(@callbacks) + end + + def build_callbacks(cops) + callbacks = {} + cops.each do |cop| + cop.callbacks_needed.each do |callback| + (callbacks[callback] ||= []) << cop + end + end + callbacks + end + + def restrict_callbacks(callbacks) + restricted = {} + RESTRICTED_CALLBACKS.each do |callback| + restricted[callback] = restricted_map(callbacks[callback]) + end + restricted + end + + def trigger_restricted_cops(event, node) + name = node.method_name + @restricted_map[event][name]&.each do |cop| + with_cop_error_handling(cop, node) do + cop.public_send(event, node) + end + end + end + + # NOTE: mutates `callbacks` in place + def restricted_map(callbacks) + map = {} + callbacks&.select! do |cop| + restrictions = cop.class.send :restrict_on_send + restrictions.each { |name| (map[name] ||= []) << cop } + restrictions.empty? + end + map + end + + def invoke(callback, cops) + cops.each { |cop| with_cop_error_handling(cop) { cop.send(callback) } } + end + + def invoke_with_argument(callback, cops, arg) + cops.each { |cop| with_cop_error_handling(cop) { cop.send(callback, arg) } } + end + + # Allow blind rescues here, since we're absorbing and packaging or + # re-raising exceptions that can be raised from within the individual + # cops' `#investigate` methods. + def with_cop_error_handling(cop, node = nil) + yield + rescue StandardError => e + raise e if @options[:raise_error] # For internal testing + + err = ErrorWithAnalyzedFileLocation.new(cause: e, node: node, cop: cop) + raise err if @options[:raise_cop_error] # From user-input option + + @errors << err + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/cop.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/cop.rb new file mode 100644 index 00000000..dba0f636 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/cop.rb @@ -0,0 +1,192 @@ +# frozen_string_literal: true + +require 'uri' +require_relative 'legacy/corrections_proxy' + +module RuboCop + module Cop + # @deprecated Use Cop::Base instead + # Legacy scaffold for Cops. + # See https://docs.rubocop.org/rubocop/v1_upgrade_notes.html + class Cop < Base + attr_reader :offenses + + exclude_from_registry + + # @deprecated + Correction = Struct.new(:lambda, :node, :cop) do + def call(corrector) + lambda.call(corrector) + rescue StandardError => e + raise ErrorWithAnalyzedFileLocation.new(cause: e, node: node, cop: cop) + end + end + + def self.inherited(_subclass) + super + warn Rainbow(<<~WARNING).yellow, uplevel: 1 + Inheriting from `RuboCop::Cop::Cop` is deprecated. Use `RuboCop::Cop::Base` instead. + For more information, see https://docs.rubocop.org/rubocop/v1_upgrade_notes.html. + WARNING + end + + def self.support_autocorrect? + method_defined?(:autocorrect) + end + + def self.joining_forces + return unless method_defined?(:join_force?) + + cop = new + Force.all.select { |force_class| cop.join_force?(force_class) } + end + + ### Deprecated registry access + + # @deprecated Use Registry.global + def self.registry + warn Rainbow(<<~WARNING).yellow, uplevel: 1 + `Cop.registry` is deprecated. Use `Registry.global` instead. + WARNING + + Registry.global + end + + # @deprecated Use Registry.all + def self.all + warn Rainbow(<<~WARNING).yellow, uplevel: 1 + `Cop.all` is deprecated. Use `Registry.all` instead. + WARNING + + Registry.all + end + + # @deprecated Use Registry.qualified_cop_name + def self.qualified_cop_name(name, origin) + warn Rainbow(<<~WARNING).yellow, uplevel: 1 + `Cop.qualified_cop_name` is deprecated. Use `Registry.qualified_cop_name` instead. + WARNING + + Registry.qualified_cop_name(name, origin) + end + + def add_offense(node_or_range, location: :expression, message: nil, severity: nil, &block) + @v0_argument = node_or_range + range = find_location(node_or_range, location) + + # Since this range may be generated from Ruby code embedded in some + # template file, we convert it to location info in the original file. + range = range_for_original(range) + + if block.nil? && !self.class.support_autocorrect? + super(range, message: message, severity: severity) + else + super(range, message: message, severity: severity) do |corrector| + emulate_v0_callsequence(corrector, &block) + end + end + end + + def find_location(node, loc) + # Location can be provided as a symbol, e.g.: `:keyword` + loc.is_a?(Symbol) ? node.loc.public_send(loc) : loc + end + + # @deprecated Use class method + def support_autocorrect? + warn Rainbow(<<~WARNING).yellow, uplevel: 1 + `support_autocorrect?` is deprecated. Use `cop.class.support_autocorrect?`. + WARNING + + self.class.support_autocorrect? + end + + # @deprecated + def corrections + warn Rainbow(<<~WARNING).yellow, uplevel: 1 + `Cop#corrections` is deprecated. + WARNING + + return [] unless @last_corrector + + Legacy::CorrectionsProxy.new(@last_corrector) + end + + # Called before all on_... have been called + def on_new_investigation + investigate(processed_source) if respond_to?(:investigate) + super + end + + # Called after all on_... have been called + def on_investigation_end + investigate_post_walk(processed_source) if respond_to?(:investigate_post_walk) + super + end + + # Called before any investigation + # @api private + def begin_investigation(processed_source, offset: 0, original: processed_source) + super + @offenses = current_offenses + @last_corrector = @current_corrector + + # We need to keep track of the original source and offset, + # because `processed_source` here may be an embedded code in it. + @current_offset = offset + @current_original = original + end + + private + + # Override Base + def callback_argument(_range) + @v0_argument + end + + def apply_correction(corrector) + suppress_clobbering { super } + end + + # Just for legacy + def emulate_v0_callsequence(corrector) + lambda = correction_lambda + yield corrector if block_given? + unless corrector.empty? + raise 'Your cop must inherit from Cop::Base and extend AutoCorrector' + end + + return unless lambda + + suppress_clobbering { lambda.call(corrector) } + end + + def correction_lambda + return unless self.class.support_autocorrect? + + dedupe_on_node(@v0_argument) { autocorrect(@v0_argument) } + end + + def dedupe_on_node(node) + @corrected_nodes ||= {}.compare_by_identity + yield unless @corrected_nodes.key?(node) + ensure + @corrected_nodes[node] = true + end + + def suppress_clobbering + yield + rescue ::Parser::ClobberingError + # ignore Clobbering errors + end + + def range_for_original(range) + ::Parser::Source::Range.new( + @current_original.buffer, + range.begin_pos + @current_offset, + range.end_pos + @current_offset + ) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/corrector.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/corrector.rb new file mode 100644 index 00000000..cb582882 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/corrector.rb @@ -0,0 +1,138 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # This class takes a source buffer and rewrite its source + # based on the different correction rules supplied. + # + # Important! + # The nodes modified by the corrections should be part of the + # AST of the source_buffer. + class Corrector < ::Parser::Source::TreeRewriter + NOOP_CONSUMER = ->(diagnostic) {} # noop + + # Duck typing for get to a ::Parser::Source::Buffer + def self.source_buffer(source) + source = source.processed_source if source.respond_to?(:processed_source) + source = source.buffer if source.respond_to?(:buffer) + source = source.source_buffer if source.respond_to?(:source_buffer) + + unless source.is_a? ::Parser::Source::Buffer + raise TypeError, 'Expected argument to lead to a Parser::Source::Buffer ' \ + "but got #{source.inspect}" + end + + source + end + + # @param source [Parser::Source::Buffer, or anything + # leading to one via `(processed_source.)buffer`] + # + # corrector = Corrector.new(cop) + def initialize(source) + source = self.class.source_buffer(source) + super( + source, + different_replacements: :raise, + swallowed_insertions: :raise, + crossing_deletions: :accept + ) + + # Don't print warnings to stderr if corrections conflict with each other + diagnostics.consumer = NOOP_CONSUMER + end + + alias rewrite process # Legacy + + # Removes `size` characters prior to the source range. + # + # @param [Parser::Source::Range, RuboCop::AST::Node] range or node + # @param [Integer] size + def remove_preceding(node_or_range, size) + range = to_range(node_or_range) + to_remove = range.with(begin_pos: range.begin_pos - size, end_pos: range.begin_pos) + remove(to_remove) + end + + # Removes `size` characters from the beginning of the given range. + # If `size` is greater than the size of `range`, the removed region can + # overrun the end of `range`. + # + # @param [Parser::Source::Range, RuboCop::AST::Node] range or node + # @param [Integer] size + def remove_leading(node_or_range, size) + range = to_range(node_or_range) + to_remove = range.with(end_pos: range.begin_pos + size) + remove(to_remove) + end + + # Removes `size` characters from the end of the given range. + # If `size` is greater than the size of `range`, the removed region can + # overrun the beginning of `range`. + # + # @param [Parser::Source::Range, RuboCop::AST::Node] range or node + # @param [Integer] size + def remove_trailing(node_or_range, size) + range = to_range(node_or_range) + to_remove = range.with(begin_pos: range.end_pos - size) + remove(to_remove) + end + + # Swaps sources at the given ranges. + # + # @param [Parser::Source::Range, RuboCop::AST::Node] node_or_range1 + # @param [Parser::Source::Range, RuboCop::AST::Node] node_or_range2 + def swap(node_or_range1, node_or_range2) + range1 = to_range(node_or_range1) + range2 = to_range(node_or_range2) + + if range1.end_pos == range2.begin_pos + insert_before(range1, range2.source) + remove(range2) + elsif range2.end_pos == range1.begin_pos + insert_before(range2, range1.source) + remove(range1) + else + replace(range1, range2.source) + replace(range2, range1.source) + end + end + + private + + # :nodoc: + def to_range(node_or_range) + range = case node_or_range + when ::RuboCop::AST::Node, ::Parser::Source::Comment + node_or_range.source_range + when ::Parser::Source::Range + node_or_range + else + raise TypeError, + 'Expected a Parser::Source::Range, Comment or ' \ + "RuboCop::AST::Node, got #{node_or_range.class}" + end + validate_buffer(range.source_buffer) + range + end + + def check_range_validity(node_or_range) + super(to_range(node_or_range)) + end + + def validate_buffer(buffer) + return if buffer == source_buffer + + unless buffer.is_a?(::Parser::Source::Buffer) + # actually this should be enforced by parser gem + raise 'Corrector expected range source buffer to be a ' \ + "Parser::Source::Buffer, but got #{buffer.class}" + end + raise "Correction target buffer #{buffer.object_id} " \ + "name:#{buffer.name.inspect} " \ + "is not current #{@source_buffer.object_id} " \ + "name:#{@source_buffer.name.inspect} under investigation" + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/alignment_corrector.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/alignment_corrector.rb new file mode 100644 index 00000000..8e56e14b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/alignment_corrector.rb @@ -0,0 +1,125 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # This class does autocorrection of nodes that should just be moved to + # the left or to the right, amount being determined by the instance + # variable column_delta. + class AlignmentCorrector + extend RangeHelp + extend Alignment + + class << self + attr_reader :processed_source + + def correct(corrector, processed_source, node, column_delta) + return unless node + + @processed_source = processed_source + expr = node.respond_to?(:loc) ? node.source_range : node + return if block_comment_within?(expr) + + taboo_ranges = inside_string_ranges(node) + + each_line(expr) do |line_begin_pos| + autocorrect_line(corrector, line_begin_pos, expr, column_delta, taboo_ranges) + end + end + + def align_end(corrector, processed_source, node, align_to) + @processed_source = processed_source + whitespace = whitespace_range(node) + return false unless whitespace.source.strip.empty? + + column = alignment_column(align_to) + corrector.replace(whitespace, ' ' * column) + end + + private + + def autocorrect_line(corrector, line_begin_pos, expr, column_delta, + taboo_ranges) + range = calculate_range(expr, line_begin_pos, column_delta) + # We must not change indentation of heredoc strings or inside other + # string literals + return if taboo_ranges.any? { |t| within?(range, t) } + + if column_delta.positive? && range.resize(1).source != "\n" + corrector.insert_before(range, ' ' * column_delta) + elsif /\A[ \t]+\z/.match?(range.source) + corrector.remove(range) + end + end + + def inside_string_ranges(node) + return [] unless node.is_a?(Parser::AST::Node) + + node.each_node(:str, :dstr, :xstr).filter_map { |n| inside_string_range(n) } + end + + def inside_string_range(node) + loc = node.location + + if node.heredoc? + loc.heredoc_body.join(loc.heredoc_end) + elsif delimited_string_literal?(node) + loc.begin.end.join(loc.end.begin) + end + end + + # Some special kinds of string literals are not composed of literal + # characters between two delimiters: + # - The source map of `?a` responds to :begin and :end but its end is + # nil. + # - The source map of `__FILE__` responds to neither :begin nor :end. + def delimited_string_literal?(node) + loc = node.location + + loc.respond_to?(:begin) && loc.begin && loc.respond_to?(:end) && loc.end + end + + def block_comment_within?(expr) + processed_source.comments.select(&:document?).any? do |c| + within?(c.source_range, expr) + end + end + + def calculate_range(expr, line_begin_pos, column_delta) + return range_between(line_begin_pos, line_begin_pos) if column_delta.positive? + + starts_with_space = expr.source_buffer.source[line_begin_pos].start_with?(' ') + + if starts_with_space + range_between(line_begin_pos, line_begin_pos + column_delta.abs) + else + range_between(line_begin_pos - column_delta.abs, line_begin_pos) + end + end + + def each_line(expr) + line_begin_pos = expr.begin_pos + expr.source.each_line do |line| + yield line_begin_pos + line_begin_pos += line.length + end + end + + def whitespace_range(node) + begin_pos = node.loc.end.begin_pos + + range_between(begin_pos - node.loc.end.column, begin_pos) + end + + def alignment_column(align_to) + if !align_to + 0 + elsif align_to.respond_to?(:loc) + align_to.source_range.column + else + align_to.column + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/condition_corrector.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/condition_corrector.rb new file mode 100644 index 00000000..10f9494b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/condition_corrector.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # This class does condition autocorrection + class ConditionCorrector + class << self + def correct_negative_condition(corrector, node) + condition = negated_condition(node) + + corrector.replace(node.loc.keyword, node.inverse_keyword) + corrector.replace(condition, condition.children.first.source) + end + + private + + def negated_condition(node) + condition = node.condition + condition = condition.children.first while condition.begin_type? + condition + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/each_to_for_corrector.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/each_to_for_corrector.rb new file mode 100644 index 00000000..e464a558 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/each_to_for_corrector.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # This class autocorrects `#each` enumeration to `for` iteration. + class EachToForCorrector + extend NodePattern::Macros + + CORRECTION_WITH_ARGUMENTS = 'for %s in %s do' + CORRECTION_WITHOUT_ARGUMENTS = 'for _ in %s do' + + def initialize(block_node) + @block_node = block_node + @collection_node = block_node.receiver + @argument_node = block_node.arguments + end + + def call(corrector) + corrector.replace(offending_range, correction) + end + + private + + attr_reader :block_node, :collection_node, :argument_node + + def correction + if block_node.arguments? + format(CORRECTION_WITH_ARGUMENTS, + collection: collection_node.source, + variables: argument_node.children.first.source) + else + format(CORRECTION_WITHOUT_ARGUMENTS, enumerable: collection_node.source) + end + end + + def offending_range + begin_range = block_node.source_range.begin + + if block_node.arguments? + begin_range.join(argument_node.source_range.end) + else + begin_range.join(block_node.loc.begin.end) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/empty_line_corrector.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/empty_line_corrector.rb new file mode 100644 index 00000000..b230be17 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/empty_line_corrector.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # This class does empty line autocorrection + class EmptyLineCorrector + class << self + def correct(corrector, node) + offense_style, range = node + + case offense_style + when :no_empty_lines + corrector.remove(range) + when :empty_lines + corrector.insert_before(range, "\n") + end + end + + def insert_before(corrector, node) + corrector.insert_before(node, "\n") + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/for_to_each_corrector.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/for_to_each_corrector.rb new file mode 100644 index 00000000..cd33923f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/for_to_each_corrector.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # This class autocorrects `for` iteration to `#each` enumeration. + class ForToEachCorrector + extend NodePattern::Macros + + CORRECTION = '%s.each do |%s|' + + def initialize(for_node) + @for_node = for_node + @variable_node = for_node.variable + @collection_node = for_node.collection + end + + def call(corrector) + offending_range = for_node.source_range.begin.join(end_range) + + corrector.replace(offending_range, correction) + end + + private + + attr_reader :for_node, :variable_node, :collection_node + + def correction + format(CORRECTION, collection: collection_source, argument: variable_node.source) + end + + def collection_source + if requires_parentheses? + "(#{collection_node.source})" + else + collection_node.source + end + end + + def requires_parentheses? + return true if collection_node.send_type? && collection_node.operator_method? + + collection_node.range_type? || collection_node.operator_keyword? + end + + def end_range + if for_node.do? + keyword_begin.end + else + collection_end.end + end + end + + def keyword_begin + for_node.loc.begin + end + + def collection_end + if collection_node.begin_type? + collection_node.loc.end + else + collection_node.source_range + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/if_then_corrector.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/if_then_corrector.rb new file mode 100644 index 00000000..54ada1e8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/if_then_corrector.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # This class autocorrects `if...then` structures to a multiline `if` statement + class IfThenCorrector + DEFAULT_INDENTATION_WIDTH = 2 + + def initialize(if_node, indentation: nil) + @if_node = if_node + @indentation = indentation || DEFAULT_INDENTATION_WIDTH + end + + def call(corrector) + corrector.replace(if_node, replacement) + end + + private + + attr_reader :if_node, :indentation + + def replacement(node = if_node, indentation = nil) + indentation = ' ' * node.source_range.column if indentation.nil? + if_branch_source = node.if_branch&.source || 'nil' + elsif_indentation = indentation if node.respond_to?(:elsif?) && node.elsif? + + if_branch = <<~RUBY + #{elsif_indentation}#{node.keyword} #{node.condition.source} + #{indentation}#{branch_body_indentation}#{if_branch_source} + RUBY + + else_branch = rewrite_else_branch(node.else_branch, indentation) + if_branch + else_branch + end + + def rewrite_else_branch(else_branch, indentation) + if else_branch.nil? + 'end' + elsif else_branch.if_type? && else_branch.elsif? + replacement(else_branch, indentation) + else + <<~RUBY.chomp + #{indentation}else + #{indentation}#{branch_body_indentation}#{else_branch.source} + #{indentation}end + RUBY + end + end + + def branch_body_indentation + @branch_body_indentation ||= (' ' * indentation).freeze + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb new file mode 100644 index 00000000..6d690736 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb @@ -0,0 +1,139 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # This class autocorrects lambda literal to method notation. + class LambdaLiteralToMethodCorrector + def initialize(block_node) + @block_node = block_node + @method = block_node.send_node + @arguments = block_node.arguments + end + + def call(corrector) + # Check for unparenthesized args' preceding and trailing whitespaces. + remove_unparenthesized_whitespace(corrector) + + if block_node.block_type? + # Avoid correcting to `lambdado` by inserting whitespace + # if none exists before or after the lambda arguments. + insert_separating_space(corrector) + + remove_arguments(corrector) + end + + replace_selector(corrector) + + replace_delimiters(corrector) + + insert_arguments(corrector) + end + + private + + attr_reader :block_node, :method, :arguments + + def remove_unparenthesized_whitespace(corrector) + return if arguments.empty? || arguments.parenthesized_call? + + remove_leading_whitespace(corrector) + remove_trailing_whitespace(corrector) + end + + def insert_separating_space(corrector) + return unless needs_separating_space? + + corrector.insert_before(block_begin, ' ') + end + + def replace_selector(corrector) + corrector.replace(method, 'lambda') + end + + def remove_arguments(corrector) + return if arguments.empty_and_without_delimiters? + + corrector.remove(arguments) + end + + def insert_arguments(corrector) + return if arguments.empty? + + arg_str = " |#{lambda_arg_string}|" + corrector.insert_after(block_node.loc.begin, arg_str) + end + + def remove_leading_whitespace(corrector) + corrector.remove_preceding( + arguments, + arguments.source_range.begin_pos - + block_node.send_node.source_range.end_pos + ) + end + + def remove_trailing_whitespace(corrector) + size = block_begin.begin_pos - arguments.source_range.end_pos - 1 + corrector.remove_preceding(block_begin, size) if size.positive? + end + + def replace_delimiters(corrector) + return if block_node.braces? || !arg_to_unparenthesized_call? + + corrector.insert_after(block_begin, ' ') unless separating_space? + + corrector.replace(block_begin, '{') + corrector.replace(block_end, '}') + end + + def lambda_arg_string + arguments.children.map(&:source).join(', ') + end + + def needs_separating_space? + (block_begin.begin_pos == arguments_end_pos && + selector_end.end_pos == arguments_begin_pos) || + block_begin.begin_pos == selector_end.end_pos + end + + def arguments_end_pos + arguments.loc.end&.end_pos + end + + def arguments_begin_pos + arguments.loc.begin&.begin_pos + end + + def block_end + block_node.loc.end + end + + def block_begin + block_node.loc.begin + end + + def selector_end + method.loc.selector.end + end + + def arg_to_unparenthesized_call? + current_node = block_node + + parent = current_node.parent + + if parent&.pair_type? + current_node = parent.parent + parent = current_node.parent + end + + return false unless parent&.send_type? + return false if parent.parenthesized_call? + + current_node.sibling_index > 1 + end + + def separating_space? + block_begin.source_buffer.source[block_begin.begin_pos + 2].match?(/\s/) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/line_break_corrector.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/line_break_corrector.rb new file mode 100644 index 00000000..f946e110 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/line_break_corrector.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # This class handles autocorrection for code that needs to be moved + # to new lines. + class LineBreakCorrector + extend Alignment + extend TrailingBody + extend Util + + class << self + attr_reader :processed_source + + def correct_trailing_body(configured_width:, corrector:, node:, + processed_source:) + @processed_source = processed_source + range = first_part_of(node.to_a.last) + eol_comment = processed_source.comment_at_line(node.source_range.line) + + break_line_before(range: range, node: node, corrector: corrector, + configured_width: configured_width) + move_comment(eol_comment: eol_comment, node: node, corrector: corrector) + remove_semicolon(node, corrector) + end + + def break_line_before(range:, node:, corrector:, configured_width:, + indent_steps: 1) + corrector.insert_before( + range, + "\n#{' ' * (node.loc.keyword.column + (indent_steps * configured_width))}" + ) + end + + def move_comment(eol_comment:, node:, corrector:) + return unless eol_comment + + text = eol_comment.source + corrector.insert_before(node, "#{text}\n#{' ' * node.loc.keyword.column}") + corrector.remove(eol_comment) + end + + private + + def remove_semicolon(node, corrector) + return unless semicolon(node) + + corrector.remove(semicolon(node).pos) + end + + def semicolon(node) + @semicolon ||= {}.compare_by_identity + @semicolon[node] ||= processed_source.sorted_tokens.select(&:semicolon?).find do |token| + next if token.pos.end_pos <= node.source_range.begin_pos + + same_line?(token, node.body) && trailing_class_definition?(token, node.body) + end + end + + def trailing_class_definition?(token, body) + token.column < body.loc.column + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb new file mode 100644 index 00000000..97f841eb --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb @@ -0,0 +1,113 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # Autocorrection logic for the closing brace of a literal either + # on the same line as the last contained elements, or a new line. + class MultilineLiteralBraceCorrector + include MultilineLiteralBraceLayout + include RangeHelp + + def self.correct(corrector, node, processed_source) + new(corrector, node, processed_source).call + end + + def initialize(corrector, node, processed_source) + @corrector = corrector + @node = node + @processed_source = processed_source + end + + def call + if closing_brace_on_same_line?(node) + correct_same_line_brace(corrector) + else + # When a comment immediately before the closing brace gets in the + # way of an easy correction, the offense is reported but not auto- + # corrected. The user must handle the delicate decision of where to + # put the comment. + return if new_line_needed_before_closing_brace?(node) + + end_range = last_element_range_with_trailing_comma(node).end + + correct_next_line_brace(corrector, end_range) + correct_heredoc_argument_method_chain(corrector, end_range) + end + end + + private + + attr_reader :corrector, :node, :processed_source + + def correct_same_line_brace(corrector) + corrector.insert_before(node.loc.end, "\n") + end + + def correct_next_line_brace(corrector, end_range) + corrector.remove(range_with_surrounding_space(node.loc.end, side: :left)) + corrector.insert_before(end_range, content_if_comment_present(corrector, node)) + end + + def correct_heredoc_argument_method_chain(corrector, end_range) + return unless (parent = node.parent) + return unless use_heredoc_argument_method_chain?(parent) + + chained_method = range_between(parent.loc.dot.begin_pos, parent.source_range.end_pos) + + corrector.remove(chained_method) + corrector.insert_after(end_range, chained_method.source) + end + + def content_if_comment_present(corrector, node) + range = range_with_surrounding_space( + children(node).last.source_range, + side: :right + ).end.resize(1) + if range.source == '#' + select_content_to_be_inserted_after_last_element(corrector, node) + else + node.loc.end.source + end + end + + def use_heredoc_argument_method_chain?(parent) + return false unless node.respond_to?(:first_argument) + return false unless (first_argument = node.first_argument) + + parent.call_type? && first_argument.str_type? && first_argument.heredoc? + end + + def select_content_to_be_inserted_after_last_element(corrector, node) + range = range_between( + node.loc.end.begin_pos, + range_by_whole_lines(node.source_range).end.end_pos + ) + + remove_trailing_content_of_comment(corrector, range) + range.source + end + + def remove_trailing_content_of_comment(corrector, range) + corrector.remove(range) + end + + def last_element_range_with_trailing_comma(node) + trailing_comma_range = last_element_trailing_comma_range(node) + if trailing_comma_range + children(node).last.source_range.join(trailing_comma_range) + else + children(node).last.source_range + end + end + + def last_element_trailing_comma_range(node) + range = range_with_surrounding_space( + children(node).last.source_range, + side: :right + ).end.resize(1) + + range.source == ',' ? range : nil + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/ordered_gem_corrector.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/ordered_gem_corrector.rb new file mode 100644 index 00000000..35dde1d2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/ordered_gem_corrector.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # This autocorrects gem dependency order + class OrderedGemCorrector + class << self + include OrderedGemNode + include RangeHelp + + attr_reader :processed_source, :comments_as_separators + + def correct(processed_source, node, + previous_declaration, comments_as_separators) + @processed_source = processed_source + @comments_as_separators = comments_as_separators + + current_range = declaration_with_comment(node) + previous_range = declaration_with_comment(previous_declaration) + + ->(corrector) { corrector.swap(current_range, previous_range) } + end + + private + + def declaration_with_comment(node) + buffer = processed_source.buffer + begin_pos = range_by_whole_lines(get_source_range(node, comments_as_separators)).begin_pos + end_line = buffer.line_for_position(node.source_range.end_pos) + end_pos = range_by_whole_lines(buffer.line_range(end_line), + include_final_newline: true).end_pos + + range_between(begin_pos, end_pos) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/parentheses_corrector.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/parentheses_corrector.rb new file mode 100644 index 00000000..bcb172ae --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/parentheses_corrector.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # This autocorrects parentheses + class ParenthesesCorrector + class << self + include RangeHelp + + COMMA_REGEXP = /(?<=\))\s*,/.freeze + + def correct(corrector, node) + corrector.remove(node.loc.begin) + corrector.remove(node.loc.end) + handle_orphaned_comma(corrector, node) + + return unless ternary_condition?(node) && next_char_is_question_mark?(node) + + corrector.insert_after(node.loc.end, ' ') + end + + private + + def ternary_condition?(node) + node.parent&.if_type? && node.parent.ternary? + end + + def next_char_is_question_mark?(node) + node.loc.last_column == node.parent.loc.question.column + end + + def only_closing_paren_before_comma?(node) + source_buffer = node.source_range.source_buffer + line_range = source_buffer.line_range(node.loc.end.line) + + line_range.source.start_with?(/\s*\)\s*,/) + end + + # If removing parentheses leaves a comma on its own line, remove all the whitespace + # preceding it to prevent a syntax error. + def handle_orphaned_comma(corrector, node) + return unless only_closing_paren_before_comma?(node) + + range = extend_range_for_heredoc(node, parens_range(node)) + corrector.remove(range) + + add_heredoc_comma(corrector, node) + end + + # Get a range for the closing parenthesis and all whitespace to the left of it + def parens_range(node) + range_with_surrounding_space( + range: node.loc.end, + buffer: node.source_range.source_buffer, + side: :left, + newlines: true, + whitespace: true, + continuations: true + ) + end + + # If the node contains a heredoc, remove the comma too + # It'll be added back in the right place later + def extend_range_for_heredoc(node, range) + return range unless heredoc?(node) + + comma_line = range_by_whole_lines(node.loc.end, buffer: node.source_range.source_buffer) + offset = comma_line.source.match(COMMA_REGEXP)[0]&.size || 0 + + range.adjust(end_pos: offset) + end + + # Add a comma back after the heredoc identifier + def add_heredoc_comma(corrector, node) + return unless heredoc?(node) + + corrector.insert_after(node.child_nodes.last, ',') + end + + def heredoc?(node) + node.child_nodes.last.loc.is_a?(Parser::Source::Map::Heredoc) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/percent_literal_corrector.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/percent_literal_corrector.rb new file mode 100644 index 00000000..b7e19a8a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/percent_literal_corrector.rb @@ -0,0 +1,116 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # This autocorrects percent literals + class PercentLiteralCorrector + include Util + + attr_reader :config, :preferred_delimiters + + def initialize(config, preferred_delimiters) + @config = config + @preferred_delimiters = preferred_delimiters + end + + def correct(corrector, node, char) + escape = escape_words?(node) + char = char.upcase if escape + delimiters = delimiters_for("%#{char}") + contents = new_contents(node, escape, delimiters) + wrap_contents(corrector, node, contents, char, delimiters) + end + + private + + def wrap_contents(corrector, node, contents, char, delimiters) + corrector.replace(node, "%#{char}#{delimiters[0]}#{contents}#{delimiters[1]}") + end + + def escape_words?(node) + node.children.any? { |w| needs_escaping?(w.children[0]) } + end + + def delimiters_for(type) + PreferredDelimiters.new(type, config, preferred_delimiters).delimiters + end + + def new_contents(node, escape, delimiters) + if node.multiline? + autocorrect_multiline_words(node, escape, delimiters) + else + autocorrect_words(node, escape, delimiters) + end + end + + def autocorrect_multiline_words(node, escape, delimiters) + contents = process_multiline_words(node, escape, delimiters) + contents << end_content(node.source) + contents.join + end + + def autocorrect_words(node, escape, delimiters) + node.children.map do |word_node| + fix_escaped_content(word_node, escape, delimiters) + end.join(' ') + end + + def process_multiline_words(node, escape, delimiters) + base_line_num = node.first_line + prev_line_num = base_line_num + node.children.map.with_index do |word_node, index| + line_breaks = line_breaks(word_node, node.source, prev_line_num, base_line_num, index) + prev_line_num = word_node.last_line + content = fix_escaped_content(word_node, escape, delimiters) + line_breaks + content + end + end + + def line_breaks(node, source, previous_line_num, base_line_num, node_index) + source_in_lines = source.split("\n") + if first_line?(node, previous_line_num) + node_index.zero? && node.first_line == base_line_num ? '' : ' ' + else + process_lines(node, previous_line_num, base_line_num, source_in_lines) + end + end + + def first_line?(node, previous_line_num) + node.first_line == previous_line_num + end + + def process_lines(node, previous_line_num, base_line_num, source_in_lines) + begin_line_num = previous_line_num - base_line_num + 1 + end_line_num = node.first_line - base_line_num + 1 + lines = source_in_lines[begin_line_num...end_line_num] + "\n#{lines.join("\n").split(node.source).first || ''}" + end + + def fix_escaped_content(word_node, escape, delimiters) + content = +word_node.children.first.to_s + content = escape_string(content) if escape + substitute_escaped_delimiters(content, delimiters) + content + end + + def substitute_escaped_delimiters(content, delimiters) + if delimiters.first != delimiters.last + # With different delimiters (eg. `[]`, `()`), if there are the same + # number of each, escaping is not necessary + delimiter_counts = delimiters.each_with_object({}) do |delimiter, counts| + counts[delimiter] = content.count(delimiter) + end + + return content if delimiter_counts[delimiters.first] == delimiter_counts[delimiters.last] + end + + delimiters.each { |delim| content.gsub!(delim, "\\#{delim}") } + end + + def end_content(source) + result = /\A(\s*)\]/.match(source.split("\n").last) + "\n#{result[1]}" if result + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/punctuation_corrector.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/punctuation_corrector.rb new file mode 100644 index 00000000..0806d26b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/punctuation_corrector.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # This autocorrects punctuation + class PunctuationCorrector + class << self + def remove_space(corrector, space_before) + corrector.remove(space_before) + end + + def add_space(corrector, token) + corrector.replace(token.pos, "#{token.pos.source} ") + end + + def swap_comma(corrector, range) + return unless range + + case range.source + when ',' then corrector.remove(range) + else corrector.insert_after(range, ',') + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/require_library_corrector.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/require_library_corrector.rb new file mode 100644 index 00000000..8a8b7a83 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/require_library_corrector.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # This class ensures a require statement is present for a standard library + # determined by the variable library_name + class RequireLibraryCorrector + extend RangeHelp + + class << self + def correct(corrector, node, library_name) + node = node.parent while node.parent? + node = node.children.first if node.begin_type? + corrector.insert_before(node, require_statement(library_name)) + end + + def require_statement(library_name) + "require '#{library_name}'\n" + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/space_corrector.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/space_corrector.rb new file mode 100644 index 00000000..81a612ce --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/space_corrector.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # This autocorrects whitespace + class SpaceCorrector + extend SurroundingSpace + + class << self + attr_reader :processed_source + + def empty_corrections(processed_source, corrector, empty_config, + left_token, right_token) + @processed_source = processed_source + range = range_between(left_token.end_pos, right_token.begin_pos) + if offending_empty_space?(empty_config, left_token, right_token) + corrector.remove(range) + corrector.insert_after(left_token.pos, ' ') + elsif offending_empty_no_space?(empty_config, left_token, right_token) + corrector.remove(range) + end + end + + def remove_space(processed_source, corrector, left_token, right_token) + @processed_source = processed_source + if left_token.space_after? + range = side_space_range(range: left_token.pos, side: :right) + corrector.remove(range) + end + return unless right_token.space_before? + + range = side_space_range(range: right_token.pos, side: :left) + corrector.remove(range) + end + + def add_space(processed_source, corrector, left_token, right_token) + @processed_source = processed_source + corrector.insert_after(left_token.pos, ' ') unless left_token.space_after? + return if right_token.space_before? + + corrector.insert_before(right_token.pos, ' ') + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/string_literal_corrector.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/string_literal_corrector.rb new file mode 100644 index 00000000..c310dc5d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/string_literal_corrector.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # This autocorrects string literals + class StringLiteralCorrector + extend Util + + class << self + def correct(corrector, node, style) + return if node.dstr_type? + + str = node.str_content + if style == :single_quotes + corrector.replace(node, to_string_literal(str)) + else + corrector.replace(node, str.inspect) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/unused_arg_corrector.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/unused_arg_corrector.rb new file mode 100644 index 00000000..dc341744 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/correctors/unused_arg_corrector.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # This autocorrects unused arguments. + class UnusedArgCorrector + extend RangeHelp + + class << self + attr_reader :processed_source + + def correct(corrector, processed_source, node) + return if %i[kwarg kwoptarg].include?(node.type) + + @processed_source = processed_source + + if node.blockarg_type? + correct_for_blockarg_type(corrector, node) + else + variable_name = if node.optarg_type? + node.node_parts[0] + else + # Extract only a var name without splat (`*`) + node.source.gsub(/\A\*+/, '') + end + + corrector.replace(node.loc.name, "_#{variable_name}") + end + end + + def correct_for_blockarg_type(corrector, node) + range = range_with_surrounding_space(node.source_range, side: :left) + range = range_with_surrounding_comma(range, :left) + + corrector.remove(range) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/documentation.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/documentation.rb new file mode 100644 index 00000000..2c234d22 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/documentation.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # Helpers for builtin documentation + module Documentation + module_function + + # @api private + def department_to_basename(department) + "cops_#{department.to_s.downcase.tr('/', '_')}" + end + + # @api private + def url_for(cop_class, config = nil) + base = department_to_basename(cop_class.department) + fragment = cop_class.cop_name.downcase.gsub(/[^a-z]/, '') + base_url = base_url_for(cop_class, config) + extension = extension_for(cop_class, config) + + "#{base_url}/#{base}#{extension}##{fragment}" if base_url + end + + # @api private + def base_url_for(cop_class, config) + if config + department_name = cop_class.department.to_s + url = config.for_department(department_name)['DocumentationBaseURL'] + return url if url + end + + default_base_url if builtin?(cop_class) + end + + # @api private + def extension_for(cop_class, config) + if config + department_name = cop_class.department + extension = config.for_department(department_name)['DocumentationExtension'] + return extension if extension + end + + default_extension + end + + # @api private + def default_base_url + 'https://docs.rubocop.org/rubocop' + end + + # @api private + def default_extension + '.html' + end + + # @api private + def builtin?(cop_class) + # any custom method will do + return false unless (m = cop_class.instance_methods(false).first) + + path, _line = cop_class.instance_method(m).source_location + path.start_with?(__dir__) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/exclude_limit.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/exclude_limit.rb new file mode 100644 index 00000000..913019ea --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/exclude_limit.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module RuboCop + # Allows specified configuration options to have an exclude limit + # ie. a maximum value tracked that it can be used by `--auto-gen-config`. + module ExcludeLimit + # Sets up a configuration option to have an exclude limit tracked. + # The parameter name given is transformed into a method name (eg. `Max` + # becomes `self.max=` and `MinDigits` becomes `self.min_digits=`). + def exclude_limit(parameter_name, method_name: transform(parameter_name)) + define_method(:"#{method_name}=") do |value| + cfg = config_to_allow_offenses + cfg[:exclude_limit] ||= {} + current_max = cfg[:exclude_limit][parameter_name] + value = [current_max, value].max if current_max + cfg[:exclude_limit][parameter_name] = value + end + end + + private + + def transform(parameter_name) + parameter_name.gsub(/(?= 2.3.3.1', '< 3.0' + # end + # + # # good + # Gem::Specification.new do |spec| + # spec.add_development_dependency 'parser', '>= 2.3.3.1', '< 3.0' + # end + # + # @example EnforcedStyle: forbidden + # + # # bad + # Gem::Specification.new do |spec| + # spec.add_dependency 'parser', '>= 2.3.3.1', '< 3.0' + # end + # + # # bad + # Gem::Specification.new do |spec| + # spec.add_development_dependency 'parser', '>= 2.3.3.1', '< 3.0' + # end + # + # # good + # Gem::Specification.new do |spec| + # spec.add_dependency 'parser' + # end + # + # # good + # Gem::Specification.new do |spec| + # spec.add_development_dependency 'parser' + # end + # + class DependencyVersion < Base + include ConfigurableEnforcedStyle + include GemspecHelp + + REQUIRED_MSG = 'Dependency version specification is required.' + FORBIDDEN_MSG = 'Dependency version specification is forbidden.' + VERSION_SPECIFICATION_REGEX = /^\s*[~<>=]*\s*[0-9.]+/.freeze + + ADD_DEPENDENCY_METHODS = %i[ + add_dependency add_runtime_dependency add_development_dependency + ].freeze + RESTRICT_ON_SEND = ADD_DEPENDENCY_METHODS + + # @!method add_dependency_method_declaration?(node) + def_node_matcher :add_dependency_method_declaration?, <<~PATTERN + (send + (lvar #match_block_variable_name?) #add_dependency_method? ...) + PATTERN + + # @!method includes_version_specification?(node) + def_node_matcher :includes_version_specification?, <<~PATTERN + (send _ #add_dependency_method? <(str #version_specification?) ...>) + PATTERN + + # @!method includes_commit_reference?(node) + def_node_matcher :includes_commit_reference?, <<~PATTERN + (send _ #add_dependency_method? <(hash <(pair (sym {:branch :ref :tag}) (str _)) ...>) ...>) + PATTERN + + def on_send(node) + return unless add_dependency_method_declaration?(node) + return if allowed_gem?(node) + + if offense?(node) + add_offense(node) + opposite_style_detected + else + correct_style_detected + end + end + + private + + def allowed_gem?(node) + allowed_gems.include?(node.first_argument.str_content) + end + + def allowed_gems + Array(cop_config['AllowedGems']) + end + + def message(_range) + if required_style? + REQUIRED_MSG + elsif forbidden_style? + FORBIDDEN_MSG + end + end + + def match_block_variable_name?(receiver_name) + gem_specification(processed_source.ast) do |block_variable_name| + return block_variable_name == receiver_name + end + end + + def add_dependency_method?(method_name) + ADD_DEPENDENCY_METHODS.include?(method_name) + end + + def offense?(node) + required_offense?(node) || forbidden_offense?(node) + end + + def required_offense?(node) + return false unless required_style? + + !includes_version_specification?(node) && !includes_commit_reference?(node) + end + + def forbidden_offense?(node) + return false unless forbidden_style? + + includes_version_specification?(node) || includes_commit_reference?(node) + end + + def forbidden_style? + style == :forbidden + end + + def required_style? + style == :required + end + + def version_specification?(expression) + expression.match?(VERSION_SPECIFICATION_REGEX) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb new file mode 100644 index 00000000..18d6f681 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb @@ -0,0 +1,91 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Gemspec + # Checks that deprecated attributes are not set in a gemspec file. + # Removing deprecated attributes allows the user to receive smaller packed gems. + # + # @example + # + # # bad + # Gem::Specification.new do |spec| + # spec.name = 'your_cool_gem_name' + # spec.test_files = Dir.glob('test/**/*') + # end + # + # # bad + # Gem::Specification.new do |spec| + # spec.name = 'your_cool_gem_name' + # spec.test_files += Dir.glob('test/**/*') + # end + # + # # good + # Gem::Specification.new do |spec| + # spec.name = 'your_cool_gem_name' + # end + # + class DeprecatedAttributeAssignment < Base + include RangeHelp + extend AutoCorrector + + MSG = 'Do not set `%s` in gemspec.' + + # @!method gem_specification(node) + def_node_matcher :gem_specification, <<~PATTERN + (block + (send + (const + (const {cbase nil?} :Gem) :Specification) :new) + ...) + PATTERN + + def on_block(block_node) + return unless gem_specification(block_node) + + block_parameter = block_node.first_argument.source + + assignment = block_node.descendants.detect do |node| + use_deprecated_attributes?(node, block_parameter) + end + return unless assignment + + message = format_message_from + add_offense(assignment, message: message) do |corrector| + range = range_by_whole_lines(assignment.source_range, include_final_newline: true) + + corrector.remove(range) + end + end + + private + + def node_and_method_name(node, attribute) + if node.op_asgn_type? + [node.lhs, attribute] + else + [node, :"#{attribute}="] + end + end + + def use_deprecated_attributes?(node, block_parameter) + %i[test_files date specification_version rubygems_version].each do |attribute| + node, method_name = node_and_method_name(node, attribute) + unless node.send_type? && node.receiver&.source == block_parameter && + node.method?(method_name) + next + end + + @attribute = attribute.to_s + return true + end + false + end + + def format_message_from + format(MSG, attribute: @attribute) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/gemspec/development_dependencies.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/gemspec/development_dependencies.rb new file mode 100644 index 00000000..a6aaf85b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/gemspec/development_dependencies.rb @@ -0,0 +1,107 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Gemspec + # Enforce that development dependencies for a gem are specified in + # `Gemfile`, rather than in the `gemspec` using + # `add_development_dependency`. Alternatively, using `EnforcedStyle: + # gemspec`, enforce that all dependencies are specified in `gemspec`, + # rather than in `Gemfile`. + # + # @example EnforcedStyle: Gemfile (default) + # # Specify runtime dependencies in your gemspec, + # # but all other dependencies in your Gemfile. + # + # # bad + # # example.gemspec + # s.add_development_dependency "foo" + # + # # good + # # Gemfile + # gem "foo" + # + # # good + # # gems.rb + # gem "foo" + # + # # good (with AllowedGems: ["bar"]) + # # example.gemspec + # s.add_development_dependency "bar" + # + # @example EnforcedStyle: gems.rb + # # Specify runtime dependencies in your gemspec, + # # but all other dependencies in your Gemfile. + # # + # # Identical to `EnforcedStyle: Gemfile`, but with a different error message. + # # Rely on Bundler/GemFilename to enforce the use of `Gemfile` vs `gems.rb`. + # + # # bad + # # example.gemspec + # s.add_development_dependency "foo" + # + # # good + # # Gemfile + # gem "foo" + # + # # good + # # gems.rb + # gem "foo" + # + # # good (with AllowedGems: ["bar"]) + # # example.gemspec + # s.add_development_dependency "bar" + # + # @example EnforcedStyle: gemspec + # # Specify all dependencies in your gemspec. + # + # # bad + # # Gemfile + # gem "foo" + # + # # good + # # example.gemspec + # s.add_development_dependency "foo" + # + # # good (with AllowedGems: ["bar"]) + # # Gemfile + # gem "bar" + # + class DevelopmentDependencies < Base + include ConfigurableEnforcedStyle + + MSG = 'Specify development dependencies in %s.' + RESTRICT_ON_SEND = %i[add_development_dependency gem].freeze + + # @!method add_development_dependency?(node) + def_node_matcher :add_development_dependency?, <<~PATTERN + (send _ :add_development_dependency (str #forbidden_gem? ...) _? _?) + PATTERN + + # @!method gem?(node) + def_node_matcher :gem?, <<~PATTERN + (send _ :gem (str #forbidden_gem? ...)) + PATTERN + + def on_send(node) + case style + when :Gemfile, :'gems.rb' + add_offense(node) if add_development_dependency?(node) + when :gemspec + add_offense(node) if gem?(node) + end + end + + private + + def forbidden_gem?(gem_name) + !cop_config['AllowedGems'].include?(gem_name) + end + + def message(_range) + format(MSG, preferred: style) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/gemspec/duplicated_assignment.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/gemspec/duplicated_assignment.rb new file mode 100644 index 00000000..e9e599aa --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/gemspec/duplicated_assignment.rb @@ -0,0 +1,133 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Gemspec + # An attribute assignment method calls should be listed only once + # in a gemspec. + # + # Assigning to an attribute with the same name using `spec.foo =` or + # `spec.attribute#[]=` will be an unintended usage. On the other hand, + # duplication of methods such # as `spec.requirements`, + # `spec.add_runtime_dependency`, and others are permitted because it is + # the intended use of appending values. + # + # @example + # # bad + # Gem::Specification.new do |spec| + # spec.name = 'rubocop' + # spec.name = 'rubocop2' + # end + # + # # good + # Gem::Specification.new do |spec| + # spec.name = 'rubocop' + # end + # + # # good + # Gem::Specification.new do |spec| + # spec.requirements << 'libmagick, v6.0' + # spec.requirements << 'A good graphics card' + # end + # + # # good + # Gem::Specification.new do |spec| + # spec.add_dependency('parallel', '~> 1.10') + # spec.add_dependency('parser', '>= 2.3.3.1', '< 3.0') + # end + # + # # bad + # Gem::Specification.new do |spec| + # spec.metadata["key"] = "value" + # spec.metadata["key"] = "value" + # end + # + # # good + # Gem::Specification.new do |spec| + # spec.metadata["key"] = "value" + # end + # + class DuplicatedAssignment < Base + include RangeHelp + include GemspecHelp + + MSG = '`%s` method calls already given on line ' \ + '%d of the gemspec.' + + # @!method assignment_method_declarations(node) + def_node_search :assignment_method_declarations, <<~PATTERN + (send + (lvar {#match_block_variable_name? :_1 :it}) _ ...) + PATTERN + + # @!method indexed_assignment_method_declarations(node) + def_node_search :indexed_assignment_method_declarations, <<~PATTERN + (send + (send (lvar {#match_block_variable_name? :_1 :it}) _) + :[]= + literal? + _ + ) + PATTERN + + def on_new_investigation + return if processed_source.blank? + + process_assignment_method_nodes + process_indexed_assignment_method_nodes + end + + private + + def process_assignment_method_nodes + duplicated_assignment_method_nodes.each do |nodes| + nodes[1..].each do |node| + register_offense(node, node.method_name, nodes.first.first_line) + end + end + end + + def process_indexed_assignment_method_nodes + duplicated_indexed_assignment_method_nodes.each do |nodes| + nodes[1..].each do |node| + assignment = "#{node.children.first.method_name}[#{node.first_argument.source}]=" + register_offense(node, assignment, nodes.first.first_line) + end + end + end + + def match_block_variable_name?(receiver_name) + gem_specification(processed_source.ast) do |block_variable_name| + return block_variable_name == receiver_name + end + end + + def duplicated_assignment_method_nodes + assignment_method_declarations(processed_source.ast) + .select(&:assignment_method?) + .group_by(&:method_name) + .values + .select { |nodes| nodes.size > 1 } + end + + def duplicated_indexed_assignment_method_nodes + indexed_assignment_method_declarations(processed_source.ast) + .group_by { |node| [node.children.first.method_name, node.first_argument] } + .values + .select { |nodes| nodes.size > 1 } + end + + def register_offense(node, assignment, line_of_first_occurrence) + line_range = node.loc.column...node.loc.last_column + offense_location = source_range(processed_source.buffer, node.first_line, line_range) + message = format( + MSG, + assignment: assignment, + line_of_first_occurrence: line_of_first_occurrence + ) + add_offense(offense_location, message: message) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/gemspec/ordered_dependencies.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/gemspec/ordered_dependencies.rb new file mode 100644 index 00000000..14aa6f78 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/gemspec/ordered_dependencies.rb @@ -0,0 +1,101 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Gemspec + # Dependencies in the gemspec should be alphabetically sorted. + # + # @example + # # bad + # spec.add_dependency 'rubocop' + # spec.add_dependency 'rspec' + # + # # good + # spec.add_dependency 'rspec' + # spec.add_dependency 'rubocop' + # + # # good + # spec.add_dependency 'rubocop' + # + # spec.add_dependency 'rspec' + # + # # bad + # spec.add_development_dependency 'rubocop' + # spec.add_development_dependency 'rspec' + # + # # good + # spec.add_development_dependency 'rspec' + # spec.add_development_dependency 'rubocop' + # + # # good + # spec.add_development_dependency 'rubocop' + # + # spec.add_development_dependency 'rspec' + # + # # bad + # spec.add_runtime_dependency 'rubocop' + # spec.add_runtime_dependency 'rspec' + # + # # good + # spec.add_runtime_dependency 'rspec' + # spec.add_runtime_dependency 'rubocop' + # + # # good + # spec.add_runtime_dependency 'rubocop' + # + # spec.add_runtime_dependency 'rspec' + # + # @example TreatCommentsAsGroupSeparators: true (default) + # # good + # # For code quality + # spec.add_dependency 'rubocop' + # # For tests + # spec.add_dependency 'rspec' + # + # @example TreatCommentsAsGroupSeparators: false + # # bad + # # For code quality + # spec.add_dependency 'rubocop' + # # For tests + # spec.add_dependency 'rspec' + class OrderedDependencies < Base + extend AutoCorrector + include OrderedGemNode + + MSG = 'Dependencies should be sorted in an alphabetical order within ' \ + 'their section of the gemspec. ' \ + 'Dependency `%s` should appear before `%s`.' + + def on_new_investigation + return if processed_source.blank? + + dependency_declarations(processed_source.ast) + .each_cons(2) do |previous, current| + next unless consecutive_lines?(previous, current) + next unless case_insensitive_out_of_order?(gem_name(current), gem_name(previous)) + next unless get_dependency_name(previous) == get_dependency_name(current) + + register_offense(previous, current) + end + end + + private + + def previous_declaration(node) + declarations = dependency_declarations(processed_source.ast) + node_index = declarations.find_index(node) + declarations.to_a[node_index - 1] + end + + def get_dependency_name(node) + node.method_name + end + + # @!method dependency_declarations(node) + def_node_search :dependency_declarations, <<~PATTERN + (send (lvar _) {:add_dependency :add_runtime_dependency :add_development_dependency} (str _) ...) + PATTERN + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/gemspec/require_mfa.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/gemspec/require_mfa.rb new file mode 100644 index 00000000..b07fe7d2 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/gemspec/require_mfa.rb @@ -0,0 +1,145 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Gemspec + # Requires a gemspec to have `rubygems_mfa_required` metadata set. + # + # This setting tells RubyGems that MFA (Multi-Factor Authentication) is + # required for accounts to be able perform privileged operations, such as + # (see RubyGems' documentation for the full list of privileged + # operations): + # + # * `gem push` + # * `gem yank` + # * `gem owner --add/remove` + # * adding or removing owners using gem ownership page + # + # This helps make your gem more secure, as users can be more + # confident that gem updates were pushed by maintainers. + # + # @example + # # bad + # Gem::Specification.new do |spec| + # # no `rubygems_mfa_required` metadata specified + # end + # + # # good + # Gem::Specification.new do |spec| + # spec.metadata = { + # 'rubygems_mfa_required' => 'true' + # } + # end + # + # # good + # Gem::Specification.new do |spec| + # spec.metadata['rubygems_mfa_required'] = 'true' + # end + # + # # bad + # Gem::Specification.new do |spec| + # spec.metadata = { + # 'rubygems_mfa_required' => 'false' + # } + # end + # + # # good + # Gem::Specification.new do |spec| + # spec.metadata = { + # 'rubygems_mfa_required' => 'true' + # } + # end + # + # # bad + # Gem::Specification.new do |spec| + # spec.metadata['rubygems_mfa_required'] = 'false' + # end + # + # # good + # Gem::Specification.new do |spec| + # spec.metadata['rubygems_mfa_required'] = 'true' + # end + # + class RequireMFA < Base + include GemspecHelp + extend AutoCorrector + + MSG = "`metadata['rubygems_mfa_required']` must be set to `'true'`." + + # @!method metadata(node) + def_node_matcher :metadata, <<~PATTERN + `{ + (send _ :metadata= $_) + (send (send _ :metadata) :[]= (str "rubygems_mfa_required") $_) + } + PATTERN + + # @!method rubygems_mfa_required(node) + def_node_search :rubygems_mfa_required, <<~PATTERN + (pair (str "rubygems_mfa_required") $_) + PATTERN + + # @!method true_string?(node) + def_node_matcher :true_string?, <<~PATTERN + (str "true") + PATTERN + + def on_block(node) # rubocop:disable Metrics/MethodLength, InternalAffairs/NumblockHandler + gem_specification(node) do |block_var| + metadata_value = metadata(node) + mfa_value = mfa_value(metadata_value) + + if mfa_value + unless true_string?(mfa_value) + add_offense(mfa_value) do |corrector| + change_value(corrector, mfa_value) + end + end + else + add_offense(node) do |corrector| + autocorrect(corrector, node, block_var, metadata_value) + end + end + end + end + + private + + def mfa_value(metadata_value) + return unless metadata_value + return metadata_value if metadata_value.str_type? + + rubygems_mfa_required(metadata_value).first + end + + def autocorrect(corrector, node, block_var, metadata) + if metadata + return unless metadata.hash_type? + + correct_metadata(corrector, metadata) + else + insert_mfa_required(corrector, node, block_var) + end + end + + def correct_metadata(corrector, metadata) + if metadata.pairs.any? + corrector.insert_after(metadata.pairs.last, ",\n'rubygems_mfa_required' => 'true'") + else + corrector.insert_before(metadata.loc.end, "'rubygems_mfa_required' => 'true'") + end + end + + def insert_mfa_required(corrector, node, block_var) + corrector.insert_before(node.loc.end, <<~RUBY) + #{block_var}.metadata['rubygems_mfa_required'] = 'true' + RUBY + end + + def change_value(corrector, value) + corrector.replace(value, "'true'") + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/gemspec/required_ruby_version.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/gemspec/required_ruby_version.rb new file mode 100644 index 00000000..57ff7066 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/gemspec/required_ruby_version.rb @@ -0,0 +1,129 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Gemspec + # Checks that `required_ruby_version` in a gemspec file is set to a valid + # value (non-blank) and matches `TargetRubyVersion` as set in RuboCop's + # configuration for the gem. + # + # This ensures that RuboCop is using the same Ruby version as the gem. + # + # @example + # # When `TargetRubyVersion` of .rubocop.yml is `2.5`. + # + # # bad + # Gem::Specification.new do |spec| + # # no `required_ruby_version` specified + # end + # + # # bad + # Gem::Specification.new do |spec| + # spec.required_ruby_version = '>= 2.4.0' + # end + # + # # bad + # Gem::Specification.new do |spec| + # spec.required_ruby_version = '>= 2.6.0' + # end + # + # # bad + # Gem::Specification.new do |spec| + # spec.required_ruby_version = '' + # end + # + # # good + # Gem::Specification.new do |spec| + # spec.required_ruby_version = '>= 2.5.0' + # end + # + # # good + # Gem::Specification.new do |spec| + # spec.required_ruby_version = '>= 2.5' + # end + # + # # accepted but not recommended + # Gem::Specification.new do |spec| + # spec.required_ruby_version = ['>= 2.5.0', '< 2.7.0'] + # end + # + # # accepted but not recommended, since + # # Ruby does not really follow semantic versioning + # Gem::Specification.new do |spec| + # spec.required_ruby_version = '~> 2.5' + # end + class RequiredRubyVersion < Base + RESTRICT_ON_SEND = %i[required_ruby_version=].freeze + NOT_EQUAL_MSG = '`required_ruby_version` and `TargetRubyVersion` ' \ + '(%s, which may be specified in ' \ + '.rubocop.yml) should be equal.' + MISSING_MSG = '`required_ruby_version` should be specified.' + + # @!method required_ruby_version?(node) + def_node_search :required_ruby_version?, <<~PATTERN + (send _ :required_ruby_version= _) + PATTERN + + # @!method defined_ruby_version(node) + def_node_matcher :defined_ruby_version, <<~PATTERN + { + $(str _) + $(array (str _) (str _)) + (send (const (const nil? :Gem) :Requirement) :new $str+) + } + PATTERN + + def on_new_investigation + return if processed_source.ast && required_ruby_version?(processed_source.ast) + + add_global_offense(MISSING_MSG) + end + + def on_send(node) + version_def = node.first_argument + return if dynamic_version?(version_def) + + ruby_version = extract_ruby_version(defined_ruby_version(version_def)) + return if ruby_version == target_ruby_version.to_s + + add_offense(version_def, message: not_equal_message(ruby_version, target_ruby_version)) + end + + private + + def dynamic_version?(node) + (node.send_type? && !node.receiver) || + node.variable? || + node.each_descendant(:send, *RuboCop::AST::Node::VARIABLES).any? + end + + def extract_ruby_version(required_ruby_version) + return unless required_ruby_version + + if required_ruby_version.is_a?(Array) + required_ruby_version = required_ruby_version.detect do |v| + /[>=]/.match?(v.str_content) + end + elsif required_ruby_version.array_type? + required_ruby_version = required_ruby_version.children.detect do |v| + /[>=]/.match?(v.str_content) + end + end + + return unless required_ruby_version + + required_ruby_version.str_content.scan(/\d/).first(2).join('.') + end + + def not_equal_message(required_ruby_version, target_ruby_version) + format( + NOT_EQUAL_MSG, + required_ruby_version: required_ruby_version, + gemspec_filename: File.basename(processed_source.file_path), + target_ruby_version: target_ruby_version + ) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb new file mode 100644 index 00000000..d74c1dd1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Gemspec + # Checks that `RUBY_VERSION` constant is not used in gemspec. + # Using `RUBY_VERSION` is dangerous because value of the + # constant is determined by `rake release`. + # It's possible to have dependency based on ruby version used + # to execute `rake release` and not user's ruby version. + # + # @example + # + # # bad + # Gem::Specification.new do |spec| + # if RUBY_VERSION >= '3.0' + # spec.add_dependency 'gem_a' + # else + # spec.add_dependency 'gem_b' + # end + # end + # + # # good + # Gem::Specification.new do |spec| + # spec.add_dependency 'gem_a' + # end + # + class RubyVersionGlobalsUsage < Base + include GemspecHelp + + MSG = 'Do not use `RUBY_VERSION` in gemspec file.' + + # @!method ruby_version?(node) + def_node_matcher :ruby_version?, '(const {cbase nil?} :RUBY_VERSION)' + + def on_const(node) + return unless gem_spec_with_ruby_version?(node) + + add_offense(node) + end + + private + + def gem_spec_with_ruby_version?(node) + gem_specification(processed_source.ast) && ruby_version?(node) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/generator.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/generator.rb new file mode 100644 index 00000000..84e481a3 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/generator.rb @@ -0,0 +1,223 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # Source and spec generator for new cops + # + # This generator will take a cop name and generate a source file + # and spec file when given a valid qualified cop name. + # @api private + class Generator + SOURCE_TEMPLATE = <<~RUBY + # frozen_string_literal: true + + module RuboCop + module Cop + module %s + # TODO: Write cop description and example of bad / good code. For every + # `SupportedStyle` and unique configuration, there needs to be examples. + # Examples must have valid Ruby syntax. Do not use upticks. + # + # @safety + # Delete this section if the cop is not unsafe (`Safe: false` or + # `SafeAutoCorrect: false`), or use it to explain how the cop is + # unsafe. + # + # @example EnforcedStyle: bar (default) + # # Description of the `bar` style. + # + # # bad + # bad_bar_method + # + # # bad + # bad_bar_method(args) + # + # # good + # good_bar_method + # + # # good + # good_bar_method(args) + # + # @example EnforcedStyle: foo + # # Description of the `foo` style. + # + # # bad + # bad_foo_method + # + # # bad + # bad_foo_method(args) + # + # # good + # good_foo_method + # + # # good + # good_foo_method(args) + # + class %s < Base + # TODO: Implement the cop in here. + # + # In many cases, you can use a node matcher for matching node pattern. + # See https://github.com/rubocop/rubocop-ast/blob/master/lib/rubocop/ast/node_pattern.rb + # + # For example + MSG = 'Use `#good_method` instead of `#bad_method`.' + + # TODO: Don't call `on_send` unless the method name is in this list + # If you don't need `on_send` in the cop you created, remove it. + RESTRICT_ON_SEND = %%i[bad_method].freeze + + # @!method bad_method?(node) + def_node_matcher :bad_method?, <<~PATTERN + (send nil? :bad_method ...) + PATTERN + + # Called on every `send` node (method call) while walking the AST. + # TODO: remove this method if inspecting `send` nodes is unneeded for your cop. + # By default, this is aliased to `on_csend` as well to handle method calls + # with safe navigation, remove the alias if this is unnecessary. + # If kept, ensure your tests cover safe navigation as well! + def on_send(node) + return unless bad_method?(node) + + add_offense(node) + end + alias on_csend on_send + end + end + end + end + RUBY + + SPEC_TEMPLATE = <<~SPEC + # frozen_string_literal: true + + RSpec.describe RuboCop::Cop::%s::%s, :config do + let(:config) { RuboCop::Config.new } + + # TODO: Write test code + # + # For example + it 'registers an offense when using `#bad_method`' do + expect_offense(<<~RUBY) + bad_method + ^^^^^^^^^^ Use `#good_method` instead of `#bad_method`. + RUBY + end + + it 'does not register an offense when using `#good_method`' do + expect_no_offenses(<<~RUBY) + good_method + RUBY + end + end + SPEC + + CONFIGURATION_ADDED_MESSAGE = + '[modify] A configuration for the cop is added into ' \ + '%s.' + + def initialize(name, output: $stdout) + @badge = Badge.parse(name) + @output = output + return if badge.qualified? + + raise ArgumentError, 'Specify a cop name with Department/Name style' + end + + def write_source + write_unless_file_exists(source_path, generated_source) + end + + def write_spec + write_unless_file_exists(spec_path, generated_spec) + end + + def inject_require(root_file_path: 'lib/rubocop.rb') + RequireFileInjector.new(source_path: source_path, root_file_path: root_file_path).inject + end + + def inject_config(config_file_path: 'config/default.yml', + version_added: '<>') + injector = + ConfigurationInjector.new(configuration_file_path: config_file_path, + badge: badge, + version_added: version_added) + + injector.inject do # rubocop:disable Lint/UnexpectedBlockArity + output.puts(format(CONFIGURATION_ADDED_MESSAGE, + configuration_file_path: config_file_path)) + end + end + + def todo + <<~TODO + Do 4 steps: + 1. Modify the description of #{badge} in config/default.yml + 2. Implement your new cop in the generated file! + 3. Commit your new cop with a message such as + e.g. "Add new `#{badge}` cop" + 4. Run `bundle exec rake changelog:new` to generate a changelog entry + for your new cop. + TODO + end + + private + + attr_reader :badge, :output + + def write_unless_file_exists(path, contents) + if File.exist?(path) + warn "rake new_cop: #{path} already exists!" + exit! + end + + dir = File.dirname(path) + FileUtils.mkdir_p(dir) + + File.write(path, contents) + output.puts "[create] #{path}" + end + + def generated_source + generate(SOURCE_TEMPLATE) + end + + def generated_spec + generate(SPEC_TEMPLATE) + end + + def generate(template) + format(template, department: badge.department.to_s.gsub('/', '::'), + cop_name: badge.cop_name) + end + + def spec_path + File.join( + 'spec', + 'rubocop', + 'cop', + snake_case(badge.department.to_s), + "#{snake_case(badge.cop_name.to_s)}_spec.rb" + ) + end + + def source_path + File.join( + 'lib', + 'rubocop', + 'cop', + snake_case(badge.department.to_s), + "#{snake_case(badge.cop_name.to_s)}.rb" + ) + end + + def snake_case(camel_case_string) + camel_case_string + .gsub('RSpec', 'Rspec') + .gsub(%r{([^A-Z/])([A-Z]+)}, '\1_\2') + .gsub(%r{([A-Z])([A-Z][^A-Z\d/]+)}, '\1_\2') + .downcase + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/generator/configuration_injector.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/generator/configuration_injector.rb new file mode 100644 index 00000000..882fcb33 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/generator/configuration_injector.rb @@ -0,0 +1,65 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + class Generator + # A class that injects a require directive into the root RuboCop file. + # It looks for other directives that require files in the same (cop) + # namespace and injects the provided one in alpha + class ConfigurationInjector + TEMPLATE = <<~YAML + %s: + Description: 'TODO: Write a description of the cop.' + Enabled: pending + VersionAdded: '%s' + YAML + + def initialize(configuration_file_path:, badge:, version_added: '<>') + @configuration_file_path = configuration_file_path + @badge = badge + @version_added = version_added + @output = output + end + + def inject + target_line = find_target_line + if target_line + configuration_entries.insert(target_line, "#{new_configuration_entry}\n") + else + configuration_entries.push("\n#{new_configuration_entry}") + end + + File.write(configuration_file_path, configuration_entries.join) + + yield if block_given? + end + + private + + attr_reader :configuration_file_path, :badge, :version_added, :output + + def configuration_entries + @configuration_entries ||= File.readlines(configuration_file_path) + end + + def new_configuration_entry + format(TEMPLATE, badge: badge, version_added: version_added) + end + + def find_target_line + configuration_entries.find.with_index do |line, index| + next unless cop_name_line?(line) + + return index if badge.to_s < line + end + + nil + end + + def cop_name_line?(yaml) + !/^[\s#]/.match?(yaml) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/generator/require_file_injector.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/generator/require_file_injector.rb new file mode 100644 index 00000000..2a097ef5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/generator/require_file_injector.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + class Generator + # A class that injects a require directive into the root RuboCop file. + # It looks for other directives that require files in the same (cop) + # namespace and injects the provided one in alpha + class RequireFileInjector + REQUIRE_PATH = /require_relative ['"](.+)['"]/.freeze + + def initialize(source_path:, root_file_path:, output: $stdout) + @source_path = Pathname(source_path) + @root_file_path = Pathname(root_file_path) + @require_entries = File.readlines(root_file_path) + @output = output + end + + def inject + return if require_exists? || !target_line + + File.write(root_file_path, updated_directives) + require = injectable_require_directive.chomp + output.puts "[modify] #{root_file_path} - `#{require}` was injected." + end + + private + + attr_reader :require_entries, :root_file_path, :source_path, :output + + def require_exists? + require_entries.any?(injectable_require_directive) + end + + def updated_directives + require_entries.insert(target_line, injectable_require_directive).join + end + + def target_line + @target_line ||= begin + in_the_same_department = false + inject_parts = require_path_fragments(injectable_require_directive) + + require_entries.find.with_index do |entry, index| + current_entry_parts = require_path_fragments(entry) + + if inject_parts[0..-2] == current_entry_parts[0..-2] + in_the_same_department = true + + break index if inject_parts.last < current_entry_parts.last + elsif in_the_same_department + break index + end + end || require_entries.size + end + end + + def require_path_fragments(require_directive) + path = require_directive.match(REQUIRE_PATH) + + path ? path.captures.first.split('/') : [] + end + + def injectable_require_directive + "require_relative '#{require_path}'\n" + end + + def require_path + path = source_path.relative_path_from(root_file_path.dirname) + path.to_s.delete_suffix('.rb') + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/ignored_node.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/ignored_node.rb new file mode 100644 index 00000000..6be9265d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/ignored_node.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + # Handles adding and checking ignored nodes. + module IgnoredNode + def ignore_node(node) + ignored_nodes << node + end + + def part_of_ignored_node?(node) + ignored_nodes.map(&:loc).any? do |ignored_loc| + next false if ignored_loc.expression.begin_pos > node.source_range.begin_pos + + ignored_end_pos = if ignored_loc.respond_to?(:heredoc_body) + ignored_loc.heredoc_end.end_pos + else + ignored_loc.expression.end_pos + end + ignored_end_pos >= node.source_range.end_pos + end + end + + def ignored_node?(node) + # Same object found in array? + ignored_nodes.any? { |n| n.equal?(node) } + end + + private + + def ignored_nodes + @ignored_nodes ||= [] + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs.rb new file mode 100644 index 00000000..39bf3b4e --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require_relative 'internal_affairs/cop_description' +require_relative 'internal_affairs/cop_enabled' +require_relative 'internal_affairs/create_empty_file' +require_relative 'internal_affairs/empty_line_between_expect_offense_and_correction' +require_relative 'internal_affairs/example_description' +require_relative 'internal_affairs/example_heredoc_delimiter' +require_relative 'internal_affairs/inherit_deprecated_cop_class' +require_relative 'internal_affairs/lambda_or_proc' +require_relative 'internal_affairs/location_exists' +require_relative 'internal_affairs/location_expression' +require_relative 'internal_affairs/location_line_equality_comparison' +require_relative 'internal_affairs/method_name_end_with' +require_relative 'internal_affairs/method_name_equal' +require_relative 'internal_affairs/node_destructuring' +require_relative 'internal_affairs/node_first_or_last_argument' +require_relative 'internal_affairs/node_matcher_directive' +require_relative 'internal_affairs/node_pattern_groups' +require_relative 'internal_affairs/node_type_group' +require_relative 'internal_affairs/node_type_multiple_predicates' +require_relative 'internal_affairs/node_type_predicate' +require_relative 'internal_affairs/numblock_handler' +require_relative 'internal_affairs/offense_location_keyword' +require_relative 'internal_affairs/on_send_without_on_csend' +require_relative 'internal_affairs/operator_keyword' +require_relative 'internal_affairs/processed_source_buffer_name' +require_relative 'internal_affairs/redundant_context_config_parameter' +require_relative 'internal_affairs/redundant_described_class_as_subject' +require_relative 'internal_affairs/redundant_expect_offense_arguments' +require_relative 'internal_affairs/redundant_let_rubocop_config_new' +require_relative 'internal_affairs/redundant_location_argument' +require_relative 'internal_affairs/redundant_message_argument' +require_relative 'internal_affairs/redundant_method_dispatch_node' +require_relative 'internal_affairs/redundant_source_range' +require_relative 'internal_affairs/single_line_comparison' +require_relative 'internal_affairs/style_detected_api_use' +require_relative 'internal_affairs/undefined_config' +require_relative 'internal_affairs/useless_message_assertion' +require_relative 'internal_affairs/useless_restrict_on_send' diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/cop_description.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/cop_description.rb new file mode 100644 index 00000000..7e472dda --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/cop_description.rb @@ -0,0 +1,118 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Enforces the cop description to start with a word such as verb. + # + # @example + # # bad + # # This cop checks .... + # class SomeCop < Base + # .... + # end + # + # # bad + # # + # # Checks ... + # class SomeCop < Base + # ... + # end + # + # # good + # # Checks ... + # class SomeCop < Base + # ... + # end + # + class CopDescription < Base + extend AutoCorrector + + MSG_STARTS_WITH_WRONG_WORD = + 'Description should be started with %s instead of `This cop ...`.' + MSG_STARTS_WITH_EMPTY_COMMENT_LINE = + 'Description should not start with an empty comment line.' + + SPECIAL_WORDS = %w[is can could should will would must may].freeze + COP_DESC_OFFENSE_REGEX = + /^\s+# This cop (?#{SPECIAL_WORDS.join('|')})?\s*(?.+?) .*/.freeze + REPLACEMENT_REGEX = /^\s+# This cop (#{SPECIAL_WORDS.join('|')})?\s*(.+?) /.freeze + EMPTY_COMMENT_LINE_REGEX = /\A\s*#\s*\n\z/.freeze + + def on_class(node) + return unless (module_node = node.parent) && node.parent_class + + description_beginning = first_comment_line(module_node) + return unless description_beginning + + if description_beginning.match?(EMPTY_COMMENT_LINE_REGEX) + register_offense_for_empty_comment_line(module_node, description_beginning) + else + start_with_subject = description_beginning.match(COP_DESC_OFFENSE_REGEX) + return unless start_with_subject + + register_offense_for_wrong_word(module_node, description_beginning, start_with_subject) + end + end + + private + + def register_offense_for_empty_comment_line(module_node, description_beginning) + range = range(module_node, description_beginning) + add_offense(range, message: MSG_STARTS_WITH_EMPTY_COMMENT_LINE) do |corrector| + corrector.remove(range) + end + end + + def register_offense_for_wrong_word(module_node, description_beginning, start_with_subject) + suggestion = start_with_subject['word']&.capitalize + range = range(module_node, description_beginning) + suggestion_for_message = suggestion_for_message(suggestion, start_with_subject) + message = format(MSG_STARTS_WITH_WRONG_WORD, suggestion: suggestion_for_message) + + add_offense(range, message: message) do |corrector| + if suggestion && !start_with_subject['special'] + replace_with_suggestion(corrector, range, suggestion, description_beginning) + end + end + end + + def replace_with_suggestion(corrector, range, suggestion, description_beginning) + replacement = description_beginning.gsub(REPLACEMENT_REGEX, "#{suggestion} ") + corrector.replace(range, replacement) + end + + def range(node, comment_line) + source_buffer = node.source_range.source_buffer + + begin_pos = node.source_range.begin_pos + begin_pos += comment_index(node, comment_line) + end_pos = begin_pos + comment_body(comment_line).length + + Parser::Source::Range.new(source_buffer, begin_pos, end_pos) + end + + def suggestion_for_message(suggestion, match_data) + if suggestion && !match_data['special'] + "`#{suggestion}`" + else + 'a word such as verb' + end + end + + def first_comment_line(node) + node.source.lines.find { |line| comment_line?(line) } + end + + def comment_body(comment_line) + comment_line.gsub(/^\s*# /, '') + end + + def comment_index(node, comment_line) + body = comment_body(comment_line) + node.source.index(body) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/cop_enabled.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/cop_enabled.rb new file mode 100644 index 00000000..ec26a3bd --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/cop_enabled.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Use `config.cop_enabled?('Department/CopName')` instead of + # traversing the config hash. + # + # @example + # # `for_cop(...)['Enabled'] + # + # # bad + # config.for_cop('Department/CopName')['Enabled'] + # + # # good + # config.cop_enabled?('Department/CopName') + # + # @example + # # when keeping a cop's config in a local and then checking the `Enabled` key + # + # # bad + # cop_config = config.for_cop('Department/CopName') + # cop_config['Enabled'] && cop_config['Foo'] + # + # # good + # config.for_enabled_cop('Department/CopName')['Foo'] + # + class CopEnabled < Base + extend AutoCorrector + + MSG = 'Use `%s` instead of `%s`.' + MSG_HASH = 'Consider replacing uses of `%s` with `config.for_enabled_cop`.' + + RESTRICT_ON_SEND = [:[]].freeze + + # @!method for_cop_enabled?(node) + def_node_matcher :for_cop_enabled?, <<~PATTERN + (send + (send + ${(send nil? :config) (ivar :@config)} :for_cop + $(str _)) :[] + (str "Enabled")) + PATTERN + + # @!method config_enabled_lookup?(node) + def_node_matcher :config_enabled_lookup?, <<~PATTERN + (send + {(lvar $_) (ivar $_) (send nil? $_)} :[] + (str "Enabled")) + PATTERN + + def on_send(node) + if (config_var, cop_name = for_cop_enabled?(node)) + handle_for_cop(node, config_var, cop_name) + elsif (config_var = config_enabled_lookup?(node)) + return unless config_var.end_with?('_config') + + handle_hash(node, config_var) + end + end + + private + + def handle_for_cop(node, config_var, cop_name) + source = node.source + quote = cop_name.loc.begin.source + cop_name = cop_name.value + + replacement = "#{config_var.source}.cop_enabled?(#{quote}#{cop_name}#{quote})" + message = format(MSG, source: source, replacement: replacement) + + add_offense(node, message: message) do |corrector| + corrector.replace(node, replacement) + end + end + + def handle_hash(node, config_var) + message = format(MSG_HASH, hash_name: config_var) + + add_offense(node, message: message) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/create_empty_file.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/create_empty_file.rb new file mode 100644 index 00000000..44ed5b14 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/create_empty_file.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Checks for uses of `create_file` with empty string second argument. + # + # @example + # + # # bad + # create_file(path, '') + # + # # good + # create_empty_file(path) + # + class CreateEmptyFile < Base + extend AutoCorrector + + MSG = 'Use `%s`.' + RESTRICT_ON_SEND = %i[create_file].freeze + + def on_send(node) + return if node.receiver + return unless (argument = node.arguments[1]) + return unless argument.str_type? && argument.value.empty? + + replacement = "create_empty_file(#{node.first_argument.source})" + message = format(MSG, replacement: replacement) + + add_offense(node, message: message) do |corrector| + corrector.replace(node, replacement) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/empty_line_between_expect_offense_and_correction.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/empty_line_between_expect_offense_and_correction.rb new file mode 100644 index 00000000..b6fb9609 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/empty_line_between_expect_offense_and_correction.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Checks whether `expect_offense` and correction expectation methods + # (i.e. `expect_correction` and `expect_no_corrections`) are separated by empty line. + # + # @example + # # bad + # it 'registers and corrects an offense' do + # expect_offense(<<~RUBY) + # bad_method + # ^^^^^^^^^^ Use `good_method`. + # RUBY + # expect_correction(<<~RUBY) + # good_method + # RUBY + # end + # + # # good + # it 'registers and corrects an offense' do + # expect_offense(<<~RUBY) + # bad_method + # ^^^^^^^^^^ Use `good_method`. + # RUBY + # + # expect_correction(<<~RUBY) + # good_method + # RUBY + # end + # + class EmptyLineBetweenExpectOffenseAndCorrection < Base + extend AutoCorrector + + MSG = 'Add empty line between `expect_offense` and `%s`.' + RESTRICT_ON_SEND = %i[expect_offense].freeze + CORRECTION_EXPECTATION_METHODS = %i[expect_correction expect_no_corrections].freeze + + def on_send(node) + return unless (next_sibling = node.right_sibling) + return unless next_sibling.respond_to?(:send_type?) && next_sibling.send_type? + + method_name = next_sibling.method_name + return unless CORRECTION_EXPECTATION_METHODS.include?(method_name) + + range = offense_range(node) + return unless range.last_line + 1 == next_sibling.loc.line + + add_offense(range, message: format(MSG, expect_correction: method_name)) do |corrector| + corrector.insert_after(range, "\n") + end + end + + private + + def offense_range(node) + first_argument = node.first_argument + + if first_argument.respond_to?(:heredoc?) && first_argument.heredoc? + first_argument.loc.heredoc_end + else + node + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/example_description.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/example_description.rb new file mode 100644 index 00000000..36e8dac7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/example_description.rb @@ -0,0 +1,118 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Checks that RSpec examples that use `expects_offense` + # or `expects_no_offenses` do not have conflicting + # descriptions. + # + # @example + # # bad + # it 'does not register an offense' do + # expect_offense('...') + # end + # + # it 'registers an offense' do + # expect_no_offenses('...') + # end + # + # # good + # it 'registers an offense' do + # expect_offense('...') + # end + # + # it 'does not register an offense' do + # expect_no_offenses('...') + # end + class ExampleDescription < Base + extend AutoCorrector + + MSG = 'Description does not match use of `%s`.' + + RESTRICT_ON_SEND = %i[ + expect_offense + expect_no_offenses + expect_correction + expect_no_corrections + ].to_set.freeze + + EXPECT_NO_OFFENSES_DESCRIPTION_MAPPING = { + /\A(adds|registers|reports|finds) (an? )?offense/ => 'does not register an offense', + /\A(flags|handles|works)\b/ => 'does not register' + }.freeze + + EXPECT_OFFENSE_DESCRIPTION_MAPPING = { + /\A(does not|doesn't) (register|find|flag|report)/ => 'registers', + /\A(does not|doesn't) add (a|an|any )?offense/ => 'registers an offense', + /\Aregisters no offense/ => 'registers an offense', + /\A(accepts|register)\b/ => 'registers' + }.freeze + + EXPECT_NO_CORRECTIONS_DESCRIPTION_MAPPING = { + /\A(auto[- ]?)?corrects?/ => 'does not correct', + /\band (auto[- ]?)?corrects/ => 'but does not correct' + }.freeze + + EXPECT_CORRECTION_DESCRIPTION_MAPPING = { + /\bbut (does not|doesn't) (auto[- ]?)?correct/ => 'and autocorrects', + /\b(does not|doesn't) (auto[- ]?)?correct/ => 'autocorrects' + }.freeze + + EXAMPLE_DESCRIPTION_MAPPING = { + expect_no_offenses: EXPECT_NO_OFFENSES_DESCRIPTION_MAPPING, + expect_offense: EXPECT_OFFENSE_DESCRIPTION_MAPPING, + expect_no_corrections: EXPECT_NO_CORRECTIONS_DESCRIPTION_MAPPING, + expect_correction: EXPECT_CORRECTION_DESCRIPTION_MAPPING + }.freeze + + # @!method offense_example(node) + def_node_matcher :offense_example, <<~PATTERN + (block + (send _ {:it :specify :xit :fit} $...) + _args + `(send nil? %RESTRICT_ON_SEND ...) + ) + PATTERN + + def on_send(node) + parent = node.each_ancestor(:block).first + return unless parent && (current_description = offense_example(parent)&.first) + + method_name = node.method_name + message = format(MSG, method_name: method_name) + + description_map = EXAMPLE_DESCRIPTION_MAPPING[method_name] + check_description(current_description, description_map, message) + end + + private + + def check_description(current_description, description_map, message) + description_text = string_contents(current_description) + return unless (new_description = correct_description(description_text, description_map)) + + quote = current_description.dstr_type? ? '"' : "'" + + add_offense(current_description, message: message) do |corrector| + corrector.replace(current_description, "#{quote}#{new_description}#{quote}") + end + end + + def correct_description(current_description, description_map) + description_map.each do |incorrect_description_pattern, preferred_description| + if incorrect_description_pattern.match?(current_description) + return current_description.gsub(incorrect_description_pattern, preferred_description) + end + end + + nil + end + + def string_contents(node) + node.type?(:str, :dstr) ? node.value : node.source + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb new file mode 100644 index 00000000..78832673 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb @@ -0,0 +1,111 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Use `RUBY` for heredoc delimiter of example Ruby code. + # + # Some editors may apply better syntax highlighting by using appropriate language names for + # the delimiter. + # + # @example + # # bad + # expect_offense(<<~CODE) + # example_ruby_code + # CODE + # + # # good + # expect_offense(<<~RUBY) + # example_ruby_code + # RUBY + class ExampleHeredocDelimiter < Base + extend AutoCorrector + + EXPECTED_HEREDOC_DELIMITER = 'RUBY' + + MSG = 'Use `RUBY` for heredoc delimiter of example Ruby code.' + + RESTRICT_ON_SEND = %i[ + expect_correction + expect_no_corrections + expect_no_offenses + expect_offense + ].freeze + + # @param node [RuboCop::AST::SendNode] + # @return [void] + def on_send(node) + heredoc_node = heredoc_node_from(node) + return unless heredoc_node + return if expected_heredoc_delimiter?(heredoc_node) + return if expected_heredoc_delimiter_in_body?(heredoc_node) + + add_offense(heredoc_node) do |corrector| + autocorrect(corrector, heredoc_node) + end + end + + private + + # @param corrector [RuboCop::Cop::Corrector] + # @param node [RuboCop::AST::StrNode] + # @return [void] + def autocorrect(corrector, node) + [ + heredoc_opening_delimiter_range_from(node), + heredoc_closing_delimiter_range_from(node) + ].each do |range| + corrector.replace(range, EXPECTED_HEREDOC_DELIMITER) + end + end + + # @param node [RuboCop::AST::StrNode] + # @return [Boolean] + def expected_heredoc_delimiter_in_body?(node) + node.location.heredoc_body.source.lines.any? do |line| + line.strip == EXPECTED_HEREDOC_DELIMITER + end + end + + # @param node [RuboCop::AST::StrNode] + # @return [Boolean] + def expected_heredoc_delimiter?(node) + heredoc_delimiter_string_from(node) == EXPECTED_HEREDOC_DELIMITER + end + + # @param node [RuboCop::AST::SendNode] + # @return [RuboCop::AST::StrNode, nil] + def heredoc_node_from(node) + return unless node.first_argument.respond_to?(:heredoc?) + return unless node.first_argument.heredoc? + + node.first_argument + end + + # @param node [RuboCop::AST::StrNode] + # @return [String] + def heredoc_delimiter_string_from(node) + node.source[Heredoc::OPENING_DELIMITER, 2] + end + + # @param node [RuboCop::AST::StrNode] + # @return [Parser::Source::Range] + def heredoc_opening_delimiter_range_from(node) + match_data = node.source.match(Heredoc::OPENING_DELIMITER) + node.source_range.begin.adjust( + begin_pos: match_data.begin(2), + end_pos: match_data.end(2) + ) + end + + # @param node [RuboCop::AST::StrNode] + # @return [Parser::Source::Range] + def heredoc_closing_delimiter_range_from(node) + node.location.heredoc_end.end.adjust( + begin_pos: -heredoc_delimiter_string_from(node).length + ) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/inherit_deprecated_cop_class.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/inherit_deprecated_cop_class.rb new file mode 100644 index 00000000..f7389e79 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/inherit_deprecated_cop_class.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # `RuboCop::Cop::Cop` is deprecated and will be removed in RuboCop 2.0. + # Your custom cop class should inherit from `RuboCop::Cop::Base` instead of + # `RuboCop::Cop::Cop`. + # + # See "v1 Upgrade Notes" for more details: + # https://docs.rubocop.org/rubocop/v1_upgrade_notes.html + # + # @example + # # bad + # class Foo < Cop + # end + # + # # good + # class Foo < Base + # end + # + class InheritDeprecatedCopClass < Base + MSG = 'Use `Base` instead of `Cop`.' + + def on_class(node) + return unless (parent_class = node.parent_class) + return unless parent_class.children.last == :Cop + + add_offense(parent_class) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/lambda_or_proc.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/lambda_or_proc.rb new file mode 100644 index 00000000..dfc4ff88 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/lambda_or_proc.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Enforces the use of `node.lambda_or_proc?` instead of `node.lambda? || node.proc?`. + # + # @example + # # bad + # node.lambda? || node.proc? + # node.proc? || node.lambda? + # + # # good + # node.lambda_or_proc? + # + class LambdaOrProc < Base + extend AutoCorrector + + MSG = 'Use `%s`.' + + # @!method lambda_or_proc(node) + def_node_matcher :lambda_or_proc, <<~PATTERN + { + (or $(send _node :lambda?) $(send _node :proc?)) + (or $(send _node :proc?) $(send _node :lambda?)) + (or + (or _ $(send _node :lambda?)) $(send _node :proc?)) + (or + (or _ $(send _node :proc?)) $(send _node :lambda?)) + } + PATTERN + + def on_or(node) + return unless (lhs, rhs = lambda_or_proc(node)) + + offense = lhs.receiver.source_range.join(rhs.source_range.end) + prefer = "#{lhs.receiver.source}.lambda_or_proc?" + + add_offense(offense, message: format(MSG, prefer: prefer)) do |corrector| + corrector.replace(offense, prefer) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/location_exists.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/location_exists.rb new file mode 100644 index 00000000..a5fa823a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/location_exists.rb @@ -0,0 +1,116 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # When a node location may not exist, `Node#loc?` or `Node#loc_is?` + # can be used instead of calling `Node#respond_to?` before using + # the value. + # + # @example + # # bad + # node.loc.respond_to?(:begin) && node.loc.begin + # + # # good + # node.loc?(:begin) + # + # # bad + # node.loc.respond_to?(:begin) && node.loc.begin.is?('(') + # + # # good + # node.loc_is?(:begin, '(') + # + # # bad + # node.loc.respond_to?(:begin) && node.loc.begin.source == '(' + # + # # good + # node.loc_is?(:begin, '(') + # + class LocationExists < Base + extend AutoCorrector + + MSG = 'Use `%s` instead of `%s`.' + + # @!method replaceable_with_loc_is(node) + def_node_matcher :replaceable_with_loc_is, <<~PATTERN + (and + (call + (call $_receiver :loc) :respond_to? + $(sym _location)) + { + (call + (call + (call _receiver :loc) _location) :is? + $(str _)) + (call + (call + (call + (call _receiver :loc) _location) :source) :== + $(str _)) + }) + PATTERN + + # @!method replaceable_with_loc(node) + def_node_matcher :replaceable_with_loc, <<~PATTERN + (and + (call + (call $_receiver :loc) :respond_to? + $(sym _location)) + (call + (call _receiver :loc) _location)) + PATTERN + + def on_and(node) + replace_with_loc(node) || replace_with_loc_is(node) + end + + private + + def replace_with_loc(node) + replaceable_with_loc(node) do |receiver, location| + if node.parent&.assignment? + register_offense(node, replace_assignment(receiver, location)) + else + register_offense(node, replacement(receiver, "loc?(#{location.source})")) + end + end + end + + def replace_with_loc_is(node) + replaceable_with_loc_is(node) do |receiver, location, value| + replacement = replacement(receiver, "loc_is?(#{location.source}, #{value.source})") + register_offense(node, replacement) + end + end + + def register_offense(node, replacement) + message = format(MSG, replacement: replacement, source: node.source) + + add_offense(node, message: message) do |corrector| + corrector.replace(node, replacement) + end + end + + def replacement(receiver, rest) + "#{replace_receiver(receiver)}#{rest}" + end + + def replace_assignment(receiver, location) + prefix = replace_receiver(receiver) + + "#{prefix}loc#{dot(receiver)}#{location.value} if #{prefix}loc?(#{location.source})" + end + + def replace_receiver(receiver) + return '' unless receiver + + "#{receiver.source}#{dot(receiver)}" + end + + def dot(node) + node.parent.loc.dot.source + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/location_expression.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/location_expression.rb new file mode 100644 index 00000000..f195f7c1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/location_expression.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Enforces the use of `node.source_range` instead of `node.location.expression`. + # + # @example + # + # # bad + # node.location.expression + # node.loc.expression + # + # # good + # node.source_range + # + class LocationExpression < Base + extend AutoCorrector + + MSG = 'Use `source_range` instead.' + RESTRICT_ON_SEND = %i[loc location].freeze + + def on_send(node) + return unless (parent = node.parent) + return unless parent.call_type? && parent.method?(:expression) + return unless parent.receiver.receiver + + offense = node.loc.selector.join(parent.source_range.end) + + add_offense(offense) do |corrector| + corrector.replace(offense, 'source_range') + end + end + alias on_csend on_send + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb new file mode 100644 index 00000000..9dd78320 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Enforces the use of `same_line?` instead of location line comparison for equality. + # + # @example + # # bad + # node.loc.line == node.parent.loc.line + # + # # bad + # node.loc.first_line == node.parent.loc.first_line + # + # # good + # same_line?(node, node.parent) + # + class LocationLineEqualityComparison < Base + extend AutoCorrector + + MSG = 'Use `%s`.' + RESTRICT_ON_SEND = [:==].freeze + + # @!method line_send(node) + def_node_matcher :line_send, <<~PATTERN + { + (send (send _ {:loc :source_range}) {:line :first_line}) + (send _ :first_line) + } + PATTERN + + # @!method location_line_equality_comparison?(node) + def_node_matcher :location_line_equality_comparison?, <<~PATTERN + (send #line_send :== #line_send) + PATTERN + + def on_send(node) + return unless location_line_equality_comparison?(node) + + lhs_receiver = extract_receiver(node.receiver) + rhs_receiver = extract_receiver(node.first_argument) + preferred = "same_line?(#{lhs_receiver}, #{rhs_receiver})" + + add_offense(node, message: format(MSG, preferred: preferred)) do |corrector| + corrector.replace(node, preferred) + end + end + + private + + def extract_receiver(node) + receiver = node.receiver + if receiver.send_type? && (receiver.method?(:loc) || receiver.method?(:source_range)) + receiver = receiver.receiver + end + receiver.source + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/method_name_end_with.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/method_name_end_with.rb new file mode 100644 index 00000000..648f61ed --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/method_name_end_with.rb @@ -0,0 +1,82 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Checks potentially usage of method identifier predicates + # defined in rubocop-ast instead of `method_name.end_with?`. + # + # @example + # # bad + # node.method_name.to_s.end_with?('=') + # + # # good + # node.assignment_method? + # + # # bad + # node.method_name.to_s.end_with?('?') + # + # # good + # node.predicate_method? + # + # # bad + # node.method_name.to_s.end_with?('!') + # + # # good + # node.bang_method? + # + class MethodNameEndWith < Base + include RangeHelp + extend AutoCorrector + + MSG = 'Use `%s` instead of `%s`.' + RESTRICT_ON_SEND = %i[end_with?].freeze + SUGGEST_METHOD_FOR_SUFFIX = { + '=' => 'assignment_method?', + '!' => 'bang_method?', + '?' => 'predicate_method?' + }.freeze + + # @!method method_name_end_with?(node) + def_node_matcher :method_name_end_with?, <<~PATTERN + { + (call + (call + $(... :method_name) :to_s) :end_with? + $(str {"=" "?" "!"})) + (call + $(... :method_name) :end_with? + $(str {"=" "?" "!"})) + } + PATTERN + + def on_send(node) + method_name_end_with?(node) do |method_name_node, end_with_arg| + next unless method_name_node.receiver + + preferred_method = SUGGEST_METHOD_FOR_SUFFIX[end_with_arg.value] + range = range(method_name_node, node) + message = format(MSG, method_name: preferred_method, method_suffix: range.source) + + add_offense(range, message: message) do |corrector| + corrector.replace(range, preferred_method) + end + end + end + alias on_csend on_send + + private + + def range(method_name_node, node) + range = if method_name_node.call_type? + method_name_node.loc.selector + else + method_name_node.source_range + end + + range_between(range.begin_pos, node.source_range.end_pos) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/method_name_equal.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/method_name_equal.rb new file mode 100644 index 00000000..ea3f56ec --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/method_name_equal.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Checks that method names are checked using `method?` method. + # + # @example + # # bad + # node.method_name == :do_something + # + # # good + # node.method?(:do_something) + # + # # bad + # node.method_name != :do_something + # + # # good + # !node.method?(:do_something) + # + class MethodNameEqual < Base + extend AutoCorrector + + MSG = 'Use `%s` instead.' + RESTRICT_ON_SEND = %i[== !=].freeze + + # @!method method_name(node) + def_node_matcher :method_name, <<~PATTERN + (send + (send + (...) :method_name) {:== :!=} + $_) + PATTERN + + def on_send(node) + method_name(node) do |method_name_arg| + bang = node.method?(:!=) ? '!' : '' + prefer = "#{bang}#{node.receiver.receiver.source}.method?(#{method_name_arg.source})" + message = format(MSG, prefer: prefer) + + add_offense(node, message: message) do |corrector| + corrector.replace(node, prefer) + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_destructuring.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_destructuring.rb new file mode 100644 index 00000000..2e3bab9b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_destructuring.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Checks that node destructuring is using the node extensions. + # + # @example Using splat expansion + # + # # bad + # _receiver, method_name, _arguments = send_node.children + # + # # bad + # _receiver, method_name, _arguments = *send_node + # + # # good + # method_name = send_node.method_name + class NodeDestructuring < Base + MSG = 'Use the methods provided with the node extensions instead ' \ + 'of manually destructuring nodes.' + + # @!method node_variable?(node) + def_node_matcher :node_variable?, <<~PATTERN + {(lvar [#node_suffix? _]) (send nil? [#node_suffix? _])} + PATTERN + + # @!method node_destructuring?(node) + def_node_matcher :node_destructuring?, <<~PATTERN + {(masgn (mlhs ...) {(send #node_variable? :children) (array (splat #node_variable?))})} + PATTERN + + def on_masgn(node) + node_destructuring?(node) { add_offense(node) } + end + + private + + def node_suffix?(method_name) + method_name.to_s.end_with?('node') + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb new file mode 100644 index 00000000..efba778a --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Checks for the use of `node.arguments.first` or `node.arguments.last` and + # suggests the use of `node.first_argument` or `node.last_argument` instead. + # + # @example + # # bad + # node.arguments.first + # node.arguments[0] + # node.arguments.last + # node.arguments[-1] + # + # # good + # node.first_argument + # node.last_argument + # + class NodeFirstOrLastArgument < Base + extend AutoCorrector + include RangeHelp + + MSG = 'Use `#%s` instead of `#%s`.' + RESTRICT_ON_SEND = %i[arguments].freeze + + # @!method arguments_first_or_last?(node) + def_node_matcher :arguments_first_or_last?, <<~PATTERN + { + (call (call !nil? :arguments) ${:first :last}) + (call (call !nil? :arguments) :[] (int ${0 -1})) + } + PATTERN + + def on_send(node) + arguments_first_or_last?(node.parent) do |end_or_index| + range = range_between(node.loc.selector.begin_pos, node.parent.source_range.end_pos) + correct = case end_or_index + when :first, 0 then 'first_argument' + when :last, -1 then 'last_argument' + else raise "Unknown end_or_index: #{end_or_index}" + end + message = format(MSG, correct: correct, incorrect: range.source) + + add_offense(range, message: message) do |corrector| + corrector.replace(range, correct) + end + end + end + alias on_csend on_send + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb new file mode 100644 index 00000000..bcf50948 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb @@ -0,0 +1,241 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Checks that node matcher definitions are tagged with a YARD `@!method` + # directive so that editors are able to find the dynamically defined + # method. + # + # @example + # # bad + # def_node_matcher :foo?, <<~PATTERN + # ... + # PATTERN + # + # # good + # # @!method foo?(node) + # def_node_matcher :foo?, <<~PATTERN + # ... + # PATTERN + # + class NodeMatcherDirective < Base + extend AutoCorrector + include RangeHelp + + MSG = 'Precede `%s` with a `@!method` YARD directive.' + MSG_WRONG_NAME = '`@!method` YARD directive has invalid method name, ' \ + 'use `%s` instead of `%s`.' + MSG_MISSING_SCOPE_SELF = 'Follow the `@!method` YARD directive with ' \ + '`@!scope class` if it is a class method.' + MSG_WRONG_SCOPE_SELF = 'Do not use the `@!scope class` YARD directive if it ' \ + 'is not a class method.' + MSG_TOO_MANY = 'Multiple `@!method` YARD directives found for this matcher.' + + RESTRICT_ON_SEND = %i[def_node_matcher def_node_search].to_set.freeze + REGEXP_METHOD = / + ^\s*\#\s* + @!method\s+(?self\.)?(?[a-z0-9_]+[?!]?)(?:\((?.*)\))? + /x.freeze + REGEXP_SCOPE = /^\s*\#\s*@!scope class/.freeze + + # @!method pattern_matcher?(node) + def_node_matcher :pattern_matcher?, <<~PATTERN + (send _ %RESTRICT_ON_SEND {str sym} {str dstr}) + PATTERN + + def on_send(node) + return unless node.arguments.count == 2 + return unless valid_method_name?(node) + + actual_name = node.first_argument.value.to_s + + # Ignore cases where the method has a receiver that isn't self + return if actual_name.include?('.') && !actual_name.start_with?('self.') + + directives = method_directives(node) + return too_many_directives(node) if directives.size > 1 + + process_directive(node, actual_name, directives.first) + end + + private + + def valid_method_name?(node) + node.first_argument.type?(:str, :sym) + end + + def method_directives(node) + comments = processed_source.ast_with_comments[node] + group_comments(comments).filter_map do |comment_method, comment_scope| + match = comment_method.text.match(REGEXP_METHOD) + next unless match + + { + node_method: comment_method, + node_scope: comment_scope, + method_name: match[:method_name], + args: match[:args], + receiver: match[:receiver], + has_scope_directive: comment_scope&.text&.match?(REGEXP_SCOPE) + } + end + end + + def group_comments(comments) + result = [] + comments.each.with_index do |comment, index| + # Grab the scope directive if it is preceded by a method directive + if comment.text.include?('@!method') + result << if (next_comment = comments[index + 1])&.text&.include?('@!scope') + [comment, next_comment] + else + [comment, nil] + end + end + end + result + end + + def too_many_directives(node) + add_offense(node, message: MSG_TOO_MANY) + end + + def process_directive(node, actual_name, directive) + return unless (offense_type = directive_offense_type(directive, actual_name)) + + register_offense(offense_type, node, directive, actual_name) + end + + def directive_offense_type(directive, actual_name) + return :missing_directive unless directive + + return :wrong_scope if wrong_scope(directive, actual_name) + return :no_scope if no_scope(directive, actual_name) + + # The method directive being prefixed by 'self.' is always an offense. + # The matched method_name does not contain the receiver but the + # def_node_match method name may so it must be removed. + if directive[:method_name] != remove_receiver(actual_name) || directive[:receiver] + :wrong_name + end + end + + def wrong_scope(directive, actual_name) + !actual_name.start_with?('self.') && directive[:has_scope_directive] + end + + def no_scope(directive, actual_name) + actual_name.start_with?('self.') && !directive[:has_scope_directive] + end + + def register_offense(offense_type, node, directive, actual_name) + message = formatted_message(offense_type, directive, actual_name, node.method_name) + + add_offense(node, message: message) do |corrector| + case offense_type + when :wrong_name + correct_method_directive(corrector, directive, actual_name) + when :wrong_scope + remove_scope_directive(corrector, directive) + when :no_scope + insert_scope_directive(corrector, directive[:node_method]) + when :missing_directive + insert_method_directive(corrector, node, actual_name) + end + end + end + + # rubocop:disable Metrics/MethodLength + def formatted_message(offense_type, directive, actual_name, method_name) + case offense_type + when :wrong_name + # Add the receiver to the name when showing an offense + current_name = if directive[:receiver] + directive[:receiver] + directive[:method_name] + else + directive[:method_name] + end + # The correct name will never include a receiver, remove it + format(MSG_WRONG_NAME, expected: remove_receiver(actual_name), actual: current_name) + when :wrong_scope + MSG_WRONG_SCOPE_SELF + when :no_scope + MSG_MISSING_SCOPE_SELF + when :missing_directive + format(MSG, method: method_name) + end + end + # rubocop:enable Metrics/MethodLength + + def remove_receiver(current) + current.delete_prefix('self.') + end + + def insert_method_directive(corrector, node, actual_name) + # If the pattern matcher uses arguments (`%1`, `%2`, etc.), include them in the directive + arguments = pattern_arguments(node.arguments[1].source) + + range = range_with_surrounding_space(node.source_range, side: :left, newlines: false) + indentation = range.source.match(/^\s*/)[0] + directive = "#{indentation}# @!method #{actual_name}(#{arguments.join(', ')})\n" + directive = "\n#{directive}" if add_newline?(node) + + corrector.insert_before(range, directive) + end + + def insert_scope_directive(corrector, node) + range = range_with_surrounding_space(node.source_range, side: :left, newlines: false) + indentation = range.source.match(/^\s*/)[0] + directive = "\n#{indentation}# @!scope class" + + corrector.insert_after(node, directive) + end + + def pattern_arguments(pattern) + arguments = %w[node] + max_pattern_var = pattern.scan(/(?<=%)\d+/).map(&:to_i).max + max_pattern_var&.times { |i| arguments << "arg#{i + 1}" } + arguments + end + + def add_newline?(node) + # Determine if a blank line should be inserted before the new directive + # in order to spread out pattern matchers + return false if node.sibling_index&.zero? + return false unless node.parent + + prev_sibling = node.parent.child_nodes[node.sibling_index - 1] + return false unless prev_sibling && pattern_matcher?(prev_sibling) + + node.loc.line == last_line(prev_sibling) + 1 + end + + def last_line(node) + if node.last_argument.heredoc? + node.last_argument.loc.heredoc_end.line + else + node.loc.last_line + end + end + + def correct_method_directive(corrector, directive, actual_name) + correct = "@!method #{remove_receiver(actual_name)}" + current_name = (directive[:receiver] || '') + directive[:method_name] + regexp = /@!method\s+#{Regexp.escape(current_name)}/ + + replacement = directive[:node_method].text.gsub(regexp, correct) + corrector.replace(directive[:node_method], replacement) + end + + def remove_scope_directive(corrector, directive) + range = range_by_whole_lines( + directive[:node_scope].source_range, + include_final_newline: true + ) + corrector.remove(range) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb new file mode 100644 index 00000000..d9b2201b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb @@ -0,0 +1,231 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Use node groups (`any_block`, `argument`, `boolean`, `call`, `numeric`, `range`) + # in node patterns instead of a union (`{ ... }`) of the member types of the group. + # + # @example + # # bad + # def_node_matcher :my_matcher, <<~PATTERN + # {send csend} + # PATTERN + # + # # good + # def_node_matcher :my_matcher, <<~PATTERN + # call + # PATTERN + # + class NodePatternGroups < Base + require_relative 'node_pattern_groups/ast_processor' + require_relative 'node_pattern_groups/ast_walker' + + include RangeHelp + extend AutoCorrector + + MSG = 'Replace `%s` in node pattern union with `%s`.' + RESTRICT_ON_SEND = %i[def_node_matcher def_node_search].freeze + NODE_GROUPS = { + any_block: %i[block numblock itblock], + any_def: %i[def defs], + any_match_pattern: %i[match_pattern match_pattern_p], + argument: %i[arg optarg restarg kwarg kwoptarg kwrestarg blockarg forward_arg shadowarg], + boolean: %i[true false], + call: %i[send csend], + numeric: %i[int float rational complex], + range: %i[irange erange] + }.freeze + + def on_new_investigation + @walker = ASTWalker.new + end + + # When a Node Pattern matcher is defined, investigate the pattern string to search + # for node types that can be replaced with a node group (ie. `{send csend}` can be + # replaced with `call`). + # + # In order to deal with node patterns in an efficient and non-brittle way, we will + # parse the Node Pattern string given to this `send` node using + # `RuboCop::AST::NodePattern::Parser::WithMeta`. `WithMeta` is important! We need + # location information so that we can calculate the exact locations within the + # pattern to report and correct. + # + # The resulting AST is processed by `NodePatternGroups::ASTProccessor` which rewrites + # the AST slightly to handle node sequences (ie. `(send _ :foo ...)`). See the + # documentation of that class for more details. + # + # Then the processed AST is walked, and metadata is collected for node types that + # can be replaced with a node group. + # + # Finally, the metadata is used to register offenses and make corrections, using + # the location data captured earlier. The ranges captured while parsing the Node + # Pattern are offset using the string argument to this `send` node to ensure + # that offenses are registered at the correct location. + # + def on_send(node) + pattern_node = node.arguments[1] + return unless acceptable_heredoc?(pattern_node) || pattern_node.str_type? + + process_pattern(pattern_node) + return if node_groups.nil? + + apply_range_offsets(pattern_node) + + node_groups.each_with_index do |group, index| + register_offense(group, index) + end + end + + def after_send(_) + @walker.reset! + end + + private + + def node_groups + @walker.node_groups + end + + # rubocop:disable InternalAffairs/RedundantSourceRange -- `node` here is a NodePatternNode + def register_offense(group, index) + replacement = replacement(group) + message = format( + MSG, + names: group.node_types.map { |node| node.source_range.source }.join('`, `'), + replacement: replacement + ) + + add_offense(group.offense_range, message: message) do |corrector| + # Only correct one group at a time to avoid clobbering. + # Other offenses will be corrected in the subsequent iterations of the + # correction loop. + next if index.positive? + + if group.other_elements? + replace_types_with_node_group(corrector, group, replacement) + else + replace_union(corrector, group, replacement) + end + end + end + + def replacement(group) + if group.sequence? + # If the original nodes were in a sequence (ie. wrapped in parentheses), + # use it to generate the resulting NodePattern syntax. + first_node_type = group.node_types.first + template = first_node_type.source_range.source + template.sub(first_node_type.child.to_s, group.name.to_s) + else + group.name + end + end + # rubocop:enable InternalAffairs/RedundantSourceRange + + # When there are other elements in the union, remove the node types that can be replaced. + def replace_types_with_node_group(corrector, group, replacement) + ranges = group.ranges.map.with_index do |range, index| + # Collect whitespace and pipes preceding each element + range_for_full_union_element(range, index, group.pipe) + end + + ranges.each { |range| corrector.remove(range) } + + corrector.insert_before(ranges.first, replacement) + end + + # If the union contains pipes, remove the pipe character as well. + # Unfortunately we don't get the location of the pipe in `loc` object, so we have + # to find it. + def range_for_full_union_element(range, index, pipe) + if index.positive? + range = if pipe + range_with_preceding_pipe(range) + else + range_with_surrounding_space(range: range, side: :left, newlines: true) + end + end + + range + end + + # Collect a preceding pipe and any whitespace left of the pipe + def range_with_preceding_pipe(range) + pos = range.begin_pos - 1 + + while pos + unless processed_source.buffer.source[pos].match?(/[\s|]/) + return range.with(begin_pos: pos + 1) + end + + pos -= 1 + end + + range + end + + # When there are no other elements, the entire union can be replaced + def replace_union(corrector, group, replacement) + corrector.replace(group.ranges.first, replacement) + end + + # rubocop:disable Metrics/AbcSize + # Calculate the ranges for each node within the pattern string that will + # be replaced or removed. Takes the offset of the string node into account. + def apply_range_offsets(pattern_node) + range, offset = range_with_offset(pattern_node) + + node_groups.each do |node_group| + node_group.ranges ||= [] + node_group.offense_range = pattern_range(range, node_group.union, offset) + + if node_group.other_elements? + node_group.node_types.each do |node_type| + node_group.ranges << pattern_range(range, node_type, offset) + end + else + node_group.ranges << node_group.offense_range + end + end + end + # rubocop:enable Metrics/AbcSize + + def pattern_range(range, node, offset) + begin_pos = node.source_range.begin_pos + end_pos = node.source_range.end_pos + size = end_pos - begin_pos + + range.adjust(begin_pos: begin_pos + offset).resize(size) + end + + def range_with_offset(pattern_node) + if pattern_node.heredoc? + [pattern_node.loc.heredoc_body, 0] + else + [pattern_node.source_range, pattern_node.loc.begin.size] + end + end + + # A heredoc can be a `dstr` without interpolation, but if there is interpolation + # there'll be a `begin` node, in which case, we cannot evaluate the pattern. + def acceptable_heredoc?(node) + node.type?(:str, :dstr) && node.heredoc? && node.each_child_node(:begin).none? + end + + def process_pattern(pattern_node) + parser = RuboCop::AST::NodePattern::Parser::WithMeta.new + ast = parser.parse(pattern_value(pattern_node)) + ast = ASTProcessor.new.process(ast) + @walker.walk(ast) + rescue RuboCop::AST::NodePattern::Invalid + # if the pattern is invalid, no offenses will be registered + end + + def pattern_value(pattern_node) + pattern_node.heredoc? ? pattern_node.loc.heredoc_body.source : pattern_node.value + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb new file mode 100644 index 00000000..71a75d63 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + class NodePatternGroups + # AST Processor for NodePattern ASTs, for use with `InternalAffairs/NodePatternGroups`. + # + # Looks for sequences and subsequences where the first item is a `node_type` node, + # and converts them to `node_sequence` nodes (not a true `Rubocop::AST::NodePattern` + # node type). + # + # The resulting AST will be walked by `InternalAffairs::NodePatternGroups::ASTWalker` + # in order to find node types in a `union` node that can be rewritten as a node group. + # + # NOTE: The `on_*` methods in this class relate not to the normal node types but + # rather to the Node Pattern node types. Not every node type is handled. + # + class ASTProcessor + include ::AST::Processor::Mixin + + def handler_missing(node) + node.updated(nil, process_children(node)) + end + + # Look for `sequence` and `subsequence` nodes that contain a `node_type` node as + # their first child. These are rewritten as `node_sequence` nodes so that it is + # possible to compare nodes while looking for replacement candidates for node groups. + # This is necessary so that extended patterns can be matched and replaced. + # ie. `{(send _ :foo ...) (csend _ :foo ...)}` can become `(call _ :foo ...)` + def on_sequence(node) + first_child = node.child + + if first_child.type == :node_type + children = [first_child.child, *process_children(node, 1..)] + + # The `node_sequence` node contains the `node_type` symbol as its first child, + # followed by all the other nodes contained in the `sequence` node. + # The location is copied from the sequence, so that the entire sequence can + # eventually be corrected in the cop. + n(:node_sequence, children, location: node.location) + else + node.updated(nil, process_children(node)) + end + end + alias on_subsequence on_sequence + + private + + def n(type, children = [], properties = {}) + NodePattern::Node.new(type, children, properties) + end + + def process_children(node, range = 0..-1) + node.children[range].map do |child| + child.is_a?(::AST::Node) ? process(child) : child + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb new file mode 100644 index 00000000..453a9ee8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb @@ -0,0 +1,131 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # rubocop:disable InternalAffairs/RedundantSourceRange -- node here is a `NodePattern::Node` + class NodePatternGroups + # Walks an AST that has been processed by `InternalAffairs::NodePatternGroups::Processor` + # in order to find `node_type` and `node_sequence` nodes that can be replaced with a node + # group in `InternalAffairs/NodePatternGroups`. + # + # Calling `ASTWalker#walk` sets `node_groups` with an array of `NodeGroup` structs + # that contain metadata about nodes that can be replaced, including location data. That + # metadata is used by the cop to register offenses and perform corrections. + class ASTWalker + # Struct to contain data about parts of a node pattern that can be replaced + NodeGroup = Struct.new( + :name, # The name of the node group that will be inserted + :union, # The entire `union` node + :node_types, # An array of `node_type` nodes that will be removed + :sequence?, # The pattern matches a node type with given attributes + :start_index, # The index in the union of the first node type to remove + :offense_range, # The range to mark an offense on + :ranges, # Range of each element to remove, since they may not be adjacent + :pipe, # Is the union delimited by pipes? + :other_elements?, # Does the union have other elements other than those to remove? + keyword_init: true + ) + + def initialize + reset! + end + + def reset! + @node_groups = [] + end + + attr_reader :node_groups + + # Recursively walk the AST in a depth-first manner. + # Only `union` nodes are handled further. + def walk(node) + return if node.nil? + + on_union(node) if node.type == :union + + node.child_nodes.each do |child| + walk(child) + end + end + + # Search `union` nodes for `node_type` and `node_sequence` nodes that can be + # collapsed into a node group. + # * `node_type` nodes are nodes with no further configuration (ie. `send`) + # * `node_sequence` nodes are nodes with further configuration (ie. `(send ...)`) + # + # Each group of types that can be collapsed will have a `NodeGroup` record added + # to `node_groups`, which is then used by the cop. + def on_union(node) + all_node_types = each_child_node(node, :node_type, :node_sequence).to_a + + each_node_group(all_node_types) do |group_name, node_types| + next unless sequences_match?(node_types) + + node_groups << node_group_data( + group_name, node, node_types, + all_node_types.index(node_types.first), + (node.children - node_types).any? + ) + end + end + + private + + def each_child_node(node, *types) + return to_enum(__method__, node, *types) unless block_given? + + node.children.each do |child| + yield child if types.empty? || types.include?(child.type) + end + + self + end + + def each_node_group(types_to_check) + # Find all node groups where all of the members are present in the union + type_names = types_to_check.map(&:child) + + NODE_GROUPS.select { |_, group| group & type_names == group }.each_key do |name| + nodes = get_relevant_nodes(types_to_check, name) + + yield name, nodes + end + end + + def get_relevant_nodes(node_types, group_name) + node_types.each_with_object([]) do |node_type, arr| + next unless NODE_GROUPS[group_name].include?(node_type.child) + + arr << node_type + end + end + + def node_group_data(name, union, node_types, start_index, other) + NodeGroup.new( + name: name, + union: union, + node_types: node_types, + sequence?: node_types.first.type == :node_sequence, + start_index: start_index, + pipe: union.source_range.source['|'], + other_elements?: other + ) + end + + def sequences_match?(types) + # Ensure all given types have the same type and the same sequence + # ie. `(send ...)` and `(csend ...) is a match + # `(send)` and `(csend ...)` is not a match + # `send` and `(csend ...)` is not a match + + types.each_cons(2).all? do |left, right| + left.type == right.type && left.children[1..] == right.children[1..] + end + end + end + end + # rubocop:enable InternalAffairs/RedundantSourceRange + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_type_group.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_type_group.rb new file mode 100644 index 00000000..6fb3a336 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_type_group.rb @@ -0,0 +1,91 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Checks that node types are checked against their group when all types of a + # group are checked. + # + # @example + # # bad + # node.type?(:irange, :erange) + # + # # good + # node.range_type? + # + # # bad + # node.type?(:irange, :erange, :send, :csend) + # + # # good + # node.type?(:range, :call) + # + class NodeTypeGroup < Base + extend AutoCorrector + include RangeHelp + + MSG = 'Use `:%s` instead of individually listing group types.' + + RESTRICT_ON_SEND = %i[type? each_ancestor each_child_node each_descendant each_node].freeze + + def on_send(node) + return unless node.receiver + + symbol_args = node.arguments.select(&:sym_type?) + return if symbol_args.none? + + NodePatternGroups::NODE_GROUPS.each do |group_name, group_types| + next unless group_satisfied?(group_types, symbol_args) + + offense_range = arguments_range(node) + add_offense(offense_range, message: format(MSG, group: group_name)) do |corrector| + autocorrect(corrector, node, symbol_args, group_name, group_types) + end + end + end + alias on_csend on_send + + private + + def arguments_range(node) + range_between( + node.first_argument.source_range.begin_pos, + node.last_argument.source_range.end_pos + ) + end + + def group_satisfied?(group_types, symbol_args) + group_types.all? { |type| symbol_args.any? { |arg| arg.value == type } } + end + + def autocorrect(corrector, node, symbol_args, group_name, group_types) + if node.method?(:type?) && node.arguments.count == group_types.count + autocorrect_to_explicit_predicate(corrector, node, group_name) + else + autocorrect_keep_method(corrector, symbol_args, group_name, group_types) + end + end + + def autocorrect_to_explicit_predicate(corrector, node, group_name) + corrector.replace(node.selector, "#{group_name}_type?") + corrector.remove(arguments_range(node)) + end + + def autocorrect_keep_method(corrector, symbol_args, group_name, group_types) + first_replaced = false + symbol_args.each do |arg| + next unless group_types.include?(arg.value) + + if first_replaced + range = range_with_surrounding_space(arg.source_range) + range = range_with_surrounding_comma(range, :left) + corrector.remove(range) + else + first_replaced = true + corrector.replace(arg, ":#{group_name}") + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb new file mode 100644 index 00000000..0744b85f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb @@ -0,0 +1,126 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Use `node.type?(:foo, :bar)` instead of `node.foo_type? || node.bar_type?`, + # and `!node.type?(:foo, :bar)` instead of `!node.foo_type? && !node.bar_type?`. + # + # @example + # + # # bad + # node.str_type? || node.sym_type? + # + # # good + # node.type?(:str, :sym) + # + # # bad + # node.type?(:str, :sym) || node.boolean_type? + # + # # good + # node.type?(:str, :sym, :boolean) + # + # # bad + # !node.str_type? && !node.sym_type? + # + # # good + # !node.type?(:str, :sym) + # + # # bad + # !node.type?(:str, :sym) && !node.boolean_type? + # + # # good + # !node.type?(:str, :sym, :boolean) + # + class NodeTypeMultiplePredicates < Base + extend AutoCorrector + + MSG_OR = 'Use `%s` instead of checking for multiple node types.' + MSG_AND = 'Use `%s` instead of checking against multiple node types.' + + # @!method one_of_node_types?(node) + def_node_matcher :one_of_node_types?, <<~PATTERN + (or $(call _receiver #type_predicate?) (call _receiver #type_predicate?)) + PATTERN + + # @!method or_another_type?(node) + def_node_matcher :or_another_type?, <<~PATTERN + (or { + $(call _receiver :type? sym+) (call _receiver #type_predicate?) | + (call _receiver #type_predicate?) $(call _receiver :type? sym+) + }) + PATTERN + + # @!method none_of_node_types?(node) + def_node_matcher :none_of_node_types?, <<~PATTERN + (and + (send $(call _receiver #type_predicate?) :!) + (send (call _receiver #type_predicate?) :!) + ) + PATTERN + + # @!method and_not_another_type?(node) + def_node_matcher :and_not_another_type?, <<~PATTERN + (and { + (send $(call _receiver :type? sym+) :!) (send (call _receiver #type_predicate?) :!) | + (send (call _receiver #type_predicate?) :!) (send $(call _receiver :type? sym+) :!) + }) + PATTERN + + def on_or(node) + return unless (send_node = one_of_node_types?(node) || or_another_type?(node)) + return unless send_node.receiver + + replacement = replacement(node, send_node) + add_offense(node, message: format(MSG_OR, replacement: replacement)) do |corrector| + corrector.replace(node, replacement) + end + end + + def on_and(node) + return unless (send_node = none_of_node_types?(node) || and_not_another_type?(node)) + return unless send_node.receiver + + replacement = "!#{replacement(node, send_node)}" + + add_offense(node, message: format(MSG_AND, replacement: replacement)) do |corrector| + corrector.replace(node, replacement) + end + end + + private + + def type_predicate?(method_name) + method_name.end_with?('_type?') + end + + def replacement(node, send_node) + send_node = send_node.children.first if send_node.method?(:!) + + types = types(node) + receiver = send_node.receiver.source + dot = send_node.loc.dot.source + + "#{receiver}#{dot}type?(:#{types.join(', :')})" + end + + def types(node) + [types_in_branch(node.lhs), types_in_branch(node.rhs)] + end + + def types_in_branch(branch) + branch = branch.children.first if branch.method?(:!) + + if branch.method?(:type?) + branch.arguments.map(&:value) + elsif branch.method?(:defined_type?) + # `node.defined_type?` relates to `node.type == :defined?` + 'defined?' + else + branch.method_name.to_s.delete_suffix('_type?') + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_type_predicate.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_type_predicate.rb new file mode 100644 index 00000000..d6da7c98 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/node_type_predicate.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Checks that node types are checked using the predicate helpers. + # + # @example + # + # # bad + # node.type == :send + # + # # good + # node.send_type? + # + class NodeTypePredicate < Base + extend AutoCorrector + + MSG = 'Use `#%s_type?` to check node type.' + RESTRICT_ON_SEND = %i[==].freeze + + # @!method node_type_check(node) + def_node_matcher :node_type_check, <<~PATTERN + (send (call _ :type) :== (sym $_)) + PATTERN + + def on_send(node) + node_type_check(node) do |node_type| + return unless Parser::Meta::NODE_TYPES.include?(node_type) + + message = format(MSG, type: node_type) + add_offense(node, message: message) do |corrector| + range = node.receiver.loc.selector.join(node.source_range.end) + + corrector.replace(range, "#{node_type}_type?") + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/numblock_handler.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/numblock_handler.rb new file mode 100644 index 00000000..8f40c4d8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/numblock_handler.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Checks for missing `numblock` handlers. The blocks with numbered + # arguments introduced in Ruby 2.7 are parsed with a node type of + # `numblock` instead of block. Cops that define `block` handlers + # need to define `numblock` handlers or disable this cope for them. + # + # @example + # + # # bad + # class BlockRelatedCop < Base + # def on_block(node) + # end + # end + # + # # good + # class BlockRelatedCop < Base + # def on_block(node) + # end + # + # alias on_numblock on_block + # end + # + # class BlockRelatedCop < Base + # def on_block(node) + # end + # + # alias_method :on_numblock, :on_block + # end + # + # class BlockRelatedCop < Base + # def on_block(node) + # end + # + # def on_numblock(node) + # end + # end + class NumblockHandler < Base + MSG = 'Define on_numblock to handle blocks with numbered arguments.' + + def on_def(node) + return unless block_handler?(node) + return unless node.parent + + add_offense(node) unless numblock_handler?(node.parent) + end + + private + + # @!method block_handler?(node) + def_node_matcher :block_handler?, <<~PATTERN + (def :on_block (args (arg :node)) ...) + PATTERN + + # @!method numblock_handler?(node) + def_node_matcher :numblock_handler?, <<~PATTERN + { + `(def :on_numblock (args (arg :node)) ...) + `(alias (sym :on_numblock) (sym :on_block)) + `(send nil? :alias_method (sym :on_numblock) (sym :on_block)) + } + PATTERN + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb new file mode 100644 index 00000000..2abcff8f --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Checks for potential uses of the location keywords which can be used as + # shortcut arguments to `#add_offense`. + # + # @example + # + # # bad + # add_offense(node, location: node.loc.selector) + # + # # good + # add_offense(node, location: :selector) + class OffenseLocationKeyword < Base + extend AutoCorrector + + MSG = 'Use `:%s` as the location argument to `#add_offense`.' + RESTRICT_ON_SEND = %i[add_offense].freeze + + def on_send(node) + node_type_check(node) do |node_arg, kwargs| + find_offending_argument(node_arg, kwargs) do |location, keyword| + add_offense(location, message: format(MSG, keyword: keyword)) do |corrector| + (*, keyword) = offending_location_argument(location.parent) + + corrector.replace(location, ":#{keyword}") + end + end + end + end + + private + + # @!method node_type_check(node) + def_node_matcher :node_type_check, <<~PATTERN + (send nil? :add_offense $_node $hash) + PATTERN + + # @!method offending_location_argument(node) + def_node_matcher :offending_location_argument, <<~PATTERN + (pair (sym :location) $(send (send $_node :loc) $_keyword)) + PATTERN + + def find_offending_argument(searched_node, kwargs) + kwargs.pairs.each do |pair| + offending_location_argument(pair) do |location, node, keyword| + yield(location, keyword) if searched_node == node + end + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb new file mode 100644 index 00000000..b6d86e82 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb @@ -0,0 +1,90 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Checks for cops that define `on_send` without define `on_csend`. + # + # Although in some cases it can be predetermined that safe navigation + # will never be used with the code checked by a specific cop, in general + # it is good practice to handle safe navigation methods if handling any + # `send` node. + # + # NOTE: It is expected to disable this cop for cops that check for method calls + # on receivers that cannot be nil (`self`, a literal, a constant), and + # method calls that will never have a receiver (ruby keywords like `raise`, + # macros like `attr_reader`, DSL methods, etc.), and other checks that wouldn't + # make sense to support safe navigation. + # + # @example + # # bad + # class MyCop < RuboCop::Cop:Base + # def on_send(node) + # # ... + # end + # end + # + # # good - explicit method definition + # class MyCop < RuboCop::Cop:Base + # def on_send(node) + # # ... + # end + # + # def on_csend(node) + # # ... + # end + # end + # + # # good - alias + # class MyCop < RuboCop::Cop:Base + # def on_send(node) + # # ... + # end + # alias on_csend on_send + # end + # + # # good - alias_method + # class MyCop < RuboCop::Cop:Base + # def on_send(node) + # # ... + # end + # alias_method :on_csend, :on_send + # end + class OnSendWithoutOnCSend < Base + RESTRICT_ON_SEND = %i[alias_method].freeze + MSG = 'Cop defines `on_send` but not `on_csend`.' + + def on_new_investigation + @on_send_definition = nil + @on_csend_definition = nil + end + + def on_investigation_end + return unless @on_send_definition && !@on_csend_definition + + add_offense(@on_send_definition) + end + + def on_def(node) + @on_send_definition = node if node.method?(:on_send) + @on_csend_definition = node if node.method?(:on_csend) + end + + def on_alias(node) + @on_send_definition = node if node.new_identifier.value == :on_send + @on_csend_definition = node if node.new_identifier.value == :on_csend + end + + def on_send(node) # rubocop:disable InternalAffairs/OnSendWithoutOnCSend + new_identifier = node.first_argument + return unless new_identifier.basic_literal? + + new_identifier = new_identifier.value + + @on_send_definition = node if new_identifier == :on_send + @on_csend_definition = node if new_identifier == :on_csend + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/operator_keyword.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/operator_keyword.rb new file mode 100644 index 00000000..be1f70d1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/operator_keyword.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Enforces the use of `node.operator_keyword?` instead of `node.and_type? || node.or_type?`. + # + # @example + # # bad + # node.and_type? || node.or_type? + # node.or_type? || node.and_type? + # + # # good + # node.operator_keyword? + # + class OperatorKeyword < Base + extend AutoCorrector + + MSG = 'Use `%s`.' + PREFERRED_METHOD = 'operator_keyword?' + + # @!method and_or_type(node) + def_node_matcher :and_or_type, <<~PATTERN + { + (or $(send _node :and_type?) $(send _node :or_type?)) + (or $(send _node :or_type?) $(send _node :and_type?)) + (or + (or _ $(send _node :and_type?)) $(send _node :or_type?)) + (or + (or _ $(send _node :or_type?)) $(send _node :and_type?)) + } + PATTERN + + def on_or(node) + return unless (lhs, rhs = and_or_type(node)) + + begin_range = lhs.receiver&.source_range || lhs.loc.selector + offense = begin_range.join(rhs.source_range.end) + prefer = lhs.receiver ? "#{lhs.receiver.source}.#{PREFERRED_METHOD}" : PREFERRED_METHOD + + add_offense(offense, message: format(MSG, prefer: prefer)) do |corrector| + corrector.replace(offense, prefer) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/plugin.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/plugin.rb new file mode 100644 index 00000000..5c5432f8 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/plugin.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require 'lint_roller' + +module RuboCop + module InternalAffairs + # A Plugin for `InternalAffairs` department, which has internal cops. + class Plugin < LintRoller::Plugin + def about + LintRoller::About.new( + name: 'rubocop-internal_affairs', + version: Version::STRING, + homepage: 'https://github.com/rubocop/rubocop/tree/master/lib/rubocop/cop/internal_affairs', + description: 'A collection of RuboCop cops to check for internal affairs.' + ) + end + + def supported?(context) + context.engine == :rubocop + end + + def rules(_context) + require_relative '../internal_affairs' + + LintRoller::Rules.new( + type: :path, + config_format: :rubocop, + value: Pathname.new(__dir__).join('../../../../config/internal_affairs.yml') + ) + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/processed_source_buffer_name.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/processed_source_buffer_name.rb new file mode 100644 index 00000000..96d1eee4 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/processed_source_buffer_name.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Enforces the use of `processed_source.file_path` instead of `processed_source.buffer.name`. + # + # @example + # + # # bad + # processed_source.buffer.name + # + # # good + # processed_source.file_path + # + class ProcessedSourceBufferName < Base + extend AutoCorrector + + MSG = 'Use `file_path` instead.' + + RESTRICT_ON_SEND = %i[name].freeze + + # @!method processed_source_buffer_name?(node) + def_node_matcher :processed_source_buffer_name?, <<~PATTERN + (send + (send + {(lvar :processed_source) (send nil? :processed_source)} :buffer) :name) + PATTERN + + def on_send(node) + return unless processed_source_buffer_name?(node) + + offense_range = node.children.first.loc.selector.begin.join(node.source_range.end) + + add_offense(offense_range) do |corrector| + corrector.replace(offense_range, 'file_path') + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/redundant_context_config_parameter.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/redundant_context_config_parameter.rb new file mode 100644 index 00000000..b31edc0b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/redundant_context_config_parameter.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Checks for redundant `:config` parameter in the `context` arguments. + # + # @example + # + # # bad + # context 'foo', :config do + # end + # + # # good + # context 'foo' do + # end + # + class RedundantContextConfigParameter < Base + include RangeHelp + extend AutoCorrector + + MSG = 'Remove the redundant `:config` parameter.' + RESTRICT_ON_SEND = %i[context].freeze + + def on_send(node) + arguments = node.arguments + config_node = arguments.detect { |argument| argument.source == ':config' } + return unless config_node + + add_offense(config_node) do |corrector| + dup_arguments = arguments.dup + dup_arguments.delete(config_node) + + corrector.replace(offense_range(arguments), dup_arguments.map(&:source).join(', ')) + end + end + + private + + def offense_range(arguments) + range_between(arguments.first.source_range.begin_pos, arguments.last.source_range.end_pos) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb new file mode 100644 index 00000000..39bf8bf9 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Checks for redundant `subject(:cop) { described_class.new }`. + # + # @example + # # bad + # RSpec.describe RuboCop::Cop::Department::Foo do + # subject(:cop) { described_class.new(config) } + # end + # + # # good + # RSpec.describe RuboCop::Cop::Department::Foo, :config do + # end + # + class RedundantDescribedClassAsSubject < Base + include RangeHelp + extend AutoCorrector + + MSG = 'Remove the redundant `subject`%s.' + + # @!method described_class_subject?(node) + def_node_matcher :described_class_subject?, <<~PATTERN + (block + (send nil? :subject + (sym :cop)) + (args) + (send + (send nil? :described_class) :new + $...)) + PATTERN + + def on_block(node) + return unless (described_class_arguments = described_class_subject?(node)) + return if described_class_arguments.count >= 2 + + describe = find_describe_method_node(node) + + should_append_config = describe && describe.last_argument.source != ':config' + additional_message = ' and specify `:config` in `describe`' if should_append_config + + message = format(MSG, additional_message: additional_message) + + add_offense(node, message: message) do |corrector| + corrector.remove(range_by_whole_lines(node.source_range, include_final_newline: true)) + + corrector.insert_after(describe.last_argument, ', :config') if should_append_config + end + end + + private + + def find_describe_method_node(block_node) + block_node.ancestors.find do |node| + node.block_type? && node.method?(:describe) + end&.send_node + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb new file mode 100644 index 00000000..4424cb07 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Checks for redundant arguments of `RuboCop::RSpec::ExpectOffense`'s methods. + # + # @example + # + # # bad + # expect_no_offenses('code', keyword: keyword) + # + # # good + # expect_no_offenses('code') + # + class RedundantExpectOffenseArguments < Base + extend AutoCorrector + + MSG = 'Remove the redundant arguments.' + RESTRICT_ON_SEND = %i[expect_no_offenses].freeze + + def on_send(node) + return if node.arguments.one? || !node.arguments[1]&.hash_type? + + range = node.first_argument.source_range.end.join(node.last_argument.source_range.end) + + add_offense(range) do |corrector| + corrector.remove(range) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb new file mode 100644 index 00000000..60ee490d --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb @@ -0,0 +1,73 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Checks that `let` is `RuboCop::Config.new` with no arguments. + # + # @example + # # bad + # RSpec.describe RuboCop::Cop::Department::Foo, :config do + # let(:config) { RuboCop::Config.new } + # end + # + # # good + # RSpec.describe RuboCop::Cop::Department::Foo, :config do + # end + # + # RSpec.describe RuboCop::Cop::Department::Foo, :config do + # let(:config) { RuboCop::Config.new(argument) } + # end + # + class RedundantLetRuboCopConfigNew < Base + include RangeHelp + extend AutoCorrector + + MSG = 'Remove `let` that is `RuboCop::Config.new` with no arguments%s.' + + # @!method let_rubocop_config_new?(node) + def_node_matcher :let_rubocop_config_new?, <<~PATTERN + (block + (send nil? :let + (sym :config)) + (args) + { + (send + (const + (const nil? :RuboCop) :Config) :new) + (send + (const + (const nil? :RuboCop) :Config) :new + (hash (pair (send (send (send nil? :described_class) :badge) :to_s) + (send nil? :cop_config)))) + } + ) + PATTERN + + def on_block(node) + return unless let_rubocop_config_new?(node) + + describe = find_describe_method_node(node) + + unless (exist_config = describe.last_argument.source == ':config') + additional_message = ' and specify `:config` in `describe`' + end + + message = format(MSG, additional_message: additional_message) + + add_offense(node, message: message) do |corrector| + corrector.remove(range_by_whole_lines(node.source_range, include_final_newline: true)) + + corrector.insert_after(describe.last_argument, ', :config') unless exist_config + end + end + + private + + def find_describe_method_node(block_node) + block_node.ancestors.find { |node| node.block_type? && node.method?(:describe) }.send_node + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb new file mode 100644 index 00000000..1ea11496 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Checks for redundant `location` argument to `#add_offense`. `location` + # argument has a default value of `:expression` and this method will + # automatically use it. + # + # @example + # + # # bad + # add_offense(node, location: :expression) + # + # # good + # add_offense(node) + # add_offense(node, location: :selector) + # + class RedundantLocationArgument < Base + include RangeHelp + extend AutoCorrector + + MSG = 'Redundant location argument to `#add_offense`.' + RESTRICT_ON_SEND = %i[add_offense].freeze + + # @!method redundant_location_argument(node) + def_node_matcher :redundant_location_argument, <<~PATTERN + (send nil? :add_offense _ + (hash <$(pair (sym :location) (sym :expression)) ...>) + ) + PATTERN + + def on_send(node) + redundant_location_argument(node) do |argument| + add_offense(argument) do |corrector| + range = offending_range(argument) + + corrector.remove(range) + end + end + end + + private + + def offending_range(node) + with_space = range_with_surrounding_space(node.source_range) + + range_with_surrounding_comma(with_space, :left) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb new file mode 100644 index 00000000..fd09f777 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Checks for redundant message arguments to `#add_offense`. This method + # will automatically use `#message` or `MSG` (in that order of priority) + # if they are defined. + # + # @example + # + # # bad + # add_offense(node, message: MSG) + # + # # good + # add_offense(node) + # + class RedundantMessageArgument < Base + include RangeHelp + extend AutoCorrector + + MSG = 'Redundant message argument to `#add_offense`.' + RESTRICT_ON_SEND = %i[add_offense].freeze + + # @!method node_type_check(node) + def_node_matcher :node_type_check, <<~PATTERN + (send nil? :add_offense _node $hash) + PATTERN + + # @!method redundant_message_argument(node) + def_node_matcher :redundant_message_argument, <<~PATTERN + (pair + (sym :message) + $(const nil? :MSG)) + PATTERN + + def on_send(node) + return unless (kwargs = node_type_check(node)) + + kwargs.pairs.each do |pair| + redundant_message_argument(pair) do + add_offense(pair) do |corrector| + range = offending_range(pair) + + corrector.remove(range) + end + end + end + end + + private + + def offending_range(node) + with_space = range_with_surrounding_space(node.source_range) + + range_with_surrounding_comma(with_space, :left) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/redundant_method_dispatch_node.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/redundant_method_dispatch_node.rb new file mode 100644 index 00000000..edadd0c6 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/redundant_method_dispatch_node.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Checks for redundant `send_node` method dispatch node. + # + # @example + # + # # bad + # node.send_node.method_name + # + # # good + # node.method_name + # + # # bad + # node.send_node.method?(:method_name) + # + # # good + # node.method?(:method_name) + # + # # bad + # node.send_node.receiver + # + # # good + # node.receiver + # + class RedundantMethodDispatchNode < Base + include RangeHelp + extend AutoCorrector + + MSG = 'Remove the redundant `send_node`.' + RESTRICT_ON_SEND = %i[method_name method? receiver].freeze + + # @!method dispatch_method(node) + def_node_matcher :dispatch_method, <<~PATTERN + { + (send $(send _ :send_node) {:method_name :receiver}) + (send $(send _ :send_node) :method? _) + } + PATTERN + + def on_send(node) + return unless (dispatch_node = dispatch_method(node)) + return unless (dot = dispatch_node.loc.dot) + + range = range_between(dot.begin_pos, dispatch_node.loc.selector.end_pos) + + add_offense(range) do |corrector| + corrector.remove(range) + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/redundant_source_range.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/redundant_source_range.rb new file mode 100644 index 00000000..f4cb32b5 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/redundant_source_range.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Checks for redundant `source_range`. + # + # @example + # + # # bad + # node.source_range.source + # + # # good + # node.source + # + # # bad + # add_offense(node.source_range) + # + # # good + # add_offense(node) + # + # # bad + # add_offense(node) { |corrector| corrector.replace(node.source_range, prefer) } + # add_offense(node) { |corrector| corrector.insert_before(node.source_range, prefer) } + # add_offense(node) { |corrector| corrector.insert_before_multi(node.source_range, prefer) } + # add_offense(node) { |corrector| corrector.insert_after(node.source_range, prefer) } + # add_offense(node) { |corrector| corrector.insert_after_multi(node.source_range, prefer) } + # add_offense(node) { |corrector| corrector.swap(node.source_range, before, after) } + # + # # good + # add_offense(node) { |corrector| corrector.replace(node, prefer) } + # add_offense(node) { |corrector| corrector.insert_before(node, prefer) } + # add_offense(node) { |corrector| corrector.insert_before_multi(node, prefer) } + # add_offense(node) { |corrector| corrector.insert_after(node, prefer) } + # add_offense(node) { |corrector| corrector.insert_after_multi(node, prefer) } + # add_offense(node) { |corrector| corrector.swap(node, before, after) } + # + class RedundantSourceRange < Base + extend AutoCorrector + + MSG = 'Remove the redundant `source_range`.' + RESTRICT_ON_SEND = %i[ + source add_offense + replace remove insert_before insert_before_multi insert_after insert_after_multi swap + ].freeze + + # @!method redundant_source_range(node) + def_node_matcher :redundant_source_range, <<~PATTERN + { + (call $(call _ :source_range) :source) + (send nil? :add_offense $(send _ :source_range) ...) + (send _ { + :replace :insert_before :insert_before_multi :insert_after :insert_after_multi + } $(send _ :source_range) _) + (send _ :remove $(send _ :source_range)) + (send _ :swap $(send _ :source_range) _ _) + } + PATTERN + + def on_send(node) + return unless (source_range = redundant_source_range(node)) + return unless source_range.receiver + return if source_range.receiver.send_type? && source_range.receiver.method?(:buffer) + + selector = source_range.loc.selector + + add_offense(selector) do |corrector| + corrector.remove(source_range.loc.dot.join(selector)) + end + end + alias on_csend on_send + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/single_line_comparison.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/single_line_comparison.rb new file mode 100644 index 00000000..e63eaca7 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/single_line_comparison.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Enforces the use of `node.single_line?` instead of + # comparing `first_line` and `last_line` for equality. + # + # @example + # # bad + # node.loc.first_line == node.loc.last_line + # + # # bad + # node.loc.last_line == node.loc.first_line + # + # # bad + # node.loc.line == node.loc.last_line + # + # # bad + # node.loc.last_line == node.loc.line + # + # # bad + # node.first_line == node.last_line + # + # # good + # node.single_line? + # + class SingleLineComparison < Base + extend AutoCorrector + + MSG = 'Use `%s`.' + RESTRICT_ON_SEND = %i[== !=].freeze + + # @!method single_line_comparison(node) + def_node_matcher :single_line_comparison, <<~PATTERN + { + (send (call $_receiver {:line :first_line}) {:== :!=} (call _receiver :last_line)) + (send (call $_receiver :last_line) {:== :!=} (call _receiver {:line :first_line})) + } + PATTERN + + def on_send(node) + return unless (receiver = single_line_comparison(node)) + + bang = node.method?(:!=) ? '!' : '' + dot = receiver.parent.loc.dot.source + preferred = "#{bang}#{extract_receiver(receiver)}#{dot}single_line?" + + add_offense(node, message: format(MSG, preferred: preferred)) do |corrector| + corrector.replace(node, preferred) + end + end + + private + + def extract_receiver(node) + node = node.receiver if node.call_type? && %i[loc source_range].include?(node.method_name) + node.source + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb new file mode 100644 index 00000000..f1cb49da --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb @@ -0,0 +1,146 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Checks for correct use of the style_detected API provided by + # `ConfigurableEnforcedStyle`. If `correct_style_detected` is used + # then `opposite_style_detected`, `unexpected_style_detected`, + # `ambiguous_style_detected`, `conflicting_styles_detected`, + # `unrecognized_style_detected` or `no_acceptable_style!` should be + # used too, and vice versa. The `xxx_style_detected` methods + # should not be used as predicates either. + # + # @example + # + # # bad + # def on_send(node) + # return add_offense(node) if opposite_style_detected + # + # correct_style_detected + # end + # + # def on_send(node) + # if offense? + # add_offense(node) + # else + # correct_style_detected + # end + # end + # + # def on_send(node) + # return unless offense? + # + # add_offense(node) + # opposite_style_detected + # end + # + # # good + # def on_send(node) + # if offense? + # add_offense(node) + # opposite_style_detected + # else + # correct_style_detected + # end + # end + # + # def on_send(node) + # add_offense(node) if offense? + # end + # + class StyleDetectedApiUse < Base + MSG_FOR_POSITIVE_WITHOUT_NEGATIVE = + '`correct_style_detected` method called without ' \ + 'calling a negative `*_style_detected` method.' + MSG_FOR_NEGATIVE_WITHOUT_POSITIVE = + 'negative `*_style_detected` methods called without ' \ + 'calling `correct_style_detected` method.' + MSG_FOR_CONDITIONAL_USE = '`*_style_detected` method called in conditional.' + RESTRICT_ON_SEND = %i[ + correct_style_detected opposite_style_detected + unexpected_style_detected ambiguous_style_detected + conflicting_styles_detected unrecognized_style_detected + no_acceptable_style! style_detected + ].freeze + + # @!method correct_style_detected_check(node) + def_node_matcher :correct_style_detected_check, <<~PATTERN + (send nil? :correct_style_detected) + PATTERN + + # @!method negative_style_detected_method_check(node) + def_node_matcher :negative_style_detected_method_check, <<~PATTERN + (send nil? /(?:opposite|unexpected|ambiguous|unrecognized)_style_detected|conflicting_styles_detected/ ...) + PATTERN + + # @!method no_acceptable_style_check(node) + def_node_matcher :no_acceptable_style_check, <<~PATTERN + (send nil? :no_acceptable_style!) + PATTERN + + # @!method style_detected_check(node) + def_node_matcher :style_detected_check, <<~PATTERN + (send nil? :style_detected ...) + PATTERN + + def on_new_investigation + @correct_style_detected_called = false + @negative_style_detected_methods_called = false + @style_detected_called = false + end + + def on_investigation_end + return if style_detected_called + return unless correct_style_detected_called ^ negative_style_detected_methods_called + + add_global_offense(MSG_FOR_POSITIVE_WITHOUT_NEGATIVE) if positive_without_negative? + add_global_offense(MSG_FOR_NEGATIVE_WITHOUT_POSITIVE) if negative_without_positive? + end + + def on_send(node) + if correct_style_detected_check(node) + @correct_style_detected_called = true + elsif negative_style_detected_method_check(node) || no_acceptable_style_check(node) + @negative_style_detected_methods_called = true + elsif style_detected_check(node) + @style_detected_called = true + end + end + + def on_if(node) + traverse_condition(node.condition) do |cond| + add_offense(cond, message: MSG_FOR_CONDITIONAL_USE) if style_detected_api_used?(cond) + end + end + + private + + attr_reader :correct_style_detected_called, + :negative_style_detected_methods_called, + :style_detected_called + + def positive_without_negative? + correct_style_detected_called && !negative_style_detected_methods_called + end + + def negative_without_positive? + negative_style_detected_methods_called && !correct_style_detected_called + end + + def style_detected_api_used?(node) + correct_style_detected_check(node) || + negative_style_detected_method_check(node) || + no_acceptable_style_check(node) || + style_detected_check(node) + end + + def traverse_condition(condition, &block) + yield condition if condition.send_type? + + condition.each_child_node { |child| traverse_condition(child, &block) } + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/undefined_config.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/undefined_config.rb new file mode 100644 index 00000000..889b0253 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/undefined_config.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Looks for references to a cop configuration key that isn't defined in config/default.yml. + class UndefinedConfig < Base + # `FileFinder` is a private API not intended to be used by cops, + # but it's fine for `InternalAffairs`. + extend FileFinder + + ALLOWED_CONFIGURATIONS = %w[ + Safe SafeAutoCorrect AutoCorrect + Severity + StyleGuide + Details + Reference References + Include Exclude + ].freeze + RESTRICT_ON_SEND = %i[[] fetch].freeze + MSG = '`%s` is not defined in the configuration for `%s` ' \ + 'in `config/default.yml`.' + CONFIG_PATH = find_file_upwards('config/default.yml', Dir.pwd) + CONFIG = if CONFIG_PATH + begin + original_debug = ConfigLoader.debug + ConfigLoader.debug = false + ConfigLoader.load_yaml_configuration(CONFIG_PATH) + ensure + ConfigLoader.debug = original_debug + end + else + {} + end + + # @!method cop_class_def(node) + def_node_search :cop_class_def, <<~PATTERN + (class _ + (const {nil? (const nil? :Cop) (const (const {cbase nil?} :RuboCop) :Cop)} + {:Base :Cop}) ...) + PATTERN + + # @!method cop_config_accessor?(node) + def_node_matcher :cop_config_accessor?, <<~PATTERN + (send (send nil? :cop_config) {:[] :fetch} ${str sym}...) + PATTERN + + def on_new_investigation + super + return unless processed_source.ast + + cop_class = cop_class_def(processed_source.ast).first + return unless (@cop_class_name = extract_cop_name(cop_class)) + + @config_for_cop = CONFIG[@cop_class_name] || {} + end + + def on_send(node) + return unless cop_class_name + return unless (config_name_node = cop_config_accessor?(node)) + return if always_allowed?(config_name_node) + return if configuration_key_defined?(config_name_node) + + message = format(MSG, name: config_name_node.value, cop: cop_class_name) + add_offense(config_name_node, message: message) + end + + private + + attr_reader :config_for_cop, :cop_class_name + + def extract_cop_name(class_node) + return unless class_node + + segments = [class_node].concat( + class_node.each_ancestor(:class, :module).take_while do |n| + n.identifier.short_name != :Cop + end + ) + + segments.reverse_each.map { |s| s.identifier.short_name }.join('/') + end + + def always_allowed?(node) + ALLOWED_CONFIGURATIONS.include?(node.value) + end + + def configuration_key_defined?(node) + config_for_cop.key?(node.value) + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb new file mode 100644 index 00000000..0a2192b1 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Checks that cops are not tested using `described_class::MSG`. + # + # @example + # + # # bad + # expect(cop.messages).to eq([described_class::MSG]) + # + # # good + # expect(cop.messages).to eq(['Do not write bad code like that.']) + # + class UselessMessageAssertion < Base + MSG = 'Do not specify cop behavior using `described_class::MSG`.' + + # @!method described_class_msg(node) + def_node_search :described_class_msg, <<~PATTERN + (const (send nil? :described_class) :MSG) + PATTERN + + # @!method rspec_expectation_on_msg?(node) + def_node_matcher :rspec_expectation_on_msg?, <<~PATTERN + (send (send nil? :expect #contains_described_class_msg?) :to ...) + PATTERN + + def on_new_investigation + return if processed_source.blank? + + assertions_using_described_class_msg.each { |node| add_offense(node) } + end + + private + + def contains_described_class_msg?(node) + described_class_msg(node).any? + end + + def assertions_using_described_class_msg + described_class_msg(processed_source.ast).reject do |node| + node.ancestors.any? { |ancestor| rspec_expectation_on_msg?(ancestor) } + end + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb new file mode 100644 index 00000000..f7a32568 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module InternalAffairs + # Check for useless `RESTRICT_ON_SEND`. + # + # @example + # # bad + # class FooCop + # RESTRICT_ON_SEND = %i[bad_method].freeze + # end + # + # # good + # class FooCop + # RESTRICT_ON_SEND = %i[bad_method].freeze + # def on_send(node) + # # ... + # end + # end + # + # # good + # class FooCop + # RESTRICT_ON_SEND = %i[bad_method].freeze + # def after_send(node) + # # ... + # end + # end + # + class UselessRestrictOnSend < Base + extend AutoCorrector + + MSG = 'Useless `RESTRICT_ON_SEND` is defined.' + + # @!method defined_send_callback?(node) + def_node_search :defined_send_callback?, <<~PATTERN + { + (def {:on_send :after_send} ...) + (alias (sym {:on_send :after_send}) _source ...) + (send nil? :alias_method {(sym {:on_send :after_send}) (str {"on_send" "after_send"})} _source ...) + } + PATTERN + + def on_casgn(node) + return if !restrict_on_send?(node) || defined_send_callback?(node.parent) + + add_offense(node) do |corrector| + corrector.remove(node) + end + end + + private + + def restrict_on_send?(node) + node.name == :RESTRICT_ON_SEND + end + end + end + end +end diff --git a/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/layout/access_modifier_indentation.rb b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/layout/access_modifier_indentation.rb new file mode 100644 index 00000000..25ebd34b --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/rubocop-1.76.1/lib/rubocop/cop/layout/access_modifier_indentation.rb @@ -0,0 +1,104 @@ +# frozen_string_literal: true + +module RuboCop + module Cop + module Layout + # Bare access modifiers (those not applying to specific methods) should be + # indented as deep as method definitions, or as deep as the `class`/`module` + # keyword, depending on configuration. + # + # @example EnforcedStyle: indent (default) + # # bad + # class Plumbus + # private + # def smooth; end + # end + # + # # good + # class Plumbus + # private + # def smooth; end + # end + # + # @example EnforcedStyle: outdent + # # bad + # class Plumbus + # private + # def smooth; end + # end + # + # # good + # class Plumbus + # private + # def smooth; end + # end + class AccessModifierIndentation < Base + include Alignment + include ConfigurableEnforcedStyle + include RangeHelp + extend AutoCorrector + + MSG = '%